diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/404.html b/404.html new file mode 100644 index 0000000000..e4309e1f02 --- /dev/null +++ b/404.html @@ -0,0 +1,24 @@ + + + + + +Page Not Found | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+ + \ No newline at end of file diff --git a/assets/css/styles.0eddb8c7.css b/assets/css/styles.0eddb8c7.css new file mode 100644 index 0000000000..c54f3ab8d6 --- /dev/null +++ b/assets/css/styles.0eddb8c7.css @@ -0,0 +1 @@ +.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}*,.loadingRing_RJI3 div{box-sizing:border-box}.authorSocials_rSDt,.authorTitle_nd0D{-webkit-box-orient:vertical;overflow:hidden}.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem;--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#0f5fe1;--ifm-color-primary-dark:##0e56cb;--ifm-color-primary-darker:##0c4cb4;--ifm-color-primary-darkest:##0b439e;--ifm-color-primary-light:##276fe4;--ifm-color-primary-lighter:##3f7fe7;--ifm-color-primary-lightest:##578fea;--ifm-code-font-size:95%;--docusaurus-highlighted-code-line-bg:#0000001a;--docusaurus-announcement-bar-height:auto;--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px;--docusaurus-blog-social-icon-size:1rem;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300)}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}html{background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;-webkit-text-size-adjust:100%;text-size-adjust:100%}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.list_eTzJ article:last-child,.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none,.tabItem_LNqP{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}.container_lyt7,.container_lyt7>svg,img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul,.tabList__CuJ{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;margin-bottom:var(--ifm-spacing-vertical);display:table!important}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){-webkit-text-decoration:none;text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_Gvgb,.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after,.searchBarContainer_NW3z.searchIndexLoading_EJ1f .searchBarLoadingRing_YnHq{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);-webkit-text-decoration:none;text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button_MlC2,.button_gV6k,.dropdown__link--active,.dropdown__link:hover,.layerComponentWip_fSEJ,.layerComponent_syzR,.link_nBo6,.link_wr7g,.menu__link:hover,.navbar__brand:hover,.navbar__link--active,.navbar__link:hover,.pagination-nav__link:hover,.pagination__link:hover,.sidebarItemLink_mo7H:hover{-webkit-text-decoration:none;text-decoration:none}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);-webkit-text-decoration:none;text-decoration:none}.content_knG7 a,.hitFooter_E9YW a,.suggestion_fB_2.cursor_eG29 mark{-webkit-text-decoration:underline;text-decoration:underline}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;pointer-events:none;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color)}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item{margin-top:0}.admonitionContent_BuS1>:last-child,.cardContainer_fWXF :last-child,.collapsibleContent_i85q p:last-child,.details_lb9f>summary>p:last-child,.footer__items,.searchResultItem_U687>h2,.tabItem_Ymn6>:last-child{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title,.title_f1Hy{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color)}.menu__caret:before,.menu__link--sublist-caret:after{content:"";height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem;filter:var(--ifm-menu-link-sublist-icon-filter)}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{left:0;opacity:0;position:fixed;top:0;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;bottom:0;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color)}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.modalH2_DhYb,.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}#nprogress,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color)}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:1rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}#nprogress .bar,.modal__zVM{left:0;top:0;position:fixed}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav{display:grid;grid-gap:var(--ifm-spacing-horizontal);gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover)}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto;padding-left:0}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]{--ifm-color-primary:#0f5fe1;--ifm-color-primary-dark:##0e56cb;--ifm-color-primary-darker:##0c4cb4;--ifm-color-primary-darkest:##0b439e;--ifm-color-primary-light:##276fe4;--ifm-color-primary-lighter:##3f7fe7;--ifm-color-primary-lightest:##578fea;--docusaurus-highlighted-code-line-bg:#0000004d}.button_MlC2,.button_gV6k{background-color:#50c3a5;border:none;border-radius:8px;color:#fff;cursor:pointer;display:inline-block;font-size:16px;font-weight:600;padding:15px 32px;text-align:center}.button_MlC2:hover,.button_gV6k:hover{background-color:#0f5fe1}.modal__zVM{align-items:center;background-color:#00000080;bottom:0;display:flex;justify-content:center;overflow-y:scroll;right:0;z-index:1000}.modalContent_zbmJ{background-color:#fff;max-height:100%;max-width:100%;width:500px}.sidebar_re4s,.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem)}.modalTitle_u975{border-bottom:2px solid #eee;padding:32px}.modalDescription_H8cB{padding:32px}.buttonBox_NbRn{text-align:left}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.contentCard_uSpk{border:2px solid #666;box-shadow:2px 2px 4px 4px #0a0a0a1a}.layerComponent_syzR{background:#43d8b24f;border:2px solid rgba(70,72,213,.539);border-radius:4px;font-weight:600}.layerComponentWip_fSEJ,.layerComponent_syzR{color:#000;font-size:10px;height:80px;margin:0 0 8px 8px;padding:8px;width:80px}.layerComponentWip_fSEJ{background-image:repeating-linear-gradient(45deg,#fff,#fff 2%,#43d8b24f 0,#43d8b24f 4%,#fff 0);border:2px dashed rgba(70,72,213,.539);border-radius:4px}.layerComponentWip_fSEJ:hover,.layerComponent_syzR:hover{background-color:#43d8b22f;color:#00f;-webkit-text-decoration:none!important;text-decoration:none!important}.chipOptional_fyWu{background-color:#892be27b}.chipMandatory_Xe7e,.chipOptional_fyWu{border-radius:8px;color:#000;font-size:8px;margin:2px 2px 0 0;max-width:fit-content;padding:2px 4px;text-align:center}.chipMandatory_Xe7e{background-color:#e2a82b94}.gradient_pRJN{background:linear-gradient(180deg,#0061ff33 20%,#50c3a5 50%,#50c3a5 80%);border-radius:16px;display:block;margin:4px}.border_XcL8{border:4px solid #0061ff;border-radius:16px;margin:4px}.bottom_ufNC{margin-bottom:16px}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}#__docusaurus-base-url-issue-banner-container,.docSidebarContainer_YfHR,.hideAction_vcyE>svg,.navbarSearchContainer_Bca1:empty,.sidebarLogo_isFc,.themedComponent_mlkZ,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark] .themedComponent--dark_xIcU,[data-theme=light] .themedComponent--light_NVdE,html:not([data-theme]) .themedComponent--light_NVdE{display:initial}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.iconExternalLink_nPIU{margin-left:.3rem}.docMainContainer_TBSr,.docRoot_UBD9{display:flex;width:100%}.docsWrapper_hBAB{display:flex;flex:1 0 auto}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;user-select:none}.hash-link:before{content:"#"}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.cardContainer_fWXF{--ifm-link-color:var(--ifm-color-emphasis-800);--ifm-link-hover-color:var(--ifm-color-emphasis-700);--ifm-link-hover-decoration:none;border:1px solid var(--ifm-color-emphasis-200);box-shadow:0 1.5px 3px 0 #00000026;transition:all var(--ifm-transition-fast) ease;transition-property:border,box-shadow}.cardContainer_fWXF:hover{border-color:var(--ifm-color-primary);box-shadow:0 3px 6px 0 #0003}.cardTitle_rnsV{font-size:1.2rem}.cardDescription_PWke{font-size:.8rem}.dropdownNavbarItemMobile_S0Fm{cursor:pointer}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}.searchBar_RVTs .dropdownMenu_qbY6{background:var(--search-local-modal-background,#f5f6f7);border-radius:6px;box-shadow:var(--search-local-modal-shadow,inset 1px 1px 0 0 #ffffff80,0 3px 8px 0 #555a64);left:auto!important;margin-top:8px;padding:var(--search-local-spacing,12px);position:relative;right:0!important;width:var(--search-local-modal-width,560px)}html[data-theme=dark] .searchBar_RVTs .dropdownMenu_qbY6{background:var(--search-local-modal-background,var(--ifm-background-color));box-shadow:var(--search-local-modal-shadow,inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309)}.searchBar_RVTs .dropdownMenu_qbY6 .suggestion_fB_2{align-items:center;background:var(--search-local-hit-background,#fff);border-radius:4px;box-shadow:var(--search-local-hit-shadow,0 1px 3px 0 #d4d9e1);color:var(--search-local-hit-color,#444950);cursor:pointer;display:flex;flex-direction:row;height:var(--search-local-hit-height,56px);padding:0 var(--search-local-spacing,12px);width:100%}.hitTree_kk6K,.noResults_l6Q3{align-items:center;display:flex}html[data-theme=dark] .dropdownMenu_qbY6 .suggestion_fB_2{background:var(--search-local-hit-background,var(--ifm-color-emphasis-100));box-shadow:var(--search-local-hit-shadow,none);color:var(--search-local-hit-color,var(--ifm-font-color-base))}.searchBar_RVTs .dropdownMenu_qbY6 .suggestion_fB_2:not(:last-child){margin-bottom:4px}.searchBar_RVTs .dropdownMenu_qbY6 .suggestion_fB_2.cursor_eG29{background-color:var(--search-local-highlight-color,var(--ifm-color-primary))}.hitFooter_E9YW a,.hitIcon_a7Zy,.hitPath_ieM4,.hitTree_kk6K,.noResultsIcon_EBY5{color:var(--search-local-muted-color,#969faf)}html[data-theme=dark] .hitIcon_a7Zy,html[data-theme=dark] .hitPath_ieM4,html[data-theme=dark] .hitTree_kk6K,html[data-theme=dark] .noResultsIcon_EBY5{color:var(--search-local-muted-color,var(--ifm-color-secondary-darkest))}.hitTree_kk6K>svg{height:var(--search-local-hit-height,56px);opacity:.5;width:24px}.hitIcon_a7Zy,.hitTree_kk6K>svg{stroke-width:var(--search-local-icon-stroke-width,1.4)}.hitAction_NqkB,.hitIcon_a7Zy{height:20px;width:20px}.hitWrapper_sAK8{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;margin:0 8px;overflow-x:hidden;width:80%}.hitWrapper_sAK8 mark{background:none;color:var(--search-local-highlight-color,var(--ifm-color-primary))}.hitTitle_vyVt{font-size:.9em}.hitPath_ieM4{font-size:.75em}.hitPath_ieM4,.hitTitle_vyVt{overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.noResults_l6Q3{flex-direction:column;justify-content:center;padding:var(--search-local-spacing,12px) 0}.noResultsIcon_EBY5{margin-bottom:var(--search-local-spacing,12px)}.hitFooter_E9YW{font-size:.85em;margin-top:var(--search-local-spacing,12px);text-align:center}.cursor_eG29 .hideAction_vcyE>svg,.tocCollapsibleContent_vkbj a{display:block}.suggestion_fB_2.cursor_eG29,.suggestion_fB_2.cursor_eG29 .hitIcon_a7Zy,.suggestion_fB_2.cursor_eG29 .hitPath_ieM4,.suggestion_fB_2.cursor_eG29 .hitTree_kk6K,.suggestion_fB_2.cursor_eG29 mark{color:var(--search-local-hit-active-color,var(--ifm-color-white))!important}.searchBarContainer_NW3z{margin-left:16px}.searchBarContainer_NW3z .searchBarLoadingRing_YnHq{display:none;left:10px;position:absolute;top:6px}.searchBarContainer_NW3z .searchClearButton_qk4g{background:none;border:none;line-height:1rem;padding:0;position:absolute;right:.8rem;top:50%;transform:translateY(-50%)}.navbar__search{position:relative}.searchIndexLoading_EJ1f .navbar__search-input{background-image:none}.searchHintContainer_Pkmr{align-items:center;display:flex;gap:4px;height:100%;justify-content:center;pointer-events:none;position:absolute;right:10px;top:0}.searchHint_iIMx{background-color:var(--ifm-navbar-search-input-background-color);border:1px solid var(--ifm-color-emphasis-500);box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-500);color:var(--ifm-navbar-search-input-placeholder-color)}html[dir=rtl] .searchHintContainer_Pkmr{left:10px;right:auto}html[dir=rtl] .searchBarContainer_NW3z .searchClearButton_qk4g{left:.8rem;right:auto}html[dir=rtl] .searchBarContainer_NW3z .searchBarLoadingRing_YnHq{left:auto;right:10px}html[dir=rtl] .navbar__search-input{padding:0 2.25em 0 .5em}.loadingRing_RJI3{display:inline-block;height:20px;opacity:var(--search-local-loading-icon-opacity,.5);position:relative;width:20px}.authorSocialIcon_XYv3,.authorSocialLink_owbf,.authorSocials_rSDt{height:var(--docusaurus-blog-social-icon-size)}.loadingRing_RJI3 div{animation:1.2s cubic-bezier(.5,0,.5,1) infinite a;border:2px solid var(--search-load-loading-icon-color,var(--ifm-navbar-search-input-color));border-color:var(--search-load-loading-icon-color,var(--ifm-navbar-search-input-color)) #0000 #0000 #0000;border-radius:50%;display:block;height:16px;margin:2px;position:absolute;width:16px}.loadingRing_RJI3 div:first-child{animation-delay:-.45s}.loadingRing_RJI3 div:nth-child(2){animation-delay:-.3s}.loadingRing_RJI3 div:nth-child(3){animation-delay:-.15s}@keyframes a{0%{transform:rotate(0)}to{transform:rotate(1turn)}}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.errorBoundaryFallback_VBag{color:red;padding:.55rem}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.sidebar_re4s{overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 2rem)}.sidebarItemTitle_pO2u{font-size:var(--ifm-h3-font-size);font-weight:var(--ifm-font-weight-bold)}.container_mt6G,.sidebarItemList_Yudw{font-size:.9rem}.sidebarItem__DBe{margin-top:.7rem}.sidebarItemLink_mo7H{color:var(--ifm-font-color-base);display:block}.sidebarItemLinkActive_I1ZP{color:var(--ifm-color-primary)!important}.yearGroupHeading_rMGB{margin-bottom:.4rem;margin-top:1.6rem}.yearGroupHeading_QT03{margin:1rem .75rem .5rem}.searchContextInput_mXoe,.searchQueryInput_CFBF{background:var(--ifm-background-color);border:var(--ifm-global-border-width) solid var(--ifm-color-content-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-font-color-base);font-size:var(--ifm-font-size-base);margin-bottom:1rem;padding:.5rem;width:100%}.authorSocialIcon_XYv3,.authorSocialLink_owbf{width:var(--docusaurus-blog-social-icon-size)}.searchResultItem_U687{border-bottom:1px solid #dfe3e8;padding:1rem 0}.searchResultItemPath_uIbk{color:var(--ifm-color-content-secondary);font-size:.8rem;margin:.5rem 0 0}.searchResultItemSummary_oZHr{font-style:italic;margin:.5rem 0 0}.heroBanner_qdFl{overflow:hidden;padding:4rem 0;position:relative;text-align:center}.buttons_AeoN{align-items:center;display:flex;justify-content:center}#marg_HODB{margin-bottom:1rem;margin-top:1rem}[data-theme=dark] .githubSvg_Uu4N,[data-theme=dark] .xSvg_y3PF{fill:var(--light)}[data-theme=light] .githubSvg_Uu4N,[data-theme=light] .xSvg_y3PF{fill:var(--dark)}.authorSocials_rSDt{align-items:center;display:flex;flex-wrap:wrap;line-clamp:1;-webkit-line-clamp:1}.authorSocialLink_owbf,.authorSocials_rSDt{line-height:0}.authorSocialLink_owbf{margin-right:.4rem}.authorImage_XqGP{--ifm-avatar-photo-size:3.6rem}.author-as-h1_n9oJ .authorImage_XqGP{--ifm-avatar-photo-size:7rem}.author-as-h2_gXvM .authorImage_XqGP{--ifm-avatar-photo-size:5.4rem}.authorDetails_lV9A{align-items:flex-start;display:flex;flex-direction:column;justify-content:space-around}.authorName_yefp{display:flex;flex-direction:row;font-size:1.1rem;line-height:1.1rem}.author-as-h1_n9oJ .authorName_yefp{display:inline;font-size:2.4rem;line-height:2.4rem}.author-as-h2_gXvM .authorName_yefp{display:inline;font-size:1.4rem;line-height:1.4rem}.authorTitle_nd0D{display:-webkit-box;font-size:.8rem;line-height:1rem;line-clamp:1;-webkit-line-clamp:1}.author-as-h1_n9oJ .authorTitle_nd0D{font-size:1.2rem;line-height:1.6rem}.author-as-h2_gXvM .authorTitle_nd0D{font-size:1rem;line-height:1.3rem}.authorBlogPostCount_iiJ5{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.8rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.authorListItem_n3yI{list-style-type:none;margin-bottom:2rem}.authorCol_Hf19{max-width:inherit!important}.imageOnlyAuthorRow_pa_O{display:flex;flex-flow:row wrap}.imageOnlyAuthorCol_G86a{margin-left:.3rem;margin-right:.3rem}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{left:0;position:absolute;top:0;fill:currentColor;height:inherit;opacity:inherit;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);-webkit-text-decoration:none;text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tag_Nnez{display:inline-block;margin:.5rem .5rem 0 1rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.lastUpdated_JAkA{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.img_ev3q{height:auto}.admonition_xJq3{margin-bottom:1em}.admonitionHeading_Gvgb{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family)}.admonitionHeading_Gvgb:not(:last-child){margin-bottom:.3rem}.admonitionHeading_Gvgb code{text-transform:none}.admonitionIcon_Rf37{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_Rf37 svg{display:inline-block;height:1.6em;width:1.6em;fill:var(--ifm-alert-foreground-color)}.tableOfContents_bqdL{overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.title_kItE{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-leading)*1.25)}@media only screen and (min-width:996px){.card_N5DL{height:100%}}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_TmdG{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_i1dp,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_TmdG:focus,.expandButton_TmdG:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);-webkit-text-decoration:none!important;text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_TmdG{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_i1dp{transform:rotate(180deg)}.docSidebarContainer_YfHR{border-right:1px solid var(--ifm-toc-border-color);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_DPk8{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_aRkj{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_TBSr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_lQrH{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_JWYK{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}.navbarSearchContainer_Bca1{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.lastUpdated_JAkA{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn,.generatedIndexPage_vN6x{max-width:75%!important}.list_eTzJ article:nth-last-child(-n+2){margin-bottom:0!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.sidebar_re4s,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block;width:max-content}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.navbarSearchContainer_Bca1{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media not (max-width:996px){.searchBar_RVTs.searchBarLeft_MXDe .dropdownMenu_qbY6{left:0!important;right:auto!important}}@media only screen and (max-width:996px){.searchQueryColumn_q7nx{max-width:60%!important}.searchContextColumn_oWAF{max-width:40%!important}}@media screen and (max-width:996px){.heroBanner_qdFl{padding:2rem}}@media only screen and (max-width:600px){.modalContent_zbmJ{height:100%}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}.navbar__search-input:not(:focus){width:2rem}.searchBar_RVTs .dropdownMenu_qbY6{max-width:calc(100vw - var(--ifm-navbar-padding-horizontal)*2);width:var(--search-local-modal-width-sm,340px)}.searchBarContainer_NW3z:not(.focused_OWtg) .searchClearButton_qk4g,.searchHintContainer_Pkmr{display:none}.title_f1Hy{font-size:2rem}}@media screen and (max-width:576px){.searchQueryColumn_q7nx{max-width:100%!important}.searchContextColumn_oWAF{max-width:100%!important;padding-left:var(--ifm-spacing-horizontal)!important}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/assets/files/clouds-public-e9ba939dfde1c0efe3a32ec6f5d1f612.yaml b/assets/files/clouds-public-e9ba939dfde1c0efe3a32ec6f5d1f612.yaml new file mode 100644 index 0000000000..01f7a2db4d --- /dev/null +++ b/assets/files/clouds-public-e9ba939dfde1c0efe3a32ec6f5d1f612.yaml @@ -0,0 +1,38 @@ +--- +public-clouds: + betacloud: + auth: + auth_url: https://api-1.betacloud.de:5000 + interface: 'public' + regions: + - name: betacloud-1 + identity_api_version: 3 + image_format: raw + block_storage_api_version: 3 + pluscloudopen: + auth: + auth_url: https://prod1.api.pco.get-cloud.io:5000 + interface: 'public' + regions: + - name: prod1 + identity_api_version: 3 + image_format: raw + block_storage_api_version: 3 + gx-scs: + auth: + auth_url: https://api.gx-scs.sovereignit.cloud:5000 + interface: 'public' + regions: + - name: RegionOne + identity_api_version: 3 + image_format: raw + block_storage_api_version: 3 + wavestack: + auth: + auth_url: https://api.wavestack.de:5000 + interface: 'public' + regions: + - name: MUC5 + identity_api_version: 3 + image_format: raw + block_storage_api_version: 3 diff --git a/assets/files/clouds.yaml-9c0c983f9c293bc5adeae683d442174e.sample b/assets/files/clouds.yaml-9c0c983f9c293bc5adeae683d442174e.sample new file mode 100644 index 0000000000..9040467c63 --- /dev/null +++ b/assets/files/clouds.yaml-9c0c983f9c293bc5adeae683d442174e.sample @@ -0,0 +1,23 @@ +--- +clouds: + betacloud: + profile: betacloud + auth: + username: USERNAME + project_name: PROJECT + project_domain_name: DOMAIN + user_domain_name: DOMAIN + pluscloudopen: + profile: pluscloudopen + auth: + username: USERNAME + project_name: PROJECT + project_domain_name: DOMAIN + user_domain_name: DOMAIN + gx-scs: + profile: gx-scs + auth: + username: u500924-USERNAME + project_name: p500924-PROJECT + project_domain_name: d500924 + user_domain_name: d500924 diff --git a/assets/images/combined_rack_visual-56539dc452d0bee6fd7c677d5117d814.jpg b/assets/images/combined_rack_visual-56539dc452d0bee6fd7c677d5117d814.jpg new file mode 100644 index 0000000000..e9278eb990 Binary files /dev/null and b/assets/images/combined_rack_visual-56539dc452d0bee6fd7c677d5117d814.jpg differ diff --git a/assets/images/disk-layout-db64866af60ef6d2c41245db78dd15d1.png b/assets/images/disk-layout-db64866af60ef6d2c41245db78dd15d1.png new file mode 100644 index 0000000000..39ccd70263 Binary files /dev/null and b/assets/images/disk-layout-db64866af60ef6d2c41245db78dd15d1.png differ diff --git a/assets/images/flavors-1-bd8d085759b264b3e58020d1390803fd.png b/assets/images/flavors-1-bd8d085759b264b3e58020d1390803fd.png new file mode 100644 index 0000000000..ace5ca0fb4 Binary files /dev/null and b/assets/images/flavors-1-bd8d085759b264b3e58020d1390803fd.png differ diff --git a/assets/images/flavors-2-d9a87ab2a63ed62ace4303facc069b8b.png b/assets/images/flavors-2-d9a87ab2a63ed62ace4303facc069b8b.png new file mode 100644 index 0000000000..9c6bc97809 Binary files /dev/null and b/assets/images/flavors-2-d9a87ab2a63ed62ace4303facc069b8b.png differ diff --git a/assets/images/getting_started_openstack_anim-d88d134eff244cf8891c5ca1efcfc65a.gif b/assets/images/getting_started_openstack_anim-d88d134eff244cf8891c5ca1efcfc65a.gif new file mode 100644 index 0000000000..2ef81b7e50 Binary files /dev/null and b/assets/images/getting_started_openstack_anim-d88d134eff244cf8891c5ca1efcfc65a.gif differ diff --git a/assets/images/github-failed-dco-82f9dafea83c36769069087ceb522cdc.png b/assets/images/github-failed-dco-82f9dafea83c36769069087ceb522cdc.png new file mode 100644 index 0000000000..a21febb629 Binary files /dev/null and b/assets/images/github-failed-dco-82f9dafea83c36769069087ceb522cdc.png differ diff --git a/assets/images/harbor_migration-15d83bf7e5b37c0bdcb698280dde0684.png b/assets/images/harbor_migration-15d83bf7e5b37c0bdcb698280dde0684.png new file mode 100644 index 0000000000..52ee905bb9 Binary files /dev/null and b/assets/images/harbor_migration-15d83bf7e5b37c0bdcb698280dde0684.png differ diff --git a/assets/images/image-01d5564077ed43bda1d921e522df7dd7.png b/assets/images/image-01d5564077ed43bda1d921e522df7dd7.png new file mode 100644 index 0000000000..6bf653030f Binary files /dev/null and b/assets/images/image-01d5564077ed43bda1d921e522df7dd7.png differ diff --git a/assets/images/image-123702bb74539962d7c6839715583f29.png b/assets/images/image-123702bb74539962d7c6839715583f29.png new file mode 100644 index 0000000000..10e845bc52 Binary files /dev/null and b/assets/images/image-123702bb74539962d7c6839715583f29.png differ diff --git a/assets/images/inventory-reconciler-acd822767003069a8935e016081383a5.png b/assets/images/inventory-reconciler-acd822767003069a8935e016081383a5.png new file mode 100644 index 0000000000..8df13374af Binary files /dev/null and b/assets/images/inventory-reconciler-acd822767003069a8935e016081383a5.png differ diff --git a/assets/images/issue-6cc9ac7387e0589d625dded707510641.png b/assets/images/issue-6cc9ac7387e0589d625dded707510641.png new file mode 100644 index 0000000000..69137a9de8 Binary files /dev/null and b/assets/images/issue-6cc9ac7387e0589d625dded707510641.png differ diff --git a/assets/images/jaeger-91a4b48820447709f604d72c396cacf8.png b/assets/images/jaeger-91a4b48820447709f604d72c396cacf8.png new file mode 100644 index 0000000000..a37e429f03 Binary files /dev/null and b/assets/images/jaeger-91a4b48820447709f604d72c396cacf8.png differ diff --git a/assets/images/monitoring_scs_detailed-593b1b8ce16c1873883e38a381e02faa.png b/assets/images/monitoring_scs_detailed-593b1b8ce16c1873883e38a381e02faa.png new file mode 100644 index 0000000000..3ddfc4cfb7 Binary files /dev/null and b/assets/images/monitoring_scs_detailed-593b1b8ce16c1873883e38a381e02faa.png differ diff --git a/assets/images/monitoring_scs_experimental-3846febea17c1ecf9baaa074ee9b1a10.png b/assets/images/monitoring_scs_experimental-3846febea17c1ecf9baaa074ee9b1a10.png new file mode 100644 index 0000000000..245954e08c Binary files /dev/null and b/assets/images/monitoring_scs_experimental-3846febea17c1ecf9baaa074ee9b1a10.png differ diff --git a/assets/images/monitoring_scs_high_level-50f86d39d750e803a31513fb32942e41.png b/assets/images/monitoring_scs_high_level-50f86d39d750e803a31513fb32942e41.png new file mode 100644 index 0000000000..ccdcb69e3a Binary files /dev/null and b/assets/images/monitoring_scs_high_level-50f86d39d750e803a31513fb32942e41.png differ diff --git a/assets/images/openstackclusterstackrelease-controller-7116cf20417bba3296181501c313ed65.png b/assets/images/openstackclusterstackrelease-controller-7116cf20417bba3296181501c313ed65.png new file mode 100644 index 0000000000..da868279bd Binary files /dev/null and b/assets/images/openstackclusterstackrelease-controller-7116cf20417bba3296181501c313ed65.png differ diff --git a/assets/images/openstacknodeimagerelease-controller-0b39df07c1e9d7a4e028f0795dd056d8.png b/assets/images/openstacknodeimagerelease-controller-0b39df07c1e9d7a4e028f0795dd056d8.png new file mode 100644 index 0000000000..a232597436 Binary files /dev/null and b/assets/images/openstacknodeimagerelease-controller-0b39df07c1e9d7a4e028f0795dd056d8.png differ diff --git a/assets/images/overview.drawio-f6a92d48381c9de5fcbbd5205e022b0a.png b/assets/images/overview.drawio-f6a92d48381c9de5fcbbd5205e022b0a.png new file mode 100644 index 0000000000..11b7df57ed Binary files /dev/null and b/assets/images/overview.drawio-f6a92d48381c9de5fcbbd5205e022b0a.png differ diff --git a/assets/images/python-osism.drawio-19e90813de60b4afa58bc7ee4a3aeae8.png b/assets/images/python-osism.drawio-19e90813de60b4afa58bc7ee4a3aeae8.png new file mode 100644 index 0000000000..7772f1484e Binary files /dev/null and b/assets/images/python-osism.drawio-19e90813de60b4afa58bc7ee4a3aeae8.png differ diff --git a/assets/images/s1-domains-projects-lecture-fig-1-85eace851f17244e8c410d319fd55cc4.svg b/assets/images/s1-domains-projects-lecture-fig-1-85eace851f17244e8c410d319fd55cc4.svg new file mode 100644 index 0000000000..f2f50a46b5 --- /dev/null +++ b/assets/images/s1-domains-projects-lecture-fig-1-85eace851f17244e8c410d319fd55cc4.svg @@ -0,0 +1,749 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/s1-fundamental-lecture-fig-1-8aac37d55a5191ee7a290c7dbd100d01.svg b/assets/images/s1-fundamental-lecture-fig-1-8aac37d55a5191ee7a290c7dbd100d01.svg new file mode 100644 index 0000000000..8c50fe95e0 --- /dev/null +++ b/assets/images/s1-fundamental-lecture-fig-1-8aac37d55a5191ee7a290c7dbd100d01.svg @@ -0,0 +1,830 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/s1-rhoso-lecture-fig-1-bf5bf84557b4600b84d1467713715582.svg b/assets/images/s1-rhoso-lecture-fig-1-bf5bf84557b4600b84d1467713715582.svg new file mode 100644 index 0000000000..4a1b674e6e --- /dev/null +++ b/assets/images/s1-rhoso-lecture-fig-1-bf5bf84557b4600b84d1467713715582.svg @@ -0,0 +1,804 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/s6-services-lecture-fig-1-ec3163f80b85ce6087ada1336c259ac7.svg b/assets/images/s6-services-lecture-fig-1-ec3163f80b85ce6087ada1336c259ac7.svg new file mode 100644 index 0000000000..502d088099 --- /dev/null +++ b/assets/images/s6-services-lecture-fig-1-ec3163f80b85ce6087ada1336c259ac7.svg @@ -0,0 +1,825 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/screenshot1-c880f78ba33fc0577dce811dc2e42724.png b/assets/images/screenshot1-c880f78ba33fc0577dce811dc2e42724.png new file mode 100644 index 0000000000..87d3beb87c Binary files /dev/null and b/assets/images/screenshot1-c880f78ba33fc0577dce811dc2e42724.png differ diff --git a/assets/images/scs_automated_pentesting_workflow-14a9ffdbf77267915ddcc95b954c4f1a.png b/assets/images/scs_automated_pentesting_workflow-14a9ffdbf77267915ddcc95b954c4f1a.png new file mode 100644 index 0000000000..1a1f5f9aac Binary files /dev/null and b/assets/images/scs_automated_pentesting_workflow-14a9ffdbf77267915ddcc95b954c4f1a.png differ diff --git a/assets/images/service-with-docker.drawio-21d9ff770c727c43ab477f857b5017e2.png b/assets/images/service-with-docker.drawio-21d9ff770c727c43ab477f857b5017e2.png new file mode 100644 index 0000000000..d07f19168a Binary files /dev/null and b/assets/images/service-with-docker.drawio-21d9ff770c727c43ab477f857b5017e2.png differ diff --git a/assets/images/service-with-kubernetes.drawio-9500d1fb61ca22792d8277f9f06e58ce.png b/assets/images/service-with-kubernetes.drawio-9500d1fb61ca22792d8277f9f06e58ce.png new file mode 100644 index 0000000000..c9ba4c4835 Binary files /dev/null and b/assets/images/service-with-kubernetes.drawio-9500d1fb61ca22792d8277f9f06e58ce.png differ diff --git a/assets/images/syself-cluster-stacks-web-61b777e4fdfc3357ad1f7f8e4b6e1864.png b/assets/images/syself-cluster-stacks-web-61b777e4fdfc3357ad1f7f8e4b6e1864.png new file mode 100644 index 0000000000..df43550371 Binary files /dev/null and b/assets/images/syself-cluster-stacks-web-61b777e4fdfc3357ad1f7f8e4b6e1864.png differ diff --git a/assets/images/tilt-4af6fa61d9a6a82abdfa1c82985f182e.png b/assets/images/tilt-4af6fa61d9a6a82abdfa1c82985f182e.png new file mode 100644 index 0000000000..a00dec81f1 Binary files /dev/null and b/assets/images/tilt-4af6fa61d9a6a82abdfa1c82985f182e.png differ diff --git a/assets/images/tilt-5733a9f1bf4409991abcf6d96d8a13bd.png b/assets/images/tilt-5733a9f1bf4409991abcf6d96d8a13bd.png new file mode 100644 index 0000000000..2235b62942 Binary files /dev/null and b/assets/images/tilt-5733a9f1bf4409991abcf6d96d8a13bd.png differ diff --git a/assets/images/user_data_backups_figure1-988dbd55659509cc1ddc9f68f2437648.png b/assets/images/user_data_backups_figure1-988dbd55659509cc1ddc9f68f2437648.png new file mode 100644 index 0000000000..1be96dd222 Binary files /dev/null and b/assets/images/user_data_backups_figure1-988dbd55659509cc1ddc9f68f2437648.png differ diff --git a/assets/images/zuul-hanging-jobs-in-a-pipeline-047d29fda9946dd80cebb88778249bce.png b/assets/images/zuul-hanging-jobs-in-a-pipeline-047d29fda9946dd80cebb88778249bce.png new file mode 100644 index 0000000000..129ffce4d1 Binary files /dev/null and b/assets/images/zuul-hanging-jobs-in-a-pipeline-047d29fda9946dd80cebb88778249bce.png differ diff --git a/assets/js/0047ab5d.5743080d.js b/assets/js/0047ab5d.5743080d.js new file mode 100644 index 0000000000..e900088cc3 --- /dev/null +++ b/assets/js/0047ab5d.5743080d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[15058],{9691:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>a,contentTitle:()=>r,default:()=>l,frontMatter:()=>c,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"iaas/guides/configuration-guide/services/index","title":"Services","description":"This section contains the documentation of the Ansible collection","source":"@site/docs/02-iaas/guides/configuration-guide/services/index.md","sourceDirName":"02-iaas/guides/configuration-guide/services","slug":"/iaas/guides/configuration-guide/services/","permalink":"/docs/iaas/guides/configuration-guide/services/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/services/index.md","tags":[],"version":"current","sidebarPosition":50,"frontMatter":{"sidebar_label":"Services","sidebar_position":50},"sidebar":"docs","previous":{"title":"User","permalink":"/docs/iaas/guides/configuration-guide/commons/user"},"next":{"title":"Chrony","permalink":"/docs/iaas/guides/configuration-guide/services/chrony"}}');var t=s(74848),o=s(28453);const c={sidebar_label:"Services",sidebar_position:50},r="Services",a={},d=[];function u(e){const i={a:"a",h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.header,{children:(0,t.jsx)(i.h1,{id:"services",children:"Services"})}),"\n",(0,t.jsxs)(i.p,{children:["This section contains the documentation of the Ansible collection\n",(0,t.jsx)(i.a,{href:"https://github.com/osism/ansible-collection-services",children:"osism.services"}),"."]})]})}function l(e={}){const{wrapper:i}={...(0,o.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,i,s)=>{s.d(i,{R:()=>c,x:()=>r});var n=s(96540);const t={},o=n.createContext(t);function c(e){const i=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),n.createElement(o.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0050251a.2b225ffc.js b/assets/js/0050251a.2b225ffc.js new file mode 100644 index 0000000000..eb5aae4739 --- /dev/null +++ b/assets/js/0050251a.2b225ffc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[11945],{92732:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>s,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"index","title":"Documentation for SCS Contributors","description":"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.","source":"@site/contributor-docs/index.md","sourceDirName":".","slug":"/","permalink":"/contributor-docs/","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"devDocs","previous":{"title":"SCS Conformance Test Implementation Guide","permalink":"/contributor-docs/development/tests/test-implementation-guide"},"next":{"title":"Identity Federation in SCS","permalink":"/contributor-docs/operations/iam/identity-federation-in-scs"}}');var r=n(74848),i=n(28453);const s={},a="Documentation for SCS Contributors",c={},d=[];function u(t){const e={a:"a",h1:"h1",header:"header",p:"p",...(0,i.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"documentation-for-scs-contributors",children:"Documentation for SCS Contributors"})}),"\n",(0,r.jsx)(e.p,{children:"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."}),"\n",(0,r.jsxs)(e.p,{children:["If you want to contribute you can reach out to us via our ",(0,r.jsx)(e.a,{href:"https://matrix.to/#/!TiDqlLmEUaXqTemaLc:matrix.org?via=matrix.org",children:"Matrix Channel"}),"."]})]})}function l(t={}){const{wrapper:e}={...(0,i.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(u,{...t})}):u(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>s,x:()=>a});var o=n(96540);const r={},i=o.createContext(r);function s(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:s(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/0058b4c6.7244ccd9.js b/assets/js/0058b4c6.7244ccd9.js new file mode 100644 index 0000000000..979fa183fa --- /dev/null +++ b/assets/js/0058b4c6.7244ccd9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[90849],{86164:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"docs":[{"type":"link","label":"Introduction","href":"/docs/","docId":"index","unlisted":false},{"type":"category","label":"IaaS Layer","items":[{"type":"category","label":"Guides","items":[{"type":"category","label":"Concept Guide","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Components","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Ceph","href":"/docs/iaas/guides/concept-guide/components/ceph","docId":"iaas/guides/concept-guide/components/ceph","unlisted":false},{"type":"link","label":"Cluster API","href":"/docs/iaas/guides/concept-guide/components/clusterapi","docId":"iaas/guides/concept-guide/components/clusterapi","unlisted":false},{"type":"link","label":"Gardener","href":"/docs/iaas/guides/concept-guide/components/gardener","docId":"iaas/guides/concept-guide/components/gardener","unlisted":false},{"type":"link","label":"Ironic","href":"/docs/iaas/guides/concept-guide/components/ironic","docId":"iaas/guides/concept-guide/components/ironic","unlisted":false},{"type":"link","label":"K3S","href":"/docs/iaas/guides/concept-guide/components/k3s","docId":"iaas/guides/concept-guide/components/k3s","unlisted":false},{"type":"link","label":"Keycloak","href":"/docs/iaas/guides/concept-guide/components/keycloak","docId":"iaas/guides/concept-guide/components/keycloak","unlisted":false},{"type":"link","label":"Netdata","href":"/docs/iaas/guides/concept-guide/components/netdata","docId":"iaas/guides/concept-guide/components/netdata","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/iaas/guides/concept-guide/components/openstack","docId":"iaas/guides/concept-guide/components/openstack","unlisted":false},{"type":"link","label":"Prometheus & Grafana","href":"/docs/iaas/guides/concept-guide/components/prometheus","docId":"iaas/guides/concept-guide/components/prometheus","unlisted":false},{"type":"link","label":"SONiC & OVN","href":"/docs/iaas/guides/concept-guide/components/sonic","docId":"iaas/guides/concept-guide/components/sonic","unlisted":false},{"type":"link","label":"Teleport","href":"/docs/iaas/guides/concept-guide/components/teleport","docId":"iaas/guides/concept-guide/components/teleport","unlisted":false}],"href":"/docs/iaas/guides/concept-guide/components/"},{"type":"link","label":"Layers in a cluster","href":"/docs/iaas/guides/concept-guide/layers","docId":"iaas/guides/concept-guide/layers","unlisted":false},{"type":"link","label":"Nodes in a cluster","href":"/docs/iaas/guides/concept-guide/nodes","docId":"iaas/guides/concept-guide/nodes","unlisted":false},{"type":"link","label":"Cluster design","href":"/docs/iaas/guides/concept-guide/design","docId":"iaas/guides/concept-guide/design","unlisted":false},{"type":"link","label":"Use cases","href":"/docs/iaas/guides/concept-guide/use-cases","docId":"iaas/guides/concept-guide/use-cases","unlisted":false},{"type":"link","label":"Hardware Bill of Materials","href":"/docs/iaas/guides/concept-guide/hardware-bom","docId":"iaas/guides/concept-guide/hardware-bom","unlisted":false}],"href":"/docs/iaas/guides/concept-guide/"},{"type":"category","label":"Deploy Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Seed","href":"/docs/iaas/guides/deploy-guide/seed","docId":"iaas/guides/deploy-guide/seed","unlisted":false},{"type":"link","label":"Manager","href":"/docs/iaas/guides/deploy-guide/manager","docId":"iaas/guides/deploy-guide/manager","unlisted":false},{"type":"link","label":"Provisioning","href":"/docs/iaas/guides/deploy-guide/provisioning","docId":"iaas/guides/deploy-guide/provisioning","unlisted":false},{"type":"link","label":"Bootstrap","href":"/docs/iaas/guides/deploy-guide/bootstrap","docId":"iaas/guides/deploy-guide/bootstrap","unlisted":false},{"type":"link","label":"Rookify (technical preview)","href":"/docs/iaas/guides/deploy-guide/rookify","docId":"iaas/guides/deploy-guide/rookify","unlisted":false},{"type":"category","label":"Services","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Infrastructure","href":"/docs/iaas/guides/deploy-guide/services/infrastructure","docId":"iaas/guides/deploy-guide/services/infrastructure","unlisted":false},{"type":"link","label":"Kubernetes","href":"/docs/iaas/guides/deploy-guide/services/kubernetes","docId":"iaas/guides/deploy-guide/services/kubernetes","unlisted":false},{"type":"link","label":"Network","href":"/docs/iaas/guides/deploy-guide/services/network","docId":"iaas/guides/deploy-guide/services/network","unlisted":false},{"type":"link","label":"Logging & Monitoring","href":"/docs/iaas/guides/deploy-guide/services/logging-monitoring","docId":"iaas/guides/deploy-guide/services/logging-monitoring","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/iaas/guides/deploy-guide/services/ceph","docId":"iaas/guides/deploy-guide/services/ceph","unlisted":false},{"type":"link","label":"Ceph via Rook (technical preview)","href":"/docs/iaas/guides/deploy-guide/services/rook","docId":"iaas/guides/deploy-guide/services/rook","unlisted":false},{"type":"link","label":"Migrate Ceph-Ansible via Rookify (technical preview)","href":"/docs/iaas/guides/deploy-guide/services/rookify","docId":"iaas/guides/deploy-guide/services/rookify","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/iaas/guides/deploy-guide/services/openstack","docId":"iaas/guides/deploy-guide/services/openstack","unlisted":false}],"href":"/docs/iaas/guides/deploy-guide/services/"},{"type":"category","label":"Examples","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cloud in a Box","href":"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box","docId":"iaas/guides/deploy-guide/examples/cloud-in-a-box","unlisted":false},{"type":"link","label":"Testbed","href":"/docs/iaas/guides/deploy-guide/examples/testbed","docId":"iaas/guides/deploy-guide/examples/testbed","unlisted":false}],"href":"/docs/iaas/guides/deploy-guide/examples/"}],"href":"/docs/iaas/guides/deploy-guide/"},{"type":"category","label":"Upgrade Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Manager","href":"/docs/iaas/guides/upgrade-guide/manager","docId":"iaas/guides/upgrade-guide/manager","unlisted":false},{"type":"link","label":"Network","href":"/docs/iaas/guides/upgrade-guide/network","docId":"iaas/guides/upgrade-guide/network","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/iaas/guides/upgrade-guide/ceph","docId":"iaas/guides/upgrade-guide/ceph","unlisted":false},{"type":"link","label":"Docker","href":"/docs/iaas/guides/upgrade-guide/docker","docId":"iaas/guides/upgrade-guide/docker","unlisted":false},{"type":"link","label":"Infrastructure","href":"/docs/iaas/guides/upgrade-guide/infrastructure","docId":"iaas/guides/upgrade-guide/infrastructure","unlisted":false},{"type":"link","label":"Logging & Monitoring","href":"/docs/iaas/guides/upgrade-guide/logging-monitoring","docId":"iaas/guides/upgrade-guide/logging-monitoring","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/iaas/guides/upgrade-guide/openstack","docId":"iaas/guides/upgrade-guide/openstack","unlisted":false}],"href":"/docs/iaas/guides/upgrade-guide/"},{"type":"category","label":"Configuration Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configuration repository","href":"/docs/iaas/guides/configuration-guide/configuration-repository","docId":"iaas/guides/configuration-guide/configuration-repository","unlisted":false},{"type":"link","label":"Inventory","href":"/docs/iaas/guides/configuration-guide/inventory","docId":"iaas/guides/configuration-guide/inventory","unlisted":false},{"type":"link","label":"Manager","href":"/docs/iaas/guides/configuration-guide/manager","docId":"iaas/guides/configuration-guide/manager","unlisted":false},{"type":"link","label":"Network","href":"/docs/iaas/guides/configuration-guide/network","docId":"iaas/guides/configuration-guide/network","unlisted":false},{"type":"link","label":"Proxy","href":"/docs/iaas/guides/configuration-guide/proxy","docId":"iaas/guides/configuration-guide/proxy","unlisted":false},{"type":"link","label":"Loadbalancer","href":"/docs/iaas/guides/configuration-guide/loadbalancer","docId":"iaas/guides/configuration-guide/loadbalancer","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/iaas/guides/configuration-guide/ceph","docId":"iaas/guides/configuration-guide/ceph","unlisted":false},{"type":"category","label":"OpenStack","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Aodh","href":"/docs/iaas/guides/configuration-guide/openstack/aodh","docId":"iaas/guides/configuration-guide/openstack/aodh","unlisted":false},{"type":"link","label":"Barbican","href":"/docs/iaas/guides/configuration-guide/openstack/barbican","docId":"iaas/guides/configuration-guide/openstack/barbican","unlisted":false},{"type":"link","label":"Ceilometer","href":"/docs/iaas/guides/configuration-guide/openstack/ceilometer","docId":"iaas/guides/configuration-guide/openstack/ceilometer","unlisted":false},{"type":"link","label":"Cinder","href":"/docs/iaas/guides/configuration-guide/openstack/cinder","docId":"iaas/guides/configuration-guide/openstack/cinder","unlisted":false},{"type":"link","label":"Designate","href":"/docs/iaas/guides/configuration-guide/openstack/designate","docId":"iaas/guides/configuration-guide/openstack/designate","unlisted":false},{"type":"link","label":"Glance","href":"/docs/iaas/guides/configuration-guide/openstack/glance","docId":"iaas/guides/configuration-guide/openstack/glance","unlisted":false},{"type":"link","label":"Heat","href":"/docs/iaas/guides/configuration-guide/openstack/heat","docId":"iaas/guides/configuration-guide/openstack/heat","unlisted":false},{"type":"link","label":"Horizon","href":"/docs/iaas/guides/configuration-guide/openstack/horizon","docId":"iaas/guides/configuration-guide/openstack/horizon","unlisted":false},{"type":"link","label":"Ironic","href":"/docs/iaas/guides/configuration-guide/openstack/ironic","docId":"iaas/guides/configuration-guide/openstack/ironic","unlisted":false},{"type":"link","label":"Keystone","href":"/docs/iaas/guides/configuration-guide/openstack/keystone","docId":"iaas/guides/configuration-guide/openstack/keystone","unlisted":false},{"type":"link","label":"Magnum","href":"/docs/iaas/guides/configuration-guide/openstack/magnum","docId":"iaas/guides/configuration-guide/openstack/magnum","unlisted":false},{"type":"link","label":"Manila","href":"/docs/iaas/guides/configuration-guide/openstack/manila","docId":"iaas/guides/configuration-guide/openstack/manila","unlisted":false},{"type":"link","label":"Neutron","href":"/docs/iaas/guides/configuration-guide/openstack/neutron","docId":"iaas/guides/configuration-guide/openstack/neutron","unlisted":false},{"type":"link","label":"Nova","href":"/docs/iaas/guides/configuration-guide/openstack/nova","docId":"iaas/guides/configuration-guide/openstack/nova","unlisted":false},{"type":"link","label":"Octavia","href":"/docs/iaas/guides/configuration-guide/openstack/octavia","docId":"iaas/guides/configuration-guide/openstack/octavia","unlisted":false},{"type":"link","label":"Placement","href":"/docs/iaas/guides/configuration-guide/openstack/placement","docId":"iaas/guides/configuration-guide/openstack/placement","unlisted":false},{"type":"link","label":"Skyline","href":"/docs/iaas/guides/configuration-guide/openstack/skyline","docId":"iaas/guides/configuration-guide/openstack/skyline","unlisted":false}],"href":"/docs/iaas/guides/configuration-guide/openstack/"},{"type":"link","label":"Ceph via Rook (technical preview)","href":"/docs/iaas/guides/configuration-guide/rook","docId":"iaas/guides/configuration-guide/rook","unlisted":false},{"type":"link","label":"Rookify (technical preview)","href":"/docs/iaas/guides/configuration-guide/rookify","docId":"iaas/guides/configuration-guide/rookify","unlisted":false},{"type":"category","label":"Commons","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Certificates","href":"/docs/iaas/guides/configuration-guide/commons/certificates","docId":"iaas/guides/configuration-guide/commons/certificates","unlisted":false},{"type":"link","label":"Packages","href":"/docs/iaas/guides/configuration-guide/commons/packages","docId":"iaas/guides/configuration-guide/commons/packages","unlisted":false},{"type":"link","label":"Resolvconf","href":"/docs/iaas/guides/configuration-guide/commons/resolvconf","docId":"iaas/guides/configuration-guide/commons/resolvconf","unlisted":false},{"type":"link","label":"Services","href":"/docs/iaas/guides/configuration-guide/commons/services","docId":"iaas/guides/configuration-guide/commons/services","unlisted":false},{"type":"link","label":"SSH Config","href":"/docs/iaas/guides/configuration-guide/commons/sshconfig","docId":"iaas/guides/configuration-guide/commons/sshconfig","unlisted":false},{"type":"link","label":"Sysctl","href":"/docs/iaas/guides/configuration-guide/commons/sysctl","docId":"iaas/guides/configuration-guide/commons/sysctl","unlisted":false},{"type":"link","label":"Timezone","href":"/docs/iaas/guides/configuration-guide/commons/timezone","docId":"iaas/guides/configuration-guide/commons/timezone","unlisted":false},{"type":"link","label":"User","href":"/docs/iaas/guides/configuration-guide/commons/user","docId":"iaas/guides/configuration-guide/commons/user","unlisted":false}],"href":"/docs/iaas/guides/configuration-guide/commons/"},{"type":"category","label":"Services","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Chrony","href":"/docs/iaas/guides/configuration-guide/services/chrony","docId":"iaas/guides/configuration-guide/services/chrony","unlisted":false},{"type":"link","label":"Docker","href":"/docs/iaas/guides/configuration-guide/services/docker","docId":"iaas/guides/configuration-guide/services/docker","unlisted":false},{"type":"link","label":"Tuned","href":"/docs/iaas/guides/configuration-guide/services/tuned","docId":"iaas/guides/configuration-guide/services/tuned","unlisted":false}],"href":"/docs/iaas/guides/configuration-guide/services/"},{"type":"link","label":"Validations","href":"/docs/iaas/guides/configuration-guide/validations/","docId":"iaas/guides/configuration-guide/validations/index","unlisted":false}],"href":"/docs/iaas/guides/configuration-guide/"},{"type":"category","label":"Operations Guide","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Manager","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Apply","href":"/docs/iaas/guides/operations-guide/manager/apply","docId":"iaas/guides/operations-guide/manager/apply","unlisted":false},{"type":"link","label":"Console","href":"/docs/iaas/guides/operations-guide/manager/console","docId":"iaas/guides/operations-guide/manager/console","unlisted":false},{"type":"link","label":"Get","href":"/docs/iaas/guides/operations-guide/manager/get","docId":"iaas/guides/operations-guide/manager/get","unlisted":false},{"type":"link","label":"Logging","href":"/docs/iaas/guides/operations-guide/manager/log","docId":"iaas/guides/operations-guide/manager/log","unlisted":false},{"type":"link","label":"Task","href":"/docs/iaas/guides/operations-guide/manager/task","docId":"iaas/guides/operations-guide/manager/task","unlisted":false}],"href":"/docs/iaas/guides/operations-guide/manager/"},{"type":"link","label":"Ceph","href":"/docs/iaas/guides/operations-guide/ceph","docId":"iaas/guides/operations-guide/ceph","unlisted":false},{"type":"link","label":"Infrastructure","href":"/docs/iaas/guides/operations-guide/infrastructure","docId":"iaas/guides/operations-guide/infrastructure","unlisted":false},{"type":"link","label":"Network","href":"/docs/iaas/guides/operations-guide/network","docId":"iaas/guides/operations-guide/network","unlisted":false},{"type":"category","label":"OpenStack","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Tools","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Image Manager","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Automated updates","href":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","docId":"iaas/guides/operations-guide/openstack/tools/image-manager/update","unlisted":false}],"href":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/"},{"type":"link","label":"Flavor Manager","href":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","docId":"iaas/guides/operations-guide/openstack/tools/flavor-manager","unlisted":false},{"type":"link","label":"Resource Manager","href":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","docId":"iaas/guides/operations-guide/openstack/tools/resource-manager","unlisted":false},{"type":"link","label":"Project Manager","href":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","docId":"iaas/guides/operations-guide/openstack/tools/project-manager","unlisted":false},{"type":"link","label":"Sandbox Manager","href":"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager","docId":"iaas/guides/operations-guide/openstack/tools/sandbox-manager","unlisted":false},{"type":"link","label":"Simple Stress","href":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","docId":"iaas/guides/operations-guide/openstack/tools/simple-stress","unlisted":false},{"type":"link","label":"OpenStack Health Monitor","href":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","docId":"iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","unlisted":false}],"href":"/docs/iaas/guides/operations-guide/openstack/tools/"},{"type":"link","label":"Cinder","href":"/docs/iaas/guides/operations-guide/openstack/cinder","docId":"iaas/guides/operations-guide/openstack/cinder","unlisted":false},{"type":"link","label":"Keystone","href":"/docs/iaas/guides/operations-guide/openstack/keystone","docId":"iaas/guides/operations-guide/openstack/keystone","unlisted":false},{"type":"link","label":"Neutron","href":"/docs/iaas/guides/operations-guide/openstack/neutron","docId":"iaas/guides/operations-guide/openstack/neutron","unlisted":false},{"type":"link","label":"Nova","href":"/docs/iaas/guides/operations-guide/openstack/nova","docId":"iaas/guides/operations-guide/openstack/nova","unlisted":false},{"type":"link","label":"Octavia","href":"/docs/iaas/guides/operations-guide/openstack/octavia","docId":"iaas/guides/operations-guide/openstack/octavia","unlisted":false}],"href":"/docs/iaas/guides/operations-guide/openstack/"},{"type":"link","label":"Ceph via Rook (technical preview)","href":"/docs/iaas/guides/operations-guide/rook","docId":"iaas/guides/operations-guide/rook","unlisted":false},{"type":"link","label":"Rookify (technical preview)","href":"/docs/iaas/guides/operations-guide/rookify","docId":"iaas/guides/operations-guide/rookify","unlisted":false}],"href":"/docs/iaas/guides/operations-guide/"},{"type":"category","label":"Troubleshooting Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Manager","href":"/docs/iaas/guides/troubleshooting-guide/manager","docId":"iaas/guides/troubleshooting-guide/manager","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/iaas/guides/troubleshooting-guide/openstack","docId":"iaas/guides/troubleshooting-guide/openstack","unlisted":false},{"type":"link","label":"Rookify (technical preview)","href":"/docs/iaas/guides/troubleshooting-guide/rookify","docId":"iaas/guides/troubleshooting-guide/rookify","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/iaas/guides/troubleshooting-guide/ceph","docId":"iaas/guides/troubleshooting-guide/ceph","unlisted":false}],"href":"/docs/iaas/guides/troubleshooting-guide/"},{"type":"link","label":"Guides","href":"/docs/iaas/guides/","docId":"iaas/guides/index","unlisted":false},{"type":"category","label":"User Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Migrate from VMware ESXi to OpenStack","href":"/docs/iaas/guides/user-guide/migration-vmware-esxi","docId":"iaas/guides/user-guide/migration-vmware-esxi","unlisted":false},{"type":"category","label":"OpenStack","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Install instance from ISO image","href":"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso","docId":"iaas/guides/user-guide/openstack/install-instance-from-iso","unlisted":false},{"type":"link","label":"Client","href":"/docs/iaas/guides/user-guide/openstack/openstackclient","docId":"iaas/guides/user-guide/openstack/openstackclient","unlisted":false},{"type":"link","label":"Security groups","href":"/docs/iaas/guides/user-guide/openstack/security-groups","docId":"iaas/guides/user-guide/openstack/security-groups","unlisted":false},{"type":"link","label":"User Data Backups","href":"/docs/iaas/guides/user-guide/openstack/user-data-backups","docId":"iaas/guides/user-guide/openstack/user-data-backups","unlisted":false}],"href":"/docs/iaas/guides/user-guide/openstack/"},{"type":"link","label":"Best Practise: How to configure and use security groups","href":"/docs/iaas/guides/user-guide/security-groups/","docId":"iaas/guides/user-guide/security-groups/security-groups","unlisted":false},{"type":"link","label":"User Data Backups","href":"/docs/iaas/guides/user-guide/user-data-backups","docId":"iaas/guides/user-guide/user-data-backups","unlisted":false}],"href":"/docs/iaas/guides/user-guide/"},{"type":"category","label":"Other Guides","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Cloud in a Box Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Running on a virtual machine","href":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","docId":"iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","unlisted":false}],"href":"/docs/iaas/guides/other-guides/cloud-in-a-box/"},{"type":"link","label":"Contributor Guide","href":"/docs/iaas/guides/other-guides/contributor-guide","docId":"iaas/guides/other-guides/contributor-guide","unlisted":false},{"type":"category","label":"Developer Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Releases","href":"/docs/iaas/guides/other-guides/developer-guide/releases","docId":"iaas/guides/other-guides/developer-guide/releases","unlisted":false},{"type":"link","label":"Scripts","href":"/docs/iaas/guides/other-guides/developer-guide/scripts","docId":"iaas/guides/other-guides/developer-guide/scripts","unlisted":false},{"type":"link","label":"Style Guide","href":"/docs/iaas/guides/other-guides/developer-guide/style-guide","docId":"iaas/guides/other-guides/developer-guide/style-guide","unlisted":false},{"type":"link","label":"Zuul CI","href":"/docs/iaas/guides/other-guides/developer-guide/zuul","docId":"iaas/guides/other-guides/developer-guide/zuul","unlisted":false}],"href":"/docs/iaas/guides/other-guides/developer-guide/"},{"type":"link","label":"Testbed Guide","href":"/docs/iaas/guides/other-guides/testbed","docId":"iaas/guides/other-guides/testbed","unlisted":false}],"href":"/docs/iaas/guides/other-guides/"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Components","items":[{"type":"category","label":"Openstack Image Manager","items":[{"type":"link","label":"Automated updates","href":"/docs/iaas/components/image-manager/update","docId":"iaas/components/image-manager/update","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/iaas/components/image-manager/"},{"type":"link","label":"Flavor Manager","href":"/docs/iaas/components/flavor-manager","docId":"iaas/components/flavor-manager","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/components"},{"type":"category","label":"Deployment Examples","items":[{"type":"link","label":"artcodix","href":"/docs/iaas/deployment-examples/artcodix/","docId":"iaas/deployment-examples/artcodix/index","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/deployment-examples"}],"collapsed":true,"collapsible":true,"href":"/docs/category/iaas-layer"},{"type":"category","label":"Container Layer","items":[{"type":"category","label":"Components","items":[{"type":"category","label":"Cluster Stacks","items":[{"type":"link","label":"Overview","href":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","docId":"container/components/cluster-stacks/components/cluster-stacks/overview","unlisted":false},{"type":"category","label":"Cluster Stack Operator","items":[{"type":"link","label":"Overview","href":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","docId":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","unlisted":false},{"type":"link","label":"Getting Started","href":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","docId":"container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","unlisted":false},{"type":"link","label":"Troubleshooting","href":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot","docId":"container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot","unlisted":false},{"type":"link","label":"Contributing","href":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/","docId":"container/components/cluster-stacks/components/cluster-stack-operator/develop/develop","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Cluster Stack Provider OpenStack","items":[{"type":"link","label":"Overview","href":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","docId":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","unlisted":false},{"type":"link","label":"Quickstart","href":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","docId":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","unlisted":false},{"type":"link","label":"Controllers","href":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","docId":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","unlisted":false},{"type":"link","label":"Developer Guide","href":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","docId":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"csctl","items":[{"type":"link","label":"Overview","href":"/docs/container/components/cluster-stacks/components/csctl/overview","docId":"container/components/cluster-stacks/components/csctl/overview","unlisted":false},{"type":"link","label":"Quickstart","href":"/docs/container/components/cluster-stacks/components/csctl/quickstart","docId":"container/components/cluster-stacks/components/csctl/quickstart","unlisted":false},{"type":"link","label":"Getting started","href":"/docs/container/components/cluster-stacks/components/csctl/getting_started","docId":"container/components/cluster-stacks/components/csctl/getting_started","unlisted":false},{"type":"link","label":"Developing and Testing csctl","href":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","docId":"container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Predefined Cluster Stacks","items":[{"type":"category","label":"Openstack","items":[{"type":"link","label":"Quickstart","href":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","docId":"container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","unlisted":false},{"type":"link","label":"Configuration","href":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","docId":"container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","unlisted":false}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true,"href":"/docs/category/cluster-stacks"},{"type":"category","label":"Container Registry","items":[{"type":"link","label":"Quickstart","href":"/docs/container/components/container-registry/docs/quickstart","docId":"container/components/container-registry/docs/quickstart","unlisted":false},{"type":"link","label":"SCS deployment","href":"/docs/container/components/container-registry/docs/scs-deployment","docId":"container/components/container-registry/docs/scs-deployment","unlisted":false},{"type":"link","label":"Rate limit","href":"/docs/container/components/container-registry/docs/rate_limit","docId":"container/components/container-registry/docs/rate_limit","unlisted":false},{"type":"link","label":"Upgrade","href":"/docs/container/components/container-registry/docs/upgrade","docId":"container/components/container-registry/docs/upgrade","unlisted":false},{"type":"link","label":"Backup and restore","href":"/docs/container/components/container-registry/docs/backup_and_restore","docId":"container/components/container-registry/docs/backup_and_restore","unlisted":false},{"type":"link","label":"Migration","href":"/docs/container/components/container-registry/docs/migration","docId":"container/components/container-registry/docs/migration","unlisted":false},{"type":"link","label":"Persistence","href":"/docs/container/components/container-registry/docs/persistence","docId":"container/components/container-registry/docs/persistence","unlisted":false},{"type":"link","label":"HA deployment","href":"/docs/container/components/container-registry/docs/ha-deployment","docId":"container/components/container-registry/docs/ha-deployment","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/container-registry"}],"collapsed":true,"collapsible":true,"href":"/docs/category/components-1"}],"collapsed":true,"collapsible":true,"href":"/docs/container/"},{"type":"category","label":"Operating SCS","items":[{"type":"category","label":"Components","items":[{"type":"category","label":"Status Page","items":[{"type":"category","label":"Concepts","items":[{"type":"link","label":"Overview","href":"/docs/operating-scs/components/status-page-openapi/docs/overview","docId":"operating-scs/components/status-page-openapi/docs/overview","unlisted":false},{"type":"link","label":"Components","href":"/docs/operating-scs/components/status-page-openapi/docs/components","docId":"operating-scs/components/status-page-openapi/docs/components","unlisted":false},{"type":"link","label":"\\"Levels of consensus\\"","href":"/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus","docId":"operating-scs/components/status-page-openapi/docs/levels_of_consensus","unlisted":false},{"type":"link","label":"Component Overview","href":"/docs/operating-scs/components/status-page-openapi/docs/component_overview","docId":"operating-scs/components/status-page-openapi/docs/component_overview","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/concepts"},{"type":"category","label":"API","items":[{"type":"link","label":"Overview","href":"/docs/operating-scs/components/status-page-api/docs/overview","docId":"operating-scs/components/status-page-api/docs/overview","unlisted":false},{"type":"link","label":"Requirements","href":"/docs/operating-scs/components/status-page-api/docs/requirements","docId":"operating-scs/components/status-page-api/docs/requirements","unlisted":false},{"type":"link","label":"Quickstart","href":"/docs/operating-scs/components/status-page-api/docs/quickstart","docId":"operating-scs/components/status-page-api/docs/quickstart","unlisted":false},{"type":"link","label":"Configuration","href":"/docs/operating-scs/components/status-page-api/docs/configuration","docId":"operating-scs/components/status-page-api/docs/configuration","unlisted":false},{"type":"link","label":"Requests","href":"/docs/operating-scs/components/status-page-api/docs/requests","docId":"operating-scs/components/status-page-api/docs/requests","unlisted":false},{"type":"link","label":"Example requests","href":"/docs/operating-scs/components/status-page-api/docs/example-requests","docId":"operating-scs/components/status-page-api/docs/example-requests","unlisted":false},{"type":"link","label":"Contribute","href":"/docs/operating-scs/components/status-page-api/docs/contribute","docId":"operating-scs/components/status-page-api/docs/contribute","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/api"},{"type":"category","label":"Deployment","items":[{"type":"link","label":"Overview","href":"/docs/operating-scs/components/status-page-deployment/docs/overview","docId":"operating-scs/components/status-page-deployment/docs/overview","unlisted":false},{"type":"link","label":"Requirements","href":"/docs/operating-scs/components/status-page-deployment/docs/requirements","docId":"operating-scs/components/status-page-deployment/docs/requirements","unlisted":false},{"type":"link","label":"Quickstart","href":"/docs/operating-scs/components/status-page-deployment/docs/quickstart","docId":"operating-scs/components/status-page-deployment/docs/quickstart","unlisted":false},{"type":"category","label":"Configuration","items":[{"type":"link","label":"Configure status page","href":"/docs/operating-scs/components/status-page-deployment/docs/configuration","docId":"operating-scs/components/status-page-deployment/docs/configuration","unlisted":false},{"type":"link","label":"kind - Local development environment","href":"/docs/operating-scs/components/status-page-deployment/docs/kind","docId":"operating-scs/components/status-page-deployment/docs/kind","unlisted":false},{"type":"link","label":"k3s - A simple deployment on a single host","href":"/docs/operating-scs/components/status-page-deployment/docs/k3s","docId":"operating-scs/components/status-page-deployment/docs/k3s","unlisted":false},{"type":"link","label":"SCS Public","href":"/docs/operating-scs/components/status-page-deployment/docs/scs-public","docId":"operating-scs/components/status-page-deployment/docs/scs-public","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/configuration"},{"type":"link","label":"Usage","href":"/docs/operating-scs/components/status-page-deployment/docs/usage","docId":"operating-scs/components/status-page-deployment/docs/usage","unlisted":false},{"type":"link","label":"Monitoring","href":"/docs/operating-scs/components/status-page-deployment/docs/monitoring","docId":"operating-scs/components/status-page-deployment/docs/monitoring","unlisted":false},{"type":"link","label":"Contribute","href":"/docs/operating-scs/components/status-page-deployment/docs/contribute","docId":"operating-scs/components/status-page-deployment/docs/contribute","unlisted":false},{"type":"link","label":"Admin authentication","href":"/docs/operating-scs/components/status-page-deployment/docs/admin-authentication","docId":"operating-scs/components/status-page-deployment/docs/admin-authentication","unlisted":false},{"type":"link","label":"FAQ","href":"/docs/operating-scs/components/status-page-deployment/docs/faq","docId":"operating-scs/components/status-page-deployment/docs/faq","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/deployment"},{"type":"category","label":"Web","items":[{"type":"link","label":"Overview","href":"/docs/operating-scs/components/status-page-web/docs/overview","docId":"operating-scs/components/status-page-web/docs/overview","unlisted":false},{"type":"link","label":"Requirements","href":"/docs/operating-scs/components/status-page-web/docs/requirements","docId":"operating-scs/components/status-page-web/docs/requirements","unlisted":false},{"type":"link","label":"Quickstart","href":"/docs/operating-scs/components/status-page-web/docs/quickstart","docId":"operating-scs/components/status-page-web/docs/quickstart","unlisted":false},{"type":"link","label":"Configuration","href":"/docs/operating-scs/components/status-page-web/docs/configuration","docId":"operating-scs/components/status-page-web/docs/configuration","unlisted":false},{"type":"link","label":"Contribute","href":"/docs/operating-scs/components/status-page-web/docs/contribute","docId":"operating-scs/components/status-page-web/docs/contribute","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/web"}],"collapsed":true,"collapsible":true,"href":"/docs/category/status-page"},{"type":"category","label":"Monitoring","items":[{"type":"link","label":"Overview","href":"/docs/operating-scs/components/monitoring/docs/overview","docId":"operating-scs/components/monitoring/docs/overview","unlisted":false},{"type":"link","label":"Quickstart","href":"/docs/operating-scs/components/monitoring/docs/quickstart","docId":"operating-scs/components/monitoring/docs/quickstart","unlisted":false},{"type":"link","label":"SCS deployment","href":"/docs/operating-scs/components/monitoring/docs/scs-deployment","docId":"operating-scs/components/monitoring/docs/scs-deployment","unlisted":false},{"type":"link","label":"K3s support","href":"/docs/operating-scs/components/monitoring/docs/k3s","docId":"operating-scs/components/monitoring/docs/k3s","unlisted":false},{"type":"link","label":"Infrastructure service endpoints","href":"/docs/operating-scs/components/monitoring/docs/infrastructure_services","docId":"operating-scs/components/monitoring/docs/infrastructure_services","unlisted":false},{"type":"link","label":"IaaS monitoring (experimental)","href":"/docs/operating-scs/components/monitoring/docs/iaas","docId":"operating-scs/components/monitoring/docs/iaas","unlisted":false},{"type":"link","label":"KaaS monitoring (experimental)","href":"/docs/operating-scs/components/monitoring/docs/kaas","docId":"operating-scs/components/monitoring/docs/kaas","unlisted":false},{"type":"link","label":"Zuul monitoring","href":"/docs/operating-scs/components/monitoring/docs/zuul","docId":"operating-scs/components/monitoring/docs/zuul","unlisted":false},{"type":"link","label":"Alertmanager notifications in Matrix chat","href":"/docs/operating-scs/components/monitoring/docs/alertmanager","docId":"operating-scs/components/monitoring/docs/alertmanager","unlisted":false},{"type":"link","label":"OAUTH","href":"/docs/operating-scs/components/monitoring/docs/oauth","docId":"operating-scs/components/monitoring/docs/oauth","unlisted":false},{"type":"link","label":"Traces","href":"/docs/operating-scs/components/monitoring/docs/tracing","docId":"operating-scs/components/monitoring/docs/tracing","unlisted":false},{"type":"link","label":"Tuning","href":"/docs/operating-scs/components/monitoring/docs/tuning","docId":"operating-scs/components/monitoring/docs/tuning","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/monitoring"},{"type":"category","label":"SCS Health Monitor","items":[{"type":"link","label":"SCS Health Monitor","href":"/docs/operating-scs/components/scs-health-monitor/overview","docId":"operating-scs/components/scs-health-monitor/overview","unlisted":false},{"type":"link","label":"Kubernetes BDD Testing Framework Documentation","href":"/docs/operating-scs/components/scs-health-monitor/Workflow","docId":"operating-scs/components/scs-health-monitor/Workflow","unlisted":false},{"type":"link","label":"Testflow-Infrastructure","href":"/docs/operating-scs/components/scs-health-monitor/Testflow","docId":"operating-scs/components/scs-health-monitor/Testflow","unlisted":false},{"type":"link","label":"Observability stack quickstart","href":"/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack","docId":"operating-scs/components/scs-health-monitor/SetupObservabilityStack","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/scs-health-monitor"},{"type":"category","label":"Central API","items":[{"type":"link","label":"Overview","href":"/docs/operating-scs/components/central-api/overview","docId":"operating-scs/components/central-api/overview","unlisted":false},{"type":"link","label":"Central API MVP","href":"/docs/operating-scs/components/central-api/poc-setup","docId":"operating-scs/components/central-api/poc-setup","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/central-api"},{"type":"category","label":"Automated Pentesting","items":[{"type":"category","label":"Pentesting IaaS","items":[{"type":"link","label":"Overview","href":"/docs/operating-scs/components/automated-pentesting-iaas/overview","docId":"operating-scs/components/automated-pentesting-iaas/overview","unlisted":false},{"type":"link","label":"Quickstart","href":"/docs/operating-scs/components/automated-pentesting-iaas/quickstart","docId":"operating-scs/components/automated-pentesting-iaas/quickstart","unlisted":false},{"type":"link","label":"Tools Description","href":"/docs/operating-scs/components/automated-pentesting-iaas/tools","docId":"operating-scs/components/automated-pentesting-iaas/tools","unlisted":false},{"type":"link","label":"Using Automated Pentesting Reports for CSPs, Operators, and Users","href":"/docs/operating-scs/components/automated-pentesting-iaas/reports","docId":"operating-scs/components/automated-pentesting-iaas/reports","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/pentesting-iaas"},{"type":"category","label":"Pentesting KaaS","items":[{"type":"link","label":"Overview","href":"/docs/operating-scs/components/automated-pentesting-kaas/overview","docId":"operating-scs/components/automated-pentesting-kaas/overview","unlisted":false},{"type":"link","label":"Quickstart Guide","href":"/docs/operating-scs/components/automated-pentesting-kaas/quickstart","docId":"operating-scs/components/automated-pentesting-kaas/quickstart","unlisted":false},{"type":"link","label":"Tools Description","href":"/docs/operating-scs/components/automated-pentesting-kaas/tools","docId":"operating-scs/components/automated-pentesting-kaas/tools","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/pentesting-kaas"}],"collapsed":true,"collapsible":true,"href":"/docs/category/automated-pentesting"}],"collapsed":true,"collapsible":true,"href":"/docs/category/components-2"},{"type":"category","label":"Guides","items":[{"type":"link","label":"Guide: Setting up openstack-health-monitor on Debian 12","href":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","docId":"operating-scs/guides/openstack-health-monitor/Debian12-Install","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/guides-1"},{"type":"category","label":"Metering","items":[{"type":"link","label":"Metering Configuration","href":"/docs/operating-scs/metering/meter_configuration","docId":"operating-scs/metering/meter_configuration","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/metering"}],"collapsed":true,"collapsible":true,"href":"/docs/category/operating-scs"},{"type":"category","label":"Identity and Access Management (IAM)","items":[{"type":"category","label":"Guides","items":[{"type":"link","label":"Domain Manager setup and usage","href":"/docs/iam/domain-manager-setup-and-usage","docId":"iam/domain-manager-setup-and-usage","unlisted":false},{"type":"link","label":"Example setup configuration in SCS deployment explained","href":"/docs/iam/SCS-example-setup-configuration-description","docId":"iam/SCS-example-setup-configuration-description","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/guides-2"},{"type":"link","label":"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)","href":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","docId":"iam/intra-SCS-federation-setup-description-for-osism-doc-operations","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/iam/"},{"type":"category","label":"Turnkey Solution","items":[{"type":"link","label":"Overview","href":"/docs/turnkey-solution/overview","docId":"turnkey-solution/overview","unlisted":false},{"type":"link","label":"Hardware-Landscape","href":"/docs/turnkey-solution/hardware-landscape","docId":"turnkey-solution/hardware-landscape","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/turnkey-solution"},{"type":"category","label":"Releases","items":[{"type":"link","label":"Release Notes for SCS Release 0","href":"/docs/releases/Release0","docId":"releases/Release0","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 1","href":"/docs/releases/Release1","docId":"releases/Release1","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 2","href":"/docs/releases/Release2","docId":"releases/Release2","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 3","href":"/docs/releases/Release3","docId":"releases/Release3","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 4","href":"/docs/releases/Release4","docId":"releases/Release4","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 5","href":"/docs/releases/Release5","docId":"releases/Release5","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 6","href":"/docs/releases/Release6","docId":"releases/Release6","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 7","href":"/docs/releases/Release7","docId":"releases/Release7","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/releases"},{"type":"link","label":"FAQ","href":"/docs/faq/","docId":"faq/index","unlisted":false},{"type":"link","label":"Glossary","href":"/docs/glossary","docId":"glossary","unlisted":false}]},"docs":{"container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow","title":"Management Cluster flow","description":"In a Cluster API management cluster, the Cluster API operators run. In our management cluster, there are also the Cluster Stack operators."},"container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow","title":"Node image flow","description":"The node image flow depends on each provider. There are various ways in which providers allow the use of custom images. We have documented the options in the cluster stacks repo."},"container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","title":"Overview","description":"Architecture","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","title":"Deep dive: User flow","description":"It is essential to understand the flow of what you have to do as a user and what happens in the background."},"container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow","title":"The workload cluster flow","description":"The workload cluster flow is implemented by two controllers and one custom resource."},"container/components/cluster-stacks/components/cluster-stack-operator/concept":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/concept","title":"Understanding the concept of Cluster Stacks","description":"The Cluster Stack framework was developed as one of the building blocks of an open-source Kubernetes-as-a-Service. The goal was to make it easier and more user-friendly to manage Kubernetes and Cluster API."},"container/components/cluster-stacks/components/cluster-stack-operator/develop/develop":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/develop/develop","title":"Contributing","description":"Develop Cluster Stack Operator","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration","title":"provider-integration","description":""},"container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing","title":"releasing","description":"Release Process"},"container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack","title":"clusterstack","description":"ClusterStack"},"container/components/cluster-stacks/components/cluster-stack-operator/terminology":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/terminology","title":"Terminology","description":"The Cluster Stacks are a framework and provide tools how to use them. The terminology is not perfect and if you have an idea how to improve it, please reach out. Right now there are the following terms:"},"container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks","title":"Managing ClusterStack objects","description":"The ClusterStack object is the central resource that you have to work with. You have to specify a provider, the name of the cluster stack you want to use, as well as the Kubernetes minor version."},"container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","title":"Getting Started","description":"Quickstart","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot","title":"Troubleshooting","description":"Check the latest events:","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow","title":"Upgrade flow","description":"This flow assumes that you have an existing cluster that references a certain ClusterClass called docker-ferrol-1-27-v1."},"container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks":{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","title":"using-local-clusterstacks","description":"This is a quickstart guide on using the local clusterstacks."},"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers":{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","title":"Controllers","description":"OpenStackClusterStackRelease controller","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop":{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","title":"Developer Guide","description":"Developing Cluster Stack Provider OpenStack operator is quite straightforward. First, you need to install some basic prerequisites:","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview":{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","title":"Overview","description":"The Cluster Stack Provider OpenStack (CSPO) works with the Cluster Stack Operator (CSO) and Cluster Stacks, enabling the creation of Kubernetes clusters in a Cluster-API-native (CAPI) fashion.","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart":{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","title":"Quickstart","description":"This document has been moved.","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting":{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","title":"Troubleshooting","description":"This guide explains general info on how to debug issues if a cluster creation fails."},"container/components/cluster-stacks/components/cluster-stacks/continuous-integration":{"id":"container/components/cluster-stacks/components/cluster-stacks/continuous-integration","title":"Continuous integration","description":"Project cluster-stacks use the SCS Zuul CI platform to"},"container/components/cluster-stacks/components/cluster-stacks/overview":{"id":"container/components/cluster-stacks/components/cluster-stacks/overview","title":"Overview","description":"Cluster Stacks","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration":{"id":"container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","title":"Configuration","description":"This page lists the custom configuration options available, including their default values and if they are optional. The following example shows how these variables can be used inside the cluster.yaml file under spec.topology.variables.","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart":{"id":"container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","title":"Quickstart","description":"This quickstart guide contains steps to install the Cluster Stack Operator (CSO) utilizing the Cluster Stack Provider OpenStack (CSPO) to provide ClusterClasses which can be used with the Kubernetes Cluster API to create Kubernetes Clusters.","sidebar":"docs"},"container/components/cluster-stacks/components/csctl/design":{"id":"container/components/cluster-stacks/components/csctl/design","title":"CSCTL - Design document","description":"The Cluster Stack Operator facilitates the usage of cluster stacks by automating all steps that can be automated. It takes cluster stacks release assets that consist mainly of two Helm charts, one to deploy in the management cluster, the other one to deploy in the workload clusters, as well as provider-specific node image (build) information."},"container/components/cluster-stacks/components/csctl/developing-and-testing-csctl":{"id":"container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","title":"Developing and Testing csctl","description":"Clone the Repo","sidebar":"docs"},"container/components/cluster-stacks/components/csctl/getting_started":{"id":"container/components/cluster-stacks/components/csctl/getting_started","title":"Getting started","description":"A Cluster Stack is full template of a Kubernetes cluster. A Cluster Stack can be configured on every provider that supports Cluster API.","sidebar":"docs"},"container/components/cluster-stacks/components/csctl/how_to_use_csctl":{"id":"container/components/cluster-stacks/components/csctl/how_to_use_csctl","title":"how_to_use_csctl","description":"Obsolete, content moved to overview.md and quickstart.md for use in docs.scs.community"},"container/components/cluster-stacks/components/csctl/overview":{"id":"container/components/cluster-stacks/components/csctl/overview","title":"Overview","description":"Introduction","sidebar":"docs"},"container/components/cluster-stacks/components/csctl/quickstart":{"id":"container/components/cluster-stacks/components/csctl/quickstart","title":"Quickstart","description":"Installation","sidebar":"docs"},"container/components/container-registry/docs/backup_and_restore":{"id":"container/components/container-registry/docs/backup_and_restore","title":"Backup and restore","description":"This page aims at providing a step-by-step guide for backup and restore Harbor","sidebar":"docs"},"container/components/container-registry/docs/ha-deployment":{"id":"container/components/container-registry/docs/ha-deployment","title":"HA deployment","description":"Prerequisites","sidebar":"docs"},"container/components/container-registry/docs/migration":{"id":"container/components/container-registry/docs/migration","title":"Migration","description":"harbormigration.png","sidebar":"docs"},"container/components/container-registry/docs/persistence":{"id":"container/components/container-registry/docs/persistence","title":"Persistence","description":"This page briefly describes and provides pointers on how Harbor persists data when it is","sidebar":"docs"},"container/components/container-registry/docs/quickstart":{"id":"container/components/container-registry/docs/quickstart","title":"Quickstart","description":"This guide shows you how to set up a working Harbor Container Registry that utilizes a Kubernetes cluster.","sidebar":"docs"},"container/components/container-registry/docs/rate_limit":{"id":"container/components/container-registry/docs/rate_limit","title":"Rate limit","description":"This page describes how the rate limiting can be set up for the Harbor container registry.","sidebar":"docs"},"container/components/container-registry/docs/scs-deployment":{"id":"container/components/container-registry/docs/scs-deployment","title":"SCS deployment","description":"The following steps were utilized for deploying the SCS reference installation of the Harbor container registry,","sidebar":"docs"},"container/components/container-registry/docs/upgrade":{"id":"container/components/container-registry/docs/upgrade","title":"Upgrade","description":"This page aims at providing additional information for upgrading Harbor","sidebar":"docs"},"container/deployment-examples/a/hardware":{"id":"container/deployment-examples/a/hardware","title":"Hardware Requirements","description":"TODO"},"container/deployment-examples/a/index":{"id":"container/deployment-examples/a/index","title":"Overview","description":"TODO"},"container/deployment-examples/a/software":{"id":"container/deployment-examples/a/software","title":"Software Requirements","description":"TODO"},"container/guides/guide1":{"id":"container/guides/guide1","title":"Guide 1","description":"TODO"},"container/index":{"id":"container/index","title":"Container Layer Introduction","description":"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:","sidebar":"docs"},"container/overview/architecture":{"id":"container/overview/architecture","title":"Architecture","description":"TODO"},"container/overview/knowledge":{"id":"container/overview/knowledge","title":"Knowledge","description":"TODO"},"faq/index":{"id":"faq/index","title":"Frequently Asked Questions","description":"What does SCS stand for?","sidebar":"docs"},"getting-started/containerization":{"id":"getting-started/containerization","title":"Containerization","description":"TODO"},"getting-started/overview":{"id":"getting-started/overview","title":"Overview","description":"TODO"},"getting-started/virtualization":{"id":"getting-started/virtualization","title":"Virtualization","description":"TODO"},"glossary":{"id":"glossary","title":"Glossary","description":"This file serves as the central glossary within SCS. It is intended to clearly","sidebar":"docs"},"iaas/components/flavor-manager":{"id":"iaas/components/flavor-manager","title":"Flavor Manager","description":"Overview","sidebar":"docs"},"iaas/components/image-manager/index":{"id":"iaas/components/image-manager/index","title":"Image Manager","description":"The OpenStack Image Manager is a tool for managing all","sidebar":"docs"},"iaas/components/image-manager/update":{"id":"iaas/components/image-manager/update","title":"Image Manager update.py","description":"Overview","sidebar":"docs"},"iaas/components/index":{"id":"iaas/components/index","title":"Tools","description":""},"iaas/components/openstack-health-monitor":{"id":"iaas/components/openstack-health-monitor","title":"Setting up OpenStack health monitor on Debian","description":"Kurt Garloff, 2024-02-20"},"iaas/components/project-manager":{"id":"iaas/components/project-manager","title":"Project Manager","description":"Overview"},"iaas/components/resource-manager":{"id":"iaas/components/resource-manager","title":"Resource Manager","description":"Preparations"},"iaas/components/sandbox-manager":{"id":"iaas/components/sandbox-manager","title":"Sandbox Manager","description":""},"iaas/components/simple-stress":{"id":"iaas/components/simple-stress","title":"Simple Stress","description":"Overview"},"iaas/deployment-examples/artcodix/index":{"id":"iaas/deployment-examples/artcodix/index","title":"artcodix","description":"Preface","sidebar":"docs"},"iaas/guides/concept-guide/components/ceph":{"id":"iaas/guides/concept-guide/components/ceph","title":"Ceph","description":"Ceph is an Open Source software defined storage platform designed to provide highly scalable","sidebar":"docs"},"iaas/guides/concept-guide/components/clusterapi":{"id":"iaas/guides/concept-guide/components/clusterapi","title":"Cluster API","description":"Kubernetes as a Service (KaaS) is a cloud service model that simplifies the deployment,","sidebar":"docs"},"iaas/guides/concept-guide/components/gardener":{"id":"iaas/guides/concept-guide/components/gardener","title":"Gardener","description":"Kubernetes as a Service (KaaS) simplifies the deployment, management, and scaling of","sidebar":"docs"},"iaas/guides/concept-guide/components/index":{"id":"iaas/guides/concept-guide/components/index","title":"Components","description":"* Infrastructure as a Service (IaaS) with OpenStack","sidebar":"docs"},"iaas/guides/concept-guide/components/ironic":{"id":"iaas/guides/concept-guide/components/ironic","title":"Ironic","description":"OpenStack Ironic is a project that provides Baremetal as a Service (BMaaS), enabling the","sidebar":"docs"},"iaas/guides/concept-guide/components/k3s":{"id":"iaas/guides/concept-guide/components/k3s","title":"K3S","description":"Lifecycle Management of K3S in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/components/keycloak":{"id":"iaas/guides/concept-guide/components/keycloak","title":"Keycloak","description":"Lifecycle Management of Keycloak in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/components/netdata":{"id":"iaas/guides/concept-guide/components/netdata","title":"Netdata","description":"Lifecycle Management of Netdata in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/components/openstack":{"id":"iaas/guides/concept-guide/components/openstack","title":"OpenStack","description":"Lifecycle Management of OpenStack in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/components/prometheus":{"id":"iaas/guides/concept-guide/components/prometheus","title":"Prometheus & Grafana","description":"Lifecycle Management of Prometheus in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/components/sonic":{"id":"iaas/guides/concept-guide/components/sonic","title":"SONiC & OVN","description":"Lifecycle Management of SONiC in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/components/teleport":{"id":"iaas/guides/concept-guide/components/teleport","title":"Teleport","description":"Lifecycle Management of Teleport in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/design":{"id":"iaas/guides/concept-guide/design","title":"Cluster design","description":"Parts of this chapter are based on the OpenStack Architecture Design Guide.","sidebar":"docs"},"iaas/guides/concept-guide/hardware-bom":{"id":"iaas/guides/concept-guide/hardware-bom","title":"Hardware Bill of Materials","description":"The brands, models and configurations listed are examples. There is no","sidebar":"docs"},"iaas/guides/concept-guide/index":{"id":"iaas/guides/concept-guide/index","title":"Concept Guide","description":"Highlevel Overview","sidebar":"docs"},"iaas/guides/concept-guide/layers":{"id":"iaas/guides/concept-guide/layers","title":"Layers in a cluster","description":"Compute Plane","sidebar":"docs"},"iaas/guides/concept-guide/nodes":{"id":"iaas/guides/concept-guide/nodes","title":"Nodes in a cluster","description":"Compute Node","sidebar":"docs"},"iaas/guides/concept-guide/use-cases":{"id":"iaas/guides/concept-guide/use-cases","title":"Use cases","description":"Hyper-converged infrastructure (HCI)","sidebar":"docs"},"iaas/guides/configuration-guide/ceph":{"id":"iaas/guides/configuration-guide/ceph","title":"Ceph","description":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/","sidebar":"docs"},"iaas/guides/configuration-guide/commons/certificates":{"id":"iaas/guides/configuration-guide/commons/certificates","title":"Certificates","description":"With the osism.commons.certificates role, it is possible to add custom CA certificates","sidebar":"docs"},"iaas/guides/configuration-guide/commons/index":{"id":"iaas/guides/configuration-guide/commons/index","title":"Commons","description":"This section contains the documentation of the Ansible collection osism.commons.","sidebar":"docs"},"iaas/guides/configuration-guide/commons/packages":{"id":"iaas/guides/configuration-guide/commons/packages","title":"Packages","description":"With the osism.commons.packages role, it is possible to add packages on a node","sidebar":"docs"},"iaas/guides/configuration-guide/commons/resolvconf":{"id":"iaas/guides/configuration-guide/commons/resolvconf","title":"Resolvconf","description":"With the osism.commons.resolvconf role, it is possible to manage the used DNS servers on a node.","sidebar":"docs"},"iaas/guides/configuration-guide/commons/services":{"id":"iaas/guides/configuration-guide/commons/services","title":"Services","description":"With the osism.commons.services role, it is possible to manage services on a node","sidebar":"docs"},"iaas/guides/configuration-guide/commons/sshconfig":{"id":"iaas/guides/configuration-guide/commons/sshconfig","title":"SSH Config","description":"With the osism.commons.sshconfig role, it is possible to manage a SSH config","sidebar":"docs"},"iaas/guides/configuration-guide/commons/sysctl":{"id":"iaas/guides/configuration-guide/commons/sysctl","title":"Sysctl","description":"With the osism.commons.sysctl role, it is possible to manage the attributes of the kernel","sidebar":"docs"},"iaas/guides/configuration-guide/commons/timezone":{"id":"iaas/guides/configuration-guide/commons/timezone","title":"Timezone","description":"With the osism.commons.timezone role, it is possible to manage the used timezone on a node.","sidebar":"docs"},"iaas/guides/configuration-guide/commons/user":{"id":"iaas/guides/configuration-guide/commons/user","title":"User","description":"With the osism.commons.user role, it is possible to manage additional","sidebar":"docs"},"iaas/guides/configuration-guide/configuration-repository":{"id":"iaas/guides/configuration-guide/configuration-repository","title":"Configuration Repository","description":"The configuration required for an OSISM managed cluster is stored in a single Git","sidebar":"docs"},"iaas/guides/configuration-guide/index":{"id":"iaas/guides/configuration-guide/index","title":"Configuration Guide","description":"","sidebar":"docs"},"iaas/guides/configuration-guide/inventory":{"id":"iaas/guides/configuration-guide/inventory","title":"Inventory","description":"The inventory used for the environment is located in the inventory directory.","sidebar":"docs"},"iaas/guides/configuration-guide/loadbalancer":{"id":"iaas/guides/configuration-guide/loadbalancer","title":"Loadbalancer","description":"The settings of the following section rely on the mechanisms of Kolla-Ansible,","sidebar":"docs"},"iaas/guides/configuration-guide/manager":{"id":"iaas/guides/configuration-guide/manager","title":"Manager","description":"Stable release","sidebar":"docs"},"iaas/guides/configuration-guide/network":{"id":"iaas/guides/configuration-guide/network","title":"Network","description":"Netplan","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/aodh":{"id":"iaas/guides/configuration-guide/openstack/aodh","title":"Aodh","description":"* Aodh admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/barbican":{"id":"iaas/guides/configuration-guide/openstack/barbican","title":"Barbican","description":"* Barbican admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/ceilometer":{"id":"iaas/guides/configuration-guide/openstack/ceilometer","title":"Ceilometer","description":"* Ceilometer admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/cinder":{"id":"iaas/guides/configuration-guide/openstack/cinder","title":"Cinder","description":"* Cinder admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/designate":{"id":"iaas/guides/configuration-guide/openstack/designate","title":"Designate","description":"* Designate admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/glance":{"id":"iaas/guides/configuration-guide/openstack/glance","title":"Glance","description":"* Glance admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/heat":{"id":"iaas/guides/configuration-guide/openstack/heat","title":"Heat","description":"* Heat admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/horizon":{"id":"iaas/guides/configuration-guide/openstack/horizon","title":"Horizon","description":"* Horizon admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/index":{"id":"iaas/guides/configuration-guide/openstack/index","title":"OpenStack","description":"Image tags","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/ironic":{"id":"iaas/guides/configuration-guide/openstack/ironic","title":"Ironic","description":"* Ironic admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/keystone":{"id":"iaas/guides/configuration-guide/openstack/keystone","title":"Keystone","description":"* Keystone admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/magnum":{"id":"iaas/guides/configuration-guide/openstack/magnum","title":"Magnum","description":"* Magnum admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/manila":{"id":"iaas/guides/configuration-guide/openstack/manila","title":"Manila","description":"* Manila admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/neutron":{"id":"iaas/guides/configuration-guide/openstack/neutron","title":"Neutron","description":"* Neutron admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/nova":{"id":"iaas/guides/configuration-guide/openstack/nova","title":"Nova","description":"* Nova admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/octavia":{"id":"iaas/guides/configuration-guide/openstack/octavia","title":"Octavia","description":"* Octavia admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/placement":{"id":"iaas/guides/configuration-guide/openstack/placement","title":"Placement","description":"* Placement admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/skyline":{"id":"iaas/guides/configuration-guide/openstack/skyline","title":"Skyline","description":"Skyline APIServer","sidebar":"docs"},"iaas/guides/configuration-guide/proxy":{"id":"iaas/guides/configuration-guide/proxy","title":"Proxy","description":"In the following examples, it is assumed that the Squid proxy integrated by OSISM","sidebar":"docs"},"iaas/guides/configuration-guide/rook":{"id":"iaas/guides/configuration-guide/rook","title":"Ceph via Rook (technical preview)","description":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/","sidebar":"docs"},"iaas/guides/configuration-guide/rookify":{"id":"iaas/guides/configuration-guide/rookify","title":"Configure Rookify: Migrate from Ceph-Ansible to Rook (Technical Preview)","description":"Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime.","sidebar":"docs"},"iaas/guides/configuration-guide/services/chrony":{"id":"iaas/guides/configuration-guide/services/chrony","title":"Chrony","description":"With the osism.services.chrony role, it is possible to manage the used NTP servers on a node.","sidebar":"docs"},"iaas/guides/configuration-guide/services/docker":{"id":"iaas/guides/configuration-guide/services/docker","title":"Docker","description":"With the osism.services.docker role, it is possible to manage Docker.","sidebar":"docs"},"iaas/guides/configuration-guide/services/index":{"id":"iaas/guides/configuration-guide/services/index","title":"Services","description":"This section contains the documentation of the Ansible collection","sidebar":"docs"},"iaas/guides/configuration-guide/services/tuned":{"id":"iaas/guides/configuration-guide/services/tuned","title":"Tuned","description":"The roller can be applied with osism apply tuned. The role is applied to all","sidebar":"docs"},"iaas/guides/configuration-guide/validations/index":{"id":"iaas/guides/configuration-guide/validations/index","title":"Validations","description":"This section contains the documentation of the Ansible collection","sidebar":"docs"},"iaas/guides/deploy-guide/bootstrap":{"id":"iaas/guides/deploy-guide/bootstrap","title":"Bootstrap","description":"The prerequisite for bootstraping the nodes of a cluster the Manager node has to be","sidebar":"docs"},"iaas/guides/deploy-guide/examples/cloud-in-a-box":{"id":"iaas/guides/deploy-guide/examples/cloud-in-a-box","title":"Cloud in a Box","description":"This section has moved. You can now find the content in the","sidebar":"docs"},"iaas/guides/deploy-guide/examples/index":{"id":"iaas/guides/deploy-guide/examples/index","title":"Examples","description":"","sidebar":"docs"},"iaas/guides/deploy-guide/examples/testbed":{"id":"iaas/guides/deploy-guide/examples/testbed","title":"Testbed","description":"This section has moved. You can now find the content in the","sidebar":"docs"},"iaas/guides/deploy-guide/index":{"id":"iaas/guides/deploy-guide/index","title":"Deploy Guide","description":"OSISM is deployed in a series of successive steps. The steps are documented in the Deploy Guide.","sidebar":"docs"},"iaas/guides/deploy-guide/manager":{"id":"iaas/guides/deploy-guide/manager","title":"Manager","description":"The prerequisite for deploying the Manager node is a Seed node. What a Seed node is","sidebar":"docs"},"iaas/guides/deploy-guide/provisioning":{"id":"iaas/guides/deploy-guide/provisioning","title":"Provisioning of bare-metal nodes","description":"For the initial deployment of the management plane and the control plane of OSISM,","sidebar":"docs"},"iaas/guides/deploy-guide/rookify":{"id":"iaas/guides/deploy-guide/rookify","title":"Deploy Rookify: Migrate to Rook from Ceph-Ansible (Technical Preview)","description":"Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime.","sidebar":"docs"},"iaas/guides/deploy-guide/seed":{"id":"iaas/guides/deploy-guide/seed","title":"Seed","description":"The prerequisite for the deployment of a cluster is a configuration repository.","sidebar":"docs"},"iaas/guides/deploy-guide/services/ceph":{"id":"iaas/guides/deploy-guide/services/ceph","title":"Ceph","description":"In OSISM it is also possible to integrate and use existing Ceph clusters. It","sidebar":"docs"},"iaas/guides/deploy-guide/services/index":{"id":"iaas/guides/deploy-guide/services/index","title":"Services","description":"The prerequisite for deploying the services of a cluster is the bootstrap of","sidebar":"docs"},"iaas/guides/deploy-guide/services/infrastructure":{"id":"iaas/guides/deploy-guide/services/infrastructure","title":"Infrastructure","description":"Common issues with deploying infrastructure services required by OpenStack","sidebar":"docs"},"iaas/guides/deploy-guide/services/kubernetes":{"id":"iaas/guides/deploy-guide/services/kubernetes","title":"Kubernetes","description":"As of OSISM 7, it is possible to create a Kubernetes cluster on all nodes.","sidebar":"docs"},"iaas/guides/deploy-guide/services/logging-monitoring":{"id":"iaas/guides/deploy-guide/services/logging-monitoring","title":"Logging & Monitoring","description":"Common issues with deploying logging & monitoring services provided by Kolla","sidebar":"docs"},"iaas/guides/deploy-guide/services/network":{"id":"iaas/guides/deploy-guide/services/network","title":"Network","description":"1. Open vSwitch (OVS)","sidebar":"docs"},"iaas/guides/deploy-guide/services/openstack":{"id":"iaas/guides/deploy-guide/services/openstack","title":"OpenStack","description":"Common issues with deploying OpenStack services are documented in the","sidebar":"docs"},"iaas/guides/deploy-guide/services/rook":{"id":"iaas/guides/deploy-guide/services/rook","title":"Ceph via Rook (technical preview)","description":"This is a technical preview and not recommended for production use yet.","sidebar":"docs"},"iaas/guides/deploy-guide/services/rookify":{"id":"iaas/guides/deploy-guide/services/rookify","title":"Migrate Ceph-Ansible via Rookify (technical preview)","description":"This is a technical preview and not recommended for production use yet.","sidebar":"docs"},"iaas/guides/index":{"id":"iaas/guides/index","title":"Guides","description":"* The Concept Guide explains which components and modules make up OSISM. It also","sidebar":"docs"},"iaas/guides/operations-guide/ceph":{"id":"iaas/guides/operations-guide/ceph","title":"Ceph","description":"Where to find docs","sidebar":"docs"},"iaas/guides/operations-guide/index":{"id":"iaas/guides/operations-guide/index","title":"Operations Guide","description":"Change Node states","sidebar":"docs"},"iaas/guides/operations-guide/infrastructure":{"id":"iaas/guides/operations-guide/infrastructure","title":"Infrastructure","description":"Loadbalancer","sidebar":"docs"},"iaas/guides/operations-guide/manager/apply":{"id":"iaas/guides/operations-guide/manager/apply","title":"Apply","description":"With the apply command it is possible to run Ansible plays. These are executed as","sidebar":"docs"},"iaas/guides/operations-guide/manager/console":{"id":"iaas/guides/operations-guide/manager/console","title":"Console","description":"A console command is available in the OSISM CLI. This allows specific parts of the","sidebar":"docs"},"iaas/guides/operations-guide/manager/get":{"id":"iaas/guides/operations-guide/manager/get","title":"Get","description":"A get command is available in the OSISM CLI. This allows to gather specific information.","sidebar":"docs"},"iaas/guides/operations-guide/manager/index":{"id":"iaas/guides/operations-guide/manager/index","title":"Manager","description":"OSISM orchestrator","sidebar":"docs"},"iaas/guides/operations-guide/manager/log":{"id":"iaas/guides/operations-guide/manager/log","title":"Logging","description":"Ansible","sidebar":"docs"},"iaas/guides/operations-guide/manager/task":{"id":"iaas/guides/operations-guide/manager/task","title":"Task","description":"List","sidebar":"docs"},"iaas/guides/operations-guide/network":{"id":"iaas/guides/operations-guide/network","title":"Network","description":"OpenStack, OVN, and Open vSwitch all really like UUIDs.","sidebar":"docs"},"iaas/guides/operations-guide/openstack/cinder":{"id":"iaas/guides/operations-guide/openstack/cinder","title":"Cinder","description":"Remove service","sidebar":"docs"},"iaas/guides/operations-guide/openstack/index":{"id":"iaas/guides/operations-guide/openstack/index","title":"OpenStack","description":"Create an external network","sidebar":"docs"},"iaas/guides/operations-guide/openstack/keystone":{"id":"iaas/guides/operations-guide/openstack/keystone","title":"Keystone","description":"* List all users of a project who have been assigned the member role","sidebar":"docs"},"iaas/guides/operations-guide/openstack/neutron":{"id":"iaas/guides/operations-guide/openstack/neutron","title":"Neutron","description":"Quality of Service (QoS)","sidebar":"docs"},"iaas/guides/operations-guide/openstack/nova":{"id":"iaas/guides/operations-guide/openstack/nova","title":"Nova","description":"Get all servers on a node","sidebar":"docs"},"iaas/guides/operations-guide/openstack/octavia":{"id":"iaas/guides/operations-guide/openstack/octavia","title":"Octavia","description":"Cleanup of amphorae missing from the DB","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/flavor-manager":{"id":"iaas/guides/operations-guide/openstack/tools/flavor-manager","title":"Flavor Manager","description":"Overview","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/image-manager/index":{"id":"iaas/guides/operations-guide/openstack/tools/image-manager/index","title":"Image Manager","description":"The OpenStack Image Manager is a tool for managing all","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/image-manager/update":{"id":"iaas/guides/operations-guide/openstack/tools/image-manager/update","title":"Image Manager update.py","description":"Overview","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/index":{"id":"iaas/guides/operations-guide/openstack/tools/index","title":"Tools","description":"","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/openstack-health-monitor":{"id":"iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","title":"Setting up OpenStack health monitor on Debian","description":"Kurt Garloff, 2024-02-20","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/project-manager":{"id":"iaas/guides/operations-guide/openstack/tools/project-manager","title":"Project Manager","description":"Overview","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/resource-manager":{"id":"iaas/guides/operations-guide/openstack/tools/resource-manager","title":"Resource Manager","description":"Preparations","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/sandbox-manager":{"id":"iaas/guides/operations-guide/openstack/tools/sandbox-manager","title":"Sandbox Manager","description":"","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/simple-stress":{"id":"iaas/guides/operations-guide/openstack/tools/simple-stress","title":"Simple Stress","description":"Overview","sidebar":"docs"},"iaas/guides/operations-guide/rook":{"id":"iaas/guides/operations-guide/rook","title":"Ceph via Rook (technical preview)","description":"This is a technical preview and not recommended for production use yet. This whole","sidebar":"docs"},"iaas/guides/operations-guide/rookify":{"id":"iaas/guides/operations-guide/rookify","title":"Use Rookify: Migrate to Rook from Ceph Ansible (Technical Preview)","description":"Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime.","sidebar":"docs"},"iaas/guides/other-guides/cloud-in-a-box/index":{"id":"iaas/guides/other-guides/cloud-in-a-box/index","title":"Cloud in a Box","description":"\ud83d\udca1 Cloud in a Box (CiaB) is a minimalistic installation of the latest stable OSISM release with only services which are needed to","sidebar":"docs"},"iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine":{"id":"iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","title":"Running on a virtual machine","description":"KVM","sidebar":"docs"},"iaas/guides/other-guides/contributor-guide":{"id":"iaas/guides/other-guides/contributor-guide","title":"Contributor Guide","description":"We welcome any issues, change requests or general feedback. Do not hestiate to open an issue.","sidebar":"docs"},"iaas/guides/other-guides/developer-guide/index":{"id":"iaas/guides/other-guides/developer-guide/index","title":"Developer Guide","description":"How to add a new service","sidebar":"docs"},"iaas/guides/other-guides/developer-guide/releases":{"id":"iaas/guides/other-guides/developer-guide/releases","title":"Releases","description":"How we handle releases","sidebar":"docs"},"iaas/guides/other-guides/developer-guide/scripts":{"id":"iaas/guides/other-guides/developer-guide/scripts","title":"Scripts","description":"Scripts are included in container images to simplify development work and to enable","sidebar":"docs"},"iaas/guides/other-guides/developer-guide/style-guide":{"id":"iaas/guides/other-guides/developer-guide/style-guide","title":"Style Guide","description":"Ansible","sidebar":"docs"},"iaas/guides/other-guides/developer-guide/zuul":{"id":"iaas/guides/other-guides/developer-guide/zuul","title":"Zuul CI","description":"We use Zuul CI as a CI service for OSISM. The service is not required for","sidebar":"docs"},"iaas/guides/other-guides/index":{"id":"iaas/guides/other-guides/index","title":"Other Guides","description":"","sidebar":"docs"},"iaas/guides/other-guides/testbed":{"id":"iaas/guides/other-guides/testbed","title":"Testbed","description":"With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack","sidebar":"docs"},"iaas/guides/troubleshooting-guide/ceph":{"id":"iaas/guides/troubleshooting-guide/ceph","title":"Ceph","description":"Where to find docs","sidebar":"docs"},"iaas/guides/troubleshooting-guide/index":{"id":"iaas/guides/troubleshooting-guide/index","title":"Troubleshooting Guide","description":"\ud83d\udca1 The Troubleshooting Guide describe how to solve issues.","sidebar":"docs"},"iaas/guides/troubleshooting-guide/manager":{"id":"iaas/guides/troubleshooting-guide/manager","title":"Manager","description":"Reset","sidebar":"docs"},"iaas/guides/troubleshooting-guide/openstack":{"id":"iaas/guides/troubleshooting-guide/openstack","title":"OpenStack","description":"Database creation fails","sidebar":"docs"},"iaas/guides/troubleshooting-guide/rookify":{"id":"iaas/guides/troubleshooting-guide/rookify","title":"Rookify (Technical Preview)","description":"Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime.","sidebar":"docs"},"iaas/guides/upgrade-guide/ceph":{"id":"iaas/guides/upgrade-guide/ceph","title":"Ceph","description":"See Rook Operations.","sidebar":"docs"},"iaas/guides/upgrade-guide/docker":{"id":"iaas/guides/upgrade-guide/docker","title":"Docker","description":"The Docker version used is defined via the parameter docker_version in the file","sidebar":"docs"},"iaas/guides/upgrade-guide/index":{"id":"iaas/guides/upgrade-guide/index","title":"Upgrade Guide","description":"In the examples, the pull of images (if supported by a role) is always run first. While","sidebar":"docs"},"iaas/guides/upgrade-guide/infrastructure":{"id":"iaas/guides/upgrade-guide/infrastructure","title":"Infrastructure","description":"1. Kubernetes","sidebar":"docs"},"iaas/guides/upgrade-guide/logging-monitoring":{"id":"iaas/guides/upgrade-guide/logging-monitoring","title":"Logging & Monitoring","description":"1. OpenSearch","sidebar":"docs"},"iaas/guides/upgrade-guide/manager":{"id":"iaas/guides/upgrade-guide/manager","title":"Manager","description":"Always read the release notes first to learn what has changed and what","sidebar":"docs"},"iaas/guides/upgrade-guide/network":{"id":"iaas/guides/upgrade-guide/network","title":"Network","description":"1. Open vSwitch (OVS)","sidebar":"docs"},"iaas/guides/upgrade-guide/openstack":{"id":"iaas/guides/upgrade-guide/openstack","title":"OpenStack","description":"When upgrade the different OpenStack services, all containers must be","sidebar":"docs"},"iaas/guides/user-guide/index":{"id":"iaas/guides/user-guide/index","title":"User Guide","description":"","sidebar":"docs"},"iaas/guides/user-guide/migration-vmware-esxi":{"id":"iaas/guides/user-guide/migration-vmware-esxi","title":"Migrate from VMware ESXi to OpenStack","description":"This guide is an example of how to perform a manual migration from a VMware ESXi host to OpenStack.","sidebar":"docs"},"iaas/guides/user-guide/openstack/index":{"id":"iaas/guides/user-guide/openstack/index","title":"OpenStack","description":"","sidebar":"docs"},"iaas/guides/user-guide/openstack/install-instance-from-iso":{"id":"iaas/guides/user-guide/openstack/install-instance-from-iso","title":"Install instance from ISO image","description":"While in general it is considered best practice to create instances from existing or specially crafted images, sometimes it is necessary to install an instance using a traditional installer packaged in an ISO image.","sidebar":"docs"},"iaas/guides/user-guide/openstack/openstackclient":{"id":"iaas/guides/user-guide/openstack/openstackclient","title":"Client","description":"OpenStackClient looks for a clouds.yaml configuration file in the following locations:","sidebar":"docs"},"iaas/guides/user-guide/openstack/security-groups":{"id":"iaas/guides/user-guide/openstack/security-groups","title":"How to configure and use security groups","description":"Security groups in OpenStack are part of the network security mechanisms provided for the users.","sidebar":"docs"},"iaas/guides/user-guide/openstack/user-data-backups":{"id":"iaas/guides/user-guide/openstack/user-data-backups","title":"User Data Backups","description":"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.","sidebar":"docs"},"iaas/guides/user-guide/security-groups/security-groups":{"id":"iaas/guides/user-guide/security-groups/security-groups","title":"Best Practise: How to configure and use security groups","description":"Security groups in OpenStack are part of the network security mechanisms provided for the users.","sidebar":"docs"},"iaas/guides/user-guide/user-data-backups":{"id":"iaas/guides/user-guide/user-data-backups","title":"User Data Backups","description":"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.","sidebar":"docs"},"iaas/overview/architecture":{"id":"iaas/overview/architecture","title":"Architecture","description":"TODO"},"iaas/overview/compute":{"id":"iaas/overview/compute","title":"Compute","description":"TODO"},"iaas/overview/knowledge":{"id":"iaas/overview/knowledge","title":"Knowledge","description":"TODO"},"iaas/overview/network":{"id":"iaas/overview/network","title":"Network","description":"TODO"},"iaas/overview/storage":{"id":"iaas/overview/storage","title":"Storage","description":"TODO"},"iam/domain-manager-setup-and-usage":{"id":"iam/domain-manager-setup-and-usage","title":"Domain Manager setup and usage","description":"The following documentation refers to a SCS standard that is still in draft state.","sidebar":"docs"},"iam/index":{"id":"iam/index","title":"Introduction on Identity Management and Federation in SCS","description":"Sovereign Cloud Stack wants to make it possible for operators to delegate","sidebar":"docs"},"iam/intra-SCS-federation-setup-description-for-osism-doc-operations":{"id":"iam/intra-SCS-federation-setup-description-for-osism-doc-operations","title":"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)","description":"The followig section is a reasonably detailed hands on description of how","sidebar":"docs"},"iam/SCS-example-setup-configuration-description":{"id":"iam/SCS-example-setup-configuration-description","title":"Example setup configuration in SCS deployment explained","description":"The following document explains the idea behind the example configuration is done.","sidebar":"docs"},"index":{"id":"index","title":"Introduction","description":"About","sidebar":"docs"},"operating-scs/audits/index":{"id":"operating-scs/audits/index","title":"Overview","description":"TODO"},"operating-scs/components/automated-pentesting-iaas/overview":{"id":"operating-scs/components/automated-pentesting-iaas/overview","title":"Overview","description":"Introdution","sidebar":"docs"},"operating-scs/components/automated-pentesting-iaas/quickstart":{"id":"operating-scs/components/automated-pentesting-iaas/quickstart","title":"Quickstart","description":"This page covers the process of setting up an IaaS layer automated pentesting pipeline.","sidebar":"docs"},"operating-scs/components/automated-pentesting-iaas/reports":{"id":"operating-scs/components/automated-pentesting-iaas/reports","title":"Using Automated Pentesting Reports for CSPs, Operators, and Users","description":"This section outlines how Infrastructure Operators (Cloud Service Providers - CSPs) and users can leverage automated pentesting reports focused on Infrastructure-as-a-Service (IaaS) and Container-as-a-Service (CaaS) environments.","sidebar":"docs"},"operating-scs/components/automated-pentesting-iaas/tools":{"id":"operating-scs/components/automated-pentesting-iaas/tools","title":"Tools Description","description":"The following tools make up the automated pentesting pipeline.","sidebar":"docs"},"operating-scs/components/automated-pentesting-kaas/overview":{"id":"operating-scs/components/automated-pentesting-kaas/overview","title":"Overview","description":"Introdution","sidebar":"docs"},"operating-scs/components/automated-pentesting-kaas/quickstart":{"id":"operating-scs/components/automated-pentesting-kaas/quickstart","title":"Quickstart Guide","description":"This document provides a quick guide to setting up and running the security scanning infrastructure using Trivy and other related tools.","sidebar":"docs"},"operating-scs/components/automated-pentesting-kaas/tools":{"id":"operating-scs/components/automated-pentesting-kaas/tools","title":"Tools Description","description":"The following tools make up the automated scanning pipeline and report sending.","sidebar":"docs"},"operating-scs/components/central-api/overview":{"id":"operating-scs/components/central-api/overview","title":"Overview","description":"Premise","sidebar":"docs"},"operating-scs/components/central-api/poc-setup":{"id":"operating-scs/components/central-api/poc-setup","title":"Central API MVP","description":"Right now, this repository implements issue 374.","sidebar":"docs"},"operating-scs/components/monitoring/docs/alertmanager":{"id":"operating-scs/components/monitoring/docs/alertmanager","title":"Alertmanager notifications in Matrix chat","description":"This page contains instructions on how to enable the Alertmanager to Matrix chat notifications in the Observer solution.","sidebar":"docs"},"operating-scs/components/monitoring/docs/iaas":{"id":"operating-scs/components/monitoring/docs/iaas","title":"IaaS monitoring (experimental)","description":"This component is marked as experimental, and it is not part of the reference SCS installation available","sidebar":"docs"},"operating-scs/components/monitoring/docs/infrastructure_services":{"id":"operating-scs/components/monitoring/docs/infrastructure_services","title":"Infrastructure service endpoints","description":"This page contains instructions on how to enable probing of infrastructure service endpoints using blackbox exporter.","sidebar":"docs"},"operating-scs/components/monitoring/docs/k3s":{"id":"operating-scs/components/monitoring/docs/k3s","title":"K3s support","description":"K3s is a certified Kubernetes distribution optimized for production environments, particularly in remote locations","sidebar":"docs"},"operating-scs/components/monitoring/docs/kaas":{"id":"operating-scs/components/monitoring/docs/kaas","title":"KaaS monitoring (experimental)","description":"This component is marked as experimental, and it is not part of the reference SCS installation available","sidebar":"docs"},"operating-scs/components/monitoring/docs/oauth":{"id":"operating-scs/components/monitoring/docs/oauth","title":"OAUTH","description":"We set up oauth2 with GitHub provider for the https//kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/.","sidebar":"docs"},"operating-scs/components/monitoring/docs/overview":{"id":"operating-scs/components/monitoring/docs/overview","title":"Overview","description":"This repository aims to build an Observer monitoring solution intended to offer a global metrics","sidebar":"docs"},"operating-scs/components/monitoring/docs/quickstart":{"id":"operating-scs/components/monitoring/docs/quickstart","title":"Quickstart","description":"These page covers the process of deploying the Observer monitoring solution","sidebar":"docs"},"operating-scs/components/monitoring/docs/scs-deployment":{"id":"operating-scs/components/monitoring/docs/scs-deployment","title":"SCS deployment","description":"The following steps were utilized to deploy the SCS reference installation of the Observer monitoring solution,","sidebar":"docs"},"operating-scs/components/monitoring/docs/status-page":{"id":"operating-scs/components/monitoring/docs/status-page","title":"Status page monitoring","description":"Prerequisites"},"operating-scs/components/monitoring/docs/tracing":{"id":"operating-scs/components/monitoring/docs/tracing","title":"Traces","description":"This page contains a guide on how to enable traces in Thanos. Traces are not enabled by default.","sidebar":"docs"},"operating-scs/components/monitoring/docs/tuning":{"id":"operating-scs/components/monitoring/docs/tuning","title":"Tuning","description":"This page contains recommended parameters to set for the Thanos components to improve performance in terms of query time.","sidebar":"docs"},"operating-scs/components/monitoring/docs/zuul":{"id":"operating-scs/components/monitoring/docs/zuul","title":"Zuul monitoring","description":"This page contains instructions on how to enable the Zuul monitoring in the Observer solution.","sidebar":"docs"},"operating-scs/components/scs-health-monitor/overview":{"id":"operating-scs/components/scs-health-monitor/overview","title":"SCS Health Monitor","description":"Welcome to the SCS Health Monitor project! This repository is dedicated to setting up scenarios for functionality and load testing on a deployed OpenStack environment. We utilize Gherkin language to write testing scenarios, and Python\'s Behave library to execute these tests.","sidebar":"docs"},"operating-scs/components/scs-health-monitor/SetupObservabilityStack":{"id":"operating-scs/components/scs-health-monitor/SetupObservabilityStack","title":"Observability stack quickstart","description":"Prerequisites","sidebar":"docs"},"operating-scs/components/scs-health-monitor/Testflow":{"id":"operating-scs/components/scs-health-monitor/Testflow","title":"Testflow-Infrastructure","description":"Quick Intro:","sidebar":"docs"},"operating-scs/components/scs-health-monitor/Workflow":{"id":"operating-scs/components/scs-health-monitor/Workflow","title":"Kubernetes BDD Testing Framework Documentation","description":"Overview","sidebar":"docs"},"operating-scs/components/status-page-api/docs/configuration":{"id":"operating-scs/components/status-page-api/docs/configuration","title":"Configuration","description":"Configuration can be done by environment variables or flags to the binary.","sidebar":"docs"},"operating-scs/components/status-page-api/docs/contribute":{"id":"operating-scs/components/status-page-api/docs/contribute","title":"Contribute","description":"Contributions are welcome at SovereignCloudStack/status-page-api.","sidebar":"docs"},"operating-scs/components/status-page-api/docs/example-requests":{"id":"operating-scs/components/status-page-api/docs/example-requests","title":"Example requests","description":"Example request for common API requests.","sidebar":"docs"},"operating-scs/components/status-page-api/docs/overview":{"id":"operating-scs/components/status-page-api/docs/overview","title":"Overview","description":"The status-page-api repository strives to provide a reference implementation of the concepts being outlined by status-page-openapi.","sidebar":"docs"},"operating-scs/components/status-page-api/docs/quickstart":{"id":"operating-scs/components/status-page-api/docs/quickstart","title":"Quickstart","description":"See requirements","sidebar":"docs"},"operating-scs/components/status-page-api/docs/requests":{"id":"operating-scs/components/status-page-api/docs/requests","title":"Requests","description":"As defined by the OpenAPI spec and status page OpenAPI decision the general API objects are used as request bodies and responses to generalize data structures. Not all object fields are handled by all requests, some are read only and some are write only. GET request wrap their return in a object field called data.","sidebar":"docs"},"operating-scs/components/status-page-api/docs/requirements":{"id":"operating-scs/components/status-page-api/docs/requirements","title":"Requirements","description":"The status page API server requires a PostgreSQL database.","sidebar":"docs"},"operating-scs/components/status-page-deployment/docs/admin-authentication":{"id":"operating-scs/components/status-page-deployment/docs/admin-authentication","title":"Admin authentication","description":"As the write operations of the API server are protected by Oathkeeper and use identities provided by Dex an Administrator is considered to be a person that can authenticate on Dex.","sidebar":"docs"},"operating-scs/components/status-page-deployment/docs/configuration":{"id":"operating-scs/components/status-page-deployment/docs/configuration","title":"Configure status page","description":"A minimal configuration of the status page deployment.","sidebar":"docs"},"operating-scs/components/status-page-deployment/docs/contribute":{"id":"operating-scs/components/status-page-deployment/docs/contribute","title":"Contribute","description":"Contributions are welcome at SovereignCloudStack/status-page-deployment.","sidebar":"docs"},"operating-scs/components/status-page-deployment/docs/faq":{"id":"operating-scs/components/status-page-deployment/docs/faq","title":"FAQ","description":"Dex needs a GitHub client secret. Where can I get it?","sidebar":"docs"},"operating-scs/components/status-page-deployment/docs/k3s":{"id":"operating-scs/components/status-page-deployment/docs/k3s","title":"k3s - A simple deployment on a single host","description":"From a new machine to a working status page in ~15 minutes.","sidebar":"docs"},"operating-scs/components/status-page-deployment/docs/kind":{"id":"operating-scs/components/status-page-deployment/docs/kind","title":"kind - Local development environment","description":"kind is a tool to quickly setup a local development environment, to test and debug the deployment.","sidebar":"docs"},"operating-scs/components/status-page-deployment/docs/monitoring":{"id":"operating-scs/components/status-page-deployment/docs/monitoring","title":"Monitoring","description":"All backend components of the status page can be instrumented to supply metrics. These metrics can be collected and visualized by monitoring technologies like Prometheus and Grafana.","sidebar":"docs"},"operating-scs/components/status-page-deployment/docs/overview":{"id":"operating-scs/components/status-page-deployment/docs/overview","title":"Overview","description":"The status page needs some components additional to the API server to be usable by operators and customers. As the API server does not implement any kind of authorization or authentication some components need to be deployed to protect the write operations of the API from unauthorized access.","sidebar":"docs"},"operating-scs/components/status-page-deployment/docs/quickstart":{"id":"operating-scs/components/status-page-deployment/docs/quickstart","title":"Quickstart","description":"To get a quickstart, please refer to the KinD or k3s guide.","sidebar":"docs"},"operating-scs/components/status-page-deployment/docs/requirements":{"id":"operating-scs/components/status-page-deployment/docs/requirements","title":"Requirements","description":"The requirements are specific for the relevant environment.","sidebar":"docs"},"operating-scs/components/status-page-deployment/docs/scs-public":{"id":"operating-scs/components/status-page-deployment/docs/scs-public","title":"SCS Public","description":"Data present in kubernetes/environments/scs-public is the deployment specified for the provided SCS Cluster, which is already fully setup to run k8s workloads.","sidebar":"docs"},"operating-scs/components/status-page-deployment/docs/usage":{"id":"operating-scs/components/status-page-deployment/docs/usage","title":"Usage","description":"You can use and test the API via any API client (Bruno, built in Swagger UI, etc.), CLI tool (like curl) or the web frontend.","sidebar":"docs"},"operating-scs/components/status-page-openapi/docs/component_overview":{"id":"operating-scs/components/status-page-openapi/docs/component_overview","title":"Component Overview","description":"This represents a part of the decision process related to the overall structure the API wants to represent.","sidebar":"docs"},"operating-scs/components/status-page-openapi/docs/components":{"id":"operating-scs/components/status-page-openapi/docs/components","title":"Components","description":"Illustrating multiple interchangeable logical \\"layers\\" of possible Status Page application stacks:","sidebar":"docs"},"operating-scs/components/status-page-openapi/docs/levels_of_consensus":{"id":"operating-scs/components/status-page-openapi/docs/levels_of_consensus","title":"\\"Levels of consensus\\"","description":"When implementing any system to be used by a group of potential users, there will be varying use cases and opinions about API\'s, programming languages, persistence models, authentication, authorization, deployment options and so on.","sidebar":"docs"},"operating-scs/components/status-page-openapi/docs/overview":{"id":"operating-scs/components/status-page-openapi/docs/overview","title":"Overview","description":"Service providers often times want to communicate the status of their systems transparently to their users.","sidebar":"docs"},"operating-scs/components/status-page-web/docs/configuration":{"id":"operating-scs/components/status-page-web/docs/configuration","title":"Configuration","description":"The SPA expects a configuration file called config.json to be present in the src/assets folder. The very same folder also contains a template for this configuration file, called config.tmpl.json. The resulting configuration, in the static build of the SPA, will be located at dist/scs-statuspage/browser/assets.","sidebar":"docs"},"operating-scs/components/status-page-web/docs/contribute":{"id":"operating-scs/components/status-page-web/docs/contribute","title":"Contribute","description":"To start developing for the status page web frontend, start by cloning the repo. Remember to run git submodule update --init afterwards to also retrieve the OpenAPI client included in the sources.","sidebar":"docs"},"operating-scs/components/status-page-web/docs/overview":{"id":"operating-scs/components/status-page-web/docs/overview","title":"Overview","description":"This repository supplies a SPA (Single Page Application), written in Angular, that uses the status-page-openapi client to connect to the API server to show components, incidents and their impacts on the system. The SPA also offers a management page, allowing authorized users to create, update and delete incidents (including future incidents, the so-called maintenance events).","sidebar":"docs"},"operating-scs/components/status-page-web/docs/quickstart":{"id":"operating-scs/components/status-page-web/docs/quickstart","title":"Quickstart","description":"To quickly start hosting the status page frontend, refer to the Quickstart guide of the status-page-deployment repository.","sidebar":"docs"},"operating-scs/components/status-page-web/docs/requirements":{"id":"operating-scs/components/status-page-web/docs/requirements","title":"Requirements","description":"Compiling the status page frontend requires Angular 17+.","sidebar":"docs"},"operating-scs/guides/openstack-health-monitor/Debian12-Install":{"id":"operating-scs/guides/openstack-health-monitor/Debian12-Install","title":"Guide: Setting up openstack-health-monitor on Debian 12","description":"Kurt Garloff, 2024-02-20","sidebar":"docs"},"operating-scs/incident-management/index":{"id":"operating-scs/incident-management/index","title":"Overview","description":"TODO"},"operating-scs/lifecycle-management/index":{"id":"operating-scs/lifecycle-management/index","title":"Overview","description":"TODO"},"operating-scs/logging/index":{"id":"operating-scs/logging/index","title":"Overview","description":"TODO"},"operating-scs/metering/meter_configuration":{"id":"operating-scs/metering/meter_configuration","title":"Metering Configuration","description":"The Metrics and events we want to use in the metering process can be defined in two ways. The first one is to allow ceilometer to poll distinct metrics and events.","sidebar":"docs"},"operating-scs/monitoring/index":{"id":"operating-scs/monitoring/index","title":"Overview","description":"TODO"},"operating-scs/overview":{"id":"operating-scs/overview","title":"Overview","description":"TODO"},"releases/Release0":{"id":"releases/Release0","title":"Release Notes for SCS Release 0","description":"(Release Date: 2021-07-15)","sidebar":"docs"},"releases/Release1":{"id":"releases/Release1","title":"Release Notes for SCS Release 1","description":"(Release Date: 2021-09-29)","sidebar":"docs"},"releases/Release2":{"id":"releases/Release2","title":"Release Notes for SCS Release 2","description":"(Release Date: 2022-03-23)","sidebar":"docs"},"releases/Release3":{"id":"releases/Release3","title":"Release Notes for SCS Release 3","description":"(Release Date: 2022-09-21)","sidebar":"docs"},"releases/Release4":{"id":"releases/Release4","title":"Release Notes for SCS Release 4","description":"(Release Date: 2023-03-22)","sidebar":"docs"},"releases/Release5":{"id":"releases/Release5","title":"Release Notes for SCS Release 5","description":"(Release Date: 2023-09-20)","sidebar":"docs"},"releases/Release6":{"id":"releases/Release6","title":"Release Notes for SCS Release 6","description":"SCS Release 6 has been published on 2024-03-20.","sidebar":"docs"},"releases/Release7":{"id":"releases/Release7","title":"Release Notes for SCS Release 7","description":"Release 7 has been published on September 11, 2024.","sidebar":"docs"},"releases/ReleaseX":{"id":"releases/ReleaseX","title":"Release Notes for SCS Release X","description":"This document is work in progress for the upcoming Release X."},"standards/index":{"id":"standards/index","title":"Standards","description":"TODO"},"turnkey-solution/hardware-landscape":{"id":"turnkey-solution/hardware-landscape","title":"The SCS Hardware-Landscape","description":"An image of the SCS hardware landscape rack","sidebar":"docs"},"turnkey-solution/overview":{"id":"turnkey-solution/overview","title":"Overview","description":"Scope of this document","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/0121636f.e159d662.js b/assets/js/0121636f.e159d662.js new file mode 100644 index 0000000000..f95eb26bc2 --- /dev/null +++ b/assets/js/0121636f.e159d662.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[95752],{53466:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>t,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/tools/project-manager","title":"Project Manager","description":"Overview","source":"@site/docs/02-iaas/guides/operations-guide/openstack/tools/project-manager.md","sourceDirName":"02-iaas/guides/operations-guide/openstack/tools","slug":"/iaas/guides/operations-guide/openstack/tools/project-manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/project-manager.md","tags":[],"version":"current","sidebarPosition":53,"frontMatter":{"sidebar_label":"Project Manager","sidebar_position":53},"sidebar":"docs","previous":{"title":"Resource Manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager"},"next":{"title":"Sandbox Manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager"}}');var i=a(74848),s=a(28453);const t={sidebar_label:"Project Manager",sidebar_position:53},r="Project Manager",c={},d=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Defaults",id:"defaults",level:2},{value:"create.py",id:"createpy",level:3},{value:"manage.py",id:"managepy",level:3},{value:"Usage",id:"usage",level:2},{value:"create.py",id:"createpy-1",level:3},{value:"Create a Domain and inital project",id:"create-a-domain-and-inital-project",level:4},{value:"Create a User for a project",id:"create-a-user-for-a-project",level:4},{value:"Create additional project with unlimited quota",id:"create-additional-project-with-unlimited-quota",level:4},{value:"Set quotas for a project",id:"set-quotas-for-a-project",level:4},{value:"Special project: images",id:"special-project-images",level:4},{value:"Special project: service",id:"special-project-service",level:4},{value:"manage.py",id:"managepy-1",level:3},{value:"Manage a specific domain only",id:"manage-a-specific-domain-only",level:4},{value:"Config files",id:"config-files",level:2},{value:"Quota Templates",id:"quota-templates",level:2},{value:"Setup Endpoints",id:"setup-endpoints",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",p:"p",pre:"pre",strong:"strong",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"project-manager",children:"Project Manager"})}),"\n",(0,i.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(n.p,{children:"The OpenStack Project Manager manages the creation of Openstack Domains, Projects and Users."}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsx)(n.p,{children:"Prepare to use the Openstack Project Manager."}),"\n",(0,i.jsx)(n.p,{children:"During installation, ldap libraries are required under Linux; you should install libldap2-dev and libsasl2-dev beforehand."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"git clone https://github.com/osism/openstack-project-manager\ncd openstack-project-manager\npipenv install\npipenv shell\n"})}),"\n",(0,i.jsx)(n.h2,{id:"defaults",children:"Defaults"}),"\n",(0,i.jsx)(n.h3,{id:"createpy",children:"create.py"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"create.py"})," command and his default options while executing the command."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:" --admin-domain default\n --assign-admin-user true\n --cloud admin\n --create-admin-user true\n --create-domain false\n --create-user false\n --domain-name-prefix true\n --has-service-network false\n --has-public-network true\n --has-shared-images true\n --internal-id unset\n --random false\n --managed-network-resources false\n --name sandbox\n --owner unset\n --password unset\n --password-length 16\n --public-network public\n --quota-class basic\n --service-network-cidr unset\n --quota-multiplier 1\n --quota-multiplier-compute unset\n --quota-multiplier-network unset\n --quota-multiplier-storage unset\n --quota-router 1\n"})}),"\n",(0,i.jsx)(n.h3,{id:"managepy",children:"manage.py"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"manage.py"})," has also some defaults while executing and will touch all projects in your Openstack Cluster, if not --domain is used."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:" --admin-domain default\n --assign-admin-user false\n --classes etc/classes.yml\n --domain unset\n --dry-run false\n --endpoints etc/endpoints.yml\n --manage-endpoints false\n --manage-homeprojects false\n --name unset\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Default Openstack Roles to users are set to ",(0,i.jsx)(n.code,{children:"member"})," and ",(0,i.jsx)(n.code,{children:"load-balancer_member"})," at this time, the behavior can only be changed in the code."]}),"\n",(0,i.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsxs)(n.p,{children:["There must be a ",(0,i.jsx)(n.code,{children:"clouds.yml"})," and a ",(0,i.jsx)(n.code,{children:"secure.yml"})," file in the directory where the OpenStack Project Manager will be executed, examples are provided within the git repository."]}),"\n",(0,i.jsx)(n.p,{children:"The cloud profile to be used can be specified via the optional --cloud parameter. By default the cloud profile with the name admin is used. It has to be and admin account, to create and modify domains, projects, users and quotas."}),"\n",(0,i.jsxs)(n.p,{children:["The Openstack Project Manager essentially consists of two parts, the ",(0,i.jsx)(n.code,{children:"create.py"})," and the ",(0,i.jsx)(n.code,{children:"manage.py"}),", there are more scripts for handling users using ldap which needs more configuration setup."]}),"\n",(0,i.jsx)(n.h3,{id:"createpy-1",children:"create.py"}),"\n",(0,i.jsx)(n.p,{children:"This command is used to create and modify domains, projects, users and quotas. As default the domain is used as prefix for all projects and users created for easy alloction in Openstack."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"create.py can't delete once created objects, this must be done using Openstack commands to remove a project or domain."})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"python src/create.py -h\nusage: create [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--create-admin-user] [--create-domain] [--create-user]\n [--domain DOMAIN] [--domain-name-prefix] [--has-public-network] [--has-service-network] [--has-shared-images] [--internal-id INTERNAL_ID] [--managed-network-resources] [--name NAME]\n [--noassign-admin-user] [--nocreate-admin-user] [--nocreate-domain] [--nocreate-user] [--nodomain-name-prefix] [--nohas-public-network] [--nohas-service-network]\n [--nohas-shared-images] [--nomanaged-network-resources] [--norandom] [--owner OWNER] [--password PASSWORD] [--password-length PASSWORD_LENGTH] [--public-network PUBLIC_NETWORK]\n [--quota-class QUOTA_CLASS] [--quota-multiplier QUOTA_MULTIPLIER] [--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE] [--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK]\n [--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE] [--quota-router QUOTA_ROUTER] [--random] [--service-network-cidr SERVICE_NETWORK_CIDR]\n\noptions:\n -h, --help show this help message and exit\n --admin-domain ADMIN_DOMAIN\n Admin domain\n --assign-admin-user Assign admin user\n --cloud CLOUD Managed cloud\n --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set\n is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the\n command-line.\n --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the\n command-line.\n --create-admin-user Create admin user\n --create-domain Create domain only\n --create-user Create user\n --domain DOMAIN Domain\n --domain-name-prefix Add domain name as prefix to the project name\n --has-public-network Has public network infrastructure\n --has-service-network\n Has service network infrastructure\n --has-shared-images Has shared images\n --internal-id INTERNAL_ID\n Internal ID\n --managed-network-resources\n Manage the network resources\n --name NAME Projectname\n --noassign-admin-user\n The inverse of --assign-admin-user\n --nocreate-admin-user\n The inverse of --create-admin-user\n --nocreate-domain The inverse of --create-domain\n --nocreate-user The inverse of --create-user\n --nodomain-name-prefix\n The inverse of --domain-name-prefix\n --nohas-public-network\n The inverse of --has-public-network\n --nohas-service-network\n The inverse of --has-service-network\n --nohas-shared-images\n The inverse of --has-shared-images\n --nomanaged-network-resources\n The inverse of --managed-network-resources\n --norandom The inverse of --random\n --owner OWNER Owner of the project\n --password PASSWORD Password\n --password-length PASSWORD_LENGTH\n Password length\n --public-network PUBLIC_NETWORK\n Public network\n --quota-class QUOTA_CLASS\n Quota class\n --quota-multiplier QUOTA_MULTIPLIER\n Quota multiplier\n --quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE\n Quota multiplier compute\n --quota-multiplier-network QUOTA_MULTIPLIER_NETWORK\n Quota multiplier network\n --quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE\n Quota multiplier storage\n --quota-router QUOTA_ROUTER\n Quota router\n --random Generate random names\n --service-network-cidr SERVICE_NETWORK_CIDR\n Service network CIDR\n"})}),"\n",(0,i.jsx)(n.h4,{id:"create-a-domain-and-inital-project",children:"Create a Domain and inital project"}),"\n",(0,i.jsxs)(n.p,{children:["When executing the ",(0,i.jsx)(n.code,{children:"create.py"})," command, the first time with ",(0,i.jsx)(n.code,{children:"--domain"}),", it will create a new domain, an admin account and the first project ",(0,i.jsx)(n.code,{children:"webshop"}),". The admin account will be created in the default Domain of Openstack and can be used for the Service Provider to manager the complete domain."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name webshop\n+----------------+----------------------+----------------------------------+\n| name | value | id |\n|----------------+----------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-webshop | 645538bf67664cfeaed32476d58f95fb |\n| admin | democompany-admin | cc8d6bf7b61d4199ba5a4230c4ec6d62 |\n| admin_password | qawsEdfg2d45Fsxc | |\n+----------------+----------------------+----------------------------------+\n"})}),"\n",(0,i.jsx)(n.h4,{id:"create-a-user-for-a-project",children:"Create a User for a project"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name webshopuser --create-user \n+----------+-------------------------+----------------------------------+\n| name | value | id |\n|----------+-------------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-webshop | 5752b6701026478f9cac122fc54eb9cb |\n| user | democompany-webshopuser | ce213655559d47d7800501124fed4d02 |\n| password | vEvM9vgRESdffWE2 | |\n+----------+-------------------------+----------------------------------+\n"})}),"\n",(0,i.jsx)(n.h4,{id:"create-additional-project-with-unlimited-quota",children:"Create additional project with unlimited quota"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name styles --quota-class unlimited\n+----------+--------------------+----------------------------------+\n| name | value | id |\n|----------+--------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-styles | 666097e396fd4f9392d6aa55c76d8267 |\n+----------+--------------------+----------------------------------+\n"})}),"\n",(0,i.jsx)(n.h4,{id:"set-quotas-for-a-project",children:"Set quotas for a project"}),"\n",(0,i.jsxs)(n.p,{children:["All quota information must be set as a property to the Openstack project within your Openstack Cluster, if no property is set, the ",(0,i.jsx)(n.code,{children:"basic"})," quotaclass of ",(0,i.jsx)(n.code,{children:"etc/classes.yml"})," will be applied.\nIt is possible to set a quota multiplier for any project."]}),"\n",(0,i.jsx)(n.p,{children:"The following command you set a multiplier of 256 of the basic quota:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack project set --property quotamultiplier=256 democompany-webshop\n"})}),"\n",(0,i.jsx)(n.p,{children:"Adjusting gigabyte quota for storage with a multiplier of 20 of the basic quota for a project:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack project set --property quotamultiplier_storage=20 democompany-webshop\n"})}),"\n",(0,i.jsx)(n.p,{children:"This will override the general quotamultiplier only for storage."}),"\n",(0,i.jsxs)(n.p,{children:["Other possible multiplier which can be set individually are: ",(0,i.jsx)(n.code,{children:"quotamultiplier_compute"}),", ",(0,i.jsx)(n.code,{children:"quotamultiplier_network"}),", ",(0,i.jsx)(n.code,{children:"quota_router"})]}),"\n",(0,i.jsxs)(n.p,{children:["To change the quotaclass to unlimited from the ",(0,i.jsx)(n.code,{children:"etc/classes.yaml"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack project set --property quotaclass=unlimited democompany-webshop\n"})}),"\n",(0,i.jsx)(n.h4,{id:"special-project-images",children:"Special project: images"}),"\n",(0,i.jsxs)(n.p,{children:["With this special Project you can share all images uploaded into this project to all other project in your domain which has set the property ",(0,i.jsx)(n.code,{children:"has-shared-images"}),", which is by default set.\nAlsoi only the domain-admin user has access to this project, other domain users won't see this, they will find the uploaded images in their projects.\nIf you want your grant other domain users also access to upload some images, you need to give them access to the images Project in Openstack."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name images\n+---------+---------------------+----------------------------------+\n| name | value | id |\n|---------+---------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-images | 6d57f39aacbe485d87733865b1e79d03 |\n+---------+---------------------+----------------------------------+\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Additionally you need to add the domain and domain-admin user to the ",(0,i.jsx)(n.code,{children:"clouds.yaml"}),", it is always named ",(0,i.jsx)(n.code,{children:"opm-domainname-admin:"})," so the manage.py can setup permissions to the projects later on and users are able to find the images."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:" opm-democompany-admin:\n auth:\n auth_url: https://keystone.my.cloud:5000/v3\n username: democompany-admin\n password: yourpassword\n user_domain_name: Default\n project_domain_name: democompany \n identity_api_version: 3\n"})}),"\n",(0,i.jsx)(n.h4,{id:"special-project-service",children:"Special project: service"}),"\n",(0,i.jsx)(n.p,{children:"With this special project you can share installed services, like a harbor, to all other projects in your domain. Per default, only the domain admin has access to this project."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name service\n+---------+---------------------+----------------------------------+\n| name | value | id |\n|---------+---------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-service | a5558f7338f94adea5f41858636256b5 |\n+---------+---------------------+----------------------------------+\n"})}),"\n",(0,i.jsx)(n.h3,{id:"managepy-1",children:"manage.py"}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["This command applies quotas, networks and routers to ",(0,i.jsx)(n.strong,{children:"all"})," projects in the Openstack Cluster, not only to those have been configured previously with the ",(0,i.jsx)(n.code,{children:"create.py"})," or ",(0,i.jsx)(n.code,{children:"openstack project set --property"})," commands."]})}),"\n",(0,i.jsx)(n.p,{children:"Best is to run this command by cron, every hour to apply all pending changes, it is also possible to run this at the command line to apply changes immediately."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"python3 src/manage.py -h\nusage: manage [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--classes CLASSES] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--domain DOMAIN] [--dry-run]\n [--endpoints ENDPOINTS] [--manage-endpoints] [--manage-homeprojects] [--name NAME] [--noassign-admin-user] [--nodry-run] [--nomanage-endpoints] [--nomanage-homeprojects]\n\noptions:\n -h, --help show this help message and exit\n --admin-domain ADMIN_DOMAIN\n Admin domain\n --assign-admin-user Assign admin user\n --classes CLASSES Path to the classes.yml file\n --cloud CLOUD Cloud name in clouds.yaml\n --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set\n is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the\n command-line.\n --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the\n command-line.\n --domain DOMAIN Domain to be managed\n --dry-run Do not really do anything\n --endpoints ENDPOINTS\n Path to the endpoints.yml file\n --manage-endpoints Manage endpoints\n --manage-homeprojects\n Manage home projects\n --name NAME Project to be managed\n --noassign-admin-user\n The inverse of --assign-admin-user\n --nodry-run The inverse of --dry-run\n --nomanage-endpoints The inverse of --manage-endpoints\n --nomanage-homeprojects\n The inverse of --manage-homeprojects\n"})}),"\n",(0,i.jsx)(n.h4,{id:"manage-a-specific-domain-only",children:"Manage a specific domain only"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python3 src/manage.py --domain democompany\n\n2024-04-19 14:24:02.873 | INFO | democompany - domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03\n2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03, domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:04.953 | INFO | democompany-images - quotaclass {'compute': {'cores': 0, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 0, 'key_pairs': 0, 'metadata_items': 128, 'ram': 0, 'server_group_members': 0, 'server_groups': 0}, 'network': {'floatingip': 0, 'network': 0, 'port': 0, 'rbac_policy': 0, 'router': 0, 'security_group': 0, 'security_group_rule': 0, 'subnet': 0, 'subnetpool': 0}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 1000, 'per_volume_gigabytes': 25, 'snapshots': 0, 'volumes': 100}, 'parent': 'default'}\n2024-04-19 14:24:04.953 | INFO | democompany-images - check network quota\n2024-04-19 14:24:05.048 | INFO | democompany-images - check compute quota\n2024-04-19 14:24:05.175 | INFO | democompany-images - check volume quota\n2024-04-19 14:24:05.286 | INFO | democompany-images - check if external rbac policy must be deleted (public)\n2024-04-19 14:24:05.349 | INFO | democompany-images - check if service rbac policy must be deleted (democompany-service)\n2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5\n2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5, domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:06.131 | INFO | democompany-service - quotaclass {'compute': {'cores': 256, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 256, 'key_pairs': 256, 'metadata_items': 128, 'ram': 262144, 'server_group_members': 256, 'server_groups': 256}, 'network': {'floatingip': 256, 'network': 256, 'port': 256, 'rbac_policy': 1024, 'router': 256, 'security_group': 256, 'security_group_rule': 1024, 'subnet': 256, 'subnetpool': 256}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 0, 'per_volume_gigabytes': 0, 'snapshots': 0, 'volumes': 0}, 'parent': 'default'}\n2024-04-19 14:24:06.131 | INFO | democompany-service - check network quota\n2024-04-19 14:24:06.212 | INFO | democompany-service - check compute quota\n2024-04-19 14:24:06.330 | INFO | democompany-service - check volume quota\n2024-04-19 14:24:06.467 | INFO | democompany-service - check if external rbac policy must be created (public)\n2024-04-19 14:24:06.589 | INFO | democompany-service - check if service rbac policy must be deleted (democompany-service)\n2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb\n2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb, domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:06.915 | INFO | democompany-webshop - quotaclass {'compute': {'cores': 4, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': -1, 'key_pairs': 4, 'metadata_items': 128, 'ram': 8192, 'server_group_members': 4, 'server_groups': 4}, 'network': {'floatingip': 4, 'network': 1, 'port': 20, 'rbac_policy': 10, 'router': 0, 'security_group': 5, 'security_group_rule': 20, 'subnet': 2, 'subnetpool': 1}, 'volume': {'backup_gigabytes': 40, 'backups': 8, 'gigabytes': 20, 'per_volume_gigabytes': 200, 'snapshots': 4, 'volumes': 4}, 'parent': 'default'}\n2024-04-19 14:24:06.915 | INFO | democompany-webshop - check network quota\n2024-04-19 14:24:06.993 | INFO | democompany-webshop - check compute quota\n2024-04-19 14:24:07.114 | INFO | democompany-webshop - check volume quota\n2024-04-19 14:24:07.254 | INFO | democompany-webshop - check if external rbac policy must be created (public)\n2024-04-19 14:24:07.334 | INFO | democompany-webshop - check if service rbac policy must be deleted (democompany-service)\n"})}),"\n",(0,i.jsx)(n.h2,{id:"config-files",children:"Config files"}),"\n",(0,i.jsxs)(n.p,{children:["The config files which can be used for ",(0,i.jsx)(n.code,{children:"create.py"})," and ",(0,i.jsx)(n.code,{children:"manage.py"})," are using the ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/oslo.config/latest/configuration/quickstart.html",children:"oslo.config format"}),", you can set the command line options as ",(0,i.jsx)(n.code,{children:"key = value pair"})," and create your own config files matching your setup."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="democompany.conf"',children:"[DEFAULT]\ncloud = admin\ndomain = democompany\n"})}),"\n",(0,i.jsx)(n.h2,{id:"quota-templates",children:"Quota Templates"}),"\n",(0,i.jsxs)(n.p,{children:["Edit the ",(0,i.jsx)(n.code,{children:"etc/classes.yml"})," file if you want to change or add new quota templates"]}),"\n",(0,i.jsx)(n.h2,{id:"setup-endpoints",children:"Setup Endpoints"}),"\n",(0,i.jsxs)(n.p,{children:["Edit the ",(0,i.jsx)(n.code,{children:"etc/endpoints.yml"})," file to fit your available endpoints"]})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>t,x:()=>r});var o=a(96540);const i={},s=o.createContext(i);function t(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/012688b3.ab8d0d7c.js b/assets/js/012688b3.ab8d0d7c.js new file mode 100644 index 0000000000..dc24287a93 --- /dev/null +++ b/assets/js/012688b3.ab8d0d7c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[55251],{56636:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"iaas/guides/concept-guide/hardware-bom","title":"Hardware Bill of Materials","description":"The brands, models and configurations listed are examples. There is no","source":"@site/docs/02-iaas/guides/concept-guide/hardware-bom.md","sourceDirName":"02-iaas/guides/concept-guide","slug":"/iaas/guides/concept-guide/hardware-bom","permalink":"/docs/iaas/guides/concept-guide/hardware-bom","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/hardware-bom.md","tags":[],"version":"current","sidebarPosition":50,"frontMatter":{"sidebar_label":"Hardware Bill of Materials","sidebar_position":50},"sidebar":"docs","previous":{"title":"Use cases","permalink":"/docs/iaas/guides/concept-guide/use-cases"},"next":{"title":"Deploy Guide","permalink":"/docs/iaas/guides/deploy-guide/"}}');var r=n(74848),o=n(28453);const i={sidebar_label:"Hardware Bill of Materials",sidebar_position:50},d="Hardware Bill of Materials",a={},l=[{value:"Control nodes",id:"control-nodes",level:2},{value:"Compute nodes",id:"compute-nodes",level:2},{value:"Storage nodes",id:"storage-nodes",level:2},{value:"Network nodes",id:"network-nodes",level:2},{value:"Manager nodes",id:"manager-nodes",level:2},{value:"Switches",id:"switches",level:2},{value:"Management switches",id:"management-switches",level:3},{value:"Leaf switches",id:"leaf-switches",level:3},{value:"Spine switches",id:"spine-switches",level:3},{value:"Network interface cards",id:"network-interface-cards",level:2}];function c(e){const s={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"hardware-bill-of-materials",children:"Hardware Bill of Materials"})}),"\n",(0,r.jsx)(s.admonition,{type:"info",children:(0,r.jsx)(s.p,{children:"The brands, models and configurations listed are examples. There is no\nsingle best specification for building a cluster. It always depends very\nmuch on the requirements of the cluster and the situation. The examples\nare not minimal and include various preferences of ours. The choice of\nhardware always depends very much on the requirements, the available budget\nand also the future plans of the cluster. There is no universal hardware\nrecommendation that fits all cases. These are all just examples."})}),"\n",(0,r.jsx)(s.h2,{id:"control-nodes",children:"Control nodes"}),"\n",(0,r.jsx)(s.p,{children:"A control node is responsible for running all or most of the OpenStack\nservices that manage API services and their associated runtimes. These\nnodes are essential for users to interact with the cluster and maintain\nits managed state."}),"\n",(0,r.jsx)(s.p,{children:"However, control nodes typically do not run user virtual machines. It is\ntherefore advisable to replicate the control nodes to ensure high availability\nand fault tolerance. A good starting point for achieving RAFT quorum is to have\nthree control nodes."}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"2x SSD with at least 480 GByte for the operating system"}),"\n",(0,r.jsx)(s.li,{children:"4x NVMe with at least 960 GByte for the services"}),"\n",(0,r.jsx)(s.li,{children:"128 GByte memory (it should be possible to upgrade to 256 GByte, or use 256\nGByte directly)"}),"\n",(0,r.jsx)(s.li,{children:"Dual port NIC with 25G or 100G (depending on which leaf switches are used)"}),"\n",(0,r.jsx)(s.li,{children:"2 CPU sockets each with at least 32 cores or 1 CPU socket with at least 64 cores"}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Real world example:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"https://www.supermicro.com/de/products/system/clouddc/1u/sys-121c-tn10r",children:"https://www.supermicro.com/de/products/system/clouddc/1u/sys-121c-tn10r"})}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"compute-nodes",children:"Compute nodes"}),"\n",(0,r.jsx)(s.p,{children:"Compute nodes are dedicated to running users' virtual machines. They do not\nhost API services, storage services or network routers, other than the basic\nnetwork infrastructure required to connect virtual machines."}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"2x SSD or NVMe with at least 480 GByte for the operating system"}),"\n",(0,r.jsx)(s.li,{children:"2x NVMe with at least 1.92 TByte for local storage recommended (if this is not implemented\nat the start, the model should be selected so that NVMe devices can be added later,\nthe size depends on which CPU and how much memory is used, 7.68 TByte is more likely to be used)"}),"\n",(0,r.jsx)(s.li,{children:"Dual port NIC with 25G or 100G (depending on which leaf switches are used)"}),"\n",(0,r.jsx)(s.li,{children:"CPU sockets and memory depends on the requirement"}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Real world example:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"https://www.supermicro.com/de/products/twin",children:"https://www.supermicro.com/de/products/twin"})}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"storage-nodes",children:"Storage nodes"}),"\n",(0,r.jsx)(s.p,{children:"A dedicated storage node runs only storage services. This can be necessary in larger\ndeployments to protect the storage services from ressource starvation through user\nworkloads."}),"\n",(0,r.jsxs)(s.p,{children:["Read the ",(0,r.jsx)(s.a,{href:"https://docs.ceph.com/en/latest/start/hardware-recommendations/",children:"Ceph hardware recommendations"})," first."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"2x SSD or NVMe with at least 480 GByte for the operating system"}),"\n",(0,r.jsx)(s.li,{children:"Dual port NIC with 100G (we recommend always using 100G for storage nodes)"}),"\n",(0,r.jsx)(s.li,{children:"Storage devices depends on the requirement"}),"\n",(0,r.jsx)(s.li,{children:"CPU sockets and memory depends on the storage devices used"}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"network-nodes",children:"Network nodes"}),"\n",(0,r.jsx)(s.p,{children:"A dedicated network node runs only network services. This is normally necessary to be\nable to map safety zones. External networks terminate on the network nodes."}),"\n",(0,r.jsx)(s.p,{children:"Real world example:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.a,{href:"https://www.supermicro.com/en/products/system/iot/1u/sys-110d-8c-fran8tp",children:"Supermicro SuperServer SYS-110D-8C-FRAN8TP"})}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"2x SSD or NVMe with at least 480 GByte for the operating system"}),"\n",(0,r.jsx)(s.li,{children:"2x DIMM slots with 32 GByte modules, leave 2 DIMM slots open for later expansion"}),"\n",(0,r.jsx)(s.li,{children:"If required, an additional dual port 25G or 100G NIC in the PCIe expansion slots"}),"\n",(0,r.jsx)(s.li,{children:"Intel Xeon Processor D-2733NT (this is onboard and not selectable)"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"manager-nodes",children:"Manager nodes"}),"\n",(0,r.jsx)(s.p,{children:"The manager node, also known as the deploy node or deployment node, is designated\nto manage the deployment process of all services. It is often also utilized to host\ncomponents of the monitoring services. It serves as the operator's entry point into\nthe cluster for operations."}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"2x SSD or NVMe with at least 1.92 TByte for the operating system and the services"}),"\n",(0,r.jsx)(s.li,{children:"64 GByte memory (it should be possible to upgrade to 128 GByte, or use 128 GByte directly)"}),"\n",(0,r.jsx)(s.li,{children:"Dual port NIC with 25G or 100G (depending on which leaf switches are used)"}),"\n",(0,r.jsx)(s.li,{children:"1 CPU socket with at least 16 cores"}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Real world example:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"https://www.supermicro.com/de/products/system/clouddc/1u/sys-121c-tn10r",children:"https://www.supermicro.com/de/products/system/clouddc/1u/sys-121c-tn10r"})}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"switches",children:"Switches"}),"\n",(0,r.jsx)(s.h3,{id:"management-switches",children:"Management switches"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["1G: ",(0,r.jsx)(s.a,{href:"https://www.edge-core.com/product/as4610-54t/",children:"Edgecore AS4610-54T"})]}),"\n",(0,r.jsxs)(s.li,{children:["10G: ",(0,r.jsx)(s.a,{href:"https://www.edge-core.com/product/dcs202/",children:"Edgecore DCS202 - AS5835-54T"})]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"leaf-switches",children:"Leaf switches"}),"\n",(0,r.jsx)(s.p,{children:"It is recommended to always use 100G for the data plane and the storage nodes.\nEspecially when using all-flash storage nodes, there is then enough bandwidth\navailable. The more and the larger flash devices you use, the more bandwidth is\nrequired."}),"\n",(0,r.jsx)(s.p,{children:"With the leaf switches for the compute plane, it depends on how large the compute\nnodes are. The more CPU sockets/cores and the more memory the compute nodes have,\nthe more bandwidth is required on the compute nodes. Depending on how large the racks\nare (or better how much power you can use in it), it may make sense to work with 100G\nswitches for the compute plane or with 25G switches if 4x 25G per compute node are used\ninstead of 2x 25G per compute node (if the compute nodes are large enough)."}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["25G: ",(0,r.jsx)(s.a,{href:"https://www.edge-core.com/product/dcs203/",children:"Edgecore DCS203 - AS7326-56X"})]}),"\n",(0,r.jsxs)(s.li,{children:["100G: ",(0,r.jsx)(s.a,{href:"https://www.edge-core.com/product/dcs204/",children:"Edgecore DCS204 - AS7726-32X"})]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"spine-switches",children:"Spine switches"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["100G: ",(0,r.jsx)(s.a,{href:"https://www.edge-core.com/product/dcs204/",children:"Edgecore DCS204 - AS7726-32X"})]}),"\n",(0,r.jsxs)(s.li,{children:["400G: ",(0,r.jsx)(s.a,{href:"https://www.edge-core.com/product/dcs510/",children:"Edgecore DCS510 - AS9716-32D"})]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"network-interface-cards",children:"Network interface cards"})]})}function h(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>i,x:()=>d});var t=n(96540);const r={},o=t.createContext(r);function i(e){const s=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/013c29c1.a7e3cf87.js b/assets/js/013c29c1.a7e3cf87.js new file mode 100644 index 0000000000..b22bd6898f --- /dev/null +++ b/assets/js/013c29c1.a7e3cf87.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[90923],{41984:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"operating-scs/components/monitoring/docs/zuul","title":"Zuul monitoring","description":"This page contains instructions on how to enable the Zuul monitoring in the Observer solution.","source":"@site/docs/04-operating-scs/components/monitoring/docs/zuul.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/zuul","permalink":"/docs/operating-scs/components/monitoring/docs/zuul","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/zuul.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"KaaS monitoring (experimental)","permalink":"/docs/operating-scs/components/monitoring/docs/kaas"},"next":{"title":"Alertmanager notifications in Matrix chat","permalink":"/docs/operating-scs/components/monitoring/docs/alertmanager"}}');var s=o(74848),r=o(28453);const i={},a="Zuul monitoring",c={},l=[];function u(e){const n={code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"zuul-monitoring",children:"Zuul monitoring"})}),"\n",(0,s.jsx)(n.p,{children:"This page contains instructions on how to enable the Zuul monitoring in the Observer solution."}),"\n",(0,s.jsx)(n.p,{children:"Zuul comes with support for the statsd protocol, hence the graphite instance is needed when\nwe want directly consume Zuul metrics."}),"\n",(0,s.jsx)(n.p,{children:"Graphite deployment:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"helm add repo kiwigrid https://kiwigrid.github.io\nhelm upgrade --install graphite kiwigrid/graphite -f zuul/values-zuul.yaml\n"})}),"\n",(0,s.jsx)(n.p,{children:"A UDP load balancer that exposes the Graphite receiver service:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f zuul/udp-lb-service.yaml\n"})}),"\n",(0,s.jsx)(n.p,{children:"Zuul dashboards:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f zuul/zuul-status-dashboard.yaml\nkubectl apply -f zuul/zuul-nodepool-dashboard.yaml\nkubectl create -f zuul/zuul-zookeeper-dashboard.yaml\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Find and uncomment a related section in ",(0,s.jsx)(n.code,{children:"values-observer.yaml"})," if you want to link the above\ndashboards to the L1 Zuul host dashboard.\nThe sections related to Zuul in the ",(0,s.jsx)(n.code,{children:"values-observer-scs.yaml"})," values file are already uncommented."]})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>a});var t=o(96540);const s={},r=t.createContext(s);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/01a85c17.38b15a38.js b/assets/js/01a85c17.38b15a38.js new file mode 100644 index 0000000000..bf849a139a --- /dev/null +++ b/assets/js/01a85c17.38b15a38.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8209],{44096:(e,t,a)=>{a.d(t,{in:()=>c,OU:()=>P,Ki:()=>A,kJ:()=>b,x:()=>l,e7:()=>m,J_:()=>f,Gx:()=>y});var s=a(96540),n=a(89532),i=a(36803),r=a(74848);function l(){const e=(0,i.A)(),t=e?.data?.blogMetadata;if(!t)throw new Error("useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context");return t}const o=s.createContext(null);function c(e){let{children:t,content:a,isBlogPostPage:n=!1}=e;const i=function(e){let{content:t,isBlogPostPage:a}=e;return(0,s.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:a})),[t,a])}({content:a,isBlogPostPage:n});return(0,r.jsx)(o.Provider,{value:i,children:t})}function m(){const e=(0,s.useContext)(o);if(null===e)throw new n.dV("BlogPostProvider");return e}var d=a(86025),u=a(44586);const g=e=>new Date(e).toISOString();function h(e){const t=e.map(x);return{author:1===t.length?t[0]:t}}function p(e,t,a){return e?{image:j({imageUrl:t(e,{absolute:!0}),caption:`title image for the blog post: ${a}`})}:{}}function b(e){const{siteConfig:t}=(0,u.A)(),{withBaseUrl:a}=(0,d.hH)(),{metadata:{blogDescription:s,blogTitle:n,permalink:i}}=e,r=`${t.url}${i}`;return{"@context":"https://schema.org","@type":"Blog","@id":r,mainEntityOfPage:r,headline:n,description:s,blogPost:e.items.map((e=>function(e,t,a){const{assets:s,frontMatter:n,metadata:i}=e,{date:r,title:l,description:o,lastUpdatedAt:c}=i,m=s.image??n.image,d=n.keywords??[],u=`${t.url}${i.permalink}`,b=c?g(c):void 0;return{"@type":"BlogPosting","@id":u,mainEntityOfPage:u,url:u,headline:l,name:l,description:o,datePublished:r,...b?{dateModified:b}:{},...h(i.authors),...p(m,a,l),...d?{keywords:d}:{}}}(e.content,t,a)))}}function f(){const e=l(),{assets:t,metadata:a}=m(),{siteConfig:s}=(0,u.A)(),{withBaseUrl:n}=(0,d.hH)(),{date:i,title:r,description:o,frontMatter:c,lastUpdatedAt:b}=a,f=t.image??c.image,x=c.keywords??[],j=b?g(b):void 0,N=`${s.url}${a.permalink}`;return{"@context":"https://schema.org","@type":"BlogPosting","@id":N,mainEntityOfPage:N,url:N,headline:r,name:r,description:o,datePublished:i,...j?{dateModified:j}:{},...h(a.authors),...p(f,n,r),...x?{keywords:x}:{},isPartOf:{"@type":"Blog","@id":`${s.url}${e.blogBasePath}`,name:e.blogTitle}}}function x(e){return{"@type":"Person",...e.name?{name:e.name}:{},...e.title?{description:e.title}:{},...e.url?{url:e.url}:{},...e.email?{email:e.email}:{},...e.imageURL?{image:e.imageURL}:{}}}function j(e){let{imageUrl:t,caption:a}=e;return{"@type":"ImageObject","@id":t,url:t,contentUrl:t,caption:a}}var N=a(56347),v=a(28774),C=a(31682),k=a(99169);function y(e){const{pathname:t}=(0,N.zy)();return(0,s.useMemo)((()=>e.filter((e=>function(e,t){return!(e.unlisted&&!(0,k.ys)(e.permalink,t))}(e,t)))),[e,t])}function A(e){const t=(0,C.$z)(e,(e=>`${new Date(e.date).getFullYear()}`)),a=Object.entries(t);return a.reverse(),a}function P(e){let{items:t,ulClassName:a,liClassName:s,linkClassName:n,linkActiveClassName:i}=e;return(0,r.jsx)("ul",{className:a,children:t.map((e=>(0,r.jsx)("li",{className:s,children:(0,r.jsx)(v.A,{isNavLink:!0,to:e.permalink,className:n,activeClassName:i,children:e.title})},e.permalink)))})}},28027:(e,t,a)=>{a.d(t,{A:()=>O});var s=a(96540),n=a(18215),i=a(59504),r=a(24581),l=a(21312),o=a(44096),c=a(6342),m=a(51107),d=a(74848);function u(e){let{year:t,yearGroupHeadingClassName:a,children:s}=e;return(0,d.jsxs)("div",{role:"group",children:[(0,d.jsx)(m.A,{as:"h3",className:a,children:t}),s]})}function g(e){let{items:t,yearGroupHeadingClassName:a,ListComponent:s}=e;if((0,c.p)().blog.sidebar.groupByYear){const e=(0,o.Ki)(t);return(0,d.jsx)(d.Fragment,{children:e.map((e=>{let[t,n]=e;return(0,d.jsx)(u,{year:t,yearGroupHeadingClassName:a,children:(0,d.jsx)(s,{items:n})},t)}))})}return(0,d.jsx)(s,{items:t})}const h=(0,s.memo)(g),p="sidebar_re4s",b="sidebarItemTitle_pO2u",f="sidebarItemList_Yudw",x="sidebarItem__DBe",j="sidebarItemLink_mo7H",N="sidebarItemLinkActive_I1ZP",v="yearGroupHeading_rMGB",C=e=>{let{items:t}=e;return(0,d.jsx)(o.OU,{items:t,ulClassName:(0,n.A)(f,"clean-list"),liClassName:x,linkClassName:j,linkActiveClassName:N})};function k(e){let{sidebar:t}=e;const a=(0,o.Gx)(t.items);return(0,d.jsx)("aside",{className:"col col--3",children:(0,d.jsxs)("nav",{className:(0,n.A)(p,"thin-scrollbar"),"aria-label":(0,l.T)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"}),children:[(0,d.jsx)("div",{className:(0,n.A)(b,"margin-bottom--md"),children:t.title}),(0,d.jsx)(h,{items:a,ListComponent:C,yearGroupHeadingClassName:v})]})})}const y=(0,s.memo)(k);var A=a(75600);const P={yearGroupHeading:"yearGroupHeading_QT03"},_=e=>{let{items:t}=e;return(0,d.jsx)(o.OU,{items:t,ulClassName:"menu__list",liClassName:"menu__list-item",linkClassName:"menu__link",linkActiveClassName:"menu__link--active"})};function w(e){let{sidebar:t}=e;const a=(0,o.Gx)(t.items);return(0,d.jsx)(h,{items:a,ListComponent:_,yearGroupHeadingClassName:P.yearGroupHeading})}function B(e){return(0,d.jsx)(A.GX,{component:w,props:e})}const G=(0,s.memo)(B);function H(e){let{sidebar:t}=e;const a=(0,r.l)();return t?.items.length?"mobile"===a?(0,d.jsx)(G,{sidebar:t}):(0,d.jsx)(y,{sidebar:t}):null}function O(e){const{sidebar:t,toc:a,children:s,...r}=e,l=t&&t.items.length>0;return(0,d.jsx)(i.A,{...r,children:(0,d.jsx)("div",{className:"container margin-vert--lg",children:(0,d.jsxs)("div",{className:"row",children:[(0,d.jsx)(H,{sidebar:t}),(0,d.jsx)("main",{className:(0,n.A)("col",{"col--7":l,"col--9 col--offset-1":!l}),children:s}),a&&(0,d.jsx)("div",{className:"col col--2",children:a})]})})})}},69158:(e,t,a)=>{a.r(t),a.d(t,{default:()=>b});a(96540);var s=a(18215),n=a(21312);const i=()=>(0,n.T)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});var r=a(61213),l=a(17559),o=a(28027),c=a(56133),m=a(51107);const d={tag:"tag_Nnez"};var u=a(74848);function g(e){let{letterEntry:t}=e;return(0,u.jsxs)("article",{children:[(0,u.jsx)(m.A,{as:"h2",id:t.letter,children:t.letter}),(0,u.jsx)("ul",{className:"padding--none",children:t.tags.map((e=>(0,u.jsx)("li",{className:d.tag,children:(0,u.jsx)(c.A,{...e})},e.permalink)))}),(0,u.jsx)("hr",{})]})}function h(e){let{tags:t}=e;const a=function(e){const t={};return Object.values(e).forEach((e=>{const a=function(e){return e[0].toUpperCase()}(e.label);t[a]??=[],t[a].push(e)})),Object.entries(t).sort(((e,t)=>{let[a]=e,[s]=t;return a.localeCompare(s)})).map((e=>{let[t,a]=e;return{letter:t,tags:a.sort(((e,t)=>e.label.localeCompare(t.label)))}}))}(t);return(0,u.jsx)("section",{className:"margin-vert--lg",children:a.map((e=>(0,u.jsx)(g,{letterEntry:e},e.letter)))})}var p=a(41463);function b(e){let{tags:t,sidebar:a}=e;const n=i();return(0,u.jsxs)(r.e3,{className:(0,s.A)(l.G.wrapper.blogPages,l.G.page.blogTagsListPage),children:[(0,u.jsx)(r.be,{title:n}),(0,u.jsx)(p.A,{tag:"blog_tags_list"}),(0,u.jsxs)(o.A,{sidebar:a,children:[(0,u.jsx)(m.A,{as:"h1",children:n}),(0,u.jsx)(h,{tags:t})]})]})}},56133:(e,t,a)=>{a.d(t,{A:()=>l});a(96540);var s=a(18215),n=a(28774);const i={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var r=a(74848);function l(e){let{permalink:t,label:a,count:l,description:o}=e;return(0,r.jsxs)(n.A,{href:t,title:o,className:(0,s.A)(i.tag,l?i.tagWithCount:i.tagRegular),children:[a,l&&(0,r.jsx)("span",{children:l})]})}}}]); \ No newline at end of file diff --git a/assets/js/03412b54.4d6caf84.js b/assets/js/03412b54.4d6caf84.js new file mode 100644 index 0000000000..358d8dc342 --- /dev/null +++ b/assets/js/03412b54.4d6caf84.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9382],{86925:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>s,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"tools/github/dco-and-licenses","title":"Developer Certificate of Origin + Licenses","description":"The Developer Certificate of Origin (DCO) is a lightweight way for contributors","source":"@site/community/tools/github/dco-and-licenses.md","sourceDirName":"tools/github","slug":"/tools/github/dco-and-licenses","permalink":"/community/tools/github/dco-and-licenses","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Branch Protection Rules","permalink":"/community/tools/github/branchprotection"},"next":{"title":"Tips and Tricks","permalink":"/community/tools/github/tips-and-tricks"}}');var o=t(74848),r=t(28453);const s={},c="Developer Certificate of Origin + Licenses",a={},d=[{value:"Further reading",id:"further-reading",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"developer-certificate-of-origin--licenses",children:"Developer Certificate of Origin + Licenses"})}),"\n",(0,o.jsx)(n.p,{children:"The Developer Certificate of Origin (DCO) is a lightweight way for contributors\nto certify that they wrote or otherwise have the right to submit the code they\nare contributing to the Sovereign Cloud Stack."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"By making a contribution to this project, I certify that:\n\n(a) The contribution was created in whole or in part by me and I\n have the right to submit it under the open source license\n indicated in the file; or\n\n(b) The contribution is based upon previous work that, to the best\n of my knowledge, is covered under an appropriate open source\n license and I have the right under that license to submit that\n work with modifications, whether created in whole or in part\n by me, under the same open source license (unless I am\n permitted to submit under a different license), as indicated\n in the file; or\n\n(c) The contribution was provided directly to me by some other\n person who certified (a), (b) or (c) and I have not modified\n it.\n\n(d) I understand and agree that this project and the contribution\n are public and that a record of the contribution (including all\n personal information I submit with it, including my sign-off) is\n maintained indefinitely and may be redistributed consistent with\n this project or the open source license(s) involved.\n"})}),"\n",(0,o.jsxs)(n.p,{children:["All contributions to the Sovereign Cloud Stack are licensed under the\n(OSI approved) open source license of the upstream project being used therein\n(very often this is the ",(0,o.jsx)(n.a,{href:"https://www.apache.org/licenses/LICENSE-2.0",children:"Apache Software License v2"}),")."]}),"\n",(0,o.jsxs)(n.p,{children:["Where we create independent code, we prefer to use the ",(0,o.jsx)(n.a,{href:"https://www.gnu.org/licenses/agpl-3.0.html",children:"GNU Affero General Public License 3"}),",\nexcept for interface code which we would put under LGPL-3 (weak copyleft).\nOwn documentation content is licensed under ",(0,o.jsx)(n.a,{href:"https://creativecommons.org/licenses/by-sa/4.0/",children:"Creative Commons BY-SA 4.0"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Contributors sign-off that they adhere to these requirements by adding a ",(0,o.jsx)(n.code,{children:"Signed-off-by"}),"\nline to commit messages."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"My fancy commit message\n\nSigned-off-by: Christian Berendt \n"})}),"\n",(0,o.jsxs)(n.p,{children:["Git has a ",(0,o.jsx)(n.code,{children:"-s"})," command line option to append this automatically to your commit message:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"git commit -s -m 'My fancy commit message'\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The status of a pull request is set to failed if commits do not contain a valid ",(0,o.jsx)(n.code,{children:"Signed-off-by"})," line."]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{alt:"Failed DCO in GitHub",src:t(15120).A+"",width:"1868",height:"864"})}),"\n",(0,o.jsxs)(n.p,{children:["Considerations behind the choice of AGPLv3, CC-BY-SA and the usage of the DCO can be found ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/license-considerations.md",children:"license-considerations.md"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"further-reading",children:"Further reading"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://developercertificate.org/",children:"https://developercertificate.org/"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/",children:"https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://lwn.net/Articles/592503/",children:"https://lwn.net/Articles/592503/"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},15120:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/github-failed-dco-82f9dafea83c36769069087ceb522cdc.png"},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>c});var i=t(96540);const o={},r=i.createContext(o);function s(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03babb4a.9e0d0bfd.js b/assets/js/03babb4a.9e0d0bfd.js new file mode 100644 index 0000000000..c2bd097b13 --- /dev/null +++ b/assets/js/03babb4a.9e0d0bfd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[62294],{11141:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>a});const s=JSON.parse('{"id":"tools/github/tips-and-tricks","title":"Tips and Tricks","description":"Octo Reminder - your friendly assistant","source":"@site/community/tools/github/tips-and-tricks.md","sourceDirName":"tools/github","slug":"/tools/github/tips-and-tricks","permalink":"/community/tools/github/tips-and-tricks","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Developer Certificate of Origin + Licenses","permalink":"/community/tools/github/dco-and-licenses"},"next":{"title":"Test and development cloud resources","permalink":"/community/cloud-resources/"}}');var i=n(74848),r=n(28453);const o={},c="Tips and Tricks",d={},a=[{value:"Octo Reminder - your friendly assistant",id:"octo-reminder---your-friendly-assistant",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"tips-and-tricks",children:"Tips and Tricks"})}),"\n",(0,i.jsx)(t.h2,{id:"octo-reminder---your-friendly-assistant",children:"Octo Reminder - your friendly assistant"}),"\n",(0,i.jsxs)(t.p,{children:["Are you tired of keeping track of planned changes or issues you scheduled for the future? Our ",(0,i.jsx)(t.a,{href:"https://github.com/apps/octo-reminder",children:"Octo Reminder"})," is here to safe you from unneeded cognitive load!"]}),"\n",(0,i.jsxs)(t.p,{children:["The app configuration is stored in our ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/.github/",children:(0,i.jsx)(t.code,{children:".github"})})," repository. Using the bot is fairly simple:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["To schedule a reminder, simply comment with ",(0,i.jsx)(t.code,{children:"/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."]}),"\n",(0,i.jsx)(t.li,{children:"If you don't specify a time for the reminder, the bot will use 9:00 CET as default reminder time."}),"\n",(0,i.jsxs)(t.li,{children:["The date and time can be anything that ",(0,i.jsx)(t.a,{href:"https://momentjs.com/docs/#/parsing/",children:"momentjs"})," understands, e.g. an ISO 8601 string or a relative string such as ",(0,i.jsx)(t.code,{children:"tomorrow"})," or ",(0,i.jsx)(t.code,{children:"next week"}),"."]}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>c});var s=n(96540);const i={},r=s.createContext(i);function o(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03c8668f.3952c747.js b/assets/js/03c8668f.3952c747.js new file mode 100644 index 0000000000..10bd3099d8 --- /dev/null +++ b/assets/js/03c8668f.3952c747.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[74507],{12092:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>l,frontMatter:()=>d,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"ops/scs-0412","title":"scs-0412: Exposition of IaaS metering data as JSON","description":"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format","source":"@site/standards/ops/scs-0412.md","sourceDirName":"ops","slug":"/ops/scs-0412","permalink":"/standards/ops/scs-0412","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0411-v1-publishing_method_for_metering_data"},"next":{"title":"V1","permalink":"/standards/scs-0412-v1-metering-json"}}');var a=s(74848),r=s(28453);const d={},i="scs-0412: Exposition of IaaS metering data as JSON",o={},c=[];function h(e){const t={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"scs-0412-exposition-of-iaas-metering-data-as-json",children:"scs-0412: Exposition of IaaS metering data as JSON"})}),"\n",(0,a.jsx)(t.p,{children:"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format\nwithin the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with\ntheir existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format\nprovided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation\nlayers and implementation components."}),"\n",(0,a.jsxs)(t.table,{children:[(0,a.jsx)(t.thead,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.th,{children:"Version"}),(0,a.jsx)(t.th,{children:"Type"}),(0,a.jsx)(t.th,{children:"State"}),(0,a.jsx)(t.th,{children:"stabilized"}),(0,a.jsx)(t.th,{children:"deprecated"})]})}),(0,a.jsx)(t.tbody,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.td,{children:(0,a.jsx)(t.a,{href:"/standards/scs-0412-v1-metering-json",children:"scs-0412-v1"})}),(0,a.jsx)(t.td,{children:"Standard"}),(0,a.jsx)(t.td,{children:"Draft"}),(0,a.jsx)(t.td,{children:"-"}),(0,a.jsx)(t.td,{children:"-"})]})})]})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>i});var n=s(96540);const a={},r=n.createContext(a);function d(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/04437fec.659ced76.js b/assets/js/04437fec.659ced76.js new file mode 100644 index 0000000000..cfd0e1336e --- /dev/null +++ b/assets/js/04437fec.659ced76.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[59075],{85646:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"scs-0114-v1-volume-type-standard","title":"SCS Volume Types","description":"Introduction","source":"@site/standards/scs-0114-v1-volume-type-standard.md","sourceDirName":".","slug":"/scs-0114-v1-volume-type-standard","permalink":"/standards/scs-0114-v1-volume-type-standard","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Volume Types","type":"Standard","status":"Stable","stabilized_at":"2024-11-13T00:00:00.000Z","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0114: SCS Volume Types","permalink":"/standards/iaas/scs-0114"},"next":{"title":"scs-0115: Default Rules for Security Groups","permalink":"/standards/iaas/scs-0115"}}');var i=s(74848),o=s(28453);const a={title:"SCS Volume Types",type:"Standard",status:"Stable",stabilized_at:new Date("2024-11-13T00:00:00.000Z"),track:"IaaS"},r=void 0,d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Glossary",id:"glossary",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Systematic Description of Volume Types",id:"systematic-description-of-volume-types",level:3},{value:"Standardized Aspects",id:"standardized-aspects",level:3},{value:"DEFAULT volume type",id:"default-volume-type",level:2},{value:"REQUIRED volume types",id:"required-volume-types",level:2},{value:"RECOMMENDED volume types",id:"recommended-volume-types",level:2},{value:"OPTIONAL volume types",id:"optional-volume-types",level:2},{value:"Implementation Details",id:"implementation-details",level:2},{value:"Encryption",id:"encryption",level:3},{value:"Replication",id:"replication",level:3},{value:"Example",id:"example",level:3},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"A volume is a virtual drive that is to be used by an instance (i.e., a virtual machine). With OpenStack,\neach volume is created per a type that determines basic features of the volume as provided by the backend,\nsuch as encryption, replication, or quality of service. As of the writing of this document, presence or absence of these\nfeatures can not be discovered with full certainty by non-privileged users via the OpenStack API."}),"\n",(0,i.jsx)(t.h3,{id:"glossary",children:"Glossary"}),"\n",(0,i.jsx)(t.p,{children:"The following special terms are used throughout this standard document:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Term"}),(0,i.jsx)(t.th,{children:"Meaning"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"volume"}),(0,i.jsx)(t.td,{children:"OpenStack resource, virtual drive which usually resides in a network storage backend"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"volume feature"}),(0,i.jsx)(t.td,{children:"A certain feature a volume can possess"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"aspect"}),(0,i.jsx)(t.td,{children:"Part of a volume type that will activate a corresponding feature in a created volume"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"AZ"}),(0,i.jsx)(t.td,{children:"Availability Zone"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Volume QoS"}),(0,i.jsx)(t.td,{children:"Quality of Service object for Volumes"})]})]})]}),"\n",(0,i.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:"As an SCS user, I want to be able to create volumes with certain common features, such as encryption or\nreplication, and to do so in a standardized manner as well as programmatically.\nThis standard outlines a way of formally advertising these common aspects for a volume type to\nnon-privileged users, so that the most suitable volume type can be discovered and selected easily \u2014 both by\nthe human user and by a program."}),"\n",(0,i.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsxs)(t.p,{children:["All considerations can be looked up in detail in the ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0111-v1-volume-type-decisions.md",children:"Decision Record for the Volume Type Standard."})]}),"\n",(0,i.jsx)(t.h3,{id:"systematic-description-of-volume-types",children:"Systematic Description of Volume Types"}),"\n",(0,i.jsxs)(t.p,{children:["To test whether a deployment has volume types with certain aspects, the discoverability of the parameters in the volume type has to be given. As for the time this standard is created, there is no way for users to discover all aspects through OpenStack commands. Therefore, the aspects, that are fulfilled within a volume type, should be stated in the beginning of the ",(0,i.jsx)(t.strong,{children:"description"})," of a volume type in the following manner:"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.code,{children:"[scs:aspect1, aspect2, ..., aspectN]..."})}),"\n",(0,i.jsx)(t.p,{children:"The mentioned aspects MUST be sorted alphabetically and every aspect should only be mentioned to the maximal amount of one."}),"\n",(0,i.jsx)(t.h3,{id:"standardized-aspects",children:"Standardized Aspects"}),"\n",(0,i.jsx)(t.p,{children:"The following table shows which aspects are considered in this standard. The third column shows how the description of the volume type has to be adjusted, if the aspect is fulfilled:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Aspect"}),(0,i.jsx)(t.th,{children:"Requirement"}),(0,i.jsx)(t.th,{children:"standardized description"}),(0,i.jsx)(t.th,{children:"comment"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Encryption"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Recommended"})}),(0,i.jsx)(t.td,{children:(0,i.jsxs)(t.strong,{children:['"[scs',":encrypted",']"']})}),(0,i.jsx)(t.td,{children:"volume is encrypted"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Replication"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Recommended"})}),(0,i.jsx)(t.td,{children:(0,i.jsxs)(t.strong,{children:['"[scs',":replicated",']"']})}),(0,i.jsx)(t.td,{children:"volume is replicated to avoid data loss in a case of hardware failure"})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"It is possible to use multiple of those aspects within one volume type. There don't have to be different volume types for each aspect.\nFor instance, one volume type that uses LUKS-encryption with a ceph storage with inherent replication would fulfill all recommendations of this standard."}),"\n",(0,i.jsx)(t.h2,{id:"default-volume-type",children:"DEFAULT volume type"}),"\n",(0,i.jsxs)(t.p,{children:["There is always a default volume type defined in an OpenStack deployment. This volume type is created in the setup of cinder and will always be present in any OpenStack deployments under the name ",(0,i.jsx)(t.code,{children:"__default__"}),". This standard does not have any requirements about this volume type at this moment, instead deployers are free to choose what fits best in their environment. Conversely, a cloud user can not expect any specific behavior or properties from volume types named ",(0,i.jsx)(t.code,{children:"__default__"}),"."]}),"\n",(0,i.jsx)(t.h2,{id:"required-volume-types",children:"REQUIRED volume types"}),"\n",(0,i.jsx)(t.p,{children:"Currently, this standard will not require volume types with certain specification."}),"\n",(0,i.jsx)(t.h2,{id:"recommended-volume-types",children:"RECOMMENDED volume types"}),"\n",(0,i.jsx)(t.p,{children:"This standard recommends to have one or more volume types, that feature encryption and replication."}),"\n",(0,i.jsx)(t.h2,{id:"optional-volume-types",children:"OPTIONAL volume types"}),"\n",(0,i.jsx)(t.p,{children:"Any other aspects of volume types, that can be found in the decision record are OPTIONAL. They SHOULD NOT be referenced in the way this standard describes. Some of them already are natively discoverable by users, while others could be described in the name or description of a volume type. Users should look into the provided volume types of the Cloud Service Providers, if they want to use some of these other aspects."}),"\n",(0,i.jsx)(t.h2,{id:"implementation-details",children:"Implementation Details"}),"\n",(0,i.jsx)(t.h3,{id:"encryption",children:"Encryption"}),"\n",(0,i.jsxs)(t.p,{children:["Encryption for volumes is an option which has to be configured within the volume type. As an admin it is possible to set encryption-provider, key size, cipher and control location. Additionally to be discoverable by users, the description should start with an aspect list such as ",(0,i.jsx)(t.code,{children:"[scs:encrypted]"})," (potentially with additional aspects). It should look like this example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-text",children:"openstack volume type show LUKS\n+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Field | Value |\n+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| access_project_ids | None |\n| description | [scs:encrypted] This volume uses LUKS-encryption |\n| id | d63307fb-167a-4aa0-9066-66595ea9fb21 |\n| is_public | True |\n| name | LUKS |\n| qos_specs_id | None |\n+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+\n"})}),"\n",(0,i.jsx)(t.h3,{id:"replication",children:"Replication"}),"\n",(0,i.jsx)(t.p,{children:"Replication states whether or not there are multiple replicas of a volume, i.e., whether the data could survive a node outage. Unfortunately, there are two ways replication can be achieved:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"In the configuration of a volume type. It then is visible as extra_spec in the properties of a volume type."}),"\n",(0,i.jsx)(t.li,{children:"Via the used backend. Ceph for example provides automatic replication, that does not need to be specified in the volume type. This is currently not visible for users."}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["To fulfill this recommendation, the description should start with an aspect list such as ",(0,i.jsx)(t.code,{children:"[scs:replicated]"})," (potentially with additional aspects)."]}),"\n",(0,i.jsx)(t.h3,{id:"example",children:"Example"}),"\n",(0,i.jsx)(t.p,{children:"One volume type that is configured as an encrypted volume type in a ceph backend, with automated replication would fit both recommendations and will be enough to comply to this part of the volume type standard."}),"\n",(0,i.jsx)(t.p,{children:"It should look like the following part:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-text",children:"+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Field | Value |\n+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| access_project_ids | None |\n| description | [scs:encrypted, replicated] Content will be replicated three times to ensure consistency and availability for your data. LUKS encryption is used. |\n| id | d63307fb-167a-4aa0-9066-66595ea9fb21 |\n| is_public | True |\n| name | hdd-three-replicas-LUKS |\n| properties | |\n| qos_specs_id | None |\n+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+\n"})}),"\n",(0,i.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["corresponding ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0111-v1-volume-type-decisions.md",children:"decision record document"})]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,i.jsxs)(t.p,{children:["The script ",(0,i.jsx)(t.code,{children:"/Tests/iaas/volume-types/volume-types-check.py"})," connects to an OpenStack environment and tests\nthe following:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["for each volume type: if its description starts with ",(0,i.jsx)(t.code,{children:"[scs:....]"}),", then this prefix is a feature list\n(sorted, each entry at most once), and each entry is one of the possible features described here,"]}),"\n",(0,i.jsx)(t.li,{children:"the recommended volume types are present (otherwise, a WARNING is produced)."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The return code is zero precisely when the test could be performed and the conditions are satisfied.\nOtherwise, detailed errors and warnings are output to stderr."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>r});var n=s(96540);const i={},o=n.createContext(i);function a(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0476f709.59f3f3b0.js b/assets/js/0476f709.59f3f3b0.js new file mode 100644 index 0000000000..a324c041aa --- /dev/null +++ b/assets/js/0476f709.59f3f3b0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[20344],{41031:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"scs-0215-v1-robustness-features","title":"Robustness features for Kubernetes clusters","description":"Introduction","source":"@site/standards/scs-0215-v1-robustness-features.md","sourceDirName":".","slug":"/scs-0215-v1-robustness-features","permalink":"/standards/scs-0215-v1-robustness-features","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Robustness features for Kubernetes clusters","type":"Standard","status":"Draft","track":"KaaS"},"sidebar":"standards","previous":{"title":"scs-0215: Robustness features for Kubernetes clusters","permalink":"/standards/kaas/scs-0215"},"next":{"title":"scs-0216: Requirements for testing cluster-stacks","permalink":"/standards/kaas/scs-0216"}}');var s=n(74848),r=n(28453);const a={title:"Robustness features for Kubernetes clusters",type:"Standard",status:"Draft",track:"KaaS"},o=void 0,c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Glossary",id:"glossary",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Kube-API rate limiting",id:"kube-api-rate-limiting",level:3},{value:"API server flags",id:"api-server-flags",level:4},{value:"Ratelimit Admission Controller",id:"ratelimit-admission-controller",level:4},{value:"Flow control",id:"flow-control",level:4},{value:"etcd maintenance",id:"etcd-maintenance",level:3},{value:"etcd backup",id:"etcd-backup",level:3},{value:"Certificate rotation",id:"certificate-rotation",level:3},{value:"Automatic certificate rotation",id:"automatic-certificate-rotation",level:4},{value:"Decision",id:"decision",level:2},{value:"Kube-API rate limiting",id:"kube-api-rate-limiting-1",level:3},{value:"etcd compaction",id:"etcd-compaction",level:3},{value:"etcd backup",id:"etcd-backup-1",level:3},{value:"Certificate rotation",id:"certificate-rotation-1",level:3},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function d(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(t.p,{children:"Kubernetes clusters in a productive environment are under the assumption to always perform perfectly without any major\ninterruptions. But due to external or unforeseen influences, clusters can be disrupted in their normal workflow, which\ncould lead to slow responsiveness or even malfunctions.\nIn order to possibly mitigate some problems for the Kubernetes clusters, robustness features should be introduced into\nthe SCS standards. These would harden the cluster infrastructure against several problems, making failures less likely."}),"\n",(0,s.jsx)(t.h3,{id:"glossary",children:"Glossary"}),"\n",(0,s.jsx)(t.p,{children:"The following special terms are used throughout this standard document:"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Term"}),(0,s.jsx)(t.th,{children:"Abbreviation"}),(0,s.jsx)(t.th,{children:"Meaning"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Certificate Authority"}),(0,s.jsx)(t.td,{children:"CA"}),(0,s.jsx)(t.td,{children:"Trusted organization that issues digital certificates entities"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Certificate Signing Request"}),(0,s.jsx)(t.td,{children:"CSR"}),(0,s.jsx)(t.td,{children:"Request in order to apply for a digital identity certificate"})]})]})]}),"\n",(0,s.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(t.p,{children:"A typical productive Kubernetes cluster could be hardened in many different ways, whereas probably many of these actions\nwould overlap and target similar weaknesses of a cluster.\nFor this version of the standard, the following points should be addressed:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Kube-API rate limiting"}),"\n",(0,s.jsx)(t.li,{children:"etcd compaction/defragmentation"}),"\n",(0,s.jsx)(t.li,{children:"etcd backup"}),"\n",(0,s.jsx)(t.li,{children:"Certificate Authority (CA) expiration avoidance"}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:'These robustness features should mainly increase the up-time of the Kubernetes cluster by avoiding downtimes either\nbecause of internal problems or external threads like "Denial of Service" attacks.\nAdditionally, the etcd database should be strengthened with these features in order to provide a secure and robust\nbackend for the Kubernetes cluster.'}),"\n",(0,s.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsx)(t.p,{children:"In order to provide a conclusive standard, some design considerations need to be set beforehand:"}),"\n",(0,s.jsx)(t.h3,{id:"kube-api-rate-limiting",children:"Kube-API rate limiting"}),"\n",(0,s.jsx)(t.p,{children:"Rate limiting is the practice of preventing too many requests to the same server in some time frame. This can help prevent\nservice interruptions due to congestion and therefore slow responsiveness or even service shutdown.\nKubernetes suggests multiple ways to integrate such a Ratelimit for its API server, a few of which will be mentioned here.\nIn order to provide a useful Ratelimit for the Kubernetes cluster, combination of these methods should be considered."}),"\n",(0,s.jsx)(t.h4,{id:"api-server-flags",children:"API server flags"}),"\n",(0,s.jsx)(t.p,{children:"The Kubernetes API server has some flags available to limit the amount of incoming requests that will be accepted by\nthe server, which should prevent crashing of the API server. This nevertheless shouldn't be the only measure to\nintroduce a rate limit, since important requests could get blocked during high traffic periods (at least according to\nthe official documentation).\nThe following controls are available to tune the server:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"max-requests-inflight"}),"\n",(0,s.jsx)(t.li,{children:"max-mutating-requests-inflight"}),"\n",(0,s.jsx)(t.li,{children:"min-request-timeout"}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["More details can be found in the following documents:\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/flow-control/",children:"Flow Control"})]}),"\n",(0,s.jsx)(t.h4,{id:"ratelimit-admission-controller",children:"Ratelimit Admission Controller"}),"\n",(0,s.jsxs)(t.p,{children:["From version 1.13 onwards, Kubernetes includes a EventRateLimit Admission Controller, which aims to mitigate Ratelimit\nproblems associated with the API server by providing limits for requests every second either to specific resources or\neven the whole API server. If requests are denied due to this Admission Controller, they're either cached or denied\ncompletely and need to be retried; this also depends on the EventRateLimit configuration.\nMore details can be found in the following documents:\n",(0,s.jsx)(t.a,{href:"https://rke.docs.rancher.com/config-options/rate-limiting",children:"Rancher rate limiting"}),"\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#eventratelimit",children:"EventRateLimit"}),"\nIt is important to note, that this only helps the API server against event overloads and not necessarily the network\nin front of it, which could still be overwhelmed."]}),"\n",(0,s.jsx)(t.h4,{id:"flow-control",children:"Flow control"}),"\n",(0,s.jsxs)(t.p,{children:["Flow control for the Kubernetes API server can be provided by the API priority and fairness feature, which classifies\nand isolates requests in a fine-grained way in order to prevent an overload of the API server.\nThe package introduces queues in order to not deny requests and dequeue them through Fair Queueing techniques.\nOverall, the Flow control package introduces many different features like request queues, rule-based flow control,\ndifferent priority levels and rate limit maximums.\nThe concept documentation offers a more in-depth explanation of the feature:\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/flow-control/",children:"Flow Control"})]}),"\n",(0,s.jsx)(t.h3,{id:"etcd-maintenance",children:"etcd maintenance"}),"\n",(0,s.jsx)(t.p,{children:"etcd is a strongly consistent, distributed key-value store that provides a reliable way to store data that needs to be\naccessed by a distributed system or cluster of machines. For these reasons, etcd was chosen as the default database\nfor Kubernetes.\nIn order to remain reliable, an etcd cluster needs periodic maintenance. This is necessary to maintain the etcd keyspace;\nfailure to do so could lead to a cluster-wide alarm, which would put the cluster into a limited-operation mode.\nTo mitigate this scenario, the etcd keyspace can be compacted. Additionally, an etcd cluster can be defragmented, which\ngives back disk space to the underlying file system and can help bring the cluster back into an operable state, if it\nran out of space earlier."}),"\n",(0,s.jsx)(t.p,{children:"etcd keyspace maintenance can be achieved by providing the necessary flags/parameters to etcd, either via the KubeadmControlPlane or in the\nconfiguration file of the etcd cluster, if it is managed independent of the Kubernetes cluster.\nPossible flags, that can be set for this feature, are:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"auto-compaction-mode"}),"\n",(0,s.jsx)(t.li,{children:"auto-compaction-retention"}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["More information about compaction can be found in the respective etcd documentation\n",(0,s.jsx)(t.a,{href:"https://etcd.io/docs/v3.3/op-guide/maintenance/",children:"etcd maintenance"})]}),"\n",(0,s.jsx)(t.h3,{id:"etcd-backup",children:"etcd backup"}),"\n",(0,s.jsxs)(t.p,{children:["An etcd cluster should be regularly backed up in order to be able to restore the cluster to a known good state at an\nearlier space in time if a failure or incorrect state happens.\nThe cluster should be backed up multiple times in order to have different possible states to go back to. This is especially\nuseful, if data in the newer backups was already corrupted in some way or important data was deleted in them.\nFor this reason, a backup strategy needs to be developed with a decreasing number of backups in an increasing period of time,\nmeaning that the previous year should only have 1 backup, but the current week should have multiple.\nInformation about the backup process can be found in the etcd documentation:\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/",children:"Upgrade etcd"})]}),"\n",(0,s.jsx)(t.h3,{id:"certificate-rotation",children:"Certificate rotation"}),"\n",(0,s.jsxs)(t.p,{children:["In order to secure the communication of a Kubernetes cluster, (TLS) certificates signed by a controlled\nCertificate Authority (CA) can be used.\nNormally, these certificates expire after a set period of time. In order to avoid expiration and failure of a cluster,\nthese certificates need to be rotated regularly and at best automatically.\nCertificates can either be rotated manually (a reference for manually working with certificates can be found\n",(0,s.jsx)(t.a,{href:"https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/79a3f79b27bd28f82f071bb877a266c2e62ee506/docs/04-certificate-authority.md",children:"here"}),")\nor automatically, which requires other things to care about in a deployment."]}),"\n",(0,s.jsxs)(t.p,{children:["Some tools or clusters provide possibilities to rotate certificates manually.\nFor example, ",(0,s.jsx)(t.code,{children:"kubeadm"})," and ",(0,s.jsx)(t.code,{children:"k3s"})," provides the following commands"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"# kubeadm\nkubeadm certs renew all\n\n# k3s\nk3s certificate rotate\n"})}),"\n",(0,s.jsx)(t.p,{children:"A CA might also expire. Unfortunately, not all Kubernetes tools have functionality to renew these certificates.\nInstead, documentation is provided to manually rotating a CA ([Manual rotation of ca certificate])."}),"\n",(0,s.jsx)(t.h4,{id:"automatic-certificate-rotation",children:"Automatic certificate rotation"}),"\n",(0,s.jsxs)(t.p,{children:["kubelet can be configured to obtain properly signed certificates from the ",(0,s.jsx)(t.code,{children:"certificates.k8s.io"})," API of Kubernetes.\nTo do this, set ",(0,s.jsx)(t.code,{children:"serverTLSBootstrap: true"})," in the configuration file of kubelet, which enables both the certificate request\nduring bootstrapping and the rotation mechanism. Setting ",(0,s.jsx)(t.code,{children:"rotateCertificates: true"})," only enables the certificate rotation [Kubeadm certs].\n",(0,s.jsx)(t.code,{children:"--rotate-certificates"})," or ",(0,s.jsx)(t.code,{children:"--rotate-server-certificates"})," shouldn't be used as command line arguments to set these flags,\nsince both parameters are deprecated according to [Certificate rotation]."]}),"\n",(0,s.jsxs)(t.p,{children:["It is also important to note that some Kubernetes clusters or admin tools provide additional ways to rotate certificates.\nFor example, ",(0,s.jsx)(t.code,{children:"kubeadm"})," automatically rotates certificates, if the cluster is updated with the tool (see [Automatic Certificate renewal]).\nThis would also mean, that at least ",(0,s.jsx)(t.code,{children:"kubeadm"}),"-based clusters can be assumed to rotate their certificates regularly,\nsince they would probably be updated within the time period described in the\nstandard ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Standards/scs-0210-v2-k8s-version-policy.md",children:"SCS-0210-v2"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["If an automatic certificate rotation happens, these certificates need to be approved either manually or by a third party\ncontroller like the ",(0,s.jsx)(t.a,{href:"https://github.com/postfinance/kubelet-csr-approver",children:"kubelet csr approver"}),", which can be deployed on\na Kubernetes cluster to automate this process."]}),"\n",(0,s.jsx)(t.p,{children:"A manual approval of these CSRs could be done with the commands"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"kubectl get csr\nkubectl certificate approve \n"})}),"\n",(0,s.jsx)(t.p,{children:"in order to complete a certificate rotation.\nBut it should be noted, that this is also most likely dependent on the Kubernetes cluster solution in use."}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"kubectl get csr"})," allows to check, if a CSR needs to be approved; a ",(0,s.jsx)(t.code,{children:"Pending"})," CSR would need to be approved."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"NAME AGE SIGNERNAME REQUESTOR CONDITION\ncsr-9wvgt 112s kubernetes.io/kubelet-serving system:node:worker-1 Pending\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Further information and examples can be found in the Kubernetes documentation:\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/",children:"Kubeadm certs"}),"\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/kubelet-tls-bootstrapping/",children:"Kubelet TLS bootstrapping"})]}),"\n",(0,s.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsx)(t.p,{children:"Robustness features combine multiple aspects of increasing the security, hardness and\nlongevity of a Kubernetes cluster. The decisions will be separated into their respective\nareas."}),"\n",(0,s.jsx)(t.h3,{id:"kube-api-rate-limiting-1",children:"Kube-API rate limiting"}),"\n",(0,s.jsx)(t.p,{children:"The number of requests send to the kube-api or Kubernetes API server MUST be limited\nin order to protect the server against outages, deceleration or malfunctions due to an\noverload of requests.\nIn order to do so, at least the following parameters MUST be set on a Kubernetes cluster:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"max-requests-inflight"}),"\n",(0,s.jsx)(t.li,{children:"max-mutating-requests-inflight"}),"\n",(0,s.jsx)(t.li,{children:"min-request-timeout"}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Values for these flags/parameters SHOULD be adapted to the needs of the environment and\nthe expected load."}),"\n",(0,s.jsxs)(t.p,{children:["A cluster MUST also activate and configure a Ratelimit admission controller.\nThis requires an ",(0,s.jsx)(t.code,{children:"EventRateLimit"})," resource to be deployed on the Kubernetes cluster.\nThe following settings are RECOMMENDED for a cluster-wide deployment, but more\nfine-grained rate limiting can also be applied, if this is necessary."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"kind: Configuration\napiVersion: eventratelimit.admission.k8s.io/v1alpha1\nlimits:\n- burst: 20000\n qps: 5000\n type: Server\n"})}),"\n",(0,s.jsx)(t.p,{children:"It is also RECOMMENDED to activate the Kubernetes API priority and fairness feature,\nwhich also uses the aforementioned cluster parameters to better queue, schedule and\nprioritize incoming requests."}),"\n",(0,s.jsx)(t.h3,{id:"etcd-compaction",children:"etcd compaction"}),"\n",(0,s.jsx)(t.p,{children:"etcd MUST be cleaned up regularly, so that it functions correctly and doesn't take\nup too much space, which happens because of its increase of the keyspace."}),"\n",(0,s.jsx)(t.p,{children:"To compact the etcd keyspace, the following flags/parameters MUST be set for etcd:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"auto-compaction-mode = periodic"}),"\n",(0,s.jsx)(t.li,{children:"auto-compaction-retention = 8h"}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"etcd-backup-1",children:"etcd backup"}),"\n",(0,s.jsx)(t.p,{children:"An etcd cluster MUST be backed up regularly. It is RECOMMENDED to adapt\na strategy of decreasing backups over longer time periods, e.g. keeping snapshots every\n10 minutes for the last 120 minutes, then one hourly for 1 day, then one daily for 2 weeks,\nthen one weekly for 3 months, then one monthly for 2 years, and after that a yearly backup.\nAt the very least, a backup MUST be done once a week.\nThese numbers can be adapted to the security setup and concerns like storage or network\nusage. It is also RECOMMENDED to encrypt the backups in order to secure them further.\nHow this is done is up to the operator."}),"\n",(0,s.jsx)(t.h3,{id:"certificate-rotation-1",children:"Certificate rotation"}),"\n",(0,s.jsx)(t.p,{children:"It should be avoided, that certificates expire either on the whole cluster or for single components.\nTo avoid this scenario, certificates MUST be rotated regularly; in the\ncase of SCS, we REQUIRE at least a yearly certificate rotation."}),"\n",(0,s.jsx)(t.p,{children:"It is also RECOMMENDED to renew the CA regularly to avoid an expiration of the CA.\nThis standard doesn't set an exact timeline for a renewal, since it is dependent on lifetime and\ntherefore expiration date of the CA in question."}),"\n",(0,s.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/flow-control/",children:"Flow Control"}),"\n",(0,s.jsx)(t.a,{href:"https://rke.docs.rancher.com/config-options/rate-limiting",children:"Rate limiting"}),"\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#eventratelimit",children:"EventRateLimit"}),"\n",(0,s.jsx)(t.a,{href:"https://etcd.io/docs/v3.3/op-guide/maintenance/",children:"etcd maintenance"}),"\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/",children:"Upgrade etcd"}),"\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/",children:"Kubeadm certs"}),"\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/kubelet-tls-bootstrapping/",children:"Kubelet TLS bootstrapping"}),"\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/kubelet-tls-bootstrapping/#certificate-rotation",children:"Certificate rotation"}),"\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/tls/manual-rotation-of-ca-certificates/",children:"Manual rotation of ca certificate"}),"\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#automatic-certificate-renewal",children:"Automatic Certificate renewal"})]}),"\n",(0,s.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsx)(t.p,{children:"Conformance Tests, OPTIONAL"})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const s={},r=i.createContext(s);function a(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/04fe2bfd.00c9a014.js b/assets/js/04fe2bfd.00c9a014.js new file mode 100644 index 0000000000..e50172ed77 --- /dev/null +++ b/assets/js/04fe2bfd.00c9a014.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[12106],{9142:(t,e,o)=>{o.r(e),o.d(e,{assets:()=>l,contentTitle:()=>u,default:()=>m,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var s=o(30107),i=o(74848),n=o(28453);const r={slug:"first-blog-post",title:"First Blog Post",authors:"itrich",tags:["community","howto"]},u=void 0,l={authorsImageUrls:[void 0]},c=[];function a(t){const e={p:"p",...(0,n.R)(),...t.components};return(0,i.jsx)(e.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"})}function m(t={}){const{wrapper:e}={...(0,n.R)(),...t.components};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(a,{...t})}):a(t)}},28453:(t,e,o)=>{o.d(e,{R:()=>r,x:()=>u});var s=o(96540);const i={},n=s.createContext(i);function r(t){const e=s.useContext(n);return s.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function u(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:r(t.components),s.createElement(n.Provider,{value:e},t.children)}},30107:t=>{t.exports=JSON.parse('{"permalink":"/blog/first-blog-post","editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/blog/2022-10-28-first-blog-post.md","source":"@site/blog/2022-10-28-first-blog-post.md","title":"First Blog Post","description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet","date":"2022-10-28T00:00:00.000Z","tags":[{"inline":true,"label":"community","permalink":"/blog/tags/community"},{"inline":true,"label":"howto","permalink":"/blog/tags/howto"}],"readingTime":0.12,"hasTruncateMarker":false,"authors":[{"name":"Eduard Itrich","title":"Community Manager @ SCS","url":"https://github.com/itrich","imageURL":"https://github.com/itrich.png","key":"itrich","page":null}],"frontMatter":{"slug":"first-blog-post","title":"First Blog Post","authors":"itrich","tags":["community","howto"]},"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/05370f9a.e603f28e.js b/assets/js/05370f9a.e603f28e.js new file mode 100644 index 0000000000..2f59d75f1b --- /dev/null +++ b/assets/js/05370f9a.e603f28e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[92864],{10090:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>o,toc:()=>u});const o=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks","title":"Managing ClusterStack objects","description":"The ClusterStack object is the central resource that you have to work with. You have to specify a provider, the name of the cluster stack you want to use, as well as the Kubernetes minor version.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/topics","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks.md","tags":[],"version":"current","frontMatter":{}}');var n=s(74848),c=s(28453);const r={},a="Managing ClusterStack objects",i={},u=[];function l(e){const t={code:"code",h1:"h1",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"managing-clusterstack-objects",children:"Managing ClusterStack objects"})}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.code,{children:"ClusterStack"})," object is the central resource that you have to work with. You have to specify a provider, the name of the cluster stack you want to use, as well as the Kubernetes minor version."]}),"\n",(0,n.jsxs)(t.p,{children:["If you want to use multiple different Kubernetes minor versions, you will have to create multiple ",(0,n.jsx)(t.code,{children:"ClusterStack"})," objects. The same goes for multiple providers, or multiple cluster stacks (e.g. ferrol) that might have different features."]}),"\n",(0,n.jsxs)(t.p,{children:["In order to use a cluster stack in a specific version, you have two options: first, you can specify a list of versions in ",(0,n.jsx)(t.code,{children:"spec.versions"}),". Second, you can enable ",(0,n.jsx)(t.code,{children:"autoSubscribe"}),", so that the operator will automatically check for the latest version and make it available to you."]}),"\n",(0,n.jsx)(t.p,{children:"Usually, you will always want to use auto-subscribe, so that the operator takes care of providing you with the latest versions."})]})}function p(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>a});var o=s(96540);const n={},c=o.createContext(n);function r(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/05e7973d.690723a4.js b/assets/js/05e7973d.690723a4.js new file mode 100644 index 0000000000..1b297d3c2a --- /dev/null +++ b/assets/js/05e7973d.690723a4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[89823],{91610:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"iaas/guides/configuration-guide/commons/sshconfig","title":"SSH Config","description":"With the osism.commons.sshconfig role, it is possible to manage a SSH config","source":"@site/docs/02-iaas/guides/configuration-guide/commons/sshconfig.md","sourceDirName":"02-iaas/guides/configuration-guide/commons","slug":"/iaas/guides/configuration-guide/commons/sshconfig","permalink":"/docs/iaas/guides/configuration-guide/commons/sshconfig","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/sshconfig.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"SSH Config"},"sidebar":"docs","previous":{"title":"Services","permalink":"/docs/iaas/guides/configuration-guide/commons/services"},"next":{"title":"Sysctl","permalink":"/docs/iaas/guides/configuration-guide/commons/sysctl"}}');var i=s(74848),o=s(28453);const r={sidebar_label:"SSH Config"},d="SSH Config",l={},c=[{value:"Extra config",id:"extra-config",level:2},{value:"Example",id:"example",level:2},{value:"Defaults",id:"defaults",level:2}];function a(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"ssh-config",children:"SSH Config"})}),"\n",(0,i.jsxs)(t.p,{children:["With the ",(0,i.jsx)(t.code,{children:"osism.commons.sshconfig"})," role, it is possible to manage a SSH config\nfile in the home directory of the operator user."]}),"\n",(0,i.jsx)(t.h2,{id:"extra-config",children:"Extra config"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"sshconfig_extra"})," parameter can be used to add any other SSH configuration to the ",(0,i.jsx)(t.code,{children:".ssh/config"})," file."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-yaml",children:"sshconfig_extra: |\n Host github.com\n\t ProxyCommand nc -X connect -x :> ssh.github.com 443\n"})}),"\n",(0,i.jsx)(t.h2,{id:"example",children:"Example"}),"\n",(0,i.jsxs)(t.p,{children:["In the ",(0,i.jsx)(t.a,{href:"https://github.com/osism/testbed",children:"testbed"}),"\nthe ",(0,i.jsx)(t.code,{children:"/home/dragon/.ssh/config"})," file is created on the manager node ",(0,i.jsx)(t.code,{children:"testbed-manager"}),"."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-none",metastring:'title="Example for an assembled /home/dragon/.ssh/config file"',children:"Host testbed-manager\n HostName testbed-manager.testbed.osism.xyz\n User dragon\n Port 22\n IdentityFile /opt/ansible/secrets/id_rsa.operator\n\n####################\nHost testbed-node-0\n HostName testbed-node-0.testbed.osism.xyz\n User dragon\n Port 22\n IdentityFile /opt/ansible/secrets/id_rsa.operator\n\n####################\nHost testbed-node-1\n HostName testbed-node-1.testbed.osism.xyz\n User dragon\n Port 22\n IdentityFile /opt/ansible/secrets/id_rsa.operator\n\n####################\nHost testbed-node-2\n HostName testbed-node-2.testbed.osism.xyz\n User dragon\n Port 22\n IdentityFile /opt/ansible/secrets/id_rsa.operator\n"})}),"\n",(0,i.jsx)(t.h2,{id:"defaults",children:"Defaults"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{style:{textAlign:"left"},children:"Parameter"}),(0,i.jsx)(t.th,{style:{textAlign:"left"},children:"Default"}),(0,i.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"sshconfig_groupname"})}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"all"})}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"All nodes in this group are included."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"sshconfig_order"})}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"20"})}),(0,i.jsxs)(t.td,{style:{textAlign:"left"},children:["The ",(0,i.jsx)(t.code,{children:".ssh/config.d"})," directory is used to prepare the ",(0,i.jsx)(t.code,{children:".ssh/config"})," file. You can add your own files in this directory. Everything with a filename prefix smaller than ",(0,i.jsx)(t.code,{children:"sshconfig_order"})," is placed at the beginning of the assembled ",(0,i.jsx)(t.code,{children:".ssh/config"})," file. Anything with a filename prefix greater than ",(0,i.jsx)(t.code,{children:"sshconfig_order"})," goes at the end."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"sshconfig_port"})}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"22"})}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"The SSH port."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"sshconfig_private_key_file"})}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"/opt/ansible/secrets/id_rsa.operator"})}),(0,i.jsxs)(t.td,{style:{textAlign:"left"},children:["The identity file to use. The file itself must already exist there. The file is created by the ",(0,i.jsx)(t.code,{children:"osism.services.manager"})," role."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"sshconfig_user"})}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:'"{{ operator_user }}"'})}),(0,i.jsxs)(t.td,{style:{textAlign:"left"},children:["The user in which home directory the ",(0,i.jsx)(t.code,{children:".ssh/config"})," file will be generated."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"sshconfig_extra"})}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:'""'})}),(0,i.jsxs)(t.td,{style:{textAlign:"left"},children:["Add additional SSH configuration to the end of the ",(0,i.jsx)(t.code,{children:".ssh/config"})," file."]})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>d});var n=s(96540);const i={},o=n.createContext(i);function r(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/061d8128.ded2488d.js b/assets/js/061d8128.ded2488d.js new file mode 100644 index 0000000000..42fdbcc82c --- /dev/null +++ b/assets/js/061d8128.ded2488d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[21009],{14643:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>d,metadata:()=>i,toc:()=>a});const i=JSON.parse('{"id":"scs-0100-v3-flavor-naming","title":"SCS Flavor Naming Standard","description":"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack\\nenvironments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM,\\nand Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for\\nusability and portability across all SCS flavors.\\n","source":"@site/standards/scs-0100-v3-flavor-naming.md","sourceDirName":".","slug":"/scs-0100-v3-flavor-naming","permalink":"/standards/scs-0100-v3-flavor-naming","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Flavor Naming Standard","type":"Standard","status":"Stable","stabilized_at":"2023-06-14T00:00:00.000Z","track":"IaaS","replaces":"scs-0100-v2-flavor-naming.md","description":"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack\\nenvironments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM,\\nand Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for\\nusability and portability across all SCS flavors.\\n"},"sidebar":"standards","previous":{"title":"V2","permalink":"/standards/scs-0100-v2-flavor-naming"},"next":{"title":"W1","permalink":"/standards/scs-0100-w1-flavor-naming-implementation-testing"}}');var r=s(74848),t=s(28453);const d={title:"SCS Flavor Naming Standard",type:"Standard",status:"Stable",stabilized_at:new Date("2023-06-14T00:00:00.000Z"),track:"IaaS",replaces:"scs-0100-v2-flavor-naming.md",description:"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack\nenvironments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM,\nand Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for\nusability and portability across all SCS flavors.\n"},o=void 0,l={},a=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Type of information included",id:"type-of-information-included",level:3},{value:"Complete Proposal for systematic flavor naming",id:"complete-proposal-for-systematic-flavor-naming",level:2},{value:"Proposal Details",id:"proposal-details",level:2},{value:"[REQUIRED] CPU Suffixes",id:"required-cpu-suffixes",level:3},{value:"Baseline",id:"baseline",level:4},{value:"Higher oversubscription",id:"higher-oversubscription",level:4},{value:"Insufficient microcode",id:"insufficient-microcode",level:4},{value:"Examples",id:"examples",level:4},{value:"[REQUIRED] Memory",id:"required-memory",level:3},{value:"Baseline",id:"baseline-1",level:4},{value:"No ECC",id:"no-ecc",level:4},{value:"Enabled Oversubscription",id:"enabled-oversubscription",level:4},{value:"Examples",id:"examples-1",level:4},{value:"[OPTIONAL] Disk sizes and types",id:"optional-disk-sizes-and-types",level:3},{value:"Baseline",id:"baseline-2",level:4},{value:"Multi-provisioned Disk",id:"multi-provisioned-disk",level:4},{value:"Examples",id:"examples-2",level:4},{value:"Naming policy compliance",id:"naming-policy-compliance",level:2},{value:"Extensions",id:"extensions",level:2},{value:"[OPTIONAL] Hypervisor",id:"optional-hypervisor",level:3},{value:"Examples",id:"examples-3",level:4},{value:"[OPTIONAL] Hardware virtualization / Nested virtualization",id:"optional-hardware-virtualization--nested-virtualization",level:3},{value:"Examples",id:"examples-4",level:4},{value:"[OPTIONAL] CPU Architecture Details",id:"optional-cpu-architecture-details",level:3},{value:"Generation and Vendor",id:"generation-and-vendor",level:4},{value:"Frequency Suffixes",id:"frequency-suffixes",level:4},{value:"Examples",id:"examples-5",level:4},{value:"[OPTIONAL] GPU support",id:"optional-gpu-support",level:3},{value:"[OPTIONAL] Infiniband",id:"optional-infiniband",level:3},{value:"Naming options advice",id:"naming-options-advice",level:3},{value:"Proposal Examples",id:"proposal-examples",level:2},{value:"Previous standard versions",id:"previous-standard-versions",level:2},{value:"Beyond SCS",id:"beyond-scs",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",del:"del",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsx)(n.p,{children:"This is the standard v3.2 for SCS Release 8.\nNote that we intend to only extend it (so it's always backwards compatible),\nbut try to avoid changing in incompatible ways.\n(See at the end for the v1 to v2 transition where we have not met that\ngoal, but at least managed to have a 1:1 relationship between v1 and v2 names.)"}),"\n",(0,r.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,r.jsx)(n.p,{children:"In OpenStack environments there is a need to define different flavors for instances.\nThe flavors are pre-defined by the operator, the customer can not change these.\nOpenStack providers thus typically offer a large selection of flavors."}),"\n",(0,r.jsxs)(n.p,{children:["While flavors can be discovered (",(0,r.jsx)(n.code,{children:"openstack flavor list"}),"), it is helpful for users (DevOps teams),\nto have a naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere."]}),"\n",(0,r.jsx)(n.p,{children:"While not all details will be encoded in the name, the key features should be obvious:\nNumber of vCPUs, RAM, Root Disk.\nExtra features are important as well: There will be flavors with GPU support, fast disks for databases,\nmemory-heavy applications, and other useful aspects of an instance."}),"\n",(0,r.jsx)(n.p,{children:"It may also be important to make the CPU generation clearly recognizable, as this is always a topic in\ndiscussions with customers."}),"\n",(0,r.jsx)(n.p,{children:"Note that not all relevant properties of flavors can be discovered; creating a specification\nto address this is a separate but related effort to the name standardization.\nCommonly used infrastructure-as-code tools do not provide a way to use discoverability\nfeatures to express something like \"I want a flavor with 2 vCPUs, 8GiB of RAM, a local\n20GB SSD disk and Infiniband support, but I don't care whether it's AMD or intel\" in a\nreasonable manner. Using flavor names to express this will thus continue to be useful,\nand we don't expect the need for standardization of flavor names to go away until\nthe commonly used IaC tools work on a higher abstraction layer than they currently do."}),"\n",(0,r.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,r.jsx)(n.h3,{id:"type-of-information-included",children:"Type of information included"}),"\n",(0,r.jsx)(n.p,{children:"From discussions of our operators with their customers we learned that\nthe following characteristics are important in a flavor description:"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{style:{textAlign:"left"},children:"Type"}),(0,r.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Generation"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"CPU Generation"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Number of CPU"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Number of vCPUs - suffixed by L,V,T,C (see below)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Amount of RAM"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Amount of memory available for the VM"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Performance Class"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Ability to label high-performance CPUs, disks, network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"CPU Type"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"X86-intel, X86-amd, ARM, RISC-V, Generic"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:'"bms"'}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Bare Metal System (no virtualization/hypervisor)"})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"This list is likely not comprehensive and will grow over time."}),"\n",(0,r.jsxs)(n.p,{children:["Rather than using random names ",(0,r.jsx)(n.code,{children:"s5a.medium"})," and assigning a discrete set of properties\nto them, we wanted to come up with a scheme that allows to systematically derive\nnames from properties and vice versa. The scheme allows for short names (by not\nencoding all details) as well as very detailed longer names."]}),"\n",(0,r.jsx)(n.h2,{id:"complete-proposal-for-systematic-flavor-naming",children:"Complete Proposal for systematic flavor naming"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Prefix"}),(0,r.jsx)(n.th,{children:"CPUs & Suffix"}),(0,r.jsx)(n.th,{children:"RAM[GiB]"}),(0,r.jsx)(n.th,{children:"optional: Disk[GB]&type"}),(0,r.jsx)(n.th,{children:"opt: extensions"})]})}),(0,r.jsx)(n.tbody,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SCS-"})}),(0,r.jsxs)(n.td,{children:["N",(0,r.jsx)(n.code,{children:"L/V/T/C"}),"[",(0,r.jsx)(n.code,{children:"i"}),"]"]}),(0,r.jsxs)(n.td,{children:[(0,r.jsx)(n.code,{children:"-"}),"N[",(0,r.jsx)(n.code,{children:"u"}),"][",(0,r.jsx)(n.code,{children:"o"}),"]"]}),(0,r.jsxs)(n.td,{children:["[",(0,r.jsx)(n.code,{children:"-"}),"[M",(0,r.jsx)(n.code,{children:"x"}),"]N[",(0,r.jsx)(n.code,{children:"n/h/s/p"}),"]]"]}),(0,r.jsxs)(n.td,{children:["[",(0,r.jsx)(n.code,{children:"_"}),"EXT]"]})]})})]}),"\n",(0,r.jsxs)(n.p,{children:["Note that N and M are placeholders for numbers here.\nThe optional fields are denoted in brackets (and have ",(0,r.jsx)(n.code,{children:"opt:"})," in the header).\nSee below for extensions."]}),"\n",(0,r.jsx)(n.p,{children:"Note that all letters are case-sensitive."}),"\n",(0,r.jsxs)(n.p,{children:["Typical flavor names look like ",(0,r.jsx)(n.code,{children:"SCS-4V-16-50"})," for a flavor with 4vCPUs (with limited\noversubscription), 16GiB RAM and a 50GB disk (of unspecified type)."]}),"\n",(0,r.jsx)(n.h2,{id:"proposal-details",children:"Proposal Details"}),"\n",(0,r.jsx)(n.h3,{id:"required-cpu-suffixes",children:"[REQUIRED] CPU Suffixes"}),"\n",(0,r.jsx)(n.p,{children:"Next to the number of vCPUs, these vCPUs need to be characterized to describe their nature."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Suffix"}),(0,r.jsx)(n.th,{children:"Meaning"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"C"}),(0,r.jsx)(n.td,{children:"dedicated Core"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"T"}),(0,r.jsx)(n.td,{children:"dedicated Thread (SMT)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"V"}),(0,r.jsx)(n.td,{children:"vCPU (oversubscribed)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"L"}),(0,r.jsx)(n.td,{children:"vCPU (heavily oversubscribed)"})]})]})]}),"\n",(0,r.jsx)(n.h4,{id:"baseline",children:"Baseline"}),"\n",(0,r.jsxs)(n.p,{children:["Note that vCPU oversubscription for a ",(0,r.jsx)(n.code,{children:"V"})," vCPU should be implemented such, that we\ncan guarantee ",(0,r.jsx)(n.em,{children:"at least 20% of a core in >99% of the time"}),"; this can be achieved by\nlimiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled)\nor by more advanced workload management logic. Otherwise ",(0,r.jsx)(n.code,{children:"L"})," (low performance) instead\nof ",(0,r.jsx)(n.code,{children:"V"})," must be used. The >99% is measured over a month (1% is 7.2h/month)."]}),"\n",(0,r.jsx)(n.p,{children:"Note that CPUs should use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.).\nIn particular,"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"microcode must be updated within less than a month of a new release; for CVSS scores above 8,\nproviders should do it in less than a week."}),"\n",(0,r.jsx)(n.li,{children:"all mitigations that are enabled by default in the Linux kernel and the KVM hypervisor\nshould be enabled,"}),"\n",(0,r.jsx)(n.li,{children:"CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) should have hyperthreading\ndisabled OR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team."}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["That is to say, except when the suffix ",(0,r.jsx)(n.code,{children:"i"})," is used, the provider commits itself to implementing the appropriate mitigations\nif and when they become available, within the timeframes mentioned above."]}),"\n",(0,r.jsxs)(n.p,{children:["If a provider does not want to commit to deploying available microcode fixes and upstream kernel/hypervisor updates within a month or\nif the provider wants to enable hyperthreading on compute hosts despite having CPUs susceptible to L1TF there\n(and no SCS-accepted core-scheduling mechanism is used for mitigation),\nthe flavors must be declared insecure with the ",(0,r.jsx)(n.code,{children:"i"})," suffix (see below)."]}),"\n",(0,r.jsx)(n.h4,{id:"higher-oversubscription",children:"Higher oversubscription"}),"\n",(0,r.jsxs)(n.p,{children:["Must be indicated with a ",(0,r.jsx)(n.code,{children:"L"})," vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and\nthe lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month)."]}),"\n",(0,r.jsx)(n.h4,{id:"insufficient-microcode",children:"Insufficient microcode"}),"\n",(0,r.jsxs)(n.p,{children:["Not using these mitigations must be indicated by an additional ",(0,r.jsx)(n.code,{children:"i"})," suffix for insecure\n(weak protection against CPU vulnerabilities through insufficient microcode, lack of disabled hyperthreading\non L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor)."]}),"\n",(0,r.jsx)(n.h4,{id:"examples",children:"Examples"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["SCS-",(0,r.jsx)(n.strong,{children:"2C"}),"-4-10n"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-",(0,r.jsx)(n.strong,{children:"2T"}),"-4-10n"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-",(0,r.jsx)(n.strong,{children:"2V"}),"-4-10n"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-",(0,r.jsx)(n.strong,{children:"2L"}),"-4-10n"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-",(0,r.jsx)(n.strong,{children:"2Li"}),"-4-10n"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.del,{children:["SCS-",(0,r.jsx)(n.strong,{children:"2"}),"-**4-10n"]})," - CPU suffix missing"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.del,{children:["SCS-",(0,r.jsx)(n.strong,{children:"2iT"}),"-4-10n"]})," - This order is forbidden"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"required-memory",children:"[REQUIRED] Memory"}),"\n",(0,r.jsx)(n.h4,{id:"baseline-1",children:"Baseline"}),"\n",(0,r.jsx)(n.p,{children:"Cloud providers should use ECC memory.\nMemory oversubscription should not be used.\nIt is allowed to specify half GiBs (e.g. 3.5), though this should not be done for larger memory sizes (>= 10GiB)."}),"\n",(0,r.jsx)(n.h4,{id:"no-ecc",children:"No ECC"}),"\n",(0,r.jsxs)(n.p,{children:["If no ECC is used, the ",(0,r.jsx)(n.code,{children:"u"})," suffix must indicate this."]}),"\n",(0,r.jsx)(n.h4,{id:"enabled-oversubscription",children:"Enabled Oversubscription"}),"\n",(0,r.jsxs)(n.p,{children:["If memory is oversubscribed, you must expose this with the ",(0,r.jsx)(n.code,{children:"o"})," suffix."]}),"\n",(0,r.jsx)(n.h4,{id:"examples-1",children:"Examples"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["SCS-2C-",(0,r.jsx)(n.strong,{children:"4"}),"-10n"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-",(0,r.jsx)(n.strong,{children:"3.5"}),"-10n"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-",(0,r.jsx)(n.strong,{children:"4u"}),"-10n"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-",(0,r.jsx)(n.strong,{children:"4o"}),"-10n"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-",(0,r.jsx)(n.strong,{children:"4uo"}),"-10n"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.del,{children:["SCS-2C-",(0,r.jsx)(n.strong,{children:"4ou"}),"-10n"]})," - This order is forbidden"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"optional-disk-sizes-and-types",children:"[OPTIONAL] Disk sizes and types"}),"\n",(0,r.jsx)(n.p,{children:"Disk sizes (in GB) should use sizes 5, 10, 20, 50, 100, 200, 500, 1000."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Disk type"}),(0,r.jsx)(n.th,{children:"Meaning"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"n"}),(0,r.jsx)(n.td,{children:"Network shared storage (ceph/cinder)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"h"}),(0,r.jsx)(n.td,{children:"Local disk (HDD: SATA/SAS class)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"s"}),(0,r.jsx)(n.td,{children:"Local SSD disk"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"p"}),(0,r.jsx)(n.td,{children:"Local high-perf NVMe"})]})]})]}),"\n",(0,r.jsx)(n.h4,{id:"baseline-2",children:"Baseline"}),"\n",(0,r.jsx)(n.p,{children:"Note that disk type might be omitted \u2014 the user then can not take any assumptions\non what storage is provided for the root disk (that the image gets provisioned to)."}),"\n",(0,r.jsxs)(n.p,{children:["It does make sense for ",(0,r.jsx)(n.code,{children:"n"})," to be requested explicitly to allow for smooth live migration.\n",(0,r.jsx)(n.code,{children:"h"})," typically provides latency advantages vs ",(0,r.jsx)(n.code,{children:"n"})," (but not necessarily bandwidth and\nalso is more likely to fail), ",(0,r.jsx)(n.code,{children:"s"})," and ",(0,r.jsx)(n.code,{children:"p"})," are for applications that need low\nlatency (high IOPS) and bandwidth disk I/O. ",(0,r.jsx)(n.code,{children:"n"})," storage is expected to survive\nsingle-disk and single-node failure."]}),"\n",(0,r.jsxs)(n.p,{children:["For specific requirements on the SSD and NVMe disks regarding IOPS and\npower-loss protection, refer to Decision Record ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0110-v1-ssd-flavors.md",children:"scs-0110-ssd-flavors"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["If the disk size is left out, the cloud is expected to allocate a disk (network or local)\nthat is large enough to fit the root file system (",(0,r.jsx)(n.code,{children:"min_disk"})," in image). This automatic\nallocation is indicated with ",(0,r.jsx)(n.code,{children:"-"})," without a disk size.\nIf the ",(0,r.jsx)(n.code,{children:"-"})," is left out completely, the user must create a boot volume manually and\ntell the instance to boot from it or use the\n",(0,r.jsx)(n.a,{href:"https://docs.openstack.org/api-ref/compute/?expanded=create-server-detail#create-server",children:(0,r.jsx)(n.code,{children:"block_device_mapping_v2"})}),"\nmechanism explicitly to create the boot volume from an image."]}),"\n",(0,r.jsx)(n.h4,{id:"multi-provisioned-disk",children:"Multi-provisioned Disk"}),"\n",(0,r.jsxs)(n.p,{children:["The disk size can be prefixed with ",(0,r.jsx)(n.code,{children:"Mx prefix"}),", where M is an integer specifying that the disk\nis provisioned M times. Multiple disks provided this way should be independent storage media,\nso users can expect some level of parallelism and independence."]}),"\n",(0,r.jsx)(n.h4,{id:"examples-2",children:"Examples"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-",(0,r.jsx)(n.strong,{children:"10n"})]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-",(0,r.jsx)(n.strong,{children:"10s"})]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-",(0,r.jsx)(n.strong,{children:"10s"}),"_bms_z3"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-",(0,r.jsx)(n.strong,{children:"3x10s"})," - Cloud creates three 10GB SSDs"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-",(0,r.jsx)(n.strong,{children:"3x10s"}),"_bms_z3"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-",(0,r.jsx)(n.strong,{children:"10"})," - Cloud decides disk type"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-",(0,r.jsx)(n.strong,{children:"10"}),"_bms_z3"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-",(0,r.jsx)(n.strong,{children:"n"})," - Cloud decides disk size (min_disk from image or larger)"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-",(0,r.jsx)(n.strong,{children:"n"}),"_bms_3"]}),"\n",(0,r.jsx)(n.li,{children:"SCS-2C-4- - Cloud decides disk type and size"}),"\n",(0,r.jsx)(n.li,{children:"SCS-2C-4-_bms_z3"}),"\n",(0,r.jsx)(n.li,{children:"SCS-2C-4-_bms_z3h_GNa-64_ib"}),"\n",(0,r.jsx)(n.li,{children:"SCS-2C-4-_ib"}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4 - You need to specify a boot volume yourself (boot from volume, or use ",(0,r.jsx)(n.code,{children:"block_device_mapping_v2"}),")"]}),"\n",(0,r.jsx)(n.li,{children:"SCS-2C-4_bms_z3"}),"\n",(0,r.jsx)(n.li,{children:"SCS-2C-4-3x10 - Cloud decides type and creates three 10GB volumes"}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.del,{children:["SCS-2C-4-",(0,r.jsx)(n.strong,{children:"1.5n"})]})," - You must not specify disk sizes which are not in full GiBs"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"naming-policy-compliance",children:"Naming policy compliance"}),"\n",(0,r.jsx)(n.p,{children:"Every flavor you offer MUST satisfy the following assertion:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["If its name starts with ",(0,r.jsx)(n.code,{children:"SCS-"}),", the name has to conform to the syntax outlined above, and\nthe flavor must ",(0,r.jsx)(n.em,{children:"at least"})," provide the capabilities indicated by the name."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"That is to say:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["You may offer flavors not following the above scheme, as long as the name does not\nstart with ",(0,r.jsx)(n.code,{children:"SCS-"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["You are allowed to understate your performance; for instance, a flavor that satisfies\n",(0,r.jsx)(n.code,{children:"SCS-1C-1.5-8s"})," (1 dedicated core, 1.5 GiB RAM, 8 GiB SSD) may also be named\n",(0,r.jsx)(n.code,{children:"SCS-1T-1-5n"})," (1 dedicated hyperthread, 1 GiB RAM, 5 GiB network volume) or even\n",(0,r.jsx)(n.code,{children:"SCS-1V-1-5"}),". Similarly, you may offer the (v3 mandatory) ",(0,r.jsx)(n.code,{children:"SCS-2V-4-20s"})," with a ",(0,r.jsx)(n.code,{children:"SCS-2V-4-20p"}),"\nimplementation (using a local NVMe instead of an SSD)."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["You must be very careful to expose low vCPU guarantees (",(0,r.jsx)(n.code,{children:"L"})," instead of ",(0,r.jsx)(n.code,{children:"V"}),"), insecure\nhyperthreading/microcode ",(0,r.jsx)(n.code,{children:"i"}),", non-ECC-RAM ",(0,r.jsx)(n.code,{children:"u"}),", memory oversubscription ",(0,r.jsx)(n.code,{children:"o"}),". Note that omitting these qualifiers\nis ",(0,r.jsx)(n.em,{children:"overstating"})," your security, reliability or performance properties and may be reason for\nclients to feel betrayed or claim damages. This would prevent SCS compliance and certification;\nin extreme cases, the SCS project might be forced to work with public statements."]}),"\n",(0,r.jsxs)(n.p,{children:["We expect all cloud providers to offer the short, less specific flavor names (such as ",(0,r.jsx)(n.code,{children:"SCS-8V-32-100"}),").\nLarger providers that offer more details (using the extension below) are expected to still also\noffer the short variants for usability and easier portability, even beyond the mandated flavors."]}),"\n",(0,r.jsx)(n.p,{children:"You must not extend the SCS naming scheme with your own extensions; you are encouraged however\nto suggest extensions that we can discuss and add to the official scheme."}),"\n",(0,r.jsx)(n.h2,{id:"extensions",children:"Extensions"}),"\n",(0,r.jsx)(n.p,{children:"Extensions provide a possibility for providers that offer a very differentiated set\nof flavors to indicate hypervisors, support for hardware/nested virtualization,\nCPU types and generations, high-frequency models, GPU support and GPU types as\nwell as Infiniband support. (More extensions may be appended in the future.)"}),"\n",(0,r.jsx)(n.p,{children:"Using the systematic naming approach ensures that two providers that offer flavors\nwith the same specific features will use the same name for them, thus simplifying\nlife for their customers when consuming these flavors."}),"\n",(0,r.jsxs)(n.p,{children:["Note that there is no need to indicate all details and extra features this way.\nFlavors may always perform better or have more features than indicated in a name.\nUnderperformance (CPU suffixes ",(0,r.jsx)(n.code,{children:"L"})," or ",(0,r.jsx)(n.code,{children:"i"})," or memory suffixes ",(0,r.jsx)(n.code,{children:"o"})," and ",(0,r.jsx)(n.code,{children:"u"}),") on the other\nhand MUST be indicated in the name; this happens rarely in practice."]}),"\n",(0,r.jsx)(n.p,{children:"For smaller providers, the ability to e.g. differentiate between an AMD Milan and an intel\nIceLake and exposed the slightly different feature set to customers and have slightly\ndifferent price points is often not worth the extra effort. This is because having\nthis extra differentiation causes fragmentation of the machines (host aggregates)\nthat can offer these flavors, thus resulting in a lower utilization (as the capacity\nmanagement will need to have a certain amount of headroom per machine pool to avoid\nrunning out of capacity)."}),"\n",(0,r.jsx)(n.p,{children:"Note that it is possible for providers to register both the generic short names and the\nlonger, more detailed names and allow them to use the same set of machines (host aggregates).\nNote that machines (hypervisors) can be part of more than one host aggregate."}),"\n",(0,r.jsx)(n.p,{children:"The extensions have the format:"}),"\n",(0,r.jsxs)(n.p,{children:["[",(0,r.jsx)(n.code,{children:"_"}),"hyp][",(0,r.jsx)(n.code,{children:"_hwv"}),"][",(0,r.jsx)(n.code,{children:"_"}),"arch[N][",(0,r.jsx)(n.code,{children:"h"}),"]][",(0,r.jsx)(n.code,{children:"_"}),"[",(0,r.jsx)(n.code,{children:"G/g"}),"]X[N][",(0,r.jsx)(n.code,{children:"-"}),"M][",(0,r.jsx)(n.code,{children:"h"}),"]][",(0,r.jsx)(n.code,{children:"_ib"}),"]"]}),"\n",(0,r.jsx)(n.p,{children:"Extensions are individually optional, but the ones that are used must appear in the order\ngiven in the above line."}),"\n",(0,r.jsxs)(n.p,{children:["Remember that letters are case-sensitive.\nIn case you wonder: Feature indicators are capitalized, modifiers are lower case.\n(An exception is the uppercase ",(0,r.jsx)(n.code,{children:"_G"})," for a pass-through GPU vs. lowercase ",(0,r.jsx)(n.code,{children:"_g"})," for vGPU.)"]}),"\n",(0,r.jsx)(n.h3,{id:"optional-hypervisor",children:"[OPTIONAL] Hypervisor"}),"\n",(0,r.jsxs)(n.p,{children:["Format: ",(0,r.jsx)(n.code,{children:"_"}),"hyp"]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.em,{children:"default Hypervisor"})," is assumed to be ",(0,r.jsx)(n.code,{children:"KVM"}),". Clouds that offer different hypervisors\nor Bare Metal Systems should indicate the Hypervisor according to the following table:"]}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"hyp"}),(0,r.jsx)(n.th,{children:"Meaning"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"kvm"}),(0,r.jsx)(n.td,{children:"KVM"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"xen"}),(0,r.jsx)(n.td,{children:"Xen"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"vmw"}),(0,r.jsx)(n.td,{children:"VMware"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"hyv"}),(0,r.jsx)(n.td,{children:"Hyper-V"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"bms"}),(0,r.jsx)(n.td,{children:"Bare Metal System"})]})]})]}),"\n",(0,r.jsx)(n.h4,{id:"examples-3",children:"Examples"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"SCS-2C-4-10n"}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,r.jsx)(n.strong,{children:"bms"})]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,r.jsx)(n.strong,{children:"bms"}),"_z3h"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"optional-hardware-virtualization--nested-virtualization",children:"[OPTIONAL] Hardware virtualization / Nested virtualization"}),"\n",(0,r.jsxs)(n.p,{children:["Format: ",(0,r.jsx)(n.code,{children:"_hwv"})]}),"\n",(0,r.jsxs)(n.p,{children:["If the instances that are created with this flavor support hardware-accelerated\nvirtualization, this can be reflected with the ",(0,r.jsx)(n.code,{children:"_hwv"})," flag (after the optional\nHypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel)\nor svm (AMD) is available. This will be the case on Bare Metal flavors on almost\nall non-ancient x86 CPUs or if your virtualization hypervisor is configured to\nsupport nested virtualization.\nFlavors without the ",(0,r.jsx)(n.code,{children:"_hwv"})," flag may or may not support hardware virtualization (as we\nrecommend enabling nesting, but don't require flavor names to reflect all\ncapabilities. Flavors may over-deliver ...)"]}),"\n",(0,r.jsx)(n.h4,{id:"examples-4",children:"Examples"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"SCS-2C-4-10 - may or may not support HW virtualization in VMs"}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10_kvm_",(0,r.jsx)(n.strong,{children:"hwv"})," - kvm with enabled nested virtualization"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10_",(0,r.jsx)(n.strong,{children:"hwv"})," - not recommended, but allowed"]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10_bms_",(0,r.jsx)(n.strong,{children:"hwv"})," - better: bare metal with HW virt support (VMX on intel, SVM on AMD, ...)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.del,{children:["SCS-2C-4-10_",(0,r.jsx)(n.strong,{children:"hwv"}),"_xen"]})," - illegal, wrong ordering"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"optional-cpu-architecture-details",children:"[OPTIONAL] CPU Architecture Details"}),"\n",(0,r.jsxs)(n.p,{children:["Format: ",(0,r.jsx)(n.code,{children:"_"}),"arch[N][",(0,r.jsx)(n.code,{children:"h"}),"]"]}),"\n",(0,r.jsx)(n.p,{children:"This extension provides more details on the specific CPU:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"vendor/architecture (arch)"}),"\n",(0,r.jsx)(n.li,{children:"generation (N)"}),"\n",(0,r.jsx)(n.li,{children:"frequency (h)"}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"generation-and-vendor",children:"Generation and Vendor"}),"\n",(0,r.jsx)(n.p,{children:"The options for arch are as follows:"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Letter"}),(0,r.jsx)(n.th,{children:"vendor/architecture"}),(0,r.jsx)(n.th,{children:"Corresponding image architecture"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"(none)"}),(0,r.jsx)(n.td,{children:"Generic x86-64"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"x86_64"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"i"})}),(0,r.jsx)(n.td,{children:"Intel x86-64"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"x86_64"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"z"})}),(0,r.jsx)(n.td,{children:"AMD (Zen) x86-64"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"x86_64"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"a"})}),(0,r.jsx)(n.td,{children:"ARM v8+"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"aarch64"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"r"})}),(0,r.jsx)(n.td,{children:"RISC-V"}),(0,r.jsx)(n.td,{children:"(not yet listed in Glance)"})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"The generation is vendor specific and can be left out, but it can only be specified in\nconjunction with a vendor. At present, these values are possible:"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Generation"}),(0,r.jsx)(n.th,{children:"i (Intel x86-64)"}),(0,r.jsx)(n.th,{children:"z (AMD x86-64)"}),(0,r.jsx)(n.th,{children:"\xa0a (AArch64)"}),(0,r.jsx)(n.th,{children:"r (RISC-V)"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"0"}),(0,r.jsx)(n.td,{children:"pre Skylake"}),(0,r.jsx)(n.td,{children:"pre Zen"}),(0,r.jsx)(n.td,{children:"pre Cortex A76"}),(0,r.jsx)(n.td,{children:"TBD"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"1"}),(0,r.jsx)(n.td,{children:"Skylake"}),(0,r.jsx)(n.td,{children:"Zen-1 (Naples)"}),(0,r.jsx)(n.td,{children:"A76/NeoN1 class"}),(0,r.jsx)(n.td,{children:"TBD"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"2"}),(0,r.jsx)(n.td,{children:"Cascade Lake"}),(0,r.jsx)(n.td,{children:"Zen-2 (Rome)"}),(0,r.jsx)(n.td,{children:"A78/x1/NeoV1 class"}),(0,r.jsx)(n.td,{children:"TBD"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"3"}),(0,r.jsx)(n.td,{children:"Ice Lake"}),(0,r.jsx)(n.td,{children:"Zen-3 (Milan)"}),(0,r.jsx)(n.td,{children:"A71x/NeoN2/V2(ARMv9)"}),(0,r.jsx)(n.td,{children:"TBD"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"4"}),(0,r.jsx)(n.td,{children:"Sapphire Rapids"}),(0,r.jsx)(n.td,{children:"Zen-4 (Genoa)"}),(0,r.jsx)(n.td,{children:"AmpereOne (ARMv8.6)"}),(0,r.jsx)(n.td,{children:"TBD"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"5"}),(0,r.jsx)(n.td,{children:"Sierra Forest(E)"}),(0,r.jsx)(n.td,{children:"Zen-5 (Turin)"}),(0,r.jsx)(n.td,{children:"A72x/NeoN3/V3(Av9.2)"}),(0,r.jsx)(n.td,{children:"TBD"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"6"}),(0,r.jsx)(n.td,{children:"Granite Rapids(P)"}),(0,r.jsx)(n.td,{}),(0,r.jsx)(n.td,{}),(0,r.jsx)(n.td,{children:"TBD"})]})]})]}),"\n",(0,r.jsxs)(n.p,{children:["It is recommended to leave out the ",(0,r.jsx)(n.code,{children:"0"}),' when specifying the old generation; this will\nhelp the parser tool, which assumes 0 for an unspecified value and does leave it\nout when generating the name for comparison. In other words: 0 has a meaning of\n"rather old or unspecified".']}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["We don't differentiate between Zen-4 (Genoa) and Zen-4c (Bergamo); L3 cache per\nSiena core is smaller on Bergamo and the frequency lower but the cores are otherwise\nidentical. As we already have a qualifier ",(0,r.jsx)(n.code,{children:"h"})," that allows to specify higher frequencies\n(which Genoa thus may use more and Bergamo not), we have enough distinction\ncapabilities. The same applies to Zen-5 (Turin) and Zen-5c (Turin Dense).\nFor intel with the server E-cores (Crestmont), these received their own\ngeneration assignment, as the difference to the server P-cores (Redwood Cove)\nis more significant."]})}),"\n",(0,r.jsx)(n.h4,{id:"frequency-suffixes",children:"Frequency Suffixes"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Suffix"}),(0,r.jsx)(n.th,{children:"Meaning"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"h"}),(0,r.jsx)(n.td,{children:">2.75GHz all-core"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"hh"}),(0,r.jsx)(n.td,{children:">3.25GHz all-core"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"hhh"}),(0,r.jsx)(n.td,{children:">3.75GHz all-core"})]})]})]}),"\n",(0,r.jsx)(n.h4,{id:"examples-5",children:"Examples"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"SCS-2C-4-10n"}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,r.jsx)(n.strong,{children:"z"})]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,r.jsx)(n.strong,{children:"z3"})]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,r.jsx)(n.strong,{children:"z3h"})]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,r.jsx)(n.strong,{children:"z3hh"})]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,r.jsx)(n.strong,{children:"z"})]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,r.jsx)(n.strong,{children:"z3"})]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,r.jsx)(n.strong,{children:"z3"})]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,r.jsx)(n.strong,{children:"z3h"})]}),"\n",(0,r.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,r.jsx)(n.strong,{children:"z3hh"})," - Bare Metal, AMD Milan with > 3.25GHz all core freq"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"optional-gpu-support",children:"[OPTIONAL] GPU support"}),"\n",(0,r.jsxs)(n.p,{children:["Format: ",(0,r.jsx)(n.code,{children:"_"}),"[",(0,r.jsx)(n.code,{children:"G/g"}),"]X[N[",(0,r.jsx)(n.code,{children:"-"}),"M[",(0,r.jsx)(n.code,{children:"h"}),"][",(0,r.jsx)(n.code,{children:"-"}),"V[",(0,r.jsx)(n.code,{children:"h"}),"]]]]"]}),"\n",(0,r.jsx)(n.p,{children:"This extension provides more details on the specific GPU:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["pass-through (",(0,r.jsx)(n.code,{children:"G"}),") vs. virtual GPU (",(0,r.jsx)(n.code,{children:"g"}),")"]}),"\n",(0,r.jsx)(n.li,{children:"vendor (X)"}),"\n",(0,r.jsx)(n.li,{children:"generation (N)"}),"\n",(0,r.jsx)(n.li,{children:"number (M) of processing units that are exposed (for pass-through) or assigned; see table below for vendor-specific terminology"}),"\n",(0,r.jsxs)(n.li,{children:["high-frequency indicator (",(0,r.jsx)(n.code,{children:"h"}),") for compute units"]}),"\n",(0,r.jsx)(n.li,{children:"amount of video memory (V) in GiB"}),"\n",(0,r.jsx)(n.li,{children:"an indicator for high-bandwidth memory"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Note that the vendor letter X is mandatory, generation and processing units are optional."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"letter X"}),(0,r.jsx)(n.th,{children:"vendor"}),(0,r.jsx)(n.th,{children:"processing units"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"N"})}),(0,r.jsx)(n.td,{children:"nVidia"}),(0,r.jsx)(n.td,{children:"streaming multiprocessors (SMs)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"A"})}),(0,r.jsx)(n.td,{children:"AMD"}),(0,r.jsx)(n.td,{children:"compute units (CUs)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"I"})}),(0,r.jsx)(n.td,{children:"Intel"}),(0,r.jsx)(n.td,{children:"execution units (EUs)"})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"For nVidia, the generation N can be f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, l=Ada Lovelace, g=Grace Hopper, ...,\nfor AMD GCN-x=0.x, RDNA1=1, C/RDNA2=2, C/RDNA3=3, C/RDNA3.5=3.5, C/RDNA4=4, ...\nfor Intel Gen9=0.9, Xe(12.1/DG1)=1, Xe(12.2)=2, Arc(12.7/DG2)=3 ...\n(Note: This may need further work to properly reflect what's out there.)"}),"\n",(0,r.jsxs)(n.p,{children:["The optional ",(0,r.jsx)(n.code,{children:"h"})," suffix to the compute unit count indicates high-frequency GPU compute units.\nIt is not normally recommended to use it except if there are several variants of cards within\na generation of GPUs and with similar number of SMs/CUs/EUs.\nIn case there are even more than two variants, the letter ",(0,r.jsx)(n.code,{children:"h"})," can be duplicated for even\nhigher frquencies."]}),"\n",(0,r.jsx)(n.p,{children:"Please note that there are GPUs from one generation and vendor that have vastly different sizes\n(or different fractions are being passed to an instance with multi-instance-GPUs). The number\nM allows to differentiate between them and have an indicator of the compute capability and\nparallelism. M can not at all be compared between different generations let alone different\nvendors."}),"\n",(0,r.jsxs)(n.p,{children:["The amount of video memory dedicated to the instance can be indicated by V (in binary\nGigabytes). This number needs to be an integer - fractional memory sizes must be rounded\ndown. An optional ",(0,r.jsx)(n.code,{children:"h"})," can be used to indicate high bandwidth memory (such as HBM2+) with\nbandwidths well above 1GiB/s."]}),"\n",(0,r.jsxs)(n.p,{children:["Example: ",(0,r.jsx)(n.code,{children:"SCS-16V-64-500s_GNa-14-6h"}),"\nThis flavor has a pass-through GPU nVidia Ampere with 14 SMs and 6 GiB of high-bandwidth video\nmemory. Looking through GPU specs you could guess it's 1/4 of an A30."]}),"\n",(0,r.jsxs)(n.p,{children:["We have a table with common GPUs in the\n",(0,r.jsx)(n.a,{href:"/standards/scs-0100-w1-flavor-naming-implementation-testing",children:"implementation hints for this standard"})]}),"\n",(0,r.jsx)(n.h3,{id:"optional-infiniband",children:"[OPTIONAL] Infiniband"}),"\n",(0,r.jsxs)(n.p,{children:["Format: ",(0,r.jsx)(n.code,{children:"_ib"})]}),"\n",(0,r.jsx)(n.p,{children:"This extension indicates Infiniband networking."}),"\n",(0,r.jsx)(n.p,{children:"More extensions may be forthcoming and appended in a later revision of this spec."}),"\n",(0,r.jsx)(n.p,{children:"Extensions need to be specified in the above-mentioned order."}),"\n",(0,r.jsx)(n.h3,{id:"naming-options-advice",children:"Naming options advice"}),"\n",(0,r.jsx)(n.p,{children:"Note that we expect most clouds to prefer short flavor names,\nnot indicating CPU details or hypervisor types. See above list\nof standard flavors to get a feeling."}),"\n",(0,r.jsxs)(n.p,{children:["However, more successful providers will often need to differentiate their\nofferings in response to customer demand and allow customers to request\nflavors with specific detailed properties. The goal of this proposal is to avoid\nproviders to invent their own names and then refer customers to (currently\nincompletely standardized) ",(0,r.jsx)(n.code,{children:"extra_specs"}),"\nor worse a non-machine-readable service descriptions to find out the details."]}),"\n",(0,r.jsxs)(n.p,{children:["So a cloud provider might well evolve from offering ",(0,r.jsx)(n.code,{children:"SCS-8T-16-50"})," to offering\n",(0,r.jsx)(n.code,{children:"SCS-8T-16-50n"}),", ",(0,r.jsx)(n.code,{children:"SCS-8T-16-50n_i2"})," and ",(0,r.jsx)(n.code,{children:"SCS-8T-16-50n_z2"})," to specify that he\nis using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome.\nWe would expect the cloud provider to still offer the generic flavor\n",(0,r.jsx)(n.code,{children:"SCS-8T-16-50"})," and allow the scheduler (placement service) to pick both more\nspecific types (or just one if e.g. capacity management considerations suggest\nso). Providers in such cases should ensure that the price of a requested\nflavor does not depend on the scheduler decisions."]}),"\n",(0,r.jsxs)(n.p,{children:["We are looking into the ",(0,r.jsx)(n.a,{href:"https://docs.openstack.org/image-guide/introduction.html#metadata-definition-metadefs-service",children:"metadefs"}),"\nmechanism and ",(0,r.jsx)(n.a,{href:"https://docs.openstack.org/api-guide/compute/extra_specs_and_properties.html",children:"extra_specs"}),"\nto allow customers to ask for specific flavor properties without the need to\nencode all these flavor details into the flavor name, so the optional pieces\nmay not be needed much. However, there must be a way to request flavor\nproperties without encoding the need into an image \u2014 the indirection via\nan image is considered broken by the SCS team."]}),"\n",(0,r.jsx)(n.h2,{id:"proposal-examples",children:"Proposal Examples"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Example"}),(0,r.jsx)(n.th,{children:"Decoding"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SCS-2C-4-10n"})}),(0,r.jsx)(n.td,{children:"2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SCS-8Ti-32-50p_i1"})}),(0,r.jsx)(n.td,{children:"8 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SCS-1L-1u-5"})}),(0,r.jsx)(n.td,{children:"1 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SCS-16T-64-200s_GNa-72-24_ib"})}),(0,r.jsx)(n.td,{children:"16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 72 Passthrough nVidia Ampere SMs"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SCS-4C-16-2x200p_a1"})}),(0,r.jsx)(n.td,{children:"4 dedicated Arm64 cores (A76 class), 16GiB RAM, 2x200GB local NVMe drives"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SCS-1V-0.5"})}),(0,r.jsx)(n.td,{children:"1 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"previous-standard-versions",children:"Previous standard versions"}),"\n",(0,r.jsxs)(n.p,{children:["Previous versions up to version 3.0 contained the list of\nmandatory/recommended flavors, which has been moved to\n",(0,r.jsx)(n.a,{href:"/standards/scs-0103-v1-standard-flavors",children:"a standard of its own"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/standards/scs-0100-v1-flavor-naming",children:"Version 1 of the standard"}),"\nused a slightly different naming syntax while the logic was exactly the same.\nWhat is a ",(0,r.jsx)(n.code,{children:"-"})," in v2 used to be a ",(0,r.jsx)(n.code,{children:":"}),"; ",(0,r.jsx)(n.code,{children:"_"})," used to be ",(0,r.jsx)(n.code,{children:"-"}),". The reason for\nthe change was certain Kubernetes tools using the flavor names as labels.\nLabels however are subject to stricter naming rules and in particular don't\nallow for a ",(0,r.jsx)(n.code,{children:":"}),". See ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/issues/190",children:"PR #190"}),"\nfor a discussion."]}),"\n",(0,r.jsx)(n.p,{children:"Version 1 flavor names can be translated to v2 using the following transformation:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-shell",children:"NAMEV2=$(echo \"$NAMEV1\" | sed -e 's/\\-/_/g' -e 's/:/-/g' -e 's/^SCS_/SCS-/')\n"})}),"\n",(0,r.jsx)(n.p,{children:"and the way back can be done with"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-shell",children:"NAMEV1=$(echo \"$NAMEV2\" | sed -e 's/\\-/:/g' -e 's/_/-/g' -e 's/^SCS:/SCS-/')\n"})}),"\n",(0,r.jsxs)(n.p,{children:["For the time being, the validation tools still accept the old names with a warning\n(despite the unchanged ",(0,r.jsx)(n.code,{children:"SCS-"})," prefix) unless you pass option ",(0,r.jsx)(n.code,{children:"-2"})," to them. They will\nhowever not count v1 flavors towards fulfilling the needs against the corresponding\nv2 mandatory flavor list unless you pass the option ",(0,r.jsx)(n.code,{children:"-1"}),".\nIn other words: An IaaS infrastructure with the 26\nv1 mandatory flavors will produce 26 warnings (for using old flavors) and 26\nerrors (for missing the 26 mandatory v2 flavors) unless you pass ",(0,r.jsx)(n.code,{children:"-1"})," in which\ncase no errors and no warnings will be produced. Registering the 26 mandatory\nv2 flavor names in addition will result in passing the test with only 26\nwarnings \u2014 unless you specify ",(0,r.jsx)(n.code,{children:"-2"}),". If you do and want to pass you'll need\nto remove the old v1 names or rename them to no longer start with ",(0,r.jsx)(n.code,{children:"SCS-"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"beyond-scs",children:"Beyond SCS"}),"\n",(0,r.jsx)(n.p,{children:"The Gaia-X provider working group which could have created a superseding standard\ndoes no longer exist."}),"\n",(0,r.jsx)(n.p,{children:"However, we have been reaching out to the OpenStack Public Cloud SIG and the ALASCA\nmembers to seek further alignment."}),"\n",(0,r.jsxs)(n.p,{children:["Getting upstream OpenStack support for flavor aliases would provide more flexibility\nand ease migrations between providers, also providers that don't offer the ",(0,r.jsx)(n.code,{children:"SCS-"}),"\nflavors."]}),"\n",(0,r.jsxs)(n.p,{children:["We also would like to see upstream ",(0,r.jsx)(n.code,{children:"extra_specs"})," standardizing the discoverability of some\nproperties exposed via the SCS names and work on IaC tooling (terraform ...)\nto make use of these when selecting a flavor."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>o});var i=s(96540);const r={},t=i.createContext(r);function d(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/066abe51.483c88c4.js b/assets/js/066abe51.483c88c4.js new file mode 100644 index 0000000000..804f207d74 --- /dev/null +++ b/assets/js/066abe51.483c88c4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[71351],{45690:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>m,frontMatter:()=>s,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"iaas/guides/concept-guide/components/sonic","title":"SONiC & OVN","description":"Lifecycle Management of SONiC in OSISM","source":"@site/docs/02-iaas/guides/concept-guide/components/sonic.md","sourceDirName":"02-iaas/guides/concept-guide/components","slug":"/iaas/guides/concept-guide/components/sonic","permalink":"/docs/iaas/guides/concept-guide/components/sonic","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/sonic.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Prometheus & Grafana","permalink":"/docs/iaas/guides/concept-guide/components/prometheus"},"next":{"title":"Teleport","permalink":"/docs/iaas/guides/concept-guide/components/teleport"}}');var t=i(74848),c=i(28453);const s={},a="SONiC & OVN",r={},l=[{value:"## Lifecycle Management of SONiC in OSISM",id:"-lifecycle-management-of-sonic-in-osism",level:2},{value:"## Lifecycle Management of Open Virtual Network (OVN) in OSISM",id:"-lifecycle-management-of-open-virtual-network-ovn-in-osism",level:2},{value:"## Lifecycle Management of Open vSwitch (OVS) in OSISM",id:"-lifecycle-management-of-open-vswitch-ovs-in-osism",level:2}];function d(e){const n={h1:"h1",h2:"h2",header:"header",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"sonic--ovn",children:"SONiC & OVN"})}),"\n",(0,t.jsx)(n.h2,{id:"-lifecycle-management-of-sonic-in-osism",children:"## Lifecycle Management of SONiC in OSISM"}),"\n",(0,t.jsx)(n.h2,{id:"-lifecycle-management-of-open-virtual-network-ovn-in-osism",children:"## Lifecycle Management of Open Virtual Network (OVN) in OSISM"}),"\n",(0,t.jsx)(n.h2,{id:"-lifecycle-management-of-open-vswitch-ovs-in-osism",children:"## Lifecycle Management of Open vSwitch (OVS) in OSISM"})]})}function m(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>s,x:()=>a});var o=i(96540);const t={},c=o.createContext(t);function s(e){const n=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),o.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/070e71f0.11720dbf.js b/assets/js/070e71f0.11720dbf.js new file mode 100644 index 0000000000..cb8843a60e --- /dev/null +++ b/assets/js/070e71f0.11720dbf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[67255],{49851:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>d,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"iaas/guides/upgrade-guide/ceph","title":"Ceph","description":"See Rook Operations.","source":"@site/docs/02-iaas/guides/upgrade-guide/ceph.md","sourceDirName":"02-iaas/guides/upgrade-guide","slug":"/iaas/guides/upgrade-guide/ceph","permalink":"/docs/iaas/guides/upgrade-guide/ceph","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/ceph.md","tags":[],"version":"current","sidebarPosition":20,"frontMatter":{"sidebar_label":"Ceph","sidebar_position":20},"sidebar":"docs","previous":{"title":"Network","permalink":"/docs/iaas/guides/upgrade-guide/network"},"next":{"title":"Docker","permalink":"/docs/iaas/guides/upgrade-guide/docker"}}');var r=s(74848),t=s(28453);const o={sidebar_label:"Ceph",sidebar_position:20},a="Ceph",d={},c=[];function p(e){const i={a:"a",code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(i.header,{children:(0,r.jsx)(i.h1,{id:"ceph",children:"Ceph"})}),"\n",(0,r.jsx)(i.pre,{children:(0,r.jsx)(i.code,{children:"osism apply ceph-rolling_update -e ireallymeanit=yes\nosism apply cephclient\n"})}),"\n",(0,r.jsx)(i.h1,{id:"ceph-via-rook-technical-preview",children:"Ceph via Rook (technical preview)"}),"\n",(0,r.jsxs)(i.p,{children:["See ",(0,r.jsx)(i.a,{href:"/docs/iaas/guides/operations-guide/rook",children:"Rook Operations"}),"."]})]})}function u(e={}){const{wrapper:i}={...(0,t.R)(),...e.components};return i?(0,r.jsx)(i,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},28453:(e,i,s)=>{s.d(i,{R:()=>o,x:()=>a});var n=s(96540);const r={},t=n.createContext(r);function o(e){const i=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(t.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/07d3bac7.8fda13ab.js b/assets/js/07d3bac7.8fda13ab.js new file mode 100644 index 0000000000..ae903e1c40 --- /dev/null +++ b/assets/js/07d3bac7.8fda13ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[30458],{62845:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>d,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"scs-0211-v1-kaas-default-storage-class","title":"SCS KaaS default storage class","description":"The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).\\nThe standard ensures that the default StorageClass, identified by the \\"storageclass.kubernetes.io/is-default-class\\"\\nannotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or\\nhost hardware failures.\\n","source":"@site/standards/scs-0211-v1-kaas-default-storage-class.md","sourceDirName":".","slug":"/scs-0211-v1-kaas-default-storage-class","permalink":"/standards/scs-0211-v1-kaas-default-storage-class","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS KaaS default storage class","type":"Standard","status":"Stable","stabilized_at":"2023-02-13T00:00:00.000Z","track":"KaaS","description":"The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).\\nThe standard ensures that the default StorageClass, identified by the \\"storageclass.kubernetes.io/is-default-class\\"\\nannotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or\\nhost hardware failures.\\n"},"sidebar":"standards","previous":{"title":"scs-0211: SCS KaaS default storage class","permalink":"/standards/kaas/scs-0211"},"next":{"title":"V2","permalink":"/standards/scs-0211-v2-kaas-default-storage-class"}}');var n=t(74848),r=t(28453);const o={title:"SCS KaaS default storage class",type:"Standard",status:"Stable",stabilized_at:new Date("2023-02-13T00:00:00.000Z"),track:"KaaS",description:'The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).\nThe standard ensures that the default StorageClass, identified by the "storageclass.kubernetes.io/is-default-class"\nannotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or\nhost hardware failures.\n'},i=void 0,d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Decision",id:"decision",level:2},{value:"Required non-performance-related properties",id:"required-non-performance-related-properties",level:3},{value:"Required performance-related properties",id:"required-performance-related-properties",level:3},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const s={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsxs)(s.p,{children:["Cluster consumers can request persistent storage via ",(0,n.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims",children:(0,n.jsx)(s.code,{children:"PersistentVolumeClaims"})})," which is provisioned automatically by cloud-provided automation.\nStorage requirements may vary across use cases, so there is the concept of ",(0,n.jsx)(s.code,{children:"StorageClasses"}),". ",(0,n.jsx)(s.code,{children:"StorageClasses"})," define some set of storage properties. So, consumers can choose one of these depending on the use case."]}),"\n",(0,n.jsx)(s.p,{children:(0,n.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/",children:"Kubernetes documentation"})}),"\n",(0,n.jsx)(s.h2,{id:"motivation",children:"Motivation"}),"\n",(0,n.jsxs)(s.p,{children:["While often times, consumers will choose a ",(0,n.jsx)(s.code,{children:"StorageClass"})," explicitly, usually, there is also a default ",(0,n.jsx)(s.code,{children:"StorageClass"})," to fall back on in case it is ",(0,n.jsx)(s.em,{children:"not"})," chosen explicitly (that is, when ",(0,n.jsx)(s.code,{children:"storageClassName"})," is not set on the ",(0,n.jsx)(s.code,{children:"PersistentVolumeClaim"}),")."]}),"\n",(0,n.jsxs)(s.p,{children:["This document attempts to define the properties this default ",(0,n.jsx)(s.code,{children:"StorageClass"})," should have."]}),"\n",(0,n.jsx)(s.h2,{id:"decision",children:"Decision"}),"\n",(0,n.jsxs)(s.p,{children:["The default ",(0,n.jsx)(s.code,{children:"StorageClass"})," is made default using the ",(0,n.jsx)(s.code,{children:"storageclass.kubernetes.io/is-default-class"})," annotation, following ",(0,n.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/",children:"Kubernetes upstream"}),". Hence, standardizing its name is not required for the intents of this standard."]}),"\n",(0,n.jsx)(s.h3,{id:"required-non-performance-related-properties",children:"Required non-performance-related properties"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"ReadWriteOnce"})," must be a supported ",(0,n.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes",children:"access mode"})]}),"\n",(0,n.jsx)(s.li,{children:"volume must be protected against data loss due to hardware failures of a single disk or host"}),"\n",(0,n.jsx)(s.li,{children:"volume must not be bound to the lifecycle of a Kubernetes Node"}),"\n"]}),"\n",(0,n.jsx)(s.p,{children:"Hence,"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:"...volume must not be backed by local storage on the Kubernetes Node VM itself"}),"\n",(0,n.jsx)(s.li,{children:"...volume may be backed by some kind of redundant storage within an AZ, across hosts"}),"\n",(0,n.jsx)(s.li,{children:"...volume may be backed by some kind of redundant storage across AZ's"}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"required-performance-related-properties",children:"Required performance-related properties"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.em,{children:"NO"})," fixed guarantees regarding latency/bandwidth/IOPS/..."]}),"\n"]}),"\n",(0,n.jsx)(s.p,{children:"Generally, customers should be able to expect low-tier performance without pricing surprises."}),"\n",(0,n.jsx)(s.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,n.jsx)(s.p,{children:"This document does not describe performance related properties.\nThis will be done in another document which is yet to be created."}),"\n",(0,n.jsx)(s.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,n.jsxs)(s.p,{children:["The script ",(0,n.jsx)(s.code,{children:"k8s-default-storage-class-check.py"})," requires a kubeconfig file with connection\ndetails for the Kubernetes cluster that should be checked for conformance.\nIt will check for a default storage class and use the associated storage provider to\ntry to create and mount a PersistentVolumeClaim with the aforementioned properties to\na container in a Pod.\nAfter it is done, it cleans up the resources.\nRule violations will be reported on various logging channels: ERROR for mandatory rules\nand INFO for recommended rules.\nAn exit code of zero indicates that the standard has been met."]})]})}function u(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>o,x:()=>i});var a=t(96540);const n={},r=a.createContext(n);function o(e){const s=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/093291a8.2a67108d.js b/assets/js/093291a8.2a67108d.js new file mode 100644 index 0000000000..d8f60b56c9 --- /dev/null +++ b/assets/js/093291a8.2a67108d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[51276],{39220:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>c,default:()=>l,frontMatter:()=>d,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"ops/scs-0411","title":"scs-0411: Push-based approach for providing usage data","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/ops/scs-0411.md","sourceDirName":"ops","slug":"/ops/scs-0411","permalink":"/standards/ops/scs-0411","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0410-v1-gnocchi-as-metering-database"},"next":{"title":"V1","permalink":"/standards/scs-0411-v1-publishing_method_for_metering_data"}}');var r=t(74848),a=t(28453);const d={},c="scs-0411: Push-based approach for providing usage data",i={},o=[];function h(e){const s={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"scs-0411-push-based-approach-for-providing-usage-data",children:"scs-0411: Push-based approach for providing usage data"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0411-v1-publishing_method_for_metering_data",children:"scs-0411-v1"})}),(0,r.jsx)(s.td,{children:"Decision Record"}),(0,r.jsx)(s.td,{children:"Draft"}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]})})]})]})}function l(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>d,x:()=>c});var n=t(96540);const r={},a=n.createContext(r);function d(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0935f628.14e0eee9.js b/assets/js/0935f628.14e0eee9.js new file mode 100644 index 0000000000..76fec24f4e --- /dev/null +++ b/assets/js/0935f628.14e0eee9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[31036],{27162:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>p,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>r});const s=JSON.parse('{"id":"operating-scs/components/status-page-openapi/docs/component_overview","title":"Component Overview","description":"This represents a part of the decision process related to the overall structure the API wants to represent.","source":"@site/docs/04-operating-scs/components/status-page-openapi/docs/component_overview.md","sourceDirName":"04-operating-scs/components/status-page-openapi/docs","slug":"/operating-scs/components/status-page-openapi/docs/component_overview","permalink":"/docs/operating-scs/components/status-page-openapi/docs/component_overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-openapi/docs/component_overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"\\"Levels of consensus\\"","permalink":"/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus"},"next":{"title":"API","permalink":"/docs/category/api"}}');var o=t(74848),a=t(28453);const i={},p="Component Overview",c={},r=[];function l(e){const n={h1:"h1",header:"header",li:"li",mermaid:"mermaid",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"component-overview",children:"Component Overview"})}),"\n",(0,o.jsx)(n.p,{children:"This represents a part of the decision process related to the overall structure the API wants to represent."}),"\n",(0,o.jsx)(n.mermaid,{value:'C4Component\n title status-page-openapi\n\n Container_Boundary(impacts, "Impacts") {\n Component(impactType, ImpactType, "ID, displayName, description")\n Component(impact, Impact, "type, reference, severity")\n Component(impactComponentList, ImpactComponentList, "[]Impact", "Impacts reference components")\n Component(impactIncidentList, ImpactIncidentList, "<>[]Impact", "Impacts reference incidents")\n Component(severity, Severity,"name, value")\n\n Rel(impact, impactType, "has")\n Rel(impactComponentList, impact, "lists")\n Rel(impactIncidentList, impact, "lists")\n Rel(impact, severity, "has")\n\n UpdateElementStyle(impact, $bgColor="green")\n UpdateElementStyle(impactComponentList, $bgColor="green")\n UpdateElementStyle(impactIncidentList, $bgColor="green")\n UpdateElementStyle(severity, $bgColor="green")\n\n UpdateRelStyle(impact, impactType, "green", "green", $offsetY="-10")\n UpdateRelStyle(impactComponentList, impact, "green", "green", $offsetY="-15")\n UpdateRelStyle(impactIncidentList, impact, "green", "green")\n UpdateRelStyle(impact, severity, "green", "green")\n }\n\n Container_Boundary(incidents, "Incidents") {\n Component(incidentUpdate, IncidentUpdate, "order, displayName, description, createdAt")\n Component(incident, Incident, "ID, displayName, description, updates, affects, beganAt, endedAt, Phase")\n\n Rel(incident, incidentUpdate, "contains")\n }\n\n Container_Boundary(phases, "Phases") {\n Component(phaseReference, PhaseReference, "Phase, order, generation")\n Component(phase, Phase, "", "it is just a name")\n Component(phaseList, PhaseList, "generation, []Phase")\n\n Rel(phaseList, phase, "lists")\n Rel(phaseReference, phase, "references")\n Rel(phaseReference, phaseList, "references")\n\n UpdateElementStyle(phaseReference, $bgColor="green")\n UpdateElementStyle(phaseList, $bgColor="green")\n\n UpdateRelStyle(phaseList, phase, "green", "green", $offsetY="5")\n UpdateRelStyle(phaseReference, phase, "green", "green", $offsetX="-30", $offsetY="10")\n UpdateRelStyle(phaseReference, phaseList, "green", "green", $offsetY="5")\n\n }\n\n Container_Boundary(components, "Components") {\n Component(component, Component, "ID, displayName, Labels, activelyAffectedBy")\n Component(labels, Labels, "", "Key value pairs")\n\n Rel(component, labels, "contains")\n }\n\n %% global relations %%\n %% deprecated %%\n Rel(incident, impactType, "has")\n BiRel(component, incident, "affects / affected by")\n\n UpdateRelStyle(incident, impactType, "red", "red")\n UpdateRelStyle(component, incident, "red", "red", $offsetX="10")\n\n %% new %%\n Rel(incident, impactComponentList, "affects")\n Rel(component, impactIncidentList, "actively affected by", "only list active/open impacts")\n Rel(incident, phaseReference, "has")\n Rel(impact, component, "references", "from impactComponentList")\n Rel(impact, incident, "references", "from impactIncidentList")\n\n UpdateRelStyle(incident, impactComponentList, "green", "green")\n UpdateRelStyle(component, impactIncidentList, "green", "green", $offsetX="-180", $offsetY="-70")\n UpdateRelStyle(incident, phaseReference, "green", "green", $offsetX="-70", $offsetY="40")\n UpdateRelStyle(impact, component, "green", "green", $offsetX="-140")\n UpdateRelStyle(impact, incident, "green", "green", $offsetX="-100")\n'}),"\n",(0,o.jsx)(n.p,{children:"Color meaning:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Blue: Existing structure"}),"\n",(0,o.jsx)(n.li,{children:"Red: Deprecated / removed"}),"\n",(0,o.jsx)(n.li,{children:"Green: New"}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>p});var s=t(96540);const o={},a=s.createContext(o);function i(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function p(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/09539d9b.59dc480e.js b/assets/js/09539d9b.59dc480e.js new file mode 100644 index 0000000000..8f009be047 --- /dev/null +++ b/assets/js/09539d9b.59dc480e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7344],{43938:(e,a,n)=>{n.r(a),n.d(a,{assets:()=>s,contentTitle:()=>t,default:()=>_,frontMatter:()=>d,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"scs-0302-w1-domain-manager-implementation-notes","title":"Domain Manager implementation notes","description":"Implementation notes","source":"@site/standards/scs-0302-w1-domain-manager-implementation-notes.md","sourceDirName":".","slug":"/scs-0302-w1-domain-manager-implementation-notes","permalink":"/standards/scs-0302-w1-domain-manager-implementation-notes","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Domain Manager implementation notes","type":"Supplement","track":"IAM","status":"Draft","supplements":["scs-0302-v1-domain-manager-role.md"]},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0302-v1-domain-manager-role"},"next":{"title":"Ops Standards","permalink":"/standards/ops/"}}');var r=n(74848),o=n(28453);const d={title:"Domain Manager implementation notes",type:"Supplement",track:"IAM",status:"Draft",supplements:["scs-0302-v1-domain-manager-role.md"]},t=void 0,s={},l=[{value:"Implementation notes",id:"implementation-notes",level:2},{value:"Policy adjustments",id:"policy-adjustments",level:3},{value:"Specifying manageable roles via "is_domain_managed_role"",id:"specifying-manageable-roles-via-is_domain_managed_role",level:4},{value:"Example: permitting multiple roles",id:"example-permitting-multiple-roles",level:5},{value:"Impact",id:"impact",level:3},{value:"Security implications",id:"security-implications",level:4}];function m(e){const a={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(a.h2,{id:"implementation-notes",children:"Implementation notes"}),"\n",(0,r.jsx)(a.admonition,{type:"caution",children:(0,r.jsxs)(a.p,{children:["If a Keystone release of OpenStack 2024.2 or later is used, ",(0,r.jsx)(a.strong,{children:"the policy configuration described in this document MUST be removed again"})," in case it was applied in the past prior to the upgrade."]})}),"\n",(0,r.jsxs)(a.admonition,{type:"info",children:[(0,r.jsx)(a.p,{children:'The implementation described in this document only applies to Keystone releases prior to the OpenStack release 2024.2 ("Dalmatian").\nThis document describes a transitional solution to offer the Domain Manager functionality for SCS clouds based on an OpenStack release earlier than 2024.2.'}),(0,r.jsx)(a.p,{children:"Beginning with the 2024.2 release of OpenStack, the Domain Manager persona is integrated natively into Keystone and the implementation described below is unnecessary and might conflict with the native implementation."})]}),"\n",(0,r.jsx)(a.h3,{id:"policy-adjustments",children:"Policy adjustments"}),"\n",(0,r.jsx)(a.p,{children:'The following policy can be applied to Keystone releases older than 2024.2 ("Dalmatian").\nIt mimics the Domain Manager persona implemented by Keystone starting with version 2024.2 and makes the functionality available for earlier releases of Keystone.'}),"\n",(0,r.jsx)(a.p,{children:"The only parts of the policy definitions below that may be changed are:"}),"\n",(0,r.jsxs)(a.ol,{children:["\n",(0,r.jsxs)(a.li,{children:['The "',(0,r.jsx)(a.code,{children:"base_*"}),'" definitions to align them to the correct OpenStack defaults matching the OpenStack release of the environment in case those differ from this template.']}),"\n",(0,r.jsxs)(a.li,{children:['The "',(0,r.jsx)(a.code,{children:"is_domain_managed_role"}),'" definition (see next section below).']}),"\n"]}),"\n",(0,r.jsx)(a.pre,{children:(0,r.jsx)(a.code,{className:"language-yaml",children:'# SCS Domain Manager policy configuration\n\n# Section A: OpenStack base definitions\n# The entries beginning with "base_" should be exact copies of the\n# default "identity:" definitions for the target OpenStack release.\n# They will be extended upon for the manager role below this section.\n"base_get_domain": "(role:reader and system_scope:all) or token.domain.id:%(target.domain.id)s or token.project.domain.id:%(target.domain.id)s"\n"base_list_domains": "(role:reader and system_scope:all)"\n"base_list_roles": "(role:reader and system_scope:all)"\n"base_get_role": "(role:reader and system_scope:all)"\n"base_list_users": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"\n"base_get_user": "(role:reader and system_scope:all) or (role:reader and token.domain.id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"\n"base_create_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"\n"base_update_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"\n"base_delete_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"\n"base_list_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"\n"base_get_project": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.project.domain_id)s) or project_id:%(target.project.id)s"\n"base_create_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"\n"base_update_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"\n"base_delete_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"\n"base_list_user_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"\n"base_check_grant": "(role:reader and system_scope:all) or ((role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"\n"base_list_grants": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)"\n"base_create_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"\n"base_revoke_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"\n"base_list_role_assignments": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"\n"base_list_groups": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"\n"base_get_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"\n"base_create_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"\n"base_update_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"\n"base_delete_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"\n"base_list_groups_for_user": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(user_id)s"\n"base_list_users_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"\n"base_remove_user_from_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"\n"base_check_user_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"\n"base_add_user_to_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"\n\n# Section B: Domain Manager Extensions\n\n# classify domain managers with a special role\n"is_domain_manager": "role:manager"\n\n# specify a rule that whitelists roles which domain admins are permitted\n# to assign and revoke within their domain\n"is_domain_managed_role": "\'member\':%(target.role.name)s or \'load-balancer_member\':%(target.role.name)s"\n\n# allow domain admins to retrieve their own domain (does not need changes)\n"identity:get_domain": "rule:base_get_domain or rule:admin_required"\n\n# list_domains is needed for GET /v3/domains?name=... requests\n# this is mandatory for things like\n# `create user --domain $DOMAIN_NAME $USER_NAME` to correctly discover\n# domains by name\n"identity:list_domains": "rule:is_domain_manager or rule:base_list_domains or rule:admin_required"\n\n# list_roles is needed for GET /v3/roles?name=... requests\n# this is mandatory for things like `role add ... $ROLE_NAME`` to correctly\n# discover roles by name\n"identity:list_roles": "rule:is_domain_manager or rule:base_list_roles or rule:admin_required"\n\n# get_role is needed for GET /v3/roles/{role_id} requests\n# this is mandatory for the OpenStack SDK to properly process role assignments\n# which are issued by role id instead of name\n"identity:get_role": "(rule:is_domain_manager and rule:is_domain_managed_role) or rule:base_get_role or rule:admin_required"\n\n# allow domain admins to manage users within their domain\n"identity:list_users": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_users or rule:admin_required"\n"identity:get_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_get_user or rule:admin_required"\n"identity:create_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_create_user or rule:admin_required"\n"identity:update_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_update_user or rule:admin_required"\n"identity:delete_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_delete_user or rule:admin_required"\n\n# allow domain admins to manage projects within their domain\n"identity:list_projects": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_projects or rule:admin_required"\n"identity:get_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_get_project or rule:admin_required"\n"identity:create_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_create_project or rule:admin_required"\n"identity:update_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_update_project or rule:admin_required"\n"identity:delete_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_delete_project or rule:admin_required"\n"identity:list_user_projects": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_user_projects or rule:admin_required"\n\n# allow domain managers to manage role assignments within their domain\n# (restricted to specific roles by the \'is_domain_managed_role\' rule)\n#\n# project-level role assignment to user within domain\n"is_domain_user_project_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s"\n# project-level role assignment to group within domain\n"is_domain_group_project_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.project.domain_id)s"\n# domain-level role assignment to group\n"is_domain_level_group_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.domain.id)s"\n# domain-level role assignment to user\n"is_domain_level_user_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.domain.id)s"\n"domain_manager_grant": "rule:is_domain_manager and (rule:is_domain_user_project_grant or rule:is_domain_group_project_grant or rule:is_domain_level_group_grant or rule:is_domain_level_user_grant)"\n"identity:check_grant": "rule:domain_manager_grant or rule:base_check_grant or rule:admin_required"\n"identity:list_grants": "rule:domain_manager_grant or rule:base_list_grants or rule:admin_required"\n"identity:create_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_create_grant or rule:admin_required"\n"identity:revoke_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_revoke_grant or rule:admin_required"\n"identity:list_role_assignments": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_role_assignments or rule:admin_required"\n\n# allow domain managers to manage groups within their domain\n"identity:list_groups": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_list_groups or rule:admin_required"\n"identity:get_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_get_group or rule:admin_required"\n"identity:create_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_create_group or rule:admin_required"\n"identity:update_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_update_group or rule:admin_required"\n"identity:delete_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_delete_group or rule:admin_required"\n"identity:list_groups_for_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_groups_for_user or rule:admin_required"\n"identity:list_users_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_list_users_in_group or rule:admin_required"\n"identity:remove_user_from_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_remove_user_from_group or rule:admin_required"\n"identity:check_user_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_check_user_in_group or rule:admin_required"\n"identity:add_user_to_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_add_user_to_group or rule:admin_required"\n'})}),"\n",(0,r.jsxs)(a.p,{children:['Note that the policy file begins with a list of "',(0,r.jsx)(a.code,{children:"base_*"}),'" rule definitions ("Section A").\nThese mirror the default policies of recent OpenStack releases.\nThey are used as a basis for the domain-manager-specific changes which are implemented in "Section B" where they are referenced to via "',(0,r.jsx)(a.code,{children:"or rule:base_*"}),'" accordingly.\nThe section of "',(0,r.jsx)(a.code,{children:"base_*"}),'" rules is meant for easy maintenance/update of default rules while keeping the domain-manager-specific rules separate.']}),"\n",(0,r.jsxs)(a.blockquote,{children:["\n",(0,r.jsxs)(a.p,{children:[(0,r.jsx)(a.strong,{children:"Note:"}),'\nThe "',(0,r.jsx)(a.code,{children:"or rule:admin_required"}),'" appendix to the rule definitions in "Section B" is included for backwards compatibility with environments not yet fully configured for the new secure RBAC standard',(0,r.jsx)(a.sup,{children:(0,r.jsx)(a.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"."]}),"\n"]}),"\n",(0,r.jsxs)(a.h4,{id:"specifying-manageable-roles-via-is_domain_managed_role",children:['Specifying manageable roles via "',(0,r.jsx)(a.code,{children:"is_domain_managed_role"}),'"']}),"\n",(0,r.jsxs)(a.p,{children:['The "',(0,r.jsx)(a.code,{children:"is_domain_managed_role"}),'" rule of the above policy template may be adjusted according to the requirements of the CSP and infrastructure architecture to specify different or multiple roles as manageable by Domain Managers as long as the policy rule adheres to the following:']}),"\n",(0,r.jsxs)(a.ul,{children:["\n",(0,r.jsxs)(a.li,{children:['the "',(0,r.jsx)(a.code,{children:"is_domain_managed_role"}),'" rule MUST NOT contain the "',(0,r.jsx)(a.code,{children:"admin"}),'" role, neither directly nor transitively']}),"\n",(0,r.jsxs)(a.li,{children:['the "',(0,r.jsx)(a.code,{children:"is_domain_managed_role"}),'" rule MUST define all applicable roles directly, it MUST NOT contain a "',(0,r.jsx)(a.code,{children:"rule:"}),'" reference within itself']}),"\n"]}),"\n",(0,r.jsx)(a.h5,{id:"example-permitting-multiple-roles",children:"Example: permitting multiple roles"}),"\n",(0,r.jsxs)(a.p,{children:['The following example permits the "',(0,r.jsx)(a.code,{children:"reader"}),'" role to be assigned/revoked by a Domain Manager in addition to the default "',(0,r.jsx)(a.code,{children:"member"}),'" and "',(0,r.jsx)(a.code,{children:"load-balancer_member"}),'" roles.\nFurther roles can be appended using the logical ',(0,r.jsx)(a.code,{children:"or"})," directive."]}),"\n",(0,r.jsx)(a.pre,{children:(0,r.jsx)(a.code,{className:"language-yaml",children:"\"is_domain_managed_role\": \"'member':%(target.role.name)s or 'load-balancer_member':%(target.role.name)s or 'reader':%(target.role.name)s\"\n"})}),"\n",(0,r.jsx)(a.p,{children:(0,r.jsxs)(a.strong,{children:["Note regarding the ",(0,r.jsx)(a.code,{children:"manager"})," role"]})}),"\n",(0,r.jsxs)(a.p,{children:['When adjusting the "',(0,r.jsx)(a.code,{children:"is_domain_managed_role"}),'" rule a CSP might opt to also include the "',(0,r.jsx)(a.code,{children:"manager"}),'" role itself in the manageable roles, resulting in Domain Managers being able to propagate the Domain Manager capabilities to other users within their domain.\nThis increases the self-service capabilities of the customer but introduces risks of Domain Managers also being able to revoke this role from themselves or each other (within their domain) in an unintended fashion.']}),"\n",(0,r.jsxs)(a.p,{children:['CSPs have to carefully evaluate whether Domain Manager designation authority should reside solely on their side or be part of the customer self-service scope and decide about adding "',(0,r.jsx)(a.code,{children:"'manager':%(target.role.name)s"}),'" to the rule accordingly.']}),"\n",(0,r.jsx)(a.h3,{id:"impact",children:"Impact"}),"\n",(0,r.jsx)(a.p,{children:"Applying this implementation modifies the API policy configuration of Keystone and introduces a new persona to Keystone to enable IAM self-service for customers within a domain.\nOnce assigned, this persona allows special Domain Manager users within a domain to manage users, project, groups and role assignments as part of the IAM self-service."}),"\n",(0,r.jsx)(a.p,{children:"However, the configuration change introduced by this implementation does not automatically assign the Domain Manager persona to any users per default.\nAssigning the new persona and granting customers the resulting self-service capabilities is a deliberate action to be taken by the CSP on a per-tenant (i.e. per domain) basis."}),"\n",(0,r.jsx)(a.p,{children:"Omitting the provisioning of any Domain Manager users (i.e. not assigning the new persona to any user) will result in an OpenStack cloud that behaves identically to a configuration without the implementation applied, making the actual usage of the functionality a CSP's choice and entirely optional."}),"\n",(0,r.jsx)(a.h4,{id:"security-implications",children:"Security implications"}),"\n",(0,r.jsxs)(a.p,{children:['As a result of the "',(0,r.jsx)(a.code,{children:"identity:list_roles"}),'" rule (see above), Domain Managers are able to see all roles via "',(0,r.jsx)(a.code,{children:"openstack role list"}),'" and can inspect the metadata of any role with "',(0,r.jsx)(a.code,{children:"openstack role show"}),'"']}),"\n","\n",(0,r.jsxs)(a.section,{"data-footnotes":!0,className:"footnotes",children:[(0,r.jsx)(a.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,r.jsxs)(a.ol,{children:["\n",(0,r.jsxs)(a.li,{id:"user-content-fn-1",children:["\n",(0,r.jsxs)(a.p,{children:[(0,r.jsx)(a.a,{href:"https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html",children:"OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC"})," ",(0,r.jsx)(a.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function _(e={}){const{wrapper:a}={...(0,o.R)(),...e.components};return a?(0,r.jsx)(a,{...e,children:(0,r.jsx)(m,{...e})}):m(e)}},28453:(e,a,n)=>{n.d(a,{R:()=>d,x:()=>t});var i=n(96540);const r={},o=i.createContext(r);function d(e){const a=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function t(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),i.createElement(o.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/096c51c8.3a7b9861.js b/assets/js/096c51c8.3a7b9861.js new file mode 100644 index 0000000000..67afe56002 --- /dev/null +++ b/assets/js/096c51c8.3a7b9861.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[92544],{20738:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"contribute/linting-guide","title":"Linting Guide","description":"In order to have a clean content repository regarding all markdown files we enforce linting on:","source":"@site/community/contribute/linting-guide.md","sourceDirName":"contribute","slug":"/contribute/linting-guide","permalink":"/community/contribute/linting-guide","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Documentation workflow explanation","permalink":"/community/contribute/docs-workflow-explanation"},"next":{"title":"Installation","permalink":"/community/contribute/local-docusaurus-development-guide"}}');var r=i(74848),l=i(28453);const o={},s="Linting Guide",c={},d=[{value:"Pre Commit",id:"pre-commit",level:2},{value:"Local Usage for development",id:"local-usage-for-development",level:2},{value:"Github Workflows",id:"github-workflows",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,l.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"linting-guide",children:"Linting Guide"})}),"\n",(0,r.jsx)(n.p,{children:"In order to have a clean content repository regarding all markdown files we enforce linting on:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"all staged files prior committing"}),"\n",(0,r.jsx)(n.li,{children:"all Pull Requests"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"pre-commit",children:"Pre Commit"}),"\n",(0,r.jsx)(n.p,{children:"Run markdownlint against staged git files with Husky git hook:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://github.com/okonet/lint-staged",children:"lint-staged"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://github.com/typicode/husky",children:"husky"})}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The rules are enforced on markdown files, for which we use:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"https://github.com/DavidAnson/markdownlint-cli2",children:"markdownlint-cli2"})," for markdownlint"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"https://github.com/prettier/prettier",children:"prettier"})," for code formatting"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The markdownlint rules are defined in the configuration file ",(0,r.jsx)(n.code,{children:".markdownlint-cli2.jsonc"})]}),"\n",(0,r.jsxs)(n.p,{children:["Additionally we use ",(0,r.jsx)(n.a,{href:"https://github.com/OnkarRuikar/markdownlint-rule-search-replace",children:"markdownlint-rule-search-replace"})," for fixing"]}),"\n",(0,r.jsx)(n.h2,{id:"local-usage-for-development",children:"Local Usage for development"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm run lint:md \nnpm run fix:md \n"})}),"\n",(0,r.jsx)(n.h2,{id:"github-workflows",children:"Github Workflows"}),"\n",(0,r.jsxs)(n.p,{children:["There are two actions running on every Pull Request on the ",(0,r.jsx)(n.code,{children:"main"})," branch."]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"link-validator.yml"}),"is checking every link in markdown files."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"pr-markdownlint.yml"}),"is checking all markdown files regarding to the rules defined within ",(0,r.jsx)(n.code,{children:".markdownlint-cli2.jsonc"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>s});var t=i(96540);const r={},l=t.createContext(r);function o(e){const n=t.useContext(l);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/09adb968.9cd91f6b.js b/assets/js/09adb968.9cd91f6b.js new file mode 100644 index 0000000000..26ef832965 --- /dev/null +++ b/assets/js/09adb968.9cd91f6b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6148],{28412:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"operating-scs/incident-management/index","title":"Overview","description":"TODO","source":"@site/docs/04-operating-scs/03-incident-management/index.md","sourceDirName":"04-operating-scs/03-incident-management","slug":"/operating-scs/incident-management/","permalink":"/docs/operating-scs/incident-management/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/03-incident-management/index.md","tags":[],"version":"current","frontMatter":{}}');var r=t(74848),c=t(28453);const i={},o="Overview",a={},d=[];function m(e){const n={h1:"h1",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(n.p,{children:"TODO"})]})}function u(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(m,{...e})}):m(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>o});var s=t(96540);const r={},c=s.createContext(r);function i(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/09ba26e2.0e3a26bb.js b/assets/js/09ba26e2.0e3a26bb.js new file mode 100644 index 0000000000..d3fdef08a9 --- /dev/null +++ b/assets/js/09ba26e2.0e3a26bb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[99244],{35186:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>a,contentTitle:()=>d,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"iaas/guides/deploy-guide/index","title":"Deploy Guide","description":"OSISM is deployed in a series of successive steps. The steps are documented in the Deploy Guide.","source":"@site/docs/02-iaas/guides/deploy-guide/index.md","sourceDirName":"02-iaas/guides/deploy-guide","slug":"/iaas/guides/deploy-guide/","permalink":"/docs/iaas/guides/deploy-guide/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/index.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Deploy Guide","sidebar_position":10},"sidebar":"docs","previous":{"title":"Hardware Bill of Materials","permalink":"/docs/iaas/guides/concept-guide/hardware-bom"},"next":{"title":"Seed","permalink":"/docs/iaas/guides/deploy-guide/seed"}}');var o=n(74848),t=n(28453);const r={sidebar_label:"Deploy Guide",sidebar_position:10},d="Deploy Guide",a={},c=[];function l(e){const i={a:"a",admonition:"admonition",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(i.header,{children:(0,o.jsx)(i.h1,{id:"deploy-guide",children:"Deploy Guide"})}),"\n",(0,o.jsx)(i.p,{children:"OSISM is deployed in a series of successive steps. The steps are documented in the Deploy Guide."}),"\n",(0,o.jsx)(i.admonition,{type:"info",children:(0,o.jsxs)(i.p,{children:["The prerequisite for the deployment of a cluster is a configuration repository.\nWhat a configuration repository is and how it is created is described in the\n",(0,o.jsx)(i.a,{href:"/docs/iaas/guides/configuration-guide/configuration-repository#creating-a-new-configuration-repository",children:"Configuration Guide"}),"."]})}),"\n",(0,o.jsxs)(i.ul,{children:["\n",(0,o.jsxs)(i.li,{children:["Step 1: ",(0,o.jsx)(i.a,{href:"../configuration-guide/configuration-repository#creating-a-new-configuration-repository",children:"Creation of a configuration repository"})]}),"\n",(0,o.jsxs)(i.li,{children:["Step 2: ",(0,o.jsx)(i.a,{href:"./seed",children:"Preparation of the seed node"})]}),"\n",(0,o.jsxs)(i.li,{children:["Step 3: ",(0,o.jsx)(i.a,{href:"./manager",children:"Preparation of the manager node"})]}),"\n",(0,o.jsxs)(i.li,{children:["Step 4: ",(0,o.jsx)(i.a,{href:"./provisioning",children:"Provisioning of the bare-metal nodes"})]}),"\n",(0,o.jsxs)(i.li,{children:["Step 5: ",(0,o.jsx)(i.a,{href:"./bootstrap",children:"Bootstrap of the bare-metal nodes"})]}),"\n",(0,o.jsxs)(i.li,{children:["Step 6: ",(0,o.jsx)(i.a,{href:"./services",children:"Deployment of the services"})]}),"\n"]})]})}function u(e={}){const{wrapper:i}={...(0,t.R)(),...e.components};return i?(0,o.jsx)(i,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>r,x:()=>d});var s=n(96540);const o={},t=s.createContext(o);function r(e){const i=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function d(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(t.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/09cf625e.62a9af43.js b/assets/js/09cf625e.62a9af43.js new file mode 100644 index 0000000000..837566b761 --- /dev/null +++ b/assets/js/09cf625e.62a9af43.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[53767],{35458:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"operating-scs/overview","title":"Overview","description":"TODO","source":"@site/docs/04-operating-scs/overview.md","sourceDirName":"04-operating-scs","slug":"/operating-scs/overview","permalink":"/docs/operating-scs/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/overview.md","tags":[],"version":"current","frontMatter":{"sidebar":1}}');var s=n(74848),o=n(28453);const c={sidebar:1},i="Overview",a={},d=[];function u(e){const t={h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,s.jsx)(t.p,{children:"TODO"})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var r=n(96540);const s={},o=r.createContext(s);function c(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0a757274.588aeb9b.js b/assets/js/0a757274.588aeb9b.js new file mode 100644 index 0000000000..c96ce08d3c --- /dev/null +++ b/assets/js/0a757274.588aeb9b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[48296],{38344:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>u,frontMatter:()=>c,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"iaas/overview/knowledge","title":"Knowledge","description":"TODO","source":"@site/docs/02-iaas/overview/knowledge.md","sourceDirName":"02-iaas/overview","slug":"/iaas/overview/knowledge","permalink":"/docs/iaas/overview/knowledge","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/overview/knowledge.md","tags":[],"version":"current","frontMatter":{}}');var r=t(74848),s=t(28453);const c={},i="Knowledge",a={},d=[];function l(e){const n={h1:"h1",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"knowledge",children:"Knowledge"})}),"\n",(0,r.jsx)(n.p,{children:"TODO"})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var o=t(96540);const r={},s=o.createContext(r);function c(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0bb6d954.24833c61.js b/assets/js/0bb6d954.24833c61.js new file mode 100644 index 0000000000..905d160dba --- /dev/null +++ b/assets/js/0bb6d954.24833c61.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[77479],{54341:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>l,frontMatter:()=>s,metadata:()=>a,toc:()=>r});const a=JSON.parse('{"id":"iaas/guides/concept-guide/components/netdata","title":"Netdata","description":"Lifecycle Management of Netdata in OSISM","source":"@site/docs/02-iaas/guides/concept-guide/components/netdata.md","sourceDirName":"02-iaas/guides/concept-guide/components","slug":"/iaas/guides/concept-guide/components/netdata","permalink":"/docs/iaas/guides/concept-guide/components/netdata","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/netdata.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Keycloak","permalink":"/docs/iaas/guides/concept-guide/components/keycloak"},"next":{"title":"OpenStack","permalink":"/docs/iaas/guides/concept-guide/components/openstack"}}');var o=n(74848),c=n(28453);const s={},i="Netdata",d={},r=[{value:"Lifecycle Management of Netdata in OSISM",id:"lifecycle-management-of-netdata-in-osism",level:2}];function u(e){const t={h1:"h1",h2:"h2",header:"header",...(0,c.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"netdata",children:"Netdata"})}),"\n",(0,o.jsx)(t.h2,{id:"lifecycle-management-of-netdata-in-osism",children:"Lifecycle Management of Netdata in OSISM"})]})}function l(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>i});var a=n(96540);const o={},c=a.createContext(o);function s(e){const t=a.useContext(c);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),a.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0bcc5672.88b461b0.js b/assets/js/0bcc5672.88b461b0.js new file mode 100644 index 0000000000..154f7fcee3 --- /dev/null +++ b/assets/js/0bcc5672.88b461b0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1085],{20254:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>m,frontMatter:()=>a,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"container/deployment-examples/a/software","title":"Software Requirements","description":"TODO","source":"@site/docs/03-container/deployment-examples/a/software.md","sourceDirName":"03-container/deployment-examples/a","slug":"/container/deployment-examples/a/software","permalink":"/docs/container/deployment-examples/a/software","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/deployment-examples/a/software.md","tags":[],"version":"current","frontMatter":{}}');var r=n(74848),s=n(28453);const a={},c="Software Requirements",i={},d=[];function l(e){const t={h1:"h1",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"software-requirements",children:"Software Requirements"})}),"\n",(0,r.jsx)(t.p,{children:"TODO"})]})}function m(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>c});var o=n(96540);const r={},s=o.createContext(r);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0c1b7bd3.62cd96f8.js b/assets/js/0c1b7bd3.62cd96f8.js new file mode 100644 index 0000000000..92fcaf0df3 --- /dev/null +++ b/assets/js/0c1b7bd3.62cd96f8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[20717],{30746:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Central API","slug":"/category/central-api","permalink":"/docs/category/central-api","sidebar":"docs","navigation":{"previous":{"title":"Observability stack quickstart","permalink":"/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack"},"next":{"title":"Overview","permalink":"/docs/operating-scs/components/central-api/overview"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/0c2cbcc3.3647afbf.js b/assets/js/0c2cbcc3.3647afbf.js new file mode 100644 index 0000000000..8779347519 --- /dev/null +++ b/assets/js/0c2cbcc3.3647afbf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[23786],{3908:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>p,frontMatter:()=>c,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"operating-scs/components/status-page-web/docs/contribute","title":"Contribute","description":"To start developing for the status page web frontend, start by cloning the repo. Remember to run git submodule update --init afterwards to also retrieve the OpenAPI client included in the sources.","source":"@site/docs/04-operating-scs/components/status-page-web/docs/contribute.md","sourceDirName":"04-operating-scs/components/status-page-web/docs","slug":"/operating-scs/components/status-page-web/docs/contribute","permalink":"/docs/operating-scs/components/status-page-web/docs/contribute","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-web/docs/contribute.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Configuration","permalink":"/docs/operating-scs/components/status-page-web/docs/configuration"},"next":{"title":"Monitoring","permalink":"/docs/category/monitoring"}}');var s=o(74848),r=o(28453);const c={},a="Contribute",i={},d=[];function l(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"contribute",children:"Contribute"})}),"\n",(0,s.jsxs)(t.p,{children:["To start developing for the status page web frontend, start by cloning ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-web",children:"the repo"}),". Remember to run ",(0,s.jsx)(t.code,{children:"git submodule update --init"})," afterwards to also retrieve the OpenAPI client included in the sources."]}),"\n",(0,s.jsxs)(t.p,{children:["Now you should follow ",(0,s.jsx)(t.a,{href:"https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/quickstart",children:"the Quickstart guide"})," of the ",(0,s.jsx)(t.code,{children:"status-page-deployment"})," repo and deploy and configure a local kind environment. You may have to modify your hosts file to re-route requests to the available components:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-hosts",children:"127.0.0.1 api.localhost dex.localhost oathkeeper.localhost web.localhost monitoring.localhost\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You can now copy the configuration file template and set the ",(0,s.jsx)(t.code,{children:"apiServerUrl"})," and ",(0,s.jsx)(t.code,{children:"dexUrl"})," properties to ",(0,s.jsx)(t.code,{children:"http://api.localhost:8080"})," and ",(0,s.jsx)(t.code,{children:"http://dex.localhost:8080"}),", respectively. Set your ",(0,s.jsx)(t.code,{children:"dexId"})," to ",(0,s.jsx)(t.code,{children:"status-page-web"})," and the ",(0,s.jsx)(t.code,{children:"redirectUrl"})," to ",(0,s.jsx)(t.code,{children:"http://localhost:4200/login"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["You are now ready to run ",(0,s.jsx)(t.code,{children:"npm install"})," to retrieve all dependencies. Afterwards, you can start the application locally by running ",(0,s.jsx)(t.code,{children:"npx ng serve"}),". The status page will be available under ",(0,s.jsx)(t.a,{href:"http://localhost:4200",children:"http://localhost:4200"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["This repo also contains ",(0,s.jsx)(t.a,{href:"https://code.visualstudio.com/docs/devcontainers/containers",children:"Devcontainer files for Visual Studio Code"})," and we suggest using this to quickly set up your development environment."]})]})}function p(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,o)=>{o.d(t,{R:()=>c,x:()=>a});var n=o(96540);const s={},r=n.createContext(s);function c(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0cb1d654.f5aaff36.js b/assets/js/0cb1d654.f5aaff36.js new file mode 100644 index 0000000000..e87ae1e637 --- /dev/null +++ b/assets/js/0cb1d654.f5aaff36.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[36182],{35720:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"operating-scs/components/monitoring/docs/overview","title":"Overview","description":"This repository aims to build an Observer monitoring solution intended to offer a global metrics","source":"@site/docs/04-operating-scs/components/monitoring/docs/overview.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/overview","permalink":"/docs/operating-scs/components/monitoring/docs/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Monitoring","permalink":"/docs/category/monitoring"},"next":{"title":"Quickstart","permalink":"/docs/operating-scs/components/monitoring/docs/quickstart"}}');var s=o(74848),i=o(28453);const r={},c="Overview",a={},l=[];function d(e){const n={a:"a",code:"code",h1:"h1",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,s.jsxs)(n.p,{children:["This repository aims to build an Observer monitoring solution intended to offer a global ",(0,s.jsx)(n.strong,{children:"metrics"}),"\nview of the CSP infrastructure. It is the platform where CSP infrastructure ",(0,s.jsx)(n.strong,{children:"metrics"}),"\nare fetched, processed, stored, and visualized. Note that this monitoring solution could\nbe extended, and the other two observability signals (logs and traces) from the CSP\ninfrastructure could also be processed here."]}),"\n",(0,s.jsxs)(n.p,{children:["The Observer monitoring solution is developed on the foundation of the ",(0,s.jsx)(n.a,{href:"https://github.com/dNationCloud/kubernetes-monitoring",children:"dNation monitoring solution"}),".\nand it is intended to become an ",(0,s.jsx)(n.strong,{children:"SCS product"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This repository includes the manifest for the stable deployment of the Observer monitoring solution,\nas well as experimental and illustrative examples of how this monitoring solution can be extended and utilized."}),"\n",(0,s.jsxs)(n.p,{children:["The stable version of the Observer monitoring solution empowers its reference SCS installation available\nat ",(0,s.jsx)(n.a,{href:"https://monitoring.scs.community",children:"https://monitoring.scs.community"}),". This deployment covers the monitoring of core SCS infrastructure services,\nsubsequently referred to as 'Monitoring of infrastructure services'. Refer to the details ",(0,s.jsx)(n.a,{href:"/docs/operating-scs/components/monitoring/docs/scs-deployment",children:"here"}),".\nThe high-level architecture could be visualized as follows:"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"monitoring_scs_high_level.png",src:o(38552).A+"",width:"970",height:"508"})}),"\n",(0,s.jsxs)(n.p,{children:["Some illustrative and experimental examples of how this monitoring solution can be utilized have been introduced\nwithin the MVP-0 version of this project (refer to the ",(0,s.jsx)(n.code,{children:"mvp-0"})," tag, related comments, and docs sections: ",(0,s.jsx)(n.a,{href:"/docs/operating-scs/components/monitoring/docs/kaas",children:"kaas"}),", ",(0,s.jsx)(n.a,{href:"/docs/operating-scs/components/monitoring/docs/iaas",children:"iaas"}),").\nThese examples include:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Monitoring of the KaaS layer"}),"\n",(0,s.jsx)(n.li,{children:"Monitoring of the IaaS layer"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The above experimental components ",(0,s.jsx)(n.strong,{children:"are not part"})," of the reference SCS installation available\nat ",(0,s.jsx)(n.a,{href:"https://monitoring.scs.community",children:"https://monitoring.scs.community"}),".\nThe high-level architecture of these experimental components could be visualized as follows:"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"monitoring_scs_experimental.png",src:o(3705).A+"",width:"946",height:"467"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},3705:(e,n,o)=>{o.d(n,{A:()=>t});const t=o.p+"assets/images/monitoring_scs_experimental-3846febea17c1ecf9baaa074ee9b1a10.png"},38552:(e,n,o)=>{o.d(n,{A:()=>t});const t=o.p+"assets/images/monitoring_scs_high_level-50f86d39d750e803a31513fb32942e41.png"},28453:(e,n,o)=>{o.d(n,{R:()=>r,x:()=>c});var t=o(96540);const s={},i=t.createContext(s);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0d2860b1.73e3b874.js b/assets/js/0d2860b1.73e3b874.js new file mode 100644 index 0000000000..6fe73181f9 --- /dev/null +++ b/assets/js/0d2860b1.73e3b874.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[67148],{59042:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>o,contentTitle:()=>c,default:()=>m,frontMatter:()=>s,metadata:()=>i,toc:()=>r});const i=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/tools/image-manager/update","title":"Image Manager update.py","description":"Overview","source":"@site/docs/02-iaas/guides/operations-guide/openstack/tools/image-manager/update.md","sourceDirName":"02-iaas/guides/operations-guide/openstack/tools/image-manager","slug":"/iaas/guides/operations-guide/openstack/tools/image-manager/update","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/image-manager/update.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"sidebar_label":"Automated updates","sidebar_position":1},"sidebar":"docs","previous":{"title":"Image Manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/"},"next":{"title":"Flavor Manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager"}}');var n=t(74848),d=t(28453);const s={sidebar_label:"Automated updates",sidebar_position:1},c="Image Manager update.py",o={},r=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Usage",id:"usage",level:2}];function u(e){const a={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,d.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(a.header,{children:(0,n.jsx)(a.h1,{id:"image-manager-updatepy",children:"Image Manager update.py"})}),"\n",(0,n.jsx)(a.h2,{id:"overview",children:"Overview"}),"\n",(0,n.jsxs)(a.p,{children:["The OpenStack Image Manager ",(0,n.jsx)(a.code,{children:"update.py"})," Script updates the ",(0,n.jsx)(a.code,{children:"/etc/images/*.yaml"})," files to the always latest release of the distributions, set S3 mirror URLs and uploads the images to the mirror."]}),"\n",(0,n.jsx)(a.p,{children:"These updated yaml files are later processed by the Image Manger itself."}),"\n",(0,n.jsx)(a.h2,{id:"installation",children:"Installation"}),"\n",(0,n.jsxs)(a.p,{children:["Prepare to use the ",(0,n.jsx)(a.code,{children:"update.py"})," script."]}),"\n",(0,n.jsx)(a.pre,{children:(0,n.jsx)(a.code,{children:"git clone https://github.com/osism/openstack-image-manager/\ncd openstack-image-manager\npipenv install\npipenv shell\n"})}),"\n",(0,n.jsx)(a.h2,{id:"usage",children:"Usage"}),"\n",(0,n.jsx)(a.pre,{children:(0,n.jsx)(a.code,{children:"python contrib/update.py --help\n\n Usage: update.py [OPTIONS]\n\n\u256d\u2500 Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 --debug Enable debug logging \u2502\n\u2502 --dry-run Do not perform any changes \u2502\n\u2502 --minio-access-key TEXT Minio access key [env var: MINIO_ACCESS_KEY] [default: None] \u2502\n\u2502 --minio-secret-key TEXT Minio secret key [env var: MINIO_SECRET_KEY] [default: None] \u2502\n\u2502 --minio-server TEXT Minio server [env var: MINIO_SERVER] [default: swift.services.a.regiocloud.tech] \u2502\n\u2502 --minio-bucket TEXT Minio bucket [env var: MINIO_BUCKET] [default: openstack-images] \u2502\n\u2502 --swift-prefix TEXT Swift prefix [env var: SWIFT_PREFIX] [default: swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/] \u2502\n\u2502 --install-completion Install completion for the current shell. \u2502\n\u2502 --show-completion Show completion for the current shell, to copy it or customize the installation. \u2502\n\u2502 --help Show this message and exit. \u2502\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n"})}),"\n",(0,n.jsx)(a.admonition,{type:"note",children:(0,n.jsxs)(a.ul,{children:["\n",(0,n.jsx)(a.li,{children:"At this time the update.py expects all yaml files at /etc/images/, which can't be configured at the moment."}),"\n",(0,n.jsx)(a.li,{children:"Mirroring can't be disabled at the moment."}),"\n"]})}),"\n",(0,n.jsxs)(a.p,{children:["Best run this script by cron or a CI job, to update all distribution files periodically to the latest release and afterwards run ",(0,n.jsx)(a.a,{href:"../image-manager/",children:"Openstack Image Manager"}),".\nThe distribution image yaml files must exist before running the script, you can use the files from the Github repo at ",(0,n.jsx)(a.code,{children:"etc/images/"})," as template for your first run."]}),"\n",(0,n.jsx)(a.pre,{children:(0,n.jsx)(a.code,{children:"$ python contrib/update.py\n2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/centos.yml\n2024-04-24 09:29:44 | INFO | update_image:179 - Checking image CentOS Stream 9\n2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-HEREBE\\d+\\.\\dDRAGONS.x86_64.qcow2\n2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cloud.centos.org/centos/9-stream/x86_64/images/CHECKSUM\n2024-04-24 09:29:44 | INFO | get_latest_default:62 - Latest URL is now https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2\n2024-04-24 09:29:44 | INFO | get_latest_default:63 - Latest filename is now CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2\n2024-04-24 09:29:44 | INFO | update_image:192 - Checksum of current CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337\n2024-04-24 09:29:44 | INFO | update_image:208 - Our checksum is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337\n2024-04-24 09:29:44 | INFO | update_image:211 - Image CentOS Stream 9 is up-to-date, nothing to do\n2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/debian.yml\n2024-04-24 09:29:44 | INFO | update_image:179 - Checking image Debian 11\n2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bullseye/latest/debian-11-genericcloud-amd64.raw\n2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bullseye/latest/SHA512SUMS\n2024-04-24 09:29:45 | INFO | update_image:192 - Checksum of current debian-11-genericcloud-amd64-20240211-1654.raw is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4\n2024-04-24 09:29:45 | INFO | update_image:208 - Our checksum is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4\n2024-04-24 09:29:45 | INFO | update_image:211 - Image Debian 11 is up-to-date, nothing to do\n2024-04-24 09:29:45 | INFO | update_image:179 - Checking image Debian 12\n2024-04-24 09:29:45 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.raw\n2024-04-24 09:29:45 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS\n2024-04-24 09:29:46 | INFO | update_image:192 - Checksum of current debian-12-genericcloud-amd64-daily-20240424-1727.raw is sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e\n2024-04-24 09:29:46 | INFO | update_image:208 - Our checksum is sha512:5401f8c6361bb2a82c2c24b4b4606d95e77229152a80e61f9c613bc88e25de9257057d0ed68b0256b745c4059162a54970fe4a8daf456b2eb67b4f5db5c97fcc\n2024-04-24 09:29:46 | INFO | update_image:229 - New values are {'version': '20240424', 'build_date': datetime.date(2024, 4, 24), 'checksum': 'sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e', 'url': 'https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240424-1727/debian-12-genericcloud-amd64-daily-20240424-1727.raw'}\n2024-04-24 09:29:46 | INFO | main:300 - Processing file /etc/images/rockylinux.yml\n2024-04-24 09:29:46 | INFO | update_image:179 - Checking image Rocky 9\n2024-04-24 09:29:46 | INFO | update_image:182 - Latest download URL is https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2\n2024-04-24 09:29:46 | INFO | update_image:185 - Getting checksums from https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2.CHECKSUM\n2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current Rocky-9-GenericCloud.latest.x86_64.qcow2 is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651\n2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651\n2024-04-24 09:29:47 | INFO | update_image:211 - Image Rocky_9 is up-to-date, nothing to do\n2024-04-24 09:29:47 | INFO | main:300 - Processing file /etc/images/ubuntu.yml\n2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04\n2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img\n2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS\n2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current jammy-server-cloudimg-amd64.img is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710\n2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710\n2024-04-24 09:29:47 | INFO | update_image:211 - Image Ubuntu_22.04 is up-to-date, nothing to do\n2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04 Minimal\n2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64.img\n2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/minimal/releases/jammy/release/SHA256SUMS\n2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current ubuntu-22.04-minimal-cloudimg-amd64.img is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65\n2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65\n2024-04-24 09:29:48 | INFO | update_image:211 - Image Ubuntu 22.04 Minimal is up-to-date, nothing to do\n2024-04-24 09:29:48 | INFO | update_image:179 - Checking image Ubuntu 24.04\n2024-04-24 09:29:48 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img\n2024-04-24 09:29:48 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/noble/current/SHA256SUMS\n2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current noble-server-cloudimg-amd64.img is sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3\n2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:d7ba8d5d1d073f2dc8351973bf4f35157c846a0ea6ee16fb2a9f45a78953e4a7\n2024-04-24 09:29:48 | INFO | update_image:229 - New values are {'version': '20240423', 'build_date': datetime.date(2024, 4, 23), 'checksum': 'sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3', 'url': 'https://cloud-images.ubuntu.com/noble/20240423/noble-server-cloudimg-amd64.img'}\n"})}),"\n",(0,n.jsxs)(a.p,{children:["These yaml files are now extended with additional fields and the ",(0,n.jsx)(a.code,{children:"update.py"})," will take care of the versions, checksum, url and build date to the latest release in the yaml file on every run."]}),"\n",(0,n.jsxs)(a.ul,{children:["\n",(0,n.jsx)(a.li,{children:"latest_checksum_url - URL of the distros checksum file"}),"\n",(0,n.jsx)(a.li,{children:"latest_url - URL of the distros latest image"}),"\n",(0,n.jsx)(a.li,{children:"mirror_url - URL of the Image File at the local S3 Mirror"}),"\n"]}),"\n",(0,n.jsx)(a.pre,{children:(0,n.jsx)(a.code,{className:"language-yaml",metastring:'title="someexample.yaml"',children:"---\nimages:\n - name: Debian 12\n enable: true\n shortname: debian-12\n format: qcow2\n login: debian\n min_disk: 8\n min_ram: 512\n status: active\n visibility: public\n multi: true\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_rng_model: virtio\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n hypervisor_type: qemu\n os_distro: debian\n os_version: '12'\n replace_frequency: quarterly\n uuid_validity: last-3\n provided_until: none\n tags: []\n latest_checksum_url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS\n latest_url:\n https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.qcow2\n versions:\n - build_date: 2024-04-11\n checksum:\n sha512:3d6f26616e2c8b705993ddef874232887cebe42f1e70fcc020827ac88e8990177d537d34538c71ae2afd3b8baca953fff71eaa7ef71e752e82532c93dcdca436\n url:\n https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240411-1714/debian-12-genericcloud-amd64-daily-20240411-1714.qcow2\n mirror_url:\n https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-images/debian-12/20240411-debian-12.qcow2\n version: '20240411'\n\n"})})]})}function m(e={}){const{wrapper:a}={...(0,d.R)(),...e.components};return a?(0,n.jsx)(a,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,a,t)=>{t.d(a,{R:()=>s,x:()=>c});var i=t(96540);const n={},d=i.createContext(n);function s(e){const a=i.useContext(d);return i.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function c(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:s(e.components),i.createElement(d.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0dfeccb2.f7dfd56f.js b/assets/js/0dfeccb2.f7dfd56f.js new file mode 100644 index 0000000000..9cb9154990 --- /dev/null +++ b/assets/js/0dfeccb2.f7dfd56f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[94342],{63532:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"scs-0410-v1-gnocchi-as-metering-database","title":"Gnocchi as database for metering","description":"for more info. --\x3e","source":"@site/standards/scs-0410-v1-gnocchi-as-metering-database.md","sourceDirName":".","slug":"/scs-0410-v1-gnocchi-as-metering-database","permalink":"/standards/scs-0410-v1-gnocchi-as-metering-database","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Gnocchi as database for metering","type":"Decision Record","status":"Draft","track":"Ops"},"sidebar":"standards","previous":{"title":"scs-0410: Gnocchi as database for metering","permalink":"/standards/ops/scs-0410"},"next":{"title":"scs-0411: Push-based approach for providing usage data","permalink":"/standards/ops/scs-0411"}}');var t=i(74848),a=i(28453);const o={title:"Gnocchi as database for metering",type:"Decision Record",status:"Draft",track:"Ops"},r=void 0,c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Definitions",id:"definitions",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options",id:"options",level:3},{value:"Using Gnocchi",id:"using-gnocchi",level:4},{value:"Using Prometheus",id:"using-prometheus",level:4},{value:"Using InfluxDB",id:"using-influxdb",level:4},{value:"Creating a custom TSDB implementation",id:"creating-a-custom-tsdb-implementation",level:4},{value:"Decision",id:"decision",level:2},{value:"Open questions",id:"open-questions",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function d(e){const n={a:"a",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsx)(n.p,{children:"In the past we noticed missing events in the telemetry stack of OpenStack.\nThis results in situations where the Cloud Service Provider (CSP)\nmay think that a resource is still in use while the owner shut it down,\nor may not be aware of a resource which has been created."}),"\n",(0,t.jsx)(n.p,{children:"Such inaccurate data is a problem,\nwhen it is supposed to be used for billing purposes."}),"\n",(0,t.jsx)(n.p,{children:"This document discusses how such metering data should be stored\nwithin the SCS.\nIn particular,\nit provides rationale for the choice of Gnocchi\nas time-series database for metering data\nwithin SCS."}),"\n",(0,t.jsx)(n.h2,{id:"definitions",children:"Definitions"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"TSDB, time-series database:\nDatabase which is specialised for storing data which is keyed by a timestamp.\nPopular examples are InfluxDB, Graphite, rrd, and Prometheus."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Metering:\nCollection of usage data of a cloud,\nfor the specific purpose of creating invoices\nto bill customers for the resources they have allocated."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"backfilling:\nThe process of adding and modifying data in the past\nwithin a time-series database."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Metric:\nA single time-series vector.\nTypically, a metric represents a single property of a resource,\nsuch as CPU usage of an instance."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Resource metrics:\nA group of metrics belonging to a single resource.\nA compute instance, for instance,\nmay have a metric indicating the number of CPUs allocated,\nanother metric indicating the amount of RAM allocated,\netc."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,t.jsx)(n.p,{children:"Being able to hold users accountable\nfor the resources they use\nis a prerequisite for commercially operating a cloud.\nThe SCS project wants to deliver a cloud stack\nwhich can be used for that purpose,\nhence providing reliable metering data is a requirement."}),"\n",(0,t.jsx)(n.p,{children:"As metering data is inherently keyed by time,\na time-series database is required.\nThe choice of time-series database is an important one\nas different databases come with different trade-offs.\nNot all databases are suitable for the kind of data\nwhich is collected in a metering context."}),"\n",(0,t.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,t.jsx)(n.p,{children:"The following requirements for a time-series database exist:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"MUST support backfilling:\nAs we need to catch up on changes to resources\nwhich may have happened during a brief network interruption,\nwe need to be able to modify data after it has been written to the TSDB."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"MUST be able to handle lots of resources:\nAs billing should happen with a resource-level granularity,\nwe expect a lot of different metrics inside the TSDB."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"MUST scale to different timescales:\nWe expect to have metrics which change frequently (e.g. object store usage)\nand metrics which change rarely (e.g. cinder volume sizes).\nThe TSDB must be able to cope with both types of metrics efficiently."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"SHOULD provide an efficient way to query all currently alive resources."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"SHOULD allow truncation of storage to remove old data."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"MUST be available under an appropriate Open Source license,\neven for productive use cases."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"options",children:"Options"}),"\n",(0,t.jsx)(n.h4,{id:"using-gnocchi",children:"Using Gnocchi"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://gnocchi.osci.io/",children:"Gnocchi"})," is a time-series database\nwhich has its origins in the OpenStack ecosystem."]}),"\n",(0,t.jsx)(n.p,{children:"It supports all requirements except truncation,\nwhich might have to be implemented."}),"\n",(0,t.jsx)(n.h4,{id:"using-prometheus",children:"Using Prometheus"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://prometheus.io",children:"Prometheus"})," is a widely used time-series database\nwith its focus on monitoring and incident response.\nWhile it is considered efficient for this use-case,\nit has shortcomings which make it unsuitable for the metering use case:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Explicit recommendation ",(0,t.jsx)(n.a,{href:"https://prometheus.io/docs/practices/instrumentation/#do-not-overuse-labels",children:"against high-cardinality metrics"}),":\nAs we would have to label metrics by resource IDs and project IDs,\nwe have to expect a very high cardinality,\nalso with a significant amount of metric churn."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Backfilling, ",(0,t.jsx)(n.a,{href:"https://prometheus.io/docs/prometheus/latest/storage/#backfilling-from-openmetrics-format",children:"albeit possible"}),", is not well-supported."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"using-influxdb",children:"Using InfluxDB"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://www.influxdata.com/",children:"InfluxDB"})," is a widely used time-series database\nwith its focus on monitoring."]}),"\n",(0,t.jsxs)(n.p,{children:["In contrast to Prometheus, it does support backfilling.\nHowever, like Prometheus,\nit seems to run ",(0,t.jsx)(n.a,{href:"https://docs.influxdata.com/influxdb/cloud/write-data/best-practices/resolve-high-cardinality/",children:"into scalability issues in high-cardinality scenarios"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"In addition,\nclustering is only available in commercial licensing options."}),"\n",(0,t.jsx)(n.h4,{id:"creating-a-custom-tsdb-implementation",children:"Creating a custom TSDB implementation"}),"\n",(0,t.jsx)(n.p,{children:"A custom TSDB implementation\nis a non-trivial project to pursue."}),"\n",(0,t.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,t.jsx)(n.p,{children:"We use Gnocchi.\nAccording to research,\nit mostly fulfills the requirements.\nWhile some small development efforts may be needed,\nto make it fully usable,\nthe amount of work is anticipated much less\nthan making Prometheus or Influx fit the bill\n(due to backfilling / cardinality scaling constraints),\nlet alone rolling a custom implementation."}),"\n",(0,t.jsx)(n.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"What will be the granularity of the events meta information?"}),"\n",(0,t.jsx)(n.p,{children:"If we decide to use resource metadata\nas a place to store slow-changing information\n(e.g. instance flavors, volume sizes),\nwe need to know what the granularity of that is."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"SCS-0411-v1"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,t.jsx)(n.p,{children:"None (this is a decision record)."})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>r});var s=i(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0e4c395f.6819d356.js b/assets/js/0e4c395f.6819d356.js new file mode 100644 index 0000000000..9835965c3b --- /dev/null +++ b/assets/js/0e4c395f.6819d356.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[33384],{11325:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"operating-scs/components/monitoring/docs/scs-deployment","title":"SCS deployment","description":"The following steps were utilized to deploy the SCS reference installation of the Observer monitoring solution,","source":"@site/docs/04-operating-scs/components/monitoring/docs/scs-deployment.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/scs-deployment","permalink":"/docs/operating-scs/components/monitoring/docs/scs-deployment","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/scs-deployment.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Quickstart","permalink":"/docs/operating-scs/components/monitoring/docs/quickstart"},"next":{"title":"K3s support","permalink":"/docs/operating-scs/components/monitoring/docs/k3s"}}');var o=s(74848),i=s(28453);const r={},l="SCS deployment",c={},a=[{value:"Architecture",id:"architecture",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install Observer solution",id:"install-observer-solution",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"scs-deployment",children:"SCS deployment"})}),"\n",(0,o.jsxs)(n.p,{children:["The following steps were utilized to deploy the SCS reference installation of the Observer monitoring solution,\nwhich is available at ",(0,o.jsx)(n.a,{href:"https://monitoring.scs.community",children:"https://monitoring.scs.community"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"architecture",children:"Architecture"}),"\n",(0,o.jsx)(n.p,{children:"Currently, the detailed architecture diagram can be visualized as follows:"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{alt:"monitoring_scs_detailed.png",src:s(79403).A+"",width:"1430",height:"1165"})}),"\n",(0,o.jsxs)(n.p,{children:["The SCS Observer includes the ",(0,o.jsx)(n.a,{href:"https://grafana.com/oss/loki/",children:"Loki"})," deployment along with the ",(0,o.jsx)(n.a,{href:"https://grafana.com/docs/loki/latest/send-data/promtail/",children:"Promtail"}),"\nagent on each Observer node. This setup ensures that the SCS Observer platform collects logs from itself and can also\nserve as a global, horizontally scalable, highly available, multi-tenant log aggregation system."]}),"\n",(0,o.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Kubernetes cluster","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["We used the R5 version of ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/",children:"SCS KaaS V1"}),", which includes an ingress controller and cert manager","\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"export KUBECONFIG=/path/to/kubeconfig\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://kubernetes.io/docs/reference/kubectl/",children:"kubectl"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://helm.sh/",children:"helm"})}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"install-observer-solution",children:"Install Observer solution"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Apply SCS brand secrets and letsencrypt issuer manifest."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f scs/logo.yaml\nkubectl apply -f scs/brand.yaml\nkubectl apply -f scs/issuer.yaml\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Deploy the Zuul monitoring related Helm chart and all associated manifests according to the instructions provided on ",(0,o.jsx)(n.a,{href:"/docs/operating-scs/components/monitoring/docs/zuul",children:"this"})," documentation page."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Deploy the Alertmanager to Matrix chat notifications related manifest according to the instructions provided on ",(0,o.jsx)(n.a,{href:"/docs/operating-scs/components/monitoring/docs/alertmanager",children:"this"})," documentation page."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Deploy the OAUTH related manifest according to the instructions provided on ",(0,o.jsx)(n.a,{href:"/docs/operating-scs/components/monitoring/docs/oauth",children:"this"})," documentation page."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Review the ",(0,o.jsx)(n.code,{children:"values-observer-scs.yaml"}),' file and locate all instances of the placeholder text "replace-me".\nThese values relate to configuring access to the object stores (for Thanos and Loki), the Grafana admin password and\nLoki API basic auth username and password.']}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Finally, install the monitoring stack using values that incorporate all the configurations mentioned above"}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/\nhelm repo update dnationcloud\nhelm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer-scs.yaml\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},79403:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/monitoring_scs_detailed-593b1b8ce16c1873883e38a381e02faa.png"},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0ea173ba.2a37f9e0.js b/assets/js/0ea173ba.2a37f9e0.js new file mode 100644 index 0000000000..5cf740db50 --- /dev/null +++ b/assets/js/0ea173ba.2a37f9e0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[75341],{39651:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>d,default:()=>h,frontMatter:()=>n,metadata:()=>c,toc:()=>o});const c=JSON.parse('{"id":"certification/overview","title":"overview","description":"SCS certificates come with various scopes. See Scopes and Versions for details.","source":"@site/standards/certification/overview.md","sourceDirName":"certification","slug":"/certification/overview","permalink":"/standards/certification/overview","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"Introduction","permalink":"/standards/"},"next":{"title":"Scopes and versions","permalink":"/standards/certification/scopes-versions"}}');var r=s(74848),i=s(28453);const n={},d="Certification",l={},o=[{value:"Becoming certified",id:"becoming-certified",level:2},{value:"Compliant cloud environments",id:"compliant-cloud-environments",level:2}];function a(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"certification",children:"Certification"})}),"\n",(0,r.jsxs)(t.p,{children:["SCS certificates come with various scopes. See ",(0,r.jsx)(t.a,{href:"/standards/certification/scopes-versions",children:"Scopes and Versions"})," for details."]}),"\n",(0,r.jsx)(t.h2,{id:"becoming-certified",children:"Becoming certified"}),"\n",(0,r.jsxs)(t.p,{children:["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 ",(0,r.jsx)(t.a,{href:"/standards/scs-0004-v1-achieving-certification",children:"document"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"compliant-cloud-environments",children:"Compliant cloud environments"}),"\n",(0,r.jsxs)(t.p,{children:["This is a list of clouds that we test on a nightly basis against the certificate scope ",(0,r.jsx)(t.em,{children:"SCS-compatible IaaS"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Version numbers are suffixed by a symbol depending on state: * for ",(0,r.jsx)(t.em,{children:"draft"}),", \u2020 for ",(0,r.jsx)(t.em,{children:"warn"})," (soon to be deprecated), and \u2020\u2020 for ",(0,r.jsx)(t.em,{children:"deprecated"}),"."]}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Name"}),(0,r.jsx)(t.th,{children:"Description"}),(0,r.jsx)(t.th,{children:"Operator"}),(0,r.jsx)(t.th,{children:(0,r.jsx)(t.a,{href:"https://docs.scs.community/standards/scs-compatible-iaas/",children:"SCS-compatible IaaS"})}),(0,r.jsx)(t.th,{style:{textAlign:"center"},children:"HealthMon"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/cloud-resources/plusserver-gx-scs.md",children:"gx-scs"})}),(0,r.jsx)(t.td,{children:"Dev environment provided for SCS & GAIA-X context"}),(0,r.jsx)(t.td,{children:"plusserver GmbH"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/gx-scs/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\ud83d\udfe7 v3\u2020\u2020"})}),(0,r.jsx)(t.td,{style:{textAlign:"center"},children:(0,r.jsx)(t.a,{href:"https://health.gx-scs.sovereignit.cloud:3000/",children:"HM"})})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://www.aov.de/",children:"aov.cloud"})}),(0,r.jsx)(t.td,{children:"Community cloud for customers"}),(0,r.jsx)(t.td,{children:"aov IT.Services GmbH"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/aov/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\ud83d\uded1 \u2013"})}),(0,r.jsx)(t.td,{style:{textAlign:"center"},children:(0,r.jsx)(t.a,{href:"https://health.aov.cloud/",children:"HM"})})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://www.rrze.fau.de/",children:"CC@RRZE"})}),(0,r.jsxs)(t.td,{children:["Private Compute Cloud (CC) for ",(0,r.jsx)(t.a,{href:"https://www.fau.de/",children:"FAU"})]}),(0,r.jsx)(t.td,{children:"Regionales Rechenzentrum Erlangen"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/cc-rrze/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\u2705 v4, v5.1"})}),(0,r.jsx)(t.td,{style:{textAlign:"center"},children:"(soon)"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://cnds.io/",children:"CNDS"})}),(0,r.jsx)(t.td,{children:"Public cloud for customers"}),(0,r.jsx)(t.td,{children:"artcodix GmbH"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/artcodix/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\u2705 v4, v5.1"})}),(0,r.jsx)(t.td,{style:{textAlign:"center"},children:(0,r.jsx)(t.a,{href:"https://ohm.muc.cloud.cnds.io/",children:"HM"})})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.a,{href:"https://www.plusserver.com/en/products/pluscloud-open",children:"pluscloud open"}),(0,r.jsx)("br",{}),"(4 regions)"]}),(0,r.jsx)(t.td,{children:"Public cloud for customers"}),(0,r.jsx)(t.td,{children:"plusserver GmbH"}),(0,r.jsxs)(t.td,{children:["prod1: ",(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/pco-prod1/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\ud83d\uded1 \u2013"}),(0,r.jsx)("br",{}),"prod2: ",(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/pco-prod2/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\ud83d\uded1 \u2013"}),(0,r.jsx)("br",{}),"prod3: ",(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/pco-prod3/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\ud83d\uded1 \u2013"}),(0,r.jsx)("br",{}),"prod4: ",(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/pco-prod4/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\ud83d\uded1 \u2013"})]}),(0,r.jsxs)(t.td,{style:{textAlign:"center"},children:[(0,r.jsx)(t.a,{href:"https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-pco",children:"HM1"}),(0,r.jsx)("br",{}),(0,r.jsx)(t.a,{href:"https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-prod2",children:"HM2"}),(0,r.jsx)("br",{}),(0,r.jsx)(t.a,{href:"https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-prod3",children:"HM3"}),(0,r.jsx)("br",{}),(0,r.jsx)(t.a,{href:"https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-prod4",children:"HM4"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"PoC KDO"}),(0,r.jsx)(t.td,{children:"Cloud PoC for FITKO"}),(0,r.jsx)(t.td,{children:"KDO Service GmbH / OSISM GmbH"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/poc-kdo/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\ud83d\uded1 \u2013"})}),(0,r.jsx)(t.td,{style:{textAlign:"center"},children:"(soon)"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"PoC WG-Cloud OSBA"}),(0,r.jsx)(t.td,{children:"Cloud PoC for FITKO"}),(0,r.jsx)(t.td,{children:"Cloud&Heat Technologies GmbH"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/poc-wgcloud/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\u2705 v4"})}),(0,r.jsx)(t.td,{style:{textAlign:"center"},children:(0,r.jsx)(t.a,{href:"https://health.poc-wgcloud.osba.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?var-mycloud=poc-wgcloud&orgId=1",children:"HM"})})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"})}),(0,r.jsx)(t.td,{children:"Public cloud for customers"}),(0,r.jsx)(t.td,{children:"OSISM GmbH"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/regio-a/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\ud83d\uded1 \u2013"})}),(0,r.jsx)(t.td,{style:{textAlign:"center"},children:(0,r.jsx)(t.a,{href:"https://apimon.services.regio.digital/public-dashboards/17cf094a47404398a5b8e35a4a3968d4?orgId=1&refresh=5m",children:"HM"})})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://www.scaleuptech.com/cloud-hosting/",children:"ScaleUp Open Cloud"})}),(0,r.jsx)(t.td,{children:"Public cloud for customers"}),(0,r.jsx)(t.td,{children:"ScaleUp Technologies GmbH & Co. KG"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/scaleup-occ2/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\u2705 v4, v5.1"})}),(0,r.jsx)(t.td,{style:{textAlign:"center"},children:(0,r.jsx)(t.a,{href:"https://health.occ2.scaleup.sovereignit.cloud",children:"HM"})})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsxs)(t.td,{children:[(0,r.jsx)(t.a,{href:"https://www.syseleven.de/en/products-services/openstack-cloud/",children:"syseleven"}),(0,r.jsx)("br",{}),"(2 SCS regions)"]}),(0,r.jsx)(t.td,{children:"Public OpenStack Cloud"}),(0,r.jsx)(t.td,{children:"SysEleven GmbH"}),(0,r.jsxs)(t.td,{children:["dus2: ",(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/syseleven-dus2/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\ud83d\udfe7 v3\u2020\u2020"}),(0,r.jsx)("br",{}),"ham1: ",(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/syseleven-ham1/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\ud83d\udfe7 v3\u2020\u2020"})]}),(0,r.jsxs)(t.td,{style:{textAlign:"center"},children:["(soon)",(0,r.jsx)("br",{}),"(soon)"]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://www.noris.de/wavestack-cloud/",children:"Wavestack"})}),(0,r.jsx)(t.td,{children:"Public cloud for customers"}),(0,r.jsx)(t.td,{children:"noris network AG/Wavecon GmbH"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://compliance.sovereignit.cloud/page/detail/wavestack/50393e6f-2ae1-4c5c-a62c-3b75f2abef3f",children:"\ud83d\uded1 \u2013"})}),(0,r.jsx)(t.td,{style:{textAlign:"center"},children:(0,r.jsx)(t.a,{href:"https://health.wavestack1.sovereignit.cloud:3000/",children:"HM"})})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>n,x:()=>d});var c=s(96540);const r={},i=c.createContext(r);function n(e){const t=c.useContext(i);return c.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:n(e.components),c.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0eef3953.9ab7cf8b.js b/assets/js/0eef3953.9ab7cf8b.js new file mode 100644 index 0000000000..a8b6d56483 --- /dev/null +++ b/assets/js/0eef3953.9ab7cf8b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[78423],{94850:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>c,frontMatter:()=>s,metadata:()=>a,toc:()=>h});const a=JSON.parse('{"id":"scs-0121-v1-Availability-Zones-Standard","title":"SCS Availability Zones","description":"Introduction","source":"@site/standards/scs-0121-v1-Availability-Zones-Standard.md","sourceDirName":".","slug":"/scs-0121-v1-Availability-Zones-Standard","permalink":"/standards/scs-0121-v1-Availability-Zones-Standard","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Availability Zones","type":"Standard","status":"Stable","stabilized_at":"2024-11-13T00:00:00.000Z","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0121: SCS Availability Zones","permalink":"/standards/iaas/scs-0121"},"next":{"title":"W1","permalink":"/standards/scs-0121-w1-Availability-Zones-Standard"}}');var i=t(74848),o=t(28453);const s={title:"SCS Availability Zones",type:"Standard",status:"Stable",stabilized_at:new Date("2024-11-13T00:00:00.000Z"),track:"IaaS"},r=void 0,l={},h=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Scope of the Availability Zone Standard",id:"scope-of-the-availability-zone-standard",level:3},{value:"Options considered",id:"options-considered",level:3},{value:"Physical-based Availability Zones",id:"physical-based-availability-zones",level:4},{value:"AZs in Compute",id:"azs-in-compute",level:4},{value:"AZs in Storage",id:"azs-in-storage",level:4},{value:"AZs in Network",id:"azs-in-network",level:4},{value:"Cross-Attaching volumes from one AZ to another compute AZ",id:"cross-attaching-volumes-from-one-az-to-another-compute-az",level:3},{value:"Standard",id:"standard",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function d(e){const n={a:"a",admonition:"admonition",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",section:"section",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"On the IaaS level especially in OpenStack it is possible to group resources in Availability Zones.\nSuch Zones often are mapped to the physical layer of a deployment, such as e.g. physical separation of hardware or redundancy of power circuits or fire zones.\nBut how CSPs apply Availability Zones to the IaaS Layer in one deplyoment may differ widely.\nTherefore this standard will address the minimal requirements that need to be met, when creating Avaiability Zones."}),"\n",(0,i.jsx)(n.h2,{id:"terminology",children:"Terminology"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Term"}),(0,i.jsx)(n.th,{children:"Explanation"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Availability Zone"}),(0,i.jsx)(n.td,{children:"(also: AZ) internal representation of physical grouping of service hosts, which also lead to internal grouping of resources."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Fire Zone"}),(0,i.jsx)(n.td,{children:"A physical separation in a data center that will contain fire within it. Effectively stopping spreading of fire."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"PDU"}),(0,i.jsx)(n.td,{children:"Power Distribution Unit, used to distribute the power to all physical machines of a single server rack."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Compute"}),(0,i.jsx)(n.td,{children:"A generic name for the IaaS service, that manages virtual machines (e.g. Nova in OpenStack)."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Network"}),(0,i.jsx)(n.td,{children:"A generic name for the IaaS service, that manages network resources (e.g. Neutron in OpenStack)."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Storage"}),(0,i.jsx)(n.td,{children:"A generic name for the IaaS service, that manages the storage backends and virtual devices (e.g. Cinder in OpenStack)."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BSI"}),(0,i.jsx)(n.td,{children:"German Federal Office for Information Security (Bundesamt f\xfcr Sicherheit in der Informationstechnik)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CSP"}),(0,i.jsx)(n.td,{children:"Cloud Service Provider, provider managing the OpenStack infrastructure."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SDN"}),(0,i.jsx)(n.td,{children:"Software Defined Network, virtual networks managed by the networking service."})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(n.p,{children:"Redundancy is a non-trivial but relevant issue for a cloud deployment.\nFirst and foremost it is necessary to increase failure safety through redundancy on the physical layer.\nThe IaaS layer as the first abstraction layer from the hardware has an important role in this topic, too.\nThe grouping of redundant physical resources into Availability Zones on the IaaS level, gives customers the option to distribute their workload to different AZs which will result in a better failure safety.\nWhile CSPs already have some similarities in their grouping of physical resources to AZs, there are also differences.\nThis standard aims to reduce those differences and will clarify, what customers can expect from Availability Zones in IaaS."}),"\n",(0,i.jsxs)(n.p,{children:["Availability Zones in IaaS can be set up for Compute, Network and Storage separately while all may be referring to the same physical separation in a deployment.\nThis standard elaborates the necessity of having Availability Zones for each of these classes of resources.\nIt will also check the requirements customers may have, when thinking about Availability Zones in relation to the taxonomy of failure safety levels ",(0,i.jsx)(n.sup,{children:(0,i.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),".\nThe result should enable CSPs to know when to create AZs to be SCS-compliant."]}),"\n",(0,i.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsxs)(n.p,{children:["Availability Zones should represent parts of the same physical deployment that are independent of each other.\nThe maximum level of physical independence is achieved through putting physical machines into different fire zones.\nIn that case a failure case up to level 3 as described in the taxonomy of failure safety levels document",(0,i.jsx)(n.sup,{children:(0,i.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})," will not lead to a complete outage of the deployment."]}),"\n",(0,i.jsx)(n.p,{children:"Having Availability Zones represent fire zones will also result in AZs being able to take workload from another AZ in a failure case of Level 3.\nSo that even the destruction of one Availability Zone will not automatically include the destruction of the other AZs."}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:["Even with fire zones being physically designed to protect parts of a data center from severe destruction in case of a fire, this will not always succeed.\nAvailability Zones in Clouds are most of the time within the same physical data center.\nIn case of a big catastrophe like a huge fire or a flood the whole data center could be destroyed.\nAvailability Zones will not protect customers against these failure cases of level 4 of the taxonomy of failure safety",(0,i.jsx)(n.sup,{children:(0,i.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"."]})}),"\n",(0,i.jsx)(n.p,{children:"Smaller deplyoments like edge deployments may not have more than one fire zone in a single location.\nTo include such deployments, it should not be required to use Availability Zones."}),"\n",(0,i.jsx)(n.p,{children:"Other physical factors that should be considered are the power supplies, internet connection, cooling and core routing.\nAvailability Zones were also used by CSPs as a representations of redundant PDUs.\nThat means there are deployments, which have Availability Zones per rack as each rack has it's own PDU and this was considered to be the single point of failure an AZ should represent.\nWhile this is also a possible measurement of independency it only provides failure safety for level 2.\nTherefore this standard should be very clear about which independency an AZ should represent and it should not be allowed to have different deployments with their Availability Zones representing different levels of failure safety."}),"\n",(0,i.jsx)(n.p,{children:"Additionally Availability Zones are available for Compute, Storage and Network services.\nThey behave differently for each of these resources and also when working across resource-based Availability Zones, e.g. attaching a volume from one AZ to a virtual machine in another AZ.\nFor each of these IaaS resource classes, it should be defined, under which circumstances Availability Zones should be used."}),"\n",(0,i.jsx)(n.h3,{id:"scope-of-the-availability-zone-standard",children:"Scope of the Availability Zone Standard"}),"\n",(0,i.jsxs)(n.p,{children:["When elaborating redundancy and failure safety in data centers, it is necessary to also define redundancy on the physical level.\nThere are already recommendations from the BSI for physical redundancy within a cloud deployment ",(0,i.jsx)(n.sup,{children:(0,i.jsx)(n.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),".\nThis standard considers these recommendation as a basis, that is followed by most CSPs.\nSo this standard will not go into details, already provided by the CSP, but will rather concentrate on the IaaS layer and only have a coarse view on the physical layer.\nThe first assumtion from the recommendations of the BSI is that the destruction of one fire zone will not lead to an outage of all power lines (not PDUs), internet connections, core routers or cooling systems."]}),"\n",(0,i.jsx)(n.p,{children:"For the setup of Availability Zone this means, that within every AZ, there needs to be redundancy in core routers, internet connection, power lines and at least two separate cooling systems.\nThis should avoid having single points of failure within the Availability Zones.\nBut all this physical infrastructure can be the same over all Availability Zones in a deployment, when it is possible to survive the destruction of one fire zone."}),"\n",(0,i.jsx)(n.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,i.jsx)(n.h4,{id:"physical-based-availability-zones",children:"Physical-based Availability Zones"}),"\n",(0,i.jsx)(n.p,{children:"It is possible standardize the usage of Availability Zones over all IaaS resources.\nThe downside from this is, that the IaaS resources behave so differently, that they have different requirements for redundancy and thus Availability Zones.\nThis is not the way to go.\nBesides that, it is already possible to create two physically separated deployments close to each other, connect them with each other and use regions to differ between the IaaS on both deployments."}),"\n",(0,i.jsx)(n.p,{children:"The question that remains is, what an Availability Zone should consist of?\nHaving one Availability Zone per fire zone gives the best level of failure safety, that can be achieved by CSPs.\nWhen building up on the relation between fire zone and physical redundancy recommendations as from the BSI, this combination is a good starting point, but need to be checked for the validity for the different IaaS resources."}),"\n",(0,i.jsx)(n.p,{children:"Another point is where Availability Zones can be instantiated and what the connection between AZs should look like.\nTo have a proper way to deal with outages of one AZ, where a second AZ can step in, a few requirements need to be met for the connection between those two AZs.\nThe amount data that needs to be transferred very fast in a failure case may be enormous, so there is a requirement for a high bandwidth between connected AZs.\nTho avoid additional failure cases the latency between those two Availability Zones need to be low.\nWith such requirements it is very clear that AZs should only reside within one (physical) region of an IaaS deployment."}),"\n",(0,i.jsx)(n.h4,{id:"azs-in-compute",children:"AZs in Compute"}),"\n",(0,i.jsx)(n.p,{children:"Compute Hosts are physical machines on which the compute service runs.\nA single virtual machine is always running on ONE compute host.\nRedundancy of virtual machines is either up to the layer above IaaS or up to the customers themself.\nHaving Availability Zones gives customers the possibility to let another virtual machine as a backup run within another Availability Zone."}),"\n",(0,i.jsx)(n.p,{children:"Customers will expect that in case of the failure of one Availability Zone all other AZs are still available.\nThe highest possible failure safety here is achieved, when Availability Zones for Compute are used for different fire zones."}),"\n",(0,i.jsx)(n.p,{children:"When the BSI recommendations are followed, there should already be redundancy in power lines, internet connection and cooling.\nAn outage of one of these physical resources will not affect the compute host and its resources for more than a minimal timeframe.\nBut when a single PDU is used for a rack, a failure of that PDU will result in an outage of all compute hosts in this rack.\nIn such a case it is not relevant, whether this rack represents a whole Availability Zone or is only part of a bigger AZ.\nAll virtual machines on the affected compute hosts will not be available and need to be restarted on other hosts, whether of the same Availability Zone or another."}),"\n",(0,i.jsx)(n.h4,{id:"azs-in-storage",children:"AZs in Storage"}),"\n",(0,i.jsx)(n.p,{children:"There are many different backends used for the storage service with Ceph being one of the most prominent backends.\nConfiguring those backends can already include to span one storage cluster over physical machines in different fire zones.\nIn combination with internal replication a configuration is possible, that already distributes replicas from volumes over different fire zones.\nWhen a deployment has such a configured storage backend, it already can provide safety in case of a failure of level 3."}),"\n",(0,i.jsx)(n.p,{children:"Using Availability Zones is also possible for the storage service, but configuring AZs, when having a configuration like above will not increase safety.\nNevertheless using AZs when having different backends in different fire zones will give customers a hint to backup volumes into storages of other AZs."}),"\n",(0,i.jsx)(n.p,{children:"Additionally when the BSI recommendations are followed, there should already be redundancy in power lines, internet connection and cooling.\nAn outage of one of these physical resources will not affect the storage host and its resources for more than a minimal timeframe.\nWhen internal replication is used, either through the IaaS or through the storage backend itself, the outage of a single PDU and such a single rack will not affect the availability of the data itself.\nAll these physical factors are not requiring the usage of an Availability Zone for Storage.\nAn increase of the level of failure safety will not be reached through AZs in these cases."}),"\n",(0,i.jsx)(n.p,{children:"Still it might be confusing when having deployments with compute AZs but without storage AZs.\nCSPs may need to communicate clearly up to which failure safety level their storage service can automatically have redundancy and from which level customers are responsible for the redundancy of their data."}),"\n",(0,i.jsx)(n.h4,{id:"azs-in-network",children:"AZs in Network"}),"\n",(0,i.jsx)(n.p,{children:"Virtualized network resources can typically be quickly and easily set up from building instructions.\nThose instructions are stored in the database of the networking service."}),"\n",(0,i.jsx)(n.p,{children:"If a physical machine, on which certain network resources are set up, is not available anymore, the resources can be rolled out on another physical machine, without being dependent on the current situation of the lost resources.\nThere might only be a loss of a few packets within the affected network resources."}),"\n",(0,i.jsxs)(n.p,{children:["With having Compute and Storage in a good state (e.g. through having fire zones with a compute AZ each and storage being replicated over the fire zones) there would be no downsides to omitting Availability Zones for the network service.\nIt might even be the opposite: Having resources running in certain Availability Zones might prevent them from being scheduled in other AZs",(0,i.jsx)(n.sup,{children:(0,i.jsx)(n.a,{href:"#user-content-fn-3",id:"user-content-fnref-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),".\nAs the network resources like routers are bound to an AZ, in a failure case of one AZ all resource definitions might still be there in the database, while the implementation of those resources is gone.\nTrying to rebuild them in another AZ is not possible, because the scheduler will not allow them to be implemented in another AZ, than the one thats present in their definition.\nIn a failure case of one AZ this might lead to a lot of manual work to rebuild the SDN from scratch instead of just re-using the definitions."]}),"\n",(0,i.jsx)(n.p,{children:"Because of this severe side effect, this standard will make no recommendations about Network AZs."}),"\n",(0,i.jsx)(n.h3,{id:"cross-attaching-volumes-from-one-az-to-another-compute-az",children:"Cross-Attaching volumes from one AZ to another compute AZ"}),"\n",(0,i.jsx)(n.p,{children:"Without the networking AZs we only need to take a closer look into attaching volumes to virtual machines across AZs."}),"\n",(0,i.jsx)(n.p,{children:"When there is more than one Storage Availability Zone, those AZs do normally align with the Compute Availability Zones.\nThis means that fire zone 1 contains compute AZ 1 and storage AZ 1 , fire zone 2 contains compute AZ 2 and storage AZ 2 and the same for fire zone 3.\nIt is possible to allow or forbid cross-attaching volumes from one storage Availability Zone to virtual machines in another AZ.\nIf it is not allowed, then the creation of volume-based virtual machines will fail, if there is no space left for VMs in the corresponding Availability Zone.\nWhile this may be unfortunate, it gives customers a very clear picture of an Availability Zone.\nIt clarifies that having a virtual machine in another AZ also requires having a backup or replication of volumes in the other storage AZ.\nThen this backup or replication can be used to create a new virtual machine in the other AZ."}),"\n",(0,i.jsx)(n.p,{children:"It seems to be a good decision to not encourage CSPs to allow cross-attach.\nCurrently CSPs also do not seem to widely use it."}),"\n",(0,i.jsx)(n.h2,{id:"standard",children:"Standard"}),"\n",(0,i.jsx)(n.p,{children:"If Compute Availability Zones are used, they MUST be in different fire zones.\nAvailabilty Zones for Storage SHOULD be setup, if there is no storage backend used that can span over different fire zones and automatically replicate the data.\nOtherwise a single Availabilty Zone for Storage SHOULD be configured."}),"\n",(0,i.jsx)(n.p,{children:"If more than one Availability Zone for Storage is set up, the attaching of volumes from one Storage Availability Zone to another Compute Availability Zone (cross-attach) SHOULD NOT be possible."}),"\n",(0,i.jsx)(n.p,{children:"Within each Availability Zone:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"there MUST be redundancy in power supply, as in line into the deployment"}),"\n",(0,i.jsx)(n.li,{children:"there MUST be redundancy in external connection (e.g. internet connection or WAN-connection)"}),"\n",(0,i.jsx)(n.li,{children:"there MUST be redundancy in core routers"}),"\n",(0,i.jsx)(n.li,{children:"there SHOULD be redundancy in the cooling system"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"AZs SHOULD only occur within the same region and have a low-latency interconnection with a high bandwidth."}),"\n",(0,i.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,i.jsx)(n.p,{children:"The taxonomy of failsafe levels can be used to get an overview over the levels of failure safety in a deployment(TODO: link after DR is merged.)"}),"\n",(0,i.jsxs)(n.p,{children:["The BSI can be consulted for further information about ",(0,i.jsx)(n.a,{href:"https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/IT-Grundschutz-Kompendium/Elementare-Gefaehrdungen/elementare-gefaehrdungen_node.html",children:"failure risks"}),", ",(0,i.jsx)(n.a,{href:"https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Grundschutz/BSI_Standards/standard_200_3.pdf?__blob=publicationFile&v=2",children:"risk analysis for a datacenter"})," or ",(0,i.jsx)(n.a,{href:"https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/RZ-Sicherheit/RZ-Verfuegbarkeitsmassnahmen.pdf?__blob=publicationFile&v=9",children:"measures for availability"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,i.jsx)(n.p,{children:"As this standard will not require Availability Zones to be present, we cannot automatically test the conformance.\nThe other parts of the standard are physical or internal and could only be tested through an audit.\nWhether there are fire zones physically available is a criteria that will never change for a single deployment - this only needs to be audited once.\nIt might be possible to also use Gaia-X Credentials to provide such information, which then could be tested."}),"\n","\n",(0,i.jsxs)(n.section,{"data-footnotes":!0,className:"footnotes",children:[(0,i.jsx)(n.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{id:"user-content-fn-1",children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/pull/579",children:"Taxonomy of Failsafe Levels in SCS (TODO: change link as soon as taxonomy is merged)"})," ",(0,i.jsx)(n.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})," ",(0,i.jsxs)(n.a,{href:"#user-content-fnref-1-2","data-footnote-backref":"","aria-label":"Back to reference 1-2",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(n.sup,{children:"2"})]})," ",(0,i.jsxs)(n.a,{href:"#user-content-fnref-1-3","data-footnote-backref":"","aria-label":"Back to reference 1-3",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(n.sup,{children:"3"})]})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{id:"user-content-fn-2",children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/RZ-Sicherheit/RZ-Verfuegbarkeitsmassnahmen.pdf?__blob=publicationFile&v=9",children:"Availability recommendations from the BSI"})," ",(0,i.jsx)(n.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{id:"user-content-fn-3",children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://docs.openstack.org/neutron/latest/admin/ovn/availability_zones.html",children:"Availability Zones in Neutron for OVN"})," ",(0,i.jsx)(n.a,{href:"#user-content-fnref-3","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>r});var a=t(96540);const i={},o=a.createContext(i);function s(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0f0de498.9b49c638.js b/assets/js/0f0de498.9b49c638.js new file mode 100644 index 0000000000..3a2c3c08b5 --- /dev/null +++ b/assets/js/0f0de498.9b49c638.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[75013],{30859:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>g,frontMatter:()=>o,metadata:()=>i,toc:()=>r});const i=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/designate","title":"Designate","description":"* Designate admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/designate.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/designate","permalink":"/docs/iaas/guides/configuration-guide/openstack/designate","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/designate.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Designate"},"sidebar":"docs","previous":{"title":"Cinder","permalink":"/docs/iaas/guides/configuration-guide/openstack/cinder"},"next":{"title":"Glance","permalink":"/docs/iaas/guides/configuration-guide/openstack/glance"}}');var s=t(74848),a=t(28453);const o={sidebar_label:"Designate"},c="Designate",d={},r=[];function u(e){const n={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"designate",children:"Designate"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/designate/latest/admin/index.html",children:"Designate admin guide"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/designate/latest/configuration/index.html",children:"Designate configuration guide"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/designate/latest/admin/config.html",children:"Designate configuration reference"})}),"\n"]})]})}function g(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var i=t(96540);const s={},a=i.createContext(s);function o(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0f1ad89c.1bb16bc8.js b/assets/js/0f1ad89c.1bb16bc8.js new file mode 100644 index 0000000000..4764e57184 --- /dev/null +++ b/assets/js/0f1ad89c.1bb16bc8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[46347],{9801:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>l,frontMatter:()=>c,metadata:()=>s,toc:()=>a});const s=JSON.parse('{"id":"operating-scs/components/status-page-deployment/docs/requirements","title":"Requirements","description":"The requirements are specific for the relevant environment.","source":"@site/docs/04-operating-scs/components/status-page-deployment/docs/requirements.md","sourceDirName":"04-operating-scs/components/status-page-deployment/docs","slug":"/operating-scs/components/status-page-deployment/docs/requirements","permalink":"/docs/operating-scs/components/status-page-deployment/docs/requirements","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-deployment/docs/requirements.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/operating-scs/components/status-page-deployment/docs/overview"},"next":{"title":"Quickstart","permalink":"/docs/operating-scs/components/status-page-deployment/docs/quickstart"}}');var o=n(74848),r=n(28453);const c={},i="Requirements",d={},a=[];function p(e){const t={code:"code",h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"requirements",children:"Requirements"})}),"\n",(0,o.jsx)(t.p,{children:"The requirements are specific for the relevant environment."}),"\n",(0,o.jsxs)(t.p,{children:["In general a running k8s cluster is needed, as well as tooling to interface with the given cluster, e.g. ",(0,o.jsx)(t.code,{children:"kubectl"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["For a local development cluster ",(0,o.jsx)(t.code,{children:"KinD"}),", ",(0,o.jsx)(t.code,{children:"minikube"})," or similar can be used. ",(0,o.jsx)(t.code,{children:"KinD"})," is the currently tested method."]}),"\n",(0,o.jsxs)(t.p,{children:["For a single machine deployment ",(0,o.jsx)(t.code,{children:"k3s"})," is the currently recommended method."]}),"\n",(0,o.jsx)(t.p,{children:"A production deployment needs a production ready k8s cluster, in which ever form is deemed practical."}),"\n",(0,o.jsx)(t.p,{children:"Please refer to the used method of deployment for more specific information about setup and requirements."})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var s=n(96540);const o={},r=s.createContext(o);function c(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0fd39870.3c6f1821.js b/assets/js/0fd39870.3c6f1821.js new file mode 100644 index 0000000000..7a0198f93c --- /dev/null +++ b/assets/js/0fd39870.3c6f1821.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[42140],{86062:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>d,metadata:()=>t,toc:()=>r});const t=JSON.parse('{"id":"operating-scs/components/status-page-api/docs/requests","title":"Requests","description":"As defined by the OpenAPI spec and status page OpenAPI decision the general API objects are used as request bodies and responses to generalize data structures. Not all object fields are handled by all requests, some are read only and some are write only. GET request wrap their return in a object field called data.","source":"@site/docs/04-operating-scs/components/status-page-api/docs/requests.md","sourceDirName":"04-operating-scs/components/status-page-api/docs","slug":"/operating-scs/components/status-page-api/docs/requests","permalink":"/docs/operating-scs/components/status-page-api/docs/requests","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-api/docs/requests.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Configuration","permalink":"/docs/operating-scs/components/status-page-api/docs/configuration"},"next":{"title":"Example requests","permalink":"/docs/operating-scs/components/status-page-api/docs/example-requests"}}');var a=s(74848),i=s(28453);const d={},o="Requests",c={},r=[{value:"Phases",id:"phases",level:2},{value:"Impact types",id:"impact-types",level:2},{value:"Severities",id:"severities",level:2},{value:"Components",id:"components",level:2},{value:"Incidents",id:"incidents",level:2},{value:"Incident update",id:"incident-update",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"requests",children:"Requests"})}),"\n",(0,a.jsxs)(n.p,{children:["As defined by the ",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi",children:"OpenAPI spec"})," and ",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0402-v1-status-page-openapi-spec-decision.md",children:"status page OpenAPI decision"})," the general API objects are used as request bodies and responses to generalize data structures. Not all object fields are handled by all requests, some are read only and some are write only. ",(0,a.jsx)(n.code,{children:"GET"})," request wrap their return in a object field called ",(0,a.jsx)(n.code,{children:"data"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Please refer to ",(0,a.jsx)(n.a,{href:"/docs/operating-scs/components/status-page-api/docs/example-requests",children:"example requests"})," to see these request in action."]}),"\n",(0,a.jsx)(n.h2,{id:"phases",children:"Phases"}),"\n",(0,a.jsxs)(n.p,{children:["Phases are always handled as lists, so ",(0,a.jsx)(n.code,{children:"GET"})," as well as ",(0,a.jsx)(n.code,{children:"POST"})," operations on phases always require the full list. When getting the phase list, it's accompanied be a generation annotation."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json5",children:'{\n "generation": 1, // omitted on POST and PATCH\n "phases": [\n "Phase 1",\n "Phase 2",\n "Pahse 3"\n ]\n}\n'})}),"\n",(0,a.jsx)(n.h2,{id:"impact-types",children:"Impact types"}),"\n",(0,a.jsxs)(n.p,{children:["Requesting (",(0,a.jsx)(n.code,{children:"GET"}),") an impact type, will return all fields, while ",(0,a.jsx)(n.code,{children:"POST"})," and ",(0,a.jsx)(n.code,{children:"PATCH"})," operations omit the ",(0,a.jsx)(n.code,{children:"id"})," field."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json5",children:'{\n "id": "UUID", // omit on POST and PATCH\n "description": "Description of the impact type.",\n "displayName": "Name"\n}\n'})}),"\n",(0,a.jsx)(n.h2,{id:"severities",children:"Severities"}),"\n",(0,a.jsxs)(n.p,{children:["For all request types (",(0,a.jsx)(n.code,{children:"GET"}),", ",(0,a.jsx)(n.code,{children:"POST"}),", ",(0,a.jsx)(n.code,{children:"PATCH"}),"), all fields of the severity are handled."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "displayName": "string",\n "value": 100\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:["As ",(0,a.jsx)(n.code,{children:"displayName"})," is the identifier it must be unique, even when modified by ",(0,a.jsx)(n.code,{children:"PATCH"})]}),"\n",(0,a.jsx)(n.h2,{id:"components",children:"Components"}),"\n",(0,a.jsxs)(n.p,{children:["When ",(0,a.jsx)(n.code,{children:"GET"}),"ing a component, all fields can be expected to be filled, while requests for ",(0,a.jsx)(n.code,{children:"POST"})," (creation) and ",(0,a.jsx)(n.code,{children:"PATCH"})," operations only handle certain fields."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json5",children:'{\n "id": "UUID", // omitted on POST and PATCH\n "activelyAffectedBy": [ // omitted on POST and PATCH\n {\n "reference": "Incident-UUID",\n "severity": 100,\n "type": "ImpactType-UUID"\n }\n ],\n "displayName": "Name",\n "labels": {\n "key": "value",\n }\n}\n'})}),"\n",(0,a.jsx)(n.h2,{id:"incidents",children:"Incidents"}),"\n",(0,a.jsx)(n.p,{children:"It is expected that incidents are the most used API object and have the most data to transmit."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json5",children:'{\n "id": "UUID", // omitted on POST and PATCH\n "affects": [\n {\n "reference": "Component-UUID",\n "severity": 100,\n "type": "ImpactType-UUID"\n }\n ],\n "beganAt": "2024-01-01T06:00:00.000Z",\n "description": "Description of the incident.",\n "displayName": "Name",\n "endedAt": "2024-01-01T08:00:00.000Z", // or null, when incident is still ongoing.\n "phase": {\n "generation": 1,\n "order": 1\n },\n "updates": [ // omitted on POST and PATCH\n 0,\n 1,\n 2\n ]\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"affects"})," field can, in theory, have as many entries as there are components. The ",(0,a.jsx)(n.code,{children:"updates"})," field is an ongoing list of updates. All changes to ",(0,a.jsx)(n.code,{children:"phase"})," should correlate to an update."]}),"\n",(0,a.jsxs)(n.p,{children:["When performing ",(0,a.jsx)(n.code,{children:"POST"})," or ",(0,a.jsx)(n.code,{children:"PATCH"})," operations on incidents the ",(0,a.jsx)(n.code,{children:"affects"})," field is of utmost importance, as it creates the ",(0,a.jsx)(n.strong,{children:"impact"}),". Only when referencing a component to an incident via the ",(0,a.jsx)(n.code,{children:"affects"})," field, an impact is created, that can be retrieved via the affected component."]}),"\n",(0,a.jsx)(n.h2,{id:"incident-update",children:"Incident update"}),"\n",(0,a.jsxs)(n.p,{children:["Whenever an incident changes, an update should be issued. When doing a ",(0,a.jsx)(n.code,{children:"GET"})," request, the ",(0,a.jsx)(n.code,{children:"order"})," field is filled, updates should be displayed in ascending order."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json5",children:'{\n "order": 0, // omitted on POST and PATCH\n "createdAt": "2024-01-01T06:15:00.000Z",\n "description": "Description of the update.",\n "displayName": "Name"\n}\n'})})]})}function p(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>o});var t=s(96540);const a={},i=t.createContext(a);function d(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/10711.74e33c32.js b/assets/js/10711.74e33c32.js new file mode 100644 index 0000000000..f703d7ee34 --- /dev/null +++ b/assets/js/10711.74e33c32.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[10711],{10711:(t,e,r)=>{r.d(e,{diagram:()=>D});var i=r(86079),a=r(697),n=r(26312),s=r(21176);const o=[];for(let S=0;S<256;++S)o.push((S+256).toString(16).slice(1));function c(t,e=0){return o[t[e+0]]+o[t[e+1]]+o[t[e+2]]+o[t[e+3]]+"-"+o[t[e+4]]+o[t[e+5]]+"-"+o[t[e+6]]+o[t[e+7]]+"-"+o[t[e+8]]+o[t[e+9]]+"-"+o[t[e+10]]+o[t[e+11]]+o[t[e+12]]+o[t[e+13]]+o[t[e+14]]+o[t[e+15]]}const l=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;const h=function(t){return"string"==typeof t&&l.test(t)};const d=function(t){if(!h(t))throw TypeError("Invalid UUID");let e;const r=new Uint8Array(16);return r[0]=(e=parseInt(t.slice(0,8),16))>>>24,r[1]=e>>>16&255,r[2]=e>>>8&255,r[3]=255&e,r[4]=(e=parseInt(t.slice(9,13),16))>>>8,r[5]=255&e,r[6]=(e=parseInt(t.slice(14,18),16))>>>8,r[7]=255&e,r[8]=(e=parseInt(t.slice(19,23),16))>>>8,r[9]=255&e,r[10]=(e=parseInt(t.slice(24,36),16))/1099511627776&255,r[11]=e/4294967296&255,r[12]=e>>>24&255,r[13]=e>>>16&255,r[14]=e>>>8&255,r[15]=255&e,r};function y(t,e,r,i){switch(t){case 0:return e&r^~e&i;case 1:case 3:return e^r^i;case 2:return e&r^e&i^r&i}}function u(t,e){return t<>>32-e}const p=function(t,e,r){function i(t,i,a,n){var s;if("string"==typeof t&&(t=function(t){t=unescape(encodeURIComponent(t));const e=[];for(let r=0;r>>0;l=c,c=o,o=u(a,30)>>>0,a=i,i=s}r[0]=r[0]+i>>>0,r[1]=r[1]+a>>>0,r[2]=r[2]+o>>>0,r[3]=r[3]+c>>>0,r[4]=r[4]+l>>>0}return[r[0]>>24&255,r[0]>>16&255,r[0]>>8&255,255&r[0],r[1]>>24&255,r[1]>>16&255,r[1]>>8&255,255&r[1],r[2]>>24&255,r[2]>>16&255,r[2]>>8&255,255&r[2],r[3]>>24&255,r[3]>>16&255,r[3]>>8&255,255&r[3],r[4]>>24&255,r[4]>>16&255,r[4]>>8&255,255&r[4]]}));r(74353),r(16750),r(42838);var _=function(){var t=function(t,e,r,i){for(r=r||{},i=t.length;i--;r[t[i]]=e);return r},e=[6,8,10,20,22,24,26,27,28],r=[1,10],i=[1,11],a=[1,12],n=[1,13],s=[1,14],o=[1,15],c=[1,21],l=[1,22],h=[1,23],d=[1,24],y=[1,25],u=[6,8,10,13,15,18,19,20,22,24,26,27,28,41,42,43,44,45],p=[1,34],_=[27,28,46,47],f=[41,42,43,44,45],m=[17,34],E=[1,54],g=[1,53],O=[17,34,36,38],b={trace:function(){},yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,entityName:11,relSpec:12,":":13,role:14,BLOCK_START:15,attributes:16,BLOCK_STOP:17,SQS:18,SQE:19,title:20,title_value:21,acc_title:22,acc_title_value:23,acc_descr:24,acc_descr_value:25,acc_descr_multiline_value:26,ALPHANUM:27,ENTITY_NAME:28,attribute:29,attributeType:30,attributeName:31,attributeKeyTypeList:32,attributeComment:33,ATTRIBUTE_WORD:34,attributeKeyType:35,COMMA:36,ATTRIBUTE_KEY:37,COMMENT:38,cardinality:39,relType:40,ZERO_OR_ONE:41,ZERO_OR_MORE:42,ONE_OR_MORE:43,ONLY_ONE:44,MD_PARENT:45,NON_IDENTIFYING:46,IDENTIFYING:47,WORD:48,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:":",15:"BLOCK_START",17:"BLOCK_STOP",18:"SQS",19:"SQE",20:"title",21:"title_value",22:"acc_title",23:"acc_title_value",24:"acc_descr",25:"acc_descr_value",26:"acc_descr_multiline_value",27:"ALPHANUM",28:"ENTITY_NAME",34:"ATTRIBUTE_WORD",36:"COMMA",37:"ATTRIBUTE_KEY",38:"COMMENT",41:"ZERO_OR_ONE",42:"ZERO_OR_MORE",43:"ONE_OR_MORE",44:"ONLY_ONE",45:"MD_PARENT",46:"NON_IDENTIFYING",47:"IDENTIFYING",48:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,4],[9,3],[9,1],[9,7],[9,6],[9,4],[9,2],[9,2],[9,2],[9,1],[11,1],[11,1],[16,1],[16,2],[29,2],[29,3],[29,3],[29,4],[30,1],[31,1],[32,1],[32,3],[35,1],[33,1],[12,3],[39,1],[39,1],[39,1],[39,1],[39,1],[40,1],[40,1],[14,1],[14,1],[14,1]],performAction:function(t,e,r,i,a,n,s){var o=n.length-1;switch(a){case 1:break;case 2:case 6:case 7:this.$=[];break;case 3:n[o-1].push(n[o]),this.$=n[o-1];break;case 4:case 5:case 19:case 43:case 27:case 28:case 31:this.$=n[o];break;case 8:i.addEntity(n[o-4]),i.addEntity(n[o-2]),i.addRelationship(n[o-4],n[o],n[o-2],n[o-3]);break;case 9:i.addEntity(n[o-3]),i.addAttributes(n[o-3],n[o-1]);break;case 10:i.addEntity(n[o-2]);break;case 11:i.addEntity(n[o]);break;case 12:i.addEntity(n[o-6],n[o-4]),i.addAttributes(n[o-6],n[o-1]);break;case 13:i.addEntity(n[o-5],n[o-3]);break;case 14:i.addEntity(n[o-3],n[o-1]);break;case 15:case 16:this.$=n[o].trim(),i.setAccTitle(this.$);break;case 17:case 18:this.$=n[o].trim(),i.setAccDescription(this.$);break;case 20:case 41:case 42:case 32:this.$=n[o].replace(/"/g,"");break;case 21:case 29:this.$=[n[o]];break;case 22:n[o].push(n[o-1]),this.$=n[o];break;case 23:this.$={attributeType:n[o-1],attributeName:n[o]};break;case 24:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeKeyTypeList:n[o]};break;case 25:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeComment:n[o]};break;case 26:this.$={attributeType:n[o-3],attributeName:n[o-2],attributeKeyTypeList:n[o-1],attributeComment:n[o]};break;case 30:n[o-2].push(n[o]),this.$=n[o-2];break;case 33:this.$={cardA:n[o],relType:n[o-1],cardB:n[o-2]};break;case 34:this.$=i.Cardinality.ZERO_OR_ONE;break;case 35:this.$=i.Cardinality.ZERO_OR_MORE;break;case 36:this.$=i.Cardinality.ONE_OR_MORE;break;case 37:this.$=i.Cardinality.ONLY_ONE;break;case 38:this.$=i.Cardinality.MD_PARENT;break;case 39:this.$=i.Identification.NON_IDENTIFYING;break;case 40:this.$=i.Identification.IDENTIFYING}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,20:r,22:i,24:a,26:n,27:s,28:o},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:16,11:9,20:r,22:i,24:a,26:n,27:s,28:o},t(e,[2,5]),t(e,[2,6]),t(e,[2,11],{12:17,39:20,15:[1,18],18:[1,19],41:c,42:l,43:h,44:d,45:y}),{21:[1,26]},{23:[1,27]},{25:[1,28]},t(e,[2,18]),t(u,[2,19]),t(u,[2,20]),t(e,[2,4]),{11:29,27:s,28:o},{16:30,17:[1,31],29:32,30:33,34:p},{11:35,27:s,28:o},{40:36,46:[1,37],47:[1,38]},t(_,[2,34]),t(_,[2,35]),t(_,[2,36]),t(_,[2,37]),t(_,[2,38]),t(e,[2,15]),t(e,[2,16]),t(e,[2,17]),{13:[1,39]},{17:[1,40]},t(e,[2,10]),{16:41,17:[2,21],29:32,30:33,34:p},{31:42,34:[1,43]},{34:[2,27]},{19:[1,44]},{39:45,41:c,42:l,43:h,44:d,45:y},t(f,[2,39]),t(f,[2,40]),{14:46,27:[1,49],28:[1,48],48:[1,47]},t(e,[2,9]),{17:[2,22]},t(m,[2,23],{32:50,33:51,35:52,37:E,38:g}),t([17,34,37,38],[2,28]),t(e,[2,14],{15:[1,55]}),t([27,28],[2,33]),t(e,[2,8]),t(e,[2,41]),t(e,[2,42]),t(e,[2,43]),t(m,[2,24],{33:56,36:[1,57],38:g}),t(m,[2,25]),t(O,[2,29]),t(m,[2,32]),t(O,[2,31]),{16:58,17:[1,59],29:32,30:33,34:p},t(m,[2,26]),{35:60,37:E},{17:[1,61]},t(e,[2,13]),t(O,[2,30]),t(e,[2,12])],defaultActions:{34:[2,27],41:[2,22]},parseError:function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},parse:function(t){var e=this,r=[0],i=[],a=[null],n=[],s=this.table,o="",c=0,l=0,h=n.slice.call(arguments,1),d=Object.create(this.lexer),y={yy:{}};for(var u in this.yy)Object.prototype.hasOwnProperty.call(this.yy,u)&&(y.yy[u]=this.yy[u]);d.setInput(t,y.yy),y.yy.lexer=d,y.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var p=d.yylloc;n.push(p);var _=d.options&&d.options.ranges;"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,m,E,g,O,b,k,R,N,T={};;){if(m=r[r.length-1],this.defaultActions[m]?E=this.defaultActions[m]:(null==f&&(N=void 0,"number"!=typeof(N=i.pop()||d.lex()||1)&&(N instanceof Array&&(N=(i=N).pop()),N=e.symbols_[N]||N),f=N),E=s[m]&&s[m][f]),void 0===E||!E.length||!E[0]){var x="";for(O in R=[],s[m])this.terminals_[O]&&O>2&&R.push("'"+this.terminals_[O]+"'");x=d.showPosition?"Parse error on line "+(c+1)+":\n"+d.showPosition()+"\nExpecting "+R.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(x,{text:d.match,token:this.terminals_[f]||f,line:d.yylineno,loc:p,expected:R})}if(E[0]instanceof Array&&E.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+f);switch(E[0]){case 1:r.push(f),a.push(d.yytext),n.push(d.yylloc),r.push(E[1]),f=null,l=d.yyleng,o=d.yytext,c=d.yylineno,p=d.yylloc;break;case 2:if(b=this.productions_[E[1]][1],T.$=a[a.length-b],T._$={first_line:n[n.length-(b||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(b||1)].first_column,last_column:n[n.length-1].last_column},_&&(T._$.range=[n[n.length-(b||1)].range[0],n[n.length-1].range[1]]),void 0!==(g=this.performAction.apply(T,[o,l,c,y.yy,E[1],a,n].concat(h))))return g;b&&(r=r.slice(0,-1*b*2),a=a.slice(0,-1*b),n=n.slice(0,-1*b)),r.push(this.productions_[E[1]][0]),a.push(T.$),n.push(T._$),k=s[r[r.length-2]][r[r.length-1]],r.push(k);break;case 3:return!0}}return!0}},k={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,r=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var a=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===i.length?this.yylloc.first_column:0)+i[i.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var r,i,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var n in a)this[n]=a[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,r,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),n=0;ne[0].length)){if(e=r,i=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,a[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,a[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,r,i){switch(r){case 0:return this.begin("acc_title"),22;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),24;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 10;case 8:case 15:case 20:break;case 9:return 8;case 10:return 28;case 11:return 48;case 12:return 4;case 13:return this.begin("block"),15;case 14:return 36;case 16:return 37;case 17:case 18:return 34;case 19:return 38;case 21:return this.popState(),17;case 22:case 54:return e.yytext[0];case 23:return 18;case 24:return 19;case 25:case 29:case 30:case 43:return 41;case 26:case 27:case 28:case 36:case 38:case 45:return 43;case 31:case 32:case 33:case 34:case 35:case 37:case 44:return 42;case 39:case 40:case 41:case 42:return 44;case 46:return 45;case 47:case 50:case 51:case 52:return 46;case 48:case 49:return 47;case 53:return 27;case 55:return 6}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:,)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i,/^(?:(.*?)[~](.*?)*[~])/i,/^(?:[\*A-Za-z_][A-Za-z0-9\-_\[\]\(\)]*)/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:one or zero\b)/i,/^(?:one or more\b)/i,/^(?:one or many\b)/i,/^(?:1\+)/i,/^(?:\|o\b)/i,/^(?:zero or one\b)/i,/^(?:zero or more\b)/i,/^(?:zero or many\b)/i,/^(?:0\+)/i,/^(?:\}o\b)/i,/^(?:many\(0\))/i,/^(?:many\(1\))/i,/^(?:many\b)/i,/^(?:\}\|)/i,/^(?:one\b)/i,/^(?:only one\b)/i,/^(?:1\b)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\s*u\b)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:to\b)/i,/^(?:optionally to\b)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:[A-Za-z_][A-Za-z0-9\-_]*)/i,/^(?:.)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},block:{rules:[14,15,16,17,18,19,20,21,22],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55],inclusive:!0}}};function R(){this.yy={}}return b.lexer=k,R.prototype=b,b.Parser=R,new R}();_.parser=_;const f=_;let m={},E=[];const g=function(t,e=void 0){return void 0===m[t]?(m[t]={attributes:[],alias:e},i.l.info("Added new entity :",t)):m[t]&&!m[t].alias&&e&&(m[t].alias=e,i.l.info(`Add alias '${e}' to entity '${t}'`)),m[t]},O={Cardinality:{ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE",MD_PARENT:"MD_PARENT"},Identification:{NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"},getConfig:()=>(0,i.c)().er,addEntity:g,addAttributes:function(t,e){let r,a=g(t);for(r=e.length-1;r>=0;r--)a.attributes.push(e[r]),i.l.debug("Added attribute ",e[r].attributeName)},getEntities:()=>m,addRelationship:function(t,e,r,a){let n={entityA:t,roleA:e,entityB:r,relSpec:a};E.push(n),i.l.debug("Added new relationship :",n)},getRelationships:()=>E,clear:function(){m={},E=[],(0,i.v)()},setAccTitle:i.s,getAccTitle:i.g,setAccDescription:i.b,getAccDescription:i.a,setDiagramTitle:i.q,getDiagramTitle:i.t},b={ONLY_ONE_START:"ONLY_ONE_START",ONLY_ONE_END:"ONLY_ONE_END",ZERO_OR_ONE_START:"ZERO_OR_ONE_START",ZERO_OR_ONE_END:"ZERO_OR_ONE_END",ONE_OR_MORE_START:"ONE_OR_MORE_START",ONE_OR_MORE_END:"ONE_OR_MORE_END",ZERO_OR_MORE_START:"ZERO_OR_MORE_START",ZERO_OR_MORE_END:"ZERO_OR_MORE_END",MD_PARENT_END:"MD_PARENT_END",MD_PARENT_START:"MD_PARENT_START"},k=b,R=function(t,e){let r;t.append("defs").append("marker").attr("id",b.MD_PARENT_START).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",b.MD_PARENT_END).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",b.ONLY_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",b.ONLY_ONE_END).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,0 L3,18 M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",b.ZERO_OR_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",b.ZERO_OR_ONE_END).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,0 L21,18"),t.append("defs").append("marker").attr("id",b.ONE_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",b.ONE_OR_MORE_END).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18"),r=t.append("defs").append("marker").attr("id",b.ZERO_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18"),r=t.append("defs").append("marker").attr("id",b.ZERO_OR_MORE_END).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")},N=/[^\dA-Za-z](\W)*/g;let T={},x=new Map;const A=function(t,e,r){let a;return Object.keys(e).forEach((function(n){const s=function(t="",e=""){const r=t.replace(N,"");return`${v(e)}${v(r)}${p(t,I)}`}(n,"entity");x.set(n,s);const o=t.append("g").attr("id",s);a=void 0===a?s:a;const c="text-"+s,l=o.append("text").classed("er entityLabel",!0).attr("id",c).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","middle").style("font-family",(0,i.c)().fontFamily).style("font-size",T.fontSize+"px").text(e[n].alias??n),{width:h,height:d}=((t,e,r)=>{const a=T.entityPadding/3,n=T.entityPadding/3,s=.85*T.fontSize,o=e.node().getBBox(),c=[];let l=!1,h=!1,d=0,y=0,u=0,p=0,_=o.height+2*a,f=1;r.forEach((t=>{void 0!==t.attributeKeyTypeList&&t.attributeKeyTypeList.length>0&&(l=!0),void 0!==t.attributeComment&&(h=!0)})),r.forEach((r=>{const n=`${e.node().id}-attr-${f}`;let o=0;const m=(0,i.x)(r.attributeType),E=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-type`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(m),g=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-name`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(r.attributeName),O={};O.tn=E,O.nn=g;const b=E.node().getBBox(),k=g.node().getBBox();if(d=Math.max(d,b.width),y=Math.max(y,k.width),o=Math.max(b.height,k.height),l){const e=void 0!==r.attributeKeyTypeList?r.attributeKeyTypeList.join(","):"",a=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-key`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(e);O.kn=a;const c=a.node().getBBox();u=Math.max(u,c.width),o=Math.max(o,c.height)}if(h){const e=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-comment`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(r.attributeComment||"");O.cn=e;const a=e.node().getBBox();p=Math.max(p,a.width),o=Math.max(o,a.height)}O.height=o,c.push(O),_+=o+2*a,f+=1}));let m=4;l&&(m+=2),h&&(m+=2);const E=d+y+u+p,g={width:Math.max(T.minEntityWidth,Math.max(o.width+2*T.entityPadding,E+n*m)),height:r.length>0?_:Math.max(T.minEntityHeight,o.height+2*T.entityPadding)};if(r.length>0){const r=Math.max(0,(g.width-E-n*m)/(m/2));e.attr("transform","translate("+g.width/2+","+(a+o.height/2)+")");let i=o.height+2*a,s="attributeBoxOdd";c.forEach((e=>{const o=i+a+e.height/2;e.tn.attr("transform","translate("+n+","+o+")");const c=t.insert("rect","#"+e.tn.node().id).classed(`er ${s}`,!0).attr("x",0).attr("y",i).attr("width",d+2*n+r).attr("height",e.height+2*a),_=parseFloat(c.attr("x"))+parseFloat(c.attr("width"));e.nn.attr("transform","translate("+(_+n)+","+o+")");const f=t.insert("rect","#"+e.nn.node().id).classed(`er ${s}`,!0).attr("x",_).attr("y",i).attr("width",y+2*n+r).attr("height",e.height+2*a);let m=parseFloat(f.attr("x"))+parseFloat(f.attr("width"));if(l){e.kn.attr("transform","translate("+(m+n)+","+o+")");const c=t.insert("rect","#"+e.kn.node().id).classed(`er ${s}`,!0).attr("x",m).attr("y",i).attr("width",u+2*n+r).attr("height",e.height+2*a);m=parseFloat(c.attr("x"))+parseFloat(c.attr("width"))}h&&(e.cn.attr("transform","translate("+(m+n)+","+o+")"),t.insert("rect","#"+e.cn.node().id).classed(`er ${s}`,"true").attr("x",m).attr("y",i).attr("width",p+2*n+r).attr("height",e.height+2*a)),i+=e.height+2*a,s="attributeBoxOdd"===s?"attributeBoxEven":"attributeBoxOdd"}))}else g.height=Math.max(T.minEntityHeight,_),e.attr("transform","translate("+g.width/2+","+g.height/2+")");return g})(o,l,e[n].attributes),y=o.insert("rect","#"+c).classed("er entityBox",!0).attr("x",0).attr("y",0).attr("width",h).attr("height",d).node().getBBox();r.setNode(s,{width:y.width,height:y.height,shape:"rect",id:s})})),a},M=function(t){return(t.entityA+t.roleA+t.entityB).replace(/\s/g,"")};let w=0;const I="28e9f9db-3c8d-5aa5-9faf-44286ae5937c";function v(t=""){return t.length>0?`${t}-`:""}const D={parser:f,db:O,renderer:{setConf:function(t){const e=Object.keys(t);for(const r of e)T[r]=t[r]},draw:function(t,e,r,o){T=(0,i.c)().er,i.l.info("Drawing ER diagram");const c=(0,i.c)().securityLevel;let l;"sandbox"===c&&(l=(0,n.Ltv)("#i"+e));const h=("sandbox"===c?(0,n.Ltv)(l.nodes()[0].contentDocument.body):(0,n.Ltv)("body")).select(`[id='${e}']`);let d;R(h,T),d=new a.T({multigraph:!0,directed:!0,compound:!1}).setGraph({rankdir:T.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));const y=A(h,o.db.getEntities(),d),u=function(t,e){return t.forEach((function(t){e.setEdge(x.get(t.entityA),x.get(t.entityB),{relationship:t},M(t))})),t}(o.db.getRelationships(),d);var p,_;(0,s.Zp)(d),p=h,(_=d).nodes().forEach((function(t){void 0!==t&&void 0!==_.node(t)&&p.select("#"+t).attr("transform","translate("+(_.node(t).x-_.node(t).width/2)+","+(_.node(t).y-_.node(t).height/2)+" )")})),u.forEach((function(t){!function(t,e,r,a,s){w++;const o=r.edge(x.get(e.entityA),x.get(e.entityB),M(e)),c=(0,n.n8j)().x((function(t){return t.x})).y((function(t){return t.y})).curve(n.qrM),l=t.insert("path","#"+a).classed("er relationshipLine",!0).attr("d",c(o.points)).style("stroke",T.stroke).style("fill","none");e.relSpec.relType===s.db.Identification.NON_IDENTIFYING&&l.attr("stroke-dasharray","8,8");let h="";switch(T.arrowMarkerAbsolute&&(h=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,h=h.replace(/\(/g,"\\("),h=h.replace(/\)/g,"\\)")),e.relSpec.cardA){case s.db.Cardinality.ZERO_OR_ONE:l.attr("marker-end","url("+h+"#"+k.ZERO_OR_ONE_END+")");break;case s.db.Cardinality.ZERO_OR_MORE:l.attr("marker-end","url("+h+"#"+k.ZERO_OR_MORE_END+")");break;case s.db.Cardinality.ONE_OR_MORE:l.attr("marker-end","url("+h+"#"+k.ONE_OR_MORE_END+")");break;case s.db.Cardinality.ONLY_ONE:l.attr("marker-end","url("+h+"#"+k.ONLY_ONE_END+")");break;case s.db.Cardinality.MD_PARENT:l.attr("marker-end","url("+h+"#"+k.MD_PARENT_END+")")}switch(e.relSpec.cardB){case s.db.Cardinality.ZERO_OR_ONE:l.attr("marker-start","url("+h+"#"+k.ZERO_OR_ONE_START+")");break;case s.db.Cardinality.ZERO_OR_MORE:l.attr("marker-start","url("+h+"#"+k.ZERO_OR_MORE_START+")");break;case s.db.Cardinality.ONE_OR_MORE:l.attr("marker-start","url("+h+"#"+k.ONE_OR_MORE_START+")");break;case s.db.Cardinality.ONLY_ONE:l.attr("marker-start","url("+h+"#"+k.ONLY_ONE_START+")");break;case s.db.Cardinality.MD_PARENT:l.attr("marker-start","url("+h+"#"+k.MD_PARENT_START+")")}const d=l.node().getTotalLength(),y=l.node().getPointAtLength(.5*d),u="rel"+w,p=t.append("text").classed("er relationshipLabel",!0).attr("id",u).attr("x",y.x).attr("y",y.y).style("text-anchor","middle").style("dominant-baseline","middle").style("font-family",(0,i.c)().fontFamily).style("font-size",T.fontSize+"px").text(e.roleA).node().getBBox();t.insert("rect","#"+u).classed("er relationshipLabelBox",!0).attr("x",y.x-p.width/2).attr("y",y.y-p.height/2).attr("width",p.width).attr("height",p.height)}(h,t,d,y,o)}));const f=T.diagramPadding;i.u.insertTitle(h,"entityTitleText",T.titleTopMargin,o.db.getDiagramTitle());const m=h.node().getBBox(),E=m.width+2*f,g=m.height+2*f;(0,i.i)(h,g,E,T.useMaxWidth),h.attr("viewBox",`${m.x-f} ${m.y-f} ${E} ${g}`)}},styles:t=>`\n .entityBox {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxOdd {\n fill: ${t.attributeBackgroundColorOdd};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxEven {\n fill: ${t.attributeBackgroundColorEven};\n stroke: ${t.nodeBorder};\n }\n\n .relationshipLabelBox {\n fill: ${t.tertiaryColor};\n opacity: 0.7;\n background-color: ${t.tertiaryColor};\n rect {\n opacity: 0.5;\n }\n }\n\n .relationshipLine {\n stroke: ${t.lineColor};\n }\n\n .entityTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n } \n #MD_PARENT_START {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n #MD_PARENT_END {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n \n`}}}]); \ No newline at end of file diff --git a/assets/js/1109f10b.7aa2aa13.js b/assets/js/1109f10b.7aa2aa13.js new file mode 100644 index 0000000000..4be7f938b1 --- /dev/null +++ b/assets/js/1109f10b.7aa2aa13.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[13605],{16538:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>d});const a=JSON.parse('{"id":"scs-0110-v1-ssd-flavors","title":"SSD Flavors","description":"Introduction","source":"@site/standards/scs-0110-v1-ssd-flavors.md","sourceDirName":".","slug":"/scs-0110-v1-ssd-flavors","permalink":"/standards/scs-0110-v1-ssd-flavors","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SSD Flavors","type":"Decision Record","status":"Stable","stabilized_at":"2023-06-14T00:00:00.000Z","track":"IaaS","enhances":"scs-0100-v2-flavor-naming.md"},"sidebar":"standards","previous":{"title":"scs-0110: SSD Flavors","permalink":"/standards/iaas/scs-0110"},"next":{"title":"scs-0111: Decisions for the Volume Type Standard","permalink":"/standards/iaas/scs-0111"}}');var s=n(74848),o=n(28453);const i={title:"SSD Flavors",type:"Decision Record",status:"Stable",stabilized_at:new Date("2023-06-14T00:00:00.000Z"),track:"IaaS",enhances:"scs-0100-v2-flavor-naming.md"},r=void 0,l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"One-node etcd (backed by redundant storage)",id:"one-node-etcd-backed-by-redundant-storage",level:4},{value:"RAM (tmpfs) etcd storage",id:"ram-tmpfs-etcd-storage",level:4},{value:"Heartbeat slowdown",id:"heartbeat-slowdown",level:4},{value:"Filesystem tuning",id:"filesystem-tuning",level:4},{value:"Flavors with local storage",id:"flavors-with-local-storage",level:4},{value:"Decision",id:"decision",level:2},{value:"Out of Scope",id:"out-of-scope",level:2},{value:"Implementation note",id:"implementation-note",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",p:"p",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(t.p,{children:"SCS defines an IaaS Flavor Naming standard that mandates a number of standard flavors\nto be available in each SCS-compliant IaaS offering. While offering or exposing\nIaaS is not a requirement for SCS-compliant infrastructure offerings \u2014 SCS allows\nfor platforms only exposing the container layer (plus S3 compatible object storage)\nfor wave 2 (container-based) cloud-native workloads --\nthe SCS reference implementation does include a complete IaaS implementation that\nmany providers want to expose as they have customers desiring access at this layer\nfor wave 1 (VM-based) cloud-native workloads or for the virtualization of more\nclassical (not cloud-native) workloads. The IaaS implementation thus comes with\nstandards."}),"\n",(0,s.jsx)(t.p,{children:"This Decision Record is about adding a few mandatory flavors on the IaaS level\nthat include flavors with local SSD (or better) storage."}),"\n",(0,s.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0100-v2-flavor-naming.md",children:"currently defined standard flavors"}),"\ndo not include\nflavors that use local storage. For certain workloads such as databases or big data\nfilesystems, local storage is highly desirable as replication may be handled at\nthe application layer, making replication/redundancy in a networked storage solution\n(ceph in the SCS reference implementation) an unneeded and undesired property.\nFurthermore, write access to networked and replicated storage typically incurs\na certain latency, as the writes can only be acknowledged once all the replicas\nhave confirmed that the data has hit stable storage. Write latency is critical\nfor e.g. relational database performance."]}),"\n",(0,s.jsx)(t.p,{children:"The main purpose for the IaaS layer in SCS is to perform as a solid foundation\nto provide and manage kubernetes container clusters in a multi-tenant scenario.\nAs such the standards at the IaaS layer should ensure that all the needed\ntypes of resources are available for the container clusters. This is not\ncurrently the case: In a scenario with multiple k8s control-plane nodes set\nup via kubeadm (as part of the k8s cluster-api automation), the control plane\nnodes each run an etcd instance and together form an etcd cluster."}),"\n",(0,s.jsx)(t.p,{children:"etcd is sensitive to scheduling, network and storage latencies. While network\nlatencies and scheduling latencies have not been observed to be an issue in\nclusters within one cloud region, the storage latency is. With remote networked\nstorage as delivered from ceph, the long tail of write latency causes etcd\nto often time out heartbeats, causing a new leader election with a leader\nchange, preventing control plane changes on k8s for a few seconds. Too many\nleader changes can slow down cluster operation and even bring it to a halt."}),"\n",(0,s.jsxs)(t.p,{children:["The etcd requirements ",(0,s.jsx)(t.a,{href:"https://etcd.io/docs/v3.5/op-guide/hardware/#example-hardware-configurations",children:"are well documented"}),".\nIn particular, over a hundred of ",(0,s.jsx)(t.em,{children:"sequential"})," IOPS are recommended. This\nrequires write latencies in the range of a single-digit ms (or better)."]}),"\n",(0,s.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsx)(t.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,s.jsx)(t.h4,{id:"one-node-etcd-backed-by-redundant-storage",children:"One-node etcd (backed by redundant storage)"}),"\n",(0,s.jsx)(t.p,{children:"If k8s uses only one control plane node, there will only be one etcd node,\navoiding timed out heartbeats. Single node control planes are typically not\nrecommended for production workloads though. They are limited with respect\nto control plane performance, have a higher chance to fail (as a single node failure\ncan create cluster control-plane downtime) and can not undergo rolling upgrades."}),"\n",(0,s.jsx)(t.p,{children:"Though not the normal setup with kubeadm, it is possible to use a multi-node\ncontrol plane using a single-node etcd. This shares some of the challenges of\nsingle-node control-planes, although recovery may be faster to perform at least\nin scenarios where the etcd backend storage is redundant and not affected by the\nsingle-node outage."}),"\n",(0,s.jsx)(t.p,{children:"Neither scenario fulfills typical requirements for production workloads."}),"\n",(0,s.jsx)(t.h4,{id:"ram-tmpfs-etcd-storage",children:"RAM (tmpfs) etcd storage"}),"\n",(0,s.jsx)(t.p,{children:"etcd could keep its database in volatile memory (e.g. on a tmpfs filesystem).\nFor multi-node etcd clusters, this could actually be made work, as long as at\nleast one cluster member stays alive and proper care is taken to remove shut-down\nnodes from the cluster. A loss of power affecting all nodes or a hardware\nmaintenance operation not tracking etcd needs would result in a complete\nloss of all cluster state. The control plane nodes would require live migration\nto avoid this in the maintenance case. For the power loss scenario, a frequent\nbackup might mitigate the cluster state loss case somewhat."}),"\n",(0,s.jsx)(t.p,{children:"The etcd database is normally limited to 2GiB in size, which is something\nthat is realistic to keep in main memory. (Typical database sizes are\nmuch smaller.)"}),"\n",(0,s.jsx)(t.p,{children:"This option requires additional care and may not be suitable for all\nproduction scenarios, but would seem a possible fallback position for\netcd. It does obviously not address the database scenario."}),"\n",(0,s.jsx)(t.h4,{id:"heartbeat-slowdown",children:"Heartbeat slowdown"}),"\n",(0,s.jsx)(t.p,{children:"To avoid causing too many fail-overs by occasional high latencies, the\nfrequency of heartbeats can be lowered from the default 1/100ms.\nThe reelection timeout should change along with it (typically set to\n10 beats)."}),"\n",(0,s.jsx)(t.p,{children:"This will cause etcd to take a bit more time to notice the loss of a node,\nwhich is not typically critical if done within reasonable limits.\nThis change however does not fully address the issue \u2014 occasional write latencies\nabove 100ms will still cause failed heartbeats, just less often."}),"\n",(0,s.jsxs)(t.p,{children:["This change has been implemented in the\n",(0,s.jsx)(t.a,{href:"https://etcd.io/docs/v3.5/op-guide/hardware/#example-hardware-configurations",children:"k8s-cluster-api-provider"}),"\nreference implementation: The heartbeat has been changed from 1/100ms (10/s)\nto 1/250ms (4/s) and the reelection timeout from 1s to 2.5s."]}),"\n",(0,s.jsx)(t.p,{children:"The etcd process also is afforded a higher CPU priority (lower niceness),\nresulting in a lower scheduling latency, as high-prio processes preempt lower-prio\nones when they get woken up. The etcd process also gets its IO priority\nincreased to get treated preferentially in case the IO scheduler has many\noutstanding requests. This has some positive effects with the CFQ IO scheduler."}),"\n",(0,s.jsx)(t.p,{children:"The slower heartbeat and the priority tweaks do lower the amount of leader\nchanges but are insufficient to completely address the issue on the tests\nperformed against networked ceph-backed storage."}),"\n",(0,s.jsx)(t.h4,{id:"filesystem-tuning",children:"Filesystem tuning"}),"\n",(0,s.jsxs)(t.p,{children:["Databases must ensure that certain data has hit stable storage before acknowledging\nwrites \u2014 this is required in order to live up to the ",(0,s.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/ACID",children:"ACID"}),"\nguarantees in situations when disruptions might happen. Databases typically use\n",(0,s.jsx)(t.code,{children:"fsync()"})," calls to ensure that write buffers are written to real persistent storage\nunless they use raw/direct block devices circumventing Linux's page and buffer cache."]}),"\n",(0,s.jsxs)(t.p,{children:["etcd normally uses a write-ahead-log (WOL) file that lives on a Linux filesystem and\nuses ",(0,s.jsx)(t.code,{children:"fsync"})," to ensure the correct write ordering. Trouble with fsync is that it\nalso causes unrelated data to be written out with most existing Linux filesystems,\nadding to the latency."]}),"\n",(0,s.jsxs)(t.p,{children:["It is possible to tell the Linux filesystems to not wait for all data to have hit\nstorage before returning from fsync() calls. This avoids the latency caused by\n",(0,s.jsx)(t.code,{children:"fsync"})," but also subverts the very reason for using ",(0,s.jsx)(t.code,{children:"fsync"}),": In case of a disruption\n(OS crash, power outage, loss of connection to storage, ...), the state is likely\nnot consistent, as the kernel has lied to the application about data having been\nwritten out. Recovery from such a scenario can range from smooth to impossible."]}),"\n",(0,s.jsx)(t.p,{children:"In a multi-node cluster, this may not be as bad as it sounds \u2014 if only one\nnode is affected by a disruption, the crashed node can be recovered by resyncing\nthe data from other nodes. In practice an inconsistent state would be considered\ntoo risky, and it should be preferred to set up a fresh node to join the\nexisting etcd cluster. This would need to be implemented to make this option\nless risky."}),"\n",(0,s.jsx)(t.p,{children:"The reference implementation has an option to use these unsafe filesystem settings.\nHowever, they are not enabled by default for good reasons."}),"\n",(0,s.jsx)(t.h4,{id:"flavors-with-local-storage",children:"Flavors with local storage"}),"\n",(0,s.jsx)(t.p,{children:"Flavors with local storage will have their root filesystem on a local storage\ndevice. To fulfill the need for high IOPS that etcd and especially databases\nhave, the local storage device should be a solid state device \u2014 an SSD or\nNVMe device. While some use cases might even be fulfilled with local\nspinning disks (or raid arrays of local spinning disks)."}),"\n",(0,s.jsx)(t.p,{children:"Local solid state storage avoids any network overhead and offers best latency.\nIt however is not typically redundant, meaning that the loss of the device\nor the complete hardware node will result in data loss. So it is meant to\nbe used with applications such as database clusters, replicating filesystems\nor block devices or etcd which can handle this at the application layer."}),"\n",(0,s.jsx)(t.p,{children:"The flavor naming spec in SCS allows performance to be understated \u2014 a\nflavor with NVMe storage can be advertised under the SSD storage name\n(and of course can be offered under both names)."}),"\n",(0,s.jsx)(t.p,{children:"Note that this addresses the simple case where the root disk with the\nroot filesystem (and possibly additional filesystems that are set up\nwhen first booting) uses the local storage. Scenarios where additional\nlow-latency networked or local storage are made available via cinder\nand attached for database storage are possible and viable options for\nsome scenarios, but not covered here."}),"\n",(0,s.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsxs)(t.p,{children:["Two new mandatory flavors: ",(0,s.jsx)(t.code,{children:"SCS-2V-4-20s"})," and ",(0,s.jsx)(t.code,{children:"SCS-4V-16-100s"})," are added\nto the SCS flavor naming standard. The first is meant to be a good fit for\nk8s control nodes with etcd while the latter is a solid base for a\nsmall database server. Clouds claiming SCS-compliance for their IaaS\nlayer MUST provide these two additional flavors."]}),"\n",(0,s.jsx)(t.p,{children:"Obviously providers MAY offer many more combinations and e.g. create\nflavors with large local SSDs."}),"\n",(0,s.jsxs)(t.p,{children:["The local storage advertised this way MUST support more than\n1000 ",(0,s.jsx)(t.em,{children:"sequential"})," IOPS per VM of both new mandatory types (which means a\nwrite latency lower than 1ms \u2014 this typically means SSDs/NVMEs that\nsupport at least several 10ks of parallel IOPS, not a challenge for\ncurrent hardware)."]}),"\n",(0,s.jsx)(t.p,{children:"Local disks, SSDs, NVMes MUST have Power-Loss-Protection such that\ndata reported to be written, but in reality being stored in RAM or SLC\ncache of an SSD or NVMe, is guaranteed to not be lost in case of a power\nloss."}),"\n",(0,s.jsx)(t.p,{children:"Like with networked storage, the provider must ensure that data\nfrom previous users is not accessible (e.g. by securely erasing it\nor by using a different encryption key) when local storage gets\nallocated to a new VM."}),"\n",(0,s.jsx)(t.h2,{id:"out-of-scope",children:"Out of Scope"}),"\n",(0,s.jsx)(t.p,{children:"Hardware nodes (hypervisors in OpenStack language) that support flavors\nwith local storage (are part of an appropriate OpenStack host aggregate)\nmay have many VMs competing for bandwidth to the attached local storage\ndevices; the host needs to be configured such that it can sustain VMs\nwriting at full speed without causing the host to be overloaded or\nto cause huge queues for these writes."}),"\n",(0,s.jsx)(t.p,{children:"A more generic approach is to apply storage QoS policies to the VMs to\nmanage bandwidth and IOPS and create the ability to have better\nperformance isolation with certain guarantees. While this is desirable,\nit has not been found a necessity for etcd in our tests.\nDisk IO QoS is not part of this spec but may be considered in another one."}),"\n",(0,s.jsx)(t.p,{children:"Live-migration with local storage is significantly more difficult than with\nnetworked storage: The contents of the local disks also need to be replicated\nover to the new host. Live-migration for these VMs may thus take significantly\nlonger or not be possible at all, depending on the configuration from the provider.\nNot supporting live-migration is OK for flavors with local disks according\nto the flavor naming spec \u2014 a capability to indicate whether\nlive-migration is supported will be subject to a flavor-metadata discoverability\nspec that is planned for the future."}),"\n",(0,s.jsx)(t.h2,{id:"implementation-note",children:"Implementation note"}),"\n",(0,s.jsx)(t.p,{children:"Local storage in OpenStack can be provided directly via nova or via the\ncinder service. While the latter has the advantage of making volumes\nvisible and manageable via most of the normal cinder capabilities, it\nhas the disadvantage of creating an indirection via iSCSI. This\nresults in higher latency. The requirements in the above spec are\nnot meant to mandate or prevent the implementation via either route."}),"\n",(0,s.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsxs)(t.p,{children:["The flavors will be added as mandatory flavors to the\n",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0100-v2-flavor-naming.md",children:"flavor-naming standard"}),",\nwhich will thus have to be released in a v3."]}),"\n",(0,s.jsxs)(t.p,{children:["The IOPS and Power-Loss requirements from this decision should become\npart of the flavor-naming standard for disk type ",(0,s.jsx)(t.code,{children:"s"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"When we standardize storage types in the future, additional possibilities\nto solve the latency requirements for databases and etcd may emerge."}),"\n",(0,s.jsx)(t.p,{children:"When we standardize QoS features there, we may amend this standard with\nQoS recommendations or possibly requirements."}),"\n",(0,s.jsx)(t.p,{children:"A future flavor metadata discoverability standard will indicate whether\nthese flavors can be live-migrated. A future VM metadata standard will allow\nusers to request live-migration and/or cold migration or restart to be or to\nnot be performed."}),"\n",(0,s.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The list of mandatory flavors that needs to be present should be added to the\n",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/SCS-Spec.MandatoryFlavors.yaml",children:"SCS-Spec.MandatoryFlavors.yaml"}),"\nspec as soon as this ADR becomes part of the certification requirements."]}),"\n",(0,s.jsx)(t.p,{children:"Checks for conforming with IOPS and purging requirements will require\ntest instances to be launched and might become part of a monitoring\nsolution."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var a=n(96540);const s={},o=a.createContext(s);function i(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/119c53e5.ba041e2a.js b/assets/js/119c53e5.ba041e2a.js new file mode 100644 index 0000000000..95d7f5f39d --- /dev/null +++ b/assets/js/119c53e5.ba041e2a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[58407],{65572:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>d,contentTitle:()=>a,default:()=>l,frontMatter:()=>t,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"iaas/guides/configuration-guide/commons/user","title":"User","description":"With the osism.commons.user role, it is possible to manage additional","source":"@site/docs/02-iaas/guides/configuration-guide/commons/user.md","sourceDirName":"02-iaas/guides/configuration-guide/commons","slug":"/iaas/guides/configuration-guide/commons/user","permalink":"/docs/iaas/guides/configuration-guide/commons/user","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/user.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"User"},"sidebar":"docs","previous":{"title":"Timezone","permalink":"/docs/iaas/guides/configuration-guide/commons/timezone"},"next":{"title":"Services","permalink":"/docs/iaas/guides/configuration-guide/services/"}}');var o=r(74848),i=r(28453);const t={sidebar_label:"User"},a="User",d={},c=[];function u(e){const s={code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"user",children:"User"})}),"\n",(0,o.jsxs)(s.p,{children:["With the ",(0,o.jsx)(s.code,{children:"osism.commons.user"})," role, it is possible to manage additional\nuser accounts on a node."]}),"\n",(0,o.jsxs)(s.p,{children:["Users are managed via the ",(0,o.jsx)(s.code,{children:"user_list"})," parameter."]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-yaml",children:"user_list:\n - name: testing\n key: ssh-rsa AAAAB...\n # default for groups is user_groups\n # groups:\n groups:\n - docker\n # default is a group with the name of the user\n # or user_primary_group if set\n # primary_group: dragon\n - name: testing_github\n key: https://github.com/testing.keys\n"})}),"\n",(0,o.jsxs)(s.p,{children:["By default a new group with the name of a user will be created and assigned as\nprimary group. It is possible to use an already existing group as primary group\nfor all users. Can be overwritten with the user specific ",(0,o.jsx)(s.code,{children:"primary_group"})," key."]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-yaml",children:"user_primary_group: dragon\n"})}),"\n",(0,o.jsxs)(s.p,{children:["If all users should be added to other specific groups by default, the ",(0,o.jsx)(s.code,{children:"user_groups"}),"\nparameter can be used. Can be overwritten with the user specific ",(0,o.jsx)(s.code,{children:"groups"})," key."]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-yaml",children:"user_groups:\n - docker\n"})}),"\n",(0,o.jsxs)(s.p,{children:["If users should be deleted, they are added to the ",(0,o.jsx)(s.code,{children:"user_delete"})," list."]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-yaml",children:"user_delete:\n - user_to_delete_1\n - user_to_delete_2\n"})})]})}function l(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var n=r(96540);const o={},i=n.createContext(o);function t(e){const s=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),n.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1276f6ab.73361147.js b/assets/js/1276f6ab.73361147.js new file mode 100644 index 0000000000..649f9722ad --- /dev/null +++ b/assets/js/1276f6ab.73361147.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[44684],{29973:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"scs-0411-v1-publishing_method_for_metering_data","title":"Push-based approach for providing usage data","description":"for more info. --\x3e","source":"@site/standards/scs-0411-v1-publishing_method_for_metering_data.md","sourceDirName":".","slug":"/scs-0411-v1-publishing_method_for_metering_data","permalink":"/standards/scs-0411-v1-publishing_method_for_metering_data","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Push-based approach for providing usage data","type":"Decision Record","status":"Draft","track":"Ops"},"sidebar":"standards","previous":{"title":"scs-0411: Push-based approach for providing usage data","permalink":"/standards/ops/scs-0411"},"next":{"title":"scs-0412: Exposition of IaaS metering data as JSON","permalink":"/standards/ops/scs-0412"}}');var i=s(74848),o=s(28453);const a={title:"Push-based approach for providing usage data",type:"Decision Record",status:"Draft",track:"Ops"},r=void 0,l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Definitions",id:"definitions",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options",id:"options",level:3},{value:"Push-based flow",id:"push-based-flow",level:4},{value:"Poll-based flow",id:"poll-based-flow",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const n={h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"In the past we noticed missing events in the telemetry stack of OpenStack.\nThis results in situations where the Cloud Service Provider (CSP)\nmay think that a resource is still in use while the owner shut it down,\nor may not be aware of a resource which has been created."}),"\n",(0,i.jsx)(n.p,{children:"Such inaccurate data is a problem,\nwhen it is supposed to be used for billing purposes."}),"\n",(0,i.jsx)(n.p,{children:"This document discusses how such metering data should be made available\nto the cloud service provider\nfor forwarding into their own billing solution."}),"\n",(0,i.jsx)(n.h2,{id:"definitions",children:"Definitions"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Push-based flow:\nIn a push-based flow,\nthe system generating data actively sends that data to a consumer."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Pull-based flow:\nIn a pull-based flow,\nthe system generating data waits for the system consuming the data\nto ask for that data."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Metering:\nCollection of usage data of a cloud,\nfor the specific purpose of creating invoices\nto bill customers for the resources they have allocated."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Billing:\nThe entire process of creation, management and sending of invoices\ngenerated from metering data."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(n.p,{children:"Being able to bill users\nfor the resources they use\nis a prerequisite for commercially operating a cloud.\nThe SCS project wants to deliver a cloud stack\nwhich can be used for that purpose,\nhence providing reliable metering data is a requirement."}),"\n",(0,i.jsx)(n.p,{children:"We generally expect that cloud providers already have\nsome kind of customer-relation management or billing system in place.\nHence, it is important that the SCS is not too opinionated\non this implementation detail,\nbut provides a system which can easily interface with other systems."}),"\n",(0,i.jsx)(n.p,{children:"This is similar to how the SCS specified the monitoring stack."}),"\n",(0,i.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsx)(n.p,{children:"The following requirements exist for the process for providing metrics to the cloud service provider:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"MUST scale to different timescales:\nWe expect to have metrics which change frequently (e.g. object store usage)\nand metrics which change rarely (e.g. cinder volume sizes)."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"options",children:"Options"}),"\n",(0,i.jsx)(n.h4,{id:"push-based-flow",children:"Push-based flow"}),"\n",(0,i.jsx)(n.p,{children:"In a push-based flow,\nthe to-be-implemented metering system pushes events to the sink\nas soon as it is reasonably confident\nthat the event can be used for billing purposes."}),"\n",(0,i.jsx)(n.h4,{id:"poll-based-flow",children:"Poll-based flow"}),"\n",(0,i.jsx)(n.p,{children:"In the poll-based flow,\nwhichever system the CSP runs would be responsible for polling the metering API\nin a frequency sufficient to capture all data with sufficient granularity."}),"\n",(0,i.jsx)(n.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"What is necessary to extend the availability of sending to various sinks?"}),"\n",(0,i.jsx)(n.li,{children:"How does the configuration look like that is needed to push to a sink from the same type that will be already implemented?"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(n.p,{children:"As we need to support very different time scales of data,\nthe push-based flow is more suitable:\nit allows the producer of the data,\nwhich knows about the interval in which it changes,\nwhen to provide new data to the consumer.\nIn contrast to that,\na poll-based flow would need the consumer to know about change intervals,\nor alternatively poll in the highest change frequency ever expected."}),"\n",(0,i.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"SCS-0410-v1"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,i.jsx)(n.p,{children:"None (this is a decision record)."})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var t=s(96540);const i={},o=t.createContext(i);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1300cb4e.81845503.js b/assets/js/1300cb4e.81845503.js new file mode 100644 index 0000000000..a3238af148 --- /dev/null +++ b/assets/js/1300cb4e.81845503.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[86273],{67601:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"scs-0104-w1-standard-images-implementation","title":"SCS Standard Images: Implementation Notes","description":"Introduction","source":"@site/standards/scs-0104-w1-standard-images-implementation.md","sourceDirName":".","slug":"/scs-0104-w1-standard-images-implementation","permalink":"/standards/scs-0104-w1-standard-images-implementation","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Standard Images: Implementation Notes","type":"Supplement","track":"IaaS","status":"Draft","supplements":["scs-0104-v1-standard-images.md"]},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0104-v1-standard-images"},"next":{"title":"scs-0110: SSD Flavors","permalink":"/standards/iaas/scs-0110"}}');var a=t(74848),i=t(28453);const r={title:"SCS Standard Images: Implementation Notes",type:"Supplement",track:"IaaS",status:"Draft",supplements:["scs-0104-v1-standard-images.md"]},o=void 0,c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Step-by-step walkthrough",id:"step-by-step-walkthrough",level:2},{value:"Option A: pragmatic",id:"option-a-pragmatic",level:3},{value:"Option B: principled",id:"option-b-principled",level:3},{value:"Operational Tooling",id:"operational-tooling",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,a.jsx)(n.p,{children:'The SCS standard on standard images does not in itself lay down what images are actually\nrequired or recommended; rather it specifies the format of a YAML file that in turn serves\nsaid purpose. The particular YAML file that an implementer (a cloud service provider or operator)\nhas to comply with is given in the respective version of the certificate scope "SCS-compatible IaaS"\nas a parameter to the standard. This document is intended to give implementers a\nstep-by-step guide on how to comply with the SCS certificate scope.'}),"\n",(0,a.jsx)(n.h2,{id:"step-by-step-walkthrough",children:"Step-by-step walkthrough"}),"\n",(0,a.jsx)(n.h3,{id:"option-a-pragmatic",children:"Option A: pragmatic"}),"\n",(0,a.jsx)(n.p,{children:"Run the test script on your environment and check the error messages :)"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Check out the ",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards",children:"standards repository"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"git clone https://github.com/SovereignCloudStack/standards.git\ncd standards\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Install requirements:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"python3 -m venv .venv && source .venv/bin/activate\npip install -r requirements.txt \n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Make sure that your ",(0,a.jsx)(n.code,{children:"OS_CLOUD"})," environment variable is set."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Run the main check script:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-shell",children:"python3 ./Tests/scs-compliance-check.py ./Tests/scs-compatible-iaas.yaml -t standard-images-check \\\n -s $OS_CLOUD -a os_cloud=$OS_CLOUD -o report.yaml -C\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Inspect console output (stderr) for error messages."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"option-b-principled",children:"Option B: principled"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["Find your intended version of the certificate scope in the ",(0,a.jsx)(n.a,{href:"https://docs.scs.community/standards/scs-compatible-iaas",children:"overview table"}),". It will most likely be one whose 'State' is 'Effective' or 'Stable'."]}),"\n",(0,a.jsxs)(n.li,{children:["In (or below) the row labeled 'scs-0104: Standard images', you find a link to the YAML file that lists mandatory and recommended images, such as ",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/scs-0104-v1-images.yaml",children:"scs-0104-v1-images.yaml"})," for v4 of the certificate scope."]}),"\n",(0,a.jsxs)(n.li,{children:["For each entry under ",(0,a.jsx)(n.code,{children:"images"}),', ensure the following (either manually or by using the OpenStack Image Manager described in the section "Operational Tooling"):',"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["if the entry says ",(0,a.jsx)(n.code,{children:"status: mandatory"}),", your environment MUST provide this image, i.e., an image whose name matches the ",(0,a.jsx)(n.code,{children:"name_scheme"})," or (in absence of a name scheme) the ",(0,a.jsx)(n.code,{children:"name"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:["every actual image in your environment ",(0,a.jsxs)(n.em,{children:["that matches the ",(0,a.jsx)(n.code,{children:"name_scheme"})," or (in absence of a name scheme) the ",(0,a.jsx)(n.code,{children:"name"})]})," has the correct ",(0,a.jsx)(n.code,{children:"image_source"})," property: its value MUST start with one of the prefixes listed under ",(0,a.jsx)(n.code,{children:"source"}),"."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"operational-tooling",children:"Operational Tooling"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.a,{href:"https://github.com/osism/openstack-image-manager",children:"openstack-image-manager"})," is able to\ncreate all standard, mandatory SCS images for you given image definitions from a YAML file.\nPlease see ",(0,a.jsx)(n.a,{href:"https://docs.scs.community/docs/iaas/components/image-manager/",children:"its documentation"})," for details."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var s=t(96540);const a={},i=s.createContext(a);function r(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/130ed5c1.5f2d06ff.js b/assets/js/130ed5c1.5f2d06ff.js new file mode 100644 index 0000000000..36465d1bbc --- /dev/null +++ b/assets/js/130ed5c1.5f2d06ff.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[19303],{89069:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"scs-0125-v1-secure-connections","title":"Secure Connections","description":"Introduction","source":"@site/standards/scs-0125-v1-secure-connections.md","sourceDirName":".","slug":"/scs-0125-v1-secure-connections","permalink":"/standards/scs-0125-v1-secure-connections","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Secure Connections","type":"Standard","status":"Draft","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0125: Secure Connections","permalink":"/standards/iaas/scs-0125"},"next":{"title":"KaaS Standards","permalink":"/standards/kaas/"}}');var s=t(74848),r=t(28453);const a={title:"Secure Connections",type:"Standard",status:"Draft",track:"IaaS"},o=void 0,c={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Communication Channels",id:"communication-channels",level:3},{value:"libvirt Hypervisor Interface on Compute Nodes",id:"libvirt-hypervisor-interface-on-compute-nodes",level:3},{value:"TLS for libvirt and live migration",id:"tls-for-libvirt-and-live-migration",level:4},{value:"Local UNIX socket and SSH live migration",id:"local-unix-socket-and-ssh-live-migration",level:4},{value:"TLS Configuration Recommendations",id:"tls-configuration-recommendations",level:3},{value:"Storage network protection",id:"storage-network-protection",level:3},{value:"Options considered",id:"options-considered",level:3},{value:"Option 1: fully mandate securing all channels without differentiation",id:"option-1-fully-mandate-securing-all-channels-without-differentiation",level:4},{value:"Option 2: only make recommendations",id:"option-2-only-make-recommendations",level:4},{value:"Option 3: mix recommendations and obligations",id:"option-3-mix-recommendations-and-obligations",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"Choosing the best protection mechanism for the libvirt hypervisor interface",id:"choosing-the-best-protection-mechanism-for-the-libvirt-hypervisor-interface",level:3},{value:"Verifying standard conformance for internal mechanisms",id:"verifying-standard-conformance-for-internal-mechanisms",level:3},{value:"Standard",id:"standard",level:2},{value:"Transport Layer Security (TLS)",id:"transport-layer-security-tls",level:3},{value:"API Interfaces",id:"api-interfaces",level:3},{value:"Database Connections",id:"database-connections",level:3},{value:"Message Queue Connections",id:"message-queue-connections",level:3},{value:"Hypervisor and Live Migration Connections",id:"hypervisor-and-live-migration-connections",level:3},{value:"External VM Connections",id:"external-vm-connections",level:3},{value:"Internal Neutron Connections",id:"internal-neutron-connections",level:3},{value:"Storage Connections",id:"storage-connections",level:3},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function l(e){const n={a:"a",blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"A lot of internal and external connectivity is established to and within a cloud infrastructure.\nDue to the nature of the IaaS approach, many communication channels may occasionally or even primarily carry potentially sensitive data of customers.\nTo protect this data from both tampering and unintended disclosure, communication channels need to be properly secured."}),"\n",(0,s.jsxs)(n.p,{children:["For this reason, the ",(0,s.jsx)(n.a,{href:"https://scs.community",children:"SCS project"})," standardizes the use of common protection mechanisms for communication channels in OpenStack infrastructures."]}),"\n",(0,s.jsx)(n.h2,{id:"terminology",children:"Terminology"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Term"}),(0,s.jsx)(n.th,{children:"Meaning"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"CA"}),(0,s.jsx)(n.td,{children:"Certificate Authority"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"CSP"}),(0,s.jsx)(n.td,{children:"Cloud Service Provider, provider managing the OpenStack infrastructure"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"PKI"}),(0,s.jsx)(n.td,{children:"Public Key Infrastructure"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"SDN"}),(0,s.jsx)(n.td,{children:"Software-Defined Networking"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"SSL"}),(0,s.jsx)(n.td,{children:"Secure Sockets Layer, the predecessor of TLS"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"TLS"}),(0,s.jsx)(n.td,{children:"Transport Layer Security"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Compute Host"}),(0,s.jsx)(n.td,{children:"System within the IaaS infrastructure that runs the hypervisor services and hosts virtual machines"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsxs)(n.p,{children:["As mentioned above, a lot of communication channels in an OpenStack infrastructure carry data that is potentially sensitive.\nFor example this includes authentication data of customers and internal OpenStack configuration data such as encryption keys among others.\nOpenStack does not generically mandate or preconfigure the use of specific protection mechanisms by itself and instead only makes recommendations about best practices in its offical ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/security-guide/",children:"Security Guide"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"To address the potential lack of implementation of such mechanisms by a CSP and to establish a reliable foundation for communication data protection in SCS clouds, the SCS project formulates this standard for securing communication channels in the infrastructure, so that a customer can rely on adequate security mechanisms being in use."}),"\n",(0,s.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsx)(n.p,{children:"There are many internal communication channels in OpenStack with different characteristics, location and eligible means of protection.\nNot all channels are equally easy to secure and some protection mechanisms might put unbearable burdens on a CSP.\nHence, careful assessment is required to determine for which the SCS standard will either mandate or recommend the use of a protection mechanism."}),"\n",(0,s.jsx)(n.p,{children:"Note that this standard only focuses on security considerations for securing the Openstack API as well as inter-component connections, which a CSP has full control over on an infrastructure level.\nThis standard will not address the security of customer-deployed instances and services on top of OpenStack or other IaaS implementations."}),"\n",(0,s.jsx)(n.p,{children:"For this distinction to be made, applicable communication channels must be categorized and classified accordingly."}),"\n",(0,s.jsx)(n.h3,{id:"communication-channels",children:"Communication Channels"}),"\n",(0,s.jsx)(n.p,{children:"The following overview will classify the main communication channels."}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"#"}),(0,s.jsx)(n.th,{children:"Classification"}),(0,s.jsx)(n.th,{children:"Details"}),(0,s.jsx)(n.th,{children:"Example solution"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"1"}),(0,s.jsx)(n.td,{children:"OpenStack database backend traffic"}),(0,s.jsx)(n.td,{children:"Replication and sync between database instances of the OpenStack services' databases"}),(0,s.jsx)(n.td,{children:"SSL/TLS"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"2"}),(0,s.jsx)(n.td,{children:"OpenStack database frontend traffic"}),(0,s.jsx)(n.td,{children:"Communication between OpenStack services and their corresponding databases"}),(0,s.jsx)(n.td,{children:"SSL/TLS"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"3"}),(0,s.jsx)(n.td,{children:"Message queue traffic"}),(0,s.jsx)(n.td,{children:"Message queue communication between OpenStack components as provided by oslo.messaging"}),(0,s.jsx)(n.td,{children:"SSL/TLS"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"4"}),(0,s.jsx)(n.td,{children:"External API communication"}),(0,s.jsx)(n.td,{children:"HTTP traffic to services registered as external endpoints in the Keystone service catalog"}),(0,s.jsx)(n.td,{children:"SSL/TLS"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"5"}),(0,s.jsx)(n.td,{children:"Internal API communication"}),(0,s.jsx)(n.td,{children:"HTTP traffic to services registered as internal endpoints in the Keystone service catalog"}),(0,s.jsx)(n.td,{children:"SSL/TLS"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"6"}),(0,s.jsx)(n.td,{children:"Nova VM migration traffic"}),(0,s.jsx)(n.td,{children:"Nova VM migration data transfer traffic between compute nodes"}),(0,s.jsx)(n.td,{children:"QEMU-native TLS"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"7"}),(0,s.jsx)(n.td,{children:"External Neutron network traffic"}),(0,s.jsx)(n.td,{children:"VM-related traffic between the network/controller nodes and external networks (e.g. internet) established through routed provider networks and floating IPs"}),(0,s.jsx)(n.td,{children:"VPN"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"8"}),(0,s.jsx)(n.td,{children:"Internal Neutron network traffic"}),(0,s.jsx)(n.td,{children:"Traffic within Neutron SDN networks exchanged between internal systems such as network/controller and compute nodes"}),(0,s.jsx)(n.td,{children:"WireGuard"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"9"}),(0,s.jsx)(n.td,{children:"Storage network frontend traffic"}),(0,s.jsx)(n.td,{children:"Traffic exchanged between OpenStack and network storage backends (e.g. Ceph)"}),(0,s.jsx)(n.td,{children:"N/A*"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"10"}),(0,s.jsx)(n.td,{children:"Storage network replication traffic"}),(0,s.jsx)(n.td,{children:"Traffic exchanged between individual storage nodes within the network storage backend for replication purposes"}),(0,s.jsx)(n.td,{children:"N/A*"})]})]})]}),"\n",(0,s.jsx)(n.p,{children:"* The characteristics of the storage network traffic is highly specific to the individual storage backend and no generic solution can be stated here."}),"\n",(0,s.jsx)(n.p,{children:"Notes about the classification categories and implications:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Most database clustering solutions (e.g. MariaDB Galera) offer TLS-based encryption of their backend channels. This needs no additional configuration in OpenStack and is a configuration solely concerning the database cluster."}),"\n",(0,s.jsx)(n.li,{children:"The database frontend interface is the primary connection target for the OpenStack services. OpenStack supports using TLS for database connections."}),"\n",(0,s.jsx)(n.li,{children:"For the message queue, AMQP-based solutions such as RabbitMQ and QPid do offer TLS natively which is also supported by OpenStack. ZeroMQ does not and requires WireGuard or CIPSO instead."}),"\n",(0,s.jsx)(n.li,{children:"External API endpoints can be protected easily by using a TLS proxy. They can then be registered with their HTTPS endpoint in the Keystone service catalog. The certificates of external APIs usually need to be signed by a well-known CA in order to be accepted by arbitrary external clients."}),"\n",(0,s.jsx)(n.li,{children:"Internal API endpoints can be treated and secured similarly to the external ones using a TLS proxy and adequate certificates."}),"\n",(0,s.jsxs)(n.li,{children:["For protecting the data transferred between compute nodes during live-migration of VMs, ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/admin/secure-live-migration-with-qemu-native-tls.html",children:"Nova offers support for QEMU-native TLS"}),". As an alternative, SSH is also a channel that Nova can be configured to use between hosts for this but requires passwordless SSH keys with root access to all other compute nodes which in turn requires further hardening."]}),"\n",(0,s.jsx)(n.li,{children:"Neutron's external network traffic leaves the IaaS infrastructure. This part is twofold: connections initiated by the VMs themselves (egress) and connections reaching VMs from the outside (ingress). The CSP cannot influence the egress connections but can offer VPNaaS for the ingress direction."}),"\n",(0,s.jsx)(n.li,{children:"Neutron's internal network traffic is one of the hardest aspects to address. Due to the highly dynamic nature of SDN, connection endpoints and relations are constantly changing. There is no holistic approach currently offered or recommended by OpenStack itself. Encrypted tunnels could be established between all involved nodes but would require a scalable solution and reliable key management. WireGuard could be considered a good starting point for this. A per-tenant/per-customer encryption remains very hard to establish this way though."}),"\n",(0,s.jsx)(n.li,{children:"The available means of securing frontend storage communication are dependent on the protocol used for communication between OpenStack and the storage backend. Some storage solutions and protocols might offer authentication and encryption functionality by default but that cannot be assumed to be the case for every possible backend. Furthermore, storage is highly sensitive to latency and performance impacts imposed by such measures. Due to the fact that OpenStack's volume encryption functionality encrypts block storage data before it enters the storage network, an unsecured communication channel may be considered not as much of a problem here as it is for other channels*."}),"\n",(0,s.jsx)(n.li,{children:"Storage network replication traffic is highly specific to the storage backend solution and its method of operation. For some backends this channel might not even exists, depending on their architecture. As such, in most cases it is up to the storage solution to provide adequate measures for protection of this channel. As with the frontend storage traffic, due to the possible at-rest encryption implemented by OpenStack, only already encrypted data is transferred here for some resources*."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"* Encryption of data implemented by OpenStack before it is passed to the storage backend currently only applies to block data of volumes that use an encrypted volume type. Other data (e.g. of unencrypted volumes, images) is transferred to and from the storage in plaintext."}),"\n",(0,s.jsx)(n.h3,{id:"libvirt-hypervisor-interface-on-compute-nodes",children:"libvirt Hypervisor Interface on Compute Nodes"}),"\n",(0,s.jsx)(n.p,{children:"Live migration of virtual machines between compute hosts requires communication between the hypervisor services of the involved hosts.\nIn OpenStack, the libvirt virtualization API is used to control the hypervisor on compute nodes as well as to enable the live migration communication.\nThis libvirt interface allows direct control of the hypervisor.\nBesides control of virtual machines themselves, in OpenStack this also includes attaching and detaching volumes, setting or retrieving their encryption keys and controlling network attachments.\nAs such, severe risks are associated with unauthorized access to this interface as it can easily compromise sensitive data of arbitrary tenants if abused."}),"\n",(0,s.jsxs)(n.p,{children:["This is acknowledged in the OpenStack Security Note ",(0,s.jsx)(n.a,{href:"https://wiki.openstack.org/wiki/OSSN/OSSN-0007",children:"OSSN-0007"}),", which recommends either configuring SASL and/or TLS for libvirt connections or utilizing the UNIX socket in combination with SSH."]}),"\n",(0,s.jsxs)(n.p,{children:["The OpenStack ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/kolla-ansible/latest/reference/compute/libvirt-guide.html#sasl-authentication",children:"kolla-ansible documentation"})," on Nova libvirt connections state:"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"This should not be considered as providing a secure, encrypted channel, since the username/password SASL mechanisms available for TCP are no longer considered cryptographically secure."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This leaves only TLS or UNIX socket with SSH as viable options for securing the channel."}),"\n",(0,s.jsx)(n.h4,{id:"tls-for-libvirt-and-live-migration",children:"TLS for libvirt and live migration"}),"\n",(0,s.jsxs)(n.p,{children:["Since the Stein release of OpenStack, Nova supports ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/admin/secure-live-migration-with-qemu-native-tls.html",children:"QEMU-native TLS"})," which protects the migration data streams using TLS.\nIt requires to add ",(0,s.jsx)(n.code,{children:'LIBVIRTD_ARGS="--listen"'})," to the ",(0,s.jsx)(n.a,{href:"https://libvirt.org/remote.html#libvirtd-configuration-file",children:"QEMU configuration"}),", which will lead to TLS being active on the libvirt interface per default (due to ",(0,s.jsx)(n.code,{children:"listen_tls"})," defaulting to being enabled).\nThis protects data streams for migration as well as the hypervisor control channel data flow with TLS but does not restrict access.\nClient certificates must be deployed additionally and libvirt configured accordingly[^4] in order to meaningfully restrict access to the interface as advised by the OSSN-0007 document, see restricting-access in ",(0,s.jsx)(n.a,{href:"https://wiki.libvirt.org/TLSDaemonConfiguration.html#restricting-access",children:"Libvirt doc"}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"local-unix-socket-and-ssh-live-migration",children:"Local UNIX socket and SSH live migration"}),"\n",(0,s.jsxs)(n.p,{children:["As an alternative to the TLS setup, libvirt can be configured to use a local UNIX socket and Nova can be configured to use SSH to this socket for live migrations instead.\nThe regular libvirt port can then be limited to localhost (",(0,s.jsx)(n.code,{children:"127.0.0.1"}),") which will make it inaccessible from outside the host but still enables local connections to use it.\nThe challenge of this approach lies in restricting the SSH access on the compute nodes appropriately to avoid full root access across compute nodes for the SSH user identity that Nova will use for live migration.\nThis can be addressed by restricting the command set that is available and the paths that are accessible to these target SSH user identities on compute nodes, limiting them to the scope strictly required by the live migration."]}),"\n",(0,s.jsx)(n.p,{children:"A basic setup for combining the UNIX socket with SSH live migration settings is illustrated below."}),"\n",(0,s.jsx)(n.p,{children:"Libvirt configuration:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-conf",children:'listen_tcp = 1\nlisten_addr = "127.0.0.1"\nunix_sock_group = "libvirt"\nunix_sock_ro_perms = "0770"\nunix_sock_rw_perms = "0770"\n'})}),"\n",(0,s.jsx)(n.p,{children:"Nova configuration:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[libvirt]\nconnection_uri=\nlive_migration_uri=qemu+ssh://...\nlive_migration_scheme = ssh\n\n"})}),"\n",(0,s.jsx)(n.h3,{id:"tls-configuration-recommendations",children:"TLS Configuration Recommendations"}),"\n",(0,s.jsx)(n.p,{children:"Server-side TLS configuration is complex and involves a lot of choices for protocol versions, cipher suites and algorithms.\nDetermining and maintaining secure configuration guidelines for this is non-trivial for a community project as it requires a high level security expertise and consistent evaluation.\nFor this reason, the standard should reference widely accepted best practices and established third party guidelines instead of creating and maintaining its own set of rules."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://wiki.mozilla.org/Security/Server_Side_TLS",children:"Mozilla publishes and maintains"})," TLS recommendations and corresponding presets for configuration and testing.\nConsidering Mozilla's well-established name in the internet and open source communities, this could qualify as a good basis for the standard concerning the TLS configurations."]}),"\n",(0,s.jsx)(n.h3,{id:"storage-network-protection",children:"Storage network protection"}),"\n",(0,s.jsx)(n.p,{children:"As stated in the overview of communication channels, the existence and characteristics of the storage frontend and replication networks are highly specific to the storage backend solution in use.\nIn conjunction with the fact that storage performance is easily impacted by anything that introduces latency or reduces throughput on these channels, there is no easy recommendation on how to secure them that can be made here."}),"\n",(0,s.jsx)(n.p,{children:"This is partially mitigated by OpenStack's ability to encrypt storage data before it enters the storage backend, protecting the data regardless of the storage channels characteristics.\nBut this only applies to block data of volumes that use an encrypted volume type and does not apply to other data put into the storage backend by OpenStack, for example images.\nAs such, this does not fully address unsecured storage channels."}),"\n",(0,s.jsx)(n.p,{children:"However, requiring the network storage channels to be dedicated physical connections separate from the other channels like tenant VM traffic or API communication can increase both the reliability as well as security of the storage connections.\nTherefore this standard should at least recommend a dedicated network infrastructure to be implemented for the storage if network storage backends are used, such as Ceph."}),"\n",(0,s.jsx)(n.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,s.jsx)(n.h4,{id:"option-1-fully-mandate-securing-all-channels-without-differentiation",children:"Option 1: fully mandate securing all channels without differentiation"}),"\n",(0,s.jsx)(n.p,{children:"This option would reach the highest security standard and establish protection on all identified communication channels simultaneously.\nHowever, this would burden CSPs greatly due to the difficulty of addressing some of the channels and properly maintaining the solution.\nAlso there is a risk of making this incompatible with existing infrastructures due to some of their specifics being mutually exclusive to the more intricate protection mechanisms such as cross-node WireGuard configurations.\nAs a third aspect, not all mechanisms might fulfill the CSPs requirements regarding performance and stability and the SCS standard cannot in good faith force CSPs to use technologies not suited to their infrastructures."}),"\n",(0,s.jsx)(n.p,{children:"This seems like a bad option from many perspectives.\nIt also allows very little flexibility and might even make SCS conformance unappealing to CSPs due to the immense effort required to reach it."}),"\n",(0,s.jsx)(n.h4,{id:"option-2-only-make-recommendations",children:"Option 2: only make recommendations"}),"\n",(0,s.jsx)(n.p,{children:"This option would limit the SCS project to only recommend mechanisms in this standard like presented in the OpenStack Security Guide.\nAlthough this can increase awareness about the best practices recommended by OpenStack and maybe encourage CSPs to abide by them, it would actually contribute very little to the security baseline of SCS infrastructures as a whole since everything would stay optional."}),"\n",(0,s.jsx)(n.p,{children:"This option would be very easy to standardize and get consensus on due to its lightweight and optional nature.\nHowever, the actual added value for SCS is questionable at best."}),"\n",(0,s.jsx)(n.h4,{id:"option-3-mix-recommendations-and-obligations",children:"Option 3: mix recommendations and obligations"}),"\n",(0,s.jsx)(n.p,{children:"This option forms a middle ground between options 1 and 2.\nFor this, the standard needs to carefully assess each communication channel, mechanisms for protecting it and the effort required to do so as well as the implications.\nThen, only for mechanisms that are known to be reliable, are feasible to implement and for which the benefits clearly outweigh the integration effort required, should this standard enforce their implementation in a permissive way.\nFor any remaining mechanisms the SCS standard should only make recommendations and refer to known best practices where applicable."}),"\n",(0,s.jsx)(n.p,{children:"This option would still offer improvements over arbitrary OpenStack clouds by establishing a baseline that goes beyond mere recommendations while still taking into account that not all communication channels are equally easy to secure and allowing necessary flexibility for the CSP."}),"\n",(0,s.jsx)(n.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,s.jsx)(n.h3,{id:"choosing-the-best-protection-mechanism-for-the-libvirt-hypervisor-interface",children:"Choosing the best protection mechanism for the libvirt hypervisor interface"}),"\n",(0,s.jsx)(n.p,{children:"As described in the Design Considerations section, there are multiple ways of securing the libvirt interface and live migration channels using TLS or SSH mechanisms.\nUpon closer inspection, this consists of two problems to address:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"encrypting migration traffic utilizing the libvirt interface itself"}),"\n",(0,s.jsx)(n.li,{children:"identifying/authenticating connecting clients and properly restricting their permission set"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"When considering problem no. 1 in an isolated fashion, the QEMU-native TLS approach could be considered preferable simply due to it being officially recommended and documented by upstream OpenStack and tightly integrated into QEMU."}),"\n",(0,s.jsx)(n.p,{children:"However, once problem no. 2 is taken into account, the choice does not seem as obvious anymore due to the fact that in order to properly authenticate clients in the TLS case, X.509 client certificate authentication along with a corresponding PKI as well as key management would be required.\nAlthough similar aspects would be relevant for the SSH approach where SSH key and identity management as well as proper permission restriction would need to be implemented, the SSH approach could turn out less complex due to the fact that the foundation for SSH identities most likely already exists on a node-level and does not need to rely on a full PKI."}),"\n",(0,s.jsx)(n.p,{children:"To properly compare both possible approaches of securing the libvirt interface, extensive testing and evaulation would be necessary along with a sophisticated key and node identity management for compute nodes which this standard alone does not provide."}),"\n",(0,s.jsx)(n.h3,{id:"verifying-standard-conformance-for-internal-mechanisms",children:"Verifying standard conformance for internal mechanisms"}),"\n",(0,s.jsx)(n.p,{children:"Most of the mentioned communication channels to be secured are part of the internal IaaS infrastructure of a SCS cloud.\nWhen an internal protection mechanism is implemented by the CSP it cannot be verified from outside of the infrastructure without administrative access to the infrastructure."}),"\n",(0,s.jsx)(n.p,{children:"Thus, the SCS community is unable to fully assess a CSPs conformance to this standard without a dedicated audit of the infrastructure."}),"\n",(0,s.jsx)(n.h2,{id:"standard",children:"Standard"}),"\n",(0,s.jsxs)(n.p,{children:["This standard will mandate or recommend appropriate measures for securing the communication channels based on existing standards and recommendations.\nIt will reference documents like the ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/security-guide/",children:"OpenStack Security Guide"})," where applicable."]}),"\n",(0,s.jsx)(n.h3,{id:"transport-layer-security-tls",children:"Transport Layer Security (TLS)"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["All server-side TLS configurations integrated into the infrastructure as covered by this standard MUST adhere to the ",(0,s.jsx)(n.a,{href:"https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29",children:'"Intermediate" Mozilla TLS configuration'}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"api-interfaces",children:"API Interfaces"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Internal API endpoints of all OpenStack services MUST use TLS. Their endpoint as registered in the Keystone service catalog MUST be an HTTPS address."}),"\n",(0,s.jsx)(n.li,{children:"External API endpoints of all OpenStack services MUST use TLS. Their endpoint as registered in the Keystone service catalog MUST be an HTTPS address."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["You MAY refer to ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/security-guide/secure-communication/tls-proxies-and-http-services.html",children:"TLS proxies and HTTP services"})," and ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/security-guide/secure-communication/secure-reference-architectures.html",children:"Secure reference architectures"})," of the OpenStack Security Guide for best practices and recommendations."]}),"\n",(0,s.jsx)(n.h3,{id:"database-connections",children:"Database Connections"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The database servers used by the OpenStack services MUST be configured for TLS transport."}),"\n",(0,s.jsxs)(n.li,{children:["All OpenStack services MUST have TLS configured for the database connection via the ",(0,s.jsx)(n.code,{children:"ssl_ca"})," directive. See ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/security-guide/databases/database-access-control.html#openstack-service-database-configuration",children:"OpenStack service database configuration"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["Database user accounts for the OpenStack services SHOULD be configured to require TLS connections via the ",(0,s.jsx)(n.code,{children:"REQUIRE SSL"})," SQL directive. See ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/security-guide/databases/database-access-control.html#require-user-accounts-to-require-ssl-transport",children:"Require user accounts to require SSL transport"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["Security MAY be further enhanced by configuring the OpenStack services to use X.509 client certificates for database authentication. See ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/security-guide/databases/database-access-control.html#authentication-with-x-509-certificates",children:"Authentication with X.509 certificates"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"message-queue-connections",children:"Message Queue Connections"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If using RabbitMQ or Qpid as the message queue service, the SSL functionality of the message broker MUST be enabled and used by the OpenStack services. See ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/security-guide/messaging/security.html#messaging-transport-security",children:"Messaging transport security"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["If using Apache Kafka, the server listener MUST be configured to accept SSL connections. See ",(0,s.jsx)(n.a,{href:"https://kafka.apache.org/documentation/#listener_configuration",children:"Apache Kafka Listener Configuration"}),". OpenStack services MUST be configured to use an SSL setting for the Kafka driver. See ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/oslo.messaging/latest/admin/kafka.html#security-options",children:"Kafka Driver Security Options"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"hypervisor-and-live-migration-connections",children:"Hypervisor and Live Migration Connections"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The live migration connections between compute nodes SHOULD be secured by encryption.","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If QEMU and libvirt are used, QEMU-native TLS is an approach officially documented by OpenStack. See ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/admin/secure-live-migration-with-qemu-native-tls.html",children:"Secure live migration with QEMU-native TLS"}),". As an alternative, SSH-based live migration MAY be configured instead."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["If using libvirt as the hypervisor interface on compute nodes the libvirt port (as per its ",(0,s.jsx)(n.code,{children:"listen_addr"})," configuration option) SHOULD NOT be exposed to the network in an unauthenticated and unprotected fashion:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"For the QEMU-native TLS configuration, it is RECOMMENDED to enforce TLS client certificate authentication and assign corresponding client identities to connecting compute nodes."}),"\n",(0,s.jsx)(n.li,{children:"For the SSH-based live migration approach, it is RECOMMENDED to limit the libvirt port/socket to the local host and establish SSH key pairs for compute nodes in conjunction with restricted SSH permissions."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["See the ",(0,s.jsx)(n.a,{href:"#libvirt-hypervisor-interface-on-compute-nodes",children:"corresponding Design Considerations section"})," for more details about the mentioned approaches."]}),"\n",(0,s.jsx)(n.h3,{id:"external-vm-connections",children:"External VM Connections"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["As an OPTIONAL measure to assist customers in protecting external connections to their OpenStack networks and VMs, the infrastructure MAY provide VPNaaS solutions to users.","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["For example the Neutron VPNaaS service MAY be integrated into the infrastructure with the Neutron VPNaaS API extension enabled. See the ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/neutron-vpnaas/latest/",children:"Neutron VPNaaS documentation"}),"."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"internal-neutron-connections",children:"Internal Neutron Connections"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"As an OPTIONAL measure to protect Neutron SDN traffic between physical nodes within the infrastructure, encrypted tunnels MAY be established between nodes involved in Neutron networks, such as compute and network controller nodes, at the network interfaces configured in Neutron (e.g. via WireGuard or similar solutions)."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"storage-connections",children:"Storage Connections"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"For storage backends that are connected to OpenStack over the network, the network connections between the OpenStack components and the storage backend SHOULD be located on a separate physical network with dedicated interfaces at the involved nodes."}),"\n",(0,s.jsx)(n.li,{children:"For storage backends that transfer replication data between individual storage nodes, the connections between those nodes SHOULD be implemented by a dedicated physical network."}),"\n",(0,s.jsx)(n.li,{children:"Where applicable, storage traffic between OpenStack components and the storage backend (frontend traffic) as well as storage replication traffic between storage nodes themselves (backend traffic) MAY be encrypted using the storage protocols native security features (if any) or a generic solution such as WireGuard."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.openstack.org/security-guide/",children:"OpenStack Security Guide"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/security-guide/secure-communication.html",children:"OpenStack Security Guide: Secure communication"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/security-guide/databases/database-transport-security.html",children:"OpenStack Security Guide: Database transport security"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/security-guide/messaging/security.html#messaging-transport-security",children:"OpenStack Security Guide: Messaging transport security"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/admin/secure-live-migration-with-qemu-native-tls.html",children:"Nova Documentation: Secure live migration with QEMU-native TLS"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://wiki.mozilla.org/Security/Server_Side_TLS",children:"MozillaWiki: Security / Server Side TLS"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsx)(n.p,{children:"Conformance tests are limited to communication channels exposed to users, such as the public API interfaces.\nInternal channels and APIs are currently not part of the automated conformance tests because they are not exposed and cannot be audited without direct access to the infrastructure."}),"\n",(0,s.jsxs)(n.p,{children:["There is a test suite in ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/secure-connections/tls-checker.py",children:(0,s.jsx)(n.code,{children:"tls-checker.py"})}),".\nThe test suite connects to the OpenStack API and retrieves all public API endpoints from the service catalog.\nIt then connects to each endpoint and verifies the compliance to the standard by checking SSL/TLS properties against the Mozilla TLS preset.\nPlease consult the associated ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/secure-connections/README.md",children:"README.md"})," for detailed setup and testing instructions."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var i=t(96540);const s={},r=i.createContext(s);function a(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/137a0b1a.d3bd71ef.js b/assets/js/137a0b1a.d3bd71ef.js new file mode 100644 index 0000000000..779a56bc09 --- /dev/null +++ b/assets/js/137a0b1a.d3bd71ef.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[27379],{13669:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"operating-scs/components/scs-health-monitor/Testflow","title":"Testflow-Infrastructure","description":"Quick Intro:","source":"@site/docs/04-operating-scs/components/scs-health-monitor/Testflow.md","sourceDirName":"04-operating-scs/components/scs-health-monitor","slug":"/operating-scs/components/scs-health-monitor/Testflow","permalink":"/docs/operating-scs/components/scs-health-monitor/Testflow","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/scs-health-monitor/Testflow.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Kubernetes BDD Testing Framework Documentation","permalink":"/docs/operating-scs/components/scs-health-monitor/Workflow"},"next":{"title":"Observability stack quickstart","permalink":"/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack"}}');var s=n(74848),a=n(28453);const o={},i="Testflow-Infrastructure",c={},l=[{value:"Quick Intro:",id:"quick-intro",level:2},{value:"Real Testing:",id:"real-testing",level:2},{value:"Extended Description:",id:"extended-description",level:2},{value:"Scaling the Benchmark Infrastructure",id:"scaling-the-benchmark-infrastructure",level:2}];function h(e){const t={br:"br",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"testflow-infrastructure",children:"Testflow-Infrastructure"})}),"\n",(0,s.jsx)(t.h2,{id:"quick-intro",children:"Quick Intro:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["After following the steps to set up the environment including setting up the monitornig, you should be able to start testing with ",(0,s.jsx)(t.code,{children:"./scs-health-monitor behave"})," a testing framwork. On the Cloud-Level you have several features that describe Test Scenerios for single components of the Openstack functionality, like the ",(0,s.jsx)(t.code,{children:"openstack_create_network.feature"}),".\nSo if you want to test whether you are able to create a network you can use that feature like this:"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"./scs-health-monitor behave openstack_create_network.feature\n"})}),"\n",(0,s.jsx)(t.p,{children:"or aswell:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"./scs-health-monitor behavex openstack_create_network.feature\n"})}),"\n",(0,s.jsx)(t.p,{children:"and a test on whether you are able to create a network is running."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["If you want to test whether you can create and delete all openstack resources you simply need this command (for ",(0,s.jsx)(t.code,{children:"openstack_testflow.feature"})," includes all the steps from the creation and delition features):"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"./scs-health-monitor behave openstack_testflow.feature\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The Use Case for the ",(0,s.jsx)(t.code,{children:"openstack_testflow.feature"})," and all the creation and deletion features is mostly debugging, because to run a whole infrastructure test this is not sadisfying the dependencies of the variouse resources. But you can set some parameters like the quantity of the resources, if you aim to see if you have a certain quota f.e.\nTo get a more detailed view on the test run you have the option ",(0,s.jsx)(t.code,{children:"--no-capture"})," and you will receive prints or informational logs during the test run."]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"./scs-health-monitor behave --no-capture openstack_create_network.feature\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["After the run each built resource will be deleted to avoid a ",(0,s.jsx)(t.code,{children:"DuplicateResource-Error"}),". If you should still encounter this Error, you will have to delete the resource in question by hand ether in the ",(0,s.jsx)(t.em,{children:"openstack cli tool"})," or in the ",(0,s.jsx)(t.em,{children:"plus cloud open"})," dashboard. But make sure this resource is not in use!"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"real-testing",children:"Real Testing:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["As we provide an automated Infrastructure Testing the real deal lies in the ",(0,s.jsx)(t.code,{children:"openstack_benchmark_build_infra.feature"}),". This Feature is creating all resources and configures them in order to build a complete infrastructure with virtual machine (vm) networks that are accessible through jumphosts (jh) that get certain floating ip and allow a port forwarding to the vms. That means it automatically sets up the ssh-access and the security group rules and makes sure applications like ",(0,s.jsx)(t.code,{children:"iperf3"})," are installed on the hosts. This infrastructure emulates a common openstack infrastructure and allows to run a number of benchmark tests to see whether it has the needed capacity."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:"You start an infrastructure test by:"}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"./scs-health-monitor behave openstack_benchmark_build_infra.feature\n"})}),"\n",(0,s.jsx)(t.p,{children:"or aswell:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"./scs-health-monitor behavex openstack_benchmark_build_infra.feature\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:"It will take some time but you can follow allong, if the infrastructure is builds up successfully.\nAfter the run it deletes all resources."}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["If you want run benchmarktests (which is the main goal of this approach), you will have to run the benchmark features together with the ",(0,s.jsx)(t.code,{children:"openstack_benchmark_build_infra.feature"})," like so:"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"./scs-health-monitor behave openstack_benchmark_build_infra.feature cloud_level_testing/features/openstack_benchmark_iperf3.feature cloud_level_testing/features/openstack_benchmark_pingVM.feature cloud_level_testing/features/openstack_benchmark_4000pi.feature\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The first feature always has to be the ",(0,s.jsx)(t.code,{children:"openstack_benchmark_build_infra.feature"}),". After that you can use the other features, as they only depend on the infrastructure, they don't need to follow a special order."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Note all features that fail and have a ",(0,s.jsx)(t.code,{children:"@create"})," or ",(0,s.jsx)(t.code,{children:"@delete"})," tag assigned to them will lead to a deletion of the build up resources right after the feature run. Hence if they are followed by a feature depending on those resources this feature will inevitably fail."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"extended-description",children:"Extended Description:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Our approach to use the behave-framework to build up and test an openstack infrastructure automated relies on certain peculiarities of this framework. First of all you have to understand the basic entities of a testrun:"}),"\n"]}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["1 testrun can contain multiple features",(0,s.jsx)(t.br,{}),"\n","1 feature can contain multiple steps",(0,s.jsx)(t.br,{}),"\n","1 step can contain multiple substeps"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["In the ",(0,s.jsx)(t.code,{children:"environment.py"})," you can define what actions have to be done ",(0,s.jsx)(t.br,{}),"\n",(0,s.jsx)(t.code,{children:"before_all"})," (in the beginning of the testrun), ",(0,s.jsx)(t.br,{}),"\n",(0,s.jsx)(t.code,{children:"after_feature"})," (after every feature) and ",(0,s.jsx)(t.br,{}),"\n",(0,s.jsx)(t.code,{children:"after_all"})," (in the end of the testrun)",(0,s.jsx)(t.br,{}),"\n","To calculate for exemple the total duration of the run we set the timer in the ",(0,s.jsx)(t.code,{children:"before_all"})," section and get the result in the ",(0,s.jsx)(t.code,{children:"after_all"})," section, where we also collect the metrics and push them to the prometheus gateway or delete all resources. In the ",(0,s.jsx)(t.code,{children:"after_feature"})," section, we delete ressources if a creation or deletion feature has failed."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["We tried to keep the steps and features as independent and self contained as possible. But in an infrastructure this is almost impossible, if you don't want to create monolytic steps and functions. Therefore we create an oblect called ",(0,s.jsx)(t.code,{children:"context"})," and an object called ",(0,s.jsx)(t.code,{children:"Collector"})," in the ",(0,s.jsx)(t.code,{children:"before_all"})," section. We store every information, that has to be passed between the steps into the context like the connection to the openstack client. The Collector fetches each resource-id, when a resource is created to ensure that all and only resources that were created in the test run are deleted in the end."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["However, if we run features, that rely on another feature like on the ",(0,s.jsx)(t.code,{children:"openstack_benchmark_build_infra.feature"})," the problem occures that the context attributes that are created during a feature run are deleted after each feature. Therefore we created a SharedContext Object that is already initialised ",(0,s.jsx)(t.code,{children:"before_all"})," and stores the data that is necessary for the following features like the test-prefix (context.test_name) and the floating ip and portforwarding (context.redirs).",(0,s.jsx)(t.br,{}),"\n","So in the end of ",(0,s.jsx)(t.code,{children:"openstack_benchmark_build_infra.feature"})," the following step must be performed: ",(0,s.jsx)(t.code,{children:"Then I can pass the context to another feature"})," (to store the needed information into the ",(0,s.jsx)(t.code,{children:"SharedContext"}),")\nand the following features have to begin with the step: ",(0,s.jsx)(t.code,{children:" Given I can get the shared context from previouse feature"})," (to transfer the shared informations into the new ",(0,s.jsx)(t.code,{children:"context"})," object)."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"scaling-the-benchmark-infrastructure",children:"Scaling the Benchmark Infrastructure"}),"\n",(0,s.jsxs)(t.p,{children:["First of all is the scale of the benchmark infrastructure highly dependent on the amount of ",(0,s.jsx)(t.strong,{children:"availability zones"})," in the project. The number of ",(0,s.jsx)(t.strong,{children:"availability zones determines how many jumphosts (jhs)"})," and networks are built. If there are for example two availbility zones, two jumphosts are created and and attached to a floating ip each.\\\nThe jumphosts are connected through a shared network but each of them is also ",(0,s.jsx)(t.strong,{children:"attached to another network of virtual machines (vms)"}),". The ",(0,s.jsx)(t.strong,{children:"quantity of vms"})," can be adjusted in the table of ",(0,s.jsx)(t.code,{children:"openstack_benchmark_build_infra.feature"}),". The vms can be reached from outside the network via port forwarding. Which is enabled by the jh. You can reach the vms by addressing the floating ip of the associated jh and the port number.\nThe range of the port numbers can also be specified in the ",(0,s.jsx)(t.code,{children:"openstack_benchmark_build_infra.feature"})," the default range is set from 222 to 229.",(0,s.jsx)(t.br,{}),"\n","Apart from that, you cannot change quantities because the infrastructure automatically adjusts in scale depending on the dependencies."]})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>i});var r=n(96540);const s={},a=r.createContext(s);function o(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/138e0e15.8230ceeb.js b/assets/js/138e0e15.8230ceeb.js new file mode 100644 index 0000000000..4b2c361a51 --- /dev/null +++ b/assets/js/138e0e15.8230ceeb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[64921],{41597:s=>{s.exports=JSON.parse('{"name":"@easyops-cn/docusaurus-search-local","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/14a658e6.26921b79.js b/assets/js/14a658e6.26921b79.js new file mode 100644 index 0000000000..a621763fc9 --- /dev/null +++ b/assets/js/14a658e6.26921b79.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[55235],{2582:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>l,frontMatter:()=>i,metadata:()=>n,toc:()=>u});const n=JSON.parse('{"id":"index","title":"Introduction","description":"Welcome to the User Documentation of the Sovereign Cloud Stack (SCS)","source":"@site/user-docs/index.md","sourceDirName":".","slug":"/","permalink":"/user-docs/","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"userDocs","next":{"title":"Application Examples","permalink":"/user-docs/category/application-examples"}}');var s=o(74848),c=o(28453);const i={},r="Introduction",a={},u=[{value:"Welcome to the User Documentation of the Sovereign Cloud Stack (SCS)",id:"welcome-to-the-user-documentation-of-the-sovereign-cloud-stack-scs",level:2}];function d(e){const t={h1:"h1",h2:"h2",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"introduction",children:"Introduction"})}),"\n",(0,s.jsx)(t.h2,{id:"welcome-to-the-user-documentation-of-the-sovereign-cloud-stack-scs",children:"Welcome to the User Documentation of the Sovereign Cloud Stack (SCS)"}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."})]})}function l(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,o)=>{o.d(t,{R:()=>i,x:()=>r});var n=o(96540);const s={},c=n.createContext(s);function i(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/14eb3368.bce869b4.js b/assets/js/14eb3368.bce869b4.js new file mode 100644 index 0000000000..779e2110f3 --- /dev/null +++ b/assets/js/14eb3368.bce869b4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[46969],{71243:(e,t,n)=>{n.d(t,{A:()=>g});n(96540);var s=n(18215),r=n(17559),i=n(26972),a=n(99169),l=n(28774),o=n(21312),c=n(86025),d=n(74848);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,c.Ay)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(l.A,{"aria-label":(0,o.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}const b={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function x(e){let{children:t,href:n,isLast:s}=e;const r="breadcrumbs__link";return s?(0,d.jsx)("span",{className:r,itemProp:"name",children:t}):n?(0,d.jsx)(l.A,{className:r,href:n,itemProp:"item",children:(0,d.jsx)("span",{itemProp:"name",children:t})}):(0,d.jsx)("span",{className:r,children:t})}function p(e){let{children:t,active:n,index:r,addMicrodata:i}=e;return(0,d.jsxs)("li",{...i&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,s.A)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,d.jsx)("meta",{itemProp:"position",content:String(r+1)})]})}function g(){const e=(0,i.OF)(),t=(0,a.Dt)();return e?(0,d.jsx)("nav",{className:(0,s.A)(r.G.docs.docBreadcrumbs,b.breadcrumbsContainer),"aria-label":(0,o.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,d.jsx)(h,{}),e.map(((t,n)=>{const s=n===e.length-1,r="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,d.jsx)(p,{active:s,index:n,addMicrodata:!!r,children:(0,d.jsx)(x,{href:r,isLast:s,children:t.label})},n)}))]})}):null}},34136:(e,t,n)=>{n.r(t),n.d(t,{default:()=>w});n(96540);var s=n(61213),r=n(26972),i=n(86025),a=n(18215),l=n(28774),o=n(53465),c=n(16654),d=n(21312),u=n(51107);const m={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var h=n(74848);function b(e){let{href:t,children:n}=e;return(0,h.jsx)(l.A,{href:t,className:(0,a.A)("card padding--lg",m.cardContainer),children:n})}function x(e){let{href:t,icon:n,title:s,description:r}=e;return(0,h.jsxs)(b,{href:t,children:[(0,h.jsxs)(u.A,{as:"h2",className:(0,a.A)("text--truncate",m.cardTitle),title:s,children:[n," ",s]}),r&&(0,h.jsx)("p",{className:(0,a.A)("text--truncate",m.cardDescription),title:r,children:r})]})}function p(e){let{item:t}=e;const n=(0,r.Nr)(t),s=function(){const{selectMessage:e}=(0,o.W)();return t=>e(t,(0,d.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,h.jsx)(x,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??s(t.items.length)}):null}function g(e){let{item:t}=e;const n=(0,c.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",s=(0,r.cC)(t.docId??void 0);return(0,h.jsx)(x,{href:t.href,icon:n,title:t.label,description:t.description??s?.description})}function v(e){let{item:t}=e;switch(t.type){case"link":return(0,h.jsx)(g,{item:t});case"category":return(0,h.jsx)(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const n=(0,r.$S)();return(0,h.jsx)(j,{items:n.items,className:t})}function j(e){const{items:t,className:n}=e;if(!t)return(0,h.jsx)(f,{...e});const s=(0,r.d1)(t);return(0,h.jsx)("section",{className:(0,a.A)("row",n),children:s.map(((e,t)=>(0,h.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,h.jsx)(v,{item:e})},t)))})}var A=n(27719),N=n(51878),T=n(4267),L=n(71243);const _={generatedIndexPage:"generatedIndexPage_vN6x",list:"list_eTzJ",title:"title_kItE"};function k(e){let{categoryGeneratedIndex:t}=e;return(0,h.jsx)(s.be,{title:t.title,description:t.description,keywords:t.keywords,image:(0,i.Ay)(t.image)})}function y(e){let{categoryGeneratedIndex:t}=e;const n=(0,r.$S)();return(0,h.jsxs)("div",{className:_.generatedIndexPage,children:[(0,h.jsx)(N.A,{}),(0,h.jsx)(L.A,{}),(0,h.jsx)(T.A,{}),(0,h.jsxs)("header",{children:[(0,h.jsx)(u.A,{as:"h1",className:_.title,children:t.title}),t.description&&(0,h.jsx)("p",{children:t.description})]}),(0,h.jsx)("article",{className:"margin-top--lg",children:(0,h.jsx)(j,{items:n.items,className:_.list})}),(0,h.jsx)("footer",{className:"margin-top--lg",children:(0,h.jsx)(A.A,{previous:t.navigation.previous,next:t.navigation.next})})]})}function w(e){return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(k,{...e}),(0,h.jsx)(y,{...e})]})}},27719:(e,t,n)=>{n.d(t,{A:()=>a});n(96540);var s=n(21312),r=n(39022),i=n(74848);function a(e){const{previous:t,next:n}=e;return(0,i.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,s.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,i.jsx)(r.A,{...t,subLabel:(0,i.jsx)(s.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),n&&(0,i.jsx)(r.A,{...n,subLabel:(0,i.jsx)(s.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},4267:(e,t,n)=>{n.d(t,{A:()=>o});n(96540);var s=n(18215),r=n(21312),i=n(17559),a=n(23025),l=n(74848);function o(e){let{className:t}=e;const n=(0,a.r)();return n.badge?(0,l.jsx)("span",{className:(0,s.A)(t,i.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,l.jsx)(r.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}},51878:(e,t,n)=>{n.d(t,{A:()=>p});n(96540);var s=n(18215),r=n(44586),i=n(28774),a=n(21312),l=n(44070),o=n(17559),c=n(53886),d=n(23025),u=n(74848);const m={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(a.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(a.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const t=m[e.versionMetadata.banner];return(0,u.jsx)(t,{...e})}function b(e){let{versionLabel:t,to:n,onClick:s}=e;return(0,u.jsx)(a.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(i.A,{to:n,onClick:s,children:(0,u.jsx)(a.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function x(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:i}}=(0,r.A)(),{pluginId:a}=(0,l.vT)({failfast:!0}),{savePreferredVersionName:d}=(0,c.g1)(a),{latestDocSuggestion:m,latestVersionSuggestion:x}=(0,l.HW)(a),p=m??(g=x).docs.find((e=>e.id===g.mainDocId));var g;return(0,u.jsxs)("div",{className:(0,s.A)(t,o.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:i,versionMetadata:n})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(b,{versionLabel:x.label,to:p.path,onClick:()=>d(x.name)})})]})}function p(e){let{className:t}=e;const n=(0,d.r)();return n.banner?(0,u.jsx)(x,{className:t,versionMetadata:n}):null}},39022:(e,t,n)=>{n.d(t,{A:()=>a});n(96540);var s=n(18215),r=n(28774),i=n(74848);function a(e){const{permalink:t,title:n,subLabel:a,isNext:l}=e;return(0,i.jsxs)(r.A,{className:(0,s.A)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[a&&(0,i.jsx)("div",{className:"pagination-nav__sublabel",children:a}),(0,i.jsx)("div",{className:"pagination-nav__label",children:n})]})}},53465:(e,t,n)=>{n.d(t,{W:()=>c});var s=n(96540),r=n(44586);const i=["zero","one","two","few","many","other"];function a(e){return i.filter((t=>e.includes(t)))}const l={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,r.A)();return(0,s.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:a(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),l}}),[e])}function c(){const e=o();return{selectMessage:(t,n)=>function(e,t,n){const s=e.split("|");if(1===s.length)return s[0];s.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${s.length}: ${e}`);const r=n.select(t),i=n.pluralForms.indexOf(r);return s[Math.min(i,s.length-1)]}(n,t,e)}}}}]); \ No newline at end of file diff --git a/assets/js/15857.19881860.js b/assets/js/15857.19881860.js new file mode 100644 index 0000000000..074dd98125 --- /dev/null +++ b/assets/js/15857.19881860.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[15857],{15857:(t,i,n)=>{n.d(i,{diagram:()=>o});var s=n(86079),e=(n(74353),n(16750),n(26312),n(42838),function(){var t=function(t,i,n,s){for(n=n||{},s=t.length;s--;n[t[s]]=i);return n},i=[6,9,10],n={trace:function(){},yy:{},symbols_:{error:2,start:3,info:4,document:5,EOF:6,line:7,statement:8,NL:9,showInfo:10,$accept:0,$end:1},terminals_:{2:"error",4:"info",6:"EOF",9:"NL",10:"showInfo"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,1]],performAction:function(t,i,n,s,e,r,h){switch(r.length,e){case 1:return s;case 4:break;case 6:s.setInfo(!0)}},table:[{3:1,4:[1,2]},{1:[3]},t(i,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},t(i,[2,3]),t(i,[2,4]),t(i,[2,5]),t(i,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,i){if(!i.recoverable){var n=new Error(t);throw n.hash=i,n}this.trace(t)},parse:function(t){var i=this,n=[0],s=[],e=[null],r=[],h=this.table,o="",l=0,c=0,a=r.slice.call(arguments,1),y=Object.create(this.lexer),u={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(u.yy[p]=this.yy[p]);y.setInput(t,u.yy),u.yy.lexer=y,u.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var f=y.yylloc;r.push(f);var g=y.options&&y.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,m,d,k,x,b,v,w,I,S={};;){if(m=n[n.length-1],this.defaultActions[m]?d=this.defaultActions[m]:(null==_&&(I=void 0,"number"!=typeof(I=s.pop()||y.lex()||1)&&(I instanceof Array&&(I=(s=I).pop()),I=i.symbols_[I]||I),_=I),d=h[m]&&h[m][_]),void 0===d||!d.length||!d[0]){var E="";for(x in w=[],h[m])this.terminals_[x]&&x>2&&w.push("'"+this.terminals_[x]+"'");E=y.showPosition?"Parse error on line "+(l+1)+":\n"+y.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==_?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(E,{text:y.match,token:this.terminals_[_]||_,line:y.yylineno,loc:f,expected:w})}if(d[0]instanceof Array&&d.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+_);switch(d[0]){case 1:n.push(_),e.push(y.yytext),r.push(y.yylloc),n.push(d[1]),_=null,c=y.yyleng,o=y.yytext,l=y.yylineno,f=y.yylloc;break;case 2:if(b=this.productions_[d[1]][1],S.$=e[e.length-b],S._$={first_line:r[r.length-(b||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(b||1)].first_column,last_column:r[r.length-1].last_column},g&&(S._$.range=[r[r.length-(b||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,c,l,u.yy,d[1],e,r].concat(a))))return k;b&&(n=n.slice(0,-1*b*2),e=e.slice(0,-1*b),r=r.slice(0,-1*b)),n.push(this.productions_[d[1]][0]),e.push(S.$),r.push(S._$),v=h[n[n.length-2]][n[n.length-1]],n.push(v);break;case 3:return!0}}return!0}},s={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)},setInput:function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var i=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===s.length?this.yylloc.first_column:0)+s[s.length-n.length].length-n[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[e[0],e[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"},test_match:function(t,i){var n,s,e;if(this.options.backtrack_lexer&&(e={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(e.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in e)this[r]=e[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,n,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var e=this._currentRules(),r=0;ri[0].length)){if(i=n,s=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,e[r])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,e[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,n,s){switch(n){case 0:return 4;case 1:return 9;case 2:return"space";case 3:return 10;case 4:return 6;case 5:return"TXT"}},rules:[/^(?:info\b)/i,/^(?:[\s\n\r]+)/i,/^(?:[\s]+)/i,/^(?:showInfo\b)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5],inclusive:!0}}};function e(){this.yy={}}return n.lexer=s,e.prototype=n,n.Parser=e,new e}());e.parser=e;const r=!1;let h=r;const o={parser:e,db:{clear:()=>{h=r},setInfo:t=>{h=t},getInfo:()=>h},renderer:{draw:(t,i,n)=>{s.l.debug("rendering info diagram\n"+t);const e=(0,s.A)(i);(0,s.i)(e,100,400,!0);e.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${n}`)}}}}}]); \ No newline at end of file diff --git a/assets/js/15e4a743.7be84146.js b/assets/js/15e4a743.7be84146.js new file mode 100644 index 0000000000..e0f61f4005 --- /dev/null +++ b/assets/js/15e4a743.7be84146.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[85609],{45155:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"operating-scs/monitoring/index","title":"Overview","description":"TODO","source":"@site/docs/04-operating-scs/02-monitoring/index.md","sourceDirName":"04-operating-scs/02-monitoring","slug":"/operating-scs/monitoring/","permalink":"/docs/operating-scs/monitoring/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/02-monitoring/index.md","tags":[],"version":"current","frontMatter":{}}');var r=t(74848),s=t(28453);const i={},c="Overview",a={},d=[];function u(e){const n={h1:"h1",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(n.p,{children:"TODO"})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>c});var o=t(96540);const r={},s=o.createContext(r);function i(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/16c50622.0126b3da.js b/assets/js/16c50622.0126b3da.js new file mode 100644 index 0000000000..313060ca34 --- /dev/null +++ b/assets/js/16c50622.0126b3da.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[14712],{36703:(i,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>d,default:()=>l,frontMatter:()=>a,metadata:()=>t,toc:()=>r});const t=JSON.parse('{"id":"iaas/guides/configuration-guide/validations/index","title":"Validations","description":"This section contains the documentation of the Ansible collection","source":"@site/docs/02-iaas/guides/configuration-guide/validations/index.md","sourceDirName":"02-iaas/guides/configuration-guide/validations","slug":"/iaas/guides/configuration-guide/validations/","permalink":"/docs/iaas/guides/configuration-guide/validations/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/validations/index.md","tags":[],"version":"current","sidebarPosition":50,"frontMatter":{"sidebar_label":"Validations","sidebar_position":50},"sidebar":"docs","previous":{"title":"Tuned","permalink":"/docs/iaas/guides/configuration-guide/services/tuned"},"next":{"title":"Operations Guide","permalink":"/docs/iaas/guides/operations-guide/"}}');var s=n(74848),o=n(28453);const a={sidebar_label:"Validations",sidebar_position:50},d="Validations",c={},r=[];function u(i){const e={a:"a",h1:"h1",header:"header",p:"p",...(0,o.R)(),...i.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.header,{children:(0,s.jsx)(e.h1,{id:"validations",children:"Validations"})}),"\n",(0,s.jsxs)(e.p,{children:["This section contains the documentation of the Ansible collection\n",(0,s.jsx)(e.a,{href:"https://github.com/osism/ansible-collection-validations",children:"osism.validations"}),"."]})]})}function l(i={}){const{wrapper:e}={...(0,o.R)(),...i.components};return e?(0,s.jsx)(e,{...i,children:(0,s.jsx)(u,{...i})}):u(i)}},28453:(i,e,n)=>{n.d(e,{R:()=>a,x:()=>d});var t=n(96540);const s={},o=t.createContext(s);function a(i){const e=t.useContext(o);return t.useMemo((function(){return"function"==typeof i?i(e):{...e,...i}}),[e,i])}function d(i){let e;return e=i.disableParentContext?"function"==typeof i.components?i.components(s):i.components||s:a(i.components),t.createElement(o.Provider,{value:e},i.children)}}}]); \ No newline at end of file diff --git a/assets/js/16ee6b7c.283ab39f.js b/assets/js/16ee6b7c.283ab39f.js new file mode 100644 index 0000000000..4d18de29d6 --- /dev/null +++ b/assets/js/16ee6b7c.283ab39f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[34826],{40227:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Guides","slug":"/category/guides-2","permalink":"/docs/category/guides-2","sidebar":"docs","navigation":{"previous":{"title":"Introduction on Identity Management and Federation in SCS","permalink":"/docs/iam/"},"next":{"title":"Domain Manager setup and usage","permalink":"/docs/iam/domain-manager-setup-and-usage"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/1722e234.0a4fa590.js b/assets/js/1722e234.0a4fa590.js new file mode 100644 index 0000000000..dfb9bef957 --- /dev/null +++ b/assets/js/1722e234.0a4fa590.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[71255],{16888:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>j,frontMatter:()=>c,metadata:()=>d,toc:()=>h});const d=JSON.parse('{"id":"cloud-resources/cloud-resources","title":"Test and development cloud resources","description":"This document gives an overview of the test and development cloud resources currently provided by our partners.","source":"@site/community/cloud-resources/cloud-resources.md","sourceDirName":"cloud-resources","slug":"/cloud-resources/","permalink":"/community/cloud-resources/","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Tips and Tricks","permalink":"/community/tools/github/tips-and-tricks"},"next":{"title":"Getting Started with OpenStack","permalink":"/community/cloud-resources/getting-started-openstack"}}');var s=n(74848),r=n(28453);const c={},l="Test and development cloud resources",i={},h=[{value:"How to request cloud resources",id:"how-to-request-cloud-resources",level:2},{value:"plusserver",id:"plusserver",level:2},{value:"Usage",id:"usage",level:3},{value:"Users",id:"users",level:3},{value:"Service Users",id:"service-users",level:3},{value:"Projects",id:"projects",level:3},{value:"Wavecon",id:"wavecon",level:2},{value:"Service Users",id:"service-users-1",level:3},{value:"Projects",id:"projects-1",level:3}];function x(e){const t={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"test-and-development-cloud-resources",children:"Test and development cloud resources"})}),"\n",(0,s.jsx)(t.p,{children:"This document gives an overview of the test and development cloud resources currently provided by our partners."}),"\n",(0,s.jsx)(t.h2,{id:"how-to-request-cloud-resources",children:"How to request cloud resources"}),"\n",(0,s.jsxs)(t.p,{children:["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 ",(0,s.jsx)(t.code,{children:"Unique Identifier"})," blank) and assign it to the particular CSP team (e.g. @SovereignCloudStack/plusserver, @SovereignCloudStack/wavecon, ...)"]}),"\n",(0,s.jsx)(t.h2,{id:"plusserver",children:"plusserver"}),"\n",(0,s.jsx)(t.h3,{id:"usage",children:"Usage"}),"\n",(0,s.jsxs)(t.p,{children:["A brief guide on how to use the resources provided by plusserver GmbH can be found ",(0,s.jsx)(t.a,{href:"/community/cloud-resources/plusserver-gx-scs",children:"here"})]}),"\n",(0,s.jsx)(t.h3,{id:"users",children:"Users"}),"\n",(0,s.jsxs)(t.p,{children:["As suggested in ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/issues/155",children:"#155"}),' the username for non-"service users" will contain the users github handle and are prefixed with a plusserver default.\n',(0,s.jsx)(t.code,{children:"prefix-<$github handle>"})]}),"\n",(0,s.jsxs)(t.blockquote,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Note"}),"\nATM this is not directly connected to the SovereignCloudStack github org membership, accounts will be created manually for now."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Example:"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"github handle"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"plusserver login"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"frosty-geek"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"u500924-frosty-geek"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"fkr"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"u500924-fkr"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]})]})]}),"\n",(0,s.jsxs)(t.blockquote,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Note"}),"\nTo easy collaboration & transparency within the SCS team all users will have their default_project_id set to ",(0,s.jsx)(t.code,{children:"p500924-scs-community"})," by default and will have full access on all projects listed below."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"service-users",children:"Service Users"}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"Unique Identifier"}),(0,s.jsx)(t.th,{children:"Service User Name"}),(0,s.jsx)(t.th,{children:"Full Access on"}),(0,s.jsx)(t.th,{children:"Community Contact"}),(0,s.jsx)(t.th,{children:"Description"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"Needed until"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"9a1576af59644a2dbbace773ad17158d"}),(0,s.jsx)(t.td,{children:"u500924-svc-sig-monitoring"}),(0,s.jsx)(t.td,{children:"p500924-sig-monitoring1"}),(0,s.jsx)(t.td,{children:"fkr"}),(0,s.jsx)(t.td,{children:"Service User - SIG Monitoring"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"31.12.2023"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"4925967416894fd78be6701689059653"}),(0,s.jsx)(t.td,{children:"u500924-svc-cloudmon"}),(0,s.jsx)(t.td,{children:"p500924-cloudmon-target"}),(0,s.jsx)(t.td,{children:"Erik-Kostelansky-dNation"}),(0,s.jsx)(t.td,{children:"Service User - VP12 Test Project"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"31.12.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"f89b3d64ddff4d9d8cadb5e06fa22299"}),(0,s.jsx)(t.td,{children:"u500924-svc-healthmonitor"}),(0,s.jsx)(t.td,{children:"p500924-scs-healthmonitor"}),(0,s.jsx)(t.td,{children:"garloff"}),(0,s.jsx)(t.td,{children:"Service User - SCS Health Monitor"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"49cc3d72fbdf41fe8dc407f57f026dbf"}),(0,s.jsx)(t.td,{children:"u500924-svc-standards"}),(0,s.jsx)(t.td,{children:"p500924-scs-healthmonitor"}),(0,s.jsx)(t.td,{children:"garloff"}),(0,s.jsx)(t.td,{children:"Service User - SCS Standards Compliance Check"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"1b6bb583fc5e40e49f2a7e9b4301de65"}),(0,s.jsx)(t.td,{children:"u500924-svc-zuul"}),(0,s.jsx)(t.td,{children:"p500924-scs-zuul"}),(0,s.jsx)(t.td,{children:"o-otte"}),(0,s.jsx)(t.td,{children:"Service User - SCS Zuul"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.11.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{}),(0,s.jsx)(t.td,{}),(0,s.jsx)(t.td,{}),(0,s.jsx)(t.td,{}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]})]})]}),"\n",(0,s.jsx)(t.h3,{id:"projects",children:"Projects"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"Unique Identifier"}),(0,s.jsx)(t.th,{children:"Project Name"}),(0,s.jsx)(t.th,{children:"Community Contact"}),(0,s.jsx)(t.th,{children:"Description"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"Needed until"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"2237c767cf5f456da19359ed31c1c16b"}),(0,s.jsx)(t.td,{children:"p500924-scs-community"}),(0,s.jsx)(t.td,{children:"fkr"}),(0,s.jsx)(t.td,{children:"SCS Community Project"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"b43cfafbcf1f4eb08865b2886c29e09b"}),(0,s.jsx)(t.td,{children:"p500924-cluster-api-session"}),(0,s.jsx)(t.td,{children:"garloff"}),(0,s.jsx)(t.td,{children:"cluster-api hands on session"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"9b7a73e516be4cd1acbd63d543985c52"}),(0,s.jsx)(t.td,{children:"p500924-gonicus-dev"}),(0,s.jsx)(t.td,{children:"o-otte"}),(0,s.jsx)(t.td,{children:"GONICUS GmbH"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"3829cc7c8f034fc985f5055a1df6f247"}),(0,s.jsx)(t.td,{children:"p500924-scs-healthmonitor"}),(0,s.jsx)(t.td,{children:"garloff"}),(0,s.jsx)(t.td,{children:"SCS Health Monitor"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"b97d38bf128b4479981c4dbe2ef70cd5"}),(0,s.jsx)(t.td,{children:"p500924-SIG-IAM"}),(0,s.jsx)(t.td,{children:"fkr"}),(0,s.jsx)(t.td,{children:"SIG IAM and VP08"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"9de7d8dc2d674e52be44904d6b338b0b"}),(0,s.jsx)(t.td,{children:"p500924-cloudmon"}),(0,s.jsx)(t.td,{children:"Erik-Kostelansky-dNation"}),(0,s.jsx)(t.td,{children:"VP12 Test Project"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"31.12.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"2c9e0e4ef8d44c36807df50b06b3c81d"}),(0,s.jsx)(t.td,{children:"p500924-cloudmon-target"}),(0,s.jsx)(t.td,{children:"Erik-Kostelansky-dNation"}),(0,s.jsx)(t.td,{children:"Target project for VP12 tests"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"31.12.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"3501db829014406884990a1016f3e25d"}),(0,s.jsx)(t.td,{children:"p500924-sig-monitoring1"}),(0,s.jsx)(t.td,{children:"fkr"}),(0,s.jsx)(t.td,{children:"SIG Monitoring - cloudmon target"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"602778bad3d3470cbe58c4f7611e8eb7"}),(0,s.jsx)(t.td,{children:"p500924-dnation"}),(0,s.jsx)(t.td,{children:"chess-knight"}),(0,s.jsx)(t.td,{children:"dNation dev for VP06c"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"91091d4039a6457db27d48d58bb1b4e4"}),(0,s.jsx)(t.td,{children:"p500924-jschoone"}),(0,s.jsx)(t.td,{children:"jschoone"}),(0,s.jsx)(t.td,{children:"KaaS dev and evaluation"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"93956190702b4a7d8a8886806d57713f"}),(0,s.jsx)(t.td,{children:"p500924-metering"}),(0,s.jsx)(t.td,{children:"cah-link"}),(0,s.jsx)(t.td,{children:"Dev Environment for VP13"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"31.12.2023"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"abbe6561cf6248b6af395334aa09af85"}),(0,s.jsx)(t.td,{children:"p500924-harbor"}),(0,s.jsx)(t.td,{children:"chess-knight"}),(0,s.jsx)(t.td,{children:"SCS Harbor for VP06c"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"e7622c1048ac4520a2d050ae141e826b"}),(0,s.jsx)(t.td,{children:"p500924-tender-6a"}),(0,s.jsx)(t.td,{children:"mxmxchere"}),(0,s.jsx)(t.td,{children:"Dev Environment for VP06a"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"eeed7e0ad33f42f189fb4165116f5a1b"}),(0,s.jsx)(t.td,{children:"p500924-dnation-k8s"}),(0,s.jsx)(t.td,{children:"matofeder"}),(0,s.jsx)(t.td,{children:"dNation dev for VP06c"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"b342f37804f14459bdf703573169bf79"}),(0,s.jsx)(t.td,{children:"p500924-minery"}),(0,s.jsx)(t.td,{children:"90n20"}),(0,s.jsx)(t.td,{children:"Testbed env for Pentesting"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.11.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"0fa3c3559f0d4f39ba7aa70c7f7188ca"}),(0,s.jsx)(t.td,{children:"p500924-tender-10-3"}),(0,s.jsx)(t.td,{children:"tonifinger"}),(0,s.jsx)(t.td,{children:"Dev Environment for VP10-3"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"b682eb90fb834278afb1182018dd2133"}),(0,s.jsx)(t.td,{children:"p500924-scoopex"}),(0,s.jsx)(t.td,{children:"scoopex"}),(0,s.jsx)(t.td,{children:"Marc's gx-scs project"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"021af0688c594bf88ed675b942d3bea8"}),(0,s.jsx)(t.td,{children:"p500924-gx-cred-generator"}),(0,s.jsx)(t.td,{children:"anjastrunk"}),(0,s.jsx)(t.td,{children:"SCS Gaia-X Self-Description Generator"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"a07c811315ad40f585945b2939ef12dd"}),(0,s.jsx)(t.td,{children:"p500924-scs-zuul"}),(0,s.jsx)(t.td,{children:"o-otte"}),(0,s.jsx)(t.td,{children:"SCS Zuul"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.11.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"1846709967a744b69f9eb48cac89bb04"}),(0,s.jsx)(t.td,{children:"p500924-scs-k8s-e2e"}),(0,s.jsx)(t.td,{children:"chess-knight"}),(0,s.jsx)(t.td,{children:"E2E-Test for KaaS"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"6ee4b373cb6d42a5bb59d5080987b70d"}),(0,s.jsx)(t.td,{children:"p500924-bitkeks"}),(0,s.jsx)(t.td,{children:"bitkeks"}),(0,s.jsx)(t.td,{children:"Cluster Stacks and Sec"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"4ea22ba875474d039cb57d20b7f710b5"}),(0,s.jsx)(t.td,{children:"p500924-kaas-playground0"}),(0,s.jsx)(t.td,{children:"jschoone"}),(0,s.jsx)(t.td,{children:"Playground0 for Hackathon"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"476672f1023b4bac8837f95a76881757"}),(0,s.jsx)(t.td,{children:"p500924-kaas-playground1"}),(0,s.jsx)(t.td,{children:"jschoone"}),(0,s.jsx)(t.td,{children:"Playground1 for Hackathon"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"04dac2927f744479a5d4c23dd0a3c378"}),(0,s.jsx)(t.td,{children:"p500924-kaas-playground2"}),(0,s.jsx)(t.td,{children:"jschoone"}),(0,s.jsx)(t.td,{children:"Playground2 for Hackathon"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"75279777029847ab9b399390c0dd6042"}),(0,s.jsx)(t.td,{children:"p500924-kaas-playground3"}),(0,s.jsx)(t.td,{children:"jschoone"}),(0,s.jsx)(t.td,{children:"Playground3 for Hackathon"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"0b3c75f80b6743778daccec0da423465"}),(0,s.jsx)(t.td,{children:"p500924-kaas-playground4"}),(0,s.jsx)(t.td,{children:"jschoone"}),(0,s.jsx)(t.td,{children:"Playground4 for Hackathon"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"2340a73644ca47189329061e9c2a0bfe"}),(0,s.jsx)(t.td,{children:"p500924-kaas-playground5"}),(0,s.jsx)(t.td,{children:"jschoone"}),(0,s.jsx)(t.td,{children:"Playground5 for Hackathon"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"3c5bae4a233c4a9d8ae2e4b799d757c9"}),(0,s.jsx)(t.td,{children:"p500924-kaas-playground6"}),(0,s.jsx)(t.td,{children:"jschoone"}),(0,s.jsx)(t.td,{children:"Playground6 for Hackathon"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"03783b4952344c849af37d26818d19f0"}),(0,s.jsx)(t.td,{children:"p500924-kaas-playground7"}),(0,s.jsx)(t.td,{children:"jschoone"}),(0,s.jsx)(t.td,{children:"Playground7 for Hackathon"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"5c6d4d7183834eafbc20108ad647a9c0"}),(0,s.jsx)(t.td,{children:"p500924-kaas-playground8"}),(0,s.jsx)(t.td,{children:"jschoone"}),(0,s.jsx)(t.td,{children:"Playground8 for Hackathon"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"7e18881932f749baa7d547ebd407b8d8"}),(0,s.jsx)(t.td,{children:"p500924-kaas-playground9"}),(0,s.jsx)(t.td,{children:"jschoone"}),(0,s.jsx)(t.td,{children:"Playground9 for Hackathon"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"d9dc2f33e76240219db484526e9f601d"}),(0,s.jsx)(t.td,{children:"p500924-akafazov"}),(0,s.jsx)(t.td,{children:"akafazov"}),(0,s.jsx)(t.td,{children:"akafazov Testbed"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"30.04.2024"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"b07ad6a84982471b9a344ef9947f0e0f"}),(0,s.jsx)(t.td,{children:"p500924-gtema"}),(0,s.jsx)(t.td,{children:"gtema"}),(0,s.jsx)(t.td,{children:"Testbed for gtema"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"e89ac8c9f66f46b5a983b2a05d2a66ec"}),(0,s.jsx)(t.td,{children:"p500924-zuse-z3"}),(0,s.jsx)(t.td,{children:"zuse-z3"}),(0,s.jsx)(t.td,{children:"Josefine's gx-scs project"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"fc1f7a0e10a64d6083dcdbcb7ccf6ff4"}),(0,s.jsx)(t.td,{children:"p500924-compliance-monitor"}),(0,s.jsx)(t.td,{children:"mbuechse"}),(0,s.jsx)(t.td,{children:"SCS Compliance Monitor Deployment"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"eba5414a4f8549b28a62af199d82dab5"}),(0,s.jsx)(t.td,{children:"p500924-tsmado"}),(0,s.jsx)(t.td,{children:"tsmado"}),(0,s.jsx)(t.td,{children:"tsmado's gx-scs project"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]})]})]}),"\n",(0,s.jsx)(t.h2,{id:"wavecon",children:"Wavecon"}),"\n",(0,s.jsx)(t.h3,{id:"service-users-1",children:"Service Users"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"Unique Identifier"}),(0,s.jsx)(t.th,{children:"Service User Name"}),(0,s.jsx)(t.th,{children:"Full Access on"}),(0,s.jsx)(t.th,{children:"Community Contact"}),(0,s.jsx)(t.th,{children:"Description"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"Needed until"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"df4af5376bbd4de587c4335622149be7"}),(0,s.jsx)(t.td,{children:"scs-standards"}),(0,s.jsx)(t.td,{children:"scs-standards"}),(0,s.jsx)(t.td,{children:"itrich"}),(0,s.jsx)(t.td,{children:"Service User - SCS Standards Compliance Check"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]})})]}),"\n",(0,s.jsx)(t.h3,{id:"projects-1",children:"Projects"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"Unique Identifier"}),(0,s.jsx)(t.th,{children:"Project Name"}),(0,s.jsx)(t.th,{children:"Community Contact"}),(0,s.jsx)(t.th,{children:"Description"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:"Needed until"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"718964b4b87446688ac04b151519fb51"}),(0,s.jsx)(t.td,{children:"scs"}),(0,s.jsx)(t.td,{children:"garloff"}),(0,s.jsx)(t.td,{children:"SCS Health Monitor"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"c46ccc9e695c4b23bacee2ad11145d9a"}),(0,s.jsx)(t.td,{children:"scs-health-monitor"}),(0,s.jsx)(t.td,{children:"garloff"}),(0,s.jsx)(t.td,{children:"SCS Health Monitor"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"00de553df86949b49365baee6375fb5a"}),(0,s.jsx)(t.td,{children:"scs-standards"}),(0,s.jsx)(t.td,{children:"itrich"}),(0,s.jsx)(t.td,{children:"SCS Health Monitor"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]})]})]})]})}function j(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(x,{...e})}):x(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>l});var d=n(96540);const s={},r=d.createContext(s);function c(e){const t=d.useContext(r);return d.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),d.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/17896441.6f5cb6f8.js b/assets/js/17896441.6f5cb6f8.js new file mode 100644 index 0000000000..e50f1ccd27 --- /dev/null +++ b/assets/js/17896441.6f5cb6f8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[18401],{32234:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var s=n(18215),a=n(44084),i=n(17559),o=n(27293),l=n(74848);function r(e){let{className:t}=e;return(0,l.jsx)(o.A,{type:"caution",title:(0,l.jsx)(a.Rc,{}),className:(0,s.A)(t,i.G.common.unlistedBanner),children:(0,l.jsx)(a.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(a.AE,{}),(0,l.jsx)(r,{...e})]})}},41689:(e,t,n)=>{n.d(t,{A:()=>d});n(96540);var s=n(18215),a=n(44084),i=n(17559),o=n(27293),l=n(74848);function r(e){let{className:t}=e;return(0,l.jsx)(o.A,{type:"caution",title:(0,l.jsx)(a.Yh,{}),className:(0,s.A)(t,i.G.common.draftBanner),children:(0,l.jsx)(a.TT,{})})}var c=n(32234);function d(e){let{metadata:t}=e;const{unlisted:n,frontMatter:s}=t;return(0,l.jsxs)(l.Fragment,{children:[(n||s.unlisted)&&(0,l.jsx)(c.A,{}),s.draft&&(0,l.jsx)(r,{})]})}},71243:(e,t,n)=>{n.d(t,{A:()=>f});n(96540);var s=n(18215),a=n(17559),i=n(26972),o=n(99169),l=n(28774),r=n(21312),c=n(86025),d=n(74848);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,c.Ay)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(l.A,{"aria-label":(0,r.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}const v={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function b(e){let{children:t,href:n,isLast:s}=e;const a="breadcrumbs__link";return s?(0,d.jsx)("span",{className:a,itemProp:"name",children:t}):n?(0,d.jsx)(l.A,{className:a,href:n,itemProp:"item",children:(0,d.jsx)("span",{itemProp:"name",children:t})}):(0,d.jsx)("span",{className:a,children:t})}function x(e){let{children:t,active:n,index:a,addMicrodata:i}=e;return(0,d.jsxs)("li",{...i&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,s.A)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,d.jsx)("meta",{itemProp:"position",content:String(a+1)})]})}function f(){const e=(0,i.OF)(),t=(0,o.Dt)();return e?(0,d.jsx)("nav",{className:(0,s.A)(a.G.docs.docBreadcrumbs,v.breadcrumbsContainer),"aria-label":(0,r.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,d.jsx)(h,{}),e.map(((t,n)=>{const s=n===e.length-1,a="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,d.jsx)(x,{active:s,index:n,addMicrodata:!!a,children:(0,d.jsx)(b,{href:a,isLast:s,children:t.label})},n)}))]})}):null}},30833:(e,t,n)=>{n.r(t),n.d(t,{default:()=>P});var s=n(96540),a=n(61213),i=n(89532),o=n(74848);const l=s.createContext(null);function r(e){let{children:t,content:n}=e;const a=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return(0,o.jsx)(l.Provider,{value:a,children:t})}function c(){const e=(0,s.useContext)(l);if(null===e)throw new i.dV("DocProvider");return e}function d(){const{metadata:e,frontMatter:t,assets:n}=c();return(0,o.jsx)(a.be,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var u=n(18215),m=n(24581),h=n(27719);function v(){const{metadata:e}=c();return(0,o.jsx)(h.A,{previous:e.previous,next:e.next})}var b=n(51878),x=n(4267),f=n(17559),p=n(62053),g=n(4336);function j(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s,tags:a}=e,i=a.length>0,l=!!(t||n||s);return i||l?(0,o.jsxs)("footer",{className:(0,u.A)(f.G.docs.docFooter,"docusaurus-mt-lg"),children:[i&&(0,o.jsx)("div",{className:(0,u.A)("row margin-top--sm",f.G.docs.docFooterTagsRow),children:(0,o.jsx)("div",{className:"col",children:(0,o.jsx)(p.A,{tags:a})})}),l&&(0,o.jsx)(g.A,{className:(0,u.A)("margin-top--sm",f.G.docs.docFooterEditMetaRow),editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s})]}):null}var A=n(41422),L=n(65195),C=n(21312);const N={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function T(e){let{collapsed:t,...n}=e;return(0,o.jsx)("button",{type:"button",...n,className:(0,u.A)("clean-btn",N.tocCollapsibleButton,!t&&N.tocCollapsibleButtonExpanded,n.className),children:(0,o.jsx)(C.A,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const _={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function k(e){let{toc:t,className:n,minHeadingLevel:s,maxHeadingLevel:a}=e;const{collapsed:i,toggleCollapsed:l}=(0,A.u)({initialState:!0});return(0,o.jsxs)("div",{className:(0,u.A)(_.tocCollapsible,!i&&_.tocCollapsibleExpanded,n),children:[(0,o.jsx)(T,{collapsed:i,onClick:l}),(0,o.jsx)(A.N,{lazy:!0,className:_.tocCollapsibleContent,collapsed:i,children:(0,o.jsx)(L.A,{toc:t,minHeadingLevel:s,maxHeadingLevel:a})})]})}const H={tocMobile:"tocMobile_ITEo"};function M(){const{toc:e,frontMatter:t}=c();return(0,o.jsx)(k,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,u.A)(f.G.docs.docTocMobile,H.tocMobile)})}var y=n(67763);function B(){const{toc:e,frontMatter:t}=c();return(0,o.jsx)(y.A,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:f.G.docs.docTocDesktop})}var I=n(51107),w=n(11544);function E(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return(0,o.jsxs)("div",{className:(0,u.A)(f.G.docs.docMarkdown,"markdown"),children:[n&&(0,o.jsx)("header",{children:(0,o.jsx)(I.A,{as:"h1",children:n})}),(0,o.jsx)(w.A,{children:t})]})}var V=n(71243),O=n(41689);const G={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function S(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.l)(),s=e.hide_table_of_contents,a=!s&&t.length>0;return{hidden:s,mobile:a?(0,o.jsx)(M,{}):void 0,desktop:!a||"desktop"!==n&&"ssr"!==n?void 0:(0,o.jsx)(B,{})}}(),{metadata:s}=c();return(0,o.jsxs)("div",{className:"row",children:[(0,o.jsxs)("div",{className:(0,u.A)("col",!n.hidden&&G.docItemCol),children:[(0,o.jsx)(O.A,{metadata:s}),(0,o.jsx)(b.A,{}),(0,o.jsxs)("div",{className:G.docItemContainer,children:[(0,o.jsxs)("article",{children:[(0,o.jsx)(V.A,{}),(0,o.jsx)(x.A,{}),n.mobile,(0,o.jsx)(E,{children:t}),(0,o.jsx)(j,{})]}),(0,o.jsx)(v,{})]})]}),n.desktop&&(0,o.jsx)("div",{className:"col col--3",children:n.desktop})]})}function P(e){const t=`docs-doc-id-${e.content.metadata.id}`,n=e.content;return(0,o.jsx)(r,{content:e.content,children:(0,o.jsxs)(a.e3,{className:t,children:[(0,o.jsx)(d,{}),(0,o.jsx)(S,{children:(0,o.jsx)(n,{})})]})})}},27719:(e,t,n)=>{n.d(t,{A:()=>o});n(96540);var s=n(21312),a=n(39022),i=n(74848);function o(e){const{previous:t,next:n}=e;return(0,i.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,s.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,i.jsx)(a.A,{...t,subLabel:(0,i.jsx)(s.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),n&&(0,i.jsx)(a.A,{...n,subLabel:(0,i.jsx)(s.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},4267:(e,t,n)=>{n.d(t,{A:()=>r});n(96540);var s=n(18215),a=n(21312),i=n(17559),o=n(23025),l=n(74848);function r(e){let{className:t}=e;const n=(0,o.r)();return n.badge?(0,l.jsx)("span",{className:(0,s.A)(t,i.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,l.jsx)(a.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}},51878:(e,t,n)=>{n.d(t,{A:()=>x});n(96540);var s=n(18215),a=n(44586),i=n(28774),o=n(21312),l=n(44070),r=n(17559),c=n(53886),d=n(23025),u=n(74848);const m={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(o.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(o.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const t=m[e.versionMetadata.banner];return(0,u.jsx)(t,{...e})}function v(e){let{versionLabel:t,to:n,onClick:s}=e;return(0,u.jsx)(o.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(i.A,{to:n,onClick:s,children:(0,u.jsx)(o.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function b(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:i}}=(0,a.A)(),{pluginId:o}=(0,l.vT)({failfast:!0}),{savePreferredVersionName:d}=(0,c.g1)(o),{latestDocSuggestion:m,latestVersionSuggestion:b}=(0,l.HW)(o),x=m??(f=b).docs.find((e=>e.id===f.mainDocId));var f;return(0,u.jsxs)("div",{className:(0,s.A)(t,r.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:i,versionMetadata:n})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(v,{versionLabel:b.label,to:x.path,onClick:()=>d(b.name)})})]})}function x(e){let{className:t}=e;const n=(0,d.r)();return n.banner?(0,u.jsx)(b,{className:t,versionMetadata:n}):null}},67763:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var s=n(18215),a=n(65195);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var o=n(74848);const l="table-of-contents__link toc-highlight",r="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,o.jsx)("div",{className:(0,s.A)(i.tableOfContents,"thin-scrollbar",t),children:(0,o.jsx)(a.A,{...n,linkClassName:l,linkActiveClassName:r})})}},65195:(e,t,n)=>{n.d(t,{A:()=>b});var s=n(96540),a=n(6342);function i(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const s=n.slice(2,e.level);e.parentIndex=Math.max(...s),n[e.level]=t}));const s=[];return t.forEach((e=>{const{parentIndex:n,...a}=e;n>=0?t[n].children.push(a):s.push(a)})),s}function o(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return t.flatMap((e=>{const t=o({toc:e.children,minHeadingLevel:n,maxHeadingLevel:s});return function(e){return e.level>=n&&e.level<=s}(e)?[{...e,children:t}]:t}))}function l(e){const t=e.getBoundingClientRect();return t.top===t.bottom?l(e.parentNode):t}function r(e,t){let{anchorTopOffset:n}=t;const s=e.find((e=>l(e).top>=n));if(s){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,s.useRef)(void 0),n=c();(0,s.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:a,minHeadingLevel:i,maxHeadingLevel:o}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),l=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const s=[];for(let a=t;a<=n;a+=1)s.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(s.join()))}({minHeadingLevel:i,maxHeadingLevel:o}),c=r(l,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(a),e.classList.add(a),t.current=e):e.classList.remove(a)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}var u=n(28774),m=n(74848);function h(e){let{toc:t,className:n,linkClassName:s,isChild:a}=e;return t.length?(0,m.jsx)("ul",{className:a?void 0:n,children:t.map((e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.A,{to:`#${e.id}`,className:s??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:s})]},e.id)))}):null}const v=s.memo(h);function b(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:l="table-of-contents__link",linkActiveClassName:r,minHeadingLevel:c,maxHeadingLevel:u,...h}=e;const b=(0,a.p)(),x=c??b.tableOfContents.minHeadingLevel,f=u??b.tableOfContents.maxHeadingLevel,p=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,s.useMemo)((()=>o({toc:i(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:x,maxHeadingLevel:f});return d((0,s.useMemo)((()=>{if(l&&r)return{linkClassName:l,linkActiveClassName:r,minHeadingLevel:x,maxHeadingLevel:f}}),[l,r,x,f])),(0,m.jsx)(v,{toc:p,className:n,linkClassName:l,...h})}},44084:(e,t,n)=>{n.d(t,{AE:()=>r,Rc:()=>o,TT:()=>d,Uh:()=>l,Yh:()=>c});n(96540);var s=n(21312),a=n(5260),i=n(74848);function o(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function r(){return(0,i.jsx)(a.A,{children:(0,i.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}}}]); \ No newline at end of file diff --git a/assets/js/178df98e.ed94b47d.js b/assets/js/178df98e.ed94b47d.js new file mode 100644 index 0000000000..d359a19447 --- /dev/null +++ b/assets/js/178df98e.ed94b47d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[98029],{93784:(e,s,t)=>{t.r(s),t.d(s,{TableCellStyleApplier:()=>l,assets:()=>o,contentTitle:()=>c,default:()=>j,frontMatter:()=>i,metadata:()=>n,toc:()=>h});const n=JSON.parse('{"id":"ops/index","title":"Ops Standards","description":"Operational Tooling Standards cover the protocols and guidelines associated with tools and utilities used for monitoring, management, and maintenance of the cloud environment. This includes standards for status pages, alerts, logs, and other operational tools, aiming to optimize the reliability, performance, and security of cloud services and resources.","source":"@site/standards/ops/index.md","sourceDirName":"ops","slug":"/ops/","permalink":"/standards/ops/","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0302-w1-domain-manager-implementation-notes"},"next":{"title":"scs-0400: Status Page create decision","permalink":"/standards/ops/scs-0400"}}');var r=t(74848),d=t(28453),a=t(96540);const i={},c="Ops Standards",o={},l=()=>{const e={3:"#FBFDE2",4:"#E2EAFD",5:"#FDE2E2"},s={2:"#FBFDE2",3:"#E2EAFD",4:"#FDE2E2"};return(0,a.useEffect)((()=>{const t=(e,s)=>{const t=document.querySelector("#"+e);if(t){const e=t.nextElementSibling;e&&"table"===e.tagName.toLowerCase()&&e.querySelectorAll("tbody tr").forEach((e=>{e.querySelectorAll("td").forEach(((e,t)=>{s[t]&&"-"!==e.textContent.trim()&&(e.style.backgroundColor=s[t])}))}))}};t("color-table-cells-overview",e),t("color-table-cells-track-overview",s)}),[]),null},h=[];function x(e){const s={a:"a",h1:"h1",header:"header",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"ops-standards",children:"Ops Standards"})}),"\n",(0,r.jsx)(s.p,{children:"Operational Tooling Standards cover the protocols and guidelines associated with tools and utilities used for monitoring, management, and maintenance of the cloud environment. This includes standards for status pages, alerts, logs, and other operational tools, aiming to optimize the reliability, performance, and security of cloud services and resources."}),"\n",(0,r.jsx)("p",{children:"*Legend to the column headings and entries:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Document states: Draft, Effective, Deprecated (and no longer effective)"}),"\n",(0,r.jsx)(s.li,{children:"Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future"}),"\n",(0,r.jsx)(s.li,{children:"Entries in the effective column marked with a \u2020 will turn deprecated in the near future"}),"\n"]}),"\n","\n","\n",(0,r.jsx)(l,{}),"\n",(0,r.jsx)("div",{id:"color-table-cells-track-overview"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Standard"}),(0,r.jsx)(s.th,{children:"Description"}),(0,r.jsx)(s.th,{children:"Draft"}),(0,r.jsx)(s.th,{children:"Effective"}),(0,r.jsx)(s.th,{children:"Deprecated*"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/ops/scs-0400",children:"scs-0400"})}),(0,r.jsx)(s.td,{children:"Status Page create decision"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0400-v1-status-page-create-decision",children:"v1"})}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/ops/scs-0401",children:"scs-0401"})}),(0,r.jsx)(s.td,{children:"Status page reference implementation decision"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0401-v1-status-page-reference-implementation-decision",children:"v1"})}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/ops/scs-0402",children:"scs-0402"})}),(0,r.jsx)(s.td,{children:"Status page OpenAPI decision"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0402-v1-status-page-openapi-spec-decision",children:"v1"})}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/ops/scs-0403",children:"scs-0403"})}),(0,r.jsx)(s.td,{children:"Architecture for the Cloud Service provider Observability System for the KaaS Layer"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0403-v1-csp-kaas-observability-stack",children:"v1"})}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/ops/scs-0410",children:"scs-0410"})}),(0,r.jsx)(s.td,{children:"Gnocchi as database for metering"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0410-v1-gnocchi-as-metering-database",children:"v1"})}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/ops/scs-0411",children:"scs-0411"})}),(0,r.jsx)(s.td,{children:"Push-based approach for providing usage data"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0411-v1-publishing_method_for_metering_data",children:"v1"})}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/ops/scs-0412",children:"scs-0412"})}),(0,r.jsx)(s.td,{children:"Exposition of IaaS metering data as JSON"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0412-v1-metering-json",children:"v1"})}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]})]})]})]})}function j(e={}){const{wrapper:s}={...(0,d.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(x,{...e})}):x(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>a,x:()=>i});var n=t(96540);const r={},d=n.createContext(r);function a(e){const s=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(d.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/184e5ead.246ccf4c.js b/assets/js/184e5ead.246ccf4c.js new file mode 100644 index 0000000000..8238cbf8d6 --- /dev/null +++ b/assets/js/184e5ead.246ccf4c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[60988],{58912:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"iaas/scs-0102","title":"scs-0102: SCS Image Metadata","description":"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating","source":"@site/standards/iaas/scs-0102.md","sourceDirName":"iaas","slug":"/iaas/scs-0102","permalink":"/standards/iaas/scs-0102","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0101-w1-entropy-implementation-testing"},"next":{"title":"V1","permalink":"/standards/scs-0102-v1-image-metadata"}}');var a=n(74848),d=n(28453);const i={},r="scs-0102: SCS Image Metadata",c={},l=[{value:"Supplement: Implementation and Testing Notes",id:"supplement-implementation-and-testing-notes",level:2}];function o(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"scs-0102-scs-image-metadata",children:"scs-0102: SCS Image Metadata"})}),"\n",(0,a.jsx)(t.p,{children:"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating\nsystem images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements,\nimage handling protocols including updating and origin, and licensing/support details. These guidelines ensure\nthat users can understand, access, and utilize OS images effectively, with clear information on features, updates,\nand licensing provided through well-defined metadata properties."}),"\n",(0,a.jsxs)(t.table,{children:[(0,a.jsx)(t.thead,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.th,{children:"Version"}),(0,a.jsx)(t.th,{children:"Type"}),(0,a.jsx)(t.th,{children:"State"}),(0,a.jsx)(t.th,{children:"stabilized"}),(0,a.jsx)(t.th,{children:"deprecated"})]})}),(0,a.jsx)(t.tbody,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.td,{children:(0,a.jsx)(t.a,{href:"/standards/scs-0102-v1-image-metadata",children:"scs-0102-v1"})}),(0,a.jsx)(t.td,{children:"Standard"}),(0,a.jsx)(t.td,{children:"Stable"}),(0,a.jsx)(t.td,{children:"2022-10-31"}),(0,a.jsx)(t.td,{children:"-"})]})})]}),"\n",(0,a.jsx)(t.h2,{id:"supplement-implementation-and-testing-notes",children:"Supplement: Implementation and Testing Notes"}),"\n",(0,a.jsxs)(t.table,{children:[(0,a.jsx)(t.thead,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.th,{children:"Version"}),(0,a.jsx)(t.th,{children:"State"}),(0,a.jsx)(t.th,{children:"stabilized"}),(0,a.jsx)(t.th,{children:"deprecated"})]})}),(0,a.jsx)(t.tbody,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.td,{children:(0,a.jsx)(t.a,{href:"/standards/scs-0102-w1-image-metadata-implementation-testing",children:"w1"})}),(0,a.jsx)(t.td,{children:"Draft"}),(0,a.jsx)(t.td,{children:"-"}),(0,a.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,d.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(o,{...e})}):o(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var s=n(96540);const a={},d=s.createContext(a);function i(e){const t=s.useContext(d);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(d.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/193dc870.df956eb6.js b/assets/js/193dc870.df956eb6.js new file mode 100644 index 0000000000..0aad44cd52 --- /dev/null +++ b/assets/js/193dc870.df956eb6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[98220],{59241:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>p,frontMatter:()=>i,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"iaas/guides/concept-guide/components/teleport","title":"Teleport","description":"Lifecycle Management of Teleport in OSISM","source":"@site/docs/02-iaas/guides/concept-guide/components/teleport.md","sourceDirName":"02-iaas/guides/concept-guide/components","slug":"/iaas/guides/concept-guide/components/teleport","permalink":"/docs/iaas/guides/concept-guide/components/teleport","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/teleport.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"SONiC & OVN","permalink":"/docs/iaas/guides/concept-guide/components/sonic"},"next":{"title":"Layers in a cluster","permalink":"/docs/iaas/guides/concept-guide/layers"}}');var s=n(74848),c=n(28453);const i={},r="Teleport",a={},d=[{value:"Lifecycle Management of Teleport in OSISM",id:"lifecycle-management-of-teleport-in-osism",level:2}];function l(e){const t={h1:"h1",h2:"h2",header:"header",...(0,c.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"teleport",children:"Teleport"})}),"\n",(0,s.jsx)(t.h2,{id:"lifecycle-management-of-teleport-in-osism",children:"Lifecycle Management of Teleport in OSISM"})]})}function p(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var o=n(96540);const s={},c=o.createContext(s);function i(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1967361e.77da87d9.js b/assets/js/1967361e.77da87d9.js new file mode 100644 index 0000000000..14e8e3b3f6 --- /dev/null +++ b/assets/js/1967361e.77da87d9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[24485],{42964:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>d,contentTitle:()=>r,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/tools/sandbox-manager","title":"Sandbox Manager","description":"","source":"@site/docs/02-iaas/guides/operations-guide/openstack/tools/sandbox-manager.md","sourceDirName":"02-iaas/guides/operations-guide/openstack/tools","slug":"/iaas/guides/operations-guide/openstack/tools/sandbox-manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/sandbox-manager.md","tags":[],"version":"current","sidebarPosition":54,"frontMatter":{"sidebar_label":"Sandbox Manager","sidebar_position":54},"sidebar":"docs","previous":{"title":"Project Manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager"},"next":{"title":"Simple Stress","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress"}}');var n=s(74848),t=s(28453);const i={sidebar_label:"Sandbox Manager",sidebar_position:54},r="Sandbox Manager",d={},c=[];function u(e){const o={h1:"h1",header:"header",...(0,t.R)(),...e.components};return(0,n.jsx)(o.header,{children:(0,n.jsx)(o.h1,{id:"sandbox-manager",children:"Sandbox Manager"})})}function p(e={}){const{wrapper:o}={...(0,t.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,o,s)=>{s.d(o,{R:()=>i,x:()=>r});var a=s(96540);const n={},t=a.createContext(n);function i(e){const o=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function r(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),a.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/19afbcc8.0b722e3d.js b/assets/js/19afbcc8.0b722e3d.js new file mode 100644 index 0000000000..f50042c5e0 --- /dev/null +++ b/assets/js/19afbcc8.0b722e3d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[14840],{83164:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>v,frontMatter:()=>i,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"getting-started/overview","title":"Overview","description":"TODO","source":"@site/docs/01-getting-started/overview.md","sourceDirName":"01-getting-started","slug":"/getting-started/overview","permalink":"/docs/getting-started/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/01-getting-started/overview.md","tags":[],"version":"current","frontMatter":{"sidebar":1}}');var s=n(74848),o=n(28453);const i={sidebar:1},c="Overview",a={},d=[];function u(e){const t={h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,s.jsx)(t.p,{children:"TODO"})]})}function v(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var r=n(96540);const s={},o=r.createContext(s);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/19cb43cd.a2a348a3.js b/assets/js/19cb43cd.a2a348a3.js new file mode 100644 index 0000000000..821c98ff89 --- /dev/null +++ b/assets/js/19cb43cd.a2a348a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[11572],{15030:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"container/components/container-registry/docs/upgrade","title":"Upgrade","description":"This page aims at providing additional information for upgrading Harbor","source":"@site/docs/03-container/components/container-registry/docs/upgrade.md","sourceDirName":"03-container/components/container-registry/docs","slug":"/container/components/container-registry/docs/upgrade","permalink":"/docs/container/components/container-registry/docs/upgrade","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/upgrade.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Rate limit","permalink":"/docs/container/components/container-registry/docs/rate_limit"},"next":{"title":"Backup and restore","permalink":"/docs/container/components/container-registry/docs/backup_and_restore"}}');var t=n(74848),a=n(28453);const i={},s="Upgrade",c={},d=[];function p(e){const r={a:"a",code:"code",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.header,{children:(0,t.jsx)(r.h1,{id:"upgrade",children:"Upgrade"})}),"\n",(0,t.jsxs)(r.p,{children:["This page aims at providing additional information for upgrading ",(0,t.jsx)(r.a,{href:"https://goharbor.io/",children:"Harbor"}),"\ncontainer registry, which operates in the Kubernetes environment and is deployed with Helm.\nIt extends the official ",(0,t.jsx)(r.a,{href:"https://goharbor.io/docs/main/administration/upgrade/helm-upgrade/",children:"Upgrading Harbor Deployed with Helm page"}),",\nwhere the upgrade process is well described. See the following upgrade hints:"]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsxs)(r.li,{children:["Always ",(0,t.jsx)(r.a,{href:"/docs/container/components/container-registry/docs/backup_and_restore",children:"backup"})," your Harbor instance before upgrade"]}),"\n",(0,t.jsxs)(r.li,{children:["Normally Harbor helm upgrade from 2 minor versions lower should be ",(0,t.jsx)(r.a,{href:"https://github.com/goharbor/harbor-helm/issues/500#issuecomment-647029797",children:"tested"}),", but always\nvalidate your planned upgrade path with recommendations in the official ",(0,t.jsx)(r.a,{href:"https://goharbor.io/docs/main/administration/upgrade/",children:"docs"}),"."]}),"\n",(0,t.jsxs)(r.li,{children:["The step-by-step upgrade is needed because of possible DDL changes in the Harbor database.\nHarbor core service executes the ",(0,t.jsx)(r.a,{href:"https://github.com/goharbor/harbor/tree/main/make/migrations/postgresql",children:"migrations scripts"})," automatically.\nThe helm upgrade process may fail in the case of the failure of migration scripts.\nHence, it is a good idea to run migration scripts with a pre-upgrade job. Harbor Helm\nhas an option ",(0,t.jsx)(r.code,{children:"enableMigrateHelmHook"})," which separates the database migration from Harbor core\nand runs the migration job as a pre-upgrade hook."]}),"\n"]})]})}function h(e={}){const{wrapper:r}={...(0,a.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,r,n)=>{n.d(r,{R:()=>i,x:()=>s});var o=n(96540);const t={},a=o.createContext(t);function i(e){const r=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function s(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),o.createElement(a.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/19e9bde5.a29dc131.js b/assets/js/19e9bde5.a29dc131.js new file mode 100644 index 0000000000..b0fff9e982 --- /dev/null +++ b/assets/js/19e9bde5.a29dc131.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[64175],{30638:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"operating-scs/components/monitoring/docs/quickstart","title":"Quickstart","description":"These page covers the process of deploying the Observer monitoring solution","source":"@site/docs/04-operating-scs/components/monitoring/docs/quickstart.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/quickstart","permalink":"/docs/operating-scs/components/monitoring/docs/quickstart","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/quickstart.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/operating-scs/components/monitoring/docs/overview"},"next":{"title":"SCS deployment","permalink":"/docs/operating-scs/components/monitoring/docs/scs-deployment"}}');var r=s(74848),o=s(28453);const i={},c="Quickstart",l={},a=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Prepare Kubernetes cluster",id:"prepare-kubernetes-cluster",level:2},{value:"Deploy Observer monitoring solution",id:"deploy-observer-monitoring-solution",level:2},{value:"Access the Observer monitoring UIs",id:"access-the-observer-monitoring-uis",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,r.jsx)(n.p,{children:"These page covers the process of deploying the Observer monitoring solution\ninto the Kubernetes cluster."}),"\n",(0,r.jsx)(n.p,{children:"The configuration options used in this tutorial result in a non-productive and simple\ndeployment of the Observer monitoring solution. The steps do not guide users to register\ncertain observer targets, such as existing Kubernetes clusters or virtual machines.\nAdditionally, the tutorial lacks guidance for deploying optional and experimental components\nlike IaaS and KaaS monitoring."}),"\n",(0,r.jsx)(n.p,{children:"At the end of this tutorial, the reader should end up with a Kubernetes cluster where the Observer solution will\nbe installed and will monitor the Kubernetes cluster hosting it."}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Kubernetes cluster"}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://kubernetes.io/docs/reference/kubectl/",children:"kubectl"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://helm.sh/",children:"helm"})}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"prepare-kubernetes-cluster",children:"Prepare Kubernetes cluster"}),"\n",(0,r.jsxs)(n.p,{children:["The Observer monitoring solution is designed to operate on Kubernetes clusters. We have continuously tested it with\nvarious Kubernetes distributions, including vanilla Kubernetes, OKD, ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/",children:"SCS KaaS V1"}),",\nand ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks",children:"SCS KaaS V2"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["To set up the SCS KaaS V2 Kubernetes cluster, please refer to the ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks/blob/feat/r6-docs/docs/quickstart.md",children:"quickstart guide"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["For local testing purposes, we recommend using ",(0,r.jsx)(n.a,{href:"https://kind.sigs.k8s.io/docs/user/quick-start/",children:"KinD"})," (Kubernetes in Docker) as follows:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kind create cluster --config kind-observer-config.yaml --image kindest/node:v1.27.3 --name observer\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If you opt not to use KinD with the custom config we provided here, and prefer utilizing another Kubernetes cluster,\nensure that the metric endpoints for various control plane components are properly exposed.\nRefer to the ",(0,r.jsx)(n.a,{href:"https://dnationcloud.github.io/kubernetes-monitoring/helpers/FAQ/#kubernetes-monitoring-shows-or-0-state-for-some-control-plane-components-are-control-plane-components-working-correctly",children:"docs"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"deploy-observer-monitoring-solution",children:"Deploy Observer monitoring solution"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/\nhelm repo update dnationcloud\nhelm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml\n"})}),"\n",(0,r.jsx)(n.h2,{id:"access-the-observer-monitoring-uis",children:"Access the Observer monitoring UIs"}),"\n",(0,r.jsx)(n.p,{children:"At this point, you should have the ability to access the Grafana, Alertmanager and Thanos UIs\nwithin the Observer monitoring cluster."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Grafana UI"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"http://localhost:30000\n"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Use the following credentials:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["username: ",(0,r.jsx)(n.code,{children:"admin"})]}),"\n",(0,r.jsxs)(n.li,{children:["password: ",(0,r.jsx)(n.code,{children:"pass"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Visit the Layer 0 dashboard, ",(0,r.jsx)(n.code,{children:"infrastructure-services-monitoring"}),", and drill down to explore cluster metrics"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"http://localhost:30000/d/monitoring/infrastructure-services-monitoring",children:"http://localhost:30000/d/monitoring/infrastructure-services-monitoring"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Alertmanager UI"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"http://localhost:30001\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Thanos UI"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"http://localhost:30002\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/19f6a518.9228f3d8.js b/assets/js/19f6a518.9228f3d8.js new file mode 100644 index 0000000000..3779838a95 --- /dev/null +++ b/assets/js/19f6a518.9228f3d8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[33444],{91976:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"mission-statement","title":"Mission Statement","description":"Sovereign Cloud Stack (SCS) offers more than just a software stack \u2014 it\'s the embodiment of a collaborative open-source spirit, united by the aim of achieving digital sovereignty. At the heart of this initiative is a foundational pillar: the community.","source":"@site/community/mission-statement.md","sourceDirName":".","slug":"/mission-statement","permalink":"/community/mission-statement","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Overview","permalink":"/community/"},"next":{"title":"License considerations for SCS","permalink":"/community/license-considerations"}}');var i=n(74848),r=n(28453);const s={},a="Mission Statement",l={},c=[{value:"Values of our collaboration",id:"values-of-our-collaboration",level:2},{value:"4+1 Open",id:"41-open",level:3},{value:"The 'Four Open"",id:"the-four-open",level:3},{value:"+1 Open",id:"1-open",level:3},{value:"Code of Conduct",id:"code-of-conduct",level:2},{value:"Sovereign Cloud Stack Community",id:"sovereign-cloud-stack-community",level:3},{value:"Our Standards",id:"our-standards",level:3},{value:"Attribution",id:"attribution",level:4}];function d(e){const t={a:"a",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"mission-statement",children:"Mission Statement"})}),"\n",(0,i.jsx)(t.p,{children:"Sovereign Cloud Stack (SCS) offers more than just a software stack \u2014 it's the embodiment of a collaborative open-source spirit, united by the aim of achieving digital sovereignty. At the heart of this initiative is a foundational pillar: the community."}),"\n",(0,i.jsx)(t.p,{children:"Open Source technology has become increasingly mature. However, the greatest software is useless if it cannot be developed and operated with full confidence. For this to happen, it is imperative that skills and knowledge be built up, fostered, and retained. In an increasingly competitive market for skilled people and complex IT systems, this is becoming an ever greater challenge for governments, institutions, and companies. How can we operate digital offerings in a self-determined, secure, and excellent manner?"}),"\n",(0,i.jsx)(t.p,{children:"The answer to this must be the collectivization of operational knowledge, just as it has been practiced for many years with software development."}),"\n",(0,i.jsx)(t.p,{children:"In essence, the community is the core of the Sovereign Cloud Stack. It not only propels its evolution but also ensures its relevance, reliability, and resilience in an ever-evolving digital landscape."}),"\n",(0,i.jsxs)(t.p,{children:["Read our ",(0,i.jsx)(t.a,{href:"https://openoperations.org/",children:"open operations manifesto"})," or join our Community either by joining our ",(0,i.jsx)(t.a,{href:"/community/collaboration",children:"team meetings"})," or by joining our ",(0,i.jsx)(t.a,{href:"https://matrix.to/#/#scs-tech:matrix.org",children:"matrix channel"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"Check out the different meetings and working topics within our team and SIG introductions."}),"\n",(0,i.jsx)(t.h2,{id:"values-of-our-collaboration",children:"Values of our collaboration"}),"\n",(0,i.jsx)(t.h3,{id:"41-open",children:"4+1 Open"}),"\n",(0,i.jsx)(t.p,{children:'For us as a community, the "Four Open" are more than a philosophy; rather, we see them as fundamental values that are essential for working collaborativly.'}),"\n",(0,i.jsx)(t.p,{children:"The Four Opens give us the frame to develop SCS as a community that can be considered an important cornerstone tomorrow. We can also contribute to future developments and play an active role in shaping them."}),"\n",(0,i.jsx)(t.h3,{id:"the-four-open",children:"The 'Four Open\""}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Open Source: source code - open software that can be modified without restriction, on the condition that it is not limited in functionality or performance"}),"\n",(0,i.jsx)(t.li,{children:"Open Design: the open process for designing the software"}),"\n",(0,i.jsx)(t.li,{children:"Open Development: the opportunity to participate in the transparent development process on an equal footing"}),"\n",(0,i.jsx)(t.li,{children:"Open Community: an equal community where everyone can be heard"}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"1-open",children:"+1 Open"}),"\n",(0,i.jsx)(t.p,{children:"For us, the 5th Open is the Open Operation. At its core, the manifesto encompasses the collective, transparent exchange of knowledge. It describes the way to encourage everyone - regardless of their level of knowledge - to contribute to the community. The 5th Open has the principle that we can only learn from mistakes and therefore has an open and friendly mistake tolerance."}),"\n",(0,i.jsxs)(t.p,{children:["Our SCS '5-Open' community is just as open as described above - join us and leave your mark on the technologies of tomorrow. Join our ",(0,i.jsx)(t.a,{href:"https://www.meetup.com/open-operations-meetup/",children:"Open Operations Meetup"}),"."]}),"\n",(0,i.jsx)(t.h2,{id:"code-of-conduct",children:"Code of Conduct"}),"\n",(0,i.jsx)(t.h3,{id:"sovereign-cloud-stack-community",children:"Sovereign Cloud Stack Community"}),"\n",(0,i.jsx)(t.p,{children:"Sovereign Cloud Stack (SCS) is a network of organizations and individuals: providers, integrators, contributors, users, developers, operators, and associates of standardized sovereign cloud infrastructure. We join forces in defining, implementing and operating a fully open, federated, compatible, interoperable cloud infrastructure and platform."}),"\n",(0,i.jsxs)(t.p,{children:["We are committed to ",(0,i.jsx)(t.a,{href:"https://www.openstack.org/four-opens/",children:'"The Four Opens"'})," of the ",(0,i.jsx)(t.a,{href:"https://openinfra.dev/",children:"Open Infrastructure Foundation"})," and align our actions according to these four non-negotiable core principles of open collaboration. To include the whole DevOps approach we added the fifth open: ",(0,i.jsx)(t.a,{href:"https://openoperations.org/",children:"Open Operations"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"We do believe that an open and welcoming environment is essential for an active and engaged community. As contributors and maintainers we pledge to make participation in our project and our community a harassment-free experience for everyone."}),"\n",(0,i.jsx)(t.p,{children:"No list is ever exhaustive, so we encourage members of the SCS community to adhere to the spirit, rather than the letter, of this code, as that is how it will be enforced. Places where this code may be particularly applicable are GitHub issues and pull requests, chat, mailing lists, team meetings, discussions on social networks broadly directed at or between members of the community, and other direct interactions within the community. Violations may lead to verbal or even public warnings or - especially in case of continued or flagrant offenses - may affect an individual's (or organization's) ability to participate within the SCS community."}),"\n",(0,i.jsx)(t.p,{children:"We encourage you to confront someone or a group of people that you observe to be in violation of the CoC (whether in letter or in spirit) with your observation, so that the person(s) can correct his/her/their behavior. If this is not successful or it is difficult for you to confront the people and you seek support for this, you may contact the SCS project lead at project-lead(at)lists.scs.community"}),"\n",(0,i.jsx)(t.p,{children:"A large fraction of SCS consists of contributions to upstream projects. All SCS contributors are expected to adhere to the respective upstream Codes of Conduct when interacting with such projects, or developing code intended for upstreaming."}),"\n",(0,i.jsx)(t.h3,{id:"our-standards",children:"Our Standards"}),"\n",(0,i.jsx)(t.p,{children:"We ask you to please adhere to the following basic rules:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Be friendly and patient."})," We were all new or lacked knowledge at various points in time. Please try to remember what it felt like to be on that end, and treat people accordingly."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Use welcoming and inclusive language."})," We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, organization, color, immigration status, social and economic status, educational level, level of experience, sex characteristics, gender identity and expression, sexual orientation, gender identity and expression, age, body size and personal appearance, disability, family status, political belief, religion, and mental and physical ability."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Be helpful."})," By helping others to learn our entire ecosystem is enriched. We encourage members of the SCS community to mentor each other and help to raise the general level of knowledge in the community whenever possible."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Choose words that shows respect, empathy and promote constructive dialogue."})," We are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable. This includes, but is not limited to:","\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Violent threats or language directed against another person."}),"\n",(0,i.jsx)(t.li,{children:"Discriminatory jokes and language."}),"\n",(0,i.jsx)(t.li,{children:"Posting sexually explicit or violent material."}),"\n",(0,i.jsx)(t.li,{children:'Posting (or threatening to post) other people\'s personally identifying information ("doxing"), regardless of whether it is publicly available.'}),"\n",(0,i.jsx)(t.li,{children:"Personal insults, especially those using racist, sexist, or otherwise discriminatory terms."}),"\n",(0,i.jsx)(t.li,{children:"Deliberately referring to others by names or pronouns counter to their identity."}),"\n",(0,i.jsx)(t.li,{children:"Unwelcome sexual attention."}),"\n",(0,i.jsx)(t.li,{children:"Repeated harassment of others, e.g. not stopping behavior when someone asks you to stop."}),"\n",(0,i.jsx)(t.li,{children:"Advocating for, or encouraging, any of the above behavior."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Be respectful, accept differing viewpoints and focus on what is best for the community."})," Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It's important to remember that a community where people feel uncomfortable or threatened is not a productive one. Members of the SCS community should be respectful when dealing with other members as well as with people outside the SCS community."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"When we disagree, try to understand why."})," Disagreements, both social and technical, happen all the time and SCS is no exception. It is important that we resolve disagreements and differing views constructively. Remember that we're different. The strength of SCS comes from its broad community, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn't mean that they're wrong. Don't forget that it is human to err and blaming each other doesn't get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes."]}),"\n"]}),"\n",(0,i.jsx)(t.h4,{id:"attribution",children:"Attribution"}),"\n",(0,i.jsxs)(t.p,{children:["This Code of Conduct is mainly adapted from the ",(0,i.jsx)(t.a,{href:"https://asahilinux.org/code-of-conduct/",children:"Asahi Linux Code of Conduct"})," and the ",(0,i.jsx)(t.a,{href:"https://www.contributor-covenant.org/version/2/1/code_of_conduct/",children:"Contributor Covenant Code of Conduct"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>a});var o=n(96540);const i={},r=o.createContext(i);function s(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1a4e3797.14ddfd7e.js b/assets/js/1a4e3797.14ddfd7e.js new file mode 100644 index 0000000000..d7e5578c87 --- /dev/null +++ b/assets/js/1a4e3797.14ddfd7e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[62138],{53465:(e,t,r)=>{r.d(t,{W:()=>u});var s=r(96540),a=r(44586);const n=["zero","one","two","few","many","other"];function c(e){return n.filter((t=>e.includes(t)))}const l={locale:"en",pluralForms:c(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,a.A)();return(0,s.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:c(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),l}}),[e])}function u(){const e=o();return{selectMessage:(t,r)=>function(e,t,r){const s=e.split("|");if(1===s.length)return s[0];s.length>r.pluralForms.length&&console.error(`For locale=${r.locale}, a maximum of ${r.pluralForms.length} plural forms are expected (${r.pluralForms.join(",")}), but the message contains ${s.length}: ${e}`);const a=r.select(t),n=r.pluralForms.indexOf(a);return s[Math.min(n,s.length-1)]}(r,t,e)}}},41283:(e,t,r)=>{r.r(t),r.d(t,{default:()=>b});var s=r(96540),a=r(44586),n=r(59504),c=r(5260),l=r(28774),o=r(21312),u=r(53465),h=r(20053),i=r(56347),m=r(92303),d=r(11088);const p=function(){const e=(0,m.A)(),t=(0,i.W6)(),r=(0,i.zy)(),{siteConfig:{baseUrl:s}}=(0,a.A)(),n=e?new URLSearchParams(r.search):null,c=n?.get("q")||"",l=n?.get("ctx")||"",o=n?.get("version")||"",u=e=>{const t=new URLSearchParams(r.search);return e?t.set("q",e):t.delete("q"),t};return{searchValue:c,searchContext:l&&Array.isArray(d.Hg)&&d.Hg.some((e=>"string"==typeof e?e===l:e.path===l))?l:"",searchVersion:o,updateSearchPath:e=>{const r=u(e);t.replace({search:r.toString()})},updateSearchContext:e=>{const s=new URLSearchParams(r.search);s.set("ctx",e),t.replace({search:s.toString()})},generateSearchPageLink:e=>{const t=u(e);return`${s}search?${t.toString()}`}}};var g=r(5891),x=r(32384),f=r(69913),y=r(86841),C=r(43810),S=r(27674),j=r(2849),A=r(4471);const w={searchContextInput:"searchContextInput_mXoe",searchQueryInput:"searchQueryInput_CFBF",searchResultItem:"searchResultItem_U687",searchResultItemPath:"searchResultItemPath_uIbk",searchResultItemSummary:"searchResultItemSummary_oZHr",searchQueryColumn:"searchQueryColumn_q7nx",searchContextColumn:"searchContextColumn_oWAF"};var I=r(43385),v=r(74848);function R(){const{siteConfig:{baseUrl:e},i18n:{currentLocale:t}}=(0,a.A)(),{selectMessage:r}=(0,u.W)(),{searchValue:n,searchContext:l,searchVersion:i,updateSearchPath:m,updateSearchContext:f}=p(),[y,C]=(0,s.useState)(n),[S,A]=(0,s.useState)(),[R,b]=(0,s.useState)(),F=`${e}${i}`,T=(0,s.useMemo)((()=>y?(0,o.T)({id:"theme.SearchPage.existingResultsTitle",message:'Search results for "{query}"',description:"The search page title for non-empty query"},{query:y}):(0,o.T)({id:"theme.SearchPage.emptyResultsTitle",message:"Search the documentation",description:"The search page title for empty query"})),[y]);(0,s.useEffect)((()=>{m(y),S&&(y?S(y,(e=>{b(e)})):b(void 0))}),[y,S]);const _=(0,s.useCallback)((e=>{C(e.target.value)}),[]);return(0,s.useEffect)((()=>{n&&n!==y&&C(n)}),[n]),(0,s.useEffect)((()=>{!async function(){const{wrappedIndexes:e,zhDictionary:t}=!Array.isArray(d.Hg)||l||d.dz?await(0,g.Z)(F,l):{wrappedIndexes:[],zhDictionary:[]};A((()=>(0,x.m)(e,t,100)))}()}),[l,F]),(0,v.jsxs)(s.Fragment,{children:[(0,v.jsxs)(c.A,{children:[(0,v.jsx)("meta",{property:"robots",content:"noindex, follow"}),(0,v.jsx)("title",{children:T})]}),(0,v.jsxs)("div",{className:"container margin-vert--lg",children:[(0,v.jsx)("h1",{children:T}),(0,v.jsxs)("div",{className:"row",children:[(0,v.jsx)("div",{className:(0,h.A)("col",{[w.searchQueryColumn]:Array.isArray(d.Hg),"col--9":Array.isArray(d.Hg),"col--12":!Array.isArray(d.Hg)}),children:(0,v.jsx)("input",{type:"search",name:"q",className:w.searchQueryInput,"aria-label":"Search",onChange:_,value:y,autoComplete:"off",autoFocus:!0})}),Array.isArray(d.Hg)?(0,v.jsx)("div",{className:(0,h.A)("col","col--3","padding-left--none",w.searchContextColumn),children:(0,v.jsxs)("select",{name:"search-context",className:w.searchContextInput,id:"context-selector",value:l,onChange:e=>f(e.target.value),children:[d.dz&&(0,v.jsx)("option",{value:"",children:(0,o.T)({id:"theme.SearchPage.searchContext.everywhere",message:"Everywhere"})}),d.Hg.map((e=>{const{label:r,path:s}=(0,I.p)(e,t);return(0,v.jsx)("option",{value:s,children:r},s)}))]})}):null]}),!S&&y&&(0,v.jsx)("div",{children:(0,v.jsx)(j.A,{})}),R&&(R.length>0?(0,v.jsx)("p",{children:r(R.length,(0,o.T)({id:"theme.SearchPage.documentsFound.plurals",message:"1 document found|{count} documents found",description:'Pluralized label for "{count} documents found". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)'},{count:R.length}))}):(0,v.jsx)("p",{children:(0,o.T)({id:"theme.SearchPage.noResultsText",message:"No documents were found",description:"The paragraph for empty search result"})})),(0,v.jsx)("section",{children:R&&R.map((e=>(0,v.jsx)(P,{searchResult:e},e.document.i)))})]})]})}function P(e){let{searchResult:{document:t,type:r,page:s,tokens:a,metadata:n}}=e;const c=r===f.i.Title,o=r===f.i.Keywords,u=r===f.i.Description,h=u||o,i=c||h,m=r===f.i.Content,p=(c?t.b:s.b).slice(),g=m||h?t.s:t.t;i||p.push(s.t);let x="";if(d.CU&&a.length>0){const e=new URLSearchParams;for(const t of a)e.append("_highlight",t);x=`?${e.toString()}`}return(0,v.jsxs)("article",{className:w.searchResultItem,children:[(0,v.jsx)("h2",{children:(0,v.jsx)(l.A,{to:t.u+x+(t.h||""),dangerouslySetInnerHTML:{__html:m||h?(0,y.Z)(g,a):(0,C.C)(g,(0,S.g)(n,"t"),a,100)}})}),p.length>0&&(0,v.jsx)("p",{className:w.searchResultItemPath,children:(0,A.$)(p)}),(m||u)&&(0,v.jsx)("p",{className:w.searchResultItemSummary,dangerouslySetInnerHTML:{__html:(0,C.C)(t.t,(0,S.g)(n,"t"),a,100)}})]})}const b=function(){return(0,v.jsx)(n.A,{children:(0,v.jsx)(R,{})})}}}]); \ No newline at end of file diff --git a/assets/js/1bb8290c.c9447e76.js b/assets/js/1bb8290c.c9447e76.js new file mode 100644 index 0000000000..dbf513fb45 --- /dev/null +++ b/assets/js/1bb8290c.c9447e76.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[53652],{42204:t=>{t.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Contribute to Docs","slug":"/category/contribute-to-docs","permalink":"/community/category/contribute-to-docs","sidebar":"community","navigation":{"previous":{"title":"Getting Started with Wavestack","permalink":"/community/cloud-resources/wavestack"},"next":{"title":"Adding Docs Guide","permalink":"/community/contribute/adding-docs-guide"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/1bc22123.adc9690c.js b/assets/js/1bc22123.adc9690c.js new file mode 100644 index 0000000000..b1b3a527cb --- /dev/null +++ b/assets/js/1bc22123.adc9690c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[14111],{35212:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"releases/ReleaseX","title":"Release Notes for SCS Release X","description":"This document is work in progress for the upcoming Release X.","source":"@site/docs/06-releases/ReleaseX.md","sourceDirName":"06-releases","slug":"/releases/ReleaseX","permalink":"/docs/releases/ReleaseX","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/ReleaseX.md","tags":[],"version":"current","frontMatter":{}}');var t=n(74848),r=n(28453);const o={},a="Release Notes for SCS Release X",l={},d=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"New Features (Highlights)",id:"new-features-highlights",level:2},{value:"Operator focused improvements",id:"operator-focused-improvements",level:3},{value:"SCS Developer focused improvements (testbed and k8s cluster management)",id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Resolved Issues",id:"resolved-issues",level:2},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in RX",id:"list-of-known-issues--restrictions-in-rx",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Thanks",id:"thanks",level:2}];function c(e){const s={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"release-notes-for-scs-release-x",children:"Release Notes for SCS Release X"})}),"\n",(0,t.jsx)(s.p,{children:"This document is work in progress for the upcoming Release X.\nRelease X will be released in Months/Year.\nThis note will be removed, once Release X is released and these notes are valid."}),"\n",(0,t.jsx)(s.h2,{id:"scope",children:"Scope"}),"\n",(0,t.jsx)(s.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,t.jsx)(s.h2,{id:"new-features-highlights",children:"New Features (Highlights)"}),"\n",(0,t.jsx)(s.h3,{id:"operator-focused-improvements",children:"Operator focused improvements"}),"\n",(0,t.jsx)(s.h3,{id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",children:"SCS Developer focused improvements (testbed and k8s cluster management)"}),"\n",(0,t.jsx)(s.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,t.jsx)(s.h2,{id:"removals",children:"Removals"}),"\n",(0,t.jsx)(s.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,t.jsx)(s.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,t.jsx)(s.h2,{id:"resolved-issues",children:"Resolved Issues"}),"\n",(0,t.jsx)(s.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,t.jsx)(s.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,t.jsx)(s.h2,{id:"list-of-known-issues--restrictions-in-rx",children:"List of known issues & restrictions in RX"}),"\n",(0,t.jsx)(s.h2,{id:"contributing",children:"Contributing"}),"\n",(0,t.jsxs)(s.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,t.jsx)(s.a,{href:"https://scs.community/contribute/",children:"How to contribute page"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"thanks",children:"Thanks"})]})}function u(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var i=n(96540);const t={},r=i.createContext(t);function o(e){const s=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1bc8ea4c.0307fde5.js b/assets/js/1bc8ea4c.0307fde5.js new file mode 100644 index 0000000000..4ee9549605 --- /dev/null +++ b/assets/js/1bc8ea4c.0307fde5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8514],{18421:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"iaas/guides/concept-guide/nodes","title":"Nodes in a cluster","description":"Compute Node","source":"@site/docs/02-iaas/guides/concept-guide/nodes.md","sourceDirName":"02-iaas/guides/concept-guide","slug":"/iaas/guides/concept-guide/nodes","permalink":"/docs/iaas/guides/concept-guide/nodes","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/nodes.md","tags":[],"version":"current","sidebarPosition":25,"frontMatter":{"sidebar_label":"Nodes in a cluster","sidebar_position":25},"sidebar":"docs","previous":{"title":"Layers in a cluster","permalink":"/docs/iaas/guides/concept-guide/layers"},"next":{"title":"Cluster design","permalink":"/docs/iaas/guides/concept-guide/design"}}');var d=o(74848),i=o(28453);const s={sidebar_label:"Nodes in a cluster",sidebar_position:25},a="Nodes in a cluster",r={},c=[{value:"Compute Node",id:"compute-node",level:2},{value:"Control Node",id:"control-node",level:2},{value:"Data Node",id:"data-node",level:2},{value:"Management Node",id:"management-node",level:2},{value:"Monitoring Node",id:"monitoring-node",level:2},{value:"Network Node",id:"network-node",level:2}];function l(e){const n={h1:"h1",h2:"h2",header:"header",...(0,i.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.header,{children:(0,d.jsx)(n.h1,{id:"nodes-in-a-cluster",children:"Nodes in a cluster"})}),"\n",(0,d.jsx)(n.h2,{id:"compute-node",children:"Compute Node"}),"\n",(0,d.jsx)(n.h2,{id:"control-node",children:"Control Node"}),"\n",(0,d.jsx)(n.h2,{id:"data-node",children:"Data Node"}),"\n",(0,d.jsx)(n.h2,{id:"management-node",children:"Management Node"}),"\n",(0,d.jsx)(n.h2,{id:"monitoring-node",children:"Monitoring Node"}),"\n",(0,d.jsx)(n.h2,{id:"network-node",children:"Network Node"})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(l,{...e})}):l(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>a});var t=o(96540);const d={},i=t.createContext(d);function s(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1c894279.fd86a422.js b/assets/js/1c894279.fd86a422.js new file mode 100644 index 0000000000..5c8e8ae596 --- /dev/null +++ b/assets/js/1c894279.fd86a422.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[81804],{31490:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"scs-0001-v1-sovereign-cloud-standards","title":"Sovereign Cloud Standards","description":"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision\\nrecords within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in\\nthe development and maintenance of interoperable and transparent cloud infrastructure standards.\\n","source":"@site/standards/scs-0001-v1-sovereign-cloud-standards.md","sourceDirName":".","slug":"/scs-0001-v1-sovereign-cloud-standards","permalink":"/standards/scs-0001-v1-sovereign-cloud-standards","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Sovereign Cloud Standards","type":"Procedural","status":"Stable","track":"Global","stabilized_at":"2022-11-28T00:00:00.000Z","description":"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision\\nrecords within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in\\nthe development and maintenance of interoperable and transparent cloud infrastructure standards.\\n"},"sidebar":"standards","previous":{"title":"scs-0001: Sovereign Cloud Standards","permalink":"/standards/global/scs-0001"},"next":{"title":"scs-0002: Standards, Docs and Organisation","permalink":"/standards/global/scs-0002"}}');var s=t(74848),d=t(28453);const r={title:"Sovereign Cloud Standards",type:"Procedural",status:"Stable",track:"Global",stabilized_at:new Date("2022-11-28T00:00:00.000Z"),description:"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision\nrecords within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in\nthe development and maintenance of interoperable and transparent cloud infrastructure standards.\n"},a=void 0,o={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Requirements",id:"requirements",level:2},{value:"Sovereign Cloud Standard documents",id:"sovereign-cloud-standard-documents",level:2},{value:"Types of documents",id:"types-of-documents",level:3},{value:"Procedural",id:"procedural",level:4},{value:"Standard",id:"standard",level:4},{value:"Decision Record",id:"decision-record",level:4},{value:"Supplement",id:"supplement",level:4},{value:"Document format",id:"document-format",level:3},{value:"Sections",id:"sections",level:3},{value:"Standard",id:"standard-1",level:4},{value:"Decision Record",id:"decision-record-1",level:4},{value:"Process",id:"process",level:2},{value:"Proposal phase",id:"proposal-phase",level:3},{value:"Proposal of a new document",id:"proposal-of-a-new-document",level:4},{value:"Proposal of a major update to a stable document",id:"proposal-of-a-major-update-to-a-stable-document",level:4},{value:"Development phase (Draft)",id:"development-phase-draft",level:3},{value:"Stabilized phase (Stable)",id:"stabilized-phase-stable",level:3},{value:"Deprecation phase (Deprecated)",id:"deprecation-phase-deprecated",level:3},{value:"Rejection",id:"rejection",level:3},{value:"Open Questions",id:"open-questions",level:2},{value:"Stabilization criteria",id:"stabilization-criteria",level:3},{value:"Breaking change criteria",id:"breaking-change-criteria",level:3},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Versioning",id:"versioning",level:3},{value:"Acknowledgements",id:"acknowledgements",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",mermaid:"mermaid",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://scs.community",children:"Sovereign Cloud Stack (SCS)"})," provides standards\nfor a range of cloud infrastructure types.\nIt strives for interoperable and sovereign cloud stacks\nwhich can be deployed and used by a wide range of organizations and individuals.\nWherever feasible,\ntransparency and openness both in respect to the inner workings of the platforms standardised by SCS,\nas well as the SCS organization itself\nare a paradigm we intend to live."]}),"\n",(0,s.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,s.jsxs)(n.p,{children:['The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in ',(0,s.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2119",children:"RFC 2119"}),"."]}),"\n",(0,s.jsx)(n.p,{children:'In addition, "FORBIDDEN" is to be interpreted equivalent to "MUST NOT".'}),"\n",(0,s.jsx)(n.h2,{id:"sovereign-cloud-standard-documents",children:"Sovereign Cloud Standard documents"}),"\n",(0,s.jsx)(n.p,{children:"One of the main products of the SCS organisation are Sovereign Cloud Standard documents."}),"\n",(0,s.jsx)(n.h3,{id:"types-of-documents",children:"Types of documents"}),"\n",(0,s.jsx)(n.h4,{id:"procedural",children:"Procedural"}),"\n",(0,s.jsx)(n.p,{children:"A procedural SCS document describes a process, a policy or a guideline\nto which the SCS community adheres."}),"\n",(0,s.jsx)(n.h4,{id:"standard",children:"Standard"}),"\n",(0,s.jsx)(n.p,{children:"A standard SCS document describes a technical standard for SCS compliant clouds.\nNote that it may not be necessary for all clouds to implement all standards."}),"\n",(0,s.jsx)(n.h4,{id:"decision-record",children:"Decision Record"}),"\n",(0,s.jsx)(n.p,{children:"Sometimes during the development of the SCS standard,\na complex technical decision needs to be taken,\nwhich does not directly result in a new standard."}),"\n",(0,s.jsxs)(n.p,{children:["The SCS document format formally integrates\nthe documentation of such decisions\nas documents of type ",(0,s.jsx)(n.code,{children:"Decision Record"}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"supplement",children:"Supplement"}),"\n",(0,s.jsx)(n.p,{children:"A supplement extends a Standard with additional information, such as implementation and testing notes,\nthat is merely informative, but not authoritative, and that may be subject to change more frequently\nthan the standard itself."}),"\n",(0,s.jsx)(n.h3,{id:"document-format",children:"Document format"}),"\n",(0,s.jsxs)(n.p,{children:["The SCS documents are provided in GitHub flavored markdown.\nEach document is assigned a unique number.\nTo disambiguate with other organisations using similar schemes\n(such as XEPs, PEPs or IETF RFCs),\nthe numbers are prefixed with ",(0,s.jsx)(n.code,{children:"SCS-"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"To allow a concept to evolve while allowing breaking changes,\neach SCS document is associated with a major version number.\nThis major version number is a positive number\nand the numbering starts at one for each document."}),"\n",(0,s.jsx)(n.p,{children:"In order to make organisation of the SCS documents easier,\neach document also has a slugified title.\nThe slugified title MUST NOT be changed after the acceptance of the document into the repository,\nas it is part of its canonical URL.\nIt MUST consist only of lower-case ASCII letters, numbers and hyphens.\nIt MUST NOT start with a hyphen and SHOULD start with a lower-case letter.\nIt SHOULD NOT contain more than one subsequent hyphen."}),"\n",(0,s.jsxs)(n.p,{children:["The file name of an SCS document is formed using the following pattern:\n",(0,s.jsx)(n.code,{children:"scs-XXXX-vN-T.md"}),", where\n",(0,s.jsx)(n.code,{children:"XXXX"})," is replaced with the zero-padded document number,\n",(0,s.jsx)(n.code,{children:"N"})," is replaced with the major version of the document, and\n",(0,s.jsx)(n.code,{children:"T"})," is replaced with the slugified title.\nFor a document with the number 190, with a major version number 2 and a slugified title ",(0,s.jsx)(n.code,{children:"flavor-naming"}),",\nthe resulting file name would be ",(0,s.jsx)(n.code,{children:"scs-0190-v2-flavor-naming.md"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Supplements deviate from this pattern in that they employ a ",(0,s.jsx)(n.code,{children:"w"})," instead of a ",(0,s.jsx)(n.code,{children:"v"})," in front of the version\nnumber, and each supplement uses the same document number as the main document it is extending."]}),"\n",(0,s.jsxs)(n.p,{children:["The second digit in ",(0,s.jsx)(n.code,{children:"XXXX"})," describes the track where the document belongs:"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Track"}),(0,s.jsx)(n.th,{children:"Number"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Global"}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"IaaS"}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"KaaS"}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"IAM"}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Ops"}),(0,s.jsx)(n.td,{children:"4"})]})]})]}),"\n",(0,s.jsx)(n.p,{children:"In addition to the number, each document has the following metadata,\nembedded in the markdown header."}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Field name"}),(0,s.jsx)(n.th,{children:"Requirement"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"type"})}),(0,s.jsx)(n.td,{children:"REQUIRED"}),(0,s.jsxs)(n.td,{children:["one of ",(0,s.jsx)(n.code,{children:"Procedural"}),", ",(0,s.jsx)(n.code,{children:"Standard"}),", ",(0,s.jsx)(n.code,{children:"Decision Record"}),", or ",(0,s.jsx)(n.code,{children:"Supplement"})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"status"})}),(0,s.jsx)(n.td,{children:"REQUIRED"}),(0,s.jsxs)(n.td,{children:["one of ",(0,s.jsx)(n.code,{children:"Draft"}),", ",(0,s.jsx)(n.code,{children:"Stable"}),", ",(0,s.jsx)(n.code,{children:"Deprecated"}),", or ",(0,s.jsx)(n.code,{children:"Rejected"})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"track"})}),(0,s.jsx)(n.td,{children:"REQUIRED"}),(0,s.jsxs)(n.td,{children:["one of ",(0,s.jsx)(n.code,{children:"Global"}),", ",(0,s.jsx)(n.code,{children:"IaaS"}),", ",(0,s.jsx)(n.code,{children:"KaaS"}),", ",(0,s.jsx)(n.code,{children:"IAM"}),", ",(0,s.jsx)(n.code,{children:"Ops"})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"supplements"})}),(0,s.jsxs)(n.td,{children:["REQUIRED precisely when ",(0,s.jsx)(n.code,{children:"type"})," is ",(0,s.jsx)(n.code,{children:"Supplement"})]}),(0,s.jsx)(n.td,{children:"list of documents that are extended by this document (e.g., multiple major versions)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"deprecated_at"})}),(0,s.jsxs)(n.td,{children:["REQUIRED if ",(0,s.jsx)(n.code,{children:"status"})," is ",(0,s.jsx)(n.code,{children:"Deprecated"})]}),(0,s.jsx)(n.td,{children:"ISO formatted date indicating the date after which the deprecation is in effect"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"stabilized_at"})}),(0,s.jsxs)(n.td,{children:["REQUIRED if ",(0,s.jsx)(n.code,{children:"status"})," was ever ",(0,s.jsx)(n.code,{children:"Stable"})]}),(0,s.jsx)(n.td,{children:"ISO formatted date indicating the date after which the document was considered stable"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"rejected_at"})}),(0,s.jsxs)(n.td,{children:["REQUIRED if ",(0,s.jsx)(n.code,{children:"status"})," is ",(0,s.jsx)(n.code,{children:"Rejected"})]}),(0,s.jsx)(n.td,{children:"ISO formatted date indicating the date on which the document was rejected"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"replaced_by"})}),(0,s.jsxs)(n.td,{children:["RECOMMENDED if ",(0,s.jsx)(n.code,{children:"status"})," is ",(0,s.jsx)(n.code,{children:"Deprecated"})," or ",(0,s.jsx)(n.code,{children:"Rejected"}),", FORBIDDEN otherwise"]}),(0,s.jsx)(n.td,{children:"List of documents which replace this document."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"replaces"})}),(0,s.jsx)(n.td,{children:"OPTIONAL"}),(0,s.jsx)(n.td,{children:"List of documents which this document replaces."})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"sections",children:"Sections"}),"\n",(0,s.jsx)(n.h4,{id:"standard-1",children:"Standard"}),"\n",(0,s.jsx)(n.p,{children:"Each Standard document MUST have the following sections:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["An ",(0,s.jsx)(n.em,{children:"Introduction"})," providing context on the document and linking to other relevant materials."]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.em,{children:"Motivation"})," section which details why this document or the thing it describes is necessary."]}),"\n",(0,s.jsx)(n.li,{children:"A section containing the actual standardization decision."}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.em,{children:"Conformance Tests"})," section that contains hints on how to validate\nconformance with this spec, ideally links to conformance test cases."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"We also RECOMMEND the following sections:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.em,{children:"Terminology"})," section which briefly describes terms used in the document, including possible abbreviations."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In addition, the following OPTIONAL sections should be considered:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.em,{children:"Design Considerations"})," section for Standard type documents,\nwhich details other choices\nwhich have been considered for the specific feature\nbut were ultimately rejected."]}),"\n",(0,s.jsxs)(n.li,{children:["An ",(0,s.jsx)(n.em,{children:"Open Questions"}),' section which links to issues\ndetailing any open discussion points with respect to a document.\nThis section is RECOMMENDED during the discussion phase (pre 1.0.0)\nas a "table of contents" of things to work on in that context.']}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.em,{children:"Related Documents"})," section which references related Standards\nor Decisions, both upstream and/or other SCS documents."]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"decision-record-1",children:"Decision Record"}),"\n",(0,s.jsx)(n.p,{children:"Each Decision Record document MUST have the following sections:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["An ",(0,s.jsx)(n.em,{children:"Abstract"})," providing a brief introduction on the topic of the document."]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.em,{children:"Context"})," section describing the issue relevant for motivating this Decision Record."]}),"\n",(0,s.jsx)(n.li,{children:"A section containing the actual decision that is introduced. The section should also include\nreasoning for this decision."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"We also RECOMMEND the following sections:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.em,{children:"Terminology"})," section which shortly describes terms used in the document, including possible abbreviations."]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.em,{children:"Related Documents"})," section which references related Standards\nor Decisions, both upstream and/or other SCS documents."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In addition, the following OPTIONAL sections should be considered:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.em,{children:"Consequences"})," section describing outcomes from implementing the changes described."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"process",children:"Process"}),"\n",(0,s.jsx)(n.p,{children:"The lifecycle of an SCS document goes through the following phases:\nDraft, Stable, Deprecated, and Rejected."}),"\n",(0,s.jsx)(n.mermaid,{value:'graph TD\n A["Draft (Proposal)"] --\x3e|Pull Request| B[Draft]\n B --\x3e|Pull Request| D[Stable]\n B --\x3e|Pull Request| E[Rejected]\n D --\x3e|Pull Request| F[Deprecated]'}),"\n",(0,s.jsxs)(n.p,{children:["All decisions for phase transitions follow loose consensus,\nwhere the group which has to form the consensus depends on the ",(0,s.jsx)(n.code,{children:"track"})," of the document:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"IaaS: The team working on infrastructure-as-a-service topics"}),"\n",(0,s.jsx)(n.li,{children:"KaaS: The team working on Kubernetes-as-a-service topics"}),"\n",(0,s.jsx)(n.li,{children:"Ops: The team working on operations topics"}),"\n",(0,s.jsx)(n.li,{children:"IAM: The team working on identity and access management topics"}),"\n",(0,s.jsx)(n.li,{children:"Global: The entire SCS community"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Supplements may be kept in Draft state, because they are not authoritative."}),"\n",(0,s.jsx)(n.h3,{id:"proposal-phase",children:"Proposal phase"}),"\n",(0,s.jsx)(n.h4,{id:"proposal-of-a-new-document",children:"Proposal of a new document"}),"\n",(0,s.jsxs)(n.p,{children:["To propose a new SCS document,\na community participant creates a pull request on GitHub\nagainst the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards",children:"standards repository in the SovereignCloudStack organisation"}),".\nIn the beginning, the pull request will contain a draft of an SCS document and\nthe community participant should present it to the SCS community.\nThey may refer to the ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/community/",children:"SCS Community page"}),"\nfor an overview of applicable means of communication and online meetings\nto get in touch with the SCS community.\nCommunity participants are encouraged to present their proposal to the SCS community early on.\nNote that the proposal draft's content does not need to be finished in any way at this stage."]}),"\n",(0,s.jsxs)(n.p,{children:["The pull request for the proposal MUST add exactly one SCS document,\nin the ",(0,s.jsx)(n.code,{children:"Standards"})," folder.\nIn the proposal phase,\nthe document number MUST be replaced with ",(0,s.jsx)(n.code,{children:"xxxx"})," in the file name,\nexcept for a Supplement, which uses the document number of the document it refers to.\nThe major version MUST be 1."]}),"\n",(0,s.jsxs)(n.p,{children:["For a document with a slugified title ",(0,s.jsx)(n.code,{children:"flavor-naming"}),",\nthe file name would for instance be ",(0,s.jsx)(n.code,{children:"scs-xxxx-v1-flavor-naming.md"}),";\nfor a Supplement of ",(0,s.jsx)(n.code,{children:"scs-0100-v3-flavor-naming.md"}),",\nthe file name might be ",(0,s.jsx)(n.code,{children:"scs-0100-w1-flavor-naming-implementation-testing.md"})," (note the ",(0,s.jsx)(n.code,{children:"w1"}),"!)."]}),"\n",(0,s.jsxs)(n.p,{children:["The metadata MUST indicate the intended ",(0,s.jsx)(n.code,{children:"track"})," and ",(0,s.jsx)(n.code,{children:"type"})," of the document,\nand the ",(0,s.jsx)(n.code,{children:"status"})," MUST be set to ",(0,s.jsx)(n.code,{children:"Draft"}),";\nfor a Supplement, the ",(0,s.jsx)(n.code,{children:"supplements"})," field MUST be set\nto a list of documents (usually containing one element)."]}),"\n",(0,s.jsxs)(n.p,{children:["Upon acceptance by the group of people identified by the ",(0,s.jsx)(n.code,{children:"track"}),",\na number is assigned\n(the next unused number)\nand the proposer is asked\nto rename the file to replace the ",(0,s.jsx)(n.code,{children:"xxxx"})," with that number\nbefore the merge of the pull request."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note:"}),"\nDocuments on the ",(0,s.jsx)(n.code,{children:"Design Record"})," track MAY be proposed or accepted directly into ",(0,s.jsx)(n.code,{children:"Stable"})," state,\nif no further discussion is required."]}),"\n",(0,s.jsxs)(n.p,{children:["Hereafter,\nthe pull request can be merged\nand henceforth the document is an official SCS document in ",(0,s.jsx)(n.code,{children:"Draft"})," state."]}),"\n",(0,s.jsx)(n.h4,{id:"proposal-of-a-major-update-to-a-stable-document",children:"Proposal of a major update to a stable document"}),"\n",(0,s.jsxs)(n.p,{children:["To propose major update to a Stable SCS document,\na community participant creates a pull request on GitHub\nagainst the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards",children:"standards repository in the SovereignCloudStack organisation"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The pull request MUST add exactly one SCS document,\nin the ",(0,s.jsx)(n.code,{children:"Standards"})," folder.\nThe document number MUST be the same as the document it is updating,\nand the major version number MUST be incremented by 1.\nThe slugified title MAY be changed."]}),"\n",(0,s.jsxs)(n.p,{children:["It MUST refer to the old document in its ",(0,s.jsx)(n.code,{children:"replaces"})," metadata.\nThe pull request SHOULD NOT modify the previous document;\ndeprecation of the previous document\nas well as adding the ",(0,s.jsx)(n.code,{children:"replaced_by"})," metadata is a separate step,\nand can only be executed once the new document is ",(0,s.jsx)(n.code,{children:"Stable"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["For a document updating a hypothetical SCS-0390-v3 document,\nthe file name may be ",(0,s.jsx)(n.code,{children:"scs-0390-v4-flavor-naming-this-time-its-serious.md"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Other than the file naming difference,\nthe proposal process is the same as for new documents.\nIn particular, the new document starts out in ",(0,s.jsx)(n.code,{children:"Draft"})," state\nand does not automatically become part of the normative corpus of an SCS release."]}),"\n",(0,s.jsx)(n.h3,{id:"development-phase-draft",children:"Development phase (Draft)"}),"\n",(0,s.jsx)(n.p,{children:"In this phase,\nthe document is developed inside the SCS community."}),"\n",(0,s.jsx)(n.p,{children:"It should not be considered to be normative for any SCS release,\neven if an SCS release happens after the acceptance of the document."}),"\n",(0,s.jsx)(n.p,{children:"Experimental and exploratory implementations are encouraged,\nhowever, implementors must be prepared for breaking changes."}),"\n",(0,s.jsx)(n.p,{children:"Changes to the documents are gated through pull requests."}),"\n",(0,s.jsx)(n.h3,{id:"stabilized-phase-stable",children:"Stabilized phase (Stable)"}),"\n",(0,s.jsxs)(n.p,{children:["Once the document is deemed ready for production use,\nits ",(0,s.jsx)(n.code,{children:"status"})," is changed to ",(0,s.jsx)(n.code,{children:"Stable"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["If the document in question is a ",(0,s.jsx)(n.code,{children:"Standard"}),"\n(and if applicable),\nthe following conditions MUST all be satisfied before stabilizing:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"the corresponding conformance tests have been implemented\naccording to the general guidelines,"}),"\n",(0,s.jsx)(n.li,{children:"they have been shown to work with the reference implementation,"}),"\n",(0,s.jsxs)(n.li,{children:["they are documented in the standard or one of its ",(0,s.jsx)(n.code,{children:"Supplement"}),"\ndocuments."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"After stabilization,\nchanges to the document which may render existing implementations non-conformant\nMUST NOT be made."}),"\n",(0,s.jsx)(n.p,{children:"If a breaking change to an existing SCS document is deemed necessary,\na new document with a new number shall be created\nand the old document SHOULD be deprecated."}),"\n",(0,s.jsx)(n.h3,{id:"deprecation-phase-deprecated",children:"Deprecation phase (Deprecated)"}),"\n",(0,s.jsx)(n.p,{children:"When a document is no longer deemed fit for production use,\nit can be marked as deprecated."}),"\n",(0,s.jsxs)(n.p,{children:["Deprecations SHOULD be announced ahead of their execution by setting the\n",(0,s.jsx)(n.code,{children:"deprecated_at"})," field to a future date and moving the ",(0,s.jsx)(n.code,{children:"status"})," to ",(0,s.jsx)(n.code,{children:"Deprecated"}),".\nThis signals current and future implementors\nthat the subject of the document\nis not considered necessary or state of the art anymore."]}),"\n",(0,s.jsxs)(n.p,{children:["If one or more replacement documents for the document exists,\nit MUST be listed in the ",(0,s.jsx)(n.code,{children:"replaced_by"})," metadata field."]}),"\n",(0,s.jsx)(n.h3,{id:"rejection",children:"Rejection"}),"\n",(0,s.jsxs)(n.p,{children:["If a document is removed from the normative corpus of SCS standards,\nits status is changed to ",(0,s.jsx)(n.code,{children:"Rejected"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["If one or more replacement documents for the document exists,\nit MUST be listed in the ",(0,s.jsx)(n.code,{children:"replaced_by"})," metadata field."]}),"\n",(0,s.jsx)(n.h2,{id:"open-questions",children:"Open Questions"}),"\n",(0,s.jsx)(n.h3,{id:"stabilization-criteria",children:"Stabilization criteria"}),"\n",(0,s.jsx)(n.p,{children:"When should a document be stabilized?\nShould we require at least one public implementation?\nShould we require a minimum experimental time?\nWhat about non-Standard track documents?"}),"\n",(0,s.jsx)(n.h3,{id:"breaking-change-criteria",children:"Breaking change criteria"}),"\n",(0,s.jsx)(n.p,{children:'When is a change breaking and cannot be applied to a Stable document?\nWhat about previously undefined behaviour (uncovered edge case)?\nWhat about ambiguous wording?\nDo we need a separate "Errata" section?'}),"\n",(0,s.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsx)(n.h3,{id:"versioning",children:"Versioning"}),"\n",(0,s.jsxs)(n.p,{children:["An alternative to the proposed scheme for stabilization\nis the use of ",(0,s.jsx)(n.a,{href:"https://semver.org/",children:"SemVer-like"})," versioning."]}),"\n",(0,s.jsxs)(n.p,{children:["In that case, one would have an individual version number with each document,\nwhere a major version greater than zero indicates a stable document.\nThe ",(0,s.jsx)(n.code,{children:"Stable"})," state would be merged with ",(0,s.jsx)(n.code,{children:"Draft"})," state into an ",(0,s.jsx)(n.em,{children:"Active"})," state\nand shared between the stabilized and the development phase."]}),"\n",(0,s.jsx)(n.p,{children:"The advantages of such an approach are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"It is easy to recognize whether an SCS document has changed between two SCS\nreleases, just by looking at the released version number."}),"\n",(0,s.jsx)(n.li,{children:"It is possible to make breaking changes after stabilization by increasing the\nmajor version number."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The disadvantages of that approach are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"It is possible to make breaking changes after stabilization.\nPotentially, a hypothetical SCS-1234 document might refer to something completely different\nin a hypothetical R15 release than what it meant in R5,\nif there have been sufficient, gradual breaking changes to the document."}),"\n",(0,s.jsx)(n.p,{children:"That means that for proper linking,\nit would be required to always include the major version number\nwhen referring to an SCS document."}),"\n",(0,s.jsx)(n.p,{children:'This implies having to keep all former versions around in a canonical, linkable form.\nThis induces non-trivial organizational and editorial overhead\nand raises questions around which changes are acceptable to "archived" versions,\nif any.'}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"It would require a clone of the SemVer spec,\nas that spec is highly specific toward software\nand does not fully\n(at least not in the standard-as-written)\ncover specifics of a standards organisation's use-cases."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"acknowledgements",children:"Acknowledgements"}),"\n",(0,s.jsxs)(n.p,{children:["This document is heavily inspired by ",(0,s.jsx)(n.a,{href:"https://xmpp.org/extensions/xep-0001.html",children:"XEP-0001"}),", as published by the XMPP Standards Foundation."]})]})}function h(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(96540);const s={},d=i.createContext(s);function r(e){const n=i.useContext(d);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1c94670e.716d1f7b.js b/assets/js/1c94670e.716d1f7b.js new file mode 100644 index 0000000000..08f3adbd6b --- /dev/null +++ b/assets/js/1c94670e.716d1f7b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[82336],{31671:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"OpenDesk on SCS","slug":"/category/opendesk-on-scs","permalink":"/user-docs/category/opendesk-on-scs","sidebar":"userDocs","navigation":{"previous":{"title":"Application Examples","permalink":"/user-docs/category/application-examples"},"next":{"title":"Overview","permalink":"/user-docs/application-examples/opendesk-on-scs/overview"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/1ca0f8e7.5b356902.js b/assets/js/1ca0f8e7.5b356902.js new file mode 100644 index 0000000000..d61f99cff9 --- /dev/null +++ b/assets/js/1ca0f8e7.5b356902.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[37810],{93817:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"container/components/container-registry/docs/scs-deployment","title":"SCS deployment","description":"The following steps were utilized for deploying the SCS reference installation of the Harbor container registry,","source":"@site/docs/03-container/components/container-registry/docs/scs-deployment.md","sourceDirName":"03-container/components/container-registry/docs","slug":"/container/components/container-registry/docs/scs-deployment","permalink":"/docs/container/components/container-registry/docs/scs-deployment","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/scs-deployment.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Quickstart","permalink":"/docs/container/components/container-registry/docs/quickstart"},"next":{"title":"Rate limit","permalink":"/docs/container/components/container-registry/docs/rate_limit"}}');var r=s(74848),i=s(28453);const c={},o="SCS deployment",l={},a=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install Harbor",id:"install-harbor",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"scs-deployment",children:"SCS deployment"})}),"\n",(0,r.jsxs)(n.p,{children:["The following steps were utilized for deploying the SCS reference installation of the Harbor container registry,\nwhich is available at ",(0,r.jsx)(n.a,{href:"https://registry.scs.community",children:"https://registry.scs.community"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Kubernetes cluster v1.20+","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["We used the R5 version of SCS KaaS V1, which includes an ingress controller and cert manager","\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"export KUBECONFIG=/path/to/kubeconfig\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Flux CLI (it is part of SCS KaaS V1)","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Installation documentation: ",(0,r.jsx)(n.a,{href:"https://fluxcd.io/flux/installation/#install-the-flux-cli",children:"https://fluxcd.io/flux/installation/#install-the-flux-cli"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s https://fluxcd.io/install.sh | sudo FLUX_VERSION=2.2.3 bash\nflux install\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://kubernetes.io/docs/reference/kubectl/",children:"kubectl"})}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"install-harbor",children:"Install Harbor"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Take ",(0,r.jsx)(n.em,{children:"ingress-nginx-controller"})," LoadBalancer IP address and create DNS record for Harbor."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"kubectl get svc -n ingress-nginx\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\ningress-nginx-controller LoadBalancer 100.92.14.168 81.163.194.219 80:30799/TCP,443:32482/TCP 2m51s\ningress-nginx-controller-admission ClusterIP 100.88.40.231 443/TCP 2m51s\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Generate secrets and install Harbor:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"base/harbor-secrets.bash # pwgen and htpasswd need to be installed\nenvs/public/s3-credentials.bash \nkubectl apply -k envs/public/\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>o});var t=s(96540);const r={},i=t.createContext(r);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1df93b7f.39dc7e68.js b/assets/js/1df93b7f.39dc7e68.js new file mode 100644 index 0000000000..eba0a6b943 --- /dev/null +++ b/assets/js/1df93b7f.39dc7e68.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[34583],{54368:(e,t,l)=>{l.d(t,{A:()=>d});l(96540);var s=l(89839);const a="gradient_pRJN",n="border_XcL8",o="bottom_ufNC";var i=l(44586),r=l(74848);const d=e=>{const{topLayers:t}=e,l=(0,i.A)().globalData["global-data-plugin"].default.architecturalOverviewData;return l?(0,r.jsxs)("div",{className:`${a} ${n} row`,children:[!t&&(0,r.jsx)("div",{style:{display:"flex",margin:" 10px 0 4px 12px"},children:(0,r.jsx)("h5",{style:{marginBottom:0},children:"SCS Component Map"})}),(0,r.jsxs)("div",{style:{display:"flex",flexWrap:"wrap"},children:[(0,r.jsx)("div",{style:{padding:"8px 8px 8px 8px",margin:"0 0 0 0"},className:`${o} col col--3`,children:l.ops.map(((e,l)=>(0,r.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components},l)))}),(0,r.jsxs)("div",{className:"col col--6",style:{padding:"8px 8px 8px 8px",margin:"0 0 0 0"},children:[l.container.map(((e,a)=>(0,r.jsx)("div",{style:{marginBottom:e===l.container[0]?"8px":"0"},children:(0,r.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components})},a))),l.iaas.map(((e,l)=>(0,r.jsx)("div",{children:(0,r.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components})},l)))]}),(0,r.jsx)("div",{className:"col col--3",style:{padding:"8px 8px 8px 8px",margin:"0 0 0 0"},children:l.iam.map(((e,l)=>(0,r.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components},l)))})]})]}):(0,r.jsx)("div",{children:"No data available."})}},89839:(e,t,l)=>{l.d(t,{A:()=>d});l(96540);const s="contentCard_uSpk",a="layerComponent_syzR",n="layerComponentWip_fSEJ";var o=l(28774),i=l(56347),r=l(74848);const d=e=>{const{title:t,body:l,url:d,buttonText:c,style:x,small:m,components:p}=e,h=(0,i.zy)();return(0,r.jsxs)("div",{style:x,className:`${s} card`,children:[(0,r.jsx)("div",{className:"card__header",children:m?(0,r.jsx)("h5",{style:{marginLeft:"-6px"},children:t}):(0,r.jsx)("h3",{children:t})}),(0,r.jsx)("div",{className:"card__body",children:(0,r.jsx)("p",{children:l})}),(0,r.jsx)("div",{style:{display:"flex",flexWrap:"wrap"},children:p&&p.map(((e,t)=>(0,r.jsx)(o.A,{to:e.url,children:(0,r.jsx)("div",{style:h.pathname==e.url?{color:"blue",backgroundColor:"#0066ff44"}:{},className:"true"==e.stable?a:n,children:e.title})},t)))}),c&&(0,r.jsx)("div",{className:"card__footer",children:(0,r.jsx)(o.A,{className:"button button--secondary button--md",to:d,children:c})})]})}},68198:(e,t,l)=>{l.r(t),l.d(t,{default:()=>r});l(96540),l(28774);var s=l(44586),a=l(59504);var n=l(89839),o=l(54368),i=l(74848);function r(){const e=(0,s.A)().globalData,t=e["global-data-plugin"].default.featureContentData,l=e["global-data-plugin"].default.additionalResourcesData;return(0,i.jsx)(a.A,{description:"Documentation and Community Platform for the Sovereign Cloud Stack",children:(0,i.jsx)("main",{children:(0,i.jsxs)("div",{className:"container",children:[(0,i.jsx)("div",{className:"row",style:{marginTop:"2rem"},children:(0,i.jsxs)("div",{className:"col col--12",children:[(0,i.jsx)("h1",{children:"Welcome to the SCS Documentation"}),(0,i.jsx)("p",{children:"Find user guides, code samples, deployment examples, reference, community pages and more."})]})}),(0,i.jsx)("div",{className:"row",children:t.map(((e,t)=>(0,i.jsx)("div",{className:"col col--3",children:(0,i.jsx)(n.A,{title:e.title,body:e.body,url:e.url,buttonText:e.buttonText})},t)))}),(0,i.jsxs)("div",{className:"row",style:{marginTop:"3rem"},children:[(0,i.jsx)("div",{className:"col col--12",children:(0,i.jsx)("h1",{children:"Architectural Layers"})}),(0,i.jsx)("div",{style:{marginLeft:"16px",marginRight:"16px"},children:(0,i.jsx)(o.A,{topLayers:!0})})]}),(0,i.jsx)("div",{className:"row",style:{marginTop:"3rem"},children:(0,i.jsx)("div",{className:"col col--12",children:(0,i.jsx)("h1",{children:"Additional Resources"})})}),(0,i.jsx)("div",{className:"row",style:{marginBottom:"5rem"},children:l.map(((e,t)=>(0,i.jsx)("div",{className:"col col--3",children:(0,i.jsx)(n.A,{title:e.title,body:e.body,url:e.url,buttonText:e.buttonText})},t)))})]})})})}}}]); \ No newline at end of file diff --git a/assets/js/1e818dbe.462fbdf9.js b/assets/js/1e818dbe.462fbdf9.js new file mode 100644 index 0000000000..41aa808581 --- /dev/null +++ b/assets/js/1e818dbe.462fbdf9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[41335],{30920:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>d,frontMatter:()=>c,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"tools/nextcloud","title":"Nextcloud","description":"We have a Nextcloud","source":"@site/community/tools/nextcloud.md","sourceDirName":"tools","slug":"/tools/nextcloud","permalink":"/community/tools/nextcloud","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Mailing Lists","permalink":"/community/tools/mailinglists"},"next":{"title":"Zuul","permalink":"/community/tools/zuul"}}');var s=n(74848),i=n(28453);const c={},r="Nextcloud",a={},l=[];function u(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"nextcloud",children:"Nextcloud"})}),"\n",(0,s.jsxs)(t.p,{children:["We have a ",(0,s.jsx)(t.a,{href:"https://nextcloud.com",children:"Nextcloud"}),"\n",(0,s.jsx)(t.a,{href:"https://scs.sovereignit.de",children:"instance"})," for sharing files, doing polls, ...\nsetup for things that are not public."]}),"\n",(0,s.jsxs)(t.p,{children:["You can contribute to SCS via the github workflows, asking questions there (via\nopening issues against the issues repository), submitting pull requests, ...\nIf you want to contribute on a regular basis, we are happy to also onboard you\nto the nextcloud and do an onboarding call. Nextcloud onboarding also adds you\nto the ",(0,s.jsx)(t.code,{children:"scs-member@lists.scs.community"})," mailing list which also add you to the\nannouncement list (described in the next paragraph)."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>r});var o=n(96540);const s={},i=o.createContext(s);function c(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1f34ee25.dab9c4a7.js b/assets/js/1f34ee25.dab9c4a7.js new file mode 100644 index 0000000000..87b010087d --- /dev/null +++ b/assets/js/1f34ee25.dab9c4a7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[53894],{16030:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>c,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"cloud-resources/wavestack","title":"Getting Started with Wavestack","description":"Getting Started with Wavestack","source":"@site/community/cloud-resources/wavestack.md","sourceDirName":"cloud-resources","slug":"/cloud-resources/wavestack","permalink":"/community/cloud-resources/wavestack","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Getting Started with Wavestack","version":"2023-03-02T00:00:00.000Z","author":"Linus Walther"},"sidebar":"community","previous":{"title":"Getting Started Gaia-X Demonstrator @ plusserver","permalink":"/community/cloud-resources/plusserver-gx-scs"},"next":{"title":"Contribute to Docs","permalink":"/community/category/contribute-to-docs"}}');var i=n(74848),r=n(28453);const a={title:"Getting Started with Wavestack",version:new Date("2023-03-02T00:00:00.000Z"),author:"Linus Walther"},c=void 0,o={},l=[{value:"Getting Started with Wavestack",id:"getting-started-with-wavestack",level:2},{value:"URLs for access",id:"urls-for-access",level:2},{value:"Authentication (UI)",id:"authentication-ui",level:2},{value:"OpenStackClient (CLI)",id:"openstackclient-cli",level:2}];function d(e){const t={a:"a",h2:"h2",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"getting-started-with-wavestack",children:"Getting Started with Wavestack"}),"\n",(0,i.jsx)(t.h2,{id:"urls-for-access",children:"URLs for access"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["UI (Horizon): ",(0,i.jsx)(t.a,{href:"https://dashboard.wavestack.de/",children:"https://dashboard.wavestack.de/"})]}),"\n",(0,i.jsxs)(t.li,{children:["API auth url (Keystone): ",(0,i.jsx)(t.a,{href:"https://api.wavestack.de:5000",children:"https://api.wavestack.de:5000"})]}),"\n",(0,i.jsxs)(t.li,{children:["Object Storage endpoint (S3/SWIFT): ",(0,i.jsx)(t.a,{href:"https://rgw.muc5.wavestack.de:443",children:"https://rgw.muc5.wavestack.de:443"})]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"authentication-ui",children:"Authentication (UI)"}),"\n",(0,i.jsx)(t.p,{children:"For your login you will need:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Username"}),"\n",(0,i.jsx)(t.li,{children:"Password"}),"\n",(0,i.jsx)(t.li,{children:"Domain"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"openstackclient-cli",children:"OpenStackClient (CLI)"}),"\n",(0,i.jsxs)(t.p,{children:["See: ",(0,i.jsx)(t.a,{href:"/community/cloud-resources/getting-started-openstack",children:"Getting Started with OpenStack"})]})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>c});var s=n(96540);const i={},r=s.createContext(i);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2049.521b0348.js b/assets/js/2049.521b0348.js new file mode 100644 index 0000000000..e5cefe7cee --- /dev/null +++ b/assets/js/2049.521b0348.js @@ -0,0 +1 @@ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2049],{76225:e=>{var t,n,r,i;(t=e.exports).foldLength=75,t.newLineChar="\r\n",t.helpers={updateTimezones:function(e){var n,r,i,s,o,a;if(!e||"vcalendar"!==e.name)return e;for(n=e.getAllSubcomponents(),r=[],i={},o=0;o0&&"\\"===e[n-1]))return n;n+=1}return-1},binsearchInsert:function(e,t,n){if(!e.length)return 0;for(var r,i,s=0,o=e.length-1;s<=o;)if((i=n(t,e[r=s+Math.floor((o-s)/2)]))<0)o=r-1;else{if(!(i>0))break;s=r+1}return i<0?r:i>0?r+1:r},dumpn:function(){t.debug&&("undefined"!=typeof console&&"log"in console?t.helpers.dumpn=function(e){console.log(e)}:t.helpers.dumpn=function(e){dump(e+"\n")},t.helpers.dumpn(arguments[0]))},clone:function(e,n){if(e&&"object"==typeof e){if(e instanceof Date)return new Date(e.getTime());if("clone"in e)return e.clone();if(Array.isArray(e)){for(var r=[],i=0;i65535?2:1:(n+=t.newLineChar+" "+r.substring(0,i),r=r.substring(i),i=s=0)}return n.substr(t.newLineChar.length+1)},pad2:function(e){switch("string"!=typeof e&&("number"==typeof e&&(e=parseInt(e)),e=String(e)),e.length){case 0:return"00";case 1:return"0"+e;default:return e}},trunc:function(e){return e<0?Math.ceil(e):Math.floor(e)},inherits:function(e,n,r){function i(){}i.prototype=e.prototype,n.prototype=new i,r&&t.helpers.extend(r,n.prototype)},extend:function(e,t){for(var n in e){var r=Object.getOwnPropertyDescriptor(e,n);r&&!Object.getOwnPropertyDescriptor(t,n)&&Object.defineProperty(t,n,r)}return t}},t.design=function(){"use strict";var e=/\\\\|\\,|\\[Nn]/g,n=/\\|,|\n/g;function r(e,t){return{matches:/.*/,fromICAL:function(t,n){return function(e,t,n){if(-1===e.indexOf("\\"))return e;n&&(t=new RegExp(t.source+"|\\\\"+n));return e.replace(t,p)}(t,e,n)},toICAL:function(e,n){var r=t;return n&&(r=new RegExp(r.source+"|"+n)),e.replace(r,(function(e){switch(e){case"\\":return"\\\\";case";":return"\\;";case",":return"\\,";case"\n":return"\\n";default:return e}}))}}}var i={defaultType:"text"},s={defaultType:"text",multiValue:","},o={defaultType:"text",structuredValue:";"},a={defaultType:"integer"},l={defaultType:"date-time",allowedTypes:["date-time","date"]},c={defaultType:"date-time"},u={defaultType:"uri"},d={defaultType:"utc-offset"},h={defaultType:"recur"},f={defaultType:"date-and-or-time",allowedTypes:["date-time","date","text"]};function p(e){switch(e){case"\\\\":return"\\";case"\\;":return";";case"\\,":return",";case"\\n":case"\\N":return"\n";default:return e}}var g={categories:s,url:u,version:i,uid:i},m={boolean:{values:["TRUE","FALSE"],fromICAL:function(e){return"TRUE"===e},toICAL:function(e){return e?"TRUE":"FALSE"}},float:{matches:/^[+-]?\d+\.\d+$/,fromICAL:function(e){var n=parseFloat(e);return t.helpers.isStrictlyNaN(n)?0:n},toICAL:function(e){return String(e)}},integer:{fromICAL:function(e){var n=parseInt(e);return t.helpers.isStrictlyNaN(n)?0:n},toICAL:function(e){return String(e)}},"utc-offset":{toICAL:function(e){return e.length<7?e.substr(0,3)+e.substr(4,2):e.substr(0,3)+e.substr(4,2)+e.substr(7,2)},fromICAL:function(e){return e.length<6?e.substr(0,3)+":"+e.substr(3,2):e.substr(0,3)+":"+e.substr(3,2)+":"+e.substr(5,2)},decorate:function(e){return t.UtcOffset.fromString(e)},undecorate:function(e){return e.toString()}}},v=t.helpers.extend(m,{text:r(/\\\\|\\;|\\,|\\[Nn]/g,/\\|;|,|\n/g),uri:{},binary:{decorate:function(e){return t.Binary.fromString(e)},undecorate:function(e){return e.toString()}},"cal-address":{},date:{decorate:function(e,n){return w.strict?t.Time.fromDateString(e,n):t.Time.fromString(e,n)},undecorate:function(e){return e.toString()},fromICAL:function(e){return!w.strict&&e.length>=15?v["date-time"].fromICAL(e):e.substr(0,4)+"-"+e.substr(4,2)+"-"+e.substr(6,2)},toICAL:function(e){var t=e.length;return 10==t?e.substr(0,4)+e.substr(5,2)+e.substr(8,2):t>=19?v["date-time"].toICAL(e):e}},"date-time":{fromICAL:function(e){if(w.strict||8!=e.length){var t=e.substr(0,4)+"-"+e.substr(4,2)+"-"+e.substr(6,2)+"T"+e.substr(9,2)+":"+e.substr(11,2)+":"+e.substr(13,2);return e[15]&&"Z"===e[15]&&(t+="Z"),t}return v.date.fromICAL(e)},toICAL:function(e){var t=e.length;if(10!=t||w.strict){if(t>=19){var n=e.substr(0,4)+e.substr(5,2)+e.substr(8,5)+e.substr(14,2)+e.substr(17,2);return e[19]&&"Z"===e[19]&&(n+="Z"),n}return e}return v.date.toICAL(e)},decorate:function(e,n){return w.strict?t.Time.fromDateTimeString(e,n):t.Time.fromString(e,n)},undecorate:function(e){return e.toString()}},duration:{decorate:function(e){return t.Duration.fromString(e)},undecorate:function(e){return e.toString()}},period:{fromICAL:function(e){var n=e.split("/");return n[0]=v["date-time"].fromICAL(n[0]),t.Duration.isValueString(n[1])||(n[1]=v["date-time"].fromICAL(n[1])),n},toICAL:function(e){return w.strict||10!=e[0].length?e[0]=v["date-time"].toICAL(e[0]):e[0]=v.date.toICAL(e[0]),t.Duration.isValueString(e[1])||(w.strict||10!=e[1].length?e[1]=v["date-time"].toICAL(e[1]):e[1]=v.date.toICAL(e[1])),e.join("/")},decorate:function(e,n){return t.Period.fromJSON(e,n,!w.strict)},undecorate:function(e){return e.toJSON()}},recur:{fromICAL:function(e){return t.Recur._stringToData(e,!0)},toICAL:function(e){var n="";for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){var i=e[r];"until"==r?i=i.length>10?v["date-time"].toICAL(i):v.date.toICAL(i):"wkst"==r?"number"==typeof i&&(i=t.Recur.numericDayToIcalDay(i)):Array.isArray(i)&&(i=i.join(",")),n+=r.toUpperCase()+"="+i+";"}return n.substr(0,n.length-1)},decorate:function(e){return t.Recur.fromData(e)},undecorate:function(e){return e.toJSON()}},time:{fromICAL:function(e){if(e.length<6)return e;var t=e.substr(0,2)+":"+e.substr(2,2)+":"+e.substr(4,2);return"Z"===e[6]&&(t+="Z"),t},toICAL:function(e){if(e.length<8)return e;var t=e.substr(0,2)+e.substr(3,2)+e.substr(6,2);return"Z"===e[8]&&(t+="Z"),t}}}),y=t.helpers.extend(g,{action:i,attach:{defaultType:"uri"},attendee:{defaultType:"cal-address"},calscale:i,class:i,comment:i,completed:c,contact:i,created:c,description:i,dtend:l,dtstamp:c,dtstart:l,due:l,duration:{defaultType:"duration"},exdate:{defaultType:"date-time",allowedTypes:["date-time","date"],multiValue:","},exrule:h,freebusy:{defaultType:"period",multiValue:","},geo:{defaultType:"float",structuredValue:";"},"last-modified":c,location:i,method:i,organizer:{defaultType:"cal-address"},"percent-complete":a,priority:a,prodid:i,"related-to":i,repeat:a,rdate:{defaultType:"date-time",allowedTypes:["date-time","date","period"],multiValue:",",detectType:function(e){return-1!==e.indexOf("/")?"period":-1===e.indexOf("T")?"date":"date-time"}},"recurrence-id":l,resources:s,"request-status":o,rrule:h,sequence:a,status:i,summary:i,transp:i,trigger:{defaultType:"duration",allowedTypes:["duration","date-time"]},tzoffsetfrom:d,tzoffsetto:d,tzurl:u,tzid:i,tzname:i}),b=t.helpers.extend(m,{text:r(e,n),uri:r(e,n),date:{decorate:function(e){return t.VCardTime.fromDateAndOrTimeString(e,"date")},undecorate:function(e){return e.toString()},fromICAL:function(e){return 8==e.length?v.date.fromICAL(e):"-"==e[0]&&6==e.length?e.substr(0,4)+"-"+e.substr(4):e},toICAL:function(e){return 10==e.length?v.date.toICAL(e):"-"==e[0]&&7==e.length?e.substr(0,4)+e.substr(5):e}},time:{decorate:function(e){return t.VCardTime.fromDateAndOrTimeString("T"+e,"time")},undecorate:function(e){return e.toString()},fromICAL:function(e){var t=b.time._splitZone(e,!0),n=t[0],r=t[1];return 6==r.length?r=r.substr(0,2)+":"+r.substr(2,2)+":"+r.substr(4,2):4==r.length&&"-"!=r[0]?r=r.substr(0,2)+":"+r.substr(2,2):5==r.length&&(r=r.substr(0,3)+":"+r.substr(3,2)),5!=n.length||"-"!=n[0]&&"+"!=n[0]||(n=n.substr(0,3)+":"+n.substr(3)),r+n},toICAL:function(e){var t=b.time._splitZone(e),n=t[0],r=t[1];return 8==r.length?r=r.substr(0,2)+r.substr(3,2)+r.substr(6,2):5==r.length&&"-"!=r[0]?r=r.substr(0,2)+r.substr(3,2):6==r.length&&(r=r.substr(0,3)+r.substr(4,2)),6!=n.length||"-"!=n[0]&&"+"!=n[0]||(n=n.substr(0,3)+n.substr(4)),r+n},_splitZone:function(e,t){var n,r,i=e.length-1,s=e.length-(t?5:6),o=e[s];return"Z"==e[i]?(n=e[i],r=e.substr(0,i)):e.length>6&&("-"==o||"+"==o)?(n=e.substr(s),r=e.substr(0,s)):(n="",r=e),[n,r]}},"date-time":{decorate:function(e){return t.VCardTime.fromDateAndOrTimeString(e,"date-time")},undecorate:function(e){return e.toString()},fromICAL:function(e){return b["date-and-or-time"].fromICAL(e)},toICAL:function(e){return b["date-and-or-time"].toICAL(e)}},"date-and-or-time":{decorate:function(e){return t.VCardTime.fromDateAndOrTimeString(e,"date-and-or-time")},undecorate:function(e){return e.toString()},fromICAL:function(e){var t=e.split("T");return(t[0]?b.date.fromICAL(t[0]):"")+(t[1]?"T"+b.time.fromICAL(t[1]):"")},toICAL:function(e){var t=e.split("T");return b.date.toICAL(t[0])+(t[1]?"T"+b.time.toICAL(t[1]):"")}},timestamp:v["date-time"],"language-tag":{matches:/^[a-zA-Z0-9-]+$/}}),D=t.helpers.extend(g,{adr:{defaultType:"text",structuredValue:";",multiValue:","},anniversary:f,bday:f,caladruri:u,caluri:u,clientpidmap:o,email:i,fburl:u,fn:i,gender:o,geo:u,impp:u,key:u,kind:i,lang:{defaultType:"language-tag"},logo:u,member:u,n:{defaultType:"text",structuredValue:";",multiValue:","},nickname:s,note:i,org:{defaultType:"text",structuredValue:";"},photo:u,related:u,rev:{defaultType:"timestamp"},role:i,sound:u,source:u,tel:{defaultType:"uri",allowedTypes:["uri","text"]},title:i,tz:{defaultType:"text",allowedTypes:["text","utc-offset","uri"]},xml:i}),A=t.helpers.extend(m,{binary:v.binary,date:b.date,"date-time":b["date-time"],"phone-number":{},uri:v.uri,text:v.text,time:v.time,vcard:v.text,"utc-offset":{toICAL:function(e){return e.substr(0,7)},fromICAL:function(e){return e.substr(0,7)},decorate:function(e){return t.UtcOffset.fromString(e)},undecorate:function(e){return e.toString()}}}),E=t.helpers.extend(g,{fn:i,n:{defaultType:"text",structuredValue:";",multiValue:","},nickname:s,photo:{defaultType:"binary",allowedTypes:["binary","uri"]},bday:{defaultType:"date-time",allowedTypes:["date-time","date"],detectType:function(e){return-1===e.indexOf("T")?"date":"date-time"}},adr:{defaultType:"text",structuredValue:";",multiValue:","},label:i,tel:{defaultType:"phone-number"},email:i,mailer:i,tz:{defaultType:"utc-offset",allowedTypes:["utc-offset","text"]},geo:{defaultType:"float",structuredValue:";"},title:i,role:i,logo:{defaultType:"binary",allowedTypes:["binary","uri"]},agent:{defaultType:"vcard",allowedTypes:["vcard","text","uri"]},org:o,note:s,prodid:i,rev:{defaultType:"date-time",allowedTypes:["date-time","date"],detectType:function(e){return-1===e.indexOf("T")?"date":"date-time"}},"sort-string":i,sound:{defaultType:"binary",allowedTypes:["binary","uri"]},class:i,key:{defaultType:"binary",allowedTypes:["binary","text"]}}),_={value:v,param:{cutype:{values:["INDIVIDUAL","GROUP","RESOURCE","ROOM","UNKNOWN"],allowXName:!0,allowIanaToken:!0},"delegated-from":{valueType:"cal-address",multiValue:",",multiValueSeparateDQuote:!0},"delegated-to":{valueType:"cal-address",multiValue:",",multiValueSeparateDQuote:!0},encoding:{values:["8BIT","BASE64"]},fbtype:{values:["FREE","BUSY","BUSY-UNAVAILABLE","BUSY-TENTATIVE"],allowXName:!0,allowIanaToken:!0},member:{valueType:"cal-address",multiValue:",",multiValueSeparateDQuote:!0},partstat:{values:["NEEDS-ACTION","ACCEPTED","DECLINED","TENTATIVE","DELEGATED","COMPLETED","IN-PROCESS"],allowXName:!0,allowIanaToken:!0},range:{values:["THISANDFUTURE"]},related:{values:["START","END"]},reltype:{values:["PARENT","CHILD","SIBLING"],allowXName:!0,allowIanaToken:!0},role:{values:["REQ-PARTICIPANT","CHAIR","OPT-PARTICIPANT","NON-PARTICIPANT"],allowXName:!0,allowIanaToken:!0},rsvp:{values:["TRUE","FALSE"]},"sent-by":{valueType:"cal-address"},tzid:{matches:/^\//},value:{values:["binary","boolean","cal-address","date","date-time","duration","float","integer","period","recur","text","time","uri","utc-offset"],allowXName:!0,allowIanaToken:!0}},property:y},S={value:b,param:{type:{valueType:"text",multiValue:","},value:{values:["text","uri","date","time","date-time","date-and-or-time","timestamp","boolean","integer","float","utc-offset","language-tag"],allowXName:!0,allowIanaToken:!0}},property:D},T={value:A,param:{type:{valueType:"text",multiValue:","},value:{values:["text","uri","date","date-time","phone-number","time","boolean","integer","float","utc-offset","vcard","binary"],allowXName:!0,allowIanaToken:!0}},property:E},w={strict:!0,defaultSet:_,defaultType:"unknown",components:{vcard:S,vcard3:T,vevent:_,vtodo:_,vjournal:_,valarm:_,vtimezone:_,daylight:_,standard:_},icalendar:_,vcard:S,vcard3:T,getDesignSet:function(e){return e&&e in w.components?w.components[e]:w.defaultSet}};return w}(),t.stringify=function(){"use strict";var e="\r\n",n="unknown",r=t.design,i=t.helpers;function s(t){"string"==typeof t[0]&&(t=[t]);for(var n=0,r=t.length,i="";n0&&("version"!==t[1][0][0]||"4.0"!==t[1][0][3])&&(u="vcard3"),n=n||r.getDesignSet(u);l1)throw new i("invalid ical body. component began but did not end");return t=null,1==n.length?n[0]:n}i.prototype=Error.prototype,s.property=function(e,t){var r={component:[[],[]],designSet:t||n.defaultSet};return s._handleContentLine(e,r),r.component[1][0]},s.component=function(e){return s(e)},s.ParserError=i,s._handleContentLine=function(e,t){var r,o,a,l,c,u,d=e.indexOf(":"),h=e.indexOf(";"),f={};if(-1!==h&&-1!==d&&h>d&&(h=-1),-1!==h){if(a=e.substring(0,h).toLowerCase(),-1==(c=s._parseParameters(e.substring(h),0,t.designSet))[2])throw new i("Invalid parameters in '"+e+"'");if(f=c[0],r=c[1].length+c[2]+h,-1===(o=e.substring(r).indexOf(":")))throw new i("Missing parameter value in '"+e+"'");l=e.substring(r+o+1)}else{if(-1===d)throw new i('invalid line (no token ";" or ":") "'+e+'"');if(a=e.substring(0,d).toLowerCase(),l=e.substring(d+1),"begin"===a){var p=[l.toLowerCase(),[],[]];return 1===t.stack.length?t.component.push(p):t.component[2].push(p),t.stack.push(t.component),t.component=p,void(t.designSet||(t.designSet=n.getDesignSet(t.component[0])))}if("end"===a)return void(t.component=t.stack.pop())}var g,m,v=!1,y=!1;a in t.designSet.property&&("multiValue"in(g=t.designSet.property[a])&&(v=g.multiValue),"structuredValue"in g&&(y=g.structuredValue),l&&"detectType"in g&&(u=g.detectType(l))),u||(u="value"in f?f.value.toLowerCase():g?g.defaultType:"unknown"),delete f.value,v&&y?m=[a,f,u,l=s._parseMultiValue(l,y,u,[],v,t.designSet,y)]:v?(m=[a,f,u],s._parseMultiValue(l,v,u,m,null,t.designSet,!1)):m=y?[a,f,u,l=s._parseMultiValue(l,y,u,[],null,t.designSet,y)]:[a,f,u,l=s._parseValue(l,u,t.designSet,!1)],"vcard"!==t.component[0]||0!==t.component[1].length||"version"===a&&"4.0"===l||(t.designSet=n.getDesignSet("vcard3")),t.component[1].push(m)},s._parseValue=function(e,t,n,r){return t in n.value&&"fromICAL"in n.value[t]?n.value[t].fromICAL(e,r):e},s._parseParameters=function(e,t,n){for(var o,a,l,c,u,d,h=t,f=0,p={},g=-1;!1!==f&&-1!==(f=r.unescapedIndexOf(e,"=",f+1));){if(0==(o=e.substr(h+1,f-h-1)).length)throw new i("Empty parameter name in '"+e+"'");if(d=!1,u=!1,c=(a=o.toLowerCase())in n.param&&n.param[a].valueType?n.param[a].valueType:"text",a in n.param&&(u=n.param[a].multiValue,n.param[a].multiValueSeparateDQuote&&(d=s._rfc6868Escape('"'+u+'"'))),'"'===e[f+1]){if(g=f+2,f=r.unescapedIndexOf(e,'"',g),u&&-1!=f)for(var m=!0;m;)e[f+1]==u&&'"'==e[f+2]?f=r.unescapedIndexOf(e,'"',f+3):m=!1;if(-1===f)throw new i('invalid line (no matching double quote) "'+e+'"');l=e.substr(g,f-g),-1===(h=r.unescapedIndexOf(e,";",f))&&(f=!1)}else{g=f+1;var v=r.unescapedIndexOf(e,";",g),y=r.unescapedIndexOf(e,":",g);-1!==y&&v>y?(v=y,f=!1):-1===v?(v=-1===y?e.length:y,f=!1):(h=v,f=v),l=e.substr(g,v-g)}if(l=s._rfc6868Escape(l),u){var b=d||u;l=s._parseMultiValue(l,b,c,[],null,n)}else l=s._parseValue(l,c,n);u&&a in p?Array.isArray(p[a])?p[a].push(l):p[a]=[p[a],l]:p[a]=l}return[p,l,g]},s._rfc6868Escape=function(e){return e.replace(/\^['n^]/g,(function(e){return o[e]}))};var o={"^'":'"',"^n":"\n","^^":"^"};return s._parseMultiValue=function(e,t,n,i,o,a,l){var c,u=0,d=0;if(0===t.length)return e;for(;-1!==(u=r.unescapedIndexOf(e,t,d));)c=e.substr(d,u-d),c=o?s._parseMultiValue(c,o,n,[],null,a,l):s._parseValue(c,n,a,l),i.push(c),d=u+t.length;return c=e.substr(d),c=o?s._parseMultiValue(c,o,n,[],null,a,l):s._parseValue(c,n,a,l),i.push(c),1==i.length?i[0]:i},s._eachLine=function(t,n){var r,i,s,o=t.length,a=t.search(e),l=a;do{s=(l=t.indexOf("\n",a)+1)>1&&"\r"===t[l-2]?2:1,0===l&&(l=o,s=0)," "===(i=t[a])||"\t"===i?r+=t.substr(a+1,l-a-(s+1)):(r&&n(null,r),r=t.substr(a,l-a-s)),a=l}while(l!==o);(r=r.trim()).length&&n(null,r)},s}(),t.Component=function(){"use strict";function e(e,t){"string"==typeof e&&(e=[e,[],[]]),this.jCal=e,this.parent=t||null}return e.prototype={_hydratedPropertyCount:0,_hydratedComponentCount:0,get name(){return this.jCal[0]},get _designSet(){return this.parent&&this.parent._designSet||t.design.getDesignSet(this.name)},_hydrateComponent:function(t){if(this._components||(this._components=[],this._hydratedComponentCount=0),this._components[t])return this._components[t];var n=new e(this.jCal[2][t],this);return this._hydratedComponentCount++,this._components[t]=n},_hydrateProperty:function(e){if(this._properties||(this._properties=[],this._hydratedPropertyCount=0),this._properties[e])return this._properties[e];var n=new t.Property(this.jCal[1][e],this);return this._hydratedPropertyCount++,this._properties[e]=n},getFirstSubcomponent:function(e){if(e)for(var t=0,n=this.jCal[2],r=n.length;t=0;s--)n&&i[s][0]!==n||this._removeObjectByIndex(e,r,s)},addSubcomponent:function(e){this._components||(this._components=[],this._hydratedComponentCount=0),e.parent&&e.parent.removeSubcomponent(e);var t=this.jCal[2].push(e.jCal);return this._components[t-1]=e,this._hydratedComponentCount++,e.parent=this,e},removeSubcomponent:function(e){var t=this._removeObject(2,"_components",e);return t&&this._hydratedComponentCount--,t},removeAllSubcomponents:function(e){var t=this._removeAllObjects(2,"_components",e);return this._hydratedComponentCount=0,t},addProperty:function(e){if(!(e instanceof t.Property))throw new TypeError("must instance of ICAL.Property");this._properties||(this._properties=[],this._hydratedPropertyCount=0),e.parent&&e.parent.removeProperty(e);var n=this.jCal[1].push(e.jCal);return this._properties[n-1]=e,this._hydratedPropertyCount++,e.parent=this,e},addPropertyWithValue:function(e,n){var r=new t.Property(e);return r.setValue(n),this.addProperty(r),r},updatePropertyWithValue:function(e,t){var n=this.getFirstProperty(e);return n?n.setValue(t):n=this.addPropertyWithValue(e,t),n},removeProperty:function(e){var t=this._removeObject(1,"_properties",e);return t&&this._hydratedPropertyCount--,t},removeAllProperties:function(e){var t=this._removeAllObjects(1,"_properties",e);return this._hydratedPropertyCount=0,t},toJSON:function(){return this.jCal},toString:function(){return t.stringify.component(this.jCal,this._designSet)}},e.fromString=function(n){return new e(t.parse.component(n))},e}(),t.Property=function(){"use strict";var e=t.design;function n(t,n){this._parent=n||null,"string"==typeof t?(this.jCal=[t,{},e.defaultType],this.jCal[2]=this.getDefaultType()):this.jCal=t,this._updateType()}return n.prototype={get type(){return this.jCal[2]},get name(){return this.jCal[0]},get parent(){return this._parent},set parent(t){var n=!this._parent||t&&t._designSet!=this._parent._designSet;return this._parent=t,this.type==e.defaultType&&n&&(this.jCal[2]=this.getDefaultType(),this._updateType()),t},get _designSet(){return this.parent?this.parent._designSet:e.defaultSet},_updateType:function(){var e=this._designSet;if(this.type in e.value){e.value[this.type];"decorate"in e.value[this.type]?this.isDecorated=!0:this.isDecorated=!1,this.name in e.property&&(this.isMultiValue="multiValue"in e.property[this.name],this.isStructuredValue="structuredValue"in e.property[this.name])}},_hydrateValue:function(e){return this._values&&this._values[e]?this._values[e]:this.jCal.length<=3+e?null:this.isDecorated?(this._values||(this._values=[]),this._values[e]=this._decorate(this.jCal[3+e])):this.jCal[3+e]},_decorate:function(e){return this._designSet.value[this.type].decorate(e,this)},_undecorate:function(e){return this._designSet.value[this.type].undecorate(e,this)},_setDecoratedValue:function(e,t){this._values||(this._values=[]),"object"==typeof e&&"icaltype"in e?(this.jCal[3+t]=this._undecorate(e),this._values[t]=e):(this.jCal[3+t]=e,this._values[t]=this._decorate(e))},getParameter:function(e){return e in this.jCal[1]?this.jCal[1][e]:void 0},getFirstParameter:function(e){var t=this.getParameter(e);return Array.isArray(t)?t[0]:t},setParameter:function(e,t){var n=e.toLowerCase();"string"==typeof t&&n in this._designSet.param&&"multiValue"in this._designSet.param[n]&&(t=[t]),this.jCal[1][e]=t},removeParameter:function(e){delete this.jCal[1][e]},getDefaultType:function(){var t=this.jCal[0],n=this._designSet;if(t in n.property){var r=n.property[t];if("defaultType"in r)return r.defaultType}return e.defaultType},resetType:function(e){this.removeAllValues(),this.jCal[2]=e,this._updateType()},getFirstValue:function(){return this._hydrateValue(0)},getValues:function(){var e=this.jCal.length-3;if(e<1)return[];for(var t=0,n=[];t0&&"object"==typeof e[0]&&"icaltype"in e[0]&&this.resetType(e[0].icaltype),this.isDecorated)for(;nn)-(n>t)},_normalize:function(){for(var e=this.toSeconds(),t=this.factor;e<-43200;)e+=97200;for(;e>50400;)e-=97200;this.fromSeconds(e),0==e&&(this.factor=t)},toICALString:function(){return t.design.icalendar.value["utc-offset"].toICAL(this.toString())},toString:function(){return(1==this.factor?"+":"-")+t.helpers.pad2(this.hours)+":"+t.helpers.pad2(this.minutes)}},e.fromString=function(e){var n={};return n.factor="+"===e[0]?1:-1,n.hours=t.helpers.strictParseInt(e.substr(1,2)),n.minutes=t.helpers.strictParseInt(e.substr(4,2)),new t.UtcOffset(n)},e.fromSeconds=function(t){var n=new e;return n.fromSeconds(t),n},e}(),t.Binary=function(){function e(e){this.value=e}return e.prototype={icaltype:"binary",decodeValue:function(){return this._b64_decode(this.value)},setEncodedValue:function(e){this.value=this._b64_encode(e)},_b64_encode:function(e){var t,n,r,i,s,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",a=0,l=0,c="",u=[];if(!e)return e;do{t=(s=e.charCodeAt(a++)<<16|e.charCodeAt(a++)<<8|e.charCodeAt(a++))>>18&63,n=s>>12&63,r=s>>6&63,i=63&s,u[l++]=o.charAt(t)+o.charAt(n)+o.charAt(r)+o.charAt(i)}while(a>16&255,n=o>>8&255,r=255&o,u[c++]=64==i?String.fromCharCode(t):64==s?String.fromCharCode(t,n):String.fromCharCode(t,n,r)}while(ln)-(t=0?i=r:s=-1,-1==s&&-1!=i)break;if((r+=s)<0)return 0;if(r>=this.changes.length)break}var a=this.changes[i];if(a.utcOffset-a.prevUtcOffset<0&&i>0){var l=t.helpers.clone(a,!0);if(t.Timezone.adjust_change(l,0,0,0,l.prevUtcOffset),t.Timezone._compare_change_fn(n,l)<0){var c=this.changes[i-1],u=!1;a.is_daylight!=u&&c.is_daylight==u&&(a=c)}}return a.utcOffset},_findNearbyChange:function(e){var n=t.helpers.binsearchInsert(this.changes,e,t.Timezone._compare_change_fn);return n>=this.changes.length?this.changes.length-1:n},_ensureCoverage:function(e){if(-1==t.Timezone._minimumExpansionYear){var n=t.Time.now();t.Timezone._minimumExpansionYear=n.year}var r=e;if(rt.Timezone.MAX_YEAR&&(r=t.Timezone.MAX_YEAR),!this.changes.length||this.expandedUntilYearn)&&h);)i.year=h.year,i.month=h.month,i.day=h.day,i.hour=h.hour,i.minute=h.minute,i.second=h.second,i.isDate=h.isDate,t.Timezone.adjust_change(i,0,0,0,-i.prevUtcOffset),r.push(i)}}else(i=a()).year=s.year,i.month=s.month,i.day=s.day,i.hour=s.hour,i.minute=s.minute,i.second=s.second,t.Timezone.adjust_change(i,0,0,0,-i.prevUtcOffset),r.push(i);return r},toString:function(){return this.tznames?this.tznames:this.tzid}},t.Timezone._compare_change_fn=function(e,t){return e.yeart.year?1:e.montht.month?1:e.dayt.day?1:e.hourt.hour?1:e.minutet.minute?1:e.secondt.second?1:0},t.Timezone.convert_time=function(e,n,r){if(e.isDate||n.tzid==r.tzid||n==t.Timezone.localTimezone||r==t.Timezone.localTimezone)return e.zone=r,e;var i=n.utcOffset(e);return e.adjust(0,0,0,-i),i=r.utcOffset(e),e.adjust(0,0,0,i),null},t.Timezone.fromData=function(e){return(new t.Timezone).fromData(e)},t.Timezone.utcTimezone=t.Timezone.fromData({tzid:"UTC"}),t.Timezone.localTimezone=t.Timezone.fromData({tzid:"floating"}),t.Timezone.adjust_change=function(e,n,r,i,s){return t.Time.prototype.adjust.call(e,n,r,i,s,e)},t.Timezone._minimumExpansionYear=-1,t.Timezone.MAX_YEAR=2035,t.Timezone.EXTRA_COVERAGE=5,t.TimezoneService=((i={get count(){return Object.keys(r).length},reset:function(){r=Object.create(null);var e=t.Timezone.utcTimezone;r.Z=e,r.UTC=e,r.GMT=e},has:function(e){return!!r[e]},get:function(e){return r[e]},register:function(e,n){if(e instanceof t.Component&&"vtimezone"===e.name&&(e=(n=new t.Timezone(e)).tzid),!(n instanceof t.Timezone))throw new TypeError("timezone must be ICAL.Timezone or ICAL.Component");r[e]=n},remove:function(e){return delete r[e]}}).reset(),i),t.Time=function(e,t){this.wrappedJSObject=this;var n=this._time=Object.create(null);n.year=0,n.month=1,n.day=1,n.hour=0,n.minute=0,n.second=0,n.isDate=!1,this.fromData(e,t)},t.Time._dowCache={},t.Time._wnCache={},t.Time.prototype={icalclass:"icaltime",_cachedUnixTime:null,get icaltype(){return this.isDate?"date":"date-time"},zone:null,_pendingNormalization:!1,clone:function(){return new t.Time(this._time,this.zone)},reset:function(){this.fromData(t.Time.epochTime),this.zone=t.Timezone.utcTimezone},resetTo:function(e,t,n,r,i,s,o){this.fromData({year:e,month:t,day:n,hour:r,minute:i,second:s,zone:o})},fromJSDate:function(e,n){return e?n?(this.zone=t.Timezone.utcTimezone,this.year=e.getUTCFullYear(),this.month=e.getUTCMonth()+1,this.day=e.getUTCDate(),this.hour=e.getUTCHours(),this.minute=e.getUTCMinutes(),this.second=e.getUTCSeconds()):(this.zone=t.Timezone.localTimezone,this.year=e.getFullYear(),this.month=e.getMonth()+1,this.day=e.getDate(),this.hour=e.getHours(),this.minute=e.getMinutes(),this.second=e.getSeconds()):this.reset(),this._cachedUnixTime=null,this},fromData:function(e,n){if(e)for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){if("icaltype"===r)continue;this[r]=e[r]}if(n&&(this.zone=n),e&&!("isDate"in e)?this.isDate=!("hour"in e):e&&"isDate"in e&&(this.isDate=e.isDate),e&&"timezone"in e){var i=t.TimezoneService.get(e.timezone);this.zone=i||t.Timezone.localTimezone}return e&&"zone"in e&&(this.zone=e.zone),this.zone||(this.zone=t.Timezone.localTimezone),this._cachedUnixTime=null,this},dayOfWeek:function(e){var n=e||t.Time.SUNDAY,r=(this.year<<12)+(this.month<<8)+(this.day<<3)+n;if(r in t.Time._dowCache)return t.Time._dowCache[r];var i=this.day,s=this.month+(this.month<3?12:0),o=this.year-(this.month<3?1:0),a=i+o+t.helpers.trunc(26*(s+1)/10)+t.helpers.trunc(o/4);return a=((a+=6*t.helpers.trunc(o/100)+t.helpers.trunc(o/400))+7-n)%7+1,t.Time._dowCache[r]=a,a},dayOfYear:function(){var e=t.Time.isLeapYear(this.year)?1:0;return t.Time.daysInYearPassedMonth[e][this.month-1]+this.day},startOfWeek:function(e){var n=e||t.Time.SUNDAY,r=this.clone();return r.day-=(this.dayOfWeek()+7-n)%7,r.isDate=!0,r.hour=0,r.minute=0,r.second=0,r},endOfWeek:function(e){var n=e||t.Time.SUNDAY,r=this.clone();return r.day+=(7-this.dayOfWeek()+n-t.Time.SUNDAY)%7,r.isDate=!0,r.hour=0,r.minute=0,r.second=0,r},startOfMonth:function(){var e=this.clone();return e.day=1,e.isDate=!0,e.hour=0,e.minute=0,e.second=0,e},endOfMonth:function(){var e=this.clone();return e.day=t.Time.daysInMonth(e.month,e.year),e.isDate=!0,e.hour=0,e.minute=0,e.second=0,e},startOfYear:function(){var e=this.clone();return e.day=1,e.month=1,e.isDate=!0,e.hour=0,e.minute=0,e.second=0,e},endOfYear:function(){var e=this.clone();return e.day=31,e.month=12,e.isDate=!0,e.hour=0,e.minute=0,e.second=0,e},startDoyWeek:function(e){var n=e||t.Time.SUNDAY,r=this.dayOfWeek()-n;return r<0&&(r+=7),this.dayOfYear()-r},getDominicalLetter:function(){return t.Time.getDominicalLetter(this.year)},nthWeekDay:function(e,n){var r,i=t.Time.daysInMonth(this.month,this.year),s=n,o=0,a=this.clone();if(s>=0){a.day=1,0!=s&&s--,o=a.day;var l=e-a.dayOfWeek();l<0&&(l+=7),o+=l,o-=e,r=e}else a.day=i,s++,(r=a.dayOfWeek()-e)<0&&(r+=7),r=i-r;return o+(r+=7*s)},isNthWeekDay:function(e,t){var n=this.dayOfWeek();return 0===t&&n===e||this.nthWeekDay(e,t)===this.day},weekNumber:function(e){var n,r=(this.year<<12)+(this.month<<8)+(this.day<<3)+e;if(r in t.Time._wnCache)return t.Time._wnCache[r];var i=this.clone();i.isDate=!0;var s=this.year;12==i.month&&i.day>25?(n=t.Time.weekOneStarts(s+1,e),i.compare(n)<0?n=t.Time.weekOneStarts(s,e):s++):(n=t.Time.weekOneStarts(s,e),i.compare(n)<0&&(n=t.Time.weekOneStarts(--s,e)));var o=i.subtractDate(n).toSeconds()/86400,a=t.helpers.trunc(o/7)+1;return t.Time._wnCache[r]=a,a},addDuration:function(e){var t=e.isNegative?-1:1,n=this.second,r=this.minute,i=this.hour,s=this.day;n+=t*e.seconds,r+=t*e.minutes,i+=t*e.hours,s+=t*e.days,s+=7*t*e.weeks,this.second=n,this.minute=r,this.hour=i,this.day=s,this._cachedUnixTime=null},subtractDate:function(e){var n=this.toUnixTime()+this.utcOffset(),r=e.toUnixTime()+e.utcOffset();return t.Duration.fromSeconds(n-r)},subtractDateTz:function(e){var n=this.toUnixTime(),r=e.toUnixTime();return t.Duration.fromSeconds(n-r)},compare:function(e){var t=this.toUnixTime(),n=e.toUnixTime();return t>n?1:n>t?-1:0},compareDateOnlyTz:function(e,n){function r(e){return t.Time._cmp_attr(i,s,e)}var i=this.convertToZone(n),s=e.convertToZone(n),o=0;return 0!=(o=r("year"))||0!=(o=r("month"))||(o=r("day")),o},convertToZone:function(e){var n=this.clone(),r=this.zone.tzid==e.tzid;return this.isDate||r||t.Timezone.convert_time(n,this.zone,e),n.zone=e,n},utcOffset:function(){return this.zone==t.Timezone.localTimezone||this.zone==t.Timezone.utcTimezone?0:this.zone.utcOffset(this)},toICALString:function(){var e=this.toString();return e.length>10?t.design.icalendar.value["date-time"].toICAL(e):t.design.icalendar.value.date.toICAL(e)},toString:function(){var e=this.year+"-"+t.helpers.pad2(this.month)+"-"+t.helpers.pad2(this.day);return this.isDate||(e+="T"+t.helpers.pad2(this.hour)+":"+t.helpers.pad2(this.minute)+":"+t.helpers.pad2(this.second),this.zone===t.Timezone.utcTimezone&&(e+="Z")),e},toJSDate:function(){return this.zone==t.Timezone.localTimezone?this.isDate?new Date(this.year,this.month-1,this.day):new Date(this.year,this.month-1,this.day,this.hour,this.minute,this.second,0):new Date(1e3*this.toUnixTime())},_normalize:function(){return this._time.isDate,this._time.isDate&&(this._time.hour=0,this._time.minute=0,this._time.second=0),this.adjust(0,0,0,0),this},adjust:function(e,n,r,i,s){var o,a,l,c,u,d,h,f=0,p=0,g=s||this._time;if(g.isDate||(l=g.second+i,g.second=l%60,o=t.helpers.trunc(l/60),g.second<0&&(g.second+=60,o--),c=g.minute+r+o,g.minute=c%60,a=t.helpers.trunc(c/60),g.minute<0&&(g.minute+=60,a--),u=g.hour+n+a,g.hour=u%24,f=t.helpers.trunc(u/24),g.hour<0&&(g.hour+=24,f--)),g.month>12?p=t.helpers.trunc((g.month-1)/12):g.month<1&&(p=t.helpers.trunc(g.month/12)-1),g.year+=p,g.month-=12*p,(d=g.day+e+f)>0)for(;!(d<=(h=t.Time.daysInMonth(g.month,g.year)));)g.month++,g.month>12&&(g.year++,g.month=1),d-=h;else for(;d<=0;)1==g.month?(g.year--,g.month=12):g.month--,d+=t.Time.daysInMonth(g.month,g.year);return g.day=d,this._cachedUnixTime=null,this},fromUnixTime:function(e){this.zone=t.Timezone.utcTimezone;var n=t.Time.epochTime.clone();n.adjust(0,0,0,e),this.year=n.year,this.month=n.month,this.day=n.day,this.hour=n.hour,this.minute=n.minute,this.second=Math.floor(n.second),this._cachedUnixTime=null},toUnixTime:function(){if(null!==this._cachedUnixTime)return this._cachedUnixTime;var e=this.utcOffset(),t=Date.UTC(this.year,this.month-1,this.day,this.hour,this.minute,this.second-e);return this._cachedUnixTime=t/1e3,this._cachedUnixTime},toJSON:function(){for(var e,t=["year","month","day","hour","minute","second","isDate"],n=Object.create(null),r=0,i=t.length;r12||(r=[0,31,28,31,30,31,30,31,31,30,31,30,31][e],2==e&&(r+=t.Time.isLeapYear(n))),r},t.Time.isLeapYear=function(e){return e<=1752?e%4==0:e%4==0&&e%100!=0||e%400==0},t.Time.fromDayOfYear=function(e,n){var r=n,i=e,s=new t.Time;s.auto_normalize=!1;var o=t.Time.isLeapYear(r)?1:0;if(i<1)return r--,o=t.Time.isLeapYear(r)?1:0,i+=t.Time.daysInYearPassedMonth[o][12],t.Time.fromDayOfYear(i,r);if(i>t.Time.daysInYearPassedMonth[o][12])return o=t.Time.isLeapYear(r)?1:0,i-=t.Time.daysInYearPassedMonth[o][12],r++,t.Time.fromDayOfYear(i,r);s.year=r,s.isDate=!0;for(var a=11;a>=0;a--)if(i>t.Time.daysInYearPassedMonth[o][a]){s.month=a+1,s.day=i-t.Time.daysInYearPassedMonth[o][a];break}return s.auto_normalize=!0,s},t.Time.fromStringv2=function(e){return new t.Time({year:parseInt(e.substr(0,4),10),month:parseInt(e.substr(5,2),10),day:parseInt(e.substr(8,2),10),isDate:!0})},t.Time.fromDateString=function(e){return new t.Time({year:t.helpers.strictParseInt(e.substr(0,4)),month:t.helpers.strictParseInt(e.substr(5,2)),day:t.helpers.strictParseInt(e.substr(8,2)),isDate:!0})},t.Time.fromDateTimeString=function(e,n){if(e.length<19)throw new Error('invalid date-time value: "'+e+'"');var r;return e[19]&&"Z"===e[19]?r="Z":n&&(r=n.getParameter("tzid")),new t.Time({year:t.helpers.strictParseInt(e.substr(0,4)),month:t.helpers.strictParseInt(e.substr(5,2)),day:t.helpers.strictParseInt(e.substr(8,2)),hour:t.helpers.strictParseInt(e.substr(11,2)),minute:t.helpers.strictParseInt(e.substr(14,2)),second:t.helpers.strictParseInt(e.substr(17,2)),timezone:r})},t.Time.fromString=function(e,n){return e.length>10?t.Time.fromDateTimeString(e,n):t.Time.fromDateString(e)},t.Time.fromJSDate=function(e,n){return(new t.Time).fromJSDate(e,n)},t.Time.fromData=function(e,n){return(new t.Time).fromData(e,n)},t.Time.now=function(){return t.Time.fromJSDate(new Date,!1)},t.Time.weekOneStarts=function(e,n){var r=t.Time.fromData({year:e,month:1,day:1,isDate:!0}),i=r.dayOfWeek(),s=n||t.Time.DEFAULT_WEEK_START;return i>t.Time.THURSDAY&&(r.day+=7),s>t.Time.THURSDAY&&(r.day-=7),r.day-=i-s,r},t.Time.getDominicalLetter=function(e){var n="GFEDCBA",r=(e+(e/4|0)+(e/400|0)-(e/100|0)-1)%7;return t.Time.isLeapYear(e)?n[(r+6)%7]+n[r]:n[r]},t.Time.epochTime=t.Time.fromData({year:1970,month:1,day:1,hour:0,minute:0,second:0,isDate:!1,timezone:"Z"}),t.Time._cmp_attr=function(e,t,n){return e[n]>t[n]?1:e[n]4?r(c,f?1:3,2):null,second:4==d?r(c,2,2):6==d?r(c,4,2):8==d?r(c,6,2):null};return l="Z"==l?t.Timezone.utcTimezone:l&&":"==l[3]?t.UtcOffset.fromString(l):null,new t.VCardTime(p,l,n)},function(){var e={SU:t.Time.SUNDAY,MO:t.Time.MONDAY,TU:t.Time.TUESDAY,WE:t.Time.WEDNESDAY,TH:t.Time.THURSDAY,FR:t.Time.FRIDAY,SA:t.Time.SATURDAY},n={};for(var r in e)e.hasOwnProperty(r)&&(n[e[r]]=r);function i(e,n,r,i){var s=i;if("+"===i[0]&&(s=i.substr(1)),s=t.helpers.strictParseInt(s),void 0!==n&&i '+n);if(void 0!==r&&i>r)throw new Error(e+': invalid value "'+i+'" must be < '+n);return s}t.Recur=function(e){this.wrappedJSObject=this,this.parts={},e&&"object"==typeof e&&this.fromData(e)},t.Recur.prototype={parts:null,interval:1,wkst:t.Time.MONDAY,until:null,count:null,freq:null,icalclass:"icalrecur",icaltype:"recur",iterator:function(e){return new t.RecurIterator({rule:this,dtstart:e})},clone:function(){return new t.Recur(this.toJSON())},isFinite:function(){return!(!this.count&&!this.until)},isByCount:function(){return!(!this.count||this.until)},addComponent:function(e,t){var n=e.toUpperCase();n in this.parts?this.parts[n].push(t):this.parts[n]=[t]},setComponent:function(e,t){this.parts[e.toUpperCase()]=t.slice()},getComponent:function(e){var t=e.toUpperCase();return t in this.parts?this.parts[t].slice():[]},getNextOccurrence:function(e,t){var n,r=this.iterator(e);do{n=r.next()}while(n&&n.compare(t)<=0);return n&&t.zone&&(n.zone=t.zone),n},fromData:function(e){for(var n in e){var r=n.toUpperCase();r in c?Array.isArray(e[n])?this.parts[r]=e[n]:this.parts[r]=[e[n]]:this[n]=e[n]}this.interval&&"number"!=typeof this.interval&&l.INTERVAL(this.interval,this),this.wkst&&"number"!=typeof this.wkst&&(this.wkst=t.Recur.icalDayToNumericDay(this.wkst)),!this.until||this.until instanceof t.Time||(this.until=t.Time.fromString(this.until))},toJSON:function(){var e=Object.create(null);for(var n in e.freq=this.freq,this.count&&(e.count=this.count),this.interval>1&&(e.interval=this.interval),this.parts)if(this.parts.hasOwnProperty(n)){var r=this.parts[n];Array.isArray(r)&&1==r.length?e[n.toLowerCase()]=r[0]:e[n.toLowerCase()]=t.helpers.clone(this.parts[n])}return this.until&&(e.until=this.until.toString()),"wkst"in this&&this.wkst!==t.Time.DEFAULT_WEEK_START&&(e.wkst=t.Recur.numericDayToIcalDay(this.wkst)),e},toString:function(){var e="FREQ="+this.freq;for(var n in this.count&&(e+=";COUNT="+this.count),this.interval>1&&(e+=";INTERVAL="+this.interval),this.parts)this.parts.hasOwnProperty(n)&&(e+=";"+n+"="+this.parts[n]);return this.until&&(e+=";UNTIL="+this.until.toICALString()),"wkst"in this&&this.wkst!==t.Time.DEFAULT_WEEK_START&&(e+=";WKST="+t.Recur.numericDayToIcalDay(this.wkst)),e}},t.Recur.icalDayToNumericDay=function(n,r){var i=r||t.Time.SUNDAY;return(e[n]-i+7)%7+1},t.Recur.numericDayToIcalDay=function(e,r){var i=e+(r||t.Time.SUNDAY)-t.Time.SUNDAY;return i>7&&(i-=7),n[i]};var s=/^(SU|MO|TU|WE|TH|FR|SA)$/,o=/^([+-])?(5[0-3]|[1-4][0-9]|[1-9])?(SU|MO|TU|WE|TH|FR|SA)$/,a=["SECONDLY","MINUTELY","HOURLY","DAILY","WEEKLY","MONTHLY","YEARLY"],l={FREQ:function(e,t,n){if(-1===a.indexOf(e))throw new Error('invalid frequency "'+e+'" expected: "'+a.join(", ")+'"');t.freq=e},COUNT:function(e,n,r){n.count=t.helpers.strictParseInt(e)},INTERVAL:function(e,n,r){n.interval=t.helpers.strictParseInt(e),n.interval<1&&(n.interval=1)},UNTIL:function(e,n,r){e.length>10?n.until=t.design.icalendar.value["date-time"].fromICAL(e):n.until=t.design.icalendar.value.date.fromICAL(e),r||(n.until=t.Time.fromString(n.until))},WKST:function(e,n,r){if(!s.test(e))throw new Error('invalid WKST value "'+e+'"');n.wkst=t.Recur.icalDayToNumericDay(e)}},c={BYSECOND:i.bind(this,"BYSECOND",0,60),BYMINUTE:i.bind(this,"BYMINUTE",0,59),BYHOUR:i.bind(this,"BYHOUR",0,23),BYDAY:function(e){if(o.test(e))return e;throw new Error('invalid BYDAY value "'+e+'"')},BYMONTHDAY:i.bind(this,"BYMONTHDAY",-31,31),BYYEARDAY:i.bind(this,"BYYEARDAY",-366,366),BYWEEKNO:i.bind(this,"BYWEEKNO",-53,53),BYMONTH:i.bind(this,"BYMONTH",1,12),BYSETPOS:i.bind(this,"BYSETPOS",-366,366)};t.Recur.fromString=function(e){var n=t.Recur._stringToData(e,!1);return new t.Recur(n)},t.Recur.fromData=function(e){return new t.Recur(e)},t.Recur._stringToData=function(e,t){for(var n=Object.create(null),r=e.split(";"),i=r.length,s=0;s=0||r<0)&&(this.last.day+=r)}else{var i=t.Recur.numericDayToIcalDay(this.dtstart.dayOfWeek());e.BYDAY=[i]}if("YEARLY"==this.rule.freq){for(;this.expand_year_days(this.last.year),!(this.days.length>0);)this.increment_year(this.rule.interval);this._nextByYearDay()}if("MONTHLY"==this.rule.freq&&this.has_by_data("BYDAY")){var s=null,o=this.last.clone(),a=t.Time.daysInMonth(this.last.month,this.last.year);for(var l in this.by_data.BYDAY)if(this.by_data.BYDAY.hasOwnProperty(l)){this.last=o.clone();n=(c=this.ruleDayOfWeek(this.by_data.BYDAY[l]))[0];var c,u=c[1],d=this.last.nthWeekDay(u,n);if(n>=6||n<=-6)throw new Error("Malformed values in BYDAY part");if(d>a||d<=0){if(s&&s.month==o.month)continue;for(;d>a||d<=0;)this.increment_month(),a=t.Time.daysInMonth(this.last.month,this.last.year),d=this.last.nthWeekDay(u,n)}this.last.day=d,(!s||this.last.compare(s)<0)&&(s=this.last.clone())}if(this.last=s.clone(),this.has_by_data("BYMONTHDAY")&&this._byDayAndMonthDay(!0),this.last.day>a||0==this.last.day)throw new Error("Malformed values in BYDAY part")}else if(this.has_by_data("BYMONTHDAY")&&this.last.day<0){a=t.Time.daysInMonth(this.last.month,this.last.year);this.last.day=a+this.last.day+1}},next:function(){var e,t=this.last?this.last.clone():null;if(this.rule.count&&this.occurrence_number>=this.rule.count||this.rule.until&&this.last.compare(this.rule.until)>0)return this.completed=!0,null;if(0==this.occurrence_number&&this.last.compare(this.dtstart)>=0)return this.occurrence_number++,this.last;do{switch(e=1,this.rule.freq){case"SECONDLY":this.next_second();break;case"MINUTELY":this.next_minute();break;case"HOURLY":this.next_hour();break;case"DAILY":this.next_day();break;case"WEEKLY":this.next_week();break;case"MONTHLY":e=this.next_month();break;case"YEARLY":this.next_year();break;default:return null}}while(!this.check_contracting_rules()||this.last.compare(this.dtstart)<0||!e);if(0==this.last.compare(t))throw new Error("Same occurrence found twice, protecting you from death by recursion");return this.rule.until&&this.last.compare(this.rule.until)>0?(this.completed=!0,null):(this.occurrence_number++,this.last)},next_second:function(){return this.next_generic("BYSECOND","SECONDLY","second","minute")},increment_second:function(e){return this.increment_generic(e,"second",60,"minute")},next_minute:function(){return this.next_generic("BYMINUTE","MINUTELY","minute","hour","next_second")},increment_minute:function(e){return this.increment_generic(e,"minute",60,"hour")},next_hour:function(){return this.next_generic("BYHOUR","HOURLY","hour","monthday","next_minute")},increment_hour:function(e){this.increment_generic(e,"hour",24,"monthday")},next_day:function(){this.by_data;var e="DAILY"==this.rule.freq;return 0==this.next_hour()||(e?this.increment_monthday(this.rule.interval):this.increment_monthday(1)),0},next_week:function(){var e=0;if(0==this.next_weekday_by_week())return e;if(this.has_by_data("BYWEEKNO")){++this.by_indices.BYWEEKNO;this.by_indices.BYWEEKNO==this.by_data.BYWEEKNO.length&&(this.by_indices.BYWEEKNO=0,e=1),this.last.month=1,this.last.day=1;var t=this.by_data.BYWEEKNO[this.by_indices.BYWEEKNO];this.last.day+=7*t,e&&this.increment_year(1)}else this.increment_monthday(7*this.rule.interval);return e},normalizeByMonthDayRules:function(e,n,r){for(var i,s=t.Time.daysInMonth(n,e),o=[],a=0,l=r.length;as)){if(i<0)i=s+(i+1);else if(0===i)continue;-1===o.indexOf(i)&&o.push(i)}return o.sort((function(e,t){return e-t}))},_byDayAndMonthDay:function(e){var n,r,i,s,o=this.by_data.BYDAY,a=0,l=o.length,c=0,u=this,d=this.last.day;function h(){for(s=t.Time.daysInMonth(u.last.month,u.last.year),n=u.normalizeByMonthDayRules(u.last.year,u.last.month,u.by_data.BYMONTHDAY),i=n.length;n[a]<=d&&(!e||n[a]!=d)&&as)f();else{var g=n[a++];if(g>=r){d=g;for(var m=0;mn&&(this.last.day=1,this.increment_month(),this.is_day_in_byday(this.last)?this.has_by_data("BYSETPOS")&&!this.check_set_position(1)||(e=1):e=0)}else if(this.has_by_data("BYMONTHDAY")){this.by_indices.BYMONTHDAY++,this.by_indices.BYMONTHDAY>=this.by_data.BYMONTHDAY.length&&(this.by_indices.BYMONTHDAY=0,this.increment_month());n=t.Time.daysInMonth(this.last.month,this.last.year);(o=this.by_data.BYMONTHDAY[this.by_indices.BYMONTHDAY])<0&&(o=n+o+1),o>n?(this.last.day=1,e=this.is_day_in_byday(this.last)):this.last.day=o}else{this.increment_month();n=t.Time.daysInMonth(this.last.month,this.last.year);this.by_data.BYMONTHDAY[0]>n?e=0:this.last.day=this.by_data.BYMONTHDAY[0]}return e},next_weekday_by_week:function(){var e=0;if(0==this.next_hour())return e;if(!this.has_by_data("BYDAY"))return 1;for(;;){var n=new t.Time;this.by_indices.BYDAY++,this.by_indices.BYDAY==Object.keys(this.by_data.BYDAY).length&&(this.by_indices.BYDAY=0,e=1);var r=this.by_data.BYDAY[this.by_indices.BYDAY],i=this.ruleDayOfWeek(r)[1];(i-=this.rule.wkst)<0&&(i+=7),n.year=this.last.year,n.month=this.last.month,n.day=this.last.day;var s=n.startDoyWeek(this.rule.wkst);if(!(i+s<1)||e){var o=t.Time.fromDayOfYear(s+i,this.last.year);return this.last.year=o.year,this.last.month=o.month,this.last.day=o.day,e}}},next_year:function(){if(0==this.next_hour())return 0;if(++this.days_index==this.days.length){this.days_index=0;do{this.increment_year(this.rule.interval),this.expand_year_days(this.last.year)}while(0==this.days.length)}return this._nextByYearDay(),1},_nextByYearDay:function(){var e=this.days[this.days_index],n=this.last.year;e<1&&(e+=1,n+=1);var r=t.Time.fromDayOfYear(e,n);this.last.day=r.day,this.last.month=r.month},ruleDayOfWeek:function(e,n){var r=e.match(/([+-]?[0-9])?(MO|TU|WE|TH|FR|SA|SU)/);return r?[parseInt(r[1]||0,10),e=t.Recur.icalDayToNumericDay(r[2],n)]:[0,0]},next_generic:function(e,t,n,r,i){var s=e in this.by_data,o=this.rule.freq==t,a=0;if(i&&0==this[i]())return a;if(s){this.by_indices[e]++;this.by_indices[e];var l=this.by_data[e];this.by_indices[e]==l.length&&(this.by_indices[e]=0,a=1),this.last[n]=l[this.by_indices[e]]}else o&&this["increment_"+n](this.rule.interval);return s&&a&&o&&this["increment_"+r](1),a},increment_monthday:function(e){for(var n=0;nr&&(this.last.day-=r,this.increment_month())}},increment_month:function(){if(this.last.day=1,this.has_by_data("BYMONTH"))this.by_indices.BYMONTH++,this.by_indices.BYMONTH==this.by_data.BYMONTH.length&&(this.by_indices.BYMONTH=0,this.increment_year(1)),this.last.month=this.by_data.BYMONTH[this.by_indices.BYMONTH];else{"MONTHLY"==this.rule.freq?this.last.month+=this.rule.interval:this.last.month++,this.last.month--;var e=t.helpers.trunc(this.last.month/12);this.last.month%=12,this.last.month++,0!=e&&this.increment_year(e)}},increment_year:function(e){this.last.year+=e},increment_generic:function(e,n,r,i){this.last[n]+=e;var s=t.helpers.trunc(this.last[n]/r);this.last[n]%=r,0!=s&&this["increment_"+i](s)},has_by_data:function(e){return e in this.rule.parts},expand_year_days:function(e){var n=new t.Time;this.days=[];var r={},i=["BYDAY","BYWEEKNO","BYMONTHDAY","BYMONTH","BYYEARDAY"];for(var s in i)if(i.hasOwnProperty(s)){var o=i[s];o in this.rule.parts&&(r[o]=this.rule.parts[o])}if("BYMONTH"in r&&"BYWEEKNO"in r){var a=1,l={};n.year=e,n.isDate=!0;for(var c=0;c0?(O=P+7*(M-1))<=A&&this.days.push(S+O):(O=B+7*(M+1))>0&&this.days.push(S+O)}}this.days.sort((function(e,t){return e-t}))}else if(2==p&&"BYDAY"in r&&"BYMONTHDAY"in r){var z=this.expand_by_day(e);for(var H in z)if(z.hasOwnProperty(H)){C=z[H];var Y=t.Time.fromDayOfYear(C,e);this.by_data.BYMONTHDAY.indexOf(Y.day)>=0&&this.days.push(C)}}else if(3==p&&"BYDAY"in r&&"BYMONTHDAY"in r&&"BYMONTH"in r){z=this.expand_by_day(e);for(var H in z)if(z.hasOwnProperty(H)){C=z[H],Y=t.Time.fromDayOfYear(C,e);this.by_data.BYMONTH.indexOf(Y.month)>=0&&this.by_data.BYMONTHDAY.indexOf(Y.day)>=0&&this.days.push(C)}}else if(2==p&&"BYDAY"in r&&"BYWEEKNO"in r){z=this.expand_by_day(e);for(var H in z)if(z.hasOwnProperty(H)){C=z[H];var U=(Y=t.Time.fromDayOfYear(C,e)).weekNumber(this.rule.wkst);this.by_data.BYWEEKNO.indexOf(U)&&this.days.push(C)}}else 3==p&&"BYDAY"in r&&"BYWEEKNO"in r&&"BYMONTHDAY"in r||(this.days=1==p&&"BYYEARDAY"in r?this.days.concat(this.by_data.BYYEARDAY):[]);return 0},expand_by_day:function(e){var t=[],n=this.last.clone();n.year=e,n.month=1,n.day=1,n.isDate=!0;var r=n.dayOfWeek();n.month=12,n.day=31,n.isDate=!0;var i=n.dayOfWeek(),s=n.dayOfYear();for(var o in this.by_data.BYDAY)if(this.by_data.BYDAY.hasOwnProperty(o)){var a=this.by_data.BYDAY[o],l=this.ruleDayOfWeek(a),c=l[0],u=l[1];if(0==c)for(var d=(u+7-r)%7+1;d<=s;d+=7)t.push(d);else if(c>0){var h;h=u>=r?u-r+1:u-r+8,t.push(h+7*(c-1))}else{var f;c=-c,f=u<=i?s-i+u:s-i+u-7,t.push(f-7*(c-1))}}return t},is_day_in_byday:function(e){for(var t in this.by_data.BYDAY)if(this.by_data.BYDAY.hasOwnProperty(t)){var n=this.by_data.BYDAY[t],r=this.ruleDayOfWeek(n),i=r[0],s=r[1],o=e.dayOfWeek();if(0==i&&s==o||e.nthWeekDay(s,i)==e.day)return 1}return 0},check_set_position:function(e){return!!this.has_by_data("BYSETPOS")&&-1!==this.by_data.BYSETPOS.indexOf(e)},sort_byday_rules:function(e){for(var t=0;tthis.ruleDayOfWeek(e[t],this.rule.wkst)[1]){var r=e[t];e[t]=e[n],e[n]=r}}},check_contract_restriction:function(t,n){var r=e._indexMap[t],i=e._expandMap[this.rule.freq][r],s=!1;if(t in this.by_data&&i==e.CONTRACT){var o=this.by_data[t];for(var a in o)if(o.hasOwnProperty(a)&&o[a]==n){s=!0;break}}else s=!0;return s},check_contracting_rules:function(){var e=this.last.dayOfWeek(),n=this.last.weekNumber(this.rule.wkst),r=this.last.dayOfYear();return this.check_contract_restriction("BYSECOND",this.last.second)&&this.check_contract_restriction("BYMINUTE",this.last.minute)&&this.check_contract_restriction("BYHOUR",this.last.hour)&&this.check_contract_restriction("BYDAY",t.Recur.numericDayToIcalDay(e))&&this.check_contract_restriction("BYWEEKNO",n)&&this.check_contract_restriction("BYMONTHDAY",this.last.day)&&this.check_contract_restriction("BYMONTH",this.last.month)&&this.check_contract_restriction("BYYEARDAY",r)},setup_defaults:function(t,n,r){var i=e._indexMap[t];return e._expandMap[this.rule.freq][i]!=e.CONTRACT&&(t in this.by_data||(this.by_data[t]=[r]),this.rule.freq!=n)?this.by_data[t][0]:r},toJSON:function(){var e=Object.create(null);return e.initialized=this.initialized,e.rule=this.rule.toJSON(),e.dtstart=this.dtstart.toJSON(),e.by_data=this.by_data,e.days=this.days,e.last=this.last.toJSON(),e.by_indices=this.by_indices,e.occurrence_number=this.occurrence_number,e}},e._indexMap={BYSECOND:0,BYMINUTE:1,BYHOUR:2,BYDAY:3,BYMONTHDAY:4,BYYEARDAY:5,BYWEEKNO:6,BYMONTH:7,BYSETPOS:8},e._expandMap={SECONDLY:[1,1,1,1,1,1,1,1],MINUTELY:[2,1,1,1,1,1,1,1],HOURLY:[2,2,1,1,1,1,1,1],DAILY:[2,2,2,1,1,1,1,1],WEEKLY:[2,2,2,2,3,3,1,1],MONTHLY:[2,2,2,2,2,3,3,1],YEARLY:[2,2,2,2,2,2,2,2]},e.UNKNOWN=0,e.CONTRACT=1,e.EXPAND=2,e.ILLEGAL=3,e}(),t.RecurExpansion=function(){function e(e){return t.helpers.formatClassType(e,t.Time)}function n(e,t){return e.compare(t)}function r(e){this.ruleDates=[],this.exDates=[],this.fromData(e)}return r.prototype={complete:!1,ruleIterators:null,ruleDates:null,exDates:null,ruleDateInc:0,exDateInc:0,exDate:null,ruleDate:null,dtstart:null,last:null,fromData:function(n){var r=t.helpers.formatClassType(n.dtstart,t.Time);if(!r)throw new Error(".dtstart (ICAL.Time) must be given");if(this.dtstart=r,n.component)this._init(n.component);else{if(this.last=e(n.last)||r.clone(),!n.ruleIterators)throw new Error(".ruleIterators or .component must be given");this.ruleIterators=n.ruleIterators.map((function(e){return t.helpers.formatClassType(e,t.RecurIterator)})),this.ruleDateInc=n.ruleDateInc,this.exDateInc=n.exDateInc,n.ruleDates&&(this.ruleDates=n.ruleDates.map(e),this.ruleDate=this.ruleDates[this.ruleDateInc]),n.exDates&&(this.exDates=n.exDates.map(e),this.exDate=this.exDates[this.exDateInc]),void 0!==n.complete&&(this.complete=n.complete)}},next:function(){for(var e,t,n,r=0;;){if(r++>500)throw new Error("max tries have occured, rule may be impossible to forfill.");if(t=this.ruleDate,e=this._nextRecurrenceIter(this.last),!t&&!e){this.complete=!0;break}if((!t||e&&t.compare(e.last)>0)&&(t=e.last.clone(),e.next()),this.ruleDate===t&&this._nextRuleDay(),this.last=t,!this.exDate||((n=this.exDate.compare(this.last))<0&&this._nextExDay(),0!==n))return this.last;this._nextExDay()}},toJSON:function(){function e(e){return e.toJSON()}var t=Object.create(null);return t.ruleIterators=this.ruleIterators.map(e),this.ruleDates&&(t.ruleDates=this.ruleDates.map(e)),this.exDates&&(t.exDates=this.exDates.map(e)),t.ruleDateInc=this.ruleDateInc,t.exDateInc=this.exDateInc,t.last=this.last.toJSON(),t.dtstart=this.dtstart.toJSON(),t.complete=this.complete,t},_extractDates:function(e,r){function i(e){s=t.helpers.binsearchInsert(o,e,n),o.splice(s,0,e)}for(var s,o=[],a=e.getAllProperties(r),l=a.length,c=0;c0)&&(r=t);return r}},r}(),t.Event=function(){function e(e,n){e instanceof t.Component||(n=e,e=null),this.component=e||new t.Component("vevent"),this._rangeExceptionCache=Object.create(null),this.exceptions=Object.create(null),this.rangeExceptions=[],n&&n.strictExceptions&&(this.strictExceptions=n.strictExceptions),n&&n.exceptions?n.exceptions.forEach(this.relateException,this):this.component.parent&&!this.isRecurrenceException()&&this.component.parent.getAllSubcomponents("vevent").forEach((function(e){e.hasProperty("recurrence-id")&&this.relateException(e)}),this)}function n(e,t){return e[0]>t[0]?1:t[0]>e[0]?-1:0}return e.prototype={THISANDFUTURE:"THISANDFUTURE",exceptions:null,strictExceptions:!1,relateException:function(e){if(this.isRecurrenceException())throw new Error("cannot relate exception to exceptions");if(e instanceof t.Component&&(e=new t.Event(e)),this.strictExceptions&&e.uid!==this.uid)throw new Error("attempted to relate unrelated exception");var r=e.recurrenceId.toString();if(this.exceptions[r]=e,e.modifiesFuture()){var i=[e.recurrenceId.toUnixTime(),r],s=t.helpers.binsearchInsert(this.rangeExceptions,i,n);this.rangeExceptions.splice(s,0,i)}},modifiesFuture:function(){return!!this.component.hasProperty("recurrence-id")&&this.component.getFirstProperty("recurrence-id").getParameter("range")===this.THISANDFUTURE},findRangeException:function(e){if(!this.rangeExceptions.length)return null;var r=e.toUnixTime(),i=t.helpers.binsearchInsert(this.rangeExceptions,[r],n);if((i-=1)<0)return null;var s=this.rangeExceptions[i];return r{"use strict";n.d(t,{d5:()=>N});var r,i,s,o=n(50172),a=[],l=[],c=o.fF.__b,u=o.fF.__r,d=o.fF.diffed,h=o.fF.__c,f=o.fF.unmount;function p(){for(var e;e=a.shift();)if(e.__P&&e.__H)try{e.__H.__h.forEach(v),e.__H.__h.forEach(y),e.__H.__h=[]}catch(r){e.__H.__h=[],o.fF.__e(r,e.__v)}}o.fF.__b=function(e){r=null,c&&c(e)},o.fF.__r=function(e){u&&u(e),0;var t=(r=e.__c).__H;t&&(i===r?(t.__h=[],r.__h=[],t.__.forEach((function(e){e.__N&&(e.__=e.__N),e.__V=l,e.__N=e.i=void 0}))):(t.__h.forEach(v),t.__h.forEach(y),t.__h=[])),i=r},o.fF.diffed=function(e){d&&d(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&(1!==a.push(t)&&s===o.fF.requestAnimationFrame||((s=o.fF.requestAnimationFrame)||m)(p)),t.__H.__.forEach((function(e){e.i&&(e.__H=e.i),e.__V!==l&&(e.__=e.__V),e.i=void 0,e.__V=l}))),i=r=null},o.fF.__c=function(e,t){t.some((function(e){try{e.__h.forEach(v),e.__h=e.__h.filter((function(e){return!e.__||y(e)}))}catch(i){t.some((function(e){e.__h&&(e.__h=[])})),t=[],o.fF.__e(i,e.__v)}})),h&&h(e,t)},o.fF.unmount=function(e){f&&f(e);var t,n=e.__c;n&&n.__H&&(n.__H.__.forEach((function(e){try{v(e)}catch(e){t=e}})),n.__H=void 0,t&&o.fF.__e(t,n.__v))};var g="function"==typeof requestAnimationFrame;function m(e){var t,n=function(){clearTimeout(r),g&&cancelAnimationFrame(t),setTimeout(e)},r=setTimeout(n,100);g&&(t=requestAnimationFrame(n))}function v(e){var t=r,n=e.__c;"function"==typeof n&&(e.__c=void 0,n()),r=t}function y(e){var t=r;e.__c=e.__(),r=t}function b(e,t){for(var n in t)e[n]=t[n];return e}function D(e,t){for(var n in e)if("__source"!==n&&!(n in t))return!0;for(var r in t)if("__source"!==r&&e[r]!==t[r])return!0;return!1}function A(e){this.props=e}(A.prototype=new o.uA).isPureReactComponent=!0,A.prototype.shouldComponentUpdate=function(e,t){return D(this.props,e)||D(this.state,t)};var E=o.fF.__b;o.fF.__b=function(e){e.type&&e.type.__f&&e.ref&&(e.props.ref=e.ref,e.ref=null),E&&E(e)};"undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.forward_ref");var _=function(e,t){return null==e?null:(0,o.v2)((0,o.v2)(e).map(t))},S=(o.v2,o.fF.__e);o.fF.__e=function(e,t,n,r){if(e.then)for(var i,s=t;s=s.__;)if((i=s.__c)&&i.__c)return null==t.__e&&(t.__e=n.__e,t.__k=n.__k),i.__c(e,t);S(e,t,n,r)};var T=o.fF.unmount;function w(e,t,n){return e&&(e.__c&&e.__c.__H&&(e.__c.__H.__.forEach((function(e){"function"==typeof e.__c&&e.__c()})),e.__c.__H=null),null!=(e=b({},e)).__c&&(e.__c.__P===n&&(e.__c.__P=t),e.__c=null),e.__k=e.__k&&e.__k.map((function(e){return w(e,t,n)}))),e}function C(e,t,n){return e&&(e.__v=null,e.__k=e.__k&&e.__k.map((function(e){return C(e,t,n)})),e.__c&&e.__c.__P===t&&(e.__e&&n.insertBefore(e.__e,e.__d),e.__c.__e=!0,e.__c.__P=n)),e}function x(){this.__u=0,this.t=null,this.__b=null}function R(e){var t=e.__.__c;return t&&t.__a&&t.__a(e)}function O(){this.u=null,this.o=null}o.fF.unmount=function(e){var t=e.__c;t&&t.__R&&t.__R(),t&&!0===e.__h&&(e.type=null),T&&T(e)},(x.prototype=new o.uA).__c=function(e,t){var n=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(n);var i=R(r.__v),s=!1,o=function(){s||(s=!0,n.__R=null,i?i(a):a())};n.__R=o;var a=function(){if(! --r.__u){if(r.state.__a){var e=r.state.__a;r.__v.__k[0]=C(e,e.__c.__P,e.__c.__O)}var t;for(r.setState({__a:r.__b=null});t=r.t.pop();)t.forceUpdate()}},l=!0===t.__h;r.__u++||l||r.setState({__a:r.__b=r.__v.__k[0]}),e.then(o,o)},x.prototype.componentWillUnmount=function(){this.t=[]},x.prototype.render=function(e,t){if(this.__b){if(this.__v.__k){var n=document.createElement("div"),r=this.__v.__k[0].__c;this.__v.__k[0]=w(this.__b,n,r.__O=r.__P)}this.__b=null}var i=t.__a&&(0,o.n)(o.FK,null,e.fallback);return i&&(i.__h=null),[(0,o.n)(o.FK,null,t.__a?null:e.children),i]};var k=function(e,t,n){if(++n[1]===n[0]&&e.o.delete(t),e.props.revealOrder&&("t"!==e.props.revealOrder[0]||!e.o.size))for(n=e.u;n;){for(;n.length>3;)n.pop()();if(n[1]>>1,1),t.i.removeChild(e)}}),(0,o.XX)((0,o.n)(I,{context:t.context},e.__v),t.l)):t.l&&t.componentWillUnmount()}function N(e,t){var n=(0,o.n)(M,{__v:e,i:t});return n.containerInfo=t,n}(O.prototype=new o.uA).__a=function(e){var t=this,n=R(t.__v),r=t.o.get(e);return r[0]++,function(i){var s=function(){t.props.revealOrder?(r.push(i),k(t,e,r)):i()};n?n(s):s()}},O.prototype.render=function(e){this.u=null,this.o=new Map;var t=(0,o.v2)(e.children);e.revealOrder&&"b"===e.revealOrder[0]&&t.reverse();for(var n=t.length;n--;)this.o.set(t[n],this.u=[1,0,this.u]);return e.children},O.prototype.componentDidUpdate=O.prototype.componentDidMount=function(){var e=this;this.o.forEach((function(t,n){k(e,n,t)}))};var P="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,B=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,z="undefined"!=typeof document,H=function(e){return("undefined"!=typeof Symbol&&"symbol"==typeof Symbol()?/fil|che|rad/i:/fil|che|ra/i).test(e)};o.uA.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach((function(e){Object.defineProperty(o.uA.prototype,e,{configurable:!0,get:function(){return this["UNSAFE_"+e]},set:function(t){Object.defineProperty(this,e,{configurable:!0,writable:!0,value:t})}})}));var Y=o.fF.event;function U(){}function j(){return this.cancelBubble}function L(){return this.defaultPrevented}o.fF.event=function(e){return Y&&(e=Y(e)),e.persist=U,e.isPropagationStopped=j,e.isDefaultPrevented=L,e.nativeEvent=e};var W={configurable:!0,get:function(){return this.class}},F=o.fF.vnode;o.fF.vnode=function(e){var t=e.type,n=e.props,r=n;if("string"==typeof t){var i=-1===t.indexOf("-");for(var s in r={},n){var a=n[s];z&&"children"===s&&"noscript"===t||"value"===s&&"defaultValue"in n&&null==a||("defaultValue"===s&&"value"in n&&null==n.value?s="value":"download"===s&&!0===a?a="":/ondoubleclick/i.test(s)?s="ondblclick":/^onchange(textarea|input)/i.test(s+t)&&!H(n.type)?s="oninput":/^onfocus$/i.test(s)?s="onfocusin":/^onblur$/i.test(s)?s="onfocusout":/^on(Ani|Tra|Tou|BeforeInp|Compo)/.test(s)?s=s.toLowerCase():i&&B.test(s)?s=s.replace(/[A-Z0-9]/g,"-$&").toLowerCase():null===a&&(a=void 0),/^oninput$/i.test(s)&&(s=s.toLowerCase(),r[s]&&(s="oninputCapture")),r[s]=a)}"select"==t&&r.multiple&&Array.isArray(r.value)&&(r.value=(0,o.v2)(n.children).forEach((function(e){e.props.selected=-1!=r.value.indexOf(e.props.value)}))),"select"==t&&null!=r.defaultValue&&(r.value=(0,o.v2)(n.children).forEach((function(e){e.props.selected=r.multiple?-1!=r.defaultValue.indexOf(e.props.value):r.defaultValue==e.props.value}))),e.props=r,n.class!=n.className&&(W.enumerable="className"in n,null!=n.className&&(r.class=n.className),Object.defineProperty(r,"className",W))}e.$$typeof=P,F&&F(e)};var V=o.fF.__r;o.fF.__r=function(e){V&&V(e),e.__c};o.FK;o.n,o.q6,o._3,o.FK,o.uA},50172:(e,t,n)=>{"use strict";n.d(t,{FK:()=>D,Ob:()=>F,Qv:()=>W,XX:()=>L,_3:()=>b,fF:()=>i,n:()=>v,q6:()=>V,uA:()=>T,v2:()=>M,zO:()=>o});var r,i,s,o,a,l,c,u,d,h={},f=[],p=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function g(e,t){for(var n in t)e[n]=t[n];return e}function m(e){var t=e.parentNode;t&&t.removeChild(e)}function v(e,t,n){var i,s,o,a={};for(o in t)"key"==o?i=t[o]:"ref"==o?s=t[o]:a[o]=t[o];if(arguments.length>2&&(a.children=arguments.length>3?r.call(arguments,2):n),"function"==typeof e&&null!=e.defaultProps)for(o in e.defaultProps)void 0===a[o]&&(a[o]=e.defaultProps[o]);return y(e,a,i,s,null)}function y(e,t,n,r,o){var a={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++s:o};return null==o&&null!=i.vnode&&i.vnode(a),a}function b(){return{current:null}}function D(e){return e.children}function A(e,t,n){"-"===t[0]?e.setProperty(t,null==n?"":n):e[t]=null==n?"":"number"!=typeof n||p.test(t)?n:n+"px"}function E(e,t,n,r,i){var s;e:if("style"===t)if("string"==typeof n)e.style.cssText=n;else{if("string"==typeof r&&(e.style.cssText=r=""),r)for(t in r)n&&t in n||A(e.style,t,"");if(n)for(t in n)r&&n[t]===r[t]||A(e.style,t,n[t])}else if("o"===t[0]&&"n"===t[1])s=t!==(t=t.replace(/Capture$/,"")),t=t.toLowerCase()in e?t.toLowerCase().slice(2):t.slice(2),e.l||(e.l={}),e.l[t+s]=n,n?r||e.addEventListener(t,s?S:_,s):e.removeEventListener(t,s?S:_,s);else if("dangerouslySetInnerHTML"!==t){if(i)t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==t&&"height"!==t&&"href"!==t&&"list"!==t&&"form"!==t&&"tabIndex"!==t&&"download"!==t&&t in e)try{e[t]=null==n?"":n;break e}catch(e){}"function"==typeof n||(null==n||!1===n&&-1==t.indexOf("-")?e.removeAttribute(t):e.setAttribute(t,n))}}function _(e){a=!0;try{return this.l[e.type+!1](i.event?i.event(e):e)}finally{a=!1}}function S(e){a=!0;try{return this.l[e.type+!0](i.event?i.event(e):e)}finally{a=!1}}function T(e,t){this.props=e,this.context=t}function w(e,t){if(null==t)return e.__?w(e.__,e.__.__k.indexOf(e)+1):null;for(var n;tt&&l.sort((function(e,t){return e.__v.__b-t.__v.__b})));O.__r=0}function k(e,t,n,r,i,s,o,a,l,c){var u,d,p,g,m,v,b,A=r&&r.__k||f,E=A.length;for(n.__k=[],u=0;u0?y(g.type,g.props,g.key,g.ref?g.ref:null,g.__v):g)){if(g.__=n,g.__b=n.__b+1,null===(p=A[u])||p&&g.key==p.key&&g.type===p.type)A[u]=void 0;else for(d=0;d=0;t--)if((n=e.__k[t])&&(r=P(n)))return r;return null}function B(e,t,n,r,s,o,a,l,c){var u,d,h,f,p,m,v,y,b,A,E,_,S,w,C,x=t.type;if(void 0!==t.constructor)return null;null!=n.__h&&(c=n.__h,l=t.__e=n.__e,t.__h=null,o=[l]),(u=i.__b)&&u(t);try{e:if("function"==typeof x){if(y=t.props,b=(u=x.contextType)&&r[u.__c],A=u?b?b.props.value:u.__:r,n.__c?v=(d=t.__c=n.__c).__=d.__E:("prototype"in x&&x.prototype.render?t.__c=d=new x(y,A):(t.__c=d=new T(y,A),d.constructor=x,d.render=j),b&&b.sub(d),d.props=y,d.state||(d.state={}),d.context=A,d.__n=r,h=d.__d=!0,d.__h=[],d._sb=[]),null==d.__s&&(d.__s=d.state),null!=x.getDerivedStateFromProps&&(d.__s==d.state&&(d.__s=g({},d.__s)),g(d.__s,x.getDerivedStateFromProps(y,d.__s))),f=d.props,p=d.state,d.__v=t,h)null==x.getDerivedStateFromProps&&null!=d.componentWillMount&&d.componentWillMount(),null!=d.componentDidMount&&d.__h.push(d.componentDidMount);else{if(null==x.getDerivedStateFromProps&&y!==f&&null!=d.componentWillReceiveProps&&d.componentWillReceiveProps(y,A),!d.__e&&null!=d.shouldComponentUpdate&&!1===d.shouldComponentUpdate(y,d.__s,A)||t.__v===n.__v){for(t.__v!==n.__v&&(d.props=y,d.state=d.__s,d.__d=!1),t.__e=n.__e,t.__k=n.__k,t.__k.forEach((function(e){e&&(e.__=t)})),E=0;E2&&(a.children=arguments.length>3?r.call(arguments,2):n),y(e.type,a,i||e.key,s||e.ref,null)}function V(e,t){var n={__c:t="__cC"+d++,__:e,Consumer:function(e,t){return e.children(t)},Provider:function(e){var n,r;return this.getChildContext||(n=[],(r={})[t]=this,this.getChildContext=function(){return r},this.shouldComponentUpdate=function(e){this.props.value!==e.value&&n.some((function(e){e.__e=!0,R(e)}))},this.sub=function(e){n.push(e);var t=e.componentWillUnmount;e.componentWillUnmount=function(){n.splice(n.indexOf(e),1),t&&t.call(e)}}),e.children}};return n.Provider.__=n.Consumer.contextType=n}r=f.slice,i={__e:function(e,t,n,r){for(var i,s,o;t=t.__;)if((i=t.__c)&&!i.__)try{if((s=i.constructor)&&null!=s.getDerivedStateFromError&&(i.setState(s.getDerivedStateFromError(e)),o=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(e,r||{}),o=i.__d),o)return i.__E=i}catch(t){e=t}throw e}},s=0,o=function(e){return null!=e&&void 0===e.constructor},a=!1,T.prototype.setState=function(e,t){var n;n=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=g({},this.state),"function"==typeof e&&(e=e(g({},n),this.props)),e&&g(n,e),null!=e&&this.__v&&(t&&this._sb.push(t),R(this))},T.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),R(this))},T.prototype.render=D,l=[],u="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,O.__r=0,d=0},67363:(e,t,n)=>{"use strict";n.d(t,{Vv:()=>de,i1:()=>d});var r=n(29174),i=n(50172);n(81098);const s=[],o={code:"en",week:{dow:0,doy:4},direction:"ltr",buttonText:{prev:"prev",next:"next",prevYear:"prev year",nextYear:"next year",year:"year",today:"today",month:"month",week:"week",day:"day",list:"list"},weekText:"W",weekTextLong:"Week",closeHint:"Close",timeHint:"Time",eventHint:"Event",allDayText:"all-day",moreLinkText:"more",noEventsText:"No events to display"},a=Object.assign(Object.assign({},o),{buttonHints:{prev:"Previous $0",next:"Next $0",today:(e,t)=>"day"===t?"Today":`This ${e}`},viewHint:"$0 view",navLinkHint:"Go to $0",moreLinkHint:e=>`Show ${e} more event${1===e?"":"s"}`});function l(e){let t=e.length>0?e[0].code:"en",n=s.concat(e),r={en:a};for(let i of n)r[i.code]=i;return{map:r,defaultCode:t}}function c(e,t){return"object"!=typeof e||Array.isArray(e)?function(e,t){let n=[].concat(e||[]),r=function(e,t){for(let n=0;n0;e-=1){let n=r.slice(0,e).join("-");if(t[n])return t[n]}}return null}(n,t)||a;return u(e,n,r)}(e,t):u(e.code,[e.code],e)}function u(e,t,n){let i=(0,r.m)([o,n],["buttonText"]);delete i.code;let{week:s}=i;return delete i.week,{codeArg:e,codes:t,week:s,simpleNumberFormat:new Intl.NumberFormat(e),options:i}}function d(e){return{id:(0,r.g)(),name:e.name,premiumReleaseDate:e.premiumReleaseDate?new Date(e.premiumReleaseDate):void 0,deps:e.deps||[],reducers:e.reducers||[],isLoadingFuncs:e.isLoadingFuncs||[],contextInit:[].concat(e.contextInit||[]),eventRefiners:e.eventRefiners||{},eventDefMemberAdders:e.eventDefMemberAdders||[],eventSourceRefiners:e.eventSourceRefiners||{},isDraggableTransformers:e.isDraggableTransformers||[],eventDragMutationMassagers:e.eventDragMutationMassagers||[],eventDefMutationAppliers:e.eventDefMutationAppliers||[],dateSelectionTransformers:e.dateSelectionTransformers||[],datePointTransforms:e.datePointTransforms||[],dateSpanTransforms:e.dateSpanTransforms||[],views:e.views||{},viewPropsTransformers:e.viewPropsTransformers||[],isPropsValid:e.isPropsValid||null,externalDefTransforms:e.externalDefTransforms||[],viewContainerAppends:e.viewContainerAppends||[],eventDropTransformers:e.eventDropTransformers||[],componentInteractions:e.componentInteractions||[],calendarInteractions:e.calendarInteractions||[],themeClasses:e.themeClasses||{},eventSourceDefs:e.eventSourceDefs||[],cmdFormatter:e.cmdFormatter,recurringTypes:e.recurringTypes||[],namedTimeZonedImpl:e.namedTimeZonedImpl,initialView:e.initialView||"",elementDraggingImpl:e.elementDraggingImpl,optionChangeHandlers:e.optionChangeHandlers||{},scrollGridImpl:e.scrollGridImpl||null,listenerRefiners:e.listenerRefiners||{},optionRefiners:e.optionRefiners||{},propSetHandlers:e.propSetHandlers||{}}}function h(){let e,t=[],n=[];return(i,s)=>(e&&(0,r.i)(i,t)&&(0,r.i)(s,n)||(e=function(e,t){let n={},r={premiumReleaseDate:void 0,reducers:[],isLoadingFuncs:[],contextInit:[],eventRefiners:{},eventDefMemberAdders:[],eventSourceRefiners:{},isDraggableTransformers:[],eventDragMutationMassagers:[],eventDefMutationAppliers:[],dateSelectionTransformers:[],datePointTransforms:[],dateSpanTransforms:[],views:{},viewPropsTransformers:[],isPropsValid:null,externalDefTransforms:[],viewContainerAppends:[],eventDropTransformers:[],componentInteractions:[],calendarInteractions:[],themeClasses:{},eventSourceDefs:[],cmdFormatter:null,recurringTypes:[],namedTimeZonedImpl:null,initialView:"",elementDraggingImpl:null,optionChangeHandlers:{},scrollGridImpl:null,listenerRefiners:{},optionRefiners:{},propSetHandlers:{}};function i(e){for(let o of e){const e=o.name,a=n[e];void 0===a?(n[e]=o.id,i(o.deps),s=o,r={premiumReleaseDate:f((t=r).premiumReleaseDate,s.premiumReleaseDate),reducers:t.reducers.concat(s.reducers),isLoadingFuncs:t.isLoadingFuncs.concat(s.isLoadingFuncs),contextInit:t.contextInit.concat(s.contextInit),eventRefiners:Object.assign(Object.assign({},t.eventRefiners),s.eventRefiners),eventDefMemberAdders:t.eventDefMemberAdders.concat(s.eventDefMemberAdders),eventSourceRefiners:Object.assign(Object.assign({},t.eventSourceRefiners),s.eventSourceRefiners),isDraggableTransformers:t.isDraggableTransformers.concat(s.isDraggableTransformers),eventDragMutationMassagers:t.eventDragMutationMassagers.concat(s.eventDragMutationMassagers),eventDefMutationAppliers:t.eventDefMutationAppliers.concat(s.eventDefMutationAppliers),dateSelectionTransformers:t.dateSelectionTransformers.concat(s.dateSelectionTransformers),datePointTransforms:t.datePointTransforms.concat(s.datePointTransforms),dateSpanTransforms:t.dateSpanTransforms.concat(s.dateSpanTransforms),views:Object.assign(Object.assign({},t.views),s.views),viewPropsTransformers:t.viewPropsTransformers.concat(s.viewPropsTransformers),isPropsValid:s.isPropsValid||t.isPropsValid,externalDefTransforms:t.externalDefTransforms.concat(s.externalDefTransforms),viewContainerAppends:t.viewContainerAppends.concat(s.viewContainerAppends),eventDropTransformers:t.eventDropTransformers.concat(s.eventDropTransformers),calendarInteractions:t.calendarInteractions.concat(s.calendarInteractions),componentInteractions:t.componentInteractions.concat(s.componentInteractions),themeClasses:Object.assign(Object.assign({},t.themeClasses),s.themeClasses),eventSourceDefs:t.eventSourceDefs.concat(s.eventSourceDefs),cmdFormatter:s.cmdFormatter||t.cmdFormatter,recurringTypes:t.recurringTypes.concat(s.recurringTypes),namedTimeZonedImpl:s.namedTimeZonedImpl||t.namedTimeZonedImpl,initialView:t.initialView||s.initialView,elementDraggingImpl:t.elementDraggingImpl||s.elementDraggingImpl,optionChangeHandlers:Object.assign(Object.assign({},t.optionChangeHandlers),s.optionChangeHandlers),scrollGridImpl:s.scrollGridImpl||t.scrollGridImpl,listenerRefiners:Object.assign(Object.assign({},t.listenerRefiners),s.listenerRefiners),optionRefiners:Object.assign(Object.assign({},t.optionRefiners),s.optionRefiners),propSetHandlers:Object.assign(Object.assign({},t.propSetHandlers),s.propSetHandlers)}):a!==o.id&&console.warn(`Duplicate plugin '${e}'`)}var t,s}return e&&i(e),i(t),r}(i,s)),t=i,n=s,e)}function f(e,t){return void 0===e?t:void 0===t?e:new Date(Math.max(e.valueOf(),t.valueOf()))}class p extends r.T{}function g(e,t,n,r){if(t[e])return t[e];let i=function(e,t,n,r){let i=n[e],s=r[e],o=e=>i&&null!==i[e]?i[e]:s&&null!==s[e]?s[e]:null,a=o("component"),l=o("superType"),c=null;if(l){if(l===e)throw new Error("Can't have a custom view type that references itself");c=g(l,t,n,r)}!a&&c&&(a=c.component);if(!a)return null;return{type:e,component:a,defaults:Object.assign(Object.assign({},c?c.defaults:{}),i?i.rawOptions:{}),overrides:Object.assign(Object.assign({},c?c.overrides:{}),s?s.rawOptions:{})}}(e,t,n,r);return i&&(t[e]=i),i}function m(e){return(0,r.a)(e,v)}function v(e){let t="function"==typeof e?{component:e}:e,{component:n}=t;return t.content?n=y(t):!n||n.prototype instanceof r.B||(n=y(Object.assign(Object.assign({},t),{content:n}))),{superType:t.type,component:n,rawOptions:t}}function y(e){return t=>(0,i.n)(r.V.Consumer,null,(n=>(0,i.n)(r.C,{elTag:"div",elClasses:(0,r.b)(n.viewSpec),renderProps:Object.assign(Object.assign({},t),{nextDayThreshold:n.options.nextDayThreshold}),generatorName:void 0,customGenerator:e.content,classNameGenerator:e.classNames,didMount:e.didMount,willUnmount:e.willUnmount})))}function b(e,t,n,i){let s=m(e),o=m(t.views),a=function(e,t){let n,r={};for(n in e)g(n,r,e,t);for(n in t)g(n,r,e,t);return r}(s,o);return(0,r.a)(a,(e=>function(e,t,n,i,s){let o=e.overrides.duration||e.defaults.duration||i.duration||n.duration,a=null,l="",c="",u={};if(o&&(a=function(e){let t=JSON.stringify(e),n=D[t];void 0===n&&(n=(0,r.d)(e),D[t]=n);return n}(o),a)){let e=(0,r.c)(a);l=e.unit,1===e.value&&(c=l,u=t[l]?t[l].rawOptions:{})}let d=t=>{let n=t.buttonText||{},r=e.defaults.buttonTextKey;return null!=r&&null!=n[r]?n[r]:null!=n[e.type]?n[e.type]:null!=n[c]?n[c]:null},h=t=>{let n=t.buttonHints||{},r=e.defaults.buttonTextKey;return null!=r&&null!=n[r]?n[r]:null!=n[e.type]?n[e.type]:null!=n[c]?n[c]:null};return{type:e.type,component:e.component,duration:a,durationUnit:l,singleUnit:c,optionDefaults:e.defaults,optionOverrides:Object.assign(Object.assign({},u),e.overrides),buttonTextOverride:d(i)||d(n)||e.overrides.buttonText,buttonTextDefault:d(s)||e.defaults.buttonText||d(r.e)||e.type,buttonTitleOverride:h(i)||h(n)||e.overrides.buttonHint,buttonTitleDefault:h(s)||e.defaults.buttonHint||h(r.e)}}(e,o,t,n,i)))}p.prototype.classes={root:"fc-theme-standard",tableCellShaded:"fc-cell-shaded",buttonGroup:"fc-button-group",button:"fc-button fc-button-primary",buttonActive:"fc-button-active"},p.prototype.baseIconClass="fc-icon",p.prototype.iconClasses={close:"fc-icon-x",prev:"fc-icon-chevron-left",next:"fc-icon-chevron-right",prevYear:"fc-icon-chevrons-left",nextYear:"fc-icon-chevrons-right"},p.prototype.rtlIconClasses={prev:"fc-icon-chevron-right",next:"fc-icon-chevron-left",prevYear:"fc-icon-chevrons-right",nextYear:"fc-icon-chevrons-left"},p.prototype.iconOverrideOption="buttonIcons",p.prototype.iconOverrideCustomButtonOption="icon",p.prototype.iconOverridePrefix="fc-icon-";let D={};function A(e,t,n){let i=t?t.activeRange:null;return S({},function(e,t){let n=(0,r.j)(t),i=[].concat(e.eventSources||[]),s=[];e.initialEvents&&i.unshift(e.initialEvents);e.events&&i.unshift(e.events);for(let o of i){let e=(0,r.p)(o,t,n);e&&s.push(e)}return s}(e,n),i,n)}function E(e,t,n,i){let s=n?n.activeRange:null;switch(t.type){case"ADD_EVENT_SOURCES":return S(e,t.sources,s,i);case"REMOVE_EVENT_SOURCE":return o=e,a=t.sourceId,(0,r.h)(o,(e=>e.sourceId!==a));case"PREV":case"NEXT":case"CHANGE_DATE":case"CHANGE_VIEW_TYPE":return n?T(e,s,i):e;case"FETCH_EVENT_SOURCES":return w(e,t.sourceIds?(0,r.f)(t.sourceIds):x(e,i),s,t.isRefetch||!1,i);case"RECEIVE_EVENTS":case"RECEIVE_EVENT_ERROR":return function(e,t,n,r){let i=e[t];if(i&&n===i.latestFetchId)return Object.assign(Object.assign({},e),{[t]:Object.assign(Object.assign({},i),{isFetching:!1,fetchRange:r})});return e}(e,t.sourceId,t.fetchId,t.fetchRange);case"REMOVE_ALL_EVENT_SOURCES":return{};default:return e}var o,a}function _(e){for(let t in e)if(e[t].isFetching)return!0;return!1}function S(e,t,n,r){let i={};for(let s of t)i[s.sourceId]=s;return n&&(i=T(i,n,r)),Object.assign(Object.assign({},e),i)}function T(e,t,n){return w(e,(0,r.h)(e,(e=>function(e,t,n){if(!R(e,n))return!e.latestFetchId;return!n.options.lazyFetching||!e.fetchRange||e.isFetching||t.starte.fetchRange.end}(e,t,n))),t,!1,n)}function w(e,t,n,r,i){let s={};for(let o in e){let a=e[o];t[o]?s[o]=C(a,n,r,i):s[o]=a}return s}function C(e,t,n,i){let{options:s,calendarApi:o}=i,a=i.pluginHooks.eventSourceDefs[e.sourceDefId],l=(0,r.g)();return a.fetch({eventSource:e,range:t,isRefetch:n,context:i},(n=>{let{rawEvents:r}=n;s.eventSourceSuccess&&(r=s.eventSourceSuccess.call(o,r,n.response)||r),e.success&&(r=e.success.call(o,r,n.response)||r),i.dispatch({type:"RECEIVE_EVENTS",sourceId:e.sourceId,fetchId:l,fetchRange:t,rawEvents:r})}),(n=>{let r=!1;s.eventSourceFailure&&(s.eventSourceFailure.call(o,n),r=!0),e.failure&&(e.failure(n),r=!0),r||console.warn(n.message,n),i.dispatch({type:"RECEIVE_EVENT_ERROR",sourceId:e.sourceId,fetchId:l,fetchRange:t,error:n})})),Object.assign(Object.assign({},e),{isFetching:!0,latestFetchId:l})}function x(e,t){return(0,r.h)(e,(e=>R(e,t)))}function R(e,t){return!t.pluginHooks.eventSourceDefs[e.sourceDefId].ignoreRange}function O(e,t){switch(t.type){case"UNSELECT_DATES":return null;case"SELECT_DATES":return t.selection;default:return e}}function k(e,t){switch(t.type){case"UNSELECT_EVENT":return"";case"SELECT_EVENT":return t.eventInstanceId;default:return e}}function I(e,t){let n;switch(t.type){case"UNSET_EVENT_DRAG":return null;case"SET_EVENT_DRAG":return n=t.state,{affectedEvents:n.affectedEvents,mutatedEvents:n.mutatedEvents,isEvent:n.isEvent};default:return e}}function M(e,t){let n;switch(t.type){case"UNSET_EVENT_RESIZE":return null;case"SET_EVENT_RESIZE":return n=t.state,{affectedEvents:n.affectedEvents,mutatedEvents:n.mutatedEvents,isEvent:n.isEvent};default:return e}}function N(e,t,n,r,i){return{header:e.headerToolbar?P(e.headerToolbar,e,t,n,r,i):null,footer:e.footerToolbar?P(e.footerToolbar,e,t,n,r,i):null}}function P(e,t,n,r,i,s){let o={},a=[],l=!1;for(let c in e){let u=B(e[c],t,n,r,i,s);o[c]=u.widgets,a.push(...u.viewsWithButtons),l=l||u.hasTitle}return{sectionWidgets:o,viewsWithButtons:a,hasTitle:l}}function B(e,t,n,i,s,o){let a="rtl"===t.direction,l=t.customButtons||{},c=n.buttonText||{},u=t.buttonText||{},d=n.buttonHints||{},h=t.buttonHints||{},f=e?e.split(" "):[],p=[],g=!1;return{widgets:f.map((e=>e.split(",").map((e=>{if("title"===e)return g=!0,{buttonName:e};let n,f,m,v,y,b;if(n=l[e])m=e=>{n.click&&n.click.call(e.target,e,e.target)},(v=i.getCustomButtonIconClass(n))||(v=i.getIconClass(e,a))||(y=n.text),b=n.hint||n.text;else if(f=s[e]){p.push(e),m=()=>{o.changeView(e)},(y=f.buttonTextOverride)||(v=i.getIconClass(e,a))||(y=f.buttonTextDefault);let n=f.buttonTextOverride||f.buttonTextDefault;b=(0,r.k)(f.buttonTitleOverride||f.buttonTitleDefault||t.viewHint,[n,e],n)}else if(o[e])if(m=()=>{o[e]()},(y=c[e])||(v=i.getIconClass(e,a))||(y=u[e]),"prevYear"===e||"nextYear"===e){let t="prevYear"===e?"prev":"next";b=(0,r.k)(d[t]||h[t],[u.year||"year","year"],u[e])}else b=t=>(0,r.k)(d[e]||h[e],[u[t]||t,t],u[e]);return{buttonName:e,buttonClick:m,buttonIcon:v,buttonText:y,buttonHint:b}})))),viewsWithButtons:p,hasTitle:g}}class z{constructor(e,t,n){this.type=e,this.getCurrentData=t,this.dateEnv=n}get calendar(){return this.getCurrentData().calendarApi}get title(){return this.getCurrentData().viewTitle}get activeStart(){return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start)}get activeEnd(){return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end)}get currentStart(){return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start)}get currentEnd(){return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end)}getOption(e){return this.getCurrentData().options[e]}}const H=d({name:"array-event-source",eventSourceDefs:[{ignoreRange:!0,parseMeta:e=>Array.isArray(e.events)?e.events:null,fetch(e,t){t({rawEvents:e.eventSource.meta})}}]});const Y=d({name:"func-event-source",eventSourceDefs:[{parseMeta:e=>"function"==typeof e.events?e.events:null,fetch(e,t,n){const{dateEnv:i}=e.context,s=e.eventSource.meta;(0,r.u)(s.bind(null,(0,r.l)(e.range,i)),(e=>t({rawEvents:e})),n)}}]});const U=d({name:"json-event-source",eventSourceRefiners:{method:String,extraParams:r.n,startParam:String,endParam:String,timeZoneParam:String},eventSourceDefs:[{parseMeta:e=>!e.url||"json"!==e.format&&e.format?null:{url:e.url,format:"json",method:(e.method||"GET").toUpperCase(),extraParams:e.extraParams,startParam:e.startParam,endParam:e.endParam,timeZoneParam:e.timeZoneParam},fetch(e,t,n){const{meta:i}=e.eventSource,s=function(e,t,n){let r,i,s,o,{dateEnv:a,options:l}=n,c={};r=e.startParam,null==r&&(r=l.startParam);i=e.endParam,null==i&&(i=l.endParam);s=e.timeZoneParam,null==s&&(s=l.timeZoneParam);o="function"==typeof e.extraParams?e.extraParams():e.extraParams||{};Object.assign(c,o),c[r]=a.formatIso(t.start),c[i]=a.formatIso(t.end),"local"!==a.timeZone&&(c[s]=a.timeZone);return c}(i,e.range,e.context);(0,r.r)(i.method,i.url,s).then((([e,n])=>{t({rawEvents:e,response:n})}),n)}}]});const j={daysOfWeek:r.n,startTime:r.d,endTime:r.d,duration:r.d,startRecur:r.n,endRecur:r.n};function L(e,t){let n=(0,r.v)(t.getCurrentData().eventSources);if(1===n.length&&1===e.length&&Array.isArray(n[0]._raw)&&Array.isArray(e[0]))return void t.dispatch({type:"RESET_RAW_EVENTS",sourceId:n[0].sourceId,rawEvents:e[0]});let i=[];for(let r of e){let e=!1;for(let t=0;t_(e.eventSources)],propSetHandlers:{dateProfile:function(e,t){t.emitter.trigger("datesSet",Object.assign(Object.assign({},(0,r.l)(e.activeRange,t.dateEnv)),{view:t.viewApi}))},eventStore:function(e,t){let{emitter:n}=t;n.hasHandlers("eventsSet")&&n.trigger("eventsSet",(0,r.w)(e,t))}}})];class F{constructor(e,t){this.runTaskOption=e,this.drainedOption=t,this.queue=[],this.delayedRunner=new r.D(this.drain.bind(this))}request(e,t){this.queue.push(e),this.delayedRunner.request(t)}pause(e){this.delayedRunner.pause(e)}resume(e,t){this.delayedRunner.resume(e,t)}drain(){let{queue:e}=this;for(;e.length;){let t,n=[];for(;t=e.shift();)this.runTask(t),n.push(t);this.drained(n)}}runTask(e){this.runTaskOption&&this.runTaskOption(e)}drained(e){this.drainedOption&&this.drainedOption(e)}}function V(e,t,n){let i;return i=/^(year|month)$/.test(e.currentRangeUnit)?e.currentRange:e.activeRange,n.formatRange(i.start,i.end,(0,r.x)(t.titleFormat||function(e){let{currentRangeUnit:t}=e;if("year"===t)return{year:"numeric"};if("month"===t)return{year:"numeric",month:"long"};let n=(0,r.y)(e.currentRange.start,e.currentRange.end);if(null!==n&&n>1)return{year:"numeric",month:"short",day:"numeric"};return{year:"numeric",month:"long",day:"numeric"}}(e)),{isEndExclusive:e.isRangeAllDay,defaultSeparator:t.titleRangeSeparator})}class G{constructor(e){this.computeCurrentViewData=(0,r.z)(this._computeCurrentViewData),this.organizeRawLocales=(0,r.z)(l),this.buildLocale=(0,r.z)(c),this.buildPluginHooks=h(),this.buildDateEnv=(0,r.z)(q),this.buildTheme=(0,r.z)(Q),this.parseToolbars=(0,r.z)(N),this.buildViewSpecs=(0,r.z)(b),this.buildDateProfileGenerator=(0,r.A)(Z),this.buildViewApi=(0,r.z)(X),this.buildViewUiProps=(0,r.A)($),this.buildEventUiBySource=(0,r.z)(K,r.E),this.buildEventUiBases=(0,r.z)(J),this.parseContextBusinessHours=(0,r.A)(te),this.buildTitle=(0,r.z)(V),this.emitter=new r.F,this.actionRunner=new F(this._handleAction.bind(this),this.updateData.bind(this)),this.currentCalendarOptionsInput={},this.currentCalendarOptionsRefined={},this.currentViewOptionsInput={},this.currentViewOptionsRefined={},this.currentCalendarOptionsRefiners={},this.optionsForRefining=[],this.optionsForHandling=[],this.getCurrentData=()=>this.data,this.dispatch=e=>{this.actionRunner.request(e)},this.props=e,this.actionRunner.pause();let t={},n=this.computeOptionsData(e.optionOverrides,t,e.calendarApi),i=n.calendarOptions.initialView||n.pluginHooks.initialView,s=this.computeCurrentViewData(i,n,e.optionOverrides,t);e.calendarApi.currentDataManager=this,this.emitter.setThisContext(e.calendarApi),this.emitter.setOptions(s.options);let o=(0,r.G)(n.calendarOptions,n.dateEnv),a=s.dateProfileGenerator.build(o);(0,r.H)(a.activeRange,o)||(o=a.currentRange.start);let u={dateEnv:n.dateEnv,options:n.calendarOptions,pluginHooks:n.pluginHooks,calendarApi:e.calendarApi,dispatch:this.dispatch,emitter:this.emitter,getCurrentData:this.getCurrentData};for(let r of n.pluginHooks.contextInit)r(u);let d=A(n.calendarOptions,a,u),f={dynamicOptionOverrides:t,currentViewType:i,currentDate:o,dateProfile:a,businessHours:this.parseContextBusinessHours(u),eventSources:d,eventUiBases:{},eventStore:(0,r.I)(),renderableEventStore:(0,r.I)(),dateSelection:null,eventSelection:"",eventDrag:null,eventResize:null,selectionConfig:this.buildViewUiProps(u).selectionConfig},p=Object.assign(Object.assign({},u),f);for(let r of n.pluginHooks.reducers)Object.assign(f,r(null,null,p));ee(f,u)&&this.emitter.trigger("loading",!0),this.state=f,this.updateData(),this.actionRunner.resume()}resetOptions(e,t){let{props:n}=this;void 0===t?n.optionOverrides=e:(n.optionOverrides=Object.assign(Object.assign({},n.optionOverrides||{}),e),this.optionsForRefining.push(...t)),(void 0===t||t.length)&&this.actionRunner.request({type:"NOTHING"})}_handleAction(e){let{props:t,state:n,emitter:i}=this,s=function(e,t){return"SET_OPTION"===t.type?Object.assign(Object.assign({},e),{[t.optionName]:t.rawOptionValue}):e}(n.dynamicOptionOverrides,e),o=this.computeOptionsData(t.optionOverrides,s,t.calendarApi),a=function(e,t){"CHANGE_VIEW_TYPE"===t.type&&(e=t.viewType);return e}(n.currentViewType,e),l=this.computeCurrentViewData(a,o,t.optionOverrides,s);t.calendarApi.currentDataManager=this,i.setThisContext(t.calendarApi),i.setOptions(l.options);let c={dateEnv:o.dateEnv,options:o.calendarOptions,pluginHooks:o.pluginHooks,calendarApi:t.calendarApi,dispatch:this.dispatch,emitter:i,getCurrentData:this.getCurrentData},{currentDate:u,dateProfile:d}=n;this.data&&this.data.dateProfileGenerator!==l.dateProfileGenerator&&(d=l.dateProfileGenerator.build(u)),u=(0,r.J)(u,e),d=function(e,t,n,r){let i;switch(t.type){case"CHANGE_VIEW_TYPE":return r.build(t.dateMarker||n);case"CHANGE_DATE":return r.build(t.dateMarker);case"PREV":if(i=r.buildPrev(e,n),i.isValid)return i;break;case"NEXT":if(i=r.buildNext(e,n),i.isValid)return i}return e}(d,e,u,l.dateProfileGenerator),"PREV"!==e.type&&"NEXT"!==e.type&&(0,r.H)(d.currentRange,u)||(u=d.currentRange.start);let h=E(n.eventSources,e,d,c),f=(0,r.K)(n.eventStore,e,h,d,c),p=_(h)&&!l.options.progressiveEventRendering&&n.renderableEventStore||f,{eventUiSingleBase:g,selectionConfig:m}=this.buildViewUiProps(c),v=this.buildEventUiBySource(h),y={dynamicOptionOverrides:s,currentViewType:a,currentDate:u,dateProfile:d,eventSources:h,eventStore:f,renderableEventStore:p,selectionConfig:m,eventUiBases:this.buildEventUiBases(p.defs,g,v),businessHours:this.parseContextBusinessHours(c),dateSelection:O(n.dateSelection,e),eventSelection:k(n.eventSelection,e),eventDrag:I(n.eventDrag,e),eventResize:M(n.eventResize,e)},b=Object.assign(Object.assign({},c),y);for(let r of o.pluginHooks.reducers)Object.assign(y,r(n,e,b));let D=ee(n,c),A=ee(y,c);!D&&A?i.trigger("loading",!0):D&&!A&&i.trigger("loading",!1),this.state=y,t.onAction&&t.onAction(e)}updateData(){let{props:e,state:t}=this,n=this.data,i=this.computeOptionsData(e.optionOverrides,t.dynamicOptionOverrides,e.calendarApi),s=this.computeCurrentViewData(t.currentViewType,i,e.optionOverrides,t.dynamicOptionOverrides),o=this.data=Object.assign(Object.assign(Object.assign({viewTitle:this.buildTitle(t.dateProfile,s.options,i.dateEnv),calendarApi:e.calendarApi,dispatch:this.dispatch,emitter:this.emitter,getCurrentData:this.getCurrentData},i),s),t),a=i.pluginHooks.optionChangeHandlers,l=n&&n.calendarOptions,c=i.calendarOptions;if(l&&l!==c){l.timeZone!==c.timeZone&&(t.eventSources=o.eventSources=function(e,t,n){let r=t?t.activeRange:null;return w(e,x(e,n),r,!0,n)}(o.eventSources,t.dateProfile,o),t.eventStore=o.eventStore=(0,r.L)(o.eventStore,n.dateEnv,o.dateEnv),t.renderableEventStore=o.renderableEventStore=(0,r.L)(o.renderableEventStore,n.dateEnv,o.dateEnv));for(let e in a)-1===this.optionsForHandling.indexOf(e)&&l[e]===c[e]||a[e](c[e],o)}this.optionsForHandling=[],e.onData&&e.onData(o)}computeOptionsData(e,t,n){if(!this.optionsForRefining.length&&e===this.stableOptionOverrides&&t===this.stableDynamicOptionOverrides)return this.stableCalendarOptionsData;let{refinedOptions:r,pluginHooks:i,localeDefaults:s,availableLocaleData:o,extra:a}=this.processRawCalendarOptions(e,t);ne(a);let l=this.buildDateEnv(r.timeZone,r.locale,r.weekNumberCalculation,r.firstDay,r.weekText,i,o,r.defaultRangeSeparator),c=this.buildViewSpecs(i.views,this.stableOptionOverrides,this.stableDynamicOptionOverrides,s),u=this.buildTheme(r,i),d=this.parseToolbars(r,this.stableOptionOverrides,u,c,n);return this.stableCalendarOptionsData={calendarOptions:r,pluginHooks:i,dateEnv:l,viewSpecs:c,theme:u,toolbarConfig:d,localeDefaults:s,availableRawLocales:o.map}}processRawCalendarOptions(e,t){let{locales:n,locale:i}=(0,r.M)([r.e,e,t]),s=this.organizeRawLocales(n),o=s.map,a=this.buildLocale(i||s.defaultCode,o).options,l=this.buildPluginHooks(e.plugins||[],W),c=this.currentCalendarOptionsRefiners=Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},r.N),r.O),r.P),l.listenerRefiners),l.optionRefiners),u={},d=(0,r.M)([r.e,a,e,t]),h={},f=this.currentCalendarOptionsInput,p=this.currentCalendarOptionsRefined,g=!1;for(let m in d)-1===this.optionsForRefining.indexOf(m)&&(d[m]===f[m]||r.Q[m]&&m in f&&r.Q[m](f[m],d[m]))?h[m]=p[m]:c[m]?(h[m]=c[m](d[m]),g=!0):u[m]=f[m];return g&&(this.currentCalendarOptionsInput=d,this.currentCalendarOptionsRefined=h,this.stableOptionOverrides=e,this.stableDynamicOptionOverrides=t),this.optionsForHandling.push(...this.optionsForRefining),this.optionsForRefining=[],{rawOptions:this.currentCalendarOptionsInput,refinedOptions:this.currentCalendarOptionsRefined,pluginHooks:l,availableLocaleData:s,localeDefaults:a,extra:u}}_computeCurrentViewData(e,t,n,r){let i=t.viewSpecs[e];if(!i)throw new Error(`viewType "${e}" is not available. Please make sure you've loaded all neccessary plugins`);let{refinedOptions:s,extra:o}=this.processRawViewOptions(i,t.pluginHooks,t.localeDefaults,n,r);return ne(o),{viewSpec:i,options:s,dateProfileGenerator:this.buildDateProfileGenerator({dateProfileGeneratorClass:i.optionDefaults.dateProfileGeneratorClass,duration:i.duration,durationUnit:i.durationUnit,usesMinMaxTime:i.optionDefaults.usesMinMaxTime,dateEnv:t.dateEnv,calendarApi:this.props.calendarApi,slotMinTime:s.slotMinTime,slotMaxTime:s.slotMaxTime,showNonCurrentDates:s.showNonCurrentDates,dayCount:s.dayCount,dateAlignment:s.dateAlignment,dateIncrement:s.dateIncrement,hiddenDays:s.hiddenDays,weekends:s.weekends,nowInput:s.now,validRangeInput:s.validRange,visibleRangeInput:s.visibleRange,fixedWeekCount:s.fixedWeekCount}),viewApi:this.buildViewApi(e,this.getCurrentData,t.dateEnv)}}processRawViewOptions(e,t,n,i,s){let o=(0,r.M)([r.e,e.optionDefaults,n,i,e.optionOverrides,s]),a=Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},r.N),r.O),r.P),r.R),t.listenerRefiners),t.optionRefiners),l={},c=this.currentViewOptionsInput,u=this.currentViewOptionsRefined,d=!1,h={};for(let f in o)o[f]===c[f]||r.Q[f]&&r.Q[f](o[f],c[f])?l[f]=u[f]:(o[f]===this.currentCalendarOptionsInput[f]||r.Q[f]&&r.Q[f](o[f],this.currentCalendarOptionsInput[f])?f in this.currentCalendarOptionsRefined&&(l[f]=this.currentCalendarOptionsRefined[f]):a[f]?l[f]=a[f](o[f]):h[f]=o[f],d=!0);return d&&(this.currentViewOptionsInput=o,this.currentViewOptionsRefined=l),{rawOptions:this.currentViewOptionsInput,refinedOptions:this.currentViewOptionsRefined,extra:h}}}function q(e,t,n,i,s,o,a,l){let u=c(t||a.defaultCode,a.map);return new r.S({calendarSystem:"gregory",timeZone:e,namedTimeZoneImpl:o.namedTimeZonedImpl,locale:u,weekNumberCalculation:n,firstDay:i,weekText:s,cmdFormatter:o.cmdFormatter,defaultSeparator:l})}function Q(e,t){return new(t.themeClasses[e.themeSystem]||p)(e)}function Z(e){return new(e.dateProfileGeneratorClass||r.U)(e)}function X(e,t,n){return new z(e,t,n)}function K(e){return(0,r.a)(e,(e=>e.ui))}function J(e,t,n){let r={"":t};for(let i in e){let t=e[i];t.sourceId&&n[t.sourceId]&&(r[i]=n[t.sourceId])}return r}function $(e){let{options:t}=e;return{eventUiSingleBase:(0,r.W)({display:t.eventDisplay,editable:t.editable,startEditable:t.eventStartEditable,durationEditable:t.eventDurationEditable,constraint:t.eventConstraint,overlap:"boolean"==typeof t.eventOverlap?t.eventOverlap:void 0,allow:t.eventAllow,backgroundColor:t.eventBackgroundColor,borderColor:t.eventBorderColor,textColor:t.eventTextColor,color:t.eventColor},e),selectionConfig:(0,r.W)({constraint:t.selectConstraint,overlap:"boolean"==typeof t.selectOverlap?t.selectOverlap:void 0,allow:t.selectAllow},e)}}function ee(e,t){for(let n of t.pluginHooks.isLoadingFuncs)if(n(e))return!0;return!1}function te(e){return(0,r.X)(e.options.businessHours,e)}function ne(e,t){for(let n in e)console.warn(`Unknown option '${n}'`+(t?` for view '${t}'`:""))}class re extends r.B{render(){let e=this.props.widgetGroups.map((e=>this.renderWidgetGroup(e)));return(0,i.n)("div",{className:"fc-toolbar-chunk"},...e)}renderWidgetGroup(e){let{props:t}=this,{theme:n}=this.context,r=[],s=!0;for(let o of e){let{buttonName:e,buttonClick:a,buttonText:l,buttonIcon:c,buttonHint:u}=o;if("title"===e)s=!1,r.push((0,i.n)("h2",{className:"fc-toolbar-title",id:t.titleId},t.title));else{let s=e===t.activeButton,o=!t.isTodayEnabled&&"today"===e||!t.isPrevEnabled&&"prev"===e||!t.isNextEnabled&&"next"===e,d=[`fc-${e}-button`,n.getClass("button")];s&&d.push(n.getClass("buttonActive")),r.push((0,i.n)("button",{type:"button",title:"function"==typeof u?u(t.navUnit):u,disabled:o,"aria-pressed":s,className:d.join(" "),onClick:a},l||(c?(0,i.n)("span",{className:c,role:"img"}):"")))}}if(r.length>1){let e=s&&n.getClass("buttonGroup")||"";return(0,i.n)("div",{className:e},...r)}return r[0]}}class ie extends r.B{render(){let e,t,{model:n,extraClassName:r}=this.props,s=!1,o=n.sectionWidgets,a=o.center;o.left?(s=!0,e=o.left):e=o.start,o.right?(s=!0,t=o.right):t=o.end;let l=[r||"","fc-toolbar",s?"fc-toolbar-ltr":""];return(0,i.n)("div",{className:l.join(" ")},this.renderSection("start",e||[]),this.renderSection("center",a||[]),this.renderSection("end",t||[]))}renderSection(e,t){let{props:n}=this;return(0,i.n)(re,{key:e,widgetGroups:t,title:n.title,navUnit:n.navUnit,activeButton:n.activeButton,isTodayEnabled:n.isTodayEnabled,isPrevEnabled:n.isPrevEnabled,isNextEnabled:n.isNextEnabled,titleId:n.titleId})}}class se extends r.B{constructor(){super(...arguments),this.state={availableWidth:null},this.handleEl=e=>{this.el=e,(0,r.Y)(this.props.elRef,e),this.updateAvailableWidth()},this.handleResize=()=>{this.updateAvailableWidth()}}render(){let{props:e,state:t}=this,{aspectRatio:n}=e,r=["fc-view-harness",n||e.liquid||e.height?"fc-view-harness-active":"fc-view-harness-passive"],s="",o="";return n?null!==t.availableWidth?s=t.availableWidth/n:o=1/n*100+"%":s=e.height||"",(0,i.n)("div",{"aria-labelledby":e.labeledById,ref:this.handleEl,className:r.join(" "),style:{height:s,paddingBottom:o}},e.children)}componentDidMount(){this.context.addResizeHandler(this.handleResize)}componentWillUnmount(){this.context.removeResizeHandler(this.handleResize)}updateAvailableWidth(){this.el&&this.props.aspectRatio&&this.setState({availableWidth:this.el.offsetWidth})}}class oe extends r.Z{constructor(e){super(e),this.handleSegClick=(e,t)=>{let{component:n}=this,{context:i}=n,s=(0,r._)(t);if(s&&n.isValidSegDownEl(e.target)){let o=(0,r.$)(e.target,".fc-event-forced-url"),a=o?o.querySelector("a[href]").href:"";i.emitter.trigger("eventClick",{el:t,event:new r.a0(n.context,s.eventRange.def,s.eventRange.instance),jsEvent:e,view:i.viewApi}),a&&!e.defaultPrevented&&(window.location.href=a)}},this.destroy=(0,r.a1)(e.el,"click",".fc-event",this.handleSegClick)}}class ae extends r.Z{constructor(e){super(e),this.handleEventElRemove=e=>{e===this.currentSegEl&&this.handleSegLeave(null,this.currentSegEl)},this.handleSegEnter=(e,t)=>{(0,r._)(t)&&(this.currentSegEl=t,this.triggerEvent("eventMouseEnter",e,t))},this.handleSegLeave=(e,t)=>{this.currentSegEl&&(this.currentSegEl=null,this.triggerEvent("eventMouseLeave",e,t))},this.removeHoverListeners=(0,r.a2)(e.el,".fc-event",this.handleSegEnter,this.handleSegLeave)}destroy(){this.removeHoverListeners()}triggerEvent(e,t,n){let{component:i}=this,{context:s}=i,o=(0,r._)(n);t&&!i.isValidSegDownEl(t.target)||s.emitter.trigger(e,{el:n,event:new r.a0(s,o.eventRange.def,o.eventRange.instance),jsEvent:t,view:s.viewApi})}}class le extends r.a3{constructor(){super(...arguments),this.buildViewContext=(0,r.z)(r.a4),this.buildViewPropTransformers=(0,r.z)(ue),this.buildToolbarProps=(0,r.z)(ce),this.headerRef=(0,i._3)(),this.footerRef=(0,i._3)(),this.interactionsStore={},this.state={viewLabelId:(0,r.a5)()},this.registerInteractiveComponent=(e,t)=>{let n=(0,r.a6)(e,t),i=[oe,ae].concat(this.props.pluginHooks.componentInteractions).map((e=>new e(n)));this.interactionsStore[e.uid]=i,r.a7[e.uid]=n},this.unregisterInteractiveComponent=e=>{let t=this.interactionsStore[e.uid];if(t){for(let e of t)e.destroy();delete this.interactionsStore[e.uid]}delete r.a7[e.uid]},this.resizeRunner=new r.D((()=>{this.props.emitter.trigger("_resize",!0),this.props.emitter.trigger("windowResize",{view:this.props.viewApi})})),this.handleWindowResize=e=>{let{options:t}=this.props;t.handleWindowResize&&e.target===window&&this.resizeRunner.request(t.windowResizeDelay)}}render(){let e,{props:t}=this,{toolbarConfig:n,options:s}=t,o=this.buildToolbarProps(t.viewSpec,t.dateProfile,t.dateProfileGenerator,t.currentDate,(0,r.a8)(t.options.now,t.dateEnv),t.viewTitle),a=!1,l="";t.isHeightAuto||t.forPrint?l="":null!=s.height?a=!0:null!=s.contentHeight?l=s.contentHeight:e=Math.max(s.aspectRatio,.5);let c=this.buildViewContext(t.viewSpec,t.viewApi,t.options,t.dateProfileGenerator,t.dateEnv,t.theme,t.pluginHooks,t.dispatch,t.getCurrentData,t.emitter,t.calendarApi,this.registerInteractiveComponent,this.unregisterInteractiveComponent),u=n.header&&n.header.hasTitle?this.state.viewLabelId:void 0;return(0,i.n)(r.V.Provider,{value:c},n.header&&(0,i.n)(ie,Object.assign({ref:this.headerRef,extraClassName:"fc-header-toolbar",model:n.header,titleId:u},o)),(0,i.n)(se,{liquid:a,height:l,aspectRatio:e,labeledById:u},this.renderView(t),this.buildAppendContent()),n.footer&&(0,i.n)(ie,Object.assign({ref:this.footerRef,extraClassName:"fc-footer-toolbar",model:n.footer,titleId:""},o)))}componentDidMount(){let{props:e}=this;this.calendarInteractions=e.pluginHooks.calendarInteractions.map((t=>new t(e))),window.addEventListener("resize",this.handleWindowResize);let{propSetHandlers:t}=e.pluginHooks;for(let n in t)t[n](e[n],e)}componentDidUpdate(e){let{props:t}=this,{propSetHandlers:n}=t.pluginHooks;for(let r in n)t[r]!==e[r]&&n[r](t[r],t)}componentWillUnmount(){window.removeEventListener("resize",this.handleWindowResize),this.resizeRunner.clear();for(let e of this.calendarInteractions)e.destroy();this.props.emitter.trigger("_unmount")}buildAppendContent(){let{props:e}=this,t=e.pluginHooks.viewContainerAppends.map((t=>t(e)));return(0,i.n)(i.FK,{},...t)}renderView(e){let{pluginHooks:t}=e,{viewSpec:n}=e,r={dateProfile:e.dateProfile,businessHours:e.businessHours,eventStore:e.renderableEventStore,eventUiBases:e.eventUiBases,dateSelection:e.dateSelection,eventSelection:e.eventSelection,eventDrag:e.eventDrag,eventResize:e.eventResize,isHeightAuto:e.isHeightAuto,forPrint:e.forPrint},s=this.buildViewPropTransformers(t.viewPropsTransformers);for(let i of s)Object.assign(r,i.transform(r,e));let o=n.component;return(0,i.n)(o,Object.assign({},r))}}function ce(e,t,n,i,s,o){let a=n.build(s,void 0,!1),l=n.buildPrev(t,i,!1),c=n.buildNext(t,i,!1);return{title:o,activeButton:e.type,navUnit:e.singleUnit,isTodayEnabled:a.isValid&&!(0,r.H)(t.currentRange,s),isPrevEnabled:l.isValid,isNextEnabled:c.isValid}}function ue(e){return e.map((e=>new e))}class de extends r.a9{constructor(e,t={}){super(),this.isRendering=!1,this.isRendered=!1,this.currentClassNames=[],this.customContentRenderId=0,this.handleAction=e=>{switch(e.type){case"SET_EVENT_DRAG":case"SET_EVENT_RESIZE":this.renderRunner.tryDrain()}},this.handleData=e=>{this.currentData=e,this.renderRunner.request(e.calendarOptions.rerenderDelay)},this.handleRenderRequest=()=>{if(this.isRendering){this.isRendered=!0;let{currentData:e}=this;(0,r.aa)((()=>{(0,i.XX)((0,i.n)(r.ab,{options:e.calendarOptions,theme:e.theme,emitter:e.emitter},((t,n,s,o)=>(this.setClassNames(t),this.setHeight(n),(0,i.n)(r.ac.Provider,{value:this.customContentRenderId},(0,i.n)(le,Object.assign({isHeightAuto:s,forPrint:o},e)))))),this.el)}))}else this.isRendered&&(this.isRendered=!1,(0,i.XX)(null,this.el),this.setClassNames([]),this.setHeight(""))},(0,r.ad)(e),this.el=e,this.renderRunner=new r.D(this.handleRenderRequest),new G({optionOverrides:t,calendarApi:this,onAction:this.handleAction,onData:this.handleData})}render(){let e=this.isRendering;e?this.customContentRenderId+=1:this.isRendering=!0,this.renderRunner.request(),e&&this.updateSize()}destroy(){this.isRendering&&(this.isRendering=!1,this.renderRunner.request())}updateSize(){(0,r.aa)((()=>{super.updateSize()}))}batchRendering(e){this.renderRunner.pause("batchRendering"),e(),this.renderRunner.resume("batchRendering")}pauseRendering(){this.renderRunner.pause("pauseRendering")}resumeRendering(){this.renderRunner.resume("pauseRendering",!0)}resetOptions(e,t){this.currentDataManager.resetOptions(e,t)}setClassNames(e){if(!(0,r.i)(e,this.currentClassNames)){let{classList:t}=this.el;for(let e of this.currentClassNames)t.remove(e);for(let n of e)t.add(n);this.currentClassNames=e}}setHeight(e){(0,r.ae)(this.el,"height",e)}}},29174:(e,t,n)=>{"use strict";n.d(t,{$:()=>p,A:()=>_e,B:()=>bt,C:()=>wt,D:()=>h,E:()=>tt,F:()=>Dn,G:()=>Ut,H:()=>Pt,I:()=>nn,J:()=>Yt,K:()=>gn,L:()=>yn,M:()=>Ge,N:()=>He,O:()=>Ue,P:()=>je,Q:()=>Le,R:()=>Ve,S:()=>ut,T:()=>dt,U:()=>Lt,V:()=>mt,W:()=>cn,X:()=>En,Y:()=>Dt,Z:()=>or,_:()=>Bn,a:()=>Je,a0:()=>On,a1:()=>_,a2:()=>S,a3:()=>yt,a4:()=>vt,a5:()=>A,a6:()=>ar,a7:()=>cr,a8:()=>jt,a9:()=>ur,aA:()=>Ht,aE:()=>hr,aF:()=>dr,aG:()=>fr,aH:()=>pr,aI:()=>gr,aO:()=>f,aP:()=>v,aR:()=>b,aV:()=>tn,aY:()=>vr,aa:()=>ht,ab:()=>sr,ac:()=>Tt,ad:()=>l,ae:()=>y,ar:()=>M,as:()=>N,at:()=>P,au:()=>B,av:()=>U,aw:()=>I,ax:()=>k,b:()=>Rt,b$:()=>wi,b0:()=>_r,b2:()=>w,b3:()=>Rr,b5:()=>kr,b6:()=>Or,b9:()=>Nt,bA:()=>Hr,bB:()=>Ur,bC:()=>Yr,bD:()=>Fr,bE:()=>jr,bF:()=>Lr,bG:()=>lr,bH:()=>Vr,bI:()=>Gr,bK:()=>ei,bO:()=>ni,bP:()=>Nn,bQ:()=>Fn,bR:()=>Yn,bS:()=>Vn,bT:()=>qn,bU:()=>Qn,bV:()=>ri,bW:()=>ii,bX:()=>wn,bZ:()=>oi,b_:()=>ai,ba:()=>Ir,bb:()=>Nr,bc:()=>Pr,bd:()=>Br,be:()=>zr,bf:()=>Kn,bg:()=>ie,bh:()=>ne,bi:()=>se,bl:()=>oe,bo:()=>Z,bp:()=>q,bs:()=>K,bt:()=>J,bu:()=>De,bv:()=>ye,bw:()=>ve,bx:()=>be,c:()=>$,ca:()=>_i,cb:()=>Ti,cc:()=>Si,cf:()=>mi,ch:()=>Jr,cj:()=>xi,ck:()=>Oi,cl:()=>Ii,cm:()=>Mi,cn:()=>Ci,co:()=>zi,cp:()=>Pi,cq:()=>Hi,cr:()=>Li,cs:()=>Vi,ct:()=>xt,cu:()=>_n,cw:()=>a,cy:()=>Zi,d:()=>V,e:()=>Ye,f:()=>$e,g:()=>O,h:()=>Ke,i:()=>ee,j:()=>pn,k:()=>Y,l:()=>Jn,m:()=>Xe,n:()=>Qe,o:()=>It,p:()=>fn,q:()=>le,r:()=>nr,s:()=>Q,t:()=>re,u:()=>er,v:()=>et,w:()=>In,x:()=>ze,y:()=>ae,z:()=>Ee});var r=n(50172),i=n(81098);const s=[],o=new Map;function a(e){s.push(e),o.forEach((t=>{u(t,e)}))}function l(e){e.isConnected&&e.getRootNode&&c(e.getRootNode())}function c(e){let t=o.get(e);if(!t||!t.isConnected){if(t=e.querySelector("style[data-fullcalendar]"),!t){t=document.createElement("style"),t.setAttribute("data-fullcalendar","");const n=function(){void 0===d&&(d=function(){const e=document.querySelector('meta[name="csp-nonce"]');if(e&&e.hasAttribute("content"))return e.getAttribute("content");const t=document.querySelector("script[nonce]");if(t)return t.nonce||"";return""}());return d}();n&&(t.nonce=n);const r=e===document?document.head:e,i=e===document?r.querySelector("script,link[rel=stylesheet],link[as=style],style"):r.firstChild;r.insertBefore(t,i)}o.set(e,t),function(e){for(const t of s)u(e,t)}(t)}}function u(e,t){const{sheet:n}=e,r=n.cssRules.length;t.split("}").forEach(((e,t)=>{(e=e.trim())&&n.insertRule(e+"}",r+t)}))}let d;"undefined"!=typeof document&&c(document);a(':root{--fc-small-font-size:.85em;--fc-page-bg-color:#fff;--fc-neutral-bg-color:hsla(0,0%,82%,.3);--fc-neutral-text-color:grey;--fc-border-color:#ddd;--fc-button-text-color:#fff;--fc-button-bg-color:#2c3e50;--fc-button-border-color:#2c3e50;--fc-button-hover-bg-color:#1e2b37;--fc-button-hover-border-color:#1a252f;--fc-button-active-bg-color:#1a252f;--fc-button-active-border-color:#151e27;--fc-event-bg-color:#3788d8;--fc-event-border-color:#3788d8;--fc-event-text-color:#fff;--fc-event-selected-overlay-color:rgba(0,0,0,.25);--fc-more-link-bg-color:#d0d0d0;--fc-more-link-text-color:inherit;--fc-event-resizer-thickness:8px;--fc-event-resizer-dot-total-width:8px;--fc-event-resizer-dot-border-width:1px;--fc-non-business-color:hsla(0,0%,84%,.3);--fc-bg-event-color:#8fdf82;--fc-bg-event-opacity:0.3;--fc-highlight-color:rgba(188,232,241,.3);--fc-today-bg-color:rgba(255,220,40,.15);--fc-now-indicator-color:red}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc{display:flex;flex-direction:column;font-size:1em}.fc,.fc *,.fc :after,.fc :before{box-sizing:border-box}.fc table{border-collapse:collapse;border-spacing:0;font-size:1em}.fc th{text-align:center}.fc td,.fc th{padding:0;vertical-align:top}.fc a[data-navlink]{cursor:pointer}.fc a[data-navlink]:hover{text-decoration:underline}.fc-direction-ltr{direction:ltr;text-align:left}.fc-direction-rtl{direction:rtl;text-align:right}.fc-theme-standard td,.fc-theme-standard th{border:1px solid var(--fc-border-color)}.fc-liquid-hack td,.fc-liquid-hack th{position:relative}@font-face{font-family:fcicons;font-style:normal;font-weight:400;src:url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBfAAAAC8AAAAYGNtYXAXVtKNAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5ZgYydxIAAAF4AAAFNGhlYWQUJ7cIAAAGrAAAADZoaGVhB20DzAAABuQAAAAkaG10eCIABhQAAAcIAAAALGxvY2ED4AU6AAAHNAAAABhtYXhwAA8AjAAAB0wAAAAgbmFtZXsr690AAAdsAAABhnBvc3QAAwAAAAAI9AAAACAAAwPAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpBgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6Qb//f//AAAAAAAg6QD//f//AAH/4xcEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAWIAjQKeAskAEwAAJSc3NjQnJiIHAQYUFwEWMjc2NCcCnuLiDQ0MJAz/AA0NAQAMJAwNDcni4gwjDQwM/wANIwz/AA0NDCMNAAAAAQFiAI0CngLJABMAACUBNjQnASYiBwYUHwEHBhQXFjI3AZ4BAA0N/wAMJAwNDeLiDQ0MJAyNAQAMIw0BAAwMDSMM4uINIwwNDQAAAAIA4gC3Ax4CngATACcAACUnNzY0JyYiDwEGFB8BFjI3NjQnISc3NjQnJiIPAQYUHwEWMjc2NCcB87e3DQ0MIw3VDQ3VDSMMDQ0BK7e3DQ0MJAzVDQ3VDCQMDQ3zuLcMJAwNDdUNIwzWDAwNIwy4twwkDA0N1Q0jDNYMDA0jDAAAAgDiALcDHgKeABMAJwAAJTc2NC8BJiIHBhQfAQcGFBcWMjchNzY0LwEmIgcGFB8BBwYUFxYyNwJJ1Q0N1Q0jDA0Nt7cNDQwjDf7V1Q0N1QwkDA0Nt7cNDQwkDLfWDCMN1Q0NDCQMt7gMIw0MDNYMIw3VDQ0MJAy3uAwjDQwMAAADAFUAAAOrA1UAMwBoAHcAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMhMjY1NCYjISIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAAVYRGRkR/qoRGRkRA1UFBAUOCQkVDAsZDf2rDRkLDBUJCA4FBQUFBQUOCQgVDAsZDQJVDRkLDBUJCQ4FBAVVAgECBQMCBwQECAX9qwQJAwQHAwMFAQICAgIBBQMDBwQDCQQCVQUIBAQHAgMFAgEC/oAZEhEZGRESGQAAAAADAFUAAAOrA1UAMwBoAIkAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMzFRQWMzI2PQEzMjY1NCYrATU0JiMiBh0BIyIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAgBkSEhmAERkZEYAZEhIZgBEZGREDVQUEBQ4JCRUMCxkN/asNGQsMFQkIDgUFBQUFBQ4JCBUMCxkNAlUNGQsMFQkJDgUEBVUCAQIFAwIHBAQIBf2rBAkDBAcDAwUBAgICAgEFAwMHBAMJBAJVBQgEBAcCAwUCAQL+gIASGRkSgBkSERmAEhkZEoAZERIZAAABAOIAjQMeAskAIAAAExcHBhQXFjI/ARcWMjc2NC8BNzY0JyYiDwEnJiIHBhQX4uLiDQ0MJAzi4gwkDA0N4uINDQwkDOLiDCQMDQ0CjeLiDSMMDQ3h4Q0NDCMN4uIMIw0MDOLiDAwNIwwAAAABAAAAAQAAa5n0y18PPPUACwQAAAAAANivOVsAAAAA2K85WwAAAAADqwNVAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAOrAAEAAAAAAAAAAAAAAAAAAAALBAAAAAAAAAAAAAAAAgAAAAQAAWIEAAFiBAAA4gQAAOIEAABVBAAAVQQAAOIAAAAAAAoAFAAeAEQAagCqAOoBngJkApoAAQAAAAsAigADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAcAAAABAAAAAAACAAcAYAABAAAAAAADAAcANgABAAAAAAAEAAcAdQABAAAAAAAFAAsAFQABAAAAAAAGAAcASwABAAAAAAAKABoAigADAAEECQABAA4ABwADAAEECQACAA4AZwADAAEECQADAA4APQADAAEECQAEAA4AfAADAAEECQAFABYAIAADAAEECQAGAA4AUgADAAEECQAKADQApGZjaWNvbnMAZgBjAGkAYwBvAG4Ac1ZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMGZjaWNvbnMAZgBjAGkAYwBvAG4Ac2ZjaWNvbnMAZgBjAGkAYwBvAG4Ac1JlZ3VsYXIAUgBlAGcAdQBsAGEAcmZjaWNvbnMAZgBjAGkAYwBvAG4Ac0ZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") format("truetype")}.fc-icon{speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;font-family:fcicons!important;font-style:normal;font-variant:normal;font-weight:400;height:1em;line-height:1;text-align:center;text-transform:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:1em}.fc-icon-chevron-left:before{content:"\\e900"}.fc-icon-chevron-right:before{content:"\\e901"}.fc-icon-chevrons-left:before{content:"\\e902"}.fc-icon-chevrons-right:before{content:"\\e903"}.fc-icon-minus-square:before{content:"\\e904"}.fc-icon-plus-square:before{content:"\\e905"}.fc-icon-x:before{content:"\\e906"}.fc .fc-button{border-radius:0;font-family:inherit;font-size:inherit;line-height:inherit;margin:0;overflow:visible;text-transform:none}.fc .fc-button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.fc .fc-button{-webkit-appearance:button}.fc .fc-button:not(:disabled){cursor:pointer}.fc .fc-button{background-color:transparent;border:1px solid transparent;border-radius:.25em;display:inline-block;font-size:1em;font-weight:400;line-height:1.5;padding:.4em .65em;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle}.fc .fc-button:hover{text-decoration:none}.fc .fc-button:focus{box-shadow:0 0 0 .2rem rgba(44,62,80,.25);outline:0}.fc .fc-button:disabled{opacity:.65}.fc .fc-button-primary{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:hover{background-color:var(--fc-button-hover-bg-color);border-color:var(--fc-button-hover-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:disabled{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button-primary:not(:disabled).fc-button-active,.fc .fc-button-primary:not(:disabled):active{background-color:var(--fc-button-active-bg-color);border-color:var(--fc-button-active-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:not(:disabled).fc-button-active:focus,.fc .fc-button-primary:not(:disabled):active:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button .fc-icon{font-size:1.5em;vertical-align:middle}.fc .fc-button-group{display:inline-flex;position:relative;vertical-align:middle}.fc .fc-button-group>.fc-button{flex:1 1 auto;position:relative}.fc .fc-button-group>.fc-button.fc-button-active,.fc .fc-button-group>.fc-button:active,.fc .fc-button-group>.fc-button:focus,.fc .fc-button-group>.fc-button:hover{z-index:1}.fc-direction-ltr .fc-button-group>.fc-button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0;margin-left:-1px}.fc-direction-ltr .fc-button-group>.fc-button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.fc-direction-rtl .fc-button-group>.fc-button:not(:first-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.fc-direction-rtl .fc-button-group>.fc-button:not(:last-child){border-bottom-left-radius:0;border-top-left-radius:0}.fc .fc-toolbar{align-items:center;display:flex;justify-content:space-between}.fc .fc-toolbar.fc-header-toolbar{margin-bottom:1.5em}.fc .fc-toolbar.fc-footer-toolbar{margin-top:1.5em}.fc .fc-toolbar-title{font-size:1.75em;margin:0}.fc-direction-ltr .fc-toolbar>*>:not(:first-child){margin-left:.75em}.fc-direction-rtl .fc-toolbar>*>:not(:first-child){margin-right:.75em}.fc-direction-rtl .fc-toolbar-ltr{flex-direction:row-reverse}.fc .fc-scroller{-webkit-overflow-scrolling:touch;position:relative}.fc .fc-scroller-liquid{height:100%}.fc .fc-scroller-liquid-absolute{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-scroller-harness{direction:ltr;overflow:hidden;position:relative}.fc .fc-scroller-harness-liquid{height:100%}.fc-direction-rtl .fc-scroller-harness>.fc-scroller{direction:rtl}.fc-theme-standard .fc-scrollgrid{border:1px solid var(--fc-border-color)}.fc .fc-scrollgrid,.fc .fc-scrollgrid table{table-layout:fixed;width:100%}.fc .fc-scrollgrid table{border-left-style:hidden;border-right-style:hidden;border-top-style:hidden}.fc .fc-scrollgrid{border-bottom-width:0;border-collapse:separate;border-right-width:0}.fc .fc-scrollgrid-liquid{height:100%}.fc .fc-scrollgrid-section,.fc .fc-scrollgrid-section table,.fc .fc-scrollgrid-section>td{height:1px}.fc .fc-scrollgrid-section-liquid>td{height:100%}.fc .fc-scrollgrid-section>*{border-left-width:0;border-top-width:0}.fc .fc-scrollgrid-section-footer>*,.fc .fc-scrollgrid-section-header>*{border-bottom-width:0}.fc .fc-scrollgrid-section-body table,.fc .fc-scrollgrid-section-footer table{border-bottom-style:hidden}.fc .fc-scrollgrid-section-sticky>*{background:var(--fc-page-bg-color);position:sticky;z-index:3}.fc .fc-scrollgrid-section-header.fc-scrollgrid-section-sticky>*{top:0}.fc .fc-scrollgrid-section-footer.fc-scrollgrid-section-sticky>*{bottom:0}.fc .fc-scrollgrid-sticky-shim{height:1px;margin-bottom:-1px}.fc-sticky{position:sticky}.fc .fc-view-harness{flex-grow:1;position:relative}.fc .fc-view-harness-active>.fc-view{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-col-header-cell-cushion{display:inline-block;padding:2px 4px}.fc .fc-bg-event,.fc .fc-highlight,.fc .fc-non-business{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-non-business{background:var(--fc-non-business-color)}.fc .fc-bg-event{background:var(--fc-bg-event-color);opacity:var(--fc-bg-event-opacity)}.fc .fc-bg-event .fc-event-title{font-size:var(--fc-small-font-size);font-style:italic;margin:.5em}.fc .fc-highlight{background:var(--fc-highlight-color)}.fc .fc-cell-shaded,.fc .fc-day-disabled{background:var(--fc-neutral-bg-color)}a.fc-event,a.fc-event:hover{text-decoration:none}.fc-event.fc-event-draggable,.fc-event[href]{cursor:pointer}.fc-event .fc-event-main{position:relative;z-index:2}.fc-event-dragging:not(.fc-event-selected){opacity:.75}.fc-event-dragging.fc-event-selected{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-event .fc-event-resizer{display:none;position:absolute;z-index:4}.fc-event-selected .fc-event-resizer,.fc-event:hover .fc-event-resizer{display:block}.fc-event-selected .fc-event-resizer{background:var(--fc-page-bg-color);border-color:inherit;border-radius:calc(var(--fc-event-resizer-dot-total-width)/2);border-style:solid;border-width:var(--fc-event-resizer-dot-border-width);height:var(--fc-event-resizer-dot-total-width);width:var(--fc-event-resizer-dot-total-width)}.fc-event-selected .fc-event-resizer:before{bottom:-20px;content:"";left:-20px;position:absolute;right:-20px;top:-20px}.fc-event-selected,.fc-event:focus{box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event-selected:before,.fc-event:focus:before{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:3}.fc-event-selected:after,.fc-event:focus:after{background:var(--fc-event-selected-overlay-color);bottom:-1px;content:"";left:-1px;position:absolute;right:-1px;top:-1px;z-index:1}.fc-h-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-h-event .fc-event-main{color:var(--fc-event-text-color)}.fc-h-event .fc-event-main-frame{display:flex}.fc-h-event .fc-event-time{max-width:100%;overflow:hidden}.fc-h-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-width:0}.fc-h-event .fc-event-title{display:inline-block;left:0;max-width:100%;overflow:hidden;right:0;vertical-align:top}.fc-h-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-start),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-end){border-bottom-left-radius:0;border-left-width:0;border-top-left-radius:0}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-end),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-start){border-bottom-right-radius:0;border-right-width:0;border-top-right-radius:0}.fc-h-event:not(.fc-event-selected) .fc-event-resizer{bottom:0;top:0;width:var(--fc-event-resizer-thickness)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end{cursor:w-resize;left:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start{cursor:e-resize;right:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-h-event.fc-event-selected .fc-event-resizer{margin-top:calc(var(--fc-event-resizer-dot-total-width)*-.5);top:50%}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-start,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-end{left:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-end,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-start{right:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc .fc-popover{box-shadow:0 2px 6px rgba(0,0,0,.15);position:absolute;z-index:9999}.fc .fc-popover-header{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:3px 4px}.fc .fc-popover-title{margin:0 2px}.fc .fc-popover-close{cursor:pointer;font-size:1.1em;opacity:.65}.fc-theme-standard .fc-popover{background:var(--fc-page-bg-color);border:1px solid var(--fc-border-color)}.fc-theme-standard .fc-popover-header{background:var(--fc-neutral-bg-color)}');class h{constructor(e){this.drainedOption=e,this.isRunning=!1,this.isDirty=!1,this.pauseDepths={},this.timeoutId=0}request(e){this.isDirty=!0,this.isPaused()||(this.clearTimeout(),null==e?this.tryDrain():this.timeoutId=setTimeout(this.tryDrain.bind(this),e))}pause(e=""){let{pauseDepths:t}=this;t[e]=(t[e]||0)+1,this.clearTimeout()}resume(e="",t){let{pauseDepths:n}=this;if(e in n){if(t)delete n[e];else{n[e]-=1,n[e]<=0&&delete n[e]}this.tryDrain()}}isPaused(){return Object.keys(this.pauseDepths).length}tryDrain(){if(!this.isRunning&&!this.isPaused()){for(this.isRunning=!0;this.isDirty;)this.isDirty=!1,this.drained();this.isRunning=!1}}clear(){this.clearTimeout(),this.isDirty=!1,this.pauseDepths={}}clearTimeout(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=0)}drained(){this.drainedOption&&this.drainedOption()}}function f(e){e.parentNode&&e.parentNode.removeChild(e)}function p(e,t){if(e.closest)return e.closest(t);if(!document.documentElement.contains(e))return null;do{if(g(e,t))return e;e=e.parentElement||e.parentNode}while(null!==e&&1===e.nodeType);return null}function g(e,t){return(e.matches||e.matchesSelector||e.msMatchesSelector).call(e,t)}const m=/(top|left|right|bottom|width|height)$/i;function v(e,t){for(let n in t)y(e,n,t[n])}function y(e,t,n){null==n?e.style[t]="":"number"==typeof n&&m.test(t)?e.style[t]=`${n}px`:e.style[t]=n}function b(e){var t,n;return null!==(n=null===(t=e.composedPath)||void 0===t?void 0:t.call(e)[0])&&void 0!==n?n:e.target}let D=0;function A(){return D+=1,"fc-dom-"+D}function E(e){e.preventDefault()}function _(e,t,n,r){let i=function(e,t){return n=>{let r=p(n.target,e);r&&t.call(r,n,r)}}(n,r);return e.addEventListener(t,i),()=>{e.removeEventListener(t,i)}}function S(e,t,n,r){let i;return _(e,"mouseover",t,((e,t)=>{if(t!==i){i=t,n(e,t);let s=e=>{i=null,r(e,t),t.removeEventListener("mouseleave",s)};t.addEventListener("mouseleave",s)}}))}const T=["webkitTransitionEnd","otransitionend","oTransitionEnd","msTransitionEnd","transitionend"];function w(e,t){let n=r=>{t(r),T.forEach((t=>{e.removeEventListener(t,n)}))};T.forEach((t=>{e.addEventListener(t,n)}))}function C(e){return Object.assign({onClick:e},x(e))}function x(e){return{tabIndex:0,onKeyDown(t){"Enter"!==t.key&&" "!==t.key||(e(t),t.preventDefault())}}}let R=0;function O(){return R+=1,String(R)}function k(){document.body.classList.add("fc-not-allowed")}function I(){document.body.classList.remove("fc-not-allowed")}function M(e){e.style.userSelect="none",e.style.webkitUserSelect="none",e.addEventListener("selectstart",E)}function N(e){e.style.userSelect="",e.style.webkitUserSelect="",e.removeEventListener("selectstart",E)}function P(e){e.addEventListener("contextmenu",E)}function B(e){e.removeEventListener("contextmenu",E)}function z(e,t,n){return n.func?n.func(e,t):function(e,t){if(!e&&!t)return 0;if(null==t)return-1;if(null==e)return 1;if("string"==typeof e||"string"==typeof t)return String(e).localeCompare(String(t));return e-t}(e[n.field],t[n.field])*(n.order||1)}function H(e,t){let n=String(e);return"000".substr(0,t-n.length)+n}function Y(e,t,n){return"function"==typeof e?e(...t):"string"==typeof e?t.reduce(((e,t,n)=>e.replace("$"+n,t||"")),e):n}function U(e,t){return e-t}function j(e){return e%1==0}function L(e){let t=e.querySelector(".fc-scrollgrid-shrink-frame"),n=e.querySelector(".fc-scrollgrid-shrink-cushion");if(!t)throw new Error("needs fc-scrollgrid-shrink-frame className");if(!n)throw new Error("needs fc-scrollgrid-shrink-cushion className");return e.getBoundingClientRect().width-t.getBoundingClientRect().width+n.getBoundingClientRect().width}const W=["years","months","days","milliseconds"],F=/^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;function V(e,t){return"string"==typeof e?function(e){let t=F.exec(e);if(t){let e=t[1]?-1:1;return{years:0,months:0,days:e*(t[2]?parseInt(t[2],10):0),milliseconds:e*(60*(t[3]?parseInt(t[3],10):0)*60*1e3+60*(t[4]?parseInt(t[4],10):0)*1e3+1e3*(t[5]?parseInt(t[5],10):0)+(t[6]?parseInt(t[6],10):0))}}return null}(e):"object"==typeof e&&e?G(e):"number"==typeof e?G({[t||"milliseconds"]:e}):null}function G(e){let t={years:e.years||e.year||0,months:e.months||e.month||0,days:e.days||e.day||0,milliseconds:60*(e.hours||e.hour||0)*60*1e3+60*(e.minutes||e.minute||0)*1e3+1e3*(e.seconds||e.second||0)+(e.milliseconds||e.millisecond||e.ms||0)},n=e.weeks||e.week;return n&&(t.days+=7*n,t.specifiedWeeks=!0),t}function q(e,t){return{years:e.years+t.years,months:e.months+t.months,days:e.days+t.days,milliseconds:e.milliseconds+t.milliseconds}}function Q(e,t){return{years:e.years-t.years,months:e.months-t.months,days:e.days-t.days,milliseconds:e.milliseconds-t.milliseconds}}function Z(e,t){return{years:e.years*t,months:e.months*t,days:e.days*t,milliseconds:e.milliseconds*t}}function X(e){return K(e)/864e5}function K(e){return 31536e6*e.years+2592e6*e.months+864e5*e.days+e.milliseconds}function J(e,t){let n=null;for(let r=0;r10&&(null==t?r=r.replace("Z",""):0!==t&&(r=r.replace("Z",Ae(t,!0)))),r}function ye(e){return e.toISOString().replace(/T.*$/,"")}function be(e){return e.toISOString().match(/^\d{4}-\d{2}/)[0]}function De(e){return H(e.getUTCHours(),2)+":"+H(e.getUTCMinutes(),2)+":"+H(e.getUTCSeconds(),2)}function Ae(e,t=!1){let n=e<0?"-":"+",r=Math.abs(e),i=Math.floor(r/60),s=Math.round(r%60);return t?`${n+H(i,2)}:${H(s,2)}`:`GMT${n}${i}${s?`:${H(s,2)}`:""}`}function Ee(e,t,n){let r,i;return function(...s){if(r){if(!ee(r,s)){n&&n(i);let r=e.apply(this,s);t&&t(r,i)||(i=r)}}else i=e.apply(this,s);return r=s,i}}function _e(e,t,n){let r,i;return s=>{if(r){if(!tt(r,s)){n&&n(i);let r=e.call(this,s);t&&t(r,i)||(i=r)}}else i=e.call(this,s);return r=s,i}}const Se={week:3,separator:0,omitZeroMinute:0,meridiem:0,omitCommas:0},Te={timeZoneName:7,era:6,year:5,month:4,day:2,weekday:2,hour:1,minute:1,second:1},we=/\s*([ap])\.?m\.?/i,Ce=/,/g,xe=/\s+/g,Re=/\u200e/g,Oe=/UTC|GMT/;class ke{constructor(e){let t={},n={},r=0;for(let i in e)i in Se?(n[i]=e[i],r=Math.max(Se[i],r)):(t[i]=e[i],i in Te&&(r=Math.max(Te[i],r)));this.standardDateProps=t,this.extendedSettings=n,this.severity=r,this.buildFormattingFunc=Ee(Ie)}format(e,t){return this.buildFormattingFunc(this.standardDateProps,this.extendedSettings,t)(e)}formatRange(e,t,n,r){let{standardDateProps:i,extendedSettings:s}=this,o=function(e,t,n){if(n.getMarkerYear(e)!==n.getMarkerYear(t))return 5;if(n.getMarkerMonth(e)!==n.getMarkerMonth(t))return 4;if(n.getMarkerDay(e)!==n.getMarkerDay(t))return 2;if(me(e)!==me(t))return 1;return 0}(e.marker,t.marker,n.calendarSystem);if(!o)return this.format(e,n);let a=o;!(a>1)||"numeric"!==i.year&&"2-digit"!==i.year||"numeric"!==i.month&&"2-digit"!==i.month||"numeric"!==i.day&&"2-digit"!==i.day||(a=1);let l=this.format(e,n),c=this.format(t,n);if(l===c)return l;let u=Ie(function(e,t){let n={};for(let r in e)(!(r in Te)||Te[r]<=t)&&(n[r]=e[r]);return n}(i,a),s,n),d=u(e),h=u(t),f=function(e,t,n,r){let i=0;for(;iAe(e.timeZoneOffset):0===r&&t.week?e=>function(e,t,n,r,i){let s=[];"long"===i?s.push(n):"short"!==i&&"narrow"!==i||s.push(t);"long"!==i&&"short"!==i||s.push(" ");s.push(r.simpleNumberFormat.format(e)),"rtl"===r.options.direction&&s.reverse();return s.join("")}(n.computeWeekNumber(e.marker),n.weekText,n.weekTextLong,n.locale,t.week):function(e,t,n){e=Object.assign({},e),t=Object.assign({},t),function(e,t){e.timeZoneName&&(e.hour||(e.hour="2-digit"),e.minute||(e.minute="2-digit"));"long"===e.timeZoneName&&(e.timeZoneName="short");t.omitZeroMinute&&(e.second||e.millisecond)&&delete t.omitZeroMinute}(e,t),e.timeZone="UTC";let r,i=new Intl.DateTimeFormat(n.locale.codes,e);if(t.omitZeroMinute){let t=Object.assign({},e);delete t.minute,r=new Intl.DateTimeFormat(n.locale.codes,t)}return s=>{let o,{marker:a}=s;return o=r&&!a.getUTCMinutes()?r:i,function(e,t,n,r,i){e=e.replace(Re,""),"short"===n.timeZoneName&&(e=function(e,t){let n=!1;e=e.replace(Oe,(()=>(n=!0,t))),n||(e+=` ${t}`);return e}(e,"UTC"===i.timeZone||null==t.timeZoneOffset?"UTC":Ae(t.timeZoneOffset)));r.omitCommas&&(e=e.replace(Ce,"").trim());r.omitZeroMinute&&(e=e.replace(":00",""));!1===r.meridiem?e=e.replace(we,"").trim():"narrow"===r.meridiem?e=e.replace(we,((e,t)=>t.toLocaleLowerCase())):"short"===r.meridiem?e=e.replace(we,((e,t)=>`${t.toLocaleLowerCase()}m`)):"lowercase"===r.meridiem&&(e=e.replace(we,(e=>e.toLocaleLowerCase())));return e=e.replace(xe," "),e=e.trim(),e}(o.format(a),s,e,t,n)}}(e,t,n)}function Me(e,t){let n=t.markerToArray(e.marker);return{marker:e.marker,timeZoneOffset:e.timeZoneOffset,array:n,year:n[0],month:n[1],day:n[2],hour:n[3],minute:n[4],second:n[5],millisecond:n[6]}}function Ne(e,t,n,r){let i=Me(e,n.calendarSystem);return{date:i,start:i,end:t?Me(t,n.calendarSystem):null,timeZone:n.timeZone,localeCodes:n.locale.codes,defaultSeparator:r||n.defaultSeparator}}class Pe{constructor(e){this.cmdStr=e}format(e,t,n){return t.cmdFormatter(this.cmdStr,Ne(e,null,t,n))}formatRange(e,t,n,r){return n.cmdFormatter(this.cmdStr,Ne(e,t,n,r))}}class Be{constructor(e){this.func=e}format(e,t,n){return this.func(Ne(e,null,t,n))}formatRange(e,t,n,r){return this.func(Ne(e,t,n,r))}}function ze(e){return"object"==typeof e&&e?new ke(e):"string"==typeof e?new Pe(e):"function"==typeof e?new Be(e):null}const He={navLinkDayClick:Qe,navLinkWeekClick:Qe,duration:V,bootstrapFontAwesome:Qe,buttonIcons:Qe,customButtons:Qe,defaultAllDayEventDuration:V,defaultTimedEventDuration:V,nextDayThreshold:V,scrollTime:V,scrollTimeReset:Boolean,slotMinTime:V,slotMaxTime:V,dayPopoverFormat:ze,slotDuration:V,snapDuration:V,headerToolbar:Qe,footerToolbar:Qe,defaultRangeSeparator:String,titleRangeSeparator:String,forceEventDuration:Boolean,dayHeaders:Boolean,dayHeaderFormat:ze,dayHeaderClassNames:Qe,dayHeaderContent:Qe,dayHeaderDidMount:Qe,dayHeaderWillUnmount:Qe,dayCellClassNames:Qe,dayCellContent:Qe,dayCellDidMount:Qe,dayCellWillUnmount:Qe,initialView:String,aspectRatio:Number,weekends:Boolean,weekNumberCalculation:Qe,weekNumbers:Boolean,weekNumberClassNames:Qe,weekNumberContent:Qe,weekNumberDidMount:Qe,weekNumberWillUnmount:Qe,editable:Boolean,viewClassNames:Qe,viewDidMount:Qe,viewWillUnmount:Qe,nowIndicator:Boolean,nowIndicatorClassNames:Qe,nowIndicatorContent:Qe,nowIndicatorDidMount:Qe,nowIndicatorWillUnmount:Qe,showNonCurrentDates:Boolean,lazyFetching:Boolean,startParam:String,endParam:String,timeZoneParam:String,timeZone:String,locales:Qe,locale:Qe,themeSystem:String,dragRevertDuration:Number,dragScroll:Boolean,allDayMaintainDuration:Boolean,unselectAuto:Boolean,dropAccept:Qe,eventOrder:function(e){let t,n,r=[],i=[];for("string"==typeof e?i=e.split(/\s*,\s*/):"function"==typeof e?i=[e]:Array.isArray(e)&&(i=e),t=0;t=0;i-=1){let s=e[i][r];if("object"==typeof s&&s)t.unshift(s);else if(void 0!==s){n[r]=s;break}}t.length&&(n[r]=Xe(t))}for(let r=e.length-1;r>=0;r-=1){let t=e[r];for(let e in t)e in n||(n[e]=t[e])}return n}function Ke(e,t){let n={};for(let r in e)t(e[r],r)&&(n[r]=e[r]);return n}function Je(e,t){let n={};for(let r in e)n[r]=t(e[r],r);return n}function $e(e){let t={};for(let n of e)t[n]=!0;return t}function et(e){let t=[];for(let n in e)t.push(e[n]);return t}function tt(e,t){if(e===t)return!0;for(let n in e)if(Ze.call(e,n)&&!(n in t))return!1;for(let n in t)if(Ze.call(t,n)&&e[n]!==t[n])return!1;return!0}const nt=/^on[A-Z]/;function rt(e,t){let n=[];for(let r in e)Ze.call(e,r)&&(r in t||n.push(r));for(let r in t)Ze.call(t,r)&&e[r]!==t[r]&&n.push(r);return n}function it(e,t,n={}){if(e===t)return!0;for(let r in t)if(!(r in e)||!st(e[r],t[r],n[r]))return!1;for(let r in e)if(!(r in t))return!1;return!0}function st(e,t,n){return e===t||!0===n||!!n&&n(e,t)}let ot={};var at,lt;at="gregory",lt=class{getMarkerYear(e){return e.getUTCFullYear()}getMarkerMonth(e){return e.getUTCMonth()}getMarkerDay(e){return e.getUTCDate()}arrayToMarker(e){return pe(e)}markerToArray(e){return fe(e)}},ot[at]=lt;const ct=/^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;class ut{constructor(e){let t=this.timeZone=e.timeZone,n="local"!==t&&"UTC"!==t;e.namedTimeZoneImpl&&n&&(this.namedTimeZoneImpl=new e.namedTimeZoneImpl(t)),this.canComputeOffset=Boolean(!n||this.namedTimeZoneImpl),this.calendarSystem=function(e){return new ot[e]}(e.calendarSystem),this.locale=e.locale,this.weekDow=e.locale.week.dow,this.weekDoy=e.locale.week.doy,"ISO"===e.weekNumberCalculation&&(this.weekDow=1,this.weekDoy=4),"number"==typeof e.firstDay&&(this.weekDow=e.firstDay),"function"==typeof e.weekNumberCalculation&&(this.weekNumberFunc=e.weekNumberCalculation),this.weekText=null!=e.weekText?e.weekText:e.locale.options.weekText,this.weekTextLong=(null!=e.weekTextLong?e.weekTextLong:e.locale.options.weekTextLong)||this.weekText,this.cmdFormatter=e.cmdFormatter,this.defaultSeparator=e.defaultSeparator}createMarker(e){let t=this.createMarkerMeta(e);return null===t?null:t.marker}createNowMarker(){return this.canComputeOffset?this.timestampToMarker((new Date).valueOf()):pe(de(new Date))}createMarkerMeta(e){if("string"==typeof e)return this.parse(e);let t=null;return"number"==typeof e?t=this.timestampToMarker(e):e instanceof Date?(e=e.valueOf(),isNaN(e)||(t=this.timestampToMarker(e))):Array.isArray(e)&&(t=pe(e)),null!==t&&ge(t)?{marker:t,isTimeUnspecified:!1,forcedTzo:null}:null}parse(e){let t=function(e){let t=ct.exec(e);if(t){let e=new Date(Date.UTC(Number(t[1]),t[3]?Number(t[3])-1:0,Number(t[5]||1),Number(t[7]||0),Number(t[8]||0),Number(t[10]||0),t[12]?1e3*Number(`0.${t[12]}`):0));if(ge(e)){let n=null;return t[13]&&(n=("-"===t[15]?-1:1)*(60*Number(t[16]||0)+Number(t[18]||0))),{marker:e,isTimeUnspecified:!t[6],timeZoneOffset:n}}}return null}(e);if(null===t)return null;let{marker:n}=t,r=null;return null!==t.timeZoneOffset&&(this.canComputeOffset?n=this.timestampToMarker(n.valueOf()-60*t.timeZoneOffset*1e3):r=t.timeZoneOffset),{marker:n,isTimeUnspecified:t.isTimeUnspecified,forcedTzo:r}}getYear(e){return this.calendarSystem.getMarkerYear(e)}getMonth(e){return this.calendarSystem.getMarkerMonth(e)}getDay(e){return this.calendarSystem.getMarkerDay(e)}add(e,t){let n=this.calendarSystem.markerToArray(e);return n[0]+=t.years,n[1]+=t.months,n[2]+=t.days,n[6]+=t.milliseconds,this.calendarSystem.arrayToMarker(n)}subtract(e,t){let n=this.calendarSystem.markerToArray(e);return n[0]-=t.years,n[1]-=t.months,n[2]-=t.days,n[6]-=t.milliseconds,this.calendarSystem.arrayToMarker(n)}addYears(e,t){let n=this.calendarSystem.markerToArray(e);return n[0]+=t,this.calendarSystem.arrayToMarker(n)}addMonths(e,t){let n=this.calendarSystem.markerToArray(e);return n[1]+=t,this.calendarSystem.arrayToMarker(n)}diffWholeYears(e,t){let{calendarSystem:n}=this;return me(e)===me(t)&&n.getMarkerDay(e)===n.getMarkerDay(t)&&n.getMarkerMonth(e)===n.getMarkerMonth(t)?n.getMarkerYear(t)-n.getMarkerYear(e):null}diffWholeMonths(e,t){let{calendarSystem:n}=this;return me(e)===me(t)&&n.getMarkerDay(e)===n.getMarkerDay(t)?n.getMarkerMonth(t)-n.getMarkerMonth(e)+12*(n.getMarkerYear(t)-n.getMarkerYear(e)):null}greatestWholeUnit(e,t){let n=this.diffWholeYears(e,t);return null!==n?{unit:"year",value:n}:(n=this.diffWholeMonths(e,t),null!==n?{unit:"month",value:n}:(n=function(e,t){let n=ae(e,t);return null!==n&&n%7==0?n/7:null}(e,t),null!==n?{unit:"week",value:n}:(n=ae(e,t),null!==n?{unit:"day",value:n}:(n=function(e,t){return(t.valueOf()-e.valueOf())/36e5}(e,t),j(n)?{unit:"hour",value:n}:(n=function(e,t){return(t.valueOf()-e.valueOf())/6e4}(e,t),j(n)?{unit:"minute",value:n}:(n=function(e,t){return(t.valueOf()-e.valueOf())/1e3}(e,t),j(n)?{unit:"second",value:n}:{unit:"millisecond",value:t.valueOf()-e.valueOf()}))))))}countDurationsBetween(e,t,n){let r;return n.years&&(r=this.diffWholeYears(e,t),null!==r)?r/(X(n)/365):n.months&&(r=this.diffWholeMonths(e,t),null!==r)?r/function(e){return X(e)/30}(n):n.days&&(r=ae(e,t),null!==r)?r/X(n):(t.valueOf()-e.valueOf())/K(n)}startOf(e,t){return"year"===t?this.startOfYear(e):"month"===t?this.startOfMonth(e):"week"===t?this.startOfWeek(e):"day"===t?le(e):"hour"===t?function(e){return pe([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours()])}(e):"minute"===t?function(e){return pe([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes()])}(e):"second"===t?function(e){return pe([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds()])}(e):null}startOfYear(e){return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(e)])}startOfMonth(e){return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(e),this.calendarSystem.getMarkerMonth(e)])}startOfWeek(e){return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(e),this.calendarSystem.getMarkerMonth(e),e.getUTCDate()-(e.getUTCDay()-this.weekDow+7)%7])}computeWeekNumber(e){return this.weekNumberFunc?this.weekNumberFunc(this.toDate(e)):function(e,t,n){let r=e.getUTCFullYear(),i=ce(e,r,t,n);if(i<1)return ce(e,r-1,t,n);let s=ce(e,r+1,t,n);return s>=1?Math.min(i,s):i}(e,this.weekDow,this.weekDoy)}format(e,t,n={}){return t.format({marker:e,timeZoneOffset:null!=n.forcedTzo?n.forcedTzo:this.offsetForMarker(e)},this)}formatRange(e,t,n,r={}){return r.isEndExclusive&&(t=ie(t,-1)),n.formatRange({marker:e,timeZoneOffset:null!=r.forcedStartTzo?r.forcedStartTzo:this.offsetForMarker(e)},{marker:t,timeZoneOffset:null!=r.forcedEndTzo?r.forcedEndTzo:this.offsetForMarker(t)},this,r.defaultSeparator)}formatIso(e,t={}){let n=null;return t.omitTimeZoneOffset||(n=null!=t.forcedTzo?t.forcedTzo:this.offsetForMarker(e)),ve(e,n,t.omitTime)}timestampToMarker(e){return"local"===this.timeZone?pe(de(new Date(e))):"UTC"!==this.timeZone&&this.namedTimeZoneImpl?pe(this.namedTimeZoneImpl.timestampToArray(e)):new Date(e)}offsetForMarker(e){return"local"===this.timeZone?-he(fe(e)).getTimezoneOffset():"UTC"===this.timeZone?0:this.namedTimeZoneImpl?this.namedTimeZoneImpl.offsetForArray(fe(e)):null}toDate(e,t){return"local"===this.timeZone?he(fe(e)):"UTC"===this.timeZone?new Date(e.valueOf()):this.namedTimeZoneImpl?new Date(e.valueOf()-1e3*this.namedTimeZoneImpl.offsetForArray(fe(e))*60):new Date(e.valueOf()-(t||0))}}class dt{constructor(e){this.iconOverrideOption&&this.setIconOverride(e[this.iconOverrideOption])}setIconOverride(e){let t,n;if("object"==typeof e&&e){for(n in t=Object.assign({},this.iconClasses),e)t[n]=this.applyIconOverridePrefix(e[n]);this.iconClasses=t}else!1===e&&(this.iconClasses={})}applyIconOverridePrefix(e){let t=this.iconOverridePrefix;return t&&0!==e.indexOf(t)&&(e=t+e),e}getClass(e){return this.classes[e]||""}getIconClass(e,t){let n;return n=t&&this.rtlIconClasses&&this.rtlIconClasses[e]||this.iconClasses[e],n?`${this.baseIconClass} ${n}`:""}getCustomButtonIconClass(e){let t;return this.iconOverrideCustomButtonOption&&(t=e[this.iconOverrideCustomButtonOption],t)?`${this.baseIconClass} ${this.applyIconOverridePrefix(t)}`:""}}function ht(e){e();let t=r.fF.debounceRendering,n=[];for(r.fF.debounceRendering=function(e){n.push(e)},r.XX(r.n(ft,{}),document.createElement("div"));n.length;)n.shift()();r.fF.debounceRendering=t}dt.prototype.classes={},dt.prototype.iconClasses={},dt.prototype.baseIconClass="",dt.prototype.iconOverridePrefix="";class ft extends r.uA{render(){return r.n("div",{})}componentDidMount(){this.setState({})}}function pt(e){let t=r.q6(e),n=t.Provider;return t.Provider=function(){let e=!this.getChildContext,t=n.apply(this,arguments);if(e){let e=[];this.shouldComponentUpdate=t=>{this.props.value!==t.value&&e.forEach((e=>{e.context=t.value,e.forceUpdate()}))},this.sub=t=>{e.push(t);let n=t.componentWillUnmount;t.componentWillUnmount=()=>{e.splice(e.indexOf(t),1),n&&n.call(t)}}}return t},t}class gt{constructor(e,t,n,r){this.execFunc=e,this.emitter=t,this.scrollTime=n,this.scrollTimeReset=r,this.handleScrollRequest=e=>{this.queuedRequest=Object.assign({},this.queuedRequest||{},e),this.drain()},t.on("_scrollRequest",this.handleScrollRequest),this.fireInitialScroll()}detach(){this.emitter.off("_scrollRequest",this.handleScrollRequest)}update(e){e&&this.scrollTimeReset?this.fireInitialScroll():this.drain()}fireInitialScroll(){this.handleScrollRequest({time:this.scrollTime})}drain(){this.queuedRequest&&this.execFunc(this.queuedRequest)&&(this.queuedRequest=null)}}const mt=pt({});function vt(e,t,n,r,i,s,o,a,l,c,u,d,h){return{dateEnv:i,options:n,pluginHooks:o,emitter:c,dispatch:a,getCurrentData:l,calendarApi:u,viewSpec:e,viewApi:t,dateProfileGenerator:r,theme:s,isRtl:"rtl"===n.direction,addResizeHandler(e){c.on("_resize",e)},removeResizeHandler(e){c.off("_resize",e)},createScrollResponder:e=>new gt(e,c,V(n.scrollTime),n.scrollTimeReset),registerInteractiveComponent:d,unregisterInteractiveComponent:h}}class yt extends r.uA{shouldComponentUpdate(e,t){return this.debug&&console.log(rt(e,this.props),rt(t,this.state)),!it(this.props,e,this.propEquality)||!it(this.state,t,this.stateEquality)}safeSetState(e){it(this.state,Object.assign(Object.assign({},this.state),e),this.stateEquality)||this.setState(e)}}yt.addPropsEquality=function(e){let t=Object.create(this.prototype.propEquality);Object.assign(t,e),this.prototype.propEquality=t},yt.addStateEquality=function(e){let t=Object.create(this.prototype.stateEquality);Object.assign(t,e),this.prototype.stateEquality=t},yt.contextType=mt,yt.prototype.propEquality={},yt.prototype.stateEquality={};class bt extends yt{}function Dt(e,t){"function"==typeof e?e(t):e&&(e.current=t)}bt.contextType=mt;class At extends bt{constructor(){super(...arguments),this.id=O(),this.queuedDomNodes=[],this.currentDomNodes=[],this.handleEl=e=>{const{options:t}=this.context,{generatorName:n}=this.props;t.customRenderingReplaces&&Et(n,t)||this.updateElRef(e)},this.updateElRef=e=>{this.props.elRef&&Dt(this.props.elRef,e)}}render(){const{props:e,context:t}=this,{options:n}=t,{customGenerator:i,defaultGenerator:s,renderProps:o}=e,a=_t(e,[],this.handleEl);let l,c,u=!1,d=[];if(null!=i){const e="function"==typeof i?i(o,r.n):i;if(!0===e)u=!0;else{const t=e&&"object"==typeof e;t&&"html"in e?a.dangerouslySetInnerHTML={__html:e.html}:t&&"domNodes"in e?d=Array.prototype.slice.call(e.domNodes):(t?(0,r.zO)(e):"function"!=typeof e)?l=e:c=e}}else u=!Et(e.generatorName,n);return u&&s&&(l=s(o)),this.queuedDomNodes=d,this.currentGeneratorMeta=c,(0,r.n)(e.elTag,a,l)}componentDidMount(){this.applyQueueudDomNodes(),this.triggerCustomRendering(!0)}componentDidUpdate(){this.applyQueueudDomNodes(),this.triggerCustomRendering(!0)}componentWillUnmount(){this.triggerCustomRendering(!1)}triggerCustomRendering(e){var t;const{props:n,context:r}=this,{handleCustomRendering:i,customRenderingMetaMap:s}=r.options;if(i){const r=null!==(t=this.currentGeneratorMeta)&&void 0!==t?t:null==s?void 0:s[n.generatorName];r&&i(Object.assign(Object.assign({id:this.id,isActive:e,containerEl:this.base,reportNewContainerEl:this.updateElRef,generatorMeta:r},n),{elClasses:(n.elClasses||[]).filter(St)}))}}applyQueueudDomNodes(){const{queuedDomNodes:e,currentDomNodes:t}=this,n=this.base;if(!ee(e,t)){t.forEach(f);for(let t of e)n.appendChild(t);this.currentDomNodes=e}}}function Et(e,t){var n;return Boolean(t.handleCustomRendering&&e&&(null===(n=t.customRenderingMetaMap)||void 0===n?void 0:n[e]))}function _t(e,t,n){const r=Object.assign(Object.assign({},e.elAttrs),{ref:n});return(e.elClasses||t)&&(r.className=(e.elClasses||[]).concat(t||[]).concat(r.className||[]).filter(Boolean).join(" ")),e.elStyle&&(r.style=e.elStyle),r}function St(e){return Boolean(e)}At.addPropsEquality({elClasses:ee,elStyle:tt,elAttrs:function(e,t){const n=rt(e,t);for(let r of n)if(!nt.test(r))return!1;return!0},renderProps:tt});const Tt=pt(0);class wt extends r.uA{constructor(){super(...arguments),this.InnerContent=Ct.bind(void 0,this),this.handleEl=e=>{this.el=e,this.props.elRef&&(Dt(this.props.elRef,e),e&&this.didMountMisfire&&this.componentDidMount())}}render(){const{props:e}=this,t=function(e,t){const n="function"==typeof e?e(t):e||[];return"string"==typeof n?[n]:n}(e.classNameGenerator,e.renderProps);if(e.children){const n=_t(e,t,this.handleEl),i=e.children(this.InnerContent,e.renderProps,n);return e.elTag?(0,r.n)(e.elTag,n,i):i}return(0,r.n)(At,Object.assign(Object.assign({},e),{elRef:this.handleEl,elTag:e.elTag||"div",elClasses:(e.elClasses||[]).concat(t),renderId:this.context}))}componentDidMount(){var e,t;this.el?null===(t=(e=this.props).didMount)||void 0===t||t.call(e,Object.assign(Object.assign({},this.props.renderProps),{el:this.el})):this.didMountMisfire=!0}componentWillUnmount(){var e,t;null===(t=(e=this.props).willUnmount)||void 0===t||t.call(e,Object.assign(Object.assign({},this.props.renderProps),{el:this.el}))}}function Ct(e,t){const n=e.props;return(0,r.n)(At,Object.assign({renderProps:n.renderProps,generatorName:n.generatorName,customGenerator:n.customGenerator,defaultGenerator:n.defaultGenerator,renderId:e.context},t))}wt.contextType=Tt;class xt extends bt{render(){let{props:e,context:t}=this,{options:n}=t,i={view:t.viewApi};return(0,r.n)(wt,Object.assign({},e,{elTag:e.elTag||"div",elClasses:[...Rt(e.viewSpec),...e.elClasses||[]],renderProps:i,classNameGenerator:n.viewClassNames,generatorName:void 0,didMount:n.viewDidMount,willUnmount:n.viewWillUnmount}),(()=>e.children))}}function Rt(e){return[`fc-${e.type}-view`,"fc-view"]}function Ot(e,t){let n,r,i=[],{start:s}=t;for(e.sort(kt),n=0;ns&&i.push({start:s,end:r.start}),r.end>s&&(s=r.end);return st.start)&&(null===e.start||null===t.end||e.start=e.start)&&(null===e.end||null!==t.end&&t.end<=e.end)}function Pt(e,t){return(null===e.start||t>=e.start)&&(null===e.end||t=K(t)&&(r=re(r,1))}return e.start&&(n=le(e.start),r&&r<=n&&(r=re(n,1))),{start:n,end:r}}function Ht(e,t,n,r){return"year"===r?V(n.diffWholeYears(e,t),"year"):"month"===r?V(n.diffWholeMonths(e,t),"month"):function(e,t){let n=le(e),r=le(t);return{years:0,months:0,days:Math.round(oe(n,r)),milliseconds:t.valueOf()-r.valueOf()-(e.valueOf()-n.valueOf())}}(e,t)}function Yt(e,t){return"CHANGE_DATE"===t.type?t.dateMarker:e}function Ut(e,t){let n=e.initialDate;return null!=n?t.createMarker(n):jt(e.now,t)}function jt(e,t){return"function"==typeof e&&(e=e()),null==e?t.createNowMarker():t.createMarker(e)}class Lt{constructor(e){this.props=e,this.nowDate=jt(e.nowInput,e.dateEnv),this.initHiddenDays()}buildPrev(e,t,n){let{dateEnv:r}=this.props,i=r.subtract(r.startOf(t,e.currentRangeUnit),e.dateIncrement);return this.build(i,-1,n)}buildNext(e,t,n){let{dateEnv:r}=this.props,i=r.add(r.startOf(t,e.currentRangeUnit),e.dateIncrement);return this.build(i,1,n)}build(e,t,n=!0){let r,i,s,o,a,l,{props:c}=this;var u,d;return r=this.buildValidRange(),r=this.trimHiddenDays(r),n&&(u=e,e=null!=(d=r).start&&u=d.end?new Date(d.end.valueOf()-1):u),i=this.buildCurrentRangeInfo(e,t),s=/^(year|month|week|day)$/.test(i.unit),o=this.buildRenderRange(this.trimHiddenDays(i.range),i.unit,s),o=this.trimHiddenDays(o),a=o,c.showNonCurrentDates||(a=It(a,i.range)),a=this.adjustActiveRange(a),a=It(a,r),l=Mt(i.range,r),Pt(o,e)||(e=o.start),{currentDate:e,validRange:r,currentRange:i.range,currentRangeUnit:i.unit,isRangeAllDay:s,activeRange:a,renderRange:o,slotMinTime:c.slotMinTime,slotMaxTime:c.slotMaxTime,isValid:l,dateIncrement:this.buildDateIncrement(i.duration)}}buildValidRange(){let e=this.props.validRangeInput,t="function"==typeof e?e.call(this.props.calendarApi,this.nowDate):e;return this.refineRange(t)||{start:null,end:null}}buildCurrentRangeInfo(e,t){let n,{props:r}=this,i=null,s=null,o=null;return r.duration?(i=r.duration,s=r.durationUnit,o=this.buildRangeFromDuration(e,t,i,s)):(n=this.props.dayCount)?(s="day",o=this.buildRangeFromDayCount(e,t,n)):(o=this.buildCustomVisibleRange(e))?s=r.dateEnv.greatestWholeUnit(o.start,o.end).unit:(i=this.getFallbackDuration(),s=$(i).unit,o=this.buildRangeFromDuration(e,t,i,s)),{duration:i,unit:s,range:o}}getFallbackDuration(){return V({day:1})}adjustActiveRange(e){let{dateEnv:t,usesMinMaxTime:n,slotMinTime:r,slotMaxTime:i}=this.props,{start:s,end:o}=e;return n&&(X(r)<0&&(s=le(s),s=t.add(s,r)),X(i)>1&&(o=le(o),o=re(o,-1),o=t.add(o,i))),{start:s,end:o}}buildRangeFromDuration(e,t,n,r){let i,s,o,{dateEnv:a,dateAlignment:l}=this.props;if(!l){let{dateIncrement:e}=this.props;l=e&&K(e)!o[e.defId].recurringDef));for(let l in o){let e=o[l];if(e.recurringDef){let{duration:n}=e.recurringDef;n||(n=e.allDay?s.defaultAllDayEventDuration:s.defaultTimedEventDuration);let o=Vt(e,n,t,r,i.recurringTypes);for(let e of o){let t=Wt(l,{start:e,end:r.add(e,n)});a[t.instanceId]=t}}}return{defs:o,instances:a}}function Vt(e,t,n,r,i){let s=i[e.recurringDef.typeId].expand(e.recurringDef.typeData,{start:r.subtract(n.start,t),end:n.end},r);return e.allDay&&(s=s.map(le)),s}const Gt={id:String,groupId:String,title:String,url:String,interactive:Boolean},qt={start:Qe,end:Qe,date:Qe,allDay:Boolean},Qt=Object.assign(Object.assign(Object.assign({},Gt),qt),{extendedProps:Qe});function Zt(e,t,n,r,i=Kt(n),s,o){let{refined:a,extra:l}=Xt(e,n,i),c=function(e,t){let n=null;e&&(n=e.defaultAllDay);null==n&&(n=t.options.defaultAllDay);return n}(t,n),u=function(e,t,n,r){for(let i=0;i{return n=t,r=e,Boolean(n.groupId&&n.groupId===r.groupId);var n,r}));return r.defs[t.defId]=t,r.instances[n.instanceId]=n,r}return{defs:{},instances:{}}}function nn(){return{defs:{},instances:{}}}function rn(e,t){return{defs:Object.assign(Object.assign({},e.defs),t.defs),instances:Object.assign(Object.assign({},e.instances),t.instances)}}function sn(e,t){let n=Ke(e.defs,t),r=Ke(e.instances,(e=>n[e.defId]));return{defs:n,instances:r}}function on(e){return Array.isArray(e)?e:"string"==typeof e?e.split(/\s+/):[]}const an={display:String,editable:Boolean,startEditable:Boolean,durationEditable:Boolean,constraint:Qe,overlap:Qe,allow:Qe,className:on,classNames:on,color:String,backgroundColor:String,borderColor:String,textColor:String},ln={display:null,startEditable:null,durationEditable:null,constraints:[],overlap:null,allows:[],backgroundColor:"",borderColor:"",textColor:"",classNames:[]};function cn(e,t){let n=function(e,t){return Array.isArray(e)?$t(e,null,t,!0):"object"==typeof e&&e?$t([e],null,t,!0):null!=e?String(e):null}(e.constraint,t);return{display:e.display||null,startEditable:null!=e.startEditable?e.startEditable:e.editable,durationEditable:null!=e.durationEditable?e.durationEditable:e.editable,constraints:null!=n?[n]:[],overlap:null!=e.overlap?e.overlap:null,allows:null!=e.allow?[e.allow]:[],backgroundColor:e.backgroundColor||e.color||"",borderColor:e.borderColor||e.color||"",textColor:e.textColor||"",classNames:(e.className||[]).concat(e.classNames||[])}}function un(e){return e.reduce(dn,ln)}function dn(e,t){return{display:null!=t.display?t.display:e.display,startEditable:null!=t.startEditable?t.startEditable:e.startEditable,durationEditable:null!=t.durationEditable?t.durationEditable:e.durationEditable,constraints:e.constraints.concat(t.constraints),overlap:"boolean"==typeof t.overlap?t.overlap:e.overlap,allows:e.allows.concat(t.allows),backgroundColor:t.backgroundColor||e.backgroundColor,borderColor:t.borderColor||e.borderColor,textColor:t.textColor||e.textColor,classNames:e.classNames.concat(t.classNames)}}const hn={id:String,defaultAllDay:Boolean,url:String,format:String,events:Qe,eventDataTransform:Qe,success:Qe,failure:Qe};function fn(e,t,n=pn(t)){let r;if("string"==typeof e?r={url:e}:"function"==typeof e||Array.isArray(e)?r={events:e}:"object"==typeof e&&e&&(r=e),r){let{refined:i,extra:s}=qe(r,n),o=function(e,t){let n=t.pluginHooks.eventSourceDefs;for(let r=n.length-1;r>=0;r-=1){let t=n[r].parseMeta(e);if(t)return{sourceDefId:r,meta:t}}return null}(i,t);if(o)return{_raw:e,isFetching:!1,latestFetchId:"",fetchRange:null,defaultAllDay:i.defaultAllDay,eventDataTransform:i.eventDataTransform,success:i.success,failure:i.failure,publicId:i.id||"",sourceId:O(),sourceDefId:o.sourceDefId,meta:o.meta,ui:cn(i,t),extendedProps:s}}return null}function pn(e){return Object.assign(Object.assign(Object.assign({},an),hn),e.pluginHooks.eventSourceRefiners)}function gn(e,t,n,r,i){switch(t.type){case"RECEIVE_EVENTS":return function(e,t,n,r,i,s){if(t&&n===t.latestFetchId){let n=$t(mn(i,t,s),t,s);return r&&(n=Ft(n,r,s)),rn(bn(e,t.sourceId),n)}return e}(e,n[t.sourceId],t.fetchId,t.fetchRange,t.rawEvents,i);case"RESET_RAW_EVENTS":return function(e,t,n,r,i){const{defIdMap:s,instanceIdMap:o}=function(e){const{defs:t,instances:n}=e,r={},i={};for(let s in t){const e=t[s],{publicId:n}=e;n&&(r[n]=s)}for(let s in n){const e=t[n[s].defId],{publicId:r}=e;r&&(i[r]=s)}return{defIdMap:r,instanceIdMap:i}}(e);let a=$t(mn(n,t,i),t,i,!1,s,o);return Ft(a,r,i)}(e,n[t.sourceId],t.rawEvents,r.activeRange,i);case"ADD_EVENTS":return function(e,t,n,r){n&&(t=Ft(t,n,r));return rn(e,t)}(e,t.eventStore,r?r.activeRange:null,i);case"RESET_EVENTS":return t.eventStore;case"MERGE_EVENTS":return rn(e,t.eventStore);case"PREV":case"NEXT":case"CHANGE_DATE":case"CHANGE_VIEW_TYPE":return r?Ft(e,r.activeRange,i):e;case"REMOVE_EVENTS":return function(e,t){let{defs:n,instances:r}=e,i={},s={};for(let o in n)t.defs[o]||(i[o]=n[o]);for(let o in r)!t.instances[o]&&i[r[o].defId]&&(s[o]=r[o]);return{defs:i,instances:s}}(e,t.eventStore);case"REMOVE_EVENT_SOURCE":return bn(e,t.sourceId);case"REMOVE_ALL_EVENT_SOURCES":return sn(e,(e=>!e.sourceId));case"REMOVE_ALL_EVENTS":return{defs:{},instances:{}};default:return e}}function mn(e,t,n){let r=n.options.eventDataTransform,i=t?t.eventDataTransform:null;return i&&(e=vn(e,i)),r&&(e=vn(e,r)),e}function vn(e,t){let n;if(t){n=[];for(let r of e){let e=t(r);e?n.push(e):null==e&&n.push(r)}}else n=e;return n}function yn(e,t,n){let{defs:r}=e,i=Je(e.instances,(e=>r[e.defId].allDay?e:Object.assign(Object.assign({},e),{range:{start:n.createMarker(t.toDate(e.range.start,e.forcedStartTzo)),end:n.createMarker(t.toDate(e.range.end,e.forcedEndTzo))},forcedStartTzo:n.canComputeOffset?null:e.forcedStartTzo,forcedEndTzo:n.canComputeOffset?null:e.forcedEndTzo})));return{defs:r,instances:i}}function bn(e,t){return sn(e,(e=>e.sourceId!==t))}class Dn{constructor(){this.handlers={},this.thisContext=null}setThisContext(e){this.thisContext=e}setOptions(e){this.options=e}on(e,t){!function(e,t,n){(e[t]||(e[t]=[])).push(n)}(this.handlers,e,t)}off(e,t){!function(e,t,n){n?e[t]&&(e[t]=e[t].filter((e=>e!==n))):delete e[t]}(this.handlers,e,t)}trigger(e,...t){let n=this.handlers[e]||[],r=this.options&&this.options[e],i=[].concat(r||[],n);for(let s of i)s.apply(this.thisContext,t)}hasHandlers(e){return Boolean(this.handlers[e]&&this.handlers[e].length||this.options&&this.options[e])}}const An={startTime:"09:00",endTime:"17:00",daysOfWeek:[1,2,3,4,5],display:"inverse-background",classNames:"fc-non-business",groupId:"_businessHours"};function En(e,t){return $t(function(e){let t;t=!0===e?[{}]:Array.isArray(e)?e.filter((e=>e.daysOfWeek)):"object"==typeof e&&e?[e]:[];return t=t.map((e=>Object.assign(Object.assign({},An),e))),t}(e),null,t)}function _n(e,t,n){n.emitter.trigger("select",Object.assign(Object.assign({},Sn(e,n)),{jsEvent:t?t.origEvent:null,view:n.viewApi||n.calendarApi.view}))}function Sn(e,t){let n={};for(let s of t.pluginHooks.dateSpanTransforms)Object.assign(n,s(e,t));var r,i;return Object.assign(n,(r=e,i=t.dateEnv,Object.assign(Object.assign({},$n(r.range,i,r.allDay)),{allDay:r.allDay}))),n}function Tn(e,t,n){let{dateEnv:r,options:i}=n,s=t;return e?(s=le(s),s=r.add(s,i.defaultAllDayEventDuration)):s=r.add(s,i.defaultTimedEventDuration),s}function wn(e,t,n,r){let i=zn(e.defs,t),s={defs:{},instances:{}};for(let o in e.defs){let t=e.defs[o];s.defs[o]=Cn(t,i[o],n,r)}for(let o in e.instances){let t=e.instances[o],a=s.defs[t.defId];s.instances[o]=xn(t,a,i[t.defId],n,r)}return s}function Cn(e,t,n,r){let i=n.standardProps||{};null==i.hasEnd&&t.durationEditable&&(n.startDelta||n.endDelta)&&(i.hasEnd=!0);let s=Object.assign(Object.assign(Object.assign({},e),i),{ui:Object.assign(Object.assign({},e.ui),i.ui)});n.extendedProps&&(s.extendedProps=Object.assign(Object.assign({},s.extendedProps),n.extendedProps));for(let o of r.pluginHooks.eventDefMutationAppliers)o(s,n,r);return!s.hasEnd&&r.options.forceEventDuration&&(s.hasEnd=!0),s}function xn(e,t,n,r,i){let{dateEnv:s}=i,o=r.standardProps&&!0===r.standardProps.allDay,a=r.standardProps&&!1===r.standardProps.hasEnd,l=Object.assign({},e);return o&&(l.range=Bt(l.range)),r.datesDelta&&n.startEditable&&(l.range={start:s.add(l.range.start,r.datesDelta),end:s.add(l.range.end,r.datesDelta)}),r.startDelta&&n.durationEditable&&(l.range={start:s.add(l.range.start,r.startDelta),end:l.range.end}),r.endDelta&&n.durationEditable&&(l.range={start:l.range.start,end:s.add(l.range.end,r.endDelta)}),a&&(l.range={start:l.range.start,end:Tn(t.allDay,l.range.start,i)}),t.allDay&&(l.range={start:le(l.range.start),end:le(l.range.end)}),l.range.endHn(e,t)))}function Hn(e,t){let n=[];return t[""]&&n.push(t[""]),t[e.defId]&&n.push(t[e.defId]),n.push(e.ui),un(n)}function Yn(e,t){let n=e.map(Un);return n.sort(((e,n)=>function(e,t,n){let r,i;for(r=0;re._seg))}function Un(e){let{eventRange:t}=e,n=t.def,r=t.instance?t.instance.range:t.range,i=r.start?r.start.valueOf():0,s=r.end?r.end.valueOf():0;return Object.assign(Object.assign(Object.assign({},n.extendedProps),n),{id:n.publicId,start:i,end:s,duration:s-i,allDay:Number(n.allDay),_seg:e})}function jn(e,t){let{pluginHooks:n}=t,r=n.isDraggableTransformers,{def:i,ui:s}=e.eventRange,o=s.startEditable;for(let a of r)o=a(o,i,s,t);return o}function Ln(e,t){return e.isStart&&e.eventRange.ui.durationEditable&&t.options.eventResizableFromStart}function Wn(e,t){return e.isEnd&&e.eventRange.ui.durationEditable}function Fn(e,t,n,r,i,s,o){let{dateEnv:a,options:l}=n,{displayEventTime:c,displayEventEnd:u}=l,d=e.eventRange.def,h=e.eventRange.instance;null==c&&(c=!1!==r),null==u&&(u=!1!==i);let f=h.range.start,p=h.range.end,g=s||e.start||e.eventRange.range.start,m=o||e.end||e.eventRange.range.end,v=le(f).valueOf()===le(g).valueOf(),y=le(ie(p,-1)).valueOf()===le(ie(m,-1)).valueOf();return c&&!d.allDay&&(v||y)?(g=v?f:g,m=y?p:m,u&&d.hasEnd?a.formatRange(g,m,t,{forcedStartTzo:s?null:h.forcedStartTzo,forcedEndTzo:o?null:h.forcedEndTzo}):a.format(g,t,{forcedTzo:s?null:h.forcedStartTzo})):""}function Vn(e,t,n){let r=e.eventRange.range;return{isPast:r.end<=(n||t.start),isFuture:r.start>=(n||t.end),isToday:t&&Pt(t,r.start)}}function Gn(e){let t=["fc-event"];return e.isMirror&&t.push("fc-event-mirror"),e.isDraggable&&t.push("fc-event-draggable"),(e.isStartResizable||e.isEndResizable)&&t.push("fc-event-resizable"),e.isDragging&&t.push("fc-event-dragging"),e.isResizing&&t.push("fc-event-resizing"),e.isSelected&&t.push("fc-event-selected"),e.isStart&&t.push("fc-event-start"),e.isEnd&&t.push("fc-event-end"),e.isPast&&t.push("fc-event-past"),e.isToday&&t.push("fc-event-today"),e.isFuture&&t.push("fc-event-future"),t}function qn(e){return e.instance?e.instance.instanceId:`${e.def.defId}:${e.range.start.toISOString()}`}function Qn(e,t){let{def:n,instance:r}=e.eventRange,{url:i}=n;if(i)return{href:i};let{emitter:s,options:o}=t,{eventInteractive:a}=o;return null==a&&(a=n.interactive,null==a&&(a=Boolean(s.hasHandlers("eventClick")))),a?x((e=>{s.trigger("eventClick",{el:e.target,event:new On(t,n,r),jsEvent:e,view:t.viewApi})})):{}}const Zn={start:Qe,end:Qe,allDay:Boolean};function Xn(e,t,n){let r=function(e,t){let{refined:n,extra:r}=qe(e,Zn),i=n.start?t.createMarkerMeta(n.start):null,s=n.end?t.createMarkerMeta(n.end):null,{allDay:o}=n;null==o&&(o=i&&i.isTimeUnspecified&&(!s||s.isTimeUnspecified));return Object.assign({range:{start:i?i.marker:null,end:s?s.marker:null},allDay:o},r)}(e,t),{range:i}=r;if(!i.start)return null;if(!i.end){if(null==n)return null;i.end=t.add(i.start,n)}return r}function Kn(e,t){return n=e.range,r=t.range,(null===n.start?null:n.start.valueOf())===(null===r.start?null:r.start.valueOf())&&(null===n.end?null:n.end.valueOf())===(null===r.end?null:r.end.valueOf())&&e.allDay===t.allDay&&function(e,t){for(let n in t)if("range"!==n&&"allDay"!==n&&e[n]!==t[n])return!1;for(let n in e)if(!(n in t))return!1;return!0}(e,t);var n,r}function Jn(e,t,n){return Object.assign(Object.assign({},$n(e,t,n)),{timeZone:t.timeZone})}function $n(e,t,n){return{start:t.toDate(e.start),end:t.toDate(e.end),startStr:t.formatIso(e.start,{omitTime:n}),endStr:t.formatIso(e.end,{omitTime:n})}}function er(e,t,n){let r=!1,i=function(e){r||(r=!0,t(e))},s=function(e){r||(r=!0,n(e))},o=e(i,s);o&&"function"==typeof o.then&&o.then(i,s)}class tr extends Error{constructor(e,t){super(e),this.response=t}}function nr(e,t,n){const r={method:e=e.toUpperCase()};return"GET"===e?t+=(-1===t.indexOf("?")?"?":"&")+new URLSearchParams(n):(r.body=new URLSearchParams(n),r.headers={"Content-Type":"application/x-www-form-urlencoded"}),fetch(t,r).then((e=>{if(e.ok)return e.json().then((t=>[t,e]),(()=>{throw new tr("Failure parsing JSON",e)}));throw new tr("Request failed",e)}))}let rr;function ir(){return null==rr&&(rr=function(){if("undefined"==typeof document)return!0;let e=document.createElement("div");e.style.position="absolute",e.style.top="0px",e.style.left="0px",e.innerHTML="
",e.querySelector("table").style.height="100px",e.querySelector("div").style.height="100%",document.body.appendChild(e);let t=e.querySelector("div").offsetHeight>0;return document.body.removeChild(e),t}()),rr}class sr extends bt{constructor(){super(...arguments),this.state={forPrint:!1},this.handleBeforePrint=()=>{ht((()=>{this.setState({forPrint:!0})}))},this.handleAfterPrint=()=>{ht((()=>{this.setState({forPrint:!1})}))}}render(){let{props:e}=this,{options:t}=e,{forPrint:n}=this.state,r=n||"auto"===t.height||"auto"===t.contentHeight,i=r||null==t.height?"":t.height,s=["fc",n?"fc-media-print":"fc-media-screen",`fc-direction-${t.direction}`,e.theme.getClass("root")];return ir()||s.push("fc-liquid-hack"),e.children(s,i,r,n)}componentDidMount(){let{emitter:e}=this.props;e.on("_beforeprint",this.handleBeforePrint),e.on("_afterprint",this.handleAfterPrint)}componentWillUnmount(){let{emitter:e}=this.props;e.off("_beforeprint",this.handleBeforePrint),e.off("_afterprint",this.handleAfterPrint)}}class or{constructor(e){this.component=e.component,this.isHitComboAllowed=e.isHitComboAllowed||null}destroy(){}}function ar(e,t){return{component:e,el:t.el,useEventCenter:null==t.useEventCenter||t.useEventCenter,isHitComboAllowed:t.isHitComboAllowed||null}}function lr(e){return{[e.component.uid]:e}}const cr={};class ur{getCurrentData(){return this.currentDataManager.getCurrentData()}dispatch(e){this.currentDataManager.dispatch(e)}get view(){return this.getCurrentData().viewApi}batchRendering(e){e()}updateSize(){this.trigger("_resize",!0)}setOption(e,t){this.dispatch({type:"SET_OPTION",optionName:e,rawOptionValue:t})}getOption(e){return this.currentDataManager.currentCalendarOptionsInput[e]}getAvailableLocaleCodes(){return Object.keys(this.getCurrentData().availableRawLocales)}on(e,t){let{currentDataManager:n}=this;n.currentCalendarOptionsRefiners[e]?n.emitter.on(e,t):console.warn(`Unknown listener name '${e}'`)}off(e,t){this.currentDataManager.emitter.off(e,t)}trigger(e,...t){this.currentDataManager.emitter.trigger(e,...t)}changeView(e,t){this.batchRendering((()=>{if(this.unselect(),t)if(t.start&&t.end)this.dispatch({type:"CHANGE_VIEW_TYPE",viewType:e}),this.dispatch({type:"SET_OPTION",optionName:"visibleRange",rawOptionValue:t});else{let{dateEnv:n}=this.getCurrentData();this.dispatch({type:"CHANGE_VIEW_TYPE",viewType:e,dateMarker:n.createMarker(t)})}else this.dispatch({type:"CHANGE_VIEW_TYPE",viewType:e})}))}zoomTo(e,t){let n;t=t||"day",n=this.getCurrentData().viewSpecs[t]||this.getUnitViewSpec(t),this.unselect(),n?this.dispatch({type:"CHANGE_VIEW_TYPE",viewType:n.type,dateMarker:e}):this.dispatch({type:"CHANGE_DATE",dateMarker:e})}getUnitViewSpec(e){let t,n,{viewSpecs:r,toolbarConfig:i}=this.getCurrentData(),s=[].concat(i.header?i.header.viewsWithButtons:[],i.footer?i.footer.viewsWithButtons:[]);for(let o in r)s.push(o);for(t=0;t{this.dispatch({type:"REMOVE_EVENTS",eventStore:kn(e)})}})}getEventById(e){let t=this.getCurrentData(),{defs:n,instances:r}=t.eventStore;e=String(e);for(let i in n){let s=n[i];if(s.publicId===e){if(s.recurringDef)return new On(t,s,null);for(let e in r){let n=r[e];if(n.defId===s.defId)return new On(t,s,n)}}}return null}getEvents(){let e=this.getCurrentData();return In(e.eventStore,e)}removeAllEvents(){this.dispatch({type:"REMOVE_ALL_EVENTS"})}getEventSources(){let e=this.getCurrentData(),t=e.eventSources,n=[];for(let r in t)n.push(new Rn(e,t[r]));return n}getEventSourceById(e){let t=this.getCurrentData(),n=t.eventSources;e=String(e);for(let r in n)if(n[r].publicId===e)return new Rn(t,n[r]);return null}addEventSource(e){let t=this.getCurrentData();if(e instanceof Rn)return t.eventSources[e.internalEventSource.sourceId]||this.dispatch({type:"ADD_EVENT_SOURCES",sources:[e.internalEventSource]}),e;let n=fn(e,t);return n?(this.dispatch({type:"ADD_EVENT_SOURCES",sources:[n]}),new Rn(t,n)):null}removeAllEventSources(){this.dispatch({type:"REMOVE_ALL_EVENT_SOURCES"})}refetchEvents(){this.dispatch({type:"FETCH_EVENT_SOURCES",isRefetch:!0})}scrollToTime(e){let t=V(e);t&&this.trigger("_scrollRequest",{time:t})}}function dr(e,t){return e.left>=t.left&&e.left=t.top&&e.topthis.eventUiBuilders[t]||Ee(yr)));for(let c in t){let n=t[c],u=s[c]||mr,d=this.eventUiBuilders[c];l[c]={businessHours:n.businessHours||e.businessHours,dateSelection:r[c]||null,eventStore:u,eventUiBases:d(e.eventUiBases[""],n.ui,i[c]),eventSelection:u.instances[e.eventSelection]?e.eventSelection:"",eventDrag:o[c]||null,eventResize:a[c]||null}}return l}_splitDateSpan(e){let t={};if(e){let n=this.getKeysForDateSpan(e);for(let r of n)t[r]=e}return t}_getKeysForEventDefs(e){return Je(e.defs,(e=>this.getKeysForEventDef(e)))}_splitEventStore(e,t){let{defs:n,instances:r}=e,i={};for(let s in n)for(let e of t[s])i[e]||(i[e]={defs:{},instances:{}}),i[e].defs[s]=n[s];for(let s in r){let e=r[s];for(let n of t[e.defId])i[n]&&(i[n].instances[s]=e)}return i}_splitIndividualUi(e,t){let n={};for(let r in e)if(r)for(let i of t[r])n[i]||(n[i]={}),n[i][r]=e[r];return n}_splitInteraction(e){let t={};if(e){let n=this._splitEventStore(e.affectedEvents,this._getKeysForEventDefs(e.affectedEvents)),r=this._getKeysForEventDefs(e.mutatedEvents),i=this._splitEventStore(e.mutatedEvents,r),s=r=>{t[r]||(t[r]={affectedEvents:n[r]||mr,mutatedEvents:i[r]||mr,isEvent:e.isEvent})};for(let e in n)s(e);for(let e in i)s(e)}return t}}function yr(e,t,n){let r=[];e&&r.push(e),t&&r.push(t);let i={"":un(r)};return n&&Object.assign(i,n),i}function br(e,t,n,r){return{dow:e.getUTCDay(),isDisabled:Boolean(r&&!Pt(r.activeRange,e)),isOther:Boolean(r&&!Pt(r.currentRange,e)),isToday:Boolean(t&&Pt(t,e)),isPast:Boolean(n?en:!!t&&e>=t.end)}}function Dr(e,t){let n=["fc-day",`fc-day-${te[e.dow]}`];return e.isDisabled?n.push("fc-day-disabled"):(e.isToday&&(n.push("fc-day-today"),n.push(t.getClass("today"))),e.isPast&&n.push("fc-day-past"),e.isFuture&&n.push("fc-day-future"),e.isOther&&n.push("fc-day-other")),n}const Ar=ze({year:"numeric",month:"long",day:"numeric"}),Er=ze({week:"long"});function _r(e,t,n="day",r=!0){const{dateEnv:i,options:s,calendarApi:o}=e;let a=i.format(t,"week"===n?Er:Ar);if(s.navLinks){let e=i.toDate(t);const l=e=>{let r="day"===n?s.navLinkDayClick:"week"===n?s.navLinkWeekClick:null;"function"==typeof r?r.call(o,i.toDate(t),e):("string"==typeof r&&(n=r),o.zoomTo(t,n))};return Object.assign({title:Y(s.navLinkHint,[a,e],a),"data-navlink":""},r?C(l):{onClick:l})}return{"aria-label":a}}let Sr,Tr=null;function wr(){return null===Tr&&(Tr=function(){let e=document.createElement("div");v(e,{position:"absolute",top:-1e3,left:0,border:0,padding:0,overflow:"scroll",direction:"rtl"}),e.innerHTML="
",document.body.appendChild(e);let t=e.firstChild.getBoundingClientRect().left>e.getBoundingClientRect().left;return f(e),t}()),Tr}function Cr(){return Sr||(Sr=function(){let e=document.createElement("div");e.style.overflow="scroll",e.style.position="absolute",e.style.top="-9999px",e.style.left="-9999px",document.body.appendChild(e);let t=xr(e);return document.body.removeChild(e),t}()),Sr}function xr(e){return{x:e.offsetHeight-e.clientHeight,y:e.offsetWidth-e.clientWidth}}function Rr(e,t=!1,n){let r=n?e.getBoundingClientRect():Or(e),i=function(e,t=!1){let n=window.getComputedStyle(e),r=parseInt(n.borderLeftWidth,10)||0,i=parseInt(n.borderRightWidth,10)||0,s=parseInt(n.borderTopWidth,10)||0,o=parseInt(n.borderBottomWidth,10)||0,a=xr(e),l=a.y-r-i,c={borderLeft:r,borderRight:i,borderTop:s,borderBottom:o,scrollbarBottom:a.x-s-o,scrollbarLeft:0,scrollbarRight:0};return wr()&&"rtl"===n.direction?c.scrollbarLeft=l:c.scrollbarRight=l,t&&(c.paddingLeft=parseInt(n.paddingLeft,10)||0,c.paddingRight=parseInt(n.paddingRight,10)||0,c.paddingTop=parseInt(n.paddingTop,10)||0,c.paddingBottom=parseInt(n.paddingBottom,10)||0),c}(e,t),s={left:r.left+i.borderLeft+i.scrollbarLeft,right:r.right-i.borderRight-i.scrollbarRight,top:r.top+i.borderTop,bottom:r.bottom-i.borderBottom-i.scrollbarBottom};return t&&(s.left+=i.paddingLeft,s.right-=i.paddingRight,s.top+=i.paddingTop,s.bottom-=i.paddingBottom),s}function Or(e){let t=e.getBoundingClientRect();return{left:t.left+window.pageXOffset,top:t.top+window.pageYOffset,right:t.right+window.pageXOffset,bottom:t.bottom+window.pageYOffset}}function kr(e){let t=[];for(;e instanceof HTMLElement;){let n=window.getComputedStyle(e);if("fixed"===n.position)break;/(auto|scroll)/.test(n.overflow+n.overflowY+n.overflowX)&&t.push(e),e=e.parentNode}return t}class Ir{constructor(e,t,n,r){this.els=t;let i=this.originClientRect=e.getBoundingClientRect();n&&this.buildElHorizontals(i.left),r&&this.buildElVerticals(i.top)}buildElHorizontals(e){let t=[],n=[];for(let r of this.els){let i=r.getBoundingClientRect();t.push(i.left-e),n.push(i.right-e)}this.lefts=t,this.rights=n}buildElVerticals(e){let t=[],n=[];for(let r of this.els){let i=r.getBoundingClientRect();t.push(i.top-e),n.push(i.bottom-e)}this.tops=t,this.bottoms=n}leftToIndex(e){let t,{lefts:n,rights:r}=this,i=n.length;for(t=0;t=n[t]&&e=n[t]&&e0}canScrollHorizontally(){return this.getMaxScrollLeft()>0}canScrollUp(){return this.getScrollTop()>0}canScrollDown(){return this.getScrollTop()0}canScrollRight(){return this.getScrollLeft()e.thickness||1)){this.getEntryThickness=e,this.strictOrder=!1,this.allowReslicing=!1,this.maxCoord=-1,this.maxStackCnt=-1,this.levelCoords=[],this.entriesByLevel=[],this.stackCnts={}}addSegs(e){let t=[];for(let n of e)this.insertEntry(n,t);return t}insertEntry(e,t){let n=this.findInsertion(e);this.isInsertionValid(n,e)?this.insertEntryAt(e,n):this.handleInvalidInsertion(n,e,t)}isInsertionValid(e,t){return(-1===this.maxCoord||e.levelCoord+this.getEntryThickness(t)<=this.maxCoord)&&(-1===this.maxStackCnt||e.stackCnti.end&&this.insertEntry({index:e.index,thickness:e.thickness,span:{start:i.end,end:r.end}},n)}insertEntryAt(e,t){let{entriesByLevel:n,levelCoords:r}=this;-1===t.lateral?(Wr(r,t.level,t.levelCoord),Wr(n,t.level,[e])):Wr(n[t.level],t.lateral,e),this.stackCnts[Ur(e)]=t.stackCnt}findInsertion(e){let{levelCoords:t,entriesByLevel:n,strictOrder:r,stackCnts:i}=this,s=t.length,o=0,a=-1,l=-1,c=null,u=0;for(let f=0;f=o+this.getEntryThickness(e))break;let d,h=n[f],p=Fr(h,e.span.start,Yr),g=p[0]+p[1];for(;(d=h[g])&&d.span.starto&&(o=e,c=d,a=f,l=g),e===o&&(u=Math.max(u,i[Ur(d)]+1)),g+=1}}let d=0;if(c)for(d=a+1;dn(e[i-1]))return[i,0];for(;ro))return[s,1];r=s+1}}return[r,0]}class Vr{constructor(e,t){this.emitter=new Dn}destroy(){}setMirrorIsVisible(e){}setMirrorNeedsRevert(e){}setAutoScrollEnabled(e){}}const Gr={};Boolean;const qr="fc-col-header-cell";function Qr(e){return e.text}class Zr extends bt{render(){let{dateEnv:e,options:t,theme:n,viewApi:i}=this.context,{props:s}=this,{date:o,dateProfile:a}=s,l=br(o,s.todayRange,null,a),c=[qr].concat(Dr(l,n)),u=e.format(o,s.dayHeaderFormat),d=!l.isDisabled&&s.colCnt>1?_r(this.context,o):{},h=Object.assign(Object.assign(Object.assign({date:e.toDate(o),view:i},s.extraRenderProps),{text:u}),l);return(0,r.n)(wt,{elTag:"th",elClasses:c,elAttrs:Object.assign({role:"columnheader",colSpan:s.colSpan,"data-date":l.isDisabled?void 0:ye(o)},s.extraDataAttrs),renderProps:h,generatorName:"dayHeaderContent",customGenerator:t.dayHeaderContent,defaultGenerator:Qr,classNameGenerator:t.dayHeaderClassNames,didMount:t.dayHeaderDidMount,willUnmount:t.dayHeaderWillUnmount},(e=>(0,r.n)("div",{className:"fc-scrollgrid-sync-inner"},!l.isDisabled&&(0,r.n)(e,{elTag:"a",elAttrs:d,elClasses:["fc-col-header-cell-cushion",s.isSticky&&"fc-sticky"]}))))}}const Xr=ze({weekday:"long"});class Kr extends bt{render(){let{props:e}=this,{dateEnv:t,theme:n,viewApi:i,options:s}=this.context,o=re(new Date(2592e5),e.dow),a={dow:e.dow,isDisabled:!1,isFuture:!1,isPast:!1,isToday:!1,isOther:!1},l=t.format(o,e.dayHeaderFormat),c=Object.assign(Object.assign(Object.assign(Object.assign({date:o},a),{view:i}),e.extraRenderProps),{text:l});return(0,r.n)(wt,{elTag:"th",elClasses:[qr,...Dr(a,n),...e.extraClassNames||[]],elAttrs:Object.assign({role:"columnheader",colSpan:e.colSpan},e.extraDataAttrs),renderProps:c,generatorName:"dayHeaderContent",customGenerator:s.dayHeaderContent,defaultGenerator:Qr,classNameGenerator:s.dayHeaderClassNames,didMount:s.dayHeaderDidMount,willUnmount:s.dayHeaderWillUnmount},(n=>(0,r.n)("div",{className:"fc-scrollgrid-sync-inner"},(0,r.n)(n,{elTag:"a",elClasses:["fc-col-header-cell-cushion",e.isSticky&&"fc-sticky"],elAttrs:{"aria-label":t.format(o,Xr)}}))))}}class Jr extends r.uA{constructor(e,t){super(e,t),this.initialNowDate=jt(t.options.now,t.dateEnv),this.initialNowQueriedMs=(new Date).valueOf(),this.state=this.computeTiming().currentState}render(){let{props:e,state:t}=this;return e.children(t.nowDate,t.todayRange)}componentDidMount(){this.setTimeout()}componentDidUpdate(e){e.unit!==this.props.unit&&(this.clearTimeout(),this.setTimeout())}componentWillUnmount(){this.clearTimeout()}computeTiming(){let{props:e,context:t}=this,n=ie(this.initialNowDate,(new Date).valueOf()-this.initialNowQueriedMs),r=t.dateEnv.startOf(n,e.unit),i=t.dateEnv.add(r,V(1,e.unit)),s=i.valueOf()-n.valueOf();return s=Math.min(864e5,s),{currentState:{nowDate:r,todayRange:$r(r)},nextState:{nowDate:i,todayRange:$r(i)},waitMs:s}}setTimeout(){let{nextState:e,waitMs:t}=this.computeTiming();this.timeoutId=setTimeout((()=>{this.setState(e,(()=>{this.setTimeout()}))}),t)}clearTimeout(){this.timeoutId&&clearTimeout(this.timeoutId)}}function $r(e){let t=le(e);return{start:t,end:re(t,1)}}Jr.contextType=mt;class ei extends bt{constructor(){super(...arguments),this.createDayHeaderFormatter=Ee(ti)}render(){let{context:e}=this,{dates:t,dateProfile:n,datesRepDistinctDays:i,renderIntro:s}=this.props,o=this.createDayHeaderFormatter(e.options.dayHeaderFormat,i,t.length);return(0,r.n)(Jr,{unit:"day"},((e,a)=>(0,r.n)("tr",{role:"row"},s&&s("day"),t.map((e=>i?(0,r.n)(Zr,{key:e.toISOString(),date:e,dateProfile:n,todayRange:a,colCnt:t.length,dayHeaderFormat:o}):(0,r.n)(Kr,{key:e.getUTCDay(),dow:e.getUTCDay(),dayHeaderFormat:o}))))))}}function ti(e,t,n){return e||function(e,t){return ze(!e||t>10?{weekday:"short"}:t>1?{weekday:"short",month:"numeric",day:"numeric",omitCommas:!0}:{weekday:"long"})}(t,n)}class ni{constructor(e,t){let n=e.start,{end:r}=e,i=[],s=[],o=-1;for(;n=t.length?t[t.length-1]+1:t[n]}}class ri{constructor(e,t){let n,r,i,{dates:s}=e;if(t){for(r=s[0].getUTCDay(),n=1;n!g[e.instanceId]))}),d=u.defs,h=u.instances,f=zn(d,e.eventUiBases);var p,g;for(let m in l){let r=l[m],o=r.range,p=c[r.defId],g=a[r.defId];if(!ui(p.constraints,o,u,e.businessHours,t))return!1;let{eventOverlap:v}=t.options,y="function"==typeof v?v:null;for(let e in h){let n=h[e];if(Mt(o,n.range)){if(!1===f[n.defId].overlap&&s.isEvent)return!1;if(!1===p.overlap)return!1;if(y&&!y(new On(t,d[n.defId],n),new On(t,g,r)))return!1}}let b=i.eventStore;for(let e of p.allows){let i,s=Object.assign(Object.assign({},n),{range:r.range,allDay:g.allDay}),o=b.defs[g.defId],a=b.instances[m];if(i=o?new On(t,o,a):new On(t,g),!e(Sn(s,t),i))return!1}}return!0}(e,t,n,r))&&!(e.dateSelection&&!function(e,t,n,r){let i=e.eventStore,s=i.defs,o=i.instances,a=e.dateSelection,l=a.range,{selectionConfig:c}=t.getCurrentData();r&&(c=r(c));if(!ui(c.constraints,l,i,e.businessHours,t))return!1;let{selectOverlap:u}=t.options,d="function"==typeof u?u:null;for(let h in o){let e=o[h];if(Mt(l,e.range)){if(!1===c.overlap)return!1;if(d&&!d(new On(t,s[e.defId],e),null))return!1}}for(let h of c.allows){if(!h(Sn(Object.assign(Object.assign({},n),a),t),null))return!1}return!0}(e,t,n,r))}function ui(e,t,n,r,i){for(let s of e)if(!fi(di(s,t,n,r,i),t))return!1;return!0}function di(e,t,n,r,i){return"businessHours"===e?hi(Ft(r,t,i)):"string"==typeof e?hi(sn(n,(t=>t.groupId===e))):"object"==typeof e&&e?hi(Ft(e,t,i)):[]}function hi(e){let{instances:t}=e,n=[];for(let r in t)n.push(t[r].range);return n}function fi(e,t){for(let n of e)if(Nt(n,t))return!0;return!1}const pi=/^(visible|hidden)$/;class gi extends bt{constructor(){super(...arguments),this.handleEl=e=>{this.el=e,Dt(this.props.elRef,e)}}render(){let{props:e}=this,{liquid:t,liquidIsAbsolute:n}=e,i=t&&n,s=["fc-scroller"];return t&&(n?s.push("fc-scroller-liquid-absolute"):s.push("fc-scroller-liquid")),(0,r.n)("div",{ref:this.handleEl,className:s.join(" "),style:{overflowX:e.overflowX,overflowY:e.overflowY,left:i&&-(e.overcomeLeft||0)||"",right:i&&-(e.overcomeRight||0)||"",bottom:i&&-(e.overcomeBottom||0)||"",marginLeft:!i&&-(e.overcomeLeft||0)||"",marginRight:!i&&-(e.overcomeRight||0)||"",marginBottom:!i&&-(e.overcomeBottom||0)||"",maxHeight:e.maxHeight||""}},e.children)}needsXScrolling(){if(pi.test(this.props.overflowX))return!1;let{el:e}=this,t=this.el.getBoundingClientRect().width-this.getYScrollbarWidth(),{children:n}=e;for(let r=0;rt)return!0}return!1}needsYScrolling(){if(pi.test(this.props.overflowY))return!1;let{el:e}=this,t=this.el.getBoundingClientRect().height-this.getXScrollbarWidth(),{children:n}=e;for(let r=0;rt)return!0}return!1}getXScrollbarWidth(){return pi.test(this.props.overflowX)?0:this.el.offsetHeight-this.el.clientHeight}getYScrollbarWidth(){return pi.test(this.props.overflowY)?0:this.el.offsetWidth-this.el.clientWidth}}class mi{constructor(e){this.masterCallback=e,this.currentMap={},this.depths={},this.callbackMap={},this.handleValue=(e,t)=>{let{depths:n,currentMap:r}=this,i=!1,s=!1;null!==e?(i=t in r,r[t]=e,n[t]=(n[t]||0)+1,s=!0):(n[t]-=1,n[t]||(delete r[t],delete this.callbackMap[t],i=!0)),this.masterCallback&&(i&&this.masterCallback(null,String(t)),s&&this.masterCallback(e,String(t)))}}createRef(e){let t=this.callbackMap[e];return t||(t=this.callbackMap[e]=t=>{this.handleValue(t,String(e))}),t}collect(e,t,n){return function(e,t=0,n,r=1){let i=[];null==n&&(n=Object.keys(e).length);for(let s=t;se),bi),this.renderMicroColGroup=Ee(Di),this.scrollerRefs=new mi,this.scrollerElRefs=new mi(this._handleScrollerEl.bind(this)),this.state={shrinkWidth:null,forceYScrollbars:!1,scrollerClientWidths:{},scrollerClientHeights:{}},this.handleSizing=()=>{this.safeSetState(Object.assign({shrinkWidth:this.computeShrinkWidth()},this.computeScrollerDims()))}}render(){let{props:e,state:t,context:n}=this,i=e.sections||[],s=this.processCols(e.cols),o=this.renderMicroColGroup(s,t.shrinkWidth),a=function(e,t){let n=["fc-scrollgrid",t.theme.getClass("table")];return e&&n.push("fc-scrollgrid-liquid"),n}(e.liquid,n);e.collapsibleWidth&&a.push("fc-scrollgrid-collapsible");let l,c=i.length,u=0,d=[],h=[],f=[];for(;u{}},i);return(0,r.n)(i?"th":"td",{ref:n.elRef,role:"presentation"},(0,r.n)("div",{className:"fc-scroller-harness"+(u?" fc-scroller-harness-liquid":"")},(0,r.n)(gi,{ref:this.scrollerRefs.createRef(h),elRef:this.scrollerElRefs.createRef(h),overflowY:d,overflowX:s.liquid?"hidden":"visible",maxHeight:e.maxHeight,liquid:u,liquidIsAbsolute:!0},f)))}_handleScrollerEl(e,t){let n=function(e,t){for(let n of e)if(n.key===t)return n;return null}(this.props.sections,t);n&&Dt(n.chunk.scrollerElRef,e)}componentDidMount(){this.handleSizing(),this.context.addResizeHandler(this.handleSizing)}componentDidUpdate(){this.handleSizing()}componentWillUnmount(){this.context.removeResizeHandler(this.handleSizing)}computeShrinkWidth(){return function(e){for(let t of e)if("shrink"===t.width)return!0;return!1}(this.props.cols)?vi(this.scrollerElRefs.getAll()):0}computeScrollerDims(){let e=Cr(),{scrollerRefs:t,scrollerElRefs:n}=this,r=!1,i={},s={};for(let o in t.currentMap){let e=t.currentMap[o];if(e&&e.needsYScrolling()){r=!0;break}}for(let o of this.props.sections){let t=o.key,a=n.currentMap[t];if(a){let n=a.parentNode;i[t]=Math.floor(n.getBoundingClientRect().width-(r?e.y:0)),s[t]=Math.floor(n.getBoundingClientRect().height)}}return{forceYScrollbars:r,scrollerClientWidths:i,scrollerClientHeights:s}}}wi.addStateEquality({scrollerClientWidths:tt,scrollerClientHeights:tt});class Ci extends bt{constructor(){super(...arguments),this.handleEl=e=>{this.el=e,e&&Pn(e,this.props.seg)}}render(){const{props:e,context:t}=this,{options:n}=t,{seg:i}=e,{eventRange:s}=i,{ui:o}=s,a={event:new On(t,s.def,s.instance),view:t.viewApi,timeText:e.timeText,textColor:o.textColor,backgroundColor:o.backgroundColor,borderColor:o.borderColor,isDraggable:!e.disableDragging&&jn(i,t),isStartResizable:!e.disableResizing&&Ln(i,t),isEndResizable:!e.disableResizing&&Wn(i),isMirror:Boolean(e.isDragging||e.isResizing||e.isDateSelecting),isStart:Boolean(i.isStart),isEnd:Boolean(i.isEnd),isPast:Boolean(e.isPast),isFuture:Boolean(e.isFuture),isToday:Boolean(e.isToday),isSelected:Boolean(e.isSelected),isDragging:Boolean(e.isDragging),isResizing:Boolean(e.isResizing)};return(0,r.n)(wt,Object.assign({},e,{elRef:this.handleEl,elClasses:[...Gn(a),...i.eventRange.ui.classNames,...e.elClasses||[]],renderProps:a,generatorName:"eventContent",customGenerator:n.eventContent,defaultGenerator:e.defaultGenerator,classNameGenerator:n.eventClassNames,didMount:n.eventDidMount,willUnmount:n.eventWillUnmount}))}componentDidUpdate(e){this.el&&this.props.seg!==e.seg&&Pn(this.el,this.props.seg)}}class xi extends bt{render(){let{props:e,context:t}=this,{options:n}=t,{seg:i}=e,{ui:s}=i.eventRange,o=Fn(i,n.eventTimeFormat||e.defaultTimeFormat,t,e.defaultDisplayEventTime,e.defaultDisplayEventEnd);return(0,r.n)(Ci,Object.assign({},e,{elTag:"a",elStyle:{borderColor:s.borderColor,backgroundColor:s.backgroundColor},elAttrs:Qn(i,t),defaultGenerator:Ri,timeText:o}),((e,t)=>(0,r.n)(r.FK,null,(0,r.n)(e,{elTag:"div",elClasses:["fc-event-main"],elStyle:{color:t.textColor}}),Boolean(t.isStartResizable)&&(0,r.n)("div",{className:"fc-event-resizer fc-event-resizer-start"}),Boolean(t.isEndResizable)&&(0,r.n)("div",{className:"fc-event-resizer fc-event-resizer-end"}))))}}function Ri(e){return(0,r.n)("div",{className:"fc-event-main-frame"},e.timeText&&(0,r.n)("div",{className:"fc-event-time"},e.timeText),(0,r.n)("div",{className:"fc-event-title-container"},(0,r.n)("div",{className:"fc-event-title fc-sticky"},e.event.title||(0,r.n)(r.FK,null,"\xa0"))))}const Oi=e=>(0,r.n)(mt.Consumer,null,(t=>{let{options:n}=t,i={isAxis:e.isAxis,date:t.dateEnv.toDate(e.date),view:t.viewApi};return(0,r.n)(wt,Object.assign({},e,{elTag:e.elTag||"div",renderProps:i,generatorName:"nowIndicatorContent",customGenerator:n.nowIndicatorContent,classNameGenerator:n.nowIndicatorClassNames,didMount:n.nowIndicatorDidMount,willUnmount:n.nowIndicatorWillUnmount}))})),ki=ze({day:"numeric"});class Ii extends bt{constructor(){super(...arguments),this.refineRenderProps=_e(Ni)}render(){let{props:e,context:t}=this,{options:n}=t,i=this.refineRenderProps({date:e.date,dateProfile:e.dateProfile,todayRange:e.todayRange,isMonthStart:e.isMonthStart||!1,showDayNumber:e.showDayNumber,extraRenderProps:e.extraRenderProps,viewApi:t.viewApi,dateEnv:t.dateEnv,monthStartFormat:n.monthStartFormat});return(0,r.n)(wt,Object.assign({},e,{elClasses:[...Dr(i,t.theme),...e.elClasses||[]],elAttrs:Object.assign(Object.assign({},e.elAttrs),i.isDisabled?{}:{"data-date":ye(e.date)}),renderProps:i,generatorName:"dayCellContent",customGenerator:n.dayCellContent,defaultGenerator:e.defaultGenerator,classNameGenerator:i.isDisabled?void 0:n.dayCellClassNames,didMount:n.dayCellDidMount,willUnmount:n.dayCellWillUnmount}))}}function Mi(e){return Boolean(e.dayCellContent||Et("dayCellContent",e))}function Ni(e){let{date:t,dateEnv:n,dateProfile:r,isMonthStart:i}=e,s=br(t,e.todayRange,null,r),o=e.showDayNumber?n.format(t,i?e.monthStartFormat:ki):"";return Object.assign(Object.assign(Object.assign({date:n.toDate(t),view:e.viewApi},s),{isMonthStart:i,dayNumberText:o}),e.extraRenderProps)}class Pi extends bt{render(){let{props:e}=this,{seg:t}=e;return(0,r.n)(Ci,{elTag:"div",elClasses:["fc-bg-event"],elStyle:{backgroundColor:t.eventRange.ui.backgroundColor},defaultGenerator:Bi,seg:t,timeText:"",isDragging:!1,isResizing:!1,isDateSelecting:!1,isSelected:!1,isPast:e.isPast,isFuture:e.isFuture,isToday:e.isToday,disableDragging:!0,disableResizing:!0})}}function Bi(e){let{title:t}=e.event;return t&&(0,r.n)("div",{className:"fc-event-title"},e.event.title)}function zi(e){return(0,r.n)("div",{className:`fc-${e}`})}const Hi=e=>(0,r.n)(mt.Consumer,null,(t=>{let{dateEnv:n,options:i}=t,{date:s}=e,o=i.weekNumberFormat||e.defaultFormat,a={num:n.computeWeekNumber(s),text:n.format(s,o),date:s};return(0,r.n)(wt,Object.assign({},e,{renderProps:a,generatorName:"weekNumberContent",customGenerator:i.weekNumberContent,defaultGenerator:Yi,classNameGenerator:i.weekNumberClassNames,didMount:i.weekNumberDidMount,willUnmount:i.weekNumberWillUnmount}))}));function Yi(e){return e.text}class Ui extends bt{constructor(){super(...arguments),this.state={titleId:A()},this.handleRootEl=e=>{this.rootEl=e,this.props.elRef&&Dt(this.props.elRef,e)},this.handleDocumentMouseDown=e=>{const t=b(e);this.rootEl.contains(t)||this.handleCloseClick()},this.handleDocumentKeyDown=e=>{"Escape"===e.key&&this.handleCloseClick()},this.handleCloseClick=()=>{let{onClose:e}=this.props;e&&e()}}render(){let{theme:e,options:t}=this.context,{props:n,state:s}=this,o=["fc-popover",e.getClass("popover")].concat(n.extraClassNames||[]);return(0,i.d5)((0,r.n)("div",Object.assign({},n.extraAttrs,{id:n.id,className:o.join(" "),"aria-labelledby":s.titleId,ref:this.handleRootEl}),(0,r.n)("div",{className:"fc-popover-header "+e.getClass("popoverHeader")},(0,r.n)("span",{className:"fc-popover-title",id:s.titleId},n.title),(0,r.n)("span",{className:"fc-popover-close "+e.getIconClass("close"),title:t.closeHint,onClick:this.handleCloseClick})),(0,r.n)("div",{className:"fc-popover-body "+e.getClass("popoverContent")},n.children)),n.parentEl)}componentDidMount(){document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleDocumentKeyDown),this.updateSize()}componentWillUnmount(){document.removeEventListener("mousedown",this.handleDocumentMouseDown),document.removeEventListener("keydown",this.handleDocumentKeyDown)}updateSize(){let{isRtl:e}=this.context,{alignmentEl:t,alignGridTop:n}=this.props,{rootEl:r}=this,i=function(e){let t=kr(e),n=e.getBoundingClientRect();for(let r of t){let e=hr(n,r.getBoundingClientRect());if(!e)return null;n=e}return n}(t);if(i){let s=r.getBoundingClientRect(),o=n?p(t,".fc-scrollgrid").getBoundingClientRect().top:i.top,a=e?i.right-s.width:i.left;o=Math.max(o,10),a=Math.min(a,document.documentElement.clientWidth-10-s.width),a=Math.max(a,10);let l=r.offsetParent.getBoundingClientRect();v(r,{top:o-l.top,left:a-l.left})}}}class ji extends zr{constructor(){super(...arguments),this.handleRootEl=e=>{this.rootEl=e,e?this.context.registerInteractiveComponent(this,{el:e,useEventCenter:!1}):this.context.unregisterInteractiveComponent(this)}}render(){let{options:e,dateEnv:t}=this.context,{props:n}=this,{startDate:i,todayRange:s,dateProfile:o}=n,a=t.format(i,e.dayPopoverFormat);return(0,r.n)(Ii,{elRef:this.handleRootEl,date:i,dateProfile:o,todayRange:s},((t,i,s)=>(0,r.n)(Ui,{elRef:s.ref,id:n.id,title:a,extraClassNames:["fc-more-popover"].concat(s.className||[]),extraAttrs:s,parentEl:n.parentEl,alignmentEl:n.alignmentEl,alignGridTop:n.alignGridTop,onClose:n.onClose},Mi(e)&&(0,r.n)(t,{elTag:"div",elClasses:["fc-more-popover-misc"]}),n.children)))}queryHit(e,t,n,r){let{rootEl:i,props:s}=this;return e>=0&&e=0&&t{this.linkEl=e,this.props.elRef&&Dt(this.props.elRef,e)},this.handleClick=e=>{let{props:t,context:n}=this,{moreLinkClick:r}=n.options,i=Fi(t).start;function s(e){let{def:t,instance:r,range:i}=e.eventRange;return{event:new On(n,t,r),start:n.dateEnv.toDate(i.start),end:n.dateEnv.toDate(i.end),isStart:e.isStart,isEnd:e.isEnd}}"function"==typeof r&&(r=r({date:i,allDay:Boolean(t.allDayDate),allSegs:t.allSegs.map(s),hiddenSegs:t.hiddenSegs.map(s),jsEvent:e,view:n.viewApi})),r&&"popover"!==r?"string"==typeof r&&n.calendarApi.zoomTo(i,r):this.setState({isPopoverOpen:!0})},this.handlePopoverClose=()=>{this.setState({isPopoverOpen:!1})}}render(){let{props:e,state:t}=this;return(0,r.n)(mt.Consumer,null,(n=>{let{viewApi:i,options:s,calendarApi:o}=n,{moreLinkText:a}=s,{moreCnt:l}=e,c=Fi(e),u="function"==typeof a?a.call(o,l):`+${l} ${a}`,d=Y(s.moreLinkHint,[l],u),h={num:l,shortText:`+${l}`,text:u,view:i};return(0,r.n)(r.FK,null,Boolean(e.moreCnt)&&(0,r.n)(wt,{elTag:e.elTag||"a",elRef:this.handleLinkEl,elClasses:[...e.elClasses||[],"fc-more-link"],elStyle:e.elStyle,elAttrs:Object.assign(Object.assign(Object.assign({},e.elAttrs),C(this.handleClick)),{title:d,"aria-expanded":t.isPopoverOpen,"aria-controls":t.isPopoverOpen?t.popoverId:""}),renderProps:h,generatorName:"moreLinkContent",customGenerator:s.moreLinkContent,defaultGenerator:e.defaultGenerator||Wi,classNameGenerator:s.moreLinkClassNames,didMount:s.moreLinkDidMount,willUnmount:s.moreLinkWillUnmount},e.children),t.isPopoverOpen&&(0,r.n)(ji,{id:t.popoverId,startDate:c.start,endDate:c.end,dateProfile:e.dateProfile,todayRange:e.todayRange,extraDateSpan:e.extraDateSpan,parentEl:this.parentEl,alignmentEl:e.alignmentElRef?e.alignmentElRef.current:this.linkEl,alignGridTop:e.alignGridTop,forceTimed:e.forceTimed,onClose:this.handlePopoverClose},e.popoverContent()))}))}componentDidMount(){this.updateParentEl()}componentDidUpdate(){this.updateParentEl()}updateParentEl(){this.linkEl&&(this.parentEl=p(this.linkEl,".fc-view-harness"))}}function Wi(e){return e.text}function Fi(e){if(e.allDayDate)return{start:e.allDayDate,end:re(e.allDayDate,1)};let{hiddenSegs:t}=e;return{start:Vi(t),end:(n=t,n.reduce(qi).eventRange.range.end)};var n}function Vi(e){return e.reduce(Gi).eventRange.range.start}function Gi(e,t){return e.eventRange.range.startt.eventRange.range.end?e:t}class Qi{constructor(){this.handlers=[]}set(e){this.currentValue=e;for(let t of this.handlers)t(e)}subscribe(e){this.handlers.push(e),void 0!==this.currentValue&&e(this.currentValue)}}class Zi extends Qi{constructor(){super(...arguments),this.map=new Map}handle(e){const{map:t}=this;let n=!1;e.isActive?(t.set(e.id,e),n=!0):t.has(e.id)&&(t.delete(e.id),n=!0),n&&this.set(t)}}},97950:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var r=n(67363),i=n(78817),s=(0,r.i1)({name:"@fullcalendar/daygrid",initialView:"dayGridMonth",views:{dayGrid:{component:i.eu,dateProfileGeneratorClass:i.LH},dayGridDay:{type:"dayGrid",duration:{days:1}},dayGridWeek:{type:"dayGrid",duration:{weeks:1}},dayGridMonth:{type:"dayGrid",duration:{months:1},fixedWeekCount:!0},dayGridYear:{type:"dayGrid",duration:{years:1}}}})},78817:(e,t,n)=>{"use strict";n.d(t,{LH:()=>I,eu:()=>O,t7:()=>R});var r=n(29174),i=n(50172);class s extends r.be{constructor(){super(...arguments),this.headerElRef=(0,i._3)()}renderSimpleLayout(e,t){let{props:n,context:s}=this,o=[],a=(0,r.cc)(s.options);return e&&o.push({type:"header",key:"header",isSticky:a,chunk:{elRef:this.headerElRef,tableClassName:"fc-col-header",rowContent:e}}),o.push({type:"body",key:"body",liquid:!0,chunk:{content:t}}),(0,i.n)(r.ct,{elClasses:["fc-daygrid"],viewSpec:s.viewSpec},(0,i.n)(r.b$,{liquid:!n.isHeightAuto&&!n.forPrint,collapsibleWidth:n.forPrint,cols:[],sections:o}))}renderHScrollLayout(e,t,n,s){let o=this.context.pluginHooks.scrollGridImpl;if(!o)throw new Error("No ScrollGrid implementation");let{props:a,context:l}=this,c=!a.forPrint&&(0,r.cc)(l.options),u=!a.forPrint&&(0,r.cb)(l.options),d=[];return e&&d.push({type:"header",key:"header",isSticky:c,chunks:[{key:"main",elRef:this.headerElRef,tableClassName:"fc-col-header",rowContent:e}]}),d.push({type:"body",key:"body",liquid:!0,chunks:[{key:"main",content:t}]}),u&&d.push({type:"footer",key:"footer",isSticky:!0,chunks:[{key:"main",content:r.ca}]}),(0,i.n)(r.ct,{elClasses:["fc-daygrid"],viewSpec:l.viewSpec},(0,i.n)(o,{liquid:!a.isHeightAuto&&!a.forPrint,forPrint:a.forPrint,collapsibleWidth:a.forPrint,colGroups:[{cols:[{span:n,minWidth:s}]}],sections:d}))}}function o(e,t){let n=[];for(let r=0;r{let n=(e.eventDrag?e.eventDrag.affectedInstances:null)||(e.eventResize?e.eventResize.affectedInstances:null)||{};return(0,i.n)(i.FK,null,t.map((t=>{let s=t.eventRange.instance.instanceId;return(0,i.n)("div",{className:"fc-daygrid-event-harness",key:s,style:{visibility:n[s]?"hidden":""}},u(t)?(0,i.n)(h,Object.assign({seg:t,isDragging:!1,isSelected:s===e.eventSelection,defaultDisplayEventEnd:!1},(0,r.bS)(t,e.todayRange))):(0,i.n)(d,Object.assign({seg:t,isDragging:!1,isResizing:!1,isDateSelecting:!1,isSelected:s===e.eventSelection,defaultDisplayEventEnd:!1},(0,r.bS)(t,e.todayRange))))})))}})}}function g(e){let t=[],n=[];for(let r of e)t.push(r.seg),r.isVisible||n.push(r.seg);return{allSegs:t,invisibleSegs:n}}const m=(0,r.x)({week:"narrow"});class v extends r.be{constructor(){super(...arguments),this.rootElRef=(0,i._3)(),this.state={dayNumberId:(0,r.a5)()},this.handleRootEl=e=>{(0,r.Y)(this.rootElRef,e),(0,r.Y)(this.props.elRef,e)}}render(){let{context:e,props:t,state:n,rootElRef:s}=this,{options:o,dateEnv:a}=e,{date:l,dateProfile:c}=t;const u=t.showDayNumber&&function(e,t,n){const{start:i,end:s}=t,o=(0,r.bg)(s,-1),a=n.getYear(i),l=n.getMonth(i),c=n.getYear(o),u=n.getMonth(o);return!(a===c&&l===u)&&Boolean(e.valueOf()===i.valueOf()||1===n.getDay(e)&&e.valueOf()(0,i.n)("div",{ref:t.innerElRef,className:"fc-daygrid-day-frame fc-scrollgrid-sync-inner",style:{minHeight:t.minHeight}},t.showWeekNumber&&(0,i.n)(r.cq,{elTag:"a",elClasses:["fc-daygrid-week-number"],elAttrs:(0,r.b0)(e,l,"week"),date:l,defaultFormat:m}),!c.isDisabled&&(t.showDayNumber||(0,r.cm)(o)||t.forceDayTop)?(0,i.n)("div",{className:"fc-daygrid-day-top"},(0,i.n)(a,{elTag:"a",elClasses:["fc-daygrid-day-number",u&&"fc-daygrid-month-start"],elAttrs:Object.assign(Object.assign({},(0,r.b0)(e,l)),{id:n.dayNumberId})})):t.showDayNumber?(0,i.n)("div",{className:"fc-daygrid-day-top",style:{visibility:"hidden"}},(0,i.n)("a",{className:"fc-daygrid-day-number"},"\xa0")):void 0,(0,i.n)("div",{className:"fc-daygrid-day-events",ref:t.fgContentElRef},t.fgContent,(0,i.n)("div",{className:"fc-daygrid-day-bottom",style:{marginTop:t.moreMarginTop}},(0,i.n)(p,{allDayDate:l,singlePlacements:t.singlePlacements,moreCnt:t.moreCnt,alignmentElRef:s,alignGridTop:!t.showDayNumber,extraDateSpan:t.extraDateSpan,dateProfile:t.dateProfile,eventSelection:t.eventSelection,eventDrag:t.eventDrag,eventResize:t.eventResize,todayRange:t.todayRange}))),(0,i.n)("div",{className:"fc-daygrid-day-bg"},t.bgContent))))}}function y(e){return e.dayNumberText||(0,i.n)(i.FK,null,"\xa0")}function b(e){return e.eventRange.instance.instanceId+":"+e.firstCol}function D(e){return b(e)+":"+e.lastCol}function A(e,t,n,r,i,s,o){let a=new _((t=>{let n=e[t.index].eventRange.instance.instanceId+":"+t.span.start+":"+(t.span.end-1);return i[n]||1}));a.allowReslicing=!0,a.strictOrder=r,!0===t||!0===n?(a.maxCoord=s,a.hiddenConsumes=!0):"number"==typeof t?a.maxStackCnt=t:"number"==typeof n&&(a.maxStackCnt=n,a.hiddenConsumes=!0);let l=[],c=[];for(let v=0;v1,s=r.span.start===a;u+=r.levelCoord-c,c=r.levelCoord+r.thickness,i?(u+=r.thickness,s&&d.push({seg:E(e,r.span.start,r.span.end,n),isVisible:!0,isAbsolute:!0,absoluteTop:r.levelCoord,marginTop:0})):s&&(d.push({seg:E(e,r.span.start,r.span.end,n),isVisible:!0,isAbsolute:!1,absoluteTop:r.levelCoord,marginTop:u}),u=0)}i.push(l),s.push(d),o.push(u)}return{singleColPlacements:i,multiColPlacements:s,leftoverMargins:o}}(d,e,o),g=[],m=[];for(let v of c){f[v.firstCol].push({seg:v,isVisible:!1,isAbsolute:!0,absoluteTop:0,marginTop:0});for(let e=v.firstCol;e<=v.lastCol;e+=1)h[e].push({seg:E(v,e,e+1,o),isVisible:!1,isAbsolute:!1,absoluteTop:0,marginTop:0})}for(let v=0;v!this.forceHidden[(0,r.bB)(e)];for(let r=0;r{e&&this.updateSizing(!0)}}render(){let{props:e,state:t,context:n}=this,{options:s}=n,o=e.cells.length,l=a(e.businessHourSegs,o),c=a(e.bgEventSegs,o),u=a(this.getHighlightSegs(),o),d=a(this.getMirrorSegs(),o),{singleColPlacements:h,multiColPlacements:f,moreCnts:p,moreMarginTops:g}=A((0,r.bR)(e.fgEventSegs,s.eventOrder),e.dayMaxEvents,e.dayMaxEventRows,s.eventOrderStrict,t.segHeights,t.maxContentHeight,e.cells),m=e.eventDrag&&e.eventDrag.affectedInstances||e.eventResize&&e.eventResize.affectedInstances||{};return(0,i.n)("tr",{ref:this.rootElRef,role:"row"},e.renderIntro&&e.renderIntro(),e.cells.map(((t,n)=>{let r=this.renderFgSegs(n,e.forPrint?h[n]:f[n],e.todayRange,m),s=this.renderFgSegs(n,function(e,t){if(!e.length)return[];let n=function(e){let t={};for(let n of e)for(let e of n)t[e.seg.eventRange.instance.instanceId]=e.absoluteTop;return t}(t);return e.map((e=>({seg:e,isVisible:!0,isAbsolute:!0,absoluteTop:n[e.eventRange.instance.instanceId],marginTop:0})))}(d[n],f),e.todayRange,{},Boolean(e.eventDrag),Boolean(e.eventResize),!1);return(0,i.n)(v,{key:t.key,elRef:this.cellElRefs.createRef(t.key),innerElRef:this.frameElRefs.createRef(t.key),dateProfile:e.dateProfile,date:t.date,showDayNumber:e.showDayNumbers,showWeekNumber:e.showWeekNumbers&&0===n,forceDayTop:e.showWeekNumbers,todayRange:e.todayRange,eventSelection:e.eventSelection,eventDrag:e.eventDrag,eventResize:e.eventResize,extraRenderProps:t.extraRenderProps,extraDataAttrs:t.extraDataAttrs,extraClassNames:t.extraClassNames,extraDateSpan:t.extraDateSpan,moreCnt:p[n],moreMarginTop:g[n],singlePlacements:h[n],fgContentElRef:this.fgElRefs.createRef(t.key),fgContent:(0,i.n)(i.FK,null,(0,i.n)(i.FK,null,r),(0,i.n)(i.FK,null,s)),bgContent:(0,i.n)(i.FK,null,this.renderFillSegs(u[n],"highlight"),this.renderFillSegs(l[n],"non-business"),this.renderFillSegs(c[n],"bg-event")),minHeight:e.cellMinHeight})})))}componentDidMount(){this.updateSizing(!0),this.context.addResizeHandler(this.handleResize)}componentDidUpdate(e,t){let n=this.props;this.updateSizing(!(0,r.E)(e,n))}componentWillUnmount(){this.context.removeResizeHandler(this.handleResize)}getHighlightSegs(){let{props:e}=this;return e.eventDrag&&e.eventDrag.segs.length?e.eventDrag.segs:e.eventResize&&e.eventResize.segs.length?e.eventResize.segs:e.dateSelectionSegs}getMirrorSegs(){let{props:e}=this;return e.eventResize&&e.eventResize.segs.length?e.eventResize.segs:[]}renderFgSegs(e,t,n,s,o,a,l){let{context:c}=this,{eventSelection:f}=this.props,{framePositions:p}=this.state,g=1===this.props.cells.length,m=o||a||l,v=[];if(p)for(let y of t){let{seg:e}=y,{instanceId:t}=e.eventRange.instance,A=y.isVisible&&!s[t],E=y.isAbsolute,_="",S="";E&&(c.isRtl?(S=0,_=p.lefts[e.lastCol]-p.lefts[e.firstCol]):(_=0,S=p.rights[e.firstCol]-p.rights[e.lastCol])),v.push((0,i.n)("div",{className:"fc-daygrid-event-harness"+(E?" fc-daygrid-event-harness-abs":""),key:b(e),ref:m?null:this.segHarnessRefs.createRef(D(e)),style:{visibility:A?"":"hidden",marginTop:E?"":y.marginTop,top:E?y.absoluteTop:"",left:_,right:S}},u(e)?(0,i.n)(h,Object.assign({seg:e,isDragging:o,isSelected:t===f,defaultDisplayEventEnd:g},(0,r.bS)(e,n))):(0,i.n)(d,Object.assign({seg:e,isDragging:o,isResizing:a,isDateSelecting:l,isSelected:t===f,defaultDisplayEventEnd:g},(0,r.bS)(e,n)))))}return v}renderFillSegs(e,t){let{isRtl:n}=this.context,{todayRange:s}=this.props,{framePositions:o}=this.state,a=[];if(o)for(let l of e){let e=n?{right:0,left:o.lefts[l.lastCol]-o.lefts[l.firstCol]}:{left:0,right:o.rights[l.firstCol]-o.rights[l.lastCol]};a.push((0,i.n)("div",{key:(0,r.bT)(l.eventRange),className:"fc-daygrid-bg-harness",style:e},"bg-event"===t?(0,i.n)(r.cp,Object.assign({seg:l},(0,r.bS)(l,s))):(0,r.co)(t)))}return(0,i.n)(i.FK,{},...a)}updateSizing(e){let{props:t,state:n,frameElRefs:i}=this;if(!t.forPrint&&null!==t.clientWidth){if(e){let e=t.cells.map((e=>i.currentMap[e.key]));if(e.length){let t=this.rootElRef.current,i=new r.ba(t,e,!0,!1);n.framePositions&&n.framePositions.similarTo(i)||this.setState({framePositions:new r.ba(t,e,!0,!1)})}}const s=this.state.segHeights,o=this.querySegHeights(),a=!0===t.dayMaxEvents||!0===t.dayMaxEventRows;this.safeSetState({segHeights:Object.assign(Object.assign({},s),o),maxContentHeight:a?this.computeMaxContentHeight():null})}}querySegHeights(){let e=this.segHarnessRefs.currentMap,t={};for(let n in e){let r=Math.round(e[n].getBoundingClientRect().height);t[n]=Math.max(t[n]||0,r)}return t}computeMaxContentHeight(){let e=this.props.cells[0].key,t=this.cellElRefs.currentMap[e],n=this.fgElRefs.currentMap[e];return t.getBoundingClientRect().bottom-n.getBoundingClientRect().top}getCellEls(){let e=this.cellElRefs.currentMap;return this.props.cells.map((t=>e[t.key]))}}S.addStateEquality({segHeights:r.E});class T extends r.be{constructor(){super(...arguments),this.splitBusinessHourSegs=(0,r.z)(o),this.splitBgEventSegs=(0,r.z)(o),this.splitFgEventSegs=(0,r.z)(o),this.splitDateSelectionSegs=(0,r.z)(o),this.splitEventDrag=(0,r.z)(l),this.splitEventResize=(0,r.z)(l),this.rowRefs=new r.cf}render(){let{props:e,context:t}=this,n=e.cells.length,s=this.splitBusinessHourSegs(e.businessHourSegs,n),o=this.splitBgEventSegs(e.bgEventSegs,n),a=this.splitFgEventSegs(e.fgEventSegs,n),l=this.splitDateSelectionSegs(e.dateSelectionSegs,n),c=this.splitEventDrag(e.eventDrag,n),u=this.splitEventResize(e.eventResize,n),d=n>=7&&e.clientWidth?e.clientWidth/t.options.aspectRatio/6:null;return(0,i.n)(r.ch,{unit:"day"},((t,r)=>(0,i.n)(i.FK,null,e.cells.map(((t,h)=>(0,i.n)(S,{ref:this.rowRefs.createRef(h),key:t.length?t[0].date.toISOString():h,showDayNumbers:n>1,showWeekNumbers:e.showWeekNumbers,todayRange:r,dateProfile:e.dateProfile,cells:t,renderIntro:e.renderRowIntro,businessHourSegs:s[h],eventSelection:e.eventSelection,bgEventSegs:o[h].filter(w),fgEventSegs:a[h],dateSelectionSegs:l[h],eventDrag:c[h],eventResize:u[h],dayMaxEvents:e.dayMaxEvents,dayMaxEventRows:e.dayMaxEventRows,clientWidth:e.clientWidth,clientHeight:e.clientHeight,cellMinHeight:d,forPrint:e.forPrint}))))))}componentDidMount(){this.registerInteractiveComponent()}componentDidUpdate(){this.registerInteractiveComponent()}registerInteractiveComponent(){if(!this.rootEl){const e=this.rowRefs.currentMap[0].getCellEls()[0],t=e?e.closest(".fc-daygrid-body"):null;t&&(this.rootEl=t,this.context.registerInteractiveComponent(this,{el:t,isHitComboAllowed:this.props.isHitComboAllowed}))}}componentWillUnmount(){this.rootEl&&(this.context.unregisterInteractiveComponent(this),this.rootEl=null)}prepareHits(){this.rowPositions=new r.ba(this.rootEl,this.rowRefs.collect().map((e=>e.getCellEls()[0])),!1,!0),this.colPositions=new r.ba(this.rootEl,this.rowRefs.currentMap[0].getCellEls(),!0,!1)}queryHit(e,t){let{colPositions:n,rowPositions:r}=this,i=n.leftToIndex(e),s=r.topToIndex(t);if(null!=s&&null!=i){let e=this.props.cells[s][i];return{dateProfile:this.props.dateProfile,dateSpan:Object.assign({range:this.getCellRange(s,i),allDay:!0},e.extraDateSpan),dayEl:this.getCellEl(s,i),rect:{left:n.lefts[i],right:n.rights[i],top:r.tops[s],bottom:r.bottoms[s]},layer:0}}return null}getCellEl(e,t){return this.rowRefs.currentMap[e].getCellEls()[t]}getCellRange(e,t){let n=this.props.cells[e][t].date;return{start:n,end:(0,r.t)(n,1)}}}function w(e){return e.eventRange.def.allDay}class C extends r.be{constructor(){super(...arguments),this.elRef=(0,i._3)(),this.needsScrollReset=!1}render(){let{props:e}=this,{dayMaxEventRows:t,dayMaxEvents:n,expandRows:r}=e,s=!0===n||!0===t;s&&!r&&(s=!1,t=null,n=null);let o=["fc-daygrid-body",s?"fc-daygrid-body-balanced":"fc-daygrid-body-unbalanced",r?"":"fc-daygrid-body-natural"];return(0,i.n)("div",{ref:this.elRef,className:o.join(" "),style:{width:e.clientWidth,minWidth:e.tableMinWidth}},(0,i.n)("table",{role:"presentation",className:"fc-scrollgrid-sync-table",style:{width:e.clientWidth,minWidth:e.tableMinWidth,height:r?e.clientHeight:""}},e.colGroupNode,(0,i.n)("tbody",{role:"presentation"},(0,i.n)(T,{dateProfile:e.dateProfile,cells:e.cells,renderRowIntro:e.renderRowIntro,showWeekNumbers:e.showWeekNumbers,clientWidth:e.clientWidth,clientHeight:e.clientHeight,businessHourSegs:e.businessHourSegs,bgEventSegs:e.bgEventSegs,fgEventSegs:e.fgEventSegs,dateSelectionSegs:e.dateSelectionSegs,eventSelection:e.eventSelection,eventDrag:e.eventDrag,eventResize:e.eventResize,dayMaxEvents:n,dayMaxEventRows:t,forPrint:e.forPrint,isHitComboAllowed:e.isHitComboAllowed}))))}componentDidMount(){this.requestScrollReset()}componentDidUpdate(e){e.dateProfile!==this.props.dateProfile?this.requestScrollReset():this.flushScrollReset()}requestScrollReset(){this.needsScrollReset=!0,this.flushScrollReset()}flushScrollReset(){if(this.needsScrollReset&&this.props.clientWidth){const e=function(e,t){let n;t.currentRangeUnit.match(/year|month/)&&(n=e.querySelector(`[data-date="${(0,r.bx)(t.currentDate)}-01"]`));n||(n=e.querySelector(`[data-date="${(0,r.bv)(t.currentDate)}"]`));return n}(this.elRef.current,this.props.dateProfile);if(e){const t=e.closest(".fc-daygrid-body"),n=t.closest(".fc-scroller"),r=e.getBoundingClientRect().top-t.getBoundingClientRect().top;n.scrollTop=r?r+1:0}this.needsScrollReset=!1}}}class x extends r.bW{constructor(){super(...arguments),this.forceDayIfListItem=!0}sliceRange(e,t){return t.sliceRange(e)}}class R extends r.be{constructor(){super(...arguments),this.slicer=new x,this.tableRef=(0,i._3)()}render(){let{props:e,context:t}=this;return(0,i.n)(C,Object.assign({ref:this.tableRef},this.slicer.sliceProps(e,e.dateProfile,e.nextDayThreshold,t,e.dayTableModel),{dateProfile:e.dateProfile,cells:e.dayTableModel.cells,colGroupNode:e.colGroupNode,tableMinWidth:e.tableMinWidth,renderRowIntro:e.renderRowIntro,dayMaxEvents:e.dayMaxEvents,dayMaxEventRows:e.dayMaxEventRows,showWeekNumbers:e.showWeekNumbers,expandRows:e.expandRows,headerAlignElRef:e.headerAlignElRef,clientWidth:e.clientWidth,clientHeight:e.clientHeight,forPrint:e.forPrint}))}}class O extends s{constructor(){super(...arguments),this.buildDayTableModel=(0,r.z)(k),this.headerRef=(0,i._3)(),this.tableRef=(0,i._3)()}render(){let{options:e,dateProfileGenerator:t}=this.context,{props:n}=this,s=this.buildDayTableModel(n.dateProfile,t),o=e.dayHeaders&&(0,i.n)(r.bK,{ref:this.headerRef,dateProfile:n.dateProfile,dates:s.headerDates,datesRepDistinctDays:1===s.rowCnt}),a=t=>(0,i.n)(R,{ref:this.tableRef,dateProfile:n.dateProfile,dayTableModel:s,businessHours:n.businessHours,dateSelection:n.dateSelection,eventStore:n.eventStore,eventUiBases:n.eventUiBases,eventSelection:n.eventSelection,eventDrag:n.eventDrag,eventResize:n.eventResize,nextDayThreshold:e.nextDayThreshold,colGroupNode:t.tableColGroupNode,tableMinWidth:t.tableMinWidth,dayMaxEvents:e.dayMaxEvents,dayMaxEventRows:e.dayMaxEventRows,showWeekNumbers:e.weekNumbers,expandRows:!n.isHeightAuto,headerAlignElRef:this.headerElRef,clientWidth:t.clientWidth,clientHeight:t.clientHeight,forPrint:n.forPrint});return e.dayMinWidth?this.renderHScrollLayout(o,a,s.colCnt,e.dayMinWidth):this.renderSimpleLayout(o,a)}}function k(e,t){let n=new r.bO(e.renderRange,t);return new r.bV(n,/year|month|week/.test(e.currentRangeUnit))}class I extends r.U{buildRenderRange(e,t,n){let i=super.buildRenderRange(e,t,n),{props:s}=this;return function(e){let t,{dateEnv:n,currentRange:i}=e,{start:s,end:o}=i;e.snapToWeek&&(s=n.startOfWeek(s),t=n.startOfWeek(o),t.valueOf()!==o.valueOf()&&(o=(0,r.bh)(t,1)));if(e.fixedWeekCount){let e=n.startOfWeek(n.startOfMonth((0,r.t)(i.end,-1))),t=Math.ceil((0,r.bi)(e,o));o=(0,r.bh)(o,6-t)}return{start:s,end:o}}({currentRange:i,snapToWeek:/^(year|month)$/.test(t),fixedWeekCount:s.fixedWeekCount,dateEnv:s.dateEnv})}}(0,r.cw)(':root{--fc-daygrid-event-dot-width:8px}.fc-daygrid-day-events:after,.fc-daygrid-day-events:before,.fc-daygrid-day-frame:after,.fc-daygrid-day-frame:before,.fc-daygrid-event-harness:after,.fc-daygrid-event-harness:before{clear:both;content:"";display:table}.fc .fc-daygrid-body{position:relative;z-index:1}.fc .fc-daygrid-day.fc-day-today{background-color:var(--fc-today-bg-color)}.fc .fc-daygrid-day-frame{min-height:100%;position:relative}.fc .fc-daygrid-day-top{display:flex;flex-direction:row-reverse}.fc .fc-day-other .fc-daygrid-day-top{opacity:.3}.fc .fc-daygrid-day-number{padding:4px;position:relative;z-index:4}.fc .fc-daygrid-month-start{font-size:1.1em;font-weight:700}.fc .fc-daygrid-day-events{margin-top:1px}.fc .fc-daygrid-body-balanced .fc-daygrid-day-events{left:0;position:absolute;right:0}.fc .fc-daygrid-body-unbalanced .fc-daygrid-day-events{min-height:2em;position:relative}.fc .fc-daygrid-body-natural .fc-daygrid-day-events{margin-bottom:1em}.fc .fc-daygrid-event-harness{position:relative}.fc .fc-daygrid-event-harness-abs{left:0;position:absolute;right:0;top:0}.fc .fc-daygrid-bg-harness{bottom:0;position:absolute;top:0}.fc .fc-daygrid-day-bg .fc-non-business{z-index:1}.fc .fc-daygrid-day-bg .fc-bg-event{z-index:2}.fc .fc-daygrid-day-bg .fc-highlight{z-index:3}.fc .fc-daygrid-event{margin-top:1px;z-index:6}.fc .fc-daygrid-event.fc-event-mirror{z-index:7}.fc .fc-daygrid-day-bottom{font-size:.85em;margin:0 2px}.fc .fc-daygrid-day-bottom:after,.fc .fc-daygrid-day-bottom:before{clear:both;content:"";display:table}.fc .fc-daygrid-more-link{border-radius:3px;cursor:pointer;line-height:1;margin-top:1px;max-width:100%;overflow:hidden;padding:2px;position:relative;white-space:nowrap;z-index:4}.fc .fc-daygrid-more-link:hover{background-color:rgba(0,0,0,.1)}.fc .fc-daygrid-week-number{background-color:var(--fc-neutral-bg-color);color:var(--fc-neutral-text-color);min-width:1.5em;padding:2px;position:absolute;text-align:center;top:0;z-index:5}.fc .fc-more-popover .fc-popover-body{min-width:220px;padding:10px}.fc-direction-ltr .fc-daygrid-event.fc-event-start,.fc-direction-rtl .fc-daygrid-event.fc-event-end{margin-left:2px}.fc-direction-ltr .fc-daygrid-event.fc-event-end,.fc-direction-rtl .fc-daygrid-event.fc-event-start{margin-right:2px}.fc-direction-ltr .fc-daygrid-more-link{float:left}.fc-direction-ltr .fc-daygrid-week-number{border-radius:0 0 3px 0;left:0}.fc-direction-rtl .fc-daygrid-more-link{float:right}.fc-direction-rtl .fc-daygrid-week-number{border-radius:0 0 0 3px;right:0}.fc-liquid-hack .fc-daygrid-day-frame{position:static}.fc-daygrid-event{border-radius:3px;font-size:var(--fc-small-font-size);position:relative;white-space:nowrap}.fc-daygrid-block-event .fc-event-time{font-weight:700}.fc-daygrid-block-event .fc-event-time,.fc-daygrid-block-event .fc-event-title{padding:1px}.fc-daygrid-dot-event{align-items:center;display:flex;padding:2px 0}.fc-daygrid-dot-event .fc-event-title{flex-grow:1;flex-shrink:1;font-weight:700;min-width:0;overflow:hidden}.fc-daygrid-dot-event.fc-event-mirror,.fc-daygrid-dot-event:hover{background:rgba(0,0,0,.1)}.fc-daygrid-dot-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-daygrid-event-dot{border:calc(var(--fc-daygrid-event-dot-width)/2) solid var(--fc-event-border-color);border-radius:calc(var(--fc-daygrid-event-dot-width)/2);box-sizing:content-box;height:0;margin:0 4px;width:0}.fc-direction-ltr .fc-daygrid-event .fc-event-time{margin-right:3px}.fc-direction-rtl .fc-daygrid-event .fc-event-time{margin-left:3px}')},95257:(e,t,n)=>{"use strict";n.d(t,{A:()=>h});var r=n(67363),i=n(29174),s=n(76225);class o{constructor(e){this.maxIterations=null!=e.maxIterations?e.maxIterations:1e3,this.skipInvalidDates=null!=e.skipInvalidDates&&e.skipInvalidDates,this.jCalData=s.parse(e.ics),this.component=new s.Component(this.jCalData),this.events=this.component.getAllSubcomponents("vevent").map((e=>new s.Event(e))),this.skipInvalidDates&&(this.events=this.events.filter((e=>{try{return e.startDate.toJSDate(),e.endDate.toJSDate(),!0}catch(t){return!1}})))}between(e,t){function n(n,r){return(!e||r>=e.getTime())&&(!t||n<=t.getTime())}function r(e){const t=e.startDate.toJSDate().getTime();let n=e.endDate.toJSDate().getTime();return e.endDate.isDate&&n>t&&(n-=1),{startTime:t,endTime:n}}const i=[];this.events.forEach((e=>{e.isRecurrenceException()&&i.push(e)}));const s={events:[],occurrences:[]};return this.events.filter((e=>!e.isRecurrenceException())).forEach((e=>{const o=[];if(e.component.getAllProperties("exdate").forEach((e=>{const t=e.getFirstValue();o.push(t.toJSDate().getTime())})),e.isRecurring()){const a=e.iterator();let l,c=0;do{if(c+=1,l=a.next(),l){const a=e.getOccurrenceDetails(l),{startTime:c,endTime:u}=r(a),d=-1!==o.indexOf(c),h=i.find((t=>t.uid===e.uid&&t.recurrenceId.toJSDate().getTime()===a.startDate.toJSDate().getTime()));if(t&&c>t.getTime())break;n(c,u)&&(h?s.events.push(h):d||s.occurrences.push(a))}}while(l&&(!this.maxIterations||ce.url&&"ics"===e.format?{url:e.url,format:"ics"}:null,fetch(e,t,n){let r=e.eventSource.meta,{internalState:i}=r;i&&!e.isRefetch||(i=r.internalState={response:null,iCalExpanderPromise:fetch(r.url,{method:"GET"}).then((e=>e.text().then((t=>(i.response=e,new o({ics:t,skipInvalidDates:!0}))))))}),i.iCalExpanderPromise.then((n=>{t({rawEvents:l(n,e.range),response:i.response})}),n)}};function l(e,t){let n=(0,i.t)(t.start,-1),r=(0,i.t)(t.end,1),s=e.between(n,r),o=[];for(let i of s.events)o.push(Object.assign(Object.assign({},c(i)),{start:i.startDate.toString(),end:d(i)&&i.endDate?i.endDate.toString():null}));for(let i of s.occurrences){let e=i.item;o.push(Object.assign(Object.assign({},c(e)),{start:i.startDate.toString(),end:d(e)&&i.endDate?i.endDate.toString():null}))}return o}function c(e){return{title:e.summary,url:u(e),extendedProps:{location:e.location,organizer:e.organizer,description:e.description}}}function u(e){let t=e.component.getFirstProperty("url");return t?t.getFirstValue():""}function d(e){return Boolean(e.component.getFirstProperty("dtend"))||Boolean(e.component.getFirstProperty("duration"))}var h=(0,r.i1)({name:"@fullcalendar/icalendar",eventSourceDefs:[a]})},38680:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>x});var r=n(67363),i=n(29174);i.bI.touchMouseIgnoreWait=500;let s=0,o=0,a=!1;class l{constructor(e){this.subjectEl=null,this.selector="",this.handleSelector="",this.shouldIgnoreMove=!1,this.shouldWatchScroll=!0,this.isDragging=!1,this.isTouchDragging=!1,this.wasTouchScroll=!1,this.handleMouseDown=e=>{if(!this.shouldIgnoreMouse()&&function(e){return 0===e.button&&!e.ctrlKey}(e)&&this.tryStart(e)){let t=this.createEventFromMouse(e,!0);this.emitter.trigger("pointerdown",t),this.initScrollWatch(t),this.shouldIgnoreMove||document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("mouseup",this.handleMouseUp)}},this.handleMouseMove=e=>{let t=this.createEventFromMouse(e);this.recordCoords(t),this.emitter.trigger("pointermove",t)},this.handleMouseUp=e=>{document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp),this.emitter.trigger("pointerup",this.createEventFromMouse(e)),this.cleanup()},this.handleTouchStart=e=>{if(this.tryStart(e)){this.isTouchDragging=!0;let t=this.createEventFromTouch(e,!0);this.emitter.trigger("pointerdown",t),this.initScrollWatch(t);let n=e.target;this.shouldIgnoreMove||n.addEventListener("touchmove",this.handleTouchMove),n.addEventListener("touchend",this.handleTouchEnd),n.addEventListener("touchcancel",this.handleTouchEnd),window.addEventListener("scroll",this.handleTouchScroll,!0)}},this.handleTouchMove=e=>{let t=this.createEventFromTouch(e);this.recordCoords(t),this.emitter.trigger("pointermove",t)},this.handleTouchEnd=e=>{if(this.isDragging){let t=e.target;t.removeEventListener("touchmove",this.handleTouchMove),t.removeEventListener("touchend",this.handleTouchEnd),t.removeEventListener("touchcancel",this.handleTouchEnd),window.removeEventListener("scroll",this.handleTouchScroll,!0),this.emitter.trigger("pointerup",this.createEventFromTouch(e)),this.cleanup(),this.isTouchDragging=!1,s+=1,setTimeout((()=>{s-=1}),i.bI.touchMouseIgnoreWait)}},this.handleTouchScroll=()=>{this.wasTouchScroll=!0},this.handleScroll=e=>{if(!this.shouldIgnoreMove){let t=window.pageXOffset-this.prevScrollX+this.prevPageX,n=window.pageYOffset-this.prevScrollY+this.prevPageY;this.emitter.trigger("pointermove",{origEvent:e,isTouch:this.isTouchDragging,subjectEl:this.subjectEl,pageX:t,pageY:n,deltaX:t-this.origPageX,deltaY:n-this.origPageY})}},this.containerEl=e,this.emitter=new i.F,e.addEventListener("mousedown",this.handleMouseDown),e.addEventListener("touchstart",this.handleTouchStart,{passive:!0}),o+=1,1===o&&window.addEventListener("touchmove",c,{passive:!1})}destroy(){this.containerEl.removeEventListener("mousedown",this.handleMouseDown),this.containerEl.removeEventListener("touchstart",this.handleTouchStart,{passive:!0}),o-=1,o||window.removeEventListener("touchmove",c,{passive:!1})}tryStart(e){let t=this.querySubjectEl(e),n=e.target;return!(!t||this.handleSelector&&!(0,i.$)(n,this.handleSelector))&&(this.subjectEl=t,this.isDragging=!0,this.wasTouchScroll=!1,!0)}cleanup(){a=!1,this.isDragging=!1,this.subjectEl=null,this.destroyScrollWatch()}querySubjectEl(e){return this.selector?(0,i.$)(e.target,this.selector):this.containerEl}shouldIgnoreMouse(){return s||this.isTouchDragging}cancelTouchScroll(){this.isDragging&&(a=!0)}initScrollWatch(e){this.shouldWatchScroll&&(this.recordCoords(e),window.addEventListener("scroll",this.handleScroll,!0))}recordCoords(e){this.shouldWatchScroll&&(this.prevPageX=e.pageX,this.prevPageY=e.pageY,this.prevScrollX=window.pageXOffset,this.prevScrollY=window.pageYOffset)}destroyScrollWatch(){this.shouldWatchScroll&&window.removeEventListener("scroll",this.handleScroll,!0)}createEventFromMouse(e,t){let n=0,r=0;return t?(this.origPageX=e.pageX,this.origPageY=e.pageY):(n=e.pageX-this.origPageX,r=e.pageY-this.origPageY),{origEvent:e,isTouch:!1,subjectEl:this.subjectEl,pageX:e.pageX,pageY:e.pageY,deltaX:n,deltaY:r}}createEventFromTouch(e,t){let n,r,i=e.touches,s=0,o=0;return i&&i.length?(n=i[0].pageX,r=i[0].pageY):(n=e.pageX,r=e.pageY),t?(this.origPageX=n,this.origPageY=r):(s=n-this.origPageX,o=r-this.origPageY),{origEvent:e,isTouch:!0,subjectEl:this.subjectEl,pageX:n,pageY:r,deltaX:s,deltaY:o}}}function c(e){a&&e.preventDefault()}class u{constructor(){this.isVisible=!1,this.sourceEl=null,this.mirrorEl=null,this.sourceElRect=null,this.parentNode=document.body,this.zIndex=9999,this.revertDuration=0}start(e,t,n){this.sourceEl=e,this.sourceElRect=this.sourceEl.getBoundingClientRect(),this.origScreenX=t-window.pageXOffset,this.origScreenY=n-window.pageYOffset,this.deltaX=0,this.deltaY=0,this.updateElPosition()}handleMove(e,t){this.deltaX=e-window.pageXOffset-this.origScreenX,this.deltaY=t-window.pageYOffset-this.origScreenY,this.updateElPosition()}setIsVisible(e){e?this.isVisible||(this.mirrorEl&&(this.mirrorEl.style.display=""),this.isVisible=e,this.updateElPosition()):this.isVisible&&(this.mirrorEl&&(this.mirrorEl.style.display="none"),this.isVisible=e)}stop(e,t){let n=()=>{this.cleanup(),t()};e&&this.mirrorEl&&this.isVisible&&this.revertDuration&&(this.deltaX||this.deltaY)?this.doRevertAnimation(n,this.revertDuration):setTimeout(n,0)}doRevertAnimation(e,t){let n=this.mirrorEl,r=this.sourceEl.getBoundingClientRect();n.style.transition="top "+t+"ms,left "+t+"ms",(0,i.aP)(n,{left:r.left,top:r.top}),(0,i.b2)(n,(()=>{n.style.transition="",e()}))}cleanup(){this.mirrorEl&&((0,i.aO)(this.mirrorEl),this.mirrorEl=null),this.sourceEl=null}updateElPosition(){this.sourceEl&&this.isVisible&&(0,i.aP)(this.getMirrorEl(),{left:this.sourceElRect.left+this.deltaX,top:this.sourceElRect.top+this.deltaY})}getMirrorEl(){let e=this.sourceElRect,t=this.mirrorEl;return t||(t=this.mirrorEl=this.sourceEl.cloneNode(!0),t.style.userSelect="none",t.style.webkitUserSelect="none",t.classList.add("fc-event-dragging"),(0,i.aP)(t,{position:"fixed",zIndex:this.zIndex,visibility:"",boxSizing:"border-box",width:e.right-e.left,height:e.bottom-e.top,right:"auto",bottom:"auto",margin:0}),this.parentNode.appendChild(t)),t}}class d extends i.bb{constructor(e,t){super(),this.handleScroll=()=>{this.scrollTop=this.scrollController.getScrollTop(),this.scrollLeft=this.scrollController.getScrollLeft(),this.handleScrollChange()},this.scrollController=e,this.doesListening=t,this.scrollTop=this.origScrollTop=e.getScrollTop(),this.scrollLeft=this.origScrollLeft=e.getScrollLeft(),this.scrollWidth=e.getScrollWidth(),this.scrollHeight=e.getScrollHeight(),this.clientWidth=e.getClientWidth(),this.clientHeight=e.getClientHeight(),this.clientRect=this.computeClientRect(),this.doesListening&&this.getEventTarget().addEventListener("scroll",this.handleScroll)}destroy(){this.doesListening&&this.getEventTarget().removeEventListener("scroll",this.handleScroll)}getScrollTop(){return this.scrollTop}getScrollLeft(){return this.scrollLeft}setScrollTop(e){this.scrollController.setScrollTop(e),this.doesListening||(this.scrollTop=Math.max(Math.min(e,this.getMaxScrollTop()),0),this.handleScrollChange())}setScrollLeft(e){this.scrollController.setScrollLeft(e),this.doesListening||(this.scrollLeft=Math.max(Math.min(e,this.getMaxScrollLeft()),0),this.handleScrollChange())}getClientWidth(){return this.clientWidth}getClientHeight(){return this.clientHeight}getScrollWidth(){return this.scrollWidth}getScrollHeight(){return this.scrollHeight}handleScrollChange(){}}class h extends d{constructor(e,t){super(new i.bc(e),t)}getEventTarget(){return this.scrollController.el}computeClientRect(){return(0,i.b3)(this.scrollController.el)}}class f extends d{constructor(e){super(new i.bd,e)}getEventTarget(){return window}computeClientRect(){return{left:this.scrollLeft,right:this.scrollLeft+this.clientWidth,top:this.scrollTop,bottom:this.scrollTop+this.clientHeight}}handleScrollChange(){this.clientRect=this.computeClientRect()}}const p="function"==typeof performance?performance.now:Date.now;class g{constructor(){this.isEnabled=!0,this.scrollQuery=[window,".fc-scroller"],this.edgeThreshold=50,this.maxVelocity=300,this.pointerScreenX=null,this.pointerScreenY=null,this.isAnimating=!1,this.scrollCaches=null,this.everMovedUp=!1,this.everMovedDown=!1,this.everMovedLeft=!1,this.everMovedRight=!1,this.animate=()=>{if(this.isAnimating){let e=this.computeBestEdge(this.pointerScreenX+window.pageXOffset,this.pointerScreenY+window.pageYOffset);if(e){let t=p();this.handleSide(e,(t-this.msSinceRequest)/1e3),this.requestAnimation(t)}else this.isAnimating=!1}}}start(e,t,n){this.isEnabled&&(this.scrollCaches=this.buildCaches(n),this.pointerScreenX=null,this.pointerScreenY=null,this.everMovedUp=!1,this.everMovedDown=!1,this.everMovedLeft=!1,this.everMovedRight=!1,this.handleMove(e,t))}handleMove(e,t){if(this.isEnabled){let n=e-window.pageXOffset,r=t-window.pageYOffset,i=null===this.pointerScreenY?0:r-this.pointerScreenY,s=null===this.pointerScreenX?0:n-this.pointerScreenX;i<0?this.everMovedUp=!0:i>0&&(this.everMovedDown=!0),s<0?this.everMovedLeft=!0:s>0&&(this.everMovedRight=!0),this.pointerScreenX=n,this.pointerScreenY=r,this.isAnimating||(this.isAnimating=!0,this.requestAnimation(p()))}}stop(){if(this.isEnabled){this.isAnimating=!1;for(let e of this.scrollCaches)e.destroy();this.scrollCaches=null}}requestAnimation(e){this.msSinceRequest=e,requestAnimationFrame(this.animate)}handleSide(e,t){let{scrollCache:n}=e,{edgeThreshold:r}=this,i=r-e.distance,s=i*i/(r*r)*this.maxVelocity*t,o=1;switch(e.name){case"left":o=-1;case"right":n.setScrollLeft(n.getScrollLeft()+s*o);break;case"top":o=-1;case"bottom":n.setScrollTop(n.getScrollTop()+s*o)}}computeBestEdge(e,t){let{edgeThreshold:n}=this,r=null,i=this.scrollCaches||[];for(let s of i){let i=s.clientRect,o=e-i.left,a=i.right-e,l=t-i.top,c=i.bottom-t;o>=0&&a>=0&&l>=0&&c>=0&&(l<=n&&this.everMovedUp&&s.canScrollUp()&&(!r||r.distance>l)&&(r={scrollCache:s,name:"top",distance:l}),c<=n&&this.everMovedDown&&s.canScrollDown()&&(!r||r.distance>c)&&(r={scrollCache:s,name:"bottom",distance:c}),o<=n&&this.everMovedLeft&&s.canScrollLeft()&&(!r||r.distance>o)&&(r={scrollCache:s,name:"left",distance:o}),a<=n&&this.everMovedRight&&s.canScrollRight()&&(!r||r.distance>a)&&(r={scrollCache:s,name:"right",distance:a}))}return r}buildCaches(e){return this.queryScrollEls(e).map((e=>e===window?new f(!1):new h(e,!1)))}queryScrollEls(e){let t=[];for(let n of this.scrollQuery)"object"==typeof n?t.push(n):t.push(...Array.prototype.slice.call(e.getRootNode().querySelectorAll(n)));return t}}class m extends i.bH{constructor(e,t){super(e),this.containerEl=e,this.delay=null,this.minDistance=0,this.touchScrollAllowed=!0,this.mirrorNeedsRevert=!1,this.isInteracting=!1,this.isDragging=!1,this.isDelayEnded=!1,this.isDistanceSurpassed=!1,this.delayTimeoutId=null,this.onPointerDown=e=>{this.isDragging||(this.isInteracting=!0,this.isDelayEnded=!1,this.isDistanceSurpassed=!1,(0,i.ar)(document.body),(0,i.at)(document.body),e.isTouch||e.origEvent.preventDefault(),this.emitter.trigger("pointerdown",e),this.isInteracting&&!this.pointer.shouldIgnoreMove&&(this.mirror.setIsVisible(!1),this.mirror.start(e.subjectEl,e.pageX,e.pageY),this.startDelay(e),this.minDistance||this.handleDistanceSurpassed(e)))},this.onPointerMove=e=>{if(this.isInteracting){if(this.emitter.trigger("pointermove",e),!this.isDistanceSurpassed){let t,n=this.minDistance,{deltaX:r,deltaY:i}=e;t=r*r+i*i,t>=n*n&&this.handleDistanceSurpassed(e)}this.isDragging&&("scroll"!==e.origEvent.type&&(this.mirror.handleMove(e.pageX,e.pageY),this.autoScroller.handleMove(e.pageX,e.pageY)),this.emitter.trigger("dragmove",e))}},this.onPointerUp=e=>{this.isInteracting&&(this.isInteracting=!1,(0,i.as)(document.body),(0,i.au)(document.body),this.emitter.trigger("pointerup",e),this.isDragging&&(this.autoScroller.stop(),this.tryStopDrag(e)),this.delayTimeoutId&&(clearTimeout(this.delayTimeoutId),this.delayTimeoutId=null))};let n=this.pointer=new l(e);n.emitter.on("pointerdown",this.onPointerDown),n.emitter.on("pointermove",this.onPointerMove),n.emitter.on("pointerup",this.onPointerUp),t&&(n.selector=t),this.mirror=new u,this.autoScroller=new g}destroy(){this.pointer.destroy(),this.onPointerUp({})}startDelay(e){"number"==typeof this.delay?this.delayTimeoutId=setTimeout((()=>{this.delayTimeoutId=null,this.handleDelayEnd(e)}),this.delay):this.handleDelayEnd(e)}handleDelayEnd(e){this.isDelayEnded=!0,this.tryStartDrag(e)}handleDistanceSurpassed(e){this.isDistanceSurpassed=!0,this.tryStartDrag(e)}tryStartDrag(e){this.isDelayEnded&&this.isDistanceSurpassed&&(this.pointer.wasTouchScroll&&!this.touchScrollAllowed||(this.isDragging=!0,this.mirrorNeedsRevert=!1,this.autoScroller.start(e.pageX,e.pageY,this.containerEl),this.emitter.trigger("dragstart",e),!1===this.touchScrollAllowed&&this.pointer.cancelTouchScroll()))}tryStopDrag(e){this.mirror.stop(this.mirrorNeedsRevert,this.stopDrag.bind(this,e))}stopDrag(e){this.isDragging=!1,this.emitter.trigger("dragend",e)}setIgnoreMove(e){this.pointer.shouldIgnoreMove=e}setMirrorIsVisible(e){this.mirror.setIsVisible(e)}setMirrorNeedsRevert(e){this.mirrorNeedsRevert=e}setAutoScrollEnabled(e){this.autoScroller.isEnabled=e}}class v{constructor(e){this.origRect=(0,i.b6)(e),this.scrollCaches=(0,i.b5)(e).map((e=>new h(e,!0)))}destroy(){for(let e of this.scrollCaches)e.destroy()}computeLeft(){let e=this.origRect.left;for(let t of this.scrollCaches)e+=t.origScrollLeft-t.getScrollLeft();return e}computeTop(){let e=this.origRect.top;for(let t of this.scrollCaches)e+=t.origScrollTop-t.getScrollTop();return e}isWithinClipping(e,t){let n={left:e,top:t};for(let r of this.scrollCaches)if(!y(r.getEventTarget())&&!(0,i.aF)(n,r.clientRect))return!1;return!0}}function y(e){let t=e.tagName;return"HTML"===t||"BODY"===t}class b{constructor(e,t){this.useSubjectCenter=!1,this.requireInitial=!0,this.initialHit=null,this.movingHit=null,this.finalHit=null,this.handlePointerDown=e=>{let{dragging:t}=this;this.initialHit=null,this.movingHit=null,this.finalHit=null,this.prepareHits(),this.processFirstCoord(e),this.initialHit||!this.requireInitial?(t.setIgnoreMove(!1),this.emitter.trigger("pointerdown",e)):t.setIgnoreMove(!0)},this.handleDragStart=e=>{this.emitter.trigger("dragstart",e),this.handleMove(e,!0)},this.handleDragMove=e=>{this.emitter.trigger("dragmove",e),this.handleMove(e)},this.handlePointerUp=e=>{this.releaseHits(),this.emitter.trigger("pointerup",e)},this.handleDragEnd=e=>{this.movingHit&&this.emitter.trigger("hitupdate",null,!0,e),this.finalHit=this.movingHit,this.movingHit=null,this.emitter.trigger("dragend",e)},this.droppableStore=t,e.emitter.on("pointerdown",this.handlePointerDown),e.emitter.on("dragstart",this.handleDragStart),e.emitter.on("dragmove",this.handleDragMove),e.emitter.on("pointerup",this.handlePointerUp),e.emitter.on("dragend",this.handleDragEnd),this.dragging=e,this.emitter=new i.F}processFirstCoord(e){let t,n={left:e.pageX,top:e.pageY},r=n,s=e.subjectEl;s instanceof HTMLElement&&(t=(0,i.b6)(s),r=(0,i.aG)(r,t));let o=this.initialHit=this.queryHitForOffset(r.left,r.top);if(o){if(this.useSubjectCenter&&t){let e=(0,i.aE)(t,o.rect);e&&(r=(0,i.aH)(e))}this.coordAdjust=(0,i.aI)(r,n)}else this.coordAdjust={left:0,top:0}}handleMove(e,t){let n=this.queryHitForOffset(e.pageX+this.coordAdjust.left,e.pageY+this.coordAdjust.top);!t&&D(this.movingHit,n)||(this.movingHit=n,this.emitter.trigger("hitupdate",n,!1,e))}prepareHits(){this.offsetTrackers=(0,i.a)(this.droppableStore,(e=>(e.component.prepareHits(),new v(e.el))))}releaseHits(){let{offsetTrackers:e}=this;for(let t in e)e[t].destroy();this.offsetTrackers={}}queryHitForOffset(e,t){let{droppableStore:n,offsetTrackers:r}=this,s=null;for(let o in n){let a=n[o].component,l=r[o];if(l&&l.isWithinClipping(e,t)){let n=l.computeLeft(),r=l.computeTop(),c=e-n,u=t-r,{origRect:d}=l,h=d.right-d.left,f=d.bottom-d.top;if(c>=0&&c=0&&us.layer)&&(e.componentId=o,e.context=a.context,e.rect.left+=n,e.rect.right+=n,e.rect.top+=r,e.rect.bottom+=r,s=e)}}}return s}}function D(e,t){return!e&&!t||Boolean(e)===Boolean(t)&&(0,i.bf)(e.dateSpan,t.dateSpan)}function A(e,t){let n={};for(let s of t.pluginHooks.datePointTransforms)Object.assign(n,s(e,t));var r,i;return Object.assign(n,(r=e,{date:(i=t.dateEnv).toDate(r.range.start),dateStr:i.formatIso(r.range.start,{omitTime:r.allDay}),allDay:r.allDay})),n}class E extends i.Z{constructor(e){super(e),this.handlePointerDown=e=>{let{dragging:t}=this,n=e.origEvent.target;t.setIgnoreMove(!this.component.isValidDateDownEl(n))},this.handleDragEnd=e=>{let{component:t}=this,{pointer:n}=this.dragging;if(!n.wasTouchScroll){let{initialHit:n,finalHit:r}=this.hitDragging;if(n&&r&&D(n,r)){let{context:r}=t,i=Object.assign(Object.assign({},A(n.dateSpan,r)),{dayEl:n.dayEl,jsEvent:e.origEvent,view:r.viewApi||r.calendarApi.view});r.emitter.trigger("dateClick",i)}}},this.dragging=new m(e.el),this.dragging.autoScroller.isEnabled=!1;let t=this.hitDragging=new b(this.dragging,(0,i.bG)(e));t.emitter.on("pointerdown",this.handlePointerDown),t.emitter.on("dragend",this.handleDragEnd)}destroy(){this.dragging.destroy()}}class _ extends i.Z{constructor(e){super(e),this.dragSelection=null,this.handlePointerDown=e=>{let{component:t,dragging:n}=this,{options:r}=t.context,i=r.selectable&&t.isValidDateDownEl(e.origEvent.target);n.setIgnoreMove(!i),n.delay=e.isTouch?function(e){let{options:t}=e.context,n=t.selectLongPressDelay;null==n&&(n=t.longPressDelay);return n}(t):null},this.handleDragStart=e=>{this.component.context.calendarApi.unselect(e)},this.handleHitUpdate=(e,t)=>{let{context:n}=this.component,r=null,s=!1;if(e){let t=this.hitDragging.initialHit;e.componentId===t.componentId&&this.isHitComboAllowed&&!this.isHitComboAllowed(t,e)||(r=function(e,t,n){let r=e.dateSpan,s=t.dateSpan,o=[r.range.start,r.range.end,s.range.start,s.range.end];o.sort(i.av);let a={};for(let i of n){let n=i(e,t);if(!1===n)return null;n&&Object.assign(a,n)}return a.range={start:o[0],end:o[3]},a.allDay=r.allDay,a}(t,e,n.pluginHooks.dateSelectionTransformers)),r&&(0,i.b_)(r,e.dateProfile,n)||(s=!0,r=null)}r?n.dispatch({type:"SELECT_DATES",selection:r}):t||n.dispatch({type:"UNSELECT_DATES"}),s?(0,i.ax)():(0,i.aw)(),t||(this.dragSelection=r)},this.handlePointerUp=e=>{this.dragSelection&&((0,i.cu)(this.dragSelection,e,this.component.context),this.dragSelection=null)};let{component:t}=e,{options:n}=t.context,r=this.dragging=new m(e.el);r.touchScrollAllowed=!1,r.minDistance=n.selectMinDistance||0,r.autoScroller.isEnabled=n.dragScroll;let s=this.hitDragging=new b(this.dragging,(0,i.bG)(e));s.emitter.on("pointerdown",this.handlePointerDown),s.emitter.on("dragstart",this.handleDragStart),s.emitter.on("hitupdate",this.handleHitUpdate),s.emitter.on("pointerup",this.handlePointerUp)}destroy(){this.dragging.destroy()}}class S extends i.Z{constructor(e){super(e),this.subjectEl=null,this.subjectSeg=null,this.isDragging=!1,this.eventRange=null,this.relevantEvents=null,this.receivingContext=null,this.validMutation=null,this.mutatedRelevantEvents=null,this.handlePointerDown=e=>{let t=e.origEvent.target,{component:n,dragging:r}=this,{mirror:s}=r,{options:o}=n.context,a=n.context;this.subjectEl=e.subjectEl;let l=this.subjectSeg=(0,i._)(e.subjectEl),c=(this.eventRange=l.eventRange).instance.instanceId;this.relevantEvents=(0,i.aV)(a.getCurrentData().eventStore,c),r.minDistance=e.isTouch?0:o.eventDragMinDistance,r.delay=e.isTouch&&c!==n.props.eventSelection?function(e){let{options:t}=e.context,n=t.eventLongPressDelay;null==n&&(n=t.longPressDelay);return n}(n):null,o.fixedMirrorParent?s.parentNode=o.fixedMirrorParent:s.parentNode=(0,i.$)(t,".fc"),s.revertDuration=o.dragRevertDuration;let u=n.isValidSegDownEl(t)&&!(0,i.$)(t,".fc-event-resizer");r.setIgnoreMove(!u),this.isDragging=u&&e.subjectEl.classList.contains("fc-event-draggable")},this.handleDragStart=e=>{let t=this.component.context,n=this.eventRange,r=n.instance.instanceId;e.isTouch?r!==this.component.props.eventSelection&&t.dispatch({type:"SELECT_EVENT",eventInstanceId:r}):t.dispatch({type:"UNSELECT_EVENT"}),this.isDragging&&(t.calendarApi.unselect(e),t.emitter.trigger("eventDragStart",{el:this.subjectEl,event:new i.a0(t,n.def,n.instance),jsEvent:e.origEvent,view:t.viewApi}))},this.handleHitUpdate=(e,t)=>{if(!this.isDragging)return;let n=this.relevantEvents,r=this.hitDragging.initialHit,s=this.component.context,o=null,a=null,l=null,c=!1,u={affectedEvents:n,mutatedEvents:(0,i.I)(),isEvent:!0};if(e){o=e.context;let t=o.options;s===o||t.editable&&t.droppable?(a=function(e,t,n){let r=e.dateSpan,s=t.dateSpan,o=r.range.start,a=s.range.start,l={};r.allDay!==s.allDay&&(l.allDay=s.allDay,l.hasEnd=t.context.options.allDayMaintainDuration,s.allDay&&(o=(0,i.q)(o)));let c=(0,i.aA)(o,a,e.context.dateEnv,e.componentId===t.componentId?e.largeUnit:null);c.milliseconds&&(l.allDay=!1);let u={datesDelta:c,standardProps:l};for(let i of n)i(u,e,t);return u}(r,e,o.getCurrentData().pluginHooks.eventDragMutationMassagers),a&&(l=(0,i.bX)(n,o.getCurrentData().eventUiBases,a,o),u.mutatedEvents=l,(0,i.bZ)(u,e.dateProfile,o)||(c=!0,a=null,l=null,u.mutatedEvents=(0,i.I)()))):o=null}this.displayDrag(o,u),c?(0,i.ax)():(0,i.aw)(),t||(s===o&&D(r,e)&&(a=null),this.dragging.setMirrorNeedsRevert(!a),this.dragging.setMirrorIsVisible(!e||!this.subjectEl.getRootNode().querySelector(".fc-event-mirror")),this.receivingContext=o,this.validMutation=a,this.mutatedRelevantEvents=l)},this.handlePointerUp=()=>{this.isDragging||this.cleanup()},this.handleDragEnd=e=>{if(this.isDragging){let t=this.component.context,n=t.viewApi,{receivingContext:r,validMutation:s}=this,o=this.eventRange.def,a=this.eventRange.instance,l=new i.a0(t,o,a),c=this.relevantEvents,u=this.mutatedRelevantEvents,{finalHit:d}=this.hitDragging;if(this.clearDrag(),t.emitter.trigger("eventDragStop",{el:this.subjectEl,event:l,jsEvent:e.origEvent,view:n}),s){if(r===t){let r=new i.a0(t,u.defs[o.defId],a?u.instances[a.instanceId]:null);t.dispatch({type:"MERGE_EVENTS",eventStore:u});let d={oldEvent:l,event:r,relatedEvents:(0,i.w)(u,t,a),revert(){t.dispatch({type:"MERGE_EVENTS",eventStore:c})}},h={};for(let e of t.getCurrentData().pluginHooks.eventDropTransformers)Object.assign(h,e(s,t));t.emitter.trigger("eventDrop",Object.assign(Object.assign(Object.assign({},d),h),{el:e.subjectEl,delta:s.datesDelta,jsEvent:e.origEvent,view:n})),t.emitter.trigger("eventChange",d)}else if(r){let s={event:l,relatedEvents:(0,i.w)(c,t,a),revert(){t.dispatch({type:"MERGE_EVENTS",eventStore:c})}};t.emitter.trigger("eventLeave",Object.assign(Object.assign({},s),{draggedEl:e.subjectEl,view:n})),t.dispatch({type:"REMOVE_EVENTS",eventStore:c}),t.emitter.trigger("eventRemove",s);let h=u.defs[o.defId],f=u.instances[a.instanceId],p=new i.a0(r,h,f);r.dispatch({type:"MERGE_EVENTS",eventStore:u});let g={event:p,relatedEvents:(0,i.w)(u,r,f),revert(){r.dispatch({type:"REMOVE_EVENTS",eventStore:u})}};r.emitter.trigger("eventAdd",g),e.isTouch&&r.dispatch({type:"SELECT_EVENT",eventInstanceId:a.instanceId}),r.emitter.trigger("drop",Object.assign(Object.assign({},A(d.dateSpan,r)),{draggedEl:e.subjectEl,jsEvent:e.origEvent,view:d.context.viewApi})),r.emitter.trigger("eventReceive",Object.assign(Object.assign({},g),{draggedEl:e.subjectEl,view:d.context.viewApi}))}}else t.emitter.trigger("_noEventDrop")}this.cleanup()};let{component:t}=this,{options:n}=t.context,r=this.dragging=new m(e.el);r.pointer.selector=S.SELECTOR,r.touchScrollAllowed=!1,r.autoScroller.isEnabled=n.dragScroll;let s=this.hitDragging=new b(this.dragging,i.a7);s.useSubjectCenter=e.useEventCenter,s.emitter.on("pointerdown",this.handlePointerDown),s.emitter.on("dragstart",this.handleDragStart),s.emitter.on("hitupdate",this.handleHitUpdate),s.emitter.on("pointerup",this.handlePointerUp),s.emitter.on("dragend",this.handleDragEnd)}destroy(){this.dragging.destroy()}displayDrag(e,t){let n=this.component.context,r=this.receivingContext;r&&r!==e&&(r===n?r.dispatch({type:"SET_EVENT_DRAG",state:{affectedEvents:t.affectedEvents,mutatedEvents:(0,i.I)(),isEvent:!0}}):r.dispatch({type:"UNSET_EVENT_DRAG"})),e&&e.dispatch({type:"SET_EVENT_DRAG",state:t})}clearDrag(){let e=this.component.context,{receivingContext:t}=this;t&&t.dispatch({type:"UNSET_EVENT_DRAG"}),e!==t&&e.dispatch({type:"UNSET_EVENT_DRAG"})}cleanup(){this.subjectSeg=null,this.isDragging=!1,this.eventRange=null,this.relevantEvents=null,this.receivingContext=null,this.validMutation=null,this.mutatedRelevantEvents=null}}S.SELECTOR=".fc-event-draggable, .fc-event-resizable";class T extends i.Z{constructor(e){super(e),this.draggingSegEl=null,this.draggingSeg=null,this.eventRange=null,this.relevantEvents=null,this.validMutation=null,this.mutatedRelevantEvents=null,this.handlePointerDown=e=>{let{component:t}=this,n=this.querySegEl(e),r=(0,i._)(n),s=this.eventRange=r.eventRange;this.dragging.minDistance=t.context.options.eventDragMinDistance,this.dragging.setIgnoreMove(!this.component.isValidSegDownEl(e.origEvent.target)||e.isTouch&&this.component.props.eventSelection!==s.instance.instanceId)},this.handleDragStart=e=>{let{context:t}=this.component,n=this.eventRange;this.relevantEvents=(0,i.aV)(t.getCurrentData().eventStore,this.eventRange.instance.instanceId);let r=this.querySegEl(e);this.draggingSegEl=r,this.draggingSeg=(0,i._)(r),t.calendarApi.unselect(),t.emitter.trigger("eventResizeStart",{el:r,event:new i.a0(t,n.def,n.instance),jsEvent:e.origEvent,view:t.viewApi})},this.handleHitUpdate=(e,t,n)=>{let{context:r}=this.component,s=this.relevantEvents,o=this.hitDragging.initialHit,a=this.eventRange.instance,l=null,c=null,u=!1,d={affectedEvents:s,mutatedEvents:(0,i.I)(),isEvent:!0};if(e){e.componentId===o.componentId&&this.isHitComboAllowed&&!this.isHitComboAllowed(o,e)||(l=function(e,t,n,r){let s=e.context.dateEnv,o=e.dateSpan.range.start,a=t.dateSpan.range.start,l=(0,i.aA)(o,a,s,e.largeUnit);if(n){if(s.add(r.start,l)r.start)return{endDelta:l};return null}(o,e,n.subjectEl.classList.contains("fc-event-resizer-start"),a.range))}l&&(c=(0,i.bX)(s,r.getCurrentData().eventUiBases,l,r),d.mutatedEvents=c,(0,i.bZ)(d,e.dateProfile,r)||(u=!0,l=null,c=null,d.mutatedEvents=null)),c?r.dispatch({type:"SET_EVENT_RESIZE",state:d}):r.dispatch({type:"UNSET_EVENT_RESIZE"}),u?(0,i.ax)():(0,i.aw)(),t||(l&&D(o,e)&&(l=null),this.validMutation=l,this.mutatedRelevantEvents=c)},this.handleDragEnd=e=>{let{context:t}=this.component,n=this.eventRange.def,r=this.eventRange.instance,s=new i.a0(t,n,r),o=this.relevantEvents,a=this.mutatedRelevantEvents;if(t.emitter.trigger("eventResizeStop",{el:this.draggingSegEl,event:s,jsEvent:e.origEvent,view:t.viewApi}),this.validMutation){let l=new i.a0(t,a.defs[n.defId],r?a.instances[r.instanceId]:null);t.dispatch({type:"MERGE_EVENTS",eventStore:a});let c={oldEvent:s,event:l,relatedEvents:(0,i.w)(a,t,r),revert(){t.dispatch({type:"MERGE_EVENTS",eventStore:o})}};t.emitter.trigger("eventResize",Object.assign(Object.assign({},c),{el:this.draggingSegEl,startDelta:this.validMutation.startDelta||(0,i.d)(0),endDelta:this.validMutation.endDelta||(0,i.d)(0),jsEvent:e.origEvent,view:t.viewApi})),t.emitter.trigger("eventChange",c)}else t.emitter.trigger("_noEventResize");this.draggingSeg=null,this.relevantEvents=null,this.validMutation=null};let{component:t}=e,n=this.dragging=new m(e.el);n.pointer.selector=".fc-event-resizer",n.touchScrollAllowed=!1,n.autoScroller.isEnabled=t.context.options.dragScroll;let r=this.hitDragging=new b(this.dragging,(0,i.bG)(e));r.emitter.on("pointerdown",this.handlePointerDown),r.emitter.on("dragstart",this.handleDragStart),r.emitter.on("hitupdate",this.handleHitUpdate),r.emitter.on("dragend",this.handleDragEnd)}destroy(){this.dragging.destroy()}querySegEl(e){return(0,i.$)(e.subjectEl,".fc-event")}}const w={fixedMirrorParent:i.n},C={dateClick:i.n,eventDragStart:i.n,eventDragStop:i.n,eventDrop:i.n,eventResizeStart:i.n,eventResizeStop:i.n,eventResize:i.n,drop:i.n,eventReceive:i.n,eventLeave:i.n};i.bI.dataAttrPrefix="";i.bH;var x=(0,r.i1)({name:"@fullcalendar/interaction",componentInteractions:[E,_,S,T],calendarInteractions:[class{constructor(e){this.context=e,this.isRecentPointerDateSelect=!1,this.matchesCancel=!1,this.matchesEvent=!1,this.onSelect=e=>{e.jsEvent&&(this.isRecentPointerDateSelect=!0)},this.onDocumentPointerDown=e=>{let t=this.context.options.unselectCancel,n=(0,i.aR)(e.origEvent);this.matchesCancel=!!(0,i.$)(n,t),this.matchesEvent=!!(0,i.$)(n,S.SELECTOR)},this.onDocumentPointerUp=e=>{let{context:t}=this,{documentPointer:n}=this,r=t.getCurrentData();if(!n.wasTouchScroll){if(r.dateSelection&&!this.isRecentPointerDateSelect){let n=t.options.unselectAuto;!n||n&&this.matchesCancel||t.calendarApi.unselect(e)}r.eventSelection&&!this.matchesEvent&&t.dispatch({type:"UNSELECT_EVENT"})}this.isRecentPointerDateSelect=!1};let t=this.documentPointer=new l(document);t.shouldIgnoreMove=!0,t.shouldWatchScroll=!1,t.emitter.on("pointerdown",this.onDocumentPointerDown),t.emitter.on("pointerup",this.onDocumentPointerUp),e.emitter.on("select",this.onSelect)}destroy(){this.context.emitter.off("select",this.onSelect),this.documentPointer.destroy()}}],elementDraggingImpl:m,optionRefiners:w,listenerRefiners:C})},17632:(e,t,n)=>{"use strict";n.d(t,{A:()=>l});var r=n(96540),i=n(40961),s=n(67363),o=n(29174);const a=parseInt(String(r.version).split(".")[0])<18;class l extends r.Component{constructor(){super(...arguments),this.elRef=(0,r.createRef)(),this.isUpdating=!1,this.isUnmounting=!1,this.state={customRenderingMap:new Map},this.requestResize=()=>{this.isUnmounting||(this.cancelResize(),this.resizeId=requestAnimationFrame((()=>{this.doResize()})))}}render(){const e=[];for(const t of this.state.customRenderingMap.values())e.push(r.createElement(c,{key:t.id,customRendering:t}));return r.createElement("div",{ref:this.elRef},e)}componentDidMount(){this.isUnmounting=!1;const e=new o.cy;let t;this.handleCustomRendering=e.handle.bind(e),this.calendar=new s.Vv(this.elRef.current,Object.assign(Object.assign({},this.props),{handleCustomRendering:this.handleCustomRendering})),this.calendar.render(),e.subscribe((e=>{const n=Date.now(),r=!t;(a||r||this.isUpdating||this.isUnmounting||n-t<100?u:i.flushSync)((()=>{this.setState({customRenderingMap:e},(()=>{t=n,r?this.doResize():this.requestResize()}))}))}))}componentDidUpdate(){this.isUpdating=!0,this.calendar.resetOptions(Object.assign(Object.assign({},this.props),{handleCustomRendering:this.handleCustomRendering})),this.isUpdating=!1}componentWillUnmount(){this.isUnmounting=!0,this.cancelResize(),this.calendar.destroy()}doResize(){this.calendar.updateSize()}cancelResize(){void 0!==this.resizeId&&(cancelAnimationFrame(this.resizeId),this.resizeId=void 0)}getApi(){return this.calendar}}l.act=u;class c extends r.PureComponent{render(){const{customRendering:e}=this.props,{generatorMeta:t}=e,n="function"==typeof t?t(e.renderProps):t;return(0,i.createPortal)(n,e.containerEl)}}function u(e){e()}},11244:(e,t,n)=>{"use strict";n.d(t,{A:()=>W});var r=n(67363),i=n(29174),s=n(50172),o=n(78817);class a extends i.aY{getKeyInfo(){return{allDay:{},timed:{}}}getKeysForDateSpan(e){return e.allDay?["allDay"]:["timed"]}getKeysForEventDef(e){return e.allDay?(0,i.bP)(e)?["timed","allDay"]:["allDay"]:["timed"]}}const l=(0,i.x)({hour:"numeric",minute:"2-digit",omitZeroMinute:!0,meridiem:"short"});function c(e){let t=["fc-timegrid-slot","fc-timegrid-slot-label",e.isLabeled?"fc-scrollgrid-shrink":"fc-timegrid-slot-minor"];return(0,s.n)(i.V.Consumer,null,(n=>{if(!e.isLabeled)return(0,s.n)("td",{className:t.join(" "),"data-time":e.isoTimeStr});let{dateEnv:r,options:o,viewApi:a}=n,c=null==o.slotLabelFormat?l:Array.isArray(o.slotLabelFormat)?(0,i.x)(o.slotLabelFormat[0]):(0,i.x)(o.slotLabelFormat),d={level:0,time:e.time,date:r.toDate(e.date),view:a,text:r.format(e.date,c)};return(0,s.n)(i.C,{elTag:"td",elClasses:t,elAttrs:{"data-time":e.isoTimeStr},renderProps:d,generatorName:"slotLabelContent",customGenerator:o.slotLabelContent,defaultGenerator:u,classNameGenerator:o.slotLabelClassNames,didMount:o.slotLabelDidMount,willUnmount:o.slotLabelWillUnmount},(e=>(0,s.n)("div",{className:"fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame"},(0,s.n)(e,{elTag:"div",elClasses:["fc-timegrid-slot-label-cushion","fc-scrollgrid-shrink-cushion"]}))))}))}function u(e){return e.text}class d extends i.B{render(){return this.props.slatMetas.map((e=>(0,s.n)("tr",{key:e.key},(0,s.n)(c,Object.assign({},e)))))}}const h=(0,i.x)({week:"short"});class f extends i.be{constructor(){super(...arguments),this.allDaySplitter=new a,this.headerElRef=(0,s._3)(),this.rootElRef=(0,s._3)(),this.scrollerElRef=(0,s._3)(),this.state={slatCoords:null},this.handleScrollTopRequest=e=>{let t=this.scrollerElRef.current;t&&(t.scrollTop=e)},this.renderHeadAxis=(e,t="")=>{let{options:n}=this.context,{dateProfile:r}=this.props,o=r.renderRange,a=1===(0,i.bl)(o.start,o.end)?(0,i.b0)(this.context,o.start,"week"):{};return n.weekNumbers&&"day"===e?(0,s.n)(i.cq,{elTag:"th",elClasses:["fc-timegrid-axis","fc-scrollgrid-shrink"],elAttrs:{"aria-hidden":!0},date:o.start,defaultFormat:h},(e=>(0,s.n)("div",{className:["fc-timegrid-axis-frame","fc-scrollgrid-shrink-frame","fc-timegrid-axis-frame-liquid"].join(" "),style:{height:t}},(0,s.n)(e,{elTag:"a",elClasses:["fc-timegrid-axis-cushion","fc-scrollgrid-shrink-cushion","fc-scrollgrid-sync-inner"],elAttrs:a})))):(0,s.n)("th",{"aria-hidden":!0,className:"fc-timegrid-axis"},(0,s.n)("div",{className:"fc-timegrid-axis-frame",style:{height:t}}))},this.renderTableRowAxis=e=>{let{options:t,viewApi:n}=this.context,r={text:t.allDayText,view:n};return(0,s.n)(i.C,{elTag:"td",elClasses:["fc-timegrid-axis","fc-scrollgrid-shrink"],elAttrs:{"aria-hidden":!0},renderProps:r,generatorName:"allDayContent",customGenerator:t.allDayContent,defaultGenerator:p,classNameGenerator:t.allDayClassNames,didMount:t.allDayDidMount,willUnmount:t.allDayWillUnmount},(t=>(0,s.n)("div",{className:["fc-timegrid-axis-frame","fc-scrollgrid-shrink-frame",null==e?" fc-timegrid-axis-frame-liquid":""].join(" "),style:{height:e}},(0,s.n)(t,{elTag:"span",elClasses:["fc-timegrid-axis-cushion","fc-scrollgrid-shrink-cushion","fc-scrollgrid-sync-inner"]}))))},this.handleSlatCoords=e=>{this.setState({slatCoords:e})}}renderSimpleLayout(e,t,n){let{context:r,props:o}=this,a=[],l=(0,i.cc)(r.options);return e&&a.push({type:"header",key:"header",isSticky:l,chunk:{elRef:this.headerElRef,tableClassName:"fc-col-header",rowContent:e}}),t&&(a.push({type:"body",key:"all-day",chunk:{content:t}}),a.push({type:"body",key:"all-day-divider",outerContent:(0,s.n)("tr",{role:"presentation",className:"fc-scrollgrid-section"},(0,s.n)("td",{className:"fc-timegrid-divider "+r.theme.getClass("tableCellShaded")}))})),a.push({type:"body",key:"body",liquid:!0,expandRows:Boolean(r.options.expandRows),chunk:{scrollerElRef:this.scrollerElRef,content:n}}),(0,s.n)(i.ct,{elRef:this.rootElRef,elClasses:["fc-timegrid"],viewSpec:r.viewSpec},(0,s.n)(i.b$,{liquid:!o.isHeightAuto&&!o.forPrint,collapsibleWidth:o.forPrint,cols:[{width:"shrink"}],sections:a}))}renderHScrollLayout(e,t,n,r,o,a,l){let c=this.context.pluginHooks.scrollGridImpl;if(!c)throw new Error("No ScrollGrid implementation");let{context:u,props:h}=this,f=!h.forPrint&&(0,i.cc)(u.options),p=!h.forPrint&&(0,i.cb)(u.options),g=[];e&&g.push({type:"header",key:"header",isSticky:f,syncRowHeights:!0,chunks:[{key:"axis",rowContent:e=>(0,s.n)("tr",{role:"presentation"},this.renderHeadAxis("day",e.rowSyncHeights[0]))},{key:"cols",elRef:this.headerElRef,tableClassName:"fc-col-header",rowContent:e}]}),t&&(g.push({type:"body",key:"all-day",syncRowHeights:!0,chunks:[{key:"axis",rowContent:e=>(0,s.n)("tr",{role:"presentation"},this.renderTableRowAxis(e.rowSyncHeights[0]))},{key:"cols",content:t}]}),g.push({key:"all-day-divider",type:"body",outerContent:(0,s.n)("tr",{role:"presentation",className:"fc-scrollgrid-section"},(0,s.n)("td",{colSpan:2,className:"fc-timegrid-divider "+u.theme.getClass("tableCellShaded")}))}));let m=u.options.nowIndicator;return g.push({type:"body",key:"body",liquid:!0,expandRows:Boolean(u.options.expandRows),chunks:[{key:"axis",content:e=>(0,s.n)("div",{className:"fc-timegrid-axis-chunk"},(0,s.n)("table",{"aria-hidden":!0,style:{height:e.expandRows?e.clientHeight:""}},e.tableColGroupNode,(0,s.n)("tbody",null,(0,s.n)(d,{slatMetas:a}))),(0,s.n)("div",{className:"fc-timegrid-now-indicator-container"},(0,s.n)(i.ch,{unit:m?"minute":"day"},(e=>{let t=m&&l&&l.safeComputeTop(e);return"number"==typeof t?(0,s.n)(i.ck,{elClasses:["fc-timegrid-now-indicator-arrow"],elStyle:{top:t},isAxis:!0,date:e}):null}))))},{key:"cols",scrollerElRef:this.scrollerElRef,content:n}]}),p&&g.push({key:"footer",type:"footer",isSticky:!0,chunks:[{key:"axis",content:i.ca},{key:"cols",content:i.ca}]}),(0,s.n)(i.ct,{elRef:this.rootElRef,elClasses:["fc-timegrid"],viewSpec:u.viewSpec},(0,s.n)(c,{liquid:!h.isHeightAuto&&!h.forPrint,forPrint:h.forPrint,collapsibleWidth:!1,colGroups:[{width:"shrink",cols:[{width:"shrink"}]},{cols:[{span:r,minWidth:o}]}],sections:g}))}getAllDayMaxEventProps(){let{dayMaxEvents:e,dayMaxEventRows:t}=this.context.options;return!0!==e&&!0!==t||(e=void 0,t=5),{dayMaxEvents:e,dayMaxEventRows:t}}}function p(e){return e.text}class g{constructor(e,t,n){this.positions=e,this.dateProfile=t,this.slotDuration=n}safeComputeTop(e){let{dateProfile:t}=this;if((0,i.H)(t.currentRange,e)){let n=(0,i.q)(e),r=e.valueOf()-n.valueOf();if(r>=(0,i.bs)(t.slotMinTime)&&r<(0,i.bs)(t.slotMaxTime))return this.computeTimeTop((0,i.d)(r))}return null}computeDateTop(e,t){return t||(t=(0,i.q)(e)),this.computeTimeTop((0,i.d)(e.valueOf()-t.valueOf()))}computeTimeTop(e){let t,n,{positions:r,dateProfile:s}=this,o=r.els.length,a=(e.milliseconds-(0,i.bs)(s.slotMinTime))/(0,i.bs)(this.slotDuration);return a=Math.max(0,a),a=Math.min(o,a),t=Math.floor(a),t=Math.min(t,o-1),n=a-t,r.tops[t]+r.getHeight(t)*n}}class m extends i.B{render(){let{props:e,context:t}=this,{options:n}=t,{slatElRefs:r}=e;return(0,s.n)("tbody",null,e.slatMetas.map(((o,a)=>{let l={time:o.time,date:t.dateEnv.toDate(o.date),view:t.viewApi};return(0,s.n)("tr",{key:o.key,ref:r.createRef(o.key)},e.axis&&(0,s.n)(c,Object.assign({},o)),(0,s.n)(i.C,{elTag:"td",elClasses:["fc-timegrid-slot","fc-timegrid-slot-lane",!o.isLabeled&&"fc-timegrid-slot-minor"],elAttrs:{"data-time":o.isoTimeStr},renderProps:l,generatorName:"slotLaneContent",customGenerator:n.slotLaneContent,classNameGenerator:n.slotLaneClassNames,didMount:n.slotLaneDidMount,willUnmount:n.slotLaneWillUnmount}))})))}}class v extends i.B{constructor(){super(...arguments),this.rootElRef=(0,s._3)(),this.slatElRefs=new i.cf}render(){let{props:e,context:t}=this;return(0,s.n)("div",{ref:this.rootElRef,className:"fc-timegrid-slots"},(0,s.n)("table",{"aria-hidden":!0,className:t.theme.getClass("table"),style:{minWidth:e.tableMinWidth,width:e.clientWidth,height:e.minHeight}},e.tableColGroupNode,(0,s.n)(m,{slatElRefs:this.slatElRefs,axis:e.axis,slatMetas:e.slatMetas})))}componentDidMount(){this.updateSizing()}componentDidUpdate(){this.updateSizing()}componentWillUnmount(){this.props.onCoords&&this.props.onCoords(null)}updateSizing(){let{context:e,props:t}=this;if(t.onCoords&&null!==t.clientWidth){this.rootElRef.current.offsetHeight&&t.onCoords(new g(new i.ba(this.rootElRef.current,(n=this.slatElRefs.currentMap,t.slatMetas.map((e=>n[e.key]))),!1,!0),this.props.dateProfile,e.options.slotDuration))}var n}}function y(e,t){let n,r=[];for(n=0;nk(e.hiddenSegs,e),defaultGenerator:A,forceTimed:!0},(e=>(0,s.n)(e,{elTag:"div",elClasses:["fc-timegrid-more-link-inner","fc-sticky"]})))}}function A(e){return e.shortText}function E(e,t,n){let r=new i.bA;null!=t&&(r.strictOrder=t),null!=n&&(r.maxStackCnt=n);let s=r.addSegs(e),o=(0,i.bE)(s),a=function(e){const{entriesByLevel:t}=e,n=w(((e,t)=>e+":"+t),((r,s)=>{let o=function(e,t,n){let{levelCoords:r,entriesByLevel:s}=e,o=s[t][n],a=r[t]+o.thickness,l=r.length,c=t;for(;c(0,i.bB)(e)),((e,r,i)=>{let s,{nextLevelNodes:o,thickness:a}=e,l=a+i,c=a/l,u=[];if(o.length)for(let t of o)if(void 0===s){let e=n(t,r,l);s=e[0],u.push(e[1])}else{let e=n(t,s,0);u.push(e[1])}else s=t;let d=(s-r)*c;return[s-d,Object.assign(Object.assign({},e),{thickness:d,nextLevelNodes:u})]}));return e.map((e=>n(e,0,0)[1]))}(a,1),{segRects:function(e){let t=[];const n=w(((e,t,n)=>(0,i.bB)(e)),((e,n,i)=>{let s=Object.assign(Object.assign({},e),{levelCoord:n,stackDepth:i,stackForward:0});return t.push(s),s.stackForward=r(e.nextLevelNodes,n+e.thickness,i+1)+1}));function r(e,t,r){let i=0;for(let s of e)i=Math.max(n(s,t,r),i);return i}return r(e,0,0),t}(a),hiddenGroups:o}}function _(e,t){if(!e)return[[],0];let{level:n,lateralStart:r,lateralEnd:i}=e,s=r,o=[];for(;s{let i=e(...r);return i in n?n[i]:n[i]=t(...r)}}function C(e,t,n=null,r=0){let i=[];if(n)for(let s=0;s(0,s.n)("div",{className:"fc-timegrid-col-frame"},(0,s.n)("div",{className:"fc-timegrid-col-bg"},this.renderFillSegs(e.businessHourSegs,"non-business"),this.renderFillSegs(e.bgEventSegs,"bg-event"),this.renderFillSegs(e.dateSelectionSegs,"highlight")),(0,s.n)("div",{className:"fc-timegrid-col-events"},this.renderFgSegs(l,a,!1,!1,!1)),(0,s.n)("div",{className:"fc-timegrid-col-events"},this.renderFgSegs(o,{},Boolean(e.eventDrag),Boolean(e.eventResize),Boolean(r),"mirror")),(0,s.n)("div",{className:"fc-timegrid-now-indicator-container"},this.renderNowIndicator(e.nowIndicatorSegs)),(0,i.cm)(n)&&(0,s.n)(t,{elTag:"div",elClasses:["fc-timegrid-col-misc"]}))))}renderFgSegs(e,t,n,r,i,s){let{props:o}=this;return o.forPrint?k(e,o):this.renderPositionedFgSegs(e,t,n,r,i,s)}renderPositionedFgSegs(e,t,n,r,o,a){let{eventMaxStack:l,eventShortHeight:c,eventOrderStrict:u,eventMinHeight:d}=this.context.options,{date:h,slatCoords:f,eventSelection:p,todayRange:g,nowDate:m}=this.props,v=n||r||o,y=C(e,h,f,d),{segPlacements:b,hiddenGroups:D}=function(e,t,n,r){let i=[],s=[];for(let c=0;c{let{seg:l,rect:u}=e,d=l.eventRange.instance.instanceId,h=v||Boolean(!t[d]&&u),f=I(u&&u.span),y=!v&&u?this.computeSegHStyle(u):{left:0,right:0},b=Boolean(u)&&u.stackForward>0,D=Boolean(u)&&u.span.end-u.span.start{let d=I(e.span),h=(f=e.entries,p=t,f.map((e=>p[e.index])));var f,p;return(0,s.n)(D,{key:(0,i.bw)((0,i.cs)(h)),hiddenSegs:h,top:d.top,bottom:d.bottom,extraDateSpan:n,dateProfile:r,todayRange:o,nowDate:a,eventSelection:l,eventDrag:c,eventResize:u})})))}renderFillSegs(e,t){let{props:n,context:r}=this,o=C(e,n.date,n.slatCoords,r.options.eventMinHeight).map(((r,o)=>{let a=e[o];return(0,s.n)("div",{key:(0,i.bT)(a.eventRange),className:"fc-timegrid-bg-harness",style:I(r)},"bg-event"===t?(0,s.n)(i.cp,Object.assign({seg:a},(0,i.bS)(a,n.todayRange,n.nowDate))):(0,i.co)(t))}));return(0,s.n)(s.FK,null,o)}renderNowIndicator(e){let{slatCoords:t,date:n}=this.props;return t?e.map(((e,r)=>(0,s.n)(i.ck,{key:r,elClasses:["fc-timegrid-now-indicator-line"],elStyle:{top:t.computeDateTop(e.start,n)},isAxis:!1,date:n}))):null}computeSegHStyle(e){let t,n,{isRtl:r,options:i}=this.context,s=i.slotEventOverlap,o=e.levelCoord,a=e.levelCoord+e.thickness;s&&(a=Math.min(1,o+2*(a-o))),r?(t=1-a,n=o):(t=o,n=1-a);let l={zIndex:e.stackDepth+1,left:100*t+"%",right:100*n+"%"};return s&&!e.stackForward&&(l[r?"marginLeft":"marginRight"]=20),l}}function k(e,{todayRange:t,nowDate:n,eventSelection:r,eventDrag:o,eventResize:a}){let l=(o?o.affectedInstances:null)||(a?a.affectedInstances:null)||{};return(0,s.n)(s.FK,null,e.map((e=>{let o=e.eventRange.instance.instanceId;return(0,s.n)("div",{key:o,style:{visibility:l[o]?"hidden":""}},(0,s.n)(R,Object.assign({seg:e,isDragging:!1,isResizing:!1,isDateSelecting:!1,isSelected:o===r,isShort:!1},(0,i.bS)(e,t,n))))})))}function I(e){return e?{top:e.start,bottom:-e.end}:{top:"",bottom:""}}class M extends i.B{constructor(){super(...arguments),this.splitFgEventSegs=(0,i.z)(y),this.splitBgEventSegs=(0,i.z)(y),this.splitBusinessHourSegs=(0,i.z)(y),this.splitNowIndicatorSegs=(0,i.z)(y),this.splitDateSelectionSegs=(0,i.z)(y),this.splitEventDrag=(0,i.z)(b),this.splitEventResize=(0,i.z)(b),this.rootElRef=(0,s._3)(),this.cellElRefs=new i.cf}render(){let{props:e,context:t}=this,n=t.options.nowIndicator&&e.slatCoords&&e.slatCoords.safeComputeTop(e.nowDate),r=e.cells.length,o=this.splitFgEventSegs(e.fgEventSegs,r),a=this.splitBgEventSegs(e.bgEventSegs,r),l=this.splitBusinessHourSegs(e.businessHourSegs,r),c=this.splitNowIndicatorSegs(e.nowIndicatorSegs,r),u=this.splitDateSelectionSegs(e.dateSelectionSegs,r),d=this.splitEventDrag(e.eventDrag,r),h=this.splitEventResize(e.eventResize,r);return(0,s.n)("div",{className:"fc-timegrid-cols",ref:this.rootElRef},(0,s.n)("table",{role:"presentation",style:{minWidth:e.tableMinWidth,width:e.clientWidth}},e.tableColGroupNode,(0,s.n)("tbody",{role:"presentation"},(0,s.n)("tr",{role:"row"},e.axis&&(0,s.n)("td",{"aria-hidden":!0,className:"fc-timegrid-col fc-timegrid-axis"},(0,s.n)("div",{className:"fc-timegrid-col-frame"},(0,s.n)("div",{className:"fc-timegrid-now-indicator-container"},"number"==typeof n&&(0,s.n)(i.ck,{elClasses:["fc-timegrid-now-indicator-arrow"],elStyle:{top:n},isAxis:!0,date:e.nowDate})))),e.cells.map(((t,n)=>(0,s.n)(O,{key:t.key,elRef:this.cellElRefs.createRef(t.key),dateProfile:e.dateProfile,date:t.date,nowDate:e.nowDate,todayRange:e.todayRange,extraRenderProps:t.extraRenderProps,extraDataAttrs:t.extraDataAttrs,extraClassNames:t.extraClassNames,extraDateSpan:t.extraDateSpan,fgEventSegs:o[n],bgEventSegs:a[n],businessHourSegs:l[n],nowIndicatorSegs:c[n],dateSelectionSegs:u[n],eventDrag:d[n],eventResize:h[n],slatCoords:e.slatCoords,eventSelection:e.eventSelection,forPrint:e.forPrint})))))))}componentDidMount(){this.updateCoords()}componentDidUpdate(){this.updateCoords()}updateCoords(){let{props:e}=this;var t;e.onColCoords&&null!==e.clientWidth&&e.onColCoords(new i.ba(this.rootElRef.current,(t=this.cellElRefs.currentMap,e.cells.map((e=>t[e.key]))),!0,!1))}}class N extends i.be{constructor(){super(...arguments),this.processSlotOptions=(0,i.z)(P),this.state={slatCoords:null},this.handleRootEl=e=>{e?this.context.registerInteractiveComponent(this,{el:e,isHitComboAllowed:this.props.isHitComboAllowed}):this.context.unregisterInteractiveComponent(this)},this.handleScrollRequest=e=>{let{onScrollTopRequest:t}=this.props,{slatCoords:n}=this.state;if(t&&n){if(e.time){let r=n.computeTimeTop(e.time);r=Math.ceil(r),r&&(r+=1),t(r)}return!0}return!1},this.handleColCoords=e=>{this.colCoords=e},this.handleSlatCoords=e=>{this.setState({slatCoords:e}),this.props.onSlatCoords&&this.props.onSlatCoords(e)}}render(){let{props:e,state:t}=this;return(0,s.n)("div",{className:"fc-timegrid-body",ref:this.handleRootEl,style:{width:e.clientWidth,minWidth:e.tableMinWidth}},(0,s.n)(v,{axis:e.axis,dateProfile:e.dateProfile,slatMetas:e.slatMetas,clientWidth:e.clientWidth,minHeight:e.expandRows?e.clientHeight:"",tableMinWidth:e.tableMinWidth,tableColGroupNode:e.axis?e.tableColGroupNode:null,onCoords:this.handleSlatCoords}),(0,s.n)(M,{cells:e.cells,axis:e.axis,dateProfile:e.dateProfile,businessHourSegs:e.businessHourSegs,bgEventSegs:e.bgEventSegs,fgEventSegs:e.fgEventSegs,dateSelectionSegs:e.dateSelectionSegs,eventSelection:e.eventSelection,eventDrag:e.eventDrag,eventResize:e.eventResize,todayRange:e.todayRange,nowDate:e.nowDate,nowIndicatorSegs:e.nowIndicatorSegs,clientWidth:e.clientWidth,tableMinWidth:e.tableMinWidth,tableColGroupNode:e.tableColGroupNode,slatCoords:t.slatCoords,onColCoords:this.handleColCoords,forPrint:e.forPrint}))}componentDidMount(){this.scrollResponder=this.context.createScrollResponder(this.handleScrollRequest)}componentDidUpdate(e){this.scrollResponder.update(e.dateProfile!==this.props.dateProfile)}componentWillUnmount(){this.scrollResponder.detach()}queryHit(e,t){let{dateEnv:n,options:r}=this.context,{colCoords:s}=this,{dateProfile:o}=this.props,{slatCoords:a}=this.state,{snapDuration:l,snapsPerSlot:c}=this.processSlotOptions(this.props.slotDuration,r.snapDuration),u=s.leftToIndex(e),d=a.positions.topToIndex(t);if(null!=u&&null!=d){let e=this.props.cells[u],r=a.positions.tops[d],h=a.positions.getHeight(d),f=(t-r)/h,p=d*c+Math.floor(f*c),g=this.props.cells[u].date,m=(0,i.bp)(o.slotMinTime,(0,i.bo)(l,p)),v=n.add(g,m),y=n.add(v,l);return{dateProfile:o,dateSpan:Object.assign({range:{start:v,end:y},allDay:!1},e.extraDateSpan),dayEl:s.els[u],rect:{left:s.lefts[u],right:s.rights[u],top:r,bottom:r+h},layer:0}}return null}}function P(e,t){let n=t||e,r=(0,i.bt)(e,n);return null===r&&(n=e,r=1),{snapDuration:n,snapsPerSlot:r}}class B extends i.bW{sliceRange(e,t){let n=[];for(let r=0;r(0,s.n)(N,Object.assign({ref:this.timeColsRef},this.slicer.sliceProps(e,n,null,t,l),{forPrint:e.forPrint,axis:e.axis,dateProfile:n,slatMetas:e.slatMetas,slotDuration:e.slotDuration,cells:r.cells[0],tableColGroupNode:e.tableColGroupNode,tableMinWidth:e.tableMinWidth,clientWidth:e.clientWidth,clientHeight:e.clientHeight,expandRows:e.expandRows,nowDate:i,nowIndicatorSegs:o&&this.slicer.sliceNowDate(i,n,a,t,l),todayRange:c,onScrollTopRequest:e.onScrollTopRequest,onSlatCoords:e.onSlatCoords}))))}}function H(e,t,n){let r=[];for(let i of e.headerDates)r.push({start:n.add(i,t.slotMinTime),end:n.add(i,t.slotMaxTime)});return r}const Y=[{hours:1},{minutes:30},{minutes:15},{seconds:30},{seconds:15}];function U(e,t,n,r,s){let o=new Date(0),a=e,l=(0,i.d)(0),c=n||function(e){let t,n,r;for(t=Y.length-1;t>=0;t-=1)if(n=(0,i.d)(Y[t]),r=(0,i.bt)(n,e),null!==r&&r>1)return n;return e}(r),u=[];for(;(0,i.bs)(a)<(0,i.bs)(t);){let e=s.add(o,a),t=null!==(0,i.bt)(l,c);u.push({date:e,time:a,key:e.toISOString(),isoTimeStr:(0,i.bu)(e),isLabeled:t}),a=(0,i.bp)(a,r),l=(0,i.bp)(l,r)}return u}function j(e,t){let n=new i.bO(e.renderRange,t);return new i.bV(n,!1)}(0,i.cw)('.fc-v-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-v-event .fc-event-main{color:var(--fc-event-text-color);height:100%}.fc-v-event .fc-event-main-frame{display:flex;flex-direction:column;height:100%}.fc-v-event .fc-event-time{flex-grow:0;flex-shrink:0;max-height:100%;overflow:hidden}.fc-v-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-height:0}.fc-v-event .fc-event-title{bottom:0;max-height:100%;overflow:hidden;top:0}.fc-v-event:not(.fc-event-start){border-top-left-radius:0;border-top-right-radius:0;border-top-width:0}.fc-v-event:not(.fc-event-end){border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-width:0}.fc-v-event.fc-event-selected:before{left:-10px;right:-10px}.fc-v-event .fc-event-resizer-start{cursor:n-resize}.fc-v-event .fc-event-resizer-end{cursor:s-resize}.fc-v-event:not(.fc-event-selected) .fc-event-resizer{height:var(--fc-event-resizer-thickness);left:0;right:0}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-start{top:calc(var(--fc-event-resizer-thickness)/-2)}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-end{bottom:calc(var(--fc-event-resizer-thickness)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer{left:50%;margin-left:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer-start{top:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer-end{bottom:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc .fc-timegrid .fc-daygrid-body{z-index:2}.fc .fc-timegrid-divider{padding:0 0 2px}.fc .fc-timegrid-body{min-height:100%;position:relative;z-index:1}.fc .fc-timegrid-axis-chunk{position:relative}.fc .fc-timegrid-axis-chunk>table,.fc .fc-timegrid-slots{position:relative;z-index:1}.fc .fc-timegrid-slot{border-bottom:0;height:1.5em}.fc .fc-timegrid-slot:empty:before{content:"\\00a0"}.fc .fc-timegrid-slot-minor{border-top-style:dotted}.fc .fc-timegrid-slot-label-cushion{display:inline-block;white-space:nowrap}.fc .fc-timegrid-slot-label{vertical-align:middle}.fc .fc-timegrid-axis-cushion,.fc .fc-timegrid-slot-label-cushion{padding:0 4px}.fc .fc-timegrid-axis-frame-liquid{height:100%}.fc .fc-timegrid-axis-frame{align-items:center;display:flex;justify-content:flex-end;overflow:hidden}.fc .fc-timegrid-axis-cushion{flex-shrink:0;max-width:60px}.fc-direction-ltr .fc-timegrid-slot-label-frame{text-align:right}.fc-direction-rtl .fc-timegrid-slot-label-frame{text-align:left}.fc-liquid-hack .fc-timegrid-axis-frame-liquid{bottom:0;height:auto;left:0;position:absolute;right:0;top:0}.fc .fc-timegrid-col.fc-day-today{background-color:var(--fc-today-bg-color)}.fc .fc-timegrid-col-frame{min-height:100%;position:relative}.fc-media-screen.fc-liquid-hack .fc-timegrid-col-frame{bottom:0;height:auto;left:0;position:absolute;right:0;top:0}.fc-media-screen .fc-timegrid-cols{bottom:0;left:0;position:absolute;right:0;top:0}.fc-media-screen .fc-timegrid-cols>table{height:100%}.fc-media-screen .fc-timegrid-col-bg,.fc-media-screen .fc-timegrid-col-events,.fc-media-screen .fc-timegrid-now-indicator-container{left:0;position:absolute;right:0;top:0}.fc .fc-timegrid-col-bg{z-index:2}.fc .fc-timegrid-col-bg .fc-non-business{z-index:1}.fc .fc-timegrid-col-bg .fc-bg-event{z-index:2}.fc .fc-timegrid-col-bg .fc-highlight{z-index:3}.fc .fc-timegrid-bg-harness{left:0;position:absolute;right:0}.fc .fc-timegrid-col-events{z-index:3}.fc .fc-timegrid-now-indicator-container{bottom:0;overflow:hidden}.fc-direction-ltr .fc-timegrid-col-events{margin:0 2.5% 0 2px}.fc-direction-rtl .fc-timegrid-col-events{margin:0 2px 0 2.5%}.fc-timegrid-event-harness{position:absolute}.fc-timegrid-event-harness>.fc-timegrid-event{bottom:0;left:0;position:absolute;right:0;top:0}.fc-timegrid-event-harness-inset .fc-timegrid-event,.fc-timegrid-event.fc-event-mirror,.fc-timegrid-more-link{box-shadow:0 0 0 1px var(--fc-page-bg-color)}.fc-timegrid-event,.fc-timegrid-more-link{border-radius:3px;font-size:var(--fc-small-font-size)}.fc-timegrid-event{margin-bottom:1px}.fc-timegrid-event .fc-event-main{padding:1px 1px 0}.fc-timegrid-event .fc-event-time{font-size:var(--fc-small-font-size);margin-bottom:1px;white-space:nowrap}.fc-timegrid-event-short .fc-event-main-frame{flex-direction:row;overflow:hidden}.fc-timegrid-event-short .fc-event-time:after{content:"\\00a0-\\00a0"}.fc-timegrid-event-short .fc-event-title{font-size:var(--fc-small-font-size)}.fc-timegrid-more-link{background:var(--fc-more-link-bg-color);color:var(--fc-more-link-text-color);cursor:pointer;margin-bottom:1px;position:absolute;z-index:9999}.fc-timegrid-more-link-inner{padding:3px 2px;top:0}.fc-direction-ltr .fc-timegrid-more-link{right:0}.fc-direction-rtl .fc-timegrid-more-link{left:0}.fc .fc-timegrid-now-indicator-line{border-color:var(--fc-now-indicator-color);border-style:solid;border-width:1px 0 0;left:0;position:absolute;right:0;z-index:4}.fc .fc-timegrid-now-indicator-arrow{border-color:var(--fc-now-indicator-color);border-style:solid;margin-top:-5px;position:absolute;z-index:4}.fc-direction-ltr .fc-timegrid-now-indicator-arrow{border-bottom-color:transparent;border-top-color:transparent;border-width:5px 0 5px 6px;left:0}.fc-direction-rtl .fc-timegrid-now-indicator-arrow{border-bottom-color:transparent;border-top-color:transparent;border-width:5px 6px 5px 0;right:0}');const L={allDaySlot:Boolean};var W=(0,r.i1)({name:"@fullcalendar/timegrid",initialView:"timeGridWeek",optionRefiners:L,views:{timeGrid:{component:class extends f{constructor(){super(...arguments),this.buildTimeColsModel=(0,i.z)(j),this.buildSlatMetas=(0,i.z)(U)}render(){let{options:e,dateEnv:t,dateProfileGenerator:n}=this.context,{props:r}=this,{dateProfile:a}=r,l=this.buildTimeColsModel(a,n),c=this.allDaySplitter.splitProps(r),u=this.buildSlatMetas(a.slotMinTime,a.slotMaxTime,e.slotLabelInterval,e.slotDuration,t),{dayMinWidth:d}=e,h=!d,f=d,p=e.dayHeaders&&(0,s.n)(i.bK,{dates:l.headerDates,dateProfile:a,datesRepDistinctDays:!0,renderIntro:h?this.renderHeadAxis:null}),g=!1!==e.allDaySlot&&(t=>(0,s.n)(o.t7,Object.assign({},c.allDay,{dateProfile:a,dayTableModel:l,nextDayThreshold:e.nextDayThreshold,tableMinWidth:t.tableMinWidth,colGroupNode:t.tableColGroupNode,renderRowIntro:h?this.renderTableRowAxis:null,showWeekNumbers:!1,expandRows:!1,headerAlignElRef:this.headerElRef,clientWidth:t.clientWidth,clientHeight:t.clientHeight,forPrint:r.forPrint},this.getAllDayMaxEventProps()))),m=t=>(0,s.n)(z,Object.assign({},c.timed,{dayTableModel:l,dateProfile:a,axis:h,slotDuration:e.slotDuration,slatMetas:u,forPrint:r.forPrint,tableColGroupNode:t.tableColGroupNode,tableMinWidth:t.tableMinWidth,clientWidth:t.clientWidth,clientHeight:t.clientHeight,onSlatCoords:this.handleSlatCoords,expandRows:t.expandRows,onScrollTopRequest:this.handleScrollTopRequest}));return f?this.renderHScrollLayout(p,g,m,l.colCnt,d,u,this.state.slatCoords):this.renderSimpleLayout(p,g,m)}},usesMinMaxTime:!0,allDaySlot:!0,slotDuration:"00:30:00",slotEventOverlap:!0},timeGridDay:{type:"timeGrid",duration:{days:1}},timeGridWeek:{type:"timeGrid",duration:{weeks:1}}}})},28453:(e,t,n)=>{"use strict";n.d(t,{R:()=>o,x:()=>a});var r=n(96540);const i={},s=r.createContext(i);function o(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/20da611c.14fadce4.js b/assets/js/20da611c.14fadce4.js new file mode 100644 index 0000000000..0b844165c7 --- /dev/null +++ b/assets/js/20da611c.14fadce4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[17491],{80903:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"operating-scs/components/monitoring/docs/k3s","title":"K3s support","description":"K3s is a certified Kubernetes distribution optimized for production environments, particularly in remote locations","source":"@site/docs/04-operating-scs/components/monitoring/docs/k3s.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/k3s","permalink":"/docs/operating-scs/components/monitoring/docs/k3s","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/k3s.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"SCS deployment","permalink":"/docs/operating-scs/components/monitoring/docs/scs-deployment"},"next":{"title":"Infrastructure service endpoints","permalink":"/docs/operating-scs/components/monitoring/docs/infrastructure_services"}}');var o=s(74848),r=s(28453);const i={},a="K3s support",l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Prepare K3s Kubernetes cluster via K3d",id:"prepare-k3s-kubernetes-cluster-via-k3d",level:2},{value:"Deploy Observer monitoring solution",id:"deploy-observer-monitoring-solution",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"k3s-support",children:"K3s support"})}),"\n",(0,o.jsx)(n.p,{children:"K3s is a certified Kubernetes distribution optimized for production environments, particularly in remote locations\nor resource-constrained environments. Within the OSISM IaaS distribution, it serves as the management cluster,\naccommodating various management software. Our aim is to integrate the SCS Observability platform as an observer solution\nfor the IaaS layer. To achieve this, we deploy the SCS Observability solution within the IaaS k3s management cluster.\nThis setup enables us to monitor not only the management k3s cluster itself but also the surrounding IaaS control\nplane components."}),"\n",(0,o.jsx)(n.p,{children:"This page contains information on how to develop and/or test the Observer solution as a monitoring solution for a k3s\ncluster. It guides the user to create an HA k3s cluster via k3d (a wrapper to run k3s in Docker) and bootstrap\nit with the Observer solution."}),"\n",(0,o.jsxs)(n.p,{children:["Note that the following tutorial guides you to deploy an HA K3s cluster consisting of 3 control plane nodes (servers)\nand one worker node (agent). The reason is that the HA K3s cluster utilizes an embedded etcd cluster as cluster storage\n(refer to ",(0,o.jsx)(n.a,{href:"https://docs.k3s.io/datastore/ha-embedded",children:"https://docs.k3s.io/datastore/ha-embedded"}),") and the HA mode is also used in OSISM Testbed and productive bare\nmetal deployments.\nUsing a single-node K3s cluster that uses the SQLite database (default) requires additional tweaks of monitoring values,\nwhich are not covered in this guide."]}),"\n",(0,o.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://k3d.io/#installation",children:"K3d"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://helm.sh/",children:"helm"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://kubernetes.io/docs/reference/kubectl/",children:"kubectl"})}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"prepare-k3s-kubernetes-cluster-via-k3d",children:"Prepare K3s Kubernetes cluster via K3d"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"k3d cluster create --config k3s-config.yaml --image rancher/k3s:v1.28.8-k3s1 observer\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If you opt not to use K3D with the custom config we provided here, and prefer utilizing another Kubernetes cluster,\nensure that the metric endpoints for various control plane components are properly exposed.\nRefer to the ",(0,o.jsx)(n.a,{href:"https://dnationcloud.github.io/kubernetes-monitoring/helpers/FAQ/#kubernetes-monitoring-shows-or-0-state-for-some-control-plane-components-are-control-plane-components-working-correctly",children:"docs"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"deploy-observer-monitoring-solution",children:"Deploy Observer monitoring solution"}),"\n",(0,o.jsxs)(n.p,{children:["K3s consolidates all Kubernetes control plane components into a single process, which means that the metrics for these\ncontrol plane components are exposed on the K3d hosts rather than through individual Kubernetes Services/PODs.\nTo customize monitoring values for K3s, refer to the specific custom HELM values file ",(0,o.jsx)(n.code,{children:"values-observer-k3s.yaml"}),".\nThis file contains the necessary configurations and adjustments needed to monitor K3s.\nNote that list of control plane node IPs (endpoints) should be overridden."]}),"\n",(0,o.jsx)(n.p,{children:"Get and store the K3d control plane node IPs:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"NODE_IPS=$(kubectl get nodes -l node-role.kubernetes.io/control-plane=true -o jsonpath='{.items[*].status.addresses[?(@.type==\"InternalIP\")].address}' | tr ' ' ',' | sed 's/^/{&/;s/$/}/')\n"})}),"\n",(0,o.jsx)(n.p,{children:"Install the monitoring stack and set the control plane component endpoints"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/\nhelm repo update dnationcloud\nhelm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer-k3s.yaml \\\n --set "kube-prometheus-stack.kubeEtcd.endpoints=$NODE_IPS" \\\n --set "kube-prometheus-stack.kubeProxy.endpoints=$NODE_IPS" \\\n --set "kube-prometheus-stack.kubeControllerManager.endpoints=$NODE_IPS" \\\n --set "kube-prometheus-stack.kubeScheduler.endpoints=$NODE_IPS"\n'})}),"\n",(0,o.jsx)(n.h1,{id:"access-the-observer-monitoring-uis",children:"Access the Observer monitoring UIs"}),"\n",(0,o.jsx)(n.p,{children:"At this point, you should have the ability to access the Grafana, Alertmanager and Prometheus UIs\nwithin the Observer monitoring cluster."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Grafana UI"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"http://localhost:30000\n"})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Use the following credentials:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["username: ",(0,o.jsx)(n.code,{children:"admin"})]}),"\n",(0,o.jsxs)(n.li,{children:["password: ",(0,o.jsx)(n.code,{children:"pass"})]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Visit the Layer 0 dashboard, ",(0,o.jsx)(n.code,{children:"infrastructure-services-monitoring"}),", and drill down to explore cluster metrics"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"http://localhost:30000/d/monitoring/infrastructure-services-monitoring",children:"http://localhost:30000/d/monitoring/infrastructure-services-monitoring"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Alertmanager UI"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"http://localhost:30001\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Prometheus UI"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"http://localhost:30002\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const o={},r=t.createContext(o);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/21176.8b369431.js b/assets/js/21176.8b369431.js new file mode 100644 index 0000000000..8dbb76ffa9 --- /dev/null +++ b/assets/js/21176.8b369431.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[21176],{21176:(n,e,r)=>{r.d(e,{Zp:()=>Ce});var t=r(8058),o=r(5664),i=r(48585),u=r(39142),a=r(34098),d=r(74722),c=r(91395),f=r(697);class s{constructor(){var n={};n._next=n._prev=n,this._sentinel=n}dequeue(){var n=this._sentinel,e=n._prev;if(e!==n)return v(e),e}enqueue(n){var e=this._sentinel;n._prev&&n._next&&v(n),n._next=e._next,e._next._prev=n,e._next=n,n._prev=e}toString(){for(var n=[],e=this._sentinel,r=e._prev;r!==e;)n.push(JSON.stringify(r,g)),r=r._prev;return"["+n.join(", ")+"]"}}function v(n){n._prev._next=n._next,n._next._prev=n._prev,delete n._next,delete n._prev}function g(n,e){if("_next"!==n&&"_prev"!==n)return e}var h=u.A(1);function l(n,e){if(n.nodeCount()<=1)return[];var r=function(n,e){var r=new f.T,o=0,i=0;t.A(n.nodes(),(function(n){r.setNode(n,{v:n,in:0,out:0})})),t.A(n.edges(),(function(n){var t=r.edge(n.v,n.w)||0,u=e(n),a=t+u;r.setEdge(n.v,n.w,a),i=Math.max(i,r.node(n.v).out+=u),o=Math.max(o,r.node(n.w).in+=u)}));var u=c.A(i+o+3).map((function(){return new s})),a=o+1;return t.A(r.nodes(),(function(n){p(u,a,r.node(n))})),{graph:r,buckets:u,zeroIdx:a}}(n,e||h),o=function(n,e,r){var t,o=[],i=e[e.length-1],u=e[0];for(;n.nodeCount();){for(;t=u.dequeue();)A(n,e,r,t);for(;t=i.dequeue();)A(n,e,r,t);if(n.nodeCount())for(var a=e.length-2;a>0;--a)if(t=e[a].dequeue()){o=o.concat(A(n,e,r,t,!0));break}}return o}(r.graph,r.buckets,r.zeroIdx);return a.A(d.A(o,(function(e){return n.outEdges(e.v,e.w)})))}function A(n,e,r,o,i){var u=i?[]:void 0;return t.A(n.inEdges(o.v),(function(t){var o=n.edge(t),a=n.node(t.v);i&&u.push({v:t.v,w:t.w}),a.out-=o,p(e,r,a)})),t.A(n.outEdges(o.v),(function(t){var o=n.edge(t),i=t.w,u=n.node(i);u.in-=o,p(e,r,u)})),n.removeNode(o.v),u}function p(n,e,r){r.out?r.in?n[r.out-r.in+e].enqueue(r):n[n.length-1].enqueue(r):n[0].enqueue(r)}function w(n){var e="greedy"===n.graph().acyclicer?l(n,function(n){return function(e){return n.edge(e).weight}}(n)):function(n){var e=[],r={},o={};function u(a){i.A(o,a)||(o[a]=!0,r[a]=!0,t.A(n.outEdges(a),(function(n){i.A(r,n.w)?e.push(n):u(n.w)})),delete r[a])}return t.A(n.nodes(),u),e}(n);t.A(e,(function(e){var r=n.edge(e);n.removeEdge(e),r.forwardName=e.name,r.reversed=!0,n.setEdge(e.w,e.v,r,o.A("rev"))}))}var m=r(98879),b=r(81942),y=r(23068),x=r(61882);const k=function(n,e,r){for(var t=-1,o=n.length;++te};var N=r(29008);const _=function(n){return n&&n.length?k(n,N.A,E):void 0};const I=function(n){var e=null==n?0:n.length;return e?n[e-1]:void 0};var T=r(52528),R=r(79841),M=r(49574);const L=function(n,e){var r={};return e=(0,M.A)(e,3),(0,R.A)(n,(function(n,t,o){(0,T.A)(r,t,e(n,t,o))})),r};var C=r(69592);const O=function(n,e){return nMath.abs(u)*c?(a<0&&(c=-c),r=c*u/a,t=c):(u<0&&(d=-d),r=d,t=d*a/u),{x:o+r,y:i+t}}function B(n){var e=d.A(c.A(Y(n)+1),(function(){return[]}));return t.A(n.nodes(),(function(r){var t=n.node(r),o=t.rank;C.A(o)||(e[o][t.order]=r)})),e}function q(n,e,r,t){var o={width:0,height:0};return arguments.length>=4&&(o.rank=r,o.order=t),F(n,"border",o,e)}function Y(n){return _(d.A(n.nodes(),(function(e){var r=n.node(e).rank;if(!C.A(r))return r})))}function z(n,e){var r=j();try{return e()}finally{console.log(n+" time: "+(j()-r)+"ms")}}function D(n,e){return e()}function $(n,e,r,t,o,i){var u={width:0,height:0,rank:i,borderType:e},a=o[e][i-1],d=F(n,"border",u,r);o[e][i]=d,n.setParent(d,t),a&&n.setEdge(a,d,{weight:1})}function J(n){var e=n.graph().rankdir.toLowerCase();"bt"!==e&&"rl"!==e||function(n){t.A(n.nodes(),(function(e){K(n.node(e))})),t.A(n.edges(),(function(e){var r=n.edge(e);t.A(r.points,K),i.A(r,"y")&&K(r)}))}(n),"lr"!==e&&"rl"!==e||(!function(n){t.A(n.nodes(),(function(e){Q(n.node(e))})),t.A(n.edges(),(function(e){var r=n.edge(e);t.A(r.points,Q),i.A(r,"x")&&Q(r)}))}(n),Z(n))}function Z(n){t.A(n.nodes(),(function(e){H(n.node(e))})),t.A(n.edges(),(function(e){H(n.edge(e))}))}function H(n){var e=n.width;n.width=n.height,n.height=e}function K(n){n.y=-n.y}function Q(n){var e=n.x;n.x=n.y,n.y=e}function U(n){n.graph().dummyChains=[],t.A(n.edges(),(function(e){!function(n,e){var r,t,o,i=e.v,u=n.node(i).rank,a=e.w,d=n.node(a).rank,c=e.name,f=n.edge(e),s=f.labelRank;if(d===u+1)return;for(n.removeEdge(e),o=0,++u;u-1?o[i?e[u]:u]:void 0}};var cn=r(25707),fn=r(74342);const sn=function(n){var e=(0,fn.A)(n),r=e%1;return e==e?r?e-r:e:0};var vn=Math.max;const gn=dn((function(n,e,r){var t=null==n?0:n.length;if(!t)return-1;var o=null==r?0:sn(r);return o<0&&(o=vn(t+o,0)),(0,cn.A)(n,(0,M.A)(e,3),o)}));var hn=r(11662);u.A(1);u.A(1);r(69471),r(9779),r(88496);var ln=r(92049);r(53098);(0,r(70805).A)("length");RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]");var An="\\ud800-\\udfff",pn="["+An+"]",wn="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",mn="\\ud83c[\\udffb-\\udfff]",bn="[^"+An+"]",yn="(?:\\ud83c[\\udde6-\\uddff]){2}",xn="[\\ud800-\\udbff][\\udc00-\\udfff]",kn="(?:"+wn+"|"+mn+")"+"?",En="[\\ufe0e\\ufe0f]?",Nn=En+kn+("(?:\\u200d(?:"+[bn,yn,xn].join("|")+")"+En+kn+")*"),_n="(?:"+[bn+wn+"?",wn,yn,xn,pn].join("|")+")";RegExp(mn+"(?="+mn+")|"+_n+Nn,"g");function In(){}function Tn(n,e,r){ln.A(e)||(e=[e]);var o=(n.isDirected()?n.successors:n.neighbors).bind(n),i=[],u={};return t.A(e,(function(e){if(!n.hasNode(e))throw new Error("Graph does not have node: "+e);Rn(n,e,"post"===r,u,o,i)})),i}function Rn(n,e,r,o,u,a){i.A(o,e)||(o[e]=!0,r||a.push(e),t.A(u(e),(function(e){Rn(n,e,r,o,u,a)})),r&&a.push(e))}In.prototype=new Error;r(73046);function Mn(n){n=function(n){var e=(new f.T).setGraph(n.graph());return t.A(n.nodes(),(function(r){e.setNode(r,n.node(r))})),t.A(n.edges(),(function(r){var t=e.edge(r.v,r.w)||{weight:0,minlen:1},o=n.edge(r);e.setEdge(r.v,r.w,{weight:t.weight+o.weight,minlen:Math.max(t.minlen,o.minlen)})})),e}(n),X(n);var e,r=en(n);for(On(r),Ln(r,n);e=Sn(r);)Fn(r,n,e,jn(r,n,e))}function Ln(n,e){var r=function(n,e){return Tn(n,e,"post")}(n,n.nodes());r=r.slice(0,r.length-1),t.A(r,(function(r){!function(n,e,r){var t=n.node(r),o=t.parent;n.edge(r,o).cutvalue=Cn(n,e,r)}(n,e,r)}))}function Cn(n,e,r){var o=n.node(r).parent,i=!0,u=e.edge(r,o),a=0;return u||(i=!1,u=e.edge(o,r)),a=u.weight,t.A(e.nodeEdges(r),(function(t){var u,d,c=t.v===r,f=c?t.w:t.v;if(f!==o){var s=c===i,v=e.edge(t).weight;if(a+=s?v:-v,u=r,d=f,n.hasEdge(u,d)){var g=n.edge(r,f).cutvalue;a+=s?-g:g}}})),a}function On(n,e){arguments.length<2&&(e=n.nodes()[0]),Pn(n,{},1,e)}function Pn(n,e,r,o,u){var a=r,d=n.node(o);return e[o]=!0,t.A(n.neighbors(o),(function(t){i.A(e,t)||(r=Pn(n,e,r,t,o))})),d.low=a,d.lim=r++,u?d.parent=u:delete d.parent,r}function Sn(n){return gn(n.edges(),(function(e){return n.edge(e).cutvalue<0}))}function jn(n,e,r){var t=r.v,o=r.w;e.hasEdge(t,o)||(t=r.w,o=r.v);var i=n.node(t),u=n.node(o),a=i,d=!1;i.lim>u.lim&&(a=u,d=!0);var c=hn.A(e.edges(),(function(e){return d===Gn(n,n.node(e.v),a)&&d!==Gn(n,n.node(e.w),a)}));return W(c,(function(n){return nn(e,n)}))}function Fn(n,e,r,o){var i=r.v,u=r.w;n.removeEdge(i,u),n.setEdge(o.v,o.w,{}),On(n),Ln(n,e),function(n,e){var r=gn(n.nodes(),(function(n){return!e.node(n).parent})),o=function(n,e){return Tn(n,e,"pre")}(n,r);o=o.slice(1),t.A(o,(function(r){var t=n.node(r).parent,o=e.edge(r,t),i=!1;o||(o=e.edge(t,r),i=!0),e.node(r).rank=e.node(t).rank+(i?o.minlen:-o.minlen)}))}(n,e)}function Gn(n,e,r){return r.low<=e.lim&&e.lim<=r.lim}function Vn(n){switch(n.graph().ranker){case"network-simplex":default:qn(n);break;case"tight-tree":!function(n){X(n),en(n)}(n);break;case"longest-path":Bn(n)}}Mn.initLowLimValues=On,Mn.initCutValues=Ln,Mn.calcCutValue=Cn,Mn.leaveEdge=Sn,Mn.enterEdge=jn,Mn.exchangeEdges=Fn;var Bn=X;function qn(n){Mn(n)}var Yn=r(38207),zn=r(89463);function Dn(n){var e=F(n,"root",{},"_root"),r=function(n){var e={};function r(o,i){var u=n.children(o);u&&u.length&&t.A(u,(function(n){r(n,i+1)})),e[o]=i}return t.A(n.children(),(function(n){r(n,1)})),e}(n),o=_(Yn.A(r))-1,i=2*o+1;n.graph().nestingRoot=e,t.A(n.edges(),(function(e){n.edge(e).minlen*=i}));var u=function(n){return zn.A(n.edges(),(function(e,r){return e+n.edge(r).weight}),0)}(n)+1;t.A(n.children(),(function(t){$n(n,e,i,u,o,r,t)})),n.graph().nodeRankFactor=i}function $n(n,e,r,o,i,u,a){var d=n.children(a);if(d.length){var c=q(n,"_bt"),f=q(n,"_bb"),s=n.node(a);n.setParent(c,a),s.borderTop=c,n.setParent(f,a),s.borderBottom=f,t.A(d,(function(t){$n(n,e,r,o,i,u,t);var d=n.node(t),s=d.borderTop?d.borderTop:t,v=d.borderBottom?d.borderBottom:t,g=d.borderTop?o:2*o,h=s!==v?1:i-u[a]+1;n.setEdge(c,s,{weight:g,minlen:h,nestingEdge:!0}),n.setEdge(v,f,{weight:g,minlen:h,nestingEdge:!0})})),n.parent(a)||n.setEdge(e,c,{weight:0,minlen:i+u[a]})}else a!==e&&n.setEdge(e,a,{weight:0,minlen:r})}var Jn=r(91641);const Zn=function(n){return(0,Jn.A)(n,5)};function Hn(n,e,r){var u=function(n){var e;for(;n.hasNode(e=o.A("_root")););return e}(n),a=new f.T({compound:!0}).setGraph({root:u}).setDefaultNodeLabel((function(e){return n.node(e)}));return t.A(n.nodes(),(function(o){var d=n.node(o),c=n.parent(o);(d.rank===e||d.minRank<=e&&e<=d.maxRank)&&(a.setNode(o),a.setParent(o,c||u),t.A(n[r](o),(function(e){var r=e.v===o?e.w:e.v,t=a.edge(r,o),i=C.A(t)?0:t.weight;a.setEdge(r,o,{weight:n.edge(e).weight+i})})),i.A(d,"minRank")&&a.setNode(o,{borderLeft:d.borderLeft[e],borderRight:d.borderRight[e]}))})),a}var Kn=r(52851);const Qn=function(n,e,r){for(var t=-1,o=n.length,i=e.length,u={};++te||i&&u&&d&&!a&&!c||t&&u&&d||!r&&d||!o)return 1;if(!t&&!i&&!c&&n=a?d:d*("desc"==r[t]?-1:1)}return n.index-e.index};const ue=function(n,e,r){e=e.length?(0,Xn.A)(e,(function(n){return(0,ln.A)(n)?function(e){return(0,ne.A)(e,1===n.length?n[0]:n)}:n})):[N.A];var t=-1;e=(0,Xn.A)(e,(0,te.A)(M.A));var o=(0,ee.A)(n,(function(n,r,o){return{criteria:(0,Xn.A)(e,(function(e){return e(n)})),index:++t,value:n}}));return re(o,(function(n,e){return ie(n,e,r)}))};var ae=r(24326),de=r(6832);const ce=(0,ae.A)((function(n,e){if(null==n)return[];var r=e.length;return r>1&&(0,de.A)(n,e[0],e[1])?e=[]:r>2&&(0,de.A)(e[0],e[1],e[2])&&(e=[e[0]]),ue(n,(0,Wn.A)(e,1),[])}));function fe(n,e){for(var r=0,t=1;t0;)e%2&&(r+=f[e+1]),f[e=e-1>>1]+=n.weight;s+=n.weight*r}))),s}function ve(n,e){var r={};return t.A(n,(function(n,e){var t=r[n.v]={indegree:0,in:[],out:[],vs:[n.v],i:e};C.A(n.barycenter)||(t.barycenter=n.barycenter,t.weight=n.weight)})),t.A(e.edges(),(function(n){var e=r[n.v],t=r[n.w];C.A(e)||C.A(t)||(t.indegree++,e.out.push(r[n.w]))})),function(n){var e=[];function r(n){return function(e){e.merged||(C.A(e.barycenter)||C.A(n.barycenter)||e.barycenter>=n.barycenter)&&function(n,e){var r=0,t=0;n.weight&&(r+=n.barycenter*n.weight,t+=n.weight);e.weight&&(r+=e.barycenter*e.weight,t+=e.weight);n.vs=e.vs.concat(n.vs),n.barycenter=r/t,n.weight=t,n.i=Math.min(e.i,n.i),e.merged=!0}(n,e)}}function o(e){return function(r){r.in.push(e),0==--r.indegree&&n.push(r)}}for(;n.length;){var i=n.pop();e.push(i),t.A(i.in.reverse(),r(i)),t.A(i.out,o(i))}return d.A(hn.A(e,(function(n){return!n.merged})),(function(n){return b.A(n,["vs","i","barycenter","weight"])}))}(hn.A(r,(function(n){return!n.indegree})))}function ge(n,e){var r,o=function(n,e){var r={lhs:[],rhs:[]};return t.A(n,(function(n){e(n)?r.lhs.push(n):r.rhs.push(n)})),r}(n,(function(n){return i.A(n,"barycenter")})),u=o.lhs,d=ce(o.rhs,(function(n){return-n.i})),c=[],f=0,s=0,v=0;u.sort((r=!!e,function(n,e){return n.barycentere.barycenter?1:r?e.i-n.i:n.i-e.i})),v=he(c,d,v),t.A(u,(function(n){v+=n.vs.length,c.push(n.vs),f+=n.barycenter*n.weight,s+=n.weight,v=he(c,d,v)}));var g={vs:a.A(c)};return s&&(g.barycenter=f/s,g.weight=s),g}function he(n,e,r){for(var t;e.length&&(t=I(e)).i<=r;)e.pop(),n.push(t.vs),r++;return r}function le(n,e,r,o){var u=n.children(e),c=n.node(e),f=c?c.borderLeft:void 0,s=c?c.borderRight:void 0,v={};f&&(u=hn.A(u,(function(n){return n!==f&&n!==s})));var g=function(n,e){return d.A(e,(function(e){var r=n.inEdges(e);if(r.length){var t=zn.A(r,(function(e,r){var t=n.edge(r),o=n.node(r.v);return{sum:e.sum+t.weight*o.order,weight:e.weight+t.weight}}),{sum:0,weight:0});return{v:e,barycenter:t.sum/t.weight,weight:t.weight}}return{v:e}}))}(n,u);t.A(g,(function(e){if(n.children(e.v).length){var t=le(n,e.v,r,o);v[e.v]=t,i.A(t,"barycenter")&&(u=e,a=t,C.A(u.barycenter)?(u.barycenter=a.barycenter,u.weight=a.weight):(u.barycenter=(u.barycenter*u.weight+a.barycenter*a.weight)/(u.weight+a.weight),u.weight+=a.weight))}var u,a}));var h=ve(g,r);!function(n,e){t.A(n,(function(n){n.vs=a.A(n.vs.map((function(n){return e[n]?e[n].vs:n})))}))}(h,v);var l=ge(h,o);if(f&&(l.vs=a.A([f,l.vs,s]),n.predecessors(f).length)){var A=n.node(n.predecessors(f)[0]),p=n.node(n.predecessors(s)[0]);i.A(l,"barycenter")||(l.barycenter=0,l.weight=0),l.barycenter=(l.barycenter*l.weight+A.order+p.order)/(l.weight+2),l.weight+=2}return l}function Ae(n){var e=Y(n),r=pe(n,c.A(1,e+1),"inEdges"),o=pe(n,c.A(e-1,-1,-1),"outEdges"),u=function(n){var e={},r=hn.A(n.nodes(),(function(e){return!n.children(e).length})),o=_(d.A(r,(function(e){return n.node(e).rank}))),u=d.A(c.A(o+1),(function(){return[]})),a=ce(r,(function(e){return n.node(e).rank}));return t.A(a,(function r(o){if(!i.A(e,o)){e[o]=!0;var a=n.node(o);u[a.rank].push(o),t.A(n.successors(o),r)}})),u}(n);me(n,u);for(var a,f=Number.POSITIVE_INFINITY,s=0,v=0;v<4;++s,++v){we(s%2?r:o,s%4>=2);var g=fe(n,u=B(n));gd||c>e[o].lim));i=o,o=t;for(;(o=n.parent(o))!==i;)a.push(o);return{path:u.concat(a.reverse()),lca:i}}(n,e,o.v,o.w),u=i.path,a=i.lca,d=0,c=u[d],f=!0;r!==o.w;){if(t=n.node(r),f){for(;(c=u[d])!==a&&n.node(c).maxRankr){var t=e;e=r,r=t}var o=n[e];o||(n[e]=o={}),o[r]=!0}function Te(n,e,r){if(e>r){var t=e;e=r,r=t}return i.A(n[e],r)}function Re(n,e,r,o,u){var a={},d=function(n,e,r,o){var u=new f.T,a=n.graph(),d=function(n,e,r){return function(t,o,u){var a,d=t.node(o),c=t.node(u),f=0;if(f+=d.width/2,i.A(d,"labelpos"))switch(d.labelpos.toLowerCase()){case"l":a=-d.width/2;break;case"r":a=d.width/2}if(a&&(f+=r?a:-a),a=0,f+=(d.dummy?e:n)/2,f+=(c.dummy?e:n)/2,f+=c.width/2,i.A(c,"labelpos"))switch(c.labelpos.toLowerCase()){case"l":a=c.width/2;break;case"r":a=-c.width/2}return a&&(f+=r?a:-a),a=0,f}}(a.nodesep,a.edgesep,o);return t.A(e,(function(e){var o;t.A(e,(function(e){var t=r[e];if(u.setNode(t),o){var i=r[o],a=u.edge(i,t);u.setEdge(i,t,Math.max(d(n,e,o),a||0))}o=e}))})),u}(n,e,r,u),c=u?"borderLeft":"borderRight";function s(n,e){for(var r=d.nodes(),t=r.pop(),o={};t;)o[t]?n(t):(o[t]=!0,r.push(t),r=r.concat(e(t))),t=r.pop()}return s((function(n){a[n]=d.inEdges(n).reduce((function(n,e){return Math.max(n,a[e.v]+d.edge(e))}),0)}),d.predecessors.bind(d)),s((function(e){var r=d.outEdges(e).reduce((function(n,e){return Math.min(n,a[e.w]-d.edge(e))}),Number.POSITIVE_INFINITY),t=n.node(e);r!==Number.POSITIVE_INFINITY&&t.borderType!==c&&(a[e]=Math.max(a[e],r))}),d.successors.bind(d)),t.A(o,(function(n){a[n]=a[r[n]]})),a}function Me(n){var e,r=B(n),o=m.A(_e(n,r),function(n,e){var r={};function o(e,o,i,u,a){var d;t.A(c.A(o,i),(function(o){d=e[o],n.node(d).dummy&&t.A(n.predecessors(d),(function(e){var t=n.node(e);t.dummy&&(t.ordera)&&Ie(r,e,d)}))}))}return zn.A(e,(function(e,r){var i,u=-1,a=0;return t.A(r,(function(t,d){if("border"===n.node(t).dummy){var c=n.predecessors(t);c.length&&(i=n.node(c[0]).order,o(r,a,d,u,i),a=d,u=i)}o(r,a,r.length,i,e.length)})),r})),r}(n,r)),i={};t.A(["u","d"],(function(u){e="u"===u?r:Yn.A(r).reverse(),t.A(["l","r"],(function(r){"r"===r&&(e=d.A(e,(function(n){return Yn.A(n).reverse()})));var a=("u"===u?n.predecessors:n.successors).bind(n),c=function(n,e,r,o){var i={},u={},a={};return t.A(e,(function(n){t.A(n,(function(n,e){i[n]=n,u[n]=n,a[n]=e}))})),t.A(e,(function(n){var e=-1;t.A(n,(function(n){var t=o(n);if(t.length){t=ce(t,(function(n){return a[n]}));for(var d=(t.length-1)/2,c=Math.floor(d),f=Math.ceil(d);c<=f;++c){var s=t[c];u[n]===n&&e{r.d(e,{A:()=>i});var t=r(6240),o=r(38446);const i=function(n,e){var r=-1,i=(0,o.A)(n)?Array(n.length):[];return(0,t.A)(n,(function(n,t,o){i[++r]=e(n,t,o)})),i}},23068:(n,e,r)=>{r.d(e,{A:()=>c});var t=r(24326),o=r(66984),i=r(6832),u=r(55615),a=Object.prototype,d=a.hasOwnProperty;const c=(0,t.A)((function(n,e){n=Object(n);var r=-1,t=e.length,c=t>2?e[2]:void 0;for(c&&(0,i.A)(e[0],e[1],c)&&(t=1);++r{r.d(e,{A:()=>o});var t=r(13588);const o=function(n){return(null==n?0:n.length)?(0,t.A)(n,1):[]}},74722:(n,e,r)=>{r.d(e,{A:()=>a});var t=r(45572),o=r(49574),i=r(52568),u=r(92049);const a=function(n,e){return((0,u.A)(n)?t.A:i.A)(n,(0,o.A)(e,3))}},81942:(n,e,r)=>{r.d(e,{A:()=>A});var t=r(66318),o=r(52851),i=r(7819),u=r(25353),a=r(23149),d=r(30901);const c=function(n,e,r,t){if(!(0,a.A)(n))return n;for(var c=-1,f=(e=(0,i.A)(e,n)).length,s=f-1,v=n;null!=v&&++c{r.d(e,{A:()=>d});var t=Math.ceil,o=Math.max;const i=function(n,e,r,i){for(var u=-1,a=o(t((e-n)/(r||1)),0),d=Array(a);a--;)d[i?a:++u]=n,n+=r;return d};var u=r(6832),a=r(74342);const d=function(n){return function(e,r,t){return t&&"number"!=typeof t&&(0,u.A)(e,r,t)&&(r=t=void 0),e=(0,a.A)(e),void 0===r?(r=e,e=0):r=(0,a.A)(r),t=void 0===t?e{r.d(e,{A:()=>l});var t=/\s/;const o=function(n){for(var e=n.length;e--&&t.test(n.charAt(e)););return e};var i=/^\s+/;const u=function(n){return n?n.slice(0,o(n)+1).replace(i,""):n};var a=r(23149),d=r(61882),c=/^[-+]0x[0-9a-f]+$/i,f=/^0b[01]+$/i,s=/^0o[0-7]+$/i,v=parseInt;const g=function(n){if("number"==typeof n)return n;if((0,d.A)(n))return NaN;if((0,a.A)(n)){var e="function"==typeof n.valueOf?n.valueOf():n;n=(0,a.A)(e)?e+"":e}if("string"!=typeof n)return 0===n?n:+n;n=u(n);var r=f.test(n);return r||s.test(n)?v(n.slice(2),r?2:8):c.test(n)?NaN:+n};var h=1/0;const l=function(n){return n?(n=g(n))===h||n===-1/0?17976931348623157e292*(n<0?-1:1):n==n?n:0:0===n?n:0}},5664:(n,e,r)=>{r.d(e,{A:()=>i});var t=r(28894),o=0;const i=function(n){var e=++o;return(0,t.A)(n)+e}}}]); \ No newline at end of file diff --git a/assets/js/21689.e6a22cb4.js b/assets/js/21689.e6a22cb4.js new file mode 100644 index 0000000000..3d1120a4a0 --- /dev/null +++ b/assets/js/21689.e6a22cb4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[21689],{10646:(e,t,n)=>{n.d(t,{H:()=>l});var r=n(82933);function l(e,t){var n=e.append("foreignObject").attr("width","100000"),l=n.append("xhtml:div");l.attr("xmlns","http://www.w3.org/1999/xhtml");var o=t.label;switch(typeof o){case"function":l.insert(o);break;case"object":l.insert((function(){return o}));break;default:l.html(o)}r.AV(l,t.labelStyle),l.style("display","inline-block"),l.style("white-space","nowrap");var a=l.node().getBoundingClientRect();return n.attr("width",a.width).attr("height",a.height),n}},82933:(e,t,n)=>{n.d(t,{AV:()=>c,De:()=>o,c$:()=>p,gh:()=>a,nh:()=>d});var r=n(34963),l=n(89610);function o(e,t){return!!e.children(t).length}function a(e){return i(e.v)+":"+i(e.w)+":"+i(e.name)}var s=/:/g;function i(e){return e?String(e).replace(s,"\\:"):""}function c(e,t){t&&e.attr("style",t)}function d(e,t,n){t&&e.attr("class",t).attr("class",n+" "+e.attr("class"))}function p(e,t){var n=t.graph();if(r.A(n)){var o=n.transition;if(l.A(o))return o(e)}return e}},75937:(e,t,n)=>{n.d(t,{A:()=>o});var r=n(72453),l=n(74886);const o=(e,t)=>r.A.lang.round(l.A.parse(e)[t])},21689:(e,t,n)=>{n.d(t,{diagram:()=>a});var r=n(35860),l=n(35900),o=n(86079);n(26312),n(697),n(21176),n(14075),n(74353),n(16750),n(42838);const a={parser:r.p,db:r.f,renderer:l.f,styles:l.a,init:e=>{e.flowchart||(e.flowchart={}),e.flowchart.arrowMarkerAbsolute=e.arrowMarkerAbsolute,(0,o.p)({flowchart:{arrowMarkerAbsolute:e.arrowMarkerAbsolute}}),l.f.setConf(e.flowchart),r.f.clear(),r.f.setGen("gen-2")}}},35900:(e,t,n)=>{n.d(t,{a:()=>f,f:()=>w});var r=n(697),l=n(26312),o=n(86079),a=n(8995),s=n(10646),i=n(75937),c=n(25582);const d={},p=async function(e,t,n,r,l,a){const i=r.select(`[id="${n}"]`),c=Object.keys(e);for(const d of c){const n=e[d];let r="default";n.classes.length>0&&(r=n.classes.join(" ")),r+=" flowchart-label";const c=(0,o.k)(n.styles);let p,b=void 0!==n.text?n.text:n.id;if(o.l.info("vertex",n,n.labelType),"markdown"===n.labelType)o.l.info("vertex",n,n.labelType);else if((0,o.m)((0,o.c)().flowchart.htmlLabels)){const e={label:b};p=(0,s.H)(i,e).node(),p.parentNode.removeChild(p)}else{const e=l.createElementNS("http://www.w3.org/2000/svg","text");e.setAttribute("style",c.labelStyle.replace("color:","fill:"));const t=b.split(o.e.lineBreakRegex);for(const n of t){const t=l.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","1"),t.textContent=n,e.appendChild(t)}p=e}let w=0,f="";switch(n.type){case"round":w=5,f="rect";break;case"square":case"group":default:f="rect";break;case"diamond":f="question";break;case"hexagon":f="hexagon";break;case"odd":case"odd_right":f="rect_left_inv_arrow";break;case"lean_right":f="lean_right";break;case"lean_left":f="lean_left";break;case"trapezoid":f="trapezoid";break;case"inv_trapezoid":f="inv_trapezoid";break;case"circle":f="circle";break;case"ellipse":f="ellipse";break;case"stadium":f="stadium";break;case"subroutine":f="subroutine";break;case"cylinder":f="cylinder";break;case"doublecircle":f="doublecircle"}const h=await(0,o.r)(b,(0,o.c)());t.setNode(n.id,{labelStyle:c.labelStyle,shape:f,labelText:h,labelType:n.labelType,rx:w,ry:w,class:r,style:c.style,id:n.id,link:n.link,linkTarget:n.linkTarget,tooltip:a.db.getTooltip(n.id)||"",domId:a.db.lookUpDomId(n.id),haveCallback:n.haveCallback,width:"group"===n.type?500:void 0,dir:n.dir,type:n.type,props:n.props,padding:(0,o.c)().flowchart.padding}),o.l.info("setNode",{labelStyle:c.labelStyle,labelType:n.labelType,shape:f,labelText:h,rx:w,ry:w,class:r,style:c.style,id:n.id,domId:a.db.lookUpDomId(n.id),width:"group"===n.type?500:void 0,type:n.type,dir:n.dir,props:n.props,padding:(0,o.c)().flowchart.padding})}},b=async function(e,t,n){o.l.info("abc78 edges = ",e);let r,a,s=0,i={};if(void 0!==e.defaultStyle){const t=(0,o.k)(e.defaultStyle);r=t.style,a=t.labelStyle}for(const c of e){s++;const n="L-"+c.start+"-"+c.end;void 0===i[n]?(i[n]=0,o.l.info("abc78 new entry",n,i[n])):(i[n]++,o.l.info("abc78 new entry",n,i[n]));let p=n+"-"+i[n];o.l.info("abc78 new link id to be used is",n,p,i[n]);const b="LS-"+c.start,w="LE-"+c.end,f={style:"",labelStyle:""};switch(f.minlen=c.length||1,"arrow_open"===c.type?f.arrowhead="none":f.arrowhead="normal",f.arrowTypeStart="arrow_open",f.arrowTypeEnd="arrow_open",c.type){case"double_arrow_cross":f.arrowTypeStart="arrow_cross";case"arrow_cross":f.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":f.arrowTypeStart="arrow_point";case"arrow_point":f.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":f.arrowTypeStart="arrow_circle";case"arrow_circle":f.arrowTypeEnd="arrow_circle"}let h="",u="";switch(c.stroke){case"normal":h="fill:none;",void 0!==r&&(h=r),void 0!==a&&(u=a),f.thickness="normal",f.pattern="solid";break;case"dotted":f.thickness="normal",f.pattern="dotted",f.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":f.thickness="thick",f.pattern="solid",f.style="stroke-width: 3.5px;fill:none;";break;case"invisible":f.thickness="invisible",f.pattern="solid",f.style="stroke-width: 0;fill:none;"}if(void 0!==c.style){const e=(0,o.k)(c.style);h=e.style,u=e.labelStyle}f.style=f.style+=h,f.labelStyle=f.labelStyle+=u,void 0!==c.interpolate?f.curve=(0,o.n)(c.interpolate,l.lUB):void 0!==e.defaultInterpolate?f.curve=(0,o.n)(e.defaultInterpolate,l.lUB):f.curve=(0,o.n)(d.curve,l.lUB),void 0===c.text?void 0!==c.style&&(f.arrowheadStyle="fill: #333"):(f.arrowheadStyle="fill: #333",f.labelpos="c"),f.labelType=c.labelType,f.label=await(0,o.r)(c.text.replace(o.e.lineBreakRegex,"\n"),(0,o.c)()),void 0===c.style&&(f.style=f.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),f.labelStyle=f.labelStyle.replace("color:","fill:"),f.id=p,f.classes="flowchart-link "+b+" "+w,t.setEdge(c.start,c.end,f,s)}},w={setConf:function(e){const t=Object.keys(e);for(const n of t)d[n]=e[n]},addVertices:p,addEdges:b,getClasses:function(e,t){return t.db.getClasses()},draw:async function(e,t,n,s){o.l.info("Drawing flowchart");let i=s.db.getDirection();void 0===i&&(i="TD");const{securityLevel:c,flowchart:d}=(0,o.c)(),w=d.nodeSpacing||50,f=d.rankSpacing||50;let h;"sandbox"===c&&(h=(0,l.Ltv)("#i"+t));const u="sandbox"===c?(0,l.Ltv)(h.nodes()[0].contentDocument.body):(0,l.Ltv)("body"),g="sandbox"===c?h.nodes()[0].contentDocument:document,y=new r.T({multigraph:!0,compound:!0}).setGraph({rankdir:i,nodesep:w,ranksep:f,marginx:0,marginy:0}).setDefaultEdgeLabel((function(){return{}}));let k;const x=s.db.getSubGraphs();o.l.info("Subgraphs - ",x);for(let r=x.length-1;r>=0;r--)k=x[r],o.l.info("Subgraph - ",k),s.db.addVertex(k.id,{text:k.title,type:k.labelType},"group",void 0,k.classes,k.dir);const v=s.db.getVertices(),m=s.db.getEdges();o.l.info("Edges",m);let S=0;for(S=x.length-1;S>=0;S--){k=x[S],(0,l.Ubm)("cluster").append("text");for(let e=0;e`.label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .cluster-label text {\n fill: ${e.titleColor};\n }\n .cluster-label span,p {\n color: ${e.titleColor};\n }\n\n .label text,span,p {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .katex path {\n fill: #000;\n stroke: #000;\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${e.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${e.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${e.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${e.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${e.edgeLabelBackground};\n fill: ${e.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${((e,t)=>{const n=i.A,r=n(e,"r"),l=n(e,"g"),o=n(e,"b");return c.A(r,l,o,t)})(e.edgeLabelBackground,.5)};\n // background-color: \n }\n\n .cluster rect {\n fill: ${e.clusterBkg};\n stroke: ${e.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${e.titleColor};\n }\n\n .cluster span,p {\n color: ${e.titleColor};\n }\n /* .cluster div {\n color: ${e.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${e.fontFamily};\n font-size: 12px;\n background: ${e.tertiaryColor};\n border: 1px solid ${e.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n }\n`}}]); \ No newline at end of file diff --git a/assets/js/21987.d9c4f162.js b/assets/js/21987.d9c4f162.js new file mode 100644 index 0000000000..25ba53d7a8 --- /dev/null +++ b/assets/js/21987.d9c4f162.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[21987],{21987:(t,e,s)=>{s.d(e,{d:()=>D,p:()=>r,s:()=>_});var n=s(26312),i=s(86079),u=function(){var t=function(t,e,s,n){for(s=s||{},n=t.length;n--;s[t[n]]=e);return s},e=[1,17],s=[1,18],n=[1,19],i=[1,39],u=[1,40],r=[1,25],a=[1,23],c=[1,24],o=[1,31],l=[1,32],h=[1,33],A=[1,34],p=[1,35],d=[1,36],y=[1,26],E=[1,27],C=[1,28],m=[1,29],f=[1,43],b=[1,30],F=[1,42],g=[1,44],k=[1,41],T=[1,45],B=[1,9],D=[1,8,9],_=[1,56],S=[1,57],N=[1,58],L=[1,59],$=[1,60],v=[1,61],O=[1,62],x=[1,8,9,39],I=[1,74],R=[1,8,9,12,13,21,37,39,42,59,60,61,62,63,64,65,70,72],w=[1,8,9,12,13,19,21,37,39,42,46,59,60,61,62,63,64,65,70,72,74,80,95,97,98],P=[13,74,80,95,97,98],M=[13,64,65,74,80,95,97,98],G=[13,59,60,61,62,63,74,80,95,97,98],U=[1,93],z=[1,110],K=[1,108],Y=[1,102],j=[1,103],Q=[1,104],X=[1,105],W=[1,106],q=[1,107],H=[1,109],J=[1,8,9,37,39,42],V=[1,8,9,21],Z=[1,8,9,78],tt=[1,8,9,21,73,74,78,80,81,82,83,84,85],et={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statements:5,graphConfig:6,CLASS_DIAGRAM:7,NEWLINE:8,EOF:9,statement:10,classLabel:11,SQS:12,STR:13,SQE:14,namespaceName:15,alphaNumToken:16,className:17,classLiteralName:18,GENERICTYPE:19,relationStatement:20,LABEL:21,namespaceStatement:22,classStatement:23,memberStatement:24,annotationStatement:25,clickStatement:26,styleStatement:27,cssClassStatement:28,noteStatement:29,direction:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,namespaceIdentifier:36,STRUCT_START:37,classStatements:38,STRUCT_STOP:39,NAMESPACE:40,classIdentifier:41,STYLE_SEPARATOR:42,members:43,CLASS:44,ANNOTATION_START:45,ANNOTATION_END:46,MEMBER:47,SEPARATOR:48,relation:49,NOTE_FOR:50,noteText:51,NOTE:52,direction_tb:53,direction_bt:54,direction_rl:55,direction_lr:56,relationType:57,lineType:58,AGGREGATION:59,EXTENSION:60,COMPOSITION:61,DEPENDENCY:62,LOLLIPOP:63,LINE:64,DOTTED_LINE:65,CALLBACK:66,LINK:67,LINK_TARGET:68,CLICK:69,CALLBACK_NAME:70,CALLBACK_ARGS:71,HREF:72,STYLE:73,ALPHA:74,stylesOpt:75,CSSCLASS:76,style:77,COMMA:78,styleComponent:79,NUM:80,COLON:81,UNIT:82,SPACE:83,BRKT:84,PCT:85,commentToken:86,textToken:87,graphCodeTokens:88,textNoTagsToken:89,TAGSTART:90,TAGEND:91,"==":92,"--":93,DEFAULT:94,MINUS:95,keywords:96,UNICODE_TEXT:97,BQUOTE_STR:98,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",19:"GENERICTYPE",21:"LABEL",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",37:"STRUCT_START",39:"STRUCT_STOP",40:"NAMESPACE",42:"STYLE_SEPARATOR",44:"CLASS",45:"ANNOTATION_START",46:"ANNOTATION_END",47:"MEMBER",48:"SEPARATOR",50:"NOTE_FOR",52:"NOTE",53:"direction_tb",54:"direction_bt",55:"direction_rl",56:"direction_lr",59:"AGGREGATION",60:"EXTENSION",61:"COMPOSITION",62:"DEPENDENCY",63:"LOLLIPOP",64:"LINE",65:"DOTTED_LINE",66:"CALLBACK",67:"LINK",68:"LINK_TARGET",69:"CLICK",70:"CALLBACK_NAME",71:"CALLBACK_ARGS",72:"HREF",73:"STYLE",74:"ALPHA",76:"CSSCLASS",78:"COMMA",80:"NUM",81:"COLON",82:"UNIT",83:"SPACE",84:"BRKT",85:"PCT",88:"graphCodeTokens",90:"TAGSTART",91:"TAGEND",92:"==",93:"--",94:"DEFAULT",95:"MINUS",96:"keywords",97:"UNICODE_TEXT",98:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,2],[17,1],[17,1],[17,2],[17,2],[17,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[22,4],[22,5],[36,2],[38,1],[38,2],[38,3],[23,1],[23,3],[23,4],[23,6],[41,2],[41,3],[25,4],[43,1],[43,2],[24,1],[24,2],[24,1],[24,1],[20,3],[20,4],[20,4],[20,5],[29,3],[29,2],[30,1],[30,1],[30,1],[30,1],[49,3],[49,2],[49,2],[49,1],[57,1],[57,1],[57,1],[57,1],[57,1],[58,1],[58,1],[26,3],[26,4],[26,3],[26,4],[26,4],[26,5],[26,3],[26,4],[26,4],[26,5],[26,4],[26,5],[26,5],[26,6],[27,3],[28,3],[75,1],[75,3],[77,1],[77,2],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[86,1],[86,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[89,1],[89,1],[89,1],[89,1],[16,1],[16,1],[16,1],[16,1],[18,1],[51,1]],performAction:function(t,e,s,n,i,u,r){var a=u.length-1;switch(i){case 8:this.$=u[a-1];break;case 9:case 11:case 12:this.$=u[a];break;case 10:case 13:case 89:this.$=u[a-1]+u[a];break;case 14:case 15:this.$=u[a-1]+"~"+u[a]+"~";break;case 16:n.addRelation(u[a]);break;case 17:u[a-1].title=n.cleanupLabel(u[a]),n.addRelation(u[a-1]);break;case 27:this.$=u[a].trim(),n.setAccTitle(this.$);break;case 28:case 29:this.$=u[a].trim(),n.setAccDescription(this.$);break;case 30:n.addClassesToNamespace(u[a-3],u[a-1]);break;case 31:n.addClassesToNamespace(u[a-4],u[a-1]);break;case 32:this.$=u[a],n.addNamespace(u[a]);break;case 33:case 43:case 86:this.$=[u[a]];break;case 34:this.$=[u[a-1]];break;case 35:u[a].unshift(u[a-2]),this.$=u[a];break;case 37:n.setCssClass(u[a-2],u[a]);break;case 38:n.addMembers(u[a-3],u[a-1]);break;case 39:n.setCssClass(u[a-5],u[a-3]),n.addMembers(u[a-5],u[a-1]);break;case 40:this.$=u[a],n.addClass(u[a]);break;case 41:this.$=u[a-1],n.addClass(u[a-1]),n.setClassLabel(u[a-1],u[a]);break;case 42:n.addAnnotation(u[a],u[a-2]);break;case 44:u[a].push(u[a-1]),this.$=u[a];break;case 45:case 47:case 48:break;case 46:n.addMember(u[a-1],n.cleanupLabel(u[a]));break;case 49:this.$={id1:u[a-2],id2:u[a],relation:u[a-1],relationTitle1:"none",relationTitle2:"none"};break;case 50:this.$={id1:u[a-3],id2:u[a],relation:u[a-1],relationTitle1:u[a-2],relationTitle2:"none"};break;case 51:this.$={id1:u[a-3],id2:u[a],relation:u[a-2],relationTitle1:"none",relationTitle2:u[a-1]};break;case 52:this.$={id1:u[a-4],id2:u[a],relation:u[a-2],relationTitle1:u[a-3],relationTitle2:u[a-1]};break;case 53:n.addNote(u[a],u[a-1]);break;case 54:n.addNote(u[a]);break;case 55:n.setDirection("TB");break;case 56:n.setDirection("BT");break;case 57:n.setDirection("RL");break;case 58:n.setDirection("LR");break;case 59:this.$={type1:u[a-2],type2:u[a],lineType:u[a-1]};break;case 60:this.$={type1:"none",type2:u[a],lineType:u[a-1]};break;case 61:this.$={type1:u[a-1],type2:"none",lineType:u[a]};break;case 62:this.$={type1:"none",type2:"none",lineType:u[a]};break;case 63:this.$=n.relationType.AGGREGATION;break;case 64:this.$=n.relationType.EXTENSION;break;case 65:this.$=n.relationType.COMPOSITION;break;case 66:this.$=n.relationType.DEPENDENCY;break;case 67:this.$=n.relationType.LOLLIPOP;break;case 68:this.$=n.lineType.LINE;break;case 69:this.$=n.lineType.DOTTED_LINE;break;case 70:case 76:this.$=u[a-2],n.setClickEvent(u[a-1],u[a]);break;case 71:case 77:this.$=u[a-3],n.setClickEvent(u[a-2],u[a-1]),n.setTooltip(u[a-2],u[a]);break;case 72:this.$=u[a-2],n.setLink(u[a-1],u[a]);break;case 73:this.$=u[a-3],n.setLink(u[a-2],u[a-1],u[a]);break;case 74:this.$=u[a-3],n.setLink(u[a-2],u[a-1]),n.setTooltip(u[a-2],u[a]);break;case 75:this.$=u[a-4],n.setLink(u[a-3],u[a-2],u[a]),n.setTooltip(u[a-3],u[a-1]);break;case 78:this.$=u[a-3],n.setClickEvent(u[a-2],u[a-1],u[a]);break;case 79:this.$=u[a-4],n.setClickEvent(u[a-3],u[a-2],u[a-1]),n.setTooltip(u[a-3],u[a]);break;case 80:this.$=u[a-3],n.setLink(u[a-2],u[a]);break;case 81:this.$=u[a-4],n.setLink(u[a-3],u[a-1],u[a]);break;case 82:this.$=u[a-4],n.setLink(u[a-3],u[a-1]),n.setTooltip(u[a-3],u[a]);break;case 83:this.$=u[a-5],n.setLink(u[a-4],u[a-2],u[a]),n.setTooltip(u[a-4],u[a-1]);break;case 84:this.$=u[a-2],n.setCssStyle(u[a-1],u[a]);break;case 85:n.setCssClass(u[a-1],u[a]);break;case 87:u[a-2].push(u[a]),this.$=u[a-2]}},table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:37,17:20,18:38,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,31:e,33:s,35:n,36:21,40:i,41:22,44:u,45:r,47:a,48:c,50:o,52:l,53:h,54:A,55:p,56:d,66:y,67:E,69:C,73:m,74:f,76:b,80:F,95:g,97:k,98:T},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},t(B,[2,5],{8:[1,46]}),{8:[1,47]},t(D,[2,16],{21:[1,48]}),t(D,[2,18]),t(D,[2,19]),t(D,[2,20]),t(D,[2,21]),t(D,[2,22]),t(D,[2,23]),t(D,[2,24]),t(D,[2,25]),t(D,[2,26]),{32:[1,49]},{34:[1,50]},t(D,[2,29]),t(D,[2,45],{49:51,57:54,58:55,13:[1,52],21:[1,53],59:_,60:S,61:N,62:L,63:$,64:v,65:O}),{37:[1,63]},t(x,[2,36],{37:[1,65],42:[1,64]}),t(D,[2,47]),t(D,[2,48]),{16:66,74:f,80:F,95:g,97:k},{16:37,17:67,18:38,74:f,80:F,95:g,97:k,98:T},{16:37,17:68,18:38,74:f,80:F,95:g,97:k,98:T},{16:37,17:69,18:38,74:f,80:F,95:g,97:k,98:T},{74:[1,70]},{13:[1,71]},{16:37,17:72,18:38,74:f,80:F,95:g,97:k,98:T},{13:I,51:73},t(D,[2,55]),t(D,[2,56]),t(D,[2,57]),t(D,[2,58]),t(R,[2,11],{16:37,18:38,17:75,19:[1,76],74:f,80:F,95:g,97:k,98:T}),t(R,[2,12],{19:[1,77]}),{15:78,16:79,74:f,80:F,95:g,97:k},{16:37,17:80,18:38,74:f,80:F,95:g,97:k,98:T},t(w,[2,112]),t(w,[2,113]),t(w,[2,114]),t(w,[2,115]),t([1,8,9,12,13,19,21,37,39,42,59,60,61,62,63,64,65,70,72],[2,116]),t(B,[2,6],{10:5,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,17:20,36:21,41:22,16:37,18:38,5:81,31:e,33:s,35:n,40:i,44:u,45:r,47:a,48:c,50:o,52:l,53:h,54:A,55:p,56:d,66:y,67:E,69:C,73:m,74:f,76:b,80:F,95:g,97:k,98:T}),{5:82,10:5,16:37,17:20,18:38,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,31:e,33:s,35:n,36:21,40:i,41:22,44:u,45:r,47:a,48:c,50:o,52:l,53:h,54:A,55:p,56:d,66:y,67:E,69:C,73:m,74:f,76:b,80:F,95:g,97:k,98:T},t(D,[2,17]),t(D,[2,27]),t(D,[2,28]),{13:[1,84],16:37,17:83,18:38,74:f,80:F,95:g,97:k,98:T},{49:85,57:54,58:55,59:_,60:S,61:N,62:L,63:$,64:v,65:O},t(D,[2,46]),{58:86,64:v,65:O},t(P,[2,62],{57:87,59:_,60:S,61:N,62:L,63:$}),t(M,[2,63]),t(M,[2,64]),t(M,[2,65]),t(M,[2,66]),t(M,[2,67]),t(G,[2,68]),t(G,[2,69]),{8:[1,89],23:90,38:88,41:22,44:u},{16:91,74:f,80:F,95:g,97:k},{43:92,47:U},{46:[1,94]},{13:[1,95]},{13:[1,96]},{70:[1,97],72:[1,98]},{21:z,73:K,74:Y,75:99,77:100,79:101,80:j,81:Q,82:X,83:W,84:q,85:H},{74:[1,111]},{13:I,51:112},t(D,[2,54]),t(D,[2,117]),t(R,[2,13]),t(R,[2,14]),t(R,[2,15]),{37:[2,32]},{15:113,16:79,37:[2,9],74:f,80:F,95:g,97:k},t(J,[2,40],{11:114,12:[1,115]}),t(B,[2,7]),{9:[1,116]},t(V,[2,49]),{16:37,17:117,18:38,74:f,80:F,95:g,97:k,98:T},{13:[1,119],16:37,17:118,18:38,74:f,80:F,95:g,97:k,98:T},t(P,[2,61],{57:120,59:_,60:S,61:N,62:L,63:$}),t(P,[2,60]),{39:[1,121]},{23:90,38:122,41:22,44:u},{8:[1,123],39:[2,33]},t(x,[2,37],{37:[1,124]}),{39:[1,125]},{39:[2,43],43:126,47:U},{16:37,17:127,18:38,74:f,80:F,95:g,97:k,98:T},t(D,[2,70],{13:[1,128]}),t(D,[2,72],{13:[1,130],68:[1,129]}),t(D,[2,76],{13:[1,131],71:[1,132]}),{13:[1,133]},t(D,[2,84],{78:[1,134]}),t(Z,[2,86],{79:135,21:z,73:K,74:Y,80:j,81:Q,82:X,83:W,84:q,85:H}),t(tt,[2,88]),t(tt,[2,90]),t(tt,[2,91]),t(tt,[2,92]),t(tt,[2,93]),t(tt,[2,94]),t(tt,[2,95]),t(tt,[2,96]),t(tt,[2,97]),t(tt,[2,98]),t(D,[2,85]),t(D,[2,53]),{37:[2,10]},t(J,[2,41]),{13:[1,136]},{1:[2,4]},t(V,[2,51]),t(V,[2,50]),{16:37,17:137,18:38,74:f,80:F,95:g,97:k,98:T},t(P,[2,59]),t(D,[2,30]),{39:[1,138]},{23:90,38:139,39:[2,34],41:22,44:u},{43:140,47:U},t(x,[2,38]),{39:[2,44]},t(D,[2,42]),t(D,[2,71]),t(D,[2,73]),t(D,[2,74],{68:[1,141]}),t(D,[2,77]),t(D,[2,78],{13:[1,142]}),t(D,[2,80],{13:[1,144],68:[1,143]}),{21:z,73:K,74:Y,77:145,79:101,80:j,81:Q,82:X,83:W,84:q,85:H},t(tt,[2,89]),{14:[1,146]},t(V,[2,52]),t(D,[2,31]),{39:[2,35]},{39:[1,147]},t(D,[2,75]),t(D,[2,79]),t(D,[2,81]),t(D,[2,82],{68:[1,148]}),t(Z,[2,87],{79:135,21:z,73:K,74:Y,80:j,81:Q,82:X,83:W,84:q,85:H}),t(J,[2,8]),t(x,[2,39]),t(D,[2,83])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],78:[2,32],113:[2,10],116:[2,4],126:[2,44],139:[2,35]},parseError:function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},parse:function(t){var e=this,s=[0],n=[],i=[null],u=[],r=this.table,a="",c=0,o=0,l=u.slice.call(arguments,1),h=Object.create(this.lexer),A={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(A.yy[p]=this.yy[p]);h.setInput(t,A.yy),A.yy.lexer=h,A.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var d=h.yylloc;u.push(d);var y=h.options&&h.options.ranges;"function"==typeof A.yy.parseError?this.parseError=A.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var E,C,m,f,b,F,g,k,T,B={};;){if(C=s[s.length-1],this.defaultActions[C]?m=this.defaultActions[C]:(null==E&&(T=void 0,"number"!=typeof(T=n.pop()||h.lex()||1)&&(T instanceof Array&&(T=(n=T).pop()),T=e.symbols_[T]||T),E=T),m=r[C]&&r[C][E]),void 0===m||!m.length||!m[0]){var D="";for(b in k=[],r[C])this.terminals_[b]&&b>2&&k.push("'"+this.terminals_[b]+"'");D=h.showPosition?"Parse error on line "+(c+1)+":\n"+h.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[E]||E)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==E?"end of input":"'"+(this.terminals_[E]||E)+"'"),this.parseError(D,{text:h.match,token:this.terminals_[E]||E,line:h.yylineno,loc:d,expected:k})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+C+", token: "+E);switch(m[0]){case 1:s.push(E),i.push(h.yytext),u.push(h.yylloc),s.push(m[1]),E=null,o=h.yyleng,a=h.yytext,c=h.yylineno,d=h.yylloc;break;case 2:if(F=this.productions_[m[1]][1],B.$=i[i.length-F],B._$={first_line:u[u.length-(F||1)].first_line,last_line:u[u.length-1].last_line,first_column:u[u.length-(F||1)].first_column,last_column:u[u.length-1].last_column},y&&(B._$.range=[u[u.length-(F||1)].range[0],u[u.length-1].range[1]]),void 0!==(f=this.performAction.apply(B,[a,o,c,A.yy,m[1],i,u].concat(l))))return f;F&&(s=s.slice(0,-1*F*2),i=i.slice(0,-1*F),u=u.slice(0,-1*F)),s.push(this.productions_[m[1]][0]),i.push(B.$),u.push(B._$),g=r[s[s.length-2]][s[s.length-1]],s.push(g);break;case 3:return!0}}return!0}},st={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===n.length?this.yylloc.first_column:0)+n[n.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var s,n,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var u in i)this[u]=i[u];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,s,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),u=0;ue[0].length)){if(e=s,n=u,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,i[u])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,s,n){switch(s){case 0:return 53;case 1:return 54;case 2:return 55;case 3:return 56;case 4:case 5:case 14:case 30:case 35:case 39:case 46:break;case 6:return this.begin("acc_title"),31;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),33;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 19:case 22:case 24:case 57:case 60:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:case 34:return 8;case 15:case 16:return 7;case 17:case 36:case 44:return"EDGE_STATE";case 18:this.begin("callback_name");break;case 20:this.popState(),this.begin("callback_args");break;case 21:return 70;case 23:return 71;case 25:return"STR";case 26:this.begin("string");break;case 27:return 73;case 28:return this.begin("namespace"),40;case 29:case 38:return this.popState(),8;case 31:return this.begin("namespace-body"),37;case 32:case 42:return this.popState(),39;case 33:case 43:return"EOF_IN_STRUCT";case 37:return this.begin("class"),44;case 40:return this.popState(),this.popState(),39;case 41:return this.begin("class-body"),37;case 45:return"OPEN_IN_STRUCT";case 47:return"MEMBER";case 48:return 76;case 49:return 66;case 50:return 67;case 51:return 69;case 52:return 50;case 53:return 52;case 54:return 45;case 55:return 46;case 56:return 72;case 58:return"GENERICTYPE";case 59:this.begin("generic");break;case 61:return"BQUOTE_STR";case 62:this.begin("bqstring");break;case 63:case 64:case 65:case 66:return 68;case 67:case 68:return 60;case 69:case 70:return 62;case 71:return 61;case 72:return 59;case 73:return 63;case 74:return 64;case 75:return 65;case 76:return 21;case 77:return 42;case 78:return 95;case 79:return"DOT";case 80:return"PLUS";case 81:return 81;case 82:return 78;case 83:case 84:return 84;case 85:return 85;case 86:case 87:return"EQUALS";case 88:return 74;case 89:return 12;case 90:return 14;case 91:return"PUNCTUATION";case 92:return 80;case 93:return 97;case 94:case 95:return 83;case 96:return 9}},rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:\[\*\])/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:["])/,/^(?:[^"]*)/,/^(?:["])/,/^(?:style\b)/,/^(?:namespace\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:\[\*\])/,/^(?:class\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[}])/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\[\*\])/,/^(?:[{])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:note for\b)/,/^(?:note\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:href\b)/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:~)/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:[`])/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:\s*\(\))/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?::)/,/^(?:,)/,/^(?:#)/,/^(?:#)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:\[)/,/^(?:\])/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:\s)/,/^(?:$)/],conditions:{"namespace-body":{rules:[26,32,33,34,35,36,37,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},namespace:{rules:[26,28,29,30,31,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},"class-body":{rules:[26,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},class:{rules:[26,38,39,40,41,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},acc_descr_multiline:{rules:[11,12,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},acc_descr:{rules:[9,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},acc_title:{rules:[7,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},callback_args:{rules:[22,23,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},callback_name:{rules:[19,20,21,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},href:{rules:[26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},struct:{rules:[26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},generic:{rules:[26,48,49,50,51,52,53,54,55,56,57,58,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},bqstring:{rules:[26,48,49,50,51,52,53,54,55,56,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},string:{rules:[24,25,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,26,27,28,37,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96],inclusive:!0}}};function nt(){this.yy={}}return et.lexer=st,nt.prototype=et,et.Parser=nt,new nt}();u.parser=u;const r=u,a=["#","+","~","-",""];class c{constructor(t,e){this.memberType=e,this.visibility="",this.classifier="";const s=(0,i.d)(t,(0,i.c)());this.parseMember(s)}getDisplayDetails(){let t=this.visibility+(0,i.x)(this.id);"method"===this.memberType&&(t+=`(${(0,i.x)(this.parameters.trim())})`,this.returnType&&(t+=" : "+(0,i.x)(this.returnType))),t=t.trim();return{displayText:t,cssStyle:this.parseClassifier()}}parseMember(t){let e="";if("method"===this.memberType){const s=/([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/,n=t.match(s);if(n){const t=n[1]?n[1].trim():"";if(a.includes(t)&&(this.visibility=t),this.id=n[2].trim(),this.parameters=n[3]?n[3].trim():"",e=n[4]?n[4].trim():"",this.returnType=n[5]?n[5].trim():"",""===e){const t=this.returnType.substring(this.returnType.length-1);t.match(/[$*]/)&&(e=t,this.returnType=this.returnType.substring(0,this.returnType.length-1))}}}else{const s=t.length,n=t.substring(0,1),i=t.substring(s-1);a.includes(n)&&(this.visibility=n),i.match(/[$*]/)&&(e=i),this.id=t.substring(""===this.visibility?0:1,""===e?s:s-1)}this.classifier=e}parseClassifier(){switch(this.classifier){case"*":return"font-style:italic;";case"$":return"text-decoration:underline;";default:return""}}}const o="classId-";let l=[],h={},A=[],p=0,d={},y=0,E=[];const C=t=>i.e.sanitizeText(t,(0,i.c)()),m=function(t){const e=i.e.sanitizeText(t,(0,i.c)());let s="",n=e;if(e.indexOf("~")>0){const t=e.split("~");n=C(t[0]),s=C(t[1])}return{className:n,type:s}},f=function(t){const e=i.e.sanitizeText(t,(0,i.c)()),{className:s,type:n}=m(e);if(Object.hasOwn(h,s))return;const u=i.e.sanitizeText(s,(0,i.c)());h[u]={id:u,type:n,label:u,cssClasses:[],methods:[],members:[],annotations:[],styles:[],domId:o+u+"-"+p},p++},b=function(t){const e=i.e.sanitizeText(t,(0,i.c)());if(e in h)return h[e].domId;throw new Error("Class not found: "+e)},F=function(t,e){f(t);const s=m(t).className,n=h[s];if("string"==typeof e){const t=e.trim();t.startsWith("<<")&&t.endsWith(">>")?n.annotations.push(C(t.substring(2,t.length-2))):t.indexOf(")")>0?n.methods.push(new c(t,"method")):t&&n.members.push(new c(t,"attribute"))}},g=function(t,e){t.split(",").forEach((function(t){let s=t;t[0].match(/\d/)&&(s=o+s),void 0!==h[s]&&h[s].cssClasses.push(e)}))},k=function(t,e,s){const n=i.e.sanitizeText(t,(0,i.c)());if("loose"!==(0,i.c)().securityLevel)return;if(void 0===e)return;const u=n;if(void 0!==h[u]){const t=b(u);let n=[];if("string"==typeof s){n=s.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0);(0,n.Ltv)(this).classed("hover",!1)}))};E.push(T);let B="TB";const D={setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,getConfig:()=>(0,i.c)().class,addClass:f,bindFunctions:function(t){E.forEach((function(e){e(t)}))},clear:function(){l=[],h={},A=[],E=[],E.push(T),d={},y=0,(0,i.v)()},getClass:function(t){return h[t]},getClasses:function(){return h},getNotes:function(){return A},addAnnotation:function(t,e){const s=m(t).className;h[s].annotations.push(e)},addNote:function(t,e){const s={id:`note${A.length}`,class:e,text:t};A.push(s)},getRelations:function(){return l},addRelation:function(t){i.l.debug("Adding relation: "+JSON.stringify(t)),f(t.id1),f(t.id2),t.id1=m(t.id1).className,t.id2=m(t.id2).className,t.relationTitle1=i.e.sanitizeText(t.relationTitle1.trim(),(0,i.c)()),t.relationTitle2=i.e.sanitizeText(t.relationTitle2.trim(),(0,i.c)()),l.push(t)},getDirection:()=>B,setDirection:t=>{B=t},addMember:F,addMembers:function(t,e){Array.isArray(e)&&(e.reverse(),e.forEach((e=>F(t,e))))},cleanupLabel:function(t){return t.startsWith(":")&&(t=t.substring(1)),C(t.trim())},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3,LOLLIPOP:4},setClickEvent:function(t,e,s){t.split(",").forEach((function(t){k(t,e,s),h[t].haveCallback=!0})),g(t,"clickable")},setCssClass:g,setLink:function(t,e,s){const n=(0,i.c)();t.split(",").forEach((function(t){let u=t;t[0].match(/\d/)&&(u=o+u),void 0!==h[u]&&(h[u].link=i.u.formatUrl(e,n),"sandbox"===n.securityLevel?h[u].linkTarget="_top":h[u].linkTarget="string"==typeof s?C(s):"_blank")})),g(t,"clickable")},getTooltip:function(t,e){return e?d[e].classes[t].tooltip:h[t].tooltip},setTooltip:function(t,e){t.split(",").forEach((function(t){void 0!==e&&(h[t].tooltip=C(e))}))},lookUpDomId:b,setDiagramTitle:i.q,getDiagramTitle:i.t,setClassLabel:function(t,e){const s=i.e.sanitizeText(t,(0,i.c)());e&&(e=C(e));const{className:n}=m(s);h[n].label=e},addNamespace:function(t){void 0===d[t]&&(d[t]={id:t,classes:{},children:{},domId:o+t+"-"+y},y++)},addClassesToNamespace:function(t,e){if(void 0!==d[t])for(const s of e){const{className:e}=m(s);h[e].parent=t,d[t].classes[e]=h[e]}},getNamespace:function(t){return d[t]},getNamespaces:function(){return d},setCssStyle:function(t,e){const s=h[t];if(e&&s)for(const n of e)n.includes(",")?s.styles.push(...n.split(",")):s.styles.push(n)}},_=t=>`g.classGroup text {\n fill: ${t.nodeBorder||t.classText};\n stroke: none;\n font-family: ${t.fontFamily};\n font-size: 10px;\n\n .title {\n font-weight: bolder;\n }\n\n}\n\n.nodeLabel, .edgeLabel {\n color: ${t.classText};\n}\n.edgeLabel .label rect {\n fill: ${t.mainBkg};\n}\n.label text {\n fill: ${t.classText};\n}\n.edgeLabel .label span {\n background: ${t.mainBkg};\n}\n\n.classTitle {\n font-weight: bolder;\n}\n.node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n\n.divider {\n stroke: ${t.nodeBorder};\n stroke-width: 1;\n}\n\ng.clickable {\n cursor: pointer;\n}\n\ng.classGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.classGroup line {\n stroke: ${t.nodeBorder};\n stroke-width: 1;\n}\n\n.classLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.classLabel .label {\n fill: ${t.nodeBorder};\n font-size: 10px;\n}\n\n.relation {\n stroke: ${t.lineColor};\n stroke-width: 1;\n fill: none;\n}\n\n.dashed-line{\n stroke-dasharray: 3;\n}\n\n.dotted-line{\n stroke-dasharray: 1 2;\n}\n\n#compositionStart, .composition {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#compositionEnd, .composition {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionStart, .extension {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionEnd, .extension {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationStart, .aggregation {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationEnd, .aggregation {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopStart, .lollipop {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopEnd, .lollipop {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n.edgeTerminals {\n font-size: 11px;\n line-height: initial;\n}\n\n.classTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`}}]); \ No newline at end of file diff --git a/assets/js/22130.0233c4cc.js b/assets/js/22130.0233c4cc.js new file mode 100644 index 0000000000..f7deeab7f2 --- /dev/null +++ b/assets/js/22130.0233c4cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[22130],{22130:(e,t,r)=>{r.d(t,{default:()=>Ja});class a{constructor(e,t,r){this.lexer=void 0,this.start=void 0,this.end=void 0,this.lexer=e,this.start=t,this.end=r}static range(e,t){return t?e&&e.loc&&t.loc&&e.loc.lexer===t.loc.lexer?new a(e.loc.lexer,e.loc.start,t.loc.end):null:e&&e.loc}}class n{constructor(e,t){this.text=void 0,this.loc=void 0,this.noexpand=void 0,this.treatAsRelax=void 0,this.text=e,this.loc=t}range(e,t){return new n(t,a.range(this,e))}}class i{constructor(e,t){this.name=void 0,this.position=void 0,this.length=void 0,this.rawMessage=void 0;var r,a,n="KaTeX parse error: "+e,o=t&&t.loc;if(o&&o.start<=o.end){var s=o.lexer.input;r=o.start,a=o.end,r===s.length?n+=" at end of input: ":n+=" at position "+(r+1)+": ";var l=s.slice(r,a).replace(/[^]/g,"$&\u0332");n+=(r>15?"\u2026"+s.slice(r-15,r):s.slice(0,r))+l+(a+15":">","<":"<",'"':""","'":"'"},l=/[&><"']/g;var h=function e(t){return"ordgroup"===t.type||"color"===t.type?1===t.body.length?e(t.body[0]):t:"font"===t.type?e(t.body):t},m={contains:function(e,t){return-1!==e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(l,(e=>s[e]))},hyphenate:function(e){return e.replace(o,"-$1").toLowerCase()},getBaseElem:h,isCharacterBox:function(e){var t=h(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},protocolFromUrl:function(e){var t=/^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(e);return t?":"!==t[2]?null:/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(t[1])?t[1].toLowerCase():null:"_relative"}},c={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:e=>"#"+e},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(e,t)=>(t.push(e),t)},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:e=>Math.max(0,e),cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:e=>Math.max(0,e),cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:e=>Math.max(0,e),cli:"-e, --max-expand ",cliProcessor:e=>"Infinity"===e?1/0:parseInt(e)},globalGroup:{type:"boolean",cli:!1}};function p(e){if(e.default)return e.default;var t=e.type,r=Array.isArray(t)?t[0]:t;if("string"!=typeof r)return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}class u{constructor(e){for(var t in this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},c)if(c.hasOwnProperty(t)){var r=c[t];this[t]=void 0!==e[t]?r.processor?r.processor(e[t]):e[t]:p(r)}}reportNonstrict(e,t,r){var a=this.strict;if("function"==typeof a&&(a=a(e,t,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new i("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]")}}useStrictBehavior(e,t,r){var a=this.strict;if("function"==typeof a)try{a=a(e,t,r)}catch(n){a="error"}return!(!a||"ignore"===a)&&(!0===a||"error"===a||("warn"===a?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]"),!1)))}isTrusted(e){if(e.url&&!e.protocol){var t=m.protocolFromUrl(e.url);if(null==t)return!1;e.protocol=t}var r="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(r)}}class d{constructor(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}sup(){return g[f[this.id]]}sub(){return g[v[this.id]]}fracNum(){return g[b[this.id]]}fracDen(){return g[y[this.id]]}cramp(){return g[x[this.id]]}text(){return g[w[this.id]]}isTight(){return this.size>=2}}var g=[new d(0,0,!1),new d(1,0,!0),new d(2,1,!1),new d(3,1,!0),new d(4,2,!1),new d(5,2,!0),new d(6,3,!1),new d(7,3,!0)],f=[4,5,4,5,6,7,6,7],v=[5,5,5,5,7,7,7,7],b=[2,3,4,5,6,7,6,7],y=[3,3,5,5,7,7,7,7],x=[1,1,3,3,5,5,7,7],w=[0,1,2,3,2,3,2,3],k={DISPLAY:g[0],TEXT:g[2],SCRIPT:g[4],SCRIPTSCRIPT:g[6]},S=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];var M=[];function z(e){for(var t=0;t=M[t]&&e<=M[t+1])return!0;return!1}S.forEach((e=>e.blocks.forEach((e=>M.push(...e)))));var A=80,T={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"};class B{constructor(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(e){return m.contains(this.classes,e)}toNode(){for(var e=document.createDocumentFragment(),t=0;te.toText())).join("")}}var C={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}},N={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},q={"\xc5":"A","\xd0":"D","\xde":"o","\xe5":"a","\xf0":"d","\xfe":"o","\u0410":"A","\u0411":"B","\u0412":"B","\u0413":"F","\u0414":"A","\u0415":"E","\u0416":"K","\u0417":"3","\u0418":"N","\u0419":"N","\u041a":"K","\u041b":"N","\u041c":"M","\u041d":"H","\u041e":"O","\u041f":"N","\u0420":"P","\u0421":"C","\u0422":"T","\u0423":"y","\u0424":"O","\u0425":"X","\u0426":"U","\u0427":"h","\u0428":"W","\u0429":"W","\u042a":"B","\u042b":"X","\u042c":"B","\u042d":"3","\u042e":"X","\u042f":"R","\u0430":"a","\u0431":"b","\u0432":"a","\u0433":"r","\u0434":"y","\u0435":"e","\u0436":"m","\u0437":"e","\u0438":"n","\u0439":"n","\u043a":"n","\u043b":"n","\u043c":"m","\u043d":"n","\u043e":"o","\u043f":"n","\u0440":"p","\u0441":"c","\u0442":"o","\u0443":"y","\u0444":"b","\u0445":"x","\u0446":"n","\u0447":"n","\u0448":"w","\u0449":"w","\u044a":"a","\u044b":"m","\u044c":"a","\u044d":"e","\u044e":"m","\u044f":"r"};function I(e,t,r){if(!C[t])throw new Error("Font metrics not found for font: "+t+".");var a=e.charCodeAt(0),n=C[t][a];if(!n&&e[0]in q&&(a=q[e[0]].charCodeAt(0),n=C[t][a]),n||"text"!==r||z(a)&&(n=C[t][77]),n)return{depth:n[0],height:n[1],italic:n[2],skew:n[3],width:n[4]}}var R={};var H=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],O=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],E=function(e,t){return t.size<2?e:H[e-1][t.size-1]};class L{constructor(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||L.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=O[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}extend(e){var t={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return new L(t)}havingStyle(e){return this.style===e?this:this.extend({style:e,size:E(this.textSize,e)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:O[e-1]})}havingBaseStyle(e){e=e||this.style.text();var t=E(L.BASESIZE,e);return this.size===t&&this.textSize===L.BASESIZE&&this.style===e?this:this.extend({style:e,size:t})}havingBaseSizing(){var e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})}withColor(e){return this.extend({color:e})}withPhantom(){return this.extend({phantom:!0})}withFont(e){return this.extend({font:e})}withTextFontFamily(e){return this.extend({fontFamily:e,font:""})}withTextFontWeight(e){return this.extend({fontWeight:e,font:""})}withTextFontShape(e){return this.extend({fontShape:e,font:""})}sizingClasses(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==L.BASESIZE?["sizing","reset-size"+this.size,"size"+L.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=function(e){var t;if(!R[t=e>=5?0:e>=3?1:2]){var r=R[t]={cssEmPerMu:N.quad[t]/18};for(var a in N)N.hasOwnProperty(a)&&(r[a]=N[a][t])}return R[t]}(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}}L.BASESIZE=6;var D={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},V={ex:!0,em:!0,mu:!0},P=function(e){return"string"!=typeof e&&(e=e.unit),e in D||e in V||"ex"===e},F=function(e,t){var r;if(e.unit in D)r=D[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{var a;if(a=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=a.fontMetrics().xHeight;else{if("em"!==e.unit)throw new i("Invalid unit: '"+e.unit+"'");r=a.fontMetrics().quad}a!==t&&(r*=a.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},G=function(e){return+e.toFixed(4)+"em"},U=function(e){return e.filter((e=>e)).join(" ")},Y=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var a=t.getColor();a&&(this.style.color=a)}},X=function(e){var t=document.createElement(e);for(var r in t.className=U(this.classes),this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var a in this.attributes)this.attributes.hasOwnProperty(a)&&t.setAttribute(a,this.attributes[a]);for(var n=0;n"};class _{constructor(e,t,r,a){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,Y.call(this,e,r,a),this.children=t||[]}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return m.contains(this.classes,e)}toNode(){return X.call(this,"span")}toMarkup(){return W.call(this,"span")}}class j{constructor(e,t,r,a){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,Y.call(this,t,a),this.children=r||[],this.setAttribute("href",e)}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return m.contains(this.classes,e)}toNode(){return X.call(this,"a")}toMarkup(){return W.call(this,"a")}}class ${constructor(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}hasClass(e){return m.contains(this.classes,e)}toNode(){var e=document.createElement("img");for(var t in e.src=this.src,e.alt=this.alt,e.className="mord",this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e}toMarkup(){var e=''+m.escape(this.alt)+'=n[0]&&e<=n[1])return r.name}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=Z[this.text])}hasClass(e){return m.contains(this.classes,e)}toNode(){var e=document.createTextNode(this.text),t=null;for(var r in this.italic>0&&((t=document.createElement("span")).style.marginRight=G(this.italic)),this.classes.length>0&&((t=t||document.createElement("span")).className=U(this.classes)),this.style)this.style.hasOwnProperty(r)&&((t=t||document.createElement("span")).style[r]=this.style[r]);return t?(t.appendChild(e),t):e}toMarkup(){var e=!1,t="0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(a)&&(r+=m.hyphenate(a)+":"+this.style[a]+";");r&&(e=!0,t+=' style="'+m.escape(r)+'"');var n=m.escape(this.text);return e?(t+=">",t+=n,t+=""):n}}class J{constructor(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}toNode(){var e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(var r=0;r':''}}class ee{constructor(e){this.attributes=void 0,this.attributes=e||{}}toNode(){var e=document.createElementNS("http://www.w3.org/2000/svg","line");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e}toMarkup(){var e="","\\gt",!0),ie(oe,le,be,"\u2208","\\in",!0),ie(oe,le,be,"\ue020","\\@not"),ie(oe,le,be,"\u2282","\\subset",!0),ie(oe,le,be,"\u2283","\\supset",!0),ie(oe,le,be,"\u2286","\\subseteq",!0),ie(oe,le,be,"\u2287","\\supseteq",!0),ie(oe,he,be,"\u2288","\\nsubseteq",!0),ie(oe,he,be,"\u2289","\\nsupseteq",!0),ie(oe,le,be,"\u22a8","\\models"),ie(oe,le,be,"\u2190","\\leftarrow",!0),ie(oe,le,be,"\u2264","\\le"),ie(oe,le,be,"\u2264","\\leq",!0),ie(oe,le,be,"<","\\lt",!0),ie(oe,le,be,"\u2192","\\rightarrow",!0),ie(oe,le,be,"\u2192","\\to"),ie(oe,he,be,"\u2271","\\ngeq",!0),ie(oe,he,be,"\u2270","\\nleq",!0),ie(oe,le,ye,"\xa0","\\ "),ie(oe,le,ye,"\xa0","\\space"),ie(oe,le,ye,"\xa0","\\nobreakspace"),ie(se,le,ye,"\xa0","\\ "),ie(se,le,ye,"\xa0"," "),ie(se,le,ye,"\xa0","\\space"),ie(se,le,ye,"\xa0","\\nobreakspace"),ie(oe,le,ye,null,"\\nobreak"),ie(oe,le,ye,null,"\\allowbreak"),ie(oe,le,ve,",",","),ie(oe,le,ve,";",";"),ie(oe,he,ce,"\u22bc","\\barwedge",!0),ie(oe,he,ce,"\u22bb","\\veebar",!0),ie(oe,le,ce,"\u2299","\\odot",!0),ie(oe,le,ce,"\u2295","\\oplus",!0),ie(oe,le,ce,"\u2297","\\otimes",!0),ie(oe,le,xe,"\u2202","\\partial",!0),ie(oe,le,ce,"\u2298","\\oslash",!0),ie(oe,he,ce,"\u229a","\\circledcirc",!0),ie(oe,he,ce,"\u22a1","\\boxdot",!0),ie(oe,le,ce,"\u25b3","\\bigtriangleup"),ie(oe,le,ce,"\u25bd","\\bigtriangledown"),ie(oe,le,ce,"\u2020","\\dagger"),ie(oe,le,ce,"\u22c4","\\diamond"),ie(oe,le,ce,"\u22c6","\\star"),ie(oe,le,ce,"\u25c3","\\triangleleft"),ie(oe,le,ce,"\u25b9","\\triangleright"),ie(oe,le,fe,"{","\\{"),ie(se,le,xe,"{","\\{"),ie(se,le,xe,"{","\\textbraceleft"),ie(oe,le,pe,"}","\\}"),ie(se,le,xe,"}","\\}"),ie(se,le,xe,"}","\\textbraceright"),ie(oe,le,fe,"{","\\lbrace"),ie(oe,le,pe,"}","\\rbrace"),ie(oe,le,fe,"[","\\lbrack",!0),ie(se,le,xe,"[","\\lbrack",!0),ie(oe,le,pe,"]","\\rbrack",!0),ie(se,le,xe,"]","\\rbrack",!0),ie(oe,le,fe,"(","\\lparen",!0),ie(oe,le,pe,")","\\rparen",!0),ie(se,le,xe,"<","\\textless",!0),ie(se,le,xe,">","\\textgreater",!0),ie(oe,le,fe,"\u230a","\\lfloor",!0),ie(oe,le,pe,"\u230b","\\rfloor",!0),ie(oe,le,fe,"\u2308","\\lceil",!0),ie(oe,le,pe,"\u2309","\\rceil",!0),ie(oe,le,xe,"\\","\\backslash"),ie(oe,le,xe,"\u2223","|"),ie(oe,le,xe,"\u2223","\\vert"),ie(se,le,xe,"|","\\textbar",!0),ie(oe,le,xe,"\u2225","\\|"),ie(oe,le,xe,"\u2225","\\Vert"),ie(se,le,xe,"\u2225","\\textbardbl"),ie(se,le,xe,"~","\\textasciitilde"),ie(se,le,xe,"\\","\\textbackslash"),ie(se,le,xe,"^","\\textasciicircum"),ie(oe,le,be,"\u2191","\\uparrow",!0),ie(oe,le,be,"\u21d1","\\Uparrow",!0),ie(oe,le,be,"\u2193","\\downarrow",!0),ie(oe,le,be,"\u21d3","\\Downarrow",!0),ie(oe,le,be,"\u2195","\\updownarrow",!0),ie(oe,le,be,"\u21d5","\\Updownarrow",!0),ie(oe,le,ge,"\u2210","\\coprod"),ie(oe,le,ge,"\u22c1","\\bigvee"),ie(oe,le,ge,"\u22c0","\\bigwedge"),ie(oe,le,ge,"\u2a04","\\biguplus"),ie(oe,le,ge,"\u22c2","\\bigcap"),ie(oe,le,ge,"\u22c3","\\bigcup"),ie(oe,le,ge,"\u222b","\\int"),ie(oe,le,ge,"\u222b","\\intop"),ie(oe,le,ge,"\u222c","\\iint"),ie(oe,le,ge,"\u222d","\\iiint"),ie(oe,le,ge,"\u220f","\\prod"),ie(oe,le,ge,"\u2211","\\sum"),ie(oe,le,ge,"\u2a02","\\bigotimes"),ie(oe,le,ge,"\u2a01","\\bigoplus"),ie(oe,le,ge,"\u2a00","\\bigodot"),ie(oe,le,ge,"\u222e","\\oint"),ie(oe,le,ge,"\u222f","\\oiint"),ie(oe,le,ge,"\u2230","\\oiiint"),ie(oe,le,ge,"\u2a06","\\bigsqcup"),ie(oe,le,ge,"\u222b","\\smallint"),ie(se,le,ue,"\u2026","\\textellipsis"),ie(oe,le,ue,"\u2026","\\mathellipsis"),ie(se,le,ue,"\u2026","\\ldots",!0),ie(oe,le,ue,"\u2026","\\ldots",!0),ie(oe,le,ue,"\u22ef","\\@cdots",!0),ie(oe,le,ue,"\u22f1","\\ddots",!0),ie(oe,le,xe,"\u22ee","\\varvdots"),ie(oe,le,me,"\u02ca","\\acute"),ie(oe,le,me,"\u02cb","\\grave"),ie(oe,le,me,"\xa8","\\ddot"),ie(oe,le,me,"~","\\tilde"),ie(oe,le,me,"\u02c9","\\bar"),ie(oe,le,me,"\u02d8","\\breve"),ie(oe,le,me,"\u02c7","\\check"),ie(oe,le,me,"^","\\hat"),ie(oe,le,me,"\u20d7","\\vec"),ie(oe,le,me,"\u02d9","\\dot"),ie(oe,le,me,"\u02da","\\mathring"),ie(oe,le,de,"\ue131","\\@imath"),ie(oe,le,de,"\ue237","\\@jmath"),ie(oe,le,xe,"\u0131","\u0131"),ie(oe,le,xe,"\u0237","\u0237"),ie(se,le,xe,"\u0131","\\i",!0),ie(se,le,xe,"\u0237","\\j",!0),ie(se,le,xe,"\xdf","\\ss",!0),ie(se,le,xe,"\xe6","\\ae",!0),ie(se,le,xe,"\u0153","\\oe",!0),ie(se,le,xe,"\xf8","\\o",!0),ie(se,le,xe,"\xc6","\\AE",!0),ie(se,le,xe,"\u0152","\\OE",!0),ie(se,le,xe,"\xd8","\\O",!0),ie(se,le,me,"\u02ca","\\'"),ie(se,le,me,"\u02cb","\\`"),ie(se,le,me,"\u02c6","\\^"),ie(se,le,me,"\u02dc","\\~"),ie(se,le,me,"\u02c9","\\="),ie(se,le,me,"\u02d8","\\u"),ie(se,le,me,"\u02d9","\\."),ie(se,le,me,"\xb8","\\c"),ie(se,le,me,"\u02da","\\r"),ie(se,le,me,"\u02c7","\\v"),ie(se,le,me,"\xa8",'\\"'),ie(se,le,me,"\u02dd","\\H"),ie(se,le,me,"\u25ef","\\textcircled");var we={"--":!0,"---":!0,"``":!0,"''":!0};ie(se,le,xe,"\u2013","--",!0),ie(se,le,xe,"\u2013","\\textendash"),ie(se,le,xe,"\u2014","---",!0),ie(se,le,xe,"\u2014","\\textemdash"),ie(se,le,xe,"\u2018","`",!0),ie(se,le,xe,"\u2018","\\textquoteleft"),ie(se,le,xe,"\u2019","'",!0),ie(se,le,xe,"\u2019","\\textquoteright"),ie(se,le,xe,"\u201c","``",!0),ie(se,le,xe,"\u201c","\\textquotedblleft"),ie(se,le,xe,"\u201d","''",!0),ie(se,le,xe,"\u201d","\\textquotedblright"),ie(oe,le,xe,"\xb0","\\degree",!0),ie(se,le,xe,"\xb0","\\degree"),ie(se,le,xe,"\xb0","\\textdegree",!0),ie(oe,le,xe,"\xa3","\\pounds"),ie(oe,le,xe,"\xa3","\\mathsterling",!0),ie(se,le,xe,"\xa3","\\pounds"),ie(se,le,xe,"\xa3","\\textsterling",!0),ie(oe,he,xe,"\u2720","\\maltese"),ie(se,he,xe,"\u2720","\\maltese");for(var ke='0123456789/@."',Se=0;Se<14;Se++){var Me=ke.charAt(Se);ie(oe,le,xe,Me,Me)}for(var ze='0123456789!@*()-=+";:?/.,',Ae=0;Ae<25;Ae++){var Te=ze.charAt(Ae);ie(se,le,xe,Te,Te)}for(var Be="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Ce=0;Ce<52;Ce++){var Ne=Be.charAt(Ce);ie(oe,le,de,Ne,Ne),ie(se,le,xe,Ne,Ne)}ie(oe,he,xe,"C","\u2102"),ie(se,he,xe,"C","\u2102"),ie(oe,he,xe,"H","\u210d"),ie(se,he,xe,"H","\u210d"),ie(oe,he,xe,"N","\u2115"),ie(se,he,xe,"N","\u2115"),ie(oe,he,xe,"P","\u2119"),ie(se,he,xe,"P","\u2119"),ie(oe,he,xe,"Q","\u211a"),ie(se,he,xe,"Q","\u211a"),ie(oe,he,xe,"R","\u211d"),ie(se,he,xe,"R","\u211d"),ie(oe,he,xe,"Z","\u2124"),ie(se,he,xe,"Z","\u2124"),ie(oe,le,de,"h","\u210e"),ie(se,le,de,"h","\u210e");for(var qe="",Ie=0;Ie<52;Ie++){var Re=Be.charAt(Ie);ie(oe,le,de,Re,qe=String.fromCharCode(55349,56320+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56372+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56424+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56580+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56684+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56736+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56788+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56840+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56944+Ie)),ie(se,le,xe,Re,qe),Ie<26&&(ie(oe,le,de,Re,qe=String.fromCharCode(55349,56632+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56476+Ie)),ie(se,le,xe,Re,qe))}ie(oe,le,de,"k",qe=String.fromCharCode(55349,56668)),ie(se,le,xe,"k",qe);for(var He=0;He<10;He++){var Oe=He.toString();ie(oe,le,de,Oe,qe=String.fromCharCode(55349,57294+He)),ie(se,le,xe,Oe,qe),ie(oe,le,de,Oe,qe=String.fromCharCode(55349,57314+He)),ie(se,le,xe,Oe,qe),ie(oe,le,de,Oe,qe=String.fromCharCode(55349,57324+He)),ie(se,le,xe,Oe,qe),ie(oe,le,de,Oe,qe=String.fromCharCode(55349,57334+He)),ie(se,le,xe,Oe,qe)}for(var Ee="\xd0\xde\xfe",Le=0;Le<3;Le++){var De=Ee.charAt(Le);ie(oe,le,de,De,De),ie(se,le,xe,De,De)}var Ve=[["mathbf","textbf","Main-Bold"],["mathbf","textbf","Main-Bold"],["mathnormal","textit","Math-Italic"],["mathnormal","textit","Math-Italic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["mathscr","textscr","Script-Regular"],["","",""],["","",""],["","",""],["mathfrak","textfrak","Fraktur-Regular"],["mathfrak","textfrak","Fraktur-Regular"],["mathbb","textbb","AMS-Regular"],["mathbb","textbb","AMS-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathitsf","textitsf","SansSerif-Italic"],["mathitsf","textitsf","SansSerif-Italic"],["","",""],["","",""],["mathtt","texttt","Typewriter-Regular"],["mathtt","texttt","Typewriter-Regular"]],Pe=[["mathbf","textbf","Main-Bold"],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathtt","texttt","Typewriter-Regular"]],Fe=function(e,t,r){return ne[r][e]&&ne[r][e].replace&&(e=ne[r][e].replace),{value:e,metrics:I(e,t,r)}},Ge=function(e,t,r,a,n){var i,o=Fe(e,t,r),s=o.metrics;if(e=o.value,s){var l=s.italic;("text"===r||a&&"mathit"===a.font)&&(l=0),i=new K(e,s.height,s.depth,l,s.skew,s.width,n)}else"undefined"!=typeof console&&console.warn("No character metrics for '"+e+"' in style '"+t+"' and mode '"+r+"'"),i=new K(e,0,0,0,0,0,n);if(a){i.maxFontSize=a.sizeMultiplier,a.style.isTight()&&i.classes.push("mtight");var h=a.getColor();h&&(i.style.color=h)}return i},Ue=(e,t)=>{if(U(e.classes)!==U(t.classes)||e.skew!==t.skew||e.maxFontSize!==t.maxFontSize)return!1;if(1===e.classes.length){var r=e.classes[0];if("mbin"===r||"mord"===r)return!1}for(var a in e.style)if(e.style.hasOwnProperty(a)&&e.style[a]!==t.style[a])return!1;for(var n in t.style)if(t.style.hasOwnProperty(n)&&e.style[n]!==t.style[n])return!1;return!0},Ye=function(e){for(var t=0,r=0,a=0,n=0;nt&&(t=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>a&&(a=i.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=a},Xe=function(e,t,r,a){var n=new _(e,t,r,a);return Ye(n),n},We=(e,t,r,a)=>new _(e,t,r,a),_e=function(e){var t=new B(e);return Ye(t),t},je=function(e,t,r){var a="";switch(e){case"amsrm":a="AMS";break;case"textrm":a="Main";break;case"textsf":a="SansSerif";break;case"texttt":a="Typewriter";break;default:a=e}return a+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")},$e={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},Ze={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},Ke={fontMap:$e,makeSymbol:Ge,mathsym:function(e,t,r,a){return void 0===a&&(a=[]),"boldsymbol"===r.font&&Fe(e,"Main-Bold",t).metrics?Ge(e,"Main-Bold",t,r,a.concat(["mathbf"])):"\\"===e||"main"===ne[t][e].font?Ge(e,"Main-Regular",t,r,a):Ge(e,"AMS-Regular",t,r,a.concat(["amsrm"]))},makeSpan:Xe,makeSvgSpan:We,makeLineSpan:function(e,t,r){var a=Xe([e],[],t);return a.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),a.style.borderBottomWidth=G(a.height),a.maxFontSize=1,a},makeAnchor:function(e,t,r,a){var n=new j(e,t,r,a);return Ye(n),n},makeFragment:_e,wrapFragment:function(e,t){return e instanceof B?Xe([],[e],t):e},makeVList:function(e,t){for(var{children:r,depth:a}=function(e){if("individualShift"===e.positionType){for(var t=e.children,r=[t[0]],a=-t[0].shift-t[0].elem.depth,n=a,i=1;i0)return Ge(n,h,a,t,o.concat(m));if(l){var c,p;if("boldsymbol"===l){var u=function(e,t,r,a,n){return"textord"!==n&&Fe(e,"Math-BoldItalic",t).metrics?{fontName:"Math-BoldItalic",fontClass:"boldsymbol"}:{fontName:"Main-Bold",fontClass:"mathbf"}}(n,a,0,0,r);c=u.fontName,p=[u.fontClass]}else s?(c=$e[l].fontName,p=[l]):(c=je(l,t.fontWeight,t.fontShape),p=[l,t.fontWeight,t.fontShape]);if(Fe(n,c,a).metrics)return Ge(n,c,a,t,o.concat(p));if(we.hasOwnProperty(n)&&"Typewriter"===c.slice(0,10)){for(var d=[],g=0;g{var r=Xe(["mspace"],[],t),a=F(e,t);return r.style.marginRight=G(a),r},staticSvg:function(e,t){var[r,a,n]=Ze[e],i=new Q(r),o=new J([i],{width:G(a),height:G(n),style:"width:"+G(a),viewBox:"0 0 "+1e3*a+" "+1e3*n,preserveAspectRatio:"xMinYMin"}),s=We(["overlay"],[o],t);return s.height=n,s.style.height=G(n),s.style.width=G(a),s},svgData:Ze,tryCombineChars:e=>{for(var t=0;t{var r=t.classes[0],a=e.classes[0];"mbin"===r&&m.contains(pt,a)?t.classes[0]="mord":"mbin"===a&&m.contains(ct,r)&&(e.classes[0]="mord")}),{node:c},p,u),ft(n,((e,t)=>{var r=yt(t),a=yt(e),n=r&&a?e.hasClass("mtight")?rt[r][a]:tt[r][a]:null;if(n)return Ke.makeGlue(n,l)}),{node:c},p,u),n},ft=function e(t,r,a,n,i){n&&t.push(n);for(var o=0;or=>{t.splice(e+1,0,r),o++})(o)}}n&&t.pop()},vt=function(e){return e instanceof B||e instanceof j||e instanceof _&&e.hasClass("enclosing")?e:null},bt=function e(t,r){var a=vt(t);if(a){var n=a.children;if(n.length){if("right"===r)return e(n[n.length-1],"right");if("left"===r)return e(n[0],"left")}}return t},yt=function(e,t){return e?(t&&(e=bt(e,t)),dt[e.classes[0]]||null):null},xt=function(e,t){var r=["nulldelimiter"].concat(e.baseSizingClasses());return mt(t.concat(r))},wt=function(e,t,r){if(!e)return mt();if(nt[e.type]){var a=nt[e.type](e,t);if(r&&t.size!==r.size){a=mt(t.sizingClasses(r),[a],t);var n=t.sizeMultiplier/r.sizeMultiplier;a.height*=n,a.depth*=n}return a}throw new i("Got group of unknown type: '"+e.type+"'")};function kt(e,t){var r=mt(["base"],e,t),a=mt(["strut"]);return a.style.height=G(r.height+r.depth),r.depth&&(a.style.verticalAlign=G(-r.depth)),r.children.unshift(a),r}function St(e,t){var r=null;1===e.length&&"tag"===e[0].type&&(r=e[0].tag,e=e[0].body);var a,n=gt(e,t,"root");2===n.length&&n[1].hasClass("tag")&&(a=n.pop());for(var i,o=[],s=[],l=0;l0&&(o.push(kt(s,t)),s=[]),o.push(n[l]));s.length>0&&o.push(kt(s,t)),r?((i=kt(gt(r,t,!0))).classes=["tag"],o.push(i)):a&&o.push(a);var m=mt(["katex-html"],o);if(m.setAttribute("aria-hidden","true"),i){var c=i.children[0];c.style.height=G(m.height+m.depth),m.depth&&(c.style.verticalAlign=G(-m.depth))}return m}function Mt(e){return new B(e)}class zt{constructor(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}setAttribute(e,t){this.attributes[e]=t}getAttribute(e){return this.attributes[e]}toNode(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=U(this.classes));for(var r=0;r0&&(e+=' class ="'+m.escape(U(this.classes))+'"'),e+=">";for(var r=0;r"}toText(){return this.children.map((e=>e.toText())).join("")}}class At{constructor(e){this.text=void 0,this.text=e}toNode(){return document.createTextNode(this.text)}toMarkup(){return m.escape(this.toText())}toText(){return this.text}}var Tt={MathNode:zt,TextNode:At,SpaceNode:class{constructor(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?"\u200a":e>=.1666&&e<=.1667?"\u2009":e>=.2222&&e<=.2223?"\u2005":e>=.2777&&e<=.2778?"\u2005\u200a":e>=-.05556&&e<=-.05555?"\u200a\u2063":e>=-.1667&&e<=-.1666?"\u2009\u2063":e>=-.2223&&e<=-.2222?"\u205f\u2063":e>=-.2778&&e<=-.2777?"\u2005\u2063":null}toNode(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",G(this.width)),e}toMarkup(){return this.character?""+this.character+"":''}toText(){return this.character?this.character:" "}},newDocumentFragment:Mt},Bt=function(e,t,r){return!ne[t][e]||!ne[t][e].replace||55349===e.charCodeAt(0)||we.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.slice(4,6)||r.font&&"tt"===r.font.slice(4,6))||(e=ne[t][e].replace),new Tt.TextNode(e)},Ct=function(e){return 1===e.length?e[0]:new Tt.MathNode("mrow",e)},Nt=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";var r=t.font;if(!r||"mathnormal"===r)return null;var a=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var n=e.text;return m.contains(["\\imath","\\jmath"],n)?null:(ne[a][n]&&ne[a][n].replace&&(n=ne[a][n].replace),I(n,Ke.fontMap[r].fontName,a)?Ke.fontMap[r].variant:null)},qt=function(e,t,r){if(1===e.length){var a=Rt(e[0],t);return r&&a instanceof zt&&"mo"===a.type&&(a.setAttribute("lspace","0em"),a.setAttribute("rspace","0em")),[a]}for(var n,i=[],o=0;o0&&(m.text=m.text.slice(0,1)+"\u0338"+m.text.slice(1),i.pop())}}}i.push(s),n=s}return i},It=function(e,t,r){return Ct(qt(e,t,r))},Rt=function(e,t){if(!e)return new Tt.MathNode("mrow");if(it[e.type])return it[e.type](e,t);throw new i("Got group of unknown type: '"+e.type+"'")};function Ht(e,t,r,a,n){var i,o=qt(e,r);i=1===o.length&&o[0]instanceof zt&&m.contains(["mrow","mtable"],o[0].type)?o[0]:new Tt.MathNode("mrow",o);var s=new Tt.MathNode("annotation",[new Tt.TextNode(t)]);s.setAttribute("encoding","application/x-tex");var l=new Tt.MathNode("semantics",[i,s]),h=new Tt.MathNode("math",[l]);h.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),a&&h.setAttribute("display","block");var c=n?"katex":"katex-mathml";return Ke.makeSpan([c],[h])}var Ot=function(e){return new L({style:e.displayMode?k.DISPLAY:k.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},Et=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=Ke.makeSpan(r,[e])}return e},Lt={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},Dt={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Vt=function(e,t,r,a,n){var i,o=e.height+e.depth+r+a;if(/fbox|color|angl/.test(t)){if(i=Ke.makeSpan(["stretchy",t],[],n),"fbox"===t){var s=n.color&&n.getColor();s&&(i.style.borderColor=s)}}else{var l=[];/^[bx]cancel$/.test(t)&&l.push(new ee({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&l.push(new ee({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var h=new J(l,{width:"100%",height:G(o)});i=Ke.makeSvgSpan([],[h],n)}return i.height=o,i.style.height=G(o),i},Pt=function(e){var t=new Tt.MathNode("mo",[new Tt.TextNode(Lt[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},Ft=function(e,t){var{span:r,minWidth:a,height:n}=function(){var r=4e5,a=e.label.slice(1);if(m.contains(["widehat","widecheck","widetilde","utilde"],a)){var n,i,o,s="ordgroup"===(d=e.base).type?d.body.length:1;if(s>5)"widehat"===a||"widecheck"===a?(n=420,r=2364,o=.42,i=a+"4"):(n=312,r=2340,o=.34,i="tilde4");else{var l=[1,1,2,2,3,3][s];"widehat"===a||"widecheck"===a?(r=[0,1062,2364,2364,2364][l],n=[0,239,300,360,420][l],o=[0,.24,.3,.3,.36,.42][l],i=a+l):(r=[0,600,1033,2339,2340][l],n=[0,260,286,306,312][l],o=[0,.26,.286,.3,.306,.34][l],i="tilde"+l)}var h=new Q(i),c=new J([h],{width:"100%",height:G(o),viewBox:"0 0 "+r+" "+n,preserveAspectRatio:"none"});return{span:Ke.makeSvgSpan([],[c],t),minWidth:0,height:o}}var p,u,d,g=[],f=Dt[a],[v,b,y]=f,x=y/1e3,w=v.length;if(1===w)p=["hide-tail"],u=[f[3]];else if(2===w)p=["halfarrow-left","halfarrow-right"],u=["xMinYMin","xMaxYMin"];else{if(3!==w)throw new Error("Correct katexImagesData or update code here to support\n "+w+" children.");p=["brace-left","brace-center","brace-right"],u=["xMinYMin","xMidYMin","xMaxYMin"]}for(var k=0;k0&&(r.style.minWidth=G(a)),r};function Gt(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Ut(e){var t=Yt(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Yt(e){return e&&("atom"===e.type||ae.hasOwnProperty(e.type))?e:null}var Xt=(e,t)=>{var r,a,n;e&&"supsub"===e.type?(r=(a=Gt(e.base,"accent")).base,e.base=r,n=function(e){if(e instanceof _)return e;throw new Error("Expected span but got "+String(e)+".")}(wt(e,t)),e.base=a):r=(a=Gt(e,"accent")).base;var i=wt(r,t.havingCrampedStyle()),o=0;if(a.isShifty&&m.isCharacterBox(r)){var s=m.getBaseElem(r);o=te(wt(s,t.havingCrampedStyle())).skew}var l,h="\\c"===a.label,c=h?i.height+i.depth:Math.min(i.height,t.fontMetrics().xHeight);if(a.isStretchy)l=Ft(a,t),l=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:l,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+G(2*o)+")",marginLeft:G(2*o)}:void 0}]},t);else{var p,u;"\\vec"===a.label?(p=Ke.staticSvg("vec",t),u=Ke.svgData.vec[1]):((p=te(p=Ke.makeOrd({mode:a.mode,text:a.label},t,"textord"))).italic=0,u=p.width,h&&(c+=p.depth)),l=Ke.makeSpan(["accent-body"],[p]);var d="\\textcircled"===a.label;d&&(l.classes.push("accent-full"),c=i.height);var g=o;d||(g-=u/2),l.style.left=G(g),"\\textcircled"===a.label&&(l.style.top=".2em"),l=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-c},{type:"elem",elem:l}]},t)}var f=Ke.makeSpan(["mord","accent"],[l],t);return n?(n.children[0]=f,n.height=Math.max(f.height,n.height),n.classes[0]="mord",n):f},Wt=(e,t)=>{var r=e.isStretchy?Pt(e.label):new Tt.MathNode("mo",[Bt(e.label,e.mode)]),a=new Tt.MathNode("mover",[Rt(e.base,t),r]);return a.setAttribute("accent","true"),a},_t=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map((e=>"\\"+e)).join("|"));ot({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:(e,t)=>{var r=lt(t[0]),a=!_t.test(e.funcName),n=!a||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:a,isShifty:n,base:r}},htmlBuilder:Xt,mathmlBuilder:Wt}),ot({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:(e,t)=>{var r=t[0],a=e.parser.mode;return"math"===a&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),a="text"),{type:"accent",mode:a,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Xt,mathmlBuilder:Wt}),ot({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0];return{type:"accentUnder",mode:r.mode,label:a,base:n}},htmlBuilder:(e,t)=>{var r=wt(e.base,t),a=Ft(e,t),n="\\utilde"===e.label?.12:0,i=Ke.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:a,wrapperClasses:["svg-align"]},{type:"kern",size:n},{type:"elem",elem:r}]},t);return Ke.makeSpan(["mord","accentunder"],[i],t)},mathmlBuilder:(e,t)=>{var r=Pt(e.label),a=new Tt.MathNode("munder",[Rt(e.base,t),r]);return a.setAttribute("accentunder","true"),a}});var jt=e=>{var t=new Tt.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};ot({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){var{parser:a,funcName:n}=e;return{type:"xArrow",mode:a.mode,label:n,body:t[0],below:r[0]}},htmlBuilder(e,t){var r,a=t.style,n=t.havingStyle(a.sup()),i=Ke.wrapFragment(wt(e.body,n,t),t),o="\\x"===e.label.slice(0,2)?"x":"cd";i.classes.push(o+"-arrow-pad"),e.below&&(n=t.havingStyle(a.sub()),(r=Ke.wrapFragment(wt(e.below,n,t),t)).classes.push(o+"-arrow-pad"));var s,l=Ft(e,t),h=-t.fontMetrics().axisHeight+.5*l.height,m=-t.fontMetrics().axisHeight-.5*l.height-.111;if((i.depth>.25||"\\xleftequilibrium"===e.label)&&(m-=i.depth),r){var c=-t.fontMetrics().axisHeight+r.height+.5*l.height+.111;s=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h},{type:"elem",elem:r,shift:c}]},t)}else s=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h}]},t);return s.children[0].children[0].children[1].classes.push("svg-align"),Ke.makeSpan(["mrel","x-arrow"],[s],t)},mathmlBuilder(e,t){var r,a=Pt(e.label);if(a.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){var n=jt(Rt(e.body,t));if(e.below){var i=jt(Rt(e.below,t));r=new Tt.MathNode("munderover",[a,i,n])}else r=new Tt.MathNode("mover",[a,n])}else if(e.below){var o=jt(Rt(e.below,t));r=new Tt.MathNode("munder",[a,o])}else r=jt(),r=new Tt.MathNode("mover",[a,r]);return r}});var $t=Ke.makeSpan;function Zt(e,t){var r=gt(e.body,t,!0);return $t([e.mclass],r,t)}function Kt(e,t){var r,a=qt(e.body,t);return"minner"===e.mclass?r=new Tt.MathNode("mpadded",a):"mord"===e.mclass?e.isCharacterBox?(r=a[0]).type="mi":r=new Tt.MathNode("mi",a):(e.isCharacterBox?(r=a[0]).type="mo":r=new Tt.MathNode("mo",a),"mbin"===e.mclass?(r.attributes.lspace="0.22em",r.attributes.rspace="0.22em"):"mpunct"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0.17em"):"mopen"===e.mclass||"mclose"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0em"):"minner"===e.mclass&&(r.attributes.lspace="0.0556em",r.attributes.width="+0.1111em")),r}ot({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];return{type:"mclass",mode:r.mode,mclass:"m"+a.slice(5),body:ht(n),isCharacterBox:m.isCharacterBox(n)}},htmlBuilder:Zt,mathmlBuilder:Kt});var Jt=e=>{var t="ordgroup"===e.type&&e.body.length?e.body[0]:e;return"atom"!==t.type||"bin"!==t.family&&"rel"!==t.family?"mord":"m"+t.family};ot({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(e,t){var{parser:r}=e;return{type:"mclass",mode:r.mode,mclass:Jt(t[0]),body:ht(t[1]),isCharacterBox:m.isCharacterBox(t[1])}}}),ot({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(e,t){var r,{parser:a,funcName:n}=e,i=t[1],o=t[0];r="\\stackrel"!==n?Jt(i):"mrel";var s={type:"op",mode:i.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:"\\stackrel"!==n,body:ht(i)},l={type:"supsub",mode:o.mode,base:s,sup:"\\underset"===n?null:o,sub:"\\underset"===n?o:null};return{type:"mclass",mode:a.mode,mclass:r,body:[l],isCharacterBox:m.isCharacterBox(l)}},htmlBuilder:Zt,mathmlBuilder:Kt}),ot({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"pmb",mode:r.mode,mclass:Jt(t[0]),body:ht(t[0])}},htmlBuilder(e,t){var r=gt(e.body,t,!0),a=Ke.makeSpan([e.mclass],r,t);return a.style.textShadow="0.02em 0.01em 0.04px",a},mathmlBuilder(e,t){var r=qt(e.body,t),a=new Tt.MathNode("mstyle",r);return a.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),a}});var Qt={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},er=e=>"textord"===e.type&&"@"===e.text;function tr(e,t,r){var a=Qt[e];switch(a){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(a,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":var n={type:"atom",text:a,mode:"math",family:"rel"},i={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[n],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[i],[]);case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":return r.callFunction("\\Big",[{type:"textord",text:"\\Vert",mode:"math"}],[]);default:return{type:"textord",text:" ",mode:"math"}}}ot({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:a}=e;return{type:"cdlabel",mode:r.mode,side:a.slice(4),label:t[0]}},htmlBuilder(e,t){var r=t.havingStyle(t.style.sup()),a=Ke.wrapFragment(wt(e.label,r,t),t);return a.classes.push("cd-label-"+e.side),a.style.bottom=G(.8-a.depth),a.height=0,a.depth=0,a},mathmlBuilder(e,t){var r=new Tt.MathNode("mrow",[Rt(e.label,t)]);return(r=new Tt.MathNode("mpadded",[r])).setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),(r=new Tt.MathNode("mstyle",[r])).setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),ot({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(e,t){var{parser:r}=e;return{type:"cdlabelparent",mode:r.mode,fragment:t[0]}},htmlBuilder(e,t){var r=Ke.wrapFragment(wt(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder:(e,t)=>new Tt.MathNode("mrow",[Rt(e.fragment,t)])}),ot({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(e,t){for(var{parser:r}=e,a=Gt(t[0],"ordgroup").body,n="",o=0;o=1114111)throw new i("\\@char with invalid code point "+n);return l<=65535?s=String.fromCharCode(l):(l-=65536,s=String.fromCharCode(55296+(l>>10),56320+(1023&l))),{type:"textord",mode:r.mode,text:s}}});var rr=(e,t)=>{var r=gt(e.body,t.withColor(e.color),!1);return Ke.makeFragment(r)},ar=(e,t)=>{var r=qt(e.body,t.withColor(e.color)),a=new Tt.MathNode("mstyle",r);return a.setAttribute("mathcolor",e.color),a};ot({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(e,t){var{parser:r}=e,a=Gt(t[0],"color-token").color,n=t[1];return{type:"color",mode:r.mode,color:a,body:ht(n)}},htmlBuilder:rr,mathmlBuilder:ar}),ot({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(e,t){var{parser:r,breakOnTokenText:a}=e,n=Gt(t[0],"color-token").color;r.gullet.macros.set("\\current@color",n);var i=r.parseExpression(!0,a);return{type:"color",mode:r.mode,color:n,body:i}},htmlBuilder:rr,mathmlBuilder:ar}),ot({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(e,t,r){var{parser:a}=e,n="["===a.gullet.future().text?a.parseSizeGroup(!0):null,i=!a.settings.displayMode||!a.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:a.mode,newLine:i,size:n&&Gt(n,"size").value}},htmlBuilder(e,t){var r=Ke.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=G(F(e.size,t)))),r},mathmlBuilder(e,t){var r=new Tt.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",G(F(e.size,t)))),r}});var nr={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},ir=e=>{var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new i("Expected a control sequence",e);return t},or=(e,t,r,a)=>{var n=e.gullet.macros.get(r.text);null==n&&(r.noexpand=!0,n={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,n,a)};ot({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(e){var{parser:t,funcName:r}=e;t.consumeSpaces();var a=t.fetch();if(nr[a.text])return"\\global"!==r&&"\\\\globallong"!==r||(a.text=nr[a.text]),Gt(t.parseFunction(),"internal");throw new i("Invalid token after macro prefix",a)}}),ot({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,a=t.gullet.popToken(),n=a.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(n))throw new i("Expected a control sequence",a);for(var o,s=0,l=[[]];"{"!==t.gullet.future().text;)if("#"===(a=t.gullet.popToken()).text){if("{"===t.gullet.future().text){o=t.gullet.future(),l[s].push("{");break}if(a=t.gullet.popToken(),!/^[1-9]$/.test(a.text))throw new i('Invalid argument number "'+a.text+'"');if(parseInt(a.text)!==s+1)throw new i('Argument number "'+a.text+'" out of order');s++,l.push([])}else{if("EOF"===a.text)throw new i("Expected a macro definition");l[s].push(a.text)}var{tokens:h}=t.gullet.consumeArg();return o&&h.unshift(o),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h)).reverse(),t.gullet.macros.set(n,{tokens:h,numArgs:s,delimiters:l},r===nr[r]),{type:"internal",mode:t.mode}}}),ot({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,a=ir(t.gullet.popToken());t.gullet.consumeSpaces();var n=(e=>{var t=e.gullet.popToken();return"="===t.text&&" "===(t=e.gullet.popToken()).text&&(t=e.gullet.popToken()),t})(t);return or(t,a,n,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),ot({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,a=ir(t.gullet.popToken()),n=t.gullet.popToken(),i=t.gullet.popToken();return or(t,a,i,"\\\\globalfuture"===r),t.gullet.pushToken(i),t.gullet.pushToken(n),{type:"internal",mode:t.mode}}});var sr=function(e,t,r){var a=I(ne.math[e]&&ne.math[e].replace||e,t,r);if(!a)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return a},lr=function(e,t,r,a){var n=r.havingBaseStyle(t),i=Ke.makeSpan(a.concat(n.sizingClasses(r)),[e],r),o=n.sizeMultiplier/r.sizeMultiplier;return i.height*=o,i.depth*=o,i.maxFontSize=n.sizeMultiplier,i},hr=function(e,t,r){var a=t.havingBaseStyle(r),n=(1-t.sizeMultiplier/a.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=G(n),e.height-=n,e.depth+=n},mr=function(e,t,r,a,n,i){var o=function(e,t,r,a){return Ke.makeSymbol(e,"Size"+t+"-Regular",r,a)}(e,t,n,a),s=lr(Ke.makeSpan(["delimsizing","size"+t],[o],a),k.TEXT,a,i);return r&&hr(s,a,k.TEXT),s},cr=function(e,t,r){var a;return a="Size1-Regular"===t?"delim-size1":"delim-size4",{type:"elem",elem:Ke.makeSpan(["delimsizinginner",a],[Ke.makeSpan([],[Ke.makeSymbol(e,t,r)])])}},pr=function(e,t,r){var a=C["Size4-Regular"][e.charCodeAt(0)]?C["Size4-Regular"][e.charCodeAt(0)][4]:C["Size1-Regular"][e.charCodeAt(0)][4],n=new Q("inner",function(e,t){switch(e){case"\u239c":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"\u239f":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23a2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23a5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23aa":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23d0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),i=new J([n],{width:G(a),height:G(t),style:"width:"+G(a),viewBox:"0 0 "+1e3*a+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=Ke.makeSvgSpan([],[i],r);return o.height=t,o.style.height=G(t),o.style.width=G(a),{type:"elem",elem:o}},ur={type:"kern",size:-.008},dr=["|","\\lvert","\\rvert","\\vert"],gr=["\\|","\\lVert","\\rVert","\\Vert"],fr=function(e,t,r,a,n,i){var o,s,l,h,c="",p=0;o=l=h=e,s=null;var u="Size1-Regular";"\\uparrow"===e?l=h="\u23d0":"\\Uparrow"===e?l=h="\u2016":"\\downarrow"===e?o=l="\u23d0":"\\Downarrow"===e?o=l="\u2016":"\\updownarrow"===e?(o="\\uparrow",l="\u23d0",h="\\downarrow"):"\\Updownarrow"===e?(o="\\Uparrow",l="\u2016",h="\\Downarrow"):m.contains(dr,e)?(l="\u2223",c="vert",p=333):m.contains(gr,e)?(l="\u2225",c="doublevert",p=556):"["===e||"\\lbrack"===e?(o="\u23a1",l="\u23a2",h="\u23a3",u="Size4-Regular",c="lbrack",p=667):"]"===e||"\\rbrack"===e?(o="\u23a4",l="\u23a5",h="\u23a6",u="Size4-Regular",c="rbrack",p=667):"\\lfloor"===e||"\u230a"===e?(l=o="\u23a2",h="\u23a3",u="Size4-Regular",c="lfloor",p=667):"\\lceil"===e||"\u2308"===e?(o="\u23a1",l=h="\u23a2",u="Size4-Regular",c="lceil",p=667):"\\rfloor"===e||"\u230b"===e?(l=o="\u23a5",h="\u23a6",u="Size4-Regular",c="rfloor",p=667):"\\rceil"===e||"\u2309"===e?(o="\u23a4",l=h="\u23a5",u="Size4-Regular",c="rceil",p=667):"("===e||"\\lparen"===e?(o="\u239b",l="\u239c",h="\u239d",u="Size4-Regular",c="lparen",p=875):")"===e||"\\rparen"===e?(o="\u239e",l="\u239f",h="\u23a0",u="Size4-Regular",c="rparen",p=875):"\\{"===e||"\\lbrace"===e?(o="\u23a7",s="\u23a8",h="\u23a9",l="\u23aa",u="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(o="\u23ab",s="\u23ac",h="\u23ad",l="\u23aa",u="Size4-Regular"):"\\lgroup"===e||"\u27ee"===e?(o="\u23a7",h="\u23a9",l="\u23aa",u="Size4-Regular"):"\\rgroup"===e||"\u27ef"===e?(o="\u23ab",h="\u23ad",l="\u23aa",u="Size4-Regular"):"\\lmoustache"===e||"\u23b0"===e?(o="\u23a7",h="\u23ad",l="\u23aa",u="Size4-Regular"):"\\rmoustache"!==e&&"\u23b1"!==e||(o="\u23ab",h="\u23a9",l="\u23aa",u="Size4-Regular");var d=sr(o,u,n),g=d.height+d.depth,f=sr(l,u,n),v=f.height+f.depth,b=sr(h,u,n),y=b.height+b.depth,x=0,w=1;if(null!==s){var S=sr(s,u,n);x=S.height+S.depth,w=2}var M=g+y+x,z=M+Math.max(0,Math.ceil((t-M)/(w*v)))*w*v,A=a.fontMetrics().axisHeight;r&&(A*=a.sizeMultiplier);var T=z/2-A,B=[];if(c.length>0){var C=z-g-y,N=Math.round(1e3*z),q=function(e,t){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v1759 h347 v-84\nH403z M403 1759 V0 H319 V1759 v"+t+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v1759 H0 v84 H347z\nM347 1759 V0 H263 V1759 v"+t+" v1759 h84z";case"vert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z";case"doublevert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z\nM367 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M410 15 H367 v585 v"+t+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+t+" v1715 h263 v84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+t+" v1799 H0 v-84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v602 h84z\nM403 1759 V0 H319 V1759 v"+t+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v602 h84z\nM347 1759 V0 h-84 V1759 v"+t+" v602 h84z";case"lparen":return"M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1\nc-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349,\n-36,557 l0,"+(t+84)+"c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210,\n949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9\nc0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5,\n-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189\nl0,-"+(t+92)+"c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3,\n-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z";case"rparen":return"M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3,\n63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5\nc11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0,"+(t+9)+"\nc-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664\nc-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11\nc0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17\nc242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558\nl0,-"+(t+144)+"c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,\n-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z";default:throw new Error("Unknown stretchy delimiter.")}}(c,Math.round(1e3*C)),I=new Q(c,q),R=(p/1e3).toFixed(3)+"em",H=(N/1e3).toFixed(3)+"em",O=new J([I],{width:R,height:H,viewBox:"0 0 "+p+" "+N}),E=Ke.makeSvgSpan([],[O],a);E.height=N/1e3,E.style.width=R,E.style.height=H,B.push({type:"elem",elem:E})}else{if(B.push(cr(h,u,n)),B.push(ur),null===s){var L=z-g-y+.016;B.push(pr(l,L,a))}else{var D=(z-g-y-x)/2+.016;B.push(pr(l,D,a)),B.push(ur),B.push(cr(s,u,n)),B.push(ur),B.push(pr(l,D,a))}B.push(ur),B.push(cr(o,u,n))}var V=a.havingBaseStyle(k.TEXT),P=Ke.makeVList({positionType:"bottom",positionData:T,children:B},V);return lr(Ke.makeSpan(["delimsizing","mult"],[P],V),k.TEXT,a,i)},vr=.08,br=function(e,t,r,a,n){var i=function(e,t,r){t*=1e3;var a="";switch(e){case"sqrtMain":a=function(e,t){return"M95,"+(622+e+t)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize1":a=function(e,t){return"M263,"+(601+e+t)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize2":a=function(e,t){return"M983 "+(10+e+t)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize3":a=function(e,t){return"M424,"+(2398+e+t)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" "+t+"\nh400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize4":a=function(e,t){return"M473,"+(2713+e+t)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"}(t,A);break;case"sqrtTall":a=function(e,t,r){return"M702 "+(e+t)+"H400000"+(40+e)+"\nH742v"+(r-54-t-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+t+"H400000v"+(40+e)+"H742z"}(t,A,r)}return a}(e,a,r),o=new Q(e,i),s=new J([o],{width:"400em",height:G(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return Ke.makeSvgSpan(["hide-tail"],[s],n)},yr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],xr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],wr=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],kr=[0,1.2,1.8,2.4,3],Sr=[{type:"small",style:k.SCRIPTSCRIPT},{type:"small",style:k.SCRIPT},{type:"small",style:k.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],Mr=[{type:"small",style:k.SCRIPTSCRIPT},{type:"small",style:k.SCRIPT},{type:"small",style:k.TEXT},{type:"stack"}],zr=[{type:"small",style:k.SCRIPTSCRIPT},{type:"small",style:k.SCRIPT},{type:"small",style:k.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],Ar=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},Tr=function(e,t,r,a){for(var n=Math.min(2,3-a.style.size);nt)return r[n]}return r[r.length-1]},Br=function(e,t,r,a,n,i){var o;"<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),o=m.contains(wr,e)?Sr:m.contains(yr,e)?zr:Mr;var s=Tr(e,t,o,a);return"small"===s.type?function(e,t,r,a,n,i){var o=Ke.makeSymbol(e,"Main-Regular",n,a),s=lr(o,t,a,i);return r&&hr(s,a,t),s}(e,s.style,r,a,n,i):"large"===s.type?mr(e,s.size,r,a,n,i):fr(e,t,r,a,n,i)},Cr={sqrtImage:function(e,t){var r,a,n=t.havingBaseSizing(),i=Tr("\\surd",e*n.sizeMultiplier,zr,n),o=n.sizeMultiplier,s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),l=0,h=0,m=0;return"small"===i.type?(e<1?o=1:e<1.4&&(o=.7),h=(1+s)/o,(r=br("sqrtMain",l=(1+s+vr)/o,m=1e3+1e3*s+80,s,t)).style.minWidth="0.853em",a=.833/o):"large"===i.type?(m=1080*kr[i.size],h=(kr[i.size]+s)/o,l=(kr[i.size]+s+vr)/o,(r=br("sqrtSize"+i.size,l,m,s,t)).style.minWidth="1.02em",a=1/o):(l=e+s+vr,h=e+s,m=Math.floor(1e3*e+s)+80,(r=br("sqrtTall",l,m,s,t)).style.minWidth="0.742em",a=1.056),r.height=h,r.style.height=G(l),{span:r,advanceWidth:a,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,a,n){if("<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),m.contains(yr,e)||m.contains(wr,e))return mr(e,t,!1,r,a,n);if(m.contains(xr,e))return fr(e,kr[t],!1,r,a,n);throw new i("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:kr,customSizedDelim:Br,leftRightDelim:function(e,t,r,a,n,i){var o=a.fontMetrics().axisHeight*a.sizeMultiplier,s=5/a.fontMetrics().ptPerEm,l=Math.max(t-o,r+o),h=Math.max(l/500*901,2*l-s);return Br(e,h,!0,a,n,i)}},Nr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},qr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Ir(e,t){var r=Yt(e);if(r&&m.contains(qr,r.text))return r;throw new i(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function Rr(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}ot({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:(e,t)=>{var r=Ir(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:Nr[e.funcName].size,mclass:Nr[e.funcName].mclass,delim:r.text}},htmlBuilder:(e,t)=>"."===e.delim?Ke.makeSpan([e.mclass]):Cr.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass]),mathmlBuilder:e=>{var t=[];"."!==e.delim&&t.push(Bt(e.delim,e.mode));var r=new Tt.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var a=G(Cr.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",a),r.setAttribute("maxsize",a),r}}),ot({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new i("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Ir(t[0],e).text,color:r}}}),ot({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=Ir(t[0],e),a=e.parser;++a.leftrightDepth;var n=a.parseExpression(!1);--a.leftrightDepth,a.expect("\\right",!1);var i=Gt(a.parseFunction(),"leftright-right");return{type:"leftright",mode:a.mode,body:n,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:(e,t)=>{Rr(e);for(var r,a,n=gt(e.body,t,!0,["mopen","mclose"]),i=0,o=0,s=!1,l=0;l{Rr(e);var r=qt(e.body,t);if("."!==e.left){var a=new Tt.MathNode("mo",[Bt(e.left,e.mode)]);a.setAttribute("fence","true"),r.unshift(a)}if("."!==e.right){var n=new Tt.MathNode("mo",[Bt(e.right,e.mode)]);n.setAttribute("fence","true"),e.rightColor&&n.setAttribute("mathcolor",e.rightColor),r.push(n)}return Ct(r)}}),ot({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=Ir(t[0],e);if(!e.parser.leftrightDepth)throw new i("\\middle without preceding \\left",r);return{type:"middle",mode:e.parser.mode,delim:r.text}},htmlBuilder:(e,t)=>{var r;if("."===e.delim)r=xt(t,[]);else{r=Cr.sizedDelim(e.delim,1,t,e.mode,[]);var a={delim:e.delim,options:t};r.isMiddle=a}return r},mathmlBuilder:(e,t)=>{var r="\\vert"===e.delim||"|"===e.delim?Bt("|","text"):Bt(e.delim,e.mode),a=new Tt.MathNode("mo",[r]);return a.setAttribute("fence","true"),a.setAttribute("lspace","0.05em"),a.setAttribute("rspace","0.05em"),a}});var Hr=(e,t)=>{var r,a,n,i=Ke.wrapFragment(wt(e.body,t),t),o=e.label.slice(1),s=t.sizeMultiplier,l=0,h=m.isCharacterBox(e.body);if("sout"===o)(r=Ke.makeSpan(["stretchy","sout"])).height=t.fontMetrics().defaultRuleThickness/s,l=-.5*t.fontMetrics().xHeight;else if("phase"===o){var c=F({number:.6,unit:"pt"},t),p=F({number:.35,unit:"ex"},t);s/=t.havingBaseSizing().sizeMultiplier;var u=i.height+i.depth+c+p;i.style.paddingLeft=G(u/2+c);var d=Math.floor(1e3*u*s),g="M400000 "+(a=d)+" H0 L"+a/2+" 0 l65 45 L145 "+(a-80)+" H400000z",f=new J([new Q("phase",g)],{width:"400em",height:G(d/1e3),viewBox:"0 0 400000 "+d,preserveAspectRatio:"xMinYMin slice"});(r=Ke.makeSvgSpan(["hide-tail"],[f],t)).style.height=G(u),l=i.depth+c+p}else{/cancel/.test(o)?h||i.classes.push("cancel-pad"):"angl"===o?i.classes.push("anglpad"):i.classes.push("boxpad");var v=0,b=0,y=0;/box/.test(o)?(y=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness),b=v=t.fontMetrics().fboxsep+("colorbox"===o?0:y)):"angl"===o?(v=4*(y=Math.max(t.fontMetrics().defaultRuleThickness,t.minRuleThickness)),b=Math.max(0,.25-i.depth)):b=v=h?.2:0,r=Vt(i,o,v,b,t),/fbox|boxed|fcolorbox/.test(o)?(r.style.borderStyle="solid",r.style.borderWidth=G(y)):"angl"===o&&.049!==y&&(r.style.borderTopWidth=G(y),r.style.borderRightWidth=G(y)),l=i.depth+b,e.backgroundColor&&(r.style.backgroundColor=e.backgroundColor,e.borderColor&&(r.style.borderColor=e.borderColor))}if(e.backgroundColor)n=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:r,shift:l},{type:"elem",elem:i,shift:0}]},t);else{var x=/cancel|phase/.test(o)?["svg-align"]:[];n=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:0},{type:"elem",elem:r,shift:l,wrapperClasses:x}]},t)}return/cancel/.test(o)&&(n.height=i.height,n.depth=i.depth),/cancel/.test(o)&&!h?Ke.makeSpan(["mord","cancel-lap"],[n],t):Ke.makeSpan(["mord"],[n],t)},Or=(e,t)=>{var r=0,a=new Tt.MathNode(e.label.indexOf("colorbox")>-1?"mpadded":"menclose",[Rt(e.body,t)]);switch(e.label){case"\\cancel":a.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":a.setAttribute("notation","downdiagonalstrike");break;case"\\phase":a.setAttribute("notation","phasorangle");break;case"\\sout":a.setAttribute("notation","horizontalstrike");break;case"\\fbox":a.setAttribute("notation","box");break;case"\\angl":a.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,a.setAttribute("width","+"+2*r+"pt"),a.setAttribute("height","+"+2*r+"pt"),a.setAttribute("lspace",r+"pt"),a.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){var n=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);a.setAttribute("style","border: "+n+"em solid "+String(e.borderColor))}break;case"\\xcancel":a.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&a.setAttribute("mathbackground",e.backgroundColor),a};ot({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(e,t,r){var{parser:a,funcName:n}=e,i=Gt(t[0],"color-token").color,o=t[1];return{type:"enclose",mode:a.mode,label:n,backgroundColor:i,body:o}},htmlBuilder:Hr,mathmlBuilder:Or}),ot({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(e,t,r){var{parser:a,funcName:n}=e,i=Gt(t[0],"color-token").color,o=Gt(t[1],"color-token").color,s=t[2];return{type:"enclose",mode:a.mode,label:n,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:Hr,mathmlBuilder:Or}),ot({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\fbox",body:t[0]}}}),ot({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];return{type:"enclose",mode:r.mode,label:a,body:n}},htmlBuilder:Hr,mathmlBuilder:Or}),ot({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(e,t){var{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\angl",body:t[0]}}});var Er={};function Lr(e){for(var{type:t,names:r,props:a,handler:n,htmlBuilder:i,mathmlBuilder:o}=e,s={type:t,numArgs:a.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:n},l=0;l{if(!e.parser.settings.displayMode)throw new i("{"+e.envName+"} can be used only in display mode.")};function Gr(e){if(-1===e.indexOf("ed"))return-1===e.indexOf("*")}function Ur(e,t,r){var{hskipBeforeAndAfter:a,addJot:o,cols:s,arraystretch:l,colSeparationType:h,autoTag:m,singleRow:c,emptySingleRow:p,maxNumCols:u,leqno:d}=t;if(e.gullet.beginGroup(),c||e.gullet.macros.set("\\cr","\\\\\\relax"),!l){var g=e.gullet.expandMacroAsText("\\arraystretch");if(null==g)l=1;else if(!(l=parseFloat(g))||l<0)throw new i("Invalid \\arraystretch: "+g)}e.gullet.beginGroup();var f=[],v=[f],b=[],y=[],x=null!=m?[]:void 0;function w(){m&&e.gullet.macros.set("\\@eqnsw","1",!0)}function k(){x&&(e.gullet.macros.get("\\df@tag")?(x.push(e.subparse([new n("\\df@tag")])),e.gullet.macros.set("\\df@tag",void 0,!0)):x.push(Boolean(m)&&"1"===e.gullet.macros.get("\\@eqnsw")))}for(w(),y.push(Pr(e));;){var S=e.parseExpression(!1,c?"\\end":"\\\\");e.gullet.endGroup(),e.gullet.beginGroup(),S={type:"ordgroup",mode:e.mode,body:S},r&&(S={type:"styling",mode:e.mode,style:r,body:[S]}),f.push(S);var M=e.fetch().text;if("&"===M){if(u&&f.length===u){if(c||h)throw new i("Too many tab characters: &",e.nextToken);e.settings.reportNonstrict("textEnv","Too few columns specified in the {array} column argument.")}e.consume()}else{if("\\end"===M){k(),1===f.length&&"styling"===S.type&&0===S.body[0].body.length&&(v.length>1||!p)&&v.pop(),y.length0&&(y+=.25),h.push({pos:y,isDashed:e[t]})}for(x(o[0]),r=0;r0&&(M<(B+=b)&&(M=B),B=0),e.addJot&&(M+=g),z.height=S,z.depth=M,y+=S,z.pos=y,y+=M+B,l[r]=z,x(o[r+1])}var C,N,q=y/2+t.fontMetrics().axisHeight,I=e.cols||[],R=[],H=[];if(e.tags&&e.tags.some((e=>e)))for(r=0;r=s)){var W=void 0;(a>0||e.hskipBeforeAndAfter)&&0!==(W=m.deflt(V.pregap,u))&&((C=Ke.makeSpan(["arraycolsep"],[])).style.width=G(W),R.push(C));var _=[];for(r=0;r0){for(var K=Ke.makeLineSpan("hline",t,c),J=Ke.makeLineSpan("hdashline",t,c),Q=[{type:"elem",elem:l,shift:0}];h.length>0;){var ee=h.pop(),te=ee.pos-q;ee.isDashed?Q.push({type:"elem",elem:J,shift:te}):Q.push({type:"elem",elem:K,shift:te})}l=Ke.makeVList({positionType:"individualShift",children:Q},t)}if(0===H.length)return Ke.makeSpan(["mord"],[l],t);var re=Ke.makeVList({positionType:"individualShift",children:H},t);return re=Ke.makeSpan(["tag"],[re],t),Ke.makeFragment([l,re])},Wr={c:"center ",l:"left ",r:"right "},_r=function(e,t){for(var r=[],a=new Tt.MathNode("mtd",[],["mtr-glue"]),n=new Tt.MathNode("mtd",[],["mml-eqn-num"]),i=0;i0){var u=e.cols,d="",g=!1,f=0,v=u.length;"separator"===u[0].type&&(c+="top ",f=1),"separator"===u[u.length-1].type&&(c+="bottom ",v-=1);for(var b=f;b0?"left ":"",c+=S[S.length-1].length>0?"right ":"";for(var M=1;M-1?"alignat":"align",o="split"===e.envName,s=Ur(e.parser,{cols:a,addJot:!0,autoTag:o?void 0:Gr(e.envName),emptySingleRow:!0,colSeparationType:n,maxNumCols:o?2:void 0,leqno:e.parser.settings.leqno},"display"),l=0,h={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){for(var m="",c=0;c0&&p&&(g=1),a[u]={type:"align",align:d,pregap:g,postgap:0}}return s.colSeparationType=p?"align":"alignat",s};Lr({type:"array",names:["array","darray"],props:{numArgs:1},handler(e,t){var r=(Yt(t[0])?[t[0]]:Gt(t[0],"ordgroup").body).map((function(e){var t=Ut(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new i("Unknown column alignment: "+t,e)})),a={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return Ur(e.parser,a,Yr(e.envName))},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(e){var t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")],r="c",a={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){var n=e.parser;if(n.consumeSpaces(),"["===n.fetch().text){if(n.consume(),n.consumeSpaces(),r=n.fetch().text,-1==="lcr".indexOf(r))throw new i("Expected l or c or r",n.nextToken);n.consume(),n.consumeSpaces(),n.expect("]"),n.consume(),a.cols=[{type:"align",align:r}]}}var o=Ur(e.parser,a,Yr(e.envName)),s=Math.max(0,...o.body.map((e=>e.length)));return o.cols=new Array(s).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[o],left:t[0],right:t[1],rightColor:void 0}:o},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(e){var t=Ur(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["subarray"],props:{numArgs:1},handler(e,t){var r=(Yt(t[0])?[t[0]]:Gt(t[0],"ordgroup").body).map((function(e){var t=Ut(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new i("Unknown column alignment: "+t,e)}));if(r.length>1)throw new i("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=Ur(e.parser,a,"script")).body.length>0&&a.body[0].length>1)throw new i("{subarray} can contain only one column");return a},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(e){var t=Ur(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},Yr(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:jr,htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(e){m.contains(["gather","gather*"],e.envName)&&Fr(e);var t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:Gr(e.envName),emptySingleRow:!0,leqno:e.parser.settings.leqno};return Ur(e.parser,t,"display")},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:jr,htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(e){Fr(e);var t={autoTag:Gr(e.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Ur(e.parser,t,"display")},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["CD"],props:{numArgs:0},handler:e=>(Fr(e),function(e){var t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();var r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new i("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}for(var a,n,o=[],s=[o],l=0;l-1);else{if(!("<>AV".indexOf(p)>-1))throw new i('Expected one of "<>AV=|." after @',h[c]);for(var d=0;d<2;d++){for(var g=!0,f=c+1;f{var r=e.font,a=t.withFont(r);return wt(e.body,a)},Kr=(e,t)=>{var r=e.font,a=t.withFont(r);return Rt(e.body,a)},Jr={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};ot({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=lt(t[0]),i=a;return i in Jr&&(i=Jr[i]),{type:"font",mode:r.mode,font:i.slice(1),body:n}},htmlBuilder:Zr,mathmlBuilder:Kr}),ot({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:(e,t)=>{var{parser:r}=e,a=t[0],n=m.isCharacterBox(a);return{type:"mclass",mode:r.mode,mclass:Jt(a),body:[{type:"font",mode:r.mode,font:"boldsymbol",body:a}],isCharacterBox:n}}}),ot({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{var{parser:r,funcName:a,breakOnTokenText:n}=e,{mode:i}=r,o=r.parseExpression(!0,n);return{type:"font",mode:i,font:"math"+a.slice(1),body:{type:"ordgroup",mode:r.mode,body:o}}},htmlBuilder:Zr,mathmlBuilder:Kr});var Qr=(e,t)=>{var r=t;return"display"===e?r=r.id>=k.SCRIPT.id?r.text():k.DISPLAY:"text"===e&&r.size===k.DISPLAY.size?r=k.TEXT:"script"===e?r=k.SCRIPT:"scriptscript"===e&&(r=k.SCRIPTSCRIPT),r},ea=(e,t)=>{var r,a=Qr(e.size,t.style),n=a.fracNum(),i=a.fracDen();r=t.havingStyle(n);var o=wt(e.numer,r,t);if(e.continued){var s=8.5/t.fontMetrics().ptPerEm,l=3.5/t.fontMetrics().ptPerEm;o.height=o.height0?3*c:7*c,d=t.fontMetrics().denom1):(m>0?(p=t.fontMetrics().num2,u=c):(p=t.fontMetrics().num3,u=3*c),d=t.fontMetrics().denom2),h){var x=t.fontMetrics().axisHeight;p-o.depth-(x+.5*m){var r=new Tt.MathNode("mfrac",[Rt(e.numer,t),Rt(e.denom,t)]);if(e.hasBarLine){if(e.barSize){var a=F(e.barSize,t);r.setAttribute("linethickness",G(a))}}else r.setAttribute("linethickness","0px");var n=Qr(e.size,t.style);if(n.size!==t.style.size){r=new Tt.MathNode("mstyle",[r]);var i=n.size===k.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",i),r.setAttribute("scriptlevel","0")}if(null!=e.leftDelim||null!=e.rightDelim){var o=[];if(null!=e.leftDelim){var s=new Tt.MathNode("mo",[new Tt.TextNode(e.leftDelim.replace("\\",""))]);s.setAttribute("fence","true"),o.push(s)}if(o.push(r),null!=e.rightDelim){var l=new Tt.MathNode("mo",[new Tt.TextNode(e.rightDelim.replace("\\",""))]);l.setAttribute("fence","true"),o.push(l)}return Ct(o)}return r};ot({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(e,t)=>{var r,{parser:a,funcName:n}=e,i=t[0],o=t[1],s=null,l=null,h="auto";switch(n){case"\\dfrac":case"\\frac":case"\\tfrac":r=!0;break;case"\\\\atopfrac":r=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":r=!1,s="(",l=")";break;case"\\\\bracefrac":r=!1,s="\\{",l="\\}";break;case"\\\\brackfrac":r=!1,s="[",l="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text"}return{type:"genfrac",mode:a.mode,continued:!1,numer:i,denom:o,hasBarLine:r,leftDelim:s,rightDelim:l,size:h,barSize:null}},htmlBuilder:ea,mathmlBuilder:ta}),ot({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0],i=t[1];return{type:"genfrac",mode:r.mode,continued:!0,numer:n,denom:i,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}}),ot({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(e){var t,{parser:r,funcName:a,token:n}=e;switch(a){case"\\over":t="\\frac";break;case"\\choose":t="\\binom";break;case"\\atop":t="\\\\atopfrac";break;case"\\brace":t="\\\\bracefrac";break;case"\\brack":t="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:r.mode,replaceWith:t,token:n}}});var ra=["display","text","script","scriptscript"],aa=function(e){var t=null;return e.length>0&&(t="."===(t=e)?null:t),t};ot({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(e,t){var r,{parser:a}=e,n=t[4],i=t[5],o=lt(t[0]),s="atom"===o.type&&"open"===o.family?aa(o.text):null,l=lt(t[1]),h="atom"===l.type&&"close"===l.family?aa(l.text):null,m=Gt(t[2],"size"),c=null;r=!!m.isBlank||(c=m.value).number>0;var p="auto",u=t[3];if("ordgroup"===u.type){if(u.body.length>0){var d=Gt(u.body[0],"textord");p=ra[Number(d.text)]}}else u=Gt(u,"textord"),p=ra[Number(u.text)];return{type:"genfrac",mode:a.mode,numer:n,denom:i,continued:!1,hasBarLine:r,barSize:c,leftDelim:s,rightDelim:h,size:p}},htmlBuilder:ea,mathmlBuilder:ta}),ot({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(e,t){var{parser:r,funcName:a,token:n}=e;return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Gt(t[0],"size").value,token:n}}}),ot({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0],i=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Gt(t[1],"infix").size),o=t[2],s=i.number>0;return{type:"genfrac",mode:r.mode,numer:n,denom:o,continued:!1,hasBarLine:s,barSize:i,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:ea,mathmlBuilder:ta});var na=(e,t)=>{var r,a,n=t.style;"supsub"===e.type?(r=e.sup?wt(e.sup,t.havingStyle(n.sup()),t):wt(e.sub,t.havingStyle(n.sub()),t),a=Gt(e.base,"horizBrace")):a=Gt(e,"horizBrace");var i,o=wt(a.base,t.havingBaseStyle(k.DISPLAY)),s=Ft(a,t);if(a.isOver?(i=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.1},{type:"elem",elem:s}]},t)).children[0].children[0].children[1].classes.push("svg-align"):(i=Ke.makeVList({positionType:"bottom",positionData:o.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:o}]},t)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=Ke.makeSpan(["mord",a.isOver?"mover":"munder"],[i],t);i=a.isOver?Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},t):Ke.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},t)}return Ke.makeSpan(["mord",a.isOver?"mover":"munder"],[i],t)};ot({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:a}=e;return{type:"horizBrace",mode:r.mode,label:a,isOver:/^\\over/.test(a),base:t[0]}},htmlBuilder:na,mathmlBuilder:(e,t)=>{var r=Pt(e.label);return new Tt.MathNode(e.isOver?"mover":"munder",[Rt(e.base,t),r])}}),ot({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[1],n=Gt(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:n})?{type:"href",mode:r.mode,href:n,body:ht(a)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:(e,t)=>{var r=gt(e.body,t,!1);return Ke.makeAnchor(e.href,[],r,t)},mathmlBuilder:(e,t)=>{var r=It(e.body,t);return r instanceof zt||(r=new zt("mrow",[r])),r.setAttribute("href",e.href),r}}),ot({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=Gt(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:a}))return r.formatUnsupportedCmd("\\url");for(var n=[],i=0;inew Tt.MathNode("mrow",qt(e.body,t))}),ot({type:"html",names:["\\htmlClass","\\htmlId","\\htmlStyle","\\htmlData"],props:{numArgs:2,argTypes:["raw","original"],allowedInText:!0},handler:(e,t)=>{var r,{parser:a,funcName:n,token:o}=e,s=Gt(t[0],"raw").string,l=t[1];a.settings.strict&&a.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var h={};switch(n){case"\\htmlClass":h.class=s,r={command:"\\htmlClass",class:s};break;case"\\htmlId":h.id=s,r={command:"\\htmlId",id:s};break;case"\\htmlStyle":h.style=s,r={command:"\\htmlStyle",style:s};break;case"\\htmlData":for(var m=s.split(","),c=0;c{var r=gt(e.body,t,!1),a=["enclosing"];e.attributes.class&&a.push(...e.attributes.class.trim().split(/\s+/));var n=Ke.makeSpan(a,r,t);for(var i in e.attributes)"class"!==i&&e.attributes.hasOwnProperty(i)&&n.setAttribute(i,e.attributes[i]);return n},mathmlBuilder:(e,t)=>It(e.body,t)}),ot({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e;return{type:"htmlmathml",mode:r.mode,html:ht(t[0]),mathml:ht(t[1])}},htmlBuilder:(e,t)=>{var r=gt(e.html,t,!1);return Ke.makeFragment(r)},mathmlBuilder:(e,t)=>It(e.mathml,t)});var ia=function(e){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(e))return{number:+e,unit:"bp"};var t=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e);if(!t)throw new i("Invalid size: '"+e+"' in \\includegraphics");var r={number:+(t[1]+t[2]),unit:t[3]};if(!P(r))throw new i("Invalid unit: '"+r.unit+"' in \\includegraphics.");return r};ot({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:(e,t,r)=>{var{parser:a}=e,n={number:0,unit:"em"},o={number:.9,unit:"em"},s={number:0,unit:"em"},l="";if(r[0])for(var h=Gt(r[0],"raw").string.split(","),m=0;m{var r=F(e.height,t),a=0;e.totalheight.number>0&&(a=F(e.totalheight,t)-r);var n=0;e.width.number>0&&(n=F(e.width,t));var i={height:G(r+a)};n>0&&(i.width=G(n)),a>0&&(i.verticalAlign=G(-a));var o=new $(e.src,e.alt,i);return o.height=r,o.depth=a,o},mathmlBuilder:(e,t)=>{var r=new Tt.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);var a=F(e.height,t),n=0;if(e.totalheight.number>0&&(n=F(e.totalheight,t)-a,r.setAttribute("valign",G(-n))),r.setAttribute("height",G(a+n)),e.width.number>0){var i=F(e.width,t);r.setAttribute("width",G(i))}return r.setAttribute("src",e.src),r}}),ot({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(e,t){var{parser:r,funcName:a}=e,n=Gt(t[0],"size");if(r.settings.strict){var i="m"===a[1],o="mu"===n.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" supports only mu units, not "+n.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:n.value}},htmlBuilder:(e,t)=>Ke.makeGlue(e.dimension,t),mathmlBuilder(e,t){var r=F(e.dimension,t);return new Tt.SpaceNode(r)}}),ot({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0];return{type:"lap",mode:r.mode,alignment:a.slice(5),body:n}},htmlBuilder:(e,t)=>{var r;"clap"===e.alignment?(r=Ke.makeSpan([],[wt(e.body,t)]),r=Ke.makeSpan(["inner"],[r],t)):r=Ke.makeSpan(["inner"],[wt(e.body,t)]);var a=Ke.makeSpan(["fix"],[]),n=Ke.makeSpan([e.alignment],[r,a],t),i=Ke.makeSpan(["strut"]);return i.style.height=G(n.height+n.depth),n.depth&&(i.style.verticalAlign=G(-n.depth)),n.children.unshift(i),n=Ke.makeSpan(["thinbox"],[n],t),Ke.makeSpan(["mord","vbox"],[n],t)},mathmlBuilder:(e,t)=>{var r=new Tt.MathNode("mpadded",[Rt(e.body,t)]);if("rlap"!==e.alignment){var a="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",a+"width")}return r.setAttribute("width","0px"),r}}),ot({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){var{funcName:r,parser:a}=e,n=a.mode;a.switchMode("math");var i="\\("===r?"\\)":"$",o=a.parseExpression(!1,i);return a.expect(i),a.switchMode(n),{type:"styling",mode:a.mode,style:"text",body:o}}}),ot({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){throw new i("Mismatched "+e.funcName)}});var oa=(e,t)=>{switch(t.style.size){case k.DISPLAY.size:return e.display;case k.TEXT.size:return e.text;case k.SCRIPT.size:return e.script;case k.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};ot({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:(e,t)=>{var{parser:r}=e;return{type:"mathchoice",mode:r.mode,display:ht(t[0]),text:ht(t[1]),script:ht(t[2]),scriptscript:ht(t[3])}},htmlBuilder:(e,t)=>{var r=oa(e,t),a=gt(r,t,!1);return Ke.makeFragment(a)},mathmlBuilder:(e,t)=>{var r=oa(e,t);return It(r,t)}});var sa=(e,t,r,a,n,i,o)=>{e=Ke.makeSpan([],[e]);var s,l,h,c=r&&m.isCharacterBox(r);if(t){var p=wt(t,a.havingStyle(n.sup()),a);l={elem:p,kern:Math.max(a.fontMetrics().bigOpSpacing1,a.fontMetrics().bigOpSpacing3-p.depth)}}if(r){var u=wt(r,a.havingStyle(n.sub()),a);s={elem:u,kern:Math.max(a.fontMetrics().bigOpSpacing2,a.fontMetrics().bigOpSpacing4-u.height)}}if(l&&s){var d=a.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+e.depth+o;h=Ke.makeVList({positionType:"bottom",positionData:d,children:[{type:"kern",size:a.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:G(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e},{type:"kern",size:l.kern},{type:"elem",elem:l.elem,marginLeft:G(i)},{type:"kern",size:a.fontMetrics().bigOpSpacing5}]},a)}else if(s){var g=e.height-o;h=Ke.makeVList({positionType:"top",positionData:g,children:[{type:"kern",size:a.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:G(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e}]},a)}else{if(!l)return e;var f=e.depth+o;h=Ke.makeVList({positionType:"bottom",positionData:f,children:[{type:"elem",elem:e},{type:"kern",size:l.kern},{type:"elem",elem:l.elem,marginLeft:G(i)},{type:"kern",size:a.fontMetrics().bigOpSpacing5}]},a)}var v=[h];if(s&&0!==i&&!c){var b=Ke.makeSpan(["mspace"],[],a);b.style.marginRight=G(i),v.unshift(b)}return Ke.makeSpan(["mop","op-limits"],v,a)},la=["\\smallint"],ha=(e,t)=>{var r,a,n,i=!1;"supsub"===e.type?(r=e.sup,a=e.sub,n=Gt(e.base,"op"),i=!0):n=Gt(e,"op");var o,s=t.style,l=!1;if(s.size===k.DISPLAY.size&&n.symbol&&!m.contains(la,n.name)&&(l=!0),n.symbol){var h=l?"Size2-Regular":"Size1-Regular",c="";if("\\oiint"!==n.name&&"\\oiiint"!==n.name||(c=n.name.slice(1),n.name="oiint"===c?"\\iint":"\\iiint"),o=Ke.makeSymbol(n.name,h,"math",t,["mop","op-symbol",l?"large-op":"small-op"]),c.length>0){var p=o.italic,u=Ke.staticSvg(c+"Size"+(l?"2":"1"),t);o=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:u,shift:l?.08:0}]},t),n.name="\\"+c,o.classes.unshift("mop"),o.italic=p}}else if(n.body){var d=gt(n.body,t,!0);1===d.length&&d[0]instanceof K?(o=d[0]).classes[0]="mop":o=Ke.makeSpan(["mop"],d,t)}else{for(var g=[],f=1;f{var r;if(e.symbol)r=new zt("mo",[Bt(e.name,e.mode)]),m.contains(la,e.name)&&r.setAttribute("largeop","false");else if(e.body)r=new zt("mo",qt(e.body,t));else{r=new zt("mi",[new At(e.name.slice(1))]);var a=new zt("mo",[Bt("\u2061","text")]);r=e.parentIsSupSub?new zt("mrow",[r,a]):Mt([r,a])}return r},ca={"\u220f":"\\prod","\u2210":"\\coprod","\u2211":"\\sum","\u22c0":"\\bigwedge","\u22c1":"\\bigvee","\u22c2":"\\bigcap","\u22c3":"\\bigcup","\u2a00":"\\bigodot","\u2a01":"\\bigoplus","\u2a02":"\\bigotimes","\u2a04":"\\biguplus","\u2a06":"\\bigsqcup"};ot({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","\u220f","\u2210","\u2211","\u22c0","\u22c1","\u22c2","\u22c3","\u2a00","\u2a01","\u2a02","\u2a04","\u2a06"],props:{numArgs:0},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=a;return 1===n.length&&(n=ca[n]),{type:"op",mode:r.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:n}},htmlBuilder:ha,mathmlBuilder:ma}),ot({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"op",mode:r.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:ht(a)}},htmlBuilder:ha,mathmlBuilder:ma});var pa={"\u222b":"\\int","\u222c":"\\iint","\u222d":"\\iiint","\u222e":"\\oint","\u222f":"\\oiint","\u2230":"\\oiiint"};ot({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:ha,mathmlBuilder:ma}),ot({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:ha,mathmlBuilder:ma}),ot({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","\u222b","\u222c","\u222d","\u222e","\u222f","\u2230"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e,a=r;return 1===a.length&&(a=pa[a]),{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:a}},htmlBuilder:ha,mathmlBuilder:ma});var ua=(e,t)=>{var r,a,n,i,o=!1;if("supsub"===e.type?(r=e.sup,a=e.sub,n=Gt(e.base,"operatorname"),o=!0):n=Gt(e,"operatorname"),n.body.length>0){for(var s=n.body.map((e=>{var t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e})),l=gt(s,t.withFont("mathrm"),!0),h=0;h{var{parser:r,funcName:a}=e,n=t[0];return{type:"operatorname",mode:r.mode,body:ht(n),alwaysHandleSupSub:"\\operatornamewithlimits"===a,limits:!1,parentIsSupSub:!1}},htmlBuilder:ua,mathmlBuilder:(e,t)=>{for(var r=qt(e.body,t.withFont("mathrm")),a=!0,n=0;ne.toText())).join("");r=[new Tt.TextNode(s)]}var l=new Tt.MathNode("mi",r);l.setAttribute("mathvariant","normal");var h=new Tt.MathNode("mo",[Bt("\u2061","text")]);return e.parentIsSupSub?new Tt.MathNode("mrow",[l,h]):Tt.newDocumentFragment([l,h])}}),Vr("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@"),st({type:"ordgroup",htmlBuilder:(e,t)=>e.semisimple?Ke.makeFragment(gt(e.body,t,!1)):Ke.makeSpan(["mord"],gt(e.body,t,!0),t),mathmlBuilder:(e,t)=>It(e.body,t,!0)}),ot({type:"overline",names:["\\overline"],props:{numArgs:1},handler(e,t){var{parser:r}=e,a=t[0];return{type:"overline",mode:r.mode,body:a}},htmlBuilder(e,t){var r=wt(e.body,t.havingCrampedStyle()),a=Ke.makeLineSpan("overline-line",t),n=t.fontMetrics().defaultRuleThickness,i=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r},{type:"kern",size:3*n},{type:"elem",elem:a},{type:"kern",size:n}]},t);return Ke.makeSpan(["mord","overline"],[i],t)},mathmlBuilder(e,t){var r=new Tt.MathNode("mo",[new Tt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var a=new Tt.MathNode("mover",[Rt(e.body,t),r]);return a.setAttribute("accent","true"),a}}),ot({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"phantom",mode:r.mode,body:ht(a)}},htmlBuilder:(e,t)=>{var r=gt(e.body,t.withPhantom(),!1);return Ke.makeFragment(r)},mathmlBuilder:(e,t)=>{var r=qt(e.body,t);return new Tt.MathNode("mphantom",r)}}),ot({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"hphantom",mode:r.mode,body:a}},htmlBuilder:(e,t)=>{var r=Ke.makeSpan([],[wt(e.body,t.withPhantom())]);if(r.height=0,r.depth=0,r.children)for(var a=0;a{var r=qt(ht(e.body),t),a=new Tt.MathNode("mphantom",r),n=new Tt.MathNode("mpadded",[a]);return n.setAttribute("height","0px"),n.setAttribute("depth","0px"),n}}),ot({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"vphantom",mode:r.mode,body:a}},htmlBuilder:(e,t)=>{var r=Ke.makeSpan(["inner"],[wt(e.body,t.withPhantom())]),a=Ke.makeSpan(["fix"],[]);return Ke.makeSpan(["mord","rlap"],[r,a],t)},mathmlBuilder:(e,t)=>{var r=qt(ht(e.body),t),a=new Tt.MathNode("mphantom",r),n=new Tt.MathNode("mpadded",[a]);return n.setAttribute("width","0px"),n}}),ot({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(e,t){var{parser:r}=e,a=Gt(t[0],"size").value,n=t[1];return{type:"raisebox",mode:r.mode,dy:a,body:n}},htmlBuilder(e,t){var r=wt(e.body,t),a=F(e.dy,t);return Ke.makeVList({positionType:"shift",positionData:-a,children:[{type:"elem",elem:r}]},t)},mathmlBuilder(e,t){var r=new Tt.MathNode("mpadded",[Rt(e.body,t)]),a=e.dy.number+e.dy.unit;return r.setAttribute("voffset",a),r}}),ot({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0},handler(e){var{parser:t}=e;return{type:"internal",mode:t.mode}}}),ot({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,argTypes:["size","size","size"]},handler(e,t,r){var{parser:a}=e,n=r[0],i=Gt(t[0],"size"),o=Gt(t[1],"size");return{type:"rule",mode:a.mode,shift:n&&Gt(n,"size").value,width:i.value,height:o.value}},htmlBuilder(e,t){var r=Ke.makeSpan(["mord","rule"],[],t),a=F(e.width,t),n=F(e.height,t),i=e.shift?F(e.shift,t):0;return r.style.borderRightWidth=G(a),r.style.borderTopWidth=G(n),r.style.bottom=G(i),r.width=a,r.height=n+i,r.depth=-i,r.maxFontSize=1.125*n*t.sizeMultiplier,r},mathmlBuilder(e,t){var r=F(e.width,t),a=F(e.height,t),n=e.shift?F(e.shift,t):0,i=t.color&&t.getColor()||"black",o=new Tt.MathNode("mspace");o.setAttribute("mathbackground",i),o.setAttribute("width",G(r)),o.setAttribute("height",G(a));var s=new Tt.MathNode("mpadded",[o]);return n>=0?s.setAttribute("height",G(n)):(s.setAttribute("height",G(n)),s.setAttribute("depth",G(-n))),s.setAttribute("voffset",G(n)),s}});var ga=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];ot({type:"sizing",names:ga,props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{var{breakOnTokenText:r,funcName:a,parser:n}=e,i=n.parseExpression(!1,r);return{type:"sizing",mode:n.mode,size:ga.indexOf(a)+1,body:i}},htmlBuilder:(e,t)=>{var r=t.havingSize(e.size);return da(e.body,r,t)},mathmlBuilder:(e,t)=>{var r=t.havingSize(e.size),a=qt(e.body,r),n=new Tt.MathNode("mstyle",a);return n.setAttribute("mathsize",G(r.sizeMultiplier)),n}}),ot({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:(e,t,r)=>{var{parser:a}=e,n=!1,i=!1,o=r[0]&&Gt(r[0],"ordgroup");if(o)for(var s="",l=0;l{var r=Ke.makeSpan([],[wt(e.body,t)]);if(!e.smashHeight&&!e.smashDepth)return r;if(e.smashHeight&&(r.height=0,r.children))for(var a=0;a{var r=new Tt.MathNode("mpadded",[Rt(e.body,t)]);return e.smashHeight&&r.setAttribute("height","0px"),e.smashDepth&&r.setAttribute("depth","0px"),r}}),ot({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){var{parser:a}=e,n=r[0],i=t[0];return{type:"sqrt",mode:a.mode,body:i,index:n}},htmlBuilder(e,t){var r=wt(e.body,t.havingCrampedStyle());0===r.height&&(r.height=t.fontMetrics().xHeight),r=Ke.wrapFragment(r,t);var a=t.fontMetrics().defaultRuleThickness,n=a;t.style.idr.height+r.depth+i&&(i=(i+m-r.height-r.depth)/2);var c=s.height-r.height-i-l;r.style.paddingLeft=G(h);var p=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+c)},{type:"elem",elem:s},{type:"kern",size:l}]},t);if(e.index){var u=t.havingStyle(k.SCRIPTSCRIPT),d=wt(e.index,u,t),g=.6*(p.height-p.depth),f=Ke.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:d}]},t),v=Ke.makeSpan(["root"],[f]);return Ke.makeSpan(["mord","sqrt"],[v,p],t)}return Ke.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder(e,t){var{body:r,index:a}=e;return a?new Tt.MathNode("mroot",[Rt(r,t),Rt(a,t)]):new Tt.MathNode("msqrt",[Rt(r,t)])}});var fa={display:k.DISPLAY,text:k.TEXT,script:k.SCRIPT,scriptscript:k.SCRIPTSCRIPT};ot({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e,t){var{breakOnTokenText:r,funcName:a,parser:n}=e,i=n.parseExpression(!0,r),o=a.slice(1,a.length-5);return{type:"styling",mode:n.mode,style:o,body:i}},htmlBuilder(e,t){var r=fa[e.style],a=t.havingStyle(r).withFont("");return da(e.body,a,t)},mathmlBuilder(e,t){var r=fa[e.style],a=t.havingStyle(r),n=qt(e.body,a),i=new Tt.MathNode("mstyle",n),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});st({type:"supsub",htmlBuilder(e,t){var r=function(e,t){var r=e.base;return r?"op"===r.type?r.limits&&(t.style.size===k.DISPLAY.size||r.alwaysHandleSupSub)?ha:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===k.DISPLAY.size||r.limits)?ua:null:"accent"===r.type?m.isCharacterBox(r.base)?Xt:null:"horizBrace"===r.type&&!e.sub===r.isOver?na:null:null}(e,t);if(r)return r(e,t);var a,n,i,{base:o,sup:s,sub:l}=e,h=wt(o,t),c=t.fontMetrics(),p=0,u=0,d=o&&m.isCharacterBox(o);if(s){var g=t.havingStyle(t.style.sup());a=wt(s,g,t),d||(p=h.height-g.fontMetrics().supDrop*g.sizeMultiplier/t.sizeMultiplier)}if(l){var f=t.havingStyle(t.style.sub());n=wt(l,f,t),d||(u=h.depth+f.fontMetrics().subDrop*f.sizeMultiplier/t.sizeMultiplier)}i=t.style===k.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;var v,b=t.sizeMultiplier,y=G(.5/c.ptPerEm/b),x=null;if(n){var w=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(h instanceof K||w)&&(x=G(-h.italic))}if(a&&n){p=Math.max(p,i,a.depth+.25*c.xHeight),u=Math.max(u,c.sub2);var S=4*c.defaultRuleThickness;if(p-a.depth-(n.height-u)0&&(p+=M,u-=M)}var z=[{type:"elem",elem:n,shift:u,marginRight:y,marginLeft:x},{type:"elem",elem:a,shift:-p,marginRight:y}];v=Ke.makeVList({positionType:"individualShift",children:z},t)}else if(n){u=Math.max(u,c.sub1,n.height-.8*c.xHeight);var A=[{type:"elem",elem:n,marginLeft:x,marginRight:y}];v=Ke.makeVList({positionType:"shift",positionData:u,children:A},t)}else{if(!a)throw new Error("supsub must have either sup or sub.");p=Math.max(p,i,a.depth+.25*c.xHeight),v=Ke.makeVList({positionType:"shift",positionData:-p,children:[{type:"elem",elem:a,marginRight:y}]},t)}var T=yt(h,"right")||"mord";return Ke.makeSpan([T],[h,Ke.makeSpan(["msupsub"],[v])],t)},mathmlBuilder(e,t){var r,a=!1;e.base&&"horizBrace"===e.base.type&&!!e.sup===e.base.isOver&&(a=!0,r=e.base.isOver),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);var n,i=[Rt(e.base,t)];if(e.sub&&i.push(Rt(e.sub,t)),e.sup&&i.push(Rt(e.sup,t)),a)n=r?"mover":"munder";else if(e.sub)if(e.sup){var o=e.base;n=o&&"op"===o.type&&o.limits&&t.style===k.DISPLAY||o&&"operatorname"===o.type&&o.alwaysHandleSupSub&&(t.style===k.DISPLAY||o.limits)?"munderover":"msubsup"}else{var s=e.base;n=s&&"op"===s.type&&s.limits&&(t.style===k.DISPLAY||s.alwaysHandleSupSub)||s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(s.limits||t.style===k.DISPLAY)?"munder":"msub"}else{var l=e.base;n=l&&"op"===l.type&&l.limits&&(t.style===k.DISPLAY||l.alwaysHandleSupSub)||l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||t.style===k.DISPLAY)?"mover":"msup"}return new Tt.MathNode(n,i)}}),st({type:"atom",htmlBuilder:(e,t)=>Ke.mathsym(e.text,e.mode,t,["m"+e.family]),mathmlBuilder(e,t){var r=new Tt.MathNode("mo",[Bt(e.text,e.mode)]);if("bin"===e.family){var a=Nt(e,t);"bold-italic"===a&&r.setAttribute("mathvariant",a)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});var va={mi:"italic",mn:"normal",mtext:"normal"};st({type:"mathord",htmlBuilder:(e,t)=>Ke.makeOrd(e,t,"mathord"),mathmlBuilder(e,t){var r=new Tt.MathNode("mi",[Bt(e.text,e.mode,t)]),a=Nt(e,t)||"italic";return a!==va[r.type]&&r.setAttribute("mathvariant",a),r}}),st({type:"textord",htmlBuilder:(e,t)=>Ke.makeOrd(e,t,"textord"),mathmlBuilder(e,t){var r,a=Bt(e.text,e.mode,t),n=Nt(e,t)||"normal";return r="text"===e.mode?new Tt.MathNode("mtext",[a]):/[0-9]/.test(e.text)?new Tt.MathNode("mn",[a]):"\\prime"===e.text?new Tt.MathNode("mo",[a]):new Tt.MathNode("mi",[a]),n!==va[r.type]&&r.setAttribute("mathvariant",n),r}});var ba={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},ya={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};st({type:"spacing",htmlBuilder(e,t){if(ya.hasOwnProperty(e.text)){var r=ya[e.text].className||"";if("text"===e.mode){var a=Ke.makeOrd(e,t,"textord");return a.classes.push(r),a}return Ke.makeSpan(["mspace",r],[Ke.mathsym(e.text,e.mode,t)],t)}if(ba.hasOwnProperty(e.text))return Ke.makeSpan(["mspace",ba[e.text]],[],t);throw new i('Unknown type of space "'+e.text+'"')},mathmlBuilder(e,t){if(!ya.hasOwnProperty(e.text)){if(ba.hasOwnProperty(e.text))return new Tt.MathNode("mspace");throw new i('Unknown type of space "'+e.text+'"')}return new Tt.MathNode("mtext",[new Tt.TextNode("\xa0")])}});var xa=()=>{var e=new Tt.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};st({type:"tag",mathmlBuilder(e,t){var r=new Tt.MathNode("mtable",[new Tt.MathNode("mtr",[xa(),new Tt.MathNode("mtd",[It(e.body,t)]),xa(),new Tt.MathNode("mtd",[It(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});var wa={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},ka={"\\textbf":"textbf","\\textmd":"textmd"},Sa={"\\textit":"textit","\\textup":"textup"},Ma=(e,t)=>{var r=e.font;return r?wa[r]?t.withTextFontFamily(wa[r]):ka[r]?t.withTextFontWeight(ka[r]):t.withTextFontShape(Sa[r]):t};ot({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];return{type:"text",mode:r.mode,body:ht(n),font:a}},htmlBuilder(e,t){var r=Ma(e,t),a=gt(e.body,r,!0);return Ke.makeSpan(["mord","text"],a,r)},mathmlBuilder(e,t){var r=Ma(e,t);return It(e.body,r)}}),ot({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"underline",mode:r.mode,body:t[0]}},htmlBuilder(e,t){var r=wt(e.body,t),a=Ke.makeLineSpan("underline-line",t),n=t.fontMetrics().defaultRuleThickness,i=Ke.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:n},{type:"elem",elem:a},{type:"kern",size:3*n},{type:"elem",elem:r}]},t);return Ke.makeSpan(["mord","underline"],[i],t)},mathmlBuilder(e,t){var r=new Tt.MathNode("mo",[new Tt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var a=new Tt.MathNode("munder",[Rt(e.body,t),r]);return a.setAttribute("accentunder","true"),a}}),ot({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(e,t){var{parser:r}=e;return{type:"vcenter",mode:r.mode,body:t[0]}},htmlBuilder(e,t){var r=wt(e.body,t),a=t.fontMetrics().axisHeight,n=.5*(r.height-a-(r.depth+a));return Ke.makeVList({positionType:"shift",positionData:n,children:[{type:"elem",elem:r}]},t)},mathmlBuilder:(e,t)=>new Tt.MathNode("mpadded",[Rt(e.body,t)],["vcenter"])}),ot({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(e,t,r){throw new i("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(e,t){for(var r=za(e),a=[],n=t.havingStyle(t.style.text()),i=0;ie.body.replace(/ /g,e.star?"\u2423":"\xa0"),Aa=at,Ta="[ \r\n\t]",Ba="(\\\\[a-zA-Z@]+)"+Ta+"*",Ca="[\u0300-\u036f]",Na=new RegExp(Ca+"+$"),qa="("+Ta+"+)|\\\\(\n|[ \r\t]+\n?)[ \r\t]*|([!-\\[\\]-\u2027\u202a-\ud7ff\uf900-\uffff]"+Ca+"*|[\ud800-\udbff][\udc00-\udfff]"+Ca+"*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5|"+Ba+"|\\\\[^\ud800-\udfff])";class Ia{constructor(e,t){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=e,this.settings=t,this.tokenRegex=new RegExp(qa,"g"),this.catcodes={"%":14,"~":13}}setCatcode(e,t){this.catcodes[e]=t}lex(){var e=this.input,t=this.tokenRegex.lastIndex;if(t===e.length)return new n("EOF",new a(this,t,t));var r=this.tokenRegex.exec(e);if(null===r||r.index!==t)throw new i("Unexpected character: '"+e[t]+"'",new n(e[t],new a(this,t,t+1)));var o=r[6]||r[3]||(r[2]?"\\ ":" ");if(14===this.catcodes[o]){var s=e.indexOf("\n",this.tokenRegex.lastIndex);return-1===s?(this.tokenRegex.lastIndex=e.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=s+1,this.lex()}return new n(o,new a(this,t,this.tokenRegex.lastIndex))}}class Ra{constructor(e,t){void 0===e&&(e={}),void 0===t&&(t={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=t,this.builtins=e,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(0===this.undefStack.length)throw new i("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var e=this.undefStack.pop();for(var t in e)e.hasOwnProperty(t)&&(null==e[t]?delete this.current[t]:this.current[t]=e[t])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)}get(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]}set(e,t,r){if(void 0===r&&(r=!1),r){for(var a=0;a0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var n=this.undefStack[this.undefStack.length-1];n&&!n.hasOwnProperty(e)&&(n[e]=this.current[e])}null==t?delete this.current[e]:this.current[e]=t}}var Ha=Dr;Vr("\\noexpand",(function(e){var t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}})),Vr("\\expandafter",(function(e){var t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}})),Vr("\\@firstoftwo",(function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}})),Vr("\\@secondoftwo",(function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}})),Vr("\\@ifnextchar",(function(e){var t=e.consumeArgs(3);e.consumeSpaces();var r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}})),Vr("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),Vr("\\TextOrMath",(function(e){var t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}}));var Oa={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};Vr("\\char",(function(e){var t,r=e.popToken(),a="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if("\\"===(r=e.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new i("\\char` missing argument");a=r.text.charCodeAt(0)}else t=10;if(t){if(null==(a=Oa[r.text])||a>=t)throw new i("Invalid base-"+t+" digit "+r.text);for(var n;null!=(n=Oa[e.future().text])&&n{var a=e.consumeArg().tokens;if(1!==a.length)throw new i("\\newcommand's first argument must be a macro name");var n=a[0].text,o=e.isDefined(n);if(o&&!t)throw new i("\\newcommand{"+n+"} attempting to redefine "+n+"; use \\renewcommand");if(!o&&!r)throw new i("\\renewcommand{"+n+"} when command "+n+" does not yet exist; use \\newcommand");var s=0;if(1===(a=e.consumeArg().tokens).length&&"["===a[0].text){for(var l="",h=e.expandNextToken();"]"!==h.text&&"EOF"!==h.text;)l+=h.text,h=e.expandNextToken();if(!l.match(/^\s*[0-9]+\s*$/))throw new i("Invalid number of arguments: "+l);s=parseInt(l),a=e.consumeArg().tokens}return e.macros.set(n,{tokens:a,numArgs:s}),""};Vr("\\newcommand",(e=>Ea(e,!1,!0))),Vr("\\renewcommand",(e=>Ea(e,!0,!1))),Vr("\\providecommand",(e=>Ea(e,!0,!0))),Vr("\\message",(e=>{var t=e.consumeArgs(1)[0];return console.log(t.reverse().map((e=>e.text)).join("")),""})),Vr("\\errmessage",(e=>{var t=e.consumeArgs(1)[0];return console.error(t.reverse().map((e=>e.text)).join("")),""})),Vr("\\show",(e=>{var t=e.popToken(),r=t.text;return console.log(t,e.macros.get(r),Aa[r],ne.math[r],ne.text[r]),""})),Vr("\\bgroup","{"),Vr("\\egroup","}"),Vr("~","\\nobreakspace"),Vr("\\lq","`"),Vr("\\rq","'"),Vr("\\aa","\\r a"),Vr("\\AA","\\r A"),Vr("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`\xa9}"),Vr("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}"),Vr("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xae}"),Vr("\u212c","\\mathscr{B}"),Vr("\u2130","\\mathscr{E}"),Vr("\u2131","\\mathscr{F}"),Vr("\u210b","\\mathscr{H}"),Vr("\u2110","\\mathscr{I}"),Vr("\u2112","\\mathscr{L}"),Vr("\u2133","\\mathscr{M}"),Vr("\u211b","\\mathscr{R}"),Vr("\u212d","\\mathfrak{C}"),Vr("\u210c","\\mathfrak{H}"),Vr("\u2128","\\mathfrak{Z}"),Vr("\\Bbbk","\\Bbb{k}"),Vr("\xb7","\\cdotp"),Vr("\\llap","\\mathllap{\\textrm{#1}}"),Vr("\\rlap","\\mathrlap{\\textrm{#1}}"),Vr("\\clap","\\mathclap{\\textrm{#1}}"),Vr("\\mathstrut","\\vphantom{(}"),Vr("\\underbar","\\underline{\\text{#1}}"),Vr("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'),Vr("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}"),Vr("\\ne","\\neq"),Vr("\u2260","\\neq"),Vr("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}"),Vr("\u2209","\\notin"),Vr("\u2258","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}"),Vr("\u2259","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}"),Vr("\u225a","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225a}}"),Vr("\u225b","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225b}}"),Vr("\u225d","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225d}}"),Vr("\u225e","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225e}}"),Vr("\u225f","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225f}}"),Vr("\u27c2","\\perp"),Vr("\u203c","\\mathclose{!\\mkern-0.8mu!}"),Vr("\u220c","\\notni"),Vr("\u231c","\\ulcorner"),Vr("\u231d","\\urcorner"),Vr("\u231e","\\llcorner"),Vr("\u231f","\\lrcorner"),Vr("\xa9","\\copyright"),Vr("\xae","\\textregistered"),Vr("\ufe0f","\\textregistered"),Vr("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}'),Vr("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}'),Vr("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}'),Vr("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}'),Vr("\\vdots","\\mathord{\\varvdots\\rule{0pt}{15pt}}"),Vr("\u22ee","\\vdots"),Vr("\\varGamma","\\mathit{\\Gamma}"),Vr("\\varDelta","\\mathit{\\Delta}"),Vr("\\varTheta","\\mathit{\\Theta}"),Vr("\\varLambda","\\mathit{\\Lambda}"),Vr("\\varXi","\\mathit{\\Xi}"),Vr("\\varPi","\\mathit{\\Pi}"),Vr("\\varSigma","\\mathit{\\Sigma}"),Vr("\\varUpsilon","\\mathit{\\Upsilon}"),Vr("\\varPhi","\\mathit{\\Phi}"),Vr("\\varPsi","\\mathit{\\Psi}"),Vr("\\varOmega","\\mathit{\\Omega}"),Vr("\\substack","\\begin{subarray}{c}#1\\end{subarray}"),Vr("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax"),Vr("\\boxed","\\fbox{$\\displaystyle{#1}$}"),Vr("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;"),Vr("\\implies","\\DOTSB\\;\\Longrightarrow\\;"),Vr("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;");var La={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};Vr("\\dots",(function(e){var t="\\dotso",r=e.expandAfterFuture().text;return r in La?t=La[r]:("\\not"===r.slice(0,4)||r in ne.math&&m.contains(["bin","rel"],ne.math[r].group))&&(t="\\dotsb"),t}));var Da={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};Vr("\\dotso",(function(e){return e.future().text in Da?"\\ldots\\,":"\\ldots"})),Vr("\\dotsc",(function(e){var t=e.future().text;return t in Da&&","!==t?"\\ldots\\,":"\\ldots"})),Vr("\\cdots",(function(e){return e.future().text in Da?"\\@cdots\\,":"\\@cdots"})),Vr("\\dotsb","\\cdots"),Vr("\\dotsm","\\cdots"),Vr("\\dotsi","\\!\\cdots"),Vr("\\dotsx","\\ldots\\,"),Vr("\\DOTSI","\\relax"),Vr("\\DOTSB","\\relax"),Vr("\\DOTSX","\\relax"),Vr("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),Vr("\\,","\\tmspace+{3mu}{.1667em}"),Vr("\\thinspace","\\,"),Vr("\\>","\\mskip{4mu}"),Vr("\\:","\\tmspace+{4mu}{.2222em}"),Vr("\\medspace","\\:"),Vr("\\;","\\tmspace+{5mu}{.2777em}"),Vr("\\thickspace","\\;"),Vr("\\!","\\tmspace-{3mu}{.1667em}"),Vr("\\negthinspace","\\!"),Vr("\\negmedspace","\\tmspace-{4mu}{.2222em}"),Vr("\\negthickspace","\\tmspace-{5mu}{.277em}"),Vr("\\enspace","\\kern.5em "),Vr("\\enskip","\\hskip.5em\\relax"),Vr("\\quad","\\hskip1em\\relax"),Vr("\\qquad","\\hskip2em\\relax"),Vr("\\tag","\\@ifstar\\tag@literal\\tag@paren"),Vr("\\tag@paren","\\tag@literal{({#1})}"),Vr("\\tag@literal",(e=>{if(e.macros.get("\\df@tag"))throw new i("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"})),Vr("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),Vr("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),Vr("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),Vr("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),Vr("\\newline","\\\\\\relax"),Vr("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var Va=G(C["Main-Regular"]["T".charCodeAt(0)][1]-.7*C["Main-Regular"]["A".charCodeAt(0)][1]);Vr("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Va+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),Vr("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Va+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),Vr("\\hspace","\\@ifstar\\@hspacer\\@hspace"),Vr("\\@hspace","\\hskip #1\\relax"),Vr("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),Vr("\\ordinarycolon",":"),Vr("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),Vr("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),Vr("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),Vr("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),Vr("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),Vr("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),Vr("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),Vr("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),Vr("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),Vr("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),Vr("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),Vr("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),Vr("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),Vr("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),Vr("\u2237","\\dblcolon"),Vr("\u2239","\\eqcolon"),Vr("\u2254","\\coloneqq"),Vr("\u2255","\\eqqcolon"),Vr("\u2a74","\\Coloneqq"),Vr("\\ratio","\\vcentcolon"),Vr("\\coloncolon","\\dblcolon"),Vr("\\colonequals","\\coloneqq"),Vr("\\coloncolonequals","\\Coloneqq"),Vr("\\equalscolon","\\eqqcolon"),Vr("\\equalscoloncolon","\\Eqqcolon"),Vr("\\colonminus","\\coloneq"),Vr("\\coloncolonminus","\\Coloneq"),Vr("\\minuscolon","\\eqcolon"),Vr("\\minuscoloncolon","\\Eqcolon"),Vr("\\coloncolonapprox","\\Colonapprox"),Vr("\\coloncolonsim","\\Colonsim"),Vr("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Vr("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Vr("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Vr("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Vr("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),Vr("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),Vr("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),Vr("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),Vr("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),Vr("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),Vr("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),Vr("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),Vr("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),Vr("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),Vr("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),Vr("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),Vr("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),Vr("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),Vr("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),Vr("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),Vr("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),Vr("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),Vr("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),Vr("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),Vr("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),Vr("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),Vr("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),Vr("\\imath","\\html@mathml{\\@imath}{\u0131}"),Vr("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),Vr("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),Vr("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),Vr("\u27e6","\\llbracket"),Vr("\u27e7","\\rrbracket"),Vr("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),Vr("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),Vr("\u2983","\\lBrace"),Vr("\u2984","\\rBrace"),Vr("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),Vr("\u29b5","\\minuso"),Vr("\\darr","\\downarrow"),Vr("\\dArr","\\Downarrow"),Vr("\\Darr","\\Downarrow"),Vr("\\lang","\\langle"),Vr("\\rang","\\rangle"),Vr("\\uarr","\\uparrow"),Vr("\\uArr","\\Uparrow"),Vr("\\Uarr","\\Uparrow"),Vr("\\N","\\mathbb{N}"),Vr("\\R","\\mathbb{R}"),Vr("\\Z","\\mathbb{Z}"),Vr("\\alef","\\aleph"),Vr("\\alefsym","\\aleph"),Vr("\\Alpha","\\mathrm{A}"),Vr("\\Beta","\\mathrm{B}"),Vr("\\bull","\\bullet"),Vr("\\Chi","\\mathrm{X}"),Vr("\\clubs","\\clubsuit"),Vr("\\cnums","\\mathbb{C}"),Vr("\\Complex","\\mathbb{C}"),Vr("\\Dagger","\\ddagger"),Vr("\\diamonds","\\diamondsuit"),Vr("\\empty","\\emptyset"),Vr("\\Epsilon","\\mathrm{E}"),Vr("\\Eta","\\mathrm{H}"),Vr("\\exist","\\exists"),Vr("\\harr","\\leftrightarrow"),Vr("\\hArr","\\Leftrightarrow"),Vr("\\Harr","\\Leftrightarrow"),Vr("\\hearts","\\heartsuit"),Vr("\\image","\\Im"),Vr("\\infin","\\infty"),Vr("\\Iota","\\mathrm{I}"),Vr("\\isin","\\in"),Vr("\\Kappa","\\mathrm{K}"),Vr("\\larr","\\leftarrow"),Vr("\\lArr","\\Leftarrow"),Vr("\\Larr","\\Leftarrow"),Vr("\\lrarr","\\leftrightarrow"),Vr("\\lrArr","\\Leftrightarrow"),Vr("\\Lrarr","\\Leftrightarrow"),Vr("\\Mu","\\mathrm{M}"),Vr("\\natnums","\\mathbb{N}"),Vr("\\Nu","\\mathrm{N}"),Vr("\\Omicron","\\mathrm{O}"),Vr("\\plusmn","\\pm"),Vr("\\rarr","\\rightarrow"),Vr("\\rArr","\\Rightarrow"),Vr("\\Rarr","\\Rightarrow"),Vr("\\real","\\Re"),Vr("\\reals","\\mathbb{R}"),Vr("\\Reals","\\mathbb{R}"),Vr("\\Rho","\\mathrm{P}"),Vr("\\sdot","\\cdot"),Vr("\\sect","\\S"),Vr("\\spades","\\spadesuit"),Vr("\\sub","\\subset"),Vr("\\sube","\\subseteq"),Vr("\\supe","\\supseteq"),Vr("\\Tau","\\mathrm{T}"),Vr("\\thetasym","\\vartheta"),Vr("\\weierp","\\wp"),Vr("\\Zeta","\\mathrm{Z}"),Vr("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),Vr("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),Vr("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),Vr("\\bra","\\mathinner{\\langle{#1}|}"),Vr("\\ket","\\mathinner{|{#1}\\rangle}"),Vr("\\braket","\\mathinner{\\langle{#1}\\rangle}"),Vr("\\Bra","\\left\\langle#1\\right|"),Vr("\\Ket","\\left|#1\\right\\rangle");var Pa=e=>t=>{var r=t.consumeArg().tokens,a=t.consumeArg().tokens,n=t.consumeArg().tokens,i=t.consumeArg().tokens,o=t.macros.get("|"),s=t.macros.get("\\|");t.macros.beginGroup();var l=t=>r=>{e&&(r.macros.set("|",o),n.length&&r.macros.set("\\|",s));var i=t;!t&&n.length&&("|"===r.future().text&&(r.popToken(),i=!0));return{tokens:i?n:a,numArgs:0}};t.macros.set("|",l(!1)),n.length&&t.macros.set("\\|",l(!0));var h=t.consumeArg().tokens,m=t.expandTokens([...i,...h,...r]);return t.macros.endGroup(),{tokens:m.reverse(),numArgs:0}};Vr("\\bra@ket",Pa(!1)),Vr("\\bra@set",Pa(!0)),Vr("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"),Vr("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"),Vr("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"),Vr("\\angln","{\\angl n}"),Vr("\\blue","\\textcolor{##6495ed}{#1}"),Vr("\\orange","\\textcolor{##ffa500}{#1}"),Vr("\\pink","\\textcolor{##ff00af}{#1}"),Vr("\\red","\\textcolor{##df0030}{#1}"),Vr("\\green","\\textcolor{##28ae7b}{#1}"),Vr("\\gray","\\textcolor{gray}{#1}"),Vr("\\purple","\\textcolor{##9d38bd}{#1}"),Vr("\\blueA","\\textcolor{##ccfaff}{#1}"),Vr("\\blueB","\\textcolor{##80f6ff}{#1}"),Vr("\\blueC","\\textcolor{##63d9ea}{#1}"),Vr("\\blueD","\\textcolor{##11accd}{#1}"),Vr("\\blueE","\\textcolor{##0c7f99}{#1}"),Vr("\\tealA","\\textcolor{##94fff5}{#1}"),Vr("\\tealB","\\textcolor{##26edd5}{#1}"),Vr("\\tealC","\\textcolor{##01d1c1}{#1}"),Vr("\\tealD","\\textcolor{##01a995}{#1}"),Vr("\\tealE","\\textcolor{##208170}{#1}"),Vr("\\greenA","\\textcolor{##b6ffb0}{#1}"),Vr("\\greenB","\\textcolor{##8af281}{#1}"),Vr("\\greenC","\\textcolor{##74cf70}{#1}"),Vr("\\greenD","\\textcolor{##1fab54}{#1}"),Vr("\\greenE","\\textcolor{##0d923f}{#1}"),Vr("\\goldA","\\textcolor{##ffd0a9}{#1}"),Vr("\\goldB","\\textcolor{##ffbb71}{#1}"),Vr("\\goldC","\\textcolor{##ff9c39}{#1}"),Vr("\\goldD","\\textcolor{##e07d10}{#1}"),Vr("\\goldE","\\textcolor{##a75a05}{#1}"),Vr("\\redA","\\textcolor{##fca9a9}{#1}"),Vr("\\redB","\\textcolor{##ff8482}{#1}"),Vr("\\redC","\\textcolor{##f9685d}{#1}"),Vr("\\redD","\\textcolor{##e84d39}{#1}"),Vr("\\redE","\\textcolor{##bc2612}{#1}"),Vr("\\maroonA","\\textcolor{##ffbde0}{#1}"),Vr("\\maroonB","\\textcolor{##ff92c6}{#1}"),Vr("\\maroonC","\\textcolor{##ed5fa6}{#1}"),Vr("\\maroonD","\\textcolor{##ca337c}{#1}"),Vr("\\maroonE","\\textcolor{##9e034e}{#1}"),Vr("\\purpleA","\\textcolor{##ddd7ff}{#1}"),Vr("\\purpleB","\\textcolor{##c6b9fc}{#1}"),Vr("\\purpleC","\\textcolor{##aa87ff}{#1}"),Vr("\\purpleD","\\textcolor{##7854ab}{#1}"),Vr("\\purpleE","\\textcolor{##543b78}{#1}"),Vr("\\mintA","\\textcolor{##f5f9e8}{#1}"),Vr("\\mintB","\\textcolor{##edf2df}{#1}"),Vr("\\mintC","\\textcolor{##e0e5cc}{#1}"),Vr("\\grayA","\\textcolor{##f6f7f7}{#1}"),Vr("\\grayB","\\textcolor{##f0f1f2}{#1}"),Vr("\\grayC","\\textcolor{##e3e5e6}{#1}"),Vr("\\grayD","\\textcolor{##d6d8da}{#1}"),Vr("\\grayE","\\textcolor{##babec2}{#1}"),Vr("\\grayF","\\textcolor{##888d93}{#1}"),Vr("\\grayG","\\textcolor{##626569}{#1}"),Vr("\\grayH","\\textcolor{##3b3e40}{#1}"),Vr("\\grayI","\\textcolor{##21242c}{#1}"),Vr("\\kaBlue","\\textcolor{##314453}{#1}"),Vr("\\kaGreen","\\textcolor{##71B307}{#1}");var Fa={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0};class Ga{constructor(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new Ra(Ha,t.macros),this.mode=r,this.stack=[]}feed(e){this.lexer=new Ia(e,this.settings)}switchMode(e){this.mode=e}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(e){this.stack.push(e)}pushTokens(e){this.stack.push(...e)}scanArgument(e){var t,r,a;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken(),({tokens:a,end:r}=this.consumeArg(["]"]))}else({tokens:a,start:t,end:r}=this.consumeArg());return this.pushToken(new n("EOF",r.loc)),this.pushTokens(a),t.range(r,"")}consumeSpaces(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}}consumeArg(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var a,n=this.future(),o=0,s=0;do{if(a=this.popToken(),t.push(a),"{"===a.text)++o;else if("}"===a.text){if(-1===--o)throw new i("Extra }",a)}else if("EOF"===a.text)throw new i("Unexpected end of input in a macro argument, expected '"+(e&&r?e[s]:"}")+"'",a);if(e&&r)if((0===o||1===o&&"{"===e[s])&&a.text===e[s]){if(++s===e.length){t.splice(-s,s);break}}else s=0}while(0!==o||r);return"{"===n.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:n,end:a}}consumeArgs(e,t){if(t){if(t.length!==e+1)throw new i("The length of delimiters doesn't match the number of args!");for(var r=t[0],a=0;athis.settings.maxExpand)throw new i("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(e){var t=this.popToken(),r=t.text,a=t.noexpand?null:this._getExpansion(r);if(null==a||e&&a.unexpandable){if(e&&null==a&&"\\"===r[0]&&!this.isDefined(r))throw new i("Undefined control sequence: "+r);return this.pushToken(t),!1}this.countExpansion(1);var n=a.tokens,o=this.consumeArgs(a.numArgs,a.delimiters);if(a.numArgs)for(var s=(n=n.slice()).length-1;s>=0;--s){var l=n[s];if("#"===l.text){if(0===s)throw new i("Incomplete placeholder at end of macro body",l);if("#"===(l=n[--s]).text)n.splice(s+1,1);else{if(!/^[1-9]$/.test(l.text))throw new i("Not a valid argument number",l);n.splice(s,2,...o[+l.text-1])}}}return this.pushTokens(n),n.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(!1===this.expandOnce()){var e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error}expandMacro(e){return this.macros.has(e)?this.expandTokens([new n(e)]):void 0}expandTokens(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;)if(!1===this.expandOnce(!0)){var a=this.stack.pop();a.treatAsRelax&&(a.noexpand=!1,a.treatAsRelax=!1),t.push(a)}return this.countExpansion(t.length),t}expandMacroAsText(e){var t=this.expandMacro(e);return t?t.map((e=>e.text)).join(""):t}_getExpansion(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){var r=this.lexer.catcodes[e];if(null!=r&&13!==r)return}var a="function"==typeof t?t(this):t;if("string"==typeof a){var n=0;if(-1!==a.indexOf("#"))for(var i=a.replace(/##/g,"");-1!==i.indexOf("#"+(n+1));)++n;for(var o=new Ia(a,this.settings),s=[],l=o.lex();"EOF"!==l.text;)s.push(l),l=o.lex();return s.reverse(),{tokens:s,numArgs:n}}return a}isDefined(e){return this.macros.has(e)||Aa.hasOwnProperty(e)||ne.math.hasOwnProperty(e)||ne.text.hasOwnProperty(e)||Fa.hasOwnProperty(e)}isExpandable(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:Aa.hasOwnProperty(e)&&!Aa[e].primitive}}var Ua=/^[\u208a\u208b\u208c\u208d\u208e\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2090\u2091\u2095\u1d62\u2c7c\u2096\u2097\u2098\u2099\u2092\u209a\u1d63\u209b\u209c\u1d64\u1d65\u2093\u1d66\u1d67\u1d68\u1d69\u1d6a]/,Ya=Object.freeze({"\u208a":"+","\u208b":"-","\u208c":"=","\u208d":"(","\u208e":")","\u2080":"0","\u2081":"1","\u2082":"2","\u2083":"3","\u2084":"4","\u2085":"5","\u2086":"6","\u2087":"7","\u2088":"8","\u2089":"9","\u2090":"a","\u2091":"e","\u2095":"h","\u1d62":"i","\u2c7c":"j","\u2096":"k","\u2097":"l","\u2098":"m","\u2099":"n","\u2092":"o","\u209a":"p","\u1d63":"r","\u209b":"s","\u209c":"t","\u1d64":"u","\u1d65":"v","\u2093":"x","\u1d66":"\u03b2","\u1d67":"\u03b3","\u1d68":"\u03c1","\u1d69":"\u03d5","\u1d6a":"\u03c7","\u207a":"+","\u207b":"-","\u207c":"=","\u207d":"(","\u207e":")","\u2070":"0","\xb9":"1","\xb2":"2","\xb3":"3","\u2074":"4","\u2075":"5","\u2076":"6","\u2077":"7","\u2078":"8","\u2079":"9","\u1d2c":"A","\u1d2e":"B","\u1d30":"D","\u1d31":"E","\u1d33":"G","\u1d34":"H","\u1d35":"I","\u1d36":"J","\u1d37":"K","\u1d38":"L","\u1d39":"M","\u1d3a":"N","\u1d3c":"O","\u1d3e":"P","\u1d3f":"R","\u1d40":"T","\u1d41":"U","\u2c7d":"V","\u1d42":"W","\u1d43":"a","\u1d47":"b","\u1d9c":"c","\u1d48":"d","\u1d49":"e","\u1da0":"f","\u1d4d":"g","\u02b0":"h","\u2071":"i","\u02b2":"j","\u1d4f":"k","\u02e1":"l","\u1d50":"m","\u207f":"n","\u1d52":"o","\u1d56":"p","\u02b3":"r","\u02e2":"s","\u1d57":"t","\u1d58":"u","\u1d5b":"v","\u02b7":"w","\u02e3":"x","\u02b8":"y","\u1dbb":"z","\u1d5d":"\u03b2","\u1d5e":"\u03b3","\u1d5f":"\u03b4","\u1d60":"\u03d5","\u1d61":"\u03c7","\u1dbf":"\u03b8"}),Xa={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"},"\u0327":{text:"\\c"}},Wa={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u1e09":"c\u0327\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\xe7":"c\u0327","\u010f":"d\u030c","\u1e0b":"d\u0307","\u1e11":"d\u0327","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u1e1d":"e\u0327\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u0229":"e\u0327","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u0123":"g\u0327","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\u1e29":"h\u0327","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u0137":"k\u0327","\u013a":"l\u0301","\u013e":"l\u030c","\u013c":"l\u0327","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\u0146":"n\u0327","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u0157":"r\u0327","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u015f":"s\u0327","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\u0163":"t\u0327","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u1e08":"C\u0327\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\xc7":"C\u0327","\u010e":"D\u030c","\u1e0a":"D\u0307","\u1e10":"D\u0327","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u1e1c":"E\u0327\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u0228":"E\u0327","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u0122":"G\u0327","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\u1e28":"H\u0327","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0136":"K\u0327","\u0139":"L\u0301","\u013d":"L\u030c","\u013b":"L\u0327","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\u0145":"N\u0327","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u0156":"R\u0327","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u015e":"S\u0327","\u0164":"T\u030c","\u1e6a":"T\u0307","\u0162":"T\u0327","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"};class _a{constructor(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new Ga(e,t,this.mode),this.settings=t,this.leftrightDepth=0}expect(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new i("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()}consume(){this.nextToken=null}fetch(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(e){this.mode=e,this.gullet.switchMode(e)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}}subparse(e){var t=this.nextToken;this.consume(),this.gullet.pushToken(new n("}")),this.gullet.pushTokens(e);var r=this.parseExpression(!1);return this.expect("}"),this.nextToken=t,r}parseExpression(e,t){for(var r=[];;){"math"===this.mode&&this.consumeSpaces();var a=this.fetch();if(-1!==_a.endOfExpression.indexOf(a.text))break;if(t&&a.text===t)break;if(e&&Aa[a.text]&&Aa[a.text].infix)break;var n=this.parseAtom(t);if(!n)break;"internal"!==n.type&&r.push(n)}return"text"===this.mode&&this.formLigatures(r),this.handleInfixNodes(r)}handleInfixNodes(e){for(var t,r=-1,a=0;a=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var l,h=ne[this.mode][t].group,m=a.range(e);if(re.hasOwnProperty(h)){var c=h;l={type:"atom",mode:this.mode,family:c,loc:m,text:t}}else l={type:h,mode:this.mode,loc:m,text:t};o=l}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(z(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),o={type:"textord",mode:"text",loc:a.range(e),text:t}}if(this.consume(),s)for(var p=0;p{n.d(t,{H:()=>l});var r=n(82933);function l(e,t){var n=e.append("foreignObject").attr("width","100000"),l=n.append("xhtml:div");l.attr("xmlns","http://www.w3.org/1999/xhtml");var o=t.label;switch(typeof o){case"function":l.insert(o);break;case"object":l.insert((function(){return o}));break;default:l.html(o)}r.AV(l,t.labelStyle),l.style("display","inline-block"),l.style("white-space","nowrap");var a=l.node().getBoundingClientRect();return n.attr("width",a.width).attr("height",a.height),n}},82933:(e,t,n)=>{n.d(t,{AV:()=>c,De:()=>o,c$:()=>p,gh:()=>a,nh:()=>d});var r=n(34963),l=n(89610);function o(e,t){return!!e.children(t).length}function a(e){return i(e.v)+":"+i(e.w)+":"+i(e.name)}var s=/:/g;function i(e){return e?String(e).replace(s,"\\:"):""}function c(e,t){t&&e.attr("style",t)}function d(e,t,n){t&&e.attr("class",t).attr("class",n+" "+e.attr("class"))}function p(e,t){var n=t.graph();if(r.A(n)){var o=n.transition;if(l.A(o))return o(e)}return e}},75937:(e,t,n)=>{n.d(t,{A:()=>o});var r=n(72453),l=n(74886);const o=(e,t)=>r.A.lang.round(l.A.parse(e)[t])},22315:(e,t,n)=>{n.d(t,{diagram:()=>i});var r=n(35860),l=(n(697),n(26312));n(86079),n(48585),n(23068),n(8058),n(21176),n(82933);n(10646);n(5664),n(91395);n(81942);l.lUB;var o=n(35900);n(74353),n(16750),n(42838),n(14075);const a={},s=function(e){const t=Object.keys(e);for(const n of t)a[n]=e[n]},i={parser:r.p,db:r.f,renderer:o.f,styles:o.a,init:e=>{e.flowchart||(e.flowchart={}),e.flowchart.arrowMarkerAbsolute=e.arrowMarkerAbsolute,s(e.flowchart),r.f.clear(),r.f.setGen("gen-1")}}},35900:(e,t,n)=>{n.d(t,{a:()=>f,f:()=>w});var r=n(697),l=n(26312),o=n(86079),a=n(8995),s=n(10646),i=n(75937),c=n(25582);const d={},p=async function(e,t,n,r,l,a){const i=r.select(`[id="${n}"]`),c=Object.keys(e);for(const d of c){const n=e[d];let r="default";n.classes.length>0&&(r=n.classes.join(" ")),r+=" flowchart-label";const c=(0,o.k)(n.styles);let p,b=void 0!==n.text?n.text:n.id;if(o.l.info("vertex",n,n.labelType),"markdown"===n.labelType)o.l.info("vertex",n,n.labelType);else if((0,o.m)((0,o.c)().flowchart.htmlLabels)){const e={label:b};p=(0,s.H)(i,e).node(),p.parentNode.removeChild(p)}else{const e=l.createElementNS("http://www.w3.org/2000/svg","text");e.setAttribute("style",c.labelStyle.replace("color:","fill:"));const t=b.split(o.e.lineBreakRegex);for(const n of t){const t=l.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","1"),t.textContent=n,e.appendChild(t)}p=e}let w=0,f="";switch(n.type){case"round":w=5,f="rect";break;case"square":case"group":default:f="rect";break;case"diamond":f="question";break;case"hexagon":f="hexagon";break;case"odd":case"odd_right":f="rect_left_inv_arrow";break;case"lean_right":f="lean_right";break;case"lean_left":f="lean_left";break;case"trapezoid":f="trapezoid";break;case"inv_trapezoid":f="inv_trapezoid";break;case"circle":f="circle";break;case"ellipse":f="ellipse";break;case"stadium":f="stadium";break;case"subroutine":f="subroutine";break;case"cylinder":f="cylinder";break;case"doublecircle":f="doublecircle"}const h=await(0,o.r)(b,(0,o.c)());t.setNode(n.id,{labelStyle:c.labelStyle,shape:f,labelText:h,labelType:n.labelType,rx:w,ry:w,class:r,style:c.style,id:n.id,link:n.link,linkTarget:n.linkTarget,tooltip:a.db.getTooltip(n.id)||"",domId:a.db.lookUpDomId(n.id),haveCallback:n.haveCallback,width:"group"===n.type?500:void 0,dir:n.dir,type:n.type,props:n.props,padding:(0,o.c)().flowchart.padding}),o.l.info("setNode",{labelStyle:c.labelStyle,labelType:n.labelType,shape:f,labelText:h,rx:w,ry:w,class:r,style:c.style,id:n.id,domId:a.db.lookUpDomId(n.id),width:"group"===n.type?500:void 0,type:n.type,dir:n.dir,props:n.props,padding:(0,o.c)().flowchart.padding})}},b=async function(e,t,n){o.l.info("abc78 edges = ",e);let r,a,s=0,i={};if(void 0!==e.defaultStyle){const t=(0,o.k)(e.defaultStyle);r=t.style,a=t.labelStyle}for(const c of e){s++;const n="L-"+c.start+"-"+c.end;void 0===i[n]?(i[n]=0,o.l.info("abc78 new entry",n,i[n])):(i[n]++,o.l.info("abc78 new entry",n,i[n]));let p=n+"-"+i[n];o.l.info("abc78 new link id to be used is",n,p,i[n]);const b="LS-"+c.start,w="LE-"+c.end,f={style:"",labelStyle:""};switch(f.minlen=c.length||1,"arrow_open"===c.type?f.arrowhead="none":f.arrowhead="normal",f.arrowTypeStart="arrow_open",f.arrowTypeEnd="arrow_open",c.type){case"double_arrow_cross":f.arrowTypeStart="arrow_cross";case"arrow_cross":f.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":f.arrowTypeStart="arrow_point";case"arrow_point":f.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":f.arrowTypeStart="arrow_circle";case"arrow_circle":f.arrowTypeEnd="arrow_circle"}let h="",u="";switch(c.stroke){case"normal":h="fill:none;",void 0!==r&&(h=r),void 0!==a&&(u=a),f.thickness="normal",f.pattern="solid";break;case"dotted":f.thickness="normal",f.pattern="dotted",f.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":f.thickness="thick",f.pattern="solid",f.style="stroke-width: 3.5px;fill:none;";break;case"invisible":f.thickness="invisible",f.pattern="solid",f.style="stroke-width: 0;fill:none;"}if(void 0!==c.style){const e=(0,o.k)(c.style);h=e.style,u=e.labelStyle}f.style=f.style+=h,f.labelStyle=f.labelStyle+=u,void 0!==c.interpolate?f.curve=(0,o.n)(c.interpolate,l.lUB):void 0!==e.defaultInterpolate?f.curve=(0,o.n)(e.defaultInterpolate,l.lUB):f.curve=(0,o.n)(d.curve,l.lUB),void 0===c.text?void 0!==c.style&&(f.arrowheadStyle="fill: #333"):(f.arrowheadStyle="fill: #333",f.labelpos="c"),f.labelType=c.labelType,f.label=await(0,o.r)(c.text.replace(o.e.lineBreakRegex,"\n"),(0,o.c)()),void 0===c.style&&(f.style=f.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),f.labelStyle=f.labelStyle.replace("color:","fill:"),f.id=p,f.classes="flowchart-link "+b+" "+w,t.setEdge(c.start,c.end,f,s)}},w={setConf:function(e){const t=Object.keys(e);for(const n of t)d[n]=e[n]},addVertices:p,addEdges:b,getClasses:function(e,t){return t.db.getClasses()},draw:async function(e,t,n,s){o.l.info("Drawing flowchart");let i=s.db.getDirection();void 0===i&&(i="TD");const{securityLevel:c,flowchart:d}=(0,o.c)(),w=d.nodeSpacing||50,f=d.rankSpacing||50;let h;"sandbox"===c&&(h=(0,l.Ltv)("#i"+t));const u="sandbox"===c?(0,l.Ltv)(h.nodes()[0].contentDocument.body):(0,l.Ltv)("body"),g="sandbox"===c?h.nodes()[0].contentDocument:document,y=new r.T({multigraph:!0,compound:!0}).setGraph({rankdir:i,nodesep:w,ranksep:f,marginx:0,marginy:0}).setDefaultEdgeLabel((function(){return{}}));let k;const x=s.db.getSubGraphs();o.l.info("Subgraphs - ",x);for(let r=x.length-1;r>=0;r--)k=x[r],o.l.info("Subgraph - ",k),s.db.addVertex(k.id,{text:k.title,type:k.labelType},"group",void 0,k.classes,k.dir);const v=s.db.getVertices(),m=s.db.getEdges();o.l.info("Edges",m);let S=0;for(S=x.length-1;S>=0;S--){k=x[S],(0,l.Ubm)("cluster").append("text");for(let e=0;e`.label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .cluster-label text {\n fill: ${e.titleColor};\n }\n .cluster-label span,p {\n color: ${e.titleColor};\n }\n\n .label text,span,p {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .katex path {\n fill: #000;\n stroke: #000;\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${e.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${e.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${e.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${e.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${e.edgeLabelBackground};\n fill: ${e.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${((e,t)=>{const n=i.A,r=n(e,"r"),l=n(e,"g"),o=n(e,"b");return c.A(r,l,o,t)})(e.edgeLabelBackground,.5)};\n // background-color: \n }\n\n .cluster rect {\n fill: ${e.clusterBkg};\n stroke: ${e.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${e.titleColor};\n }\n\n .cluster span,p {\n color: ${e.titleColor};\n }\n /* .cluster div {\n color: ${e.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${e.fontFamily};\n font-size: 12px;\n background: ${e.tertiaryColor};\n border: 1px solid ${e.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n }\n`}}]); \ No newline at end of file diff --git a/assets/js/22869887.2b3d9b3d.js b/assets/js/22869887.2b3d9b3d.js new file mode 100644 index 0000000000..2798402257 --- /dev/null +++ b/assets/js/22869887.2b3d9b3d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[62673],{9485:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>i});const s=JSON.parse('{"id":"global/scs-0005","title":"scs-0005: Governance of the SCS community","description":"SCS-0005 outlines the structure and governance of the SCS community by the SCS Project Board and how this is elected.","source":"@site/standards/global/scs-0005.md","sourceDirName":"global","slug":"/global/scs-0005","permalink":"/standards/global/scs-0005","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0004-v1-achieving-certification"},"next":{"title":"V1","permalink":"/standards/scs-0005-v1-project-governance"}}');var r=n(74848),c=n(28453);const o={},a="scs-0005: Governance of the SCS community",d={},i=[];function l(e){const t={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0005-governance-of-the-scs-community",children:"scs-0005: Governance of the SCS community"})}),"\n",(0,r.jsx)(t.p,{children:"SCS-0005 outlines the structure and governance of the SCS community by the SCS Project Board and how this is elected."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0005-v1-project-governance",children:"scs-0005-v1"})}),(0,r.jsx)(t.td,{children:"Procedural"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},c=s.createContext(r);function o(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/22aa5ce0.fa2cb810.js b/assets/js/22aa5ce0.fa2cb810.js new file mode 100644 index 0000000000..fb52bf69c7 --- /dev/null +++ b/assets/js/22aa5ce0.fa2cb810.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[66910],{4814:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>o});const r=JSON.parse('{"id":"ops/scs-0403","title":"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/ops/scs-0403.md","sourceDirName":"ops","slug":"/ops/scs-0403","permalink":"/standards/ops/scs-0403","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0402-v1-status-page-openapi-spec-decision"},"next":{"title":"V1","permalink":"/standards/scs-0403-v1-csp-kaas-observability-stack"}}');var n=s(74848),c=s(28453);const a={},i="scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer",d={},o=[];function l(e){const t={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"scs-0403-architecture-for-the-cloud-service-provider-observability-system-for-the-kaas-layer",children:"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer"})}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0403-v1-csp-kaas-observability-stack",children:"scs-0403-v1"})}),(0,n.jsx)(t.td,{children:"Decision Record"}),(0,n.jsx)(t.td,{children:"Draft"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>i});var r=s(96540);const n={},c=r.createContext(n);function a(e){const t=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),r.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/23417.726793c8.js b/assets/js/23417.726793c8.js new file mode 100644 index 0000000000..69d177e25a --- /dev/null +++ b/assets/js/23417.726793c8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[23417],{23417:(t,e,i)=>{i.d(e,{diagram:()=>T});var n=i(86079),r=i(26312),s=i(21176),a=i(697),l=(i(74353),i(16750),i(42838),function(){var t=function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i},e=[1,3],i=[1,4],n=[1,5],r=[1,6],s=[5,6,8,9,11,13,31,32,33,34,35,36,44,62,63],a=[1,18],l=[2,7],c=[1,22],o=[1,23],h=[1,24],u=[1,25],y=[1,26],d=[1,27],p=[1,20],_=[1,28],E=[1,29],g=[62,63],R=[5,8,9,11,13,31,32,33,34,35,36,44,51,53,62,63],m=[1,47],f=[1,48],I=[1,49],b=[1,50],k=[1,51],S=[1,52],T=[1,53],N=[53,54],x=[1,64],A=[1,60],v=[1,61],q=[1,62],$=[1,63],O=[1,65],w=[1,69],C=[1,70],L=[1,67],F=[1,68],M=[5,8,9,11,13,31,32,33,34,35,36,44,62,63],D={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,acc_title:9,acc_title_value:10,acc_descr:11,acc_descr_value:12,acc_descr_multiline_value:13,requirementDef:14,elementDef:15,relationshipDef:16,requirementType:17,requirementName:18,STRUCT_START:19,requirementBody:20,ID:21,COLONSEP:22,id:23,TEXT:24,text:25,RISK:26,riskLevel:27,VERIFYMTHD:28,verifyType:29,STRUCT_STOP:30,REQUIREMENT:31,FUNCTIONAL_REQUIREMENT:32,INTERFACE_REQUIREMENT:33,PERFORMANCE_REQUIREMENT:34,PHYSICAL_REQUIREMENT:35,DESIGN_CONSTRAINT:36,LOW_RISK:37,MED_RISK:38,HIGH_RISK:39,VERIFY_ANALYSIS:40,VERIFY_DEMONSTRATION:41,VERIFY_INSPECTION:42,VERIFY_TEST:43,ELEMENT:44,elementName:45,elementBody:46,TYPE:47,type:48,DOCREF:49,ref:50,END_ARROW_L:51,relationship:52,LINE:53,END_ARROW_R:54,CONTAINS:55,COPIES:56,DERIVES:57,SATISFIES:58,VERIFIES:59,REFINES:60,TRACES:61,unqString:62,qString:63,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",9:"acc_title",10:"acc_title_value",11:"acc_descr",12:"acc_descr_value",13:"acc_descr_multiline_value",19:"STRUCT_START",21:"ID",22:"COLONSEP",24:"TEXT",26:"RISK",28:"VERIFYMTHD",30:"STRUCT_STOP",31:"REQUIREMENT",32:"FUNCTIONAL_REQUIREMENT",33:"INTERFACE_REQUIREMENT",34:"PERFORMANCE_REQUIREMENT",35:"PHYSICAL_REQUIREMENT",36:"DESIGN_CONSTRAINT",37:"LOW_RISK",38:"MED_RISK",39:"HIGH_RISK",40:"VERIFY_ANALYSIS",41:"VERIFY_DEMONSTRATION",42:"VERIFY_INSPECTION",43:"VERIFY_TEST",44:"ELEMENT",47:"TYPE",49:"DOCREF",51:"END_ARROW_L",53:"LINE",54:"END_ARROW_R",55:"CONTAINS",56:"COPIES",57:"DERIVES",58:"SATISFIES",59:"VERIFIES",60:"REFINES",61:"TRACES",62:"unqString",63:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,2],[4,2],[4,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[14,5],[20,5],[20,5],[20,5],[20,5],[20,2],[20,1],[17,1],[17,1],[17,1],[17,1],[17,1],[17,1],[27,1],[27,1],[27,1],[29,1],[29,1],[29,1],[29,1],[15,5],[46,5],[46,5],[46,2],[46,1],[16,5],[16,5],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[18,1],[18,1],[23,1],[23,1],[25,1],[25,1],[45,1],[45,1],[48,1],[48,1],[50,1],[50,1]],performAction:function(t,e,i,n,r,s,a){var l=s.length-1;switch(r){case 4:this.$=s[l].trim(),n.setAccTitle(this.$);break;case 5:case 6:this.$=s[l].trim(),n.setAccDescription(this.$);break;case 7:this.$=[];break;case 13:n.addRequirement(s[l-3],s[l-4]);break;case 14:n.setNewReqId(s[l-2]);break;case 15:n.setNewReqText(s[l-2]);break;case 16:n.setNewReqRisk(s[l-2]);break;case 17:n.setNewReqVerifyMethod(s[l-2]);break;case 20:this.$=n.RequirementType.REQUIREMENT;break;case 21:this.$=n.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 22:this.$=n.RequirementType.INTERFACE_REQUIREMENT;break;case 23:this.$=n.RequirementType.PERFORMANCE_REQUIREMENT;break;case 24:this.$=n.RequirementType.PHYSICAL_REQUIREMENT;break;case 25:this.$=n.RequirementType.DESIGN_CONSTRAINT;break;case 26:this.$=n.RiskLevel.LOW_RISK;break;case 27:this.$=n.RiskLevel.MED_RISK;break;case 28:this.$=n.RiskLevel.HIGH_RISK;break;case 29:this.$=n.VerifyType.VERIFY_ANALYSIS;break;case 30:this.$=n.VerifyType.VERIFY_DEMONSTRATION;break;case 31:this.$=n.VerifyType.VERIFY_INSPECTION;break;case 32:this.$=n.VerifyType.VERIFY_TEST;break;case 33:n.addElement(s[l-3]);break;case 34:n.setNewElementType(s[l-2]);break;case 35:n.setNewElementDocRef(s[l-2]);break;case 38:n.addRelationship(s[l-2],s[l],s[l-4]);break;case 39:n.addRelationship(s[l-2],s[l-4],s[l]);break;case 40:this.$=n.Relationships.CONTAINS;break;case 41:this.$=n.Relationships.COPIES;break;case 42:this.$=n.Relationships.DERIVES;break;case 43:this.$=n.Relationships.SATISFIES;break;case 44:this.$=n.Relationships.VERIFIES;break;case 45:this.$=n.Relationships.REFINES;break;case 46:this.$=n.Relationships.TRACES}},table:[{3:1,4:2,6:e,9:i,11:n,13:r},{1:[3]},{3:8,4:2,5:[1,7],6:e,9:i,11:n,13:r},{5:[1,9]},{10:[1,10]},{12:[1,11]},t(s,[2,6]),{3:12,4:2,6:e,9:i,11:n,13:r},{1:[2,2]},{4:17,5:a,7:13,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},t(s,[2,4]),t(s,[2,5]),{1:[2,1]},{8:[1,30]},{4:17,5:a,7:31,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{4:17,5:a,7:32,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{4:17,5:a,7:33,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{4:17,5:a,7:34,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{4:17,5:a,7:35,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{18:36,62:[1,37],63:[1,38]},{45:39,62:[1,40],63:[1,41]},{51:[1,42],53:[1,43]},t(g,[2,20]),t(g,[2,21]),t(g,[2,22]),t(g,[2,23]),t(g,[2,24]),t(g,[2,25]),t(R,[2,49]),t(R,[2,50]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{19:[1,44]},{19:[2,47]},{19:[2,48]},{19:[1,45]},{19:[2,53]},{19:[2,54]},{52:46,55:m,56:f,57:I,58:b,59:k,60:S,61:T},{52:54,55:m,56:f,57:I,58:b,59:k,60:S,61:T},{5:[1,55]},{5:[1,56]},{53:[1,57]},t(N,[2,40]),t(N,[2,41]),t(N,[2,42]),t(N,[2,43]),t(N,[2,44]),t(N,[2,45]),t(N,[2,46]),{54:[1,58]},{5:x,20:59,21:A,24:v,26:q,28:$,30:O},{5:w,30:C,46:66,47:L,49:F},{23:71,62:_,63:E},{23:72,62:_,63:E},t(M,[2,13]),{22:[1,73]},{22:[1,74]},{22:[1,75]},{22:[1,76]},{5:x,20:77,21:A,24:v,26:q,28:$,30:O},t(M,[2,19]),t(M,[2,33]),{22:[1,78]},{22:[1,79]},{5:w,30:C,46:80,47:L,49:F},t(M,[2,37]),t(M,[2,38]),t(M,[2,39]),{23:81,62:_,63:E},{25:82,62:[1,83],63:[1,84]},{27:85,37:[1,86],38:[1,87],39:[1,88]},{29:89,40:[1,90],41:[1,91],42:[1,92],43:[1,93]},t(M,[2,18]),{48:94,62:[1,95],63:[1,96]},{50:97,62:[1,98],63:[1,99]},t(M,[2,36]),{5:[1,100]},{5:[1,101]},{5:[2,51]},{5:[2,52]},{5:[1,102]},{5:[2,26]},{5:[2,27]},{5:[2,28]},{5:[1,103]},{5:[2,29]},{5:[2,30]},{5:[2,31]},{5:[2,32]},{5:[1,104]},{5:[2,55]},{5:[2,56]},{5:[1,105]},{5:[2,57]},{5:[2,58]},{5:x,20:106,21:A,24:v,26:q,28:$,30:O},{5:x,20:107,21:A,24:v,26:q,28:$,30:O},{5:x,20:108,21:A,24:v,26:q,28:$,30:O},{5:x,20:109,21:A,24:v,26:q,28:$,30:O},{5:w,30:C,46:110,47:L,49:F},{5:w,30:C,46:111,47:L,49:F},t(M,[2,14]),t(M,[2,15]),t(M,[2,16]),t(M,[2,17]),t(M,[2,34]),t(M,[2,35])],defaultActions:{8:[2,2],12:[2,1],30:[2,3],31:[2,8],32:[2,9],33:[2,10],34:[2,11],35:[2,12],37:[2,47],38:[2,48],40:[2,53],41:[2,54],83:[2,51],84:[2,52],86:[2,26],87:[2,27],88:[2,28],90:[2,29],91:[2,30],92:[2,31],93:[2,32],95:[2,55],96:[2,56],98:[2,57],99:[2,58]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=this,i=[0],n=[],r=[null],s=[],a=this.table,l="",c=0,o=0,h=s.slice.call(arguments,1),u=Object.create(this.lexer),y={yy:{}};for(var d in this.yy)Object.prototype.hasOwnProperty.call(this.yy,d)&&(y.yy[d]=this.yy[d]);u.setInput(t,y.yy),y.yy.lexer=u,y.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var p=u.yylloc;s.push(p);var _=u.options&&u.options.ranges;"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var E,g,R,m,f,I,b,k,S,T={};;){if(g=i[i.length-1],this.defaultActions[g]?R=this.defaultActions[g]:(null==E&&(S=void 0,"number"!=typeof(S=n.pop()||u.lex()||1)&&(S instanceof Array&&(S=(n=S).pop()),S=e.symbols_[S]||S),E=S),R=a[g]&&a[g][E]),void 0===R||!R.length||!R[0]){var N="";for(f in k=[],a[g])this.terminals_[f]&&f>2&&k.push("'"+this.terminals_[f]+"'");N=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[E]||E)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==E?"end of input":"'"+(this.terminals_[E]||E)+"'"),this.parseError(N,{text:u.match,token:this.terminals_[E]||E,line:u.yylineno,loc:p,expected:k})}if(R[0]instanceof Array&&R.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+E);switch(R[0]){case 1:i.push(E),r.push(u.yytext),s.push(u.yylloc),i.push(R[1]),E=null,o=u.yyleng,l=u.yytext,c=u.yylineno,p=u.yylloc;break;case 2:if(I=this.productions_[R[1]][1],T.$=r[r.length-I],T._$={first_line:s[s.length-(I||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(I||1)].first_column,last_column:s[s.length-1].last_column},_&&(T._$.range=[s[s.length-(I||1)].range[0],s[s.length-1].range[1]]),void 0!==(m=this.performAction.apply(T,[l,o,c,y.yy,R[1],r,s].concat(h))))return m;I&&(i=i.slice(0,-1*I*2),r=r.slice(0,-1*I),s=s.slice(0,-1*I)),i.push(this.productions_[R[1]][0]),r.push(T.$),s.push(T._$),b=a[i[i.length-2]][i[i.length-1]],i.push(b);break;case 3:return!0}}return!0}},P={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,i=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var i,n,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in r)this[s]=r[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),s=0;se[0].length)){if(e=i,n=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,r[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,i,n){switch(i){case 0:return"title";case 1:return this.begin("acc_title"),9;case 2:return this.popState(),"acc_title_value";case 3:return this.begin("acc_descr"),11;case 4:return this.popState(),"acc_descr_value";case 5:this.begin("acc_descr_multiline");break;case 6:case 48:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:return 5;case 9:case 10:case 11:break;case 12:return 8;case 13:return 6;case 14:return 19;case 15:return 30;case 16:return 22;case 17:return 21;case 18:return 24;case 19:return 26;case 20:return 28;case 21:return 31;case 22:return 32;case 23:return 33;case 24:return 34;case 25:return 35;case 26:return 36;case 27:return 37;case 28:return 38;case 29:return 39;case 30:return 40;case 31:return 41;case 32:return 42;case 33:return 43;case 34:return 44;case 35:return 55;case 36:return 56;case 37:return 57;case 38:return 58;case 39:return 59;case 40:return 60;case 41:return 61;case 42:return 47;case 43:return 49;case 44:return 51;case 45:return 54;case 46:return 53;case 47:this.begin("string");break;case 49:return"qString";case 50:return e.yytext=e.yytext.trim(),62}},rules:[/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^\r\n\{\<\>\-\=]*)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},unqString:{rules:[],inclusive:!1},token:{rules:[],inclusive:!1},string:{rules:[48,49],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,50],inclusive:!0}}};function V(){this.yy={}}return D.lexer=P,V.prototype=D,D.Parser=V,new V}());l.parser=l;const c=l;let o=[],h={},u={},y={},d={};const p={RequirementType:{REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"},RiskLevel:{LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"},VerifyType:{VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"},Relationships:{CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"},getConfig:()=>(0,n.c)().req,addRequirement:(t,e)=>(void 0===u[t]&&(u[t]={name:t,type:e,id:h.id,text:h.text,risk:h.risk,verifyMethod:h.verifyMethod}),h={},u[t]),getRequirements:()=>u,setNewReqId:t=>{void 0!==h&&(h.id=t)},setNewReqText:t=>{void 0!==h&&(h.text=t)},setNewReqRisk:t=>{void 0!==h&&(h.risk=t)},setNewReqVerifyMethod:t=>{void 0!==h&&(h.verifyMethod=t)},setAccTitle:n.s,getAccTitle:n.g,setAccDescription:n.b,getAccDescription:n.a,addElement:t=>(void 0===d[t]&&(d[t]={name:t,type:y.type,docRef:y.docRef},n.l.info("Added new requirement: ",t)),y={},d[t]),getElements:()=>d,setNewElementType:t=>{void 0!==y&&(y.type=t)},setNewElementDocRef:t=>{void 0!==y&&(y.docRef=t)},addRelationship:(t,e,i)=>{o.push({type:t,src:e,dst:i})},getRelationships:()=>o,clear:()=>{o=[],h={},u={},y={},d={},(0,n.v)()}},_={CONTAINS:"contains",ARROW:"arrow"},E=_,g=(t,e)=>{let i=t.append("defs").append("marker").attr("id",_.CONTAINS+"_line_ending").attr("refX",0).attr("refY",e.line_height/2).attr("markerWidth",e.line_height).attr("markerHeight",e.line_height).attr("orient","auto").append("g");i.append("circle").attr("cx",e.line_height/2).attr("cy",e.line_height/2).attr("r",e.line_height/2).attr("fill","none"),i.append("line").attr("x1",0).attr("x2",e.line_height).attr("y1",e.line_height/2).attr("y2",e.line_height/2).attr("stroke-width",1),i.append("line").attr("y1",0).attr("y2",e.line_height).attr("x1",e.line_height/2).attr("x2",e.line_height/2).attr("stroke-width",1),t.append("defs").append("marker").attr("id",_.ARROW+"_line_ending").attr("refX",e.line_height).attr("refY",.5*e.line_height).attr("markerWidth",e.line_height).attr("markerHeight",e.line_height).attr("orient","auto").append("path").attr("d",`M0,0\n L${e.line_height},${e.line_height/2}\n M${e.line_height},${e.line_height/2}\n L0,${e.line_height}`).attr("stroke-width",1)};let R={},m=0;const f=(t,e)=>t.insert("rect","#"+e).attr("class","req reqBox").attr("x",0).attr("y",0).attr("width",R.rect_min_width+"px").attr("height",R.rect_min_height+"px"),I=(t,e,i)=>{let n=R.rect_min_width/2,r=t.append("text").attr("class","req reqLabel reqTitle").attr("id",e).attr("x",n).attr("y",R.rect_padding).attr("dominant-baseline","hanging"),s=0;i.forEach((t=>{0==s?r.append("tspan").attr("text-anchor","middle").attr("x",R.rect_min_width/2).attr("dy",0).text(t):r.append("tspan").attr("text-anchor","middle").attr("x",R.rect_min_width/2).attr("dy",.75*R.line_height).text(t),s++}));let a=1.5*R.rect_padding+s*R.line_height*.75;return t.append("line").attr("class","req-title-line").attr("x1","0").attr("x2",R.rect_min_width).attr("y1",a).attr("y2",a),{titleNode:r,y:a}},b=(t,e,i,n)=>{let r=t.append("text").attr("class","req reqLabel").attr("id",e).attr("x",R.rect_padding).attr("y",n).attr("dominant-baseline","hanging"),s=0;let a=[];return i.forEach((t=>{let e=t.length;for(;e>30&&s<3;){let i=t.substring(0,30);e=(t=t.substring(30,t.length)).length,a[a.length]=i,s++}if(3==s){let t=a[a.length-1];a[a.length-1]=t.substring(0,t.length-4)+"..."}else a[a.length]=t;s=0})),a.forEach((t=>{r.append("tspan").attr("x",R.rect_padding).attr("dy",R.line_height).text(t)})),r},k=function(t,e,i,s,a){const l=i.edge(S(e.src),S(e.dst)),c=(0,r.n8j)().x((function(t){return t.x})).y((function(t){return t.y})),o=t.insert("path","#"+s).attr("class","er relationshipLine").attr("d",c(l.points)).attr("fill","none");e.type==a.db.Relationships.CONTAINS?o.attr("marker-start","url("+n.e.getUrl(R.arrowMarkerAbsolute)+"#"+e.type+"_line_ending)"):(o.attr("stroke-dasharray","10,7"),o.attr("marker-end","url("+n.e.getUrl(R.arrowMarkerAbsolute)+"#"+E.ARROW+"_line_ending)")),((t,e,i,n)=>{const r=e.node().getTotalLength(),s=e.node().getPointAtLength(.5*r),a="rel"+m;m++;const l=t.append("text").attr("class","req relationshipLabel").attr("id",a).attr("x",s.x).attr("y",s.y).attr("text-anchor","middle").attr("dominant-baseline","middle").text(n).node().getBBox();t.insert("rect","#"+a).attr("class","req reqLabelBox").attr("x",s.x-l.width/2).attr("y",s.y-l.height/2).attr("width",l.width).attr("height",l.height).attr("fill","white").attr("fill-opacity","85%")})(t,o,0,`<<${e.type}>>`)},S=t=>t.replace(/\s/g,"").replace(/\./g,"_"),T={parser:c,db:p,renderer:{draw:(t,e,i,l)=>{R=(0,n.c)().requirement;const c=R.securityLevel;let o;"sandbox"===c&&(o=(0,r.Ltv)("#i"+e));const h=("sandbox"===c?(0,r.Ltv)(o.nodes()[0].contentDocument.body):(0,r.Ltv)("body")).select(`[id='${e}']`);g(h,R);const u=new a.T({multigraph:!1,compound:!1,directed:!0}).setGraph({rankdir:R.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));let y=l.db.getRequirements(),d=l.db.getElements(),p=l.db.getRelationships();var _,E,m;_=y,E=u,m=h,Object.keys(_).forEach((t=>{let e=_[t];t=S(t),n.l.info("Added new requirement: ",t);const i=m.append("g").attr("id",t),r=f(i,"req-"+t);let s=I(i,t+"_title",[`<<${e.type}>>`,`${e.name}`]);b(i,t+"_body",[`Id: ${e.id}`,`Text: ${e.text}`,`Risk: ${e.risk}`,`Verification: ${e.verifyMethod}`],s.y);const a=r.node().getBBox();E.setNode(t,{width:a.width,height:a.height,shape:"rect",id:t})})),((t,e,i)=>{Object.keys(t).forEach((n=>{let r=t[n];const s=S(n),a=i.append("g").attr("id",s),l="element-"+s,c=f(a,l);let o=I(a,l+"_title",["<>",`${n}`]);b(a,l+"_body",[`Type: ${r.type||"Not Specified"}`,`Doc Ref: ${r.docRef||"None"}`],o.y);const h=c.node().getBBox();e.setNode(s,{width:h.width,height:h.height,shape:"rect",id:s})}))})(d,u,h),((t,e)=>{t.forEach((function(t){let i=S(t.src),n=S(t.dst);e.setEdge(i,n,{relationship:t})}))})(p,u),(0,s.Zp)(u),function(t,e){e.nodes().forEach((function(i){void 0!==i&&void 0!==e.node(i)&&(t.select("#"+i),t.select("#"+i).attr("transform","translate("+(e.node(i).x-e.node(i).width/2)+","+(e.node(i).y-e.node(i).height/2)+" )"))}))}(h,u),p.forEach((function(t){k(h,t,u,e,l)}));const T=R.rect_padding,N=h.node().getBBox(),x=N.width+2*T,A=N.height+2*T;(0,n.i)(h,A,x,R.useMaxWidth),h.attr("viewBox",`${N.x-T} ${N.y-T} ${x} ${A}`)}},styles:t=>`\n\n marker {\n fill: ${t.relationColor};\n stroke: ${t.relationColor};\n }\n\n marker.cross {\n stroke: ${t.lineColor};\n }\n\n svg {\n font-family: ${t.fontFamily};\n font-size: ${t.fontSize};\n }\n\n .reqBox {\n fill: ${t.requirementBackground};\n fill-opacity: 1.0;\n stroke: ${t.requirementBorderColor};\n stroke-width: ${t.requirementBorderSize};\n }\n \n .reqTitle, .reqLabel{\n fill: ${t.requirementTextColor};\n }\n .reqLabelBox {\n fill: ${t.relationLabelBackground};\n fill-opacity: 1.0;\n }\n\n .req-title-line {\n stroke: ${t.requirementBorderColor};\n stroke-width: ${t.requirementBorderSize};\n }\n .relationshipLine {\n stroke: ${t.relationColor};\n stroke-width: 1;\n }\n .relationshipLabel {\n fill: ${t.relationLabelColor};\n }\n\n`}}}]); \ No newline at end of file diff --git a/assets/js/23687.3e0df620.js b/assets/js/23687.3e0df620.js new file mode 100644 index 0000000000..73604457e1 --- /dev/null +++ b/assets/js/23687.3e0df620.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[23687],{23687:(t,e,a)=>{a.d(e,{diagram:()=>at});var r=a(86079),s=a(26312),i=a(79186),n=a(16750),o=(a(74353),a(42838),function(){var t=function(t,e,a,r){for(a=a||{},r=t.length;r--;a[t[r]]=e);return a},e=[1,2],a=[1,3],r=[1,4],s=[2,4],i=[1,9],n=[1,11],o=[1,13],c=[1,14],l=[1,16],d=[1,17],h=[1,18],p=[1,24],g=[1,25],u=[1,26],x=[1,27],y=[1,28],m=[1,29],b=[1,30],f=[1,31],T=[1,32],E=[1,33],w=[1,34],P=[1,35],v=[1,36],_=[1,37],L=[1,38],k=[1,39],I=[1,41],M=[1,42],N=[1,43],A=[1,44],O=[1,45],S=[1,46],D=[1,4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,48,49,50,52,53,54,59,60,61,62,70],R=[4,5,16,50,52,53],C=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],$=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,49,50,52,53,54,59,60,61,62,70],Y=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,48,50,52,53,54,59,60,61,62,70],B=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,50,52,53,54,59,60,61,62,70],V=[68,69,70],F=[1,120],q={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,SD:6,document:7,line:8,statement:9,box_section:10,box_line:11,participant_statement:12,create:13,box:14,restOfLine:15,end:16,signal:17,autonumber:18,NUM:19,off:20,activate:21,actor:22,deactivate:23,note_statement:24,links_statement:25,link_statement:26,properties_statement:27,details_statement:28,title:29,legacy_title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,loop:36,rect:37,opt:38,alt:39,else_sections:40,par:41,par_sections:42,par_over:43,critical:44,option_sections:45,break:46,option:47,and:48,else:49,participant:50,AS:51,participant_actor:52,destroy:53,note:54,placement:55,text2:56,over:57,actor_pair:58,links:59,link:60,properties:61,details:62,spaceList:63,",":64,left_of:65,right_of:66,signaltype:67,"+":68,"-":69,ACTOR:70,SOLID_OPEN_ARROW:71,DOTTED_OPEN_ARROW:72,SOLID_ARROW:73,DOTTED_ARROW:74,SOLID_CROSS:75,DOTTED_CROSS:76,SOLID_POINT:77,DOTTED_POINT:78,TXT:79,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",6:"SD",13:"create",14:"box",15:"restOfLine",16:"end",18:"autonumber",19:"NUM",20:"off",21:"activate",23:"deactivate",29:"title",30:"legacy_title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"loop",37:"rect",38:"opt",39:"alt",41:"par",43:"par_over",44:"critical",46:"break",47:"option",48:"and",49:"else",50:"participant",51:"AS",52:"participant_actor",53:"destroy",54:"note",57:"over",59:"links",60:"link",61:"properties",62:"details",64:",",65:"left_of",66:"right_of",68:"+",69:"-",70:"ACTOR",71:"SOLID_OPEN_ARROW",72:"DOTTED_OPEN_ARROW",73:"SOLID_ARROW",74:"DOTTED_ARROW",75:"SOLID_CROSS",76:"DOTTED_CROSS",77:"SOLID_POINT",78:"DOTTED_POINT",79:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[10,0],[10,2],[11,2],[11,1],[11,1],[9,1],[9,2],[9,4],[9,2],[9,4],[9,3],[9,3],[9,2],[9,3],[9,3],[9,2],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[9,2],[9,2],[9,1],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[45,1],[45,4],[42,1],[42,4],[40,1],[40,4],[12,5],[12,3],[12,5],[12,3],[12,3],[24,4],[24,4],[25,3],[26,3],[27,3],[28,3],[63,2],[63,1],[58,3],[58,1],[55,1],[55,1],[17,5],[17,5],[17,4],[22,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[56,1]],performAction:function(t,e,a,r,s,i,n){var o=i.length-1;switch(s){case 3:return r.apply(i[o]),i[o];case 4:case 9:case 8:case 13:this.$=[];break;case 5:case 10:i[o-1].push(i[o]),this.$=i[o-1];break;case 6:case 7:case 11:case 12:case 62:this.$=i[o];break;case 15:i[o].type="createParticipant",this.$=i[o];break;case 16:i[o-1].unshift({type:"boxStart",boxData:r.parseBoxData(i[o-2])}),i[o-1].push({type:"boxEnd",boxText:i[o-2]}),this.$=i[o-1];break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(i[o-2]),sequenceIndexStep:Number(i[o-1]),sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(i[o-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:r.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:i[o-1]};break;case 23:this.$={type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:i[o-1]};break;case 29:r.setDiagramTitle(i[o].substring(6)),this.$=i[o].substring(6);break;case 30:r.setDiagramTitle(i[o].substring(7)),this.$=i[o].substring(7);break;case 31:this.$=i[o].trim(),r.setAccTitle(this.$);break;case 32:case 33:this.$=i[o].trim(),r.setAccDescription(this.$);break;case 34:i[o-1].unshift({type:"loopStart",loopText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.LOOP_START}),i[o-1].push({type:"loopEnd",loopText:i[o-2],signalType:r.LINETYPE.LOOP_END}),this.$=i[o-1];break;case 35:i[o-1].unshift({type:"rectStart",color:r.parseMessage(i[o-2]),signalType:r.LINETYPE.RECT_START}),i[o-1].push({type:"rectEnd",color:r.parseMessage(i[o-2]),signalType:r.LINETYPE.RECT_END}),this.$=i[o-1];break;case 36:i[o-1].unshift({type:"optStart",optText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.OPT_START}),i[o-1].push({type:"optEnd",optText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.OPT_END}),this.$=i[o-1];break;case 37:i[o-1].unshift({type:"altStart",altText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.ALT_START}),i[o-1].push({type:"altEnd",signalType:r.LINETYPE.ALT_END}),this.$=i[o-1];break;case 38:i[o-1].unshift({type:"parStart",parText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.PAR_START}),i[o-1].push({type:"parEnd",signalType:r.LINETYPE.PAR_END}),this.$=i[o-1];break;case 39:i[o-1].unshift({type:"parStart",parText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.PAR_OVER_START}),i[o-1].push({type:"parEnd",signalType:r.LINETYPE.PAR_END}),this.$=i[o-1];break;case 40:i[o-1].unshift({type:"criticalStart",criticalText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.CRITICAL_START}),i[o-1].push({type:"criticalEnd",signalType:r.LINETYPE.CRITICAL_END}),this.$=i[o-1];break;case 41:i[o-1].unshift({type:"breakStart",breakText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.BREAK_START}),i[o-1].push({type:"breakEnd",optText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.BREAK_END}),this.$=i[o-1];break;case 43:this.$=i[o-3].concat([{type:"option",optionText:r.parseMessage(i[o-1]),signalType:r.LINETYPE.CRITICAL_OPTION},i[o]]);break;case 45:this.$=i[o-3].concat([{type:"and",parText:r.parseMessage(i[o-1]),signalType:r.LINETYPE.PAR_AND},i[o]]);break;case 47:this.$=i[o-3].concat([{type:"else",altText:r.parseMessage(i[o-1]),signalType:r.LINETYPE.ALT_ELSE},i[o]]);break;case 48:i[o-3].draw="participant",i[o-3].type="addParticipant",i[o-3].description=r.parseMessage(i[o-1]),this.$=i[o-3];break;case 49:i[o-1].draw="participant",i[o-1].type="addParticipant",this.$=i[o-1];break;case 50:i[o-3].draw="actor",i[o-3].type="addParticipant",i[o-3].description=r.parseMessage(i[o-1]),this.$=i[o-3];break;case 51:i[o-1].draw="actor",i[o-1].type="addParticipant",this.$=i[o-1];break;case 52:i[o-1].type="destroyParticipant",this.$=i[o-1];break;case 53:this.$=[i[o-1],{type:"addNote",placement:i[o-2],actor:i[o-1].actor,text:i[o]}];break;case 54:i[o-2]=[].concat(i[o-1],i[o-1]).slice(0,2),i[o-2][0]=i[o-2][0].actor,i[o-2][1]=i[o-2][1].actor,this.$=[i[o-1],{type:"addNote",placement:r.PLACEMENT.OVER,actor:i[o-2].slice(0,2),text:i[o]}];break;case 55:this.$=[i[o-1],{type:"addLinks",actor:i[o-1].actor,text:i[o]}];break;case 56:this.$=[i[o-1],{type:"addALink",actor:i[o-1].actor,text:i[o]}];break;case 57:this.$=[i[o-1],{type:"addProperties",actor:i[o-1].actor,text:i[o]}];break;case 58:this.$=[i[o-1],{type:"addDetails",actor:i[o-1].actor,text:i[o]}];break;case 61:this.$=[i[o-2],i[o]];break;case 63:this.$=r.PLACEMENT.LEFTOF;break;case 64:this.$=r.PLACEMENT.RIGHTOF;break;case 65:this.$=[i[o-4],i[o-1],{type:"addMessage",from:i[o-4].actor,to:i[o-1].actor,signalType:i[o-3],msg:i[o],activate:!0},{type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:i[o-1]}];break;case 66:this.$=[i[o-4],i[o-1],{type:"addMessage",from:i[o-4].actor,to:i[o-1].actor,signalType:i[o-3],msg:i[o]},{type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:i[o-4]}];break;case 67:this.$=[i[o-3],i[o-1],{type:"addMessage",from:i[o-3].actor,to:i[o-1].actor,signalType:i[o-2],msg:i[o]}];break;case 68:this.$={type:"addParticipant",actor:i[o]};break;case 69:this.$=r.LINETYPE.SOLID_OPEN;break;case 70:this.$=r.LINETYPE.DOTTED_OPEN;break;case 71:this.$=r.LINETYPE.SOLID;break;case 72:this.$=r.LINETYPE.DOTTED;break;case 73:this.$=r.LINETYPE.SOLID_CROSS;break;case 74:this.$=r.LINETYPE.DOTTED_CROSS;break;case 75:this.$=r.LINETYPE.SOLID_POINT;break;case 76:this.$=r.LINETYPE.DOTTED_POINT;break;case 77:this.$=r.parseMessage(i[o].trim().substring(1))}},table:[{3:1,4:e,5:a,6:r},{1:[3]},{3:5,4:e,5:a,6:r},{3:6,4:e,5:a,6:r},t([1,4,5,13,14,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],s,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:i,5:n,8:8,9:10,12:12,13:o,14:c,17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},t(D,[2,5]),{9:47,12:12,13:o,14:c,17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},t(D,[2,7]),t(D,[2,8]),t(D,[2,14]),{12:48,50:_,52:L,53:k},{15:[1,49]},{5:[1,50]},{5:[1,53],19:[1,51],20:[1,52]},{22:54,70:S},{22:55,70:S},{5:[1,56]},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},t(D,[2,29]),t(D,[2,30]),{32:[1,61]},{34:[1,62]},t(D,[2,33]),{15:[1,63]},{15:[1,64]},{15:[1,65]},{15:[1,66]},{15:[1,67]},{15:[1,68]},{15:[1,69]},{15:[1,70]},{22:71,70:S},{22:72,70:S},{22:73,70:S},{67:74,71:[1,75],72:[1,76],73:[1,77],74:[1,78],75:[1,79],76:[1,80],77:[1,81],78:[1,82]},{55:83,57:[1,84],65:[1,85],66:[1,86]},{22:87,70:S},{22:88,70:S},{22:89,70:S},{22:90,70:S},t([5,51,64,71,72,73,74,75,76,77,78,79],[2,68]),t(D,[2,6]),t(D,[2,15]),t(R,[2,9],{10:91}),t(D,[2,17]),{5:[1,93],19:[1,92]},{5:[1,94]},t(D,[2,21]),{5:[1,95]},{5:[1,96]},t(D,[2,24]),t(D,[2,25]),t(D,[2,26]),t(D,[2,27]),t(D,[2,28]),t(D,[2,31]),t(D,[2,32]),t(C,s,{7:97}),t(C,s,{7:98}),t(C,s,{7:99}),t($,s,{40:100,7:101}),t(Y,s,{42:102,7:103}),t(Y,s,{7:103,42:104}),t(B,s,{45:105,7:106}),t(C,s,{7:107}),{5:[1,109],51:[1,108]},{5:[1,111],51:[1,110]},{5:[1,112]},{22:115,68:[1,113],69:[1,114],70:S},t(V,[2,69]),t(V,[2,70]),t(V,[2,71]),t(V,[2,72]),t(V,[2,73]),t(V,[2,74]),t(V,[2,75]),t(V,[2,76]),{22:116,70:S},{22:118,58:117,70:S},{70:[2,63]},{70:[2,64]},{56:119,79:F},{56:121,79:F},{56:122,79:F},{56:123,79:F},{4:[1,126],5:[1,128],11:125,12:127,16:[1,124],50:_,52:L,53:k},{5:[1,129]},t(D,[2,19]),t(D,[2,20]),t(D,[2,22]),t(D,[2,23]),{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[1,130],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[1,131],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[1,132],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{16:[1,133]},{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[2,46],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,49:[1,134],50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{16:[1,135]},{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[2,44],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,48:[1,136],50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{16:[1,137]},{16:[1,138]},{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[2,42],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,47:[1,139],50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[1,140],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{15:[1,141]},t(D,[2,49]),{15:[1,142]},t(D,[2,51]),t(D,[2,52]),{22:143,70:S},{22:144,70:S},{56:145,79:F},{56:146,79:F},{56:147,79:F},{64:[1,148],79:[2,62]},{5:[2,55]},{5:[2,77]},{5:[2,56]},{5:[2,57]},{5:[2,58]},t(D,[2,16]),t(R,[2,10]),{12:149,50:_,52:L,53:k},t(R,[2,12]),t(R,[2,13]),t(D,[2,18]),t(D,[2,34]),t(D,[2,35]),t(D,[2,36]),t(D,[2,37]),{15:[1,150]},t(D,[2,38]),{15:[1,151]},t(D,[2,39]),t(D,[2,40]),{15:[1,152]},t(D,[2,41]),{5:[1,153]},{5:[1,154]},{56:155,79:F},{56:156,79:F},{5:[2,67]},{5:[2,53]},{5:[2,54]},{22:157,70:S},t(R,[2,11]),t($,s,{7:101,40:158}),t(Y,s,{7:103,42:159}),t(B,s,{7:106,45:160}),t(D,[2,48]),t(D,[2,50]),{5:[2,65]},{5:[2,66]},{79:[2,61]},{16:[2,47]},{16:[2,45]},{16:[2,43]}],defaultActions:{5:[2,1],6:[2,2],85:[2,63],86:[2,64],119:[2,55],120:[2,77],121:[2,56],122:[2,57],123:[2,58],145:[2,67],146:[2,53],147:[2,54],155:[2,65],156:[2,66],157:[2,61],158:[2,47],159:[2,45],160:[2,43]},parseError:function(t,e){if(!e.recoverable){var a=new Error(t);throw a.hash=e,a}this.trace(t)},parse:function(t){var e=this,a=[0],r=[],s=[null],i=[],n=this.table,o="",c=0,l=0,d=i.slice.call(arguments,1),h=Object.create(this.lexer),p={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(p.yy[g]=this.yy[g]);h.setInput(t,p.yy),p.yy.lexer=h,p.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var u=h.yylloc;i.push(u);var x=h.options&&h.options.ranges;"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var y,m,b,f,T,E,w,P,v,_={};;){if(m=a[a.length-1],this.defaultActions[m]?b=this.defaultActions[m]:(null==y&&(v=void 0,"number"!=typeof(v=r.pop()||h.lex()||1)&&(v instanceof Array&&(v=(r=v).pop()),v=e.symbols_[v]||v),y=v),b=n[m]&&n[m][y]),void 0===b||!b.length||!b[0]){var L="";for(T in P=[],n[m])this.terminals_[T]&&T>2&&P.push("'"+this.terminals_[T]+"'");L=h.showPosition?"Parse error on line "+(c+1)+":\n"+h.showPosition()+"\nExpecting "+P.join(", ")+", got '"+(this.terminals_[y]||y)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==y?"end of input":"'"+(this.terminals_[y]||y)+"'"),this.parseError(L,{text:h.match,token:this.terminals_[y]||y,line:h.yylineno,loc:u,expected:P})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+y);switch(b[0]){case 1:a.push(y),s.push(h.yytext),i.push(h.yylloc),a.push(b[1]),y=null,l=h.yyleng,o=h.yytext,c=h.yylineno,u=h.yylloc;break;case 2:if(E=this.productions_[b[1]][1],_.$=s[s.length-E],_._$={first_line:i[i.length-(E||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(E||1)].first_column,last_column:i[i.length-1].last_column},x&&(_._$.range=[i[i.length-(E||1)].range[0],i[i.length-1].range[1]]),void 0!==(f=this.performAction.apply(_,[o,l,c,p.yy,b[1],s,i].concat(d))))return f;E&&(a=a.slice(0,-1*E*2),s=s.slice(0,-1*E),i=i.slice(0,-1*E)),a.push(this.productions_[b[1]][0]),s.push(_.$),i.push(_._$),w=n[a[a.length-2]][a[a.length-1]],a.push(w);break;case 3:return!0}}return!0}},W={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,a=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),a.length-1&&(this.yylineno-=a.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:a?(a.length===r.length?this.yylloc.first_column:0)+r[r.length-a.length].length-a[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var a,r,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],a=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a)return a;if(this._backtrack){for(var i in s)this[i]=s[i];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,a,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),i=0;ie[0].length)){if(e=a,r=i,this.options.backtrack_lexer){if(!1!==(t=this.test_match(a,s[i])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,a,r){switch(a){case 0:case 51:case 64:return 5;case 1:case 2:case 3:case 4:case 5:break;case 6:return 19;case 7:return this.begin("LINE"),14;case 8:return this.begin("ID"),50;case 9:return this.begin("ID"),52;case 10:return 13;case 11:return this.begin("ID"),53;case 12:return e.yytext=e.yytext.trim(),this.begin("ALIAS"),70;case 13:return this.popState(),this.popState(),this.begin("LINE"),51;case 14:return this.popState(),this.popState(),5;case 15:return this.begin("LINE"),36;case 16:return this.begin("LINE"),37;case 17:return this.begin("LINE"),38;case 18:return this.begin("LINE"),39;case 19:return this.begin("LINE"),49;case 20:return this.begin("LINE"),41;case 21:return this.begin("LINE"),43;case 22:return this.begin("LINE"),48;case 23:return this.begin("LINE"),44;case 24:return this.begin("LINE"),47;case 25:return this.begin("LINE"),46;case 26:return this.popState(),15;case 27:return 16;case 28:return 65;case 29:return 66;case 30:return 59;case 31:return 60;case 32:return 61;case 33:return 62;case 34:return 57;case 35:return 54;case 36:return this.begin("ID"),21;case 37:return this.begin("ID"),23;case 38:return 29;case 39:return 30;case 40:return this.begin("acc_title"),31;case 41:return this.popState(),"acc_title_value";case 42:return this.begin("acc_descr"),33;case 43:return this.popState(),"acc_descr_value";case 44:this.begin("acc_descr_multiline");break;case 45:this.popState();break;case 46:return"acc_descr_multiline_value";case 47:return 6;case 48:return 18;case 49:return 20;case 50:return 64;case 52:return e.yytext=e.yytext.trim(),70;case 53:return 73;case 54:return 74;case 55:return 71;case 56:return 72;case 57:return 75;case 58:return 76;case 59:return 77;case 60:return 78;case 61:return 79;case 62:return 68;case 63:return 69;case 65:return"INVALID"}},rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:box\b)/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:create\b)/i,/^(?:destroy\b)/i,/^(?:[^\->:\n,;]+?([\-]*[^\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:par_over\b)/i,/^(?:and\b)/i,/^(?:critical\b)/i,/^(?:option\b)/i,/^(?:break\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[45,46],inclusive:!1},acc_descr:{rules:[43],inclusive:!1},acc_title:{rules:[41],inclusive:!1},ID:{rules:[2,3,12],inclusive:!1},ALIAS:{rules:[2,3,13,14],inclusive:!1},LINE:{rules:[2,3,26],inclusive:!1},INITIAL:{rules:[0,1,3,4,5,6,7,8,9,10,11,15,16,17,18,19,20,21,22,23,24,25,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,44,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65],inclusive:!0}}};function z(){this.yy={}}return q.lexer=W,z.prototype=q,q.Parser=z,new z}());o.parser=o;const c=o;const l=new class{constructor(t){this.init=t,this.records=this.init()}reset(){this.records=this.init()}}((()=>({prevActor:void 0,actors:{},createdActors:{},destroyedActors:{},boxes:[],messages:[],notes:[],sequenceNumbersEnabled:!1,wrapEnabled:void 0,currentBox:void 0,lastCreated:void 0,lastDestroyed:void 0}))),d=function(t,e,a,r){let s=l.records.currentBox;const i=l.records.actors[t];if(i){if(l.records.currentBox&&i.box&&l.records.currentBox!==i.box)throw new Error("A same participant should only be defined in one Box: "+i.name+" can't be in '"+i.box.name+"' and in '"+l.records.currentBox.name+"' at the same time.");if(s=i.box?i.box:l.records.currentBox,i.box=s,i&&e===i.name&&null==a)return}null!=a&&null!=a.text||(a={text:e,wrap:null,type:r}),null!=r&&null!=a.text||(a={text:e,wrap:null,type:r}),l.records.actors[t]={box:s,name:e,description:a.text,wrap:void 0===a.wrap&&g()||!!a.wrap,prevActor:l.records.prevActor,links:{},properties:{},actorCnt:null,rectData:null,type:r||"participant"},l.records.prevActor&&l.records.actors[l.records.prevActor]&&(l.records.actors[l.records.prevActor].nextActor=t),l.records.currentBox&&l.records.currentBox.actorKeys.push(t),l.records.prevActor=t},h=function(t,e,a={text:void 0,wrap:void 0},r,s=!1){if(r===u.ACTIVE_END){if((t=>{let e,a=0;for(e=0;e>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},e}}return l.records.messages.push({from:t,to:e,message:a.text,wrap:void 0===a.wrap&&g()||!!a.wrap,type:r,activate:s}),!0},p=function(t){return l.records.actors[t]},g=()=>void 0!==l.records.wrapEnabled?l.records.wrapEnabled:(0,r.c)().sequence.wrap,u={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25,AUTONUMBER:26,CRITICAL_START:27,CRITICAL_OPTION:28,CRITICAL_END:29,BREAK_START:30,BREAK_END:31,PAR_OVER_START:32},x=function(t,e,a){const r={actor:t,placement:e,message:a.text,wrap:void 0===a.wrap&&g()||!!a.wrap},s=[].concat(t,t);l.records.notes.push(r),l.records.messages.push({from:s[0],to:s[1],message:a.text,wrap:void 0===a.wrap&&g()||!!a.wrap,type:u.NOTE,placement:e})},y=function(t,e){const a=p(t);try{let t=(0,r.d)(e.text,(0,r.c)());t=t.replace(/&/g,"&"),t=t.replace(/=/g,"=");m(a,JSON.parse(t))}catch(s){r.l.error("error while parsing actor link text",s)}};function m(t,e){if(null==t.links)t.links=e;else for(let a in e)t.links[a]=e[a]}const b=function(t,e){const a=p(t);try{let t=(0,r.d)(e.text,(0,r.c)());f(a,JSON.parse(t))}catch(s){r.l.error("error while parsing actor properties text",s)}};function f(t,e){if(null==t.properties)t.properties=e;else for(let a in e)t.properties[a]=e[a]}const T=function(t,e){const a=p(t),s=document.getElementById(e.text);try{const t=s.innerHTML,e=JSON.parse(t);e.properties&&f(a,e.properties),e.links&&m(a,e.links)}catch(i){r.l.error("error while parsing actor details text",i)}},E=function(t){if(Array.isArray(t))t.forEach((function(t){E(t)}));else switch(t.type){case"sequenceIndex":l.records.messages.push({from:void 0,to:void 0,message:{start:t.sequenceIndex,step:t.sequenceIndexStep,visible:t.sequenceVisible},wrap:!1,type:t.signalType});break;case"addParticipant":d(t.actor,t.actor,t.description,t.draw);break;case"createParticipant":if(l.records.actors[t.actor])throw new Error("It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior");l.records.lastCreated=t.actor,d(t.actor,t.actor,t.description,t.draw),l.records.createdActors[t.actor]=l.records.messages.length;break;case"destroyParticipant":l.records.lastDestroyed=t.actor,l.records.destroyedActors[t.actor]=l.records.messages.length;break;case"activeStart":case"activeEnd":h(t.actor,void 0,void 0,t.signalType);break;case"addNote":x(t.actor,t.placement,t.text);break;case"addLinks":y(t.actor,t.text);break;case"addALink":!function(t,e){const a=p(t);try{const t={};let o=(0,r.d)(e.text,(0,r.c)());var s=o.indexOf("@");o=o.replace(/&/g,"&"),o=o.replace(/=/g,"=");var i=o.slice(0,s-1).trim(),n=o.slice(s+1).trim();t[i]=n,m(a,t)}catch(o){r.l.error("error while parsing actor link text",o)}}(t.actor,t.text);break;case"addProperties":b(t.actor,t.text);break;case"addDetails":T(t.actor,t.text);break;case"addMessage":if(l.records.lastCreated){if(t.to!==l.records.lastCreated)throw new Error("The created participant "+l.records.lastCreated+" does not have an associated creating message after its declaration. Please check the sequence diagram.");l.records.lastCreated=void 0}else if(l.records.lastDestroyed){if(t.to!==l.records.lastDestroyed&&t.from!==l.records.lastDestroyed)throw new Error("The destroyed participant "+l.records.lastDestroyed+" does not have an associated destroying message after its declaration. Please check the sequence diagram.");l.records.lastDestroyed=void 0}h(t.from,t.to,t.msg,t.signalType,t.activate);break;case"boxStart":e=t.boxData,l.records.boxes.push({name:e.text,wrap:void 0===e.wrap&&g()||!!e.wrap,fill:e.color,actorKeys:[]}),l.records.currentBox=l.records.boxes.slice(-1)[0];break;case"boxEnd":l.records.currentBox=void 0;break;case"loopStart":h(void 0,void 0,t.loopText,t.signalType);break;case"loopEnd":case"rectEnd":case"optEnd":case"altEnd":case"parEnd":case"criticalEnd":case"breakEnd":h(void 0,void 0,void 0,t.signalType);break;case"rectStart":h(void 0,void 0,t.color,t.signalType);break;case"optStart":h(void 0,void 0,t.optText,t.signalType);break;case"altStart":case"else":h(void 0,void 0,t.altText,t.signalType);break;case"setAccTitle":(0,r.s)(t.text);break;case"parStart":case"and":h(void 0,void 0,t.parText,t.signalType);break;case"criticalStart":h(void 0,void 0,t.criticalText,t.signalType);break;case"option":h(void 0,void 0,t.optionText,t.signalType);break;case"breakStart":h(void 0,void 0,t.breakText,t.signalType)}var e},w={addActor:d,addMessage:function(t,e,a,r){l.records.messages.push({from:t,to:e,message:a.text,wrap:void 0===a.wrap&&g()||!!a.wrap,answer:r})},addSignal:h,addLinks:y,addDetails:T,addProperties:b,autoWrap:g,setWrap:function(t){l.records.wrapEnabled=t},enableSequenceNumbers:function(){l.records.sequenceNumbersEnabled=!0},disableSequenceNumbers:function(){l.records.sequenceNumbersEnabled=!1},showSequenceNumbers:()=>l.records.sequenceNumbersEnabled,getMessages:function(){return l.records.messages},getActors:function(){return l.records.actors},getCreatedActors:function(){return l.records.createdActors},getDestroyedActors:function(){return l.records.destroyedActors},getActor:p,getActorKeys:function(){return Object.keys(l.records.actors)},getActorProperty:function(t,e){if(void 0!==t&&void 0!==t.properties)return t.properties[e]},getAccTitle:r.g,getBoxes:function(){return l.records.boxes},getDiagramTitle:r.t,setDiagramTitle:r.q,getConfig:()=>(0,r.c)().sequence,clear:function(){l.reset(),(0,r.v)()},parseMessage:function(t){const e=t.trim(),a={text:e.replace(/^:?(?:no)?wrap:/,"").trim(),wrap:null!==e.match(/^:?wrap:/)||null===e.match(/^:?nowrap:/)&&void 0};return r.l.debug("parseMessage:",a),a},parseBoxData:function(t){const e=t.match(/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/);let a=null!=e&&e[1]?e[1].trim():"transparent",s=null!=e&&e[2]?e[2].trim():void 0;if(window&&window.CSS)window.CSS.supports("color",a)||(a="transparent",s=t.trim());else{const e=(new Option).style;e.color=a,e.color!==a&&(a="transparent",s=t.trim())}return{color:a,text:void 0!==s?(0,r.d)(s.replace(/^:?(?:no)?wrap:/,""),(0,r.c)()):void 0,wrap:void 0!==s?null!==s.match(/^:?wrap:/)||null===s.match(/^:?nowrap:/)&&void 0:void 0}},LINETYPE:u,ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},addNote:x,setAccTitle:r.s,apply:E,setAccDescription:r.b,getAccDescription:r.a,hasAtLeastOneBox:function(){return l.records.boxes.length>0},hasAtLeastOneBoxWithTitle:function(){return l.records.boxes.some((t=>t.name))}},P=t=>`.actor {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n\n text.actor > tspan {\n fill: ${t.actorTextColor};\n stroke: none;\n }\n\n .actor-line {\n stroke: ${t.actorLineColor};\n }\n\n .messageLine0 {\n stroke-width: 1.5;\n stroke-dasharray: none;\n stroke: ${t.signalColor};\n }\n\n .messageLine1 {\n stroke-width: 1.5;\n stroke-dasharray: 2, 2;\n stroke: ${t.signalColor};\n }\n\n #arrowhead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .sequenceNumber {\n fill: ${t.sequenceNumberColor};\n }\n\n #sequencenumber {\n fill: ${t.signalColor};\n }\n\n #crosshead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .messageText {\n fill: ${t.signalTextColor};\n stroke: none;\n }\n\n .labelBox {\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBkgColor};\n }\n\n .labelText, .labelText > tspan {\n fill: ${t.labelTextColor};\n stroke: none;\n }\n\n .loopText, .loopText > tspan {\n fill: ${t.loopTextColor};\n stroke: none;\n }\n\n .loopLine {\n stroke-width: 2px;\n stroke-dasharray: 2, 2;\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBorderColor};\n }\n\n .note {\n //stroke: #decc93;\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n }\n\n .noteText, .noteText > tspan {\n fill: ${t.noteTextColor};\n stroke: none;\n }\n\n .activation0 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation1 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation2 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .actorPopupMenu {\n position: absolute;\n }\n\n .actorPopupMenuPanel {\n position: absolute;\n fill: ${t.actorBkg};\n box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);\n filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));\n}\n .actor-man line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n .actor-man circle, line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n stroke-width: 2px;\n }\n`,v="actor-top",_="actor-bottom",L=function(t,e){return(0,i.d)(t,e)},k=async function(t,e,a=null){let s=t.append("foreignObject");const i=await(0,r.r)(e.text,(0,r.F)()),n=s.append("xhtml:div").attr("style","width: fit-content;").attr("xmlns","http://www.w3.org/1999/xhtml").html(i).node().getBoundingClientRect();if(s.attr("height",Math.round(n.height)).attr("width",Math.round(n.width)),"noteText"===e.class){const a=t.node().firstChild;a.setAttribute("height",n.height+2*e.textMargin);const r=a.getBBox();s.attr("x",Math.round(r.x+r.width/2-n.width/2)).attr("y",Math.round(r.y+r.height/2-n.height/2))}else if(a){let{startx:t,stopx:r,starty:i}=a;if(t>r){const e=t;t=r,r=e}s.attr("x",Math.round(t+Math.abs(t-r)/2-n.width/2)),"loopText"===e.class?s.attr("y",Math.round(i)):s.attr("y",Math.round(i-n.height))}return[s]},I=function(t,e){let a=0,s=0;const i=e.text.split(r.e.lineBreakRegex),[n,o]=(0,r.D)(e.fontSize);let c=[],l=0,d=()=>e.y;if(void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0)switch(e.valign){case"top":case"start":d=()=>Math.round(e.y+e.textMargin);break;case"middle":case"center":d=()=>Math.round(e.y+(a+s+e.textMargin)/2);break;case"bottom":case"end":d=()=>Math.round(e.y+(a+s+2*e.textMargin)-e.textMargin)}if(void 0!==e.anchor&&void 0!==e.textMargin&&void 0!==e.width)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="middle",e.alignmentBaseline="middle"}for(let[h,p]of i.entries()){void 0!==e.textMargin&&0===e.textMargin&&void 0!==n&&(l=h*n);const i=t.append("text");i.attr("x",e.x),i.attr("y",d()),void 0!==e.anchor&&i.attr("text-anchor",e.anchor).attr("dominant-baseline",e.dominantBaseline).attr("alignment-baseline",e.alignmentBaseline),void 0!==e.fontFamily&&i.style("font-family",e.fontFamily),void 0!==o&&i.style("font-size",o),void 0!==e.fontWeight&&i.style("font-weight",e.fontWeight),void 0!==e.fill&&i.attr("fill",e.fill),void 0!==e.class&&i.attr("class",e.class),void 0!==e.dy?i.attr("dy",e.dy):0!==l&&i.attr("dy",l);const g=p||r.Z;if(e.tspan){const t=i.append("tspan");t.attr("x",e.x),void 0!==e.fill&&t.attr("fill",e.fill),t.text(g)}else i.text(g);void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0&&(s+=(i._groups||i)[0][0].getBBox().height,a=s),c.push(i)}return c},M=function(t,e){const a=t.append("polygon");var r,s,i,n,o;return a.attr("points",(r=e.x,s=e.y,i=e.width,n=e.height,r+","+s+" "+(r+i)+","+s+" "+(r+i)+","+(s+n-(o=7))+" "+(r+i-1.2*o)+","+(s+n)+" "+r+","+(s+n))),a.attr("class","labelBox"),e.y=e.y+e.height/2,I(t,e),a};let N=-1;const A=(t,e,a,r)=>{t.select&&a.forEach((a=>{const s=e[a],i=t.select("#actor"+s.actorCnt);!r.mirrorActors&&s.stopy?i.attr("y2",s.stopy+s.height/2):r.mirrorActors&&i.attr("y2",s.stopy)}))},O=function(t,e){(0,i.a)(t,e)},S=function(){return{x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}},D=function(){function t(t,e,a,r,s,n,o){i(e.append("text").attr("x",a+s/2).attr("y",r+n/2+5).style("text-anchor","middle").text(t),o)}function e(t,e,a,s,n,o,c,l){const{actorFontSize:d,actorFontFamily:h,actorFontWeight:p}=l,[g,u]=(0,r.D)(d),x=t.split(r.e.lineBreakRegex);for(let r=0;ra?c.width:a;const g=d.append("rect");if(g.attr("class","actorPopupMenuPanel"+h),g.attr("x",c.x),g.attr("y",c.height),g.attr("fill",c.fill),g.attr("stroke",c.stroke),g.attr("width",p),g.attr("height",c.height),g.attr("rx",c.rx),g.attr("ry",c.ry),null!=i){var u=20;for(let t in i){var x=d.append("a"),y=(0,n.Jf)(i[t]);x.attr("xlink:href",y),x.attr("target","_blank"),R(r)(t,x,c.x+10,c.height+u,p,20,{class:"actor"},r),u+=30}}return g.attr("height",u),{height:c.height+u,width:p}},anchorElement:function(t){return t.append("g")},drawActivation:function(t,e,a,r,s){const n=(0,i.g)(),o=e.anchored;n.x=e.startx,n.y=e.starty,n.class="activation"+s%3,n.width=e.stopx-e.startx,n.height=a-e.starty,L(o,n)},drawLoop:async function(t,e,a,s){const{boxMargin:n,boxTextMargin:o,labelBoxHeight:c,labelBoxWidth:l,messageFontFamily:d,messageFontSize:h,messageFontWeight:p}=s,g=t.append("g"),u=function(t,e,a,r){return g.append("line").attr("x1",t).attr("y1",e).attr("x2",a).attr("y2",r).attr("class","loopLine")};u(e.startx,e.starty,e.stopx,e.starty),u(e.stopx,e.starty,e.stopx,e.stopy),u(e.startx,e.stopy,e.stopx,e.stopy),u(e.startx,e.starty,e.startx,e.stopy),void 0!==e.sections&&e.sections.forEach((function(t){u(e.startx,t.y,e.stopx,t.y).style("stroke-dasharray","3, 3")}));let x=(0,i.e)();x.text=a,x.x=e.startx,x.y=e.starty,x.fontFamily=d,x.fontSize=h,x.fontWeight=p,x.anchor="middle",x.valign="middle",x.tspan=!1,x.width=l||50,x.height=c||20,x.textMargin=o,x.class="labelText",M(g,x),x=S(),x.text=e.title,x.x=e.startx+l/2+(e.stopx-e.startx)/2,x.y=e.starty+n+o,x.anchor="middle",x.valign="middle",x.textMargin=o,x.class="loopText",x.fontFamily=d,x.fontSize=h,x.fontWeight=p,x.wrap=!0;let y=(0,r.G)(x.text)?await k(g,x,e):I(g,x);if(void 0!==e.sectionTitles)for(const[i,m]of Object.entries(e.sectionTitles))if(m.message){x.text=m.message,x.x=e.startx+(e.stopx-e.startx)/2,x.y=e.sections[i].y+n+o,x.class="loopText",x.anchor="middle",x.valign="middle",x.tspan=!1,x.fontFamily=d,x.fontSize=h,x.fontWeight=p,x.wrap=e.wrap,(0,r.G)(x.text)?(e.starty=e.sections[i].y,await k(g,x,e)):I(g,x);let t=Math.round(y.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));e.sections[i].height+=t-(n+o)}return e.height=Math.round(e.stopy-e.starty),g},drawBackgroundRect:O,insertArrowHead:function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",7.9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},insertArrowFilledHead:function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",15.5).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},insertSequenceNumber:function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},insertArrowCrossHead:function(t){t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",4).attr("refY",4.5).append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1pt").attr("d","M 1,2 L 6,7 M 6,2 L 1,7")},insertDatabaseIcon:function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},insertComputerIcon:function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},insertClockIcon:function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},getTextObj:S,getNoteRect:function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},fixLifeLineHeights:A,sanitizeUrl:n.Jf};let $={};const Y={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:function(){return Math.max.apply(null,0===this.actors.length?[0]:this.actors.map((t=>t.height||0)))+(0===this.loops.length?0:this.loops.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.messages.length?0:this.messages.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.notes.length?0:this.notes.map((t=>t.height||0)).reduce(((t,e)=>t+e)))},clear:function(){this.actors=[],this.boxes=[],this.loops=[],this.messages=[],this.notes=[]},addBox:function(t){this.boxes.push(t)},addActor:function(t){this.actors.push(t)},addLoop:function(t){this.loops.push(t)},addMessage:function(t){this.messages.push(t)},addNote:function(t){this.notes.push(t)},lastActor:function(){return this.actors[this.actors.length-1]},lastLoop:function(){return this.loops[this.loops.length-1]},lastMessage:function(){return this.messages[this.messages.length-1]},lastNote:function(){return this.notes[this.notes.length-1]},actors:[],boxes:[],loops:[],messages:[],notes:[]},init:function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,j((0,r.c)())},updateVal:function(t,e,a,r){void 0===t[e]?t[e]=a:t[e]=r(a,t[e])},updateBounds:function(t,e,a,r){const s=this;let i=0;function n(n){return function(o){i++;const c=s.sequenceItems.length-i+1;s.updateVal(o,"starty",e-c*$.boxMargin,Math.min),s.updateVal(o,"stopy",r+c*$.boxMargin,Math.max),s.updateVal(Y.data,"startx",t-c*$.boxMargin,Math.min),s.updateVal(Y.data,"stopx",a+c*$.boxMargin,Math.max),"activation"!==n&&(s.updateVal(o,"startx",t-c*$.boxMargin,Math.min),s.updateVal(o,"stopx",a+c*$.boxMargin,Math.max),s.updateVal(Y.data,"starty",e-c*$.boxMargin,Math.min),s.updateVal(Y.data,"stopy",r+c*$.boxMargin,Math.max))}}this.sequenceItems.forEach(n()),this.activations.forEach(n("activation"))},insert:function(t,e,a,s){const i=r.e.getMin(t,a),n=r.e.getMax(t,a),o=r.e.getMin(e,s),c=r.e.getMax(e,s);this.updateVal(Y.data,"startx",i,Math.min),this.updateVal(Y.data,"starty",o,Math.min),this.updateVal(Y.data,"stopx",n,Math.max),this.updateVal(Y.data,"stopy",c,Math.max),this.updateBounds(i,o,n,c)},newActivation:function(t,e,a){const r=a[t.from.actor],s=G(t.from.actor).length||0,i=r.x+r.width/2+(s-1)*$.activationWidth/2;this.activations.push({startx:i,starty:this.verticalPos+2,stopx:i+$.activationWidth,stopy:void 0,actor:t.from.actor,anchored:C.anchorElement(e)})},endActivation:function(t){const e=this.activations.map((function(t){return t.actor})).lastIndexOf(t.from.actor);return this.activations.splice(e,1)[0]},createLoop:function(t={message:void 0,wrap:!1,width:void 0},e){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}},newLoop:function(t={message:void 0,wrap:!1,width:void 0},e){this.sequenceItems.push(this.createLoop(t,e))},endLoop:function(){return this.sequenceItems.pop()},isLoopOverlap:function(){return!!this.sequenceItems.length&&this.sequenceItems[this.sequenceItems.length-1].overlap},addSectionToLoop:function(t){const e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:Y.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)},saveVerticalPos:function(){this.isLoopOverlap()&&(this.savedVerticalPos=this.verticalPos)},resetVerticalPos:function(){this.isLoopOverlap()&&(this.verticalPos=this.savedVerticalPos)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=r.e.getMax(this.data.stopy,this.verticalPos)},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return{bounds:this.data,models:this.models}}},B=async function(t,e){Y.bumpVerticalPos($.boxMargin),e.height=$.boxMargin,e.starty=Y.getVerticalPos();const a=(0,i.g)();a.x=e.startx,a.y=e.starty,a.width=e.width||$.width,a.class="note";const s=t.append("g"),n=C.drawRect(s,a),o=(0,i.e)();o.x=e.startx,o.y=e.starty,o.width=a.width,o.dy="1em",o.text=e.message,o.class="noteText",o.fontFamily=$.noteFontFamily,o.fontSize=$.noteFontSize,o.fontWeight=$.noteFontWeight,o.anchor=$.noteAlign,o.textMargin=$.noteMargin,o.valign="center";const c=(0,r.G)(o.text)?await k(s,o):I(s,o),l=Math.round(c.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));n.attr("height",l+2*$.noteMargin),e.height+=l+2*$.noteMargin,Y.bumpVerticalPos(l+2*$.noteMargin),e.stopy=e.starty+l+2*$.noteMargin,e.stopx=e.startx+a.width,Y.insert(e.startx,e.starty,e.stopx,e.stopy),Y.models.addNote(e)},V=t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),F=t=>({fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight}),q=t=>({fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight});async function W(t,e){Y.bumpVerticalPos(10);const{startx:a,stopx:s,message:i}=e,n=r.e.splitBreaks(i).length,o=(0,r.G)(i),c=o?await(0,r.H)(i,(0,r.c)()):r.u.calculateTextDimensions(i,V($));if(!o){const t=c.height/n;e.height+=t,Y.bumpVerticalPos(t)}let l,d=c.height-10;const h=c.width;if(a===s){l=Y.getVerticalPos()+d,$.rightAngles||(d+=$.boxMargin,l=Y.getVerticalPos()+d),d+=30;const t=r.e.getMax(h/2,$.width/2);Y.insert(a-t,Y.getVerticalPos()-10+d,s+t,Y.getVerticalPos()+30+d)}else d+=$.boxMargin,l=Y.getVerticalPos()+d,Y.insert(a,l-10,s,l);return Y.bumpVerticalPos(d),e.height+=d,e.stopy=e.starty+e.height,Y.insert(e.fromBounds,e.starty,e.toBounds,e.stopy),l}const z=async function(t,e,a,s){const{startx:n,stopx:o,starty:c,message:l,type:d,sequenceIndex:h,sequenceVisible:p}=e,g=r.u.calculateTextDimensions(l,V($)),u=(0,i.e)();u.x=n,u.y=c+10,u.width=o-n,u.class="messageText",u.dy="1em",u.text=l,u.fontFamily=$.messageFontFamily,u.fontSize=$.messageFontSize,u.fontWeight=$.messageFontWeight,u.anchor=$.messageAlign,u.valign="center",u.textMargin=$.wrapPadding,u.tspan=!1,(0,r.G)(u.text)?await k(t,u,{startx:n,stopx:o,starty:a}):I(t,u);const x=g.width;let y;n===o?y=$.rightAngles?t.append("path").attr("d",`M ${n},${a} H ${n+r.e.getMax($.width/2,x/2)} V ${a+25} H ${n}`):t.append("path").attr("d","M "+n+","+a+" C "+(n+60)+","+(a-10)+" "+(n+60)+","+(a+30)+" "+n+","+(a+20)):(y=t.append("line"),y.attr("x1",n),y.attr("y1",a),y.attr("x2",o),y.attr("y2",a)),d===s.db.LINETYPE.DOTTED||d===s.db.LINETYPE.DOTTED_CROSS||d===s.db.LINETYPE.DOTTED_POINT||d===s.db.LINETYPE.DOTTED_OPEN?(y.style("stroke-dasharray","3, 3"),y.attr("class","messageLine1")):y.attr("class","messageLine0");let m="";$.arrowMarkerAbsolute&&(m=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,m=m.replace(/\(/g,"\\("),m=m.replace(/\)/g,"\\)")),y.attr("stroke-width",2),y.attr("stroke","none"),y.style("fill","none"),d!==s.db.LINETYPE.SOLID&&d!==s.db.LINETYPE.DOTTED||y.attr("marker-end","url("+m+"#arrowhead)"),d!==s.db.LINETYPE.SOLID_POINT&&d!==s.db.LINETYPE.DOTTED_POINT||y.attr("marker-end","url("+m+"#filled-head)"),d!==s.db.LINETYPE.SOLID_CROSS&&d!==s.db.LINETYPE.DOTTED_CROSS||y.attr("marker-end","url("+m+"#crosshead)"),(p||$.showSequenceNumbers)&&(y.attr("marker-start","url("+m+"#sequencenumber)"),t.append("text").attr("x",n).attr("y",a+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(h))},H=async function(t,e,a,s){if(s){let s=0;Y.bumpVerticalPos(2*$.boxMargin);for(const i of a){const a=e[i];a.stopy||(a.stopy=Y.getVerticalPos());const n=await C.drawActor(t,a,$,!0);s=r.e.getMax(s,n)}Y.bumpVerticalPos(s+$.boxMargin)}else for(const r of a){const a=e[r];await C.drawActor(t,a,$,!1)}},U=function(t,e,a,r){let s=0,i=0;for(const n of a){const a=e[n],o=Z(a),c=C.drawPopup(t,a,o,$,$.forceMenus,r);c.height>s&&(s=c.height),c.width+a.x>i&&(i=c.width+a.x)}return{maxHeight:s,maxWidth:i}},j=function(t){(0,r.f)($,t),t.fontFamily&&($.actorFontFamily=$.noteFontFamily=$.messageFontFamily=t.fontFamily),t.fontSize&&($.actorFontSize=$.noteFontSize=$.messageFontSize=t.fontSize),t.fontWeight&&($.actorFontWeight=$.noteFontWeight=$.messageFontWeight=t.fontWeight)},G=function(t){return Y.activations.filter((function(e){return e.actor===t}))},K=function(t,e){const a=e[t],s=G(t);return[s.reduce((function(t,e){return r.e.getMin(t,e.startx)}),a.x+a.width/2-1),s.reduce((function(t,e){return r.e.getMax(t,e.stopx)}),a.x+a.width/2+1)]};function X(t,e,a,s,i){Y.bumpVerticalPos(a);let n=s;if(e.id&&e.message&&t[e.id]){const a=t[e.id].width,i=V($);e.message=r.u.wrapLabel(`[${e.message}]`,a-2*$.wrapPadding,i),e.width=a,e.wrap=!0;const o=r.u.calculateTextDimensions(e.message,i),c=r.e.getMax(o.height,$.labelBoxHeight);n=s+c,r.l.debug(`${c} - ${e.message}`)}i(e),Y.bumpVerticalPos(n)}function J(t,e,a,r,s,i,n){function o(a,r){a.x2,p=t=>c?-t:t;t.from===t.to?d=l:(t.activate&&!h&&(d+=p($.activationWidth/2-1)),[a.db.LINETYPE.SOLID_OPEN,a.db.LINETYPE.DOTTED_OPEN].includes(t.type)||(d+=p(3)));const g=[s,i,n,o],u=Math.abs(l-d);t.wrap&&t.message&&(t.message=r.u.wrapLabel(t.message,r.e.getMax(u+2*$.wrapPadding,$.width),V($)));const x=r.u.calculateTextDimensions(t.message,V($));return{width:r.e.getMax(t.wrap?0:x.width+2*$.wrapPadding,u+2*$.wrapPadding,$.width),height:0,startx:l,stopx:d,starty:0,stopy:0,message:t.message,type:t.type,wrap:t.wrap,fromBounds:Math.min.apply(null,g),toBounds:Math.max.apply(null,g)}},et=async function(t,e,a,s){const i={},n=[];let o,c,l;for(const d of t){switch(d.id=r.u.random({length:10}),d.type){case s.db.LINETYPE.LOOP_START:case s.db.LINETYPE.ALT_START:case s.db.LINETYPE.OPT_START:case s.db.LINETYPE.PAR_START:case s.db.LINETYPE.PAR_OVER_START:case s.db.LINETYPE.CRITICAL_START:case s.db.LINETYPE.BREAK_START:n.push({id:d.id,msg:d.message,from:Number.MAX_SAFE_INTEGER,to:Number.MIN_SAFE_INTEGER,width:0});break;case s.db.LINETYPE.ALT_ELSE:case s.db.LINETYPE.PAR_AND:case s.db.LINETYPE.CRITICAL_OPTION:d.message&&(o=n.pop(),i[o.id]=o,i[d.id]=o,n.push(o));break;case s.db.LINETYPE.LOOP_END:case s.db.LINETYPE.ALT_END:case s.db.LINETYPE.OPT_END:case s.db.LINETYPE.PAR_END:case s.db.LINETYPE.CRITICAL_END:case s.db.LINETYPE.BREAK_END:o=n.pop(),i[o.id]=o;break;case s.db.LINETYPE.ACTIVE_START:{const t=e[d.from?d.from.actor:d.to.actor],a=G(d.from?d.from.actor:d.to.actor).length,r=t.x+t.width/2+(a-1)*$.activationWidth/2,s={startx:r,stopx:r+$.activationWidth,actor:d.from.actor,enabled:!0};Y.activations.push(s)}break;case s.db.LINETYPE.ACTIVE_END:{const t=Y.activations.map((t=>t.actor)).lastIndexOf(d.from.actor);delete Y.activations.splice(t,1)[0]}}void 0!==d.placement?(c=await Q(d,e,s),d.noteModel=c,n.forEach((t=>{o=t,o.from=r.e.getMin(o.from,c.startx),o.to=r.e.getMax(o.to,c.startx+c.width),o.width=r.e.getMax(o.width,Math.abs(o.from-o.to))-$.labelBoxWidth}))):(l=tt(d,e,s),d.msgModel=l,l.startx&&l.stopx&&n.length>0&&n.forEach((t=>{if(o=t,l.startx===l.stopx){const t=e[d.from],a=e[d.to];o.from=r.e.getMin(t.x-l.width/2,t.x-t.width/2,o.from),o.to=r.e.getMax(a.x+l.width/2,a.x+t.width/2,o.to),o.width=r.e.getMax(o.width,Math.abs(o.to-o.from))-$.labelBoxWidth}else o.from=r.e.getMin(l.startx,o.from),o.to=r.e.getMax(l.stopx,o.to),o.width=r.e.getMax(o.width,l.width)-$.labelBoxWidth})))}return Y.activations=[],r.l.debug("Loop type widths:",i),i},at={parser:c,db:w,renderer:{bounds:Y,drawActors:H,drawActorsPopup:U,setConf:j,draw:async function(t,e,a,i){const{securityLevel:n,sequence:o}=(0,r.c)();let c;$=o,"sandbox"===n&&(c=(0,s.Ltv)("#i"+e));const l="sandbox"===n?(0,s.Ltv)(c.nodes()[0].contentDocument.body):(0,s.Ltv)("body"),d="sandbox"===n?c.nodes()[0].contentDocument:document;Y.init(),r.l.debug(i.db);const h="sandbox"===n?l.select(`[id="${e}"]`):(0,s.Ltv)(`[id="${e}"]`),p=i.db.getActors(),g=i.db.getCreatedActors(),u=i.db.getDestroyedActors(),x=i.db.getBoxes();let y=i.db.getActorKeys();const m=i.db.getMessages(),b=i.db.getDiagramTitle(),f=i.db.hasAtLeastOneBox(),T=i.db.hasAtLeastOneBoxWithTitle(),E=await async function(t,e,a){const s={};for(const i of e)if(t[i.to]&&t[i.from]){const e=t[i.to];if(i.placement===a.db.PLACEMENT.LEFTOF&&!e.prevActor)continue;if(i.placement===a.db.PLACEMENT.RIGHTOF&&!e.nextActor)continue;const n=void 0!==i.placement,o=!n,c=n?F($):V($),l=i.wrap?r.u.wrapLabel(i.message,$.width-2*$.wrapPadding,c):i.message,d=((0,r.G)(l)?await(0,r.H)(i.message,(0,r.c)()):r.u.calculateTextDimensions(l,c)).width+2*$.wrapPadding;o&&i.from===e.nextActor?s[i.to]=r.e.getMax(s[i.to]||0,d):o&&i.from===e.prevActor?s[i.from]=r.e.getMax(s[i.from]||0,d):o&&i.from===i.to?(s[i.from]=r.e.getMax(s[i.from]||0,d/2),s[i.to]=r.e.getMax(s[i.to]||0,d/2)):i.placement===a.db.PLACEMENT.RIGHTOF?s[i.from]=r.e.getMax(s[i.from]||0,d):i.placement===a.db.PLACEMENT.LEFTOF?s[e.prevActor]=r.e.getMax(s[e.prevActor]||0,d):i.placement===a.db.PLACEMENT.OVER&&(e.prevActor&&(s[e.prevActor]=r.e.getMax(s[e.prevActor]||0,d/2)),e.nextActor&&(s[i.from]=r.e.getMax(s[i.from]||0,d/2)))}return r.l.debug("maxMessageWidthPerActor:",s),s}(p,m,i);if($.height=await async function(t,e,a){let s=0;for(const n of Object.keys(t)){const e=t[n];e.wrap&&(e.description=r.u.wrapLabel(e.description,$.width-2*$.wrapPadding,q($)));const a=(0,r.G)(e.description)?await(0,r.H)(e.description,(0,r.c)()):r.u.calculateTextDimensions(e.description,q($));e.width=e.wrap?$.width:r.e.getMax($.width,a.width+2*$.wrapPadding),e.height=e.wrap?r.e.getMax(a.height,$.height):$.height,s=r.e.getMax(s,e.height)}for(const n in e){const a=t[n];if(!a)continue;const s=t[a.nextActor];if(!s){const t=e[n]+$.actorMargin-a.width/2;a.margin=r.e.getMax(t,$.actorMargin);continue}const i=e[n]+$.actorMargin-a.width/2-s.width/2;a.margin=r.e.getMax(i,$.actorMargin)}let i=0;return a.forEach((e=>{const a=V($);let s=e.actorKeys.reduce(((e,a)=>e+(t[a].width+(t[a].margin||0))),0);s-=2*$.boxTextMargin,e.wrap&&(e.name=r.u.wrapLabel(e.name,s-2*$.wrapPadding,a));const n=r.u.calculateTextDimensions(e.name,a);i=r.e.getMax(n.height,i);const o=r.e.getMax(s,n.width+2*$.wrapPadding);if(e.margin=$.boxTextMargin,st.textMaxHeight=i)),r.e.getMax(s,$.height)}(p,E,x),C.insertComputerIcon(h),C.insertDatabaseIcon(h),C.insertClockIcon(h),f&&(Y.bumpVerticalPos($.boxMargin),T&&Y.bumpVerticalPos(x[0].textMaxHeight)),!0===$.hideUnusedParticipants){const t=new Set;m.forEach((e=>{t.add(e.from),t.add(e.to)})),y=y.filter((e=>t.has(e)))}await async function(t,e,a,s,i,n,o){let c,l=0,d=0,h=0;for(const p of s){const t=e[p],s=t.box;c&&c!=s&&(o||Y.models.addBox(c),d+=$.boxMargin+c.margin),s&&s!=c&&(o||(s.x=l+d,s.y=i),d+=s.margin),t.width=t.width||$.width,t.height=r.e.getMax(t.height||$.height,$.height),t.margin=t.margin||$.actorMargin,h=r.e.getMax(h,t.height),a[t.name]&&(d+=t.width/2),t.x=l+d,t.starty=Y.getVerticalPos(),Y.insert(t.x,i,t.x+t.width,t.height),l+=t.width+d,t.box&&(t.box.width=l+s.margin-t.box.x),d=t.margin,c=t.box,Y.models.addActor(t)}c&&!o&&Y.models.addBox(c),Y.bumpVerticalPos(h)}(0,p,g,y,0,0,!1);const w=await et(m,p,E,i);function P(t,e){const a=Y.endActivation(t);a.starty+18>e&&(a.starty=e-6,e+=12),C.drawActivation(h,a,e,$,G(t.from.actor).length),Y.insert(a.startx,e-10,a.stopx,e)}C.insertArrowHead(h),C.insertArrowCrossHead(h),C.insertArrowFilledHead(h),C.insertSequenceNumber(h);let v=1,_=1;const L=[],k=[];let I=0;for(const s of m){let t,e,a;switch(s.type){case i.db.LINETYPE.NOTE:Y.resetVerticalPos(),e=s.noteModel,await B(h,e);break;case i.db.LINETYPE.ACTIVE_START:Y.newActivation(s,h,p);break;case i.db.LINETYPE.ACTIVE_END:P(s,Y.getVerticalPos());break;case i.db.LINETYPE.LOOP_START:X(w,s,$.boxMargin,$.boxMargin+$.boxTextMargin,(t=>Y.newLoop(t)));break;case i.db.LINETYPE.LOOP_END:t=Y.endLoop(),await C.drawLoop(h,t,"loop",$),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos()),Y.models.addLoop(t);break;case i.db.LINETYPE.RECT_START:X(w,s,$.boxMargin,$.boxMargin,(t=>Y.newLoop(void 0,t.message)));break;case i.db.LINETYPE.RECT_END:t=Y.endLoop(),k.push(t),Y.models.addLoop(t),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos());break;case i.db.LINETYPE.OPT_START:X(w,s,$.boxMargin,$.boxMargin+$.boxTextMargin,(t=>Y.newLoop(t)));break;case i.db.LINETYPE.OPT_END:t=Y.endLoop(),await C.drawLoop(h,t,"opt",$),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos()),Y.models.addLoop(t);break;case i.db.LINETYPE.ALT_START:X(w,s,$.boxMargin,$.boxMargin+$.boxTextMargin,(t=>Y.newLoop(t)));break;case i.db.LINETYPE.ALT_ELSE:X(w,s,$.boxMargin+$.boxTextMargin,$.boxMargin,(t=>Y.addSectionToLoop(t)));break;case i.db.LINETYPE.ALT_END:t=Y.endLoop(),await C.drawLoop(h,t,"alt",$),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos()),Y.models.addLoop(t);break;case i.db.LINETYPE.PAR_START:case i.db.LINETYPE.PAR_OVER_START:X(w,s,$.boxMargin,$.boxMargin+$.boxTextMargin,(t=>Y.newLoop(t))),Y.saveVerticalPos();break;case i.db.LINETYPE.PAR_AND:X(w,s,$.boxMargin+$.boxTextMargin,$.boxMargin,(t=>Y.addSectionToLoop(t)));break;case i.db.LINETYPE.PAR_END:t=Y.endLoop(),await C.drawLoop(h,t,"par",$),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos()),Y.models.addLoop(t);break;case i.db.LINETYPE.AUTONUMBER:v=s.message.start||v,_=s.message.step||_,s.message.visible?i.db.enableSequenceNumbers():i.db.disableSequenceNumbers();break;case i.db.LINETYPE.CRITICAL_START:X(w,s,$.boxMargin,$.boxMargin+$.boxTextMargin,(t=>Y.newLoop(t)));break;case i.db.LINETYPE.CRITICAL_OPTION:X(w,s,$.boxMargin+$.boxTextMargin,$.boxMargin,(t=>Y.addSectionToLoop(t)));break;case i.db.LINETYPE.CRITICAL_END:t=Y.endLoop(),await C.drawLoop(h,t,"critical",$),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos()),Y.models.addLoop(t);break;case i.db.LINETYPE.BREAK_START:X(w,s,$.boxMargin,$.boxMargin+$.boxTextMargin,(t=>Y.newLoop(t)));break;case i.db.LINETYPE.BREAK_END:t=Y.endLoop(),await C.drawLoop(h,t,"break",$),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos()),Y.models.addLoop(t);break;default:try{a=s.msgModel,a.starty=Y.getVerticalPos(),a.sequenceIndex=v,a.sequenceVisible=i.db.showSequenceNumbers();const t=await W(0,a);J(s,a,t,I,p,g,u),L.push({messageModel:a,lineStartY:t}),Y.models.addMessage(a)}catch(K){r.l.error("error while drawing message",K)}}[i.db.LINETYPE.SOLID_OPEN,i.db.LINETYPE.DOTTED_OPEN,i.db.LINETYPE.SOLID,i.db.LINETYPE.DOTTED,i.db.LINETYPE.SOLID_CROSS,i.db.LINETYPE.DOTTED_CROSS,i.db.LINETYPE.SOLID_POINT,i.db.LINETYPE.DOTTED_POINT].includes(s.type)&&(v+=_),I++}r.l.debug("createdActors",g),r.l.debug("destroyedActors",u),await H(h,p,y,!1);for(const r of L)await z(h,r.messageModel,r.lineStartY,i);$.mirrorActors&&await H(h,p,y,!0),k.forEach((t=>C.drawBackgroundRect(h,t))),A(h,p,y,$);for(const r of Y.models.boxes)r.height=Y.getVerticalPos()-r.y,Y.insert(r.x,r.y,r.x+r.width,r.height),r.startx=r.x,r.starty=r.y,r.stopx=r.startx+r.width,r.stopy=r.starty+r.height,r.stroke="rgb(0,0,0, 0.5)",await C.drawBox(h,r,$);f&&Y.bumpVerticalPos($.boxMargin);const M=U(h,p,y,d),{bounds:N}=Y.getBounds();let O=N.stopy-N.starty;O{w.setWrap(t)}}},79186:(t,e,a)=>{a.d(e,{a:()=>n,b:()=>l,c:()=>c,d:()=>i,e:()=>h,f:()=>o,g:()=>d});var r=a(16750),s=a(86079);const i=(t,e)=>{const a=t.append("rect");if(a.attr("x",e.x),a.attr("y",e.y),a.attr("fill",e.fill),a.attr("stroke",e.stroke),a.attr("width",e.width),a.attr("height",e.height),e.name&&a.attr("name",e.name),void 0!==e.rx&&a.attr("rx",e.rx),void 0!==e.ry&&a.attr("ry",e.ry),void 0!==e.attrs)for(const r in e.attrs)a.attr(r,e.attrs[r]);return void 0!==e.class&&a.attr("class",e.class),a},n=(t,e)=>{const a={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};i(t,a).lower()},o=(t,e)=>{const a=e.text.replace(s.J," "),r=t.append("text");r.attr("x",e.x),r.attr("y",e.y),r.attr("class","legend"),r.style("text-anchor",e.anchor),void 0!==e.class&&r.attr("class",e.class);const i=r.append("tspan");return i.attr("x",e.x+2*e.textMargin),i.text(a),r},c=(t,e,a,s)=>{const i=t.append("image");i.attr("x",e),i.attr("y",a);const n=(0,r.Jf)(s);i.attr("xlink:href",n)},l=(t,e,a,s)=>{const i=t.append("use");i.attr("x",e),i.attr("y",a);const n=(0,r.Jf)(s);i.attr("xlink:href",`#${n}`)},d=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),h=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})}}]); \ No newline at end of file diff --git a/assets/js/23c48947.4f17eb98.js b/assets/js/23c48947.4f17eb98.js new file mode 100644 index 0000000000..cb38034e2b --- /dev/null +++ b/assets/js/23c48947.4f17eb98.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3813],{7938:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>d,metadata:()=>r,toc:()=>o});const r=JSON.parse('{"id":"iaas/scs-0124","title":"scs-0124: Standard for the security of IaaS service software","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0124.md","sourceDirName":"iaas","slug":"/iaas/scs-0124","permalink":"/standards/iaas/scs-0124","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services"},"next":{"title":"V1","permalink":"/standards/scs-0124-v1-security-of-iaas-service-software"}}');var a=t(74848),n=t(28453);const d={},i="scs-0124: Standard for the security of IaaS service software",c={},o=[{value:"Supplement: SCS Standard for the security of IaaS service software: Implementation and Testing Notes",id:"supplement-scs-standard-for-the-security-of-iaas-service-software-implementation-and-testing-notes",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(s.header,{children:(0,a.jsx)(s.h1,{id:"scs-0124-standard-for-the-security-of-iaas-service-software",children:"scs-0124: Standard for the security of IaaS service software"})}),"\n",(0,a.jsxs)(s.table,{children:[(0,a.jsx)(s.thead,{children:(0,a.jsxs)(s.tr,{children:[(0,a.jsx)(s.th,{children:"Version"}),(0,a.jsx)(s.th,{children:"Type"}),(0,a.jsx)(s.th,{children:"State"}),(0,a.jsx)(s.th,{children:"stabilized"}),(0,a.jsx)(s.th,{children:"deprecated"})]})}),(0,a.jsx)(s.tbody,{children:(0,a.jsxs)(s.tr,{children:[(0,a.jsx)(s.td,{children:(0,a.jsx)(s.a,{href:"/standards/scs-0124-v1-security-of-iaas-service-software",children:"scs-0124-v1"})}),(0,a.jsx)(s.td,{children:"Standard"}),(0,a.jsx)(s.td,{children:"Draft"}),(0,a.jsx)(s.td,{children:"-"}),(0,a.jsx)(s.td,{children:"-"})]})})]}),"\n",(0,a.jsx)(s.h2,{id:"supplement-scs-standard-for-the-security-of-iaas-service-software-implementation-and-testing-notes",children:"Supplement: SCS Standard for the security of IaaS service software: Implementation and Testing Notes"}),"\n",(0,a.jsxs)(s.table,{children:[(0,a.jsx)(s.thead,{children:(0,a.jsxs)(s.tr,{children:[(0,a.jsx)(s.th,{children:"Version"}),(0,a.jsx)(s.th,{children:"State"}),(0,a.jsx)(s.th,{children:"stabilized"}),(0,a.jsx)(s.th,{children:"deprecated"})]})}),(0,a.jsx)(s.tbody,{children:(0,a.jsxs)(s.tr,{children:[(0,a.jsx)(s.td,{children:(0,a.jsx)(s.a,{href:"/standards/scs-0124-w1-security-of-iaas-service-software",children:"w1"})}),(0,a.jsx)(s.td,{children:"Draft"}),(0,a.jsx)(s.td,{children:"-"}),(0,a.jsx)(s.td,{children:"-"})]})})]})]})}function l(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,a.jsx)(s,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>d,x:()=>i});var r=t(96540);const a={},n=r.createContext(a);function d(e){const s=r.useContext(n);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),r.createElement(n.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/23d0e2bb.e4d271b6.js b/assets/js/23d0e2bb.e4d271b6.js new file mode 100644 index 0000000000..9cbc8f79db --- /dev/null +++ b/assets/js/23d0e2bb.e4d271b6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[16323],{98808:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"iaas/scs-0114","title":"scs-0114: SCS Volume Types","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0114.md","sourceDirName":"iaas","slug":"/iaas/scs-0114","permalink":"/standards/iaas/scs-0114","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0113-v1-security-groups-decision-record"},"next":{"title":"V1","permalink":"/standards/scs-0114-v1-volume-type-standard"}}');var r=t(74848),d=t(28453);const a={},c="scs-0114: SCS Volume Types",i={},o=[];function l(e){const s={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"scs-0114-scs-volume-types",children:"scs-0114: SCS Volume Types"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0114-v1-volume-type-standard",children:"scs-0114-v1"})}),(0,r.jsx)(s.td,{children:"Standard"}),(0,r.jsx)(s.td,{children:"Stable"}),(0,r.jsx)(s.td,{children:"2024-11-13"}),(0,r.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,d.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>a,x:()=>c});var n=t(96540);const r={},d=n.createContext(r);function a(e){const s=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(d.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/23e62f09.4919e30c.js b/assets/js/23e62f09.4919e30c.js new file mode 100644 index 0000000000..a2fcb7ead6 --- /dev/null +++ b/assets/js/23e62f09.4919e30c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[68966],{17828:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>d,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"iam/scs-0300","title":"scs-0300: Requirements for SSO identity federation","description":"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign","source":"@site/standards/iam/scs-0300.md","sourceDirName":"iam","slug":"/iam/scs-0300","permalink":"/standards/iam/scs-0300","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"IAM Standards","permalink":"/standards/iam/"},"next":{"title":"V1","permalink":"/standards/scs-0300-v1-requirements-for-sso-identity-federation"}}');var i=n(74848),r=n(28453);const d={},a="scs-0300: Requirements for SSO identity federation",o={},c=[];function l(e){const t={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"scs-0300-requirements-for-sso-identity-federation",children:"scs-0300: Requirements for SSO identity federation"})}),"\n",(0,i.jsx)(t.p,{children:"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign\nCloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed\nexternally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard\nfocuses on delegating authentication to external identity providers and mapping users to roles within SCS for\nauthorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity\nProvider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible."}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Version"}),(0,i.jsx)(t.th,{children:"Type"}),(0,i.jsx)(t.th,{children:"State"}),(0,i.jsx)(t.th,{children:"stabilized"}),(0,i.jsx)(t.th,{children:"deprecated"})]})}),(0,i.jsx)(t.tbody,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"/standards/scs-0300-v1-requirements-for-sso-identity-federation",children:"scs-0300-v1"})}),(0,i.jsx)(t.td,{children:"Decision Record"}),(0,i.jsx)(t.td,{children:"Stable"}),(0,i.jsx)(t.td,{children:"2023-06-21"}),(0,i.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>d,x:()=>a});var s=n(96540);const i={},r=s.createContext(i);function d(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/24073.f2ca0f12.js b/assets/js/24073.f2ca0f12.js new file mode 100644 index 0000000000..2d8bff9833 --- /dev/null +++ b/assets/js/24073.f2ca0f12.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[24073],{24073:(t,e,r)=>{r.d(e,{diagram:()=>z});var i=r(86079),a=r(26312),n=(r(74353),r(16750),r(42838),function(){var t=function(t,e,r,i){for(r=r||{},i=t.length;i--;r[t[i]]=e);return r},e=[1,3],r=[1,6],i=[1,4],a=[1,5],n=[2,5],c=[1,12],s=[5,7,13,19,21,23,24,26,28,31,37,40,47],o=[7,13,19,21,23,24,26,28,31,37,40],l=[7,12,13,19,21,23,24,26,28,31,37,40],h=[7,13,47],m=[1,42],y=[1,41],u=[7,13,29,32,35,38,47],p=[1,55],g=[1,56],b=[1,57],d=[7,13,32,35,42,47],f={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,GG:5,document:6,EOF:7,":":8,DIR:9,options:10,body:11,OPT:12,NL:13,line:14,statement:15,commitStatement:16,mergeStatement:17,cherryPickStatement:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,section:24,branchStatement:25,CHECKOUT:26,ref:27,BRANCH:28,ORDER:29,NUM:30,CHERRY_PICK:31,COMMIT_ID:32,STR:33,PARENT_COMMIT:34,COMMIT_TAG:35,EMPTYSTR:36,MERGE:37,COMMIT_TYPE:38,commitType:39,COMMIT:40,commit_arg:41,COMMIT_MSG:42,NORMAL:43,REVERSE:44,HIGHLIGHT:45,ID:46,";":47,$accept:0,$end:1},terminals_:{2:"error",5:"GG",7:"EOF",8:":",9:"DIR",12:"OPT",13:"NL",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"section",26:"CHECKOUT",28:"BRANCH",29:"ORDER",30:"NUM",31:"CHERRY_PICK",32:"COMMIT_ID",33:"STR",34:"PARENT_COMMIT",35:"COMMIT_TAG",36:"EMPTYSTR",37:"MERGE",38:"COMMIT_TYPE",40:"COMMIT",42:"COMMIT_MSG",43:"NORMAL",44:"REVERSE",45:"HIGHLIGHT",46:"ID",47:";"},productions_:[0,[3,2],[3,3],[3,4],[3,5],[6,0],[6,2],[10,2],[10,1],[11,0],[11,2],[14,2],[14,1],[15,1],[15,1],[15,1],[15,2],[15,2],[15,1],[15,1],[15,1],[15,2],[25,2],[25,4],[18,3],[18,5],[18,5],[18,7],[18,7],[18,5],[18,5],[18,5],[18,7],[18,7],[18,7],[18,7],[17,2],[17,4],[17,4],[17,4],[17,6],[17,6],[17,6],[17,6],[17,6],[17,6],[17,8],[17,8],[17,8],[17,8],[17,8],[17,8],[16,2],[16,3],[16,3],[16,5],[16,5],[16,3],[16,5],[16,5],[16,5],[16,5],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,3],[16,5],[16,5],[16,5],[16,5],[16,5],[16,5],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[41,0],[41,1],[39,1],[39,1],[39,1],[27,1],[27,1],[4,1],[4,1],[4,1]],performAction:function(t,e,r,i,a,n,c){var s=n.length-1;switch(a){case 2:return n[s];case 3:return n[s-1];case 4:return i.setDirection(n[s-3]),n[s-1];case 6:i.setOptions(n[s-1]),this.$=n[s];break;case 7:n[s-1]+=n[s],this.$=n[s-1];break;case 9:this.$=[];break;case 10:n[s-1].push(n[s]),this.$=n[s-1];break;case 11:this.$=n[s-1];break;case 16:this.$=n[s].trim(),i.setAccTitle(this.$);break;case 17:case 18:this.$=n[s].trim(),i.setAccDescription(this.$);break;case 19:i.addSection(n[s].substr(8)),this.$=n[s].substr(8);break;case 21:i.checkout(n[s]);break;case 22:i.branch(n[s]);break;case 23:i.branch(n[s-2],n[s]);break;case 24:i.cherryPick(n[s],"",void 0);break;case 25:i.cherryPick(n[s-2],"",void 0,n[s]);break;case 26:i.cherryPick(n[s-2],"",n[s]);break;case 27:i.cherryPick(n[s-4],"",n[s],n[s-2]);break;case 28:i.cherryPick(n[s-4],"",n[s-2],n[s]);break;case 29:i.cherryPick(n[s],"",n[s-2]);break;case 30:i.cherryPick(n[s],"","");break;case 31:i.cherryPick(n[s-2],"","");break;case 32:i.cherryPick(n[s-4],"","",n[s-2]);break;case 33:i.cherryPick(n[s-4],"","",n[s]);break;case 34:i.cherryPick(n[s-2],"",n[s-4],n[s]);break;case 35:i.cherryPick(n[s-2],"","",n[s]);break;case 36:i.merge(n[s],"","","");break;case 37:i.merge(n[s-2],n[s],"","");break;case 38:i.merge(n[s-2],"",n[s],"");break;case 39:i.merge(n[s-2],"","",n[s]);break;case 40:i.merge(n[s-4],n[s],"",n[s-2]);break;case 41:i.merge(n[s-4],"",n[s],n[s-2]);break;case 42:i.merge(n[s-4],"",n[s-2],n[s]);break;case 43:i.merge(n[s-4],n[s-2],n[s],"");break;case 44:i.merge(n[s-4],n[s-2],"",n[s]);break;case 45:i.merge(n[s-4],n[s],n[s-2],"");break;case 46:i.merge(n[s-6],n[s-4],n[s-2],n[s]);break;case 47:i.merge(n[s-6],n[s],n[s-4],n[s-2]);break;case 48:i.merge(n[s-6],n[s-4],n[s],n[s-2]);break;case 49:i.merge(n[s-6],n[s-2],n[s-4],n[s]);break;case 50:i.merge(n[s-6],n[s],n[s-2],n[s-4]);break;case 51:i.merge(n[s-6],n[s-2],n[s],n[s-4]);break;case 52:i.commit(n[s]);break;case 53:i.commit("","",i.commitType.NORMAL,n[s]);break;case 54:i.commit("","",n[s],"");break;case 55:i.commit("","",n[s],n[s-2]);break;case 56:i.commit("","",n[s-2],n[s]);break;case 57:i.commit("",n[s],i.commitType.NORMAL,"");break;case 58:i.commit("",n[s-2],i.commitType.NORMAL,n[s]);break;case 59:i.commit("",n[s],i.commitType.NORMAL,n[s-2]);break;case 60:i.commit("",n[s-2],n[s],"");break;case 61:i.commit("",n[s],n[s-2],"");break;case 62:i.commit("",n[s-4],n[s-2],n[s]);break;case 63:i.commit("",n[s-4],n[s],n[s-2]);break;case 64:i.commit("",n[s-2],n[s-4],n[s]);break;case 65:i.commit("",n[s],n[s-4],n[s-2]);break;case 66:i.commit("",n[s],n[s-2],n[s-4]);break;case 67:i.commit("",n[s-2],n[s],n[s-4]);break;case 68:i.commit(n[s],"",i.commitType.NORMAL,"");break;case 69:i.commit(n[s],"",i.commitType.NORMAL,n[s-2]);break;case 70:i.commit(n[s-2],"",i.commitType.NORMAL,n[s]);break;case 71:i.commit(n[s-2],"",n[s],"");break;case 72:i.commit(n[s],"",n[s-2],"");break;case 73:i.commit(n[s],n[s-2],i.commitType.NORMAL,"");break;case 74:i.commit(n[s-2],n[s],i.commitType.NORMAL,"");break;case 75:i.commit(n[s-4],"",n[s-2],n[s]);break;case 76:i.commit(n[s-4],"",n[s],n[s-2]);break;case 77:i.commit(n[s-2],"",n[s-4],n[s]);break;case 78:i.commit(n[s],"",n[s-4],n[s-2]);break;case 79:i.commit(n[s],"",n[s-2],n[s-4]);break;case 80:i.commit(n[s-2],"",n[s],n[s-4]);break;case 81:i.commit(n[s-4],n[s],n[s-2],"");break;case 82:i.commit(n[s-4],n[s-2],n[s],"");break;case 83:i.commit(n[s-2],n[s],n[s-4],"");break;case 84:i.commit(n[s],n[s-2],n[s-4],"");break;case 85:i.commit(n[s],n[s-4],n[s-2],"");break;case 86:i.commit(n[s-2],n[s-4],n[s],"");break;case 87:i.commit(n[s-4],n[s],i.commitType.NORMAL,n[s-2]);break;case 88:i.commit(n[s-4],n[s-2],i.commitType.NORMAL,n[s]);break;case 89:i.commit(n[s-2],n[s],i.commitType.NORMAL,n[s-4]);break;case 90:i.commit(n[s],n[s-2],i.commitType.NORMAL,n[s-4]);break;case 91:i.commit(n[s],n[s-4],i.commitType.NORMAL,n[s-2]);break;case 92:i.commit(n[s-2],n[s-4],i.commitType.NORMAL,n[s]);break;case 93:i.commit(n[s-6],n[s-4],n[s-2],n[s]);break;case 94:i.commit(n[s-6],n[s-4],n[s],n[s-2]);break;case 95:i.commit(n[s-6],n[s-2],n[s-4],n[s]);break;case 96:i.commit(n[s-6],n[s],n[s-4],n[s-2]);break;case 97:i.commit(n[s-6],n[s-2],n[s],n[s-4]);break;case 98:i.commit(n[s-6],n[s],n[s-2],n[s-4]);break;case 99:i.commit(n[s-4],n[s-6],n[s-2],n[s]);break;case 100:i.commit(n[s-4],n[s-6],n[s],n[s-2]);break;case 101:i.commit(n[s-2],n[s-6],n[s-4],n[s]);break;case 102:i.commit(n[s],n[s-6],n[s-4],n[s-2]);break;case 103:i.commit(n[s-2],n[s-6],n[s],n[s-4]);break;case 104:i.commit(n[s],n[s-6],n[s-2],n[s-4]);break;case 105:i.commit(n[s],n[s-4],n[s-2],n[s-6]);break;case 106:i.commit(n[s-2],n[s-4],n[s],n[s-6]);break;case 107:i.commit(n[s],n[s-2],n[s-4],n[s-6]);break;case 108:i.commit(n[s-2],n[s],n[s-4],n[s-6]);break;case 109:i.commit(n[s-4],n[s-2],n[s],n[s-6]);break;case 110:i.commit(n[s-4],n[s],n[s-2],n[s-6]);break;case 111:i.commit(n[s-2],n[s-4],n[s-6],n[s]);break;case 112:i.commit(n[s],n[s-4],n[s-6],n[s-2]);break;case 113:i.commit(n[s-2],n[s],n[s-6],n[s-4]);break;case 114:i.commit(n[s],n[s-2],n[s-6],n[s-4]);break;case 115:i.commit(n[s-4],n[s-2],n[s-6],n[s]);break;case 116:i.commit(n[s-4],n[s],n[s-6],n[s-2]);break;case 117:this.$="";break;case 118:this.$=n[s];break;case 119:this.$=i.commitType.NORMAL;break;case 120:this.$=i.commitType.REVERSE;break;case 121:this.$=i.commitType.HIGHLIGHT}},table:[{3:1,4:2,5:e,7:r,13:i,47:a},{1:[3]},{3:7,4:2,5:e,7:r,13:i,47:a},{6:8,7:n,8:[1,9],9:[1,10],10:11,13:c},t(s,[2,124]),t(s,[2,125]),t(s,[2,126]),{1:[2,1]},{7:[1,13]},{6:14,7:n,10:11,13:c},{8:[1,15]},t(o,[2,9],{11:16,12:[1,17]}),t(l,[2,8]),{1:[2,2]},{7:[1,18]},{6:19,7:n,10:11,13:c},{7:[2,6],13:[1,22],14:20,15:21,16:23,17:24,18:25,19:[1,26],21:[1,27],23:[1,28],24:[1,29],25:30,26:[1,31],28:[1,35],31:[1,34],37:[1,33],40:[1,32]},t(l,[2,7]),{1:[2,3]},{7:[1,36]},t(o,[2,10]),{4:37,7:r,13:i,47:a},t(o,[2,12]),t(h,[2,13]),t(h,[2,14]),t(h,[2,15]),{20:[1,38]},{22:[1,39]},t(h,[2,18]),t(h,[2,19]),t(h,[2,20]),{27:40,33:m,46:y},t(h,[2,117],{41:43,32:[1,46],33:[1,48],35:[1,44],38:[1,45],42:[1,47]}),{27:49,33:m,46:y},{32:[1,50],35:[1,51]},{27:52,33:m,46:y},{1:[2,4]},t(o,[2,11]),t(h,[2,16]),t(h,[2,17]),t(h,[2,21]),t(u,[2,122]),t(u,[2,123]),t(h,[2,52]),{33:[1,53]},{39:54,43:p,44:g,45:b},{33:[1,58]},{33:[1,59]},t(h,[2,118]),t(h,[2,36],{32:[1,60],35:[1,62],38:[1,61]}),{33:[1,63]},{33:[1,64],36:[1,65]},t(h,[2,22],{29:[1,66]}),t(h,[2,53],{32:[1,68],38:[1,67],42:[1,69]}),t(h,[2,54],{32:[1,71],35:[1,70],42:[1,72]}),t(d,[2,119]),t(d,[2,120]),t(d,[2,121]),t(h,[2,57],{35:[1,73],38:[1,74],42:[1,75]}),t(h,[2,68],{32:[1,78],35:[1,76],38:[1,77]}),{33:[1,79]},{39:80,43:p,44:g,45:b},{33:[1,81]},t(h,[2,24],{34:[1,82],35:[1,83]}),{32:[1,84]},{32:[1,85]},{30:[1,86]},{39:87,43:p,44:g,45:b},{33:[1,88]},{33:[1,89]},{33:[1,90]},{33:[1,91]},{33:[1,92]},{33:[1,93]},{39:94,43:p,44:g,45:b},{33:[1,95]},{33:[1,96]},{39:97,43:p,44:g,45:b},{33:[1,98]},t(h,[2,37],{35:[1,100],38:[1,99]}),t(h,[2,38],{32:[1,102],35:[1,101]}),t(h,[2,39],{32:[1,103],38:[1,104]}),{33:[1,105]},{33:[1,106],36:[1,107]},{33:[1,108]},{33:[1,109]},t(h,[2,23]),t(h,[2,55],{32:[1,110],42:[1,111]}),t(h,[2,59],{38:[1,112],42:[1,113]}),t(h,[2,69],{32:[1,115],38:[1,114]}),t(h,[2,56],{32:[1,116],42:[1,117]}),t(h,[2,61],{35:[1,118],42:[1,119]}),t(h,[2,72],{32:[1,121],35:[1,120]}),t(h,[2,58],{38:[1,122],42:[1,123]}),t(h,[2,60],{35:[1,124],42:[1,125]}),t(h,[2,73],{35:[1,127],38:[1,126]}),t(h,[2,70],{32:[1,129],38:[1,128]}),t(h,[2,71],{32:[1,131],35:[1,130]}),t(h,[2,74],{35:[1,133],38:[1,132]}),{39:134,43:p,44:g,45:b},{33:[1,135]},{33:[1,136]},{33:[1,137]},{33:[1,138]},{39:139,43:p,44:g,45:b},t(h,[2,25],{35:[1,140]}),t(h,[2,26],{34:[1,141]}),t(h,[2,31],{34:[1,142]}),t(h,[2,29],{34:[1,143]}),t(h,[2,30],{34:[1,144]}),{33:[1,145]},{33:[1,146]},{39:147,43:p,44:g,45:b},{33:[1,148]},{39:149,43:p,44:g,45:b},{33:[1,150]},{33:[1,151]},{33:[1,152]},{33:[1,153]},{33:[1,154]},{33:[1,155]},{33:[1,156]},{39:157,43:p,44:g,45:b},{33:[1,158]},{33:[1,159]},{33:[1,160]},{39:161,43:p,44:g,45:b},{33:[1,162]},{39:163,43:p,44:g,45:b},{33:[1,164]},{33:[1,165]},{33:[1,166]},{39:167,43:p,44:g,45:b},{33:[1,168]},t(h,[2,43],{35:[1,169]}),t(h,[2,44],{38:[1,170]}),t(h,[2,42],{32:[1,171]}),t(h,[2,45],{35:[1,172]}),t(h,[2,40],{38:[1,173]}),t(h,[2,41],{32:[1,174]}),{33:[1,175],36:[1,176]},{33:[1,177]},{33:[1,178]},{33:[1,179]},{33:[1,180]},t(h,[2,66],{42:[1,181]}),t(h,[2,79],{32:[1,182]}),t(h,[2,67],{42:[1,183]}),t(h,[2,90],{38:[1,184]}),t(h,[2,80],{32:[1,185]}),t(h,[2,89],{38:[1,186]}),t(h,[2,65],{42:[1,187]}),t(h,[2,78],{32:[1,188]}),t(h,[2,64],{42:[1,189]}),t(h,[2,84],{35:[1,190]}),t(h,[2,77],{32:[1,191]}),t(h,[2,83],{35:[1,192]}),t(h,[2,63],{42:[1,193]}),t(h,[2,91],{38:[1,194]}),t(h,[2,62],{42:[1,195]}),t(h,[2,85],{35:[1,196]}),t(h,[2,86],{35:[1,197]}),t(h,[2,92],{38:[1,198]}),t(h,[2,76],{32:[1,199]}),t(h,[2,87],{38:[1,200]}),t(h,[2,75],{32:[1,201]}),t(h,[2,81],{35:[1,202]}),t(h,[2,82],{35:[1,203]}),t(h,[2,88],{38:[1,204]}),{33:[1,205]},{39:206,43:p,44:g,45:b},{33:[1,207]},{33:[1,208]},{39:209,43:p,44:g,45:b},{33:[1,210]},t(h,[2,27]),t(h,[2,32]),t(h,[2,28]),t(h,[2,33]),t(h,[2,34]),t(h,[2,35]),{33:[1,211]},{33:[1,212]},{33:[1,213]},{39:214,43:p,44:g,45:b},{33:[1,215]},{39:216,43:p,44:g,45:b},{33:[1,217]},{33:[1,218]},{33:[1,219]},{33:[1,220]},{33:[1,221]},{33:[1,222]},{33:[1,223]},{39:224,43:p,44:g,45:b},{33:[1,225]},{33:[1,226]},{33:[1,227]},{39:228,43:p,44:g,45:b},{33:[1,229]},{39:230,43:p,44:g,45:b},{33:[1,231]},{33:[1,232]},{33:[1,233]},{39:234,43:p,44:g,45:b},t(h,[2,46]),t(h,[2,48]),t(h,[2,47]),t(h,[2,49]),t(h,[2,51]),t(h,[2,50]),t(h,[2,107]),t(h,[2,108]),t(h,[2,105]),t(h,[2,106]),t(h,[2,110]),t(h,[2,109]),t(h,[2,114]),t(h,[2,113]),t(h,[2,112]),t(h,[2,111]),t(h,[2,116]),t(h,[2,115]),t(h,[2,104]),t(h,[2,103]),t(h,[2,102]),t(h,[2,101]),t(h,[2,99]),t(h,[2,100]),t(h,[2,98]),t(h,[2,97]),t(h,[2,96]),t(h,[2,95]),t(h,[2,93]),t(h,[2,94])],defaultActions:{7:[2,1],13:[2,2],18:[2,3],36:[2,4]},parseError:function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},parse:function(t){var e=this,r=[0],i=[],a=[null],n=[],c=this.table,s="",o=0,l=0,h=n.slice.call(arguments,1),m=Object.create(this.lexer),y={yy:{}};for(var u in this.yy)Object.prototype.hasOwnProperty.call(this.yy,u)&&(y.yy[u]=this.yy[u]);m.setInput(t,y.yy),y.yy.lexer=m,y.yy.parser=this,void 0===m.yylloc&&(m.yylloc={});var p=m.yylloc;n.push(p);var g=m.options&&m.options.ranges;"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var b,d,f,$,k,x,_,T,w,E={};;){if(d=r[r.length-1],this.defaultActions[d]?f=this.defaultActions[d]:(null==b&&(w=void 0,"number"!=typeof(w=i.pop()||m.lex()||1)&&(w instanceof Array&&(w=(i=w).pop()),w=e.symbols_[w]||w),b=w),f=c[d]&&c[d][b]),void 0===f||!f.length||!f[0]){var L="";for(k in T=[],c[d])this.terminals_[k]&&k>2&&T.push("'"+this.terminals_[k]+"'");L=m.showPosition?"Parse error on line "+(o+1)+":\n"+m.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(L,{text:m.match,token:this.terminals_[b]||b,line:m.yylineno,loc:p,expected:T})}if(f[0]instanceof Array&&f.length>1)throw new Error("Parse Error: multiple actions possible at state: "+d+", token: "+b);switch(f[0]){case 1:r.push(b),a.push(m.yytext),n.push(m.yylloc),r.push(f[1]),b=null,l=m.yyleng,s=m.yytext,o=m.yylineno,p=m.yylloc;break;case 2:if(x=this.productions_[f[1]][1],E.$=a[a.length-x],E._$={first_line:n[n.length-(x||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(x||1)].first_column,last_column:n[n.length-1].last_column},g&&(E._$.range=[n[n.length-(x||1)].range[0],n[n.length-1].range[1]]),void 0!==($=this.performAction.apply(E,[s,l,o,y.yy,f[1],a,n].concat(h))))return $;x&&(r=r.slice(0,-1*x*2),a=a.slice(0,-1*x),n=n.slice(0,-1*x)),r.push(this.productions_[f[1]][0]),a.push(E.$),n.push(E._$),_=c[r[r.length-2]][r[r.length-1]],r.push(_);break;case 3:return!0}}return!0}},$={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,r=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var a=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===i.length?this.yylloc.first_column:0)+i[i.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var r,i,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var n in a)this[n]=a[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,r,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),n=0;ne[0].length)){if(e=r,i=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,a[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,a[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,r,i){switch(r){case 0:return this.begin("acc_title"),19;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),21;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:case 30:case 34:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 13;case 8:case 9:break;case 10:return 5;case 11:return 40;case 12:return 32;case 13:return 38;case 14:return 42;case 15:return 43;case 16:return 44;case 17:return 45;case 18:return 35;case 19:return 28;case 20:return 29;case 21:return 37;case 22:return 31;case 23:return 34;case 24:return 26;case 25:case 26:return 9;case 27:return 8;case 28:return"CARET";case 29:this.begin("options");break;case 31:return 12;case 32:return 36;case 33:this.begin("string");break;case 35:return 33;case 36:return 30;case 37:return 46;case 38:return 7}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit(?=\s|$))/i,/^(?:id:)/i,/^(?:type:)/i,/^(?:msg:)/i,/^(?:NORMAL\b)/i,/^(?:REVERSE\b)/i,/^(?:HIGHLIGHT\b)/i,/^(?:tag:)/i,/^(?:branch(?=\s|$))/i,/^(?:order:)/i,/^(?:merge(?=\s|$))/i,/^(?:cherry-pick(?=\s|$))/i,/^(?:parent:)/i,/^(?:checkout(?=\s|$))/i,/^(?:LR\b)/i,/^(?:TB\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:[ \r\n\t]+end\b)/i,/^(?:[\s\S]+(?=[ \r\n\t]+end))/i,/^(?:["]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[0-9]+(?=\s|$))/i,/^(?:\w([-\./\w]*[-\w])?)/i,/^(?:$)/i,/^(?:\s+)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},options:{rules:[30,31],inclusive:!1},string:{rules:[34,35],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,32,33,36,37,38,39],inclusive:!0}}};function k(){this.yy={}}return f.lexer=$,k.prototype=f,f.Parser=k,new k}());n.parser=n;const c=n;let s=(0,i.c)().gitGraph.mainBranchName,o=(0,i.c)().gitGraph.mainBranchOrder,l={},h=null,m={};m[s]={name:s,order:o};let y={};y[s]=h;let u=s,p="LR",g=0;function b(){return(0,i.y)({length:7})}let d={};const f=function(t){if(t=i.e.sanitizeText(t,(0,i.c)()),void 0===y[t]){let e=new Error('Trying to checkout branch which is not yet created. (Help try using "branch '+t+'")');throw e.hash={text:"checkout "+t,token:"checkout "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"branch '+t+'"']},e}{u=t;const e=y[u];h=l[e]}};function $(t,e,r){const i=t.indexOf(e);-1===i?t.push(r):t.splice(i,1,r)}function k(t){const e=t.reduce(((t,e)=>t.seq>e.seq?t:e),t[0]);let r="";t.forEach((function(t){r+=t===e?"\t*":"\t|"}));const a=[r,e.id,e.seq];for(let i in y)y[i]===e.id&&a.push(i);if(i.l.debug(a.join(" ")),e.parents&&2==e.parents.length){const r=l[e.parents[0]];$(t,e,r),t.push(l[e.parents[1]])}else{if(0==e.parents.length)return;{const r=l[e.parents];$(t,e,r)}}k(t=function(t,e){const r=Object.create(null);return t.reduce(((t,i)=>{const a=e(i);return r[a]||(r[a]=!0,t.push(i)),t}),[])}(t,(t=>t.id)))}const x=function(){const t=Object.keys(l).map((function(t){return l[t]}));return t.forEach((function(t){i.l.debug(t.id)})),t.sort(((t,e)=>t.seq-e.seq)),t},_={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4},T={getConfig:()=>(0,i.c)().gitGraph,setDirection:function(t){p=t},setOptions:function(t){i.l.debug("options str",t),t=(t=t&&t.trim())||"{}";try{d=JSON.parse(t)}catch(e){i.l.error("error while parsing gitGraph options",e.message)}},getOptions:function(){return d},commit:function(t,e,r,a){i.l.debug("Entering commit:",t,e,r,a),e=i.e.sanitizeText(e,(0,i.c)()),t=i.e.sanitizeText(t,(0,i.c)()),a=i.e.sanitizeText(a,(0,i.c)());const n={id:e||g+"-"+b(),message:t,seq:g++,type:r||_.NORMAL,tag:a||"",parents:null==h?[]:[h.id],branch:u};h=n,l[n.id]=n,y[u]=n.id,i.l.debug("in pushCommit "+n.id)},branch:function(t,e){if(t=i.e.sanitizeText(t,(0,i.c)()),void 0!==y[t]){let e=new Error('Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout '+t+'")');throw e.hash={text:"branch "+t,token:"branch "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"checkout '+t+'"']},e}y[t]=null!=h?h.id:null,m[t]={name:t,order:e?parseInt(e,10):null},f(t),i.l.debug("in createBranch")},merge:function(t,e,r,a){t=i.e.sanitizeText(t,(0,i.c)()),e=i.e.sanitizeText(e,(0,i.c)());const n=l[y[u]],c=l[y[t]];if(u===t){let e=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(void 0===n||!n){let e=new Error('Incorrect usage of "merge". Current branch ('+u+")has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["commit"]},e}if(void 0===y[t]){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") does not exist");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch "+t]},e}if(void 0===c||!c){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"commit"']},e}if(n===c){let e=new Error('Incorrect usage of "merge". Both branches have same head');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(e&&void 0!==l[e]){let i=new Error('Incorrect usage of "merge". Commit with id:'+e+" already exists, use different custom Id");throw i.hash={text:"merge "+t+e+r+a,token:"merge "+t+e+r+a,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["merge "+t+" "+e+"_UNIQUE "+r+" "+a]},i}const s={id:e||g+"-"+b(),message:"merged branch "+t+" into "+u,seq:g++,parents:[null==h?null:h.id,y[t]],branch:u,type:_.MERGE,customType:r,customId:!!e,tag:a||""};h=s,l[s.id]=s,y[u]=s.id,i.l.debug(y),i.l.debug("in mergeBranch")},cherryPick:function(t,e,r,a){if(i.l.debug("Entering cherryPick:",t,e,r),t=i.e.sanitizeText(t,(0,i.c)()),e=i.e.sanitizeText(e,(0,i.c)()),r=i.e.sanitizeText(r,(0,i.c)()),a=i.e.sanitizeText(a,(0,i.c)()),!t||void 0===l[t]){let r=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}let n=l[t],c=n.branch;if(a&&(!Array.isArray(n.parents)||!n.parents.includes(a))){throw new Error("Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit.")}if(n.type===_.MERGE&&!a){throw new Error("Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified.")}if(!e||void 0===l[e]){if(c===u){let r=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}const s=l[y[u]];if(void 0===s||!s){let r=new Error('Incorrect usage of "cherry-pick". Current branch ('+u+")has no commits");throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}const o={id:g+"-"+b(),message:"cherry-picked "+n+" into "+u,seq:g++,parents:[null==h?null:h.id,n.id],branch:u,type:_.CHERRY_PICK,tag:r??`cherry-pick:${n.id}${n.type===_.MERGE?`|parent:${a}`:""}`};h=o,l[o.id]=o,y[u]=o.id,i.l.debug(y),i.l.debug("in cherryPick")}},checkout:f,prettyPrint:function(){i.l.debug(l);k([x()[0]])},clear:function(){l={},h=null;let t=(0,i.c)().gitGraph.mainBranchName,e=(0,i.c)().gitGraph.mainBranchOrder;y={},y[t]=null,m={},m[t]={name:t,order:e},u=t,g=0,(0,i.v)()},getBranchesAsObjArray:function(){return Object.values(m).map(((t,e)=>null!==t.order?t:{...t,order:parseFloat(`0.${e}`,10)})).sort(((t,e)=>t.order-e.order)).map((({name:t})=>({name:t})))},getBranches:function(){return y},getCommits:function(){return l},getCommitsArray:x,getCurrentBranch:function(){return u},getDirection:function(){return p},getHead:function(){return h},setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,setDiagramTitle:i.q,getDiagramTitle:i.t,commitType:_};let w={};const E=0,L=1,M=2,v=3,I=4;let A={},R={},O=[],C=0,S="LR";const P=t=>{const e=document.createElementNS("http://www.w3.org/2000/svg","text");let r=[];r="string"==typeof t?t.split(/\\n|\n|/gi):Array.isArray(t)?t:[];for(const i of r){const t=document.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","0"),t.setAttribute("class","row"),t.textContent=i.trim(),e.appendChild(t)}return e},B=(t,e,r)=>{const a=(0,i.c)().gitGraph,n=t.append("g").attr("class","commit-bullets"),c=t.append("g").attr("class","commit-labels");let s=0;"TB"===S&&(s=30);const o=Object.keys(e).sort(((t,r)=>e[t].seq-e[r].seq)),l=a.parallelCommits,h=10;o.forEach((t=>{const i=e[t];if(l)if(i.parents.length){const t=(t=>{let e="",r=0;return t.forEach((t=>{const i="TB"===S?R[t].y:R[t].x;i>=r&&(e=t,r=i)})),e||void 0})(i.parents);s="TB"===S?R[t].y+40:R[t].x+40}else s=0,"TB"===S&&(s=30);const o=s+h,m="TB"===S?o:A[i.branch].pos,y="TB"===S?A[i.branch].pos:o;if(r){let t,e=void 0!==i.customType&&""!==i.customType?i.customType:i.type;switch(e){case E:t="commit-normal";break;case L:t="commit-reverse";break;case M:t="commit-highlight";break;case v:t="commit-merge";break;case I:t="commit-cherry-pick";break;default:t="commit-normal"}if(e===M){const e=n.append("rect");e.attr("x",y-10),e.attr("y",m-10),e.attr("height",20),e.attr("width",20),e.attr("class",`commit ${i.id} commit-highlight${A[i.branch].index%8} ${t}-outer`),n.append("rect").attr("x",y-6).attr("y",m-6).attr("height",12).attr("width",12).attr("class",`commit ${i.id} commit${A[i.branch].index%8} ${t}-inner`)}else if(e===I)n.append("circle").attr("cx",y).attr("cy",m).attr("r",10).attr("class",`commit ${i.id} ${t}`),n.append("circle").attr("cx",y-3).attr("cy",m+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${i.id} ${t}`),n.append("circle").attr("cx",y+3).attr("cy",m+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${i.id} ${t}`),n.append("line").attr("x1",y+3).attr("y1",m+1).attr("x2",y).attr("y2",m-5).attr("stroke","#fff").attr("class",`commit ${i.id} ${t}`),n.append("line").attr("x1",y-3).attr("y1",m+1).attr("x2",y).attr("y2",m-5).attr("stroke","#fff").attr("class",`commit ${i.id} ${t}`);else{const r=n.append("circle");if(r.attr("cx",y),r.attr("cy",m),r.attr("r",i.type===v?9:10),r.attr("class",`commit ${i.id} commit${A[i.branch].index%8}`),e===v){const e=n.append("circle");e.attr("cx",y),e.attr("cy",m),e.attr("r",6),e.attr("class",`commit ${t} ${i.id} commit${A[i.branch].index%8}`)}if(e===L){n.append("path").attr("d",`M ${y-5},${m-5}L${y+5},${m+5}M${y-5},${m+5}L${y+5},${m-5}`).attr("class",`commit ${t} ${i.id} commit${A[i.branch].index%8}`)}}}if(R[i.id]="TB"===S?{x:y,y:o}:{x:o,y:m},r){const t=4,e=2;if(i.type!==I&&(i.customId&&i.type===v||i.type!==v)&&a.showCommitLabel){const r=c.append("g"),n=r.insert("rect").attr("class","commit-label-bkg"),l=r.append("text").attr("x",s).attr("y",m+25).attr("class","commit-label").text(i.id);let h=l.node().getBBox();if(n.attr("x",o-h.width/2-e).attr("y",m+13.5).attr("width",h.width+2*e).attr("height",h.height+2*e),"TB"===S&&(n.attr("x",y-(h.width+4*t+5)).attr("y",m-12),l.attr("x",y-(h.width+4*t)).attr("y",m+h.height-12)),"TB"!==S&&l.attr("x",o-h.width/2),a.rotateCommitLabel)if("TB"===S)l.attr("transform","rotate(-45, "+y+", "+m+")"),n.attr("transform","rotate(-45, "+y+", "+m+")");else{let t=-7.5-(h.width+10)/25*9.5,e=10+h.width/25*8.5;r.attr("transform","translate("+t+", "+e+") rotate(-45, "+s+", "+m+")")}}if(i.tag){const r=c.insert("polygon"),a=c.append("circle"),n=c.append("text").attr("y",m-16).attr("class","tag-label").text(i.tag);let l=n.node().getBBox();n.attr("x",o-l.width/2);const u=l.height/2,p=m-19.2;r.attr("class","tag-label-bkg").attr("points",`\n ${s-l.width/2-t/2},${p+e}\n ${s-l.width/2-t/2},${p-e}\n ${o-l.width/2-t},${p-u-e}\n ${o+l.width/2+t},${p-u-e}\n ${o+l.width/2+t},${p+u+e}\n ${o-l.width/2-t},${p+u+e}`),a.attr("cx",s-l.width/2+t/2).attr("cy",p).attr("r",1.5).attr("class","tag-hole"),"TB"===S&&(r.attr("class","tag-label-bkg").attr("points",`\n ${y},${s+e}\n ${y},${s-e}\n ${y+h},${s-u-e}\n ${y+h+l.width+t},${s-u-e}\n ${y+h+l.width+t},${s+u+e}\n ${y+h},${s+u+e}`).attr("transform","translate(12,12) rotate(45, "+y+","+s+")"),a.attr("cx",y+t/2).attr("cy",s).attr("transform","translate(12,12) rotate(45, "+y+","+s+")"),n.attr("x",y+5).attr("y",s+3).attr("transform","translate(14,14) rotate(45, "+y+","+s+")"))}}s+=50,s>C&&(C=s)}))},N=(t,e,r,i,a)=>{const n=("TB"===S?r.x{return(i=r).seq>t.seq&&i.seqt.branch===n)(r);var i}))},G=(t,e,r=0)=>{const i=t+Math.abs(t-e)/2;if(r>5)return i;if(O.every((t=>Math.abs(t-i)>=10)))return O.push(i),i;const a=Math.abs(t-e);return G(t,e-a/5,r+1)},H=(t,e)=>{const r=t.append("g").attr("class","commit-arrows");Object.keys(e).forEach((t=>{const i=e[t];i.parents&&i.parents.length>0&&i.parents.forEach((t=>{((t,e,r,i)=>{const a=R[e.id],n=R[r.id],c=N(e,r,a,n,i);let s,o="",l="",h=0,m=0,y=A[r.branch].index;if(r.type===v&&e.id!==r.parents[0]&&(y=A[e.branch].index),c){o="A 10 10, 0, 0, 0,",l="A 10 10, 0, 0, 1,",h=10,m=10;const t=a.yn.x&&(o="A 20 20, 0, 0, 0,",l="A 20 20, 0, 0, 1,",h=20,m=20,s=r.type===v&&e.id!==r.parents[0]?`M ${a.x} ${a.y} L ${a.x} ${n.y-h} ${l} ${a.x-m} ${n.y} L ${n.x} ${n.y}`:`M ${a.x} ${a.y} L ${n.x+h} ${a.y} ${o} ${n.x} ${a.y+m} L ${n.x} ${n.y}`),a.x===n.x&&(s=`M ${a.x} ${a.y} L ${n.x} ${n.y}`)):(a.yn.y&&(s=r.type===v&&e.id!==r.parents[0]?`M ${a.x} ${a.y} L ${n.x-h} ${a.y} ${o} ${n.x} ${a.y-m} L ${n.x} ${n.y}`:`M ${a.x} ${a.y} L ${a.x} ${n.y+h} ${l} ${a.x+m} ${n.y} L ${n.x} ${n.y}`),a.y===n.y&&(s=`M ${a.x} ${a.y} L ${n.x} ${n.y}`));t.append("path").attr("d",s).attr("class","arrow arrow"+y%8)})(r,e[t],i,e)}))}))},z={parser:c,db:T,renderer:{draw:function(t,e,r,n){A={},R={},w={},C=0,O=[],S="LR";const c=(0,i.c)(),s=c.gitGraph;i.l.debug("in gitgraph renderer",t+"\n","id:",e,r),w=n.db.getCommits();const o=n.db.getBranchesAsObjArray();S=n.db.getDirection();const l=(0,a.Ltv)(`[id="${e}"]`);let h=0;o.forEach(((t,e)=>{const r=P(t.name),i=l.append("g"),a=i.insert("g").attr("class","branchLabel"),n=a.insert("g").attr("class","label branch-label");n.node().appendChild(r);let c=r.getBBox();A[t.name]={pos:h,index:e},h+=50+(s.rotateCommitLabel?40:0)+("TB"===S?c.width/2:0),n.remove(),a.remove(),i.remove()})),B(l,w,!1),s.showBranches&&((t,e)=>{const r=(0,i.c)().gitGraph,a=t.append("g");e.forEach(((t,e)=>{const i=e%8,n=A[t.name].pos,c=a.append("line");c.attr("x1",0),c.attr("y1",n),c.attr("x2",C),c.attr("y2",n),c.attr("class","branch branch"+i),"TB"===S&&(c.attr("y1",30),c.attr("x1",n),c.attr("y2",C),c.attr("x2",n)),O.push(n);let s=t.name;const o=P(s),l=a.insert("rect"),h=a.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+i);h.node().appendChild(o);let m=o.getBBox();l.attr("class","branchLabelBkg label"+i).attr("rx",4).attr("ry",4).attr("x",-m.width-4-(!0===r.rotateCommitLabel?30:0)).attr("y",-m.height/2+8).attr("width",m.width+18).attr("height",m.height+4),h.attr("transform","translate("+(-m.width-14-(!0===r.rotateCommitLabel?30:0))+", "+(n-m.height/2-1)+")"),"TB"===S&&(l.attr("x",n-m.width/2-10).attr("y",0),h.attr("transform","translate("+(n-m.width/2-5)+", 0)")),"TB"!==S&&l.attr("transform","translate(-19, "+(n-m.height/2)+")")}))})(l,o),H(l,w),B(l,w,!0),i.u.insertTitle(l,"gitTitleText",s.titleTopMargin,n.db.getDiagramTitle()),(0,i.z)(void 0,l,s.diagramPadding,s.useMaxWidth??c.useMaxWidth)}},styles:t=>`\n .commit-id,\n .commit-msg,\n .branch-label {\n fill: lightgrey;\n color: lightgrey;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n ${[0,1,2,3,4,5,6,7].map((e=>`\n .branch-label${e} { fill: ${t["gitBranchLabel"+e]}; }\n .commit${e} { stroke: ${t["git"+e]}; fill: ${t["git"+e]}; }\n .commit-highlight${e} { stroke: ${t["gitInv"+e]}; fill: ${t["gitInv"+e]}; }\n .label${e} { fill: ${t["git"+e]}; }\n .arrow${e} { stroke: ${t["git"+e]}; }\n `)).join("\n")}\n\n .branch {\n stroke-width: 1;\n stroke: ${t.lineColor};\n stroke-dasharray: 2;\n }\n .commit-label { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelColor};}\n .commit-label-bkg { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelBackground}; opacity: 0.5; }\n .tag-label { font-size: ${t.tagLabelFontSize}; fill: ${t.tagLabelColor};}\n .tag-label-bkg { fill: ${t.tagLabelBackground}; stroke: ${t.tagLabelBorder}; }\n .tag-hole { fill: ${t.textColor}; }\n\n .commit-merge {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n .commit-reverse {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n stroke-width: 3;\n }\n .commit-highlight-outer {\n }\n .commit-highlight-inner {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n\n .arrow { stroke-width: 8; stroke-linecap: round; fill: none}\n .gitTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/24104.f591bad1.js b/assets/js/24104.f591bad1.js new file mode 100644 index 0000000000..ec0ed1d765 --- /dev/null +++ b/assets/js/24104.f591bad1.js @@ -0,0 +1 @@ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[24104],{62954:(n,t,e)=>{n.exports=function(){function n(t,e,i){function r(a,o){if(!e[a]){if(!t[a]){if(c)return c(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var s=e[a]={exports:{}};t[a][0].call(s.exports,(function(n){return r(t[a][1][n]||n)}),s,s.exports,n,t,e,i)}return e[a].exports}for(var c=void 0,a=0;a0&&void 0!==arguments[0]?arguments[0]:{},i=e.defaultLayoutOptions,c=void 0===i?{}:i,o=e.algorithms,u=void 0===o?["layered","stress","mrtree","radial","force","disco","sporeOverlap","sporeCompaction","rectpacking"]:o,s=e.workerFactory,h=e.workerUrl;if(r(this,n),this.defaultLayoutOptions=c,this.initialized=!1,void 0===h&&void 0===s)throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'.");var f=s;void 0!==h&&void 0===s&&(f=function(n){return new Worker(n)});var l=f(h);if("function"!=typeof l.postMessage)throw new TypeError("Created worker does not provide the required 'postMessage' function.");this.worker=new a(l),this.worker.postMessage({cmd:"register",algorithms:u}).then((function(n){return t.initialized=!0})).catch(console.err)}return i(n,[{key:"layout",value:function(n){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},e=t.layoutOptions,i=void 0===e?this.defaultLayoutOptions:e,r=t.logging,c=void 0!==r&&r,a=t.measureExecutionTime,o=void 0!==a&&a;return n?this.worker.postMessage({cmd:"layout",graph:n,layoutOptions:i,options:{logging:c,measureExecutionTime:o}}):Promise.reject(new Error("Missing mandatory parameter 'graph'."))}},{key:"knownLayoutAlgorithms",value:function(){return this.worker.postMessage({cmd:"algorithms"})}},{key:"knownLayoutOptions",value:function(){return this.worker.postMessage({cmd:"options"})}},{key:"knownLayoutCategories",value:function(){return this.worker.postMessage({cmd:"categories"})}},{key:"terminateWorker",value:function(){this.worker.terminate()}}]),n}();e.default=c;var a=function(){function n(t){var e=this;if(r(this,n),void 0===t)throw new Error("Missing mandatory parameter 'worker'.");this.resolvers={},this.worker=t,this.worker.onmessage=function(n){setTimeout((function(){e.receive(e,n)}),0)}}return i(n,[{key:"postMessage",value:function(n){var t=this.id||0;this.id=t+1,n.id=t;var e=this;return new Promise((function(i,r){e.resolvers[t]=function(n,t){n?(e.convertGwtStyleError(n),r(n)):i(t)},e.worker.postMessage(n)}))}},{key:"receive",value:function(n,t){var e=t.data,i=n.resolvers[e.id];i&&(delete n.resolvers[e.id],e.error?i(e.error):i(null,e.data))}},{key:"terminate",value:function(){this.worker.terminate&&this.worker.terminate()}},{key:"convertGwtStyleError",value:function(n){if(n){var t=n.__java$exception;t&&(t.cause&&t.cause.backingJsObject&&(n.cause=t.cause.backingJsObject,this.convertGwtStyleError(n.cause)),delete n.__java$exception)}}}]),n}()},{}],2:[function(n,t,i){(function(n){(function(){"use strict";var e;function r(){}function c(){}function a(){}function o(){}function u(){}function s(){}function h(){}function f(){}function l(){}function b(){}function w(){}function d(){}function g(){}function p(){}function m(){}function v(){}function k(){}function y(){}function M(){}function T(){}function j(){}function E(){}function S(){}function P(){}function C(){}function I(){}function O(){}function A(){}function L(){}function N(){}function $(){}function D(){}function x(){}function R(){}function K(){}function F(){}function _(){}function B(){}function H(){}function U(){}function G(){}function q(){}function X(){}function z(){}function V(){}function W(){}function Q(){}function J(){}function Y(){}function Z(){}function nn(){}function tn(){}function en(){}function rn(){}function cn(){}function an(){}function on(){}function un(){}function sn(){}function hn(){}function fn(){}function ln(){}function bn(){}function wn(){}function dn(){}function gn(){}function pn(){}function mn(){}function vn(){}function kn(){}function yn(){}function Mn(){}function Tn(){}function jn(){}function En(){}function Sn(){}function Pn(){}function Cn(){}function In(){}function On(){}function An(){}function Ln(){}function Nn(){}function $n(){}function Dn(){}function xn(){}function Rn(){}function Kn(){}function Fn(){}function _n(){}function Bn(){}function Hn(){}function Un(){}function Gn(){}function qn(){}function Xn(){}function zn(){}function Vn(){}function Wn(){}function Qn(){}function Jn(){}function Yn(){}function Zn(){}function nt(){}function tt(){}function et(){}function it(){}function rt(){}function ct(){}function at(){}function ot(){}function ut(){}function st(){}function ht(){}function ft(){}function lt(){}function bt(){}function wt(){}function dt(){}function gt(){}function pt(){}function mt(){}function vt(){}function kt(){}function yt(){}function Mt(){}function Tt(){}function jt(){}function Et(){}function St(){}function Pt(){}function Ct(){}function It(){}function Ot(){}function At(){}function Lt(){}function Nt(){}function $t(){}function Dt(){}function xt(){}function Rt(){}function Kt(){}function Ft(){}function _t(){}function Bt(){}function Ht(){}function Ut(){}function Gt(){}function qt(){}function Xt(){}function zt(){}function Vt(){}function Wt(){}function Qt(){}function Jt(){}function Yt(){}function Zt(){}function ne(){}function te(){}function ee(){}function ie(){}function re(){}function ce(){}function ae(){}function oe(){}function ue(){}function se(){}function he(){}function fe(){}function le(){}function be(){}function we(){}function de(){}function ge(){}function pe(){}function me(){}function ve(){}function ke(){}function ye(){}function Me(){}function Te(){}function je(){}function Ee(){}function Se(){}function Pe(){}function Ce(){}function Ie(){}function Oe(){}function Ae(){}function Le(){}function Ne(){}function $e(){}function De(){}function xe(){}function Re(){}function Ke(){}function Fe(){}function _e(){}function Be(){}function He(){}function Ue(){}function Ge(){}function qe(){}function Xe(){}function ze(){}function Ve(){}function We(){}function Qe(){}function Je(){}function Ye(){}function Ze(){}function ni(){}function ti(){}function ei(){}function ii(){}function ri(){}function ci(){}function ai(){}function oi(){}function ui(){}function si(){}function hi(){}function fi(){}function li(){}function bi(){}function wi(){}function di(){}function gi(){}function pi(){}function mi(){}function vi(){}function ki(){}function yi(){}function Mi(){}function Ti(){}function ji(){}function Ei(){}function Si(){}function Pi(){}function Ci(){}function Ii(){}function Oi(){}function Ai(){}function Li(){}function Ni(){}function $i(){}function Di(){}function xi(){}function Ri(){}function Ki(){}function Fi(){}function _i(){}function Bi(){}function Hi(){}function Ui(){}function Gi(){}function qi(){}function Xi(){}function zi(){}function Vi(){}function Wi(){}function Qi(){}function Ji(){}function Yi(){}function Zi(){}function nr(){}function tr(){}function er(){}function ir(){}function rr(){}function cr(){}function ar(){}function or(){}function ur(){}function sr(){}function hr(){}function fr(){}function lr(){}function br(){}function wr(){}function dr(){}function gr(){}function pr(){}function mr(){}function vr(){}function kr(){}function yr(){}function Mr(){}function Tr(){}function jr(){}function Er(){}function Sr(){}function Pr(){}function Cr(){}function Ir(){}function Or(){}function Ar(){}function Lr(){}function Nr(){}function $r(){}function Dr(){}function xr(){}function Rr(){}function Kr(){}function Fr(){}function _r(){}function Br(){}function Hr(){}function Ur(){}function Gr(){}function qr(){}function Xr(){}function zr(){}function Vr(){}function Wr(){}function Qr(){}function Jr(){}function Yr(){}function Zr(){}function nc(){}function tc(){}function ec(){}function ic(){}function rc(){}function cc(){}function ac(){}function oc(){}function uc(){}function sc(){}function hc(){}function fc(){}function lc(){}function bc(){}function wc(){}function dc(){}function gc(){}function pc(){}function mc(){}function vc(){}function kc(){}function yc(){}function Mc(){}function Tc(){}function jc(){}function Ec(){}function Sc(){}function Pc(){}function Cc(){}function Ic(){}function Oc(){}function Ac(){}function Lc(){}function Nc(){}function $c(){}function Dc(){}function xc(){}function Rc(){}function Kc(){}function Fc(){}function _c(){}function Bc(){}function Hc(){}function Uc(){}function Gc(){}function qc(){}function Xc(){}function zc(){}function Vc(){}function Wc(){}function Qc(){}function Jc(){}function Yc(){}function Zc(){}function na(){}function ta(){}function ea(){}function ia(){}function ra(){}function ca(){}function aa(){}function oa(){}function ua(){}function sa(){}function ha(){}function fa(){}function la(){}function ba(){}function wa(){}function da(){}function ga(){}function pa(){}function ma(){}function va(){}function ka(){}function ya(){}function Ma(){}function Ta(){}function ja(){}function Ea(){}function Sa(){}function Pa(){}function Ca(){}function Ia(){}function Oa(){}function Aa(){}function La(){}function Na(){}function $a(){}function Da(){}function xa(){}function Ra(){}function Ka(){}function Fa(){}function _a(){}function Ba(){}function Ha(){}function Ua(){}function Ga(){}function qa(){}function Xa(){}function za(){}function Va(){}function Wa(){}function Qa(){}function Ja(){}function Ya(){}function Za(){}function no(){}function to(){}function eo(){}function io(){}function ro(){}function co(){}function ao(){}function oo(){}function uo(){}function so(){}function ho(){}function fo(){}function lo(){}function bo(){}function wo(){}function go(){}function po(){}function mo(){}function vo(){}function ko(){}function yo(){}function Mo(){}function To(){}function jo(){}function Eo(){}function So(){}function Po(){}function Co(){}function Io(){}function Oo(){}function Ao(){}function Lo(){}function No(){}function $o(){}function Do(){}function xo(){}function Ro(){}function Ko(){}function Fo(){}function _o(){}function Bo(){}function Ho(){}function Uo(){}function Go(){}function qo(){}function Xo(){}function zo(){}function Vo(){}function Wo(){}function Qo(){}function Jo(){}function Yo(){}function Zo(){}function nu(){}function tu(){}function eu(){}function iu(){}function ru(){}function cu(){}function au(){}function ou(){}function uu(){}function su(){}function hu(){}function fu(){}function lu(){}function bu(){}function wu(){}function du(){}function gu(){}function pu(){}function mu(){}function vu(){}function ku(){}function yu(){}function Mu(){}function Tu(){}function ju(){}function Eu(){}function Su(){}function Pu(){}function Cu(){}function Iu(){}function Ou(){}function Au(){}function Lu(){}function Nu(){}function $u(){}function Du(){}function xu(){}function Ru(){}function Ku(){}function Fu(){}function _u(){}function Bu(){}function Hu(){}function Uu(){}function Gu(){}function qu(){}function Xu(){}function zu(){}function Vu(){}function Wu(){}function Qu(){}function Ju(){}function Yu(){}function Zu(){}function ns(){}function ts(){}function es(){}function is(){}function rs(){}function cs(){}function as(){}function os(){}function us(){}function ss(){}function hs(){}function fs(){}function ls(){}function bs(){}function ws(){}function ds(){}function gs(){}function ps(){}function ms(){}function vs(){}function ks(){}function ys(){}function Ms(){}function Ts(){}function js(){}function Es(){}function Ss(){}function Ps(){}function Cs(){}function Is(){}function Os(){}function As(){}function Ls(){}function Ns(){}function $s(){}function Ds(){}function xs(){}function Rs(){}function Ks(){}function Fs(){}function _s(){}function Bs(){}function Hs(){}function Us(){}function Gs(){}function qs(){}function Xs(){}function zs(){}function Vs(){}function Ws(){}function Qs(){}function Js(){}function Ys(){}function Zs(){}function nh(){}function th(){}function eh(){}function ih(){}function rh(){}function ch(){}function ah(){}function oh(){}function uh(){}function sh(){}function hh(){}function fh(){}function lh(){}function bh(){}function wh(){}function dh(){}function gh(){}function ph(){}function mh(){}function vh(){}function kh(){}function yh(){}function Mh(){}function Th(){}function jh(){}function Eh(){}function Sh(){}function Ph(){}function Ch(){}function Ih(){}function Oh(){}function Ah(){}function Lh(){}function Nh(){}function $h(){}function Dh(){}function xh(){}function Rh(){}function Kh(){}function Fh(){}function _h(){}function Bh(){}function Hh(){}function Uh(){}function Gh(){}function qh(){}function Xh(){}function zh(){}function Vh(){}function Wh(){}function Qh(){}function Jh(){}function Yh(){}function Zh(){}function nf(){}function tf(){}function ef(){}function rf(){}function cf(){}function af(){}function of(){}function uf(){}function sf(){}function hf(){}function ff(){}function lf(){}function bf(){}function wf(){}function df(){}function gf(){}function pf(){}function mf(){}function vf(){}function kf(){}function yf(){}function Mf(){}function Tf(){}function jf(){}function Ef(){}function Sf(){}function Pf(){}function Cf(){}function If(){}function Of(){}function Af(){}function Lf(){}function Nf(){}function $f(){}function Df(){}function xf(){}function Rf(n){}function Kf(n){}function Ff(){gy()}function _f(){VS()}function Bf(){MEn()}function Hf(){pbn()}function Uf(){ryn()}function Gf(){oOn()}function qf(){cGn()}function Xf(){yjn()}function zf(){Bjn()}function Vf(){WS()}function Wf(){HB()}function Qf(){QS()}function Jf(){Pun()}function Yf(){F7()}function Zf(){Ean()}function nl(){Y0()}function tl(){Pan()}function el(){Unn()}function il(){Q0()}function rl(){Cln()}function cl(){Ian()}function al(){Can()}function ol(){c6()}function ul(){Oan()}function sl(){jIn()}function hl(){YS()}function fl(){VYn()}function ll(){jYn()}function bl(){Aan()}function wl(){Iun()}function dl(){Z0()}function gl(){Pjn()}function pl(){t2()}function ml(){gUn()}function vl(){eDn()}function kl(){tcn()}function yl(){Kdn()}function Ml(){QGn()}function Tl(){e3()}function jl(){ncn()}function El(){EHn()}function Sl(){jOn()}function Pl(){IHn()}function Cl(){S_n()}function Il(){fIn()}function Ol(){uBn()}function Al(){jMn()}function Ll(){oB()}function Nl(){Stn()}function $l(){lIn()}function Dl(){XYn()}function xl(){Iln()}function Rl(){Wmn()}function Kl(){Oun()}function Fl(){tXn()}function _l(){vGn()}function Bl(n){tJ(n)}function Hl(n){this.a=n}function Ul(n){this.a=n}function Gl(n){this.a=n}function ql(n){this.a=n}function Xl(n){this.a=n}function zl(n){this.a=n}function Vl(n){this.a=n}function Wl(n){this.a=n}function Ql(n){this.a=n}function Jl(n){this.a=n}function Yl(n){this.a=n}function Zl(n){this.a=n}function nb(n){this.a=n}function tb(n){this.a=n}function eb(n){this.a=n}function ib(n){this.a=n}function rb(n){this.a=n}function cb(n){this.a=n}function ab(n){this.a=n}function ob(n){this.a=n}function ub(n){this.a=n}function sb(n){this.a=n}function hb(n){this.b=n}function fb(n){this.c=n}function lb(n){this.a=n}function bb(n){this.a=n}function wb(n){this.a=n}function db(n){this.a=n}function gb(n){this.a=n}function pb(n){this.a=n}function mb(n){this.a=n}function vb(n){this.a=n}function kb(n){this.a=n}function yb(n){this.a=n}function Mb(n){this.a=n}function Tb(n){this.a=n}function jb(n){this.a=n}function Eb(n){this.a=n}function Sb(n){this.a=n}function Pb(n){this.a=n}function Cb(n){this.a=n}function Ib(){this.a=[]}function Ob(n,t){n.a=t}function Ab(n,t){n.a=t}function Lb(n,t){n.b=t}function Nb(n,t){n.b=t}function $b(n,t){n.b=t}function Db(n,t){n.j=t}function xb(n,t){n.g=t}function Rb(n,t){n.i=t}function Kb(n,t){n.c=t}function Fb(n,t){n.c=t}function _b(n,t){n.d=t}function Bb(n,t){n.d=t}function Hb(n,t){n.k=t}function Ub(n,t){n.c=t}function Gb(n,t){n.c=t}function qb(n,t){n.a=t}function Xb(n,t){n.a=t}function zb(n,t){n.f=t}function Vb(n,t){n.a=t}function Wb(n,t){n.b=t}function Qb(n,t){n.d=t}function Jb(n,t){n.i=t}function Yb(n,t){n.o=t}function Zb(n,t){n.r=t}function nw(n,t){n.a=t}function tw(n,t){n.b=t}function ew(n,t){n.e=t}function iw(n,t){n.f=t}function rw(n,t){n.g=t}function cw(n,t){n.e=t}function aw(n,t){n.f=t}function ow(n,t){n.f=t}function uw(n,t){n.a=t}function sw(n,t){n.b=t}function hw(n,t){n.n=t}function fw(n,t){n.a=t}function lw(n,t){n.c=t}function bw(n,t){n.c=t}function ww(n,t){n.c=t}function dw(n,t){n.a=t}function gw(n,t){n.a=t}function pw(n,t){n.d=t}function mw(n,t){n.d=t}function vw(n,t){n.e=t}function kw(n,t){n.e=t}function yw(n,t){n.g=t}function Mw(n,t){n.f=t}function Tw(n,t){n.j=t}function jw(n,t){n.a=t}function Ew(n,t){n.a=t}function Sw(n,t){n.b=t}function Pw(n){n.b=n.a}function Cw(n){n.c=n.d.d}function Iw(n){this.a=n}function Ow(n){this.a=n}function Aw(n){this.a=n}function Lw(n){this.a=n}function Nw(n){this.a=n}function $w(n){this.a=n}function Dw(n){this.a=n}function xw(n){this.a=n}function Rw(n){this.a=n}function Kw(n){this.a=n}function Fw(n){this.a=n}function _w(n){this.a=n}function Bw(n){this.a=n}function Hw(n){this.a=n}function Uw(n){this.b=n}function Gw(n){this.b=n}function qw(n){this.b=n}function Xw(n){this.a=n}function zw(n){this.a=n}function Vw(n){this.c=n}function Ww(n){this.c=n}function Qw(n){this.c=n}function Jw(n){this.d=n}function Yw(n){this.a=n}function Zw(n){this.a=n}function nd(n){this.a=n}function td(n){this.a=n}function ed(n){this.a=n}function id(n){this.a=n}function rd(n){this.a=n}function cd(n){this.a=n}function ad(n){this.a=n}function od(n){this.a=n}function ud(n){this.a=n}function sd(n){this.a=n}function hd(n){this.a=n}function fd(n){this.a=n}function ld(n){this.a=n}function bd(n){this.a=n}function wd(n){this.a=n}function dd(n){this.a=n}function gd(n){this.a=n}function pd(n){this.a=n}function md(n){this.a=n}function vd(n){this.a=n}function kd(n){this.a=n}function yd(n){this.a=n}function Md(n){this.a=n}function Td(n){this.a=n}function jd(n){this.a=n}function Ed(n){this.a=n}function Sd(n){this.a=n}function Pd(n){this.a=n}function Cd(n){this.a=n}function Id(n){this.a=n}function Od(n){this.a=n}function Ad(n){this.a=n}function Ld(n){this.a=n}function Nd(n){this.a=n}function $d(n){this.a=n}function Dd(n){this.a=n}function xd(n){this.a=n}function Rd(n){this.a=n}function Kd(n){this.a=n}function Fd(n){this.a=n}function _d(n){this.a=n}function Bd(n){this.a=n}function Hd(n){this.a=n}function Ud(n){this.a=n}function Gd(n){this.a=n}function qd(n){this.a=n}function Xd(n){this.e=n}function zd(n){this.a=n}function Vd(n){this.a=n}function Wd(n){this.a=n}function Qd(n){this.a=n}function Jd(n){this.a=n}function Yd(n){this.a=n}function Zd(n){this.a=n}function ng(n){this.a=n}function tg(n){this.a=n}function eg(n){this.a=n}function ig(n){this.a=n}function rg(n){this.a=n}function cg(n){this.a=n}function ag(n){this.a=n}function og(n){this.a=n}function ug(n){this.a=n}function sg(n){this.a=n}function hg(n){this.a=n}function fg(n){this.a=n}function lg(n){this.a=n}function bg(n){this.a=n}function wg(n){this.a=n}function dg(n){this.a=n}function gg(n){this.a=n}function pg(n){this.a=n}function mg(n){this.a=n}function vg(n){this.a=n}function kg(n){this.a=n}function yg(n){this.a=n}function Mg(n){this.a=n}function Tg(n){this.a=n}function jg(n){this.a=n}function Eg(n){this.a=n}function Sg(n){this.a=n}function Pg(n){this.a=n}function Cg(n){this.a=n}function Ig(n){this.a=n}function Og(n){this.a=n}function Ag(n){this.a=n}function Lg(n){this.a=n}function Ng(n){this.a=n}function $g(n){this.a=n}function Dg(n){this.a=n}function xg(n){this.a=n}function Rg(n){this.a=n}function Kg(n){this.a=n}function Fg(n){this.a=n}function _g(n){this.a=n}function Bg(n){this.a=n}function Hg(n){this.a=n}function Ug(n){this.a=n}function Gg(n){this.a=n}function qg(n){this.a=n}function Xg(n){this.a=n}function zg(n){this.c=n}function Vg(n){this.b=n}function Wg(n){this.a=n}function Qg(n){this.a=n}function Jg(n){this.a=n}function Yg(n){this.a=n}function Zg(n){this.a=n}function np(n){this.a=n}function tp(n){this.a=n}function ep(n){this.a=n}function ip(n){this.a=n}function rp(n){this.a=n}function cp(n){this.a=n}function ap(n){this.a=n}function op(n){this.a=n}function up(n){this.a=n}function sp(n){this.a=n}function hp(n){this.a=n}function fp(n){this.a=n}function lp(n){this.a=n}function bp(n){this.a=n}function wp(n){this.a=n}function dp(n){this.a=n}function gp(n){this.a=n}function pp(n){this.a=n}function mp(n){this.a=n}function vp(n){this.a=n}function kp(n){this.a=n}function yp(n){this.a=n}function Mp(n){this.a=n}function Tp(n){this.a=n}function jp(n){this.a=n}function Ep(n){this.a=n}function Sp(n){this.a=n}function Pp(n){this.a=n}function Cp(n){this.a=n}function Ip(n){this.a=n}function Op(n){this.a=n}function Ap(n){this.a=n}function Lp(n){this.a=n}function Np(n){this.a=n}function $p(n){this.a=n}function Dp(n){this.a=n}function xp(n){this.a=n}function Rp(n){this.a=n}function Kp(n){this.a=n}function Fp(n){this.a=n}function _p(n){this.a=n}function Bp(n){this.a=n}function Hp(n){this.a=n}function Up(n){this.a=n}function Gp(n){this.a=n}function qp(n){this.a=n}function Xp(n){this.a=n}function zp(n){this.a=n}function Vp(n){this.a=n}function Wp(n){this.a=n}function Qp(n){this.a=n}function Jp(n){this.f=n}function Yp(n){this.a=n}function Zp(n){this.a=n}function nm(n){this.a=n}function tm(n){this.a=n}function em(n){this.a=n}function im(n){this.a=n}function rm(n){this.a=n}function cm(n){this.a=n}function am(n){this.a=n}function om(n){this.a=n}function um(n){this.a=n}function sm(n){this.a=n}function hm(n){this.a=n}function fm(n){this.a=n}function lm(n){this.a=n}function bm(n){this.a=n}function wm(n){this.a=n}function dm(n){this.a=n}function gm(n){this.a=n}function pm(n){this.a=n}function mm(n){this.a=n}function vm(n){this.a=n}function km(n){this.a=n}function ym(n){this.a=n}function Mm(n){this.a=n}function Tm(n){this.a=n}function jm(n){this.a=n}function Em(n){this.a=n}function Sm(n){this.a=n}function Pm(n){this.a=n}function Cm(n){this.b=n}function Im(n){this.a=n}function Om(n){this.a=n}function Am(n){this.a=n}function Lm(n){this.a=n}function Nm(n){this.a=n}function $m(n){this.a=n}function Dm(n){this.a=n}function xm(n){this.b=n}function Rm(n){this.a=n}function Km(n){this.a=n}function Fm(n){this.a=n}function _m(n){this.a=n}function Bm(n){this.c=n}function Hm(n){this.e=n}function Um(n){this.a=n}function Gm(n){this.a=n}function qm(n){this.a=n}function Xm(n){this.d=n}function zm(n){this.a=n}function Vm(n){this.a=n}function Wm(n){this.a=n}function Qm(n){this.e=n}function Jm(){this.a=0}function Ym(){$V(this)}function Zm(){IN(this)}function nv(){XQ(this)}function tv(){Rf(this)}function ev(){this.c=nBt}function iv(n,t){n.b+=t}function rv(n,t){t.Wb(n)}function cv(n){return n.a}function av(n){return n.a}function ov(n){return n.a}function uv(n){return n.a}function sv(n){return n.a}function hv(n){return n.e}function fv(){return null}function lv(){return null}function bv(){mj(),xJn()}function wv(n){n.b.Of(n.e)}function dv(n){n.b=new rT}function gv(n,t){n.b=t-n.b}function pv(n,t){n.a=t-n.a}function mv(n,t){n.push(t)}function vv(n,t){n.sort(t)}function kv(n,t){t.jd(n.a)}function yv(n,t){NLn(t,n)}function Mv(n,t,e){n.Yd(e,t)}function Tv(n,t){n.e=t,t.b=n}function jv(n){sB(),this.a=n}function Ev(n){sB(),this.a=n}function Sv(n){sB(),this.a=n}function Pv(n){ZW(),this.a=n}function Cv(n){EZ(),_at.le(n)}function Iv(){Iv=E,new Ym}function Ov(){vx.call(this)}function Av(){vx.call(this)}function Lv(){Ov.call(this)}function Nv(){Ov.call(this)}function $v(){Ov.call(this)}function Dv(){Ov.call(this)}function xv(){Ov.call(this)}function Rv(){Ov.call(this)}function Kv(){Ov.call(this)}function Fv(){Ov.call(this)}function _v(){Ov.call(this)}function Bv(){Ov.call(this)}function Hv(){Ov.call(this)}function Uv(){this.a=this}function Gv(){this.Bb|=256}function qv(){this.b=new hL}function Xv(n,t){n.length=t}function zv(n,t){kD(n.a,t)}function Vv(n,t){LOn(n.c,t)}function Wv(n,t){FV(n.b,t)}function Qv(n,t){bMn(n.a,t)}function Jv(n,t){Vdn(n.a,t)}function Yv(n,t){Msn(n.e,t)}function Zv(n){C$n(n.c,n.b)}function nk(n,t){n.kc().Nb(t)}function tk(n){this.a=Agn(n)}function ek(){this.a=new Ym}function ik(){this.a=new Ym}function rk(){this.a=new hS}function ck(){this.a=new Zm}function ak(){this.a=new Zm}function ok(){this.a=new Zm}function uk(){this.a=new kn}function sk(){this.a=new g7}function hk(){this.a=new lt}function fk(){this.a=new V0}function lk(){this.a=new NF}function bk(){this.a=new Zm}function wk(){this.a=new Zm}function dk(){this.a=new Zm}function gk(){this.a=new Zm}function pk(){this.d=new Zm}function mk(){this.a=new i4}function vk(){this.a=new ek}function kk(){this.a=new Ym}function yk(){this.b=new Ym}function Mk(){this.b=new Zm}function Tk(){this.e=new Zm}function jk(){this.a=new sl}function Ek(){this.d=new Zm}function Sk(){BZ.call(this)}function Pk(){BZ.call(this)}function Ck(){Zm.call(this)}function Ik(){Lv.call(this)}function Ok(){ck.call(this)}function Ak(){HF.call(this)}function Lk(){gk.call(this)}function Nk(){tv.call(this)}function $k(){Nk.call(this)}function Dk(){tv.call(this)}function xk(){Dk.call(this)}function Rk(){oy.call(this)}function Kk(){oy.call(this)}function Fk(){oy.call(this)}function _k(){hy.call(this)}function Bk(){ts.call(this)}function Hk(){ts.call(this)}function Uk(){lS.call(this)}function Gk(){wy.call(this)}function qk(){wy.call(this)}function Xk(){Ym.call(this)}function zk(){Ym.call(this)}function Vk(){Ym.call(this)}function Wk(){Kan.call(this)}function Qk(){ek.call(this)}function Jk(){Gv.call(this)}function Yk(){$D.call(this)}function Zk(){Ym.call(this)}function ny(){$D.call(this)}function ty(){Ym.call(this)}function ey(){Ym.call(this)}function iy(){ps.call(this)}function ry(){iy.call(this)}function cy(){ps.call(this)}function ay(){$f.call(this)}function oy(){this.a=new ek}function uy(){this.a=new Ym}function sy(){this.a=new Zm}function hy(){this.a=new Ym}function fy(){this.a=new lS}function ly(){this.j=new Zm}function by(){this.a=new zj}function wy(){this.a=new gs}function dy(){this.a=new Do}function gy(){gy=E,wat=new c}function py(){py=E,Mat=new ky}function my(){my=E,Tat=new vy}function vy(){ib.call(this,"")}function ky(){ib.call(this,"")}function yy(n){Arn.call(this,n)}function My(n){Arn.call(this,n)}function Ty(n){Ql.call(this,n)}function jy(n){HE.call(this,n)}function Ey(n){HE.call(this,n)}function Sy(n){jy.call(this,n)}function Py(n){jy.call(this,n)}function Cy(n){jy.call(this,n)}function Iy(n){c8.call(this,n)}function Oy(n){c8.call(this,n)}function Ay(n){K_.call(this,n)}function Ly(n){XE.call(this,n)}function Ny(n){WE.call(this,n)}function $y(n){WE.call(this,n)}function Dy(n){WE.call(this,n)}function xy(n){cOn.call(this,n)}function Ry(n){xy.call(this,n)}function Ky(n){Uz.call(this,n)}function Fy(n){Ky.call(this,n)}function _y(){Cb.call(this,{})}function By(){By=E,Vat=new T}function Hy(){Hy=E,Iat=new X$}function Uy(){Uy=E,Dat=new r}function Gy(){Gy=E,Fat=new p}function qy(){qy=E,Hat=new k}function Xy(n){UD(),this.a=n}function zy(n){Cun(),this.a=n}function Vy(n){rz(),this.f=n}function Wy(n){rz(),this.f=n}function Qy(n){aB(),this.a=n}function Jy(n){n.b=null,n.c=0}function Yy(n,t){n.e=t,yFn(n,t)}function Zy(n,t){n.a=t,WAn(n)}function nM(n,t,e){n.a[t.g]=e}function tM(n,t,e){nSn(e,n,t)}function eM(n,t){F_(t.i,n.n)}function iM(n,t){yln(n).Cd(t)}function rM(n,t){n.a.ec().Mc(t)}function cM(n,t){return n.g-t.g}function aM(n,t){return n*n/t}function oM(n){return tJ(n),n}function uM(n){return tJ(n),n}function sM(n){return tJ(n),n}function hM(n){return new Pb(n)}function fM(n){return new QW(n)}function lM(n){return tJ(n),n}function bM(n){return tJ(n),n}function wM(n){Ky.call(this,n)}function dM(n){Ky.call(this,n)}function gM(n){Ky.call(this,n)}function pM(n){Uz.call(this,n)}function mM(n){Ky.call(this,n)}function vM(n){Ky.call(this,n)}function kM(n){Ky.call(this,n)}function yM(n){Ky.call(this,n)}function MM(n){Ky.call(this,n)}function TM(n){Ky.call(this,n)}function jM(n){Ky.call(this,n)}function EM(n){Ky.call(this,n)}function SM(n){Ky.call(this,n)}function PM(n){Ky.call(this,n)}function CM(n){Ky.call(this,n)}function IM(n){tJ(n),this.a=n}function OM(n){return hln(n),n}function AM(n){zV(n,n.length)}function LM(n){return n.b==n.c}function NM(n){return!!n&&n.b}function $M(n){return!!n&&n.k}function DM(n){return!!n&&n.j}function xM(n,t,e){n.c.Ef(t,e)}function RM(n,t){n.be(t),t.ae(n)}function KM(n){sB(),this.a=WW(n)}function FM(){this.a=mK(WW(TZn))}function _M(){throw hv(new Kv)}function BM(){throw hv(new Kv)}function HM(){throw hv(new Kv)}function UM(){throw hv(new Kv)}function GM(){throw hv(new Kv)}function qM(){throw hv(new Kv)}function XM(){XM=E,EZ()}function zM(){$w.call(this,"")}function VM(){$w.call(this,"")}function WM(){$w.call(this,"")}function QM(){$w.call(this,"")}function JM(n){dM.call(this,n)}function YM(n){dM.call(this,n)}function ZM(n){vM.call(this,n)}function nT(n){qw.call(this,n)}function tT(n){nT.call(this,n)}function eT(n){gx.call(this,n)}function iT(n){Qx.call(this,n,0)}function rT(){L2.call(this,12,3)}function cT(n,t){return B0(n,t)}function aT(n,t){return Ltn(n,t)}function oT(n,t){return n.a-t.a}function uT(n,t){return n.a-t.a}function sT(n,t){return n.a-t.a}function hT(n,t){return t in n.a}function fT(n){return n.a?n.b:0}function lT(n){return n.a?n.b:0}function bT(n,t,e){t.Cd(n.a[e])}function wT(n,t,e){t.Pe(n.a[e])}function dT(n,t){n.b=new eN(t)}function gT(n,t){return n.b=t,n}function pT(n,t){return n.c=t,n}function mT(n,t){return n.f=t,n}function vT(n,t){return n.g=t,n}function kT(n,t){return n.a=t,n}function yT(n,t){return n.f=t,n}function MT(n,t){return n.k=t,n}function TT(n,t){return n.a=t,n}function jT(n,t){return n.e=t,n}function ET(n,t){return n.e=t,n}function ST(n,t){return n.f=t,n}function PT(n,t){n.b=!0,n.d=t}function CT(n,t){return n.b-t.b}function IT(n,t){return n.g-t.g}function OT(n,t){return n?0:t-1}function AT(n,t){return n?0:t-1}function LT(n,t){return n?t-1:0}function NT(n,t){return n.s-t.s}function $T(n,t){return t.rg(n)}function DT(n,t){return n.b=t,n}function xT(n,t){return n.a=t,n}function RT(n,t){return n.c=t,n}function KT(n,t){return n.d=t,n}function FT(n,t){return n.e=t,n}function _T(n,t){return n.f=t,n}function BT(n,t){return n.a=t,n}function HT(n,t){return n.b=t,n}function UT(n,t){return n.c=t,n}function GT(n,t){return n.c=t,n}function qT(n,t){return n.b=t,n}function XT(n,t){return n.d=t,n}function zT(n,t){return n.e=t,n}function VT(n,t){return n.f=t,n}function WT(n,t){return n.g=t,n}function QT(n,t){return n.a=t,n}function JT(n,t){return n.i=t,n}function YT(n,t){return n.j=t,n}function ZT(n,t){jIn(),o2(t,n)}function nj(n,t,e){az(n.a,t,e)}function tj(n){Y_.call(this,n)}function ej(n){dpn.call(this,n)}function ij(n){TY.call(this,n)}function rj(n){TY.call(this,n)}function cj(n){Drn.call(this,n)}function aj(n){HY.call(this,n)}function oj(n){HY.call(this,n)}function uj(){S$.call(this,"")}function sj(){this.a=0,this.b=0}function hj(){this.b=0,this.a=0}function fj(n,t){n.b=0,Ccn(n,t)}function lj(n,t){return n.k=t,n}function bj(n,t){return n.j=t,n}function wj(n,t){n.c=t,n.b=!0}function dj(){dj=E,rut=ePn()}function gj(){gj=E,xKt=AEn()}function pj(){pj=E,RKt=VPn()}function mj(){mj=E,NFt=aan()}function vj(){vj=E,y_t=LEn()}function kj(){kj=E,xBt=NEn()}function yj(){yj=E,RBt=qAn()}function Mj(n){return n.e&&n.e()}function Tj(n){return n.l|n.m<<22}function jj(n,t){return n.c._b(t)}function Ej(n,t){return Uwn(n.b,t)}function Sj(n){return n?n.d:null}function Pj(n){return n?n.g:null}function Cj(n){return n?n.i:null}function Ij(n){return vK(n),n.o}function Oj(n,t){return n.a+=t,n}function Aj(n,t){return n.a+=t,n}function Lj(n,t){return n.a+=t,n}function Nj(n,t){return n.a+=t,n}function $j(n,t){for(;n.Bd(t););}function Dj(n){this.a=new sS(n)}function xj(){throw hv(new Kv)}function Rj(){throw hv(new Kv)}function Kj(){throw hv(new Kv)}function Fj(){throw hv(new Kv)}function _j(){throw hv(new Kv)}function Bj(){throw hv(new Kv)}function Hj(n){this.a=new Hz(n)}function Uj(){this.a=new mKn(iIt)}function Gj(){this.b=new mKn(ZSt)}function qj(){this.a=new mKn(dOt)}function Xj(){this.b=new mKn(VAt)}function zj(){this.b=new mKn(VAt)}function Vj(n){this.a=0,this.b=n}function Wj(n){CQn(),uYn(this,n)}function Qj(n){return GQ(n),n.a}function Jj(n){return n.b!=n.d.c}function Yj(n,t){return n.d[t.p]}function Zj(n,t){return vFn(n,t)}function nE(n,t,e){n.splice(t,e)}function tE(n,t){for(;n.Re(t););}function eE(n){n.c?P_n(n):C_n(n)}function iE(){throw hv(new Kv)}function rE(){throw hv(new Kv)}function cE(){throw hv(new Kv)}function aE(){throw hv(new Kv)}function oE(){throw hv(new Kv)}function uE(){throw hv(new Kv)}function sE(){throw hv(new Kv)}function hE(){throw hv(new Kv)}function fE(){throw hv(new Kv)}function lE(){throw hv(new Kv)}function bE(){throw hv(new Bv)}function wE(){throw hv(new Bv)}function dE(n){this.a=new gE(n)}function gE(n){Zan(this,n,fOn())}function pE(n){return!n||FQ(n)}function mE(n){return-1!=dHt[n]}function vE(){0!=Uat&&(Uat=0),qat=-1}function kE(){null==hZn&&(hZn=[])}function yE(n,t){RD.call(this,n,t)}function ME(n,t){yE.call(this,n,t)}function TE(n,t){this.a=n,this.b=t}function jE(n,t){this.a=n,this.b=t}function EE(n,t){this.a=n,this.b=t}function SE(n,t){this.a=n,this.b=t}function PE(n,t){this.a=n,this.b=t}function CE(n,t){this.a=n,this.b=t}function IE(n,t){this.a=n,this.b=t}function OE(n,t){this.e=n,this.d=t}function AE(n,t){this.b=n,this.c=t}function LE(n,t){this.b=n,this.a=t}function NE(n,t){this.b=n,this.a=t}function $E(n,t){this.b=n,this.a=t}function DE(n,t){this.b=n,this.a=t}function xE(n,t){this.a=n,this.b=t}function RE(n,t){this.a=n,this.b=t}function KE(n,t){this.a=n,this.f=t}function FE(n,t){this.g=n,this.i=t}function _E(n,t){this.f=n,this.g=t}function BE(n,t){this.b=n,this.c=t}function HE(n){FD(n.dc()),this.c=n}function UE(n,t){this.a=n,this.b=t}function GE(n,t){this.a=n,this.b=t}function qE(n){this.a=uG(WW(n),15)}function XE(n){this.a=uG(WW(n),15)}function zE(n){this.a=uG(WW(n),85)}function VE(n){this.b=uG(WW(n),85)}function WE(n){this.b=uG(WW(n),51)}function QE(){this.q=new e.Date}function JE(n,t){this.a=n,this.b=t}function YE(n,t){return PV(n.b,t)}function ZE(n,t){return n.b.Hc(t)}function nS(n,t){return n.b.Ic(t)}function tS(n,t){return n.b.Qc(t)}function eS(n,t){return n.b.Hc(t)}function iS(n,t){return n.c.uc(t)}function rS(n,t){return udn(n.c,t)}function cS(n,t){return n.a._b(t)}function aS(n,t){return n>t&&t0}function $P(n,t){return dwn(n,t)<0}function DP(n,t){return RX(n.a,t)}function xP(n,t){U0.call(this,n,t)}function RP(n){nQ(),K_.call(this,n)}function KP(n,t){zX(n,n.length,t)}function FP(n,t){dW(n,n.length,t)}function _P(n,t){return n.a.get(t)}function BP(n,t){return PV(n.e,t)}function HP(n){return tJ(n),!1}function UP(n){this.a=uG(WW(n),229)}function GP(n){h3.call(this,n,21)}function qP(n,t){_E.call(this,n,t)}function XP(n,t){_E.call(this,n,t)}function zP(n,t){this.b=n,this.a=t}function VP(n,t){this.d=n,this.e=t}function WP(n,t){this.a=n,this.b=t}function QP(n,t){this.a=n,this.b=t}function JP(n,t){this.a=n,this.b=t}function YP(n,t){this.a=n,this.b=t}function ZP(n,t){this.a=n,this.b=t}function nC(n,t){this.b=n,this.a=t}function tC(n,t){this.b=n,this.a=t}function eC(n,t){_E.call(this,n,t)}function iC(n,t){_E.call(this,n,t)}function rC(n,t){_E.call(this,n,t)}function cC(n,t){_E.call(this,n,t)}function aC(n,t){_E.call(this,n,t)}function oC(n,t){_E.call(this,n,t)}function uC(n,t){_E.call(this,n,t)}function sC(n,t){this.b=n,this.a=t}function hC(n,t){_E.call(this,n,t)}function fC(n,t){this.b=n,this.a=t}function lC(n,t){_E.call(this,n,t)}function bC(n,t){this.b=n,this.a=t}function wC(n,t){_E.call(this,n,t)}function dC(n,t){_E.call(this,n,t)}function gC(n,t){_E.call(this,n,t)}function pC(n,t,e){n.splice(t,0,e)}function mC(n,t,e){n.Mb(e)&&t.Cd(e)}function vC(n,t,e){t.Pe(n.a.Ye(e))}function kC(n,t,e){t.Dd(n.a.Ze(e))}function yC(n,t,e){t.Cd(n.a.Kb(e))}function MC(n,t){return $x(n.c,t)}function TC(n,t){return $x(n.e,t)}function jC(n,t){_E.call(this,n,t)}function EC(n,t){_E.call(this,n,t)}function SC(n,t){_E.call(this,n,t)}function PC(n,t){_E.call(this,n,t)}function CC(n,t){_E.call(this,n,t)}function IC(n,t){_E.call(this,n,t)}function OC(n,t){this.a=n,this.b=t}function AC(n,t){this.a=n,this.b=t}function LC(n,t){this.a=n,this.b=t}function NC(n,t){this.a=n,this.b=t}function $C(n,t){this.a=n,this.b=t}function DC(n,t){this.a=n,this.b=t}function xC(n,t){this.b=n,this.a=t}function RC(n,t){this.b=n,this.a=t}function KC(n,t){this.b=n,this.a=t}function FC(n,t){this.c=n,this.d=t}function _C(n,t){this.e=n,this.d=t}function BC(n,t){this.a=n,this.b=t}function HC(n,t){this.a=n,this.b=t}function UC(n,t){this.a=n,this.b=t}function GC(n,t){this.b=n,this.a=t}function qC(n,t){this.b=t,this.c=n}function XC(n,t){_E.call(this,n,t)}function zC(n,t){_E.call(this,n,t)}function VC(n,t){_E.call(this,n,t)}function WC(n,t){_E.call(this,n,t)}function QC(n,t){_E.call(this,n,t)}function JC(n,t){_E.call(this,n,t)}function YC(n,t){_E.call(this,n,t)}function ZC(n,t){_E.call(this,n,t)}function nI(n,t){_E.call(this,n,t)}function tI(n,t){_E.call(this,n,t)}function eI(n,t){_E.call(this,n,t)}function iI(n,t){_E.call(this,n,t)}function rI(n,t){_E.call(this,n,t)}function cI(n,t){_E.call(this,n,t)}function aI(n,t){_E.call(this,n,t)}function oI(n,t){_E.call(this,n,t)}function uI(n,t){_E.call(this,n,t)}function sI(n,t){_E.call(this,n,t)}function hI(n,t){_E.call(this,n,t)}function fI(n,t){_E.call(this,n,t)}function lI(n,t){_E.call(this,n,t)}function bI(n,t){_E.call(this,n,t)}function wI(n,t){_E.call(this,n,t)}function dI(n,t){_E.call(this,n,t)}function gI(n,t){_E.call(this,n,t)}function pI(n,t){_E.call(this,n,t)}function mI(n,t){_E.call(this,n,t)}function vI(n,t){_E.call(this,n,t)}function kI(n,t){_E.call(this,n,t)}function yI(n,t){_E.call(this,n,t)}function MI(n,t){_E.call(this,n,t)}function TI(n,t){_E.call(this,n,t)}function jI(n,t){_E.call(this,n,t)}function EI(n,t){this.b=n,this.a=t}function SI(n,t){_E.call(this,n,t)}function PI(n,t){this.a=n,this.b=t}function CI(n,t){this.a=n,this.b=t}function II(n,t){this.a=n,this.b=t}function OI(n,t){_E.call(this,n,t)}function AI(n,t){_E.call(this,n,t)}function LI(n,t){this.a=n,this.b=t}function NI(n,t){return PU(),t!=n}function $I(n){return MK(n.a),n.b}function DI(n){return K$n(n,n.c),n}function xI(){return dj(),new rut}function RI(){UB(),this.a=new xF}function KI(){oFn(),this.a=new ek}function FI(){e2(),this.b=new ek}function _I(n,t){this.b=n,this.d=t}function BI(n,t){this.a=n,this.b=t}function HI(n,t){this.a=n,this.b=t}function UI(n,t){this.a=n,this.b=t}function GI(n,t){this.b=n,this.a=t}function qI(n,t){_E.call(this,n,t)}function XI(n,t){_E.call(this,n,t)}function zI(n,t){_E.call(this,n,t)}function VI(n,t){_E.call(this,n,t)}function WI(n,t){_E.call(this,n,t)}function QI(n,t){_E.call(this,n,t)}function JI(n,t){_E.call(this,n,t)}function YI(n,t){_E.call(this,n,t)}function ZI(n,t){_E.call(this,n,t)}function nO(n,t){_E.call(this,n,t)}function tO(n,t){_E.call(this,n,t)}function eO(n,t){_E.call(this,n,t)}function iO(n,t){_E.call(this,n,t)}function rO(n,t){_E.call(this,n,t)}function cO(n,t){_E.call(this,n,t)}function aO(n,t){_E.call(this,n,t)}function oO(n,t){_E.call(this,n,t)}function uO(n,t){_E.call(this,n,t)}function sO(n,t){_E.call(this,n,t)}function hO(n,t){_E.call(this,n,t)}function fO(n,t){_E.call(this,n,t)}function lO(n,t){_E.call(this,n,t)}function bO(n,t){_E.call(this,n,t)}function wO(n,t){_E.call(this,n,t)}function dO(n,t){this.b=n,this.a=t}function gO(n,t){this.b=n,this.a=t}function pO(n,t){this.b=n,this.a=t}function mO(n,t){this.b=n,this.a=t}function vO(n,t){this.a=n,this.b=t}function kO(n,t){this.a=n,this.b=t}function yO(n,t){this.a=n,this.b=t}function MO(n,t){this.a=n,this.b=t}function TO(n,t){_E.call(this,n,t)}function jO(n,t){_E.call(this,n,t)}function EO(n,t){_E.call(this,n,t)}function SO(n,t){_E.call(this,n,t)}function PO(n,t){_E.call(this,n,t)}function CO(n,t){_E.call(this,n,t)}function IO(n,t){_E.call(this,n,t)}function OO(n,t){_E.call(this,n,t)}function AO(n,t){_E.call(this,n,t)}function LO(n,t){_E.call(this,n,t)}function NO(n,t){_E.call(this,n,t)}function $O(n,t){_E.call(this,n,t)}function DO(n,t){_E.call(this,n,t)}function xO(n,t){_E.call(this,n,t)}function RO(n,t){_E.call(this,n,t)}function KO(n,t){_E.call(this,n,t)}function FO(n,t){_E.call(this,n,t)}function _O(n,t){_E.call(this,n,t)}function BO(n,t){_E.call(this,n,t)}function HO(n,t){_E.call(this,n,t)}function UO(n,t){this.a=n,this.b=t}function GO(n,t){this.a=n,this.b=t}function qO(n,t){this.a=n,this.b=t}function XO(n,t){this.a=n,this.b=t}function zO(n,t){this.a=n,this.b=t}function VO(n,t){this.a=n,this.b=t}function WO(n,t){this.a=n,this.b=t}function QO(n,t){this.a=n,this.b=t}function JO(n,t){this.a=n,this.b=t}function YO(n,t){this.a=n,this.b=t}function ZO(n,t){this.a=n,this.b=t}function nA(n,t){this.a=n,this.b=t}function tA(n,t){this.a=n,this.b=t}function eA(n,t){this.b=n,this.a=t}function iA(n,t){this.b=n,this.a=t}function rA(n,t){this.b=n,this.a=t}function cA(n,t){this.b=n,this.a=t}function aA(n,t){this.a=n,this.b=t}function oA(n,t){this.a=n,this.b=t}function uA(n,t){_E.call(this,n,t)}function sA(n,t){this.a=n,this.b=t}function hA(n,t){this.a=n,this.b=t}function fA(n,t){_E.call(this,n,t)}function lA(n,t){this.f=n,this.c=t}function bA(n,t){return $x(n.g,t)}function wA(n,t){return $x(t.b,n)}function dA(n,t){return ymn(n.a,t)}function gA(n,t){return-n.b.af(t)}function pA(n,t){n&&vJ(AFt,n,t)}function mA(n,t){n.i=null,lon(n,t)}function vA(n,t,e){MSn(t,jAn(n,e))}function kA(n,t,e){MSn(t,jAn(n,e))}function yA(n,t){BRn(n.a,uG(t,58))}function MA(n,t){aen(n.a,uG(t,12))}function TA(n,t){this.a=n,this.b=t}function jA(n,t){this.a=n,this.b=t}function EA(n,t){this.a=n,this.b=t}function SA(n,t){this.a=n,this.b=t}function PA(n,t){this.a=n,this.b=t}function CA(n,t){this.d=n,this.b=t}function IA(n,t){this.e=n,this.a=t}function OA(n,t){this.b=n,this.c=t}function AA(n,t){this.i=n,this.g=t}function LA(n,t){this.d=n,this.e=t}function NA(n,t){Iin(new DD(n),t)}function $A(n){return kmn(n.c,n.b)}function DA(n){return n?n.md():null}function xA(n){return null==n?null:n}function RA(n){return typeof n===pZn}function KA(n){return typeof n===dZn}function FA(n){return typeof n===gZn}function _A(n,t){return 0==dwn(n,t)}function BA(n,t){return dwn(n,t)>=0}function HA(n,t){return 0!=dwn(n,t)}function UA(n,t){return Zun(n.Kc(),t)}function GA(n,t){return n.Rd().Xb(t)}function qA(n){return bpn(n),n.d.gc()}function XA(n){return Fq(null==n),n}function zA(n,t){return n.a+=""+t,n}function VA(n,t){return n.a+=""+t,n}function WA(n,t){return n.a+=""+t,n}function QA(n,t){return n.a+=""+t,n}function JA(n,t){return n.a+=""+t,n}function YA(n,t){return n.a+=""+t,n}function ZA(n){return""+(tJ(n),n)}function nL(n){$V(this),xun(this,n)}function tL(){J0(),ez.call(this)}function eL(n,t){Bz.call(this,n,t)}function iL(n,t){Bz.call(this,n,t)}function rL(n,t){Bz.call(this,n,t)}function cL(n,t){s8(n,t,n.c.b,n.c)}function aL(n,t){s8(n,t,n.a,n.a.a)}function oL(n){return u3(n,0),null}function uL(){this.b=0,this.a=!1}function sL(){this.b=0,this.a=!1}function hL(){this.b=new sS(orn(12))}function fL(){fL=E,fht=Abn(Nkn())}function lL(){lL=E,_wt=Abn(bKn())}function bL(){bL=E,bPt=Abn(usn())}function wL(){wL=E,Iv(),Bat=new Ym}function dL(n){return n.a=0,n.b=0,n}function gL(n,t){return n.a=t.g+1,n}function pL(n,t){w_.call(this,n,t)}function mL(n,t){uF.call(this,n,t)}function vL(n,t){AA.call(this,n,t)}function kL(n,t){zx.call(this,n,t)}function yL(n,t){Zsn.call(this,n,t)}function ML(n,t){TP(),vJ(_Ft,n,t)}function TL(n,t){n.q.setTime(W4(t))}function jL(n){e.clearTimeout(n)}function EL(n){return WW(n),new iN(n)}function SL(n,t){return xA(n)===xA(t)}function PL(n,t){return n.a.a.a.cc(t)}function CL(n,t){return r1(n.a,0,t)}function IL(n){return jW(uG(n,74))}function OL(n){return t0((tJ(n),n))}function AL(n){return t0((tJ(n),n))}function LL(n){return p$(n.l,n.m,n.h)}function NL(n,t){return d$(n.a,t.a)}function $L(n,t){return rW(n.a,t.a)}function DL(n,t){return ugn(n.a,t.a)}function xL(n,t){return n.indexOf(t)}function RL(n,t){return 2==n.j[t.p]}function KL(n,t){return n==t?0:n?1:-1}function FL(n){return n<10?"0"+n:""+n}function _L(n){return typeof n===gZn}function BL(n){return n==Flt||n==Hlt}function HL(n){return n==Flt||n==_lt}function UL(n,t){return d$(n.g,t.g)}function GL(n){return Ten(n.b.b,n,0)}function qL(){lX.call(this,0,0,0,0)}function XL(){td.call(this,new u8)}function zL(n,t){Ntn(n,0,n.length,t)}function VL(n,t){return kD(n.a,t),t}function WL(n,t){return GB(),t.a+=n}function QL(n,t){return GB(),t.a+=n}function JL(n,t){return GB(),t.c+=n}function YL(n,t){return kD(n.c,t),n}function ZL(n,t){return gsn(n.a,t),n}function nN(n){this.a=xI(),this.b=n}function tN(n){this.a=xI(),this.b=n}function eN(n){this.a=n.a,this.b=n.b}function iN(n){this.a=n,Ff.call(this)}function rN(n){this.a=n,Ff.call(this)}function cN(){gY.call(this,0,0,0,0)}function aN(n){return gsn(new wJ,n)}function oN(n){return xJ(uG(n,123))}function uN(n){return n.vh()&&n.wh()}function sN(n){return n!=uRt&&n!=sRt}function hN(n){return n==JDt||n==YDt}function fN(n){return n==nxt||n==QDt}function lN(n){return n==wjt||n==bjt}function bN(n,t){return d$(n.g,t.g)}function wN(n,t){return new Zsn(t,n)}function dN(n,t){return new Zsn(t,n)}function gN(n){return nG(n.b.Kc(),n.a)}function pN(n,t){sbn(n,t),Ocn(n,n.D)}function mN(n,t,e){Scn(n,t),pcn(n,e)}function vN(n,t,e){kcn(n,t),vcn(n,e)}function kN(n,t,e){ycn(n,t),Mcn(n,e)}function yN(n,t,e){mcn(n,t),jcn(n,e)}function MN(n,t,e){Tcn(n,t),Ecn(n,e)}function TN(n,t,e){AK.call(this,n,t,e)}function jN(n){lA.call(this,n,!0)}function EN(){qP.call(this,"Tail",3)}function SN(){qP.call(this,"Head",1)}function PN(n){cHn(),Bun.call(this,n)}function CN(n){lX.call(this,n,n,n,n)}function IN(n){n.c=Inn(dat,EZn,1,0,5,1)}function ON(n){return n.b&&sXn(n),n.a}function AN(n){return n.b&&sXn(n),n.c}function LN(n,t){Nut||(n.b=t)}function NN(n,t){return n[n.length]=t}function $N(n,t){return n[n.length]=t}function DN(n,t){return Ern(t,h0(n))}function xN(n,t){return Ern(t,h0(n))}function RN(n,t){return kan(UW(n.d),t)}function KN(n,t){return kan(UW(n.g),t)}function FN(n,t){return kan(UW(n.j),t)}function _N(n,t){uF.call(this,n.b,t)}function BN(n,t){ttn(z5(n.a),v2(t))}function HN(n,t){ttn(Aen(n.a),k2(t))}function UN(n,t,e){kN(e,e.i+n,e.j+t)}function GN(n,t,e){uQ(n.c[t.g],t.g,e)}function qN(n,t,e){uG(n.c,71).Gi(t,e)}function XN(n,t,e){return uQ(n,t,e),e}function zN(n){Prn(n.Sf(),new Od(n))}function VN(n){return null!=n?Hon(n):0}function WN(n){return null==n?0:Hon(n)}function QN(n){QYn(),Qm.call(this,n)}function JN(n){this.a=n,WU.call(this,n)}function YN(){YN=E,e.Math.log(2)}function ZN(){ZN=E,kP(),rBt=WKt}function n$(){n$=E,vSt=new rpn(kxt)}function t$(){t$=E,new e$,new Zm}function e$(){new Ym,new Ym,new Ym}function i$(){throw hv(new TM(hat))}function r$(){throw hv(new TM(hat))}function c$(){throw hv(new TM(fat))}function a$(){throw hv(new TM(fat))}function o$(n){this.a=n,VE.call(this,n)}function u$(n){this.a=n,VE.call(this,n)}function s$(n,t){ZW(),this.a=n,this.b=t}function h$(n,t){WW(t),uY(n).Jc(new b)}function f$(n,t){UX(n.c,n.c.length,t)}function l$(n){return n.at?1:0}function g$(n,t){return dwn(n,t)>0?n:t}function p$(n,t,e){return{l:n,m:t,h:e}}function m$(n,t){null!=n.a&&MA(t,n.a)}function v$(n){c2(n,null),u2(n,null)}function k$(n,t,e){return vJ(n.g,e,t)}function y$(n,t,e){return avn(t,e,n.c)}function M$(n,t,e){return vJ(n.k,e,t)}function T$(n,t,e){return gWn(n,t,e),e}function j$(n,t){return n2(),t.n.b+=n}function E$(n){HZ.call(this),this.b=n}function S$(n){LF.call(this),this.a=n}function P$(){qP.call(this,"Range",2)}function C$(n){this.b=n,this.a=new Zm}function I$(n){this.b=new tt,this.a=n}function O$(n){n.a=new R,n.c=new R}function A$(n){n.a=new Ym,n.d=new Ym}function L$(n){s2(n,null),h2(n,null)}function N$(n,t){return kWn(n.a,t,null)}function $$(n,t){return vJ(n.a,t.a,t)}function D$(n){return new MO(n.a,n.b)}function x$(n){return new MO(n.c,n.d)}function R$(n){return new MO(n.c,n.d)}function K$(n,t){return rVn(n.c,n.b,t)}function F$(n,t){return null!=n&&Eyn(n,t)}function _$(n,t){return-1!=Yhn(n.Kc(),t)}function B$(n){return n.Ob()?n.Pb():null}function H$(n){this.b=(hZ(),new Vw(n))}function U$(n){this.a=n,Ym.call(this)}function G$(){zx.call(this,null,null)}function q$(){Vx.call(this,null,null)}function X$(){_E.call(this,"INSTANCE",0)}function z$(){FEn(),this.a=new mKn(Llt)}function V$(n){return mvn(n,0,n.length)}function W$(n,t){return new ex(n.Kc(),t)}function Q$(n,t){return null!=n.a.Bc(t)}function J$(n,t){Czn(n),n.Gc(uG(t,15))}function Y$(n,t,e){n.c.bd(t,uG(e,136))}function Z$(n,t,e){n.c.Ui(t,uG(e,136))}function nD(n,t){n.c&&(cq(t),B1(t))}function tD(n,t){n.q.setHours(t),Iqn(n,t)}function eD(n,t){KR(t,n.a.a.a,n.a.a.b)}function iD(n,t,e,i){uQ(n.a[t.g],e.g,i)}function rD(n,t,e){return n.a[t.g][e.g]}function cD(n,t){return n.e[t.c.p][t.p]}function aD(n,t){return n.c[t.c.p][t.p]}function oD(n,t){return n.a[t.c.p][t.p]}function uD(n,t){return n.j[t.p]=oRn(t)}function sD(n,t){return null!=n.a.Bc(t)}function hD(n,t){return uM(pK(t.a))<=n}function fD(n,t){return uM(pK(t.a))>=n}function lD(n,t){return r7(n.f,t.Pg())}function bD(n,t){return n.a*t.a+n.b*t.b}function wD(n,t){return n.a0?t/(n*n):100*t}function jR(n,t){return n>0?t*t/n:t*t*100}function ER(n,t){return uG(ain(n.a,t),34)}function SR(n,t){return jIn(),UNn(n,t.e,t)}function PR(n,t,e){return ZS(),e.Mg(n,t)}function CR(n){return tcn(),n.e.a+n.f.a/2}function IR(n,t,e){return tcn(),e.e.a-n*t}function OR(n){return tcn(),n.e.b+n.f.b/2}function AR(n,t,e){return tcn(),e.e.b-n*t}function LR(n){n.d=new bR(n),n.e=new Ym}function NR(){this.a=new K1,this.b=new K1}function $R(n){this.c=n,this.a=1,this.b=1}function DR(n){aYn(),dv(this),this.Ff(n)}function xR(n,t,e){Stn(),n.pf(t)&&e.Cd(n)}function RR(n,t,e){return kD(t,xpn(n,e))}function KR(n,t,e){return n.a+=t,n.b+=e,n}function FR(n,t,e){return n.a*=t,n.b*=e,n}function _R(n,t){return n.a=t.a,n.b=t.b,n}function BR(n){return n.a=-n.a,n.b=-n.b,n}function HR(n,t,e){return n.a-=t,n.b-=e,n}function UR(n){lS.call(this),dan(this,n)}function GR(){_E.call(this,"GROW_TREE",0)}function qR(){_E.call(this,"POLYOMINO",0)}function XR(n,t,e){ltn.call(this,n,t,e,2)}function zR(n,t,e){$dn(z5(n.a),t,v2(e))}function VR(n,t){jP(),zx.call(this,n,t)}function WR(n,t){EP(),Vx.call(this,n,t)}function QR(n,t){EP(),WR.call(this,n,t)}function JR(n,t){EP(),Vx.call(this,n,t)}function YR(n,t){return n.c.Fc(uG(t,136))}function ZR(n,t,e){$dn(Aen(n.a),t,k2(e))}function nK(n){this.c=n,ycn(n,0),Mcn(n,0)}function tK(n,t){ZN(),OX.call(this,n,t)}function eK(n,t){ZN(),tK.call(this,n,t)}function iK(n,t){ZN(),tK.call(this,n,t)}function rK(n,t){ZN(),OX.call(this,n,t)}function cK(n,t){ZN(),iK.call(this,n,t)}function aK(n,t){ZN(),rK.call(this,n,t)}function oK(n,t){ZN(),OX.call(this,n,t)}function uK(n,t,e){return t.zl(n.e,n.c,e)}function sK(n,t,e){return t.Al(n.e,n.c,e)}function hK(n,t,e){return JXn(Len(n,t),e)}function fK(n,t){return mwn(n.e,uG(t,54))}function lK(n){return null==n?null:AQn(n)}function bK(n){return null==n?null:mOn(n)}function wK(n){return null==n?null:cpn(n)}function dK(n){return null==n?null:cpn(n)}function gK(n){return Fq(null==n||KA(n)),n}function pK(n){return Fq(null==n||FA(n)),n}function mK(n){return Fq(null==n||RA(n)),n}function vK(n){null==n.o&&axn(n)}function kK(n){if(!n)throw hv(new Dv)}function yK(n){if(!n)throw hv(new Nv)}function MK(n){if(!n)throw hv(new Bv)}function TK(n){if(!n)throw hv(new xv)}function jK(n){if(!n)throw hv(new Fv)}function EK(){EK=E,KFt=new Gk,new qk}function SK(){SK=E,zCt=new Cm("root")}function PK(){Kan.call(this),this.Bb|=P0n}function CK(n,t){this.d=n,Cw(this),this.b=t}function IK(n,t){Fnn.call(this,n),this.a=t}function OK(n,t){Fnn.call(this,n),this.a=t}function AK(n,t,e){A7.call(this,n,t,e,null)}function LK(n,t,e){A7.call(this,n,t,e,null)}function NK(n,t){this.c=n,OE.call(this,n,t)}function $K(n,t){this.a=n,NK.call(this,n,t)}function DK(n){this.q=new e.Date(W4(n))}function xK(n){return n>8?0:n+1}function RK(n,t){Nut||kD(n.a,t)}function KK(n,t){return WS(),jsn(t.d.i,n)}function FK(n,t){return Pun(),new oHn(t,n)}function _K(n,t,e){return n.Ne(t,e)<=0?e:t}function BK(n,t,e){return n.Ne(t,e)<=0?t:e}function HK(n,t){return uG(ain(n.b,t),143)}function UK(n,t){return uG(ain(n.c,t),233)}function GK(n){return uG(zq(n.a,n.b),294)}function qK(n){return new MO(n.c,n.d+n.a)}function XK(n){return tJ(n),n?1231:1237}function zK(n){return n2(),lN(uG(n,203))}function VK(){VK=E,lht=ggn((Qmn(),JRt))}function WK(n,t){t.a?W$n(n,t):sD(n.a,t.b)}function QK(n,t,e){++n.j,n.tj(),Ann(n,t,e)}function JK(n,t,e){++n.j,n.qj(t,n.Zi(t,e))}function YK(n,t,e){n.fd(t).Rb(e)}function ZK(n,t,e){return e=DUn(n,t,6,e)}function nF(n,t,e){return e=DUn(n,t,3,e)}function tF(n,t,e){return e=DUn(n,t,9,e)}function eF(n,t){return ZZ(t,W2n),n.f=t,n}function iF(n,t){return(t&vZn)%n.d.length}function rF(n,t,e){return fXn(n.c,n.b,t,e)}function cF(n,t){this.c=n,Drn.call(this,t)}function aF(n,t){this.a=n,xm.call(this,t)}function oF(n,t){this.a=n,xm.call(this,t)}function uF(n,t){Cm.call(this,n),this.a=t}function sF(n,t){Bm.call(this,n),this.a=t}function hF(n,t){Bm.call(this,n),this.a=t}function fF(n){smn.call(this,0,0),this.f=n}function lF(n,t,e){return n.a+=mvn(t,0,e),n}function bF(n){return!n.a&&(n.a=new M),n.a}function wF(n,t){var e;return e=n.e,n.e=t,e}function dF(n,t){var e;return e=t,!!n.Fe(e)}function gF(n,t){return qx(),n==t?0:n?1:-1}function pF(n,t){n.a.bd(n.b,t),++n.b,n.c=-1}function mF(n){n.b?mF(n.b):n.f.c.zc(n.e,n.d)}function vF(n){$V(n.e),n.d.b=n.d,n.d.a=n.d}function kF(n,t,e){vS(),Ob(n,t.Ve(n.a,e))}function yF(n,t,e){return UV(n,uG(t,22),e)}function MF(n,t){return aT(new Array(t),n)}function TF(n){return pz(Dz(n,32))^pz(n)}function jF(n){return String.fromCharCode(n)}function EF(n){return null==n?null:n.message}function SF(n,t,e){return n.apply(t,e)}function PF(n,t){n[U0n].call(n,t)}function CF(n,t){n[U0n].call(n,t)}function IF(n,t){return WS(),!jsn(t.d.i,n)}function OF(n,t,e,i){lX.call(this,n,t,e,i)}function AF(){HF.call(this),this.a=new sj}function LF(){this.n=new sj,this.o=new sj}function NF(){this.b=new sj,this.c=new Zm}function $F(){this.a=new Zm,this.b=new Zm}function DF(){this.a=new lt,this.b=new qv}function xF(){this.b=new u8,this.a=new u8}function RF(){this.b=new ek,this.a=new ek}function KF(){this.b=new Ym,this.a=new Ym}function FF(){this.b=new Gj,this.a=new Ma}function _F(){this.a=new hl,this.b=new oc}function BF(){this.a=new Zm,this.d=new Zm}function HF(){this.n=new Dk,this.i=new cN}function UF(n){this.a=(man(n,g1n),new R7(n))}function GF(n){this.a=(man(n,g1n),new R7(n))}function qF(n){return n<100?null:new cj(n)}function XF(n,t){return n.n.a=(tJ(t),t+10)}function zF(n,t){return n.n.a=(tJ(t),t+10)}function VF(n,t){return t==n||sSn(mRn(t),n)}function WF(n,t){return null==vJ(n.a,t,"")}function QF(n,t){return t.qi(n.a)}function JF(n,t){return n.a+=t.a,n.b+=t.b,n}function YF(n,t){return n.a-=t.a,n.b-=t.b,n}function ZF(n){return Xv(n.j.c,0),n.a=-1,n}function n_(n,t,e){return e=DUn(n,t,11,e)}function t_(n,t,e){null!=e&&Xan(t,gTn(n,e))}function e_(n,t,e){null!=e&&zan(t,gTn(n,e))}function i_(n,t,e,i){fV.call(this,n,t,e,i)}function r_(n,t,e,i){fV.call(this,n,t,e,i)}function c_(n,t,e,i){r_.call(this,n,t,e,i)}function a_(n,t,e,i){wV.call(this,n,t,e,i)}function o_(n,t,e,i){wV.call(this,n,t,e,i)}function u_(n,t,e,i){wV.call(this,n,t,e,i)}function s_(n,t,e,i){o_.call(this,n,t,e,i)}function h_(n,t,e,i){o_.call(this,n,t,e,i)}function f_(n,t,e,i){u_.call(this,n,t,e,i)}function l_(n,t,e,i){h_.call(this,n,t,e,i)}function b_(n,t,e,i){kV.call(this,n,t,e,i)}function w_(n,t){dM.call(this,Hit+n+Vet+t)}function d_(n,t){return n.jk().wi().ri(n,t)}function g_(n,t){return n.jk().wi().ti(n,t)}function p_(n,t){return tJ(n),xA(n)===xA(t)}function m_(n,t){return tJ(n),xA(n)===xA(t)}function v_(n,t){return n.b.Bd(new QP(n,t))}function k_(n,t){return n.b.Bd(new JP(n,t))}function y_(n,t){return n.b.Bd(new YP(n,t))}function M_(n,t){return n.e=uG(n.d.Kb(t),159)}function T_(n,t,e){return n.lastIndexOf(t,e)}function j_(n,t,e){return ugn(n[t.a],n[e.a])}function E_(n,t){return kfn(t,(jYn(),Oyt),n)}function S_(n,t){return d$(t.a.d.p,n.a.d.p)}function P_(n,t){return d$(n.a.d.p,t.a.d.p)}function C_(n,t){return ugn(n.c-n.s,t.c-t.s)}function I_(n,t){return ugn(n.b.e.a,t.b.e.a)}function O_(n,t){return ugn(n.c.e.a,t.c.e.a)}function A_(n){return n.c?Ten(n.c.a,n,0):-1}function L_(n){return n==rRt||n==aRt||n==cRt}function N_(n,t){this.c=n,QV.call(this,n,t)}function $_(n,t,e){this.a=n,Qx.call(this,t,e)}function D_(n){this.c=n,rL.call(this,YZn,0)}function x_(n,t,e){this.c=t,this.b=e,this.a=n}function R_(n){PU(),this.d=n,this.a=new ND}function K_(n){sB(),this.a=(hZ(),new nT(n))}function F_(n,t){hN(n.f)?JDn(n,t):wCn(n,t)}function __(n,t){sG.call(this,n,n.length,t)}function B_(n,t){Nut||t&&(n.d=t)}function H_(n,t){return F$(t,15)&&G_n(n.c,t)}function U_(n,t,e){return uG(n.c,71).Wk(t,e)}function G_(n,t,e){return uG(n.c,71).Xk(t,e)}function q_(n,t,e){return uK(n,uG(t,343),e)}function X_(n,t,e){return sK(n,uG(t,343),e)}function z_(n,t,e){return yPn(n,uG(t,343),e)}function V_(n,t,e){return FCn(n,uG(t,343),e)}function W_(n,t){return null==t?null:Xwn(n.b,t)}function Q_(n){return FA(n)?(tJ(n),n):n.ue()}function J_(n){return!isNaN(n)&&!isFinite(n)}function Y_(n){O$(this),BY(this),Qon(this,n)}function Z_(n){IN(this),dG(this.c,0,n.Pc())}function nB(n,t,e){this.a=n,this.b=t,this.c=e}function tB(n,t,e){this.a=n,this.b=t,this.c=e}function eB(n,t,e){this.d=n,this.b=e,this.a=t}function iB(n){this.a=n,bS(),Bsn(Date.now())}function rB(n){LQ(n.a),Lnn(n.c,n.b),n.b=null}function cB(){cB=E,out=new K,uut=new F}function aB(){aB=E,DFt=Inn(dat,EZn,1,0,5,1)}function oB(){oB=E,X_t=Inn(dat,EZn,1,0,5,1)}function uB(){uB=E,z_t=Inn(dat,EZn,1,0,5,1)}function sB(){sB=E,new jv((hZ(),hZ(),zot))}function hB(n){return Rtn(),Fcn((xtn(),Mut),n)}function fB(n){return ybn(),Fcn((bnn(),xut),n)}function lB(n){return _kn(),Fcn((k8(),Jut),n)}function bB(n){return Xin(),Fcn((y8(),tst),n)}function wB(n){return W_n(),Fcn((uhn(),kst),n)}function dB(n){return Yrn(),Fcn((fnn(),Cst),n)}function gB(n){return Ktn(),Fcn((hnn(),Dst),n)}function pB(n){return Yen(),Fcn((lnn(),Bst),n)}function mB(n){return JYn(),Fcn((fL(),fht),n)}function vB(n){return ehn(),Fcn((_tn(),vht),n)}function kB(n){return vyn(),Fcn((Htn(),Eht),n)}function yB(n){return myn(),Fcn((Btn(),Rht),n)}function MB(n){return BS(),Fcn((r6(),_ht),n)}function TB(n){return zin(),Fcn((M8(),vft),n)}function jB(n){return Jen(),Fcn((wnn(),vlt),n)}function EB(n){return uIn(),Fcn(($in(),Ilt),n)}function SB(n){return Xhn(),Fcn((Gtn(),Glt),n)}function PB(n){return Uvn(),Fcn((Utn(),ibt),n)}function CB(n,t){if(!n)throw hv(new vM(t))}function IB(n){if(!n)throw hv(new kM(PZn))}function OB(n,t){if(n!=t)throw hv(new Fv)}function AB(n,t,e){this.a=n,this.b=t,this.c=e}function LB(n,t,e){this.a=n,this.b=t,this.c=e}function NB(n,t,e){this.a=n,this.b=t,this.c=e}function $B(n,t,e){this.b=n,this.a=t,this.c=e}function DB(n,t,e){this.b=n,this.c=t,this.a=e}function xB(n,t,e){this.a=n,this.b=t,this.c=e}function RB(n,t,e){this.e=t,this.b=n,this.d=e}function KB(n,t,e){this.b=n,this.a=t,this.c=e}function FB(n,t,e){return vS(),n.a.Yd(t,e),t}function _B(n){var t;return(t=new yn).e=n,t}function BB(n){var t;return(t=new pk).b=n,t}function HB(){HB=E,Nbt=new $e,$bt=new De}function UB(){UB=E,Jwt=new ui,Qwt=new si}function GB(){GB=E,rdt=new mr,cdt=new vr}function qB(n){return gon(),Fcn((q7(),Cdt),n)}function XB(n){return zYn(),Fcn((lL(),_wt),n)}function zB(n){return Ghn(),Fcn((Xtn(),Wwt),n)}function VB(n){return qhn(),Fcn((qtn(),ldt),n)}function WB(n){return gPn(),Fcn((Din(),vdt),n)}function QB(n){return h_n(),Fcn((osn(),Kdt),n)}function JB(n){return vAn(),Fcn((ecn(),zdt),n)}function YB(n){return H7(),Fcn((I8(),Jdt),n)}function ZB(n){return jan(),Fcn((U7(),egt),n)}function nH(n){return ran(),Fcn((G7(),ogt),n)}function tH(n){return kvn(),Fcn((xin(),wgt),n)}function eH(n){return Vin(),Fcn((E8(),mgt),n)}function iH(n){return RIn(),Fcn((ccn(),Jgt),n)}function rH(n){return r_n(),Fcn((Efn(),spt),n)}function cH(n){return ihn(),Fcn((z7(),wpt),n)}function aH(n){return Zen(),Fcn((V7(),vpt),n)}function oH(n){return Y6(),Fcn((j8(),Tpt),n)}function uH(n){return ESn(),Fcn((rcn(),Ugt),n)}function sH(n){return Pfn(),Fcn((X7(),Tgt),n)}function hH(n){return tOn(),Fcn((icn(),Agt),n)}function fH(n){return Wtn(),Fcn((S8(),Dgt),n)}function lH(n){return Gpn(),Fcn((Kin(),$mt),n)}function bH(n){return MKn(),Fcn((chn(),ojt),n)}function wH(n){return Cwn(),Fcn((W7(),ljt),n)}function dH(n){return Yyn(),Fcn((ztn(),mjt),n)}function gH(n){return pyn(),Fcn((Rin(),Ejt),n)}function pH(n){return THn(),Fcn((Sfn(),Rjt),n)}function mH(n){return yvn(),Fcn((Vtn(),Ujt),n)}function vH(n){return nin(),Fcn((P8(),zjt),n)}function kH(n){return can(),Fcn((Y7(),Yjt),n)}function yH(n){return isn(),Fcn((Q7(),iEt),n)}function MH(n){return Sln(),Fcn((J7(),uEt),n)}function TH(n){return kbn(),Fcn((Z7(),bEt),n)}function jH(n){return ian(),Fcn((nnn(),mEt),n)}function EH(n){return zhn(),Fcn((tnn(),TEt),n)}function SH(n){return ean(),Fcn((snn(),GEt),n)}function PH(n){return Z6(),Fcn((C8(),nSt),n)}function CH(n){return b0(),Fcn((L8(),bSt),n)}function IH(n){return w0(),Fcn((N8(),pSt),n)}function OH(n){return _7(),Fcn(($8(),RSt),n)}function AH(n){return l0(),Fcn((D8(),XSt),n)}function LH(n){return Cjn(),Fcn((sen(),YSt),n)}function NH(n){return OHn(),Fcn((bL(),bPt),n)}function $H(n){return Pln(),Fcn((enn(),mPt),n)}function DH(n){return mbn(),Fcn((uen(),KCt),n)}function xH(n){return i3(),Fcn((O8(),HCt),n)}function RH(n){return pon(),Fcn((A8(),JCt),n)}function KH(n){return zPn(),Fcn((Fin(),rIt),n)}function FH(n){return vbn(),Fcn((inn(),bIt),n)}function _H(n){return Ptn(),Fcn((x8(),uIt),n)}function BH(n){return dTn(),Fcn((oen(),tOt),n)}function HH(n){return esn(),Fcn((rnn(),aOt),n)}function UH(n){return Jmn(),Fcn((cnn(),fOt),n)}function GH(n){return Zyn(),Fcn((ann(),gOt),n)}function qH(n){return Bgn(),Fcn((onn(),LOt),n)}function XH(n){return a9(),Fcn((R8(),jAt),n)}function zH(n){return Aun(),Fcn((T8(),Lbt),n)}function VH(n){return zIn(),Fcn((acn(),mbt),n)}function WH(n){return den(),Fcn((unn(),IAt),n)}function QH(n){return rhn(),Fcn((K8(),NAt),n)}function JH(n){return _Rn(),Fcn((_in(),BAt),n)}function YH(n){return nP(),Fcn(($6(),WAt),n)}function ZH(n){return Rdn(),Fcn((gnn(),XAt),n)}function nU(n){return tP(),Fcn((D6(),YAt),n)}function tU(n){return B7(),Fcn((F8(),eLt),n)}function eU(n){return pOn(),Fcn((Bin(),sLt),n)}function iU(n){return eP(),Fcn((x6(),XLt),n)}function rU(n){return Vhn(),Fcn((_8(),QLt),n)}function cU(n){return Rkn(),Fcn((Uin(),bNt),n)}function aU(n){return lAn(),Fcn((csn(),TNt),n)}function oU(n){return nMn(),Fcn((ocn(),DNt),n)}function uU(n){return ZSn(),Fcn((ucn(),t$t),n)}function sU(n){return xdn(),Fcn((Hin(),ext),n)}function hU(n){return Zrn(),Fcn((pnn(),oxt),n)}function fU(n){return _gn(),Fcn((hen(),bxt),n)}function lU(n){return RCn(),Fcn((scn(),yxt),n)}function bU(n){return Own(),Fcn((dnn(),Nxt),n)}function wU(n){return Ajn(),Fcn((fen(),Fxt),n)}function dU(n){return VDn(),Fcn((ohn(),Qxt),n)}function gU(n){return Vkn(),Fcn((Gin(),iRt),n)}function pU(n){return $Pn(),Fcn((hcn(),fRt),n)}function mU(n){return eNn(),Fcn((fcn(),vRt),n)}function vU(n){return KQn(),Fcn((qin(),HRt),n)}function kU(n){return Qmn(),Fcn((len(),ZRt),n)}function yU(n){return oUn(),Fcn((ahn(),hKt),n)}function MU(n){return Iwn(),Fcn((mnn(),dKt),n)}function TU(n,t){return tJ(n),n+(tJ(t),t)}function jU(n){return CU(),Fcn((B8(),vKt),n)}function EU(n){return qpn(),Fcn((ben(),EKt),n)}function SU(n){return Eln(),Fcn((wen(),LKt),n)}function PU(){PU=E,KQn(),zEt=_Rt,VEt=kRt}function CU(){CU=E,gKt=new Pq,pKt=new gV}function IU(n){return!n.e&&(n.e=new Zm),n.e}function OU(n,t){this.c=n,this.a=t,this.b=t-n}function AU(n,t,e){this.a=n,this.b=t,this.c=e}function LU(n,t,e){this.a=n,this.b=t,this.c=e}function NU(n,t,e){this.a=n,this.b=t,this.c=e}function $U(n,t,e){this.a=n,this.b=t,this.c=e}function DU(n,t,e){this.a=n,this.b=t,this.c=e}function xU(n,t,e){this.a=n,this.b=t,this.c=e}function RU(n,t,e){this.e=n,this.a=t,this.c=e}function KU(n,t,e){ZN(),_1.call(this,n,t,e)}function FU(n,t,e){ZN(),CQ.call(this,n,t,e)}function _U(n,t,e){ZN(),CQ.call(this,n,t,e)}function BU(n,t,e){ZN(),CQ.call(this,n,t,e)}function HU(n,t,e){ZN(),FU.call(this,n,t,e)}function UU(n,t,e){ZN(),FU.call(this,n,t,e)}function GU(n,t,e){ZN(),UU.call(this,n,t,e)}function qU(n,t,e){ZN(),_U.call(this,n,t,e)}function XU(n,t,e){ZN(),BU.call(this,n,t,e)}function zU(n){lX.call(this,n.d,n.c,n.a,n.b)}function VU(n){lX.call(this,n.d,n.c,n.a,n.b)}function WU(n){this.d=n,Cw(this),this.b=Ez(n.d)}function QU(n){return rDn(),Fcn((asn(),SFt),n)}function JU(n,t){return WW(n),WW(t),new jE(n,t)}function YU(n,t){return WW(n),WW(t),new WG(n,t)}function ZU(n,t){return WW(n),WW(t),new QG(n,t)}function nG(n,t){return WW(n),WW(t),new DE(n,t)}function tG(n){return MK(0!=n.b),Lrn(n,n.a.a)}function eG(n){return MK(0!=n.b),Lrn(n,n.c.b)}function iG(n){return!n.c&&(n.c=new Ks),n.c}function rG(n){var t;return cin(t=new Zm,n),t}function cG(n){var t;return cin(t=new ek,n),t}function aG(n){var t;return Fon(t=new rk,n),t}function oG(n){var t;return Fon(t=new lS,n),t}function uG(n,t){return Fq(null==n||Eyn(n,t)),n}function sG(n,t,e){_z.call(this,t,e),this.a=n}function hG(n,t){this.c=n,this.b=t,this.a=!1}function fG(){this.a=";,;",this.b="",this.c=""}function lG(n,t,e){this.b=n,eL.call(this,t,e)}function bG(n,t,e){this.c=n,VP.call(this,t,e)}function wG(n,t,e){FC.call(this,n,t),this.b=e}function dG(n,t,e){b$n(e,0,n,t,e.length,!1)}function gG(n,t,e,i,r){n.b=t,n.c=e,n.d=i,n.a=r}function pG(n,t,e,i,r){n.d=t,n.c=e,n.a=i,n.b=r}function mG(n,t){t&&(n.b=t,n.a=(GQ(t),t.a))}function vG(n,t){if(!n)throw hv(new vM(t))}function kG(n,t){if(!n)throw hv(new kM(t))}function yG(n,t){if(!n)throw hv(new gM(t))}function MG(n,t){return YS(),d$(n.d.p,t.d.p)}function TG(n,t){return tcn(),ugn(n.e.b,t.e.b)}function jG(n,t){return tcn(),ugn(n.e.a,t.e.a)}function EG(n,t){return d$(wq(n.d),wq(t.d))}function SG(n,t){return t&&$Q(n,t.d)?t:null}function PG(n,t){return t==(KQn(),_Rt)?n.c:n.d}function CG(n){return Esn(LV(_L(n)?Gsn(n):n))}function IG(n){return new MO(n.c+n.b,n.d+n.a)}function OG(n){return null!=n&&!mpn(n,n_t,t_t)}function AG(n,t){return(ldn(n)<<4|ldn(t))&D1n}function LG(n,t,e,i,r){n.c=t,n.d=e,n.b=i,n.a=r}function NG(n){var t,e;t=n.b,e=n.c,n.b=e,n.c=t}function $G(n){var t,e;e=n.d,t=n.a,n.d=t,n.a=e}function DG(n,t){var e;return e=n.c,Jan(n,t),e}function xG(n,t){return n.g=t<0?-1:t,n}function RG(n,t){return Brn(n),n.a*=t,n.b*=t,n}function KG(n,t,e){Orn.call(this,t,e),this.d=n}function FG(n,t,e){LA.call(this,n,t),this.c=e}function _G(n,t,e){LA.call(this,n,t),this.c=e}function BG(n){uB(),ps.call(this),this.ci(n)}function HG(){N7(),OQ.call(this,(MP(),l_t))}function UG(n){return QYn(),new IX(0,n)}function GG(){GG=E,hZ(),CBt=new Xw(bct)}function qG(){qG=E,new Gyn((my(),Tat),(py(),Mat))}function XG(){XG=E,bot=Inn(dot,zZn,17,256,0,1)}function zG(){this.b=uM(pK(Jkn((cGn(),Bft))))}function VG(n){this.b=n,this.a=Mz(this.b.a).Od()}function WG(n,t){this.b=n,this.a=t,Ff.call(this)}function QG(n,t){this.a=n,this.b=t,Ff.call(this)}function JG(n,t,e){this.a=n,vL.call(this,t,e)}function YG(n,t,e){this.a=n,vL.call(this,t,e)}function ZG(n,t,e){nrn(n,t,new QW(e))}function nq(n,t,e){var i;return i=n[t],n[t]=e,i}function tq(n){return Ltn(n.slice(),n)}function eq(n){var t;return t=n.n,n.a.b+t.d+t.a}function iq(n){var t;return t=n.n,n.e.b+t.d+t.a}function rq(n){var t;return t=n.n,n.e.a+t.b+t.c}function cq(n){n.a.b=n.b,n.b.a=n.a,n.a=n.b=null}function aq(n,t){return s8(n,t,n.c.b,n.c),!0}function oq(n){return n.a?n.a:sY(n)}function uq(n){return lZ(),bIn(n)==R0(gIn(n))}function sq(n){return lZ(),gIn(n)==R0(bIn(n))}function hq(n,t){return CEn(n,new FC(t.a,t.b))}function fq(n,t){return TJ(),IMn(n,t),new bJ(n,t)}function lq(n,t){return n.c=t)throw hv(new Ik)}function Wz(n,t){return cdn(n,(tJ(t),new ud(t)))}function Qz(n,t){return cdn(n,(tJ(t),new sd(t)))}function Jz(n,t,e){return BYn(n,uG(t,12),uG(e,12))}function Yz(n){return Lun(),0!=uG(n,12).g.c.length}function Zz(n){return Lun(),0!=uG(n,12).e.c.length}function nV(n,t){return Pun(),ugn(t.a.o.a,n.a.o.a)}function tV(n,t){t.Bb&Qtt&&!n.a.o&&(n.a.o=t)}function eV(n,t){t.Ug("General 'Rotator",1),lQn(n)}function iV(n,t,e){t.qf(e,uM(pK(cQ(n.b,e)))*n.a)}function rV(n,t,e){return l_n(),qun(n,t)&&qun(n,e)}function cV(n){return eNn(),!n.Hc(wRt)&&!n.Hc(gRt)}function aV(n){return n.e?T7(n.e):null}function oV(n){return _L(n)?""+n:K_n(n)}function uV(n){var t;for(t=n;t.f;)t=t.f;return t}function sV(n,t,e){return uQ(t,0,nX(t[0],e[0])),t}function hV(n,t,e,i){var r;(r=n.i).i=t,r.a=e,r.b=i}function fV(n,t,e,i){MD.call(this,n,t,e),this.b=i}function lV(n,t,e,i,r){btn.call(this,n,t,e,i,r,-1)}function bV(n,t,e,i,r){wtn.call(this,n,t,e,i,r,-1)}function wV(n,t,e,i){FG.call(this,n,t,e),this.b=i}function dV(n){lA.call(this,n,!1),this.a=!1}function gV(){BO.call(this,"LOOKAHEAD_LAYOUT",1)}function pV(n){this.b=n,Zx.call(this,n),qD(this)}function mV(n){this.b=n,tR.call(this,n),XD(this)}function vV(n,t,e){this.a=n,i_.call(this,t,e,5,6)}function kV(n,t,e,i){this.b=n,MD.call(this,t,e,i)}function yV(n,t){this.b=n,fb.call(this,n.b),this.a=t}function MV(n){this.a=Fyn(n.a),this.b=new Z_(n.b)}function TV(n,t){ZW(),UE.call(this,n,Dwn(new IM(t)))}function jV(n,t){return QYn(),new PQ(n,t,0)}function EV(n,t){return QYn(),new PQ(6,n,t)}function SV(n,t){for(tJ(t);n.Ob();)t.Cd(n.Pb())}function PV(n,t){return RA(t)?AZ(n,t):!!FX(n.f,t)}function CV(n,t){return t.Vh()?mwn(n.b,uG(t,54)):t}function IV(n,t){return m_(n.substr(0,t.length),t)}function OV(n){return new Fz(new YD(n.a.length,n.a))}function AV(n){return new MO(n.c+n.b/2,n.d+n.a/2)}function LV(n){return p$(~n.l&f0n,~n.m&f0n,~n.h&l0n)}function NV(n){return typeof n===wZn||typeof n===mZn}function $V(n){n.f=new nN(n),n.i=new tN(n),++n.g}function DV(n){if(!n)throw hv(new Bv);return n.d}function xV(n){var t;return MK(null!=(t=Rfn(n))),t}function RV(n){var t;return MK(null!=(t=sgn(n))),t}function KV(n,t){var e;return e7(t,e=n.a.gc()),e-t}function FV(n,t){return null==n.a.zc(t,n)}function _V(n,t){return null==n.a.zc(t,(qx(),tot))}function BV(n){return new fX(null,oW(n,n.length))}function HV(n,t,e){return HXn(n,uG(t,42),uG(e,176))}function UV(n,t,e){return Mon(n.a,t),nq(n.b,t.g,e)}function GV(n,t,e){Vz(e,n.a.c.length),Y8(n.a,e,t)}function qV(n,t,e,i){ubn(t,e,n.length),XV(n,t,e,i)}function XV(n,t,e,i){var r;for(r=t;r0?e.Math.log(n/t):-100}function rW(n,t){return dwn(n,t)<0?-1:dwn(n,t)>0?1:0}function cW(n,t){J$(n,F$(t,160)?t:uG(t,2036).Rl())}function aW(n,t){if(null==n)throw hv(new MM(t))}function oW(n,t){return $rn(t,n.length),new Sq(n,t)}function uW(n,t){return!!t&&Qon(n,t)}function sW(){return Hy(),Uhn(cT(Lat,1),p1n,549,0,[Iat])}function hW(n){return 0==n.e?n:new VV(-n.e,n.d,n.a)}function fW(n,t){return ugn(n.c.c+n.c.b,t.c.c+t.c.b)}function lW(n,t){s8(n.d,t,n.b.b,n.b),++n.a,n.c=null}function bW(n,t){return n.c?bW(n.c,t):kD(n.b,t),n}function wW(n,t,e){var i;return i=uin(n,t),W5(n,t,e),i}function dW(n,t,e){var i;for(i=0;i=n.g}function uQ(n,t,e){return yK(null==e||aGn(n,e)),n[t]=e}function sQ(n,t){return s3(t,n.length+1),n.substr(t)}function hQ(n,t){for(tJ(t);n.c=n?new mS:ton(n-1)}function HQ(n){return!n.a&&n.c?n.c.b:n.a}function UQ(n){return F$(n,616)?n:new e0(n)}function GQ(n){n.c?GQ(n.c):(vgn(n),n.d=!0)}function qQ(n){n.c?n.c.$e():(n.d=!0,uKn(n))}function XQ(n){n.b=!1,n.c=!1,n.d=!1,n.a=!1}function zQ(n){return n.c.i.c==n.d.i.c}function VQ(n,t){var e;(e=n.Ih(t))>=0?n.ki(e):zLn(n,t)}function WQ(n,t){n.c<0||n.b.b0;)n=n<<1|(n<0?1:0);return n}function CJ(n,t){var e;return e=new bQ(n),mv(t.c,e),e}function IJ(n,t){n.u.Hc((eNn(),wRt))&&vNn(n,t),knn(n,t)}function OJ(n,t){return xA(n)===xA(t)||null!=n&&udn(n,t)}function AJ(n,t){return RX(n.a,t)?n.b[uG(t,22).g]:null}function LJ(){return BS(),Uhn(cT(oft,1),p1n,489,0,[Kht])}function NJ(){return nP(),Uhn(cT(JAt,1),p1n,490,0,[zAt])}function $J(){return tP(),Uhn(cT(tLt,1),p1n,558,0,[QAt])}function DJ(){return eP(),Uhn(cT(WLt,1),p1n,539,0,[GLt])}function xJ(n){return!n.n&&(n.n=new fV(lFt,n,1,7)),n.n}function RJ(n){return!n.c&&(n.c=new fV(wFt,n,9,9)),n.c}function KJ(n){return!n.c&&(n.c=new f_(cFt,n,5,8)),n.c}function FJ(n){return!n.b&&(n.b=new f_(cFt,n,4,7)),n.b}function _J(n){return n.j.c.length=0,oY(n.c),ZF(n.a),n}function BJ(n){return n.e==wct&&kw(n,akn(n.g,n.b)),n.e}function HJ(n){return n.f==wct&&Mw(n,tEn(n.g,n.b)),n.f}function UJ(n,t,e,i){return Dsn(n,t,e,!1),pdn(n,i),n}function GJ(n,t){this.b=n,QV.call(this,n,t),qD(this)}function qJ(n,t){this.b=n,N_.call(this,n,t),XD(this)}function XJ(n){this.d=n,this.a=this.d.b,this.b=this.d.c}function zJ(n,t){this.b=n,this.c=t,this.a=new fS(this.b)}function VJ(n,t){return s3(t,n.length),n.charCodeAt(t)}function WJ(n,t){jgn(n,uM($cn(t,"x")),uM($cn(t,"y")))}function QJ(n,t){jgn(n,uM($cn(t,"x")),uM($cn(t,"y")))}function JJ(n,t){return vgn(n),new fX(n,new ien(t,n.a))}function YJ(n,t){return vgn(n),new fX(n,new f7(t,n.a))}function ZJ(n,t){return vgn(n),new IK(n,new s7(t,n.a))}function nY(n,t){return vgn(n),new OK(n,new h7(t,n.a))}function tY(n,t){return new MZ(uG(WW(n),50),uG(WW(t),50))}function eY(n,t){return ugn(n.d.c+n.d.b/2,t.d.c+t.d.b/2)}function iY(n,t,e){e.a?Mcn(n,t.b-n.f/2):ycn(n,t.a-n.g/2)}function rY(n,t){return ugn(n.g.c+n.g.b/2,t.g.c+t.g.b/2)}function cY(n,t){return qS(),ugn((tJ(n),n),(tJ(t),t))}function aY(n){return null!=n&&ZE(UFt,n.toLowerCase())}function oY(n){var t;for(t=n.Kc();t.Ob();)t.Pb(),t.Qb()}function uY(n){var t;return!(t=n.b)&&(n.b=t=new Yl(n)),t}function sY(n){return con(n)||null}function hY(n,t){var e,i;return(e=n/t)>(i=t0(e))&&++i,i}function fY(n,t,e){var i;(i=uG(n.d.Kb(e),159))&&i.Nb(t)}function lY(n,t,e){KXn(n.a,e),jhn(e),EDn(n.b,e),Tzn(t,e)}function bY(n,t,e,i){this.a=n,this.c=t,this.b=e,this.d=i}function wY(n,t,e,i){this.c=n,this.b=t,this.a=e,this.d=i}function dY(n,t,e,i){this.c=n,this.b=t,this.d=e,this.a=i}function gY(n,t,e,i){this.c=n,this.d=t,this.b=e,this.a=i}function pY(n,t,e,i){this.a=n,this.d=t,this.c=e,this.b=i}function mY(n,t,e,i){this.a=n,this.e=t,this.d=e,this.c=i}function vY(n,t,e,i){this.a=n,this.c=t,this.d=e,this.b=i}function kY(n,t,e){this.a=L1n,this.d=n,this.b=t,this.c=e}function yY(n,t,e,i){_E.call(this,n,t),this.a=e,this.b=i}function MY(n,t){this.d=(tJ(n),n),this.a=16449,this.c=t}function TY(n){this.a=new Zm,this.e=Inn(YHt,zZn,53,n,0,2)}function jY(n){n.Ug("No crossing minimization",1),n.Vg()}function EY(){Ky.call(this,"There is no more element.")}function SY(n,t,e,i){this.a=n,this.b=t,this.c=e,this.d=i}function PY(n,t,e,i){this.a=n,this.b=t,this.c=e,this.d=i}function CY(n,t,e,i){this.e=n,this.a=t,this.c=e,this.d=i}function IY(n,t,e,i){this.a=n,this.c=t,this.d=e,this.b=i}function OY(n,t,e,i){ZN(),l7.call(this,t,e,i),this.a=n}function AY(n,t,e,i){ZN(),l7.call(this,t,e,i),this.a=n}function LY(n,t,e){var i;return i=eJn(n),t.ti(e,i)}function NY(n){var t;return Urn(t=new ev,n),t}function $Y(n){var t;return MIn(t=new ev,n),t}function DY(n,t){return Qun(t,cQ(n.f,t)),null}function xY(n){return!n.b&&(n.b=new fV(aFt,n,12,3)),n.b}function RY(n){return Fq(null==n||NV(n)&&!(n.Tm===j)),n}function KY(n){return n.n&&(n.e!==E1n&&n.je(),n.j=null),n}function FY(n){if(bpn(n.d),n.d.d!=n.c)throw hv(new Fv)}function _Y(n){return MK(n.b0&&XEn(this)}function UY(n,t){this.a=n,CK.call(this,n,uG(n.d,15).fd(t))}function GY(n,t){return ugn(EX(n)*jX(n),EX(t)*jX(t))}function qY(n,t){return ugn(EX(n)*jX(n),EX(t)*jX(t))}function XY(n){return BNn(n)&&oM(gK(zDn(n,(jYn(),hMt))))}function zY(n,t){return UNn(n,uG(oIn(t,(jYn(),UMt)),17),t)}function VY(n,t){return uG(oIn(n,(GYn(),Vpt)),15).Fc(t),t}function WY(n,t){return n.b=t.b,n.c=t.c,n.d=t.d,n.a=t.a,n}function QY(n,t,e,i){this.b=n,this.c=i,rL.call(this,t,e)}function JY(n,t,e){n.i=0,n.e=0,t!=e&&tln(n,t,e)}function YY(n,t,e){n.i=0,n.e=0,t!=e&&eln(n,t,e)}function ZY(n,t,e){return JS(),opn(uG(cQ(n.e,t),529),e)}function nZ(n){return n.f||(n.f=new OE(n,n.c))}function tZ(n,t){return Hwn(n.j,t.s,t.c)+Hwn(t.e,n.s,n.c)}function eZ(n,t){n.e&&!n.e.a&&(iv(n.e,t),eZ(n.e,t))}function iZ(n,t){n.d&&!n.d.a&&(iv(n.d,t),iZ(n.d,t))}function rZ(n,t){return-ugn(EX(n)*jX(n),EX(t)*jX(t))}function cZ(n){return uG(n.ld(),149).Pg()+":"+cpn(n.md())}function aZ(){HIn(this,new Fl),this.wb=(tQ(),M_t),vj()}function oZ(n){this.b=new Zm,Ohn(this.b,this.b),this.a=n}function uZ(n,t){new lS,this.a=new Uk,this.b=n,this.c=t}function sZ(){sZ=E,Jot=new N,Yot=new N,Zot=new $}function hZ(){hZ=E,zot=new C,Vot=new O,Wot=new A}function fZ(){fZ=E,Gut=new dn,Xut=new tz,qut=new gn}function lZ(){lZ=E,aft=new Zm,cft=new Ym,rft=new Zm}function bZ(n,t){if(null==n)throw hv(new MM(t));return n}function wZ(n){return!n.a&&(n.a=new fV(bFt,n,10,11)),n.a}function dZ(n){return!n.q&&(n.q=new fV(p_t,n,11,10)),n.q}function gZ(n){return!n.s&&(n.s=new fV(o_t,n,21,17)),n.s}function pZ(n){return WW(n),KMn(new Fz(ix(n.a.Kc(),new h)))}function mZ(n,t){return Tbn(n),Tbn(t),cM(uG(n,22),uG(t,22))}function vZ(n,t,e){nrn(n,t,new Pb(Q_(e)))}function kZ(n,t,e,i,r,c){wtn.call(this,n,t,e,i,r,c?-2:-1)}function yZ(n,t,e,i){LA.call(this,t,e),this.b=n,this.a=i}function MZ(n,t){Sy.call(this,new Hz(n)),this.a=n,this.b=t}function TZ(n){this.b=n,this.c=n,n.e=null,n.c=null,this.a=1}function jZ(n){var t;GB(),(t=uG(n.g,10)).n.a=n.d.c+t.d.b}function EZ(){var n,t;EZ=E,t=!ovn(),n=new v,_at=t?new m:n}function SZ(n){return hZ(),F$(n,59)?new eT(n):new gx(n)}function PZ(n){return F$(n,16)?new oX(uG(n,16)):cG(n.Kc())}function CZ(n){return new WD(n,n.e.Rd().gc()*n.c.Rd().gc())}function IZ(n){return new QD(n,n.e.Rd().gc()*n.c.Rd().gc())}function OZ(n){return n&&n.hashCode?n.hashCode():xx(n)}function AZ(n,t){return null==t?!!FX(n.f,null):_X(n.i,t)}function LZ(n,t){var e;return(e=Q$(n.a,t))&&(t.d=null),e}function NZ(n,t,e){return!!n.f&&n.f.ef(t,e)}function $Z(n,t,e,i){uQ(n.c[t.g],e.g,i),uQ(n.c[e.g],t.g,i)}function DZ(n,t,e,i){uQ(n.c[t.g],t.g,e),uQ(n.b[t.g],t.g,i)}function xZ(n,t,e){return uM(pK(e.a))<=n&&uM(pK(e.b))>=t}function RZ(n,t){this.g=n,this.d=Uhn(cT(pbt,1),e6n,10,0,[t])}function KZ(n){this.c=n,this.b=new Hj(uG(WW(new pn),50))}function FZ(n){this.c=n,this.b=new Hj(uG(WW(new jt),50))}function _Z(n){this.b=n,this.a=new Hj(uG(WW(new nt),50))}function BZ(){this.b=new ek,this.d=new lS,this.e=new Ok}function HZ(){this.c=new sj,this.d=new sj,this.e=new sj}function UZ(){this.a=new Uk,this.b=(man(3,g1n),new R7(3))}function GZ(n,t){this.e=n,this.a=dat,this.b=$Bn(t),this.c=t}function qZ(n){this.c=n.c,this.d=n.d,this.b=n.b,this.a=n.a}function XZ(n,t,e,i,r,c){this.a=n,Ran.call(this,t,e,i,r,c)}function zZ(n,t,e,i,r,c){this.a=n,Ran.call(this,t,e,i,r,c)}function VZ(n,t,e,i,r,c,a){return new i8(n.e,t,e,i,r,c,a)}function WZ(n,t,e){return e>=0&&m_(n.substr(e,t.length),t)}function QZ(n,t){return F$(t,149)&&m_(n.b,uG(t,149).Pg())}function JZ(n,t){return n.a?t.Gh().Kc():uG(t.Gh(),71).Ii()}function YZ(n,t){var e;return w8(e=n.b.Qc(t),n.b.gc()),e}function ZZ(n,t){if(null==n)throw hv(new MM(t));return n}function n1(n){return n.u||(y9(n),n.u=new aF(n,n)),n.u}function t1(n){this.a=(hZ(),F$(n,59)?new eT(n):new gx(n))}function e1(n){return uG(Lsn(n,16),29)||n.ii()}function i1(n,t){var e;return e=Ij(n.Rm),null==t?e:e+": "+t}function r1(n,t,e){return Knn(t,e,n.length),n.substr(t,e-t)}function c1(n,t){HF.call(this),Qrn(this),this.a=n,this.c=t}function a1(n){n&&i1(n,n.ie()),String.fromCharCode(10)}function o1(n){XM(),e.setTimeout((function(){throw n}),0)}function u1(){return _kn(),Uhn(cT(nst,1),p1n,436,0,[Wut,Vut])}function s1(){return Xin(),Uhn(cT(mst,1),p1n,435,0,[Yut,Zut])}function h1(){return zin(),Uhn(cT(mlt,1),p1n,432,0,[gft,pft])}function f1(){return Aun(),Uhn(cT(Dbt,1),p1n,517,0,[Obt,Ibt])}function l1(){return Y6(),Uhn(cT(Nmt,1),p1n,429,0,[kpt,ypt])}function b1(){return Vin(),Uhn(cT(Mgt,1),p1n,428,0,[dgt,ggt])}function w1(){return H7(),Uhn(cT(tgt,1),p1n,431,0,[Vdt,Wdt])}function d1(){return nin(),Uhn(cT(Jjt,1),p1n,430,0,[Gjt,qjt])}function g1(){return Z6(),Uhn(cT(cSt,1),p1n,531,0,[YEt,JEt])}function p1(){return pon(),Uhn(cT(iIt,1),p1n,501,0,[VCt,WCt])}function m1(){return b0(),Uhn(cT(gSt,1),p1n,523,0,[fSt,hSt])}function v1(){return w0(),Uhn(cT(xSt,1),p1n,522,0,[wSt,dSt])}function k1(){return _7(),Uhn(cT(qSt,1),p1n,528,0,[DSt,$St])}function y1(){return Wtn(),Uhn(cT(Hgt,1),p1n,488,0,[Ngt,Lgt])}function M1(){return a9(),Uhn(cT(CAt,1),p1n,491,0,[yAt,MAt])}function T1(){return rhn(),Uhn(cT($At,1),p1n,492,0,[OAt,AAt])}function j1(){return i3(),Uhn(cT(QCt,1),p1n,433,0,[_Ct,FCt])}function E1(){return Ptn(),Uhn(cT(lIt,1),p1n,434,0,[cIt,aIt])}function S1(){return l0(),Uhn(cT(JSt,1),p1n,465,0,[USt,GSt])}function P1(){return B7(),Uhn(cT(uLt,1),p1n,438,0,[nLt,ZAt])}function C1(){return Vhn(),Uhn(cT(JLt,1),p1n,437,0,[VLt,zLt])}function I1(){return CU(),Uhn(cT(jKt,1),p1n,347,0,[gKt,pKt])}function O1(n,t,e,i){return e>=0?n.Uh(t,e,i):n.Ch(null,e,i)}function A1(n){return 0==n.b.b?n.a.sf():tG(n.b)}function L1(n){if(5!=n.p)throw hv(new xv);return pz(n.f)}function N1(n){if(5!=n.p)throw hv(new xv);return pz(n.k)}function $1(n){return xA(n.a)===xA((Oun(),Q_t))&&eVn(n),n.a}function D1(n,t){n.b=t,n.c>0&&n.b>0&&(n.g=mX(n.c,n.b,n.a))}function x1(n,t){n.c=t,n.c>0&&n.b>0&&(n.g=mX(n.c,n.b,n.a))}function R1(n,t){nw(this,new MO(n.a,n.b)),tw(this,oG(t))}function K1(){Py.call(this,new sS(orn(12))),FD(!0),this.a=2}function F1(n,t,e){QYn(),Qm.call(this,n),this.b=t,this.a=e}function _1(n,t,e){ZN(),Hm.call(this,t),this.a=n,this.b=e}function B1(n){var t;t=n.c.d.b,n.b=t,n.a=n.c.d,t.a=n.c.d.b=n}function H1(n){return 0==n.b?null:(MK(0!=n.b),Lrn(n,n.a.a))}function U1(n,t){return null==t?DA(FX(n.f,null)):_P(n.i,t)}function G1(n,t,e,i,r){return new AOn(n,(Rtn(),vut),t,e,i,r)}function q1(n,t){return V5(t),Jcn(n,Inn(YHt,W1n,28,t,15,1),t)}function X1(n,t){return bZ(n,"set1"),bZ(t,"set2"),new GE(n,t)}function z1(n,t){var e=Rat[n.charCodeAt(0)];return null==e?n:e}function V1(n,t){var e;return pWn(n,t,e=new B),e.d}function W1(n,t,e,i){var r;r=new AF,t.a[e.g]=r,UV(n.b,i,r)}function Q1(n,t){return JF(BR(Lcn(n.f,t)),n.f.d)}function J1(n){Lan(n.a),zN(n.a),Apn(new Ad(n.a))}function Y1(n,t){iBn(n,!0),Prn(n.e.Rf(),new DB(n,!0,t))}function Z1(n,t){return lZ(),n==R0(bIn(t))||n==R0(gIn(t))}function n0(n,t){return tcn(),uG(oIn(t,(QGn(),ACt)),17).a==n}function t0(n){return 0|Math.max(Math.min(n,vZn),-2147483648)}function e0(n){this.a=uG(WW(n),277),this.b=(hZ(),new mx(n))}function i0(n,t,e){this.i=new Zm,this.b=n,this.g=t,this.a=e}function r0(n,t,e){this.a=new Zm,this.e=n,this.f=t,this.c=e}function c0(n,t,e){this.c=new Zm,this.e=n,this.f=t,this.b=e}function a0(n){HF.call(this),Qrn(this),this.a=n,this.c=!0}function o0(n){function t(){}return t.prototype=n||{},new t}function u0(n){if(n.Ae())return null;var t=n.n;return sZn[t]}function s0(n){return n.Db>>16!=3?null:uG(n.Cb,27)}function h0(n){return n.Db>>16!=9?null:uG(n.Cb,27)}function f0(n){return n.Db>>16!=6?null:uG(n.Cb,74)}function l0(){l0=E,USt=new XI(z2n,0),GSt=new XI(V2n,1)}function b0(){b0=E,fSt=new OI(V2n,0),hSt=new OI(z2n,1)}function w0(){w0=E,wSt=new AI(c3n,0),dSt=new AI("UP",1)}function d0(){d0=E,Aat=Abn((Hy(),Uhn(cT(Lat,1),p1n,549,0,[Iat])))}function g0(n){var t;return Dfn(t=new Dj(orn(n.length)),n),t}function p0(n,t){return n.b+=t.b,n.c+=t.c,n.d+=t.d,n.a+=t.a,n}function m0(n,t){return!!Chn(n,t)&&(lan(n),!0)}function v0(n,t){if(null==t)throw hv(new Rv);return Tvn(n,t)}function k0(n,t){var e;e=n.q.getHours(),n.q.setDate(t),Iqn(n,e)}function y0(n,t,e){var i;(i=n.Ih(t))>=0?n.bi(i,e):lRn(n,t,e)}function M0(n,t){var e;return(e=n.Ih(t))>=0?n.Wh(e):$Nn(n,t)}function T0(n,t){var e;for(WW(t),e=n.a;e;e=e.c)t.Yd(e.g,e.i)}function j0(n,t,e){var i;i=Ufn(n,t,e),n.b=new Don(i.c.length)}function E0(n,t,e){W0(),n&&vJ(LFt,n,t),n&&vJ(AFt,n,e)}function S0(n,t){return UB(),qx(),uG(t.a,17).a0}function O0(n){var t;return t=n.d,t=n.bj(n.f),ttn(n,t),t.Ob()}function A0(n,t){var e;return zCn(e=new aX(t),n),new Z_(e)}function L0(n){if(0!=n.p)throw hv(new xv);return HA(n.f,0)}function N0(n){if(0!=n.p)throw hv(new xv);return HA(n.k,0)}function $0(n){return n.Db>>16!=7?null:uG(n.Cb,241)}function D0(n){return n.Db>>16!=6?null:uG(n.Cb,241)}function x0(n){return n.Db>>16!=7?null:uG(n.Cb,167)}function R0(n){return n.Db>>16!=11?null:uG(n.Cb,27)}function K0(n){return n.Db>>16!=17?null:uG(n.Cb,29)}function F0(n){return n.Db>>16!=3?null:uG(n.Cb,155)}function _0(n){return vgn(n),JJ(n,new Md(new ek))}function B0(n,t){var e=n.a=n.a||[];return e[t]||(e[t]=n.ve(t))}function H0(n,t){var e;e=n.q.getHours(),n.q.setMonth(t),Iqn(n,e)}function U0(n,t){LD(this),this.f=t,this.g=n,KY(this),this.je()}function G0(n,t){this.a=n,this.c=D$(this.a),this.b=new qZ(t)}function q0(n,t,e){this.a=t,this.c=n,this.b=(WW(e),new Z_(e))}function X0(n,t,e){this.a=t,this.c=n,this.b=(WW(e),new Z_(e))}function z0(n){this.a=n,this.b=Inn(WEt,zZn,2043,n.e.length,0,2)}function V0(){this.a=new XL,this.e=new ek,this.g=0,this.i=0}function W0(){W0=E,LFt=new Ym,AFt=new Ym,pA(iut,new fs)}function Q0(){Q0=E,jEt=wz(new wJ,(uIn(),Plt),(zYn(),Owt))}function J0(){J0=E,EEt=wz(new wJ,(uIn(),Plt),(zYn(),Owt))}function Y0(){Y0=E,PEt=wz(new wJ,(uIn(),Plt),(zYn(),Owt))}function Z0(){Z0=E,tSt=Aq(new wJ,(uIn(),Plt),(zYn(),ewt))}function n2(){n2=E,aSt=Aq(new wJ,(uIn(),Plt),(zYn(),ewt))}function t2(){t2=E,sSt=Aq(new wJ,(uIn(),Plt),(zYn(),ewt))}function e2(){e2=E,mSt=Aq(new wJ,(uIn(),Plt),(zYn(),ewt))}function i2(n,t,e,i,r,c){return new Ken(n.e,t,n.Lj(),e,i,r,c)}function r2(n,t,e){return null==t?VAn(n.f,null,e):kgn(n.i,t,e)}function c2(n,t){n.c&&men(n.c.g,n),n.c=t,n.c&&kD(n.c.g,n)}function a2(n,t){n.c&&men(n.c.a,n),n.c=t,n.c&&kD(n.c.a,n)}function o2(n,t){n.i&&men(n.i.j,n),n.i=t,n.i&&kD(n.i.j,n)}function u2(n,t){n.d&&men(n.d.e,n),n.d=t,n.d&&kD(n.d.e,n)}function s2(n,t){n.a&&men(n.a.k,n),n.a=t,n.a&&kD(n.a.k,n)}function h2(n,t){n.b&&men(n.b.f,n),n.b=t,n.b&&kD(n.b.f,n)}function f2(n,t){dQ(n,n.b,n.c),uG(n.b.b,68),t&&uG(t.b,68).b}function l2(n,t){return ugn(uG(n.c,65).c.e.b,uG(t.c,65).c.e.b)}function b2(n,t){return ugn(uG(n.c,65).c.e.a,uG(t.c,65).c.e.a)}function w2(n){return Mbn(),qx(),0!=uG(n.a,86).d.e}function d2(n,t){F$(n.Cb,184)&&(uG(n.Cb,184).tb=null),qon(n,t)}function g2(n,t){F$(n.Cb,90)&&yLn(y9(uG(n.Cb,90)),4),qon(n,t)}function p2(n,t){Pgn(n,t),F$(n.Cb,90)&&yLn(y9(uG(n.Cb,90)),2)}function m2(n,t){null!=t.c&&pQ(n,new QW(t.c))}function v2(n){var t;return vj(),Urn(t=new ev,n),t}function k2(n){var t;return vj(),Urn(t=new ev,n),t}function y2(n){for(var t;;)if(t=n.Pb(),!n.Ob())return t}function M2(n,t,e){return kD(n.a,(TJ(),IMn(t,e),new FE(t,e))),n}function T2(n,t){return PP(),ein(t)?new Cq(t,n):new OA(t,n)}function j2(n){return cHn(),dwn(n,0)>=0?Rmn(n):hW(Rmn(Men(n)))}function E2(n){var t;return t=uG(tq(n.b),9),new nB(n.a,t,n.c)}function S2(n,t){var e;return(e=uG(Xwn(nZ(n.a),t),16))?e.gc():0}function P2(n,t,e){var i;hdn(t,e,n.c.length),i=e-t,nE(n.c,t,i)}function C2(n,t,e){hdn(t,e,n.gc()),this.c=n,this.a=t,this.b=e-t}function I2(n){this.c=new lS,this.b=n.b,this.d=n.c,this.a=n.a}function O2(n){this.a=e.Math.cos(n),this.b=e.Math.sin(n)}function A2(n,t,e,i){this.c=n,this.d=i,s2(this,t),h2(this,e)}function L2(n,t){Ey.call(this,new sS(orn(n))),man(t,XZn),this.a=t}function N2(n,t,e){return new AOn(n,(Rtn(),mut),null,!1,t,e)}function $2(n,t,e){return new AOn(n,(Rtn(),kut),t,e,null,!1)}function D2(){return ybn(),Uhn(cT(Rut,1),p1n,108,0,[Cut,Iut,Out])}function x2(){return Yen(),Uhn(cT(hht,1),p1n,472,0,[Fst,Kst,Rst])}function R2(){return Ktn(),Uhn(cT(xst,1),p1n,471,0,[Ast,Ost,Lst])}function K2(){return Yrn(),Uhn(cT(Ist,1),p1n,237,0,[jst,Est,Sst])}function F2(){return Jen(),Uhn(cT(Clt,1),p1n,391,0,[glt,dlt,plt])}function _2(){return gon(),Uhn(cT(Rdt,1),p1n,372,0,[Sdt,Edt,jdt])}function B2(){return jan(),Uhn(cT(agt,1),p1n,322,0,[Zdt,Ydt,ngt])}function H2(){return ran(),Uhn(cT(bgt,1),p1n,351,0,[igt,cgt,rgt])}function U2(){return Pfn(),Uhn(cT(Ogt,1),p1n,460,0,[kgt,vgt,ygt])}function G2(){return ihn(),Uhn(cT(mpt,1),p1n,299,0,[fpt,lpt,hpt])}function q2(){return Zen(),Uhn(cT(Mpt,1),p1n,311,0,[gpt,ppt,dpt])}function X2(){return Cwn(),Uhn(cT(pjt,1),p1n,390,0,[ujt,sjt,hjt])}function z2(){return can(),Uhn(cT(eEt,1),p1n,463,0,[Qjt,Vjt,Wjt])}function V2(){return isn(),Uhn(cT(oEt,1),p1n,387,0,[Zjt,nEt,tEt])}function W2(){return Sln(),Uhn(cT(lEt,1),p1n,349,0,[aEt,rEt,cEt])}function Q2(){return kbn(),Uhn(cT(pEt,1),p1n,350,0,[sEt,hEt,fEt])}function J2(){return ian(),Uhn(cT(MEt,1),p1n,352,0,[gEt,wEt,dEt])}function Y2(){return zhn(),Uhn(cT(xEt,1),p1n,388,0,[kEt,yEt,vEt])}function Z2(){return ean(),Uhn(cT(qEt,1),p1n,464,0,[_Et,BEt,HEt])}function n3(n){return Gfn(Uhn(cT(PNt,1),zZn,8,0,[n.i.n,n.n,n.a]))}function t3(){return Pln(),Uhn(cT(RCt,1),p1n,392,0,[gPt,dPt,wPt])}function e3(){e3=E,UCt=wz(new wJ,(Cjn(),WSt),(OHn(),ePt))}function i3(){i3=E,_Ct=new JI("DFS",0),FCt=new JI("BFS",1)}function r3(n,t,e){var i;(i=new ia).b=t,i.a=e,++t.b,kD(n.d,i)}function c3(n,t,e){var i;JF(i=new eN(e.d),n),jgn(t,i.a,i.b)}function a3(n,t){pD(n,pz(E3($z(t,24),W0n)),pz(E3(t,W0n)))}function o3(n,t){if(n<0||n>t)throw hv(new dM(h2n+n+f2n+t))}function u3(n,t){if(n<0||n>=t)throw hv(new dM(h2n+n+f2n+t))}function s3(n,t){if(n<0||n>=t)throw hv(new JM(h2n+n+f2n+t))}function h3(n,t){this.b=(tJ(n),n),this.a=t&j0n?t:64|t|VZn}function f3(n){return vgn(n),sZ(),sZ(),krn(n,Yot)}function l3(n,t,e){var i;return(i=uXn(n,t,!1)).b<=t&&i.a<=e}function b3(){return den(),Uhn(cT(LAt,1),p1n,439,0,[EAt,PAt,SAt])}function w3(){return Bgn(),Uhn(cT(kAt,1),p1n,394,0,[IOt,OOt,COt])}function d3(){return Jmn(),Uhn(cT(dOt,1),p1n,445,0,[oOt,uOt,sOt])}function g3(){return Zyn(),Uhn(cT(AOt,1),p1n,456,0,[lOt,wOt,bOt])}function p3(){return vbn(),Uhn(cT(nOt,1),p1n,393,0,[sIt,hIt,fIt])}function m3(){return esn(),Uhn(cT(hOt,1),p1n,300,0,[iOt,rOt,eOt])}function v3(){return Own(),Uhn(cT(Kxt,1),p1n,346,0,[Oxt,Ixt,Axt])}function k3(){return Rdn(),Uhn(cT(VAt,1),p1n,444,0,[HAt,UAt,GAt])}function y3(){return Zrn(),Uhn(cT(lxt,1),p1n,278,0,[ixt,rxt,cxt])}function M3(){return Iwn(),Uhn(cT(mKt,1),p1n,280,0,[lKt,fKt,bKt])}function T3(n){return WW(n),F$(n,16)?new Z_(uG(n,16)):rG(n.Kc())}function j3(n,t){return n&&n.equals?n.equals(t):xA(n)===xA(t)}function E3(n,t){return Esn(Oz(_L(n)?Gsn(n):n,_L(t)?Gsn(t):t))}function S3(n,t){return Esn(Az(_L(n)?Gsn(n):n,_L(t)?Gsn(t):t))}function P3(n,t){return Esn(Lz(_L(n)?Gsn(n):n,_L(t)?Gsn(t):t))}function C3(n,t){var e;return kK(!!(e=(tJ(n),n).g)),tJ(t),e(t)}function I3(n,t){var e,i;return i=KV(n,t),e=n.a.fd(i),new BE(n,e)}function O3(n){return n.Db>>16!=6?null:uG(J$n(n),241)}function A3(n){if(2!=n.p)throw hv(new xv);return pz(n.f)&D1n}function L3(n){if(2!=n.p)throw hv(new xv);return pz(n.k)&D1n}function N3(n){return MK(n.ai?1:0}function Y3(n,t){var e;return e=jen(t),uG(cQ(n.c,e),17).a}function Z3(n,t,e){var i;i=n.d[t.p],n.d[t.p]=n.d[e.p],n.d[e.p]=i}function n4(n,t,e){var i;n.n&&t&&e&&(i=new Yu,kD(n.e,i))}function t4(n,t){if(FV(n.a,t),t.d)throw hv(new Ky(p2n));t.d=n}function e4(n,t){this.a=new Zm,this.d=new Zm,this.f=n,this.c=t}function i4(){this.c=new z$,this.a=new p7,this.b=new yk,XS()}function r4(){Whn(),this.b=new Ym,this.a=new Ym,this.c=new Zm}function c4(n,t,e){this.d=n,this.j=t,this.e=e,this.o=-1,this.p=3}function a4(n,t,e){this.d=n,this.k=t,this.f=e,this.o=-1,this.p=5}function o4(n,t,e,i,r,c){Bcn.call(this,n,t,e,i,r),c&&(this.o=-2)}function u4(n,t,e,i,r,c){Hcn.call(this,n,t,e,i,r),c&&(this.o=-2)}function s4(n,t,e,i,r,c){E9.call(this,n,t,e,i,r),c&&(this.o=-2)}function h4(n,t,e,i,r,c){qcn.call(this,n,t,e,i,r),c&&(this.o=-2)}function f4(n,t,e,i,r,c){S9.call(this,n,t,e,i,r),c&&(this.o=-2)}function l4(n,t,e,i,r,c){Ucn.call(this,n,t,e,i,r),c&&(this.o=-2)}function b4(n,t,e,i,r,c){Gcn.call(this,n,t,e,i,r),c&&(this.o=-2)}function w4(n,t,e,i,r,c){P9.call(this,n,t,e,i,r),c&&(this.o=-2)}function d4(n,t,e,i){Hm.call(this,e),this.b=n,this.c=t,this.d=i}function g4(n,t){this.f=n,this.a=(N7(),MBt),this.c=MBt,this.b=t}function p4(n,t){this.g=n,this.d=(N7(),TBt),this.a=TBt,this.b=t}function m4(n,t){!n.c&&(n.c=new wsn(n,0)),BXn(n.c,(uVn(),nHt),t)}function v4(n,t){return lxn(n,t,F$(t,102)&&!!(uG(t,19).Bb&P0n))}function k4(n,t){return rW(Bsn(n.q.getTime()),Bsn(t.q.getTime()))}function y4(n){return Dq(n.e.Rd().gc()*n.c.Rd().gc(),16,new zl(n))}function M4(n){return!(!n.u||0==z5(n.u.a).i||n.n&&yMn(n.n))}function T4(n){return!(!n.a||0==Aen(n.a.a).i||n.b&&MMn(n.b))}function j4(n,t){return 0==t?!!n.o&&0!=n.o.f:Wkn(n,t)}function E4(n,t,e){var i;return!!(i=uG(n.Zb().xc(t),16))&&i.Hc(e)}function S4(n,t,e){var i;return!!(i=uG(n.Zb().xc(t),16))&&i.Mc(e)}function P4(n,t){var e;return e=1-t,n.a[e]=Ton(n.a[e],e),Ton(n,t)}function C4(n,t){var e;return e=E3(n,L0n),S3(Nz(t,32),e)}function I4(n,t,e){WW(n),mjn(new q0(new Z_(n),t,e))}function O4(n,t,e){WW(n),vjn(new X0(new Z_(n),t,e))}function A4(n,t,e,i,r,c){return Dsn(n,t,e,c),gdn(n,i),vdn(n,r),n}function L4(n,t,e,i){return n.a+=""+r1(null==t?IZn:cpn(t),e,i),n}function N4(n,t){this.a=n,Jw.call(this,n),o3(t,n.gc()),this.b=t}function $4(n){this.a=Inn(dat,EZn,1,pfn(e.Math.max(8,n))<<1,5,1)}function D4(n){return uG(Ekn(n,Inn(pbt,e6n,10,n.c.length,0,1)),199)}function x4(n){return uG(Ekn(n,Inn(obt,t6n,18,n.c.length,0,1)),483)}function R4(n){return n.a?0==n.e.length?n.a.a:n.a.a+""+n.e:n.c}function K4(n){for(;n.d>0&&0==n.a[--n.d];);0==n.a[n.d++]&&(n.e=0)}function F4(n){return MK(n.b.b!=n.d.a),n.c=n.b=n.b.b,--n.a,n.c.c}function _4(n,t,e){n.a=t,n.c=e,n.b.a.$b(),BY(n.d),Xv(n.e.a.c,0)}function B4(n,t){var e;n.e=new dy,f$(e=GFn(t),n.c),T_n(n,e,0)}function H4(n,t,e,i){var r;(r=new gu).a=t,r.b=e,r.c=i,aq(n.a,r)}function U4(n,t,e,i){var r;(r=new gu).a=t,r.b=e,r.c=i,aq(n.b,r)}function G4(n,t,e){if(n<0||te)throw hv(new dM(QOn(n,t,e)))}function q4(n,t){if(n<0||n>=t)throw hv(new dM(TLn(n,t)));return n}function X4(n){if(!("stack"in n))try{throw n}catch(t){}return n}function z4(n){return JS(),F$(n.g,10)?uG(n.g,10):null}function V4(n){return!uY(n).dc()&&(h$(n,new w),!0)}function W4(n){var t;return _L(n)?-0==(t=n)?0:t:Gen(n)}function Q4(n,t){return!!F$(t,44)&&sTn(n.a,uG(t,44))}function J4(n,t){return!!F$(t,44)&&sTn(n.a,uG(t,44))}function Y4(n,t){return!!F$(t,44)&&sTn(n.a,uG(t,44))}function Z4(n){var t;return GQ(n),t=new D,tE(n.a,new vd(t)),t}function n6(){var n,t;return n=new ev,kD(gBt,t=n),t}function t6(n){var t;return GQ(n),t=new x,tE(n.a,new kd(t)),t}function e6(n,t){return n.a<=n.b&&(t.Dd(n.a++),!0)}function i6(n){dun.call(this,n,(Rtn(),put),null,!1,null,!1)}function r6(){r6=E,_ht=Abn((BS(),Uhn(cT(oft,1),p1n,489,0,[Kht])))}function c6(){c6=E,$Et=MJ(xwn(1),xwn(4)),NEt=MJ(xwn(1),xwn(2))}function a6(n,t){return new LU(t,HR(D$(t.e),n,n),(qx(),!0))}function o6(n){return new R7((man(n,v1n),arn(Lgn(Lgn(5,n),n/10|0))))}function u6(n){return Dq(n.e.Rd().gc()*n.c.Rd().gc(),273,new Xl(n))}function s6(n){return uG(Ekn(n,Inn(Abt,i6n,12,n.c.length,0,1)),2042)}function h6(n){return n2(),!(v9(n)||!v9(n)&&n.c.i.c==n.d.i.c)}function f6(n,t){return ncn(),uG(oIn(t,(QGn(),kCt)),17).a>=n.gc()}function l6(n,t){_Jn(t,n),NG(n.d),NG(uG(oIn(n,(jYn(),SMt)),214))}function b6(n,t){BJn(t,n),$G(n.d),$G(uG(oIn(n,(jYn(),SMt)),214))}function w6(n,t,e){n.d&&men(n.d.e,n),n.d=t,n.d&&GX(n.d.e,e,n)}function d6(n,t,e){return e.f.c.length>0?HV(n.a,t,e):HV(n.b,t,e)}function g6(n,t,e){var i;i=bkn();try{return SF(n,t,e)}finally{m8(i)}}function p6(n,t){var e,i;return i=null,(e=v0(n,t))&&(i=e.pe()),i}function m6(n,t){var e,i;return i=null,(e=v0(n,t))&&(i=e.se()),i}function v6(n,t){var e,i;return i=null,(e=uin(n,t))&&(i=e.se()),i}function k6(n,t){var e,i;return i=null,(e=v0(n,t))&&(i=uAn(e)),i}function y6(n,t,e){var i;return i=jvn(e),yHn(n.g,i,t),yHn(n.i,t,e),t}function M6(n,t,e){this.d=new qg(this),this.e=n,this.i=t,this.f=e}function T6(n,t,e,i){this.e=null,this.c=n,this.d=t,this.a=e,this.b=i}function j6(n,t,e,i){A$(this),this.c=n,this.e=t,this.f=e,this.b=i}function E6(n,t,e,i){this.d=n,this.n=t,this.g=e,this.o=i,this.p=-1}function S6(n,t,e,i){return F$(e,59)?new Yx(n,t,e,i):new qz(n,t,e,i)}function P6(n){return F$(n,16)?uG(n,16).dc():!n.Kc().Ob()}function C6(n){if(n.e.g!=n.b)throw hv(new Fv);return!!n.c&&n.d>0}function I6(n){return MK(n.b!=n.d.c),n.c=n.b,n.b=n.b.a,++n.a,n.c.c}function O6(n,t){tJ(t),uQ(n.a,n.c,t),n.c=n.c+1&n.a.length-1,JTn(n)}function A6(n,t){tJ(t),n.b=n.b-1&n.a.length-1,uQ(n.a,n.b,t),JTn(n)}function L6(n){var t;t=n.Gh(),this.a=F$(t,71)?uG(t,71).Ii():t.Kc()}function N6(n){return new h3(Vrn(uG(n.a.md(),16).gc(),n.a.ld()),16)}function $6(){$6=E,WAt=Abn((nP(),Uhn(cT(JAt,1),p1n,490,0,[zAt])))}function D6(){D6=E,YAt=Abn((tP(),Uhn(cT(tLt,1),p1n,558,0,[QAt])))}function x6(){x6=E,XLt=Abn((eP(),Uhn(cT(WLt,1),p1n,539,0,[GLt])))}function R6(){return Uvn(),Uhn(cT(abt,1),p1n,389,0,[tbt,Zlt,Ylt,nbt])}function K6(){return Rtn(),Uhn(cT(Tut,1),p1n,304,0,[put,mut,vut,kut])}function F6(){return vyn(),Uhn(cT(Sht,1),p1n,332,0,[yht,kht,Mht,Tht])}function _6(){return myn(),Uhn(cT(Fht,1),p1n,406,0,[Nht,Lht,$ht,Dht])}function B6(){return ehn(),Uhn(cT(jht,1),p1n,417,0,[pht,wht,dht,ght])}function H6(){return Xhn(),Uhn(cT(ebt,1),p1n,416,0,[Flt,Hlt,_lt,Blt])}function U6(){return qhn(),Uhn(cT(mdt,1),p1n,421,0,[odt,udt,sdt,hdt])}function G6(){return Ghn(),Uhn(cT(adt,1),p1n,371,0,[zwt,qwt,Xwt,Gwt])}function q6(){return Yyn(),Uhn(cT(jjt,1),p1n,203,0,[djt,gjt,wjt,bjt])}function X6(){return yvn(),Uhn(cT(Xjt,1),p1n,284,0,[Fjt,Kjt,_jt,Bjt])}function z6(n){return n.j==(KQn(),KRt)&&$x(_$n(n),kRt)}function V6(n,t){var e;c2(e=t.a,t.c.d),u2(e,t.d.d),Xun(e.a,n.n)}function W6(n,t){var e;return!(e=uG(ain(n.b,t),67))&&(e=new lS),e}function Q6(n){return JS(),F$(n.g,154)?uG(n.g,154):null}function J6(n){n.a=null,n.e=null,Xv(n.b.c,0),Xv(n.f.c,0),n.c=null}function Y6(){Y6=E,kpt=new sI(G2n,0),ypt=new sI("TOP_LEFT",1)}function Z6(){Z6=E,YEt=new SI("UPPER",0),JEt=new SI("LOWER",1)}function n5(n,t){return bD(new MO(t.e.a+t.f.a/2,t.e.b+t.f.b/2),n)}function t5(n,t){return uG(yx(Wz(uG(Y9(n.k,t),15).Oc(),Fdt)),113)}function e5(n,t){return uG(yx(Qz(uG(Y9(n.k,t),15).Oc(),Fdt)),113)}function i5(){return Cjn(),Uhn(cT(ZSt,1),p1n,405,0,[zSt,VSt,WSt,QSt])}function r5(){return mbn(),Uhn(cT(BCt,1),p1n,353,0,[xCt,$Ct,DCt,NCt])}function c5(){return dTn(),Uhn(cT(cOt,1),p1n,354,0,[ZIt,JIt,YIt,QIt])}function a5(){return Qmn(),Uhn(cT(sKt,1),p1n,386,0,[QRt,JRt,WRt,VRt])}function o5(){return Ajn(),Uhn(cT(Wxt,1),p1n,291,0,[Rxt,$xt,Dxt,xxt])}function u5(){return _gn(),Uhn(cT(kxt,1),p1n,223,0,[fxt,sxt,uxt,hxt])}function s5(){return qpn(),Uhn(cT(SKt,1),p1n,320,0,[TKt,kKt,MKt,yKt])}function h5(){return Eln(),Uhn(cT(DKt,1),p1n,415,0,[CKt,IKt,PKt,OKt])}function f5(n){return W0(),PV(LFt,n)?uG(cQ(LFt,n),341).Qg():null}function l5(n,t,e){return t<0?$Nn(n,e):uG(e,69).wk().Bk(n,n.hi(),t)}function b5(n,t,e){var i;return i=jvn(e),yHn(n.j,i,t),vJ(n.k,t,e),t}function w5(n,t,e){var i;return i=jvn(e),yHn(n.d,i,t),vJ(n.e,t,e),t}function d5(n){var t;return gj(),t=new es,n&&ARn(t,n),t}function g5(n){var t;return t=n.aj(n.i),n.i>0&&qGn(n.g,0,t,0,n.i),t}function p5(n,t){var e;for(e=n.j.c.length;e>24}function y5(n){if(1!=n.p)throw hv(new xv);return pz(n.k)<<24>>24}function M5(n){if(7!=n.p)throw hv(new xv);return pz(n.k)<<16>>16}function T5(n){if(7!=n.p)throw hv(new xv);return pz(n.f)<<16>>16}function j5(n,t){return 0==t.e||0==n.e?_ot:(b_n(),yKn(n,t))}function E5(n,t){return xA(t)===xA(n)?"(this Map)":null==t?IZn:cpn(t)}function S5(n,t,e){return Rz(pK(DA(FX(n.f,t))),pK(DA(FX(n.f,e))))}function P5(n,t,e){var i;i=uG(cQ(n.g,e),60),kD(n.a.c,new WO(t,i))}function C5(n,t,e){n.i=0,n.e=0,t!=e&&(eln(n,t,e),tln(n,t,e))}function I5(n,t,e,i,r){kD(t,uLn(r,Bxn(r,e,i))),LIn(n,r,t)}function O5(n,t,e,i,r){this.i=n,this.a=t,this.e=e,this.j=i,this.f=r}function A5(n,t){HZ.call(this),this.a=n,this.b=t,kD(this.a.b,this)}function L5(n){this.b=new Ym,this.c=new Ym,this.d=new Ym,this.a=n}function N5(n,t){var e;return e=new QM,n.Gd(e),e.a+="..",t.Hd(e),e.a}function $5(n,t){var e;for(e=t;e;)KR(n,e.i,e.j),e=R0(e);return n}function D5(n,t,e){var i;return i=jvn(e),vJ(n.b,i,t),vJ(n.c,t,e),t}function x5(n){var t;for(t=0;n.Ob();)n.Pb(),t=Lgn(t,1);return arn(t)}function R5(n,t){var e;return PP(),uOn(e=uG(n,69).vk(),t),e.xl(t)}function K5(n,t,e){if(e){var i=e.oe();n.a[t]=i(e)}else delete n.a[t]}function F5(n,t){var e;e=n.q.getHours(),n.q.setFullYear(t+V1n),Iqn(n,e)}function _5(n,t){return uG(null==t?DA(FX(n.f,null)):_P(n.i,t),288)}function B5(n,t){return n==(zIn(),dbt)&&t==dbt?4:n==dbt||t==dbt?8:32}function H5(n,t,e){return aqn(n,t,e,F$(t,102)&&!!(uG(t,19).Bb&P0n))}function U5(n,t,e){return Dqn(n,t,e,F$(t,102)&&!!(uG(t,19).Bb&P0n))}function G5(n,t,e){return Cxn(n,t,e,F$(t,102)&&!!(uG(t,19).Bb&P0n))}function q5(n){n.b!=n.c&&(n.a=Inn(dat,EZn,1,8,5,1),n.b=0,n.c=0)}function X5(n){return MK(n.a=0&&n.a[e]===t[e];e--);return e<0}function g8(n){var t;return n?new aX(n):(Fon(t=new XL,n),t)}function p8(n,t){var e,i;i=!1;do{i|=e=Tfn(n,t)}while(e);return i}function m8(n){n&&Cin((Gy(),Fat)),--Uat,n&&-1!=qat&&(jL(qat),qat=-1)}function v8(n){aCn(),pD(this,pz(E3($z(n,24),W0n)),pz(E3(n,W0n)))}function k8(){k8=E,Jut=Abn((_kn(),Uhn(cT(nst,1),p1n,436,0,[Wut,Vut])))}function y8(){y8=E,tst=Abn((Xin(),Uhn(cT(mst,1),p1n,435,0,[Yut,Zut])))}function M8(){M8=E,vft=Abn((zin(),Uhn(cT(mlt,1),p1n,432,0,[gft,pft])))}function T8(){T8=E,Lbt=Abn((Aun(),Uhn(cT(Dbt,1),p1n,517,0,[Obt,Ibt])))}function j8(){j8=E,Tpt=Abn((Y6(),Uhn(cT(Nmt,1),p1n,429,0,[kpt,ypt])))}function E8(){E8=E,mgt=Abn((Vin(),Uhn(cT(Mgt,1),p1n,428,0,[dgt,ggt])))}function S8(){S8=E,Dgt=Abn((Wtn(),Uhn(cT(Hgt,1),p1n,488,0,[Ngt,Lgt])))}function P8(){P8=E,zjt=Abn((nin(),Uhn(cT(Jjt,1),p1n,430,0,[Gjt,qjt])))}function C8(){C8=E,nSt=Abn((Z6(),Uhn(cT(cSt,1),p1n,531,0,[YEt,JEt])))}function I8(){I8=E,Jdt=Abn((H7(),Uhn(cT(tgt,1),p1n,431,0,[Vdt,Wdt])))}function O8(){O8=E,HCt=Abn((i3(),Uhn(cT(QCt,1),p1n,433,0,[_Ct,FCt])))}function A8(){A8=E,JCt=Abn((pon(),Uhn(cT(iIt,1),p1n,501,0,[VCt,WCt])))}function L8(){L8=E,bSt=Abn((b0(),Uhn(cT(gSt,1),p1n,523,0,[fSt,hSt])))}function N8(){N8=E,pSt=Abn((w0(),Uhn(cT(xSt,1),p1n,522,0,[wSt,dSt])))}function $8(){$8=E,RSt=Abn((_7(),Uhn(cT(qSt,1),p1n,528,0,[DSt,$St])))}function D8(){D8=E,XSt=Abn((l0(),Uhn(cT(JSt,1),p1n,465,0,[USt,GSt])))}function x8(){x8=E,uIt=Abn((Ptn(),Uhn(cT(lIt,1),p1n,434,0,[cIt,aIt])))}function R8(){R8=E,jAt=Abn((a9(),Uhn(cT(CAt,1),p1n,491,0,[yAt,MAt])))}function K8(){K8=E,NAt=Abn((rhn(),Uhn(cT($At,1),p1n,492,0,[OAt,AAt])))}function F8(){F8=E,eLt=Abn((B7(),Uhn(cT(uLt,1),p1n,438,0,[nLt,ZAt])))}function _8(){_8=E,QLt=Abn((Vhn(),Uhn(cT(JLt,1),p1n,437,0,[VLt,zLt])))}function B8(){B8=E,vKt=Abn((CU(),Uhn(cT(jKt,1),p1n,347,0,[gKt,pKt])))}function H8(){return xdn(),Uhn(cT(axt,1),p1n,88,0,[ZDt,YDt,JDt,QDt,nxt])}function U8(){return KQn(),Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt])}function G8(n,t,e){return uG(null==t?VAn(n.f,null,e):kgn(n.i,t,e),288)}function q8(n){return(n.k==(zIn(),dbt)||n.k==lbt)&&vR(n,(GYn(),$pt))}function X8(n){return n.c&&n.d?z3(n.c)+"->"+z3(n.d):"e_"+xx(n)}function z8(n,t){var e,i;for(tJ(t),i=n.Kc();i.Ob();)e=i.Pb(),t.Cd(e)}function V8(n,t){var e;vZ(e=new _y,"x",t.a),vZ(e,"y",t.b),pQ(n,e)}function W8(n,t){var e;vZ(e=new _y,"x",t.a),vZ(e,"y",t.b),pQ(n,e)}function Q8(n,t){var e;for(e=t;e;)KR(n,-e.i,-e.j),e=R0(e);return n}function J8(n,t){var e,i;for(e=t,i=0;e>0;)i+=n.a[e],e-=e&-e;return i}function Y8(n,t,e){var i;return u3(t,n.c.length),i=n.c[t],n.c[t]=e,i}function Z8(n,t,e){n.a.c.length=0,sVn(n,t,e),0==n.a.c.length||mUn(n,t)}function n9(n){n.i=0,FP(n.b,null),FP(n.c,null),n.a=null,n.e=null,++n.g}function t9(){t9=E,Nut=!0,Aut=!1,Lut=!1,Dut=!1,$ut=!1}function e9(n){t9(),Nut||(this.c=n,this.e=!0,this.a=new Zm)}function i9(n,t){this.c=0,this.b=t,iL.call(this,n,17493),this.a=this.c}function r9(n){NYn(),dv(this),this.a=new lS,Lln(this,n),aq(this.a,n)}function c9(){IN(this),this.b=new MO(M0n,M0n),this.a=new MO(T0n,T0n)}function a9(){a9=E,yAt=new oO(x6n,0),MAt=new oO("TARGET_WIDTH",1)}function o9(n,t){return(vgn(n),Qj(new fX(n,new ien(t,n.a)))).Bd(Kut)}function u9(){return uIn(),Uhn(cT(Llt,1),p1n,367,0,[Tlt,jlt,Elt,Slt,Plt])}function s9(){return gPn(),Uhn(cT(Pdt,1),p1n,375,0,[wdt,gdt,pdt,ddt,bdt])}function h9(){return kvn(),Uhn(cT(pgt,1),p1n,348,0,[sgt,ugt,fgt,lgt,hgt])}function f9(){return pyn(),Uhn(cT(xjt,1),p1n,323,0,[Tjt,kjt,yjt,vjt,Mjt])}function l9(){return Gpn(),Uhn(cT(ajt,1),p1n,171,0,[Lmt,Cmt,Imt,Omt,Amt])}function b9(){return zPn(),Uhn(cT(oIt,1),p1n,368,0,[tIt,YCt,eIt,ZCt,nIt])}function w9(){return _Rn(),Uhn(cT(qAt,1),p1n,373,0,[xAt,DAt,KAt,RAt,FAt])}function d9(){return pOn(),Uhn(cT(qLt,1),p1n,324,0,[iLt,rLt,oLt,cLt,aLt])}function g9(){return Rkn(),Uhn(cT(MNt,1),p1n,170,0,[hNt,sNt,oNt,fNt,uNt])}function p9(){return Vkn(),Uhn(cT(hRt,1),p1n,256,0,[Zxt,tRt,Jxt,Yxt,nRt])}function m9(n){return XM(),function(){return g6(n,this,arguments)}}function v9(n){return!(!n.c||!n.d||!n.c.i||n.c.i!=n.d.i)}function k9(n,t){return!!F$(t,143)&&m_(n.c,uG(t,143).c)}function y9(n){return n.t||(n.t=new $m(n),$dn(new Qy(n),0,n.t)),n.t}function M9(n){this.b=n,DD.call(this,n),this.a=uG(Lsn(this.b.a,4),129)}function T9(n){this.b=n,nR.call(this,n),this.a=uG(Lsn(this.b.a,4),129)}function j9(n,t,e,i,r){b7.call(this,t,i,r),Kf(this),this.c=n,this.b=e}function E9(n,t,e,i,r){c4.call(this,t,i,r),Kf(this),this.c=n,this.a=e}function S9(n,t,e,i,r){a4.call(this,t,i,r),Kf(this),this.c=n,this.a=e}function P9(n,t,e,i,r){b7.call(this,t,i,r),Kf(this),this.c=n,this.a=e}function C9(n,t){return uG(ain(n.d,t),23)||uG(ain(n.e,t),23)}function I9(n,t){var e,i;return e=t.ld(),!!(i=n.Fe(e))&&OJ(i.e,t.md())}function O9(n,t){var e;return new FE(e=t.ld(),n.e.pc(e,uG(t.md(),16)))}function A9(n,t){var e;return null==(e=n.a.get(t))?Inn(dat,EZn,1,0,5,1):e}function L9(n){var t;return t=n.length,m_(S0n.substr(S0n.length-t,t),n)}function N9(n){if(hDn(n))return n.c=n.a,n.a.Pb();throw hv(new Bv)}function $9(n,t){return 0==t||0==n.e?n:t>0?MFn(n,t):rvn(n,-t)}function D9(n,t){return 0==t||0==n.e?n:t>0?rvn(n,t):MFn(n,-t)}function x9(n){xP.call(this,null==n?IZn:cpn(n),F$(n,82)?uG(n,82):null)}function R9(n){var t;return n.c||F$(t=n.r,90)&&(n.c=uG(t,29)),n.c}function K9(n){var t;return zsn(t=new UZ,n),kfn(t,(jYn(),bMt),null),t}function F9(n){var t,e;return t=n.c.i,e=n.d.i,t.k==(zIn(),lbt)&&e.k==lbt}function _9(n){return p$(n&f0n,n>>22&f0n,n<0?l0n:0)}function B9(n){var t,e,i;for(e=0,i=(t=n).length;e=0?n.Lh(i,e,!0):YNn(n,t,e)}function G9(n,t,e){return ugn(bD($kn(n),D$(t.b)),bD($kn(n),D$(e.b)))}function q9(n,t,e){return ugn(bD($kn(n),D$(t.e)),bD($kn(n),D$(e.e)))}function X9(n,t){return e.Math.min(atn(t.a,n.d.d.c),atn(t.b,n.d.d.c))}function z9(n,t){n._i(n.i+1),yD(n,n.i,n.Zi(n.i,t)),n.Mi(n.i++,t),n.Ni()}function V9(n){var t,e;++n.j,t=n.g,e=n.i,n.g=null,n.i=0,n.Oi(e,t),n.Ni()}function W9(n,t,e){var i;xun(i=new U$(n.a),n.a.a),VAn(i.f,t,e),n.a.a=i}function Q9(n,t,e,i){var r;for(r=0;r<$st;r++)qX(n.a[r][t.g],e,i[t.g])}function J9(n,t,e,i){var r;for(r=0;rt)throw hv(new dM(iLn(n,t,"index")));return n}function i7(n,t){var e;return u3(t,n.c.length),e=n.c[t],nE(n.c,t,1),e}function r7(n,t){var e,i;return tJ(n),e=n,tJ(t),e==(i=t)?0:et.p?-1:0}function E7(n){var t;return n.a||F$(t=n.r,156)&&(n.a=uG(t,156)),n.a}function S7(n,t,e){return++n.e,--n.f,uG(n.d[t].gd(e),136).md()}function P7(n){var t;return t=n.ld(),JU(uG(n.md(),16).Nc(),new Wl(t))}function C7(n,t){return!!PV(n.a,t)&&(u7(n.a,t),!0)}function I7(n,t,e){return q4(t,n.e.Rd().gc()),q4(e,n.c.Rd().gc()),n.a[t][e]}function O7(n,t,e){this.a=n,this.b=t,this.c=e,kD(n.t,this),kD(t.i,this)}function A7(n,t,e,i){this.f=n,this.e=t,this.d=e,this.b=i,this.c=i?i.d:null}function L7(){this.b=new lS,this.a=new lS,this.b=new lS,this.a=new lS}function N7(){var n,t;N7=E,vj(),t=new Gv,MBt=t,n=new Wk,TBt=n}function $7(n){return vgn(n),new IK(n,new lG(n,n.a.e,4|n.a.d))}function D7(n){var t;for(GQ(n),t=0;n.a.Bd(new hn);)t=Lgn(t,1);return t}function x7(n,t){return tJ(t),n.c=0,"Initial capacity must not be negative")}function K7(){K7=E,jNt=new Cm("org.eclipse.elk.labels.labelManager")}function F7(){F7=E,Uwt=new uF("separateLayerConnections",(Ghn(),zwt))}function _7(){_7=E,DSt=new qI("REGULAR",0),$St=new qI("CRITICAL",1)}function B7(){B7=E,nLt=new lO("FIXED",0),ZAt=new lO("CENTER_NODE",1)}function H7(){H7=E,Vdt=new WC("QUADRATIC",0),Wdt=new WC("SCANLINE",1)}function U7(){U7=E,egt=Abn((jan(),Uhn(cT(agt,1),p1n,322,0,[Zdt,Ydt,ngt])))}function G7(){G7=E,ogt=Abn((ran(),Uhn(cT(bgt,1),p1n,351,0,[igt,cgt,rgt])))}function q7(){q7=E,Cdt=Abn((gon(),Uhn(cT(Rdt,1),p1n,372,0,[Sdt,Edt,jdt])))}function X7(){X7=E,Tgt=Abn((Pfn(),Uhn(cT(Ogt,1),p1n,460,0,[kgt,vgt,ygt])))}function z7(){z7=E,wpt=Abn((ihn(),Uhn(cT(mpt,1),p1n,299,0,[fpt,lpt,hpt])))}function V7(){V7=E,vpt=Abn((Zen(),Uhn(cT(Mpt,1),p1n,311,0,[gpt,ppt,dpt])))}function W7(){W7=E,ljt=Abn((Cwn(),Uhn(cT(pjt,1),p1n,390,0,[ujt,sjt,hjt])))}function Q7(){Q7=E,iEt=Abn((isn(),Uhn(cT(oEt,1),p1n,387,0,[Zjt,nEt,tEt])))}function J7(){J7=E,uEt=Abn((Sln(),Uhn(cT(lEt,1),p1n,349,0,[aEt,rEt,cEt])))}function Y7(){Y7=E,Yjt=Abn((can(),Uhn(cT(eEt,1),p1n,463,0,[Qjt,Vjt,Wjt])))}function Z7(){Z7=E,bEt=Abn((kbn(),Uhn(cT(pEt,1),p1n,350,0,[sEt,hEt,fEt])))}function nnn(){nnn=E,mEt=Abn((ian(),Uhn(cT(MEt,1),p1n,352,0,[gEt,wEt,dEt])))}function tnn(){tnn=E,TEt=Abn((zhn(),Uhn(cT(xEt,1),p1n,388,0,[kEt,yEt,vEt])))}function enn(){enn=E,mPt=Abn((Pln(),Uhn(cT(RCt,1),p1n,392,0,[gPt,dPt,wPt])))}function inn(){inn=E,bIt=Abn((vbn(),Uhn(cT(nOt,1),p1n,393,0,[sIt,hIt,fIt])))}function rnn(){rnn=E,aOt=Abn((esn(),Uhn(cT(hOt,1),p1n,300,0,[iOt,rOt,eOt])))}function cnn(){cnn=E,fOt=Abn((Jmn(),Uhn(cT(dOt,1),p1n,445,0,[oOt,uOt,sOt])))}function ann(){ann=E,gOt=Abn((Zyn(),Uhn(cT(AOt,1),p1n,456,0,[lOt,wOt,bOt])))}function onn(){onn=E,LOt=Abn((Bgn(),Uhn(cT(kAt,1),p1n,394,0,[IOt,OOt,COt])))}function unn(){unn=E,IAt=Abn((den(),Uhn(cT(LAt,1),p1n,439,0,[EAt,PAt,SAt])))}function snn(){snn=E,GEt=Abn((ean(),Uhn(cT(qEt,1),p1n,464,0,[_Et,BEt,HEt])))}function hnn(){hnn=E,Dst=Abn((Ktn(),Uhn(cT(xst,1),p1n,471,0,[Ast,Ost,Lst])))}function fnn(){fnn=E,Cst=Abn((Yrn(),Uhn(cT(Ist,1),p1n,237,0,[jst,Est,Sst])))}function lnn(){lnn=E,Bst=Abn((Yen(),Uhn(cT(hht,1),p1n,472,0,[Fst,Kst,Rst])))}function bnn(){bnn=E,xut=Abn((ybn(),Uhn(cT(Rut,1),p1n,108,0,[Cut,Iut,Out])))}function wnn(){wnn=E,vlt=Abn((Jen(),Uhn(cT(Clt,1),p1n,391,0,[glt,dlt,plt])))}function dnn(){dnn=E,Nxt=Abn((Own(),Uhn(cT(Kxt,1),p1n,346,0,[Oxt,Ixt,Axt])))}function gnn(){gnn=E,XAt=Abn((Rdn(),Uhn(cT(VAt,1),p1n,444,0,[HAt,UAt,GAt])))}function pnn(){pnn=E,oxt=Abn((Zrn(),Uhn(cT(lxt,1),p1n,278,0,[ixt,rxt,cxt])))}function mnn(){mnn=E,dKt=Abn((Iwn(),Uhn(cT(mKt,1),p1n,280,0,[lKt,fKt,bKt])))}function vnn(n,t){return!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),ymn(n.o,t)}function knn(n,t){var e;n.C&&((e=uG(AJ(n.b,t),127).n).d=n.C.d,e.a=n.C.a)}function ynn(n){var t,e,i,r;r=n.d,t=n.a,e=n.b,i=n.c,n.d=e,n.a=i,n.b=r,n.c=t}function Mnn(n){return!n.g&&(n.g=new ds),!n.g.b&&(n.g.b=new Om(n)),n.g.b}function Tnn(n){return!n.g&&(n.g=new ds),!n.g.c&&(n.g.c=new Nm(n)),n.g.c}function jnn(n){return!n.g&&(n.g=new ds),!n.g.d&&(n.g.d=new Am(n)),n.g.d}function Enn(n){return!n.g&&(n.g=new ds),!n.g.a&&(n.g.a=new Lm(n)),n.g.a}function Snn(n,t,e,i){return e&&(i=e.Rh(t,emn(e.Dh(),n.c.uk()),null,i)),i}function Pnn(n,t,e,i){return e&&(i=e.Th(t,emn(e.Dh(),n.c.uk()),null,i)),i}function Cnn(n,t,e,i){var r;return KGn(r=Inn(YHt,W1n,28,t+1,15,1),n,t,e,i),r}function Inn(n,t,e,i,r,c){var a;return a=PTn(r,i),10!=r&&Uhn(cT(n,c),t,e,r,a),a}function Onn(n,t,e){var i,r;for(r=new Zsn(t,n),i=0;ie||t=0?n.Lh(e,!0,!0):YNn(n,t,!0)}function ktn(n,t,e){var i;return i=Ufn(n,t,e),n.b=new Don(i.c.length),ZFn(n,i)}function ytn(n){if(n.b<=0)throw hv(new Bv);return--n.b,n.a-=n.c.c,xwn(n.a)}function Mtn(n){var t;if(!n.a)throw hv(new EY);return t=n.a,n.a=R0(n.a),t}function Ttn(n){for(;!n.a;)if(!y_(n.c,new yd(n)))return!1;return!0}function jtn(n){return WW(n),F$(n,204)?uG(n,204):new sb(n)}function Etn(n){Stn(),uG(n.of((XYn(),bDt)),181).Fc((eNn(),dRt)),n.qf(lDt,null)}function Stn(){Stn=E,tNt=new hu,iNt=new fu,eNt=Rln((XYn(),lDt),tNt,q$t,iNt)}function Ptn(){Ptn=E,cIt=new nO("LEAF_NUMBER",0),aIt=new nO("NODE_SIZE",1)}function Ctn(n){n.a=Inn(YHt,W1n,28,n.b+1,15,1),n.c=Inn(YHt,W1n,28,n.b,15,1),n.d=0}function Itn(n,t){n.a.Ne(t.d,n.b)>0&&(kD(n.c,new wG(t.c,t.d,n.d)),n.b=t.d)}function Otn(n,t){if(null==n.g||t>=n.i)throw hv(new pL(t,n.i));return n.g[t]}function Atn(n,t,e){if(gln(n,e),null!=e&&!n.fk(e))throw hv(new Nv);return e}function Ltn(n,t){return 10!=Min(t)&&Uhn(Tbn(t),t.Sm,t.__elementTypeId$,Min(t),n),n}function Ntn(n,t,e,i){sZ(),i=i||Jot,rLn(n.slice(t,e),n,t,e,-t,i)}function $tn(n,t,e,i,r){return t<0?YNn(n,e,i):uG(e,69).wk().yk(n,n.hi(),t,i,r)}function Dtn(n,t){return ugn(uM(pK(oIn(n,(GYn(),bmt)))),uM(pK(oIn(t,bmt))))}function xtn(){xtn=E,Mut=Abn((Rtn(),Uhn(cT(Tut,1),p1n,304,0,[put,mut,vut,kut])))}function Rtn(){Rtn=E,put=new qP("All",0),mut=new SN,vut=new P$,kut=new EN}function Ktn(){Ktn=E,Ast=new aC(z2n,0),Ost=new aC(G2n,1),Lst=new aC(V2n,2)}function Ftn(){Ftn=E,tXn(),sHt=M0n,uHt=T0n,fHt=new Rw(M0n),hHt=new Rw(T0n)}function _tn(){_tn=E,vht=Abn((ehn(),Uhn(cT(jht,1),p1n,417,0,[pht,wht,dht,ght])))}function Btn(){Btn=E,Rht=Abn((myn(),Uhn(cT(Fht,1),p1n,406,0,[Nht,Lht,$ht,Dht])))}function Htn(){Htn=E,Eht=Abn((vyn(),Uhn(cT(Sht,1),p1n,332,0,[yht,kht,Mht,Tht])))}function Utn(){Utn=E,ibt=Abn((Uvn(),Uhn(cT(abt,1),p1n,389,0,[tbt,Zlt,Ylt,nbt])))}function Gtn(){Gtn=E,Glt=Abn((Xhn(),Uhn(cT(ebt,1),p1n,416,0,[Flt,Hlt,_lt,Blt])))}function qtn(){qtn=E,ldt=Abn((qhn(),Uhn(cT(mdt,1),p1n,421,0,[odt,udt,sdt,hdt])))}function Xtn(){Xtn=E,Wwt=Abn((Ghn(),Uhn(cT(adt,1),p1n,371,0,[zwt,qwt,Xwt,Gwt])))}function ztn(){ztn=E,mjt=Abn((Yyn(),Uhn(cT(jjt,1),p1n,203,0,[djt,gjt,wjt,bjt])))}function Vtn(){Vtn=E,Ujt=Abn((yvn(),Uhn(cT(Xjt,1),p1n,284,0,[Fjt,Kjt,_jt,Bjt])))}function Wtn(){Wtn=E,Ngt=new iI(q4n,0),Lgt=new iI("IMPROVE_STRAIGHTNESS",1)}function Qtn(n,t){var e,i;return i=t/n.c.Rd().gc()|0,e=t%n.c.Rd().gc(),I7(n,i,e)}function Jtn(n){var t;if(n.nl())for(t=n.i-1;t>=0;--t)zrn(n,t);return g5(n)}function Ytn(n){var t,e;if(!n.b)return null;for(e=n.b;t=e.a[0];)e=t;return e}function Ztn(n){var t,e;if(!n.b)return null;for(e=n.b;t=e.a[1];)e=t;return e}function nen(n){return F$(n,180)?""+uG(n,180).a:null==n?null:cpn(n)}function ten(n){return F$(n,180)?""+uG(n,180).a:null==n?null:cpn(n)}function een(n,t){if(t.a)throw hv(new Ky(p2n));FV(n.a,t),t.a=n,!n.j&&(n.j=t)}function ien(n,t){rL.call(this,t.zd(),-16449&t.yd()),tJ(n),this.a=n,this.c=t}function ren(n,t){return new LU(t,KR(D$(t.e),t.f.a+n,t.f.b+n),(qx(),!1))}function cen(n,t){return PU(),kD(n,new WO(t,xwn(t.e.c.length+t.g.c.length)))}function aen(n,t){return PU(),kD(n,new WO(t,xwn(t.e.c.length+t.g.c.length)))}function oen(){oen=E,tOt=Abn((dTn(),Uhn(cT(cOt,1),p1n,354,0,[ZIt,JIt,YIt,QIt])))}function uen(){uen=E,KCt=Abn((mbn(),Uhn(cT(BCt,1),p1n,353,0,[xCt,$Ct,DCt,NCt])))}function sen(){sen=E,YSt=Abn((Cjn(),Uhn(cT(ZSt,1),p1n,405,0,[zSt,VSt,WSt,QSt])))}function hen(){hen=E,bxt=Abn((_gn(),Uhn(cT(kxt,1),p1n,223,0,[fxt,sxt,uxt,hxt])))}function fen(){fen=E,Fxt=Abn((Ajn(),Uhn(cT(Wxt,1),p1n,291,0,[Rxt,$xt,Dxt,xxt])))}function len(){len=E,ZRt=Abn((Qmn(),Uhn(cT(sKt,1),p1n,386,0,[QRt,JRt,WRt,VRt])))}function ben(){ben=E,EKt=Abn((qpn(),Uhn(cT(SKt,1),p1n,320,0,[TKt,kKt,MKt,yKt])))}function wen(){wen=E,LKt=Abn((Eln(),Uhn(cT(DKt,1),p1n,415,0,[CKt,IKt,PKt,OKt])))}function den(){den=E,EAt=new uO(g7n,0),PAt=new uO(k9n,1),SAt=new uO(q4n,2)}function gen(n,t,e,i,r){return tJ(n),tJ(t),tJ(e),tJ(i),tJ(r),new WV(n,t,i)}function pen(n,t){var e;return(e=uG(u7(n.e,t),400))?(cq(e),e.e):null}function men(n,t){var e;return-1!=(e=Ten(n,t,0))&&(i7(n,e),!0)}function ven(n,t,e){var i;return GQ(n),(i=new un).a=t,n.a.Nb(new nC(i,e)),i.a}function ken(n){var t;return GQ(n),t=Inn(eUt,I0n,28,0,15,1),tE(n.a,new md(t)),t}function yen(n){var t;if(!oon(n))throw hv(new Bv);return n.e=1,t=n.d,n.d=null,t}function Men(n){var t;return _L(n)&&(t=0-n,!isNaN(t))?t:Esn(gfn(n))}function Ten(n,t,e){for(;e=0?Dyn(n,e,!0,!0):YNn(n,t,!0)}function Ven(n){var t;return null==(t=Kcn(Lsn(n,32)))&&($vn(n),t=Kcn(Lsn(n,32))),t}function Wen(n){var t;return n.Oh()||(t=iQ(n.Dh())-n.ji(),n.$h().Mk(t)),n.zh()}function Qen(n,t){Iht=new et,xht=t,uG((Cht=n).b,68),Rnn(Cht,Iht,null),Szn(Cht)}function Jen(){Jen=E,glt=new dC("XY",0),dlt=new dC("X",1),plt=new dC("Y",2)}function Yen(){Yen=E,Fst=new oC("TOP",0),Kst=new oC(G2n,1),Rst=new oC(Q2n,2)}function Zen(){Zen=E,gpt=new uI(q4n,0),ppt=new uI("TOP",1),dpt=new uI(Q2n,2)}function nin(){nin=E,Gjt=new pI("INPUT_ORDER",0),qjt=new pI("PORT_DEGREE",1)}function tin(){tin=E,Jat=p$(f0n,f0n,524287),Yat=p$(0,0,b0n),Zat=_9(1),_9(2),not=_9(0)}function ein(n){var t;return n.d!=n.r&&(t=bEn(n),n.e=!!t&&t.lk()==srt,n.d=t),n.e}function iin(n,t,e){var i;return i=n.g[t],yD(n,t,n.Zi(t,e)),n.Ri(t,e,i),n.Ni(),i}function rin(n,t){var e;return(e=n.dd(t))>=0&&(n.gd(e),!0)}function cin(n,t){var e;for(WW(n),WW(t),e=!1;t.Ob();)e|=n.Fc(t.Pb());return e}function ain(n,t){var e;return(e=uG(cQ(n.e,t),400))?(nD(n,e),e.e):null}function oin(n){var t,e;return t=n/60|0,0==(e=n%60)?""+t:t+":"+e}function uin(n,t){var e=n.a[t],i=(Cfn(),Wat)[typeof e];return i?i(e):Vbn(typeof e)}function sin(n,t){return vgn(n),new fX(n,new D_(new f7(t,n.a)))}function hin(n){var t;return null!=(t=0==n.b.c.length?null:zq(n.b,0))&&Con(n,0),t}function fin(n,t){var e,i,r;r=t.c.i,i=(e=uG(cQ(n.f,r),60)).d.c-e.e.c,fun(t.a,i,0)}function lin(n,t){var e;for(++n.d,++n.c[t],e=t+1;e=0;)++t[0]}function din(n,t){ycn(n,null==t||J_((tJ(t),t))||isNaN((tJ(t),t))?0:(tJ(t),t))}function gin(n,t){Mcn(n,null==t||J_((tJ(t),t))||isNaN((tJ(t),t))?0:(tJ(t),t))}function pin(n,t){kcn(n,null==t||J_((tJ(t),t))||isNaN((tJ(t),t))?0:(tJ(t),t))}function min(n,t){vcn(n,null==t||J_((tJ(t),t))||isNaN((tJ(t),t))?0:(tJ(t),t))}function vin(n,t,e){return bD(new MO(e.e.a+e.f.a/2,e.e.b+e.f.b/2),n)==(tJ(t),t)}function kin(n,t){return F$(t,102)&&uG(t,19).Bb&P0n?new yL(t,n):new Zsn(t,n)}function yin(n,t){return F$(t,102)&&uG(t,19).Bb&P0n?new yL(t,n):new Zsn(t,n)}function Min(n){return null==n.__elementTypeCategory$?10:n.__elementTypeCategory$}function Tin(n,t){return t==(cB(),cB(),uut)?n.toLocaleLowerCase():n.toLowerCase()}function jin(n){if(!n.e)throw hv(new Bv);return n.c=n.a=n.e,n.e=n.e.e,--n.d,n.a.f}function Ein(n){if(!n.c)throw hv(new Bv);return n.e=n.a=n.c,n.c=n.c.c,++n.d,n.a.f}function Sin(n){var t;for(++n.a,t=n.c.a.length;n.an.a[i]&&(i=e);return i}function Lin(n){var t;return!!(t=uG(oIn(n,(GYn(),Spt)),313))&&t.a==n}function Nin(n){var t;return!!(t=uG(oIn(n,(GYn(),Spt)),313))&&t.i==n}function $in(){$in=E,Ilt=Abn((uIn(),Uhn(cT(Llt,1),p1n,367,0,[Tlt,jlt,Elt,Slt,Plt])))}function Din(){Din=E,vdt=Abn((gPn(),Uhn(cT(Pdt,1),p1n,375,0,[wdt,gdt,pdt,ddt,bdt])))}function xin(){xin=E,wgt=Abn((kvn(),Uhn(cT(pgt,1),p1n,348,0,[sgt,ugt,fgt,lgt,hgt])))}function Rin(){Rin=E,Ejt=Abn((pyn(),Uhn(cT(xjt,1),p1n,323,0,[Tjt,kjt,yjt,vjt,Mjt])))}function Kin(){Kin=E,$mt=Abn((Gpn(),Uhn(cT(ajt,1),p1n,171,0,[Lmt,Cmt,Imt,Omt,Amt])))}function Fin(){Fin=E,rIt=Abn((zPn(),Uhn(cT(oIt,1),p1n,368,0,[tIt,YCt,eIt,ZCt,nIt])))}function _in(){_in=E,BAt=Abn((_Rn(),Uhn(cT(qAt,1),p1n,373,0,[xAt,DAt,KAt,RAt,FAt])))}function Bin(){Bin=E,sLt=Abn((pOn(),Uhn(cT(qLt,1),p1n,324,0,[iLt,rLt,oLt,cLt,aLt])))}function Hin(){Hin=E,ext=Abn((xdn(),Uhn(cT(axt,1),p1n,88,0,[ZDt,YDt,JDt,QDt,nxt])))}function Uin(){Uin=E,bNt=Abn((Rkn(),Uhn(cT(MNt,1),p1n,170,0,[hNt,sNt,oNt,fNt,uNt])))}function Gin(){Gin=E,iRt=Abn((Vkn(),Uhn(cT(hRt,1),p1n,256,0,[Zxt,tRt,Jxt,Yxt,nRt])))}function qin(){qin=E,HRt=Abn((KQn(),Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt])))}function Xin(){Xin=E,Yut=new iC("BY_SIZE",0),Zut=new iC("BY_SIZE_AND_SHAPE",1)}function zin(){zin=E,gft=new wC("EADES",0),pft=new wC("FRUCHTERMAN_REINGOLD",1)}function Vin(){Vin=E,dgt=new nI("READING_DIRECTION",0),ggt=new nI("ROTATION",1)}function Win(){Win=E,zlt=new Pt,Vlt=new At,qlt=new Lt,Xlt=new Ot,Wlt=new Nt}function Qin(n){this.b=new Zm,this.a=new Zm,this.c=new Zm,this.d=new Zm,this.e=n}function Jin(n){this.g=n,this.f=new Zm,this.a=e.Math.min(this.g.c.c,this.g.d.c)}function Yin(n,t,e){HF.call(this),Qrn(this),this.a=n,this.c=e,this.b=t.d,this.f=t.e}function Zin(n,t,e){var i;for(i=new Ww(e);i.a=0&&t0?t-1:t,lj(bj(xcn(xG(new fy,e),n.n),n.j),n.k)}function rrn(n){var t;t=new Yk,ttn((!n.q&&(n.q=new fV(p_t,n,11,10)),n.q),t)}function crn(n){return(2&n.i?"interface ":1&n.i?"":"class ")+(vK(n),n.o)}function arn(n){return dwn(n,vZn)>0?vZn:dwn(n,j1n)<0?j1n:pz(n)}function orn(n){return n<3?(man(n,b1n),n+1):n=-.01&&n.a<=Z2n&&(n.a=0),n.b>=-.01&&n.b<=Z2n&&(n.b=0),n}function Trn(n){var t,e;for(l_n(),e=G9n,t=0;te&&(e=n[t]);return e}function jrn(n,t){var e;if(!(e=EKn(n.Dh(),t)))throw hv(new vM(Gtt+t+ztt));return e}function Ern(n,t){var e;for(e=n;R0(e);)if((e=R0(e))==t)return!0;return!1}function Srn(n,t){var e,i,r;for(i=t.a.ld(),e=uG(t.a.md(),16).gc(),r=0;rn||n>t)throw hv(new YM("fromIndex: 0, toIndex: "+n+Q0n+t))}function Drn(n){if(n<0)throw hv(new vM("Illegal Capacity: "+n));this.g=this.aj(n)}function xrn(n,t){return YN(),oan(T1n),e.Math.abs(n-t)<=T1n||n==t||isNaN(n)&&isNaN(t)}function Rrn(n,t){var e,i,r,c;for(r=0,c=(i=n.d).length;r0&&(n.a/=t,n.b/=t),n}function Hrn(n){var t;return n.w?n.w:((t=O3(n))&&!t.Vh()&&(n.w=t),t)}function Urn(n,t){var e,i;i=n.a,e=kdn(n,t,null),i!=t&&!n.e&&(e=PWn(n,t,e)),e&&e.oj()}function Grn(n,t,e){var i,r;i=t;do{r=uM(n.p[i.p])+e,n.p[i.p]=r,i=n.a[i.p]}while(i!=t)}function qrn(n,t,e){var i=function(){return n.apply(i,arguments)};return t.apply(i,e),i}function Xrn(n){var t;return null==n?null:NCn(t=uG(n,195),t.length)}function zrn(n,t){if(null==n.g||t>=n.i)throw hv(new pL(t,n.i));return n.Wi(t,n.g[t])}function Vrn(n,t){var e,i;for(hZ(),i=new Zm,e=0;e=14&&t<=16)),n}function Fcn(n,t){var e;return tJ(t),vG(!!(e=n[":"+t]),"Enum constant undefined: "+t),e}function _cn(n,t,e,i,r,c){var a;return Rcn(e,a=VW(n,t)),a.i=r?8:0,a.f=i,a.e=r,a.g=c,a}function Bcn(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=1,this.c=n,this.a=e}function Hcn(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=2,this.c=n,this.a=e}function Ucn(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=6,this.c=n,this.a=e}function Gcn(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=7,this.c=n,this.a=e}function qcn(n,t,e,i,r){this.d=t,this.j=i,this.e=r,this.o=-1,this.p=4,this.c=n,this.a=e}function Xcn(n,t){var e,i,r,c;for(r=0,c=(i=t).length;r=0))throw hv(new vM("tolerance ("+n+") must be >= 0"));return n}function uan(n,t){var e;return F$(t,44)?n.c.Mc(t):(e=ymn(n,t),Svn(n,t),e)}function san(n,t,e){return Kbn(n,t),qon(n,e),Pcn(n,0),Ccn(n,1),mdn(n,!0),ddn(n,!0),n}function han(n,t){var e;if(e=n.gc(),t<0||t>e)throw hv(new w_(t,e));return new N_(n,t)}function fan(n,t){n.b=e.Math.max(n.b,t.d),n.e+=t.r+(0==n.a.c.length?0:n.c),kD(n.a,t)}function lan(n){TK(n.c>=0),Rvn(n.d,n.c)<0&&(n.a=n.a-1&n.d.a.length-1,n.b=n.d.c),n.c=-1}function ban(n){var t;for(t=n.c.Cc().Kc();t.Ob();)uG(t.Pb(),16).$b();n.c.$b(),n.d=0}function wan(n){var t,e,i,r;for(i=0,r=(e=n.a).length;i=0}function Ban(n,t){n.r>0&&n.c0&&0!=n.g&&Ban(n.i,t/n.r*n.i.d))}function Han(n,t){var e;e=n.c,n.c=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,1,e,n.c))}function Uan(n,t){var e;e=n.c,n.c=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,4,e,n.c))}function Gan(n,t){var e;e=n.k,n.k=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,2,e,n.k))}function qan(n,t){var e;e=n.D,n.D=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,2,e,n.D))}function Xan(n,t){var e;e=n.f,n.f=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,8,e,n.f))}function zan(n,t){var e;e=n.i,n.i=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,7,e,n.i))}function Van(n,t){var e;e=n.a,n.a=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,8,e,n.a))}function Wan(n,t){var e;e=n.b,n.b=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,0,e,n.b))}function Qan(n,t){var e;e=n.b,n.b=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,0,e,n.b))}function Jan(n,t){var e;e=n.c,n.c=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,1,e,n.c))}function Yan(n,t){var e;e=n.d,n.d=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,1,e,n.d))}function Zan(n,t,e){var i;n.b=t,n.a=e,i=512&~n.a?new $f:new ay,n.c=qFn(i,n.b,n.a)}function non(n,t){return EFn(n.e,t)?(PP(),ein(t)?new Cq(t,n):new OA(t,n)):new PA(t,n)}function ton(n){return 0>n?new mS:new OK(null,new i9(n+1,n))}function eon(n,t){var e;return hZ(),e=new sS(1),RA(n)?r2(e,n,t):VAn(e.f,n,t),new Vw(e)}function ion(n,t){var e,i;return e=n.c,(i=t.e[n.p])>0?uG(zq(e.a,i-1),10):null}function ron(n,t){var e,i;return(e=n.o+n.p)<(i=t.o+t.p)?-1:e==i?0:1}function con(n){var t;return F$(t=oIn(n,(GYn(),rmt)),167)?Qpn(uG(t,167)):null}function aon(n){var t;return(n=e.Math.max(n,2))>(t=pfn(n))?(t<<=1)>0?t:d1n:t}function oon(n){switch(_D(3!=n.e),n.e){case 2:return!1;case 0:return!0}return a7(n)}function uon(n,t){var e;return!!F$(t,8)&&(e=uG(t,8),n.a==e.a&&n.b==e.b)}function son(n,t){var e;e=new et,uG(t.b,68),uG(t.b,68),uG(t.b,68),Prn(t.a,new $U(n,e,t))}function hon(n,t){var e,i;for(i=t.vc().Kc();i.Ob();)rSn(n,(e=uG(i.Pb(),44)).ld(),e.md())}function fon(n,t){var e;e=n.d,n.d=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,11,e,n.d))}function lon(n,t){var e;e=n.j,n.j=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,13,e,n.j))}function bon(n,t){var e;e=n.b,n.b=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,21,e,n.b))}function won(n,t){0==(t9(),Nut?null:t.c).length&&RK(t,new G),r2(n.a,Nut?null:t.c,t)}function don(n,t){t.Ug("Hierarchical port constraint processing",1),ayn(n),yYn(n),t.Vg()}function gon(){gon=E,Sdt=new VC("START",0),Edt=new VC("MIDDLE",1),jdt=new VC("END",2)}function pon(){pon=E,VCt=new YI("P1_NODE_PLACEMENT",0),WCt=new YI("P2_EDGE_ROUTING",1)}function mon(){mon=E,Wft=new Cm(E4n),Qft=new Cm(S4n),Vft=new Cm(P4n),zft=new Cm(C4n)}function von(n){var t;return OB(n.f.g,n.d),MK(n.b),n.c=n.a,t=uG(n.a.Pb(),44),n.b=Phn(n),t}function kon(n){return null==n.b?(EP(),EP(),eBt):n.ul()?n.tl():n.sl()}function yon(n,t){var e;return!((e=null==t?-1:Ten(n.b,t,0))<0||(Con(n,e),0))}function Mon(n,t){var e;return tJ(t),e=t.g,!n.b[e]&&(uQ(n.b,e,t),++n.c,!0)}function Ton(n,t){var e,i;return e=1-t,i=n.a[e],n.a[e]=i.a[t],i.a[t]=n,n.b=!0,i.b=!1,i}function jon(n,t){var e,i;for(i=t.Kc();i.Ob();)e=uG(i.Pb(),272),n.b=!0,FV(n.e,e),e.b=n}function Eon(n,t){var e,i;return e=uG(oIn(n,(jYn(),rTt)),8),i=uG(oIn(t,rTt),8),ugn(e.b,i.b)}function Son(n,t,e){var i,r;return r=t>>5,i=31&t,E3(Dz(n.n[e][r],pz(Nz(i,1))),3)}function Pon(n,t,e){var i,r,c;for(c=n.a.length-1,r=n.b,i=0;i0?1:0:(!n.c&&(n.c=j2(Bsn(n.f))),n.c).e}function tun(n,t){t?null==n.B&&(n.B=n.D,n.D=null):null!=n.B&&(n.D=n.B,n.B=null)}function eun(n,t){return Xhn(),n==Flt&&t==Hlt||n==Hlt&&t==Flt||n==Blt&&t==_lt||n==_lt&&t==Blt}function iun(n,t){return Xhn(),n==Flt&&t==_lt||n==Flt&&t==Blt||n==Hlt&&t==Blt||n==Hlt&&t==_lt}function run(n,t){return YN(),oan(Z2n),e.Math.abs(0-t)<=Z2n||0==t||isNaN(0)&&isNaN(t)?0:n/t}function cun(n,t){return uM(pK(yx(cdn(YJ(new fX(null,new h3(n.c.b,16)),new _g(n)),t))))}function aun(n,t){return uM(pK(yx(cdn(YJ(new fX(null,new h3(n.c.b,16)),new Fg(n)),t))))}function oun(){return r_n(),Uhn(cT(bpt,1),p1n,259,0,[Zgt,tpt,ept,ipt,rpt,cpt,opt,Ygt,npt,apt])}function uun(){return THn(),Uhn(cT(Hjt,1),p1n,243,0,[$jt,Ijt,Ljt,Ojt,Ajt,Sjt,Njt,Djt,Pjt,Cjt])}function sun(n,t){t.Ug("General Compactor",1),Bpn(uG(zDn(n,(jOn(),LIt)),393)).Cg(n)}function hun(n,t){var e,i;return e=uG(zDn(n,(jOn(),FIt)),17),i=uG(zDn(t,FIt),17),d$(e.a,i.a)}function fun(n,t,e){var i,r;for(r=Fkn(n,0);r.b!=r.d.c;)(i=uG(I6(r),8)).a+=t,i.b+=e;return n}function lun(n,t,e){var i;for(i=n.b[e&n.f];i;i=i.b)if(e==i.a&&xQ(t,i.g))return i;return null}function bun(n,t,e){var i;for(i=n.c[e&n.f];i;i=i.d)if(e==i.f&&xQ(t,i.i))return i;return null}function wun(n,t,e){var i,r,c;for(i=0,r=0;r>>31;0!=i&&(n[e]=i)}function dun(n,t,e,i,r,c){var a;this.c=n,tTn(n,a=new Zm,t,n.b,e,i,r,c),this.a=new N4(a,0)}function gun(){this.c=new Vj(0),this.b=new Vj(F9n),this.d=new Vj(K9n),this.a=new Vj(_3n)}function pun(n,t,e,i,r,c,a){_E.call(this,n,t),this.d=e,this.e=i,this.c=r,this.b=c,this.a=n7(a)}function mun(n,t,e,i,r,c,a,o,u,s,h,f,l){return eLn(n,t,e,i,r,c,a,o,u,s,h,f,l),Sgn(n,!1),n}function vun(n){return n.b.c.i.k==(zIn(),lbt)?uG(oIn(n.b.c.i,(GYn(),rmt)),12):n.b.c}function kun(n){return n.b.d.i.k==(zIn(),lbt)?uG(oIn(n.b.d.i,(GYn(),rmt)),12):n.b.d}function yun(n){var t;return _A((t=t6(n)).a,0)?(gS(),gS(),fut):(gS(),new dR(t.b))}function Mun(n){var t;return _A((t=Z4(n)).a,0)?(dS(),dS(),hut):(dS(),new wR(t.b))}function Tun(n){var t;return _A((t=Z4(n)).a,0)?(dS(),dS(),hut):(dS(),new wR(t.c))}function jun(n){switch(n.g){case 2:return KQn(),_Rt;case 4:return KQn(),kRt;default:return n}}function Eun(n){switch(n.g){case 1:return KQn(),KRt;case 3:return KQn(),yRt;default:return n}}function Sun(n){switch(n.g){case 0:return new Wo;case 1:return new Qo;default:return null}}function Pun(){Pun=E,Hwt=new uF("edgelabelcenterednessanalysis.includelabel",(qx(),tot))}function Cun(){Cun=E,FEt=Lvn(gL(Aq(Aq(new wJ,(uIn(),Elt),(zYn(),kwt)),Slt,hwt),Plt),vwt)}function Iun(){Iun=E,XEt=Lvn(gL(Aq(Aq(new wJ,(uIn(),Elt),(zYn(),kwt)),Slt,hwt),Plt),vwt)}function Oun(){Oun=E,V_t=new Qk,Q_t=Uhn(cT(o_t,1),krt,179,0,[]),W_t=Uhn(cT(p_t,1),yrt,62,0,[])}function Aun(){Aun=E,Obt=new PC("TO_INTERNAL_LTR",0),Ibt=new PC("TO_INPUT_DIRECTION",1)}function Lun(){Lun=E,Tbt=new Bt,ybt=new Ht,Mbt=new Ut,kbt=new Gt,jbt=new qt,Ebt=new Xt}function Nun(n,t){t.Ug(g6n,1),Apn(FS(new Ad((zS(),new mY(n,!1,!1,new Ft))))),t.Vg()}function $un(n,t,e){e.Ug("DFS Treeifying phase",1),qmn(n,t),qKn(n,t),n.a=null,n.b=null,e.Vg()}function Dun(n,t){return qx(),RA(n)?r7(n,mK(t)):FA(n)?Rz(n,pK(t)):KA(n)?xz(n,gK(t)):n.Fd(t)}function xun(n,t){var e,i;for(tJ(t),i=t.vc().Kc();i.Ob();)e=uG(i.Pb(),44),n.zc(e.ld(),e.md())}function Run(n,t,e){var i;for(i=e.Kc();i.Ob();)if(!H5(n,t,i.Pb()))return!1;return!0}function Kun(n,t,e,i,r){var c;return e&&(c=emn(t.Dh(),n.c),r=e.Rh(t,-1-(-1==c?i:c),null,r)),r}function Fun(n,t,e,i,r){var c;return e&&(c=emn(t.Dh(),n.c),r=e.Th(t,-1-(-1==c?i:c),null,r)),r}function _un(n){var t;if(-2==n.b){if(0==n.e)t=-1;else for(t=0;0==n.a[t];t++);n.b=t}return n.b}function Bun(n){if(tJ(n),0==n.length)throw hv(new ZM("Zero length BigInteger"));XHn(this,n)}function Hun(n){this.i=n.gc(),this.i>0&&(this.g=this.aj(this.i+(this.i/8|0)+1),n.Qc(this.g))}function Uun(n,t,e){this.g=n,this.d=t,this.e=e,this.a=new Zm,RLn(this),hZ(),f$(this.a,null)}function Gun(n,t){t.q=n,n.d=e.Math.max(n.d,t.r),n.b+=t.d+(0==n.a.c.length?0:n.c),kD(n.a,t)}function qun(n,t){var e,i,r,c;return r=n.c,e=n.c+n.b,c=n.d,i=n.d+n.a,t.a>r&&t.ac&&t.b(r=n.a.length)?e=r:s3(t,e+1),n.a=r1(n.a,0,t)+""+i+sQ(n.a,e)}function msn(n,t){n.a=Lgn(n.a,1),n.c=e.Math.min(n.c,t),n.b=e.Math.max(n.b,t),n.d=Lgn(n.d,t)}function vsn(n,t){return t1||n.Ob())return++n.a,n.g=0,t=n.i,n.Ob(),t;throw hv(new Bv)}function Fsn(n){switch(n.a.g){case 1:return new KI;case 3:return new zTn;default:return new ml}}function _sn(n,t){switch(t){case 1:return!!n.n&&0!=n.n.i;case 2:return null!=n.k}return j4(n,t)}function Bsn(n){return p0n>22),r=n.h+t.h+(i>>22),p$(e&f0n,i&f0n,r&l0n)}function Thn(n,t){var e,i,r;return e=n.l-t.l,i=n.m-t.m+(e>>22),r=n.h-t.h+(i>>22),p$(e&f0n,i&f0n,r&l0n)}function jhn(n){var t,e;for(BQn(n),e=new Ww(n.d);e.a(i=n.gc()))throw hv(new w_(t,i));return n.Si()&&(e=A0(n,e)),n.Ei(t,e)}function wfn(n,t,e,i,r){var c,a;for(a=e;a<=r;a++)for(c=t;c<=i;c++)eTn(n,c,a)||HBn(n,c,a,!0,!1)}function dfn(n){var t,e,i;for(l_n(),e=Inn(PNt,zZn,8,2,0,1),i=0,t=0;t<2;t++)i+=.5,e[t]=WMn(i,n);return e}function gfn(n){var t,e;return p$(t=1+~n.l&f0n,e=~n.m+(0==t?1:0)&f0n,~n.h+(0==t&&0==e?1:0)&l0n)}function pfn(n){var t;if(n<0)return j1n;if(0==n)return 0;for(t=d1n;!(t&n);t>>=1);return t}function mfn(n,t,e){return!(n>=128)&&HA(n<64?E3(Nz(1,n),e):E3(Nz(1,n-64),t),0)}function vfn(n,t,e){return null==e?(!n.q&&(n.q=new Ym),u7(n.q,t)):(!n.q&&(n.q=new Ym),vJ(n.q,t,e)),n}function kfn(n,t,e){return null==e?(!n.q&&(n.q=new Ym),u7(n.q,t)):(!n.q&&(n.q=new Ym),vJ(n.q,t,e)),n}function yfn(n){var t,e;return zsn(e=new d7,n),kfn(e,(mon(),Wft),n),kqn(n,e,t=new Ym),zWn(n,e,t),e}function Mfn(n){var t,e;return t=n.t-n.k[n.o.p]*n.d+n.j[n.o.p]>n.f,e=n.u+n.e[n.o.p]*n.d>n.f*n.s*n.d,t||e}function Tfn(n,t){var e,i,r;for(e=!1,i=n.a[t].length,r=0;r=0,"Negative initial capacity"),vG(t>=0,"Non-positive load factor"),$V(this)}function $fn(n,t,e,i,r){var c,a;if(a=n.length,c=e.length,t<0||i<0||r<0||t+r>a||i+r>c)throw hv(new Lv)}function Dfn(n,t){var e,i,r,c,a;for(hZ(),a=!1,r=0,c=(i=t).length;r1||t>=0&&n.b<3)}function Yfn(n){var t,e,i;t=1+~n.l&f0n,e=~n.m+(0==t?1:0)&f0n,i=~n.h+(0==t&&0==e?1:0)&l0n,n.l=t,n.m=e,n.h=i}function Zfn(n){var t,e,i;for(hZ(),i=1,e=n.Kc();e.Ob();)i=31*i+(null!=(t=e.Pb())?Hon(t):0),i|=0;return i}function nln(n,t,e,i,r){var c;return c=gDn(n,t),e&&Yfn(c),r&&(n=hTn(n,t),Qat=i?gfn(n):p$(n.l,n.m,n.h)),c}function tln(n,t,e){n.g=mAn(n,t,(KQn(),kRt),n.b),n.d=mAn(n,e,kRt,n.b),0!=n.g.c&&0!=n.d.c&&AIn(n)}function eln(n,t,e){n.g=mAn(n,t,(KQn(),_Rt),n.j),n.d=mAn(n,e,_Rt,n.j),0!=n.g.c&&0!=n.d.c&&AIn(n)}function iln(n,t){switch(t){case 7:return!!n.e&&0!=n.e.i;case 8:return!!n.d&&0!=n.d.i}return Kpn(n,t)}function rln(n,t){switch(t.g){case 0:F$(n.b,641)||(n.b=new lsn);break;case 1:F$(n.b,642)||(n.b=new zG)}}function cln(n){if(0===n.g)return new eu;throw hv(new vM(lnt+(null!=n.f?n.f:""+n.g)))}function aln(n){if(0===n.g)return new nu;throw hv(new vM(lnt+(null!=n.f?n.f:""+n.g)))}function oln(n,t,e){return!Qj(JJ(new fX(null,new h3(n.c,16)),new hd(new GO(t,e)))).Bd((vS(),Kut))}function uln(n,t){return bD($kn(uG(oIn(t,(QGn(),cCt)),88)),new MO(n.c.e.a-n.b.e.a,n.c.e.b-n.b.e.b))<=0}function sln(n,t){for(;null!=n.g||n.c?null==n.g||0!=n.i&&uG(n.g[n.i-1],51).Ob():O0(n);)yA(t,Wxn(n))}function hln(n){var t;for(t=new Ww(n.a.b);t.ai?1:0}function yln(n){return kD(n.c,(Whn(),ZLt)),xrn(n.a,uM(pK(Jkn((lmn(),WTt)))))?new zu:new zp(n)}function Mln(n){for(;!n.d||!n.d.Ob();){if(!n.b||LM(n.b))return null;n.d=uG(xV(n.b),51)}return n.d}function Tln(n){switch(n.g){case 1:return K9n;default:case 2:return 0;case 3:return _3n;case 4:return F9n}}function jln(){var n;return QYn(),VHt||(n=eR(kJn("M",!0)),n=CX(kJn("M",!1),n),VHt=n)}function Eln(){Eln=E,CKt=new uA("ELK",0),IKt=new uA("JSON",1),PKt=new uA("DOT",2),OKt=new uA("SVG",3)}function Sln(){Sln=E,aEt=new kI("STACKED",0),rEt=new kI("REVERSE_STACKED",1),cEt=new kI("SEQUENCED",2)}function Pln(){Pln=E,gPt=new WI(q4n,0),dPt=new WI("MIDDLE_TO_MIDDLE",1),wPt=new WI("AVOID_OVERLAP",2)}function Cln(){Cln=E,tdt=new ji,edt=new Ei,ndt=new Mi,Zwt=new Si,tJ(new Ti),Ywt=new L}function Iln(){Iln=E,Pxt=new CN(15),Sxt=new _N((XYn(),W$t),Pxt),Cxt=mDt,Mxt=a$t,Txt=_$t,Ext=U$t,jxt=H$t}function Oln(n,t){var e,i,r,c,a;for(r=0,c=(i=t).length;r=n.b.c.length||(_ln(n,2*t+1),(e=2*t+2)0&&(t.Cd(e),e.i&&Zdn(e))}function Hln(n,t,e){var i;for(i=e-1;i>=0&&n[i]===t[i];i--);return i<0?0:$P(E3(n[i],L0n),E3(t[i],L0n))?-1:1}function Uln(n,t,e){var i,r;this.g=n,this.c=t,this.a=this,this.d=this,r=aon(e),i=Inn($at,l1n,227,r,0,1),this.b=i}function Gln(n,t,e,i,r){var c,a;for(a=e;a<=r;a++)for(c=t;c<=i;c++)if(eTn(n,c,a))return!0;return!1}function qln(n,t){var e;for(e=n.Zb().Cc().Kc();e.Ob();)if(uG(e.Pb(),16).Hc(t))return!0;return!1}function Xln(n,t,e){var i,r,c,a;for(tJ(e),a=!1,c=n.fd(t),r=e.Kc();r.Ob();)i=r.Pb(),c.Rb(i),a=!0;return a}function zln(n,t){var e,i;return i=uG(Lsn(n.a,4),129),e=Inn(xFt,Uit,424,t,0,1),null!=i&&qGn(i,0,e,0,i.length),e}function Vln(n,t){var e;return e=new Z_n(!!(256&n.f),n.i,n.a,n.d,!!(16&n.f),n.j,n.g,t),null!=n.e||(e.c=n),e}function Wln(n,t){var e;return n===t||!!F$(t,85)&&(e=uG(t,85),OOn(Mz(n),e.vc()))}function Qln(n,t,e){var i,r;for(r=e.Kc();r.Ob();)if(i=uG(r.Pb(),44),n.Be(t,i.md()))return!0;return!1}function Jln(n,t,e){return n.d[t.p][e.p]||(Kyn(n,t,e),n.d[t.p][e.p]=!0,n.d[e.p][t.p]=!0),n.a[t.p][e.p]}function Yln(n,t){return!(!n||n==t||!vR(t,(GYn(),zpt)))&&uG(oIn(t,(GYn(),zpt)),10)!=n}function Zln(n){switch(n.i){case 2:return!0;case 1:return!1;case-1:++n.c;default:return n.$l()}}function nbn(n){switch(n.i){case-2:return!0;case-1:return!1;case 1:--n.c;default:return n._l()}}function tbn(n){U0.call(this,"The given string does not match the expected format for individual spacings.",n)}function ebn(n,t){var e;t.Ug("Min Size Preprocessing",1),e=xAn(n),Myn(n,(lBn(),EOt),e.a),Myn(n,MOt,e.b),t.Vg()}function ibn(n){var t,e,i;for(t=0,i=Inn(PNt,zZn,8,n.b,0,1),e=Fkn(n,0);e.b!=e.d.c;)i[t++]=uG(I6(e),8);return i}function rbn(n,t,e){var i,r;for(i=new lS,r=Fkn(e,0);r.b!=r.d.c;)aq(i,new eN(uG(I6(r),8)));Xln(n,t,i)}function cbn(n,t){var e;return e=Lgn(n,t),$P(P3(n,t),0)|BA(P3(n,e),0)?e:Lgn(YZn,P3(Dz(e,63),1))}function abn(n,t){var e,i;return(e=uG(n.d.Bc(t),16))?((i=n.e.hc()).Gc(e),n.e.d-=e.gc(),e.$b(),i):null}function obn(n){var t;if((t=n.a.c.length)>0)return Vz(t-1,n.a.c.length),i7(n.a,t-1);throw hv(new _v)}function ubn(n,t,e){if(n>t)throw hv(new vM(o2n+n+u2n+t));if(n<0||t>e)throw hv(new YM(o2n+n+s2n+t+Q0n+e))}function sbn(n,t){null==n.D&&null!=n.B&&(n.D=n.B,n.B=null),qan(n,null==t?null:(tJ(t),t)),n.C&&n.hl(null)}function hbn(n,t){var e;e=null!=Jkn((lmn(),WTt))&&null!=t.Sg()?uM(pK(t.Sg()))/uM(pK(Jkn(WTt))):1,vJ(n.b,t,e)}function fbn(n,t){var e,i;if(0!=(i=n.c[t]))for(n.c[t]=0,n.d-=i,e=t+1;eR9n?n-i>R9n:i-n>R9n)}function Qbn(n,t){var e;for(e=0;er&&(USn(t.q,r),i=e!=t.q.d)),i}function Zbn(n,t){var i,r,c,a,o;return a=t.i,o=t.j,r=a-(i=n.f).i,c=o-i.j,e.Math.sqrt(r*r+c*c)}function nwn(n,t){var e;return(e=Kvn(n))||(!ZKt&&(ZKt=new Ps),ZXn(),ttn((e=new Xm(sxn(t))).El(),n)),e}function twn(n,t){var e,i;return(e=uG(n.c.Bc(t),16))?((i=n.hc()).Gc(e),n.d-=e.gc(),e.$b(),n.mc(i)):n.jc()}function ewn(n,t){var e,i;for(i=0!=uRn(n.d,1),e=!0;e;)e=!1,e=t.c.mg(t.e,i),e|=PKn(n,t,i,!1),i=!i;Gon(n)}function iwn(n,t,e,i){var r,c;n.a=t,c=i?0:1,n.f=(r=new _On(n.c,n.a,e,c),new eBn(e,n.a,r,n.e,n.b,n.c==(ean(),BEt)))}function rwn(n){var t;return MK(n.a!=n.b),t=n.d.a[n.a],jK(n.b==n.d.c&&null!=t),n.c=n.a,n.a=n.a+1&n.d.a.length-1,t}function cwn(n){var t;if(0!=n.c)return n.c;for(t=0;t=n.c.b:n.a<=n.c.b))throw hv(new Bv);return t=n.a,n.a+=n.c.c,++n.b,xwn(t)}function own(n){var t;return zsn(t=new S$(n.a),n),kfn(t,(GYn(),rmt),n),t.o.a=n.g,t.o.b=n.f,t.n.a=n.i,t.n.b=n.j,t}function uwn(n){return(KQn(),LRt).Hc(n.j)?uM(pK(oIn(n,(GYn(),Mmt)))):Gfn(Uhn(cT(PNt,1),zZn,8,0,[n.i.n,n.n,n.a])).b}function swn(n){var t;return t=aN(KEt),uG(oIn(n,(GYn(),Hpt)),21).Hc((r_n(),rpt))&&Aq(t,(uIn(),Elt),(zYn(),Cwt)),t}function hwn(n){var t,e;for(e=new ek,t=new Ww(n);t.a=0?t:-t;i>0;)i%2==0?(e*=e,i=i/2|0):(r*=e,i-=1);return t<0?1/r:r}function pwn(n,t){var e,i,r;for(r=1,e=n,i=t>=0?t:-t;i>0;)i%2==0?(e*=e,i=i/2|0):(r*=e,i-=1);return t<0?1/r:r}function mwn(n,t){var e,i,r,c;return(c=fLn((i=t,(r=n?Kvn(n):null)&&r.Gl(),i)))==t&&(e=Kvn(n))&&e.Gl(),c}function vwn(n,t,e){var i,r;return r=n.f,n.f=t,4&n.Db&&!(1&n.Db)&&(i=new lV(n,1,0,r,t),e?e.nj(i):e=i),e}function kwn(n,t,e){var i,r;return r=n.b,n.b=t,4&n.Db&&!(1&n.Db)&&(i=new lV(n,1,3,r,t),e?e.nj(i):e=i),e}function ywn(n,t,e){var i,r;return r=n.a,n.a=t,4&n.Db&&!(1&n.Db)&&(i=new lV(n,1,1,r,t),e?e.nj(i):e=i),e}function Mwn(n){var t,e,i,r;if(null!=n)for(e=0;e=i||t-129&&n<128?(XG(),!(e=bot[t=n+128])&&(e=bot[t]=new Iw(n)),e):new Iw(n)}function Rwn(n){var t,e;return n>-129&&n<128?(eX(),!(e=Mot[t=n+128])&&(e=Mot[t]=new Aw(n)),e):new Aw(n)}function Kwn(n,t){n.a.c.length>0&&Lln(uG(zq(n.a,n.a.c.length-1),579),t)||kD(n.a,new r9(t))}function Fwn(n){var t,e;GB(),t=n.d.c-n.e.c,Prn((e=uG(n.g,154)).b,new Pg(t)),Prn(e.c,new Cg(t)),z8(e.i,new Ig(t))}function _wn(n){var t;return(t=new WM).a+="VerticalSegment ",QA(t,n.e),t.a+=" ",JA(t,KD(new FM,new Ww(n.k))),t.a}function Bwn(n,t){var e,i;for(e=0,i=Dgn(n,t).Kc();i.Ob();)e+=null!=oIn(uG(i.Pb(),12),(GYn(),lmt))?1:0;return e}function Hwn(n,t,e){var i,r,c;for(i=0,c=Fkn(n,0);c.b!=c.d.c&&!((r=uM(pK(I6(c))))>e);)r>=t&&++i;return i}function Uwn(n,t){WW(n);try{return n._b(t)}catch(e){if(F$(e=Ehn(e),212)||F$(e,169))return!1;throw hv(e)}}function Gwn(n,t){WW(n);try{return n.Hc(t)}catch(e){if(F$(e=Ehn(e),212)||F$(e,169))return!1;throw hv(e)}}function qwn(n,t){WW(n);try{return n.Mc(t)}catch(e){if(F$(e=Ehn(e),212)||F$(e,169))return!1;throw hv(e)}}function Xwn(n,t){WW(n);try{return n.xc(t)}catch(e){if(F$(e=Ehn(e),212)||F$(e,169))return null;throw hv(e)}}function zwn(n,t){WW(n);try{return n.Bc(t)}catch(e){if(F$(e=Ehn(e),212)||F$(e,169))return null;throw hv(e)}}function Vwn(n,t){switch(t.g){case 2:case 1:return Dgn(n,t);case 3:case 4:return Spn(Dgn(n,t))}return hZ(),hZ(),zot}function Wwn(n){var t;return 64&n.Db?vxn(n):((t=new fx(vxn(n))).a+=" (name: ",VA(t,n.zb),t.a+=")",t.a)}function Qwn(n){var t;return(t=uG(ain(n.c.c,""),233))||(t=new I2(UT(HT(new du,""),"Other")),Akn(n.c.c,"",t)),t}function Jwn(n,t,e){var i,r;return r=n.sb,n.sb=t,4&n.Db&&!(1&n.Db)&&(i=new lV(n,1,4,r,t),e?e.nj(i):e=i),e}function Ywn(n,t,e){var i,r;return r=n.r,n.r=t,4&n.Db&&!(1&n.Db)&&(i=new lV(n,1,8,r,n.r),e?e.nj(i):e=i),e}function Zwn(n,t,e){var i;return i=new Ken(n.e,4,13,t.c||(YYn(),N_t),null,Hyn(n,t),!1),e?e.nj(i):e=i,e}function ndn(n,t,e){var i;return i=new Ken(n.e,3,13,null,t.c||(YYn(),N_t),Hyn(n,t),!1),e?e.nj(i):e=i,e}function tdn(n,t){var e,i;return!(i=(e=uG(t,691)).el())&&e.fl(i=F$(t,90)?new CA(n,uG(t,29)):new g4(n,uG(t,156))),i}function edn(n,t,e){var i;n._i(n.i+1),i=n.Zi(t,e),t!=n.i&&qGn(n.g,t,n.g,t+1,n.i-t),uQ(n.g,t,i),++n.i,n.Mi(t,e),n.Ni()}function idn(n,t){var e;return t.a&&(e=t.a.a.length,n.a?JA(n.a,n.b):n.a=new lx(n.d),L4(n.a,t.a,t.d.length,e)),n}function rdn(n,t){var e;n.c=t,n.a=Jpn(t),n.a<54&&(n.f=(e=t.d>1?C4(t.a[0],t.a[1]):C4(t.a[0],0),W4(t.e>0?e:Men(e))))}function cdn(n,t){var e;return e=new un,n.a.Bd(e)?(UD(),new Xy(tJ(ven(n,e.a,t)))):(GQ(n),UD(),UD(),sut)}function adn(n,t){var e;0!=n.c.length&&(zL(e=uG(Ekn(n,Inn(pbt,e6n,10,n.c.length,0,1)),199),new Oe),WNn(e,t))}function odn(n,t){var e;0!=n.c.length&&(zL(e=uG(Ekn(n,Inn(pbt,e6n,10,n.c.length,0,1)),199),new Ae),WNn(e,t))}function udn(n,t){return RA(n)?m_(n,t):FA(n)?p_(n,t):KA(n)?(tJ(n),xA(n)===xA(t)):Cz(n)?n.Fb(t):xX(n)?SL(n,t):j3(n,t)}function sdn(n,t,e){if(t<0)zLn(n,e);else{if(!e.rk())throw hv(new vM(Gtt+e.xe()+qtt));uG(e,69).wk().Ek(n,n.hi(),t)}}function hdn(n,t,e){if(n<0||t>e)throw hv(new dM(o2n+n+s2n+t+", size: "+e));if(n>t)throw hv(new vM(o2n+n+u2n+t))}function fdn(n){var t;return 64&n.Db?vxn(n):((t=new fx(vxn(n))).a+=" (source: ",VA(t,n.d),t.a+=")",t.a)}function ldn(n){return n>=65&&n<=70?n-65+10:n>=97&&n<=102?n-97+10:n>=48&&n<=57?n-48:0}function bdn(n){var t,e,i,r;for(JYn(),i=0,r=(e=Nkn()).length;i=0?Rmn(n):hW(Rmn(Men(n))))}function Sdn(n,t,e,i,r,c){this.e=new Zm,this.f=(can(),Qjt),kD(this.e,n),this.d=t,this.a=e,this.b=i,this.f=r,this.c=c}function Pdn(n,t,i){n.n=Jq(nUt,[zZn,E0n],[376,28],14,[i,t0(e.Math.ceil(t/32))],2),n.o=t,n.p=i,n.j=t-1>>1,n.k=i-1>>1}function Cdn(n){return n=((n=((n-=n>>1&1431655765)>>2&858993459)+(858993459&n))>>4)+n&252645135,n+=n>>8,63&(n+=n>>16)}function Idn(n,t){var e,i;for(i=new DD(n);i.e!=i.i.gc();)if(e=uG(Zkn(i),142),xA(t)===xA(e))return!0;return!1}function Odn(n,t,e){var i,r;return(r=jxn(n.b,t))&&(i=uG(JXn(Len(n,r),""),29))?hxn(n,i,t,e):null}function Adn(n,t,e){var i,r;return(r=jxn(n.b,t))&&(i=uG(JXn(Len(n,r),""),29))?fxn(n,i,t,e):null}function Ldn(n,t){var e;if(null==(e=dcn(n.i,t)))throw hv(new SM("Node did not exist in input."));return Qun(t,e),null}function Ndn(n,t){var e;if(F$(e=EKn(n,t),331))return uG(e,35);throw hv(new vM(Gtt+t+"' is not a valid attribute"))}function $dn(n,t,e){var i;if(t>(i=n.gc()))throw hv(new w_(t,i));if(n.Si()&&n.Hc(e))throw hv(new vM(Xet));n.Gi(t,e)}function Ddn(n,t){t.Ug("Sort end labels",1),kS(JJ(sin(new fX(null,new h3(n.b,16)),new we),new de),new ge),t.Vg()}function xdn(){xdn=E,ZDt=new PO(Y2n,0),YDt=new PO(V2n,1),JDt=new PO(z2n,2),QDt=new PO(c3n,3),nxt=new PO("UP",4)}function Rdn(){Rdn=E,HAt=new fO("P1_STRUCTURE",0),UAt=new fO("P2_PROCESSING_ORDER",1),GAt=new fO("P3_EXECUTION",2)}function Kdn(){Kdn=E,qCt=Lvn(Lvn(gP(Lvn(Lvn(gP(Aq(new wJ,(Cjn(),VSt),(OHn(),fPt)),WSt),oPt),sPt),QSt),iPt),hPt)}function Fdn(n){switch(uG(oIn(n,(GYn(),Xpt)),311).g){case 1:kfn(n,Xpt,(Zen(),dpt));break;case 2:kfn(n,Xpt,(Zen(),ppt))}}function _dn(n){switch(n){case 0:return new Fk;case 1:return new Rk;case 2:return new Kk;default:throw hv(new Dv)}}function Bdn(n){switch(n.g){case 2:return YDt;case 1:return JDt;case 4:return QDt;case 3:return nxt;default:return ZDt}}function Hdn(n,t){switch(n.b.g){case 0:case 1:return t;case 2:case 3:return new gY(t.d,0,t.a,t.b);default:return null}}function Udn(n){switch(n.g){case 1:return _Rt;case 2:return yRt;case 3:return kRt;case 4:return KRt;default:return FRt}}function Gdn(n){switch(n.g){case 1:return KRt;case 2:return _Rt;case 3:return yRt;case 4:return kRt;default:return FRt}}function qdn(n){switch(n.g){case 1:return kRt;case 2:return KRt;case 3:return _Rt;case 4:return yRt;default:return FRt}}function Xdn(n,t,e,i){switch(t){case 1:return!n.n&&(n.n=new fV(lFt,n,1,7)),n.n;case 2:return n.k}return ajn(n,t,e,i)}function zdn(n,t,e){var i,r;return n.Pj()?(r=n.Qj(),i=HNn(n,t,e),n.Jj(n.Ij(7,xwn(e),i,t,r)),i):HNn(n,t,e)}function Vdn(n,t){var e,i,r;null==n.d?(++n.e,--n.f):(r=t.ld(),S7(n,i=((e=t.Bi())&vZn)%n.d.length,Txn(n,i,e,r)))}function Wdn(n,t){var e;e=!!(n.Bb&w1n),t?n.Bb|=w1n:n.Bb&=-1025,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,10,e,t))}function Qdn(n,t){var e;e=!!(n.Bb&j0n),t?n.Bb|=j0n:n.Bb&=-4097,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,12,e,t))}function Jdn(n,t){var e;e=!!(n.Bb&hrt),t?n.Bb|=hrt:n.Bb&=-8193,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,15,e,t))}function Ydn(n,t){var e;e=!!(n.Bb&frt),t?n.Bb|=frt:n.Bb&=-2049,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,11,e,t))}function Zdn(n){var t;n.g&&(CFn((t=n.c.kg()?n.f:n.a).a,n.o,!0),CFn(t.a,n.o,!1),kfn(n.o,(jYn(),JMt),($Pn(),rRt)))}function ngn(n){var t;if(!n.a)throw hv(new kM("Cannot offset an unassigned cut."));t=n.c-n.b,n.b+=t,iZ(n,t),eZ(n,t)}function tgn(n,t){var e;if(null==(e=cQ(n.k,t)))throw hv(new SM("Port did not exist in input."));return Qun(t,e),null}function egn(n){var t,e;for(e=bxn(Hrn(n)).Kc();e.Ob();)if(qUn(n,t=mK(e.Pb())))return h8((yP(),r_t),t);return null}function ign(n){var t,e;for(e=n.p.a.ec().Kc();e.Ob();)if((t=uG(e.Pb(),218)).f&&n.b[t.c]<-1e-10)return t;return null}function rgn(n){var t,e;for(e=jQ(new WM,91),t=!0;n.Ob();)t||(e.a+=TZn),t=!1,QA(e,n.Pb());return(e.a+="]",e).a}function cgn(n){var t,e,i;for(t=new Zm,i=new Ww(n.b);i.at?1:n==t?0==n?ugn(1/n,1/t):0:isNaN(n)?isNaN(t)?0:1:-1}function sgn(n){var t;return null==(t=n.a[n.c-1&n.a.length-1])?null:(n.c=n.c-1&n.a.length-1,uQ(n.a,n.c,null),t)}function hgn(n){var t,e,i;for(i=0,e=n.length,t=0;t=1?YDt:QDt:t}function mgn(n){switch(uG(oIn(n,(jYn(),Vyt)),223).g){case 1:return new ic;case 3:return new uc;default:return new ec}}function vgn(n){if(n.c)vgn(n.c);else if(n.d)throw hv(new kM("Stream already terminated, can't be modified or used"))}function kgn(n,t,e){var i;return i=n.a.get(t),n.a.set(t,void 0===e?null:e),void 0===i?(++n.c,++n.b.g):++n.d,i}function ygn(n,t,e){var i,r;for(r=n.a.ec().Kc();r.Ob();)if(i=uG(r.Pb(),10),yhn(e,uG(zq(t,i.p),16)))return i;return null}function Mgn(n,t,e){var i;return i=0,t&&(fN(n.a)?i+=t.f.a/2:i+=t.f.b/2),e&&(fN(n.a)?i+=e.f.a/2:i+=e.f.b/2),i}function Tgn(n,t,e){var i;!(i=e)&&(i=xG(new fy,0)),i.Ug(K4n,2),zyn(n.b,t,i.eh(1)),Xzn(n,t,i.eh(1)),hJn(t,i.eh(1)),i.Vg()}function jgn(n,t,e){var i;return gj(),Scn(i=new ns,t),pcn(i,e),n&&ttn((!n.a&&(n.a=new MD(eFt,n,5)),n.a),i),i}function Egn(n){var t;return 64&n.Db?vxn(n):((t=new fx(vxn(n))).a+=" (identifier: ",VA(t,n.k),t.a+=")",t.a)}function Sgn(n,t){var e;e=!!(n.Bb&Qtt),t?n.Bb|=Qtt:n.Bb&=-32769,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,18,e,t))}function Pgn(n,t){var e;e=!!(n.Bb&Qtt),t?n.Bb|=Qtt:n.Bb&=-32769,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,18,e,t))}function Cgn(n,t){var e;e=!!(n.Bb&VZn),t?n.Bb|=VZn:n.Bb&=-16385,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,16,e,t))}function Ign(n,t){var e;e=!!(n.Bb&P0n),t?n.Bb|=P0n:n.Bb&=-65537,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,20,e,t))}function Ogn(n){var t;return t=Inn(JHt,N1n,28,2,15,1),n-=P0n,t[0]=(n>>10)+C0n&D1n,t[1]=56320+(1023&n)&D1n,mvn(t,0,t.length)}function Agn(n){var t;return(t=YIn(n))>34028234663852886e22?M0n:t<-34028234663852886e22?T0n:t}function Lgn(n,t){var e;return _L(n)&&_L(t)&&p0n<(e=n+t)&&e"+V3(t.c):"e_"+Hon(t),n.b&&n.c?V3(n.b)+"->"+V3(n.c):"e_"+Hon(n))}function Kgn(n,t){return m_(t.b&&t.c?V3(t.b)+"->"+V3(t.c):"e_"+Hon(t),n.b&&n.c?V3(n.b)+"->"+V3(n.c):"e_"+Hon(n))}function Fgn(n,t){return YN(),oan(T1n),e.Math.abs(n-t)<=T1n||n==t||isNaN(n)&&isNaN(t)?0:nt?1:KL(isNaN(n),isNaN(t))}function _gn(){_gn=E,fxt=new IO(Y2n,0),sxt=new IO("POLYLINE",1),uxt=new IO("ORTHOGONAL",2),hxt=new IO("SPLINES",3)}function Bgn(){Bgn=E,IOt=new aO("ASPECT_RATIO_DRIVEN",0),OOt=new aO("MAX_SCALE_DRIVEN",1),COt=new aO("AREA_DRIVEN",2)}function Hgn(n,t,e){try{Vfn(n,t,e)}catch(i){throw F$(i=Ehn(i),606)?hv(new x9(i)):hv(i)}return t}function Ugn(n){var t,e;for(t=0,e=n.length;tt&&i.Ne(n[c-1],n[c])>0;--c)a=n[c],uQ(n,c,n[c-1]),uQ(n,c-1,a)}function Zgn(n,t){var e,i,r,c,a;if(e=t.f,Akn(n.c.d,e,t),null!=t.g)for(c=0,a=(r=t.g).length;ct){F4(e);break}}lW(e,t)}function tpn(n,t){var i,r;r=uM(pK(Omn(z4(t),(jYn(),dTt)))),TEn(t,i=e.Math.max(0,r/2-.5),1),kD(n,new xC(t,i))}function epn(n,t,e){e.Ug("Straight Line Edge Routing",1),e.dh(t,l7n),DXn(n,uG(zDn(t,(SK(),zCt)),27)),e.dh(t,w7n)}function ipn(n,t){0==n.n.c.length&&kD(n.n,new c0(n.s,n.t,n.i)),kD(n.b,t),zMn(uG(zq(n.n,n.n.c.length-1),209),t),nqn(n,t)}function rpn(n){var t;this.a=new nB(t=uG(n.e&&n.e(),9),uG(MF(t,t.length),9),0),this.b=Inn(dat,EZn,1,this.a.a.length,5,1)}function cpn(n){return Array.isArray(n)&&n.Tm===j?Ij(Tbn(n))+"@"+(Hon(n)>>>0).toString(16):n.toString()}function apn(n,t){return n.h==b0n&&0==n.m&&0==n.l?(t&&(Qat=p$(0,0,0)),LL((tin(),Zat))):(t&&(Qat=p$(n.l,n.m,n.h)),p$(0,0,0))}function opn(n,t){switch(t.g){case 2:return n.b;case 1:return n.c;case 4:return n.d;case 3:return n.a;default:return!1}}function upn(n,t){switch(t.g){case 2:return n.b;case 1:return n.c;case 4:return n.d;case 3:return n.a;default:return!1}}function spn(n,t,e,i){switch(t){case 3:return n.f;case 4:return n.g;case 5:return n.i;case 6:return n.j}return Xdn(n,t,e,i)}function hpn(n,t){if(t==n.d)return n.e;if(t==n.e)return n.d;throw hv(new vM("Node "+t+" not part of edge "+n))}function fpn(n,t){var e;if(F$(e=EKn(n.Dh(),t),102))return uG(e,19);throw hv(new vM(Gtt+t+"' is not a valid reference"))}function lpn(n,t,e,i){if(t<0)lRn(n,e,i);else{if(!e.rk())throw hv(new vM(Gtt+e.xe()+qtt));uG(e,69).wk().Ck(n,n.hi(),t,i)}}function bpn(n){var t;if(n.b){if(bpn(n.b),n.b.d!=n.c)throw hv(new Fv)}else n.d.dc()&&(t=uG(n.f.c.xc(n.e),16))&&(n.d=t)}function wpn(n){var t,e;for(VK(),t=n.o.b,e=uG(uG(Y9(n.r,(KQn(),KRt)),21),87).Kc();e.Ob();)uG(e.Pb(),117).e.b+=t}function dpn(n){var t,e,i;for(this.a=new XL,i=new Ww(n);i.a=r)return t.c+e;return t.c+t.b.gc()}function ppn(n,t){var e,i,r,c;for(EK(),r=t,Ntn(i=Jtn(n),0,i.length,r),e=0;e0&&(i+=r,++e);return e>1&&(i+=n.d*(e-1)),i}function Mpn(n){var t,e,i;return i=gCn(n),!pE(n.c)&&(nrn(i,"knownLayouters",e=new Ib),t=new jm(e),z8(n.c,t)),i}function Tpn(n){var t,e,i;for((i=new zM).a+="[",t=0,e=n.gc();t0&&(s3(t-1,n.length),58==n.charCodeAt(t-1))&&!mpn(n,n_t,t_t)}function Cpn(n,t){var e;return xA(n)===xA(t)||!!F$(t,92)&&(e=uG(t,92),n.e==e.e&&n.d==e.d&&d8(n,e.a))}function Ipn(n){switch(KQn(),n.g){case 4:return yRt;case 1:return kRt;case 3:return KRt;case 2:return _Rt;default:return FRt}}function Opn(n){var t,e;if(n.b)return n.b;for(e=Nut?null:n.d;e;){if(t=Nut?null:e.b)return t;e=Nut?null:e.d}return pS(),Eut}function Apn(n){var t,e;for(e=uM(pK(n.a.of((XYn(),LDt)))),t=new Ww(n.a.Sf());t.a>5),15,1))[e]=1<3;)r*=10,--c;n=(n+(r>>1))/r|0}return i.i=n,!0}function emn(n,t){var e,i,r;if(null==n.i&&eqn(n),e=n.i,-1!=(i=t.Lj()))for(r=e.length;i=0;--i)for(t=e[i],r=0;r>1,this.k=t-1>>1}function hmn(n){Stn(),uG(n.of((XYn(),q$t)),181).Hc((oUn(),oKt))&&(uG(n.of(bDt),181).Fc((eNn(),pRt)),uG(n.of(q$t),181).Mc(oKt))}function fmn(n){var t,e;t=n.d==(vAn(),Bdt),e=dPn(n),kfn(n.a,(jYn(),byt),t&&!e||!t&&e?(nMn(),LNt):(nMn(),ANt))}function lmn(){lmn=E,ZS(),jYn(),WTt=ETt,QTt=n7(Uhn(cT(lNt,1),m9n,149,0,[wTt,dTt,pTt,mTt,yTt,MTt,TTt,jTt,PTt,ITt,gTt,vTt,STt]))}function bmn(n,t){var e;return(e=uG(l8(n,ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15)).Qc(Nq(e.gc()))}function wmn(n,t){var e,i;if((i=new od(n.a.ad(t,!0))).a.gc()<=1)throw hv(new Rv);return(e=i.a.ec().Kc()).Pb(),uG(e.Pb(),40)}function dmn(n,t,e){var i;return i=uM(n.p[t.i.p])+uM(n.d[t.i.p])+t.n.b+t.a.b,uM(n.p[e.i.p])+uM(n.d[e.i.p])+e.n.b+e.a.b-i}function gmn(n,t){return n.i>0&&(t.lengthn.i&&uQ(t,n.i,null),t}function pmn(n){var t;return 64&n.Db?Wwn(n):((t=new fx(Wwn(n))).a+=" (instanceClassName: ",VA(t,n.D),t.a+=")",t.a)}function mmn(n){var t,e,i,r;for(r=0,e=0,i=n.length;e0&&(n._j(),-1!=Txn(n,((e=null==t?0:Hon(t))&vZn)%n.d.length,e,t))}function Mmn(n,t){var i,r;n.a=Lgn(n.a,1),n.c=e.Math.min(n.c,t),n.b=e.Math.max(n.b,t),n.d+=t,i=t-n.f,r=n.e+i,n.f=r-n.e-i,n.e=r}function Tmn(n,t){switch(t){case 3:return void vcn(n,0);case 4:return void kcn(n,0);case 5:return void ycn(n,0);case 6:return void Mcn(n,0)}Awn(n,t)}function jmn(n,t){switch(t.g){case 1:return YU(n.j,(Lun(),ybt));case 2:return YU(n.j,(Lun(),Tbt));default:return hZ(),hZ(),zot}}function Emn(n){var t;switch(ZW(),(t=n.Pc()).length){case 0:return jat;case 1:return new Uq(WW(t[0]));default:return new t1(Ugn(t))}}function Smn(n,t){n.Xj();try{n.d.bd(n.e++,t),n.f=n.d.j,n.g=-1}catch(e){throw F$(e=Ehn(e),77)?hv(new Fv):hv(e)}}function Pmn(){Pmn=E,lBt=new Is,cBt=new Os,aBt=new As,oBt=new Ls,uBt=new Ns,sBt=new $s,hBt=new Ds,fBt=new xs,bBt=new Rs}function Cmn(n,t){var e,i;return wL(),i=null,t==(e=bF((qy(),qy(),Hat)))&&(i=uG(U1(Bat,n),624)),i||(i=new JW(n),t==e&&r2(Bat,n,i)),i}function Imn(n){return Yyn(),(n.q?n.q:(hZ(),hZ(),Vot))._b((jYn(),LMt))?uG(oIn(n,LMt),203):uG(oIn(HQ(n),NMt),203)}function Omn(n,t){var e,i;return i=null,vR(n,(jYn(),kTt))&&(e=uG(oIn(n,kTt),96)).pf(t)&&(i=e.of(t)),null==i&&(i=oIn(HQ(n),t)),i}function Amn(n,t){var e,i,r;return!!F$(t,44)&&(i=(e=uG(t,44)).ld(),xQ(r=Xwn(n.Rc(),i),e.md())&&(null!=r||n.Rc()._b(i)))}function Lmn(n,t){var e,i;return n.f>0&&(n._j(),e=ZNn(n,((i=null==t?0:Hon(t))&vZn)%n.d.length,i,t))?e.md():null}function Nmn(n,t,e){var i,r,c;return n.Pj()?(i=n.i,c=n.Qj(),edn(n,i,t),r=n.Ij(3,null,t,i,c),e?e.nj(r):e=r):edn(n,n.i,t),e}function $mn(n,t,e){var i,r;return i=new Ken(n.e,4,10,F$(r=t.c,90)?uG(r,29):(YYn(),x_t),null,Hyn(n,t),!1),e?e.nj(i):e=i,e}function Dmn(n,t,e){var i,r;return i=new Ken(n.e,3,10,null,F$(r=t.c,90)?uG(r,29):(YYn(),x_t),Hyn(n,t),!1),e?e.nj(i):e=i,e}function xmn(n){var t;return VK(),t=new eN(uG(n.e.of((XYn(),U$t)),8)),n.B.Hc((oUn(),eKt))&&(t.a<=0&&(t.a=20),t.b<=0&&(t.b=20)),t}function Rmn(n){var t,e;return cHn(),e=pz(n),0!=(t=pz(Dz(n,32)))?new x3(e,t):e>10||e<0?new Z5(1,e):Rot[e]}function Kmn(n,t){var e;return _L(n)&&_L(t)&&p0n<(e=n%t)&&e=0?c=c.a[1]:(r=c,c=c.a[0])}return r}function nvn(n,t,e){var i,r,c;for(r=null,c=n.b;c;){if(i=n.a.Ne(t,c.d),e&&0==i)return c;i<=0?c=c.a[0]:(r=c,c=c.a[1])}return r}function tvn(n,t,e,i){var r,c,a;return r=!1,nWn(n.f,e,i)&&(hkn(n.f,n.a[t][e],n.a[t][i]),a=(c=n.a[t])[i],c[i]=c[e],c[e]=a,r=!0),r}function evn(n,t,e){var i,r,c;for(r=uG(cQ(n.b,e),183),i=0,c=new Ww(t.j);c.a>5,t&=31,r=n.d+e+(0==t?0:1),kCn(i=Inn(YHt,W1n,28,r,15,1),n.a,e,t),K4(c=new VV(n.e,r,i)),c}function cvn(n,t){var e;for(e=new Fz(ix(Xgn(n).a.Kc(),new h));hDn(e);)if(uG(N9(e),18).d.i.c==t)return!1;return!0}function avn(n,t,i){var r,c,a,o,u;return o=n.k,u=t.k,c=pK(Omn(n,r=i[o.g][u.g])),a=pK(Omn(t,r)),e.Math.max((tJ(c),c),(tJ(a),a))}function ovn(){return Error.stackTraceLimit>0?(e.Error.stackTraceLimit=Error.stackTraceLimit=64,!0):"stack"in new Error}function uvn(n,t){return YN(),YN(),oan(T1n),(e.Math.abs(n-t)<=T1n||n==t||isNaN(n)&&isNaN(t)?0:nt?1:KL(isNaN(n),isNaN(t)))>0}function svn(n,t){return YN(),YN(),oan(T1n),(e.Math.abs(n-t)<=T1n||n==t||isNaN(n)&&isNaN(t)?0:nt?1:KL(isNaN(n),isNaN(t)))<0}function hvn(n,t){return YN(),YN(),oan(T1n),(e.Math.abs(n-t)<=T1n||n==t||isNaN(n)&&isNaN(t)?0:nt?1:KL(isNaN(n),isNaN(t)))<=0}function fvn(n,t){for(var e=0;!t[e]||""==t[e];)e++;for(var i=t[e++];e0&&this.b>0&&(this.g=mX(this.c,this.b,this.a))}function Tvn(n,t){var e,i=n.a;t=String(t),i.hasOwnProperty(t)&&(e=i[t]);var r=(Cfn(),Wat)[typeof e];return r?r(e):Vbn(typeof e)}function jvn(n){if(!(Iet in n.a))throw hv(new SM("Every element must have an id."));return fNn(v0(n,Iet))}function Evn(n){var t,e;for(e=WOn(n),t=null;2==n.c;)EYn(n),t||(QYn(),QYn(),kzn(t=new QN(2),e),e=t),e.Jm(WOn(n));return e}function Svn(n,t){var e,i;return n._j(),(e=ZNn(n,((i=null==t?0:Hon(t))&vZn)%n.d.length,i,t))?(uan(n,e),e.md()):null}function Pvn(n,t){return n.e>t.e?1:n.et.d?n.e:n.d=48&&n<48+e.Math.min(10,10)?n-48:n>=97&&n<97?n-97+10:n>=65&&n<65?n-65+10:-1}function Ivn(n,t){if(t.c==n)return t.d;if(t.d==n)return t.c;throw hv(new vM("Input edge is not connected to the input port."))}function Ovn(n){if(Bvn(Fnt,n))return qx(),eot;if(Bvn(_nt,n))return qx(),tot;throw hv(new vM("Expecting true or false"))}function Avn(n){switch(typeof n){case pZn:return pln(n);case gZn:return OL(n);case dZn:return XK(n);default:return null==n?0:xx(n)}}function Lvn(n,t){if(n.a<0)throw hv(new kM("Did not call before(...) or after(...) before calling add(...)."));return hR(n,n.a,t),n}function Nvn(n){return W0(),F$(n,162)?uG(cQ(AFt,iut),295).Rg(n):PV(AFt,Tbn(n))?uG(cQ(AFt,Tbn(n)),295).Rg(n):null}function $vn(n){var t;return 32&n.Db||0!=(t=iQ(uG(Lsn(n,16),29)||n.ii())-iQ(n.ii()))&&Dvn(n,32,Inn(dat,EZn,1,t,5,1)),n}function Dvn(n,t,e){var i;n.Db&t?null==e?H$n(n,t):-1==(i=jTn(n,t))?n.Eb=e:uQ(Kcn(n.Eb),i,e):null!=e&&lFn(n,t,e)}function xvn(n,t,e,i){var r;0!=t.c.length&&(r=gRn(e,i),kS(krn(new fX(null,new h3(WLn(t),1)),new ba),new pY(n,e,r,i)))}function Rvn(n,t){var e,i,r;return i=n.a.length-1,e=t-n.b&i,r=n.c-t&i,jK(e<(n.c-n.b&i)),e>=r?(Pbn(n,t),-1):(Sbn(n,t),1)}function Kvn(n){var t,e,i;if(!(i=n.Jh()))for(t=0,e=n.Ph();e;e=e.Ph()){if(++t>O0n)return e.Qh();if((i=e.Jh())||e==n)break}return i}function Fvn(n,t){var e;return xA(t)===xA(n)||!!F$(t,21)&&(e=uG(t,21)).gc()==n.gc()&&n.Ic(e)}function _vn(n,t){return n.et.e?1:n.ft.f?1:Hon(n)-Hon(t)}function Bvn(n,t){return tJ(n),null!=t&&(!!m_(n,t)||n.length==t.length&&m_(n.toLowerCase(),t.toLowerCase()))}function Hvn(n){var t,e;return dwn(n,-129)>0&&dwn(n,128)<0?(tX(),t=pz(n)+128,!(e=got[t])&&(e=got[t]=new Ow(n)),e):new Ow(n)}function Uvn(){Uvn=E,tbt=new EC(q4n,0),Zlt=new EC("INSIDE_PORT_SIDE_GROUPS",1),Ylt=new EC("GROUP_MODEL_ORDER",2),nbt=new EC(X4n,3)}function Gvn(n){var t;return n.b||wj(n,!(t=QF(n.e,n.a))||!m_(_nt,Lmn((!t.b&&(t.b=new XR((YYn(),H_t),wBt,t)),t.b),"qualified"))),n.c}function qvn(n,t){var e,i;for(s3(t,n.length),e=n.charCodeAt(t),i=t+1;i2e3&&(Gat=n,qat=e.setTimeout(vE,10)),0==Uat++&&(Pin((Gy(),Fat)),!0)}function wkn(n,t,e){var i;(Aut?(Opn(n),1):Lut||Dut?(pS(),1):$ut&&(pS(),0))&&((i=new iB(t)).b=e,qIn(n,i))}function dkn(n,t){var e;e=!n.A.Hc((Qmn(),JRt))||n.q==($Pn(),cRt),n.u.Hc((eNn(),wRt))?e?QQn(n,t):TQn(n,t):n.u.Hc(gRt)&&(e?YWn(n,t):MJn(n,t))}function gkn(n){var t;xA(zDn(n,(XYn(),E$t)))===xA((Own(),Oxt))&&(R0(n)?(t=uG(zDn(R0(n),E$t),346),Myn(n,E$t,t)):Myn(n,E$t,Axt))}function pkn(n){var t,e;return!!vR(n.d.i,(jYn(),UMt))&&(t=uG(oIn(n.c.i,UMt),17),e=uG(oIn(n.d.i,UMt),17),d$(t.a,e.a)>0)}function mkn(n,t,i){return new gY(e.Math.min(n.a,t.a)-i/2,e.Math.min(n.b,t.b)-i/2,e.Math.abs(n.a-t.a)+i,e.Math.abs(n.b-t.b)+i)}function vkn(n){var t;this.d=new Zm,this.j=new sj,this.g=new sj,t=n.g.b,this.f=uG(oIn(HQ(t),(jYn(),Byt)),88),this.e=uM(pK(eyn(t,yTt)))}function kkn(n){this.d=new Zm,this.e=new u8,this.c=Inn(YHt,W1n,28,(KQn(),Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt])).length,15,1),this.b=n}function ykn(n,t,e){var i;switch(i=e[n.g][t],n.g){case 1:case 3:return new MO(0,i);case 2:case 4:return new MO(i,0);default:return null}}function Mkn(n,t,e){var i;i=uG(A1(t.f),205);try{i.rf(n,e),WQ(t.f,i)}catch(r){throw F$(r=Ehn(r),103),hv(r)}}function Tkn(n,t,e){var i,r,c,a;return i=null,(c=DVn(aan(),t))&&(r=null,null!=(a=vVn(c,e))&&(r=n.qf(c,a)),i=r),i}function jkn(n,t,e,i){var r;if(t>=(r=n.length))return r;for(t=t>0?t:0;ti&&uQ(t,i,null),t}function Skn(n,t){var e,i;for(i=n.a.length,t.lengthi&&uQ(t,i,null),t}function Pkn(n,t){var e,i;++n.j,null!=t&&e$n(t,e=F$(i=n.a.Cb,99)?uG(i,99).th():null)?Dvn(n.a,4,e):Dvn(n.a,4,uG(t,129))}function Ckn(n){var t;if(null==n)return null;if(null==(t=Exn(yXn(n,!0))))throw hv(new PM("Invalid hexBinary value: '"+n+"'"));return t}function Ikn(n,t,e){var i;t.a.length>0&&(kD(n.b,new hG(t.a,e)),0<(i=t.a.length)?t.a=r1(t.a,0,0):0>i&&(t.a+=V$(Inn(JHt,N1n,28,-i,15,1))))}function Okn(n,t,e){var i;if(!e[t.d])for(e[t.d]=!0,i=new Ww(Ebn(t));i.a=n.b>>1)for(i=n.c,e=n.b;e>t;--e)i=i.b;else for(i=n.a.a,e=0;e=0?n.Wh(r):$Nn(n,i):e<0?$Nn(n,i):uG(i,69).wk().Bk(n,n.hi(),e)}function Qkn(n){var t,e;for(!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),t=(e=n.o).c.Kc();t.e!=t.i.gc();)uG(t.Yj(),44).md();return Tnn(e)}function Jkn(n){var t;if(F$(n.a,4)){if(null==(t=Nvn(n.a)))throw hv(new kM(Bnt+n.b+"'. "+Rnt+(vK($Ft),$Ft.k)+Knt));return t}return n.a}function Ykn(n,t){var e,i;if(n.j.length!=t.j.length)return!1;for(e=0,i=n.j.length;e=64&&t<128&&(r=S3(r,Nz(1,t-64)));return r}function eyn(n,t){var e,i;return i=null,vR(n,(XYn(),ODt))&&(e=uG(oIn(n,ODt),96)).pf(t)&&(i=e.of(t)),null==i&&HQ(n)&&(i=oIn(HQ(n),t)),i}function iyn(n,t){var e;return e=uG(oIn(n,(jYn(),bMt)),75),_$(t,cbt)?e?BY(e):(e=new Uk,kfn(n,bMt,e)):e&&kfn(n,bMt,null),e}function ryn(){ryn=E,XYn(),ift=SDt,Jht=M$t,Xht=c$t,Yht=W$t,MEn(),tft=cst,nft=ist,eft=ost,Zht=est,pbn(),Vht=Hht,zht=Bht,Wht=Ght,Qht=qht}function cyn(n){switch(qS(),this.c=new Zm,this.d=n,n.g){case 0:case 2:this.a=kJ(Qlt),this.b=M0n;break;case 3:case 1:this.a=Qlt,this.b=T0n}}function ayn(n){var t;L_(uG(oIn(n,(jYn(),JMt)),101))&&(c$n((u3(0,(t=n.b).c.length),uG(t.c[0],30))),c$n(uG(zq(t,t.c.length-1),30)))}function oyn(n,t){t.Ug("Self-Loop post-processing",1),kS(JJ(JJ(sin(new fX(null,new h3(n.b,16)),new Di),new xi),new Ri),new Ki),t.Vg()}function uyn(n,t,e){var i;if(n.c)ycn(n.c,n.c.i+t),Mcn(n.c,n.c.j+e);else for(i=new Ww(n.b);i.a=0&&(e.d=n.t);break;case 3:n.t>=0&&(e.a=n.t)}n.C&&(e.b=n.C.b,e.c=n.C.c)}function pyn(){pyn=E,Tjt=new wI(k9n,0),kjt=new wI(D6n,1),yjt=new wI("LINEAR_SEGMENTS",2),vjt=new wI("BRANDES_KOEPF",3),Mjt=new wI(v9n,4)}function myn(){myn=E,Nht=new lC(o3n,0),Lht=new lC(u3n,1),$ht=new lC(s3n,2),Dht=new lC(h3n,3),Nht.a=!1,Lht.a=!0,$ht.a=!1,Dht.a=!0}function vyn(){vyn=E,yht=new hC(o3n,0),kht=new hC(u3n,1),Mht=new hC(s3n,2),Tht=new hC(h3n,3),yht.a=!1,kht.a=!0,Mht.a=!1,Tht.a=!0}function kyn(n,t,e,i){var r;return e>=0?n.Sh(t,e,i):(n.Ph()&&(i=(r=n.Fh())>=0?n.Ah(i):n.Ph().Th(n,-1-r,null,i)),n.Ch(t,e,i))}function yyn(n,t){switch(t){case 7:return!n.e&&(n.e=new f_(aFt,n,7,4)),void Czn(n.e);case 8:return!n.d&&(n.d=new f_(aFt,n,8,5)),void Czn(n.d)}Tmn(n,t)}function Myn(n,t,e){return null==e?(!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),Svn(n.o,t)):(!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),rSn(n.o,t,e)),n}function Tyn(n,t){var e,i,r,c;for(hZ(),e=n,c=t,F$(n,21)&&!F$(t,21)&&(e=t,c=n),r=e.Kc();r.Ob();)if(i=r.Pb(),c.Hc(i))return!1;return!0}function jyn(n,t,e,i){if(t.ae.b)return!0}return!1}function Eyn(n,t){return RA(n)?!!bZn[t]:n.Sm?!!n.Sm[t]:FA(n)?!!lZn[t]:!!KA(n)&&!!fZn[t]}function Syn(n){var t;t=n.a;do{(t=uG(N9(new Fz(ix(qgn(t).a.Kc(),new h))),18).c.i).k==(zIn(),wbt)&&n.b.Fc(t)}while(t.k==(zIn(),wbt));n.b=Spn(n.b)}function Pyn(n,t){var i,r,c;for(c=n,r=new Fz(ix(qgn(t).a.Kc(),new h));hDn(r);)(i=uG(N9(r),18)).c.i.c&&(c=e.Math.max(c,i.c.i.c.p));return c}function Cyn(n,t){var e,i,r;for(r=0,i=uG(uG(Y9(n.r,t),21),87).Kc();i.Ob();)r+=(e=uG(i.Pb(),117)).d.d+e.b.Mf().b+e.d.a,i.Ob()&&(r+=n.w);return r}function Iyn(n,t){var e,i,r;for(r=0,i=uG(uG(Y9(n.r,t),21),87).Kc();i.Ob();)r+=(e=uG(i.Pb(),117)).d.b+e.b.Mf().a+e.d.c,i.Ob()&&(r+=n.w);return r}function Oyn(n){var t,e,i;if(e=0,0==(i=GFn(n)).c.length)return 1;for(t=new Ww(i);t.a=0?n.Lh(a,e,!0):YNn(n,c,e):uG(c,69).wk().yk(n,n.hi(),r,e,i)}function xyn(n,t,e,i){var r;(r=bdn(t.pf((XYn(),K$t))?uG(t.of(K$t),21):n.j))!=(JYn(),sht)&&(e&&!vvn(r)||LOn(Sxn(n,r,i),t))}function Ryn(n){switch(n.g){case 1:return ehn(),pht;case 3:return ehn(),wht;case 2:return ehn(),ght;case 4:return ehn(),dht;default:return null}}function Kyn(n,t,e){if(n.e)switch(n.b){case 1:JY(n.c,t,e);break;case 0:YY(n.c,t,e)}else C5(n.c,t,e);n.a[t.p][e.p]=n.c.i,n.a[e.p][t.p]=n.c.e}function Fyn(n){var t,e;if(null==n)return null;for(e=Inn(pbt,zZn,199,n.length,0,2),t=0;t=0)return i;if(n.ol())for(e=0;e=(r=n.gc()))throw hv(new w_(t,r));if(n.Si()&&(i=n.dd(e))>=0&&i!=t)throw hv(new vM(Xet));return n.Xi(t,e)}function Gyn(n,t){if(this.a=uG(WW(n),253),this.b=uG(WW(t),253),n.Ed(t)>0||n==(py(),Mat)||t==(my(),Tat))throw hv(new vM("Invalid range: "+N5(n,t)))}function qyn(n){var t,e;for(this.b=new Zm,this.c=n,this.a=!1,e=new Ww(n.a);e.a0),(t&-t)==t)return t0(t*uRn(n,31)*4.656612873077393e-10);do{i=(e=uRn(n,31))%t}while(e-i+(t-1)<0);return t0(i)}function rMn(n,t,e){switch(e.g){case 1:n.a=t.a/2,n.b=0;break;case 2:n.a=t.a,n.b=t.b/2;break;case 3:n.a=t.a/2,n.b=t.b;break;case 4:n.a=0,n.b=t.b/2}}function cMn(n,t,e,i){var r,c;for(r=t;r1&&(r=Xyn(n,t)),r}function sMn(n){var t;return new MO(t=uM(pK(zDn(n,(XYn(),BDt))))*e.Math.sqrt((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a).i),t/uM(pK(zDn(n,_Dt))))}function hMn(n){var t;return n.f&&n.f.Vh()&&(t=uG(n.f,54),n.f=uG(mwn(n,t),84),n.f!=t&&4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,9,8,t,n.f))),n.f}function fMn(n){var t;return n.i&&n.i.Vh()&&(t=uG(n.i,54),n.i=uG(mwn(n,t),84),n.i!=t&&4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,9,7,t,n.i))),n.i}function lMn(n){var t;return n.b&&64&n.b.Db&&(t=n.b,n.b=uG(mwn(n,t),19),n.b!=t&&4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,9,21,t,n.b))),n.b}function bMn(n,t){var e,i,r;null==n.d?(++n.e,++n.f):(i=t.Bi(),eKn(n,n.f+1),r=(i&vZn)%n.d.length,!(e=n.d[r])&&(e=n.d[r]=n.dk()),e.Fc(t),++n.f)}function wMn(n,t,e){var i;return!t.tk()&&(-2!=t.Ik()?null==(i=t.ik())?null==e:udn(i,e):t.qk()==n.e.Dh()&&null==e)}function dMn(){var n;man(16,b1n),n=aon(16),this.b=Inn(Cat,l1n,303,n,0,1),this.c=Inn(Cat,l1n,303,n,0,1),this.a=null,this.e=null,this.i=0,this.f=n-1,this.g=0}function gMn(n){LF.call(this),this.k=(zIn(),dbt),this.j=(man(6,g1n),new R7(6)),this.b=(man(2,g1n),new R7(2)),this.d=new $k,this.f=new xk,this.a=n}function pMn(n){var t,e;n.c.length<=1||(iAn(n,uG((t=w_n(n,(KQn(),KRt))).a,17).a,uG(t.b,17).a),iAn(n,uG((e=w_n(n,_Rt)).a,17).a,uG(e.b,17).a))}function mMn(n,t,e){var i,r;for(i=(r=n.a.b).c.length;i102?-1:n<=57?n-48:n<65?-1:n<=70?n-65+10:n<97?-1:n-97+10}function IMn(n,t){if(null==n)throw hv(new MM("null key in entry: null="+t));if(null==t)throw hv(new MM("null value in entry: "+n+"=null"))}function OMn(n,t){for(var e,i;n.Ob();){if(!t.Ob())return!1;if(e=n.Pb(),i=t.Pb(),!(xA(e)===xA(i)||null!=e&&udn(e,i)))return!1}return!t.Ob()}function AMn(n,t){var i;return i=Uhn(cT(eUt,1),I0n,28,15,[Nbn(n.a[0],t),Nbn(n.a[1],t),Nbn(n.a[2],t)]),n.d&&(i[0]=e.Math.max(i[0],i[2]),i[2]=i[0]),i}function LMn(n,t){var i;return i=Uhn(cT(eUt,1),I0n,28,15,[$bn(n.a[0],t),$bn(n.a[1],t),$bn(n.a[2],t)]),n.d&&(i[0]=e.Math.max(i[0],i[2]),i[2]=i[0]),i}function NMn(n,t,e){L_(uG(oIn(t,(jYn(),JMt)),101))||(Z8(n,t,yOn(t,e)),Z8(n,t,yOn(t,(KQn(),KRt))),Z8(n,t,yOn(t,yRt)),hZ(),f$(t.j,new Gg(n)))}function $Mn(n){var t,e;for(n.c||oVn(n),e=new Uk,N3(t=new Ww(n.a));t.a0&&(s3(0,t.length),43==t.charCodeAt(0))?(s3(1,t.length+1),t.substr(1)):t)}function nTn(n){var t;return null==n?null:new PN((t=yXn(n,!0)).length>0&&(s3(0,t.length),43==t.charCodeAt(0))?(s3(1,t.length+1),t.substr(1)):t)}function tTn(n,t,e,i,r,c,a,o){var u,s;i&&((u=i.a[0])&&tTn(n,t,e,u,r,c,a,o),ljn(n,e,i.d,r,c,a,o)&&t.Fc(i),(s=i.a[1])&&tTn(n,t,e,s,r,c,a,o))}function eTn(n,t,e){try{return _A(Son(n,t,e),1)}catch(i){throw F$(i=Ehn(i),333)?hv(new dM(b3n+n.o+"*"+n.p+w3n+t+TZn+e+d3n)):hv(i)}}function iTn(n,t,e){try{return _A(Son(n,t,e),0)}catch(i){throw F$(i=Ehn(i),333)?hv(new dM(b3n+n.o+"*"+n.p+w3n+t+TZn+e+d3n)):hv(i)}}function rTn(n,t,e){try{return _A(Son(n,t,e),2)}catch(i){throw F$(i=Ehn(i),333)?hv(new dM(b3n+n.o+"*"+n.p+w3n+t+TZn+e+d3n)):hv(i)}}function cTn(n,t){if(-1==n.g)throw hv(new xv);n.Xj();try{n.d.hd(n.g,t),n.f=n.d.j}catch(e){throw F$(e=Ehn(e),77)?hv(new Fv):hv(e)}}function aTn(n){var t,e,i;for(e=new Ww(n.b);e.ac&&uQ(t,c,null),t}function uTn(n,t){var e,i;if(i=n.gc(),null==t){for(e=0;e0&&(u+=r),s[h]=a,a+=o*(u+i)}function TTn(n){var t,e,i;for(i=n.f,n.n=Inn(eUt,I0n,28,i,15,1),n.d=Inn(eUt,I0n,28,i,15,1),t=0;t0?n.c:0),++c;n.b=r,n.d=a}function ATn(n,t){var i;return i=Uhn(cT(eUt,1),I0n,28,15,[eMn(n,(Yrn(),jst),t),eMn(n,Est,t),eMn(n,Sst,t)]),n.f&&(i[0]=e.Math.max(i[0],i[2]),i[2]=i[0]),i}function LTn(n,t,e){try{HBn(n,t+n.j,e+n.k,!1,!0)}catch(i){throw F$(i=Ehn(i),77)?hv(new dM(i.g+g3n+t+TZn+e+").")):hv(i)}}function NTn(n,t,e){try{HBn(n,t+n.j,e+n.k,!0,!1)}catch(i){throw F$(i=Ehn(i),77)?hv(new dM(i.g+g3n+t+TZn+e+").")):hv(i)}}function $Tn(n){var t;vR(n,(jYn(),PMt))&&((t=uG(oIn(n,PMt),21)).Hc((VDn(),Bxt))?(t.Mc(Bxt),t.Fc(Uxt)):t.Hc(Uxt)&&(t.Mc(Uxt),t.Fc(Bxt)))}function DTn(n){var t;vR(n,(jYn(),PMt))&&((t=uG(oIn(n,PMt),21)).Hc((VDn(),Vxt))?(t.Mc(Vxt),t.Fc(Xxt)):t.Hc(Xxt)&&(t.Mc(Xxt),t.Fc(Vxt)))}function xTn(n,t,e,i){var r,c,a;return null==n.a&&nOn(n,t),a=t.b.j.c.length,c=e.d.p,(r=i.d.p-1)<0&&(r=a-1),c<=r?n.a[r]-n.a[c]:n.a[a-1]-n.a[c]+n.a[r]}function RTn(n){var t,e;if(!n.b)for(n.b=o6(uG(n.f,27).kh().i),e=new DD(uG(n.f,27).kh());e.e!=e.i.gc();)t=uG(Zkn(e),135),kD(n.b,new Wy(t));return n.b}function KTn(n){var t,e;if(!n.e)for(n.e=o6(RJ(uG(n.f,27)).i),e=new DD(RJ(uG(n.f,27)));e.e!=e.i.gc();)t=uG(Zkn(e),123),kD(n.e,new Jp(t));return n.e}function FTn(n){var t,e;if(!n.a)for(n.a=o6(wZ(uG(n.f,27)).i),e=new DD(wZ(uG(n.f,27)));e.e!=e.i.gc();)t=uG(Zkn(e),27),kD(n.a,new Wx(n,t));return n.a}function _Tn(n){var t;if(!n.C&&(null!=n.D||null!=n.B))if(t=KWn(n))n.hl(t);else try{n.hl(null)}catch(e){if(!F$(e=Ehn(e),63))throw hv(e)}return n.C}function BTn(n){switch(n.q.g){case 5:QEn(n,(KQn(),yRt)),QEn(n,KRt);break;case 4:TVn(n,(KQn(),yRt)),TVn(n,KRt);break;default:PAn(n,(KQn(),yRt)),PAn(n,KRt)}}function HTn(n){switch(n.q.g){case 5:JEn(n,(KQn(),kRt)),JEn(n,_Rt);break;case 4:jVn(n,(KQn(),kRt)),jVn(n,_Rt);break;default:CAn(n,(KQn(),kRt)),CAn(n,_Rt)}}function UTn(n,t){var i,r,c;for(c=new sj,r=n.Kc();r.Ob();)tHn(i=uG(r.Pb(),36),c.a,0),c.a+=i.f.a+t,c.b=e.Math.max(c.b,i.f.b);return c.b>0&&(c.b+=t),c}function GTn(n,t){var i,r,c;for(c=new sj,r=n.Kc();r.Ob();)tHn(i=uG(r.Pb(),36),0,c.b),c.b+=i.f.b+t,c.a=e.Math.max(c.a,i.f.a);return c.a>0&&(c.a+=t),c}function qTn(n){var t,i,r;for(r=vZn,i=new Ww(n.a);i.a>16==6?n.Cb.Th(n,5,fFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||n.ii(),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function WTn(n){EZ();var t=n.e;if(t&&t.stack){var e=t.stack,i=t+"\n";return e.substring(0,i.length)==i&&(e=e.substring(i.length)),e.split("\n")}return[]}function QTn(n){var t;return Tan(),(t=wot)[n>>>28]|t[n>>24&15]<<4|t[n>>20&15]<<8|t[n>>16&15]<<12|t[n>>12&15]<<16|t[n>>8&15]<<20|t[n>>4&15]<<24|t[15&n]<<28}function JTn(n){var t,i,r;n.b==n.c&&(r=n.a.length,i=pfn(e.Math.max(8,r))<<1,0!=n.b?(Pon(n,t=MF(n.a,i),r),n.a=t,n.b=0):Xv(n.a,i),n.c=r)}function YTn(n,t){var e;return(e=n.b).pf((XYn(),uDt))?e.ag()==(KQn(),_Rt)?-e.Mf().a-uM(pK(e.of(uDt))):t+uM(pK(e.of(uDt))):e.ag()==(KQn(),_Rt)?-e.Mf().a:t}function ZTn(n){var t;return 0!=n.b.c.length&&uG(zq(n.b,0),72).a?uG(zq(n.b,0),72).a:null!=(t=sY(n))?t:""+(n.c?Ten(n.c.a,n,0):-1)}function njn(n){var t;return 0!=n.f.c.length&&uG(zq(n.f,0),72).a?uG(zq(n.f,0),72).a:null!=(t=sY(n))?t:""+(n.i?Ten(n.i.j,n,0):-1)}function tjn(n,t){var e,i;if(t<0||t>=n.gc())return null;for(e=t;e0?n.c:0),c=e.Math.max(c,t.d),++r;n.e=a,n.b=c}function rjn(n){var t,e;if(!n.b)for(n.b=o6(uG(n.f,123).kh().i),e=new DD(uG(n.f,123).kh());e.e!=e.i.gc();)t=uG(Zkn(e),135),kD(n.b,new Wy(t));return n.b}function cjn(n,t){var e,i,r;if(t.dc())return EK(),EK(),KFt;for(e=new cF(n,t.gc()),r=new DD(n);r.e!=r.i.gc();)i=Zkn(r),t.Hc(i)&&ttn(e,i);return e}function ajn(n,t,e,i){return 0==t?i?(!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),n.o):(!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),Tnn(n.o)):Dyn(n,t,e,i)}function ojn(n){var t,e;if(n.rb)for(t=0,e=n.rb.i;t>22))>>22)<0||(n.l=e&f0n,n.m=i&f0n,n.h=r&l0n,0)))}function ljn(n,t,e,i,r,c,a){var o,u;return!(t.Te()&&(u=n.a.Ne(e,i),u<0||!r&&0==u)||t.Ue()&&(o=n.a.Ne(e,c),o>0||!a&&0==o))}function bjn(n,t){if(Cln(),0!=n.j.g-t.j.g)return 0;switch(n.j.g){case 2:return Wgn(t,edt)-Wgn(n,edt);case 4:return Wgn(n,tdt)-Wgn(t,tdt)}return 0}function wjn(n){switch(n.g){case 0:return jgt;case 1:return Egt;case 2:return Sgt;case 3:return Pgt;case 4:return Cgt;case 5:return Igt;default:return null}}function djn(n,t,e){var i,r;return Kbn(r=new ny,t),qon(r,e),ttn((!n.c&&(n.c=new fV(m_t,n,12,10)),n.c),r),Pcn(i=r,0),Ccn(i,1),mdn(i,!0),ddn(i,!0),i}function gjn(n,t){var e,i;if(t>=n.i)throw hv(new pL(t,n.i));return++n.j,e=n.g[t],(i=n.i-t-1)>0&&qGn(n.g,t+1,n.g,t,i),uQ(n.g,--n.i,null),n.Qi(t,e),n.Ni(),e}function pjn(n,t){var e;return n.Db>>16==17?n.Cb.Th(n,21,h_t,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||n.ii(),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function mjn(n){var t,e,i;for(hZ(),f$(n.c,n.a),i=new Ww(n.c);i.ae.a.c.length))throw hv(new vM("index must be >= 0 and <= layer node count"));n.c&&men(n.c.a,n),n.c=e,e&&GX(e.a,t,n)}function Djn(n,t){var e,i,r;for(i=new Fz(ix(Ggn(n).a.Kc(),new h));hDn(i);)return e=uG(N9(i),18),new Ul(WW((r=uG(t.Kb(e),10)).n.b+r.o.b/2));return gy(),gy(),wat}function xjn(n,t){this.c=new Ym,this.a=n,this.b=t,this.d=uG(oIn(n,(GYn(),kmt)),312),xA(oIn(n,(jYn(),CMt)))===xA((Wtn(),Lgt))?this.e=new Pk:this.e=new Sk}function Rjn(n,t){var e,i;return i=null,n.pf((XYn(),ODt))&&(e=uG(n.of(ODt),96)).pf(t)&&(i=e.of(t)),null==i&&n.Tf()&&(i=n.Tf().of(t)),null==i&&(i=Jkn(t)),i}function Kjn(n,t){var e,i;e=n.fd(t);try{return i=e.Pb(),e.Qb(),i}catch(r){throw F$(r=Ehn(r),112)?hv(new dM("Can't remove element "+t)):hv(r)}}function Fjn(n,t){var e,i,r;if(0==(e=Wqn(n,t,r=new Lfn((i=new QE).q.getFullYear()-V1n,i.q.getMonth(),i.q.getDate())))||e0?t:0),++i;return new MO(r,c)}function zjn(n,t){var e;return n.Db>>16==6?n.Cb.Th(n,6,aFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(tYn(),BKt),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function Vjn(n,t){var e;return n.Db>>16==7?n.Cb.Th(n,1,iFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(tYn(),UKt),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function Wjn(n,t){var e;return n.Db>>16==9?n.Cb.Th(n,9,bFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(tYn(),qKt),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function Qjn(n,t){var e;return n.Db>>16==5?n.Cb.Th(n,9,w_t,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(YYn(),O_t),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function Jjn(n,t){var e;return n.Db>>16==7?n.Cb.Th(n,6,fFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(YYn(),F_t),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function Yjn(n,t){var e;return n.Db>>16==3?n.Cb.Th(n,0,uFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(YYn(),T_t),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function Zjn(){this.a=new ss,this.g=new dMn,this.j=new dMn,this.b=new Ym,this.d=new dMn,this.i=new dMn,this.k=new Ym,this.c=new Ym,this.e=new Ym,this.f=new Ym}function nEn(n,t,e){var i,r,c;for(e<0&&(e=0),c=n.i,r=e;rO0n)return eEn(n,i);if(i==n)return!0}}return!1}function iEn(n){switch(Gx(),n.q.g){case 5:uNn(n,(KQn(),yRt)),uNn(n,KRt);break;case 4:Kxn(n,(KQn(),yRt)),Kxn(n,KRt);break;default:$Qn(n,(KQn(),yRt)),$Qn(n,KRt)}}function rEn(n){switch(Gx(),n.q.g){case 5:k$n(n,(KQn(),kRt)),k$n(n,_Rt);break;case 4:fyn(n,(KQn(),kRt)),fyn(n,_Rt);break;default:DQn(n,(KQn(),kRt)),DQn(n,_Rt)}}function cEn(n){var t,e;(t=uG(oIn(n,(cGn(),Dft)),17))?(e=t.a,kfn(n,(mon(),Qft),0==e?new Upn:new v8(e))):kfn(n,(mon(),Qft),new v8(1))}function aEn(n,t){var e;switch(e=n.i,t.g){case 1:return-(n.n.b+n.o.b);case 2:return n.n.a-e.o.a;case 3:return n.n.b-e.o.b;case 4:return-(n.n.a+n.o.a)}return 0}function oEn(n,t){switch(n.g){case 0:return t==(Gpn(),Imt)?qwt:Xwt;case 1:return t==(Gpn(),Imt)?qwt:Gwt;case 2:return t==(Gpn(),Imt)?Gwt:Xwt;default:return Gwt}}function uEn(n,t){var i,r,c;for(men(n.a,t),n.e-=t.r+(0==n.a.c.length?0:n.c),c=b7n,r=new Ww(n.a);r.a>16==3?n.Cb.Th(n,12,bFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(tYn(),_Kt),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function hEn(n,t){var e;return n.Db>>16==11?n.Cb.Th(n,10,bFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(tYn(),GKt),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function fEn(n,t){var e;return n.Db>>16==10?n.Cb.Th(n,11,h_t,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(YYn(),R_t),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function lEn(n,t){var e;return n.Db>>16==10?n.Cb.Th(n,12,p_t,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(YYn(),__t),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function bEn(n){var t;return 1&n.Bb||!n.r||!n.r.Vh()||(t=uG(n.r,54),n.r=uG(mwn(n,t),142),n.r!=t&&4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,9,8,t,n.r))),n.r}function wEn(n,t,i){var r;return r=Uhn(cT(eUt,1),I0n,28,15,[BCn(n,(Yrn(),jst),t,i),BCn(n,Est,t,i),BCn(n,Sst,t,i)]),n.f&&(r[0]=e.Math.max(r[0],r[2]),r[2]=r[0]),r}function dEn(n,t){var e,i,r;if(0!=(r=lyn(n,t)).c.length)for(f$(r,new ti),e=r.c.length,i=0;i>19)!=(o=t.h>>19)?o-a:(i=n.h)!=(c=t.h)?i-c:(e=n.m)!=(r=t.m)?e-r:n.l-t.l}function MEn(){MEn=E,W_n(),ost=new mL($2n,ust=dst),Xin(),cst=new mL(D2n,ast=Zut),_kn(),ist=new mL(x2n,rst=Wut),est=new mL(R2n,(qx(),!0))}function TEn(n,t,e){var i,r;i=t*e,F$(n.g,154)?(r=Q6(n)).f.d?r.f.a||(n.d.a+=i+Z2n):(n.d.d-=i+Z2n,n.d.a+=i+Z2n):F$(n.g,10)&&(n.d.d-=i,n.d.a+=2*i)}function jEn(n,t,i){var r,c,a,o,u;for(c=n[i.g],u=new Ww(t.d);u.a0?n.b:0),++i;t.b=r,t.e=c}function SEn(n){var t,e,i;if(i=n.b,aS(n.i,i.length)){for(e=2*i.length,n.b=Inn(Cat,l1n,303,e,0,1),n.c=Inn(Cat,l1n,303,e,0,1),n.f=e-1,n.i=0,t=n.a;t;t=t.c)HLn(n,t,t);++n.g}}function PEn(n,t,e,i){var r,c,a,o;for(r=0;ro&&(u=o/r),(c=e.Math.abs(n.b))>a&&(s=a/c),vD(n,e.Math.min(u,s)),n}function AEn(){var n,t;tXn();try{if(t=uG(ASn((MP(),l_t),aet),2113))return t}catch(e){if(!F$(e=Ehn(e),103))throw hv(e);n=e,AW((t$(),n))}return new rs}function LEn(){var n,t;tXn();try{if(t=uG(ASn((MP(),l_t),Drt),2040))return t}catch(e){if(!F$(e=Ehn(e),103))throw hv(e);n=e,AW((t$(),n))}return new _s}function NEn(){var n,t;Ftn();try{if(t=uG(ASn((MP(),l_t),lct),2122))return t}catch(e){if(!F$(e=Ehn(e),103))throw hv(e);n=e,AW((t$(),n))}return new Nh}function $En(n,t,e){var i,r;return r=n.e,n.e=t,4&n.Db&&!(1&n.Db)&&(i=new lV(n,1,4,r,t),e?e.nj(i):e=i),r!=t&&(e=PWn(n,t?bRn(n,t):n.a,e)),e}function DEn(){QE.call(this),this.e=-1,this.a=!1,this.p=j1n,this.k=-1,this.c=-1,this.b=-1,this.g=!1,this.f=-1,this.j=-1,this.n=-1,this.i=-1,this.d=-1,this.o=j1n}function xEn(n,t){var e,i,r;if(i=n.b.d.d,n.a||(i+=n.b.d.a),r=t.b.d.d,t.a||(r+=t.b.d.a),0==(e=ugn(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function REn(n,t){var e,i,r;if(i=n.b.b.d,n.a||(i+=n.b.b.a),r=t.b.b.d,t.a||(r+=t.b.b.a),0==(e=ugn(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function KEn(n,t){var e,i,r;if(i=n.b.g.d,n.a||(i+=n.b.g.a),r=t.b.g.d,t.a||(r+=t.b.g.a),0==(e=ugn(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function FEn(){FEn=E,klt=wz(Aq(Aq(Aq(new wJ,(uIn(),Slt),(zYn(),owt)),Slt,fwt),Plt,mwt),Plt,Wbt),Mlt=Aq(Aq(new wJ,Slt,Fbt),Slt,Qbt),ylt=wz(new wJ,Plt,Ybt)}function _En(n){var t,e,i,r,c;for(t=uG(oIn(n,(GYn(),$pt)),85),c=n.n,i=t.Cc().Kc();i.Ob();)(r=(e=uG(i.Pb(),314)).i).c+=c.a,r.d+=c.b,e.c?P_n(e):C_n(e);kfn(n,$pt,null)}function BEn(n,t,e){var i,r;switch(i=(r=n.b).d,t.g){case 1:return-i.d-e;case 2:return r.o.a+i.c+e;case 3:return r.o.b+i.a+e;case 4:return-i.b-e;default:return-1}}function HEn(n,t,e){var i;for(e.Ug("Interactive node placement",1),n.a=uG(oIn(t,(GYn(),kmt)),312),i=new Ww(t.b);i.a0&&(r=ZNn(n,(c&vZn)%n.d.length,c,t))?r.nd(e):(i=n.ck(c,t,e),n.c.Fc(i),null)}function cSn(n,t){var e,i,r,c;switch(tdn(n,t).Kl()){case 3:case 2:for(r=0,c=(e=hXn(t)).i;r=0;r--)if(m_(n[r].d,t)||m_(n[r].d,i)){n.length>=r+1&&n.splice(0,r+1);break}return n}function bSn(n,t){var i;return _L(n)&&_L(t)&&p0n<(i=n/t)&&i0&&(n.b+=2,n.a+=r):(n.b+=1,n.a+=e.Math.min(r,c))}function ySn(n){var t;t=uG(oIn(uG(hyn(n.b,0),40),(QGn(),pCt)),107),kfn(n,(OQn(),kPt),new MO(0,0)),rUn(new L7,n,t.b+t.c-uM(pK(oIn(n,PPt))),t.d+t.a-uM(pK(oIn(n,IPt))))}function MSn(n,t){var e;if(e=!1,RA(t)&&(e=!0,pQ(n,new QW(mK(t)))),e||F$(t,242)&&(e=!0,pQ(n,new Pb(Q_(uG(t,242))))),!e)throw hv(new pM(Cet))}function TSn(n,t,e,i){var r,c,a;return r=new Ken(n.e,1,10,F$(a=t.c,90)?uG(a,29):(YYn(),x_t),F$(c=e.c,90)?uG(c,29):(YYn(),x_t),Hyn(n,t),!1),i?i.nj(r):i=r,i}function jSn(n){var t,e;switch(uG(oIn(HQ(n),(jYn(),lMt)),429).g){case 0:return t=n.n,e=n.o,new MO(t.a+e.a/2,t.b+e.b/2);case 1:return new eN(n.n);default:return null}}function ESn(){ESn=E,Fgt=new rI(q4n,0),Kgt=new rI("LEFTUP",1),Bgt=new rI("RIGHTUP",2),Rgt=new rI("LEFTDOWN",3),_gt=new rI("RIGHTDOWN",4),xgt=new rI("BALANCED",5)}function SSn(n,t,e){var i,r,c;if(0==(i=ugn(n.a[t.p],n.a[e.p]))){if(r=uG(oIn(t,(GYn(),Vpt)),15),c=uG(oIn(e,Vpt),15),r.Hc(e))return-1;if(c.Hc(t))return 1}return i}function PSn(n){switch(n.g){case 1:return new So;case 2:return new Po;case 3:return new Eo;case 0:return null;default:throw hv(new vM(k7n+(null!=n.f?n.f:""+n.g)))}}function CSn(n,t,e){switch(t){case 1:return!n.n&&(n.n=new fV(lFt,n,1,7)),Czn(n.n),!n.n&&(n.n=new fV(lFt,n,1,7)),void CW(n.n,uG(e,16));case 2:return void Gan(n,mK(e))}bln(n,t,e)}function ISn(n,t,e){switch(t){case 3:return void vcn(n,uM(pK(e)));case 4:return void kcn(n,uM(pK(e)));case 5:return void ycn(n,uM(pK(e)));case 6:return void Mcn(n,uM(pK(e)))}CSn(n,t,e)}function OSn(n,t,e){var i,r;(i=CCn(r=new ny,t,null))&&i.oj(),qon(r,e),ttn((!n.c&&(n.c=new fV(m_t,n,12,10)),n.c),r),Pcn(r,0),Ccn(r,1),mdn(r,!0),ddn(r,!0)}function ASn(n,t){var e,i;return F$(e=_P(n.i,t),241)?((i=uG(e,241)).zi(),i.wi()):F$(e,507)?i=uG(e,2037).b:null}function LSn(n,t,e,i){var r,c;return WW(t),WW(e),Ren(!!(c=uG(W_(n.d,t),17)),"Row %s not in %s",t,n.e),Ren(!!(r=uG(W_(n.b,e),17)),"Column %s not in %s",e,n.c),Hhn(n,c.a,r.a,i)}function NSn(n,t,e,i,r,c,a){var o,u,s,h,f;if(f=PTn(o=(s=c==a-1)?i:0,h=r[c]),10!=i&&Uhn(cT(n,a-c),t[c],e[c],o,f),!s)for(++c,u=0;u1||-1==o?(c=uG(u,15),r.Wb(Vpn(n,c))):r.Wb(uUn(n,uG(u,58))))}function zSn(n,t,e,i){kE();var r=hZn;function c(){for(var n=0;n0)return!1;return!0}function QSn(n){var t,e,i,r,c;for(i=new bsn(new Nw(n.b).a);i.b;)t=uG((e=von(i)).ld(),10),c=uG(uG(e.md(),42).a,10),r=uG(uG(e.md(),42).b,8),JF(dL(t.n),JF(D$(c.n),r))}function JSn(n){switch(uG(oIn(n.b,(jYn(),Jyt)),387).g){case 1:kS(YJ(sin(new fX(null,new h3(n.d,16)),new Vr),new Wr),new Qr);break;case 2:gBn(n);break;case 0:mLn(n)}}function YSn(n,t,e){var i,r,c;for(!(i=e)&&(i=new fy),i.Ug("Layout",n.a.c.length),c=new Ww(n.a);c.a$9n)return e;i>-1e-6&&++e}return e}function rPn(n,t){var e;t!=n.b?(e=null,n.b&&(e=O1(n.b,n,-4,e)),t&&(e=kyn(t,n,-4,e)),(e=kwn(n,t,e))&&e.oj()):4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,3,t,t))}function cPn(n,t){var e;t!=n.f?(e=null,n.f&&(e=O1(n.f,n,-1,e)),t&&(e=kyn(t,n,-1,e)),(e=vwn(n,t,e))&&e.oj()):4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,0,t,t))}function aPn(n,t,e,i){var r,c,a;return uN(n.e)&&(a=VZ(n,1,r=t.Lk(),t.md(),c=e.md(),r.Jk()?Dqn(n,r,c,F$(r,102)&&!!(uG(r,19).Bb&P0n)):-1,!0),i?i.nj(a):i=a),i}function oPn(n){var t,e,i;if(null==n)return null;if((e=uG(n,15)).dc())return"";for(i=new zM,t=e.Kc();t.Ob();)VA(i,(uVn(),mK(t.Pb()))),i.a+=" ";return CL(i,i.a.length-1)}function uPn(n){var t,e,i;if(null==n)return null;if((e=uG(n,15)).dc())return"";for(i=new zM,t=e.Kc();t.Ob();)VA(i,(uVn(),mK(t.Pb()))),i.a+=" ";return CL(i,i.a.length-1)}function sPn(n,t,e){var i,r;return i=n.c[t.c.p][t.p],r=n.c[e.c.p][e.p],null!=i.a&&null!=r.a?Rz(i.a,r.a):null!=i.a?-1:null!=r.a?1:0}function hPn(n,t,e){return e.Ug("Tree layout",1),_J(n.b),JV(n.b,(Cjn(),zSt),zSt),JV(n.b,VSt,VSt),JV(n.b,WSt,WSt),JV(n.b,QSt,QSt),n.a=Qzn(n.b,t),YSn(n,t,e.eh(1)),e.Vg(),t}function fPn(n,t){var e,i,r;if(t)for(r=((e=new Gz(t.a.length)).b-e.a)*e.c<0?(CP(),XHt):new xD(e);r.Ob();)i=v6(t,uG(r.Pb(),17).a),QJ(new om(n).a,i)}function lPn(n,t){var e,i,r;if(t)for(r=((e=new Gz(t.a.length)).b-e.a)*e.c<0?(CP(),XHt):new xD(e);r.Ob();)i=v6(t,uG(r.Pb(),17).a),WJ(new Yp(n).a,i)}function bPn(n){if(null!=n&&n.length>0&&33==VJ(n,n.length-1))try{return null==sxn(r1(n,0,n.length-1)).e}catch(t){if(!F$(t=Ehn(t),33))throw hv(t)}return!1}function wPn(n,t,e){var i,r;switch(i=pgn(HQ(t)),o2(r=new lOn,t),e.g){case 1:NLn(r,Gdn(Ipn(i)));break;case 2:NLn(r,Ipn(i))}return kfn(r,(jYn(),QMt),pK(oIn(n,QMt))),r}function dPn(n){var t,e;return t=uG(N9(new Fz(ix(qgn(n.a).a.Kc(),new h))),18),e=uG(N9(new Fz(ix(Xgn(n.a).a.Kc(),new h))),18),oM(gK(oIn(t,(GYn(),pmt))))||oM(gK(oIn(e,pmt)))}function gPn(){gPn=E,wdt=new zC("ONE_SIDE",0),gdt=new zC("TWO_SIDES_CORNER",1),pdt=new zC("TWO_SIDES_OPPOSING",2),ddt=new zC("THREE_SIDES",3),bdt=new zC("FOUR_SIDES",4)}function pPn(n,t){var e,i,r,c;for(c=new Zm,r=0,i=t.Kc();i.Ob();){for(e=xwn(uG(i.Pb(),17).a+r);e.a=n.f)break;mv(c.c,e)}return c}function mPn(n,t){var e,i,r;for(i=new Ww(t.a);i.a0&&Mjn(this,this.c-1,(KQn(),kRt)),this.c0&&n[0].length>0&&(this.c=oM(gK(oIn(HQ(n[0][0]),(GYn(),Wpt))))),this.a=Inn(REt,zZn,2117,n.length,0,2),this.b=Inn(UEt,zZn,2118,n.length,0,2),this.d=new zbn}function LPn(n){return 0!=n.c.length&&((u3(0,n.c.length),uG(n.c[0],18)).c.i.k==(zIn(),wbt)||o9(YJ(new fX(null,new h3(n,16)),new xc),new Rc))}function NPn(n,t){var i,r,c,a,o,u;for(o=GFn(t),c=t.f,u=t.g,a=e.Math.sqrt(c*c+u*u),r=0,i=new Ww(o);i.a=0?(e=bSn(n,g0n),i=Kmn(n,g0n)):(e=bSn(t=Dz(n,1),5e8),i=Lgn(Nz(i=Kmn(t,5e8),1),E3(n,1))),S3(Nz(i,32),E3(e,L0n))}function YPn(n,t,e){var i;switch(MK(0!=t.b),i=uG(Lrn(t,t.a.a),8),e.g){case 0:i.b=0;break;case 2:i.b=n.f;break;case 3:i.a=0;break;default:i.a=n.g}return lW(Fkn(t,0),i),t}function ZPn(n,t,e,i){var r,c,a,o,u;switch(u=n.b,o=ykn(a=(c=t.d).j,u.d[a.g],e),r=JF(D$(c.n),c.a),c.j.g){case 1:case 3:o.a+=r.a;break;case 2:case 4:o.b+=r.b}s8(i,o,i.c.b,i.c)}function nCn(n,t,e){var i,r,c,a;for(a=Ten(n.e,t,0),(c=new Tk).b=e,i=new N4(n.e,a);i.b1;t>>=1)1&t&&(i=j5(i,e)),e=1==e.d?j5(e,e):new nkn(_Un(e.a,e.d,Inn(YHt,W1n,28,e.d<<1,15,1)));return i=j5(i,e)}function aCn(){var n,t,e,i;for(aCn=E,but=Inn(eUt,I0n,28,25,15,1),wut=Inn(eUt,I0n,28,33,15,1),i=152587890625e-16,t=32;t>=0;t--)wut[t]=i,i*=.5;for(e=1,n=24;n>=0;n--)but[n]=e,e*=.5}function oCn(n){var t,e;if(oM(gK(zDn(n,(jYn(),sMt)))))for(e=new Fz(ix(eRn(n).a.Kc(),new h));hDn(e);)if(BNn(t=uG(N9(e),74))&&oM(gK(zDn(t,hMt))))return!0;return!1}function uCn(n,t){var e,i,r;FV(n.f,t)&&(t.b=n,i=t.c,-1!=Ten(n.j,i,0)||kD(n.j,i),r=t.d,-1!=Ten(n.j,r,0)||kD(n.j,r),0!=(e=t.a.b).c.length&&(!n.i&&(n.i=new vkn(n)),Psn(n.i,e)))}function sCn(n){var t,e,i,r;return(e=(t=n.c.d).j)==(r=(i=n.d.d).j)?t.p=0&&m_(n.substr(t,3),"GMT")||t>=0&&m_(n.substr(t,3),"UTC")?(e[0]=t+3,PUn(n,e,i)):PUn(n,e,i)}function wCn(n,t){var e,i,r,c,a;for(c=n.g.a,a=n.g.b,i=new Ww(n.d);i.ae;c--)n[c]|=t[c-e-1]>>>a,n[c-1]=t[c-e-1]<0&&qGn(n.g,t,n.g,t+i,o),a=e.Kc(),n.i+=i,r=0;r>4&15,c=15&n[i],a[r++]=JKt[e],a[r++]=JKt[c];return mvn(a,0,a.length)}function $Cn(n){var t,e;return n>=P0n?(t=C0n+(n-P0n>>10&1023)&D1n,e=56320+(n-P0n&1023)&D1n,String.fromCharCode(t)+""+String.fromCharCode(e)):String.fromCharCode(n&D1n)}function DCn(n,t){var e,i,r,c;return VK(),(r=uG(uG(Y9(n.r,t),21),87)).gc()>=2&&(i=uG(r.Kc().Pb(),117),e=n.u.Hc((eNn(),bRt)),c=n.u.Hc(pRt),!i.a&&!e&&(2==r.gc()||c))}function xCn(n,t,e,i,r){var c,a,o;for(c=zFn(n,t,e,i,r),o=!1;!c;)gxn(n,r,!0),o=!0,c=zFn(n,t,e,i,r);o&&gxn(n,r,!1),0!=(a=Jhn(r)).c.length&&(n.d&&n.d.Gg(a),xCn(n,r,e,i,a))}function RCn(){RCn=E,mxt=new OO(q4n,0),gxt=new OO("DIRECTED",1),vxt=new OO("UNDIRECTED",2),wxt=new OO("ASSOCIATION",3),pxt=new OO("GENERALIZATION",4),dxt=new OO("DEPENDENCY",5)}function KCn(n,t){var e;if(!h0(n))throw hv(new kM(Stt));switch(e=h0(n),t.g){case 1:return-(n.j+n.f);case 2:return n.i-e.g;case 3:return n.j-e.f;case 4:return-(n.i+n.g)}return 0}function FCn(n,t,e){var i,r,c;return i=t.Lk(),c=t.md(),r=i.Jk()?VZ(n,4,i,c,null,Dqn(n,i,c,F$(i,102)&&!!(uG(i,19).Bb&P0n)),!0):VZ(n,i.tk()?2:1,i,c,i.ik(),-1,!0),e?e.nj(r):e=r,e}function _Cn(n,t){var e,i;for(tJ(t),i=n.b.c.length,kD(n.b,t);i>0;){if(e=i,i=(i-1)/2|0,n.a.Ne(zq(n.b,i),t)<=0)return Y8(n.b,e,t),!0;Y8(n.b,e,zq(n.b,i))}return Y8(n.b,i,t),!0}function BCn(n,t,i,r){var c,a;if(c=0,i)c=$bn(n.a[i.g][t.g],r);else for(a=0;a<$st;a++)c=e.Math.max(c,$bn(n.a[a][t.g],r));return t==(Yrn(),Est)&&n.b&&(c=e.Math.max(c,n.b.a)),c}function HCn(n,t){var e,i,r,c,a;return i=n.i,r=t.i,!(!i||!r)&&i.i==r.i&&i.i!=(KQn(),kRt)&&i.i!=(KQn(),_Rt)&&(e=(c=i.g.a)+i.j.a,c<=(a=r.g.a)+r.j.a&&e>=a)}function UCn(n){switch(n.g){case 0:return new Uo;case 1:return new qo;default:throw hv(new vM("No implementation is available for the width approximator "+(null!=n.f?n.f:""+n.g)))}}function GCn(n,t,e,i){var r;if(r=!1,RA(i)&&(r=!0,ZG(t,e,mK(i))),r||KA(i)&&(r=!0,GCn(n,t,e,i)),r||F$(i,242)&&(r=!0,vZ(t,e,uG(i,242))),!r)throw hv(new pM(Cet))}function qCn(n,t){var e,i,r;if((e=t.qi(n.a))&&null!=(r=Lmn((!e.b&&(e.b=new XR((YYn(),H_t),wBt,e)),e.b),Srt)))for(i=1;i<(gAn(),mBt).length;++i)if(m_(mBt[i],r))return i;return 0}function XCn(n,t){var e,i,r;if((e=t.qi(n.a))&&null!=(r=Lmn((!e.b&&(e.b=new XR((YYn(),H_t),wBt,e)),e.b),Srt)))for(i=1;i<(gAn(),vBt).length;++i)if(m_(vBt[i],r))return i;return 0}function zCn(n,t){var e,i,r,c;if(tJ(t),(c=n.a.gc())0?1:0;c.a[r]!=e;)c=c.a[r],r=n.a.Ne(e.d,c.d)>0?1:0;c.a[r]=i,i.b=e.b,i.a[0]=e.a[0],i.a[1]=e.a[1],e.a[0]=null,e.a[1]=null}function ZCn(n){var t,e,i,r;for(t=new Zm,zV(e=Inn(ZHt,B2n,28,n.a.c.length,16,1),e.length),r=new Ww(n.a);r.a0&&lUn((u3(0,e.c.length),uG(e.c[0],30)),n),e.c.length>1&&lUn(uG(zq(e,e.c.length-1),30),n),t.Vg()}function eIn(n){return eNn(),!(qsn(X1(WX(wRt,Uhn(cT(BRt,1),p1n,279,0,[gRt])),n))>1||qsn(X1(WX(bRt,Uhn(cT(BRt,1),p1n,279,0,[lRt,pRt])),n))>1)}function iIn(n,t){F$(U1((MP(),l_t),n),507)?r2(l_t,n,new EA(this,t)):r2(l_t,n,this),HIn(this,t),t==(vj(),y_t)?(this.wb=uG(this,2038),uG(t,2040)):this.wb=(tQ(),M_t)}function rIn(n){var t,e;if(null==n)return null;for(t=null,e=0;e=$1n?"error":i>=900?"warn":i>=800?"info":"log",n.a),n.b&&SKn(t,e,n.b,"Exception: ",!0))}function oIn(n,t){var e,i;return!n.q&&(n.q=new Ym),null!=(i=cQ(n.q,t))?i:(F$(e=t.Sg(),4)&&(null==e?(!n.q&&(n.q=new Ym),u7(n.q,t)):(!n.q&&(n.q=new Ym),vJ(n.q,t,e))),e)}function uIn(){uIn=E,Tlt=new gC("P1_CYCLE_BREAKING",0),jlt=new gC("P2_LAYERING",1),Elt=new gC("P3_NODE_ORDERING",2),Slt=new gC("P4_NODE_PLACEMENT",3),Plt=new gC("P5_EDGE_ROUTING",4)}function sIn(n,t){var e;if(Win(),n.c==t.c){if(n.b==t.b||eun(n.b,t.b)){if(e=BL(n.b)?1:-1,n.a&&!t.a)return e;if(!n.a&&t.a)return-e}return d$(n.b.g,t.b.g)}return ugn(n.c,t.c)}function hIn(n,t){var e,i;if(kIn(n,t))return!0;for(i=new Ww(t);i.a=(r=n.Ej())||t<0)throw hv(new dM(zet+t+Vet+r));if(e>=r||e<0)throw hv(new dM(Wet+e+Vet+r));return t!=e?(c=n.Cj(e),n.qj(t,c),i=c):i=n.xj(e),i}function mIn(n){var t,e,i;if(i=n,n)for(t=0,e=n.Eh();e;e=e.Eh()){if(++t>O0n)return mIn(e);if(i=e,e==n)throw hv(new kM("There is a cycle in the containment hierarchy of "+n))}return i}function vIn(n){var t,e,i;for(i=new Ysn(TZn,"[","]"),e=n.Kc();e.Ob();)o7(i,xA(t=e.Pb())===xA(n)?"(this Collection)":null==t?IZn:cpn(t));return i.a?0==i.e.length?i.a.a:i.a.a+""+i.e:i.c}function kIn(n,t){var e,i;if(i=!1,t.gc()<2)return!1;for(e=0;e1&&(n.j.b+=n.e)):(n.j.a+=i.a,n.j.b=e.Math.max(n.j.b,i.b),n.d.c.length>1&&(n.j.a+=n.e))}function jIn(){jIn=E,ydt=Uhn(cT(YRt,1),z4n,64,0,[(KQn(),yRt),kRt,KRt]),kdt=Uhn(cT(YRt,1),z4n,64,0,[kRt,KRt,_Rt]),Mdt=Uhn(cT(YRt,1),z4n,64,0,[KRt,_Rt,yRt]),Tdt=Uhn(cT(YRt,1),z4n,64,0,[_Rt,yRt,kRt])}function EIn(n,t,e,i){var r,c,a,o,u;if(c=n.c.d,a=n.d.d,c.j!=a.j)for(u=n.b,r=c.j,o=null;r!=a.j;)o=0==t?qdn(r):Udn(r),aq(i,JF(ykn(r,u.d[r.g],e),ykn(o,u.d[o.g],e))),r=o}function SIn(n,t,e,i){var r,c,a,o,u;return o=uG((a=Sjn(n.a,t,e)).a,17).a,c=uG(a.b,17).a,i&&(u=uG(oIn(t,(GYn(),lmt)),10),r=uG(oIn(e,lmt),10),u&&r&&(C5(n.b,u,r),o+=n.b.i,c+=n.b.e)),o>c}function PIn(n){var t,e,i,r,c,a,o,u;for(this.a=Fyn(n),this.b=new Zm,i=0,r=(e=n).length;iGK(n.d).c?(n.i+=n.g.c,Bmn(n.d)):GK(n.d).c>GK(n.g).c?(n.e+=n.d.c,Bmn(n.g)):(n.i+=TX(n.g),n.e+=TX(n.d),Bmn(n.g),Bmn(n.d))}function LIn(n,t,e){var i,r,c,a;for(c=t.q,a=t.r,new A2((_7(),$St),t,c,1),new A2($St,c,a,1),r=new Ww(e);r.au&&(s=u/r),(c=e.Math.abs(t.b-n.b))>a&&(h=a/c),o=e.Math.min(s,h),n.a+=o*(t.a-n.a),n.b+=o*(t.b-n.b)}function FIn(n,t,e,i,r){var c,a;for(a=!1,c=uG(zq(e.b,0),27);Sqn(n,t,c,i,r)&&(a=!0,HSn(e,c),0!=e.b.c.length);)c=uG(zq(e.b,0),27);return 0==e.b.c.length&&uEn(e.j,e),a&&OTn(t.q),a}function _In(n,t){var e,i,r,c;if(l_n(),t.b<2)return!1;for(i=e=uG(I6(c=Fkn(t,0)),8);c.b!=c.d.c;){if(VRn(n,i,r=uG(I6(c),8)))return!0;i=r}return!!VRn(n,i,e)}function BIn(n,t,e,i){return 0==e?(!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),G_(n.o,t,i)):uG(ern(uG(Lsn(n,16),29)||n.ii(),e),69).wk().Ak(n,$vn(n),e-iQ(n.ii()),t,i)}function HIn(n,t){var e;t!=n.sb?(e=null,n.sb&&(e=uG(n.sb,54).Th(n,1,sFt,e)),t&&(e=uG(t,54).Rh(n,1,sFt,e)),(e=Jwn(n,t,e))&&e.oj()):4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,4,t,t))}function UIn(n,t){var e,i;if(!t)throw hv(new SM("All edge sections need an end point."));e=$cn(t,"x"),mcn(new rm(n).a,(tJ(e),e)),i=$cn(t,"y"),jcn(new cm(n).a,(tJ(i),i))}function GIn(n,t){var e,i;if(!t)throw hv(new SM("All edge sections need a start point."));e=$cn(t,"x"),Tcn(new tm(n).a,(tJ(e),e)),i=$cn(t,"y"),Ecn(new em(n).a,(tJ(i),i))}function qIn(n,t){var e,i,r,c,a;for(i=0,c=xln(n).length;i>22-t,r=n.h<>22-t):t<44?(e=0,i=n.l<>44-t):(e=0,i=0,r=n.l<n)throw hv(new vM("k must be smaller than n"));return 0==t||t==n?1:0==n?0:uSn(n)/(uSn(t)*uSn(n-t))}function iOn(n,t){var e,i,r,c;for(e=new jN(n);null!=e.g||e.c?null==e.g||0!=e.i&&uG(e.g[e.i-1],51).Ob():O0(e);)if(F$(c=uG(Wxn(e),58),167))for(i=uG(c,167),r=0;r>4],t[2*e+1]=mHt[15&r];return mvn(t,0,t.length)}function vOn(n){var t;switch(TJ(),n.c.length){case 0:return Eat;case 1:return fq((t=uG(ULn(new Ww(n)),44)).ld(),t.md());default:return new xy(uG(Ekn(n,Inn(Sat,c1n,44,n.c.length,0,1)),173))}}function kOn(n){var t,e,i,r,c;for(t=new ND,e=new ND,A6(t,n),A6(e,n);e.b!=e.c;)for(c=new Ww(uG(xV(e),36).a);c.a0&&sHn(n,e,t),r):j$n(n,t,e)}function jOn(){jOn=E,XYn(),BIt=mDt,VIt=DDt,$It=_$t,DIt=U$t,xIt=q$t,NIt=K$t,RIt=V$t,_It=bDt,EHn(),AIt=dIt,LIt=gIt,UIt=MIt,XIt=EIt,GIt=TIt,qIt=jIt,KIt=mIt,FIt=kIt,HIt=yIt,zIt=SIt,WIt=CIt,OIt=wIt}function EOn(n,t){var e,i,r,c,a;if(n.e<=t)return n.g;if(l3(n,n.g,t))return n.g;for(c=n.r,i=n.g,a=n.r,r=(c-i)/2+i;i+11&&(n.e.b+=n.a)):(n.e.a+=i.a,n.e.b=e.Math.max(n.e.b,i.b),n.d.c.length>1&&(n.e.a+=n.a))}function NOn(n){var t,e,i,r;switch(t=(r=n.i).b,i=r.j,e=r.g,r.a.g){case 0:e.a=(n.g.b.o.a-i.a)/2;break;case 1:e.a=t.d.n.a+t.d.a.a;break;case 2:e.a=t.d.n.a+t.d.a.a-i.a;break;case 3:e.b=t.d.n.b+t.d.a.b}}function $On(n,t,e){var i,r,c;for(r=new Fz(ix(Ggn(e).a.Kc(),new h));hDn(r);)v9(i=uG(N9(r),18))||!v9(i)&&i.c.i.c==i.d.i.c||(c=aRn(n,i,e,new Ck)).c.length>1&&mv(t.c,c)}function DOn(n,t,e,i,r){if(ii&&(n.a=i),n.br&&(n.b=r),n}function xOn(n){if(F$(n,143))return dKn(uG(n,143));if(F$(n,233))return Mpn(uG(n,233));if(F$(n,23))return WIn(uG(n,23));throw hv(new vM(Aet+vIn(new IM(Uhn(cT(dat,1),EZn,1,5,[n])))))}function ROn(n,t,e,i,r){var c,a,o;for(c=!0,a=0;a>>r|e[a+i+1]<>>r,++a}return c}function KOn(n,t,e,i){var r,c;if(t.k==(zIn(),wbt))for(c=new Fz(ix(qgn(t).a.Kc(),new h));hDn(c);)if((r=uG(N9(c),18)).c.i.k==wbt&&n.c.a[r.c.i.c.p]==i&&n.c.a[t.c.p]==e)return!0;return!1}function FOn(n,t){var e,i,r,c;return t&=63,e=n.h&l0n,t<22?(c=e>>>t,r=n.m>>t|e<<22-t,i=n.l>>t|n.m<<22-t):t<44?(c=0,r=e>>>t-22,i=n.m>>t-22|n.h<<44-t):(c=0,r=0,i=e>>>t-44),p$(i&f0n,r&f0n,c&l0n)}function _On(n,t,e,i){var r;this.b=i,this.e=n==(ean(),BEt),r=t[e],this.d=Jq(ZHt,[zZn,B2n],[183,28],16,[r.length,r.length],2),this.a=Jq(YHt,[zZn,W1n],[53,28],15,[r.length,r.length],2),this.c=new IPn(t,e)}function BOn(n){var t,e,i;for(n.k=new L2((KQn(),Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt])).length,n.j.c.length),i=new Ww(n.j);i.a=e)return YOn(n,t,i.p),!0;return!1}function XOn(n,t,e,i){var r,c,a,o,u,s;for(a=e.length,c=0,r=-1,s=Tin((s3(t,n.length+1),n.substr(t)),(cB(),out)),o=0;oc&&IV(s,Tin(e[o],out))&&(r=o,c=u);return r>=0&&(i[0]=t+c),r}function zOn(n){var t;return 64&n.Db?rOn(n):(t=new lx(Ftt),!n.a||JA(JA((t.a+=' "',t),n.a),'"'),JA(Nj(JA(Nj(JA(Nj(JA(Nj((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function VOn(n,t,e){var i,r,c,a,o;for(o=VKn(n.e.Dh(),t),r=uG(n.g,124),i=0,a=0;ae?iLn(n,e,"start index"):t<0||t>e?iLn(t,e,"end index"):LBn("end index (%s) must not be less than start index (%s)",Uhn(cT(dat,1),EZn,1,5,[xwn(t),xwn(n)]))}function JOn(n,t){var e,i,r,c;for(i=0,r=n.length;i0&&nAn(n,c,e));t.p=0}function tAn(n){var t;this.c=new lS,this.f=n.e,this.e=n.d,this.i=n.g,this.d=n.c,this.b=n.b,this.k=n.j,this.a=n.a,n.i?this.j=n.i:this.j=new nB(t=uG(Mj(MNt),9),uG(MF(t,t.length),9),0),this.g=n.f}function eAn(n){var t,e,i,r;for(t=jQ(JA(new lx("Predicates."),"and"),40),e=!0,r=new Jw(n);r.b0?o[a-1]:Inn(pbt,e6n,10,0,0,1),r=o[a],s=a=0?n.ki(r):zLn(n,i)}else sdn(n,e,i)}function uAn(n){var t,e;if(e=null,t=!1,F$(n,211)&&(t=!0,e=uG(n,211).a),t||F$(n,263)&&(t=!0,e=""+uG(n,263).a),t||F$(n,493)&&(t=!0,e=""+uG(n,493).a),!t)throw hv(new pM(Cet));return e}function sAn(n,t,e){var i,r,c,a,o,u;for(u=VKn(n.e.Dh(),t),i=0,o=n.i,r=uG(n.g,124),a=0;a=n.d.b.c.length&&((t=new bQ(n.d)).p=i.p-1,kD(n.d.b,t),(e=new bQ(n.d)).p=i.p,kD(n.d.b,e)),a2(i,uG(zq(n.d.b,i.p),30))}function yAn(n,t,e){var i,r,c;if(!n.b[t.g]){for(n.b[t.g]=!0,!(i=e)&&(i=new L7),aq(i.b,t),c=n.a[t.g].Kc();c.Ob();)(r=uG(c.Pb(),65)).b!=t&&yAn(n,r.b,i),r.c!=t&&yAn(n,r.c,i),aq(i.a,r);return i}return null}function MAn(n){switch(n.g){case 0:case 1:case 2:return KQn(),yRt;case 3:case 4:case 5:return KQn(),KRt;case 6:case 7:case 8:return KQn(),_Rt;case 9:case 10:case 11:return KQn(),kRt;default:return KQn(),FRt}}function TAn(n,t){var e;return 0!=n.c.length&&(e=Imn((u3(0,n.c.length),uG(n.c[0],18)).c.i),n2(),e==(Yyn(),wjt)||e==bjt||o9(YJ(new fX(null,new h3(n,16)),new Kc),new up(t)))}function jAn(n,t){if(F$(t,207))return KN(n,uG(t,27));if(F$(t,193))return FN(n,uG(t,123));if(F$(t,452))return RN(n,uG(t,166));throw hv(new vM(Aet+vIn(new IM(Uhn(cT(dat,1),EZn,1,5,[t])))))}function EAn(n,t,e){var i,r;if(this.f=n,e7(e,r=(i=uG(cQ(n.b,t),260))?i.a:0),e>=(r/2|0))for(this.e=i?i.c:null,this.d=r;e++0;)Ein(this);this.b=t,this.a=null}function SAn(n,t){var e,i;t.a?WKn(n,t):(!!(e=uG(jS(n.b,t.b),60))&&e==n.a[t.b.f]&&!!e.a&&e.a!=t.b.a&&e.c.Fc(t.b),!!(i=uG(TS(n.b,t.b),60))&&n.a[i.f]==t.b&&!!i.a&&i.a!=t.b.a&&t.b.c.Fc(i),sD(n.b,t.b))}function PAn(n,t){var e,i;if(e=uG(AJ(n.b,t),127),uG(uG(Y9(n.r,t),21),87).dc())return e.n.b=0,void(e.n.c=0);e.n.b=n.C.b,e.n.c=n.C.c,n.A.Hc((Qmn(),JRt))&&vBn(n,t),i=Iyn(n,t),M_n(n,t)==(Vkn(),Zxt)&&(i+=2*n.w),e.a.a=i}function CAn(n,t){var e,i;if(e=uG(AJ(n.b,t),127),uG(uG(Y9(n.r,t),21),87).dc())return e.n.d=0,void(e.n.a=0);e.n.d=n.C.d,e.n.a=n.C.a,n.A.Hc((Qmn(),JRt))&&kBn(n,t),i=Cyn(n,t),M_n(n,t)==(Vkn(),Zxt)&&(i+=2*n.w),e.a.b=i}function IAn(n,t){var e,i,r,c;for(c=new Zm,i=new Ww(t);i.ai&&(s3(t-1,n.length),n.charCodeAt(t-1)<=32);)--t;return i>0||te.a&&(i.Hc((ZSn(),VNt))?r=(t.a-e.a)/2:i.Hc(QNt)&&(r=t.a-e.a)),t.b>e.b&&(i.Hc((ZSn(),YNt))?c=(t.b-e.b)/2:i.Hc(JNt)&&(c=t.b-e.b)),JCn(n,r,c)}function eLn(n,t,e,i,r,c,a,o,u,s,h,f,l){F$(n.Cb,90)&&yLn(y9(uG(n.Cb,90)),4),qon(n,e),n.f=a,Qdn(n,o),Ydn(n,u),Wdn(n,s),Jdn(n,h),mdn(n,f),Cgn(n,l),ddn(n,!0),Pcn(n,r),n.Zk(c),Kbn(n,t),null!=i&&(n.i=null,lon(n,i))}function iLn(n,t,e){if(n<0)return LBn(jZn,Uhn(cT(dat,1),EZn,1,5,[e,xwn(n)]));if(t<0)throw hv(new vM(SZn+t));return LBn("%s (%s) must not be greater than size (%s)",Uhn(cT(dat,1),EZn,1,5,[e,xwn(n),xwn(t)]))}function rLn(n,t,e,i,r,c){var a,o,u;if(i-e<7)Ygn(t,e,i,c);else if(rLn(t,n,o=e+r,u=o+((a=i+r)-o>>1),-r,c),rLn(t,n,u,a,-r,c),c.Ne(n[u-1],n[u])<=0)for(;e=0?n.bi(c,e):lRn(n,r,e)}else lpn(n,i,r,e)}function hLn(n){var t,e;if(n.f){for(;n.n>0;){if(F$(e=(t=uG(n.k.Xb(n.n-1),76)).Lk(),102)&&uG(e,19).Bb&Qtt&&(!n.e||e.pk()!=tFt||0!=e.Lj())&&null!=t.md())return!0;--n.n}return!1}return n.n>0}function fLn(n){var t,e,i,r;if(e=uG(n,54)._h())try{if(i=null,(t=jxn((MP(),l_t),xUn(jpn(e))))&&(r=t.ai())&&(i=r.Fl(bM(e.e))),i&&i!=n)return fLn(i)}catch(c){if(!F$(c=Ehn(c),63))throw hv(c)}return n}function lLn(n,t,e){var i,r;e.Ug("Remove overlaps",1),e.dh(t,l7n),i=uG(zDn(t,(SK(),zCt)),27),n.f=i,n.a=aMn(uG(zDn(t,(jOn(),zIt)),300)),rw(n,(tJ(r=pK(zDn(t,(XYn(),DDt)))),r)),xWn(n,t,GFn(i),e),e.dh(t,w7n)}function bLn(n){var t,e,i;if(oM(gK(zDn(n,(XYn(),C$t))))){for(i=new Zm,e=new Fz(ix(eRn(n).a.Kc(),new h));hDn(e);)BNn(t=uG(N9(e),74))&&oM(gK(zDn(t,I$t)))&&mv(i.c,t);return i}return hZ(),hZ(),zot}function wLn(n){if(!n)return By(),Vat;var t=n.valueOf?n.valueOf():n;if(t!==n){var i=Wat[typeof t];return i?i(t):Vbn(typeof t)}return n instanceof Array||n instanceof e.Array?new Eb(n):new Cb(n)}function dLn(n,t,i){var r,c,a;switch(a=n.o,(c=(r=uG(AJ(n.p,i),252)).i).b=gNn(r),c.a=dNn(r),c.b=e.Math.max(c.b,a.a),c.b>a.a&&!t&&(c.b=a.a),c.c=-(c.b-a.a)/2,i.g){case 1:c.d=-c.a;break;case 3:c.d=a.b}YGn(r),rqn(r)}function gLn(n,t,i){var r,c,a;switch(a=n.o,(c=(r=uG(AJ(n.p,i),252)).i).b=gNn(r),c.a=dNn(r),c.a=e.Math.max(c.a,a.b),c.a>a.b&&!t&&(c.a=a.b),c.d=-(c.a-a.b)/2,i.g){case 4:c.c=-c.b;break;case 2:c.c=a.a}YGn(r),rqn(r)}function pLn(n,t){var e,i,r,c,a;if(!t.dc())if(r=uG(t.Xb(0),131),1!=t.gc())for(e=1;e0)try{i=vUn(t,j1n,vZn)}catch(r){throw F$(r=Ehn(r),130)?hv(new Pen(r)):hv(r)}return!n.a&&(n.a=new qm(n)),i<(e=n.a).i&&i>=0?uG(zrn(e,i),58):null}function TLn(n,t){if(n<0)return LBn(jZn,Uhn(cT(dat,1),EZn,1,5,["index",xwn(n)]));if(t<0)throw hv(new vM(SZn+t));return LBn("%s (%s) must be less than size (%s)",Uhn(cT(dat,1),EZn,1,5,["index",xwn(n),xwn(t)]))}function jLn(n){var t,e,i,r,c;if(null==n)return IZn;for(c=new Ysn(TZn,"[","]"),i=0,r=(e=n).length;i=0?n.Lh(e,!0,!0):YNn(n,r,!0),160),uG(i,220).Zl(t)}function VLn(n){var t,i;return n>-0x800000000000&&n<0x800000000000?0==n?0:((t=n<0)&&(n=-n),i=t0(e.Math.floor(e.Math.log(n)/.6931471805599453)),(!t||n!=e.Math.pow(2,i))&&++i,i):dhn(Bsn(n))}function WLn(n){var t,e,i,r,c,a,o;for(c=new XL,e=new Ww(n);e.a2&&o.e.b+o.j.b<=2&&(r=o,i=a),c.a.zc(r,c),r.q=i);return c}function QLn(n,t,e){e.Ug("Eades radial",1),e.dh(t,w7n),n.d=uG(zDn(t,(SK(),zCt)),27),n.c=uM(pK(zDn(t,(jOn(),HIt)))),n.e=aMn(uG(zDn(t,zIt),300)),n.a=_pn(uG(zDn(t,WIt),434)),n.b=PSn(uG(zDn(t,KIt),354)),UEn(n),e.dh(t,w7n)}function JLn(n,t){if(t.Ug("Target Width Setter",1),!vnn(n,(S_n(),vAt)))throw hv(new jM("A target width has to be set if the TargetWidthWidthApproximator should be used."));Myn(n,(lBn(),POt),pK(zDn(n,vAt))),t.Vg()}function YLn(n,t){var e,i,r;return zsn(i=new gMn(n),t),kfn(i,(GYn(),Kpt),t),kfn(i,(jYn(),JMt),($Pn(),cRt)),kfn(i,byt,(nMn(),ONt)),Hb(i,(zIn(),lbt)),o2(e=new lOn,i),NLn(e,(KQn(),_Rt)),o2(r=new lOn,i),NLn(r,kRt),i}function ZLn(n){switch(n.g){case 0:return new zy((ean(),_Et));case 1:return new bl;case 2:return new wl;default:throw hv(new vM("No implementation is available for the crossing minimizer "+(null!=n.f?n.f:""+n.g)))}}function nNn(n,t){var e,i,r,c;for(n.c[t.p]=!0,kD(n.a,t),c=new Ww(t.j);c.a=(c=a.gc()))a.$b();else for(r=a.Kc(),i=0;i0?HM():c<0&&bNn(n,t,-c),!0)}function dNn(n){var t,e,i,r,c,a;if(a=0,0==n.b){for(t=0,r=0,c=(i=AMn(n,!0)).length;r0&&(a+=e,++t);t>1&&(a+=n.c*(t-1))}else a=fT(Mun(ZJ(JJ(BV(n.a),new jn),new En)));return a>0?a+n.n.d+n.n.a:0}function gNn(n){var t,e,i,r,c,a;if(a=0,0==n.b)a=fT(Mun(ZJ(JJ(BV(n.a),new Mn),new Tn)));else{for(t=0,r=0,c=(i=LMn(n,!0)).length;r0&&(a+=e,++t);t>1&&(a+=n.c*(t-1))}return a>0?a+n.n.b+n.n.c:0}function pNn(n){var t,e;if(2!=n.c.length)throw hv(new kM("Order only allowed for two paths."));u3(0,n.c.length),t=uG(n.c[0],18),u3(1,n.c.length),e=uG(n.c[1],18),t.d.i!=e.c.i&&(n.c.length=0,mv(n.c,e),mv(n.c,t))}function mNn(n,t,e){var i;for(vN(e,t.g,t.f),kN(e,t.i,t.j),i=0;i<(!t.a&&(t.a=new fV(bFt,t,10,11)),t.a).i;i++)mNn(n,uG(zrn((!t.a&&(t.a=new fV(bFt,t,10,11)),t.a),i),27),uG(zrn((!e.a&&(e.a=new fV(bFt,e,10,11)),e.a),i),27))}function vNn(n,t){var i,r,c,a;for(i=(a=uG(AJ(n.b,t),127)).a,c=uG(uG(Y9(n.r,t),21),87).Kc();c.Ob();)(r=uG(c.Pb(),117)).c&&(i.a=e.Math.max(i.a,rq(r.c)));if(i.a>0)switch(t.g){case 2:a.n.c=n.s;break;case 4:a.n.b=n.s}}function kNn(n,t){var e,i,r;return 0==(e=uG(oIn(t,(cGn(),$ft)),17).a-uG(oIn(n,$ft),17).a)?(i=YF(D$(uG(oIn(n,(mon(),zft)),8)),uG(oIn(n,Vft),8)),r=YF(D$(uG(oIn(t,zft),8)),uG(oIn(t,Vft),8)),ugn(i.a*i.b,r.a*r.b)):e}function yNn(n,t){var e,i,r;return 0==(e=uG(oIn(t,(QGn(),yCt)),17).a-uG(oIn(n,yCt),17).a)?(i=YF(D$(uG(oIn(n,(OQn(),vPt)),8)),uG(oIn(n,kPt),8)),r=YF(D$(uG(oIn(t,vPt),8)),uG(oIn(t,kPt),8)),ugn(i.a*i.b,r.a*r.b)):e}function MNn(n){var t,e;return(e=new WM).a+="e_",null!=(t=bhn(n))&&(e.a+=""+t),n.c&&n.d&&(JA((e.a+=" ",e),njn(n.c)),JA(QA((e.a+="[",e),n.c.i),"]"),JA((e.a+=Y4n,e),njn(n.d)),JA(QA((e.a+="[",e),n.d.i),"]")),e.a}function TNn(n){switch(n.g){case 0:return new Tl;case 1:return new jl;case 2:return new yl;case 3:return new kl;default:throw hv(new vM("No implementation is available for the layout phase "+(null!=n.f?n.f:""+n.g)))}}function jNn(n,t,i,r,c){var a;switch(a=0,c.g){case 1:a=e.Math.max(0,t.b+n.b-(i.b+r));break;case 3:a=e.Math.max(0,-n.b-r);break;case 2:a=e.Math.max(0,-n.a-r);break;case 4:a=e.Math.max(0,t.a+n.a-(i.a+r))}return a}function ENn(n,t,e){var i,r,c;if(e)for(c=((i=new Gz(e.a.length)).b-i.a)*i.c<0?(CP(),XHt):new xD(i);c.Ob();)r=v6(e,uG(c.Pb(),17).a),vet in r.a||ket in r.a?bHn(n,r,t):JJn(n,r,t),GD(uG(cQ(n.b,jvn(r)),74))}function SNn(n){var t,e;switch(n.b){case-1:return!0;case 0:return(e=n.t)>1||-1==e||(t=bEn(n))&&(PP(),t.lk()==srt)?(n.b=-1,!0):(n.b=1,!1);default:return!1}}function PNn(n,t){var e,i,r,c;if(EYn(n),0!=n.c||123!=n.a)throw hv(new CM(rZn((t$(),bit))));if(c=112==t,i=n.d,(e=aR(n.i,125,i))<0)throw hv(new CM(rZn((t$(),wit))));return r=r1(n.i,i,e),n.d=e+1,itn(r,c,!(512&~n.e))}function CNn(n){var t,e,i,r,c,a,o;if((i=n.a.c.length)>0)for(a=n.c.d,r=vD(YF(new MO((o=n.d.d).a,o.b),a),1/(i+1)),c=new MO(a.a,a.b),e=new Ww(n.a);e.a=0&&i=0?n.Lh(e,!0,!0):YNn(n,r,!0),160),uG(i,220).Wl(t);throw hv(new vM(Gtt+t.xe()+ztt))}function DNn(){var n;return IP(),pBt?uG(jxn((MP(),l_t),Drt),2038):(ML(Sat,new Eh),yWn(),n=uG(F$(U1((MP(),l_t),Drt),560)?U1(l_t,Drt):new dJ,560),pBt=!0,HYn(n),oZn(n),vJ((pP(),k_t),n,new Bs),r2(l_t,Drt,n),n)}function xNn(n,t){var e,i,r,c;n.j=-1,uN(n.e)?(e=n.i,c=0!=n.i,z9(n,t),i=new Ken(n.e,3,n.c,null,t,e,c),r=t.zl(n.e,n.c,null),(r=yPn(n,t,r))?(r.nj(i),r.oj()):Msn(n.e,i)):(z9(n,t),(r=t.zl(n.e,n.c,null))&&r.oj())}function RNn(n,t){var e,i,r;if(r=0,(i=t[0])>=n.length)return-1;for(s3(i,n.length),e=n.charCodeAt(i);e>=48&&e<=57&&(r=10*r+(e-48),!(++i>=n.length));)s3(i,n.length),e=n.charCodeAt(i);return i>t[0]?t[0]=i:r=-1,r}function KNn(n){var t,i,r,c,a;return i=c=uG(n.a,17).a,r=a=uG(n.b,17).a,t=e.Math.max(e.Math.abs(c),e.Math.abs(a)),c<=0&&c==a?(i=0,r=a-1):c==-t&&a!=t?(i=a,r=c,a>=0&&++i):(i=-a,r=c),new WO(xwn(i),xwn(r))}function FNn(n,t,e,i){var r,c,a,o,u,s;for(r=0;r=0&&s>=0&&u=n.i)throw hv(new dM(zet+t+Vet+n.i));if(e>=n.i)throw hv(new dM(Wet+e+Vet+n.i));return i=n.g[e],t!=e&&(t>16))>>16&16),e+=t=(i=(n>>=t)-256)>>16&8,e+=t=(i=(n<<=t)-j0n)>>16&4,(e+=t=(i=(n<<=t)-VZn)>>16&2)+2-(t=(i=(n<<=t)>>14)&~(i>>1)))}function qNn(n){var t,e,i,r;for(lZ(),aft=new Zm,cft=new Ym,rft=new Zm,!n.a&&(n.a=new fV(bFt,n,10,11)),JQn(t=n.a),r=new DD(t);r.e!=r.i.gc();)i=uG(Zkn(r),27),-1==Ten(aft,i,0)&&(e=new Zm,kD(rft,e),skn(i,e));return rft}function XNn(n,t,e){var i,r,c,a;n.a=e.b.d,F$(t,326)?(z8(c=COn(r=JFn(uG(t,74),!1,!1)),i=new Kd(n)),sqn(c,r),null!=t.of((XYn(),L$t))&&z8(uG(t.of(L$t),75),i)):((a=uG(t,422)).rh(a.nh()+n.a.a),a.sh(a.oh()+n.a.b))}function zNn(n,t){var e,i,r;for(r=new Zm,i=Fkn(t.a,0);i.b!=i.d.c;)(e=uG(I6(i),65)).c.g==n.g&&xA(oIn(e.b,(QGn(),ACt)))!==xA(oIn(e.c,ACt))&&!o9(new fX(null,new h3(r,16)),new kp(e))&&mv(r.c,e);return f$(r,new ja),r}function VNn(n,t,e){var i,r,c,a;return F$(t,153)&&F$(e,153)?(c=uG(t,153),a=uG(e,153),n.a[c.a][a.a]+n.a[a.a][c.a]):F$(t,250)&&F$(e,250)&&(i=uG(t,250),r=uG(e,250),i.a==r.a)?uG(oIn(r.a,(cGn(),$ft)),17).a:0}function WNn(n,t){var i,r,c,a,o,u,s,h;for(h=uM(pK(oIn(t,(jYn(),ITt)))),s=n[0].n.a+n[0].o.a+n[0].d.c+h,u=1;u=0?e:(o=NQ(YF(new MO(a.c+a.b/2,a.d+a.a/2),new MO(c.c+c.b/2,c.d+c.a/2))),-(oGn(c,a)-1)*o)}function JNn(n,t,e){var i;kS(new fX(null,(!e.a&&(e.a=new fV(oFt,e,6,6)),new h3(e.a,16))),new zO(n,t)),kS(new fX(null,(!e.n&&(e.n=new fV(lFt,e,1,7)),new h3(e.n,16))),new VO(n,t)),(i=uG(zDn(e,(XYn(),L$t)),75))&&fun(i,n,t)}function YNn(n,t,e){var i,r,c;if(c=iVn((gAn(),kBt),n.Dh(),t))return PP(),uG(c,69).xk()||(c=_3(Nen(kBt,c))),r=uG((i=n.Ih(c))>=0?n.Lh(i,!0,!0):YNn(n,c,!0),160),uG(r,220).Sl(t,e);throw hv(new vM(Gtt+t.xe()+ztt))}function ZNn(n,t,e,i){var r,c,a,o,u;if(r=n.d[t])if(c=r.g,u=r.i,null!=i){for(o=0;o=e&&(i=t,c=(u=(o.c+o.a)/2)-e,o.c<=u-e&&GX(n,i++,new OU(o.c,c)),(a=u+e)<=o.a&&(r=new OU(a,o.a),o3(i,n.c.length),pC(n.c,i,r)))}function o$n(n,t,e){var i,r,c,a;if(!t.dc()){for(i=new lS,a=t.Kc();a.Ob();)for(c=uG(a.Pb(),40),vJ(n.a,xwn(c.g),xwn(e)),r=new Tp(Fkn(new Mp(c).a.d,0));Jj(r.a);)s8(i,uG(I6(r.a),65).c,i.c.b,i.c);o$n(n,i,e+1)}}function u$n(n){var t;if(n.c||null!=n.g){if(null==n.g)return!0;if(0==n.i)return!1;t=uG(n.g[n.i-1],51)}else n.d=n.bj(n.f),ttn(n,n.d),t=n.d;return t==n.b&&null.Vm>=null.Um()?(Wxn(n),u$n(n)):t.Ob()}function s$n(n){if(this.a=n,n.c.i.k==(zIn(),lbt))this.c=n.c,this.d=uG(oIn(n.c.i,(GYn(),Fpt)),64);else{if(n.d.i.k!=lbt)throw hv(new vM("Edge "+n+" is not an external edge."));this.c=n.d,this.d=uG(oIn(n.d.i,(GYn(),Fpt)),64)}}function h$n(n,t){var e,i,r;r=n.b,n.b=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,3,r,n.b)),t?t!=n&&(qon(n,t.zb),Icn(n,t.d),Uan(n,null==(e=null==(i=t.c)?t.zb:i)||m_(e,t.zb)?null:e)):(qon(n,null),Icn(n,0),Uan(n,null))}function f$n(n,t){var e;this.e=(ZW(),WW(n),ZW(),Emn(n)),this.c=(WW(t),Emn(t)),FD(this.e.Rd().dc()==this.c.Rd().dc()),this.d=Qgn(this.e),this.b=Qgn(this.c),e=Jq(dat,[zZn,EZn],[5,1],5,[this.e.Rd().gc(),this.c.Rd().gc()],2),this.a=e,wan(this)}function l$n(n){var t=(!Rat&&(Rat=mJn()),Rat);return'"'+n.replace(/[\x00-\x1f\xad\u0600-\u0603\u06dd\u070f\u17b4\u17b5\u200b-\u200f\u2028-\u202e\u2060-\u2064\u206a-\u206f\ufeff\ufff9-\ufffb"\\]/g,(function(n){return z1(n,t)}))+'"'}function b$n(n,t,i,r,c,a){var o,u,s,h,f;if(0!=c)for(xA(n)===xA(i)&&(n=n.slice(t,t+c),t=0),s=i,u=t,h=t+c;u=(a=null==(e=uG(Lsn(n.a,4),129))?0:e.length))throw hv(new w_(t,a));return r=e[t],1==a?i=null:(qGn(e,0,i=Inn(xFt,Uit,424,a-1,0,1),0,t),(c=a-t-1)>0&&qGn(e,t+1,i,t,c)),Pkn(n,i),GAn(n,t,r),r}function p$n(n){var t,e;if(n.f){for(;n.n0?Ipn(e):Gdn(Ipn(e)),Myn(t,eTt,r)}function M$n(n,t){t.Ug("Partition preprocessing",1),kS(uG(l8(JJ(sin(JJ(new fX(null,new h3(n.a,16)),new mi),new vi),new ki),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15).Oc(),new yi),t.Vg()}function T$n(n,t){var e,i,r,c,a;for(a=n.j,t.a!=t.b&&f$(a,new Yr),r=a.c.length/2|0,i=0;i0&&sHn(n,e,t),c):null!=i.a?(sHn(n,t,e),-1):null!=r.a?(sHn(n,e,t),1):0}function E$n(n,t){var e,i,r,c,a;for(r=t.b.b,n.a=Inn(yat,H3n,15,r,0,1),n.b=Inn(ZHt,B2n,28,r,16,1),a=Fkn(t.b,0);a.b!=a.d.c;)c=uG(I6(a),40),n.a[c.g]=new lS;for(i=Fkn(t.a,0);i.b!=i.d.c;)e=uG(I6(i),65),n.a[e.b.g].Fc(e),n.a[e.c.g].Fc(e)}function S$n(n,t){var e,i,r,c;n.Pj()?(e=n.Ej(),c=n.Qj(),++n.j,n.qj(e,n.Zi(e,t)),i=n.Ij(3,null,t,e,c),n.Mj()&&(r=n.Nj(t,null))?(r.nj(i),r.oj()):n.Jj(i)):(vQ(n,t),n.Mj()&&(r=n.Nj(t,null))&&r.oj())}function P$n(n,t,e){var i,r,c;n.Pj()?(c=n.Qj(),edn(n,t,e),i=n.Ij(3,null,e,t,c),n.Mj()?(r=n.Nj(e,null),n.Tj()&&(r=n.Uj(e,r)),r?(r.nj(i),r.oj()):n.Jj(i)):n.Jj(i)):(edn(n,t,e),n.Mj()&&(r=n.Nj(e,null))&&r.oj())}function C$n(n,t){var e,i,r,c,a;for(a=VKn(n.e.Dh(),t),r=new ls,e=uG(n.g,124),c=n.i;--c>=0;)i=e[c],a.am(i.Lk())&&ttn(r,i);!PJn(n,r)&&uN(n.e)&&Yv(n,t.Jk()?VZ(n,6,t,(hZ(),zot),null,-1,!1):VZ(n,t.tk()?2:1,t,null,null,-1,!1))}function I$n(n,t){var e,i,r,c;return n.a==(RIn(),Vgt)||(r=t.a.c,e=t.a.c+t.a.b,!(t.j&&(c=(i=t.A).c.c.a-i.o.a/2,r-(i.n.a+i.o.a)>c)||t.q&&(c=(i=t.C).c.c.a-i.o.a/2,i.n.a-e>c)))}function O$n(n){var t,e,i,r,c,a;for(e2(),e=new u8,i=new Ww(n.e.b);i.a1?n.e*=uM(n.a):n.f/=uM(n.a),_bn(n),Vvn(n),EBn(n),kfn(n.b,(ryn(),Qht),n.g)}function x$n(n,t,e){var i,r,c,a,o;for(i=0,o=e,t||(i=e*(n.c.length-1),o*=-1),c=new Ww(n);c.a=0?n.Ah(null):n.Ph().Th(n,-1-t,null,null),n.Bh(uG(r,54),e),i&&i.oj(),n.vh()&&n.wh()&&e>-1&&Msn(n,new lV(n,9,e,c,r)),r):c}function Y$n(n,t){var e,i,r,c,a;for(c=n.b.Ce(t),i=null==(e=n.a.get(c))?Inn(dat,EZn,1,0,5,1):e,a=0;a>5)>=n.d)return n.e<0;if(e=n.a[r],t=1<<(31&t),n.e<0){if(r<(i=_un(n)))return!1;e=i==r?-e:~e}return!!(e&t)}function oDn(n,t,e,i){var r;uG(e.b,68),uG(e.b,68),uG(i.b,68),uG(i.b,68),RG(r=YF(D$(uG(e.b,68).c),uG(i.b,68).c),LLn(uG(e.b,68),uG(i.b,68),r)),uG(i.b,68),uG(i.b,68),uG(i.b,68).c.a,r.a,uG(i.b,68).c.b,r.b,uG(i.b,68),Prn(i.a,new $U(n,t,i))}function uDn(n,t){var e,i,r,c,a,o,u;if(c=t.e)for(e=J$n(c),i=uG(n.g,689),a=0;a>16)),15).dd(c))0&&((!hN(n.a.c)||!t.n.d)&&(!fN(n.a.c)||!t.n.b)&&(t.g.d+=e.Math.max(0,r/2-.5)),(!hN(n.a.c)||!t.n.a)&&(!fN(n.a.c)||!t.n.c)&&(t.g.a-=r-1))}function bDn(n){var t,i,r,c,a;if(a=VUn(n,c=new Zm),t=uG(oIn(n,(GYn(),lmt)),10))for(r=new Ww(t.j);r.a>t,c=n.m>>t|e<<22-t,r=n.l>>t|n.m<<22-t):t<44?(a=i?l0n:0,c=e>>t-22,r=n.m>>t-22|e<<44-t):(a=i?l0n:0,c=i?f0n:0,r=e>>t-44),p$(r&f0n,c&f0n,a&l0n)}function pDn(n){var t,i,r,c,a,o;for(this.c=new Zm,this.d=n,r=M0n,c=M0n,t=T0n,i=T0n,o=Fkn(n,0);o.b!=o.d.c;)a=uG(I6(o),8),r=e.Math.min(r,a.a),c=e.Math.min(c,a.b),t=e.Math.max(t,a.a),i=e.Math.max(i,a.b);this.a=new gY(r,c,t-r,i-c)}function mDn(n,t){var e,i,r,c;for(i=new Ww(n.b);i.a0&&F$(t,44)&&(n.a._j(),c=null==(u=(s=uG(t,44)).ld())?0:Hon(u),a=iF(n.a,c),e=n.a.d[a]))for(i=uG(e.g,379),h=e.i,o=0;o=2)for(t=pK((i=c.Kc()).Pb());i.Ob();)a=t,t=pK(i.Pb()),r=e.Math.min(r,(tJ(t),t-(tJ(a),a)));return r}function xDn(n,t){var e,i,r;for(r=new Zm,i=Fkn(t.a,0);i.b!=i.d.c;)(e=uG(I6(i),65)).b.g==n.g&&!m_(e.b.c,H9n)&&xA(oIn(e.b,(QGn(),ACt)))!==xA(oIn(e.c,ACt))&&!o9(new fX(null,new h3(r,16)),new yp(e))&&mv(r.c,e);return f$(r,new Ca),r}function RDn(n,t){var e,i,r;if(xA(t)===xA(WW(n)))return!0;if(!F$(t,15))return!1;if(i=uG(t,15),(r=n.gc())!=i.gc())return!1;if(F$(i,59)){for(e=0;e0&&(r=e),a=new Ww(n.f.e);a.a0?(t-=1,e-=1):i>=0&&r<0?(t+=1,e+=1):i>0&&r>=0?(t-=1,e+=1):(t+=1,e-=1),new WO(xwn(t),xwn(e))}function exn(n,t){return n.ct.c?1:n.bt.b?1:n.a!=t.a?Hon(n.a)-Hon(t.a):n.d==(Z6(),YEt)&&t.d==JEt?-1:n.d==JEt&&t.d==YEt?1:0}function ixn(n,t){var e,i,r,c,a;return a=(c=t.a).c.i==t.b?c.d:c.c,i=c.c.i==t.b?c.c:c.d,(r=dmn(n.a,a,i))>0&&r0):r<0&&-r0)}function rxn(n,t,e,i){var r,c,a,o,u,s;for(r=(t-n.d)/n.c.c.length,c=0,n.a+=e,n.d=t,s=new Ww(n.c);s.a>24;return a}function axn(n){if(n.ze()){var t=n.c;return t.Ae()?n.o="["+t.n:t.ze()?n.o="["+t.xe():n.o="[L"+t.xe()+";",n.b=t.we()+"[]",void(n.k=t.ye()+"[]")}var e=n.j,i=n.d;i=i.split("/"),n.o=fvn(".",[e,fvn("$",i)]),n.b=fvn(".",[e,fvn(".",i)]),n.k=i[i.length-1]}function oxn(n,t){var e,i,r,c,a;for(a=null,c=new Ww(n.e.a);c.a=0;t-=2)for(e=0;e<=t;e+=2)(n.b[e]>n.b[e+2]||n.b[e]===n.b[e+2]&&n.b[e+1]>n.b[e+3])&&(i=n.b[e+2],n.b[e+2]=n.b[e],n.b[e]=i,i=n.b[e+3],n.b[e+3]=n.b[e+1],n.b[e+1]=i);n.c=!0}}function mxn(n,t){var e,i,r,c,a,o,u,s,h;for(s=-1,h=0,o=0,u=(a=n).length;o0&&++h;++s}return h}function vxn(n){var t;return(t=new lx(Ij(n.Rm))).a+="@",JA(t,(Hon(n)>>>0).toString(16)),n.Vh()?(t.a+=" (eProxyURI: ",QA(t,n._h()),n.Kh()&&(t.a+=" eClass: ",QA(t,n.Kh())),t.a+=")"):n.Kh()&&(t.a+=" (eClass: ",QA(t,n.Kh()),t.a+=")"),t.a}function kxn(n){var t,e,i;if(n.e)throw hv(new kM((vK(Qut),v2n+Qut.k+k2n)));for(n.d==(xdn(),ZDt)&&GWn(n,JDt),e=new Ww(n.a.a);e.a>24}return e}function Sxn(n,t,e){var i,r,c;if(!(r=uG(AJ(n.i,t),314)))if(r=new Yin(n.d,t,e),UV(n.i,t,r),vvn(t))iD(n.a,t.c,t.b,r);else switch(c=MAn(t),i=uG(AJ(n.p,c),252),c.g){case 1:case 3:r.j=!0,nM(i,t.b,r);break;case 4:case 2:r.k=!0,nM(i,t.c,r)}return r}function Pxn(n,t){var e,i,r,c,a,o,u,s,h;for(u=iR(n.c-n.b&n.a.length-1),s=null,h=null,c=new XJ(n);c.a!=c.b;)r=uG(rwn(c),10),e=(o=uG(oIn(r,(GYn(),Zpt)),12))?o.i:null,i=(a=uG(oIn(r,nmt),12))?a.i:null,s==e&&h==i||(F$n(u,t),s=e,h=i),mv(u.c,r);F$n(u,t)}function Cxn(n,t,e,i){var r,c,a,o,u,s;if(o=new ls,u=VKn(n.e.Dh(),t),r=uG(n.g,124),PP(),uG(t,69).xk())for(a=0;a=0)return r;for(c=1,a=new Ww(t.j);a.a=0)return r;for(c=1,a=new Ww(t.j);a.a0&&t.Ne((u3(r-1,n.c.length),uG(n.c[r-1],10)),c)>0;)Y8(n,r,(u3(r-1,n.c.length),uG(n.c[r-1],10))),--r;u3(r,n.c.length),n.c[r]=c}e.a=new Ym,e.b=new Ym}function Lxn(n,t,e){var i,r,c,a,o,u,s;for(s=new nB(i=uG(t.e&&t.e(),9),uG(MF(i,i.length),9),0),a=0,o=(c=WGn(e,"[\\[\\]\\s,]+")).length;a=0?(t||(t=new VM,i>0&&VA(t,(Knn(0,i,n.length),n.substr(0,i)))),t.a+="\\",TQ(t,e&D1n)):t&&TQ(t,e&D1n);return t?t.a:n}function $xn(n){var t,i,r;for(i=new Ww(n.a.a.b);i.a0&&((!hN(n.a.c)||!t.n.d)&&(!fN(n.a.c)||!t.n.b)&&(t.g.d-=e.Math.max(0,r/2-.5)),(!hN(n.a.c)||!t.n.a)&&(!fN(n.a.c)||!t.n.c)&&(t.g.a+=e.Math.max(0,r-1)))}function Dxn(n,t,e){var i;if(2==(n.c-n.b&n.a.length-1))t==(KQn(),yRt)||t==kRt?(prn(uG(Rfn(n),15),(Ajn(),$xt)),prn(uG(Rfn(n),15),Dxt)):(prn(uG(Rfn(n),15),(Ajn(),Dxt)),prn(uG(Rfn(n),15),$xt));else for(i=new XJ(n);i.a!=i.b;)prn(uG(rwn(i),15),e)}function xxn(n,t){var e,i,r,c,a,o;for(a=new N4(i=rG(new Pm(n)),i.c.length),o=new N4(r=rG(new Pm(t)),r.c.length),c=null;a.b>0&&o.b>0&&(MK(a.b>0),e=uG(a.a.Xb(a.c=--a.b),27),MK(o.b>0),e==uG(o.a.Xb(o.c=--o.b),27));)c=e;return c}function Rxn(n,t,e){var i,r,c,a;Y3(n,t)>Y3(n,e)?(i=Dgn(e,(KQn(),kRt)),n.d=i.dc()?0:dq(uG(i.Xb(0),12)),a=Dgn(t,_Rt),n.b=a.dc()?0:dq(uG(a.Xb(0),12))):(r=Dgn(e,(KQn(),_Rt)),n.d=r.dc()?0:dq(uG(r.Xb(0),12)),c=Dgn(t,kRt),n.b=c.dc()?0:dq(uG(c.Xb(0),12)))}function Kxn(n,t){var e,i,r,c;for(e=n.o.a,c=uG(uG(Y9(n.r,t),21),87).Kc();c.Ob();)(r=uG(c.Pb(),117)).e.a=e*uM(pK(r.b.of(bht))),r.e.b=(i=r.b).pf((XYn(),uDt))?i.ag()==(KQn(),yRt)?-i.Mf().b-uM(pK(i.of(uDt))):uM(pK(i.of(uDt))):i.ag()==(KQn(),yRt)?-i.Mf().b:0}function Fxn(n,t){var e,i,r,c;for(t.Ug("Self-Loop pre-processing",1),i=new Ww(n.a);i.an.c));a++)r.a>=n.s&&(c<0&&(c=a),o=a);return u=(n.s+n.c)/2,c>=0&&(u=wP((u3(i=fHn(n,t,c,o),t.c.length),uG(t.c[i],339))),a$n(t,i,e)),u}function Hxn(n,t,e){var i,r,c,a,o;for(Yan(r=new vs,(tJ(t),t)),!r.b&&(r.b=new XR((YYn(),H_t),wBt,r)),o=r.b,a=1;a0&&tVn(this,r)}function Gxn(n,t,e,i,r,c){var a,o,u;if(!r[t.a]){for(r[t.a]=!0,!(a=i)&&(a=new d7),kD(a.e,t),u=c[t.a].Kc();u.Ob();)(o=uG(u.Pb(),290)).d!=e&&o.c!=e&&(o.c!=t&&Gxn(n,o.c,t,a,r,c),o.d!=t&&Gxn(n,o.d,t,a,r,c),kD(a.c,o),Ohn(a.d,o.b));return a}return null}function qxn(n){var t,e,i;for(t=0,e=new Ww(n.e);e.a=2}function Xxn(n,t,e,i,r){var c,a,o,u,s;for(c=n.c.d.j,a=uG(hyn(e,0),8),s=1;s1||qsn(X1(WX(Bxt,Uhn(cT(eRt,1),p1n,95,0,[_xt,Uxt])),n))>1||qsn(X1(WX(Vxt,Uhn(cT(eRt,1),p1n,95,0,[zxt,Xxt])),n))>1)}function Vxn(n,t,e){var i,r,c;for(c=new Ww(n.t);c.a0&&(i.b.n-=i.c,i.b.n<=0&&i.b.u>0&&aq(t,i.b));for(r=new Ww(n.i);r.a0&&(i.a.u-=i.c,i.a.u<=0&&i.a.n>0&&aq(e,i.a))}function Wxn(n){var t,e,i;if(null==n.g&&(n.d=n.bj(n.f),ttn(n,n.d),n.c))return n.f;if(i=(t=uG(n.g[n.i-1],51)).Pb(),n.e=t,(e=n.bj(i)).Ob())n.d=e,ttn(n,e);else for(n.d=null;!t.Ob()&&(uQ(n.g,--n.i,null),0!=n.i);)t=uG(n.g[n.i-1],51);return i}function Qxn(n,t){var e,i,r,c,a,o;if(r=(i=t).Lk(),EFn(n.e,r)){if(r.Si()&&H5(n,r,i.md()))return!1}else for(o=VKn(n.e.Dh(),r),e=uG(n.g,124),c=0;c1||e>1)return 2;return t+e==1?2:0}function uRn(n,t){var i,r,c,a;return c=n.a*X0n+1502*n.b,a=n.b*X0n+11,c+=i=e.Math.floor(a*z0n),a-=i*V0n,c%=V0n,n.a=c,n.b=a,t<=24?e.Math.floor(n.a*but[t]):((r=n.a*(1<=2147483648&&(r-=4294967296),r)}function sRn(n,t,e){var i,r,c,a,o,u,s;for(c=new Zm,Uqn(n,s=new lS,a=new lS,t),RVn(n,s,a,t,e),u=new Ww(n);u.ai.b.g&&mv(c.c,i);return c}function hRn(n,t,e){var i,r,c,a,o;for(a=n.c,c=(e.q?e.q:(hZ(),hZ(),Vot)).vc().Kc();c.Ob();)r=uG(c.Pb(),44),!Qj(JJ(new fX(null,new h3(a,16)),new hd(new kO(t,r)))).Bd((vS(),Kut))&&(F$(o=r.md(),4)&&null!=(i=Nvn(o))&&(o=i),t.qf(uG(r.ld(),149),o))}function fRn(n,t,e){var i;if(_J(n.b),JV(n.b,(Rdn(),HAt),(eP(),GLt)),JV(n.b,UAt,t.g),JV(n.b,GAt,t.a),n.a=Qzn(n.b,t),e.Ug("Compaction by shrinking a tree",n.a.c.length),t.i.c.length>1)for(i=new Ww(n.a);i.a=0?n.Lh(i,!0,!0):YNn(n,c,!0),160),uG(r,220).Xl(t,e)}function bRn(n,t){var e,i,r,c;if(t){for(c=!(r=F$(n.Cb,90)||F$(n.Cb,102))&&F$(n.Cb,331),e=new DD((!t.a&&(t.a=new AX(t,g_t,t)),t.a));e.e!=e.i.gc();)if(i=MGn(uG(Zkn(e),89)),r?F$(i,90):c?F$(i,156):i)return i;return r?(YYn(),x_t):(YYn(),N_t)}return null}function wRn(n,t){var e,i,r;for(t.Ug("Resize child graph to fit parent.",1),i=new Ww(n.b);i.a=2*t&&kD(e,new OU(a[i-1]+t,a[i]-t));return e}function pRn(n,t,e){var i,r,c,a,o;if(e)for(c=((i=new Gz(e.a.length)).b-i.a)*i.c<0?(CP(),XHt):new xD(i);c.Ob();)(r=v6(e,uG(c.Pb(),17).a))&&(Gan(a=b5(n,(gj(),o=new Hk,!!t&&LRn(o,t),o),r),k6(r,Iet)),fCn(r,a),kLn(r,a),qfn(n,r,a))}function mRn(n){var t,e,i,r;if(!n.j){if(r=new Ss,null==(t=V_t).a.zc(n,t)){for(i=new DD(n1(n));i.e!=i.i.gc();)CW(r,mRn(e=uG(Zkn(i),29))),ttn(r,e);t.a.Bc(n)}lbn(r),n.j=new vL((uG(zrn(gZ((tQ(),M_t).o),11),19),r.i),r.g),y9(n).b&=-33}return n.j}function vRn(n){var t,e,i,r;if(null==n)return null;if(i=yXn(n,!0),r=yct.length,m_(i.substr(i.length-r,r),yct))if(4==(e=i.length)){if(s3(0,i.length),43==(t=i.charCodeAt(0)))return fHt;if(45==t)return hHt}else if(3==e)return fHt;return new tk(i)}function kRn(n){var t,e,i;return(e=n.l)&e-1||(i=n.m)&i-1||(t=n.h)&t-1||0==t&&0==i&&0==e?-1:0==t&&0==i&&0!=e?pan(e):0==t&&0!=i&&0==e?pan(i)+22:0!=t&&0==i&&0==e?pan(t)+44:-1}function yRn(n,t){var e,i,r,c,a;for(r=t.a&n.f,c=null,i=n.b[r];;i=i.b){if(i==t){c?c.b=t.b:n.b[r]=t.b;break}c=i}for(a=t.f&n.f,c=null,e=n.c[a];;e=e.d){if(e==t){c?c.d=t.d:n.c[a]=t.d;break}c=e}t.e?t.e.c=t.c:n.a=t.c,t.c?t.c.e=t.e:n.e=t.e,--n.i,++n.g}function MRn(n,t){var e;t.d?t.d.b=t.b:n.a=t.b,t.b?t.b.d=t.d:n.e=t.d,t.e||t.c?(--(e=uG(nJ(uG(cQ(n.b,t.a),260)),260)).a,t.e?t.e.c=t.c:e.b=uG(nJ(t.c),511),t.c?t.c.e=t.e:e.c=uG(nJ(t.e),511)):((e=uG(nJ(uG(u7(n.b,t.a),260)),260)).a=0,++n.c),--n.d}function TRn(n){var t,i,r,c,a,o,u,s,h,f;for(i=n.o,t=n.p,o=vZn,c=j1n,u=vZn,a=j1n,h=0;h0),c.a.Xb(c.c=--c.b),pF(c,r),MK(c.b3&&Fen(n,0,t-3))}function CRn(n){var t,e,i,r;return xA(oIn(n,(jYn(),rMt)))===xA((Own(),Ixt))?!n.e&&xA(oIn(n,Oyt))!==xA((ihn(),hpt)):(i=uG(oIn(n,Ayt),299),r=oM(gK(oIn(n,Ryt)))||xA(oIn(n,Kyt))===xA((jan(),Ydt)),t=uG(oIn(n,Iyt),17).a,e=n.a.c.length,!r&&i!=(ihn(),hpt)&&(0==t||t>e))}function IRn(n){var t,e;for(e=0;e0);e++);if(e>0&&e0);t++);return t>0&&e>16!=6&&t){if(eEn(n,t))throw hv(new vM(net+A$n(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?zjn(n,i):n.Cb.Th(n,-1-e,null,i)),t&&(i=kyn(t,n,6,i)),(i=ZK(n,t,i))&&i.oj()}else 4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,6,t,t))}function ARn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=3&&t){if(eEn(n,t))throw hv(new vM(net+SXn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?sEn(n,i):n.Cb.Th(n,-1-e,null,i)),t&&(i=kyn(t,n,12,i)),(i=nF(n,t,i))&&i.oj()}else 4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,3,t,t))}function LRn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=9&&t){if(eEn(n,t))throw hv(new vM(net+VBn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Wjn(n,i):n.Cb.Th(n,-1-e,null,i)),t&&(i=kyn(t,n,9,i)),(i=tF(n,t,i))&&i.oj()}else 4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,9,t,t))}function NRn(n){var t,e,i,r,c;if(i=bEn(n),null==(c=n.j)&&i)return n.Jk()?null:i.ik();if(F$(i,156)){if((e=i.jk())&&(r=e.wi())!=n.i){if((t=uG(i,156)).nk())try{n.g=r.ti(t,c)}catch(a){if(!F$(a=Ehn(a),82))throw hv(a);n.g=null}n.i=r}return n.g}return null}function $Rn(n){var t;return kD(t=new Zm,new ZP(new MO(n.c,n.d),new MO(n.c+n.b,n.d))),kD(t,new ZP(new MO(n.c,n.d),new MO(n.c,n.d+n.a))),kD(t,new ZP(new MO(n.c+n.b,n.d+n.a),new MO(n.c+n.b,n.d))),kD(t,new ZP(new MO(n.c+n.b,n.d+n.a),new MO(n.c,n.d+n.a))),t}function DRn(n){var t,e;if(null==n)return IZn;try{return cpn(n)}catch(i){if(F$(i=Ehn(i),103))return t=i,e=Ij(Tbn(n))+"@"+(bS(),(Avn(n)>>>0).toString(16)),wkn(ghn(),(pS(),"Exception during lenientFormat for "+e),t),"<"+e+" threw "+Ij(t.Rm)+">";throw hv(i)}}function xRn(n,t,e){var i,r;for(r=t.a.ec().Kc();r.Ob();)i=uG(r.Pb(),74),!uG(cQ(n.b,i),272)&&(R0(bIn(i))==R0(gIn(i))?QKn(n,i,e):bIn(i)==R0(gIn(i))?null==cQ(n.c,i)&&null!=cQ(n.b,gIn(i))&&bWn(n,i,e,!1):null==cQ(n.d,i)&&null!=cQ(n.b,bIn(i))&&bWn(n,i,e,!0))}function RRn(n,t){var e,i,r,c,a,o,u;for(r=n.Kc();r.Ob();)for(i=uG(r.Pb(),10),o2(o=new lOn,i),NLn(o,(KQn(),kRt)),kfn(o,(GYn(),fmt),(qx(),!0)),a=t.Kc();a.Ob();)c=uG(a.Pb(),10),o2(u=new lOn,c),NLn(u,_Rt),kfn(u,fmt,!0),kfn(e=new UZ,fmt,!0),c2(e,o),u2(e,u)}function KRn(n,t,e,i){var r,c,a,o;r=evn(n,t,e),c=evn(n,e,t),a=uG(cQ(n.c,t),118),o=uG(cQ(n.c,e),118),r1)for(t=jx((e=new sk,++n.b,e),n.d),o=Fkn(c,0);o.b!=o.d.c;)a=uG(I6(o),125),RKn(xS(DS(RS($S(new uk,1),0),t),a))}function URn(n,t,e){var i,r,c,a;for(e.Ug("Breaking Point Removing",1),n.a=uG(oIn(t,(jYn(),Vyt)),223),r=new Ww(t.b);r.a>16!=11&&t){if(eEn(n,t))throw hv(new vM(net+zBn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?hEn(n,i):n.Cb.Th(n,-1-e,null,i)),t&&(i=kyn(t,n,10,i)),(i=n_(n,t,i))&&i.oj()}else 4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,11,t,t))}function qRn(n){var t,e,i,r;for(i=new bsn(new Nw(n.b).a);i.b;)r=uG((e=von(i)).ld(),12),kfn(t=uG(e.md(),10),(GYn(),rmt),r),kfn(r,lmt,t),kfn(r,qpt,(qx(),!0)),NLn(r,uG(oIn(t,Fpt),64)),oIn(t,Fpt),kfn(r.i,(jYn(),JMt),($Pn(),oRt)),uG(oIn(HQ(r.i),Hpt),21).Fc((r_n(),rpt))}function XRn(n,t,e){var i,r,c;if(i=0,r=0,n.c)for(c=new Ww(n.d.i.j);c.ac.a)return-1;if(r.a(u=null==n.d?0:n.d.length)){for(h=n.d,n.d=Inn(IFt,qit,66,2*u+4,0,1),c=0;c=0x8000000000000000?(tin(),Jat):(i=!1,n<0&&(i=!0,n=-n),e=0,n>=d0n&&(n-=(e=t0(n/d0n))*d0n),t=0,n>=w0n&&(n-=(t=t0(n/w0n))*w0n),r=p$(t0(n),t,e),i&&Yfn(r),r)}function uKn(n){var t,e,i,r,c;if(c=new Zm,Prn(n.b,new Ed(c)),n.b.c.length=0,0!=c.c.length){for(u3(0,c.c.length),t=uG(c.c[0],82),e=1,i=c.c.length;e=-t&&r==t?new WO(xwn(i-1),xwn(r)):new WO(xwn(i),xwn(r-1))}function bKn(){return zYn(),Uhn(cT(Vwt,1),p1n,81,0,[qbt,Hbt,Xbt,uwt,Pwt,lwt,Nwt,pwt,Ewt,iwt,ywt,gwt,Swt,Zbt,Dwt,xbt,kwt,Iwt,swt,Cwt,Rwt,Twt,Rbt,jwt,Kwt,Awt,xwt,hwt,Qbt,fwt,owt,$wt,_bt,Vbt,wwt,Fbt,dwt,cwt,nwt,mwt,ewt,Ubt,Bbt,awt,twt,vwt,Lwt,Kbt,Mwt,rwt,bwt,Jbt,Wbt,Owt,zbt,Ybt,Gbt])}function wKn(n,t,e){n.d=0,n.b=0,t.k==(zIn(),gbt)&&e.k==gbt&&uG(oIn(t,(GYn(),rmt)),10)==uG(oIn(e,rmt),10)&&(jen(t).j==(KQn(),yRt)?Rxn(n,t,e):Rxn(n,e,t)),t.k==gbt&&e.k==wbt?jen(t).j==(KQn(),yRt)?n.d=1:n.b=1:e.k==gbt&&t.k==wbt&&(jen(e).j==(KQn(),yRt)?n.b=1:n.d=1),GMn(n,t,e)}function dKn(n){var t,e,i,r,c;return c=gCn(n),null!=n.a&&ZG(c,"category",n.a),!pE(new Lw(n.d))&&(nrn(c,"knownOptions",i=new Ib),t=new Mm(i),z8(new Lw(n.d),t)),!pE(n.g)&&(nrn(c,"supportedFeatures",r=new Ib),e=new Tm(r),z8(n.g,e)),c}function gKn(n){var t,e,i,r,c,a,o,u;for(t=336,e=0,r=new UF(n.length),o=0,u=(a=n).length;o>16!=7&&t){if(eEn(n,t))throw hv(new vM(net+zOn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Vjn(n,i):n.Cb.Th(n,-1-e,null,i)),t&&(i=uG(t,54).Rh(n,1,iFt,i)),(i=dz(n,t,i))&&i.oj()}else 4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,7,t,t))}function kKn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=3&&t){if(eEn(n,t))throw hv(new vM(net+fdn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Yjn(n,i):n.Cb.Th(n,-1-e,null,i)),t&&(i=uG(t,54).Rh(n,0,uFt,i)),(i=gz(n,t,i))&&i.oj()}else 4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,3,t,t))}function yKn(n,t){var e,i,r,c,a,o,u,s,h;return b_n(),t.d>n.d&&(o=n,n=t,t=o),t.d<63?KFn(n,t):(s=$9(n,a=(-2&n.d)<<4),h=$9(t,a),i=mXn(n,D9(s,a)),r=mXn(t,D9(h,a)),u=yKn(s,h),e=yKn(i,r),c=D9(c=Zzn(Zzn(c=yKn(mXn(s,i),mXn(r,h)),u),e),a),Zzn(Zzn(u=D9(u,a<<1),c),e))}function MKn(){MKn=E,rjt=new fI(v9n,0),tjt=new fI("LONGEST_PATH",1),ejt=new fI("LONGEST_PATH_SOURCE",2),YTt=new fI("COFFMAN_GRAHAM",3),njt=new fI(D6n,4),cjt=new fI("STRETCH_WIDTH",5),ijt=new fI("MIN_WIDTH",6),JTt=new fI("BF_MODEL_ORDER",7),ZTt=new fI("DF_MODEL_ORDER",8)}function TKn(n,t,e){var i,r,c,a,o;for(a=Vwn(n,e),o=Inn(pbt,e6n,10,t.length,0,1),i=0,c=a.Kc();c.Ob();)oM(gK(oIn(r=uG(c.Pb(),12),(GYn(),qpt))))&&(o[i++]=uG(oIn(r,lmt),10));if(i=0;r+=e?1:-1)c|=t.c.lg(o,r,e,i&&!oM(gK(oIn(t.j,(GYn(),Bpt))))&&!oM(gK(oIn(t.j,(GYn(),mmt))))),c|=t.q.ug(o,r,e),c|=wBn(n,o[r],e,i);return FV(n.c,t),c}function CKn(n,t,e){var i,r,c,a,o,u,s,h;for(s=0,h=(u=s6(n.j)).length;s1&&(n.a=!0),YX(uG(e.b,68),JF(D$(uG(t.b,68).c),vD(YF(D$(uG(e.b,68).a),uG(t.b,68).a),r))),f2(n,t),AKn(n,e)}function LKn(n){var t,e,i,r,c,a;for(r=new Ww(n.a.a);r.a0&&c>0?t++:i>0?e++:c>0?r++:e++}hZ(),f$(n.j,new bi)}function $Kn(n){var t,e;e=null,t=uG(zq(n.g,0),18);do{if(vR(e=t.d.i,(GYn(),nmt)))return uG(oIn(e,nmt),12).i;if(e.k!=(zIn(),dbt)&&hDn(new Fz(ix(Xgn(e).a.Kc(),new h))))t=uG(N9(new Fz(ix(Xgn(e).a.Kc(),new h))),18);else if(e.k!=dbt)return null}while(e&&e.k!=(zIn(),dbt));return e}function DKn(n,t){var e,i,r,c,a,o,u,s,h;for(o=t.j,a=t.g,u=uG(zq(o,o.c.length-1),113),u3(0,o.c.length),s=xTn(n,a,u,h=uG(o.c[0],113)),c=1;cs&&(u=e,h=r,s=i);t.a=h,t.c=u}function xKn(n,t,e){var i,r,c,a,o,u,s;for(s=new Hj(new ip(n)),o=0,u=(a=Uhn(cT(Abt,1),i6n,12,0,[t,e])).length;ou-n.b&&ou-n.a&&o0?c.a?e>(o=c.b.Mf().a)&&(r=(e-o)/2,c.d.b=r,c.d.c=r):c.d.c=n.s+e:cV(n.u)&&((i=ECn(c.b)).c<0&&(c.d.b=-i.c),i.c+i.b>c.b.Mf().a&&(c.d.c=i.c+i.b-c.b.Mf().a))}function rFn(n,t){var e,i,r,c,a;a=new Zm,e=t;do{(c=uG(cQ(n.b,e),131)).B=e.c,c.D=e.d,mv(a.c,c),e=uG(cQ(n.k,e),18)}while(e);return u3(0,a.c.length),(i=uG(a.c[0],131)).j=!0,i.A=uG(i.d.a.ec().Kc().Pb(),18).c.i,(r=uG(zq(a,a.c.length-1),131)).q=!0,r.C=uG(r.d.a.ec().Kc().Pb(),18).d.i,a}function cFn(n){var t,i;if(t=uG(n.a,17).a,i=uG(n.b,17).a,t>=0){if(t==i)return new WO(xwn(-t-1),xwn(-t-1));if(t==-i)return new WO(xwn(-t),xwn(i+1))}return e.Math.abs(t)>e.Math.abs(i)?new WO(xwn(-t),xwn(t<0?i:i+1)):new WO(xwn(t+1),xwn(i))}function aFn(n){var t,e;e=uG(oIn(n,(jYn(),gMt)),171),t=uG(oIn(n,(GYn(),Xpt)),311),e==(Gpn(),Imt)?(kfn(n,gMt,Lmt),kfn(n,Xpt,(Zen(),ppt))):e==Amt?(kfn(n,gMt,Lmt),kfn(n,Xpt,(Zen(),dpt))):t==(Zen(),ppt)?(kfn(n,gMt,Imt),kfn(n,Xpt,gpt)):t==dpt&&(kfn(n,gMt,Amt),kfn(n,Xpt,gpt))}function oFn(){oFn=E,LSt=new oa,CSt=Aq(new wJ,(uIn(),Elt),(zYn(),swt)),ASt=wz(Aq(new wJ,Elt,Twt),Plt,Mwt),NSt=Lvn(Lvn(gP(wz(Aq(new wJ,Tlt,Nwt),Plt,Lwt),Slt),Awt),$wt),ISt=wz(Aq(Aq(Aq(new wJ,jlt,lwt),Slt,wwt),Slt,dwt),Plt,bwt),OSt=wz(Aq(Aq(new wJ,Slt,dwt),Slt,Vbt),Plt,zbt)}function uFn(){uFn=E,KSt=Aq(wz(new wJ,(uIn(),Plt),(zYn(),Jbt)),Elt,swt),HSt=Lvn(Lvn(gP(wz(Aq(new wJ,Tlt,Nwt),Plt,Lwt),Slt),Awt),$wt),FSt=wz(Aq(Aq(Aq(new wJ,jlt,lwt),Slt,wwt),Slt,dwt),Plt,bwt),BSt=Aq(Aq(new wJ,Elt,Twt),Plt,Mwt),_St=wz(Aq(Aq(new wJ,Slt,dwt),Slt,Vbt),Plt,zbt)}function sFn(n,t,e,i,r){var c,a;(v9(t)||t.c.i.c!=t.d.i.c)&&uon(Gfn(Uhn(cT(PNt,1),zZn,8,0,[r.i.n,r.n,r.a])),e)||v9(t)||(t.c==r?sR(t.a,0,new eN(e)):aq(t.a,new eN(e)),i&&!cS(n.a,e)&&((a=uG(oIn(t,(jYn(),bMt)),75))||(a=new Uk,kfn(t,bMt,a)),s8(a,c=new eN(e),a.c.b,a.c),FV(n.a,c)))}function hFn(n,t){var e,i,r,c;for(e=(c=pz(Ngn(h1n,PJ(pz(Ngn(null==t?0:Hon(t),f1n)),15))))&n.b.length-1,r=null,i=n.b[e];i;r=i,i=i.a)if(i.d==c&&xQ(i.i,t))return r?r.a=i.a:n.b[e]=i.a,RM(uG(nJ(i.c),604),uG(nJ(i.f),604)),Tv(uG(nJ(i.b),227),uG(nJ(i.e),227)),--n.f,++n.e,!0;return!1}function fFn(n){var t;for(t=new Fz(ix(qgn(n).a.Kc(),new h));hDn(t);)if(uG(N9(t),18).c.i.k!=(zIn(),bbt))throw hv(new jM(y6n+ZTn(n)+"' has its layer constraint set to FIRST, but has at least one incoming edge that does not come from a FIRST_SEPARATE node. That must not happen."))}function lFn(n,t,e){var i,r,c,a,o,u;if(0==(r=Cdn(254&n.Db)))n.Eb=e;else{if(1==r)a=Inn(dat,EZn,1,2,5,1),0==jTn(n,t)?(a[0]=e,a[1]=n.Eb):(a[0]=n.Eb,a[1]=e);else for(a=Inn(dat,EZn,1,r+1,5,1),c=Kcn(n.Eb),i=2,o=0,u=0;i<=128;i<<=1)i==t?a[u++]=e:n.Db&i&&(a[u++]=c[o++]);n.Eb=a}n.Db|=t}function bFn(n,t,i){var r,c,a,o;for(this.b=new Zm,c=0,r=0,o=new Ww(n);o.a0&&(c+=(a=uG(zq(this.b,0),176)).o,r+=a.p),c*=2,r*=2,t>1?c=t0(e.Math.ceil(c*t)):r=t0(e.Math.ceil(r/t)),this.a=new smn(c,r)}function wFn(n,t,i,r,c,a){var o,u,s,h,f,l,b,w,d,g;for(h=r,t.j&&t.o?(d=(b=uG(cQ(n.f,t.A),60)).d.c+b.d.b,--h):d=t.a.c+t.a.b,f=c,i.q&&i.o?(s=(b=uG(cQ(n.f,i.C),60)).d.c,++f):s=i.a.c,w=d+(u=(s-d)/e.Math.max(2,f-h)),l=h;l=0;a+=r?1:-1){for(o=t[a],u=i==(KQn(),kRt)?r?Dgn(o,i):Spn(Dgn(o,i)):r?Spn(Dgn(o,i)):Dgn(o,i),c&&(n.c[o.p]=u.gc()),f=u.Kc();f.Ob();)h=uG(f.Pb(),12),n.d[h.p]=s++;Ohn(e,u)}}function pFn(n,t,e){var i,r,c,a,o,u,s,h;for(c=uM(pK(n.b.Kc().Pb())),s=uM(pK(whn(t.b))),i=vD(D$(n.a),s-e),r=vD(D$(t.a),e-c),vD(h=JF(i,r),1/(s-c)),this.a=h,this.b=new Zm,o=!0,(a=n.b.Kc()).Pb();a.Ob();)u=uM(pK(a.Pb())),o&&u-e>$9n&&(this.b.Fc(e),o=!1),this.b.Fc(u);o&&this.b.Fc(e)}function mFn(n){var t,e,i,r;if(wHn(n,n.n),n.d.c.length>0){for(AM(n.c);fDn(n,uG(N3(new Ww(n.e.a)),125))>5,t&=31,i>=n.d)return n.e<0?(cHn(),Dot):(cHn(),_ot);if(c=n.d-i,ROn(r=Inn(YHt,W1n,28,c+1,15,1),c,n.a,i,t),n.e<0){for(e=0;e0&&n.a[e]<<32-t){for(e=0;e=0)&&(!(e=iVn((gAn(),kBt),r,t))||((i=e.Ik())>1||-1==i)&&3!=sJ(Nen(kBt,e))))}function SFn(n,t,e,i){var r,c,a,o,u;return o=lCn(uG(zrn((!t.b&&(t.b=new f_(cFt,t,4,7)),t.b),0),84)),u=lCn(uG(zrn((!t.c&&(t.c=new f_(cFt,t,5,8)),t.c),0),84)),R0(o)==R0(u)||Ern(u,o)?null:(a=s0(t))==e?i:(c=uG(cQ(n.a,a),10))&&(r=c.e)?r:null}function PFn(n,t,e){var i,r,c,a;for(e.Ug("Longest path to source layering",1),n.a=t,a=n.a.a,n.b=Inn(YHt,W1n,28,a.c.length,15,1),i=0,c=new Ww(a);c.a0&&(i[0]+=n.d,o-=i[0]),i[2]>0&&(i[2]+=n.d,o-=i[2]),a=e.Math.max(0,o),i[1]=e.Math.max(i[1],o),Q9(n,Est,c.c+r.b+i[0]-(i[1]-o)/2,i),t==Est&&(n.c.b=a,n.c.c=c.c+r.b+(a-o)/2)}function BFn(){this.c=Inn(eUt,I0n,28,(KQn(),Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt])).length,15,1),this.b=Inn(eUt,I0n,28,Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt]).length,15,1),this.a=Inn(eUt,I0n,28,Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt]).length,15,1),KP(this.c,M0n),KP(this.b,T0n),KP(this.a,T0n)}function HFn(n,t,e){var i,r,c,a;if(t<=e?(r=t,c=e):(r=e,c=t),i=0,null==n.b)n.b=Inn(YHt,W1n,28,2,15,1),n.b[0]=r,n.b[1]=c,n.c=!0;else{if(i=n.b.length,n.b[i-1]+1==r)return void(n.b[i-1]=c);a=Inn(YHt,W1n,28,i+2,15,1),qGn(n.b,0,a,0,i),n.b=a,n.b[i-1]>=r&&(n.c=!1,n.a=!1),n.b[i++]=r,n.b[i]=c,n.c||pxn(n)}}function UFn(n,t,e){var i,r,c,a,o,u,s;for(s=t.d,n.a=new R7(s.c.length),n.c=new Ym,o=new Ww(s);o.a=0?n.Lh(s,!1,!0):YNn(n,e,!1),61).Kc();c.Ob();){for(r=uG(c.Pb(),58),h=0;h1;)e_n(r,r.i-1);return i}function YFn(n,t){var e,i,r,c,a,o;for(e=new ND,r=new Ww(n.b);r.an.d[a.p]&&(e+=J8(n.b,c),A6(n.a,xwn(c)));for(;!LM(n.a);)lin(n.b,uG(xV(n.a),17).a)}return e}function n_n(n){var t,e,i,r,c,a,o;for(n.a=new xF,o=0,r=0,i=new Ww(n.i.b);i.au.d&&(f=u.d+u.a+h));i.c.d=f,t.a.zc(i,t),s=e.Math.max(s,i.c.d+i.c.a)}return s}function r_n(){r_n=E,Zgt=new aI("COMMENTS",0),tpt=new aI("EXTERNAL_PORTS",1),ept=new aI("HYPEREDGES",2),ipt=new aI("HYPERNODES",3),rpt=new aI("NON_FREE_PORTS",4),cpt=new aI("NORTH_SOUTH_PORTS",5),opt=new aI(F6n,6),Ygt=new aI("CENTER_LABELS",7),npt=new aI("END_LABELS",8),apt=new aI("PARTITIONS",9)}function c_n(n,t,e,i,r){return i<0?((i=XOn(n,r,Uhn(cT($ot,1),zZn,2,6,[x1n,R1n,K1n,F1n,_1n,B1n,H1n,U1n,G1n,q1n,X1n,z1n]),t))<0&&(i=XOn(n,r,Uhn(cT($ot,1),zZn,2,6,["Jan","Feb","Mar","Apr",_1n,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),!(i<0||(e.k=i,0))):i>0&&(e.k=i-1,!0)}function a_n(n,t,e,i,r){return i<0?((i=XOn(n,r,Uhn(cT($ot,1),zZn,2,6,[x1n,R1n,K1n,F1n,_1n,B1n,H1n,U1n,G1n,q1n,X1n,z1n]),t))<0&&(i=XOn(n,r,Uhn(cT($ot,1),zZn,2,6,["Jan","Feb","Mar","Apr",_1n,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),!(i<0||(e.k=i,0))):i>0&&(e.k=i-1,!0)}function o_n(n,t,e,i,r,c){var a,o,u;if(o=32,i<0){if(t[0]>=n.length)return!1;if(43!=(o=VJ(n,t[0]))&&45!=o)return!1;if(++t[0],(i=RNn(n,t))<0)return!1;45==o&&(i=-i)}return 32==o&&t[0]-e==2&&2==r.b&&(a=(u=(new QE).q.getFullYear()-V1n+V1n-80)%100,c.a=i==a,i+=100*(u/100|0)+(i=0?Rmn(n):hW(Rmn(Men(n)))),qot[t]=BA(Nz(n,t),0)?Rmn(Nz(n,t)):hW(Rmn(Men(Nz(n,t)))),n=Ngn(n,5);for(;t=h&&(s=r);s&&(f=e.Math.max(f,s.a.o.a)),f>b&&(l=h,b=f)}return l}function v_n(n){var t,e,i,r,c,a,o;for(c=new Hj(uG(WW(new Dn),50)),o=T0n,e=new Ww(n.d);e.aF7n?f$(s,n.b):r<=F7n&&r>_7n?f$(s,n.d):r<=_7n&&r>B7n?f$(s,n.c):r<=B7n&&f$(s,n.a),a=T_n(n,s,a);return c}function j_n(n,t,e,i){var r,c,a,o,u;for(r=(i.c+i.a)/2,BY(t.j),aq(t.j,r),BY(e.e),aq(e.e,r),u=new hj,a=new Ww(n.f);a.a1&&(i=new MO(r,e.b),aq(t.a,i)),dan(t.a,Uhn(cT(PNt,1),zZn,8,0,[f,h]))}function O_n(n,t,e){var i,r;for(t=48;e--)pHt[e]=e-48<<24>>24;for(i=70;i>=65;i--)pHt[i]=i-65+10<<24>>24;for(r=102;r>=97;r--)pHt[r]=r-97+10<<24>>24;for(c=0;c<10;c++)mHt[c]=48+c&D1n;for(n=10;n<=15;n++)mHt[n]=65+n-10&D1n}function N_n(n,t){t.Ug("Process graph bounds",1),kfn(n,(OQn(),PPt),$I(Tun(ZJ(new fX(null,new h3(n.b,16)),new Ka)))),kfn(n,IPt,$I(Tun(ZJ(new fX(null,new h3(n.b,16)),new Fa)))),kfn(n,SPt,$I(Mun(ZJ(new fX(null,new h3(n.b,16)),new _a)))),kfn(n,CPt,$I(Mun(ZJ(new fX(null,new h3(n.b,16)),new Ba)))),t.Vg()}function $_n(n){var t,i,r,c,a;c=uG(oIn(n,(jYn(),DMt)),21),a=uG(oIn(n,KMt),21),t=new eN(i=new MO(n.f.a+n.d.b+n.d.c,n.f.b+n.d.d+n.d.a)),c.Hc((Qmn(),VRt))&&(r=uG(oIn(n,RMt),8),a.Hc((oUn(),eKt))&&(r.a<=0&&(r.a=20),r.b<=0&&(r.b=20)),t.a=e.Math.max(i.a,r.a),t.b=e.Math.max(i.b,r.b)),oM(gK(oIn(n,xMt)))||cXn(n,i,t)}function D_n(n,t){var e,i,r,c;for(c=Dgn(t,(KQn(),KRt)).Kc();c.Ob();)i=uG(c.Pb(),12),(e=uG(oIn(i,(GYn(),lmt)),10))&&RKn(xS(DS(RS($S(new uk,0),.1),n.i[t.p].d),n.i[e.p].a));for(r=Dgn(t,yRt).Kc();r.Ob();)i=uG(r.Pb(),12),(e=uG(oIn(i,(GYn(),lmt)),10))&&RKn(xS(DS(RS($S(new uk,0),.1),n.i[e.p].d),n.i[t.p].a))}function x_n(n){var t,e,i,r,c;if(!n.c){if(c=new ks,null==(t=V_t).a.zc(n,t)){for(i=new DD(z5(n));i.e!=i.i.gc();)F$(r=MGn(e=uG(Zkn(i),89)),90)&&CW(c,x_n(uG(r,29))),ttn(c,e);t.a.Bc(n),t.a.gc()}imn(c),lbn(c),n.c=new vL((uG(zrn(gZ((tQ(),M_t).o),15),19),c.i),c.g),y9(n).b&=-33}return n.c}function R_n(n){var t;if(10!=n.c)throw hv(new CM(rZn((t$(),eit))));switch(t=n.a){case 110:t=10;break;case 114:t=13;break;case 116:t=9;break;case 92:case 124:case 46:case 94:case 45:case 63:case 42:case 43:case 123:case 125:case 40:case 41:case 91:case 93:break;default:throw hv(new CM(rZn((t$(),Lit))))}return t}function K_n(n){var t,e,i,r;if(0==n.l&&0==n.m&&0==n.h)return"0";if(n.h==b0n&&0==n.m&&0==n.l)return"-9223372036854775808";if(n.h>>19)return"-"+K_n(gfn(n));for(e=n,i="";0!=e.l||0!=e.m||0!=e.h;){if(e=Yzn(e,_9(g0n),!0),t=""+Tj(Qat),0!=e.l||0!=e.m||0!=e.h)for(r=9-t.length;r>0;r--)t="0"+t;i=t+i}return i}function F_n(n){var t,e,i,r,c,a,o;for(t=!1,e=0,r=new Ww(n.d.b);r.a=n.a)return-1;if(!_Pn(t,i))return-1;if(P6(uG(r.Kb(t),20)))return 1;for(c=0,o=uG(r.Kb(t),20).Kc();o.Ob();){if(-1==(u=U_n(n,(a=uG(o.Pb(),18)).c.i==t?a.d.i:a.c.i,i,r)))return-1;if((c=e.Math.max(c,u))>n.c-1)return-1}return c+1}function G_n(n,t){var e,i,r,c,a,o;if(xA(t)===xA(n))return!0;if(!F$(t,15))return!1;if(i=uG(t,15),o=n.gc(),i.gc()!=o)return!1;if(a=i.Kc(),n.Yi()){for(e=0;e0)if(n._j(),null!=t){for(c=0;c>24;case 97:case 98:case 99:case 100:case 101:case 102:return n-97+10<<24>>24;case 65:case 66:case 67:case 68:case 69:case 70:return n-65+10<<24>>24;default:throw hv(new ZM("Invalid hexadecimal"))}}function W_n(){W_n=E,pst=new rC("SPIRAL",0),lst=new rC("LINE_BY_LINE",1),bst=new rC("MANHATTAN",2),fst=new rC("JITTER",3),dst=new rC("QUADRANTS_LINE_BY_LINE",4),gst=new rC("QUADRANTS_MANHATTAN",5),wst=new rC("QUADRANTS_JITTER",6),hst=new rC("COMBINE_LINE_BY_LINE_MANHATTAN",7),sst=new rC("COMBINE_JITTER_MANHATTAN",8)}function Q_n(n,t,e,i){var r,c,a,o,u,s;for(u=pSn(n,e),s=pSn(t,e),r=!1;u&&s&&(i||ejn(u,s,e));)a=pSn(u,e),o=pSn(s,e),Ien(t),Ien(n),c=u.c,pVn(u,!1),pVn(s,!1),e?($jn(t,s.p,c),t.p=s.p,$jn(n,u.p+1,c),n.p=u.p):($jn(n,u.p,c),n.p=u.p,$jn(t,s.p+1,c),t.p=s.p),a2(u,null),a2(s,null),u=a,s=o,r=!0;return r}function J_n(n){switch(n.g){case 0:return new ul;case 1:return new al;case 3:return new iP;case 4:return new Sc;case 5:return new RF;case 6:return new ol;case 2:return new cl;case 7:return new Zf;case 8:return new tl;default:throw hv(new vM("No implementation is available for the layerer "+(null!=n.f?n.f:""+n.g)))}}function Y_n(n,t,e,i){var r,c,a,o,u;for(r=!1,c=!1,o=new Ww(i.j);o.a=t.length)throw hv(new dM("Greedy SwitchDecider: Free layer not in graph."));this.c=t[n],this.e=new R_(i),Aon(this.e,this.c,(KQn(),_Rt)),this.i=new R_(i),Aon(this.i,this.c,kRt),this.f=new sX(this.c),this.a=!c&&r.i&&!r.s&&this.c[0].k==(zIn(),lbt),this.a&&rAn(this,n,t.length)}function iBn(n,t){var e,i,r,c,a,o;c=!n.B.Hc((oUn(),nKt)),a=n.B.Hc(iKt),n.a=new umn(a,c,n.c),n.n&&WY(n.a.n,n.n),nM(n.g,(Yrn(),Est),n.a),t||((i=new tkn(1,c,n.c)).n.a=n.k,UV(n.p,(KQn(),yRt),i),(r=new tkn(1,c,n.c)).n.d=n.k,UV(n.p,KRt,r),(o=new tkn(0,c,n.c)).n.c=n.k,UV(n.p,_Rt,o),(e=new tkn(0,c,n.c)).n.b=n.k,UV(n.p,kRt,e))}function rBn(n){var t,e,i;switch((t=uG(oIn(n.d,(jYn(),Vyt)),223)).g){case 2:e=UJn(n);break;case 3:i=new Zm,kS(JJ(YJ(sin(sin(new fX(null,new h3(n.d.b,16)),new Or),new Ar),new Lr),new pr),new Ng(i)),e=i;break;default:throw hv(new kM("Compaction not supported for "+t+" edges."))}xzn(n,e),z8(new Lw(n.g),new Ag(n))}function cBn(n,t){var e,i,r,c,a,o,u;if(t.Ug("Process directions",1),(e=uG(oIn(n,(QGn(),cCt)),88))!=(xdn(),QDt))for(r=Fkn(n.b,0);r.b!=r.d.c;){switch(i=uG(I6(r),40),o=uG(oIn(i,(OQn(),GPt)),17).a,u=uG(oIn(i,qPt),17).a,e.g){case 4:u*=-1;break;case 1:c=o,o=u,u=c;break;case 2:a=o,o=-u,u=a}kfn(i,GPt,xwn(o)),kfn(i,qPt,xwn(u))}t.Vg()}function aBn(n,t){var e;return e=new Yn,t&&zsn(e,uG(cQ(n.a,iFt),96)),F$(t,422)&&zsn(e,uG(cQ(n.a,rFt),96)),F$(t,366)?(zsn(e,uG(cQ(n.a,lFt),96)),e):(F$(t,84)&&zsn(e,uG(cQ(n.a,cFt),96)),F$(t,207)?(zsn(e,uG(cQ(n.a,bFt),96)),e):F$(t,193)?(zsn(e,uG(cQ(n.a,wFt),96)),e):(F$(t,326)&&zsn(e,uG(cQ(n.a,aFt),96)),e))}function oBn(n){var t,e,i,r,c,a,o;for(o=new c9,a=new Ww(n.a);a.a0&&t=0)return!1;if(t.p=e.b,kD(e.e,t),i==(zIn(),wbt)||i==gbt)for(r=new Ww(t.j);r.an.d[o.p]&&(e+=J8(n.b,c),A6(n.a,xwn(c))):++a;for(e+=n.b.d*a;!LM(n.a);)lin(n.b,uG(xV(n.a),17).a)}return e}function $Bn(n){var t,e,i,r,c,a;return c=0,(t=bEn(n)).kk()&&(c|=4),n.Bb&hrt&&(c|=2),F$(n,102)?(r=lMn(e=uG(n,19)),e.Bb&Qtt&&(c|=32),r&&(iQ(K0(r)),c|=8,((a=r.t)>1||-1==a)&&(c|=16),r.Bb&Qtt&&(c|=64)),e.Bb&P0n&&(c|=frt),c|=w1n):F$(t,469)?c|=512:(i=t.kk())&&1&i.i&&(c|=256),512&n.Bb&&(c|=128),c}function DBn(n,t){var e;return n.f==CBt?(e=sJ(Nen((gAn(),kBt),t)),n.e?4==e&&t!=(m$n(),NBt)&&t!=(m$n(),OBt)&&t!=(m$n(),ABt)&&t!=(m$n(),LBt):2==e):!(!n.d||!(n.d.Hc(t)||n.d.Hc(_3(Nen((gAn(),kBt),t)))||n.d.Hc(iVn((gAn(),kBt),n.b,t))))||!(!n.f||!WRn((gAn(),n.f),HJ(Nen(kBt,t))))&&(e=sJ(Nen(kBt,t)),n.e?4==e:2==e)}function xBn(n){var t,e,i,r,c,a,o,u,s,h,f,l;for(f=-1,l=0,s=0,h=(u=n).length;s0&&++l;++f}return l}function RBn(n,t,i,r){var c,a,o,u,s,h,f,l;return s=(o=uG(zDn(i,(XYn(),mDt)),8)).a,f=o.b+n,(c=e.Math.atan2(f,s))<0&&(c+=f7n),(c+=t)>f7n&&(c-=f7n),h=(u=uG(zDn(r,mDt),8)).a,l=u.b+n,(a=e.Math.atan2(l,h))<0&&(a+=f7n),(a+=t)>f7n&&(a-=f7n),YN(),oan(1e-10),e.Math.abs(c-a)<=1e-10||c==a||isNaN(c)&&isNaN(a)?0:ca?1:KL(isNaN(c),isNaN(a))}function KBn(n){var t,e,i,r,c,a,o;for(o=new Ym,i=new Ww(n.a.b);i.a=n.o)throw hv(new Ik);a=t>>5,c=Nz(1,pz(Nz(31&t,1))),n.n[e][a]=r?S3(n.n[e][a],c):E3(n.n[e][a],CG(c)),c=Nz(c,1),n.n[e][a]=i?S3(n.n[e][a],c):E3(n.n[e][a],CG(c))}catch(o){throw F$(o=Ehn(o),333)?hv(new dM(b3n+n.o+"*"+n.p+w3n+t+TZn+e+d3n)):hv(o)}}function UBn(n,t,e,i){var r,c,a,o,u,s,h,f;for(f=new Hj(new ep(n)),o=0,u=(a=Uhn(cT(pbt,1),e6n,10,0,[t,e])).length;o0&&(!(i=(!n.n&&(n.n=new fV(lFt,n,1,7)),uG(zrn(n.n,0),135)).a)||JA(JA((t.a+=' "',t),i),'"'))),JA(Nj(JA(Nj(JA(Nj(JA(Nj((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function VBn(n){var t,e,i;return 64&n.Db?rOn(n):(t=new lx(Btt),(e=n.k)?JA(JA((t.a+=' "',t),e),'"'):(!n.n&&(n.n=new fV(lFt,n,1,7)),n.n.i>0&&(!(i=(!n.n&&(n.n=new fV(lFt,n,1,7)),uG(zrn(n.n,0),135)).a)||JA(JA((t.a+=' "',t),i),'"'))),JA(Nj(JA(Nj(JA(Nj(JA(Nj((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function WBn(n,t){var e,i,r,c,a;for(t==(Sln(),rEt)&&_An(uG(Y9(n.a,(gPn(),wdt)),15)),r=uG(Y9(n.a,(gPn(),wdt)),15).Kc();r.Ob();)switch(i=uG(r.Pb(),105),e=uG(zq(i.j,0),113).d.j,f$(c=new Z_(i.j),new Fr),t.g){case 2:TCn(n,c,e,(gon(),Edt),1);break;case 1:case 0:TCn(n,new C2(c,0,a=IRn(c)),e,(gon(),Edt),0),TCn(n,new C2(c,a,c.c.length),e,Edt,1)}}function QBn(n,t){var e,i,r,c,a,o;if(null==t||0==t.length)return null;if(!(r=uG(U1(n.a,t),143))){for(i=new _w(new Fw(n.b).a.vc().Kc());i.a.Ob();)if(c=uG(i.a.Pb(),44),a=(e=uG(c.md(),143)).c,o=t.length,m_(a.substr(a.length-o,o),t)&&(t.length==a.length||46==VJ(a,a.length-t.length-1))){if(r)return null;r=e}r&&r2(n.a,t,r)}return r}function JBn(n,t){var e,i,r;return e=new Bn,(i=uG(l8(YJ(new fX(null,new h3(n.f,16)),e),gen(new W,new Q,new rn,new cn,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Out),Iut]))),21).gc())<(r=uG(l8(YJ(new fX(null,new h3(t.f,16)),e),gen(new W,new Q,new rn,new cn,Uhn(cT(Rut,1),p1n,108,0,[Out,Iut]))),21).gc())?-1:i==r?0:1}function YBn(n){var t,e,i;vR(n,(jYn(),PMt))&&((i=uG(oIn(n,PMt),21)).dc()||(e=new nB(t=uG(Mj(eRt),9),uG(MF(t,t.length),9),0),i.Hc((VDn(),Gxt))?Mon(e,Gxt):Mon(e,qxt),i.Hc(Hxt)||Mon(e,Hxt),i.Hc(Bxt)?Mon(e,Vxt):i.Hc(_xt)?Mon(e,zxt):i.Hc(Uxt)&&Mon(e,Xxt),i.Hc(Vxt)?Mon(e,Bxt):i.Hc(zxt)?Mon(e,_xt):i.Hc(Xxt)&&Mon(e,Uxt),kfn(n,PMt,e)))}function ZBn(n){var t,e,i,r,c,a,o;for(r=uG(oIn(n,(GYn(),zpt)),10),u3(0,(i=n.j).c.length),e=uG(i.c[0],12),a=new Ww(r.j);a.ar.p?(NLn(c,KRt),c.d&&(o=c.o.b,t=c.a.b,c.a.b=o-t)):c.j==KRt&&r.p>n.p&&(NLn(c,yRt),c.d&&(o=c.o.b,t=c.a.b,c.a.b=-(o-t)));break}return r}function nHn(n,t,e,i,r){var c,a,o,u,s,h,f;if(!(F$(t,207)||F$(t,366)||F$(t,193)))throw hv(new vM("Method only works for ElkNode-, ElkLabel and ElkPort-objects."));return a=n.a/2,u=t.i+i-a,h=t.j+r-a,s=u+t.g+n.a,f=h+t.f+n.a,aq(c=new Uk,new MO(u,h)),aq(c,new MO(u,f)),aq(c,new MO(s,f)),aq(c,new MO(s,h)),zsn(o=new pDn(c),t),e&&vJ(n.b,t,o),o}function tHn(n,t,e){var i,r,c,a,o,u,s,h;for(c=new MO(t,e),s=new Ww(n.a);s.a1&&(i=new MO(r,e.b),aq(t.a,i)),dan(t.a,Uhn(cT(PNt,1),zZn,8,0,[f,h]))}function THn(){THn=E,$jt=new dI(q4n,0),Ijt=new dI("NIKOLOV",1),Ljt=new dI("NIKOLOV_PIXEL",2),Ojt=new dI("NIKOLOV_IMPROVED",3),Ajt=new dI("NIKOLOV_IMPROVED_PIXEL",4),Sjt=new dI("DUMMYNODE_PERCENTAGE",5),Njt=new dI("NODECOUNT_PERCENTAGE",6),Djt=new dI("NO_BOUNDARY",7),Pjt=new dI("MODEL_ORDER_LEFT_TO_RIGHT",8),Cjt=new dI("MODEL_ORDER_RIGHT_TO_LEFT",9)}function jHn(n){var t,e,i,r,c;for(i=n.length,t=new VM,c=0;c=40)&&IGn(n),rzn(n),mFn(n),e=ign(n),i=0;e&&i0&&aq(n.f,c)):(n.c[a]-=s+1,n.c[a]<=0&&n.a[a]>0&&aq(n.e,c))))}function rUn(n,t,e,i){var r,c,a,o,u,s,h;for(YF(u=new MO(e,i),uG(oIn(t,(OQn(),kPt)),8)),h=Fkn(t.b,0);h.b!=h.d.c;)JF((s=uG(I6(h),40)).e,u),aq(n.b,s);for(o=uG(l8(_0(new fX(null,new h3(t.a,16))),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15).Kc();o.Ob();){for(c=Fkn((a=uG(o.Pb(),65)).a,0);c.b!=c.d.c;)(r=uG(I6(c),8)).a+=u.a,r.b+=u.b;aq(n.a,a)}}function cUn(n,t){var e,i,r,c;if(0<(F$(n,16)?uG(n,16).gc():x5(n.Kc()))){if(1<(r=t)){for(--r,c=new Ea,i=n.Kc();i.Ob();)e=uG(i.Pb(),40),c=zcn(Uhn(cT(vat,1),EZn,20,0,[c,new Mp(e)]));return cUn(c,r)}if(r<0){for(c=new Sa,i=n.Kc();i.Ob();)e=uG(i.Pb(),40),c=zcn(Uhn(cT(vat,1),EZn,20,0,[c,new Mp(e)]));if(0<(F$(c,16)?uG(c,16).gc():x5(c.Kc())))return cUn(c,r)}}return uG(B$(n.Kc()),40)}function aUn(n,t,e){var i,r,c,a;for(e.Ug("Processor order nodes",2),n.b=uM(pK(oIn(t,(QGn(),ECt)))),n.a=uG(oIn(t,cCt),88),n.a==(xdn(),ZDt)&&(n.a=QDt,kfn(t,cCt,n.a)),r=new lS,a=Fkn(t.b,0);a.b!=a.d.c;)oM(gK(oIn(c=uG(I6(a),40),(OQn(),UPt))))&&s8(r,c,r.c.b,r.c);MK(0!=r.b),izn(n,i=uG(r.a.a.c,40)),e.fh(1),GBn(n,i,0-uM(pK(oIn(i,(OQn(),NPt))))/2,0),e.fh(1),e.Vg()}function oUn(){oUn=E,eKt=new FO("DEFAULT_MINIMUM_SIZE",0),rKt=new FO("MINIMUM_SIZE_ACCOUNTS_FOR_PADDING",1),tKt=new FO("COMPUTE_PADDING",2),cKt=new FO("OUTSIDE_NODE_LABELS_OVERHANG",3),aKt=new FO("PORTS_OVERHANG",4),uKt=new FO("UNIFORM_PORT_SPACING",5),oKt=new FO("SPACE_EFFICIENT_PORT_LABELS",6),iKt=new FO("FORCE_TABULAR_NODE_LABELS",7),nKt=new FO("ASYMMETRICAL",8)}function uUn(n,t){var e,i,r,c,a,o,u,s;if(t){if(e=(c=t.Dh())?Hrn(c).wi().si(c):null){for(Akn(n,t,e),u=0,s=(null==(r=t.Dh()).i&&eqn(r),r.i).length;u=0&&u2*c?(h=new Jrn(f),s=EX(a)/jX(a),u=KJn(h,t,new Dk,e,i,r,s),JF(dL(h.e),u),f.c.length=0,c=0,mv(f.c,h),mv(f.c,a),c=EX(h)*jX(h)+EX(a)*jX(a)):(mv(f.c,a),c+=EX(a)*jX(a));return f}function lUn(n,t){var e,i,r,c,a,o;if((o=uG(oIn(t,(jYn(),JMt)),101))==($Pn(),aRt)||o==cRt)for(r=new MO(t.f.a+t.d.b+t.d.c,t.f.b+t.d.d+t.d.a).b,a=new Ww(n.a);a.ae?t:e;s<=f;++s)s==e?o=i++:(c=r[s],h=w.am(c.Lk()),s==t&&(u=s!=f||h?i:i-1),h&&++i);return l=uG(zdn(n,t,e),76),o!=u&&Yv(n,new wtn(n.e,7,a,xwn(o),b.md(),u)),l}return uG(zdn(n,t,e),76)}function wUn(n,t){var e,i,r,c,a,o;for(t.Ug("Port order processing",1),o=uG(oIn(n,(jYn(),iTt)),430),e=new Ww(n.b);e.a=0&&(!fjn(n,a)||(u<22?o.l|=1<>>1,a.m=s>>>1|(1&h)<<21,a.l=f>>>1|(1&s)<<21,--u;return e&&Yfn(o),c&&(i?(Qat=gfn(n),r&&(Qat=Thn(Qat,(tin(),Zat)))):Qat=p$(n.l,n.m,n.h)),o}function mUn(n,t){var e,i,r,c,a,o,u,s,h,f;for(s=n.e[t.c.p][t.p]+1,u=t.c.a.c.length+1,o=new Ww(n.a);o.a0&&(s3(0,n.length),45==n.charCodeAt(0)||(s3(0,n.length),43==n.charCodeAt(0)))?1:0;ie)throw hv(new ZM(y0n+n+'"'));return a}function kUn(n){var t,i,r,c,a,o;for(a=new lS,c=new Ww(n.a);c.a1)&&1==t&&uG(n.a[n.b],10).k==(zIn(),bbt)?Gqn(uG(n.a[n.b],10),(Ajn(),$xt)):i&&(!e||(n.c-n.b&n.a.length-1)>1)&&1==t&&uG(n.a[n.c-1&n.a.length-1],10).k==(zIn(),bbt)?Gqn(uG(n.a[n.c-1&n.a.length-1],10),(Ajn(),Dxt)):2==(n.c-n.b&n.a.length-1)?(Gqn(uG(Rfn(n),10),(Ajn(),$xt)),Gqn(uG(Rfn(n),10),Dxt)):Pxn(n,r),q5(n)}function EUn(n,t,i){var r,c,a,o,u;for(a=0,c=new DD((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a));c.e!=c.i.gc();)o="",0==(!(r=uG(Zkn(c),27)).n&&(r.n=new fV(lFt,r,1,7)),r.n).i||(o=uG(zrn((!r.n&&(r.n=new fV(lFt,r,1,7)),r.n),0),135).a),zsn(u=new wln(a++,t,o),r),kfn(u,(OQn(),RPt),r),u.e.b=r.j+r.f/2,u.f.a=e.Math.max(r.g,1),u.e.a=r.i+r.g/2,u.f.b=e.Math.max(r.f,1),aq(t.b,u),VAn(i.f,r,u)}function SUn(n){var t,e,i,r,c;i=uG(oIn(n,(GYn(),rmt)),27),c=uG(zDn(i,(jYn(),DMt)),181).Hc((Qmn(),JRt)),n.e||(r=uG(oIn(n,Hpt),21),t=new MO(n.f.a+n.d.b+n.d.c,n.f.b+n.d.d+n.d.a),r.Hc((r_n(),tpt))?(Myn(i,JMt,($Pn(),cRt)),ZQn(i,t.a,t.b,!1,!0)):oM(gK(zDn(i,xMt)))||ZQn(i,t.a,t.b,!0,!0)),Myn(i,DMt,c?ggn(JRt):new nB(e=uG(Mj(sKt),9),uG(MF(e,e.length),9),0))}function PUn(n,t,e){var i,r,c,a;if(t[0]>=n.length)return e.o=0,!0;switch(VJ(n,t[0])){case 43:r=1;break;case 45:r=-1;break;default:return e.o=0,!0}if(++t[0],c=t[0],0==(a=RNn(n,t))&&t[0]==c)return!1;if(t[0]a&&(a=r,s.c.length=0),r==a&&kD(s,new WO(e.c.i,e)));hZ(),f$(s,n.c),GX(n.b,o.p,s)}}function AUn(n,t){var e,i,r,c,a,o,u,s;for(c=new Ww(t.b);c.aa&&(a=r,s.c.length=0),r==a&&kD(s,new WO(e.d.i,e)));hZ(),f$(s,n.c),GX(n.f,o.p,s)}}function LUn(n,t){var e,i,r,c,a,o,u;if(null==(u=gK(oIn(t,(QGn(),TCt))))||(tJ(u),u)){for(E$n(n,t),r=new Zm,o=Fkn(t.b,0);o.b!=o.d.c;)(e=yAn(n,uG(I6(o),40),null))&&(zsn(e,t),mv(r.c,e));if(n.a=null,n.b=null,r.c.length>1)for(i=new Ww(r);i.a=0&&o!=e&&(c=new lV(n,1,o,a,null),i?i.nj(c):i=c),e>=0&&(c=new lV(n,1,e,o==e?a:null,t),i?i.nj(c):i=c)),i}function xUn(n){var t,e,i;if(null==n.b){if(i=new zM,null!=n.i&&(VA(i,n.i),i.a+=":"),256&n.f){for(256&n.f&&null!=n.a&&(aY(n.i)||(i.a+="//"),VA(i,n.a)),null!=n.d&&(i.a+="/",VA(i,n.d)),16&n.f&&(i.a+="/"),t=0,e=n.j.length;ts)&&(u+o+uXn(i,s,!1).a<=t.b&&(dtn(e,c-e.s),e.c=!0,dtn(i,c-e.s),oMn(i,e.s,e.t+e.d+o),i.k=!0,Gun(e.q,i),h=!0,r&&(fan(t,i),i.j=t,n.c.length>a&&(uEn((u3(a,n.c.length),uG(n.c[a],186)),i),0==(u3(a,n.c.length),uG(n.c[a],186)).a.c.length&&i7(n,a)))),h)}function UUn(n,t){var e,i,r,c,a;if(t.Ug("Partition midprocessing",1),r=new K1,kS(JJ(new fX(null,new h3(n.a,16)),new di),new kg(r)),0!=r.d){for(a=uG(l8(f3(new fX(null,(r.i||(r.i=new RD(r,r.c))).Nc())),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15),e=uG((i=a.Kc()).Pb(),17);i.Ob();)c=uG(i.Pb(),17),RRn(uG(Y9(r,e),21),uG(Y9(r,c),21)),e=c;t.Vg()}}function GUn(n,t,e){var i,r,c,a,o;if(0==t.p){for(t.p=1,(r=e)||(r=new WO(new Zm,new nB(i=uG(Mj(YRt),9),uG(MF(i,i.length),9),0))),uG(r.a,15).Fc(t),t.k==(zIn(),lbt)&&uG(r.b,21).Fc(uG(oIn(t,(GYn(),Fpt)),64)),a=new Ww(t.j);a.a0)if(r=uG(n.Ab.g,2033),null==t){for(c=0;ci.s&&ua)return KQn(),kRt;break;case 4:case 3:if(h<0)return KQn(),yRt;if(h+e>c)return KQn(),KRt}return(u=(s+o/2)/a)+(i=(h+e/2)/c)<=1&&u-i<=0?(KQn(),_Rt):u+i>=1&&u-i>=0?(KQn(),kRt):i<.5?(KQn(),yRt):(KQn(),KRt)}function tGn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b;for(e=!1,u=uM(pK(oIn(t,(jYn(),ETt)))),l=T1n*u,r=new Ww(t.b);r.aa.n.b-a.d.d+h.a+l&&(b=s.g+h.g,h.a=(h.g*h.a+s.g*s.a)/b,h.g=b,s.f=h,e=!0)),c=a,s=h;return e}function eGn(n,t,e,i,r,c,a){var o,u,s,h,f;for(f=new cN,u=t.Kc();u.Ob();)for(h=new Ww(uG(u.Pb(),853).Rf());h.a0?o.a?r>(s=o.b.Mf().b)&&(n.v||1==o.c.d.c.length?(a=(r-s)/2,o.d.d=a,o.d.a=a):(i=(uG(zq(o.c.d,0),187).Mf().b-s)/2,o.d.d=e.Math.max(0,i),o.d.a=r-i-s)):o.d.a=n.t+r:cV(n.u)&&((c=ECn(o.b)).d<0&&(o.d.d=-c.d),c.d+c.a>o.b.Mf().b&&(o.d.a=c.d+c.a-o.b.Mf().b))}function cGn(){cGn=E,$ft=new _N((XYn(),vDt),xwn(1)),_ft=new _N(DDt,80),Fft=new _N(CDt,5),kft=new _N(c$t,r4n),Dft=new _N(kDt,xwn(1)),Kft=new _N(TDt,(qx(),!0)),Aft=new CN(50),Oft=new _N(W$t,Aft),Mft=O$t,Lft=sDt,yft=new _N(p$t,!1),Ift=V$t,Pft=H$t,Cft=q$t,Sft=_$t,Eft=K$t,Nft=bDt,oOn(),jft=sft,Bft=wft,Tft=uft,xft=fft,Rft=bft,Gft=HDt,Xft=XDt,Uft=BDt,Hft=_Dt,Iwn(),new _N(UDt,qft=fKt)}function aGn(n,t){var e;switch(Min(n)){case 6:return RA(t);case 7:return FA(t);case 8:return KA(t);case 3:return Array.isArray(t)&&!((e=Min(t))>=14&&e<=16);case 11:return null!=t&&typeof t===mZn;case 12:return null!=t&&(typeof t===wZn||typeof t==mZn);case 0:return Eyn(t,n.__elementTypeId$);case 2:return NV(t)&&!(t.Tm===j);case 1:return NV(t)&&!(t.Tm===j)||Eyn(t,n.__elementTypeId$);default:return!0}}function oGn(n,t){var i,r,c,a;return r=e.Math.min(e.Math.abs(n.c-(t.c+t.b)),e.Math.abs(n.c+n.b-t.c)),a=e.Math.min(e.Math.abs(n.d-(t.d+t.a)),e.Math.abs(n.d+n.a-t.d)),(i=e.Math.abs(n.c+n.b/2-(t.c+t.b/2)))>n.b/2+t.b/2||(c=e.Math.abs(n.d+n.a/2-(t.d+t.a/2)))>n.a/2+t.a/2?1:0==i&&0==c?0:0==i?a/c+1:0==c?r/i+1:e.Math.min(r/i,a/c)+1}function uGn(n,t){var e,i,r,c,a,o,u;for(c=0,o=0,u=0,r=new Ww(n.f.e);r.a0&&n.d!=(Jen(),plt)&&(o+=a*(i.d.a+n.a[t.a][i.a]*(t.d.a-i.d.a)/e)),e>0&&n.d!=(Jen(),dlt)&&(u+=a*(i.d.b+n.a[t.a][i.a]*(t.d.b-i.d.b)/e)));switch(n.d.g){case 1:return new MO(o/c,t.d.b);case 2:return new MO(t.d.a,u/c);default:return new MO(o/c,u/c)}}function sGn(n){var t,e,i,r,c;for(kD(c=new R7((!n.a&&(n.a=new MD(eFt,n,5)),n.a).i+2),new MO(n.j,n.k)),kS(new fX(null,(!n.a&&(n.a=new MD(eFt,n,5)),new h3(n.a,16))),new Vp(c)),kD(c,new MO(n.b,n.c)),t=1;t0&&(hfn(u,!1,(xdn(),JDt)),hfn(u,!0,YDt)),Prn(t.g,new UC(n,e)),vJ(n.g,t,e)}function lGn(){var n;for(lGn=E,pot=Uhn(cT(YHt,1),W1n,28,15,[-1,-1,30,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5]),mot=Inn(YHt,W1n,28,37,15,1),vot=Uhn(cT(YHt,1),W1n,28,15,[-1,-1,63,40,32,28,25,23,21,20,19,19,18,18,17,17,16,16,16,15,15,15,15,14,14,14,14,14,14,13,13,13,13,13,13,13,13]),kot=Inn(nUt,E0n,28,37,14,1),n=2;n<=36;n++)mot[n]=t0(e.Math.pow(n,pot[n])),kot[n]=bSn(YZn,mot[n])}function bGn(n){var t;if(1!=(!n.a&&(n.a=new fV(oFt,n,6,6)),n.a).i)throw hv(new vM(Ptt+(!n.a&&(n.a=new fV(oFt,n,6,6)),n.a).i));return t=new Uk,Shn(uG(zrn((!n.b&&(n.b=new f_(cFt,n,4,7)),n.b),0),84))&&Qon(t,pYn(n,Shn(uG(zrn((!n.b&&(n.b=new f_(cFt,n,4,7)),n.b),0),84)),!1)),Shn(uG(zrn((!n.c&&(n.c=new f_(cFt,n,5,8)),n.c),0),84))&&Qon(t,pYn(n,Shn(uG(zrn((!n.c&&(n.c=new f_(cFt,n,5,8)),n.c),0),84)),!0)),t}function wGn(n,t){var e,i,r;for(r=!1,i=new Fz(ix((t.d?n.a.c==(b0(),fSt)?qgn(t.b):Xgn(t.b):n.a.c==(b0(),hSt)?qgn(t.b):Xgn(t.b)).a.Kc(),new h));hDn(i);)if(e=uG(N9(i),18),(oM(n.a.f[n.a.g[t.b.p].p])||v9(e)||e.c.i.c!=e.d.i.c)&&!oM(n.a.n[n.a.g[t.b.p].p])&&!oM(n.a.n[n.a.g[t.b.p].p])&&(r=!0,cS(n.b,n.a.g[vTn(e,t.b).p])))return t.c=!0,t.a=e,t;return t.c=r,t.a=null,t}function dGn(n,t,e){var i,r,c,a,o,u,s;if(0==(i=e.gc()))return!1;if(n.Pj())if(u=n.Qj(),nmn(n,t,e),a=1==i?n.Ij(3,null,e.Kc().Pb(),t,u):n.Ij(5,null,e,t,u),n.Mj()){for(o=i<100?null:new cj(i),c=t+i,r=t;r0){for(o=0;o>16==-15&&n.Cb.Yh()&&Cen(new btn(n.Cb,9,13,e,n.c,Hyn(Aen(uG(n.Cb,62)),n))):F$(n.Cb,90)&&n.Db>>16==-23&&n.Cb.Yh()&&(F$(t=n.c,90)||(YYn(),t=x_t),F$(e,90)||(YYn(),e=x_t),Cen(new btn(n.Cb,9,10,e,t,Hyn(z5(uG(n.Cb,29)),n)))))),n.c}function TGn(n,t,e){var i,r,c,a,o,u,s,h;for(e.Ug("Hyperedge merging",1),CDn(n,t),o=new N4(t.b,0);o.b0,o=hpn(t,c),Px(e?o.b:o.g,t),1==Ebn(o).c.length&&s8(i,o,i.c.b,i.c),r=new WO(c,t),A6(n.o,r),men(n.e.a,c))}function OGn(n,t){var i,r,c,a;return r=e.Math.abs(AV(n.b).a-AV(t.b).a),a=e.Math.abs(AV(n.b).b-AV(t.b).b),i=1,c=1,r>n.b.b/2+t.b.b/2&&(i=1-e.Math.min(e.Math.abs(n.b.c-(t.b.c+t.b.b)),e.Math.abs(n.b.c+n.b.b-t.b.c))/r),a>n.b.a/2+t.b.a/2&&(c=1-e.Math.min(e.Math.abs(n.b.d-(t.b.d+t.b.a)),e.Math.abs(n.b.d+n.b.a-t.b.d))/a),(1-e.Math.min(i,c))*e.Math.sqrt(r*r+a*a)}function AGn(n){var t,e,i;for(wQn(n,n.e,n.f,(l0(),USt),!0,n.c,n.i),wQn(n,n.e,n.f,USt,!1,n.c,n.i),wQn(n,n.e,n.f,GSt,!0,n.c,n.i),wQn(n,n.e,n.f,GSt,!1,n.c,n.i),yGn(n,n.c,n.e,n.f,n.i),e=new N4(n.i,0);e.b=65;e--)dHt[e]=e-65<<24>>24;for(i=122;i>=97;i--)dHt[i]=i-97+26<<24>>24;for(r=57;r>=48;r--)dHt[r]=r-48+52<<24>>24;for(dHt[43]=62,dHt[47]=63,c=0;c<=25;c++)gHt[c]=65+c&D1n;for(a=26,u=0;a<=51;++a,u++)gHt[a]=97+u&D1n;for(n=52,o=0;n<=61;++n,o++)gHt[n]=48+o&D1n;gHt[62]=43,gHt[63]=47}function $Gn(n,t){var i,r,c,a,o,u;return(c=nun(n))==(u=nun(t))?n.e==t.e&&n.a<54&&t.a<54?n.ft.f?1:0:(r=n.e-t.e,(i=(n.d>0?n.d:e.Math.floor((n.a-1)*A0n)+1)-(t.d>0?t.d:e.Math.floor((t.a-1)*A0n)+1))>r+1?c:i0&&(o=j5(o,_qn(r))),Pvn(a,o))):cs&&(l=0,b+=u+t,u=0),tHn(a,l,b),i=e.Math.max(i,l+h.a),u=e.Math.max(u,h.b),l+=h.a+t;return new MO(i+t,b+u+t)}function RGn(n,t){var e,i,r,c,a,o,u;if(!h0(n))throw hv(new kM(Stt));if(c=(i=h0(n)).g,r=i.f,c<=0&&r<=0)return KQn(),FRt;switch(o=n.i,u=n.j,t.g){case 2:case 1:if(o<0)return KQn(),_Rt;if(o+n.g>c)return KQn(),kRt;break;case 4:case 3:if(u<0)return KQn(),yRt;if(u+n.f>r)return KQn(),KRt}return(a=(o+n.g/2)/c)+(e=(u+n.f/2)/r)<=1&&a-e<=0?(KQn(),_Rt):a+e>=1&&a-e>=0?(KQn(),kRt):e<.5?(KQn(),yRt):(KQn(),KRt)}function KGn(n,t,e,i,r){var c,a;if(c=Lgn(E3(t[0],L0n),E3(i[0],L0n)),n[0]=pz(c),c=$z(c,32),e>=r){for(a=1;a0&&(r.b[a++]=0,r.b[a++]=c.b[0]-1),t=1;t0&&(Qb(u,u.d-r.d),r.c==(_7(),$St)&&Vb(u,u.a-r.d),u.d<=0&&u.i>0&&s8(t,u,t.c.b,t.c));for(c=new Ww(n.f);c.a0&&(Jb(o,o.i-r.d),r.c==(_7(),$St)&&Wb(o,o.b-r.d),o.i<=0&&o.d>0&&s8(e,o,e.c.b,e.c))}function GGn(n,t,e,i,r){var c,a,o,u,s,h,f,l,b;for(hZ(),f$(n,new Bu),a=oG(n),b=new Zm,l=new Zm,o=null,u=0;0!=a.b;)c=uG(0==a.b?null:(MK(0!=a.b),Lrn(a,a.a.a)),163),!o||EX(o)*jX(o)/21&&(u>EX(o)*jX(o)/2||0==a.b)&&(f=new Jrn(l),h=EX(o)/jX(o),s=KJn(f,t,new Dk,e,i,r,h),JF(dL(f.e),s),o=f,mv(b.c,f),u=0,l.c.length=0));return Ohn(b,l),b}function qGn(n,t,e,i,r){var c,a,o,u,s,h,f;if(bS(),aW(n,"src"),aW(e,"dest"),f=Tbn(n),u=Tbn(e),yG(!!(4&f.i),"srcType is not an array"),yG(!!(4&u.i),"destType is not an array"),h=f.c,a=u.c,yG(1&h.i?h==a:!(1&a.i),"Array types don't match"),$fn(n,t,e,i,r),1&h.i||f==u)b$n(n,t,e,i,r,!0);else if(s=Kcn(n),c=Kcn(e),xA(n)===xA(e)&&ti;)uQ(c,o,s[--t]);else for(o=i+r;i0),i.a.Xb(i.c=--i.b),h>f+o&&LQ(i);for(c=new Ww(l);c.a0),i.a.Xb(i.c=--i.b)}}function VGn(){var n,t,e,i,r,c;if(QYn(),WHt)return WHt;for(TXn(n=new K3(4),kJn(iat,!0)),lWn(n,kJn("M",!0)),lWn(n,kJn("C",!0)),c=new K3(4),i=0;i<11;i++)HFn(c,i,i);return TXn(t=new K3(4),kJn("M",!0)),HFn(t,4448,4607),HFn(t,65438,65439),kzn(r=new QN(2),n),kzn(r,OHt),(e=new QN(2)).Jm(CX(c,kJn("L",!0))),e.Jm(t),e=new n8(3,e),e=new eW(r,e),WHt=e}function WGn(n,t){var e,i,r,c,a,o,u,s;for(e=new RegExp(t,"g"),u=Inn($ot,zZn,2,0,6,1),i=0,s=n,c=null;;){if(null==(o=e.exec(s))||""==s){u[i]=s;break}a=o.index,u[i]=(Knn(0,a,s.length),s.substr(0,a)),s=r1(s,a+o[0].length,s.length),e.lastIndex=0,c==s&&(u[i]=(Knn(0,1,s.length),s.substr(0,1)),s3(1,s.length+1),s=s.substr(1)),c=s,++i}if(n.length>0){for(r=u.length;r>0&&""==u[r-1];)--r;r0&&(l-=r[0]+n.c,r[0]+=n.c),r[2]>0&&(l-=r[2]+n.c),r[1]=e.Math.max(r[1],l),qX(n.a[1],i.c+t.b+r[0]-(r[1]-l)/2,r[1]);for(u=0,h=(a=n.a).length;u0?(n.n.c.length-1)*n.i:0,i=new Ww(n.n);i.a1)for(i=Fkn(r,0);i.b!=i.d.c;)for(c=0,o=new Ww((e=uG(I6(i),235)).e);o.a0&&(t[0]+=n.c,l-=t[0]),t[2]>0&&(l-=t[2]+n.c),t[1]=e.Math.max(t[1],l),XX(n.a[1],r.d+i.d+t[0]-(t[1]-l)/2,t[1]);else for(w=r.d+i.d,b=r.a-i.d-i.a,s=0,f=(o=n.a).length;s0||0==Fgn(c.b.d,n.b.d+n.b.a)&&r.b<0||0==Fgn(c.b.d+c.b.a,n.b.d)&&r.b>0){u=0;break}}else u=e.Math.min(u,LLn(n,c,r));u=e.Math.min(u,uqn(n,a,u,r))}return u}function sqn(n,t){var e,i,r,c,a,o;if(n.b<2)throw hv(new vM("The vector chain must contain at least a source and a target point."));for(MK(0!=n.b),MN(t,(i=uG(n.a.a.c,8)).a,i.b),o=new Zx((!t.a&&(t.a=new MD(eFt,t,5)),t.a)),c=Fkn(n,1);c.a=0&&c!=e)throw hv(new vM(Xet));for(r=0,u=0;uuM(oD(a.g,a.d[0]).a)?(MK(u.b>0),u.a.Xb(u.c=--u.b),pF(u,a),r=!0):o.e&&o.e.gc()>0&&(c=(!o.e&&(o.e=new Zm),o.e).Mc(t),s=(!o.e&&(o.e=new Zm),o.e).Mc(e),(c||s)&&((!o.e&&(o.e=new Zm),o.e).Fc(a),++a.c));r||mv(i.c,a)}function bqn(n,t,e){var i,r,c,a,o,u,s,h,f,l;return h=n.a.i+n.a.g/2,f=n.a.i+n.a.g/2,a=new MO(t.i+t.g/2,t.j+t.f/2),(u=uG(zDn(t,(XYn(),mDt)),8)).a=u.a+h,u.b=u.b+f,r=(a.b-u.b)/(a.a-u.a),i=a.b-r*a.a,o=new MO(e.i+e.g/2,e.j+e.f/2),(s=uG(zDn(e,mDt),8)).a=s.a+h,s.b=s.b+f,c=(o.b-s.b)/(o.a-s.a),l=(i-(o.b-c*o.a))/(c-r),!(u.a>>0).toString(16),t.length-2,t.length):n>=P0n?"\\v"+r1(t="0"+(n>>>0).toString(16),t.length-6,t.length):""+String.fromCharCode(n&D1n)}return e}function Tqn(n){var t,e,i;if(sN(uG(oIn(n,(jYn(),JMt)),101)))for(e=new Ww(n.j);e.a=t.o&&e.f<=t.f||.5*t.a<=e.f&&1.5*t.a>=e.f){if((c=uG(zq(t.n,t.n.c.length-1),209)).e+c.d+e.g+r<=i&&(uG(zq(t.n,t.n.c.length-1),209).f-n.f+e.f<=n.b||1==n.a.c.length))return ipn(t,e),!0;if(t.s+e.g<=i&&(t.t+t.d+e.f+r<=n.b||1==n.a.c.length))return kD(t.b,e),a=uG(zq(t.n,t.n.c.length-1),209),kD(t.n,new c0(t.s,a.f+a.a+t.i,t.i)),zMn(uG(zq(t.n,t.n.c.length-1),209),e),nqn(t,e),!0}return!1}function Pqn(n,t,e){var i,r,c,a;return n.Pj()?(r=null,c=n.Qj(),i=n.Ij(1,a=iin(n,t,e),e,t,c),n.Mj()&&!(n.Yi()&&null!=a?udn(a,e):xA(a)===xA(e))?(null!=a&&(r=n.Oj(a,r)),r=n.Nj(e,r),n.Tj()&&(r=n.Wj(a,e,r)),r?(r.nj(i),r.oj()):n.Jj(i)):(n.Tj()&&(r=n.Wj(a,e,r)),r?(r.nj(i),r.oj()):n.Jj(i)),a):(a=iin(n,t,e),n.Mj()&&!(n.Yi()&&null!=a?udn(a,e):xA(a)===xA(e))&&(r=null,null!=a&&(r=n.Oj(a,null)),(r=n.Nj(e,r))&&r.oj()),a)}function Cqn(n,t){var e,i,r,c;if(t.Ug("Path-Like Graph Wrapping",1),0!=n.b.c.length)if(null==(r=new dDn(n)).i&&(r.i=aun(r,new pc)),e=uM(r.i)*r.f/(null==r.i&&(r.i=aun(r,new pc)),uM(r.i)),r.b>e)t.Vg();else{switch(uG(oIn(n,(jYn(),BTt)),351).g){case 2:c=new kc;break;case 0:c=new hc;break;default:c=new yc}if(i=c.og(n,r),!c.pg())switch(uG(oIn(n,zTt),352).g){case 2:i=KLn(r,i);break;case 1:i=pPn(r,i)}yzn(n,r,i),t.Vg()}else t.Vg()}function Iqn(n,t){var i,r,c,a,o,u,s;t%=24,n.q.getHours()!=t&&((i=new e.Date(n.q.getTime())).setDate(i.getDate()+1),(o=n.q.getTimezoneOffset()-i.getTimezoneOffset())>0&&(u=o/60|0,s=o%60,r=n.q.getDate(),n.q.getHours()+u>=24&&++r,c=new e.Date(n.q.getFullYear(),n.q.getMonth(),r,t+u,n.q.getMinutes()+s,n.q.getSeconds(),n.q.getMilliseconds()),n.q.setTime(c.getTime()))),a=n.q.getTime(),n.q.setTime(a+36e5),n.q.getHours()!=t&&n.q.setTime(a)}function Oqn(n,t){var e,i,r,c;if(a3(n.d,n.e),n.c.a.$b(),0!=uM(pK(oIn(t.j,(jYn(),yyt))))||0!=uM(pK(oIn(t.j,yyt))))for(e=B3n,xA(oIn(t.j,Syt))!==xA((yvn(),Fjt))&&kfn(t.j,(GYn(),Bpt),(qx(),!0)),c=uG(oIn(t.j,OTt),17).a,r=0;r(u3(c+1,t.c.length),uG(t.c[c+1],17)).a-i&&++o,kD(r,(u3(c+o,t.c.length),uG(t.c[c+o],17))),a+=(u3(c+o,t.c.length),uG(t.c[c+o],17)).a-i,++e;e=g&&n.e[s.p]>w*n.b||v>=i*g)&&(mv(l.c,u),u=new Zm,Qon(o,a),a.a.$b(),h-=f,b=e.Math.max(b,h*n.b+d),h+=v,m=v,v=0,f=0,d=0);return new WO(b,l)}function $qn(n){var t,e,i,r,c;if(!n.d){if(c=new js,null==(t=V_t).a.zc(n,t)){for(e=new DD(n1(n));e.e!=e.i.gc();)CW(c,$qn(uG(Zkn(e),29)));t.a.Bc(n),t.a.gc()}for(r=c.i,!n.q&&(n.q=new fV(p_t,n,11,10)),i=new DD(n.q);i.e!=i.i.gc();++r)uG(Zkn(i),411);CW(c,(!n.q&&(n.q=new fV(p_t,n,11,10)),n.q)),lbn(c),n.d=new vL((uG(zrn(gZ((tQ(),M_t).o),9),19),c.i),c.g),n.e=uG(c.g,688),null==n.e&&(n.e=W_t),y9(n).b&=-17}return n.d}function Dqn(n,t,e,i){var r,c,a,o,u,s;if(s=VKn(n.e.Dh(),t),u=0,r=uG(n.g,124),PP(),uG(t,69).xk()){for(a=0;a1||-1==w)if(f=uG(d,71),l=uG(h,71),f.dc())l.$b();else for(a=!!lMn(t),c=0,o=n.a?f.Kc():f.Ii();o.Ob();)s=uG(o.Pb(),58),(r=uG(ain(n,s),58))?(a?-1==(u=l.dd(r))?l.Gi(c,r):c!=u&&l.Ui(c,r):l.Gi(c,r),++c):n.b&&!a&&(l.Gi(c,s),++c);else null==d?h.Wb(null):null==(r=ain(n,d))?n.b&&!lMn(t)&&h.Wb(d):h.Wb(r)}function Rqn(n,t){var i,r,c,a,o,u,s,f;for(i=new Ne,c=new Fz(ix(qgn(t).a.Kc(),new h));hDn(c);)if(!v9(r=uG(N9(c),18))&&_Pn(u=r.c.i,$bt)){if(-1==(f=U_n(n,u,$bt,Nbt)))continue;i.b=e.Math.max(i.b,f),!i.a&&(i.a=new Zm),kD(i.a,u)}for(o=new Fz(ix(Xgn(t).a.Kc(),new h));hDn(o);)if(!v9(a=uG(N9(o),18))&&_Pn(s=a.d.i,Nbt)){if(-1==(f=U_n(n,s,Nbt,$bt)))continue;i.d=e.Math.max(i.d,f),!i.c&&(i.c=new Zm),kD(i.c,s)}return i}function Kqn(n,t,e,i){var r,c,a,o,u,s,h;if(e.d.i!=t.i){for(Hb(r=new gMn(n),(zIn(),wbt)),kfn(r,(GYn(),rmt),e),kfn(r,(jYn(),JMt),($Pn(),cRt)),mv(i.c,r),o2(a=new lOn,r),NLn(a,(KQn(),_Rt)),o2(o=new lOn,r),NLn(o,kRt),h=e.d,u2(e,a),zsn(c=new UZ,e),kfn(c,bMt,null),c2(c,o),u2(c,h),s=new N4(e.b,0);s.b1e6)throw hv(new wM("power of ten too big"));if(n<=vZn)return D9(t$n(Got[1],t),t);for(r=i=t$n(Got[1],vZn),e=Bsn(n-vZn),t=t0(n%vZn);dwn(e,vZn)>0;)r=j5(r,i),e=$gn(e,vZn);for(r=D9(r=j5(r,t$n(Got[1],t)),vZn),e=Bsn(n-vZn);dwn(e,vZn)>0;)r=D9(r,vZn),e=$gn(e,vZn);return r=D9(r,t)}function Bqn(n){var t,e,i,r,c,a,o,u;for(a=new Ww(n.a);a.as&&i>s)){r=!1,e._g()&&e.bh("bk node placement breaks on "+o+" which should have been after "+h);break}h=o,s=uM(t.p[o.p])+uM(t.d[o.p])+o.o.b+o.d.a}if(!r)break}return e._g()&&e.bh(t+" is feasible: "+r),r}function Xqn(n,t,e,i){var r,c,a,o,u,s,h;if(Hb(c=new gMn(n),(zIn(),gbt)),kfn(c,(jYn(),JMt),($Pn(),cRt)),r=0,t){for(kfn(a=new lOn,(GYn(),rmt),t),kfn(c,rmt,t.i),NLn(a,(KQn(),_Rt)),o2(a,c),s=0,h=(u=x4(t.e)).length;s0)){if(r=-1,32==VJ(h.c,0)){if(f=s[0],win(t,s),s[0]>f)continue}else if(WZ(t,h.c,s[0])){s[0]+=h.c.length;continue}return 0}if(r<0&&h.a&&(r=u,c=s[0],i=0),r>=0){if(o=h.b,u==r&&0==(o-=i++))return 0;if(!rJn(t,s,h,o,a)){u=r-1,s[0]=c;continue}}else if(r=-1,!rJn(t,s,h,0,a))return 0}return LQn(a,e)?s[0]:0}function Qqn(n,t,e){var i,r,c,a,o,u,s,h,f,l;for(h=new Kz(new Fd(e)),zV(o=Inn(ZHt,B2n,28,n.f.e.c.length,16,1),o.length),e[t.a]=0,s=new Ww(n.f.e);s.a=0&&!eTn(n,h,f);)--f;r[h]=f}for(b=0;b=0&&!eTn(n,o,w);)--o;c[w]=o}for(u=0;ut[l]&&li[u]&&HBn(n,u,l,!1,!0)}function Yqn(n){var t,e,i,r,c,a,o,u;e=oM(gK(oIn(n,(cGn(),yft)))),c=n.a.c.d,o=n.a.d.d,e?(a=vD(YF(new MO(o.a,o.b),c),.5),u=vD(D$(n.e),.5),t=YF(JF(new MO(c.a,c.b),a),u),_R(n.d,t)):(r=uM(pK(oIn(n.a,Fft))),i=n.d,c.a>=o.a?c.b>=o.b?(i.a=o.a+(c.a-o.a)/2+r,i.b=o.b+(c.b-o.b)/2-r-n.e.b):(i.a=o.a+(c.a-o.a)/2+r,i.b=c.b+(o.b-c.b)/2+r):c.b>=o.b?(i.a=c.a+(o.a-c.a)/2+r,i.b=o.b+(c.b-o.b)/2+r):(i.a=c.a+(o.a-c.a)/2+r,i.b=c.b+(o.b-c.b)/2-r-n.e.b))}function Zqn(n){var t,e,i,r,c,a;if(!n.f){if(a=new Ms,c=new Ms,null==(t=V_t).a.zc(n,t)){for(r=new DD(n1(n));r.e!=r.i.gc();)CW(a,Zqn(uG(Zkn(r),29)));t.a.Bc(n),t.a.gc()}for(!n.s&&(n.s=new fV(o_t,n,21,17)),i=new DD(n.s);i.e!=i.i.gc();)F$(e=uG(Zkn(i),179),102)&&ttn(c,uG(e,19));lbn(c),n.r=new JG(n,(uG(zrn(gZ((tQ(),M_t).o),6),19),c.i),c.g),CW(a,n.r),lbn(a),n.f=new vL((uG(zrn(gZ(M_t.o),5),19),a.i),a.g),y9(n).b&=-3}return n.f}function nXn(n){hP(n,new hCn(FT(DT(KT(RT(new bu,$3n),"ELK DisCo"),"Layouter for arranging unconnected subgraphs. The subgraphs themselves are, by default, not laid out."),new ct))),U4(n,$3n,D3n,Jkn(ift)),U4(n,$3n,x3n,Jkn(Jht)),U4(n,$3n,R3n,Jkn(Xht)),U4(n,$3n,K3n,Jkn(Yht)),U4(n,$3n,D2n,Jkn(tft)),U4(n,$3n,x2n,Jkn(nft)),U4(n,$3n,$2n,Jkn(eft)),U4(n,$3n,R2n,Jkn(Zht)),U4(n,$3n,I3n,Jkn(Vht)),U4(n,$3n,O3n,Jkn(zht)),U4(n,$3n,A3n,Jkn(Wht)),U4(n,$3n,L3n,Jkn(Qht))}function tXn(){tXn=E,JKt=Uhn(cT(JHt,1),N1n,28,15,[48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70]),YKt=new RegExp("[ \t\n\r\f]+");try{QKt=Uhn(cT(iBt,1),EZn,2114,0,[new Km((wL(),Cmn("yyyy-MM-dd'T'HH:mm:ss'.'SSSZ",bF((qy(),qy(),Hat))))),new Km(Cmn("yyyy-MM-dd'T'HH:mm:ss'.'SSS",bF(Hat))),new Km(Cmn("yyyy-MM-dd'T'HH:mm:ss",bF(Hat))),new Km(Cmn("yyyy-MM-dd'T'HH:mm",bF(Hat))),new Km(Cmn("yyyy-MM-dd",bF(Hat)))])}catch(n){if(!F$(n=Ehn(n),82))throw hv(n)}}function eXn(n,t){var e,i,r;if(i=0!=uRn(n.d,1),0==rHn(n,t)&&oM(gK(oIn(t.j,(GYn(),Bpt)))))return 0;!oM(gK(oIn(t.j,(GYn(),Bpt))))&&!oM(gK(oIn(t.j,mmt)))||xA(oIn(t.j,(jYn(),Syt)))===xA((yvn(),Fjt))?t.c.mg(t.e,i):i=oM(gK(oIn(t.j,Bpt))),PKn(n,t,i,!0),oM(gK(oIn(t.j,mmt)))&&kfn(t.j,mmt,(qx(),!1)),oM(gK(oIn(t.j,Bpt)))&&(kfn(t.j,Bpt,(qx(),!1)),kfn(t.j,mmt,!0)),e=rHn(n,t);do{if(Gon(n),0==e)return 0;r=e,PKn(n,t,i=!i,!1),e=rHn(n,t)}while(r>e);return r}function iXn(n,t){var e,i,r;if(i=0!=uRn(n.d,1),0==BAn(n,t)&&oM(gK(oIn(t.j,(GYn(),Bpt)))))return 0;!oM(gK(oIn(t.j,(GYn(),Bpt))))&&!oM(gK(oIn(t.j,mmt)))||xA(oIn(t.j,(jYn(),Syt)))===xA((yvn(),Fjt))?t.c.mg(t.e,i):i=oM(gK(oIn(t.j,Bpt))),PKn(n,t,i,!0),oM(gK(oIn(t.j,mmt)))&&kfn(t.j,mmt,(qx(),!1)),oM(gK(oIn(t.j,Bpt)))&&(kfn(t.j,Bpt,(qx(),!1)),kfn(t.j,mmt,!0)),e=BAn(n,t);do{if(Gon(n),0==e)return 0;r=e,PKn(n,t,i=!i,!1),e=BAn(n,t)}while(r>e);return r}function rXn(n,t,i,r){var c,a,o,u,s,h,f,l,b;return h=(s=YF(new MO(i.a,i.b),n)).a*t.b-s.b*t.a,f=t.a*r.b-t.b*r.a,l=(s.a*r.b-s.b*r.a)/f,b=h/f,0==f?0==h?(a=atn(n,c=JF(new MO(i.a,i.b),vD(new MO(r.a,r.b),.5))),o=atn(JF(new MO(n.a,n.b),t),c),u=.5*e.Math.sqrt(r.a*r.a+r.b*r.b),a=0&&l<=1&&b>=0&&b<=1?JF(new MO(n.a,n.b),vD(new MO(t.a,t.b),l)):null}function cXn(n,t,e){var i,r,c,a,o;if(i=uG(oIn(n,(jYn(),Pyt)),21),e.a>t.a&&(i.Hc((ZSn(),VNt))?n.c.a+=(e.a-t.a)/2:i.Hc(QNt)&&(n.c.a+=e.a-t.a)),e.b>t.b&&(i.Hc((ZSn(),YNt))?n.c.b+=(e.b-t.b)/2:i.Hc(JNt)&&(n.c.b+=e.b-t.b)),uG(oIn(n,(GYn(),Hpt)),21).Hc((r_n(),tpt))&&(e.a>t.a||e.b>t.b))for(o=new Ww(n.a);o.at.a&&(i.Hc((ZSn(),VNt))?n.c.a+=(e.a-t.a)/2:i.Hc(QNt)&&(n.c.a+=e.a-t.a)),e.b>t.b&&(i.Hc((ZSn(),YNt))?n.c.b+=(e.b-t.b)/2:i.Hc(JNt)&&(n.c.b+=e.b-t.b)),uG(oIn(n,(GYn(),Hpt)),21).Hc((r_n(),tpt))&&(e.a>t.a||e.b>t.b))for(a=new Ww(n.a);a.a0?n.i:0)>t&&s>0&&(a=0,o+=s+n.i,c=e.Math.max(c,b),r+=s+n.i,s=0,b=0,i&&(++l,kD(n.n,new c0(n.s,o,n.i))),u=0),b+=h.g+(u>0?n.i:0),s=e.Math.max(s,h.f),i&&zMn(uG(zq(n.n,l),209),h),a+=h.g+(u>0?n.i:0),++u;return c=e.Math.max(c,b),r+=s,i&&(n.r=c,n.d=r,ijn(n.j)),new gY(n.s,n.t,c,r)}function sXn(n){var t,i,r,c,a,o,u,s,h,f,l;for(n.b=!1,f=M0n,u=T0n,l=M0n,s=T0n,i=n.e.a.ec().Kc();i.Ob();)for(r=(t=uG(i.Pb(),272)).a,f=e.Math.min(f,r.c),u=e.Math.max(u,r.c+r.b),l=e.Math.min(l,r.d),s=e.Math.max(s,r.d+r.a),a=new Ww(t.c);a.an.o.a&&(f=(s-n.o.a)/2,u.b=e.Math.max(u.b,f),u.c=e.Math.max(u.c,f))}}function wXn(n){var t,e,i,r,c,a;for(YL(r=new r4,(Whn(),YLt)),i=new Jw(new IM(new JE(n,Yon(n,Inn($ot,zZn,2,0,6,1))).b));i.bo?1:-1:Hln(n.a,t.a,c)))f=-u,h=a==u?t7(t.a,o,n.a,c):Cnn(t.a,o,n.a,c);else if(f=a,a==u){if(0==r)return cHn(),_ot;h=t7(n.a,c,t.a,o)}else h=Cnn(n.a,c,t.a,o);return K4(s=new VV(f,h.length,h)),s}function vXn(n,t){var e,i,r;if(r=PGn(t),!t.c&&(t.c=new fV(wFt,t,9,9)),kS(new fX(null,(!t.c&&(t.c=new fV(wFt,t,9,9)),new h3(t.c,16))),new Jd(r)),CWn(t,i=uG(oIn(r,(GYn(),Hpt)),21)),i.Hc((r_n(),tpt)))for(e=new DD((!t.c&&(t.c=new fV(wFt,t,9,9)),t.c));e.e!=e.i.gc();)pQn(n,t,r,uG(Zkn(e),123));return 0!=uG(zDn(t,(jYn(),DMt)),181).gc()&&u_n(t,r),oM(gK(oIn(r,HMt)))&&i.Fc(apt),vR(r,fTt)&&iM(new omn(uM(pK(oIn(r,fTt)))),r),xA(zDn(t,rMt))===xA((Own(),Ixt))?UYn(n,t,r):dYn(n,t,r),r}function kXn(n){var t,e,i,r,c,a,o;for(i=new Ww(n.b);i.a0?r1(e.a,0,c-1):"":(Knn(0,c-1,n.length),n.substr(0,c-1)):e?e.a:n}function MXn(n,t){var e,i,r,c,a,o,u;for(t.Ug("Sort By Input Model "+oIn(n,(jYn(),Syt)),1),r=0,i=new Ww(n.b);i.a=n.b.length?(c[r++]=a.b[i++],c[r++]=a.b[i++]):i>=a.b.length?(c[r++]=n.b[e++],c[r++]=n.b[e++]):a.b[i]0?n.i:0)),++t;for(dgn(n.n,s),n.d=i,n.r=r,n.g=0,n.f=0,n.e=0,n.o=M0n,n.p=M0n,a=new Ww(n.b);a.a0&&(!(r=(!n.n&&(n.n=new fV(lFt,n,1,7)),uG(zrn(n.n,0),135)).a)||JA(JA((t.a+=' "',t),r),'"'))),!n.b&&(n.b=new f_(cFt,n,4,7)),e=!(n.b.i<=1&&(!n.c&&(n.c=new f_(cFt,n,5,8)),n.c.i<=1)),t.a+=e?" [":" ",JA(t,KD(new FM,new DD(n.b))),e&&(t.a+="]"),t.a+=Y4n,e&&(t.a+="["),JA(t,KD(new FM,new DD(n.c))),e&&(t.a+="]"),t.a)}function PXn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E;for(k=n.c,y=t.c,e=Ten(k.a,n,0),i=Ten(y.a,t,0),m=uG(jmn(n,(can(),Vjt)).Kc().Pb(),12),j=uG(jmn(n,Wjt).Kc().Pb(),12),v=uG(jmn(t,Vjt).Kc().Pb(),12),E=uG(jmn(t,Wjt).Kc().Pb(),12),g=x4(m.e),M=x4(j.g),p=x4(v.e),T=x4(E.g),$jn(n,i,y),s=0,b=(c=p).length;sh?new A2((_7(),DSt),i,t,s-h):s>0&&h>0&&(new A2((_7(),DSt),t,i,0),new A2(DSt,i,t,0))),a)}function AXn(n,t,e){var i,r,c;for(n.a=new Zm,c=Fkn(t.b,0);c.b!=c.d.c;){for(r=uG(I6(c),40);uG(oIn(r,(QGn(),ACt)),17).a>n.a.c.length-1;)kD(n.a,new WO(B3n,G9n));i=uG(oIn(r,ACt),17).a,e==(xdn(),JDt)||e==YDt?(r.e.auM(pK(uG(zq(n.a,i),42).b))&&sw(uG(zq(n.a,i),42),r.e.a+r.f.a)):(r.e.buM(pK(uG(zq(n.a,i),42).b))&&sw(uG(zq(n.a,i),42),r.e.b+r.f.b))}}function LXn(n,t,e,i){var r,c,a,o,u,s;if(c=pgn(i),!oM(gK(oIn(i,(jYn(),jMt))))&&!oM(gK(oIn(n,uMt)))||sN(uG(oIn(n,JMt),101)))switch(o2(o=new lOn,n),t?((s=o.n).a=t.a-n.n.a,s.b=t.b-n.n.b,DOn(s,0,0,n.o.a,n.o.b),NLn(o,nGn(o,c))):(r=Ipn(c),NLn(o,e==(can(),Wjt)?r:Gdn(r))),a=uG(oIn(i,(GYn(),Hpt)),21),u=o.j,c.g){case 2:case 1:(u==(KQn(),yRt)||u==KRt)&&a.Fc((r_n(),cpt));break;case 4:case 3:(u==(KQn(),kRt)||u==_Rt)&&a.Fc((r_n(),cpt))}else r=Ipn(c),o=zUn(n,e,e==(can(),Wjt)?r:Gdn(r));return o}function NXn(n,t){var i,r,c,a,o;for(o=new bsn(new Nw(n.f.b).a);o.b;){if(c=uG((a=von(o)).ld(),602),1==t){if(c.Af()!=(xdn(),nxt)&&c.Af()!=QDt)continue}else if(c.Af()!=(xdn(),JDt)&&c.Af()!=YDt)continue;switch(r=uG(uG(a.md(),42).b,86),i=uG(uG(a.md(),42).a,194).c,c.Af().g){case 2:r.g.c=n.e.a,r.g.b=e.Math.max(1,r.g.b+i);break;case 1:r.g.c=r.g.c+i,r.g.b=e.Math.max(1,r.g.b-i);break;case 4:r.g.d=n.e.b,r.g.a=e.Math.max(1,r.g.a+i);break;case 3:r.g.d=r.g.d+i,r.g.a=e.Math.max(1,r.g.a-i)}}}function $Xn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g;for(u=Inn(YHt,W1n,28,t.b.c.length,15,1),h=Inn(vbt,p1n,273,t.b.c.length,0,1),s=Inn(pbt,e6n,10,t.b.c.length,0,1),b=0,w=(l=n.a).length;b0&&s[r]&&(d=y$(n.b,s[r],c)),g=e.Math.max(g,c.c.c.b+d);for(a=new Ww(f.e);a.a1)throw hv(new vM(dct));u||(c=R5(t,i.Kc().Pb()),a.Fc(c))}return bfn(n,sAn(n,t,e),a)}function BXn(n,t,e){var i,r,c,a,o,u,s;if(EFn(n.e,t))PP(),C$n((o=uG(t,69).xk()?new Cq(t,n):new OA(t,n)).c,o.b),K$(o,uG(e,16));else{for(s=VKn(n.e.Dh(),t),i=uG(n.g,124),c=0;c"}null!=u&&(t.a+=""+u)}else n.e?null!=(o=n.e.zb)&&(t.a+=""+o):(t.a+="?",n.b?(t.a+=" super ",XXn(n.b,t)):n.f&&(t.a+=" extends ",XXn(n.f,t)))}function zXn(n){n.b=null,n.a=null,n.o=null,n.q=null,n.v=null,n.w=null,n.B=null,n.p=null,n.Q=null,n.R=null,n.S=null,n.T=null,n.U=null,n.V=null,n.W=null,n.bb=null,n.eb=null,n.ab=null,n.H=null,n.db=null,n.c=null,n.d=null,n.f=null,n.n=null,n.r=null,n.s=null,n.u=null,n.G=null,n.J=null,n.e=null,n.j=null,n.i=null,n.g=null,n.k=null,n.t=null,n.F=null,n.I=null,n.L=null,n.M=null,n.O=null,n.P=null,n.$=null,n.N=null,n.Z=null,n.cb=null,n.K=null,n.D=null,n.A=null,n.C=null,n._=null,n.fb=null,n.X=null,n.Y=null,n.gb=!1,n.hb=!1}function VXn(n){var t,i,r,c;if(r=bYn((!n.c&&(n.c=j2(Bsn(n.f))),n.c),0),0==n.e||0==n.a&&-1!=n.f&&n.e<0)return r;if(t=nun(n)<0?1:0,i=n.e,r.length,e.Math.abs(t0(n.e)),c=new QM,1==t&&(c.a+="-"),n.e>0)if((i-=r.length-t)>=0){for(c.a+="0.";i>Pot.length;i-=Pot.length)Xq(c,Pot);lF(c,Pot,t0(i)),JA(c,(s3(t,r.length+1),r.substr(t)))}else JA(c,r1(r,t,t0(i=t-i))),c.a+=".",JA(c,sQ(r,t0(i)));else{for(JA(c,(s3(t,r.length+1),r.substr(t)));i<-Pot.length;i+=Pot.length)Xq(c,Pot);lF(c,Pot,t0(-i))}return c.a}function WXn(n){var t,e,i,r,c;if(n.k!=(zIn(),dbt))return!1;if(n.j.c.length<=1)return!1;if(uG(oIn(n,(jYn(),JMt)),101)==($Pn(),cRt))return!1;if(Yyn(),(i=(n.q?n.q:(hZ(),hZ(),Vot))._b(LMt)?uG(oIn(n,LMt),203):uG(oIn(HQ(n),NMt),203))==djt)return!1;if(i!=wjt&&i!=bjt){if(r=uM(pK(Omn(n,ITt))),!(t=uG(oIn(n,CTt),140))&&(t=new OF(r,r,r,r)),c=Dgn(n,(KQn(),_Rt)),t.d+t.a+(c.gc()-1)*r>n.o.b)return!1;if(e=Dgn(n,kRt),t.d+t.a+(e.gc()-1)*r>n.o.b)return!1}return!0}function QXn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d;t.Ug("Orthogonal edge routing",1),s=uM(pK(oIn(n,(jYn(),STt)))),e=uM(pK(oIn(n,gTt))),i=uM(pK(oIn(n,vTt))),l=new NW(0,e),d=0,a=new N4(n.b,0),o=null,h=null,u=null,f=null;do{f=(h=a.b0?(b=(w-1)*e,o&&(b+=i),h&&(b+=i),bt||oM(gK(zDn(o,(S_n(),nAt)))))&&(r=0,c+=s.b+e,mv(h.c,s),fan(s=new e4(c,e),i=new dln(0,s.f,s,e)),r=0),0==i.b.c.length||!oM(gK(zDn(R0(o),(S_n(),uAt))))&&(o.f>=i.o&&o.f<=i.f||.5*i.a<=o.f&&1.5*i.a>=o.f)?ipn(i,o):(fan(s,a=new dln(i.s+i.r+e,s.f,s,e)),ipn(a,o)),r=o.i+o.g;return mv(h.c,s),h}function szn(n){var t,e,i,r;if(!(null==n.b||n.b.length<=2||n.a)){for(t=0,r=0;r=n.b[r+1])r+=2;else{if(!(e0)for(i=new Z_(uG(Y9(n.a,c),21)),hZ(),f$(i,new Gd(t)),r=new N4(c.b,0);r.b0&&i>=-6?i>=0?Ex(c,e-t0(n.e),String.fromCharCode(46)):(psn(c,t-1,t-1,"0."),Ex(c,t+1,mvn(Pot,0,-t0(i)-1))):(e-t>=1&&(Ex(c,t,String.fromCharCode(46)),++e),Ex(c,e,String.fromCharCode(69)),i>0&&Ex(c,++e,String.fromCharCode(43)),Ex(c,++e,""+oV(Bsn(i)))),n.g=c.a,n.g))}function gzn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T;r=uM(pK(oIn(t,(jYn(),AMt)))),l=4,c=3,M=20/(y=uG(oIn(t,OTt),17).a),b=!1,s=0,o=vZn;do{for(a=1!=s,f=0!=s,T=0,m=0,k=(g=n.a).length;my)?(s=2,o=vZn):0==s?(s=1,o=T):(s=0,o=T):(b=T>=o||o-T0?1:KL(isNaN(r),isNaN(0)))>=0^(oan(I9n),(e.Math.abs(u)<=I9n||0==u||isNaN(u)&&isNaN(0)?0:u<0?-1:u>0?1:KL(isNaN(u),isNaN(0)))>=0)?e.Math.max(u,r):(oan(I9n),(e.Math.abs(r)<=I9n||0==r||isNaN(r)&&isNaN(0)?0:r<0?-1:r>0?1:KL(isNaN(r),isNaN(0)))>0?e.Math.sqrt(u*u+r*r):-e.Math.sqrt(u*u+r*r))}function kzn(n,t){var e,i,r,c,a;if(t)if(!n.a&&(n.a=new ck),2!=n.e)if(1!=t.e)0!=(a=n.a.a.c.length)?0!=(c=uG(DQ(n.a,a-1),122)).e&&10!=c.e||0!=t.e&&10!=t.e?zv(n.a,t):(0==t.e||t.Mm().length,0==c.e?(e=new VM,(i=c.Km())>=P0n?VA(e,Ogn(i)):TQ(e,i&D1n),c=new F1(10,null,0),GV(n.a,c,a-1)):(c.Mm().length,VA(e=new VM,c.Mm())),0==t.e?(i=t.Km())>=P0n?VA(e,Ogn(i)):TQ(e,i&D1n):VA(e,t.Mm()),uG(c,530).b=e.a):zv(n.a,t);else for(r=0;r1&&(u=s.Hg(u,n.a,o));return 1==u.c.length?uG(zq(u,u.c.length-1),238):2==u.c.length?ezn((u3(0,u.c.length),uG(u.c[0],238)),(u3(1,u.c.length),uG(u.c[1],238)),a,c):null}function Ezn(n,t,e){var i,r,c,a,o,u,s;for(e.Ug("Find roots",1),n.a.c.length=0,r=Fkn(t.b,0);r.b!=r.d.c;)0==(i=uG(I6(r),40)).b.b&&(kfn(i,(OQn(),UPt),(qx(),!0)),kD(n.a,i));switch(n.a.c.length){case 0:kfn(c=new wln(0,t,"DUMMY_ROOT"),(OQn(),UPt),(qx(),!0)),kfn(c,jPt,!0),aq(t.b,c);break;case 1:break;default:for(a=new wln(0,t,H9n),u=new Ww(n.a);u.a=e.Math.abs(r.b)?(r.b=0,a.d+a.a>o.d&&a.do.c&&a.c0){if(t=new AA(n.i,n.g),c=(e=n.i)<100?null:new cj(e),n.Tj())for(i=0;i0){for(o=n.g,s=n.i,V9(n),c=s<100?null:new cj(s),i=0;i>13|(15&n.m)<<9,r=n.m>>4&8191,c=n.m>>17|(255&n.h)<<5,a=(1048320&n.h)>>8,g=i*(o=8191&t.l),p=r*o,m=c*o,v=a*o,0!=(u=t.l>>13|(15&t.m)<<9)&&(g+=e*u,p+=i*u,m+=r*u,v+=c*u),0!=(s=t.m>>4&8191)&&(p+=e*s,m+=i*s,v+=r*s),0!=(h=t.m>>17|(255&t.h)<<5)&&(m+=e*h,v+=i*h),0!=(f=(1048320&t.h)>>8)&&(v+=e*f),b=((d=e*o)>>22)+(g>>9)+((262143&p)<<4)+((31&m)<<17),w=(p>>18)+(m>>5)+((4095&v)<<8),w+=(b+=(l=(d&f0n)+((511&g)<<13))>>22)>>22,p$(l&=f0n,b&=f0n,w&=l0n)}function Azn(n){var t,i,r,c,a,o,u;if(0!=(u=uG(zq(n.j,0),12)).g.c.length&&0!=u.e.c.length)throw hv(new kM("Interactive layout does not support NORTH/SOUTH ports with incoming _and_ outgoing edges."));if(0!=u.g.c.length){for(a=M0n,i=new Ww(u.g);i.a4){if(!n.fk(t))return!1;if(n.al()){if(o=(e=(i=uG(t,54)).Eh())==n.e&&(n.ml()?i.yh(i.Fh(),n.il())==n.jl():-1-i.Fh()==n.Lj()),n.nl()&&!o&&!e&&i.Jh())for(r=0;r0&&nAn(n,o,h);for(r=new Ww(h);r.an.d[r.p]&&(e+=J8(n.b,i)*uG(a.b,17).a,A6(n.a,xwn(i)));for(;!LM(n.a);)lin(n.b,uG(xV(n.a),17).a)}return e}function Dzn(n,t){var e,i,r,c,a,o,u,s,h,f;if(h=uG(oIn(n,(GYn(),Fpt)),64),i=uG(zq(n.j,0),12),h==(KQn(),yRt)?NLn(i,KRt):h==KRt&&NLn(i,yRt),uG(oIn(t,(jYn(),DMt)),181).Hc((Qmn(),JRt))){if(u=uM(pK(oIn(n,TTt))),s=uM(pK(oIn(n,jTt))),a=uM(pK(oIn(n,yTt))),(o=uG(oIn(t,nTt),21)).Hc((eNn(),wRt)))for(e=s,f=n.o.a/2-i.n.a,c=new Ww(i.f);c.a0&&(s=n.n.a/c);break;case 2:case 4:(r=n.i.o.b)>0&&(s=n.n.b/r)}kfn(n,(GYn(),bmt),s)}if(u=n.o,a=n.a,i)a.a=i.a,a.b=i.b,n.d=!0;else if(t!=uRt&&t!=sRt&&o!=FRt)switch(o.g){case 1:a.a=u.a/2;break;case 2:a.a=u.a,a.b=u.b/2;break;case 3:a.a=u.a/2,a.b=u.b;break;case 4:a.b=u.b/2}else a.a=u.a/2,a.b=u.b/2}function _zn(n){var t,e,i,r,c,a,o,u,s,h;if(n.Pj())if(h=n.Ej(),u=n.Qj(),h>0)if(t=new Hun(n.pj()),c=(e=h)<100?null:new cj(e),QK(n,e,t.g),r=1==e?n.Ij(4,zrn(t,0),null,0,u):n.Ij(6,t,null,-1,u),n.Mj()){for(i=new DD(t);i.e!=i.i.gc();)c=n.Oj(Zkn(i),c);c?(c.nj(r),c.oj()):n.Jj(r)}else c?(c.nj(r),c.oj()):n.Jj(r);else QK(n,n.Ej(),n.Fj()),n.Jj(n.Ij(6,(hZ(),zot),null,-1,u));else if(n.Mj())if((h=n.Ej())>0){for(o=n.Fj(),s=h,QK(n,h,o),c=s<100?null:new cj(s),i=0;i1&&EX(a)*jX(a)/2>o[0]){for(c=0;co[c];)++c;f=new Jrn(new C2(b,0,c+1)),h=EX(a)/jX(a),u=KJn(f,t,new Dk,e,i,r,h),JF(dL(f.e),u),kG(_Cn(l,f),D0n),_jn(l,new C2(b,c+1,b.c.length)),b.c.length=0,s=0,zX(o,o.length,0)}else null!=(0==l.b.c.length?null:zq(l.b,0))&&Con(l,0),s>0&&(o[s]=o[s-1]),o[s]+=EX(a)*jX(a),++s,mv(b.c,a);return b}function Hzn(n,t){var e,i,r,c;c=new Z_((e=t.b).j),r=0,(i=e.j).c.length=0,mW(uG(ssn(n.b,(KQn(),yRt),(gon(),Sdt)),15),e),r=cMn(c,r,new Br,i),mW(uG(ssn(n.b,yRt,Edt),15),e),r=cMn(c,r,new $r,i),mW(uG(ssn(n.b,yRt,jdt),15),e),mW(uG(ssn(n.b,kRt,Sdt),15),e),mW(uG(ssn(n.b,kRt,Edt),15),e),r=cMn(c,r,new Hr,i),mW(uG(ssn(n.b,kRt,jdt),15),e),mW(uG(ssn(n.b,KRt,Sdt),15),e),r=cMn(c,r,new Ur,i),mW(uG(ssn(n.b,KRt,Edt),15),e),r=cMn(c,r,new Gr,i),mW(uG(ssn(n.b,KRt,jdt),15),e),mW(uG(ssn(n.b,_Rt,Sdt),15),e),r=cMn(c,r,new Rr,i),mW(uG(ssn(n.b,_Rt,Edt),15),e),mW(uG(ssn(n.b,_Rt,jdt),15),e)}function Uzn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b;for(o=new Ww(t);o.a.5?p-=2*a*(w-.5):w<.5&&(p+=2*c*(.5-w)),p<(r=o.d.b)&&(p=r),d=o.d.c,p>g.a-d-h&&(p=g.a-d-h),o.n.a=t+p}}function Wzn(n){var t,e,i;if((e=uG(oIn(n,(jYn(),gMt)),171))==(Gpn(),Imt)){for(t=new Fz(ix(qgn(n).a.Kc(),new h));hDn(t);)if(!F9(uG(N9(t),18)))throw hv(new jM(y6n+ZTn(n)+"' has its layer constraint set to FIRST_SEPARATE, but has at least one incoming edge. FIRST_SEPARATE nodes must not have incoming edges."))}else if(e==Amt)for(i=new Fz(ix(Xgn(n).a.Kc(),new h));hDn(i);)if(!F9(uG(N9(i),18)))throw hv(new jM(y6n+ZTn(n)+"' has its layer constraint set to LAST_SEPARATE, but has at least one outgoing edge. LAST_SEPARATE nodes must not have outgoing edges."))}function Qzn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w;if(n.e&&n.c.c>19&&(t=gfn(t),u=!u),a=kRn(t),c=!1,r=!1,i=!1,n.h==b0n&&0==n.m&&0==n.l){if(r=!0,c=!0,-1!=a)return o=gDn(n,a),u&&Yfn(o),e&&(Qat=p$(0,0,0)),o;n=LL((tin(),Jat)),i=!0,u=!u}else n.h>>19&&(c=!0,n=gfn(n),i=!0,u=!u);return-1!=a?nln(n,a,u,c,e):yEn(n,t)<0?(e&&(Qat=c?gfn(n):p$(n.l,n.m,n.h)),p$(0,0,0)):pUn(i?n:p$(n.l,n.m,n.h),t,u,c,r,e)}function Zzn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w;if(a=n.e,u=t.e,0==a)return t;if(0==u)return n;if((c=n.d)+(o=t.d)==2)return e=E3(n.a[0],L0n),i=E3(t.a[0],L0n),a==u?(w=pz(h=Lgn(e,i)),0==(b=pz(Dz(h,32)))?new Z5(a,w):new VV(a,2,Uhn(cT(YHt,1),W1n,28,15,[w,b]))):(cHn(),BA(a<0?$gn(i,e):$gn(e,i),0)?Rmn(a<0?$gn(i,e):$gn(e,i)):hW(Rmn(Men(a<0?$gn(i,e):$gn(e,i)))));if(a==u)l=a,f=c>=o?Cnn(n.a,c,t.a,o):Cnn(t.a,o,n.a,c);else{if(0==(r=c!=o?c>o?1:-1:Hln(n.a,t.a,c)))return cHn(),_ot;1==r?(l=a,f=t7(n.a,c,t.a,o)):(l=u,f=t7(t.a,o,n.a,c))}return K4(s=new VV(l,f.length,f)),s}function nVn(n,t){var e,i,r,c,a,o,u;if(!(n.g>t.f||t.g>n.f)){for(e=0,i=0,a=n.w.a.ec().Kc();a.Ob();)r=uG(a.Pb(),12),Wbn(Gfn(Uhn(cT(PNt,1),zZn,8,0,[r.i.n,r.n,r.a])).b,t.g,t.f)&&++e;for(o=n.r.a.ec().Kc();o.Ob();)r=uG(o.Pb(),12),Wbn(Gfn(Uhn(cT(PNt,1),zZn,8,0,[r.i.n,r.n,r.a])).b,t.g,t.f)&&--e;for(u=t.w.a.ec().Kc();u.Ob();)r=uG(u.Pb(),12),Wbn(Gfn(Uhn(cT(PNt,1),zZn,8,0,[r.i.n,r.n,r.a])).b,n.g,n.f)&&++i;for(c=t.r.a.ec().Kc();c.Ob();)r=uG(c.Pb(),12),Wbn(Gfn(Uhn(cT(PNt,1),zZn,8,0,[r.i.n,r.n,r.a])).b,n.g,n.f)&&--i;e=0)return e;switch(sJ(Nen(n,e))){case 2:if(m_("",tdn(n,e.qk()).xe())){if(u=hxn(n,t,o=HJ(Nen(n,e)),BJ(Nen(n,e))))return u;for(a=0,s=(r=AHn(n,t)).gc();a1)throw hv(new vM(dct));for(h=VKn(n.e.Dh(),t),i=uG(n.g,124),a=0;a1,h=new w7(b.b);l$(h.a)||l$(h.b);)l=(s=uG(l$(h.a)?N3(h.a):N3(h.b),18)).c==b?s.d:s.c,e.Math.abs(Gfn(Uhn(cT(PNt,1),zZn,8,0,[l.i.n,l.n,l.a])).b-o.b)>1&&sFn(n,s,o,a,b)}}function oVn(n){var t,i,r,c,a,o;if(c=new N4(n.e,0),r=new N4(n.a,0),n.d)for(i=0;i$9n;){for(a=t,o=0;e.Math.abs(t-a)<$9n;)++o,t=uM((MK(c.b0),c.a.Xb(c.c=--c.b),zGn(n,n.b-o,a,r,c),MK(c.b0),r.a.Xb(r.c=--r.b)}if(!n.d)for(i=0;i0?(n.f[s.p]=l/(s.e.c.length+s.g.c.length),n.c=e.Math.min(n.c,n.f[s.p]),n.b=e.Math.max(n.b,n.f[s.p])):o&&(n.f[s.p]=l)}}function hVn(n){n.b=null,n.bb=null,n.fb=null,n.qb=null,n.a=null,n.c=null,n.d=null,n.e=null,n.f=null,n.n=null,n.M=null,n.L=null,n.Q=null,n.R=null,n.K=null,n.db=null,n.eb=null,n.g=null,n.i=null,n.j=null,n.k=null,n.gb=null,n.o=null,n.p=null,n.q=null,n.r=null,n.$=null,n.ib=null,n.S=null,n.T=null,n.t=null,n.s=null,n.u=null,n.v=null,n.w=null,n.B=null,n.A=null,n.C=null,n.D=null,n.F=null,n.G=null,n.H=null,n.I=null,n.J=null,n.P=null,n.Z=null,n.U=null,n.V=null,n.W=null,n.X=null,n.Y=null,n._=null,n.ab=null,n.cb=null,n.hb=null,n.nb=null,n.lb=null,n.mb=null,n.ob=null,n.pb=null,n.jb=null,n.kb=null,n.N=!1,n.O=!1}function fVn(n,t,e){var i,r;for(e.Ug("Graph transformation ("+n.a+")",1),r=T3(t.a),i=new Ww(t.b);i.a=o.b.c)&&(o.b=t),(!o.c||t.c<=o.c.c)&&(o.d=o.c,o.c=t),(!o.e||t.d>=o.e.d)&&(o.e=t),(!o.f||t.d<=o.f.d)&&(o.f=t);return i=new cyn((Xhn(),Flt)),O4(n,Vlt,new IM(Uhn(cT(Klt,1),EZn,382,0,[i]))),a=new cyn(Hlt),O4(n,zlt,new IM(Uhn(cT(Klt,1),EZn,382,0,[a]))),r=new cyn(_lt),O4(n,Xlt,new IM(Uhn(cT(Klt,1),EZn,382,0,[r]))),c=new cyn(Blt),O4(n,qlt,new IM(Uhn(cT(Klt,1),EZn,382,0,[c]))),jRn(i.c,Flt),jRn(r.c,_lt),jRn(c.c,Blt),jRn(a.c,Hlt),o.a.c.length=0,Ohn(o.a,i.c),Ohn(o.a,Spn(r.c)),Ohn(o.a,c.c),Ohn(o.a,Spn(a.c)),o}function wVn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d;for(t.Ug(snt,1),w=uM(pK(zDn(n,(lBn(),POt)))),o=uM(pK(zDn(n,(S_n(),bAt)))),u=uG(zDn(n,hAt),107),Non((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a)),f=uzn((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a),w,o),!n.a&&(n.a=new fV(bFt,n,10,11)),h=new Ww(f);h.a0&&(n.a=o+(l-1)*r,t.c.b+=n.a,t.f.b+=n.a),0!=b.a.gc()&&(l=YVn(new NW(1,r),t,b,w,t.f.b+o-t.c.b))>0&&(t.f.b+=o+(l-1)*r)}function gVn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y;for(f=uM(pK(oIn(n,(jYn(),mTt)))),r=uM(pK(oIn(n,RTt))),kfn(b=new Qu,mTt,f+r),m=(h=t).d,g=h.c.i,v=h.d.i,p=GL(g.c),k=GL(v.c),c=new Zm,l=p;l<=k;l++)Hb(u=new gMn(n),(zIn(),wbt)),kfn(u,(GYn(),rmt),h),kfn(u,JMt,($Pn(),cRt)),kfn(u,kTt,b),w=uG(zq(n.b,l),30),l==p?$jn(u,w.a.c.length-i,w):a2(u,w),(y=uM(pK(oIn(h,tMt))))<0&&kfn(h,tMt,y=0),u.o.b=y,d=e.Math.floor(y/2),NLn(o=new lOn,(KQn(),_Rt)),o2(o,u),o.n.b=d,NLn(s=new lOn,kRt),o2(s,u),s.n.b=d,u2(h,o),zsn(a=new UZ,h),kfn(a,bMt,null),c2(a,s),u2(a,m),IEn(u,h,a),mv(c.c,a),h=a;return c}function pVn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g;for(o=uG(yOn(n,(KQn(),_Rt)).Kc().Pb(),12).e,f=uG(yOn(n,kRt).Kc().Pb(),12).g,a=o.c.length,g=n3(uG(zq(n.j,0),12));a-- >0;){for(u3(0,o.c.length),b=uG(o.c[0],18),u3(0,f.c.length),r=Ten((i=uG(f.c[0],18)).d.e,i,0),w6(b,i.d,r),c2(i,null),u2(i,null),l=b.a,t&&aq(l,new eN(g)),e=Fkn(i.a,0);e.b!=e.d.c;)aq(l,new eN(uG(I6(e),8)));for(d=b.b,h=new Ww(i.b);h.aa)&&FV(n.b,uG(g.b,18));++o}c=a}}}function vVn(n,t){var e;if(null==t||m_(t,IZn))return null;if(0==t.length&&n.k!=(lAn(),pNt))return null;switch(n.k.g){case 1:return Bvn(t,Fnt)?(qx(),eot):Bvn(t,_nt)?(qx(),tot):null;case 2:try{return xwn(vUn(t,j1n,vZn))}catch(i){if(F$(i=Ehn(i),130))return null;throw hv(i)}case 4:try{return YIn(t)}catch(i){if(F$(i=Ehn(i),130))return null;throw hv(i)}case 3:return t;case 5:return wbn(n),NNn(n,t);case 6:return wbn(n),Lxn(n,n.a,t);case 7:try{return(e=Q$n(n)).cg(t),e}catch(i){if(F$(i=Ehn(i),33))return null;throw hv(i)}default:throw hv(new kM("Invalid type set for this layout option."))}}function kVn(n){var t;switch(n.d){case 1:if(n.Sj())return-2!=n.o;break;case 2:if(n.Sj())return-2==n.o;break;case 3:case 5:case 4:case 6:case 7:return n.o>-2;default:return!1}switch(t=n.Rj(),n.p){case 0:return null!=t&&oM(gK(t))!=HA(n.k,0);case 1:return null!=t&&uG(t,222).a!=pz(n.k)<<24>>24;case 2:return null!=t&&uG(t,180).a!=(pz(n.k)&D1n);case 6:return null!=t&&HA(uG(t,168).a,n.k);case 5:return null!=t&&uG(t,17).a!=pz(n.k);case 7:return null!=t&&uG(t,191).a!=pz(n.k)<<16>>16;case 3:return null!=t&&uM(pK(t))!=n.j;case 4:return null!=t&&uG(t,161).a!=n.j;default:return null==t?null!=n.n:!udn(t,n.n)}}function yVn(n,t,e){var i,r,c,a;return n.ol()&&n.nl()&&xA(a=CV(n,uG(e,58)))!==xA(e)?(n.xj(t),n.Dj(t,Atn(n,t,a)),n.al()&&(r=uG(e,54),c=n.ml()?n.kl()?r.Th(n.b,lMn(uG(ern(e1(n.b),n.Lj()),19)).n,uG(ern(e1(n.b),n.Lj()).Hk(),29).kk(),null):r.Th(n.b,emn(r.Dh(),lMn(uG(ern(e1(n.b),n.Lj()),19))),null,null):r.Th(n.b,-1-n.Lj(),null,null),!uG(a,54).Ph()&&(i=uG(a,54),c=n.ml()?n.kl()?i.Rh(n.b,lMn(uG(ern(e1(n.b),n.Lj()),19)).n,uG(ern(e1(n.b),n.Lj()).Hk(),29).kk(),c):i.Rh(n.b,emn(i.Dh(),lMn(uG(ern(e1(n.b),n.Lj()),19))),null,c):i.Rh(n.b,-1-n.Lj(),null,c)),c&&c.oj()),uN(n.b)&&n.Jj(n.Ij(9,e,a,t,!1)),a):e}function MVn(n){var t,e,i,r,c,a,o,u,s,h;for(i=new Zm,a=new Ww(n.e.a);a.a0&&(o=e.Math.max(o,run(n.C.b+r.d.b,c))),f=r,l=c,b=a;n.C&&n.C.c>0&&(w=b+n.C.c,h&&(w+=f.d.c),o=e.Math.max(o,(YN(),oan(Z2n),e.Math.abs(l-1)<=Z2n||1==l||isNaN(l)&&isNaN(1)?0:w/(1-l)))),i.n.b=0,i.a.a=o}function jVn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w;if(i=uG(AJ(n.b,t),127),(s=uG(uG(Y9(n.r,t),21),87)).dc())return i.n.d=0,void(i.n.a=0);for(h=n.u.Hc((eNn(),wRt)),o=0,n.A.Hc((Qmn(),JRt))&&kBn(n,t),u=s.Kc(),f=null,b=0,l=0;u.Ob();)a=uM(pK((r=uG(u.Pb(),117)).b.of((Gx(),bht)))),c=r.b.Mf().b,f?(w=l+f.d.a+n.w+r.d.d,o=e.Math.max(o,(YN(),oan(Z2n),e.Math.abs(b-a)<=Z2n||b==a||isNaN(b)&&isNaN(a)?0:w/(a-b)))):n.C&&n.C.d>0&&(o=e.Math.max(o,run(n.C.d+r.d.d,a))),f=r,b=a,l=c;n.C&&n.C.a>0&&(w=l+n.C.a,h&&(w+=f.d.a),o=e.Math.max(o,(YN(),oan(Z2n),e.Math.abs(b-1)<=Z2n||1==b||isNaN(b)&&isNaN(1)?0:w/(1-b)))),i.n.d=0,i.a.b=o}function EVn(n,t,e,i,r,c,a,o){var u,s,h,f,l,b,w,d;if(b=!1,u=cKn(e.q,t.f+t.b-e.q.f),l=i.f>t.b&&o,h=uXn(i,d=r-(e.q.e+u-a),!1).a,l&&h>i.f)return!1;if(l){for(f=0,w=new Ww(t.d);w.a=(u3(c,n.c.length),uG(n.c[c],186)).e,!(!l&&h>t.b&&!s)&&((s||l||h<=t.b)&&(s&&h>t.b?(e.d=h,dtn(e,EOn(e,h))):(USn(e.q,u),e.c=!0),dtn(i,r-(e.s+e.r)),oMn(i,e.q.e+e.q.d,t.f),fan(t,i),n.c.length>c&&(uEn((u3(c,n.c.length),uG(n.c[c],186)),i),0==(u3(c,n.c.length),uG(n.c[c],186)).a.c.length&&i7(n,c)),b=!0),b))}function SVn(n,t,e){var i,r,c,a,o,u;for(this.g=n,o=t.d.length,u=e.d.length,this.d=Inn(pbt,e6n,10,o+u,0,1),a=0;a0?Rrn(this,this.f/this.a):null!=oD(t.g,t.d[0]).a&&null!=oD(e.g,e.d[0]).a?Rrn(this,(uM(oD(t.g,t.d[0]).a)+uM(oD(e.g,e.d[0]).a))/2):null!=oD(t.g,t.d[0]).a?Rrn(this,oD(t.g,t.d[0]).a):null!=oD(e.g,e.d[0]).a&&Rrn(this,oD(e.g,e.d[0]).a)}function PVn(n,t){var e,i,r,c,a,o,u,s,h;for(n.a=new wQ(efn(axt)),i=new Ww(t.a);i.a=1&&(g-a>0&&f>=0?(u.n.a+=d,u.n.b+=c*a):g-a<0&&h>=0&&(u.n.a+=d*g,u.n.b+=c));n.o.a=t.a,n.o.b=t.b,kfn(n,(jYn(),DMt),(Qmn(),new nB(i=uG(Mj(sKt),9),uG(MF(i,i.length),9),0)))}function LVn(n,t,e,i,r,c){if(null!=t&&mpn(t,YFt,ZFt))throw hv(new vM("invalid scheme: "+t));if(!(n||null!=e&&-1==xL(e,$Cn(35))&&e.length>0&&(s3(0,e.length),47!=e.charCodeAt(0))))throw hv(new vM("invalid opaquePart: "+e));if(n&&(null==t||!ZE(UFt,t.toLowerCase()))&&null!=e&&mpn(e,n_t,t_t))throw hv(new vM(Vit+e));if(n&&null!=t&&ZE(UFt,t.toLowerCase())&&!bPn(e))throw hv(new vM(Vit+e));if(!Ppn(i))throw hv(new vM("invalid device: "+i));if(!Jbn(r))throw hv(new vM(null==r?"invalid segments: null":"invalid segment: "+Lbn(r)));if(null!=c&&-1!=xL(c,$Cn(35)))throw hv(new vM("invalid query: "+c))}function NVn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p;if(i.Ug("Network simplex layering",1),n.b=t,p=4*uG(oIn(t,(jYn(),OTt)),17).a,(g=n.b.a).c.length<1)i.Vg();else{for(d=null,c=Fkn(a=RHn(n,g),0);c.b!=c.d.c;){for(r=uG(I6(c),15),u=p*t0(e.Math.sqrt(r.gc())),YHn(kT(MT(yT(_B(o=dUn(r)),u),d),!0),i.eh(1)),l=n.b.b,w=new Ww(o.a);w.a1)for(d=Inn(YHt,W1n,28,n.b.b.c.length,15,1),f=0,h=new Ww(n.b.b);h.a0?(Ikn(n,e,0),e.a+=String.fromCharCode(i),Ikn(n,e,r=qvn(t,c)),c+=r-1):39==i?c+10&&w.a<=0){u.c.length=0,mv(u.c,w);break}(b=w.i-w.d)>=o&&(b>o&&(u.c.length=0,o=b),mv(u.c,w))}0!=u.c.length&&(a=uG(zq(u,iMn(r,u.c.length)),118),v.a.Bc(a),a.g=h++,UGn(a,t,e,i),u.c.length=0)}for(g=n.c.length+1,l=new Ww(n);l.aT0n||t.o==wSt&&s=o&&r<=u)o<=r&&c<=u?(e[h++]=r,e[h++]=c,i+=2):o<=r?(e[h++]=r,e[h++]=u,n.b[i]=u+1,a+=2):c<=u?(e[h++]=o,e[h++]=c,i+=2):(e[h++]=o,e[h++]=u,n.b[i]=u+1);else{if(!(uT1n)&&u<10);ET(n.c,new yt),_Vn(n),YV(n.c),lVn(n.f)}function XVn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g;for(i=uG(oIn(n,(jYn(),JMt)),101),o=n.f,a=n.d,u=o.a+a.b+a.c,s=0-a.d-n.c.b,f=o.b+a.d+a.a-n.c.b,h=new Zm,l=new Zm,c=new Ww(t);c.a=2){for(a=uG(I6(u=Fkn(e,0)),8),o=uG(I6(u),8);o.a0&&hfn(u,!0,(xdn(),YDt)),a.k==(zIn(),lbt)&&XQ(u),vJ(n.f,a,t)):((s=(i=uG(pZ(Ggn(a)),18)).c.i)==a&&(s=i.d.i),f=new WO(s,YF(D$(a.n),s.n)),vJ(n.b,a,f))}function WVn(n){var t,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v;for(i=uG(oIn(n,(OQn(),RPt)),27),u=vZn,s=vZn,a=j1n,o=j1n,m=Fkn(n.b,0);m.b!=m.d.c;)l=(g=uG(I6(m),40)).e,b=g.f,u=e.Math.min(u,l.a-b.a/2),s=e.Math.min(s,l.b-b.b/2),a=e.Math.max(a,l.a+b.a/2),o=e.Math.max(o,l.b+b.b/2);for(f=uG(zDn(i,(QGn(),pCt)),107),p=Fkn(n.b,0);p.b!=p.d.c;)F$(h=oIn(g=uG(I6(p),40),RPt),207)&&(kN(r=uG(h,27),g.e.a,g.e.b),aKn(r,g));for(d=Fkn(n.a,0);d.b!=d.d.c;)w=uG(I6(d),65),(t=uG(oIn(w,RPt),74))&&sqn(w.a,JFn(t,!0,!0));v=a-u+(f.b+f.c),c=o-s+(f.d+f.a),oM(gK(zDn(i,(XYn(),H$t))))||ZQn(i,v,c,!1,!1),Myn(i,h$t,v-(f.b+f.c)),Myn(i,s$t,c-(f.d+f.a))}function QVn(n,t){var e,i,r,c,a,o,u,s,f;for(o=!0,r=0,u=n.g[t.p],s=t.o.b+n.o,e=n.d[t.p][2],Y8(n.b,u,xwn(uG(zq(n.b,u),17).a-1+e)),Y8(n.c,u,uM(pK(zq(n.c,u)))-s+e*n.f),++u>=n.j?(++n.j,kD(n.b,xwn(1)),kD(n.c,s)):(i=n.d[t.p][1],Y8(n.b,u,xwn(uG(zq(n.b,u),17).a+1-i)),Y8(n.c,u,uM(pK(zq(n.c,u)))+s-i*n.f)),(n.r==(THn(),Ijt)&&(uG(zq(n.b,u),17).a>n.k||uG(zq(n.b,u-1),17).a>n.k)||n.r==Ljt&&(uM(pK(zq(n.c,u)))>n.n||uM(pK(zq(n.c,u-1)))>n.n))&&(o=!1),c=new Fz(ix(qgn(t).a.Kc(),new h));hDn(c);)a=uG(N9(c),18).c.i,n.g[a.p]==u&&(r+=uG((f=QVn(n,a)).a,17).a,o=o&&oM(gK(f.b)));return n.g[t.p]=u,new WO(xwn(r+=n.d[t.p][0]),(qx(),!!o))}function JVn(n,t){var e,i;uM(pK(oIn(t,(jYn(),dTt))))<2&&kfn(t,dTt,2),uG(oIn(t,Byt),88)==(xdn(),ZDt)&&kfn(t,Byt,pgn(t)),0==(e=uG(oIn(t,sTt),17)).a?kfn(t,(GYn(),dmt),new Upn):kfn(t,(GYn(),dmt),new v8(e.a)),null==gK(oIn(t,OMt))&&kfn(t,OMt,(qx(),xA(oIn(t,Vyt))===xA((_gn(),uxt)))),kS(new fX(null,new h3(t.a,16)),new Hd(n)),kS(sin(new fX(null,new h3(t.b,16)),new dt),new Ud(n)),i=new CVn(t),kfn(t,(GYn(),kmt),i),_J(n.a),JV(n.a,(uIn(),Tlt),uG(oIn(t,Fyt),188)),JV(n.a,jlt,uG(oIn(t,MMt),188)),JV(n.a,Elt,uG(oIn(t,Kyt),188)),JV(n.a,Slt,uG(oIn(t,$Mt),188)),JV(n.a,Plt,Rsn(uG(oIn(t,Vyt),223))),ZL(n.a,iYn(t)),kfn(t,wmt,Qzn(n.a,t))}function YVn(n,t,i,r,c){var a,o,u,s,h,f,l,b,w,d,g,p,m;for(l=new Ym,o=new Zm,HAn(n,i,n.d.Ag(),o,l),HAn(n,r,n.d.Bg(),o,l),n.b=.2*(g=DDn(sin(new fX(null,new h3(o,16)),new pa)),p=DDn(sin(new fX(null,new h3(o,16)),new ma)),e.Math.min(g,p)),a=0,u=0;u=2&&(m=sRn(o,!0,b),!n.e&&(n.e=new pp(n)),xvn(n.e,m,o,n.b)),BPn(o,b),oWn(o),w=-1,f=new Ww(o);f.ao)}function tWn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v;for(h=M0n,f=M0n,u=T0n,s=T0n,b=new Ww(t.i);b.a-1){for(r=Fkn(o,0);r.b!=r.d.c;)(i=uG(I6(r),131)).v=a;for(;0!=o.b;)for(t=new Ww((i=uG(Kjn(o,0),131)).i);t.a-1){for(c=new Ww(o);c.a0||(Yb(u,e.Math.min(u.o,r.o-1)),Jb(u,u.i-1),0==u.i&&mv(o.c,u))}}function uWn(n,t,i,r,c){var a,o,u,s;return s=M0n,o=!1,a=!!(u=rXn(n,YF(new MO(t.a,t.b),n),JF(new MO(i.a,i.b),c),YF(new MO(r.a,r.b),i)))&&!(e.Math.abs(u.a-n.a)<=Hnt&&e.Math.abs(u.b-n.b)<=Hnt||e.Math.abs(u.a-t.a)<=Hnt&&e.Math.abs(u.b-t.b)<=Hnt),(u=rXn(n,YF(new MO(t.a,t.b),n),i,c))&&((e.Math.abs(u.a-n.a)<=Hnt&&e.Math.abs(u.b-n.b)<=Hnt)==(e.Math.abs(u.a-t.a)<=Hnt&&e.Math.abs(u.b-t.b)<=Hnt)||a?s=e.Math.min(s,NQ(YF(u,i))):o=!0),(u=rXn(n,YF(new MO(t.a,t.b),n),r,c))&&(o||(e.Math.abs(u.a-n.a)<=Hnt&&e.Math.abs(u.b-n.b)<=Hnt)==(e.Math.abs(u.a-t.a)<=Hnt&&e.Math.abs(u.b-t.b)<=Hnt)||a)&&(s=e.Math.min(s,NQ(YF(u,r)))),s}function sWn(n){hP(n,new hCn(xT(FT(DT(KT(RT(new bu,$4n),D4n),"Minimizes the stress within a layout using stress majorization. Stress exists if the euclidean distance between a pair of nodes doesn't match their graph theoretic distance, that is, the shortest path between the two nodes. The method allows to specify individual edge lengths."),new gt),c4n))),U4(n,$4n,f4n,Jkn(olt)),U4(n,$4n,b4n,(qx(),!0)),U4(n,$4n,p4n,Jkn(hlt)),U4(n,$4n,x4n,Jkn(flt)),U4(n,$4n,g4n,Jkn(llt)),U4(n,$4n,m4n,Jkn(slt)),U4(n,$4n,w4n,Jkn(blt)),U4(n,$4n,v4n,Jkn(wlt)),U4(n,$4n,I4n,Jkn(alt)),U4(n,$4n,A4n,Jkn(rlt)),U4(n,$4n,L4n,Jkn(clt)),U4(n,$4n,N4n,Jkn(ult)),U4(n,$4n,O4n,Jkn(ilt))}function hWn(n){var t,e,i,r,c,a,o,u;for(t=null,i=new Ww(n);i.a0&&0==e.c&&(!t&&(t=new Zm),mv(t.c,e));if(t)for(;0!=t.c.length;){if((e=uG(i7(t,0),239)).b&&e.b.c.length>0)for(!e.b&&(e.b=new Zm),c=new Ww(e.b);c.aTen(n,e,0))return new WO(r,e)}else if(uM(oD(r.g,r.d[0]).a)>uM(oD(e.g,e.d[0]).a))return new WO(r,e);for(o=(!e.e&&(e.e=new Zm),e.e).Kc();o.Ob();)!(a=uG(o.Pb(),239)).b&&(a.b=new Zm),o3(0,(u=a.b).c.length),pC(u.c,0,e),a.c==u.c.length&&mv(t.c,a)}return null}function fWn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g;for(t.Ug("Interactive crossing minimization",1),a=0,c=new Ww(n.b);c.a0&&(e+=u.n.a+u.o.a/2,++f),b=new Ww(u.j);b.a0&&(e/=f),g=Inn(eUt,I0n,28,i.a.c.length,15,1),o=0,s=new Ww(i.a);s.a=o&&r<=u)o<=r&&c<=u?i+=2:o<=r?(n.b[i]=u+1,a+=2):c<=u?(e[h++]=r,e[h++]=o-1,i+=2):(e[h++]=r,e[h++]=o-1,n.b[i]=u+1,a+=2);else{if(!(u2?(Ohn(s=new Zm,new C2(w,1,w.b)),zsn(d=new pDn(vYn(s,g+n.a)),t),mv(i.c,d)):d=uG(cQ(n.b,r?bIn(t):gIn(t)),272),o=bIn(t),r&&(o=gIn(t)),a=GOn(b,o),u=g+n.a,a.a?(u+=e.Math.abs(b.b-h.b),l=new MO(h.a,(h.b+b.b)/2)):(u+=e.Math.abs(b.a-h.a),l=new MO((h.a+b.a)/2,h.b)),vJ(r?n.d:n.c,t,new bTn(d,a,l,u)),vJ(n.b,t,d),!t.n&&(t.n=new fV(lFt,t,1,7)),f=new DD(t.n);f.e!=f.i.gc();)c=nHn(n,uG(Zkn(f),135),!0,0,0),mv(i.c,c)}function wWn(n){var t,e,i,r,c,a,o;if(!n.A.dc()){if(n.A.Hc((Qmn(),QRt))&&(uG(AJ(n.b,(KQn(),yRt)),127).k=!0,uG(AJ(n.b,KRt),127).k=!0,t=n.q!=($Pn(),aRt)&&n.q!=cRt,Db(uG(AJ(n.b,kRt),127),t),Db(uG(AJ(n.b,_Rt),127),t),Db(n.g,t),n.A.Hc(JRt)&&(uG(AJ(n.b,yRt),127).j=!0,uG(AJ(n.b,KRt),127).j=!0,uG(AJ(n.b,kRt),127).k=!0,uG(AJ(n.b,_Rt),127).k=!0,n.g.k=!0)),n.A.Hc(WRt))for(n.a.j=!0,n.a.k=!0,n.g.j=!0,n.g.k=!0,o=n.B.Hc((oUn(),cKt)),c=0,a=(r=Nkn()).length;c0),c=uG(s.a.Xb(s.c=--s.b),18);c!=i&&s.b>0;)n.a[c.p]=!0,n.a[i.p]=!0,MK(s.b>0),c=uG(s.a.Xb(s.c=--s.b),18);s.b>0&&LQ(s)}}function pWn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b;if(!n.b)return!1;for(a=null,l=null,r=1,(u=new _nn(null,null)).a[1]=n.b,f=u;f.a[r];)s=r,o=l,l=f,f=f.a[r],r=(i=n.a.Ne(t,f.d))<0?0:1,0==i&&(!e.c||OJ(f.e,e.d))&&(a=f),f&&f.b||NM(f.a[r])||(NM(f.a[1-r])?l=l.a[s]=Ton(f,r):NM(f.a[1-r])||(b=l.a[1-s])&&(NM(b.a[1-s])||NM(b.a[s])?(c=o.a[1]==l?1:0,NM(b.a[s])?o.a[c]=P4(l,s):NM(b.a[1-s])&&(o.a[c]=Ton(l,s)),f.b=o.a[c].b=!0,o.a[c].a[0].b=!1,o.a[c].a[1].b=!1):(l.b=!1,b.b=!0,f.b=!0)));return a&&(e.b=!0,e.d=a.e,f!=a&&(YCn(n,u,a,h=new _nn(f.d,f.e)),l==a&&(l=h)),l.a[l.a[1]==f?1:0]=f.a[f.a[0]?0:1],--n.c),n.b=u.a[1],n.b&&(n.b.b=!1),e.b}function mWn(n){var t,i,r,c,a,o,u,s,h,f,l,b;for(c=new Ww(n.a.a.b);c.a0?r-=864e5:r+=864e5,u=new DK(Lgn(Bsn(t.q.getTime()),r))),h=new QM,s=n.a.length,c=0;c=97&&i<=122||i>=65&&i<=90){for(a=c+1;a=s)throw hv(new vM("Missing trailing '"));a+1=14&&o<=16?F$(i,183)?o7(e,PLn(uG(i,183))):F$(i,195)?o7(e,xPn(uG(i,195))):F$(i,201)?o7(e,aOn(uG(i,201))):F$(i,2111)?o7(e,RPn(uG(i,2111))):F$(i,53)?o7(e,SLn(uG(i,53))):F$(i,376)?o7(e,aNn(uG(i,376))):F$(i,846)?o7(e,ELn(uG(i,846))):F$(i,109)&&o7(e,jLn(uG(i,109))):t.a._b(i)?(e.a?JA(e.a,e.b):e.a=new lx(e.d),WA(e.a,"[...]")):o7(e,MWn(Kcn(i),new oX(t))):o7(e,null==i?IZn:cpn(i));return e.a?0==e.e.length?e.a.a:e.a.a+""+e.e:e.c}function TWn(n,t){var e,i,r,c;c=n.F,null==t?(n.F=null,sbn(n,null)):(n.F=(tJ(t),t),-1!=(i=xL(t,$Cn(60)))?(Knn(0,i,t.length),r=t.substr(0,i),-1==xL(t,$Cn(46))&&!m_(r,dZn)&&!m_(r,lrt)&&!m_(r,brt)&&!m_(r,wrt)&&!m_(r,drt)&&!m_(r,grt)&&!m_(r,prt)&&!m_(r,mrt)&&(r=vrt),-1!=(e=ax(t,$Cn(62)))&&(r+=""+(s3(e+1,t.length+1),t.substr(e+1))),sbn(n,r)):(r=t,-1==xL(t,$Cn(46))&&(-1!=(i=xL(t,$Cn(91)))&&(Knn(0,i,t.length),r=t.substr(0,i)),m_(r,dZn)||m_(r,lrt)||m_(r,brt)||m_(r,wrt)||m_(r,drt)||m_(r,grt)||m_(r,prt)||m_(r,mrt)?r=t:(r=vrt,-1!=i&&(r+=""+(s3(i,t.length+1),t.substr(i))))),sbn(n,r),r==t&&(n.F=n.D))),4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,5,c,t))}function jWn(n,t){var e,i,r,c,a,o,u,s;if(s3(o=t.length-1,t.length),93==(a=t.charCodeAt(o))){if((c=xL(t,$Cn(91)))>=0)return r=fpn(n,(Knn(1,c,t.length),t.substr(1,c-1))),Knn(c+1,o,t.length),GJn(n,t.substr(c+1,o-(c+1)),r)}else{if(e=-1,null==oot&&(oot=new RegExp("\\d")),oot.test(String.fromCharCode(a))&&(e=T_(t,$Cn(46),o-1))>=0){i=uG(U9(n,jrn(n,(Knn(1,e,t.length),t.substr(1,e-1))),!1),61),u=0;try{u=vUn((s3(e+1,t.length+1),t.substr(e+1)),j1n,vZn)}catch(h){throw F$(h=Ehn(h),130)?hv(new Pen(h)):hv(h)}if(u>16==-10?e=uG(n.Cb,292).Yk(t,e):n.Db>>16==-15&&(!t&&(YYn(),t=N_t),!o&&(YYn(),o=N_t),n.Cb.Yh()&&(a=new Ken(n.Cb,1,13,o,t,Hyn(Aen(uG(n.Cb,62)),n),!1),e?e.nj(a):e=a));else if(F$(n.Cb,90))n.Db>>16==-23&&(F$(t,90)||(YYn(),t=x_t),F$(o,90)||(YYn(),o=x_t),n.Cb.Yh()&&(a=new Ken(n.Cb,1,10,o,t,Hyn(z5(uG(n.Cb,29)),n),!1),e?e.nj(a):e=a));else if(F$(n.Cb,457))for(!(c=uG(n.Cb,850)).b&&(c.b=new Um(new ty)),r=new Gm(new bsn(new Nw(c.b.a).a));r.a.b;)e=PWn(i=uG(von(r.a).ld(),89),bRn(i,c),e);return e}function CWn(n,t){var e,i,r,c,a,o,u,s,h,f,l;for(a=oM(gK(zDn(n,(jYn(),sMt)))),l=uG(zDn(n,nTt),21),u=!1,s=!1,f=new DD((!n.c&&(n.c=new fV(wFt,n,9,9)),n.c));!(f.e==f.i.gc()||u&&s);){for(c=uG(Zkn(f),123),o=0,r=OV(zcn(Uhn(cT(vat,1),EZn,20,0,[(!c.d&&(c.d=new f_(aFt,c,8,5)),c.d),(!c.e&&(c.e=new f_(aFt,c,7,4)),c.e)])));hDn(r)&&(i=uG(N9(r),74),h=a&&BNn(i)&&oM(gK(zDn(i,hMt))),e=Lzn((!i.b&&(i.b=new f_(cFt,i,4,7)),i.b),c)?n==R0(lCn(uG(zrn((!i.c&&(i.c=new f_(cFt,i,5,8)),i.c),0),84))):n==R0(lCn(uG(zrn((!i.b&&(i.b=new f_(cFt,i,4,7)),i.b),0),84))),!((h||e)&&++o>1)););(o>0||l.Hc((eNn(),wRt))&&(!c.n&&(c.n=new fV(lFt,c,1,7)),c.n).i>0)&&(u=!0),o>1&&(s=!0)}u&&t.Fc((r_n(),tpt)),s&&t.Fc((r_n(),ept))}function IWn(n){var t,i,r,c,a,o,u,s,h,f,l,b;if((b=uG(zDn(n,(XYn(),_$t)),21)).dc())return null;if(u=0,o=0,b.Hc((Qmn(),QRt))){for(f=uG(zDn(n,sDt),101),r=2,i=2,c=2,a=2,t=R0(n)?uG(zDn(R0(n),d$t),88):uG(zDn(n,d$t),88),h=new DD((!n.c&&(n.c=new fV(wFt,n,9,9)),n.c));h.e!=h.i.gc();)if(s=uG(Zkn(h),123),(l=uG(zDn(s,gDt),64))==(KQn(),FRt)&&(l=RGn(s,t),Myn(s,gDt,l)),f==($Pn(),cRt))switch(l.g){case 1:r=e.Math.max(r,s.i+s.g);break;case 2:i=e.Math.max(i,s.j+s.f);break;case 3:c=e.Math.max(c,s.i+s.g);break;case 4:a=e.Math.max(a,s.j+s.f)}else switch(l.g){case 1:r+=s.g+2;break;case 2:i+=s.f+2;break;case 3:c+=s.g+2;break;case 4:a+=s.f+2}u=e.Math.max(r,c),o=e.Math.max(i,a)}return ZQn(n,u,o,!0,!0)}function OWn(n,t,i,r,c){var a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y;for(v=uG(l8(krn(JJ(new fX(null,new h3(t.d,16)),new Rg(i)),new Kg(i)),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15),l=vZn,f=j1n,s=new Ww(t.b.j);s.a0)?s&&(h=d.p,a?++h:--h,f=!(VRn(i=afn(uG(zq(d.c.a,h),10)),k,e[0])||rV(i,k,e[0]))):f=!0),l=!1,(v=t.D.i)&&v.c&&o.e&&(a&&v.p>0||!a&&v.p=0){for(u=null,o=new N4(h.a,s+1);o.ba?1:KL(isNaN(0),isNaN(a)))<0&&(oan(I9n),(e.Math.abs(a-1)<=I9n||1==a||isNaN(a)&&isNaN(1)?0:a<1?-1:a>1?1:KL(isNaN(a),isNaN(1)))<0)&&(oan(I9n),(e.Math.abs(0-o)<=I9n||0==o||isNaN(0)&&isNaN(o)?0:0o?1:KL(isNaN(0),isNaN(o)))<0)&&(oan(I9n),(e.Math.abs(o-1)<=I9n||1==o||isNaN(o)&&isNaN(1)?0:o<1?-1:o>1?1:KL(isNaN(o),isNaN(1)))<0))}function KWn(n){var t,e,i,r;if(-1!=(t=xL(e=null!=n.D?n.D:n.B,$Cn(91)))){Knn(0,t,e.length),i=e.substr(0,t),r=new zM;do{r.a+="["}while(-1!=(t=aR(e,91,++t)));m_(i,dZn)?r.a+="Z":m_(i,lrt)?r.a+="B":m_(i,brt)?r.a+="C":m_(i,wrt)?r.a+="D":m_(i,drt)?r.a+="F":m_(i,grt)?r.a+="I":m_(i,prt)?r.a+="J":m_(i,mrt)?r.a+="S":(r.a+="L",r.a+=""+i,r.a+=";");try{return null}catch(c){if(!F$(c=Ehn(c),63))throw hv(c)}}else if(-1==xL(e,$Cn(46))){if(m_(e,dZn))return ZHt;if(m_(e,lrt))return tUt;if(m_(e,brt))return JHt;if(m_(e,wrt))return eUt;if(m_(e,drt))return iUt;if(m_(e,grt))return YHt;if(m_(e,prt))return nUt;if(m_(e,mrt))return rUt}return null}function FWn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k;for(n.e=t,o=qNn(t),v=new Zm,i=new Ww(o);i.a=0&&d=s.c.c.length?B5((zIn(),dbt),wbt):B5((zIn(),wbt),wbt),h*=2,c=i.a.g,i.a.g=e.Math.max(c,c+(h-c)),a=i.b.g,i.b.g=e.Math.max(a,a+(h-a)),r=t}else pNn(o),WXn((u3(0,o.c.length),uG(o.c[0],18)).d.i)||kD(n.o,o)}function UWn(n){var t,i,r,c;for(kS(JJ(new fX(null,new h3(n.a.b,16)),new kr),new yr),QSn(n),kS(JJ(new fX(null,new h3(n.a.b,16)),new Mr),new Tr),n.c==(_gn(),hxt)&&(kS(JJ(sin(new fX(null,new h3(new Lw(n.f),1)),new jr),new Er),new Og(n)),kS(JJ(YJ(sin(sin(new fX(null,new h3(n.d.b,16)),new Sr),new Pr),new Cr),new Ir),new Lg(n))),c=new MO(M0n,M0n),t=new MO(T0n,T0n),r=new Ww(n.a.b);r.a0&&(t.a+=TZn),XWn(uG(Zkn(a),167),t);for(t.a+=Y4n,o=new Zx((!i.c&&(i.c=new f_(cFt,i,5,8)),i.c));o.e!=o.i.gc();)o.e>0&&(t.a+=TZn),XWn(uG(Zkn(o),167),t);t.a+=")"}}}function zWn(n,t,i){var r,c,a,o,u,s,f,l;for(s=new DD((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a));s.e!=s.i.gc();)for(c=new Fz(ix(eRn(u=uG(Zkn(s),27)).a.Kc(),new h));hDn(c);){if(!(r=uG(N9(c),74)).b&&(r.b=new f_(cFt,r,4,7)),!(r.b.i<=1&&(!r.c&&(r.c=new f_(cFt,r,5,8)),r.c.i<=1)))throw hv(new EM("Graph must not contain hyperedges."));if(!z$n(r)&&u!=lCn(uG(zrn((!r.c&&(r.c=new f_(cFt,r,5,8)),r.c),0),84)))for(zsn(f=new $F,r),kfn(f,(mon(),Wft),r),Kb(f,uG(DA(FX(i.f,u)),153)),Bb(f,uG(cQ(i,lCn(uG(zrn((!r.c&&(r.c=new f_(cFt,r,5,8)),r.c),0),84))),153)),kD(t.c,f),o=new DD((!r.n&&(r.n=new fV(lFt,r,1,7)),r.n));o.e!=o.i.gc();)zsn(l=new A5(f,(a=uG(Zkn(o),135)).a),a),kfn(l,Wft,a),l.e.a=e.Math.max(a.g,1),l.e.b=e.Math.max(a.f,1),Yqn(l),kD(t.d,l)}}function VWn(n,t,i){var r,c,a,o,u,s,h,f;switch(i.Ug("Node promotion heuristic",1),n.i=t,n.r=uG(oIn(t,(jYn(),yMt)),243),n.r!=(THn(),Pjt)&&n.r!=Cjt?RQn(n):n_n(n),f=uG(oIn(n.i,kMt),17).a,a=new hi,n.r.g){case 2:case 1:default:tzn(n,a);break;case 3:for(n.r=Djt,tzn(n,a),s=0,u=new Ww(n.b);u.an.k&&(n.r=Ijt,tzn(n,a));break;case 4:for(n.r=Djt,tzn(n,a),h=0,c=new Ww(n.c);c.an.n&&(n.r=Ljt,tzn(n,a));break;case 6:tzn(n,new mg(t0(e.Math.ceil(n.g.length*f/100))));break;case 5:tzn(n,new vg(t0(e.Math.ceil(n.e*f/100))));break;case 8:IYn(n,!0);break;case 9:IYn(n,!1)}n.r!=Pjt&&n.r!=Cjt?JKn(n,t):BBn(n,t),i.Vg()}function WWn(n){var t,e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p;for(pF(u=new N4(s=n.b,0),new bQ(n)),g=!1,c=1;u.b0&&(b.d+=f.n.d,b.d+=f.d),b.a>0&&(b.a+=f.n.a,b.a+=f.d),b.b>0&&(b.b+=f.n.b,b.b+=f.d),b.c>0&&(b.c+=f.n.c,b.c+=f.d),b}function JWn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d;for(b=i.d,l=i.c,o=(a=new MO(i.f.a+i.d.b+i.d.c,i.f.b+i.d.d+i.d.a)).b,h=new Ww(n.a);h.a0&&(n.c[t.c.p][t.p].d+=uRn(n.i,24)*z0n*.07000000029802322-.03500000014901161,n.c[t.c.p][t.p].a=n.c[t.c.p][t.p].d/n.c[t.c.p][t.p].b)}}function tQn(n){var t,e,i,r,c,a,o,u,s,h,f,l,b,w;for(l=new Ww(n);l.ar.d,r.d=e.Math.max(r.d,t),u&&i&&(r.d=e.Math.max(r.d,r.a),r.a=r.d+c);break;case 3:i=t>r.a,r.a=e.Math.max(r.a,t),u&&i&&(r.a=e.Math.max(r.a,r.d),r.d=r.a+c);break;case 2:i=t>r.c,r.c=e.Math.max(r.c,t),u&&i&&(r.c=e.Math.max(r.b,r.c),r.b=r.c+c);break;case 4:i=t>r.b,r.b=e.Math.max(r.b,t),u&&i&&(r.b=e.Math.max(r.b,r.c),r.c=r.b+c)}}}function rQn(n,t){var e,i,r,c,a,o,u,s,h;return s="",0==t.length?n.ne(L1n,O1n,-1,-1):(m_((h=KAn(t)).substr(0,3),"at ")&&(s3(3,h.length+1),h=h.substr(3)),-1==(a=(h=h.replace(/\[.*?\]/g,"")).indexOf("("))?-1==(a=h.indexOf("@"))?(s=h,h=""):(s=KAn((s3(a+1,h.length+1),h.substr(a+1))),h=KAn((Knn(0,a,h.length),h.substr(0,a)))):(Knn(a+1,e=h.indexOf(")",a),h.length),s=h.substr(a+1,e-(a+1)),h=KAn((Knn(0,a,h.length),h.substr(0,a)))),-1!=(a=xL(h,$Cn(46)))&&(s3(a+1,h.length+1),h=h.substr(a+1)),(0==h.length||m_(h,"Anonymous function"))&&(h=O1n),o=ax(s,$Cn(58)),r=T_(s,$Cn(58),o-1),u=-1,i=-1,c=L1n,-1!=o&&-1!=r&&(Knn(0,r,s.length),c=s.substr(0,r),u=rR((Knn(r+1,o,s.length),s.substr(r+1,o-(r+1)))),i=rR((s3(o+1,s.length+1),s.substr(o+1)))),n.ne(c,h,u,i))}function cQn(n){var t,e,i,r,c,a,o,u,s,h,f;for(s=new Ww(n);s.a0||h.j==_Rt&&h.e.c.length-h.g.c.length<0)){t=!1;break}for(r=new Ww(h.g);r.a=h&&M>=p&&(b+=d.n.b+g.n.b+g.a.b-y,++u));if(i)for(o=new Ww(v.e);o.a=h&&M>=p&&(b+=d.n.b+g.n.b+g.a.b-y,++u))}u>0&&(T+=b/u,++w)}w>0?(t.a=c*T/w,t.g=w):(t.a=0,t.g=0)}function oQn(n){var t,e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T;for(l=(c=n.f.b).a,h=c.b,w=n.e.g,b=n.e.f,vN(n.e,c.a,c.b),M=l/w,T=h/b,s=new DD(xJ(n.e));s.e!=s.i.gc();)ycn(u=uG(Zkn(s),135),u.i*M),Mcn(u,u.j*T);for(m=new DD(RJ(n.e));m.e!=m.i.gc();)k=(p=uG(Zkn(m),123)).i,y=p.j,k>0&&ycn(p,k*M),y>0&&Mcn(p,y*T);for(Yun(n.b,new ft),t=new Zm,o=new bsn(new Nw(n.c).a);o.b;)i=uG((a=von(o)).ld(),74),e=uG(a.md(),407).a,r=JFn(i,!1,!1),sqn(f=YPn(bIn(i),COn(r),e),r),(v=wIn(i))&&-1==Ten(t,v,0)&&(mv(t.c,v),iY(v,(MK(0!=f.b),uG(f.a.a.c,8)),e));for(g=new bsn(new Nw(n.d).a);g.b;)i=uG((d=von(g)).ld(),74),e=uG(d.md(),407).a,r=JFn(i,!1,!1),f=YPn(gIn(i),fln(COn(r)),e),sqn(f=fln(f),r),(v=dIn(i))&&-1==Ten(t,v,0)&&(mv(t.c,v),iY(v,(MK(0!=f.b),uG(f.c.b.c,8)),e))}function uQn(n,t,e,i){var r,c,a,o,u;return sKn(o=new kQn(t),i),r=!0,n&&n.pf((XYn(),d$t))&&(r=(c=uG(n.of((XYn(),d$t)),88))==(xdn(),ZDt)||c==JDt||c==YDt),iBn(o,!1),Prn(o.e.Rf(),new DB(o,!1,r)),W1(o,o.f,(Yrn(),jst),(KQn(),yRt)),W1(o,o.f,Sst,KRt),W1(o,o.g,jst,_Rt),W1(o,o.g,Sst,kRt),gyn(o,yRt),gyn(o,KRt),IJ(o,kRt),IJ(o,_Rt),VK(),(a=o.A.Hc((Qmn(),VRt))&&o.B.Hc((oUn(),rKt))?xmn(o):null)&&dT(o.a,a),iQn(o),BTn(o),HTn(o),wWn(o),NHn(o),iEn(o),dkn(o,yRt),dkn(o,KRt),IBn(o),UXn(o),e?(wpn(o),rEn(o),dkn(o,kRt),dkn(o,_Rt),u=o.B.Hc((oUn(),cKt)),dLn(o,u,yRt),dLn(o,u,KRt),gLn(o,u,kRt),gLn(o,u,_Rt),kS(new fX(null,new h3(new Fw(o.i),0)),new Cn),kS(JJ(new fX(null,FW(o.r).a.oc()),new In),new On),jPn(o),o.e.Pf(o.o),kS(new fX(null,FW(o.r).a.oc()),new An),o.o):o.o}function sQn(n){var t,i,r,c,a,o,u,s,h,f,l,b,w,d,g;for(h=M0n,r=new Ww(n.a.b);r.a1)for(z8(v,new BI(n,b=new Izn(w,v,r))),mv(o.c,b),f=v.a.ec().Kc();f.Ob();)men(a,uG(f.Pb(),42).b);if(u.a.gc()>1)for(z8(u,new HI(n,b=new Izn(w,u,r))),mv(o.c,b),f=u.a.ec().Kc();f.Ob();)men(a,uG(f.Pb(),42).b)}}function dQn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m;if(g=n.n,p=n.o,b=n.d,l=uM(pK(Omn(n,(jYn(),lTt)))),t){for(f=l*(t.gc()-1),w=0,s=t.Kc();s.Ob();)f+=(o=uG(s.Pb(),10)).o.a,w=e.Math.max(w,o.o.b);for(m=g.a-(f-p.a)/2,a=g.b-b.d+w,c=r=p.a/(t.gc()+1),u=t.Kc();u.Ob();)(o=uG(u.Pb(),10)).n.a=m,o.n.b=a-o.o.b,m+=o.o.a+l,(h=ERn(o)).n.a=o.o.a/2-h.a.a,h.n.b=o.o.b,(d=uG(oIn(o,(GYn(),Ppt)),12)).e.c.length+d.g.c.length==1&&(d.n.a=c-d.a.a,d.n.b=0,o2(d,n)),c+=r}if(i){for(f=l*(i.gc()-1),w=0,s=i.Kc();s.Ob();)f+=(o=uG(s.Pb(),10)).o.a,w=e.Math.max(w,o.o.b);for(m=g.a-(f-p.a)/2,a=g.b+p.b+b.a-w,c=r=p.a/(i.gc()+1),u=i.Kc();u.Ob();)(o=uG(u.Pb(),10)).n.a=m,o.n.b=a,m+=o.o.a+l,(h=ERn(o)).n.a=o.o.a/2-h.a.a,h.n.b=0,(d=uG(oIn(o,(GYn(),Ppt)),12)).e.c.length+d.g.c.length==1&&(d.n.a=c-d.a.a,d.n.b=p.b,o2(d,n)),c+=r}}function gQn(n,t){var i,r,c,a,o,u;if(uG(oIn(t,(GYn(),Hpt)),21).Hc((r_n(),tpt))){for(u=new Ww(t.a);u.a=0&&a0&&(uG(AJ(n.b,t),127).a.b=i)}function jQn(n,t,e,i){var r,c,a,o,u,s,h,f,l,b,w,d;if(l=uM(pK(oIn(n,(jYn(),TTt)))),b=uM(pK(oIn(n,jTt))),f=uM(pK(oIn(n,yTt))),o=n.o,a=(c=uG(zq(n.j,0),12)).n,d=hAn(c,f)){if(t.Hc((eNn(),wRt)))switch(uG(oIn(n,(GYn(),Fpt)),64).g){case 1:d.c=(o.a-d.b)/2-a.a,d.d=b;break;case 3:d.c=(o.a-d.b)/2-a.a,d.d=-b-d.a;break;case 2:e&&0==c.e.c.length&&0==c.g.c.length?(h=i?d.a:uG(zq(c.f,0),72).o.b,d.d=(o.b-h)/2-a.b):d.d=o.b+b-a.b,d.c=-l-d.b;break;case 4:e&&0==c.e.c.length&&0==c.g.c.length?(h=i?d.a:uG(zq(c.f,0),72).o.b,d.d=(o.b-h)/2-a.b):d.d=o.b+b-a.b,d.c=l}else if(t.Hc(gRt))switch(uG(oIn(n,(GYn(),Fpt)),64).g){case 1:case 3:d.c=a.a+l;break;case 2:case 4:e&&!c.c?(h=i?d.a:uG(zq(c.f,0),72).o.b,d.d=(o.b-h)/2-a.b):d.d=a.b+b}for(r=d.d,s=new Ww(c.f);s.a=n.length)return{done:!0};var i=n[e++];return{value:[i,t.get(i)],done:!1}}}},__n()||(n.prototype.createObject=function(){return{}},n.prototype.get=function(n){return this.obj[":"+n]},n.prototype.set=function(n,t){this.obj[":"+n]=t},n.prototype[U0n]=function(n){delete this.obj[":"+n]},n.prototype.keys=function(){var n=[];for(var t in this.obj)58==t.charCodeAt(0)&&n.push(t.substring(1));return n}),n}function OQn(){OQn=E,RPt=new Cm(E4n),new Cm(S4n),new uF("DEPTH",xwn(0)),EPt=new uF("FAN",xwn(0)),TPt=new uF(Q9n,xwn(0)),UPt=new uF("ROOT",(qx(),!1)),APt=new uF("LEFTNEIGHBOR",null),BPt=new uF("RIGHTNEIGHBOR",null),LPt=new uF("LEFTSIBLING",null),HPt=new uF("RIGHTSIBLING",null),jPt=new uF("DUMMY",!1),new uF("LEVEL",xwn(0)),_Pt=new uF("REMOVABLE_EDGES",new lS),GPt=new uF("XCOOR",xwn(0)),qPt=new uF("YCOOR",xwn(0)),NPt=new uF("LEVELHEIGHT",0),DPt=new uF("LEVELMIN",0),$Pt=new uF("LEVELMAX",0),PPt=new uF("GRAPH_XMIN",0),IPt=new uF("GRAPH_YMIN",0),SPt=new uF("GRAPH_XMAX",0),CPt=new uF("GRAPH_YMAX",0),MPt=new uF("COMPACT_LEVEL_ASCENSION",!1),yPt=new uF("COMPACT_CONSTRAINTS",new Zm),OPt=new uF("ID",""),KPt=new uF("POSITION",xwn(0)),FPt=new uF("PRELIM",0),xPt=new uF("MODIFIER",0),kPt=new Cm(P4n),vPt=new Cm(C4n)}function AQn(n){var t,e,i,r,c,a,o,u,s,h,f,l,b,w,d;if(NGn(),null==n)return null;if(0==(f=8*n.length))return"";for(l=f/24|0,c=null,c=Inn(JHt,N1n,28,4*(0!=(o=f%24)?l+1:l),15,1),s=0,h=0,t=0,e=0,i=0,a=0,r=0,u=0;u>24,s=(3&t)<<24>>24,b=-128&t?(t>>2^192)<<24>>24:t>>2<<24>>24,w=-128&e?(e>>4^240)<<24>>24:e>>4<<24>>24,d=-128&(i=n[r++])?(i>>6^252)<<24>>24:i>>6<<24>>24,c[a++]=gHt[b],c[a++]=gHt[w|s<<4],c[a++]=gHt[h<<2|d],c[a++]=gHt[63&i];return 8==o?(s=(3&(t=n[r]))<<24>>24,b=-128&t?(t>>2^192)<<24>>24:t>>2<<24>>24,c[a++]=gHt[b],c[a++]=gHt[s<<4],c[a++]=61,c[a++]=61):16==o&&(t=n[r],h=(15&(e=n[r+1]))<<24>>24,s=(3&t)<<24>>24,b=-128&t?(t>>2^192)<<24>>24:t>>2<<24>>24,w=-128&e?(e>>4^240)<<24>>24:e>>4<<24>>24,c[a++]=gHt[b],c[a++]=gHt[w|s<<4],c[a++]=gHt[h<<2],c[a++]=61),mvn(c,0,c.length)}function LQn(n,t){var i,r,c,a,o,u;if(0==n.e&&n.p>0&&(n.p=-(n.p-1)),n.p>j1n&&F5(t,n.p-V1n),o=t.q.getDate(),k0(t,1),n.k>=0&&H0(t,n.k),n.c>=0?k0(t,n.c):n.k>=0?(r=35-new Lfn(t.q.getFullYear()-V1n,t.q.getMonth(),35).q.getDate(),k0(t,e.Math.min(r,o))):k0(t,o),n.f<0&&(n.f=t.q.getHours()),n.b>0&&n.f<12&&(n.f+=12),tD(t,24==n.f&&n.g?0:n.f),n.j>=0&&y7(t,n.j),n.n>=0&&Nnn(t,n.n),n.i>=0&&TL(t,Lgn(Ngn(bSn(Bsn(t.q.getTime()),$1n),$1n),n.i)),n.a&&(F5(c=new QE,c.q.getFullYear()-V1n-80),$P(Bsn(t.q.getTime()),Bsn(c.q.getTime()))&&F5(t,c.q.getFullYear()-V1n+100)),n.d>=0)if(-1==n.c)(i=(7+n.d-t.q.getDay())%7)>3&&(i-=7),u=t.q.getMonth(),k0(t,t.q.getDate()+i),t.q.getMonth()!=u&&k0(t,t.q.getDate()+(i>0?-7:7));else if(t.q.getDay()!=n.d)return!1;return n.o>j1n&&(a=t.q.getTimezoneOffset(),TL(t,Lgn(Bsn(t.q.getTime()),60*(n.o-a)*$1n))),!0}function NQn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p;if(F$(r=oIn(t,(GYn(),rmt)),207)){for(b=uG(r,27),w=t.e,f=new eN(t.c),c=t.d,f.a+=c.b,f.b+=c.d,$x(uG(zDn(b,(jYn(),KMt)),181),(oUn(),tKt))&&(Ab(l=uG(zDn(b,_Mt),107),c.a),_b(l,c.d),Lb(l,c.b),Fb(l,c.c)),e=new Zm,s=new Ww(t.a);s.ai.c.length-1;)kD(i,new WO(B3n,G9n));e=uG(oIn(r,ACt),17).a,hN(uG(oIn(n,cCt),88))?(r.e.auM(pK((u3(e,i.c.length),uG(i.c[e],42)).b))&&sw((u3(e,i.c.length),uG(i.c[e],42)),r.e.a+r.f.a)):(r.e.buM(pK((u3(e,i.c.length),uG(i.c[e],42)).b))&&sw((u3(e,i.c.length),uG(i.c[e],42)),r.e.b+r.f.b))}for(c=Fkn(n.b,0);c.b!=c.d.c;)r=uG(I6(c),40),e=uG(oIn(r,(QGn(),ACt)),17).a,kfn(r,(OQn(),DPt),pK((u3(e,i.c.length),uG(i.c[e],42)).a)),kfn(r,$Pt,pK((u3(e,i.c.length),uG(i.c[e],42)).b));t.Vg()}function RQn(n){var t,i,r,c,a,o,u,s,f,l,b,w,d,g,p;for(n.o=uM(pK(oIn(n.i,(jYn(),ETt)))),n.f=uM(pK(oIn(n.i,vTt))),n.j=n.i.b.c.length,u=n.j-1,w=0,n.k=0,n.n=0,n.b=n7(Inn(dot,zZn,17,n.j,0,1)),n.c=n7(Inn(fot,zZn,345,n.j,7,1)),o=new Ww(n.i.b);o.a0&&kD(n.q,l),kD(n.p,l);d=s+(t-=r),f+=t*n.f,Y8(n.b,u,xwn(d)),Y8(n.c,u,f),n.k=e.Math.max(n.k,d),n.n=e.Math.max(n.n,f),n.e+=t,t+=p}}function KQn(){var n;KQn=E,FRt=new RO(Y2n,0),yRt=new RO(o3n,1),kRt=new RO(u3n,2),KRt=new RO(s3n,3),_Rt=new RO(h3n,4),hZ(),SRt=new nT(new nB(n=uG(Mj(YRt),9),uG(MF(n,n.length),9),0)),PRt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[]))),MRt=Nwn(WX(kRt,Uhn(cT(YRt,1),z4n,64,0,[]))),DRt=Nwn(WX(KRt,Uhn(cT(YRt,1),z4n,64,0,[]))),RRt=Nwn(WX(_Rt,Uhn(cT(YRt,1),z4n,64,0,[]))),LRt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[KRt]))),ERt=Nwn(WX(kRt,Uhn(cT(YRt,1),z4n,64,0,[_Rt]))),$Rt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[_Rt]))),CRt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[kRt]))),xRt=Nwn(WX(KRt,Uhn(cT(YRt,1),z4n,64,0,[_Rt]))),TRt=Nwn(WX(kRt,Uhn(cT(YRt,1),z4n,64,0,[KRt]))),ARt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[kRt,_Rt]))),jRt=Nwn(WX(kRt,Uhn(cT(YRt,1),z4n,64,0,[KRt,_Rt]))),NRt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[KRt,_Rt]))),IRt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[kRt,KRt]))),ORt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[kRt,KRt,_Rt])))}function FQn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y;for(t.Ug(j6n,1),w=new Zm,k=new Zm,s=new Ww(n.b);s.a0&&(y-=d),Vzn(o,y),l=0,w=new Ww(o.a);w.a0),u.a.Xb(u.c=--u.b)),s=.4*r*l,!a&&u.b0&&(s3(0,t.length),64!=(o=t.charCodeAt(0)))){if(37==o&&(u=!1,0!=(h=t.lastIndexOf("%"))&&(h==f-1||(s3(h+1,t.length),u=46==t.charCodeAt(h+1))))){if(Knn(1,h,t.length),m=m_("%",a=t.substr(1,h-1))?null:eJn(a),i=0,u)try{i=vUn((s3(h+2,t.length+1),t.substr(h+2)),j1n,vZn)}catch(v){throw F$(v=Ehn(v),130)?hv(new Pen(v)):hv(v)}for(d=kon(n.Gh());d.Ob();)if(F$(b=Ksn(d),519)&&(p=(r=uG(b,598)).d,(null==m?null==p:m_(m,p))&&0==i--))return r;return null}if(l=-1==(s=t.lastIndexOf("."))?t:(Knn(0,s,t.length),t.substr(0,s)),e=0,-1!=s)try{e=vUn((s3(s+1,t.length+1),t.substr(s+1)),j1n,vZn)}catch(v){if(!F$(v=Ehn(v),130))throw hv(v);l=t}for(l=m_("%",l)?null:eJn(l),w=kon(n.Gh());w.Ob();)if(F$(b=Ksn(w),197)&&(g=(c=uG(b,197)).xe(),(null==l?null==g:m_(l,g))&&0==e--))return c;return null}return jWn(n,t)}function WQn(n){var t,e,i,r,c,a,o,u,s,f,l,b,w,d,g,p,m;for(s=new Ym,o=new K1,i=new Ww(n.a.a.b);i.at.d.c){if((b=n.c[t.a.d])==(g=n.c[f.a.d]))continue;RKn(xS(DS(RS($S(new uk,1),100),b),g))}}}function QQn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T;if(b=uG(uG(Y9(n.r,t),21),87),t!=(KQn(),kRt)&&t!=_Rt){for(a=t==yRt?(ehn(),wht):(ehn(),pht),y=t==yRt?(Yen(),Fst):(Yen(),Rst),c=(r=(i=uG(AJ(n.b,t),127)).i).c+Trn(Uhn(cT(eUt,1),I0n,28,15,[i.n.b,n.C.b,n.k])),m=r.c+r.b-Trn(Uhn(cT(eUt,1),I0n,28,15,[i.n.c,n.C.c,n.k])),o=TT(BB(a),n.t),v=t==yRt?T0n:M0n,l=b.Kc();l.Ob();)!(h=uG(l.Pb(),117)).c||h.c.d.c.length<=0||(p=h.b.Mf(),g=h.e,(d=(w=h.c).i).b=(s=w.n,w.e.a+s.b+s.c),d.a=(u=w.n,w.e.b+u.d+u.a),ZZ(y,W2n),w.f=y,etn(w,(Ktn(),Lst)),d.c=g.a-(d.b-p.a)/2,M=e.Math.min(c,g.a),T=e.Math.max(m,g.a+p.a),d.cT&&(d.c=T-d.b),kD(o.d,new ZX(d,Hdn(o,d))),v=t==yRt?e.Math.max(v,g.b+h.b.Mf().b):e.Math.min(v,g.b));for(v+=t==yRt?n.t:-n.t,(k=cmn((o.e=v,o)))>0&&(uG(AJ(n.b,t),127).a.b=k),f=b.Kc();f.Ob();)!(h=uG(f.Pb(),117)).c||h.c.d.c.length<=0||((d=h.c.i).c-=h.e.a,d.d-=h.e.b)}else TQn(n,t)}function JQn(n){var t,e,i,r,c,a,o,u,s,f;for(t=new Ym,a=new DD(n);a.e!=a.i.gc();){for(c=uG(Zkn(a),27),e=new ek,vJ(cft,c,e),f=new at,i=uG(l8(new fX(null,new LW(new Fz(ix(tRn(c).a.Kc(),new h)))),HX(f,ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)])))),85),Ycn(e,uG(i.xc((qx(),!0)),16),new ot),r=uG(l8(JJ(uG(i.xc(!1),15).Lc(),new ut),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut]))),15).Kc();r.Ob();)(s=wIn(uG(r.Pb(),74)))&&((o=uG(DA(FX(t.f,s)),21))||(o=TFn(s),VAn(t.f,s,o)),Qon(e,o));for(i=uG(l8(new fX(null,new LW(new Fz(ix(eRn(c).a.Kc(),new h)))),HX(f,ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut])))),85),Ycn(e,uG(i.xc(!0),16),new st),u=uG(l8(JJ(uG(i.xc(!1),15).Lc(),new ht),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut]))),15).Kc();u.Ob();)(s=dIn(uG(u.Pb(),74)))&&((o=uG(DA(FX(t.f,s)),21))||(o=TFn(s),VAn(t.f,s,o)),Qon(e,o))}}function YQn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d;if(pXn(),(u=dwn(n,0)<0)&&(n=Men(n)),0==dwn(n,0))switch(t){case 0:return"0";case 1:return N0n;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return(b=new WM).a+=t<0?"0E+":"0E",b.a+=t==j1n?"2147483648":""+-t,b.a}f=Inn(JHt,N1n,28,1+(h=18),15,1),e=h,d=n;do{s=d,d=bSn(d,10),f[--e]=pz(Lgn(48,$gn(s,Ngn(d,10))))&D1n}while(0!=dwn(d,0));if(r=$gn($gn($gn(h,e),t),1),0==t)return u&&(f[--e]=45),mvn(f,e,h-e);if(t>0&&dwn(r,-6)>=0){if(dwn(r,0)>=0){for(c=e+pz(r),o=h-1;o>=c;o--)f[o+1]=f[o];return f[++c]=46,u&&(f[--e]=45),mvn(f,e,h-e+1)}for(a=2;$P(a,Lgn(Men(r),1));a++)f[--e]=48;return f[--e]=46,f[--e]=48,u&&(f[--e]=45),mvn(f,e,h-e)}return w=e+1,i=h,l=new QM,u&&(l.a+="-"),i-w>=1?(jQ(l,f[e]),l.a+=".",l.a+=mvn(f,e+1,h-e-1)):l.a+=mvn(f,e,h-e),l.a+="E",dwn(r,0)>0&&(l.a+="+"),l.a+=""+oV(r),l.a}function ZQn(n,t,i,r,c){var a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T;if(p=new MO(n.g,n.f),(g=xAn(n)).a=e.Math.max(g.a,t),g.b=e.Math.max(g.b,i),T=g.a/p.a,f=g.b/p.b,y=g.a-p.a,s=g.b-p.b,r)for(o=R0(n)?uG(zDn(R0(n),(XYn(),d$t)),88):uG(zDn(n,(XYn(),d$t)),88),u=xA(zDn(n,(XYn(),sDt)))===xA(($Pn(),cRt)),v=new DD((!n.c&&(n.c=new fV(wFt,n,9,9)),n.c));v.e!=v.i.gc();)switch(m=uG(Zkn(v),123),(k=uG(zDn(m,gDt),64))==(KQn(),FRt)&&(k=RGn(m,o),Myn(m,gDt,k)),k.g){case 1:u||ycn(m,m.i*T);break;case 2:ycn(m,m.i+y),u||Mcn(m,m.j*f);break;case 3:u||ycn(m,m.i*T),Mcn(m,m.j+s);break;case 4:u||Mcn(m,m.j*f)}if(vN(n,g.a,g.b),c)for(b=new DD((!n.n&&(n.n=new fV(lFt,n,1,7)),n.n));b.e!=b.i.gc();)w=(l=uG(Zkn(b),135)).i+l.g/2,d=l.j+l.f/2,(M=w/p.a)+(h=d/p.b)>=1&&(M-h>0&&d>=0?(ycn(l,l.i+y),Mcn(l,l.j+s*h)):M-h<0&&w>=0&&(ycn(l,l.i+y*M),Mcn(l,l.j+s)));return Myn(n,(XYn(),_$t),(Qmn(),new nB(a=uG(Mj(sKt),9),uG(MF(a,a.length),9),0))),new MO(T,f)}function nJn(n){hP(n,new hCn(xT(FT(DT(KT(RT(new bu,x7n),"ELK Radial"),'A radial layout provider which is based on the algorithm of Peter Eades published in "Drawing free trees.", published by International Institute for Advanced Study of Social Information Science, Fujitsu Limited in 1991. The radial layouter takes a tree and places the nodes in radial order around the root. The nodes of the same tree level are placed on the same radius.'),new Oo),x7n))),U4(n,x7n,b9n,Jkn(BIt)),U4(n,x7n,o4n,Jkn(VIt)),U4(n,x7n,p4n,Jkn($It)),U4(n,x7n,x4n,Jkn(DIt)),U4(n,x7n,g4n,Jkn(xIt)),U4(n,x7n,m4n,Jkn(NIt)),U4(n,x7n,w4n,Jkn(RIt)),U4(n,x7n,v4n,Jkn(_It)),U4(n,x7n,P7n,Jkn(AIt)),U4(n,x7n,S7n,Jkn(LIt)),U4(n,x7n,E7n,Jkn(UIt)),U4(n,x7n,A7n,Jkn(XIt)),U4(n,x7n,L7n,Jkn(GIt)),U4(n,x7n,N7n,Jkn(qIt)),U4(n,x7n,O7n,Jkn(KIt)),U4(n,x7n,T7n,Jkn(FIt)),U4(n,x7n,j7n,Jkn(HIt)),U4(n,x7n,C7n,Jkn(zIt)),U4(n,x7n,I7n,Jkn(WIt)),U4(n,x7n,M7n,Jkn(OIt))}function tJn(n){var t,e,i,r,c,a,o,u,s,h,f;if(null==n)throw hv(new ZM(IZn));if(s=n,u=!1,(c=n.length)>0&&(s3(0,n.length),45!=(t=n.charCodeAt(0))&&43!=t||(s3(1,n.length+1),n=n.substr(1),--c,u=45==t)),0==c)throw hv(new ZM(y0n+s+'"'));for(;n.length>0&&(s3(0,n.length),48==n.charCodeAt(0));)s3(1,n.length+1),n=n.substr(1),--c;if(c>(lGn(),vot)[10])throw hv(new ZM(y0n+s+'"'));for(r=0;r0&&(f=-parseInt((Knn(0,i,n.length),n.substr(0,i)),10),s3(i,n.length+1),n=n.substr(i),c-=i,e=!1);c>=a;){if(i=parseInt((Knn(0,a,n.length),n.substr(0,a)),10),s3(a,n.length+1),n=n.substr(a),c-=a,e)e=!1;else{if(dwn(f,o)<0)throw hv(new ZM(y0n+s+'"'));f=Ngn(f,h)}f=$gn(f,i)}if(dwn(f,0)>0)throw hv(new ZM(y0n+s+'"'));if(!u&&dwn(f=Men(f),0)<0)throw hv(new ZM(y0n+s+'"'));return f}function eJn(n){var t,e,i,r,c,a,o,u;if(ZXn(),null==n)return null;if((r=xL(n,$Cn(37)))<0)return n;for(u=new lx((Knn(0,r,n.length),n.substr(0,r))),t=Inn(tUt,ret,28,4,15,1),o=0,i=0,a=n.length;rr+2&&mfn((s3(r+1,n.length),n.charCodeAt(r+1)),QFt,JFt)&&mfn((s3(r+2,n.length),n.charCodeAt(r+2)),QFt,JFt))if(e=AG((s3(r+1,n.length),n.charCodeAt(r+1)),(s3(r+2,n.length),n.charCodeAt(r+2))),r+=2,i>0?128==(192&e)?t[o++]=e<<24>>24:i=0:e>=128&&(192==(224&e)?(t[o++]=e<<24>>24,i=2):224==(240&e)?(t[o++]=e<<24>>24,i=3):240==(248&e)&&(t[o++]=e<<24>>24,i=4)),i>0){if(o==i){switch(o){case 2:jQ(u,((31&t[0])<<6|63&t[1])&D1n);break;case 3:jQ(u,((15&t[0])<<12|(63&t[1])<<6|63&t[2])&D1n)}o=0,i=0}}else{for(c=0;c=2){if(0==(!n.a&&(n.a=new fV(oFt,n,6,6)),n.a).i)gj(),i=new is,ttn((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a),i);else if((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a).i>1)for(l=new Zx((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a));l.e!=l.i.gc();)$Sn(l);sqn(t,uG(zrn((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a),0),166))}if(f)for(r=new DD((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a));r.e!=r.i.gc();)for(s=new DD((!(i=uG(Zkn(r),166)).a&&(i.a=new MD(eFt,i,5)),i.a));s.e!=s.i.gc();)u=uG(Zkn(s),377),o.a=e.Math.max(o.a,u.a),o.b=e.Math.max(o.b,u.b);for(a=new DD((!n.n&&(n.n=new fV(lFt,n,1,7)),n.n));a.e!=a.i.gc();)c=uG(Zkn(a),135),(h=uG(zDn(c,Cxt),8))&&kN(c,h.a,h.b),f&&(o.a=e.Math.max(o.a,c.i+c.g),o.b=e.Math.max(o.b,c.j+c.f));return o}function rJn(n,t,e,i,r){var c,a,o;if(win(n,t),a=t[0],c=VJ(e.c,0),o=-1,Jfn(e))if(i>0){if(a+i>n.length)return!1;o=RNn((Knn(0,a+i,n.length),n.substr(0,a+i)),t)}else o=RNn(n,t);switch(c){case 71:return o=XOn(n,a,Uhn(cT($ot,1),zZn,2,6,[Q1n,J1n]),t),r.e=o,!0;case 77:return c_n(n,t,r,o,a);case 76:return a_n(n,t,r,o,a);case 69:return XAn(n,t,a,r);case 99:return zAn(n,t,a,r);case 97:return o=XOn(n,a,Uhn(cT($ot,1),zZn,2,6,["AM","PM"]),t),r.b=o,!0;case 121:return o_n(n,t,a,o,e,r);case 100:return!(o<=0||(r.c=o,0));case 83:return!(o<0)&&tmn(o,a,t[0],r);case 104:12==o&&(o=0);case 75:case 72:return!(o<0||(r.f=o,r.g=!1,0));case 107:return!(o<0||(r.f=o,r.g=!0,0));case 109:return!(o<0||(r.j=o,0));case 115:return!(o<0||(r.n=o,0));case 90:if(aT[s]&&(d=s),f=new Ww(n.a.b);f.a1;){if(c=nKn(t),l=a.g,d=uG(zDn(t,hAt),107),g=uM(pK(zDn(t,VOt))),(!t.a&&(t.a=new fV(bFt,t,10,11)),t.a).i>1&&uM(pK(zDn(t,(lBn(),jOt))))!=M0n&&(a.c+(d.b+d.c))/(a.b+(d.d+d.a))1&&uM(pK(zDn(t,(lBn(),TOt))))!=M0n&&(a.c+(d.b+d.c))/(a.b+(d.d+d.a))>g&&Myn(c,(lBn(),POt),e.Math.max(uM(pK(zDn(t,EOt))),uM(pK(zDn(c,POt)))-uM(pK(zDn(t,TOt))))),(h=(s=kYn(w=new vO(r,f),c,b)).g)>=l&&h==h){for(o=0;o<(!c.a&&(c.a=new fV(bFt,c,10,11)),c.a).i;o++)mNn(n,uG(zrn((!c.a&&(c.a=new fV(bFt,c,10,11)),c.a),o),27),uG(zrn((!t.a&&(t.a=new fV(bFt,t,10,11)),t.a),o),27));Irn(t,w),x1(a,s.c),D1(a,s.b)}--u}Myn(t,(lBn(),mOt),a.b),Myn(t,vOt,a.c),i.Vg()}function uJn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v;for(t.Ug("Interactive node layering",1),i=new Zm,b=new Ww(n.a);b.a=u){MK(v.b>0),v.a.Xb(v.c=--v.b);break}p.a>s&&(r?(Ohn(r.b,p.b),r.a=e.Math.max(r.a,p.a),LQ(v)):(kD(p.b,f),p.c=e.Math.min(p.c,s),p.a=e.Math.max(p.a,u),r=p))}r||((r=new Mk).c=s,r.a=u,pF(v,r),kD(r.b,f))}for(o=n.b,h=0,m=new Ww(i);m.aw&&(a&&(cL(M,b),cL(j,xwn(h.b-1))),I=i.b,O+=b+t,b=0,f=e.Math.max(f,i.b+i.c+C)),ycn(u,I),Mcn(u,O),f=e.Math.max(f,I+C+i.c),b=e.Math.max(b,l),I+=C+t;if(f=e.Math.max(f,r),(P=O+b+i.a)t4n,S=e.Math.abs(b.b-d.b)>t4n,(!i&&E&&S||i&&(E||S))&&aq(p.a,y)),Qon(p.a,r),0==r.b?b=y:(MK(0!=r.b),b=uG(r.c.b.c,8)),hhn(w,l,g),kun(c)==j&&(HQ(j.i)!=c.a&&pAn(g=new sj,HQ(j.i),v),kfn(p,Smt,g)),sOn(w,p,v),f.a.zc(w,f);c2(p,M),u2(p,j)}for(h=f.a.ec().Kc();h.Ob();)c2(s=uG(h.Pb(),18),null),u2(s,null);t.Vg()}function fJn(n,t){var e,i,r,c,a,o,u,s,h,f,l;for(h=(r=uG(oIn(n,(QGn(),cCt)),88))==(xdn(),JDt)||r==YDt?QDt:YDt,e=uG(l8(JJ(new fX(null,new h3(n.b,16)),new $a),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15),(u=uG(l8(YJ(e.Oc(),new Pp(t)),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut]))),15)).Gc(uG(l8(YJ(e.Oc(),new Cp(t)),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut]))),16)),u.jd(new Ip(h)),l=new Hj(new Op(r)),i=new Ym,o=u.Kc();o.Ob();)a=uG(o.Pb(),240),s=uG(a.a,40),oM(gK(a.c))?(l.a.zc(s,(qx(),tot)),new od(l.a.Zc(s,!1)).a.gc()>0&&vJ(i,s,uG(new od(l.a.Zc(s,!1)).a.Vc(),40)),new od(l.a.ad(s,!0)).a.gc()>1&&vJ(i,wmn(l,s),s)):(new od(l.a.Zc(s,!1)).a.gc()>0&&xA(c=uG(new od(l.a.Zc(s,!1)).a.Vc(),40))===xA(DA(FX(i.f,s)))&&uG(oIn(s,(OQn(),yPt)),15).Fc(c),new od(l.a.ad(s,!0)).a.gc()>1&&(f=wmn(l,s),xA(DA(FX(i.f,f)))===xA(s)&&uG(oIn(f,(OQn(),yPt)),15).Fc(s)),l.a.Bc(s))}function lJn(n){var t,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y;if(1==n.gc())return uG(n.Xb(0),235);if(n.gc()<=0)return new d7;for(c=n.Kc();c.Ob();){for(i=uG(c.Pb(),235),d=0,f=vZn,l=vZn,s=j1n,h=j1n,w=new Ww(i.e);w.au&&(k=0,y+=o+m,o=0),eUn(g,i,k,y),t=e.Math.max(t,k+p.a),o=e.Math.max(o,p.b),k+=p.a+m;return g}function bJn(n){var t,e,i,r,c,a,o,u,s,h,f,l,b,w,d,g;if(NGn(),null==n)return null;if((w=hgn(c=_en(n)))%4!=0)return null;if(0==(d=w/4|0))return Inn(tUt,ret,28,0,15,1);for(f=null,t=0,e=0,i=0,r=0,a=0,o=0,u=0,s=0,b=0,l=0,h=0,f=Inn(tUt,ret,28,3*d,15,1);b>4)<<24>>24,f[l++]=((15&e)<<4|i>>2&15)<<24>>24,f[l++]=(i<<6|r)<<24>>24}return mE(a=c[h++])&&mE(o=c[h++])?(t=dHt[a],e=dHt[o],u=c[h++],s=c[h++],-1==dHt[u]||-1==dHt[s]?61==u&&61==s?15&e?null:(qGn(f,0,g=Inn(tUt,ret,28,3*b+1,15,1),0,3*b),g[l]=(t<<2|e>>4)<<24>>24,g):61!=u&&61==s?3&(i=dHt[u])?null:(qGn(f,0,g=Inn(tUt,ret,28,3*b+2,15,1),0,3*b),g[l++]=(t<<2|e>>4)<<24>>24,g[l]=((15&e)<<4|i>>2&15)<<24>>24,g):null:(i=dHt[u],r=dHt[s],f[l++]=(t<<2|e>>4)<<24>>24,f[l++]=((15&e)<<4|i>>2&15)<<24>>24,f[l++]=(i<<6|r)<<24>>24,f)):null}function wJn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v;for(t.Ug(j6n,1),l=uG(oIn(n,(jYn(),Vyt)),223),i=new Ww(n.b);i.a=2){for(b=!0,e=uG(N3(h=new Ww(r.j)),12),f=null;h.a0)if(r=f.gc(),s=t0(e.Math.floor((r+1)/2))-1,c=t0(e.Math.ceil((r+1)/2))-1,t.o==dSt)for(h=c;h>=s;h--)t.a[k.p]==k&&(d=uG(f.Xb(h),42),w=uG(d.a,10),!cS(i,d.b)&&b>n.b.e[w.p]&&(t.a[w.p]=k,t.g[k.p]=t.g[w.p],t.a[k.p]=t.g[k.p],t.f[t.g[k.p].p]=(qx(),!!(oM(t.f[t.g[k.p].p])&k.k==(zIn(),wbt))),b=n.b.e[w.p]));else for(h=s;h<=c;h++)t.a[k.p]==k&&(p=uG(f.Xb(h),42),g=uG(p.a,10),!cS(i,p.b)&&b0&&(c=uG(zq(p.c.a,T-1),10),o=n.i[c.p],E=e.Math.ceil(y$(n.n,c,p)),a=M.a.e-p.d.d-(o.a.e+c.o.b+c.d.a)-E),h=M0n,T0&&j.a.e.e-j.a.a-(j.b.e.e-j.b.a)<0,d=k.a.e.e-k.a.a-(k.b.e.e-k.b.a)<0&&j.a.e.e-j.a.a-(j.b.e.e-j.b.a)>0,w=k.a.e.e+k.b.aj.b.e.e+j.a.a,y=0,!g&&!d&&(b?a+l>0?y=l:h-r>0&&(y=r):w&&(a+u>0?y=u:h-v>0&&(y=v))),M.a.e+=y,M.b&&(M.d.e+=y),1)))}function pJn(n,t,i){var r,c,a,o,u,s,h,f,l,b;if(r=new gY(t.Lf().a,t.Lf().b,t.Mf().a,t.Mf().b),c=new cN,n.c)for(o=new Ww(t.Rf());o.as&&(i.a+=V$(Inn(JHt,N1n,28,-s,15,1))),i.a+="Is",xL(u,$Cn(32))>=0)for(r=0;r=i.o.b/2}p?(g=uG(oIn(i,(GYn(),Pmt)),15))?l?c=g:(r=uG(oIn(i,Ept),15))?c=g.gc()<=r.gc()?g:r:(c=new Zm,kfn(i,Ept,c)):(c=new Zm,kfn(i,Pmt,c)):(r=uG(oIn(i,(GYn(),Ept)),15))?f?c=r:(g=uG(oIn(i,Pmt),15))?c=r.gc()<=g.gc()?r:g:(c=new Zm,kfn(i,Pmt,c)):(c=new Zm,kfn(i,Ept,c)),c.Fc(n),kfn(n,(GYn(),Ppt),e),t.d==e?(u2(t,null),e.e.c.length+e.g.c.length==0&&o2(e,null),Nln(e)):(c2(t,null),e.e.c.length+e.g.c.length==0&&o2(e,null)),BY(t.a)}function jJn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S,P,C,I,O,A;for(i.Ug("MinWidth layering",1),w=t.b,j=t.a,A=uG(oIn(t,(jYn(),mMt)),17).a,u=uG(oIn(t,vMt),17).a,n.b=uM(pK(oIn(t,dTt))),n.d=M0n,y=new Ww(j);y.a0?(h=0,p&&(h+=u),h+=(E-1)*o,v&&(h+=u),j&&v&&(h=e.Math.max(h,GKn(v,o,m,T))),h=n.a&&(r=Rqn(n,m),l=e.Math.max(l,r.b),k=e.Math.max(k,r.d),kD(u,new WO(m,r)));for(T=new Zm,f=0;f0),g.a.Xb(g.c=--g.b),pF(g,j=new bQ(n.b)),MK(g.b0){for(l=h<100?null:new cj(h),w=(s=new Hun(t)).g,g=Inn(YHt,W1n,28,h,15,1),i=0,v=new Drn(h),r=0;r=0;)if(null!=b?udn(b,w[u]):xA(b)===xA(w[u])){g.length<=i&&qGn(g,0,g=Inn(YHt,W1n,28,2*g.length,15,1),0,i),g[i++]=r,ttn(v,w[u]);break n}if(xA(b)===xA(o))break}}if(s=v,w=v.g,h=i,i>g.length&&qGn(g,0,g=Inn(YHt,W1n,28,i,15,1),0,i),i>0){for(m=!0,c=0;c=0;)gjn(n,g[a]);if(i!=h){for(r=h;--r>=i;)gjn(s,r);qGn(g,0,g=Inn(YHt,W1n,28,i,15,1),0,i)}t=s}}}else for(t=cjn(n,t),r=n.i;--r>=0;)t.Hc(n.g[r])&&(gjn(n,r),m=!0);if(m){if(null!=g){for(f=1==(e=t.gc())?i2(n,4,t.Kc().Pb(),null,g[0],d):i2(n,6,t,g,g[0],d),l=e<100?null:new cj(e),r=t.Kc();r.Ob();)l=X_(n,uG(b=r.Pb(),76),l);l?(l.nj(f),l.oj()):Msn(n.e,f)}else{for(l=qF(t.gc()),r=t.Kc();r.Ob();)l=X_(n,uG(b=r.Pb(),76),l);l&&l.oj()}return!0}return!1}function CJn(n,t){var e,i,r,c,a,o,u,s,f,l,b,w,d,g,p,m,v;for((e=new qyn(t)).a||TUn(t),s=oBn(t),u=new K1,g=new BFn,d=new Ww(t.a);d.a0||i.o==dSt&&c=e}function AJn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m;for(f=t,h=new K1,l=new K1,c=p6(f,yet),IOn((i=new SY(n,e,h,l)).a,i.b,i.c,i.d,c),d=(h.i||(h.i=new RD(h,h.c))).Kc();d.Ob();)for(w=uG(d.Pb(),166),o=uG(Y9(h,w),21).Kc();o.Ob();){if(a=o.Pb(),!(b=uG(dcn(n.d,a),166)))throw r=k6(f,Iet),hv(new SM(Det+a+xet+r+$et));!w.e&&(w.e=new f_(oFt,w,10,9)),ttn(w.e,b)}for(p=(l.i||(l.i=new RD(l,l.c))).Kc();p.Ob();)for(g=uG(p.Pb(),166),s=uG(Y9(l,g),21).Kc();s.Ob();){if(u=s.Pb(),!(b=uG(dcn(n.d,u),166)))throw r=k6(f,Iet),hv(new SM(Det+u+xet+r+$et));!g.g&&(g.g=new f_(oFt,g,9,10)),ttn(g.g,b)}!e.b&&(e.b=new f_(cFt,e,4,7)),0!=e.b.i&&(!e.c&&(e.c=new f_(cFt,e,5,8)),0!=e.c.i)&&(!e.b&&(e.b=new f_(cFt,e,4,7)),e.b.i<=1&&(!e.c&&(e.c=new f_(cFt,e,5,8)),e.c.i<=1))&&1==(!e.a&&(e.a=new fV(oFt,e,6,6)),e.a).i&&(hMn(m=uG(zrn((!e.a&&(e.a=new fV(oFt,e,6,6)),e.a),0),166))||fMn(m)||(Xan(m,uG(zrn((!e.b&&(e.b=new f_(cFt,e,4,7)),e.b),0),84)),zan(m,uG(zrn((!e.c&&(e.c=new f_(cFt,e,5,8)),e.c),0),84))))}function LJn(n){var t,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S;for(k=0,y=(v=n.a).length;k0?(f=uG(zq(l.c.a,a-1),10),j=y$(n.b,l,f),g=l.n.b-l.d.d-(f.n.b+f.o.b+f.d.a+j)):g=l.n.b-l.d.d,s=e.Math.min(g,s),a1&&(o=e.Math.min(o,e.Math.abs(uG(hyn(u.a,1),8).b-f.b)))));else for(d=new Ww(t.j);d.ac&&(a=b.a-c,o=vZn,r.c.length=0,c=b.a),b.a>=c&&(mv(r.c,u),u.a.b>1&&(o=e.Math.min(o,e.Math.abs(uG(hyn(u.a,u.a.b-2),8).b-b.b)))));if(0!=r.c.length&&a>t.o.a/2&&o>t.o.b/2){for(o2(w=new lOn,t),NLn(w,(KQn(),yRt)),w.n.a=t.o.a/2,o2(g=new lOn,t),NLn(g,KRt),g.n.a=t.o.a/2,g.n.b=t.o.b,s=new Ww(r);s.a=h.b?c2(u,g):c2(u,w)):(h=uG(eG(u.a),8),(0==u.a.b?n3(u.c):uG(pR(u.a),8)).b>=h.b?u2(u,g):u2(u,w)),(l=uG(oIn(u,(jYn(),bMt)),75))&&Wpn(l,h,!0);t.n.a=c-t.o.a/2}}function $Jn(n,t,i){var r,c,a,o,u,s,h,f,l;for(u=Fkn(n.b,0);u.b!=u.d.c;)if(!m_((o=uG(I6(u),40)).c,H9n))for(h=xDn(o,n),t==(xdn(),JDt)||t==YDt?f$(h,new co):f$(h,new ao),s=h.c.length,r=0;r=0?Ipn(o):Gdn(Ipn(o)),n.qf(eTt,b)),s=new sj,l=!1,n.pf(WMt)?(_R(s,uG(n.of(WMt),8)),l=!0):mD(s,a.a/2,a.b/2),b.g){case 4:kfn(h,gMt,(Gpn(),Imt)),kfn(h,Npt,(Pfn(),ygt)),h.o.b=a.b,d<0&&(h.o.a=-d),NLn(f,(KQn(),kRt)),l||(s.a=a.a),s.a-=a.a;break;case 2:kfn(h,gMt,(Gpn(),Amt)),kfn(h,Npt,(Pfn(),vgt)),h.o.b=a.b,d<0&&(h.o.a=-d),NLn(f,(KQn(),_Rt)),l||(s.a=0);break;case 1:kfn(h,Xpt,(Zen(),ppt)),h.o.a=a.a,d<0&&(h.o.b=-d),NLn(f,(KQn(),KRt)),l||(s.b=a.b),s.b-=a.b;break;case 3:kfn(h,Xpt,(Zen(),dpt)),h.o.a=a.a,d<0&&(h.o.b=-d),NLn(f,(KQn(),yRt)),l||(s.b=0)}if(_R(f.n,s),kfn(h,WMt,s),t==rRt||t==aRt||t==cRt){if(w=0,t==rRt&&n.pf(YMt))switch(b.g){case 1:case 2:w=uG(n.of(YMt),17).a;break;case 3:case 4:w=-uG(n.of(YMt),17).a}else switch(b.g){case 4:case 2:w=c.b,t==aRt&&(w/=r.b);break;case 1:case 3:w=c.a,t==aRt&&(w/=r.a)}kfn(h,bmt,w)}return kfn(h,Fpt,b),h}function xJn(){function n(n){var t=this;this.dispatch=function(t){var e=t.data;switch(e.cmd){case"algorithms":var i=rmn((hZ(),new qw(new Fw(NFt.b))));n.postMessage({id:e.id,data:i});break;case"categories":var r=rmn((hZ(),new qw(new Fw(NFt.c))));n.postMessage({id:e.id,data:r});break;case"options":var c=rmn((hZ(),new qw(new Fw(NFt.d))));n.postMessage({id:e.id,data:c});break;case"register":OVn(e.algorithms),n.postMessage({id:e.id});break;case"layout":Vqn(e.graph,e.layoutOptions||{},e.options||{}),n.postMessage({id:e.id,data:e.graph})}},this.saveDispatch=function(e){try{t.dispatch(e)}catch(i){n.postMessage({id:e.data.id,error:i})}}}function e(t){var e=this;this.dispatcher=new n({postMessage:function(n){e.onmessage({data:n})}}),this.postMessage=function(n){setTimeout((function(){e.dispatcher.saveDispatch({data:n})}),0)}}if(mj(),typeof document===r2n&&typeof self!==r2n){var r=new n(self);self.onmessage=r.saveDispatch}else typeof t!==r2n&&t.exports&&(Object.defineProperty(i,"__esModule",{value:!0}),t.exports={default:e,Worker:e})}function RJn(n,t,e){var i,r,c,a,o,u,s,h,f,l;for(zsn(h=new gMn(e),t),kfn(h,(GYn(),rmt),t),h.o.a=t.g,h.o.b=t.f,h.n.a=t.i,h.n.b=t.j,kD(e.a,h),vJ(n.a,t,h),(0!=(!t.a&&(t.a=new fV(bFt,t,10,11)),t.a).i||oM(gK(zDn(t,(jYn(),sMt)))))&&kfn(h,Cpt,(qx(),!0)),s=uG(oIn(e,Hpt),21),(f=uG(oIn(h,(jYn(),JMt)),101))==($Pn(),sRt)?kfn(h,JMt,uRt):f!=uRt&&s.Fc((r_n(),rpt)),l=0,i=uG(oIn(e,Byt),88),u=new DD((!t.c&&(t.c=new fV(wFt,t,9,9)),t.c));u.e!=u.i.gc();)o=uG(Zkn(u),123),(xA(zDn(r=R0(t),Syt))!==xA((yvn(),Fjt))||xA(zDn(r,Fyt))===xA((kvn(),lgt))||xA(zDn(r,Fyt))===xA((kvn(),hgt))||oM(gK(zDn(r,Cyt)))||xA(zDn(r,kyt))!==xA((Uvn(),tbt))||xA(zDn(r,yMt))===xA((THn(),Pjt))||xA(zDn(r,yMt))===xA((THn(),Cjt))||xA(zDn(r,MMt))===xA((MKn(),JTt))||xA(zDn(r,MMt))===xA((MKn(),ZTt)))&&!oM(gK(zDn(t,jyt)))&&Myn(o,imt,xwn(l++)),oM(gK(zDn(o,FMt)))||mQn(n,o,h,s,i,f);for(a=new DD((!t.n&&(t.n=new fV(lFt,t,1,7)),t.n));a.e!=a.i.gc();)!oM(gK(zDn(c=uG(Zkn(a),135),FMt)))&&c.a&&kD(h.b,own(c));return oM(gK(oIn(h,gyt)))&&s.Fc((r_n(),Zgt)),oM(gK(oIn(h,uMt)))&&(s.Fc((r_n(),ipt)),s.Fc(ept),kfn(h,JMt,uRt)),h}function KJn(n,t,i,r,c,a,o){var u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S,P,C,I,O,A;for(g=0,P=0,h=new Ww(n.b);h.ag&&(a&&(cL(T,w),cL(E,xwn(f.b-1)),kD(n.d,d),u.c.length=0),O=i.b,A+=w+t,w=0,l=e.Math.max(l,i.b+i.c+I)),mv(u.c,s),uyn(s,O,A),l=e.Math.max(l,O+I+i.c),w=e.Math.max(w,b),O+=I+t,d=s;if(Ohn(n.a,u),kD(n.d,uG(zq(u,u.c.length-1),163)),l=e.Math.max(l,r),(C=A+w+i.a)r.d.d+r.d.a?f.f.d=!0:(f.f.d=!0,f.f.a=!0))),i.b!=i.d.c&&(t=e);f&&(c=uG(cQ(n.f,a.d.i),60),t.bc.d.d+c.d.a?f.f.d=!0:(f.f.d=!0,f.f.a=!0))}for(o=new Fz(ix(qgn(b).a.Kc(),new h));hDn(o);)0!=(a=uG(N9(o),18)).a.b&&(t=uG(pR(a.a),8),a.d.j==(KQn(),yRt)&&((g=new Hqn(t,new MO(t.a,r.d.d),r,a)).f.a=!0,g.a=a.d,mv(d.c,g)),a.d.j==KRt&&((g=new Hqn(t,new MO(t.a,r.d.d+r.d.a),r,a)).f.d=!0,g.a=a.d,mv(d.c,g)))}return d}function GJn(n,t,e){var i,r,c,a,o,u,s,h,f,l;for(u=new Zm,f=t.length,a=Ffn(e),s=0;s=w&&(m>w&&(b.c.length=0,w=m),mv(b.c,a));0!=b.c.length&&(l=uG(zq(b,iMn(t,b.c.length)),131),P.a.Bc(l),l.s=d++,Vxn(l,E,M),b.c.length=0)}for(k=n.c.length+1,o=new Ww(n);o.aS.s&&(LQ(e),men(S.i,i),i.c>0&&(i.a=S,kD(S.t,i),i.b=T,kD(T.i,i)))}function zJn(n,t,e,i,r){var c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E;for(w=new R7(t.b),m=new R7(t.b),l=new R7(t.b),M=new R7(t.b),d=new R7(t.b),y=Fkn(t,0);y.b!=y.d.c;)for(o=new Ww((v=uG(I6(y),12)).g);o.a0,g=v.g.c.length>0,s&&g?mv(l.c,v):s?mv(w.c,v):g&&mv(m.c,v);for(b=new Ww(w);b.av.nh()-h.b&&(b=v.nh()-h.b),w>v.oh()-h.d&&(w=v.oh()-h.d),f0){for(k=Fkn(n.f,0);k.b!=k.d.c;)uG(I6(k),10).p+=w-n.e;kAn(n),BY(n.f),O_n(n,r,d)}else{for(aq(n.f,d),d.p=r,n.e=e.Math.max(n.e,r),a=new Fz(ix(qgn(d).a.Kc(),new h));hDn(a);)(c=uG(N9(a),18)).c.i.c||c.c.i.k!=(zIn(),bbt)||(aq(n.f,c.c.i),c.c.i.p=r-1);n.c=r}else kAn(n),BY(n.f),r=0,hDn(new Fz(ix(qgn(d).a.Kc(),new h)))?O_n(n,r=(w=Pyn(w=0,d))+2,d):(aq(n.f,d),d.p=0,n.e=e.Math.max(n.e,0),n.b=uG(zq(n.d.b,0),30),n.c=0);for(0==n.f.b||kAn(n),n.d.a.c.length=0,v=new Zm,f=new Ww(n.d.b);f.a=48&&t<=57))throw hv(new CM(rZn((t$(),Nit))));for(i=t-48;r=48&&t<=57;)if((i=10*i+t-48)<0)throw hv(new CM(rZn((t$(),Rit))));if(e=i,44==t){if(r>=n.j)throw hv(new CM(rZn((t$(),Dit))));if((t=VJ(n.i,r++))>=48&&t<=57){for(e=t-48;r=48&&t<=57;)if((e=10*e+t-48)<0)throw hv(new CM(rZn((t$(),Rit))));if(i>e)throw hv(new CM(rZn((t$(),xit))))}else e=-1}if(125!=t)throw hv(new CM(rZn((t$(),$it))));n.bm(r)?(QYn(),QYn(),c=new n8(9,c),n.d=r+1):(QYn(),QYn(),c=new n8(3,c),n.d=r),c.Om(i),c.Nm(e),EYn(n)}}return c}function iYn(n){var t,e,i;switch(e=uG(oIn(n,(GYn(),Hpt)),21),t=aN(klt),uG(oIn(n,(jYn(),rMt)),346)==(Own(),Ixt)&&gsn(t,ylt),oM(gK(oIn(n,eMt)))?Aq(t,(uIn(),Tlt),(zYn(),Iwt)):Aq(t,(uIn(),Elt),(zYn(),Iwt)),null!=oIn(n,(K7(),jNt))&&gsn(t,Mlt),(oM(gK(oIn(n,fMt)))||oM(gK(oIn(n,iMt))))&&wz(t,(uIn(),Plt),(zYn(),Ubt)),uG(oIn(n,Byt),88).g){case 2:case 3:case 4:wz(Aq(t,(uIn(),Tlt),(zYn(),qbt)),Plt,Gbt)}switch(e.Hc((r_n(),Zgt))&&wz(Aq(Aq(t,(uIn(),Tlt),(zYn(),Hbt)),Slt,_bt),Plt,Bbt),xA(oIn(n,yMt))!==xA((THn(),$jt))&&Aq(t,(uIn(),Elt),(zYn(),ywt)),e.Hc(apt)&&(Aq(t,(uIn(),Tlt),(zYn(),Pwt)),Aq(t,jlt,Ewt),Aq(t,Elt,Swt)),xA(oIn(n,vyt))!==xA((RIn(),Vgt))&&xA(oIn(n,Vyt))!==xA((_gn(),sxt))&&wz(t,(uIn(),Plt),(zYn(),rwt)),oM(gK(oIn(n,aMt)))&&Aq(t,(uIn(),Elt),(zYn(),iwt)),oM(gK(oIn(n,Ryt)))&&Aq(t,(uIn(),Elt),(zYn(),Dwt)),CRn(n)&&(i=(xA(oIn(n,rMt))===xA(Ixt)?uG(oIn(n,Oyt),299):uG(oIn(n,Ayt),299))==(ihn(),fpt)?(zYn(),jwt):(zYn(),Kwt),Aq(t,(uIn(),Slt),i)),uG(oIn(n,qTt),388).g){case 1:Aq(t,(uIn(),Slt),(zYn(),xwt));break;case 2:wz(Aq(Aq(t,(uIn(),Elt),(zYn(),xbt)),Slt,Rbt),Plt,Kbt)}return xA(oIn(n,Syt))!==xA((yvn(),Fjt))&&Aq(t,(uIn(),Elt),(zYn(),Rwt)),t}function rYn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v;if(PV(n.a,t)){if(cS(uG(cQ(n.a,t),49),e))return 1}else vJ(n.a,t,new ek);if(PV(n.a,e)){if(cS(uG(cQ(n.a,e),49),t))return-1}else vJ(n.a,e,new ek);if(PV(n.e,t)){if(cS(uG(cQ(n.e,t),49),e))return-1}else vJ(n.e,t,new ek);if(PV(n.e,e)){if(cS(uG(cQ(n.a,e),49),t))return 1}else vJ(n.e,e,new ek);if(n.c==(yvn(),_jt)||!vR(t,(GYn(),imt))||!vR(e,(GYn(),imt))){for(f=null,s=new Ww(t.j);s.a(a=_Sn(n,e))?uHn(n,t,e):uHn(n,e,t),ra?1:0}return(i=uG(oIn(t,(GYn(),imt)),17).a)>(c=uG(oIn(e,imt),17).a)?uHn(n,t,e):uHn(n,e,t),ic?1:0}function cYn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b,w,d;if(null==e)return null;if(n.a!=t.jk())throw hv(new vM(tet+t.xe()+eet));if(F$(t,469)){if(!(d=y_n(uG(t,685),e)))throw hv(new vM(iet+e+"' is not a valid enumerator of '"+t.xe()+"'"));return d}switch(tdn((gAn(),kBt),t).Nl()){case 2:e=yXn(e,!1);break;case 3:e=yXn(e,!0)}if(i=tdn(kBt,t).Jl())return i.jk().wi().ti(i,e);if(f=tdn(kBt,t).Ll()){for(d=new Zm,s=0,h=(u=Fln(e)).length;s1)for(b=new Zx((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a));b.e!=b.i.gc();)$Sn(b);for(d=C,C>k+v?d=k+v:Cy+w?g=y+w:Ik-v&&dy-w&&gC+P?T=C+P:kI+M?j=I+M:yC-P&&TI-M&&ji&&(f=i-1),(l=N+uRn(t,24)*z0n*h-h/2)<0?l=1:l>r&&(l=r-1),gj(),Scn(c=new ns,f),pcn(c,l),ttn((!o.a&&(o.a=new MD(eFt,o,5)),o.a),c)}function lYn(n){hP(n,new hCn(FT(DT(KT(RT(new bu,ant),"ELK Rectangle Packing"),"Algorithm for packing of unconnected boxes, i.e. graphs without edges. The given order of the boxes is always preserved and the main reading direction of the boxes is left to right. The algorithm is divided into two phases. One phase approximates the width in which the rectangles can be placed. The next phase places the rectangles in rows using the previously calculated width as bounding width and bundles rectangles with a similar height in blocks. A compaction step reduces the size of the drawing. Finally, the rectangles are expanded to fill their bounding box and eliminate empty unused spaces."),new _o))),U4(n,ant,R3n,1.3),U4(n,ant,d4n,(qx(),!1)),U4(n,ant,K3n,fAt),U4(n,ant,o4n,15),U4(n,ant,r9n,Jkn(WOt)),U4(n,ant,p4n,Jkn(eAt)),U4(n,ant,x4n,Jkn(rAt)),U4(n,ant,g4n,Jkn(cAt)),U4(n,ant,m4n,Jkn(tAt)),U4(n,ant,w4n,Jkn(aAt)),U4(n,ant,v4n,Jkn(lAt)),U4(n,ant,J7n,Jkn(pAt)),U4(n,ant,Y7n,Jkn(gAt)),U4(n,ant,Q7n,Jkn(vAt)),U4(n,ant,W7n,Jkn(mAt)),U4(n,ant,Z7n,Jkn(sAt)),U4(n,ant,nnt,Jkn(uAt)),U4(n,ant,tnt,Jkn(oAt)),U4(n,ant,ent,Jkn(dAt)),U4(n,ant,f4n,Jkn(YOt)),U4(n,ant,g9n,Jkn(ZOt)),U4(n,ant,z7n,Jkn(JOt)),U4(n,ant,X7n,Jkn(QOt)),U4(n,ant,V7n,Jkn(nAt)),U4(n,ant,q7n,Jkn(wAt))}function bYn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S,P,C;if(pXn(),j=n.e,w=n.d,r=n.a,0==j)switch(t){case 0:return"0";case 1:return N0n;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return(M=new WM).a+=t<0?"0E+":"0E",M.a+=-t,M.a}if(k=Inn(JHt,N1n,28,1+(v=10*w+1+7),15,1),e=v,1==w)if((o=r[0])<0){C=E3(o,L0n);do{d=C,C=bSn(C,10),k[--e]=48+pz($gn(d,Ngn(C,10)))&D1n}while(0!=dwn(C,0))}else{C=o;do{d=C,C=C/10|0,k[--e]=d-10*C+48&D1n}while(0!=C)}else{qGn(r,0,S=Inn(YHt,W1n,28,w,15,1),0,P=w);n:for(;;){for(T=0,s=P-1;s>=0;s--)p=JPn(Lgn(Nz(T,32),E3(S[s],L0n))),S[s]=pz(p),T=pz($z(p,32));m=pz(T),g=e;do{k[--e]=48+m%10&D1n}while(0!=(m=m/10|0)&&0!=e);for(i=9-g+e,u=0;u0;u++)k[--e]=48;for(f=P-1;0==S[f];f--)if(0==f)break n;P=f+1}for(;48==k[e];)++e}if(b=j<0,a=v-e-t-1,0==t)return b&&(k[--e]=45),mvn(k,e,v-e);if(t>0&&a>=-6){if(a>=0){for(h=e+a,l=v-1;l>=h;l--)k[l+1]=k[l];return k[++h]=46,b&&(k[--e]=45),mvn(k,e,v-e+1)}for(f=2;f<1-a;f++)k[--e]=48;return k[--e]=46,k[--e]=48,b&&(k[--e]=45),mvn(k,e,v-e)}return E=e+1,c=v,y=new QM,b&&(y.a+="-"),c-E>=1?(jQ(y,k[e]),y.a+=".",y.a+=mvn(k,e+1,v-e-1)):y.a+=mvn(k,e,v-e),y.a+="E",a>0&&(y.a+="+"),y.a+=""+a,y.a}function wYn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y;switch(n.c=t,n.g=new Ym,vP(),Apn(new Ad(new Vy(n.c))),m=mK(zDn(n.c,(fIn(),dLt))),o=uG(zDn(n.c,pLt),324),k=uG(zDn(n.c,mLt),437),c=uG(zDn(n.c,hLt),490),v=uG(zDn(n.c,gLt),438),n.j=uM(pK(zDn(n.c,vLt))),a=n.a,o.g){case 0:a=n.a;break;case 1:a=n.b;break;case 2:a=n.i;break;case 3:a=n.e;break;case 4:a=n.f;break;default:throw hv(new vM(lnt+(null!=o.f?o.f:""+o.g)))}if(n.d=new i0(a,k,c),kfn(n.d,(rsn(),Oht),gK(zDn(n.c,lLt))),n.d.c=oM(gK(zDn(n.c,fLt))),0==wZ(n.c).i)return n.d;for(h=new DD(wZ(n.c));h.e!=h.i.gc();){for(l=(s=uG(Zkn(h),27)).g/2,f=s.f/2,y=new MO(s.i+l,s.j+f);PV(n.g,y);)KR(y,(e.Math.random()-.5)*t4n,(e.Math.random()-.5)*t4n);w=uG(zDn(s,(XYn(),$$t)),140),d=new G0(y,new gY(y.a-l-n.j/2-w.b,y.b-f-n.j/2-w.d,s.g+n.j+(w.b+w.c),s.f+n.j+(w.d+w.a))),kD(n.d.i,d),vJ(n.g,y,new WO(d,s))}switch(v.g){case 0:if(null==m)n.d.d=uG(zq(n.d.i,0),68);else for(p=new Ww(n.d.i);p.a0?S+1:1);for(a=new Ww(y.g);a.a0?S+1:1)}0==n.c[s]?aq(n.e,d):0==n.a[s]&&aq(n.f,d),++s}for(w=-1,b=1,f=new Zm,n.d=uG(oIn(t,(GYn(),dmt)),234);A>0;){for(;0!=n.e.b;)C=uG(tG(n.e),10),n.b[C.p]=w--,iUn(n,C),--A;for(;0!=n.f.b;)I=uG(tG(n.f),10),n.b[I.p]=b++,iUn(n,I),--A;if(A>0){for(l=j1n,m=new Ww(v);m.a=l&&(k>l&&(f.c.length=0,l=k),mv(f.c,d));h=n.sg(f),n.b[h.p]=b++,iUn(n,h),--A}}for(P=v.c.length+1,s=0;sn.b[O]&&(pqn(i,!0),kfn(t,Lpt,(qx(),!0)));n.a=null,n.c=null,n.b=null,BY(n.f),BY(n.e),e.Vg()}function pYn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T;for(M=uG(zrn((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a),0),166),f=new Uk,y=new Ym,T=sGn(M),VAn(y.f,M,T),b=new Ym,r=new lS,d=OV(zcn(Uhn(cT(vat,1),EZn,20,0,[(!t.d&&(t.d=new f_(aFt,t,8,5)),t.d),(!t.e&&(t.e=new f_(aFt,t,7,4)),t.e)])));hDn(d);){if(w=uG(N9(d),74),1!=(!n.a&&(n.a=new fV(oFt,n,6,6)),n.a).i)throw hv(new vM(Ptt+(!n.a&&(n.a=new fV(oFt,n,6,6)),n.a).i));w!=n&&(s8(r,p=uG(zrn((!w.a&&(w.a=new fV(oFt,w,6,6)),w.a),0),166),r.c.b,r.c),(g=uG(DA(FX(y.f,p)),13))||(g=sGn(p),VAn(y.f,p,g)),l=i?YF(new eN(uG(zq(T,T.c.length-1),8)),uG(zq(g,g.c.length-1),8)):YF(new eN((u3(0,T.c.length),uG(T.c[0],8))),(u3(0,g.c.length),uG(g.c[0],8))),VAn(b.f,p,l))}if(0!=r.b)for(m=uG(zq(T,i?T.c.length-1:0),8),h=1;h1&&s8(f,m,f.c.b,f.c),yrn(c)));m=v}return f}function mYn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S;for(e.Ug(o7n,1),S=uG(l8(JJ(new fX(null,new h3(t,16)),new wo),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15),h=uG(l8(JJ(new fX(null,new h3(t,16)),new Lp(t)),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut]))),15),w=uG(l8(JJ(new fX(null,new h3(t,16)),new Ap(t)),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut]))),15),d=Inn(lPt,z9n,40,t.gc(),0,1),a=0;a=0&&E=0&&!d[b]){d[b]=r,h.gd(o),--o;break}if((b=E-l)=0&&!d[b]){d[b]=r,h.gd(o),--o;break}}for(w.jd(new go),u=d.length-1;u>=0;u--)d[u]||w.dc()||(d[u]=uG(w.Xb(0),40),w.gd(0));for(s=0;s=0;u--)aq(e,(u3(u,a.c.length),uG(a.c[u],8)));return e}function kYn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k;for(v=uM(pK(zDn(t,(lBn(),POt)))),b=uM(pK(zDn(t,EOt))),l=uM(pK(zDn(t,MOt))),Non((!t.a&&(t.a=new fV(bFt,t,10,11)),t.a)),p=uzn((!t.a&&(t.a=new fV(bFt,t,10,11)),t.a),v,n.b),g=0;gl&&uEn((u3(l,t.c.length),uG(t.c[l],186)),h),h=null;t.c.length>l&&0==(u3(l,t.c.length),uG(t.c[l],186)).a.c.length;)men(t,(u3(l,t.c.length),t.c[l]));if(!h){--a;continue}if(!oM(gK(uG(zq(h.b,0),27).of((S_n(),nAt))))&&HUn(t,w,c,h,g,e,l,i)){d=!0;continue}if(g){if(b=w.b,f=h.f,!oM(gK(uG(zq(h.b,0),27).of(nAt)))&&EVn(t,w,c,h,e,l,i,r)){if(d=!0,b=n.j)return n.a=-1,void(n.c=1);if(t=VJ(n.i,n.d++),n.a=t,1!=n.b){switch(t){case 124:i=2;break;case 42:i=3;break;case 43:i=4;break;case 63:i=5;break;case 41:i=7;break;case 46:i=8;break;case 91:i=9;break;case 94:i=11;break;case 36:i=12;break;case 40:if(i=6,n.d>=n.j)break;if(63!=VJ(n.i,n.d))break;if(++n.d>=n.j)throw hv(new CM(rZn((t$(),iit))));switch(t=VJ(n.i,n.d++)){case 58:i=13;break;case 61:i=14;break;case 33:i=15;break;case 91:i=19;break;case 62:i=18;break;case 60:if(n.d>=n.j)throw hv(new CM(rZn((t$(),iit))));if(61==(t=VJ(n.i,n.d++)))i=16;else{if(33!=t)throw hv(new CM(rZn((t$(),rit))));i=17}break;case 35:for(;n.d=n.j)throw hv(new CM(rZn((t$(),eit))));n.a=VJ(n.i,n.d++);break;default:i=0}n.c=i}else{switch(t){case 92:if(i=10,n.d>=n.j)throw hv(new CM(rZn((t$(),eit))));n.a=VJ(n.i,n.d++);break;case 45:!(512&~n.e)&&n.df&&(f=d.e.a+d.f.a+b),l=f+u.f.a;break;case 4:f=g.b-b-u.f.b,d.e.b-b-u.f.bf&&(f=d.e.b+d.f.b+b),l=f+u.f.b}else if(d)switch(r.g){case 2:l=(f=d.e.a-b-u.f.a)+u.f.a;break;case 1:l=(f=d.e.a+d.f.a+b)+u.f.a;break;case 4:l=(f=d.e.b-b-u.f.b)+u.f.b;break;case 3:l=(f=d.e.b+d.f.b+b)+u.f.b}xA(oIn(t,uCt))===xA((Pln(),wPt))?(c=f,a=l,null!=(o=lln(JJ(new fX(null,new h3(n.a,16)),new GI(c,a)))).a?r==(xdn(),JDt)||r==YDt?u.e.a=f:u.e.b=f:null!=(o=r==(xdn(),JDt)||r==nxt?lln(JJ(Wrn(new fX(null,new h3(n.a,16))),new Ep(c))):lln(JJ(Wrn(new fX(null,new h3(n.a,16))),new Sp(c)))).a&&(r==JDt||r==YDt?u.e.a=uM(pK((MK(null!=o.a),uG(o.a,42)).a)):u.e.b=uM(pK((MK(null!=o.a),uG(o.a,42)).a))),null!=o.a&&(h=Ten(n.a,(MK(null!=o.a),o.a),0))>0&&h!=uG(oIn(u,ACt),17).a&&(kfn(u,MPt,(qx(),!0)),kfn(u,ACt,xwn(h)))):r==(xdn(),JDt)||r==YDt?u.e.a=f:u.e.b=f}e.Vg()}}function PYn(n){var t,e,i,r,c,a,o,u;for(n.b=1,EYn(n),t=null,0==n.c&&94==n.a?(EYn(n),QYn(),QYn(),HFn(t=new K3(4),0,zct),a=new K3(4)):(QYn(),QYn(),a=new K3(4)),r=!0;1!=(u=n.c);){if(0==u&&93==n.a&&!r){t&&(lWn(t,a),a=t);break}if(e=n.a,i=!1,10==u)switch(e){case 100:case 68:case 119:case 87:case 115:case 83:TXn(a,MUn(e)),i=!0;break;case 105:case 73:case 99:case 67:TXn(a,MUn(e)),(e=-1)<0&&(i=!0);break;case 112:case 80:if(!(o=PNn(n,e)))throw hv(new CM(rZn((t$(),git))));TXn(a,o),i=!0;break;default:e=R_n(n)}else if(24==u&&!r){if(t&&(lWn(t,a),a=t),lWn(a,PYn(n)),0!=n.c||93!=n.a)throw hv(new CM(rZn((t$(),kit))));break}if(EYn(n),!i){if(0==u){if(91==e)throw hv(new CM(rZn((t$(),yit))));if(93==e)throw hv(new CM(rZn((t$(),Mit))));if(45==e&&!r&&93!=n.a)throw hv(new CM(rZn((t$(),Tit))))}if(0!=n.c||45!=n.a||45==e&&r)HFn(a,e,e);else{if(EYn(n),1==(u=n.c))throw hv(new CM(rZn((t$(),mit))));if(0==u&&93==n.a)HFn(a,e,e),HFn(a,45,45);else{if(0==u&&93==n.a||24==u)throw hv(new CM(rZn((t$(),Tit))));if(c=n.a,0==u){if(91==c)throw hv(new CM(rZn((t$(),yit))));if(93==c)throw hv(new CM(rZn((t$(),Mit))));if(45==c)throw hv(new CM(rZn((t$(),Tit))))}else 10==u&&(c=R_n(n));if(EYn(n),e>c)throw hv(new CM(rZn((t$(),Sit))));HFn(a,e,c)}}}r=!1}if(1==n.c)throw hv(new CM(rZn((t$(),mit))));return pxn(a),szn(a),n.b=0,EYn(n),a}function CYn(n,t,e){var i,r,c,a,o,u,s,f,l,b,w,d,g,p,m,v,k,y,M;if(e.Ug("Coffman-Graham Layering",1),0!=t.a.c.length){for(M=uG(oIn(t,(jYn(),wMt)),17).a,u=0,a=0,b=new Ww(t.a);b.a=M||!cvn(m,i))&&(i=CJ(t,f)),a2(m,i),c=new Fz(ix(qgn(m).a.Kc(),new h));hDn(c);)r=uG(N9(c),18),n.a[r.p]||(g=r.c.i,--n.e[g.p],0==n.e[g.p]&&kG(_Cn(w,g),D0n));for(s=f.c.length-1;s>=0;--s)kD(t.b,(u3(s,f.c.length),uG(f.c[s],30)));t.a.c.length=0,e.Vg()}else e.Vg()}function IYn(n,t){var e,i,r,c,a,o,u,s,f,l,b,w,d,g,p,m,v,k;k=!1;do{for(k=!1,c=t?new Lw(n.a.b).a.gc()-2:1;t?c>=0:cuG(oIn(g,imt),17).a)&&(v=!1);if(v){for(o=t?c+1:c-1,a=!1,m=!0,i=!1,s=Fkn(W6(n.a,xwn(o)),0);s.b!=s.d.c;)vR(u=uG(I6(s),10),imt)?u.p!=f.p&&(a|=t?uG(oIn(u,imt),17).auG(oIn(f,imt),17).a,m=!1):!a&&m&&u.k==(zIn(),bbt)&&(i=!0,(l=t?uG(N9(new Fz(ix(qgn(u).a.Kc(),new h))),18).c.i:uG(N9(new Fz(ix(Xgn(u).a.Kc(),new h))),18).d.i)==f&&(e=t?uG(N9(new Fz(ix(Xgn(u).a.Kc(),new h))),18).d.i:uG(N9(new Fz(ix(qgn(u).a.Kc(),new h))),18).c.i,(t?uG(ER(n.a,e),17).a-uG(ER(n.a,l),17).a:uG(ER(n.a,l),17).a-uG(ER(n.a,e),17).a)<=2&&(m=!1)));if(i&&m&&(e=t?uG(N9(new Fz(ix(Xgn(f).a.Kc(),new h))),18).d.i:uG(N9(new Fz(ix(qgn(f).a.Kc(),new h))),18).c.i,(t?uG(ER(n.a,e),17).a-uG(ER(n.a,f),17).a:uG(ER(n.a,f),17).a-uG(ER(n.a,e),17).a)<=2&&e.k==(zIn(),dbt)&&(m=!1)),a||m){for(d=SRn(n,f,t);0!=d.a.gc();)w=uG(d.a.ec().Kc().Pb(),10),d.a.Bc(w),Qon(d,SRn(n,w,t));--b,k=!0}}}}while(k)}function OYn(n){Hxn(n.c,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#decimal"])),Hxn(n.d,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#integer"])),Hxn(n.e,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#boolean"])),Hxn(n.f,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EBoolean",Bet,"EBoolean:Object"])),Hxn(n.i,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#byte"])),Hxn(n.g,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#hexBinary"])),Hxn(n.j,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EByte",Bet,"EByte:Object"])),Hxn(n.n,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EChar",Bet,"EChar:Object"])),Hxn(n.t,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#double"])),Hxn(n.u,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EDouble",Bet,"EDouble:Object"])),Hxn(n.F,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#float"])),Hxn(n.G,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EFloat",Bet,"EFloat:Object"])),Hxn(n.I,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#int"])),Hxn(n.J,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EInt",Bet,"EInt:Object"])),Hxn(n.N,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#long"])),Hxn(n.O,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"ELong",Bet,"ELong:Object"])),Hxn(n.Z,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#short"])),Hxn(n.$,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EShort",Bet,"EShort:Object"])),Hxn(n._,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#string"]))}function AYn(n,t,e,i,r,c,a){var o,u,s,h,f,l,b,w;return l=uG(i.a,17).a,b=uG(i.b,17).a,f=n.b,w=n.c,o=0,h=0,t==(xdn(),JDt)||t==YDt?(h=$I(jdn(ZJ(YJ(new fX(null,new h3(e.b,16)),new mo),new Ya))),f.e.b+f.f.b/2>h?(s=++b,o=uM(pK(yx(Wz(YJ(new fX(null,new h3(e.b,16)),new pO(r,s)),new Za))))):(u=++l,o=uM(pK(yx(Qz(YJ(new fX(null,new h3(e.b,16)),new mO(r,u)),new no)))))):(h=$I(jdn(ZJ(YJ(new fX(null,new h3(e.b,16)),new ro),new Ja))),f.e.a+f.f.a/2>h?(s=++b,o=uM(pK(yx(Wz(YJ(new fX(null,new h3(e.b,16)),new dO(r,s)),new to))))):(u=++l,o=uM(pK(yx(Qz(YJ(new fX(null,new h3(e.b,16)),new gO(r,u)),new eo)))))),t==JDt?(cL(n.a,new MO(uM(pK(oIn(f,(OQn(),DPt))))-r,o)),cL(n.a,new MO(w.e.a+w.f.a+r+c,o)),cL(n.a,new MO(w.e.a+w.f.a+r+c,w.e.b+w.f.b/2)),cL(n.a,new MO(w.e.a+w.f.a,w.e.b+w.f.b/2))):t==YDt?(cL(n.a,new MO(uM(pK(oIn(f,(OQn(),$Pt))))+r,f.e.b+f.f.b/2)),cL(n.a,new MO(f.e.a+f.f.a+r,o)),cL(n.a,new MO(w.e.a-r-c,o)),cL(n.a,new MO(w.e.a-r-c,w.e.b+w.f.b/2)),cL(n.a,new MO(w.e.a,w.e.b+w.f.b/2))):t==nxt?(cL(n.a,new MO(o,uM(pK(oIn(f,(OQn(),DPt))))-r)),cL(n.a,new MO(o,w.e.b+w.f.b+r+c)),cL(n.a,new MO(w.e.a+w.f.a/2,w.e.b+w.f.b+r+c)),cL(n.a,new MO(w.e.a+w.f.a/2,w.e.b+w.f.b+r))):(0==n.a.b||(uG(pR(n.a),8).b=uM(pK(oIn(f,(OQn(),$Pt))))+r*uG(a.b,17).a),cL(n.a,new MO(o,uM(pK(oIn(f,(OQn(),$Pt))))+r*uG(a.b,17).a)),cL(n.a,new MO(o,w.e.b-r*uG(a.a,17).a-c))),new WO(xwn(l),xwn(b))}function LYn(n){var t,e,i,r,c,a,o,u,s,h,f,l,b;if(a=!0,f=null,i=null,r=null,t=!1,b=HFt,s=null,c=null,(u=jkn(n,o=0,YFt,ZFt))=0&&m_(n.substr(o,2),"//")?(Knn(o+=2,u=jkn(n,o,n_t,t_t),n.length),i=n.substr(o,u-o),o=u):null==f||o!=n.length&&(s3(o,n.length),47==n.charCodeAt(o))||(a=!1,-1==(u=cx(n,$Cn(35),o))&&(u=n.length),Knn(o,u,n.length),i=n.substr(o,u-o),o=u);if(!e&&o0&&58==VJ(h,h.length-1)&&(r=h,o=u)),ouxn(c))&&(f=c);for(!f&&(u3(0,d.c.length),f=uG(d.c[0],185)),w=new Ww(t.b);w.al&&(P=0,C+=f+T,f=0),rUn(y,o,P,C),t=e.Math.max(t,P+M.a),f=e.Math.max(f,M.b),P+=M.a+T;for(k=new Ym,i=new Ym,E=new Ww(n);E.a=-1900?1:0,JA(n,e>=4?Uhn(cT($ot,1),zZn,2,6,[Q1n,J1n])[a]:Uhn(cT($ot,1),zZn,2,6,["BC","AD"])[a]);break;case 121:Kkn(n,e,i);break;case 77:tUn(n,e,i);break;case 107:Fen(n,0==(o=r.q.getHours())?24:o,e);break;case 83:PRn(n,e,r);break;case 69:u=i.q.getDay(),JA(n,5==e?Uhn(cT($ot,1),zZn,2,6,["S","M","T","W","T","F","S"])[u]:4==e?Uhn(cT($ot,1),zZn,2,6,[Y1n,Z1n,n0n,t0n,e0n,i0n,r0n])[u]:Uhn(cT($ot,1),zZn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[u]);break;case 97:r.q.getHours()>=12&&r.q.getHours()<24?JA(n,Uhn(cT($ot,1),zZn,2,6,["AM","PM"])[1]):JA(n,Uhn(cT($ot,1),zZn,2,6,["AM","PM"])[0]);break;case 104:Fen(n,0==(s=r.q.getHours()%12)?12:s,e);break;case 75:Fen(n,r.q.getHours()%12,e);break;case 72:Fen(n,r.q.getHours(),e);break;case 99:h=i.q.getDay(),5==e?JA(n,Uhn(cT($ot,1),zZn,2,6,["S","M","T","W","T","F","S"])[h]):4==e?JA(n,Uhn(cT($ot,1),zZn,2,6,[Y1n,Z1n,n0n,t0n,e0n,i0n,r0n])[h]):3==e?JA(n,Uhn(cT($ot,1),zZn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[h]):Fen(n,h,1);break;case 76:f=i.q.getMonth(),5==e?JA(n,Uhn(cT($ot,1),zZn,2,6,["J","F","M","A","M","J","J","A","S","O","N","D"])[f]):4==e?JA(n,Uhn(cT($ot,1),zZn,2,6,[x1n,R1n,K1n,F1n,_1n,B1n,H1n,U1n,G1n,q1n,X1n,z1n])[f]):3==e?JA(n,Uhn(cT($ot,1),zZn,2,6,["Jan","Feb","Mar","Apr",_1n,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"])[f]):Fen(n,f+1,e);break;case 81:l=i.q.getMonth()/3|0,JA(n,e<4?Uhn(cT($ot,1),zZn,2,6,["Q1","Q2","Q3","Q4"])[l]:Uhn(cT($ot,1),zZn,2,6,["1st quarter","2nd quarter","3rd quarter","4th quarter"])[l]);break;case 100:Fen(n,i.q.getDate(),e);break;case 109:Fen(n,r.q.getMinutes(),e);break;case 115:Fen(n,r.q.getSeconds(),e);break;case 122:JA(n,e<4?c.c[0]:c.c[1]);break;case 118:JA(n,c.b);break;case 90:JA(n,e<3?GLn(c):3==e?rNn(c):cNn(c.a));break;default:return!1}return!0}function FYn(n,t,e,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S,P,C;if(iHn(t),u=uG(zrn((!t.b&&(t.b=new f_(cFt,t,4,7)),t.b),0),84),h=uG(zrn((!t.c&&(t.c=new f_(cFt,t,5,8)),t.c),0),84),o=lCn(u),s=lCn(h),a=0==(!t.a&&(t.a=new fV(oFt,t,6,6)),t.a).i?null:uG(zrn((!t.a&&(t.a=new fV(oFt,t,6,6)),t.a),0),166),M=uG(cQ(n.a,o),10),S=uG(cQ(n.a,s),10),T=null,P=null,F$(u,193)&&(F$(y=uG(cQ(n.a,u),305),12)?T=uG(y,12):F$(y,10)&&(M=uG(y,10),T=uG(zq(M.j,0),12))),F$(h,193)&&(F$(E=uG(cQ(n.a,h),305),12)?P=uG(E,12):F$(E,10)&&(S=uG(E,10),P=uG(zq(S.j,0),12))),!M||!S)throw hv(new EM("The source or the target of edge "+t+" could not be found. This usually happens when an edge connects a node laid out by ELK Layered to a node in another level of hierarchy laid out by either another instance of ELK Layered or another layout algorithm alltogether. The former can be solved by setting the hierarchyHandling option to INCLUDE_CHILDREN."));for(zsn(d=new UZ,t),kfn(d,(GYn(),rmt),t),kfn(d,(jYn(),bMt),null),b=uG(oIn(i,Hpt),21),M==S&&b.Fc((r_n(),opt)),T||(can(),k=Wjt,j=null,a&&sN(uG(oIn(M,JMt),101))&&($5(j=new MO(a.j,a.k),s0(t)),Q8(j,e),Ern(s,o)&&(k=Vjt,JF(j,M.n))),T=LXn(M,j,k,i)),P||(can(),k=Vjt,C=null,a&&sN(uG(oIn(S,JMt),101))&&($5(C=new MO(a.b,a.c),s0(t)),Q8(C,e)),P=LXn(S,C,k,HQ(S))),c2(d,T),u2(d,P),(T.e.c.length>1||T.g.c.length>1||P.e.c.length>1||P.g.c.length>1)&&b.Fc((r_n(),ept)),l=new DD((!t.n&&(t.n=new fV(lFt,t,1,7)),t.n));l.e!=l.i.gc();)if(!oM(gK(zDn(f=uG(Zkn(l),135),FMt)))&&f.a)switch(g=own(f),kD(d.b,g),uG(oIn(g,Xyt),278).g){case 1:case 2:b.Fc((r_n(),npt));break;case 0:b.Fc((r_n(),Ygt)),kfn(g,Xyt,(Zrn(),ixt))}if(c=uG(oIn(i,Kyt),322),p=uG(oIn(i,$Mt),323),r=c==(jan(),Ydt)||p==(pyn(),kjt),a&&0!=(!a.a&&(a.a=new MD(eFt,a,5)),a.a).i&&r){for(m=COn(a),w=new Uk,v=Fkn(m,0);v.b!=v.d.c;)aq(w,new eN(uG(I6(v),8)));kfn(d,cmt,w)}return d}function _Yn(n,t,e,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S,P,C,I;for(j=0,E=0,M=new Ym,k=uG(yx(Wz(YJ(new fX(null,new h3(n.b,16)),new io),new fo)),17).a+1,T=Inn(YHt,W1n,28,k,15,1),d=Inn(YHt,W1n,28,k,15,1),w=0;w1)for(o=P+1;ou.b.e.b*(1-g)+u.c.e.b*g));b++);if(y.gc()>0){if(C=0==u.a.b?D$(u.b.e):uG(pR(u.a),8),m=JF(D$(uG(y.Xb(y.gc()-1),40).e),uG(y.Xb(y.gc()-1),40).f),f=JF(D$(uG(y.Xb(0),40).e),uG(y.Xb(0),40).f),b>=y.gc()-1&&C.b>m.b&&u.c.e.b>m.b)continue;if(b<=0&&C.bu.b.e.a*(1-g)+u.c.e.a*g));b++);if(y.gc()>0){if(C=0==u.a.b?D$(u.b.e):uG(pR(u.a),8),m=JF(D$(uG(y.Xb(y.gc()-1),40).e),uG(y.Xb(y.gc()-1),40).f),f=JF(D$(uG(y.Xb(0),40).e),uG(y.Xb(0),40).f),b>=y.gc()-1&&C.a>m.a&&u.c.e.a>m.a)continue;if(b<=0&&C.a=uM(pK(oIn(n,(OQn(),CPt))))&&++E):(l.f&&l.d.e.a<=uM(pK(oIn(n,(OQn(),PPt))))&&++j,l.g&&l.c.e.a+l.c.f.a>=uM(pK(oIn(n,(OQn(),SPt))))&&++E)}else 0==v?hNn(u):v<0&&(++T[P],++d[I],j=uG((S=AYn(u,t,n,new WO(xwn(j),xwn(E)),e,i,new WO(xwn(d[I]),xwn(T[P])))).a,17).a,E=uG(S.b,17).a)}function BYn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m;if(i=t,u=e,n.b&&i.j==(KQn(),_Rt)&&u.j==(KQn(),_Rt)&&(m=i,i=u,u=m),PV(n.a,i)){if(cS(uG(cQ(n.a,i),49),u))return 1}else vJ(n.a,i,new ek);if(PV(n.a,u)){if(cS(uG(cQ(n.a,u),49),i))return-1}else vJ(n.a,u,new ek);if(PV(n.d,i)){if(cS(uG(cQ(n.d,i),49),u))return-1}else vJ(n.d,i,new ek);if(PV(n.d,u)){if(cS(uG(cQ(n.a,u),49),i))return 1}else vJ(n.d,u,new ek);if(i.j!=u.j)return-1==(p=bN(i.j,u.j))?hHn(n,u,i):hHn(n,i,u),p;if(0!=i.e.c.length&&0!=u.e.c.length){if(n.b&&0!=(p=Dbn(i,u)))return-1==p?hHn(n,u,i):1==p&&hHn(n,i,u),p;if((c=uG(zq(i.e,0),18).c.i)==(h=uG(zq(u.e,0),18).c.i))return(r=uG(oIn(uG(zq(i.e,0),18),(GYn(),imt)),17).a)>(s=uG(oIn(uG(zq(u.e,0),18),imt),17).a)?hHn(n,i,u):hHn(n,u,i),rs?1:0;for(d=0,g=(w=n.c).length;d(s=uG(oIn(l,imt),17).a)?hHn(n,i,u):hHn(n,u,i),rs?1:0):n.b&&0!=(p=Dbn(i,u))?(-1==p?hHn(n,u,i):1==p&&hHn(n,i,u),p):(a=0,f=0,vR(uG(zq(i.g,0),18),imt)&&(a=uG(oIn(uG(zq(i.g,0),18),imt),17).a),vR(uG(zq(u.g,0),18),imt)&&(f=uG(oIn(uG(zq(i.g,0),18),imt),17).a),o&&o==l?oM(gK(oIn(uG(zq(i.g,0),18),pmt)))&&!oM(gK(oIn(uG(zq(u.g,0),18),pmt)))?(hHn(n,i,u),1):!oM(gK(oIn(uG(zq(i.g,0),18),pmt)))&&oM(gK(oIn(uG(zq(u.g,0),18),pmt)))?(hHn(n,u,i),-1):(a>f?hHn(n,i,u):hHn(n,u,i),af?1:0):(n.f&&(n.f._b(o)&&(a=uG(n.f.xc(o),17).a),n.f._b(l)&&(f=uG(n.f.xc(l),17).a)),a>f?hHn(n,i,u):hHn(n,u,i),af?1:0))):0!=i.e.c.length&&0!=u.g.c.length?(hHn(n,i,u),1):0!=i.g.c.length&&0!=u.e.c.length?(hHn(n,u,i),-1):vR(i,(GYn(),imt))&&vR(u,imt)?((r=uG(oIn(i,imt),17).a)>(s=uG(oIn(u,imt),17).a)?hHn(n,i,u):hHn(n,u,i),rs?1:0):(hHn(n,u,i),-1)}function HYn(n){n.gb||(n.gb=!0,n.b=Nsn(n,0),Von(n.b,18),Won(n.b,19),n.a=Nsn(n,1),Von(n.a,1),Won(n.a,2),Won(n.a,3),Won(n.a,4),Won(n.a,5),n.o=Nsn(n,2),Von(n.o,8),Von(n.o,9),Won(n.o,10),Won(n.o,11),Won(n.o,12),Won(n.o,13),Won(n.o,14),Won(n.o,15),Won(n.o,16),Won(n.o,17),Won(n.o,18),Won(n.o,19),Won(n.o,20),Won(n.o,21),Won(n.o,22),Won(n.o,23),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),n.p=Nsn(n,3),Von(n.p,2),Von(n.p,3),Von(n.p,4),Von(n.p,5),Won(n.p,6),Won(n.p,7),rrn(n.p),rrn(n.p),n.q=Nsn(n,4),Von(n.q,8),n.v=Nsn(n,5),Won(n.v,9),rrn(n.v),rrn(n.v),rrn(n.v),n.w=Nsn(n,6),Von(n.w,2),Von(n.w,3),Von(n.w,4),Won(n.w,5),n.B=Nsn(n,7),Won(n.B,1),rrn(n.B),rrn(n.B),rrn(n.B),n.Q=Nsn(n,8),Won(n.Q,0),rrn(n.Q),n.R=Nsn(n,9),Von(n.R,1),n.S=Nsn(n,10),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),n.T=Nsn(n,11),Won(n.T,10),Won(n.T,11),Won(n.T,12),Won(n.T,13),Won(n.T,14),rrn(n.T),rrn(n.T),n.U=Nsn(n,12),Von(n.U,2),Von(n.U,3),Won(n.U,4),Won(n.U,5),Won(n.U,6),Won(n.U,7),rrn(n.U),n.V=Nsn(n,13),Won(n.V,10),n.W=Nsn(n,14),Von(n.W,18),Von(n.W,19),Von(n.W,20),Won(n.W,21),Won(n.W,22),Won(n.W,23),n.bb=Nsn(n,15),Von(n.bb,10),Von(n.bb,11),Von(n.bb,12),Von(n.bb,13),Von(n.bb,14),Von(n.bb,15),Von(n.bb,16),Won(n.bb,17),rrn(n.bb),rrn(n.bb),n.eb=Nsn(n,16),Von(n.eb,2),Von(n.eb,3),Von(n.eb,4),Von(n.eb,5),Von(n.eb,6),Von(n.eb,7),Won(n.eb,8),Won(n.eb,9),n.ab=Nsn(n,17),Von(n.ab,0),Von(n.ab,1),n.H=Nsn(n,18),Won(n.H,0),Won(n.H,1),Won(n.H,2),Won(n.H,3),Won(n.H,4),Won(n.H,5),rrn(n.H),n.db=Nsn(n,19),Won(n.db,2),n.c=$sn(n,20),n.d=$sn(n,21),n.e=$sn(n,22),n.f=$sn(n,23),n.i=$sn(n,24),n.g=$sn(n,25),n.j=$sn(n,26),n.k=$sn(n,27),n.n=$sn(n,28),n.r=$sn(n,29),n.s=$sn(n,30),n.t=$sn(n,31),n.u=$sn(n,32),n.fb=$sn(n,33),n.A=$sn(n,34),n.C=$sn(n,35),n.D=$sn(n,36),n.F=$sn(n,37),n.G=$sn(n,38),n.I=$sn(n,39),n.J=$sn(n,40),n.L=$sn(n,41),n.M=$sn(n,42),n.N=$sn(n,43),n.O=$sn(n,44),n.P=$sn(n,45),n.X=$sn(n,46),n.Y=$sn(n,47),n.Z=$sn(n,48),n.$=$sn(n,49),n._=$sn(n,50),n.cb=$sn(n,51),n.K=$sn(n,52))}function UYn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E;for(a=new lS,v=uG(oIn(e,(jYn(),Byt)),88),d=0,Qon(a,(!t.a&&(t.a=new fV(bFt,t,10,11)),t.a));0!=a.b;)(xA(zDn(s=R0(h=uG(0==a.b?null:(MK(0!=a.b),Lrn(a,a.a.a)),27)),Syt))!==xA((yvn(),Fjt))||xA(zDn(s,Fyt))===xA((kvn(),lgt))||xA(zDn(s,Fyt))===xA((kvn(),hgt))||oM(gK(zDn(s,Cyt)))||xA(zDn(s,kyt))!==xA((Uvn(),tbt))||xA(zDn(s,yMt))===xA((THn(),Pjt))||xA(zDn(s,yMt))===xA((THn(),Cjt))||xA(zDn(s,MMt))===xA((MKn(),JTt))||xA(zDn(s,MMt))===xA((MKn(),ZTt)))&&!oM(gK(zDn(h,jyt)))&&Myn(h,(GYn(),imt),xwn(d++)),!oM(gK(zDn(h,FMt)))&&(l=0!=(!h.a&&(h.a=new fV(bFt,h,10,11)),h.a).i,w=oCn(h),b=xA(zDn(h,rMt))===xA((Own(),Ixt)),p=null,(E=!vnn(h,(XYn(),e$t))||L9(mK(zDn(h,e$t))))&&b&&(l||w)&&(kfn(p=PGn(h),Byt,v),vR(p,fTt)&&iM(new omn(uM(pK(oIn(p,fTt)))),p),0!=uG(zDn(h,DMt),181).gc()&&(f=p,kS(new fX(null,(!h.c&&(h.c=new fV(wFt,h,9,9)),new h3(h.c,16))),new Yd(f)),u_n(h,p))),k=e,(y=uG(cQ(n.a,R0(h)),10))&&(k=y.e),g=RJn(n,h,k),p&&(g.e=p,p.e=g,Qon(a,(!h.a&&(h.a=new fV(bFt,h,10,11)),h.a))));for(d=0,s8(a,t,a.c.b,a.c);0!=a.b;){for(u=new DD((!(c=uG(0==a.b?null:(MK(0!=a.b),Lrn(a,a.a.a)),27)).b&&(c.b=new fV(aFt,c,12,3)),c.b));u.e!=u.i.gc();)iHn(o=uG(Zkn(u),74)),(xA(zDn(t,Syt))!==xA((yvn(),Fjt))||xA(zDn(t,Fyt))===xA((kvn(),lgt))||xA(zDn(t,Fyt))===xA((kvn(),hgt))||oM(gK(zDn(t,Cyt)))||xA(zDn(t,kyt))!==xA((Uvn(),tbt))||xA(zDn(t,yMt))===xA((THn(),Pjt))||xA(zDn(t,yMt))===xA((THn(),Cjt))||xA(zDn(t,MMt))===xA((MKn(),JTt))||xA(zDn(t,MMt))===xA((MKn(),ZTt)))&&Myn(o,(GYn(),imt),xwn(d++)),T=lCn(uG(zrn((!o.b&&(o.b=new f_(cFt,o,4,7)),o.b),0),84)),j=lCn(uG(zrn((!o.c&&(o.c=new f_(cFt,o,5,8)),o.c),0),84)),oM(gK(zDn(o,FMt)))||oM(gK(zDn(T,FMt)))||oM(gK(zDn(j,FMt)))||(m=c,BNn(o)&&oM(gK(zDn(T,sMt)))&&oM(gK(zDn(o,hMt)))||Ern(j,T)?m=T:Ern(T,j)&&(m=j),k=e,(y=uG(cQ(n.a,m),10))&&(k=y.e),kfn(FYn(n,o,m,k),(GYn(),Ipt),SFn(n,o,t,e)));if(b=xA(zDn(c,rMt))===xA((Own(),Ixt)))for(r=new DD((!c.a&&(c.a=new fV(bFt,c,10,11)),c.a));r.e!=r.i.gc();)E=!vnn(i=uG(Zkn(r),27),(XYn(),e$t))||L9(mK(zDn(i,e$t))),M=xA(zDn(i,rMt))===xA(Ixt),E&&M&&s8(a,i,a.c.b,a.c)}}function GYn(){var n,t;GYn=E,rmt=new Cm(E4n),Ipt=new Cm("coordinateOrigin"),wmt=new Cm("processors"),Cpt=new uF("compoundNode",(qx(),!1)),qpt=new uF("insideConnections",!1),cmt=new Cm("originalBendpoints"),amt=new Cm("originalDummyNodePosition"),omt=new Cm("originalLabelEdge"),gmt=new Cm("representedLabels"),$pt=new Cm("endLabels"),Dpt=new Cm("endLabel.origin"),Qpt=new uF("labelSide",(Ajn(),Rxt)),emt=new uF("maxEdgeThickness",0),pmt=new uF("reversed",!1),dmt=new Cm(S4n),Zpt=new uF("longEdgeSource",null),nmt=new uF("longEdgeTarget",null),Ypt=new uF("longEdgeHasLabelDummies",!1),Jpt=new uF("longEdgeBeforeLabelDummy",!1),Npt=new uF("edgeConstraint",(Pfn(),kgt)),zpt=new Cm("inLayerLayoutUnit"),Xpt=new uF("inLayerConstraint",(Zen(),gpt)),Vpt=new uF("inLayerSuccessorConstraint",new Zm),Wpt=new uF("inLayerSuccessorConstraintBetweenNonDummies",!1),lmt=new Cm("portDummy"),Opt=new uF("crossingHint",xwn(0)),Hpt=new uF("graphProperties",new nB(t=uG(Mj(bpt),9),uG(MF(t,t.length),9),0)),Fpt=new uF("externalPortSide",(KQn(),FRt)),_pt=new uF("externalPortSize",new sj),Rpt=new Cm("externalPortReplacedDummies"),Kpt=new Cm("externalPortReplacedDummy"),xpt=new uF("externalPortConnections",new nB(n=uG(Mj(YRt),9),uG(MF(n,n.length),9),0)),bmt=new uF(i3n,0),jpt=new Cm("barycenterAssociates"),Pmt=new Cm("TopSideComments"),Ept=new Cm("BottomSideComments"),Ppt=new Cm("CommentConnectionPort"),Gpt=new uF("inputCollect",!1),hmt=new uF("outputCollect",!1),Lpt=new uF("cyclic",!1),Apt=new Cm("crossHierarchyMap"),Smt=new Cm("targetOffset"),new uF("splineLabelSize",new sj),kmt=new Cm("spacings"),fmt=new uF("partitionConstraint",!1),Spt=new Cm("breakingPoint.info"),jmt=new Cm("splines.survivingEdge"),Tmt=new Cm("splines.route.start"),ymt=new Cm("splines.edgeChain"),smt=new Cm("originalPortConstraints"),vmt=new Cm("selfLoopHolder"),Mmt=new Cm("splines.nsPortY"),imt=new Cm("modelOrder"),tmt=new Cm("longEdgeTargetNode"),Bpt=new uF(_6n,!1),mmt=new uF(_6n,!1),Upt=new Cm("layerConstraints.hiddenNodes"),umt=new Cm("layerConstraints.opposidePort"),Emt=new Cm("targetNode.modelOrder")}function qYn(n,t,i,r){var c,a,o,u,s,h,f,l,b,w,d;for(l=Fkn(n.b,0);l.b!=l.d.c;)if(!m_((f=uG(I6(l),40)).c,H9n))for(a=uG(l8(new fX(null,new h3(zNn(f,n),16)),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15),t==(xdn(),JDt)||t==YDt?a.jd(new oo):a.jd(new uo),d=a.gc(),c=0;c0&&(u=uG(pR(uG(a.Xb(c),65).a),8).a,b=f.e.a+f.f.a/2,s=uG(pR(uG(a.Xb(c),65).a),8).b,w=f.e.b+f.f.b/2,r>0&&e.Math.abs(s-w)/(e.Math.abs(u-b)/40)>50&&cL(uG(a.Xb(c),65).a,new MO(f.e.a+f.f.a+r/5.3,w>s?f.e.b+f.f.b*o-r/2:f.e.b+f.f.b*o+r/2))),cL(uG(a.Xb(c),65).a,new MO(f.e.a+f.f.a,f.e.b+f.f.b*o))):t==YDt?(h=uM(pK(oIn(f,(OQn(),DPt)))),f.e.a-r>h?cL(uG(a.Xb(c),65).a,new MO(h-i,f.e.b+f.f.b*o)):uG(a.Xb(c),65).a.b>0&&(u=uG(pR(uG(a.Xb(c),65).a),8).a,b=f.e.a+f.f.a/2,s=uG(pR(uG(a.Xb(c),65).a),8).b,w=f.e.b+f.f.b/2,r>0&&e.Math.abs(s-w)/(e.Math.abs(u-b)/40)>50&&cL(uG(a.Xb(c),65).a,new MO(f.e.a-r/5.3,w>s?f.e.b+f.f.b*o-r/2:f.e.b+f.f.b*o+r/2))),cL(uG(a.Xb(c),65).a,new MO(f.e.a,f.e.b+f.f.b*o))):t==nxt?(h=uM(pK(oIn(f,(OQn(),$Pt)))),f.e.b+f.f.b+r0&&(u=uG(pR(uG(a.Xb(c),65).a),8).a,b=f.e.a+f.f.a/2,s=uG(pR(uG(a.Xb(c),65).a),8).b,w=f.e.b+f.f.b/2,r>0&&e.Math.abs(u-b)/(e.Math.abs(s-w)/40)>50&&cL(uG(a.Xb(c),65).a,new MO(b>u?f.e.a+f.f.a*o-r/2:f.e.a+f.f.a*o+r/2,f.e.b+r/5.3+f.f.b))),cL(uG(a.Xb(c),65).a,new MO(f.e.a+f.f.a*o,f.e.b+f.f.b))):(h=uM(pK(oIn(f,(OQn(),DPt)))),uln(uG(a.Xb(c),65),n)?cL(uG(a.Xb(c),65).a,new MO(f.e.a+f.f.a*o,uG(pR(uG(a.Xb(c),65).a),8).b)):f.e.b-r>h?cL(uG(a.Xb(c),65).a,new MO(f.e.a+f.f.a*o,h-i)):uG(a.Xb(c),65).a.b>0&&(u=uG(pR(uG(a.Xb(c),65).a),8).a,b=f.e.a+f.f.a/2,s=uG(pR(uG(a.Xb(c),65).a),8).b,w=f.e.b+f.f.b/2,r>0&&e.Math.abs(u-b)/(e.Math.abs(s-w)/40)>50&&cL(uG(a.Xb(c),65).a,new MO(b>u?f.e.a+f.f.a*o-r/2:f.e.a+f.f.a*o+r/2,f.e.b-r/5.3))),cL(uG(a.Xb(c),65).a,new MO(f.e.a+f.f.a*o,f.e.b)))}function XYn(){var n,t;XYn=E,e$t=new Cm(Vnt),yDt=new Cm(Wnt),nMn(),i$t=new mL(X8n,r$t=CNt),new Jm,c$t=new mL(R3n,null),a$t=new Cm(Qnt),ZSn(),b$t=WX(ZNt,Uhn(cT(txt,1),p1n,298,0,[WNt])),l$t=new mL(r9n,b$t),w$t=new mL(q8n,(qx(),!1)),xdn(),d$t=new mL(W8n,g$t=ZDt),_gn(),k$t=new mL(m8n,y$t=fxt),j$t=new mL(Xnt,!1),Own(),E$t=new mL(b8n,S$t=Oxt),Q$t=new CN(12),W$t=new mL(K3n,Q$t),O$t=new mL(f4n,!1),A$t=new mL(g9n,!1),V$t=new mL(w4n,!1),$Pn(),sDt=new mL(l4n,hDt=sRt),mDt=new Cm(b9n),vDt=new Cm(a4n),kDt=new Cm(s4n),TDt=new Cm(h4n),N$t=new Uk,L$t=new mL(c9n,N$t),f$t=new mL(u9n,!1),P$t=new mL(s9n,!1),new Cm(Jnt),D$t=new Nk,$$t=new mL(w9n,D$t),z$t=new mL(U8n,!1),new Jm,MDt=new mL(Ynt,1),h$t=new Cm(Znt),s$t=new Cm(ntt),HDt=new mL(k4n,!1),new mL(ttt,!0),xwn(0),new mL(ett,xwn(100)),new mL(itt,!1),xwn(0),new mL(rtt,xwn(4e3)),xwn(0),new mL(ctt,xwn(400)),new mL(att,!1),new mL(ott,!1),new mL(utt,!0),new mL(stt,!1),qpn(),o$t=new mL(znt,u$t=TKt),jDt=new mL(A8n,10),EDt=new mL(L8n,10),SDt=new mL(D3n,20),PDt=new mL(N8n,10),CDt=new mL(u4n,2),IDt=new mL($8n,10),ADt=new mL(D8n,0),LDt=new mL(K8n,5),NDt=new mL(x8n,1),$Dt=new mL(R8n,1),DDt=new mL(o4n,20),xDt=new mL(F8n,10),FDt=new mL(_8n,10),ODt=new Cm(B8n),KDt=new qL,RDt=new mL(d9n,KDt),Z$t=new Cm(l9n),J$t=new mL(f9n,Y$t=!1),R$t=new CN(5),x$t=new mL(Q8n,R$t),VDn(),t=uG(Mj(eRt),9),F$t=new nB(t,uG(MF(t,t.length),9),0),K$t=new mL(m4n,F$t),Vkn(),tDt=new mL(Z8n,eDt=Zxt),rDt=new Cm(n9n),cDt=new Cm(t9n),aDt=new Cm(e9n),iDt=new Cm(i9n),n=uG(Mj(sKt),9),B$t=new nB(n,uG(MF(n,n.length),9),0),_$t=new mL(p4n,B$t),X$t=ggn((oUn(),eKt)),q$t=new mL(g4n,X$t),G$t=new MO(0,0),U$t=new mL(x4n,G$t),H$t=new mL(d4n,!1),Zrn(),m$t=new mL(a9n,v$t=ixt),p$t=new mL(b4n,!1),new Cm(htt),xwn(1),new mL(ftt,null),oDt=new Cm(h9n),fDt=new Cm(o9n),KQn(),gDt=new mL(G8n,pDt=FRt),uDt=new Cm(H8n),eNn(),wDt=ggn(gRt),bDt=new mL(v4n,wDt),lDt=new mL(J8n,!1),dDt=new mL(Y8n,!0),new Jm,XDt=new mL(y4n,1),VDt=new mL(ltt,null),BDt=new mL(M4n,150),_Dt=new mL(T4n,1.414),UDt=new mL(j4n,null),GDt=new mL(btt,1),C$t=new mL(z8n,!1),I$t=new mL(V8n,!1),M$t=new mL(x3n,1),RCn(),new mL(wtt,T$t=mxt),nDt=!0,Iwn(),zDt=fKt,WDt=fKt,qDt=fKt}function zYn(){zYn=E,qbt=new CC("DIRECTION_PREPROCESSOR",0),Hbt=new CC("COMMENT_PREPROCESSOR",1),Xbt=new CC("EDGE_AND_LAYER_CONSTRAINT_EDGE_REVERSER",2),uwt=new CC("INTERACTIVE_EXTERNAL_PORT_POSITIONER",3),Pwt=new CC("PARTITION_PREPROCESSOR",4),lwt=new CC("LABEL_DUMMY_INSERTER",5),Nwt=new CC("SELF_LOOP_PREPROCESSOR",6),pwt=new CC("LAYER_CONSTRAINT_PREPROCESSOR",7),Ewt=new CC("PARTITION_MIDPROCESSOR",8),iwt=new CC("HIGH_DEGREE_NODE_LAYER_PROCESSOR",9),ywt=new CC("NODE_PROMOTION",10),gwt=new CC("LAYER_CONSTRAINT_POSTPROCESSOR",11),Swt=new CC("PARTITION_POSTPROCESSOR",12),Zbt=new CC("HIERARCHICAL_PORT_CONSTRAINT_PROCESSOR",13),Dwt=new CC("SEMI_INTERACTIVE_CROSSMIN_PROCESSOR",14),xbt=new CC("BREAKING_POINT_INSERTER",15),kwt=new CC("LONG_EDGE_SPLITTER",16),Iwt=new CC("PORT_SIDE_PROCESSOR",17),swt=new CC("INVERTED_PORT_PROCESSOR",18),Cwt=new CC("PORT_LIST_SORTER",19),Rwt=new CC("SORT_BY_INPUT_ORDER_OF_MODEL",20),Twt=new CC("NORTH_SOUTH_PORT_PREPROCESSOR",21),Rbt=new CC("BREAKING_POINT_PROCESSOR",22),jwt=new CC(p6n,23),Kwt=new CC(m6n,24),Awt=new CC("SELF_LOOP_PORT_RESTORER",25),xwt=new CC("SINGLE_EDGE_GRAPH_WRAPPER",26),hwt=new CC("IN_LAYER_CONSTRAINT_PROCESSOR",27),Qbt=new CC("END_NODE_PORT_LABEL_MANAGEMENT_PROCESSOR",28),fwt=new CC("LABEL_AND_NODE_SIZE_PROCESSOR",29),owt=new CC("INNERMOST_NODE_MARGIN_CALCULATOR",30),$wt=new CC("SELF_LOOP_ROUTER",31),_bt=new CC("COMMENT_NODE_MARGIN_CALCULATOR",32),Vbt=new CC("END_LABEL_PREPROCESSOR",33),wwt=new CC("LABEL_DUMMY_SWITCHER",34),Fbt=new CC("CENTER_LABEL_MANAGEMENT_PROCESSOR",35),dwt=new CC("LABEL_SIDE_SELECTOR",36),cwt=new CC("HYPEREDGE_DUMMY_MERGER",37),nwt=new CC("HIERARCHICAL_PORT_DUMMY_SIZE_PROCESSOR",38),mwt=new CC("LAYER_SIZE_AND_GRAPH_HEIGHT_CALCULATOR",39),ewt=new CC("HIERARCHICAL_PORT_POSITION_PROCESSOR",40),Ubt=new CC("CONSTRAINTS_POSTPROCESSOR",41),Bbt=new CC("COMMENT_POSTPROCESSOR",42),awt=new CC("HYPERNODE_PROCESSOR",43),twt=new CC("HIERARCHICAL_PORT_ORTHOGONAL_EDGE_ROUTER",44),vwt=new CC("LONG_EDGE_JOINER",45),Lwt=new CC("SELF_LOOP_POSTPROCESSOR",46),Kbt=new CC("BREAKING_POINT_REMOVER",47),Mwt=new CC("NORTH_SOUTH_PORT_POSTPROCESSOR",48),rwt=new CC("HORIZONTAL_COMPACTOR",49),bwt=new CC("LABEL_DUMMY_REMOVER",50),Jbt=new CC("FINAL_SPLINE_BENDPOINTS_CALCULATOR",51),Wbt=new CC("END_LABEL_SORTER",52),Owt=new CC("REVERSED_EDGE_RESTORER",53),zbt=new CC("END_LABEL_POSTPROCESSOR",54),Ybt=new CC("HIERARCHICAL_NODE_RESIZER",55),Gbt=new CC("DIRECTION_POSTPROCESSOR",56)}function VYn(){VYn=E,Vin(),mvt=new mL(B6n,vvt=dgt),xvt=new mL(H6n,(qx(),!1)),Y6(),Bvt=new mL(U6n,Hvt=kpt),akt=new mL(G6n,!1),okt=new mL(q6n,!0),Dmt=new mL(X6n,!1),nin(),Skt=new mL(z6n,Pkt=Gjt),xwn(1),Dkt=new mL(V6n,xwn(7)),xkt=new mL(W6n,!1),Rvt=new mL(Q6n,!1),kvn(),gvt=new mL(J6n,pvt=sgt),MKn(),rkt=new mL(Y6n,ckt=rjt),Gpn(),Vvt=new mL(Z6n,Wvt=Lmt),xwn(-1),zvt=new mL(n5n,null),xwn(-1),Qvt=new mL(t5n,xwn(-1)),xwn(-1),Jvt=new mL(e5n,xwn(4)),xwn(-1),Zvt=new mL(i5n,xwn(2)),THn(),ekt=new mL(r5n,ikt=$jt),xwn(0),tkt=new mL(c5n,xwn(0)),qvt=new mL(a5n,xwn(vZn)),jan(),wvt=new mL(o5n,dvt=Zdt),Jmt=new mL(u5n,!1),avt=new mL(s5n,.1),lvt=new mL(h5n,!1),uvt=new mL(f5n,null),svt=new mL(l5n,null),xwn(-1),hvt=new mL(b5n,null),xwn(-1),fvt=new mL(w5n,xwn(-1)),xwn(0),Ymt=new mL(d5n,xwn(40)),ihn(),ivt=new mL(g5n,rvt=lpt),Zmt=new mL(p5n,nvt=hpt),pyn(),jkt=new mL(m5n,Ekt=vjt),wkt=new Cm(v5n),Wtn(),ukt=new mL(k5n,skt=Lgt),ESn(),fkt=new mL(y5n,lkt=Fgt),new Jm,pkt=new mL(M5n,.3),vkt=new Cm(T5n),Yyn(),kkt=new mL(j5n,ykt=djt),isn(),Svt=new mL(E5n,Pvt=nEt),Sln(),Cvt=new mL(S5n,Ivt=aEt),kbn(),Ovt=new mL(P5n,Avt=fEt),Nvt=new mL(C5n,.2),jvt=new mL(I5n,2),Akt=new mL(O5n,null),Nkt=new mL(A5n,10),Lkt=new mL(L5n,10),$kt=new mL(N5n,20),xwn(0),Ckt=new mL($5n,xwn(0)),xwn(0),Ikt=new mL(D5n,xwn(0)),xwn(0),Okt=new mL(x5n,xwn(0)),xmt=new mL(R5n,!1),RIn(),Fmt=new mL(K5n,_mt=Vgt),H7(),Rmt=new mL(F5n,Kmt=Wdt),Fvt=new mL(_5n,!1),xwn(0),Kvt=new mL(B5n,xwn(16)),xwn(0),_vt=new mL(H5n,xwn(5)),zhn(),ryt=new mL(U5n,cyt=kEt),Rkt=new mL(G5n,10),_kt=new mL(q5n,1),ran(),Vkt=new mL(X5n,Wkt=cgt),Ukt=new Cm(z5n),Xkt=xwn(1),xwn(0),qkt=new mL(V5n,Xkt),ian(),syt=new mL(W5n,hyt=wEt),ayt=new Cm(Q5n),nyt=new mL(J5n,!0),Ykt=new mL(Y5n,2),eyt=new mL(Z5n,!0),tOn(),Mvt=new mL(n8n,Tvt=Cgt),vAn(),kvt=new mL(t8n,yvt=Hdt),yvn(),Wmt=new mL(e8n,Qmt=Fjt),Vmt=new mL(i8n,!1),zmt=new mL(r8n,!1),Uvn(),Bmt=new mL(c8n,Hmt=tbt),Cwn(),qmt=new mL(a8n,Xmt=ujt),Umt=new mL(o8n,0),Gmt=new mL(u8n,0),Gvt=fgt,Uvt=Ydt,Yvt=ijt,nkt=ijt,Xvt=YTt,Own(),ovt=Ixt,bvt=Zdt,cvt=Zdt,tvt=Zdt,evt=Ixt,dkt=Mjt,gkt=vjt,hkt=vjt,bkt=vjt,mkt=yjt,Tkt=Mjt,Mkt=Mjt,_gn(),Lvt=hxt,$vt=hxt,Dvt=fEt,Evt=sxt,Kkt=yEt,Fkt=vEt,Bkt=yEt,Hkt=vEt,Qkt=yEt,Jkt=vEt,Gkt=rgt,zkt=cgt,fyt=yEt,lyt=vEt,oyt=yEt,uyt=vEt,tyt=vEt,Zkt=vEt,iyt=vEt}function WYn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S,P,C,I,O,A,L,N,$,D,x,R,K,F,_,B,H,U,G,q,X,z,V,W,Q,J,Y,Z,nn,tn,en,rn,cn,an,on,un;for(Y=0,N=0,x=(O=t).length;N0&&(n.a[U.p]=Y++)}for(rn=0,$=0,R=(A=i).length;$0;){for(MK(z.b>0),X=0,u=new Ww((U=uG(z.a.Xb(z.c=--z.b),12)).e);u.a0&&(U.j==(KQn(),yRt)?(n.a[U.p]=rn,++rn):(n.a[U.p]=rn+K+_,++_))}rn+=_}for(q=new Ym,d=new XL,L=0,D=(I=t).length;Lh.b&&(h.b=V)):U.i.c==J&&(Vh.c&&(h.c=V));for(Ntn(g,0,g.length,null),en=Inn(YHt,W1n,28,g.length,15,1),r=Inn(YHt,W1n,28,rn+1,15,1),m=0;m0;)j%2>0&&(c+=on[j+1]),++on[j=(j-1)/2|0];for(S=Inn(ZEt,EZn,374,2*g.length,0,1),y=0;y0&&(A1(O.f),0)){if(uG(zDn(g,UDt),280)==fKt)throw hv(new jM("Topdown Layout Providers should only be used on parallel nodes."));XA(A1(O.f)),null.Um(),vN(g,e.Math.max(g.g,null.Vm),e.Math.max(g.f,null.Vm))}else null!=zDn(g,VDt)&&(H=uG(zDn(g,VDt),347).Tg(g),vN(g,e.Math.max(g.g,H.a),e.Math.max(g.f,H.b)));if(D=uG(zDn(t,W$t),107),b=t.g-(D.b+D.c),l=t.f-(D.d+D.a),G.bh("Available Child Area: ("+b+"|"+l+")"),Myn(t,c$t,b/l),Mkn(t,c,r.eh(N)),uG(zDn(t,UDt),280)==bKt&&(VJn(t),vN(t,D.b+uM(pK(zDn(t,h$t)))+D.c,D.d+uM(pK(zDn(t,s$t)))+D.a)),G.bh("Executed layout algorithm: "+mK(zDn(t,e$t))+" on node "+t.k),uG(zDn(t,UDt),280)==fKt){if(b<0||l<0)throw hv(new jM("The size defined by the parent parallel node is too small for the space provided by the paddings of the child hierarchical node. "+t.k));for(vnn(t,h$t)||vnn(t,s$t)||VJn(t),d=uM(pK(zDn(t,h$t))),w=uM(pK(zDn(t,s$t))),G.bh("Desired Child Area: ("+d+"|"+w+")"),R=b/d,K=l/w,x=e.Math.min(R,e.Math.min(K,uM(pK(zDn(t,GDt))))),Myn(t,XDt,x),G.bh(t.k+" -- Local Scale Factor (X|Y): ("+R+"|"+K+")"),v=uG(zDn(t,l$t),21),a=0,o=0,x'?":m_(rit,n)?"'(?<' or '(? toIndex: ",s2n=", toIndex: ",h2n="Index: ",f2n=", Size: ",l2n="org.eclipse.elk.alg.common",b2n={50:1},w2n="org.eclipse.elk.alg.common.compaction",d2n="Scanline/EventHandler",g2n="org.eclipse.elk.alg.common.compaction.oned",p2n="CNode belongs to another CGroup.",m2n="ISpacingsHandler/1",v2n="The ",k2n=" instance has been finished already.",y2n="The direction ",M2n=" is not supported by the CGraph instance.",T2n="OneDimensionalCompactor",j2n="OneDimensionalCompactor/lambda$0$Type",E2n="Quadruplet",S2n="ScanlineConstraintCalculator",P2n="ScanlineConstraintCalculator/ConstraintsScanlineHandler",C2n="ScanlineConstraintCalculator/ConstraintsScanlineHandler/lambda$0$Type",I2n="ScanlineConstraintCalculator/Timestamp",O2n="ScanlineConstraintCalculator/lambda$0$Type",A2n={178:1,46:1},L2n="org.eclipse.elk.alg.common.compaction.options",N2n="org.eclipse.elk.core.data",$2n="org.eclipse.elk.polyomino.traversalStrategy",D2n="org.eclipse.elk.polyomino.lowLevelSort",x2n="org.eclipse.elk.polyomino.highLevelSort",R2n="org.eclipse.elk.polyomino.fill",K2n={134:1},F2n="polyomino",_2n="org.eclipse.elk.alg.common.networksimplex",B2n={183:1,3:1,4:1},H2n="org.eclipse.elk.alg.common.nodespacing",U2n="org.eclipse.elk.alg.common.nodespacing.cellsystem",G2n="CENTER",q2n={217:1,336:1},X2n={3:1,4:1,5:1,603:1},z2n="LEFT",V2n="RIGHT",W2n="Vertical alignment cannot be null",Q2n="BOTTOM",J2n="org.eclipse.elk.alg.common.nodespacing.internal",Y2n="UNDEFINED",Z2n=.01,n3n="org.eclipse.elk.alg.common.nodespacing.internal.algorithm",t3n="LabelPlacer/lambda$0$Type",e3n="LabelPlacer/lambda$1$Type",i3n="portRatioOrPosition",r3n="org.eclipse.elk.alg.common.overlaps",c3n="DOWN",a3n="org.eclipse.elk.alg.common.polyomino",o3n="NORTH",u3n="EAST",s3n="SOUTH",h3n="WEST",f3n="org.eclipse.elk.alg.common.polyomino.structures",l3n="Direction",b3n="Grid is only of size ",w3n=". Requested point (",d3n=") is out of bounds.",g3n=" Given center based coordinates were (",p3n="org.eclipse.elk.graph.properties",m3n="IPropertyHolder",v3n={3:1,96:1,137:1},k3n="org.eclipse.elk.alg.common.spore",y3n="org.eclipse.elk.alg.common.utils",M3n={205:1},T3n="org.eclipse.elk.core",j3n="Connected Components Compaction",E3n="org.eclipse.elk.alg.disco",S3n="org.eclipse.elk.alg.disco.graph",P3n="org.eclipse.elk.alg.disco.options",C3n="CompactionStrategy",I3n="org.eclipse.elk.disco.componentCompaction.strategy",O3n="org.eclipse.elk.disco.componentCompaction.componentLayoutAlgorithm",A3n="org.eclipse.elk.disco.debug.discoGraph",L3n="org.eclipse.elk.disco.debug.discoPolys",N3n="componentCompaction",$3n="org.eclipse.elk.disco",D3n="org.eclipse.elk.spacing.componentComponent",x3n="org.eclipse.elk.edge.thickness",R3n="org.eclipse.elk.aspectRatio",K3n="org.eclipse.elk.padding",F3n="org.eclipse.elk.alg.disco.transform",_3n=1.5707963267948966,B3n=17976931348623157e292,H3n={3:1,4:1,5:1,198:1},U3n={3:1,6:1,4:1,5:1,100:1,115:1},G3n="org.eclipse.elk.alg.force",q3n="ComponentsProcessor",X3n="ComponentsProcessor/1",z3n="ElkGraphImporter/lambda$0$Type",V3n="org.eclipse.elk.alg.force.graph",W3n="Component Layout",Q3n="org.eclipse.elk.alg.force.model",J3n="org.eclipse.elk.force.model",Y3n="org.eclipse.elk.force.iterations",Z3n="org.eclipse.elk.force.repulsivePower",n4n="org.eclipse.elk.force.temperature",t4n=.001,e4n="org.eclipse.elk.force.repulsion",i4n="org.eclipse.elk.alg.force.options",r4n=1.600000023841858,c4n="org.eclipse.elk.force",a4n="org.eclipse.elk.priority",o4n="org.eclipse.elk.spacing.nodeNode",u4n="org.eclipse.elk.spacing.edgeLabel",s4n="org.eclipse.elk.randomSeed",h4n="org.eclipse.elk.separateConnectedComponents",f4n="org.eclipse.elk.interactive",l4n="org.eclipse.elk.portConstraints",b4n="org.eclipse.elk.edgeLabels.inline",w4n="org.eclipse.elk.omitNodeMicroLayout",d4n="org.eclipse.elk.nodeSize.fixedGraphSize",g4n="org.eclipse.elk.nodeSize.options",p4n="org.eclipse.elk.nodeSize.constraints",m4n="org.eclipse.elk.nodeLabels.placement",v4n="org.eclipse.elk.portLabels.placement",k4n="org.eclipse.elk.topdownLayout",y4n="org.eclipse.elk.topdown.scaleFactor",M4n="org.eclipse.elk.topdown.hierarchicalNodeWidth",T4n="org.eclipse.elk.topdown.hierarchicalNodeAspectRatio",j4n="org.eclipse.elk.topdown.nodeType",E4n="origin",S4n="random",P4n="boundingBox.upLeft",C4n="boundingBox.lowRight",I4n="org.eclipse.elk.stress.fixed",O4n="org.eclipse.elk.stress.desiredEdgeLength",A4n="org.eclipse.elk.stress.dimension",L4n="org.eclipse.elk.stress.epsilon",N4n="org.eclipse.elk.stress.iterationLimit",$4n="org.eclipse.elk.stress",D4n="ELK Stress",x4n="org.eclipse.elk.nodeSize.minimum",R4n="org.eclipse.elk.alg.force.stress",K4n="Layered layout",F4n="org.eclipse.elk.alg.layered",_4n="org.eclipse.elk.alg.layered.compaction.components",B4n="org.eclipse.elk.alg.layered.compaction.oned",H4n="org.eclipse.elk.alg.layered.compaction.oned.algs",U4n="org.eclipse.elk.alg.layered.compaction.recthull",G4n="org.eclipse.elk.alg.layered.components",q4n="NONE",X4n="MODEL_ORDER",z4n={3:1,6:1,4:1,9:1,5:1,126:1},V4n={3:1,6:1,4:1,5:1,150:1,100:1,115:1},W4n="org.eclipse.elk.alg.layered.compound",Q4n={47:1},J4n="org.eclipse.elk.alg.layered.graph",Y4n=" -> ",Z4n="Not supported by LGraph",n6n="Port side is undefined",t6n={3:1,6:1,4:1,5:1,483:1,150:1,100:1,115:1},e6n={3:1,6:1,4:1,5:1,150:1,199:1,210:1,100:1,115:1},i6n={3:1,6:1,4:1,5:1,150:1,2042:1,210:1,100:1,115:1},r6n="([{\"' \t\r\n",c6n=")]}\"' \t\r\n",a6n="The given string contains parts that cannot be parsed as numbers.",o6n="org.eclipse.elk.core.math",u6n={3:1,4:1,140:1,214:1,423:1},s6n={3:1,4:1,107:1,214:1,423:1},h6n="org.eclipse.elk.alg.layered.graph.transform",f6n="ElkGraphImporter",l6n="ElkGraphImporter/lambda$1$Type",b6n="ElkGraphImporter/lambda$2$Type",w6n="ElkGraphImporter/lambda$4$Type",d6n="org.eclipse.elk.alg.layered.intermediate",g6n="Node margin calculation",p6n="ONE_SIDED_GREEDY_SWITCH",m6n="TWO_SIDED_GREEDY_SWITCH",v6n="No implementation is available for the layout processor ",k6n="IntermediateProcessorStrategy",y6n="Node '",M6n="FIRST_SEPARATE",T6n="LAST_SEPARATE",j6n="Odd port side processing",E6n="org.eclipse.elk.alg.layered.intermediate.compaction",S6n="org.eclipse.elk.alg.layered.intermediate.greedyswitch",P6n="org.eclipse.elk.alg.layered.p3order.counting",C6n={230:1},I6n="org.eclipse.elk.alg.layered.intermediate.loops",O6n="org.eclipse.elk.alg.layered.intermediate.loops.ordering",A6n="org.eclipse.elk.alg.layered.intermediate.loops.routing",L6n="org.eclipse.elk.alg.layered.intermediate.preserveorder",N6n="org.eclipse.elk.alg.layered.intermediate.wrapping",$6n="org.eclipse.elk.alg.layered.options",D6n="INTERACTIVE",x6n="GREEDY",R6n="DEPTH_FIRST",K6n="EDGE_LENGTH",F6n="SELF_LOOPS",_6n="firstTryWithInitialOrder",B6n="org.eclipse.elk.layered.directionCongruency",H6n="org.eclipse.elk.layered.feedbackEdges",U6n="org.eclipse.elk.layered.interactiveReferencePoint",G6n="org.eclipse.elk.layered.mergeEdges",q6n="org.eclipse.elk.layered.mergeHierarchyEdges",X6n="org.eclipse.elk.layered.allowNonFlowPortsToSwitchSides",z6n="org.eclipse.elk.layered.portSortingStrategy",V6n="org.eclipse.elk.layered.thoroughness",W6n="org.eclipse.elk.layered.unnecessaryBendpoints",Q6n="org.eclipse.elk.layered.generatePositionAndLayerIds",J6n="org.eclipse.elk.layered.cycleBreaking.strategy",Y6n="org.eclipse.elk.layered.layering.strategy",Z6n="org.eclipse.elk.layered.layering.layerConstraint",n5n="org.eclipse.elk.layered.layering.layerChoiceConstraint",t5n="org.eclipse.elk.layered.layering.layerId",e5n="org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth",i5n="org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor",r5n="org.eclipse.elk.layered.layering.nodePromotion.strategy",c5n="org.eclipse.elk.layered.layering.nodePromotion.maxIterations",a5n="org.eclipse.elk.layered.layering.coffmanGraham.layerBound",o5n="org.eclipse.elk.layered.crossingMinimization.strategy",u5n="org.eclipse.elk.layered.crossingMinimization.forceNodeModelOrder",s5n="org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness",h5n="org.eclipse.elk.layered.crossingMinimization.semiInteractive",f5n="org.eclipse.elk.layered.crossingMinimization.inLayerPredOf",l5n="org.eclipse.elk.layered.crossingMinimization.inLayerSuccOf",b5n="org.eclipse.elk.layered.crossingMinimization.positionChoiceConstraint",w5n="org.eclipse.elk.layered.crossingMinimization.positionId",d5n="org.eclipse.elk.layered.crossingMinimization.greedySwitch.activationThreshold",g5n="org.eclipse.elk.layered.crossingMinimization.greedySwitch.type",p5n="org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type",m5n="org.eclipse.elk.layered.nodePlacement.strategy",v5n="org.eclipse.elk.layered.nodePlacement.favorStraightEdges",k5n="org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening",y5n="org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment",M5n="org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening",T5n="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility",j5n="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default",E5n="org.eclipse.elk.layered.edgeRouting.selfLoopDistribution",S5n="org.eclipse.elk.layered.edgeRouting.selfLoopOrdering",P5n="org.eclipse.elk.layered.edgeRouting.splines.mode",C5n="org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor",I5n="org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth",O5n="org.eclipse.elk.layered.spacing.baseValue",A5n="org.eclipse.elk.layered.spacing.edgeNodeBetweenLayers",L5n="org.eclipse.elk.layered.spacing.edgeEdgeBetweenLayers",N5n="org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers",$5n="org.eclipse.elk.layered.priority.direction",D5n="org.eclipse.elk.layered.priority.shortness",x5n="org.eclipse.elk.layered.priority.straightness",R5n="org.eclipse.elk.layered.compaction.connectedComponents",K5n="org.eclipse.elk.layered.compaction.postCompaction.strategy",F5n="org.eclipse.elk.layered.compaction.postCompaction.constraints",_5n="org.eclipse.elk.layered.highDegreeNodes.treatment",B5n="org.eclipse.elk.layered.highDegreeNodes.threshold",H5n="org.eclipse.elk.layered.highDegreeNodes.treeHeight",U5n="org.eclipse.elk.layered.wrapping.strategy",G5n="org.eclipse.elk.layered.wrapping.additionalEdgeSpacing",q5n="org.eclipse.elk.layered.wrapping.correctionFactor",X5n="org.eclipse.elk.layered.wrapping.cutting.strategy",z5n="org.eclipse.elk.layered.wrapping.cutting.cuts",V5n="org.eclipse.elk.layered.wrapping.cutting.msd.freedom",W5n="org.eclipse.elk.layered.wrapping.validify.strategy",Q5n="org.eclipse.elk.layered.wrapping.validify.forbiddenIndices",J5n="org.eclipse.elk.layered.wrapping.multiEdge.improveCuts",Y5n="org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty",Z5n="org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges",n8n="org.eclipse.elk.layered.edgeLabels.sideSelection",t8n="org.eclipse.elk.layered.edgeLabels.centerLabelPlacementStrategy",e8n="org.eclipse.elk.layered.considerModelOrder.strategy",i8n="org.eclipse.elk.layered.considerModelOrder.portModelOrder",r8n="org.eclipse.elk.layered.considerModelOrder.noModelOrder",c8n="org.eclipse.elk.layered.considerModelOrder.components",a8n="org.eclipse.elk.layered.considerModelOrder.longEdgeStrategy",o8n="org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence",u8n="org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence",s8n="layering",h8n="layering.minWidth",f8n="layering.nodePromotion",l8n="crossingMinimization",b8n="org.eclipse.elk.hierarchyHandling",w8n="crossingMinimization.greedySwitch",d8n="nodePlacement",g8n="nodePlacement.bk",p8n="edgeRouting",m8n="org.eclipse.elk.edgeRouting",v8n="spacing",k8n="priority",y8n="compaction",M8n="compaction.postCompaction",T8n="Specifies whether and how post-process compaction is applied.",j8n="highDegreeNodes",E8n="wrapping",S8n="wrapping.cutting",P8n="wrapping.validify",C8n="wrapping.multiEdge",I8n="edgeLabels",O8n="considerModelOrder",A8n="org.eclipse.elk.spacing.commentComment",L8n="org.eclipse.elk.spacing.commentNode",N8n="org.eclipse.elk.spacing.edgeEdge",$8n="org.eclipse.elk.spacing.edgeNode",D8n="org.eclipse.elk.spacing.labelLabel",x8n="org.eclipse.elk.spacing.labelPortHorizontal",R8n="org.eclipse.elk.spacing.labelPortVertical",K8n="org.eclipse.elk.spacing.labelNode",F8n="org.eclipse.elk.spacing.nodeSelfLoop",_8n="org.eclipse.elk.spacing.portPort",B8n="org.eclipse.elk.spacing.individual",H8n="org.eclipse.elk.port.borderOffset",U8n="org.eclipse.elk.noLayout",G8n="org.eclipse.elk.port.side",q8n="org.eclipse.elk.debugMode",X8n="org.eclipse.elk.alignment",z8n="org.eclipse.elk.insideSelfLoops.activate",V8n="org.eclipse.elk.insideSelfLoops.yo",W8n="org.eclipse.elk.direction",Q8n="org.eclipse.elk.nodeLabels.padding",J8n="org.eclipse.elk.portLabels.nextToPortIfPossible",Y8n="org.eclipse.elk.portLabels.treatAsGroup",Z8n="org.eclipse.elk.portAlignment.default",n9n="org.eclipse.elk.portAlignment.north",t9n="org.eclipse.elk.portAlignment.south",e9n="org.eclipse.elk.portAlignment.west",i9n="org.eclipse.elk.portAlignment.east",r9n="org.eclipse.elk.contentAlignment",c9n="org.eclipse.elk.junctionPoints",a9n="org.eclipse.elk.edgeLabels.placement",o9n="org.eclipse.elk.port.index",u9n="org.eclipse.elk.commentBox",s9n="org.eclipse.elk.hypernode",h9n="org.eclipse.elk.port.anchor",f9n="org.eclipse.elk.partitioning.activate",l9n="org.eclipse.elk.partitioning.partition",b9n="org.eclipse.elk.position",w9n="org.eclipse.elk.margins",d9n="org.eclipse.elk.spacing.portsSurrounding",g9n="org.eclipse.elk.interactiveLayout",p9n="org.eclipse.elk.core.util",m9n={3:1,4:1,5:1,601:1},v9n="NETWORK_SIMPLEX",k9n="SIMPLE",y9n={106:1,47:1},M9n="org.eclipse.elk.alg.layered.p1cycles",T9n="org.eclipse.elk.alg.layered.p2layers",j9n={413:1,230:1},E9n={846:1,3:1,4:1},S9n="org.eclipse.elk.alg.layered.p3order",P9n="org.eclipse.elk.alg.layered.p4nodes",C9n={3:1,4:1,5:1,854:1},I9n=1e-5,O9n="org.eclipse.elk.alg.layered.p4nodes.bk",A9n="org.eclipse.elk.alg.layered.p5edges",L9n="org.eclipse.elk.alg.layered.p5edges.orthogonal",N9n="org.eclipse.elk.alg.layered.p5edges.orthogonal.direction",$9n=1e-6,D9n="org.eclipse.elk.alg.layered.p5edges.splines",x9n=.09999999999999998,R9n=1e-8,K9n=4.71238898038469,F9n=3.141592653589793,_9n="org.eclipse.elk.alg.mrtree",B9n=.10000000149011612,H9n="SUPER_ROOT",U9n="org.eclipse.elk.alg.mrtree.graph",G9n=-17976931348623157e292,q9n="org.eclipse.elk.alg.mrtree.intermediate",X9n="Processor compute fanout",z9n={3:1,6:1,4:1,5:1,534:1,100:1,115:1},V9n="Set neighbors in level",W9n="org.eclipse.elk.alg.mrtree.options",Q9n="DESCENDANTS",J9n="org.eclipse.elk.mrtree.compaction",Y9n="org.eclipse.elk.mrtree.edgeEndTextureLength",Z9n="org.eclipse.elk.mrtree.treeLevel",n7n="org.eclipse.elk.mrtree.positionConstraint",t7n="org.eclipse.elk.mrtree.weighting",e7n="org.eclipse.elk.mrtree.edgeRoutingMode",i7n="org.eclipse.elk.mrtree.searchOrder",r7n="Position Constraint",c7n="org.eclipse.elk.mrtree",a7n="org.eclipse.elk.tree",o7n="Processor arrange level",u7n="org.eclipse.elk.alg.mrtree.p2order",s7n="org.eclipse.elk.alg.mrtree.p4route",h7n="org.eclipse.elk.alg.radial",f7n=6.283185307179586,l7n="Before",b7n=5e-324,w7n="After",d7n="org.eclipse.elk.alg.radial.intermediate",g7n="COMPACTION",p7n="org.eclipse.elk.alg.radial.intermediate.compaction",m7n={3:1,4:1,5:1,100:1},v7n="org.eclipse.elk.alg.radial.intermediate.optimization",k7n="No implementation is available for the layout option ",y7n="org.eclipse.elk.alg.radial.options",M7n="org.eclipse.elk.radial.centerOnRoot",T7n="org.eclipse.elk.radial.orderId",j7n="org.eclipse.elk.radial.radius",E7n="org.eclipse.elk.radial.rotate",S7n="org.eclipse.elk.radial.compactor",P7n="org.eclipse.elk.radial.compactionStepSize",C7n="org.eclipse.elk.radial.sorter",I7n="org.eclipse.elk.radial.wedgeCriteria",O7n="org.eclipse.elk.radial.optimizationCriteria",A7n="org.eclipse.elk.radial.rotation.targetAngle",L7n="org.eclipse.elk.radial.rotation.computeAdditionalWedgeSpace",N7n="org.eclipse.elk.radial.rotation.outgoingEdgeAngles",$7n="Compaction",D7n="rotation",x7n="org.eclipse.elk.radial",R7n="org.eclipse.elk.alg.radial.p1position.wedge",K7n="org.eclipse.elk.alg.radial.sorting",F7n=5.497787143782138,_7n=3.9269908169872414,B7n=2.356194490192345,H7n="org.eclipse.elk.alg.rectpacking",U7n="org.eclipse.elk.alg.rectpacking.intermediate",G7n="org.eclipse.elk.alg.rectpacking.options",q7n="org.eclipse.elk.rectpacking.trybox",X7n="org.eclipse.elk.rectpacking.currentPosition",z7n="org.eclipse.elk.rectpacking.desiredPosition",V7n="org.eclipse.elk.rectpacking.inNewRow",W7n="org.eclipse.elk.rectpacking.widthApproximation.strategy",Q7n="org.eclipse.elk.rectpacking.widthApproximation.targetWidth",J7n="org.eclipse.elk.rectpacking.widthApproximation.optimizationGoal",Y7n="org.eclipse.elk.rectpacking.widthApproximation.lastPlaceShift",Z7n="org.eclipse.elk.rectpacking.packing.strategy",nnt="org.eclipse.elk.rectpacking.packing.compaction.rowHeightReevaluation",tnt="org.eclipse.elk.rectpacking.packing.compaction.iterations",ent="org.eclipse.elk.rectpacking.whiteSpaceElimination.strategy",int="widthApproximation",rnt="Compaction Strategy",cnt="packing.compaction",ant="org.eclipse.elk.rectpacking",ont="org.eclipse.elk.alg.rectpacking.p1widthapproximation",unt="org.eclipse.elk.alg.rectpacking.p2packing",snt="No Compaction",hnt="org.eclipse.elk.alg.rectpacking.p3whitespaceelimination",fnt="org.eclipse.elk.alg.rectpacking.util",lnt="No implementation available for ",bnt="org.eclipse.elk.alg.spore",wnt="org.eclipse.elk.alg.spore.options",dnt="org.eclipse.elk.sporeCompaction",gnt="org.eclipse.elk.underlyingLayoutAlgorithm",pnt="org.eclipse.elk.processingOrder.treeConstruction",mnt="org.eclipse.elk.processingOrder.spanningTreeCostFunction",vnt="org.eclipse.elk.processingOrder.preferredRoot",knt="org.eclipse.elk.processingOrder.rootSelection",ynt="org.eclipse.elk.structure.structureExtractionStrategy",Mnt="org.eclipse.elk.compaction.compactionStrategy",Tnt="org.eclipse.elk.compaction.orthogonal",jnt="org.eclipse.elk.overlapRemoval.maxIterations",Ent="org.eclipse.elk.overlapRemoval.runScanline",Snt="processingOrder",Pnt="overlapRemoval",Cnt="org.eclipse.elk.sporeOverlap",Int="org.eclipse.elk.alg.spore.p1structure",Ont="org.eclipse.elk.alg.spore.p2processingorder",Ant="org.eclipse.elk.alg.spore.p3execution",Lnt="Topdown Layout",Nnt="Invalid index: ",$nt="org.eclipse.elk.core.alg",Dnt={341:1},xnt={295:1},Rnt="Make sure its type is registered with the ",Knt=" utility class.",Fnt="true",_nt="false",Bnt="Couldn't clone property '",Hnt=.05,Unt="org.eclipse.elk.core.options",Gnt=1.2999999523162842,qnt="org.eclipse.elk.box",Xnt="org.eclipse.elk.expandNodes",znt="org.eclipse.elk.box.packingMode",Vnt="org.eclipse.elk.algorithm",Wnt="org.eclipse.elk.resolvedAlgorithm",Qnt="org.eclipse.elk.bendPoints",Jnt="org.eclipse.elk.labelManager",Ynt="org.eclipse.elk.scaleFactor",Znt="org.eclipse.elk.childAreaWidth",ntt="org.eclipse.elk.childAreaHeight",ttt="org.eclipse.elk.animate",ett="org.eclipse.elk.animTimeFactor",itt="org.eclipse.elk.layoutAncestors",rtt="org.eclipse.elk.maxAnimTime",ctt="org.eclipse.elk.minAnimTime",att="org.eclipse.elk.progressBar",ott="org.eclipse.elk.validateGraph",utt="org.eclipse.elk.validateOptions",stt="org.eclipse.elk.zoomToFit",htt="org.eclipse.elk.font.name",ftt="org.eclipse.elk.font.size",ltt="org.eclipse.elk.topdown.sizeApproximator",btt="org.eclipse.elk.topdown.scaleCap",wtt="org.eclipse.elk.edge.type",dtt="partitioning",gtt="nodeLabels",ptt="portAlignment",mtt="nodeSize",vtt="port",ktt="portLabels",ytt="topdown",Mtt="insideSelfLoops",Ttt="org.eclipse.elk.fixed",jtt="org.eclipse.elk.random",Ett={3:1,34:1,22:1,347:1},Stt="port must have a parent node to calculate the port side",Ptt="The edge needs to have exactly one edge section. Found: ",Ctt="org.eclipse.elk.core.util.adapters",Itt="org.eclipse.emf.ecore",Ott="org.eclipse.elk.graph",Att="EMapPropertyHolder",Ltt="ElkBendPoint",Ntt="ElkGraphElement",$tt="ElkConnectableShape",Dtt="ElkEdge",xtt="ElkEdgeSection",Rtt="EModelElement",Ktt="ENamedElement",Ftt="ElkLabel",_tt="ElkNode",Btt="ElkPort",Htt={94:1,93:1},Utt="org.eclipse.emf.common.notify.impl",Gtt="The feature '",qtt="' is not a valid changeable feature",Xtt="Expecting null",ztt="' is not a valid feature",Vtt="The feature ID",Wtt=" is not a valid feature ID",Qtt=32768,Jtt={110:1,94:1,93:1,58:1,54:1,99:1},Ytt="org.eclipse.emf.ecore.impl",Ztt="org.eclipse.elk.graph.impl",net="Recursive containment not allowed for ",tet="The datatype '",eet="' is not a valid classifier",iet="The value '",ret={195:1,3:1,4:1},cet="The class '",aet="http://www.eclipse.org/elk/ElkGraph",oet="property",uet="value",set="source",het="properties",fet="identifier",bet="height",wet="width",det="parent",get="text",pet="children",met="hierarchical",vet="sources",ket="targets",yet="sections",Met="bendPoints",Tet="outgoingShape",jet="incomingShape",Eet="outgoingSections",Set="incomingSections",Pet="org.eclipse.emf.common.util",Cet="Severe implementation error in the Json to ElkGraph importer.",Iet="id",Oet="org.eclipse.elk.graph.json",Aet="Unhandled parameter types: ",Let="startPoint",Net="An edge must have at least one source and one target (edge id: '",$et="').",Det="Referenced edge section does not exist: ",xet=" (edge id: '",Ret="target",Ket="sourcePoint",Fet="targetPoint",_et="group",Bet="name",Het="connectableShape cannot be null",Uet="edge cannot be null",Get="Passed edge is not 'simple'.",qet="org.eclipse.elk.graph.util",Xet="The 'no duplicates' constraint is violated",zet="targetIndex=",Vet=", size=",Wet="sourceIndex=",Qet={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1},Jet={3:1,4:1,20:1,31:1,56:1,16:1,51:1,15:1,59:1,70:1,66:1,61:1,596:1},Yet="logging",Zet="measureExecutionTime",nit="parser.parse.1",tit="parser.parse.2",eit="parser.next.1",iit="parser.next.2",rit="parser.next.3",cit="parser.next.4",ait="parser.factor.1",oit="parser.factor.2",uit="parser.factor.3",sit="parser.factor.4",hit="parser.factor.5",fit="parser.factor.6",lit="parser.atom.1",bit="parser.atom.2",wit="parser.atom.3",dit="parser.atom.4",git="parser.atom.5",pit="parser.cc.1",mit="parser.cc.2",vit="parser.cc.3",kit="parser.cc.5",yit="parser.cc.6",Mit="parser.cc.7",Tit="parser.cc.8",jit="parser.ope.1",Eit="parser.ope.2",Sit="parser.ope.3",Pit="parser.descape.1",Cit="parser.descape.2",Iit="parser.descape.3",Oit="parser.descape.4",Ait="parser.descape.5",Lit="parser.process.1",Nit="parser.quantifier.1",$it="parser.quantifier.2",Dit="parser.quantifier.3",xit="parser.quantifier.4",Rit="parser.quantifier.5",Kit="org.eclipse.emf.common.notify",Fit={424:1,686:1},_it={3:1,4:1,20:1,31:1,56:1,16:1,15:1,70:1,61:1},Bit={378:1,152:1},Hit="index=",Uit={3:1,4:1,5:1,129:1},Git={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,61:1},qit={3:1,6:1,4:1,5:1,198:1},Xit={3:1,4:1,5:1,173:1,379:1},zit=";/?:@&=+$,",Vit="invalid authority: ",Wit="EAnnotation",Qit="ETypedElement",Jit="EStructuralFeature",Yit="EAttribute",Zit="EClassifier",nrt="EEnumLiteral",trt="EGenericType",ert="EOperation",irt="EParameter",rrt="EReference",crt="ETypeParameter",art="org.eclipse.emf.ecore.util",ort={79:1},urt={3:1,20:1,16:1,15:1,61:1,597:1,79:1,71:1,97:1},srt="org.eclipse.emf.ecore.util.FeatureMap$Entry",hrt=8192,frt=2048,lrt="byte",brt="char",wrt="double",drt="float",grt="int",prt="long",mrt="short",vrt="java.lang.Object",krt={3:1,4:1,5:1,254:1},yrt={3:1,4:1,5:1,688:1},Mrt={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1,71:1},Trt={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1,79:1,71:1,97:1},jrt="mixed",Ert="http:///org/eclipse/emf/ecore/util/ExtendedMetaData",Srt="kind",Prt={3:1,4:1,5:1,689:1},Crt={3:1,4:1,20:1,31:1,56:1,16:1,15:1,70:1,61:1,79:1,71:1,97:1},Irt={20:1,31:1,56:1,16:1,15:1,61:1,71:1},Ort={51:1,128:1,287:1},Art={76:1,343:1},Lrt="The value of type '",Nrt="' must be of type '",$rt=1352,Drt="http://www.eclipse.org/emf/2002/Ecore",xrt=-32768,Rrt="constraints",Krt="baseType",Frt="getEStructuralFeature",_rt="getFeatureID",Brt="feature",Hrt="getOperationID",Urt="operation",Grt="defaultValue",qrt="eTypeParameters",Xrt="isInstance",zrt="getEEnumLiteral",Vrt="eContainingClass",Wrt={57:1},Qrt={3:1,4:1,5:1,124:1},Jrt="org.eclipse.emf.ecore.resource",Yrt={94:1,93:1,599:1,2034:1},Zrt="org.eclipse.emf.ecore.resource.impl",nct="unspecified",tct="simple",ect="attribute",ict="attributeWildcard",rct="element",cct="elementWildcard",act="collapse",oct="itemType",uct="namespace",sct="##targetNamespace",hct="whiteSpace",fct="wildcards",lct="http://www.eclipse.org/emf/2003/XMLType",bct="##any",wct="uninitialized",dct="The multiplicity constraint is violated",gct="org.eclipse.emf.ecore.xml.type",pct="ProcessingInstruction",mct="SimpleAnyType",vct="XMLTypeDocumentRoot",kct="org.eclipse.emf.ecore.xml.type.impl",yct="INF",Mct="processing",Tct="ENTITIES_._base",jct="minLength",Ect="ENTITY",Sct="NCName",Pct="IDREFS_._base",Cct="integer",Ict="token",Oct="pattern",Act="[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*",Lct="\\i\\c*",Nct="[\\i-[:]][\\c-[:]]*",$ct="nonPositiveInteger",Dct="maxInclusive",xct="NMTOKEN",Rct="NMTOKENS_._base",Kct="nonNegativeInteger",Fct="minInclusive",_ct="normalizedString",Bct="unsignedByte",Hct="unsignedInt",Uct="18446744073709551615",Gct="unsignedShort",qct="processingInstruction",Xct="org.eclipse.emf.ecore.xml.type.internal",zct=1114111,Vct="Internal Error: shorthands: \\u",Wct="xml:isDigit",Qct="xml:isWord",Jct="xml:isSpace",Yct="xml:isNameChar",Zct="xml:isInitialNameChar",nat="09\u0660\u0669\u06f0\u06f9\u0966\u096f\u09e6\u09ef\u0a66\u0a6f\u0ae6\u0aef\u0b66\u0b6f\u0be7\u0bef\u0c66\u0c6f\u0ce6\u0cef\u0d66\u0d6f\u0e50\u0e59\u0ed0\u0ed9\u0f20\u0f29",tat="AZaz\xc0\xd6\xd8\xf6\xf8\u0131\u0134\u013e\u0141\u0148\u014a\u017e\u0180\u01c3\u01cd\u01f0\u01f4\u01f5\u01fa\u0217\u0250\u02a8\u02bb\u02c1\u0386\u0386\u0388\u038a\u038c\u038c\u038e\u03a1\u03a3\u03ce\u03d0\u03d6\u03da\u03da\u03dc\u03dc\u03de\u03de\u03e0\u03e0\u03e2\u03f3\u0401\u040c\u040e\u044f\u0451\u045c\u045e\u0481\u0490\u04c4\u04c7\u04c8\u04cb\u04cc\u04d0\u04eb\u04ee\u04f5\u04f8\u04f9\u0531\u0556\u0559\u0559\u0561\u0586\u05d0\u05ea\u05f0\u05f2\u0621\u063a\u0641\u064a\u0671\u06b7\u06ba\u06be\u06c0\u06ce\u06d0\u06d3\u06d5\u06d5\u06e5\u06e6\u0905\u0939\u093d\u093d\u0958\u0961\u0985\u098c\u098f\u0990\u0993\u09a8\u09aa\u09b0\u09b2\u09b2\u09b6\u09b9\u09dc\u09dd\u09df\u09e1\u09f0\u09f1\u0a05\u0a0a\u0a0f\u0a10\u0a13\u0a28\u0a2a\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59\u0a5c\u0a5e\u0a5e\u0a72\u0a74\u0a85\u0a8b\u0a8d\u0a8d\u0a8f\u0a91\u0a93\u0aa8\u0aaa\u0ab0\u0ab2\u0ab3\u0ab5\u0ab9\u0abd\u0abd\u0ae0\u0ae0\u0b05\u0b0c\u0b0f\u0b10\u0b13\u0b28\u0b2a\u0b30\u0b32\u0b33\u0b36\u0b39\u0b3d\u0b3d\u0b5c\u0b5d\u0b5f\u0b61\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95\u0b99\u0b9a\u0b9c\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8\u0baa\u0bae\u0bb5\u0bb7\u0bb9\u0c05\u0c0c\u0c0e\u0c10\u0c12\u0c28\u0c2a\u0c33\u0c35\u0c39\u0c60\u0c61\u0c85\u0c8c\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9\u0cde\u0cde\u0ce0\u0ce1\u0d05\u0d0c\u0d0e\u0d10\u0d12\u0d28\u0d2a\u0d39\u0d60\u0d61\u0e01\u0e2e\u0e30\u0e30\u0e32\u0e33\u0e40\u0e45\u0e81\u0e82\u0e84\u0e84\u0e87\u0e88\u0e8a\u0e8a\u0e8d\u0e8d\u0e94\u0e97\u0e99\u0e9f\u0ea1\u0ea3\u0ea5\u0ea5\u0ea7\u0ea7\u0eaa\u0eab\u0ead\u0eae\u0eb0\u0eb0\u0eb2\u0eb3\u0ebd\u0ebd\u0ec0\u0ec4\u0f40\u0f47\u0f49\u0f69\u10a0\u10c5\u10d0\u10f6\u1100\u1100\u1102\u1103\u1105\u1107\u1109\u1109\u110b\u110c\u110e\u1112\u113c\u113c\u113e\u113e\u1140\u1140\u114c\u114c\u114e\u114e\u1150\u1150\u1154\u1155\u1159\u1159\u115f\u1161\u1163\u1163\u1165\u1165\u1167\u1167\u1169\u1169\u116d\u116e\u1172\u1173\u1175\u1175\u119e\u119e\u11a8\u11a8\u11ab\u11ab\u11ae\u11af\u11b7\u11b8\u11ba\u11ba\u11bc\u11c2\u11eb\u11eb\u11f0\u11f0\u11f9\u11f9\u1e00\u1e9b\u1ea0\u1ef9\u1f00\u1f15\u1f18\u1f1d\u1f20\u1f45\u1f48\u1f4d\u1f50\u1f57\u1f59\u1f59\u1f5b\u1f5b\u1f5d\u1f5d\u1f5f\u1f7d\u1f80\u1fb4\u1fb6\u1fbc\u1fbe\u1fbe\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3\u1fd6\u1fdb\u1fe0\u1fec\u1ff2\u1ff4\u1ff6\u1ffc\u2126\u2126\u212a\u212b\u212e\u212e\u2180\u2182\u3007\u3007\u3021\u3029\u3041\u3094\u30a1\u30fa\u3105\u312c\u4e00\u9fa5\uac00\ud7a3",eat="Private Use",iat="ASSIGNED",rat="\0\x7f\x80\xff\u0100\u017f\u0180\u024f\u0250\u02af\u02b0\u02ff\u0300\u036f\u0370\u03ff\u0400\u04ff\u0530\u058f\u0590\u05ff\u0600\u06ff\u0700\u074f\u0780\u07bf\u0900\u097f\u0980\u09ff\u0a00\u0a7f\u0a80\u0aff\u0b00\u0b7f\u0b80\u0bff\u0c00\u0c7f\u0c80\u0cff\u0d00\u0d7f\u0d80\u0dff\u0e00\u0e7f\u0e80\u0eff\u0f00\u0fff\u1000\u109f\u10a0\u10ff\u1100\u11ff\u1200\u137f\u13a0\u13ff\u1400\u167f\u1680\u169f\u16a0\u16ff\u1780\u17ff\u1800\u18af\u1e00\u1eff\u1f00\u1fff\u2000\u206f\u2070\u209f\u20a0\u20cf\u20d0\u20ff\u2100\u214f\u2150\u218f\u2190\u21ff\u2200\u22ff\u2300\u23ff\u2400\u243f\u2440\u245f\u2460\u24ff\u2500\u257f\u2580\u259f\u25a0\u25ff\u2600\u26ff\u2700\u27bf\u2800\u28ff\u2e80\u2eff\u2f00\u2fdf\u2ff0\u2fff\u3000\u303f\u3040\u309f\u30a0\u30ff\u3100\u312f\u3130\u318f\u3190\u319f\u31a0\u31bf\u3200\u32ff\u3300\u33ff\u3400\u4db5\u4e00\u9fff\ua000\ua48f\ua490\ua4cf\uac00\ud7a3\ue000\uf8ff\uf900\ufaff\ufb00\ufb4f\ufb50\ufdff\ufe20\ufe2f\ufe30\ufe4f\ufe50\ufe6f\ufe70\ufefe\ufeff\ufeff\uff00\uffef",cat="UNASSIGNED",aat={3:1,122:1},oat="org.eclipse.emf.ecore.xml.type.util",uat={3:1,4:1,5:1,381:1},sat="org.eclipse.xtext.xbase.lib",hat="Cannot add elements to a Range",fat="Cannot set elements in a Range",lat="Cannot remove elements from a Range",bat="user.agent";e.goog=e.goog||{},e.goog.global=e.goog.global||e,sZn={},sDn(1,null,{},r),uZn.Fb=function(n){return SL(this,n)},uZn.Gb=function(){return this.Rm},uZn.Hb=function(){return xx(this)},uZn.Ib=function(){return Ij(Tbn(this))+"@"+(Hon(this)>>>0).toString(16)},uZn.equals=function(n){return this.Fb(n)},uZn.hashCode=function(){return this.Hb()},uZn.toString=function(){return this.Ib()},sDn(297,1,{297:1,2124:1},Ifn),uZn.ve=function(n){var t;return(t=new Ifn).i=4,t.c=n>1?B0(this,n-1):this,t},uZn.we=function(){return vK(this),this.b},uZn.xe=function(){return Ij(this)},uZn.ye=function(){return vK(this),this.k},uZn.ze=function(){return!!(4&this.i)},uZn.Ae=function(){return!!(1&this.i)},uZn.Ib=function(){return crn(this)},uZn.i=0;var wat,dat=zW(kZn,"Object",1),gat=zW(kZn,"Class",297);sDn(2096,1,yZn),zW(MZn,"Optional",2096),sDn(1191,2096,yZn,c),uZn.Fb=function(n){return n===this},uZn.Hb=function(){return 2040732332},uZn.Ib=function(){return"Optional.absent()"},uZn.Jb=function(n){return WW(n),gy(),wat},zW(MZn,"Absent",1191),sDn(636,1,{},FM),zW(MZn,"Joiner",636);var pat=Iq(MZn,"Predicate");sDn(589,1,{178:1,589:1,3:1,46:1},Hl),uZn.Mb=function(n){return Wfn(this,n)},uZn.Lb=function(n){return Wfn(this,n)},uZn.Fb=function(n){var t;return!!F$(n,589)&&(t=uG(n,589),PDn(this.a,t.a))},uZn.Hb=function(){return Zfn(this.a)+306654252},uZn.Ib=function(){return eAn(this.a)},zW(MZn,"Predicates/AndPredicate",589),sDn(419,2096,{419:1,3:1},Ul),uZn.Fb=function(n){var t;return!!F$(n,419)&&(t=uG(n,419),udn(this.a,t.a))},uZn.Hb=function(){return 1502476572+Hon(this.a)},uZn.Ib=function(){return CZn+this.a+")"},uZn.Jb=function(n){return new Ul(bZ(n.Kb(this.a),"the Function passed to Optional.transform() must not return null."))},zW(MZn,"Present",419),sDn(204,1,OZn),uZn.Nb=function(n){SV(this,n)},uZn.Qb=function(){_M()},zW(AZn,"UnmodifiableIterator",204),sDn(2076,204,LZn),uZn.Qb=function(){_M()},uZn.Rb=function(n){throw hv(new Kv)},uZn.Wb=function(n){throw hv(new Kv)},zW(AZn,"UnmodifiableListIterator",2076),sDn(399,2076,LZn),uZn.Ob=function(){return this.c0},uZn.Pb=function(){if(this.c>=this.d)throw hv(new Bv);return this.Xb(this.c++)},uZn.Tb=function(){return this.c},uZn.Ub=function(){if(this.c<=0)throw hv(new Bv);return this.Xb(--this.c)},uZn.Vb=function(){return this.c-1},uZn.c=0,uZn.d=0,zW(AZn,"AbstractIndexedListIterator",399),sDn(713,204,OZn),uZn.Ob=function(){return oon(this)},uZn.Pb=function(){return yen(this)},uZn.e=1,zW(AZn,"AbstractIterator",713),sDn(2084,1,{229:1}),uZn.Zb=function(){return this.f||(this.f=this.ac())},uZn.Fb=function(n){return Aln(this,n)},uZn.Hb=function(){return Hon(this.Zb())},uZn.dc=function(){return 0==this.gc()},uZn.ec=function(){return kz(this)},uZn.Ib=function(){return cpn(this.Zb())},zW(AZn,"AbstractMultimap",2084),sDn(742,2084,NZn),uZn.$b=function(){ban(this)},uZn._b=function(n){return jj(this,n)},uZn.ac=function(){return new OE(this,this.c)},uZn.ic=function(n){return this.hc()},uZn.bc=function(){return new RD(this,this.c)},uZn.jc=function(){return this.mc(this.hc())},uZn.kc=function(){return new My(this)},uZn.lc=function(){return ICn(this.c.vc().Nc(),new o,64,this.d)},uZn.cc=function(n){return Y9(this,n)},uZn.fc=function(n){return twn(this,n)},uZn.gc=function(){return this.d},uZn.mc=function(n){return hZ(),new qw(n)},uZn.nc=function(){return new yy(this)},uZn.oc=function(){return ICn(this.c.Cc().Nc(),new a,64,this.d)},uZn.pc=function(n,t){return new A7(this,n,t,null)},uZn.d=0,zW(AZn,"AbstractMapBasedMultimap",742),sDn(1696,742,NZn),uZn.hc=function(){return new R7(this.a)},uZn.jc=function(){return hZ(),hZ(),zot},uZn.cc=function(n){return uG(Y9(this,n),15)},uZn.fc=function(n){return uG(twn(this,n),15)},uZn.Zb=function(){return nZ(this)},uZn.Fb=function(n){return Aln(this,n)},uZn.qc=function(n){return uG(Y9(this,n),15)},uZn.rc=function(n){return uG(twn(this,n),15)},uZn.mc=function(n){return SZ(uG(n,15))},uZn.pc=function(n,t){return S6(this,n,uG(t,15),null)},zW(AZn,"AbstractListMultimap",1696),sDn(748,1,$Zn),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return this.c.Ob()||this.e.Ob()},uZn.Pb=function(){var n;return this.e.Ob()||(n=uG(this.c.Pb(),44),this.b=n.ld(),this.a=uG(n.md(),16),this.e=this.a.Kc()),this.sc(this.b,this.e.Pb())},uZn.Qb=function(){this.e.Qb(),uG(nJ(this.a),16).dc()&&this.c.Qb(),--this.d.d},zW(AZn,"AbstractMapBasedMultimap/Itr",748),sDn(1129,748,$Zn,yy),uZn.sc=function(n,t){return t},zW(AZn,"AbstractMapBasedMultimap/1",1129),sDn(1130,1,{},a),uZn.Kb=function(n){return uG(n,16).Nc()},zW(AZn,"AbstractMapBasedMultimap/1methodref$spliterator$Type",1130),sDn(1131,748,$Zn,My),uZn.sc=function(n,t){return new FE(n,t)},zW(AZn,"AbstractMapBasedMultimap/2",1131);var mat=Iq(DZn,"Map");sDn(2065,1,xZn),uZn.wc=function(n){Yun(this,n)},uZn.yc=function(n,t,e){return Jgn(this,n,t,e)},uZn.$b=function(){this.vc().$b()},uZn.tc=function(n){return sTn(this,n)},uZn._b=function(n){return!!TPn(this,n,!1)},uZn.uc=function(n){var t,e;for(t=this.vc().Kc();t.Ob();)if(e=uG(t.Pb(),44).md(),xA(n)===xA(e)||null!=n&&udn(n,e))return!0;return!1},uZn.Fb=function(n){var t,e,i;if(n===this)return!0;if(!F$(n,85))return!1;if(i=uG(n,85),this.gc()!=i.gc())return!1;for(e=i.vc().Kc();e.Ob();)if(t=uG(e.Pb(),44),!this.tc(t))return!1;return!0},uZn.xc=function(n){return DA(TPn(this,n,!1))},uZn.Hb=function(){return tfn(this.vc())},uZn.dc=function(){return 0==this.gc()},uZn.ec=function(){return new Lw(this)},uZn.zc=function(n,t){throw hv(new TM("Put not supported on this map"))},uZn.Ac=function(n){xun(this,n)},uZn.Bc=function(n){return DA(TPn(this,n,!0))},uZn.gc=function(){return this.vc().gc()},uZn.Ib=function(){return KPn(this)},uZn.Cc=function(){return new Fw(this)},zW(DZn,"AbstractMap",2065),sDn(2085,2065,xZn),uZn.bc=function(){return new VE(this)},uZn.vc=function(){return vz(this)},uZn.ec=function(){return this.g||(this.g=this.bc())},uZn.Cc=function(){return this.i||(this.i=new zE(this))},zW(AZn,"Maps/ViewCachingAbstractMap",2085),sDn(402,2085,xZn,OE),uZn.xc=function(n){return srn(this,n)},uZn.Bc=function(n){return abn(this,n)},uZn.$b=function(){this.d==this.e.c?this.e.$b():Hq(new Gq(this))},uZn._b=function(n){return Uwn(this.d,n)},uZn.Ec=function(){return new Gl(this)},uZn.Dc=function(){return this.Ec()},uZn.Fb=function(n){return this===n||udn(this.d,n)},uZn.Hb=function(){return Hon(this.d)},uZn.ec=function(){return this.e.ec()},uZn.gc=function(){return this.d.gc()},uZn.Ib=function(){return cpn(this.d)},zW(AZn,"AbstractMapBasedMultimap/AsMap",402);var vat=Iq(kZn,"Iterable");sDn(31,1,RZn),uZn.Jc=function(n){z8(this,n)},uZn.Lc=function(){return this.Oc()},uZn.Nc=function(){return new h3(this,0)},uZn.Oc=function(){return new fX(null,this.Nc())},uZn.Fc=function(n){throw hv(new TM("Add not supported on this collection"))},uZn.Gc=function(n){return Qon(this,n)},uZn.$b=function(){oY(this)},uZn.Hc=function(n){return Wpn(this,n,!1)},uZn.Ic=function(n){return yhn(this,n)},uZn.dc=function(){return 0==this.gc()},uZn.Mc=function(n){return Wpn(this,n,!0)},uZn.Pc=function(){return Sz(this)},uZn.Qc=function(n){return oTn(this,n)},uZn.Ib=function(){return vIn(this)},zW(DZn,"AbstractCollection",31);var kat=Iq(DZn,"Set");sDn(KZn,31,FZn),uZn.Nc=function(){return new h3(this,1)},uZn.Fb=function(n){return Fvn(this,n)},uZn.Hb=function(){return tfn(this)},zW(DZn,"AbstractSet",KZn),sDn(2068,KZn,FZn),zW(AZn,"Sets/ImprovedAbstractSet",2068),sDn(2069,2068,FZn),uZn.$b=function(){this.Rc().$b()},uZn.Hc=function(n){return Amn(this,n)},uZn.dc=function(){return this.Rc().dc()},uZn.Mc=function(n){var t;return!(!this.Hc(n)||!F$(n,44))&&(t=uG(n,44),this.Rc().ec().Mc(t.ld()))},uZn.gc=function(){return this.Rc().gc()},zW(AZn,"Maps/EntrySet",2069),sDn(1127,2069,FZn,Gl),uZn.Hc=function(n){return Gwn(this.a.d.vc(),n)},uZn.Kc=function(){return new Gq(this.a)},uZn.Rc=function(){return this.a},uZn.Mc=function(n){var t;return!!Gwn(this.a.d.vc(),n)&&(t=uG(nJ(uG(n,44)),44),H9(this.a.e,t.ld()),!0)},uZn.Nc=function(){return JU(this.a.d.vc().Nc(),new ql(this.a))},zW(AZn,"AbstractMapBasedMultimap/AsMap/AsMapEntries",1127),sDn(1128,1,{},ql),uZn.Kb=function(n){return O9(this.a,uG(n,44))},zW(AZn,"AbstractMapBasedMultimap/AsMap/AsMapEntries/0methodref$wrapEntry$Type",1128),sDn(746,1,$Zn,Gq),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){var n;return n=uG(this.b.Pb(),44),this.a=uG(n.md(),16),O9(this.c,n)},uZn.Ob=function(){return this.b.Ob()},uZn.Qb=function(){IB(!!this.a),this.b.Qb(),this.c.e.d-=this.a.gc(),this.a.$b(),this.a=null},zW(AZn,"AbstractMapBasedMultimap/AsMap/AsMapIterator",746),sDn(542,2068,FZn,VE),uZn.$b=function(){this.b.$b()},uZn.Hc=function(n){return this.b._b(n)},uZn.Jc=function(n){WW(n),this.b.wc(new db(n))},uZn.dc=function(){return this.b.dc()},uZn.Kc=function(){return new Ny(this.b.vc().Kc())},uZn.Mc=function(n){return!!this.b._b(n)&&(this.b.Bc(n),!0)},uZn.gc=function(){return this.b.gc()},zW(AZn,"Maps/KeySet",542),sDn(327,542,FZn,RD),uZn.$b=function(){Hq(new AE(this,this.b.vc().Kc()))},uZn.Ic=function(n){return this.b.ec().Ic(n)},uZn.Fb=function(n){return this===n||udn(this.b.ec(),n)},uZn.Hb=function(){return Hon(this.b.ec())},uZn.Kc=function(){return new AE(this,this.b.vc().Kc())},uZn.Mc=function(n){var t,e;return e=0,(t=uG(this.b.Bc(n),16))&&(e=t.gc(),t.$b(),this.a.d-=e),e>0},uZn.Nc=function(){return this.b.ec().Nc()},zW(AZn,"AbstractMapBasedMultimap/KeySet",327),sDn(747,1,$Zn,AE),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return this.c.Ob()},uZn.Pb=function(){return this.a=uG(this.c.Pb(),44),this.a.ld()},uZn.Qb=function(){var n;IB(!!this.a),n=uG(this.a.md(),16),this.c.Qb(),this.b.a.d-=n.gc(),n.$b(),this.a=null},zW(AZn,"AbstractMapBasedMultimap/KeySet/1",747),sDn(503,402,{85:1,133:1},NK),uZn.bc=function(){return this.Sc()},uZn.ec=function(){return this.Uc()},uZn.Sc=function(){return new yE(this.c,this.Wc())},uZn.Tc=function(){return this.Wc().Tc()},uZn.Uc=function(){return this.b||(this.b=this.Sc())},uZn.Vc=function(){return this.Wc().Vc()},uZn.Wc=function(){return uG(this.d,133)},zW(AZn,"AbstractMapBasedMultimap/SortedAsMap",503),sDn(446,503,_Zn,$K),uZn.bc=function(){return new ME(this.a,uG(uG(this.d,133),139))},uZn.Sc=function(){return new ME(this.a,uG(uG(this.d,133),139))},uZn.ec=function(){return uG(this.b||(this.b=new ME(this.a,uG(uG(this.d,133),139))),277)},uZn.Uc=function(){return uG(this.b||(this.b=new ME(this.a,uG(uG(this.d,133),139))),277)},uZn.Wc=function(){return uG(uG(this.d,133),139)},uZn.Xc=function(n){return uG(uG(this.d,133),139).Xc(n)},uZn.Yc=function(n){return uG(uG(this.d,133),139).Yc(n)},uZn.Zc=function(n,t){return new $K(this.a,uG(uG(this.d,133),139).Zc(n,t))},uZn.$c=function(n){return uG(uG(this.d,133),139).$c(n)},uZn._c=function(n){return uG(uG(this.d,133),139)._c(n)},uZn.ad=function(n,t){return new $K(this.a,uG(uG(this.d,133),139).ad(n,t))},zW(AZn,"AbstractMapBasedMultimap/NavigableAsMap",446),sDn(502,327,BZn,yE),uZn.Nc=function(){return this.b.ec().Nc()},zW(AZn,"AbstractMapBasedMultimap/SortedKeySet",502),sDn(401,502,HZn,ME),zW(AZn,"AbstractMapBasedMultimap/NavigableKeySet",401),sDn(551,31,RZn,A7),uZn.Fc=function(n){var t,e;return bpn(this),e=this.d.dc(),(t=this.d.Fc(n))&&(++this.f.d,e&&mF(this)),t},uZn.Gc=function(n){var t,e,i;return!n.dc()&&(bpn(this),i=this.d.gc(),(t=this.d.Gc(n))&&(e=this.d.gc(),this.f.d+=e-i,0==i&&mF(this)),t)},uZn.$b=function(){var n;bpn(this),0!=(n=this.d.gc())&&(this.d.$b(),this.f.d-=n,DX(this))},uZn.Hc=function(n){return bpn(this),this.d.Hc(n)},uZn.Ic=function(n){return bpn(this),this.d.Ic(n)},uZn.Fb=function(n){return n===this||(bpn(this),udn(this.d,n))},uZn.Hb=function(){return bpn(this),Hon(this.d)},uZn.Kc=function(){return bpn(this),new WU(this)},uZn.Mc=function(n){var t;return bpn(this),(t=this.d.Mc(n))&&(--this.f.d,DX(this)),t},uZn.gc=function(){return qA(this)},uZn.Nc=function(){return bpn(this),this.d.Nc()},uZn.Ib=function(){return bpn(this),cpn(this.d)},zW(AZn,"AbstractMapBasedMultimap/WrappedCollection",551);var yat=Iq(DZn,"List");sDn(744,551,{20:1,31:1,16:1,15:1},qz),uZn.jd=function(n){Lon(this,n)},uZn.Nc=function(){return bpn(this),this.d.Nc()},uZn.bd=function(n,t){var e;bpn(this),e=this.d.dc(),uG(this.d,15).bd(n,t),++this.a.d,e&&mF(this)},uZn.cd=function(n,t){var e,i,r;return!t.dc()&&(bpn(this),r=this.d.gc(),(e=uG(this.d,15).cd(n,t))&&(i=this.d.gc(),this.a.d+=i-r,0==r&&mF(this)),e)},uZn.Xb=function(n){return bpn(this),uG(this.d,15).Xb(n)},uZn.dd=function(n){return bpn(this),uG(this.d,15).dd(n)},uZn.ed=function(){return bpn(this),new JN(this)},uZn.fd=function(n){return bpn(this),new UY(this,n)},uZn.gd=function(n){var t;return bpn(this),t=uG(this.d,15).gd(n),--this.a.d,DX(this),t},uZn.hd=function(n,t){return bpn(this),uG(this.d,15).hd(n,t)},uZn.kd=function(n,t){return bpn(this),S6(this.a,this.e,uG(this.d,15).kd(n,t),this.b?this.b:this)},zW(AZn,"AbstractMapBasedMultimap/WrappedList",744),sDn(1126,744,{20:1,31:1,16:1,15:1,59:1},Yx),zW(AZn,"AbstractMapBasedMultimap/RandomAccessWrappedList",1126),sDn(628,1,$Zn,WU),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return FY(this),this.b.Ob()},uZn.Pb=function(){return FY(this),this.b.Pb()},uZn.Qb=function(){zD(this)},zW(AZn,"AbstractMapBasedMultimap/WrappedCollection/WrappedIterator",628),sDn(745,628,UZn,JN,UY),uZn.Qb=function(){zD(this)},uZn.Rb=function(n){var t;t=0==qA(this.a),(FY(this),uG(this.b,128)).Rb(n),++this.a.a.d,t&&mF(this.a)},uZn.Sb=function(){return(FY(this),uG(this.b,128)).Sb()},uZn.Tb=function(){return(FY(this),uG(this.b,128)).Tb()},uZn.Ub=function(){return(FY(this),uG(this.b,128)).Ub()},uZn.Vb=function(){return(FY(this),uG(this.b,128)).Vb()},uZn.Wb=function(n){(FY(this),uG(this.b,128)).Wb(n)},zW(AZn,"AbstractMapBasedMultimap/WrappedList/WrappedListIterator",745),sDn(743,551,BZn,AK),uZn.Nc=function(){return bpn(this),this.d.Nc()},zW(AZn,"AbstractMapBasedMultimap/WrappedSortedSet",743),sDn(1125,743,HZn,TN),zW(AZn,"AbstractMapBasedMultimap/WrappedNavigableSet",1125),sDn(1124,551,FZn,LK),uZn.Nc=function(){return bpn(this),this.d.Nc()},zW(AZn,"AbstractMapBasedMultimap/WrappedSet",1124),sDn(1133,1,{},o),uZn.Kb=function(n){return P7(uG(n,44))},zW(AZn,"AbstractMapBasedMultimap/lambda$1$Type",1133),sDn(1132,1,{},Wl),uZn.Kb=function(n){return new FE(this.a,n)},zW(AZn,"AbstractMapBasedMultimap/lambda$2$Type",1132);var Mat,Tat,jat,Eat,Sat=Iq(DZn,"Map/Entry");sDn(358,1,GZn),uZn.Fb=function(n){var t;return!!F$(n,44)&&(t=uG(n,44),xQ(this.ld(),t.ld())&&xQ(this.md(),t.md()))},uZn.Hb=function(){var n,t;return n=this.ld(),t=this.md(),(null==n?0:Hon(n))^(null==t?0:Hon(t))},uZn.nd=function(n){throw hv(new Kv)},uZn.Ib=function(){return this.ld()+"="+this.md()},zW(AZn,qZn,358),sDn(2086,31,RZn),uZn.$b=function(){this.od().$b()},uZn.Hc=function(n){var t;return!!F$(n,44)&&(t=uG(n,44),E4(this.od(),t.ld(),t.md()))},uZn.Mc=function(n){var t;return!!F$(n,44)&&(t=uG(n,44),S4(this.od(),t.ld(),t.md()))},uZn.gc=function(){return this.od().d},zW(AZn,"Multimaps/Entries",2086),sDn(749,2086,RZn,Ql),uZn.Kc=function(){return this.a.kc()},uZn.od=function(){return this.a},uZn.Nc=function(){return this.a.lc()},zW(AZn,"AbstractMultimap/Entries",749),sDn(750,749,FZn,Ty),uZn.Nc=function(){return this.a.lc()},uZn.Fb=function(n){return OOn(this,n)},uZn.Hb=function(){return Jon(this)},zW(AZn,"AbstractMultimap/EntrySet",750),sDn(751,31,RZn,Jl),uZn.$b=function(){this.a.$b()},uZn.Hc=function(n){return qln(this.a,n)},uZn.Kc=function(){return this.a.nc()},uZn.gc=function(){return this.a.d},uZn.Nc=function(){return this.a.oc()},zW(AZn,"AbstractMultimap/Values",751),sDn(2087,31,{849:1,20:1,31:1,16:1}),uZn.Jc=function(n){WW(n),uY(this).Jc(new yb(n))},uZn.Nc=function(){var n;return ICn(n=uY(this).Nc(),new d,64|1296&n.yd(),this.a.d)},uZn.Fc=function(n){return HM(),!0},uZn.Gc=function(n){return WW(this),WW(n),F$(n,552)?V4(uG(n,849)):!n.dc()&&cin(this,n.Kc())},uZn.Hc=function(n){var t;return((t=uG(Xwn(nZ(this.a),n),16))?t.gc():0)>0},uZn.Fb=function(n){return nxn(this,n)},uZn.Hb=function(){return Hon(uY(this))},uZn.dc=function(){return uY(this).dc()},uZn.Mc=function(n){return bNn(this,n,1)>0},uZn.Ib=function(){return cpn(uY(this))},zW(AZn,"AbstractMultiset",2087),sDn(2089,2068,FZn),uZn.$b=function(){ban(this.a.a)},uZn.Hc=function(n){var t;return!(!F$(n,504)||(t=uG(n,425),uG(t.a.md(),16).gc()<=0||S2(this.a,t.a.ld())!=uG(t.a.md(),16).gc()))},uZn.Mc=function(n){var t,e,i;return!(!F$(n,504)||(t=(e=uG(n,425)).a.ld(),0==(i=uG(e.a.md(),16).gc())))&&wNn(this.a,t,i)},zW(AZn,"Multisets/EntrySet",2089),sDn(1139,2089,FZn,Yl),uZn.Kc=function(){return new Dy(vz(nZ(this.a.a)).Kc())},uZn.gc=function(){return nZ(this.a.a).gc()},zW(AZn,"AbstractMultiset/EntrySet",1139),sDn(627,742,NZn),uZn.hc=function(){return this.pd()},uZn.jc=function(){return this.qd()},uZn.cc=function(n){return this.rd(n)},uZn.fc=function(n){return this.sd(n)},uZn.Zb=function(){return this.f||(this.f=this.ac())},uZn.qd=function(){return hZ(),hZ(),Wot},uZn.Fb=function(n){return Aln(this,n)},uZn.rd=function(n){return uG(Y9(this,n),21)},uZn.sd=function(n){return uG(twn(this,n),21)},uZn.mc=function(n){return hZ(),new nT(uG(n,21))},uZn.pc=function(n,t){return new LK(this,n,uG(t,21))},zW(AZn,"AbstractSetMultimap",627),sDn(1723,627,NZn),uZn.hc=function(){return new Hj(this.b)},uZn.pd=function(){return new Hj(this.b)},uZn.jc=function(){return UQ(new Hj(this.b))},uZn.qd=function(){return UQ(new Hj(this.b))},uZn.cc=function(n){return uG(uG(Y9(this,n),21),87)},uZn.rd=function(n){return uG(uG(Y9(this,n),21),87)},uZn.fc=function(n){return uG(uG(twn(this,n),21),87)},uZn.sd=function(n){return uG(uG(twn(this,n),21),87)},uZn.mc=function(n){return F$(n,277)?UQ(uG(n,277)):(hZ(),new mx(uG(n,87)))},uZn.Zb=function(){return this.f||(this.f=F$(this.c,139)?new $K(this,uG(this.c,139)):F$(this.c,133)?new NK(this,uG(this.c,133)):new OE(this,this.c))},uZn.pc=function(n,t){return F$(t,277)?new TN(this,n,uG(t,277)):new AK(this,n,uG(t,87))},zW(AZn,"AbstractSortedSetMultimap",1723),sDn(1724,1723,NZn),uZn.Zb=function(){return uG(uG(this.f||(this.f=F$(this.c,139)?new $K(this,uG(this.c,139)):F$(this.c,133)?new NK(this,uG(this.c,133)):new OE(this,this.c)),133),139)},uZn.ec=function(){return uG(uG(this.i||(this.i=F$(this.c,139)?new ME(this,uG(this.c,139)):F$(this.c,133)?new yE(this,uG(this.c,133)):new RD(this,this.c)),87),277)},uZn.bc=function(){return F$(this.c,139)?new ME(this,uG(this.c,139)):F$(this.c,133)?new yE(this,uG(this.c,133)):new RD(this,this.c)},zW(AZn,"AbstractSortedKeySortedSetMultimap",1724),sDn(2109,1,{2046:1}),uZn.Fb=function(n){return fSn(this,n)},uZn.Hb=function(){return tfn(this.g||(this.g=new nb(this)))},uZn.Ib=function(){return KPn(this.f||(this.f=new VD(this)))},zW(AZn,"AbstractTable",2109),sDn(679,KZn,FZn,nb),uZn.$b=function(){UM()},uZn.Hc=function(n){var t,e;return!!F$(n,479)&&(t=uG(n,697),!!(e=uG(Xwn(BW(this.a),GA(t.c.e,t.b)),85))&&Gwn(e.vc(),new FE(GA(t.c.c,t.a),I7(t.c,t.b,t.a))))},uZn.Kc=function(){return CZ(this.a)},uZn.Mc=function(n){var t,e;return!!F$(n,479)&&(t=uG(n,697),!!(e=uG(Xwn(BW(this.a),GA(t.c.e,t.b)),85))&&qwn(e.vc(),new FE(GA(t.c.c,t.a),I7(t.c,t.b,t.a))))},uZn.gc=function(){return $q(this.a)},uZn.Nc=function(){return u6(this.a)},zW(AZn,"AbstractTable/CellSet",679),sDn(2025,31,RZn,tb),uZn.$b=function(){UM()},uZn.Hc=function(n){return QPn(this.a,n)},uZn.Kc=function(){return IZ(this.a)},uZn.gc=function(){return $q(this.a)},uZn.Nc=function(){return y4(this.a)},zW(AZn,"AbstractTable/Values",2025),sDn(1697,1696,NZn),zW(AZn,"ArrayListMultimapGwtSerializationDependencies",1697),sDn(520,1697,NZn,rT,L2),uZn.hc=function(){return new R7(this.a)},uZn.a=0,zW(AZn,"ArrayListMultimap",520),sDn(678,2109,{678:1,2046:1,3:1},f$n),zW(AZn,"ArrayTable",678),sDn(2021,399,LZn,WD),uZn.Xb=function(n){return new Ofn(this.a,n)},zW(AZn,"ArrayTable/1",2021),sDn(2022,1,{},Xl),uZn.td=function(n){return new Ofn(this.a,n)},zW(AZn,"ArrayTable/1methodref$getCell$Type",2022),sDn(2110,1,{697:1}),uZn.Fb=function(n){var t;return n===this||!!F$(n,479)&&(t=uG(n,697),xQ(GA(this.c.e,this.b),GA(t.c.e,t.b))&&xQ(GA(this.c.c,this.a),GA(t.c.c,t.a))&&xQ(I7(this.c,this.b,this.a),I7(t.c,t.b,t.a)))},uZn.Hb=function(){return Obn(Uhn(cT(dat,1),EZn,1,5,[GA(this.c.e,this.b),GA(this.c.c,this.a),I7(this.c,this.b,this.a)]))},uZn.Ib=function(){return"("+GA(this.c.e,this.b)+","+GA(this.c.c,this.a)+")="+I7(this.c,this.b,this.a)},zW(AZn,"Tables/AbstractCell",2110),sDn(479,2110,{479:1,697:1},Ofn),uZn.a=0,uZn.b=0,uZn.d=0,zW(AZn,"ArrayTable/2",479),sDn(2024,1,{},zl),uZn.td=function(n){return Qtn(this.a,n)},zW(AZn,"ArrayTable/2methodref$getValue$Type",2024),sDn(2023,399,LZn,QD),uZn.Xb=function(n){return Qtn(this.a,n)},zW(AZn,"ArrayTable/3",2023),sDn(2077,2065,xZn),uZn.$b=function(){Hq(this.kc())},uZn.vc=function(){return new wb(this)},uZn.lc=function(){return new MY(this.kc(),this.gc())},zW(AZn,"Maps/IteratorBasedAbstractMap",2077),sDn(842,2077,xZn),uZn.$b=function(){throw hv(new Kv)},uZn._b=function(n){return Ej(this.c,n)},uZn.kc=function(){return new JD(this,this.c.b.c.gc())},uZn.lc=function(){return Dq(this.c.b.c.gc(),16,new Vl(this))},uZn.xc=function(n){var t;return(t=uG(W_(this.c,n),17))?this.vd(t.a):null},uZn.dc=function(){return this.c.b.c.dc()},uZn.ec=function(){return Tz(this.c)},uZn.zc=function(n,t){var e;if(!(e=uG(W_(this.c,n),17)))throw hv(new vM(this.ud()+" "+n+" not in "+Tz(this.c)));return this.wd(e.a,t)},uZn.Bc=function(n){throw hv(new Kv)},uZn.gc=function(){return this.c.b.c.gc()},zW(AZn,"ArrayTable/ArrayMap",842),sDn(2020,1,{},Vl),uZn.td=function(n){return qW(this.a,n)},zW(AZn,"ArrayTable/ArrayMap/0methodref$getEntry$Type",2020),sDn(2018,358,GZn,TE),uZn.ld=function(){return uR(this.a,this.b)},uZn.md=function(){return this.a.vd(this.b)},uZn.nd=function(n){return this.a.wd(this.b,n)},uZn.b=0,zW(AZn,"ArrayTable/ArrayMap/1",2018),sDn(2019,399,LZn,JD),uZn.Xb=function(n){return qW(this.a,n)},zW(AZn,"ArrayTable/ArrayMap/2",2019),sDn(2017,842,xZn,yV),uZn.ud=function(){return"Column"},uZn.vd=function(n){return I7(this.b,this.a,n)},uZn.wd=function(n,t){return Hhn(this.b,this.a,n,t)},uZn.a=0,zW(AZn,"ArrayTable/Row",2017),sDn(843,842,xZn,VD),uZn.vd=function(n){return new yV(this.a,n)},uZn.zc=function(n,t){return uG(t,85),GM()},uZn.wd=function(n,t){return uG(t,85),qM()},uZn.ud=function(){return"Row"},zW(AZn,"ArrayTable/RowMap",843),sDn(1157,1,WZn,jE),uZn.Ad=function(n){return!!(-262&this.a.yd()&n)},uZn.yd=function(){return-262&this.a.yd()},uZn.zd=function(){return this.a.zd()},uZn.Nb=function(n){this.a.Nb(new SE(n,this.b))},uZn.Bd=function(n){return this.a.Bd(new EE(n,this.b))},zW(AZn,"CollectSpliterators/1",1157),sDn(1158,1,QZn,EE),uZn.Cd=function(n){this.a.Cd(this.b.Kb(n))},zW(AZn,"CollectSpliterators/1/lambda$0$Type",1158),sDn(1159,1,QZn,SE),uZn.Cd=function(n){this.a.Cd(this.b.Kb(n))},zW(AZn,"CollectSpliterators/1/lambda$1$Type",1159),sDn(1154,1,WZn,x_),uZn.Ad=function(n){return!!((16464|this.b)&n)},uZn.yd=function(){return 16464|this.b},uZn.zd=function(){return this.a.zd()},uZn.Nb=function(n){this.a.Qe(new CE(n,this.c))},uZn.Bd=function(n){return this.a.Re(new PE(n,this.c))},uZn.b=0,zW(AZn,"CollectSpliterators/1WithCharacteristics",1154),sDn(1155,1,JZn,PE),uZn.Dd=function(n){this.a.Cd(this.b.td(n))},zW(AZn,"CollectSpliterators/1WithCharacteristics/lambda$0$Type",1155),sDn(1156,1,JZn,CE),uZn.Dd=function(n){this.a.Cd(this.b.td(n))},zW(AZn,"CollectSpliterators/1WithCharacteristics/lambda$1$Type",1156),sDn(1150,1,WZn),uZn.Ad=function(n){return!!(this.a&n)},uZn.yd=function(){return this.a},uZn.zd=function(){return this.e&&(this.b=g$(this.b,this.e.zd())),g$(this.b,0)},uZn.Nb=function(n){this.e&&(this.e.Nb(n),this.e=null),this.c.Nb(new IE(this,n)),this.b=0},uZn.Bd=function(n){for(;;){if(this.e&&this.e.Bd(n))return HA(this.b,YZn)&&(this.b=$gn(this.b,1)),!0;if(this.e=null,!this.c.Bd(new eb(this)))return!1}},uZn.a=0,uZn.b=0,zW(AZn,"CollectSpliterators/FlatMapSpliterator",1150),sDn(1152,1,QZn,eb),uZn.Cd=function(n){M_(this.a,n)},zW(AZn,"CollectSpliterators/FlatMapSpliterator/lambda$0$Type",1152),sDn(1153,1,QZn,IE),uZn.Cd=function(n){fY(this.a,this.b,n)},zW(AZn,"CollectSpliterators/FlatMapSpliterator/lambda$1$Type",1153),sDn(1151,1150,WZn,T6),zW(AZn,"CollectSpliterators/FlatMapSpliteratorOfObject",1151),sDn(253,1,ZZn),uZn.Fd=function(n){return this.Ed(uG(n,253))},uZn.Ed=function(n){var t;return n==(my(),Tat)?1:n==(py(),Mat)?-1:(qG(),0!=(t=Dun(this.a,n.a))?t:F$(this,526)==F$(n,526)?0:F$(this,526)?1:-1)},uZn.Id=function(){return this.a},uZn.Fb=function(n){return pTn(this,n)},zW(AZn,"Cut",253),sDn(1823,253,ZZn,ky),uZn.Ed=function(n){return n==this?0:1},uZn.Gd=function(n){throw hv(new Av)},uZn.Hd=function(n){n.a+="+\u221e)"},uZn.Id=function(){throw hv(new kM(n1n))},uZn.Hb=function(){return bS(),Avn(this)},uZn.Jd=function(n){return!1},uZn.Ib=function(){return"+\u221e"},zW(AZn,"Cut/AboveAll",1823),sDn(526,253,{253:1,526:1,3:1,34:1},bx),uZn.Gd=function(n){QA((n.a+="(",n),this.a)},uZn.Hd=function(n){jQ(QA(n,this.a),93)},uZn.Hb=function(){return~Hon(this.a)},uZn.Jd=function(n){return qG(),Dun(this.a,n)<0},uZn.Ib=function(){return"/"+this.a+"\\"},zW(AZn,"Cut/AboveValue",526),sDn(1822,253,ZZn,vy),uZn.Ed=function(n){return n==this?0:-1},uZn.Gd=function(n){n.a+="(-\u221e"},uZn.Hd=function(n){throw hv(new Av)},uZn.Id=function(){throw hv(new kM(n1n))},uZn.Hb=function(){return bS(),Avn(this)},uZn.Jd=function(n){return!0},uZn.Ib=function(){return"-\u221e"},zW(AZn,"Cut/BelowAll",1822),sDn(1824,253,ZZn,wx),uZn.Gd=function(n){QA((n.a+="[",n),this.a)},uZn.Hd=function(n){jQ(QA(n,this.a),41)},uZn.Hb=function(){return Hon(this.a)},uZn.Jd=function(n){return qG(),Dun(this.a,n)<=0},uZn.Ib=function(){return"\\"+this.a+"/"},zW(AZn,"Cut/BelowValue",1824),sDn(547,1,t1n),uZn.Jc=function(n){z8(this,n)},uZn.Ib=function(){return rgn(uG(bZ(this,"use Optional.orNull() instead of Optional.or(null)"),20).Kc())},zW(AZn,"FluentIterable",547),sDn(442,547,t1n,iN),uZn.Kc=function(){return new Fz(ix(this.a.Kc(),new h))},zW(AZn,"FluentIterable/2",442),sDn(1059,547,t1n,rN),uZn.Kc=function(){return OV(this)},zW(AZn,"FluentIterable/3",1059),sDn(724,399,LZn,YD),uZn.Xb=function(n){return this.a[n].Kc()},zW(AZn,"FluentIterable/3/1",724),sDn(2070,1,{}),uZn.Ib=function(){return cpn(this.Kd().b)},zW(AZn,"ForwardingObject",2070),sDn(2071,2070,e1n),uZn.Kd=function(){return this.Ld()},uZn.Jc=function(n){z8(this,n)},uZn.Lc=function(){return this.Oc()},uZn.Nc=function(){return new h3(this,0)},uZn.Oc=function(){return new fX(null,this.Nc())},uZn.Fc=function(n){return this.Ld(),Rj()},uZn.Gc=function(n){return this.Ld(),Kj()},uZn.$b=function(){this.Ld(),Fj()},uZn.Hc=function(n){return this.Ld().Hc(n)},uZn.Ic=function(n){return this.Ld().Ic(n)},uZn.dc=function(){return this.Ld().b.dc()},uZn.Kc=function(){return this.Ld().Kc()},uZn.Mc=function(n){return this.Ld(),_j()},uZn.gc=function(){return this.Ld().b.gc()},uZn.Pc=function(){return this.Ld().Pc()},uZn.Qc=function(n){return this.Ld().Qc(n)},zW(AZn,"ForwardingCollection",2071),sDn(2078,31,i1n),uZn.Kc=function(){return this.Od()},uZn.Fc=function(n){throw hv(new Kv)},uZn.Gc=function(n){throw hv(new Kv)},uZn.Md=function(){return this.c||(this.c=this.Nd())},uZn.$b=function(){throw hv(new Kv)},uZn.Hc=function(n){return null!=n&&Wpn(this,n,!1)},uZn.Nd=function(){switch(this.gc()){case 0:return ZW(),ZW(),jat;case 1:return ZW(),new Uq(WW(this.Od().Pb()));default:return new TV(this,this.Pc())}},uZn.Mc=function(n){throw hv(new Kv)},zW(AZn,"ImmutableCollection",2078),sDn(727,2078,i1n,jv),uZn.Kc=function(){return jtn(this.a.Kc())},uZn.Hc=function(n){return null!=n&&this.a.Hc(n)},uZn.Ic=function(n){return this.a.Ic(n)},uZn.dc=function(){return this.a.dc()},uZn.Od=function(){return jtn(this.a.Kc())},uZn.gc=function(){return this.a.gc()},uZn.Pc=function(){return this.a.Pc()},uZn.Qc=function(n){return this.a.Qc(n)},uZn.Ib=function(){return cpn(this.a)},zW(AZn,"ForwardingImmutableCollection",727),sDn(307,2078,r1n),uZn.Kc=function(){return this.Od()},uZn.ed=function(){return this.Pd(0)},uZn.fd=function(n){return this.Pd(n)},uZn.jd=function(n){Lon(this,n)},uZn.Nc=function(){return new h3(this,16)},uZn.kd=function(n,t){return this.Qd(n,t)},uZn.bd=function(n,t){throw hv(new Kv)},uZn.cd=function(n,t){throw hv(new Kv)},uZn.Md=function(){return this},uZn.Fb=function(n){return RDn(this,n)},uZn.Hb=function(){return Xsn(this)},uZn.dd=function(n){return null==n?-1:uTn(this,n)},uZn.Od=function(){return this.Pd(0)},uZn.Pd=function(n){return oR(this,n)},uZn.gd=function(n){throw hv(new Kv)},uZn.hd=function(n,t){throw hv(new Kv)},uZn.Qd=function(n,t){return Dwn(new C2(new qE(this),n,t))},zW(AZn,"ImmutableList",307),sDn(2105,307,r1n),uZn.Kc=function(){return jtn(this.Rd().Kc())},uZn.kd=function(n,t){return Dwn(this.Rd().kd(n,t))},uZn.Hc=function(n){return null!=n&&this.Rd().Hc(n)},uZn.Ic=function(n){return this.Rd().Ic(n)},uZn.Fb=function(n){return udn(this.Rd(),n)},uZn.Xb=function(n){return GA(this,n)},uZn.Hb=function(){return Hon(this.Rd())},uZn.dd=function(n){return this.Rd().dd(n)},uZn.dc=function(){return this.Rd().dc()},uZn.Od=function(){return jtn(this.Rd().Kc())},uZn.gc=function(){return this.Rd().gc()},uZn.Qd=function(n,t){return Dwn(this.Rd().kd(n,t))},uZn.Pc=function(){return this.Rd().Qc(Inn(dat,EZn,1,this.Rd().gc(),5,1))},uZn.Qc=function(n){return this.Rd().Qc(n)},uZn.Ib=function(){return cpn(this.Rd())},zW(AZn,"ForwardingImmutableList",2105),sDn(729,1,a1n),uZn.vc=function(){return Mz(this)},uZn.wc=function(n){Yun(this,n)},uZn.ec=function(){return Tz(this)},uZn.yc=function(n,t,e){return Jgn(this,n,t,e)},uZn.Cc=function(){return this.Vd()},uZn.$b=function(){throw hv(new Kv)},uZn._b=function(n){return null!=this.xc(n)},uZn.uc=function(n){return this.Vd().Hc(n)},uZn.Td=function(){return new Ev(this)},uZn.Ud=function(){return new Sv(this)},uZn.Fb=function(n){return Wln(this,n)},uZn.Hb=function(){return Mz(this).Hb()},uZn.dc=function(){return 0==this.gc()},uZn.zc=function(n,t){return BM()},uZn.Bc=function(n){throw hv(new Kv)},uZn.Ib=function(){return QIn(this)},uZn.Vd=function(){return this.e?this.e:this.e=this.Ud()},uZn.c=null,uZn.d=null,uZn.e=null,zW(AZn,"ImmutableMap",729),sDn(730,729,a1n),uZn._b=function(n){return Ej(this,n)},uZn.uc=function(n){return iS(this.b,n)},uZn.Sd=function(){return $wn(new Zl(this))},uZn.Td=function(){return $wn(SJ(this.b))},uZn.Ud=function(){return sB(),new jv(jJ(this.b))},uZn.Fb=function(n){return rS(this.b,n)},uZn.xc=function(n){return W_(this,n)},uZn.Hb=function(){return Hon(this.b.c)},uZn.dc=function(){return this.b.c.dc()},uZn.gc=function(){return this.b.c.gc()},uZn.Ib=function(){return cpn(this.b.c)},zW(AZn,"ForwardingImmutableMap",730),sDn(2072,2071,o1n),uZn.Kd=function(){return this.Wd()},uZn.Ld=function(){return this.Wd()},uZn.Nc=function(){return new h3(this,1)},uZn.Fb=function(n){return n===this||this.Wd().Fb(n)},uZn.Hb=function(){return this.Wd().Hb()},zW(AZn,"ForwardingSet",2072),sDn(1085,2072,o1n,Zl),uZn.Kd=function(){return EJ(this.a.b)},uZn.Ld=function(){return EJ(this.a.b)},uZn.Hc=function(n){if(F$(n,44)&&null==uG(n,44).ld())return!1;try{return eS(EJ(this.a.b),n)}catch(t){if(F$(t=Ehn(t),212))return!1;throw hv(t)}},uZn.Wd=function(){return EJ(this.a.b)},uZn.Qc=function(n){var t;return t=YZ(EJ(this.a.b),n),EJ(this.a.b).b.gc()=0?"+":"")+(i/60|0),t=FL(e.Math.abs(i)%60),(cIn(),nut)[this.q.getDay()]+" "+tut[this.q.getMonth()]+" "+FL(this.q.getDate())+" "+FL(this.q.getHours())+":"+FL(this.q.getMinutes())+":"+FL(this.q.getSeconds())+" GMT"+n+t+" "+this.q.getFullYear()};var Xat,zat,Vat,Wat,Qat,Jat,Yat,Zat,not,tot,eot,iot=zW(DZn,"Date",206);sDn(2015,206,s0n,DEn),uZn.a=!1,uZn.b=0,uZn.c=0,uZn.d=0,uZn.e=0,uZn.f=0,uZn.g=!1,uZn.i=0,uZn.j=0,uZn.k=0,uZn.n=0,uZn.o=0,uZn.p=0,zW("com.google.gwt.i18n.shared.impl","DateRecord",2015),sDn(2064,1,{}),uZn.pe=function(){return null},uZn.qe=function(){return null},uZn.re=function(){return null},uZn.se=function(){return null},uZn.te=function(){return null},zW(h0n,"JSONValue",2064),sDn(221,2064,{221:1},Ib,Eb),uZn.Fb=function(n){return!!F$(n,221)&&j3(this.a,uG(n,221).a)},uZn.oe=function(){return uv},uZn.Hb=function(){return OZ(this.a)},uZn.pe=function(){return this},uZn.Ib=function(){var n,t,e;for(e=new lx("["),t=0,n=this.a.length;t0&&(e.a+=","),QA(e,uin(this,t));return e.a+="]",e.a},zW(h0n,"JSONArray",221),sDn(493,2064,{493:1},Sb),uZn.oe=function(){return sv},uZn.qe=function(){return this},uZn.Ib=function(){return qx(),""+this.a},uZn.a=!1,zW(h0n,"JSONBoolean",493),sDn(997,63,S1n,Fy),zW(h0n,"JSONException",997),sDn(1036,2064,{},T),uZn.oe=function(){return fv},uZn.Ib=function(){return IZn},zW(h0n,"JSONNull",1036),sDn(263,2064,{263:1},Pb),uZn.Fb=function(n){return!!F$(n,263)&&this.a==uG(n,263).a},uZn.oe=function(){return av},uZn.Hb=function(){return OL(this.a)},uZn.re=function(){return this},uZn.Ib=function(){return this.a+""},uZn.a=0,zW(h0n,"JSONNumber",263),sDn(190,2064,{190:1},_y,Cb),uZn.Fb=function(n){return!!F$(n,190)&&j3(this.a,uG(n,190).a)},uZn.oe=function(){return ov},uZn.Hb=function(){return OZ(this.a)},uZn.se=function(){return this},uZn.Ib=function(){var n,t,e,i,r,c;for(c=new lx("{"),n=!0,i=0,r=(e=Yon(this,Inn($ot,zZn,2,0,6,1))).length;i=0?":"+this.c:"")+")"},uZn.c=0;var jot=zW(kZn,"StackTraceElement",319);bZn={3:1,484:1,34:1,2:1};var Eot,Sot,Pot,Cot,Iot,Oot,Aot,Lot,Not,$ot=zW(kZn,C1n,2);sDn(111,427,{484:1},zM,VM,fx),zW(kZn,"StringBuffer",111),sDn(104,427,{484:1},WM,QM,lx),zW(kZn,"StringBuilder",104),sDn(702,77,v0n,JM),zW(kZn,"StringIndexOutOfBoundsException",702),sDn(2145,1,{}),sDn(48,63,{3:1,103:1,63:1,82:1,48:1},Kv,TM),zW(kZn,"UnsupportedOperationException",48),sDn(247,242,{3:1,34:1,242:1,247:1},Edn,Wj),uZn.Fd=function(n){return $Gn(this,uG(n,247))},uZn.ue=function(){return YIn(dzn(this))},uZn.Fb=function(n){var t;return this===n||!!F$(n,247)&&(t=uG(n,247),this.e==t.e&&0==$Gn(this,t))},uZn.Hb=function(){var n;return 0!=this.b?this.b:this.a<54?(n=Bsn(this.f),this.b=pz(E3(n,-1)),this.b=33*this.b+pz(E3($z(n,32),-1)),this.b=17*this.b+t0(this.e),this.b):(this.b=17*cwn(this.c)+t0(this.e),this.b)},uZn.Ib=function(){return dzn(this)},uZn.a=0,uZn.b=0,uZn.d=0,uZn.e=0,uZn.f=0;var Dot,xot,Rot,Kot,Fot,_ot,Bot=zW("java.math","BigDecimal",247);sDn(92,242,{3:1,34:1,242:1,92:1},Z5,x3,VV,nkn,PN),uZn.Fd=function(n){return Pvn(this,uG(n,92))},uZn.ue=function(){return YIn(bYn(this,0))},uZn.Fb=function(n){return Cpn(this,n)},uZn.Hb=function(){return cwn(this)},uZn.Ib=function(){return bYn(this,0)},uZn.b=-2,uZn.c=0,uZn.d=0,uZn.e=0;var Hot,Uot,Got,qot,Xot=zW("java.math","BigInteger",92);sDn(498,2065,xZn),uZn.$b=function(){$V(this)},uZn._b=function(n){return PV(this,n)},uZn.uc=function(n){return Qln(this,n,this.i)||Qln(this,n,this.f)},uZn.vc=function(){return new Nw(this)},uZn.xc=function(n){return cQ(this,n)},uZn.zc=function(n,t){return vJ(this,n,t)},uZn.Bc=function(n){return u7(this,n)},uZn.gc=function(){return oS(this)},uZn.g=0,zW(DZn,"AbstractHashMap",498),sDn(267,KZn,FZn,Nw),uZn.$b=function(){this.a.$b()},uZn.Hc=function(n){return Q4(this,n)},uZn.Kc=function(){return new bsn(this.a)},uZn.Mc=function(n){var t;return!!Q4(this,n)&&(t=uG(n,44).ld(),this.a.Bc(t),!0)},uZn.gc=function(){return this.a.gc()},zW(DZn,"AbstractHashMap/EntrySet",267),sDn(268,1,$Zn,bsn),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){return von(this)},uZn.Ob=function(){return this.b},uZn.Qb=function(){Oen(this)},uZn.b=!1,uZn.d=0,zW(DZn,"AbstractHashMap/EntrySetIterator",268),sDn(426,1,$Zn,Jw),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return AP(this)},uZn.Pb=function(){return _Y(this)},uZn.Qb=function(){LQ(this)},uZn.b=0,uZn.c=-1,zW(DZn,"AbstractList/IteratorImpl",426),sDn(98,426,UZn,N4),uZn.Qb=function(){LQ(this)},uZn.Rb=function(n){pF(this,n)},uZn.Sb=function(){return this.b>0},uZn.Tb=function(){return this.b},uZn.Ub=function(){return MK(this.b>0),this.a.Xb(this.c=--this.b)},uZn.Vb=function(){return this.b-1},uZn.Wb=function(n){TK(-1!=this.c),this.a.hd(this.c,n)},zW(DZn,"AbstractList/ListIteratorImpl",98),sDn(244,56,m1n,C2),uZn.bd=function(n,t){o3(n,this.b),this.c.bd(this.a+n,t),++this.b},uZn.Xb=function(n){return u3(n,this.b),this.c.Xb(this.a+n)},uZn.gd=function(n){var t;return u3(n,this.b),t=this.c.gd(this.a+n),--this.b,t},uZn.hd=function(n,t){return u3(n,this.b),this.c.hd(this.a+n,t)},uZn.gc=function(){return this.b},uZn.a=0,uZn.b=0,zW(DZn,"AbstractList/SubList",244),sDn(266,KZn,FZn,Lw),uZn.$b=function(){this.a.$b()},uZn.Hc=function(n){return this.a._b(n)},uZn.Kc=function(){return new Kw(this.a.vc().Kc())},uZn.Mc=function(n){return!!this.a._b(n)&&(this.a.Bc(n),!0)},uZn.gc=function(){return this.a.gc()},zW(DZn,"AbstractMap/1",266),sDn(541,1,$Zn,Kw),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return this.a.Ob()},uZn.Pb=function(){return uG(this.a.Pb(),44).ld()},uZn.Qb=function(){this.a.Qb()},zW(DZn,"AbstractMap/1/1",541),sDn(231,31,RZn,Fw),uZn.$b=function(){this.a.$b()},uZn.Hc=function(n){return this.a.uc(n)},uZn.Kc=function(){return new _w(this.a.vc().Kc())},uZn.gc=function(){return this.a.gc()},zW(DZn,"AbstractMap/2",231),sDn(301,1,$Zn,_w),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return this.a.Ob()},uZn.Pb=function(){return uG(this.a.Pb(),44).md()},uZn.Qb=function(){this.a.Qb()},zW(DZn,"AbstractMap/2/1",301),sDn(494,1,{494:1,44:1}),uZn.Fb=function(n){var t;return!!F$(n,44)&&(t=uG(n,44),OJ(this.d,t.ld())&&OJ(this.e,t.md()))},uZn.ld=function(){return this.d},uZn.md=function(){return this.e},uZn.Hb=function(){return VN(this.d)^VN(this.e)},uZn.nd=function(n){return wF(this,n)},uZn.Ib=function(){return this.d+"="+this.e},zW(DZn,"AbstractMap/AbstractEntry",494),sDn(397,494,{494:1,397:1,44:1},VP),zW(DZn,"AbstractMap/SimpleEntry",397),sDn(2082,1,$0n),uZn.Fb=function(n){var t;return!!F$(n,44)&&(t=uG(n,44),OJ(this.ld(),t.ld())&&OJ(this.md(),t.md()))},uZn.Hb=function(){return VN(this.ld())^VN(this.md())},uZn.Ib=function(){return this.ld()+"="+this.md()},zW(DZn,qZn,2082),sDn(2090,2065,_Zn),uZn.Xc=function(n){return Sj(this.Ee(n))},uZn.tc=function(n){return I9(this,n)},uZn._b=function(n){return dF(this,n)},uZn.vc=function(){return new Uw(this)},uZn.Tc=function(){return DV(this.Ge())},uZn.Yc=function(n){return Sj(this.He(n))},uZn.xc=function(n){var t;return t=n,DA(this.Fe(t))},uZn.$c=function(n){return Sj(this.Ie(n))},uZn.ec=function(){return new Bw(this)},uZn.Vc=function(){return DV(this.Je())},uZn._c=function(n){return Sj(this.Ke(n))},zW(DZn,"AbstractNavigableMap",2090),sDn(629,KZn,FZn,Uw),uZn.Hc=function(n){return F$(n,44)&&I9(this.b,uG(n,44))},uZn.Kc=function(){return this.b.De()},uZn.Mc=function(n){var t;return!!F$(n,44)&&(t=uG(n,44),this.b.Le(t))},uZn.gc=function(){return this.b.gc()},zW(DZn,"AbstractNavigableMap/EntrySet",629),sDn(1146,KZn,HZn,Bw),uZn.Nc=function(){return new GP(this)},uZn.$b=function(){this.a.$b()},uZn.Hc=function(n){return dF(this.a,n)},uZn.Kc=function(){return new Hw(this.a.vc().b.De())},uZn.Mc=function(n){return!!dF(this.a,n)&&(this.a.Bc(n),!0)},uZn.gc=function(){return this.a.gc()},zW(DZn,"AbstractNavigableMap/NavigableKeySet",1146),sDn(1147,1,$Zn,Hw),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return AP(this.a.a)},uZn.Pb=function(){return kR(this.a).ld()},uZn.Qb=function(){rB(this.a)},zW(DZn,"AbstractNavigableMap/NavigableKeySet/1",1147),sDn(2103,31,RZn),uZn.Fc=function(n){return kG(_Cn(this,n),D0n),!0},uZn.Gc=function(n){return tJ(n),vG(n!=this,"Can't add a queue to itself"),Qon(this,n)},uZn.$b=function(){for(;null!=hin(this););},zW(DZn,"AbstractQueue",2103),sDn(310,31,{4:1,20:1,31:1,16:1},ND,$4),uZn.Fc=function(n){return O6(this,n),!0},uZn.$b=function(){q5(this)},uZn.Hc=function(n){return Chn(new XJ(this),n)},uZn.dc=function(){return LM(this)},uZn.Kc=function(){return new XJ(this)},uZn.Mc=function(n){return m0(new XJ(this),n)},uZn.gc=function(){return this.c-this.b&this.a.length-1},uZn.Nc=function(){return new h3(this,272)},uZn.Qc=function(n){var t;return t=this.c-this.b&this.a.length-1,n.lengtht&&uQ(n,t,null),n},uZn.b=0,uZn.c=0,zW(DZn,"ArrayDeque",310),sDn(459,1,$Zn,XJ),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return this.a!=this.b},uZn.Pb=function(){return rwn(this)},uZn.Qb=function(){lan(this)},uZn.a=0,uZn.b=0,uZn.c=-1,zW(DZn,"ArrayDeque/IteratorImpl",459),sDn(13,56,x0n,Zm,R7,Z_),uZn.bd=function(n,t){GX(this,n,t)},uZn.Fc=function(n){return kD(this,n)},uZn.cd=function(n,t){return Cbn(this,n,t)},uZn.Gc=function(n){return Ohn(this,n)},uZn.$b=function(){Xv(this.c,0)},uZn.Hc=function(n){return-1!=Ten(this,n,0)},uZn.Jc=function(n){Prn(this,n)},uZn.Xb=function(n){return zq(this,n)},uZn.dd=function(n){return Ten(this,n,0)},uZn.dc=function(){return 0==this.c.length},uZn.Kc=function(){return new Ww(this)},uZn.gd=function(n){return i7(this,n)},uZn.Mc=function(n){return men(this,n)},uZn.ce=function(n,t){P2(this,n,t)},uZn.hd=function(n,t){return Y8(this,n,t)},uZn.gc=function(){return this.c.length},uZn.jd=function(n){f$(this,n)},uZn.Pc=function(){return tq(this.c)},uZn.Qc=function(n){return Ekn(this,n)};var zot,Vot,Wot,Qot,Jot,Yot,Zot,nut,tut,eut=zW(DZn,"ArrayList",13);sDn(7,1,$Zn,Ww),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return l$(this)},uZn.Pb=function(){return N3(this)},uZn.Qb=function(){tW(this)},uZn.a=0,uZn.b=-1,zW(DZn,"ArrayList/1",7),sDn(2112,e.Function,{},P),uZn.Me=function(n,t){return ugn(n,t)},sDn(151,56,R0n,IM),uZn.Hc=function(n){return-1!=gan(this,n)},uZn.Jc=function(n){var t,e,i,r;for(tJ(n),i=0,r=(e=this.a).length;i0)throw hv(new vM(Y0n+n+" greater than "+this.e));return this.f.Te()?G1(this.c,this.b,this.a,n,t):N2(this.c,n,t)},uZn.zc=function(n,t){if(!ljn(this.c,this.f,n,this.b,this.a,this.e,this.d))throw hv(new vM(n+" outside the range "+this.b+" to "+this.e));return xfn(this.c,n,t)},uZn.Bc=function(n){var t;return t=n,ljn(this.c,this.f,t,this.b,this.a,this.e,this.d)?V1(this.c,t):null},uZn.Le=function(n){return $Q(this,n.ld())&&Lnn(this.c,n)},uZn.gc=function(){var n,t,e;if(!((t=this.f.Te()?this.a?Zmn(this.c,this.b,!0):Zmn(this.c,this.b,!1):Ytn(this.c))&&$Q(this,t.d)&&t))return 0;for(n=0,e=new dun(this.c,this.f,this.b,this.a,this.e,this.d);AP(e.a);e.b=uG(_Y(e.a),44))++n;return n},uZn.ad=function(n,t){if(this.f.Te()&&this.c.a.Ne(n,this.b)<0)throw hv(new vM(Y0n+n+Z0n+this.b));return this.f.Ue()?G1(this.c,n,t,this.e,this.d):$2(this.c,n,t)},uZn.a=!1,uZn.d=!1,zW(DZn,"TreeMap/SubMap",631),sDn(304,22,n2n,qP),uZn.Te=function(){return!1},uZn.Ue=function(){return!1};var Mut,Tut=_cn(DZn,"TreeMap/SubMapType",304,Oat,K6,hB);sDn(1143,304,n2n,SN),uZn.Ue=function(){return!0},_cn(DZn,"TreeMap/SubMapType/1",1143,Tut,null,null),sDn(1144,304,n2n,P$),uZn.Te=function(){return!0},uZn.Ue=function(){return!0},_cn(DZn,"TreeMap/SubMapType/2",1144,Tut,null,null),sDn(1145,304,n2n,EN),uZn.Te=function(){return!0},_cn(DZn,"TreeMap/SubMapType/3",1145,Tut,null,null),sDn(157,KZn,{3:1,20:1,31:1,16:1,277:1,21:1,87:1,157:1},rk,Hj,od),uZn.Nc=function(){return new GP(this)},uZn.Fc=function(n){return _V(this,n)},uZn.$b=function(){this.a.$b()},uZn.Hc=function(n){return this.a._b(n)},uZn.Kc=function(){return this.a.ec().Kc()},uZn.Mc=function(n){return sD(this,n)},uZn.gc=function(){return this.a.gc()};var jut=zW(DZn,"TreeSet",157);sDn(1082,1,{},ud),uZn.Ve=function(n,t){return _K(this.a,n,t)},zW(t2n,"BinaryOperator/lambda$0$Type",1082),sDn(1083,1,{},sd),uZn.Ve=function(n,t){return BK(this.a,n,t)},zW(t2n,"BinaryOperator/lambda$1$Type",1083),sDn(952,1,{},H),uZn.Kb=function(n){return n},zW(t2n,"Function/lambda$0$Type",952),sDn(395,1,y1n,hd),uZn.Mb=function(n){return!this.a.Mb(n)},zW(t2n,"Predicate/lambda$2$Type",395),sDn(581,1,{581:1});var Eut,Sut,Put=zW(e2n,"Handler",581);sDn(2107,1,yZn),uZn.xe=function(){return"DUMMY"},uZn.Ib=function(){return this.xe()},zW(e2n,"Level",2107),sDn(1706,2107,yZn,U),uZn.xe=function(){return"INFO"},zW(e2n,"Level/LevelInfo",1706),sDn(1843,1,{},ik),zW(e2n,"LogManager",1843),sDn(1896,1,yZn,iB),uZn.b=null,zW(e2n,"LogRecord",1896),sDn(525,1,{525:1},e9),uZn.e=!1;var Cut,Iut,Out,Aut=!1,Lut=!1,Nut=!1,$ut=!1,Dut=!1;zW(e2n,"Logger",525),sDn(835,581,{581:1},G),zW(e2n,"SimpleConsoleLogHandler",835),sDn(108,22,{3:1,34:1,22:1,108:1},XP);var xut,Rut=_cn(c2n,"Collector/Characteristics",108,Oat,D2,fB);sDn(758,1,{},WV),zW(c2n,"CollectorImpl",758),sDn(1074,1,{},q),uZn.Ve=function(n,t){return idn(uG(n,213),uG(t,213))},zW(c2n,"Collectors/10methodref$merge$Type",1074),sDn(1075,1,{},X),uZn.Kb=function(n){return R4(uG(n,213))},zW(c2n,"Collectors/11methodref$toString$Type",1075),sDn(1076,1,{},fd),uZn.Kb=function(n){return qx(),!!IL(n)},zW(c2n,"Collectors/12methodref$test$Type",1076),sDn(144,1,{},z),uZn.Yd=function(n,t){uG(n,16).Fc(t)},zW(c2n,"Collectors/20methodref$add$Type",144),sDn(146,1,{},V),uZn.Xe=function(){return new Zm},zW(c2n,"Collectors/21methodref$ctor$Type",146),sDn(359,1,{},W),uZn.Xe=function(){return new ek},zW(c2n,"Collectors/23methodref$ctor$Type",359),sDn(360,1,{},Q),uZn.Yd=function(n,t){FV(uG(n,49),t)},zW(c2n,"Collectors/24methodref$add$Type",360),sDn(1069,1,{},J),uZn.Ve=function(n,t){return IS(uG(n,15),uG(t,16))},zW(c2n,"Collectors/4methodref$addAll$Type",1069),sDn(1073,1,{},Y),uZn.Yd=function(n,t){o7(uG(n,213),uG(t,484))},zW(c2n,"Collectors/9methodref$add$Type",1073),sDn(1072,1,{},fG),uZn.Xe=function(){return new Ysn(this.a,this.b,this.c)},zW(c2n,"Collectors/lambda$15$Type",1072),sDn(1077,1,{},Z),uZn.Xe=function(){var n;return Akn(n=new u8,(qx(),!1),new Zm),Akn(n,!0,new Zm),n},zW(c2n,"Collectors/lambda$22$Type",1077),sDn(1078,1,{},ld),uZn.Xe=function(){return Uhn(cT(dat,1),EZn,1,5,[this.a])},zW(c2n,"Collectors/lambda$25$Type",1078),sDn(1079,1,{},bd),uZn.Yd=function(n,t){Yq(this.a,Kcn(n))},zW(c2n,"Collectors/lambda$26$Type",1079),sDn(1080,1,{},wd),uZn.Ve=function(n,t){return sV(this.a,Kcn(n),Kcn(t))},zW(c2n,"Collectors/lambda$27$Type",1080),sDn(1081,1,{},nn),uZn.Kb=function(n){return Kcn(n)[0]},zW(c2n,"Collectors/lambda$28$Type",1081),sDn(728,1,{},tn),uZn.Ve=function(n,t){return nX(n,t)},zW(c2n,"Collectors/lambda$4$Type",728),sDn(145,1,{},en),uZn.Ve=function(n,t){return ES(uG(n,16),uG(t,16))},zW(c2n,"Collectors/lambda$42$Type",145),sDn(361,1,{},rn),uZn.Ve=function(n,t){return SS(uG(n,49),uG(t,49))},zW(c2n,"Collectors/lambda$50$Type",361),sDn(362,1,{},cn),uZn.Kb=function(n){return uG(n,49)},zW(c2n,"Collectors/lambda$51$Type",362),sDn(1068,1,{},dd),uZn.Yd=function(n,t){vln(this.a,uG(n,85),t)},zW(c2n,"Collectors/lambda$7$Type",1068),sDn(1070,1,{},an),uZn.Ve=function(n,t){return Ahn(uG(n,85),uG(t,85),new J)},zW(c2n,"Collectors/lambda$8$Type",1070),sDn(1071,1,{},gd),uZn.Kb=function(n){return zgn(this.a,uG(n,85))},zW(c2n,"Collectors/lambda$9$Type",1071),sDn(550,1,{}),uZn.$e=function(){qQ(this)},uZn.d=!1,zW(c2n,"TerminatableStream",550),sDn(827,550,a2n,IK),uZn.$e=function(){qQ(this)},zW(c2n,"DoubleStreamImpl",827),sDn(1847,736,WZn,lG),uZn.Re=function(n){return FMn(this,uG(n,189))},uZn.a=null,zW(c2n,"DoubleStreamImpl/2",1847),sDn(1848,1,_0n,pd),uZn.Pe=function(n){$N(this.a,n)},zW(c2n,"DoubleStreamImpl/2/lambda$0$Type",1848),sDn(1845,1,_0n,md),uZn.Pe=function(n){NN(this.a,n)},zW(c2n,"DoubleStreamImpl/lambda$0$Type",1845),sDn(1846,1,_0n,vd),uZn.Pe=function(n){Mmn(this.a,n)},zW(c2n,"DoubleStreamImpl/lambda$2$Type",1846),sDn(1397,735,WZn,i9),uZn.Re=function(n){return e6(this,uG(n,202))},uZn.a=0,uZn.b=0,uZn.c=0,zW(c2n,"IntStream/5",1397),sDn(806,550,a2n,OK),uZn.$e=function(){qQ(this)},uZn._e=function(){return GQ(this),this.a},zW(c2n,"IntStreamImpl",806),sDn(807,550,a2n,mS),uZn.$e=function(){qQ(this)},uZn._e=function(){return GQ(this),BD(),dut},zW(c2n,"IntStreamImpl/Empty",807),sDn(1687,1,JZn,kd),uZn.Dd=function(n){msn(this.a,n)},zW(c2n,"IntStreamImpl/lambda$4$Type",1687);var Kut,Fut=Iq(c2n,"Stream");sDn(26,550,{533:1,687:1,848:1},fX),uZn.$e=function(){qQ(this)},zW(c2n,"StreamImpl",26),sDn(1102,500,WZn,D_),uZn.Bd=function(n){for(;Ttn(this);){if(this.a.Bd(n))return!0;qQ(this.b),this.b=null,this.a=null}return!1},zW(c2n,"StreamImpl/1",1102),sDn(1103,1,QZn,yd),uZn.Cd=function(n){mG(this.a,uG(n,848))},zW(c2n,"StreamImpl/1/lambda$0$Type",1103),sDn(1104,1,y1n,Md),uZn.Mb=function(n){return FV(this.a,n)},zW(c2n,"StreamImpl/1methodref$add$Type",1104),sDn(1105,500,WZn,QY),uZn.Bd=function(n){var t;return this.a||(t=new Zm,this.b.a.Nb(new Td(t)),hZ(),f$(t,this.c),this.a=new h3(t,16)),urn(this.a,n)},uZn.a=null,zW(c2n,"StreamImpl/5",1105),sDn(1106,1,QZn,Td),uZn.Cd=function(n){kD(this.a,n)},zW(c2n,"StreamImpl/5/2methodref$add$Type",1106),sDn(737,500,WZn,ien),uZn.Bd=function(n){for(this.b=!1;!this.b&&this.c.Bd(new WP(this,n)););return this.b},uZn.b=!1,zW(c2n,"StreamImpl/FilterSpliterator",737),sDn(1096,1,QZn,WP),uZn.Cd=function(n){Xz(this.a,this.b,n)},zW(c2n,"StreamImpl/FilterSpliterator/lambda$0$Type",1096),sDn(1091,736,WZn,s7),uZn.Re=function(n){return v_(this,uG(n,189))},zW(c2n,"StreamImpl/MapToDoubleSpliterator",1091),sDn(1095,1,QZn,QP),uZn.Cd=function(n){vC(this.a,this.b,n)},zW(c2n,"StreamImpl/MapToDoubleSpliterator/lambda$0$Type",1095),sDn(1090,735,WZn,h7),uZn.Re=function(n){return k_(this,uG(n,202))},zW(c2n,"StreamImpl/MapToIntSpliterator",1090),sDn(1094,1,QZn,JP),uZn.Cd=function(n){kC(this.a,this.b,n)},zW(c2n,"StreamImpl/MapToIntSpliterator/lambda$0$Type",1094),sDn(734,500,WZn,f7),uZn.Bd=function(n){return y_(this,n)},zW(c2n,"StreamImpl/MapToObjSpliterator",734),sDn(1093,1,QZn,YP),uZn.Cd=function(n){yC(this.a,this.b,n)},zW(c2n,"StreamImpl/MapToObjSpliterator/lambda$0$Type",1093),sDn(1092,500,WZn,Fan),uZn.Bd=function(n){for(;NP(this.b,0);){if(!this.a.Bd(new on))return!1;this.b=$gn(this.b,1)}return this.a.Bd(n)},uZn.b=0,zW(c2n,"StreamImpl/SkipSpliterator",1092),sDn(1097,1,QZn,on),uZn.Cd=function(n){},zW(c2n,"StreamImpl/SkipSpliterator/lambda$0$Type",1097),sDn(626,1,QZn,un),uZn.Cd=function(n){Ob(this,n)},zW(c2n,"StreamImpl/ValueConsumer",626),sDn(1098,1,QZn,sn),uZn.Cd=function(n){vS()},zW(c2n,"StreamImpl/lambda$0$Type",1098),sDn(1099,1,QZn,hn),uZn.Cd=function(n){vS()},zW(c2n,"StreamImpl/lambda$1$Type",1099),sDn(1100,1,{},jd),uZn.Ve=function(n,t){return FB(this.a,n,t)},zW(c2n,"StreamImpl/lambda$4$Type",1100),sDn(1101,1,QZn,nC),uZn.Cd=function(n){kF(this.b,this.a,n)},zW(c2n,"StreamImpl/lambda$5$Type",1101),sDn(1107,1,QZn,Ed),uZn.Cd=function(n){Usn(this.a,uG(n,380))},zW(c2n,"TerminatableStream/lambda$0$Type",1107),sDn(2142,1,{}),sDn(2014,1,{},fn),zW("javaemul.internal","ConsoleLogger",2014);var _ut=0;sDn(2134,1,{}),sDn(1830,1,QZn,ln),uZn.Cd=function(n){uG(n,317)},zW(l2n,"BowyerWatsonTriangulation/lambda$0$Type",1830),sDn(1831,1,QZn,Pd),uZn.Cd=function(n){Qon(this.a,uG(n,317).e)},zW(l2n,"BowyerWatsonTriangulation/lambda$1$Type",1831),sDn(1832,1,QZn,bn),uZn.Cd=function(n){uG(n,177)},zW(l2n,"BowyerWatsonTriangulation/lambda$2$Type",1832),sDn(1827,1,b2n,Cd),uZn.Ne=function(n,t){return S5(this.a,uG(n,177),uG(t,177))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(l2n,"NaiveMinST/lambda$0$Type",1827),sDn(449,1,{},Sd),zW(l2n,"NodeMicroLayout",449),sDn(177,1,{177:1},ZP),uZn.Fb=function(n){var t;return!!F$(n,177)&&(t=uG(n,177),OJ(this.a,t.a)&&OJ(this.b,t.b)||OJ(this.a,t.b)&&OJ(this.b,t.a))},uZn.Hb=function(){return VN(this.a)+VN(this.b)};var But=zW(l2n,"TEdge",177);sDn(317,1,{317:1},gqn),uZn.Fb=function(n){var t;return!!F$(n,317)&&Den(this,(t=uG(n,317)).a)&&Den(this,t.b)&&Den(this,t.c)},uZn.Hb=function(){return VN(this.a)+VN(this.b)+VN(this.c)},zW(l2n,"TTriangle",317),sDn(225,1,{225:1},C$),zW(l2n,"Tree",225),sDn(1218,1,{},q0),zW(w2n,"Scanline",1218);var Hut=Iq(w2n,d2n);sDn(1758,1,{},Qin),zW(g2n,"CGraph",1758),sDn(316,1,{316:1},V0),uZn.b=0,uZn.c=0,uZn.d=0,uZn.g=0,uZn.i=0,uZn.k=T0n,zW(g2n,"CGroup",316),sDn(830,1,{},fk),zW(g2n,"CGroup/CGroupBuilder",830),sDn(60,1,{60:1},NF),uZn.Ib=function(){return this.j?mK(this.j.Kb(this)):(vK(zut),zut.o+"@"+(xx(this)>>>0).toString(16))},uZn.f=0,uZn.i=T0n;var Uut,Gut,qut,Xut,zut=zW(g2n,"CNode",60);sDn(829,1,{},lk),zW(g2n,"CNode/CNodeBuilder",829),sDn(1590,1,{},wn),uZn.ff=function(n,t){return 0},uZn.gf=function(n,t){return 0},zW(g2n,m2n,1590),sDn(1853,1,{},dn),uZn.cf=function(n){var t,i,r,c,a,o,u,s,h,f,l,b,w,d,g;for(h=M0n,r=new Ww(n.a.b);r.ae.d.c||e.d.c==r.d.c&&e.d.b0?n+this.n.d+this.n.a:0},uZn.kf=function(){var n,t,i,r,c;if(c=0,this.e)this.b?c=this.b.a:this.a[1][1]&&(c=this.a[1][1].kf());else if(this.g)c=ypn(this,wEn(this,null,!0));else for(Yrn(),i=0,r=(t=Uhn(cT(Ist,1),p1n,237,0,[jst,Est,Sst])).length;i0?c+this.n.b+this.n.c:0},uZn.lf=function(){var n,t,e,i,r;if(this.g)for(n=wEn(this,null,!1),Yrn(),i=0,r=(e=Uhn(cT(Ist,1),p1n,237,0,[jst,Est,Sst])).length;i0&&(r[0]+=this.d,i-=r[0]),r[2]>0&&(r[2]+=this.d,i-=r[2]),this.c.a=e.Math.max(0,i),this.c.d=t.d+n.d+(this.c.a-i)/2,r[1]=e.Math.max(r[1],i),J9(this,Est,t.d+n.d+r[0]-(r[1]-i)/2,r)},uZn.b=null,uZn.d=0,uZn.e=!1,uZn.f=!1,uZn.g=!1;var Ost,Ast,Lst,Nst=0,$st=0;zW(U2n,"GridContainerCell",1538),sDn(471,22,{3:1,34:1,22:1,471:1},aC);var Dst,xst=_cn(U2n,"HorizontalLabelAlignment",471,Oat,R2,gB);sDn(314,217,{217:1,314:1},a0,Yin,c1),uZn.jf=function(){return iq(this)},uZn.kf=function(){return rq(this)},uZn.a=0,uZn.c=!1;var Rst,Kst,Fst,_st=zW(U2n,"LabelCell",314);sDn(252,336,{217:1,336:1,252:1},tkn),uZn.jf=function(){return dNn(this)},uZn.kf=function(){return gNn(this)},uZn.lf=function(){YGn(this)},uZn.mf=function(){rqn(this)},uZn.b=0,uZn.c=0,uZn.d=!1,zW(U2n,"StripContainerCell",252),sDn(1691,1,y1n,Mn),uZn.Mb=function(n){return $M(uG(n,217))},zW(U2n,"StripContainerCell/lambda$0$Type",1691),sDn(1692,1,{},Tn),uZn.Ye=function(n){return uG(n,217).kf()},zW(U2n,"StripContainerCell/lambda$1$Type",1692),sDn(1693,1,y1n,jn),uZn.Mb=function(n){return DM(uG(n,217))},zW(U2n,"StripContainerCell/lambda$2$Type",1693),sDn(1694,1,{},En),uZn.Ye=function(n){return uG(n,217).jf()},zW(U2n,"StripContainerCell/lambda$3$Type",1694),sDn(472,22,{3:1,34:1,22:1,472:1},oC);var Bst,Hst,Ust,Gst,qst,Xst,zst,Vst,Wst,Qst,Jst,Yst,Zst,nht,tht,eht,iht,rht,cht,aht,oht,uht,sht,hht=_cn(U2n,"VerticalLabelAlignment",472,Oat,x2,pB);sDn(800,1,{},kQn),uZn.c=0,uZn.d=0,uZn.k=0,uZn.s=0,uZn.t=0,uZn.v=!1,uZn.w=0,uZn.D=!1,zW(J2n,"NodeContext",800),sDn(1536,1,b2n,Sn),uZn.Ne=function(n,t){return UL(uG(n,64),uG(t,64))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(J2n,"NodeContext/0methodref$comparePortSides$Type",1536),sDn(1537,1,b2n,Pn),uZn.Ne=function(n,t){return ACn(uG(n,117),uG(t,117))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(J2n,"NodeContext/1methodref$comparePortContexts$Type",1537),sDn(164,22,{3:1,34:1,22:1,164:1},pun);var fht,lht,bht,wht,dht,ght,pht,mht=_cn(J2n,"NodeLabelLocation",164,Oat,Nkn,mB);sDn(117,1,{117:1},v$n),uZn.a=!1,zW(J2n,"PortContext",117),sDn(1541,1,QZn,Cn),uZn.Cd=function(n){eE(uG(n,314))},zW(n3n,t3n,1541),sDn(1542,1,y1n,In),uZn.Mb=function(n){return!!uG(n,117).c},zW(n3n,e3n,1542),sDn(1543,1,QZn,On),uZn.Cd=function(n){eE(uG(n,117).c)},zW(n3n,"LabelPlacer/lambda$2$Type",1543),sDn(1540,1,QZn,An),uZn.Cd=function(n){VK(),wv(uG(n,117))},zW(n3n,"NodeLabelAndSizeUtilities/lambda$0$Type",1540),sDn(801,1,QZn,DB),uZn.Cd=function(n){aP(this.b,this.c,this.a,uG(n,187))},uZn.a=!1,uZn.c=!1,zW(n3n,"NodeLabelCellCreator/lambda$0$Type",801),sDn(1539,1,QZn,Ld),uZn.Cd=function(n){Vv(this.a,uG(n,187))},zW(n3n,"PortContextCreator/lambda$0$Type",1539),sDn(1902,1,{},Ln),zW(r3n,"GreedyRectangleStripOverlapRemover",1902),sDn(1903,1,b2n,Nn),uZn.Ne=function(n,t){return Cx(uG(n,226),uG(t,226))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(r3n,"GreedyRectangleStripOverlapRemover/0methodref$compareByYCoordinate$Type",1903),sDn(1849,1,{},pk),uZn.a=5,uZn.e=0,zW(r3n,"RectangleStripOverlapRemover",1849),sDn(1850,1,b2n,$n),uZn.Ne=function(n,t){return Ix(uG(n,226),uG(t,226))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(r3n,"RectangleStripOverlapRemover/0methodref$compareLeftRectangleBorders$Type",1850),sDn(1852,1,b2n,Dn),uZn.Ne=function(n,t){return fW(uG(n,226),uG(t,226))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(r3n,"RectangleStripOverlapRemover/1methodref$compareRightRectangleBorders$Type",1852),sDn(417,22,{3:1,34:1,22:1,417:1},uC);var vht,kht,yht,Mht,Tht,jht=_cn(r3n,"RectangleStripOverlapRemover/OverlapRemovalDirection",417,Oat,B6,vB);sDn(226,1,{226:1},ZX),zW(r3n,"RectangleStripOverlapRemover/RectangleNode",226),sDn(1851,1,QZn,Nd),uZn.Cd=function(n){lTn(this.a,uG(n,226))},zW(r3n,"RectangleStripOverlapRemover/lambda$1$Type",1851),sDn(1323,1,b2n,xn),uZn.Ne=function(n,t){return fzn(uG(n,176),uG(t,176))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(a3n,"PolyominoCompactor/CornerCasesGreaterThanRestComparator",1323),sDn(1326,1,{},Rn),uZn.Kb=function(n){return uG(n,334).a},zW(a3n,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$0$Type",1326),sDn(1327,1,y1n,Kn),uZn.Mb=function(n){return uG(n,332).a},zW(a3n,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$1$Type",1327),sDn(1328,1,y1n,Fn),uZn.Mb=function(n){return uG(n,332).a},zW(a3n,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$2$Type",1328),sDn(1321,1,b2n,_n),uZn.Ne=function(n,t){return JBn(uG(n,176),uG(t,176))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(a3n,"PolyominoCompactor/MinNumOfExtensionDirectionsComparator",1321),sDn(1324,1,{},Bn),uZn.Kb=function(n){return uG(n,334).a},zW(a3n,"PolyominoCompactor/MinNumOfExtensionDirectionsComparator/lambda$0$Type",1324),sDn(781,1,b2n,Hn),uZn.Ne=function(n,t){return lhn(uG(n,176),uG(t,176))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(a3n,"PolyominoCompactor/MinNumOfExtensionsComparator",781),sDn(1319,1,b2n,Un),uZn.Ne=function(n,t){return ron(uG(n,330),uG(t,330))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(a3n,"PolyominoCompactor/MinPerimeterComparator",1319),sDn(1320,1,b2n,Gn),uZn.Ne=function(n,t){return Byn(uG(n,330),uG(t,330))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(a3n,"PolyominoCompactor/MinPerimeterComparatorWithShape",1320),sDn(1322,1,b2n,qn),uZn.Ne=function(n,t){return zHn(uG(n,176),uG(t,176))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(a3n,"PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator",1322),sDn(1325,1,{},Xn),uZn.Kb=function(n){return uG(n,334).a},zW(a3n,"PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator/lambda$0$Type",1325),sDn(782,1,{},sC),uZn.Ve=function(n,t){return d6(this,uG(n,42),uG(t,176))},zW(a3n,"SuccessorCombination",782),sDn(649,1,{},zn),uZn.Ve=function(n,t){var e;return KNn((e=uG(n,42),uG(t,176),e))},zW(a3n,"SuccessorJitter",649),sDn(648,1,{},Vn),uZn.Ve=function(n,t){var e;return cFn((e=uG(n,42),uG(t,176),e))},zW(a3n,"SuccessorLineByLine",648),sDn(573,1,{},Wn),uZn.Ve=function(n,t){var e;return txn((e=uG(n,42),uG(t,176),e))},zW(a3n,"SuccessorManhattan",573),sDn(1344,1,{},Qn),uZn.Ve=function(n,t){var e;return lKn((e=uG(n,42),uG(t,176),e))},zW(a3n,"SuccessorMaxNormWindingInMathPosSense",1344),sDn(409,1,{},$d),uZn.Ve=function(n,t){return HV(this,n,t)},uZn.c=!1,uZn.d=!1,uZn.e=!1,uZn.f=!1,zW(a3n,"SuccessorQuadrantsGeneric",409),sDn(1345,1,{},Jn),uZn.Kb=function(n){return uG(n,334).a},zW(a3n,"SuccessorQuadrantsGeneric/lambda$0$Type",1345),sDn(332,22,{3:1,34:1,22:1,332:1},hC),uZn.a=!1;var Eht,Sht=_cn(f3n,l3n,332,Oat,F6,kB);sDn(1317,1,{}),uZn.Ib=function(){var n,t,e,i,r,c;for(e=" ",n=xwn(0),r=0;r=0?"b"+n+"["+X8(this.a)+"]":"b["+X8(this.a)+"]":"b_"+xx(this)},zW(V3n,"FBendpoint",250),sDn(290,137,{3:1,290:1,96:1,137:1},$F),uZn.Ib=function(){return X8(this)},zW(V3n,"FEdge",290),sDn(235,137,{3:1,235:1,96:1,137:1},d7);var uft,sft,hft,fft,lft,bft,wft,dft,gft,pft,mft=zW(V3n,"FGraph",235);sDn(454,309,{3:1,454:1,309:1,96:1,137:1},A5),uZn.Ib=function(){return null==this.b||0==this.b.length?"l["+X8(this.a)+"]":"l_"+this.b},zW(V3n,"FLabel",454),sDn(153,309,{3:1,153:1,309:1,96:1,137:1},E$),uZn.Ib=function(){return z3(this)},uZn.a=0,zW(V3n,"FNode",153),sDn(2100,1,{}),uZn.vf=function(n){pGn(this,n)},uZn.wf=function(){ITn(this)},uZn.d=0,zW(Q3n,"AbstractForceModel",2100),sDn(641,2100,{641:1},lsn),uZn.uf=function(n,t){var i,r,c,a;return qzn(this.f,n,t),c=YF(D$(t.d),n.d),a=e.Math.sqrt(c.a*c.a+c.b*c.b),r=e.Math.max(0,a-NQ(n.e)/2-NQ(t.e)/2),vD(c,((i=VNn(this.e,n,t))>0?-iW(r,this.c)*i:TR(r,this.b)*uG(oIn(n,(cGn(),$ft)),17).a)/a),c},uZn.vf=function(n){pGn(this,n),this.a=uG(oIn(n,(cGn(),Tft)),17).a,this.c=uM(pK(oIn(n,_ft))),this.b=uM(pK(oIn(n,xft)))},uZn.xf=function(n){return n0&&(a-=aM(r,this.a)*i),vD(c,a*this.b/o),c},uZn.vf=function(n){var t,i,r,c,a,o,u;for(pGn(this,n),this.b=uM(pK(oIn(n,(cGn(),Bft)))),this.c=this.b/uG(oIn(n,Tft),17).a,r=n.e.c.length,a=0,c=0,u=new Ww(n.e);u.a0},uZn.a=0,uZn.b=0,uZn.c=0,zW(Q3n,"FruchtermanReingoldModel",642),sDn(860,1,K2n,Gf),uZn.hf=function(n){Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,J3n),""),"Force Model"),"Determines the model for force calculation."),hft),(lAn(),gNt)),mlt),ggn((Rkn(),hNt))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Y3n),""),"Iterations"),"The number of iterations on the force model."),xwn(300)),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Z3n),""),"Repulsive Power"),"Determines how many bend points are added to the edge; such bend points are regarded as repelling particles in the force model"),xwn(0)),mNt),dot),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,n4n),""),"FR Temperature"),"The temperature is used as a scaling factor for particle displacements."),t4n),dNt),fot),ggn(hNt)))),H4(n,n4n,J3n,dft),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,e4n),""),"Eades Repulsion"),"Factor for repulsive forces in Eades' model."),5),dNt),fot),ggn(hNt)))),H4(n,e4n,J3n,lft),vJn((new qf,n))},zW(i4n,"ForceMetaDataProvider",860),sDn(432,22,{3:1,34:1,22:1,432:1},wC);var vft,kft,yft,Mft,Tft,jft,Eft,Sft,Pft,Cft,Ift,Oft,Aft,Lft,Nft,$ft,Dft,xft,Rft,Kft,Fft,_ft,Bft,Hft,Uft,Gft,qft,Xft,zft,Vft,Wft,Qft,Jft,Yft,Zft,nlt,tlt,elt,ilt,rlt,clt,alt,olt,ult,slt,hlt,flt,llt,blt,wlt,dlt,glt,plt,mlt=_cn(i4n,"ForceModelStrategy",432,Oat,h1,TB);sDn($1n,1,K2n,qf),uZn.hf=function(n){vJn(n)},zW(i4n,"ForceOptions",$1n),sDn(1001,1,{},mt),uZn.sf=function(){return new hk},uZn.tf=function(n){},zW(i4n,"ForceOptions/ForceFactory",1001),sDn(861,1,K2n,Xf),uZn.hf=function(n){Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,I4n),""),"Fixed Position"),"Prevent that the node is moved by the layout algorithm."),(qx(),!1)),(lAn(),wNt)),cot),ggn((Rkn(),sNt))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,O4n),""),"Desired Edge Length"),"Either specified for parent nodes or for individual edges, where the latter takes higher precedence."),100),dNt),fot),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[oNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,A4n),""),"Layout Dimension"),"Dimensions that are permitted to be altered during layout."),Zft),gNt),Clt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,L4n),""),"Stress Epsilon"),"Termination criterion for the iterative process."),t4n),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,N4n),""),"Iteration Limit"),"Maximum number of performed iterations. Takes higher precedence than 'epsilon'."),xwn(vZn)),mNt),dot),ggn(hNt)))),sWn((new zf,n))},zW(i4n,"StressMetaDataProvider",861),sDn(1004,1,K2n,zf),uZn.hf=function(n){sWn(n)},zW(i4n,"StressOptions",1004),sDn(1005,1,{},gt),uZn.sf=function(){return new DF},uZn.tf=function(n){},zW(i4n,"StressOptions/StressFactory",1005),sDn(1110,205,M3n,DF),uZn.rf=function(n,t){var e,i,r,c;for(t.Ug(D4n,1),oM(gK(zDn(n,(Bjn(),olt))))?oM(gK(zDn(n,blt)))||J1(new Sd((vP(),new Vy(n)))):Zxn(new hk,n,t.eh(1)),i=yfn(n),c=(e=tqn(this.a,i)).Kc();c.Ob();)(r=uG(c.Pb(),235)).e.c.length<=1||(czn(this.b,r),QDn(this.b),Prn(r.d,new pt));YJn(i=lJn(e)),t.Vg()},zW(R4n,"StressLayoutProvider",1110),sDn(1111,1,QZn,pt),uZn.Cd=function(n){Yqn(uG(n,454))},zW(R4n,"StressLayoutProvider/lambda$0$Type",1111),sDn(1002,1,{},qv),uZn.c=0,uZn.e=0,uZn.g=0,zW(R4n,"StressMajorization",1002),sDn(391,22,{3:1,34:1,22:1,391:1},dC);var vlt,klt,ylt,Mlt,Tlt,jlt,Elt,Slt,Plt,Clt=_cn(R4n,"StressMajorization/Dimension",391,Oat,F2,jB);sDn(1003,1,b2n,Fd),uZn.Ne=function(n,t){return j_(this.a,uG(n,153),uG(t,153))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(R4n,"StressMajorization/lambda$0$Type",1003),sDn(1192,1,{},i4),zW(F4n,"ElkLayered",1192),sDn(1193,1,QZn,_d),uZn.Cd=function(n){OLn(this.a,uG(n,36))},zW(F4n,"ElkLayered/lambda$0$Type",1193),sDn(1194,1,QZn,Bd),uZn.Cd=function(n){E_(this.a,uG(n,36))},zW(F4n,"ElkLayered/lambda$1$Type",1194),sDn(1281,1,{},z$),zW(F4n,"GraphConfigurator",1281),sDn(770,1,QZn,Hd),uZn.Cd=function(n){XIn(this.a,uG(n,10))},zW(F4n,"GraphConfigurator/lambda$0$Type",770),sDn(771,1,{},dt),uZn.Kb=function(n){return FEn(),new fX(null,new h3(uG(n,30).a,16))},zW(F4n,"GraphConfigurator/lambda$1$Type",771),sDn(772,1,QZn,Ud),uZn.Cd=function(n){XIn(this.a,uG(n,10))},zW(F4n,"GraphConfigurator/lambda$2$Type",772),sDn(1109,205,M3n,mk),uZn.rf=function(n,t){var e;e=vXn(new kk,n),xA(zDn(n,(jYn(),rMt)))===xA((Own(),Ixt))?Tgn(this.a,e,t):BDn(this.a,e,t),t.$g()||NQn(new Vf,e)},zW(F4n,"LayeredLayoutProvider",1109),sDn(367,22,{3:1,34:1,22:1,367:1},gC);var Ilt,Olt,Alt,Llt=_cn(F4n,"LayeredPhases",367,Oat,u9,EB);sDn(1717,1,{},$an),uZn.i=0,zW(_4n,"ComponentsToCGraphTransformer",1717),sDn(1718,1,{},wt),uZn.yf=function(n,t){return e.Math.min(null!=n.a?uM(n.a):n.c.i,null!=t.a?uM(t.a):t.c.i)},uZn.zf=function(n,t){return e.Math.min(null!=n.a?uM(n.a):n.c.i,null!=t.a?uM(t.a):t.c.i)},zW(_4n,"ComponentsToCGraphTransformer/1",1718),sDn(86,1,{86:1}),uZn.i=0,uZn.k=!0,uZn.o=T0n;var Nlt,$lt,Dlt,xlt=zW(B4n,"CNode",86);sDn(470,86,{470:1,86:1},Jx,Yvn),uZn.Ib=function(){return""},zW(_4n,"ComponentsToCGraphTransformer/CRectNode",470),sDn(1688,1,{},vt),zW(_4n,"OneDimensionalComponentsCompaction",1688),sDn(1689,1,{},kt),uZn.Kb=function(n){return w2(uG(n,42))},uZn.Fb=function(n){return this===n},zW(_4n,"OneDimensionalComponentsCompaction/lambda$0$Type",1689),sDn(1690,1,{},yt),uZn.Kb=function(n){return xgn(uG(n,42))},uZn.Fb=function(n){return this===n},zW(_4n,"OneDimensionalComponentsCompaction/lambda$1$Type",1690),sDn(1720,1,{},wQ),zW(B4n,"CGraph",1720),sDn(194,1,{194:1},Zvn),uZn.b=0,uZn.c=0,uZn.e=0,uZn.g=!0,uZn.i=T0n,zW(B4n,"CGroup",194),sDn(1719,1,{},Mt),uZn.yf=function(n,t){return e.Math.max(null!=n.a?uM(n.a):n.c.i,null!=t.a?uM(t.a):t.c.i)},uZn.zf=function(n,t){return e.Math.max(null!=n.a?uM(n.a):n.c.i,null!=t.a?uM(t.a):t.c.i)},zW(B4n,m2n,1719),sDn(1721,1,{},i$n),uZn.d=!1;var Rlt=zW(B4n,T2n,1721);sDn(1722,1,{},Tt),uZn.Kb=function(n){return GS(),qx(),0!=uG(uG(n,42).a,86).d.e},uZn.Fb=function(n){return this===n},zW(B4n,j2n,1722),sDn(833,1,{},cX),uZn.a=!1,uZn.b=!1,uZn.c=!1,uZn.d=!1,zW(B4n,E2n,833),sDn(1898,1,{},nz),zW(H4n,S2n,1898);var Klt=Iq(U4n,d2n);sDn(1899,1,{382:1},FZ),uZn.bf=function(n){DFn(this,uG(n,476))},zW(H4n,P2n,1899),sDn(V1n,1,b2n,jt),uZn.Ne=function(n,t){return rY(uG(n,86),uG(t,86))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(H4n,C2n,V1n),sDn(476,1,{476:1},KC),uZn.a=!1,zW(H4n,I2n,476),sDn(1901,1,b2n,Et),uZn.Ne=function(n,t){return KEn(uG(n,476),uG(t,476))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(H4n,O2n,1901),sDn(148,1,{148:1},FC,wG),uZn.Fb=function(n){var t;return null!=n&&Ult==Tbn(n)&&(t=uG(n,148),OJ(this.c,t.c)&&OJ(this.d,t.d))},uZn.Hb=function(){return Obn(Uhn(cT(dat,1),EZn,1,5,[this.c,this.d]))},uZn.Ib=function(){return"("+this.c+TZn+this.d+(this.a?"cx":"")+this.b+")"},uZn.a=!0,uZn.c=0,uZn.d=0;var Flt,_lt,Blt,Hlt,Ult=zW(U4n,"Point",148);sDn(416,22,{3:1,34:1,22:1,416:1},jC);var Glt,qlt,Xlt,zlt,Vlt,Wlt,Qlt,Jlt,Ylt,Zlt,nbt,tbt,ebt=_cn(U4n,"Point/Quadrant",416,Oat,H6,SB);sDn(1708,1,{},dk),uZn.b=null,uZn.c=null,uZn.d=null,uZn.e=null,uZn.f=null,zW(U4n,"RectilinearConvexHull",1708),sDn(583,1,{382:1},cyn),uZn.bf=function(n){Itn(this,uG(n,148))},uZn.b=0,zW(U4n,"RectilinearConvexHull/MaximalElementsEventHandler",583),sDn(1710,1,b2n,St),uZn.Ne=function(n,t){return cY(pK(n),pK(t))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(U4n,"RectilinearConvexHull/MaximalElementsEventHandler/lambda$0$Type",1710),sDn(1709,1,{382:1},Jin),uZn.bf=function(n){pKn(this,uG(n,148))},uZn.a=0,uZn.b=null,uZn.c=null,uZn.d=null,uZn.e=null,zW(U4n,"RectilinearConvexHull/RectangleEventHandler",1709),sDn(1711,1,b2n,Pt),uZn.Ne=function(n,t){return H3(uG(n,148),uG(t,148))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(U4n,"RectilinearConvexHull/lambda$0$Type",1711),sDn(1712,1,b2n,At),uZn.Ne=function(n,t){return U3(uG(n,148),uG(t,148))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(U4n,"RectilinearConvexHull/lambda$1$Type",1712),sDn(1713,1,b2n,Lt),uZn.Ne=function(n,t){return B3(uG(n,148),uG(t,148))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(U4n,"RectilinearConvexHull/lambda$2$Type",1713),sDn(1714,1,b2n,Ot),uZn.Ne=function(n,t){return G3(uG(n,148),uG(t,148))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(U4n,"RectilinearConvexHull/lambda$3$Type",1714),sDn(1715,1,b2n,Nt),uZn.Ne=function(n,t){return sIn(uG(n,148),uG(t,148))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(U4n,"RectilinearConvexHull/lambda$4$Type",1715),sDn(1716,1,{},X0),zW(U4n,"Scanline",1716),sDn(2104,1,{}),zW(G4n,"AbstractGraphPlacer",2104),sDn(335,1,{335:1},DR),uZn.Ff=function(n){return!!this.Gf(n)&&(UNn(this.b,uG(oIn(n,(GYn(),xpt)),21),n),!0)},uZn.Gf=function(n){var t,e,i;for(t=uG(oIn(n,(GYn(),xpt)),21),i=uG(Y9(Jlt,t),21).Kc();i.Ob();)if(e=uG(i.Pb(),21),!uG(Y9(this.b,e),15).dc())return!1;return!0},zW(G4n,"ComponentGroup",335),sDn(779,2104,{},gk),uZn.Hf=function(n){var t;for(t=new Ww(this.a);t.ai&&(f=0,l+=u+r,u=0),tHn(a,f+(s=a.c).a,l+s.b),dL(s),c=e.Math.max(c,f+h.a),u=e.Math.max(u,h.b),f+=h.a+r;t.f.a=c,t.f.b=l+u},uZn.Jf=function(n,t){var e,i,r,c,a;if(xA(oIn(t,(jYn(),kyt)))===xA((Uvn(),tbt))){for(i=n.Kc();i.Ob();){for(a=0,c=new Ww((e=uG(i.Pb(),36)).a);c.ai&&!uG(oIn(a,(GYn(),xpt)),21).Hc((KQn(),yRt))||s&&uG(oIn(s,(GYn(),xpt)),21).Hc((KQn(),kRt))||uG(oIn(a,(GYn(),xpt)),21).Hc((KQn(),_Rt)))&&(b=l,w+=u+r,u=0),h=a.c,uG(oIn(a,(GYn(),xpt)),21).Hc((KQn(),yRt))&&(b=c+r),tHn(a,b+h.a,w+h.b),c=e.Math.max(c,b+f.a),uG(oIn(a,xpt),21).Hc(KRt)&&(l=e.Math.max(l,b+f.a+r)),dL(h),u=e.Math.max(u,f.b),b+=f.a+r,s=a;t.f.a=c,t.f.b=w+u},uZn.Jf=function(n,t){},zW(G4n,"ModelOrderRowGraphPlacer",1313),sDn(1311,1,b2n,xt),uZn.Ne=function(n,t){return Wsn(uG(n,36),uG(t,36))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(G4n,"SimpleRowGraphPlacer/1",1311),sDn(1280,1,A2n,Rt),uZn.Lb=function(n){var t;return!!(t=uG(oIn(uG(n,249).b,(jYn(),bMt)),75))&&0!=t.b},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){var t;return!!(t=uG(oIn(uG(n,249).b,(jYn(),bMt)),75))&&0!=t.b},zW(W4n,"CompoundGraphPostprocessor/1",1280),sDn(1279,1,Q4n,yk),uZn.Kf=function(n,t){zyn(this,uG(n,36),t)},zW(W4n,"CompoundGraphPreprocessor",1279),sDn(453,1,{453:1},Sdn),uZn.c=!1,zW(W4n,"CompoundGraphPreprocessor/ExternalPort",453),sDn(249,1,{249:1},$B),uZn.Ib=function(){return MR(this.c)+":"+MNn(this.b)},zW(W4n,"CrossHierarchyEdge",249),sDn(777,1,b2n,Gd),uZn.Ne=function(n,t){return Njn(this,uG(n,249),uG(t,249))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(W4n,"CrossHierarchyEdgeComparator",777),sDn(305,137,{3:1,305:1,96:1,137:1}),uZn.p=0,zW(J4n,"LGraphElement",305),sDn(18,305,{3:1,18:1,305:1,96:1,137:1},UZ),uZn.Ib=function(){return MNn(this)};var obt=zW(J4n,"LEdge",18);sDn(36,305,{3:1,20:1,36:1,305:1,96:1,137:1},Dan),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return new Ww(this.b)},uZn.Ib=function(){return 0==this.b.c.length?"G-unlayered"+vIn(this.a):0==this.a.c.length?"G-layered"+vIn(this.b):"G[layerless"+vIn(this.a)+", layers"+vIn(this.b)+"]"};var ubt,sbt=zW(J4n,"LGraph",36);sDn(666,1,{}),uZn.Lf=function(){return this.e.n},uZn.of=function(n){return oIn(this.e,n)},uZn.Mf=function(){return this.e.o},uZn.Nf=function(){return this.e.p},uZn.pf=function(n){return vR(this.e,n)},uZn.Of=function(n){this.e.n.a=n.a,this.e.n.b=n.b},uZn.Pf=function(n){this.e.o.a=n.a,this.e.o.b=n.b},uZn.Qf=function(n){this.e.p=n},zW(J4n,"LGraphAdapters/AbstractLShapeAdapter",666),sDn(474,1,{853:1},qd),uZn.Rf=function(){var n,t;if(!this.b)for(this.b=iR(this.a.b.c.length),t=new Ww(this.a.b);t.a0&&Hbn((s3(t-1,n.length),n.charCodeAt(t-1)),c6n);)--t;if(r> ",n),njn(e)),JA(QA((n.a+="[",n),e.i),"]")),n.a},uZn.c=!0,uZn.d=!1;var Pbt,Cbt,Ibt,Obt,Abt=zW(J4n,"LPort",12);sDn(408,1,t1n,zd),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return new Vd(new Ww(this.a.e))},zW(J4n,"LPort/1",408),sDn(1309,1,$Zn,Vd),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){return uG(N3(this.a),18).c},uZn.Ob=function(){return l$(this.a)},uZn.Qb=function(){tW(this.a)},zW(J4n,"LPort/1/1",1309),sDn(369,1,t1n,Wd),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return new Qd(new Ww(this.a.g))},zW(J4n,"LPort/2",369),sDn(776,1,$Zn,Qd),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){return uG(N3(this.a),18).d},uZn.Ob=function(){return l$(this.a)},uZn.Qb=function(){tW(this.a)},zW(J4n,"LPort/2/1",776),sDn(1302,1,t1n,LC),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return new w7(this)},zW(J4n,"LPort/CombineIter",1302),sDn(208,1,$Zn,w7),uZn.Nb=function(n){SV(this,n)},uZn.Qb=function(){xj()},uZn.Ob=function(){return Dx(this)},uZn.Pb=function(){return l$(this.a)?N3(this.a):N3(this.b)},zW(J4n,"LPort/CombineIter/1",208),sDn(1303,1,A2n,Bt),uZn.Lb=function(n){return Yz(n)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return Lun(),0!=uG(n,12).g.c.length},zW(J4n,"LPort/lambda$0$Type",1303),sDn(1304,1,A2n,Ht),uZn.Lb=function(n){return Zz(n)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return Lun(),0!=uG(n,12).e.c.length},zW(J4n,"LPort/lambda$1$Type",1304),sDn(1305,1,A2n,Ut),uZn.Lb=function(n){return Lun(),uG(n,12).j==(KQn(),yRt)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return Lun(),uG(n,12).j==(KQn(),yRt)},zW(J4n,"LPort/lambda$2$Type",1305),sDn(1306,1,A2n,Gt),uZn.Lb=function(n){return Lun(),uG(n,12).j==(KQn(),kRt)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return Lun(),uG(n,12).j==(KQn(),kRt)},zW(J4n,"LPort/lambda$3$Type",1306),sDn(1307,1,A2n,qt),uZn.Lb=function(n){return Lun(),uG(n,12).j==(KQn(),KRt)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return Lun(),uG(n,12).j==(KQn(),KRt)},zW(J4n,"LPort/lambda$4$Type",1307),sDn(1308,1,A2n,Xt),uZn.Lb=function(n){return Lun(),uG(n,12).j==(KQn(),_Rt)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return Lun(),uG(n,12).j==(KQn(),_Rt)},zW(J4n,"LPort/lambda$5$Type",1308),sDn(30,305,{3:1,20:1,305:1,30:1,96:1,137:1},bQ),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return new Ww(this.a)},uZn.Ib=function(){return"L_"+Ten(this.b.b,this,0)+vIn(this.a)},zW(J4n,"Layer",30),sDn(1330,1,{},kk),zW(h6n,f6n,1330),sDn(1334,1,{},zt),uZn.Kb=function(n){return lCn(uG(n,84))},zW(h6n,"ElkGraphImporter/0methodref$connectableShapeToNode$Type",1334),sDn(1337,1,{},Vt),uZn.Kb=function(n){return lCn(uG(n,84))},zW(h6n,"ElkGraphImporter/1methodref$connectableShapeToNode$Type",1337),sDn(1331,1,QZn,Jd),uZn.Cd=function(n){y$n(this.a,uG(n,123))},zW(h6n,z3n,1331),sDn(1332,1,QZn,Yd),uZn.Cd=function(n){y$n(this.a,uG(n,123))},zW(h6n,l6n,1332),sDn(1333,1,{},Wt),uZn.Kb=function(n){return new fX(null,new h3(KJ(uG(n,74)),16))},zW(h6n,b6n,1333),sDn(1335,1,y1n,Zd),uZn.Mb=function(n){return DN(this.a,uG(n,27))},zW(h6n,w6n,1335),sDn(1336,1,{},Qt),uZn.Kb=function(n){return new fX(null,new h3(FJ(uG(n,74)),16))},zW(h6n,"ElkGraphImporter/lambda$5$Type",1336),sDn(1338,1,y1n,ng),uZn.Mb=function(n){return xN(this.a,uG(n,27))},zW(h6n,"ElkGraphImporter/lambda$7$Type",1338),sDn(1339,1,y1n,Jt),uZn.Mb=function(n){return XY(uG(n,74))},zW(h6n,"ElkGraphImporter/lambda$8$Type",1339),sDn(1297,1,{},Vf),zW(h6n,"ElkGraphLayoutTransferrer",1297),sDn(1298,1,y1n,tg),uZn.Mb=function(n){return IF(this.a,uG(n,18))},zW(h6n,"ElkGraphLayoutTransferrer/lambda$0$Type",1298),sDn(1299,1,QZn,eg),uZn.Cd=function(n){WS(),kD(this.a,uG(n,18))},zW(h6n,"ElkGraphLayoutTransferrer/lambda$1$Type",1299),sDn(1300,1,y1n,ig),uZn.Mb=function(n){return KK(this.a,uG(n,18))},zW(h6n,"ElkGraphLayoutTransferrer/lambda$2$Type",1300),sDn(1301,1,QZn,rg),uZn.Cd=function(n){WS(),kD(this.a,uG(n,18))},zW(h6n,"ElkGraphLayoutTransferrer/lambda$3$Type",1301),sDn(819,1,{},xF),zW(d6n,"BiLinkedHashMultiMap",819),sDn(1550,1,Q4n,Yt),uZn.Kf=function(n,t){Bon(uG(n,36),t)},zW(d6n,"CommentNodeMarginCalculator",1550),sDn(1551,1,{},Zt),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"CommentNodeMarginCalculator/lambda$0$Type",1551),sDn(1552,1,QZn,ne),uZn.Cd=function(n){bXn(uG(n,10))},zW(d6n,"CommentNodeMarginCalculator/lambda$1$Type",1552),sDn(1553,1,Q4n,te),uZn.Kf=function(n,t){WFn(uG(n,36),t)},zW(d6n,"CommentPostprocessor",1553),sDn(1554,1,Q4n,ee),uZn.Kf=function(n,t){yQn(uG(n,36),t)},zW(d6n,"CommentPreprocessor",1554),sDn(1555,1,Q4n,ie),uZn.Kf=function(n,t){KKn(uG(n,36),t)},zW(d6n,"ConstraintsPostprocessor",1555),sDn(1556,1,Q4n,re),uZn.Kf=function(n,t){Csn(uG(n,36),t)},zW(d6n,"EdgeAndLayerConstraintEdgeReverser",1556),sDn(1557,1,Q4n,ce),uZn.Kf=function(n,t){amn(uG(n,36),t)},zW(d6n,"EndLabelPostprocessor",1557),sDn(1558,1,{},ae),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"EndLabelPostprocessor/lambda$0$Type",1558),sDn(1559,1,y1n,oe),uZn.Mb=function(n){return q8(uG(n,10))},zW(d6n,"EndLabelPostprocessor/lambda$1$Type",1559),sDn(1560,1,QZn,ue),uZn.Cd=function(n){_En(uG(n,10))},zW(d6n,"EndLabelPostprocessor/lambda$2$Type",1560),sDn(1561,1,Q4n,se),uZn.Kf=function(n,t){AAn(uG(n,36),t)},zW(d6n,"EndLabelPreprocessor",1561),sDn(1562,1,{},he),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"EndLabelPreprocessor/lambda$0$Type",1562),sDn(1563,1,QZn,NB),uZn.Cd=function(n){oP(this.a,this.b,this.c,uG(n,10))},uZn.a=0,uZn.b=0,uZn.c=!1,zW(d6n,"EndLabelPreprocessor/lambda$1$Type",1563),sDn(1564,1,y1n,fe),uZn.Mb=function(n){return xA(oIn(uG(n,72),(jYn(),Xyt)))===xA((Zrn(),cxt))},zW(d6n,"EndLabelPreprocessor/lambda$2$Type",1564),sDn(1565,1,QZn,cg),uZn.Cd=function(n){aq(this.a,uG(n,72))},zW(d6n,"EndLabelPreprocessor/lambda$3$Type",1565),sDn(1566,1,y1n,le),uZn.Mb=function(n){return xA(oIn(uG(n,72),(jYn(),Xyt)))===xA((Zrn(),rxt))},zW(d6n,"EndLabelPreprocessor/lambda$4$Type",1566),sDn(1567,1,QZn,ag),uZn.Cd=function(n){aq(this.a,uG(n,72))},zW(d6n,"EndLabelPreprocessor/lambda$5$Type",1567),sDn(1615,1,Q4n,_f),uZn.Kf=function(n,t){Ddn(uG(n,36),t)},zW(d6n,"EndLabelSorter",1615),sDn(1616,1,b2n,be),uZn.Ne=function(n,t){return okn(uG(n,466),uG(t,466))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"EndLabelSorter/1",1616),sDn(466,1,{466:1},oZ),zW(d6n,"EndLabelSorter/LabelGroup",466),sDn(1617,1,{},we),uZn.Kb=function(n){return VS(),new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"EndLabelSorter/lambda$0$Type",1617),sDn(1618,1,y1n,de),uZn.Mb=function(n){return VS(),uG(n,10).k==(zIn(),dbt)},zW(d6n,"EndLabelSorter/lambda$1$Type",1618),sDn(1619,1,QZn,ge),uZn.Cd=function(n){VIn(uG(n,10))},zW(d6n,"EndLabelSorter/lambda$2$Type",1619),sDn(1620,1,y1n,pe),uZn.Mb=function(n){return VS(),xA(oIn(uG(n,72),(jYn(),Xyt)))===xA((Zrn(),rxt))},zW(d6n,"EndLabelSorter/lambda$3$Type",1620),sDn(1621,1,y1n,me),uZn.Mb=function(n){return VS(),xA(oIn(uG(n,72),(jYn(),Xyt)))===xA((Zrn(),cxt))},zW(d6n,"EndLabelSorter/lambda$4$Type",1621),sDn(1568,1,Q4n,ve),uZn.Kf=function(n,t){qXn(this,uG(n,36))},uZn.b=0,uZn.c=0,zW(d6n,"FinalSplineBendpointsCalculator",1568),sDn(1569,1,{},ke),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"FinalSplineBendpointsCalculator/lambda$0$Type",1569),sDn(1570,1,{},ye),uZn.Kb=function(n){return new fX(null,new LW(new Fz(ix(Xgn(uG(n,10)).a.Kc(),new h))))},zW(d6n,"FinalSplineBendpointsCalculator/lambda$1$Type",1570),sDn(1571,1,y1n,Me),uZn.Mb=function(n){return!v9(uG(n,18))},zW(d6n,"FinalSplineBendpointsCalculator/lambda$2$Type",1571),sDn(1572,1,y1n,Te),uZn.Mb=function(n){return vR(uG(n,18),(GYn(),Tmt))},zW(d6n,"FinalSplineBendpointsCalculator/lambda$3$Type",1572),sDn(1573,1,QZn,og),uZn.Cd=function(n){ZHn(this.a,uG(n,131))},zW(d6n,"FinalSplineBendpointsCalculator/lambda$4$Type",1573),sDn(1574,1,QZn,je),uZn.Cd=function(n){_An(uG(n,18).a)},zW(d6n,"FinalSplineBendpointsCalculator/lambda$5$Type",1574),sDn(803,1,Q4n,ug),uZn.Kf=function(n,t){fVn(this,uG(n,36),t)},zW(d6n,"GraphTransformer",803),sDn(517,22,{3:1,34:1,22:1,517:1},PC);var Lbt,Nbt,$bt,Dbt=_cn(d6n,"GraphTransformer/Mode",517,Oat,f1,zH);sDn(1575,1,Q4n,Ee),uZn.Kf=function(n,t){wRn(uG(n,36),t)},zW(d6n,"HierarchicalNodeResizingProcessor",1575),sDn(1576,1,Q4n,Se),uZn.Kf=function(n,t){don(uG(n,36),t)},zW(d6n,"HierarchicalPortConstraintProcessor",1576),sDn(1577,1,b2n,Pe),uZn.Ne=function(n,t){return wyn(uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"HierarchicalPortConstraintProcessor/NodeComparator",1577),sDn(1578,1,Q4n,Ce),uZn.Kf=function(n,t){HGn(uG(n,36),t)},zW(d6n,"HierarchicalPortDummySizeProcessor",1578),sDn(1579,1,Q4n,Ie),uZn.Kf=function(n,t){z_n(this,uG(n,36),t)},uZn.a=0,zW(d6n,"HierarchicalPortOrthogonalEdgeRouter",1579),sDn(1580,1,b2n,Oe),uZn.Ne=function(n,t){return Ox(uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"HierarchicalPortOrthogonalEdgeRouter/1",1580),sDn(1581,1,b2n,Ae),uZn.Ne=function(n,t){return Dtn(uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"HierarchicalPortOrthogonalEdgeRouter/2",1581),sDn(1582,1,Q4n,Le),uZn.Kf=function(n,t){tIn(uG(n,36),t)},zW(d6n,"HierarchicalPortPositionProcessor",1582),sDn(1583,1,Q4n,Wf),uZn.Kf=function(n,t){SJn(this,uG(n,36))},uZn.a=0,uZn.c=0,zW(d6n,"HighDegreeNodeLayeringProcessor",1583),sDn(580,1,{580:1},Ne),uZn.b=-1,uZn.d=-1,zW(d6n,"HighDegreeNodeLayeringProcessor/HighDegreeNodeInformation",580),sDn(1584,1,{},$e),uZn.Kb=function(n){return HB(),qgn(uG(n,10))},uZn.Fb=function(n){return this===n},zW(d6n,"HighDegreeNodeLayeringProcessor/lambda$0$Type",1584),sDn(1585,1,{},De),uZn.Kb=function(n){return HB(),Xgn(uG(n,10))},uZn.Fb=function(n){return this===n},zW(d6n,"HighDegreeNodeLayeringProcessor/lambda$1$Type",1585),sDn(1591,1,Q4n,xe),uZn.Kf=function(n,t){TGn(this,uG(n,36),t)},zW(d6n,"HyperedgeDummyMerger",1591),sDn(804,1,{},xB),uZn.a=!1,uZn.b=!1,uZn.c=!1,zW(d6n,"HyperedgeDummyMerger/MergeState",804),sDn(1592,1,{},Re),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"HyperedgeDummyMerger/lambda$0$Type",1592),sDn(1593,1,{},Ke),uZn.Kb=function(n){return new fX(null,new h3(uG(n,10).j,16))},zW(d6n,"HyperedgeDummyMerger/lambda$1$Type",1593),sDn(1594,1,QZn,Fe),uZn.Cd=function(n){uG(n,12).p=-1},zW(d6n,"HyperedgeDummyMerger/lambda$2$Type",1594),sDn(1595,1,Q4n,_e),uZn.Kf=function(n,t){kGn(uG(n,36),t)},zW(d6n,"HypernodesProcessor",1595),sDn(1596,1,Q4n,Be),uZn.Kf=function(n,t){_Gn(uG(n,36),t)},zW(d6n,"InLayerConstraintProcessor",1596),sDn(1597,1,Q4n,He),uZn.Kf=function(n,t){Nun(uG(n,36),t)},zW(d6n,"InnermostNodeMarginCalculator",1597),sDn(1598,1,Q4n,Ue),uZn.Kf=function(n,t){gQn(this,uG(n,36))},uZn.a=T0n,uZn.b=T0n,uZn.c=M0n,uZn.d=M0n;var xbt,Rbt,Kbt,Fbt,_bt,Bbt,Hbt,Ubt,Gbt,qbt,Xbt,zbt,Vbt,Wbt,Qbt,Jbt,Ybt,Zbt,nwt,twt,ewt,iwt,rwt,cwt,awt,owt,uwt,swt,hwt,fwt,lwt,bwt,wwt,dwt,gwt,pwt,mwt,vwt,kwt,ywt,Mwt,Twt,jwt,Ewt,Swt,Pwt,Cwt,Iwt,Owt,Awt,Lwt,Nwt,$wt,Dwt,xwt,Rwt,Kwt,Fwt=zW(d6n,"InteractiveExternalPortPositioner",1598);sDn(1599,1,{},Ge),uZn.Kb=function(n){return uG(n,18).d.i},uZn.Fb=function(n){return this===n},zW(d6n,"InteractiveExternalPortPositioner/lambda$0$Type",1599),sDn(1600,1,{},sg),uZn.Kb=function(n){return Lx(this.a,pK(n))},uZn.Fb=function(n){return this===n},zW(d6n,"InteractiveExternalPortPositioner/lambda$1$Type",1600),sDn(1601,1,{},qe),uZn.Kb=function(n){return uG(n,18).c.i},uZn.Fb=function(n){return this===n},zW(d6n,"InteractiveExternalPortPositioner/lambda$2$Type",1601),sDn(1602,1,{},hg),uZn.Kb=function(n){return Nx(this.a,pK(n))},uZn.Fb=function(n){return this===n},zW(d6n,"InteractiveExternalPortPositioner/lambda$3$Type",1602),sDn(1603,1,{},fg),uZn.Kb=function(n){return XF(this.a,pK(n))},uZn.Fb=function(n){return this===n},zW(d6n,"InteractiveExternalPortPositioner/lambda$4$Type",1603),sDn(1604,1,{},lg),uZn.Kb=function(n){return zF(this.a,pK(n))},uZn.Fb=function(n){return this===n},zW(d6n,"InteractiveExternalPortPositioner/lambda$5$Type",1604),sDn(81,22,{3:1,34:1,22:1,81:1,196:1},CC),uZn.dg=function(){switch(this.g){case 15:return new fc;case 22:return new lc;case 47:return new dc;case 28:case 35:return new ei;case 32:return new Yt;case 42:return new te;case 1:return new ee;case 41:return new ie;case 56:return new ug((Aun(),Obt));case 0:return new ug((Aun(),Ibt));case 2:return new re;case 54:return new ce;case 33:return new se;case 51:return new ve;case 55:return new Ee;case 13:return new Se;case 38:return new Ce;case 44:return new Ie;case 40:return new Le;case 9:return new Wf;case 49:return new Ux;case 37:return new xe;case 43:return new _e;case 27:return new Be;case 30:return new He;case 3:return new Ue;case 18:return new ze;case 29:return new Ve;case 5:return new Qf;case 50:return new Xe;case 34:return new Jf;case 36:return new ii;case 52:return new _f;case 11:return new ri;case 7:return new Yf;case 39:return new ci;case 45:return new ai;case 16:return new oi;case 10:return new RI;case 48:return new fi;case 21:return new li;case 23:return new zy((ean(),BEt));case 8:return new wi;case 12:return new gi;case 4:return new pi;case 19:return new rl;case 17:return new Pi;case 53:return new Ci;case 6:return new Bi;case 25:return new jk;case 46:return new $i;case 31:return new _F;case 14:return new Wi;case 26:return new Mc;case 20:return new nr;case 24:return new zy((ean(),HEt));default:throw hv(new vM(v6n+(null!=this.f?this.f:""+this.g)))}};var _wt,Bwt,Hwt,Uwt,Gwt,qwt,Xwt,zwt,Vwt=_cn(d6n,k6n,81,Oat,bKn,XB);sDn(1605,1,Q4n,ze),uZn.Kf=function(n,t){bQn(uG(n,36),t)},zW(d6n,"InvertedPortProcessor",1605),sDn(1606,1,Q4n,Ve),uZn.Kf=function(n,t){xHn(uG(n,36),t)},zW(d6n,"LabelAndNodeSizeProcessor",1606),sDn(1607,1,y1n,We),uZn.Mb=function(n){return uG(n,10).k==(zIn(),dbt)},zW(d6n,"LabelAndNodeSizeProcessor/lambda$0$Type",1607),sDn(1608,1,y1n,Qe),uZn.Mb=function(n){return uG(n,10).k==(zIn(),lbt)},zW(d6n,"LabelAndNodeSizeProcessor/lambda$1$Type",1608),sDn(1609,1,QZn,KB),uZn.Cd=function(n){uP(this.b,this.a,this.c,uG(n,10))},uZn.a=!1,uZn.c=!1,zW(d6n,"LabelAndNodeSizeProcessor/lambda$2$Type",1609),sDn(1610,1,Q4n,Qf),uZn.Kf=function(n,t){EWn(uG(n,36),t)},zW(d6n,"LabelDummyInserter",1610),sDn(1611,1,A2n,Je),uZn.Lb=function(n){return xA(oIn(uG(n,72),(jYn(),Xyt)))===xA((Zrn(),ixt))},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return xA(oIn(uG(n,72),(jYn(),Xyt)))===xA((Zrn(),ixt))},zW(d6n,"LabelDummyInserter/1",1611),sDn(1612,1,Q4n,Xe),uZn.Kf=function(n,t){eWn(uG(n,36),t)},zW(d6n,"LabelDummyRemover",1612),sDn(1613,1,y1n,Ye),uZn.Mb=function(n){return oM(gK(oIn(uG(n,72),(jYn(),qyt))))},zW(d6n,"LabelDummyRemover/lambda$0$Type",1613),sDn(1378,1,Q4n,Jf),uZn.Kf=function(n,t){UVn(this,uG(n,36),t)},uZn.a=null,zW(d6n,"LabelDummySwitcher",1378),sDn(293,1,{293:1},oHn),uZn.c=0,uZn.d=null,uZn.f=0,zW(d6n,"LabelDummySwitcher/LabelDummyInfo",293),sDn(1379,1,{},Ze),uZn.Kb=function(n){return Pun(),new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"LabelDummySwitcher/lambda$0$Type",1379),sDn(1380,1,y1n,ni),uZn.Mb=function(n){return Pun(),uG(n,10).k==(zIn(),bbt)},zW(d6n,"LabelDummySwitcher/lambda$1$Type",1380),sDn(1381,1,{},bg),uZn.Kb=function(n){return FK(this.a,uG(n,10))},zW(d6n,"LabelDummySwitcher/lambda$2$Type",1381),sDn(1382,1,QZn,wg),uZn.Cd=function(n){gQ(this.a,uG(n,293))},zW(d6n,"LabelDummySwitcher/lambda$3$Type",1382),sDn(1383,1,b2n,ti),uZn.Ne=function(n,t){return nV(uG(n,293),uG(t,293))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"LabelDummySwitcher/lambda$4$Type",1383),sDn(802,1,Q4n,ei),uZn.Kf=function(n,t){Dnn(uG(n,36),t)},zW(d6n,"LabelManagementProcessor",802),sDn(1614,1,Q4n,ii),uZn.Kf=function(n,t){jFn(uG(n,36),t)},zW(d6n,"LabelSideSelector",1614),sDn(1622,1,Q4n,ri),uZn.Kf=function(n,t){yqn(uG(n,36),t)},zW(d6n,"LayerConstraintPostprocessor",1622),sDn(1623,1,Q4n,Yf),uZn.Kf=function(n,t){vDn(uG(n,36),t)},zW(d6n,"LayerConstraintPreprocessor",1623),sDn(371,22,{3:1,34:1,22:1,371:1},IC);var Wwt,Qwt,Jwt,Ywt,Zwt,ndt,tdt,edt,idt,rdt,cdt,adt=_cn(d6n,"LayerConstraintPreprocessor/HiddenNodeConnections",371,Oat,G6,zB);sDn(1624,1,Q4n,ci),uZn.Kf=function(n,t){zzn(uG(n,36),t)},zW(d6n,"LayerSizeAndGraphHeightCalculator",1624),sDn(1625,1,Q4n,ai),uZn.Kf=function(n,t){dRn(uG(n,36),t)},zW(d6n,"LongEdgeJoiner",1625),sDn(1626,1,Q4n,oi),uZn.Kf=function(n,t){bzn(uG(n,36),t)},zW(d6n,"LongEdgeSplitter",1626),sDn(1627,1,Q4n,RI),uZn.Kf=function(n,t){VWn(this,uG(n,36),t)},uZn.e=0,uZn.f=0,uZn.j=0,uZn.k=0,uZn.n=0,uZn.o=0,zW(d6n,"NodePromotion",1627),sDn(1628,1,b2n,ui),uZn.Ne=function(n,t){return $ln(uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"NodePromotion/1",1628),sDn(1629,1,b2n,si),uZn.Ne=function(n,t){return Dln(uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"NodePromotion/2",1629),sDn(1630,1,{},hi),uZn.Kb=function(n){return uG(n,42),UB(),qx(),!0},uZn.Fb=function(n){return this===n},zW(d6n,"NodePromotion/lambda$0$Type",1630),sDn(1631,1,{},mg),uZn.Kb=function(n){return P0(this.a,uG(n,42))},uZn.Fb=function(n){return this===n},uZn.a=0,zW(d6n,"NodePromotion/lambda$1$Type",1631),sDn(1632,1,{},vg),uZn.Kb=function(n){return S0(this.a,uG(n,42))},uZn.Fb=function(n){return this===n},uZn.a=0,zW(d6n,"NodePromotion/lambda$2$Type",1632),sDn(1633,1,Q4n,fi),uZn.Kf=function(n,t){wJn(uG(n,36),t)},zW(d6n,"NorthSouthPortPostprocessor",1633),sDn(1634,1,Q4n,li),uZn.Kf=function(n,t){FQn(uG(n,36),t)},zW(d6n,"NorthSouthPortPreprocessor",1634),sDn(1635,1,b2n,bi),uZn.Ne=function(n,t){return Qsn(uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"NorthSouthPortPreprocessor/lambda$0$Type",1635),sDn(1636,1,Q4n,wi),uZn.Kf=function(n,t){UUn(uG(n,36),t)},zW(d6n,"PartitionMidprocessor",1636),sDn(1637,1,y1n,di),uZn.Mb=function(n){return vR(uG(n,10),(jYn(),UMt))},zW(d6n,"PartitionMidprocessor/lambda$0$Type",1637),sDn(1638,1,QZn,kg),uZn.Cd=function(n){zY(this.a,uG(n,10))},zW(d6n,"PartitionMidprocessor/lambda$1$Type",1638),sDn(1639,1,Q4n,gi),uZn.Kf=function(n,t){JRn(uG(n,36),t)},zW(d6n,"PartitionPostprocessor",1639),sDn(1640,1,Q4n,pi),uZn.Kf=function(n,t){M$n(uG(n,36),t)},zW(d6n,"PartitionPreprocessor",1640),sDn(1641,1,y1n,mi),uZn.Mb=function(n){return vR(uG(n,10),(jYn(),UMt))},zW(d6n,"PartitionPreprocessor/lambda$0$Type",1641),sDn(1642,1,{},vi),uZn.Kb=function(n){return new fX(null,new LW(new Fz(ix(Xgn(uG(n,10)).a.Kc(),new h))))},zW(d6n,"PartitionPreprocessor/lambda$1$Type",1642),sDn(1643,1,y1n,ki),uZn.Mb=function(n){return pkn(uG(n,18))},zW(d6n,"PartitionPreprocessor/lambda$2$Type",1643),sDn(1644,1,QZn,yi),uZn.Cd=function(n){rfn(uG(n,18))},zW(d6n,"PartitionPreprocessor/lambda$3$Type",1644),sDn(1645,1,Q4n,rl),uZn.Kf=function(n,t){wUn(uG(n,36),t)},zW(d6n,"PortListSorter",1645),sDn(1648,1,b2n,Mi),uZn.Ne=function(n,t){return Q5(uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"PortListSorter/lambda$0$Type",1648),sDn(1650,1,b2n,Ti),uZn.Ne=function(n,t){return hGn(uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"PortListSorter/lambda$1$Type",1650),sDn(1646,1,{},ji),uZn.Kb=function(n){return Cln(),uG(n,12).e},zW(d6n,"PortListSorter/lambda$2$Type",1646),sDn(1647,1,{},Ei),uZn.Kb=function(n){return Cln(),uG(n,12).g},zW(d6n,"PortListSorter/lambda$3$Type",1647),sDn(1649,1,b2n,Si),uZn.Ne=function(n,t){return bjn(uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"PortListSorter/lambda$4$Type",1649),sDn(1651,1,Q4n,Pi),uZn.Kf=function(n,t){FDn(uG(n,36),t)},zW(d6n,"PortSideProcessor",1651),sDn(1652,1,Q4n,Ci),uZn.Kf=function(n,t){SBn(uG(n,36),t)},zW(d6n,"ReversedEdgeRestorer",1652),sDn(1657,1,Q4n,jk),uZn.Kf=function(n,t){kTn(this,uG(n,36),t)},zW(d6n,"SelfLoopPortRestorer",1657),sDn(1658,1,{},Ii),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"SelfLoopPortRestorer/lambda$0$Type",1658),sDn(1659,1,y1n,Oi),uZn.Mb=function(n){return uG(n,10).k==(zIn(),dbt)},zW(d6n,"SelfLoopPortRestorer/lambda$1$Type",1659),sDn(1660,1,y1n,Ai),uZn.Mb=function(n){return vR(uG(n,10),(GYn(),vmt))},zW(d6n,"SelfLoopPortRestorer/lambda$2$Type",1660),sDn(1661,1,{},Li),uZn.Kb=function(n){return uG(oIn(uG(n,10),(GYn(),vmt)),337)},zW(d6n,"SelfLoopPortRestorer/lambda$3$Type",1661),sDn(1662,1,QZn,gg),uZn.Cd=function(n){gOn(this.a,uG(n,337))},zW(d6n,"SelfLoopPortRestorer/lambda$4$Type",1662),sDn(805,1,QZn,Ni),uZn.Cd=function(n){BOn(uG(n,105))},zW(d6n,"SelfLoopPortRestorer/lambda$5$Type",805),sDn(1663,1,Q4n,$i),uZn.Kf=function(n,t){oyn(uG(n,36),t)},zW(d6n,"SelfLoopPostProcessor",1663),sDn(1664,1,{},Di),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"SelfLoopPostProcessor/lambda$0$Type",1664),sDn(1665,1,y1n,xi),uZn.Mb=function(n){return uG(n,10).k==(zIn(),dbt)},zW(d6n,"SelfLoopPostProcessor/lambda$1$Type",1665),sDn(1666,1,y1n,Ri),uZn.Mb=function(n){return vR(uG(n,10),(GYn(),vmt))},zW(d6n,"SelfLoopPostProcessor/lambda$2$Type",1666),sDn(1667,1,QZn,Ki),uZn.Cd=function(n){gSn(uG(n,10))},zW(d6n,"SelfLoopPostProcessor/lambda$3$Type",1667),sDn(1668,1,{},Fi),uZn.Kb=function(n){return new fX(null,new h3(uG(n,105).f,1))},zW(d6n,"SelfLoopPostProcessor/lambda$4$Type",1668),sDn(1669,1,QZn,dg),uZn.Cd=function(n){V6(this.a,uG(n,340))},zW(d6n,"SelfLoopPostProcessor/lambda$5$Type",1669),sDn(1670,1,y1n,_i),uZn.Mb=function(n){return!!uG(n,105).i},zW(d6n,"SelfLoopPostProcessor/lambda$6$Type",1670),sDn(1671,1,QZn,pg),uZn.Cd=function(n){eM(this.a,uG(n,105))},zW(d6n,"SelfLoopPostProcessor/lambda$7$Type",1671),sDn(1653,1,Q4n,Bi),uZn.Kf=function(n,t){Fxn(uG(n,36),t)},zW(d6n,"SelfLoopPreProcessor",1653),sDn(1654,1,{},Hi),uZn.Kb=function(n){return new fX(null,new h3(uG(n,105).f,1))},zW(d6n,"SelfLoopPreProcessor/lambda$0$Type",1654),sDn(1655,1,{},Ui),uZn.Kb=function(n){return uG(n,340).a},zW(d6n,"SelfLoopPreProcessor/lambda$1$Type",1655),sDn(1656,1,QZn,Gi),uZn.Cd=function(n){v$(uG(n,18))},zW(d6n,"SelfLoopPreProcessor/lambda$2$Type",1656),sDn(1672,1,Q4n,_F),uZn.Kf=function(n,t){xIn(this,uG(n,36),t)},zW(d6n,"SelfLoopRouter",1672),sDn(1673,1,{},qi),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"SelfLoopRouter/lambda$0$Type",1673),sDn(1674,1,y1n,Xi),uZn.Mb=function(n){return uG(n,10).k==(zIn(),dbt)},zW(d6n,"SelfLoopRouter/lambda$1$Type",1674),sDn(1675,1,y1n,zi),uZn.Mb=function(n){return vR(uG(n,10),(GYn(),vmt))},zW(d6n,"SelfLoopRouter/lambda$2$Type",1675),sDn(1676,1,{},Vi),uZn.Kb=function(n){return uG(oIn(uG(n,10),(GYn(),vmt)),337)},zW(d6n,"SelfLoopRouter/lambda$3$Type",1676),sDn(1677,1,QZn,OC),uZn.Cd=function(n){lY(this.a,this.b,uG(n,337))},zW(d6n,"SelfLoopRouter/lambda$4$Type",1677),sDn(1678,1,Q4n,Wi),uZn.Kf=function(n,t){tFn(uG(n,36),t)},zW(d6n,"SemiInteractiveCrossMinProcessor",1678),sDn(1679,1,y1n,Qi),uZn.Mb=function(n){return uG(n,10).k==(zIn(),dbt)},zW(d6n,"SemiInteractiveCrossMinProcessor/lambda$0$Type",1679),sDn(1680,1,y1n,Ji),uZn.Mb=function(n){return MX(uG(n,10))._b((jYn(),rTt))},zW(d6n,"SemiInteractiveCrossMinProcessor/lambda$1$Type",1680),sDn(1681,1,b2n,Yi),uZn.Ne=function(n,t){return Eon(uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"SemiInteractiveCrossMinProcessor/lambda$2$Type",1681),sDn(1682,1,{},Zi),uZn.Ve=function(n,t){return VY(uG(n,10),uG(t,10))},zW(d6n,"SemiInteractiveCrossMinProcessor/lambda$3$Type",1682),sDn(1684,1,Q4n,nr),uZn.Kf=function(n,t){MXn(uG(n,36),t)},zW(d6n,"SortByInputModelProcessor",1684),sDn(1685,1,y1n,tr),uZn.Mb=function(n){return 0!=uG(n,12).g.c.length},zW(d6n,"SortByInputModelProcessor/lambda$0$Type",1685),sDn(1686,1,QZn,yg),uZn.Cd=function(n){ZOn(this.a,uG(n,12))},zW(d6n,"SortByInputModelProcessor/lambda$1$Type",1686),sDn(1759,817,{},Kon),uZn.df=function(n){var t,e,i,r;switch(this.c=n,this.a.g){case 2:t=new Zm,kS(JJ(new fX(null,new h3(this.c.a.b,16)),new dr),new BC(this,t)),QAn(this,new ir),Prn(t,new rr),t.c.length=0,kS(JJ(new fX(null,new h3(this.c.a.b,16)),new cr),new Tg(t)),QAn(this,new ar),Prn(t,new or),t.c.length=0,e=w$(Tun(ZJ(new fX(null,new h3(this.c.a.b,16)),new jg(this))),new ur),kS(new fX(null,new h3(this.c.a.a,16)),new NC(e,t)),QAn(this,new hr),Prn(t,new fr),t.c.length=0;break;case 3:i=new Zm,QAn(this,new er),r=w$(Tun(ZJ(new fX(null,new h3(this.c.a.b,16)),new Mg(this))),new sr),kS(JJ(new fX(null,new h3(this.c.a.b,16)),new lr),new DC(r,i)),QAn(this,new br),Prn(i,new wr),i.c.length=0;break;default:throw hv(new Hv)}},uZn.b=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation",1759),sDn(1760,1,A2n,er),uZn.Lb=function(n){return F$(uG(n,60).g,154)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return F$(uG(n,60).g,154)},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$0$Type",1760),sDn(1761,1,{},Mg),uZn.Ye=function(n){return $Ln(this.a,uG(n,60))},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$1$Type",1761),sDn(1769,1,M1n,AC),uZn.de=function(){TEn(this.a,this.b,-1)},uZn.b=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$10$Type",1769),sDn(1771,1,A2n,ir),uZn.Lb=function(n){return F$(uG(n,60).g,154)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return F$(uG(n,60).g,154)},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$11$Type",1771),sDn(1772,1,QZn,rr),uZn.Cd=function(n){uG(n,380).de()},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$12$Type",1772),sDn(1773,1,y1n,cr),uZn.Mb=function(n){return F$(uG(n,60).g,10)},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$13$Type",1773),sDn(1775,1,QZn,Tg),uZn.Cd=function(n){tpn(this.a,uG(n,60))},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$14$Type",1775),sDn(1774,1,M1n,xC),uZn.de=function(){TEn(this.b,this.a,-1)},uZn.a=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$15$Type",1774),sDn(1776,1,A2n,ar),uZn.Lb=function(n){return F$(uG(n,60).g,10)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return F$(uG(n,60).g,10)},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$16$Type",1776),sDn(1777,1,QZn,or),uZn.Cd=function(n){uG(n,380).de()},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$17$Type",1777),sDn(1778,1,{},jg),uZn.Ye=function(n){return DLn(this.a,uG(n,60))},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$18$Type",1778),sDn(1779,1,{},ur),uZn.We=function(){return 0},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$19$Type",1779),sDn(1762,1,{},sr),uZn.We=function(){return 0},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$2$Type",1762),sDn(1781,1,QZn,NC),uZn.Cd=function(n){uz(this.a,this.b,uG(n,316))},uZn.a=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$20$Type",1781),sDn(1780,1,M1n,$C),uZn.de=function(){HDn(this.a,this.b,-1)},uZn.b=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$21$Type",1780),sDn(1782,1,A2n,hr),uZn.Lb=function(n){return uG(n,60),!0},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return uG(n,60),!0},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$22$Type",1782),sDn(1783,1,QZn,fr),uZn.Cd=function(n){uG(n,380).de()},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$23$Type",1783),sDn(1763,1,y1n,lr),uZn.Mb=function(n){return F$(uG(n,60).g,10)},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$3$Type",1763),sDn(1765,1,QZn,DC),uZn.Cd=function(n){sz(this.a,this.b,uG(n,60))},uZn.a=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$4$Type",1765),sDn(1764,1,M1n,RC),uZn.de=function(){TEn(this.b,this.a,-1)},uZn.a=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$5$Type",1764),sDn(1766,1,A2n,br),uZn.Lb=function(n){return uG(n,60),!0},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return uG(n,60),!0},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$6$Type",1766),sDn(1767,1,QZn,wr),uZn.Cd=function(n){uG(n,380).de()},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$7$Type",1767),sDn(1768,1,y1n,dr),uZn.Mb=function(n){return F$(uG(n,60).g,154)},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$8$Type",1768),sDn(1770,1,QZn,BC),uZn.Cd=function(n){mrn(this.a,this.b,uG(n,60))},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$9$Type",1770),sDn(1586,1,Q4n,Ux),uZn.Kf=function(n,t){Mzn(this,uG(n,36),t)},zW(E6n,"HorizontalGraphCompactor",1586),sDn(1587,1,{},Eg),uZn.ff=function(n,t){var e,i;return $en(n,t)?0:(e=z4(n),i=z4(t),e&&e.k==(zIn(),lbt)||i&&i.k==(zIn(),lbt)?0:_x(uG(oIn(this.a.a,(GYn(),kmt)),312),e?e.k:(zIn(),wbt),i?i.k:(zIn(),wbt)))},uZn.gf=function(n,t){var e,i;return $en(n,t)?1:(e=z4(n),i=z4(t),Bx(uG(oIn(this.a.a,(GYn(),kmt)),312),e?e.k:(zIn(),wbt),i?i.k:(zIn(),wbt)))},zW(E6n,"HorizontalGraphCompactor/1",1587),sDn(1588,1,{},gr),uZn.ef=function(n,t){return JS(),0==n.a.i},zW(E6n,"HorizontalGraphCompactor/lambda$0$Type",1588),sDn(1589,1,{},Sg),uZn.ef=function(n,t){return ZY(this.a,n,t)},zW(E6n,"HorizontalGraphCompactor/lambda$1$Type",1589),sDn(1730,1,{},Sen),zW(E6n,"LGraphToCGraphTransformer",1730),sDn(1738,1,y1n,pr),uZn.Mb=function(n){return null!=n},zW(E6n,"LGraphToCGraphTransformer/0methodref$nonNull$Type",1738),sDn(1731,1,{},mr),uZn.Kb=function(n){return GB(),cpn(oIn(uG(uG(n,60).g,10),(GYn(),rmt)))},zW(E6n,"LGraphToCGraphTransformer/lambda$0$Type",1731),sDn(1732,1,{},vr),uZn.Kb=function(n){return GB(),_wn(uG(uG(n,60).g,154))},zW(E6n,"LGraphToCGraphTransformer/lambda$1$Type",1732),sDn(1741,1,y1n,kr),uZn.Mb=function(n){return GB(),F$(uG(n,60).g,10)},zW(E6n,"LGraphToCGraphTransformer/lambda$10$Type",1741),sDn(1742,1,QZn,yr),uZn.Cd=function(n){jZ(uG(n,60))},zW(E6n,"LGraphToCGraphTransformer/lambda$11$Type",1742),sDn(1743,1,y1n,Mr),uZn.Mb=function(n){return GB(),F$(uG(n,60).g,154)},zW(E6n,"LGraphToCGraphTransformer/lambda$12$Type",1743),sDn(1747,1,QZn,Tr),uZn.Cd=function(n){Fwn(uG(n,60))},zW(E6n,"LGraphToCGraphTransformer/lambda$13$Type",1747),sDn(1744,1,QZn,Pg),uZn.Cd=function(n){WL(this.a,uG(n,8))},uZn.a=0,zW(E6n,"LGraphToCGraphTransformer/lambda$14$Type",1744),sDn(1745,1,QZn,Cg),uZn.Cd=function(n){JL(this.a,uG(n,116))},uZn.a=0,zW(E6n,"LGraphToCGraphTransformer/lambda$15$Type",1745),sDn(1746,1,QZn,Ig),uZn.Cd=function(n){QL(this.a,uG(n,8))},uZn.a=0,zW(E6n,"LGraphToCGraphTransformer/lambda$16$Type",1746),sDn(1748,1,{},jr),uZn.Kb=function(n){return GB(),new fX(null,new LW(new Fz(ix(Xgn(uG(n,10)).a.Kc(),new h))))},zW(E6n,"LGraphToCGraphTransformer/lambda$17$Type",1748),sDn(1749,1,y1n,Er),uZn.Mb=function(n){return GB(),v9(uG(n,18))},zW(E6n,"LGraphToCGraphTransformer/lambda$18$Type",1749),sDn(1750,1,QZn,Og),uZn.Cd=function(n){fin(this.a,uG(n,18))},zW(E6n,"LGraphToCGraphTransformer/lambda$19$Type",1750),sDn(1734,1,QZn,Ag),uZn.Cd=function(n){Q3(this.a,uG(n,154))},zW(E6n,"LGraphToCGraphTransformer/lambda$2$Type",1734),sDn(1751,1,{},Sr),uZn.Kb=function(n){return GB(),new fX(null,new h3(uG(n,30).a,16))},zW(E6n,"LGraphToCGraphTransformer/lambda$20$Type",1751),sDn(1752,1,{},Pr),uZn.Kb=function(n){return GB(),new fX(null,new LW(new Fz(ix(Xgn(uG(n,10)).a.Kc(),new h))))},zW(E6n,"LGraphToCGraphTransformer/lambda$21$Type",1752),sDn(1753,1,{},Cr),uZn.Kb=function(n){return GB(),uG(oIn(uG(n,18),(GYn(),Tmt)),15)},zW(E6n,"LGraphToCGraphTransformer/lambda$22$Type",1753),sDn(1754,1,y1n,Ir),uZn.Mb=function(n){return Hx(uG(n,15))},zW(E6n,"LGraphToCGraphTransformer/lambda$23$Type",1754),sDn(1755,1,QZn,Lg),uZn.Cd=function(n){pLn(this.a,uG(n,15))},zW(E6n,"LGraphToCGraphTransformer/lambda$24$Type",1755),sDn(1733,1,QZn,HC),uZn.Cd=function(n){P5(this.a,this.b,uG(n,154))},zW(E6n,"LGraphToCGraphTransformer/lambda$3$Type",1733),sDn(1735,1,{},Or),uZn.Kb=function(n){return GB(),new fX(null,new h3(uG(n,30).a,16))},zW(E6n,"LGraphToCGraphTransformer/lambda$4$Type",1735),sDn(1736,1,{},Ar),uZn.Kb=function(n){return GB(),new fX(null,new LW(new Fz(ix(Xgn(uG(n,10)).a.Kc(),new h))))},zW(E6n,"LGraphToCGraphTransformer/lambda$5$Type",1736),sDn(1737,1,{},Lr),uZn.Kb=function(n){return GB(),uG(oIn(uG(n,18),(GYn(),Tmt)),15)},zW(E6n,"LGraphToCGraphTransformer/lambda$6$Type",1737),sDn(1739,1,QZn,Ng),uZn.Cd=function(n){xLn(this.a,uG(n,15))},zW(E6n,"LGraphToCGraphTransformer/lambda$8$Type",1739),sDn(1740,1,QZn,UC),uZn.Cd=function(n){k$(this.a,this.b,uG(n,154))},zW(E6n,"LGraphToCGraphTransformer/lambda$9$Type",1740),sDn(1729,1,{},Nr),uZn.cf=function(n){var t,e,i,r,c;for(this.a=n,this.d=new ak,this.c=Inn(Tst,EZn,125,this.a.a.a.c.length,0,1),this.b=0,e=new Ww(this.a.a.a);e.a=g&&(kD(a,xwn(f)),v=e.Math.max(v,k[f-1]-l),u+=d,p+=k[f-1]-p,l=k[f-1],d=s[f]),d=e.Math.max(d,s[f]),++f;u+=d}(w=e.Math.min(1/v,1/t.b/u))>r&&(r=w,i=a)}return i},uZn.pg=function(){return!1},zW(N6n,"MSDCutIndexHeuristic",816),sDn(1683,1,Q4n,Mc),uZn.Kf=function(n,t){Cqn(uG(n,36),t)},zW(N6n,"SingleEdgeGraphWrapper",1683),sDn(232,22,{3:1,34:1,22:1,232:1},QC);var zdt,Vdt,Wdt,Qdt=_cn($6n,"CenterEdgeLabelPlacementStrategy",232,Oat,znn,JB);sDn(431,22,{3:1,34:1,22:1,431:1},WC);var Jdt,Ydt,Zdt,ngt,tgt=_cn($6n,"ConstraintCalculationStrategy",431,Oat,w1,YB);sDn(322,22,{3:1,34:1,22:1,322:1,188:1,196:1},JC),uZn.dg=function(){return ZLn(this)},uZn.qg=function(){return ZLn(this)};var egt,igt,rgt,cgt,agt=_cn($6n,"CrossingMinimizationStrategy",322,Oat,B2,ZB);sDn(351,22,{3:1,34:1,22:1,351:1},YC);var ogt,ugt,sgt,hgt,fgt,lgt,bgt=_cn($6n,"CuttingStrategy",351,Oat,H2,nH);sDn(348,22,{3:1,34:1,22:1,348:1,188:1,196:1},ZC),uZn.dg=function(){return ODn(this)},uZn.qg=function(){return ODn(this)};var wgt,dgt,ggt,pgt=_cn($6n,"CycleBreakingStrategy",348,Oat,h9,tH);sDn(428,22,{3:1,34:1,22:1,428:1},nI);var mgt,vgt,kgt,ygt,Mgt=_cn($6n,"DirectionCongruency",428,Oat,b1,eH);sDn(460,22,{3:1,34:1,22:1,460:1},tI);var Tgt,jgt,Egt,Sgt,Pgt,Cgt,Igt,Ogt=_cn($6n,"EdgeConstraint",460,Oat,U2,sH);sDn(283,22,{3:1,34:1,22:1,283:1},eI);var Agt,Lgt,Ngt,$gt=_cn($6n,"EdgeLabelSideSelection",283,Oat,Gnn,hH);sDn(488,22,{3:1,34:1,22:1,488:1},iI);var Dgt,xgt,Rgt,Kgt,Fgt,_gt,Bgt,Hgt=_cn($6n,"EdgeStraighteningStrategy",488,Oat,y1,fH);sDn(281,22,{3:1,34:1,22:1,281:1},rI);var Ugt,Ggt,qgt,Xgt,zgt,Vgt,Wgt,Qgt=_cn($6n,"FixedAlignment",281,Oat,qnn,uH);sDn(282,22,{3:1,34:1,22:1,282:1},cI);var Jgt,Ygt,Zgt,npt,tpt,ept,ipt,rpt,cpt,apt,opt,upt=_cn($6n,"GraphCompactionStrategy",282,Oat,Xnn,iH);sDn(259,22,{3:1,34:1,22:1,259:1},aI);var spt,hpt,fpt,lpt,bpt=_cn($6n,"GraphProperties",259,Oat,oun,rH);sDn(299,22,{3:1,34:1,22:1,299:1},oI);var wpt,dpt,gpt,ppt,mpt=_cn($6n,"GreedySwitchType",299,Oat,G2,cH);sDn(311,22,{3:1,34:1,22:1,311:1},uI);var vpt,kpt,ypt,Mpt=_cn($6n,"InLayerConstraint",311,Oat,q2,aH);sDn(429,22,{3:1,34:1,22:1,429:1},sI);var Tpt,jpt,Ept,Spt,Ppt,Cpt,Ipt,Opt,Apt,Lpt,Npt,$pt,Dpt,xpt,Rpt,Kpt,Fpt,_pt,Bpt,Hpt,Upt,Gpt,qpt,Xpt,zpt,Vpt,Wpt,Qpt,Jpt,Ypt,Zpt,nmt,tmt,emt,imt,rmt,cmt,amt,omt,umt,smt,hmt,fmt,lmt,bmt,wmt,dmt,gmt,pmt,mmt,vmt,kmt,ymt,Mmt,Tmt,jmt,Emt,Smt,Pmt,Cmt,Imt,Omt,Amt,Lmt,Nmt=_cn($6n,"InteractiveReferencePoint",429,Oat,l1,oH);sDn(171,22,{3:1,34:1,22:1,171:1},hI);var $mt,Dmt,xmt,Rmt,Kmt,Fmt,_mt,Bmt,Hmt,Umt,Gmt,qmt,Xmt,zmt,Vmt,Wmt,Qmt,Jmt,Ymt,Zmt,nvt,tvt,evt,ivt,rvt,cvt,avt,ovt,uvt,svt,hvt,fvt,lvt,bvt,wvt,dvt,gvt,pvt,mvt,vvt,kvt,yvt,Mvt,Tvt,jvt,Evt,Svt,Pvt,Cvt,Ivt,Ovt,Avt,Lvt,Nvt,$vt,Dvt,xvt,Rvt,Kvt,Fvt,_vt,Bvt,Hvt,Uvt,Gvt,qvt,Xvt,zvt,Vvt,Wvt,Qvt,Jvt,Yvt,Zvt,nkt,tkt,ekt,ikt,rkt,ckt,akt,okt,ukt,skt,hkt,fkt,lkt,bkt,wkt,dkt,gkt,pkt,mkt,vkt,kkt,ykt,Mkt,Tkt,jkt,Ekt,Skt,Pkt,Ckt,Ikt,Okt,Akt,Lkt,Nkt,$kt,Dkt,xkt,Rkt,Kkt,Fkt,_kt,Bkt,Hkt,Ukt,Gkt,qkt,Xkt,zkt,Vkt,Wkt,Qkt,Jkt,Ykt,Zkt,nyt,tyt,eyt,iyt,ryt,cyt,ayt,oyt,uyt,syt,hyt,fyt,lyt,byt,wyt,dyt,gyt,pyt,myt,vyt,kyt,yyt,Myt,Tyt,jyt,Eyt,Syt,Pyt,Cyt,Iyt,Oyt,Ayt,Lyt,Nyt,$yt,Dyt,xyt,Ryt,Kyt,Fyt,_yt,Byt,Hyt,Uyt,Gyt,qyt,Xyt,zyt,Vyt,Wyt,Qyt,Jyt,Yyt,Zyt,nMt,tMt,eMt,iMt,rMt,cMt,aMt,oMt,uMt,sMt,hMt,fMt,lMt,bMt,wMt,dMt,gMt,pMt,mMt,vMt,kMt,yMt,MMt,TMt,jMt,EMt,SMt,PMt,CMt,IMt,OMt,AMt,LMt,NMt,$Mt,DMt,xMt,RMt,KMt,FMt,_Mt,BMt,HMt,UMt,GMt,qMt,XMt,zMt,VMt,WMt,QMt,JMt,YMt,ZMt,nTt,tTt,eTt,iTt,rTt,cTt,aTt,oTt,uTt,sTt,hTt,fTt,lTt,bTt,wTt,dTt,gTt,pTt,mTt,vTt,kTt,yTt,MTt,TTt,jTt,ETt,STt,PTt,CTt,ITt,OTt,ATt,LTt,NTt,$Tt,DTt,xTt,RTt,KTt,FTt,_Tt,BTt,HTt,UTt,GTt,qTt,XTt,zTt,VTt,WTt,QTt,JTt,YTt,ZTt,njt,tjt,ejt,ijt,rjt,cjt,ajt=_cn($6n,"LayerConstraint",171,Oat,l9,lH);sDn(859,1,K2n,fl),uZn.hf=function(n){Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,B6n),""),"Direction Congruency"),"Specifies how drawings of the same graph with different layout directions compare to each other: either a natural reading direction is preserved or the drawings are rotated versions of each other."),vvt),(lAn(),gNt)),Mgt),ggn((Rkn(),hNt))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,H6n),""),"Feedback Edges"),"Whether feedback edges should be highlighted by routing around the nodes."),(qx(),!1)),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,U6n),""),"Interactive Reference Point"),"Determines which point of a node is considered by interactive layout phases."),Hvt),gNt),Nmt),ggn(hNt)))),H4(n,U6n,J6n,Gvt),H4(n,U6n,o5n,Uvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,G6n),""),"Merge Edges"),"Edges that have no ports are merged so they touch the connected nodes at the same points. When this option is disabled, one port is created for each edge directly connected to a node. When it is enabled, all such incoming edges share an input port, and all outgoing edges share an output port."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,q6n),""),"Merge Hierarchy-Crossing Edges"),"If hierarchical layout is active, hierarchy-crossing edges use as few hierarchical ports as possible. They are broken by the algorithm, with hierarchical ports inserted as required. Usually, one such port is created for each edge at each hierarchy crossing point. With this option set to true, we try to create as few hierarchical ports as possible in the process. In particular, all edges that form a hyperedge can share a port."),!0),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(VT(JT(QT(YT(qT(GT(WT(XT(zT(new xu,X6n),""),"Allow Non-Flow Ports To Switch Sides"),"Specifies whether non-flow ports may switch sides if their node's port constraints are either FIXED_SIDE or FIXED_ORDER. A non-flow port is a port on a side that is not part of the currently configured layout flow. For instance, given a left-to-right layout direction, north and south ports would be considered non-flow ports. Further note that the underlying criterium whether to switch sides or not solely relies on the minimization of edge crossings. Hence, edge length and other aesthetics criteria are not addressed."),!1),wNt),cot),ggn(fNt)),Uhn(cT($ot,1),zZn,2,6,["org.eclipse.elk.layered.northOrSouthPort"])))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,z6n),""),"Port Sorting Strategy"),"Only relevant for nodes with FIXED_SIDE port constraints. Determines the way a node's ports are distributed on the sides of a node if their order is not prescribed. The option is set on parent nodes."),Pkt),gNt),Jjt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,V6n),""),"Thoroughness"),"How much effort should be spent to produce a nice layout."),xwn(7)),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,W6n),""),"Add Unnecessary Bendpoints"),"Adds bend points even if an edge does not change direction. If true, each long edge dummy will contribute a bend point to its edges and hierarchy-crossing edges will always get a bend point where they cross hierarchy boundaries. By default, bend points are only added where an edge changes direction."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Q6n),""),"Generate Position and Layer IDs"),"If enabled position id and layer id are generated, which are usually only used internally when setting the interactiveLayout option. This option should be specified on the root node."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,J6n),"cycleBreaking"),"Cycle Breaking Strategy"),"Strategy for cycle breaking. Cycle breaking looks for cycles in the graph and determines which edges to reverse to break the cycles. Reversed edges will end up pointing to the opposite direction of regular edges (that is, reversed edges will point left if edges usually point right)."),pvt),gNt),pgt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Y6n),s8n),"Node Layering Strategy"),"Strategy for node layering."),ckt),gNt),fjt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Z6n),s8n),"Layer Constraint"),"Determines a constraint on the placement of the node regarding the layering."),Wvt),gNt),ajt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,n5n),s8n),"Layer Choice Constraint"),"Allows to set a constraint regarding the layer placement of a node. Let i be the value of teh constraint. Assumed the drawing has n layers and i < n. If set to i, it expresses that the node should be placed in i-th layer. Should i>=n be true then the node is placed in the last layer of the drawing. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),null),mNt),dot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,t5n),s8n),"Layer ID"),"Layer identifier that was calculated by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),xwn(-1)),mNt),dot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,e5n),h8n),"Upper Bound On Width [MinWidth Layerer]"),"Defines a loose upper bound on the width of the MinWidth layerer. If set to '-1' multiple values are tested and the best result is selected."),xwn(4)),mNt),dot),ggn(hNt)))),H4(n,e5n,Y6n,Yvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,i5n),h8n),"Upper Layer Estimation Scaling Factor [MinWidth Layerer]"),"Multiplied with Upper Bound On Width for defining an upper bound on the width of layers which haven't been determined yet, but whose maximum width had been (roughly) estimated by the MinWidth algorithm. Compensates for too high estimations. If set to '-1' multiple values are tested and the best result is selected."),xwn(2)),mNt),dot),ggn(hNt)))),H4(n,i5n,Y6n,nkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,r5n),f8n),"Node Promotion Strategy"),"Reduces number of dummy nodes after layering phase (if possible)."),ikt),gNt),Hjt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,c5n),f8n),"Max Node Promotion Iterations"),"Limits the number of iterations for node promotion."),xwn(0)),mNt),dot),ggn(hNt)))),H4(n,c5n,r5n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,a5n),"layering.coffmanGraham"),"Layer Bound"),"The maximum number of nodes allowed per layer."),xwn(vZn)),mNt),dot),ggn(hNt)))),H4(n,a5n,Y6n,Xvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,o5n),l8n),"Crossing Minimization Strategy"),"Strategy for crossing minimization."),dvt),gNt),agt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,u5n),l8n),"Force Node Model Order"),"The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,s5n),l8n),"Hierarchical Sweepiness"),"How likely it is to use cross-hierarchy (1) vs bottom-up (-1)."),.1),dNt),fot),ggn(hNt)))),H4(n,s5n,b8n,ovt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,h5n),l8n),"Semi-Interactive Crossing Minimization"),"Preserves the order of nodes within a layer but still minimizes crossings between edges connecting long edge dummies. Derives the desired order from positions specified by the 'org.eclipse.elk.position' layout option. Requires a crossing minimization strategy that is able to process 'in-layer' constraints."),!1),wNt),cot),ggn(hNt)))),H4(n,h5n,o5n,bvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,f5n),l8n),"In Layer Predecessor of"),"Allows to set a constraint which specifies of which node the current node is the predecessor. If set to 's' then the node is the predecessor of 's' and is in the same layer"),null),kNt),$ot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,l5n),l8n),"In Layer Successor of"),"Allows to set a constraint which specifies of which node the current node is the successor. If set to 's' then the node is the successor of 's' and is in the same layer"),null),kNt),$ot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,b5n),l8n),"Position Choice Constraint"),"Allows to set a constraint regarding the position placement of a node in a layer. Assumed the layer in which the node placed includes n other nodes and i < n. If set to i, it expresses that the node should be placed at the i-th position. Should i>=n be true then the node is placed at the last position in the layer. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),null),mNt),dot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,w5n),l8n),"Position ID"),"Position within a layer that was determined by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),xwn(-1)),mNt),dot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,d5n),w8n),"Greedy Switch Activation Threshold"),"By default it is decided automatically if the greedy switch is activated or not. The decision is based on whether the size of the input graph (without dummy nodes) is smaller than the value of this option. A '0' enforces the activation."),xwn(40)),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,g5n),w8n),"Greedy Switch Crossing Minimization"),"Greedy Switch strategy for crossing minimization. The greedy switch heuristic is executed after the regular crossing minimization as a post-processor. Note that if 'hierarchyHandling' is set to 'INCLUDE_CHILDREN', the 'greedySwitchHierarchical.type' option must be used."),rvt),gNt),mpt),ggn(hNt)))),H4(n,g5n,o5n,cvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,p5n),"crossingMinimization.greedySwitchHierarchical"),"Greedy Switch Crossing Minimization (hierarchical)"),"Activates the greedy switch heuristic in case hierarchical layout is used. The differences to the non-hierarchical case (see 'greedySwitch.type') are: 1) greedy switch is inactive by default, 3) only the option value set on the node at which hierarchical layout starts is relevant, and 2) if it's activated by the user, it properly addresses hierarchy-crossing edges."),nvt),gNt),mpt),ggn(hNt)))),H4(n,p5n,o5n,tvt),H4(n,p5n,b8n,evt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,m5n),d8n),"Node Placement Strategy"),"Strategy for node placement."),Ekt),gNt),xjt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,v5n),d8n),"Favor Straight Edges Over Balancing"),"Favor straight edges over a balanced node placement. The default behavior is determined automatically based on the used 'edgeRouting'. For an orthogonal style it is set to true, for all other styles to false."),wNt),cot),ggn(hNt)))),H4(n,v5n,m5n,dkt),H4(n,v5n,m5n,gkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,k5n),g8n),"BK Edge Straightening"),"Specifies whether the Brandes Koepf node placer tries to increase the number of straight edges at the expense of diagram size. There is a subtle difference to the 'favorStraightEdges' option, which decides whether a balanced placement of the nodes is desired, or not. In bk terms this means combining the four alignments into a single balanced one, or not. This option on the other hand tries to straighten additional edges during the creation of each of the four alignments."),skt),gNt),Hgt),ggn(hNt)))),H4(n,k5n,m5n,hkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,y5n),g8n),"BK Fixed Alignment"),"Tells the BK node placer to use a certain alignment (out of its four) instead of the one producing the smallest height, or the combination of all four."),lkt),gNt),Qgt),ggn(hNt)))),H4(n,y5n,m5n,bkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,M5n),"nodePlacement.linearSegments"),"Linear Segments Deflection Dampening"),"Dampens the movement of nodes to keep the diagram from getting too large."),.3),dNt),fot),ggn(hNt)))),H4(n,M5n,m5n,mkt),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,T5n),"nodePlacement.networkSimplex"),"Node Flexibility"),"Aims at shorter and straighter edges. Two configurations are possible: (a) allow ports to move freely on the side they are assigned to (the order is always defined beforehand), (b) additionally allow to enlarge a node wherever it helps. If this option is not configured for a node, the 'nodeFlexibility.default' value is used, which is specified for the node's parent."),gNt),jjt),ggn(sNt)))),H4(n,T5n,m5n,Tkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,j5n),"nodePlacement.networkSimplex.nodeFlexibility"),"Node Flexibility Default"),"Default value of the 'nodeFlexibility' option for the children of a hierarchical node."),ykt),gNt),jjt),ggn(hNt)))),H4(n,j5n,m5n,Mkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,E5n),p8n),"Self-Loop Distribution"),"Alter the distribution of the loops around the node. It only takes effect for PortConstraints.FREE."),Pvt),gNt),oEt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,S5n),p8n),"Self-Loop Ordering"),"Alter the ordering of the loops they can either be stacked or sequenced. It only takes effect for PortConstraints.FREE."),Ivt),gNt),lEt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,P5n),"edgeRouting.splines"),"Spline Routing Mode"),"Specifies the way control points are assembled for each individual edge. CONSERVATIVE ensures that edges are properly routed around the nodes but feels rather orthogonal at times. SLOPPY uses fewer control points to obtain curvier edge routes but may result in edges overlapping nodes."),Avt),gNt),pEt),ggn(hNt)))),H4(n,P5n,m8n,Lvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,C5n),"edgeRouting.splines.sloppy"),"Sloppy Spline Layer Spacing Factor"),"Spacing factor for routing area between layers when using sloppy spline routing."),.2),dNt),fot),ggn(hNt)))),H4(n,C5n,m8n,$vt),H4(n,C5n,P5n,Dvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,I5n),"edgeRouting.polyline"),"Sloped Edge Zone Width"),"Width of the strip to the left and to the right of each layer where the polyline edge router is allowed to refrain from ensuring that edges are routed horizontally. This prevents awkward bend points for nodes that extent almost to the edge of their layer."),2),dNt),fot),ggn(hNt)))),H4(n,I5n,m8n,Evt),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,O5n),v8n),"Spacing Base Value"),"An optional base value for all other layout options of the 'spacing' group. It can be used to conveniently alter the overall 'spaciousness' of the drawing. Whenever an explicit value is set for the other layout options, this base value will have no effect. The base value is not inherited, i.e. it must be set for each hierarchical node."),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,A5n),v8n),"Edge Node Between Layers Spacing"),"The spacing to be preserved between nodes and edges that are routed next to the node's layer. For the spacing between nodes and edges that cross the node's layer 'spacing.edgeNode' is used."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,L5n),v8n),"Edge Edge Between Layer Spacing"),"Spacing to be preserved between pairs of edges that are routed between the same pair of layers. Note that 'spacing.edgeEdge' is used for the spacing between pairs of edges crossing the same layer."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,N5n),v8n),"Node Node Between Layers Spacing"),"The spacing to be preserved between any pair of nodes of two adjacent layers. Note that 'spacing.nodeNode' is used for the spacing between nodes within the layer itself."),20),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,$5n),k8n),"Direction Priority"),"Defines how important it is to have a certain edge point into the direction of the overall layout. This option is evaluated during the cycle breaking phase."),xwn(0)),mNt),dot),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,D5n),k8n),"Shortness Priority"),"Defines how important it is to keep an edge as short as possible. This option is evaluated during the layering phase."),xwn(0)),mNt),dot),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,x5n),k8n),"Straightness Priority"),"Defines how important it is to keep an edge straight, i.e. aligned with one of the two axes. This option is evaluated during node placement."),xwn(0)),mNt),dot),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,R5n),y8n),j3n),"Tries to further compact components (disconnected sub-graphs)."),!1),wNt),cot),ggn(hNt)))),H4(n,R5n,h4n,!0),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,K5n),M8n),"Post Compaction Strategy"),T8n),_mt),gNt),upt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,F5n),M8n),"Post Compaction Constraint Calculation"),T8n),Kmt),gNt),tgt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,_5n),j8n),"High Degree Node Treatment"),"Makes room around high degree nodes to place leafs and trees."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,B5n),j8n),"High Degree Node Threshold"),"Whether a node is considered to have a high degree."),xwn(16)),mNt),dot),ggn(hNt)))),H4(n,B5n,_5n,!0),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,H5n),j8n),"High Degree Node Maximum Tree Height"),"Maximum height of a subtree connected to a high degree node to be moved to separate layers."),xwn(5)),mNt),dot),ggn(hNt)))),H4(n,H5n,_5n,!0),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,U5n),E8n),"Graph Wrapping Strategy"),"For certain graphs and certain prescribed drawing areas it may be desirable to split the laid out graph into chunks that are placed side by side. The edges that connect different chunks are 'wrapped' around from the end of one chunk to the start of the other chunk. The points between the chunks are referred to as 'cuts'."),cyt),gNt),xEt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,G5n),E8n),"Additional Wrapped Edges Spacing"),"To visually separate edges that are wrapped from regularly routed edges an additional spacing value can be specified in form of this layout option. The spacing is added to the regular edgeNode spacing."),10),dNt),fot),ggn(hNt)))),H4(n,G5n,U5n,Kkt),H4(n,G5n,U5n,Fkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,q5n),E8n),"Correction Factor for Wrapping"),"At times and for certain types of graphs the executed wrapping may produce results that are consistently biased in the same fashion: either wrapping to often or to rarely. This factor can be used to correct the bias. Internally, it is simply multiplied with the 'aspect ratio' layout option."),1),dNt),fot),ggn(hNt)))),H4(n,q5n,U5n,Bkt),H4(n,q5n,U5n,Hkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,X5n),S8n),"Cutting Strategy"),"The strategy by which the layer indexes are determined at which the layering crumbles into chunks."),Wkt),gNt),bgt),ggn(hNt)))),H4(n,X5n,U5n,Qkt),H4(n,X5n,U5n,Jkt),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,z5n),S8n),"Manually Specified Cuts"),"Allows the user to specify her own cuts for a certain graph."),vNt),yat),ggn(hNt)))),H4(n,z5n,X5n,Gkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,V5n),"wrapping.cutting.msd"),"MSD Freedom"),"The MSD cutting strategy starts with an initial guess on the number of chunks the graph should be split into. The freedom specifies how much the strategy may deviate from this guess. E.g. if an initial number of 3 is computed, a freedom of 1 allows 2, 3, and 4 cuts."),Xkt),mNt),dot),ggn(hNt)))),H4(n,V5n,X5n,zkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,W5n),P8n),"Validification Strategy"),"When wrapping graphs, one can specify indices that are not allowed as split points. The validification strategy makes sure every computed split point is allowed."),hyt),gNt),MEt),ggn(hNt)))),H4(n,W5n,U5n,fyt),H4(n,W5n,U5n,lyt),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,Q5n),P8n),"Valid Indices for Wrapping"),null),vNt),yat),ggn(hNt)))),H4(n,Q5n,U5n,oyt),H4(n,Q5n,U5n,uyt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,J5n),C8n),"Improve Cuts"),"For general graphs it is important that not too many edges wrap backwards. Thus a compromise between evenly-distributed cuts and the total number of cut edges is sought."),!0),wNt),cot),ggn(hNt)))),H4(n,J5n,U5n,tyt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Y5n),C8n),"Distance Penalty When Improving Cuts"),null),2),dNt),fot),ggn(hNt)))),H4(n,Y5n,U5n,Zkt),H4(n,Y5n,J5n,!0),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Z5n),C8n),"Improve Wrapped Edges"),"The initial wrapping is performed in a very simple way. As a consequence, edges that wrap from one chunk to another may be unnecessarily long. Activating this option tries to shorten such edges."),!0),wNt),cot),ggn(hNt)))),H4(n,Z5n,U5n,iyt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,n8n),I8n),"Edge Label Side Selection"),"Method to decide on edge label sides."),Tvt),gNt),$gt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,t8n),I8n),"Edge Center Label Placement Strategy"),"Determines in which layer center labels of long edges should be placed."),yvt),gNt),Qdt),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[uNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,e8n),O8n),"Consider Model Order"),"Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting."),Qmt),gNt),Xjt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,i8n),O8n),"Consider Port Order"),"If disabled the port order of output ports is derived from the edge order and input ports are ordered by their incoming connections. If enabled all ports are ordered by the port model order."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,r8n),O8n),"No Model Order"),"Set on a node to not set a model order for this node even though it is a real node."),!1),wNt),cot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,c8n),O8n),"Consider Model Order for Components"),"If set to NONE the usual ordering strategy (by cumulative node priority and size of nodes) is used. INSIDE_PORT_SIDES orders the components with external ports only inside the groups with the same port side. FORCE_MODEL_ORDER enforces the mode order on components. This option might produce bad alignments and sub optimal drawings in terms of used area since the ordering should be respected."),Hmt),gNt),abt),ggn(hNt)))),H4(n,c8n,h4n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,a8n),O8n),"Long Edge Ordering Strategy"),"Indicates whether long edges are sorted under, over, or equal to nodes that have no connection to a previous layer in a left-to-right or right-to-left layout. Under and over changes to right and left in a vertical layout."),Xmt),gNt),pjt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,o8n),O8n),"Crossing Counter Node Order Influence"),"Indicates with what percentage (1 for 100%) violations of the node model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal node order. Defaults to no influence (0)."),0),dNt),fot),ggn(hNt)))),H4(n,o8n,e8n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,u8n),O8n),"Crossing Counter Port Order Influence"),"Indicates with what percentage (1 for 100%) violations of the port model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal port order. Defaults to no influence (0)."),0),dNt),fot),ggn(hNt)))),H4(n,u8n,e8n,null),eZn((new ll,n))},zW($6n,"LayeredMetaDataProvider",859),sDn(998,1,K2n,ll),uZn.hf=function(n){eZn(n)},zW($6n,"LayeredOptions",998),sDn(999,1,{},Tc),uZn.sf=function(){return new mk},uZn.tf=function(n){},zW($6n,"LayeredOptions/LayeredFactory",999),sDn(1391,1,{}),uZn.a=0,zW(p9n,"ElkSpacings/AbstractSpacingsBuilder",1391),sDn(792,1391,{},omn),zW($6n,"LayeredSpacings/LayeredSpacingsBuilder",792),sDn(265,22,{3:1,34:1,22:1,265:1,188:1,196:1},fI),uZn.dg=function(){return J_n(this)},uZn.qg=function(){return J_n(this)};var ojt,ujt,sjt,hjt,fjt=_cn($6n,"LayeringStrategy",265,Oat,tan,bH);sDn(390,22,{3:1,34:1,22:1,390:1},lI);var ljt,bjt,wjt,djt,gjt,pjt=_cn($6n,"LongEdgeOrderingStrategy",390,Oat,X2,wH);sDn(203,22,{3:1,34:1,22:1,203:1},bI);var mjt,vjt,kjt,yjt,Mjt,Tjt,jjt=_cn($6n,"NodeFlexibility",203,Oat,q6,dH);sDn(323,22,{3:1,34:1,22:1,323:1,188:1,196:1},wI),uZn.dg=function(){return IDn(this)},uZn.qg=function(){return IDn(this)};var Ejt,Sjt,Pjt,Cjt,Ijt,Ojt,Ajt,Ljt,Njt,$jt,Djt,xjt=_cn($6n,"NodePlacementStrategy",323,Oat,f9,gH);sDn(243,22,{3:1,34:1,22:1,243:1},dI);var Rjt,Kjt,Fjt,_jt,Bjt,Hjt=_cn($6n,"NodePromotionStrategy",243,Oat,uun,pH);sDn(284,22,{3:1,34:1,22:1,284:1},gI);var Ujt,Gjt,qjt,Xjt=_cn($6n,"OrderingStrategy",284,Oat,X6,mH);sDn(430,22,{3:1,34:1,22:1,430:1},pI);var zjt,Vjt,Wjt,Qjt,Jjt=_cn($6n,"PortSortingStrategy",430,Oat,d1,vH);sDn(463,22,{3:1,34:1,22:1,463:1},mI);var Yjt,Zjt,nEt,tEt,eEt=_cn($6n,"PortType",463,Oat,z2,kH);sDn(387,22,{3:1,34:1,22:1,387:1},vI);var iEt,rEt,cEt,aEt,oEt=_cn($6n,"SelfLoopDistributionStrategy",387,Oat,V2,yH);sDn(349,22,{3:1,34:1,22:1,349:1},kI);var uEt,sEt,hEt,fEt,lEt=_cn($6n,"SelfLoopOrderingStrategy",349,Oat,W2,MH);sDn(312,1,{312:1},CVn),zW($6n,"Spacings",312),sDn(350,22,{3:1,34:1,22:1,350:1},yI);var bEt,wEt,dEt,gEt,pEt=_cn($6n,"SplineRoutingMode",350,Oat,Q2,TH);sDn(352,22,{3:1,34:1,22:1,352:1},MI);var mEt,vEt,kEt,yEt,MEt=_cn($6n,"ValidifyStrategy",352,Oat,J2,jH);sDn(388,22,{3:1,34:1,22:1,388:1},TI);var TEt,jEt,EEt,SEt,PEt,CEt,IEt,OEt,AEt,LEt,NEt,$Et,DEt,xEt=_cn($6n,"WrappingStrategy",388,Oat,Y2,EH);sDn(1398,1,y9n,il),uZn.rg=function(n){return uG(n,36),jEt},uZn.Kf=function(n,t){mzn(this,uG(n,36),t)},zW(M9n,"DepthFirstCycleBreaker",1398),sDn(793,1,y9n,ez),uZn.rg=function(n){return uG(n,36),EEt},uZn.Kf=function(n,t){gYn(this,uG(n,36),t)},uZn.sg=function(n){return uG(zq(n,iMn(this.d,n.c.length)),10)},zW(M9n,"GreedyCycleBreaker",793),sDn(1401,793,y9n,tL),uZn.sg=function(n){var t,e,i,r;for(r=null,t=vZn,i=new Ww(n);i.a1&&(oM(gK(oIn(HQ((u3(0,n.c.length),uG(n.c[0],10))),(jYn(),Cyt))))?Axn(n,this.d,uG(this,669)):(hZ(),f$(n,this.d)),xsn(this.e,n))},uZn.lg=function(n,t,e,i){var r,c,a,o,u,s,h;for(t!=vX(e,n.length)&&(c=n[t-(e?1:-1)],v7(this.f,c,e?(can(),Wjt):(can(),Vjt))),r=n[t][0],h=!i||r.k==(zIn(),lbt),s=n7(n[t]),this.vg(s,h,!1,e),a=0,u=new Ww(s);u.a"),n0?j0(this.a,n[t-1],n[t]):!e&&t1&&(oM(gK(oIn(HQ((u3(0,n.c.length),uG(n.c[0],10))),(jYn(),Cyt))))?Axn(n,this.d,this):(hZ(),f$(n,this.d)),oM(gK(oIn(HQ((u3(0,n.c.length),uG(n.c[0],10))),Cyt)))||xsn(this.e,n))},zW(S9n,"ModelOrderBarycenterHeuristic",669),sDn(1866,1,b2n,Zg),uZn.Ne=function(n,t){return TOn(this.a,uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(S9n,"ModelOrderBarycenterHeuristic/lambda$0$Type",1866),sDn(1423,1,y9n,wl),uZn.rg=function(n){var t;return uG(n,36),Aq(t=aN(XEt),(uIn(),Elt),(zYn(),Cwt)),t},uZn.Kf=function(n,t){jY((uG(n,36),t))},zW(S9n,"NoCrossingMinimizer",1423),sDn(809,413,j9n,rj),uZn.tg=function(n,t,e){var i,r,c,a,o,u,s,h,f,l,b;switch(f=this.g,e.g){case 1:for(r=0,c=0,h=new Ww(n.j);h.a1&&(r.j==(KQn(),kRt)?this.b[n]=!0:r.j==_Rt&&n>0&&(this.b[n-1]=!0))},uZn.f=0,zW(P6n,"AllCrossingsCounter",1861),sDn(595,1,{},Don),uZn.b=0,uZn.d=0,zW(P6n,"BinaryIndexedTree",595),sDn(532,1,{},R_),zW(P6n,"CrossingsCounter",532),sDn(1950,1,b2n,np),uZn.Ne=function(n,t){return wX(this.a,uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(P6n,"CrossingsCounter/lambda$0$Type",1950),sDn(1951,1,b2n,tp),uZn.Ne=function(n,t){return dX(this.a,uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(P6n,"CrossingsCounter/lambda$1$Type",1951),sDn(1952,1,b2n,ep),uZn.Ne=function(n,t){return gX(this.a,uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(P6n,"CrossingsCounter/lambda$2$Type",1952),sDn(1953,1,b2n,ip),uZn.Ne=function(n,t){return pX(this.a,uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(P6n,"CrossingsCounter/lambda$3$Type",1953),sDn(1954,1,QZn,rp),uZn.Cd=function(n){cen(this.a,uG(n,12))},zW(P6n,"CrossingsCounter/lambda$4$Type",1954),sDn(1955,1,y1n,cp),uZn.Mb=function(n){return NI(this.a,uG(n,12))},zW(P6n,"CrossingsCounter/lambda$5$Type",1955),sDn(1956,1,QZn,ap),uZn.Cd=function(n){MA(this,n)},zW(P6n,"CrossingsCounter/lambda$6$Type",1956),sDn(1957,1,QZn,EI),uZn.Cd=function(n){var t;PU(),A6(this.b,(t=this.a,uG(n,12),t))},zW(P6n,"CrossingsCounter/lambda$7$Type",1957),sDn(839,1,A2n,Nc),uZn.Lb=function(n){return PU(),vR(uG(n,12),(GYn(),lmt))},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return PU(),vR(uG(n,12),(GYn(),lmt))},zW(P6n,"CrossingsCounter/lambda$8$Type",839),sDn(1949,1,{},op),zW(P6n,"HyperedgeCrossingsCounter",1949),sDn(478,1,{34:1,478:1},BF),uZn.Fd=function(n){return _vn(this,uG(n,478))},uZn.b=0,uZn.c=0,uZn.e=0,uZn.f=0;var QEt=zW(P6n,"HyperedgeCrossingsCounter/Hyperedge",478);sDn(374,1,{34:1,374:1},bY),uZn.Fd=function(n){return exn(this,uG(n,374))},uZn.b=0,uZn.c=0;var JEt,YEt,ZEt=zW(P6n,"HyperedgeCrossingsCounter/HyperedgeCorner",374);sDn(531,22,{3:1,34:1,22:1,531:1},SI);var nSt,tSt,eSt,iSt,rSt,cSt=_cn(P6n,"HyperedgeCrossingsCounter/HyperedgeCorner/Type",531,Oat,g1,PH);sDn(1425,1,y9n,dl),uZn.rg=function(n){return uG(oIn(uG(n,36),(GYn(),Hpt)),21).Hc((r_n(),tpt))?tSt:null},uZn.Kf=function(n,t){HEn(this,uG(n,36),t)},zW(P9n,"InteractiveNodePlacer",1425),sDn(1426,1,y9n,gl),uZn.rg=function(n){return uG(oIn(uG(n,36),(GYn(),Hpt)),21).Hc((r_n(),tpt))?eSt:null},uZn.Kf=function(n,t){XMn(this,uG(n,36),t)},zW(P9n,"LinearSegmentsNodePlacer",1426),sDn(261,1,{34:1,261:1},Tk),uZn.Fd=function(n){return CT(this,uG(n,261))},uZn.Fb=function(n){var t;return!!F$(n,261)&&(t=uG(n,261),this.b==t.b)},uZn.Hb=function(){return this.b},uZn.Ib=function(){return"ls"+vIn(this.e)},uZn.a=0,uZn.b=0,uZn.c=-1,uZn.d=-1,uZn.g=0;var aSt,oSt=zW(P9n,"LinearSegmentsNodePlacer/LinearSegment",261);sDn(1428,1,y9n,iz),uZn.rg=function(n){return uG(oIn(uG(n,36),(GYn(),Hpt)),21).Hc((r_n(),tpt))?aSt:null},uZn.Kf=function(n,t){WJn(this,uG(n,36),t)},uZn.b=0,uZn.g=0,zW(P9n,"NetworkSimplexPlacer",1428),sDn(1447,1,b2n,$c),uZn.Ne=function(n,t){return d$(uG(n,17).a,uG(t,17).a)},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(P9n,"NetworkSimplexPlacer/0methodref$compare$Type",1447),sDn(1449,1,b2n,Dc),uZn.Ne=function(n,t){return d$(uG(n,17).a,uG(t,17).a)},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(P9n,"NetworkSimplexPlacer/1methodref$compare$Type",1449),sDn(655,1,{655:1},PI);var uSt=zW(P9n,"NetworkSimplexPlacer/EdgeRep",655);sDn(412,1,{412:1},wY),uZn.b=!1;var sSt,hSt,fSt,lSt=zW(P9n,"NetworkSimplexPlacer/NodeRep",412);sDn(515,13,{3:1,4:1,20:1,31:1,56:1,13:1,16:1,15:1,59:1,515:1},Ck),zW(P9n,"NetworkSimplexPlacer/Path",515),sDn(1429,1,{},xc),uZn.Kb=function(n){return uG(n,18).d.i.k},zW(P9n,"NetworkSimplexPlacer/Path/lambda$0$Type",1429),sDn(1430,1,y1n,Rc),uZn.Mb=function(n){return uG(n,273)==(zIn(),wbt)},zW(P9n,"NetworkSimplexPlacer/Path/lambda$1$Type",1430),sDn(1431,1,{},Kc),uZn.Kb=function(n){return uG(n,18).d.i},zW(P9n,"NetworkSimplexPlacer/Path/lambda$2$Type",1431),sDn(1432,1,y1n,up),uZn.Mb=function(n){return zK(Imn(uG(n,10)))},zW(P9n,"NetworkSimplexPlacer/Path/lambda$3$Type",1432),sDn(1433,1,y1n,Fc),uZn.Mb=function(n){return mq(uG(n,12))},zW(P9n,"NetworkSimplexPlacer/lambda$0$Type",1433),sDn(1434,1,QZn,CI),uZn.Cd=function(n){M$(this.a,this.b,uG(n,12))},zW(P9n,"NetworkSimplexPlacer/lambda$1$Type",1434),sDn(1443,1,QZn,sp),uZn.Cd=function(n){FLn(this.a,uG(n,18))},zW(P9n,"NetworkSimplexPlacer/lambda$10$Type",1443),sDn(1444,1,{},_c),uZn.Kb=function(n){return n2(),new fX(null,new h3(uG(n,30).a,16))},zW(P9n,"NetworkSimplexPlacer/lambda$11$Type",1444),sDn(1445,1,QZn,hp),uZn.Cd=function(n){D_n(this.a,uG(n,10))},zW(P9n,"NetworkSimplexPlacer/lambda$12$Type",1445),sDn(1446,1,{},Bc),uZn.Kb=function(n){return n2(),xwn(uG(n,125).e)},zW(P9n,"NetworkSimplexPlacer/lambda$13$Type",1446),sDn(1448,1,{},Hc),uZn.Kb=function(n){return n2(),xwn(uG(n,125).e)},zW(P9n,"NetworkSimplexPlacer/lambda$15$Type",1448),sDn(1450,1,y1n,Uc),uZn.Mb=function(n){return n2(),uG(n,412).c.k==(zIn(),dbt)},zW(P9n,"NetworkSimplexPlacer/lambda$17$Type",1450),sDn(1451,1,y1n,Gc),uZn.Mb=function(n){return n2(),uG(n,412).c.j.c.length>1},zW(P9n,"NetworkSimplexPlacer/lambda$18$Type",1451),sDn(1452,1,QZn,dY),uZn.Cd=function(n){Dpn(this.c,this.b,this.d,this.a,uG(n,412))},uZn.c=0,uZn.d=0,zW(P9n,"NetworkSimplexPlacer/lambda$19$Type",1452),sDn(1435,1,{},qc),uZn.Kb=function(n){return n2(),new fX(null,new h3(uG(n,30).a,16))},zW(P9n,"NetworkSimplexPlacer/lambda$2$Type",1435),sDn(1453,1,QZn,fp),uZn.Cd=function(n){j$(this.a,uG(n,12))},uZn.a=0,zW(P9n,"NetworkSimplexPlacer/lambda$20$Type",1453),sDn(1454,1,{},Xc),uZn.Kb=function(n){return n2(),new fX(null,new h3(uG(n,30).a,16))},zW(P9n,"NetworkSimplexPlacer/lambda$21$Type",1454),sDn(1455,1,QZn,lp),uZn.Cd=function(n){uD(this.a,uG(n,10))},zW(P9n,"NetworkSimplexPlacer/lambda$22$Type",1455),sDn(1456,1,y1n,zc),uZn.Mb=function(n){return zK(n)},zW(P9n,"NetworkSimplexPlacer/lambda$23$Type",1456),sDn(1457,1,{},Vc),uZn.Kb=function(n){return n2(),new fX(null,new h3(uG(n,30).a,16))},zW(P9n,"NetworkSimplexPlacer/lambda$24$Type",1457),sDn(1458,1,y1n,bp),uZn.Mb=function(n){return RL(this.a,uG(n,10))},zW(P9n,"NetworkSimplexPlacer/lambda$25$Type",1458),sDn(1459,1,QZn,II),uZn.Cd=function(n){$On(this.a,this.b,uG(n,10))},zW(P9n,"NetworkSimplexPlacer/lambda$26$Type",1459),sDn(1460,1,y1n,Wc),uZn.Mb=function(n){return n2(),!v9(uG(n,18))},zW(P9n,"NetworkSimplexPlacer/lambda$27$Type",1460),sDn(1461,1,y1n,Qc),uZn.Mb=function(n){return n2(),!v9(uG(n,18))},zW(P9n,"NetworkSimplexPlacer/lambda$28$Type",1461),sDn(1462,1,{},wp),uZn.Ve=function(n,t){return T$(this.a,uG(n,30),uG(t,30))},zW(P9n,"NetworkSimplexPlacer/lambda$29$Type",1462),sDn(1436,1,{},Jc),uZn.Kb=function(n){return n2(),new fX(null,new LW(new Fz(ix(Xgn(uG(n,10)).a.Kc(),new h))))},zW(P9n,"NetworkSimplexPlacer/lambda$3$Type",1436),sDn(1437,1,y1n,Yc),uZn.Mb=function(n){return n2(),h6(uG(n,18))},zW(P9n,"NetworkSimplexPlacer/lambda$4$Type",1437),sDn(1438,1,QZn,dp),uZn.Cd=function(n){vqn(this.a,uG(n,18))},zW(P9n,"NetworkSimplexPlacer/lambda$5$Type",1438),sDn(1439,1,{},Zc),uZn.Kb=function(n){return n2(),new fX(null,new h3(uG(n,30).a,16))},zW(P9n,"NetworkSimplexPlacer/lambda$6$Type",1439),sDn(1440,1,y1n,na),uZn.Mb=function(n){return n2(),uG(n,10).k==(zIn(),dbt)},zW(P9n,"NetworkSimplexPlacer/lambda$7$Type",1440),sDn(1441,1,{},ta),uZn.Kb=function(n){return n2(),new fX(null,new LW(new Fz(ix(Ggn(uG(n,10)).a.Kc(),new h))))},zW(P9n,"NetworkSimplexPlacer/lambda$8$Type",1441),sDn(1442,1,y1n,ea),uZn.Mb=function(n){return n2(),pq(uG(n,18))},zW(P9n,"NetworkSimplexPlacer/lambda$9$Type",1442),sDn(1424,1,y9n,pl),uZn.rg=function(n){return uG(oIn(uG(n,36),(GYn(),Hpt)),21).Hc((r_n(),tpt))?sSt:null},uZn.Kf=function(n,t){RXn(uG(n,36),t)},zW(P9n,"SimpleNodePlacer",1424),sDn(185,1,{185:1},WHn),uZn.Ib=function(){var n;return n="",this.c==(b0(),fSt)?n+=V2n:this.c==hSt&&(n+=z2n),this.o==(w0(),wSt)?n+=c3n:this.o==dSt?n+="UP":n+="BALANCED",n},zW(O9n,"BKAlignedLayout",185),sDn(523,22,{3:1,34:1,22:1,523:1},OI);var bSt,wSt,dSt,gSt=_cn(O9n,"BKAlignedLayout/HDirection",523,Oat,m1,CH);sDn(522,22,{3:1,34:1,22:1,522:1},AI);var pSt,mSt,vSt,kSt,ySt,MSt,TSt,jSt,ESt,SSt,PSt,CSt,ISt,OSt,ASt,LSt,NSt,$St,DSt,xSt=_cn(O9n,"BKAlignedLayout/VDirection",522,Oat,v1,IH);sDn(1699,1,{},LI),zW(O9n,"BKAligner",1699),sDn(1702,1,{},xjn),zW(O9n,"BKCompactor",1702),sDn(663,1,{663:1},ia),uZn.a=0,zW(O9n,"BKCompactor/ClassEdge",663),sDn(467,1,{467:1},Ek),uZn.a=null,uZn.b=0,zW(O9n,"BKCompactor/ClassNode",467),sDn(1427,1,y9n,FI),uZn.rg=function(n){return uG(oIn(uG(n,36),(GYn(),Hpt)),21).Hc((r_n(),tpt))?mSt:null},uZn.Kf=function(n,t){$Yn(this,uG(n,36),t)},uZn.d=!1,zW(O9n,"BKNodePlacer",1427),sDn(1700,1,{},ra),uZn.d=0,zW(O9n,"NeighborhoodInformation",1700),sDn(1701,1,b2n,gp),uZn.Ne=function(n,t){return vrn(this,uG(n,42),uG(t,42))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(O9n,"NeighborhoodInformation/NeighborComparator",1701),sDn(823,1,{}),zW(O9n,"ThresholdStrategy",823),sDn(1825,823,{},Sk),uZn.wg=function(n,t,e){return this.a.o==(w0(),dSt)?M0n:T0n},uZn.xg=function(){},zW(O9n,"ThresholdStrategy/NullThresholdStrategy",1825),sDn(587,1,{587:1},_I),uZn.c=!1,uZn.d=!1,zW(O9n,"ThresholdStrategy/Postprocessable",587),sDn(1826,823,{},Pk),uZn.wg=function(n,t,e){var i,r,c;return r=t==e,i=this.a.a[e.p]==t,r||i?(c=n,this.a.c,b0(),r&&(c=FXn(this,t,!0)),!isNaN(c)&&!isFinite(c)&&i&&(c=FXn(this,e,!1)),c):n},uZn.xg=function(){for(var n,t,e;0!=this.d.b;)(t=wGn(this,e=uG(H1(this.d),587))).a&&(n=t.a,(oM(this.a.f[this.a.g[e.b.p].p])||v9(n)||n.c.i.c!=n.d.i.c)&&(ixn(this,e)||VL(this.e,e)));for(;0!=this.e.a.c.length;)ixn(this,uG(obn(this.e),587))},zW(O9n,"ThresholdStrategy/SimpleThresholdStrategy",1826),sDn(645,1,{645:1,188:1,196:1},ca),uZn.dg=function(){return Fsn(this)},uZn.qg=function(){return Fsn(this)},zW(A9n,"EdgeRouterFactory",645),sDn(1485,1,y9n,ml),uZn.rg=function(n){return RFn(uG(n,36))},uZn.Kf=function(n,t){QXn(uG(n,36),t)},zW(A9n,"OrthogonalEdgeRouter",1485),sDn(1478,1,y9n,KI),uZn.rg=function(n){return oSn(uG(n,36))},uZn.Kf=function(n,t){XQn(this,uG(n,36),t)},zW(A9n,"PolylineEdgeRouter",1478),sDn(1479,1,A2n,oa),uZn.Lb=function(n){return shn(uG(n,10))},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return shn(uG(n,10))},zW(A9n,"PolylineEdgeRouter/1",1479),sDn(1872,1,y1n,ua),uZn.Mb=function(n){return uG(n,132).c==(_7(),$St)},zW(L9n,"HyperEdgeCycleDetector/lambda$0$Type",1872),sDn(1873,1,{},sa),uZn.Ze=function(n){return uG(n,132).d},zW(L9n,"HyperEdgeCycleDetector/lambda$1$Type",1873),sDn(1874,1,y1n,ha),uZn.Mb=function(n){return uG(n,132).c==(_7(),$St)},zW(L9n,"HyperEdgeCycleDetector/lambda$2$Type",1874),sDn(1875,1,{},fa),uZn.Ze=function(n){return uG(n,132).d},zW(L9n,"HyperEdgeCycleDetector/lambda$3$Type",1875),sDn(1876,1,{},la),uZn.Ze=function(n){return uG(n,132).d},zW(L9n,"HyperEdgeCycleDetector/lambda$4$Type",1876),sDn(1877,1,{},aa),uZn.Ze=function(n){return uG(n,132).d},zW(L9n,"HyperEdgeCycleDetector/lambda$5$Type",1877),sDn(118,1,{34:1,118:1},nhn),uZn.Fd=function(n){return IT(this,uG(n,118))},uZn.Fb=function(n){var t;return!!F$(n,118)&&(t=uG(n,118),this.g==t.g)},uZn.Hb=function(){return this.g},uZn.Ib=function(){var n,t,e,i;for(n=new lx("{"),i=new Ww(this.n);i.a"+this.b+" ("+yR(this.c)+")"},uZn.d=0,zW(L9n,"HyperEdgeSegmentDependency",132),sDn(528,22,{3:1,34:1,22:1,528:1},qI);var RSt,KSt,FSt,_St,BSt,HSt,USt,GSt,qSt=_cn(L9n,"HyperEdgeSegmentDependency/DependencyType",528,Oat,k1,OH);sDn(1878,1,{},pp),zW(L9n,"HyperEdgeSegmentSplitter",1878),sDn(1879,1,{},hj),uZn.a=0,uZn.b=0,zW(L9n,"HyperEdgeSegmentSplitter/AreaRating",1879),sDn(339,1,{339:1},OU),uZn.a=0,uZn.b=0,uZn.c=0,zW(L9n,"HyperEdgeSegmentSplitter/FreeArea",339),sDn(1880,1,b2n,ba),uZn.Ne=function(n,t){return C_(uG(n,118),uG(t,118))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(L9n,"HyperEdgeSegmentSplitter/lambda$0$Type",1880),sDn(1881,1,QZn,pY),uZn.Cd=function(n){I5(this.a,this.d,this.c,this.b,uG(n,118))},uZn.b=0,zW(L9n,"HyperEdgeSegmentSplitter/lambda$1$Type",1881),sDn(1882,1,{},wa),uZn.Kb=function(n){return new fX(null,new h3(uG(n,118).e,16))},zW(L9n,"HyperEdgeSegmentSplitter/lambda$2$Type",1882),sDn(1883,1,{},da),uZn.Kb=function(n){return new fX(null,new h3(uG(n,118).j,16))},zW(L9n,"HyperEdgeSegmentSplitter/lambda$3$Type",1883),sDn(1884,1,{},ga),uZn.Ye=function(n){return uM(pK(n))},zW(L9n,"HyperEdgeSegmentSplitter/lambda$4$Type",1884),sDn(664,1,{},NW),uZn.a=0,uZn.b=0,uZn.c=0,zW(L9n,"OrthogonalRoutingGenerator",664),sDn(1703,1,{},pa),uZn.Kb=function(n){return new fX(null,new h3(uG(n,118).e,16))},zW(L9n,"OrthogonalRoutingGenerator/lambda$0$Type",1703),sDn(1704,1,{},ma),uZn.Kb=function(n){return new fX(null,new h3(uG(n,118).j,16))},zW(L9n,"OrthogonalRoutingGenerator/lambda$1$Type",1704),sDn(670,1,{}),zW(N9n,"BaseRoutingDirectionStrategy",670),sDn(1870,670,{},Rk),uZn.yg=function(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t+n.o*i,h=new Ww(n.n);h.at4n&&(c=n,r=new MO(l,a=f),aq(o.a,r),WUn(this,o,c,r,!1),(b=n.r)&&(r=new MO(w=uM(pK(hyn(b.e,0))),a),aq(o.a,r),WUn(this,o,c,r,!1),c=b,r=new MO(w,a=t+b.o*i),aq(o.a,r),WUn(this,o,c,r,!1)),r=new MO(g,a),aq(o.a,r),WUn(this,o,c,r,!1)))},uZn.zg=function(n){return n.i.n.a+n.n.a+n.a.a},uZn.Ag=function(){return KQn(),KRt},uZn.Bg=function(){return KQn(),yRt},zW(N9n,"NorthToSouthRoutingStrategy",1870),sDn(1871,670,{},Kk),uZn.yg=function(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t-n.o*i,h=new Ww(n.n);h.at4n&&(c=n,r=new MO(l,a=f),aq(o.a,r),WUn(this,o,c,r,!1),(b=n.r)&&(r=new MO(w=uM(pK(hyn(b.e,0))),a),aq(o.a,r),WUn(this,o,c,r,!1),c=b,r=new MO(w,a=t-b.o*i),aq(o.a,r),WUn(this,o,c,r,!1)),r=new MO(g,a),aq(o.a,r),WUn(this,o,c,r,!1)))},uZn.zg=function(n){return n.i.n.a+n.n.a+n.a.a},uZn.Ag=function(){return KQn(),yRt},uZn.Bg=function(){return KQn(),KRt},zW(N9n,"SouthToNorthRoutingStrategy",1871),sDn(1869,670,{},Fk),uZn.yg=function(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t+n.o*i,h=new Ww(n.n);h.at4n&&(c=n,r=new MO(a=f,l),aq(o.a,r),WUn(this,o,c,r,!0),(b=n.r)&&(r=new MO(a,w=uM(pK(hyn(b.e,0)))),aq(o.a,r),WUn(this,o,c,r,!0),c=b,r=new MO(a=t+b.o*i,w),aq(o.a,r),WUn(this,o,c,r,!0)),r=new MO(a,g),aq(o.a,r),WUn(this,o,c,r,!0)))},uZn.zg=function(n){return n.i.n.b+n.n.b+n.a.b},uZn.Ag=function(){return KQn(),kRt},uZn.Bg=function(){return KQn(),_Rt},zW(N9n,"WestToEastRoutingStrategy",1869),sDn(828,1,{},jqn),uZn.Ib=function(){return vIn(this.a)},uZn.b=0,uZn.c=!1,uZn.d=!1,uZn.f=0,zW(D9n,"NubSpline",828),sDn(418,1,{418:1},pFn,R1),zW(D9n,"NubSpline/PolarCP",418),sDn(1480,1,y9n,zTn),uZn.rg=function(n){return HPn(uG(n,36))},uZn.Kf=function(n,t){EJn(this,uG(n,36),t)},zW(D9n,"SplineEdgeRouter",1480),sDn(274,1,{274:1},O7),uZn.Ib=function(){return this.a+" ->("+this.c+") "+this.b},uZn.c=0,zW(D9n,"SplineEdgeRouter/Dependency",274),sDn(465,22,{3:1,34:1,22:1,465:1},XI);var XSt,zSt,VSt,WSt,QSt,JSt=_cn(D9n,"SplineEdgeRouter/SideToProcess",465,Oat,S1,AH);sDn(1481,1,y1n,va),uZn.Mb=function(n){return uFn(),!uG(n,131).o},zW(D9n,"SplineEdgeRouter/lambda$0$Type",1481),sDn(1482,1,{},ka),uZn.Ze=function(n){return uFn(),uG(n,131).v+1},zW(D9n,"SplineEdgeRouter/lambda$1$Type",1482),sDn(1483,1,QZn,BI),uZn.Cd=function(n){yq(this.a,this.b,uG(n,42))},zW(D9n,"SplineEdgeRouter/lambda$2$Type",1483),sDn(1484,1,QZn,HI),uZn.Cd=function(n){Mq(this.a,this.b,uG(n,42))},zW(D9n,"SplineEdgeRouter/lambda$3$Type",1484),sDn(131,1,{34:1,131:1},UAn,Izn),uZn.Fd=function(n){return NT(this,uG(n,131))},uZn.b=0,uZn.e=!1,uZn.f=0,uZn.g=0,uZn.j=!1,uZn.k=!1,uZn.n=0,uZn.o=!1,uZn.p=!1,uZn.q=!1,uZn.s=0,uZn.u=0,uZn.v=0,uZn.F=0,zW(D9n,"SplineSegment",131),sDn(468,1,{468:1},ya),uZn.a=0,uZn.b=!1,uZn.c=!1,uZn.d=!1,uZn.e=!1,uZn.f=0,zW(D9n,"SplineSegment/EdgeInformation",468),sDn(1198,1,{},Ma),zW(_9n,q3n,1198),sDn(1199,1,b2n,Ta),uZn.Ne=function(n,t){return yNn(uG(n,121),uG(t,121))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(_9n,X3n,1199),sDn(1197,1,{},Gj),zW(_9n,"MrTree",1197),sDn(405,22,{3:1,34:1,22:1,405:1,188:1,196:1},zI),uZn.dg=function(){return TNn(this)},uZn.qg=function(){return TNn(this)};var YSt,ZSt=_cn(_9n,"TreeLayoutPhases",405,Oat,i5,LH);sDn(1112,205,M3n,FF),uZn.rf=function(n,t){var e,i,r,c,a,o,u;for(oM(gK(zDn(n,(QGn(),gCt))))||J1(new Sd((vP(),new Vy(n)))),(c=t.eh(B9n)).Ug("build tGraph",1),zsn(o=new L7,n),kfn(o,(OQn(),RPt),n),EUn(n,o,u=new Ym),iGn(n,o,u),a=o,c.Vg(),(c=t.eh(B9n)).Ug("Split graph",1),r=LUn(this.a,a),c.Vg(),i=new Ww(r);i.a"+V3(this.c):"e_"+Hon(this)},zW(U9n,"TEdge",65),sDn(121,137,{3:1,121:1,96:1,137:1},L7),uZn.Ib=function(){var n,t,e,i,r;for(r=null,i=Fkn(this.b,0);i.b!=i.d.c;)r+=(null==(e=uG(I6(i),40)).c||0==e.c.length?"n_"+e.g:"n_"+e.c)+"\n";for(t=Fkn(this.a,0);t.b!=t.d.c;)r+=((n=uG(I6(t),65)).b&&n.c?V3(n.b)+"->"+V3(n.c):"e_"+Hon(n))+"\n";return r};var nPt=zW(U9n,"TGraph",121);sDn(643,508,{3:1,508:1,643:1,96:1,137:1}),zW(U9n,"TShape",643),sDn(40,643,{3:1,508:1,40:1,643:1,96:1,137:1},wln),uZn.Ib=function(){return V3(this)};var tPt,ePt,iPt,rPt,cPt,aPt,oPt,uPt,sPt,hPt,fPt,lPt=zW(U9n,"TNode",40);sDn(236,1,t1n,Mp),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return new Tp(Fkn(this.a.d,0))},zW(U9n,"TNode/2",236),sDn(329,1,$Zn,Tp),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){return uG(I6(this.a),65).c},uZn.Ob=function(){return Jj(this.a)},uZn.Qb=function(){yrn(this.a)},zW(U9n,"TNode/2/1",329),sDn(1923,1,Q4n,Oa),uZn.Kf=function(n,t){SYn(this,uG(n,121),t)},zW(q9n,"CompactionProcessor",1923),sDn(1924,1,b2n,jp),uZn.Ne=function(n,t){return ksn(this.a,uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$0$Type",1924),sDn(1925,1,y1n,GI),uZn.Mb=function(n){return xZ(this.b,this.a,uG(n,42))},uZn.a=0,uZn.b=0,zW(q9n,"CompactionProcessor/lambda$1$Type",1925),sDn(1934,1,b2n,Aa),uZn.Ne=function(n,t){return vW(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$10$Type",1934),sDn(1935,1,b2n,La),uZn.Ne=function(n,t){return Kx(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$11$Type",1935),sDn(1936,1,b2n,Na),uZn.Ne=function(n,t){return kW(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$12$Type",1936),sDn(1926,1,y1n,Ep),uZn.Mb=function(n){return hD(this.a,uG(n,42))},uZn.a=0,zW(q9n,"CompactionProcessor/lambda$2$Type",1926),sDn(1927,1,y1n,Sp),uZn.Mb=function(n){return fD(this.a,uG(n,42))},uZn.a=0,zW(q9n,"CompactionProcessor/lambda$3$Type",1927),sDn(1928,1,y1n,$a),uZn.Mb=function(n){return-1==uG(n,40).c.indexOf(H9n)},zW(q9n,"CompactionProcessor/lambda$4$Type",1928),sDn(1929,1,{},Pp),uZn.Kb=function(n){return a6(this.a,uG(n,40))},uZn.a=0,zW(q9n,"CompactionProcessor/lambda$5$Type",1929),sDn(1930,1,{},Cp),uZn.Kb=function(n){return ren(this.a,uG(n,40))},uZn.a=0,zW(q9n,"CompactionProcessor/lambda$6$Type",1930),sDn(1931,1,b2n,Ip),uZn.Ne=function(n,t){return G9(this.a,uG(n,240),uG(t,240))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$7$Type",1931),sDn(1932,1,b2n,Op),uZn.Ne=function(n,t){return q9(this.a,uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$8$Type",1932),sDn(1933,1,b2n,Da),uZn.Ne=function(n,t){return Fx(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$9$Type",1933),sDn(1921,1,Q4n,xa),uZn.Kf=function(n,t){cBn(uG(n,121),t)},zW(q9n,"DirectionProcessor",1921),sDn(1913,1,Q4n,KF),uZn.Kf=function(n,t){YUn(this,uG(n,121),t)},zW(q9n,"FanProcessor",1913),sDn(1937,1,Q4n,Ra),uZn.Kf=function(n,t){N_n(uG(n,121),t)},zW(q9n,"GraphBoundsProcessor",1937),sDn(1938,1,{},Ka),uZn.Ye=function(n){return uG(n,40).e.a},zW(q9n,"GraphBoundsProcessor/lambda$0$Type",1938),sDn(1939,1,{},Fa),uZn.Ye=function(n){return uG(n,40).e.b},zW(q9n,"GraphBoundsProcessor/lambda$1$Type",1939),sDn(1940,1,{},_a),uZn.Ye=function(n){return lP(uG(n,40))},zW(q9n,"GraphBoundsProcessor/lambda$2$Type",1940),sDn(1941,1,{},Ba),uZn.Ye=function(n){return fP(uG(n,40))},zW(q9n,"GraphBoundsProcessor/lambda$3$Type",1941),sDn(262,22,{3:1,34:1,22:1,262:1,196:1},VI),uZn.dg=function(){switch(this.g){case 0:return new sy;case 1:return new KF;case 2:return new uy;case 3:return new Xa;case 4:return new Ua;case 8:return new Ha;case 5:return new xa;case 6:return new Va;case 7:return new Oa;case 9:return new Ra;case 10:return new Wa;default:throw hv(new vM(v6n+(null!=this.f?this.f:""+this.g)))}};var bPt,wPt,dPt,gPt,pPt=_cn(q9n,k6n,262,Oat,usn,NH);sDn(1920,1,Q4n,Ha),uZn.Kf=function(n,t){xQn(uG(n,121),t)},zW(q9n,"LevelCoordinatesProcessor",1920),sDn(1918,1,Q4n,Ua),uZn.Kf=function(n,t){ZRn(this,uG(n,121),t)},uZn.a=0,zW(q9n,"LevelHeightProcessor",1918),sDn(1919,1,t1n,Ga),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return hZ(),wS(),Qot},zW(q9n,"LevelHeightProcessor/1",1919),sDn(1914,1,Q4n,uy),uZn.Kf=function(n,t){g_n(this,uG(n,121),t)},zW(q9n,"LevelProcessor",1914),sDn(1915,1,y1n,qa),uZn.Mb=function(n){return oM(gK(oIn(uG(n,40),(OQn(),UPt))))},zW(q9n,"LevelProcessor/lambda$0$Type",1915),sDn(1916,1,Q4n,Xa),uZn.Kf=function(n,t){DAn(this,uG(n,121),t)},uZn.a=0,zW(q9n,"NeighborsProcessor",1916),sDn(1917,1,t1n,za),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return hZ(),wS(),Qot},zW(q9n,"NeighborsProcessor/1",1917),sDn(1922,1,Q4n,Va),uZn.Kf=function(n,t){JUn(this,uG(n,121),t)},uZn.a=0,zW(q9n,"NodePositionProcessor",1922),sDn(1912,1,Q4n,sy),uZn.Kf=function(n,t){Ezn(this,uG(n,121),t)},zW(q9n,"RootProcessor",1912),sDn(1942,1,Q4n,Wa),uZn.Kf=function(n,t){Wyn(uG(n,121),t)},zW(q9n,"Untreeifyer",1942),sDn(392,22,{3:1,34:1,22:1,392:1},WI);var mPt,vPt,kPt,yPt,MPt,TPt,jPt,EPt,SPt,PPt,CPt,IPt,OPt,APt,LPt,NPt,$Pt,DPt,xPt,RPt,KPt,FPt,_Pt,BPt,HPt,UPt,GPt,qPt,XPt,zPt,VPt,WPt,QPt,JPt,YPt,ZPt,nCt,tCt,eCt,iCt,rCt,cCt,aCt,oCt,uCt,sCt,hCt,fCt,lCt,bCt,wCt,dCt,gCt,pCt,mCt,vCt,kCt,yCt,MCt,TCt,jCt,ECt,SCt,PCt,CCt,ICt,OCt,ACt,LCt,NCt,$Ct,DCt,xCt,RCt=_cn(W9n,"EdgeRoutingMode",392,Oat,t3,$H);sDn(862,1,K2n,vl),uZn.hf=function(n){Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,J9n),""),r7n),"Turns on Tree compaction which decreases the size of the whole tree by placing nodes of multiple levels in one large level"),(qx(),!1)),(lAn(),wNt)),cot),ggn((Rkn(),hNt))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Y9n),""),"Edge End Texture Length"),"Should be set to the length of the texture at the end of an edge. This value can be used to improve the Edge Routing."),7),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Z9n),""),"Tree Level"),"The index for the tree level the node is in"),xwn(0)),mNt),dot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,n7n),""),r7n),"When set to a positive number this option will force the algorithm to place the node to the specified position within the trees layer if weighting is set to constraint"),xwn(-1)),mNt),dot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,t7n),""),"Weighting of Nodes"),"Which weighting to use when computing a node order."),tCt),gNt),BCt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,e7n),""),"Edge Routing Mode"),"Chooses an Edge Routing algorithm."),WPt),gNt),RCt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,i7n),""),"Search Order"),"Which search order to use when computing a spanning tree."),YPt),gNt),QCt),ggn(hNt)))),yJn((new Ml,n))},zW(W9n,"MrTreeMetaDataProvider",862),sDn(1006,1,K2n,Ml),uZn.hf=function(n){yJn(n)},zW(W9n,"MrTreeOptions",1006),sDn(1007,1,{},Qa),uZn.sf=function(){return new FF},uZn.tf=function(n){},zW(W9n,"MrTreeOptions/MrtreeFactory",1007),sDn(353,22,{3:1,34:1,22:1,353:1},QI);var KCt,FCt,_Ct,BCt=_cn(W9n,"OrderWeighting",353,Oat,r5,DH);sDn(433,22,{3:1,34:1,22:1,433:1},JI);var HCt,UCt,GCt,qCt,XCt,zCt,VCt,WCt,QCt=_cn(W9n,"TreeifyingOrder",433,Oat,j1,xH);sDn(1486,1,y9n,Tl),uZn.rg=function(n){return uG(n,121),UCt},uZn.Kf=function(n,t){$un(this,uG(n,121),t)},zW("org.eclipse.elk.alg.mrtree.p1treeify","DFSTreeifyer",1486),sDn(1487,1,y9n,jl),uZn.rg=function(n){return uG(n,121),GCt},uZn.Kf=function(n,t){E_n(this,uG(n,121),t)},zW(u7n,"NodeOrderer",1487),sDn(1494,1,{},lo),uZn.td=function(n){return Nq(n)},zW(u7n,"NodeOrderer/0methodref$lambda$6$Type",1494),sDn(1488,1,y1n,bo),uZn.Mb=function(n){return ncn(),oM(gK(oIn(uG(n,40),(OQn(),UPt))))},zW(u7n,"NodeOrderer/lambda$0$Type",1488),sDn(1489,1,y1n,wo),uZn.Mb=function(n){return ncn(),uG(oIn(uG(n,40),(QGn(),kCt)),17).a<0},zW(u7n,"NodeOrderer/lambda$1$Type",1489),sDn(1490,1,y1n,Lp),uZn.Mb=function(n){return _an(this.a,uG(n,40))},zW(u7n,"NodeOrderer/lambda$2$Type",1490),sDn(1491,1,y1n,Ap),uZn.Mb=function(n){return f6(this.a,uG(n,40))},zW(u7n,"NodeOrderer/lambda$3$Type",1491),sDn(1492,1,b2n,go),uZn.Ne=function(n,t){return frn(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(u7n,"NodeOrderer/lambda$4$Type",1492),sDn(1493,1,y1n,po),uZn.Mb=function(n){return ncn(),0!=uG(oIn(uG(n,40),(OQn(),EPt)),17).a},zW(u7n,"NodeOrderer/lambda$5$Type",1493),sDn(1495,1,y9n,yl),uZn.rg=function(n){return uG(n,121),qCt},uZn.Kf=function(n,t){aUn(this,uG(n,121),t)},uZn.b=0,zW("org.eclipse.elk.alg.mrtree.p3place","NodePlacer",1495),sDn(1496,1,y9n,kl),uZn.rg=function(n){return uG(n,121),XCt},uZn.Kf=function(n,t){gHn(uG(n,121),t)},zW(s7n,"EdgeRouter",1496),sDn(1498,1,b2n,fo),uZn.Ne=function(n,t){return d$(uG(n,17).a,uG(t,17).a)},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/0methodref$compare$Type",1498),sDn(1503,1,{},Ya),uZn.Ye=function(n){return uM(pK(n))},zW(s7n,"EdgeRouter/1methodref$doubleValue$Type",1503),sDn(1505,1,b2n,Za),uZn.Ne=function(n,t){return ugn(uM(pK(n)),uM(pK(t)))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/2methodref$compare$Type",1505),sDn(1507,1,b2n,no),uZn.Ne=function(n,t){return ugn(uM(pK(n)),uM(pK(t)))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/3methodref$compare$Type",1507),sDn(1509,1,{},Ja),uZn.Ye=function(n){return uM(pK(n))},zW(s7n,"EdgeRouter/4methodref$doubleValue$Type",1509),sDn(1511,1,b2n,to),uZn.Ne=function(n,t){return ugn(uM(pK(n)),uM(pK(t)))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/5methodref$compare$Type",1511),sDn(1513,1,b2n,eo),uZn.Ne=function(n,t){return ugn(uM(pK(n)),uM(pK(t)))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/6methodref$compare$Type",1513),sDn(1497,1,{},io),uZn.Kb=function(n){return tcn(),uG(oIn(uG(n,40),(QGn(),ACt)),17)},zW(s7n,"EdgeRouter/lambda$0$Type",1497),sDn(1508,1,{},ro),uZn.Kb=function(n){return CR(uG(n,40))},zW(s7n,"EdgeRouter/lambda$11$Type",1508),sDn(1510,1,{},dO),uZn.Kb=function(n){return vq(this.b,this.a,uG(n,40))},uZn.a=0,uZn.b=0,zW(s7n,"EdgeRouter/lambda$13$Type",1510),sDn(1512,1,{},gO),uZn.Kb=function(n){return IR(this.b,this.a,uG(n,40))},uZn.a=0,uZn.b=0,zW(s7n,"EdgeRouter/lambda$15$Type",1512),sDn(1514,1,b2n,co),uZn.Ne=function(n,t){return Gkn(uG(n,65),uG(t,65))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/lambda$17$Type",1514),sDn(1515,1,b2n,ao),uZn.Ne=function(n,t){return qkn(uG(n,65),uG(t,65))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/lambda$18$Type",1515),sDn(1516,1,b2n,oo),uZn.Ne=function(n,t){return zkn(uG(n,65),uG(t,65))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/lambda$19$Type",1516),sDn(1499,1,y1n,Np),uZn.Mb=function(n){return n0(this.a,uG(n,40))},uZn.a=0,zW(s7n,"EdgeRouter/lambda$2$Type",1499),sDn(1517,1,b2n,uo),uZn.Ne=function(n,t){return Xkn(uG(n,65),uG(t,65))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/lambda$20$Type",1517),sDn(1500,1,b2n,so),uZn.Ne=function(n,t){return TG(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/lambda$3$Type",1500),sDn(1501,1,b2n,ho),uZn.Ne=function(n,t){return jG(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/lambda$4$Type",1501),sDn(1502,1,{},mo),uZn.Kb=function(n){return OR(uG(n,40))},zW(s7n,"EdgeRouter/lambda$5$Type",1502),sDn(1504,1,{},pO),uZn.Kb=function(n){return kq(this.b,this.a,uG(n,40))},uZn.a=0,uZn.b=0,zW(s7n,"EdgeRouter/lambda$7$Type",1504),sDn(1506,1,{},mO),uZn.Kb=function(n){return AR(this.b,this.a,uG(n,40))},uZn.a=0,uZn.b=0,zW(s7n,"EdgeRouter/lambda$9$Type",1506),sDn(675,1,{675:1},wTn),uZn.e=0,uZn.f=!1,uZn.g=!1,zW(s7n,"MultiLevelEdgeNodeNodeGap",675),sDn(1943,1,b2n,vo),uZn.Ne=function(n,t){return l2(uG(n,240),uG(t,240))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"MultiLevelEdgeNodeNodeGap/lambda$0$Type",1943),sDn(1944,1,b2n,ko),uZn.Ne=function(n,t){return b2(uG(n,240),uG(t,240))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"MultiLevelEdgeNodeNodeGap/lambda$1$Type",1944),sDn(501,22,{3:1,34:1,22:1,501:1,188:1,196:1},YI),uZn.dg=function(){return Fpn(this)},uZn.qg=function(){return Fpn(this)};var JCt,YCt,ZCt,nIt,tIt,eIt,iIt=_cn(h7n,"RadialLayoutPhases",501,Oat,p1,RH);sDn(1113,205,M3n,Uj),uZn.rf=function(n,t){var e,i,r,c;if(e=_Kn(this,n),t.Ug("Radial layout",e.c.length),oM(gK(zDn(n,(jOn(),RIt))))||J1(new Sd((vP(),new Vy(n)))),c=XPn(n),Myn(n,(SK(),zCt),c),!c)throw hv(new vM("The given graph is not a tree!"));for(0==(i=uM(pK(zDn(n,HIt))))&&(i=tNn(n)),Myn(n,HIt,i),r=new Ww(_Kn(this,n));r.a=3)for(v=uG(zrn(p,0),27),k=uG(zrn(p,1),27),r=0;r+2=v.f+k.f+u||k.f>=m.f+v.f+u){y=!0;break}++r}else y=!0;if(!y){for(h=p.i,c=new DD(p);c.e!=c.i.gc();)Myn(uG(Zkn(c),27),(XYn(),vDt),xwn(h)),--h;return XGn(n,new fy),void t.Vg()}for(_J(this.a),JV(this.a,(Jmn(),oOt),uG(zDn(n,mAt),188)),JV(this.a,uOt,uG(zDn(n,sAt),188)),JV(this.a,sOt,uG(zDn(n,dAt),188)),ZL(this.a,(Aq(T=new wJ,oOt,(Zyn(),wOt)),Aq(T,uOt,bOt),oM(gK(zDn(n,YOt)))&&Aq(T,oOt,lOt),T)),o=1/(i=Qzn(this.a,n)).c.length,l=new Ww(i);l.a0&&Qbn((s3(t-1,n.length),n.charCodeAt(t-1)),c6n);)--t;if(e>=t)throw hv(new vM("The given string does not contain any numbers."));if(2!=(i=WGn((Knn(e,t,n.length),n.substr(e,t-e)),",|;|\r|\n")).length)throw hv(new vM("Exactly two numbers are expected, "+i.length+" were found."));try{this.a=YIn(KAn(i[0])),this.b=YIn(KAn(i[1]))}catch(r){throw F$(r=Ehn(r),130)?hv(new vM(a6n+r)):hv(r)}},uZn.Ib=function(){return"("+this.a+","+this.b+")"},uZn.a=0,uZn.b=0;var PNt=zW(o6n,"KVector",8);sDn(75,67,{3:1,4:1,20:1,31:1,56:1,16:1,67:1,15:1,75:1,423:1},Uk,tj,UR),uZn.Pc=function(){return ibn(this)},uZn.cg=function(n){var t,e,i,r,c;e=WGn(n,",|;|\\(|\\)|\\[|\\]|\\{|\\}| |\t|\n"),BY(this);try{for(t=0,r=0,i=0,c=0;t0&&(r%2==0?i=YIn(e[t]):c=YIn(e[t]),r>0&&r%2!=0&&aq(this,new MO(i,c)),++r),++t}catch(a){throw F$(a=Ehn(a),130)?hv(new vM("The given string does not match the expected format for vectors."+a)):hv(a)}},uZn.Ib=function(){var n,t,e;for(n=new lx("("),t=Fkn(this,0);t.b!=t.d.c;)JA(n,(e=uG(I6(t),8)).a+","+e.b),t.b!=t.d.c&&(n.a+="; ");return(n.a+=")",n).a};var CNt,INt,ONt,ANt,LNt,NNt,$Nt=zW(o6n,"KVectorChain",75);sDn(255,22,{3:1,34:1,22:1,255:1},TO);var DNt,xNt,RNt,KNt,FNt,_Nt,BNt,HNt,UNt,GNt,qNt,XNt,zNt,VNt,WNt,QNt,JNt,YNt,ZNt,n$t=_cn(Unt,"Alignment",255,Oat,Ynn,oU);sDn(991,1,K2n,$l),uZn.hf=function(n){ZUn(n)},zW(Unt,"BoxLayouterOptions",991),sDn(992,1,{},Ru),uZn.sf=function(){return new _u},uZn.tf=function(n){},zW(Unt,"BoxLayouterOptions/BoxFactory",992),sDn(298,22,{3:1,34:1,22:1,298:1},SO);var t$t,e$t,i$t,r$t,c$t,a$t,o$t,u$t,s$t,h$t,f$t,l$t,b$t,w$t,d$t,g$t,p$t,m$t,v$t,k$t,y$t,M$t,T$t,j$t,E$t,S$t,P$t,C$t,I$t,O$t,A$t,L$t,N$t,$$t,D$t,x$t,R$t,K$t,F$t,_$t,B$t,H$t,U$t,G$t,q$t,X$t,z$t,V$t,W$t,Q$t,J$t,Y$t,Z$t,nDt,tDt,eDt,iDt,rDt,cDt,aDt,oDt,uDt,sDt,hDt,fDt,lDt,bDt,wDt,dDt,gDt,pDt,mDt,vDt,kDt,yDt,MDt,TDt,jDt,EDt,SDt,PDt,CDt,IDt,ODt,ADt,LDt,NDt,$Dt,DDt,xDt,RDt,KDt,FDt,_Dt,BDt,HDt,UDt,GDt,qDt,XDt,zDt,VDt,WDt,QDt,JDt,YDt,ZDt,nxt,txt=_cn(Unt,"ContentAlignment",298,Oat,Znn,uU);sDn(699,1,K2n,Dl),uZn.hf=function(n){Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,Vnt),""),"Layout Algorithm"),"Select a specific layout algorithm."),(lAn(),kNt)),$ot),ggn((Rkn(),hNt))))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,Wnt),""),"Resolved Layout Algorithm"),"Meta data associated with the selected algorithm."),vNt),aNt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,X8n),""),"Alignment"),"Alignment of the selected node relative to other nodes; the exact meaning depends on the used algorithm."),r$t),gNt),n$t),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,R3n),""),"Aspect Ratio"),"The desired aspect ratio of the drawing, that is the quotient of width by height."),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,Qnt),""),"Bend Points"),"A fixed list of bend points for the edge. This is used by the 'Fixed Layout' algorithm to specify a pre-defined routing for an edge. The vector chain must include the source point, any bend points, and the target point, so it must have at least two points."),vNt),$Nt),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,r9n),""),"Content Alignment"),"Specifies how the content of a node are aligned. Each node can individually control the alignment of its contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that option."),b$t),pNt),txt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,q8n),""),"Debug Mode"),"Whether additional debug information shall be generated."),(qx(),!1)),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,W8n),""),l3n),"Overall direction of edges: horizontal (right / left) or vertical (down / up)."),g$t),gNt),axt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,m8n),""),"Edge Routing"),"What kind of edge routing style should be applied for the content of a parent node. Algorithms may also set this option to single edges in order to mark them as splines. The bend point list of edges with this option set to SPLINES must be interpreted as control points for a piecewise cubic spline."),y$t),gNt),kxt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Xnt),""),"Expand Nodes"),"If active, nodes are expanded to fill the area of their parent."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,b8n),""),"Hierarchy Handling"),"Determines whether separate layout runs are triggered for different compound nodes in a hierarchical graph. Setting a node's hierarchy handling to `INCLUDE_CHILDREN` will lay out that node and all of its descendants in a single layout run, until a descendant is encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that setting. Including multiple levels of hierarchy in a single layout run may allow cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` (or not set at all), the default behavior is `SEPARATE_CHILDREN`."),S$t),gNt),Kxt),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[sNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,K3n),""),"Padding"),"The padding to be left to a parent element's border when placing child elements. This can also serve as an output option of a layout algorithm if node size calculation is setup appropriately."),Q$t),vNt),Sbt),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[sNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,f4n),""),"Interactive"),"Whether the algorithm should be run in interactive mode for the content of a parent node. What this means exactly depends on how the specific algorithm interprets this option. Usually in the interactive mode algorithms try to modify the current layout as little as possible."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,g9n),""),"interactive Layout"),"Whether the graph should be changeable interactively and by setting constraints"),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,w4n),""),"Omit Node Micro Layout"),"Node micro layout comprises the computation of node dimensions (if requested), the placement of ports and their labels, and the placement of node labels. The functionality is implemented independent of any specific layout algorithm and shouldn't have any negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, this option allows to deactivate the micro layout."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,l4n),""),"Port Constraints"),"Defines constraints of the position of the ports of a node."),hDt),gNt),mRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,b9n),""),"Position"),"The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to specify a pre-defined position."),vNt),PNt),WX(sNt,Uhn(cT(MNt,1),p1n,170,0,[fNt,uNt]))))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,a4n),""),"Priority"),"Defines the priority of an object; its meaning depends on the specific layout algorithm and the context where it is used."),mNt),dot),WX(sNt,Uhn(cT(MNt,1),p1n,170,0,[oNt]))))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,s4n),""),"Randomization Seed"),"Seed used for pseudo-random number generators to control the layout algorithm. If the value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time)."),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,h4n),""),"Separate Connected Components"),"Whether each connected component should be processed separately."),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,c9n),""),"Junction Points"),"This option is not used as option, but as output of the layout algorithms. It is attached to edges and determines the points where junction symbols should be drawn in order to represent hyperedges with orthogonal routing. Whether such points are computed depends on the chosen layout algorithm and edge routing style. The points are put into the vector chain with no specific order."),N$t),vNt),$Nt),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,u9n),""),"Comment Box"),"Whether the node should be regarded as a comment box instead of a regular node. In that case its placement should be similar to how labels are handled. Any edges incident to a comment box specify to which graph elements the comment is related."),!1),wNt),cot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,s9n),""),"Hypernode"),"Whether the node should be handled as a hypernode."),!1),wNt),cot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,Jnt),""),"Label Manager"),"Label managers can shorten labels upon a layout algorithm's request."),vNt),cUt),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[uNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,w9n),""),"Margins"),"Margins define additional space around the actual bounds of a graph element. For instance, ports or labels being placed on the outside of a node's border might introduce such a margin. The margin is used to guarantee non-overlap of other graph elements with those ports or labels."),D$t),vNt),hbt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,U8n),""),"No Layout"),"No layout is done for the associated element. This is used to mark parts of a diagram to avoid their inclusion in the layout graph, or to mark parts of the layout graph to prevent layout engines from processing them. If you wish to exclude the contents of a compound node from automatic layout, while the node itself is still considered on its own layer, use the 'Fixed Layout' algorithm for that node."),!1),wNt),cot),WX(sNt,Uhn(cT(MNt,1),p1n,170,0,[oNt,fNt,uNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Ynt),""),"Scale Factor"),"The scaling factor to be applied to the corresponding node in recursive layout. It causes the corresponding node's size to be adjusted, and its ports and labels to be sized and placed accordingly after the layout of that node has been determined (and before the node itself and its siblings are arranged). The scaling is not reverted afterwards, so the resulting layout graph contains the adjusted size and position data. This option is currently not supported if 'Layout Hierarchy' is set."),1),dNt),fot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,Znt),""),"Child Area Width"),"The width of the area occupied by the laid out children of a node."),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,ntt),""),"Child Area Height"),"The height of the area occupied by the laid out children of a node."),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,k4n),""),Lnt),"Turns topdown layout on and off. If this option is enabled, hierarchical layout will be computed first for the root node and then for its children recursively. Layouts are then scaled down to fit the area provided by their parents. Graphs must follow a certain structure for topdown layout to work properly. {@link TopdownNodeTypes.PARALLEL_NODE} nodes must have children of type {@link TopdownNodeTypes.HIERARCHICAL_NODE} and must define {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} for their children. Furthermore they need to be laid out using an algorithm that is a {@link TopdownLayoutProvider}. Hierarchical nodes can also be parents of other hierarchical nodes and can optionally use a {@link TopdownSizeApproximator} to dynamically set sizes during topdown layout. In this case {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} should be set on the node itself rather than the parent. The values are then used by the size approximator as base values. Hierarchical nodes require the layout option {@link nodeSize.fixedGraphSize} to be true to prevent the algorithm used there from resizing the hierarchical node. This option is not supported if 'Hierarchy Handling' is set to 'INCLUDE_CHILDREN'"),!1),wNt),cot),ggn(hNt)))),H4(n,k4n,j4n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,ttt),""),"Animate"),"Whether the shift from the old layout to the new computed layout shall be animated."),!0),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,ett),""),"Animation Time Factor"),"Factor for computation of animation time. The higher the value, the longer the animation time. If the value is 0, the resulting time is always equal to the minimum defined by 'Minimal Animation Time'."),xwn(100)),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,itt),""),"Layout Ancestors"),"Whether the hierarchy levels on the path from the selected element to the root of the diagram shall be included in the layout process."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,rtt),""),"Maximal Animation Time"),"The maximal time for animations, in milliseconds."),xwn(4e3)),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,ctt),""),"Minimal Animation Time"),"The minimal time for animations, in milliseconds."),xwn(400)),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,att),""),"Progress Bar"),"Whether a progress bar shall be displayed during layout computations."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,ott),""),"Validate Graph"),"Whether the graph shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,utt),""),"Validate Options"),"Whether layout options shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!0),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,stt),""),"Zoom to Fit"),"Whether the zoom level shall be set to view the whole diagram after layout."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,znt),"box"),"Box Layout Mode"),"Configures the packing mode used by the {@link BoxLayoutProvider}. If SIMPLE is not required (neither priorities are used nor the interactive mode), GROUP_DEC can improve the packing and decrease the area. GROUP_MIXED and GROUP_INC may, in very specific scenarios, work better."),u$t),gNt),SKt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,A8n),v8n),"Comment Comment Spacing"),"Spacing to be preserved between a comment box and other comment boxes connected to the same node. The space left between comment boxes of different nodes is controlled by the node-node spacing."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,L8n),v8n),"Comment Node Spacing"),"Spacing to be preserved between a node and its connected comment boxes. The space left between a node and the comments of another node is controlled by the node-node spacing."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,D3n),v8n),"Components Spacing"),"Spacing to be preserved between pairs of connected components. This option is only relevant if 'separateConnectedComponents' is activated."),20),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,N8n),v8n),"Edge Spacing"),"Spacing to be preserved between any two edges. Note that while this can somewhat easily be satisfied for the segments of orthogonally drawn edges, it is harder for general polylines or splines."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,u4n),v8n),"Edge Label Spacing"),"The minimal distance to be preserved between a label and the edge it is associated with. Note that the placement of a label is influenced by the 'edgelabels.placement' option."),2),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,$8n),v8n),"Edge Node Spacing"),"Spacing to be preserved between nodes and edges."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,D8n),v8n),"Label Spacing"),"Determines the amount of space to be left between two labels of the same graph element."),0),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,K8n),v8n),"Label Node Spacing"),"Spacing to be preserved between labels and the border of node they are associated with. Note that the placement of a label is influenced by the 'nodelabels.placement' option."),5),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,x8n),v8n),"Horizontal spacing between Label and Port"),"Horizontal spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,R8n),v8n),"Vertical spacing between Label and Port"),"Vertical spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,o4n),v8n),"Node Spacing"),"The minimal distance to be preserved between each two nodes."),20),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,F8n),v8n),"Node Self Loop Spacing"),"Spacing to be preserved between a node and its self loops."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,_8n),v8n),"Port Spacing"),"Spacing between pairs of ports of the same node."),10),dNt),fot),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[sNt]))))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,B8n),v8n),"Individual Spacing"),"Allows to specify individual spacing values for graph elements that shall be different from the value specified for the element's parent."),vNt),AKt),WX(sNt,Uhn(cT(MNt,1),p1n,170,0,[oNt,fNt,uNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,d9n),v8n),"Additional Port Space"),"Additional space around the sets of ports on each node side. For each side of a node, this option can reserve additional space before and after the ports on each side. For example, a top spacing of 20 makes sure that the first port on the western and eastern side is 20 units away from the northern border."),KDt),vNt),hbt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,l9n),dtt),"Layout Partition"),"Partition to which the node belongs. This requires Layout Partitioning to be active. Nodes with lower partition IDs will appear to the left of nodes with higher partition IDs (assuming a left-to-right layout direction)."),mNt),dot),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[sNt]))))),H4(n,l9n,f9n,nDt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,f9n),dtt),"Layout Partitioning"),"Whether to activate partitioned layout. This will allow to group nodes through the Layout Partition option. a pair of nodes with different partition indices is then placed such that the node with lower index is placed to the left of the other node (with left-to-right layout direction). Depending on the layout algorithm, this may only be guaranteed to work if all nodes have a layout partition configured, or at least if edges that cross partitions are not part of a partition-crossing cycle."),Y$t),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Q8n),gtt),"Node Label Padding"),"Define padding for node labels that are placed inside of a node."),R$t),vNt),Sbt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,m4n),gtt),"Node Label Placement"),"Hints for where node labels are to be placed; if empty, the node label's position is not modified."),F$t),pNt),eRt),WX(sNt,Uhn(cT(MNt,1),p1n,170,0,[uNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Z8n),ptt),"Port Alignment"),"Defines the default port distribution for a node. May be overridden for each side individually."),eDt),gNt),hRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,n9n),ptt),"Port Alignment (North)"),"Defines how ports on the northern side are placed, overriding the node's general port alignment."),gNt),hRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,t9n),ptt),"Port Alignment (South)"),"Defines how ports on the southern side are placed, overriding the node's general port alignment."),gNt),hRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,e9n),ptt),"Port Alignment (West)"),"Defines how ports on the western side are placed, overriding the node's general port alignment."),gNt),hRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,i9n),ptt),"Port Alignment (East)"),"Defines how ports on the eastern side are placed, overriding the node's general port alignment."),gNt),hRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,p4n),mtt),"Node Size Constraints"),"What should be taken into account when calculating a node's size. Empty size constraints specify that a node's size is already fixed and should not be changed."),B$t),pNt),sKt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,g4n),mtt),"Node Size Options"),"Options modifying the behavior of the size constraints set on a node. Each member of the set specifies something that should be taken into account when calculating node sizes. The empty set corresponds to no further modifications."),X$t),pNt),wKt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,x4n),mtt),"Node Size Minimum"),"The minimal size to which a node can be reduced."),G$t),vNt),PNt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,d4n),mtt),"Fixed Graph Size"),"By default, the fixed layout provider will enlarge a graph until it is large enough to contain its children. If this option is set, it won't do so."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,a9n),I8n),"Edge Label Placement"),"Gives a hint on where to put edge labels."),v$t),gNt),lxt),ggn(uNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,b4n),I8n),"Inline Edge Labels"),"If true, an edge label is placed directly on its edge. May only apply to center edge labels. This kind of label placement is only advisable if the label's rendering is such that it is not crossed by its edge and thus stays legible."),!1),wNt),cot),ggn(uNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,htt),"font"),"Font Name"),"Font name used for a label."),kNt),$ot),ggn(uNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,ftt),"font"),"Font Size"),"Font size used for a label."),mNt),dot),ggn(uNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,h9n),vtt),"Port Anchor Offset"),"The offset to the port position where connections shall be attached."),vNt),PNt),ggn(fNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,o9n),vtt),"Port Index"),"The index of a port in the fixed order around a node. The order is assumed as clockwise, starting with the leftmost port on the top side. This option must be set if 'Port Constraints' is set to FIXED_ORDER and no specific positions are given for the ports. Additionally, the option 'Port Side' must be defined in this case."),mNt),dot),ggn(fNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,G8n),vtt),"Port Side"),"The side of a node on which a port is situated. This option must be set if 'Port Constraints' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given for the ports."),pDt),gNt),YRt),ggn(fNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,H8n),vtt),"Port Border Offset"),"The offset of ports on the node border. With a positive offset the port is moved outside of the node, while with a negative offset the port is moved towards the inside. An offset of 0 means that the port is placed directly on the node border, i.e. if the port side is north, the port's south border touches the nodes's north border; if the port side is east, the port's west border touches the nodes's east border; if the port side is south, the port's north border touches the node's south border; if the port side is west, the port's east border touches the node's west border."),dNt),fot),ggn(fNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,v4n),ktt),"Port Label Placement"),"Decides on a placement method for port labels; if empty, the node label's position is not modified."),wDt),pNt),BRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,J8n),ktt),"Port Labels Next to Port"),"Use 'portLabels.placement': NEXT_TO_PORT_OF_POSSIBLE."),!1),wNt),cot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Y8n),ktt),"Treat Port Labels as Group"),"If this option is true (default), the labels of a port will be treated as a group when it comes to centering them next to their port. If this option is false, only the first label will be centered next to the port, with the others being placed below. This only applies to labels of eastern and western ports and will have no effect if labels are not placed next to their port."),!0),wNt),cot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,y4n),ytt),"Topdown Scale Factor"),"The scaling factor to be applied to the nodes laid out within the node in recursive topdown layout. The difference to 'Scale Factor' is that the node itself is not scaled. This value has to be set on hierarchical nodes."),1),dNt),fot),ggn(hNt)))),H4(n,y4n,j4n,zDt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,ltt),ytt),"Topdown Size Approximator"),"The size approximator to be used to set sizes of hierarchical nodes during topdown layout. The default value is null, which results in nodes keeping whatever size is defined for them e.g. through parent parallel node or by manually setting the size."),null),gNt),jKt),ggn(sNt)))),H4(n,ltt,j4n,WDt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,M4n),ytt),"Topdown Hierarchical Node Width"),"The fixed size of a hierarchical node when using topdown layout. If this value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to the node itself."),150),dNt),fot),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[sNt]))))),H4(n,M4n,j4n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,T4n),ytt),"Topdown Hierarchical Node Aspect Ratio"),"The fixed aspect ratio of a hierarchical node when using topdown layout. Default is 1/sqrt(2). If this value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to the node itself."),1.414),dNt),fot),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[sNt]))))),H4(n,T4n,j4n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,j4n),ytt),"Topdown Node Type"),"The different node types used for topdown layout. If the node type is set to {@link TopdownNodeTypes.PARALLEL_NODE} the algorithm must be set to a {@link TopdownLayoutProvider} such as {@link TopdownPacking}. The {@link nodeSize.fixedGraphSize} option is technically only required for hierarchical nodes."),null),gNt),mKt),ggn(sNt)))),H4(n,j4n,d4n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,btt),ytt),"Topdown Scale Cap"),"Determines the upper limit for the topdown scale factor. The default value is 1.0 which ensures that nested children never end up appearing larger than their parents in terms of unit sizes such as the font size. If the limit is larger, nodes will fully utilize the available space, but it is counteriniuitive for inner nodes to have a larger scale than outer nodes."),1),dNt),fot),ggn(hNt)))),H4(n,btt,j4n,qDt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,z8n),Mtt),"Activate Inside Self Loops"),"Whether this node allows to route self loops inside of it instead of around it. If set to true, this will make the node a compound node if it isn't already, and will require the layout algorithm to support compound nodes with hierarchical ports."),!1),wNt),cot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,V8n),Mtt),"Inside Self Loop"),"Whether a self loop should be routed inside a node instead of around that node."),!1),wNt),cot),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,x3n),"edge"),"Edge Thickness"),"The thickness of an edge. This is a hint on the line width used to draw an edge, possibly requiring more space to be reserved for it."),1),dNt),fot),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,wtt),"edge"),"Edge Type"),"The type of an edge. This is usually used for UML class diagrams, where associations must be handled differently from generalizations."),T$t),gNt),Lxt),ggn(oNt)))),sP(n,new I2(BT(UT(HT(new du,S0n),"Layered"),'The layer-based method was introduced by Sugiyama, Tagawa and Toda in 1981. It emphasizes the direction of edges by pointing as many edges as possible into the same direction. The nodes are arranged in layers, which are sometimes called "hierarchies", and then reordered such that the number of edge crossings is minimized. Afterwards, concrete coordinates are computed for the nodes and edge bend points.'))),sP(n,new I2(BT(UT(HT(new du,"org.eclipse.elk.orthogonal"),"Orthogonal"),'Orthogonal methods that follow the "topology-shape-metrics" approach by Batini, Nardelli and Tamassia \'86. The first phase determines the topology of the drawing by applying a planarization technique, which results in a planar representation of the graph. The orthogonal shape is computed in the second phase, which aims at minimizing the number of edge bends, and is called orthogonalization. The third phase leads to concrete coordinates for nodes and edge bend points by applying a compaction method, thus defining the metrics.'))),sP(n,new I2(BT(UT(HT(new du,c4n),"Force"),"Layout algorithms that follow physical analogies by simulating a system of attractive and repulsive forces. The first successful method of this kind was proposed by Eades in 1984."))),sP(n,new I2(BT(UT(HT(new du,"org.eclipse.elk.circle"),"Circle"),"Circular layout algorithms emphasize cycles or biconnected components of a graph by arranging them in circles. This is useful if a drawing is desired where such components are clearly grouped, or where cycles are shown as prominent OPTIONS of the graph."))),sP(n,new I2(BT(UT(HT(new du,a7n),"Tree"),"Specialized layout methods for trees, i.e. acyclic graphs. The regular structure of graphs that have no undirected cycles can be emphasized using an algorithm of this type."))),sP(n,new I2(BT(UT(HT(new du,"org.eclipse.elk.planar"),"Planar"),"Algorithms that require a planar or upward planar graph. Most of these algorithms are theoretically interesting, but not practically usable."))),sP(n,new I2(BT(UT(HT(new du,x7n),"Radial"),"Radial layout algorithms usually position the nodes of the graph on concentric circles."))),kHn((new xl,n)),ZUn((new $l,n)),A_n((new Rl,n))},zW(Unt,"CoreOptions",699),sDn(88,22,{3:1,34:1,22:1,88:1},PO);var ext,ixt,rxt,cxt,axt=_cn(Unt,l3n,88,Oat,H8,sU);sDn(278,22,{3:1,34:1,22:1,278:1},CO);var oxt,uxt,sxt,hxt,fxt,lxt=_cn(Unt,"EdgeLabelPlacement",278,Oat,y3,hU);sDn(223,22,{3:1,34:1,22:1,223:1},IO);var bxt,wxt,dxt,gxt,pxt,mxt,vxt,kxt=_cn(Unt,"EdgeRouting",223,Oat,u5,fU);sDn(321,22,{3:1,34:1,22:1,321:1},OO);var yxt,Mxt,Txt,jxt,Ext,Sxt,Pxt,Cxt,Ixt,Oxt,Axt,Lxt=_cn(Unt,"EdgeType",321,Oat,Jnn,lU);sDn(989,1,K2n,xl),uZn.hf=function(n){kHn(n)},zW(Unt,"FixedLayouterOptions",989),sDn(990,1,{},Ku),uZn.sf=function(){return new Wu},uZn.tf=function(n){},zW(Unt,"FixedLayouterOptions/FixedFactory",990),sDn(346,22,{3:1,34:1,22:1,346:1},AO);var Nxt,$xt,Dxt,xxt,Rxt,Kxt=_cn(Unt,"HierarchyHandling",346,Oat,v3,bU);sDn(291,22,{3:1,34:1,22:1,291:1},LO);var Fxt,_xt,Bxt,Hxt,Uxt,Gxt,qxt,Xxt,zxt,Vxt,Wxt=_cn(Unt,"LabelSide",291,Oat,o5,wU);sDn(95,22,{3:1,34:1,22:1,95:1},NO);var Qxt,Jxt,Yxt,Zxt,nRt,tRt,eRt=_cn(Unt,"NodeLabelPlacement",95,Oat,bcn,dU);sDn(256,22,{3:1,34:1,22:1,256:1},$O);var iRt,rRt,cRt,aRt,oRt,uRt,sRt,hRt=_cn(Unt,"PortAlignment",256,Oat,p9,gU);sDn(101,22,{3:1,34:1,22:1,101:1},DO);var fRt,lRt,bRt,wRt,dRt,gRt,pRt,mRt=_cn(Unt,"PortConstraints",101,Oat,Qnn,pU);sDn(279,22,{3:1,34:1,22:1,279:1},xO);var vRt,kRt,yRt,MRt,TRt,jRt,ERt,SRt,PRt,CRt,IRt,ORt,ARt,LRt,NRt,$Rt,DRt,xRt,RRt,KRt,FRt,_Rt,BRt=_cn(Unt,"PortLabelPlacement",279,Oat,Wnn,mU);sDn(64,22,{3:1,34:1,22:1,64:1},RO);var HRt,URt,GRt,qRt,XRt,zRt,VRt,WRt,QRt,JRt,YRt=_cn(Unt,"PortSide",64,Oat,U8,vU);sDn(993,1,K2n,Rl),uZn.hf=function(n){A_n(n)},zW(Unt,"RandomLayouterOptions",993),sDn(994,1,{},Fu),uZn.sf=function(){return new Xu},uZn.tf=function(n){},zW(Unt,"RandomLayouterOptions/RandomFactory",994),sDn(386,22,{3:1,34:1,22:1,386:1},KO);var ZRt,nKt,tKt,eKt,iKt,rKt,cKt,aKt,oKt,uKt,sKt=_cn(Unt,"SizeConstraint",386,Oat,a5,kU);sDn(264,22,{3:1,34:1,22:1,264:1},FO);var hKt,fKt,lKt,bKt,wKt=_cn(Unt,"SizeOptions",264,Oat,Man,yU);sDn(280,22,{3:1,34:1,22:1,280:1},_O);var dKt,gKt,pKt,mKt=_cn(Unt,"TopdownNodeTypes",280,Oat,M3,MU);sDn(347,22,Ett);var vKt,kKt,yKt,MKt,TKt,jKt=_cn(Unt,"TopdownSizeApproximator",347,Oat,I1,jU);sDn(987,347,Ett,Pq),uZn.Tg=function(n){return sMn(n)},_cn(Unt,"TopdownSizeApproximator/1",987,jKt,null,null),sDn(988,347,Ett,gV),uZn.Tg=function(n){var t,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k;for(t=uG(zDn(n,(XYn(),yDt)),143),gj(),aKn(p=new Bk,n),m=new Ym,a=new DD((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a));a.e!=a.i.gc();)r=uG(Zkn(a),27),GRn(b=new Bk,p),aKn(b,r),k=sMn(r),vN(b,e.Math.max(r.g,k.a),e.Math.max(r.f,k.b)),VAn(m.f,r,b);for(c=new DD((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a));c.e!=c.i.gc();)for(s=new DD((!(r=uG(Zkn(c),27)).e&&(r.e=new f_(aFt,r,7,4)),r.e));s.e!=s.i.gc();)u=uG(Zkn(s),74),d=uG(DA(FX(m.f,r)),27),g=uG(cQ(m,zrn((!u.c&&(u.c=new f_(cFt,u,5,8)),u.c),0)),27),ttn((!(w=new es).b&&(w.b=new f_(cFt,w,4,7)),w.b),d),ttn((!w.c&&(w.c=new f_(cFt,w,5,8)),w.c),g),ARn(w,R0(d)),aKn(w,u);h=uG(A1(t.f),205);try{h.rf(p,new Zu),WQ(t.f,h)}catch(y){throw F$(y=Ehn(y),103),hv(y)}return vnn(p,h$t)||vnn(p,s$t)||VJn(p),o=uM(pK(zDn(p,h$t)))/uM(pK(zDn(p,s$t))),i=uM(pK(zDn(p,BDt)))*e.Math.sqrt((!p.a&&(p.a=new fV(bFt,p,10,11)),p.a).i),l=(v=uG(zDn(p,W$t),107)).b+v.c+1,f=v.d+v.a+1,new MO(e.Math.max(l,i),e.Math.max(f,i/o))},_cn(Unt,"TopdownSizeApproximator/2",988,jKt,null,null),sDn(344,1,{871:1},fy),uZn.Ug=function(n,t){return dCn(this,n,t)},uZn.Vg=function(){POn(this)},uZn.Wg=function(){return this.q},uZn.Xg=function(){return this.f?SZ(this.f):null},uZn.Yg=function(){return SZ(this.a)},uZn.Zg=function(){return this.p},uZn.$g=function(){return!1},uZn._g=function(){return this.n},uZn.ah=function(){return null!=this.p&&!this.b},uZn.bh=function(n){var t;this.n&&(t=n,kD(this.f,t))},uZn.dh=function(n,t){var e,i;this.n&&n&&n4(this,(i=uUn(e=new DW,n),_Wn(e),i),(Eln(),CKt))},uZn.eh=function(n){var t;return this.b?null:(t=irn(this,this.g),aq(this.a,t),t.i=this,this.d=n,t)},uZn.fh=function(n){n>0&&!this.b&&Ban(this,n)},uZn.b=!1,uZn.c=0,uZn.d=-1,uZn.e=null,uZn.f=null,uZn.g=-1,uZn.j=!1,uZn.k=!1,uZn.n=!1,uZn.o=0,uZn.q=0,uZn.r=0,zW(p9n,"BasicProgressMonitor",344),sDn(717,205,M3n,_u),uZn.rf=function(n,t){XGn(n,t)},zW(p9n,"BoxLayoutProvider",717),sDn(983,1,b2n,qp),uZn.Ne=function(n,t){return tKn(this,uG(n,27),uG(t,27))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},uZn.a=!1,zW(p9n,"BoxLayoutProvider/1",983),sDn(163,1,{163:1},Jrn,nK),uZn.Ib=function(){return this.c?zBn(this.c):vIn(this.b)},zW(p9n,"BoxLayoutProvider/Group",163),sDn(320,22,{3:1,34:1,22:1,320:1},HO);var EKt,SKt=_cn(p9n,"BoxLayoutProvider/PackingMode",320,Oat,s5,EU);sDn(984,1,b2n,Bu),uZn.Ne=function(n,t){return rZ(uG(n,163),uG(t,163))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(p9n,"BoxLayoutProvider/lambda$0$Type",984),sDn(985,1,b2n,Hu),uZn.Ne=function(n,t){return GY(uG(n,163),uG(t,163))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(p9n,"BoxLayoutProvider/lambda$1$Type",985),sDn(986,1,b2n,Uu),uZn.Ne=function(n,t){return qY(uG(n,163),uG(t,163))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(p9n,"BoxLayoutProvider/lambda$2$Type",986),sDn(1384,1,{845:1},Gu),uZn.Mg=function(n,t){return ZS(),!F$(t,167)||Zj((Whn(),uG(n,167)),t)},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$0$Type",1384),sDn(1385,1,QZn,Xp),uZn.Cd=function(n){hbn(this.a,uG(n,149))},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$1$Type",1385),sDn(1386,1,QZn,zu),uZn.Cd=function(n){uG(n,96),ZS()},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$2$Type",1386),sDn(1390,1,QZn,zp),uZn.Cd=function(n){_on(this.a,uG(n,96))},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$3$Type",1390),sDn(1388,1,y1n,UO),uZn.Mb=function(n){return oln(this.a,this.b,uG(n,149))},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$4$Type",1388),sDn(1387,1,y1n,GO),uZn.Mb=function(n){return PR(this.a,this.b,uG(n,845))},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$5$Type",1387),sDn(1389,1,QZn,qO),uZn.Cd=function(n){iV(this.a,this.b,uG(n,149))},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$6$Type",1389),sDn(947,1,{},Vu),uZn.Kb=function(n){return oN(n)},uZn.Fb=function(n){return this===n},zW(p9n,"ElkUtil/lambda$0$Type",947),sDn(948,1,QZn,XO),uZn.Cd=function(n){JNn(this.a,this.b,uG(n,74))},uZn.a=0,uZn.b=0,zW(p9n,"ElkUtil/lambda$1$Type",948),sDn(949,1,QZn,zO),uZn.Cd=function(n){tM(this.a,this.b,uG(n,166))},uZn.a=0,uZn.b=0,zW(p9n,"ElkUtil/lambda$2$Type",949),sDn(950,1,QZn,VO),uZn.Cd=function(n){UN(this.a,this.b,uG(n,135))},uZn.a=0,uZn.b=0,zW(p9n,"ElkUtil/lambda$3$Type",950),sDn(951,1,QZn,Vp),uZn.Cd=function(n){Lq(this.a,uG(n,377))},zW(p9n,"ElkUtil/lambda$4$Type",951),sDn(325,1,{34:1,325:1},Jm),uZn.Fd=function(n){return wD(this,uG(n,242))},uZn.Fb=function(n){var t;return!!F$(n,325)&&(t=uG(n,325),this.a==t.a)},uZn.Hb=function(){return t0(this.a)},uZn.Ib=function(){return this.a+" (exclusive)"},uZn.a=0,zW(p9n,"ExclusiveBounds/ExclusiveLowerBound",325),sDn(1119,205,M3n,Wu),uZn.rf=function(n,t){var i,r,c,a,o,u,s,f,l,b,w,d,g,p,m,v,k,y,M,T,j;for(t.Ug("Fixed Layout",1),a=uG(zDn(n,(XYn(),k$t)),223),b=0,w=0,m=new DD((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a));m.e!=m.i.gc();){for(g=uG(Zkn(m),27),(j=uG(zDn(g,(Iln(),Cxt)),8))&&(kN(g,j.a,j.b),uG(zDn(g,Txt),181).Hc((Qmn(),VRt))&&(d=uG(zDn(g,Ext),8)).a>0&&d.b>0&&ZQn(g,d.a,d.b,!0,!0)),b=e.Math.max(b,g.i+g.g),w=e.Math.max(w,g.j+g.f),f=new DD((!g.n&&(g.n=new fV(lFt,g,1,7)),g.n));f.e!=f.i.gc();)u=uG(Zkn(f),135),(j=uG(zDn(u,Cxt),8))&&kN(u,j.a,j.b),b=e.Math.max(b,g.i+u.i+u.g),w=e.Math.max(w,g.j+u.j+u.f);for(y=new DD((!g.c&&(g.c=new fV(wFt,g,9,9)),g.c));y.e!=y.i.gc();)for(k=uG(Zkn(y),123),(j=uG(zDn(k,Cxt),8))&&kN(k,j.a,j.b),M=g.i+k.i,T=g.j+k.j,b=e.Math.max(b,M+k.g),w=e.Math.max(w,T+k.f),s=new DD((!k.n&&(k.n=new fV(lFt,k,1,7)),k.n));s.e!=s.i.gc();)u=uG(Zkn(s),135),(j=uG(zDn(u,Cxt),8))&&kN(u,j.a,j.b),b=e.Math.max(b,M+u.i+u.g),w=e.Math.max(w,T+u.j+u.f);for(c=new Fz(ix(eRn(g).a.Kc(),new h));hDn(c);)l=iJn(i=uG(N9(c),74)),b=e.Math.max(b,l.a),w=e.Math.max(w,l.b);for(r=new Fz(ix(tRn(g).a.Kc(),new h));hDn(r);)R0(bIn(i=uG(N9(r),74)))!=n&&(l=iJn(i),b=e.Math.max(b,l.a),w=e.Math.max(w,l.b))}if(a==(_gn(),uxt))for(p=new DD((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a));p.e!=p.i.gc();)for(r=new Fz(ix(eRn(g=uG(Zkn(p),27)).a.Kc(),new h));hDn(r);)0==(o=bGn(i=uG(N9(r),74))).b?Myn(i,L$t,null):Myn(i,L$t,o);oM(gK(zDn(n,(Iln(),jxt))))||ZQn(n,b+(v=uG(zDn(n,Sxt),107)).b+v.c,w+v.d+v.a,!0,!0),t.Vg()},zW(p9n,"FixedLayoutProvider",1119),sDn(385,137,{3:1,423:1,385:1,96:1,137:1},Qu,qen),uZn.cg=function(n){var t,e,i,r,c,a,o;if(n)try{for(a=WGn(n,";,;"),r=0,c=(i=a).length;r>16&D1n|n^(e&D1n)<<16},uZn.Kc=function(){return new Wp(this)},uZn.Ib=function(){return null==this.a&&null==this.b?"pair(null,null)":null==this.a?"pair(null,"+cpn(this.b)+")":null==this.b?"pair("+cpn(this.a)+",null)":"pair("+cpn(this.a)+","+cpn(this.b)+")"},zW(p9n,"Pair",42),sDn(995,1,$Zn,Wp),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return!this.c&&(!this.b&&null!=this.a.a||null!=this.a.b)},uZn.Pb=function(){if(!this.c&&!this.b&&null!=this.a.a)return this.b=!0,this.a.a;if(!this.c&&null!=this.a.b)return this.c=!0,this.a.b;throw hv(new Bv)},uZn.Qb=function(){throw this.c&&null!=this.a.b?this.a.b=null:this.b&&null!=this.a.a&&(this.a.a=null),hv(new xv)},uZn.b=!1,uZn.c=!1,zW(p9n,"Pair/1",995),sDn(455,1,{455:1},vY),uZn.Fb=function(n){return OJ(this.a,uG(n,455).a)&&OJ(this.c,uG(n,455).c)&&OJ(this.d,uG(n,455).d)&&OJ(this.b,uG(n,455).b)},uZn.Hb=function(){return Obn(Uhn(cT(dat,1),EZn,1,5,[this.a,this.c,this.d,this.b]))},uZn.Ib=function(){return"("+this.a+TZn+this.c+TZn+this.d+TZn+this.b+")"},zW(p9n,"Quadruple",455),sDn(1108,205,M3n,Xu),uZn.rf=function(n,t){var e;t.Ug("Random Layout",1),0!=(!n.a&&(n.a=new fV(bFt,n,10,11)),n.a).i?(vQn(n,(e=uG(zDn(n,(Wmn(),XRt)),17))&&0!=e.a?new v8(e.a):new Upn,sM(pK(zDn(n,URt))),sM(pK(zDn(n,zRt))),uG(zDn(n,GRt),107)),t.Vg()):t.Vg()},zW(p9n,"RandomLayoutProvider",1108),sDn(240,1,{240:1},LU),uZn.Fb=function(n){return OJ(this.a,uG(n,240).a)&&OJ(this.b,uG(n,240).b)&&OJ(this.c,uG(n,240).c)},uZn.Hb=function(){return Obn(Uhn(cT(dat,1),EZn,1,5,[this.a,this.b,this.c]))},uZn.Ib=function(){return"("+this.a+TZn+this.b+TZn+this.c+")"},zW(p9n,"Triple",240),sDn(562,1,{}),uZn.Lf=function(){return new MO(this.f.i,this.f.j)},uZn.of=function(n){return QZ(n,(XYn(),uDt))?zDn(this.f,$Kt):zDn(this.f,n)},uZn.Mf=function(){return new MO(this.f.g,this.f.f)},uZn.Nf=function(){return this.g},uZn.pf=function(n){return vnn(this.f,n)},uZn.Of=function(n){ycn(this.f,n.a),Mcn(this.f,n.b)},uZn.Pf=function(n){kcn(this.f,n.a),vcn(this.f,n.b)},uZn.Qf=function(n){this.g=n},uZn.g=0,zW(Ctt,"ElkGraphAdapters/AbstractElkGraphElementAdapter",562),sDn(563,1,{853:1},Qp),uZn.Rf=function(){var n,t;if(!this.b)for(this.b=o6(xJ(this.a).i),t=new DD(xJ(this.a));t.e!=t.i.gc();)n=uG(Zkn(t),135),kD(this.b,new Wy(n));return this.b},uZn.b=null,zW(Ctt,"ElkGraphAdapters/ElkEdgeAdapter",563),sDn(289,562,{},Vy),uZn.Sf=function(){return FTn(this)},uZn.a=null,zW(Ctt,"ElkGraphAdapters/ElkGraphAdapter",289),sDn(640,562,{187:1},Wy),zW(Ctt,"ElkGraphAdapters/ElkLabelAdapter",640),sDn(639,562,{695:1},Wx),uZn.Rf=function(){return RTn(this)},uZn.Vf=function(){var n;return!(n=uG(zDn(this.f,(XYn(),$$t)),140))&&(n=new Nk),n},uZn.Xf=function(){return KTn(this)},uZn.Zf=function(n){var t;t=new zU(n),Myn(this.f,(XYn(),$$t),t)},uZn.$f=function(n){Myn(this.f,(XYn(),W$t),new VU(n))},uZn.Tf=function(){return this.d},uZn.Uf=function(){var n,t;if(!this.a)for(this.a=new Zm,t=new Fz(ix(tRn(uG(this.f,27)).a.Kc(),new h));hDn(t);)n=uG(N9(t),74),kD(this.a,new Qp(n));return this.a},uZn.Wf=function(){var n,t;if(!this.c)for(this.c=new Zm,t=new Fz(ix(eRn(uG(this.f,27)).a.Kc(),new h));hDn(t);)n=uG(N9(t),74),kD(this.c,new Qp(n));return this.c},uZn.Yf=function(){return 0!=wZ(uG(this.f,27)).i||oM(gK(uG(this.f,27).of((XYn(),C$t))))},uZn._f=function(){Xen(this,(vP(),NKt))},uZn.a=null,uZn.b=null,uZn.c=null,uZn.d=null,uZn.e=null,zW(Ctt,"ElkGraphAdapters/ElkNodeAdapter",639),sDn(1284,562,{852:1},Jp),uZn.Rf=function(){return rjn(this)},uZn.Uf=function(){var n,t;if(!this.a)for(this.a=iR(uG(this.f,123).hh().i),t=new DD(uG(this.f,123).hh());t.e!=t.i.gc();)n=uG(Zkn(t),74),kD(this.a,new Qp(n));return this.a},uZn.Wf=function(){var n,t;if(!this.c)for(this.c=iR(uG(this.f,123).ih().i),t=new DD(uG(this.f,123).ih());t.e!=t.i.gc();)n=uG(Zkn(t),74),kD(this.c,new Qp(n));return this.c},uZn.ag=function(){return uG(uG(this.f,123).of((XYn(),gDt)),64)},uZn.bg=function(){var n,t,e,i,r,c,a;for(i=h0(uG(this.f,123)),e=new DD(uG(this.f,123).ih());e.e!=e.i.gc();)for(a=new DD((!(n=uG(Zkn(e),74)).c&&(n.c=new f_(cFt,n,5,8)),n.c));a.e!=a.i.gc();){if(Ern(lCn(c=uG(Zkn(a),84)),i))return!0;if(lCn(c)==i&&oM(gK(zDn(n,(XYn(),I$t)))))return!0}for(t=new DD(uG(this.f,123).hh());t.e!=t.i.gc();)for(r=new DD((!(n=uG(Zkn(t),74)).b&&(n.b=new f_(cFt,n,4,7)),n.b));r.e!=r.i.gc();)if(Ern(lCn(uG(Zkn(r),84)),i))return!0;return!1},uZn.a=null,uZn.b=null,uZn.c=null,zW(Ctt,"ElkGraphAdapters/ElkPortAdapter",1284),sDn(1285,1,b2n,qu),uZn.Ne=function(n,t){return XBn(uG(n,123),uG(t,123))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(Ctt,"ElkGraphAdapters/PortComparator",1285);var xKt,RKt,KKt,FKt,_Kt,BKt,HKt,UKt,GKt,qKt,XKt,zKt,VKt,WKt,QKt,JKt,YKt,ZKt,nFt=Iq(Itt,"EObject"),tFt=Iq(Ott,Att),eFt=Iq(Ott,Ltt),iFt=Iq(Ott,Ntt),rFt=Iq(Ott,"ElkShape"),cFt=Iq(Ott,$tt),aFt=Iq(Ott,Dtt),oFt=Iq(Ott,xtt),uFt=Iq(Itt,Rtt),sFt=Iq(Itt,"EFactory"),hFt=Iq(Itt,Ktt),fFt=Iq(Itt,"EPackage"),lFt=Iq(Ott,Ftt),bFt=Iq(Ott,_tt),wFt=Iq(Ott,Btt);sDn(93,1,Htt),uZn.th=function(){return this.uh(),null},uZn.uh=function(){return null},uZn.vh=function(){return this.uh(),!1},uZn.wh=function(){return!1},uZn.xh=function(n){Msn(this,n)},zW(Utt,"BasicNotifierImpl",93),sDn(99,93,Jtt),uZn.Yh=function(){return uN(this)},uZn.yh=function(n,t){return n},uZn.zh=function(){throw hv(new Kv)},uZn.Ah=function(n){var t;return t=lMn(uG(ern(this.Dh(),this.Fh()),19)),this.Ph().Th(this,t.n,t.f,n)},uZn.Bh=function(n,t){throw hv(new Kv)},uZn.Ch=function(n,t,e){return DUn(this,n,t,e)},uZn.Dh=function(){var n;return this.zh()&&(n=this.zh().Nk())?n:this.ii()},uZn.Eh=function(){return J$n(this)},uZn.Fh=function(){throw hv(new Kv)},uZn.Gh=function(){var n,t;return!(t=this.$h().Ok())&&this.zh().Tk((jP(),t=null==(n=$1(eqn(this.Dh())))?tBt:new zx(this,n))),t},uZn.Hh=function(n,t){return n},uZn.Ih=function(n){return n.pk()?n.Lj():emn(this.Dh(),n)},uZn.Jh=function(){var n;return(n=this.zh())?n.Qk():null},uZn.Kh=function(){return this.zh()?this.zh().Nk():null},uZn.Lh=function(n,t,e){return Dyn(this,n,t,e)},uZn.Mh=function(n){return vtn(this,n)},uZn.Nh=function(n,t){return U9(this,n,t)},uZn.Oh=function(){var n;return!!(n=this.zh())&&n.Rk()},uZn.Ph=function(){throw hv(new Kv)},uZn.Qh=function(){return Kvn(this)},uZn.Rh=function(n,t,e,i){return kyn(this,n,t,i)},uZn.Sh=function(n,t,e){return uG(ern(this.Dh(),t),69).wk().zk(this,this.hi(),t-this.ji(),n,e)},uZn.Th=function(n,t,e,i){return O1(this,n,t,i)},uZn.Uh=function(n,t,e){return uG(ern(this.Dh(),t),69).wk().Ak(this,this.hi(),t-this.ji(),n,e)},uZn.Vh=function(){return!!this.zh()&&!!this.zh().Pk()},uZn.Wh=function(n){return Wkn(this,n)},uZn.Xh=function(n){return M0(this,n)},uZn.Zh=function(n){return jWn(this,n)},uZn.$h=function(){throw hv(new Kv)},uZn._h=function(){return this.zh()?this.zh().Pk():null},uZn.ai=function(){return Kvn(this)},uZn.bi=function(n,t){sLn(this,n,t)},uZn.ci=function(n){this.$h().Sk(n)},uZn.di=function(n){this.$h().Vk(n)},uZn.ei=function(n){this.$h().Uk(n)},uZn.fi=function(n,t){var e,i,r,c;return(c=this.Jh())&&n&&(t=Nyn(c.El(),this,t),c.Il(this)),(i=this.Ph())&&(PHn(this,this.Ph(),this.Fh()).Bb&P0n?(r=i.Qh())&&(n?!c&&r.Il(this):r.Hl(this)):(t=(e=this.Fh())>=0?this.Ah(t):this.Ph().Th(this,-1-e,null,t),t=this.Ch(null,-1,t))),this.di(n),t},uZn.gi=function(n){var t,e,i,r,c,a,o;if((c=emn(e=this.Dh(),n))>=(t=this.ji()))return uG(n,69).wk().Dk(this,this.hi(),c-t);if(c<=-1){if(!(a=iVn((gAn(),kBt),e,n)))throw hv(new vM(Gtt+n.xe()+ztt));if(PP(),uG(a,69).xk()||(a=_3(Nen(kBt,a))),r=uG((i=this.Ih(a))>=0?this.Lh(i,!0,!0):YNn(this,a,!0),160),(o=a.Ik())>1||-1==o)return uG(uG(r,220).Sl(n,!1),79)}else if(n.Jk())return uG((i=this.Ih(n))>=0?this.Lh(i,!1,!0):YNn(this,n,!1),79);return new jA(this,n)},uZn.hi=function(){return Wen(this)},uZn.ii=function(){return(tQ(),M_t).S},uZn.ji=function(){return iQ(this.ii())},uZn.ki=function(n){oAn(this,n)},uZn.Ib=function(){return vxn(this)},zW(Ytt,"BasicEObjectImpl",99),sDn(119,99,{110:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1}),uZn.li=function(n){return Ven(this)[n]},uZn.mi=function(n,t){uQ(Ven(this),n,t)},uZn.ni=function(n){uQ(Ven(this),n,null)},uZn.th=function(){return uG(Lsn(this,4),129)},uZn.uh=function(){throw hv(new Kv)},uZn.vh=function(){return!!(4&this.Db)},uZn.zh=function(){throw hv(new Kv)},uZn.oi=function(n){Dvn(this,2,n)},uZn.Bh=function(n,t){this.Db=t<<16|255&this.Db,this.oi(n)},uZn.Dh=function(){return e1(this)},uZn.Fh=function(){return this.Db>>16},uZn.Gh=function(){var n;return jP(),null==(n=$1(eqn(uG(Lsn(this,16),29)||this.ii())))?tBt:new zx(this,n)},uZn.wh=function(){return!(1&this.Db)},uZn.Jh=function(){return uG(Lsn(this,128),2034)},uZn.Kh=function(){return uG(Lsn(this,16),29)},uZn.Oh=function(){return!!(32&this.Db)},uZn.Ph=function(){return uG(Lsn(this,2),54)},uZn.Vh=function(){return!!(64&this.Db)},uZn.$h=function(){throw hv(new Kv)},uZn._h=function(){return uG(Lsn(this,64),288)},uZn.ci=function(n){Dvn(this,16,n)},uZn.di=function(n){Dvn(this,128,n)},uZn.ei=function(n){Dvn(this,64,n)},uZn.hi=function(){return $vn(this)},uZn.Db=0,zW(Ytt,"MinimalEObjectImpl",119),sDn(120,119,{110:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),uZn.oi=function(n){this.Cb=n},uZn.Ph=function(){return this.Cb},zW(Ytt,"MinimalEObjectImpl/Container",120),sDn(2083,120,{110:1,342:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),uZn.Lh=function(n,t,e){return ajn(this,n,t,e)},uZn.Uh=function(n,t,e){return BIn(this,n,t,e)},uZn.Wh=function(n){return j4(this,n)},uZn.bi=function(n,t){bln(this,n,t)},uZn.ii=function(){return tYn(),VKt},uZn.ki=function(n){ffn(this,n)},uZn.nf=function(){return Qkn(this)},uZn.gh=function(){return!this.o&&(this.o=new ltn((tYn(),XKt),EFt,this,0)),this.o},uZn.of=function(n){return zDn(this,n)},uZn.pf=function(n){return vnn(this,n)},uZn.qf=function(n,t){return Myn(this,n,t)},zW(Ztt,"EMapPropertyHolderImpl",2083),sDn(572,120,{110:1,377:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},ns),uZn.Lh=function(n,t,e){switch(n){case 0:return this.a;case 1:return this.b}return Dyn(this,n,t,e)},uZn.Wh=function(n){switch(n){case 0:return 0!=this.a;case 1:return 0!=this.b}return Wkn(this,n)},uZn.bi=function(n,t){switch(n){case 0:return void Scn(this,uM(pK(t)));case 1:return void pcn(this,uM(pK(t)))}sLn(this,n,t)},uZn.ii=function(){return tYn(),KKt},uZn.ki=function(n){switch(n){case 0:return void Scn(this,0);case 1:return void pcn(this,0)}oAn(this,n)},uZn.Ib=function(){var n;return 64&this.Db?vxn(this):((n=new fx(vxn(this))).a+=" (x: ",Oj(n,this.a),n.a+=", y: ",Oj(n,this.b),n.a+=")",n.a)},uZn.a=0,uZn.b=0,zW(Ztt,"ElkBendPointImpl",572),sDn(739,2083,{110:1,342:1,167:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),uZn.Lh=function(n,t,e){return Xdn(this,n,t,e)},uZn.Sh=function(n,t,e){return SCn(this,n,t,e)},uZn.Uh=function(n,t,e){return phn(this,n,t,e)},uZn.Wh=function(n){return _sn(this,n)},uZn.bi=function(n,t){CSn(this,n,t)},uZn.ii=function(){return tYn(),HKt},uZn.ki=function(n){Awn(this,n)},uZn.jh=function(){return this.k},uZn.kh=function(){return xJ(this)},uZn.Ib=function(){return Egn(this)},uZn.k=null,zW(Ztt,"ElkGraphElementImpl",739),sDn(740,739,{110:1,342:1,167:1,422:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),uZn.Lh=function(n,t,e){return spn(this,n,t,e)},uZn.Wh=function(n){return Kpn(this,n)},uZn.bi=function(n,t){ISn(this,n,t)},uZn.ii=function(){return tYn(),zKt},uZn.ki=function(n){Tmn(this,n)},uZn.lh=function(){return this.f},uZn.mh=function(){return this.g},uZn.nh=function(){return this.i},uZn.oh=function(){return this.j},uZn.ph=function(n,t){vN(this,n,t)},uZn.qh=function(n,t){kN(this,n,t)},uZn.rh=function(n){ycn(this,n)},uZn.sh=function(n){Mcn(this,n)},uZn.Ib=function(){return rOn(this)},uZn.f=0,uZn.g=0,uZn.i=0,uZn.j=0,zW(Ztt,"ElkShapeImpl",740),sDn(741,740,{110:1,342:1,84:1,167:1,422:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),uZn.Lh=function(n,t,e){return SMn(this,n,t,e)},uZn.Sh=function(n,t,e){return tSn(this,n,t,e)},uZn.Uh=function(n,t,e){return eSn(this,n,t,e)},uZn.Wh=function(n){return iln(this,n)},uZn.bi=function(n,t){SDn(this,n,t)},uZn.ii=function(){return tYn(),FKt},uZn.ki=function(n){yyn(this,n)},uZn.hh=function(){return!this.d&&(this.d=new f_(aFt,this,8,5)),this.d},uZn.ih=function(){return!this.e&&(this.e=new f_(aFt,this,7,4)),this.e},zW(Ztt,"ElkConnectableShapeImpl",741),sDn(326,739,{110:1,342:1,74:1,167:1,326:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},es),uZn.Ah=function(n){return sEn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 3:return s0(this);case 4:return!this.b&&(this.b=new f_(cFt,this,4,7)),this.b;case 5:return!this.c&&(this.c=new f_(cFt,this,5,8)),this.c;case 6:return!this.a&&(this.a=new fV(oFt,this,6,6)),this.a;case 7:return qx(),!this.b&&(this.b=new f_(cFt,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new f_(cFt,this,5,8)),this.c.i<=1));case 8:return qx(),!!z$n(this);case 9:return qx(),!!BNn(this);case 10:return qx(),!this.b&&(this.b=new f_(cFt,this,4,7)),0!=this.b.i&&(!this.c&&(this.c=new f_(cFt,this,5,8)),0!=this.c.i)}return Xdn(this,n,t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 3:return this.Cb&&(e=(i=this.Db>>16)>=0?sEn(this,e):this.Cb.Th(this,-1-i,null,e)),nF(this,uG(n,27),e);case 4:return!this.b&&(this.b=new f_(cFt,this,4,7)),Nmn(this.b,n,e);case 5:return!this.c&&(this.c=new f_(cFt,this,5,8)),Nmn(this.c,n,e);case 6:return!this.a&&(this.a=new fV(oFt,this,6,6)),Nmn(this.a,n,e)}return SCn(this,n,t,e)},uZn.Uh=function(n,t,e){switch(t){case 3:return nF(this,null,e);case 4:return!this.b&&(this.b=new f_(cFt,this,4,7)),Nyn(this.b,n,e);case 5:return!this.c&&(this.c=new f_(cFt,this,5,8)),Nyn(this.c,n,e);case 6:return!this.a&&(this.a=new fV(oFt,this,6,6)),Nyn(this.a,n,e)}return phn(this,n,t,e)},uZn.Wh=function(n){switch(n){case 3:return!!s0(this);case 4:return!!this.b&&0!=this.b.i;case 5:return!!this.c&&0!=this.c.i;case 6:return!!this.a&&0!=this.a.i;case 7:return!this.b&&(this.b=new f_(cFt,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new f_(cFt,this,5,8)),this.c.i<=1));case 8:return z$n(this);case 9:return BNn(this);case 10:return!this.b&&(this.b=new f_(cFt,this,4,7)),0!=this.b.i&&(!this.c&&(this.c=new f_(cFt,this,5,8)),0!=this.c.i)}return _sn(this,n)},uZn.bi=function(n,t){switch(n){case 3:return void ARn(this,uG(t,27));case 4:return!this.b&&(this.b=new f_(cFt,this,4,7)),Czn(this.b),!this.b&&(this.b=new f_(cFt,this,4,7)),void CW(this.b,uG(t,16));case 5:return!this.c&&(this.c=new f_(cFt,this,5,8)),Czn(this.c),!this.c&&(this.c=new f_(cFt,this,5,8)),void CW(this.c,uG(t,16));case 6:return!this.a&&(this.a=new fV(oFt,this,6,6)),Czn(this.a),!this.a&&(this.a=new fV(oFt,this,6,6)),void CW(this.a,uG(t,16))}CSn(this,n,t)},uZn.ii=function(){return tYn(),_Kt},uZn.ki=function(n){switch(n){case 3:return void ARn(this,null);case 4:return!this.b&&(this.b=new f_(cFt,this,4,7)),void Czn(this.b);case 5:return!this.c&&(this.c=new f_(cFt,this,5,8)),void Czn(this.c);case 6:return!this.a&&(this.a=new fV(oFt,this,6,6)),void Czn(this.a)}Awn(this,n)},uZn.Ib=function(){return SXn(this)},zW(Ztt,"ElkEdgeImpl",326),sDn(452,2083,{110:1,342:1,166:1,452:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},is),uZn.Ah=function(n){return zjn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 1:return this.j;case 2:return this.k;case 3:return this.b;case 4:return this.c;case 5:return!this.a&&(this.a=new MD(eFt,this,5)),this.a;case 6:return f0(this);case 7:return t?fMn(this):this.i;case 8:return t?hMn(this):this.f;case 9:return!this.g&&(this.g=new f_(oFt,this,9,10)),this.g;case 10:return!this.e&&(this.e=new f_(oFt,this,10,9)),this.e;case 11:return this.d}return ajn(this,n,t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?zjn(this,e):this.Cb.Th(this,-1-i,null,e)),ZK(this,uG(n,74),e);case 9:return!this.g&&(this.g=new f_(oFt,this,9,10)),Nmn(this.g,n,e);case 10:return!this.e&&(this.e=new f_(oFt,this,10,9)),Nmn(this.e,n,e)}return uG(ern(uG(Lsn(this,16),29)||(tYn(),BKt),t),69).wk().zk(this,$vn(this),t-iQ((tYn(),BKt)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 5:return!this.a&&(this.a=new MD(eFt,this,5)),Nyn(this.a,n,e);case 6:return ZK(this,null,e);case 9:return!this.g&&(this.g=new f_(oFt,this,9,10)),Nyn(this.g,n,e);case 10:return!this.e&&(this.e=new f_(oFt,this,10,9)),Nyn(this.e,n,e)}return BIn(this,n,t,e)},uZn.Wh=function(n){switch(n){case 1:return 0!=this.j;case 2:return 0!=this.k;case 3:return 0!=this.b;case 4:return 0!=this.c;case 5:return!!this.a&&0!=this.a.i;case 6:return!!f0(this);case 7:return!!this.i;case 8:return!!this.f;case 9:return!!this.g&&0!=this.g.i;case 10:return!!this.e&&0!=this.e.i;case 11:return null!=this.d}return j4(this,n)},uZn.bi=function(n,t){switch(n){case 1:return void Tcn(this,uM(pK(t)));case 2:return void Ecn(this,uM(pK(t)));case 3:return void mcn(this,uM(pK(t)));case 4:return void jcn(this,uM(pK(t)));case 5:return!this.a&&(this.a=new MD(eFt,this,5)),Czn(this.a),!this.a&&(this.a=new MD(eFt,this,5)),void CW(this.a,uG(t,16));case 6:return void ORn(this,uG(t,74));case 7:return void zan(this,uG(t,84));case 8:return void Xan(this,uG(t,84));case 9:return!this.g&&(this.g=new f_(oFt,this,9,10)),Czn(this.g),!this.g&&(this.g=new f_(oFt,this,9,10)),void CW(this.g,uG(t,16));case 10:return!this.e&&(this.e=new f_(oFt,this,10,9)),Czn(this.e),!this.e&&(this.e=new f_(oFt,this,10,9)),void CW(this.e,uG(t,16));case 11:return void fon(this,mK(t))}bln(this,n,t)},uZn.ii=function(){return tYn(),BKt},uZn.ki=function(n){switch(n){case 1:return void Tcn(this,0);case 2:return void Ecn(this,0);case 3:return void mcn(this,0);case 4:return void jcn(this,0);case 5:return!this.a&&(this.a=new MD(eFt,this,5)),void Czn(this.a);case 6:return void ORn(this,null);case 7:return void zan(this,null);case 8:return void Xan(this,null);case 9:return!this.g&&(this.g=new f_(oFt,this,9,10)),void Czn(this.g);case 10:return!this.e&&(this.e=new f_(oFt,this,10,9)),void Czn(this.e);case 11:return void fon(this,null)}ffn(this,n)},uZn.Ib=function(){return A$n(this)},uZn.b=0,uZn.c=0,uZn.d=null,uZn.j=0,uZn.k=0,zW(Ztt,"ElkEdgeSectionImpl",452),sDn(158,120,{110:1,94:1,93:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1}),uZn.Lh=function(n,t,e){return 0==n?(!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab):$tn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t,e)},uZn.Sh=function(n,t,e){return 0==t?(!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e)):uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().zk(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Uh=function(n,t,e){return 0==t?(!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e)):uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().Ak(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Wh=function(n){return 0==n?!!this.Ab&&0!=this.Ab.i:l5(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.Zh=function(n){return VQn(this,n)},uZn.bi=function(n,t){if(0===n)return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));lpn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t)},uZn.di=function(n){Dvn(this,128,n)},uZn.ii=function(){return YYn(),$_t},uZn.ki=function(n){if(0===n)return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);sdn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.pi=function(){this.Bb|=1},uZn.qi=function(n){return qUn(this,n)},uZn.Bb=0,zW(Ytt,"EModelElementImpl",158),sDn(720,158,{110:1,94:1,93:1,480:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1},Fl),uZn.ri=function(n,t){return cWn(this,n,t)},uZn.si=function(n){var t,e,i,r;if(this.a!=Hrn(n)||256&n.Bb)throw hv(new vM(cet+n.zb+eet));for(e=n1(n);0!=z5(e.a).i;){if(_Tn(t=uG(yVn(e,0,F$(r=uG(zrn(z5(e.a),0),89).c,90)?uG(r,29):(YYn(),x_t)),29)))return uG(i=Hrn(t).wi().si(t),54).ci(n),i;e=n1(t)}return"java.util.Map$Entry"==(null!=n.D?n.D:n.B)?new Eq(n):new BG(n)},uZn.ti=function(n,t){return cYn(this,n,t)},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.a}return $tn(this,n-iQ((YYn(),A_t)),ern(uG(Lsn(this,16),29)||A_t,n),t,e)},uZn.Sh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 1:return this.a&&(e=uG(this.a,54).Th(this,4,fFt,e)),ywn(this,uG(n,241),e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),A_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),A_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 1:return ywn(this,null,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),A_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),A_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return!!this.a}return l5(this,n-iQ((YYn(),A_t)),ern(uG(Lsn(this,16),29)||A_t,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void yIn(this,uG(t,241))}lpn(this,n-iQ((YYn(),A_t)),ern(uG(Lsn(this,16),29)||A_t,n),t)},uZn.ii=function(){return YYn(),A_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void yIn(this,null)}sdn(this,n-iQ((YYn(),A_t)),ern(uG(Lsn(this,16),29)||A_t,n))},zW(Ytt,"EFactoryImpl",720),sDn(1037,720,{110:1,2113:1,94:1,93:1,480:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1},rs),uZn.ri=function(n,t){switch(n.hk()){case 12:return uG(t,149).Pg();case 13:return cpn(t);default:throw hv(new vM(tet+n.xe()+eet))}},uZn.si=function(n){var t;switch(-1==n.G&&(n.G=(t=Hrn(n))?Hyn(t.vi(),n):-1),n.G){case 4:return new cs;case 6:return new Bk;case 7:return new Hk;case 8:return new es;case 9:return new ns;case 10:return new is;case 11:return new as;default:throw hv(new vM(cet+n.zb+eet))}},uZn.ti=function(n,t){switch(n.hk()){case 13:case 12:return null;default:throw hv(new vM(tet+n.xe()+eet))}},zW(Ztt,"ElkGraphFactoryImpl",1037),sDn(448,158,{110:1,94:1,93:1,155:1,197:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1}),uZn.Gh=function(){var n;return null==(n=$1(eqn(uG(Lsn(this,16),29)||this.ii())))?(jP(),jP(),tBt):new VR(this,n)},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.xe()}return $tn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb}return l5(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void this.ui(mK(t))}lpn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t)},uZn.ii=function(){return YYn(),D_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void this.ui(null)}sdn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.xe=function(){return this.zb},uZn.ui=function(n){qon(this,n)},uZn.Ib=function(){return Wwn(this)},uZn.zb=null,zW(Ytt,"ENamedElementImpl",448),sDn(184,448,{110:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,54:1,99:1,158:1,184:1,119:1,120:1,690:1},aZ),uZn.Ah=function(n){return Jjn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.yb;case 3:return this.xb;case 4:return this.sb;case 5:return!this.rb&&(this.rb=new vV(this,s_t,this)),this.rb;case 6:return!this.vb&&(this.vb=new i_(fFt,this,6,7)),this.vb;case 7:return t?this.Db>>16==7?uG(this.Cb,241):null:$0(this)}return $tn(this,n-iQ((YYn(),F_t)),ern(uG(Lsn(this,16),29)||F_t,n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 4:return this.sb&&(e=uG(this.sb,54).Th(this,1,sFt,e)),Jwn(this,uG(n,480),e);case 5:return!this.rb&&(this.rb=new vV(this,s_t,this)),Nmn(this.rb,n,e);case 6:return!this.vb&&(this.vb=new i_(fFt,this,6,7)),Nmn(this.vb,n,e);case 7:return this.Cb&&(e=(i=this.Db>>16)>=0?Jjn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,7,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),F_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),F_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 4:return Jwn(this,null,e);case 5:return!this.rb&&(this.rb=new vV(this,s_t,this)),Nyn(this.rb,n,e);case 6:return!this.vb&&(this.vb=new i_(fFt,this,6,7)),Nyn(this.vb,n,e);case 7:return DUn(this,null,7,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),F_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),F_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.yb;case 3:return null!=this.xb;case 4:return!!this.sb;case 5:return!!this.rb&&0!=this.rb.i;case 6:return!!this.vb&&0!=this.vb.i;case 7:return!!$0(this)}return l5(this,n-iQ((YYn(),F_t)),ern(uG(Lsn(this,16),29)||F_t,n))},uZn.Zh=function(n){return jKn(this,n)||VQn(this,n)},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void qon(this,mK(t));case 2:return void zon(this,mK(t));case 3:return void Xon(this,mK(t));case 4:return void HIn(this,uG(t,480));case 5:return!this.rb&&(this.rb=new vV(this,s_t,this)),Czn(this.rb),!this.rb&&(this.rb=new vV(this,s_t,this)),void CW(this.rb,uG(t,16));case 6:return!this.vb&&(this.vb=new i_(fFt,this,6,7)),Czn(this.vb),!this.vb&&(this.vb=new i_(fFt,this,6,7)),void CW(this.vb,uG(t,16))}lpn(this,n-iQ((YYn(),F_t)),ern(uG(Lsn(this,16),29)||F_t,n),t)},uZn.ei=function(n){var t,e;if(n&&this.rb)for(e=new DD(this.rb);e.e!=e.i.gc();)F$(t=Zkn(e),364)&&(uG(t,364).w=null);Dvn(this,64,n)},uZn.ii=function(){return YYn(),F_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void qon(this,null);case 2:return void zon(this,null);case 3:return void Xon(this,null);case 4:return void HIn(this,null);case 5:return!this.rb&&(this.rb=new vV(this,s_t,this)),void Czn(this.rb);case 6:return!this.vb&&(this.vb=new i_(fFt,this,6,7)),void Czn(this.vb)}sdn(this,n-iQ((YYn(),F_t)),ern(uG(Lsn(this,16),29)||F_t,n))},uZn.pi=function(){ojn(this)},uZn.vi=function(){return!this.rb&&(this.rb=new vV(this,s_t,this)),this.rb},uZn.wi=function(){return this.sb},uZn.xi=function(){return this.ub},uZn.yi=function(){return this.xb},uZn.zi=function(){return this.yb},uZn.Ai=function(n){this.ub=n},uZn.Ib=function(){var n;return 64&this.Db?Wwn(this):((n=new fx(Wwn(this))).a+=" (nsURI: ",VA(n,this.yb),n.a+=", nsPrefix: ",VA(n,this.xb),n.a+=")",n.a)},uZn.xb=null,uZn.yb=null,zW(Ytt,"EPackageImpl",184),sDn(569,184,{110:1,2115:1,569:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,54:1,99:1,158:1,184:1,119:1,120:1,690:1},iDn),uZn.q=!1,uZn.r=!1;var dFt=!1;zW(Ztt,"ElkGraphPackageImpl",569),sDn(366,740,{110:1,342:1,167:1,135:1,422:1,366:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},cs),uZn.Ah=function(n){return Vjn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 7:return x0(this);case 8:return this.a}return spn(this,n,t,e)},uZn.Sh=function(n,t,e){var i;return 7===t?(this.Cb&&(e=(i=this.Db>>16)>=0?Vjn(this,e):this.Cb.Th(this,-1-i,null,e)),dz(this,uG(n,167),e)):SCn(this,n,t,e)},uZn.Uh=function(n,t,e){return 7==t?dz(this,null,e):phn(this,n,t,e)},uZn.Wh=function(n){switch(n){case 7:return!!x0(this);case 8:return!m_("",this.a)}return Kpn(this,n)},uZn.bi=function(n,t){switch(n){case 7:return void vKn(this,uG(t,167));case 8:return void Van(this,mK(t))}ISn(this,n,t)},uZn.ii=function(){return tYn(),UKt},uZn.ki=function(n){switch(n){case 7:return void vKn(this,null);case 8:return void Van(this,"")}Tmn(this,n)},uZn.Ib=function(){return zOn(this)},uZn.a="",zW(Ztt,"ElkLabelImpl",366),sDn(207,741,{110:1,342:1,84:1,167:1,27:1,422:1,207:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},Bk),uZn.Ah=function(n){return hEn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 9:return!this.c&&(this.c=new fV(wFt,this,9,9)),this.c;case 10:return!this.a&&(this.a=new fV(bFt,this,10,11)),this.a;case 11:return R0(this);case 12:return!this.b&&(this.b=new fV(aFt,this,12,3)),this.b;case 13:return qx(),!this.a&&(this.a=new fV(bFt,this,10,11)),this.a.i>0}return SMn(this,n,t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 9:return!this.c&&(this.c=new fV(wFt,this,9,9)),Nmn(this.c,n,e);case 10:return!this.a&&(this.a=new fV(bFt,this,10,11)),Nmn(this.a,n,e);case 11:return this.Cb&&(e=(i=this.Db>>16)>=0?hEn(this,e):this.Cb.Th(this,-1-i,null,e)),n_(this,uG(n,27),e);case 12:return!this.b&&(this.b=new fV(aFt,this,12,3)),Nmn(this.b,n,e)}return tSn(this,n,t,e)},uZn.Uh=function(n,t,e){switch(t){case 9:return!this.c&&(this.c=new fV(wFt,this,9,9)),Nyn(this.c,n,e);case 10:return!this.a&&(this.a=new fV(bFt,this,10,11)),Nyn(this.a,n,e);case 11:return n_(this,null,e);case 12:return!this.b&&(this.b=new fV(aFt,this,12,3)),Nyn(this.b,n,e)}return eSn(this,n,t,e)},uZn.Wh=function(n){switch(n){case 9:return!!this.c&&0!=this.c.i;case 10:return!!this.a&&0!=this.a.i;case 11:return!!R0(this);case 12:return!!this.b&&0!=this.b.i;case 13:return!this.a&&(this.a=new fV(bFt,this,10,11)),this.a.i>0}return iln(this,n)},uZn.bi=function(n,t){switch(n){case 9:return!this.c&&(this.c=new fV(wFt,this,9,9)),Czn(this.c),!this.c&&(this.c=new fV(wFt,this,9,9)),void CW(this.c,uG(t,16));case 10:return!this.a&&(this.a=new fV(bFt,this,10,11)),Czn(this.a),!this.a&&(this.a=new fV(bFt,this,10,11)),void CW(this.a,uG(t,16));case 11:return void GRn(this,uG(t,27));case 12:return!this.b&&(this.b=new fV(aFt,this,12,3)),Czn(this.b),!this.b&&(this.b=new fV(aFt,this,12,3)),void CW(this.b,uG(t,16))}SDn(this,n,t)},uZn.ii=function(){return tYn(),GKt},uZn.ki=function(n){switch(n){case 9:return!this.c&&(this.c=new fV(wFt,this,9,9)),void Czn(this.c);case 10:return!this.a&&(this.a=new fV(bFt,this,10,11)),void Czn(this.a);case 11:return void GRn(this,null);case 12:return!this.b&&(this.b=new fV(aFt,this,12,3)),void Czn(this.b)}yyn(this,n)},uZn.Ib=function(){return zBn(this)},zW(Ztt,"ElkNodeImpl",207),sDn(193,741,{110:1,342:1,84:1,167:1,123:1,422:1,193:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},Hk),uZn.Ah=function(n){return Wjn(this,n)},uZn.Lh=function(n,t,e){return 9==n?h0(this):SMn(this,n,t,e)},uZn.Sh=function(n,t,e){var i;return 9===t?(this.Cb&&(e=(i=this.Db>>16)>=0?Wjn(this,e):this.Cb.Th(this,-1-i,null,e)),tF(this,uG(n,27),e)):tSn(this,n,t,e)},uZn.Uh=function(n,t,e){return 9==t?tF(this,null,e):eSn(this,n,t,e)},uZn.Wh=function(n){return 9==n?!!h0(this):iln(this,n)},uZn.bi=function(n,t){9!==n?SDn(this,n,t):LRn(this,uG(t,27))},uZn.ii=function(){return tYn(),qKt},uZn.ki=function(n){9!==n?yyn(this,n):LRn(this,null)},uZn.Ib=function(){return VBn(this)},zW(Ztt,"ElkPortImpl",193);var gFt=Iq(Pet,"BasicEMap/Entry");sDn(1122,120,{110:1,44:1,94:1,93:1,136:1,58:1,114:1,54:1,99:1,119:1,120:1},as),uZn.Fb=function(n){return this===n},uZn.ld=function(){return this.b},uZn.Hb=function(){return xx(this)},uZn.Di=function(n){Wan(this,uG(n,149))},uZn.Lh=function(n,t,e){switch(n){case 0:return this.b;case 1:return this.c}return Dyn(this,n,t,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.b;case 1:return null!=this.c}return Wkn(this,n)},uZn.bi=function(n,t){switch(n){case 0:return void Wan(this,uG(t,149));case 1:return void Han(this,t)}sLn(this,n,t)},uZn.ii=function(){return tYn(),XKt},uZn.ki=function(n){switch(n){case 0:return void Wan(this,null);case 1:return void Han(this,null)}oAn(this,n)},uZn.Bi=function(){var n;return-1==this.a&&(n=this.b,this.a=n?Hon(n):0),this.a},uZn.md=function(){return this.c},uZn.Ci=function(n){this.a=n},uZn.nd=function(n){var t;return t=this.c,Han(this,n),t},uZn.Ib=function(){var n;return 64&this.Db?vxn(this):(JA(JA(JA(n=new WM,this.b?this.b.Pg():IZn),Y4n),ox(this.c)),n.a)},uZn.a=-1,uZn.c=null;var pFt,mFt,vFt,kFt,yFt,MFt,TFt,jFt,EFt=zW(Ztt,"ElkPropertyToValueMapEntryImpl",1122);sDn(996,1,{},ss),zW(Oet,"JsonAdapter",996),sDn(216,63,S1n,SM),zW(Oet,"JsonImportException",216),sDn(868,1,{},Zjn),zW(Oet,"JsonImporter",868),sDn(903,1,{},QO),zW(Oet,"JsonImporter/lambda$0$Type",903),sDn(904,1,{},JO),zW(Oet,"JsonImporter/lambda$1$Type",904),sDn(912,1,{},Yp),zW(Oet,"JsonImporter/lambda$10$Type",912),sDn(914,1,{},YO),zW(Oet,"JsonImporter/lambda$11$Type",914),sDn(915,1,{},ZO),zW(Oet,"JsonImporter/lambda$12$Type",915),sDn(921,1,{},SY),zW(Oet,"JsonImporter/lambda$13$Type",921),sDn(920,1,{},PY),zW(Oet,"JsonImporter/lambda$14$Type",920),sDn(916,1,{},nA),zW(Oet,"JsonImporter/lambda$15$Type",916),sDn(917,1,{},tA),zW(Oet,"JsonImporter/lambda$16$Type",917),sDn(918,1,{},eA),zW(Oet,"JsonImporter/lambda$17$Type",918),sDn(919,1,{},iA),zW(Oet,"JsonImporter/lambda$18$Type",919),sDn(924,1,{},Zp),zW(Oet,"JsonImporter/lambda$19$Type",924),sDn(905,1,{},nm),zW(Oet,"JsonImporter/lambda$2$Type",905),sDn(922,1,{},tm),zW(Oet,"JsonImporter/lambda$20$Type",922),sDn(923,1,{},em),zW(Oet,"JsonImporter/lambda$21$Type",923),sDn(927,1,{},im),zW(Oet,"JsonImporter/lambda$22$Type",927),sDn(925,1,{},rm),zW(Oet,"JsonImporter/lambda$23$Type",925),sDn(926,1,{},cm),zW(Oet,"JsonImporter/lambda$24$Type",926),sDn(929,1,{},am),zW(Oet,"JsonImporter/lambda$25$Type",929),sDn(928,1,{},om),zW(Oet,"JsonImporter/lambda$26$Type",928),sDn(930,1,QZn,rA),uZn.Cd=function(n){ptn(this.b,this.a,mK(n))},zW(Oet,"JsonImporter/lambda$27$Type",930),sDn(931,1,QZn,cA),uZn.Cd=function(n){mtn(this.b,this.a,mK(n))},zW(Oet,"JsonImporter/lambda$28$Type",931),sDn(932,1,{},aA),zW(Oet,"JsonImporter/lambda$29$Type",932),sDn(908,1,{},um),zW(Oet,"JsonImporter/lambda$3$Type",908),sDn(933,1,{},oA),zW(Oet,"JsonImporter/lambda$30$Type",933),sDn(934,1,{},sm),zW(Oet,"JsonImporter/lambda$31$Type",934),sDn(935,1,{},hm),zW(Oet,"JsonImporter/lambda$32$Type",935),sDn(936,1,{},fm),zW(Oet,"JsonImporter/lambda$33$Type",936),sDn(937,1,{},lm),zW(Oet,"JsonImporter/lambda$34$Type",937),sDn(870,1,{},bm),zW(Oet,"JsonImporter/lambda$35$Type",870),sDn(941,1,{},DU),zW(Oet,"JsonImporter/lambda$36$Type",941),sDn(938,1,QZn,wm),uZn.Cd=function(n){V8(this.a,uG(n,377))},zW(Oet,"JsonImporter/lambda$37$Type",938),sDn(939,1,QZn,sA),uZn.Cd=function(n){vA(this.a,this.b,uG(n,166))},zW(Oet,"JsonImporter/lambda$38$Type",939),sDn(940,1,QZn,hA),uZn.Cd=function(n){kA(this.a,this.b,uG(n,166))},zW(Oet,"JsonImporter/lambda$39$Type",940),sDn(906,1,{},dm),zW(Oet,"JsonImporter/lambda$4$Type",906),sDn(942,1,QZn,gm),uZn.Cd=function(n){W8(this.a,uG(n,8))},zW(Oet,"JsonImporter/lambda$40$Type",942),sDn(907,1,{},pm),zW(Oet,"JsonImporter/lambda$5$Type",907),sDn(911,1,{},mm),zW(Oet,"JsonImporter/lambda$6$Type",911),sDn(909,1,{},vm),zW(Oet,"JsonImporter/lambda$7$Type",909),sDn(910,1,{},km),zW(Oet,"JsonImporter/lambda$8$Type",910),sDn(913,1,{},ym),zW(Oet,"JsonImporter/lambda$9$Type",913),sDn(961,1,QZn,Mm),uZn.Cd=function(n){pQ(this.a,new QW(mK(n)))},zW(Oet,"JsonMetaDataConverter/lambda$0$Type",961),sDn(962,1,QZn,Tm),uZn.Cd=function(n){SW(this.a,uG(n,245))},zW(Oet,"JsonMetaDataConverter/lambda$1$Type",962),sDn(963,1,QZn,jm),uZn.Cd=function(n){m2(this.a,uG(n,143))},zW(Oet,"JsonMetaDataConverter/lambda$2$Type",963),sDn(964,1,QZn,Em),uZn.Cd=function(n){PW(this.a,uG(n,170))},zW(Oet,"JsonMetaDataConverter/lambda$3$Type",964),sDn(245,22,{3:1,34:1,22:1,245:1},fA);var SFt,PFt=_cn(p3n,"GraphFeature",245,Oat,brn,QU);sDn(11,1,{34:1,149:1},Cm,uF,mL,_N),uZn.Fd=function(n){return dD(this,uG(n,149))},uZn.Fb=function(n){return QZ(this,n)},uZn.Sg=function(){return Jkn(this)},uZn.Pg=function(){return this.b},uZn.Hb=function(){return pln(this.b)},uZn.Ib=function(){return this.b},zW(p3n,"Property",11),sDn(671,1,b2n,Sm),uZn.Ne=function(n,t){return wgn(this,uG(n,96),uG(t,96))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(p3n,"PropertyHolderComparator",671),sDn(709,1,$Zn,Pm),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){return Mtn(this)},uZn.Qb=function(){xj()},uZn.Ob=function(){return!!this.a},zW(qet,"ElkGraphUtil/AncestorIterator",709);var CFt=Iq(Pet,"EList");sDn(70,56,{20:1,31:1,56:1,16:1,15:1,70:1,61:1}),uZn.bd=function(n,t){$dn(this,n,t)},uZn.Fc=function(n){return ttn(this,n)},uZn.cd=function(n,t){return bfn(this,n,t)},uZn.Gc=function(n){return CW(this,n)},uZn.Ii=function(){return new nR(this)},uZn.Ji=function(){return new tR(this)},uZn.Ki=function(n){return han(this,n)},uZn.Li=function(){return!0},uZn.Mi=function(n,t){},uZn.Ni=function(){},uZn.Oi=function(n,t){Ann(this,n,t)},uZn.Pi=function(n,t,e){},uZn.Qi=function(n,t){},uZn.Ri=function(n,t,e){},uZn.Fb=function(n){return G_n(this,n)},uZn.Hb=function(){return Bhn(this)},uZn.Si=function(){return!1},uZn.Kc=function(){return new DD(this)},uZn.ed=function(){return new Zx(this)},uZn.fd=function(n){var t;if(t=this.gc(),n<0||n>t)throw hv(new w_(n,t));return new QV(this,n)},uZn.Ui=function(n,t){this.Ti(n,this.dd(t))},uZn.Mc=function(n){return rin(this,n)},uZn.Wi=function(n,t){return t},uZn.hd=function(n,t){return Uyn(this,n,t)},uZn.Ib=function(){return Tpn(this)},uZn.Yi=function(){return!0},uZn.Zi=function(n,t){return gln(this,t)},zW(Pet,"AbstractEList",70),sDn(66,70,Qet,ls,Drn,Hun),uZn.Ei=function(n,t){return PCn(this,n,t)},uZn.Fi=function(n){return QMn(this,n)},uZn.Gi=function(n,t){edn(this,n,t)},uZn.Hi=function(n){z9(this,n)},uZn.$i=function(n){return Otn(this,n)},uZn.$b=function(){V9(this)},uZn.Hc=function(n){return sSn(this,n)},uZn.Xb=function(n){return zrn(this,n)},uZn._i=function(n){var t,e,i;++this.j,n>(e=null==this.g?0:this.g.length)&&(i=this.g,(t=e+(e/2|0)+4)=0&&(this.gd(t),!0)},uZn.Xi=function(n,t){return this.Dj(n,this.Zi(n,t))},uZn.gc=function(){return this.Ej()},uZn.Pc=function(){return this.Fj()},uZn.Qc=function(n){return this.Gj(n)},uZn.Ib=function(){return this.Hj()},zW(Pet,"DelegatingEList",2093),sDn(2094,2093,_it),uZn.Ei=function(n,t){return dGn(this,n,t)},uZn.Fi=function(n){return this.Ei(this.Ej(),n)},uZn.Gi=function(n,t){cDn(this,n,t)},uZn.Hi=function(n){S$n(this,n)},uZn.Li=function(){return!this.Mj()},uZn.$b=function(){_zn(this)},uZn.Ij=function(n,t,e,i,r){return new zZ(this,n,t,e,i,r)},uZn.Jj=function(n){Msn(this.jj(),n)},uZn.Kj=function(){return null},uZn.Lj=function(){return-1},uZn.jj=function(){return null},uZn.Mj=function(){return!1},uZn.Nj=function(n,t){return t},uZn.Oj=function(n,t){return t},uZn.Pj=function(){return!1},uZn.Qj=function(){return!this.Aj()},uZn.Ti=function(n,t){var e,i;return this.Pj()?(i=this.Qj(),e=pIn(this,n,t),this.Jj(this.Ij(7,xwn(t),e,n,i)),e):pIn(this,n,t)},uZn.gd=function(n){var t,e,i,r;return this.Pj()?(e=null,i=this.Qj(),t=this.Ij(4,r=Oq(this,n),null,n,i),this.Mj()&&r?(e=this.Oj(r,e))?(e.nj(t),e.oj()):this.Jj(t):e?(e.nj(t),e.oj()):this.Jj(t),r):(r=Oq(this,n),this.Mj()&&r&&(e=this.Oj(r,null))&&e.oj(),r)},uZn.Xi=function(n,t){return gGn(this,n,t)},zW(Utt,"DelegatingNotifyingListImpl",2094),sDn(152,1,Bit),uZn.nj=function(n){return kPn(this,n)},uZn.oj=function(){Cen(this)},uZn.gj=function(){return this.d},uZn.Kj=function(){return null},uZn.Rj=function(){return null},uZn.hj=function(n){return-1},uZn.ij=function(){return OFn(this)},uZn.jj=function(){return null},uZn.kj=function(){return AFn(this)},uZn.lj=function(){return this.o<0?this.o<-2?-2-this.o-1:-1:this.o},uZn.Sj=function(){return!1},uZn.mj=function(n){var t,e,i,r,c,a,o,u;switch(this.d){case 1:case 2:switch(n.gj()){case 1:case 2:if(xA(n.jj())===xA(this.jj())&&this.hj(null)==n.hj(null))return this.g=n.ij(),1==n.gj()&&(this.d=1),!0}case 4:if(4===n.gj()&&xA(n.jj())===xA(this.jj())&&this.hj(null)==n.hj(null))return a=kVn(this),c=this.o<0?this.o<-2?-2-this.o-1:-1:this.o,i=n.lj(),this.d=6,u=new Drn(2),c<=i?(ttn(u,this.n),ttn(u,n.kj()),this.g=Uhn(cT(YHt,1),W1n,28,15,[this.o=c,i+1])):(ttn(u,n.kj()),ttn(u,this.n),this.g=Uhn(cT(YHt,1),W1n,28,15,[this.o=i,c])),this.n=u,a||(this.o=-2-this.o-1),!0;break;case 6:if(4===n.gj()&&xA(n.jj())===xA(this.jj())&&this.hj(null)==n.hj(null)){for(a=kVn(this),i=n.lj(),o=uG(this.g,53),e=Inn(YHt,W1n,28,o.length+1,15,1),t=0;t>>0).toString(16))).a+=" (eventType: ",this.d){case 1:e.a+="SET";break;case 2:e.a+="UNSET";break;case 3:e.a+="ADD";break;case 5:e.a+="ADD_MANY";break;case 4:e.a+="REMOVE";break;case 6:e.a+="REMOVE_MANY";break;case 7:e.a+="MOVE";break;case 8:e.a+="REMOVING_ADAPTER";break;case 9:e.a+="RESOLVE";break;default:Aj(e,this.d)}if(pHn(this)&&(e.a+=", touch: true"),e.a+=", position: ",Aj(e,this.o<0?this.o<-2?-2-this.o-1:-1:this.o),e.a+=", notifier: ",zA(e,this.jj()),e.a+=", feature: ",zA(e,this.Kj()),e.a+=", oldValue: ",zA(e,AFn(this)),e.a+=", newValue: ",6==this.d&&F$(this.g,53)){for(t=uG(this.g,53),e.a+="[",n=0;n10?(this.b&&this.c.j==this.a||(this.b=new oX(this),this.a=this.j),cS(this.b,n)):sSn(this,n)},uZn.Yi=function(){return!0},uZn.a=0,zW(Pet,"AbstractEList/1",966),sDn(302,77,v0n,w_),zW(Pet,"AbstractEList/BasicIndexOutOfBoundsException",302),sDn(37,1,$Zn,DD),uZn.Nb=function(n){SV(this,n)},uZn.Xj=function(){if(this.i.j!=this.f)throw hv(new Fv)},uZn.Yj=function(){return Zkn(this)},uZn.Ob=function(){return this.e!=this.i.gc()},uZn.Pb=function(){return this.Yj()},uZn.Qb=function(){$Sn(this)},uZn.e=0,uZn.f=0,uZn.g=-1,zW(Pet,"AbstractEList/EIterator",37),sDn(286,37,UZn,Zx,QV),uZn.Qb=function(){$Sn(this)},uZn.Rb=function(n){Smn(this,n)},uZn.Zj=function(){var n;try{return n=this.d.Xb(--this.e),this.Xj(),this.g=this.e,n}catch(t){throw F$(t=Ehn(t),77)?(this.Xj(),hv(new Bv)):hv(t)}},uZn.$j=function(n){cTn(this,n)},uZn.Sb=function(){return 0!=this.e},uZn.Tb=function(){return this.e},uZn.Ub=function(){return this.Zj()},uZn.Vb=function(){return this.e-1},uZn.Wb=function(n){this.$j(n)},zW(Pet,"AbstractEList/EListIterator",286),sDn(355,37,$Zn,nR),uZn.Yj=function(){return nyn(this)},uZn.Qb=function(){throw hv(new Kv)},zW(Pet,"AbstractEList/NonResolvingEIterator",355),sDn(398,286,UZn,tR,N_),uZn.Rb=function(n){throw hv(new Kv)},uZn.Yj=function(){var n;try{return n=this.c.Vi(this.e),this.Xj(),this.g=this.e++,n}catch(t){throw F$(t=Ehn(t),77)?(this.Xj(),hv(new Bv)):hv(t)}},uZn.Zj=function(){var n;try{return n=this.c.Vi(--this.e),this.Xj(),this.g=this.e,n}catch(t){throw F$(t=Ehn(t),77)?(this.Xj(),hv(new Bv)):hv(t)}},uZn.Qb=function(){throw hv(new Kv)},uZn.Wb=function(n){throw hv(new Kv)},zW(Pet,"AbstractEList/NonResolvingEListIterator",398),sDn(2080,70,Git),uZn.Ei=function(n,t){var e,i,r,c,a,o,u,s,h;if(0!=(i=t.gc())){for(e=zln(this,(s=null==(u=uG(Lsn(this.a,4),129))?0:u.length)+i),(h=s-n)>0&&qGn(u,n,e,n+i,h),o=t.Kc(),c=0;ce)throw hv(new w_(n,e));return new qJ(this,n)},uZn.$b=function(){var n,t;++this.j,t=null==(n=uG(Lsn(this.a,4),129))?0:n.length,Pkn(this,null),Ann(this,t,n)},uZn.Hc=function(n){var t,e,i,r;if(null!=(t=uG(Lsn(this.a,4),129)))if(null!=n){for(i=0,r=(e=t).length;i=(e=null==(t=uG(Lsn(this.a,4),129))?0:t.length))throw hv(new w_(n,e));return t[n]},uZn.dd=function(n){var t,e,i;if(null!=(t=uG(Lsn(this.a,4),129)))if(null!=n){for(e=0,i=t.length;ee)throw hv(new w_(n,e));return new GJ(this,n)},uZn.Ti=function(n,t){var e,i,r;if(n>=(r=null==(e=lvn(this))?0:e.length))throw hv(new dM(zet+n+Vet+r));if(t>=r)throw hv(new dM(Wet+t+Vet+r));return i=e[t],n!=t&&(n0&&qGn(n,0,t,0,e),t},uZn.Qc=function(n){var t,e;return(e=null==(t=uG(Lsn(this.a,4),129))?0:t.length)>0&&(n.lengthe&&uQ(n,e,null),n},zW(Pet,"ArrayDelegatingEList",2080),sDn(1051,37,$Zn,M9),uZn.Xj=function(){if(this.b.j!=this.f||xA(uG(Lsn(this.b.a,4),129))!==xA(this.a))throw hv(new Fv)},uZn.Qb=function(){$Sn(this),this.a=uG(Lsn(this.b.a,4),129)},zW(Pet,"ArrayDelegatingEList/EIterator",1051),sDn(722,286,UZn,pV,GJ),uZn.Xj=function(){if(this.b.j!=this.f||xA(uG(Lsn(this.b.a,4),129))!==xA(this.a))throw hv(new Fv)},uZn.$j=function(n){cTn(this,n),this.a=uG(Lsn(this.b.a,4),129)},uZn.Qb=function(){$Sn(this),this.a=uG(Lsn(this.b.a,4),129)},zW(Pet,"ArrayDelegatingEList/EListIterator",722),sDn(1052,355,$Zn,T9),uZn.Xj=function(){if(this.b.j!=this.f||xA(uG(Lsn(this.b.a,4),129))!==xA(this.a))throw hv(new Fv)},zW(Pet,"ArrayDelegatingEList/NonResolvingEIterator",1052),sDn(723,398,UZn,mV,qJ),uZn.Xj=function(){if(this.b.j!=this.f||xA(uG(Lsn(this.b.a,4),129))!==xA(this.a))throw hv(new Fv)},zW(Pet,"ArrayDelegatingEList/NonResolvingEListIterator",723),sDn(615,302,v0n,pL),zW(Pet,"BasicEList/BasicIndexOutOfBoundsException",615),sDn(710,66,Qet,AA),uZn.bd=function(n,t){throw hv(new Kv)},uZn.Fc=function(n){throw hv(new Kv)},uZn.cd=function(n,t){throw hv(new Kv)},uZn.Gc=function(n){throw hv(new Kv)},uZn.$b=function(){throw hv(new Kv)},uZn._i=function(n){throw hv(new Kv)},uZn.Kc=function(){return this.Ii()},uZn.ed=function(){return this.Ji()},uZn.fd=function(n){return this.Ki(n)},uZn.Ti=function(n,t){throw hv(new Kv)},uZn.Ui=function(n,t){throw hv(new Kv)},uZn.gd=function(n){throw hv(new Kv)},uZn.Mc=function(n){throw hv(new Kv)},uZn.hd=function(n,t){throw hv(new Kv)},zW(Pet,"BasicEList/UnmodifiableEList",710),sDn(721,1,{3:1,20:1,16:1,15:1,61:1,597:1}),uZn.bd=function(n,t){Y$(this,n,uG(t,44))},uZn.Fc=function(n){return YR(this,uG(n,44))},uZn.Jc=function(n){z8(this,n)},uZn.Xb=function(n){return uG(zrn(this.c,n),136)},uZn.Ti=function(n,t){return uG(this.c.Ti(n,t),44)},uZn.Ui=function(n,t){Z$(this,n,uG(t,44))},uZn.Lc=function(){return new fX(null,new h3(this,16))},uZn.gd=function(n){return uG(this.c.gd(n),44)},uZn.hd=function(n,t){return EW(this,n,uG(t,44))},uZn.jd=function(n){Lon(this,n)},uZn.Nc=function(){return new h3(this,16)},uZn.Oc=function(){return new fX(null,new h3(this,16))},uZn.cd=function(n,t){return this.c.cd(n,t)},uZn.Gc=function(n){return this.c.Gc(n)},uZn.$b=function(){this.c.$b()},uZn.Hc=function(n){return this.c.Hc(n)},uZn.Ic=function(n){return yhn(this.c,n)},uZn._j=function(){var n,t;if(null==this.d){for(this.d=Inn(IFt,qit,66,2*this.f+1,0,1),t=this.e,this.f=0,n=this.c.Kc();n.e!=n.i.gc();)bMn(this,uG(n.Yj(),136));this.e=t}},uZn.Fb=function(n){return H_(this,n)},uZn.Hb=function(){return Bhn(this.c)},uZn.dd=function(n){return this.c.dd(n)},uZn.ak=function(){this.c=new Im(this)},uZn.dc=function(){return 0==this.f},uZn.Kc=function(){return this.c.Kc()},uZn.ed=function(){return this.c.ed()},uZn.fd=function(n){return this.c.fd(n)},uZn.bk=function(){return Tnn(this)},uZn.ck=function(n,t,e){return new xU(n,t,e)},uZn.dk=function(){return new ws},uZn.Mc=function(n){return uan(this,n)},uZn.gc=function(){return this.f},uZn.kd=function(n,t){return new C2(this.c,n,t)},uZn.Pc=function(){return this.c.Pc()},uZn.Qc=function(n){return this.c.Qc(n)},uZn.Ib=function(){return Tpn(this.c)},uZn.e=0,uZn.f=0,zW(Pet,"BasicEMap",721),sDn(1046,66,Qet,Im),uZn.Mi=function(n,t){Qv(this,uG(t,136))},uZn.Pi=function(n,t,e){var i;++(i=this,uG(t,136),i).a.e},uZn.Qi=function(n,t){Jv(this,uG(t,136))},uZn.Ri=function(n,t,e){fR(this,uG(t,136),uG(e,136))},uZn.Oi=function(n,t){Osn(this.a)},zW(Pet,"BasicEMap/1",1046),sDn(1047,66,Qet,ws),uZn.aj=function(n){return Inn(FFt,Xit,621,n,0,1)},zW(Pet,"BasicEMap/2",1047),sDn(1048,KZn,FZn,Om),uZn.$b=function(){this.a.c.$b()},uZn.Hc=function(n){return ymn(this.a,n)},uZn.Kc=function(){return 0==this.a.f?(EK(),KFt.a):new aj(this.a)},uZn.Mc=function(n){var t;return t=this.a.f,Svn(this.a,n),this.a.f!=t},uZn.gc=function(){return this.a.f},zW(Pet,"BasicEMap/3",1048),sDn(1049,31,RZn,Am),uZn.$b=function(){this.a.c.$b()},uZn.Hc=function(n){return q_n(this.a,n)},uZn.Kc=function(){return 0==this.a.f?(EK(),KFt.a):new oj(this.a)},uZn.gc=function(){return this.a.f},zW(Pet,"BasicEMap/4",1049),sDn(1050,KZn,FZn,Lm),uZn.$b=function(){this.a.c.$b()},uZn.Hc=function(n){var t,e,i,r,c,a,o,u,s;if(this.a.f>0&&F$(n,44)&&(this.a._j(),r=null==(o=(u=uG(n,44)).ld())?0:Hon(o),c=iF(this.a,r),t=this.a.d[c]))for(e=uG(t.g,379),s=t.i,a=0;a"+this.c},uZn.a=0;var KFt,FFt=zW(Pet,"BasicEMap/EntryImpl",621);sDn(546,1,{},ds),zW(Pet,"BasicEMap/View",546),sDn(783,1,{}),uZn.Fb=function(n){return PDn((hZ(),zot),n)},uZn.Hb=function(){return Zfn((hZ(),zot))},uZn.Ib=function(){return vIn((hZ(),zot))},zW(Pet,"ECollections/BasicEmptyUnmodifiableEList",783),sDn(1348,1,UZn,gs),uZn.Nb=function(n){SV(this,n)},uZn.Rb=function(n){throw hv(new Kv)},uZn.Ob=function(){return!1},uZn.Sb=function(){return!1},uZn.Pb=function(){throw hv(new Bv)},uZn.Tb=function(){return 0},uZn.Ub=function(){throw hv(new Bv)},uZn.Vb=function(){return-1},uZn.Qb=function(){throw hv(new Kv)},uZn.Wb=function(n){throw hv(new Kv)},zW(Pet,"ECollections/BasicEmptyUnmodifiableEList/1",1348),sDn(1346,783,{20:1,16:1,15:1,61:1},Gk),uZn.bd=function(n,t){iE()},uZn.Fc=function(n){return rE()},uZn.cd=function(n,t){return cE()},uZn.Gc=function(n){return aE()},uZn.$b=function(){oE()},uZn.Hc=function(n){return!1},uZn.Ic=function(n){return!1},uZn.Jc=function(n){z8(this,n)},uZn.Xb=function(n){return oL((hZ(),n)),null},uZn.dd=function(n){return-1},uZn.dc=function(){return!0},uZn.Kc=function(){return this.a},uZn.ed=function(){return this.a},uZn.fd=function(n){return this.a},uZn.Ti=function(n,t){return uE()},uZn.Ui=function(n,t){sE()},uZn.Lc=function(){return new fX(null,new h3(this,16))},uZn.gd=function(n){return hE()},uZn.Mc=function(n){return fE()},uZn.hd=function(n,t){return lE()},uZn.gc=function(){return 0},uZn.jd=function(n){Lon(this,n)},uZn.Nc=function(){return new h3(this,16)},uZn.Oc=function(){return new fX(null,new h3(this,16))},uZn.kd=function(n,t){return hZ(),new C2(zot,n,t)},uZn.Pc=function(){return Sz((hZ(),zot))},uZn.Qc=function(n){return hZ(),oTn(zot,n)},zW(Pet,"ECollections/EmptyUnmodifiableEList",1346),sDn(1347,783,{20:1,16:1,15:1,61:1,597:1},qk),uZn.bd=function(n,t){iE()},uZn.Fc=function(n){return rE()},uZn.cd=function(n,t){return cE()},uZn.Gc=function(n){return aE()},uZn.$b=function(){oE()},uZn.Hc=function(n){return!1},uZn.Ic=function(n){return!1},uZn.Jc=function(n){z8(this,n)},uZn.Xb=function(n){return oL((hZ(),n)),null},uZn.dd=function(n){return-1},uZn.dc=function(){return!0},uZn.Kc=function(){return this.a},uZn.ed=function(){return this.a},uZn.fd=function(n){return this.a},uZn.Ti=function(n,t){return uE()},uZn.Ui=function(n,t){sE()},uZn.Lc=function(){return new fX(null,new h3(this,16))},uZn.gd=function(n){return hE()},uZn.Mc=function(n){return fE()},uZn.hd=function(n,t){return lE()},uZn.gc=function(){return 0},uZn.jd=function(n){Lon(this,n)},uZn.Nc=function(){return new h3(this,16)},uZn.Oc=function(){return new fX(null,new h3(this,16))},uZn.kd=function(n,t){return hZ(),new C2(zot,n,t)},uZn.Pc=function(){return Sz((hZ(),zot))},uZn.Qc=function(n){return hZ(),oTn(zot,n)},uZn.bk=function(){return hZ(),hZ(),Vot},zW(Pet,"ECollections/EmptyUnmodifiableEMap",1347);var _Ft,BFt=Iq(Pet,"Enumerator");sDn(288,1,{288:1},Z_n),uZn.Fb=function(n){var t;return this===n||!!F$(n,288)&&(t=uG(n,288),this.f==t.f&&yX(this.i,t.i)&&kX(this.a,256&this.f?256&t.f?t.a:null:256&t.f?null:t.a)&&kX(this.d,t.d)&&kX(this.g,t.g)&&kX(this.e,t.e)&&Ykn(this,t))},uZn.Hb=function(){return this.f},uZn.Ib=function(){return xUn(this)},uZn.f=0;var HFt,UFt,GFt,qFt=0,XFt=0,zFt=0,VFt=0,WFt=0,QFt=0,JFt=0,YFt=0,ZFt=0,n_t=0,t_t=0,e_t=0,i_t=0;zW(Pet,"URI",288),sDn(1121,45,B0n,Xk),uZn.zc=function(n,t){return uG(r2(this,mK(n),uG(t,288)),288)},zW(Pet,"URI/URICache",1121),sDn(506,66,Qet,us,$X),uZn.Si=function(){return!0},zW(Pet,"UniqueEList",506),sDn(590,63,S1n,Pen),zW(Pet,"WrappedException",590);var r_t,c_t=Iq(Itt,Wit),a_t=Iq(Itt,Qit),o_t=Iq(Itt,Jit),u_t=Iq(Itt,Yit),s_t=Iq(Itt,Zit),h_t=Iq(Itt,"EClass"),f_t=Iq(Itt,"EDataType");sDn(1233,45,B0n,zk),uZn.xc=function(n){return RA(n)?U1(this,n):DA(FX(this.f,n))},zW(Itt,"EDataType/Internal/ConversionDelegate/Factory/Registry/Impl",1233);var l_t,b_t,w_t=Iq(Itt,"EEnum"),d_t=Iq(Itt,nrt),g_t=Iq(Itt,trt),p_t=Iq(Itt,ert),m_t=Iq(Itt,irt),v_t=Iq(Itt,rrt);sDn(1042,1,{},os),uZn.Ib=function(){return"NIL"},zW(Itt,"EStructuralFeature/Internal/DynamicValueHolder/1",1042),sDn(1041,45,B0n,Vk),uZn.xc=function(n){return RA(n)?U1(this,n):DA(FX(this.f,n))},zW(Itt,"EStructuralFeature/Internal/SettingDelegate/Factory/Registry/Impl",1041);var k_t,y_t,M_t,T_t,j_t,E_t,S_t,P_t,C_t,I_t,O_t,A_t,L_t,N_t,$_t,D_t,x_t,R_t,K_t,F_t,__t,B_t,H_t,U_t,G_t,q_t,X_t,z_t,V_t,W_t,Q_t,J_t=Iq(Itt,crt),Y_t=Iq(Itt,"EValidator/PatternMatcher"),Z_t=Iq(art,"FeatureMap/Entry");sDn(545,1,{76:1},TA),uZn.Lk=function(){return this.a},uZn.md=function(){return this.b},zW(Ytt,"BasicEObjectImpl/1",545),sDn(1040,1,ort,jA),uZn.Fk=function(n){return U9(this.a,this.b,n)},uZn.Qj=function(){return M0(this.a,this.b)},uZn.Wb=function(n){y0(this.a,this.b,n)},uZn.Gk=function(){VQ(this.a,this.b)},zW(Ytt,"BasicEObjectImpl/4",1040),sDn(2081,1,{114:1}),uZn.Mk=function(n){this.e=0==n?X_t:Inn(dat,EZn,1,n,5,1)},uZn.li=function(n){return this.e[n]},uZn.mi=function(n,t){this.e[n]=t},uZn.ni=function(n){this.e[n]=null},uZn.Nk=function(){return this.c},uZn.Ok=function(){throw hv(new Kv)},uZn.Pk=function(){throw hv(new Kv)},uZn.Qk=function(){return this.d},uZn.Rk=function(){return null!=this.e},uZn.Sk=function(n){this.c=n},uZn.Tk=function(n){throw hv(new Kv)},uZn.Uk=function(n){throw hv(new Kv)},uZn.Vk=function(n){this.d=n},zW(Ytt,"BasicEObjectImpl/EPropertiesHolderBaseImpl",2081),sDn(192,2081,{114:1},Ll),uZn.Ok=function(){return this.a},uZn.Pk=function(){return this.b},uZn.Tk=function(n){this.a=n},uZn.Uk=function(n){this.b=n},zW(Ytt,"BasicEObjectImpl/EPropertiesHolderImpl",192),sDn(516,99,Jtt,ps),uZn.uh=function(){return this.f},uZn.zh=function(){return this.k},uZn.Bh=function(n,t){this.g=n,this.i=t},uZn.Dh=function(){return 2&this.j?this.$h().Nk():this.ii()},uZn.Fh=function(){return this.i},uZn.wh=function(){return!!(1&this.j)},uZn.Ph=function(){return this.g},uZn.Vh=function(){return!!(4&this.j)},uZn.$h=function(){return!this.k&&(this.k=new Ll),this.k},uZn.ci=function(n){this.$h().Sk(n),n?this.j|=2:this.j&=-3},uZn.ei=function(n){this.$h().Uk(n),n?this.j|=4:this.j&=-5},uZn.ii=function(){return(tQ(),M_t).S},uZn.i=0,uZn.j=1,zW(Ytt,"EObjectImpl",516),sDn(798,516,{110:1,94:1,93:1,58:1,114:1,54:1,99:1},BG),uZn.li=function(n){return this.e[n]},uZn.mi=function(n,t){this.e[n]=t},uZn.ni=function(n){this.e[n]=null},uZn.Dh=function(){return this.d},uZn.Ih=function(n){return emn(this.d,n)},uZn.Kh=function(){return this.d},uZn.Oh=function(){return null!=this.e},uZn.$h=function(){return!this.k&&(this.k=new ms),this.k},uZn.ci=function(n){this.d=n},uZn.hi=function(){var n;return null==this.e&&(n=iQ(this.d),this.e=0==n?z_t:Inn(dat,EZn,1,n,5,1)),this},uZn.ji=function(){return 0},zW(Ytt,"DynamicEObjectImpl",798),sDn(1522,798,{110:1,44:1,94:1,93:1,136:1,58:1,114:1,54:1,99:1},Eq),uZn.Fb=function(n){return this===n},uZn.Hb=function(){return xx(this)},uZn.ci=function(n){this.d=n,this.b=EKn(n,"key"),this.c=EKn(n,uet)},uZn.Bi=function(){var n;return-1==this.a&&(n=zen(this,this.b),this.a=null==n?0:Hon(n)),this.a},uZn.ld=function(){return zen(this,this.b)},uZn.md=function(){return zen(this,this.c)},uZn.Ci=function(n){this.a=n},uZn.Di=function(n){y0(this,this.b,n)},uZn.nd=function(n){var t;return t=zen(this,this.c),y0(this,this.c,n),t},uZn.a=0,zW(Ytt,"DynamicEObjectImpl/BasicEMapEntry",1522),sDn(1523,1,{114:1},ms),uZn.Mk=function(n){throw hv(new Kv)},uZn.li=function(n){throw hv(new Kv)},uZn.mi=function(n,t){throw hv(new Kv)},uZn.ni=function(n){throw hv(new Kv)},uZn.Nk=function(){throw hv(new Kv)},uZn.Ok=function(){return this.a},uZn.Pk=function(){return this.b},uZn.Qk=function(){return this.c},uZn.Rk=function(){throw hv(new Kv)},uZn.Sk=function(n){throw hv(new Kv)},uZn.Tk=function(n){this.a=n},uZn.Uk=function(n){this.b=n},uZn.Vk=function(n){this.c=n},zW(Ytt,"DynamicEObjectImpl/DynamicEPropertiesHolderImpl",1523),sDn(519,158,{110:1,94:1,93:1,598:1,155:1,58:1,114:1,54:1,99:1,519:1,158:1,119:1,120:1},vs),uZn.Ah=function(n){return Yjn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.d;case 2:return e?(!this.b&&(this.b=new XR((YYn(),H_t),wBt,this)),this.b):(!this.b&&(this.b=new XR((YYn(),H_t),wBt,this)),Tnn(this.b));case 3:return F0(this);case 4:return!this.a&&(this.a=new MD(nFt,this,4)),this.a;case 5:return!this.c&&(this.c=new OD(nFt,this,5)),this.c}return $tn(this,n-iQ((YYn(),T_t)),ern(uG(Lsn(this,16),29)||T_t,n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 3:return this.Cb&&(e=(i=this.Db>>16)>=0?Yjn(this,e):this.Cb.Th(this,-1-i,null,e)),gz(this,uG(n,155),e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),T_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),T_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 2:return!this.b&&(this.b=new XR((YYn(),H_t),wBt,this)),G_(this.b,n,e);case 3:return gz(this,null,e);case 4:return!this.a&&(this.a=new MD(nFt,this,4)),Nyn(this.a,n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),T_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),T_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.d;case 2:return!!this.b&&0!=this.b.f;case 3:return!!F0(this);case 4:return!!this.a&&0!=this.a.i;case 5:return!!this.c&&0!=this.c.i}return l5(this,n-iQ((YYn(),T_t)),ern(uG(Lsn(this,16),29)||T_t,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void xq(this,mK(t));case 2:return!this.b&&(this.b=new XR((YYn(),H_t),wBt,this)),void Jun(this.b,t);case 3:return void kKn(this,uG(t,155));case 4:return!this.a&&(this.a=new MD(nFt,this,4)),Czn(this.a),!this.a&&(this.a=new MD(nFt,this,4)),void CW(this.a,uG(t,16));case 5:return!this.c&&(this.c=new OD(nFt,this,5)),Czn(this.c),!this.c&&(this.c=new OD(nFt,this,5)),void CW(this.c,uG(t,16))}lpn(this,n-iQ((YYn(),T_t)),ern(uG(Lsn(this,16),29)||T_t,n),t)},uZn.ii=function(){return YYn(),T_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void Yan(this,null);case 2:return!this.b&&(this.b=new XR((YYn(),H_t),wBt,this)),void this.b.c.$b();case 3:return void kKn(this,null);case 4:return!this.a&&(this.a=new MD(nFt,this,4)),void Czn(this.a);case 5:return!this.c&&(this.c=new OD(nFt,this,5)),void Czn(this.c)}sdn(this,n-iQ((YYn(),T_t)),ern(uG(Lsn(this,16),29)||T_t,n))},uZn.Ib=function(){return fdn(this)},uZn.d=null,zW(Ytt,"EAnnotationImpl",519),sDn(141,721,urt,ltn),uZn.Gi=function(n,t){qN(this,n,uG(t,44))},uZn.Wk=function(n,t){return U_(this,uG(n,44),t)},uZn.$i=function(n){return uG(uG(this.c,71).$i(n),136)},uZn.Ii=function(){return uG(this.c,71).Ii()},uZn.Ji=function(){return uG(this.c,71).Ji()},uZn.Ki=function(n){return uG(this.c,71).Ki(n)},uZn.Xk=function(n,t){return G_(this,n,t)},uZn.Fk=function(n){return uG(this.c,79).Fk(n)},uZn.ak=function(){},uZn.Qj=function(){return uG(this.c,79).Qj()},uZn.ck=function(n,t,e){var i;return(i=uG(Hrn(this.b).wi().si(this.b),136)).Ci(n),i.Di(t),i.nd(e),i},uZn.dk=function(){return new Vm(this)},uZn.Wb=function(n){Jun(this,n)},uZn.Gk=function(){uG(this.c,79).Gk()},zW(art,"EcoreEMap",141),sDn(165,141,urt,XR),uZn._j=function(){var n,t,e,i,r;if(null==this.d){for(r=Inn(IFt,qit,66,2*this.f+1,0,1),e=this.c.Kc();e.e!=e.i.gc();)!(n=r[i=((t=uG(e.Yj(),136)).Bi()&vZn)%r.length])&&(n=r[i]=new Vm(this)),n.Fc(t);this.d=r}},zW(Ytt,"EAnnotationImpl/1",165),sDn(292,448,{110:1,94:1,93:1,155:1,197:1,58:1,114:1,481:1,54:1,99:1,158:1,292:1,119:1,120:1}),uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return qx(),!!(256&this.Bb);case 3:return qx(),!!(512&this.Bb);case 4:return xwn(this.s);case 5:return xwn(this.t);case 6:return qx(),!!this.Jk();case 7:return qx(),this.s>=1;case 8:return t?bEn(this):this.r;case 9:return this.q}return $tn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 9:return IW(this,e)}return uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().Ak(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!(256&this.Bb);case 3:return!(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return this.Jk();case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yQ(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yQ(this.q).i)}return l5(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.bi=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void this.ui(mK(t));case 2:return void ddn(this,oM(gK(t)));case 3:return void mdn(this,oM(gK(t)));case 4:return void Pcn(this,uG(t,17).a);case 5:return void this.Zk(uG(t,17).a);case 8:return void Kbn(this,uG(t,142));case 9:return void((e=CCn(this,uG(t,89),null))&&e.oj())}lpn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t)},uZn.ii=function(){return YYn(),G_t},uZn.ki=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void this.ui(null);case 2:return void ddn(this,!0);case 3:return void mdn(this,!0);case 4:return void Pcn(this,0);case 5:return void this.Zk(1);case 8:return void Kbn(this,null);case 9:return void((t=CCn(this,null,null))&&t.oj())}sdn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.pi=function(){bEn(this),this.Bb|=1},uZn.Hk=function(){return bEn(this)},uZn.Ik=function(){return this.t},uZn.Jk=function(){var n;return(n=this.t)>1||-1==n},uZn.Si=function(){return!!(512&this.Bb)},uZn.Yk=function(n,t){return Ywn(this,n,t)},uZn.Zk=function(n){Ccn(this,n)},uZn.Ib=function(){return L$n(this)},uZn.s=0,uZn.t=1,zW(Ytt,"ETypedElementImpl",292),sDn(462,292,{110:1,94:1,93:1,155:1,197:1,58:1,179:1,69:1,114:1,481:1,54:1,99:1,158:1,462:1,292:1,119:1,120:1,692:1}),uZn.Ah=function(n){return pjn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return qx(),!!(256&this.Bb);case 3:return qx(),!!(512&this.Bb);case 4:return xwn(this.s);case 5:return xwn(this.t);case 6:return qx(),!!this.Jk();case 7:return qx(),this.s>=1;case 8:return t?bEn(this):this.r;case 9:return this.q;case 10:return qx(),!!(this.Bb&w1n);case 11:return qx(),!!(this.Bb&frt);case 12:return qx(),!!(this.Bb&j0n);case 13:return this.j;case 14:return NRn(this);case 15:return qx(),!!(this.Bb&hrt);case 16:return qx(),!!(this.Bb&VZn);case 17:return K0(this)}return $tn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 17:return this.Cb&&(e=(i=this.Db>>16)>=0?pjn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,17,e)}return uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().zk(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 9:return IW(this,e);case 17:return DUn(this,null,17,e)}return uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().Ak(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!(256&this.Bb);case 3:return!(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return this.Jk();case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yQ(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yQ(this.q).i);case 10:return!(this.Bb&w1n);case 11:return!!(this.Bb&frt);case 12:return!!(this.Bb&j0n);case 13:return null!=this.j;case 14:return null!=NRn(this);case 15:return!!(this.Bb&hrt);case 16:return!!(this.Bb&VZn);case 17:return!!K0(this)}return l5(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.bi=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void g2(this,mK(t));case 2:return void ddn(this,oM(gK(t)));case 3:return void mdn(this,oM(gK(t)));case 4:return void Pcn(this,uG(t,17).a);case 5:return void this.Zk(uG(t,17).a);case 8:return void Kbn(this,uG(t,142));case 9:return void((e=CCn(this,uG(t,89),null))&&e.oj());case 10:return void Wdn(this,oM(gK(t)));case 11:return void Ydn(this,oM(gK(t)));case 12:return void Qdn(this,oM(gK(t)));case 13:return void mA(this,mK(t));case 15:return void Jdn(this,oM(gK(t)));case 16:return void Cgn(this,oM(gK(t)))}lpn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t)},uZn.ii=function(){return YYn(),U_t},uZn.ki=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return F$(this.Cb,90)&&yLn(y9(uG(this.Cb,90)),4),void qon(this,null);case 2:return void ddn(this,!0);case 3:return void mdn(this,!0);case 4:return void Pcn(this,0);case 5:return void this.Zk(1);case 8:return void Kbn(this,null);case 9:return void((t=CCn(this,null,null))&&t.oj());case 10:return void Wdn(this,!0);case 11:return void Ydn(this,!1);case 12:return void Qdn(this,!1);case 13:return this.i=null,void lon(this,null);case 15:return void Jdn(this,!1);case 16:return void Cgn(this,!1)}sdn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.pi=function(){BJ(Nen((gAn(),kBt),this)),bEn(this),this.Bb|=1},uZn.pk=function(){return this.f},uZn.ik=function(){return NRn(this)},uZn.qk=function(){return K0(this)},uZn.uk=function(){return null},uZn.$k=function(){return this.k},uZn.Lj=function(){return this.n},uZn.vk=function(){return qSn(this)},uZn.wk=function(){var n,t,e,i,r,c,a,o,u;return this.p||((null==(e=K0(this)).i&&eqn(e),e.i).length,(i=this.uk())&&iQ(K0(i)),n=(a=(r=bEn(this)).kk())?1&a.i?a==ZHt?cot:a==YHt?dot:a==iUt?lot:a==eUt?fot:a==nUt?yot:a==rUt?Tot:a==tUt?uot:hot:a:null,t=NRn(this),o=r.ik(),Vgn(this),this.Bb&VZn&&((c=cSn((gAn(),kBt),e))&&c!=this||(c=_3(Nen(kBt,this))))?this.p=new SA(this,c):this.Jk()?this.al()?i?this.Bb&hrt?n?this.bl()?this.p=new CY(47,n,this,i):this.p=new CY(5,n,this,i):this.bl()?this.p=new r8(46,this,i):this.p=new r8(4,this,i):n?this.bl()?this.p=new CY(49,n,this,i):this.p=new CY(7,n,this,i):this.bl()?this.p=new r8(48,this,i):this.p=new r8(6,this,i):this.Bb&hrt?n?n==Sat?this.p=new RU(50,gFt,this):this.bl()?this.p=new RU(43,n,this):this.p=new RU(1,n,this):this.bl()?this.p=new GZ(42,this):this.p=new GZ(0,this):n?n==Sat?this.p=new RU(41,gFt,this):this.bl()?this.p=new RU(45,n,this):this.p=new RU(3,n,this):this.bl()?this.p=new GZ(44,this):this.p=new GZ(2,this):F$(r,156)?n==Z_t?this.p=new GZ(40,this):512&this.Bb?this.Bb&hrt?this.p=n?new RU(9,n,this):new GZ(8,this):this.p=n?new RU(11,n,this):new GZ(10,this):this.Bb&hrt?this.p=n?new RU(13,n,this):new GZ(12,this):this.p=n?new RU(15,n,this):new GZ(14,this):i?(u=i.t)>1||-1==u?this.bl()?this.Bb&hrt?this.p=n?new CY(25,n,this,i):new r8(24,this,i):this.p=n?new CY(27,n,this,i):new r8(26,this,i):this.Bb&hrt?this.p=n?new CY(29,n,this,i):new r8(28,this,i):this.p=n?new CY(31,n,this,i):new r8(30,this,i):this.bl()?this.Bb&hrt?this.p=n?new CY(33,n,this,i):new r8(32,this,i):this.p=n?new CY(35,n,this,i):new r8(34,this,i):this.Bb&hrt?this.p=n?new CY(37,n,this,i):new r8(36,this,i):this.p=n?new CY(39,n,this,i):new r8(38,this,i):this.bl()?this.Bb&hrt?this.p=n?new RU(17,n,this):new GZ(16,this):this.p=n?new RU(19,n,this):new GZ(18,this):this.Bb&hrt?this.p=n?new RU(21,n,this):new GZ(20,this):this.p=n?new RU(23,n,this):new GZ(22,this):this._k()?this.bl()?this.p=new KU(uG(r,29),this,i):this.p=new _1(uG(r,29),this,i):F$(r,156)?n==Z_t?this.p=new GZ(40,this):this.Bb&hrt?this.p=n?new bz(t,o,this,(Pmn(),a==YHt?hBt:a==ZHt?cBt:a==nUt?fBt:a==iUt?sBt:a==eUt?uBt:a==rUt?bBt:a==tUt?aBt:a==JHt?oBt:lBt)):new AY(uG(r,156),t,o,this):this.p=n?new lz(t,o,this,(Pmn(),a==YHt?hBt:a==ZHt?cBt:a==nUt?fBt:a==iUt?sBt:a==eUt?uBt:a==rUt?bBt:a==tUt?aBt:a==JHt?oBt:lBt)):new OY(uG(r,156),t,o,this):this.al()?i?this.Bb&hrt?this.bl()?this.p=new GU(uG(r,29),this,i):this.p=new UU(uG(r,29),this,i):this.bl()?this.p=new HU(uG(r,29),this,i):this.p=new FU(uG(r,29),this,i):this.Bb&hrt?this.bl()?this.p=new cK(uG(r,29),this):this.p=new iK(uG(r,29),this):this.bl()?this.p=new eK(uG(r,29),this):this.p=new tK(uG(r,29),this):this.bl()?i?this.Bb&hrt?this.p=new qU(uG(r,29),this,i):this.p=new _U(uG(r,29),this,i):this.Bb&hrt?this.p=new aK(uG(r,29),this):this.p=new rK(uG(r,29),this):i?this.Bb&hrt?this.p=new XU(uG(r,29),this,i):this.p=new BU(uG(r,29),this,i):this.Bb&hrt?this.p=new oK(uG(r,29),this):this.p=new OX(uG(r,29),this)),this.p},uZn.rk=function(){return!!(this.Bb&w1n)},uZn._k=function(){return!1},uZn.al=function(){return!1},uZn.sk=function(){return!!(this.Bb&VZn)},uZn.xk=function(){return ein(this)},uZn.bl=function(){return!1},uZn.tk=function(){return!!(this.Bb&hrt)},uZn.cl=function(n){this.k=n},uZn.ui=function(n){g2(this,n)},uZn.Ib=function(){return MBn(this)},uZn.e=!1,uZn.n=0,zW(Ytt,"EStructuralFeatureImpl",462),sDn(331,462,{110:1,94:1,93:1,35:1,155:1,197:1,58:1,179:1,69:1,114:1,481:1,54:1,99:1,331:1,158:1,462:1,292:1,119:1,120:1,692:1},Wk),uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return qx(),!!(256&this.Bb);case 3:return qx(),!!(512&this.Bb);case 4:return xwn(this.s);case 5:return xwn(this.t);case 6:return qx(),!!SNn(this);case 7:return qx(),this.s>=1;case 8:return t?bEn(this):this.r;case 9:return this.q;case 10:return qx(),!!(this.Bb&w1n);case 11:return qx(),!!(this.Bb&frt);case 12:return qx(),!!(this.Bb&j0n);case 13:return this.j;case 14:return NRn(this);case 15:return qx(),!!(this.Bb&hrt);case 16:return qx(),!!(this.Bb&VZn);case 17:return K0(this);case 18:return qx(),!!(this.Bb&Qtt);case 19:return t?khn(this):E7(this)}return $tn(this,n-iQ((YYn(),j_t)),ern(uG(Lsn(this,16),29)||j_t,n),t,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!(256&this.Bb);case 3:return!(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return SNn(this);case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yQ(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yQ(this.q).i);case 10:return!(this.Bb&w1n);case 11:return!!(this.Bb&frt);case 12:return!!(this.Bb&j0n);case 13:return null!=this.j;case 14:return null!=NRn(this);case 15:return!!(this.Bb&hrt);case 16:return!!(this.Bb&VZn);case 17:return!!K0(this);case 18:return!!(this.Bb&Qtt);case 19:return!!E7(this)}return l5(this,n-iQ((YYn(),j_t)),ern(uG(Lsn(this,16),29)||j_t,n))},uZn.bi=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void g2(this,mK(t));case 2:return void ddn(this,oM(gK(t)));case 3:return void mdn(this,oM(gK(t)));case 4:return void Pcn(this,uG(t,17).a);case 5:return void fj(this,uG(t,17).a);case 8:return void Kbn(this,uG(t,142));case 9:return void((e=CCn(this,uG(t,89),null))&&e.oj());case 10:return void Wdn(this,oM(gK(t)));case 11:return void Ydn(this,oM(gK(t)));case 12:return void Qdn(this,oM(gK(t)));case 13:return void mA(this,mK(t));case 15:return void Jdn(this,oM(gK(t)));case 16:return void Cgn(this,oM(gK(t)));case 18:return void Sgn(this,oM(gK(t)))}lpn(this,n-iQ((YYn(),j_t)),ern(uG(Lsn(this,16),29)||j_t,n),t)},uZn.ii=function(){return YYn(),j_t},uZn.ki=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return F$(this.Cb,90)&&yLn(y9(uG(this.Cb,90)),4),void qon(this,null);case 2:return void ddn(this,!0);case 3:return void mdn(this,!0);case 4:return void Pcn(this,0);case 5:return this.b=0,void Ccn(this,1);case 8:return void Kbn(this,null);case 9:return void((t=CCn(this,null,null))&&t.oj());case 10:return void Wdn(this,!0);case 11:return void Ydn(this,!1);case 12:return void Qdn(this,!1);case 13:return this.i=null,void lon(this,null);case 15:return void Jdn(this,!1);case 16:return void Cgn(this,!1);case 18:return void Sgn(this,!1)}sdn(this,n-iQ((YYn(),j_t)),ern(uG(Lsn(this,16),29)||j_t,n))},uZn.pi=function(){khn(this),BJ(Nen((gAn(),kBt),this)),bEn(this),this.Bb|=1},uZn.Jk=function(){return SNn(this)},uZn.Yk=function(n,t){return this.b=0,this.a=null,Ywn(this,n,t)},uZn.Zk=function(n){fj(this,n)},uZn.Ib=function(){var n;return 64&this.Db?MBn(this):((n=new fx(MBn(this))).a+=" (iD: ",Lj(n,!!(this.Bb&Qtt)),n.a+=")",n.a)},uZn.b=0,zW(Ytt,"EAttributeImpl",331),sDn(364,448,{110:1,94:1,93:1,142:1,155:1,197:1,58:1,114:1,54:1,99:1,364:1,158:1,119:1,120:1,691:1}),uZn.dl=function(n){return n.Dh()==this},uZn.Ah=function(n){return VTn(this,n)},uZn.Bh=function(n,t){this.w=null,this.Db=t<<16|255&this.Db,this.Cb=n},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return _Tn(this);case 4:return this.ik();case 5:return this.F;case 6:return t?Hrn(this):D0(this);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),this.A}return $tn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?VTn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,6,e)}return uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().zk(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 6:return DUn(this,null,6,e);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),Nyn(this.A,n,e)}return uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().Ak(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!_Tn(this);case 4:return null!=this.ik();case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!D0(this);case 7:return!!this.A&&0!=this.A.i}return l5(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void d2(this,mK(t));case 2:return void pN(this,mK(t));case 5:return void TWn(this,mK(t));case 7:return!this.A&&(this.A=new PD(J_t,this,7)),Czn(this.A),!this.A&&(this.A=new PD(J_t,this,7)),void CW(this.A,uG(t,16))}lpn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t)},uZn.ii=function(){return YYn(),S_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return F$(this.Cb,184)&&(uG(this.Cb,184).tb=null),void qon(this,null);case 2:return sbn(this,null),void Ocn(this,this.D);case 5:return void TWn(this,null);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),void Czn(this.A)}sdn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.hk=function(){var n;return-1==this.G&&(this.G=(n=Hrn(this))?Hyn(n.vi(),this):-1),this.G},uZn.ik=function(){return null},uZn.jk=function(){return Hrn(this)},uZn.el=function(){return this.v},uZn.kk=function(){return _Tn(this)},uZn.lk=function(){return null!=this.D?this.D:this.B},uZn.mk=function(){return this.F},uZn.fk=function(n){return LGn(this,n)},uZn.fl=function(n){this.v=n},uZn.gl=function(n){tun(this,n)},uZn.hl=function(n){this.C=n},uZn.ui=function(n){d2(this,n)},uZn.Ib=function(){return pmn(this)},uZn.C=null,uZn.D=null,uZn.G=-1,zW(Ytt,"EClassifierImpl",364),sDn(90,364,{110:1,94:1,93:1,29:1,142:1,155:1,197:1,58:1,114:1,54:1,99:1,90:1,364:1,158:1,482:1,119:1,120:1,691:1},Kl),uZn.dl=function(n){return VF(this,n.Dh())},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return _Tn(this);case 4:return null;case 5:return this.F;case 6:return t?Hrn(this):D0(this);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),this.A;case 8:return qx(),!!(256&this.Bb);case 9:return qx(),!!(512&this.Bb);case 10:return n1(this);case 11:return!this.q&&(this.q=new fV(p_t,this,11,10)),this.q;case 12:return hXn(this);case 13:return Zqn(this);case 14:return Zqn(this),this.r;case 15:return hXn(this),this.k;case 16:return RAn(this);case 17:return $qn(this);case 18:return eqn(this);case 19:return mRn(this);case 20:return hXn(this),this.o;case 21:return!this.s&&(this.s=new fV(o_t,this,21,17)),this.s;case 22:return z5(this);case 23:return x_n(this)}return $tn(this,n-iQ((YYn(),E_t)),ern(uG(Lsn(this,16),29)||E_t,n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?VTn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,6,e);case 11:return!this.q&&(this.q=new fV(p_t,this,11,10)),Nmn(this.q,n,e);case 21:return!this.s&&(this.s=new fV(o_t,this,21,17)),Nmn(this.s,n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),E_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),E_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 6:return DUn(this,null,6,e);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),Nyn(this.A,n,e);case 11:return!this.q&&(this.q=new fV(p_t,this,11,10)),Nyn(this.q,n,e);case 21:return!this.s&&(this.s=new fV(o_t,this,21,17)),Nyn(this.s,n,e);case 22:return Nyn(z5(this),n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),E_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),E_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!_Tn(this);case 4:return!1;case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!D0(this);case 7:return!!this.A&&0!=this.A.i;case 8:return!!(256&this.Bb);case 9:return!!(512&this.Bb);case 10:return!(!this.u||0==z5(this.u.a).i||this.n&&yMn(this.n));case 11:return!!this.q&&0!=this.q.i;case 12:return 0!=hXn(this).i;case 13:return 0!=Zqn(this).i;case 14:return Zqn(this),0!=this.r.i;case 15:return hXn(this),0!=this.k.i;case 16:return 0!=RAn(this).i;case 17:return 0!=$qn(this).i;case 18:return 0!=eqn(this).i;case 19:return 0!=mRn(this).i;case 20:return hXn(this),!!this.o;case 21:return!!this.s&&0!=this.s.i;case 22:return!!this.n&&yMn(this.n);case 23:return 0!=x_n(this).i}return l5(this,n-iQ((YYn(),E_t)),ern(uG(Lsn(this,16),29)||E_t,n))},uZn.Zh=function(n){return(null==this.i||this.q&&0!=this.q.i?null:EKn(this,n))||VQn(this,n)},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void d2(this,mK(t));case 2:return void pN(this,mK(t));case 5:return void TWn(this,mK(t));case 7:return!this.A&&(this.A=new PD(J_t,this,7)),Czn(this.A),!this.A&&(this.A=new PD(J_t,this,7)),void CW(this.A,uG(t,16));case 8:return void gdn(this,oM(gK(t)));case 9:return void vdn(this,oM(gK(t)));case 10:return _zn(n1(this)),void CW(n1(this),uG(t,16));case 11:return!this.q&&(this.q=new fV(p_t,this,11,10)),Czn(this.q),!this.q&&(this.q=new fV(p_t,this,11,10)),void CW(this.q,uG(t,16));case 21:return!this.s&&(this.s=new fV(o_t,this,21,17)),Czn(this.s),!this.s&&(this.s=new fV(o_t,this,21,17)),void CW(this.s,uG(t,16));case 22:return Czn(z5(this)),void CW(z5(this),uG(t,16))}lpn(this,n-iQ((YYn(),E_t)),ern(uG(Lsn(this,16),29)||E_t,n),t)},uZn.ii=function(){return YYn(),E_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return F$(this.Cb,184)&&(uG(this.Cb,184).tb=null),void qon(this,null);case 2:return sbn(this,null),void Ocn(this,this.D);case 5:return void TWn(this,null);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),void Czn(this.A);case 8:return void gdn(this,!1);case 9:return void vdn(this,!1);case 10:return void(this.u&&_zn(this.u));case 11:return!this.q&&(this.q=new fV(p_t,this,11,10)),void Czn(this.q);case 21:return!this.s&&(this.s=new fV(o_t,this,21,17)),void Czn(this.s);case 22:return void(this.n&&Czn(this.n))}sdn(this,n-iQ((YYn(),E_t)),ern(uG(Lsn(this,16),29)||E_t,n))},uZn.pi=function(){var n,t;if(hXn(this),Zqn(this),RAn(this),$qn(this),eqn(this),mRn(this),x_n(this),V9(iG(y9(this))),this.s)for(n=0,t=this.s.i;n=0;--t)zrn(this,t);return gmn(this,n)},uZn.Gk=function(){Czn(this)},uZn.Zi=function(n,t){return Dcn(this,n,t)},zW(art,"EcoreEList",632),sDn(505,632,Trt,FG),uZn.Li=function(){return!1},uZn.Lj=function(){return this.c},uZn.Mj=function(){return!1},uZn.ol=function(){return!0},uZn.Si=function(){return!0},uZn.Wi=function(n,t){return t},uZn.Yi=function(){return!1},uZn.c=0,zW(art,"EObjectEList",505),sDn(83,505,Trt,MD),uZn.Mj=function(){return!0},uZn.ml=function(){return!1},uZn.al=function(){return!0},zW(art,"EObjectContainmentEList",83),sDn(555,83,Trt,TD),uZn.Ni=function(){this.b=!0},uZn.Qj=function(){return this.b},uZn.Gk=function(){var n;Czn(this),uN(this.e)?(n=this.b,this.b=!1,Msn(this.e,new j9(this.e,2,this.c,n,!1))):this.b=!1},uZn.b=!1,zW(art,"EObjectContainmentEList/Unsettable",555),sDn(1161,555,Trt,hz),uZn.Ti=function(n,t){var e,i;return e=uG(zdn(this,n,t),89),uN(this.e)&&Yv(this,new wtn(this.a,7,(YYn(),P_t),xwn(t),F$(i=e.c,90)?uG(i,29):x_t,n)),e},uZn.Uj=function(n,t){return Dmn(this,uG(n,89),t)},uZn.Vj=function(n,t){return $mn(this,uG(n,89),t)},uZn.Wj=function(n,t,e){return TSn(this,uG(n,89),uG(t,89),e)},uZn.Ij=function(n,t,e,i,r){switch(n){case 3:return i2(this,n,t,e,i,this.i>1);case 5:return i2(this,n,t,e,i,this.i-uG(e,15).gc()>0);default:return new Ken(this.e,n,this.c,t,e,i,!0)}},uZn.Tj=function(){return!0},uZn.Qj=function(){return yMn(this)},uZn.Gk=function(){Czn(this)},zW(Ytt,"EClassImpl/1",1161),sDn(1175,1174,Fit),uZn.dj=function(n){var t,e,i,r,c,a,o;if(8!=(e=n.gj())){if(0==(i=xkn(n)))switch(e){case 1:case 9:null!=(o=n.kj())&&(!(t=y9(uG(o,482))).c&&(t.c=new Ks),rin(t.c,n.jj())),null!=(a=n.ij())&&(1&(r=uG(a,482)).Bb||(!(t=y9(r)).c&&(t.c=new Ks),ttn(t.c,uG(n.jj(),29))));break;case 3:null!=(a=n.ij())&&(1&(r=uG(a,482)).Bb||(!(t=y9(r)).c&&(t.c=new Ks),ttn(t.c,uG(n.jj(),29))));break;case 5:if(null!=(a=n.ij()))for(c=uG(a,16).Kc();c.Ob();)1&(r=uG(c.Pb(),482)).Bb||(!(t=y9(r)).c&&(t.c=new Ks),ttn(t.c,uG(n.jj(),29)));break;case 4:null!=(o=n.kj())&&(1&(r=uG(o,482)).Bb||(!(t=y9(r)).c&&(t.c=new Ks),rin(t.c,n.jj())));break;case 6:if(null!=(o=n.kj()))for(c=uG(o,16).Kc();c.Ob();)1&(r=uG(c.Pb(),482)).Bb||(!(t=y9(r)).c&&(t.c=new Ks),rin(t.c,n.jj()))}this.ql(i)}},uZn.ql=function(n){bBn(this,n)},uZn.b=63,zW(Ytt,"ESuperAdapter",1175),sDn(1176,1175,Fit,$m),uZn.ql=function(n){yLn(this,n)},zW(Ytt,"EClassImpl/10",1176),sDn(1165,710,Trt),uZn.Ei=function(n,t){return PCn(this,n,t)},uZn.Fi=function(n){return QMn(this,n)},uZn.Gi=function(n,t){edn(this,n,t)},uZn.Hi=function(n){z9(this,n)},uZn.$i=function(n){return Otn(this,n)},uZn.Xi=function(n,t){return iin(this,n,t)},uZn.Wk=function(n,t){throw hv(new Kv)},uZn.Ii=function(){return new nR(this)},uZn.Ji=function(){return new tR(this)},uZn.Ki=function(n){return han(this,n)},uZn.Xk=function(n,t){throw hv(new Kv)},uZn.Fk=function(n){return this},uZn.Qj=function(){return 0!=this.i},uZn.Wb=function(n){throw hv(new Kv)},uZn.Gk=function(){throw hv(new Kv)},zW(art,"EcoreEList/UnmodifiableEList",1165),sDn(328,1165,Trt,vL),uZn.Yi=function(){return!1},zW(art,"EcoreEList/UnmodifiableEList/FastCompare",328),sDn(1168,328,Trt,Afn),uZn.dd=function(n){var t,e;if(F$(n,179)&&-1!=(t=uG(n,179).Lj()))for(e=this.i;t4){if(!this.fk(n))return!1;if(this.al()){if(a=(t=(e=uG(n,54)).Eh())==this.b&&(this.ml()?e.yh(e.Fh(),uG(ern(e1(this.b),this.Lj()).Hk(),29).kk())==lMn(uG(ern(e1(this.b),this.Lj()),19)).n:-1-e.Fh()==this.Lj()),this.nl()&&!a&&!t&&e.Jh())for(i=0;i1||-1==e)},uZn.ml=function(){var n;return!!F$(n=ern(e1(this.b),this.Lj()),102)&&!!lMn(uG(n,19))},uZn.nl=function(){var n;return!!F$(n=ern(e1(this.b),this.Lj()),102)&&!!(uG(n,19).Bb&P0n)},uZn.dd=function(n){var t,e,i;if((e=this.zj(n))>=0)return e;if(this.ol())for(t=0,i=this.Ej();t=0;--n)yVn(this,n,this.xj(n));return this.Fj()},uZn.Qc=function(n){var t;if(this.nl())for(t=this.Ej()-1;t>=0;--t)yVn(this,t,this.xj(t));return this.Gj(n)},uZn.Gk=function(){_zn(this)},uZn.Zi=function(n,t){return Atn(this,n,t)},zW(art,"DelegatingEcoreEList",756),sDn(1171,756,Crt,aF),uZn.qj=function(n,t){zR(this,n,uG(t,29))},uZn.rj=function(n){BN(this,uG(n,29))},uZn.xj=function(n){var t;return F$(t=uG(zrn(z5(this.a),n),89).c,90)?uG(t,29):(YYn(),x_t)},uZn.Cj=function(n){var t;return F$(t=uG(e_n(z5(this.a),n),89).c,90)?uG(t,29):(YYn(),x_t)},uZn.Dj=function(n,t){return YMn(this,n,uG(t,29))},uZn.Li=function(){return!1},uZn.Ij=function(n,t,e,i,r){return null},uZn.sj=function(){return new Rm(this)},uZn.tj=function(){Czn(z5(this.a))},uZn.uj=function(n){return Mdn(this,n)},uZn.vj=function(n){var t;for(t=n.Kc();t.Ob();)if(!Mdn(this,t.Pb()))return!1;return!0},uZn.wj=function(n){var t,e,i;if(F$(n,15)&&(i=uG(n,15)).gc()==z5(this.a).i){for(t=i.Kc(),e=new DD(this);t.Ob();)if(xA(t.Pb())!==xA(Zkn(e)))return!1;return!0}return!1},uZn.yj=function(){var n,t,e,i;for(t=1,n=new DD(z5(this.a));n.e!=n.i.gc();)t=31*t+((e=F$(i=uG(Zkn(n),89).c,90)?uG(i,29):(YYn(),x_t))?xx(e):0);return t},uZn.zj=function(n){var t,e,i,r;for(i=0,e=new DD(z5(this.a));e.e!=e.i.gc();){if(t=uG(Zkn(e),89),xA(n)===xA(F$(r=t.c,90)?uG(r,29):(YYn(),x_t)))return i;++i}return-1},uZn.Aj=function(){return 0==z5(this.a).i},uZn.Bj=function(){return null},uZn.Ej=function(){return z5(this.a).i},uZn.Fj=function(){var n,t,e,i,r,c;for(c=z5(this.a).i,r=Inn(dat,EZn,1,c,5,1),e=0,t=new DD(z5(this.a));t.e!=t.i.gc();)n=uG(Zkn(t),89),r[e++]=F$(i=n.c,90)?uG(i,29):(YYn(),x_t);return r},uZn.Gj=function(n){var t,e,i,r;for(r=z5(this.a).i,n.lengthr&&uQ(n,r,null),e=0,t=new DD(z5(this.a));t.e!=t.i.gc();)uQ(n,e++,F$(i=uG(Zkn(t),89).c,90)?uG(i,29):(YYn(),x_t));return n},uZn.Hj=function(){var n,t,e,i,r;for((r=new zM).a+="[",n=z5(this.a),t=0,i=z5(this.a).i;t>16)>=0?VTn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,6,e);case 9:return!this.a&&(this.a=new fV(d_t,this,9,5)),Nmn(this.a,n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),I_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),I_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 6:return DUn(this,null,6,e);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),Nyn(this.A,n,e);case 9:return!this.a&&(this.a=new fV(d_t,this,9,5)),Nyn(this.a,n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),I_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),I_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!_Tn(this);case 4:return!!dbn(this);case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!D0(this);case 7:return!!this.A&&0!=this.A.i;case 8:return!(256&this.Bb);case 9:return!!this.a&&0!=this.a.i}return l5(this,n-iQ((YYn(),I_t)),ern(uG(Lsn(this,16),29)||I_t,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void d2(this,mK(t));case 2:return void pN(this,mK(t));case 5:return void TWn(this,mK(t));case 7:return!this.A&&(this.A=new PD(J_t,this,7)),Czn(this.A),!this.A&&(this.A=new PD(J_t,this,7)),void CW(this.A,uG(t,16));case 8:return void pdn(this,oM(gK(t)));case 9:return!this.a&&(this.a=new fV(d_t,this,9,5)),Czn(this.a),!this.a&&(this.a=new fV(d_t,this,9,5)),void CW(this.a,uG(t,16))}lpn(this,n-iQ((YYn(),I_t)),ern(uG(Lsn(this,16),29)||I_t,n),t)},uZn.ii=function(){return YYn(),I_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return F$(this.Cb,184)&&(uG(this.Cb,184).tb=null),void qon(this,null);case 2:return sbn(this,null),void Ocn(this,this.D);case 5:return void TWn(this,null);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),void Czn(this.A);case 8:return void pdn(this,!0);case 9:return!this.a&&(this.a=new fV(d_t,this,9,5)),void Czn(this.a)}sdn(this,n-iQ((YYn(),I_t)),ern(uG(Lsn(this,16),29)||I_t,n))},uZn.pi=function(){var n,t;if(this.a)for(n=0,t=this.a.i;n>16==5?uG(this.Cb,685):null}return $tn(this,n-iQ((YYn(),O_t)),ern(uG(Lsn(this,16),29)||O_t,n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 5:return this.Cb&&(e=(i=this.Db>>16)>=0?Qjn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,5,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),O_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),O_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 5:return DUn(this,null,5,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),O_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),O_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0!=this.d;case 3:return!!this.b;case 4:return null!=this.c;case 5:return!(this.Db>>16!=5||!uG(this.Cb,685))}return l5(this,n-iQ((YYn(),O_t)),ern(uG(Lsn(this,16),29)||O_t,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void qon(this,mK(t));case 2:return void Icn(this,uG(t,17).a);case 3:return void h$n(this,uG(t,2039));case 4:return void Uan(this,mK(t))}lpn(this,n-iQ((YYn(),O_t)),ern(uG(Lsn(this,16),29)||O_t,n),t)},uZn.ii=function(){return YYn(),O_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void qon(this,null);case 2:return void Icn(this,0);case 3:return void h$n(this,null);case 4:return void Uan(this,null)}sdn(this,n-iQ((YYn(),O_t)),ern(uG(Lsn(this,16),29)||O_t,n))},uZn.Ib=function(){var n;return null==(n=this.c)?this.zb:n},uZn.b=null,uZn.c=null,uZn.d=0,zW(Ytt,"EEnumLiteralImpl",582);var nBt,tBt,eBt,iBt=Iq(Ytt,"EFactoryImpl/InternalEDateTimeFormat");sDn(499,1,{2114:1},Km),zW(Ytt,"EFactoryImpl/1ClientInternalEDateTimeFormat",499),sDn(248,120,{110:1,94:1,93:1,89:1,58:1,114:1,54:1,99:1,248:1,119:1,120:1},ev),uZn.Ch=function(n,t,e){var i;return e=DUn(this,n,t,e),this.e&&F$(n,179)&&(i=bRn(this,this.e))!=this.c&&(e=PWn(this,i,e)),e},uZn.Lh=function(n,t,e){switch(n){case 0:return this.f;case 1:return!this.d&&(this.d=new MD(g_t,this,1)),this.d;case 2:return t?MGn(this):this.c;case 3:return this.b;case 4:return this.e;case 5:return t?PMn(this):this.a}return $tn(this,n-iQ((YYn(),L_t)),ern(uG(Lsn(this,16),29)||L_t,n),t,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return vwn(this,null,e);case 1:return!this.d&&(this.d=new MD(g_t,this,1)),Nyn(this.d,n,e);case 3:return kwn(this,null,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),L_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),L_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.f;case 1:return!!this.d&&0!=this.d.i;case 2:return!!this.c;case 3:return!!this.b;case 4:return!!this.e;case 5:return!!this.a}return l5(this,n-iQ((YYn(),L_t)),ern(uG(Lsn(this,16),29)||L_t,n))},uZn.bi=function(n,t){switch(n){case 0:return void cPn(this,uG(t,89));case 1:return!this.d&&(this.d=new MD(g_t,this,1)),Czn(this.d),!this.d&&(this.d=new MD(g_t,this,1)),void CW(this.d,uG(t,16));case 3:return void rPn(this,uG(t,89));case 4:return void MIn(this,uG(t,850));case 5:return void Urn(this,uG(t,142))}lpn(this,n-iQ((YYn(),L_t)),ern(uG(Lsn(this,16),29)||L_t,n),t)},uZn.ii=function(){return YYn(),L_t},uZn.ki=function(n){switch(n){case 0:return void cPn(this,null);case 1:return!this.d&&(this.d=new MD(g_t,this,1)),void Czn(this.d);case 3:return void rPn(this,null);case 4:return void MIn(this,null);case 5:return void Urn(this,null)}sdn(this,n-iQ((YYn(),L_t)),ern(uG(Lsn(this,16),29)||L_t,n))},uZn.Ib=function(){var n;return(n=new lx(vxn(this))).a+=" (expression: ",XXn(this,n),n.a+=")",n.a},zW(Ytt,"EGenericTypeImpl",248),sDn(2067,2062,Irt),uZn.Gi=function(n,t){YK(this,n,t)},uZn.Wk=function(n,t){return YK(this,this.gc(),n),t},uZn.$i=function(n){return hyn(this.pj(),n)},uZn.Ii=function(){return this.Ji()},uZn.pj=function(){return new zm(this)},uZn.Ji=function(){return this.Ki(0)},uZn.Ki=function(n){return this.pj().fd(n)},uZn.Xk=function(n,t){return Wpn(this,n,!0),t},uZn.Ti=function(n,t){var e;return e=Kjn(this,t),this.fd(n).Rb(e),e},uZn.Ui=function(n,t){Wpn(this,t,!0),this.fd(n).Rb(t)},zW(art,"AbstractSequentialInternalEList",2067),sDn(496,2067,Irt,zx),uZn.$i=function(n){return hyn(this.pj(),n)},uZn.Ii=function(){return null==this.b?(EP(),EP(),eBt):this.sl()},uZn.pj=function(){return new kL(this.a,this.b)},uZn.Ji=function(){return null==this.b?(EP(),EP(),eBt):this.sl()},uZn.Ki=function(n){var t,e;if(null==this.b){if(n<0||n>1)throw hv(new dM(Hit+n+", size=0"));return EP(),EP(),eBt}for(e=this.sl(),t=0;t0;)if(t=this.c[--this.d],(!this.e||t.pk()!=tFt||0!=t.Lj())&&(!this.vl()||this.b.Xh(t)))if(c=this.b.Nh(t,this.ul()),this.f=(PP(),uG(t,69).xk()),this.f||t.Jk()){if(this.ul()?(i=uG(c,15),this.k=i):(i=uG(c,71),this.k=this.j=i),F$(this.k,59)?(this.o=this.k.gc(),this.n=this.o):this.p=this.j?this.j.Ki(this.k.gc()):this.k.fd(this.k.gc()),this.p?dAn(this,this.p):hLn(this))return r=this.p?this.p.Ub():this.j?this.j.$i(--this.n):this.k.Xb(--this.n),this.f?((n=uG(r,76)).Lk(),e=n.md(),this.i=e):(e=r,this.i=e),this.g=-3,!0}else if(null!=c)return this.k=null,this.p=null,e=c,this.i=e,this.g=-2,!0;return this.k=null,this.p=null,this.g=-1,!1}},uZn.Pb=function(){return Ksn(this)},uZn.Tb=function(){return this.a},uZn.Ub=function(){var n;if(this.g<-1||this.Sb())return--this.a,this.g=0,n=this.i,this.Sb(),n;throw hv(new Bv)},uZn.Vb=function(){return this.a-1},uZn.Qb=function(){throw hv(new Kv)},uZn.ul=function(){return!1},uZn.Wb=function(n){throw hv(new Kv)},uZn.vl=function(){return!0},uZn.a=0,uZn.d=0,uZn.f=!1,uZn.g=0,uZn.n=0,uZn.o=0,zW(art,"EContentsEList/FeatureIteratorImpl",287),sDn(711,287,Ort,WR),uZn.ul=function(){return!0},zW(art,"EContentsEList/ResolvingFeatureIteratorImpl",711),sDn(1178,711,Ort,QR),uZn.vl=function(){return!1},zW(Ytt,"ENamedElementImpl/1/1",1178),sDn(1179,287,Ort,JR),uZn.vl=function(){return!1},zW(Ytt,"ENamedElementImpl/1/2",1179),sDn(39,152,Bit,t8,e8,lV,btn,Ken,j9,Bcn,o4,Hcn,u4,E9,s4,qcn,h4,S9,f4,Ucn,l4,bV,wtn,kZ,Gcn,b4,P9,w4),uZn.Kj=function(){return ntn(this)},uZn.Rj=function(){var n;return(n=ntn(this))?n.ik():null},uZn.hj=function(n){return-1==this.b&&this.a&&(this.b=this.c.Hh(this.a.Lj(),this.a.pk())),this.c.yh(this.b,n)},uZn.jj=function(){return this.c},uZn.Sj=function(){var n;return!!(n=ntn(this))&&n.tk()},uZn.b=-1,zW(Ytt,"ENotificationImpl",39),sDn(411,292,{110:1,94:1,93:1,155:1,197:1,58:1,62:1,114:1,481:1,54:1,99:1,158:1,411:1,292:1,119:1,120:1},Yk),uZn.Ah=function(n){return fEn(this,n)},uZn.Lh=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return qx(),!!(256&this.Bb);case 3:return qx(),!!(512&this.Bb);case 4:return xwn(this.s);case 5:return xwn(this.t);case 6:return qx(),(i=this.t)>1||-1==i;case 7:return qx(),this.s>=1;case 8:return t?bEn(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?uG(this.Cb,29):null;case 11:return!this.d&&(this.d=new PD(J_t,this,11)),this.d;case 12:return!this.c&&(this.c=new fV(m_t,this,12,10)),this.c;case 13:return!this.a&&(this.a=new oF(this,this)),this.a;case 14:return Aen(this)}return $tn(this,n-iQ((YYn(),R_t)),ern(uG(Lsn(this,16),29)||R_t,n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 10:return this.Cb&&(e=(i=this.Db>>16)>=0?fEn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,10,e);case 12:return!this.c&&(this.c=new fV(m_t,this,12,10)),Nmn(this.c,n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),R_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),R_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 9:return IW(this,e);case 10:return DUn(this,null,10,e);case 11:return!this.d&&(this.d=new PD(J_t,this,11)),Nyn(this.d,n,e);case 12:return!this.c&&(this.c=new fV(m_t,this,12,10)),Nyn(this.c,n,e);case 14:return Nyn(Aen(this),n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),R_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),R_t)),n,e)},uZn.Wh=function(n){var t;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!(256&this.Bb);case 3:return!(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(t=this.t)>1||-1==t;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yQ(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yQ(this.q).i);case 10:return!(this.Db>>16!=10||!uG(this.Cb,29));case 11:return!!this.d&&0!=this.d.i;case 12:return!!this.c&&0!=this.c.i;case 13:return!(!this.a||0==Aen(this.a.a).i||this.b&&MMn(this.b));case 14:return!!this.b&&MMn(this.b)}return l5(this,n-iQ((YYn(),R_t)),ern(uG(Lsn(this,16),29)||R_t,n))},uZn.bi=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void qon(this,mK(t));case 2:return void ddn(this,oM(gK(t)));case 3:return void mdn(this,oM(gK(t)));case 4:return void Pcn(this,uG(t,17).a);case 5:return void Ccn(this,uG(t,17).a);case 8:return void Kbn(this,uG(t,142));case 9:return void((e=CCn(this,uG(t,89),null))&&e.oj());case 11:return!this.d&&(this.d=new PD(J_t,this,11)),Czn(this.d),!this.d&&(this.d=new PD(J_t,this,11)),void CW(this.d,uG(t,16));case 12:return!this.c&&(this.c=new fV(m_t,this,12,10)),Czn(this.c),!this.c&&(this.c=new fV(m_t,this,12,10)),void CW(this.c,uG(t,16));case 13:return!this.a&&(this.a=new oF(this,this)),_zn(this.a),!this.a&&(this.a=new oF(this,this)),void CW(this.a,uG(t,16));case 14:return Czn(Aen(this)),void CW(Aen(this),uG(t,16))}lpn(this,n-iQ((YYn(),R_t)),ern(uG(Lsn(this,16),29)||R_t,n),t)},uZn.ii=function(){return YYn(),R_t},uZn.ki=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void qon(this,null);case 2:return void ddn(this,!0);case 3:return void mdn(this,!0);case 4:return void Pcn(this,0);case 5:return void Ccn(this,1);case 8:return void Kbn(this,null);case 9:return void((t=CCn(this,null,null))&&t.oj());case 11:return!this.d&&(this.d=new PD(J_t,this,11)),void Czn(this.d);case 12:return!this.c&&(this.c=new fV(m_t,this,12,10)),void Czn(this.c);case 13:return void(this.a&&_zn(this.a));case 14:return void(this.b&&Czn(this.b))}sdn(this,n-iQ((YYn(),R_t)),ern(uG(Lsn(this,16),29)||R_t,n))},uZn.pi=function(){var n,t;if(this.c)for(n=0,t=this.c.i;ni&&uQ(n,i,null),e=0,t=new DD(Aen(this.a));t.e!=t.i.gc();)uQ(n,e++,uG(Zkn(t),89).c||(YYn(),N_t));return n},uZn.Hj=function(){var n,t,e,i;for((i=new zM).a+="[",n=Aen(this.a),t=0,e=Aen(this.a).i;t1);case 5:return i2(this,n,t,e,i,this.i-uG(e,15).gc()>0);default:return new Ken(this.e,n,this.c,t,e,i,!0)}},uZn.Tj=function(){return!0},uZn.Qj=function(){return MMn(this)},uZn.Gk=function(){Czn(this)},zW(Ytt,"EOperationImpl/2",1377),sDn(507,1,{2037:1,507:1},EA),zW(Ytt,"EPackageImpl/1",507),sDn(14,83,Trt,fV),uZn.il=function(){return this.d},uZn.jl=function(){return this.b},uZn.ml=function(){return!0},uZn.b=0,zW(art,"EObjectContainmentWithInverseEList",14),sDn(365,14,Trt,i_),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectContainmentWithInverseEList/Resolving",365),sDn(308,365,Trt,vV),uZn.Ni=function(){this.a.tb=null},zW(Ytt,"EPackageImpl/2",308),sDn(1278,1,{},Ps),zW(Ytt,"EPackageImpl/3",1278),sDn(733,45,B0n,Zk),uZn._b=function(n){return RA(n)?AZ(this,n):!!FX(this.f,n)},zW(Ytt,"EPackageRegistryImpl",733),sDn(518,292,{110:1,94:1,93:1,155:1,197:1,58:1,2116:1,114:1,481:1,54:1,99:1,158:1,518:1,292:1,119:1,120:1},ny),uZn.Ah=function(n){return lEn(this,n)},uZn.Lh=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return qx(),!!(256&this.Bb);case 3:return qx(),!!(512&this.Bb);case 4:return xwn(this.s);case 5:return xwn(this.t);case 6:return qx(),(i=this.t)>1||-1==i;case 7:return qx(),this.s>=1;case 8:return t?bEn(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?uG(this.Cb,62):null}return $tn(this,n-iQ((YYn(),__t)),ern(uG(Lsn(this,16),29)||__t,n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 10:return this.Cb&&(e=(i=this.Db>>16)>=0?lEn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,10,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),__t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),__t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 9:return IW(this,e);case 10:return DUn(this,null,10,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),__t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),__t)),n,e)},uZn.Wh=function(n){var t;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!(256&this.Bb);case 3:return!(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(t=this.t)>1||-1==t;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yQ(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yQ(this.q).i);case 10:return!(this.Db>>16!=10||!uG(this.Cb,62))}return l5(this,n-iQ((YYn(),__t)),ern(uG(Lsn(this,16),29)||__t,n))},uZn.ii=function(){return YYn(),__t},zW(Ytt,"EParameterImpl",518),sDn(102,462,{110:1,94:1,93:1,155:1,197:1,58:1,19:1,179:1,69:1,114:1,481:1,54:1,99:1,158:1,102:1,462:1,292:1,119:1,120:1,692:1},PK),uZn.Lh=function(n,t,e){var i,r;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return qx(),!!(256&this.Bb);case 3:return qx(),!!(512&this.Bb);case 4:return xwn(this.s);case 5:return xwn(this.t);case 6:return qx(),(r=this.t)>1||-1==r;case 7:return qx(),this.s>=1;case 8:return t?bEn(this):this.r;case 9:return this.q;case 10:return qx(),!!(this.Bb&w1n);case 11:return qx(),!!(this.Bb&frt);case 12:return qx(),!!(this.Bb&j0n);case 13:return this.j;case 14:return NRn(this);case 15:return qx(),!!(this.Bb&hrt);case 16:return qx(),!!(this.Bb&VZn);case 17:return K0(this);case 18:return qx(),!!(this.Bb&Qtt);case 19:return qx(),!!((i=lMn(this))&&i.Bb&Qtt);case 20:return qx(),!!(this.Bb&P0n);case 21:return t?lMn(this):this.b;case 22:return t?Ffn(this):R9(this);case 23:return!this.a&&(this.a=new OD(u_t,this,23)),this.a}return $tn(this,n-iQ((YYn(),B_t)),ern(uG(Lsn(this,16),29)||B_t,n),t,e)},uZn.Wh=function(n){var t,e;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!(256&this.Bb);case 3:return!(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(e=this.t)>1||-1==e;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yQ(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yQ(this.q).i);case 10:return!(this.Bb&w1n);case 11:return!!(this.Bb&frt);case 12:return!!(this.Bb&j0n);case 13:return null!=this.j;case 14:return null!=NRn(this);case 15:return!!(this.Bb&hrt);case 16:return!!(this.Bb&VZn);case 17:return!!K0(this);case 18:return!!(this.Bb&Qtt);case 19:return!!(t=lMn(this))&&!!(t.Bb&Qtt);case 20:return!(this.Bb&P0n);case 21:return!!this.b;case 22:return!!R9(this);case 23:return!!this.a&&0!=this.a.i}return l5(this,n-iQ((YYn(),B_t)),ern(uG(Lsn(this,16),29)||B_t,n))},uZn.bi=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void g2(this,mK(t));case 2:return void ddn(this,oM(gK(t)));case 3:return void mdn(this,oM(gK(t)));case 4:return void Pcn(this,uG(t,17).a);case 5:return void Ccn(this,uG(t,17).a);case 8:return void Kbn(this,uG(t,142));case 9:return void((e=CCn(this,uG(t,89),null))&&e.oj());case 10:return void Wdn(this,oM(gK(t)));case 11:return void Ydn(this,oM(gK(t)));case 12:return void Qdn(this,oM(gK(t)));case 13:return void mA(this,mK(t));case 15:return void Jdn(this,oM(gK(t)));case 16:return void Cgn(this,oM(gK(t)));case 18:return void p2(this,oM(gK(t)));case 20:return void Ign(this,oM(gK(t)));case 21:return void bon(this,uG(t,19));case 23:return!this.a&&(this.a=new OD(u_t,this,23)),Czn(this.a),!this.a&&(this.a=new OD(u_t,this,23)),void CW(this.a,uG(t,16))}lpn(this,n-iQ((YYn(),B_t)),ern(uG(Lsn(this,16),29)||B_t,n),t)},uZn.ii=function(){return YYn(),B_t},uZn.ki=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return F$(this.Cb,90)&&yLn(y9(uG(this.Cb,90)),4),void qon(this,null);case 2:return void ddn(this,!0);case 3:return void mdn(this,!0);case 4:return void Pcn(this,0);case 5:return void Ccn(this,1);case 8:return void Kbn(this,null);case 9:return void((t=CCn(this,null,null))&&t.oj());case 10:return void Wdn(this,!0);case 11:return void Ydn(this,!1);case 12:return void Qdn(this,!1);case 13:return this.i=null,void lon(this,null);case 15:return void Jdn(this,!1);case 16:return void Cgn(this,!1);case 18:return Pgn(this,!1),void(F$(this.Cb,90)&&yLn(y9(uG(this.Cb,90)),2));case 20:return void Ign(this,!0);case 21:return void bon(this,null);case 23:return!this.a&&(this.a=new OD(u_t,this,23)),void Czn(this.a)}sdn(this,n-iQ((YYn(),B_t)),ern(uG(Lsn(this,16),29)||B_t,n))},uZn.pi=function(){Ffn(this),BJ(Nen((gAn(),kBt),this)),bEn(this),this.Bb|=1},uZn.uk=function(){return lMn(this)},uZn._k=function(){var n;return!!(n=lMn(this))&&!!(n.Bb&Qtt)},uZn.al=function(){return!!(this.Bb&Qtt)},uZn.bl=function(){return!!(this.Bb&P0n)},uZn.Yk=function(n,t){return this.c=null,Ywn(this,n,t)},uZn.Ib=function(){var n;return 64&this.Db?MBn(this):((n=new fx(MBn(this))).a+=" (containment: ",Lj(n,!!(this.Bb&Qtt)),n.a+=", resolveProxies: ",Lj(n,!!(this.Bb&P0n)),n.a+=")",n.a)},zW(Ytt,"EReferenceImpl",102),sDn(561,120,{110:1,44:1,94:1,93:1,136:1,58:1,114:1,54:1,99:1,561:1,119:1,120:1},Cs),uZn.Fb=function(n){return this===n},uZn.ld=function(){return this.b},uZn.md=function(){return this.c},uZn.Hb=function(){return xx(this)},uZn.Di=function(n){Rq(this,mK(n))},uZn.nd=function(n){return DG(this,mK(n))},uZn.Lh=function(n,t,e){switch(n){case 0:return this.b;case 1:return this.c}return $tn(this,n-iQ((YYn(),H_t)),ern(uG(Lsn(this,16),29)||H_t,n),t,e)},uZn.Wh=function(n){switch(n){case 0:return null!=this.b;case 1:return null!=this.c}return l5(this,n-iQ((YYn(),H_t)),ern(uG(Lsn(this,16),29)||H_t,n))},uZn.bi=function(n,t){switch(n){case 0:return void Kq(this,mK(t));case 1:return void Jan(this,mK(t))}lpn(this,n-iQ((YYn(),H_t)),ern(uG(Lsn(this,16),29)||H_t,n),t)},uZn.ii=function(){return YYn(),H_t},uZn.ki=function(n){switch(n){case 0:return void Qan(this,null);case 1:return void Jan(this,null)}sdn(this,n-iQ((YYn(),H_t)),ern(uG(Lsn(this,16),29)||H_t,n))},uZn.Bi=function(){var n;return-1==this.a&&(n=this.b,this.a=null==n?0:pln(n)),this.a},uZn.Ci=function(n){this.a=n},uZn.Ib=function(){var n;return 64&this.Db?vxn(this):((n=new fx(vxn(this))).a+=" (key: ",VA(n,this.b),n.a+=", value: ",VA(n,this.c),n.a+=")",n.a)},uZn.a=-1,uZn.b=null,uZn.c=null;var rBt,cBt,aBt,oBt,uBt,sBt,hBt,fBt,lBt,bBt,wBt=zW(Ytt,"EStringToStringMapEntryImpl",561),dBt=Iq(art,"FeatureMap/Entry/Internal");sDn(576,1,Art),uZn.xl=function(n){return this.yl(uG(n,54))},uZn.yl=function(n){return this.xl(n)},uZn.Fb=function(n){var t,e;return this===n||!!F$(n,76)&&(t=uG(n,76)).Lk()==this.c&&(null==(e=this.md())?null==t.md():udn(e,t.md()))},uZn.Lk=function(){return this.c},uZn.Hb=function(){var n;return n=this.md(),Hon(this.c)^(null==n?0:Hon(n))},uZn.Ib=function(){var n,t;return t=Hrn((n=this.c).qk()).yi(),n.xe(),(null!=t&&0!=t.length?t+":"+n.xe():n.xe())+"="+this.md()},zW(Ytt,"EStructuralFeatureImpl/BasicFeatureMapEntry",576),sDn(791,576,Art,sF),uZn.yl=function(n){return new sF(this.c,n)},uZn.md=function(){return this.a},uZn.zl=function(n,t,e){return Kun(this,n,this.a,t,e)},uZn.Al=function(n,t,e){return Fun(this,n,this.a,t,e)},zW(Ytt,"EStructuralFeatureImpl/ContainmentUpdatingFeatureMapEntry",791),sDn(1350,1,{},SA),uZn.yk=function(n,t,e,i,r){return uG(vtn(n,this.b),220).Yl(this.a).Fk(i)},uZn.zk=function(n,t,e,i,r){return uG(vtn(n,this.b),220).Pl(this.a,i,r)},uZn.Ak=function(n,t,e,i,r){return uG(vtn(n,this.b),220).Ql(this.a,i,r)},uZn.Bk=function(n,t,e){return uG(vtn(n,this.b),220).Yl(this.a).Qj()},uZn.Ck=function(n,t,e,i){uG(vtn(n,this.b),220).Yl(this.a).Wb(i)},uZn.Dk=function(n,t,e){return uG(vtn(n,this.b),220).Yl(this.a)},uZn.Ek=function(n,t,e){uG(vtn(n,this.b),220).Yl(this.a).Gk()},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateFeatureMapDelegator",1350),sDn(91,1,{},RU,CY,GZ,r8),uZn.yk=function(n,t,e,i,r){var c;if(null==(c=t.li(e))&&t.mi(e,c=xYn(this,n)),!r)switch(this.e){case 50:case 41:return uG(c,597).bk();case 40:return uG(c,220).Vl()}return c},uZn.zk=function(n,t,e,i,r){var c;return null==(c=t.li(e))&&t.mi(e,c=xYn(this,n)),uG(c,71).Wk(i,r)},uZn.Ak=function(n,t,e,i,r){var c;return null!=(c=t.li(e))&&(r=uG(c,71).Xk(i,r)),r},uZn.Bk=function(n,t,e){var i;return null!=(i=t.li(e))&&uG(i,79).Qj()},uZn.Ck=function(n,t,e,i){var r;!(r=uG(t.li(e),79))&&t.mi(e,r=xYn(this,n)),r.Wb(i)},uZn.Dk=function(n,t,e){var i;return null==(i=t.li(e))&&t.mi(e,i=xYn(this,n)),F$(i,79)?uG(i,79):new _m(uG(t.li(e),15))},uZn.Ek=function(n,t,e){var i;!(i=uG(t.li(e),79))&&t.mi(e,i=xYn(this,n)),i.Gk()},uZn.b=0,uZn.e=0,zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateMany",91),sDn(512,1,{}),uZn.zk=function(n,t,e,i,r){throw hv(new Kv)},uZn.Ak=function(n,t,e,i,r){throw hv(new Kv)},uZn.Dk=function(n,t,e){return new IY(this,n,t,e)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingle",512),sDn(1367,1,ort,IY),uZn.Fk=function(n){return this.a.yk(this.c,this.d,this.b,n,!0)},uZn.Qj=function(){return this.a.Bk(this.c,this.d,this.b)},uZn.Wb=function(n){this.a.Ck(this.c,this.d,this.b,n)},uZn.Gk=function(){this.a.Ek(this.c,this.d,this.b)},uZn.b=0,zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingle/1",1367),sDn(784,512,{},_1),uZn.yk=function(n,t,e,i,r){return PHn(n,n.Ph(),n.Fh())==this.b?this.bl()&&i?J$n(n):n.Ph():null},uZn.zk=function(n,t,e,i,r){var c,a;return n.Ph()&&(r=(c=n.Fh())>=0?n.Ah(r):n.Ph().Th(n,-1-c,null,r)),a=emn(n.Dh(),this.e),n.Ch(i,a,r)},uZn.Ak=function(n,t,e,i,r){var c;return c=emn(n.Dh(),this.e),n.Ch(null,c,r)},uZn.Bk=function(n,t,e){var i;return i=emn(n.Dh(),this.e),!!n.Ph()&&n.Fh()==i},uZn.Ck=function(n,t,e,i){var r,c,a,o,u;if(null!=i&&!LGn(this.a,i))throw hv(new mM(Lrt+(F$(i,58)?nPn(uG(i,58).Dh()):crn(Tbn(i)))+Nrt+this.a+"'"));if(r=n.Ph(),a=emn(n.Dh(),this.e),xA(i)!==xA(r)||n.Fh()!=a&&null!=i){if(eEn(n,uG(i,58)))throw hv(new vM(net+n.Ib()));u=null,r&&(u=(c=n.Fh())>=0?n.Ah(u):n.Ph().Th(n,-1-c,null,u)),(o=uG(i,54))&&(u=o.Rh(n,emn(o.Dh(),this.b),null,u)),(u=n.Ch(o,a,u))&&u.oj()}else n.vh()&&n.wh()&&Msn(n,new lV(n,1,a,i,i))},uZn.Ek=function(n,t,e){var i,r,c;n.Ph()?(c=(i=n.Fh())>=0?n.Ah(null):n.Ph().Th(n,-1-i,null,null),r=emn(n.Dh(),this.e),(c=n.Ch(null,r,c))&&c.oj()):n.vh()&&n.wh()&&Msn(n,new bV(n,1,this.e,null,null))},uZn.bl=function(){return!1},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainer",784),sDn(1351,784,{},KU),uZn.bl=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainerResolving",1351),sDn(574,512,{}),uZn.yk=function(n,t,e,i,r){var c;return null==(c=t.li(e))?this.b:xA(c)===xA(rBt)?null:c},uZn.Bk=function(n,t,e){var i;return null!=(i=t.li(e))&&(xA(i)===xA(rBt)||!udn(i,this.b))},uZn.Ck=function(n,t,e,i){var r,c;n.vh()&&n.wh()?(r=null==(c=t.li(e))?this.b:xA(c)===xA(rBt)?null:c,null==i?null!=this.c?(t.mi(e,null),i=this.b):null!=this.b?t.mi(e,rBt):t.mi(e,null):(this.Bl(i),t.mi(e,i)),Msn(n,this.d.Cl(n,1,this.e,r,i))):null==i?null!=this.c?t.mi(e,null):null!=this.b?t.mi(e,rBt):t.mi(e,null):(this.Bl(i),t.mi(e,i))},uZn.Ek=function(n,t,e){var i,r;n.vh()&&n.wh()?(i=null==(r=t.li(e))?this.b:xA(r)===xA(rBt)?null:r,t.ni(e),Msn(n,this.d.Cl(n,1,this.e,i,this.b))):t.ni(e)},uZn.Bl=function(n){throw hv(new $v)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData",574),sDn($rt,1,{},Is),uZn.Cl=function(n,t,e,i,r){return new bV(n,t,e,i,r)},uZn.Dl=function(n,t,e,i,r,c){return new kZ(n,t,e,i,r,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator",$rt),sDn(1368,$rt,{},Os),uZn.Cl=function(n,t,e,i,r){return new P9(n,t,e,oM(gK(i)),oM(gK(r)))},uZn.Dl=function(n,t,e,i,r,c){return new w4(n,t,e,oM(gK(i)),oM(gK(r)),c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/1",1368),sDn(1369,$rt,{},As),uZn.Cl=function(n,t,e,i,r){return new Bcn(n,t,e,uG(i,222).a,uG(r,222).a)},uZn.Dl=function(n,t,e,i,r,c){return new o4(n,t,e,uG(i,222).a,uG(r,222).a,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/2",1369),sDn(1370,$rt,{},Ls),uZn.Cl=function(n,t,e,i,r){return new Hcn(n,t,e,uG(i,180).a,uG(r,180).a)},uZn.Dl=function(n,t,e,i,r,c){return new u4(n,t,e,uG(i,180).a,uG(r,180).a,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/3",1370),sDn(1371,$rt,{},Ns),uZn.Cl=function(n,t,e,i,r){return new E9(n,t,e,uM(pK(i)),uM(pK(r)))},uZn.Dl=function(n,t,e,i,r,c){return new s4(n,t,e,uM(pK(i)),uM(pK(r)),c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/4",1371),sDn(1372,$rt,{},$s),uZn.Cl=function(n,t,e,i,r){return new qcn(n,t,e,uG(i,161).a,uG(r,161).a)},uZn.Dl=function(n,t,e,i,r,c){return new h4(n,t,e,uG(i,161).a,uG(r,161).a,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/5",1372),sDn(1373,$rt,{},Ds),uZn.Cl=function(n,t,e,i,r){return new S9(n,t,e,uG(i,17).a,uG(r,17).a)},uZn.Dl=function(n,t,e,i,r,c){return new f4(n,t,e,uG(i,17).a,uG(r,17).a,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/6",1373),sDn(1374,$rt,{},xs),uZn.Cl=function(n,t,e,i,r){return new Ucn(n,t,e,uG(i,168).a,uG(r,168).a)},uZn.Dl=function(n,t,e,i,r,c){return new l4(n,t,e,uG(i,168).a,uG(r,168).a,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/7",1374),sDn(1375,$rt,{},Rs),uZn.Cl=function(n,t,e,i,r){return new Gcn(n,t,e,uG(i,191).a,uG(r,191).a)},uZn.Dl=function(n,t,e,i,r,c){return new b4(n,t,e,uG(i,191).a,uG(r,191).a,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/8",1375),sDn(1353,574,{},OY),uZn.Bl=function(n){if(!this.a.fk(n))throw hv(new mM(Lrt+Tbn(n)+Nrt+this.a+"'"))},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataDynamic",1353),sDn(1354,574,{},lz),uZn.Bl=function(n){},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataStatic",1354),sDn(785,574,{}),uZn.Bk=function(n,t,e){return null!=t.li(e)},uZn.Ck=function(n,t,e,i){var r,c;n.vh()&&n.wh()?(r=!0,null==(c=t.li(e))?(r=!1,c=this.b):xA(c)===xA(rBt)&&(c=null),null==i?null!=this.c?(t.mi(e,null),i=this.b):t.mi(e,rBt):(this.Bl(i),t.mi(e,i)),Msn(n,this.d.Dl(n,1,this.e,c,i,!r))):null==i?null!=this.c?t.mi(e,null):t.mi(e,rBt):(this.Bl(i),t.mi(e,i))},uZn.Ek=function(n,t,e){var i,r;n.vh()&&n.wh()?(i=!0,null==(r=t.li(e))?(i=!1,r=this.b):xA(r)===xA(rBt)&&(r=null),t.ni(e),Msn(n,this.d.Dl(n,2,this.e,r,this.b,i))):t.ni(e)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettable",785),sDn(1355,785,{},AY),uZn.Bl=function(n){if(!this.a.fk(n))throw hv(new mM(Lrt+Tbn(n)+Nrt+this.a+"'"))},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableDynamic",1355),sDn(1356,785,{},bz),uZn.Bl=function(n){},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableStatic",1356),sDn(410,512,{},OX),uZn.yk=function(n,t,e,i,r){var c,a,o,u,s;if(s=t.li(e),this.tk()&&xA(s)===xA(rBt))return null;if(this.bl()&&i&&null!=s){if((o=uG(s,54)).Vh()&&o!=(u=mwn(n,o))){if(!LGn(this.a,u))throw hv(new mM(Lrt+Tbn(u)+Nrt+this.a+"'"));t.mi(e,s=u),this.al()&&(c=uG(u,54),a=o.Th(n,this.b?emn(o.Dh(),this.b):-1-emn(n.Dh(),this.e),null,null),!c.Ph()&&(a=c.Rh(n,this.b?emn(c.Dh(),this.b):-1-emn(n.Dh(),this.e),null,a)),a&&a.oj()),n.vh()&&n.wh()&&Msn(n,new bV(n,9,this.e,o,u))}return s}return s},uZn.zk=function(n,t,e,i,r){var c,a;return xA(a=t.li(e))===xA(rBt)&&(a=null),t.mi(e,i),this.Mj()?xA(a)!==xA(i)&&null!=a&&(r=(c=uG(a,54)).Th(n,emn(c.Dh(),this.b),null,r)):this.al()&&null!=a&&(r=uG(a,54).Th(n,-1-emn(n.Dh(),this.e),null,r)),n.vh()&&n.wh()&&(!r&&(r=new cj(4)),r.nj(new bV(n,1,this.e,a,i))),r},uZn.Ak=function(n,t,e,i,r){var c;return xA(c=t.li(e))===xA(rBt)&&(c=null),t.ni(e),n.vh()&&n.wh()&&(!r&&(r=new cj(4)),this.tk()?r.nj(new bV(n,2,this.e,c,null)):r.nj(new bV(n,1,this.e,c,null))),r},uZn.Bk=function(n,t,e){return null!=t.li(e)},uZn.Ck=function(n,t,e,i){var r,c,a,o,u;if(null!=i&&!LGn(this.a,i))throw hv(new mM(Lrt+(F$(i,58)?nPn(uG(i,58).Dh()):crn(Tbn(i)))+Nrt+this.a+"'"));o=null!=(u=t.li(e)),this.tk()&&xA(u)===xA(rBt)&&(u=null),a=null,this.Mj()?xA(u)!==xA(i)&&(null!=u&&(a=(r=uG(u,54)).Th(n,emn(r.Dh(),this.b),null,a)),null!=i&&(a=(r=uG(i,54)).Rh(n,emn(r.Dh(),this.b),null,a))):this.al()&&xA(u)!==xA(i)&&(null!=u&&(a=uG(u,54).Th(n,-1-emn(n.Dh(),this.e),null,a)),null!=i&&(a=uG(i,54).Rh(n,-1-emn(n.Dh(),this.e),null,a))),null==i&&this.tk()?t.mi(e,rBt):t.mi(e,i),n.vh()&&n.wh()?(c=new kZ(n,1,this.e,u,i,this.tk()&&!o),a?(a.nj(c),a.oj()):Msn(n,c)):a&&a.oj()},uZn.Ek=function(n,t,e){var i,r,c,a,o;a=null!=(o=t.li(e)),this.tk()&&xA(o)===xA(rBt)&&(o=null),c=null,null!=o&&(this.Mj()?c=(i=uG(o,54)).Th(n,emn(i.Dh(),this.b),null,c):this.al()&&(c=uG(o,54).Th(n,-1-emn(n.Dh(),this.e),null,c))),t.ni(e),n.vh()&&n.wh()?(r=new kZ(n,this.tk()?2:1,this.e,o,null,a),c?(c.nj(r),c.oj()):Msn(n,r)):c&&c.oj()},uZn.Mj=function(){return!1},uZn.al=function(){return!1},uZn.bl=function(){return!1},uZn.tk=function(){return!1},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObject",410),sDn(575,410,{},tK),uZn.al=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainment",575),sDn(1359,575,{},eK),uZn.bl=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentResolving",1359),sDn(787,575,{},iK),uZn.tk=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettable",787),sDn(1361,787,{},cK),uZn.bl=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettableResolving",1361),sDn(650,575,{},FU),uZn.Mj=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverse",650),sDn(1360,650,{},HU),uZn.bl=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseResolving",1360),sDn(788,650,{},UU),uZn.tk=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettable",788),sDn(1362,788,{},GU),uZn.bl=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettableResolving",1362),sDn(651,410,{},rK),uZn.bl=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolving",651),sDn(1363,651,{},aK),uZn.tk=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingUnsettable",1363),sDn(789,651,{},_U),uZn.Mj=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverse",789),sDn(1364,789,{},qU),uZn.tk=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverseUnsettable",1364),sDn(1357,410,{},oK),uZn.tk=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectUnsettable",1357),sDn(786,410,{},BU),uZn.Mj=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverse",786),sDn(1358,786,{},XU),uZn.tk=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverseUnsettable",1358),sDn(790,576,Art,EQ),uZn.yl=function(n){return new EQ(this.a,this.c,n)},uZn.md=function(){return this.b},uZn.zl=function(n,t,e){return Snn(this,n,this.b,e)},uZn.Al=function(n,t,e){return Pnn(this,n,this.b,e)},zW(Ytt,"EStructuralFeatureImpl/InverseUpdatingFeatureMapEntry",790),sDn(1365,1,ort,_m),uZn.Fk=function(n){return this.a},uZn.Qj=function(){return F$(this.a,97)?uG(this.a,97).Qj():!this.a.dc()},uZn.Wb=function(n){this.a.$b(),this.a.Gc(uG(n,15))},uZn.Gk=function(){F$(this.a,97)?uG(this.a,97).Gk():this.a.$b()},zW(Ytt,"EStructuralFeatureImpl/SettingMany",1365),sDn(1366,576,Art,o8),uZn.xl=function(n){return new hF((uVn(),oHt),this.b.ri(this.a,n))},uZn.md=function(){return null},uZn.zl=function(n,t,e){return e},uZn.Al=function(n,t,e){return e},zW(Ytt,"EStructuralFeatureImpl/SimpleContentFeatureMapEntry",1366),sDn(652,576,Art,hF),uZn.xl=function(n){return new hF(this.c,n)},uZn.md=function(){return this.a},uZn.zl=function(n,t,e){return e},uZn.Al=function(n,t,e){return e},zW(Ytt,"EStructuralFeatureImpl/SimpleFeatureMapEntry",652),sDn(403,506,Qet,Ks),uZn.aj=function(n){return Inn(h_t,EZn,29,n,0,1)},uZn.Yi=function(){return!1},zW(Ytt,"ESuperAdapter/1",403),sDn(457,448,{110:1,94:1,93:1,155:1,197:1,58:1,114:1,850:1,54:1,99:1,158:1,457:1,119:1,120:1},Fs),uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return!this.a&&(this.a=new AX(this,g_t,this)),this.a}return $tn(this,n-iQ((YYn(),q_t)),ern(uG(Lsn(this,16),29)||q_t,n),t,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 2:return!this.a&&(this.a=new AX(this,g_t,this)),Nyn(this.a,n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),q_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),q_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!!this.a&&0!=this.a.i}return l5(this,n-iQ((YYn(),q_t)),ern(uG(Lsn(this,16),29)||q_t,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void qon(this,mK(t));case 2:return!this.a&&(this.a=new AX(this,g_t,this)),Czn(this.a),!this.a&&(this.a=new AX(this,g_t,this)),void CW(this.a,uG(t,16))}lpn(this,n-iQ((YYn(),q_t)),ern(uG(Lsn(this,16),29)||q_t,n),t)},uZn.ii=function(){return YYn(),q_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void qon(this,null);case 2:return!this.a&&(this.a=new AX(this,g_t,this)),void Czn(this.a)}sdn(this,n-iQ((YYn(),q_t)),ern(uG(Lsn(this,16),29)||q_t,n))},zW(Ytt,"ETypeParameterImpl",457),sDn(458,83,Trt,AX),uZn.Nj=function(n,t){return mCn(this,uG(n,89),t)},uZn.Oj=function(n,t){return vCn(this,uG(n,89),t)},zW(Ytt,"ETypeParameterImpl/1",458),sDn(647,45,B0n,ty),uZn.ec=function(){return new Um(this)},zW(Ytt,"ETypeParameterImpl/2",647),sDn(570,KZn,FZn,Um),uZn.Fc=function(n){return WF(this,uG(n,89))},uZn.Gc=function(n){var t,e,i;for(i=!1,e=n.Kc();e.Ob();)t=uG(e.Pb(),89),null==vJ(this.a,t,"")&&(i=!0);return i},uZn.$b=function(){$V(this.a)},uZn.Hc=function(n){return PV(this.a,n)},uZn.Kc=function(){return new Gm(new bsn(new Nw(this.a).a))},uZn.Mc=function(n){return C7(this,n)},uZn.gc=function(){return oS(this.a)},zW(Ytt,"ETypeParameterImpl/2/1",570),sDn(571,1,$Zn,Gm),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){return uG(von(this.a).ld(),89)},uZn.Ob=function(){return this.a.b},uZn.Qb=function(){Oen(this.a)},zW(Ytt,"ETypeParameterImpl/2/1/1",571),sDn(1329,45,B0n,ey),uZn._b=function(n){return RA(n)?AZ(this,n):!!FX(this.f,n)},uZn.xc=function(n){var t;return F$(t=RA(n)?U1(this,n):DA(FX(this.f,n)),851)?(t=uG(t,851).Kk(),vJ(this,uG(n,241),t),t):null!=t?t:null==n?(SP(),EBt):null},zW(Ytt,"EValidatorRegistryImpl",1329),sDn(1349,720,{110:1,94:1,93:1,480:1,155:1,58:1,114:1,2040:1,54:1,99:1,158:1,119:1,120:1},_s),uZn.ri=function(n,t){switch(n.hk()){case 21:case 22:case 23:case 24:case 26:case 31:case 32:case 37:case 38:case 39:case 40:case 43:case 44:case 48:case 49:case 20:return null==t?null:cpn(t);case 25:return Xrn(t);case 27:return nen(t);case 28:return ten(t);case 29:return null==t?null:N$(QKt[0],uG(t,206));case 41:return null==t?"":Ij(uG(t,297));case 42:return cpn(t);case 50:return mK(t);default:throw hv(new vM(tet+n.xe()+eet))}},uZn.si=function(n){var t;switch(-1==n.G&&(n.G=(t=Hrn(n))?Hyn(t.vi(),n):-1),n.G){case 0:return new Wk;case 1:return new vs;case 2:return new Kl;case 4:return new Gv;case 5:return new Jk;case 6:return new Uv;case 7:return new Fl;case 10:return new ps;case 11:return new Yk;case 12:return new aZ;case 13:return new ny;case 14:return new PK;case 17:return new Cs;case 18:return new ev;case 19:return new Fs;default:throw hv(new vM(cet+n.zb+eet))}},uZn.ti=function(n,t){switch(n.hk()){case 20:return null==t?null:new Wj(t);case 21:return null==t?null:new PN(t);case 23:case 22:return null==t?null:Ovn(t);case 26:case 24:return null==t?null:Ben(vUn(t,-128,127)<<24>>24);case 25:return cxn(t);case 27:return sjn(t);case 28:return hjn(t);case 29:return rIn(t);case 32:case 31:return null==t?null:YIn(t);case 38:case 37:return null==t?null:new tk(t);case 40:case 39:return null==t?null:xwn(vUn(t,j1n,vZn));case 41:case 42:return null;case 44:case 43:return null==t?null:Hvn(tJn(t));case 49:case 48:return null==t?null:Rwn(vUn(t,xrt,32767)<<16>>16);case 50:return t;default:throw hv(new vM(tet+n.xe()+eet))}},zW(Ytt,"EcoreFactoryImpl",1349),sDn(560,184,{110:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,2038:1,54:1,99:1,158:1,184:1,560:1,119:1,120:1,690:1},dJ),uZn.gb=!1,uZn.hb=!1;var gBt,pBt=!1;zW(Ytt,"EcorePackageImpl",560),sDn(1234,1,{851:1},Bs),uZn.Kk=function(){return HD(),SBt},zW(Ytt,"EcorePackageImpl/1",1234),sDn(1243,1,Wrt,Hs),uZn.fk=function(n){return F$(n,155)},uZn.gk=function(n){return Inn(uFt,EZn,155,n,0,1)},zW(Ytt,"EcorePackageImpl/10",1243),sDn(1244,1,Wrt,Us),uZn.fk=function(n){return F$(n,197)},uZn.gk=function(n){return Inn(hFt,EZn,197,n,0,1)},zW(Ytt,"EcorePackageImpl/11",1244),sDn(1245,1,Wrt,Gs),uZn.fk=function(n){return F$(n,58)},uZn.gk=function(n){return Inn(nFt,EZn,58,n,0,1)},zW(Ytt,"EcorePackageImpl/12",1245),sDn(1246,1,Wrt,qs),uZn.fk=function(n){return F$(n,411)},uZn.gk=function(n){return Inn(p_t,yrt,62,n,0,1)},zW(Ytt,"EcorePackageImpl/13",1246),sDn(1247,1,Wrt,Xs),uZn.fk=function(n){return F$(n,241)},uZn.gk=function(n){return Inn(fFt,EZn,241,n,0,1)},zW(Ytt,"EcorePackageImpl/14",1247),sDn(1248,1,Wrt,zs),uZn.fk=function(n){return F$(n,518)},uZn.gk=function(n){return Inn(m_t,EZn,2116,n,0,1)},zW(Ytt,"EcorePackageImpl/15",1248),sDn(1249,1,Wrt,Vs),uZn.fk=function(n){return F$(n,102)},uZn.gk=function(n){return Inn(v_t,krt,19,n,0,1)},zW(Ytt,"EcorePackageImpl/16",1249),sDn(1250,1,Wrt,Ws),uZn.fk=function(n){return F$(n,179)},uZn.gk=function(n){return Inn(o_t,krt,179,n,0,1)},zW(Ytt,"EcorePackageImpl/17",1250),sDn(1251,1,Wrt,Qs),uZn.fk=function(n){return F$(n,481)},uZn.gk=function(n){return Inn(a_t,EZn,481,n,0,1)},zW(Ytt,"EcorePackageImpl/18",1251),sDn(1252,1,Wrt,Js),uZn.fk=function(n){return F$(n,561)},uZn.gk=function(n){return Inn(wBt,Xit,561,n,0,1)},zW(Ytt,"EcorePackageImpl/19",1252),sDn(1235,1,Wrt,Ys),uZn.fk=function(n){return F$(n,331)},uZn.gk=function(n){return Inn(u_t,krt,35,n,0,1)},zW(Ytt,"EcorePackageImpl/2",1235),sDn(1253,1,Wrt,Zs),uZn.fk=function(n){return F$(n,248)},uZn.gk=function(n){return Inn(g_t,Prt,89,n,0,1)},zW(Ytt,"EcorePackageImpl/20",1253),sDn(1254,1,Wrt,nh),uZn.fk=function(n){return F$(n,457)},uZn.gk=function(n){return Inn(J_t,EZn,850,n,0,1)},zW(Ytt,"EcorePackageImpl/21",1254),sDn(1255,1,Wrt,th),uZn.fk=function(n){return KA(n)},uZn.gk=function(n){return Inn(cot,zZn,485,n,8,1)},zW(Ytt,"EcorePackageImpl/22",1255),sDn(1256,1,Wrt,eh),uZn.fk=function(n){return F$(n,195)},uZn.gk=function(n){return Inn(tUt,zZn,195,n,0,2)},zW(Ytt,"EcorePackageImpl/23",1256),sDn(1257,1,Wrt,ih),uZn.fk=function(n){return F$(n,222)},uZn.gk=function(n){return Inn(uot,zZn,222,n,0,1)},zW(Ytt,"EcorePackageImpl/24",1257),sDn(1258,1,Wrt,rh),uZn.fk=function(n){return F$(n,180)},uZn.gk=function(n){return Inn(hot,zZn,180,n,0,1)},zW(Ytt,"EcorePackageImpl/25",1258),sDn(1259,1,Wrt,ch),uZn.fk=function(n){return F$(n,206)},uZn.gk=function(n){return Inn(iot,zZn,206,n,0,1)},zW(Ytt,"EcorePackageImpl/26",1259),sDn(1260,1,Wrt,ah),uZn.fk=function(n){return!1},uZn.gk=function(n){return Inn(aUt,EZn,2215,n,0,1)},zW(Ytt,"EcorePackageImpl/27",1260),sDn(1261,1,Wrt,oh),uZn.fk=function(n){return FA(n)},uZn.gk=function(n){return Inn(fot,zZn,345,n,7,1)},zW(Ytt,"EcorePackageImpl/28",1261),sDn(1262,1,Wrt,uh),uZn.fk=function(n){return F$(n,61)},uZn.gk=function(n){return Inn(CFt,H3n,61,n,0,1)},zW(Ytt,"EcorePackageImpl/29",1262),sDn(1236,1,Wrt,sh),uZn.fk=function(n){return F$(n,519)},uZn.gk=function(n){return Inn(c_t,{3:1,4:1,5:1,2033:1},598,n,0,1)},zW(Ytt,"EcorePackageImpl/3",1236),sDn(1263,1,Wrt,hh),uZn.fk=function(n){return F$(n,582)},uZn.gk=function(n){return Inn(BFt,EZn,2039,n,0,1)},zW(Ytt,"EcorePackageImpl/30",1263),sDn(1264,1,Wrt,fh),uZn.fk=function(n){return F$(n,160)},uZn.gk=function(n){return Inn(IBt,H3n,160,n,0,1)},zW(Ytt,"EcorePackageImpl/31",1264),sDn(1265,1,Wrt,lh),uZn.fk=function(n){return F$(n,76)},uZn.gk=function(n){return Inn(Z_t,Qrt,76,n,0,1)},zW(Ytt,"EcorePackageImpl/32",1265),sDn(1266,1,Wrt,bh),uZn.fk=function(n){return F$(n,161)},uZn.gk=function(n){return Inn(lot,zZn,161,n,0,1)},zW(Ytt,"EcorePackageImpl/33",1266),sDn(1267,1,Wrt,wh),uZn.fk=function(n){return F$(n,17)},uZn.gk=function(n){return Inn(dot,zZn,17,n,0,1)},zW(Ytt,"EcorePackageImpl/34",1267),sDn(1268,1,Wrt,dh),uZn.fk=function(n){return F$(n,297)},uZn.gk=function(n){return Inn(gat,EZn,297,n,0,1)},zW(Ytt,"EcorePackageImpl/35",1268),sDn(1269,1,Wrt,gh),uZn.fk=function(n){return F$(n,168)},uZn.gk=function(n){return Inn(yot,zZn,168,n,0,1)},zW(Ytt,"EcorePackageImpl/36",1269),sDn(1270,1,Wrt,ph),uZn.fk=function(n){return F$(n,85)},uZn.gk=function(n){return Inn(mat,EZn,85,n,0,1)},zW(Ytt,"EcorePackageImpl/37",1270),sDn(1271,1,Wrt,mh),uZn.fk=function(n){return F$(n,599)},uZn.gk=function(n){return Inn(jBt,EZn,599,n,0,1)},zW(Ytt,"EcorePackageImpl/38",1271),sDn(1272,1,Wrt,vh),uZn.fk=function(n){return!1},uZn.gk=function(n){return Inn(oUt,EZn,2216,n,0,1)},zW(Ytt,"EcorePackageImpl/39",1272),sDn(1237,1,Wrt,kh),uZn.fk=function(n){return F$(n,90)},uZn.gk=function(n){return Inn(h_t,EZn,29,n,0,1)},zW(Ytt,"EcorePackageImpl/4",1237),sDn(1273,1,Wrt,yh),uZn.fk=function(n){return F$(n,191)},uZn.gk=function(n){return Inn(Tot,zZn,191,n,0,1)},zW(Ytt,"EcorePackageImpl/40",1273),sDn(1274,1,Wrt,Mh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(Ytt,"EcorePackageImpl/41",1274),sDn(1275,1,Wrt,Th),uZn.fk=function(n){return F$(n,596)},uZn.gk=function(n){return Inn(OFt,EZn,596,n,0,1)},zW(Ytt,"EcorePackageImpl/42",1275),sDn(1276,1,Wrt,jh),uZn.fk=function(n){return!1},uZn.gk=function(n){return Inn(uUt,zZn,2217,n,0,1)},zW(Ytt,"EcorePackageImpl/43",1276),sDn(1277,1,Wrt,Eh),uZn.fk=function(n){return F$(n,44)},uZn.gk=function(n){return Inn(Sat,c1n,44,n,0,1)},zW(Ytt,"EcorePackageImpl/44",1277),sDn(1238,1,Wrt,Sh),uZn.fk=function(n){return F$(n,142)},uZn.gk=function(n){return Inn(s_t,EZn,142,n,0,1)},zW(Ytt,"EcorePackageImpl/5",1238),sDn(1239,1,Wrt,Ph),uZn.fk=function(n){return F$(n,156)},uZn.gk=function(n){return Inn(f_t,EZn,156,n,0,1)},zW(Ytt,"EcorePackageImpl/6",1239),sDn(1240,1,Wrt,Ch),uZn.fk=function(n){return F$(n,469)},uZn.gk=function(n){return Inn(w_t,EZn,685,n,0,1)},zW(Ytt,"EcorePackageImpl/7",1240),sDn(1241,1,Wrt,Ih),uZn.fk=function(n){return F$(n,582)},uZn.gk=function(n){return Inn(d_t,EZn,694,n,0,1)},zW(Ytt,"EcorePackageImpl/8",1241),sDn(1242,1,Wrt,Oh),uZn.fk=function(n){return F$(n,480)},uZn.gk=function(n){return Inn(sFt,EZn,480,n,0,1)},zW(Ytt,"EcorePackageImpl/9",1242),sDn(1038,2080,Git,Qy),uZn.Mi=function(n,t){wdn(this,uG(t,424))},uZn.Qi=function(n,t){GAn(this,n,uG(t,424))},zW(Ytt,"MinimalEObjectImpl/1ArrayDelegatingAdapterList",1038),sDn(1039,152,Bit,SQ),uZn.jj=function(){return this.a.a},zW(Ytt,"MinimalEObjectImpl/1ArrayDelegatingAdapterList/1",1039),sDn(1067,1066,{},e$),zW("org.eclipse.emf.ecore.plugin","EcorePlugin",1067);var mBt,vBt,kBt,yBt,MBt,TBt,jBt=Iq(Jrt,"Resource");sDn(799,1524,Yrt),uZn.Hl=function(n){},uZn.Il=function(n){},uZn.El=function(){return!this.a&&(this.a=new qm(this)),this.a},uZn.Fl=function(n){var t,e,i,r,c;if((i=n.length)>0){if(s3(0,n.length),47==n.charCodeAt(0)){for(c=new R7(4),r=1,t=1;t0&&(Knn(0,e,n.length),n=n.substr(0,e))}return lNn(this,n)},uZn.Gl=function(){return this.c},uZn.Ib=function(){return Ij(this.Rm)+"@"+(Hon(this)>>>0).toString(16)+" uri='"+this.d+"'"},uZn.b=!1,zW(Zrt,"ResourceImpl",799),sDn(1525,799,Yrt,Xm),zW(Zrt,"BinaryResourceImpl",1525),sDn(1190,708,Jet),uZn.bj=function(n){return F$(n,58)?JZ(this,uG(n,58)):F$(n,599)?new DD(uG(n,599).El()):xA(n)===xA(this.f)?uG(n,16).Kc():(EK(),KFt.a)},uZn.Ob=function(){return u$n(this)},uZn.a=!1,zW(art,"EcoreUtil/ContentTreeIterator",1190),sDn(1526,1190,Jet,dV),uZn.bj=function(n){return xA(n)===xA(this.f)?uG(n,15).Kc():new L6(uG(n,58))},zW(Zrt,"ResourceImpl/5",1526),sDn(658,2092,Mrt,qm),uZn.Hc=function(n){return this.i<=4?sSn(this,n):F$(n,54)&&uG(n,54).Jh()==this.a},uZn.Mi=function(n,t){n==this.i-1&&(this.a.b||(this.a.b=!0))},uZn.Oi=function(n,t){0==n?this.a.b||(this.a.b=!0):Ann(this,n,t)},uZn.Qi=function(n,t){},uZn.Ri=function(n,t,e){},uZn.Lj=function(){return 2},uZn.jj=function(){return this.a},uZn.Mj=function(){return!0},uZn.Nj=function(n,t){return t=uG(n,54).fi(this.a,t)},uZn.Oj=function(n,t){return uG(n,54).fi(null,t)},uZn.Pj=function(){return!1},uZn.Si=function(){return!0},uZn.aj=function(n){return Inn(nFt,EZn,58,n,0,1)},uZn.Yi=function(){return!1},zW(Zrt,"ResourceImpl/ContentsEList",658),sDn(970,2062,m1n,zm),uZn.fd=function(n){return this.a.Ki(n)},uZn.gc=function(){return this.a.gc()},zW(art,"AbstractSequentialInternalEList/1",970),sDn(634,1,{},HG),zW(art,"BasicExtendedMetaData",634),sDn(1181,1,{},CA),uZn.Jl=function(){return null},uZn.Kl=function(){return-2==this.a&&fw(this,qCn(this.d,this.b)),this.a},uZn.Ll=function(){return null},uZn.Ml=function(){return hZ(),hZ(),zot},uZn.xe=function(){return this.c==wct&&lw(this,ckn(this.d,this.b)),this.c},uZn.Nl=function(){return 0},uZn.a=-2,uZn.c=wct,zW(art,"BasicExtendedMetaData/EClassExtendedMetaDataImpl",1181),sDn(1182,1,{},g4),uZn.Jl=function(){return this.a==(N7(),MBt)&&dw(this,TBn(this.f,this.b)),this.a},uZn.Kl=function(){return 0},uZn.Ll=function(){return this.c==(N7(),MBt)&&bw(this,jBn(this.f,this.b)),this.c},uZn.Ml=function(){return!this.d&&pw(this,iqn(this.f,this.b)),this.d},uZn.xe=function(){return this.e==wct&&vw(this,ckn(this.f,this.b)),this.e},uZn.Nl=function(){return-2==this.g&&yw(this,DPn(this.f,this.b)),this.g},uZn.e=wct,uZn.g=-2,zW(art,"BasicExtendedMetaData/EDataTypeExtendedMetaDataImpl",1182),sDn(1180,1,{},IA),uZn.b=!1,uZn.c=!1,zW(art,"BasicExtendedMetaData/EPackageExtendedMetaDataImpl",1180),sDn(1183,1,{},p4),uZn.c=-2,uZn.e=wct,uZn.f=wct,zW(art,"BasicExtendedMetaData/EStructuralFeatureExtendedMetaDataImpl",1183),sDn(593,632,Trt,_G),uZn.Lj=function(){return this.c},uZn.ol=function(){return!1},uZn.Wi=function(n,t){return t},uZn.c=0,zW(art,"EDataTypeEList",593);var EBt,SBt,PBt,CBt,IBt=Iq(art,"FeatureMap");sDn(78,593,{3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1,79:1,160:1,220:1,2036:1,71:1,97:1},wsn),uZn.bd=function(n,t){iKn(this,n,uG(t,76))},uZn.Fc=function(n){return Qxn(this,uG(n,76))},uZn.Hi=function(n){OW(this,uG(n,76))},uZn.Nj=function(n,t){return q_(this,uG(n,76),t)},uZn.Oj=function(n,t){return X_(this,uG(n,76),t)},uZn.Ti=function(n,t){return bUn(this,n,t)},uZn.Wi=function(n,t){return IVn(this,n,uG(t,76))},uZn.hd=function(n,t){return kFn(this,n,uG(t,76))},uZn.Uj=function(n,t){return z_(this,uG(n,76),t)},uZn.Vj=function(n,t){return V_(this,uG(n,76),t)},uZn.Wj=function(n,t,e){return aPn(this,uG(n,76),uG(t,76),e)},uZn.Zi=function(n,t){return WPn(this,n,uG(t,76))},uZn.Ol=function(n,t){return GHn(this,n,t)},uZn.cd=function(n,t){var e,i,r,c,a,o,u,s,h;for(s=new Drn(t.gc()),r=t.Kc();r.Ob();)if(c=(i=uG(r.Pb(),76)).Lk(),EFn(this.e,c))(!c.Si()||!H5(this,c,i.md())&&!sSn(s,i))&&ttn(s,i);else{for(h=VKn(this.e.Dh(),c),e=uG(this.g,124),a=!0,o=0;o=0;)if(t=n[this.c],this.k.am(t.Lk()))return this.j=this.f?t:t.md(),this.i=-2,!0;return this.i=-1,this.g=-1,!1},zW(art,"BasicFeatureMap/FeatureEIterator",420),sDn(676,420,UZn,yL),uZn.ul=function(){return!0},zW(art,"BasicFeatureMap/ResolvingFeatureEIterator",676),sDn(968,496,Irt,G$),uZn.pj=function(){return this},zW(art,"EContentsEList/1",968),sDn(969,496,Irt,kL),uZn.ul=function(){return!1},zW(art,"EContentsEList/2",969),sDn(967,287,Ort,q$),uZn.wl=function(n){},uZn.Ob=function(){return!1},uZn.Sb=function(){return!1},zW(art,"EContentsEList/FeatureIteratorImpl/1",967),sDn(840,593,Trt,jD),uZn.Ni=function(){this.a=!0},uZn.Qj=function(){return this.a},uZn.Gk=function(){var n;Czn(this),uN(this.e)?(n=this.a,this.a=!1,Msn(this.e,new j9(this.e,2,this.c,n,!1))):this.a=!1},uZn.a=!1,zW(art,"EDataTypeEList/Unsettable",840),sDn(1958,593,Trt,ED),uZn.Si=function(){return!0},zW(art,"EDataTypeUniqueEList",1958),sDn(1959,840,Trt,SD),uZn.Si=function(){return!0},zW(art,"EDataTypeUniqueEList/Unsettable",1959),sDn(147,83,Trt,PD),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectContainmentEList/Resolving",147),sDn(1184,555,Trt,CD),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectContainmentEList/Unsettable/Resolving",1184),sDn(766,14,Trt,r_),uZn.Ni=function(){this.a=!0},uZn.Qj=function(){return this.a},uZn.Gk=function(){var n;Czn(this),uN(this.e)?(n=this.a,this.a=!1,Msn(this.e,new j9(this.e,2,this.c,n,!1))):this.a=!1},uZn.a=!1,zW(art,"EObjectContainmentWithInverseEList/Unsettable",766),sDn(1222,766,Trt,c_),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectContainmentWithInverseEList/Unsettable/Resolving",1222),sDn(757,505,Trt,ID),uZn.Ni=function(){this.a=!0},uZn.Qj=function(){return this.a},uZn.Gk=function(){var n;Czn(this),uN(this.e)?(n=this.a,this.a=!1,Msn(this.e,new j9(this.e,2,this.c,n,!1))):this.a=!1},uZn.a=!1,zW(art,"EObjectEList/Unsettable",757),sDn(338,505,Trt,OD),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectResolvingEList",338),sDn(1844,757,Trt,AD),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectResolvingEList/Unsettable",1844),sDn(1527,1,{},Ah),zW(art,"EObjectValidator",1527),sDn(559,505,Trt,wV),uZn.il=function(){return this.d},uZn.jl=function(){return this.b},uZn.Mj=function(){return!0},uZn.ml=function(){return!0},uZn.b=0,zW(art,"EObjectWithInverseEList",559),sDn(1225,559,Trt,a_),uZn.ll=function(){return!0},zW(art,"EObjectWithInverseEList/ManyInverse",1225),sDn(635,559,Trt,o_),uZn.Ni=function(){this.a=!0},uZn.Qj=function(){return this.a},uZn.Gk=function(){var n;Czn(this),uN(this.e)?(n=this.a,this.a=!1,Msn(this.e,new j9(this.e,2,this.c,n,!1))):this.a=!1},uZn.a=!1,zW(art,"EObjectWithInverseEList/Unsettable",635),sDn(1224,635,Trt,s_),uZn.ll=function(){return!0},zW(art,"EObjectWithInverseEList/Unsettable/ManyInverse",1224),sDn(767,559,Trt,u_),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectWithInverseResolvingEList",767),sDn(32,767,Trt,f_),uZn.ll=function(){return!0},zW(art,"EObjectWithInverseResolvingEList/ManyInverse",32),sDn(768,635,Trt,h_),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectWithInverseResolvingEList/Unsettable",768),sDn(1223,768,Trt,l_),uZn.ll=function(){return!0},zW(art,"EObjectWithInverseResolvingEList/Unsettable/ManyInverse",1223),sDn(1185,632,Trt),uZn.Li=function(){return!(1792&this.b)},uZn.Ni=function(){this.b|=1},uZn.kl=function(){return!!(4&this.b)},uZn.Mj=function(){return!!(40&this.b)},uZn.ll=function(){return!!(16&this.b)},uZn.ml=function(){return!!(8&this.b)},uZn.nl=function(){return!!(this.b&frt)},uZn.al=function(){return!!(32&this.b)},uZn.ol=function(){return!!(this.b&w1n)},uZn.fk=function(n){return this.d?v5(this.d,n):this.Lk().Hk().fk(n)},uZn.Qj=function(){return 2&this.b?!!(1&this.b):0!=this.i},uZn.Si=function(){return!!(128&this.b)},uZn.Gk=function(){var n;Czn(this),2&this.b&&(uN(this.e)?(n=!!(1&this.b),this.b&=-2,Yv(this,new j9(this.e,2,emn(this.e.Dh(),this.Lk()),n,!1))):this.b&=-2)},uZn.Yi=function(){return!(1536&this.b)},uZn.b=0,zW(art,"EcoreEList/Generic",1185),sDn(1186,1185,Trt,yZ),uZn.Lk=function(){return this.a},zW(art,"EcoreEList/Dynamic",1186),sDn(765,66,Qet,Vm),uZn.aj=function(n){return Acn(this.a.a,n)},zW(art,"EcoreEMap/1",765),sDn(764,83,Trt,kV),uZn.Mi=function(n,t){bMn(this.b,uG(t,136))},uZn.Oi=function(n,t){Osn(this.b)},uZn.Pi=function(n,t,e){var i;++(i=this.b,uG(t,136),i).e},uZn.Qi=function(n,t){Vdn(this.b,uG(t,136))},uZn.Ri=function(n,t,e){Vdn(this.b,uG(e,136)),xA(e)===xA(t)&&uG(e,136).Ci(WN(uG(t,136).ld())),bMn(this.b,uG(t,136))},zW(art,"EcoreEMap/DelegateEObjectContainmentEList",764),sDn(1220,141,urt,xan),zW(art,"EcoreEMap/Unsettable",1220),sDn(1221,764,Trt,b_),uZn.Ni=function(){this.a=!0},uZn.Qj=function(){return this.a},uZn.Gk=function(){var n;Czn(this),uN(this.e)?(n=this.a,this.a=!1,Msn(this.e,new j9(this.e,2,this.c,n,!1))):this.a=!1},uZn.a=!1,zW(art,"EcoreEMap/Unsettable/UnsettableDelegateEObjectContainmentEList",1221),sDn(1189,215,B0n,DW),uZn.a=!1,uZn.b=!1,zW(art,"EcoreUtil/Copier",1189),sDn(759,1,$Zn,L6),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return Ymn(this)},uZn.Pb=function(){var n;return Ymn(this),n=this.b,this.b=null,n},uZn.Qb=function(){this.a.Qb()},zW(art,"EcoreUtil/ProperContentIterator",759),sDn(1528,1527,{},_l),zW(art,"EcoreValidator",1528),Iq(art,"FeatureMapUtil/Validator"),sDn(1295,1,{2041:1},Lh),uZn.am=function(n){return!0},zW(art,"FeatureMapUtil/1",1295),sDn(773,1,{2041:1},MQn),uZn.am=function(n){var t;return this.c==n||(null==(t=gK(cQ(this.a,n)))?DBn(this,n)?(W9(this.a,n,(qx(),eot)),!0):(W9(this.a,n,(qx(),tot)),!1):t==(qx(),eot))},uZn.e=!1,zW(art,"FeatureMapUtil/BasicValidator",773),sDn(774,45,B0n,U$),zW(art,"FeatureMapUtil/BasicValidator/Cache",774),sDn(509,56,{20:1,31:1,56:1,16:1,15:1,61:1,79:1,71:1,97:1},OA),uZn.bd=function(n,t){LFn(this.c,this.b,n,t)},uZn.Fc=function(n){return GHn(this.c,this.b,n)},uZn.cd=function(n,t){return _Xn(this.c,this.b,n,t)},uZn.Gc=function(n){return K$(this,n)},uZn.Gi=function(n,t){hrn(this.c,this.b,n,t)},uZn.Wk=function(n,t){return OBn(this.c,this.b,n,t)},uZn.$i=function(n){return gXn(this.c,this.b,n,!1)},uZn.Ii=function(){return wN(this.c,this.b)},uZn.Ji=function(){return dN(this.c,this.b)},uZn.Ki=function(n){return Onn(this.c,this.b,n)},uZn.Xk=function(n,t){return rF(this,n,t)},uZn.$b=function(){Zv(this)},uZn.Hc=function(n){return H5(this.c,this.b,n)},uZn.Ic=function(n){return Run(this.c,this.b,n)},uZn.Xb=function(n){return gXn(this.c,this.b,n,!0)},uZn.Fk=function(n){return this},uZn.dd=function(n){return U5(this.c,this.b,n)},uZn.dc=function(){return $A(this)},uZn.Qj=function(){return!kmn(this.c,this.b)},uZn.Kc=function(){return kin(this.c,this.b)},uZn.ed=function(){return yin(this.c,this.b)},uZn.fd=function(n){return lgn(this.c,this.b,n)},uZn.Ti=function(n,t){return EGn(this.c,this.b,n,t)},uZn.Ui=function(n,t){xnn(this.c,this.b,n,t)},uZn.gd=function(n){return VOn(this.c,this.b,n)},uZn.Mc=function(n){return DHn(this.c,this.b,n)},uZn.hd=function(n,t){return hqn(this.c,this.b,n,t)},uZn.Wb=function(n){C$n(this.c,this.b),K$(this,uG(n,15))},uZn.gc=function(){return fgn(this.c,this.b)},uZn.Pc=function(){return v4(this.c,this.b)},uZn.Qc=function(n){return G5(this.c,this.b,n)},uZn.Ib=function(){var n,t;for((t=new zM).a+="[",n=wN(this.c,this.b);Zln(n);)VA(t,ox(_yn(n))),Zln(n)&&(t.a+=TZn);return t.a+="]",t.a},uZn.Gk=function(){C$n(this.c,this.b)},zW(art,"FeatureMapUtil/FeatureEList",509),sDn(644,39,Bit,i8),uZn.hj=function(n){return ydn(this,n)},uZn.mj=function(n){var t,e,i,r;switch(this.d){case 1:case 2:if(xA(n.jj())===xA(this.c)&&ydn(this,null)==n.hj(null))return this.g=n.ij(),1==n.gj()&&(this.d=1),!0;break;case 3:if(3===n.gj()&&xA(n.jj())===xA(this.c)&&ydn(this,null)==n.hj(null))return this.d=5,ttn(t=new Drn(2),this.g),ttn(t,n.ij()),this.g=t,!0;break;case 5:if(3===n.gj()&&xA(n.jj())===xA(this.c)&&ydn(this,null)==n.hj(null))return uG(this.g,16).Fc(n.ij()),!0;break;case 4:switch(n.gj()){case 3:if(xA(n.jj())===xA(this.c)&&ydn(this,null)==n.hj(null))return this.d=1,this.g=n.ij(),!0;break;case 4:if(xA(n.jj())===xA(this.c)&&ydn(this,null)==n.hj(null))return this.d=6,ttn(r=new Drn(2),this.n),ttn(r,n.kj()),this.n=r,i=Uhn(cT(YHt,1),W1n,28,15,[this.o,n.lj()]),this.g=i,!0}break;case 6:if(4===n.gj()&&xA(n.jj())===xA(this.c)&&ydn(this,null)==n.hj(null))return uG(this.n,16).Fc(n.kj()),qGn(i=uG(this.g,53),0,e=Inn(YHt,W1n,28,i.length+1,15,1),0,i.length),e[i.length]=n.lj(),this.g=e,!0}return!1},zW(art,"FeatureMapUtil/FeatureENotificationImpl",644),sDn(564,509,{20:1,31:1,56:1,16:1,15:1,61:1,79:1,160:1,220:1,2036:1,71:1,97:1},Cq),uZn.Ol=function(n,t){return GHn(this.c,n,t)},uZn.Pl=function(n,t,e){return OBn(this.c,n,t,e)},uZn.Ql=function(n,t,e){return fXn(this.c,n,t,e)},uZn.Rl=function(){return this},uZn.Sl=function(n,t){return dXn(this.c,n,t)},uZn.Tl=function(n){return uG(gXn(this.c,this.b,n,!1),76).Lk()},uZn.Ul=function(n){return uG(gXn(this.c,this.b,n,!1),76).md()},uZn.Vl=function(){return this.a},uZn.Wl=function(n){return!kmn(this.c,n)},uZn.Xl=function(n,t){BXn(this.c,n,t)},uZn.Yl=function(n){return non(this.c,n)},uZn.Zl=function(n){ETn(this.c,n)},zW(art,"FeatureMapUtil/FeatureFeatureMap",564),sDn(1294,1,ort,PA),uZn.Fk=function(n){return gXn(this.b,this.a,-1,n)},uZn.Qj=function(){return!kmn(this.b,this.a)},uZn.Wb=function(n){BXn(this.b,this.a,n)},uZn.Gk=function(){C$n(this.b,this.a)},zW(art,"FeatureMapUtil/FeatureValue",1294);var OBt,ABt,LBt,NBt,$Bt,DBt=Iq(gct,"AnyType");sDn(680,63,S1n,PM),zW(gct,"InvalidDatatypeValueException",680);var xBt,RBt,KBt,FBt,_Bt,BBt,HBt,UBt,GBt,qBt,XBt,zBt,VBt,WBt,QBt,JBt,YBt,ZBt,nHt,tHt,eHt,iHt,rHt,cHt,aHt,oHt,uHt,sHt,hHt,fHt,lHt=Iq(gct,pct),bHt=Iq(gct,mct),wHt=Iq(gct,vct);sDn(844,516,{110:1,94:1,93:1,58:1,54:1,99:1,857:1},iy),uZn.Lh=function(n,t,e){switch(n){case 0:return e?(!this.c&&(this.c=new wsn(this,0)),this.c):(!this.c&&(this.c=new wsn(this,0)),this.c.b);case 1:return e?(!this.c&&(this.c=new wsn(this,0)),uG(T2(this.c,(uVn(),FBt)),160)):(!this.c&&(this.c=new wsn(this,0)),uG(uG(T2(this.c,(uVn(),FBt)),160),220)).Vl();case 2:return e?(!this.b&&(this.b=new wsn(this,2)),this.b):(!this.b&&(this.b=new wsn(this,2)),this.b.b)}return $tn(this,n-iQ(this.ii()),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():this.ii(),n),t,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.c&&(this.c=new wsn(this,0)),$Hn(this.c,n,e);case 1:return(!this.c&&(this.c=new wsn(this,0)),uG(uG(T2(this.c,(uVn(),FBt)),160),71)).Xk(n,e);case 2:return!this.b&&(this.b=new wsn(this,2)),$Hn(this.b,n,e)}return uG(ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():this.ii(),t),69).wk().Ak(this,Wen(this),t-iQ(this.ii()),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.c&&0!=this.c.i;case 1:return!(!this.c&&(this.c=new wsn(this,0)),uG(T2(this.c,(uVn(),FBt)),160)).dc();case 2:return!!this.b&&0!=this.b.i}return l5(this,n-iQ(this.ii()),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():this.ii(),n))},uZn.bi=function(n,t){switch(n){case 0:return!this.c&&(this.c=new wsn(this,0)),void cW(this.c,t);case 1:return void(!this.c&&(this.c=new wsn(this,0)),uG(uG(T2(this.c,(uVn(),FBt)),160),220)).Wb(t);case 2:return!this.b&&(this.b=new wsn(this,2)),void cW(this.b,t)}lpn(this,n-iQ(this.ii()),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():this.ii(),n),t)},uZn.ii=function(){return uVn(),KBt},uZn.ki=function(n){switch(n){case 0:return!this.c&&(this.c=new wsn(this,0)),void Czn(this.c);case 1:return void(!this.c&&(this.c=new wsn(this,0)),uG(T2(this.c,(uVn(),FBt)),160)).$b();case 2:return!this.b&&(this.b=new wsn(this,2)),void Czn(this.b)}sdn(this,n-iQ(this.ii()),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():this.ii(),n))},uZn.Ib=function(){var n;return 4&this.j?vxn(this):((n=new fx(vxn(this))).a+=" (mixed: ",zA(n,this.c),n.a+=", anyAttribute: ",zA(n,this.b),n.a+=")",n.a)},zW(kct,"AnyTypeImpl",844),sDn(681,516,{110:1,94:1,93:1,58:1,54:1,99:1,2119:1,681:1},Uh),uZn.Lh=function(n,t,e){switch(n){case 0:return this.a;case 1:return this.b}return $tn(this,n-iQ((uVn(),JBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():JBt,n),t,e)},uZn.Wh=function(n){switch(n){case 0:return null!=this.a;case 1:return null!=this.b}return l5(this,n-iQ((uVn(),JBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():JBt,n))},uZn.bi=function(n,t){switch(n){case 0:return void jw(this,mK(t));case 1:return void Sw(this,mK(t))}lpn(this,n-iQ((uVn(),JBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():JBt,n),t)},uZn.ii=function(){return uVn(),JBt},uZn.ki=function(n){switch(n){case 0:return void(this.a=null);case 1:return void(this.b=null)}sdn(this,n-iQ((uVn(),JBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():JBt,n))},uZn.Ib=function(){var n;return 4&this.j?vxn(this):((n=new fx(vxn(this))).a+=" (data: ",VA(n,this.a),n.a+=", target: ",VA(n,this.b),n.a+=")",n.a)},uZn.a=null,uZn.b=null,zW(kct,"ProcessingInstructionImpl",681),sDn(682,844,{110:1,94:1,93:1,58:1,54:1,99:1,857:1,2120:1,682:1},ry),uZn.Lh=function(n,t,e){switch(n){case 0:return e?(!this.c&&(this.c=new wsn(this,0)),this.c):(!this.c&&(this.c=new wsn(this,0)),this.c.b);case 1:return e?(!this.c&&(this.c=new wsn(this,0)),uG(T2(this.c,(uVn(),FBt)),160)):(!this.c&&(this.c=new wsn(this,0)),uG(uG(T2(this.c,(uVn(),FBt)),160),220)).Vl();case 2:return e?(!this.b&&(this.b=new wsn(this,2)),this.b):(!this.b&&(this.b=new wsn(this,2)),this.b.b);case 3:return!this.c&&(this.c=new wsn(this,0)),mK(dXn(this.c,(uVn(),nHt),!0));case 4:return g_(this.a,(!this.c&&(this.c=new wsn(this,0)),mK(dXn(this.c,(uVn(),nHt),!0))));case 5:return this.a}return $tn(this,n-iQ((uVn(),ZBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():ZBt,n),t,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.c&&0!=this.c.i;case 1:return!(!this.c&&(this.c=new wsn(this,0)),uG(T2(this.c,(uVn(),FBt)),160)).dc();case 2:return!!this.b&&0!=this.b.i;case 3:return!this.c&&(this.c=new wsn(this,0)),null!=mK(dXn(this.c,(uVn(),nHt),!0));case 4:return null!=g_(this.a,(!this.c&&(this.c=new wsn(this,0)),mK(dXn(this.c,(uVn(),nHt),!0))));case 5:return!!this.a}return l5(this,n-iQ((uVn(),ZBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():ZBt,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.c&&(this.c=new wsn(this,0)),void cW(this.c,t);case 1:return void(!this.c&&(this.c=new wsn(this,0)),uG(uG(T2(this.c,(uVn(),FBt)),160),220)).Wb(t);case 2:return!this.b&&(this.b=new wsn(this,2)),void cW(this.b,t);case 3:return void m4(this,mK(t));case 4:return void m4(this,d_(this.a,t));case 5:return void Ew(this,uG(t,156))}lpn(this,n-iQ((uVn(),ZBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():ZBt,n),t)},uZn.ii=function(){return uVn(),ZBt},uZn.ki=function(n){switch(n){case 0:return!this.c&&(this.c=new wsn(this,0)),void Czn(this.c);case 1:return void(!this.c&&(this.c=new wsn(this,0)),uG(T2(this.c,(uVn(),FBt)),160)).$b();case 2:return!this.b&&(this.b=new wsn(this,2)),void Czn(this.b);case 3:return!this.c&&(this.c=new wsn(this,0)),void BXn(this.c,(uVn(),nHt),null);case 4:return void m4(this,d_(this.a,null));case 5:return void(this.a=null)}sdn(this,n-iQ((uVn(),ZBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():ZBt,n))},zW(kct,"SimpleAnyTypeImpl",682),sDn(683,516,{110:1,94:1,93:1,58:1,54:1,99:1,2121:1,683:1},cy),uZn.Lh=function(n,t,e){switch(n){case 0:return e?(!this.a&&(this.a=new wsn(this,0)),this.a):(!this.a&&(this.a=new wsn(this,0)),this.a.b);case 1:return e?(!this.b&&(this.b=new ltn((YYn(),H_t),wBt,this,1)),this.b):(!this.b&&(this.b=new ltn((YYn(),H_t),wBt,this,1)),Tnn(this.b));case 2:return e?(!this.c&&(this.c=new ltn((YYn(),H_t),wBt,this,2)),this.c):(!this.c&&(this.c=new ltn((YYn(),H_t),wBt,this,2)),Tnn(this.c));case 3:return!this.a&&(this.a=new wsn(this,0)),T2(this.a,(uVn(),iHt));case 4:return!this.a&&(this.a=new wsn(this,0)),T2(this.a,(uVn(),rHt));case 5:return!this.a&&(this.a=new wsn(this,0)),T2(this.a,(uVn(),aHt));case 6:return!this.a&&(this.a=new wsn(this,0)),T2(this.a,(uVn(),oHt))}return $tn(this,n-iQ((uVn(),eHt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():eHt,n),t,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.a&&(this.a=new wsn(this,0)),$Hn(this.a,n,e);case 1:return!this.b&&(this.b=new ltn((YYn(),H_t),wBt,this,1)),G_(this.b,n,e);case 2:return!this.c&&(this.c=new ltn((YYn(),H_t),wBt,this,2)),G_(this.c,n,e);case 5:return!this.a&&(this.a=new wsn(this,0)),rF(T2(this.a,(uVn(),aHt)),n,e)}return uG(ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():(uVn(),eHt),t),69).wk().Ak(this,Wen(this),t-iQ((uVn(),eHt)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.a&&0!=this.a.i;case 1:return!!this.b&&0!=this.b.f;case 2:return!!this.c&&0!=this.c.f;case 3:return!this.a&&(this.a=new wsn(this,0)),!$A(T2(this.a,(uVn(),iHt)));case 4:return!this.a&&(this.a=new wsn(this,0)),!$A(T2(this.a,(uVn(),rHt)));case 5:return!this.a&&(this.a=new wsn(this,0)),!$A(T2(this.a,(uVn(),aHt)));case 6:return!this.a&&(this.a=new wsn(this,0)),!$A(T2(this.a,(uVn(),oHt)))}return l5(this,n-iQ((uVn(),eHt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():eHt,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.a&&(this.a=new wsn(this,0)),void cW(this.a,t);case 1:return!this.b&&(this.b=new ltn((YYn(),H_t),wBt,this,1)),void Jun(this.b,t);case 2:return!this.c&&(this.c=new ltn((YYn(),H_t),wBt,this,2)),void Jun(this.c,t);case 3:return!this.a&&(this.a=new wsn(this,0)),Zv(T2(this.a,(uVn(),iHt))),!this.a&&(this.a=new wsn(this,0)),void K$(T2(this.a,iHt),uG(t,16));case 4:return!this.a&&(this.a=new wsn(this,0)),Zv(T2(this.a,(uVn(),rHt))),!this.a&&(this.a=new wsn(this,0)),void K$(T2(this.a,rHt),uG(t,16));case 5:return!this.a&&(this.a=new wsn(this,0)),Zv(T2(this.a,(uVn(),aHt))),!this.a&&(this.a=new wsn(this,0)),void K$(T2(this.a,aHt),uG(t,16));case 6:return!this.a&&(this.a=new wsn(this,0)),Zv(T2(this.a,(uVn(),oHt))),!this.a&&(this.a=new wsn(this,0)),void K$(T2(this.a,oHt),uG(t,16))}lpn(this,n-iQ((uVn(),eHt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():eHt,n),t)},uZn.ii=function(){return uVn(),eHt},uZn.ki=function(n){switch(n){case 0:return!this.a&&(this.a=new wsn(this,0)),void Czn(this.a);case 1:return!this.b&&(this.b=new ltn((YYn(),H_t),wBt,this,1)),void this.b.c.$b();case 2:return!this.c&&(this.c=new ltn((YYn(),H_t),wBt,this,2)),void this.c.c.$b();case 3:return!this.a&&(this.a=new wsn(this,0)),void Zv(T2(this.a,(uVn(),iHt)));case 4:return!this.a&&(this.a=new wsn(this,0)),void Zv(T2(this.a,(uVn(),rHt)));case 5:return!this.a&&(this.a=new wsn(this,0)),void Zv(T2(this.a,(uVn(),aHt)));case 6:return!this.a&&(this.a=new wsn(this,0)),void Zv(T2(this.a,(uVn(),oHt)))}sdn(this,n-iQ((uVn(),eHt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():eHt,n))},uZn.Ib=function(){var n;return 4&this.j?vxn(this):((n=new fx(vxn(this))).a+=" (mixed: ",zA(n,this.a),n.a+=")",n.a)},zW(kct,"XMLTypeDocumentRootImpl",683),sDn(2028,720,{110:1,94:1,93:1,480:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1,2122:1},Nh),uZn.ri=function(n,t){switch(n.hk()){case 7:case 8:case 9:case 10:case 16:case 22:case 23:case 24:case 25:case 26:case 32:case 33:case 34:case 36:case 37:case 44:case 45:case 50:case 51:case 53:case 55:case 56:case 57:case 58:case 60:case 61:case 4:return null==t?null:cpn(t);case 19:case 28:case 29:case 35:case 38:case 39:case 41:case 46:case 52:case 54:case 5:return mK(t);case 6:return lK(uG(t,195));case 12:case 47:case 49:case 11:return cWn(this,n,t);case 13:return null==t?null:VXn(uG(t,247));case 15:case 14:return null==t?null:MW(uM(pK(t)));case 17:return oPn((uVn(),t));case 18:return oPn(t);case 21:case 20:return null==t?null:TW(uG(t,161).a);case 27:return bK(uG(t,195));case 30:return STn((uVn(),uG(t,15)));case 31:return STn(uG(t,15));case 40:return dK((uVn(),t));case 42:return uPn((uVn(),t));case 43:return uPn(t);case 59:case 48:return wK((uVn(),t));default:throw hv(new vM(tet+n.xe()+eet))}},uZn.si=function(n){var t;switch(-1==n.G&&(n.G=(t=Hrn(n))?Hyn(t.vi(),n):-1),n.G){case 0:return new iy;case 1:return new Uh;case 2:return new ry;case 3:return new cy;default:throw hv(new vM(cet+n.zb+eet))}},uZn.ti=function(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p;switch(n.hk()){case 5:case 52:case 4:return t;case 6:return syn(t);case 8:case 7:return null==t?null:MPn(t);case 9:return null==t?null:Ben(vUn((i=yXn(t,!0)).length>0&&(s3(0,i.length),43==i.charCodeAt(0))?(s3(1,i.length+1),i.substr(1)):i,-128,127)<<24>>24);case 10:return null==t?null:Ben(vUn((r=yXn(t,!0)).length>0&&(s3(0,r.length),43==r.charCodeAt(0))?(s3(1,r.length+1),r.substr(1)):r,-128,127)<<24>>24);case 11:return mK(cYn(this,(uVn(),HBt),t));case 12:return mK(cYn(this,(uVn(),UBt),t));case 13:return null==t?null:new Wj(yXn(t,!0));case 15:case 14:return iRn(t);case 16:return mK(cYn(this,(uVn(),GBt),t));case 17:return bvn((uVn(),t));case 18:return bvn(t);case 28:case 29:case 35:case 38:case 39:case 41:case 54:case 19:return yXn(t,!0);case 21:case 20:return vRn(t);case 22:return mK(cYn(this,(uVn(),qBt),t));case 23:return mK(cYn(this,(uVn(),XBt),t));case 24:return mK(cYn(this,(uVn(),zBt),t));case 25:return mK(cYn(this,(uVn(),VBt),t));case 26:return mK(cYn(this,(uVn(),WBt),t));case 27:return Ckn(t);case 30:return wvn((uVn(),t));case 31:return wvn(t);case 32:return null==t?null:xwn(vUn((h=yXn(t,!0)).length>0&&(s3(0,h.length),43==h.charCodeAt(0))?(s3(1,h.length+1),h.substr(1)):h,j1n,vZn));case 33:return null==t?null:new PN((f=yXn(t,!0)).length>0&&(s3(0,f.length),43==f.charCodeAt(0))?(s3(1,f.length+1),f.substr(1)):f);case 34:return null==t?null:xwn(vUn((l=yXn(t,!0)).length>0&&(s3(0,l.length),43==l.charCodeAt(0))?(s3(1,l.length+1),l.substr(1)):l,j1n,vZn));case 36:return null==t?null:Hvn(tJn((b=yXn(t,!0)).length>0&&(s3(0,b.length),43==b.charCodeAt(0))?(s3(1,b.length+1),b.substr(1)):b));case 37:return null==t?null:Hvn(tJn((w=yXn(t,!0)).length>0&&(s3(0,w.length),43==w.charCodeAt(0))?(s3(1,w.length+1),w.substr(1)):w));case 40:return nTn((uVn(),t));case 42:return dvn((uVn(),t));case 43:return dvn(t);case 44:return null==t?null:new PN((d=yXn(t,!0)).length>0&&(s3(0,d.length),43==d.charCodeAt(0))?(s3(1,d.length+1),d.substr(1)):d);case 45:return null==t?null:new PN((g=yXn(t,!0)).length>0&&(s3(0,g.length),43==g.charCodeAt(0))?(s3(1,g.length+1),g.substr(1)):g);case 46:return yXn(t,!1);case 47:return mK(cYn(this,(uVn(),QBt),t));case 59:case 48:return ZMn((uVn(),t));case 49:return mK(cYn(this,(uVn(),YBt),t));case 50:return null==t?null:Rwn(vUn((p=yXn(t,!0)).length>0&&(s3(0,p.length),43==p.charCodeAt(0))?(s3(1,p.length+1),p.substr(1)):p,xrt,32767)<<16>>16);case 51:return null==t?null:Rwn(vUn((c=yXn(t,!0)).length>0&&(s3(0,c.length),43==c.charCodeAt(0))?(s3(1,c.length+1),c.substr(1)):c,xrt,32767)<<16>>16);case 53:return mK(cYn(this,(uVn(),tHt),t));case 55:return null==t?null:Rwn(vUn((a=yXn(t,!0)).length>0&&(s3(0,a.length),43==a.charCodeAt(0))?(s3(1,a.length+1),a.substr(1)):a,xrt,32767)<<16>>16);case 56:return null==t?null:Rwn(vUn((o=yXn(t,!0)).length>0&&(s3(0,o.length),43==o.charCodeAt(0))?(s3(1,o.length+1),o.substr(1)):o,xrt,32767)<<16>>16);case 57:return null==t?null:Hvn(tJn((u=yXn(t,!0)).length>0&&(s3(0,u.length),43==u.charCodeAt(0))?(s3(1,u.length+1),u.substr(1)):u));case 58:return null==t?null:Hvn(tJn((s=yXn(t,!0)).length>0&&(s3(0,s.length),43==s.charCodeAt(0))?(s3(1,s.length+1),s.substr(1)):s));case 60:return null==t?null:xwn(vUn((e=yXn(t,!0)).length>0&&(s3(0,e.length),43==e.charCodeAt(0))?(s3(1,e.length+1),e.substr(1)):e,j1n,vZn));case 61:return null==t?null:xwn(vUn(yXn(t,!0),j1n,vZn));default:throw hv(new vM(tet+n.xe()+eet))}},zW(kct,"XMLTypeFactoryImpl",2028),sDn(594,184,{110:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,54:1,99:1,158:1,184:1,119:1,120:1,690:1,2044:1,594:1},gJ),uZn.N=!1,uZn.O=!1;var dHt,gHt,pHt,mHt,vHt,kHt=!1;zW(kct,"XMLTypePackageImpl",594),sDn(1961,1,{851:1},$h),uZn.Kk=function(){return vGn(),qHt},zW(kct,"XMLTypePackageImpl/1",1961),sDn(1970,1,Wrt,Dh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/10",1970),sDn(1971,1,Wrt,xh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/11",1971),sDn(1972,1,Wrt,Rh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/12",1972),sDn(1973,1,Wrt,Kh),uZn.fk=function(n){return FA(n)},uZn.gk=function(n){return Inn(fot,zZn,345,n,7,1)},zW(kct,"XMLTypePackageImpl/13",1973),sDn(1974,1,Wrt,Fh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/14",1974),sDn(1975,1,Wrt,_h),uZn.fk=function(n){return F$(n,15)},uZn.gk=function(n){return Inn(yat,H3n,15,n,0,1)},zW(kct,"XMLTypePackageImpl/15",1975),sDn(1976,1,Wrt,Bh),uZn.fk=function(n){return F$(n,15)},uZn.gk=function(n){return Inn(yat,H3n,15,n,0,1)},zW(kct,"XMLTypePackageImpl/16",1976),sDn(1977,1,Wrt,Hh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/17",1977),sDn(1978,1,Wrt,Gh),uZn.fk=function(n){return F$(n,161)},uZn.gk=function(n){return Inn(lot,zZn,161,n,0,1)},zW(kct,"XMLTypePackageImpl/18",1978),sDn(1979,1,Wrt,qh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/19",1979),sDn(1962,1,Wrt,Xh),uZn.fk=function(n){return F$(n,857)},uZn.gk=function(n){return Inn(DBt,EZn,857,n,0,1)},zW(kct,"XMLTypePackageImpl/2",1962),sDn(1980,1,Wrt,zh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/20",1980),sDn(1981,1,Wrt,Vh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/21",1981),sDn(1982,1,Wrt,Wh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/22",1982),sDn(1983,1,Wrt,Qh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/23",1983),sDn(1984,1,Wrt,Jh),uZn.fk=function(n){return F$(n,195)},uZn.gk=function(n){return Inn(tUt,zZn,195,n,0,2)},zW(kct,"XMLTypePackageImpl/24",1984),sDn(1985,1,Wrt,Yh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/25",1985),sDn(1986,1,Wrt,Zh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/26",1986),sDn(1987,1,Wrt,nf),uZn.fk=function(n){return F$(n,15)},uZn.gk=function(n){return Inn(yat,H3n,15,n,0,1)},zW(kct,"XMLTypePackageImpl/27",1987),sDn(1988,1,Wrt,tf),uZn.fk=function(n){return F$(n,15)},uZn.gk=function(n){return Inn(yat,H3n,15,n,0,1)},zW(kct,"XMLTypePackageImpl/28",1988),sDn(1989,1,Wrt,ef),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/29",1989),sDn(1963,1,Wrt,rf),uZn.fk=function(n){return F$(n,681)},uZn.gk=function(n){return Inn(lHt,EZn,2119,n,0,1)},zW(kct,"XMLTypePackageImpl/3",1963),sDn(1990,1,Wrt,cf),uZn.fk=function(n){return F$(n,17)},uZn.gk=function(n){return Inn(dot,zZn,17,n,0,1)},zW(kct,"XMLTypePackageImpl/30",1990),sDn(1991,1,Wrt,af),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/31",1991),sDn(1992,1,Wrt,of),uZn.fk=function(n){return F$(n,168)},uZn.gk=function(n){return Inn(yot,zZn,168,n,0,1)},zW(kct,"XMLTypePackageImpl/32",1992),sDn(1993,1,Wrt,uf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/33",1993),sDn(1994,1,Wrt,sf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/34",1994),sDn(1995,1,Wrt,hf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/35",1995),sDn(1996,1,Wrt,ff),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/36",1996),sDn(1997,1,Wrt,lf),uZn.fk=function(n){return F$(n,15)},uZn.gk=function(n){return Inn(yat,H3n,15,n,0,1)},zW(kct,"XMLTypePackageImpl/37",1997),sDn(1998,1,Wrt,bf),uZn.fk=function(n){return F$(n,15)},uZn.gk=function(n){return Inn(yat,H3n,15,n,0,1)},zW(kct,"XMLTypePackageImpl/38",1998),sDn(1999,1,Wrt,wf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/39",1999),sDn(1964,1,Wrt,df),uZn.fk=function(n){return F$(n,682)},uZn.gk=function(n){return Inn(bHt,EZn,2120,n,0,1)},zW(kct,"XMLTypePackageImpl/4",1964),sDn(2e3,1,Wrt,gf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/40",2e3),sDn(2001,1,Wrt,pf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/41",2001),sDn(2002,1,Wrt,mf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/42",2002),sDn(2003,1,Wrt,vf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/43",2003),sDn(2004,1,Wrt,kf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/44",2004),sDn(2005,1,Wrt,yf),uZn.fk=function(n){return F$(n,191)},uZn.gk=function(n){return Inn(Tot,zZn,191,n,0,1)},zW(kct,"XMLTypePackageImpl/45",2005),sDn(2006,1,Wrt,Mf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/46",2006),sDn(2007,1,Wrt,Tf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/47",2007),sDn(2008,1,Wrt,jf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/48",2008),sDn(2009,1,Wrt,Ef),uZn.fk=function(n){return F$(n,191)},uZn.gk=function(n){return Inn(Tot,zZn,191,n,0,1)},zW(kct,"XMLTypePackageImpl/49",2009),sDn(1965,1,Wrt,Sf),uZn.fk=function(n){return F$(n,683)},uZn.gk=function(n){return Inn(wHt,EZn,2121,n,0,1)},zW(kct,"XMLTypePackageImpl/5",1965),sDn(2010,1,Wrt,Pf),uZn.fk=function(n){return F$(n,168)},uZn.gk=function(n){return Inn(yot,zZn,168,n,0,1)},zW(kct,"XMLTypePackageImpl/50",2010),sDn(2011,1,Wrt,Cf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/51",2011),sDn(2012,1,Wrt,If),uZn.fk=function(n){return F$(n,17)},uZn.gk=function(n){return Inn(dot,zZn,17,n,0,1)},zW(kct,"XMLTypePackageImpl/52",2012),sDn(1966,1,Wrt,Of),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/6",1966),sDn(1967,1,Wrt,Af),uZn.fk=function(n){return F$(n,195)},uZn.gk=function(n){return Inn(tUt,zZn,195,n,0,2)},zW(kct,"XMLTypePackageImpl/7",1967),sDn(1968,1,Wrt,Lf),uZn.fk=function(n){return KA(n)},uZn.gk=function(n){return Inn(cot,zZn,485,n,8,1)},zW(kct,"XMLTypePackageImpl/8",1968),sDn(1969,1,Wrt,Nf),uZn.fk=function(n){return F$(n,222)},uZn.gk=function(n){return Inn(uot,zZn,222,n,0,1)},zW(kct,"XMLTypePackageImpl/9",1969),sDn(55,63,S1n,CM),zW(Xct,"RegEx/ParseException",55),sDn(836,1,{},$f),uZn.bm=function(n){return n16*e)throw hv(new CM(rZn((t$(),Cit))));e=16*e+r}if(125!=this.a)throw hv(new CM(rZn((t$(),Iit))));if(e>zct)throw hv(new CM(rZn((t$(),Oit))));n=e}else{if(r=0,0!=this.c||(r=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(e=r,EYn(this),0!=this.c||(r=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));n=e=16*e+r}break;case 117:if(i=0,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=16*t+i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=16*t+i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));n=t=16*t+i;break;case 118:if(EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=16*t+i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=16*t+i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=16*t+i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=16*t+i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if((t=16*t+i)>zct)throw hv(new CM(rZn((t$(),"parser.descappe.4"))));n=t;break;case 65:case 90:case 122:throw hv(new CM(rZn((t$(),Ait))))}return n},uZn.dm=function(n){var t;switch(n){case 100:t=32&~this.e?(QYn(),CHt):kJn("Nd",!0);break;case 68:t=32&~this.e?(QYn(),NHt):kJn("Nd",!1);break;case 119:t=32&~this.e?(QYn(),HHt):kJn("IsWord",!0);break;case 87:t=32&~this.e?(QYn(),DHt):kJn("IsWord",!1);break;case 115:t=32&~this.e?(QYn(),RHt):kJn("IsSpace",!0);break;case 83:t=32&~this.e?(QYn(),$Ht):kJn("IsSpace",!1);break;default:throw hv(new Ky(Vct+n.toString(16)))}return t},uZn.em=function(n){var t,e,i,r,c,a,o,u,s,h,f;for(this.b=1,EYn(this),t=null,0==this.c&&94==this.a?(EYn(this),n?(QYn(),QYn(),s=new K3(5)):(QYn(),QYn(),HFn(t=new K3(4),0,zct),s=new K3(4))):(QYn(),QYn(),s=new K3(4)),r=!0;1!=(f=this.c)&&(0!=f||93!=this.a||r);){if(r=!1,e=this.a,i=!1,10==f)switch(e){case 100:case 68:case 119:case 87:case 115:case 83:TXn(s,this.dm(e)),i=!0;break;case 105:case 73:case 99:case 67:(e=this.um(s,e))<0&&(i=!0);break;case 112:case 80:if(!(h=PNn(this,e)))throw hv(new CM(rZn((t$(),git))));TXn(s,h),i=!0;break;default:e=this.cm()}else if(20==f){if((c=aR(this.i,58,this.d))<0)throw hv(new CM(rZn((t$(),pit))));if(a=!0,94==VJ(this.i,this.d)&&(++this.d,a=!1),!(o=itn(r1(this.i,this.d,c),a,!(512&~this.e))))throw hv(new CM(rZn((t$(),vit))));if(TXn(s,o),i=!0,c+1>=this.j||93!=VJ(this.i,c+1))throw hv(new CM(rZn((t$(),pit))));this.d=c+2}if(EYn(this),!i)if(0!=this.c||45!=this.a)HFn(s,e,e);else{if(EYn(this),1==(f=this.c))throw hv(new CM(rZn((t$(),mit))));0==f&&93==this.a?(HFn(s,e,e),HFn(s,45,45)):(u=this.a,10==f&&(u=this.cm()),EYn(this),HFn(s,e,u))}(this.e&w1n)==w1n&&0==this.c&&44==this.a&&EYn(this)}if(1==this.c)throw hv(new CM(rZn((t$(),mit))));return t&&(lWn(t,s),s=t),pxn(s),szn(s),this.b=0,EYn(this),s},uZn.fm=function(){var n,t,e,i;for(e=this.em(!1);7!=(i=this.c);){if(n=this.a,(0!=i||45!=n&&38!=n)&&4!=i)throw hv(new CM(rZn((t$(),Eit))));if(EYn(this),9!=this.c)throw hv(new CM(rZn((t$(),jit))));if(t=this.em(!1),4==i)TXn(e,t);else if(45==n)lWn(e,t);else{if(38!=n)throw hv(new Ky("ASSERT"));GVn(e,t)}}return EYn(this),e},uZn.gm=function(){var n,t;return n=this.a-48,QYn(),QYn(),t=new F1(12,null,n),!this.g&&(this.g=new ck),zv(this.g,new Wm(n)),EYn(this),t},uZn.hm=function(){return EYn(this),QYn(),KHt},uZn.im=function(){return EYn(this),QYn(),xHt},uZn.jm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.km=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.lm=function(){return EYn(this),jln()},uZn.mm=function(){return EYn(this),QYn(),_Ht},uZn.nm=function(){return EYn(this),QYn(),UHt},uZn.om=function(){var n;if(this.d>=this.j||64!=(65504&(n=VJ(this.i,this.d++))))throw hv(new CM(rZn((t$(),lit))));return EYn(this),QYn(),QYn(),new IX(0,n-64)},uZn.pm=function(){return EYn(this),VGn()},uZn.qm=function(){return EYn(this),QYn(),GHt},uZn.rm=function(){var n;return QYn(),QYn(),n=new IX(0,105),EYn(this),n},uZn.sm=function(){return EYn(this),QYn(),BHt},uZn.tm=function(){return EYn(this),QYn(),FHt},uZn.um=function(n,t){return this.cm()},uZn.vm=function(){return EYn(this),QYn(),AHt},uZn.wm=function(){var n,t,e,i,r;if(this.d+1>=this.j)throw hv(new CM(rZn((t$(),sit))));if(i=-1,t=null,49<=(n=VJ(this.i,this.d))&&n<=57){if(i=n-48,!this.g&&(this.g=new ck),zv(this.g,new Wm(i)),++this.d,41!=VJ(this.i,this.d))throw hv(new CM(rZn((t$(),ait))));++this.d}else switch(63==n&&--this.d,EYn(this),(t=eYn(this)).e){case 20:case 21:case 22:case 23:break;case 8:if(7!=this.c)throw hv(new CM(rZn((t$(),ait))));break;default:throw hv(new CM(rZn((t$(),hit))))}if(EYn(this),e=null,2==(r=Evn(this)).e){if(2!=r.Pm())throw hv(new CM(rZn((t$(),fit))));e=r.Lm(1),r=r.Lm(0)}if(7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),QYn(),QYn(),new bin(i,t,r,e)},uZn.xm=function(){return EYn(this),QYn(),LHt},uZn.ym=function(){var n;if(EYn(this),n=jV(24,Evn(this)),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.zm=function(){var n;if(EYn(this),n=jV(20,Evn(this)),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.Am=function(){var n;if(EYn(this),n=jV(22,Evn(this)),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.Bm=function(){var n,t,e,i,r;for(n=0,e=0,t=-1;this.d=this.j)throw hv(new CM(rZn((t$(),oit))));if(45==t){for(++this.d;this.d=this.j)throw hv(new CM(rZn((t$(),oit))))}if(58==t){if(++this.d,EYn(this),i=GW(Evn(this),n,e),7!=this.c)throw hv(new CM(rZn((t$(),ait))));EYn(this)}else{if(41!=t)throw hv(new CM(rZn((t$(),uit))));++this.d,EYn(this),i=GW(Evn(this),n,e)}return i},uZn.Cm=function(){var n;if(EYn(this),n=jV(21,Evn(this)),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.Dm=function(){var n;if(EYn(this),n=jV(23,Evn(this)),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.Em=function(){var n,t;if(EYn(this),n=this.f++,t=EV(Evn(this),n),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),t},uZn.Fm=function(){var n;if(EYn(this),n=EV(Evn(this),0),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.Gm=function(n){return EYn(this),5==this.c?(EYn(this),CX(n,(QYn(),QYn(),new n8(9,n)))):CX(n,(QYn(),QYn(),new n8(3,n)))},uZn.Hm=function(n){var t;return EYn(this),QYn(),QYn(),t=new QN(2),5==this.c?(EYn(this),kzn(t,OHt),kzn(t,n)):(kzn(t,n),kzn(t,OHt)),t},uZn.Im=function(n){return EYn(this),5==this.c?(EYn(this),QYn(),QYn(),new n8(9,n)):(QYn(),QYn(),new n8(3,n))},uZn.a=0,uZn.b=0,uZn.c=0,uZn.d=0,uZn.e=0,uZn.f=1,uZn.g=null,uZn.j=0,zW(Xct,"RegEx/RegexParser",836),sDn(1947,836,{},ay),uZn.bm=function(n){return!1},uZn.cm=function(){return R_n(this)},uZn.dm=function(n){return MUn(n)},uZn.em=function(n){return PYn(this)},uZn.fm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.gm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.hm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.im=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.jm=function(){return EYn(this),MUn(67)},uZn.km=function(){return EYn(this),MUn(73)},uZn.lm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.mm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.nm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.om=function(){return EYn(this),MUn(99)},uZn.pm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.qm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.rm=function(){return EYn(this),MUn(105)},uZn.sm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.tm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.um=function(n,t){return TXn(n,MUn(t)),-1},uZn.vm=function(){return EYn(this),QYn(),QYn(),new IX(0,94)},uZn.wm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.xm=function(){return EYn(this),QYn(),QYn(),new IX(0,36)},uZn.ym=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.zm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.Am=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.Bm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.Cm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.Dm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.Em=function(){var n;if(EYn(this),n=EV(Evn(this),0),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.Fm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.Gm=function(n){return EYn(this),CX(n,(QYn(),QYn(),new n8(3,n)))},uZn.Hm=function(n){var t;return EYn(this),QYn(),QYn(),kzn(t=new QN(2),n),kzn(t,OHt),t},uZn.Im=function(n){return EYn(this),QYn(),QYn(),new n8(3,n)};var yHt=null,MHt=null;zW(Xct,"RegEx/ParserForXMLSchema",1947),sDn(122,1,aat,Qm),uZn.Jm=function(n){throw hv(new Ky("Not supported."))},uZn.Km=function(){return-1},uZn.Lm=function(n){return null},uZn.Mm=function(){return null},uZn.Nm=function(n){},uZn.Om=function(n){},uZn.Pm=function(){return 0},uZn.Ib=function(){return this.Qm(0)},uZn.Qm=function(n){return 11==this.e?".":""},uZn.e=0;var THt,jHt,EHt,SHt,PHt,CHt,IHt,OHt,AHt,LHt,NHt,$Ht,DHt,xHt,RHt,KHt,FHt,_Ht,BHt,HHt,UHt,GHt,qHt,XHt,zHt=null,VHt=null,WHt=null,QHt=zW(Xct,"RegEx/Token",122);sDn(138,122,{3:1,138:1,122:1},K3),uZn.Qm=function(n){var t,e,i;if(4==this.e)if(this==IHt)e=".";else if(this==CHt)e="\\d";else if(this==HHt)e="\\w";else if(this==RHt)e="\\s";else{for((i=new zM).a+="[",t=0;t0&&(i.a+=","),this.b[t]===this.b[t+1]?VA(i,Mqn(this.b[t])):(VA(i,Mqn(this.b[t])),i.a+="-",VA(i,Mqn(this.b[t+1])));i.a+="]",e=i.a}else if(this==NHt)e="\\D";else if(this==DHt)e="\\W";else if(this==$Ht)e="\\S";else{for((i=new zM).a+="[^",t=0;t0&&(i.a+=","),this.b[t]===this.b[t+1]?VA(i,Mqn(this.b[t])):(VA(i,Mqn(this.b[t])),i.a+="-",VA(i,Mqn(this.b[t+1])));i.a+="]",e=i.a}return e},uZn.a=!1,uZn.c=!1,zW(Xct,"RegEx/RangeToken",138),sDn(592,1,{592:1},Wm),uZn.a=0,zW(Xct,"RegEx/RegexParser/ReferencePosition",592),sDn(591,1,{3:1,591:1},gE),uZn.Fb=function(n){var t;return null!=n&&!!F$(n,591)&&(t=uG(n,591),m_(this.b,t.b)&&this.a==t.a)},uZn.Hb=function(){return pln(this.b+"/"+XKn(this.a))},uZn.Ib=function(){return this.c.Qm(this.a)},uZn.a=0,zW(Xct,"RegEx/RegularExpression",591),sDn(228,122,aat,IX),uZn.Km=function(){return this.a},uZn.Qm=function(n){var t,e;switch(this.e){case 0:switch(this.a){case 124:case 42:case 43:case 63:case 40:case 41:case 46:case 91:case 123:case 92:e="\\"+jF(this.a&D1n);break;case 12:e="\\f";break;case 10:e="\\n";break;case 13:e="\\r";break;case 9:e="\\t";break;case 27:e="\\e";break;default:e=this.a>=P0n?"\\v"+r1(t="0"+(this.a>>>0).toString(16),t.length-6,t.length):""+jF(this.a&D1n)}break;case 8:e=this==AHt||this==LHt?""+jF(this.a&D1n):"\\"+jF(this.a&D1n);break;default:e=null}return e},uZn.a=0,zW(Xct,"RegEx/Token/CharToken",228),sDn(318,122,aat,n8),uZn.Lm=function(n){return this.a},uZn.Nm=function(n){this.b=n},uZn.Om=function(n){this.c=n},uZn.Pm=function(){return 1},uZn.Qm=function(n){var t;if(3==this.e)if(this.c<0&&this.b<0)t=this.a.Qm(n)+"*";else if(this.c==this.b)t=this.a.Qm(n)+"{"+this.c+"}";else if(this.c>=0&&this.b>=0)t=this.a.Qm(n)+"{"+this.c+","+this.b+"}";else{if(!(this.c>=0&&this.b<0))throw hv(new Ky("Token#toString(): CLOSURE "+this.c+TZn+this.b));t=this.a.Qm(n)+"{"+this.c+",}"}else if(this.c<0&&this.b<0)t=this.a.Qm(n)+"*?";else if(this.c==this.b)t=this.a.Qm(n)+"{"+this.c+"}?";else if(this.c>=0&&this.b>=0)t=this.a.Qm(n)+"{"+this.c+","+this.b+"}?";else{if(!(this.c>=0&&this.b<0))throw hv(new Ky("Token#toString(): NONGREEDYCLOSURE "+this.c+TZn+this.b));t=this.a.Qm(n)+"{"+this.c+",}?"}return t},uZn.b=0,uZn.c=0,zW(Xct,"RegEx/Token/ClosureToken",318),sDn(837,122,aat,eW),uZn.Lm=function(n){return 0==n?this.a:this.b},uZn.Pm=function(){return 2},uZn.Qm=function(n){return 3==this.b.e&&this.b.Lm(0)==this.a?this.a.Qm(n)+"+":9==this.b.e&&this.b.Lm(0)==this.a?this.a.Qm(n)+"+?":this.a.Qm(n)+""+this.b.Qm(n)},zW(Xct,"RegEx/Token/ConcatToken",837),sDn(1945,122,aat,bin),uZn.Lm=function(n){if(0==n)return this.d;if(1==n)return this.b;throw hv(new Ky("Internal Error: "+n))},uZn.Pm=function(){return this.b?2:1},uZn.Qm=function(n){var t;return t=this.c>0?"(?("+this.c+")":8==this.a.e?"(?("+this.a+")":"(?"+this.a,this.b?t+=this.d+"|"+this.b+")":t+=this.d+")",t},uZn.c=0,zW(Xct,"RegEx/Token/ConditionToken",1945),sDn(1946,122,aat,R3),uZn.Lm=function(n){return this.b},uZn.Pm=function(){return 1},uZn.Qm=function(n){return"(?"+(0==this.a?"":XKn(this.a))+(0==this.c?"":XKn(this.c))+":"+this.b.Qm(n)+")"},uZn.a=0,uZn.c=0,zW(Xct,"RegEx/Token/ModifierToken",1946),sDn(838,122,aat,PQ),uZn.Lm=function(n){return this.a},uZn.Pm=function(){return 1},uZn.Qm=function(n){var t;switch(t=null,this.e){case 6:t=0==this.b?"(?:"+this.a.Qm(n)+")":"("+this.a.Qm(n)+")";break;case 20:t="(?="+this.a.Qm(n)+")";break;case 21:t="(?!"+this.a.Qm(n)+")";break;case 22:t="(?<="+this.a.Qm(n)+")";break;case 23:t="(?"+this.a.Qm(n)+")"}return t},uZn.b=0,zW(Xct,"RegEx/Token/ParenToken",838),sDn(530,122,{3:1,122:1,530:1},F1),uZn.Mm=function(){return this.b},uZn.Qm=function(n){return 12==this.e?"\\"+this.a:Nxn(this.b)},uZn.a=0,zW(Xct,"RegEx/Token/StringToken",530),sDn(477,122,aat,QN),uZn.Jm=function(n){kzn(this,n)},uZn.Lm=function(n){return uG(DQ(this.a,n),122)},uZn.Pm=function(){return this.a?this.a.a.c.length:0},uZn.Qm=function(n){var t,e,i,r,c;if(1==this.e){if(2==this.a.a.c.length)t=uG(DQ(this.a,0),122),r=3==(e=uG(DQ(this.a,1),122)).e&&e.Lm(0)==t?t.Qm(n)+"+":9==e.e&&e.Lm(0)==t?t.Qm(n)+"+?":t.Qm(n)+""+e.Qm(n);else{for(c=new zM,i=0;i=this.c.b:this.a<=this.c.b},uZn.Sb=function(){return this.b>0},uZn.Tb=function(){return this.b},uZn.Vb=function(){return this.b-1},uZn.Qb=function(){throw hv(new TM(lat))},uZn.a=0,uZn.b=0,zW(sat,"ExclusiveRange/RangeIterator",258);var JHt=hJ(brt,"C"),YHt=hJ(grt,"I"),ZHt=hJ(dZn,"Z"),nUt=hJ(prt,"J"),tUt=hJ(lrt,"B"),eUt=hJ(wrt,"D"),iUt=hJ(drt,"F"),rUt=hJ(mrt,"S"),cUt=Iq("org.eclipse.elk.core.labels","ILabelManager"),aUt=Iq(Pet,"DiagnosticChain"),oUt=Iq(Jrt,"ResourceSet"),uUt=zW(Pet,"InvocationTargetException",null),sUt=(XM(),m9),hUt=hUt=zSn;Nan(bv),van("permProps",[[["locale","default"],[bat,"gecko1_8"]],[["locale","default"],[bat,"safari"]]]),hUt(null,"elk",null)}).call(this)}).call(this,void 0!==e.g?e.g:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(n,t,e){"use strict";function i(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}function r(n,t){if(!n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?n:t}function c(n,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);n.prototype=Object.create(t&&t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(n,t):n.__proto__=t)}var a=function(t){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,e);var c=Object.assign({},t),a=!1;try{n.resolve("web-worker"),a=!0}catch(s){}if(t.workerUrl)if(a){var o=n("web-worker");c.workerFactory=function(n){return new o(n)}}else console.warn("Web worker requested but 'web-worker' package not installed. \nConsider installing the package or pass your own 'workerFactory' to ELK's constructor.\n... Falling back to non-web worker version.");if(!c.workerFactory){var u=n("./elk-worker.min.js").Worker;c.workerFactory=function(n){return new u(n)}}return r(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,c))}return c(e,t),e}(n("./elk-api.js").default);Object.defineProperty(t.exports,"__esModule",{value:!0}),t.exports=a,a.default=a},{"./elk-api.js":1,"./elk-worker.min.js":2,"web-worker":4}],4:[function(n,t,e){t.exports=Worker},{}]},{},[3])(3)},24104:(n,t,e)=>{"use strict";e.d(t,{diagram:()=>y});var i=e(35860),r=e(26312),c=e(88146),a=e(86079),o=e(62954);e(74353),e(16750),e(42838);const u=new o;let s={};const h={};let f={};const l=(n,t,e)=>{const i={TB:{in:{north:"north"},out:{south:"west",west:"east",east:"south"}},LR:{in:{west:"west"},out:{east:"south",south:"north",north:"east"}},RL:{in:{east:"east"},out:{west:"north",north:"south",south:"west"}},BT:{in:{south:"south"},out:{north:"east",east:"west",west:"north"}}};return i.TD=i.TB,i[e][t][n]},b=(n,t,e)=>{if(a.l.info("getNextPort",{node:n,edgeDirection:t,graphDirection:e}),!s[n])switch(e){case"TB":case"TD":s[n]={inPosition:"north",outPosition:"south"};break;case"BT":s[n]={inPosition:"south",outPosition:"north"};break;case"RL":s[n]={inPosition:"east",outPosition:"west"};break;case"LR":s[n]={inPosition:"west",outPosition:"east"}}const i="in"===t?s[n].inPosition:s[n].outPosition;return"in"===t?s[n].inPosition=l(s[n].inPosition,t,e):s[n].outPosition=l(s[n].outPosition,t,e),i},w=function(n,t,e,i){a.l.info("abc78 edges = ",n);const o=i.insert("g").attr("class","edgeLabels");let u,s,l={},w=t.db.getDirection();if(void 0!==n.defaultStyle){const t=(0,a.k)(n.defaultStyle);u=t.style,s=t.labelStyle}return n.forEach((function(t){const i="L-"+t.start+"-"+t.end;void 0===l[i]?(l[i]=0,a.l.info("abc78 new entry",i,l[i])):(l[i]++,a.l.info("abc78 new entry",i,l[i]));let d=i+"-"+l[i];a.l.info("abc78 new link id to be used is",i,d,l[i]);const g="LS-"+t.start,p="LE-"+t.end,m={style:"",labelStyle:""};switch(m.minlen=t.length||1,"arrow_open"===t.type?m.arrowhead="none":m.arrowhead="normal",m.arrowTypeStart="arrow_open",m.arrowTypeEnd="arrow_open",t.type){case"double_arrow_cross":m.arrowTypeStart="arrow_cross";case"arrow_cross":m.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":m.arrowTypeStart="arrow_point";case"arrow_point":m.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":m.arrowTypeStart="arrow_circle";case"arrow_circle":m.arrowTypeEnd="arrow_circle"}let v="",k="";switch(t.stroke){case"normal":v="fill:none;",void 0!==u&&(v=u),void 0!==s&&(k=s),m.thickness="normal",m.pattern="solid";break;case"dotted":m.thickness="normal",m.pattern="dotted",m.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":m.thickness="thick",m.pattern="solid",m.style="stroke-width: 3.5px;fill:none;"}if(void 0!==t.style){const n=(0,a.k)(t.style);v=n.style,k=n.labelStyle}m.style=m.style+=v,m.labelStyle=m.labelStyle+=k,void 0!==t.interpolate?m.curve=(0,a.n)(t.interpolate,r.lUB):void 0!==n.defaultInterpolate?m.curve=(0,a.n)(n.defaultInterpolate,r.lUB):m.curve=(0,a.n)(h.curve,r.lUB),void 0===t.text?void 0!==t.style&&(m.arrowheadStyle="fill: #333"):(m.arrowheadStyle="fill: #333",m.labelpos="c"),m.labelType=t.labelType,m.label=t.text.replace(a.e.lineBreakRegex,"\n"),void 0===t.style&&(m.style=m.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),m.labelStyle=m.labelStyle.replace("color:","fill:"),m.id=d,m.classes="flowchart-link "+g+" "+p;const y=(0,c.f)(o,m),{source:M,target:T,sourceId:j,targetId:E}=((n,t)=>{let e=n.start,i=n.end;const r=e,c=i,a=f[e],o=f[i];return a&&o?("diamond"===a.type&&(e=`${e}-${b(e,"out",t)}`),"diamond"===o.type&&(i=`${i}-${b(i,"in",t)}`),{source:e,target:i,sourceId:r,targetId:c}):{source:e,target:i}})(t,w);a.l.debug("abc78 source and target",M,T),e.edges.push({id:"e"+t.start+t.end,sources:[M],targets:[T],sourceId:j,targetId:E,labelEl:y,labels:[{width:m.width,height:m.height,orgWidth:m.width,orgHeight:m.height,text:m.label,layoutOptions:{"edgeLabels.inline":"true","edgeLabels.placement":"CENTER"}}],edgeData:m})})),e},d=function(n,t,e){const i=((n,t,e)=>{const{parentById:i}=e,r=new Set;let c=n;for(;c;){if(r.add(c),c===t)return c;c=i[c]}for(c=t;c;){if(r.has(c))return c;c=i[c]}return"root"})(n,t,e);if(void 0===i||"root"===i)return{x:0,y:0};const r=f[i].offset;return{x:r.posX,y:r.posY}},g=function(n,t,e,i,a,o){const u=d(t.sourceId,t.targetId,a),s=t.sections[0].startPoint,h=t.sections[0].endPoint,f=(t.sections[0].bendPoints?t.sections[0].bendPoints:[]).map((n=>[n.x+u.x,n.y+u.y])),l=[[s.x+u.x,s.y+u.y],...f,[h.x+u.x,h.y+u.y]],{x:b,y:w}=(0,c.k)(t.edgeData),g=(0,r.n8j)().x(b).y(w).curve(r.lUB),p=n.insert("path").attr("d",g(l)).attr("class","path "+e.classes).attr("fill","none"),m=n.insert("g").attr("class","edgeLabel"),v=(0,r.Ltv)(m.node().appendChild(t.labelEl)),k=v.node().firstChild.getBoundingClientRect();v.attr("width",k.width),v.attr("height",k.height),m.attr("transform",`translate(${t.labels[0].x+u.x}, ${t.labels[0].y+u.y})`),function(n,t,e,i,r){let a="";i&&(a=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,a=a.replace(/\(/g,"\\("),a=a.replace(/\)/g,"\\)")),(0,c.m)(n,t,a,r,e)}(p,e,i.type,i.arrowMarkerAbsolute,o)},p=(n,t)=>{n.forEach((n=>{n.children||(n.children=[]);const e=t.childrenById[n.id];e&&e.forEach((t=>{n.children.push(f[t])})),p(n.children,t)}))},m=(n,t,e,i,r,c,o)=>{e.forEach((function(e){if(e)if(f[e.id].offset={posX:e.x+n,posY:e.y+t,x:n,y:t,depth:o,width:e.width,height:e.height},"group"===e.type){const i=r.insert("g").attr("class","subgraph");i.insert("rect").attr("class","subgraph subgraph-lvl-"+o%5+" node").attr("x",e.x+n).attr("y",e.y+t).attr("width",e.width).attr("height",e.height);const c=i.insert("g").attr("class","label"),u=(0,a.F)().flowchart.htmlLabels?e.labelData.width/2:0;c.attr("transform",`translate(${e.labels[0].x+n+e.x+u}, ${e.labels[0].y+t+e.y+3})`),c.node().appendChild(e.labelData.labelNode),a.l.info("Id (UGH)= ",e.type,e.labels)}else a.l.info("Id (UGH)= ",e.id),e.el.attr("transform",`translate(${e.x+n+e.width/2}, ${e.y+t+e.height/2})`)})),e.forEach((function(e){e&&"group"===e.type&&m(n+e.x,t+e.y,e.children,i,r,c,o+1)}))},v={getClasses:function(n,t){return a.l.info("Extracting classes"),t.db.getClasses()},draw:async function(n,t,e,i){var o;i.db.clear(),f={},s={},i.db.setGen("gen-2"),i.parser.parse(n);const h=(0,r.Ltv)("body").append("div").attr("style","height:400px").attr("id","cy");let l={id:"root",layoutOptions:{"elk.hierarchyHandling":"INCLUDE_CHILDREN","org.eclipse.elk.padding":"[top=100, left=100, bottom=110, right=110]","elk.layered.spacing.edgeNodeBetweenLayers":"30","elk.direction":"DOWN"},children:[],edges:[]};switch(a.l.info("Drawing flowchart using v3 renderer",u),i.db.getDirection()){case"BT":l.layoutOptions["elk.direction"]="UP";break;case"TB":l.layoutOptions["elk.direction"]="DOWN";break;case"LR":l.layoutOptions["elk.direction"]="RIGHT";break;case"RL":l.layoutOptions["elk.direction"]="LEFT"}const{securityLevel:b,flowchart:d}=(0,a.F)();let v;"sandbox"===b&&(v=(0,r.Ltv)("#i"+t));const k="sandbox"===b?(0,r.Ltv)(v.nodes()[0].contentDocument.body):(0,r.Ltv)("body"),y="sandbox"===b?v.nodes()[0].contentDocument:document,M=k.select(`[id="${t}"]`);(0,c.a)(M,["point","circle","cross"],i.type,t);const T=i.db.getVertices();let j;const E=i.db.getSubGraphs();a.l.info("Subgraphs - ",E);for(let r=E.length-1;r>=0;r--)j=E[r],i.db.addVertex(j.id,{text:j.title,type:j.labelType},"group",void 0,j.classes,j.dir);const S=M.insert("g").attr("class","subgraphs"),P=function(n){const t={parentById:{},childrenById:{}},e=n.getSubGraphs();return a.l.info("Subgraphs - ",e),e.forEach((function(n){n.nodes.forEach((function(e){t.parentById[e]=n.id,void 0===t.childrenById[n.id]&&(t.childrenById[n.id]=[]),t.childrenById[n.id].push(e)}))})),e.forEach((function(n){n.id,void 0!==t.parentById[n.id]&&t.parentById[n.id]})),t}(i.db);l=await async function(n,t,e,i,r,o,u){const s=e.select(`[id="${t}"]`).insert("g").attr("class","nodes"),h=Object.keys(n);return await Promise.all(h.map((async function(t){const e=n[t];let u="default";e.classes.length>0&&(u=e.classes.join(" ")),u+=" flowchart-label";const h=(0,a.k)(e.styles);let l=void 0!==e.text?e.text:e.id;const b={width:0,height:0},w=[{id:e.id+"-west",layoutOptions:{"port.side":"WEST"}},{id:e.id+"-east",layoutOptions:{"port.side":"EAST"}},{id:e.id+"-south",layoutOptions:{"port.side":"SOUTH"}},{id:e.id+"-north",layoutOptions:{"port.side":"NORTH"}}];let d=0,g="",p={};switch(e.type){case"round":d=5,g="rect";break;case"square":case"group":default:g="rect";break;case"diamond":g="question",p={portConstraints:"FIXED_SIDE"};break;case"hexagon":g="hexagon";break;case"odd":case"odd_right":g="rect_left_inv_arrow";break;case"lean_right":g="lean_right";break;case"lean_left":g="lean_left";break;case"trapezoid":g="trapezoid";break;case"inv_trapezoid":g="inv_trapezoid";break;case"circle":g="circle";break;case"ellipse":g="ellipse";break;case"stadium":g="stadium";break;case"subroutine":g="subroutine";break;case"cylinder":g="cylinder";break;case"doublecircle":g="doublecircle"}const m={labelStyle:h.labelStyle,shape:g,labelText:l,labelType:e.labelType,rx:d,ry:d,class:u,style:h.style,id:e.id,link:e.link,linkTarget:e.linkTarget,tooltip:r.db.getTooltip(e.id)||"",domId:r.db.lookUpDomId(e.id),haveCallback:e.haveCallback,width:"group"===e.type?500:void 0,dir:e.dir,type:e.type,props:e.props,padding:(0,a.F)().flowchart.padding};let v,k;if("group"!==m.type)k=await(0,c.e)(s,m,e.dir),v=k.node().getBBox();else{i.createElementNS("http://www.w3.org/2000/svg","text");const{shapeSvg:n,bbox:t}=await(0,c.l)(s,m,void 0,!0);b.width=t.width,b.wrappingWidth=(0,a.F)().flowchart.wrappingWidth,b.height=t.height,b.labelNode=n.node(),m.labelData=b}const y={id:e.id,ports:"diamond"===e.type?w:[],layoutOptions:p,labelText:l,labelData:b,domId:r.db.lookUpDomId(e.id),width:null==v?void 0:v.width,height:null==v?void 0:v.height,type:e.type,el:k,parent:o.parentById[e.id]};f[m.id]=y}))),u}(T,t,k,y,i,P,l);const C=M.insert("g").attr("class","edges edgePath"),I=i.db.getEdges();l=w(I,i,l,M);Object.keys(f).forEach((n=>{const t=f[n];t.parent||l.children.push(t),void 0!==P.childrenById[n]&&(t.labels=[{text:t.labelText,layoutOptions:{"nodeLabels.placement":"[H_CENTER, V_TOP, INSIDE]"},width:t.labelData.width,height:t.labelData.height}],delete t.x,delete t.y,delete t.width,delete t.height)})),p(l.children,P),a.l.info("after layout",JSON.stringify(l,null,2));const O=await u.layout(l);m(0,0,O.children,M,S,i,0),a.l.info("after layout",O),null==(o=O.edges)||o.map((n=>{g(C,n,n.edgeData,i,P,t)})),(0,a.o)({},M,d.diagramPadding,d.useMaxWidth),h.remove()}},k=n=>`.label {\n font-family: ${n.fontFamily};\n color: ${n.nodeTextColor||n.textColor};\n }\n .cluster-label text {\n fill: ${n.titleColor};\n }\n .cluster-label span {\n color: ${n.titleColor};\n }\n\n .label text,span {\n fill: ${n.nodeTextColor||n.textColor};\n color: ${n.nodeTextColor||n.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${n.mainBkg};\n stroke: ${n.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${n.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${n.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${n.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${n.edgeLabelBackground};\n rect {\n opacity: 0.85;\n background-color: ${n.edgeLabelBackground};\n fill: ${n.edgeLabelBackground};\n }\n text-align: center;\n }\n\n .cluster rect {\n fill: ${n.clusterBkg};\n stroke: ${n.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${n.titleColor};\n }\n\n .cluster span {\n color: ${n.titleColor};\n }\n /* .cluster div {\n color: ${n.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${n.fontFamily};\n font-size: 12px;\n background: ${n.tertiaryColor};\n border: 1px solid ${n.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${n.textColor};\n }\n .subgraph {\n stroke-width:2;\n rx:3;\n }\n // .subgraph-lvl-1 {\n // fill:#ccc;\n // // stroke:black;\n // }\n\n .flowchart-label text {\n text-anchor: middle;\n }\n\n ${(n=>{let t="";for(let e=0;e<5;e++)t+=`\n .subgraph-lvl-${e} {\n fill: ${n[`surface${e}`]};\n stroke: ${n[`surfacePeer${e}`]};\n }\n `;return t})(n)}\n`,y={db:i.d,renderer:v,parser:i.p,styles:k}}}]); \ No newline at end of file diff --git a/assets/js/25cf6706.ef87443d.js b/assets/js/25cf6706.ef87443d.js new file mode 100644 index 0000000000..d84db0c1b9 --- /dev/null +++ b/assets/js/25cf6706.ef87443d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[97104],{46305:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>r,contentTitle:()=>s,default:()=>l,frontMatter:()=>c,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/octavia","title":"Octavia","description":"* Octavia admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/octavia.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/octavia","permalink":"/docs/iaas/guides/configuration-guide/openstack/octavia","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/octavia.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Octavia"},"sidebar":"docs","previous":{"title":"Nova","permalink":"/docs/iaas/guides/configuration-guide/openstack/nova"},"next":{"title":"Placement","permalink":"/docs/iaas/guides/configuration-guide/openstack/placement"}}');var n=a(74848),o=a(28453);const c={sidebar_label:"Octavia"},s="Octavia",r={},d=[];function u(e){const t={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"octavia",children:"Octavia"})}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://docs.openstack.org/octavia/latest/admin/index.html",children:"Octavia admin guide"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://docs.openstack.org/octavia/latest/configuration/index.html",children:"Octavia configuration guide"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://docs.openstack.org/octavia/latest/configuration/configref.html",children:"Octavia configuration reference"})}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,a)=>{a.d(t,{R:()=>c,x:()=>s});var i=a(96540);const n={},o=i.createContext(n);function c(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/26bc5a46.b8c798b6.js b/assets/js/26bc5a46.b8c798b6.js new file mode 100644 index 0000000000..172da322a6 --- /dev/null +++ b/assets/js/26bc5a46.b8c798b6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[32914],{65916:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>l,frontMatter:()=>s,metadata:()=>a,toc:()=>i});const a=JSON.parse('{"id":"iaas/guides/upgrade-guide/docker","title":"Docker","description":"The Docker version used is defined via the parameter docker_version in the file","source":"@site/docs/02-iaas/guides/upgrade-guide/docker.md","sourceDirName":"02-iaas/guides/upgrade-guide","slug":"/iaas/guides/upgrade-guide/docker","permalink":"/docs/iaas/guides/upgrade-guide/docker","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/docker.md","tags":[],"version":"current","sidebarPosition":20,"frontMatter":{"sidebar_label":"Docker","sidebar_position":20},"sidebar":"docs","previous":{"title":"Ceph","permalink":"/docs/iaas/guides/upgrade-guide/ceph"},"next":{"title":"Infrastructure","permalink":"/docs/iaas/guides/upgrade-guide/infrastructure"}}');var t=r(74848),o=r(28453);const s={sidebar_label:"Docker",sidebar_position:20},d="Docker",c={},i=[{value:"Restart behaviour",id:"restart-behaviour",level:2}];function u(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"docker",children:"Docker"})}),"\n",(0,t.jsxs)(n.p,{children:["The Docker version used is defined via the parameter ",(0,t.jsx)(n.code,{children:"docker_version"})," in the file\n",(0,t.jsx)(n.code,{children:"environments/configuration.yml"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"docker_version: '5:20.10.24'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["All installable versions can be displayed with ",(0,t.jsx)(n.code,{children:"apt-cache madison docker-ce"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ apt-cache madison docker-ce\n docker-ce | 5:24.0.6-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:24.0.5-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:24.0.4-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:24.0.3-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:24.0.2-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:24.0.1-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:24.0.0-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.6-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.5-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.4-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.3-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.2-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.1-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.0-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.24~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.23~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.22~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.21~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.20~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.19~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.18~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.17~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.16~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.15~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.14~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.13~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If, for example, you want to change the Docker version from ",(0,t.jsx)(n.code,{children:"20.10.24"})," to ",(0,t.jsx)(n.code,{children:"24.0.6"}),", ",(0,t.jsx)(n.code,{children:"docker_version"})," in\n",(0,t.jsx)(n.code,{children:"environments/configuration.yml"})," is changed accordingly. The ",(0,t.jsx)(n.code,{children:"5:"})," prefix is placed in front of the version. Commit and push the changes to your configuration repository afterwards."]}),"\n",(0,t.jsx)(n.p,{children:"The upgrade of Docker is then done with the OSISM CLI. Docker on the manager itself is updated differently.\nThis does not work on the manager itself because the Docker service may be started during the upgrade and\nindividual containers may be started as a result. This would interrupt the run of the role itself."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply docker -l 'docker:!manager'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["By default, ",(0,t.jsx)(n.code,{children:"serial"})," is set to ",(0,t.jsx)(n.code,{children:"1"})," so that the the hosts are upgrade one after the other.\nTo adjust this, either use the ",(0,t.jsx)(n.code,{children:"osism_serial"})," dictionary in the ",(0,t.jsx)(n.code,{children:"environments/configuration.yml"})," file\nto change the value in ",(0,t.jsx)(n.code,{children:"docker"})," or append ",(0,t.jsx)(n.code,{children:"-e serial=10%"})," to upgrade, for example, 10%\nwith each iteration."]}),"\n",(0,t.jsx)(n.p,{children:"Please note that it is not a good idea to upgrade more than one Docker service at a time.\nThis can lead to anomalies, especially on storage nodes and control nodes. It is recommended\nnot to change the default of 1."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"osism_serial:\n docker: 10%\n"})}),"\n",(0,t.jsxs)(n.p,{children:["On the manager itself, the ",(0,t.jsx)(n.code,{children:"run.sh"})," script in the manager environment of the configuration must\ncurrently be used to upgrade the Docker service. In a future release a dedicated ",(0,t.jsx)(n.code,{children:"osism update docker"}),"\ncommand will be available for this purpose."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"cd /opt/configuration/environments/manager\nANSIBLE_ASK_VAULT_PASS=True ./run.sh docker\n"})}),"\n",(0,t.jsx)(n.h2,{id:"restart-behaviour",children:"Restart behaviour"}),"\n",(0,t.jsxs)(n.p,{children:["When upgrading, the Docker service is restarted. As a result, it can come to a restart of the\nrunning containers. This can lead to interruptions in individual services. A change in\n",(0,t.jsx)(n.code,{children:"/etc/docker/daemon.json"})," due to a new configuration parameter etc. can also result in a\nrequired restart."]}),"\n",(0,t.jsxs)(n.p,{children:["Whether the containers are restarted when the Docker Service is restarted depends on whether the\n",(0,t.jsx)(n.a,{href:"https://docs.docker.com/config/containers/live-restore/",children:"Live Restore feature"})," is used.\nThis can be configured via the parameter ",(0,t.jsx)(n.code,{children:"docker_live_restore"}),". Live restore is enabled by default."]}),"\n",(0,t.jsxs)(n.p,{children:["It is important to set the ",(0,t.jsx)(n.code,{children:"docker_live_restore"})," parameter explicitly as a string. This means\n",(0,t.jsx)(n.code,{children:'docker_live_restore: "false"'})," or ",(0,t.jsx)(n.code,{children:'docker_live_restore: "true"'}),"."]}),"\n",(0,t.jsx)(n.p,{children:"But even if the Live Restore feature is enabled, certain upgrades will cause running containers\nto be restarted:"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["Live restore allows you to keep containers running across Docker daemon updates, but is only\nsupported when installing patch releases (",(0,t.jsx)(n.code,{children:"YY.MM.x"}),"), not for major (",(0,t.jsx)(n.code,{children:"YY.MM"}),") daemon upgrades."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"There are two ways to prevent a restart of the Docker service during an upgrade."}),"\n",(0,t.jsx)(n.p,{children:"If the restart behaviour of the Docker service is changed, always make sure to restart the\nDocker service manually afterwards (e.g. by a system reboot)."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["A host group can be defined via the parameter ",(0,t.jsx)(n.code,{children:"docker_ignore_restart_groupname"}),". The\nrestart of the Docker service is not triggered for all hosts in this group. By default,\n",(0,t.jsx)(n.code,{children:"docker_ignore_restart_groupname"})," is set to ",(0,t.jsx)(n.code,{children:"manager"}),". The parameter is best set in the\n",(0,t.jsx)(n.code,{children:"environments/configuration.yml"})," file when making an adjustment. For example, to prevent\nthe restart on all hosts, ",(0,t.jsx)(n.code,{children:"docker_ignore_restart_groupname"})," is set to ",(0,t.jsx)(n.code,{children:"generic"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"docker_ignore_restart_groupname: generic\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["With the parameter ",(0,t.jsx)(n.code,{children:"docker_allow_restart"}),", the restart of the Docker service can be\nprevented. By default, ",(0,t.jsx)(n.code,{children:"docker_allow_restart"})," is set to ",(0,t.jsx)(n.code,{children:"true"}),". It is recommended to set\nthis parameter only at runtime. Otherwise, the best place for the parameter is the\n",(0,t.jsx)(n.code,{children:"environments/configuration.yml"})," file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply docker -e docker_allow_restart=false\n"})}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>s,x:()=>d});var a=r(96540);const t={},o=a.createContext(t);function s(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/26c6a551.de394283.js b/assets/js/26c6a551.de394283.js new file mode 100644 index 0000000000..0e2fe9a42c --- /dev/null +++ b/assets/js/26c6a551.de394283.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[75804],{50145:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>f,frontMatter:()=>c,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"certification/overview.template","title":"overview.template","description":"SCS certificates come with various scopes. See Scopes and Versions for details.","source":"@site/standards/certification/overview.template.md","sourceDirName":"certification","slug":"/certification/overview.template","permalink":"/standards/certification/overview.template","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{}}');var o=i(74848),s=i(28453);const c={},r="Certification",a={},l=[{value:"Becoming certified",id:"becoming-certified",level:2},{value:"Compliant cloud environments",id:"compliant-cloud-environments",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"certification",children:"Certification"})}),"\n",(0,o.jsxs)(t.p,{children:["SCS certificates come with various scopes. See ",(0,o.jsx)(t.a,{href:"/standards/certification/scopes-versions",children:"Scopes and Versions"})," for details."]}),"\n",(0,o.jsx)(t.h2,{id:"becoming-certified",children:"Becoming certified"}),"\n",(0,o.jsxs)(t.p,{children:["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 ",(0,o.jsx)(t.a,{href:"/standards/scs-0004-v1-achieving-certification",children:"document"}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"compliant-cloud-environments",children:"Compliant cloud environments"}),"\n",(0,o.jsxs)(t.p,{children:["This is a list of clouds that we test on a nightly basis against the certificate scope ",(0,o.jsx)(t.em,{children:"SCS-compatible IaaS"}),"."]})]})}function f(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>c,x:()=>r});var n=i(96540);const o={},s=n.createContext(o);function c(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/26dd306b.baa3b0e4.js b/assets/js/26dd306b.baa3b0e4.js new file mode 100644 index 0000000000..f2bd2827bf --- /dev/null +++ b/assets/js/26dd306b.baa3b0e4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[52342],{6738:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>d,default:()=>l,frontMatter:()=>r,metadata:()=>i,toc:()=>u});const i=JSON.parse('{"id":"iaas/guides/other-guides/index","title":"Other Guides","description":"","source":"@site/docs/02-iaas/guides/other-guides/index.md","sourceDirName":"02-iaas/guides/other-guides","slug":"/iaas/guides/other-guides/","permalink":"/docs/iaas/guides/other-guides/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/index.md","tags":[],"version":"current","sidebarPosition":60,"frontMatter":{"sidebar_label":"Other Guides","sidebar_position":60},"sidebar":"docs","previous":{"title":"User Data Backups","permalink":"/docs/iaas/guides/user-guide/user-data-backups"},"next":{"title":"Cloud in a Box Guide","permalink":"/docs/iaas/guides/other-guides/cloud-in-a-box/"}}');var o=t(74848),n=t(28453);const r={sidebar_label:"Other Guides",sidebar_position:60},d="Other Guides",a={},u=[];function c(e){const s={h1:"h1",header:"header",...(0,n.R)(),...e.components};return(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"other-guides",children:"Other Guides"})})}function l(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>d});var i=t(96540);const o={},n=i.createContext(o);function r(e){const s=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(n.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/26ef8bfb.441bf3ab.js b/assets/js/26ef8bfb.441bf3ab.js new file mode 100644 index 0000000000..ec1037da11 --- /dev/null +++ b/assets/js/26ef8bfb.441bf3ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[43848],{47388:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Deployment","slug":"/category/deployment","permalink":"/docs/category/deployment","sidebar":"docs","navigation":{"previous":{"title":"Contribute","permalink":"/docs/operating-scs/components/status-page-api/docs/contribute"},"next":{"title":"Overview","permalink":"/docs/operating-scs/components/status-page-deployment/docs/overview"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/27899.de8c0f95.js b/assets/js/27899.de8c0f95.js new file mode 100644 index 0000000000..a810adf3d8 --- /dev/null +++ b/assets/js/27899.de8c0f95.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[27899],{27899:(t,e,s)=>{s.d(e,{D:()=>l,S:()=>c,a:()=>h,b:()=>a,c:()=>o,d:()=>B,p:()=>r,s:()=>P});var i=s(86079),n=function(){var t=function(t,e,s,i){for(s=s||{},i=t.length;i--;s[t[i]]=e);return s},e=[1,2],s=[1,3],i=[1,4],n=[2,4],r=[1,9],o=[1,11],a=[1,15],c=[1,16],l=[1,17],h=[1,18],u=[1,30],d=[1,19],p=[1,20],y=[1,21],f=[1,22],m=[1,23],g=[1,25],S=[1,26],_=[1,27],k=[1,28],T=[1,29],b=[1,32],E=[1,33],x=[1,34],C=[1,35],$=[1,31],v=[1,4,5,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],D=[1,4,5,13,14,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],A=[4,5,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],L={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,cssClassStatement:11,idStatement:12,DESCR:13,"--\x3e":14,HIDE_EMPTY:15,scale:16,WIDTH:17,COMPOSIT_STATE:18,STRUCT_START:19,STRUCT_STOP:20,STATE_DESCR:21,AS:22,ID:23,FORK:24,JOIN:25,CHOICE:26,CONCURRENT:27,note:28,notePosition:29,NOTE_TEXT:30,direction:31,acc_title:32,acc_title_value:33,acc_descr:34,acc_descr_value:35,acc_descr_multiline_value:36,classDef:37,CLASSDEF_ID:38,CLASSDEF_STYLEOPTS:39,DEFAULT:40,class:41,CLASSENTITY_IDS:42,STYLECLASS:43,direction_tb:44,direction_bt:45,direction_rl:46,direction_lr:47,eol:48,";":49,EDGE_STATE:50,STYLE_SEPARATOR:51,left_of:52,right_of:53,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",13:"DESCR",14:"--\x3e",15:"HIDE_EMPTY",16:"scale",17:"WIDTH",18:"COMPOSIT_STATE",19:"STRUCT_START",20:"STRUCT_STOP",21:"STATE_DESCR",22:"AS",23:"ID",24:"FORK",25:"JOIN",26:"CHOICE",27:"CONCURRENT",28:"note",30:"NOTE_TEXT",32:"acc_title",33:"acc_title_value",34:"acc_descr",35:"acc_descr_value",36:"acc_descr_multiline_value",37:"classDef",38:"CLASSDEF_ID",39:"CLASSDEF_STYLEOPTS",40:"DEFAULT",41:"class",42:"CLASSENTITY_IDS",43:"STYLECLASS",44:"direction_tb",45:"direction_bt",46:"direction_rl",47:"direction_lr",49:";",50:"EDGE_STATE",51:"STYLE_SEPARATOR",52:"left_of",53:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,1],[9,4],[9,4],[9,1],[9,2],[9,2],[9,1],[10,3],[10,3],[11,3],[31,1],[31,1],[31,1],[31,1],[48,1],[48,1],[12,1],[12,1],[12,3],[12,3],[29,1],[29,1]],performAction:function(t,e,s,i,n,r,o){var a=r.length-1;switch(n){case 3:return i.setRootDoc(r[a]),r[a];case 4:this.$=[];break;case 5:"nl"!=r[a]&&(r[a-1].push(r[a]),this.$=r[a-1]);break;case 6:case 7:case 11:this.$=r[a];break;case 8:this.$="nl";break;case 12:const t=r[a-1];t.description=i.trimColon(r[a]),this.$=t;break;case 13:this.$={stmt:"relation",state1:r[a-2],state2:r[a]};break;case 14:const e=i.trimColon(r[a]);this.$={stmt:"relation",state1:r[a-3],state2:r[a-1],description:e};break;case 18:this.$={stmt:"state",id:r[a-3],type:"default",description:"",doc:r[a-1]};break;case 19:var c=r[a],l=r[a-2].trim();if(r[a].match(":")){var h=r[a].split(":");c=h[0],l=[l,h[1]]}this.$={stmt:"state",id:c,type:"default",description:l};break;case 20:this.$={stmt:"state",id:r[a-3],type:"default",description:r[a-5],doc:r[a-1]};break;case 21:this.$={stmt:"state",id:r[a],type:"fork"};break;case 22:this.$={stmt:"state",id:r[a],type:"join"};break;case 23:this.$={stmt:"state",id:r[a],type:"choice"};break;case 24:this.$={stmt:"state",id:i.getDividerId(),type:"divider"};break;case 25:this.$={stmt:"state",id:r[a-1].trim(),note:{position:r[a-2].trim(),text:r[a].trim()}};break;case 28:this.$=r[a].trim(),i.setAccTitle(this.$);break;case 29:case 30:this.$=r[a].trim(),i.setAccDescription(this.$);break;case 31:case 32:this.$={stmt:"classDef",id:r[a-1].trim(),classes:r[a].trim()};break;case 33:this.$={stmt:"applyClass",id:r[a-1].trim(),styleClass:r[a].trim()};break;case 34:i.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 35:i.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 36:i.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 37:i.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 40:case 41:this.$={stmt:"state",id:r[a].trim(),type:"default",description:""};break;case 42:case 43:this.$={stmt:"state",id:r[a-2].trim(),classes:[r[a].trim()],type:"default",description:""}}},table:[{3:1,4:e,5:s,6:i},{1:[3]},{3:5,4:e,5:s,6:i},{3:6,4:e,5:s,6:i},t([1,4,5,15,16,18,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],n,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:r,5:o,8:8,9:10,10:12,11:13,12:14,15:a,16:c,18:l,21:h,23:u,24:d,25:p,26:y,27:f,28:m,31:24,32:g,34:S,36:_,37:k,41:T,44:b,45:E,46:x,47:C,50:$},t(v,[2,5]),{9:36,10:12,11:13,12:14,15:a,16:c,18:l,21:h,23:u,24:d,25:p,26:y,27:f,28:m,31:24,32:g,34:S,36:_,37:k,41:T,44:b,45:E,46:x,47:C,50:$},t(v,[2,7]),t(v,[2,8]),t(v,[2,9]),t(v,[2,10]),t(v,[2,11],{13:[1,37],14:[1,38]}),t(v,[2,15]),{17:[1,39]},t(v,[2,17],{19:[1,40]}),{22:[1,41]},t(v,[2,21]),t(v,[2,22]),t(v,[2,23]),t(v,[2,24]),{29:42,30:[1,43],52:[1,44],53:[1,45]},t(v,[2,27]),{33:[1,46]},{35:[1,47]},t(v,[2,30]),{38:[1,48],40:[1,49]},{42:[1,50]},t(D,[2,40],{51:[1,51]}),t(D,[2,41],{51:[1,52]}),t(v,[2,34]),t(v,[2,35]),t(v,[2,36]),t(v,[2,37]),t(v,[2,6]),t(v,[2,12]),{12:53,23:u,50:$},t(v,[2,16]),t(A,n,{7:54}),{23:[1,55]},{23:[1,56]},{22:[1,57]},{23:[2,44]},{23:[2,45]},t(v,[2,28]),t(v,[2,29]),{39:[1,58]},{39:[1,59]},{43:[1,60]},{23:[1,61]},{23:[1,62]},t(v,[2,13],{13:[1,63]}),{4:r,5:o,8:8,9:10,10:12,11:13,12:14,15:a,16:c,18:l,20:[1,64],21:h,23:u,24:d,25:p,26:y,27:f,28:m,31:24,32:g,34:S,36:_,37:k,41:T,44:b,45:E,46:x,47:C,50:$},t(v,[2,19],{19:[1,65]}),{30:[1,66]},{23:[1,67]},t(v,[2,31]),t(v,[2,32]),t(v,[2,33]),t(D,[2,42]),t(D,[2,43]),t(v,[2,14]),t(v,[2,18]),t(A,n,{7:68}),t(v,[2,25]),t(v,[2,26]),{4:r,5:o,8:8,9:10,10:12,11:13,12:14,15:a,16:c,18:l,20:[1,69],21:h,23:u,24:d,25:p,26:y,27:f,28:m,31:24,32:g,34:S,36:_,37:k,41:T,44:b,45:E,46:x,47:C,50:$},t(v,[2,20])],defaultActions:{5:[2,1],6:[2,2],44:[2,44],45:[2,45]},parseError:function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},parse:function(t){var e=this,s=[0],i=[],n=[null],r=[],o=this.table,a="",c=0,l=0,h=r.slice.call(arguments,1),u=Object.create(this.lexer),d={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(d.yy[p]=this.yy[p]);u.setInput(t,d.yy),d.yy.lexer=u,d.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var y=u.yylloc;r.push(y);var f=u.options&&u.options.ranges;"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var m,g,S,_,k,T,b,E,x,C={};;){if(g=s[s.length-1],this.defaultActions[g]?S=this.defaultActions[g]:(null==m&&(x=void 0,"number"!=typeof(x=i.pop()||u.lex()||1)&&(x instanceof Array&&(x=(i=x).pop()),x=e.symbols_[x]||x),m=x),S=o[g]&&o[g][m]),void 0===S||!S.length||!S[0]){var $="";for(k in E=[],o[g])this.terminals_[k]&&k>2&&E.push("'"+this.terminals_[k]+"'");$=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError($,{text:u.match,token:this.terminals_[m]||m,line:u.yylineno,loc:y,expected:E})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+m);switch(S[0]){case 1:s.push(m),n.push(u.yytext),r.push(u.yylloc),s.push(S[1]),m=null,l=u.yyleng,a=u.yytext,c=u.yylineno,y=u.yylloc;break;case 2:if(T=this.productions_[S[1]][1],C.$=n[n.length-T],C._$={first_line:r[r.length-(T||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(T||1)].first_column,last_column:r[r.length-1].last_column},f&&(C._$.range=[r[r.length-(T||1)].range[0],r[r.length-1].range[1]]),void 0!==(_=this.performAction.apply(C,[a,l,c,d.yy,S[1],n,r].concat(h))))return _;T&&(s=s.slice(0,-1*T*2),n=n.slice(0,-1*T),r=r.slice(0,-1*T)),s.push(this.productions_[S[1]][0]),n.push(C.$),r.push(C._$),b=o[s[s.length-2]][s[s.length-1]],s.push(b);break;case 3:return!0}}return!0}},I={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===i.length?this.yylloc.first_column:0)+i[i.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var s,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,s,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;re[0].length)){if(e=s,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,n[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,s,i){switch(s){case 0:return 40;case 1:case 39:return 44;case 2:case 40:return 45;case 3:case 41:return 46;case 4:case 42:return 47;case 5:case 6:case 8:case 9:case 10:case 11:case 51:case 53:case 59:break;case 7:case 74:return 5;case 12:case 29:return this.pushState("SCALE"),16;case 13:case 30:return 17;case 14:case 20:case 31:case 46:case 49:this.popState();break;case 15:return this.begin("acc_title"),32;case 16:return this.popState(),"acc_title_value";case 17:return this.begin("acc_descr"),34;case 18:return this.popState(),"acc_descr_value";case 19:this.begin("acc_descr_multiline");break;case 21:return"acc_descr_multiline_value";case 22:return this.pushState("CLASSDEF"),37;case 23:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 24:return this.popState(),this.pushState("CLASSDEFID"),38;case 25:return this.popState(),39;case 26:return this.pushState("CLASS"),41;case 27:return this.popState(),this.pushState("CLASS_STYLE"),42;case 28:return this.popState(),43;case 32:this.pushState("STATE");break;case 33:case 36:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),24;case 34:case 37:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),25;case 35:case 38:return this.popState(),e.yytext=e.yytext.slice(0,-10).trim(),26;case 43:this.pushState("STATE_STRING");break;case 44:return this.pushState("STATE_ID"),"AS";case 45:case 61:return this.popState(),"ID";case 47:return"STATE_DESCR";case 48:return 18;case 50:return this.popState(),this.pushState("struct"),19;case 52:return this.popState(),20;case 54:return this.begin("NOTE"),28;case 55:return this.popState(),this.pushState("NOTE_ID"),52;case 56:return this.popState(),this.pushState("NOTE_ID"),53;case 57:this.popState(),this.pushState("FLOATING_NOTE");break;case 58:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 60:return"NOTE_TEXT";case 62:return this.popState(),this.pushState("NOTE_TEXT"),23;case 63:return this.popState(),e.yytext=e.yytext.substr(2).trim(),30;case 64:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),30;case 65:case 66:return 6;case 67:return 15;case 68:return 50;case 69:return 23;case 70:return e.yytext=e.yytext.trim(),13;case 71:return 14;case 72:return 27;case 73:return 51;case 75:return"INVALID"}},rules:[/^(?:default\b)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:classDef\s+)/i,/^(?:DEFAULT\s+)/i,/^(?:\w+\s+)/i,/^(?:[^\n]*)/i,/^(?:class\s+)/i,/^(?:(\w+)+((,\s*\w+)*))/i,/^(?:[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?::::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[9,10],inclusive:!1},struct:{rules:[9,10,22,26,32,39,40,41,42,51,52,53,54,68,69,70,71,72],inclusive:!1},FLOATING_NOTE_ID:{rules:[61],inclusive:!1},FLOATING_NOTE:{rules:[58,59,60],inclusive:!1},NOTE_TEXT:{rules:[63,64],inclusive:!1},NOTE_ID:{rules:[62],inclusive:!1},NOTE:{rules:[55,56,57],inclusive:!1},CLASS_STYLE:{rules:[28],inclusive:!1},CLASS:{rules:[27],inclusive:!1},CLASSDEFID:{rules:[25],inclusive:!1},CLASSDEF:{rules:[23,24],inclusive:!1},acc_descr_multiline:{rules:[20,21],inclusive:!1},acc_descr:{rules:[18],inclusive:!1},acc_title:{rules:[16],inclusive:!1},SCALE:{rules:[13,14,30,31],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[45],inclusive:!1},STATE_STRING:{rules:[46,47],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[9,10,33,34,35,36,37,38,43,44,48,49,50],inclusive:!1},ID:{rules:[9,10],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,10,11,12,15,17,19,22,26,29,32,50,54,65,66,67,68,69,70,71,73,74,75],inclusive:!0}}};function O(){this.yy={}}return L.lexer=I,O.prototype=L,L.Parser=O,new O}();n.parser=n;const r=n,o="TB",a="state",c="relation",l="default",h="divider",u="[*]",d="start",p=u,y="color",f="fill";let m="LR",g=[],S={};let _={root:{relations:[],states:{},documents:{}}},k=_.root,T=0,b=0;const E=t=>JSON.parse(JSON.stringify(t)),x=(t,e,s)=>{if(e.stmt===c)x(t,e.state1,!0),x(t,e.state2,!1);else if(e.stmt===a&&("[*]"===e.id?(e.id=s?t.id+"_start":t.id+"_end",e.start=s):e.id=e.id.trim()),e.doc){const t=[];let s,n=[];for(s=0;s0&&n.length>0){const s={stmt:a,id:(0,i.I)(),type:"divider",doc:E(n)};t.push(E(s)),e.doc=t}e.doc.forEach((t=>x(e,t,!0)))}},C=function(t,e=l,s=null,n=null,r=null,o=null,a=null,c=null){const h=null==t?void 0:t.trim();if(void 0===k.states[h]?(i.l.info("Adding state ",h,n),k.states[h]={id:h,descriptions:[],type:e,doc:s,note:r,classes:[],styles:[],textStyles:[]}):(k.states[h].doc||(k.states[h].doc=s),k.states[h].type||(k.states[h].type=e)),n&&(i.l.info("Setting state description",h,n),"string"==typeof n&&I(h,n.trim()),"object"==typeof n&&n.forEach((t=>I(h,t.trim())))),r&&(k.states[h].note=r,k.states[h].note.text=i.e.sanitizeText(k.states[h].note.text,(0,i.c)())),o){i.l.info("Setting state classes",h,o);("string"==typeof o?[o]:o).forEach((t=>N(h,t.trim())))}if(a){i.l.info("Setting state styles",h,a);("string"==typeof a?[a]:a).forEach((t=>R(h,t.trim())))}if(c){i.l.info("Setting state styles",h,a);("string"==typeof c?[c]:c).forEach((t=>w(h,t.trim())))}},$=function(t){_={root:{relations:[],states:{},documents:{}}},k=_.root,T=0,S={},t||(0,i.v)()},v=function(t){return k.states[t]};function D(t=""){let e=t;return t===u&&(T++,e=`${d}${T}`),e}function A(t="",e=l){return t===u?d:e}const L=function(t,e,s){if("object"==typeof t)!function(t,e,s){let n=D(t.id.trim()),r=A(t.id.trim(),t.type),o=D(e.id.trim()),a=A(e.id.trim(),e.type);C(n,r,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles),C(o,a,e.doc,e.description,e.note,e.classes,e.styles,e.textStyles),k.relations.push({id1:n,id2:o,relationTitle:i.e.sanitizeText(s,(0,i.c)())})}(t,e,s);else{const n=D(t.trim()),r=A(t),o=function(t=""){let e=t;return t===p&&(T++,e=`end${T}`),e}(e.trim()),a=function(t="",e=l){return t===p?"end":e}(e);C(n,r),C(o,a),k.relations.push({id1:n,id2:o,title:i.e.sanitizeText(s,(0,i.c)())})}},I=function(t,e){const s=k.states[t],n=e.startsWith(":")?e.replace(":","").trim():e;s.descriptions.push(i.e.sanitizeText(n,(0,i.c)()))},O=function(t,e=""){void 0===S[t]&&(S[t]={id:t,styles:[],textStyles:[]});const s=S[t];null!=e&&e.split(",").forEach((t=>{const e=t.replace(/([^;]*);/,"$1").trim();if(t.match(y)){const t=e.replace(f,"bgFill").replace(y,f);s.textStyles.push(t)}s.styles.push(e)}))},N=function(t,e){t.split(",").forEach((function(t){let s=v(t);if(void 0===s){const e=t.trim();C(e),s=v(e)}s.classes.push(e)}))},R=function(t,e){const s=v(t);void 0!==s&&s.textStyles.push(e)},w=function(t,e){const s=v(t);void 0!==s&&s.textStyles.push(e)},B={getConfig:()=>(0,i.c)().state,addState:C,clear:$,getState:v,getStates:function(){return k.states},getRelations:function(){return k.relations},getClasses:function(){return S},getDirection:()=>m,addRelation:L,getDividerId:()=>(b++,"divider-id-"+b),setDirection:t=>{m=t},cleanupLabel:function(t){return":"===t.substring(0,1)?t.substr(2).trim():t.trim()},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3},logDocuments:function(){i.l.info("Documents = ",_)},getRootDoc:()=>g,setRootDoc:t=>{i.l.info("Setting root doc",t),g=t},getRootDocV2:()=>(x({id:"root"},{id:"root",doc:g},!0),{id:"root",doc:g}),extract:t=>{let e;e=t.doc?t.doc:t,i.l.info(e),$(!0),i.l.info("Extract",e),e.forEach((t=>{switch(t.stmt){case a:C(t.id.trim(),t.type,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles);break;case c:L(t.state1,t.state2,t.description);break;case"classDef":O(t.id.trim(),t.classes);break;case"applyClass":N(t.id.trim(),t.styleClass)}}))},trimColon:t=>t&&":"===t[0]?t.substr(1).trim():t.trim(),getAccTitle:i.g,setAccTitle:i.s,getAccDescription:i.a,setAccDescription:i.b,addStyleClass:O,setCssClass:N,addDescription:I,setDiagramTitle:i.q,getDiagramTitle:i.t},P=t=>`\ndefs #statediagram-barbEnd {\n fill: ${t.transitionColor};\n stroke: ${t.transitionColor};\n }\ng.stateGroup text {\n fill: ${t.nodeBorder};\n stroke: none;\n font-size: 10px;\n}\ng.stateGroup text {\n fill: ${t.textColor};\n stroke: none;\n font-size: 10px;\n\n}\ng.stateGroup .state-title {\n font-weight: bolder;\n fill: ${t.stateLabelColor};\n}\n\ng.stateGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.stateGroup line {\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.transition {\n stroke: ${t.transitionColor};\n stroke-width: 1;\n fill: none;\n}\n\n.stateGroup .composit {\n fill: ${t.background};\n border-bottom: 1px\n}\n\n.stateGroup .alt-composit {\n fill: #e0e0e0;\n border-bottom: 1px\n}\n\n.state-note {\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n\n text {\n fill: ${t.noteTextColor};\n stroke: none;\n font-size: 10px;\n }\n}\n\n.stateLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.edgeLabel .label rect {\n fill: ${t.labelBackgroundColor};\n opacity: 0.5;\n}\n.edgeLabel .label text {\n fill: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n.label div .edgeLabel {\n color: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n\n.stateLabel text {\n fill: ${t.stateLabelColor};\n font-size: 10px;\n font-weight: bold;\n}\n\n.node circle.state-start {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node .fork-join {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node circle.state-end {\n fill: ${t.innerEndBackground};\n stroke: ${t.background};\n stroke-width: 1.5\n}\n.end-state-inner {\n fill: ${t.compositeBackground||t.background};\n // stroke: ${t.background};\n stroke-width: 1.5\n}\n\n.node rect {\n fill: ${t.stateBkg||t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n.node polygon {\n fill: ${t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};;\n stroke-width: 1px;\n}\n#statediagram-barbEnd {\n fill: ${t.lineColor};\n}\n\n.statediagram-cluster rect {\n fill: ${t.compositeTitleBackground};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n\n.cluster-label, .nodeLabel {\n color: ${t.stateLabelColor};\n}\n\n.statediagram-cluster rect.outer {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state .divider {\n stroke: ${t.stateBorder||t.nodeBorder};\n}\n\n.statediagram-state .title-state {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-cluster.statediagram-cluster .inner {\n fill: ${t.compositeBackground||t.background};\n}\n.statediagram-cluster.statediagram-cluster-alt .inner {\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.statediagram-cluster .inner {\n rx:0;\n ry:0;\n}\n\n.statediagram-state rect.basic {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state rect.divider {\n stroke-dasharray: 10,10;\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.note-edge {\n stroke-dasharray: 5;\n}\n\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n\n.statediagram-note text {\n fill: ${t.noteTextColor};\n}\n\n.statediagram-note .nodeLabel {\n color: ${t.noteTextColor};\n}\n.statediagram .edgeLabel {\n color: red; // ${t.noteTextColor};\n}\n\n#dependencyStart, #dependencyEnd {\n fill: ${t.lineColor};\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.statediagramTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`}}]); \ No newline at end of file diff --git a/assets/js/27e03890.02584dc7.js b/assets/js/27e03890.02584dc7.js new file mode 100644 index 0000000000..7737d22fd0 --- /dev/null +++ b/assets/js/27e03890.02584dc7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[22339],{66083:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"scs-0219-w1-kaas-networking","title":"KaaS Networking Standard: Implementation Notes","description":"List of compliant CNI Plugins","source":"@site/standards/scs-0219-w1-kaas-networking.md","sourceDirName":".","slug":"/scs-0219-w1-kaas-networking","permalink":"/standards/scs-0219-w1-kaas-networking","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"KaaS Networking Standard: Implementation Notes","type":"Supplement","track":"KaaS","status":"Draft","supplements":["scs-0219-v1-kaas-networking.md"]},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0219-v1-kaas-networking"},"next":{"title":"IAM Standards","permalink":"/standards/iam/"}}');var s=n(74848),o=n(28453);const r={title:"KaaS Networking Standard: Implementation Notes",type:"Supplement",track:"KaaS",status:"Draft",supplements:["scs-0219-v1-kaas-networking.md"]},a=void 0,l={},c=[{value:"List of compliant CNI Plugins",id:"list-of-compliant-cni-plugins",level:2}];function h(e){const t={a:"a",h2:"h2",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"list-of-compliant-cni-plugins",children:"List of compliant CNI Plugins"}),"\n",(0,s.jsxs)(t.p,{children:["The Kubernetes Network Policy API working group maintains a ",(0,s.jsx)(t.a,{href:"https://network-policy-api.sigs.k8s.io/implementations/",children:"list of work-in-progress implementations"})," of the AdminNetworkPolicy and BaselineAdminNetworkPolicy resources.\nBesides their own proof-of-concept implementation of ",(0,s.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/kube-network-policies",children:"kube-network-policies"}),", at the time of writing they list the following CNI plugins:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/ovn-org/ovn-kubernetes/",children:"OVN-Kubernetes"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/antrea-io/antrea/",children:"Antrea"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/kubeovn/kube-ovn",children:"KubeOVN"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/projectcalico/calico",children:"Calico"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/cilium/cilium",children:"Cilium"})}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"All of these plugins also implement the basic NetworkPolicy API, and are therefore compliant both with the standard's requirements and recommendations."}),"\n",(0,s.jsxs)(t.p,{children:["The CNI plugin ",(0,s.jsx)(t.a,{href:"https://github.com/flannel-io/flannel",children:"Flannel"})," does not support network policies by itself, but can be combined with Calico for policy enforcement.\nThis configuration is known as ",(0,s.jsx)(t.a,{href:"https://docs.tigera.io/calico/latest/getting-started/kubernetes/flannel/install-for-flannel",children:"Canal"})," and will likely profit from Calico's support for AdminNetworkPolicy."]}),"\n",(0,s.jsxs)(t.p,{children:["There are more CNI plugins that support the NetworkPolicy API, but are not known to work on support of the AdminNetworkPolicy extensions.\nAs such they are still compliant with the current version of the Standard.\nHowever, these seem to be either vendor-specific, like the ",(0,s.jsx)(t.a,{href:"https://learn.microsoft.com/de-de/azure/aks/configure-azure-cni",children:"Azure CNI"}),", or unmaintained, like ",(0,s.jsx)(t.a,{href:"https://github.com/weaveworks/weave",children:"Weave"}),"."]})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var i=n(96540);const s={},o=i.createContext(s);function r(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/27f24dfd.0e160ba7.js b/assets/js/27f24dfd.0e160ba7.js new file mode 100644 index 0000000000..cdca9df118 --- /dev/null +++ b/assets/js/27f24dfd.0e160ba7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[14132],{92947:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"scs-0214-v1-k8s-node-distribution","title":"Kubernetes Node Distribution and Availability","description":"Introduction","source":"@site/standards/scs-0214-v1-k8s-node-distribution.md","sourceDirName":".","slug":"/scs-0214-v1-k8s-node-distribution","permalink":"/standards/scs-0214-v1-k8s-node-distribution","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Kubernetes Node Distribution and Availability","type":"Standard","status":"Stable","stabilized_at":"2024-02-08T00:00:00.000Z","track":"KaaS"},"sidebar":"standards","previous":{"title":"scs-0214: Kubernetes Node Distribution and Availability","permalink":"/standards/kaas/scs-0214"},"next":{"title":"V2","permalink":"/standards/scs-0214-v2-k8s-node-distribution"}}');var s=n(74848),o=n(28453);const r={title:"Kubernetes Node Distribution and Availability",type:"Standard",status:"Stable",stabilized_at:new Date("2024-02-08T00:00:00.000Z"),track:"KaaS"},a=void 0,d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Glossary",id:"glossary",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Decision",id:"decision",level:2}];function c(e){const t={a:"a",h2:"h2",h3:"h3",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(t.p,{children:"A Kubernetes instance is provided as a cluster, which consists of a set of machines,\nso-called nodes. A cluster is composed of a control plane and at least one worker node.\nThe control plane manages the worker nodes and therefore the pods in the cluster by making\ndecisions about scheduling, event detection and rights management. Inside the control plane,\nmultiple components exist, which can be duplicated and distributed over multiple nodes\ninside the cluster. Typically, no user workloads are run on these nodes in order to\nseparate the controller component from user workloads, which could pose a security risk."}),"\n",(0,s.jsx)(t.h3,{id:"glossary",children:"Glossary"}),"\n",(0,s.jsx)(t.p,{children:"The following terms are used throughout this document:"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Term"}),(0,s.jsx)(t.th,{children:"Meaning"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Worker"}),(0,s.jsx)(t.td,{children:"Virtual or bare-metal machine, which hosts workloads of customers"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Control Plane"}),(0,s.jsx)(t.td,{children:"Virtual or bare-metal machine, which hosts the container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Machine"}),(0,s.jsx)(t.td,{children:"Virtual or bare-metal entity with computational capabilities"})]})]})]}),"\n",(0,s.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(t.p,{children:'In normal day-to-day operation, it is not unusual for some operational failures, either\ndue to wear and tear of hardware, software misconfigurations, external problems or\nuser errors. Whichever was the source of such an outage, it always means down-time for\noperations and users and possible even data loss.\nTherefore, a Kubernetes cluster in a productive environment should be distributed over\nmultiple "failure zones" in order to provide fault-tolerance and high availability.\nThis is especially important for the control plane of the cluster, since it contains the\nstate of the whole cluster. A failure of this component could mean an unrecoverable failure\nof the whole cluster.'}),"\n",(0,s.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsxs)(t.p,{children:["Most design considerations of this standard follow the previously written Decision Record\n",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0213-v1-k8s-nodes-anti-affinity.md",children:"Kubernetes Nodes Anti Affinity"})," as well as the Kubernetes documents about\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/",children:"High Availability"})," and ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/best-practices/cluster-large/",children:"Best practices for large clusters"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"SCS wishes to prefer distributed, highly-available systems due to their obvious advantages\nlike fault-tolerance and data redundancy. But it also understands the costs and overhead\nfor the providers associated with this effort, since the infrastructure needs to have\nhardware which will just be used to provide fail-over safety or duplication."}),"\n",(0,s.jsxs)(t.p,{children:["The document ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/best-practices/cluster-large/",children:"Best practices for large clusters"})," describes the concept of a failure zone.\nThis term isn't defined any further, but can in this context be described as a number of\nphysical (computing) machines in such a vicinity to each other (either through physical\nor logical interconnection in some way), that specific problems inside this zone would put\nall these machines at risk of failure/shutdown. It is therefore necessary for important\ndata or services to not be present just on one failure zone.\nHow such a failure zone should be defined is dependent on the risk model of the service/data\nand its owner as well as the capabilities of the provider. Zones could be set from things\nlike single machines or racks up to whole datacenters or even regions, which could be\ncoupled by things like electrical grids. They're therefore purely logical entities, which\nshouldn't be defined further in this document."]}),"\n",(0,s.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsx)(t.p,{children:"This standard formulates the requirement for the distribution of Kubernetes nodes in order\nto provide a fault-tolerant and available Kubernetes cluster infrastructure.\nSince some providers only have small environments to work with and therefore couldn't\ncomply with this standard, it will be treated as a RECOMMENDED standard, where providers\ncan OPT OUT."}),"\n",(0,s.jsx)(t.p,{children:"If the standard is used by a provider, the following decisions are binding and valid:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"The control plane nodes MUST be distributed over multiple physical machines. Kubernetes\nprovides best-practices on this topic, which are also RECOMMENDED by SCS."}),"\n",(0,s.jsx)(t.li,{children:'At least one control plane instance MUST be run in each "failure zone", more are\nRECOMMENDED in each "failure zone" to provide fault-tolerance for each zone.'}),"\n",(0,s.jsx)(t.li,{children:'Worker nodes are RECOMMENDED to be distributed over multiple zones. This policy makes\nit OPTIONAL to provide a worker node in each "failure zone", meaning that worker nodes\ncan also be scaled vertically first before scaling horizontally.'}),"\n",(0,s.jsx)(t.li,{children:'Worker node distribution MUST be indicated to the user through some kind of labeling\nin order to enable (anti)-affinity for workloads over "failure zones".'}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var i=n(96540);const s={},o=i.createContext(s);function r(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/287cd167.a1547f74.js b/assets/js/287cd167.a1547f74.js new file mode 100644 index 0000000000..0e30597530 --- /dev/null +++ b/assets/js/287cd167.a1547f74.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[13043],{64737:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>i,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>c,toc:()=>u});const c=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","title":"Quickstart","description":"This document has been moved.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs","slug":"/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview"},"next":{"title":"Controllers","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers"}}');var n=s(74848),o=s(28453);const r={},a="Quickstart",i={},u=[];function d(t){const e={a:"a",h1:"h1",header:"header",p:"p",...(0,o.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,n.jsx)(e.p,{children:"This document has been moved."}),"\n",(0,n.jsxs)(e.p,{children:["You can find the current version of the quickstart guide ",(0,n.jsx)(e.a,{href:"https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart",children:"here"}),"."]})]})}function p(t={}){const{wrapper:e}={...(0,o.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(d,{...t})}):d(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>r,x:()=>a});var c=s(96540);const n={},o=c.createContext(n);function r(t){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(n):t.components||n:r(t.components),c.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/2886628e.34d61deb.js b/assets/js/2886628e.34d61deb.js new file mode 100644 index 0000000000..cf0cd3999d --- /dev/null +++ b/assets/js/2886628e.34d61deb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[37778],{7338:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>a});const o=JSON.parse('{"id":"tools/github/branchprotection","title":"Branch Protection Rules","description":"To protect our source code from unwanted changes, we enforce the following branch protection rules for all repositories within our GitHub organization:","source":"@site/community/tools/github/branchprotection.md","sourceDirName":"tools/github","slug":"/tools/github/branchprotection","permalink":"/community/tools/github/branchprotection","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Zuul","permalink":"/community/tools/zuul"},"next":{"title":"Developer Certificate of Origin + Licenses","permalink":"/community/tools/github/dco-and-licenses"}}');var r=n(74848),s=n(28453);const i={},c="Branch Protection Rules",l={},a=[];function u(e){const t={a:"a",code:"code",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"branch-protection-rules",children:"Branch Protection Rules"})}),"\n",(0,r.jsxs)(t.p,{children:["To protect our source code from unwanted changes, we enforce the following branch protection rules for all repositories within our ",(0,r.jsx)(t.a,{href:"https://github.com/SovereignCloudStack",children:"GitHub organization"}),":"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Require a pull request before merging into our default branch ",(0,r.jsx)(t.code,{children:"main"}),".","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Require at least one approval before pull requests can be merged."}),"\n",(0,r.jsx)(t.li,{children:"Dismiss stale pull request approvals when new commits are pushed"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["Require status checks to pass before merging","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Require branches to be up to date before merging"}),"\n",(0,r.jsxs)(t.li,{children:["Status checks that are required:","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/community/tools/github/dco-and-licenses",children:"DCO"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.li,{children:"Do not allow bypassing the above settings"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The branch protection rules are rolled out by our ",(0,r.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/github-manager",children:(0,r.jsx)(t.code,{children:"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 ",(0,r.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/github-manager/blob/main/orgs/SovereignCloudStack/data.yaml",children:(0,r.jsx)(t.code,{children:"orgs/SovereignCloudStack/data.yaml"})}),"."]}),"\n",(0,r.jsx)(t.p,{children:"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."})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var o=n(96540);const r={},s=o.createContext(r);function i(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/28c03198.0fca2cc1.js b/assets/js/28c03198.0fca2cc1.js new file mode 100644 index 0000000000..adef54a4c9 --- /dev/null +++ b/assets/js/28c03198.0fca2cc1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[11935],{7281:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"scs-0124-w1-security-of-iaas-service-software","title":"SCS Standard for the security of IaaS service software: Implementation and Testing Notes","description":"Testing or Detecting security updates in software","source":"@site/standards/scs-0124-w1-security-of-iaas-service-software.md","sourceDirName":".","slug":"/scs-0124-w1-security-of-iaas-service-software","permalink":"/standards/scs-0124-w1-security-of-iaas-service-software","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Standard for the security of IaaS service software: Implementation and Testing Notes","type":"Supplement","track":"IaaS","status":"Draft","supplements":["scs-0124-v1-security-of-iaas-service-software.md"]},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0124-v1-security-of-iaas-service-software"},"next":{"title":"scs-0125: Secure Connections","permalink":"/standards/iaas/scs-0125"}}');var r=s(74848),a=s(28453);const i={title:"SCS Standard for the security of IaaS service software: Implementation and Testing Notes",type:"Supplement",track:"IaaS",status:"Draft",supplements:["scs-0124-v1-security-of-iaas-service-software.md"]},o=void 0,d={},c=[{value:"Testing or Detecting security updates in software",id:"testing-or-detecting-security-updates-in-software",level:2},{value:"Procedure to become compliant to the security of IaaS service software Standard",id:"procedure-to-become-compliant-to-the-security-of-iaas-service-software-standard",level:3},{value:"Procedure when new vulnerabilites are discovered",id:"procedure-when-new-vulnerabilites-are-discovered",level:3}];function l(e){const t={h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h2,{id:"testing-or-detecting-security-updates-in-software",children:"Testing or Detecting security updates in software"}),"\n",(0,r.jsx)(t.p,{children:"It is not always possible to automatically test, whether the software has the newest security updates.\nThis is because software versions may differ or some CSPs might have added downstream code parts or using other software than the reference.\nAlso vulnerabilites and their fixes are quite different in testing, some might not be testable while others are.\nAdditionally testing might be perceived as an attack on the infrastructure.\nSo this standard will rely on the work and information CSPs must provide.\nThere are different cases and procedures which are addressed in the following parts, that lead to compliance for this standard."}),"\n",(0,r.jsx)(t.h3,{id:"procedure-to-become-compliant-to-the-security-of-iaas-service-software-standard",children:"Procedure to become compliant to the security of IaaS service software Standard"}),"\n",(0,r.jsx)(t.p,{children:"This is the procedure when a new deployment wants to achieve SCS-conformancy.\nThere are two states such a deployment can be in:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"When a deployment is newly build or installed it usually uses software which includes all the latest security and bug fixes.\nSuch deployments should be considered compliant to the standard."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"When a CSP wants to make an older deployment compliant to the SCS standards and thus also to this standard, it should be checked, whether the running software is up to date and all vulnerabilites are fixed.\nAny updates or upgrades to even newer versions should be done before the SCS compliance for every other standard is checked.\nAfterwards the CSP may provide information about the used software in an SBOM or otherwise should provide a notice about the deployment having integrated all necessary vulnerability patches."}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"procedure-when-new-vulnerabilites-are-discovered",children:"Procedure when new vulnerabilites are discovered"}),"\n",(0,r.jsx)(t.p,{children:"Whenever there are new vulnerabilities discovered in IaaS service software like OpenStack there is either an internal discussion ongoing or it is just a smaller issue.\nIn the first case CSPs should have someone following such discussions and may even help preparing and testing patches.\nFrom the moment on the vulnerability is disclosed publicly, the risk of it being actively exploited increases greatly.\nSo CSPs MUST watch out for announcements like in the OSSAs and OSSNs and when they are affected, update their deployment within the following timeframes according to the severity of the issue:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Critical (CVSS = 9.0 \u2013 10.0): 3 hours"}),"\n",(0,r.jsx)(t.li,{children:"High (CVSS = 7.0 \u2013 8.9): 3 days"}),"\n",(0,r.jsx)(t.li,{children:"Mid (CVSS = 4.0 \u2013 6.9): 1 month"}),"\n",(0,r.jsx)(t.li,{children:"Low (CVSS = 0.1 \u2013 3.9): 3 months"}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"Afterwards CSPs MUST provide a notice to the OSBA, that they are not or not anymore affected by the vulnerabilty.\nThis can be done through either telling, what patches were integrated or showing configuration that renders the attack impossible.\nIt could also be provided a list of services, when the affected service is not used in that deployment."})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>o});var n=s(96540);const r={},a=n.createContext(r);function i(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/28d842ee.e9a5c66c.js b/assets/js/28d842ee.e9a5c66c.js new file mode 100644 index 0000000000..50c1a4a44c --- /dev/null +++ b/assets/js/28d842ee.e9a5c66c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[73405],{74511:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"scs-0112-v1-sonic","title":"SONiC Support in SCS","description":"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.\\n","source":"@site/standards/scs-0112-v1-sonic.md","sourceDirName":".","slug":"/scs-0112-v1-sonic","permalink":"/standards/scs-0112-v1-sonic","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SONiC Support in SCS","type":"Decision Record","status":"Draft","track":"IaaS","description":"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.\\n"},"sidebar":"standards","previous":{"title":"scs-0112: SONiC Support in SCS","permalink":"/standards/iaas/scs-0112"},"next":{"title":"scs-0113: Security Groups Decision Record","permalink":"/standards/iaas/scs-0113"}}');var s=n(74848),o=n(28453);const r={title:"SONiC Support in SCS",type:"Decision Record",status:"Draft",track:"IaaS",description:"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.\n"},a=void 0,l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"SONiC as a network OS where dynamic network configuration in Openstack is required",id:"sonic-as-a-network-os-where-dynamic-network-configuration-in-openstack-is-required",level:3},{value:"Automation and tooling for SONiC",id:"automation-and-tooling-for-sonic",level:3},{value:"OVN for SONiC",id:"ovn-for-sonic",level:3},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Option 1: SCS distribution of SONiC",id:"option-1-scs-distribution-of-sonic",level:4},{value:"Option 2: SCS will support SONiC but will not change it",id:"option-2-scs-will-support-sonic-but-will-not-change-it",level:4},{value:"Option 3: SCS develops SCS-specific modules as add-on for any SONiC (Community or Enterprise)",id:"option-3-scs-develops-scs-specific-modules-as-add-on-for-any-sonic-community-or-enterprise",level:4},{value:"Option 4: SCS does not adopt SONiC at all",id:"option-4-scs-does-not-adopt-sonic-at-all",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"State of SONiC community?",id:"state-of-sonic-community",level:3},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2}];function c(e){const i={a:"a",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(i.p,{children:["SONiC support in ",(0,s.jsx)(i.a,{href:"https://scs.community",children:"SCS"})," was considered within the context of ",(0,s.jsx)(i.a,{href:"https://scs.community/tenders/lot4",children:"VP04 Networking"}),", sub-lot 1 SDN scalability. Different challenges and approaches to SDN scalability have been explored and more specifically those who require support in the underlay network. Using SONiC in the underlay can have benefits for SCS users by using a standardized OS for network devices and also having a clear path for network scalability when using SONiC. For this to work, we have to define how SONiC is used and supported architecturally in SCS. This document outlines the architectural decisions in regard to SONiC support and integration in SCS."]}),"\n",(0,s.jsx)(i.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(i.p,{children:"In respect to SDN scalability improvements in Openstack and SCS, there are several ways SONiC can be leveraged."}),"\n",(0,s.jsx)(i.h3,{id:"sonic-as-a-network-os-where-dynamic-network-configuration-in-openstack-is-required",children:"SONiC as a network OS where dynamic network configuration in Openstack is required"}),"\n",(0,s.jsx)(i.p,{children:"In many network designs for Openstack, configuration of the actual network hardware by Openstack Neutron service is required. The following network designs apply:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:"VLANs. Using VLANs to segment tenant networks requires the network switch to be configured. This can be manual or dynamic configuration via the ML2 Neutron driver."}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:"EVPN/VXLAN on the switch. In this use case, SONiC runs on leaf switches. Leafs terminate VXLAN endpoints and run BGP/EVPN for the control plane. Again, the ML2 Neutron driver is used to dynamically configure the network switch. The link between the switch and the service is regular VLAN."}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:"VXLAN on servers and switches. This is a hybrid use case, where most of the SDN is pushed to the server, but the network is still involved where support for bare metal hosts is needed."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"automation-and-tooling-for-sonic",children:"Automation and tooling for SONiC"}),"\n",(0,s.jsx)(i.p,{children:"There is no tooling in SCS or Openstack communities to facilitate the rollout and configuration of enterprise scale SONiC deployments. Netbox and OSISM can be integrated, so that Netbox becomes the source of truth for network configuration and OSISM supports the initial rollout and configuration for the switches."}),"\n",(0,s.jsx)(i.h3,{id:"ovn-for-sonic",children:"OVN for SONiC"}),"\n",(0,s.jsx)(i.p,{children:"OVN and OVS are extensively leveraged in Neutron to SDN. In large scale deployments, OVN can become a bottleneck by exhausting resources on network nodes. SONiC can host the OVN control plane as a module (container) and spare the resources in network nodes. There is however a potential other bottleneck on SONiC hardware, as OVN control plane can be resource intensive. This is a potential area for further investigation."}),"\n",(0,s.jsx)(i.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsx)(i.p,{children:"There are different ways SONiC support can be implemented in SCS, very similar to existing approaches with Linux."}),"\n",(0,s.jsx)(i.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,s.jsx)(i.h4,{id:"option-1-scs-distribution-of-sonic",children:"Option 1: SCS distribution of SONiC"}),"\n",(0,s.jsx)(i.p,{children:"With this approach, SCS will create its own distribution of SONiC, similar to what Debian or Arch are for Linux. This distribution will be based on the SONiC community distribution, but will have SCS specific modules, which will be developed and maintained by SCS. SCS will contribute its code to dedicated SCS repositories and build its own SONiC images. The code can eventually be pushed upstream, but not as top priority. This approach will allow SCS to have a clear path for SONiC support and integration in SCS, but will also require SCS to maintain a distribution of SONiC, which is a significant effort. Upstream/downstream changes will have to be managed and maintained. However, the advantage is that SCS will have full control over the distribution and can make changes as needed. Users will have to use the SCS distribution of SONiC, which will be based on the community distribution. If users already deploy community or enterprise SONiC, a migration path to SCS SONiC will be needed."}),"\n",(0,s.jsx)(i.h4,{id:"option-2-scs-will-support-sonic-but-will-not-change-it",children:"Option 2: SCS will support SONiC but will not change it"}),"\n",(0,s.jsx)(i.p,{children:"SCS supports enterprise and community versions of SONiC but will not develop its own code for it. This will significantly limit the ability to develop new features for SDN, because all changes will be done in the tooling around SONiC and not in the OS itself. The advantages are that SCS will still improve SONiC support and will have minimal effort for this. The downside is that some features like OVN control plane for SONiC will not be possible."}),"\n",(0,s.jsx)(i.h4,{id:"option-3-scs-develops-scs-specific-modules-as-add-on-for-any-sonic-community-or-enterprise",children:"Option 3: SCS develops SCS-specific modules as add-on for any SONiC (Community or Enterprise)"}),"\n",(0,s.jsx)(i.p,{children:"In option 3, SCS will change SONiC by releasing its own modules for it. Those module can be provided as add-ons and installed on top of any version, community or enterprise. While compatibility between the modules the SONiC releases will need to be maintained, there will be much broader support for SONiC and users will be able to pick and chose distributions based on their existing relationships and experience and use SCS independent of this. In cases where SCS provides contributions to core SONiC, those can be made in upstream Community repositories, so that the whole community including the propitiatory vendors can adopt them eventually."}),"\n",(0,s.jsx)(i.h4,{id:"option-4-scs-does-not-adopt-sonic-at-all",children:"Option 4: SCS does not adopt SONiC at all"}),"\n",(0,s.jsx)(i.p,{children:"This option entails no dedicated effort on SCS's part in supporting SONiC network equipment for its users and software stack. Users can still use SONiC from what is available by other projects or if they invest the effort themselves. This has several disadvantages:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"SCS is not contributing to the SONiC community"}),"\n",(0,s.jsx)(i.li,{children:"the value for SCS by users who already use or plan to invest in SONiC is diminished"}),"\n",(0,s.jsx)(i.li,{children:"users have less incentive to use community SONiC and switch to Enterprise SONiC"}),"\n",(0,s.jsx)(i.li,{children:"SCS will not be able to leverage SONiC for SDN scalability improvements"}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,s.jsx)(i.h3,{id:"state-of-sonic-community",children:"State of SONiC community?"}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.strong,{children:"community version: mature or not?"})}),"\n",(0,s.jsx)(i.p,{children:'Commits: between 40-52 per month. Contributors to master: 10-20. Mailing list: 6 lists, about 10-30 messages/month for list. Community version supports 25 hardware vendors. Requires significant time and resource investment and "Explorer\'s mindset".'}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.strong,{children:"enterprise version: mature or not?"})}),"\n",(0,s.jsx)(i.p,{children:"Multiple vendor distributions. Expensive in general"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"release schedule - how often are features and bugfixes released?"}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"New tags appears on different periods, once 2 times per month, other 3 months between releases."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"adoption penetration - how many vendors use it? What type of vendors (big, medium and large)?"}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"Good initial adoption: Microsoft, Target. Adoption requires time and money"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Is SONiC being overtaken by alternatives: SmartNICs and DPUs? How relevant is it still and will be in the coming years?"}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"Actually not, because of different use cases."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Sustainability of community SONIC for 2025+"}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"The SONiC community is healthy and growing, however progress is slower due to factors like investment of resources. The barrier of entry is much higher than other similar OSS projects."}),"\n",(0,s.jsx)(i.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsx)(i.p,{children:"IaaS team recommends to use Option 3: SCS develops SCS-specific modules as add-on for any SONiC (Community or Enterprise). It has the best tradeoff between time and resource investment and benefits for the community. Adopting this strategy would allow SCS to be agile and quickly adopt SONiC, by providing users with clear path while allowing the freedom to choose different hardware and software vendors. SCS code can be packaged independently of each SONiC distribution and installed as add-on. Also, SCS contributions to core SONiC will be done directly upstream, so that the whole community can benefit from them."}),"\n",(0,s.jsx)(i.p,{children:"Work on hardware support in SONiC should be raised in upstream and SCS shouldn't make significant investments in this area."}),"\n",(0,s.jsx)(i.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"https://input.scs.community/VP04-issues-455-research-SDN-scalability",children:"Research SDN scalability"})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"https://input.scs.community/SCS-DR-SONIC-usage",children:"Results SONIC Usage in SCS"})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"https://input.scs.community/oW_plPZ6RkuXs3k9mrRDdw#",children:"SONiC Community research"})}),"\n"]})]})}function h(e={}){const{wrapper:i}={...(0,o.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>r,x:()=>a});var t=n(96540);const s={},o=t.createContext(s);function r(e){const i=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(o.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/28f8b1f8.a20caeef.js b/assets/js/28f8b1f8.a20caeef.js new file mode 100644 index 0000000000..72d326acc5 --- /dev/null +++ b/assets/js/28f8b1f8.a20caeef.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[21698],{3415:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Turnkey Solution","slug":"/category/turnkey-solution","permalink":"/docs/category/turnkey-solution","sidebar":"docs","navigation":{"previous":{"title":"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)","permalink":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations"},"next":{"title":"Overview","permalink":"/docs/turnkey-solution/overview"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/291e1144.a80b3444.js b/assets/js/291e1144.a80b3444.js new file mode 100644 index 0000000000..ef0d563460 --- /dev/null +++ b/assets/js/291e1144.a80b3444.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[54644],{99121:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>i});const o=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow","title":"The workload cluster flow","description":"The workload cluster flow is implemented by two controllers and one custom resource.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/architecture","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow.md","tags":[],"version":"current","frontMatter":{}}');var r=s(74848),n=s(28453);const a={},c="The workload cluster flow",l={},i=[];function d(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"the-workload-cluster-flow",children:"The workload cluster flow"})}),"\n",(0,r.jsx)(t.p,{children:"The workload cluster flow is implemented by two controllers and one custom resource."}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"ClusterAddon"})," resource gets created by the ClusterAddonCreate controller for any ",(0,r.jsx)(t.code,{children:"Cluster"})," resource that is applied."]}),"\n",(0,r.jsxs)(t.p,{children:["The user never interacts with the ",(0,r.jsx)(t.code,{children:"ClusterAddon"})," resource as it is created, updated, and deleted automatically."]}),"\n",(0,r.jsx)(t.p,{children:"It is updated by the ClusterAddon controller, which makes sure that all cluster addons are applied in the respective workload cluster."}),"\n",(0,r.jsx)(t.p,{children:"The controller follows a simple pattern. When a cluster is created, it waits until the cluster is ready. If that is the case, it applies all objects from the ClusterAddon Helm Chart."}),"\n",(0,r.jsx)(t.p,{children:"If a cluster is updated, it checks whether there has been an update of the cluster addons and only if that's the case, it applies the objects again. It also deletes objects that have been there in the previous version but are not there anymore."}),"\n",(0,r.jsxs)(t.p,{children:["Applying the objects has one additional step: we take the idea of the cluster-api-addon-provider-helm and add a few details about the ",(0,r.jsx)(t.code,{children:"Cluster"})," and the ",(0,r.jsx)(t.code,{children:"ProviderCluster"})," in there (",(0,r.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/cluster-api-addon-provider-helm/blob/main/internal/value_substitutions.go",children:"https://github.com/kubernetes-sigs/cluster-api-addon-provider-helm/blob/main/internal/value_substitutions.go"}),")."]}),"\n",(0,r.jsx)(t.p,{children:"This is necessary, because normal templating could not inject these values that are only available at runtime but that are very important to the resources that we apply as cluster addons."}),"\n",(0,r.jsx)(t.p,{children:"As this controller relies on the release assets to be downloaded - as do other controllers that do not download anything themselves - there is one issue after a container restart that we have to solve:"}),"\n",(0,r.jsx)(t.p,{children:"If the container restarts, then everything that was stored in memory or without external volume in the container, will be lost. Therefore, a container restart requires to fetch from Github again."}),"\n",(0,r.jsxs)(t.p,{children:["This takes a bit of time, even if it is just one second. If a ",(0,r.jsx)(t.code,{children:"ClusterAddon"})," reconciles within this one second, it willl realize though, that the desired file is not available yet. Instead of throwing an error, we can intelligently requeue again."]}),"\n",(0,r.jsx)(t.p,{children:"The same pattern is followed in all other controllers as well, if needed."}),"\n",(0,r.jsx)(t.p,{children:"This controller also sets intelligent conditions into the status of the objects to make sure that the user can understand what is going on."})]})}function h(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>c});var o=s(96540);const r={},n=o.createContext(r);function a(e){const t=o.useContext(n);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),o.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/29c2cfba.e82e0a7b.js b/assets/js/29c2cfba.e82e0a7b.js new file mode 100644 index 0000000000..19c30f28c2 --- /dev/null +++ b/assets/js/29c2cfba.e82e0a7b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[98547],{46796:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"contribute/doc-files-structure-guide","title":"Documentation Files Structure","description":"Structure Best Practice","source":"@site/community/contribute/doc-files-structure-guide.md","sourceDirName":"contribute","slug":"/contribute/doc-files-structure-guide","permalink":"/community/contribute/doc-files-structure-guide","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Adding Docs Guide","permalink":"/community/contribute/adding-docs-guide"},"next":{"title":"Documentation workflow explanation","permalink":"/community/contribute/docs-workflow-explanation"}}');var r=n(74848),o=n(28453);const a={},s="Documentation Files Structure",l={},c=[{value:"Structure Best Practice",id:"structure-best-practice",level:2},{value:"Overview - mandatory",id:"overview---mandatory",level:3},{value:"Requirements - mandatory",id:"requirements---mandatory",level:3},{value:"Quickstart - optional. If it is possible, then mandatory",id:"quickstart---optional-if-it-is-possible-then-mandatory",level:3},{value:"Getting Started - mandatory",id:"getting-started---mandatory",level:3},{value:"Configuration \u2013 mandatory",id:"configuration--mandatory",level:3},{value:"Contribute \u2013 mandatory",id:"contribute--mandatory",level:3},{value:"FAQ`s \u2013 optional",id:"faqs--optional",level:3}];function d(t){const e={h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ul:"ul",...(0,o.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"documentation-files-structure",children:"Documentation Files Structure"})}),"\n",(0,r.jsx)(e.h2,{id:"structure-best-practice",children:"Structure Best Practice"}),"\n",(0,r.jsx)(e.h3,{id:"overview---mandatory",children:"Overview - mandatory"}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsx)(e.li,{children:"What is it and for what do I need this? What benefits does it have for users?"}),"\n",(0,r.jsx)(e.li,{children:"What organization/company does this belong to? (Link to company/organization)"}),"\n",(0,r.jsx)(e.li,{children:"Where am I \u2013 as module \u2013 within the bigger context of SCS?"}),"\n"]}),"\n",(0,r.jsx)(e.h3,{id:"requirements---mandatory",children:"Requirements - mandatory"}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsx)(e.li,{children:"What minimal requirements do i need to quickstart?"}),"\n"]}),"\n",(0,r.jsx)(e.h3,{id:"quickstart---optional-if-it-is-possible-then-mandatory",children:"Quickstart - optional. If it is possible, then mandatory"}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsx)(e.li,{children:"Link to requirements"}),"\n",(0,r.jsx)(e.li,{children:"What is the aim of this quickstart guide?"}),"\n",(0,r.jsx)(e.li,{children:"Caution: only for testing, not for production"}),"\n",(0,r.jsx)(e.li,{children:"Rule: one line per command for easy copy&paste and one line for description where possible"}),"\n",(0,r.jsx)(e.li,{children:"Rule: only one working path for installation!"}),"\n"]}),"\n",(0,r.jsx)(e.h3,{id:"getting-started---mandatory",children:"Getting Started - mandatory"}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsx)(e.li,{children:"Aim is a production ready installation"}),"\n"]}),"\n",(0,r.jsx)(e.h3,{id:"configuration--mandatory",children:"Configuration \u2013 mandatory"}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsx)(e.li,{children:"Showing all possible config options"}),"\n"]}),"\n",(0,r.jsx)(e.h3,{id:"contribute--mandatory",children:"Contribute \u2013 mandatory"}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsx)(e.li,{children:"Description for how can i contribute with Link to Github repository"}),"\n"]}),"\n",(0,r.jsx)(e.h3,{id:"faqs--optional",children:"FAQ`s \u2013 optional"}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsx)(e.li,{children:"Roadmap - optional"}),"\n"]})]})}function u(t={}){const{wrapper:e}={...(0,o.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(d,{...t})}):d(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>a,x:()=>s});var i=n(96540);const r={},o=i.createContext(r);function a(t){const e=i.useContext(o);return i.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:a(t.components),i.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/2ab96e79.bb47bad9.js b/assets/js/2ab96e79.bb47bad9.js new file mode 100644 index 0000000000..31b8b95e7e --- /dev/null +++ b/assets/js/2ab96e79.bb47bad9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[23844],{56793:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>a});const s=JSON.parse('{"id":"iaas/guides/other-guides/cloud-in-a-box/index","title":"Cloud in a Box","description":"\ud83d\udca1 Cloud in a Box (CiaB) is a minimalistic installation of the latest stable OSISM release with only services which are needed to","source":"@site/docs/02-iaas/guides/other-guides/cloud-in-a-box/index.md","sourceDirName":"02-iaas/guides/other-guides/cloud-in-a-box","slug":"/iaas/guides/other-guides/cloud-in-a-box/","permalink":"/docs/iaas/guides/other-guides/cloud-in-a-box/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/cloud-in-a-box/index.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Cloud in a Box Guide"},"sidebar":"docs","previous":{"title":"Other Guides","permalink":"/docs/iaas/guides/other-guides/"},"next":{"title":"Running on a virtual machine","permalink":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine"}}');var i=t(74848),l=t(28453);const o={sidebar_label:"Cloud in a Box Guide"},r="Cloud in a Box",d={},a=[{value:"Requirements",id:"requirements",level:2},{value:"Types",id:"types",level:2},{value:"Installation",id:"installation",level:2},{value:"Automated installation (recommended)",id:"automated-installation-recommended",level:3},{value:"Manual installation",id:"manual-installation",level:3},{value:"Usage",id:"usage",level:2},{value:"Wireguard VPN service access",id:"wireguard-vpn-service-access",level:3},{value:"Webinterfaces",id:"webinterfaces",level:3},{value:"Command-line interfaces",id:"command-line-interfaces",level:3},{value:"Import of additional images",id:"import-of-additional-images",level:3},{value:"Upgrade",id:"upgrade",level:3},{value:"Customisations",id:"customisations",level:2},{value:"Use of 2nd NIC for external network",id:"use-of-2nd-nic-for-external-network",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Development",id:"development",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,l.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"cloud-in-a-box",children:"Cloud in a Box"})}),"\n",(0,i.jsx)(n.p,{children:"\ud83d\udca1 Cloud in a Box (CiaB) is a minimalistic installation of the latest stable OSISM release with only services which are needed to\nmake it work with Kubernetes. It is intended for use as a development system on bare-metal or for use in edge environments or for\ntraining purposes. Its flexibility makes it ideal for building, testing, and refining cloud infrastructure setups in controlled\nenvironments, enabling teams to experiment with different configurations and scenarios before deploying them to production"}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["At the moment the secrets are stored in plain text in the ",(0,i.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box",children:"osism/cloud-in-a-box"}),"\nrepository and are not secure. Do not use for public accessible systems. In the future, the secrets will be generated automatically."]})}),"\n",(0,i.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,i.jsx)(n.p,{children:"The system to be used as Cloud in a Box must fulfill these minimum requirements."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Type of resource"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Amount"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"CPU"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"at least 1 socket with 4 cores"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"More is better here. This is the minimum where you can't use much payload (LBaaS, VMs). The use of Kubernetes with Cluster API is not possible with this minimum size."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"RAM"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"at least 32 GByte"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"More is better here. In principle, it also works with 8 GByte, but then no payload (LBaaS, VMs) can be used. Kubernetes with Cluster API cannot be used then."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Storage"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"at least 1 TByte"}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["Has to be available as ",(0,i.jsx)(n.code,{children:"/dev/sda"})," or ",(0,i.jsx)(n.code,{children:"/dev/nvme0n1"}),". Less than 1 TByte is also possible, the smaller the less storage is available for use in Ceph."]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Network"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"at least 1 network interface (DHCP and internet access)"}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["An optional ",(0,i.jsx)(n.a,{href:"#use-of-2nd-nic-for-external-network",children:"2nd network interface can be used for external connectivity"}),"."]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"USB stick"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"at least 2 GByte"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Installation media for Cloud in a Box bootstrapping"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"types",children:"Types"}),"\n",(0,i.jsx)(n.p,{children:"There are three types of Cloud in a Box."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.strong,{children:"sandbox"})," type is intended for developers and demonstrations. A full OSISM installation\nis one there which also includes Ceph and OpenSearch, for example. In the course of the\ninstallation, necessary images, networks, etc. are also created."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.strong,{children:"edge"})," type is intended to be deployed as an appliance to provide an edge cloud on a\nsingle node. Compared to the sandbox, certain services are not provided there or are\nimplemented differently. For example, OpenSearch is not deployed because the logs are\ndelivered to a central location. The storage backend will also be implemented differently there\nin the future instead of Ceph."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.strong,{children:"kubernetes"})," type is intended to be deployed as an appliance to provide a edge Kubernetes\ncluster on a single node."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsx)(n.h3,{id:"automated-installation-recommended",children:"Automated installation (recommended)"}),"\n",(0,i.jsxs)(n.p,{children:["The images currently download and install the\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box",children:"latest state of the installation scripts"}),",\ntherefore it is mandatory to update the installation media at least when the underlying Ubuntu operating\nsystem release changes. The installation of older releases is currently not supported."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Download one of the Cloud in a Box images of type sandbox"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/osism-node-image/ubuntu-autoinstall-cloud-in-a-box-1.iso",children:"ubuntu-autoinstall-cloud-in-a-box-1.iso"})," (with first block device as ",(0,i.jsx)(n.code,{children:"/dev/sda"}),")"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/osism-node-image/ubuntu-autoinstall-cloud-in-a-box-2.iso",children:"ubuntu-autoinstall-cloud-in-a-box-2.iso"})," (with first block device as ",(0,i.jsx)(n.code,{children:"/dev/nvme0n1"}),")"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Use a tool like ",(0,i.jsx)(n.a,{href:"https://etcher.balena.io",children:"balenaEtcher"})," or ",(0,i.jsx)(n.code,{children:"dd"})," to create a bootable USB stick with the Cloud\nin a Box image."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Boot from the USB stick. Make sure that the boot from USB is activated in the BIOS."}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"When booting from this USB stick, all data on the hard disks will be destroyed\nwithout confirmation."})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"The installation of the operating system (Ubuntu 22.04) will start and take a few minutes. After that the system\nwill shutdown."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"The first start of the system"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Remove the USB storage device\n(The USB stick is only needed again if the Cloud in a Box system is to be fully reinstalled.)"}),"\n",(0,i.jsx)(n.li,{children:"Connect the first network interface to an ethernet interface that provides access to the internet via DHCP configuration"}),"\n",(0,i.jsx)(n.li,{children:"Boot the system from the internal hard disk device"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"The deployment will start. This takes some time and the system will shutdown when the\ndeployment is finished. This takes roughly an hour, possibly longer depending on the\nhardware and internet connection."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Start the system again. System is ready for use, by default DHCP is tried on the first network device."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Login via SSH. Use the user ",(0,i.jsx)(n.code,{children:"dragon"})," with the password ",(0,i.jsx)(n.code,{children:"password"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"ssh dragon@IP_ADDRESS_FROM_YOUR_SERVER\n"})}),"\n",(0,i.jsxs)(n.admonition,{type:"info",children:[(0,i.jsxs)(n.p,{children:["You can obtain the IP address by inspecting the logs of your DHCP server or from the ",(0,i.jsx)(n.em,{children:"issue text"})," of the virtual consoles of the system."]}),(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Cloud in a Box Issue Text",src:t(31357).A+"",width:"420",height:"109"})})]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"manual-installation",children:"Manual installation"}),"\n",(0,i.jsxs)(n.p,{children:["The scripts are not idempotent yet. In case there is any fail during ",(0,i.jsx)(n.code,{children:"bootstrap.sh"})," or ",(0,i.jsx)(n.code,{children:"deploy.sh"})," you have to\nstart over with fresh installation."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Follow the ",(0,i.jsx)(n.a,{href:"../../deploy-guide/provisioning",children:"provisioning guide"}),",\nskip the part about disk layout and do it this way:"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Disk layout",src:t(75662).A+"",width:"1033",height:"769"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Create a 1 GByte ext4 partition mounted in ",(0,i.jsx)(n.code,{children:"/boot"})]}),"\n",(0,i.jsx)(n.li,{children:"Create a 8 GByte swap partition"}),"\n",(0,i.jsx)(n.li,{children:"Create a 120 GByte unformatted partition"}),"\n",(0,i.jsxs)(n.li,{children:["Use a ",(0,i.jsx)(n.code,{children:"Create volume group (LVM)"})," to create a volume group called ",(0,i.jsx)(n.code,{children:"system"})," with the size of\n120 GByte on the partition 4 you just created"]}),"\n",(0,i.jsxs)(n.li,{children:["Create a logical volume by selecting the ",(0,i.jsx)(n.code,{children:"Free Space"})," option under ",(0,i.jsx)(n.code,{children:"system"})," LVM. This volume\nshould be mounted in ",(0,i.jsx)(n.code,{children:"/"})," and have size of 100 GByte"]}),"\n",(0,i.jsx)(n.li,{children:"Create a partition with the size of the rest of the drive's space"}),"\n",(0,i.jsxs)(n.li,{children:["Create a new LVM volume group on partition 5 called ",(0,i.jsx)(n.code,{children:"osd-vg"})," (will be used for Ceph)"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"After the Ubuntu installation, the system will be rebooted"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Log into the machine via console to get its IP address and then use SSH to connect to the machine"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Clone the ",(0,i.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box",children:"osism/cloud-in-a-box"})," repository into ",(0,i.jsx)(n.code,{children:"/opt/cloud-in-a-box"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo git clone https://github.com/osism/cloud-in-a-box /opt/cloud-in-a-box\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Disable conflicting services from the default Ubuntu installation"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo /opt/cloud-in-a-box/cleanup.sh\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Install upgrades"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo apt update\nsudo apt upgrade\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Run the ",(0,i.jsx)(n.code,{children:"bootstrap.sh"})," script with the required ",(0,i.jsx)(n.a,{href:"#types",children:"type"})," (use of ",(0,i.jsx)(n.code,{children:"sandbox"})," is recommended)"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo /opt/cloud-in-a-box/bootstrap.sh sandbox\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Run the ",(0,i.jsx)(n.code,{children:"deploy.sh"})," script with the same type as in step 8 to deploy services like Ceph and OpenStack"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo /opt/cloud-in-a-box/deploy.sh sandbox\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Shutdown the system"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo shutdown -h now\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Start the system again. System is ready for use, by default DHCP is tried on the first network device."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Login via SSH. Use the user ",(0,i.jsx)(n.code,{children:"dragon"})," with the password ",(0,i.jsx)(n.code,{children:"password"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"ssh dragon@IP_ADDRESS_FROM_YOUR_SERVER\n"})}),"\n",(0,i.jsxs)(n.admonition,{type:"info",children:[(0,i.jsxs)(n.p,{children:["You can obtain the IP address by inspecting the logs of your DHCP server or from the ",(0,i.jsx)(n.em,{children:"issue text"})," of the virtual consoles of the system."]}),(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Cloud in a Box Issue Text",src:t(31357).A+"",width:"420",height:"109"})})]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsx)(n.h3,{id:"wireguard-vpn-service-access",children:"Wireguard VPN service access"}),"\n",(0,i.jsxs)(n.p,{children:["Copy the ",(0,i.jsx)(n.code,{children:"/home/dragon/wireguard-client.conf"})," file from Cloud in a Box to your workstation. This is necessary\nfor using the web endpoints on your workstation. Rename the Wireguard config file to something\nlike ",(0,i.jsx)(n.code,{children:"cloud-in-a-box.conf"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"If you want to connect to the Cloud in a Box system from multiple clients, change the client IP\naddress in the config file to be different on each client."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"scp dragon@IP_ADDRESS_FROM_YOUR_SERVER:/home/dragon/wireguard-client.conf $HOME/cloud-in-a-box.conf\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Install Wireguard on your workstation, if you have not done this before. For instructions how to do\nit on your workstation, please have a look on the documentation of your used distribution. The\nWireguard documentation you will find ",(0,i.jsx)(n.a,{href:"https://www.wireguard.com",children:"here"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Start the Wireguard tunnel."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo wg-quick up $HOME/cloud-in-a-box.conf\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Once the Wireguard tunnel has been set up, it is possible to access individual services on a name-based basis.\nAs a test, you can try whether the name ",(0,i.jsx)(n.code,{children:"api.in-a-box.cloud"})," resolves correctly to the IP address ",(0,i.jsx)(n.code,{children:"192.168.16.254"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"dig +short A api.in-a-box.cloud\n192.168.16.254\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If this does not work, a DNS filter such as Pi-hole or AdGuard will most likely be used. This ensures that private\nIP ranges such as ",(0,i.jsx)(n.code,{children:"192.168.16.0/20"})," are not resolved via a public DNS server. If this is the case, the following\nentries must be added to the local ",(0,i.jsx)(n.code,{children:"/etc/hosts"})," file for the name resolution to work."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"192.166.16.10\tcgit.services.in-a-box.cloud\n192.166.16.10\tnetbox.services.in-a-box.cloud\n192.168.16.10\tara.services.in-a-box.cloud\n192.168.16.10\tflower.services.in-a-box.cloud\n192.168.16.10\thomer.services.in-a-box.cloud\n192.168.16.10\tphpmyadmin.services.in-a-box.cloud\n192.168.16.10 manager.systems.in-a-box.cloud\n192.168.16.254\tapi.in-a-box.cloud\n"})}),"\n",(0,i.jsx)(n.h3,{id:"webinterfaces",children:"Webinterfaces"}),"\n",(0,i.jsx)(n.p,{children:"If you want to access the services please choose the URL from the following list:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Name"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"URL"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Username"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Password"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"ARA"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"https://ara.services.in-a-box.cloud",children:"https://ara.services.in-a-box.cloud"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"ara"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Ceph"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"http://manager.systems.in-a-box.cloud:7000",children:"http://manager.systems.in-a-box.cloud:7000"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"admin"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Configuration"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"https://cgit.services.in-a-box.cloud",children:"https://cgit.services.in-a-box.cloud"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Flower"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"https://flower.services.in-a-box.cloud",children:"https://flower.services.in-a-box.cloud"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Grafana"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"https://api.in-a-box.cloud:3000",children:"https://api.in-a-box.cloud:3000"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"admin"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"HAProxy"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"http://manager.systems.in-a-box.cloud:1984",children:"http://manager.systems.in-a-box.cloud:1984"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"openstack"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Homer"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"https://homer.services.in-a-box.cloud",children:"https://homer.services.in-a-box.cloud"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Horizon"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"https://api.in-a-box.cloud",children:"https://api.in-a-box.cloud"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["admin",(0,i.jsx)("br",{}),"test"]}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["password",(0,i.jsx)("br",{}),"test"]}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["domain: default, project: admin",(0,i.jsx)("br",{}),"domain: test, project: test"]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Netbox"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"https://netbox.services.in-a-box.cloud",children:"https://netbox.services.in-a-box.cloud"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"admin"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Netdata"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"http://manager.systems.in-a-box.cloud:19999",children:"http://manager.systems.in-a-box.cloud:19999"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"OpenSearch Dashboards"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"https://api.in-a-box.cloud:5601",children:"https://api.in-a-box.cloud:5601"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"opensearch"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"RabbitMQ"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"https://api.in-a-box.cloud:15672",children:"https://api.in-a-box.cloud:15672"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"openstack"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Skyline"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"https://api.in-a-box.cloud:9999",children:"https://api.in-a-box.cloud:9999"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["admin",(0,i.jsx)("br",{}),"test"]}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["password",(0,i.jsx)("br",{}),"test"]}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["domain: default, project: admin",(0,i.jsx)("br",{}),"domain: test, project: test"]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"phpMyAdmin"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.a,{href:"https://phpmyadmin.services.in-a-box.cloud",children:"https://phpmyadmin.services.in-a-box.cloud"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"root_shard_0"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"command-line-interfaces",children:"Command-line interfaces"}),"\n",(0,i.jsx)(n.p,{children:"Login to Cloud in a Box as described in step 8 of the installation chapter."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Select one of the preconfigured environments:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"system"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"admin"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"test"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Set the environment by exporting the environment variable: ",(0,i.jsx)(n.code,{children:"OS_CLOUD"}),":","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"export OS_CLOUD=admin\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Use ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/newton/user-guide/cli.html",children:"OpenStack CLI"})," via the command ",(0,i.jsx)(n.code,{children:"openstack"}),".","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack availability zone list\nopenstack image list\nopenstack server list # After installation there are no servers\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"import-of-additional-images",children:"Import of additional images"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"https://github.com/osism/openstack-image-manager/",children:"OpenStack Image Manager"})," is used to manage images.\nIn the example, the ",(0,i.jsx)(n.code,{children:"Garden Linux"})," image is imported."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"osism manage images --cloud=admin --filter 'Garden Linux'\n"})}),"\n",(0,i.jsxs)(n.p,{children:["All available images can be found in the ",(0,i.jsx)(n.a,{href:"https://github.com/osism/openstack-image-manager/tree/main/etc/images",children:"osism/openstack-image-manager"})," repository."]}),"\n",(0,i.jsx)(n.h3,{id:"upgrade",children:"Upgrade"}),"\n",(0,i.jsx)(n.p,{children:"It is best to execute the commands within a screen session, it takes some time. Please note\nthat you cannot update the Ceph deployment at the moment. This will be enabled in the future."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"osism apply configuration\n/opt/configuration/upgrade.sh\ndocker system prune -a\n"})}),"\n",(0,i.jsx)(n.h2,{id:"customisations",children:"Customisations"}),"\n",(0,i.jsx)(n.h3,{id:"use-of-2nd-nic-for-external-network",children:"Use of 2nd NIC for external network"}),"\n",(0,i.jsx)(n.p,{children:"In the default configuration, the Cloud in a Box is built in such a way that an internal\nVLAN101 is used as an simulated external network and this is made usable via the 1st network\ninterface using masquerading. This makes it possible for instances running on the Cloud\nin a Box to reach the internet. The disadvantage of this is that the instances themselves\ncan only be reached via floating IP addresses from the Cloud in a Box system itself or\nvia the Wireguard tunnel. Especially in edge environments, however, one would usually like\nto have this differently and the instances should be directly accessible via the local\nnetwork."}),"\n",(0,i.jsx)(n.p,{children:"To make this work, first identify the name of a 2nd network card to be used."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"dragon@manager:~$ sudo lshw -class network -short\nH/W path Device Class Description\n============================================================\n/0/100/2.2/0 eno7 network Ethernet Connection X552 10 GbE SFP+\n/0/100/2.2/0.1 eno8 network Ethernet Connection X552 10 GbE SFP+\n/0/100/1c/0 eno1 network I210 Gigabit Network Connection\n/0/100/1c.1/0 eno2 network I210 Gigabit Network Connection\n/0/100/1c.4/0 eno3 network I350 Gigabit Network Connection\n/0/100/1c.4/0.1 eno4 network I350 Gigabit Network Connection\n/0/100/1c.4/0.2 eno5 network I350 Gigabit Network Connection\n/0/100/1c.4/0.3 eno6 network I350 Gigabit Network Connection\n"})}),"\n",(0,i.jsxs)(n.p,{children:["In the following we use ",(0,i.jsx)(n.code,{children:"eno7"}),". Activate the device manually with ",(0,i.jsx)(n.code,{children:"sudo ip link set up dev eno7"}),".\nThen check that a link is actually present."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"dragon@manager:~$ ethtool eno7\nSettings for eno7:\n\tSupported ports: [ FIBRE ]\n\tSupported link modes: 10000baseT/Full\n[...]\n\tLink detected: yes\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Now this device is made permanently known in the network configuration. Select the MTU\naccordingly. For 1 GBit rather ",(0,i.jsx)(n.code,{children:"1500"})," than ",(0,i.jsx)(n.code,{children:"9100"}),". The 2nd network interface should be\nconfigured without IP configuration (neither static nor DHCP)."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/opt/configuration/inventory/group_vars/generic/network.yml"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/opt/configuration/environments/manager/group_vars/manager.yml"})}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"network_ethernets:\n eno1:\n dhcp4: true\n eno7:\n mtu: 9100\n"})}),"\n",(0,i.jsx)(n.p,{children:"Then, this change is deployed and applied."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"osism apply network\nsudo netplan apply\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Now the configuration for Neutron and OVN is prepared. ",(0,i.jsx)(n.code,{children:"network_workload_interface"}),"\nis expanded by the 2nd network interface. The order is not random, first ",(0,i.jsx)(n.code,{children:"vlan101"}),"\nthen ",(0,i.jsx)(n.code,{children:"eno7"}),". ",(0,i.jsx)(n.code,{children:"neutron_bridge_name"})," is added."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/opt/configuration/inventory/group_vars/generic/network.yml"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/opt/configuration/environments/manager/group_vars/manager.yml"})}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'network_workload_interface: "vlan101,eno7"\nneutron_bridge_name: "br-ex,br-add"\n'})}),"\n",(0,i.jsx)(n.p,{children:"Then, this change is deployed."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"osism reconciler sync\nosism apply openvswitch\nosism apply ovn\nosism apply neutron\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Now segments and/or subnets can be configured. In this case, ",(0,i.jsx)(n.code,{children:"eno7"})," is configured as an\nuntagged port on the remote side."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"/opt/configuration/environments/openstack/playbook-additional-public-network.yml"})}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"- name: Create additional public network\n hosts: localhost\n connection: local\n\n tasks:\n - name: Create additional public network\n openstack.cloud.network:\n cloud: admin\n state: present\n name: public-add\n external: true\n provider_network_type: flat\n provider_physical_network: physnet2\n\n - name: Create additional public subnet\n openstack.cloud.subnet:\n cloud: admin\n state: present\n name: subnet-public-add\n network_name: public-add\n cidr: 192.168.23.0/24\n enable_dhcp: false\n allocation_pool_start: 192.168.23.100\n allocation_pool_end: 192.168.23.200\n gateway_ip: 192.168.23.1\n dns_nameservers:\n - 8.8.8.8\n - 9.9.9.9\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The additional public network can now be made known with\n",(0,i.jsx)(n.code,{children:"osism apply -e openstack additional-public-network"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["There is now a 2nd floating IP address pool with the name ",(0,i.jsx)(n.code,{children:"public-add"}),"\navailable for use. If instances are to be started directly in this network,\n",(0,i.jsx)(n.code,{children:"enable_dhcp: true"})," must be set. In this case, it should be clarified in\nadvance with the provider of the external network whether the use of DHCP\nis permitted there."]}),"\n",(0,i.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Broken disk setup",src:t(14661).A+"",width:"2020",height:"1194"})}),"\n",(0,i.jsxs)(n.p,{children:["This error means that your disk setup is broken. Use ",(0,i.jsx)(n.code,{children:"cfdisk"})," and delete all partitions on\nthe system on which you want to install the Cloud in a Box image."]}),"\n",(0,i.jsxs)(n.p,{children:["With ",(0,i.jsx)(n.code,{children:"lsblk"})," you can verify if the partitions are empty."]}),"\n",(0,i.jsx)(n.h2,{id:"development",children:"Development"}),"\n",(0,i.jsx)(n.p,{children:"For the further development of the scripts and the mechanisms of the Cloud in a Box,\nyou need to know the following."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["The operating system is brought onto the node via ",(0,i.jsx)(n.a,{href:"https://github.com/osism/node-image",children:"an automatic Ubuntu installation"}),"\nthat uses ",(0,i.jsx)(n.a,{href:"https://cloud-init.io",children:"cloud-init"})]}),"\n",(0,i.jsxs)(n.li,{children:["The installation starts the script ",(0,i.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box/blob/main/init.sh",children:"init.sh"})," which performs\nan initial clone of the ",(0,i.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box",children:"osism/cloud-in-a-box"})," repository and a checkout of\nthe ",(0,i.jsx)(n.code,{children:"main"})," branch. It also executes the ",(0,i.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box/blob/main/deploy.sh",children:"deploy.sh"})," and\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box/blob/main/bootstrap.sh",children:"bootstrap.sh"})," scripts."]}),"\n",(0,i.jsxs)(n.li,{children:["The installation persists the kernel parameters of the initial boot to the file ",(0,i.jsx)(n.code,{children:"/etc/.initial-kernel-commandline"})]}),"\n",(0,i.jsxs)(n.li,{children:["The status and activities of the deployment are logged in ",(0,i.jsx)(n.code,{children:"/var/log/install-cloud-in-a-box.log"}),". For proper colors use ",(0,i.jsx)(n.code,{children:"less -r"}),".\nSearch for ",(0,i.jsx)(n.code,{children:"OVERALL STATUS"})," to find the result of the specific installation steps."]}),"\n",(0,i.jsxs)(n.li,{children:["Branch and location of the ",(0,i.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box",children:"osism/cloud-in-a-box"})," repository can be overriden\nby setting the kernel parameters ",(0,i.jsx)(n.code,{children:"ciab_repo_url"})," (a public repository address without authentication) and ",(0,i.jsx)(n.code,{children:"ciab_branch"}),"\n(a name of a branch, use only ASCII chars, ",(0,i.jsx)(n.code,{children:"-"}),", and ",(0,i.jsx)(n.code,{children:"_"}),")."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},75662:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/disk-layout-db64866af60ef6d2c41245db78dd15d1.png"},31357:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/issue-6cc9ac7387e0589d625dded707510641.png"},14661:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/screenshot1-c880f78ba33fc0577dce811dc2e42724.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const i={},l=s.createContext(i);function o(e){const n=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2abb9c6f.658c3960.js b/assets/js/2abb9c6f.658c3960.js new file mode 100644 index 0000000000..b835355af7 --- /dev/null +++ b/assets/js/2abb9c6f.658c3960.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[76372],{44107:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>i,default:()=>d,frontMatter:()=>c,metadata:()=>o,toc:()=>u});const o=JSON.parse('{"id":"iaas/guides/concept-guide/components/prometheus","title":"Prometheus & Grafana","description":"Lifecycle Management of Prometheus in OSISM","source":"@site/docs/02-iaas/guides/concept-guide/components/prometheus.md","sourceDirName":"02-iaas/guides/concept-guide/components","slug":"/iaas/guides/concept-guide/components/prometheus","permalink":"/docs/iaas/guides/concept-guide/components/prometheus","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/prometheus.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"OpenStack","permalink":"/docs/iaas/guides/concept-guide/components/openstack"},"next":{"title":"SONiC & OVN","permalink":"/docs/iaas/guides/concept-guide/components/sonic"}}');var s=t(74848),a=t(28453);const c={},i="Prometheus & Grafana",r={},u=[{value:"Lifecycle Management of Prometheus in OSISM",id:"lifecycle-management-of-prometheus-in-osism",level:2},{value:"Lifecycle Management of Grafana in OSISM",id:"lifecycle-management-of-grafana-in-osism",level:2}];function m(e){const n={h1:"h1",h2:"h2",header:"header",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"prometheus--grafana",children:"Prometheus & Grafana"})}),"\n",(0,s.jsx)(n.h2,{id:"lifecycle-management-of-prometheus-in-osism",children:"Lifecycle Management of Prometheus in OSISM"}),"\n",(0,s.jsx)(n.h2,{id:"lifecycle-management-of-grafana-in-osism",children:"Lifecycle Management of Grafana in OSISM"})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(m,{...e})}):m(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var o=t(96540);const s={},a=o.createContext(s);function c(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2c0d30da.93627fee.js b/assets/js/2c0d30da.93627fee.js new file mode 100644 index 0000000000..27d931568d --- /dev/null +++ b/assets/js/2c0d30da.93627fee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[16218],{71307:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"application-examples/opendesk-on-scs/requirements","title":"Requirements","description":"You can find the general requirements in the openDesk documentation. Please study them before beginning. This howto only touches on requirements concerning the rollout on an SCS cluster.","source":"@site/user-docs/application-examples/opendesk-on-scs/requirements.md","sourceDirName":"application-examples/opendesk-on-scs","slug":"/application-examples/opendesk-on-scs/requirements","permalink":"/user-docs/application-examples/opendesk-on-scs/requirements","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"userDocs","previous":{"title":"Quickstart","permalink":"/user-docs/application-examples/opendesk-on-scs/quickstart"},"next":{"title":"Getting started: Deployment from a local machine","permalink":"/user-docs/application-examples/opendesk-on-scs/getting_started"}}');var r=s(74848),o=s(28453);const a={},i="Requirements",c={},l=[{value:"Preparation of your local environment",id:"preparation-of-your-local-environment",level:2},{value:"Command line tools",id:"command-line-tools",level:3},{value:"KUBECONFIG",id:"kubeconfig",level:3},{value:"Preparation of the nameserver",id:"preparation-of-the-nameserver",level:2},{value:"Preparation of the Kubernetes cluster",id:"preparation-of-the-kubernetes-cluster",level:2},{value:"Install cert-manager",id:"install-cert-manager",level:3},{value:"Deploy a certificate issuer",id:"deploy-a-certificate-issuer",level:3},{value:"Ingress Controller",id:"ingress-controller",level:3},{value:"Prometheus",id:"prometheus",level:3},{value:"Storage",id:"storage",level:3},{value:"Optional: Credentials for a mail relay",id:"optional-credentials-for-a-mail-relay",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"requirements",children:"Requirements"})}),"\n",(0,r.jsxs)(n.p,{children:["You can find the general ",(0,r.jsx)(n.a,{href:"https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk/-/blob/main/docs/requirements.md",children:"requirements"})," in the openDesk documentation. Please study them before beginning. This howto only touches on requirements concerning the rollout on an SCS cluster."]}),"\n",(0,r.jsx)(n.h2,{id:"preparation-of-your-local-environment",children:"Preparation of your local environment"}),"\n",(0,r.jsx)(n.h3,{id:"command-line-tools",children:"Command line tools"}),"\n",(0,r.jsx)(n.p,{children:"You will need the following command line tools on your machine:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://kubernetes.io/de/docs/tasks/tools/install-kubectl/",children:"kubectl"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://helm.sh/",children:"helm"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://helmfile.readthedocs.io/en/latest/",children:"helmfile"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://github.com/databus23/helm-diff",children:"helmDiff"})}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["If you run into any problems, please check the openDesk ",(0,r.jsx)(n.a,{href:"https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk/-/blob/main/docs/requirements.md",children:"requirements"})," for the required software versions of these tools."]}),"\n",(0,r.jsx)(n.h3,{id:"kubeconfig",children:"KUBECONFIG"}),"\n",(0,r.jsxs)(n.p,{children:["Store the cluster access information for your SCS cluster in ",(0,r.jsx)(n.code,{children:"~/.kube/config"}),". Test the access to the cluster on your command line with a ",(0,r.jsx)(n.code,{children:"kubectl"})," command, e.g. ",(0,r.jsx)(n.code,{children:"kubectl get nodes"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"preparation-of-the-nameserver",children:"Preparation of the nameserver"}),"\n",(0,r.jsxs)(n.p,{children:["openDesk consists of a number of resources with different virtual host names and subdomains. The proposed procedure deploys openDesk on a subdomain that matches the name of the namespace you choose. You will thus get URLs like ",(0,r.jsx)(n.code,{children:"portal.dev.example.org"})," or ",(0,r.jsx)(n.code,{children:"wiki.prod.example.org"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Therefore it is recommended to create a wildcard A record for the domain in your nameserver (e.g. ",(0,r.jsx)(n.code,{children:"*.example.org"}),") and point it to your cluster's public IP address."]}),"\n",(0,r.jsx)(n.p,{children:"It is of course possible to create individual A records for all resources."}),"\n",(0,r.jsxs)(n.p,{children:["The choice of your nameserver has an impact: It is recommended to use a nameserver that gives you API access: In this howto, TLS certificates are fetched from the certification authority ",(0,r.jsx)(n.a,{href:"https://letsencrypt.org/",children:"Letsencrypt"}),". Because of the number of different services, a wildcard certificate comes in handy. Note that you can only request wildcard certificates from Letsencrypt via the ",(0,r.jsx)(n.a,{href:"https://letsencrypt.org/docs/challenge-types/",children:"dns-01 challenge"}),". To do so you need a nameserver with API access. If your nameserver does not support this, you can delegate the zone to a different nameserver and fetch an API access token from there."]}),"\n",(0,r.jsx)(n.h2,{id:"preparation-of-the-kubernetes-cluster",children:"Preparation of the Kubernetes cluster"}),"\n",(0,r.jsx)(n.h3,{id:"install-cert-manager",children:"Install cert-manager"}),"\n",(0,r.jsxs)(n.p,{children:["Install cert-manager in your cluster. It is required to include the custom resource definitions (",(0,r.jsx)(n.code,{children:"--set installCRDs=true"}),")."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"helm repo add jetstack https://charts.jetstack.io --force-update\nhelm repo update\nhelm upgrade -i cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set installCRDs=true\n"})}),"\n",(0,r.jsx)(n.h3,{id:"deploy-a-certificate-issuer",children:"Deploy a certificate issuer"}),"\n",(0,r.jsxs)(n.p,{children:["The openDesk helmfiles are based on the assumption that you - as the cluster admin - take care of a certificate issuer that can just be used then. For Letsencrypt's ACME dns-01 challenge add a ",(0,r.jsx)(n.a,{href:"https://cert-manager.io/docs/concepts/issuer/",children:"cluster issuer"})," by defining it in a file, e.g. ",(0,r.jsx)(n.code,{children:"clusterIssuer.yaml"})," and applying it to the cluster. Check the documentation for your respective DNS provider to put together the relevant configuration details."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"---\napiVersion: v1\nkind: Secret\nmetadata:\n name: my-dns-provider\ndata:\n secret-access-key: my-generated-access-token\n---\napiVersion: cert-manager.io/v1\nkind: ClusterIssuer\nmetadata:\n name: letsencrypt-staging\nspec:\n acme:\n privateKeySecretRef:\n name: example-account-key\n server: https://acme-staging-v02.api.letsencrypt.org/directory\n solvers:\n - dns01:\n my-dns-provider:\n region: eu-west-1\n accessKeyID: my-key-id\n secretAccessKeySecretRef:\n name: my-dns-provider\n key: secret-access-key\n selector:\n dnsNames:\n - '*.example.org'\n---\napiVersion: cert-manager.io/v1\nkind: ClusterIssuer\nmetadata:\n name: letsencrypt-prod\nspec:\n acme:\n privateKeySecretRef:\n name: example-account-key\n server: https://acme-v02.api.letsencrypt.org/directory\n solvers:\n - dns01:\n my-dns-provider:\n region: eu-west-1\n accessKeyID: my-key-id\n secretAccessKeySecretRef:\n name: my-dns-provider\n key: secret-access-key\n selector:\n dnsNames:\n - '*.example.org'\n"})}),"\n",(0,r.jsx)(n.h3,{id:"ingress-controller",children:"Ingress Controller"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/kubernetes/ingress-nginx",children:"Ingress-nginx"})," is the only tested ingress controller. The installation must support snippet annotations (",(0,r.jsx)(n.code,{children:"allowSnippetAnnotations=true"}),"). You can install and update it as shown below. Note that for production environments it is recommended to reconsider the HSTS setting given here."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"helm upgrade --install ingress-nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginx --namespace ingress-nginx --create-namespace --set controller.allowSnippetAnnotations=true --set controller.config.hsts=false\n"})}),"\n",(0,r.jsx)(n.h3,{id:"prometheus",children:"Prometheus"}),"\n",(0,r.jsx)(n.p,{children:"Prometheus is a requirement:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"helm repo add prometheus-community https://prometheus-community.github.io/helm-charts\nhelm upgrade -i prometheus prometheus-community/kube-prometheus-stack --namespace prometheus --create-namespace\n"})}),"\n",(0,r.jsx)(n.h3,{id:"storage",children:"Storage"}),"\n",(0,r.jsx)(n.p,{children:"Clarify with your SCS cluster operator what kind of storage your K8s cluster provides. Your configuration will need the according information. You can query the available storage classes like so:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"kubectl get storageclasses.storage.k8s.io\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can hand over the storage class in your ",(0,r.jsx)(n.code,{children:"values.yaml.gotmpl"})," (see ",(0,r.jsx)(n.a,{href:"/user-docs/application-examples/opendesk-on-scs/getting_started",children:"Getting Started"}),")."]}),"\n",(0,r.jsx)(n.h3,{id:"optional-credentials-for-a-mail-relay",children:"Optional: Credentials for a mail relay"}),"\n",(0,r.jsx)(n.p,{children:"If you want your openDesk deployment to be able to send outgoing emails, have the hostname and credentials of an SMTP relay at hand."})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>i});var t=s(96540);const r={},o=t.createContext(r);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2c36e6c1.61127581.js b/assets/js/2c36e6c1.61127581.js new file mode 100644 index 0000000000..6f0063dc28 --- /dev/null +++ b/assets/js/2c36e6c1.61127581.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[43136],{50370:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>n,toc:()=>a});const n=JSON.parse('{"id":"turnkey-solution/overview","title":"Overview","description":"Scope of this document","source":"@site/docs/turnkey-solution/overview.md","sourceDirName":"turnkey-solution","slug":"/turnkey-solution/overview","permalink":"/docs/turnkey-solution/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/turnkey-solution/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Turnkey Solution","permalink":"/docs/category/turnkey-solution"},"next":{"title":"Hardware-Landscape","permalink":"/docs/turnkey-solution/hardware-landscape"}}');var d=s(74848),i=s(28453);const c={},r="Overview",o={},a=[{value:"Scope of this document",id:"scope-of-this-document",level:2},{value:"Overview table",id:"overview-table",level:2}];function l(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(t.header,{children:(0,d.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,d.jsx)(t.h2,{id:"scope-of-this-document",children:"Scope of this document"}),"\n",(0,d.jsx)(t.p,{children:"The Sovereign Cloud Stack software (reference implementation) consists of numerous modules. This is intentional, as we have various operators that have deployed preexisting technology or have specific requirements and expect SCS to fit into it. It is good practice to build technology in a modular way, as this allows different pieces to move at its own speed and ensures that work is invested into proper abstractions and interfaces to build a losely coupled system that is resilient."}),"\n",(0,d.jsx)(t.p,{children:"That said, the most value is derived by operators that consume the complete stack. We thus provide an overview over all components and some hints of how to deploy them."}),"\n",(0,d.jsx)(t.p,{children:"We start with the functional stack at the bottom, where a deployment on server hardware is automated."}),"\n",(0,d.jsx)(t.h2,{id:"overview-table",children:"Overview table"}),"\n",(0,d.jsxs)(t.table,{children:[(0,d.jsx)(t.thead,{children:(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.th,{children:"Layer"}),(0,d.jsx)(t.th,{children:"Component"}),(0,d.jsx)(t.th,{children:"Subcomponent"}),(0,d.jsx)(t.th,{children:"Purpose"}),(0,d.jsx)(t.th,{children:"Status"}),(0,d.jsx)(t.th,{children:"Requirements"}),(0,d.jsx)(t.th,{children:"Documentation"})]})}),(0,d.jsxs)(t.tbody,{children:[(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"Infra"}),(0,d.jsx)(t.td,{children:"OSISM"}),(0,d.jsx)(t.td,{children:"Manager, Netbox, ..."}),(0,d.jsx)(t.td,{children:"Lifecycle Manage deployment"}),(0,d.jsx)(t.td,{children:"Prod"}),(0,d.jsx)(t.td,{children:"HW"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/iaas/guides/configuration-guide/",children:"https://docs.scs.community/docs/iaas/guides/configuration-guide/"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"Ops"}),(0,d.jsx)(t.td,{children:"OSISM"}),(0,d.jsx)(t.td,{children:"Prometheus, Netdata, AlertMgr, ..."}),(0,d.jsx)(t.td,{children:"Monitor Infra layer"}),(0,d.jsx)(t.td,{children:"Prod"}),(0,d.jsx)(t.td,{children:"HW"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/iaas/guides/concept-guide/#components-in-a-cluster",children:"https://docs.scs.community/docs/iaas/guides/concept-guide/#components-in-a-cluster"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"SDS"}),(0,d.jsx)(t.td,{children:"OSISM"}),(0,d.jsx)(t.td,{children:"ceph"}),(0,d.jsx)(t.td,{children:"Storage (Block, Object)"}),(0,d.jsx)(t.td,{children:"Prod"}),(0,d.jsx)(t.td,{children:"HW"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/iaas/guides/concept-guide/components/ceph",children:"https://docs.scs.community/docs/iaas/guides/concept-guide/components/ceph"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"SDN"}),(0,d.jsx)(t.td,{children:"OSISM"}),(0,d.jsx)(t.td,{children:"OVN"}),(0,d.jsx)(t.td,{children:"Networking"}),(0,d.jsx)(t.td,{children:"Prod"}),(0,d.jsx)(t.td,{children:"HW"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/iaas/guides/concept-guide/components/sonic#-lifecycle-management-of-open-virtual-network-ovn-in-osism",children:"https://docs.scs.community/docs/iaas/guides/concept-guide/components/sonic#-lifecycle-management-of-open-virtual-network-ovn-in-osism"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"IaaS"}),(0,d.jsx)(t.td,{children:"OSISM"}),(0,d.jsx)(t.td,{children:"OpenStack"}),(0,d.jsx)(t.td,{children:"Virtualization"}),(0,d.jsx)(t.td,{children:"Prod"}),(0,d.jsx)(t.td,{children:"HW"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/iaas/guides/concept-guide/components/openstack",children:"https://docs.scs.community/docs/iaas/guides/concept-guide/components/openstack"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"KaaS"}),(0,d.jsx)(t.td,{children:"ClusterStacks"}),(0,d.jsx)(t.td,{children:"CAPI, CAPO, ClusterStacks, CSO, CSPO"}),(0,d.jsx)(t.td,{children:"K8s cluster management"}),(0,d.jsx)(t.td,{children:"Stable"}),(0,d.jsx)(t.td,{children:"IaaS"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stacks/overview",children:"https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stacks/overview"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"PaaS"}),(0,d.jsx)(t.td,{children:"Registry"}),(0,d.jsx)(t.td,{children:"harbor"}),(0,d.jsx)(t.td,{children:"Container registry"}),(0,d.jsx)(t.td,{children:"Prod"}),(0,d.jsx)(t.td,{children:"KaaS"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/category/container-registry",children:"https://docs.scs.community/docs/category/container-registry"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"API"}),(0,d.jsx)(t.td,{children:"Central API"}),(0,d.jsx)(t.td,{children:"Central API"}),(0,d.jsx)(t.td,{children:"API for IAM, IaaS, KaaS"}),(0,d.jsx)(t.td,{children:"Tech Preview"}),(0,d.jsx)(t.td,{children:"KaaS"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://scs.community/tech/2024/08/13/central-api-tech-preview-release/",children:"https://scs.community/tech/2024/08/13/central-api-tech-preview-release/"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"Ops"}),(0,d.jsx)(t.td,{children:"OS Health Monitor"}),(0,d.jsx)(t.td,{children:"OSHM (old)"}),(0,d.jsx)(t.td,{children:"IaaS monitor"}),(0,d.jsx)(t.td,{children:"Deprecated"}),(0,d.jsx)(t.td,{children:"IaaS"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install",children:"https://docs.scs.community/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"Ops"}),(0,d.jsx)(t.td,{children:"Health Monitor"}),(0,d.jsx)(t.td,{children:"OSHM (new)"}),(0,d.jsx)(t.td,{children:"IaaS monitor"}),(0,d.jsx)(t.td,{children:"Stable"}),(0,d.jsx)(t.td,{children:"IaaS"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/category/scs-health-monitor",children:"https://docs.scs.community/docs/category/scs-health-monitor"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"Ops"}),(0,d.jsx)(t.td,{children:"Health Monitor"}),(0,d.jsx)(t.td,{children:"SCS monitoring"}),(0,d.jsx)(t.td,{children:"K8s cluster monitor"}),(0,d.jsx)(t.td,{children:"Prod"}),(0,d.jsx)(t.td,{children:"KaaS"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/category/monitoring",children:"https://docs.scs.community/docs/category/monitoring"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"Ops"}),(0,d.jsx)(t.td,{children:"Status Page"}),(0,d.jsx)(t.td,{children:"SCS Status Page"}),(0,d.jsx)(t.td,{children:"Publication of platform status"}),(0,d.jsx)(t.td,{children:"Technical Preview"}),(0,d.jsx)(t.td,{children:"KaaS"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/category/status-page",children:"https://docs.scs.community/docs/category/status-page"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"Ops"}),(0,d.jsx)(t.td,{children:"Metering"}),(0,d.jsx)(t.td,{children:"SCS metering"}),(0,d.jsx)(t.td,{children:"Usage data collection"}),(0,d.jsx)(t.td,{children:"Tech Preview"}),(0,d.jsx)(t.td,{children:"IaaS"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/category/metering",children:"https://docs.scs.community/docs/category/metering"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"Ops"}),(0,d.jsx)(t.td,{children:"SCS Compliance"}),(0,d.jsx)(t.td,{children:"SCS compliance tests"}),(0,d.jsx)(t.td,{children:"Testsuite"}),(0,d.jsx)(t.td,{children:"Stable"}),(0,d.jsx)(t.td,{children:"IaaS+KaaS"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/standards/scs-0004-v1-achieving-certification",children:"https://docs.scs.community/standards/scs-0004-v1-achieving-certification"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"CI"}),(0,d.jsx)(t.td,{children:"SCS pipelines"}),(0,d.jsx)(t.td,{children:"zuul"}),(0,d.jsx)(t.td,{children:"Automation and validation"}),(0,d.jsx)(t.td,{children:"Stable"}),(0,d.jsx)(t.td,{children:"IaaS (KaaS optional)"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/community/tools/zuul",children:"https://docs.scs.community/community/tools/zuul"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"Sec"}),(0,d.jsx)(t.td,{children:"Pentesting"}),(0,d.jsx)(t.td,{children:"SCS Pentesting"}),(0,d.jsx)(t.td,{children:"Automated security assessent"}),(0,d.jsx)(t.td,{children:"Stable"}),(0,d.jsx)(t.td,{children:"zuul"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/docs/operating-scs/components/automated-pentesting-iaas/overview#scs-automated-pentesting",children:"https://docs.scs.community/docs/operating-scs/components/automated-pentesting-iaas/overview#scs-automated-pentesting"})})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:"IAM"}),(0,d.jsx)(t.td,{children:"Keycloak"}),(0,d.jsx)(t.td,{children:"Keycloak"}),(0,d.jsx)(t.td,{children:"ID provider and broker for federation"}),(0,d.jsx)(t.td,{children:"Stable"}),(0,d.jsx)(t.td,{children:"IaaS"}),(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"https://docs.scs.community/contributor-docs/operations/iam/identity-federation-in-scs",children:"https://docs.scs.community/contributor-docs/operations/iam/identity-federation-in-scs"})})]})]})]}),"\n",(0,d.jsx)(t.p,{children:"Legend for status:"}),"\n",(0,d.jsxs)(t.ul,{children:["\n",(0,d.jsx)(t.li,{children:"Prod = Proven in numerous production environments"}),"\n",(0,d.jsx)(t.li,{children:"Stable = Stable release, fully supported, may not be removed without prior deprecation"}),"\n",(0,d.jsx)(t.li,{children:"Tech Preview = Technical preview, may not be depended upon yet and may undergo significant change or removal in the future"}),"\n",(0,d.jsx)(t.li,{children:"Deprecated = Still supported, but to be removed in the future"}),"\n"]}),"\n",(0,d.jsx)(t.p,{children:"Notes:"}),"\n",(0,d.jsxs)(t.ul,{children:["\n",(0,d.jsx)(t.li,{children:"OSISM comes with numerous components to manage the hardware deployment of the Infra and IaaS stack, such as homer (the portal), ARA, netbox, netdata, ... which are not all listed here. Their deployment is covered with a standard OSISM deployment and thus no separate deployment guides are linked here."}),"\n",(0,d.jsx)(t.li,{children:"Similarly, Cluster Stacks, building on top of Kubernetes Cluster API, consists of a set of components that are all meant to be used together and are thus covered in one set of documents. This also includes the cluster-add-ons to integrate with the underlaying IaaS. Note that while Cluster Stack has been designed and implemented to work very well on SCS IaaS, it does also fully support other IaaS environments (such as e.g. docker for development or Hetzner for production)."}),"\n",(0,d.jsx)(t.li,{children:"The journey to provide seamless self-service federation across all layers of the SCS stack is a long one; while the IAM solution included is stable, it is still limited in scope, which has prevented broad adoption thus far. Work is underway to address this, which is reflected in the linked documentation."}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,d.jsx)(t,{...e,children:(0,d.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>r});var n=s(96540);const d={},i=n.createContext(d);function c(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:c(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2cc9d448.804fac55.js b/assets/js/2cc9d448.804fac55.js new file mode 100644 index 0000000000..dd0a12e78e --- /dev/null +++ b/assets/js/2cc9d448.804fac55.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[83574],{95199:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"releases/Release6","title":"Release Notes for SCS Release 6","description":"SCS Release 6 has been published on 2024-03-20.","source":"@site/docs/06-releases/Release6.md","sourceDirName":"06-releases","slug":"/releases/Release6","permalink":"/docs/releases/Release6","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release6.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Release Notes for SCS Release 5","permalink":"/docs/releases/Release5"},"next":{"title":"Release Notes for SCS Release 7","permalink":"/docs/releases/Release7"}}');var t=n(74848),a=n(28453);const r={},o="Release Notes for SCS Release 6",l={},c=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"IaaS",id:"iaas",level:3},{value:"KaaS",id:"kaas",level:3},{value:"Operations",id:"operations",level:3},{value:"Observability",id:"observability",level:4},{value:"Zuul",id:"zuul",level:4},{value:"IAM",id:"iam",level:3},{value:"New Features (Highlights)",id:"new-features-highlights",level:2},{value:"Operator focused improvements",id:"operator-focused-improvements",level:3},{value:"OpenStack Health Monitor",id:"openstack-health-monitor",level:4},{value:"SCS Developer focused improvements (testbed and k8s cluster management)",id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",level:3},{value:"KaaS",id:"kaas-1",level:4},{value:"Preview: Domain Manager Persona",id:"preview-domain-manager-persona",level:3},{value:"Preview: Central API",id:"preview-central-api",level:3},{value:"Preview: Keycloak Home-IdP-discovery",id:"preview-keycloak-home-idp-discovery",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Security assessment for IaaS",id:"security-assessment-for-iaas",level:3},{value:"Resolved Issues",id:"resolved-issues",level:2},{value:"Preview: proper scope filtering for domain list API",id:"preview-proper-scope-filtering-for-domain-list-api",level:3},{value:"Documentation",id:"documentation",level:2},{value:"Highlighted blog posts",id:"highlighted-blog-posts",level:3},{value:"IAM",id:"iam-1",level:3},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R6",id:"list-of-known-issues--restrictions-in-r6",level:2},{value:"IaaS",id:"iaas-1",level:3},{value:"Loadbalancer service (octavia)",id:"loadbalancer-service-octavia",level:4},{value:"KaaS",id:"kaas-2",level:3},{value:"IAM",id:"iam-2",level:3},{value:"Contributing",id:"contributing",level:2},{value:"Thanks",id:"thanks",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"release-notes-for-scs-release-6",children:"Release Notes for SCS Release 6"})}),"\n",(0,t.jsx)(s.p,{children:"SCS Release 6 has been published on 2024-03-20."}),"\n",(0,t.jsx)(s.h2,{id:"scope",children:"Scope"}),"\n",(0,t.jsxs)(s.p,{children:["Just as our previous release, Release 6 has been developed alongside a set of ",(0,t.jsx)(s.a,{href:"https://scs.community/2023/12/29/scs-r6-enables/",children:"associated outcomes"}),".\nOverall with Release 6 it becomes apparent that SCS is efficient to operate."]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"SCS is standardized"}),"\n",(0,t.jsx)(s.li,{children:"SCS is understandable"}),"\n",(0,t.jsx)(s.li,{children:"SCS enables"}),"\n",(0,t.jsx)(s.li,{children:"SCS is transparent"}),"\n",(0,t.jsx)(s.li,{children:"SCS is continuously built and tested"}),"\n",(0,t.jsx)(s.li,{children:"SCS is opinionated"}),"\n",(0,t.jsx)(s.li,{children:"SCS charters new territory"}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,t.jsx)(s.h3,{id:"iaas",children:"IaaS"}),"\n",(0,t.jsxs)(s.p,{children:["The IaaS reference implementation is based on ",(0,t.jsx)(s.a,{href:"https://osism.tech/docs/release-notes/osism-7",children:"OSISM 7.0.0"}),"\nand delivers the following components:"]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://releases.openstack.org/bobcat/highlights.html",children:"OpenStack 2023.2 (Bobcat)"})}),"\n",(0,t.jsxs)(s.li,{children:["Default Ceph version is ",(0,t.jsx)(s.a,{href:"https://docs.ceph.com/en/reef/releases/quincy/#v17-2-5-quincy",children:"Ceph Quincy"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://docs.ceph.com/en/latest/releases/reef/",children:"Ceph Reef"})," is included as a technical preview"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://www.openvswitch.org",children:"OVS"})," and ",(0,t.jsx)(s.a,{href:"https://www.ovn.org/en/",children:"OVN"})," have been updated and switched to LTS versions","\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://mail.openvswitch.org/pipermail/ovs-announce/2024-February/000343.html",children:"OVS 3.3.0"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://mail.openvswitch.org/pipermail/ovs-announce/2024-March/000344.html",children:"OVN 24.03.1"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"kaas",children:"KaaS"}),"\n",(0,t.jsx)(s.p,{children:"On the KaaS level, the development of the Cluster Stacks as KaaS V2 has reached a state where the approach is finally usable. With Cluster Stacks it is possible to bundle all components of Kubernetes clusters, i.e. node images, Kubernetes configuration, and cluster addons (core applications necessary to use a Kubernetes cluster) together and use the bundles to create and update clusters with one simple command."}),"\n",(0,t.jsx)(s.p,{children:"One bundle, a Cluster Stack, can be tested extensively and is only released if both creating and upgrading clusters works smoothly. Users of these Cluster Stacks profit from the Cluster Stack Operator that works alongside with Cluster API to create and update ready-to-use clusters easily."}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"k8s-cluster-api-provider"})," (KaaS v1)","\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"Moved to OpenTofu"}),"\n",(0,t.jsx)(s.li,{children:"Migrated to ClusterClass (last not least to ease the migration to Cluster Stacks)"}),"\n",(0,t.jsx)(s.li,{children:"HTTP_Proxy configurable"}),"\n",(0,t.jsx)(s.li,{children:"OVN LB"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks",children:"Cluster Stacks"})," (KaaS v2)","\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"First Cluster Stacks for OpenStack build"}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/",children:"Cluster Stack Operator"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"core component to manage Cluster Stack releases"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-provider-openstack",children:"Cluster Stack Provider OpenStack"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"manages node image release for OpenStack"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/csctl",children:"csctl"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"builds Cluster Stacks assets"}),"\n",(0,t.jsx)(s.li,{children:"builds node images"}),"\n",(0,t.jsx)(s.li,{children:"tests Cluster Stacks"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"operations",children:"Operations"}),"\n",(0,t.jsx)(s.h4,{id:"observability",children:"Observability"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-observability",children:"Observability stack reference implementation"})," is based on ",(0,t.jsx)(s.a,{href:"https://github.com/dNationCloud/kubernetes-monitoring-stack",children:"dNation Kubernetes monitoring stack v3.5.0"}),"\nand delivers the following components:"]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["Monitoring of ",(0,t.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/monitoring/docs/overview",children:"infrastructure services"})," such as Kubernetes clusters, physical or virtual machines, and infrastructure endpoints"]}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/monitoring/docs/zuul",children:"Zuul CI monitoring"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/monitoring/docs/alertmanager",children:"Matrix chat notifications"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/monitoring/docs/oauth",children:"OAUTH authentication"})}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/monitoring/docs/iaas",children:"IaaS monitoring"})," is included as a technical preview"]}),"\n"]}),"\n",(0,t.jsx)(s.h4,{id:"zuul",children:"Zuul"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"Created a development deployment for advancement testing."}),"\n",(0,t.jsx)(s.li,{children:"Simplified the installation requirements."}),"\n",(0,t.jsx)(s.li,{children:"Updated the Zuul repository's README file to include complete installation instructions for Terraform an Ansible."}),"\n",(0,t.jsx)(s.li,{children:"Added the clouds data into the ansible vault."}),"\n",(0,t.jsx)(s.li,{children:"Created an independent ansible Zuul role."}),"\n",(0,t.jsx)(s.li,{children:"Moved the custom Zuul tasks from the playbook and incorporated them into the role."}),"\n",(0,t.jsx)(s.li,{children:"Moved the custom Zuul variables from the playbook into the role's variables."}),"\n",(0,t.jsx)(s.li,{children:"Included the installation of Letsencrypt which adds certificates as part of the installation."}),"\n",(0,t.jsx)(s.li,{children:"Added a volume on the VM for the MariaDB instance to use for continuity."}),"\n",(0,t.jsx)(s.li,{children:"Added volumes on the VM for Zookeeper to use for the data snapshots and datalog."}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"iam",children:"IAM"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"Updated Keycloak image to 23.0.6."}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://registry.scs.community/harbor/projects/22/repositories/scs-keycloak/artifacts-tab",children:"Custom SCS-Keycloak image"})," now includes the ",(0,t.jsx)(s.a,{href:"https://github.com/sventorben/keycloak-home-idp-discovery",children:"Home-IdP-discovery"})," plugin."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"new-features-highlights",children:"New Features (Highlights)"}),"\n",(0,t.jsx)(s.h3,{id:"operator-focused-improvements",children:"Operator focused improvements"}),"\n",(0,t.jsxs)(s.p,{children:["A Kubernetes engine, via ",(0,t.jsx)(s.a,{href:"https://k3s.io",children:"k3s"}),", has been introduced to the control plane of the IaaS reference\nimplementation."]}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.code,{children:"osism"})," now deploys Keycloak to k3s via ",(0,t.jsx)(s.a,{href:"https://github.com/codecentric/helm-charts/blob/master/charts/keycloakx/README.md",children:"codecentric/keycloakx"})," helm chart and ",(0,t.jsx)(s.a,{href:"https://github.com/cloudnative-pg/charts",children:"CloudNativePG"})," operator."]}),"\n",(0,t.jsxs)(s.p,{children:["Rotation of the Octavia Amphora images has been added to the ",(0,t.jsx)(s.code,{children:"osism"})," command. ",(0,t.jsx)(s.code,{children:"osism manage image octavia"})," will rotate\nthe image, which is rebuilt on a daily basis."]}),"\n",(0,t.jsx)(s.h4,{id:"openstack-health-monitor",children:"OpenStack Health Monitor"}),"\n",(0,t.jsxs)(s.p,{children:["A new monitoring stack will replace the old\n",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/",children:"openstack-health-monitor"}),".\nNevertheless, it is currently still in heavy use and has thus seen a few improvements\nresponding to challenges observed in real-life clouds:"]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["A new ",(0,t.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install",children:"installation guide"})]}),"\n",(0,t.jsx)(s.li,{children:"Robustness against leaking volumes even with overloaded cinder API"}),"\n",(0,t.jsx)(s.li,{children:"Robustness against leaking ports from OVN LB health-monitor"}),"\n",(0,t.jsx)(s.li,{children:"Robustness against leftover keypairs"}),"\n",(0,t.jsx)(s.li,{children:"Avoid some followup errors when VM creation failed"}),"\n",(0,t.jsxs)(s.li,{children:["Add logic to startup os-health-mon in tmux windows via ",(0,t.jsx)(s.code,{children:"systemctl --user"})]}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",children:"SCS Developer focused improvements (testbed and k8s cluster management)"}),"\n",(0,t.jsx)(s.h4,{id:"kaas-1",children:"KaaS"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"Every component of Cluster Stacks brings a Tilt environment for local test and development"}),"\n",(0,t.jsx)(s.li,{children:"With csctl Cluster Stacks assets can be created and tested locally without uploading to GitHub"}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"preview-domain-manager-persona",children:"Preview: Domain Manager Persona"}),"\n",(0,t.jsxs)(s.p,{children:["A Domain Manager role has been established in a ",(0,t.jsx)(s.a,{href:"https://docs.scs.community/standards/scs-0302-v1-domain-manager-role",children:"standard draft in SCS"})," aiming to allow self-service capabilities for customers at the identity API.\nWork is in progress to ",(0,t.jsx)(s.a,{href:"https://bugs.launchpad.net/keystone/+bug/2045974",children:"contribute this functionality to OpenStack Keystone"})," and the corresponding ",(0,t.jsx)(s.a,{href:"https://review.opendev.org/c/openstack/keystone-specs/+/903172",children:"upstream spec"})," is currently under review.\nThe feature is expected to be available in the next SCS release."]}),"\n",(0,t.jsx)(s.h3,{id:"preview-central-api",children:"Preview: Central API"}),"\n",(0,t.jsxs)(s.p,{children:['To improve the experience of SCS cloud customers, the idea of a "Central API" was discussed. Such API should enable customers to manage various "as-a-Service" resources. For example: OpenStack instances as well as Kubernetes clusters as well as Keycloak OAuth2 clients.\nRead about the trade-offs and ideas in the ',(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/central-api",children:"central-api repository"})," and feel free to test out the ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/central-api/blob/0422e8ca24667b04b7364ffa461f85c3de51a50a/poc-setup.md",children:"POC"}),"."]}),"\n",(0,t.jsx)(s.h3,{id:"preview-keycloak-home-idp-discovery",children:"Preview: Keycloak Home-IdP-discovery"}),"\n",(0,t.jsxs)(s.p,{children:["To improve flexibility of onboarding new customer domains via IdP federation, SCS now deploys Keycloak with the ",(0,t.jsx)(s.a,{href:"https://github.com/sventorben/keycloak-home-idp-discovery",children:"Home-IdP-discovery"}),' plugin. The idea is, that Keystone federates out to a single Keycloak "proxy" realm (called ',(0,t.jsx)(s.code,{children:"osism"}),' in the testbed) and using the plugin, Keycloak can identify the user specific realm from an email-format login-ID. Operators can create dedicated realms for each customer and Keycloak uses internal federation to redirect from the "proxy" realm to the specific customer realm. In the customer ream they can configure IdP federation (OpenID-Connect or SAML) to their own IAM solution. The ',(0,t.jsx)(s.a,{href:"https://docs.scs.community/docs/iam",children:"IAM section"})," of the SCS documentation shall be extended to detail the configuration. SCS is working upstream to contribute required enhancements in the\nmapping of users, groups and roles from OpenID-Connect token claims to the OpenStack Keystone access management."]}),"\n",(0,t.jsx)(s.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["For the IaaS reference implementation, please refer to the ",(0,t.jsx)(s.a,{href:"https://osism.tech/docs/release-notes/osism-7#upgrade-notes",children:"OSISM 7.0.0 Upgrade Notes"}),"."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"removals",children:"Removals"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["Please check the removals for OSISM in the ",(0,t.jsx)(s.a,{href:"https://osism.tech/docs/release-notes/osism-7#removals--deprecations",children:"upstream removal notices"}),"."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"KaaSv1 is still provided with R6, but we do not intend to include it in R7 again.\nWe want to rather focus on the feature completeness of the much more future-proof\ncluster-stacks."}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["In upstream OSISM the role for deploying the Tang service (",(0,t.jsx)(s.code,{children:"osism.services.tang"}),") has been deprecated.\nWe would like to encourage active contributions in this area via the deprecation, since this piece of\ncode is currently not actively maintained nor -- to our knowledge -- actively used."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,t.jsx)(s.p,{children:"During the R6 development cycle a few security issues were reported and we issued security\nadvisories and addressed them via maintenance updates. All of these issues are also fixed\nin the upcoming R6 release. These include:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["A ",(0,t.jsx)(s.a,{href:"https://scs.community/de/security/2024/02/20/cve-2023-3966/",children:"OvS vulnerability with crafted Geneve packets and HW acceleration"})]}),"\n",(0,t.jsxs)(s.li,{children:["A ",(0,t.jsx)(s.a,{href:"https://scs.community/de/security/2024/03/15/cve-2024-2182/",children:"OVN vulnerability against specific BFD packets"})]}),"\n"]}),"\n",(0,t.jsx)(s.p,{children:"Other security topics were covered in our community blog as well:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://scs.community/2024/01/03/intel-amd-cpu-vulns/",children:"Delving into the Technical Depths of Intel-SA-00950 and AMD Cachewarp Vulnerabilities"})}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"security-assessment-for-iaas",children:"Security assessment for IaaS"}),"\n",(0,t.jsx)(s.p,{children:"We invested in a range of penetration tests of the IaaS layer which resulted in valuable insight in possible improvements (e.g. applying hardening measures):"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"External pentesting of components (scanning, blackbox testing)"}),"\n",(0,t.jsx)(s.li,{children:"Internal pentesting of components with privileged and unprivileged system users (scanning from inside the cluster)"}),"\n",(0,t.jsx)(s.li,{children:"Scanning and pentesting the environment from a customer workload machine"}),"\n"]}),"\n",(0,t.jsxs)(s.p,{children:["The vision of SCS is to have continuous security assurance by adding security checks and pentesting tooling\nto our CI pipelines; this is currently in implementation. Next step will then be to also cover other parts\n(beyond the IaaS layer) of our stack with manual and then\n",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/security-infra-scan-pipeline",children:"automated penetration testing"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"resolved-issues",children:"Resolved Issues"}),"\n",(0,t.jsx)(s.h3,{id:"preview-proper-scope-filtering-for-domain-list-api",children:"Preview: proper scope filtering for domain list API"}),"\n",(0,t.jsxs)(s.p,{children:["A fix to a bug where listing domains via Keystone API would return domains not intended to be visible to the requesting entity was ",(0,t.jsx)(s.a,{href:"https://bugs.launchpad.net/keystone/+bug/2041611",children:"contributed and merged upstream"}),".\nThe fix is expected to be available by the next SCS release."]}),"\n",(0,t.jsx)(s.h2,{id:"documentation",children:"Documentation"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"https://docs.scs.commnutiy/",children:"docs page"})," has come a long way in the last 6 months.\nIt pulls in a lot more content from the various projects and structures it in a much\nmore accessible way. Look at the ",(0,t.jsx)(s.a,{href:"https://docs.scs.community/standards",children:"standards"})," pages\nthere to get an impression."]}),"\n",(0,t.jsx)(s.h3,{id:"highlighted-blog-posts",children:"Highlighted blog posts"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["Oct'23: ",(0,t.jsx)(s.a,{href:"https://scs.community/2023/10/19/progress-openstack-cli-with-federation/",children:"Progress: OpenStack API access with OpenID Connect in Sovereign Cloud Stack"})]}),"\n",(0,t.jsxs)(s.li,{children:["Nov'23: ",(0,t.jsx)(s.a,{href:"https://scs.community/tech/2023/11/21/confidential-computing-in-digital-sovereign-environments/",children:"Confidential Computing in digital sovereign environments"})]}),"\n",(0,t.jsxs)(s.li,{children:["Dec'23: ",(0,t.jsx)(s.a,{href:"https://scs.community/tech/2023/12/06/mvp-monitoring/",children:"SCS observability and monitoring - An opinionated proposal"})]}),"\n",(0,t.jsxs)(s.li,{children:["Dec'23: ",(0,t.jsx)(s.a,{href:"https://scs.community/2023/12/23/clusterstacks/",children:"Cluster Stacks"})]}),"\n",(0,t.jsxs)(s.li,{children:["Feb'24: ",(0,t.jsx)(s.a,{href:"https://scs.community/2024/02/09/sdn-scalability/",children:"SDN scalability improvements"})]}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"iam-1",children:"IAM"}),"\n",(0,t.jsxs)(s.p,{children:["The documentation now contains an ",(0,t.jsx)(s.a,{href:"https://docs.scs.community/docs/iam",children:"IAM overview document"})," which explains current\nlimitations for the dynamic mapping of user roles and shall be extended to explain configuration options for Operators."]}),"\n",(0,t.jsx)(s.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,t.jsxs)(s.p,{children:["The standards have evolved, increasing the amount of guarantees that software developers\nand operators have for workloads that work across SCS-compatible clouds.\nThe ",(0,t.jsx)(s.a,{href:"https://docs.scs.community/standards/scs-compatible-iaas",children:"SCS-compatible IaaS-v4"}),"\nhas seen improvements and better test coverage; the OSISM IaaS reference implementation\nfulfills all of these standards in the default configuration."]}),"\n",(0,t.jsxs)(s.p,{children:["For the Kubernetes layer, we have our first set of standards almost finalized.\nSome of the standards for ",(0,t.jsx)(s.a,{href:"https://docs.scs.community/standards/scs-compatible-kaas",children:"SCS-compatible KaaS-v1"}),"\nare unfortunately hard to test, so we are working on adding some more tests before\nwe cut it in stone. We aim for both KaaSv1 and v2 to fulfill the standards.\n(Future standards will likely not be fulfilled by KaaSv1 as it's being deprecated.)"]}),"\n",(0,t.jsx)(s.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,t.jsxs)(s.p,{children:["A number of repositories follow OSISM's example and use the ",(0,t.jsx)(s.code,{children:"7.0.0"})," or ",(0,t.jsx)(s.code,{children:"v7.0.0"})," tag\nto denote SCS Release 6."]}),"\n",(0,t.jsx)(s.h2,{id:"list-of-known-issues--restrictions-in-r6",children:"List of known issues & restrictions in R6"}),"\n",(0,t.jsx)(s.h3,{id:"iaas-1",children:"IaaS"}),"\n",(0,t.jsx)(s.h4,{id:"loadbalancer-service-octavia",children:"Loadbalancer service (octavia)"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["Creating loadbalancers in Cloud-in-a-Box installations fails with the\nerror message that the VIP subnet does not exist. ",(0,t.jsx)(s.a,{href:"https://github.com/osism/issues/issues/890",children:"OSISM #890"})]}),"\n",(0,t.jsxs)(s.li,{children:["When using ",(0,t.jsx)(s.code,{children:"--provider ovn"})," with a loadbalancer health-monitor, we leak ports ",(0,t.jsx)(s.code,{children:"ovn-lb-hm-$SUBNETID"})," in all\nbut the VIP subnet, if we clean up the LB members before the health-monitor. This is tracked as\n",(0,t.jsx)(s.a,{href:"https://github.com/osism/issues/issues/921",children:"OSISM issue #921"}),". Deleting the health-monitor before the\nmembers or using ",(0,t.jsx)(s.code,{children:"openstack loadbalancer delete --cascade"})," avoids this issue."]}),"\n",(0,t.jsxs)(s.li,{children:["With amphora loadbalancers, we can end up in situations that LB deletion does no longer work due to\na failover or a failed creation of the vrrp port. This is tracked in\n",(0,t.jsx)(s.a,{href:"https://github.com/osism/issues/issues/925",children:"OSISM issue #925"}),". An upstream fix exists and a backport\nis already underway."]}),"\n"]}),"\n",(0,t.jsx)(s.p,{children:"We expect to resolve these issues with a maintenance update."}),"\n",(0,t.jsx)(s.h3,{id:"kaas-2",children:"KaaS"}),"\n",(0,t.jsx)(s.p,{children:"Some features of KaaS v1 are not available yet in KaaS v2 because they are WIP in upstream CAPO.\nThis includes the creation of some of the optional components such as e.g. the deployment\nof ingress service, cert-manager, flux, harbor. More importantly, we do not yet have the\nhandling of restrictive security groups implemented nor the ability to avoid OpenStack\nscheduling more than one control plane node on the same host (hypervisor)."}),"\n",(0,t.jsx)(s.p,{children:"For this reason, we are including KaaS v1 (k8s-cluster-api-provider) in the R6 release,\nso existing users can upgrade to the latest upstream code and continuing using it as\na maintained solution while they evaluate the migration to KaaS v2 (cluster-stacks)."}),"\n",(0,t.jsx)(s.p,{children:"We will address most of the gaps during the next release cycle."}),"\n",(0,t.jsx)(s.p,{children:"KaaS v1 should not be used for new deployments; we intend to remove it with the next\nrelease (R7)."}),"\n",(0,t.jsx)(s.h3,{id:"iam-2",children:"IAM"}),"\n",(0,t.jsx)(s.p,{children:"Since Keycloak is a Java application it requires importing certificates into its certificate store.\nAs the Keycloak pod in k3s now runs the service as non-root user, it gets more challenging to import\ncustom certificates from arbitrary customers for IdP federation. In case this topic is interesting for\nspecific deployments, the SCS project team would like to hear from users and discuss how to best\nexpose such a capability."}),"\n",(0,t.jsx)(s.h2,{id:"contributing",children:"Contributing"}),"\n",(0,t.jsxs)(s.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,t.jsx)(s.a,{href:"https://scs.community/contribute/",children:"How to contribute page"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"thanks",children:"Thanks"}),"\n",(0,t.jsx)(s.p,{children:"We have had considerable help from many partners and upstream projects during\nthe R6 development cycle. We continue to be grateful for the generous support\nfrom providers that support with infrastructure that we can use for testing and\ndevelopment. plusserver has been particularly generous and also helped us\nfinding a few issues during the pre-release phase by upgrading test\nenvironments and testing them."})]})}function h(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>o});var i=n(96540);const t={},a=i.createContext(t);function r(e){const s=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2ce1dccd.7c208000.js b/assets/js/2ce1dccd.7c208000.js new file mode 100644 index 0000000000..c4f7cf8c58 --- /dev/null +++ b/assets/js/2ce1dccd.7c208000.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[91026],{58840:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"iaas/components/image-manager/index","title":"Image Manager","description":"The OpenStack Image Manager is a tool for managing all","source":"@site/docs/02-iaas/components/image-manager/index.md","sourceDirName":"02-iaas/components/image-manager","slug":"/iaas/components/image-manager/","permalink":"/docs/iaas/components/image-manager/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/image-manager/index.md","tags":[],"version":"current","sidebarPosition":50,"frontMatter":{"sidebar_label":"Image Manager","sidebar_position":50},"sidebar":"docs","previous":{"title":"Components","permalink":"/docs/category/components"},"next":{"title":"Automated updates","permalink":"/docs/iaas/components/image-manager/update"}}');var a=i(74848),t=i(28453);const r={sidebar_label:"Image Manager",sidebar_position:50},o="Image Manager",l={},c=[{value:"Requirements",id:"requirements",level:2},{value:"OpenStack Image Service (Glance)",id:"openstack-image-service-glance",level:3},{value:"Object storage backend",id:"object-storage-backend",level:3},{value:"Getting started",id:"getting-started",level:2},{value:"Image definitions",id:"image-definitions",level:2},{value:"SCS image standard",id:"scs-image-standard",level:3},{value:"Image with regular rebuilds",id:"image-with-regular-rebuilds",level:3},{value:"Image without regular rebuild",id:"image-without-regular-rebuild",level:3},{value:"Other properties",id:"other-properties",level:3},{value:"Image properties",id:"image-properties",level:4},{value:"Image tags",id:"image-tags",level:4},{value:"image status",id:"image-status",level:4},{value:"Image visibility",id:"image-visibility",level:4},{value:"Usage",id:"usage",level:2},{value:"Mirroring images",id:"mirroring-images",level:3},{value:"Updating images",id:"updating-images",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"image-manager",children:"Image Manager"})}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.a,{href:"https://pypi.org/project/openstack-image-manager/",children:"OpenStack Image Manager"})," is a tool for managing all\nimages on an OpenStack environment"]}),"\n",(0,a.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,a.jsx)(n.p,{children:"This information is only relevant for the operator of an OpenStack environment. You can skip this section if\nyou want to use OpenStack Image Manager as a normal user and you are not an operator of an openStack environment."}),"\n",(0,a.jsx)(n.h3,{id:"openstack-image-service-glance",children:"OpenStack Image Service (Glance)"}),"\n",(0,a.jsx)(n.p,{children:"The OpenStack Image Service (Glance) is required to upload and discover data assets that are used by other\nservices."}),"\n",(0,a.jsx)(n.p,{children:"Since this script stores many images in a single project, the Glance quota must be set accordingly high or to unlimited."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ini",children:"[DEFAULT]\nuser_storage_quota = 1TB\n"})}),"\n",(0,a.jsxs)(n.p,{children:["With most storage backends it makes sense to convert the imported images directly to RAW. So it is required for using Ceph and it's\nfeatures too. Recited from the Ceph documentation ",(0,a.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rbd/qemu-rbd/",children:"QEMU and block devices"})," and\n",(0,a.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rbd/rbd-openstack/",children:"Block devices and OpenStack"}),"."]}),"\n",(0,a.jsxs)(n.admonition,{type:"info",children:[(0,a.jsx)(n.p,{children:"The raw data format is really the only sensible format option to use with RBD. Technically, you could use other QEMU-supported formats\n(such as qcow2 or vmdk), but doing so would add additional overhead, and would also render the volume unsafe for virtual machine live\nmigration when caching (see below) is enabled."}),(0,a.jsx)(n.p,{children:"Important Ceph doesn't support QCOW2 for hosting a virtual machine disk. Thus if you want to boot virtual machines in Ceph (ephemeral\nbackend or boot from volume), the Glance image format must be RAW."}),(0,a.jsxs)(n.p,{children:["See the ",(0,a.jsx)(n.a,{href:"https://docs.openstack.org/glance/latest/configuration/sample-configuration.html",children:"OpenStack Glance documentation"}),"\nfor more details."]})]}),"\n",(0,a.jsx)(n.p,{children:"This requires the following parameter for the image import workflow."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ini",children:"[taskflow_executor]\nconversion_format = raw\n\n[image_import_opts]\nimage_import_plugins = ['image_decompression', 'image_conversion']\n\n[image_conversion]\noutput_format = raw\n"})}),"\n",(0,a.jsx)(n.h3,{id:"object-storage-backend",children:"Object storage backend"}),"\n",(0,a.jsx)(n.p,{children:"If the mirror functionality is used, an object storage backend is required. The use of the mirror functionality\nis optional and is not used by default."}),"\n",(0,a.jsx)(n.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,a.jsxs)(n.p,{children:["This ",(0,a.jsx)(n.strong,{children:"Getting started"})," will upload a private image to your OpenStack environment with\nthe help of the OpenStack Image Manager."]}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Install the ",(0,a.jsx)(n.a,{href:"https://pypi.org/project/openstack-image-manager/",children:"openstack-image-manager"})," package with\n",(0,a.jsx)(n.a,{href:"https://pypi.org/project/pip/",children:"pip"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"pip3 install openstack-image-manager\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The installation can also be done via ",(0,a.jsx)(n.a,{href:"https://pypi.org/project/pipenv/",children:"pipenv"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["A ",(0,a.jsx)(n.code,{children:"Pipefile"})," file is created with this content. The ",(0,a.jsx)(n.a,{href:"https://pypi.org/project/openstack-image-manager/#history",children:"latest version of openstack-image-manager"}),"\nis used."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ini",children:'[[source]]\nurl = "https://pypi.org/simple"\nverify_ssl = true\nname = "pypi"\n\n[packages]\nopenstack-image-manager = "==0.20240403.0"\n\n[dev-packages]\n\n[requires]\npython_version = "3.10"\n'})}),"\n",(0,a.jsx)(n.p,{children:"The dependencies are then installed and the shell is prepared for use:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"pipenv install\npipenv shell\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Create a image definition in the file ",(0,a.jsx)(n.code,{children:"getting-started.yml"})," in the local directory ",(0,a.jsx)(n.code,{children:"images"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"---\nimages:\n - name: MyCirros\n enable: true\n format: qcow2\n login: cirros\n password: gocubsgo\n min_disk: 1\n min_ram: 32\n status: active\n visibility: private\n multi: false\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_rng_model: virtio\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n hypervisor_type: qemu\n os_distro: cirros\n replace_frequency: never\n uuid_validity: none\n provided_until: none\n tags: []\n versions:\n - version: '0.6.2'\n url: https://github.com/cirros-dev/cirros/releases/download/0.6.2/cirros-0.6.2-x86_64-disk.img\n checksum: \"sha256:07e44a73e54c94d988028515403c1ed762055e01b83a767edf3c2b387f78ce00\"\n build_date: 2023-05-30\n - version: '0.6.3'\n url: https://github.com/cirros-dev/cirros/releases/download/0.6.3/cirros-0.6.3-x86_64-disk.img\n checksum: \"sha256:7d6355852aeb6dbcd191bcda7cd74f1536cfe5cbf8a10495a7283a8396e4b75b\"\n build_date: 2024-09-26\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Run the OpenStack Image Manager. It is assumed that a profile with the name ",(0,a.jsx)(n.code,{children:"openstack"})," exists in the\n",(0,a.jsx)(n.a,{href:"https://docs.openstack.org/python-openstackclient/latest/configuration/index.html#configuration-files",children:"clouds.yaml"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'openstack-image-manager --cloud openstack --filter ".*Cirr.*" --images images/\n'})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"image-definitions",children:"Image definitions"}),"\n",(0,a.jsxs)(n.p,{children:["The configuration consists of different parameter settings, such as values for\nminimum RAM or the visibility of the image. Have a look at the examples below\nfor all parameters. After a change to the configuration, validate it with\n",(0,a.jsx)(n.code,{children:"tox -- --dry-run"}),"."]}),"\n",(0,a.jsx)(n.h3,{id:"scs-image-standard",children:"SCS image standard"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["The value of ",(0,a.jsx)(n.code,{children:"login"})," is stored as ",(0,a.jsx)(n.code,{children:"image_original_user"})," in the metadata of an image."]}),"\n",(0,a.jsxs)(n.li,{children:["If ",(0,a.jsx)(n.code,{children:"image_description"})," is not set as meta information, ",(0,a.jsx)(n.code,{children:"image_description"})," is set to the name of the image."]}),"\n",(0,a.jsxs)(n.li,{children:["The value of ",(0,a.jsx)(n.code,{children:"build_date"})," of a specific version of an image is stored as ",(0,a.jsx)(n.code,{children:"image_build_date"})," in the metadata of an image."]}),"\n",(0,a.jsxs)(n.li,{children:["The value of ",(0,a.jsx)(n.code,{children:"url"})," of a specific version of an image is stored as ",(0,a.jsx)(n.code,{children:"image_source"})," in the metadata of an image."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"image-with-regular-rebuilds",children:"Image with regular rebuilds"}),"\n",(0,a.jsx)(n.p,{children:"This type of image definition is used for images that are rebuilt at regular\nintervals. For example, this is the case for the daily builds of the Ubuntu\nimages."}),"\n",(0,a.jsxs)(n.p,{children:["The attribute ",(0,a.jsx)(n.code,{children:"multi: true"})," is set."]}),"\n",(0,a.jsxs)(n.p,{children:["With this type of image definition, the version of the distribution (or product,\nwhatever is contained in the image) used is already in the name of the image\ndefinition. The ",(0,a.jsx)(n.code,{children:"version"})," properties from the definition's ",(0,a.jsx)(n.code,{children:"versions"})," list\nare appended only to older iterations of the image as timestamp suffixes\nin parentheses upon each rotation (except for the latest entry)."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"images:\n - name: Ubuntu 24.04\n format: qcow2\n login: ubuntu\n min_disk: 8\n min_ram: 512\n status: active\n visibility: public\n multi: true\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n os_distro: ubuntu\n os_version: '24.04'\n tags: []\n versions:\n - version: '20240416'\n url: https://cloud-images.ubuntu.com/noble/20240416/noble-server-cloudimg-amd64.img\n - version: '20240422'\n url: https://cloud-images.ubuntu.com/noble/20240422/noble-server-cloudimg-amd64.img\n"})}),"\n",(0,a.jsx)(n.p,{children:"This configuration creates the following images:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.strong,{children:"Ubuntu 24.04 (20240416)"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.strong,{children:"Ubuntu 24.04"})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"If a newer build is added, the following rotation takes place:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Ubuntu 24.04 (20240416)"})," does not change"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Ubuntu 24.04"})," becomes ",(0,a.jsx)(n.strong,{children:"Ubuntu 24.04 (20240422)"})]}),"\n",(0,a.jsxs)(n.li,{children:["the new image becomes ",(0,a.jsx)(n.strong,{children:"Ubuntu 24.04"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["By default the last three images will be visible. When a fourth image is added, the visibility of\nthe last image in the list is changed to ",(0,a.jsx)(n.code,{children:"community"})," and the image can be deleted in the future."]}),"\n",(0,a.jsx)(n.h3,{id:"image-without-regular-rebuild",children:"Image without regular rebuild"}),"\n",(0,a.jsx)(n.p,{children:"This type of image definition is used for images that are not rebuilt. For example,\nthis is the case for the flatcar images. For each release of Flatcar there is exactly\none image which will not be rebuilt in the future."}),"\n",(0,a.jsxs)(n.p,{children:["The attribute ",(0,a.jsx)(n.code,{children:"multi: false"})," is set."]}),"\n",(0,a.jsxs)(n.p,{children:["With this type of image definition, the version of the distribution (or product,\nwhatever is contained in the image) used is not in the name of the image definition.\nInstead, the ",(0,a.jsx)(n.code,{children:"version"})," properties from the image definition's ",(0,a.jsx)(n.code,{children:"versions"})," list\nare appended as static version suffixes to the images' names."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"images:\n - name: RancherOS\n format: qcow2\n login: rancher\n min_disk: 8\n min_ram: 2048\n status: active\n visibility: public\n multi: false\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n tags: []\n versions:\n - version: '1.3.0'\n url: https://github.com/rancher/os/releases/download/v1.3.0/rancheros-openstack.img\n - version: '1.4.0'\n url: https://github.com/rancher/os/releases/download/v1.4.0/rancheros-openstack.img\n - version: '1.4.1'\n url: https://github.com/rancher/os/releases/download/v1.4.1/rancheros-openstack.img\n"})}),"\n",(0,a.jsx)(n.p,{children:"This configuration creates the following images:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.strong,{children:"RancherOS 1.3.0"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.strong,{children:"RancherOS 1.4.0"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.strong,{children:"RancherOS 1.4.1"})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["If a new version is added, no rotation takes place. The new version is added\nas ",(0,a.jsx)(n.strong,{children:"RancherOS x.y.z"}),". Here also the visibility of older images is not changed."]}),"\n",(0,a.jsx)(n.h3,{id:"other-properties",children:"Other properties"}),"\n",(0,a.jsx)(n.h4,{id:"image-properties",children:"Image properties"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Removal of properties is not yet possible"}),"\n",(0,a.jsx)(n.li,{children:"URL, name and format can not be changed"}),"\n",(0,a.jsxs)(n.li,{children:["Any keys can be added to ",(0,a.jsx)(n.code,{children:"meta"}),", these will be added to the image"]}),"\n",(0,a.jsxs)(n.li,{children:["Existing keys in ",(0,a.jsx)(n.code,{children:"meta"})," can be changed, the same applies to ",(0,a.jsx)(n.code,{children:"min_disk"}),"\nand ",(0,a.jsx)(n.code,{children:"min_ram"})]}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"image-tags",children:"Image tags"}),"\n",(0,a.jsx)(n.h4,{id:"image-status",children:"image status"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["deactivation: change ",(0,a.jsx)(n.code,{children:"status"})," to ",(0,a.jsx)(n.code,{children:"deactivated"})]}),"\n",(0,a.jsxs)(n.li,{children:["reactivation: change ",(0,a.jsx)(n.code,{children:"status"})," to ",(0,a.jsx)(n.code,{children:"active"})]}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"image-visibility",children:"Image visibility"}),"\n",(0,a.jsxs)(n.p,{children:["A full documentation about the visibility of images can be found in the ",(0,a.jsx)(n.strong,{children:"Image visibility"})," section in the\n",(0,a.jsx)(n.a,{href:"https://docs.openstack.org/api-ref/image/v2/index.html#general-information",children:"OpenStack Image Service API Documentation"}),"."]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["public: set ",(0,a.jsx)(n.code,{children:"visibility"})," to ",(0,a.jsx)(n.code,{children:"public"})]}),"\n",(0,a.jsxs)(n.li,{children:["community: set ",(0,a.jsx)(n.code,{children:"visibility"})," to ",(0,a.jsx)(n.code,{children:"community"})]}),"\n",(0,a.jsxs)(n.li,{children:["shared: set ",(0,a.jsx)(n.code,{children:"visibility"})," to ",(0,a.jsx)(n.code,{children:"shared"})]}),"\n",(0,a.jsxs)(n.li,{children:["private: set ",(0,a.jsx)(n.code,{children:"visibility"})," to ",(0,a.jsx)(n.code,{children:"private"})]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,a.jsx)(n.h3,{id:"mirroring-images",children:"Mirroring images"}),"\n",(0,a.jsx)(n.p,{children:"Since the upstreams often only keep their images for a short time, we mirror most of the images on REGIO.cloud.\nThis makes us independent of the availability of the images in the individual upstreams."}),"\n",(0,a.jsx)(n.h3,{id:"updating-images",children:"Updating images"}),"\n",(0,a.jsxs)(n.p,{children:["Some of the images are automatically updated by a ",(0,a.jsx)(n.a,{href:"update",children:"CI job"}),". The latest available build at the time of the CI job execution is mirrored and\nmade available as the current version."]}),"\n",(0,a.jsx)(n.p,{children:"Currently, the following images are updated once a week (every Sunday at 0 am):"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Almalinux"}),"\n",(0,a.jsx)(n.li,{children:"CentOS"}),"\n",(0,a.jsx)(n.li,{children:"Debian"}),"\n",(0,a.jsx)(n.li,{children:"Rockylinux"}),"\n",(0,a.jsx)(n.li,{children:"Ubuntu"}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>o});var s=i(96540);const a={},t=s.createContext(a);function r(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2d071e49.e08425dd.js b/assets/js/2d071e49.e08425dd.js new file mode 100644 index 0000000000..83b6030980 --- /dev/null +++ b/assets/js/2d071e49.e08425dd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[60953],{70160:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"operating-scs/components/monitoring/docs/kaas","title":"KaaS monitoring (experimental)","description":"This component is marked as experimental, and it is not part of the reference SCS installation available","source":"@site/docs/04-operating-scs/components/monitoring/docs/kaas.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/kaas","permalink":"/docs/operating-scs/components/monitoring/docs/kaas","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/kaas.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"IaaS monitoring (experimental)","permalink":"/docs/operating-scs/components/monitoring/docs/iaas"},"next":{"title":"Zuul monitoring","permalink":"/docs/operating-scs/components/monitoring/docs/zuul"}}');var s=t(74848),i=t(28453);const r={},o="KaaS monitoring (experimental)",c={},l=[{value:"Enable KaaS layer monitoring",id:"enable-kaas-layer-monitoring",level:2},{value:"KaaS metric importer",id:"kaas-metric-importer",level:2},{value:"KaaS mock service",id:"kaas-mock-service",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"kaas-monitoring-experimental",children:"KaaS monitoring (experimental)"})}),"\n",(0,s.jsxs)(n.p,{children:["This component is marked as experimental, and it is not part of the reference SCS installation available\nat ",(0,s.jsx)(n.a,{href:"https://monitoring.scs.community",children:"https://monitoring.scs.community"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"enable-kaas-layer-monitoring",children:"Enable KaaS layer monitoring"}),"\n",(0,s.jsx)(n.p,{children:"TODO: Provide clear instructions on how to enable KaaS layer monitoring."}),"\n",(0,s.jsxs)(n.p,{children:["Please check out the ",(0,s.jsx)(n.code,{children:"mvp-0"})," tag and find the related comments on what needs to be done in the monitoring\nvalues to enable KaaS monitoring in your Observer cluster."]}),"\n",(0,s.jsx)(n.h2,{id:"kaas-metric-importer",children:"KaaS metric importer"}),"\n",(0,s.jsx)(n.p,{children:"To test the Monitoring of the KaaS layer use case, deploy the Kaas-metric-importer\ninto the Observer cluster."}),"\n",(0,s.jsx)(n.p,{children:"The Kaas-metric-importer is a simple service through which the KaaS software registers\nand unregisters newly created or deleted KaaS clusters in the Observer monitoring.\nThis functionality enables the Observer monitoring to differentiate between KaaS clusters deleted intentionally\nand those that have stopped writing metrics to the Observer monitoring for any reason."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f kaas/kaas-metric-importer.yaml\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The Kaas-metric-importer uses an image built from ",(0,s.jsx)(n.a,{href:"https://github.com/m3dbx/prometheus_remote_client_golang",children:"https://github.com/m3dbx/prometheus_remote_client_golang"}),".\nIt has mounted configmap and based on configmap keys it pushes custom metric ",(0,s.jsx)(n.code,{children:"kaas"}),"\nwith label ",(0,s.jsx)(n.code,{children:"cluster"})," and value ",(0,s.jsx)(n.code,{children:"1"})," into the thanos receiver."]}),"\n",(0,s.jsx)(n.p,{children:"Example of configmap:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'data:\n workload-cluster: ""\n'})}),"\n",(0,s.jsxs)(n.p,{children:["It pushes metric e.g. ",(0,s.jsx)(n.code,{children:'kaas{cluster="workload-cluster"} 1'})," to the Observer.\nIt is important to keep the configmap up-to-date with your KaaS offering. This is automated e.g.\nin the KaaS mock service below."]}),"\n",(0,s.jsx)(n.h2,{id:"kaas-mock-service",children:"KaaS mock service"}),"\n",(0,s.jsx)(n.p,{children:"To evaluate the Monitoring of the KaaS layer use case and view actual metrics in your\nObserver monitoring cluster, you can launch the KaaS mock service."}),"\n",(0,s.jsxs)(n.p,{children:["Put your Observer monitoring cluster kubeconfig into the ",(0,s.jsx)(n.code,{children:"./kaas/manifests/"})," directory and name\nit ",(0,s.jsx)(n.code,{children:"observer-kubeconfig.yaml"})," (or adjust kaas service ",(0,s.jsx)(n.code,{children:"./kaas/app/config.py"})," accordingly)."]}),"\n",(0,s.jsx)(n.p,{children:"If you're utilizing the KinD Observer deployment outlined in this tutorial, collect the kubeconfig using the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kind get kubeconfig --name observer > ./kaas/manifests/observer-kubeconfig.yaml\n"})}),"\n",(0,s.jsxs)(n.p,{children:["All KaaS mock service dependencies can be installed via the corresponding ",(0,s.jsx)(n.code,{children:"./kaas/requirements.txt"})," file.\nInstalling them into a Python virtualenv is recommended."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd kaas\npython3 -m venv .venv # Optional\nsource .venv/bin/activate # Optional\n# Install kaas dependencies\npip install -r requirements.txt\n\n# Launch the KaaS mock service\nmake kaas\n"})}),"\n",(0,s.jsx)(n.p,{children:"At this point, you should have the ability to access the KaaS mock service Swagger UI:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"http://127.0.0.1:8080/kaas\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Create KaaS cluster through Swagger UI: ",(0,s.jsx)(n.a,{href:"http://127.0.0.1:8080/kaas#/Clusters/create_cluster_api_clusters__post",children:"Create Cluster"})," or\ncall directly the KaaS service API via some client, e.g.:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'curl -X POST -H "Content-Type: application/json" http://127.0.0.1:8080/api/clusters/ -d \'{"name": "kaas"}\'\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Navigate to the ",(0,s.jsx)(n.a,{href:"http://localhost:30000/d/kaas-monitoring/kaas-monitoring",children:"KaaS Monitoring dashboard"}),"\nin the Observer monitoring. After a few minutes (approximately 4), your KaaS cluster should become visible.\nClick on the cluster box to dive into KaaS cluster dashboards at a more detailed level.\nRepeat the process to explore further and gain deeper insights."]}),"\n",(0,s.jsx)(n.p,{children:"Note: The disk utilization expression for the Docker environment has not been adjusted,\nso you will encounter non-realistic numbers in the nodes/disk sections. However,\nthe other sections should accurately reflect the reality."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Retrieve a list of all KaaS clusters and check their status. Swagger UI: ",(0,s.jsx)(n.a,{href:"http://127.0.0.1:8080/kaas#/Clusters/get_clusters_api_clusters__get",children:"Get List of Clusters"})," or\ncall directly the KaaS service API via some client, e.g.:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s -X GET -H 'accept: application/json' http://127.0.0.1:8080/api/clusters/\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Get Kaas Cluster kubeconfig by its name through Swagger UI: ",(0,s.jsx)(n.a,{href:"http://127.0.0.1:8080/kaas#/Clusters/get_kubeconfig_api_clusters__name__get",children:"Get Cluster kubeconfig"})," or\ncall directly the KaaS service API via some client and save it, e.g.:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s -X GET -H 'accept: application/json' http://127.0.0.1:8080/api/clusters/kaas > kaas-kube\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Now, you have the opportunity to play with your KaaS cluster and experiment with triggering\nmonitoring alerts by initiating actions like destroying certain components \ud83d\ude0e."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl --kubeconfig kaas-kube get po -A\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Finally, delete your KaaS cluster by its name through Swagger UI: ",(0,s.jsx)(n.a,{href:"http://127.0.0.1:8080/kaas#/Clusters/delete_cluster_api_clusters__delete",children:"Delete Cluster"})," or\ncall directly the KaaS service API via some client and save it, e.g.:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -X DELETE http://127.0.0.1:8080/api/clusters/?name=kaas\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2e505a53.791a4104.js b/assets/js/2e505a53.791a4104.js new file mode 100644 index 0000000000..deae41f297 --- /dev/null +++ b/assets/js/2e505a53.791a4104.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[79089],{53179:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Monitoring","slug":"/category/monitoring","permalink":"/docs/category/monitoring","sidebar":"docs","navigation":{"previous":{"title":"Contribute","permalink":"/docs/operating-scs/components/status-page-web/docs/contribute"},"next":{"title":"Overview","permalink":"/docs/operating-scs/components/monitoring/docs/overview"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/2ee7a08a.2d5ef364.js b/assets/js/2ee7a08a.2d5ef364.js new file mode 100644 index 0000000000..742a7acd64 --- /dev/null +++ b/assets/js/2ee7a08a.2d5ef364.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5658],{86628:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"iaas/guides/concept-guide/components/clusterapi","title":"Cluster API","description":"Kubernetes as a Service (KaaS) is a cloud service model that simplifies the deployment,","source":"@site/docs/02-iaas/guides/concept-guide/components/clusterapi.md","sourceDirName":"02-iaas/guides/concept-guide/components","slug":"/iaas/guides/concept-guide/components/clusterapi","permalink":"/docs/iaas/guides/concept-guide/components/clusterapi","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/clusterapi.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Ceph","permalink":"/docs/iaas/guides/concept-guide/components/ceph"},"next":{"title":"Gardener","permalink":"/docs/iaas/guides/concept-guide/components/gardener"}}');var i=t(74848),a=t(28453);const r={},o="Cluster API",c={},l=[{value:"Lifecycle Management of Cluster API in OSISM",id:"lifecycle-management-of-cluster-api-in-osism",level:2},{value:"Cluster API with OpenStack Magnum",id:"cluster-api-with-openstack-magnum",level:3},{value:"Cluster API with SCS Cluster Stacks",id:"cluster-api-with-scs-cluster-stacks",level:3}];function u(e){const n={h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"cluster-api",children:"Cluster API"})}),"\n",(0,i.jsx)(n.p,{children:"Kubernetes as a Service (KaaS) is a cloud service model that simplifies the deployment,\nmanagement and scaling of Kubernetes clusters. By abstracting the underlying infrastructure,\nKaaS allows organisations to focus on developing and deploying applications without the\ncomplexities of cluster management. One of the most powerful tools for implementing KaaS\nis the Cluster API, an official Kubernetes project that provides declarative APIs and tools\nfor managing the lifecycle of Kubernetes clusters."}),"\n",(0,i.jsx)(n.p,{children:"Key benefits of Cluster API include:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Declarative Cluster Management: Cluster API allows users to define the desired state of\nclusters using YAML manifests. This declarative approach simplifies the process of creating,\nupdating, and deleting clusters, making it easier to automate and version control cluster\nconfigurations."}),"\n",(0,i.jsx)(n.li,{children:"Infrastructure Abstraction: Cluster API abstracts the underlying infrastructure, enabling\nthe deployment of Kubernetes clusters across various environments, including public clouds\n(AWS, Azure, GCP), private clouds (OpenStack), and on-premises data centers. This abstraction\nensures that the same API can be used regardless of the infrastructure provider."}),"\n",(0,i.jsx)(n.li,{children:"Consistent Lifecycle Management: Cluster API standardizes the lifecycle management of\nKubernetes clusters, including provisioning, scaling, upgrading, and deletion. This consistency\nreduces operational overhead and ensures that clusters are managed uniformly across different\nenvironments."}),"\n",(0,i.jsx)(n.li,{children:"Extensibility and Customization: Cluster API\u2019s modular architecture allows for extensibility\nthrough the use of custom resource definitions (CRDs) and controllers. Organizations can tailor\nthe API to meet specific requirements, such as integrating with existing CI/CD pipelines or\nadding custom operational logic."}),"\n",(0,i.jsx)(n.li,{children:"Improved Operational Efficiency: By leveraging Cluster API, organizations can automate repetitive\ntasks, reduce human error, and ensure that clusters are configured according to best practices.\nThis automation leads to increased operational efficiency and faster delivery of applications."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"By using Kubernetes as a Service with Cluster API, organisations can achieve a highly automated,\nscalable and consistent approach to managing Kubernetes clusters across different environments.\nThis allows them to focus more on application development, and less on the operational\ncomplexities of managing Kubernetes infrastructure."}),"\n",(0,i.jsx)(n.h2,{id:"lifecycle-management-of-cluster-api-in-osism",children:"Lifecycle Management of Cluster API in OSISM"}),"\n",(0,i.jsx)(n.h3,{id:"cluster-api-with-openstack-magnum",children:"Cluster API with OpenStack Magnum"}),"\n",(0,i.jsx)(n.h3,{id:"cluster-api-with-scs-cluster-stacks",children:"Cluster API with SCS Cluster Stacks"})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var s=t(96540);const i={},a=s.createContext(i);function r(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2f1a0bb3.710e4e6d.js b/assets/js/2f1a0bb3.710e4e6d.js new file mode 100644 index 0000000000..c27f085d4c --- /dev/null +++ b/assets/js/2f1a0bb3.710e4e6d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[16594],{78706:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Metering","slug":"/category/metering","permalink":"/docs/category/metering","sidebar":"docs","navigation":{"previous":{"title":"Guide: Setting up openstack-health-monitor on Debian 12","permalink":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install"},"next":{"title":"Metering Configuration","permalink":"/docs/operating-scs/metering/meter_configuration"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/310c7ee8.ba4abbd3.js b/assets/js/310c7ee8.ba4abbd3.js new file mode 100644 index 0000000000..6f68737f1e --- /dev/null +++ b/assets/js/310c7ee8.ba4abbd3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[80295],{49322:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>p,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"scs-0210-w1-k8s-version-policy-implementation-testing","title":"SCS K8S Version Policy: Implementation and Testing Notes","description":"Implementation notes","source":"@site/standards/scs-0210-w1-k8s-version-policy-implementation-testing.md","sourceDirName":".","slug":"/scs-0210-w1-k8s-version-policy-implementation-testing","permalink":"/standards/scs-0210-w1-k8s-version-policy-implementation-testing","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS K8S Version Policy: Implementation and Testing Notes","type":"Supplement","track":"KaaS","status":"Draft","supplements":["scs-0210-v2-k8s-version-policy.md"]},"sidebar":"standards","previous":{"title":"V2","permalink":"/standards/scs-0210-v2-k8s-version-policy"},"next":{"title":"scs-0211: SCS KaaS default storage class","permalink":"/standards/kaas/scs-0211"}}');var i=s(74848),a=s(28453);const o={title:"SCS K8S Version Policy: Implementation and Testing Notes",type:"Supplement",track:"KaaS",status:"Draft",supplements:["scs-0210-v2-k8s-version-policy.md"]},r=void 0,l={},c=[{value:"Implementation notes",id:"implementation-notes",level:2},{value:"Automated tests",id:"automated-tests",level:2},{value:"Implementation",id:"implementation",level:3},{value:"Manual tests",id:"manual-tests",level:2}];function d(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"implementation-notes",children:"Implementation notes"}),"\n",(0,i.jsxs)(t.p,{children:["The standard is quite concise about ",(0,i.jsx)(t.a,{href:"https://docs.scs.community/standards/scs-0210-v2-k8s-version-policy#decision",children:"the regulations"}),",\nso they are not restated here. Suffice it to say that a\nCSP must make new versions for their KaaS offering available in a timely fashion, so that\nnew versions are available in a short window of time.\nOlder versions need to be supported until the end of their support window."]}),"\n",(0,i.jsxs)(t.p,{children:["Concrete implementation details can't be given here, since not every CSP does provide\ntheir versions the same way. The best advice to give is to monitor the\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/releases/",children:"Kubernetes releases page"})," closely."]}),"\n",(0,i.jsx)(t.h2,{id:"automated-tests",children:"Automated tests"}),"\n",(0,i.jsx)(t.h3,{id:"implementation",children:"Implementation"}),"\n",(0,i.jsxs)(t.p,{children:["The script ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/kaas/k8s-version-policy/k8s_version_policy.py",children:(0,i.jsx)(t.code,{children:"k8s_version_policy.py"})}),"\nconnects to an existing K8s cluster and checks the version against a list of versions, that\nare calculated to be inside a recency window."]}),"\n",(0,i.jsx)(t.p,{children:"Note that this implementation is subject to change, because testing an existing cluster is not\nsufficient to guarantee that all active k8s branches are supported and kept up to date."}),"\n",(0,i.jsx)(t.h2,{id:"manual-tests",children:"Manual tests"}),"\n",(0,i.jsx)(t.p,{children:"None."})]})}function p(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>r});var n=s(96540);const i={},a=n.createContext(i);function o(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/31329.9487c967.js b/assets/js/31329.9487c967.js new file mode 100644 index 0000000000..6009a5b754 --- /dev/null +++ b/assets/js/31329.9487c967.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[31329],{31329:(t,i,e)=>{e.d(i,{diagram:()=>F});var s=e(86079),n=e(9312),a=e(26312),h=(e(74353),e(16750),e(42838),function(){var t=function(t,i,e,s){for(e=e||{},s=t.length;s--;e[t[s]]=i);return e},i=[1,10,12,14,16,18,19,21,23],e=[2,6],s=[1,3],n=[1,5],a=[1,6],h=[1,7],o=[1,5,10,12,14,16,18,19,21,23,34,35,36],r=[1,25],l=[1,26],c=[1,28],g=[1,29],u=[1,30],x=[1,31],d=[1,32],p=[1,33],f=[1,34],y=[1,35],m=[1,36],b=[1,37],A=[1,43],w=[1,42],S=[1,47],C=[1,50],k=[1,10,12,14,16,18,19,21,23,34,35,36],_=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],T=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],R=[1,64],D={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:function(t,i,e,s,n,a,h){var o=a.length-1;switch(n){case 5:s.setOrientation(a[o]);break;case 9:s.setDiagramTitle(a[o].text.trim());break;case 12:s.setLineData({text:"",type:"text"},a[o]);break;case 13:s.setLineData(a[o-1],a[o]);break;case 14:s.setBarData({text:"",type:"text"},a[o]);break;case 15:s.setBarData(a[o-1],a[o]);break;case 16:this.$=a[o].trim(),s.setAccTitle(this.$);break;case 17:case 18:this.$=a[o].trim(),s.setAccDescription(this.$);break;case 19:case 27:this.$=a[o-1];break;case 20:this.$=[Number(a[o-2]),...a[o]];break;case 21:this.$=[Number(a[o])];break;case 22:s.setXAxisTitle(a[o]);break;case 23:s.setXAxisTitle(a[o-1]);break;case 24:s.setXAxisTitle({type:"text",text:""});break;case 25:s.setXAxisBand(a[o]);break;case 26:s.setXAxisRangeData(Number(a[o-2]),Number(a[o]));break;case 28:this.$=[a[o-2],...a[o]];break;case 29:this.$=[a[o]];break;case 30:s.setYAxisTitle(a[o]);break;case 31:s.setYAxisTitle(a[o-1]);break;case 32:s.setYAxisTitle({type:"text",text:""});break;case 33:s.setYAxisRangeData(Number(a[o-2]),Number(a[o]));break;case 37:case 38:this.$={text:a[o],type:"text"};break;case 39:this.$={text:a[o],type:"markdown"};break;case 40:this.$=a[o];break;case 41:this.$=a[o-1]+""+a[o]}},table:[t(i,e,{3:1,4:2,7:4,5:s,34:n,35:a,36:h}),{1:[3]},t(i,e,{4:2,7:4,3:8,5:s,34:n,35:a,36:h}),t(i,e,{4:2,7:4,6:9,3:10,5:s,8:[1,11],34:n,35:a,36:h}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},t(o,[2,34]),t(o,[2,35]),t(o,[2,36]),{1:[2,1]},t(i,e,{4:2,7:4,3:21,5:s,34:n,35:a,36:h}),{1:[2,3]},t(o,[2,5]),t(i,[2,7],{4:22,34:n,35:a,36:h}),{11:23,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{11:39,13:38,24:A,27:w,29:40,30:41,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{11:45,15:44,27:S,33:46,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{11:49,17:48,24:C,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{11:52,17:51,24:C,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{20:[1,53]},{22:[1,54]},t(k,[2,18]),{1:[2,2]},t(k,[2,8]),t(k,[2,9]),t(_,[2,37],{40:55,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b}),t(_,[2,38]),t(_,[2,39]),t(T,[2,40]),t(T,[2,42]),t(T,[2,43]),t(T,[2,44]),t(T,[2,45]),t(T,[2,46]),t(T,[2,47]),t(T,[2,48]),t(T,[2,49]),t(T,[2,50]),t(T,[2,51]),t(k,[2,10]),t(k,[2,22],{30:41,29:56,24:A,27:w}),t(k,[2,24]),t(k,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},t(k,[2,11]),t(k,[2,30],{33:60,27:S}),t(k,[2,32]),{31:[1,61]},t(k,[2,12]),{17:62,24:C},{25:63,27:R},t(k,[2,14]),{17:65,24:C},t(k,[2,16]),t(k,[2,17]),t(T,[2,41]),t(k,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},t(k,[2,31]),{27:[1,69]},t(k,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},t(k,[2,15]),t(k,[2,26]),t(k,[2,27]),{11:59,32:72,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},t(k,[2,33]),t(k,[2,19]),{25:73,27:R},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:function(t,i){if(!i.recoverable){var e=new Error(t);throw e.hash=i,e}this.trace(t)},parse:function(t){var i=this,e=[0],s=[],n=[null],a=[],h=this.table,o="",r=0,l=0,c=a.slice.call(arguments,1),g=Object.create(this.lexer),u={yy:{}};for(var x in this.yy)Object.prototype.hasOwnProperty.call(this.yy,x)&&(u.yy[x]=this.yy[x]);g.setInput(t,u.yy),u.yy.lexer=g,u.yy.parser=this,void 0===g.yylloc&&(g.yylloc={});var d=g.yylloc;a.push(d);var p=g.options&&g.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,y,m,b,A,w,S,C,k,_={};;){if(y=e[e.length-1],this.defaultActions[y]?m=this.defaultActions[y]:(null==f&&(k=void 0,"number"!=typeof(k=s.pop()||g.lex()||1)&&(k instanceof Array&&(k=(s=k).pop()),k=i.symbols_[k]||k),f=k),m=h[y]&&h[y][f]),void 0===m||!m.length||!m[0]){var T="";for(A in C=[],h[y])this.terminals_[A]&&A>2&&C.push("'"+this.terminals_[A]+"'");T=g.showPosition?"Parse error on line "+(r+1)+":\n"+g.showPosition()+"\nExpecting "+C.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(r+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(T,{text:g.match,token:this.terminals_[f]||f,line:g.yylineno,loc:d,expected:C})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+y+", token: "+f);switch(m[0]){case 1:e.push(f),n.push(g.yytext),a.push(g.yylloc),e.push(m[1]),f=null,l=g.yyleng,o=g.yytext,r=g.yylineno,d=g.yylloc;break;case 2:if(w=this.productions_[m[1]][1],_.$=n[n.length-w],_._$={first_line:a[a.length-(w||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(w||1)].first_column,last_column:a[a.length-1].last_column},p&&(_._$.range=[a[a.length-(w||1)].range[0],a[a.length-1].range[1]]),void 0!==(b=this.performAction.apply(_,[o,l,r,u.yy,m[1],n,a].concat(c))))return b;w&&(e=e.slice(0,-1*w*2),n=n.slice(0,-1*w),a=a.slice(0,-1*w)),e.push(this.productions_[m[1]][0]),n.push(_.$),a.push(_._$),S=h[e[e.length-2]][e[e.length-1]],e.push(S);break;case 3:return!0}}return!0}},L={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)},setInput:function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var i=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===s.length?this.yylloc.first_column:0)+s[s.length-e.length].length-e[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"},test_match:function(t,i){var e,s,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var a in n)this[a]=n[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,e,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),a=0;ai[0].length)){if(i=e,s=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,n[a])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,n[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,e,s){switch(e){case 0:case 1:case 5:case 43:break;case 2:case 3:return this.popState(),34;case 4:return 34;case 6:return 10;case 7:return this.pushState("acc_title"),19;case 8:return this.popState(),"acc_title_value";case 9:return this.pushState("acc_descr"),21;case 10:return this.popState(),"acc_descr_value";case 11:this.pushState("acc_descr_multiline");break;case 12:case 25:case 27:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 5;case 15:return 8;case 16:return this.pushState("axis_data"),"X_AXIS";case 17:return this.pushState("axis_data"),"Y_AXIS";case 18:return this.pushState("axis_band_data"),24;case 19:return 31;case 20:return this.pushState("data"),16;case 21:return this.pushState("data"),18;case 22:return this.pushState("data_inner"),24;case 23:return 27;case 24:return this.popState(),26;case 26:this.pushState("string");break;case 28:return"STR";case 29:return 24;case 30:return 26;case 31:return 43;case 32:return"COLON";case 33:return 44;case 34:return 28;case 35:return 45;case 36:return 46;case 37:return 48;case 38:return 50;case 39:return 47;case 40:return 41;case 41:return 49;case 42:return 42;case 44:return 35;case 45:return 36}},rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:(\r?\n))/i,/^(?:(\r?\n))/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:\{)/i,/^(?:[^\}]*)/i,/^(?:xychart-beta\b)/i,/^(?:(?:vertical|horizontal))/i,/^(?:x-axis\b)/i,/^(?:y-axis\b)/i,/^(?:\[)/i,/^(?:-->)/i,/^(?:line\b)/i,/^(?:bar\b)/i,/^(?:\[)/i,/^(?:[+-]?(?:\d+(?:\.\d+)?|\.\d+))/i,/^(?:\])/i,/^(?:(?:`\) \{ this\.pushState\(md_string\); \}\n\(\?:\(\?!`"\)\.\)\+ \{ return MD_STR; \}\n\(\?:`))/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s+)/i,/^(?:;)/i,/^(?:$)/i],conditions:{data_inner:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,23,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},data:{rules:[0,1,3,4,5,6,7,9,11,14,15,16,17,20,21,22,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_band_data:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_data:{rules:[0,1,2,4,5,6,7,9,11,14,15,16,17,18,19,20,21,23,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[],inclusive:!1},md_string:{rules:[],inclusive:!1},string:{rules:[27,28],inclusive:!1},INITIAL:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0}}};function P(){this.yy={}}return D.lexer=L,P.prototype=D,D.Parser=P,new P}());h.parser=h;const o=h;function r(t){return"bar"===t.type}function l(t){return"band"===t.type}function c(t){return"linear"===t.type}class g{constructor(t){this.parentGroup=t}getMaxDimension(t,i){if(!this.parentGroup)return{width:t.reduce(((t,i)=>Math.max(i.length,t)),0)*i,height:i};const e={width:0,height:0},s=this.parentGroup.append("g").attr("visibility","hidden").attr("font-size",i);for(const a of t){const t=(0,n.c)(s,1,a),h=t?t.width:a.length*i,o=t?t.height:i;e.width=Math.max(e.width,h),e.height=Math.max(e.height,o)}return s.remove(),e}}class u{constructor(t,i,e,s){this.axisConfig=t,this.title=i,this.textDimensionCalculator=e,this.axisThemeConfig=s,this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left",this.showTitle=!1,this.showLabel=!1,this.showTick=!1,this.showAxisLine=!1,this.outerPadding=0,this.titleTextHeight=0,this.labelTextHeight=0,this.range=[0,10],this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left"}setRange(t){this.range=t,"left"===this.axisPosition||"right"===this.axisPosition?this.boundingRect.height=t[1]-t[0]:this.boundingRect.width=t[1]-t[0],this.recalculateScale()}getRange(){return[this.range[0]+this.outerPadding,this.range[1]-this.outerPadding]}setAxisPosition(t){this.axisPosition=t,this.setRange(this.range)}getTickDistance(){const t=this.getRange();return Math.abs(t[0]-t[1])/this.getTickValues().length}getAxisOuterPadding(){return this.outerPadding}getLabelDimension(){return this.textDimensionCalculator.getMaxDimension(this.getTickValues().map((t=>t.toString())),this.axisConfig.labelFontSize)}recalculateOuterPaddingToDrawBar(){.7*this.getTickDistance()>2*this.outerPadding&&(this.outerPadding=Math.floor(.7*this.getTickDistance()/2)),this.recalculateScale()}calculateSpaceIfDrawnHorizontally(t){let i=t.height;if(this.axisConfig.showAxisLine&&i>this.axisConfig.axisLineWidth&&(i-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const e=this.getLabelDimension(),s=.2*t.width;this.outerPadding=Math.min(e.width/2,s);const n=e.height+2*this.axisConfig.labelPadding;this.labelTextHeight=e.height,n<=i&&(i-=n,this.showLabel=!0)}if(this.axisConfig.showTick&&i>=this.axisConfig.tickLength&&(this.showTick=!0,i-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const t=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),e=t.height+2*this.axisConfig.titlePadding;this.titleTextHeight=t.height,e<=i&&(i-=e,this.showTitle=!0)}this.boundingRect.width=t.width,this.boundingRect.height=t.height-i}calculateSpaceIfDrawnVertical(t){let i=t.width;if(this.axisConfig.showAxisLine&&i>this.axisConfig.axisLineWidth&&(i-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const e=this.getLabelDimension(),s=.2*t.height;this.outerPadding=Math.min(e.height/2,s);const n=e.width+2*this.axisConfig.labelPadding;n<=i&&(i-=n,this.showLabel=!0)}if(this.axisConfig.showTick&&i>=this.axisConfig.tickLength&&(this.showTick=!0,i-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const t=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),e=t.height+2*this.axisConfig.titlePadding;this.titleTextHeight=t.height,e<=i&&(i-=e,this.showTitle=!0)}this.boundingRect.width=t.width-i,this.boundingRect.height=t.height}calculateSpace(t){return"left"===this.axisPosition||"right"===this.axisPosition?this.calculateSpaceIfDrawnVertical(t):this.calculateSpaceIfDrawnHorizontally(t),this.recalculateScale(),{width:this.boundingRect.width,height:this.boundingRect.height}}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}getDrawableElementsForLeftAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.x+this.boundingRect.width-this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["left-axis","axisl-line"],data:[{path:`M ${i},${this.boundingRect.y} L ${i},${this.boundingRect.y+this.boundingRect.height} `,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["left-axis","label"],data:this.getTickValues().map((t=>({text:t.toString(),x:this.boundingRect.x+this.boundingRect.width-(this.showLabel?this.axisConfig.labelPadding:0)-(this.showTick?this.axisConfig.tickLength:0)-(this.showAxisLine?this.axisConfig.axisLineWidth:0),y:this.getScaleValue(t),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"middle",horizontalPos:"right"})))}),this.showTick){const i=this.boundingRect.x+this.boundingRect.width-(this.showAxisLine?this.axisConfig.axisLineWidth:0);t.push({type:"path",groupTexts:["left-axis","ticks"],data:this.getTickValues().map((t=>({path:`M ${i},${this.getScaleValue(t)} L ${i-this.axisConfig.tickLength},${this.getScaleValue(t)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth})))})}return this.showTitle&&t.push({type:"text",groupTexts:["left-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.axisConfig.titlePadding,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:270,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElementsForBottomAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.y+this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["bottom-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${i} L ${this.boundingRect.x+this.boundingRect.width},${i}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["bottom-axis","label"],data:this.getTickValues().map((t=>({text:t.toString(),x:this.getScaleValue(t),y:this.boundingRect.y+this.axisConfig.labelPadding+(this.showTick?this.axisConfig.tickLength:0)+(this.showAxisLine?this.axisConfig.axisLineWidth:0),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"})))}),this.showTick){const i=this.boundingRect.y+(this.showAxisLine?this.axisConfig.axisLineWidth:0);t.push({type:"path",groupTexts:["bottom-axis","ticks"],data:this.getTickValues().map((t=>({path:`M ${this.getScaleValue(t)},${i} L ${this.getScaleValue(t)},${i+this.axisConfig.tickLength}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth})))})}return this.showTitle&&t.push({type:"text",groupTexts:["bottom-axis","title"],data:[{text:this.title,x:this.range[0]+(this.range[1]-this.range[0])/2,y:this.boundingRect.y+this.boundingRect.height-this.axisConfig.titlePadding-this.titleTextHeight,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElementsForTopAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.y+this.boundingRect.height-this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["top-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${i} L ${this.boundingRect.x+this.boundingRect.width},${i}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["top-axis","label"],data:this.getTickValues().map((t=>({text:t.toString(),x:this.getScaleValue(t),y:this.boundingRect.y+(this.showTitle?this.titleTextHeight+2*this.axisConfig.titlePadding:0)+this.axisConfig.labelPadding,fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"})))}),this.showTick){const i=this.boundingRect.y;t.push({type:"path",groupTexts:["top-axis","ticks"],data:this.getTickValues().map((t=>({path:`M ${this.getScaleValue(t)},${i+this.boundingRect.height-(this.showAxisLine?this.axisConfig.axisLineWidth:0)} L ${this.getScaleValue(t)},${i+this.boundingRect.height-this.axisConfig.tickLength-(this.showAxisLine?this.axisConfig.axisLineWidth:0)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth})))})}return this.showTitle&&t.push({type:"text",groupTexts:["top-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.axisConfig.titlePadding,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElements(){if("left"===this.axisPosition)return this.getDrawableElementsForLeftAxis();if("right"===this.axisPosition)throw Error("Drawing of right axis is not implemented");return"bottom"===this.axisPosition?this.getDrawableElementsForBottomAxis():"top"===this.axisPosition?this.getDrawableElementsForTopAxis():[]}}class x extends u{constructor(t,i,e,s,n){super(t,s,n,i),this.categories=e,this.scale=(0,a.WH)().domain(this.categories).range(this.getRange())}setRange(t){super.setRange(t)}recalculateScale(){this.scale=(0,a.WH)().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(.5),s.l.trace("BandAxis axis final categories, range: ",this.categories,this.getRange())}getTickValues(){return this.categories}getScaleValue(t){return this.scale(t)||this.getRange()[0]}}class d extends u{constructor(t,i,e,s,n){super(t,s,n,i),this.domain=e,this.scale=(0,a.m4Y)().domain(this.domain).range(this.getRange())}getTickValues(){return this.scale.ticks()}recalculateScale(){const t=[...this.domain];"left"===this.axisPosition&&t.reverse(),this.scale=(0,a.m4Y)().domain(t).range(this.getRange())}getScaleValue(t){return this.scale(t)}}function p(t,i,e,s){const n=new g(s);return l(t)?new x(i,e,t.categories,t.title,n):new d(i,e,[t.min,t.max],t.title,n)}class f{constructor(t,i,e,s){this.textDimensionCalculator=t,this.chartConfig=i,this.chartData=e,this.chartThemeConfig=s,this.boundingRect={x:0,y:0,width:0,height:0},this.showChartTitle=!1}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){const i=this.textDimensionCalculator.getMaxDimension([this.chartData.title],this.chartConfig.titleFontSize),e=Math.max(i.width,t.width),s=i.height+2*this.chartConfig.titlePadding;return i.width<=e&&i.height<=s&&this.chartConfig.showTitle&&this.chartData.title&&(this.boundingRect.width=e,this.boundingRect.height=s,this.showChartTitle=!0),{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){const t=[];return this.showChartTitle&&t.push({groupTexts:["chart-title"],type:"text",data:[{fontSize:this.chartConfig.titleFontSize,text:this.chartData.title,verticalPos:"middle",horizontalPos:"center",x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.chartThemeConfig.titleColor,rotation:0}]}),t}}function y(t,i,e,s){const n=new g(s);return new f(n,t,i,e)}class m{constructor(t,i,e,s,n){this.plotData=t,this.xAxis=i,this.yAxis=e,this.orientation=s,this.plotIndex=n}getDrawableElement(){const t=this.plotData.data.map((t=>[this.xAxis.getScaleValue(t[0]),this.yAxis.getScaleValue(t[1])]));let i;return i="horizontal"===this.orientation?(0,a.n8j)().y((t=>t[0])).x((t=>t[1]))(t):(0,a.n8j)().x((t=>t[0])).y((t=>t[1]))(t),i?[{groupTexts:["plot",`line-plot-${this.plotIndex}`],type:"path",data:[{path:i,strokeFill:this.plotData.strokeFill,strokeWidth:this.plotData.strokeWidth}]}]:[]}}class b{constructor(t,i,e,s,n,a){this.barData=t,this.boundingRect=i,this.xAxis=e,this.yAxis=s,this.orientation=n,this.plotIndex=a}getDrawableElement(){const t=this.barData.data.map((t=>[this.xAxis.getScaleValue(t[0]),this.yAxis.getScaleValue(t[1])])),i=.95*Math.min(2*this.xAxis.getAxisOuterPadding(),this.xAxis.getTickDistance()),e=i/2;return"horizontal"===this.orientation?[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:t.map((t=>({x:this.boundingRect.x,y:t[0]-e,height:i,width:t[1]-this.boundingRect.x,fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill})))}]:[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:t.map((t=>({x:t[0]-e,y:t[1],width:i,height:this.boundingRect.y+this.boundingRect.height-t[1],fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill})))}]}}class A{constructor(t,i,e){this.chartConfig=t,this.chartData=i,this.chartThemeConfig=e,this.boundingRect={x:0,y:0,width:0,height:0}}setAxes(t,i){this.xAxis=t,this.yAxis=i}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){return this.boundingRect.width=t.width,this.boundingRect.height=t.height,{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){if(!this.xAxis||!this.yAxis)throw Error("Axes must be passed to render Plots");const t=[];for(const[i,e]of this.chartData.plots.entries())switch(e.type){case"line":{const s=new m(e,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,i);t.push(...s.getDrawableElement())}break;case"bar":{const s=new b(e,this.boundingRect,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,i);t.push(...s.getDrawableElement())}}return t}}function w(t,i,e){return new A(t,i,e)}class S{constructor(t,i,e,s){this.chartConfig=t,this.chartData=i,this.componentStore={title:y(t,i,e,s),plot:w(t,i,e),xAxis:p(i.xAxis,t.xAxis,{titleColor:e.xAxisTitleColor,labelColor:e.xAxisLabelColor,tickColor:e.xAxisTickColor,axisLineColor:e.xAxisLineColor},s),yAxis:p(i.yAxis,t.yAxis,{titleColor:e.yAxisTitleColor,labelColor:e.yAxisLabelColor,tickColor:e.yAxisTickColor,axisLineColor:e.yAxisLineColor},s)}}calculateVerticalSpace(){let t=this.chartConfig.width,i=this.chartConfig.height,e=0,s=0,n=Math.floor(t*this.chartConfig.plotReservedSpacePercent/100),a=Math.floor(i*this.chartConfig.plotReservedSpacePercent/100),h=this.componentStore.plot.calculateSpace({width:n,height:a});t-=h.width,i-=h.height,h=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:i}),s=h.height,i-=h.height,this.componentStore.xAxis.setAxisPosition("bottom"),h=this.componentStore.xAxis.calculateSpace({width:t,height:i}),i-=h.height,this.componentStore.yAxis.setAxisPosition("left"),h=this.componentStore.yAxis.calculateSpace({width:t,height:i}),e=h.width,t-=h.width,t>0&&(n+=t,t=0),i>0&&(a+=i,i=0),this.componentStore.plot.calculateSpace({width:n,height:a}),this.componentStore.plot.setBoundingBoxXY({x:e,y:s}),this.componentStore.xAxis.setRange([e,e+n]),this.componentStore.xAxis.setBoundingBoxXY({x:e,y:s+a}),this.componentStore.yAxis.setRange([s,s+a]),this.componentStore.yAxis.setBoundingBoxXY({x:0,y:s}),this.chartData.plots.some((t=>r(t)))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateHorizontalSpace(){let t=this.chartConfig.width,i=this.chartConfig.height,e=0,s=0,n=0,a=Math.floor(t*this.chartConfig.plotReservedSpacePercent/100),h=Math.floor(i*this.chartConfig.plotReservedSpacePercent/100),o=this.componentStore.plot.calculateSpace({width:a,height:h});t-=o.width,i-=o.height,o=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:i}),e=o.height,i-=o.height,this.componentStore.xAxis.setAxisPosition("left"),o=this.componentStore.xAxis.calculateSpace({width:t,height:i}),t-=o.width,s=o.width,this.componentStore.yAxis.setAxisPosition("top"),o=this.componentStore.yAxis.calculateSpace({width:t,height:i}),i-=o.height,n=e+o.height,t>0&&(a+=t,t=0),i>0&&(h+=i,i=0),this.componentStore.plot.calculateSpace({width:a,height:h}),this.componentStore.plot.setBoundingBoxXY({x:s,y:n}),this.componentStore.yAxis.setRange([s,s+a]),this.componentStore.yAxis.setBoundingBoxXY({x:s,y:e}),this.componentStore.xAxis.setRange([n,n+h]),this.componentStore.xAxis.setBoundingBoxXY({x:0,y:n}),this.chartData.plots.some((t=>r(t)))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateSpace(){"horizontal"===this.chartConfig.chartOrientation?this.calculateHorizontalSpace():this.calculateVerticalSpace()}getDrawableElement(){this.calculateSpace();const t=[];this.componentStore.plot.setAxes(this.componentStore.xAxis,this.componentStore.yAxis);for(const i of Object.values(this.componentStore))t.push(...i.getDrawableElements());return t}}class C{static build(t,i,e,s){return new S(t,i,e,s).getDrawableElement()}}let k,_=0,T=I(),R=v(),D=M(),L=R.plotColorPalette.split(",").map((t=>t.trim())),P=!1,E=!1;function v(){const t=(0,s.E)(),i=(0,s.F)();return(0,s.C)(t.xyChart,i.themeVariables.xyChart)}function I(){const t=(0,s.F)();return(0,s.C)(s.B.xyChart,t.xyChart)}function M(){return{yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]}}function $(t){const i=(0,s.F)();return(0,s.d)(t.trim(),i)}function z(t,i){D.xAxis={type:"linear",title:D.xAxis.title,min:t,max:i},P=!0}function B(t){let i=[];if(0===t.length)return i;if(!P){const i=c(D.xAxis)?D.xAxis.min:1/0,e=c(D.xAxis)?D.xAxis.max:-1/0;z(Math.min(i,1),Math.max(e,t.length))}if(E||function(t){const i=Math.min(...t),e=Math.max(...t),s=c(D.yAxis)?D.yAxis.min:1/0,n=c(D.yAxis)?D.yAxis.max:-1/0;D.yAxis={type:"linear",title:D.yAxis.title,min:Math.min(s,i),max:Math.max(n,e)}}(t),l(D.xAxis)&&(i=D.xAxis.categories.map(((i,e)=>[i,t[e]]))),c(D.xAxis)){const e=D.xAxis.min,s=D.xAxis.max,n=(s-e+1)/t.length,a=[];for(let t=e;t<=s;t+=n)a.push(`${t}`);i=a.map(((i,e)=>[i,t[e]]))}return i}function W(t){return L[0===t?0:t%L.length]}const F={parser:o,db:{getDrawableElem:function(){if(0===D.plots.length)throw Error("No Plot to render, please provide a plot with some data");return D.title=(0,s.t)(),C.build(T,D,R,k)},clear:function(){(0,s.v)(),_=0,T=I(),D={yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]},R=v(),L=R.plotColorPalette.split(",").map((t=>t.trim())),P=!1,E=!1},setAccTitle:s.s,getAccTitle:s.g,setDiagramTitle:s.q,getDiagramTitle:s.t,getAccDescription:s.a,setAccDescription:s.b,setOrientation:function(t){T.chartOrientation="horizontal"===t?"horizontal":"vertical"},setXAxisTitle:function(t){D.xAxis.title=$(t.text)},setXAxisRangeData:z,setXAxisBand:function(t){D.xAxis={type:"band",title:D.xAxis.title,categories:t.map((t=>$(t.text)))},P=!0},setYAxisTitle:function(t){D.yAxis.title=$(t.text)},setYAxisRangeData:function(t,i){D.yAxis={type:"linear",title:D.yAxis.title,min:t,max:i},E=!0},setLineData:function(t,i){const e=B(i);D.plots.push({type:"line",strokeFill:W(_),strokeWidth:2,data:e}),_++},setBarData:function(t,i){const e=B(i);D.plots.push({type:"bar",fill:W(_),data:e}),_++},setTmpSVGG:function(t){k=t},getChartThemeConfig:function(){return R},getChartConfig:function(){return T}},renderer:{draw:(t,i,e,n)=>{const a=n.db,h=a.getChartThemeConfig(),o=a.getChartConfig();function r(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}s.l.debug("Rendering xychart chart\n"+t);const l=(0,s.A)(i),c=l.append("g").attr("class","main"),g=c.append("rect").attr("width",o.width).attr("height",o.height).attr("class","background");(0,s.i)(l,o.height,o.width,!0),l.attr("viewBox",`0 0 ${o.width} ${o.height}`),g.attr("fill",h.backgroundColor),a.setTmpSVGG(l.append("g").attr("class","mermaid-tmp-group"));const u=a.getDrawableElem(),x={};function d(t){let i=c,e="";for(const[s]of t.entries()){let n=c;s>0&&x[e]&&(n=x[e]),e+=t[s],i=x[e],i||(i=x[e]=n.append("g").attr("class",t[s]))}return i}for(const s of u){if(0===s.data.length)continue;const t=d(s.groupTexts);switch(s.type){case"rect":t.selectAll("rect").data(s.data).enter().append("rect").attr("x",(t=>t.x)).attr("y",(t=>t.y)).attr("width",(t=>t.width)).attr("height",(t=>t.height)).attr("fill",(t=>t.fill)).attr("stroke",(t=>t.strokeFill)).attr("stroke-width",(t=>t.strokeWidth));break;case"text":t.selectAll("text").data(s.data).enter().append("text").attr("x",0).attr("y",0).attr("fill",(t=>t.fill)).attr("font-size",(t=>t.fontSize)).attr("dominant-baseline",(t=>"top"===t.verticalPos?"text-before-edge":"middle")).attr("text-anchor",(t=>{return"left"===(i=t.horizontalPos)?"start":"right"===i?"end":"middle";var i})).attr("transform",(t=>r(t))).text((t=>t.text));break;case"path":t.selectAll("path").data(s.data).enter().append("path").attr("d",(t=>t.path)).attr("fill",(t=>t.fill?t.fill:"none")).attr("stroke",(t=>t.strokeFill)).attr("stroke-width",(t=>t.strokeWidth))}}}}}}}]); \ No newline at end of file diff --git a/assets/js/315ee77a.43c90a4c.js b/assets/js/315ee77a.43c90a4c.js new file mode 100644 index 0000000000..823e89f4a6 --- /dev/null +++ b/assets/js/315ee77a.43c90a4c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[78353],{31642:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"operating-scs/components/scs-health-monitor/overview","title":"SCS Health Monitor","description":"Welcome to the SCS Health Monitor project! This repository is dedicated to setting up scenarios for functionality and load testing on a deployed OpenStack environment. We utilize Gherkin language to write testing scenarios, and Python\'s Behave library to execute these tests.","source":"@site/docs/04-operating-scs/components/scs-health-monitor/overview.md","sourceDirName":"04-operating-scs/components/scs-health-monitor","slug":"/operating-scs/components/scs-health-monitor/overview","permalink":"/docs/operating-scs/components/scs-health-monitor/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/scs-health-monitor/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"SCS Health Monitor","permalink":"/docs/category/scs-health-monitor"},"next":{"title":"Kubernetes BDD Testing Framework Documentation","permalink":"/docs/operating-scs/components/scs-health-monitor/Workflow"}}');var i=s(74848),o=s(28453);const r={},a="SCS Health Monitor",l={},c=[{value:"Description",id:"description",level:2},{value:"Getting Started",id:"getting-started",level:2},{value:"Using the test framework",id:"using-the-test-framework",level:2},{value:"Execute a specific test",id:"execute-a-specific-test",level:3},{value:"Execute a series of tests",id:"execute-a-series-of-tests",level:3},{value:"Publish results to Prometheus",id:"publish-results-to-prometheus",level:2},{value:"Setting up Prometheus and Prometheus Push Gateway locally",id:"setting-up-prometheus-and-prometheus-push-gateway-locally",level:3},{value:"Exporting metrics to Prometheus Push Gateway",id:"exporting-metrics-to-prometheus-push-gateway",level:3},{value:"Use a docker image",id:"use-a-docker-image",level:2},{value:"Collaborators",id:"collaborators",level:2},{value:"Useful links and references",id:"useful-links-and-references",level:2}];function h(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"scs-health-monitor",children:"SCS Health Monitor"})}),"\n",(0,i.jsx)(t.p,{children:"Welcome to the SCS Health Monitor project! This repository is dedicated to setting up scenarios for functionality and load testing on a deployed OpenStack environment. We utilize Gherkin language to write testing scenarios, and Python's Behave library to execute these tests."}),"\n",(0,i.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,i.jsx)(t.p,{children:"The SCS Health Monitor project aims to ensure the robustness and reliability of OpenStack environments by simulating various scenarios and assessing their performance under different loads. By employing Gherkin language and Behave library, we can define clear, human-readable test cases that cover a wide range of functionalities, from basic system checks to complex stress tests."}),"\n",(0,i.jsx)(t.h2,{id:"getting-started",children:"Getting Started"}),"\n",(0,i.jsx)(t.p,{children:"To get started with the SCS Health Monitor project, follow these steps:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:["Clone ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor",children:"healt-monitor repository"})," to your local machine."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"git clone git@github.com:SovereignCloudStack/scs-health-monitor.git\ncd scs-health-monitor\n"})}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Install the required dependencies"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["listed in the ",(0,i.jsx)(t.code,{children:"[Dockerfile](https://github.com/SovereignCloudStack/scs-health-monitor/blob/main/Dockerfile)"})," file\n(see: ",(0,i.jsx)(t.code,{children:"apt-get ..."}),")"]}),"\n",(0,i.jsxs)(t.li,{children:["listed in the ",(0,i.jsx)(t.code,{children:"[requirements.txt](https://github.com/SovereignCloudStack/scs-health-monitor/blob/main/requirements.txt)"})," file by executing the following command:","\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"./scs-health-monitor deps\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:["Review the existing Gherkin scenarios in the ",(0,i.jsx)(t.code,{children:"[cloud_level_testing/features](https://github.com/SovereignCloudStack/scs-health-monitor/tree/main/cloud_level_testing/features)"})," and ",(0,i.jsx)(t.code,{children:"[container_level_testing/features](https://github.com/SovereignCloudStack/scs-health-monitor/tree/main/container_level_testing/features)"})," directories to understand the testing coverage."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'Create a openstack project with a user with "manager" privileges and suitable quotas:'}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"cores: 50"}),"\n",(0,i.jsx)(t.li,{children:"instances: 30"}),"\n",(0,i.jsx)(t.li,{children:"ram: 128000"}),"\n",(0,i.jsx)(t.li,{children:"volumes: 20"}),"\n",(0,i.jsx)(t.li,{children:"gigabytes: 200"}),"\n",(0,i.jsx)(t.li,{children:"security_groups: 50"}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["You can use the ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/openstack-workload-generator",children:"openstack workload mananger"})]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"${OPENSTACK_WORKLOAD_MANAGER_INSTALLATION_DIR?the installation dir}/openstack_workload_generator \\\n --create_domains scs-health-monitor \\\n --create_projects test-project \\\n --create_machines none \\\n --clouds_yaml $PWD/clouds.yaml \\\n --config ${OPENSTACK_WORKLOAD_MANAGER_INSTALLATION_DIR}/profiles/health-mon.yaml\n"})}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:["Create a ",(0,i.jsx)(t.code,{children:"clouds.yaml"})," (",(0,i.jsx)(t.a,{href:"/assets/config-examples/clouds.yaml",children:"example"}),") file in the root of the repository-clone to configure API access to OpenStack."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:["Create a ",(0,i.jsx)(t.code,{children:"env.yaml"})," (",(0,i.jsx)(t.a,{href:"/assets/config-examples/env.yaml",children:"example"}),") file containing configuration needed for performing the tests.\n(Configure at least the ",(0,i.jsx)(t.code,{children:"CLOUD_NAME"})," to specify which project should be used)"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:["Execute the tests using Behave library to validate the functionality and performance of your OpenStack environment.\n(see ",(0,i.jsx)(t.a,{href:"#using-the-test-framework",children:"next section"}),")"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"using-the-test-framework",children:"Using the test framework"}),"\n",(0,i.jsx)(t.h3,{id:"execute-a-specific-test",children:"Execute a specific test"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"./scs-health-monitor behave cloud_level_testing/features/openstack_create_network.feature\n"})}),"\n",(0,i.jsx)(t.p,{children:"Here are some basic commands to run the tests:"}),"\n",(0,i.jsx)(t.h3,{id:"execute-a-series-of-tests",children:"Execute a series of tests"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Run all scenarios for IaaS"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"./scs-health-monitor behave cloud_level_testing/features/\n"})}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Run all scenarios for KaaS"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"./scs-health-monitor behave container_level_testing/features/\n"})}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'Run all scenarios for IaaS with the "network" and the "cleanup" tag'}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"./scs-health-monitor behave --tags=network cloud_level_testing/features/\n./scs-health-monitor behave --tags=cleanup cloud_level_testing/features/\n"})}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Run all of the IaaS scenarios, but parallel only the features"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"./scs-health-monitor behavex --parallel-scheme cloud_level_testing/features/\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["There is a possibility to run it on the ",(0,i.jsx)(t.a,{href:"https://github.com/hrcorval/behavex",children:"behavex"})," framework as well. To get more information, ",(0,i.jsx)(t.a,{href:"https://pypi.org/project/behavex/",children:"here"})," is a link to the documentation."]}),"\n",(0,i.jsx)(t.h2,{id:"publish-results-to-prometheus",children:"Publish results to Prometheus"}),"\n",(0,i.jsxs)(t.p,{children:["The scs-health-monitor is capable to puhlish the results to a prometheus instance.\nDetails of the available measurements are available in the ",(0,i.jsx)(t.a,{href:"docs/Metric_List.md",children:"METRIC OVERVIEW"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"setting-up-prometheus-and-prometheus-push-gateway-locally",children:"Setting up Prometheus and Prometheus Push Gateway locally"}),"\n",(0,i.jsx)(t.p,{children:"For the purposes of gathering information from the test cases being performed against OpenStack, Prometheus metrics are being gathered during excecution of the test, then later these metrics are pushed to a Prometheus Push Gateway."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.a,{href:"./ObservabilityStack/SetupObservabilityStack.md",children:"Here"})," you can find a useful quickstart quide on setting up Promethus Stack and Prometheus push gateway locally."]}),"\n",(0,i.jsx)(t.h3,{id:"exporting-metrics-to-prometheus-push-gateway",children:"Exporting metrics to Prometheus Push Gateway"}),"\n",(0,i.jsxs)(t.p,{children:["To be able to push the metrics gathered during test executions, you must first configure the prometheus push gateway endpoint. You achieve this by adding these lines to a ",(0,i.jsx)(t.em,{children:(0,i.jsx)(t.a,{href:"/assets/config-examples/env.yaml",children:"env.yaml"})}),":"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:'# Required\n# If not present the metrics won\'t\n# be pushed by the test scenarios\nPROMETHEUS_ENDPOINT: "localhost:30001"\n\n# Optional (default: "SCS-Health-Monitor")\n# Specify the job label value that\n# gets added to the metrics\nPROMETHEUS_BATCH_NAME: "SCS-Health-Monitor"\n\n# Required\n# The name of the cloud from clouds.yaml\n# that the test scenarios will be ran on\nCLOUD_NAME: "gx"\n\n# Optional (default: true)\n# Apply start time and stop time to prometheus batch name\nAPPEND_TIMESTAMP_TO_BATCH_NAME: true\n'})}),"\n",(0,i.jsxs)(t.p,{children:["This ",(0,i.jsx)(t.code,{children:"env.yaml"})," file must be placed in the root of the repository. This is where you should be also issuing all the ",(0,i.jsx)(t.em,{children:"behave <...>"})," commands to execute the test scenarios."]}),"\n",(0,i.jsx)(t.h2,{id:"use-a-docker-image",children:"Use a docker image"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["Create a docker image","\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"docker build --progress plain -t scs-health-monitor -f Dockerfile .\n"})}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["Execute a docker image","\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:'sudo chown 1001:1001 ./env.yaml ./clouds.yaml ./ca-certificates.crt\nDOCKER_MOUNTS="-v ./env.yaml:/installation/env.yaml -v ./clouds.yaml:/installation/clouds.yaml -v ./ca-certificates.crt:/installation/ca-certificates.crt"\n# A shell\ndocker run -ti ${DOCKER_MOUNTS?not set} --rm --entrypoint /bin/bash --name scs-health-monitor scs-health-monitor\n# Entrypoint execution\ndocker run -ti ${DOCKER_MOUNTS?not set} --rm --name scs-health-monitor scs-health-monitor behave \ndocker run -ti ${DOCKER_MOUNTS?not set} --rm --name scs-health-monitor scs-health-monitor behave cloud_level_testing/features/openstack_create_network.feature\n'})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"collaborators",children:"Collaborators"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["Piotr Bigos ",(0,i.jsx)(t.a,{href:"https://github.com/piobig2871",children:"@piobig2871"})]}),"\n",(0,i.jsxs)(t.li,{children:["Erik Kostelansk\xfd ",(0,i.jsx)(t.a,{href:"https://github.com/Erik-Kostelansky-dNation",children:"@Erik-Kostelansky-dNation"})]}),"\n",(0,i.jsxs)(t.li,{children:["Katharina Trentau ",(0,i.jsx)(t.a,{href:"https://github.com/fraugabel",children:"@fraugabel"})]}),"\n",(0,i.jsxs)(t.li,{children:["\u013dubom\xedr Dobrovodsk\xfd ",(0,i.jsx)(t.a,{href:"https://github.com/dobrovodskydnation",children:"@dobrovodskydnation"})]}),"\n",(0,i.jsxs)(t.li,{children:["Tom\xe1\u0161 Sm\xe4do ",(0,i.jsx)(t.a,{href:"https://github.com/tsmado",children:"@tsmado"})]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"useful-links-and-references",children:"Useful links and references"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://docs.openstack.org/openstacksdk/latest/user/",children:"Openstack python SDK documentation"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://docs.openstack.org/python-openstackclient/latest/",children:"Openstack CLI tool documentation"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://jenisys.github.io/behave.example/tutorials/tutorial04.html",children:"Parameterisation of tests using scenario outlines"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://behave.readthedocs.io/en/stable/tutorial.html",children:"Short but concise tutorial on how to setup behave test scenarios"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor",children:"The legacy but complete implementation"})}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>a});var n=s(96540);const i={},o=n.createContext(i);function r(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3180fd0e.24b8ae34.js b/assets/js/3180fd0e.24b8ae34.js new file mode 100644 index 0000000000..dd33803204 --- /dev/null +++ b/assets/js/3180fd0e.24b8ae34.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[78340],{62465:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>r,contentTitle:()=>l,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>d});const a=JSON.parse('{"id":"scs-0211-w1-kaas-default-storage-class-implementation-testing","title":"SCS KaaS default storage class: Implementation and Testing Notes","description":"Implementation notes","source":"@site/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing.md","sourceDirName":".","slug":"/scs-0211-w1-kaas-default-storage-class-implementation-testing","permalink":"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS KaaS default storage class: Implementation and Testing Notes","type":"Supplement","track":"KaaS","status":"Draft","supplements":["scs-0211-v1-kaas-default-storage-class.md"]},"sidebar":"standards","previous":{"title":"V2","permalink":"/standards/scs-0211-v2-kaas-default-storage-class"},"next":{"title":"scs-0212: Requirements for container registries","permalink":"/standards/kaas/scs-0212"}}');var n=s(74848),o=s(28453);const i={title:"SCS KaaS default storage class: Implementation and Testing Notes",type:"Supplement",track:"KaaS",status:"Draft",supplements:["scs-0211-v1-kaas-default-storage-class.md"]},l=void 0,r={},d=[{value:"Implementation notes",id:"implementation-notes",level:2},{value:"Automated tests",id:"automated-tests",level:2},{value:"Notes",id:"notes",level:3},{value:"Implementation",id:"implementation",level:3},{value:"Manual tests",id:"manual-tests",level:2}];function c(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"implementation-notes",children:"Implementation notes"}),"\n",(0,n.jsxs)(t.p,{children:["A ",(0,n.jsx)(t.code,{children:"StorageClass"})," is made default by using the ",(0,n.jsx)(t.code,{children:"storageclass.kubernetes.io/is-default-class"}),"\nannotation; a standardized name is not given. ",(0,n.jsx)(t.code,{children:"ReadWriteOnce"})," must be supported by the volume,\nand it must be protected against data loss due to hardware failures.\nTherefore, volumes must not be bound to the lifecycle of a Kubernetes node and, at best,\nbe backed by some kind of redundant storage.\nGuarantees for latency, bandwidth, IOPS and so on are not given."]}),"\n",(0,n.jsxs)(t.p,{children:["The cost-intensive part of this standard would be the hardware failure protection by binding\nthe ",(0,n.jsx)(t.code,{children:"StorageClass"})," to redundant, non-lifecycle bound storage, since this would mean that\nstorage needs to be provided in a higher capacity to achieve the same usable capacity."]}),"\n",(0,n.jsx)(t.h2,{id:"automated-tests",children:"Automated tests"}),"\n",(0,n.jsx)(t.h3,{id:"notes",children:"Notes"}),"\n",(0,n.jsxs)(t.p,{children:["The test for the ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0211-v1-kaas-default-storage-class.md",children:"SCS Kaas Default storage class"}),"\nchecks if a default storage class is available and if this storage class can be used\nto create a ",(0,n.jsx)(t.code,{children:"PersistentVolume"})," from a ",(0,n.jsx)(t.code,{children:"PersistentVolumeClaim"})," for a container."]}),"\n",(0,n.jsx)(t.h3,{id:"implementation",children:"Implementation"}),"\n",(0,n.jsxs)(t.p,{children:["The script ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/kaas/k8s-default-storage-class/k8s-default-storage-class-check.py",children:(0,n.jsx)(t.code,{children:"k8s-default-storage-class-check.py"})}),"\nconnects to an existing K8s cluster and checks for the availability of a default storage class.\nThis can also be done via Sonobuoy."]}),"\n",(0,n.jsx)(t.h2,{id:"manual-tests",children:"Manual tests"}),"\n",(0,n.jsx)(t.p,{children:"None."})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>l});var a=s(96540);const n={},o=a.createContext(n);function i(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/31d44bea.facefabd.js b/assets/js/31d44bea.facefabd.js new file mode 100644 index 0000000000..29ecfb31a6 --- /dev/null +++ b/assets/js/31d44bea.facefabd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[40935],{69676:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>l,contentTitle:()=>c,default:()=>u,frontMatter:()=>a,metadata:()=>r,toc:()=>i});const r=JSON.parse('{"id":"operating-scs/components/scs-health-monitor/SetupObservabilityStack","title":"Observability stack quickstart","description":"Prerequisites","source":"@site/docs/04-operating-scs/components/scs-health-monitor/SetupObservabilityStack.md","sourceDirName":"04-operating-scs/components/scs-health-monitor","slug":"/operating-scs/components/scs-health-monitor/SetupObservabilityStack","permalink":"/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/scs-health-monitor/SetupObservabilityStack.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Testflow-Infrastructure","permalink":"/docs/operating-scs/components/scs-health-monitor/Testflow"},"next":{"title":"Central API","permalink":"/docs/category/central-api"}}');var n=t(74848),o=t(28453);const a={},c="Observability stack quickstart",l={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Setup process",id:"setup-process",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"observability-stack-quickstart",children:"Observability stack quickstart"})}),"\n",(0,n.jsx)(s.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsxs)(s.p,{children:["Kubernetes is required to setup this observability stack consisting of Prometheus, Grafana and Prometheus push gateway.\nOne recommendation for setting up a local Kubernetes environment is to use ",(0,n.jsx)(s.a,{href:"https://kind.sigs.k8s.io/",children:"KIND (Kubernetes in Docker)"}),". KIND provides a lightweight way to create Kubernetes clusters using Docker containers. ",(0,n.jsx)(s.a,{href:"https://docs.docker.com/desktop/kubernetes/",children:"Docker Desktop"})," also has support for kubernetes."]}),"\n",(0,n.jsx)(s.h2,{id:"setup-process",children:"Setup process"}),"\n",(0,n.jsx)(s.p,{children:"To set up Prometheus stack and Prometheus Pushgateway on local Kubernetes using Helm, you can follow these steps:"}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsx)(s.li,{children:"Add Helm Chart Repositories:"}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"helm repo add prometheus-community https://prometheus-community.github.io/helm-charts\nhelm repo update\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"2",children:["\n",(0,n.jsx)(s.li,{children:"Install Prometheus Stack:"}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:'helm install my-kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 57.0.3 -f "./Values/PrometheusStackValues.yaml"\n'})}),"\n",(0,n.jsxs)(s.p,{children:["This command will install the Prometheus stack on your Kubernetes cluster ",(0,n.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor/tree/ba9049292c3da5afcdae52b1cca15759e074e950/docs/ObservabilityStack/Values/PrometheusStackValues.yaml",children:"using these values"}),"."]}),"\n",(0,n.jsxs)(s.ol,{start:"3",children:["\n",(0,n.jsx)(s.li,{children:"Install Prometheus Pushgateway:"}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:'helm install my-prometheus-pushgateway prometheus-community/prometheus-pushgateway --version 2.8.0 -f "./Values/PrometheusPushGateway.yaml"\n'})}),"\n",(0,n.jsxs)(s.p,{children:["This command will install Prometheus Pushgateway on your Kubernetes cluster ",(0,n.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor/tree/ba9049292c3da5afcdae52b1cca15759e074e950/docs/ObservabilityStack/Values/PrometheusPushGateway.yaml",children:"using these values"}),"."]}),"\n",(0,n.jsxs)(s.ol,{start:"4",children:["\n",(0,n.jsx)(s.li,{children:"Set Docker Context:"}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"kubectl config get-contexts\nkubectl config use-context docker-desktop\n"})}),"\n",(0,n.jsx)(s.p,{children:"Ensure that the Docker context is correctly set to your local Kubernetes cluster."}),"\n",(0,n.jsxs)(s.ol,{start:"5",children:["\n",(0,n.jsx)(s.li,{children:"Expose Services Locally:"}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"kubectl apply -f ./k8s/nodePorts.yaml\n"})}),"\n",(0,n.jsx)(s.p,{children:"This command will apply the configuration to expose services using nodePort service on Kubernetes."}),"\n",(0,n.jsx)(s.p,{children:"An alternative to using NodePort for exposing services to localhost in a local Kubernetes setup is to use kubectl port-forward. This command allows you to forward local ports to a port on a specific pod within the Kubernetes cluster. Here's how you can use it:"}),"\n",(0,n.jsxs)(s.ol,{start:"6",children:["\n",(0,n.jsx)(s.li,{children:"Port Forwarding for Prometheus Stack:"}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"\nkubectl port-forward svc/ :\n"})}),"\n",(0,n.jsx)(s.p,{children:"Replace with the actual name of the Prometheus service in your Kubernetes cluster. is the port number on your localhost where you want to access Prometheus, and is the port on which Prometheus is running within the cluster. The same applies to prometheus push gateway or any other service you may want to expose."}),"\n",(0,n.jsx)(s.p,{children:"For example:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"kubectl port-forward svc/my-kube-prometheus-stack-prometheus 9090:9090\nkubectl port-forward svc/my-prometheus-pushgateway 9091:9091\n"})}),"\n",(0,n.jsx)(s.p,{children:'Make sure to replace "./Values/PrometheusStackValues" with the actual path to your Prometheus Stack values file. Also, adjust the path to the nodePorts.yaml file if it\'s located in a different directory.'}),"\n",(0,n.jsx)(s.p,{children:"Remember to replace placeholders such as my-kube-prometheus-stack and my-prometheus-pushgateway with appropriate names for your deployments."}),"\n",(0,n.jsx)(s.p,{children:"Once you've executed these commands, Prometheus stack and Prometheus Pushgateway should be set up and accessible on your local Kubernetes cluster."}),"\n",(0,n.jsxs)(s.ol,{start:"7",children:["\n",(0,n.jsx)(s.li,{children:"Uninstall helm chart\nIf you want to reinstall or remove the deployed observability stack, you can use the following commands:"}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"# List deployed helm charts\nhelm list\n\n# Delete helm chart (all deployed k8s resources) with name \nhelm uninstall \n"})})]})}function u(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>a,x:()=>c});var r=t(96540);const n={},o=r.createContext(n);function a(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/31e2019b.ad1d60d1.js b/assets/js/31e2019b.ad1d60d1.js new file mode 100644 index 0000000000..a3296e814c --- /dev/null +++ b/assets/js/31e2019b.ad1d60d1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[13974],{98247:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"container/components/cluster-stacks/components/csctl/quickstart","title":"Quickstart","description":"Installation","source":"@site/docs/03-container/components/cluster-stacks/components/csctl/quickstart.md","sourceDirName":"03-container/components/cluster-stacks/components/csctl","slug":"/container/components/cluster-stacks/components/csctl/quickstart","permalink":"/docs/container/components/cluster-stacks/components/csctl/quickstart","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/csctl/quickstart.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/container/components/cluster-stacks/components/csctl/overview"},"next":{"title":"Getting started","permalink":"/docs/container/components/cluster-stacks/components/csctl/getting_started"}}');var o=s(74848),c=s(28453);const a={},r="Quickstart",i={},l=[{value:"Installation",id:"installation",level:2},{value:"Creating Cluster Stacks",id:"creating-cluster-stacks",level:2},{value:"Different modes of csctl",id:"different-modes-of-csctl",level:2},{value:"Hash mode",id:"hash-mode",level:3},{value:"Stable mode",id:"stable-mode",level:3},{value:"Beta mode",id:"beta-mode",level:3},{value:"Custom mode",id:"custom-mode",level:3}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,c.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,o.jsx)(t.h2,{id:"installation",children:"Installation"}),"\n",(0,o.jsxs)(t.p,{children:["To download ",(0,o.jsx)(t.code,{children:"csctl"})," there are two ways.\nGo to ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/csctl/releases/latest",children:"https://github.com/SovereignCloudStack/csctl/releases/latest"})," and then click on the binary. The name of the binary looks similar to this ",(0,o.jsx)(t.code,{children:"csctl_0.0.3_linux_amd64.tar.gz"})," for Linux amd64 architecture."]}),"\n",(0,o.jsxs)(t.p,{children:["This will download the binary in your ",(0,o.jsx)(t.code,{children:"~/Downloads"})," directory. Use the following commands to move it to your PATH."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"tar xvzf ~/Downloads/csctl__linux_amd64.tar.gz\nchmod u+x ~/Downloads/csctl\nsudo mv ~/Downloads/csctl /usr/local/bin/csctl\n"})}),"\n",(0,o.jsxs)(t.p,{children:["Alternative way of installing the binary is to use ",(0,o.jsx)(t.code,{children:"[gh](https://github.com/cli/cli)"})," command line tool.\nUse the following command to download the latest binary from GitHub."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"gh release download -p 'csctl__linux_amd64.tar.gz' -R SovereignCloudStack/csctl\ntar xvzf csctl__linux_amd64.tar.gz\nchmod u+x csctl\nsudo mv ./csctl /usr/local/bin/csctl\n"})}),"\n",(0,o.jsx)(t.p,{children:"For darwin based systems, the steps are similar, you'll have to choose darwin based binaries instead of linux one mentioned above. You'll also need to update your destination directory."}),"\n",(0,o.jsx)(t.h2,{id:"creating-cluster-stacks",children:"Creating Cluster Stacks"}),"\n",(0,o.jsxs)(t.p,{children:["The most important subcommand is ",(0,o.jsx)(t.code,{children:"create"}),". This command takes a path to the directory where you configured your Cluster Stack and generates the necessary files in the output directory via the ",(0,o.jsx)(t.code,{children:"--output"})," flag:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"$ csctl create --output \n"})}),"\n",(0,o.jsxs)(t.p,{children:["You can specify your node image registry with the flag ",(0,o.jsx)(t.code,{children:"--node-image-registry"}),". The plugin of your provider will update the node images in the respective container registry."]}),"\n",(0,o.jsxs)(t.p,{children:["You can use the ",(0,o.jsx)(t.code,{children:"--mode"})," flag to specify the mode you want to use."]}),"\n",(0,o.jsx)(t.p,{children:"For example:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"$ csctl create --output --mode hash --node-image-registry \n"})}),"\n",(0,o.jsx)(t.p,{children:"You have to be authenticated to your cloud provider and container registry to which you want to upload the node images."}),"\n",(0,o.jsx)(t.h2,{id:"different-modes-of-csctl",children:"Different modes of csctl"}),"\n",(0,o.jsx)(t.p,{children:"The csctl has multiple modes that can be used for different use cases."}),"\n",(0,o.jsx)(t.h3,{id:"hash-mode",children:"Hash mode"}),"\n",(0,o.jsxs)(t.p,{children:["This mode is the most used one, as it allows quick iterations and testing of a cluster stack. It takes the hash of the content of the cluster stack and generates a semver version on this. You can combine it with the ",(0,o.jsx)(t.code,{children:"custom"})," channel of Cluster Stack Operator and test your Cluster Stacks easily!"]}),"\n",(0,o.jsx)(t.h3,{id:"stable-mode",children:"Stable mode"}),"\n",(0,o.jsx)(t.p,{children:'This mode checks for existing releases of cluster stacks and versions your cluster stack accordingly. If you have an existing release of "v1", then it would use "v2" for the new one. It also checks whether the node images and cluster addons have changed or not and will only update the versions if something actually changed.'}),"\n",(0,o.jsx)(t.h3,{id:"beta-mode",children:"Beta mode"}),"\n",(0,o.jsx)(t.p,{children:'Similar to stable mode, but for a beta release channel. It versions according to "v0-beta.1", etc.'}),"\n",(0,o.jsx)(t.h3,{id:"custom-mode",children:"Custom mode"}),"\n",(0,o.jsx)(t.p,{children:"The custom mode can be used to define your own version. You can input any semver version and your cluster stack will be versioned accordingly."})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>r});var n=s(96540);const o={},c=n.createContext(o);function a(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/320ccb30.4f011db4.js b/assets/js/320ccb30.4f011db4.js new file mode 100644 index 0000000000..74ad5584a9 --- /dev/null +++ b/assets/js/320ccb30.4f011db4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[67677],{18418:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"operating-scs/components/monitoring/docs/oauth","title":"OAUTH","description":"We set up oauth2 with GitHub provider for the https//kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/.","source":"@site/docs/04-operating-scs/components/monitoring/docs/oauth.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/oauth","permalink":"/docs/operating-scs/components/monitoring/docs/oauth","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/oauth.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Alertmanager notifications in Matrix chat","permalink":"/docs/operating-scs/components/monitoring/docs/alertmanager"},"next":{"title":"Traces","permalink":"/docs/operating-scs/components/monitoring/docs/tracing"}}');var o=t(74848),i=t(28453);const r={},a="OAUTH",c={},l=[];function d(e){const n={a:"a",code:"code",h1:"h1",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"oauth",children:"OAUTH"})}),"\n",(0,o.jsxs)(n.p,{children:["We set up oauth2 with GitHub provider for the ",(0,o.jsx)(n.a,{href:"https://monitoring.scs.community",children:"https://monitoring.scs.community"})," according to the ",(0,o.jsx)(n.a,{href:"https://kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/",children:"https://kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["To use it, inspect ",(0,o.jsx)(n.code,{children:"oauth/oauth2-proxy.yaml"})," and modify it according to your needs.\nYou want to change at least these:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"OAUTH2_PROXY_CLIENT_ID"}),"\n",(0,o.jsx)(n.li,{children:"OAUTH2_PROXY_CLIENT_SECRET"}),"\n",(0,o.jsx)(n.li,{children:"OAUTH2_PROXY_COOKIE_SECRET"}),"\n",(0,o.jsx)(n.li,{children:"ingress host"}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"Then deploy oauth2-proxy as follows:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f oauth/oauth2-proxy.yaml\n"})}),"\n",(0,o.jsx)(n.p,{children:"We set up OAuth authentication for these components:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Thanos Query","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"it is exposed via ingress on monitoring.scs.community/thanos"}),"\n",(0,o.jsxs)(n.li,{children:["modified with ",(0,o.jsx)(n.code,{children:"--web.external-prefix=thanos"})," extra flag","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"ruler query endpoint and grafana datasource url need to be modified"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["Alertmanager","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"it is exposed via ingress on monitoring.scs.community/alertmanager"}),"\n",(0,o.jsxs)(n.li,{children:["modified with ",(0,o.jsx)(n.code,{children:"routePrefix: /alertmanager"})," alertmanagerSpec","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"ruler alertmanager url needs to be modified"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["You have to also uncomment a related sections in ",(0,o.jsx)(n.code,{children:"values-observer.yaml"})," for exposing\nthe components via ingress.\nThe sections related to OAUTH in the ",(0,o.jsx)(n.code,{children:"values-observer-scs.yaml"})," values file are already uncommented."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const o={},i=s.createContext(o);function r(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/32227eef.57791a6a.js b/assets/js/32227eef.57791a6a.js new file mode 100644 index 0000000000..ddb435c0ca --- /dev/null +++ b/assets/js/32227eef.57791a6a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[53429],{84091:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>o});const t=JSON.parse('{"id":"scs-0003-v1-sovereign-cloud-standards-yaml","title":"Sovereign Cloud Standards YAML","description":"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,\\ncategorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning\\nin a machine-readable YAML format for clarity, traceability, and tool integration.\\n","source":"@site/standards/scs-0003-v1-sovereign-cloud-standards-yaml.md","sourceDirName":".","slug":"/scs-0003-v1-sovereign-cloud-standards-yaml","permalink":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Sovereign Cloud Standards YAML","type":"Procedural","status":"Draft","track":"Global","description":"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,\\ncategorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning\\nin a machine-readable YAML format for clarity, traceability, and tool integration.\\n"},"sidebar":"standards","previous":{"title":"scs-0003: Sovereign Cloud Standards YAML","permalink":"/standards/global/scs-0003"},"next":{"title":"scs-0004: Regulations for achieving SCS-compatible certification","permalink":"/standards/global/scs-0004"}}');var n=s(74848),r=s(28453);const d={title:"Sovereign Cloud Standards YAML",type:"Procedural",status:"Draft",track:"Global",description:"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,\ncategorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning\nin a machine-readable YAML format for clarity, traceability, and tool integration.\n"},c=void 0,a={},o=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Overview of mandatory SCS standards",id:"overview-of-mandatory-scs-standards",level:3},{value:"Lifecycle of certificate scopes",id:"lifecycle-of-certificate-scopes",level:3},{value:"Machine-readability for further processing",id:"machine-readability-for-further-processing",level:3},{value:"Basic concepts",id:"basic-concepts",level:2},{value:"SCS Certification YAML",id:"scs-certification-yaml",level:2},{value:"Prerequisite descriptor",id:"prerequisite-descriptor",level:3},{value:"Version descriptor",id:"version-descriptor",level:3},{value:"Include descriptor",id:"include-descriptor",level:4},{value:"Selector expressions",id:"selector-expressions",level:4},{value:"Module descriptor",id:"module-descriptor",level:3},{value:"Check descriptor",id:"check-descriptor",level:3},{value:"Automated check",id:"automated-check",level:4},{value:"Manual check",id:"manual-check",level:4},{value:"Test-case descriptor",id:"test-case-descriptor",level:3},{value:"Timeline entry",id:"timeline-entry",level:3},{value:"Process",id:"process",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"File format",id:"file-format",level:3},{value:"Dependency graph for certifications",id:"dependency-graph-for-certifications",level:3},{value:"Tooling",id:"tooling",level:2},{value:"Open Questions",id:"open-questions",level:2},{value:"Acknowledgements",id:"acknowledgements",level:2}];function l(e){const i={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",mermaid:"mermaid",ol:"ol",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsxs)(i.p,{children:["The ",(0,n.jsx)(i.a,{href:"https://scs.community",children:"Sovereign Cloud Stack (SCS)"})," provides standards for a range of cloud infrastructure types.\nIt strives for interoperable and sovereign cloud offerings which can be deployed and used by a wide range of organizations and individuals."]}),"\n",(0,n.jsx)(i.p,{children:"SCS plans to offer six kinds of certificates with varying scope. These scopes can be sorted into two dimensions:"}),"\n",(0,n.jsxs)(i.ol,{children:["\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.em,{children:"certification level"}),", of which there are three:","\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsx)(i.li,{children:"SCS-compatible"}),"\n",(0,n.jsx)(i.li,{children:"SCS-open"}),"\n",(0,n.jsx)(i.li,{children:"SCS-sovereign"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.em,{children:"cloud layer"}),", of which there are two:","\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsx)(i.li,{children:"infrastructure as a service (IaaS)"}),"\n",(0,n.jsx)(i.li,{children:"Kubernetes as a service (KaaS)"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(i.p,{children:["So, for instance, a certificate can have the scope ",(0,n.jsx)(i.em,{children:"SCS-compatible IaaS"})," or ",(0,n.jsx)(i.em,{children:"SCS-sovereign KaaS"}),".\nNote that we don't currently have separate certification layers for Operations and IAM.\nWe expect that tests for these aspects will exist, but be incorporated into the IaaS\nand KaaS layers."]}),"\n",(0,n.jsxs)(i.p,{children:['Each certificate scope amounts to a set of standards that have to be fulfilled by the cloud service in question in order for a certificate to be issued.\nIn addition, a certificate with a certain scope may only be issued if some other certificate is already held.\nCase in point: the certification levels are meant to be seen as a progression, where the upper levels build on the lower ones, and\nthe certificate for "SCS-open IaaS" will only be issued if a certificate for "SCS-compatible IaaS" is already held.\nWe say that the latter certificate is a ',(0,n.jsx)(i.em,{children:"prerequisite"})," of the former."]}),"\n",(0,n.jsx)(i.p,{children:"Naturally, as the state of the art progresses, so do our certificates. We keep track of the changes by means of versioning.\nThat is to say that each certificate scope can come in several versions, each one of them having its distinct timespan when it is in effect.\nFor instance, we might have"}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsx)(i.li,{children:"SCS-compatible IaaS v1, effective 2021-01-01 through 2023-10-31"}),"\n",(0,n.jsx)(i.li,{children:"SCS-compatible IaaS v2, effective 2023-03-23 through 2023-11-30"}),"\n"]}),"\n",(0,n.jsx)(i.p,{children:"and so on (but usually, we aim to keep at most two versions in effect, with an overlap of 4 to 6 weeks)."}),"\n",(0,n.jsx)(i.p,{children:"This decision record describes two main points:"}),"\n",(0,n.jsxs)(i.ol,{children:["\n",(0,n.jsx)(i.li,{children:"How we denote our certificate scopes by means of a YAML file."}),"\n",(0,n.jsx)(i.li,{children:"Our process for constructing and progressing the certificate scopes."}),"\n"]}),"\n",(0,n.jsx)(i.h2,{id:"motivation",children:"Motivation"}),"\n",(0,n.jsx)(i.p,{children:"This decision record establishes a mechanism (by means of the YAML file) with the following three main objectives:"}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsx)(i.li,{children:"to provide an overview of the mandatory standards for the different SCS certificate scopes"}),"\n",(0,n.jsx)(i.li,{children:"to make the lifecycle of certificate scopes traceable"}),"\n",(0,n.jsx)(i.li,{children:"to provide a machine-readable document for further processing (e.g. for a compliance tool suite or continuous integration)."}),"\n"]}),"\n",(0,n.jsx)(i.h3,{id:"overview-of-mandatory-scs-standards",children:"Overview of mandatory SCS standards"}),"\n",(0,n.jsx)(i.p,{children:"Digging through a repository of draft, stable, replaced and rejected standards becomes increasingly challenging with a growing number\ndocuments and decision records. A central document that lists all mandatory standards to acquire a certificate with a certain scope can\nresolve this issue. It provides clarity for providers as well as users and helps to understand the value\nproposition of SCS."}),"\n",(0,n.jsx)(i.h3,{id:"lifecycle-of-certificate-scopes",children:"Lifecycle of certificate scopes"}),"\n",(0,n.jsx)(i.p,{children:"Standards and therefore certifications will evolve over time. To provide transparency and traceability for the lifecycle of SCS certificate\nscopes, the whole history of our certifications should be recorded. Pre-notification of changes to our certificate scopes allows\nusers to adapt their environments or deployment automation to the new standards in advance."}),"\n",(0,n.jsx)(i.h3,{id:"machine-readability-for-further-processing",children:"Machine-readability for further processing"}),"\n",(0,n.jsx)(i.p,{children:"By providing a machine-readable document, we can generate web-friendly overviews of our certificate scopes as well as create a tool suite\nthat checks environments against all described standards."}),"\n",(0,n.jsx)(i.h2,{id:"basic-concepts",children:"Basic concepts"}),"\n",(0,n.jsx)(i.p,{children:"The introduction stated that a certificate scope amounts to a set of standards that have to be fulfilled by the cloud service in question in order for a certificate to be issued.\nWhile instructive, this view is still a bit simplified. Let's get more precise now by defining the following concepts."}),"\n",(0,n.jsxs)(i.ol,{children:["\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.em,{children:"(Test) subject"}),":\nThe cloud under test."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.em,{children:"Test case"})," (also spelled testcase in code):\nA statement about the subject that can be evaluated unambiguously to be either satisfied or not. The result is either ",(0,n.jsx)(i.code,{children:"PASS"})," or ",(0,n.jsx)(i.code,{children:"FAIL"}),", or\u2014if the test could not be performed\u2014",(0,n.jsx)(i.code,{children:"DNF"}),' (did not finish).\nA test case can be as simple as "the subject conforms to standard X", but a standard can also be decomposed into multiple test cases, which can then be reported on (also to the customers) individually.\nThis latter option has the advantage that we can show explicitly if the subject complies with optional parts of the standard.']}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.em,{children:"Check"}),":\nA script that determines and reports the results of certain test cases. The report is printed to stdout, and each test case is reported as a single line of the form ",(0,n.jsx)(i.code,{children:"testcase-id: [PASS/FAIL]"}),". The result ",(0,n.jsx)(i.code,{children:"DNF"})," is not reported. Lines of other forms are permissible and will be ignored.\nWe also occasionally extend the concept of ",(0,n.jsx)(i.em,{children:"check"})," to manual audits."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.em,{children:"Module"}),":\nA collection of test cases and corresponding checks, together with additional meta information such as the result lifetime, description, and a list of tags for a test case.\nUltimately, we aim to specify one module for each version of each standard: the module translates the standard into something measurable and, ideally, executable to be used for certification."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.em,{children:"Selector (expression)"}),":\nAn expression used to select test cases by referring to the tags that must (or must not) be present."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.em,{children:"Target"}),':\nA named collection of test cases specified using selector expressions.\nUltimately, the certification of a subject always depends on a designated "main" target; all its test cases must be passed for the certificate to be awarded.\nFurther targets can be used to report on optional aspects of the certificate, such as particularly good security and encryption measures.']}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.em,{children:"(Certificate-scope) version"}),':\nA collection of modules and a collection of targets, one of them being "main".\nNote that a collection of modules can again be construed as a (larger) module. We opt to use one module per standard version, as mentioned above, in order to make commonalities between certificate-scope versions explicit.']}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.em,{children:"Certificate scope"}),":\nA list of certificate-scope versions."]}),"\n"]}),"\n",(0,n.jsx)(i.p,{children:"Having introduced these concepts, we can now get even more precise by defining the actual specification in YAML format."}),"\n",(0,n.jsx)(i.h2,{id:"scs-certification-yaml",children:"SCS Certification YAML"}),"\n",(0,n.jsxs)(i.p,{children:["Each certificate scope is recorded in a dedicated YAML file, e.g. ",(0,n.jsx)(i.code,{children:"scs-open-kaas.yaml"}),".\nFor an example of such a file, see\n",(0,n.jsx)(i.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/scs-compatible-iaas.yaml",children:"scs-compatible-iaas.yaml"})," or\n",(0,n.jsx)(i.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/scs-compatible-kaas.yaml",children:"scs-compatible-kaas.yaml"}),"."]}),"\n",(0,n.jsxs)(i.p,{children:["The certification YAML ",(0,n.jsx)(i.em,{children:"MUST"})," contain the following keys:"]}),"\n",(0,n.jsxs)(i.table,{children:[(0,n.jsx)(i.thead,{children:(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.th,{children:"Key"}),(0,n.jsx)(i.th,{children:"Type"}),(0,n.jsx)(i.th,{children:"Description"}),(0,n.jsx)(i.th,{children:"Example"})]})}),(0,n.jsxs)(i.tbody,{children:[(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"uuid"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"Universally unique identifier"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"d912d0a5-826a-4b01-bafd-b48f65f76f43"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"name"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"Full name of this certificate scope"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"SCS-open KaaS"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"url"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"Valid URL to the latest raw version of this document"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/scs-open-kaas.yaml"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"modules"})}),(0,n.jsx)(i.td,{children:"Array of maps"}),(0,n.jsx)(i.td,{children:"List of module descriptors (described below)"}),(0,n.jsx)(i.td,{children:"(see below)"})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"timeline"})}),(0,n.jsx)(i.td,{children:"Array of maps"}),(0,n.jsx)(i.td,{children:"List of timeline entries (described below)"}),(0,n.jsx)(i.td,{children:"(see below)"})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"versions"})}),(0,n.jsx)(i.td,{children:"Array of maps"}),(0,n.jsx)(i.td,{children:"List of version descriptors (described below)"}),(0,n.jsx)(i.td,{children:"(see below)"})]})]})]}),"\n",(0,n.jsxs)(i.p,{children:["A uuid may be generated on the command line using the tool ",(0,n.jsx)(i.code,{children:"uuidgen"})," or using Python as follows: ",(0,n.jsx)(i.code,{children:'python3 -c "import uuid; print(uuid.uuid4())"'})]}),"\n",(0,n.jsxs)(i.p,{children:["The certification YAML ",(0,n.jsx)(i.em,{children:"MAY"})," contain the following keys:"]}),"\n",(0,n.jsxs)(i.table,{children:[(0,n.jsx)(i.thead,{children:(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.th,{children:"Key"}),(0,n.jsx)(i.th,{children:"Type"}),(0,n.jsx)(i.th,{children:"Description"})]})}),(0,n.jsxs)(i.tbody,{children:[(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"prerequisite"})}),(0,n.jsx)(i.td,{children:"Map"}),(0,n.jsx)(i.td,{children:"Descriptor for the prerequisite certificate scope (see below)"})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"variables"})}),(0,n.jsx)(i.td,{children:"Array of String"}),(0,n.jsx)(i.td,{children:"Lists variables that may occur in check tool descriptors"})]})]})]}),"\n",(0,n.jsx)(i.p,{children:"The main check tool will expect an assignment for these variables (which is specific to the subject under test), and every occurrence of the variable in the check tool descriptor will be substituted accordingly."}),"\n",(0,n.jsx)(i.h3,{id:"prerequisite-descriptor",children:"Prerequisite descriptor"}),"\n",(0,n.jsx)(i.p,{children:"A certificate within a certain level (above SCS-compatible) can only be granted if a valid corresponding certificate of the level below is presented,\nwhere corresponding means: of the same layer. The latter certificate is said to be a prerequisite for the former."}),"\n",(0,n.jsx)(i.p,{children:"We implement this logic by allowing for the designation of a certificate scope as a prerequisite;\nthen a certificate of that prerequisite scope has to be presented before the certificate of the scope in question can be granted."}),"\n",(0,n.jsxs)(i.table,{children:[(0,n.jsx)(i.thead,{children:(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.th,{children:"Key"}),(0,n.jsx)(i.th,{children:"Type"}),(0,n.jsx)(i.th,{children:"Description"}),(0,n.jsx)(i.th,{children:"Example"})]})}),(0,n.jsxs)(i.tbody,{children:[(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"name"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"Full name of the certificate scope"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"SCS-compatible IaaS"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"url"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"Valid URL to the latest raw version of the certificate scope"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/scs-compatible-iaas.yaml"})})]})]})]}),"\n",(0,n.jsx)(i.h3,{id:"version-descriptor",children:"Version descriptor"}),"\n",(0,n.jsxs)(i.table,{children:[(0,n.jsx)(i.thead,{children:(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.th,{children:"Key"}),(0,n.jsx)(i.th,{children:"Type"}),(0,n.jsx)(i.th,{children:"Description"}),(0,n.jsx)(i.th,{children:"Example"})]})}),(0,n.jsxs)(i.tbody,{children:[(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"version"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"required: version of the particular list of standards"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"v3"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"include"})}),(0,n.jsx)(i.td,{children:"Array"}),(0,n.jsx)(i.td,{children:"required: list of module ids or include descriptors (see below)"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"[scs-0100-v3]"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"targets"})}),(0,n.jsx)(i.td,{children:"Map of maps"}),(0,n.jsx)(i.td,{children:"required: this maps target names to selector expressions (explained below)"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"main: mandatory"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"stabilized_at"})}),(0,n.jsx)(i.td,{children:"Date"}),(0,n.jsx)(i.td,{children:"ISO formatted date indicating the date after this version is considered stable."}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"2022-11-09"})})]})]})]}),"\n",(0,n.jsxs)(i.p,{children:["The ids of the test cases of all the modules specified via ",(0,n.jsx)(i.code,{children:"include"})," MUST be pairwise different."]}),"\n",(0,n.jsxs)(i.p,{children:["Once a version descriptor has a ",(0,n.jsx)(i.code,{children:"stabilized_at"})," field, the version is deemed ",(0,n.jsx)(i.em,{children:"stable"}),", and the descriptor may no longer be changed."]}),"\n",(0,n.jsx)(i.h4,{id:"include-descriptor",children:"Include descriptor"}),"\n",(0,n.jsx)(i.p,{children:"Each include may be specified by means of a module id (i.e., a string) or by an include descriptor:"}),"\n",(0,n.jsxs)(i.table,{children:[(0,n.jsx)(i.thead,{children:(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.th,{children:"Key"}),(0,n.jsx)(i.th,{children:"Type"}),(0,n.jsx)(i.th,{children:"Description"}),(0,n.jsx)(i.th,{children:"Example"})]})}),(0,n.jsxs)(i.tbody,{children:[(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"ref"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"id of the module to be included"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"scs-0100-v3"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"parameters"})}),(0,n.jsx)(i.td,{children:"Map"}),(0,n.jsx)(i.td,{children:"Maps parameter names to parameter values"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"image_spec: https://raw.github...s/scs-0104-v1-images.yaml"})})]})]})]}),"\n",(0,n.jsx)(i.p,{children:"When the referenced module uses parameters, then these parameters must be assigned values here."}),"\n",(0,n.jsx)(i.h4,{id:"selector-expressions",children:"Selector expressions"}),"\n",(0,n.jsx)(i.p,{children:"In order to define what a selector expression is, we need to define tags, atoms and terms first."}),"\n",(0,n.jsxs)(i.p,{children:["A ",(0,n.jsx)(i.em,{children:"tag"})," is a string that does not contain any space, comma, forward slash, or exclamation mark."]}),"\n",(0,n.jsxs)(i.p,{children:["Examples: ",(0,n.jsx)(i.code,{children:"iaas"}),", ",(0,n.jsx)(i.code,{children:"mandatory"}),", ",(0,n.jsx)(i.code,{children:"recommended"}),", ",(0,n.jsx)(i.code,{children:"encryption"}),"."]}),"\n",(0,n.jsxs)(i.p,{children:["An ",(0,n.jsx)(i.em,{children:"atom"})," is a string that is either (i) a tag or (ii) an exclamation mark followed by tag.\nA list of tags ",(0,n.jsx)(i.em,{children:"satisfies"})," the atom if"]}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsx)(i.li,{children:"the atom is of form (i) and the tag is contained in the list, or"}),"\n",(0,n.jsx)(i.li,{children:"the atom is of form (ii) and the tag is not contained in the list."}),"\n"]}),"\n",(0,n.jsxs)(i.p,{children:["Examples: ",(0,n.jsx)(i.code,{children:"mandatory"}),", ",(0,n.jsx)(i.code,{children:"!mandatory"}),"."]}),"\n",(0,n.jsxs)(i.p,{children:["A ",(0,n.jsx)(i.em,{children:"term"})," is a string that is a non-empty list of atoms joined by slashes.\nA list of tags ",(0,n.jsx)(i.em,{children:"satisfies"})," the term if it satisfies at least one of the atoms."]}),"\n",(0,n.jsxs)(i.p,{children:["Examples: ",(0,n.jsx)(i.code,{children:"mandatory"}),", ",(0,n.jsx)(i.code,{children:"mandatory/recommended"}),", ",(0,n.jsx)(i.code,{children:"!mandatory/encryption"}),"."]}),"\n",(0,n.jsxs)(i.p,{children:["A ",(0,n.jsx)(i.em,{children:"selector (expression)"})," is a string that is a non-empty list of terms joined by space.\nA list of tags ",(0,n.jsx)(i.em,{children:"satisfies"})," the selector if it satisfies all the terms."]}),"\n",(0,n.jsxs)(i.p,{children:["Examples: ",(0,n.jsx)(i.code,{children:"mandatory"}),", ",(0,n.jsx)(i.code,{children:"iaas mandatory"}),", ",(0,n.jsx)(i.code,{children:"iaas !mandatory/encryption"}),"."]}),"\n",(0,n.jsxs)(i.p,{children:["In the map ",(0,n.jsx)(i.code,{children:"targets"})," above, it is possible to specify a list of selectors that are joined by comma.\n(Note that this is still a string, not a YAML list.)\nA list of tags satisfies this list of selectors if it satisfies at least one of the selectors."]}),"\n",(0,n.jsxs)(i.p,{children:["Examples: ",(0,n.jsx)(i.code,{children:"mandatory iaas, recommended kaas"})," (NOT: ",(0,n.jsx)(i.code,{children:"[mandatory iaas, recommended kaas]"}),")"]}),"\n",(0,n.jsx)(i.h3,{id:"module-descriptor",children:"Module descriptor"}),"\n",(0,n.jsxs)(i.table,{children:[(0,n.jsx)(i.thead,{children:(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.th,{children:"Key"}),(0,n.jsx)(i.th,{children:"Type"}),(0,n.jsx)(i.th,{children:"Description"}),(0,n.jsx)(i.th,{children:"Example"})]})}),(0,n.jsxs)(i.tbody,{children:[(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"id"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"id for referring to this module"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"scs-0100-v3"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"name"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"name of this module"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"Flavor naming v3"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"url"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"Valid URL to relevant documentation (usually a standard document)"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"https://docs.scs.community/standards/scs-0100-v3-flavor-naming"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"parameters"})}),(0,n.jsx)(i.td,{children:"List"}),(0,n.jsx)(i.td,{children:"List of parameters that the checks in this module might use"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"[image_spec]"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"run"})}),(0,n.jsx)(i.td,{children:"Array"}),(0,n.jsx)(i.td,{children:"List of all checks that should be run; each entry being a check descriptor"}),(0,n.jsx)(i.td,{children:"(see below)"})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"testcases"})}),(0,n.jsx)(i.td,{children:"Array"}),(0,n.jsx)(i.td,{children:"List of all test cases; each entry being a test-case descriptor"}),(0,n.jsx)(i.td,{children:"(see below)"})]})]})]}),"\n",(0,n.jsx)(i.p,{children:"The parameters specified here will be added to the variable assignment for all check tools that belong to this module, so they will be substituted in the same way.\nThe values to these parameters must be provided in the include descriptor as explained above."}),"\n",(0,n.jsx)(i.p,{children:"Using parameters offers two advantages:"}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsx)(i.li,{children:"they may show up in the automatically generated documentation, whereas the check tools themselves probably won't."}),"\n",(0,n.jsx)(i.li,{children:"multiple versions of a standard can be represented using the same module, if everything that changes between versions can be captured by the parameters."}),"\n"]}),"\n",(0,n.jsx)(i.h3,{id:"check-descriptor",children:"Check descriptor"}),"\n",(0,n.jsx)(i.p,{children:"The following fields are valid for every check descriptor:"}),"\n",(0,n.jsxs)(i.table,{children:[(0,n.jsx)(i.thead,{children:(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.th,{children:"Key"}),(0,n.jsx)(i.th,{children:"Type"}),(0,n.jsx)(i.th,{children:"Description"}),(0,n.jsx)(i.th,{children:"Example"})]})}),(0,n.jsx)(i.tbody,{children:(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"section"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsxs)(i.td,{children:[(0,n.jsx)(i.em,{children:"Optional"})," what section to associate this check with (sections can be checked in isolation)"]}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"weekly"})})]})})]}),"\n",(0,n.jsx)(i.p,{children:"Additional fields are valid depending on whether the check is automated or manual."}),"\n",(0,n.jsx)(i.h4,{id:"automated-check",children:"Automated check"}),"\n",(0,n.jsxs)(i.table,{children:[(0,n.jsx)(i.thead,{children:(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.th,{children:"Key"}),(0,n.jsx)(i.th,{children:"Type"}),(0,n.jsx)(i.th,{children:"Description"}),(0,n.jsx)(i.th,{children:"Example"})]})}),(0,n.jsxs)(i.tbody,{children:[(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"executable"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"Valid local filename (relative to the path of scs-compliance-check.py) of a script that verifies compliance with the particular standard"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.em,{children:"image-md-check.py"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"env"})}),(0,n.jsx)(i.td,{children:"Map"}),(0,n.jsxs)(i.td,{children:[(0,n.jsx)(i.em,{children:"Optional"})," key-value map of environment variables (values may use variables)"]}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"OS_CLOUD: {os_cloud}"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"args"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsxs)(i.td,{children:[(0,n.jsx)(i.em,{children:"Optional"})," command-line arguments to be passed to the ",(0,n.jsx)(i.code,{children:"check_tool"})," (may use variables)"]}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"-v -k {kubeconfig}"})})]})]})]}),"\n",(0,n.jsxs)(i.p,{children:["As mentioned, variables may be used within ",(0,n.jsx)(i.code,{children:"env"})," and ",(0,n.jsx)(i.code,{children:"args"}),"; they are enclosed in single braces, like so: ",(0,n.jsx)(i.code,{children:"{var}"}),".\nIf a brace is desired, it needs to be doubled: ",(0,n.jsx)(i.code,{children:"{{"})," will be turned into ",(0,n.jsx)(i.code,{children:"{"}),". When the main check tool is run,\neach occurrence of a variable will be substituted for according to the variable assignment for the subject under test."]}),"\n",(0,n.jsxs)(i.p,{children:[(0,n.jsx)(i.em,{children:"Note"}),": the ",(0,n.jsx)(i.code,{children:"executable"})," could in principle also be given via a URL; however, this is not yet supported due to security considerations."]}),"\n",(0,n.jsx)(i.h4,{id:"manual-check",children:"Manual check"}),"\n",(0,n.jsx)(i.p,{children:"TBD"}),"\n",(0,n.jsx)(i.h3,{id:"test-case-descriptor",children:"Test-case descriptor"}),"\n",(0,n.jsxs)(i.table,{children:[(0,n.jsx)(i.thead,{children:(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.th,{children:"Key"}),(0,n.jsx)(i.th,{children:"Type"}),(0,n.jsx)(i.th,{children:"Description"}),(0,n.jsx)(i.th,{children:"Example"})]})}),(0,n.jsxs)(i.tbody,{children:[(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"id"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"Identifier for this test case (immutable and unique within this module)"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"image-md-check"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"lifetime"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsxs)(i.td,{children:["One of: ",(0,n.jsx)(i.code,{children:"day"})," (",(0,n.jsx)(i.em,{children:"default"}),"), ",(0,n.jsx)(i.code,{children:"week"}),", ",(0,n.jsx)(i.code,{children:"month"}),", ",(0,n.jsx)(i.code,{children:"quarter"}),"; the test result is valid until the end of the next period"]}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"week"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"tags"})}),(0,n.jsx)(i.td,{children:"List of strings"}),(0,n.jsx)(i.td,{children:"A tag is a keyword that will be used to select this test case using a selector expression"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"[mandatory]"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"description"})}),(0,n.jsx)(i.td,{children:"String"}),(0,n.jsx)(i.td,{children:"Short description of the test case"}),(0,n.jsx)(i.td,{})]})]})]}),"\n",(0,n.jsx)(i.p,{children:"A tag MUST NOT contain any of these characters: space, comma, exclamation mark, forward slash."}),"\n",(0,n.jsxs)(i.p,{children:["The ",(0,n.jsx)(i.code,{children:"id"})," of a test case MUST NOT be changed.\nExceptions MAY be made if the test case is not referenced by any stable version."]}),"\n",(0,n.jsx)(i.h3,{id:"timeline-entry",children:"Timeline entry"}),"\n",(0,n.jsx)(i.p,{children:"The timeline is a list of timeline entries as detailed below. Each timeline entry represents a time period\nstarting at a given date and ending immediately before the chronologically next entry, if any, otherwise the\ntime period extends indefinitely. The list itself SHOULD be sorted by this date in descending order, however\ntooling MUST NOT depend on this order."}),"\n",(0,n.jsxs)(i.table,{children:[(0,n.jsx)(i.thead,{children:(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.th,{children:"Key"}),(0,n.jsx)(i.th,{children:"Type"}),(0,n.jsx)(i.th,{children:"Description"}),(0,n.jsx)(i.th,{children:"Example"})]})}),(0,n.jsxs)(i.tbody,{children:[(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"date"})}),(0,n.jsx)(i.td,{children:"Date"}),(0,n.jsx)(i.td,{children:"ISO formatted date indicating the date when this period begins."}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"2022-11-09"})})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"versions"})}),(0,n.jsx)(i.td,{children:"Map of strings"}),(0,n.jsx)(i.td,{children:"Maps versions to validity code"}),(0,n.jsx)(i.td,{children:(0,n.jsx)(i.code,{children:"v3: effective"})})]})]})]}),"\n",(0,n.jsx)(i.p,{children:"The following validity codes are recognized:"}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"effective"}),": the version can be certified against; it MUST be stable at the start of the period."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"warn"}),": the version can be certified against, but a PASS MUST be accompanied by a warning that the version\nis about to expire; the version MUST be stable at the start of the period."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"draft"}),": the version can be tested against, but not certified; the version need not be stable."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"deprecated"}),": the version can be tested against, but not certified."]}),"\n"]}),"\n",(0,n.jsxs)(i.p,{children:["Any version not listed in ",(0,n.jsx)(i.code,{children:"versions"})," is considered ",(0,n.jsx)(i.code,{children:"deprecated"}),"."]}),"\n",(0,n.jsxs)(i.p,{children:["If no other restriction is given, any version listed in ",(0,n.jsx)(i.code,{children:"version"})," SHOULD be tested against.\nThis includes any version listed as ",(0,n.jsx)(i.code,{children:"deprecated"}),"; the rationale here is that, while the test subject\ncan no longer be certified against it, some customers may still work with that version."]}),"\n",(0,n.jsx)(i.p,{children:"Note: Compliance with a new (effective) version often implies compliance with an older (deprecated) one.\nIncluding the older one into the test is meant to increase the confidence that this is indeed the case, or,\nif it isn't, serves to provide a clear picture of how many test subjects still comply with the old version."}),"\n",(0,n.jsx)(i.p,{children:"Note: We intend to keep only one version in effect, except for a grace period of 4 to 6 weeks, when two versions\nare effective at the same time."}),"\n",(0,n.jsx)(i.h2,{id:"process",children:"Process"}),"\n",(0,n.jsx)(i.p,{children:"The lifecycle any version of any certificate scope goes through the following phases:\nDraft and (optionally) Stable. The phase transition is performed using a pull request."}),"\n",(0,n.jsx)(i.mermaid,{value:"graph TD\n B[Draft] --\x3e|Pull Request| D[Stable]"}),"\n",(0,n.jsx)(i.p,{children:"The timeline is considered append-only (or rather, prepend-only). A new entry is added using\na pull request."}),"\n",(0,n.jsx)(i.p,{children:"It is possible to use the same pull request to add a new version, stabilize some version, and\nadd a new timeline entry, if so desired."}),"\n",(0,n.jsx)(i.p,{children:"Each pull request is to be voted upon in the corresponding team meeting. The vote has to be\non the pull request only, i.e., it may not affect any other pull request or issue, and it\nmust be announced 14 days in advance via the corresponding mailing list."}),"\n",(0,n.jsx)(i.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,n.jsx)(i.h3,{id:"file-format",children:"File format"}),"\n",(0,n.jsx)(i.p,{children:"In order to have a document that can be processed by a wide range of tools, we need to opt for a simple but yet well-supported format.\nYAML offers readability for humans as well as good support by many frameworks. Since YAML is heavily used in the cloud and container\ndomain, the choice is obvious."}),"\n",(0,n.jsx)(i.h3,{id:"dependency-graph-for-certifications",children:"Dependency graph for certifications"}),"\n",(0,n.jsx)(i.p,{children:"This standard only allows depending on exactly one certification, otherwise we would need to use a list of mappings. Since this is\nin accordance to the current plan of the SIG Standardization & Certification, we can safely ignore multiple dependency of\ncertification for now."}),"\n",(0,n.jsx)(i.h2,{id:"tooling",children:"Tooling"}),"\n",(0,n.jsxs)(i.p,{children:["The SCS repository Docs has a tool ",(0,n.jsx)(i.code,{children:"scs-compliance-check.py"})," in the ",(0,n.jsx)(i.code,{children:"Tests"})," directory\nwhich parses the SCS Certification YAML and then runs the tests referenced there, returning the results\nof the tests."]}),"\n",(0,n.jsx)(i.h2,{id:"open-questions",children:"Open Questions"}),"\n",(0,n.jsx)(i.h2,{id:"acknowledgements",children:"Acknowledgements"}),"\n",(0,n.jsxs)(i.p,{children:["This document is heavily inspired by the ",(0,n.jsx)(i.a,{href:"https://yml.publiccode.tools/",children:"publiccode.yml standard"}),", as published by the ",(0,n.jsx)(i.a,{href:"https://publiccode.net/",children:"Foundation for Public Code"}),"."]})]})}function h(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,i,s)=>{s.d(i,{R:()=>d,x:()=>c});var t=s(96540);const n={},r=t.createContext(n);function d(e){const i=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function c(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:d(e.components),t.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/32dcd940.91903a0a.js b/assets/js/32dcd940.91903a0a.js new file mode 100644 index 0000000000..1343f2e5a8 --- /dev/null +++ b/assets/js/32dcd940.91903a0a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[86],{66607:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/placement","title":"Placement","description":"* Placement admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/placement.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/placement","permalink":"/docs/iaas/guides/configuration-guide/openstack/placement","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/placement.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Placement"},"sidebar":"docs","previous":{"title":"Octavia","permalink":"/docs/iaas/guides/configuration-guide/openstack/octavia"},"next":{"title":"Skyline","permalink":"/docs/iaas/guides/configuration-guide/openstack/skyline"}}');var a=t(74848),c=t(28453);const s={sidebar_label:"Placement"},o="Placement",r={},l=[];function d(e){const n={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"placement",children:"Placement"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://docs.openstack.org/placement/latest/admin/index.html",children:"Placement admin guide"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://docs.openstack.org/placement/latest/configuration/index.html",children:"Placement configuration guide"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://docs.openstack.org/placement/latest/configuration/config.html",children:"Placement configuration reference"})}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>o});var i=t(96540);const a={},c=i.createContext(a);function s(e){const n=i.useContext(c);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),i.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3347.c5d6f453.js b/assets/js/3347.c5d6f453.js new file mode 100644 index 0000000000..3009385df1 --- /dev/null +++ b/assets/js/3347.c5d6f453.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3347],{44096:(e,t,a)=>{a.d(t,{in:()=>c,OU:()=>_,Ki:()=>M,kJ:()=>f,x:()=>l,e7:()=>u,J_:()=>x,Gx:()=>A});var n=a(96540),s=a(89532),r=a(36803),i=a(74848);function l(){const e=(0,r.A)(),t=e?.data?.blogMetadata;if(!t)throw new Error("useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context");return t}const o=n.createContext(null);function c(e){let{children:t,content:a,isBlogPostPage:s=!1}=e;const r=function(e){let{content:t,isBlogPostPage:a}=e;return(0,n.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:a})),[t,a])}({content:a,isBlogPostPage:s});return(0,i.jsx)(o.Provider,{value:r,children:t})}function u(){const e=(0,n.useContext)(o);if(null===e)throw new s.dV("BlogPostProvider");return e}var m=a(86025),h=a(44586);const d=e=>new Date(e).toISOString();function g(e){const t=e.map(v);return{author:1===t.length?t[0]:t}}function p(e,t,a){return e?{image:j({imageUrl:t(e,{absolute:!0}),caption:`title image for the blog post: ${a}`})}:{}}function f(e){const{siteConfig:t}=(0,h.A)(),{withBaseUrl:a}=(0,m.hH)(),{metadata:{blogDescription:n,blogTitle:s,permalink:r}}=e,i=`${t.url}${r}`;return{"@context":"https://schema.org","@type":"Blog","@id":i,mainEntityOfPage:i,headline:s,description:n,blogPost:e.items.map((e=>function(e,t,a){const{assets:n,frontMatter:s,metadata:r}=e,{date:i,title:l,description:o,lastUpdatedAt:c}=r,u=n.image??s.image,m=s.keywords??[],h=`${t.url}${r.permalink}`,f=c?d(c):void 0;return{"@type":"BlogPosting","@id":h,mainEntityOfPage:h,url:h,headline:l,name:l,description:o,datePublished:i,...f?{dateModified:f}:{},...g(r.authors),...p(u,a,l),...m?{keywords:m}:{}}}(e.content,t,a)))}}function x(){const e=l(),{assets:t,metadata:a}=u(),{siteConfig:n}=(0,h.A)(),{withBaseUrl:s}=(0,m.hH)(),{date:r,title:i,description:o,frontMatter:c,lastUpdatedAt:f}=a,x=t.image??c.image,v=c.keywords??[],j=f?d(f):void 0,b=`${n.url}${a.permalink}`;return{"@context":"https://schema.org","@type":"BlogPosting","@id":b,mainEntityOfPage:b,url:b,headline:i,name:i,description:o,datePublished:r,...j?{dateModified:j}:{},...g(a.authors),...p(x,s,i),...v?{keywords:v}:{},isPartOf:{"@type":"Blog","@id":`${n.url}${e.blogBasePath}`,name:e.blogTitle}}}function v(e){return{"@type":"Person",...e.name?{name:e.name}:{},...e.title?{description:e.title}:{},...e.url?{url:e.url}:{},...e.email?{email:e.email}:{},...e.imageURL?{image:e.imageURL}:{}}}function j(e){let{imageUrl:t,caption:a}=e;return{"@type":"ImageObject","@id":t,url:t,contentUrl:t,caption:a}}var b=a(56347),w=a(28774),N=a(31682),k=a(99169);function A(e){const{pathname:t}=(0,b.zy)();return(0,n.useMemo)((()=>e.filter((e=>function(e,t){return!(e.unlisted&&!(0,k.ys)(e.permalink,t))}(e,t)))),[e,t])}function M(e){const t=(0,N.$z)(e,(e=>`${new Date(e.date).getFullYear()}`)),a=Object.entries(t);return a.reverse(),a}function _(e){let{items:t,ulClassName:a,liClassName:n,linkClassName:s,linkActiveClassName:r}=e;return(0,i.jsx)("ul",{className:a,children:t.map((e=>(0,i.jsx)("li",{className:n,children:(0,i.jsx)(w.A,{isNavLink:!0,to:e.permalink,className:s,activeClassName:r,children:e.title})},e.permalink)))})}},56913:(e,t,a)=>{a.d(t,{A:()=>j});a(96540);var n=a(18215),s=a(28774),r=a(74848);const i="githubSvg_Uu4N";const l="xSvg_y3PF";const o=function(e){return(0,r.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...e,children:[(0,r.jsx)("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),(0,r.jsx)("path",{d:"M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0"}),(0,r.jsx)("path",{d:"M3.6 9h16.8"}),(0,r.jsx)("path",{d:"M3.6 15h16.8"}),(0,r.jsx)("path",{d:"M11.5 3a17 17 0 0 0 0 18"}),(0,r.jsx)("path",{d:"M12.5 3a17 17 0 0 1 0 18"})]})},c={authorSocials:"authorSocials_rSDt",authorSocialLink:"authorSocialLink_owbf",authorSocialIcon:"authorSocialIcon_XYv3"},u={twitter:{Icon:function(e){return(0,r.jsx)("svg",{viewBox:"0 0 256 209",width:"1em",height:"1em",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid",...e,children:(0,r.jsx)("path",{d:"M256 25.45c-9.42 4.177-19.542 7-30.166 8.27 10.845-6.5 19.172-16.793 23.093-29.057a105.183 105.183 0 0 1-33.351 12.745C205.995 7.201 192.346.822 177.239.822c-29.006 0-52.523 23.516-52.523 52.52 0 4.117.465 8.125 1.36 11.97-43.65-2.191-82.35-23.1-108.255-54.876-4.52 7.757-7.11 16.78-7.11 26.404 0 18.222 9.273 34.297 23.365 43.716a52.312 52.312 0 0 1-23.79-6.57c-.003.22-.003.44-.003.661 0 25.447 18.104 46.675 42.13 51.5a52.592 52.592 0 0 1-23.718.9c6.683 20.866 26.08 36.05 49.062 36.475-17.975 14.086-40.622 22.483-65.228 22.483-4.24 0-8.42-.249-12.529-.734 23.243 14.902 50.85 23.597 80.51 23.597 96.607 0 149.434-80.031 149.434-149.435 0-2.278-.05-4.543-.152-6.795A106.748 106.748 0 0 0 256 25.45",fill:"#55acee"})})},label:"Twitter"},github:{Icon:function(e){return(0,r.jsx)("svg",{viewBox:"0 0 256 250",width:"1em",height:"1em",...e,className:(0,n.A)(e.className,i),xmlns:"http://www.w3.org/2000/svg",style:{"--dark":"#000","--light":"#fff"},preserveAspectRatio:"xMidYMid",children:(0,r.jsx)("path",{d:"M128.001 0C57.317 0 0 57.307 0 128.001c0 56.554 36.676 104.535 87.535 121.46 6.397 1.185 8.746-2.777 8.746-6.158 0-3.052-.12-13.135-.174-23.83-35.61 7.742-43.124-15.103-43.124-15.103-5.823-14.795-14.213-18.73-14.213-18.73-11.613-7.944.876-7.78.876-7.78 12.853.902 19.621 13.19 19.621 13.19 11.417 19.568 29.945 13.911 37.249 10.64 1.149-8.272 4.466-13.92 8.127-17.116-28.431-3.236-58.318-14.212-58.318-63.258 0-13.975 5-25.394 13.188-34.358-1.329-3.224-5.71-16.242 1.24-33.874 0 0 10.749-3.44 35.21 13.121 10.21-2.836 21.16-4.258 32.038-4.307 10.878.049 21.837 1.47 32.066 4.307 24.431-16.56 35.165-13.12 35.165-13.12 6.967 17.63 2.584 30.65 1.255 33.873 8.207 8.964 13.173 20.383 13.173 34.358 0 49.163-29.944 59.988-58.447 63.157 4.591 3.972 8.682 11.762 8.682 23.704 0 17.126-.148 30.91-.148 35.126 0 3.407 2.304 7.398 8.792 6.14C219.37 232.5 256 184.537 256 128.002 256 57.307 198.691 0 128.001 0Zm-80.06 182.34c-.282.636-1.283.827-2.194.39-.929-.417-1.45-1.284-1.15-1.922.276-.655 1.279-.838 2.205-.399.93.418 1.46 1.293 1.139 1.931Zm6.296 5.618c-.61.566-1.804.303-2.614-.591-.837-.892-.994-2.086-.375-2.66.63-.566 1.787-.301 2.626.591.838.903 1 2.088.363 2.66Zm4.32 7.188c-.785.545-2.067.034-2.86-1.104-.784-1.138-.784-2.503.017-3.05.795-.547 2.058-.055 2.861 1.075.782 1.157.782 2.522-.019 3.08Zm7.304 8.325c-.701.774-2.196.566-3.29-.49-1.119-1.032-1.43-2.496-.726-3.27.71-.776 2.213-.558 3.315.49 1.11 1.03 1.45 2.505.701 3.27Zm9.442 2.81c-.31 1.003-1.75 1.459-3.199 1.033-1.448-.439-2.395-1.613-2.103-2.626.301-1.01 1.747-1.484 3.207-1.028 1.446.436 2.396 1.602 2.095 2.622Zm10.744 1.193c.036 1.055-1.193 1.93-2.715 1.95-1.53.034-2.769-.82-2.786-1.86 0-1.065 1.202-1.932 2.733-1.958 1.522-.03 2.768.818 2.768 1.868Zm10.555-.405c.182 1.03-.875 2.088-2.387 2.37-1.485.271-2.861-.365-3.05-1.386-.184-1.056.893-2.114 2.376-2.387 1.514-.263 2.868.356 3.061 1.403Z"})})},label:"GitHub"},stackoverflow:{Icon:function(e){return(0,r.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 169.61 200",width:"1em",height:"1em",...e,children:[(0,r.jsx)("path",{d:"M140.44 178.38v-48.65h21.61V200H0v-70.27h21.61v48.65z",fill:"#bcbbbb"}),(0,r.jsx)("path",{d:"M124.24 140.54l4.32-16.22-86.97-17.83-3.78 17.83zM49.7 82.16L130.72 120l7.56-16.22-81.02-37.83zm22.68-40l68.06 57.3 11.35-13.51-68.6-57.3-11.35 13.51zM116.14 0l-14.59 10.81 53.48 71.89 14.58-10.81zM37.81 162.16h86.43v-16.21H37.81z",fill:"#f48024"})]})},label:"Stack Overflow"},linkedin:{Icon:function(e){return(0,r.jsx)("svg",{width:"1em",height:"1em",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid",viewBox:"0 0 256 256",...e,children:(0,r.jsx)("path",{d:"M218.123 218.127h-37.931v-59.403c0-14.165-.253-32.4-19.728-32.4-19.756 0-22.779 15.434-22.779 31.369v60.43h-37.93V95.967h36.413v16.694h.51a39.907 39.907 0 0 1 35.928-19.733c38.445 0 45.533 25.288 45.533 58.186l-.016 67.013ZM56.955 79.27c-12.157.002-22.014-9.852-22.016-22.009-.002-12.157 9.851-22.014 22.008-22.016 12.157-.003 22.014 9.851 22.016 22.008A22.013 22.013 0 0 1 56.955 79.27m18.966 138.858H37.95V95.967h37.97v122.16ZM237.033.018H18.89C8.58-.098.125 8.161-.001 18.471v219.053c.122 10.315 8.576 18.582 18.89 18.474h218.144c10.336.128 18.823-8.139 18.966-18.474V18.454c-.147-10.33-8.635-18.588-18.966-18.453",fill:"#0A66C2"})})},label:"LinkedIn"},x:{Icon:function(e){return(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",fill:"none",viewBox:"0 0 1200 1227",...e,className:(0,n.A)(e.className,l),style:{"--dark":"#000","--light":"#fff"},children:(0,r.jsx)("path",{d:"M714.163 519.284 1160.89 0h-105.86L667.137 450.887 357.328 0H0l468.492 681.821L0 1226.37h105.866l409.625-476.152 327.181 476.152H1200L714.137 519.284h.026ZM569.165 687.828l-47.468-67.894-377.686-540.24h162.604l304.797 435.991 47.468 67.894 396.2 566.721H892.476L569.165 687.854v-.026Z"})})},label:"X"}};function m(e){let{platform:t,link:a}=e;const{Icon:i,label:l}=u[m=t]??{Icon:o,label:m};var m;return(0,r.jsx)(s.A,{className:c.authorSocialLink,href:a,title:l,children:(0,r.jsx)(i,{className:(0,n.A)(c.authorSocialLink)})})}function h(e){let{author:t}=e;const a=Object.entries(t.socials??{});return(0,r.jsx)("div",{className:c.authorSocials,children:a.map((e=>{let[t,a]=e;return(0,r.jsx)(m,{platform:t,link:a},t)}))})}var d=a(51107);const g={authorImage:"authorImage_XqGP","author-as-h1":"author-as-h1_n9oJ","author-as-h2":"author-as-h2_gXvM",authorDetails:"authorDetails_lV9A",authorName:"authorName_yefp",authorTitle:"authorTitle_nd0D",authorBlogPostCount:"authorBlogPostCount_iiJ5"};function p(e){return e.href?(0,r.jsx)(s.A,{...e}):(0,r.jsx)(r.Fragment,{children:e.children})}function f(e){let{title:t}=e;return(0,r.jsx)("small",{className:g.authorTitle,title:t,children:t})}function x(e){let{name:t,as:a}=e;return a?(0,r.jsx)(d.A,{as:a,className:g.authorName,children:t}):(0,r.jsx)("span",{className:g.authorName,children:t})}function v(e){let{count:t}=e;return(0,r.jsx)("span",{className:(0,n.A)(g.authorBlogPostCount),children:t})}function j(e){let{as:t,author:a,className:s,count:i}=e;const{name:l,title:o,url:c,imageURL:u,email:m,page:d}=a,j=d?.permalink||c||m&&`mailto:${m}`||void 0;return(0,r.jsxs)("div",{className:(0,n.A)("avatar margin-bottom--sm",s,g[`author-as-${t}`]),children:[u&&(0,r.jsx)(p,{href:j,className:"avatar__photo-link",children:(0,r.jsx)("img",{className:(0,n.A)("avatar__photo",g.authorImage),src:u,alt:l})}),(l||o)&&(0,r.jsxs)("div",{className:(0,n.A)("avatar__intro",g.authorDetails),children:[(0,r.jsxs)("div",{className:"avatar__name",children:[l&&(0,r.jsx)(p,{href:j,children:(0,r.jsx)(x,{name:l,as:t})}),void 0!==i&&(0,r.jsx)(v,{count:i})]}),!!o&&(0,r.jsx)(f,{title:o}),(0,r.jsx)(h,{author:a})]})]})}},28027:(e,t,a)=>{a.d(t,{A:()=>L});var n=a(96540),s=a(18215),r=a(59504),i=a(24581),l=a(21312),o=a(44096),c=a(6342),u=a(51107),m=a(74848);function h(e){let{year:t,yearGroupHeadingClassName:a,children:n}=e;return(0,m.jsxs)("div",{role:"group",children:[(0,m.jsx)(u.A,{as:"h3",className:a,children:t}),n]})}function d(e){let{items:t,yearGroupHeadingClassName:a,ListComponent:n}=e;if((0,c.p)().blog.sidebar.groupByYear){const e=(0,o.Ki)(t);return(0,m.jsx)(m.Fragment,{children:e.map((e=>{let[t,s]=e;return(0,m.jsx)(h,{year:t,yearGroupHeadingClassName:a,children:(0,m.jsx)(n,{items:s})},t)}))})}return(0,m.jsx)(n,{items:t})}const g=(0,n.memo)(d),p="sidebar_re4s",f="sidebarItemTitle_pO2u",x="sidebarItemList_Yudw",v="sidebarItem__DBe",j="sidebarItemLink_mo7H",b="sidebarItemLinkActive_I1ZP",w="yearGroupHeading_rMGB",N=e=>{let{items:t}=e;return(0,m.jsx)(o.OU,{items:t,ulClassName:(0,s.A)(x,"clean-list"),liClassName:v,linkClassName:j,linkActiveClassName:b})};function k(e){let{sidebar:t}=e;const a=(0,o.Gx)(t.items);return(0,m.jsx)("aside",{className:"col col--3",children:(0,m.jsxs)("nav",{className:(0,s.A)(p,"thin-scrollbar"),"aria-label":(0,l.T)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"}),children:[(0,m.jsx)("div",{className:(0,s.A)(f,"margin-bottom--md"),children:t.title}),(0,m.jsx)(g,{items:a,ListComponent:N,yearGroupHeadingClassName:w})]})})}const A=(0,n.memo)(k);var M=a(75600);const _={yearGroupHeading:"yearGroupHeading_QT03"},C=e=>{let{items:t}=e;return(0,m.jsx)(o.OU,{items:t,ulClassName:"menu__list",liClassName:"menu__list-item",linkClassName:"menu__link",linkActiveClassName:"menu__link--active"})};function y(e){let{sidebar:t}=e;const a=(0,o.Gx)(t.items);return(0,m.jsx)(g,{items:a,ListComponent:C,yearGroupHeadingClassName:_.yearGroupHeading})}function P(e){return(0,m.jsx)(M.GX,{component:y,props:e})}const B=(0,n.memo)(P);function I(e){let{sidebar:t}=e;const a=(0,i.l)();return t?.items.length?"mobile"===a?(0,m.jsx)(B,{sidebar:t}):(0,m.jsx)(A,{sidebar:t}):null}function L(e){const{sidebar:t,toc:a,children:n,...i}=e,l=t&&t.items.length>0;return(0,m.jsx)(r.A,{...i,children:(0,m.jsx)("div",{className:"container margin-vert--lg",children:(0,m.jsxs)("div",{className:"row",children:[(0,m.jsx)(I,{sidebar:t}),(0,m.jsx)("main",{className:(0,s.A)("col",{"col--7":l,"col--9 col--offset-1":!l}),children:n}),a&&(0,m.jsx)("div",{className:"col col--2",children:a})]})})})}},53465:(e,t,a)=>{a.d(t,{W:()=>c});var n=a(96540),s=a(44586);const r=["zero","one","two","few","many","other"];function i(e){return r.filter((t=>e.includes(t)))}const l={locale:"en",pluralForms:i(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,s.A)();return(0,n.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:i(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),l}}),[e])}function c(){const e=o();return{selectMessage:(t,a)=>function(e,t,a){const n=e.split("|");if(1===n.length)return n[0];n.length>a.pluralForms.length&&console.error(`For locale=${a.locale}, a maximum of ${a.pluralForms.length} plural forms are expected (${a.pluralForms.join(",")}), but the message contains ${n.length}: ${e}`);const s=a.select(t),r=a.pluralForms.indexOf(s);return n[Math.min(r,n.length-1)]}(a,t,e)}}}}]); \ No newline at end of file diff --git a/assets/js/343a1afc.cd8b95a6.js b/assets/js/343a1afc.cd8b95a6.js new file mode 100644 index 0000000000..459912e224 --- /dev/null +++ b/assets/js/343a1afc.cd8b95a6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[28965],{38735:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>l,frontMatter:()=>c,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"operating-scs/logging/index","title":"Overview","description":"TODO","source":"@site/docs/04-operating-scs/06-logging/index.md","sourceDirName":"04-operating-scs/06-logging","slug":"/operating-scs/logging/","permalink":"/docs/operating-scs/logging/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/06-logging/index.md","tags":[],"version":"current","frontMatter":{}}');var s=t(74848),r=t(28453);const c={},i="Overview",a={},d=[];function g(e){const n={h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,s.jsx)(n.p,{children:"TODO"})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(g,{...e})}):g(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var o=t(96540);const s={},r=o.createContext(s);function c(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/34c3e4b2.0ecfe87d.js b/assets/js/34c3e4b2.0ecfe87d.js new file mode 100644 index 0000000000..3fb5369477 --- /dev/null +++ b/assets/js/34c3e4b2.0ecfe87d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[40163],{76129:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>d,metadata:()=>r,toc:()=>o});const r=JSON.parse('{"id":"iaas/scs-0115","title":"scs-0115: Default Rules for Security Groups","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0115.md","sourceDirName":"iaas","slug":"/iaas/scs-0115","permalink":"/standards/iaas/scs-0115","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0114-v1-volume-type-standard"},"next":{"title":"V1","permalink":"/standards/scs-0115-v1-default-rules-for-security-groups"}}');var n=t(74848),a=t(28453);const d={},c="scs-0115: Default Rules for Security Groups",i={},o=[];function l(e){const s={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"scs-0115-default-rules-for-security-groups",children:"scs-0115: Default Rules for Security Groups"})}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Version"}),(0,n.jsx)(s.th,{children:"Type"}),(0,n.jsx)(s.th,{children:"State"}),(0,n.jsx)(s.th,{children:"stabilized"}),(0,n.jsx)(s.th,{children:"deprecated"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0115-v1-default-rules-for-security-groups",children:"scs-0115-v1"})}),(0,n.jsx)(s.td,{children:"Standard"}),(0,n.jsx)(s.td,{children:"Stable"}),(0,n.jsx)(s.td,{children:"2024-11-13"}),(0,n.jsx)(s.td,{children:"-"})]})})]})]})}function u(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>d,x:()=>c});var r=t(96540);const n={},a=r.createContext(n);function d(e){const s=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:d(e.components),r.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/34fc7a35.59c1b86e.js b/assets/js/34fc7a35.59c1b86e.js new file mode 100644 index 0000000000..60feaabc95 --- /dev/null +++ b/assets/js/34fc7a35.59c1b86e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[97399],{28478:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"container/components/cluster-stacks/components/csctl/overview","title":"Overview","description":"Introduction","source":"@site/docs/03-container/components/cluster-stacks/components/csctl/overview.md","sourceDirName":"03-container/components/cluster-stacks/components/csctl","slug":"/container/components/cluster-stacks/components/csctl/overview","permalink":"/docs/container/components/cluster-stacks/components/csctl/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/csctl/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Developer Guide","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop"},"next":{"title":"Quickstart","permalink":"/docs/container/components/cluster-stacks/components/csctl/quickstart"}}');var o=s(74848),c=s(28453);const r={},a="Overview",i={},l=[{value:"Introduction",id:"introduction",level:2},{value:"What does csctl do?",id:"what-does-csctl-do",level:2},{value:"Features of csctl",id:"features-of-csctl",level:2}];function d(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",...(0,c.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,o.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,o.jsxs)(t.p,{children:["The ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator",children:"Cluster Stack Operator"})," facilitates the usage of ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks",children:"Cluster Stacks"})," by automating all steps that can be automated. It takes Cluster Stacks release assets that consist mainly of two Helm charts, one to deploy in the management cluster, the other one to deploy in the workload clusters, as well as provider-specific node image (build) information."]}),"\n",(0,o.jsx)(t.p,{children:"Users can take existing releases of Cluster Stacks and the operator and will be able to create clusters easily."}),"\n",(0,o.jsx)(t.p,{children:"This project facilitates building node image artifacts and release assets that can be used with the Cluster Stack Operator."}),"\n",(0,o.jsx)(t.h2,{id:"what-does-csctl-do",children:"What does csctl do?"}),"\n",(0,o.jsx)(t.p,{children:"As a user, you can create clusters based on Cluster Stacks with the help of the Cluster Stack Operator. The operator needs certain files, e.g. to apply the required Helm charts, and to get the necessary information about the versions in the cluster stack."}),"\n",(0,o.jsx)(t.p,{children:"In order to not generate these files manually, this CLI tool takes a certain pre-defined directory structure, in which users can configure all necessary Helm charts and build scripts for node images, and generates the assets that the Cluster Stack Operator can process."}),"\n",(0,o.jsx)(t.p,{children:"Therefore, this tool can be used to configure Cluster Stacks and to test them with the Cluster Stack Operator. It can also be used to release stable releases of Cluster Stacks that can be published for a broader community."}),"\n",(0,o.jsx)(t.h2,{id:"features-of-csctl",children:"Features of csctl"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsx)(t.p,{children:"Testing and quick iterations\ncsctl is created with a single focus of building Cluster Stacks and testing them with Cluster Stack Operator quickly. This tool helps in doing quick iterations and facilitates testing Cluster Stacks."}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsx)(t.p,{children:"Versioning\nWhen configuring Cluster Stacks, it is necessary to put versions in the configuration, e.g. to version a Helm chart or node images. This process is facilitated by the csctl through its own templating and mechanism to generate the right version, based on the content hash (for testing) or on a previous version (stable or beta channel). Users only have to use the right templating and the csctl will do all the versioning automatically."}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsx)(t.p,{children:"Plugin mechanism for providers\nThe plugin mechanism of csctl allows providers to implement all provider-specific steps that are needed for this provider. This can contain a fully automated building and uploading process for node images, which can be referenced in the Cluster Stack (using the templating logic for versioning)."}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsx)(t.p,{children:"Automated testing of Cluster Stacks\nThe csctl enables automated testing of Cluster Stacks if integrated in a CI process that first builds all necessary files as well as node images (if needed) and then uses them to create a workload cluster based on the Cluster Stack."}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>a});var n=s(96540);const o={},c=n.createContext(o);function r(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/35860.bf296fec.js b/assets/js/35860.bf296fec.js new file mode 100644 index 0000000000..108701c50e --- /dev/null +++ b/assets/js/35860.bf296fec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[35860],{35860:(t,e,s)=>{s.d(e,{d:()=>st,f:()=>et,p:()=>r});var u=s(26312),i=s(86079),n=function(){var t=function(t,e,s,u){for(s=s||{},u=t.length;u--;s[t[u]]=e);return s},e=[1,4],s=[1,3],u=[1,5],i=[1,8,9,10,11,27,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],n=[2,2],r=[1,13],a=[1,14],c=[1,15],o=[1,16],l=[1,23],h=[1,25],A=[1,26],d=[1,27],p=[1,49],y=[1,48],E=[1,29],f=[1,30],g=[1,31],k=[1,32],D=[1,33],b=[1,44],F=[1,46],T=[1,42],C=[1,47],_=[1,43],B=[1,50],S=[1,45],m=[1,51],x=[1,52],v=[1,34],L=[1,35],I=[1,36],R=[1,37],$=[1,57],N=[1,8,9,10,11,27,32,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],O=[1,61],w=[1,60],P=[1,62],U=[8,9,11,73,75],V=[1,88],G=[1,93],M=[1,92],K=[1,89],Y=[1,85],j=[1,91],X=[1,87],z=[1,94],H=[1,90],W=[1,95],Q=[1,86],q=[8,9,10,11,73,75],Z=[8,9,10,11,44,73,75],J=[8,9,10,11,29,42,44,46,48,50,52,54,56,58,61,63,65,66,68,73,75,86,99,102,103,106,108,111,112,113],tt=[8,9,11,42,58,73,75,86,99,102,103,106,108,111,112,113],et=[42,58,86,99,102,103,106,108,111,112,113],st=[1,121],ut=[1,120],it=[1,128],nt=[1,142],rt=[1,143],at=[1,144],ct=[1,145],ot=[1,130],lt=[1,132],ht=[1,136],At=[1,137],dt=[1,138],pt=[1,139],yt=[1,140],Et=[1,141],ft=[1,146],gt=[1,147],kt=[1,126],Dt=[1,127],bt=[1,134],Ft=[1,129],Tt=[1,133],Ct=[1,131],_t=[8,9,10,11,27,32,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],Bt=[1,149],St=[8,9,11],mt=[8,9,10,11,14,42,58,86,102,103,106,108,111,112,113],xt=[1,169],vt=[1,165],Lt=[1,166],It=[1,170],Rt=[1,167],$t=[1,168],Nt=[75,113,116],Ot=[8,9,10,11,12,14,27,29,32,42,58,73,81,82,83,84,85,86,87,102,106,108,111,112,113],wt=[10,103],Pt=[31,47,49,51,53,55,60,62,64,65,67,69,113,114,115],Ut=[1,235],Vt=[1,233],Gt=[1,237],Mt=[1,231],Kt=[1,232],Yt=[1,234],jt=[1,236],Xt=[1,238],zt=[1,255],Ht=[8,9,11,103],Wt=[8,9,10,11,58,81,102,103,106,107,108,109],Qt={trace:function(){},yy:{},symbols_:{error:2,start:3,graphConfig:4,document:5,line:6,statement:7,SEMI:8,NEWLINE:9,SPACE:10,EOF:11,GRAPH:12,NODIR:13,DIR:14,FirstStmtSeparator:15,ending:16,endToken:17,spaceList:18,spaceListNewline:19,vertexStatement:20,separator:21,styleStatement:22,linkStyleStatement:23,classDefStatement:24,classStatement:25,clickStatement:26,subgraph:27,textNoTags:28,SQS:29,text:30,SQE:31,end:32,direction:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,link:39,node:40,styledVertex:41,AMP:42,vertex:43,STYLE_SEPARATOR:44,idString:45,DOUBLECIRCLESTART:46,DOUBLECIRCLEEND:47,PS:48,PE:49,"(-":50,"-)":51,STADIUMSTART:52,STADIUMEND:53,SUBROUTINESTART:54,SUBROUTINEEND:55,VERTEX_WITH_PROPS_START:56,"NODE_STRING[field]":57,COLON:58,"NODE_STRING[value]":59,PIPE:60,CYLINDERSTART:61,CYLINDEREND:62,DIAMOND_START:63,DIAMOND_STOP:64,TAGEND:65,TRAPSTART:66,TRAPEND:67,INVTRAPSTART:68,INVTRAPEND:69,linkStatement:70,arrowText:71,TESTSTR:72,START_LINK:73,edgeText:74,LINK:75,edgeTextToken:76,STR:77,MD_STR:78,textToken:79,keywords:80,STYLE:81,LINKSTYLE:82,CLASSDEF:83,CLASS:84,CLICK:85,DOWN:86,UP:87,textNoTagsToken:88,stylesOpt:89,"idString[vertex]":90,"idString[class]":91,CALLBACKNAME:92,CALLBACKARGS:93,HREF:94,LINK_TARGET:95,"STR[link]":96,"STR[tooltip]":97,alphaNum:98,DEFAULT:99,numList:100,INTERPOLATE:101,NUM:102,COMMA:103,style:104,styleComponent:105,NODE_STRING:106,UNIT:107,BRKT:108,PCT:109,idStringToken:110,MINUS:111,MULT:112,UNICODE_TEXT:113,TEXT:114,TAGSTART:115,EDGE_TEXT:116,alphaNumToken:117,direction_tb:118,direction_bt:119,direction_rl:120,direction_lr:121,$accept:0,$end:1},terminals_:{2:"error",8:"SEMI",9:"NEWLINE",10:"SPACE",11:"EOF",12:"GRAPH",13:"NODIR",14:"DIR",27:"subgraph",29:"SQS",31:"SQE",32:"end",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",42:"AMP",44:"STYLE_SEPARATOR",46:"DOUBLECIRCLESTART",47:"DOUBLECIRCLEEND",48:"PS",49:"PE",50:"(-",51:"-)",52:"STADIUMSTART",53:"STADIUMEND",54:"SUBROUTINESTART",55:"SUBROUTINEEND",56:"VERTEX_WITH_PROPS_START",57:"NODE_STRING[field]",58:"COLON",59:"NODE_STRING[value]",60:"PIPE",61:"CYLINDERSTART",62:"CYLINDEREND",63:"DIAMOND_START",64:"DIAMOND_STOP",65:"TAGEND",66:"TRAPSTART",67:"TRAPEND",68:"INVTRAPSTART",69:"INVTRAPEND",72:"TESTSTR",73:"START_LINK",75:"LINK",77:"STR",78:"MD_STR",81:"STYLE",82:"LINKSTYLE",83:"CLASSDEF",84:"CLASS",85:"CLICK",86:"DOWN",87:"UP",90:"idString[vertex]",91:"idString[class]",92:"CALLBACKNAME",93:"CALLBACKARGS",94:"HREF",95:"LINK_TARGET",96:"STR[link]",97:"STR[tooltip]",99:"DEFAULT",101:"INTERPOLATE",102:"NUM",103:"COMMA",106:"NODE_STRING",107:"UNIT",108:"BRKT",109:"PCT",111:"MINUS",112:"MULT",113:"UNICODE_TEXT",114:"TEXT",115:"TAGSTART",116:"EDGE_TEXT",118:"direction_tb",119:"direction_bt",120:"direction_rl",121:"direction_lr"},productions_:[0,[3,2],[5,0],[5,2],[6,1],[6,1],[6,1],[6,1],[6,1],[4,2],[4,2],[4,2],[4,3],[16,2],[16,1],[17,1],[17,1],[17,1],[15,1],[15,1],[15,2],[19,2],[19,2],[19,1],[19,1],[18,2],[18,1],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,9],[7,6],[7,4],[7,1],[7,2],[7,2],[7,1],[21,1],[21,1],[21,1],[20,3],[20,4],[20,2],[20,1],[40,1],[40,5],[41,1],[41,3],[43,4],[43,4],[43,6],[43,4],[43,4],[43,4],[43,8],[43,4],[43,4],[43,4],[43,6],[43,4],[43,4],[43,4],[43,4],[43,4],[43,1],[39,2],[39,3],[39,3],[39,1],[39,3],[74,1],[74,2],[74,1],[74,1],[70,1],[71,3],[30,1],[30,2],[30,1],[30,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[28,1],[28,2],[28,1],[28,1],[24,5],[25,5],[26,2],[26,4],[26,3],[26,5],[26,3],[26,5],[26,5],[26,7],[26,2],[26,4],[26,2],[26,4],[26,4],[26,6],[22,5],[23,5],[23,5],[23,9],[23,9],[23,7],[23,7],[100,1],[100,3],[89,1],[89,3],[104,1],[104,2],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[79,1],[79,1],[79,1],[79,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[76,1],[76,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[45,1],[45,2],[98,1],[98,2],[33,1],[33,1],[33,1],[33,1]],performAction:function(t,e,s,u,i,n,r){var a=n.length-1;switch(i){case 2:case 28:case 29:case 30:case 31:case 32:this.$=[];break;case 3:(!Array.isArray(n[a])||n[a].length>0)&&n[a-1].push(n[a]),this.$=n[a-1];break;case 4:case 176:case 49:case 71:case 174:this.$=n[a];break;case 11:u.setDirection("TB"),this.$="TB";break;case 12:u.setDirection(n[a-1]),this.$=n[a-1];break;case 27:this.$=n[a-1].nodes;break;case 33:this.$=u.addSubGraph(n[a-6],n[a-1],n[a-4]);break;case 34:this.$=u.addSubGraph(n[a-3],n[a-1],n[a-3]);break;case 35:this.$=u.addSubGraph(void 0,n[a-1],void 0);break;case 37:this.$=n[a].trim(),u.setAccTitle(this.$);break;case 38:case 39:this.$=n[a].trim(),u.setAccDescription(this.$);break;case 43:u.addLink(n[a-2].stmt,n[a],n[a-1]),this.$={stmt:n[a],nodes:n[a].concat(n[a-2].nodes)};break;case 44:u.addLink(n[a-3].stmt,n[a-1],n[a-2]),this.$={stmt:n[a-1],nodes:n[a-1].concat(n[a-3].nodes)};break;case 45:this.$={stmt:n[a-1],nodes:n[a-1]};break;case 46:this.$={stmt:n[a],nodes:n[a]};break;case 47:case 121:case 123:this.$=[n[a]];break;case 48:this.$=n[a-4].concat(n[a]);break;case 50:this.$=n[a-2],u.setClass(n[a-2],n[a]);break;case 51:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"square");break;case 52:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"doublecircle");break;case 53:this.$=n[a-5],u.addVertex(n[a-5],n[a-2],"circle");break;case 54:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"ellipse");break;case 55:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"stadium");break;case 56:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"subroutine");break;case 57:this.$=n[a-7],u.addVertex(n[a-7],n[a-1],"rect",void 0,void 0,void 0,Object.fromEntries([[n[a-5],n[a-3]]]));break;case 58:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"cylinder");break;case 59:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"round");break;case 60:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"diamond");break;case 61:this.$=n[a-5],u.addVertex(n[a-5],n[a-2],"hexagon");break;case 62:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"odd");break;case 63:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"trapezoid");break;case 64:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"inv_trapezoid");break;case 65:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"lean_right");break;case 66:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"lean_left");break;case 67:this.$=n[a],u.addVertex(n[a]);break;case 68:n[a-1].text=n[a],this.$=n[a-1];break;case 69:case 70:n[a-2].text=n[a-1],this.$=n[a-2];break;case 72:var c=u.destructLink(n[a],n[a-2]);this.$={type:c.type,stroke:c.stroke,length:c.length,text:n[a-1]};break;case 73:case 79:case 94:case 96:this.$={text:n[a],type:"text"};break;case 74:case 80:case 95:this.$={text:n[a-1].text+""+n[a],type:n[a-1].type};break;case 75:case 81:this.$={text:n[a],type:"string"};break;case 76:case 82:case 97:this.$={text:n[a],type:"markdown"};break;case 77:c=u.destructLink(n[a]);this.$={type:c.type,stroke:c.stroke,length:c.length};break;case 78:this.$=n[a-1];break;case 98:this.$=n[a-4],u.addClass(n[a-2],n[a]);break;case 99:this.$=n[a-4],u.setClass(n[a-2],n[a]);break;case 100:case 108:this.$=n[a-1],u.setClickEvent(n[a-1],n[a]);break;case 101:case 109:this.$=n[a-3],u.setClickEvent(n[a-3],n[a-2]),u.setTooltip(n[a-3],n[a]);break;case 102:this.$=n[a-2],u.setClickEvent(n[a-2],n[a-1],n[a]);break;case 103:this.$=n[a-4],u.setClickEvent(n[a-4],n[a-3],n[a-2]),u.setTooltip(n[a-4],n[a]);break;case 104:this.$=n[a-2],u.setLink(n[a-2],n[a]);break;case 105:this.$=n[a-4],u.setLink(n[a-4],n[a-2]),u.setTooltip(n[a-4],n[a]);break;case 106:this.$=n[a-4],u.setLink(n[a-4],n[a-2],n[a]);break;case 107:this.$=n[a-6],u.setLink(n[a-6],n[a-4],n[a]),u.setTooltip(n[a-6],n[a-2]);break;case 110:this.$=n[a-1],u.setLink(n[a-1],n[a]);break;case 111:this.$=n[a-3],u.setLink(n[a-3],n[a-2]),u.setTooltip(n[a-3],n[a]);break;case 112:this.$=n[a-3],u.setLink(n[a-3],n[a-2],n[a]);break;case 113:this.$=n[a-5],u.setLink(n[a-5],n[a-4],n[a]),u.setTooltip(n[a-5],n[a-2]);break;case 114:this.$=n[a-4],u.addVertex(n[a-2],void 0,void 0,n[a]);break;case 115:this.$=n[a-4],u.updateLink([n[a-2]],n[a]);break;case 116:this.$=n[a-4],u.updateLink(n[a-2],n[a]);break;case 117:this.$=n[a-8],u.updateLinkInterpolate([n[a-6]],n[a-2]),u.updateLink([n[a-6]],n[a]);break;case 118:this.$=n[a-8],u.updateLinkInterpolate(n[a-6],n[a-2]),u.updateLink(n[a-6],n[a]);break;case 119:this.$=n[a-6],u.updateLinkInterpolate([n[a-4]],n[a]);break;case 120:this.$=n[a-6],u.updateLinkInterpolate(n[a-4],n[a]);break;case 122:case 124:n[a-2].push(n[a]),this.$=n[a-2];break;case 126:this.$=n[a-1]+n[a];break;case 175:case 177:this.$=n[a-1]+""+n[a];break;case 178:this.$={stmt:"dir",value:"TB"};break;case 179:this.$={stmt:"dir",value:"BT"};break;case 180:this.$={stmt:"dir",value:"RL"};break;case 181:this.$={stmt:"dir",value:"LR"}}},table:[{3:1,4:2,9:e,10:s,12:u},{1:[3]},t(i,n,{5:6}),{4:7,9:e,10:s,12:u},{4:8,9:e,10:s,12:u},{13:[1,9],14:[1,10]},{1:[2,1],6:11,7:12,8:r,9:a,10:c,11:o,20:17,22:18,23:19,24:20,25:21,26:22,27:l,33:24,34:h,36:A,38:d,40:28,41:38,42:p,43:39,45:40,58:y,81:E,82:f,83:g,84:k,85:D,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x,118:v,119:L,120:I,121:R},t(i,[2,9]),t(i,[2,10]),t(i,[2,11]),{8:[1,54],9:[1,55],10:$,15:53,18:56},t(N,[2,3]),t(N,[2,4]),t(N,[2,5]),t(N,[2,6]),t(N,[2,7]),t(N,[2,8]),{8:O,9:w,11:P,21:58,39:59,70:63,73:[1,64],75:[1,65]},{8:O,9:w,11:P,21:66},{8:O,9:w,11:P,21:67},{8:O,9:w,11:P,21:68},{8:O,9:w,11:P,21:69},{8:O,9:w,11:P,21:70},{8:O,9:w,10:[1,71],11:P,21:72},t(N,[2,36]),{35:[1,73]},{37:[1,74]},t(N,[2,39]),t(U,[2,46],{18:75,10:$}),{10:[1,76]},{10:[1,77]},{10:[1,78]},{10:[1,79]},{14:V,42:G,58:M,77:[1,83],86:K,92:[1,80],94:[1,81],98:82,102:Y,103:j,106:X,108:z,111:H,112:W,113:Q,117:84},t(N,[2,178]),t(N,[2,179]),t(N,[2,180]),t(N,[2,181]),t(q,[2,47]),t(q,[2,49],{44:[1,96]}),t(Z,[2,67],{110:109,29:[1,97],42:p,46:[1,98],48:[1,99],50:[1,100],52:[1,101],54:[1,102],56:[1,103],58:y,61:[1,104],63:[1,105],65:[1,106],66:[1,107],68:[1,108],86:b,99:F,102:T,103:C,106:_,108:B,111:S,112:m,113:x}),t(J,[2,174]),t(J,[2,135]),t(J,[2,136]),t(J,[2,137]),t(J,[2,138]),t(J,[2,139]),t(J,[2,140]),t(J,[2,141]),t(J,[2,142]),t(J,[2,143]),t(J,[2,144]),t(J,[2,145]),t(i,[2,12]),t(i,[2,18]),t(i,[2,19]),{9:[1,110]},t(tt,[2,26],{18:111,10:$}),t(N,[2,27]),{40:112,41:38,42:p,43:39,45:40,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},t(N,[2,40]),t(N,[2,41]),t(N,[2,42]),t(et,[2,71],{71:113,60:[1,115],72:[1,114]}),{74:116,76:117,77:[1,118],78:[1,119],113:st,116:ut},t([42,58,60,72,86,99,102,103,106,108,111,112,113],[2,77]),t(N,[2,28]),t(N,[2,29]),t(N,[2,30]),t(N,[2,31]),t(N,[2,32]),{10:it,12:nt,14:rt,27:at,28:122,32:ct,42:ot,58:lt,73:ht,77:[1,124],78:[1,125],80:135,81:At,82:dt,83:pt,84:yt,85:Et,86:ft,87:gt,88:123,102:kt,106:Dt,108:bt,111:Ft,112:Tt,113:Ct},t(_t,n,{5:148}),t(N,[2,37]),t(N,[2,38]),t(U,[2,45],{42:Bt}),{42:p,45:150,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},{99:[1,151],100:152,102:[1,153]},{42:p,45:154,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},{42:p,45:155,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},t(St,[2,100],{10:[1,156],93:[1,157]}),{77:[1,158]},t(St,[2,108],{117:160,10:[1,159],14:V,42:G,58:M,86:K,102:Y,103:j,106:X,108:z,111:H,112:W,113:Q}),t(St,[2,110],{10:[1,161]}),t(mt,[2,176]),t(mt,[2,163]),t(mt,[2,164]),t(mt,[2,165]),t(mt,[2,166]),t(mt,[2,167]),t(mt,[2,168]),t(mt,[2,169]),t(mt,[2,170]),t(mt,[2,171]),t(mt,[2,172]),t(mt,[2,173]),{42:p,45:162,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},{30:163,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:171,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:173,48:[1,172],65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:174,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:175,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:176,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{106:[1,177]},{30:178,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:179,63:[1,180],65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:181,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:182,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:183,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},t(J,[2,175]),t(i,[2,20]),t(tt,[2,25]),t(U,[2,43],{18:184,10:$}),t(et,[2,68],{10:[1,185]}),{10:[1,186]},{30:187,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{75:[1,188],76:189,113:st,116:ut},t(Nt,[2,73]),t(Nt,[2,75]),t(Nt,[2,76]),t(Nt,[2,161]),t(Nt,[2,162]),{8:O,9:w,10:it,11:P,12:nt,14:rt,21:191,27:at,29:[1,190],32:ct,42:ot,58:lt,73:ht,80:135,81:At,82:dt,83:pt,84:yt,85:Et,86:ft,87:gt,88:192,102:kt,106:Dt,108:bt,111:Ft,112:Tt,113:Ct},t(Ot,[2,94]),t(Ot,[2,96]),t(Ot,[2,97]),t(Ot,[2,150]),t(Ot,[2,151]),t(Ot,[2,152]),t(Ot,[2,153]),t(Ot,[2,154]),t(Ot,[2,155]),t(Ot,[2,156]),t(Ot,[2,157]),t(Ot,[2,158]),t(Ot,[2,159]),t(Ot,[2,160]),t(Ot,[2,83]),t(Ot,[2,84]),t(Ot,[2,85]),t(Ot,[2,86]),t(Ot,[2,87]),t(Ot,[2,88]),t(Ot,[2,89]),t(Ot,[2,90]),t(Ot,[2,91]),t(Ot,[2,92]),t(Ot,[2,93]),{6:11,7:12,8:r,9:a,10:c,11:o,20:17,22:18,23:19,24:20,25:21,26:22,27:l,32:[1,193],33:24,34:h,36:A,38:d,40:28,41:38,42:p,43:39,45:40,58:y,81:E,82:f,83:g,84:k,85:D,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x,118:v,119:L,120:I,121:R},{10:$,18:194},{10:[1,195],42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:109,111:S,112:m,113:x},{10:[1,196]},{10:[1,197],103:[1,198]},t(wt,[2,121]),{10:[1,199],42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:109,111:S,112:m,113:x},{10:[1,200],42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:109,111:S,112:m,113:x},{77:[1,201]},t(St,[2,102],{10:[1,202]}),t(St,[2,104],{10:[1,203]}),{77:[1,204]},t(mt,[2,177]),{77:[1,205],95:[1,206]},t(q,[2,50],{110:109,42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,111:S,112:m,113:x}),{31:[1,207],65:xt,79:208,113:It,114:Rt,115:$t},t(Pt,[2,79]),t(Pt,[2,81]),t(Pt,[2,82]),t(Pt,[2,146]),t(Pt,[2,147]),t(Pt,[2,148]),t(Pt,[2,149]),{47:[1,209],65:xt,79:208,113:It,114:Rt,115:$t},{30:210,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{49:[1,211],65:xt,79:208,113:It,114:Rt,115:$t},{51:[1,212],65:xt,79:208,113:It,114:Rt,115:$t},{53:[1,213],65:xt,79:208,113:It,114:Rt,115:$t},{55:[1,214],65:xt,79:208,113:It,114:Rt,115:$t},{58:[1,215]},{62:[1,216],65:xt,79:208,113:It,114:Rt,115:$t},{64:[1,217],65:xt,79:208,113:It,114:Rt,115:$t},{30:218,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{31:[1,219],65:xt,79:208,113:It,114:Rt,115:$t},{65:xt,67:[1,220],69:[1,221],79:208,113:It,114:Rt,115:$t},{65:xt,67:[1,223],69:[1,222],79:208,113:It,114:Rt,115:$t},t(U,[2,44],{42:Bt}),t(et,[2,70]),t(et,[2,69]),{60:[1,224],65:xt,79:208,113:It,114:Rt,115:$t},t(et,[2,72]),t(Nt,[2,74]),{30:225,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},t(_t,n,{5:226}),t(Ot,[2,95]),t(N,[2,35]),{41:227,42:p,43:39,45:40,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},{10:Ut,58:Vt,81:Gt,89:228,102:Mt,104:229,105:230,106:Kt,107:Yt,108:jt,109:Xt},{10:Ut,58:Vt,81:Gt,89:239,101:[1,240],102:Mt,104:229,105:230,106:Kt,107:Yt,108:jt,109:Xt},{10:Ut,58:Vt,81:Gt,89:241,101:[1,242],102:Mt,104:229,105:230,106:Kt,107:Yt,108:jt,109:Xt},{102:[1,243]},{10:Ut,58:Vt,81:Gt,89:244,102:Mt,104:229,105:230,106:Kt,107:Yt,108:jt,109:Xt},{42:p,45:245,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},t(St,[2,101]),{77:[1,246]},{77:[1,247],95:[1,248]},t(St,[2,109]),t(St,[2,111],{10:[1,249]}),t(St,[2,112]),t(Z,[2,51]),t(Pt,[2,80]),t(Z,[2,52]),{49:[1,250],65:xt,79:208,113:It,114:Rt,115:$t},t(Z,[2,59]),t(Z,[2,54]),t(Z,[2,55]),t(Z,[2,56]),{106:[1,251]},t(Z,[2,58]),t(Z,[2,60]),{64:[1,252],65:xt,79:208,113:It,114:Rt,115:$t},t(Z,[2,62]),t(Z,[2,63]),t(Z,[2,65]),t(Z,[2,64]),t(Z,[2,66]),t([10,42,58,86,99,102,103,106,108,111,112,113],[2,78]),{31:[1,253],65:xt,79:208,113:It,114:Rt,115:$t},{6:11,7:12,8:r,9:a,10:c,11:o,20:17,22:18,23:19,24:20,25:21,26:22,27:l,32:[1,254],33:24,34:h,36:A,38:d,40:28,41:38,42:p,43:39,45:40,58:y,81:E,82:f,83:g,84:k,85:D,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x,118:v,119:L,120:I,121:R},t(q,[2,48]),t(St,[2,114],{103:zt}),t(Ht,[2,123],{105:256,10:Ut,58:Vt,81:Gt,102:Mt,106:Kt,107:Yt,108:jt,109:Xt}),t(Wt,[2,125]),t(Wt,[2,127]),t(Wt,[2,128]),t(Wt,[2,129]),t(Wt,[2,130]),t(Wt,[2,131]),t(Wt,[2,132]),t(Wt,[2,133]),t(Wt,[2,134]),t(St,[2,115],{103:zt}),{10:[1,257]},t(St,[2,116],{103:zt}),{10:[1,258]},t(wt,[2,122]),t(St,[2,98],{103:zt}),t(St,[2,99],{110:109,42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,111:S,112:m,113:x}),t(St,[2,103]),t(St,[2,105],{10:[1,259]}),t(St,[2,106]),{95:[1,260]},{49:[1,261]},{60:[1,262]},{64:[1,263]},{8:O,9:w,11:P,21:264},t(N,[2,34]),{10:Ut,58:Vt,81:Gt,102:Mt,104:265,105:230,106:Kt,107:Yt,108:jt,109:Xt},t(Wt,[2,126]),{14:V,42:G,58:M,86:K,98:266,102:Y,103:j,106:X,108:z,111:H,112:W,113:Q,117:84},{14:V,42:G,58:M,86:K,98:267,102:Y,103:j,106:X,108:z,111:H,112:W,113:Q,117:84},{95:[1,268]},t(St,[2,113]),t(Z,[2,53]),{30:269,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},t(Z,[2,61]),t(_t,n,{5:270}),t(Ht,[2,124],{105:256,10:Ut,58:Vt,81:Gt,102:Mt,106:Kt,107:Yt,108:jt,109:Xt}),t(St,[2,119],{117:160,10:[1,271],14:V,42:G,58:M,86:K,102:Y,103:j,106:X,108:z,111:H,112:W,113:Q}),t(St,[2,120],{117:160,10:[1,272],14:V,42:G,58:M,86:K,102:Y,103:j,106:X,108:z,111:H,112:W,113:Q}),t(St,[2,107]),{31:[1,273],65:xt,79:208,113:It,114:Rt,115:$t},{6:11,7:12,8:r,9:a,10:c,11:o,20:17,22:18,23:19,24:20,25:21,26:22,27:l,32:[1,274],33:24,34:h,36:A,38:d,40:28,41:38,42:p,43:39,45:40,58:y,81:E,82:f,83:g,84:k,85:D,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x,118:v,119:L,120:I,121:R},{10:Ut,58:Vt,81:Gt,89:275,102:Mt,104:229,105:230,106:Kt,107:Yt,108:jt,109:Xt},{10:Ut,58:Vt,81:Gt,89:276,102:Mt,104:229,105:230,106:Kt,107:Yt,108:jt,109:Xt},t(Z,[2,57]),t(N,[2,33]),t(St,[2,117],{103:zt}),t(St,[2,118],{103:zt})],defaultActions:{},parseError:function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},parse:function(t){var e=this,s=[0],u=[],i=[null],n=[],r=this.table,a="",c=0,o=0,l=n.slice.call(arguments,1),h=Object.create(this.lexer),A={yy:{}};for(var d in this.yy)Object.prototype.hasOwnProperty.call(this.yy,d)&&(A.yy[d]=this.yy[d]);h.setInput(t,A.yy),A.yy.lexer=h,A.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var p=h.yylloc;n.push(p);var y=h.options&&h.options.ranges;"function"==typeof A.yy.parseError?this.parseError=A.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var E,f,g,k,D,b,F,T,C,_={};;){if(f=s[s.length-1],this.defaultActions[f]?g=this.defaultActions[f]:(null==E&&(C=void 0,"number"!=typeof(C=u.pop()||h.lex()||1)&&(C instanceof Array&&(C=(u=C).pop()),C=e.symbols_[C]||C),E=C),g=r[f]&&r[f][E]),void 0===g||!g.length||!g[0]){var B="";for(D in T=[],r[f])this.terminals_[D]&&D>2&&T.push("'"+this.terminals_[D]+"'");B=h.showPosition?"Parse error on line "+(c+1)+":\n"+h.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[E]||E)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==E?"end of input":"'"+(this.terminals_[E]||E)+"'"),this.parseError(B,{text:h.match,token:this.terminals_[E]||E,line:h.yylineno,loc:p,expected:T})}if(g[0]instanceof Array&&g.length>1)throw new Error("Parse Error: multiple actions possible at state: "+f+", token: "+E);switch(g[0]){case 1:s.push(E),i.push(h.yytext),n.push(h.yylloc),s.push(g[1]),E=null,o=h.yyleng,a=h.yytext,c=h.yylineno,p=h.yylloc;break;case 2:if(b=this.productions_[g[1]][1],_.$=i[i.length-b],_._$={first_line:n[n.length-(b||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(b||1)].first_column,last_column:n[n.length-1].last_column},y&&(_._$.range=[n[n.length-(b||1)].range[0],n[n.length-1].range[1]]),void 0!==(k=this.performAction.apply(_,[a,o,c,A.yy,g[1],i,n].concat(l))))return k;b&&(s=s.slice(0,-1*b*2),i=i.slice(0,-1*b),n=n.slice(0,-1*b)),s.push(this.productions_[g[1]][0]),i.push(_.$),n.push(_._$),F=r[s[s.length-2]][s[s.length-1]],s.push(F);break;case 3:return!0}}return!0}},qt={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var u=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===u.length?this.yylloc.first_column:0)+u[u.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var s,u,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(u=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=u.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:u?u[u.length-1].length-u[u.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var n in i)this[n]=i[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,s,u;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),n=0;ne[0].length)){if(e=s,u=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,i[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[u]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,s,u){switch(s){case 0:return this.begin("acc_title"),34;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),36;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:case 8:case 11:case 14:case 17:case 27:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:this.begin("callbackname");break;case 9:this.popState(),this.begin("callbackargs");break;case 10:return 92;case 12:return 93;case 13:return"MD_STR";case 15:this.begin("md_string");break;case 16:return"STR";case 18:this.pushState("string");break;case 19:return 81;case 20:return 99;case 21:return 82;case 22:return 101;case 23:return 83;case 24:return 84;case 25:return 94;case 26:this.begin("click");break;case 28:return 85;case 29:case 30:case 31:return t.lex.firstGraph()&&this.begin("dir"),12;case 32:return 27;case 33:return 32;case 34:case 35:case 36:case 37:return 95;case 38:return this.popState(),13;case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 48:return this.popState(),14;case 49:return 118;case 50:return 119;case 51:return 120;case 52:return 121;case 53:return 102;case 54:case 95:return 108;case 55:return 44;case 56:return 58;case 57:case 96:return 42;case 58:return 8;case 59:return 103;case 60:case 94:return 112;case 61:case 64:case 67:return this.popState(),75;case 62:return this.pushState("edgeText"),73;case 63:case 66:case 69:return 116;case 65:return this.pushState("thickEdgeText"),73;case 68:return this.pushState("dottedEdgeText"),73;case 70:return 75;case 71:return this.popState(),51;case 72:case 108:return"TEXT";case 73:return this.pushState("ellipseText"),50;case 74:return this.popState(),53;case 75:return this.pushState("text"),52;case 76:return this.popState(),55;case 77:return this.pushState("text"),54;case 78:return 56;case 79:return this.pushState("text"),65;case 80:return this.popState(),62;case 81:return this.pushState("text"),61;case 82:return this.popState(),47;case 83:return this.pushState("text"),46;case 84:return this.popState(),67;case 85:return this.popState(),69;case 86:return 114;case 87:return this.pushState("trapText"),66;case 88:return this.pushState("trapText"),68;case 89:return 115;case 90:return 65;case 91:return 87;case 92:return"SEP";case 93:return 86;case 97:return 106;case 98:return 111;case 99:return 113;case 100:return this.popState(),60;case 101:return this.pushState("text"),60;case 102:return this.popState(),49;case 103:return this.pushState("text"),48;case 104:return this.popState(),31;case 105:return this.pushState("text"),29;case 106:return this.popState(),64;case 107:return this.pushState("text"),63;case 109:return"QUOTE";case 110:return 9;case 111:return 10;case 112:return 11}},rules:[/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["][`])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:["])/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s])/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:flowchart-elk\b)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:[^-]|-(?!-)+)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:[^=]|=(?!))/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:[^\.]|\.(?!))/,/^(?:\s*~~[\~]+\s*)/,/^(?:[-/\)][\)])/,/^(?:[^\(\)\[\]\{\}]|!\)+)/,/^(?:\(-)/,/^(?:\]\))/,/^(?:\(\[)/,/^(?:\]\])/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:>)/,/^(?:\)\])/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\(\(\()/,/^(?:[\\(?=\])][\]])/,/^(?:\/(?=\])\])/,/^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:\*)/,/^(?:#)/,/^(?:&)/,/^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/,/^(?:-)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\|)/,/^(?:\))/,/^(?:\()/,/^(?:\])/,/^(?:\[)/,/^(?:(\}))/,/^(?:\{)/,/^(?:[^\[\]\(\)\{\}\|\"]+)/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{callbackargs:{rules:[11,12,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},callbackname:{rules:[8,9,10,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},href:{rules:[15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},click:{rules:[15,18,27,28,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},dottedEdgeText:{rules:[15,18,67,69,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},thickEdgeText:{rules:[15,18,64,66,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},edgeText:{rules:[15,18,61,63,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},trapText:{rules:[15,18,70,73,75,77,81,83,84,85,86,87,88,101,103,105,107],inclusive:!1},ellipseText:{rules:[15,18,70,71,72,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},text:{rules:[15,18,70,73,74,75,76,77,80,81,82,83,87,88,100,101,102,103,104,105,106,107,108],inclusive:!1},vertex:{rules:[15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},dir:{rules:[15,18,38,39,40,41,42,43,44,45,46,47,48,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},acc_descr_multiline:{rules:[5,6,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},acc_descr:{rules:[3,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},acc_title:{rules:[1,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},md_string:{rules:[13,14,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},string:{rules:[15,16,17,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},INITIAL:{rules:[0,2,4,7,15,18,19,20,21,22,23,24,25,26,29,30,31,32,33,34,35,36,37,49,50,51,52,53,54,55,56,57,58,59,60,61,62,64,65,67,68,70,73,75,77,78,79,81,83,87,88,89,90,91,92,93,94,95,96,97,98,99,101,103,105,107,109,110,111,112],inclusive:!0}}};function Zt(){this.yy={}}return Qt.lexer=qt,Zt.prototype=Qt,Qt.Parser=Zt,new Zt}();n.parser=n;const r=n;let a,c,o=0,l=(0,i.c)(),h={},A=[],d={},p=[],y={},E={},f=0,g=!0,k=[];const D=t=>i.e.sanitizeText(t,l),b=function(t){const e=Object.keys(h);for(const s of e)if(h[s].id===t)return h[s].domId;return t},F=function(t,e,s,u,n,r,a={}){let c,A=t;void 0!==A&&0!==A.trim().length&&(void 0===h[A]&&(h[A]={id:A,labelType:"text",domId:"flowchart-"+A+"-"+o,styles:[],classes:[]}),o++,void 0!==e?(l=(0,i.c)(),c=D(e.text.trim()),h[A].labelType=e.type,'"'===c[0]&&'"'===c[c.length-1]&&(c=c.substring(1,c.length-1)),h[A].text=c):void 0===h[A].text&&(h[A].text=t),void 0!==s&&(h[A].type=s),null!=u&&u.forEach((function(t){h[A].styles.push(t)})),null!=n&&n.forEach((function(t){h[A].classes.push(t)})),void 0!==r&&(h[A].dir=r),void 0===h[A].props?h[A].props=a:void 0!==a&&Object.assign(h[A].props,a))},T=function(t,e,s){const u={start:t,end:e,type:void 0,text:"",labelType:"text"};i.l.info("abc78 Got edge...",u);const n=s.text;if(void 0!==n&&(u.text=D(n.text.trim()),'"'===u.text[0]&&'"'===u.text[u.text.length-1]&&(u.text=u.text.substring(1,u.text.length-1)),u.labelType=n.type),void 0!==s&&(u.type=s.type,u.stroke=s.stroke,u.length=s.length),(null==u?void 0:u.length)>10&&(u.length=10),!(A.length<(l.maxEdges??500)))throw new Error(`Edge limit exceeded. ${A.length} edges found, but the limit is ${l.maxEdges}.\n\nInitialize mermaid with maxEdges set to a higher number to allow more edges.\nYou cannot set this config via configuration inside the diagram as it is a secure config.\nYou have to call mermaid.initialize.`);i.l.info("abc78 pushing edge..."),A.push(u)},C=function(t,e,s){let u,n;for(i.l.info("addLink (abc78)",t,e,s),u=0;u=A.length)throw new Error(`The index ${t} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${A.length-1}. (Help: Ensure that the index is within the range of existing edges.)`);"default"===t?A.defaultStyle=e:(-1===i.u.isSubstringInArray("fill",e)&&e.push("fill:none"),A[t].style=e)}))},S=function(t,e){t.split(",").forEach((function(t){void 0===d[t]&&(d[t]={id:t,styles:[],textStyles:[]}),null!=e&&e.forEach((function(e){if(e.match("color")){const s=e.replace("fill","bgFill").replace("color","fill");d[t].textStyles.push(s)}d[t].styles.push(e)}))}))},m=function(t){a=t,a.match(/.*/)&&(a="LR"),a.match(/.*v/)&&(a="TB"),"TD"===a&&(a="TB")},x=function(t,e){t.split(",").forEach((function(t){let s=t;void 0!==h[s]&&h[s].classes.push(e),void 0!==y[s]&&y[s].classes.push(e)}))},v=function(t,e,s){t.split(",").forEach((function(t){void 0!==h[t]&&(h[t].link=i.u.formatUrl(e,l),h[t].linkTarget=s)})),x(t,"clickable")},L=function(t){if(E.hasOwnProperty(t))return E[t]},I=function(t,e,s){t.split(",").forEach((function(t){!function(t,e,s){let u=b(t);if("loose"!==(0,i.c)().securityLevel)return;if(void 0===e)return;let n=[];if("string"==typeof s){n=s.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0);(0,u.Ltv)(this).classed("hover",!1)}))};k.push(P);const U=function(t="gen-1"){h={},d={},A=[],k=[P],p=[],y={},f=0,E={},g=!0,c=t,l=(0,i.c)(),(0,i.v)()},V=t=>{c=t||"gen-2"},G=function(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"},M=function(t,e,s){let u=t.text.trim(),n=s.text;t===s&&s.text.match(/\s/)&&(u=void 0);let r=[];const{nodeList:a,dir:o}=function(t){const e={boolean:{},number:{},string:{}},s=[];let u;return{nodeList:t.filter((function(t){const i=typeof t;return t.stmt&&"dir"===t.stmt?(u=t.value,!1):""!==t.trim()&&(i in e?!e[i].hasOwnProperty(t)&&(e[i][t]=!0):!s.includes(t)&&s.push(t))})),dir:u}}(r.concat.apply(r,e));if(r=a,"gen-1"===c)for(let i=0;i2e3)return;if(j[Y]=e,p[e].id===t)return{result:!0,count:0};let u=0,i=1;for(;u=0){const s=X(t,e);if(s.result)return{result:!0,count:i+s.count};i+=s.count}u+=1}return{result:!1,count:i}},z=function(t){return j[t]},H=function(){Y=-1,p.length>0&&X("none",p.length-1)},W=function(){return p},Q=()=>!!g&&(g=!1,!0),q=(t,e)=>{const s=(t=>{const e=t.trim();let s=e.slice(0,-1),u="arrow_open";switch(e.slice(-1)){case"x":u="arrow_cross","x"===e[0]&&(u="double_"+u,s=s.slice(1));break;case">":u="arrow_point","<"===e[0]&&(u="double_"+u,s=s.slice(1));break;case"o":u="arrow_circle","o"===e[0]&&(u="double_"+u,s=s.slice(1))}let i="normal",n=s.length-1;"="===s[0]&&(i="thick"),"~"===s[0]&&(i="invisible");let r=((t,e)=>{const s=e.length;let u=0;for(let i=0;i{let e=t.trim(),s="arrow_open";switch(e[0]){case"<":s="arrow_point",e=e.slice(1);break;case"x":s="arrow_cross",e=e.slice(1);break;case"o":s="arrow_circle",e=e.slice(1)}let u="normal";return e.includes("=")&&(u="thick"),e.includes(".")&&(u="dotted"),{type:s,stroke:u}})(e),u.stroke!==s.stroke)return{type:"INVALID",stroke:"INVALID"};if("arrow_open"===u.type)u.type=s.type;else{if(u.type!==s.type)return{type:"INVALID",stroke:"INVALID"};u.type="double_"+u.type}return"double_arrow"===u.type&&(u.type="double_arrow_point"),u.length=s.length,u}return s},Z=(t,e)=>{let s=!1;return t.forEach((t=>{t.nodes.indexOf(e)>=0&&(s=!0)})),s},J=(t,e)=>{const s=[];return t.nodes.forEach(((u,i)=>{Z(e,u)||s.push(t.nodes[i])})),{nodes:s}},tt={firstGraph:Q},et={defaultConfig:()=>i.K.flowchart,setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,addVertex:F,lookUpDomId:b,addLink:C,updateLinkInterpolate:_,updateLink:B,addClass:S,setDirection:m,setClass:x,setTooltip:function(t,e){t.split(",").forEach((function(t){void 0!==e&&(E["gen-1"===c?b(t):t]=D(e))}))},getTooltip:L,setClickEvent:I,setLink:v,bindFunctions:R,getDirection:$,getVertices:N,getEdges:O,getClasses:w,clear:U,setGen:V,defaultStyle:G,addSubGraph:M,getDepthFirstPos:z,indexNodes:H,getSubGraphs:W,destructLink:q,lex:tt,exists:Z,makeUniq:J,setDiagramTitle:i.q,getDiagramTitle:i.t},st=Object.freeze(Object.defineProperty({__proto__:null,addClass:S,addLink:C,addSingleLink:T,addSubGraph:M,addVertex:F,bindFunctions:R,clear:U,default:et,defaultStyle:G,destructLink:q,firstGraph:Q,getClasses:w,getDepthFirstPos:z,getDirection:$,getEdges:O,getSubGraphs:W,getTooltip:L,getVertices:N,indexNodes:H,lex:tt,lookUpDomId:b,setClass:x,setClickEvent:I,setDirection:m,setGen:V,setLink:v,updateLink:B,updateLinkInterpolate:_},Symbol.toStringTag,{value:"Module"}))}}]); \ No newline at end of file diff --git a/assets/js/35b359a4.4bad58e8.js b/assets/js/35b359a4.4bad58e8.js new file mode 100644 index 0000000000..281f2d505f --- /dev/null +++ b/assets/js/35b359a4.4bad58e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[27683],{35798:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>p,frontMatter:()=>o,metadata:()=>n,toc:()=>h});const n=JSON.parse('{"id":"iaas/guides/other-guides/testbed","title":"Testbed","description":"With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack","source":"@site/docs/02-iaas/guides/other-guides/testbed.mdx","sourceDirName":"02-iaas/guides/other-guides","slug":"/iaas/guides/other-guides/testbed","permalink":"/docs/iaas/guides/other-guides/testbed","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/testbed.mdx","tags":[],"version":"current","frontMatter":{"sidebar_label":"Testbed Guide"},"sidebar":"docs","previous":{"title":"Zuul CI","permalink":"/docs/iaas/guides/other-guides/developer-guide/zuul"},"next":{"title":"Components","permalink":"/docs/category/components"}}');var l=s(74848),i=s(28453),r=s(11470),d=s(19365);const o={sidebar_label:"Testbed Guide"},c="Testbed",a={},h=[{value:"Requirements",id:"requirements",level:2},{value:"Cloud access",id:"cloud-access",level:3},{value:"Cloud resources",id:"cloud-resources",level:3},{value:"Software",id:"software",level:3},{value:"Deployment",id:"deployment",level:2},{value:"Usage",id:"usage",level:2},{value:"Custom CA",id:"custom-ca",level:3},{value:"VPN access",id:"vpn-access",level:3},{value:"Wireguard",id:"wireguard",level:4},{value:"sshuttle",id:"sshuttle",level:4},{value:"Static entries in /etc/hosts",id:"static-entries-in-etchosts",level:3},{value:"Webinterfaces",id:"webinterfaces",level:3},{value:"Authentication with OIDC",id:"authentication-with-oidc",level:3},{value:"OpenStack web dashboard (Horizon) login via OIDC",id:"openstack-web-dashboard-horizon-login-via-oidc",level:4},{value:"OpenStack web dashboard (Horizon) logout",id:"openstack-web-dashboard-horizon-logout",level:4},{value:"Usage of the OpenStack CLI",id:"usage-of-the-openstack-cli",level:4},{value:"OpenStack CLI operations with OpenID Connect password",id:"openstack-cli-operations-with-openid-connect-password",level:4},{value:"OpenStack CLI token issue with OpenID Connect",id:"openstack-cli-token-issue-with-openid-connect",level:4},{value:"Advanced Usage",id:"advanced-usage",level:2},{value:"External API",id:"external-api",level:3},{value:"Change versions",id:"change-versions",level:3},{value:"Deploy services",id:"deploy-services",level:3},{value:"Upgrade services",id:"upgrade-services",level:3},{value:"Add new OSD in Ceph",id:"add-new-osd-in-ceph",level:3},{value:"Ceph via Rook (technical preview)",id:"ceph-via-rook-technical-preview",level:3},{value:"Using testbed for OpenStack development",id:"using-testbed-for-openstack-development",level:2},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Ansible errors",id:"ansible-errors",level:3},{value:"Unsupported locale setting",id:"unsupported-locale-setting",level:3},{value:"Appendix",id:"appendix",level:2},{value:"Configuration",id:"configuration",level:3},{value:"Variables",id:"variables",level:4},{value:"Overrides",id:"overrides",level:4},{value:"Customisations",id:"customisations",level:4},{value:"Notes",id:"notes",level:3},{value:"Supported releases",id:"supported-releases",level:3},{value:"Included services",id:"included-services",level:3},{value:"Infrastructure",id:"infrastructure",level:4},{value:"OpenStack",id:"openstack",level:4},{value:"Makefile reference",id:"makefile-reference",level:3},{value:"CI jobs",id:"ci-jobs",level:3}];function x(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(t.header,{children:(0,l.jsx)(t.h1,{id:"testbed",children:"Testbed"})}),"\n",(0,l.jsxs)(t.p,{children:["With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack\ndeployment on an existing OpenStack environment such as Cleura or ",(0,l.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"}),"."]}),"\n",(0,l.jsxs)(t.p,{children:["OSISM is the reference implementation for the Infrastructure as a Service (IaaS) layer in the\n",(0,l.jsx)(t.a,{href:"https://www.sovereigncloudstack.org",children:"Sovereign Cloud Stack"})," (SCS) project. The OSISM Testbed is therefore\nused in the SCS project to test and work on the Instrastructure as a Service layer."]}),"\n",(0,l.jsx)(t.p,{children:"The OSISM Testbed is intended as a playground. Further services and integration will\nbe added over time. A increasing number of best practices and experiences from the productive\ndeployments will be included here in the future. It will become more production-like\nover time. However, at no point does it claim to represent a production setup exactly."}),"\n",(0,l.jsx)(t.h2,{id:"requirements",children:"Requirements"}),"\n",(0,l.jsx)(t.h3,{id:"cloud-access",children:"Cloud access"}),"\n",(0,l.jsx)(t.p,{children:"The usual prerequisite is to have an account on one of the supported OpenStack cloud providers.\nAs the OSISM Testbed also virtualizes systems itself, the OpenStack cluster should provide\nthe capabilities for nested virtualization."}),"\n",(0,l.jsx)(t.p,{children:"It is not part of this guide to describe the registration with the individual cloud\nproviders. Please contact the respective cloud provider for this."}),"\n",(0,l.jsxs)(t.table,{children:[(0,l.jsx)(t.thead,{children:(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Product"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Provider"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Profile name"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,l.jsxs)(t.tbody,{children:[(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Cleura"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Cleura"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"cleura"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Fuga Cloud"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"FUGA"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"fuga"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"HuaweiCloud"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"HuaweiCloud"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"huaweicloud"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"OVH"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"OVH"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"ovh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"OpenTelekomCloud"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"T-Systems"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"otc"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"pluscloud open"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"plusserver"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"pluscloudopen"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"pluscloud SCS Test"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"plusserver"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"gx-scs"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"REGIO.cloud"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"OSISM"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"regiocloud"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"REGIO.cloud"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"OSISM"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"regio-fast"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"boot from NVMe SSD backed volumes"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Wavestack"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"noris network"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"wavestack"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"CNDS Cloud"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"artcodix"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"artcodix"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,l.jsxs)(t.p,{children:["For each cloud provider listed in the table, a predefined profile is available in the\n",(0,l.jsx)(t.code,{children:"terraform/environments"})," directory. This profile contains the name of the public\nnetwork, which flavors to use, etc."]}),"\n",(0,l.jsxs)(t.p,{children:["Here is an example from the profile for ",(0,l.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"}),"."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-text",children:'flavor_manager = "SCS-4V-16-50"\nflavor_node = "SCS-8V-32-50"\nvolume_type = "ssd"\nimage = "Ubuntu 22.04"\nimage_node = "Ubuntu 22.04"\npublic = "public"\navailability_zone = "nova"\nvolume_availability_zone = "nova"\nnetwork_availability_zone = "nova"\n'})}),"\n",(0,l.jsx)(t.h3,{id:"cloud-resources",children:"Cloud resources"}),"\n",(0,l.jsx)(t.p,{children:"The OSISM Testbed requires at least the following project quota when using the default flavors:"}),"\n",(0,l.jsxs)(t.table,{children:[(0,l.jsx)(t.thead,{children:(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Quantity"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Resource"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,l.jsxs)(t.tbody,{children:[(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"4"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Instances"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"28 VCPUs + 112 GByte RAM (3 modes, 1 manager)"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"9"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Volumes"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"90 GByte volume storage"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Floating IP"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Keypair"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"3"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Security group"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"16"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Security group rules"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Network"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Subetwork"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"6"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Ports"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Router"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,l.jsx)(t.h3,{id:"software",children:"Software"}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"make"})," must be installed on the system"]}),"\n",(0,l.jsxs)(t.li,{children:["Wireguard or ",(0,l.jsx)(t.code,{children:"sshuttle"})," must be installed on your system for VPN access"]}),"\n",(0,l.jsxs)(t.li,{children:["Python must be installed, the Python version used must be at least 3.10, otherwise\nthe current Ansible release cannot be used (details in the\n",(0,l.jsx)(t.a,{href:"https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix",children:"Ansible support matrix"}),")"]}),"\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"python3-venv"})," must be installed for managing Python dependencies like Ansible"]}),"\n"]}),"\n",(0,l.jsx)(t.h2,{id:"deployment",children:"Deployment"}),"\n",(0,l.jsx)(t.p,{children:"This section describes step by step how to deploy the OSISM Testbed."}),"\n",(0,l.jsxs)(t.ol,{children:["\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsx)(t.p,{children:"Request access from the administrator of the respective cloud or get access to an OpenStack cloud."}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsxs)(t.p,{children:["Clone the ",(0,l.jsx)(t.a,{href:"https://github.com/osism/testbed",children:"osism/testbed"})," repository."]}),"\n",(0,l.jsx)(t.p,{children:"The repository can also be cloned to any other location."}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"mkdir -p ~/src/github.com/osism\ngit clone https://github.com/osism/testbed ~/src/github.com/osism/testbed\ncd ~/src/github.com/osism/testbed\n"})}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsx)(t.p,{children:"Configure your cloud access profile"}),"\n",(0,l.jsxs)(t.p,{children:["The access data for the cloud provider used is stored in ",(0,l.jsx)(t.code,{children:"terraform/clouds.yaml"})," and (optionally)\nin ",(0,l.jsx)(t.code,{children:"terraform/secure.yaml"})," (same structure, if you want to store credentials on a separate place)."]}),"\n",(0,l.jsxs)(t.p,{children:["In file ",(0,l.jsx)(t.a,{href:"https://github.com/osism/testbed/blob/main/terraform/clouds.yaml.sample",children:"terraform/clouds.yaml.sample"}),"\nyou will find examples of typical setups. Settings that are identical for all users of a cloud can be defined\ncentrally via the profiles of the file\n",(0,l.jsx)(t.a,{href:"https://github.com/osism/testbed/blob/main/terraform/clouds-public.yaml",children:"terraform/clouds-public.yaml"}),".\nYou can reference these settings by using the ",(0,l.jsx)(t.code,{children:"profile"})," parameter in cloud-specific\ndefinition in ",(0,l.jsx)(t.code,{children:"terraform/clouds.yaml"}),"."]}),"\n",(0,l.jsxs)(t.p,{children:["The user specific settings of the ",(0,l.jsx)(t.code,{children:"clouds.yaml"})," file are provided by the cloud provider. Please check the\ndocumentation of the cloud provider you are using or their support for details."]}),"\n",(0,l.jsxs)(t.p,{children:[(0,l.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"})," is used as an example here. The cloud name in ",(0,l.jsx)(t.code,{children:"clouds.yaml"}),"\nand the environment name (value of ",(0,l.jsx)(t.code,{children:"ENVIRONMENT"}),") are ",(0,l.jsx)(t.code,{children:"regiocloud"})," in this case. It is important that\nthe name of the cloud in ",(0,l.jsx)(t.code,{children:"clouds.yaml"})," matches the name of the environment to be used. The names must\nbe identical. It is currently not possible to name the cloud ",(0,l.jsx)(t.code,{children:"regiocloud-123"})," in ",(0,l.jsx)(t.code,{children:"clouds.yaml"})," if the\nenvironment is ",(0,l.jsx)(t.code,{children:"regiocloud"}),"."]}),"\n",(0,l.jsxs)(t.p,{children:["If another cloud is used, replace ",(0,l.jsx)(t.code,{children:"regiocloud"})," with the respective profile name ",(0,l.jsx)(t.a,{href:"#cloud-access",children:"from the table above"}),"."]}),"\n",(0,l.jsxs)(r.A,{children:[(0,l.jsxs)(d.A,{value:"testbed-cloud-access-with-app-credentials",label:"Application Credentials",children:[(0,l.jsxs)(t.p,{children:["The use of application credentials is preferred. This way it is not necessary to store\ndetails like username, project name or sensitive information like the password in the\n",(0,l.jsx)(t.code,{children:"clouds.yaml"})," file."]}),(0,l.jsxs)(t.p,{children:["The application credentials can be found in Horizon under ",(0,l.jsx)(t.strong,{children:"Identity"}),". Use ",(0,l.jsx)(t.code,{children:"OSISM Testbed"})," as\nname and click ",(0,l.jsx)(t.code,{children:"Create Application Credential"}),"."]}),(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/clouds.yaml"',children:'clouds:\n regiocloud:\n profile: regiocloud\n auth:\n application_credential_id: ID\n application_credential_secret: SECRET\n auth_type: "v3applicationcredential"\n'})}),(0,l.jsxs)(t.p,{children:["If you want to make use of ",(0,l.jsx)(t.code,{children:"terraform/secure.yaml"})," add your application credential secret there\ninstead of ",(0,l.jsx)(t.code,{children:"terraform/clouds.yaml"}),"."]}),(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/secure.yaml"',children:"clouds:\n regiocloud:\n auth:\n application_credential_secret: SECRET\n"})})]}),(0,l.jsxs)(d.A,{value:"testbed-cloud-access-with-username-password",label:"Username/Password",children:[(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/clouds.yaml"',children:"clouds:\n regiocloud:\n profile: regiocloud\n auth:\n project_name: PROJECT\n username: USERNAME\n project_domain_name: DOMAIN\n user_domain_name: DOMAIN\n"})}),(0,l.jsxs)(t.p,{children:["If you want to make use of ",(0,l.jsx)(t.code,{children:"terraform/secure.yaml"})," add your password there instead of ",(0,l.jsx)(t.code,{children:"terraform/clouds.yaml"}),"."]}),(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/secure.yaml"',children:"clouds:\n regiocloud:\n auth:\n password: PASSWORD\n"})})]})]}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsx)(t.p,{children:"Prepare the deployment."}),"\n",(0,l.jsxs)(t.p,{children:["The versions of Ansible and ",(0,l.jsx)(t.a,{href:"https://opentofu.org",children:"OpenTofu"})," are managed\nautomatically and necessary dependencies are cloned."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"make prepare\n"})}),"\n",(0,l.jsxs)(t.p,{children:["If any error occurs during preparation and you want to run the preparation\nagain, it is important to run ",(0,l.jsx)(t.code,{children:"make wipe-local-install"})," first. Otherwise the\npreparation will not be redone completely and necessary parts will be missing\nlater on."]}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsx)(t.p,{children:"Create the infrastructure with OpenTofu."}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"make ENVIRONMENT=regiocloud create\n"})}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsx)(t.p,{children:"Deploy the OSISM manager and bootstrap all nodes."}),"\n",(0,l.jsxs)(r.A,{children:[(0,l.jsx)(d.A,{value:"testbed-deploy-latst",label:"Deploy latest manager version",children:(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"make ENVIRONMENT=regiocloud manager\n"})})}),(0,l.jsx)(d.A,{value:"testbed-deploy-stable",label:"Deploy a stable manager version",children:(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"make ENVIRONMENT=regiocloud VERSION_MANAGER=8.0.1 manager\n"})})})]}),"\n",(0,l.jsxs)(t.p,{children:["Replace the version with the version you prefer.\nCheck the ",(0,l.jsx)(t.a,{href:"https://osism.tech/docs/release-notes/",children:"OSISM release notes"}),"\nto find out what's available."]}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsx)(t.p,{children:"After the bootstrap, you can log in to the manager via SSH."}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"make ENVIRONMENT=regiocloud login\n"})}),"\n",(0,l.jsx)(t.p,{children:"Yo can log in to the nodes of the cluster via the manager."}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"osism console testbed-node-0\n"})}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsx)(t.p,{children:"Deploy all services."}),"\n",(0,l.jsxs)(r.A,{children:[(0,l.jsxs)(d.A,{value:"testbed-deploy-multi-steps",label:"Deployment in single steps",children:[(0,l.jsxs)(t.p,{children:["It is also possible to deploy the services step by step on the\nmanager. To do this, first log in to the manager with ",(0,l.jsx)(t.code,{children:"make ENVIRONMENT=regiocloud login"}),"\nand then execute the deploy scripts one after the other. It is recommended to do this\nwithin a screen session."]}),(0,l.jsx)(t.p,{children:"Deploying the services takes some time and depends on how much bandwidth is available,\nhow the instances are equipped, etc. 90-120 minutes is not unusual when Ceph and OpenStack\nare fully deployed."}),(0,l.jsxs)(t.p,{children:["To speed up the Ansible playbooks, ",(0,l.jsx)(t.a,{href:"https://ara.recordsansible.org",children:"ARA"})," can be disabled. This\nis done by executing ",(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/disable-ara.sh"}),". Run this script ",(0,l.jsx)(t.strong,{children:"before"})," the deployment scripts.\nAfterwards no more logs are available in the ARA web\ninterface. To re-enable ARA use ",(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/enable-ara.sh"}),"."]}),(0,l.jsxs)(t.p,{children:["There is also the option of pre-population of images with ",(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/pull-images.sh"}),"\nso that deployments do not have to be lengthy. Run this script ",(0,l.jsx)(t.strong,{children:"before"})," the deployment scripts."]}),(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"/opt/configuration/scripts/deploy/001-helper-services.sh\n/opt/configuration/scripts/deploy/005-kubernetes.sh\n/opt/configuration/scripts/deploy/100-ceph-services.sh\n/opt/configuration/scripts/deploy/200-infrastructure-services-basic.sh\n/opt/configuration/scripts/deploy/300-openstack-services-basic.sh\n/opt/configuration/scripts/deploy/400-monitoring-services.sh\n"})}),(0,l.jsxs)(t.p,{children:["Prepare OpenStack resources like public network, flavors and images by running\n",(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/bootstrap.sh"}),". Run this script ",(0,l.jsx)(t.strong,{children:"after"})," the deployment scripts."]}),(0,l.jsxs)(t.admonition,{type:"info",children:[(0,l.jsxs)(t.p,{children:["If you only want to deploy the monitoring services with ",(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/400-monitoring-services.sh"}),",\na few dependencies must be deployed first. You can then use the monitoring services without having to install a\ncomplete OpenStack & Ceph environment."]}),(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"osism apply common\nosism apply loadbalancer\nosism apply opensearch\nosism apply mariadb\n"})})]})]}),(0,l.jsxs)(d.A,{value:"testbed-deploy-single-step",label:"Deployment of all services",children:[(0,l.jsx)(t.p,{children:"In this single step deployment, Ceph, OpenStack and all necessary\ninfrastructure services (MariaDB, RabbitMQ, ...) are deployed.\nDepending on the cloud, the deployment will take some time. Up to two hours is not unusual."}),(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"make ENVIRONMENT=regiocloud deploy\n"})})]})]}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsxs)(t.p,{children:["If you want to verify the deployment with ",(0,l.jsx)(t.a,{href:"https://opendev.org/openinfra/refstack",children:"refstack"})," run\n",(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/check.sh"}),". This step will take some time and is optional."]}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsx)(t.p,{children:"The machine images required for the use of Kubernetes Cluster API and the amphora driver of OpenStack Octavia\nservice are not provided by default to save resources on the OSISM Testbed and improve deployment time.\nThese can be provisioned if required."}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"/opt/configuration/scripts/bootstrap/301-openstack-octavia-amhpora-image.sh\n/opt/configuration/scripts/bootstrap/302-openstack-k8s-clusterapi-images.sh\n"})}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsx)(t.p,{children:"If you want you can create a test project with a test user after login. It also\ncreates an instance with a volume attached to a network with a router. This step is optional."}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"osism apply --environment openstack test\n"})}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsx)(t.p,{children:"When the OSISM Testbed is no longer needed, it can be deleted."}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"make ENVIRONMENT=regiocloud clean\n"})}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(t.h2,{id:"usage",children:"Usage"}),"\n",(0,l.jsx)(t.p,{children:"Deployment must be completed at this point."}),"\n",(0,l.jsx)(t.h3,{id:"custom-ca",children:"Custom CA"}),"\n",(0,l.jsxs)(t.p,{children:["The OSISM Testbed deployment currently uses hostnames in the domain ",(0,l.jsx)(t.code,{children:"testbed.osism.xyz"}),". This is a real domain\nand we provide the DNS records matching the addresses used in the OSISM Testbed, so that once you connect to your testbed via a direct\nlink or Wireguard, you can access hosts and servers by their hostname (e.g. ",(0,l.jsx)(t.code,{children:"ssh testbed-manager.testbed.osism.xyz"}),")."]}),"\n",(0,l.jsxs)(t.p,{children:["We also provide a wildcard TLS certificate signed by a custom CA for ",(0,l.jsx)(t.code,{children:"testbed.osism.xyz"})," and ",(0,l.jsx)(t.code,{children:"*.testbed.osism.xyz"}),".\nThis CA is always used for each testbed. The CA is not regenerated and it is not planned to change this for the next 10 years."]}),"\n",(0,l.jsxs)(t.p,{children:["In order for these certificates to be recognized locally as valid, the CA\n",(0,l.jsx)(t.a,{href:"https://raw.githubusercontent.com/osism/testbed/main/environments/kolla/certificates/ca/testbed.crt",children:"environments/kolla/certificates/ca/testbed.crt"}),"\nmust be imported locally."]}),"\n",(0,l.jsx)(t.h3,{id:"vpn-access",children:"VPN access"}),"\n",(0,l.jsx)(t.h4,{id:"wireguard",children:"Wireguard"}),"\n",(0,l.jsxs)(t.p,{children:["Install wireguard on your workstation, if you have not done this before. For instructions how to do\nit on your workstation, please have a look on the documentation of your used distribution. The\nwireguard documentation you will find ",(0,l.jsx)(t.a,{href:"https://www.wireguard.com",children:"here"}),"."]}),"\n",(0,l.jsx)(t.p,{children:"Start the wireguard tunnel.\n(Press CTRL+c to keep the tunnel running forever. The make target also launches a browser tab with references to all services)"}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"make vpn-wireguard ENVIRONMENT=regiocloud\n"})}),"\n",(0,l.jsx)(t.p,{children:"If you want to connect to the OSISM Testbed from multiple clients, change the client IP\naddress in the downloaded configuration file to be different on each client."}),"\n",(0,l.jsxs)(t.p,{children:["If you only want to download the Wireguard configuration, you can use the ",(0,l.jsx)(t.code,{children:"vpn-wireguard-config"}),"\ntarget. The configuration is then available in the file ",(0,l.jsx)(t.code,{children:"wg-testbed-regiocloud.conf"}),", for example."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"make vpn-wireguard-config ENVIRONMENT=regiocloud\n"})}),"\n",(0,l.jsx)(t.h4,{id:"sshuttle",children:"sshuttle"}),"\n",(0,l.jsxs)(t.p,{children:["If you do not want to use Wireguard you can also work with ",(0,l.jsx)(t.a,{href:"https://github.com/sshuttle/sshuttle",children:"sshuttle"}),"."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"make vpn-sshuttle ENVIRONMENT=regiocloud\nkillall sshuttle\n"})}),"\n",(0,l.jsxs)(t.h3,{id:"static-entries-in-etchosts",children:["Static entries in ",(0,l.jsx)(t.code,{children:"/etc/hosts"})]}),"\n",(0,l.jsxs)(t.p,{children:["If you are unable to access the following domains, you can customize your local ",(0,l.jsx)(t.code,{children:"/etc/hosts"}),"\nwith the following static entries. This may be necessary, for example, if you use Pi-hole and\nall DNS entries from a public DNS with a non-public IP address are filtered."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"# OSISM Testbed hosts\n192.168.16.5 ara.testbed.osism.xyz ara\n192.168.16.5 cgit.testbed.osism.xyz cgit\n192.168.16.5 flower.testbed.osism.xyz flower\n192.168.16.5 homer.testbed.osism.xyz homer\n192.168.16.5 netbox.testbed.osism.xyz netbox\n192.168.16.5 testbed-manager.testbed.osism.xyz testbed-manager\n192.168.16.5 nexus.testbed.osism.xyz nexus\n192.168.16.5 phpmyadmin.testbed.osism.xyz phpmyadmin\n192.168.16.9 api-int.testbed.osism.xyz api-int\n192.168.16.10 testbed-node-0.testbed.osism.xyz testbed-node-0\n192.168.16.11 testbed-node-1.testbed.osism.xyz testbed-node-1\n192.168.16.12 testbed-node-2.testbed.osism.xyz testbed-node-2\n192.168.16.13 testbed-node-3.testbed.osism.xyz testbed-node-3\n192.168.16.14 testbed-node-4.testbed.osism.xyz testbed-node-4\n192.168.16.15 testbed-node-5.testbed.osism.xyz testbed-node-5\n192.168.16.16 testbed-node-6.testbed.osism.xyz testbed-node-6\n192.168.16.17 testbed-node-7.testbed.osism.xyz testbed-node-7\n192.168.16.18 testbed-node-8.testbed.osism.xyz testbed-node-8\n192.168.16.19 testbed-node-9.testbed.osism.xyz testbed-node-9\n192.168.16.100 keycloak.testbed.osism.xyz keycloak\n192.168.16.254 api.testbed.osism.xyz api\n"})}),"\n",(0,l.jsx)(t.h3,{id:"webinterfaces",children:"Webinterfaces"}),"\n",(0,l.jsxs)(t.p,{children:["All SSL enabled services within the OSISM Testbed use certs which are signed by the self-signed\n",(0,l.jsx)(t.a,{href:"https://raw.githubusercontent.com/osism/testbed/main/environments/kolla/certificates/ca/testbed.crt",children:"OSISM Testbed CA"}),"\n(Download the file and import it as certification authority to your browser)."]}),"\n",(0,l.jsx)(t.p,{children:"If you want to access the services please choose the URL from the following table."}),"\n",(0,l.jsxs)(t.table,{children:[(0,l.jsx)(t.thead,{children:(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"URL"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Username"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Password"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,l.jsxs)(t.tbody,{children:[(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"ARA"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://ara.testbed.osism.xyz",children:"https://ara.testbed.osism.xyz"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"ara"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Ceph"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:8140",children:"https://api-int.testbed.osism.xyz:8140"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Flower"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://flower.testbed.osism.xyz",children:"https://flower.testbed.osism.xyz"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}}),(0,l.jsx)(t.td,{style:{textAlign:"left"}}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Grafana"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:3000",children:"https://api-int.testbed.osism.xyz:3000"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"HAProxy (testbed-node-0)"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"http://testbed-node-0.testbed.osism.xyz:1984",children:"http://testbed-node-0.testbed.osism.xyz:1984"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"HAProxy (testbed-node-1)"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"http://testbed-node-1.testbed.osism.xyz:1984",children:"http://testbed-node-1.testbed.osism.xyz:1984"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"HAProxy (testbed-node-2)"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"http://testbed-node-2.testbed.osism.xyz:1984",children:"http://testbed-node-2.testbed.osism.xyz:1984"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Homer"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://homer.testbed.osism.xyz",children:"https://homer.testbed.osism.xyz"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}}),(0,l.jsx)(t.td,{style:{textAlign:"left"}}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Horizon (via Keycloak)"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://api.testbed.osism.xyz",children:"https://api.testbed.osism.xyz"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"alice"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Horizon (via Keystone)"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://api.testbed.osism.xyz",children:"https://api.testbed.osism.xyz"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"domain: default"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Horizon (via Keystone)"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://api.testbed.osism.xyz",children:"https://api.testbed.osism.xyz"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"test"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"test"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"domain: test"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Keycloak"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz/auth",children:"https://keycloak.testbed.osism.xyz/auth"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Netbox"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://netbox.testbed.osism.xyz",children:"https://netbox.testbed.osism.xyz"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Netdata"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"http://testbed-manager.testbed.osism.xyz:19999",children:"http://testbed-manager.testbed.osism.xyz:19999"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}}),(0,l.jsx)(t.td,{style:{textAlign:"left"}}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Nexus"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://nexus.testbed.osism.xyz",children:"https://nexus.testbed.osism.xyz"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"OpenSearch Dashboards"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://api.testbed.osism.xyz:5601",children:"https://api.testbed.osism.xyz:5601"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"opensearch"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Prometheus"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:9091",children:"https://api-int.testbed.osism.xyz:9091"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"RabbitMQ"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:15672",children:"https://api-int.testbed.osism.xyz:15672"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"phpMyAdmin"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.a,{href:"https://phpmyadmin.testbed.osism.xyz",children:"https://phpmyadmin.testbed.osism.xyz"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"root"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,l.jsx)(t.h3,{id:"authentication-with-oidc",children:"Authentication with OIDC"}),"\n",(0,l.jsx)(t.p,{children:"Authentication with OpenID Connect (OIDC) is possible via Keycloak, which is automatically configured for the OIDC mechanism."}),"\n",(0,l.jsx)(t.h4,{id:"openstack-web-dashboard-horizon-login-via-oidc",children:"OpenStack web dashboard (Horizon) login via OIDC"}),"\n",(0,l.jsxs)(t.p,{children:["For logging in via OIDC, open your browser at OpenStack Dashboard Login Page, select ",(0,l.jsx)(t.strong,{children:"Authenticate via Keycloak"}),", after being\nredirected to the Keycloak login page, perform the login with the credentials ",(0,l.jsx)(t.strong,{children:"alice"})," and ",(0,l.jsx)(t.strong,{children:"password"}),".\nAfter that you will be redirected back to the Horizon dashboard, where you will be logged in with the user ",(0,l.jsx)(t.strong,{children:"alice"}),"."]}),"\n",(0,l.jsx)(t.h4,{id:"openstack-web-dashboard-horizon-logout",children:"OpenStack web dashboard (Horizon) logout"}),"\n",(0,l.jsxs)(t.p,{children:["Keep in mind, that clicking ",(0,l.jsx)(t.strong,{children:"Sign Out"})," on the Horizon dashboard currently doesn't revoke your OIDC token, and any consequent\nattempt to ",(0,l.jsx)(t.strong,{children:"Authenticate via Keycloak"})," will succeed without providing the credentials."]}),"\n",(0,l.jsx)(t.p,{children:"The expiration time of the Single Sign On tokens can be controlled on multiple levels in Keycloak."}),"\n",(0,l.jsxs)(t.ol,{children:["\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsxs)(t.p,{children:["On realm level under ",(0,l.jsx)(t.em,{children:"Realm Settings"})," > ",(0,l.jsx)(t.em,{children:"Tokens"}),".\nAssuming the ",(0,l.jsx)(t.em,{children:"keycloak_realm"})," ansible variable is the default ",(0,l.jsx)(t.em,{children:"osism"}),", and keycloak is listening on\n",(0,l.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz",children:"keycloak.testbed.osism.xyz"}),", then the configuration form is available\n",(0,l.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz/auth/admin/master/console/#/realms/osism/token-settings",children:"here"}),"."]}),"\n",(0,l.jsxs)(t.p,{children:["Detailed information is available in the Keycloak Server Administrator Documentation\n",(0,l.jsx)(t.a,{href:"https://www.keycloak.org/docs/latest/server_admin/#_timeouts",children:"Session and Token Timeouts"})," section."]}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsxs)(t.p,{children:["In a realm down on the ",(0,l.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz/auth/admin/master/console/#/realms/osism/clients",children:"client level"}),"\nselect the client (keystone), and under ",(0,l.jsx)(t.em,{children:"Settings"})," > ",(0,l.jsx)(t.em,{children:"Advanced Settings"}),"."]}),"\n",(0,l.jsxs)(t.p,{children:["It is recommended to keep the ",(0,l.jsx)(t.em,{children:"Access Token Lifespan"})," on a relatively low value, with the trend of blocking third party\ncookies. For further information see the Keycloak documentation's ",(0,l.jsx)(t.a,{href:"https://www.keycloak.org/docs/latest/securing_apps/#browsers-with-blocked-third-party-cookies",children:"Browsers with Blocked Third-Party Cookies"})," section."]}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(t.h4,{id:"usage-of-the-openstack-cli",children:"Usage of the OpenStack CLI"}),"\n",(0,l.jsxs)(t.p,{children:["The ",(0,l.jsx)(t.code,{children:"environments/openstack"})," folder contains the needed files for the openstack client:"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"cd environments/openstack\nexport OS_CLOUD= # i.e. admin\nopenstack floating ip list\n"})}),"\n",(0,l.jsx)(t.h4,{id:"openstack-cli-operations-with-openid-connect-password",children:"OpenStack CLI operations with OpenID Connect password"}),"\n",(0,l.jsxs)(t.p,{children:["Using the OpenStack cli is also possible via OIDC, assuming you provisioned the user ",(0,l.jsx)(t.strong,{children:"alice"})," with password ",(0,l.jsx)(t.strong,{children:"password"}),",\nthen you can perform a simple ",(0,l.jsx)(t.code,{children:"project list"})," operation like this:"]}),"\n",(0,l.jsx)(t.p,{children:'See chapter "Usage the OpenStack CLI" for basic openstack usage.'}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"openstack \\\n --os-cacert /etc/ssl/certs/ca-certificates.crt \\\n --os-auth-url https://api.testbed.osism.xyz:5000/v3 \\\n --os-auth-type v3oidcpassword \\\n --os-client-id keystone \\\n --os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \\\n --os-username alice \\\n --os-password password \\\n --os-identity-provider keycloak \\\n --os-protocol openid \\\n --os-identity-api-version 3 \\\n --os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \\\nproject list\n"})}),"\n",(0,l.jsx)(t.h4,{id:"openstack-cli-token-issue-with-openid-connect",children:"OpenStack CLI token issue with OpenID Connect"}),"\n",(0,l.jsxs)(t.p,{children:["It is also possible to exchange your username/password to a token, for further use with the cli.\nThe ",(0,l.jsx)(t.code,{children:"token issue"})," subcommand returns an SQL table, in which the ",(0,l.jsx)(t.code,{children:"id"})," column's ",(0,l.jsx)(t.code,{children:"value"})," field contains the token:"]}),"\n",(0,l.jsx)(t.p,{children:'See chapter "Usage the OpenStack CLI" for basic openstack usage.'}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:'openstack \\\n --os-cacert /etc/ssl/certs/ca-certificates.crt \\\n --os-auth-url https://api.testbed.osism.xyz:5000/v3 \\\n --os-auth-type v3oidcpassword \\\n --os-client-id keystone \\\n --os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \\\n --os-username alice \\\n --os-password password \\\n --os-identity-provider keycloak \\\n --os-protocol openid \\\n --os-identity-api-version 3 \\\n --os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \\\n --os-openid-scope "openid profile email" \\\ntoken issue \\\n -c id\n -f value\n'})}),"\n",(0,l.jsx)(t.p,{children:"An example token is like:"}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-sh",children:"gAAAAABhC98gL8nsQWknro3JWDXWLFCG3CDr3Mi9OIlvVAZMjy2mNgYtlXv_0yAIy-\nnSlLAaLIGhht17-mwf8uclKgRuNVsYLSmgUpB163l89-ch2w2_OFe9zNSQNWf4qfd8\nCl7E7XvvUoFr1N8Gh09vaYLvRvYgCGV05xBUSs76qCHa0qElPUsk56s5ft4ALrSrzD\n4cEQRVb5PXNjywdZk9_gtJziz31A7sD4LPIy82O5N9NryDoDw\n"})}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsx)(t.li,{children:"TODO: OpenStack CLI operations with token"}),"\n",(0,l.jsx)(t.li,{children:"TODO: OpenStack CLI token revoke"}),"\n"]}),"\n",(0,l.jsx)(t.h2,{id:"advanced-usage",children:"Advanced Usage"}),"\n",(0,l.jsx)(t.h3,{id:"external-api",children:"External API"}),"\n",(0,l.jsxs)(t.p,{children:["It is possible to provide the OpenStack APIs and the OpenStack Dashboard via the manager's public IP address.\nThis is not enabled by default, with the exception of the OTC profile. To provide the OpenStack APIs and the\nOpenStack dashboard via the public IP address of the manager, the following changes are necessary in the\n",(0,l.jsx)(t.code,{children:"terraform/environments/regiocloud.tfvars"})," file. If a cloud other than the REGIO.cloud is used, the profile\nof the other cloud is changed accordingly."]}),"\n",(0,l.jsxs)(t.ol,{children:["\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsxs)(t.p,{children:["Add the customisation ",(0,l.jsx)(t.code,{children:"external_api"}),". This customisation makes sure that the required security group rules\nare created for the various OpenStack APIs and the OpenStack dashboard."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:"# customisation:external_api\n"})}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsxs)(t.p,{children:["Set parameter ",(0,l.jsx)(t.code,{children:"external_api"})," to ",(0,l.jsx)(t.code,{children:"true"}),". This makes sure that all necessary changes are made in the configuration\nrepository when the manager service is deployed. It is correct that this is added as a comment."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:"external_api = true\n"})}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsxs)(t.p,{children:["After the deployment of the manager service and the OpenStack services, the OpenStack APIs and the OpenStack\ndashboard can be reached via a DNS name. The service ",(0,l.jsx)(t.a,{href:"https://traefik.me",children:"traefik.me"})," is used for the DNS record.\nRun the following two commands on the manager node to get the DNS record."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:'$ source /opt/manager-vars.sh\n$ echo "api-${MANAGER_PUBLIC_IP_ADDRESS//./-}.traefik.me"\napi-80-158-46-219.traefik.me\n'})}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(t.h3,{id:"change-versions",children:"Change versions"}),"\n",(0,l.jsxs)(t.ol,{children:["\n",(0,l.jsxs)(t.li,{children:["Go to ",(0,l.jsx)(t.code,{children:"/opt/configuration"})," on ",(0,l.jsx)(t.code,{children:"testbed-manager"})]}),"\n",(0,l.jsxs)(t.li,{children:["Run ",(0,l.jsx)(t.code,{children:"./scripts/set-openstack-version.sh 2024.2"})," to set the OpenStack version to ",(0,l.jsx)(t.code,{children:"2024.2"})]}),"\n",(0,l.jsxs)(t.li,{children:["Run ",(0,l.jsx)(t.code,{children:"./scripts/set-ceph-version.sh reef"})," to set the Ceph version to ",(0,l.jsx)(t.code,{children:"reef"})]}),"\n",(0,l.jsxs)(t.li,{children:["Run ",(0,l.jsx)(t.code,{children:"osism update manager"})," to update the manager service"]}),"\n"]}),"\n",(0,l.jsx)(t.h3,{id:"deploy-services",children:"Deploy services"}),"\n",(0,l.jsxs)(t.table,{children:[(0,l.jsx)(t.thead,{children:(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Script"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,l.jsxs)(t.tbody,{children:[(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/000-manager-service.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/001-helper-services.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/100-ceph-services.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Alternative to ceph-ansible"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/100-rook-services.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/200-infrastructure-services.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/300-openstack-services.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/310-openstack-services-extended.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/400-monitoring-services.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/500-kubernetes.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/510-clusterapi.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,l.jsx)(t.h3,{id:"upgrade-services",children:"Upgrade services"}),"\n",(0,l.jsxs)(t.table,{children:[(0,l.jsx)(t.thead,{children:(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Script"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,l.jsxs)(t.tbody,{children:[(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/100-ceph-services.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/100-rook-services.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Alternative to ceph-ansible"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/200-infrastructure-services.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/300-openstack-services.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/310-openstack-services-extended.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/400-monitoring-services.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/500-kubernetes.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/510-clusterapi.sh"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,l.jsx)(t.h3,{id:"add-new-osd-in-ceph",children:"Add new OSD in Ceph"}),"\n",(0,l.jsx)(t.p,{children:"In the testbed, three volumes per node are provided for use by Ceph by default. Two of\nthese devices are used as OSDs during the initial deployment. The third device is intended\nfor testing the addition of a further OSD to the Ceph cluster."}),"\n",(0,l.jsxs)(t.ol,{children:["\n",(0,l.jsxs)(t.li,{children:["Add ",(0,l.jsx)(t.code,{children:"sdd"})," to ",(0,l.jsx)(t.code,{children:"ceph_osd_devices"})," in ",(0,l.jsx)(t.code,{children:"/opt/configuration/inventory/host_vars/testbed-node-0/ceph-lvm-configuration.yml"}),".\nThe following content is an example, the IDs look different everywhere. Do not copy 1:1\nbut only add ",(0,l.jsx)(t.code,{children:"sdd"})," to the file."]}),"\n"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-yaml",children:"---\n#\n# This is Ceph LVM configuration for testbed-node-0\n# generated by ceph-configure-lvm-volumes playbook.\n#\nceph_osd_devices:\n sdb:\n osd_lvm_uuid: 95a9a2e0-b23f-55b2-a04f-e02ddfc0e82a\n sdc:\n osd_lvm_uuid: 29899765-42bf-557b-ae9c-5c7c984b2243\n sdd:\nlvm_volumes:\n- data: osd-block-95a9a2e0-b23f-55b2-a04f-e02ddfc0e82a\n data_vg: ceph-95a9a2e0-b23f-55b2-a04f-e02ddfc0e82a\n- data: osd-block-29899765-42bf-557b-ae9c-5c7c984b2243\n data_vg: ceph-29899765-42bf-557b-ae9c-5c7c984b2243\n"})}),"\n",(0,l.jsxs)(t.ol,{start:"2",children:["\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsxs)(t.p,{children:["Run ",(0,l.jsx)(t.code,{children:"osism apply ceph-configure-lvm-volumes -l testbed-node-0"})]}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsxs)(t.p,{children:["Run ",(0,l.jsx)(t.code,{children:"cp /tmp/testbed-node-0-ceph-lvm-configuration.yml /opt/configuration/inventory/host_vars/testbed-node-0/ceph-lvm-configuration.yml"}),"."]}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsxs)(t.p,{children:["Run ",(0,l.jsx)(t.code,{children:"osism reconciler sync"})]}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsxs)(t.p,{children:["Run ",(0,l.jsx)(t.code,{children:"osism apply ceph-create-lvm-devices -l testbed-node-0"})]}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsxs)(t.p,{children:["Run ",(0,l.jsx)(t.code,{children:"osism apply ceph-osds -l testbed-node-0 -e ceph_handler_osds_restart=false"})]}),"\n"]}),"\n",(0,l.jsxs)(t.li,{children:["\n",(0,l.jsx)(t.p,{children:"Check the OSD tree"}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:"$ ceph osd tree\nID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF\n-1 0.13640 root default\n-3 0.05846 host testbed-node-0\n 2 hdd 0.01949 osd.2 up 1.00000 1.00000\n 4 hdd 0.01949 osd.4 up 1.00000 1.00000\n 6 hdd 0.01949 osd.6 up 1.00000 1.00000\n-5 0.03897 host testbed-node-1\n 0 hdd 0.01949 osd.0 up 1.00000 1.00000\n 5 hdd 0.01949 osd.5 up 1.00000 1.00000\n-7 0.03897 host testbed-node-2\n 1 hdd 0.01949 osd.1 up 1.00000 1.00000\n 3 hdd 0.01949 osd.3 up 1.00000 1.00000\n"})}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(t.h3,{id:"ceph-via-rook-technical-preview",children:"Ceph via Rook (technical preview)"}),"\n",(0,l.jsxs)(t.p,{children:["Please have a look at ",(0,l.jsx)(t.a,{href:"/docs/iaas/guides/deploy-guide/services/rook",children:"Deploy Guide - Services - Rook"})," and ",(0,l.jsx)(t.a,{href:"/docs/iaas/guides/configuration-guide/rook",children:"Configuration Guide - Rook"})," for details on how to configure Rook."]}),"\n",(0,l.jsx)(t.p,{children:"To deploy this in the testbed, you can use an environment variable in your make target."}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:"make CEPH_STACK=rook manager\nmake CEPH_STACK=rook ceph\n"})}),"\n",(0,l.jsxs)(t.p,{children:["This will make sure ",(0,l.jsx)(t.code,{children:"/opt/manager-vars.sh"})," gets ",(0,l.jsx)(t.code,{children:"CEPH_STACK=rook"})," set which is later being used by:"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:"/opt/configuration/scripts/deploy-services.sh\n/opt/configuration/scripts/deploy-ceph-services.sh\n/opt/configuration/scripts/upgrade/100-rook-services.sh\n"})}),"\n",(0,l.jsx)(t.h2,{id:"using-testbed-for-openstack-development",children:"Using testbed for OpenStack development"}),"\n",(0,l.jsxs)(t.p,{children:["Testbed may be used for doing development on OpenStack services through ",(0,l.jsx)(t.a,{href:"https://docs.openstack.org/kolla-ansible/latest/contributor/kolla-for-openstack-development.html",children:(0,l.jsx)(t.code,{children:"kolla_dev_mode"})}),".\n",(0,l.jsx)(t.code,{children:"kolla_dev_mode"})," may be activated for all supported service by adding"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:"kolla_dev_mode: true\n"})}),"\n",(0,l.jsxs)(t.p,{children:["to ",(0,l.jsx)(t.code,{children:"environments/kolla/configuration.yml"}),". This will check out the ",(0,l.jsx)(t.code,{children:"git"})," repositories of all supported and enabled OpenStack services under ",(0,l.jsx)(t.code,{children:"/opt/stack"})," and bind mount them into the appropriate containers.\nSince this will fetch a lot of repositories it is advisable to enable this only selectively for the services you are going to work on. You can do so by adding a boolean variable to ",(0,l.jsx)(t.code,{children:"environments/kolla/configuration.yml"})," consisting of the service name and the suffix ",(0,l.jsx)(t.code,{children:"_dev_mode"}),", e.g.:"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:"cinder_dev_mode: true\n"})}),"\n",(0,l.jsxs)(t.p,{children:["You may customise the used ",(0,l.jsx)(t.code,{children:"git"})," repository by adding ",(0,l.jsx)(t.code,{children:"kolla_repos_git"})," to ",(0,l.jsx)(t.code,{children:"environments/kolla/configuration.yml"})," to specify a common root for the repositories of all services, which will be completed by the service's name, e.g.:"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:'kolla_repos_git: "https://github.com/openstack"\n'})}),"\n",(0,l.jsxs)(t.p,{children:["will pull services from their ",(0,l.jsx)(t.code,{children:"github"})," mirror. E.g. pull nova from ",(0,l.jsx)(t.a,{href:"https://github.com/openstack/nova",children:"https://github.com/openstack/nova"}),"\nThe complete repository of a single service may be changed by adding a variable consisting of the service name and the suffix ",(0,l.jsx)(t.code,{children:"_git_repository"}),", e.g."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:'cinder_git_repository: "https://github.com/myorg/my_custom_cinder_fork"\n'})}),"\n",(0,l.jsxs)(t.p,{children:["You may Specify the ",(0,l.jsx)(t.code,{children:"git"})," reference globally by setting"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:"kolla_source_version: my_feature_branch\n"})}),"\n",(0,l.jsxs)(t.p,{children:["in ",(0,l.jsx)(t.code,{children:"environments/kolla/configuration.yml"})," or for specific services via service name and suffix ",(0,l.jsx)(t.code,{children:"_source_version"}),", e.g."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:"cinder_source_version: my_cinder_feature\n"})}),"\n",(0,l.jsxs)(t.p,{children:["In order to update the ",(0,l.jsx)(t.code,{children:"git"})," repositories on ",(0,l.jsx)(t.code,{children:"kolla-ansible"})," deployments set either"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:"kolla_dev_repos_pull: true\n"})}),"\n",(0,l.jsx)(t.p,{children:"or, e.g."}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{children:"cinder_dev_repos_pull: true\n"})}),"\n",(0,l.jsxs)(t.p,{children:["in ",(0,l.jsx)(t.code,{children:"environments/kolla/configuration.yml"})," to set the setting for all repositories or a service specific one."]}),"\n",(0,l.jsx)(t.p,{children:"Thus, as an example for a development workflow:"}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsxs)(t.li,{children:["Create a ",(0,l.jsx)(t.code,{children:"git"})," mirror of the OpenStack service you want to work on"]}),"\n",(0,l.jsxs)(t.li,{children:["In ",(0,l.jsx)(t.code,{children:"environments/kolla/configuration.yml"}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsxs)(t.li,{children:["Set the corresponding ",(0,l.jsx)(t.code,{children:"_dev_mode"})," variable to ",(0,l.jsx)(t.code,{children:"true"})]}),"\n",(0,l.jsxs)(t.li,{children:["Set the corresponding ",(0,l.jsx)(t.code,{children:"_git_repository"})," variable to your development mirror created above"]}),"\n",(0,l.jsxs)(t.li,{children:["Set the corresponding ",(0,l.jsx)(t.code,{children:"_source_version"})," variable to a branch name you intend to push your changes to"]}),"\n",(0,l.jsxs)(t.li,{children:["Set the corresponding ",(0,l.jsx)(t.code,{children:"_dev_repos_pull"})," variable to ",(0,l.jsx)(t.code,{children:"true"})]}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(t.li,{children:"Commit your changes and push them to the specified branch in the specified mirror"}),"\n",(0,l.jsxs)(t.li,{children:["Run ",(0,l.jsx)(t.code,{children:"osism apply "})," on the manager to checkout the code on every testbed node"]}),"\n",(0,l.jsx)(t.li,{children:"Restart the service containers to actually pick up the new code"}),"\n"]}),"\n",(0,l.jsx)(t.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,l.jsx)(t.h3,{id:"ansible-errors",children:"Ansible errors"}),"\n",(0,l.jsxs)(t.p,{children:["Ansible errors that have something to do with undefined variables (e.g. ",(0,l.jsx)(t.code,{children:"AnsibleUndefined"}),") are most likely due to cached\nfacts that are no longer valid. The facts can be updated by running ",(0,l.jsx)(t.code,{children:"osism apply facts"}),"."]}),"\n",(0,l.jsx)(t.h3,{id:"unsupported-locale-setting",children:"Unsupported locale setting"}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"$ make prepare\nansible-playbook -i localhost, ansible/check-local-versions.yml\nERROR: Ansible could not initialize the preferred locale: unsupported locale setting\nmake: *** [prepare] Error 1\n"})}),"\n",(0,l.jsxs)(t.p,{children:["To solve the problem you have to modify the ",(0,l.jsx)(t.code,{children:"Makefile"}),". Change the 1st line as follows."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"export LC_ALL=en_US.UTF-8\n"})}),"\n",(0,l.jsxs)(t.p,{children:["To find out the locale used on the system ",(0,l.jsx)(t.code,{children:"printenv"})," can be used."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:'$ printenv | grep -i lang|locale\nLANG="en_US.UTF-8"\nLC_COLLATE="en_US.UTF-8"\nLC_CTYPE="UTF-8"\nLC_MESSAGES="en_US.UTF-8"\nLC_MONETARY="en_US.UTF-8"\nLC_NUMERIC="en_US.UTF-8"\nLC_TIME="en_US.UTF-8"\nLC_ALL=\n'})}),"\n",(0,l.jsx)(t.h2,{id:"appendix",children:"Appendix"}),"\n",(0,l.jsx)(t.h3,{id:"configuration",children:"Configuration"}),"\n",(0,l.jsx)(t.p,{children:"This section describes how to configure and customise the OSISM Testbed."}),"\n",(0,l.jsx)(t.h4,{id:"variables",children:"Variables"}),"\n",(0,l.jsxs)(t.p,{children:["The defaults for the OpenTofu variables are intended for ",(0,l.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"}),"."]}),"\n",(0,l.jsxs)(t.table,{children:[(0,l.jsx)(t.thead,{children:(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Variable"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Default"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,l.jsxs)(t.tbody,{children:[(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"availability_zone"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"nova"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"ceph_version"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"quincy"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"cloud_provider"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"regiocloud"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"configuration_version"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"main"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"deploy_monitoring"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"false"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"dns_nameservers"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:'["8.8.8.8", "9.9.9.9"]'})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"enable_config_drive"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"true"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"external_api"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"false"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"flavor_manager"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"SCS-4V-16-50"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"flavor_node"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"SCS-8V-32-50"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"image"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"Ubuntu 22.04"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Only Ubuntu 22.04 is currently supported"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"image_node"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"Ubuntu 22.04"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"Only Ubuntu 22.04 is currently supported"})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"keypair"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"testbed"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"manager_version"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"latest"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"network_availability_zone"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"nova"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"number_of_nodes"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"3"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"number_of_volumes"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"3"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"openstack_version"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"2023.2"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"prefix"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"testbed"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"public"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"external"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"refstack"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"false"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"volume_availability_zone"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"nova"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"volume_size_base"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"30"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"volume_size_storage"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"10"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:"volume_type"}),(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"__DEFAULT__"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,l.jsx)(t.h4,{id:"overrides",children:"Overrides"}),"\n",(0,l.jsxs)(t.table,{children:[(0,l.jsx)(t.thead,{children:(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,l.jsxs)(t.tbody,{children:[(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"manager_boot_from_image"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"manager_boot_from_volume"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"neutron_availability_zone_hints_network"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"neutron_availability_zone_hints_router"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"neutron_router_enable_snat"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"nodes_boot_from_image"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"nodes_boot_from_volume"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"nodes_use_ephemeral_storage"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,l.jsx)(t.h4,{id:"customisations",children:"Customisations"}),"\n",(0,l.jsxs)(t.table,{children:[(0,l.jsx)(t.thead,{children:(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,l.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,l.jsxs)(t.tbody,{children:[(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"access_floatingip"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"access_ipv4"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"access_ipv6"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"default"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"external_api"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(t.tr,{children:[(0,l.jsx)(t.td,{style:{textAlign:"left"},children:(0,l.jsx)(t.code,{children:"neutron_floatingip"})}),(0,l.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,l.jsx)(t.h3,{id:"notes",children:"Notes"}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsx)(t.li,{children:"The configuration is intentionally kept quite static. Please create no PRs to make the configuration more flexible/dynamic."}),"\n",(0,l.jsx)(t.li,{children:"The OSISM documentation uses hostnames, examples, addresses etc. from OSISM Testbed."}),"\n",(0,l.jsxs)(t.li,{children:["The third volume (",(0,l.jsx)(t.code,{children:"/dev/sdd"}),") is not enabled for Ceph by default. This is to test the scaling of Ceph."]}),"\n",(0,l.jsx)(t.li,{children:"The manager is used as pull through cache for Docker images and Ubuntu packages. This reduces the amount of traffic consumed."}),"\n"]}),"\n",(0,l.jsx)(t.h3,{id:"supported-releases",children:"Supported releases"}),"\n",(0,l.jsx)(t.p,{children:"The following stable Ceph and OpenStack releases are supported."}),"\n",(0,l.jsxs)(t.p,{children:["The deployment of Ceph is based on ",(0,l.jsx)(t.a,{href:"https://docs.ceph.com/ceph-ansible/",children:"ceph-ansible"}),"."]}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsxs)(t.li,{children:["Ceph Quincy (",(0,l.jsx)(t.strong,{children:"default"}),")"]}),"\n",(0,l.jsx)(t.li,{children:"Ceph Reef"}),"\n",(0,l.jsx)(t.li,{children:"Ceph Squid"}),"\n"]}),"\n",(0,l.jsxs)(t.p,{children:["The deployment of OpenStack is based on ",(0,l.jsx)(t.a,{href:"https://docs.openstack.org/kolla-ansible/latest/",children:"kolla-ansible"}),"."]}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsx)(t.li,{children:"OpenStack 2023.1"}),"\n",(0,l.jsx)(t.li,{children:"OpenStack 2023.2"}),"\n",(0,l.jsxs)(t.li,{children:["OpenStack 2024.1 (",(0,l.jsx)(t.strong,{children:"default"}),")"]}),"\n"]}),"\n",(0,l.jsxs)(t.p,{children:["The deployment of Kubernetes is based on ",(0,l.jsx)(t.a,{href:"https://github.com/techno-tim/k3s-ansible",children:"k3s-ansible"}),"."]}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsxs)(t.li,{children:["Kubernetes v1.30 (",(0,l.jsx)(t.strong,{children:"default"}),")"]}),"\n"]}),"\n",(0,l.jsx)(t.h3,{id:"included-services",children:"Included services"}),"\n",(0,l.jsx)(t.p,{children:"The following services can currently be used with the OSISM Testbed without further adjustments."}),"\n",(0,l.jsx)(t.h4,{id:"infrastructure",children:"Infrastructure"}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsx)(t.li,{children:"Ceph"}),"\n",(0,l.jsx)(t.li,{children:"Cluster API Management Cluster"}),"\n",(0,l.jsx)(t.li,{children:"Fluentd"}),"\n",(0,l.jsx)(t.li,{children:"Gnocchi"}),"\n",(0,l.jsx)(t.li,{children:"Grafana"}),"\n",(0,l.jsx)(t.li,{children:"Haproxy"}),"\n",(0,l.jsx)(t.li,{children:"Keepalived"}),"\n",(0,l.jsx)(t.li,{children:"Keycloak"}),"\n",(0,l.jsx)(t.li,{children:"Kubernetes"}),"\n",(0,l.jsx)(t.li,{children:"Mariadb"}),"\n",(0,l.jsx)(t.li,{children:"Memcached"}),"\n",(0,l.jsx)(t.li,{children:"Netbox"}),"\n",(0,l.jsx)(t.li,{children:"Netdata"}),"\n",(0,l.jsx)(t.li,{children:"Opensearch"}),"\n",(0,l.jsx)(t.li,{children:"Openvswitch"}),"\n",(0,l.jsx)(t.li,{children:"Prometheus exporters"}),"\n",(0,l.jsx)(t.li,{children:"Rabbitmq"}),"\n",(0,l.jsx)(t.li,{children:"Redis"}),"\n"]}),"\n",(0,l.jsx)(t.h4,{id:"openstack",children:"OpenStack"}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsx)(t.li,{children:"Barbican"}),"\n",(0,l.jsx)(t.li,{children:"Ceilometer"}),"\n",(0,l.jsx)(t.li,{children:"Cinder"}),"\n",(0,l.jsx)(t.li,{children:"Designate"}),"\n",(0,l.jsx)(t.li,{children:"Glance"}),"\n",(0,l.jsx)(t.li,{children:"Heat"}),"\n",(0,l.jsx)(t.li,{children:"Horizon"}),"\n",(0,l.jsx)(t.li,{children:"Ironic"}),"\n",(0,l.jsx)(t.li,{children:"Keystone"}),"\n",(0,l.jsx)(t.li,{children:"Magnum"}),"\n",(0,l.jsx)(t.li,{children:"Manila"}),"\n",(0,l.jsx)(t.li,{children:"Neutron"}),"\n",(0,l.jsx)(t.li,{children:"Nova (with Libvirt/KVM)"}),"\n",(0,l.jsx)(t.li,{children:"Octavia"}),"\n",(0,l.jsx)(t.li,{children:"Skyline"}),"\n"]}),"\n",(0,l.jsx)(t.h3,{id:"makefile-reference",children:"Makefile reference"}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-bash",children:"$ make help\n\nUsage:\n make \n help Display this help.\n clean Destroy infrastructure with OpenTofu.\n wipe-local-install Wipe the software dependencies in `venv`.\n create Create required infrastructure with OpenTofu.\n login Log in on the manager.\n vpn-wireguard Establish a wireguard vpn tunnel.\n vpn-sshuttle Establish a sshuttle vpn tunnel.\n bootstrap Bootstrap everything.\n manager Deploy only the manager service.\n identity Deploy only identity services.\n ceph Deploy only ceph services.\n deploy Deploy everything and then check it.\n prepare Run local preperations.\n deps Install software preconditions to `venv`.\n\n$ make \n"})}),"\n",(0,l.jsx)(t.h3,{id:"ci-jobs",children:"CI jobs"}),"\n",(0,l.jsxs)(t.p,{children:["You can inspect the ",(0,l.jsx)(t.a,{href:"https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Ftestbed&skip=0",children:"results of the daily zuul jobs"}),"."]})]})}function p(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,l.jsx)(t,{...e,children:(0,l.jsx)(x,{...e})}):x(e)}},19365:(e,t,s)=>{s.d(t,{A:()=>r});s(96540);var n=s(18215);const l={tabItem:"tabItem_Ymn6"};var i=s(74848);function r(e){let{children:t,hidden:s,className:r}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,n.A)(l.tabItem,r),hidden:s,children:t})}},11470:(e,t,s)=>{s.d(t,{A:()=>A});var n=s(96540),l=s(18215),i=s(23104),r=s(56347),d=s(205),o=s(57485),c=s(31682),a=s(70679);function h(e){return n.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,n.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function x(e){const{values:t,children:s}=e;return(0,n.useMemo)((()=>{const e=t??function(e){return h(e).map((e=>{let{props:{value:t,label:s,attributes:n,default:l}}=e;return{value:t,label:s,attributes:n,default:l}}))}(s);return function(e){const t=(0,c.XI)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,s])}function p(e){let{value:t,tabValues:s}=e;return s.some((e=>e.value===t))}function u(e){let{queryString:t=!1,groupId:s}=e;const l=(0,r.W6)(),i=function(e){let{queryString:t=!1,groupId:s}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!s)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return s??null}({queryString:t,groupId:s});return[(0,o.aZ)(i),(0,n.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(l.location.search);t.set(i,e),l.replace({...l.location,search:t.toString()})}),[i,l])]}function j(e){const{defaultValue:t,queryString:s=!1,groupId:l}=e,i=x(e),[r,o]=(0,n.useState)((()=>function(e){let{defaultValue:t,tabValues:s}=e;if(0===s.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!p({value:t,tabValues:s}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${s.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=s.find((e=>e.default))??s[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:i}))),[c,h]=u({queryString:s,groupId:l}),[j,f]=function(e){let{groupId:t}=e;const s=function(e){return e?`docusaurus.tab.${e}`:null}(t),[l,i]=(0,a.Dv)(s);return[l,(0,n.useCallback)((e=>{s&&i.set(e)}),[s,i])]}({groupId:l}),g=(()=>{const e=c??j;return p({value:e,tabValues:i})?e:null})();(0,d.A)((()=>{g&&o(g)}),[g]);return{selectedValue:r,selectValue:(0,n.useCallback)((e=>{if(!p({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);o(e),h(e),f(e)}),[h,f,i]),tabValues:i}}var f=s(92303);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var y=s(74848);function m(e){let{className:t,block:s,selectedValue:n,selectValue:r,tabValues:d}=e;const o=[],{blockElementScrollPositionUntilNextRender:c}=(0,i.a_)(),a=e=>{const t=e.currentTarget,s=o.indexOf(t),l=d[s].value;l!==n&&(c(t),r(l))},h=e=>{let t=null;switch(e.key){case"Enter":a(e);break;case"ArrowRight":{const s=o.indexOf(e.currentTarget)+1;t=o[s]??o[0];break}case"ArrowLeft":{const s=o.indexOf(e.currentTarget)-1;t=o[s]??o[o.length-1];break}}t?.focus()};return(0,y.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.A)("tabs",{"tabs--block":s},t),children:d.map((e=>{let{value:t,label:s,attributes:i}=e;return(0,y.jsx)("li",{role:"tab",tabIndex:n===t?0:-1,"aria-selected":n===t,ref:e=>o.push(e),onKeyDown:h,onClick:a,...i,className:(0,l.A)("tabs__item",g.tabItem,i?.className,{"tabs__item--active":n===t}),children:s??t},t)}))})}function b(e){let{lazy:t,children:s,selectedValue:i}=e;const r=(Array.isArray(s)?s:[s]).filter(Boolean);if(t){const e=r.find((e=>e.props.value===i));return e?(0,n.cloneElement)(e,{className:(0,l.A)("margin-top--md",e.props.className)}):null}return(0,y.jsx)("div",{className:"margin-top--md",children:r.map(((e,t)=>(0,n.cloneElement)(e,{key:t,hidden:e.props.value!==i})))})}function v(e){const t=j(e);return(0,y.jsxs)("div",{className:(0,l.A)("tabs-container",g.tabList),children:[(0,y.jsx)(m,{...t,...e}),(0,y.jsx)(b,{...t,...e})]})}function A(e){const t=(0,f.A)();return(0,y.jsx)(v,{...e,children:h(e.children)},String(t))}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>d});var n=s(96540);const l={},i=n.createContext(l);function r(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:r(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/35fbae7a.f73644fd.js b/assets/js/35fbae7a.f73644fd.js new file mode 100644 index 0000000000..faec5ba086 --- /dev/null +++ b/assets/js/35fbae7a.f73644fd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[91617],{24361:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"cloud-resources/plusserver-gx-scs","title":"Getting Started Gaia-X Demonstrator @ plusserver","description":"Getting Started for the Gaia-X Demonstrator @ plusserver","source":"@site/community/cloud-resources/plusserver-gx-scs.md","sourceDirName":"cloud-resources","slug":"/cloud-resources/plusserver-gx-scs","permalink":"/community/cloud-resources/plusserver-gx-scs","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Getting Started Gaia-X Demonstrator @ plusserver","version":"2022-12-22T00:00:00.000Z","author":"Ralf Heiringhoff, Mathias Fechner"},"sidebar":"community","previous":{"title":"Getting Started with OpenStack","permalink":"/community/cloud-resources/getting-started-openstack"},"next":{"title":"Getting Started with Wavestack","permalink":"/community/cloud-resources/wavestack"}}');var n=s(74848),i=s(28453);const o={title:"Getting Started Gaia-X Demonstrator @ plusserver",version:new Date("2022-12-22T00:00:00.000Z"),author:"Ralf Heiringhoff, Mathias Fechner"},c=void 0,a={},l=[{value:"Getting Started for the Gaia-X Demonstrator @ plusserver",id:"getting-started-for-the-gaia-x-demonstrator--plusserver",level:2},{value:"URLs for access",id:"urls-for-access",level:2},{value:"Authentication (UI)",id:"authentication-ui",level:2},{value:"Getting Started with OpenStack",id:"getting-started-with-openstack",level:2}];function u(e){const t={a:"a",code:"code",h2:"h2",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"getting-started-for-the-gaia-x-demonstrator--plusserver",children:"Getting Started for the Gaia-X Demonstrator @ plusserver"}),"\n",(0,n.jsx)(t.h2,{id:"urls-for-access",children:"URLs for access"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["UI (Horizon): ",(0,n.jsx)(t.a,{href:"https://ui.gx-scs.sovereignit.cloud/",children:"https://ui.gx-scs.sovereignit.cloud/"})]}),"\n",(0,n.jsxs)(t.li,{children:["API auth url (Keystone): ",(0,n.jsx)(t.a,{href:"https://api.gx-scs.sovereignit.cloud:5000",children:"https://api.gx-scs.sovereignit.cloud:5000"})]}),"\n",(0,n.jsxs)(t.li,{children:["Object Storage endpoint (S3/SWIFT): ",(0,n.jsx)(t.a,{href:"https://api.gx-scs.sovereignit.cloud:8080",children:"https://api.gx-scs.sovereignit.cloud:8080"})]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"authentication-ui",children:"Authentication (UI)"}),"\n",(0,n.jsx)(t.p,{children:"For your login you will need:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Username (",(0,n.jsx)(t.code,{children:"u500924-<$github-handle>"}),")"]}),"\n",(0,n.jsx)(t.li,{children:"Password"}),"\n",(0,n.jsxs)(t.li,{children:["Domain (",(0,n.jsx)(t.code,{children:"d500924"}),")"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"getting-started-with-openstack",children:"Getting Started with OpenStack"}),"\n",(0,n.jsxs)(t.p,{children:["See ",(0,n.jsx)(t.a,{href:"/community/cloud-resources/getting-started-openstack",children:"Getting Started with OpenStack"})]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>c});var r=s(96540);const n={},i=r.createContext(n);function o(e){const t=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/36994c47.63c2e6ec.js b/assets/js/36994c47.63c2e6ec.js new file mode 100644 index 0000000000..b2a797dc68 --- /dev/null +++ b/assets/js/36994c47.63c2e6ec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[89858],{45516:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-blog","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/36c47bdd.094edef4.js b/assets/js/36c47bdd.094edef4.js new file mode 100644 index 0000000000..aa3902650a --- /dev/null +++ b/assets/js/36c47bdd.094edef4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9766],{41284:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>s,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"collaboration/team-ops","title":"Team Ops","description":"We build tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.","source":"@site/community/collaboration/team-ops.md","sourceDirName":"collaboration","slug":"/collaboration/team-ops","permalink":"/community/collaboration/team-ops","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Team Container","permalink":"/community/collaboration/team-container"},"next":{"title":"SIG Central API","permalink":"/community/collaboration/sig-central-api"}}');var a=n(74848),r=n(28453);const s={},i="Team Ops",c={},l=[];function u(e){const t={h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"team-ops",children:"Team Ops"})}),"\n",(0,a.jsx)(t.p,{children:"We build tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud."})]})}function m(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>i});var o=n(96540);const a={},r=o.createContext(a);function s(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/36d4bf8b.49617d24.js b/assets/js/36d4bf8b.49617d24.js new file mode 100644 index 0000000000..cb49498571 --- /dev/null +++ b/assets/js/36d4bf8b.49617d24.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[26590],{1273:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"scs-0121-w1-Availability-Zones-Standard","title":"SCS Availability Zones: Implementation and Testing Notes","description":"Automated Tests","source":"@site/standards/scs-0121-w1-Availability-Zones-Standard.md","sourceDirName":".","slug":"/scs-0121-w1-Availability-Zones-Standard","permalink":"/standards/scs-0121-w1-Availability-Zones-Standard","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Availability Zones: Implementation and Testing Notes","type":"Supplement","track":"IaaS","status":"Draft","supplements":["scs-0121-v1-Availability-Zones-Standard.md"]},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0121-v1-Availability-Zones-Standard"},"next":{"title":"scs-0122: _End-to-End Encryption between Customer Workloads_","permalink":"/standards/iaas/scs-0122"}}');var a=n(74848),s=n(28453);const o={title:"SCS Availability Zones: Implementation and Testing Notes",type:"Supplement",track:"IaaS",status:"Draft",supplements:["scs-0121-v1-Availability-Zones-Standard.md"]},r=void 0,d={},l=[{value:"Automated Tests",id:"automated-tests",level:2},{value:"Required Documentation",id:"required-documentation",level:2},{value:"Alternative Documentation",id:"alternative-documentation",level:3},{value:"Physical Audits",id:"physical-audits",level:2}];function c(e){const t={a:"a",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h2,{id:"automated-tests",children:"Automated Tests"}),"\n",(0,a.jsx)(t.p,{children:"The standard will not preclude small deployments and edge deployments, that both will not meet the requirement for being divided into multiple Availability Zones.\nThus multiple Availability Zones are not always present.\nSomtimes there can just be a single Availability Zones.\nBecause of that, there will be no automated tests to search for AZs."}),"\n",(0,a.jsx)(t.h2,{id:"required-documentation",children:"Required Documentation"}),"\n",(0,a.jsx)(t.p,{children:"The requirements for each Availability Zone are written in the Standard.\nFor each deployment, that uses more than a single Availability Zone, the CSP has to provide documentation to proof the following points:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:"The presence of fire zones MUST be documented (e.g. through construction plans of the deployment)."}),"\n",(0,a.jsx)(t.li,{children:"The correct configuration of one AZ per fire zone MUST be documented."}),"\n",(0,a.jsx)(t.li,{children:"The redundancy in Power Supply within each AZ MUST be documented."}),"\n",(0,a.jsx)(t.li,{children:"The redundancy in external connection within each AZ MUST be documented."}),"\n",(0,a.jsx)(t.li,{children:"The redundancy in core routers within each AZ MUST be documented."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"All of these requirements will either not change at all like the fire zones or it is very unlikely for them to change like redundant internet connection.\nBecause of this documentation must only be provided in the following cases:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:"When a new deployment with multiple AZs should be tested for compliance."}),"\n",(0,a.jsx)(t.li,{children:"When there are physical changes in a deplyoment, which already provided the documentation: the changes needs to be documented and provided as soon as possible."}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"alternative-documentation",children:"Alternative Documentation"}),"\n",(0,a.jsx)(t.p,{children:"If a deployment already did undergo certification like ISO 27001 or ISO 9001, those certificates can be provided as part of the documentation to cover the redundancy parts.\nIt is still required to document the existence of fire zones and the correct configuration of one AZ per fire zone."}),"\n",(0,a.jsx)(t.h2,{id:"physical-audits",children:"Physical Audits"}),"\n",(0,a.jsxs)(t.p,{children:["In cases where it is reasonable to mistrust the provided documentation, a physical audit by a natural person - called auditor - send by e.g. the ",(0,a.jsx)(t.a,{href:"https://osb-alliance.de/",children:"OSBA"})," should be performed.\nThe CSP of the deployment, which needs such an audit, should grant access to the auditor to the physical infrastructure and should show them all necessary IaaS-Layer configurations, that are needed to verify compliance to this standard."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var i=n(96540);const a={},s=i.createContext(a);function o(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/36f749d2.2c85dfe6.js b/assets/js/36f749d2.2c85dfe6.js new file mode 100644 index 0000000000..65995623a4 --- /dev/null +++ b/assets/js/36f749d2.2c85dfe6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[14602],{22905:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"operating-scs/audits/index","title":"Overview","description":"TODO","source":"@site/docs/04-operating-scs/04-audits/index.md","sourceDirName":"04-operating-scs/04-audits","slug":"/operating-scs/audits/","permalink":"/docs/operating-scs/audits/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/04-audits/index.md","tags":[],"version":"current","frontMatter":{}}');var r=n(74848),o=n(28453);const c={},i="Overview",a={},d=[];function u(e){const t={h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(t.p,{children:"TODO"})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var s=n(96540);const r={},o=s.createContext(r);function c(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/37a5cb6b.73cefc7d.js b/assets/js/37a5cb6b.73cefc7d.js new file mode 100644 index 0000000000..56db234375 --- /dev/null +++ b/assets/js/37a5cb6b.73cefc7d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[91384],{51727:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>l,frontMatter:()=>d,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"ops/scs-0402","title":"scs-0402: Status page OpenAPI decision","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/ops/scs-0402.md","sourceDirName":"ops","slug":"/ops/scs-0402","permalink":"/standards/ops/scs-0402","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0401-v1-status-page-reference-implementation-decision"},"next":{"title":"V1","permalink":"/standards/scs-0402-v1-status-page-openapi-spec-decision"}}');var r=t(74848),c=t(28453);const d={},a="scs-0402: Status page OpenAPI decision",i={},o=[];function p(e){const s={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"scs-0402-status-page-openapi-decision",children:"scs-0402: Status page OpenAPI decision"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0402-v1-status-page-openapi-spec-decision",children:"scs-0402-v1"})}),(0,r.jsx)(s.td,{children:"Decision Record"}),(0,r.jsx)(s.td,{children:"Draft"}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]})})]})]})}function l(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>d,x:()=>a});var n=t(96540);const r={},c=n.createContext(r);function d(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/38c9ef35.6b1b4eed.js b/assets/js/38c9ef35.6b1b4eed.js new file mode 100644 index 0000000000..f7fb453323 --- /dev/null +++ b/assets/js/38c9ef35.6b1b4eed.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[13131],{35042:(e,t,s)=>{s.r(t),s.d(t,{TableCellStyleApplier:()=>o,assets:()=>i,contentTitle:()=>l,default:()=>x,frontMatter:()=>c,metadata:()=>n,toc:()=>h});const n=JSON.parse('{"id":"global/index","title":"Global Standards","description":"This track encompasses the foundational standards that guide the overall structure, documentation, and general topics related to the Sovereign Cloud Stack. It serves as the core framework, ensuring consistency, clarity, and comprehensibility across all aspects of the cloud stack, fostering an environment where information is easily accessible and understood.","source":"@site/standards/global/index.md","sourceDirName":"global","slug":"/global/","permalink":"/standards/global/","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"Overview","permalink":"/standards/standards/overview"},"next":{"title":"scs-0001: Sovereign Cloud Standards","permalink":"/standards/global/scs-0001"}}');var r=s(74848),d=s(28453),a=s(96540);const c={},l="Global Standards",i={},o=()=>{const e={3:"#FBFDE2",4:"#E2EAFD",5:"#FDE2E2"},t={2:"#FBFDE2",3:"#E2EAFD",4:"#FDE2E2"};return(0,a.useEffect)((()=>{const s=(e,t)=>{const s=document.querySelector("#"+e);if(s){const e=s.nextElementSibling;e&&"table"===e.tagName.toLowerCase()&&e.querySelectorAll("tbody tr").forEach((e=>{e.querySelectorAll("td").forEach(((e,s)=>{t[s]&&"-"!==e.textContent.trim()&&(e.style.backgroundColor=t[s])}))}))}};s("color-table-cells-overview",e),s("color-table-cells-track-overview",t)}),[]),null},h=[];function u(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"global-standards",children:"Global Standards"})}),"\n",(0,r.jsx)(t.p,{children:"This track encompasses the foundational standards that guide the overall structure, documentation, and general topics related to the Sovereign Cloud Stack. It serves as the core framework, ensuring consistency, clarity, and comprehensibility across all aspects of the cloud stack, fostering an environment where information is easily accessible and understood."}),"\n",(0,r.jsx)("p",{children:"*Legend to the column headings and entries:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Document states: Draft, Effective, Deprecated (and no longer effective)"}),"\n",(0,r.jsx)(t.li,{children:"Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future"}),"\n",(0,r.jsx)(t.li,{children:"Entries in the effective column marked with a \u2020 will turn deprecated in the near future"}),"\n"]}),"\n","\n","\n",(0,r.jsx)(o,{}),"\n",(0,r.jsx)("div",{id:"color-table-cells-track-overview"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Standard"}),(0,r.jsx)(t.th,{children:"Description"}),(0,r.jsx)(t.th,{children:"Draft"}),(0,r.jsx)(t.th,{children:"Effective"}),(0,r.jsx)(t.th,{children:"Deprecated*"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/global/scs-0001",children:"scs-0001"})}),(0,r.jsx)(t.td,{children:"Sovereign Cloud Standards"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0001-v1-sovereign-cloud-standards",children:"v1"})}),(0,r.jsx)(t.td,{children:"-"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/global/scs-0002",children:"scs-0002"})}),(0,r.jsx)(t.td,{children:"Standards, Docs and Organisation"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0002-v2-standards-docs-org",children:"v2"})}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0002-v1-standards-docs-org",children:"v1"})}),(0,r.jsx)(t.td,{children:"-"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/global/scs-0003",children:"scs-0003"})}),(0,r.jsx)(t.td,{children:"Sovereign Cloud Standards YAML"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",children:"v1"})}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/global/scs-0004",children:"scs-0004"})}),(0,r.jsx)(t.td,{children:"Regulations for achieving SCS-compatible certification"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0004-v1-achieving-certification",children:"v1"})}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/global/scs-0005",children:"scs-0005"})}),(0,r.jsx)(t.td,{children:"Governance of the SCS community"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0005-v1-project-governance",children:"v1"})}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})]})]})]})}function x(e={}){const{wrapper:t}={...(0,d.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>c});var n=s(96540);const r={},d=n.createContext(r);function a(e){const t=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(d.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3a1d878d.38aa923b.js b/assets/js/3a1d878d.38aa923b.js new file mode 100644 index 0000000000..4170fb968f --- /dev/null +++ b/assets/js/3a1d878d.38aa923b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[78031],{72731:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"iaas/guides/concept-guide/components/openstack","title":"OpenStack","description":"Lifecycle Management of OpenStack in OSISM","source":"@site/docs/02-iaas/guides/concept-guide/components/openstack.md","sourceDirName":"02-iaas/guides/concept-guide/components","slug":"/iaas/guides/concept-guide/components/openstack","permalink":"/docs/iaas/guides/concept-guide/components/openstack","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/openstack.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Netdata","permalink":"/docs/iaas/guides/concept-guide/components/netdata"},"next":{"title":"Prometheus & Grafana","permalink":"/docs/iaas/guides/concept-guide/components/prometheus"}}');var c=t(74848),i=t(28453);const o={},r="OpenStack",a={},l=[{value:"Lifecycle Management of OpenStack in OSISM",id:"lifecycle-management-of-openstack-in-osism",level:2},{value:"OpenStack cluster",id:"openstack-cluster",level:2},{value:"OpenStack services architecture",id:"openstack-services-architecture",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"openstack",children:"OpenStack"})}),"\n",(0,c.jsx)(n.h2,{id:"lifecycle-management-of-openstack-in-osism",children:"Lifecycle Management of OpenStack in OSISM"}),"\n",(0,c.jsxs)(n.p,{children:["The open source project Kolla from the ",(0,c.jsx)(n.a,{href:"https://openinfra.dev",children:"OpenInfra Foundation"})," is\nused in OSISM for the life cycle management of OpenStack. Kolla\u2019s mission is to provide\nproduction-ready containers and deployment tools for operating OpenStack clouds. Kolla has\nbeen actively developed by a very diverse team for 10 years and is one of the most common\n(if not the most common) life cycle management tool for OpenStack."]}),"\n",(0,c.jsxs)(n.p,{children:["The container images provided by Kolla are not only used by Kolla itself. They are also used\nin TripleO, the basis for the now discontinued\n",(0,c.jsx)(n.a,{href:"https://www.redhat.com/en/technologies/linux-platforms/openstack-platform",children:"RedHat OpenStack Platform"}),",\nand the ",(0,c.jsx)(n.a,{href:"https://github.com/openstack-k8s-operators",children:"OpenStack Kubernetes Operators"}),",\nthe basis for the new\n",(0,c.jsx)(n.a,{href:"https://www.redhat.com/en/blog/red-hat-openstack-services-openshift-next-generation-red-hat-openstack-platform",children:"RedHat OpenStack Services on OpenShift"}),"."]}),"\n",(0,c.jsx)(n.h2,{id:"openstack-cluster",children:"OpenStack cluster"}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"OpenStack cluster",src:t(39523).A+"",width:"918",height:"413"})}),"\n",(0,c.jsxs)(n.p,{children:["Image source: ",(0,c.jsx)(n.a,{href:"https://redhatquickcourses.github.io/rhoso-intro/rhoso-intro/1/ch1-intro/s1-rhoso-lecture.html",children:"Introduction to Red Hat OpenStack Services on OpenShift"})]}),"\n",(0,c.jsx)(n.h2,{id:"openstack-services-architecture",children:"OpenStack services architecture"}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"OpenStack Services Architecture",src:t(91881).A+"",width:"960",height:"540"})}),"\n",(0,c.jsxs)(n.p,{children:["Image source: ",(0,c.jsx)(n.a,{href:"https://redhatquickcourses.github.io/rhoso-intro/rhoso-intro/1/ch2-services/s1-fundamental-lecture.html",children:"Introduction to Red Hat OpenStack Services on OpenShift"})]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Swift: Object Storage"}),"\n",(0,c.jsx)(n.li,{children:"Manila: Shared Filesystems"}),"\n",(0,c.jsx)(n.li,{children:"Octavia: Load balancer"}),"\n",(0,c.jsx)(n.li,{children:"Designate: DNS"}),"\n",(0,c.jsx)(n.li,{children:"Heat: Orchestration"}),"\n",(0,c.jsx)(n.li,{children:"Placement"}),"\n",(0,c.jsx)(n.li,{children:"Barbican: Key Management"}),"\n",(0,c.jsx)(n.li,{children:"Nova: Compute"}),"\n",(0,c.jsx)(n.li,{children:"Cinder: Block Storage"}),"\n",(0,c.jsx)(n.li,{children:"Neutron: Networking"}),"\n",(0,c.jsx)(n.li,{children:"Glance: Image"}),"\n",(0,c.jsx)(n.li,{children:"Horizon: Dashboard"}),"\n",(0,c.jsx)(n.li,{children:"Ironic: Bare Metal Provisioning"}),"\n",(0,c.jsx)(n.li,{children:"Ceilometer: Metering"}),"\n"]}),"\n",(0,c.jsx)(n.h1,{id:"general-architecture-of-openstack-services",children:"General architecture of OpenStack services"}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"General Architecture of OpenStack Services",src:t(32885).A+"",width:"908",height:"506"})}),"\n",(0,c.jsxs)(n.p,{children:["Image source: ",(0,c.jsx)(n.a,{href:"https://redhatquickcourses.github.io/rhoso-arch/rhoso-arch/1/ch1-architecture/s6-services-lecture.html",children:"Red Hat OpenStack Services on OpenShift Architecture"})]}),"\n",(0,c.jsx)(n.h1,{id:"multitenancy-with-openstack",children:"Multitenancy with OpenStack"}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"Multitenancy with OpenStack",src:t(52818).A+"",width:"903",height:"503"})}),"\n",(0,c.jsxs)(n.p,{children:["Image source: ",(0,c.jsx)(n.a,{href:"https://redhatquickcourses.github.io/rhoso-intro/rhoso-intro/1/ch3-multitenancy/s1-domains-projects-lecture.html",children:"Introduction to Red Hat OpenStack Services on OpenShift"})]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},52818:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/s1-domains-projects-lecture-fig-1-85eace851f17244e8c410d319fd55cc4.svg"},91881:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/s1-fundamental-lecture-fig-1-8aac37d55a5191ee7a290c7dbd100d01.svg"},39523:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/s1-rhoso-lecture-fig-1-bf5bf84557b4600b84d1467713715582.svg"},32885:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/s6-services-lecture-fig-1-ec3163f80b85ce6087ada1336c259ac7.svg"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const c={},i=s.createContext(c);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3a2db09e.a962eb9b.js b/assets/js/3a2db09e.a962eb9b.js new file mode 100644 index 0000000000..273caabc7a --- /dev/null +++ b/assets/js/3a2db09e.a962eb9b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[18121],{68070:o=>{o.exports=JSON.parse('{"tags":[{"label":"community","permalink":"/blog/tags/community","count":1},{"label":"howto","permalink":"/blog/tags/howto","count":1}]}')}}]); \ No newline at end of file diff --git a/assets/js/3a36ab0d.30a77aa2.js b/assets/js/3a36ab0d.30a77aa2.js new file mode 100644 index 0000000000..d8b58359ec --- /dev/null +++ b/assets/js/3a36ab0d.30a77aa2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[46125],{13383:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"scs-0214-w1-k8s-node-distribution-implementation-testing","title":"Kubernetes Node Distribution and Availability: Implementation and Testing Notes","description":"Implementation notes","source":"@site/standards/scs-0214-w1-k8s-node-distribution-implementation-testing.md","sourceDirName":".","slug":"/scs-0214-w1-k8s-node-distribution-implementation-testing","permalink":"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Kubernetes Node Distribution and Availability: Implementation and Testing Notes","type":"Supplement","track":"KaaS","status":"Draft","supplements":["scs-0214-v1-k8s-node-distribution.md","scs-0214-v2-k8s-node-distribution.md"]},"sidebar":"standards","previous":{"title":"V2","permalink":"/standards/scs-0214-v2-k8s-node-distribution"},"next":{"title":"scs-0215: Robustness features for Kubernetes clusters","permalink":"/standards/kaas/scs-0215"}}');var i=n(74848),o=n(28453);const a={title:"Kubernetes Node Distribution and Availability: Implementation and Testing Notes",type:"Supplement",track:"KaaS",status:"Draft",supplements:["scs-0214-v1-k8s-node-distribution.md","scs-0214-v2-k8s-node-distribution.md"]},r=void 0,d={},l=[{value:"Implementation notes",id:"implementation-notes",level:2},{value:"Automated tests",id:"automated-tests",level:2},{value:"Manual tests",id:"manual-tests",level:2}];function u(e){const t={a:"a",code:"code",h2:"h2",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"implementation-notes",children:"Implementation notes"}),"\n",(0,i.jsx)(t.p,{children:'A Kubernetes clusters control plane must be distributed over multiple physical machines, as well\nas different "failure zones". How these are defined is at the moment up to the CSP.\nWorker nodes can also be distributed over "failure zones", but this isn\'t a requirement.\nDistribution must be shown through labelling, so that users can access these information.'}),"\n",(0,i.jsxs)(t.p,{children:["Node distribution metadata is provided through the usage of the labels\n",(0,i.jsx)(t.code,{children:"topology.kubernetes.io/region"})," and ",(0,i.jsx)(t.code,{children:"topology.kubernetes.io/zone"}),"."]}),"\n",(0,i.jsx)(t.h2,{id:"automated-tests",children:"Automated tests"}),"\n",(0,i.jsx)(t.p,{children:"Currently, automated testing is not readily possible because we cannot access information about\nthe underlying host of a node (as opposed to its region and zone). Therefore, the test will only output\na tentative result."}),"\n",(0,i.jsxs)(t.p,{children:["The current implementation can be found in the script ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/kaas/k8s-node-distribution/k8s_node_distribution_check.py",children:(0,i.jsx)(t.code,{children:"k8s_node_distribution_check.py"})}),"."]}),"\n",(0,i.jsx)(t.h2,{id:"manual-tests",children:"Manual tests"}),"\n",(0,i.jsx)(t.p,{children:"None."})]})}function c(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var s=n(96540);const i={},o=s.createContext(i);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3abbf0e9.9c0ef763.js b/assets/js/3abbf0e9.9c0ef763.js new file mode 100644 index 0000000000..6687977a35 --- /dev/null +++ b/assets/js/3abbf0e9.9c0ef763.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[80231],{81252:(e,i,o)=>{o.r(i),o.d(i,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>a});const n=JSON.parse('{"id":"iaas/guides/operations-guide/rookify","title":"Use Rookify: Migrate to Rook from Ceph Ansible (Technical Preview)","description":"Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime.","source":"@site/docs/02-iaas/guides/operations-guide/rookify.md","sourceDirName":"02-iaas/guides/operations-guide","slug":"/iaas/guides/operations-guide/rookify","permalink":"/docs/iaas/guides/operations-guide/rookify","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/rookify.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Rookify (technical preview)"},"sidebar":"docs","previous":{"title":"Ceph via Rook (technical preview)","permalink":"/docs/iaas/guides/operations-guide/rook"},"next":{"title":"Troubleshooting Guide","permalink":"/docs/iaas/guides/troubleshooting-guide/"}}');var t=o(74848),s=o(28453);const r={sidebar_label:"Rookify (technical preview)"},l="Use Rookify: Migrate to Rook from Ceph Ansible (Technical Preview)",d={},a=[{value:"Consider Using a Pickle File",id:"consider-using-a-pickle-file",level:2},{value:"Rookify CLI",id:"rookify-cli",level:2},{value:"Run",id:"run",level:3},{value:"--dry-run",id:"--dry-run",level:3},{value:"--migrate",id:"--migrate",level:3},{value:"--help",id:"--help",level:3},{value:"--show-states",id:"--show-states",level:3},{value:"Debugging and Testing",id:"debugging-and-testing",level:2},{value:"Set logging to debug level",id:"set-logging-to-debug-level",level:3},{value:"Run tests",id:"run-tests",level:3}];function c(e){const i={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.header,{children:(0,t.jsx)(i.h1,{id:"use-rookify-migrate-to-rook-from-ceph-ansible-technical-preview",children:"Use Rookify: Migrate to Rook from Ceph Ansible (Technical Preview)"})}),"\n",(0,t.jsx)(i.admonition,{type:"warning",children:(0,t.jsxs)(i.p,{children:["Rookify is developed to migrate from Ceph-Ansible to Rook ",(0,t.jsx)(i.em,{children:"in place"})," and ",(0,t.jsx)(i.em,{children:"without downtime"}),".\nNevertheless, it is ",(0,t.jsx)(i.strong,{children:"strongly advised"})," to test Rookify in a controlled environment first, such as the ",(0,t.jsx)(i.a,{href:"https://github.com/osism/testbed",children:"OSISM testbed"}),". Additionally ensure that precautionary backups are made and all other necessary safety measures are in place."]})}),"\n",(0,t.jsxs)(i.p,{children:["For a condensed summary of the information covered here, refer to the ",(0,t.jsx)(i.a,{href:"https://github.com/SovereignCloudStack/rookify",children:"Rookify GitHub repository"}),"."]}),"\n",(0,t.jsx)(i.h2,{id:"consider-using-a-pickle-file",children:"Consider Using a Pickle File"}),"\n",(0,t.jsxs)(i.p,{children:["To track the migration, you can add a pickle file. Specify this option in the ",(0,t.jsx)(i.code,{children:"config.yaml"}),":"]}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{className:"language-yaml",metastring:'title="config.example.yaml"',children:"general:\n machine_pickle_file: data.pickle\n"})}),"\n",(0,t.jsxs)(i.p,{children:["You can then view the migration progress by running ",(0,t.jsx)(i.code,{children:"rookify --show-states"}),"."]}),"\n",(0,t.jsx)(i.admonition,{type:"warning",children:(0,t.jsx)(i.p,{children:"Rookify treats the pickle file as a source of truth for its operations. If you want to start a clean migration, ensure you delete the file first."})}),"\n",(0,t.jsx)(i.h2,{id:"rookify-cli",children:"Rookify CLI"}),"\n",(0,t.jsx)(i.h3,{id:"run",children:"Run"}),"\n",(0,t.jsx)(i.admonition,{type:"note",children:(0,t.jsxs)(i.p,{children:["By default, Rookify runs in preflight mode (",(0,t.jsx)(i.code,{children:"--dry-run"}),")."]})}),"\n",(0,t.jsxs)(i.p,{children:["Rookify runs in preflight mode by default, meaning it performs all preflight checks on the modules and their dependent modules, as configured in ",(0,t.jsx)(i.code,{children:"config.yaml"}),", without executing the migration."]}),"\n",(0,t.jsx)(i.h3,{id:"--dry-run",children:"--dry-run"}),"\n",(0,t.jsx)(i.admonition,{type:"tip",children:(0,t.jsx)(i.p,{children:"Run preflight-mode to ensure Rookify can connect to your target systems."})}),"\n",(0,t.jsxs)(i.p,{children:["Rookify's ",(0,t.jsx)(i.code,{children:"preflight-mode"})," allows you to verify that basic commands and connections to the target systems are functioning correctly. Running ",(0,t.jsx)(i.code,{children:"--dry-run"})," or ",(0,t.jsx)(i.code,{children:"-d"})," mode ensures no migration processes are executed."]}),"\n",(0,t.jsx)(i.h3,{id:"--migrate",children:"--migrate"}),"\n",(0,t.jsx)(i.admonition,{type:"tip",children:(0,t.jsxs)(i.p,{children:["Ensure that you use the correct ",(0,t.jsx)(i.code,{children:"data.pickle"})," file. If you used the pickle file for other setups previously, be sure to delete it."]})}),"\n",(0,t.jsxs)(i.p,{children:["Rookify's ",(0,t.jsx)(i.code,{children:"execution-mode"})," allows you to run the migration. This is a point of no (easy) return. Be sure to check all your configurations. Run ",(0,t.jsx)(i.code,{children:"--migrate"})," or ",(0,t.jsx)(i.code,{children:"-m"})," to execute the migration process."]}),"\n",(0,t.jsx)(i.h3,{id:"--help",children:"--help"}),"\n",(0,t.jsxs)(i.p,{children:["Run ",(0,t.jsx)(i.code,{children:"rookify --help"})," to view the various CLI options available."]}),"\n",(0,t.jsx)(i.h3,{id:"--show-states",children:"--show-states"}),"\n",(0,t.jsxs)(i.p,{children:["Run ",(0,t.jsx)(i.code,{children:"--show-states"})," or ",(0,t.jsx)(i.code,{children:"-s"})," to display the status of your migration process. Note that if you specified a pickle file, Rookify will use it to determine the state of migration."]}),"\n",(0,t.jsx)(i.h2,{id:"debugging-and-testing",children:"Debugging and Testing"}),"\n",(0,t.jsxs)(i.p,{children:["If you encounter issues with Rookify, you can start by setting the logging level to ",(0,t.jsx)(i.code,{children:"DEBUG"}),".\nIf further troubleshooting is needed, you can run the tests included in the Rookify code."]}),"\n",(0,t.jsx)(i.h3,{id:"set-logging-to-debug-level",children:"Set logging to debug level"}),"\n",(0,t.jsxs)(i.p,{children:["Edit the ",(0,t.jsx)(i.code,{children:"config.yaml"}),' and set the logging level to "DEBUG":']}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{className:"language-yaml",metastring:'title="config.example.yaml"',children:'logging:\n level: DEBUG\n format:\n time: "%Y-%m-%d %H:%M.%S" # other example: "iso"\n renderer: console # or: json\n'})}),"\n",(0,t.jsxs)(i.p,{children:["You can also customize other formatting options, as shown in the comments. For more details, refer to the ",(0,t.jsx)(i.a,{href:"https://www.structlog.org/en/stable/standard-library.html",children:"structlog"}),"."]}),"\n",(0,t.jsx)(i.h3,{id:"run-tests",children:"Run tests"}),"\n",(0,t.jsx)(i.p,{children:"To run tests on Rookify, ensure you have access to the Rookify code on your system. Then:"}),"\n",(0,t.jsxs)(i.ol,{children:["\n",(0,t.jsxs)(i.li,{children:["Run ",(0,t.jsx)(i.code,{children:"make run-tests-locally"})," from the working directory of the Rookify repository. If you prefer a containerized setup, use ",(0,t.jsx)(i.code,{children:"make run-tests"}),"."]}),"\n",(0,t.jsxs)(i.li,{children:["Alternatively, run ",(0,t.jsx)(i.code,{children:".venv/bin/python -m pytest"})," from the virtual environment of your installation."]}),"\n"]})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,i,o)=>{o.d(i,{R:()=>r,x:()=>l});var n=o(96540);const t={},s=n.createContext(t);function r(e){const i=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function l(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),n.createElement(s.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3ad2c61e.ff4e783f.js b/assets/js/3ad2c61e.ff4e783f.js new file mode 100644 index 0000000000..bcf8fa5f3f --- /dev/null +++ b/assets/js/3ad2c61e.ff4e783f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[38384],{45449:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>p,frontMatter:()=>a,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"iaas/guides/concept-guide/components/ceph","title":"Ceph","description":"Ceph is an Open Source software defined storage platform designed to provide highly scalable","source":"@site/docs/02-iaas/guides/concept-guide/components/ceph.md","sourceDirName":"02-iaas/guides/concept-guide/components","slug":"/iaas/guides/concept-guide/components/ceph","permalink":"/docs/iaas/guides/concept-guide/components/ceph","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/ceph.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Components","permalink":"/docs/iaas/guides/concept-guide/components/"},"next":{"title":"Cluster API","permalink":"/docs/iaas/guides/concept-guide/components/clusterapi"}}');var s=i(74848),o=i(28453);const a={},c="Ceph",r={},l=[{value:"Lifecycle Management of Ceph in OSISM",id:"lifecycle-management-of-ceph-in-osism",level:2}];function d(e){const n={h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"ceph",children:"Ceph"})}),"\n",(0,s.jsx)(n.p,{children:"Ceph is an Open Source software defined storage platform designed to provide highly scalable\nobject, block and file-based storage in a unified system. Designed for flexibility,\nCeph integrates seamlessly with cloud infrastructures like OpenStack and supports\ndiverse workloads with robust, self-healing and self-managing capabilities."}),"\n",(0,s.jsx)(n.p,{children:"Key benefits of Ceph include:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Scalability: Ceph is designed to scale from terabytes to exabytes, easily meeting\nthe needs of small businesses to large enterprises."}),"\n",(0,s.jsx)(n.li,{children:"Resilience: With built-in redundancy and data replication, Ceph ensures data\nintegrity and availability even in the face of hardware failures."}),"\n",(0,s.jsx)(n.li,{children:"High performance: Using a distributed architecture, Ceph delivers high throughput\nand low latency, making it ideal for high-demand workloads."}),"\n",(0,s.jsx)(n.li,{children:"Cost-effective: As open source, Ceph eliminates licensing costs and its ability to\nrun on commodity hardware reduces CapEx."}),"\n",(0,s.jsx)(n.li,{children:"Versatility: Ceph supports a variety of storage types - object, block and file -\non a single platform, simplifying storage management and reducing operational complexity."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"lifecycle-management-of-ceph-in-osism",children:"Lifecycle Management of Ceph in OSISM"})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>c});var t=i(96540);const s={},o=t.createContext(s);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3d19221e.8a0b07e0.js b/assets/js/3d19221e.8a0b07e0.js new file mode 100644 index 0000000000..80227acbee --- /dev/null +++ b/assets/js/3d19221e.8a0b07e0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3714],{984:(s,e,o)=>{o.r(e),o.d(e,{assets:()=>d,contentTitle:()=>r,default:()=>l,frontMatter:()=>c,metadata:()=>n,toc:()=>a});const n=JSON.parse('{"id":"iaas/guides/configuration-guide/commons/index","title":"Commons","description":"This section contains the documentation of the Ansible collection osism.commons.","source":"@site/docs/02-iaas/guides/configuration-guide/commons/index.md","sourceDirName":"02-iaas/guides/configuration-guide/commons","slug":"/iaas/guides/configuration-guide/commons/","permalink":"/docs/iaas/guides/configuration-guide/commons/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/index.md","tags":[],"version":"current","sidebarPosition":50,"frontMatter":{"sidebar_label":"Commons","sidebar_position":50},"sidebar":"docs","previous":{"title":"Rookify (technical preview)","permalink":"/docs/iaas/guides/configuration-guide/rookify"},"next":{"title":"Certificates","permalink":"/docs/iaas/guides/configuration-guide/commons/certificates"}}');var t=o(74848),i=o(28453);const c={sidebar_label:"Commons",sidebar_position:50},r="Commons",d={},a=[];function m(s){const e={a:"a",h1:"h1",header:"header",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...s.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"commons",children:"Commons"})}),"\n",(0,t.jsxs)(e.p,{children:["This section contains the documentation of the Ansible collection ",(0,t.jsx)(e.a,{href:"https://github.com/osism/ansible-collection-commons",children:"osism.commons"}),"."]}),"\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:(0,t.jsx)(e.strong,{children:"Role"})}),(0,t.jsx)(e.th,{children:(0,t.jsx)(e.strong,{children:"Description"})})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"osism.commons.network"}),(0,t.jsx)(e.td,{})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"osism.commons.packages"}),(0,t.jsx)(e.td,{})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"osism.commons.services"}),(0,t.jsx)(e.td,{})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"osism.commons.sshconfig"}),(0,t.jsx)(e.td,{})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"osism.commons.timezone"}),(0,t.jsx)(e.td,{})]})]})]})]})}function l(s={}){const{wrapper:e}={...(0,i.R)(),...s.components};return e?(0,t.jsx)(e,{...s,children:(0,t.jsx)(m,{...s})}):m(s)}},28453:(s,e,o)=>{o.d(e,{R:()=>c,x:()=>r});var n=o(96540);const t={},i=n.createContext(t);function c(s){const e=n.useContext(i);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function r(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(t):s.components||t:c(s.components),n.createElement(i.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/3d9e0922.22db4721.js b/assets/js/3d9e0922.22db4721.js new file mode 100644 index 0000000000..beaac8a127 --- /dev/null +++ b/assets/js/3d9e0922.22db4721.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[62069],{86460:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>d,default:()=>l,frontMatter:()=>c,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"ops/scs-0410","title":"scs-0410: Gnocchi as database for metering","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/ops/scs-0410.md","sourceDirName":"ops","slug":"/ops/scs-0410","permalink":"/standards/ops/scs-0410","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0403-v1-csp-kaas-observability-stack"},"next":{"title":"V1","permalink":"/standards/scs-0410-v1-gnocchi-as-metering-database"}}');var r=t(74848),a=t(28453);const c={},d="scs-0410: Gnocchi as database for metering",i={},o=[];function h(e){const s={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"scs-0410-gnocchi-as-database-for-metering",children:"scs-0410: Gnocchi as database for metering"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0410-v1-gnocchi-as-metering-database",children:"scs-0410-v1"})}),(0,r.jsx)(s.td,{children:"Decision Record"}),(0,r.jsx)(s.td,{children:"Draft"}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]})})]})]})}function l(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>c,x:()=>d});var n=t(96540);const r={},a=n.createContext(r);function c(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3e493f26.c3d21fd8.js b/assets/js/3e493f26.c3d21fd8.js new file mode 100644 index 0000000000..9bd42491a4 --- /dev/null +++ b/assets/js/3e493f26.c3d21fd8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[96029],{33171:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>l,frontMatter:()=>c,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"iaas/overview/network","title":"Network","description":"TODO","source":"@site/docs/02-iaas/overview/network.md","sourceDirName":"02-iaas/overview","slug":"/iaas/overview/network","permalink":"/docs/iaas/overview/network","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/overview/network.md","tags":[],"version":"current","frontMatter":{}}');var r=n(74848),s=n(28453);const c={},i="Network",a={},d=[];function u(e){const t={h1:"h1",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"network",children:"Network"})}),"\n",(0,r.jsx)(t.p,{children:"TODO"})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var o=n(96540);const r={},s=o.createContext(r);function c(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3f3928dc.56e36d76.js b/assets/js/3f3928dc.56e36d76.js new file mode 100644 index 0000000000..292eb8d6bd --- /dev/null +++ b/assets/js/3f3928dc.56e36d76.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[43213],{43868:(s,e,d)=>{d.r(e),d.d(e,{TableCellStyleApplier:()=>h,assets:()=>l,contentTitle:()=>c,default:()=>o,frontMatter:()=>i,metadata:()=>r,toc:()=>x});const r=JSON.parse('{"id":"iaas/index","title":"IaaS Standards","description":"The IaaS Layer Standards track focuses on the protocols, guidelines, and specifications that govern the infrastructure as a service layer. This encompasses standards for virtual machines, storage, networking, and other foundational resources, ensuring seamless, efficient, and secure operation, interoperability, and management of the underlying cloud infrastructure.","source":"@site/standards/iaas/index.md","sourceDirName":"iaas","slug":"/iaas/","permalink":"/standards/iaas/","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0005-v1-project-governance"},"next":{"title":"scs-0100: SCS Flavor Naming Standard","permalink":"/standards/iaas/scs-0100"}}');var n=d(74848),t=d(28453),a=d(96540);const i={},c="IaaS Standards",l={},h=()=>{const s={3:"#FBFDE2",4:"#E2EAFD",5:"#FDE2E2"},e={2:"#FBFDE2",3:"#E2EAFD",4:"#FDE2E2"};return(0,a.useEffect)((()=>{const d=(s,e)=>{const d=document.querySelector("#"+s);if(d){const s=d.nextElementSibling;s&&"table"===s.tagName.toLowerCase()&&s.querySelectorAll("tbody tr").forEach((s=>{s.querySelectorAll("td").forEach(((s,d)=>{e[d]&&"-"!==s.textContent.trim()&&(s.style.backgroundColor=e[d])}))}))}};d("color-table-cells-overview",s),d("color-table-cells-track-overview",e)}),[]),null},x=[];function j(s){const e={a:"a",em:"em",h1:"h1",header:"header",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"iaas-standards",children:"IaaS Standards"})}),"\n",(0,n.jsx)(e.p,{children:"The IaaS Layer Standards track focuses on the protocols, guidelines, and specifications that govern the infrastructure as a service layer. This encompasses standards for virtual machines, storage, networking, and other foundational resources, ensuring seamless, efficient, and secure operation, interoperability, and management of the underlying cloud infrastructure."}),"\n",(0,n.jsx)("p",{children:"*Legend to the column headings and entries:"}),"\n",(0,n.jsxs)(e.ul,{children:["\n",(0,n.jsx)(e.li,{children:"Document states: Draft, Effective, Deprecated (and no longer effective)"}),"\n",(0,n.jsx)(e.li,{children:"Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future"}),"\n",(0,n.jsx)(e.li,{children:"Entries in the effective column marked with a \u2020 will turn deprecated in the near future"}),"\n"]}),"\n","\n","\n",(0,n.jsx)(h,{}),"\n",(0,n.jsx)("div",{id:"color-table-cells-track-overview"}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:"Standard"}),(0,n.jsx)(e.th,{children:"Description"}),(0,n.jsx)(e.th,{children:"Draft"}),(0,n.jsx)(e.th,{children:"Effective"}),(0,n.jsx)(e.th,{children:"Deprecated*"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0100",children:"scs-0100"})}),(0,n.jsx)(e.td,{children:"SCS Flavor Naming Standard"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"v3"})}),(0,n.jsxs)(e.td,{children:[(0,n.jsx)(e.a,{href:"/standards/scs-0100-v1-flavor-naming",children:"v1"}),", ",(0,n.jsx)(e.a,{href:"/standards/scs-0100-v2-flavor-naming",children:"v2"})]})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0100-w1-flavor-naming-implementation-testing",children:"w1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0101",children:"scs-0101"})}),(0,n.jsx)(e.td,{children:"SCS Entropy"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0101-v1-entropy",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0101-w1-entropy-implementation-testing",children:"w1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0102",children:"scs-0102"})}),(0,n.jsx)(e.td,{children:"SCS Image Metadata"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0102-v1-image-metadata",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0102-w1-image-metadata-implementation-testing",children:"w1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0103",children:"scs-0103"})}),(0,n.jsx)(e.td,{children:"SCS Standard Flavors and Properties"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0103-v1-standard-flavors",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0104",children:"scs-0104"})}),(0,n.jsx)(e.td,{children:"SCS Standard Images"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0104-v1-standard-images",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:"Supplement: Implementation Notes"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0104-w1-standard-images-implementation",children:"w1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0110",children:"scs-0110"})}),(0,n.jsx)(e.td,{children:"SSD Flavors"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0110-v1-ssd-flavors",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0111",children:"scs-0111"})}),(0,n.jsx)(e.td,{children:"Decisions for the Volume Type Standard"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0111-v1-volume-type-decisions",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0112",children:"scs-0112"})}),(0,n.jsx)(e.td,{children:"SONiC Support in SCS"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0112-v1-sonic",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0113",children:"scs-0113"})}),(0,n.jsx)(e.td,{children:"Security Groups Decision Record"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0113-v1-security-groups-decision-record",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0114",children:"scs-0114"})}),(0,n.jsx)(e.td,{children:"SCS Volume Types"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0114-v1-volume-type-standard",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0115",children:"scs-0115"})}),(0,n.jsx)(e.td,{children:"Default Rules for Security Groups"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0115-v1-default-rules-for-security-groups",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0116",children:"scs-0116"})}),(0,n.jsx)(e.td,{children:"SCS Key Manager Standard"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0116-v1-key-manager-standard",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0116-w1-key-manager-implementation-testing",children:"w1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0117",children:"scs-0117"})}),(0,n.jsx)(e.td,{children:"Volume Backup Functionality"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0117-v1-volume-backup-service",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0118",children:"scs-0118"})}),(0,n.jsx)(e.td,{children:"SCS Taxonomy of Failsafe Levels"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0118-v1-taxonomy-of-failsafe-levels",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:"Supplement: Examples of Failure Cases and their impact on IaaS and KaaS resources"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0118-w1-example-impacts-of-failure-scenarios",children:"w1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0119",children:"scs-0119"})}),(0,n.jsx)(e.td,{children:"Replacement of the deprecated ceph-ansible tool"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0119-v1-rook-decision",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0120",children:"scs-0120"})}),(0,n.jsx)(e.td,{children:"Cluster-API images"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0120-v1-capi-images",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0121",children:"scs-0121"})}),(0,n.jsx)(e.td,{children:"SCS Availability Zones"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0121-v1-Availability-Zones-Standard",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0121-w1-Availability-Zones-Standard",children:"w1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0122",children:"scs-0122"})}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.em,{children:"End-to-End Encryption between Customer Workloads"})}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0122-v1-node-to-node-encryption",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0123",children:"scs-0123"})}),(0,n.jsx)(e.td,{children:"Mandatory and Supported IaaS Services"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0124",children:"scs-0124"})}),(0,n.jsx)(e.td,{children:"Standard for the security of IaaS service software"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0124-v1-security-of-iaas-service-software",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{}),(0,n.jsx)(e.td,{children:"Supplement: SCS Standard for the security of IaaS service software: Implementation and Testing Notes"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0124-w1-security-of-iaas-service-software",children:"w1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/iaas/scs-0125",children:"scs-0125"})}),(0,n.jsx)(e.td,{children:"Secure Connections"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0125-v1-secure-connections",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]})]})]})]})}function o(s={}){const{wrapper:e}={...(0,t.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(j,{...s})}):j(s)}},28453:(s,e,d)=>{d.d(e,{R:()=>a,x:()=>i});var r=d(96540);const n={},t=r.createContext(n);function a(s){const e=r.useContext(t);return r.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function i(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:a(s.components),r.createElement(t.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/3ff13a62.4623da87.js b/assets/js/3ff13a62.4623da87.js new file mode 100644 index 0000000000..74c347a096 --- /dev/null +++ b/assets/js/3ff13a62.4623da87.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[55743],{40044:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"container/index","title":"Container Layer Introduction","description":"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:","source":"@site/docs/03-container/index.md","sourceDirName":"03-container","slug":"/container/","permalink":"/docs/container/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/index.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"artcodix","permalink":"/docs/iaas/deployment-examples/artcodix/"},"next":{"title":"Components","permalink":"/docs/category/components-1"}}');var a=t(74848),i=t(28453);const o={},s="Container Layer Introduction",l={},c=[{value:"Target groups",id:"target-groups",level:2},{value:"What is it not",id:"what-is-it-not",level:2},{value:"Prerequisites and Requirements",id:"prerequisites-and-requirements",level:3},{value:"Features",id:"features",level:3},{value:"Limitations",id:"limitations",level:3}];function d(e){const n={h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"container-layer-introduction",children:"Container Layer Introduction"})}),"\n",(0,a.jsx)(n.p,{children:"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:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"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."}),"\n",(0,a.jsx)(n.li,{children:"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."}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"target-groups",children:"Target groups"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"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."}),"\n",(0,a.jsx)(n.li,{children:"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."}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"what-is-it-not",children:"What is it not"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"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."}),"\n",(0,a.jsx)(n.li,{children:"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."}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"prerequisites-and-requirements",children:"Prerequisites and Requirements"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Knowledge: Familiarity with Kubernetes, container orchestration, and basic cloud infrastructure principles is pivotal."}),"\n",(0,a.jsx)(n.li,{children:"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."}),"\n",(0,a.jsx)(n.li,{children:"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."}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"features",children:"Features"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Automated Cluster Management: The Cluster API automates the process of creating, scaling, managing and updating Kubernetes clusters, thus significantly reducing the operational overhead."}),"\n",(0,a.jsx)(n.li,{children:"Standardized Operations: Upholding SCS standards across various clusters ensures operational consistency and reliability."}),"\n",(0,a.jsx)(n.li,{children:"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."}),"\n",(0,a.jsx)(n.li,{children:"Container Registry Integration: The container layer has an optional container registry, facilitating easy management and deployment of container images."}),"\n",(0,a.jsx)(n.li,{children:"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."}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"limitations",children:"Limitations"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"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."}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>s});var r=t(96540);const a={},i=r.createContext(a);function o(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/406caaae.533c43b8.js b/assets/js/406caaae.533c43b8.js new file mode 100644 index 0000000000..15f6aa081b --- /dev/null +++ b/assets/js/406caaae.533c43b8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[26918],{36715:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>p});const s=JSON.parse('{"id":"operating-scs/components/status-page-web/docs/overview","title":"Overview","description":"This repository supplies a SPA (Single Page Application), written in Angular, that uses the status-page-openapi client to connect to the API server to show components, incidents and their impacts on the system. The SPA also offers a management page, allowing authorized users to create, update and delete incidents (including future incidents, the so-called maintenance events).","source":"@site/docs/04-operating-scs/components/status-page-web/docs/overview.md","sourceDirName":"04-operating-scs/components/status-page-web/docs","slug":"/operating-scs/components/status-page-web/docs/overview","permalink":"/docs/operating-scs/components/status-page-web/docs/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-web/docs/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Web","permalink":"/docs/category/web"},"next":{"title":"Requirements","permalink":"/docs/operating-scs/components/status-page-web/docs/requirements"}}');var o=n(74848),a=n(28453);const i={},r="Overview",c={},p=[];function d(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,o.jsxs)(t.p,{children:["This repository supplies a SPA (Single Page Application), written in ",(0,o.jsx)(t.a,{href:"https://angular.dev/",children:"Angular"}),", that uses the ",(0,o.jsxs)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi/tree/main/lib/status-page-api/angular-client",children:[(0,o.jsx)(t.code,{children:"status-page-openapi"})," client"]})," to connect to the ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-api",children:"API server"})," to show components, incidents and their impacts on the system. The SPA also offers a management page, allowing authorized users to create, update and delete incidents (including future incidents, the so-called maintenance events)."]}),"\n",(0,o.jsxs)(t.p,{children:["The SPA is released as a container running ",(0,o.jsx)(t.a,{href:"https://nginx.org/",children:"nginx"})," to serve the static build of the application. No other server components are needed to serve the application."]})]})}function u(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var s=n(96540);const o={},a=s.createContext(o);function i(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/40d9468c.18cd8ac5.js b/assets/js/40d9468c.18cd8ac5.js new file mode 100644 index 0000000000..65c125bb3a --- /dev/null +++ b/assets/js/40d9468c.18cd8ac5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[90783],{85281:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>a});const i=JSON.parse('{"id":"iaas/guides/other-guides/developer-guide/index","title":"Developer Guide","description":"How to add a new service","source":"@site/docs/02-iaas/guides/other-guides/developer-guide/index.md","sourceDirName":"02-iaas/guides/other-guides/developer-guide","slug":"/iaas/guides/other-guides/developer-guide/","permalink":"/docs/iaas/guides/other-guides/developer-guide/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/developer-guide/index.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Developer Guide"},"sidebar":"docs","previous":{"title":"Contributor Guide","permalink":"/docs/iaas/guides/other-guides/contributor-guide"},"next":{"title":"Releases","permalink":"/docs/iaas/guides/other-guides/developer-guide/releases"}}');var l=t(74848),n=t(28453);const r={sidebar_label:"Developer Guide"},o="Developer Guide",d={},a=[{value:"How to add a new service",id:"how-to-add-a-new-service",level:2},{value:"How to add a new container image",id:"how-to-add-a-new-container-image",level:2},{value:"How service deployment works",id:"how-service-deployment-works",level:2},{value:"Docker",id:"docker",level:3},{value:"Kubernetes",id:"kubernetes",level:3}];function c(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.header,{children:(0,l.jsx)(s.h1,{id:"developer-guide",children:"Developer Guide"})}),"\n",(0,l.jsx)(s.h2,{id:"how-to-add-a-new-service",children:"How to add a new service"}),"\n",(0,l.jsxs)(s.p,{children:["If you want to add a new service to OSISM, this is done via an Ansible role and (most often)\na container image. The following steps are necessary and are demonstrated using the example\nof ",(0,l.jsx)(s.code,{children:"osism.services.cgit"}),"."]}),"\n",(0,l.jsxs)(s.table,{children:[(0,l.jsx)(s.thead,{children:(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.th,{style:{textAlign:"left"},children:"Description"}),(0,l.jsx)(s.th,{style:{textAlign:"left"},children:"Example"})]})}),(0,l.jsxs)(s.tbody,{children:[(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{style:{textAlign:"left"},children:"Add the Ansible role in one of the Ansible collection repositories"}),(0,l.jsx)(s.td,{style:{textAlign:"left"},children:(0,l.jsx)(s.a,{href:"https://github.com/osism/ansible-collection-services/pull/578/files",children:"https://github.com/osism/ansible-collection-services/pull/578/files"})})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{style:{textAlign:"left"},children:"Add the Ansible playbook"}),(0,l.jsx)(s.td,{style:{textAlign:"left"},children:(0,l.jsx)(s.a,{href:"https://github.com/osism/ansible-playbooks/pull/215/files",children:"https://github.com/osism/ansible-playbooks/pull/215/files"})})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{style:{textAlign:"left"},children:"Add the Ansible inventory group"}),(0,l.jsx)(s.td,{style:{textAlign:"left"},children:(0,l.jsx)(s.a,{href:"https://github.com/osism/cfg-generics/pull/225/files",children:"https://github.com/osism/cfg-generics/pull/225/files"})})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{style:{textAlign:"left"},children:"Add the used container image(s) to the release repository"}),(0,l.jsx)(s.td,{style:{textAlign:"left"},children:(0,l.jsx)(s.a,{href:"https://github.com/osism/release/pull/278/files",children:"https://github.com/osism/release/pull/278/files"})})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{style:{textAlign:"left"},children:"Add the container images(s) to osism-ansible container image"}),(0,l.jsx)(s.td,{style:{textAlign:"left"},children:(0,l.jsx)(s.a,{href:"https://github.com/osism/container-image-osism-ansible/pull/215/files",children:"https://github.com/osism/container-image-osism-ansible/pull/215/files"})})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{style:{textAlign:"left"},children:"Add the container image registry/registries and host(s) to the defaults repository"}),(0,l.jsx)(s.td,{style:{textAlign:"left"},children:(0,l.jsx)(s.a,{href:"https://github.com/osism/defaults/pull/54/files",children:"https://github.com/osism/defaults/pull/54/files"})})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{style:{textAlign:"left"},children:"Add a sample deployment to the testbed"}),(0,l.jsx)(s.td,{style:{textAlign:"left"},children:(0,l.jsx)(s.a,{href:"https://github.com/osism/testbed/pull/1043/files",children:"https://github.com/osism/testbed/pull/1043/files"})})]})]})]}),"\n",(0,l.jsx)(s.h2,{id:"how-to-add-a-new-container-image",children:"How to add a new container image"}),"\n",(0,l.jsxs)(s.p,{children:["If required, add a new container image in the ",(0,l.jsx)(s.a,{href:"https://github.com/osism/container-images",children:"osism/container-images"}),"\nrepository. The example here is from the ",(0,l.jsx)(s.code,{children:"osism.services.keycloak"})," role: ",(0,l.jsx)(s.a,{href:"https://github.com/osism/container-images/pull/34/files",children:"https://github.com/osism/container-images/pull/34/files"}),"."]}),"\n",(0,l.jsx)(s.p,{children:"Whenever possible, upstream container images should be used. If only minor customizations are necessary,\nalways work with overlay container images based on upstream container images."}),"\n",(0,l.jsx)(s.h2,{id:"how-service-deployment-works",children:"How service deployment works"}),"\n",(0,l.jsx)(s.h3,{id:"docker",children:"Docker"}),"\n",(0,l.jsx)(s.p,{children:(0,l.jsx)(s.img,{alt:"Service deployment with Docker",src:t(44601).A+"",width:"281",height:"892"})}),"\n",(0,l.jsx)(s.h3,{id:"kubernetes",children:"Kubernetes"}),"\n",(0,l.jsx)(s.p,{children:(0,l.jsx)(s.img,{alt:"Service deployment with Kubernetes",src:t(31469).A+"",width:"281",height:"902"})})]})}function h(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,l.jsx)(s,{...e,children:(0,l.jsx)(c,{...e})}):c(e)}},44601:(e,s,t)=>{t.d(s,{A:()=>i});const i=t.p+"assets/images/service-with-docker.drawio-21d9ff770c727c43ab477f857b5017e2.png"},31469:(e,s,t)=>{t.d(s,{A:()=>i});const i=t.p+"assets/images/service-with-kubernetes.drawio-9500d1fb61ca22792d8277f9f06e58ce.png"},28453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>o});var i=t(96540);const l={},n=i.createContext(l);function r(e){const s=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:r(e.components),i.createElement(n.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/41ab9761.c95ba8c0.js b/assets/js/41ab9761.c95ba8c0.js new file mode 100644 index 0000000000..63eb65b7f5 --- /dev/null +++ b/assets/js/41ab9761.c95ba8c0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[45676],{80572:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>_,frontMatter:()=>s,metadata:()=>a,toc:()=>r});const a=JSON.parse('{"id":"operating-scs/metering/meter_configuration","title":"Metering Configuration","description":"The Metrics and events we want to use in the metering process can be defined in two ways. The first one is to allow ceilometer to poll distinct metrics and events.","source":"@site/docs/04-operating-scs/07-metering/meter_configuration.md","sourceDirName":"04-operating-scs/07-metering","slug":"/operating-scs/metering/meter_configuration","permalink":"/docs/operating-scs/metering/meter_configuration","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/07-metering/meter_configuration.md","tags":[],"version":"current","frontMatter":{"title":"Metering Configuration","type":null,"status":"Draft","track":"Global"},"sidebar":"docs","previous":{"title":"Metering","permalink":"/docs/category/metering"},"next":{"title":"Introduction on Identity Management and Federation in SCS","permalink":"/docs/iam/"}}');var i=t(74848),d=t(28453);const s={title:"Metering Configuration",type:null,status:"Draft",track:"Global"},l=void 0,o={},r=[{value:"1. ceilometer metering configuration",id:"1-ceilometer-metering-configuration",level:2},{value:"1.1 polling.yaml",id:"11-pollingyaml",level:3},{value:"1.2 event_definitions.yaml",id:"12-event_definitionsyaml",level:3},{value:"1.3 event_pipeline.yaml",id:"13-event_pipelineyaml",level:3},{value:"1.4 pipeline.yaml",id:"14-pipelineyaml",level:3}];function p(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,d.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"The Metrics and events we want to use in the metering process can be defined in two ways. The first one is to allow ceilometer to poll distinct metrics and events.\nThis can be achived by setting up ceilometers config files."}),"\n",(0,i.jsx)(n.h2,{id:"1-ceilometer-metering-configuration",children:"1. ceilometer metering configuration"}),"\n",(0,i.jsx)(n.p,{children:"there is the polling.yaml file that describes what metrics to poll and when. It allows to create multiple sources for the ceilometer pipeline with different metrics and intervals."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://docs.openstack.org/ceilometer/latest/admin/telemetry-data-collection.html#polling",children:"ceilometer polling"}),"\n",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/ceilometer/latest/admin/telemetry-measurements.html#telemetry-bare-metal-service",children:"ceilometer polling metrics"})]}),"\n",(0,i.jsx)(n.h3,{id:"11-pollingyaml",children:"1.1 polling.yaml"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"---\nsources:\n - name: billing_source # 'source name'\n interval: 300 # 'how often the samples should be generated'\n meters:\n - \"volume.size\" # 'meter filter'\n # - \"*\" # 'using all pollsters\n"})}),"\n",(0,i.jsx)(n.p,{children:"in the event_definitions file all data structure of events are defined. If a message with a distinct event_type appears, the Fields and values from the message are matched with the Event-object."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://docs.openstack.org/ceilometer/latest/admin/telemetry-events.html",children:"ceilometer events"}),"\n",(0,i.jsx)(n.a,{href:"https://github.com/openstack/ceilometer/blob/master/ceilometer/pipeline/data/event_definitions.yaml",children:"ceilometer event_definitions"})]}),"\n",(0,i.jsx)(n.h3,{id:"12-event_definitionsyaml",children:"1.2 event_definitions.yaml"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'---\n- event_type: "compute.instance.*"\n traits: &instance_traits\n tenant_id:\n fields: payload.tenant_id\n user_id:\n fields: payload.user_id\n instance_id:\n fields: payload.instance_id\n display_name:\n fields: payload.display_name\n resource_id:\n fields: payload.instance_id\n cell_name:\n fields: payload.cell_name\n host:\n fields: publisher_id.`split(., 1, 1)`\n service:\n fields: publisher_id.`split(., 0, -1)`\n memory_mb:\n type: int\n fields: payload.memory_mb\n disk_gb:\n type: int\n fields: payload.disk_gb\n root_gb:\n type: int\n fields: payload.root_gb\n ephemeral_gb:\n type: int\n fields: payload.ephemeral_gb\n vcpus:\n type: int\n fields: payload.vcpus\n instance_type_id:\n fields: payload.instance_type_id\n instance_type:\n fields: payload.instance_type\n state:\n fields: payload.state\n os_architecture:\n fields: payload.image_meta.\'org.openstack__1__architecture\'\n os_version:\n fields: payload.image_meta.\'org.openstack__1__os_version\'\n os_distro:\n fields: payload.image_meta.\'org.openstack__1__os_distro\'\n launched_at:\n type: datetime\n fields: payload.launched_at\n deleted_at:\n type: datetime\n fields: payload.deleted_at\n- event_type: compute.instance.create.end\n traits:\n <<: *instance_traits\n availability_zone:\n fields: payload.availability_zone\n- event_type: compute.instance.update\n traits:\n <<: *instance_traits\n old_state:\n fields: payload.old_state\n- event_type: compute.instance.exists\n traits:\n <<: *instance_traits\n audit_period_beginning:\n type: datetime\n fields: payload.audit_period_beginning\n audit_period_ending:\n type: datetime\n fields: payload.audit_period_ending\n- event_type:\n [\n "volume.exists",\n "volume.retype",\n "volume.create.*",\n "volume.delete.*",\n "volume.resize.*",\n "volume.attach.*",\n "volume.detach.*",\n "volume.update.*",\n "snapshot.exists",\n "snapshot.create.*",\n "snapshot.delete.*",\n "snapshot.update.*",\n "volume.transfer.accept.end",\n "snapshot.transfer.accept.end",\n ]\n traits: &cinder_traits\n user_id:\n fields: payload.user_id\n project_id:\n fields: payload.tenant_id\n availability_zone:\n fields: payload.availability_zone\n display_name:\n fields: payload.display_name\n replication_status:\n fields: payload.replication_status\n status:\n fields: payload.status\n created_at:\n type: datetime\n fields: payload.created_at\n image_id:\n fields: payload.glance_metadata[?key=image_id].value\n instance_id:\n fields: payload.volume_attachment[0].server_id\n- event_type:\n [\n "volume.transfer.*",\n "volume.exists",\n "volume.retype",\n "volume.create.*",\n "volume.delete.*",\n "volume.resize.*",\n "volume.attach.*",\n "volume.detach.*",\n "volume.update.*",\n "snapshot.transfer.accept.end",\n ]\n traits:\n <<: *cinder_traits\n resource_id:\n fields: payload.volume_id\n host:\n fields: payload.host\n size:\n type: int\n fields: payload.size\n type:\n fields: payload.volume_type\n replication_status:\n fields: payload.replication_status\n- event_type: ["snapshot.transfer.accept.end"]\n traits:\n <<: *cinder_traits\n resource_id:\n fields: payload.snapshot_id\n project_id:\n fields: payload.tenant_id\n- event_type:\n ["share.create.*", "share.delete.*", "share.extend.*", "share.shrink.*"]\n traits: &share_traits\n share_id:\n fields: payload.share_id\n user_id:\n fields: payload.user_id\n project_id:\n fields: payload.tenant_id\n snapshot_id:\n fields: payload.snapshot_id\n availability_zone:\n fields: payload.availability_zone\n status:\n fields: payload.status\n created_at:\n type: datetime\n fields: payload.created_at\n share_group_id:\n fields: payload.share_group_id\n size:\n type: int\n fields: payload.size\n name:\n fields: payload.name\n proto:\n fields: payload.proto\n is_public:\n fields: payload.is_public\n description:\n fields: payload.description\n host:\n fields: payload.host\n- event_type:\n [\n "snapshot.exists",\n "snapshot.create.*",\n "snapshot.delete.*",\n "snapshot.update.*",\n ]\n traits:\n <<: *cinder_traits\n resource_id:\n fields: payload.snapshot_id\n volume_id:\n fields: payload.volume_id\n- event_type: ["image_volume_cache.*"]\n traits:\n image_id:\n fields: payload.image_id\n host:\n fields: payload.host\n- event_type: ["image.create", "image.update", "image.upload", "image.delete"]\n traits: &glance_crud\n project_id:\n fields: payload.owner\n resource_id:\n fields: payload.id\n name:\n fields: payload.name\n status:\n fields: payload.status\n created_at:\n type: datetime\n fields: payload.created_at\n user_id:\n fields: payload.owner\n deleted_at:\n type: datetime\n fields: payload.deleted_at\n size:\n type: int\n fields: payload.size\n- event_type: image.send\n traits: &glance_send\n receiver_project:\n fields: payload.receiver_tenant_id\n receiver_user:\n fields: payload.receiver_user_id\n user_id:\n fields: payload.owner_id\n image_id:\n fields: payload.image_id\n destination_ip:\n fields: payload.destination_ip\n bytes_sent:\n type: int\n fields: payload.bytes_sent\n- event_type: orchestration.stack.*\n traits: &orchestration_crud\n project_id:\n fields: payload.tenant_id\n user_id:\n fields: ["ctxt.trustor_user_id", "ctxt.user_id"]\n resource_id:\n fields: payload.stack_identity\n name:\n fields: payload.name\n- event_type: sahara.cluster.*\n traits: &sahara_crud\n project_id:\n fields: payload.project_id\n user_id:\n fields: ctxt.user_id\n resource_id:\n fields: payload.cluster_id\n name:\n fields: payload.name\n- event_type: sahara.cluster.health\n traits: &sahara_health\n <<: *sahara_crud\n verification_id:\n fields: payload.verification_id\n health_check_status:\n fields: payload.health_check_status\n health_check_name:\n fields: payload.health_check_name\n health_check_description:\n fields: payload.health_check_description\n created_at:\n type: datetime\n fields: payload.created_at\n updated_at:\n type: datetime\n fields: payload.updated_at\n- event_type:\n [\n "identity.user.*",\n "identity.project.*",\n "identity.group.*",\n "identity.role.*",\n "identity.OS-TRUST:trust.*",\n "identity.region.*",\n "identity.service.*",\n "identity.endpoint.*",\n "identity.policy.*",\n ]\n traits: &identity_crud\n resource_id:\n fields: payload.resource_info\n initiator_id:\n fields: payload.initiator.id\n project_id:\n fields: payload.initiator.project_id\n domain_id:\n fields: payload.initiator.domain_id\n- event_type: identity.role_assignment.*\n traits: &identity_role_assignment\n role:\n fields: payload.role\n group:\n fields: payload.group\n domain:\n fields: payload.domain\n user:\n fields: payload.user\n project:\n fields: payload.project\n- event_type: identity.authenticate\n traits: &identity_authenticate\n typeURI:\n fields: payload.typeURI\n id:\n fields: payload.id\n action:\n fields: payload.action\n eventType:\n fields: payload.eventType\n eventTime:\n type: datetime\n fields: payload.eventTime\n outcome:\n fields: payload.outcome\n initiator_typeURI:\n fields: payload.initiator.typeURI\n initiator_id:\n fields: payload.initiator.id\n initiator_name:\n fields: payload.initiator.name\n initiator_host_agent:\n fields: payload.initiator.host.agent\n initiator_host_addr:\n fields: payload.initiator.host.address\n target_typeURI:\n fields: payload.target.typeURI\n target_id:\n fields: payload.target.id\n observer_typeURI:\n fields: payload.observer.typeURI\n observer_id:\n fields: payload.observer.id\n- event_type: objectstore.http.request\n traits: &objectstore_request\n typeURI:\n fields: payload.typeURI\n id:\n fields: payload.id\n action:\n fields: payload.action\n eventType:\n fields: payload.eventType\n eventTime:\n type: datetime\n fields: payload.eventTime\n outcome:\n fields: payload.outcome\n initiator_typeURI:\n fields: payload.initiator.typeURI\n initiator_id:\n fields: payload.initiator.id\n initiator_project_id:\n fields: payload.initiator.project_id\n target_typeURI:\n fields: payload.target.typeURI\n target_id:\n fields: payload.target.id\n target_action:\n fields: payload.target.action\n target_metadata_path:\n fields: payload.target.metadata.path\n target_metadata_version:\n fields: payload.target.metadata.version\n target_metadata_container:\n fields: payload.target.metadata.container\n target_metadata_object:\n fields: payload.target.metadata.object\n observer_id:\n fields: payload.observer.id\n- event_type:\n [\n "network.*",\n "subnet.*",\n "port.*",\n "router.*",\n "floatingip.*",\n "firewall.*",\n "firewall_policy.*",\n "firewall_rule.*",\n "vpnservice.*",\n "ipsecpolicy.*",\n "ikepolicy.*",\n "ipsec_site_connection.*",\n ]\n traits: &network_traits\n user_id:\n fields: ctxt.user_id\n project_id:\n fields: ctxt.tenant_id\n- event_type: network.*\n traits:\n <<: *network_traits\n name:\n fields: payload.network.name\n resource_id:\n fields: ["payload.network.id", "payload.id"]\n- event_type: subnet.*\n traits:\n <<: *network_traits\n name:\n fields: payload.subnet.name\n resource_id:\n fields: ["payload.subnet.id", "payload.id"]\n- event_type: port.*\n traits:\n <<: *network_traits\n name:\n fields: payload.port.name\n resource_id:\n fields: ["payload.port.id", "payload.id"]\n- event_type: router.*\n traits:\n <<: *network_traits\n name:\n fields: payload.router.name\n resource_id:\n fields: ["payload.router.id", "payload.id"]\n- event_type: floatingip.*\n traits:\n <<: *network_traits\n resource_id:\n fields: ["payload.floatingip.id", "payload.id"]\n- event_type: firewall.*\n traits:\n <<: *network_traits\n name:\n fields: payload.firewall.name\n resource_id:\n fields: ["payload.firewall.id", "payload.id"]\n- event_type: firewall_policy.*\n traits:\n <<: *network_traits\n name:\n fields: payload.firewall_policy.name\n resource_id:\n fields: ["payload.firewall_policy.id", "payload.id"]\n- event_type: firewall_rule.*\n traits:\n <<: *network_traits\n name:\n fields: payload.firewall_rule.name\n resource_id:\n fields: ["payload.firewall_rule.id", "payload.id"]\n- event_type: vpnservice.*\n traits:\n <<: *network_traits\n name:\n fields: payload.vpnservice.name\n resource_id:\n fields: ["payload.vpnservice.id", "payload.id"]\n- event_type: ipsecpolicy.*\n traits:\n <<: *network_traits\n name:\n fields: payload.ipsecpolicy.name\n resource_id:\n fields: ["payload.ipsecpolicy.id", "payload.id"]\n- event_type: ikepolicy.*\n traits:\n <<: *network_traits\n name:\n fields: payload.ikepolicy.name\n resource_id:\n fields: ["payload.ikepolicy.id", "payload.id"]\n- event_type: ipsec_site_connection.*\n traits:\n <<: *network_traits\n resource_id:\n fields: ["payload.ipsec_site_connection.id", "payload.id"]\n- event_type: "*http.*"\n traits: &http_audit\n project_id:\n fields: payload.initiator.project_id\n user_id:\n fields: payload.initiator.id\n typeURI:\n fields: payload.typeURI\n eventType:\n fields: payload.eventType\n action:\n fields: payload.action\n outcome:\n fields: payload.outcome\n id:\n fields: payload.id\n eventTime:\n type: datetime\n fields: payload.eventTime\n requestPath:\n fields: payload.requestPath\n observer_id:\n fields: payload.observer.id\n target_id:\n fields: payload.target.id\n target_typeURI:\n fields: payload.target.typeURI\n target_name:\n fields: payload.target.name\n initiator_typeURI:\n fields: payload.initiator.typeURI\n initiator_id:\n fields: payload.initiator.id\n initiator_name:\n fields: payload.initiator.name\n initiator_host_address:\n fields: payload.initiator.host.address\n- event_type: "*http.response"\n traits:\n <<: *http_audit\n reason_code:\n fields: payload.reason.reasonCode\n- event_type: ["dns.domain.create", "dns.domain.update", "dns.domain.delete"]\n traits: &dns_domain_traits\n status:\n fields: payload.status\n retry:\n fields: payload.retry\n description:\n fields: payload.description\n expire:\n fields: payload.expire\n email:\n fields: payload.email\n ttl:\n fields: payload.ttl\n action:\n fields: payload.action\n name:\n fields: payload.name\n resource_id:\n fields: payload.id\n created_at:\n type: datetime\n fields: payload.created_at\n updated_at:\n type: datetime\n fields: payload.updated_at\n version:\n fields: payload.version\n parent_domain_id:\n fields: parent_domain_id\n serial:\n fields: payload.serial\n- event_type: dns.domain.exists\n traits:\n <<: *dns_domain_traits\n audit_period_beginning:\n type: datetime\n fields: payload.audit_period_beginning\n audit_period_ending:\n type: datetime\n fields: payload.audit_period_ending\n- event_type: trove.*\n traits: &trove_base_traits\n instance_type:\n fields: payload.instance_type\n user_id:\n fields: payload.user_id\n resource_id:\n fields: payload.instance_id\n instance_type_id:\n fields: payload.instance_type_id\n launched_at:\n type: datetime\n fields: payload.launched_at\n instance_name:\n fields: payload.instance_name\n state:\n fields: payload.state\n nova_instance_id:\n fields: payload.nova_instance_id\n service_id:\n fields: payload.service_id\n created_at:\n type: datetime\n fields: payload.created_at\n region:\n fields: payload.region\n- event_type:\n [\n "trove.instance.create",\n "trove.instance.modify_volume",\n "trove.instance.modify_flavor",\n "trove.instance.delete",\n ]\n traits: &trove_common_traits\n name:\n fields: payload.name\n availability_zone:\n fields: payload.availability_zone\n instance_size:\n type: int\n fields: payload.instance_size\n volume_size:\n type: int\n fields: payload.volume_size\n nova_volume_id:\n fields: payload.nova_volume_id\n- event_type: trove.instance.create\n traits:\n <<: [*trove_base_traits, *trove_common_traits]\n- event_type: trove.instance.modify_volume\n traits:\n <<: [*trove_base_traits, *trove_common_traits]\n old_volume_size:\n type: int\n fields: payload.old_volume_size\n modify_at:\n type: datetime\n fields: payload.modify_at\n- event_type: trove.instance.modify_flavor\n traits:\n <<: [*trove_base_traits, *trove_common_traits]\n old_instance_size:\n type: int\n fields: payload.old_instance_size\n modify_at:\n type: datetime\n fields: payload.modify_at\n- event_type: trove.instance.delete\n traits:\n <<: [*trove_base_traits, *trove_common_traits]\n deleted_at:\n type: datetime\n fields: payload.deleted_at\n- event_type: trove.instance.exists\n traits:\n <<: *trove_base_traits\n display_name:\n fields: payload.display_name\n audit_period_beginning:\n type: datetime\n fields: payload.audit_period_beginning\n audit_period_ending:\n type: datetime\n fields: payload.audit_period_ending\n- event_type: profiler.*\n traits:\n project:\n fields: payload.project\n service:\n fields: payload.service\n name:\n fields: payload.name\n base_id:\n fields: payload.base_id\n trace_id:\n fields: payload.trace_id\n parent_id:\n fields: payload.parent_id\n timestamp:\n type: datetime\n fields: payload.timestamp\n host:\n fields: payload.info.host\n path:\n fields: payload.info.request.path\n query:\n fields: payload.info.request.query\n method:\n fields: payload.info.request.method\n scheme:\n fields: payload.info.request.scheme\n db.statement:\n fields: payload.info.db.statement\n db.params:\n fields: payload.info.db.params\n- event_type: "magnum.cluster.*"\n traits: &magnum_cluster_crud\n id:\n fields: payload.id\n typeURI:\n fields: payload.typeURI\n eventType:\n fields: payload.eventType\n eventTime:\n type: datetime\n fields: payload.eventTime\n action:\n fields: payload.action\n outcome:\n fields: payload.outcome\n initiator_id:\n fields: payload.initiator.id\n initiator_typeURI:\n fields: payload.initiator.typeURI\n initiator_name:\n fields: payload.initiator.name\n initiator_host_agent:\n fields: payload.initiator.host.agent\n initiator_host_address:\n fields: payload.initiator.host.address\n target_id:\n fields: payload.target.id\n target_typeURI:\n fields: payload.target.typeURI\n observer_id:\n fields: payload.observer.id\n observer_typeURI:\n fields: payload.observer.typeURI\n- event_type: "alarm.*"\n traits:\n id:\n fields: payload.alarm_id\n user_id:\n fields: payload.user_id\n project_id:\n fields: payload.project_id\n on_behalf_of:\n fields: payload.on_behalf_of\n severity:\n fields: payload.severity\n detail:\n fields: payload.detail\n type:\n fields: payload.type\n'})}),"\n",(0,i.jsx)(n.p,{children:"The event_pipeline can be used to filter events and pipeline them to different publishers.\nthe notifier publisher is the message queue broadcasster (RabbitMQ)."}),"\n",(0,i.jsx)(n.h3,{id:"13-event_pipelineyaml",children:"1.3 event_pipeline.yaml"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"---\nsources:\n - name: event_source # 'source name'\n events:\n - \"*\" # 'event filter'\n sinks:\n - event_sink # 'sink name'\nsinks:\n - name: event_sink # 'sink name'\n publishers: # 'list of publishers'\n - notifier://\n - http://localhost:8088/post_json\n"})}),"\n",(0,i.jsx)(n.p,{children:"The pipeline.yaml can be used to filter and pipeline all metrics and events since events send via the notifier also appears in the meters and send them to different publishers."}),"\n",(0,i.jsx)(n.p,{children:"In our case we want to push to the metering api."}),"\n",(0,i.jsx)(n.h3,{id:"14-pipelineyaml",children:"1.4 pipeline.yaml"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'---\nsources:\n - name: meter_source\n meters:\n - "*"\n sinks:\n - meter_sink\nsinks:\n - name: meter_sink\n publishers:\n - gnocchi://?archive_policy=ceilometer-low&filter_project=service\n - http://localhost:8088/post_json\n'})})]})}function _(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>l});var a=t(96540);const i={},d=a.createContext(i);function s(e){const n=a.useContext(d);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),a.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/41be304a.2cd07daf.js b/assets/js/41be304a.2cd07daf.js new file mode 100644 index 0000000000..7479c8c83f --- /dev/null +++ b/assets/js/41be304a.2cd07daf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[90205],{28792:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"iaas/scs-0123","title":"scs-0123: Mandatory and Supported IaaS Services","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0123.md","sourceDirName":"iaas","slug":"/iaas/scs-0123","permalink":"/standards/iaas/scs-0123","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0122-v1-node-to-node-encryption"},"next":{"title":"V1","permalink":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services"}}');var a=s(74848),r=s(28453);const d={},c="scs-0123: Mandatory and Supported IaaS Services",i={},o=[];function l(e){const t={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"scs-0123-mandatory-and-supported-iaas-services",children:"scs-0123: Mandatory and Supported IaaS Services"})}),"\n",(0,a.jsxs)(t.table,{children:[(0,a.jsx)(t.thead,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.th,{children:"Version"}),(0,a.jsx)(t.th,{children:"Type"}),(0,a.jsx)(t.th,{children:"State"}),(0,a.jsx)(t.th,{children:"stabilized"}),(0,a.jsx)(t.th,{children:"deprecated"})]})}),(0,a.jsx)(t.tbody,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.td,{children:(0,a.jsx)(t.a,{href:"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services",children:"scs-0123-v1"})}),(0,a.jsx)(t.td,{children:"Standard"}),(0,a.jsx)(t.td,{children:"Stable"}),(0,a.jsx)(t.td,{children:"2024-11-20"}),(0,a.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>c});var n=s(96540);const a={},r=n.createContext(a);function d(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/41f0af85.0ea3a7d8.js b/assets/js/41f0af85.0ea3a7d8.js new file mode 100644 index 0000000000..0ab7eb2cfe --- /dev/null +++ b/assets/js/41f0af85.0ea3a7d8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[26608],{27843:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>i,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>p});const o=JSON.parse('{"id":"operating-scs/components/status-page-deployment/docs/contribute","title":"Contribute","description":"Contributions are welcome at SovereignCloudStack/status-page-deployment.","source":"@site/docs/04-operating-scs/components/status-page-deployment/docs/contribute.md","sourceDirName":"04-operating-scs/components/status-page-deployment/docs","slug":"/operating-scs/components/status-page-deployment/docs/contribute","permalink":"/docs/operating-scs/components/status-page-deployment/docs/contribute","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-deployment/docs/contribute.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Monitoring","permalink":"/docs/operating-scs/components/status-page-deployment/docs/monitoring"},"next":{"title":"Admin authentication","permalink":"/docs/operating-scs/components/status-page-deployment/docs/admin-authentication"}}');var s=n(74848),c=n(28453);const r={},a="Contribute",i={},p=[];function d(t){const e={a:"a",h1:"h1",header:"header",p:"p",...(0,c.R)(),...t.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.header,{children:(0,s.jsx)(e.h1,{id:"contribute",children:"Contribute"})}),"\n",(0,s.jsxs)(e.p,{children:["Contributions are welcome at ",(0,s.jsx)(e.a,{href:"https://github.com/SovereignCloudStack/status-page-deployment",children:"SovereignCloudStack/status-page-deployment"}),"."]})]})}function u(t={}){const{wrapper:e}={...(0,c.R)(),...t.components};return e?(0,s.jsx)(e,{...t,children:(0,s.jsx)(d,{...t})}):d(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>r,x:()=>a});var o=n(96540);const s={},c=o.createContext(s);function r(t){const e=o.useContext(c);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:r(t.components),o.createElement(c.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/420452be.2c62066d.js b/assets/js/420452be.2c62066d.js new file mode 100644 index 0000000000..bbcb8e2cfb --- /dev/null +++ b/assets/js/420452be.2c62066d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1911],{85763:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"tools/matrix","title":"Matrix","description":"We have created an open community space on the Matrix federation. Feel free to join the several channels and start chatting with our community. A good starting point is entering the General & Announcements and the Tech channel.","source":"@site/community/tools/matrix.md","sourceDirName":"tools","slug":"/tools/matrix","permalink":"/community/tools/matrix","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Jitsi","permalink":"/community/tools/jitsi"},"next":{"title":"Mailing Lists","permalink":"/community/tools/mailinglists"}}');var r=n(74848),o=n(28453);const a={},s="Matrix",c={},l=[{value:"Client and Registration",id:"client-and-registration",level:2}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"matrix",children:"Matrix"})}),"\n",(0,r.jsxs)(t.p,{children:["We have created an ",(0,r.jsx)(t.a,{href:"https://matrix.to/#/!TiDqlLmEUaXqTemaLc:matrix.org?via=matrix.org",children:"open community space on the Matrix federation"}),". Feel free to join the several channels and start chatting with our community. A good starting point is entering the ",(0,r.jsx)(t.a,{href:"https://matrix.to/#/#scs-general:matrix.org",children:"General & Announcements"})," and the ",(0,r.jsx)(t.a,{href:"https://matrix.to/#/#scs-tech:matrix.org",children:"Tech"})," channel."]}),"\n",(0,r.jsx)(t.h2,{id:"client-and-registration",children:"Client and Registration"}),"\n",(0,r.jsxs)(t.p,{children:["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 ",(0,r.jsx)(t.code,{children:"matrix.org"})," homeserver via the Element web client: ",(0,r.jsx)(t.a,{href:"https://app.element.io/#/register%5D",children:"https://app.element.io/#/register"}),". A list of curated Matrix clients is collected on the official Matrix website: ",(0,r.jsx)(t.a,{href:"https://matrix.org/clients/",children:"https://matrix.org/clients/"})]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>s});var i=n(96540);const r={},o=i.createContext(r);function a(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/422fff4b.f89f91ff.js b/assets/js/422fff4b.f89f91ff.js new file mode 100644 index 0000000000..d4464812e5 --- /dev/null +++ b/assets/js/422fff4b.f89f91ff.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[86227],{29003:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"kaas/scs-0210","title":"scs-0210: SCS K8S Version Policy","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/kaas/scs-0210.md","sourceDirName":"kaas","slug":"/kaas/scs-0210","permalink":"/standards/kaas/scs-0210","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests"},"next":{"title":"V1","permalink":"/standards/scs-0210-v1-k8s-new-version-policy"}}');var r=t(74848),d=t(28453);const i={},c="scs-0210: SCS K8S Version Policy",a={},l=[{value:"Supplement: Implementation and Testing Notes",id:"supplement-implementation-and-testing-notes",level:2}];function o(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"scs-0210-scs-k8s-version-policy",children:"scs-0210: SCS K8S Version Policy"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0210-v1-k8s-new-version-policy",children:"scs-0210-v1"})}),(0,r.jsx)(s.td,{children:"Standard"}),(0,r.jsx)(s.td,{children:"Deprecated"}),(0,r.jsx)(s.td,{children:"2023-02-07"}),(0,r.jsx)(s.td,{children:"2024-02-08"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0210-v2-k8s-version-policy",children:"scs-0210-v2"})}),(0,r.jsx)(s.td,{children:"Standard"}),(0,r.jsx)(s.td,{children:"Stable"}),(0,r.jsx)(s.td,{children:"2024-02-08"}),(0,r.jsx)(s.td,{children:"-"})]})]})]}),"\n",(0,r.jsx)(s.h2,{id:"supplement-implementation-and-testing-notes",children:"Supplement: Implementation and Testing Notes"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0210-w1-k8s-version-policy-implementation-testing",children:"w1"})}),(0,r.jsx)(s.td,{children:"Draft"}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,d.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>c});var n=t(96540);const r={},d=n.createContext(r);function i(e){const s=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(d.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/43498.6eca7dce.js b/assets/js/43498.6eca7dce.js new file mode 100644 index 0000000000..ba7b81bc5a --- /dev/null +++ b/assets/js/43498.6eca7dce.js @@ -0,0 +1,2 @@ +/*! For license information please see 43498.6eca7dce.js.LICENSE.txt */ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[43498],{16750:(t,e)=>{"use strict";e.Jf=e.dz=void 0;var i=/^([^\w]*)(javascript|data|vbscript)/im,r=/&#(\w+)(^\w|;)?/g,n=/&(newline|tab);/gi,o=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,a=/^.+(:|:)/gim,s=[".","/"];e.dz="about:blank",e.Jf=function(t){if(!t)return e.dz;var l,c=(l=t,l.replace(o,"").replace(r,(function(t,e){return String.fromCharCode(e)}))).replace(n,"").replace(o,"").trim();if(!c)return e.dz;if(function(t){return s.indexOf(t[0])>-1}(c))return c;var h=c.match(a);if(!h)return c;var u=h[0];return i.test(u)?e.dz:c}},27293:(t,e,i)=>{"use strict";i.d(e,{A:()=>F});var r=i(96540),n=i(74848);function o(t){const{mdxAdmonitionTitle:e,rest:i}=function(t){const e=r.Children.toArray(t),i=e.find((t=>r.isValidElement(t)&&"mdxAdmonitionTitle"===t.type)),o=e.filter((t=>t!==i)),a=i?.props.children;return{mdxAdmonitionTitle:a,rest:o.length>0?(0,n.jsx)(n.Fragment,{children:o}):null}}(t.children),o=t.title??e;return{...t,...o&&{title:o},children:i}}var a=i(18215),s=i(21312),l=i(17559);const c={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function h(t){let{type:e,className:i,children:r}=t;return(0,n.jsx)("div",{className:(0,a.A)(l.G.common.admonition,l.G.common.admonitionType(e),c.admonition,i),children:r})}function u(t){let{icon:e,title:i}=t;return(0,n.jsxs)("div",{className:c.admonitionHeading,children:[(0,n.jsx)("span",{className:c.admonitionIcon,children:e}),i]})}function d(t){let{children:e}=t;return e?(0,n.jsx)("div",{className:c.admonitionContent,children:e}):null}function f(t){const{type:e,icon:i,title:r,children:o,className:a}=t;return(0,n.jsxs)(h,{type:e,className:a,children:[r||i?(0,n.jsx)(u,{title:r,icon:i}):null,(0,n.jsx)(d,{children:o})]})}function p(t){return(0,n.jsx)("svg",{viewBox:"0 0 14 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const g={icon:(0,n.jsx)(p,{}),title:(0,n.jsx)(s.A,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function m(t){return(0,n.jsx)(f,{...g,...t,className:(0,a.A)("alert alert--secondary",t.className),children:t.children})}function y(t){return(0,n.jsx)("svg",{viewBox:"0 0 12 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const x={icon:(0,n.jsx)(y,{}),title:(0,n.jsx)(s.A,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function C(t){return(0,n.jsx)(f,{...x,...t,className:(0,a.A)("alert alert--success",t.className),children:t.children})}function b(t){return(0,n.jsx)("svg",{viewBox:"0 0 14 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const _={icon:(0,n.jsx)(b,{}),title:(0,n.jsx)(s.A,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function v(t){return(0,n.jsx)(f,{..._,...t,className:(0,a.A)("alert alert--info",t.className),children:t.children})}function k(t){return(0,n.jsx)("svg",{viewBox:"0 0 16 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const T={icon:(0,n.jsx)(k,{}),title:(0,n.jsx)(s.A,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function A(t){return(0,n.jsx)("svg",{viewBox:"0 0 12 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const w={icon:(0,n.jsx)(A,{}),title:(0,n.jsx)(s.A,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const S={icon:(0,n.jsx)(k,{}),title:(0,n.jsx)(s.A,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const B={...{note:m,tip:C,info:v,warning:function(t){return(0,n.jsx)(f,{...T,...t,className:(0,a.A)("alert alert--warning",t.className),children:t.children})},danger:function(t){return(0,n.jsx)(f,{...w,...t,className:(0,a.A)("alert alert--danger",t.className),children:t.children})}},...{secondary:t=>(0,n.jsx)(m,{title:"secondary",...t}),important:t=>(0,n.jsx)(v,{title:"important",...t}),success:t=>(0,n.jsx)(C,{title:"success",...t}),caution:function(t){return(0,n.jsx)(f,{...S,...t,className:(0,a.A)("alert alert--warning",t.className),children:t.children})}}};function F(t){const e=o(t),i=(r=e.type,B[r]||(console.warn(`No admonition component found for admonition type "${r}". Using Info as fallback.`),B.info));var r;return(0,n.jsx)(i,{...e})}},4336:(t,e,i)=>{"use strict";i.d(e,{A:()=>m});i(96540);var r=i(18215),n=i(21312),o=i(17559),a=i(28774);const s={iconEdit:"iconEdit_Z9Sw"};var l=i(74848);function c(t){let{className:e,...i}=t;return(0,l.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,r.A)(s.iconEdit,e),"aria-hidden":"true",...i,children:(0,l.jsx)("g",{children:(0,l.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function h(t){let{editUrl:e}=t;return(0,l.jsxs)(a.A,{to:e,className:o.G.common.editThisPage,children:[(0,l.jsx)(c,{}),(0,l.jsx)(n.A,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}var u=i(36266);function d(t){let{lastUpdatedAt:e}=t;const i=new Date(e),r=(0,u.i)({day:"numeric",month:"short",year:"numeric",timeZone:"UTC"}).format(i);return(0,l.jsx)(n.A,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,l.jsx)("b",{children:(0,l.jsx)("time",{dateTime:i.toISOString(),itemProp:"dateModified",children:r})})},children:" on {date}"})}function f(t){let{lastUpdatedBy:e}=t;return(0,l.jsx)(n.A,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,l.jsx)("b",{children:e})},children:" by {user}"})}function p(t){let{lastUpdatedAt:e,lastUpdatedBy:i}=t;return(0,l.jsxs)("span",{className:o.G.common.lastUpdated,children:[(0,l.jsx)(n.A,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:e?(0,l.jsx)(d,{lastUpdatedAt:e}):"",byUser:i?(0,l.jsx)(f,{lastUpdatedBy:i}):""},children:"Last updated{atDate}{byUser}"}),!1]})}const g={lastUpdated:"lastUpdated_JAkA"};function m(t){let{className:e,editUrl:i,lastUpdatedAt:n,lastUpdatedBy:o}=t;return(0,l.jsxs)("div",{className:(0,r.A)("row",e),children:[(0,l.jsx)("div",{className:"col",children:i&&(0,l.jsx)(h,{editUrl:i})}),(0,l.jsx)("div",{className:(0,r.A)("col",g.lastUpdated),children:(n||o)&&(0,l.jsx)(p,{lastUpdatedAt:n,lastUpdatedBy:o})})]})}},11544:(t,e,i)=>{"use strict";i.d(e,{A:()=>yt});var r=i(96540),n=i(28453),o=i(5260),a=i(92303),s=i(18215),l=i(95293),c=i(6342);function h(){const{prism:t}=(0,c.p)(),{colorMode:e}=(0,l.G)(),i=t.theme,r=t.darkTheme||i;return"dark"===e?r:i}var u=i(17559),d=i(18426),f=i.n(d);const p=/title=(?["'])(?.*?)\1/,g=/\{(?<range>[\d,-]+)\}/,m={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},y={...m,lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""},vb:{start:"['\u2018\u2019]",end:""},vbnet:{start:"(?:_\\s*)?['\u2018\u2019]",end:""},rem:{start:"[Rr][Ee][Mm]\\b",end:""},f90:{start:"!",end:""},ml:{start:"\\(\\*",end:"\\*\\)"},cobol:{start:"\\*>",end:""}},x=Object.keys(m);function C(t,e){const i=t.map((t=>{const{start:i,end:r}=y[t];return`(?:${i}\\s*(${e.flatMap((t=>[t.line,t.block?.start,t.block?.end].filter(Boolean))).join("|")})\\s*${r})`})).join("|");return new RegExp(`^\\s*(?:${i})\\s*$`)}function b(t,e){let i=t.replace(/\n$/,"");const{language:r,magicComments:n,metastring:o}=e;if(o&&g.test(o)){const t=o.match(g).groups.range;if(0===n.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${o}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const e=n[0].className,r=f()(t).filter((t=>t>0)).map((t=>[t-1,[e]]));return{lineClassNames:Object.fromEntries(r),code:i}}if(void 0===r)return{lineClassNames:{},code:i};const a=function(t,e){switch(t){case"js":case"javascript":case"ts":case"typescript":return C(["js","jsBlock"],e);case"jsx":case"tsx":return C(["js","jsBlock","jsx"],e);case"html":return C(["js","jsBlock","html"],e);case"python":case"py":case"bash":return C(["bash"],e);case"markdown":case"md":return C(["html","jsx","bash"],e);case"tex":case"latex":case"matlab":return C(["tex"],e);case"lua":case"haskell":case"sql":return C(["lua"],e);case"wasm":return C(["wasm"],e);case"vb":case"vba":case"visual-basic":return C(["vb","rem"],e);case"vbnet":return C(["vbnet","rem"],e);case"batch":return C(["rem"],e);case"basic":return C(["rem","f90"],e);case"fsharp":return C(["js","ml"],e);case"ocaml":case"sml":return C(["ml"],e);case"fortran":return C(["f90"],e);case"cobol":return C(["cobol"],e);default:return C(x,e)}}(r,n),s=i.split("\n"),l=Object.fromEntries(n.map((t=>[t.className,{start:0,range:""}]))),c=Object.fromEntries(n.filter((t=>t.line)).map((t=>{let{className:e,line:i}=t;return[i,e]}))),h=Object.fromEntries(n.filter((t=>t.block)).map((t=>{let{className:e,block:i}=t;return[i.start,e]}))),u=Object.fromEntries(n.filter((t=>t.block)).map((t=>{let{className:e,block:i}=t;return[i.end,e]})));for(let f=0;f<s.length;){const t=s[f].match(a);if(!t){f+=1;continue}const e=t.slice(1).find((t=>void 0!==t));c[e]?l[c[e]].range+=`${f},`:h[e]?l[h[e]].start=f:u[e]&&(l[u[e]].range+=`${l[u[e]].start}-${f-1},`),s.splice(f,1)}i=s.join("\n");const d={};return Object.entries(l).forEach((t=>{let[e,{range:i}]=t;f()(i).forEach((t=>{d[t]??=[],d[t].push(e)}))})),{lineClassNames:d,code:i}}const _={codeBlockContainer:"codeBlockContainer_Ckt0"};var v=i(74848);function k(t){let{as:e,...i}=t;const r=function(t){const e={color:"--prism-color",backgroundColor:"--prism-background-color"},i={};return Object.entries(t.plain).forEach((t=>{let[r,n]=t;const o=e[r];o&&"string"==typeof n&&(i[o]=n)})),i}(h());return(0,v.jsx)(e,{...i,style:r,className:(0,s.A)(i.className,_.codeBlockContainer,u.G.common.codeBlock)})}const T={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function A(t){let{children:e,className:i}=t;return(0,v.jsx)(k,{as:"pre",tabIndex:0,className:(0,s.A)(T.codeBlockStandalone,"thin-scrollbar",i),children:(0,v.jsx)("code",{className:T.codeBlockLines,children:e})})}var w=i(89532);const S={attributes:!0,characterData:!0,childList:!0,subtree:!0};function B(t,e){const[i,n]=(0,r.useState)(),o=(0,r.useCallback)((()=>{n(t.current?.closest("[role=tabpanel][hidden]"))}),[t,n]);(0,r.useEffect)((()=>{o()}),[o]),function(t,e,i){void 0===i&&(i=S);const n=(0,w._q)(e),o=(0,w.Be)(i);(0,r.useEffect)((()=>{const e=new MutationObserver(n);return t&&e.observe(t,o),()=>e.disconnect()}),[t,n,o])}(i,(t=>{t.forEach((t=>{"attributes"===t.type&&"hidden"===t.attributeName&&(e(),o())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}var F=i(78181);const L={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function M(t){let{line:e,classNames:i,showLineNumbers:r,getLineProps:n,getTokenProps:o}=t;1===e.length&&"\n"===e[0].content&&(e[0].content="");const a=n({line:e,className:(0,s.A)(i,r&&L.codeLine)}),l=e.map(((t,e)=>(0,v.jsx)("span",{...o({token:t})},e)));return(0,v.jsxs)("span",{...a,children:[r?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)("span",{className:L.codeLineNumber}),(0,v.jsx)("span",{className:L.codeLineContent,children:l})]}):l,(0,v.jsx)("br",{})]})}var E=i(21312);function N(t){return(0,v.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,v.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function O(t){return(0,v.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,v.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const j={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function I(t){let{code:e,className:i}=t;const[n,o]=(0,r.useState)(!1),a=(0,r.useRef)(void 0),l=(0,r.useCallback)((()=>{!function(t,e){let{target:i=document.body}=void 0===e?{}:e;if("string"!=typeof t)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof t}\`.`);const r=document.createElement("textarea"),n=document.activeElement;r.value=t,r.setAttribute("readonly",""),r.style.contain="strict",r.style.position="absolute",r.style.left="-9999px",r.style.fontSize="12pt";const o=document.getSelection(),a=o.rangeCount>0&&o.getRangeAt(0);i.append(r),r.select(),r.selectionStart=0,r.selectionEnd=t.length;let s=!1;try{s=document.execCommand("copy")}catch{}r.remove(),a&&(o.removeAllRanges(),o.addRange(a)),n&&n.focus()}(e),o(!0),a.current=window.setTimeout((()=>{o(!1)}),1e3)}),[e]);return(0,r.useEffect)((()=>()=>window.clearTimeout(a.current)),[]),(0,v.jsx)("button",{type:"button","aria-label":n?(0,E.T)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,E.T)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,E.T)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,s.A)("clean-btn",i,j.copyButton,n&&j.copyButtonCopied),onClick:l,children:(0,v.jsxs)("span",{className:j.copyButtonIcons,"aria-hidden":"true",children:[(0,v.jsx)(N,{className:j.copyButtonIcon}),(0,v.jsx)(O,{className:j.copyButtonSuccessIcon})]})})}function D(t){return(0,v.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,v.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const q={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function $(t){let{className:e,onClick:i,isEnabled:r}=t;const n=(0,E.T)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,v.jsx)("button",{type:"button",onClick:i,className:(0,s.A)("clean-btn",e,r&&q.wordWrapButtonEnabled),"aria-label":n,title:n,children:(0,v.jsx)(D,{className:q.wordWrapButtonIcon,"aria-hidden":"true"})})}function z(t){let{children:e,className:i="",metastring:n,title:o,showLineNumbers:a,language:l}=t;const{prism:{defaultLanguage:u,magicComments:d}}=(0,c.p)(),f=function(t){return t?.toLowerCase()}(l??function(t){const e=t.split(" ").find((t=>t.startsWith("language-")));return e?.replace(/language-/,"")}(i)??u),g=h(),m=function(){const[t,e]=(0,r.useState)(!1),[i,n]=(0,r.useState)(!1),o=(0,r.useRef)(null),a=(0,r.useCallback)((()=>{const i=o.current.querySelector("code");t?i.removeAttribute("style"):(i.style.whiteSpace="pre-wrap",i.style.overflowWrap="anywhere"),e((t=>!t))}),[o,t]),s=(0,r.useCallback)((()=>{const{scrollWidth:t,clientWidth:e}=o.current,i=t>e||o.current.querySelector("code").hasAttribute("style");n(i)}),[o]);return B(o,s),(0,r.useEffect)((()=>{s()}),[t,s]),(0,r.useEffect)((()=>(window.addEventListener("resize",s,{passive:!0}),()=>{window.removeEventListener("resize",s)})),[s]),{codeBlockRef:o,isEnabled:t,isCodeScrollable:i,toggle:a}}(),y=function(t){return t?.match(p)?.groups.title??""}(n)||o,{lineClassNames:x,code:C}=b(e,{metastring:n,language:f,magicComments:d}),_=a??function(t){return Boolean(t?.includes("showLineNumbers"))}(n);return(0,v.jsxs)(k,{as:"div",className:(0,s.A)(i,f&&!i.includes(`language-${f}`)&&`language-${f}`),children:[y&&(0,v.jsx)("div",{className:T.codeBlockTitle,children:y}),(0,v.jsxs)("div",{className:T.codeBlockContent,children:[(0,v.jsx)(F.f4,{theme:g,code:C,language:f??"text",children:t=>{let{className:e,style:i,tokens:r,getLineProps:n,getTokenProps:o}=t;return(0,v.jsx)("pre",{tabIndex:0,ref:m.codeBlockRef,className:(0,s.A)(e,T.codeBlock,"thin-scrollbar"),style:i,children:(0,v.jsx)("code",{className:(0,s.A)(T.codeBlockLines,_&&T.codeBlockLinesWithNumbering),children:r.map(((t,e)=>(0,v.jsx)(M,{line:t,getLineProps:n,getTokenProps:o,classNames:x[e],showLineNumbers:_},e)))})})}}),(0,v.jsxs)("div",{className:T.buttonGroup,children:[(m.isEnabled||m.isCodeScrollable)&&(0,v.jsx)($,{className:T.codeButton,onClick:()=>m.toggle(),isEnabled:m.isEnabled}),(0,v.jsx)(I,{className:T.codeButton,code:C})]})]})]})}function P(t){let{children:e,...i}=t;const n=(0,a.A)(),o=function(t){return r.Children.toArray(t).some((t=>(0,r.isValidElement)(t)))?t:Array.isArray(t)?t.join(""):t}(e),s="string"==typeof o?z:A;return(0,v.jsx)(s,{...i,children:o},String(n))}function R(t){return(0,v.jsx)("code",{...t})}var W=i(28774);var U=i(15066),H=i(63427),Y=i(41422);const V={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function G(t){return!!t&&("SUMMARY"===t.tagName||G(t.parentElement))}function X(t,e){return!!t&&(t===e||X(t.parentElement,e))}function Z(t){let{summary:e,children:i,...n}=t;(0,H.A)().collectAnchor(n.id);const o=(0,a.A)(),s=(0,r.useRef)(null),{collapsed:l,setCollapsed:c}=(0,Y.u)({initialState:!n.open}),[h,u]=(0,r.useState)(n.open),d=r.isValidElement(e)?e:(0,v.jsx)("summary",{children:e??"Details"});return(0,v.jsxs)("details",{...n,ref:s,open:h,"data-collapsed":l,className:(0,U.A)(V.details,o&&V.isBrowser,n.className),onMouseDown:t=>{G(t.target)&&t.detail>1&&t.preventDefault()},onClick:t=>{t.stopPropagation();const e=t.target;G(e)&&X(e,s.current)&&(t.preventDefault(),l?(c(!1),u(!0)):c(!0))},children:[d,(0,v.jsx)(Y.N,{lazy:!1,collapsed:l,disableSSRStyle:!0,onCollapseTransitionEnd:t=>{c(t),u(!t)},children:(0,v.jsx)("div",{className:V.collapsibleContent,children:i})})]})}const J={details:"details_b_Ee"},Q="alert alert--info";function K(t){let{...e}=t;return(0,v.jsx)(Z,{...e,className:(0,s.A)(Q,J.details,e.className)})}function tt(t){const e=r.Children.toArray(t.children),i=e.find((t=>r.isValidElement(t)&&"summary"===t.type)),n=(0,v.jsx)(v.Fragment,{children:e.filter((t=>t!==i))});return(0,v.jsx)(K,{...t,summary:i,children:n})}var et=i(51107);function it(t){return(0,v.jsx)(et.A,{...t})}const rt={containsTaskList:"containsTaskList_mC6p"};function nt(t){if(void 0!==t)return(0,s.A)(t,t?.includes("contains-task-list")&&rt.containsTaskList)}const ot={img:"img_ev3q"};var at=i(27293),st=i(67489),lt=i(12181),ct=i(86079);const ht="docusaurus-mermaid-container";function ut(){const{colorMode:t}=(0,l.G)(),e=(0,c.p)().mermaid,i=e.theme[t],{options:n}=e;return(0,r.useMemo)((()=>({startOnLoad:!1,...n,theme:i})),[i,n])}function dt(t){let{text:e,config:i}=t;const[n,o]=(0,r.useState)(null),a=(0,r.useRef)(`mermaid-svg-${Math.round(1e7*Math.random())}`).current,s=ut(),l=i??s;return(0,r.useEffect)((()=>{(async function(t){let{id:e,text:i,config:r}=t;ct.N.mermaidAPI.initialize(r);try{return await ct.N.render(e,i)}catch(n){throw document.querySelector(`#d${e}`)?.remove(),n}})({id:a,text:e,config:l}).then(o).catch((t=>{o((()=>{throw t}))}))}),[a,e,l]),n}const ft={container:"container_lyt7"};function pt(t){let{renderResult:e}=t;const i=(0,r.useRef)(null);return(0,r.useEffect)((()=>{const t=i.current;e.bindFunctions?.(t)}),[e]),(0,v.jsx)("div",{ref:i,className:`${ht} ${ft.container}`,dangerouslySetInnerHTML:{__html:e.svg}})}function gt(t){let{value:e}=t;const i=dt({text:e});return null===i?null:(0,v.jsx)(pt,{renderResult:i})}const mt={Head:o.A,details:tt,Details:tt,code:function(t){return function(t){return void 0!==t.children&&r.Children.toArray(t.children).every((t=>"string"==typeof t&&!t.includes("\n")))}(t)?(0,v.jsx)(R,{...t}):(0,v.jsx)(P,{...t})},a:function(t){return(0,v.jsx)(W.A,{...t})},pre:function(t){return(0,v.jsx)(v.Fragment,{children:t.children})},ul:function(t){return(0,v.jsx)("ul",{...t,className:nt(t.className)})},li:function(t){return(0,H.A)().collectAnchor(t.id),(0,v.jsx)("li",{...t})},img:function(t){return(0,v.jsx)("img",{decoding:"async",loading:"lazy",...t,className:(e=t.className,(0,s.A)(e,ot.img))});var e},h1:t=>(0,v.jsx)(it,{as:"h1",...t}),h2:t=>(0,v.jsx)(it,{as:"h2",...t}),h3:t=>(0,v.jsx)(it,{as:"h3",...t}),h4:t=>(0,v.jsx)(it,{as:"h4",...t}),h5:t=>(0,v.jsx)(it,{as:"h5",...t}),h6:t=>(0,v.jsx)(it,{as:"h6",...t}),admonition:at.A,mermaid:function(t){return(0,v.jsx)(st.A,{fallback:t=>(0,v.jsx)(lt.MN,{...t}),children:(0,v.jsx)(gt,{...t})})}};function yt(t){let{children:e}=t;return(0,v.jsx)(n.x,{components:mt,children:e})}},39022:(t,e,i)=>{"use strict";i.d(e,{A:()=>a});i(96540);var r=i(18215),n=i(28774),o=i(74848);function a(t){const{permalink:e,title:i,subLabel:a,isNext:s}=t;return(0,o.jsxs)(n.A,{className:(0,r.A)("pagination-nav__link",s?"pagination-nav__link--next":"pagination-nav__link--prev"),to:e,children:[a&&(0,o.jsx)("div",{className:"pagination-nav__sublabel",children:a}),(0,o.jsx)("div",{className:"pagination-nav__label",children:i})]})}},56133:(t,e,i)=>{"use strict";i.d(e,{A:()=>s});i(96540);var r=i(18215),n=i(28774);const o={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var a=i(74848);function s(t){let{permalink:e,label:i,count:s,description:l}=t;return(0,a.jsxs)(n.A,{href:e,title:l,className:(0,r.A)(o.tag,s?o.tagWithCount:o.tagRegular),children:[i,s&&(0,a.jsx)("span",{children:s})]})}},62053:(t,e,i)=>{"use strict";i.d(e,{A:()=>l});i(96540);var r=i(18215),n=i(21312),o=i(56133);const a={tags:"tags_jXut",tag:"tag_QGVx"};var s=i(74848);function l(t){let{tags:e}=t;return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("b",{children:(0,s.jsx)(n.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,s.jsx)("ul",{className:(0,r.A)(a.tags,"padding--none","margin-left--sm"),children:e.map((t=>(0,s.jsx)("li",{className:a.tag,children:(0,s.jsx)(o.A,{...t})},t.permalink)))})]})}},36266:(t,e,i)=>{"use strict";i.d(e,{i:()=>n});var r=i(44586);function n(t){void 0===t&&(t={});const{i18n:{currentLocale:e}}=(0,r.A)(),i=function(){const{i18n:{currentLocale:t,localeConfigs:e}}=(0,r.A)();return e[t].calendar}();return new Intl.DateTimeFormat(e,{calendar:i,...t})}},74353:function(t){t.exports=function(){"use strict";var t=1e3,e=6e4,i=36e5,r="millisecond",n="second",o="minute",a="hour",s="day",l="week",c="month",h="quarter",u="year",d="date",f="Invalid Date",p=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,g=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,m={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],i=t%100;return"["+t+(e[(i-20)%10]||e[i]||e[0])+"]"}},y=function(t,e,i){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(i)+t},x={s:y,z:function(t){var e=-t.utcOffset(),i=Math.abs(e),r=Math.floor(i/60),n=i%60;return(e<=0?"+":"-")+y(r,2,"0")+":"+y(n,2,"0")},m:function t(e,i){if(e.date()<i.date())return-t(i,e);var r=12*(i.year()-e.year())+(i.month()-e.month()),n=e.clone().add(r,c),o=i-n<0,a=e.clone().add(r+(o?-1:1),c);return+(-(r+(i-n)/(o?n-a:a-n))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return{M:c,y:u,w:l,d:s,D:d,h:a,m:o,s:n,ms:r,Q:h}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},C="en",b={};b[C]=m;var _="$isDayjsObject",v=function(t){return t instanceof w||!(!t||!t[_])},k=function t(e,i,r){var n;if(!e)return C;if("string"==typeof e){var o=e.toLowerCase();b[o]&&(n=o),i&&(b[o]=i,n=o);var a=e.split("-");if(!n&&a.length>1)return t(a[0])}else{var s=e.name;b[s]=e,n=s}return!r&&n&&(C=n),n||!r&&C},T=function(t,e){if(v(t))return t.clone();var i="object"==typeof e?e:{};return i.date=t,i.args=arguments,new w(i)},A=x;A.l=k,A.i=v,A.w=function(t,e){return T(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var w=function(){function m(t){this.$L=k(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[_]=!0}var y=m.prototype;return y.parse=function(t){this.$d=function(t){var e=t.date,i=t.utc;if(null===e)return new Date(NaN);if(A.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(p);if(r){var n=r[2]-1||0,o=(r[7]||"0").substring(0,3);return i?new Date(Date.UTC(r[1],n,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)):new Date(r[1],n,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)}}return new Date(e)}(t),this.init()},y.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},y.$utils=function(){return A},y.isValid=function(){return!(this.$d.toString()===f)},y.isSame=function(t,e){var i=T(t);return this.startOf(e)<=i&&i<=this.endOf(e)},y.isAfter=function(t,e){return T(t)<this.startOf(e)},y.isBefore=function(t,e){return this.endOf(e)<T(t)},y.$g=function(t,e,i){return A.u(t)?this[e]:this.set(i,t)},y.unix=function(){return Math.floor(this.valueOf()/1e3)},y.valueOf=function(){return this.$d.getTime()},y.startOf=function(t,e){var i=this,r=!!A.u(e)||e,h=A.p(t),f=function(t,e){var n=A.w(i.$u?Date.UTC(i.$y,e,t):new Date(i.$y,e,t),i);return r?n:n.endOf(s)},p=function(t,e){return A.w(i.toDate()[t].apply(i.toDate("s"),(r?[0,0,0,0]:[23,59,59,999]).slice(e)),i)},g=this.$W,m=this.$M,y=this.$D,x="set"+(this.$u?"UTC":"");switch(h){case u:return r?f(1,0):f(31,11);case c:return r?f(1,m):f(0,m+1);case l:var C=this.$locale().weekStart||0,b=(g<C?g+7:g)-C;return f(r?y-b:y+(6-b),m);case s:case d:return p(x+"Hours",0);case a:return p(x+"Minutes",1);case o:return p(x+"Seconds",2);case n:return p(x+"Milliseconds",3);default:return this.clone()}},y.endOf=function(t){return this.startOf(t,!1)},y.$set=function(t,e){var i,l=A.p(t),h="set"+(this.$u?"UTC":""),f=(i={},i[s]=h+"Date",i[d]=h+"Date",i[c]=h+"Month",i[u]=h+"FullYear",i[a]=h+"Hours",i[o]=h+"Minutes",i[n]=h+"Seconds",i[r]=h+"Milliseconds",i)[l],p=l===s?this.$D+(e-this.$W):e;if(l===c||l===u){var g=this.clone().set(d,1);g.$d[f](p),g.init(),this.$d=g.set(d,Math.min(this.$D,g.daysInMonth())).$d}else f&&this.$d[f](p);return this.init(),this},y.set=function(t,e){return this.clone().$set(t,e)},y.get=function(t){return this[A.p(t)]()},y.add=function(r,h){var d,f=this;r=Number(r);var p=A.p(h),g=function(t){var e=T(f);return A.w(e.date(e.date()+Math.round(t*r)),f)};if(p===c)return this.set(c,this.$M+r);if(p===u)return this.set(u,this.$y+r);if(p===s)return g(1);if(p===l)return g(7);var m=(d={},d[o]=e,d[a]=i,d[n]=t,d)[p]||1,y=this.$d.getTime()+r*m;return A.w(y,this)},y.subtract=function(t,e){return this.add(-1*t,e)},y.format=function(t){var e=this,i=this.$locale();if(!this.isValid())return i.invalidDate||f;var r=t||"YYYY-MM-DDTHH:mm:ssZ",n=A.z(this),o=this.$H,a=this.$m,s=this.$M,l=i.weekdays,c=i.months,h=i.meridiem,u=function(t,i,n,o){return t&&(t[i]||t(e,r))||n[i].slice(0,o)},d=function(t){return A.s(o%12||12,t,"0")},p=h||function(t,e,i){var r=t<12?"AM":"PM";return i?r.toLowerCase():r};return r.replace(g,(function(t,r){return r||function(t){switch(t){case"YY":return String(e.$y).slice(-2);case"YYYY":return A.s(e.$y,4,"0");case"M":return s+1;case"MM":return A.s(s+1,2,"0");case"MMM":return u(i.monthsShort,s,c,3);case"MMMM":return u(c,s);case"D":return e.$D;case"DD":return A.s(e.$D,2,"0");case"d":return String(e.$W);case"dd":return u(i.weekdaysMin,e.$W,l,2);case"ddd":return u(i.weekdaysShort,e.$W,l,3);case"dddd":return l[e.$W];case"H":return String(o);case"HH":return A.s(o,2,"0");case"h":return d(1);case"hh":return d(2);case"a":return p(o,a,!0);case"A":return p(o,a,!1);case"m":return String(a);case"mm":return A.s(a,2,"0");case"s":return String(e.$s);case"ss":return A.s(e.$s,2,"0");case"SSS":return A.s(e.$ms,3,"0");case"Z":return n}return null}(t)||n.replace(":","")}))},y.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},y.diff=function(r,d,f){var p,g=this,m=A.p(d),y=T(r),x=(y.utcOffset()-this.utcOffset())*e,C=this-y,b=function(){return A.m(g,y)};switch(m){case u:p=b()/12;break;case c:p=b();break;case h:p=b()/3;break;case l:p=(C-x)/6048e5;break;case s:p=(C-x)/864e5;break;case a:p=C/i;break;case o:p=C/e;break;case n:p=C/t;break;default:p=C}return f?p:A.a(p)},y.daysInMonth=function(){return this.endOf(c).$D},y.$locale=function(){return b[this.$L]},y.locale=function(t,e){if(!t)return this.$L;var i=this.clone(),r=k(t,e,!0);return r&&(i.$L=r),i},y.clone=function(){return A.w(this.$d,this)},y.toDate=function(){return new Date(this.valueOf())},y.toJSON=function(){return this.isValid()?this.toISOString():null},y.toISOString=function(){return this.$d.toISOString()},y.toString=function(){return this.$d.toUTCString()},m}(),S=w.prototype;return T.prototype=S,[["$ms",r],["$s",n],["$m",o],["$H",a],["$W",s],["$M",c],["$y",u],["$D",d]].forEach((function(t){S[t[1]]=function(e){return this.$g(e,t[0],t[1])}})),T.extend=function(t,e){return t.$i||(t(e,w,T),t.$i=!0),T},T.locale=k,T.isDayjs=v,T.unix=function(t){return T(1e3*t)},T.en=b[C],T.Ls=b,T.p={},T}()},42838:function(t){t.exports=function(){"use strict";const{entries:t,setPrototypeOf:e,isFrozen:i,getPrototypeOf:r,getOwnPropertyDescriptor:n}=Object;let{freeze:o,seal:a,create:s}=Object,{apply:l,construct:c}="undefined"!=typeof Reflect&&Reflect;o||(o=function(t){return t}),a||(a=function(t){return t}),l||(l=function(t,e,i){return t.apply(e,i)}),c||(c=function(t,e){return new t(...e)});const h=v(Array.prototype.forEach),u=v(Array.prototype.pop),d=v(Array.prototype.push),f=v(String.prototype.toLowerCase),p=v(String.prototype.toString),g=v(String.prototype.match),m=v(String.prototype.replace),y=v(String.prototype.indexOf),x=v(String.prototype.trim),C=v(Object.prototype.hasOwnProperty),b=v(RegExp.prototype.test),_=k(TypeError);function v(t){return function(e){for(var i=arguments.length,r=new Array(i>1?i-1:0),n=1;n<i;n++)r[n-1]=arguments[n];return l(t,e,r)}}function k(t){return function(){for(var e=arguments.length,i=new Array(e),r=0;r<e;r++)i[r]=arguments[r];return c(t,i)}}function T(t,r){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:f;e&&e(t,null);let o=r.length;for(;o--;){let e=r[o];if("string"==typeof e){const t=n(e);t!==e&&(i(r)||(r[o]=t),e=t)}t[e]=!0}return t}function A(t){for(let e=0;e<t.length;e++)C(t,e)||(t[e]=null);return t}function w(e){const i=s(null);for(const[r,n]of t(e))C(e,r)&&(Array.isArray(n)?i[r]=A(n):n&&"object"==typeof n&&n.constructor===Object?i[r]=w(n):i[r]=n);return i}function S(t,e){for(;null!==t;){const i=n(t,e);if(i){if(i.get)return v(i.get);if("function"==typeof i.value)return v(i.value)}t=r(t)}function i(){return null}return i}const B=o(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),F=o(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),L=o(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),M=o(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),E=o(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),N=o(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),O=o(["#text"]),j=o(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),I=o(["accent-height","accumulate","additive","alignment-baseline","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),D=o(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),q=o(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),$=a(/\{\{[\w\W]*|[\w\W]*\}\}/gm),z=a(/<%[\w\W]*|[\w\W]*%>/gm),P=a(/\${[\w\W]*}/gm),R=a(/^data-[\-\w.\u00B7-\uFFFF]/),W=a(/^aria-[\-\w]+$/),U=a(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),H=a(/^(?:\w+script|data):/i),Y=a(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),V=a(/^html$/i),G=a(/^[a-z][.\w]*(-[.\w]+)+$/i);var X=Object.freeze({__proto__:null,MUSTACHE_EXPR:$,ERB_EXPR:z,TMPLIT_EXPR:P,DATA_ATTR:R,ARIA_ATTR:W,IS_ALLOWED_URI:U,IS_SCRIPT_OR_DATA:H,ATTR_WHITESPACE:Y,DOCTYPE_NAME:V,CUSTOM_ELEMENT:G});const Z={element:1,attribute:2,text:3,cdataSection:4,entityReference:5,entityNode:6,progressingInstruction:7,comment:8,document:9,documentType:10,documentFragment:11,notation:12},J=function(){return"undefined"==typeof window?null:window},Q=function(t,e){if("object"!=typeof t||"function"!=typeof t.createPolicy)return null;let i=null;const r="data-tt-policy-suffix";e&&e.hasAttribute(r)&&(i=e.getAttribute(r));const n="dompurify"+(i?"#"+i:"");try{return t.createPolicy(n,{createHTML:t=>t,createScriptURL:t=>t})}catch(o){return console.warn("TrustedTypes policy "+n+" could not be created."),null}};function K(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:J();const i=t=>K(t);if(i.version="3.1.6",i.removed=[],!e||!e.document||e.document.nodeType!==Z.document)return i.isSupported=!1,i;let{document:r}=e;const n=r,a=n.currentScript,{DocumentFragment:l,HTMLTemplateElement:c,Node:v,Element:k,NodeFilter:A,NamedNodeMap:$=e.NamedNodeMap||e.MozNamedAttrMap,HTMLFormElement:z,DOMParser:P,trustedTypes:R}=e,W=k.prototype,H=S(W,"cloneNode"),Y=S(W,"remove"),G=S(W,"nextSibling"),tt=S(W,"childNodes"),et=S(W,"parentNode");if("function"==typeof c){const t=r.createElement("template");t.content&&t.content.ownerDocument&&(r=t.content.ownerDocument)}let it,rt="";const{implementation:nt,createNodeIterator:ot,createDocumentFragment:at,getElementsByTagName:st}=r,{importNode:lt}=n;let ct={};i.isSupported="function"==typeof t&&"function"==typeof et&&nt&&void 0!==nt.createHTMLDocument;const{MUSTACHE_EXPR:ht,ERB_EXPR:ut,TMPLIT_EXPR:dt,DATA_ATTR:ft,ARIA_ATTR:pt,IS_SCRIPT_OR_DATA:gt,ATTR_WHITESPACE:mt,CUSTOM_ELEMENT:yt}=X;let{IS_ALLOWED_URI:xt}=X,Ct=null;const bt=T({},[...B,...F,...L,...E,...O]);let _t=null;const vt=T({},[...j,...I,...D,...q]);let kt=Object.seal(s(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),Tt=null,At=null,wt=!0,St=!0,Bt=!1,Ft=!0,Lt=!1,Mt=!0,Et=!1,Nt=!1,Ot=!1,jt=!1,It=!1,Dt=!1,qt=!0,$t=!1;const zt="user-content-";let Pt=!0,Rt=!1,Wt={},Ut=null;const Ht=T({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let Yt=null;const Vt=T({},["audio","video","img","source","image","track"]);let Gt=null;const Xt=T({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Zt="http://www.w3.org/1998/Math/MathML",Jt="http://www.w3.org/2000/svg",Qt="http://www.w3.org/1999/xhtml";let Kt=Qt,te=!1,ee=null;const ie=T({},[Zt,Jt,Qt],p);let re=null;const ne=["application/xhtml+xml","text/html"],oe="text/html";let ae=null,se=null;const le=r.createElement("form"),ce=function(t){return t instanceof RegExp||t instanceof Function},he=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!se||se!==t){if(t&&"object"==typeof t||(t={}),t=w(t),re=-1===ne.indexOf(t.PARSER_MEDIA_TYPE)?oe:t.PARSER_MEDIA_TYPE,ae="application/xhtml+xml"===re?p:f,Ct=C(t,"ALLOWED_TAGS")?T({},t.ALLOWED_TAGS,ae):bt,_t=C(t,"ALLOWED_ATTR")?T({},t.ALLOWED_ATTR,ae):vt,ee=C(t,"ALLOWED_NAMESPACES")?T({},t.ALLOWED_NAMESPACES,p):ie,Gt=C(t,"ADD_URI_SAFE_ATTR")?T(w(Xt),t.ADD_URI_SAFE_ATTR,ae):Xt,Yt=C(t,"ADD_DATA_URI_TAGS")?T(w(Vt),t.ADD_DATA_URI_TAGS,ae):Vt,Ut=C(t,"FORBID_CONTENTS")?T({},t.FORBID_CONTENTS,ae):Ht,Tt=C(t,"FORBID_TAGS")?T({},t.FORBID_TAGS,ae):{},At=C(t,"FORBID_ATTR")?T({},t.FORBID_ATTR,ae):{},Wt=!!C(t,"USE_PROFILES")&&t.USE_PROFILES,wt=!1!==t.ALLOW_ARIA_ATTR,St=!1!==t.ALLOW_DATA_ATTR,Bt=t.ALLOW_UNKNOWN_PROTOCOLS||!1,Ft=!1!==t.ALLOW_SELF_CLOSE_IN_ATTR,Lt=t.SAFE_FOR_TEMPLATES||!1,Mt=!1!==t.SAFE_FOR_XML,Et=t.WHOLE_DOCUMENT||!1,jt=t.RETURN_DOM||!1,It=t.RETURN_DOM_FRAGMENT||!1,Dt=t.RETURN_TRUSTED_TYPE||!1,Ot=t.FORCE_BODY||!1,qt=!1!==t.SANITIZE_DOM,$t=t.SANITIZE_NAMED_PROPS||!1,Pt=!1!==t.KEEP_CONTENT,Rt=t.IN_PLACE||!1,xt=t.ALLOWED_URI_REGEXP||U,Kt=t.NAMESPACE||Qt,kt=t.CUSTOM_ELEMENT_HANDLING||{},t.CUSTOM_ELEMENT_HANDLING&&ce(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(kt.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&ce(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(kt.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(kt.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Lt&&(St=!1),It&&(jt=!0),Wt&&(Ct=T({},O),_t=[],!0===Wt.html&&(T(Ct,B),T(_t,j)),!0===Wt.svg&&(T(Ct,F),T(_t,I),T(_t,q)),!0===Wt.svgFilters&&(T(Ct,L),T(_t,I),T(_t,q)),!0===Wt.mathMl&&(T(Ct,E),T(_t,D),T(_t,q))),t.ADD_TAGS&&(Ct===bt&&(Ct=w(Ct)),T(Ct,t.ADD_TAGS,ae)),t.ADD_ATTR&&(_t===vt&&(_t=w(_t)),T(_t,t.ADD_ATTR,ae)),t.ADD_URI_SAFE_ATTR&&T(Gt,t.ADD_URI_SAFE_ATTR,ae),t.FORBID_CONTENTS&&(Ut===Ht&&(Ut=w(Ut)),T(Ut,t.FORBID_CONTENTS,ae)),Pt&&(Ct["#text"]=!0),Et&&T(Ct,["html","head","body"]),Ct.table&&(T(Ct,["tbody"]),delete Tt.tbody),t.TRUSTED_TYPES_POLICY){if("function"!=typeof t.TRUSTED_TYPES_POLICY.createHTML)throw _('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof t.TRUSTED_TYPES_POLICY.createScriptURL)throw _('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');it=t.TRUSTED_TYPES_POLICY,rt=it.createHTML("")}else void 0===it&&(it=Q(R,a)),null!==it&&"string"==typeof rt&&(rt=it.createHTML(""));o&&o(t),se=t}},ue=T({},["mi","mo","mn","ms","mtext"]),de=T({},["foreignobject","annotation-xml"]),fe=T({},["title","style","font","a","script"]),pe=T({},[...F,...L,...M]),ge=T({},[...E,...N]),me=function(t){let e=et(t);e&&e.tagName||(e={namespaceURI:Kt,tagName:"template"});const i=f(t.tagName),r=f(e.tagName);return!!ee[t.namespaceURI]&&(t.namespaceURI===Jt?e.namespaceURI===Qt?"svg"===i:e.namespaceURI===Zt?"svg"===i&&("annotation-xml"===r||ue[r]):Boolean(pe[i]):t.namespaceURI===Zt?e.namespaceURI===Qt?"math"===i:e.namespaceURI===Jt?"math"===i&&de[r]:Boolean(ge[i]):t.namespaceURI===Qt?!(e.namespaceURI===Jt&&!de[r])&&!(e.namespaceURI===Zt&&!ue[r])&&!ge[i]&&(fe[i]||!pe[i]):!("application/xhtml+xml"!==re||!ee[t.namespaceURI]))},ye=function(t){d(i.removed,{element:t});try{et(t).removeChild(t)}catch(e){Y(t)}},xe=function(t,e){try{d(i.removed,{attribute:e.getAttributeNode(t),from:e})}catch(r){d(i.removed,{attribute:null,from:e})}if(e.removeAttribute(t),"is"===t&&!_t[t])if(jt||It)try{ye(e)}catch(r){}else try{e.setAttribute(t,"")}catch(r){}},Ce=function(t){let e=null,i=null;if(Ot)t="<remove></remove>"+t;else{const e=g(t,/^[\r\n\t ]+/);i=e&&e[0]}"application/xhtml+xml"===re&&Kt===Qt&&(t='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+t+"</body></html>");const n=it?it.createHTML(t):t;if(Kt===Qt)try{e=(new P).parseFromString(n,re)}catch(a){}if(!e||!e.documentElement){e=nt.createDocument(Kt,"template",null);try{e.documentElement.innerHTML=te?rt:n}catch(a){}}const o=e.body||e.documentElement;return t&&i&&o.insertBefore(r.createTextNode(i),o.childNodes[0]||null),Kt===Qt?st.call(e,Et?"html":"body")[0]:Et?e.documentElement:o},be=function(t){return ot.call(t.ownerDocument||t,t,A.SHOW_ELEMENT|A.SHOW_COMMENT|A.SHOW_TEXT|A.SHOW_PROCESSING_INSTRUCTION|A.SHOW_CDATA_SECTION,null)},_e=function(t){return t instanceof z&&("string"!=typeof t.nodeName||"string"!=typeof t.textContent||"function"!=typeof t.removeChild||!(t.attributes instanceof $)||"function"!=typeof t.removeAttribute||"function"!=typeof t.setAttribute||"string"!=typeof t.namespaceURI||"function"!=typeof t.insertBefore||"function"!=typeof t.hasChildNodes)},ve=function(t){return"function"==typeof v&&t instanceof v},ke=function(t,e,r){ct[t]&&h(ct[t],(t=>{t.call(i,e,r,se)}))},Te=function(t){let e=null;if(ke("beforeSanitizeElements",t,null),_e(t))return ye(t),!0;const r=ae(t.nodeName);if(ke("uponSanitizeElement",t,{tagName:r,allowedTags:Ct}),t.hasChildNodes()&&!ve(t.firstElementChild)&&b(/<[/\w]/g,t.innerHTML)&&b(/<[/\w]/g,t.textContent))return ye(t),!0;if(t.nodeType===Z.progressingInstruction)return ye(t),!0;if(Mt&&t.nodeType===Z.comment&&b(/<[/\w]/g,t.data))return ye(t),!0;if(!Ct[r]||Tt[r]){if(!Tt[r]&&we(r)){if(kt.tagNameCheck instanceof RegExp&&b(kt.tagNameCheck,r))return!1;if(kt.tagNameCheck instanceof Function&&kt.tagNameCheck(r))return!1}if(Pt&&!Ut[r]){const e=et(t)||t.parentNode,i=tt(t)||t.childNodes;if(i&&e)for(let r=i.length-1;r>=0;--r){const n=H(i[r],!0);n.__removalCount=(t.__removalCount||0)+1,e.insertBefore(n,G(t))}}return ye(t),!0}return t instanceof k&&!me(t)?(ye(t),!0):"noscript"!==r&&"noembed"!==r&&"noframes"!==r||!b(/<\/no(script|embed|frames)/i,t.innerHTML)?(Lt&&t.nodeType===Z.text&&(e=t.textContent,h([ht,ut,dt],(t=>{e=m(e,t," ")})),t.textContent!==e&&(d(i.removed,{element:t.cloneNode()}),t.textContent=e)),ke("afterSanitizeElements",t,null),!1):(ye(t),!0)},Ae=function(t,e,i){if(qt&&("id"===e||"name"===e)&&(i in r||i in le))return!1;if(St&&!At[e]&&b(ft,e));else if(wt&&b(pt,e));else if(!_t[e]||At[e]){if(!(we(t)&&(kt.tagNameCheck instanceof RegExp&&b(kt.tagNameCheck,t)||kt.tagNameCheck instanceof Function&&kt.tagNameCheck(t))&&(kt.attributeNameCheck instanceof RegExp&&b(kt.attributeNameCheck,e)||kt.attributeNameCheck instanceof Function&&kt.attributeNameCheck(e))||"is"===e&&kt.allowCustomizedBuiltInElements&&(kt.tagNameCheck instanceof RegExp&&b(kt.tagNameCheck,i)||kt.tagNameCheck instanceof Function&&kt.tagNameCheck(i))))return!1}else if(Gt[e]);else if(b(xt,m(i,mt,"")));else if("src"!==e&&"xlink:href"!==e&&"href"!==e||"script"===t||0!==y(i,"data:")||!Yt[t])if(Bt&&!b(gt,m(i,mt,"")));else if(i)return!1;return!0},we=function(t){return"annotation-xml"!==t&&g(t,yt)},Se=function(t){ke("beforeSanitizeAttributes",t,null);const{attributes:e}=t;if(!e)return;const r={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:_t};let n=e.length;for(;n--;){const a=e[n],{name:s,namespaceURI:l,value:c}=a,d=ae(s);let f="value"===s?c:x(c);if(r.attrName=d,r.attrValue=f,r.keepAttr=!0,r.forceKeepAttr=void 0,ke("uponSanitizeAttribute",t,r),f=r.attrValue,Mt&&b(/((--!?|])>)|<\/(style|title)/i,f)){xe(s,t);continue}if(r.forceKeepAttr)continue;if(xe(s,t),!r.keepAttr)continue;if(!Ft&&b(/\/>/i,f)){xe(s,t);continue}Lt&&h([ht,ut,dt],(t=>{f=m(f,t," ")}));const p=ae(t.nodeName);if(Ae(p,d,f)){if(!$t||"id"!==d&&"name"!==d||(xe(s,t),f=zt+f),it&&"object"==typeof R&&"function"==typeof R.getAttributeType)if(l);else switch(R.getAttributeType(p,d)){case"TrustedHTML":f=it.createHTML(f);break;case"TrustedScriptURL":f=it.createScriptURL(f)}try{l?t.setAttributeNS(l,s,f):t.setAttribute(s,f),_e(t)?ye(t):u(i.removed)}catch(o){}}}ke("afterSanitizeAttributes",t,null)},Be=function t(e){let i=null;const r=be(e);for(ke("beforeSanitizeShadowDOM",e,null);i=r.nextNode();)ke("uponSanitizeShadowNode",i,null),Te(i)||(i.content instanceof l&&t(i.content),Se(i));ke("afterSanitizeShadowDOM",e,null)};return i.sanitize=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=null,o=null,a=null,s=null;if(te=!t,te&&(t="\x3c!--\x3e"),"string"!=typeof t&&!ve(t)){if("function"!=typeof t.toString)throw _("toString is not a function");if("string"!=typeof(t=t.toString()))throw _("dirty is not a string, aborting")}if(!i.isSupported)return t;if(Nt||he(e),i.removed=[],"string"==typeof t&&(Rt=!1),Rt){if(t.nodeName){const e=ae(t.nodeName);if(!Ct[e]||Tt[e])throw _("root node is forbidden and cannot be sanitized in-place")}}else if(t instanceof v)r=Ce("\x3c!----\x3e"),o=r.ownerDocument.importNode(t,!0),o.nodeType===Z.element&&"BODY"===o.nodeName||"HTML"===o.nodeName?r=o:r.appendChild(o);else{if(!jt&&!Lt&&!Et&&-1===t.indexOf("<"))return it&&Dt?it.createHTML(t):t;if(r=Ce(t),!r)return jt?null:Dt?rt:""}r&&Ot&&ye(r.firstChild);const c=be(Rt?t:r);for(;a=c.nextNode();)Te(a)||(a.content instanceof l&&Be(a.content),Se(a));if(Rt)return t;if(jt){if(It)for(s=at.call(r.ownerDocument);r.firstChild;)s.appendChild(r.firstChild);else s=r;return(_t.shadowroot||_t.shadowrootmode)&&(s=lt.call(n,s,!0)),s}let u=Et?r.outerHTML:r.innerHTML;return Et&&Ct["!doctype"]&&r.ownerDocument&&r.ownerDocument.doctype&&r.ownerDocument.doctype.name&&b(V,r.ownerDocument.doctype.name)&&(u="<!DOCTYPE "+r.ownerDocument.doctype.name+">\n"+u),Lt&&h([ht,ut,dt],(t=>{u=m(u,t," ")})),it&&Dt?it.createHTML(u):u},i.setConfig=function(){he(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),Nt=!0},i.clearConfig=function(){se=null,Nt=!1},i.isValidAttribute=function(t,e,i){se||he({});const r=ae(t),n=ae(e);return Ae(r,n,i)},i.addHook=function(t,e){"function"==typeof e&&(ct[t]=ct[t]||[],d(ct[t],e))},i.removeHook=function(t){if(ct[t])return u(ct[t])},i.removeHooks=function(t){ct[t]&&(ct[t]=[])},i.removeAllHooks=function(){ct={}},i}return K()}()},18426:(t,e)=>{function i(t){let e,i=[];for(let r of t.split(",").map((t=>t.trim())))if(/^-?\d+$/.test(r))i.push(parseInt(r,10));else if(e=r.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[t,r,n,o]=e;if(r&&o){r=parseInt(r),o=parseInt(o);const t=r<o?1:-1;"-"!==n&&".."!==n&&"\u2025"!==n||(o+=t);for(let e=r;e!==o;e+=t)i.push(e)}}return i}e.default=i,t.exports=i},60513:(t,e,i)=>{"use strict";function r(t){for(var e=[],i=1;i<arguments.length;i++)e[i-1]=arguments[i];var r=Array.from("string"==typeof t?[t]:t);r[r.length-1]=r[r.length-1].replace(/\r?\n([\t ]*)$/,"");var n=r.reduce((function(t,e){var i=e.match(/\n([\t ]+|(?!\s).)/g);return i?t.concat(i.map((function(t){var e,i;return null!==(i=null===(e=t.match(/[\t ]/g))||void 0===e?void 0:e.length)&&void 0!==i?i:0}))):t}),[]);if(n.length){var o=new RegExp("\n[\t ]{"+Math.min.apply(Math,n)+"}","g");r=r.map((function(t){return t.replace(o,"\n")}))}r[0]=r[0].replace(/^\r?\n/,"");var a=r[0];return e.forEach((function(t,e){var i=a.match(/(?:^|\n)( *)$/),n=i?i[1]:"",o=t;"string"==typeof t&&t.includes("\n")&&(o=String(t).split("\n").map((function(t,e){return 0===e?t:""+n+t})).join("\n")),a+=o+r[e+1]})),a}i.d(e,{T:()=>r})},28453:(t,e,i)=>{"use strict";i.d(e,{R:()=>a,x:()=>s});var r=i(96540);const n={},o=r.createContext(n);function a(t){const e=r.useContext(o);return r.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(n):t.components||n:a(t.components),r.createElement(o.Provider,{value:e},t.children)}},26312:(t,e,i)=>{"use strict";function r(t,e){let i;if(void 0===e)for(const r of t)null!=r&&(i<r||void 0===i&&r>=r)&&(i=r);else{let r=-1;for(let n of t)null!=(n=e(n,++r,t))&&(i<n||void 0===i&&n>=n)&&(i=n)}return i}function n(t,e){let i;if(void 0===e)for(const r of t)null!=r&&(i>r||void 0===i&&r>=r)&&(i=r);else{let r=-1;for(let n of t)null!=(n=e(n,++r,t))&&(i>n||void 0===i&&n>=n)&&(i=n)}return i}function o(t){return t}i.d(e,{JLW:()=>cs,l78:()=>x,tlR:()=>y,qrM:()=>vs,Yu4:()=>Ts,IA3:()=>ws,Wi0:()=>Bs,PGM:()=>Fs,OEq:()=>Ms,y8u:()=>Os,olC:()=>Is,IrU:()=>qs,oDi:()=>Ps,Q7f:()=>Ws,cVp:()=>Hs,lUB:()=>ds,Lx9:()=>Vs,nVG:()=>el,uxU:()=>il,Xf2:()=>ol,GZz:()=>sl,UPb:()=>cl,dyv:()=>ll,bEH:()=>pr,n8j:()=>gs,T9B:()=>r,jkA:()=>n,rLf:()=>xs,WH:()=>kr,m4Y:()=>mn,UMr:()=>vr,w7C:()=>Na,zt:()=>Oa,Ltv:()=>ja,Ubm:()=>Ia,JWy:()=>Vi,UAC:()=>Nn,DCK:()=>uo,TUC:()=>Rn,Agd:()=>Mn,t6C:()=>Sn,wXd:()=>Fn,ABi:()=>qn,Ui6:()=>Qn,rGn:()=>Wn,ucG:()=>Bn,YPH:()=>Dn,Mol:()=>Pn,PGu:()=>$n,GuW:()=>zn});var a=1,s=2,l=3,c=4,h=1e-6;function u(t){return"translate("+t+",0)"}function d(t){return"translate(0,"+t+")"}function f(t){return e=>+t(e)}function p(t,e){return e=Math.max(0,t.bandwidth()-2*e)/2,t.round()&&(e=Math.round(e)),i=>+t(i)+e}function g(){return!this.__axis}function m(t,e){var i=[],r=null,n=null,m=6,y=6,x=3,C="undefined"!=typeof window&&window.devicePixelRatio>1?0:.5,b=t===a||t===c?-1:1,_=t===c||t===s?"x":"y",v=t===a||t===l?u:d;function k(u){var d=null==r?e.ticks?e.ticks.apply(e,i):e.domain():r,k=null==n?e.tickFormat?e.tickFormat.apply(e,i):o:n,T=Math.max(m,0)+x,A=e.range(),w=+A[0]+C,S=+A[A.length-1]+C,B=(e.bandwidth?p:f)(e.copy(),C),F=u.selection?u.selection():u,L=F.selectAll(".domain").data([null]),M=F.selectAll(".tick").data(d,e).order(),E=M.exit(),N=M.enter().append("g").attr("class","tick"),O=M.select("line"),j=M.select("text");L=L.merge(L.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),M=M.merge(N),O=O.merge(N.append("line").attr("stroke","currentColor").attr(_+"2",b*m)),j=j.merge(N.append("text").attr("fill","currentColor").attr(_,b*T).attr("dy",t===a?"0em":t===l?"0.71em":"0.32em")),u!==F&&(L=L.transition(u),M=M.transition(u),O=O.transition(u),j=j.transition(u),E=E.transition(u).attr("opacity",h).attr("transform",(function(t){return isFinite(t=B(t))?v(t+C):this.getAttribute("transform")})),N.attr("opacity",h).attr("transform",(function(t){var e=this.parentNode.__axis;return v((e&&isFinite(e=e(t))?e:B(t))+C)}))),E.remove(),L.attr("d",t===c||t===s?y?"M"+b*y+","+w+"H"+C+"V"+S+"H"+b*y:"M"+C+","+w+"V"+S:y?"M"+w+","+b*y+"V"+C+"H"+S+"V"+b*y:"M"+w+","+C+"H"+S),M.attr("opacity",1).attr("transform",(function(t){return v(B(t)+C)})),O.attr(_+"2",b*m),j.attr(_,b*T).text(k),F.filter(g).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===s?"start":t===c?"end":"middle"),F.each((function(){this.__axis=B}))}return k.scale=function(t){return arguments.length?(e=t,k):e},k.ticks=function(){return i=Array.from(arguments),k},k.tickArguments=function(t){return arguments.length?(i=null==t?[]:Array.from(t),k):i.slice()},k.tickValues=function(t){return arguments.length?(r=null==t?null:Array.from(t),k):r&&r.slice()},k.tickFormat=function(t){return arguments.length?(n=t,k):n},k.tickSize=function(t){return arguments.length?(m=y=+t,k):m},k.tickSizeInner=function(t){return arguments.length?(m=+t,k):m},k.tickSizeOuter=function(t){return arguments.length?(y=+t,k):y},k.tickPadding=function(t){return arguments.length?(x=+t,k):x},k.offset=function(t){return arguments.length?(C=+t,k):C},k}function y(t){return m(a,t)}function x(t){return m(l,t)}function C(){}function b(t){return null==t?C:function(){return this.querySelector(t)}}function _(t){return null==t?[]:Array.isArray(t)?t:Array.from(t)}function v(){return[]}function k(t){return null==t?v:function(){return this.querySelectorAll(t)}}function T(t){return function(){return this.matches(t)}}function A(t){return function(e){return e.matches(t)}}var w=Array.prototype.find;function S(){return this.firstElementChild}var B=Array.prototype.filter;function F(){return Array.from(this.children)}function L(t){return new Array(t.length)}function M(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}function E(t,e,i,r,n,o){for(var a,s=0,l=e.length,c=o.length;s<c;++s)(a=e[s])?(a.__data__=o[s],r[s]=a):i[s]=new M(t,o[s]);for(;s<l;++s)(a=e[s])&&(n[s]=a)}function N(t,e,i,r,n,o,a){var s,l,c,h=new Map,u=e.length,d=o.length,f=new Array(u);for(s=0;s<u;++s)(l=e[s])&&(f[s]=c=a.call(l,l.__data__,s,e)+"",h.has(c)?n[s]=l:h.set(c,l));for(s=0;s<d;++s)c=a.call(t,o[s],s,o)+"",(l=h.get(c))?(r[s]=l,l.__data__=o[s],h.delete(c)):i[s]=new M(t,o[s]);for(s=0;s<u;++s)(l=e[s])&&h.get(f[s])===l&&(n[s]=l)}function O(t){return t.__data__}function j(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function I(t,e){return t<e?-1:t>e?1:t>=e?0:NaN}M.prototype={constructor:M,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var D="http://www.w3.org/1999/xhtml";const q={svg:"http://www.w3.org/2000/svg",xhtml:D,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function $(t){var e=t+="",i=e.indexOf(":");return i>=0&&"xmlns"!==(e=t.slice(0,i))&&(t=t.slice(i+1)),q.hasOwnProperty(e)?{space:q[e],local:t}:t}function z(t){return function(){this.removeAttribute(t)}}function P(t){return function(){this.removeAttributeNS(t.space,t.local)}}function R(t,e){return function(){this.setAttribute(t,e)}}function W(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function U(t,e){return function(){var i=e.apply(this,arguments);null==i?this.removeAttribute(t):this.setAttribute(t,i)}}function H(t,e){return function(){var i=e.apply(this,arguments);null==i?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,i)}}function Y(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function V(t){return function(){this.style.removeProperty(t)}}function G(t,e,i){return function(){this.style.setProperty(t,e,i)}}function X(t,e,i){return function(){var r=e.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,i)}}function Z(t,e){return t.style.getPropertyValue(e)||Y(t).getComputedStyle(t,null).getPropertyValue(e)}function J(t){return function(){delete this[t]}}function Q(t,e){return function(){this[t]=e}}function K(t,e){return function(){var i=e.apply(this,arguments);null==i?delete this[t]:this[t]=i}}function tt(t){return t.trim().split(/^|\s+/)}function et(t){return t.classList||new it(t)}function it(t){this._node=t,this._names=tt(t.getAttribute("class")||"")}function rt(t,e){for(var i=et(t),r=-1,n=e.length;++r<n;)i.add(e[r])}function nt(t,e){for(var i=et(t),r=-1,n=e.length;++r<n;)i.remove(e[r])}function ot(t){return function(){rt(this,t)}}function at(t){return function(){nt(this,t)}}function st(t,e){return function(){(e.apply(this,arguments)?rt:nt)(this,t)}}function lt(){this.textContent=""}function ct(t){return function(){this.textContent=t}}function ht(t){return function(){var e=t.apply(this,arguments);this.textContent=null==e?"":e}}function ut(){this.innerHTML=""}function dt(t){return function(){this.innerHTML=t}}function ft(t){return function(){var e=t.apply(this,arguments);this.innerHTML=null==e?"":e}}function pt(){this.nextSibling&&this.parentNode.appendChild(this)}function gt(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function mt(t){return function(){var e=this.ownerDocument,i=this.namespaceURI;return i===D&&e.documentElement.namespaceURI===D?e.createElement(t):e.createElementNS(i,t)}}function yt(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function xt(t){var e=$(t);return(e.local?yt:mt)(e)}function Ct(){return null}function bt(){var t=this.parentNode;t&&t.removeChild(this)}function _t(){var t=this.cloneNode(!1),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function vt(){var t=this.cloneNode(!0),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function kt(t){return function(){var e=this.__on;if(e){for(var i,r=0,n=-1,o=e.length;r<o;++r)i=e[r],t.type&&i.type!==t.type||i.name!==t.name?e[++n]=i:this.removeEventListener(i.type,i.listener,i.options);++n?e.length=n:delete this.__on}}}function Tt(t,e,i){return function(){var r,n=this.__on,o=function(t){return function(e){t.call(this,e,this.__data__)}}(e);if(n)for(var a=0,s=n.length;a<s;++a)if((r=n[a]).type===t.type&&r.name===t.name)return this.removeEventListener(r.type,r.listener,r.options),this.addEventListener(r.type,r.listener=o,r.options=i),void(r.value=e);this.addEventListener(t.type,o,i),r={type:t.type,name:t.name,value:e,listener:o,options:i},n?n.push(r):this.__on=[r]}}function At(t,e,i){var r=Y(t),n=r.CustomEvent;"function"==typeof n?n=new n(e,i):(n=r.document.createEvent("Event"),i?(n.initEvent(e,i.bubbles,i.cancelable),n.detail=i.detail):n.initEvent(e,!1,!1)),t.dispatchEvent(n)}function wt(t,e){return function(){return At(this,t,e)}}function St(t,e){return function(){return At(this,t,e.apply(this,arguments))}}it.prototype={add:function(t){this._names.indexOf(t)<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var e=this._names.indexOf(t);e>=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var Bt=[null];function Ft(t,e){this._groups=t,this._parents=e}function Lt(){return new Ft([[document.documentElement]],Bt)}Ft.prototype=Lt.prototype={constructor:Ft,select:function(t){"function"!=typeof t&&(t=b(t));for(var e=this._groups,i=e.length,r=new Array(i),n=0;n<i;++n)for(var o,a,s=e[n],l=s.length,c=r[n]=new Array(l),h=0;h<l;++h)(o=s[h])&&(a=t.call(o,o.__data__,h,s))&&("__data__"in o&&(a.__data__=o.__data__),c[h]=a);return new Ft(r,this._parents)},selectAll:function(t){t="function"==typeof t?function(t){return function(){return _(t.apply(this,arguments))}}(t):k(t);for(var e=this._groups,i=e.length,r=[],n=[],o=0;o<i;++o)for(var a,s=e[o],l=s.length,c=0;c<l;++c)(a=s[c])&&(r.push(t.call(a,a.__data__,c,s)),n.push(a));return new Ft(r,n)},selectChild:function(t){return this.select(null==t?S:function(t){return function(){return w.call(this.children,t)}}("function"==typeof t?t:A(t)))},selectChildren:function(t){return this.selectAll(null==t?F:function(t){return function(){return B.call(this.children,t)}}("function"==typeof t?t:A(t)))},filter:function(t){"function"!=typeof t&&(t=T(t));for(var e=this._groups,i=e.length,r=new Array(i),n=0;n<i;++n)for(var o,a=e[n],s=a.length,l=r[n]=[],c=0;c<s;++c)(o=a[c])&&t.call(o,o.__data__,c,a)&&l.push(o);return new Ft(r,this._parents)},data:function(t,e){if(!arguments.length)return Array.from(this,O);var i,r=e?N:E,n=this._parents,o=this._groups;"function"!=typeof t&&(i=t,t=function(){return i});for(var a=o.length,s=new Array(a),l=new Array(a),c=new Array(a),h=0;h<a;++h){var u=n[h],d=o[h],f=d.length,p=j(t.call(u,u&&u.__data__,h,n)),g=p.length,m=l[h]=new Array(g),y=s[h]=new Array(g);r(u,d,m,y,c[h]=new Array(f),p,e);for(var x,C,b=0,_=0;b<g;++b)if(x=m[b]){for(b>=_&&(_=b+1);!(C=y[_])&&++_<g;);x._next=C||null}}return(s=new Ft(s,n))._enter=l,s._exit=c,s},enter:function(){return new Ft(this._enter||this._groups.map(L),this._parents)},exit:function(){return new Ft(this._exit||this._groups.map(L),this._parents)},join:function(t,e,i){var r=this.enter(),n=this,o=this.exit();return"function"==typeof t?(r=t(r))&&(r=r.selection()):r=r.append(t+""),null!=e&&(n=e(n))&&(n=n.selection()),null==i?o.remove():i(o),r&&n?r.merge(n).order():n},merge:function(t){for(var e=t.selection?t.selection():t,i=this._groups,r=e._groups,n=i.length,o=r.length,a=Math.min(n,o),s=new Array(n),l=0;l<a;++l)for(var c,h=i[l],u=r[l],d=h.length,f=s[l]=new Array(d),p=0;p<d;++p)(c=h[p]||u[p])&&(f[p]=c);for(;l<n;++l)s[l]=i[l];return new Ft(s,this._parents)},selection:function(){return this},order:function(){for(var t=this._groups,e=-1,i=t.length;++e<i;)for(var r,n=t[e],o=n.length-1,a=n[o];--o>=0;)(r=n[o])&&(a&&4^r.compareDocumentPosition(a)&&a.parentNode.insertBefore(r,a),a=r);return this},sort:function(t){function e(e,i){return e&&i?t(e.__data__,i.__data__):!e-!i}t||(t=I);for(var i=this._groups,r=i.length,n=new Array(r),o=0;o<r;++o){for(var a,s=i[o],l=s.length,c=n[o]=new Array(l),h=0;h<l;++h)(a=s[h])&&(c[h]=a);c.sort(e)}return new Ft(n,this._parents).order()},call:function(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this},nodes:function(){return Array.from(this)},node:function(){for(var t=this._groups,e=0,i=t.length;e<i;++e)for(var r=t[e],n=0,o=r.length;n<o;++n){var a=r[n];if(a)return a}return null},size:function(){let t=0;for(const e of this)++t;return t},empty:function(){return!this.node()},each:function(t){for(var e=this._groups,i=0,r=e.length;i<r;++i)for(var n,o=e[i],a=0,s=o.length;a<s;++a)(n=o[a])&&t.call(n,n.__data__,a,o);return this},attr:function(t,e){var i=$(t);if(arguments.length<2){var r=this.node();return i.local?r.getAttributeNS(i.space,i.local):r.getAttribute(i)}return this.each((null==e?i.local?P:z:"function"==typeof e?i.local?H:U:i.local?W:R)(i,e))},style:function(t,e,i){return arguments.length>1?this.each((null==e?V:"function"==typeof e?X:G)(t,e,null==i?"":i)):Z(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?J:"function"==typeof e?K:Q)(t,e)):this.node()[t]},classed:function(t,e){var i=tt(t+"");if(arguments.length<2){for(var r=et(this.node()),n=-1,o=i.length;++n<o;)if(!r.contains(i[n]))return!1;return!0}return this.each(("function"==typeof e?st:e?ot:at)(i,e))},text:function(t){return arguments.length?this.each(null==t?lt:("function"==typeof t?ht:ct)(t)):this.node().textContent},html:function(t){return arguments.length?this.each(null==t?ut:("function"==typeof t?ft:dt)(t)):this.node().innerHTML},raise:function(){return this.each(pt)},lower:function(){return this.each(gt)},append:function(t){var e="function"==typeof t?t:xt(t);return this.select((function(){return this.appendChild(e.apply(this,arguments))}))},insert:function(t,e){var i="function"==typeof t?t:xt(t),r=null==e?Ct:"function"==typeof e?e:b(e);return this.select((function(){return this.insertBefore(i.apply(this,arguments),r.apply(this,arguments)||null)}))},remove:function(){return this.each(bt)},clone:function(t){return this.select(t?vt:_t)},datum:function(t){return arguments.length?this.property("__data__",t):this.node().__data__},on:function(t,e,i){var r,n,o=function(t){return t.trim().split(/^|\s+/).map((function(t){var e="",i=t.indexOf(".");return i>=0&&(e=t.slice(i+1),t=t.slice(0,i)),{type:t,name:e}}))}(t+""),a=o.length;if(!(arguments.length<2)){for(s=e?Tt:kt,r=0;r<a;++r)this.each(s(o[r],e,i));return this}var s=this.node().__on;if(s)for(var l,c=0,h=s.length;c<h;++c)for(r=0,l=s[c];r<a;++r)if((n=o[r]).type===l.type&&n.name===l.name)return l.value},dispatch:function(t,e){return this.each(("function"==typeof e?St:wt)(t,e))},[Symbol.iterator]:function*(){for(var t=this._groups,e=0,i=t.length;e<i;++e)for(var r,n=t[e],o=0,a=n.length;o<a;++o)(r=n[o])&&(yield r)}};const Mt=Lt;var Et={value:()=>{}};function Nt(){for(var t,e=0,i=arguments.length,r={};e<i;++e){if(!(t=arguments[e]+"")||t in r||/[\s.]/.test(t))throw new Error("illegal type: "+t);r[t]=[]}return new Ot(r)}function Ot(t){this._=t}function jt(t,e){for(var i,r=0,n=t.length;r<n;++r)if((i=t[r]).name===e)return i.value}function It(t,e,i){for(var r=0,n=t.length;r<n;++r)if(t[r].name===e){t[r]=Et,t=t.slice(0,r).concat(t.slice(r+1));break}return null!=i&&t.push({name:e,value:i}),t}Ot.prototype=Nt.prototype={constructor:Ot,on:function(t,e){var i,r,n=this._,o=(r=n,(t+"").trim().split(/^|\s+/).map((function(t){var e="",i=t.indexOf(".");if(i>=0&&(e=t.slice(i+1),t=t.slice(0,i)),t&&!r.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:e}}))),a=-1,s=o.length;if(!(arguments.length<2)){if(null!=e&&"function"!=typeof e)throw new Error("invalid callback: "+e);for(;++a<s;)if(i=(t=o[a]).type)n[i]=It(n[i],t.name,e);else if(null==e)for(i in n)n[i]=It(n[i],t.name,null);return this}for(;++a<s;)if((i=(t=o[a]).type)&&(i=jt(n[i],t.name)))return i},copy:function(){var t={},e=this._;for(var i in e)t[i]=e[i].slice();return new Ot(t)},call:function(t,e){if((i=arguments.length-2)>0)for(var i,r,n=new Array(i),o=0;o<i;++o)n[o]=arguments[o+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(o=0,i=(r=this._[t]).length;o<i;++o)r[o].value.apply(e,n)},apply:function(t,e,i){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var r=this._[t],n=0,o=r.length;n<o;++n)r[n].value.apply(e,i)}};const Dt=Nt;var qt,$t,zt=0,Pt=0,Rt=0,Wt=1e3,Ut=0,Ht=0,Yt=0,Vt="object"==typeof performance&&performance.now?performance:Date,Gt="object"==typeof window&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function Xt(){return Ht||(Gt(Zt),Ht=Vt.now()+Yt)}function Zt(){Ht=0}function Jt(){this._call=this._time=this._next=null}function Qt(t,e,i){var r=new Jt;return r.restart(t,e,i),r}function Kt(){Ht=(Ut=Vt.now())+Yt,zt=Pt=0;try{!function(){Xt(),++zt;for(var t,e=qt;e;)(t=Ht-e._time)>=0&&e._call.call(void 0,t),e=e._next;--zt}()}finally{zt=0,function(){var t,e,i=qt,r=1/0;for(;i;)i._call?(r>i._time&&(r=i._time),t=i,i=i._next):(e=i._next,i._next=null,i=t?t._next=e:qt=e);$t=t,ee(r)}(),Ht=0}}function te(){var t=Vt.now(),e=t-Ut;e>Wt&&(Yt-=e,Ut=t)}function ee(t){zt||(Pt&&(Pt=clearTimeout(Pt)),t-Ht>24?(t<1/0&&(Pt=setTimeout(Kt,t-Vt.now()-Yt)),Rt&&(Rt=clearInterval(Rt))):(Rt||(Ut=Vt.now(),Rt=setInterval(te,Wt)),zt=1,Gt(Kt)))}function ie(t,e,i){var r=new Jt;return e=null==e?0:+e,r.restart((i=>{r.stop(),t(i+e)}),e,i),r}Jt.prototype=Qt.prototype={constructor:Jt,restart:function(t,e,i){if("function"!=typeof t)throw new TypeError("callback is not a function");i=(null==i?Xt():+i)+(null==e?0:+e),this._next||$t===this||($t?$t._next=this:qt=this,$t=this),this._call=t,this._time=i,ee()},stop:function(){this._call&&(this._call=null,this._time=1/0,ee())}};var re=Dt("start","end","cancel","interrupt"),ne=[],oe=0,ae=1,se=2,le=3,ce=4,he=5,ue=6;function de(t,e,i,r,n,o){var a=t.__transition;if(a){if(i in a)return}else t.__transition={};!function(t,e,i){var r,n=t.__transition;function o(t){i.state=ae,i.timer.restart(a,i.delay,i.time),i.delay<=t&&a(t-i.delay)}function a(o){var c,h,u,d;if(i.state!==ae)return l();for(c in n)if((d=n[c]).name===i.name){if(d.state===le)return ie(a);d.state===ce?(d.state=ue,d.timer.stop(),d.on.call("interrupt",t,t.__data__,d.index,d.group),delete n[c]):+c<e&&(d.state=ue,d.timer.stop(),d.on.call("cancel",t,t.__data__,d.index,d.group),delete n[c])}if(ie((function(){i.state===le&&(i.state=ce,i.timer.restart(s,i.delay,i.time),s(o))})),i.state=se,i.on.call("start",t,t.__data__,i.index,i.group),i.state===se){for(i.state=le,r=new Array(u=i.tween.length),c=0,h=-1;c<u;++c)(d=i.tween[c].value.call(t,t.__data__,i.index,i.group))&&(r[++h]=d);r.length=h+1}}function s(e){for(var n=e<i.duration?i.ease.call(null,e/i.duration):(i.timer.restart(l),i.state=he,1),o=-1,a=r.length;++o<a;)r[o].call(t,n);i.state===he&&(i.on.call("end",t,t.__data__,i.index,i.group),l())}function l(){for(var r in i.state=ue,i.timer.stop(),delete n[e],n)return;delete t.__transition}n[e]=i,i.timer=Qt(o,0,i.time)}(t,i,{name:e,index:r,group:n,on:re,tween:ne,time:o.time,delay:o.delay,duration:o.duration,ease:o.ease,timer:null,state:oe})}function fe(t,e){var i=ge(t,e);if(i.state>oe)throw new Error("too late; already scheduled");return i}function pe(t,e){var i=ge(t,e);if(i.state>le)throw new Error("too late; already running");return i}function ge(t,e){var i=t.__transition;if(!i||!(i=i[e]))throw new Error("transition not found");return i}function me(t,e){return t=+t,e=+e,function(i){return t*(1-i)+e*i}}var ye,xe=180/Math.PI,Ce={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function be(t,e,i,r,n,o){var a,s,l;return(a=Math.sqrt(t*t+e*e))&&(t/=a,e/=a),(l=t*i+e*r)&&(i-=t*l,r-=e*l),(s=Math.sqrt(i*i+r*r))&&(i/=s,r/=s,l/=s),t*r<e*i&&(t=-t,e=-e,l=-l,a=-a),{translateX:n,translateY:o,rotate:Math.atan2(e,t)*xe,skewX:Math.atan(l)*xe,scaleX:a,scaleY:s}}function _e(t,e,i,r){function n(t){return t.length?t.pop()+" ":""}return function(o,a){var s=[],l=[];return o=t(o),a=t(a),function(t,r,n,o,a,s){if(t!==n||r!==o){var l=a.push("translate(",null,e,null,i);s.push({i:l-4,x:me(t,n)},{i:l-2,x:me(r,o)})}else(n||o)&&a.push("translate("+n+e+o+i)}(o.translateX,o.translateY,a.translateX,a.translateY,s,l),function(t,e,i,o){t!==e?(t-e>180?e+=360:e-t>180&&(t+=360),o.push({i:i.push(n(i)+"rotate(",null,r)-2,x:me(t,e)})):e&&i.push(n(i)+"rotate("+e+r)}(o.rotate,a.rotate,s,l),function(t,e,i,o){t!==e?o.push({i:i.push(n(i)+"skewX(",null,r)-2,x:me(t,e)}):e&&i.push(n(i)+"skewX("+e+r)}(o.skewX,a.skewX,s,l),function(t,e,i,r,o,a){if(t!==i||e!==r){var s=o.push(n(o)+"scale(",null,",",null,")");a.push({i:s-4,x:me(t,i)},{i:s-2,x:me(e,r)})}else 1===i&&1===r||o.push(n(o)+"scale("+i+","+r+")")}(o.scaleX,o.scaleY,a.scaleX,a.scaleY,s,l),o=a=null,function(t){for(var e,i=-1,r=l.length;++i<r;)s[(e=l[i]).i]=e.x(t);return s.join("")}}}var ve=_e((function(t){const e=new("function"==typeof DOMMatrix?DOMMatrix:WebKitCSSMatrix)(t+"");return e.isIdentity?Ce:be(e.a,e.b,e.c,e.d,e.e,e.f)}),"px, ","px)","deg)"),ke=_e((function(t){return null==t?Ce:(ye||(ye=document.createElementNS("http://www.w3.org/2000/svg","g")),ye.setAttribute("transform",t),(t=ye.transform.baseVal.consolidate())?be((t=t.matrix).a,t.b,t.c,t.d,t.e,t.f):Ce)}),", ",")",")");function Te(t,e){var i,r;return function(){var n=pe(this,t),o=n.tween;if(o!==i)for(var a=0,s=(r=i=o).length;a<s;++a)if(r[a].name===e){(r=r.slice()).splice(a,1);break}n.tween=r}}function Ae(t,e,i){var r,n;if("function"!=typeof i)throw new Error;return function(){var o=pe(this,t),a=o.tween;if(a!==r){n=(r=a).slice();for(var s={name:e,value:i},l=0,c=n.length;l<c;++l)if(n[l].name===e){n[l]=s;break}l===c&&n.push(s)}o.tween=n}}function we(t,e,i){var r=t._id;return t.each((function(){var t=pe(this,r);(t.value||(t.value={}))[e]=i.apply(this,arguments)})),function(t){return ge(t,r).value[e]}}function Se(t,e,i){t.prototype=e.prototype=i,i.constructor=t}function Be(t,e){var i=Object.create(t.prototype);for(var r in e)i[r]=e[r];return i}function Fe(){}var Le=.7,Me=1/Le,Ee="\\s*([+-]?\\d+)\\s*",Ne="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",Oe="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",je=/^#([0-9a-f]{3,8})$/,Ie=new RegExp(`^rgb\\(${Ee},${Ee},${Ee}\\)$`),De=new RegExp(`^rgb\\(${Oe},${Oe},${Oe}\\)$`),qe=new RegExp(`^rgba\\(${Ee},${Ee},${Ee},${Ne}\\)$`),$e=new RegExp(`^rgba\\(${Oe},${Oe},${Oe},${Ne}\\)$`),ze=new RegExp(`^hsl\\(${Ne},${Oe},${Oe}\\)$`),Pe=new RegExp(`^hsla\\(${Ne},${Oe},${Oe},${Ne}\\)$`),Re={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};function We(){return this.rgb().formatHex()}function Ue(){return this.rgb().formatRgb()}function He(t){var e,i;return t=(t+"").trim().toLowerCase(),(e=je.exec(t))?(i=e[1].length,e=parseInt(e[1],16),6===i?Ye(e):3===i?new Ze(e>>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===i?Ve(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===i?Ve(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=Ie.exec(t))?new Ze(e[1],e[2],e[3],1):(e=De.exec(t))?new Ze(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=qe.exec(t))?Ve(e[1],e[2],e[3],e[4]):(e=$e.exec(t))?Ve(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=ze.exec(t))?ii(e[1],e[2]/100,e[3]/100,1):(e=Pe.exec(t))?ii(e[1],e[2]/100,e[3]/100,e[4]):Re.hasOwnProperty(t)?Ye(Re[t]):"transparent"===t?new Ze(NaN,NaN,NaN,0):null}function Ye(t){return new Ze(t>>16&255,t>>8&255,255&t,1)}function Ve(t,e,i,r){return r<=0&&(t=e=i=NaN),new Ze(t,e,i,r)}function Ge(t){return t instanceof Fe||(t=He(t)),t?new Ze((t=t.rgb()).r,t.g,t.b,t.opacity):new Ze}function Xe(t,e,i,r){return 1===arguments.length?Ge(t):new Ze(t,e,i,null==r?1:r)}function Ze(t,e,i,r){this.r=+t,this.g=+e,this.b=+i,this.opacity=+r}function Je(){return`#${ei(this.r)}${ei(this.g)}${ei(this.b)}`}function Qe(){const t=Ke(this.opacity);return`${1===t?"rgb(":"rgba("}${ti(this.r)}, ${ti(this.g)}, ${ti(this.b)}${1===t?")":`, ${t})`}`}function Ke(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function ti(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function ei(t){return((t=ti(t))<16?"0":"")+t.toString(16)}function ii(t,e,i,r){return r<=0?t=e=i=NaN:i<=0||i>=1?t=e=NaN:e<=0&&(t=NaN),new ni(t,e,i,r)}function ri(t){if(t instanceof ni)return new ni(t.h,t.s,t.l,t.opacity);if(t instanceof Fe||(t=He(t)),!t)return new ni;if(t instanceof ni)return t;var e=(t=t.rgb()).r/255,i=t.g/255,r=t.b/255,n=Math.min(e,i,r),o=Math.max(e,i,r),a=NaN,s=o-n,l=(o+n)/2;return s?(a=e===o?(i-r)/s+6*(i<r):i===o?(r-e)/s+2:(e-i)/s+4,s/=l<.5?o+n:2-o-n,a*=60):s=l>0&&l<1?0:a,new ni(a,s,l,t.opacity)}function ni(t,e,i,r){this.h=+t,this.s=+e,this.l=+i,this.opacity=+r}function oi(t){return(t=(t||0)%360)<0?t+360:t}function ai(t){return Math.max(0,Math.min(1,t||0))}function si(t,e,i){return 255*(t<60?e+(i-e)*t/60:t<180?i:t<240?e+(i-e)*(240-t)/60:e)}function li(t,e,i,r,n){var o=t*t,a=o*t;return((1-3*t+3*o-a)*e+(4-6*o+3*a)*i+(1+3*t+3*o-3*a)*r+a*n)/6}Se(Fe,He,{copy(t){return Object.assign(new this.constructor,this,t)},displayable(){return this.rgb().displayable()},hex:We,formatHex:We,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return ri(this).formatHsl()},formatRgb:Ue,toString:Ue}),Se(Ze,Xe,Be(Fe,{brighter(t){return t=null==t?Me:Math.pow(Me,t),new Ze(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=null==t?Le:Math.pow(Le,t),new Ze(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Ze(ti(this.r),ti(this.g),ti(this.b),Ke(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Je,formatHex:Je,formatHex8:function(){return`#${ei(this.r)}${ei(this.g)}${ei(this.b)}${ei(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Qe,toString:Qe})),Se(ni,(function(t,e,i,r){return 1===arguments.length?ri(t):new ni(t,e,i,null==r?1:r)}),Be(Fe,{brighter(t){return t=null==t?Me:Math.pow(Me,t),new ni(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=null==t?Le:Math.pow(Le,t),new ni(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,i=this.l,r=i+(i<.5?i:1-i)*e,n=2*i-r;return new Ze(si(t>=240?t-240:t+120,n,r),si(t,n,r),si(t<120?t+240:t-120,n,r),this.opacity)},clamp(){return new ni(oi(this.h),ai(this.s),ai(this.l),Ke(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=Ke(this.opacity);return`${1===t?"hsl(":"hsla("}${oi(this.h)}, ${100*ai(this.s)}%, ${100*ai(this.l)}%${1===t?")":`, ${t})`}`}}));const ci=t=>()=>t;function hi(t,e){return function(i){return t+i*e}}function ui(t){return 1==(t=+t)?di:function(e,i){return i-e?function(t,e,i){return t=Math.pow(t,i),e=Math.pow(e,i)-t,i=1/i,function(r){return Math.pow(t+r*e,i)}}(e,i,t):ci(isNaN(e)?i:e)}}function di(t,e){var i=e-t;return i?hi(t,i):ci(isNaN(t)?e:t)}const fi=function t(e){var i=ui(e);function r(t,e){var r=i((t=Xe(t)).r,(e=Xe(e)).r),n=i(t.g,e.g),o=i(t.b,e.b),a=di(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=n(e),t.b=o(e),t.opacity=a(e),t+""}}return r.gamma=t,r}(1);function pi(t){return function(e){var i,r,n=e.length,o=new Array(n),a=new Array(n),s=new Array(n);for(i=0;i<n;++i)r=Xe(e[i]),o[i]=r.r||0,a[i]=r.g||0,s[i]=r.b||0;return o=t(o),a=t(a),s=t(s),r.opacity=1,function(t){return r.r=o(t),r.g=a(t),r.b=s(t),r+""}}}pi((function(t){var e=t.length-1;return function(i){var r=i<=0?i=0:i>=1?(i=1,e-1):Math.floor(i*e),n=t[r],o=t[r+1],a=r>0?t[r-1]:2*n-o,s=r<e-1?t[r+2]:2*o-n;return li((i-r/e)*e,a,n,o,s)}})),pi((function(t){var e=t.length;return function(i){var r=Math.floor(((i%=1)<0?++i:i)*e),n=t[(r+e-1)%e],o=t[r%e],a=t[(r+1)%e],s=t[(r+2)%e];return li((i-r/e)*e,n,o,a,s)}}));var gi=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,mi=new RegExp(gi.source,"g");function yi(t,e){var i,r,n,o=gi.lastIndex=mi.lastIndex=0,a=-1,s=[],l=[];for(t+="",e+="";(i=gi.exec(t))&&(r=mi.exec(e));)(n=r.index)>o&&(n=e.slice(o,n),s[a]?s[a]+=n:s[++a]=n),(i=i[0])===(r=r[0])?s[a]?s[a]+=r:s[++a]=r:(s[++a]=null,l.push({i:a,x:me(i,r)})),o=mi.lastIndex;return o<e.length&&(n=e.slice(o),s[a]?s[a]+=n:s[++a]=n),s.length<2?l[0]?function(t){return function(e){return t(e)+""}}(l[0].x):function(t){return function(){return t}}(e):(e=l.length,function(t){for(var i,r=0;r<e;++r)s[(i=l[r]).i]=i.x(t);return s.join("")})}function xi(t,e){var i;return("number"==typeof e?me:e instanceof He?fi:(i=He(e))?(e=i,fi):yi)(t,e)}function Ci(t){return function(){this.removeAttribute(t)}}function bi(t){return function(){this.removeAttributeNS(t.space,t.local)}}function _i(t,e,i){var r,n,o=i+"";return function(){var a=this.getAttribute(t);return a===o?null:a===r?n:n=e(r=a,i)}}function vi(t,e,i){var r,n,o=i+"";return function(){var a=this.getAttributeNS(t.space,t.local);return a===o?null:a===r?n:n=e(r=a,i)}}function ki(t,e,i){var r,n,o;return function(){var a,s,l=i(this);if(null!=l)return(a=this.getAttribute(t))===(s=l+"")?null:a===r&&s===n?o:(n=s,o=e(r=a,l));this.removeAttribute(t)}}function Ti(t,e,i){var r,n,o;return function(){var a,s,l=i(this);if(null!=l)return(a=this.getAttributeNS(t.space,t.local))===(s=l+"")?null:a===r&&s===n?o:(n=s,o=e(r=a,l));this.removeAttributeNS(t.space,t.local)}}function Ai(t,e){var i,r;function n(){var n=e.apply(this,arguments);return n!==r&&(i=(r=n)&&function(t,e){return function(i){this.setAttributeNS(t.space,t.local,e.call(this,i))}}(t,n)),i}return n._value=e,n}function wi(t,e){var i,r;function n(){var n=e.apply(this,arguments);return n!==r&&(i=(r=n)&&function(t,e){return function(i){this.setAttribute(t,e.call(this,i))}}(t,n)),i}return n._value=e,n}function Si(t,e){return function(){fe(this,t).delay=+e.apply(this,arguments)}}function Bi(t,e){return e=+e,function(){fe(this,t).delay=e}}function Fi(t,e){return function(){pe(this,t).duration=+e.apply(this,arguments)}}function Li(t,e){return e=+e,function(){pe(this,t).duration=e}}var Mi=Mt.prototype.constructor;function Ei(t){return function(){this.style.removeProperty(t)}}var Ni=0;function Oi(t,e,i,r){this._groups=t,this._parents=e,this._name=i,this._id=r}function ji(){return++Ni}var Ii=Mt.prototype;Oi.prototype=function(t){return Mt().transition(t)}.prototype={constructor:Oi,select:function(t){var e=this._name,i=this._id;"function"!=typeof t&&(t=b(t));for(var r=this._groups,n=r.length,o=new Array(n),a=0;a<n;++a)for(var s,l,c=r[a],h=c.length,u=o[a]=new Array(h),d=0;d<h;++d)(s=c[d])&&(l=t.call(s,s.__data__,d,c))&&("__data__"in s&&(l.__data__=s.__data__),u[d]=l,de(u[d],e,i,d,u,ge(s,i)));return new Oi(o,this._parents,e,i)},selectAll:function(t){var e=this._name,i=this._id;"function"!=typeof t&&(t=k(t));for(var r=this._groups,n=r.length,o=[],a=[],s=0;s<n;++s)for(var l,c=r[s],h=c.length,u=0;u<h;++u)if(l=c[u]){for(var d,f=t.call(l,l.__data__,u,c),p=ge(l,i),g=0,m=f.length;g<m;++g)(d=f[g])&&de(d,e,i,g,f,p);o.push(f),a.push(l)}return new Oi(o,a,e,i)},selectChild:Ii.selectChild,selectChildren:Ii.selectChildren,filter:function(t){"function"!=typeof t&&(t=T(t));for(var e=this._groups,i=e.length,r=new Array(i),n=0;n<i;++n)for(var o,a=e[n],s=a.length,l=r[n]=[],c=0;c<s;++c)(o=a[c])&&t.call(o,o.__data__,c,a)&&l.push(o);return new Oi(r,this._parents,this._name,this._id)},merge:function(t){if(t._id!==this._id)throw new Error;for(var e=this._groups,i=t._groups,r=e.length,n=i.length,o=Math.min(r,n),a=new Array(r),s=0;s<o;++s)for(var l,c=e[s],h=i[s],u=c.length,d=a[s]=new Array(u),f=0;f<u;++f)(l=c[f]||h[f])&&(d[f]=l);for(;s<r;++s)a[s]=e[s];return new Oi(a,this._parents,this._name,this._id)},selection:function(){return new Mi(this._groups,this._parents)},transition:function(){for(var t=this._name,e=this._id,i=ji(),r=this._groups,n=r.length,o=0;o<n;++o)for(var a,s=r[o],l=s.length,c=0;c<l;++c)if(a=s[c]){var h=ge(a,e);de(a,t,i,c,s,{time:h.time+h.delay+h.duration,delay:0,duration:h.duration,ease:h.ease})}return new Oi(r,this._parents,t,i)},call:Ii.call,nodes:Ii.nodes,node:Ii.node,size:Ii.size,empty:Ii.empty,each:Ii.each,on:function(t,e){var i=this._id;return arguments.length<2?ge(this.node(),i).on.on(t):this.each(function(t,e,i){var r,n,o=function(t){return(t+"").trim().split(/^|\s+/).every((function(t){var e=t.indexOf(".");return e>=0&&(t=t.slice(0,e)),!t||"start"===t}))}(e)?fe:pe;return function(){var a=o(this,t),s=a.on;s!==r&&(n=(r=s).copy()).on(e,i),a.on=n}}(i,t,e))},attr:function(t,e){var i=$(t),r="transform"===i?ke:xi;return this.attrTween(t,"function"==typeof e?(i.local?Ti:ki)(i,r,we(this,"attr."+t,e)):null==e?(i.local?bi:Ci)(i):(i.local?vi:_i)(i,r,e))},attrTween:function(t,e){var i="attr."+t;if(arguments.length<2)return(i=this.tween(i))&&i._value;if(null==e)return this.tween(i,null);if("function"!=typeof e)throw new Error;var r=$(t);return this.tween(i,(r.local?Ai:wi)(r,e))},style:function(t,e,i){var r="transform"==(t+="")?ve:xi;return null==e?this.styleTween(t,function(t,e){var i,r,n;return function(){var o=Z(this,t),a=(this.style.removeProperty(t),Z(this,t));return o===a?null:o===i&&a===r?n:n=e(i=o,r=a)}}(t,r)).on("end.style."+t,Ei(t)):"function"==typeof e?this.styleTween(t,function(t,e,i){var r,n,o;return function(){var a=Z(this,t),s=i(this),l=s+"";return null==s&&(this.style.removeProperty(t),l=s=Z(this,t)),a===l?null:a===r&&l===n?o:(n=l,o=e(r=a,s))}}(t,r,we(this,"style."+t,e))).each(function(t,e){var i,r,n,o,a="style."+e,s="end."+a;return function(){var l=pe(this,t),c=l.on,h=null==l.value[a]?o||(o=Ei(e)):void 0;c===i&&n===h||(r=(i=c).copy()).on(s,n=h),l.on=r}}(this._id,t)):this.styleTween(t,function(t,e,i){var r,n,o=i+"";return function(){var a=Z(this,t);return a===o?null:a===r?n:n=e(r=a,i)}}(t,r,e),i).on("end.style."+t,null)},styleTween:function(t,e,i){var r="style."+(t+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==e)return this.tween(r,null);if("function"!=typeof e)throw new Error;return this.tween(r,function(t,e,i){var r,n;function o(){var o=e.apply(this,arguments);return o!==n&&(r=(n=o)&&function(t,e,i){return function(r){this.style.setProperty(t,e.call(this,r),i)}}(t,o,i)),r}return o._value=e,o}(t,e,null==i?"":i))},text:function(t){return this.tween("text","function"==typeof t?function(t){return function(){var e=t(this);this.textContent=null==e?"":e}}(we(this,"text",t)):function(t){return function(){this.textContent=t}}(null==t?"":t+""))},textTween:function(t){var e="text";if(arguments.length<1)return(e=this.tween(e))&&e._value;if(null==t)return this.tween(e,null);if("function"!=typeof t)throw new Error;return this.tween(e,function(t){var e,i;function r(){var r=t.apply(this,arguments);return r!==i&&(e=(i=r)&&function(t){return function(e){this.textContent=t.call(this,e)}}(r)),e}return r._value=t,r}(t))},remove:function(){return this.on("end.remove",function(t){return function(){var e=this.parentNode;for(var i in this.__transition)if(+i!==t)return;e&&e.removeChild(this)}}(this._id))},tween:function(t,e){var i=this._id;if(t+="",arguments.length<2){for(var r,n=ge(this.node(),i).tween,o=0,a=n.length;o<a;++o)if((r=n[o]).name===t)return r.value;return null}return this.each((null==e?Te:Ae)(i,t,e))},delay:function(t){var e=this._id;return arguments.length?this.each(("function"==typeof t?Si:Bi)(e,t)):ge(this.node(),e).delay},duration:function(t){var e=this._id;return arguments.length?this.each(("function"==typeof t?Fi:Li)(e,t)):ge(this.node(),e).duration},ease:function(t){var e=this._id;return arguments.length?this.each(function(t,e){if("function"!=typeof e)throw new Error;return function(){pe(this,t).ease=e}}(e,t)):ge(this.node(),e).ease},easeVarying:function(t){if("function"!=typeof t)throw new Error;return this.each(function(t,e){return function(){var i=e.apply(this,arguments);if("function"!=typeof i)throw new Error;pe(this,t).ease=i}}(this._id,t))},end:function(){var t,e,i=this,r=i._id,n=i.size();return new Promise((function(o,a){var s={value:a},l={value:function(){0==--n&&o()}};i.each((function(){var i=pe(this,r),n=i.on;n!==t&&((e=(t=n).copy())._.cancel.push(s),e._.interrupt.push(s),e._.end.push(l)),i.on=e})),0===n&&o()}))},[Symbol.iterator]:Ii[Symbol.iterator]};var Di={time:null,delay:0,duration:250,ease:function(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}};function qi(t,e){for(var i;!(i=t.__transition)||!(i=i[e]);)if(!(t=t.parentNode))throw new Error(`transition ${e} not found`);return i}Mt.prototype.interrupt=function(t){return this.each((function(){!function(t,e){var i,r,n,o=t.__transition,a=!0;if(o){for(n in e=null==e?null:e+"",o)(i=o[n]).name===e?(r=i.state>se&&i.state<he,i.state=ue,i.timer.stop(),i.on.call(r?"interrupt":"cancel",t,t.__data__,i.index,i.group),delete o[n]):a=!1;a&&delete t.__transition}}(this,t)}))},Mt.prototype.transition=function(t){var e,i;t instanceof Oi?(e=t._id,t=t._name):(e=ji(),(i=Di).time=Xt(),t=null==t?null:t+"");for(var r=this._groups,n=r.length,o=0;o<n;++o)for(var a,s=r[o],l=s.length,c=0;c<l;++c)(a=s[c])&&de(a,t,e,c,s,i||qi(a,e));return new Oi(r,this._parents,t,e)};const{abs:$i,max:zi,min:Pi}=Math;function Ri(t){return[+t[0],+t[1]]}function Wi(t){return[Ri(t[0]),Ri(t[1])]}["w","e"].map(Ui),["n","s"].map(Ui),["n","w","e","s","nw","ne","sw","se"].map(Ui);function Ui(t){return{type:t}}function Hi(t){if(!t.ok)throw new Error(t.status+" "+t.statusText);return t.text()}function Yi(t){return(e,i)=>function(t,e){return fetch(t,e).then(Hi)}(e,i).then((e=>(new DOMParser).parseFromString(e,t)))}Yi("application/xml");Yi("text/html");var Vi=Yi("image/svg+xml");const Gi=Math.PI/180,Xi=180/Math.PI,Zi=.96422,Ji=1,Qi=.82521,Ki=4/29,tr=6/29,er=3*tr*tr,ir=tr*tr*tr;function rr(t){if(t instanceof nr)return new nr(t.l,t.a,t.b,t.opacity);if(t instanceof ur)return dr(t);t instanceof Ze||(t=Ge(t));var e,i,r=lr(t.r),n=lr(t.g),o=lr(t.b),a=or((.2225045*r+.7168786*n+.0606169*o)/Ji);return r===n&&n===o?e=i=a:(e=or((.4360747*r+.3850649*n+.1430804*o)/Zi),i=or((.0139322*r+.0971045*n+.7141733*o)/Qi)),new nr(116*a-16,500*(e-a),200*(a-i),t.opacity)}function nr(t,e,i,r){this.l=+t,this.a=+e,this.b=+i,this.opacity=+r}function or(t){return t>ir?Math.pow(t,1/3):t/er+Ki}function ar(t){return t>tr?t*t*t:er*(t-Ki)}function sr(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function lr(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function cr(t){if(t instanceof ur)return new ur(t.h,t.c,t.l,t.opacity);if(t instanceof nr||(t=rr(t)),0===t.a&&0===t.b)return new ur(NaN,0<t.l&&t.l<100?0:NaN,t.l,t.opacity);var e=Math.atan2(t.b,t.a)*Xi;return new ur(e<0?e+360:e,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}function hr(t,e,i,r){return 1===arguments.length?cr(t):new ur(t,e,i,null==r?1:r)}function ur(t,e,i,r){this.h=+t,this.c=+e,this.l=+i,this.opacity=+r}function dr(t){if(isNaN(t.h))return new nr(t.l,0,0,t.opacity);var e=t.h*Gi;return new nr(t.l,Math.cos(e)*t.c,Math.sin(e)*t.c,t.opacity)}function fr(t){return function(e,i){var r=t((e=hr(e)).h,(i=hr(i)).h),n=di(e.c,i.c),o=di(e.l,i.l),a=di(e.opacity,i.opacity);return function(t){return e.h=r(t),e.c=n(t),e.l=o(t),e.opacity=a(t),e+""}}}Se(nr,(function(t,e,i,r){return 1===arguments.length?rr(t):new nr(t,e,i,null==r?1:r)}),Be(Fe,{brighter(t){return new nr(this.l+18*(null==t?1:t),this.a,this.b,this.opacity)},darker(t){return new nr(this.l-18*(null==t?1:t),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,i=isNaN(this.b)?t:t-this.b/200;return new Ze(sr(3.1338561*(e=Zi*ar(e))-1.6168667*(t=Ji*ar(t))-.4906146*(i=Qi*ar(i))),sr(-.9787684*e+1.9161415*t+.033454*i),sr(.0719453*e-.2289914*t+1.4052427*i),this.opacity)}})),Se(ur,hr,Be(Fe,{brighter(t){return new ur(this.h,this.c,this.l+18*(null==t?1:t),this.opacity)},darker(t){return new ur(this.h,this.c,this.l-18*(null==t?1:t),this.opacity)},rgb(){return dr(this).rgb()}}));const pr=fr((function(t,e){var i=e-t;return i?hi(t,i>180||i<-180?i-360*Math.round(i/360):i):ci(isNaN(t)?e:t)}));fr(di);function gr(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t)}return this}class mr extends Map{constructor(t,e=br){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:e}}),null!=t)for(const[i,r]of t)this.set(i,r)}get(t){return super.get(yr(this,t))}has(t){return super.has(yr(this,t))}set(t,e){return super.set(xr(this,t),e)}delete(t){return super.delete(Cr(this,t))}}Set;function yr({_intern:t,_key:e},i){const r=e(i);return t.has(r)?t.get(r):i}function xr({_intern:t,_key:e},i){const r=e(i);return t.has(r)?t.get(r):(t.set(r,i),i)}function Cr({_intern:t,_key:e},i){const r=e(i);return t.has(r)&&(i=t.get(r),t.delete(r)),i}function br(t){return null!==t&&"object"==typeof t?t.valueOf():t}const _r=Symbol("implicit");function vr(){var t=new mr,e=[],i=[],r=_r;function n(n){let o=t.get(n);if(void 0===o){if(r!==_r)return r;t.set(n,o=e.push(n)-1)}return i[o%i.length]}return n.domain=function(i){if(!arguments.length)return e.slice();e=[],t=new mr;for(const r of i)t.has(r)||t.set(r,e.push(r)-1);return n},n.range=function(t){return arguments.length?(i=Array.from(t),n):i.slice()},n.unknown=function(t){return arguments.length?(r=t,n):r},n.copy=function(){return vr(e,i).unknown(r)},gr.apply(n,arguments),n}function kr(){var t,e,i=vr().unknown(void 0),r=i.domain,n=i.range,o=0,a=1,s=!1,l=0,c=0,h=.5;function u(){var i=r().length,u=a<o,d=u?a:o,f=u?o:a;t=(f-d)/Math.max(1,i-l+2*c),s&&(t=Math.floor(t)),d+=(f-d-t*(i-l))*h,e=t*(1-l),s&&(d=Math.round(d),e=Math.round(e));var p=function(t,e,i){t=+t,e=+e,i=(n=arguments.length)<2?(e=t,t=0,1):n<3?1:+i;for(var r=-1,n=0|Math.max(0,Math.ceil((e-t)/i)),o=new Array(n);++r<n;)o[r]=t+r*i;return o}(i).map((function(e){return d+t*e}));return n(u?p.reverse():p)}return delete i.unknown,i.domain=function(t){return arguments.length?(r(t),u()):r()},i.range=function(t){return arguments.length?([o,a]=t,o=+o,a=+a,u()):[o,a]},i.rangeRound=function(t){return[o,a]=t,o=+o,a=+a,s=!0,u()},i.bandwidth=function(){return e},i.step=function(){return t},i.round=function(t){return arguments.length?(s=!!t,u()):s},i.padding=function(t){return arguments.length?(l=Math.min(1,c=+t),u()):l},i.paddingInner=function(t){return arguments.length?(l=Math.min(1,t),u()):l},i.paddingOuter=function(t){return arguments.length?(c=+t,u()):c},i.align=function(t){return arguments.length?(h=Math.max(0,Math.min(1,t)),u()):h},i.copy=function(){return kr(r(),[o,a]).round(s).paddingInner(l).paddingOuter(c).align(h)},gr.apply(u(),arguments)}const Tr=Math.sqrt(50),Ar=Math.sqrt(10),wr=Math.sqrt(2);function Sr(t,e,i){const r=(e-t)/Math.max(0,i),n=Math.floor(Math.log10(r)),o=r/Math.pow(10,n),a=o>=Tr?10:o>=Ar?5:o>=wr?2:1;let s,l,c;return n<0?(c=Math.pow(10,-n)/a,s=Math.round(t*c),l=Math.round(e*c),s/c<t&&++s,l/c>e&&--l,c=-c):(c=Math.pow(10,n)*a,s=Math.round(t/c),l=Math.round(e/c),s*c<t&&++s,l*c>e&&--l),l<s&&.5<=i&&i<2?Sr(t,e,2*i):[s,l,c]}function Br(t,e,i){return Sr(t=+t,e=+e,i=+i)[2]}function Fr(t,e,i){i=+i;const r=(e=+e)<(t=+t),n=r?Br(e,t,i):Br(t,e,i);return(r?-1:1)*(n<0?1/-n:n)}function Lr(t,e){return null==t||null==e?NaN:t<e?-1:t>e?1:t>=e?0:NaN}function Mr(t,e){return null==t||null==e?NaN:e<t?-1:e>t?1:e>=t?0:NaN}function Er(t){let e,i,r;function n(t,r,n=0,o=t.length){if(n<o){if(0!==e(r,r))return o;do{const e=n+o>>>1;i(t[e],r)<0?n=e+1:o=e}while(n<o)}return n}return 2!==t.length?(e=Lr,i=(e,i)=>Lr(t(e),i),r=(e,i)=>t(e)-i):(e=t===Lr||t===Mr?t:Nr,i=t,r=t),{left:n,center:function(t,e,i=0,o=t.length){const a=n(t,e,i,o-1);return a>i&&r(t[a-1],e)>-r(t[a],e)?a-1:a},right:function(t,r,n=0,o=t.length){if(n<o){if(0!==e(r,r))return o;do{const e=n+o>>>1;i(t[e],r)<=0?n=e+1:o=e}while(n<o)}return n}}}function Nr(){return 0}const Or=Er(Lr),jr=Or.right,Ir=(Or.left,Er((function(t){return null===t?NaN:+t})).center,jr);function Dr(t,e){var i,r=e?e.length:0,n=t?Math.min(r,t.length):0,o=new Array(n),a=new Array(r);for(i=0;i<n;++i)o[i]=Pr(t[i],e[i]);for(;i<r;++i)a[i]=e[i];return function(t){for(i=0;i<n;++i)a[i]=o[i](t);return a}}function qr(t,e){var i=new Date;return t=+t,e=+e,function(r){return i.setTime(t*(1-r)+e*r),i}}function $r(t,e){var i,r={},n={};for(i in null!==t&&"object"==typeof t||(t={}),null!==e&&"object"==typeof e||(e={}),e)i in t?r[i]=Pr(t[i],e[i]):n[i]=e[i];return function(t){for(i in r)n[i]=r[i](t);return n}}function zr(t,e){e||(e=[]);var i,r=t?Math.min(e.length,t.length):0,n=e.slice();return function(o){for(i=0;i<r;++i)n[i]=t[i]*(1-o)+e[i]*o;return n}}function Pr(t,e){var i,r,n=typeof e;return null==e||"boolean"===n?ci(e):("number"===n?me:"string"===n?(i=He(e))?(e=i,fi):yi:e instanceof He?fi:e instanceof Date?qr:(r=e,!ArrayBuffer.isView(r)||r instanceof DataView?Array.isArray(e)?Dr:"function"!=typeof e.valueOf&&"function"!=typeof e.toString||isNaN(e)?$r:me:zr))(t,e)}function Rr(t,e){return t=+t,e=+e,function(i){return Math.round(t*(1-i)+e*i)}}function Wr(t){return+t}var Ur=[0,1];function Hr(t){return t}function Yr(t,e){return(e-=t=+t)?function(i){return(i-t)/e}:(i=isNaN(e)?NaN:.5,function(){return i});var i}function Vr(t,e,i){var r=t[0],n=t[1],o=e[0],a=e[1];return n<r?(r=Yr(n,r),o=i(a,o)):(r=Yr(r,n),o=i(o,a)),function(t){return o(r(t))}}function Gr(t,e,i){var r=Math.min(t.length,e.length)-1,n=new Array(r),o=new Array(r),a=-1;for(t[r]<t[0]&&(t=t.slice().reverse(),e=e.slice().reverse());++a<r;)n[a]=Yr(t[a],t[a+1]),o[a]=i(e[a],e[a+1]);return function(e){var i=Ir(t,e,1,r)-1;return o[i](n[i](e))}}function Xr(t,e){return e.domain(t.domain()).range(t.range()).interpolate(t.interpolate()).clamp(t.clamp()).unknown(t.unknown())}function Zr(){var t,e,i,r,n,o,a=Ur,s=Ur,l=Pr,c=Hr;function h(){var t,e,i,l=Math.min(a.length,s.length);return c!==Hr&&(t=a[0],e=a[l-1],t>e&&(i=t,t=e,e=i),c=function(i){return Math.max(t,Math.min(e,i))}),r=l>2?Gr:Vr,n=o=null,u}function u(e){return null==e||isNaN(e=+e)?i:(n||(n=r(a.map(t),s,l)))(t(c(e)))}return u.invert=function(i){return c(e((o||(o=r(s,a.map(t),me)))(i)))},u.domain=function(t){return arguments.length?(a=Array.from(t,Wr),h()):a.slice()},u.range=function(t){return arguments.length?(s=Array.from(t),h()):s.slice()},u.rangeRound=function(t){return s=Array.from(t),l=Rr,h()},u.clamp=function(t){return arguments.length?(c=!!t||Hr,h()):c!==Hr},u.interpolate=function(t){return arguments.length?(l=t,h()):l},u.unknown=function(t){return arguments.length?(i=t,u):i},function(i,r){return t=i,e=r,h()}}function Jr(){return Zr()(Hr,Hr)}var Qr,Kr=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function tn(t){if(!(e=Kr.exec(t)))throw new Error("invalid format: "+t);var e;return new en({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function en(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function rn(t,e){if((i=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var i,r=t.slice(0,i);return[r.length>1?r[0]+r.slice(2):r,+t.slice(i+1)]}function nn(t){return(t=rn(Math.abs(t)))?t[1]:NaN}function on(t,e){var i=rn(t,e);if(!i)return t+"";var r=i[0],n=i[1];return n<0?"0."+new Array(-n).join("0")+r:r.length>n+1?r.slice(0,n+1)+"."+r.slice(n+1):r+new Array(n-r.length+2).join("0")}tn.prototype=en.prototype,en.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const an={"%":(t,e)=>(100*t).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:function(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)},e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>on(100*t,e),r:on,s:function(t,e){var i=rn(t,e);if(!i)return t+"";var r=i[0],n=i[1],o=n-(Qr=3*Math.max(-8,Math.min(8,Math.floor(n/3))))+1,a=r.length;return o===a?r:o>a?r+new Array(o-a+1).join("0"):o>0?r.slice(0,o)+"."+r.slice(o):"0."+new Array(1-o).join("0")+rn(t,Math.max(0,e+o-1))[0]},X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function sn(t){return t}var ln,cn,hn,un=Array.prototype.map,dn=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"];function fn(t){var e,i,r=void 0===t.grouping||void 0===t.thousands?sn:(e=un.call(t.grouping,Number),i=t.thousands+"",function(t,r){for(var n=t.length,o=[],a=0,s=e[0],l=0;n>0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),o.push(t.substring(n-=s,n+s)),!((l+=s+1)>r));)s=e[a=(a+1)%e.length];return o.reverse().join(i)}),n=void 0===t.currency?"":t.currency[0]+"",o=void 0===t.currency?"":t.currency[1]+"",a=void 0===t.decimal?".":t.decimal+"",s=void 0===t.numerals?sn:function(t){return function(e){return e.replace(/[0-9]/g,(function(e){return t[+e]}))}}(un.call(t.numerals,String)),l=void 0===t.percent?"%":t.percent+"",c=void 0===t.minus?"\u2212":t.minus+"",h=void 0===t.nan?"NaN":t.nan+"";function u(t){var e=(t=tn(t)).fill,i=t.align,u=t.sign,d=t.symbol,f=t.zero,p=t.width,g=t.comma,m=t.precision,y=t.trim,x=t.type;"n"===x?(g=!0,x="g"):an[x]||(void 0===m&&(m=12),y=!0,x="g"),(f||"0"===e&&"="===i)&&(f=!0,e="0",i="=");var C="$"===d?n:"#"===d&&/[boxX]/.test(x)?"0"+x.toLowerCase():"",b="$"===d?o:/[%p]/.test(x)?l:"",_=an[x],v=/[defgprs%]/.test(x);function k(t){var n,o,l,d=C,k=b;if("c"===x)k=_(t)+k,t="";else{var T=(t=+t)<0||1/t<0;if(t=isNaN(t)?h:_(Math.abs(t),m),y&&(t=function(t){t:for(var e,i=t.length,r=1,n=-1;r<i;++r)switch(t[r]){case".":n=e=r;break;case"0":0===n&&(n=r),e=r;break;default:if(!+t[r])break t;n>0&&(n=0)}return n>0?t.slice(0,n)+t.slice(e+1):t}(t)),T&&0==+t&&"+"!==u&&(T=!1),d=(T?"("===u?u:c:"-"===u||"("===u?"":u)+d,k=("s"===x?dn[8+Qr/3]:"")+k+(T&&"("===u?")":""),v)for(n=-1,o=t.length;++n<o;)if(48>(l=t.charCodeAt(n))||l>57){k=(46===l?a+t.slice(n+1):t.slice(n))+k,t=t.slice(0,n);break}}g&&!f&&(t=r(t,1/0));var A=d.length+t.length+k.length,w=A<p?new Array(p-A+1).join(e):"";switch(g&&f&&(t=r(w+t,w.length?p-k.length:1/0),w=""),i){case"<":t=d+t+k+w;break;case"=":t=d+w+t+k;break;case"^":t=w.slice(0,A=w.length>>1)+d+t+k+w.slice(A);break;default:t=w+d+t+k}return s(t)}return m=void 0===m?6:/[gprs]/.test(x)?Math.max(1,Math.min(21,m)):Math.max(0,Math.min(20,m)),k.toString=function(){return t+""},k}return{format:u,formatPrefix:function(t,e){var i=u(((t=tn(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor(nn(e)/3))),n=Math.pow(10,-r),o=dn[8+r/3];return function(t){return i(n*t)+o}}}}function pn(t,e,i,r){var n,o=Fr(t,e,i);switch((r=tn(null==r?",f":r)).type){case"s":var a=Math.max(Math.abs(t),Math.abs(e));return null!=r.precision||isNaN(n=function(t,e){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(nn(e)/3)))-nn(Math.abs(t)))}(o,a))||(r.precision=n),hn(r,a);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(n=function(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,nn(e)-nn(t))+1}(o,Math.max(Math.abs(t),Math.abs(e))))||(r.precision=n-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(n=function(t){return Math.max(0,-nn(Math.abs(t)))}(o))||(r.precision=n-2*("%"===r.type))}return cn(r)}function gn(t){var e=t.domain;return t.ticks=function(t){var i=e();return function(t,e,i){if(!((i=+i)>0))return[];if((t=+t)==(e=+e))return[t];const r=e<t,[n,o,a]=r?Sr(e,t,i):Sr(t,e,i);if(!(o>=n))return[];const s=o-n+1,l=new Array(s);if(r)if(a<0)for(let c=0;c<s;++c)l[c]=(o-c)/-a;else for(let c=0;c<s;++c)l[c]=(o-c)*a;else if(a<0)for(let c=0;c<s;++c)l[c]=(n+c)/-a;else for(let c=0;c<s;++c)l[c]=(n+c)*a;return l}(i[0],i[i.length-1],null==t?10:t)},t.tickFormat=function(t,i){var r=e();return pn(r[0],r[r.length-1],null==t?10:t,i)},t.nice=function(i){null==i&&(i=10);var r,n,o=e(),a=0,s=o.length-1,l=o[a],c=o[s],h=10;for(c<l&&(n=l,l=c,c=n,n=a,a=s,s=n);h-- >0;){if((n=Br(l,c,i))===r)return o[a]=l,o[s]=c,e(o);if(n>0)l=Math.floor(l/n)*n,c=Math.ceil(c/n)*n;else{if(!(n<0))break;l=Math.ceil(l*n)/n,c=Math.floor(c*n)/n}r=n}return t},t}function mn(){var t=Jr();return t.copy=function(){return Xr(t,mn())},gr.apply(t,arguments),gn(t)}ln=fn({thousands:",",grouping:[3],currency:["$",""]}),cn=ln.format,hn=ln.formatPrefix;const yn=1e3,xn=6e4,Cn=36e5,bn=864e5,_n=6048e5,vn=2592e6,kn=31536e6,Tn=new Date,An=new Date;function wn(t,e,i,r){function n(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return n.floor=e=>(t(e=new Date(+e)),e),n.ceil=i=>(t(i=new Date(i-1)),e(i,1),t(i),i),n.round=t=>{const e=n(t),i=n.ceil(t);return t-e<i-t?e:i},n.offset=(t,i)=>(e(t=new Date(+t),null==i?1:Math.floor(i)),t),n.range=(i,r,o)=>{const a=[];if(i=n.ceil(i),o=null==o?1:Math.floor(o),!(i<r&&o>0))return a;let s;do{a.push(s=new Date(+i)),e(i,o),t(i)}while(s<i&&i<r);return a},n.filter=i=>wn((e=>{if(e>=e)for(;t(e),!i(e);)e.setTime(e-1)}),((t,r)=>{if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!i(t););else for(;--r>=0;)for(;e(t,1),!i(t););})),i&&(n.count=(e,r)=>(Tn.setTime(+e),An.setTime(+r),t(Tn),t(An),Math.floor(i(Tn,An))),n.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?n.filter(r?e=>r(e)%t==0:e=>n.count(0,e)%t==0):n:null)),n}const Sn=wn((()=>{}),((t,e)=>{t.setTime(+t+e)}),((t,e)=>e-t));Sn.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?wn((e=>{e.setTime(Math.floor(e/t)*t)}),((e,i)=>{e.setTime(+e+i*t)}),((e,i)=>(i-e)/t)):Sn:null);Sn.range;const Bn=wn((t=>{t.setTime(t-t.getMilliseconds())}),((t,e)=>{t.setTime(+t+e*yn)}),((t,e)=>(e-t)/yn),(t=>t.getUTCSeconds())),Fn=(Bn.range,wn((t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*yn)}),((t,e)=>{t.setTime(+t+e*xn)}),((t,e)=>(e-t)/xn),(t=>t.getMinutes()))),Ln=(Fn.range,wn((t=>{t.setUTCSeconds(0,0)}),((t,e)=>{t.setTime(+t+e*xn)}),((t,e)=>(e-t)/xn),(t=>t.getUTCMinutes()))),Mn=(Ln.range,wn((t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*yn-t.getMinutes()*xn)}),((t,e)=>{t.setTime(+t+e*Cn)}),((t,e)=>(e-t)/Cn),(t=>t.getHours()))),En=(Mn.range,wn((t=>{t.setUTCMinutes(0,0,0)}),((t,e)=>{t.setTime(+t+e*Cn)}),((t,e)=>(e-t)/Cn),(t=>t.getUTCHours()))),Nn=(En.range,wn((t=>t.setHours(0,0,0,0)),((t,e)=>t.setDate(t.getDate()+e)),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*xn)/bn),(t=>t.getDate()-1))),On=(Nn.range,wn((t=>{t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+e)}),((t,e)=>(e-t)/bn),(t=>t.getUTCDate()-1))),jn=(On.range,wn((t=>{t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+e)}),((t,e)=>(e-t)/bn),(t=>Math.floor(t/bn))));jn.range;function In(t){return wn((e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),((t,e)=>{t.setDate(t.getDate()+7*e)}),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*xn)/_n))}const Dn=In(0),qn=In(1),$n=In(2),zn=In(3),Pn=In(4),Rn=In(5),Wn=In(6);Dn.range,qn.range,$n.range,zn.range,Pn.range,Rn.range,Wn.range;function Un(t){return wn((e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+7*e)}),((t,e)=>(e-t)/_n))}const Hn=Un(0),Yn=Un(1),Vn=Un(2),Gn=Un(3),Xn=Un(4),Zn=Un(5),Jn=Un(6),Qn=(Hn.range,Yn.range,Vn.range,Gn.range,Xn.range,Zn.range,Jn.range,wn((t=>{t.setDate(1),t.setHours(0,0,0,0)}),((t,e)=>{t.setMonth(t.getMonth()+e)}),((t,e)=>e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())),(t=>t.getMonth()))),Kn=(Qn.range,wn((t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)}),((t,e)=>e.getUTCMonth()-t.getUTCMonth()+12*(e.getUTCFullYear()-t.getUTCFullYear())),(t=>t.getUTCMonth()))),to=(Kn.range,wn((t=>{t.setMonth(0,1),t.setHours(0,0,0,0)}),((t,e)=>{t.setFullYear(t.getFullYear()+e)}),((t,e)=>e.getFullYear()-t.getFullYear()),(t=>t.getFullYear())));to.every=t=>isFinite(t=Math.floor(t))&&t>0?wn((e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),((e,i)=>{e.setFullYear(e.getFullYear()+i*t)})):null;to.range;const eo=wn((t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)}),((t,e)=>e.getUTCFullYear()-t.getUTCFullYear()),(t=>t.getUTCFullYear()));eo.every=t=>isFinite(t=Math.floor(t))&&t>0?wn((e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),((e,i)=>{e.setUTCFullYear(e.getUTCFullYear()+i*t)})):null;eo.range;function io(t,e,i,r,n,o){const a=[[Bn,1,yn],[Bn,5,5e3],[Bn,15,15e3],[Bn,30,3e4],[o,1,xn],[o,5,3e5],[o,15,9e5],[o,30,18e5],[n,1,Cn],[n,3,108e5],[n,6,216e5],[n,12,432e5],[r,1,bn],[r,2,1728e5],[i,1,_n],[e,1,vn],[e,3,7776e6],[t,1,kn]];function s(e,i,r){const n=Math.abs(i-e)/r,o=Er((([,,t])=>t)).right(a,n);if(o===a.length)return t.every(Fr(e/kn,i/kn,r));if(0===o)return Sn.every(Math.max(Fr(e,i,r),1));const[s,l]=a[n/a[o-1][2]<a[o][2]/n?o-1:o];return s.every(l)}return[function(t,e,i){const r=e<t;r&&([t,e]=[e,t]);const n=i&&"function"==typeof i.range?i:s(t,e,i),o=n?n.range(t,+e+1):[];return r?o.reverse():o},s]}const[ro,no]=io(eo,Kn,Hn,jn,En,Ln),[oo,ao]=io(to,Qn,Dn,Nn,Mn,Fn);function so(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function lo(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function co(t,e,i){return{y:t,m:e,d:i,H:0,M:0,S:0,L:0}}var ho,uo,fo={"-":"",_:" ",0:"0"},po=/^\s*\d+/,go=/^%/,mo=/[\\^$*+?|[\]().{}]/g;function yo(t,e,i){var r=t<0?"-":"",n=(r?-t:t)+"",o=n.length;return r+(o<i?new Array(i-o+1).join(e)+n:n)}function xo(t){return t.replace(mo,"\\$&")}function Co(t){return new RegExp("^(?:"+t.map(xo).join("|")+")","i")}function bo(t){return new Map(t.map(((t,e)=>[t.toLowerCase(),e])))}function _o(t,e,i){var r=po.exec(e.slice(i,i+1));return r?(t.w=+r[0],i+r[0].length):-1}function vo(t,e,i){var r=po.exec(e.slice(i,i+1));return r?(t.u=+r[0],i+r[0].length):-1}function ko(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.U=+r[0],i+r[0].length):-1}function To(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.V=+r[0],i+r[0].length):-1}function Ao(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.W=+r[0],i+r[0].length):-1}function wo(t,e,i){var r=po.exec(e.slice(i,i+4));return r?(t.y=+r[0],i+r[0].length):-1}function So(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),i+r[0].length):-1}function Bo(t,e,i){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(i,i+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),i+r[0].length):-1}function Fo(t,e,i){var r=po.exec(e.slice(i,i+1));return r?(t.q=3*r[0]-3,i+r[0].length):-1}function Lo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.m=r[0]-1,i+r[0].length):-1}function Mo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.d=+r[0],i+r[0].length):-1}function Eo(t,e,i){var r=po.exec(e.slice(i,i+3));return r?(t.m=0,t.d=+r[0],i+r[0].length):-1}function No(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.H=+r[0],i+r[0].length):-1}function Oo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.M=+r[0],i+r[0].length):-1}function jo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.S=+r[0],i+r[0].length):-1}function Io(t,e,i){var r=po.exec(e.slice(i,i+3));return r?(t.L=+r[0],i+r[0].length):-1}function Do(t,e,i){var r=po.exec(e.slice(i,i+6));return r?(t.L=Math.floor(r[0]/1e3),i+r[0].length):-1}function qo(t,e,i){var r=go.exec(e.slice(i,i+1));return r?i+r[0].length:-1}function $o(t,e,i){var r=po.exec(e.slice(i));return r?(t.Q=+r[0],i+r[0].length):-1}function zo(t,e,i){var r=po.exec(e.slice(i));return r?(t.s=+r[0],i+r[0].length):-1}function Po(t,e){return yo(t.getDate(),e,2)}function Ro(t,e){return yo(t.getHours(),e,2)}function Wo(t,e){return yo(t.getHours()%12||12,e,2)}function Uo(t,e){return yo(1+Nn.count(to(t),t),e,3)}function Ho(t,e){return yo(t.getMilliseconds(),e,3)}function Yo(t,e){return Ho(t,e)+"000"}function Vo(t,e){return yo(t.getMonth()+1,e,2)}function Go(t,e){return yo(t.getMinutes(),e,2)}function Xo(t,e){return yo(t.getSeconds(),e,2)}function Zo(t){var e=t.getDay();return 0===e?7:e}function Jo(t,e){return yo(Dn.count(to(t)-1,t),e,2)}function Qo(t){var e=t.getDay();return e>=4||0===e?Pn(t):Pn.ceil(t)}function Ko(t,e){return t=Qo(t),yo(Pn.count(to(t),t)+(4===to(t).getDay()),e,2)}function ta(t){return t.getDay()}function ea(t,e){return yo(qn.count(to(t)-1,t),e,2)}function ia(t,e){return yo(t.getFullYear()%100,e,2)}function ra(t,e){return yo((t=Qo(t)).getFullYear()%100,e,2)}function na(t,e){return yo(t.getFullYear()%1e4,e,4)}function oa(t,e){var i=t.getDay();return yo((t=i>=4||0===i?Pn(t):Pn.ceil(t)).getFullYear()%1e4,e,4)}function aa(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+yo(e/60|0,"0",2)+yo(e%60,"0",2)}function sa(t,e){return yo(t.getUTCDate(),e,2)}function la(t,e){return yo(t.getUTCHours(),e,2)}function ca(t,e){return yo(t.getUTCHours()%12||12,e,2)}function ha(t,e){return yo(1+On.count(eo(t),t),e,3)}function ua(t,e){return yo(t.getUTCMilliseconds(),e,3)}function da(t,e){return ua(t,e)+"000"}function fa(t,e){return yo(t.getUTCMonth()+1,e,2)}function pa(t,e){return yo(t.getUTCMinutes(),e,2)}function ga(t,e){return yo(t.getUTCSeconds(),e,2)}function ma(t){var e=t.getUTCDay();return 0===e?7:e}function ya(t,e){return yo(Hn.count(eo(t)-1,t),e,2)}function xa(t){var e=t.getUTCDay();return e>=4||0===e?Xn(t):Xn.ceil(t)}function Ca(t,e){return t=xa(t),yo(Xn.count(eo(t),t)+(4===eo(t).getUTCDay()),e,2)}function ba(t){return t.getUTCDay()}function _a(t,e){return yo(Yn.count(eo(t)-1,t),e,2)}function va(t,e){return yo(t.getUTCFullYear()%100,e,2)}function ka(t,e){return yo((t=xa(t)).getUTCFullYear()%100,e,2)}function Ta(t,e){return yo(t.getUTCFullYear()%1e4,e,4)}function Aa(t,e){var i=t.getUTCDay();return yo((t=i>=4||0===i?Xn(t):Xn.ceil(t)).getUTCFullYear()%1e4,e,4)}function wa(){return"+0000"}function Sa(){return"%"}function Ba(t){return+t}function Fa(t){return Math.floor(+t/1e3)}function La(t){return new Date(t)}function Ma(t){return t instanceof Date?+t:+new Date(+t)}function Ea(t,e,i,r,n,o,a,s,l,c){var h=Jr(),u=h.invert,d=h.domain,f=c(".%L"),p=c(":%S"),g=c("%I:%M"),m=c("%I %p"),y=c("%a %d"),x=c("%b %d"),C=c("%B"),b=c("%Y");function _(t){return(l(t)<t?f:s(t)<t?p:a(t)<t?g:o(t)<t?m:r(t)<t?n(t)<t?y:x:i(t)<t?C:b)(t)}return h.invert=function(t){return new Date(u(t))},h.domain=function(t){return arguments.length?d(Array.from(t,Ma)):d().map(La)},h.ticks=function(e){var i=d();return t(i[0],i[i.length-1],null==e?10:e)},h.tickFormat=function(t,e){return null==e?_:c(e)},h.nice=function(t){var i=d();return t&&"function"==typeof t.range||(t=e(i[0],i[i.length-1],null==t?10:t)),t?d(function(t,e){var i,r=0,n=(t=t.slice()).length-1,o=t[r],a=t[n];return a<o&&(i=r,r=n,n=i,i=o,o=a,a=i),t[r]=e.floor(o),t[n]=e.ceil(a),t}(i,t)):h},h.copy=function(){return Xr(h,Ea(t,e,i,r,n,o,a,s,l,c))},h}function Na(){return gr.apply(Ea(oo,ao,to,Qn,Dn,Nn,Mn,Fn,Bn,uo).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)}!function(t){ho=function(t){var e=t.dateTime,i=t.date,r=t.time,n=t.periods,o=t.days,a=t.shortDays,s=t.months,l=t.shortMonths,c=Co(n),h=bo(n),u=Co(o),d=bo(o),f=Co(a),p=bo(a),g=Co(s),m=bo(s),y=Co(l),x=bo(l),C={a:function(t){return a[t.getDay()]},A:function(t){return o[t.getDay()]},b:function(t){return l[t.getMonth()]},B:function(t){return s[t.getMonth()]},c:null,d:Po,e:Po,f:Yo,g:ra,G:oa,H:Ro,I:Wo,j:Uo,L:Ho,m:Vo,M:Go,p:function(t){return n[+(t.getHours()>=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:Ba,s:Fa,S:Xo,u:Zo,U:Jo,V:Ko,w:ta,W:ea,x:null,X:null,y:ia,Y:na,Z:aa,"%":Sa},b={a:function(t){return a[t.getUTCDay()]},A:function(t){return o[t.getUTCDay()]},b:function(t){return l[t.getUTCMonth()]},B:function(t){return s[t.getUTCMonth()]},c:null,d:sa,e:sa,f:da,g:ka,G:Aa,H:la,I:ca,j:ha,L:ua,m:fa,M:pa,p:function(t){return n[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:Ba,s:Fa,S:ga,u:ma,U:ya,V:Ca,w:ba,W:_a,x:null,X:null,y:va,Y:Ta,Z:wa,"%":Sa},_={a:function(t,e,i){var r=f.exec(e.slice(i));return r?(t.w=p.get(r[0].toLowerCase()),i+r[0].length):-1},A:function(t,e,i){var r=u.exec(e.slice(i));return r?(t.w=d.get(r[0].toLowerCase()),i+r[0].length):-1},b:function(t,e,i){var r=y.exec(e.slice(i));return r?(t.m=x.get(r[0].toLowerCase()),i+r[0].length):-1},B:function(t,e,i){var r=g.exec(e.slice(i));return r?(t.m=m.get(r[0].toLowerCase()),i+r[0].length):-1},c:function(t,i,r){return T(t,e,i,r)},d:Mo,e:Mo,f:Do,g:So,G:wo,H:No,I:No,j:Eo,L:Io,m:Lo,M:Oo,p:function(t,e,i){var r=c.exec(e.slice(i));return r?(t.p=h.get(r[0].toLowerCase()),i+r[0].length):-1},q:Fo,Q:$o,s:zo,S:jo,u:vo,U:ko,V:To,w:_o,W:Ao,x:function(t,e,r){return T(t,i,e,r)},X:function(t,e,i){return T(t,r,e,i)},y:So,Y:wo,Z:Bo,"%":qo};function v(t,e){return function(i){var r,n,o,a=[],s=-1,l=0,c=t.length;for(i instanceof Date||(i=new Date(+i));++s<c;)37===t.charCodeAt(s)&&(a.push(t.slice(l,s)),null!=(n=fo[r=t.charAt(++s)])?r=t.charAt(++s):n="e"===r?" ":"0",(o=e[r])&&(r=o(i,n)),a.push(r),l=s+1);return a.push(t.slice(l,s)),a.join("")}}function k(t,e){return function(i){var r,n,o=co(1900,void 0,1);if(T(o,t,i+="",0)!=i.length)return null;if("Q"in o)return new Date(o.Q);if("s"in o)return new Date(1e3*o.s+("L"in o?o.L:0));if(e&&!("Z"in o)&&(o.Z=0),"p"in o&&(o.H=o.H%12+12*o.p),void 0===o.m&&(o.m="q"in o?o.q:0),"V"in o){if(o.V<1||o.V>53)return null;"w"in o||(o.w=1),"Z"in o?(n=(r=lo(co(o.y,0,1))).getUTCDay(),r=n>4||0===n?Yn.ceil(r):Yn(r),r=On.offset(r,7*(o.V-1)),o.y=r.getUTCFullYear(),o.m=r.getUTCMonth(),o.d=r.getUTCDate()+(o.w+6)%7):(n=(r=so(co(o.y,0,1))).getDay(),r=n>4||0===n?qn.ceil(r):qn(r),r=Nn.offset(r,7*(o.V-1)),o.y=r.getFullYear(),o.m=r.getMonth(),o.d=r.getDate()+(o.w+6)%7)}else("W"in o||"U"in o)&&("w"in o||(o.w="u"in o?o.u%7:"W"in o?1:0),n="Z"in o?lo(co(o.y,0,1)).getUTCDay():so(co(o.y,0,1)).getDay(),o.m=0,o.d="W"in o?(o.w+6)%7+7*o.W-(n+5)%7:o.w+7*o.U-(n+6)%7);return"Z"in o?(o.H+=o.Z/100|0,o.M+=o.Z%100,lo(o)):so(o)}}function T(t,e,i,r){for(var n,o,a=0,s=e.length,l=i.length;a<s;){if(r>=l)return-1;if(37===(n=e.charCodeAt(a++))){if(n=e.charAt(a++),!(o=_[n in fo?e.charAt(a++):n])||(r=o(t,i,r))<0)return-1}else if(n!=i.charCodeAt(r++))return-1}return r}return C.x=v(i,C),C.X=v(r,C),C.c=v(e,C),b.x=v(i,b),b.X=v(r,b),b.c=v(e,b),{format:function(t){var e=v(t+="",C);return e.toString=function(){return t},e},parse:function(t){var e=k(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=v(t+="",b);return e.toString=function(){return t},e},utcParse:function(t){var e=k(t+="",!0);return e.toString=function(){return t},e}}}(t),uo=ho.format,ho.parse,ho.utcFormat,ho.utcParse}({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});const Oa=function(t){for(var e=t.length/6|0,i=new Array(e),r=0;r<e;)i[r]="#"+t.slice(6*r,6*++r);return i}("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab");function ja(t){return"string"==typeof t?new Ft([[document.querySelector(t)]],[document.documentElement]):new Ft([[t]],Bt)}function Ia(t){return"string"==typeof t?new Ft([document.querySelectorAll(t)],[document.documentElement]):new Ft([_(t)],Bt)}function Da(t){return function(){return t}}const qa=Math.abs,$a=Math.atan2,za=Math.cos,Pa=Math.max,Ra=Math.min,Wa=Math.sin,Ua=Math.sqrt,Ha=1e-12,Ya=Math.PI,Va=Ya/2,Ga=2*Ya;function Xa(t){return t>=1?Va:t<=-1?-Va:Math.asin(t)}const Za=Math.PI,Ja=2*Za,Qa=1e-6,Ka=Ja-Qa;function ts(t){this._+=t[0];for(let e=1,i=t.length;e<i;++e)this._+=arguments[e]+t[e]}class es{constructor(t){this._x0=this._y0=this._x1=this._y1=null,this._="",this._append=null==t?ts:function(t){let e=Math.floor(t);if(!(e>=0))throw new Error(`invalid digits: ${t}`);if(e>15)return ts;const i=10**e;return function(t){this._+=t[0];for(let e=1,r=t.length;e<r;++e)this._+=Math.round(arguments[e]*i)/i+t[e]}}(t)}moveTo(t,e){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}`}closePath(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._append`Z`)}lineTo(t,e){this._append`L${this._x1=+t},${this._y1=+e}`}quadraticCurveTo(t,e,i,r){this._append`Q${+t},${+e},${this._x1=+i},${this._y1=+r}`}bezierCurveTo(t,e,i,r,n,o){this._append`C${+t},${+e},${+i},${+r},${this._x1=+n},${this._y1=+o}`}arcTo(t,e,i,r,n){if(t=+t,e=+e,i=+i,r=+r,(n=+n)<0)throw new Error(`negative radius: ${n}`);let o=this._x1,a=this._y1,s=i-t,l=r-e,c=o-t,h=a-e,u=c*c+h*h;if(null===this._x1)this._append`M${this._x1=t},${this._y1=e}`;else if(u>Qa)if(Math.abs(h*s-l*c)>Qa&&n){let d=i-o,f=r-a,p=s*s+l*l,g=d*d+f*f,m=Math.sqrt(p),y=Math.sqrt(u),x=n*Math.tan((Za-Math.acos((p+u-g)/(2*m*y)))/2),C=x/y,b=x/m;Math.abs(C-1)>Qa&&this._append`L${t+C*c},${e+C*h}`,this._append`A${n},${n},0,0,${+(h*d>c*f)},${this._x1=t+b*s},${this._y1=e+b*l}`}else this._append`L${this._x1=t},${this._y1=e}`;else;}arc(t,e,i,r,n,o){if(t=+t,e=+e,o=!!o,(i=+i)<0)throw new Error(`negative radius: ${i}`);let a=i*Math.cos(r),s=i*Math.sin(r),l=t+a,c=e+s,h=1^o,u=o?r-n:n-r;null===this._x1?this._append`M${l},${c}`:(Math.abs(this._x1-l)>Qa||Math.abs(this._y1-c)>Qa)&&this._append`L${l},${c}`,i&&(u<0&&(u=u%Ja+Ja),u>Ka?this._append`A${i},${i},0,1,${h},${t-a},${e-s}A${i},${i},0,1,${h},${this._x1=l},${this._y1=c}`:u>Qa&&this._append`A${i},${i},0,${+(u>=Za)},${h},${this._x1=t+i*Math.cos(n)},${this._y1=e+i*Math.sin(n)}`)}rect(t,e,i,r){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}h${i=+i}v${+r}h${-i}Z`}toString(){return this._}}function is(t){let e=3;return t.digits=function(i){if(!arguments.length)return e;if(null==i)e=null;else{const t=Math.floor(i);if(!(t>=0))throw new RangeError(`invalid digits: ${i}`);e=t}return t},()=>new es(e)}function rs(t){return t.innerRadius}function ns(t){return t.outerRadius}function os(t){return t.startAngle}function as(t){return t.endAngle}function ss(t){return t&&t.padAngle}function ls(t,e,i,r,n,o,a){var s=t-i,l=e-r,c=(a?o:-o)/Ua(s*s+l*l),h=c*l,u=-c*s,d=t+h,f=e+u,p=i+h,g=r+u,m=(d+p)/2,y=(f+g)/2,x=p-d,C=g-f,b=x*x+C*C,_=n-o,v=d*g-p*f,k=(C<0?-1:1)*Ua(Pa(0,_*_*b-v*v)),T=(v*C-x*k)/b,A=(-v*x-C*k)/b,w=(v*C+x*k)/b,S=(-v*x+C*k)/b,B=T-m,F=A-y,L=w-m,M=S-y;return B*B+F*F>L*L+M*M&&(T=w,A=S),{cx:T,cy:A,x01:-h,y01:-u,x11:T*(n/_-1),y11:A*(n/_-1)}}function cs(){var t=rs,e=ns,i=Da(0),r=null,n=os,o=as,a=ss,s=null,l=is(c);function c(){var c,h,u,d=+t.apply(this,arguments),f=+e.apply(this,arguments),p=n.apply(this,arguments)-Va,g=o.apply(this,arguments)-Va,m=qa(g-p),y=g>p;if(s||(s=c=l()),f<d&&(h=f,f=d,d=h),f>Ha)if(m>Ga-Ha)s.moveTo(f*za(p),f*Wa(p)),s.arc(0,0,f,p,g,!y),d>Ha&&(s.moveTo(d*za(g),d*Wa(g)),s.arc(0,0,d,g,p,y));else{var x,C,b=p,_=g,v=p,k=g,T=m,A=m,w=a.apply(this,arguments)/2,S=w>Ha&&(r?+r.apply(this,arguments):Ua(d*d+f*f)),B=Ra(qa(f-d)/2,+i.apply(this,arguments)),F=B,L=B;if(S>Ha){var M=Xa(S/d*Wa(w)),E=Xa(S/f*Wa(w));(T-=2*M)>Ha?(v+=M*=y?1:-1,k-=M):(T=0,v=k=(p+g)/2),(A-=2*E)>Ha?(b+=E*=y?1:-1,_-=E):(A=0,b=_=(p+g)/2)}var N=f*za(b),O=f*Wa(b),j=d*za(k),I=d*Wa(k);if(B>Ha){var D,q=f*za(_),$=f*Wa(_),z=d*za(v),P=d*Wa(v);if(m<Ya)if(D=function(t,e,i,r,n,o,a,s){var l=i-t,c=r-e,h=a-n,u=s-o,d=u*l-h*c;if(!(d*d<Ha))return[t+(d=(h*(e-o)-u*(t-n))/d)*l,e+d*c]}(N,O,z,P,q,$,j,I)){var R=N-D[0],W=O-D[1],U=q-D[0],H=$-D[1],Y=1/Wa(((u=(R*U+W*H)/(Ua(R*R+W*W)*Ua(U*U+H*H)))>1?0:u<-1?Ya:Math.acos(u))/2),V=Ua(D[0]*D[0]+D[1]*D[1]);F=Ra(B,(d-V)/(Y-1)),L=Ra(B,(f-V)/(Y+1))}else F=L=0}A>Ha?L>Ha?(x=ls(z,P,N,O,f,L,y),C=ls(q,$,j,I,f,L,y),s.moveTo(x.cx+x.x01,x.cy+x.y01),L<B?s.arc(x.cx,x.cy,L,$a(x.y01,x.x01),$a(C.y01,C.x01),!y):(s.arc(x.cx,x.cy,L,$a(x.y01,x.x01),$a(x.y11,x.x11),!y),s.arc(0,0,f,$a(x.cy+x.y11,x.cx+x.x11),$a(C.cy+C.y11,C.cx+C.x11),!y),s.arc(C.cx,C.cy,L,$a(C.y11,C.x11),$a(C.y01,C.x01),!y))):(s.moveTo(N,O),s.arc(0,0,f,b,_,!y)):s.moveTo(N,O),d>Ha&&T>Ha?F>Ha?(x=ls(j,I,q,$,d,-F,y),C=ls(N,O,z,P,d,-F,y),s.lineTo(x.cx+x.x01,x.cy+x.y01),F<B?s.arc(x.cx,x.cy,F,$a(x.y01,x.x01),$a(C.y01,C.x01),!y):(s.arc(x.cx,x.cy,F,$a(x.y01,x.x01),$a(x.y11,x.x11),!y),s.arc(0,0,d,$a(x.cy+x.y11,x.cx+x.x11),$a(C.cy+C.y11,C.cx+C.x11),y),s.arc(C.cx,C.cy,F,$a(C.y11,C.x11),$a(C.y01,C.x01),!y))):s.arc(0,0,d,k,v,y):s.lineTo(j,I)}else s.moveTo(0,0);if(s.closePath(),c)return s=null,c+""||null}return c.centroid=function(){var i=(+t.apply(this,arguments)+ +e.apply(this,arguments))/2,r=(+n.apply(this,arguments)+ +o.apply(this,arguments))/2-Ya/2;return[za(r)*i,Wa(r)*i]},c.innerRadius=function(e){return arguments.length?(t="function"==typeof e?e:Da(+e),c):t},c.outerRadius=function(t){return arguments.length?(e="function"==typeof t?t:Da(+t),c):e},c.cornerRadius=function(t){return arguments.length?(i="function"==typeof t?t:Da(+t),c):i},c.padRadius=function(t){return arguments.length?(r=null==t?null:"function"==typeof t?t:Da(+t),c):r},c.startAngle=function(t){return arguments.length?(n="function"==typeof t?t:Da(+t),c):n},c.endAngle=function(t){return arguments.length?(o="function"==typeof t?t:Da(+t),c):o},c.padAngle=function(t){return arguments.length?(a="function"==typeof t?t:Da(+t),c):a},c.context=function(t){return arguments.length?(s=null==t?null:t,c):s},c}es.prototype;Array.prototype.slice;function hs(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function us(t){this._context=t}function ds(t){return new us(t)}function fs(t){return t[0]}function ps(t){return t[1]}function gs(t,e){var i=Da(!0),r=null,n=ds,o=null,a=is(s);function s(s){var l,c,h,u=(s=hs(s)).length,d=!1;for(null==r&&(o=n(h=a())),l=0;l<=u;++l)!(l<u&&i(c=s[l],l,s))===d&&((d=!d)?o.lineStart():o.lineEnd()),d&&o.point(+t(c,l,s),+e(c,l,s));if(h)return o=null,h+""||null}return t="function"==typeof t?t:void 0===t?fs:Da(t),e="function"==typeof e?e:void 0===e?ps:Da(e),s.x=function(e){return arguments.length?(t="function"==typeof e?e:Da(+e),s):t},s.y=function(t){return arguments.length?(e="function"==typeof t?t:Da(+t),s):e},s.defined=function(t){return arguments.length?(i="function"==typeof t?t:Da(!!t),s):i},s.curve=function(t){return arguments.length?(n=t,null!=r&&(o=n(r)),s):n},s.context=function(t){return arguments.length?(null==t?r=o=null:o=n(r=t),s):r},s}function ms(t,e){return e<t?-1:e>t?1:e>=t?0:NaN}function ys(t){return t}function xs(){var t=ys,e=ms,i=null,r=Da(0),n=Da(Ga),o=Da(0);function a(a){var s,l,c,h,u,d=(a=hs(a)).length,f=0,p=new Array(d),g=new Array(d),m=+r.apply(this,arguments),y=Math.min(Ga,Math.max(-Ga,n.apply(this,arguments)-m)),x=Math.min(Math.abs(y)/d,o.apply(this,arguments)),C=x*(y<0?-1:1);for(s=0;s<d;++s)(u=g[p[s]=s]=+t(a[s],s,a))>0&&(f+=u);for(null!=e?p.sort((function(t,i){return e(g[t],g[i])})):null!=i&&p.sort((function(t,e){return i(a[t],a[e])})),s=0,c=f?(y-d*C)/f:0;s<d;++s,m=h)l=p[s],h=m+((u=g[l])>0?u*c:0)+C,g[l]={data:a[l],index:s,value:u,startAngle:m,endAngle:h,padAngle:x};return g}return a.value=function(e){return arguments.length?(t="function"==typeof e?e:Da(+e),a):t},a.sortValues=function(t){return arguments.length?(e=t,i=null,a):e},a.sort=function(t){return arguments.length?(i=t,e=null,a):i},a.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:Da(+t),a):r},a.endAngle=function(t){return arguments.length?(n="function"==typeof t?t:Da(+t),a):n},a.padAngle=function(t){return arguments.length?(o="function"==typeof t?t:Da(+t),a):o},a}function Cs(){}function bs(t,e,i){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+i)/6)}function _s(t){this._context=t}function vs(t){return new _s(t)}function ks(t){this._context=t}function Ts(t){return new ks(t)}function As(t){this._context=t}function ws(t){return new As(t)}us.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._context.lineTo(t,e)}}},_s.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:bs(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:bs(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},ks.prototype={areaStart:Cs,areaEnd:Cs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:bs(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},As.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var i=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(i,r):this._context.moveTo(i,r);break;case 3:this._point=4;default:bs(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};class Ss{constructor(t,e){this._context=t,this._x=e}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line}point(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._x?this._context.bezierCurveTo(this._x0=(this._x0+t)/2,this._y0,this._x0,e,t,e):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+e)/2,t,this._y0,t,e)}this._x0=t,this._y0=e}}function Bs(t){return new Ss(t,!0)}function Fs(t){return new Ss(t,!1)}function Ls(t,e){this._basis=new _s(t),this._beta=e}Ls.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,i=t.length-1;if(i>0)for(var r,n=t[0],o=e[0],a=t[i]-n,s=e[i]-o,l=-1;++l<=i;)r=l/i,this._basis.point(this._beta*t[l]+(1-this._beta)*(n+r*a),this._beta*e[l]+(1-this._beta)*(o+r*s));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};const Ms=function t(e){function i(t){return 1===e?new _s(t):new Ls(t,e)}return i.beta=function(e){return t(+e)},i}(.85);function Es(t,e,i){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-i),t._x2,t._y2)}function Ns(t,e){this._context=t,this._k=(1-e)/6}Ns.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Es(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:Es(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Os=function t(e){function i(t){return new Ns(t,e)}return i.tension=function(e){return t(+e)},i}(0);function js(t,e){this._context=t,this._k=(1-e)/6}js.prototype={areaStart:Cs,areaEnd:Cs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Es(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Is=function t(e){function i(t){return new js(t,e)}return i.tension=function(e){return t(+e)},i}(0);function Ds(t,e){this._context=t,this._k=(1-e)/6}Ds.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Es(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const qs=function t(e){function i(t){return new Ds(t,e)}return i.tension=function(e){return t(+e)},i}(0);function $s(t,e,i){var r=t._x1,n=t._y1,o=t._x2,a=t._y2;if(t._l01_a>Ha){var s=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,l=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*s-t._x0*t._l12_2a+t._x2*t._l01_2a)/l,n=(n*s-t._y0*t._l12_2a+t._y2*t._l01_2a)/l}if(t._l23_a>Ha){var c=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,h=3*t._l23_a*(t._l23_a+t._l12_a);o=(o*c+t._x1*t._l23_2a-e*t._l12_2a)/h,a=(a*c+t._y1*t._l23_2a-i*t._l12_2a)/h}t._context.bezierCurveTo(r,n,o,a,t._x2,t._y2)}function zs(t,e){this._context=t,this._alpha=e}zs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var i=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:$s(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Ps=function t(e){function i(t){return e?new zs(t,e):new Ns(t,0)}return i.alpha=function(e){return t(+e)},i}(.5);function Rs(t,e){this._context=t,this._alpha=e}Rs.prototype={areaStart:Cs,areaEnd:Cs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){if(t=+t,e=+e,this._point){var i=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:$s(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Ws=function t(e){function i(t){return e?new Rs(t,e):new js(t,0)}return i.alpha=function(e){return t(+e)},i}(.5);function Us(t,e){this._context=t,this._alpha=e}Us.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var i=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:$s(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Hs=function t(e){function i(t){return e?new Us(t,e):new Ds(t,0)}return i.alpha=function(e){return t(+e)},i}(.5);function Ys(t){this._context=t}function Vs(t){return new Ys(t)}function Gs(t){return t<0?-1:1}function Xs(t,e,i){var r=t._x1-t._x0,n=e-t._x1,o=(t._y1-t._y0)/(r||n<0&&-0),a=(i-t._y1)/(n||r<0&&-0),s=(o*n+a*r)/(r+n);return(Gs(o)+Gs(a))*Math.min(Math.abs(o),Math.abs(a),.5*Math.abs(s))||0}function Zs(t,e){var i=t._x1-t._x0;return i?(3*(t._y1-t._y0)/i-e)/2:e}function Js(t,e,i){var r=t._x0,n=t._y0,o=t._x1,a=t._y1,s=(o-r)/3;t._context.bezierCurveTo(r+s,n+s*e,o-s,a-s*i,o,a)}function Qs(t){this._context=t}function Ks(t){this._context=new tl(t)}function tl(t){this._context=t}function el(t){return new Qs(t)}function il(t){return new Ks(t)}function rl(t){this._context=t}function nl(t){var e,i,r=t.length-1,n=new Array(r),o=new Array(r),a=new Array(r);for(n[0]=0,o[0]=2,a[0]=t[0]+2*t[1],e=1;e<r-1;++e)n[e]=1,o[e]=4,a[e]=4*t[e]+2*t[e+1];for(n[r-1]=2,o[r-1]=7,a[r-1]=8*t[r-1]+t[r],e=1;e<r;++e)i=n[e]/o[e-1],o[e]-=i,a[e]-=i*a[e-1];for(n[r-1]=a[r-1]/o[r-1],e=r-2;e>=0;--e)n[e]=(a[e]-n[e+1])/o[e];for(o[r-1]=(t[r]+n[r-1])/2,e=0;e<r-1;++e)o[e]=2*t[e+1]-n[e+1];return[n,o]}function ol(t){return new rl(t)}function al(t,e){this._context=t,this._t=e}function sl(t){return new al(t,.5)}function ll(t){return new al(t,0)}function cl(t){return new al(t,1)}function hl(t,e,i){this.k=t,this.x=e,this.y=i}Ys.prototype={areaStart:Cs,areaEnd:Cs,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}},Qs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:Js(this,this._t0,Zs(this,this._t0))}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){var i=NaN;if(e=+e,(t=+t)!==this._x1||e!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,Js(this,Zs(this,i=Xs(this,t,e)),i);break;default:Js(this,this._t0,i=Xs(this,t,e))}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=i}}},(Ks.prototype=Object.create(Qs.prototype)).point=function(t,e){Qs.prototype.point.call(this,e,t)},tl.prototype={moveTo:function(t,e){this._context.moveTo(e,t)},closePath:function(){this._context.closePath()},lineTo:function(t,e){this._context.lineTo(e,t)},bezierCurveTo:function(t,e,i,r,n,o){this._context.bezierCurveTo(e,t,r,i,o,n)}},rl.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,e=this._y,i=t.length;if(i)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),2===i)this._context.lineTo(t[1],e[1]);else for(var r=nl(t),n=nl(e),o=0,a=1;a<i;++o,++a)this._context.bezierCurveTo(r[0][o],n[0][o],r[1][o],n[1][o],t[a],e[a]);(this._line||0!==this._line&&1===i)&&this._context.closePath(),this._line=1-this._line,this._x=this._y=null},point:function(t,e){this._x.push(+t),this._y.push(+e)}},al.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=this._y=NaN,this._point=0},lineEnd:function(){0<this._t&&this._t<1&&2===this._point&&this._context.lineTo(this._x,this._y),(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line>=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var i=this._x*(1-this._t)+t*this._t;this._context.lineTo(i,this._y),this._context.lineTo(i,e)}}this._x=t,this._y=e}},hl.prototype={constructor:hl,scale:function(t){return 1===t?this:new hl(this.k*t,this.x,this.y)},translate:function(t,e){return 0===t&0===e?this:new hl(this.k,this.x+this.k*t,this.y+this.k*e)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};new hl(1,0,0);hl.prototype},93539:(t,e,i)=>{"use strict";i.d(e,{A:()=>a});var r=i(72453),n=i(63122);const o=class{constructor(){this.type=n.Z.ALL}get(){return this.type}set(t){if(this.type&&this.type!==t)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=t}reset(){this.type=n.Z.ALL}is(t){return this.type===t}};const a=new class{constructor(t,e){this.color=e,this.changed=!1,this.data=t,this.type=new o}set(t,e){return this.color=e,this.changed=!1,this.data=t,this.type.type=n.Z.ALL,this}_ensureHSL(){const t=this.data,{h:e,s:i,l:n}=t;void 0===e&&(t.h=r.A.channel.rgb2hsl(t,"h")),void 0===i&&(t.s=r.A.channel.rgb2hsl(t,"s")),void 0===n&&(t.l=r.A.channel.rgb2hsl(t,"l"))}_ensureRGB(){const t=this.data,{r:e,g:i,b:n}=t;void 0===e&&(t.r=r.A.channel.hsl2rgb(t,"r")),void 0===i&&(t.g=r.A.channel.hsl2rgb(t,"g")),void 0===n&&(t.b=r.A.channel.hsl2rgb(t,"b"))}get r(){const t=this.data,e=t.r;return this.type.is(n.Z.HSL)||void 0===e?(this._ensureHSL(),r.A.channel.hsl2rgb(t,"r")):e}get g(){const t=this.data,e=t.g;return this.type.is(n.Z.HSL)||void 0===e?(this._ensureHSL(),r.A.channel.hsl2rgb(t,"g")):e}get b(){const t=this.data,e=t.b;return this.type.is(n.Z.HSL)||void 0===e?(this._ensureHSL(),r.A.channel.hsl2rgb(t,"b")):e}get h(){const t=this.data,e=t.h;return this.type.is(n.Z.RGB)||void 0===e?(this._ensureRGB(),r.A.channel.rgb2hsl(t,"h")):e}get s(){const t=this.data,e=t.s;return this.type.is(n.Z.RGB)||void 0===e?(this._ensureRGB(),r.A.channel.rgb2hsl(t,"s")):e}get l(){const t=this.data,e=t.l;return this.type.is(n.Z.RGB)||void 0===e?(this._ensureRGB(),r.A.channel.rgb2hsl(t,"l")):e}get a(){return this.data.a}set r(t){this.type.set(n.Z.RGB),this.changed=!0,this.data.r=t}set g(t){this.type.set(n.Z.RGB),this.changed=!0,this.data.g=t}set b(t){this.type.set(n.Z.RGB),this.changed=!0,this.data.b=t}set h(t){this.type.set(n.Z.HSL),this.changed=!0,this.data.h=t}set s(t){this.type.set(n.Z.HSL),this.changed=!0,this.data.s=t}set l(t){this.type.set(n.Z.HSL),this.changed=!0,this.data.l=t}set a(t){this.changed=!0,this.data.a=t}}({r:0,g:0,b:0,a:0},"transparent")},74886:(t,e,i)=>{"use strict";i.d(e,{A:()=>g});var r=i(93539),n=i(63122);const o={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:t=>{if(35!==t.charCodeAt(0))return;const e=t.match(o.re);if(!e)return;const i=e[1],n=parseInt(i,16),a=i.length,s=a%4==0,l=a>4,c=l?1:17,h=l?8:4,u=s?0:-1,d=l?255:15;return r.A.set({r:(n>>h*(u+3)&d)*c,g:(n>>h*(u+2)&d)*c,b:(n>>h*(u+1)&d)*c,a:s?(n&d)*c/255:1},t)},stringify:t=>{const{r:e,g:i,b:r,a:o}=t;return o<1?`#${n.Y[Math.round(e)]}${n.Y[Math.round(i)]}${n.Y[Math.round(r)]}${n.Y[Math.round(255*o)]}`:`#${n.Y[Math.round(e)]}${n.Y[Math.round(i)]}${n.Y[Math.round(r)]}`}},a=o;var s=i(72453);const l={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:t=>{const e=t.match(l.hueRe);if(e){const[,t,i]=e;switch(i){case"grad":return s.A.channel.clamp.h(.9*parseFloat(t));case"rad":return s.A.channel.clamp.h(180*parseFloat(t)/Math.PI);case"turn":return s.A.channel.clamp.h(360*parseFloat(t))}}return s.A.channel.clamp.h(parseFloat(t))},parse:t=>{const e=t.charCodeAt(0);if(104!==e&&72!==e)return;const i=t.match(l.re);if(!i)return;const[,n,o,a,c,h]=i;return r.A.set({h:l._hue2deg(n),s:s.A.channel.clamp.s(parseFloat(o)),l:s.A.channel.clamp.l(parseFloat(a)),a:c?s.A.channel.clamp.a(h?parseFloat(c)/100:parseFloat(c)):1},t)},stringify:t=>{const{h:e,s:i,l:r,a:n}=t;return n<1?`hsla(${s.A.lang.round(e)}, ${s.A.lang.round(i)}%, ${s.A.lang.round(r)}%, ${n})`:`hsl(${s.A.lang.round(e)}, ${s.A.lang.round(i)}%, ${s.A.lang.round(r)}%)`}},c=l,h={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:t=>{t=t.toLowerCase();const e=h.colors[t];if(e)return a.parse(e)},stringify:t=>{const e=a.stringify(t);for(const i in h.colors)if(h.colors[i]===e)return i}},u=h,d={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:t=>{const e=t.charCodeAt(0);if(114!==e&&82!==e)return;const i=t.match(d.re);if(!i)return;const[,n,o,a,l,c,h,u,f]=i;return r.A.set({r:s.A.channel.clamp.r(o?2.55*parseFloat(n):parseFloat(n)),g:s.A.channel.clamp.g(l?2.55*parseFloat(a):parseFloat(a)),b:s.A.channel.clamp.b(h?2.55*parseFloat(c):parseFloat(c)),a:u?s.A.channel.clamp.a(f?parseFloat(u)/100:parseFloat(u)):1},t)},stringify:t=>{const{r:e,g:i,b:r,a:n}=t;return n<1?`rgba(${s.A.lang.round(e)}, ${s.A.lang.round(i)}, ${s.A.lang.round(r)}, ${s.A.lang.round(n)})`:`rgb(${s.A.lang.round(e)}, ${s.A.lang.round(i)}, ${s.A.lang.round(r)})`}},f=d,p={format:{keyword:h,hex:a,rgb:d,rgba:d,hsl:l,hsla:l},parse:t=>{if("string"!=typeof t)return t;const e=a.parse(t)||f.parse(t)||c.parse(t)||u.parse(t);if(e)return e;throw new Error(`Unsupported color format: "${t}"`)},stringify:t=>!t.changed&&t.color?t.color:t.type.is(n.Z.HSL)||void 0===t.data.r?c.stringify(t):t.a<1||!Number.isInteger(t.r)||!Number.isInteger(t.g)||!Number.isInteger(t.b)?f.stringify(t):a.stringify(t)},g=p},63122:(t,e,i)=>{"use strict";i.d(e,{Y:()=>n,Z:()=>o});var r=i(72453);const n={};for(let a=0;a<=255;a++)n[a]=r.A.unit.dec2hex(a);const o={ALL:0,RGB:1,HSL:2}},95635:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(72453),n=i(74886);const o=(t,e,i)=>{const o=n.A.parse(t),a=o[e],s=r.A.channel.clamp[e](a+i);return a!==s&&(o[e]=s),n.A.stringify(o)}},8232:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(72453),n=i(74886);const o=(t,e)=>{const i=n.A.parse(t);for(const n in e)i[n]=r.A.channel.clamp[n](e[n]);return n.A.stringify(i)}},75263:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=i(95635);const n=(t,e)=>(0,r.A)(t,"l",-e)},3219:(t,e,i)=>{"use strict";i.d(e,{A:()=>s});var r=i(72453),n=i(74886);const o=t=>{const{r:e,g:i,b:o}=n.A.parse(t),a=.2126*r.A.channel.toLinear(e)+.7152*r.A.channel.toLinear(i)+.0722*r.A.channel.toLinear(o);return r.A.lang.round(a)},a=t=>o(t)>=.5,s=t=>!a(t)},78041:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=i(95635);const n=(t,e)=>(0,r.A)(t,"l",e)},25582:(t,e,i)=>{"use strict";i.d(e,{A:()=>s});var r=i(72453),n=i(93539),o=i(74886),a=i(8232);const s=(t,e,i=0,s=1)=>{if("number"!=typeof t)return(0,a.A)(t,{a:e});const l=n.A.set({r:r.A.channel.clamp.r(t),g:r.A.channel.clamp.g(e),b:r.A.channel.clamp.b(i),a:r.A.channel.clamp.a(s)});return o.A.stringify(l)}},72453:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});const r={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:t=>t>=255?255:t<0?0:t,g:t=>t>=255?255:t<0?0:t,b:t=>t>=255?255:t<0?0:t,h:t=>t%360,s:t=>t>=100?100:t<0?0:t,l:t=>t>=100?100:t<0?0:t,a:t=>t>=1?1:t<0?0:t},toLinear:t=>{const e=t/255;return t>.03928?Math.pow((e+.055)/1.055,2.4):e/12.92},hue2rgb:(t,e,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t),hsl2rgb:({h:t,s:e,l:i},n)=>{if(!e)return 2.55*i;t/=360,e/=100;const o=(i/=100)<.5?i*(1+e):i+e-i*e,a=2*i-o;switch(n){case"r":return 255*r.hue2rgb(a,o,t+1/3);case"g":return 255*r.hue2rgb(a,o,t);case"b":return 255*r.hue2rgb(a,o,t-1/3)}},rgb2hsl:({r:t,g:e,b:i},r)=>{t/=255,e/=255,i/=255;const n=Math.max(t,e,i),o=Math.min(t,e,i),a=(n+o)/2;if("l"===r)return 100*a;if(n===o)return 0;const s=n-o;if("s"===r)return 100*(a>.5?s/(2-n-o):s/(n+o));switch(n){case t:return 60*((e-i)/s+(e<i?6:0));case e:return 60*((i-t)/s+2);case i:return 60*((t-e)/s+4);default:return-1}}},n={channel:r,lang:{clamp:(t,e,i)=>e>i?Math.min(e,Math.max(i,t)):Math.min(i,Math.max(e,t)),round:t=>Math.round(1e10*t)/1e10},unit:{dec2hex:t=>{const e=Math.round(t).toString(16);return e.length>1?e:`0${e}`}}}},80127:(t,e,i)=>{"use strict";i.d(e,{A:()=>d});const r=function(){this.__data__=[],this.size=0};var n=i(66984);const o=function(t,e){for(var i=t.length;i--;)if((0,n.A)(t[i][0],e))return i;return-1};var a=Array.prototype.splice;const s=function(t){var e=this.__data__,i=o(e,t);return!(i<0)&&(i==e.length-1?e.pop():a.call(e,i,1),--this.size,!0)};const l=function(t){var e=this.__data__,i=o(e,t);return i<0?void 0:e[i][1]};const c=function(t){return o(this.__data__,t)>-1};const h=function(t,e){var i=this.__data__,r=o(i,t);return r<0?(++this.size,i.push([t,e])):i[r][1]=e,this};function u(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e<i;){var r=t[e];this.set(r[0],r[1])}}u.prototype.clear=r,u.prototype.delete=s,u.prototype.get=l,u.prototype.has=c,u.prototype.set=h;const d=u},68335:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(18744),n=i(41917);const o=(0,r.A)(n.A,"Map")},29471:(t,e,i)=>{"use strict";i.d(e,{A:()=>k});const r=(0,i(18744).A)(Object,"create");const n=function(){this.__data__=r?r(null):{},this.size=0};const o=function(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e};var a=Object.prototype.hasOwnProperty;const s=function(t){var e=this.__data__;if(r){var i=e[t];return"__lodash_hash_undefined__"===i?void 0:i}return a.call(e,t)?e[t]:void 0};var l=Object.prototype.hasOwnProperty;const c=function(t){var e=this.__data__;return r?void 0!==e[t]:l.call(e,t)};const h=function(t,e){var i=this.__data__;return this.size+=this.has(t)?0:1,i[t]=r&&void 0===e?"__lodash_hash_undefined__":e,this};function u(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e<i;){var r=t[e];this.set(r[0],r[1])}}u.prototype.clear=n,u.prototype.delete=o,u.prototype.get=s,u.prototype.has=c,u.prototype.set=h;const d=u;var f=i(80127),p=i(68335);const g=function(){this.size=0,this.__data__={hash:new d,map:new(p.A||f.A),string:new d}};const m=function(t){var e=typeof t;return"string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t};const y=function(t,e){var i=t.__data__;return m(e)?i["string"==typeof e?"string":"hash"]:i.map};const x=function(t){var e=y(this,t).delete(t);return this.size-=e?1:0,e};const C=function(t){return y(this,t).get(t)};const b=function(t){return y(this,t).has(t)};const _=function(t,e){var i=y(this,t),r=i.size;return i.set(t,e),this.size+=i.size==r?0:1,this};function v(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e<i;){var r=t[e];this.set(r[0],r[1])}}v.prototype.clear=g,v.prototype.delete=x,v.prototype.get=C,v.prototype.has=b,v.prototype.set=_;const k=v},39857:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(18744),n=i(41917);const o=(0,r.A)(n.A,"Set")},11754:(t,e,i)=>{"use strict";i.d(e,{A:()=>d});var r=i(80127);const n=function(){this.__data__=new r.A,this.size=0};const o=function(t){var e=this.__data__,i=e.delete(t);return this.size=e.size,i};const a=function(t){return this.__data__.get(t)};const s=function(t){return this.__data__.has(t)};var l=i(68335),c=i(29471);const h=function(t,e){var i=this.__data__;if(i instanceof r.A){var n=i.__data__;if(!l.A||n.length<199)return n.push([t,e]),this.size=++i.size,this;i=this.__data__=new c.A(n)}return i.set(t,e),this.size=i.size,this};function u(t){var e=this.__data__=new r.A(t);this.size=e.size}u.prototype.clear=n,u.prototype.delete=o,u.prototype.get=a,u.prototype.has=s,u.prototype.set=h;const d=u},241:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=i(41917).A.Symbol},43988:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=i(41917).A.Uint8Array},83607:(t,e,i)=>{"use strict";i.d(e,{A:()=>h});const r=function(t,e){for(var i=-1,r=Array(t);++i<t;)r[i]=e(i);return r};var n=i(52274),o=i(92049),a=i(99912),s=i(25353),l=i(33858),c=Object.prototype.hasOwnProperty;const h=function(t,e){var i=(0,o.A)(t),h=!i&&(0,n.A)(t),u=!i&&!h&&(0,a.A)(t),d=!i&&!h&&!u&&(0,l.A)(t),f=i||h||u||d,p=f?r(t.length,String):[],g=p.length;for(var m in t)!e&&!c.call(t,m)||f&&("length"==m||u&&("offset"==m||"parent"==m)||d&&("buffer"==m||"byteLength"==m||"byteOffset"==m)||(0,s.A)(m,g))||p.push(m);return p}},52851:(t,e,i)=>{"use strict";i.d(e,{A:()=>a});var r=i(52528),n=i(66984),o=Object.prototype.hasOwnProperty;const a=function(t,e,i){var a=t[e];o.call(t,e)&&(0,n.A)(a,i)&&(void 0!==i||e in t)||(0,r.A)(t,e,i)}},52528:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=i(84171);const n=function(t,e,i){"__proto__"==e&&r.A?(0,r.A)(t,e,{configurable:!0,enumerable:!0,value:i,writable:!0}):t[e]=i}},4574:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){return function(e,i,r){for(var n=-1,o=Object(e),a=r(e),s=a.length;s--;){var l=a[t?s:++n];if(!1===i(o[l],l,o))break}return e}}()},88496:(t,e,i)=>{"use strict";i.d(e,{A:()=>d});var r=i(241),n=Object.prototype,o=n.hasOwnProperty,a=n.toString,s=r.A?r.A.toStringTag:void 0;const l=function(t){var e=o.call(t,s),i=t[s];try{t[s]=void 0;var r=!0}catch(l){}var n=a.call(t);return r&&(e?t[s]=i:delete t[s]),n};var c=Object.prototype.toString;const h=function(t){return c.call(t)};var u=r.A?r.A.toStringTag:void 0;const d=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":u&&u in Object(t)?l(t):h(t)}},69471:(t,e,i)=>{"use strict";i.d(e,{A:()=>a});var r=i(97271);const n=(0,i(40367).A)(Object.keys,Object);var o=Object.prototype.hasOwnProperty;const a=function(t){if(!(0,r.A)(t))return n(t);var e=[];for(var i in Object(t))o.call(t,i)&&"constructor"!=i&&e.push(i);return e}},24326:(t,e,i)=>{"use strict";i.d(e,{A:()=>a});var r=i(29008),n=i(76875),o=i(67525);const a=function(t,e){return(0,o.A)((0,n.A)(t,e,r.A),t+"")}},52789:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){return function(e){return t(e)}}},90565:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=i(43988);const n=function(t){var e=new t.constructor(t.byteLength);return new r.A(e).set(new r.A(t)),e}},80154:(t,e,i)=>{"use strict";i.d(e,{A:()=>l});var r=i(41917),n="object"==typeof exports&&exports&&!exports.nodeType&&exports,o=n&&"object"==typeof module&&module&&!module.nodeType&&module,a=o&&o.exports===n?r.A.Buffer:void 0,s=a?a.allocUnsafe:void 0;const l=function(t,e){if(e)return t.slice();var i=t.length,r=s?s(i):new t.constructor(i);return t.copy(r),r}},1801:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=i(90565);const n=function(t,e){var i=e?(0,r.A)(t.buffer):t.buffer;return new t.constructor(i,t.byteOffset,t.length)}},39759:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t,e){var i=-1,r=t.length;for(e||(e=Array(r));++i<r;)e[i]=t[i];return e}},22031:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(52851),n=i(52528);const o=function(t,e,i,o){var a=!i;i||(i={});for(var s=-1,l=e.length;++s<l;){var c=e[s],h=o?o(i[c],t[c],c,i,t):void 0;void 0===h&&(h=t[c]),a?(0,n.A)(i,c,h):(0,r.A)(i,c,h)}return i}},84171:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=i(18744);const n=function(){try{var t=(0,r.A)(Object,"defineProperty");return t({},"",{}),t}catch(e){}}()},72136:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r="object"==typeof global&&global&&global.Object===Object&&global},18744:(t,e,i)=>{"use strict";i.d(e,{A:()=>x});var r=i(89610);const n=i(41917).A["__core-js_shared__"];var o,a=(o=/[^.]+$/.exec(n&&n.keys&&n.keys.IE_PROTO||""))?"Symbol(src)_1."+o:"";const s=function(t){return!!a&&a in t};var l=i(23149),c=i(81121),h=/^\[object .+?Constructor\]$/,u=Function.prototype,d=Object.prototype,f=u.toString,p=d.hasOwnProperty,g=RegExp("^"+f.call(p).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");const m=function(t){return!(!(0,l.A)(t)||s(t))&&((0,r.A)(t)?g:h).test((0,c.A)(t))};const y=function(t,e){return null==t?void 0:t[e]};const x=function(t,e){var i=y(t,e);return m(i)?i:void 0}},15647:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=(0,i(40367).A)(Object.getPrototypeOf,Object)},9779:(t,e,i)=>{"use strict";i.d(e,{A:()=>k});var r=i(18744),n=i(41917);const o=(0,r.A)(n.A,"DataView");var a=i(68335);const s=(0,r.A)(n.A,"Promise");var l=i(39857);const c=(0,r.A)(n.A,"WeakMap");var h=i(88496),u=i(81121),d="[object Map]",f="[object Promise]",p="[object Set]",g="[object WeakMap]",m="[object DataView]",y=(0,u.A)(o),x=(0,u.A)(a.A),C=(0,u.A)(s),b=(0,u.A)(l.A),_=(0,u.A)(c),v=h.A;(o&&v(new o(new ArrayBuffer(1)))!=m||a.A&&v(new a.A)!=d||s&&v(s.resolve())!=f||l.A&&v(new l.A)!=p||c&&v(new c)!=g)&&(v=function(t){var e=(0,h.A)(t),i="[object Object]"==e?t.constructor:void 0,r=i?(0,u.A)(i):"";if(r)switch(r){case y:return m;case x:return d;case C:return f;case b:return p;case _:return g}return e});const k=v},18598:(t,e,i)=>{"use strict";i.d(e,{A:()=>l});var r=i(23149),n=Object.create;const o=function(){function t(){}return function(e){if(!(0,r.A)(e))return{};if(n)return n(e);t.prototype=e;var i=new t;return t.prototype=void 0,i}}();var a=i(15647),s=i(97271);const l=function(t){return"function"!=typeof t.constructor||(0,s.A)(t)?{}:o((0,a.A)(t))}},25353:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=/^(?:0|[1-9]\d*)$/;const n=function(t,e){var i=typeof t;return!!(e=null==e?9007199254740991:e)&&("number"==i||"symbol"!=i&&r.test(t))&&t>-1&&t%1==0&&t<e}},6832:(t,e,i)=>{"use strict";i.d(e,{A:()=>s});var r=i(66984),n=i(38446),o=i(25353),a=i(23149);const s=function(t,e,i){if(!(0,a.A)(i))return!1;var s=typeof e;return!!("number"==s?(0,n.A)(i)&&(0,o.A)(e,i.length):"string"==s&&e in i)&&(0,r.A)(i[e],t)}},97271:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=Object.prototype;const n=function(t){var e=t&&t.constructor;return t===("function"==typeof e&&e.prototype||r)}},64841:(t,e,i)=>{"use strict";i.d(e,{A:()=>s});var r=i(72136),n="object"==typeof exports&&exports&&!exports.nodeType&&exports,o=n&&"object"==typeof module&&module&&!module.nodeType&&module,a=o&&o.exports===n&&r.A.process;const s=function(){try{var t=o&&o.require&&o.require("util").types;return t||a&&a.binding&&a.binding("util")}catch(e){}}()},40367:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t,e){return function(i){return t(e(i))}}},76875:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});const r=function(t,e,i){switch(i.length){case 0:return t.call(e);case 1:return t.call(e,i[0]);case 2:return t.call(e,i[0],i[1]);case 3:return t.call(e,i[0],i[1],i[2])}return t.apply(e,i)};var n=Math.max;const o=function(t,e,i){return e=n(void 0===e?t.length-1:e,0),function(){for(var o=arguments,a=-1,s=n(o.length-e,0),l=Array(s);++a<s;)l[a]=o[e+a];a=-1;for(var c=Array(e+1);++a<e;)c[a]=o[a];return c[e]=i(l),r(t,this,c)}}},41917:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(72136),n="object"==typeof self&&self&&self.Object===Object&&self;const o=r.A||n||Function("return this")()},67525:(t,e,i)=>{"use strict";i.d(e,{A:()=>l});var r=i(39142),n=i(84171),o=i(29008);const a=n.A?function(t,e){return(0,n.A)(t,"toString",{configurable:!0,enumerable:!1,value:(0,r.A)(e),writable:!0})}:o.A;var s=Date.now;const l=function(t){var e=0,i=0;return function(){var r=s(),n=16-(r-i);if(i=r,n>0){if(++e>=800)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}(a)},81121:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=Function.prototype.toString;const n=function(t){if(null!=t){try{return r.call(t)}catch(e){}try{return t+""}catch(e){}}return""}},39142:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){return function(){return t}}},66984:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t,e){return t===e||t!=t&&e!=e}},29008:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){return t}},52274:(t,e,i)=>{"use strict";i.d(e,{A:()=>c});var r=i(88496),n=i(53098);const o=function(t){return(0,n.A)(t)&&"[object Arguments]"==(0,r.A)(t)};var a=Object.prototype,s=a.hasOwnProperty,l=a.propertyIsEnumerable;const c=o(function(){return arguments}())?o:function(t){return(0,n.A)(t)&&s.call(t,"callee")&&!l.call(t,"callee")}},92049:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=Array.isArray},38446:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(89610),n=i(5254);const o=function(t){return null!=t&&(0,n.A)(t.length)&&!(0,r.A)(t)}},53533:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(38446),n=i(53098);const o=function(t){return(0,n.A)(t)&&(0,r.A)(t)}},99912:(t,e,i)=>{"use strict";i.d(e,{A:()=>l});var r=i(41917);const n=function(){return!1};var o="object"==typeof exports&&exports&&!exports.nodeType&&exports,a=o&&"object"==typeof module&&module&&!module.nodeType&&module,s=a&&a.exports===o?r.A.Buffer:void 0;const l=(s?s.isBuffer:void 0)||n},66401:(t,e,i)=>{"use strict";i.d(e,{A:()=>d});var r=i(69471),n=i(9779),o=i(52274),a=i(92049),s=i(38446),l=i(99912),c=i(97271),h=i(33858),u=Object.prototype.hasOwnProperty;const d=function(t){if(null==t)return!0;if((0,s.A)(t)&&((0,a.A)(t)||"string"==typeof t||"function"==typeof t.splice||(0,l.A)(t)||(0,h.A)(t)||(0,o.A)(t)))return!t.length;var e=(0,n.A)(t);if("[object Map]"==e||"[object Set]"==e)return!t.size;if((0,c.A)(t))return!(0,r.A)(t).length;for(var i in t)if(u.call(t,i))return!1;return!0}},89610:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(88496),n=i(23149);const o=function(t){if(!(0,n.A)(t))return!1;var e=(0,r.A)(t);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e}},5254:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=9007199254740991}},23149:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},53098:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){return null!=t&&"object"==typeof t}},34963:(t,e,i)=>{"use strict";i.d(e,{A:()=>u});var r=i(88496),n=i(15647),o=i(53098),a=Function.prototype,s=Object.prototype,l=a.toString,c=s.hasOwnProperty,h=l.call(Object);const u=function(t){if(!(0,o.A)(t)||"[object Object]"!=(0,r.A)(t))return!1;var e=(0,n.A)(t);if(null===e)return!0;var i=c.call(e,"constructor")&&e.constructor;return"function"==typeof i&&i instanceof i&&l.call(i)==h}},33858:(t,e,i)=>{"use strict";i.d(e,{A:()=>u});var r=i(88496),n=i(5254),o=i(53098),a={};a["[object Float32Array]"]=a["[object Float64Array]"]=a["[object Int8Array]"]=a["[object Int16Array]"]=a["[object Int32Array]"]=a["[object Uint8Array]"]=a["[object Uint8ClampedArray]"]=a["[object Uint16Array]"]=a["[object Uint32Array]"]=!0,a["[object Arguments]"]=a["[object Array]"]=a["[object ArrayBuffer]"]=a["[object Boolean]"]=a["[object DataView]"]=a["[object Date]"]=a["[object Error]"]=a["[object Function]"]=a["[object Map]"]=a["[object Number]"]=a["[object Object]"]=a["[object RegExp]"]=a["[object Set]"]=a["[object String]"]=a["[object WeakMap]"]=!1;const s=function(t){return(0,o.A)(t)&&(0,n.A)(t.length)&&!!a[(0,r.A)(t)]};var l=i(52789),c=i(64841),h=c.A&&c.A.isTypedArray;const u=h?(0,l.A)(h):s},55615:(t,e,i)=>{"use strict";i.d(e,{A:()=>h});var r=i(83607),n=i(23149),o=i(97271);const a=function(t){var e=[];if(null!=t)for(var i in Object(t))e.push(i);return e};var s=Object.prototype.hasOwnProperty;const l=function(t){if(!(0,n.A)(t))return a(t);var e=(0,o.A)(t),i=[];for(var r in t)("constructor"!=r||!e&&s.call(t,r))&&i.push(r);return i};var c=i(38446);const h=function(t){return(0,c.A)(t)?(0,r.A)(t,!0):l(t)}},46632:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(29471);function n(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new TypeError("Expected a function");var i=function(){var r=arguments,n=e?e.apply(this,r):r[0],o=i.cache;if(o.has(n))return o.get(n);var a=t.apply(this,r);return i.cache=o.set(n,a)||o,a};return i.cache=new(n.Cache||r.A),i}n.Cache=r.A;const o=n},98879:(t,e,i)=>{"use strict";i.d(e,{A:()=>B});var r=i(11754),n=i(52528),o=i(66984);const a=function(t,e,i){(void 0!==i&&!(0,o.A)(t[e],i)||void 0===i&&!(e in t))&&(0,n.A)(t,e,i)};var s=i(4574),l=i(80154),c=i(1801),h=i(39759),u=i(18598),d=i(52274),f=i(92049),p=i(53533),g=i(99912),m=i(89610),y=i(23149),x=i(34963),C=i(33858);const b=function(t,e){if(("constructor"!==e||"function"!=typeof t[e])&&"__proto__"!=e)return t[e]};var _=i(22031),v=i(55615);const k=function(t){return(0,_.A)(t,(0,v.A)(t))};const T=function(t,e,i,r,n,o,s){var _=b(t,i),v=b(e,i),T=s.get(v);if(T)a(t,i,T);else{var A=o?o(_,v,i+"",t,e,s):void 0,w=void 0===A;if(w){var S=(0,f.A)(v),B=!S&&(0,g.A)(v),F=!S&&!B&&(0,C.A)(v);A=v,S||B||F?(0,f.A)(_)?A=_:(0,p.A)(_)?A=(0,h.A)(_):B?(w=!1,A=(0,l.A)(v,!0)):F?(w=!1,A=(0,c.A)(v,!0)):A=[]:(0,x.A)(v)||(0,d.A)(v)?(A=_,(0,d.A)(_)?A=k(_):(0,y.A)(_)&&!(0,m.A)(_)||(A=(0,u.A)(v))):w=!1}w&&(s.set(v,A),n(A,v,r,o,s),s.delete(v)),a(t,i,A)}};const A=function t(e,i,n,o,l){e!==i&&(0,s.A)(i,(function(s,c){if(l||(l=new r.A),(0,y.A)(s))T(e,i,c,n,t,o,l);else{var h=o?o(b(e,c),s,c+"",e,i,l):void 0;void 0===h&&(h=s),a(e,c,h)}}),v.A)};var w=i(24326),S=i(6832);const B=function(t){return(0,w.A)((function(e,i){var r=-1,n=i.length,o=n>1?i[n-1]:void 0,a=n>2?i[2]:void 0;for(o=t.length>3&&"function"==typeof o?(n--,o):void 0,a&&(0,S.A)(i[0],i[1],a)&&(o=n<3?void 0:o,n=1),e=Object(e);++r<n;){var s=i[r];s&&t(e,s,r,o)}return e}))}((function(t,e,i){A(t,e,i)}))},86079:(t,e,i)=>{"use strict";i.d(e,{A:()=>Hi,B:()=>Rt,C:()=>ve,D:()=>_e,E:()=>Ot,F:()=>Oe,G:()=>Tt,H:()=>At,I:()=>ue,J:()=>ht,K:()=>qi,L:()=>Ni,M:()=>Te,N:()=>co,Z:()=>ee,a:()=>Li,b:()=>Fi,c:()=>Ii,d:()=>pt,e:()=>St,f:()=>te,g:()=>Bi,h:()=>ye,i:()=>xi,j:()=>me,k:()=>ce,l:()=>st,m:()=>yt,n:()=>oe,o:()=>Ci,p:()=>Di,q:()=>Mi,r:()=>wt,s:()=>Si,t:()=>Ei,u:()=>ke,v:()=>wi,w:()=>pe,x:()=>xt,y:()=>de,z:()=>zi});var r=i(60513),n=i(74353),o=i(16750),a=i(26312),s=i(42838),l=i(74886),c=i(8232);const h=(t,e)=>{const i=l.A.parse(t),r={};for(const n in e)e[n]&&(r[n]=i[n]+e[n]);return(0,c.A)(t,r)};var u=i(25582);const d=(t,e,i=50)=>{const{r:r,g:n,b:o,a:a}=l.A.parse(t),{r:s,g:c,b:h,a:d}=l.A.parse(e),f=i/100,p=2*f-1,g=a-d,m=((p*g==-1?p:(p+g)/(1+p*g))+1)/2,y=1-m,x=r*m+s*y,C=n*m+c*y,b=o*m+h*y,_=a*f+d*(1-f);return(0,u.A)(x,C,b,_)},f=(t,e=100)=>{const i=l.A.parse(t);return i.r=255-i.r,i.g=255-i.g,i.b=255-i.b,d(i,t,e)};var p=i(75263),g=i(78041),m=i(3219),y=i(46632),x=i(98879),C="comm",b="rule",_="decl",v=Math.abs,k=String.fromCharCode;Object.assign;function T(t){return t.trim()}function A(t,e,i){return t.replace(e,i)}function w(t,e,i){return t.indexOf(e,i)}function S(t,e){return 0|t.charCodeAt(e)}function B(t,e,i){return t.slice(e,i)}function F(t){return t.length}function L(t,e){return e.push(t),t}function M(t,e){for(var i="",r=0;r<t.length;r++)i+=e(t[r],r,t,e)||"";return i}function E(t,e,i,r){switch(t.type){case"@layer":if(t.children.length)break;case"@import":case _:return t.return=t.return||t.value;case C:return"";case"@keyframes":return t.return=t.value+"{"+M(t.children,r)+"}";case b:if(!F(t.value=t.props.join(",")))return""}return F(i=M(t.children,r))?t.return=t.value+"{"+i+"}":""}var N=1,O=1,j=0,I=0,D=0,q="";function $(t,e,i,r,n,o,a,s){return{value:t,root:e,parent:i,type:r,props:n,children:o,line:N,column:O,length:a,return:"",siblings:s}}function z(){return D=I>0?S(q,--I):0,O--,10===D&&(O=1,N--),D}function P(){return D=I<j?S(q,I++):0,O++,10===D&&(O=1,N++),D}function R(){return S(q,I)}function W(){return I}function U(t,e){return B(q,t,e)}function H(t){switch(t){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}function Y(t){return N=O=1,j=F(q=t),I=0,[]}function V(t){return q="",t}function G(t){return T(U(I-1,J(91===t?t+2:40===t?t+1:t)))}function X(t){for(;(D=R())&&D<33;)P();return H(t)>2||H(D)>3?"":" "}function Z(t,e){for(;--e&&P()&&!(D<48||D>102||D>57&&D<65||D>70&&D<97););return U(t,W()+(e<6&&32==R()&&32==P()))}function J(t){for(;P();)switch(D){case t:return I;case 34:case 39:34!==t&&39!==t&&J(D);break;case 40:41===t&&J(t);break;case 92:P()}return I}function Q(t,e){for(;P()&&t+D!==57&&(t+D!==84||47!==R()););return"/*"+U(e,I-1)+"*"+k(47===t?t:P())}function K(t){for(;!H(R());)P();return U(t,I)}function tt(t){return V(et("",null,null,null,[""],t=Y(t),0,[0],t))}function et(t,e,i,r,n,o,a,s,l){for(var c=0,h=0,u=a,d=0,f=0,p=0,g=1,m=1,y=1,x=0,C="",b=n,_=o,T=r,B=C;m;)switch(p=x,x=P()){case 40:if(108!=p&&58==S(B,u-1)){-1!=w(B+=A(G(x),"&","&\f"),"&\f",v(c?s[c-1]:0))&&(y=-1);break}case 34:case 39:case 91:B+=G(x);break;case 9:case 10:case 13:case 32:B+=X(p);break;case 92:B+=Z(W()-1,7);continue;case 47:switch(R()){case 42:case 47:L(rt(Q(P(),W()),e,i,l),l);break;default:B+="/"}break;case 123*g:s[c++]=F(B)*y;case 125*g:case 59:case 0:switch(x){case 0:case 125:m=0;case 59+h:-1==y&&(B=A(B,/\f/g,"")),f>0&&F(B)-u&&L(f>32?nt(B+";",r,i,u-1,l):nt(A(B," ","")+";",r,i,u-2,l),l);break;case 59:B+=";";default:if(L(T=it(B,e,i,c,h,n,s,C,b=[],_=[],u,o),o),123===x)if(0===h)et(B,e,T,T,b,o,u,s,_);else switch(99===d&&110===S(B,3)?100:d){case 100:case 108:case 109:case 115:et(t,T,T,r&&L(it(t,T,T,0,0,n,s,C,n,b=[],u,_),_),n,_,u,s,r?b:_);break;default:et(B,T,T,T,[""],_,0,s,_)}}c=h=f=0,g=y=1,C=B="",u=a;break;case 58:u=1+F(B),f=p;default:if(g<1)if(123==x)--g;else if(125==x&&0==g++&&125==z())continue;switch(B+=k(x),x*g){case 38:y=h>0?1:(B+="\f",-1);break;case 44:s[c++]=(F(B)-1)*y,y=1;break;case 64:45===R()&&(B+=G(P())),d=R(),h=u=F(C=B+=K(W())),x++;break;case 45:45===p&&2==F(B)&&(g=0)}}return o}function it(t,e,i,r,n,o,a,s,l,c,h,u){for(var d=n-1,f=0===n?o:[""],p=function(t){return t.length}(f),g=0,m=0,y=0;g<r;++g)for(var x=0,C=B(t,d+1,d=v(m=a[g])),_=t;x<p;++x)(_=T(m>0?f[x]+" "+C:A(C,/&\f/g,f[x])))&&(l[y++]=_);return $(t,e,i,0===n?b:s,l,c,h,u)}function rt(t,e,i,r){return $(t,e,i,C,k(D),B(t,2,-2),0,r)}function nt(t,e,i,r,n){return $(t,e,i,_,B(t,0,r),B(t,r+1,-1),r,n)}var ot=i(66401);const at={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},st={trace:(...t)=>{},debug:(...t)=>{},info:(...t)=>{},warn:(...t)=>{},error:(...t)=>{},fatal:(...t)=>{}},lt=function(t="fatal"){let e=at.fatal;"string"==typeof t?(t=t.toLowerCase())in at&&(e=at[t]):"number"==typeof t&&(e=t),st.trace=()=>{},st.debug=()=>{},st.info=()=>{},st.warn=()=>{},st.error=()=>{},st.fatal=()=>{},e<=at.fatal&&(st.fatal=console.error?console.error.bind(console,ct("FATAL"),"color: orange"):console.log.bind(console,"\x1b[35m",ct("FATAL"))),e<=at.error&&(st.error=console.error?console.error.bind(console,ct("ERROR"),"color: orange"):console.log.bind(console,"\x1b[31m",ct("ERROR"))),e<=at.warn&&(st.warn=console.warn?console.warn.bind(console,ct("WARN"),"color: orange"):console.log.bind(console,"\x1b[33m",ct("WARN"))),e<=at.info&&(st.info=console.info?console.info.bind(console,ct("INFO"),"color: lightblue"):console.log.bind(console,"\x1b[34m",ct("INFO"))),e<=at.debug&&(st.debug=console.debug?console.debug.bind(console,ct("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",ct("DEBUG"))),e<=at.trace&&(st.trace=console.debug?console.debug.bind(console,ct("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",ct("TRACE")))},ct=t=>`%c${n().format("ss.SSS")} : ${t} : `,ht=/<br\s*\/?>/gi,ut=(()=>{let t=!1;return()=>{t||(!function(){const t="data-temp-href-target";s.addHook("beforeSanitizeAttributes",(e=>{"A"===e.tagName&&e.hasAttribute("target")&&e.setAttribute(t,e.getAttribute("target")||"")})),s.addHook("afterSanitizeAttributes",(e=>{"A"===e.tagName&&e.hasAttribute(t)&&(e.setAttribute("target",e.getAttribute(t)||""),e.removeAttribute(t),"_blank"===e.getAttribute("target")&&e.setAttribute("rel","noopener"))}))}(),t=!0)}})();const dt=t=>{ut();return s.sanitize(t)},ft=(t,e)=>{var i;if(!1!==(null==(i=e.flowchart)?void 0:i.htmlLabels)){const i=e.securityLevel;"antiscript"===i||"strict"===i?t=dt(t):"loose"!==i&&(t=(t=(t=mt(t)).replace(/</g,"<").replace(/>/g,">")).replace(/=/g,"="),t=gt(t))}return t},pt=(t,e)=>t?t=e.dompurifyConfig?s.sanitize(ft(t,e),e.dompurifyConfig).toString():s.sanitize(ft(t,e),{FORBID_TAGS:["style"]}).toString():t,gt=t=>t.replace(/#br#/g,"<br/>"),mt=t=>t.replace(ht,"#br#"),yt=t=>!1!==t&&!["false","null","0"].includes(String(t).trim().toLowerCase()),xt=function(t){const e=t.split(/(,)/),i=[];for(let r=0;r<e.length;r++){let t=e[r];if(","===t&&r>0&&r+1<e.length){const n=e[r-1],o=e[r+1];bt(n,o)&&(t=n+","+o,r++,i.pop())}i.push(_t(t))}return i.join("")},Ct=(t,e)=>Math.max(0,t.split(e).length-1),bt=(t,e)=>{const i=Ct(t,"~"),r=Ct(e,"~");return 1===i&&1===r},_t=t=>{const e=Ct(t,"~");let i=!1;if(e<=1)return t;e%2!=0&&t.startsWith("~")&&(t=t.substring(1),i=!0);const r=[...t];let n=r.indexOf("~"),o=r.lastIndexOf("~");for(;-1!==n&&-1!==o&&n!==o;)r[n]="<",r[o]=">",n=r.indexOf("~"),o=r.lastIndexOf("~");return i&&r.unshift("~"),r.join("")},vt=()=>void 0!==window.MathMLElement,kt=/\$\$(.*)\$\$/g,Tt=t=>{var e;return((null==(e=t.match(kt))?void 0:e.length)??0)>0},At=async(t,e)=>{t=await wt(t,e);const i=document.createElement("div");i.innerHTML=t,i.id="katex-temp",i.style.visibility="hidden",i.style.position="absolute",i.style.top="0";const r=document.querySelector("body");null==r||r.insertAdjacentElement("beforeend",i);const n={width:i.clientWidth,height:i.clientHeight};return i.remove(),n},wt=async(t,e)=>{if(!Tt(t))return t;if(!vt()&&!e.legacyMathML)return t.replace(kt,"MathML is unsupported in this environment.");const{default:r}=await i.e(22130).then(i.bind(i,22130));return t.split(ht).map((t=>Tt(t)?`\n <div style="display: flex; align-items: center; justify-content: center; white-space: nowrap;">\n ${t}\n </div>\n `:`<div>${t}</div>`)).join("").replace(kt,((t,e)=>r.renderToString(e,{throwOnError:!0,displayMode:!0,output:vt()?"mathml":"htmlAndMathml"}).replace(/\n/g," ").replace(/<annotation.*<\/annotation>/g,"")))},St={getRows:t=>{if(!t)return[""];return mt(t).replace(/\\n/g,"#br#").split("#br#")},sanitizeText:pt,sanitizeTextOrArray:(t,e)=>"string"==typeof t?pt(t,e):t.flat().map((t=>pt(t,e))),hasBreaks:t=>ht.test(t),splitBreaks:t=>t.split(ht),lineBreakRegex:ht,removeScript:dt,getUrl:t=>{let e="";return t&&(e=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,e=e.replaceAll(/\(/g,"\\("),e=e.replaceAll(/\)/g,"\\)")),e},evaluate:yt,getMax:function(...t){const e=t.filter((t=>!isNaN(t)));return Math.max(...e)},getMin:function(...t){const e=t.filter((t=>!isNaN(t)));return Math.min(...e)}},Bt=(t,e)=>h(t,e?{s:-40,l:10}:{s:-40,l:-10}),Ft="#ffffff",Lt="#f2f2f2";let Mt=class{constructor(){this.background="#f4f4f4",this.primaryColor="#fff4dd",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px"}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||h(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||h(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||Bt(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||Bt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||Bt(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||Bt(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||f(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||f(this.tertiaryColor),this.lineColor=this.lineColor||f(this.background),this.arrowheadColor=this.arrowheadColor||f(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?(0,p.A)(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||"grey",this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||(0,p.A)(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||f(this.lineColor),this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||(0,g.A)(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||this.tertiaryColor,this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||h(this.primaryColor,{h:30}),this.cScale4=this.cScale4||h(this.primaryColor,{h:60}),this.cScale5=this.cScale5||h(this.primaryColor,{h:90}),this.cScale6=this.cScale6||h(this.primaryColor,{h:120}),this.cScale7=this.cScale7||h(this.primaryColor,{h:150}),this.cScale8=this.cScale8||h(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||h(this.primaryColor,{h:270}),this.cScale10=this.cScale10||h(this.primaryColor,{h:300}),this.cScale11=this.cScale11||h(this.primaryColor,{h:330}),this.darkMode)for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScale"+h]=(0,p.A)(this["cScale"+h],75);else for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScale"+h]=(0,p.A)(this["cScale"+h],25);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleInv"+h]=this["cScaleInv"+h]||f(this["cScale"+h]);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this.darkMode?this["cScalePeer"+h]=this["cScalePeer"+h]||(0,g.A)(this["cScale"+h],10):this["cScalePeer"+h]=this["cScalePeer"+h]||(0,p.A)(this["cScale"+h],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleLabel"+h]=this["cScaleLabel"+h]||this.scaleLabelColor;const d=this.darkMode?-4:-1;for(let f=0;f<5;f++)this["surface"+f]=this["surface"+f]||h(this.mainBkg,{h:180,s:-15,l:d*(5+3*f)}),this["surfacePeer"+f]=this["surfacePeer"+f]||h(this.mainBkg,{h:180,s:-15,l:d*(8+3*f)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||this.primaryColor,this.fillType1=this.fillType1||this.secondaryColor,this.fillType2=this.fillType2||h(this.primaryColor,{h:64}),this.fillType3=this.fillType3||h(this.secondaryColor,{h:64}),this.fillType4=this.fillType4||h(this.primaryColor,{h:-64}),this.fillType5=this.fillType5||h(this.secondaryColor,{h:-64}),this.fillType6=this.fillType6||h(this.primaryColor,{h:128}),this.fillType7=this.fillType7||h(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||h(this.primaryColor,{l:-10}),this.pie5=this.pie5||h(this.secondaryColor,{l:-10}),this.pie6=this.pie6||h(this.tertiaryColor,{l:-10}),this.pie7=this.pie7||h(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||h(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||h(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||h(this.primaryColor,{h:60,l:-20}),this.pie11=this.pie11||h(this.primaryColor,{h:-60,l:-20}),this.pie12=this.pie12||h(this.primaryColor,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.A)(this.quadrant1Fill)?(0,g.A)(this.quadrant1Fill):(0,p.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?(0,p.A)(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||h(this.primaryColor,{h:-30}),this.git4=this.git4||h(this.primaryColor,{h:-60}),this.git5=this.git5||h(this.primaryColor,{h:-90}),this.git6=this.git6||h(this.primaryColor,{h:60}),this.git7=this.git7||h(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,g.A)(this.git0,25),this.git1=(0,g.A)(this.git1,25),this.git2=(0,g.A)(this.git2,25),this.git3=(0,g.A)(this.git3,25),this.git4=(0,g.A)(this.git4,25),this.git5=(0,g.A)(this.git5,25),this.git6=(0,g.A)(this.git6,25),this.git7=(0,g.A)(this.git7,25)):(this.git0=(0,p.A)(this.git0,25),this.git1=(0,p.A)(this.git1,25),this.git2=(0,p.A)(this.git2,25),this.git3=(0,p.A)(this.git3,25),this.git4=(0,p.A)(this.git4,25),this.git5=(0,p.A)(this.git5,25),this.git6=(0,p.A)(this.git6,25),this.git7=(0,p.A)(this.git7,25)),this.gitInv0=this.gitInv0||f(this.git0),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||Ft,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Lt}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};let Et=class{constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=(0,g.A)(this.primaryColor,16),this.tertiaryColor=h(this.primaryColor,{h:-160}),this.primaryBorderColor=f(this.background),this.secondaryBorderColor=Bt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Bt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.tertiaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=(0,g.A)(f("#323D47"),10),this.lineColor="calculated",this.border1="#81B1DB",this.border2=(0,u.A)(255,255,255,.25),this.arrowheadColor="calculated",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#F9FFFE",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="calculated",this.activationBkgColor="calculated",this.sequenceNumberColor="black",this.sectionBkgColor=(0,p.A)("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.excludeBkgColor=(0,p.A)(this.sectionBkgColor,10),this.taskBorderColor=(0,u.A)(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=(0,u.A)(255,255,255,50),this.activeTaskBkgColor="#81B1DB",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="grey",this.critBorderColor="#E83737",this.critBkgColor="#E83737",this.taskTextDarkColor="calculated",this.todayLineColor="#DB5757",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd"}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;this.secondBkg=(0,g.A)(this.mainBkg,16),this.lineColor=this.mainContrastColor,this.arrowheadColor=this.mainContrastColor,this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.edgeLabelBackground=(0,g.A)(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.mainContrastColor,this.signalColor=this.mainContrastColor,this.signalTextColor=this.mainContrastColor,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.mainContrastColor,this.loopTextColor=this.mainContrastColor,this.noteBorderColor=this.secondaryBorderColor,this.noteBkgColor=this.secondBkg,this.noteTextColor=this.secondaryTextColor,this.activationBorderColor=this.border1,this.activationBkgColor=this.secondBkg,this.altSectionBkgColor=this.background,this.taskBkgColor=(0,g.A)(this.mainBkg,23),this.taskTextColor=this.darkTextColor,this.taskTextLightColor=this.mainContrastColor,this.taskTextOutsideColor=this.taskTextLightColor,this.gridColor=this.mainContrastColor,this.doneTaskBkgColor=this.mainContrastColor,this.taskTextDarkColor=this.darkTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#555",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#f4f4f4",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=h(this.primaryColor,{h:64}),this.fillType3=h(this.secondaryColor,{h:64}),this.fillType4=h(this.primaryColor,{h:-64}),this.fillType5=h(this.secondaryColor,{h:-64}),this.fillType6=h(this.primaryColor,{h:128}),this.fillType7=h(this.secondaryColor,{h:128}),this.cScale1=this.cScale1||"#0b0000",this.cScale2=this.cScale2||"#4d1037",this.cScale3=this.cScale3||"#3f5258",this.cScale4=this.cScale4||"#4f2f1b",this.cScale5=this.cScale5||"#6e0a0a",this.cScale6=this.cScale6||"#3b0048",this.cScale7=this.cScale7||"#995a01",this.cScale8=this.cScale8||"#154706",this.cScale9=this.cScale9||"#161722",this.cScale10=this.cScale10||"#00296f",this.cScale11=this.cScale11||"#01629c",this.cScale12=this.cScale12||"#010029",this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||h(this.primaryColor,{h:30}),this.cScale4=this.cScale4||h(this.primaryColor,{h:60}),this.cScale5=this.cScale5||h(this.primaryColor,{h:90}),this.cScale6=this.cScale6||h(this.primaryColor,{h:120}),this.cScale7=this.cScale7||h(this.primaryColor,{h:150}),this.cScale8=this.cScale8||h(this.primaryColor,{h:210}),this.cScale9=this.cScale9||h(this.primaryColor,{h:270}),this.cScale10=this.cScale10||h(this.primaryColor,{h:300}),this.cScale11=this.cScale11||h(this.primaryColor,{h:330});for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleInv"+h]=this["cScaleInv"+h]||f(this["cScale"+h]);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScalePeer"+h]=this["cScalePeer"+h]||(0,g.A)(this["cScale"+h],10);for(let d=0;d<5;d++)this["surface"+d]=this["surface"+d]||h(this.mainBkg,{h:30,s:-30,l:-(4*d-10)}),this["surfacePeer"+d]=this["surfacePeer"+d]||h(this.mainBkg,{h:30,s:-30,l:-(4*d-7)});this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleLabel"+h]=this["cScaleLabel"+h]||this.scaleLabelColor;for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["pie"+h]=this["cScale"+h];this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.A)(this.quadrant1Fill)?(0,g.A)(this.quadrant1Fill):(0,p.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#3498db,#2ecc71,#e74c3c,#f1c40f,#bdc3c7,#ffffff,#34495e,#9b59b6,#1abc9c,#e67e22"},this.classText=this.primaryTextColor,this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?(0,p.A)(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=(0,g.A)(this.secondaryColor,20),this.git1=(0,g.A)(this.pie2||this.secondaryColor,20),this.git2=(0,g.A)(this.pie3||this.tertiaryColor,20),this.git3=(0,g.A)(this.pie4||h(this.primaryColor,{h:-30}),20),this.git4=(0,g.A)(this.pie5||h(this.primaryColor,{h:-60}),20),this.git5=(0,g.A)(this.pie6||h(this.primaryColor,{h:-90}),10),this.git6=(0,g.A)(this.pie7||h(this.primaryColor,{h:60}),10),this.git7=(0,g.A)(this.pie8||h(this.primaryColor,{h:120}),20),this.gitInv0=this.gitInv0||f(this.git0),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||f(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||f(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||(0,g.A)(this.background,12),this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||(0,g.A)(this.background,2)}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};let Nt=class{constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=h(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=h(this.primaryColor,{h:-160}),this.primaryBorderColor=Bt(this.primaryColor,this.darkMode),this.secondaryBorderColor=Bt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Bt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.tertiaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.background="white",this.mainBkg="#ECECFF",this.secondBkg="#ffffde",this.lineColor="#333333",this.border1="#9370DB",this.border2="#aaaa33",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#e8e8e8",this.textColor="#333",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="grey",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="calculated",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="calculated",this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor="calculated",this.taskTextOutsideColor=this.taskTextDarkColor,this.taskTextClickableColor="calculated",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBorderColor="calculated",this.critBkgColor="calculated",this.todayLineColor="calculated",this.sectionBkgColor=(0,u.A)(102,102,255,.49),this.altSectionBkgColor="white",this.sectionBkgColor2="#fff400",this.taskBorderColor="#534fbc",this.taskBkgColor="#8a90dd",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="#534fbc",this.activeTaskBkgColor="#bfc7ff",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.updateColors()}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||h(this.primaryColor,{h:30}),this.cScale4=this.cScale4||h(this.primaryColor,{h:60}),this.cScale5=this.cScale5||h(this.primaryColor,{h:90}),this.cScale6=this.cScale6||h(this.primaryColor,{h:120}),this.cScale7=this.cScale7||h(this.primaryColor,{h:150}),this.cScale8=this.cScale8||h(this.primaryColor,{h:210}),this.cScale9=this.cScale9||h(this.primaryColor,{h:270}),this.cScale10=this.cScale10||h(this.primaryColor,{h:300}),this.cScale11=this.cScale11||h(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||(0,p.A)(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||(0,p.A)(this.tertiaryColor,40);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScale"+h]=(0,p.A)(this["cScale"+h],10),this["cScalePeer"+h]=this["cScalePeer"+h]||(0,p.A)(this["cScale"+h],25);for(let d=0;d<this.THEME_COLOR_LIMIT;d++)this["cScaleInv"+d]=this["cScaleInv"+d]||h(this["cScale"+d],{h:180});for(let d=0;d<5;d++)this["surface"+d]=this["surface"+d]||h(this.mainBkg,{h:30,l:-(5+5*d)}),this["surfacePeer"+d]=this["surfacePeer"+d]||h(this.mainBkg,{h:30,l:-(7+5*d)});if(this.scaleLabelColor="calculated"!==this.scaleLabelColor&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor,"calculated"!==this.labelTextColor){this.cScaleLabel0=this.cScaleLabel0||f(this.labelTextColor),this.cScaleLabel3=this.cScaleLabel3||f(this.labelTextColor);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.labelTextColor}this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.textColor,this.edgeLabelBackground=this.labelBackground,this.actorBorder=(0,g.A)(this.border1,23),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.signalColor=this.textColor,this.signalTextColor=this.textColor,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=h(this.primaryColor,{h:64}),this.fillType3=h(this.secondaryColor,{h:64}),this.fillType4=h(this.primaryColor,{h:-64}),this.fillType5=h(this.secondaryColor,{h:-64}),this.fillType6=h(this.primaryColor,{h:128}),this.fillType7=h(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||h(this.tertiaryColor,{l:-40}),this.pie4=this.pie4||h(this.primaryColor,{l:-10}),this.pie5=this.pie5||h(this.secondaryColor,{l:-30}),this.pie6=this.pie6||h(this.tertiaryColor,{l:-20}),this.pie7=this.pie7||h(this.primaryColor,{h:60,l:-20}),this.pie8=this.pie8||h(this.primaryColor,{h:-60,l:-40}),this.pie9=this.pie9||h(this.primaryColor,{h:120,l:-40}),this.pie10=this.pie10||h(this.primaryColor,{h:60,l:-40}),this.pie11=this.pie11||h(this.primaryColor,{h:-90,l:-40}),this.pie12=this.pie12||h(this.primaryColor,{h:120,l:-30}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.A)(this.quadrant1Fill)?(0,g.A)(this.quadrant1Fill):(0,p.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#ECECFF,#8493A6,#FFC3A0,#DCDDE1,#B8E994,#D1A36F,#C3CDE6,#FFB6C1,#496078,#F8F3E3"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.labelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||h(this.primaryColor,{h:-30}),this.git4=this.git4||h(this.primaryColor,{h:-60}),this.git5=this.git5||h(this.primaryColor,{h:-90}),this.git6=this.git6||h(this.primaryColor,{h:60}),this.git7=this.git7||h(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,g.A)(this.git0,25),this.git1=(0,g.A)(this.git1,25),this.git2=(0,g.A)(this.git2,25),this.git3=(0,g.A)(this.git3,25),this.git4=(0,g.A)(this.git4,25),this.git5=(0,g.A)(this.git5,25),this.git6=(0,g.A)(this.git6,25),this.git7=(0,g.A)(this.git7,25)):(this.git0=(0,p.A)(this.git0,25),this.git1=(0,p.A)(this.git1,25),this.git2=(0,p.A)(this.git2,25),this.git3=(0,p.A)(this.git3,25),this.git4=(0,p.A)(this.git4,25),this.git5=(0,p.A)(this.git5,25),this.git6=(0,p.A)(this.git6,25),this.git7=(0,p.A)(this.git7,25)),this.gitInv0=this.gitInv0||(0,p.A)(f(this.git0),25),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||f(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||f(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||Ft,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Lt}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};const Ot=t=>{const e=new Nt;return e.calculate(t),e};let jt=class{constructor(){this.background="#f4f4f4",this.primaryColor="#cde498",this.secondaryColor="#cdffb2",this.background="white",this.mainBkg="#cde498",this.secondBkg="#cdffb2",this.lineColor="green",this.border1="#13540c",this.border2="#6eaa49",this.arrowheadColor="green",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.tertiaryColor=(0,g.A)("#cde498",10),this.primaryBorderColor=Bt(this.primaryColor,this.darkMode),this.secondaryBorderColor=Bt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Bt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.primaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#333",this.edgeLabelBackground="#e8e8e8",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="grey",this.signalColor="#333",this.signalTextColor="#333",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="#326932",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="#6eaa49",this.altSectionBkgColor="white",this.sectionBkgColor2="#6eaa49",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="#487e3a",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;this.actorBorder=(0,p.A)(this.mainBkg,20),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||h(this.primaryColor,{h:30}),this.cScale4=this.cScale4||h(this.primaryColor,{h:60}),this.cScale5=this.cScale5||h(this.primaryColor,{h:90}),this.cScale6=this.cScale6||h(this.primaryColor,{h:120}),this.cScale7=this.cScale7||h(this.primaryColor,{h:150}),this.cScale8=this.cScale8||h(this.primaryColor,{h:210}),this.cScale9=this.cScale9||h(this.primaryColor,{h:270}),this.cScale10=this.cScale10||h(this.primaryColor,{h:300}),this.cScale11=this.cScale11||h(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||(0,p.A)(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||(0,p.A)(this.tertiaryColor,40);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScale"+h]=(0,p.A)(this["cScale"+h],10),this["cScalePeer"+h]=this["cScalePeer"+h]||(0,p.A)(this["cScale"+h],25);for(let d=0;d<this.THEME_COLOR_LIMIT;d++)this["cScaleInv"+d]=this["cScaleInv"+d]||h(this["cScale"+d],{h:180});this.scaleLabelColor="calculated"!==this.scaleLabelColor&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor;for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleLabel"+h]=this["cScaleLabel"+h]||this.scaleLabelColor;for(let d=0;d<5;d++)this["surface"+d]=this["surface"+d]||h(this.mainBkg,{h:30,s:-30,l:-(5+5*d)}),this["surfacePeer"+d]=this["surfacePeer"+d]||h(this.mainBkg,{h:30,s:-30,l:-(8+5*d)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.taskBorderColor=this.border1,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=h(this.primaryColor,{h:64}),this.fillType3=h(this.secondaryColor,{h:64}),this.fillType4=h(this.primaryColor,{h:-64}),this.fillType5=h(this.secondaryColor,{h:-64}),this.fillType6=h(this.primaryColor,{h:128}),this.fillType7=h(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||h(this.primaryColor,{l:-30}),this.pie5=this.pie5||h(this.secondaryColor,{l:-30}),this.pie6=this.pie6||h(this.tertiaryColor,{h:40,l:-40}),this.pie7=this.pie7||h(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||h(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||h(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||h(this.primaryColor,{h:60,l:-50}),this.pie11=this.pie11||h(this.primaryColor,{h:-60,l:-50}),this.pie12=this.pie12||h(this.primaryColor,{h:120,l:-50}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.A)(this.quadrant1Fill)?(0,g.A)(this.quadrant1Fill):(0,p.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#CDE498,#FF6B6B,#A0D2DB,#D7BDE2,#F0F0F0,#FFC3A0,#7FD8BE,#FF9A8B,#FAF3E0,#FFF176"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||h(this.primaryColor,{h:-30}),this.git4=this.git4||h(this.primaryColor,{h:-60}),this.git5=this.git5||h(this.primaryColor,{h:-90}),this.git6=this.git6||h(this.primaryColor,{h:60}),this.git7=this.git7||h(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,g.A)(this.git0,25),this.git1=(0,g.A)(this.git1,25),this.git2=(0,g.A)(this.git2,25),this.git3=(0,g.A)(this.git3,25),this.git4=(0,g.A)(this.git4,25),this.git5=(0,g.A)(this.git5,25),this.git6=(0,g.A)(this.git6,25),this.git7=(0,g.A)(this.git7,25)):(this.git0=(0,p.A)(this.git0,25),this.git1=(0,p.A)(this.git1,25),this.git2=(0,p.A)(this.git2,25),this.git3=(0,p.A)(this.git3,25),this.git4=(0,p.A)(this.git4,25),this.git5=(0,p.A)(this.git5,25),this.git6=(0,p.A)(this.git6,25),this.git7=(0,p.A)(this.git7,25)),this.gitInv0=this.gitInv0||f(this.git0),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||f(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||f(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||Ft,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Lt}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};class It{constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=(0,g.A)(this.contrast,55),this.background="#ffffff",this.tertiaryColor=h(this.primaryColor,{h:-160}),this.primaryBorderColor=Bt(this.primaryColor,this.darkMode),this.secondaryBorderColor=Bt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Bt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.tertiaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.mainBkg="#eee",this.secondBkg="calculated",this.lineColor="#666",this.border1="#999",this.border2="calculated",this.note="#ffa",this.text="#333",this.critical="#d42",this.done="#bbb",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="white",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="calculated",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="white",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBkgColor="calculated",this.critBorderColor="calculated",this.todayLineColor="calculated",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;this.secondBkg=(0,g.A)(this.contrast,55),this.border2=this.contrast,this.actorBorder=(0,g.A)(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.lineColor,this.signalColor=this.text,this.signalTextColor=this.text,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.text,this.loopTextColor=this.text,this.noteBorderColor="#999",this.noteBkgColor="#666",this.noteTextColor="#fff",this.cScale0=this.cScale0||"#555",this.cScale1=this.cScale1||"#F4F4F4",this.cScale2=this.cScale2||"#555",this.cScale3=this.cScale3||"#BBB",this.cScale4=this.cScale4||"#777",this.cScale5=this.cScale5||"#999",this.cScale6=this.cScale6||"#DDD",this.cScale7=this.cScale7||"#FFF",this.cScale8=this.cScale8||"#DDD",this.cScale9=this.cScale9||"#BBB",this.cScale10=this.cScale10||"#999",this.cScale11=this.cScale11||"#777";for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleInv"+h]=this["cScaleInv"+h]||f(this["cScale"+h]);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this.darkMode?this["cScalePeer"+h]=this["cScalePeer"+h]||(0,g.A)(this["cScale"+h],10):this["cScalePeer"+h]=this["cScalePeer"+h]||(0,p.A)(this["cScale"+h],10);this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor),this.cScaleLabel0=this.cScaleLabel0||this.cScale1,this.cScaleLabel2=this.cScaleLabel2||this.cScale1;for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleLabel"+h]=this["cScaleLabel"+h]||this.scaleLabelColor;for(let d=0;d<5;d++)this["surface"+d]=this["surface"+d]||h(this.mainBkg,{l:-(5+5*d)}),this["surfacePeer"+d]=this["surfacePeer"+d]||h(this.mainBkg,{l:-(8+5*d)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.text,this.sectionBkgColor=(0,g.A)(this.contrast,30),this.sectionBkgColor2=(0,g.A)(this.contrast,30),this.taskBorderColor=(0,p.A)(this.contrast,10),this.taskBkgColor=this.contrast,this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor=this.text,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.gridColor=(0,g.A)(this.border1,30),this.doneTaskBkgColor=this.done,this.doneTaskBorderColor=this.lineColor,this.critBkgColor=this.critical,this.critBorderColor=(0,p.A)(this.critBkgColor,10),this.todayLineColor=this.critBkgColor,this.transitionColor=this.transitionColor||"#000",this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f4f4f4",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.stateBorder=this.stateBorder||"#000",this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#222",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=h(this.primaryColor,{h:64}),this.fillType3=h(this.secondaryColor,{h:64}),this.fillType4=h(this.primaryColor,{h:-64}),this.fillType5=h(this.secondaryColor,{h:-64}),this.fillType6=h(this.primaryColor,{h:128}),this.fillType7=h(this.secondaryColor,{h:128});for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["pie"+h]=this["cScale"+h];this.pie12=this.pie0,this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.A)(this.quadrant1Fill)?(0,g.A)(this.quadrant1Fill):(0,p.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#EEE,#6BB8E4,#8ACB88,#C7ACD6,#E8DCC2,#FFB2A8,#FFF380,#7E8D91,#FFD8B1,#FAF3E0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=(0,p.A)(this.pie1,25)||this.primaryColor,this.git1=this.pie2||this.secondaryColor,this.git2=this.pie3||this.tertiaryColor,this.git3=this.pie4||h(this.primaryColor,{h:-30}),this.git4=this.pie5||h(this.primaryColor,{h:-60}),this.git5=this.pie6||h(this.primaryColor,{h:-90}),this.git6=this.pie7||h(this.primaryColor,{h:60}),this.git7=this.pie8||h(this.primaryColor,{h:120}),this.gitInv0=this.gitInv0||f(this.git0),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.branchLabelColor=this.branchLabelColor||this.labelTextColor,this.gitBranchLabel0=this.branchLabelColor,this.gitBranchLabel1="white",this.gitBranchLabel2=this.branchLabelColor,this.gitBranchLabel3="white",this.gitBranchLabel4=this.branchLabelColor,this.gitBranchLabel5=this.branchLabelColor,this.gitBranchLabel6=this.branchLabelColor,this.gitBranchLabel7=this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||Ft,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Lt}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}}const Dt={base:{getThemeVariables:t=>{const e=new Mt;return e.calculate(t),e}},dark:{getThemeVariables:t=>{const e=new Et;return e.calculate(t),e}},default:{getThemeVariables:Ot},forest:{getThemeVariables:t=>{const e=new jt;return e.calculate(t),e}},neutral:{getThemeVariables:t=>{const e=new It;return e.calculate(t),e}}},qt={flowchart:{useMaxWidth:!0,titleTopMargin:25,subGraphTitleMargin:{top:0,bottom:0},diagramPadding:8,htmlLabels:!0,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,defaultRenderer:"dagre-wrapper",wrappingWidth:200},sequence:{useMaxWidth:!0,hideUnusedParticipants:!1,activationWidth:10,diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",mirrorActors:!0,forceMenus:!1,bottomMarginAdj:1,rightAngles:!1,showSequenceNumbers:!1,actorFontSize:14,actorFontFamily:'"Open Sans", sans-serif',actorFontWeight:400,noteFontSize:14,noteFontFamily:'"trebuchet ms", verdana, arial, sans-serif',noteFontWeight:400,noteAlign:"center",messageFontSize:16,messageFontFamily:'"trebuchet ms", verdana, arial, sans-serif',messageFontWeight:400,wrap:!1,wrapPadding:10,labelBoxWidth:50,labelBoxHeight:20},gantt:{useMaxWidth:!0,titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,axisFormat:"%Y-%m-%d",topAxis:!1,displayMode:"",weekday:"sunday"},journey:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"]},class:{useMaxWidth:!0,titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,defaultRenderer:"dagre-wrapper",htmlLabels:!1},state:{useMaxWidth:!0,titleTopMargin:25,dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,defaultRenderer:"dagre-wrapper"},er:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,stroke:"gray",fill:"honeydew",fontSize:12},pie:{useMaxWidth:!0,textPosition:.75},quadrantChart:{useMaxWidth:!0,chartWidth:500,chartHeight:500,titleFontSize:20,titlePadding:10,quadrantPadding:5,xAxisLabelPadding:5,yAxisLabelPadding:5,xAxisLabelFontSize:16,yAxisLabelFontSize:16,quadrantLabelFontSize:16,quadrantTextTopPadding:5,pointTextPadding:5,pointLabelFontSize:12,pointRadius:5,xAxisPosition:"top",yAxisPosition:"left",quadrantInternalBorderStrokeWidth:1,quadrantExternalBorderStrokeWidth:2},xyChart:{useMaxWidth:!0,width:700,height:500,titleFontSize:20,titlePadding:10,showTitle:!0,xAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},yAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},chartOrientation:"vertical",plotReservedSpacePercent:50},requirement:{useMaxWidth:!0,rect_fill:"#f9f9f9",text_color:"#333",rect_border_size:"0.5px",rect_border_color:"#bbb",rect_min_width:200,rect_min_height:200,fontSize:14,rect_padding:10,line_height:20},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200},timeline:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],disableMulticolor:!1},gitGraph:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0,parallelCommits:!1,arrowMarkerAbsolute:!1},c4:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,c4ShapeInRow:4,nextLinePaddingX:0,c4BoundaryInRow:2,personFontSize:14,personFontFamily:'"Open Sans", sans-serif',personFontWeight:"normal",external_personFontSize:14,external_personFontFamily:'"Open Sans", sans-serif',external_personFontWeight:"normal",systemFontSize:14,systemFontFamily:'"Open Sans", sans-serif',systemFontWeight:"normal",external_systemFontSize:14,external_systemFontFamily:'"Open Sans", sans-serif',external_systemFontWeight:"normal",system_dbFontSize:14,system_dbFontFamily:'"Open Sans", sans-serif',system_dbFontWeight:"normal",external_system_dbFontSize:14,external_system_dbFontFamily:'"Open Sans", sans-serif',external_system_dbFontWeight:"normal",system_queueFontSize:14,system_queueFontFamily:'"Open Sans", sans-serif',system_queueFontWeight:"normal",external_system_queueFontSize:14,external_system_queueFontFamily:'"Open Sans", sans-serif',external_system_queueFontWeight:"normal",boundaryFontSize:14,boundaryFontFamily:'"Open Sans", sans-serif',boundaryFontWeight:"normal",messageFontSize:12,messageFontFamily:'"Open Sans", sans-serif',messageFontWeight:"normal",containerFontSize:14,containerFontFamily:'"Open Sans", sans-serif',containerFontWeight:"normal",external_containerFontSize:14,external_containerFontFamily:'"Open Sans", sans-serif',external_containerFontWeight:"normal",container_dbFontSize:14,container_dbFontFamily:'"Open Sans", sans-serif',container_dbFontWeight:"normal",external_container_dbFontSize:14,external_container_dbFontFamily:'"Open Sans", sans-serif',external_container_dbFontWeight:"normal",container_queueFontSize:14,container_queueFontFamily:'"Open Sans", sans-serif',container_queueFontWeight:"normal",external_container_queueFontSize:14,external_container_queueFontFamily:'"Open Sans", sans-serif',external_container_queueFontWeight:"normal",componentFontSize:14,componentFontFamily:'"Open Sans", sans-serif',componentFontWeight:"normal",external_componentFontSize:14,external_componentFontFamily:'"Open Sans", sans-serif',external_componentFontWeight:"normal",component_dbFontSize:14,component_dbFontFamily:'"Open Sans", sans-serif',component_dbFontWeight:"normal",external_component_dbFontSize:14,external_component_dbFontFamily:'"Open Sans", sans-serif',external_component_dbFontWeight:"normal",component_queueFontSize:14,component_queueFontFamily:'"Open Sans", sans-serif',component_queueFontWeight:"normal",external_component_queueFontSize:14,external_component_queueFontFamily:'"Open Sans", sans-serif',external_component_queueFontWeight:"normal",wrap:!0,wrapPadding:10,person_bg_color:"#08427B",person_border_color:"#073B6F",external_person_bg_color:"#686868",external_person_border_color:"#8A8A8A",system_bg_color:"#1168BD",system_border_color:"#3C7FC0",system_db_bg_color:"#1168BD",system_db_border_color:"#3C7FC0",system_queue_bg_color:"#1168BD",system_queue_border_color:"#3C7FC0",external_system_bg_color:"#999999",external_system_border_color:"#8A8A8A",external_system_db_bg_color:"#999999",external_system_db_border_color:"#8A8A8A",external_system_queue_bg_color:"#999999",external_system_queue_border_color:"#8A8A8A",container_bg_color:"#438DD5",container_border_color:"#3C7FC0",container_db_bg_color:"#438DD5",container_db_border_color:"#3C7FC0",container_queue_bg_color:"#438DD5",container_queue_border_color:"#3C7FC0",external_container_bg_color:"#B3B3B3",external_container_border_color:"#A6A6A6",external_container_db_bg_color:"#B3B3B3",external_container_db_border_color:"#A6A6A6",external_container_queue_bg_color:"#B3B3B3",external_container_queue_border_color:"#A6A6A6",component_bg_color:"#85BBF0",component_border_color:"#78A8D8",component_db_bg_color:"#85BBF0",component_db_border_color:"#78A8D8",component_queue_bg_color:"#85BBF0",component_queue_border_color:"#78A8D8",external_component_bg_color:"#CCCCCC",external_component_border_color:"#BFBFBF",external_component_db_bg_color:"#CCCCCC",external_component_db_border_color:"#BFBFBF",external_component_queue_bg_color:"#CCCCCC",external_component_queue_border_color:"#BFBFBF"},sankey:{useMaxWidth:!0,width:600,height:400,linkColor:"gradient",nodeAlignment:"justify",showValues:!0,prefix:"",suffix:""},block:{useMaxWidth:!0,padding:8},theme:"default",maxTextSize:5e4,maxEdges:500,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize","maxEdges"],legacyMathML:!1,deterministicIds:!1,fontSize:16},$t={...qt,deterministicIDSeed:void 0,themeCSS:void 0,themeVariables:Dt.default.getThemeVariables(),sequence:{...qt.sequence,messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},noteFont:function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}},actorFont:function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}}},gantt:{...qt.gantt,tickInterval:void 0,useWidth:void 0},c4:{...qt.c4,useWidth:void 0,personFont:function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}},external_personFont:function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}},systemFont:function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}},external_systemFont:function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}},system_dbFont:function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}},external_system_dbFont:function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}},system_queueFont:function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}},external_system_queueFont:function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}},containerFont:function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}},external_containerFont:function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}},container_dbFont:function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}},external_container_dbFont:function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}},container_queueFont:function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}},external_container_queueFont:function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}},componentFont:function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}},external_componentFont:function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}},component_dbFont:function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}},external_component_dbFont:function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}},component_queueFont:function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}},external_component_queueFont:function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}},boundaryFont:function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}},messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}}},pie:{...qt.pie,useWidth:984},xyChart:{...qt.xyChart,useWidth:void 0},requirement:{...qt.requirement,useWidth:void 0},gitGraph:{...qt.gitGraph,useMaxWidth:!1},sankey:{...qt.sankey,useMaxWidth:!1}},zt=(t,e="")=>Object.keys(t).reduce(((i,r)=>Array.isArray(t[r])?i:"object"==typeof t[r]&&null!==t[r]?[...i,e+r,...zt(t[r],"")]:[...i,e+r]),[]),Pt=new Set(zt($t,"")),Rt=$t,Wt=t=>{if(st.debug("sanitizeDirective called with",t),"object"==typeof t&&null!=t)if(Array.isArray(t))t.forEach((t=>Wt(t)));else{for(const e of Object.keys(t)){if(st.debug("Checking key",e),e.startsWith("__")||e.includes("proto")||e.includes("constr")||!Pt.has(e)||null==t[e]){st.debug("sanitize deleting key: ",e),delete t[e];continue}if("object"==typeof t[e]){st.debug("sanitizing object",e),Wt(t[e]);continue}const i=["themeCSS","fontFamily","altFontFamily"];for(const r of i)e.includes(r)&&(st.debug("sanitizing css option",e),t[e]=Ut(t[e]))}if(t.themeVariables)for(const e of Object.keys(t.themeVariables)){const i=t.themeVariables[e];(null==i?void 0:i.match)&&!i.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[e]="")}st.debug("After sanitization",t)}},Ut=t=>{let e=0,i=0;for(const r of t){if(e<i)return"{ /* ERROR: Unbalanced CSS */ }";"{"===r?e++:"}"===r&&i++}return e!==i?"{ /* ERROR: Unbalanced CSS */ }":t},Ht=/^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s,Yt=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,Vt=/\s*%%.*\n/gm;class Gt extends Error{constructor(t){super(t),this.name="UnknownDiagramError"}}const Xt={},Zt=function(t,e){t=t.replace(Ht,"").replace(Yt,"").replace(Vt,"\n");for(const[i,{detector:r}]of Object.entries(Xt)){if(r(t,e))return i}throw new Gt(`No diagram type detected matching given configuration for text: ${t}`)},Jt=(...t)=>{for(const{id:e,detector:i,loader:r}of t)Qt(e,i,r)},Qt=(t,e,i)=>{Xt[t]?st.error(`Detector with key ${t} already exists`):Xt[t]={detector:e,loader:i},st.debug(`Detector with key ${t} added${i?" with loader":""}`)},Kt=(t,e,{depth:i=2,clobber:r=!1}={})=>{const n={depth:i,clobber:r};return Array.isArray(e)&&!Array.isArray(t)?(e.forEach((e=>Kt(t,e,n))),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach((e=>{t.includes(e)||t.push(e)})),t):void 0===t||i<=0?null!=t&&"object"==typeof t&&"object"==typeof e?Object.assign(t,e):e:(void 0!==e&&"object"==typeof t&&"object"==typeof e&&Object.keys(e).forEach((n=>{"object"!=typeof e[n]||void 0!==t[n]&&"object"!=typeof t[n]?(r||"object"!=typeof t[n]&&"object"!=typeof e[n])&&(t[n]=e[n]):(void 0===t[n]&&(t[n]=Array.isArray(e[n])?[]:{}),t[n]=Kt(t[n],e[n],{depth:i-1,clobber:r}))})),t)},te=Kt,ee="\u200b",ie={curveBasis:a.qrM,curveBasisClosed:a.Yu4,curveBasisOpen:a.IA3,curveBumpX:a.Wi0,curveBumpY:a.PGM,curveBundle:a.OEq,curveCardinalClosed:a.olC,curveCardinalOpen:a.IrU,curveCardinal:a.y8u,curveCatmullRomClosed:a.Q7f,curveCatmullRomOpen:a.cVp,curveCatmullRom:a.oDi,curveLinear:a.lUB,curveLinearClosed:a.Lx9,curveMonotoneX:a.nVG,curveMonotoneY:a.uxU,curveNatural:a.Xf2,curveStep:a.GZz,curveStepAfter:a.UPb,curveStepBefore:a.dyv},re=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,ne=function(t,e=null){try{const i=new RegExp(`[%]{2}(?![{]${re.source})(?=[}][%]{2}).*\n`,"ig");let r;t=t.trim().replace(i,"").replace(/'/gm,'"'),st.debug(`Detecting diagram directive${null!==e?" type:"+e:""} based on the text:${t}`);const n=[];for(;null!==(r=Yt.exec(t));)if(r.index===Yt.lastIndex&&Yt.lastIndex++,r&&!e||e&&r[1]&&r[1].match(e)||e&&r[2]&&r[2].match(e)){const t=r[1]?r[1]:r[2],e=r[3]?r[3].trim():r[4]?JSON.parse(r[4].trim()):null;n.push({type:t,args:e})}return 0===n.length?{type:t,args:null}:1===n.length?n[0]:n}catch(i){return st.error(`ERROR: ${i.message} - Unable to parse directive type: '${e}' based on the text: '${t}'`),{type:void 0,args:null}}};function oe(t,e){if(!t)return e;const i=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return ie[i]??e}function ae(t,e){return t&&e?Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)):0}const se=(t,e=2)=>{const i=Math.pow(10,e);return Math.round(t*i)/i},le=(t,e)=>{let i,r=e;for(const n of t){if(i){const t=ae(n,i);if(t<r)r-=t;else{const e=r/t;if(e<=0)return i;if(e>=1)return{x:n.x,y:n.y};if(e>0&&e<1)return{x:se((1-e)*i.x+e*n.x,5),y:se((1-e)*i.y+e*n.y,5)}}}i=n}throw new Error("Could not find a suitable point for the given distance")};function ce(t){let e="",i="";for(const r of t)void 0!==r&&(r.startsWith("color:")||r.startsWith("text-align:")?i=i+r+";":e=e+r+";");return{style:e,labelStyle:i}}let he=0;const ue=()=>(he++,"id-"+Math.random().toString(36).substr(2,12)+"-"+he);const de=t=>function(t){let e="";const i="0123456789abcdef";for(let r=0;r<t;r++)e+=i.charAt(Math.floor(16*Math.random()));return e}(t.length),fe=function(t,e){const i=e.text.replace(St.lineBreakRegex," "),[,r]=_e(e.fontSize),n=t.append("text");n.attr("x",e.x),n.attr("y",e.y),n.style("text-anchor",e.anchor),n.style("font-family",e.fontFamily),n.style("font-size",r),n.style("font-weight",e.fontWeight),n.attr("fill",e.fill),void 0!==e.class&&n.attr("class",e.class);const o=n.append("tspan");return o.attr("x",e.x+2*e.textMargin),o.attr("fill",e.fill),o.text(i),n},pe=(0,y.A)(((t,e,i)=>{if(!t)return t;if(i=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"<br/>"},i),St.lineBreakRegex.test(t))return t;const r=t.split(" "),n=[];let o="";return r.forEach(((t,a)=>{const s=ye(`${t} `,i),l=ye(o,i);if(s>e){const{hyphenatedStrings:r,remainingWord:a}=ge(t,e,"-",i);n.push(o,...r),o=a}else l+s>=e?(n.push(o),o=t):o=[o,t].filter(Boolean).join(" ");a+1===r.length&&n.push(o)})),n.filter((t=>""!==t)).join(i.joinWith)}),((t,e,i)=>`${t}${e}${i.fontSize}${i.fontWeight}${i.fontFamily}${i.joinWith}`)),ge=(0,y.A)(((t,e,i="-",r)=>{r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},r);const n=[...t],o=[];let a="";return n.forEach(((t,s)=>{const l=`${a}${t}`;if(ye(l,r)>=e){const t=s+1,e=n.length===t,r=`${l}${i}`;o.push(e?l:r),a=""}else a=l})),{hyphenatedStrings:o,remainingWord:a}}),((t,e,i="-",r)=>`${t}${e}${i}${r.fontSize}${r.fontWeight}${r.fontFamily}`));function me(t,e){return xe(t,e).height}function ye(t,e){return xe(t,e).width}const xe=(0,y.A)(((t,e)=>{const{fontSize:i=12,fontFamily:r="Arial",fontWeight:n=400}=e;if(!t)return{width:0,height:0};const[,o]=_e(i),s=["sans-serif",r],l=t.split(St.lineBreakRegex),c=[],h=(0,a.Ltv)("body");if(!h.remove)return{width:0,height:0,lineHeight:0};const u=h.append("svg");for(const a of s){let t=0;const e={width:0,height:0,lineHeight:0};for(const i of l){const r={x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0,text:""};r.text=i||ee;const s=fe(u,r).style("font-size",o).style("font-weight",n).style("font-family",a),l=(s._groups||s)[0][0].getBBox();if(0===l.width&&0===l.height)throw new Error("svg element not in render tree");e.width=Math.round(Math.max(e.width,l.width)),t=Math.round(l.height),e.height+=t,e.lineHeight=Math.round(Math.max(e.lineHeight,t))}c.push(e)}u.remove();return c[isNaN(c[1].height)||isNaN(c[1].width)||isNaN(c[1].lineHeight)||c[0].height>c[1].height&&c[0].width>c[1].width&&c[0].lineHeight>c[1].lineHeight?0:1]}),((t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`));let Ce;function be(t){return"str"in t}const _e=t=>{if("number"==typeof t)return[t,t+"px"];const e=parseInt(t??"",10);return Number.isNaN(e)?[void 0,void 0]:t===String(e)?[e,t+"px"]:[e,t]};function ve(t,e){return(0,x.A)({},t,e)}const ke={assignWithDepth:te,wrapLabel:pe,calculateTextHeight:me,calculateTextWidth:ye,calculateTextDimensions:xe,cleanAndMerge:ve,detectInit:function(t,e){const i=ne(t,/(?:init\b)|(?:initialize\b)/);let r={};if(Array.isArray(i)){const t=i.map((t=>t.args));Wt(t),r=te(r,[...t])}else r=i.args;if(!r)return;let n=Zt(t,e);const o="config";return void 0!==r[o]&&("flowchart-v2"===n&&(n="flowchart"),r[n]=r[o],delete r[o]),r},detectDirective:ne,isSubstringInArray:function(t,e){for(const[i,r]of e.entries())if(r.match(t))return i;return-1},interpolateToCurve:oe,calcLabelPosition:function(t){return 1===t.length?t[0]:function(t){let e,i=0;return t.forEach((t=>{i+=ae(t,e),e=t})),le(t,i/2)}(t)},calcCardinalityPosition:(t,e,i)=>{st.info(`our points ${JSON.stringify(e)}`),e[0]!==i&&(e=e.reverse());const r=le(e,25),n=t?10:5,o=Math.atan2(e[0].y-r.y,e[0].x-r.x),a={x:0,y:0};return a.x=Math.sin(o)*n+(e[0].x+r.x)/2,a.y=-Math.cos(o)*n+(e[0].y+r.y)/2,a},calcTerminalLabelPosition:function(t,e,i){const r=structuredClone(i);st.info("our points",r),"start_left"!==e&&"start_right"!==e&&r.reverse();const n=le(r,25+t),o=10+.5*t,a=Math.atan2(r[0].y-n.y,r[0].x-n.x),s={x:0,y:0};return"start_left"===e?(s.x=Math.sin(a+Math.PI)*o+(r[0].x+n.x)/2,s.y=-Math.cos(a+Math.PI)*o+(r[0].y+n.y)/2):"end_right"===e?(s.x=Math.sin(a-Math.PI)*o+(r[0].x+n.x)/2-5,s.y=-Math.cos(a-Math.PI)*o+(r[0].y+n.y)/2-5):"end_left"===e?(s.x=Math.sin(a)*o+(r[0].x+n.x)/2-5,s.y=-Math.cos(a)*o+(r[0].y+n.y)/2-5):(s.x=Math.sin(a)*o+(r[0].x+n.x)/2,s.y=-Math.cos(a)*o+(r[0].y+n.y)/2),s},formatUrl:function(t,e){const i=t.trim();if(i)return"loose"!==e.securityLevel?(0,o.Jf)(i):i},getStylesFromArray:ce,generateId:ue,random:de,runFunc:(t,...e)=>{const i=t.split("."),r=i.length-1,n=i[r];let o=window;for(let a=0;a<r;a++)if(o=o[i[a]],!o)return void st.error(`Function name: ${t} not found in window`);o[n](...e)},entityDecode:function(t){return Ce=Ce||document.createElement("div"),t=escape(t).replace(/%26/g,"&").replace(/%23/g,"#").replace(/%3B/g,";"),Ce.innerHTML=t,unescape(Ce.textContent)},insertTitle:(t,e,i,r)=>{var n;if(!r)return;const o=null==(n=t.node())?void 0:n.getBBox();o&&t.append("text").text(r).attr("x",o.x+o.width/2).attr("y",-i).attr("class",e)},parseFontSize:_e,InitIDGenerator:class{constructor(t=!1,e){this.count=0,this.count=e?e.length:0,this.next=t?()=>this.count++:()=>Date.now()}}},Te=function(t){return t.replace(/\ufb02\xb0\xb0/g,"&#").replace(/\ufb02\xb0/g,"&").replace(/\xb6\xdf/g,";")},Ae="10.9.3",we=Object.freeze(Rt);let Se,Be=te({},we),Fe=[],Le=te({},we);const Me=(t,e)=>{let i=te({},t),r={};for(const n of e)je(n),r=te(r,n);if(i=te(i,r),r.theme&&r.theme in Dt){const t=te({},Se),e=te(t.themeVariables||{},r.themeVariables);i.theme&&i.theme in Dt&&(i.themeVariables=Dt[i.theme].getThemeVariables(e))}return Le=i,ze(Le),Le},Ee=()=>te({},Be),Ne=t=>(ze(t),te(Le,t),Oe()),Oe=()=>te({},Le),je=t=>{t&&(["secure",...Be.secure??[]].forEach((e=>{Object.hasOwn(t,e)&&(st.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])})),Object.keys(t).forEach((e=>{e.startsWith("__")&&delete t[e]})),Object.keys(t).forEach((e=>{"string"==typeof t[e]&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],"object"==typeof t[e]&&je(t[e])})))},Ie=t=>{Wt(t),!t.fontFamily||t.themeVariables&&t.themeVariables.fontFamily||(t.themeVariables={fontFamily:t.fontFamily}),Fe.push(t),Me(Be,Fe)},De=(t=Be)=>{Fe=[],Me(t,Fe)},qe={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead."},$e={},ze=t=>{var e;t&&((t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&&($e[e="LAZY_LOAD_DEPRECATED"]||(st.warn(qe[e]),$e[e]=!0)))},Pe={id:"c4",detector:t=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(t),loader:async()=>{const{diagram:t}=await i.e(53292).then(i.bind(i,53292));return{id:"c4",diagram:t}}},Re="flowchart",We={id:Re,detector:(t,e)=>{var i,r;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer)&&"elk"!==(null==(r=null==e?void 0:e.flowchart)?void 0:r.defaultRenderer)&&/^\s*graph/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(51169),i.e(9312),i.e(21176),i.e(88146),i.e(8995),i.e(35860),i.e(22315)]).then(i.bind(i,22315));return{id:Re,diagram:t}}},Ue="flowchart-v2",He={id:Ue,detector:(t,e)=>{var i,r,n;return"dagre-d3"!==(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer)&&"elk"!==(null==(r=null==e?void 0:e.flowchart)?void 0:r.defaultRenderer)&&(!(!/^\s*graph/.test(t)||"dagre-wrapper"!==(null==(n=null==e?void 0:e.flowchart)?void 0:n.defaultRenderer))||/^\s*flowchart/.test(t))},loader:async()=>{const{diagram:t}=await Promise.all([i.e(51169),i.e(9312),i.e(21176),i.e(88146),i.e(8995),i.e(35860),i.e(21689)]).then(i.bind(i,21689));return{id:Ue,diagram:t}}},Ye={id:"er",detector:t=>/^\s*erDiagram/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(51169),i.e(21176),i.e(10711)]).then(i.bind(i,10711));return{id:"er",diagram:t}}},Ve="gitGraph",Ge={id:Ve,detector:t=>/^\s*gitGraph/.test(t),loader:async()=>{const{diagram:t}=await i.e(24073).then(i.bind(i,24073));return{id:Ve,diagram:t}}},Xe="gantt",Ze={id:Xe,detector:t=>/^\s*gantt/.test(t),loader:async()=>{const{diagram:t}=await i.e(8989).then(i.bind(i,8989));return{id:Xe,diagram:t}}},Je="info",Qe={id:Je,detector:t=>/^\s*info/.test(t),loader:async()=>{const{diagram:t}=await i.e(15857).then(i.bind(i,15857));return{id:Je,diagram:t}}},Ke={id:"pie",detector:t=>/^\s*pie/.test(t),loader:async()=>{const{diagram:t}=await i.e(48846).then(i.bind(i,48846));return{id:"pie",diagram:t}}},ti="quadrantChart",ei={id:ti,detector:t=>/^\s*quadrantChart/.test(t),loader:async()=>{const{diagram:t}=await i.e(94564).then(i.bind(i,94564));return{id:ti,diagram:t}}},ii="xychart",ri={id:ii,detector:t=>/^\s*xychart-beta/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(9312),i.e(31329)]).then(i.bind(i,31329));return{id:ii,diagram:t}}},ni="requirement",oi={id:ni,detector:t=>/^\s*requirement(Diagram)?/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(51169),i.e(21176),i.e(23417)]).then(i.bind(i,23417));return{id:ni,diagram:t}}},ai="sequence",si={id:ai,detector:t=>/^\s*sequenceDiagram/.test(t),loader:async()=>{const{diagram:t}=await i.e(23687).then(i.bind(i,23687));return{id:ai,diagram:t}}},li="class",ci={id:li,detector:(t,e)=>{var i;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.class)?void 0:i.defaultRenderer)&&/^\s*classDiagram/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(51169),i.e(21176),i.e(21987),i.e(86770)]).then(i.bind(i,86770));return{id:li,diagram:t}}},hi="classDiagram",ui={id:hi,detector:(t,e)=>{var i;return!(!/^\s*classDiagram/.test(t)||"dagre-wrapper"!==(null==(i=null==e?void 0:e.class)?void 0:i.defaultRenderer))||/^\s*classDiagram-v2/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(51169),i.e(9312),i.e(21176),i.e(88146),i.e(8995),i.e(21987),i.e(85628)]).then(i.bind(i,85628));return{id:hi,diagram:t}}},di="state",fi={id:di,detector:(t,e)=>{var i;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.state)?void 0:i.defaultRenderer)&&/^\s*stateDiagram/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(51169),i.e(21176),i.e(27899),i.e(95163)]).then(i.bind(i,95163));return{id:di,diagram:t}}},pi="stateDiagram",gi={id:pi,detector:(t,e)=>{var i;return!!/^\s*stateDiagram-v2/.test(t)||!(!/^\s*stateDiagram/.test(t)||"dagre-wrapper"!==(null==(i=null==e?void 0:e.state)?void 0:i.defaultRenderer))},loader:async()=>{const{diagram:t}=await Promise.all([i.e(51169),i.e(9312),i.e(21176),i.e(88146),i.e(8995),i.e(27899),i.e(50141)]).then(i.bind(i,50141));return{id:pi,diagram:t}}},mi="journey",yi={id:mi,detector:t=>/^\s*journey/.test(t),loader:async()=>{const{diagram:t}=await i.e(82144).then(i.bind(i,82144));return{id:mi,diagram:t}}},xi=function(t,e,i,r){const n=function(t,e,i){let r=new Map;return i?(r.set("width","100%"),r.set("style",`max-width: ${e}px;`)):(r.set("height",t),r.set("width",e)),r}(e,i,r);!function(t,e){for(let i of e)t.attr(i[0],i[1])}(t,n)},Ci=function(t,e,i,r){const n=e.node().getBBox(),o=n.width,a=n.height;st.info(`SVG bounds: ${o}x${a}`,n);let s=0,l=0;st.info(`Graph bounds: ${s}x${l}`,t),s=o+2*i,l=a+2*i,st.info(`Calculated bounds: ${s}x${l}`),xi(e,l,s,r);const c=`${n.x-i} ${n.y-i} ${n.width+2*i} ${n.height+2*i}`;e.attr("viewBox",c)},bi={},_i=(t,e,i)=>{let r="";return t in bi&&bi[t]?r=bi[t](i):st.warn(`No theme found for ${t}`),` & {\n font-family: ${i.fontFamily};\n font-size: ${i.fontSize};\n fill: ${i.textColor}\n }\n\n /* Classes common for multiple diagrams */\n\n & .error-icon {\n fill: ${i.errorBkgColor};\n }\n & .error-text {\n fill: ${i.errorTextColor};\n stroke: ${i.errorTextColor};\n }\n\n & .edge-thickness-normal {\n stroke-width: 2px;\n }\n & .edge-thickness-thick {\n stroke-width: 3.5px\n }\n & .edge-pattern-solid {\n stroke-dasharray: 0;\n }\n\n & .edge-pattern-dashed{\n stroke-dasharray: 3;\n }\n .edge-pattern-dotted {\n stroke-dasharray: 2;\n }\n\n & .marker {\n fill: ${i.lineColor};\n stroke: ${i.lineColor};\n }\n & .marker.cross {\n stroke: ${i.lineColor};\n }\n\n & svg {\n font-family: ${i.fontFamily};\n font-size: ${i.fontSize};\n }\n\n ${r}\n\n ${e}\n`};let vi="",ki="",Ti="";const Ai=t=>pt(t,Oe()),wi=()=>{vi="",Ti="",ki=""},Si=t=>{vi=Ai(t).replace(/^\s+/g,"")},Bi=()=>vi,Fi=t=>{Ti=Ai(t).replace(/\n\s+/g,"\n")},Li=()=>Ti,Mi=t=>{ki=Ai(t)},Ei=()=>ki,Ni=Object.freeze(Object.defineProperty({__proto__:null,clear:wi,getAccDescription:Li,getAccTitle:Bi,getDiagramTitle:Ei,setAccDescription:Fi,setAccTitle:Si,setDiagramTitle:Mi},Symbol.toStringTag,{value:"Module"})),Oi=st,ji=lt,Ii=Oe,Di=Ne,qi=we,$i=t=>pt(t,Ii()),zi=Ci,Pi={},Ri=(t,e,i)=>{var r,n,o;if(Pi[t])throw new Error(`Diagram ${t} already registered.`);Pi[t]=e,i&&Qt(t,i),n=t,void 0!==(o=e.styles)&&(bi[n]=o),null==(r=e.injectUtils)||r.call(e,Oi,ji,Ii,$i,zi,Ni,(()=>{}))},Wi=t=>{if(t in Pi)return Pi[t];throw new Ui(t)};class Ui extends Error{constructor(t){super(`Diagram ${t} not found.`)}}const Hi=t=>{var e;const{securityLevel:i}=Ii();let r=(0,a.Ltv)("body");if("sandbox"===i){const i=(null==(e=(0,a.Ltv)(`#i${t}`).node())?void 0:e.contentDocument)??document;r=(0,a.Ltv)(i.body)}return r.select(`#${t}`)},Yi={draw:(t,e,i)=>{st.debug("rendering svg for syntax error\n");const r=Hi(e),n=r.append("g");r.attr("viewBox","0 0 2412 512"),xi(r,100,512,!0),n.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),n.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),n.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),n.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),n.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),n.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),n.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),n.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${i}`)}},Vi=Yi,Gi={db:{},renderer:Yi,parser:{parser:{yy:{}},parse:()=>{}}},Xi="flowchart-elk",Zi={id:Xi,detector:(t,e)=>{var i;return!!(/^\s*flowchart-elk/.test(t)||/^\s*flowchart|graph/.test(t)&&"elk"===(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer))},loader:async()=>{const{diagram:t}=await Promise.all([i.e(9312),i.e(88146),i.e(35860),i.e(24104)]).then(i.bind(i,24104));return{id:Xi,diagram:t}}},Ji="timeline",Qi={id:Ji,detector:t=>/^\s*timeline/.test(t),loader:async()=>{const{diagram:t}=await i.e(50971).then(i.bind(i,50971));return{id:Ji,diagram:t}}},Ki="mindmap",tr={id:Ki,detector:t=>/^\s*mindmap/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(9312),i.e(92704)]).then(i.bind(i,92704));return{id:Ki,diagram:t}}},er="sankey",ir={id:er,detector:t=>/^\s*sankey-beta/.test(t),loader:async()=>{const{diagram:t}=await i.e(64529).then(i.bind(i,64529));return{id:er,diagram:t}}},rr="block",nr={id:rr,detector:t=>/^\s*block-beta/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(51169),i.e(9312),i.e(88146),i.e(56625)]).then(i.bind(i,56625));return{id:rr,diagram:t}}};let or=!1;const ar=()=>{or||(or=!0,Ri("error",Gi,(t=>"error"===t.toLowerCase().trim())),Ri("---",{db:{clear:()=>{}},styles:{},renderer:{draw:()=>{}},parser:{parser:{yy:{}},parse:()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")}},init:()=>null},(t=>t.toLowerCase().trimStart().startsWith("---"))),Jt(Pe,ui,ci,Ye,Ze,Qe,Ke,oi,si,Zi,He,We,tr,Qi,Ge,gi,fi,yi,ei,ir,ri,nr))};class sr{constructor(t,e={}){this.text=t,this.metadata=e,this.type="graph",this.text=function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/classDef.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/#\w+;/g,(function(t){const e=t.substring(1,t.length-1);return/^\+?\d+$/.test(e)?"\ufb02\xb0\xb0"+e+"\xb6\xdf":"\ufb02\xb0"+e+"\xb6\xdf"})),e}(t),this.text+="\n";const i=Oe();try{this.type=Zt(t,i)}catch(n){this.type="error",this.detectError=n}const r=Wi(this.type);st.debug("Type "+this.type),this.db=r.db,this.renderer=r.renderer,this.parser=r.parser,this.parser.parser.yy=this.db,this.init=r.init,this.parse()}parse(){var t,e,i,r,n;if(this.detectError)throw this.detectError;null==(e=(t=this.db).clear)||e.call(t);const o=Oe();null==(i=this.init)||i.call(this,o),this.metadata.title&&(null==(n=(r=this.db).setDiagramTitle)||n.call(r,this.metadata.title)),this.parser.parse(this.text)}async render(t,e){await this.renderer.draw(this.text,t,e,this)}getParser(){return this.parser}getType(){return this.type}}const lr=async(t,e={})=>{const i=Zt(t,Oe());try{Wi(i)}catch(r){const t=Xt[i].loader;if(!t)throw new Gt(`Diagram ${i} not found.`);const{id:e,diagram:n}=await t();Ri(e,n)}return new sr(t,e)};let cr=[];const hr="graphics-document document";const ur=t=>t.replace(/^\s*%%(?!{)[^\n]+\n?/gm,"").trimStart();function dr(t){return null==t}var fr={isNothing:dr,isObject:function(t){return"object"==typeof t&&null!==t},toArray:function(t){return Array.isArray(t)?t:dr(t)?[]:[t]},repeat:function(t,e){var i,r="";for(i=0;i<e;i+=1)r+=t;return r},isNegativeZero:function(t){return 0===t&&Number.NEGATIVE_INFINITY===1/t},extend:function(t,e){var i,r,n,o;if(e)for(i=0,r=(o=Object.keys(e)).length;i<r;i+=1)t[n=o[i]]=e[n];return t}};function pr(t,e){var i="",r=t.reason||"(unknown reason)";return t.mark?(t.mark.name&&(i+='in "'+t.mark.name+'" '),i+="("+(t.mark.line+1)+":"+(t.mark.column+1)+")",!e&&t.mark.snippet&&(i+="\n\n"+t.mark.snippet),r+" "+i):r}function gr(t,e){Error.call(this),this.name="YAMLException",this.reason=t,this.mark=e,this.message=pr(this,!1),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||""}gr.prototype=Object.create(Error.prototype),gr.prototype.constructor=gr,gr.prototype.toString=function(t){return this.name+": "+pr(this,t)};var mr=gr;function yr(t,e,i,r,n){var o="",a="",s=Math.floor(n/2)-1;return r-e>s&&(e=r-s+(o=" ... ").length),i-r>s&&(i=r+s-(a=" ...").length),{str:o+t.slice(e,i).replace(/\t/g,"\u2192")+a,pos:r-e+o.length}}function xr(t,e){return fr.repeat(" ",e-t.length)+t}var Cr=function(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),"number"!=typeof e.indent&&(e.indent=1),"number"!=typeof e.linesBefore&&(e.linesBefore=3),"number"!=typeof e.linesAfter&&(e.linesAfter=2);for(var i,r=/\r?\n|\r|\0/g,n=[0],o=[],a=-1;i=r.exec(t.buffer);)o.push(i.index),n.push(i.index+i[0].length),t.position<=i.index&&a<0&&(a=n.length-2);a<0&&(a=n.length-1);var s,l,c="",h=Math.min(t.line+e.linesAfter,o.length).toString().length,u=e.maxLength-(e.indent+h+3);for(s=1;s<=e.linesBefore&&!(a-s<0);s++)l=yr(t.buffer,n[a-s],o[a-s],t.position-(n[a]-n[a-s]),u),c=fr.repeat(" ",e.indent)+xr((t.line-s+1).toString(),h)+" | "+l.str+"\n"+c;for(l=yr(t.buffer,n[a],o[a],t.position,u),c+=fr.repeat(" ",e.indent)+xr((t.line+1).toString(),h)+" | "+l.str+"\n",c+=fr.repeat("-",e.indent+h+3+l.pos)+"^\n",s=1;s<=e.linesAfter&&!(a+s>=o.length);s++)l=yr(t.buffer,n[a+s],o[a+s],t.position-(n[a]-n[a+s]),u),c+=fr.repeat(" ",e.indent)+xr((t.line+s+1).toString(),h)+" | "+l.str+"\n";return c.replace(/\n$/,"")},br=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],_r=["scalar","sequence","mapping"];var vr=function(t,e){var i,r;if(e=e||{},Object.keys(e).forEach((function(e){if(-1===br.indexOf(e))throw new mr('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')})),this.options=e,this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.representName=e.representName||null,this.defaultStyle=e.defaultStyle||null,this.multi=e.multi||!1,this.styleAliases=(i=e.styleAliases||null,r={},null!==i&&Object.keys(i).forEach((function(t){i[t].forEach((function(e){r[String(e)]=t}))})),r),-1===_r.indexOf(this.kind))throw new mr('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')};function kr(t,e){var i=[];return t[e].forEach((function(t){var e=i.length;i.forEach((function(i,r){i.tag===t.tag&&i.kind===t.kind&&i.multi===t.multi&&(e=r)})),i[e]=t})),i}function Tr(t){return this.extend(t)}Tr.prototype.extend=function(t){var e=[],i=[];if(t instanceof vr)i.push(t);else if(Array.isArray(t))i=i.concat(t);else{if(!t||!Array.isArray(t.implicit)&&!Array.isArray(t.explicit))throw new mr("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");t.implicit&&(e=e.concat(t.implicit)),t.explicit&&(i=i.concat(t.explicit))}e.forEach((function(t){if(!(t instanceof vr))throw new mr("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(t.loadKind&&"scalar"!==t.loadKind)throw new mr("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(t.multi)throw new mr("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")})),i.forEach((function(t){if(!(t instanceof vr))throw new mr("Specified list of YAML types (or a single Type object) contains a non-Type object.")}));var r=Object.create(Tr.prototype);return r.implicit=(this.implicit||[]).concat(e),r.explicit=(this.explicit||[]).concat(i),r.compiledImplicit=kr(r,"implicit"),r.compiledExplicit=kr(r,"explicit"),r.compiledTypeMap=function(){var t,e,i={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}};function r(t){t.multi?(i.multi[t.kind].push(t),i.multi.fallback.push(t)):i[t.kind][t.tag]=i.fallback[t.tag]=t}for(t=0,e=arguments.length;t<e;t+=1)arguments[t].forEach(r);return i}(r.compiledImplicit,r.compiledExplicit),r};var Ar=new Tr({explicit:[new vr("tag:yaml.org,2002:str",{kind:"scalar",construct:function(t){return null!==t?t:""}}),new vr("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(t){return null!==t?t:[]}}),new vr("tag:yaml.org,2002:map",{kind:"mapping",construct:function(t){return null!==t?t:{}}})]});var wr=new vr("tag:yaml.org,2002:null",{kind:"scalar",resolve:function(t){if(null===t)return!0;var e=t.length;return 1===e&&"~"===t||4===e&&("null"===t||"Null"===t||"NULL"===t)},construct:function(){return null},predicate:function(t){return null===t},represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"},empty:function(){return""}},defaultStyle:"lowercase"});var Sr=new vr("tag:yaml.org,2002:bool",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e=t.length;return 4===e&&("true"===t||"True"===t||"TRUE"===t)||5===e&&("false"===t||"False"===t||"FALSE"===t)},construct:function(t){return"true"===t||"True"===t||"TRUE"===t},predicate:function(t){return"[object Boolean]"===Object.prototype.toString.call(t)},represent:{lowercase:function(t){return t?"true":"false"},uppercase:function(t){return t?"TRUE":"FALSE"},camelcase:function(t){return t?"True":"False"}},defaultStyle:"lowercase"});function Br(t){return 48<=t&&t<=55}function Fr(t){return 48<=t&&t<=57}var Lr=new vr("tag:yaml.org,2002:int",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e,i,r=t.length,n=0,o=!1;if(!r)return!1;if("-"!==(e=t[n])&&"+"!==e||(e=t[++n]),"0"===e){if(n+1===r)return!0;if("b"===(e=t[++n])){for(n++;n<r;n++)if("_"!==(e=t[n])){if("0"!==e&&"1"!==e)return!1;o=!0}return o&&"_"!==e}if("x"===e){for(n++;n<r;n++)if("_"!==(e=t[n])){if(!(48<=(i=t.charCodeAt(n))&&i<=57||65<=i&&i<=70||97<=i&&i<=102))return!1;o=!0}return o&&"_"!==e}if("o"===e){for(n++;n<r;n++)if("_"!==(e=t[n])){if(!Br(t.charCodeAt(n)))return!1;o=!0}return o&&"_"!==e}}if("_"===e)return!1;for(;n<r;n++)if("_"!==(e=t[n])){if(!Fr(t.charCodeAt(n)))return!1;o=!0}return!(!o||"_"===e)},construct:function(t){var e,i=t,r=1;if(-1!==i.indexOf("_")&&(i=i.replace(/_/g,"")),"-"!==(e=i[0])&&"+"!==e||("-"===e&&(r=-1),e=(i=i.slice(1))[0]),"0"===i)return 0;if("0"===e){if("b"===i[1])return r*parseInt(i.slice(2),2);if("x"===i[1])return r*parseInt(i.slice(2),16);if("o"===i[1])return r*parseInt(i.slice(2),8)}return r*parseInt(i,10)},predicate:function(t){return"[object Number]"===Object.prototype.toString.call(t)&&t%1==0&&!fr.isNegativeZero(t)},represent:{binary:function(t){return t>=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},octal:function(t){return t>=0?"0o"+t.toString(8):"-0o"+t.toString(8).slice(1)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),Mr=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");var Er=/^[-+]?[0-9]+e/;var Nr=new vr("tag:yaml.org,2002:float",{kind:"scalar",resolve:function(t){return null!==t&&!(!Mr.test(t)||"_"===t[t.length-1])},construct:function(t){var e,i;return i="-"===(e=t.replace(/_/g,"").toLowerCase())[0]?-1:1,"+-".indexOf(e[0])>=0&&(e=e.slice(1)),".inf"===e?1===i?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:i*parseFloat(e,10)},predicate:function(t){return"[object Number]"===Object.prototype.toString.call(t)&&(t%1!=0||fr.isNegativeZero(t))},represent:function(t,e){var i;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(fr.isNegativeZero(t))return"-0.0";return i=t.toString(10),Er.test(i)?i.replace("e",".e"):i},defaultStyle:"lowercase"}),Or=Ar.extend({implicit:[wr,Sr,Lr,Nr]}),jr=Or,Ir=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),Dr=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");var qr=new vr("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:function(t){return null!==t&&(null!==Ir.exec(t)||null!==Dr.exec(t))},construct:function(t){var e,i,r,n,o,a,s,l,c=0,h=null;if(null===(e=Ir.exec(t))&&(e=Dr.exec(t)),null===e)throw new Error("Date resolve error");if(i=+e[1],r=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(i,r,n));if(o=+e[4],a=+e[5],s=+e[6],e[7]){for(c=e[7].slice(0,3);c.length<3;)c+="0";c=+c}return e[9]&&(h=6e4*(60*+e[10]+ +(e[11]||0)),"-"===e[9]&&(h=-h)),l=new Date(Date.UTC(i,r,n,o,a,s,c)),h&&l.setTime(l.getTime()-h),l},instanceOf:Date,represent:function(t){return t.toISOString()}});var $r=new vr("tag:yaml.org,2002:merge",{kind:"scalar",resolve:function(t){return"<<"===t||null===t}}),zr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";var Pr=new vr("tag:yaml.org,2002:binary",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e,i,r=0,n=t.length,o=zr;for(i=0;i<n;i++)if(!((e=o.indexOf(t.charAt(i)))>64)){if(e<0)return!1;r+=6}return r%8==0},construct:function(t){var e,i,r=t.replace(/[\r\n=]/g,""),n=r.length,o=zr,a=0,s=[];for(e=0;e<n;e++)e%4==0&&e&&(s.push(a>>16&255),s.push(a>>8&255),s.push(255&a)),a=a<<6|o.indexOf(r.charAt(e));return 0===(i=n%4*6)?(s.push(a>>16&255),s.push(a>>8&255),s.push(255&a)):18===i?(s.push(a>>10&255),s.push(a>>2&255)):12===i&&s.push(a>>4&255),new Uint8Array(s)},predicate:function(t){return"[object Uint8Array]"===Object.prototype.toString.call(t)},represent:function(t){var e,i,r="",n=0,o=t.length,a=zr;for(e=0;e<o;e++)e%3==0&&e&&(r+=a[n>>18&63],r+=a[n>>12&63],r+=a[n>>6&63],r+=a[63&n]),n=(n<<8)+t[e];return 0===(i=o%3)?(r+=a[n>>18&63],r+=a[n>>12&63],r+=a[n>>6&63],r+=a[63&n]):2===i?(r+=a[n>>10&63],r+=a[n>>4&63],r+=a[n<<2&63],r+=a[64]):1===i&&(r+=a[n>>2&63],r+=a[n<<4&63],r+=a[64],r+=a[64]),r}}),Rr=Object.prototype.hasOwnProperty,Wr=Object.prototype.toString;var Ur=new vr("tag:yaml.org,2002:omap",{kind:"sequence",resolve:function(t){if(null===t)return!0;var e,i,r,n,o,a=[],s=t;for(e=0,i=s.length;e<i;e+=1){if(r=s[e],o=!1,"[object Object]"!==Wr.call(r))return!1;for(n in r)if(Rr.call(r,n)){if(o)return!1;o=!0}if(!o)return!1;if(-1!==a.indexOf(n))return!1;a.push(n)}return!0},construct:function(t){return null!==t?t:[]}}),Hr=Object.prototype.toString;var Yr=new vr("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:function(t){if(null===t)return!0;var e,i,r,n,o,a=t;for(o=new Array(a.length),e=0,i=a.length;e<i;e+=1){if(r=a[e],"[object Object]"!==Hr.call(r))return!1;if(1!==(n=Object.keys(r)).length)return!1;o[e]=[n[0],r[n[0]]]}return!0},construct:function(t){if(null===t)return[];var e,i,r,n,o,a=t;for(o=new Array(a.length),e=0,i=a.length;e<i;e+=1)r=a[e],n=Object.keys(r),o[e]=[n[0],r[n[0]]];return o}}),Vr=Object.prototype.hasOwnProperty;var Gr=new vr("tag:yaml.org,2002:set",{kind:"mapping",resolve:function(t){if(null===t)return!0;var e,i=t;for(e in i)if(Vr.call(i,e)&&null!==i[e])return!1;return!0},construct:function(t){return null!==t?t:{}}}),Xr=jr.extend({implicit:[qr,$r],explicit:[Pr,Ur,Yr,Gr]}),Zr=Object.prototype.hasOwnProperty,Jr=1,Qr=2,Kr=3,tn=4,en=1,rn=2,nn=3,on=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,an=/[\x85\u2028\u2029]/,sn=/[,\[\]\{\}]/,ln=/^(?:!|!!|![a-z\-]+!)$/i,cn=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function hn(t){return Object.prototype.toString.call(t)}function un(t){return 10===t||13===t}function dn(t){return 9===t||32===t}function fn(t){return 9===t||32===t||10===t||13===t}function pn(t){return 44===t||91===t||93===t||123===t||125===t}function gn(t){var e;return 48<=t&&t<=57?t-48:97<=(e=32|t)&&e<=102?e-97+10:-1}function mn(t){return 48===t?"\0":97===t?"\x07":98===t?"\b":116===t||9===t?"\t":110===t?"\n":118===t?"\v":102===t?"\f":114===t?"\r":101===t?"\x1b":32===t?" ":34===t?'"':47===t?"/":92===t?"\\":78===t?"\x85":95===t?"\xa0":76===t?"\u2028":80===t?"\u2029":""}function yn(t){return t<=65535?String.fromCharCode(t):String.fromCharCode(55296+(t-65536>>10),56320+(t-65536&1023))}for(var xn=new Array(256),Cn=new Array(256),bn=0;bn<256;bn++)xn[bn]=mn(bn)?1:0,Cn[bn]=mn(bn);function _n(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||Xr,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function vn(t,e){var i={name:t.filename,buffer:t.input.slice(0,-1),position:t.position,line:t.line,column:t.position-t.lineStart};return i.snippet=Cr(i),new mr(e,i)}function kn(t,e){throw vn(t,e)}function Tn(t,e){t.onWarning&&t.onWarning.call(null,vn(t,e))}var An={YAML:function(t,e,i){var r,n,o;null!==t.version&&kn(t,"duplication of %YAML directive"),1!==i.length&&kn(t,"YAML directive accepts exactly one argument"),null===(r=/^([0-9]+)\.([0-9]+)$/.exec(i[0]))&&kn(t,"ill-formed argument of the YAML directive"),n=parseInt(r[1],10),o=parseInt(r[2],10),1!==n&&kn(t,"unacceptable YAML version of the document"),t.version=i[0],t.checkLineBreaks=o<2,1!==o&&2!==o&&Tn(t,"unsupported YAML version of the document")},TAG:function(t,e,i){var r,n;2!==i.length&&kn(t,"TAG directive accepts exactly two arguments"),r=i[0],n=i[1],ln.test(r)||kn(t,"ill-formed tag handle (first argument) of the TAG directive"),Zr.call(t.tagMap,r)&&kn(t,'there is a previously declared suffix for "'+r+'" tag handle'),cn.test(n)||kn(t,"ill-formed tag prefix (second argument) of the TAG directive");try{n=decodeURIComponent(n)}catch(o){kn(t,"tag prefix is malformed: "+n)}t.tagMap[r]=n}};function wn(t,e,i,r){var n,o,a,s;if(e<i){if(s=t.input.slice(e,i),r)for(n=0,o=s.length;n<o;n+=1)9===(a=s.charCodeAt(n))||32<=a&&a<=1114111||kn(t,"expected valid JSON character");else on.test(s)&&kn(t,"the stream contains non-printable characters");t.result+=s}}function Sn(t,e,i,r){var n,o,a,s;for(fr.isObject(i)||kn(t,"cannot merge mappings; the provided source object is unacceptable"),a=0,s=(n=Object.keys(i)).length;a<s;a+=1)o=n[a],Zr.call(e,o)||(e[o]=i[o],r[o]=!0)}function Bn(t,e,i,r,n,o,a,s,l){var c,h;if(Array.isArray(n))for(c=0,h=(n=Array.prototype.slice.call(n)).length;c<h;c+=1)Array.isArray(n[c])&&kn(t,"nested arrays are not supported inside keys"),"object"==typeof n&&"[object Object]"===hn(n[c])&&(n[c]="[object Object]");if("object"==typeof n&&"[object Object]"===hn(n)&&(n="[object Object]"),n=String(n),null===e&&(e={}),"tag:yaml.org,2002:merge"===r)if(Array.isArray(o))for(c=0,h=o.length;c<h;c+=1)Sn(t,e,o[c],i);else Sn(t,e,o,i);else t.json||Zr.call(i,n)||!Zr.call(e,n)||(t.line=a||t.line,t.lineStart=s||t.lineStart,t.position=l||t.position,kn(t,"duplicated mapping key")),"__proto__"===n?Object.defineProperty(e,n,{configurable:!0,enumerable:!0,writable:!0,value:o}):e[n]=o,delete i[n];return e}function Fn(t){var e;10===(e=t.input.charCodeAt(t.position))?t.position++:13===e?(t.position++,10===t.input.charCodeAt(t.position)&&t.position++):kn(t,"a line break is expected"),t.line+=1,t.lineStart=t.position,t.firstTabInLine=-1}function Ln(t,e,i){for(var r=0,n=t.input.charCodeAt(t.position);0!==n;){for(;dn(n);)9===n&&-1===t.firstTabInLine&&(t.firstTabInLine=t.position),n=t.input.charCodeAt(++t.position);if(e&&35===n)do{n=t.input.charCodeAt(++t.position)}while(10!==n&&13!==n&&0!==n);if(!un(n))break;for(Fn(t),n=t.input.charCodeAt(t.position),r++,t.lineIndent=0;32===n;)t.lineIndent++,n=t.input.charCodeAt(++t.position)}return-1!==i&&0!==r&&t.lineIndent<i&&Tn(t,"deficient indentation"),r}function Mn(t){var e,i=t.position;return!(45!==(e=t.input.charCodeAt(i))&&46!==e||e!==t.input.charCodeAt(i+1)||e!==t.input.charCodeAt(i+2)||(i+=3,0!==(e=t.input.charCodeAt(i))&&!fn(e)))}function En(t,e){1===e?t.result+=" ":e>1&&(t.result+=fr.repeat("\n",e-1))}function Nn(t,e){var i,r,n=t.tag,o=t.anchor,a=[],s=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=a),r=t.input.charCodeAt(t.position);0!==r&&(-1!==t.firstTabInLine&&(t.position=t.firstTabInLine,kn(t,"tab characters must not be used in indentation")),45===r)&&fn(t.input.charCodeAt(t.position+1));)if(s=!0,t.position++,Ln(t,!0,-1)&&t.lineIndent<=e)a.push(null),r=t.input.charCodeAt(t.position);else if(i=t.line,In(t,e,Kr,!1,!0),a.push(t.result),Ln(t,!0,-1),r=t.input.charCodeAt(t.position),(t.line===i||t.lineIndent>e)&&0!==r)kn(t,"bad indentation of a sequence entry");else if(t.lineIndent<e)break;return!!s&&(t.tag=n,t.anchor=o,t.kind="sequence",t.result=a,!0)}function On(t){var e,i,r,n,o=!1,a=!1;if(33!==(n=t.input.charCodeAt(t.position)))return!1;if(null!==t.tag&&kn(t,"duplication of a tag property"),60===(n=t.input.charCodeAt(++t.position))?(o=!0,n=t.input.charCodeAt(++t.position)):33===n?(a=!0,i="!!",n=t.input.charCodeAt(++t.position)):i="!",e=t.position,o){do{n=t.input.charCodeAt(++t.position)}while(0!==n&&62!==n);t.position<t.length?(r=t.input.slice(e,t.position),n=t.input.charCodeAt(++t.position)):kn(t,"unexpected end of the stream within a verbatim tag")}else{for(;0!==n&&!fn(n);)33===n&&(a?kn(t,"tag suffix cannot contain exclamation marks"):(i=t.input.slice(e-1,t.position+1),ln.test(i)||kn(t,"named tag handle cannot contain such characters"),a=!0,e=t.position+1)),n=t.input.charCodeAt(++t.position);r=t.input.slice(e,t.position),sn.test(r)&&kn(t,"tag suffix cannot contain flow indicator characters")}r&&!cn.test(r)&&kn(t,"tag name cannot contain such characters: "+r);try{r=decodeURIComponent(r)}catch(s){kn(t,"tag name is malformed: "+r)}return o?t.tag=r:Zr.call(t.tagMap,i)?t.tag=t.tagMap[i]+r:"!"===i?t.tag="!"+r:"!!"===i?t.tag="tag:yaml.org,2002:"+r:kn(t,'undeclared tag handle "'+i+'"'),!0}function jn(t){var e,i;if(38!==(i=t.input.charCodeAt(t.position)))return!1;for(null!==t.anchor&&kn(t,"duplication of an anchor property"),i=t.input.charCodeAt(++t.position),e=t.position;0!==i&&!fn(i)&&!pn(i);)i=t.input.charCodeAt(++t.position);return t.position===e&&kn(t,"name of an anchor node must contain at least one character"),t.anchor=t.input.slice(e,t.position),!0}function In(t,e,i,r,n){var o,a,s,l,c,h,u,d,f,p=1,g=!1,m=!1;if(null!==t.listener&&t.listener("open",t),t.tag=null,t.anchor=null,t.kind=null,t.result=null,o=a=s=tn===i||Kr===i,r&&Ln(t,!0,-1)&&(g=!0,t.lineIndent>e?p=1:t.lineIndent===e?p=0:t.lineIndent<e&&(p=-1)),1===p)for(;On(t)||jn(t);)Ln(t,!0,-1)?(g=!0,s=o,t.lineIndent>e?p=1:t.lineIndent===e?p=0:t.lineIndent<e&&(p=-1)):s=!1;if(s&&(s=g||n),1!==p&&tn!==i||(d=Jr===i||Qr===i?e:e+1,f=t.position-t.lineStart,1===p?s&&(Nn(t,f)||function(t,e,i){var r,n,o,a,s,l,c,h=t.tag,u=t.anchor,d={},f=Object.create(null),p=null,g=null,m=null,y=!1,x=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=d),c=t.input.charCodeAt(t.position);0!==c;){if(y||-1===t.firstTabInLine||(t.position=t.firstTabInLine,kn(t,"tab characters must not be used in indentation")),r=t.input.charCodeAt(t.position+1),o=t.line,63!==c&&58!==c||!fn(r)){if(a=t.line,s=t.lineStart,l=t.position,!In(t,i,Qr,!1,!0))break;if(t.line===o){for(c=t.input.charCodeAt(t.position);dn(c);)c=t.input.charCodeAt(++t.position);if(58===c)fn(c=t.input.charCodeAt(++t.position))||kn(t,"a whitespace character is expected after the key-value separator within a block mapping"),y&&(Bn(t,d,f,p,g,null,a,s,l),p=g=m=null),x=!0,y=!1,n=!1,p=t.tag,g=t.result;else{if(!x)return t.tag=h,t.anchor=u,!0;kn(t,"can not read an implicit mapping pair; a colon is missed")}}else{if(!x)return t.tag=h,t.anchor=u,!0;kn(t,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===c?(y&&(Bn(t,d,f,p,g,null,a,s,l),p=g=m=null),x=!0,y=!0,n=!0):y?(y=!1,n=!0):kn(t,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),t.position+=1,c=r;if((t.line===o||t.lineIndent>e)&&(y&&(a=t.line,s=t.lineStart,l=t.position),In(t,e,tn,!0,n)&&(y?g=t.result:m=t.result),y||(Bn(t,d,f,p,g,m,a,s,l),p=g=m=null),Ln(t,!0,-1),c=t.input.charCodeAt(t.position)),(t.line===o||t.lineIndent>e)&&0!==c)kn(t,"bad indentation of a mapping entry");else if(t.lineIndent<e)break}return y&&Bn(t,d,f,p,g,null,a,s,l),x&&(t.tag=h,t.anchor=u,t.kind="mapping",t.result=d),x}(t,f,d))||function(t,e){var i,r,n,o,a,s,l,c,h,u,d,f,p=!0,g=t.tag,m=t.anchor,y=Object.create(null);if(91===(f=t.input.charCodeAt(t.position)))a=93,c=!1,o=[];else{if(123!==f)return!1;a=125,c=!0,o={}}for(null!==t.anchor&&(t.anchorMap[t.anchor]=o),f=t.input.charCodeAt(++t.position);0!==f;){if(Ln(t,!0,e),(f=t.input.charCodeAt(t.position))===a)return t.position++,t.tag=g,t.anchor=m,t.kind=c?"mapping":"sequence",t.result=o,!0;p?44===f&&kn(t,"expected the node content, but found ','"):kn(t,"missed comma between flow collection entries"),d=null,s=l=!1,63===f&&fn(t.input.charCodeAt(t.position+1))&&(s=l=!0,t.position++,Ln(t,!0,e)),i=t.line,r=t.lineStart,n=t.position,In(t,e,Jr,!1,!0),u=t.tag,h=t.result,Ln(t,!0,e),f=t.input.charCodeAt(t.position),!l&&t.line!==i||58!==f||(s=!0,f=t.input.charCodeAt(++t.position),Ln(t,!0,e),In(t,e,Jr,!1,!0),d=t.result),c?Bn(t,o,y,u,h,d,i,r,n):s?o.push(Bn(t,null,y,u,h,d,i,r,n)):o.push(h),Ln(t,!0,e),44===(f=t.input.charCodeAt(t.position))?(p=!0,f=t.input.charCodeAt(++t.position)):p=!1}kn(t,"unexpected end of the stream within a flow collection")}(t,d)?m=!0:(a&&function(t,e){var i,r,n,o,a,s=en,l=!1,c=!1,h=e,u=0,d=!1;if(124===(o=t.input.charCodeAt(t.position)))r=!1;else{if(62!==o)return!1;r=!0}for(t.kind="scalar",t.result="";0!==o;)if(43===(o=t.input.charCodeAt(++t.position))||45===o)en===s?s=43===o?nn:rn:kn(t,"repeat of a chomping mode identifier");else{if(!((n=48<=(a=o)&&a<=57?a-48:-1)>=0))break;0===n?kn(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):c?kn(t,"repeat of an indentation width identifier"):(h=e+n-1,c=!0)}if(dn(o)){do{o=t.input.charCodeAt(++t.position)}while(dn(o));if(35===o)do{o=t.input.charCodeAt(++t.position)}while(!un(o)&&0!==o)}for(;0!==o;){for(Fn(t),t.lineIndent=0,o=t.input.charCodeAt(t.position);(!c||t.lineIndent<h)&&32===o;)t.lineIndent++,o=t.input.charCodeAt(++t.position);if(!c&&t.lineIndent>h&&(h=t.lineIndent),un(o))u++;else{if(t.lineIndent<h){s===nn?t.result+=fr.repeat("\n",l?1+u:u):s===en&&l&&(t.result+="\n");break}for(r?dn(o)?(d=!0,t.result+=fr.repeat("\n",l?1+u:u)):d?(d=!1,t.result+=fr.repeat("\n",u+1)):0===u?l&&(t.result+=" "):t.result+=fr.repeat("\n",u):t.result+=fr.repeat("\n",l?1+u:u),l=!0,c=!0,u=0,i=t.position;!un(o)&&0!==o;)o=t.input.charCodeAt(++t.position);wn(t,i,t.position,!1)}}return!0}(t,d)||function(t,e){var i,r,n;if(39!==(i=t.input.charCodeAt(t.position)))return!1;for(t.kind="scalar",t.result="",t.position++,r=n=t.position;0!==(i=t.input.charCodeAt(t.position));)if(39===i){if(wn(t,r,t.position,!0),39!==(i=t.input.charCodeAt(++t.position)))return!0;r=t.position,t.position++,n=t.position}else un(i)?(wn(t,r,n,!0),En(t,Ln(t,!1,e)),r=n=t.position):t.position===t.lineStart&&Mn(t)?kn(t,"unexpected end of the document within a single quoted scalar"):(t.position++,n=t.position);kn(t,"unexpected end of the stream within a single quoted scalar")}(t,d)||function(t,e){var i,r,n,o,a,s,l;if(34!==(s=t.input.charCodeAt(t.position)))return!1;for(t.kind="scalar",t.result="",t.position++,i=r=t.position;0!==(s=t.input.charCodeAt(t.position));){if(34===s)return wn(t,i,t.position,!0),t.position++,!0;if(92===s){if(wn(t,i,t.position,!0),un(s=t.input.charCodeAt(++t.position)))Ln(t,!1,e);else if(s<256&&xn[s])t.result+=Cn[s],t.position++;else if((a=120===(l=s)?2:117===l?4:85===l?8:0)>0){for(n=a,o=0;n>0;n--)(a=gn(s=t.input.charCodeAt(++t.position)))>=0?o=(o<<4)+a:kn(t,"expected hexadecimal character");t.result+=yn(o),t.position++}else kn(t,"unknown escape sequence");i=r=t.position}else un(s)?(wn(t,i,r,!0),En(t,Ln(t,!1,e)),i=r=t.position):t.position===t.lineStart&&Mn(t)?kn(t,"unexpected end of the document within a double quoted scalar"):(t.position++,r=t.position)}kn(t,"unexpected end of the stream within a double quoted scalar")}(t,d)?m=!0:!function(t){var e,i,r;if(42!==(r=t.input.charCodeAt(t.position)))return!1;for(r=t.input.charCodeAt(++t.position),e=t.position;0!==r&&!fn(r)&&!pn(r);)r=t.input.charCodeAt(++t.position);return t.position===e&&kn(t,"name of an alias node must contain at least one character"),i=t.input.slice(e,t.position),Zr.call(t.anchorMap,i)||kn(t,'unidentified alias "'+i+'"'),t.result=t.anchorMap[i],Ln(t,!0,-1),!0}(t)?function(t,e,i){var r,n,o,a,s,l,c,h,u=t.kind,d=t.result;if(fn(h=t.input.charCodeAt(t.position))||pn(h)||35===h||38===h||42===h||33===h||124===h||62===h||39===h||34===h||37===h||64===h||96===h)return!1;if((63===h||45===h)&&(fn(r=t.input.charCodeAt(t.position+1))||i&&pn(r)))return!1;for(t.kind="scalar",t.result="",n=o=t.position,a=!1;0!==h;){if(58===h){if(fn(r=t.input.charCodeAt(t.position+1))||i&&pn(r))break}else if(35===h){if(fn(t.input.charCodeAt(t.position-1)))break}else{if(t.position===t.lineStart&&Mn(t)||i&&pn(h))break;if(un(h)){if(s=t.line,l=t.lineStart,c=t.lineIndent,Ln(t,!1,-1),t.lineIndent>=e){a=!0,h=t.input.charCodeAt(t.position);continue}t.position=o,t.line=s,t.lineStart=l,t.lineIndent=c;break}}a&&(wn(t,n,o,!1),En(t,t.line-s),n=o=t.position,a=!1),dn(h)||(o=t.position+1),h=t.input.charCodeAt(++t.position)}return wn(t,n,o,!1),!!t.result||(t.kind=u,t.result=d,!1)}(t,d,Jr===i)&&(m=!0,null===t.tag&&(t.tag="?")):(m=!0,null===t.tag&&null===t.anchor||kn(t,"alias node should not have any properties")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===p&&(m=s&&Nn(t,f))),null===t.tag)null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);else if("?"===t.tag){for(null!==t.result&&"scalar"!==t.kind&&kn(t,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+t.kind+'"'),l=0,c=t.implicitTypes.length;l<c;l+=1)if((u=t.implicitTypes[l]).resolve(t.result)){t.result=u.construct(t.result),t.tag=u.tag,null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);break}}else if("!"!==t.tag){if(Zr.call(t.typeMap[t.kind||"fallback"],t.tag))u=t.typeMap[t.kind||"fallback"][t.tag];else for(u=null,l=0,c=(h=t.typeMap.multi[t.kind||"fallback"]).length;l<c;l+=1)if(t.tag.slice(0,h[l].tag.length)===h[l].tag){u=h[l];break}u||kn(t,"unknown tag !<"+t.tag+">"),null!==t.result&&u.kind!==t.kind&&kn(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+u.kind+'", not "'+t.kind+'"'),u.resolve(t.result,t.tag)?(t.result=u.construct(t.result,t.tag),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):kn(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")}return null!==t.listener&&t.listener("close",t),null!==t.tag||null!==t.anchor||m}function Dn(t){var e,i,r,n,o=t.position,a=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap=Object.create(null),t.anchorMap=Object.create(null);0!==(n=t.input.charCodeAt(t.position))&&(Ln(t,!0,-1),n=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==n));){for(a=!0,n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!fn(n);)n=t.input.charCodeAt(++t.position);for(r=[],(i=t.input.slice(e,t.position)).length<1&&kn(t,"directive name must not be less than one character in length");0!==n;){for(;dn(n);)n=t.input.charCodeAt(++t.position);if(35===n){do{n=t.input.charCodeAt(++t.position)}while(0!==n&&!un(n));break}if(un(n))break;for(e=t.position;0!==n&&!fn(n);)n=t.input.charCodeAt(++t.position);r.push(t.input.slice(e,t.position))}0!==n&&Fn(t),Zr.call(An,i)?An[i](t,i,r):Tn(t,'unknown document directive "'+i+'"')}Ln(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,Ln(t,!0,-1)):a&&kn(t,"directives end mark is expected"),In(t,t.lineIndent-1,tn,!1,!0),Ln(t,!0,-1),t.checkLineBreaks&&an.test(t.input.slice(o,t.position))&&Tn(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&Mn(t)?46===t.input.charCodeAt(t.position)&&(t.position+=3,Ln(t,!0,-1)):t.position<t.length-1&&kn(t,"end of the stream or a document separator is expected")}function qn(t,e){e=e||{},0!==(t=String(t)).length&&(10!==t.charCodeAt(t.length-1)&&13!==t.charCodeAt(t.length-1)&&(t+="\n"),65279===t.charCodeAt(0)&&(t=t.slice(1)));var i=new _n(t,e),r=t.indexOf("\0");for(-1!==r&&(i.position=r,kn(i,"null byte is not allowed in input")),i.input+="\0";32===i.input.charCodeAt(i.position);)i.lineIndent+=1,i.position+=1;for(;i.position<i.length-1;)Dn(i);return i.documents}var $n=Or,zn={loadAll:function(t,e,i){null!==e&&"object"==typeof e&&void 0===i&&(i=e,e=null);var r=qn(t,i);if("function"!=typeof e)return r;for(var n=0,o=r.length;n<o;n+=1)e(r[n])},load:function(t,e){var i=qn(t,e);if(0!==i.length){if(1===i.length)return i[0];throw new mr("expected a single document in the stream, but found more")}}}.load;const Pn=t=>t.replace(/\r\n?/g,"\n").replace(/<(\w+)([^>]*)>/g,((t,e,i)=>"<"+e+i.replace(/="([^"]*)"/g,"='$1'")+">")),Rn=t=>{const{text:e,metadata:i}=function(t){const e=t.match(Ht);if(!e)return{text:t,metadata:{}};let i=zn(e[1],{schema:$n})??{};i="object"!=typeof i||Array.isArray(i)?{}:i;const r={};return i.displayMode&&(r.displayMode=i.displayMode.toString()),i.title&&(r.title=i.title.toString()),i.config&&(r.config=i.config),{text:t.slice(e[0].length),metadata:r}}(t),{displayMode:r,title:n,config:o={}}=i;return r&&(o.gantt||(o.gantt={}),o.gantt.displayMode=r),{title:n,config:o,text:e}},Wn=t=>{const e=ke.detectInit(t)??{},i=ke.detectDirective(t,"wrap");return Array.isArray(i)?e.wrap=i.some((({type:t})=>{})):"wrap"===(null==i?void 0:i.type)&&(e.wrap=!0),{text:(r=t,r.replace(Yt,"")),directive:e};var r};function Un(t){const e=Pn(t),i=Rn(e),r=Wn(i.text),n=ve(i.config,r.directive);return{code:t=ur(r.text),title:i.title,config:n}}const Hn=["foreignobject"],Yn=["dominant-baseline"];function Vn(t){const e=Un(t);return De(),Ie(e.config??{}),e}const Gn=(t,e,i=[])=>`\n.${t} ${e} { ${i.join(" !important; ")} !important; }`,Xn=(t,e,i,r)=>{const n=((t,e={})=>{var i;let r="";if(void 0!==t.themeCSS&&(r+=`\n${t.themeCSS}`),void 0!==t.fontFamily&&(r+=`\n:root { --mermaid-font-family: ${t.fontFamily}}`),void 0!==t.altFontFamily&&(r+=`\n:root { --mermaid-alt-font-family: ${t.altFontFamily}}`),!(0,ot.A)(e)){const n=t.htmlLabels||(null==(i=t.flowchart)?void 0:i.htmlLabels)?["> *","span"]:["rect","polygon","ellipse","circle","path"];for(const t in e){const i=e[t];(0,ot.A)(i.styles)||n.forEach((t=>{r+=Gn(i.id,t,i.styles)})),(0,ot.A)(i.textStyles)||(r+=Gn(i.id,"tspan",i.textStyles))}}return r})(t,i);return M(tt(`${r}{${_i(e,n,t.themeVariables)}}`),E)},Zn=(t,e,i,r,n)=>{const o=t.append("div");o.attr("id",i),r&&o.attr("style",r);const a=o.append("svg").attr("id",e).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg");return n&&a.attr("xmlns:xlink",n),a.append("g"),t};function Jn(t,e){return t.append("iframe").attr("id",e).attr("style","width: 100%; height: 100%;").attr("sandbox","")}const Qn=(t,e={})=>{const{code:i}=Un(t);return lr(i,e)};const Kn=Object.freeze({render:async function(t,e,i){var r,n,o,l,c,h;ar();const u=Vn(e);e=u.code;const d=Oe();st.debug(d),e.length>((null==d?void 0:d.maxTextSize)??5e4)&&(e="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa");const f="#"+t,p="i"+t,g="#"+p,m="d"+t,y="#"+m;let x=(0,a.Ltv)("body");const C="sandbox"===d.securityLevel,b="loose"===d.securityLevel,_=d.fontFamily;if(void 0!==i){if(i&&(i.innerHTML=""),C){const t=Jn((0,a.Ltv)(i),p);x=(0,a.Ltv)(t.nodes()[0].contentDocument.body),x.node().style.margin=0}else x=(0,a.Ltv)(i);Zn(x,t,m,`font-family: ${_}`,"http://www.w3.org/1999/xlink")}else{if(((t,e,i,r)=>{var n,o,a;null==(n=t.getElementById(e))||n.remove(),null==(o=t.getElementById(i))||o.remove(),null==(a=t.getElementById(r))||a.remove()})(document,t,m,p),C){const t=Jn((0,a.Ltv)("body"),p);x=(0,a.Ltv)(t.nodes()[0].contentDocument.body),x.node().style.margin=0}else x=(0,a.Ltv)("body");Zn(x,t,m)}let v,k;try{v=await Qn(e,{title:u.title})}catch(O){v=new sr("error"),k=O}const T=x.select(y).node(),A=v.type,w=T.firstChild,S=w.firstChild,B=null==(n=(r=v.renderer).getClasses)?void 0:n.call(r,e,v),F=Xn(d,A,B,f),L=document.createElement("style");L.innerHTML=F,w.insertBefore(L,S);try{await v.renderer.draw(e,t,Ae,v)}catch(j){throw Vi.draw(e,t,Ae),j}!function(t,e,i,r){(function(t,e){t.attr("role",hr),""!==e&&t.attr("aria-roledescription",e)})(e,t),function(t,e,i,r){if(void 0!==t.insert){if(i){const e=`chart-desc-${r}`;t.attr("aria-describedby",e),t.insert("desc",":first-child").attr("id",e).text(i)}if(e){const i=`chart-title-${r}`;t.attr("aria-labelledby",i),t.insert("title",":first-child").attr("id",i).text(e)}}}(e,i,r,e.attr("id"))}(A,x.select(`${y} svg`),null==(l=(o=v.db).getAccTitle)?void 0:l.call(o),null==(h=(c=v.db).getAccDescription)?void 0:h.call(c)),x.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns","http://www.w3.org/1999/xhtml");let M=x.select(y).node().innerHTML;if(st.debug("config.arrowMarkerAbsolute",d.arrowMarkerAbsolute),M=((t="",e,i)=>{let r=t;return i||e||(r=r.replace(/marker-end="url\([\d+./:=?A-Za-z-]*?#/g,'marker-end="url(#')),r=Te(r),r=r.replace(/<br>/g,"<br/>"),r})(M,C,yt(d.arrowMarkerAbsolute)),C){M=((t="",e)=>{var i,r;return`<iframe style="width:100%;height:${(null==(r=null==(i=null==e?void 0:e.viewBox)?void 0:i.baseVal)?void 0:r.height)?e.viewBox.baseVal.height+"px":"100%"};border:0;margin:0;" src="data:text/html;base64,${btoa('<body style="margin:0">'+t+"</body>")}" sandbox="allow-top-navigation-by-user-activation allow-popups">\n The "iframe" tag is not supported by your browser.\n</iframe>`})(M,x.select(y+" svg").node())}else b||(M=s.sanitize(M,{ADD_TAGS:Hn,ADD_ATTR:Yn}));if(cr.forEach((t=>{t()})),cr=[],k)throw k;const E=C?g:y,N=(0,a.Ltv)(E).node();return N&&"remove"in N&&N.remove(),{svg:M,bindFunctions:v.db.bindFunctions}},parse:async function(t,e){ar(),t=Vn(t).code;try{await Qn(t)}catch(i){if(null==e?void 0:e.suppressErrors)return!1;throw i}return!0},getDiagramFromText:Qn,initialize:function(t={}){var e;(null==t?void 0:t.fontFamily)&&!(null==(e=t.themeVariables)?void 0:e.fontFamily)&&(t.themeVariables||(t.themeVariables={}),t.themeVariables.fontFamily=t.fontFamily),Se=te({},t),(null==t?void 0:t.theme)&&t.theme in Dt?t.themeVariables=Dt[t.theme].getThemeVariables(t.themeVariables):t&&(t.themeVariables=Dt.default.getThemeVariables(t.themeVariables));const i="object"==typeof t?(t=>(Be=te({},we),Be=te(Be,t),t.theme&&Dt[t.theme]&&(Be.themeVariables=Dt[t.theme].getThemeVariables(t.themeVariables)),Me(Be,Fe),Be))(t):Ee();lt(i.logLevel),ar()},getConfig:Oe,setConfig:Ne,getSiteConfig:Ee,updateSiteConfig:t=>(Be=te(Be,t),Me(Be,Fe),Be),reset:()=>{De()},globalReset:()=>{De(we)},defaultConfig:we});lt(Oe().logLevel),De(Oe());const to=(t,e,i)=>{st.warn(t),be(t)?(i&&i(t.str,t.hash),e.push({...t,message:t.str,error:t})):(i&&i(t),t instanceof Error&&e.push({str:t.message,message:t.message,hash:t.name,error:t}))},eo=async function(t={querySelector:".mermaid"}){try{await io(t)}catch(e){if(be(e)&&st.error(e.str),co.parseError&&co.parseError(e),!t.suppressErrors)throw st.error("Use the suppressErrors option to suppress these errors"),e}},io=async function({postRenderCallback:t,querySelector:e,nodes:i}={querySelector:".mermaid"}){const n=Kn.getConfig();let o;if(st.debug((t?"":"No ")+"Callback function found"),i)o=i;else{if(!e)throw new Error("Nodes and querySelector are both undefined");o=document.querySelectorAll(e)}st.debug(`Found ${o.length} diagrams`),void 0!==(null==n?void 0:n.startOnLoad)&&(st.debug("Start On Load: "+(null==n?void 0:n.startOnLoad)),Kn.updateSiteConfig({startOnLoad:null==n?void 0:n.startOnLoad}));const a=new ke.InitIDGenerator(n.deterministicIds,n.deterministicIDSeed);let s;const l=[];for(const h of Array.from(o)){if(st.info("Rendering diagram: "+h.id),h.getAttribute("data-processed"))continue;h.setAttribute("data-processed","true");const e=`mermaid-${a.next()}`;s=h.innerHTML,s=(0,r.T)(ke.entityDecode(s)).trim().replace(/<br\s*\/?>/gi,"<br/>");const i=ke.detectInit(s);i&&st.debug("Detected early reinit: ",i);try{const{svg:i,bindFunctions:r}=await lo(e,s,h);h.innerHTML=i,t&&await t(e),r&&r(h)}catch(c){to(c,l,co.parseError)}}if(l.length>0)throw l[0]},ro=function(t){Kn.initialize(t)},no=function(){if(co.startOnLoad){const{startOnLoad:t}=Kn.getConfig();t&&co.run().catch((t=>st.error("Mermaid failed to initialize",t)))}};"undefined"!=typeof document&&window.addEventListener("load",no,!1);const oo=[];let ao=!1;const so=async()=>{if(!ao){for(ao=!0;oo.length>0;){const e=oo.shift();if(e)try{await e()}catch(t){st.error("Error executing queue",t)}}ao=!1}},lo=(t,e,i)=>new Promise(((r,n)=>{oo.push((()=>new Promise(((o,a)=>{Kn.render(t,e,i).then((t=>{o(t),r(t)}),(t=>{var e;st.error("Error parsing",t),null==(e=co.parseError)||e.call(co,t),a(t),n(t)}))})))),so().catch(n)})),co={startOnLoad:!0,mermaidAPI:Kn,parse:async(t,e)=>new Promise(((i,r)=>{oo.push((()=>new Promise(((n,o)=>{Kn.parse(t,e).then((t=>{n(t),i(t)}),(t=>{var e;st.error("Error parsing",t),null==(e=co.parseError)||e.call(co,t),o(t),r(t)}))})))),so().catch(r)})),render:lo,init:async function(t,e,i){st.warn("mermaid.init is deprecated. Please use run instead."),t&&ro(t);const r={postRenderCallback:i,querySelector:".mermaid"};"string"==typeof e?r.querySelector=e:e&&(e instanceof HTMLElement?r.nodes=[e]:r.nodes=e),await eo(r)},run:eo,registerExternalDiagrams:async(t,{lazyLoad:e=!0}={})=>{Jt(...t),!1===e&&await(async()=>{st.debug("Loading registered diagrams");const t=(await Promise.allSettled(Object.entries(Xt).map((async([t,{detector:e,loader:i}])=>{if(i)try{Wi(t)}catch(r){try{const{diagram:t,id:r}=await i();Ri(r,t,e)}catch(n){throw st.error(`Failed to load external diagram with key ${t}. Removing from detectors.`),delete Xt[t],n}}})))).filter((t=>"rejected"===t.status));if(t.length>0){st.error(`Failed to load ${t.length} external diagrams`);for(const e of t)st.error(e);throw new Error(`Failed to load ${t.length} external diagrams`)}})()},initialize:ro,parseError:void 0,contentLoaded:no,setParseErrorHandler:function(t){co.parseError=t},detectType:Zt}}}]); \ No newline at end of file diff --git a/assets/js/43498.6eca7dce.js.LICENSE.txt b/assets/js/43498.6eca7dce.js.LICENSE.txt new file mode 100644 index 0000000000..110c6efd55 --- /dev/null +++ b/assets/js/43498.6eca7dce.js.LICENSE.txt @@ -0,0 +1,9 @@ +/*! + * Wait for document loaded before starting the execution + */ + +/*! @license DOMPurify 3.1.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.1.6/LICENSE */ + +/*! Check if previously processed */ + +/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ diff --git a/assets/js/437bedbc.a0a08777.js b/assets/js/437bedbc.a0a08777.js new file mode 100644 index 0000000000..eac9373668 --- /dev/null +++ b/assets/js/437bedbc.a0a08777.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[19745],{3904:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"releases/Release4","title":"Release Notes for SCS Release 4","description":"(Release Date: 2023-03-22)","source":"@site/docs/06-releases/Release4.md","sourceDirName":"06-releases","slug":"/releases/Release4","permalink":"/docs/releases/Release4","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release4.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Release Notes for SCS Release 3","permalink":"/docs/releases/Release3"},"next":{"title":"Release Notes for SCS Release 5","permalink":"/docs/releases/Release5"}}');var i=n(74848),r=n(28453);const o={},a="Release Notes for SCS Release 4",l={},d=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"New Features (Highlights)",id:"new-features-highlights",level:2},{value:"Operator focused improvements",id:"operator-focused-improvements",level:3},{value:"SCS Developer focused improvements (testbed and k8s cluster management)",id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Deprecations via OSISM",id:"deprecations-via-osism",level:3},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Resolved Issues",id:"resolved-issues",level:2},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R4",id:"list-of-known-issues--restrictions-in-r4",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Thanks",id:"thanks",level:2}];function c(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"release-notes-for-scs-release-4",children:"Release Notes for SCS Release 4"})}),"\n",(0,i.jsx)(s.p,{children:"(Release Date: 2023-03-22)"}),"\n",(0,i.jsx)(s.h2,{id:"scope",children:"Scope"}),"\n",(0,i.jsx)(s.p,{children:"Release 4 has been developed alongside a set of associated outcomes. These outcomes are comprised of:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"SCS is standardized"}),"\n",(0,i.jsx)(s.li,{children:"SCS is federated"}),"\n",(0,i.jsx)(s.li,{children:"SCS is continuously built and tested"}),"\n",(0,i.jsx)(s.li,{children:"SCS is understandable"}),"\n",(0,i.jsx)(s.li,{children:"SCS enables Operators with an excellent toolbox"}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:"The SCS project is completely developed in the open, based on the principles of the four opens. Due to this a lot of our work can be tracked and used continuously without waiting for the half-year releases. Especially, but not limited to, this includes our efforts in regards to documentation and our standards."}),"\n",(0,i.jsxs)(s.p,{children:["One of the major highlights that happened in the R4 development cycle is our work on assuring ",(0,i.jsx)(s.em,{children:"SCS is understandable"}),".\nBe sure to look at ",(0,i.jsx)(s.a,{href:"https://docs.scs.community",children:"our new documentation entry point"}),".\nWe have created a ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/contribute/adding-docs-guide.md",children:"systematic approach"})," to structure documentation which already has been implemented for the ",(0,i.jsx)(s.a,{href:"https://docs.scs.community/docs/category/openstack-image-manager/",children:"OpenStack Image Manager"}),",\nthe ",(0,i.jsx)(s.a,{href:"https://docs.scs.community/docs/category/osism-testbed/",children:"OSISM testbed"})," and the ",(0,i.jsx)(s.a,{href:"https://docs.scs.community/docs/category/k8s-cluster-api-provider/",children:"K8s Cluster API Provider"}),". More will follow in a continuous manner."]}),"\n",(0,i.jsxs)(s.p,{children:["Our community has created a growing amount of ",(0,i.jsx)(s.a,{href:"https://scs.community/blog/",children:"blog articles"})," which also help to understand the SCS project, its community and the technology that is worked on."]}),"\n",(0,i.jsx)(s.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://releases.openstack.org/zed/highlights.html",children:"OpenStack Zed release"})}),"\n",(0,i.jsx)(s.li,{children:"Ceph Quincy is available, the default release of Ceph is still Pacific."}),"\n",(0,i.jsxs)(s.li,{children:["The base infrastructure is provided by\n",(0,i.jsx)(s.a,{href:"https://release.osism.tech/notes/5.0.0.html",children:"OSISM 5.0.0"}),"\nwhich in turn builds on top of kolla and kolla-ansible."]}),"\n",(0,i.jsxs)(s.li,{children:["With ",(0,i.jsx)(s.a,{href:"https://github.com/osism/cloud-in-a-box",children:"Cloud-in-a-Box"})," there is an easy way to get SCS up and running on a single hardware node as a test environment. There are two blog posts (",(0,i.jsx)(s.a,{href:"https://scs.community/2023/03/15/ciab/",children:"part 1"})," and ",(0,i.jsx)(s.a,{href:"https://scs.community/2023/03/15/ciab-2/",children:"part2"}),") covering it."]}),"\n",(0,i.jsx)(s.li,{children:"For new deployments of the IaaS reference implementation Ubuntu 22.04 is recommended while existing installations can be upgraded to R4 while staying on Ubuntu 20.04. With Release 5, upgrading to Ubuntu 22.04 will be required."}),"\n",(0,i.jsxs)(s.li,{children:["With ",(0,i.jsx)(s.a,{href:"https://github.com/osism/node-image",children:"osism/node-image"})," an iso image for much easier bootstrapping of new OSISM environments is available now"]}),"\n",(0,i.jsxs)(s.li,{children:["The software for our ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"Kubernetes Cluster-API reference implementation"})," has been updated and highlights are covered in own ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R4.md",children:"release notes"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"new-features-highlights",children:"New Features (Highlights)"}),"\n",(0,i.jsx)(s.h3,{id:"operator-focused-improvements",children:"Operator focused improvements"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["The ",(0,i.jsx)(s.a,{href:"https://github.com/osism/openstack-image-manager",children:"Openstack Image Manager"})," has seen many improvements and is the reference command to assure the images available comply with the ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Drafts/Image-Properties-Spec.md",children:"SCS Image Standard"})]}),"\n",(0,i.jsxs)(s.li,{children:["For Ceph, special playbooks were added to validate the deployment status of the OSD, MON and MGR services in OSISM. The commands for use are ",(0,i.jsx)(s.code,{children:"osism validate ceph-osds"}),", ",(0,i.jsx)(s.code,{children:"osism validate ceph-mons"}),", and ",(0,i.jsx)(s.code,{children:"osism validate ceph-mgrs"}),"."]}),"\n",(0,i.jsx)(s.li,{children:"OVN has been updated to version 22.09."}),"\n",(0,i.jsx)(s.li,{children:"OVS has been updated to version 3.0.1."}),"\n",(0,i.jsxs)(s.li,{children:["The ",(0,i.jsx)(s.a,{href:"https://github.com/osism/testbed",children:"testbed"})," uses per default a proxy for container pulling. This will allow for airgapped installations out of the box. Please note: a full airgap support (with local mirrors, etc.) will follow in a future release."]}),"\n",(0,i.jsxs)(s.li,{children:["The efforts to create a well-maintained status page with well-defined interfaces resulted in an OpenAPI specification (within its own ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi",children:"repository"}),") which is intended to be implementable by multiple implementations."]}),"\n",(0,i.jsxs)(s.li,{children:["The dashboard of the ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/",children:"OpenStack Health Monitor"})," is in use by the SCS operators and has proven helpful a number of times in detecting and addressing issues. That said, it only received a few fixes and minor enhancements, as we plan to replace it with a more generic and more maintainable solution soon."]}),"\n",(0,i.jsx)(s.li,{children:"The k8s clusters built with our k8s-capi implementation now allow controlling the versions of more components; the latest tested and stable versions are used by default (if enabled). The latest version for the cilium CNI for example allows testing the upcoming k8s gateway API."}),"\n",(0,i.jsx)(s.li,{children:"The k8s cluster now allows filtering access to the kubernetes API by IP ranges."}),"\n",(0,i.jsx)(s.li,{children:"The k8s clusters now have the proxy protocol enabled with the nginx-ingress controller, so client IPs are visible; the previous issue that blocked internal access could be worked around."}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",children:"SCS Developer focused improvements (testbed and k8s cluster management)"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["The testbed has been significantly simplified for new operators and developers and a ",(0,i.jsx)(s.a,{href:"https://docs.osism.tech/testbed/quickstart.html",children:"Quick Start"})," guide has been added."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["For the IaaS reference implementation, please refer to the ",(0,i.jsx)(s.a,{href:"https://release.osism.tech/notes/5.0.0.html#upgrade-notes",children:"OSISM 5.0.0 Upgrade Notes"}),"."]}),"\n",(0,i.jsxs)(s.li,{children:["The k8s Cluster Management solution has an enhanced ",(0,i.jsx)(s.a,{href:"https://docs.scs.community/docs/k8s-cluster-api-provider/doc/Upgrade-Guide",children:"upgrade guide"})," that covers the upgrade of clusters as well as the upgrade of the cluster management server."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"removals",children:"Removals"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"The ospurge wrapper script has been removed from the osism.services.openstackclient role. The ospurge project is no longer compatible with the current OpenStack SDK. The command openstack project purge can be used as an alternative."}),"\n",(0,i.jsx)(s.li,{children:"The docker-compose package is uninstalled by the osism.commons.docker_compose role. The Compose v2 plugin for Docker is now used instead of the old standalone docker-compose CLI. A dummy script has been added to /usr/local/bin which displays a corresponding message when using docker-compose."}),"\n",(0,i.jsxs)(s.li,{children:["Further removals from the IaaS reference implementation, please refer to the ",(0,i.jsx)(s.a,{href:"https://release.osism.tech/notes/5.0.0.html#removals",children:"OSISM 5.0.0 Removals Section"}),"."]}),"\n",(0,i.jsxs)(s.li,{children:["The k8s cluster parameter ",(0,i.jsx)(s.code,{children:"ETCD_PRIO_BOOST"})," that was already unused has been removed as announced with R3."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,i.jsx)(s.h3,{id:"deprecations-via-osism",children:"Deprecations via OSISM"}),"\n",(0,i.jsxs)(s.p,{children:["For these please also refer to the ",(0,i.jsx)(s.a,{href:"https://release.osism.tech/notes/5.0.0.html#deprecations",children:"upstream deprecation notices"})]}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"The role osism.services.bird is deprecated. In future, FRRouting (osism.services.frr) will be used."}),"\n",(0,i.jsx)(s.li,{children:"The role osism.services.minikube is deprecated. In future osism.services.k8s will be used."}),"\n",(0,i.jsx)(s.li,{children:"Heat is deprecated in favor of more generic Infrastructure as Code tools like Terraform as of now and will be removed in the future (exact removal date is not yet known)"}),"\n",(0,i.jsx)(s.li,{children:"Swift (currently available as Technical Preview) will be removed in favor of Ceph RGW"}),"\n",(0,i.jsx)(s.li,{children:"Trove (currently available as Technical Preview) will be removed in favor of Kubernetes database operators"}),"\n",(0,i.jsxs)(s.li,{children:["Skydive (currently available as Technical Preview) will be removed in the future, the project is not maintained anymore, last commit is 8th Jan 2022: ",(0,i.jsx)(s.a,{href:"https://review.opendev.org/c/openstack/kolla/+/869191",children:"https://review.opendev.org/c/openstack/kolla/+/869191"})]}),"\n",(0,i.jsxs)(s.li,{children:["The login to a registry with the ",(0,i.jsx)(s.code,{children:"osism.services.docker"})," role is deprecated in favor of the new ",(0,i.jsx)(s.code,{children:"osism.commons.docker_login"})," role."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,i.jsx)(s.p,{children:"Throughout the Release 4 development cycle, the SCS project issued two security advisories for upstream components:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["In November 2022 an advisory regarding ",(0,i.jsx)(s.a,{href:"https://www.openssl.org/news/secadv/20221101.txt",children:"CVE-2022-3602 and CVE-2022-3786"})," in OpenSSL was issued.\nOur ",(0,i.jsx)(s.a,{href:"https://scs.community/security/2022/11/01/advisory-spookyssl/",children:"advisory"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["In February 2023 an advisory regarding ",(0,i.jsx)(s.a,{href:"https://cve.report/CVE-2022-47951",children:"CVE 2022-47951"})," in OpenStack components nova and glance was published.\nOur ",(0,i.jsx)(s.a,{href:"https://scs.community/security/2023/01/24/cve-2022-47951/",children:"advisory"}),"."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:"Fixes were delivered via maintenance updates to existing R3 deployments, but of course also included in the main development branch that became R4."}),"\n",(0,i.jsx)(s.h2,{id:"resolved-issues",children:"Resolved Issues"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Breakage with old kustomize syntax has been addressed.(",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/issues/328",children:"k8s-capi/#328"}),")"]}),"\n",(0,i.jsxs)(s.li,{children:["The move of k8s container images from k8s.gcr.io to registry.k8s.io needed adjustments.(",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/issues/321",children:"k8s-capi/#321"}),")"]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,i.jsxs)(s.p,{children:["The last months saw intense work in the standardization area. The process how standards are created has been documented.\nThe standards are collected in its own ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards",children:"standards"}),' repository.\nA machine readable file lists the required (and optional) standards that apply to "SCS-compatible" conformance at\nthe IaaS and the Container (KaaS) layer. The referenced executables are used by the compliance checking framework\nto test existing implementations for compliance. To run the checker, the tester needs access to the infrastructure\nunder test (normal user privileges are sufficient) and standard openstack and kubernetes client tools -- or just\nuse the docker container that is provided.']}),"\n",(0,i.jsxs)(s.p,{children:["The public clouds based on the SCS reference implementation from plusserver and Noris/Wavecon are tested automatically\nfrom us and the live result is visible in ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards",children:"standards page"}),".\nWe will enhance the standardization and test coverage significantly in the next months and we hope to list a number\nof more clouds there soon."]}),"\n",(0,i.jsx)(s.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,i.jsxs)(s.p,{children:["The code in OSISM and a number of SCS repositories will receive the ",(0,i.jsx)(s.code,{children:"v5.0.0"})," tag; some repositories use\n",(0,i.jsx)(s.code,{children:"maintained/v5.0.x"})," and ",(0,i.jsx)(s.code,{children:"maintained/v5.x"})," branches for providing code that only gets bug- and security fixes (5.0.x)\nor only those plus selected, backwards-compatible enhancements (5.x)."]}),"\n",(0,i.jsx)(s.h2,{id:"list-of-known-issues--restrictions-in-r4",children:"List of known issues & restrictions in R4"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"The k8s cluster-API code does not work well with OpenStack API endpoints that require trusting a custom CA."}),"\n",(0,i.jsxs)(s.li,{children:["The OpenStack component Horizon has two issues when working with Swift endpoints. One issue is a ",(0,i.jsx)(s.a,{href:"https://bugs.launchpad.net/horizon/+bug/1993005",children:"known bug"})," when uploading objects to Swift endpoints. A workaround will be released shortly after R4. The ",(0,i.jsx)(s.a,{href:"https://github.com/osism/issues/issues/488",children:"second issue"})," is that existing Swift containers can not be set to public."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(s.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,i.jsx)(s.a,{href:"https://scs.community/contribute/",children:"How to contribute page"}),"."]}),"\n",(0,i.jsx)(s.h2,{id:"thanks",children:"Thanks"}),"\n",(0,i.jsx)(s.p,{children:"The work for R4 has been done by many contributors from our community.\nThe special thanks goes out to our contributors who participate in our community\non a very regular base - without these the various team calls and events like\nthe hackathons would be much less successful and fun."}),"\n",(0,i.jsx)(s.p,{children:"Of course we are leveraging a huge amount of open source technology that has been\ncreated by our friends in other communities, many of which are part of the\nCNCF, Linux Foudation, OIF, and others. We participate and contribute where\nwe can and definitely want to acknowledge the great work that we build upon."})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var t=n(96540);const i={},r=t.createContext(i);function o(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/43915cdf.5b6049bd.js b/assets/js/43915cdf.5b6049bd.js new file mode 100644 index 0000000000..b5183842fa --- /dev/null +++ b/assets/js/43915cdf.5b6049bd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[86512],{26589:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"operating-scs/components/status-page-deployment/docs/usage","title":"Usage","description":"You can use and test the API via any API client (Bruno, built in Swagger UI, etc.), CLI tool (like curl) or the web frontend.","source":"@site/docs/04-operating-scs/components/status-page-deployment/docs/usage.md","sourceDirName":"04-operating-scs/components/status-page-deployment/docs","slug":"/operating-scs/components/status-page-deployment/docs/usage","permalink":"/docs/operating-scs/components/status-page-deployment/docs/usage","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-deployment/docs/usage.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"SCS Public","permalink":"/docs/operating-scs/components/status-page-deployment/docs/scs-public"},"next":{"title":"Monitoring","permalink":"/docs/operating-scs/components/status-page-deployment/docs/monitoring"}}');var o=t(74848),r=t(28453);const c={},i="Usage",a={},d=[{value:"Receive auth code",id:"receive-auth-code",level:2},{value:"Exchange token",id:"exchange-token",level:3},{value:"Use API",id:"use-api",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"usage",children:"Usage"})}),"\n",(0,o.jsxs)(n.p,{children:["You can use and test the API via any API client (",(0,o.jsx)(n.a,{href:"https://www.usebruno.com/",children:"Bruno"}),", built in Swagger UI, etc.), CLI tool (like ",(0,o.jsx)(n.code,{children:"curl"}),") or the web frontend."]}),"\n",(0,o.jsxs)(n.p,{children:["All examples provided use ",(0,o.jsx)(n.code,{children:"curl"}),", the most manual methods and the public SCS release."]}),"\n",(0,o.jsx)(n.h2,{id:"receive-auth-code",children:"Receive auth code"}),"\n",(0,o.jsxs)(n.p,{children:["Visit the ",(0,o.jsx)(n.a,{href:"https://status-idp.k8s.scs.community/.well-known/openid-configuration",children:"openid-configuration"})," of the running Dex and build an auth URL from the provided information and your desired parameters."]}),"\n",(0,o.jsx)(n.p,{children:"For example:"}),"\n",(0,o.jsx)(n.p,{children:"https:///login"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-txt",children:"https://status-idp.k8s.scs.community/auth?client_id=status-page-web&redirect_uri=https%3A%2F%2Fstatus.k8s.scs.community%2Flogin&response_type=code&scope=openid+profile+email+offline_access\n"})}),"\n",(0,o.jsx)(n.p,{children:"And visit the generated URL to start the Authorization Code Flow."}),"\n",(0,o.jsxs)(n.p,{children:["After authentication you get redirect to ",(0,o.jsx)(n.code,{children:"https://status.k8s.scs.community/login?code=<your-code>&state="})]}),"\n",(0,o.jsx)(n.h3,{id:"exchange-token",children:"Exchange token"}),"\n",(0,o.jsx)(n.p,{children:"Copy your code and send it to the token URL."}),"\n",(0,o.jsx)(n.p,{children:"For example:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'$ curl -sL \\\n-X POST \\\n-H \'Content-Type: application/x-www-form-urlencoded\' \\\n-d \'client_id=status-page-web\' \\\n-d \'client_secret=<your-secret>\' \\\n-d \'code=<your-code>\' \\\n-d \'redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Flogin\' \\\n-d \'grant_type=authorization_code\' \\\nhttps://status-idp.k8s.scs.community/token\n\n{\n "access_token": "<your-access-token>",\n "token_type": "bearer",\n "expires_in": 86399,\n "refresh_token": "<your-refresh-token>",\n "id_token": "<your-id-token>"\n}\n'})}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"NOTE"}),": Be ",(0,o.jsx)(n.strong,{children:"extremely careful"})," with your ",(0,o.jsx)(n.strong,{children:"code"})," and ",(0,o.jsx)(n.strong,{children:"client secret"})," as they represent ",(0,o.jsx)(n.strong,{children:"credentials"}),"!"]}),"\n",(0,o.jsx)(n.h3,{id:"use-api",children:"Use API"}),"\n",(0,o.jsx)(n.p,{children:"Copy your id token and use it as bearer token in writing requests."}),"\n",(0,o.jsx)(n.p,{children:"For example creating a new component:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl -sL \\\n-X POST \\\n-H 'Authorization: Bearer <your-id-token>' \\\n-H 'Content-Type: application/json' \\\n-d '{\"displayName\":\"Test-Component\"}'\\\nhttps://status-api.k8s.scs.community/components\n"})}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"NOTE"}),": Be ",(0,o.jsx)(n.strong,{children:"extremely careful"})," with your ",(0,o.jsx)(n.strong,{children:"id token"})," and ",(0,o.jsx)(n.strong,{children:"access token"})," as they represent ",(0,o.jsx)(n.strong,{children:"credentials"}),"!"]}),"\n",(0,o.jsxs)(n.p,{children:["More usage examples can be found at ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/status-page-api/blob/main/docs/example-requests.md",children:"SovereignCloudStack/status-page-api/docs/example-requests.md"})]})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var s=t(96540);const o={},r=s.createContext(o);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/440f3548.d9ef556f.js b/assets/js/440f3548.d9ef556f.js new file mode 100644 index 0000000000..fbf50b0e22 --- /dev/null +++ b/assets/js/440f3548.d9ef556f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[99417],{86105:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"application-examples/opendesk-on-scs/quickstart","title":"Quickstart","description":"To get started quickly, you can use the wrapper script that does parts of the work described in Getting started. Please see that page for details nevertheless. # noqa: [relative-link-path]","source":"@site/user-docs/application-examples/opendesk-on-scs/quickstart.md","sourceDirName":"application-examples/opendesk-on-scs","slug":"/application-examples/opendesk-on-scs/quickstart","permalink":"/user-docs/application-examples/opendesk-on-scs/quickstart","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"userDocs","previous":{"title":"Overview","permalink":"/user-docs/application-examples/opendesk-on-scs/overview"},"next":{"title":"Requirements","permalink":"/user-docs/application-examples/opendesk-on-scs/requirements"}}');var o=n(74848),r=n(28453);const i={},a="Quickstart",l={},c=[];function d(e){const s={a:"a",code:"code",h1:"h1",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,o.jsxs)(s.p,{children:["To get started quickly, you can use the ",(0,o.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/opendesk-on-scs/blob/main/helper/deploy-openDesk",children:"wrapper script"})," that does parts of the work described in ",(0,o.jsx)(s.a,{href:"/user-docs/application-examples/opendesk-on-scs/getting_started",children:"Getting started"}),". Please see that page for details nevertheless. # noqa: [relative-link-path]"]}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.a,{href:"https://docs.scs.community/docs/faq/",children:"Get a Sovereign Cloud Stack cluster"}),"."]}),"\n",(0,o.jsxs)(s.li,{children:["Go through the openDesk ",(0,o.jsx)(s.a,{href:"/user-docs/application-examples/opendesk-on-scs/requirements",children:"requirements"}),"."]}),"\n",(0,o.jsxs)(s.li,{children:["Clone the ",(0,o.jsx)(s.a,{href:"https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk",children:"openDesk repository"}),":"]}),"\n"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"git clone https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk\ncd opendesk\n"})}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["Create a folder for the settings of your environment: ",(0,o.jsx)(s.code,{children:"mkdir -p helmfile/environments/example-env/dev/"})]}),"\n",(0,o.jsxs)(s.li,{children:["Add one or more files with your configuration, for example ",(0,o.jsx)(s.code,{children:"values.yaml.gotmpl"})," (see ",(0,o.jsx)(s.a,{href:"/user-docs/application-examples/opendesk-on-scs/getting_started",children:"Getting Started"})," for an example)."]}),"\n",(0,o.jsxs)(s.li,{children:["Reference the environment you want to deploy in ",(0,o.jsx)(s.code,{children:"helmfile.yaml"}),":"]}),"\n"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:'cat helmfile.yaml <<__EOF__\nexample-env:\n values:\n - "helmfile/environments/example-env/dev/*.yaml.gotmpl"\n__EOF__\n'})}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["Download the ",(0,o.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/opendesk-on-scs/blob/main/helper/deploy-openDesk",children:"wrapper script"}),". Make it executable."]}),"\n",(0,o.jsx)(s.li,{children:"Edit the variables at the top of the script to fit your needs."}),"\n",(0,o.jsx)(s.li,{children:"Run it."}),"\n"]})]})}function p(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>i,x:()=>a});var t=n(96540);const o={},r=t.createContext(o);function i(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/441bd449.1e4679b6.js b/assets/js/441bd449.1e4679b6.js new file mode 100644 index 0000000000..a5fce008e2 --- /dev/null +++ b/assets/js/441bd449.1e4679b6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[49851],{46333:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>t,metadata:()=>n,toc:()=>h});const n=JSON.parse('{"id":"iaas/guides/troubleshooting-guide/ceph","title":"Ceph","description":"Where to find docs","source":"@site/docs/02-iaas/guides/troubleshooting-guide/ceph.md","sourceDirName":"02-iaas/guides/troubleshooting-guide","slug":"/iaas/guides/troubleshooting-guide/ceph","permalink":"/docs/iaas/guides/troubleshooting-guide/ceph","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/troubleshooting-guide/ceph.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Ceph"},"sidebar":"docs","previous":{"title":"Rookify (technical preview)","permalink":"/docs/iaas/guides/troubleshooting-guide/rookify"},"next":{"title":"Guides","permalink":"/docs/iaas/guides/"}}');var r=o(74848),d=o(28453);const t={sidebar_label:"Ceph"},i="Ceph",c={},h=[{value:"Where to find docs",id:"where-to-find-docs",level:2},{value:"Critical medium error",id:"critical-medium-error",level:2}];function a(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"ceph",children:"Ceph"})}),"\n",(0,r.jsx)(s.h2,{id:"where-to-find-docs",children:"Where to find docs"}),"\n",(0,r.jsxs)(s.p,{children:["The official Ceph documentation is located on ",(0,r.jsx)(s.a,{href:"https://docs.ceph.com/en/latest/rados/troubleshooting/",children:"https://docs.ceph.com/en/latest/rados/troubleshooting/"})]}),"\n",(0,r.jsxs)(s.p,{children:["It is ",(0,r.jsx)(s.strong,{children:"strongly advised"})," to use the documentation for the version being used."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Pacific - ",(0,r.jsx)(s.a,{href:"https://docs.ceph.com/en/pacific/rados/troubleshooting/",children:"https://docs.ceph.com/en/pacific/rados/troubleshooting/"})]}),"\n",(0,r.jsxs)(s.li,{children:["Quincy - ",(0,r.jsx)(s.a,{href:"https://docs.ceph.com/en/quincy/rados/troubleshooting/",children:"https://docs.ceph.com/en/quincy/rados/troubleshooting/"})]}),"\n",(0,r.jsxs)(s.li,{children:["Reef - ",(0,r.jsx)(s.a,{href:"https://docs.ceph.com/en/reef/rados/troubleshooting/",children:"https://docs.ceph.com/en/reef/rados/troubleshooting/"})]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"critical-medium-error",children:"Critical medium error"}),"\n",(0,r.jsxs)(s.p,{children:["The block device ",(0,r.jsx)(s.code,{children:"sdf"})," has errors. You can see this in the kernel ring buffer, for example."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ sudo dmesg\n[...]\n[14062414.575715] sd 14:0:5:0: [sdf] tag#2120 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=1s\n[14062414.575722] sd 14:0:5:0: [sdf] tag#2120 Sense Key : Medium Error [current] [descriptor]\n[14062414.575725] sd 14:0:5:0: [sdf] tag#2120 Add. Sense: Unrecovered read error\n[14062414.575728] sd 14:0:5:0: [sdf] tag#2120 CDB: Read(16) 88 00 00 00 00 01 09 7c d9 50 00 00 00 80 00 00\n[14062414.575730] critical medium error, dev sdf, sector 4454144360 op 0x0:(READ) flags 0x0 phys_seg 13 prio class 2\n"})}),"\n",(0,r.jsx)(s.p,{children:"It may also be displayed in the health details of Ceph."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ ceph -s\n[...]\n health: HEALTH_WARN\n Too many repaired reads on 1 OSDs\n[...]\n\n$ ceph health detail\nHEALTH_WARN Too many repaired reads on 1 OSDs\n[WRN] OSD_TOO_MANY_REPAIRS: Too many repaired reads on 1 OSDs\n osd.17 had 13 reads repaire\n"})}),"\n",(0,r.jsxs)(s.p,{children:["In this case the block device ",(0,r.jsx)(s.code,{children:"sdf"})," is in the storage node ",(0,r.jsx)(s.code,{children:"sto1001"}),". The OSD assigned\nto this block device can be determined."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ ceph device ls | grep 'sto1001:sdf'\nSEAGATE_ST16000NM004J_ZR604ZDZ0000C210PWE9 sto1001:sdf osd.17\n"})}),"\n",(0,r.jsx)(s.p,{children:"If you only know the OSD ID, you can also determine the associated block device and the storage node."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ ceph device ls | grep osd.17\n[...]\nSEAGATE_ST16000NM004J_ZR604ZDZ0000C210PWE9 sto1001:sdf osd.17\n"})}),"\n",(0,r.jsx)(s.p,{children:"The broken OSD can be removed from the Ceph cluster. The Ceph cluster is then rebalanced.\nThis can take some time and cause a high level of activity on the Ceph cluster."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ ceph osd out osd.17\nmarked out osd.17.\n"})}),"\n",(0,r.jsx)(s.p,{children:"On the storage node disable the OSD service for the OSD."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ sudo systemctl stop ceph-osd@17.service\n"})})]})}function l(e={}){const{wrapper:s}={...(0,d.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},28453:(e,s,o)=>{o.d(s,{R:()=>t,x:()=>i});var n=o(96540);const r={},d=n.createContext(r);function t(e){const s=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:t(e.components),n.createElement(d.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4468ebd1.521491ee.js b/assets/js/4468ebd1.521491ee.js new file mode 100644 index 0000000000..1d10859997 --- /dev/null +++ b/assets/js/4468ebd1.521491ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[98805],{45378:(t,e,o)=>{o.r(e),o.d(e,{assets:()=>l,contentTitle:()=>u,default:()=>m,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var s=o(30107),i=o(74848),n=o(28453);const r={slug:"first-blog-post",title:"First Blog Post",authors:"itrich",tags:["community","howto"]},u=void 0,l={authorsImageUrls:[void 0]},c=[];function a(t){const e={p:"p",...(0,n.R)(),...t.components};return(0,i.jsx)(e.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"})}function m(t={}){const{wrapper:e}={...(0,n.R)(),...t.components};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(a,{...t})}):a(t)}},28453:(t,e,o)=>{o.d(e,{R:()=>r,x:()=>u});var s=o(96540);const i={},n=s.createContext(i);function r(t){const e=s.useContext(n);return s.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function u(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:r(t.components),s.createElement(n.Provider,{value:e},t.children)}},30107:t=>{t.exports=JSON.parse('{"permalink":"/blog/first-blog-post","editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/blog/2022-10-28-first-blog-post.md","source":"@site/blog/2022-10-28-first-blog-post.md","title":"First Blog Post","description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet","date":"2022-10-28T00:00:00.000Z","tags":[{"inline":true,"label":"community","permalink":"/blog/tags/community"},{"inline":true,"label":"howto","permalink":"/blog/tags/howto"}],"readingTime":0.12,"hasTruncateMarker":false,"authors":[{"name":"Eduard Itrich","title":"Community Manager @ SCS","url":"https://github.com/itrich","imageURL":"https://github.com/itrich.png","key":"itrich","page":null}],"frontMatter":{"slug":"first-blog-post","title":"First Blog Post","authors":"itrich","tags":["community","howto"]},"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/452be0ad.89efc290.js b/assets/js/452be0ad.89efc290.js new file mode 100644 index 0000000000..a0ffff8fb0 --- /dev/null +++ b/assets/js/452be0ad.89efc290.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5546],{9840:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>u});const o=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","title":"Overview","description":"The Cluster Stack Provider OpenStack (CSPO) works with the Cluster Stack Operator (CSO) and Cluster Stacks, enabling the creation of Kubernetes clusters in a Cluster-API-native (CAPI) fashion.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs","slug":"/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Contributing","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/"},"next":{"title":"Quickstart","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart"}}');var s=n(74848),c=n(28453);const r={},a="Overview",i={},u=[];function l(e){const t={a:"a",h1:"h1",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,s.jsx)(t.p,{children:"The Cluster Stack Provider OpenStack (CSPO) works with the Cluster Stack Operator (CSO) and Cluster Stacks, enabling the creation of Kubernetes clusters in a Cluster-API-native (CAPI) fashion."}),"\n",(0,s.jsx)(t.p,{children:"The primary goal of the CSPO is to facilitate the import of node images in a manner specific to OpenStack. These images are then used to create Kubernetes workload clusters on top of the OpenStack infrastructure."}),"\n",(0,s.jsxs)(t.p,{children:["To gain a comprehensive understanding of the entire concept, we recommend familiarizing yourself with the fundamental ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/blob/main/docs/concept.md",children:"concepts"})," and ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/blob/main/docs/architecture/overview.md",children:"architecture"})," outlined in ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/blob/main/README.md",children:"CSO"})," and ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks/blob/main/README.md",children:"Cluster Stacks"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var o=n(96540);const s={},c=o.createContext(s);function r(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/45741.81122685.js b/assets/js/45741.81122685.js new file mode 100644 index 0000000000..8e195b996e --- /dev/null +++ b/assets/js/45741.81122685.js @@ -0,0 +1 @@ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[45741],{45741:()=>{}}]); \ No newline at end of file diff --git a/assets/js/45bfeaeb.2b7e3720.js b/assets/js/45bfeaeb.2b7e3720.js new file mode 100644 index 0000000000..71959b708d --- /dev/null +++ b/assets/js/45bfeaeb.2b7e3720.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[34257],{31020:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>u,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"tools/zuul","title":"Zuul","description":"Zuul CI/CD pipelines and project gating","source":"@site/community/tools/zuul.md","sourceDirName":"tools","slug":"/tools/zuul","permalink":"/community/tools/zuul","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Nextcloud","permalink":"/community/tools/nextcloud"},"next":{"title":"Branch Protection Rules","permalink":"/community/tools/github/branchprotection"}}');var i=o(74848),l=o(28453);const s={},r="Zuul",u={},a=[{value:"Zuul CI/CD pipelines and project gating",id:"zuul-cicd-pipelines-and-project-gating",level:2},{value:"How to make a repo use Zuul",id:"how-to-make-a-repo-use-zuul",level:3},{value:"General information about Zuul",id:"general-information-about-zuul",level:3}];function c(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,l.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"zuul",children:"Zuul"})}),"\n",(0,i.jsx)(n.h2,{id:"zuul-cicd-pipelines-and-project-gating",children:"Zuul CI/CD pipelines and project gating"}),"\n",(0,i.jsx)(n.p,{children:"Since we are expecting a lot of pipelines beeing created and used GitHub actions won't keep up\nwell. We also expect cross-repository and even cross-project dependencies. Therefore we decided to\nuse Zuul as our main pipeline solution."}),"\n",(0,i.jsx)(n.h3,{id:"how-to-make-a-repo-use-zuul",children:"How to make a repo use Zuul"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Make Zuul aware of your repository in this ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul_deployment",children:"repo"})]}),"\n",(0,i.jsxs)(n.li,{children:["Create a file ",(0,i.jsx)(n.em,{children:".zuul.yaml"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["An example can be found ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-sandbox/blob/main/.zuul.yaml",children:"here"})]}),"\n",(0,i.jsxs)(n.li,{children:["You can have a job section containing ",(0,i.jsx)(n.em,{children:"self-defined"})," jobs which you need to write on your own"]}),"\n",(0,i.jsxs)(n.li,{children:["You have to have a project section containing","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"the default-branch name"}),"\n",(0,i.jsx)(n.li,{children:"the merge-mode which should be used to auto-merge"}),"\n",(0,i.jsx)(n.li,{children:"the jobs to run in each pipeline (gh_check, gh_gate, gh_post, gh_tag)"}),"\n",(0,i.jsxs)(n.li,{children:["these pipelines are triggered by events which can be looked up ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul_config/blob/main/zuul.d/gh_pipelines.yaml",children:"here"})]}),"\n",(0,i.jsxs)(n.li,{children:["some default jobs can be found ",(0,i.jsx)(n.a,{href:"https://opendev.org/zuul/zuul-jobs/src/branch/master/playbooks",children:"here"})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["If you have ",(0,i.jsx)(n.em,{children:"self-defined"})," jobs, you need to create a folder ",(0,i.jsx)(n.em,{children:".playbooks"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"this folder containers ansible playbooks which will be triggered"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"general-information-about-zuul",children:"General information about Zuul"}),"\n",(0,i.jsx)(n.p,{children:"Zuul does not take anything for granted. If you need to have something installed,\nyou should install it via ansible. Our test-machines are basically pimped\ndocker-containers, so we might run into issues some time. But for now, things work pretty good."})]})}function d(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>r});var t=o(96540);const i={},l=t.createContext(i);function s(e){const n=t.useContext(l);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/45f4377b.e52402bc.js b/assets/js/45f4377b.e52402bc.js new file mode 100644 index 0000000000..826338972e --- /dev/null +++ b/assets/js/45f4377b.e52402bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[68965],{9089:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"iaas/guides/deploy-guide/seed","title":"Seed","description":"The prerequisite for the deployment of a cluster is a configuration repository.","source":"@site/docs/02-iaas/guides/deploy-guide/seed.md","sourceDirName":"02-iaas/guides/deploy-guide","slug":"/iaas/guides/deploy-guide/seed","permalink":"/docs/iaas/guides/deploy-guide/seed","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/seed.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Seed","sidebar_position":10},"sidebar":"docs","previous":{"title":"Deploy Guide","permalink":"/docs/iaas/guides/deploy-guide/"},"next":{"title":"Manager","permalink":"/docs/iaas/guides/deploy-guide/manager"}}');var t=n(74848),s=n(28453);const r={sidebar_label:"Seed",sidebar_position:10},a="Seed",d={},c=[{value:"Install required packages",id:"install-required-packages",level:2},{value:"Get a copy of the configuration repository",id:"get-a-copy-of-the-configuration-repository",level:2}];function l(e){const i={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.header,{children:(0,t.jsx)(i.h1,{id:"seed",children:"Seed"})}),"\n",(0,t.jsx)(i.admonition,{type:"info",children:(0,t.jsxs)(i.p,{children:["The prerequisite for the deployment of a cluster is a configuration repository.\nWhat a configuration repository is and how it is created is described in the\n",(0,t.jsx)(i.a,{href:"/docs/iaas/guides/configuration-guide/configuration-repository#creating-a-new-configuration-repository",children:"Configuration Guide"}),"."]})}),"\n",(0,t.jsx)(i.p,{children:"The seed node is used once for the initial bootstrap of the manager node. The seed node can\nalso be used to initially create and prepare the configuration repository. The seed node is\nnot the manager node itself. It is sufficient to use the local workstation. It doesn't have\nto be a dedicated system. The seed node is no longer needed in the further process. The seed\nnode must be able to reach the manager node via SSH. It is important for the further process\nthat no packages are installed manually on the manager. Especially not Docker."}),"\n",(0,t.jsx)(i.p,{children:"The use of Linux on the seed node is recommended. Other operating systems should also\nwork without problems. It is assumed in this documentation that Ubuntu 22.04 is used on\nthe seed node."}),"\n",(0,t.jsx)(i.h2,{id:"install-required-packages",children:"Install required packages"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"sudo apt-get install git python3-pip python3-virtualenv sshpass libssh-dev\n"})}),"\n",(0,t.jsx)(i.h2,{id:"get-a-copy-of-the-configuration-repository",children:"Get a copy of the configuration repository"}),"\n",(0,t.jsxs)(i.p,{children:["Each environment managed with OSISM is based on a configuration repository. This was\npreviously created with Cookiecutter and the ",(0,t.jsx)(i.a,{href:"https://github.com/osism/cfg-cookiecutter",children:"osism/cfg-cookiecutter"}),"\nrepository."]}),"\n",(0,t.jsxs)(i.p,{children:["The creation of the configuration repository is covered in chapter\n",(0,t.jsx)(i.a,{href:"/docs/iaas/guides/configuration-guide/configuration-repository#creating-a-new-configuration-repository",children:"Creation of a configuration repository"}),"\nof the ",(0,t.jsx)(i.a,{href:"/docs/iaas/guides/configuration-guide/",children:"Configuration Guide"}),"."]}),"\n",(0,t.jsx)(i.p,{children:"A configuration repository is stored on a Git server (e.g. GitHub, Gitlab, ...). The\nconfiguration repository is individual for each environment and is therefore not provided\nby us."}),"\n",(0,t.jsxs)(i.p,{children:["The configuration repository to be used must be available on the seed node. In the following\nexample, replace ",(0,t.jsx)(i.code,{children:"YOUR_ORG"})," and ",(0,t.jsx)(i.code,{children:"YOUR_NEW_CONFIGURATION_REPOSITORY"})," accordingly."]}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"git clone ssh://git@github.com:YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY.git\n"})}),"\n",(0,t.jsx)(i.p,{children:"Examples:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:["The repository is located in the ",(0,t.jsx)(i.code,{children:"regiocloud"})," organisation on GitHub, has the name\nconfiguration and can be accessed via SSH: ",(0,t.jsx)(i.code,{children:"ssh://git@github.com:regiocloud/configuration.git"})]}),"\n",(0,t.jsxs)(i.li,{children:["The repository is located in the ",(0,t.jsx)(i.code,{children:"regiocloud"})," organisation on Gitlab, has the name configuration\nand can be accessed via SSH: ",(0,t.jsx)(i.code,{children:"ssh://git@gitlab.com:regiocloud/configuration.git"})]}),"\n",(0,t.jsxs)(i.li,{children:["The repository is located in the ",(0,t.jsx)(i.code,{children:"regiocloud"})," organisation on an internal Gitlab, has the name\nconfiguration and can be accessed via SSH: ",(0,t.jsx)(i.code,{children:"ssh://git@git.services.osism.tech:regiocloud/configuration.git"})]}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"If necessary, the configuration SSH key can be used for the initial transfer of the repository."}),"\n",(0,t.jsxs)(i.p,{children:["For this, the following content is added in ",(0,t.jsx)(i.code,{children:"~/.ssh/config"})," and the SSH privte key is stored in\n",(0,t.jsx)(i.code,{children:"~/.ssh/id_rsa.configuration"}),"."]}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"Host github.com\n HostName github.com\n User git\n Port 22\n IdentityFile ~/.ssh/id_rsa.configuration\n"})})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>r,x:()=>a});var o=n(96540);const t={},s=o.createContext(t);function r(e){const i=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),o.createElement(s.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/46a1aa97.feddc5a1.js b/assets/js/46a1aa97.feddc5a1.js new file mode 100644 index 0000000000..7c853351d6 --- /dev/null +++ b/assets/js/46a1aa97.feddc5a1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[94561],{13083:e=>{e.exports=JSON.parse('{"version":{"pluginId":"contributor-docs","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"devDocs":[{"type":"category","label":"Developer documentation","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"tests","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"SCS RFC2119 Keyword Test Guide","href":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","docId":"development/tests/rfc2119-keyword-test-guide","unlisted":false},{"type":"link","label":"SCS Conformance Test Implementation Guide","href":"/contributor-docs/development/tests/test-implementation-guide","docId":"development/tests/test-implementation-guide","unlisted":false}]}],"href":"/contributor-docs/development/"},{"type":"link","label":"Documentation for SCS Contributors","href":"/contributor-docs/","docId":"index","unlisted":false},{"type":"category","label":"operations","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"iam","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Identity Federation in SCS","href":"/contributor-docs/operations/iam/identity-federation-in-scs","docId":"operations/iam/identity-federation-in-scs","unlisted":false},{"type":"link","label":"OpenStack Federation via OpenID-Connect","href":"/contributor-docs/operations/iam/openstack-federation-via-oidc","docId":"operations/iam/openstack-federation-via-oidc","unlisted":false}]},{"type":"category","label":"operations","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Zuul users guide","href":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","docId":"operations/operations/zuul-ci-cd-quickstart-user-guide","unlisted":false}]}]}]},"docs":{"development/index":{"id":"development/index","title":"Developer documentation","description":"Welcome to the developer section of the contributor docs. Here you will find","sidebar":"devDocs"},"development/tests/rfc2119-keyword-test-guide":{"id":"development/tests/rfc2119-keyword-test-guide","title":"SCS RFC2119 Keyword Test Guide","description":"Introduction","sidebar":"devDocs"},"development/tests/test-implementation-guide":{"id":"development/tests/test-implementation-guide","title":"SCS Conformance Test Implementation Guide","description":"SovereignCloudStack (SCS) uses conformance tests to certify","sidebar":"devDocs"},"index":{"id":"index","title":"Documentation for SCS Contributors","description":"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.","sidebar":"devDocs"},"operations/iam/identity-federation-in-scs":{"id":"operations/iam/identity-federation-in-scs","title":"Identity Federation in SCS","description":"SovereignCloudStack wants to make it possible for operators to delegate","sidebar":"devDocs"},"operations/iam/openstack-federation-via-oidc":{"id":"operations/iam/openstack-federation-via-oidc","title":"OpenStack Federation via OpenID-Connect","description":"Keystone supports federating authentication and authorization decisions via several mechanisms","sidebar":"devDocs"},"operations/operations/zuul-ci-cd-quickstart-user-guide":{"id":"operations/operations/zuul-ci-cd-quickstart-user-guide","title":"Zuul users guide","description":"Prerequisites","sidebar":"devDocs"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/473bdf69.b1ee068d.js b/assets/js/473bdf69.b1ee068d.js new file mode 100644 index 0000000000..b0183a8a7e --- /dev/null +++ b/assets/js/473bdf69.b1ee068d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[25930],{30941:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>t,toc:()=>i});const t=JSON.parse('{"id":"operating-scs/components/status-page-deployment/docs/monitoring","title":"Monitoring","description":"All backend components of the status page can be instrumented to supply metrics. These metrics can be collected and visualized by monitoring technologies like Prometheus and Grafana.","source":"@site/docs/04-operating-scs/components/status-page-deployment/docs/monitoring.md","sourceDirName":"04-operating-scs/components/status-page-deployment/docs","slug":"/operating-scs/components/status-page-deployment/docs/monitoring","permalink":"/docs/operating-scs/components/status-page-deployment/docs/monitoring","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-deployment/docs/monitoring.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Usage","permalink":"/docs/operating-scs/components/status-page-deployment/docs/usage"},"next":{"title":"Contribute","permalink":"/docs/operating-scs/components/status-page-deployment/docs/contribute"}}');var d=n(74848),r=n(28453);const o={},a="Monitoring",c={},i=[{value:"Endpoints",id:"endpoints",level:2},{value:"Dashboards",id:"dashboards",level:2},{value:"KinD",id:"kind",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(s.header,{children:(0,d.jsx)(s.h1,{id:"monitoring",children:"Monitoring"})}),"\n",(0,d.jsxs)(s.p,{children:["All backend components of the status page can be instrumented to supply metrics. These metrics can be collected and visualized by monitoring technologies like ",(0,d.jsx)(s.a,{href:"https://prometheus.io/",children:"Prometheus"})," and ",(0,d.jsx)(s.a,{href:"https://grafana.com/",children:"Grafana"}),"."]}),"\n",(0,d.jsx)(s.h2,{id:"endpoints",children:"Endpoints"}),"\n",(0,d.jsx)(s.p,{children:"The services expose their metrics endpoints on different ports."}),"\n",(0,d.jsxs)(s.table,{children:[(0,d.jsx)(s.thead,{children:(0,d.jsxs)(s.tr,{children:[(0,d.jsx)(s.th,{children:"Service"}),(0,d.jsx)(s.th,{children:"Port (Name)"}),(0,d.jsx)(s.th,{children:"Endpoint"})]})}),(0,d.jsxs)(s.tbody,{children:[(0,d.jsxs)(s.tr,{children:[(0,d.jsx)(s.td,{children:(0,d.jsx)(s.code,{children:"api-db"})}),(0,d.jsxs)(s.td,{children:[(0,d.jsx)(s.code,{children:"9187"})," (",(0,d.jsx)(s.code,{children:"metrics"}),")"]}),(0,d.jsx)(s.td,{children:(0,d.jsx)(s.code,{children:"/metrics"})})]}),(0,d.jsxs)(s.tr,{children:[(0,d.jsx)(s.td,{children:(0,d.jsx)(s.code,{children:"api"})}),(0,d.jsxs)(s.td,{children:[(0,d.jsx)(s.code,{children:"9000"})," (",(0,d.jsx)(s.code,{children:"metrics"}),")"]}),(0,d.jsx)(s.td,{children:(0,d.jsx)(s.code,{children:"/metrics"})})]}),(0,d.jsxs)(s.tr,{children:[(0,d.jsx)(s.td,{children:(0,d.jsx)(s.code,{children:"dex"})}),(0,d.jsxs)(s.td,{children:[(0,d.jsx)(s.code,{children:"5558"})," (",(0,d.jsx)(s.code,{children:"telemetry"}),")"]}),(0,d.jsx)(s.td,{children:(0,d.jsx)(s.code,{children:"/metrics"})})]}),(0,d.jsxs)(s.tr,{children:[(0,d.jsx)(s.td,{children:(0,d.jsx)(s.code,{children:"oathkeeper"})}),(0,d.jsxs)(s.td,{children:[(0,d.jsx)(s.code,{children:"9000"})," (",(0,d.jsx)(s.code,{children:"metrics"}),")"]}),(0,d.jsx)(s.td,{children:(0,d.jsx)(s.code,{children:"/metrics"})})]})]})]}),"\n",(0,d.jsx)(s.h2,{id:"dashboards",children:"Dashboards"}),"\n",(0,d.jsx)(s.p,{children:"To visualize the supplied metrics, some dashboards are needed."}),"\n",(0,d.jsxs)(s.p,{children:["For the used database and exporter the ",(0,d.jsx)(s.a,{href:"https://grafana.com/grafana/dashboards/9628-postgresql-database/",children:"PostgreSQL Database"})," dashboard is recommended."]}),"\n",(0,d.jsxs)(s.p,{children:["Go runtime metrics can be visualized by the ",(0,d.jsx)(s.a,{href:"https://grafana.com/grafana/dashboards/10826-go-metrics/",children:"Go Metrics"})," dashboard."]}),"\n",(0,d.jsxs)(s.p,{children:["Hand crafted dashboard for Dex, Oathkeeper and the status-page-api are located at ",(0,d.jsx)(s.code,{children:"kubernetes/feature/monitoring/grafana/dashboards"})," and have according prefixes."]}),"\n",(0,d.jsx)(s.h2,{id:"kind",children:"KinD"}),"\n",(0,d.jsx)(s.p,{children:"The KinD deployment deploys Grafana and Prometheus pods and sets up the data source and dashboards, to work with the rest of the deployment out of the box."}),"\n",(0,d.jsx)(s.p,{children:"The Grafana frontend can be accessed by port forwarding the reverse proxy:"}),"\n",(0,d.jsx)(s.pre,{children:(0,d.jsx)(s.code,{className:"language-bash",children:"kubectl --context kind-status-page -n status-page port-forward pods/status-page-reverse-proxy-78d588d58b-7rdn6 8080:8080\n"})}),"\n",(0,d.jsxs)(s.p,{children:["Afterwards Grafana can be accessed by navigating to ",(0,d.jsx)(s.code,{children:"monitoring.localhost:8080"}),". Use the username ",(0,d.jsx)(s.code,{children:"admin"})," and password ",(0,d.jsx)(s.code,{children:"s3cr3t"}),"."]})]})}function l(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,d.jsx)(s,{...e,children:(0,d.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var t=n(96540);const d={},r=t.createContext(d);function o(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:o(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/477ed06d.f275f379.js b/assets/js/477ed06d.f275f379.js new file mode 100644 index 0000000000..aa0001cbac --- /dev/null +++ b/assets/js/477ed06d.f275f379.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[93502],{6701:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>o});const s=JSON.parse('{"id":"iaas/scs-0101","title":"scs-0101: SCS Entropy","description":"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations","source":"@site/standards/iaas/scs-0101.md","sourceDirName":"iaas","slug":"/iaas/scs-0101","permalink":"/standards/iaas/scs-0101","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0100-w1-flavor-naming-implementation-testing"},"next":{"title":"V1","permalink":"/standards/scs-0101-v1-entropy"}}');var r=n(74848),i=n(28453);const a={},d="scs-0101: SCS Entropy",c={},o=[{value:"Supplement: Implementation and Testing Notes",id:"supplement-implementation-and-testing-notes",level:2}];function l(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0101-scs-entropy",children:"scs-0101: SCS Entropy"})}),"\n",(0,r.jsx)(t.p,{children:"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations\nsuch as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and\nactivating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy\naccessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into\nvirtual instances and ensures the availability and quality of entropy in virtual environments, promoting system\nsecurity and efficiency."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0101-v1-entropy",children:"scs-0101-v1"})}),(0,r.jsx)(t.td,{children:"Standard"}),(0,r.jsx)(t.td,{children:"Stable"}),(0,r.jsx)(t.td,{children:"2024-02-08"}),(0,r.jsx)(t.td,{children:"-"})]})})]}),"\n",(0,r.jsx)(t.h2,{id:"supplement-implementation-and-testing-notes",children:"Supplement: Implementation and Testing Notes"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0101-w1-entropy-implementation-testing",children:"w1"})}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>d});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/48846.2215b4ad.js b/assets/js/48846.2215b4ad.js new file mode 100644 index 0000000000..d55300a615 --- /dev/null +++ b/assets/js/48846.2215b4ad.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[48846],{48846:(t,e,i)=>{i.d(e,{diagram:()=>d});var n=i(86079),s=i(26312),r=(i(74353),i(16750),i(42838),function(){var t=function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i},e=[1,3],i=[1,4],n=[1,5],s=[1,6],r=[1,10,12,14,16,18,19,20,21,22],l=[2,4],a=[1,5,10,12,14,16,18,19,20,21,22],c=[20,21,22],o=[2,7],h=[1,12],u=[1,13],y=[1,14],p=[1,15],d=[1,16],g=[1,17],f={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,PIE:5,document:6,showData:7,line:8,statement:9,txt:10,value:11,title:12,title_value:13,acc_title:14,acc_title_value:15,acc_descr:16,acc_descr_value:17,acc_descr_multiline_value:18,section:19,NEWLINE:20,";":21,EOF:22,$accept:0,$end:1},terminals_:{2:"error",5:"PIE",7:"showData",10:"txt",11:"value",12:"title",13:"title_value",14:"acc_title",15:"acc_title_value",16:"acc_descr",17:"acc_descr_value",18:"acc_descr_multiline_value",19:"section",20:"NEWLINE",21:";",22:"EOF"},productions_:[0,[3,2],[3,2],[3,3],[6,0],[6,2],[8,2],[9,0],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[4,1],[4,1],[4,1]],performAction:function(t,e,i,n,s,r,l){var a=r.length-1;switch(s){case 3:n.setShowData(!0);break;case 6:this.$=r[a-1];break;case 8:n.addSection(r[a-1],n.cleanupValue(r[a]));break;case 9:this.$=r[a].trim(),n.setDiagramTitle(this.$);break;case 10:this.$=r[a].trim(),n.setAccTitle(this.$);break;case 11:case 12:this.$=r[a].trim(),n.setAccDescription(this.$);break;case 13:n.addSection(r[a].substr(8)),this.$=r[a].substr(8)}},table:[{3:1,4:2,5:e,20:i,21:n,22:s},{1:[3]},{3:7,4:2,5:e,20:i,21:n,22:s},t(r,l,{6:8,7:[1,9]}),t(a,[2,14]),t(a,[2,15]),t(a,[2,16]),{1:[2,1]},t(c,o,{8:10,9:11,1:[2,2],10:h,12:u,14:y,16:p,18:d,19:g}),t(r,l,{6:18}),t(r,[2,5]),{4:19,20:i,21:n,22:s},{11:[1,20]},{13:[1,21]},{15:[1,22]},{17:[1,23]},t(c,[2,12]),t(c,[2,13]),t(c,o,{8:10,9:11,1:[2,3],10:h,12:u,14:y,16:p,18:d,19:g}),t(r,[2,6]),t(c,[2,8]),t(c,[2,9]),t(c,[2,10]),t(c,[2,11])],defaultActions:{7:[2,1]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=this,i=[0],n=[],s=[null],r=[],l=this.table,a="",c=0,o=0,h=r.slice.call(arguments,1),u=Object.create(this.lexer),y={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(y.yy[p]=this.yy[p]);u.setInput(t,y.yy),y.yy.lexer=u,y.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var d=u.yylloc;r.push(d);var g=u.options&&u.options.ranges;"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,_,m,k,b,x,v,S,w,$={};;){if(_=i[i.length-1],this.defaultActions[_]?m=this.defaultActions[_]:(null==f&&(w=void 0,"number"!=typeof(w=n.pop()||u.lex()||1)&&(w instanceof Array&&(w=(n=w).pop()),w=e.symbols_[w]||w),f=w),m=l[_]&&l[_][f]),void 0===m||!m.length||!m[0]){var E="";for(b in S=[],l[_])this.terminals_[b]&&b>2&&S.push("'"+this.terminals_[b]+"'");E=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+S.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(E,{text:u.match,token:this.terminals_[f]||f,line:u.yylineno,loc:d,expected:S})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+f);switch(m[0]){case 1:i.push(f),s.push(u.yytext),r.push(u.yylloc),i.push(m[1]),f=null,o=u.yyleng,a=u.yytext,c=u.yylineno,d=u.yylloc;break;case 2:if(x=this.productions_[m[1]][1],$.$=s[s.length-x],$._$={first_line:r[r.length-(x||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(x||1)].first_column,last_column:r[r.length-1].last_column},g&&($._$.range=[r[r.length-(x||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply($,[a,o,c,y.yy,m[1],s,r].concat(h))))return k;x&&(i=i.slice(0,-1*x*2),s=s.slice(0,-1*x),r=r.slice(0,-1*x)),i.push(this.productions_[m[1]][0]),s.push($.$),r.push($._$),v=l[i[i.length-2]][i[i.length-1]],i.push(v);break;case 3:return!0}}return!0}},_={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,i=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var i,n,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((i=this._input.match(this.rules[s[r]]))&&(!e||i[0].length>e[0].length)){if(e=i,n=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,i,n){switch(i){case 0:case 1:case 3:case 4:break;case 2:return 20;case 5:return this.begin("title"),12;case 6:return this.popState(),"title_value";case 7:return this.begin("acc_title"),14;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),16;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:case 15:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:this.begin("string");break;case 16:return"txt";case 17:return 5;case 18:return 7;case 19:return"value";case 20:return 22}},rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:[\s]+)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:pie\b)/i,/^(?:showData\b)/i,/^(?::[\s]*[\d]+(?:\.[\d]+)?)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[6],inclusive:!1},string:{rules:[15,16],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,7,9,11,14,17,18,19,20],inclusive:!0}}};function m(){this.yy={}}return f.lexer=_,m.prototype=f,f.Parser=m,new m}());r.parser=r;const l=r,a=n.B.pie,c={},o=!1;let h=c,u=o;const y=structuredClone(a),p={getConfig:()=>structuredClone(y),clear:()=>{h=structuredClone(c),u=o,(0,n.v)()},setDiagramTitle:n.q,getDiagramTitle:n.t,setAccTitle:n.s,getAccTitle:n.g,setAccDescription:n.b,getAccDescription:n.a,addSection:(t,e)=>{t=(0,n.d)(t,(0,n.c)()),void 0===h[t]&&(h[t]=e,n.l.debug(`added new section: ${t}, with value: ${e}`))},getSections:()=>h,cleanupValue:t=>(":"===t.substring(0,1)&&(t=t.substring(1).trim()),Number(t.trim())),setShowData:t=>{u=t},getShowData:()=>u},d={parser:l,db:p,renderer:{draw:(t,e,i,r)=>{n.l.debug("rendering pie chart\n"+t);const l=r.db,a=(0,n.c)(),c=(0,n.C)(l.getConfig(),a.pie),o=18,h=450,u=h,y=(0,n.A)(e),p=y.append("g"),d=l.getSections();p.attr("transform","translate(225,225)");const{themeVariables:g}=a;let[f]=(0,n.D)(g.pieOuterStrokeWidth);f??(f=2);const _=c.textPosition,m=Math.min(u,h)/2-40,k=(0,s.JLW)().innerRadius(0).outerRadius(m),b=(0,s.JLW)().innerRadius(m*_).outerRadius(m*_);p.append("circle").attr("cx",0).attr("cy",0).attr("r",m+f/2).attr("class","pieOuterCircle");const x=(t=>{const e=Object.entries(t).map((t=>({label:t[0],value:t[1]}))).sort(((t,e)=>e.value-t.value));return(0,s.rLf)().value((t=>t.value))(e)})(d),v=[g.pie1,g.pie2,g.pie3,g.pie4,g.pie5,g.pie6,g.pie7,g.pie8,g.pie9,g.pie10,g.pie11,g.pie12],S=(0,s.UMr)(v);p.selectAll("mySlices").data(x).enter().append("path").attr("d",k).attr("fill",(t=>S(t.data.label))).attr("class","pieCircle");let w=0;Object.keys(d).forEach((t=>{w+=d[t]})),p.selectAll("mySlices").data(x).enter().append("text").text((t=>(t.data.value/w*100).toFixed(0)+"%")).attr("transform",(t=>"translate("+b.centroid(t)+")")).style("text-anchor","middle").attr("class","slice"),p.append("text").text(l.getDiagramTitle()).attr("x",0).attr("y",-200).attr("class","pieTitleText");const $=p.selectAll(".legend").data(S.domain()).enter().append("g").attr("class","legend").attr("transform",((t,e)=>"translate(216,"+(22*e-22*S.domain().length/2)+")"));$.append("rect").attr("width",o).attr("height",o).style("fill",S).style("stroke",S),$.data(x).append("text").attr("x",22).attr("y",14).text((t=>{const{label:e,value:i}=t.data;return l.getShowData()?`${e} [${i}]`:e}));const E=512+Math.max(...$.selectAll("text").nodes().map((t=>(null==t?void 0:t.getBoundingClientRect().width)??0)));y.attr("viewBox",`0 0 ${E} 450`),(0,n.i)(y,h,E,c.useMaxWidth)}},styles:t=>`\n .pieCircle{\n stroke: ${t.pieStrokeColor};\n stroke-width : ${t.pieStrokeWidth};\n opacity : ${t.pieOpacity};\n }\n .pieOuterCircle{\n stroke: ${t.pieOuterStrokeColor};\n stroke-width: ${t.pieOuterStrokeWidth};\n fill: none;\n }\n .pieTitleText {\n text-anchor: middle;\n font-size: ${t.pieTitleTextSize};\n fill: ${t.pieTitleTextColor};\n font-family: ${t.fontFamily};\n }\n .slice {\n font-family: ${t.fontFamily};\n fill: ${t.pieSectionTextColor};\n font-size:${t.pieSectionTextSize};\n // fill: white;\n }\n .legend text {\n fill: ${t.pieLegendTextColor};\n font-family: ${t.fontFamily};\n font-size: ${t.pieLegendTextSize};\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/4913574b.736db4b7.js b/assets/js/4913574b.736db4b7.js new file mode 100644 index 0000000000..0fd591c28b --- /dev/null +++ b/assets/js/4913574b.736db4b7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[99084],{27795:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"operating-scs/components/status-page-deployment/docs/overview","title":"Overview","description":"The status page needs some components additional to the API server to be usable by operators and customers. As the API server does not implement any kind of authorization or authentication some components need to be deployed to protect the write operations of the API from unauthorized access.","source":"@site/docs/04-operating-scs/components/status-page-deployment/docs/overview.md","sourceDirName":"04-operating-scs/components/status-page-deployment/docs","slug":"/operating-scs/components/status-page-deployment/docs/overview","permalink":"/docs/operating-scs/components/status-page-deployment/docs/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-deployment/docs/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Deployment","permalink":"/docs/category/deployment"},"next":{"title":"Requirements","permalink":"/docs/operating-scs/components/status-page-deployment/docs/requirements"}}');var s=n(74848),a=n(28453);const r={},i="Overview",d={},c=[{value:"Components",id:"components",level:2},{value:"Component overview",id:"component-overview",level:3},{value:"Deployment repository",id:"deployment-repository",level:2}];function p(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",ol:"ol",p:"p",section:"section",sup:"sup",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,s.jsxs)(t.p,{children:["The status page needs some components additional to the ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-api",children:"API server"})," to be usable by operators and customers. As the API server ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0402-v1-status-page-openapi-spec-decision.md#authentication-and-authorization",children:"does not implement any kind of authorization or authentication"})," some components need to be deployed to protect the write operations of the API from unauthorized access."]}),"\n",(0,s.jsx)(t.h2,{id:"components",children:"Components"}),"\n",(0,s.jsx)(t.p,{children:"These components are picked as examples and can be exchanged with any technology that is fitting the use case."}),"\n",(0,s.jsxs)(t.p,{children:["The used components are ",(0,s.jsx)(t.a,{href:"https://www.ory.sh/docs/oathkeeper",children:"Oathkeeper"})," and ",(0,s.jsx)(t.a,{href:"https://dexidp.io/",children:"Dex"})," to implement AuthN",(0,s.jsx)(t.sup,{children:(0,s.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})," and AuthZ",(0,s.jsx)(t.sup,{children:(0,s.jsx)(t.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),". Oathkeeper is a proxy that handles incoming requests and authorization, while Dex is used as an identity broker, used for authentication, to be used in conjunction with Oathkeeper to secure the API server."]}),"\n",(0,s.jsxs)(t.p,{children:["Furthermore the API server needs a running database, for this ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0401-v1-status-page-reference-implementation-decision.md#database",children:"PostgreSQL is used"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["Last but not least the the status page is completed by a web front. For this the reference implementation from the ",(0,s.jsxs)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-web",children:[(0,s.jsx)(t.code,{children:"status-page-web"})," repository"]}),"."]}),"\n",(0,s.jsx)(t.p,{children:"Some deployments use reverse proxies, ingress controllers or can even use the gateway API. These are deployment specific and can be used as the use case requires."}),"\n",(0,s.jsx)(t.h3,{id:"component-overview",children:"Component overview"}),"\n",(0,s.jsx)(t.mermaid,{value:' C4Container\n title Component overview status page\n\n Person(user, User, "A user who wants to know about the status.")\n Person(admin, Admin, "An administrator who can update the status.")\n\n Container_Boundary(status-page, "Status Page") {\n Container(web, "Web Frontend", "JavaScript, Angular", "Provides all the status page functionality to persons via their web browser")\n Container(dex, "Dex IdP", "", "Intermediate IdP to retrieve user data.")\n Container(api, "API Server", "Go", "Delivers data to the Web Frontend")\n ContainerDb(api-db, "API Database", "SQL Database", "Stores components, incidents, severities, phases, etc.")\n Container(oathkeeper, "Oathkeeper", "AuthN, AuthZ", "Authentication proxy for write operations on the API Server.")\n\n Rel(api, api-db, "Request data")\n Rel(web, oathkeeper, "Request data", "Unauthenticated read, authenticated write")\n Rel(oathkeeper, api, "Proxy and protect",)\n Rel(web, dex, "Authentication")\n Rel(oathkeeper, dex, "Authenticate user requests")\n }\n\n Rel(user, web, "Reads status")\n Rel(admin, web, "Writes status")\n Rel(admin, dex, "Authenticate")'}),"\n",(0,s.jsx)(t.h2,{id:"deployment-repository",children:"Deployment repository"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-deployment",children:"deployment repository"})," contains a ",(0,s.jsxs)(t.a,{href:"/docs/operating-scs/components/status-page-deployment/docs/kind",children:["local development environment using ",(0,s.jsx)(t.code,{children:"KinD"})]}),", templates for other deployments, in ",(0,s.jsx)(t.a,{href:"/docs/operating-scs/components/status-page-deployment/docs/k3s",children:"example using k3s"})," and the skeleton of the deployment for the ",(0,s.jsx)(t.a,{href:"/docs/operating-scs/components/status-page-deployment/docs/scs-public",children:"public SCS cluster"}),"."]}),"\n","\n",(0,s.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,s.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,s.jsxs)(t.p,{children:["Authentication ",(0,s.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{id:"user-content-fn-2",children:["\n",(0,s.jsxs)(t.p,{children:["Authorization ",(0,s.jsx)(t.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>i});var o=n(96540);const s={},a=o.createContext(s);function r(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/49993131.a37e22c3.js b/assets/js/49993131.a37e22c3.js new file mode 100644 index 0000000000..57e1c3415a --- /dev/null +++ b/assets/js/49993131.a37e22c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[28460],{62197:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>c,frontMatter:()=>o,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"iaas/guides/other-guides/developer-guide/releases","title":"Releases","description":"How we handle releases","source":"@site/docs/02-iaas/guides/other-guides/developer-guide/releases.md","sourceDirName":"02-iaas/guides/other-guides/developer-guide","slug":"/iaas/guides/other-guides/developer-guide/releases","permalink":"/docs/iaas/guides/other-guides/developer-guide/releases","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/developer-guide/releases.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Releases","sidebar_position":10},"sidebar":"docs","previous":{"title":"Developer Guide","permalink":"/docs/iaas/guides/other-guides/developer-guide/"},"next":{"title":"Scripts","permalink":"/docs/iaas/guides/other-guides/developer-guide/scripts"}}');var i=s(74848),r=s(28453);const o={sidebar_label:"Releases",sidebar_position:10},a="Releases",l={},d=[{value:"How we handle releases",id:"how-we-handle-releases",level:2},{value:"How to make a release",id:"how-to-make-a-release",level:2},{value:"Stable release",id:"stable-release",level:3},{value:"How we write release notes",id:"how-we-write-release-notes",level:2},{value:"Installation",id:"installation",level:3},{value:"Usage",id:"usage",level:3},{value:"Example",id:"example",level:3},{value:"Repositories without release notes",id:"repositories-without-release-notes",level:3}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"releases",children:"Releases"})}),"\n",(0,i.jsx)(n.h2,{id:"how-we-handle-releases",children:"How we handle releases"}),"\n",(0,i.jsx)(n.p,{children:"Currently we do a major release every 6 months. Minor releases we do when\nneeded and about every 2 weeks."}),"\n",(0,i.jsx)(n.p,{children:"In a minor release, only updates, bug fixes, etc. take place. There are also\nno major upgrades of included components such as OpenStack, Keycloak or Ceph\nin a minor release."}),"\n",(0,i.jsx)(n.p,{children:"It is possible to jump from any minor version within a major version to higher\nminor versions without any intervention."}),"\n",(0,i.jsx)(n.p,{children:"Deprecations, removals, etc. take place in a major release. New mandatory\nfeatures are also added in a major release. Upgrades of the included components\ncan also take place during a major release (e.g. OpenStack Xena -> OpenStack Yoga)."}),"\n",(0,i.jsx)(n.p,{children:"It is possible to jump from the previous major version to the next major version.\nIt may be that manual intervention is necessary. For example, configuration\nparameters may need to be added or services that no longer exist may need to be\nremoved."}),"\n",(0,i.jsx)(n.h2,{id:"how-to-make-a-release",children:"How to make a release"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On all repositories that are used, check that the versions to be used have an\nappropriate version tag (e.g. ",(0,i.jsx)(n.code,{children:"v0.20230308.0"}),")."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism/ansible-collection-commons\nosism/ansible-collection-services\nosism/ansible-collection-validations\nosism/ansible-defaults\nosism/ansible-playbooks\nosism/ansible-playbooks-manager\nosism/cf-generics\nosism/kolla-operations\nosism/python-osism\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Copy the ",(0,i.jsx)(n.code,{children:"latest"})," directory. The release to be created is used as the new name."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"latest -> 6.0.0b\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Remove all ",(0,i.jsx)(n.code,{children:"# renovate"})," lines from the ",(0,i.jsx)(n.code,{children:"base.yml"})," file."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Remove all Ceph and OpenStack releases that should not be part of the pre-release.\nThere is only one OpenStack version and one Ceph version per (pre-)release."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Ensure that the symlinks ",(0,i.jsx)(n.code,{children:"openstack.yml"})," and ",(0,i.jsx)(n.code,{children:"ceph.yml"})," point to the releases\nto be used in this pre-release."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"base.yml\nceph-pacific.yml\nceph.yml -> ceph-pacific.yml\nopenstack-zed.yml\nopenstack.yml -> openstack-zed.yml\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Run ",(0,i.jsx)(n.code,{children:"src/prepare-release.py"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"RELEASE=6.0.0b python3 src/prepare-release.py\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Do the steps from the ",(0,i.jsx)(n.code,{children:"Stable release"})," starting from the 4th step."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"stable-release",children:"Stable release"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Copy the directory of the last pre-release or the previous stable release.\nThe release to be created is used as the new name."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"5.0.0a -> 5.0.0b\n5.0.0b -> 5.0.0\n5.0.0 -> 5.1.0\n5.1.0 -> 5.2.0\n5.2.0 -> 5.3.0\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Change all necessary versions in the YAML files within the new directory.\nIn any case, the version of the pre-release or the version of the stable\nrelease must be replaced by the release to be created."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"The release to be created is submitted as a pull request as usual and then\nmerged."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Add a tag with the name of the new release to the listed repositories."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism/container-image-ceph-ansible\nosism/container-image-inventory-reconciler\nosism/container-image-osism-ansible\nosism/container-images-kolla\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["After completing the creation of the images in repository ",(0,i.jsx)(n.code,{children:"container-images-kolla"}),",\nthe file ",(0,i.jsx)(n.code,{children:"images.yml"})," must be added to repository ",(0,i.jsx)(n.code,{children:"osism/sbom"})," as\n",(0,i.jsx)(n.code,{children:"5.0.0/openstack.yml"})," (instead of ",(0,i.jsx)(n.code,{children:"5.0.0"}),", the corresponding release is used).\nThe file is available as a build artefact of the ",(0,i.jsx)(n.code,{children:"Release container images"})," action\non the created tag."]}),"\n",(0,i.jsxs)(n.p,{children:["Before the file is added, it is enhanced with the checksums of the images. The script\nis available in the ",(0,i.jsx)(n.code,{children:"osism/sbom"})," repository."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"VERSION=5.0.0 python3 scripts/add-image-checksum.py\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["If ",(0,i.jsx)(n.code,{children:"5.0.0/openstack.yml"})," is present in ",(0,i.jsx)(n.code,{children:"osism/sbom"}),", repository\n",(0,i.jsx)(n.code,{children:"osism/container-image-kolla-ansible"})," can be tagged like the other\nrepositories before."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add the created SPDX files from the listed repositories to the ",(0,i.jsx)(n.code,{children:"osism/sbom"})," repository.\nThe file are available as build artefacts of the ",(0,i.jsx)(n.code,{children:"Build container image"})," action\non the created tags."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism/container-image-ceph-ansible\nosism/container-image-kolla-ansible\nosism/container-image-osism-ansible\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add and run temporary CI jobs in ",(0,i.jsx)(n.code,{children:"osism/testbed"})," that uses the pre-release."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'- job:\n name: testbed-deploy-stable-next\n parent: testbed-deploy\n vars:\n manager_version: "5.0.0a"\n refstack: true\n nodeset: testbed-orchestrator\n\n- job:\n name: testbed-upgrade-stable-next\n parent: testbed-deploy\n vars:\n manager_version: "4.2.0"\n manager_version_next: "5.0.0a"\n nodeset: testbed-orchestrator\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Test. Test. Test."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Prepare a PR to change the stable version to the new stable version in the following Zuul jobs\nin the ",(0,i.jsx)(n.code,{children:"osism/testbed"})," repository. All tests there must pass successfully before the tag is\nset on this repository in the next step. The temporary CI jobs (step 8) are removed again with\nthis PR."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"testbed-deploy-stable\ntestbed-update-stable\ntestbed-update-stable\ntestbed-upgrade-stable\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add a new release notes file to ",(0,i.jsx)(n.code,{children:"doc/sorce/notes"}),". Generate the versions table with the\nhelp of the ",(0,i.jsx)(n.code,{children:"release-table.py"})," script in the ",(0,i.jsx)(n.code,{children:"osism/sbom"})," repository."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["After all known issues are documented, a corresponding tag, e.g. ",(0,i.jsx)(n.code,{children:"5.0.0"}),", is set on the\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/release/releases",children:"osism/release"})," repository."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Create a ",(0,i.jsx)(n.a,{href:"https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository",children:"GitHub release"})," with the new tag on the\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/release/releases",children:"osism/release"})," repository. The release is\nnow public available."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["As the last of the release process, the previously prepared PR is merged on the\n",(0,i.jsx)(n.code,{children:"osism/testbed"})," repository to change the stable version."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"how-we-write-release-notes",children:"How we write release notes"}),"\n",(0,i.jsxs)(n.p,{children:["We use ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/reno/latest/",children:"Reno"})," to manage the release notes."]}),"\n",(0,i.jsx)(n.h3,{id:"installation",children:"Installation"}),"\n",(0,i.jsxs)(n.p,{children:["Reno is provided as a ",(0,i.jsx)(n.a,{href:"https://pypi.org/project/reno/",children:"Python package"})," and can be installed with pip."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"pip3 install reno\n"})}),"\n",(0,i.jsx)(n.h3,{id:"usage",children:"Usage"}),"\n",(0,i.jsxs)(n.p,{children:["For each change in a repository, a release note is created with Reno.\nSomething meaningful is used as the name for the note. For example, if the\nrequirements file for Ansible is removed, ",(0,i.jsx)(n.code,{children:"remove-ansible-requirements"})," is a good name."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ reno new remove-ansible-requirements\nno configuration file in: ./releasenotes/config.yaml, ./reno.yaml\nCreated new notes file in releasenotes/notes/remove-ansible-requirements-6c6eba43f616bc6b.yaml\n"})}),"\n",(0,i.jsx)(n.p,{children:"The created file contains prepared entries for several categories. It is described briefly\nin each instance which contents belong in which category. What is not needed is deleted."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"prelude: >\n Replace this text with content to appear at the top of the section for this\n release. All of the prelude content is merged together and then rendered\n separately from the items listed in other parts of the file, so the text\n needs to be worded so that both the prelude and the other items make sense\n when read independently. This may mean repeating some details. Not every\n release note requires a prelude. Usually only notes describing major\n features or adding release theme details should have a prelude.\nfeatures:\n - |\n List new features here, or remove this section. All of the list items in\n this section are combined when the release notes are rendered, so the text\n needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\nissues:\n - |\n List known issues here, or remove this section. All of the list items in\n this section are combined when the release notes are rendered, so the text\n needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\nupgrade:\n - |\n List upgrade notes here, or remove this section. All of the list items in\n this section are combined when the release notes are rendered, so the text\n needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\ndeprecations:\n - |\n List deprecations notes here, or remove this section. All of the list\n items in this section are combined when the release notes are rendered, so\n the text needs to be worded so that it does not depend on any information\n only available in another section, such as the prelude. This may mean\n repeating some details.\ncritical:\n - |\n Add critical notes here, or remove this section. All of the list items in\n this section are combined when the release notes are rendered, so the text\n needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\nsecurity:\n - |\n Add security notes here, or remove this section. All of the list items in\n this section are combined when the release notes are rendered, so the text\n needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\nfixes:\n - |\n Add normal bug fixes here, or remove this section. All of the list items\n in this section are combined when the release notes are rendered, so the\n text needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\nother:\n - |\n Add other notes here, or remove this section. All of the list items in\n this section are combined when the release notes are rendered, so the text\n needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\n"})}),"\n",(0,i.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,i.jsxs)(n.p,{children:["Here is an example of a ",(0,i.jsx)(n.a,{href:"https://github.com/osism/cfg-generics/commit/e2f04a9f4a51eb058446d7a8ab6835df53989099",children:"commit from the osism/cfg-generics repository"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"---\nfeatures:\n - |\n The `requirements.yml` has been removed. The version will be set in the `run.sh`\n script for the seed process in the future exactly as later in the update process\n via the parameters `ANSIBLE_COLLECTION_SERVICES_VERSION` and\n `ANSIBLE_PLAYBOOKS_MANAGER_VERSION`.\nupgrade:\n - |\n In existing configuration repositories, the `environments/manager/requirements.yml`\n file can be removed after the generics have been synced.\n"})}),"\n",(0,i.jsx)(n.h3,{id:"repositories-without-release-notes",children:"Repositories without release notes"}),"\n",(0,i.jsx)(n.p,{children:"We do not create release notes in the following repositories:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"osism/github-manager"}),"\n",(0,i.jsx)(n.li,{children:"osism/osism.github.io"}),"\n",(0,i.jsx)(n.li,{children:"osism/release"}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const i={},r=t.createContext(i);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/49bc3785.4e9d7a4e.js b/assets/js/49bc3785.4e9d7a4e.js new file mode 100644 index 0000000000..f12892c6db --- /dev/null +++ b/assets/js/49bc3785.4e9d7a4e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8592],{53998:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>r,contentTitle:()=>c,default:()=>x,frontMatter:()=>d,metadata:()=>l,toc:()=>h});const l=JSON.parse('{"id":"hackathons/checklist","title":"Hackathon planning checklist","description":"This checklist is designed to simplify the planning of hackathons and meetups. All items are suggestions and optionally adaptable","source":"@site/community/hackathons/checklist.md","sourceDirName":"hackathons","slug":"/hackathons/checklist","permalink":"/community/hackathons/checklist","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{}}');var t=i(74848),n=i(28453);const d={},c="Hackathon planning checklist",r={},h=[{value:"Checklist 6 months before Hackathon",id:"checklist-6-months-before-hackathon",level:2},{value:"Checklist advertising",id:"checklist-advertising",level:2},{value:"Checklist 5 months before Hackathon",id:"checklist-5-months-before-hackathon",level:2},{value:"Checklist hotel",id:"checklist-hotel",level:2},{value:"Iportant things",id:"iportant-things",level:3},{value:"Nice-to-have things",id:"nice-to-have-things",level:3},{value:"Checklist 4 months before Hackathon",id:"checklist-4-months-before-hackathon",level:2},{value:"Checklist for evening before location",id:"checklist-for-evening-before-location",level:2},{value:"Checklist rooms 1",id:"checklist-rooms-1",level:2},{value:"Checklist merch (examples)",id:"checklist-merch-examples",level:2},{value:"Checklist 3 months before Hackathon",id:"checklist-3-months-before-hackathon",level:2},{value:"Checklist evening event",id:"checklist-evening-event",level:2},{value:"Checklist 2 months before Hackathon",id:"checklist-2-months-before-hackathon",level:2},{value:"Snacks checklist",id:"snacks-checklist",level:2},{value:"Breakfast examples",id:"breakfast-examples",level:3},{value:"Snack exemples",id:"snack-exemples",level:3},{value:"Vegan snack examples",id:"vegan-snack-examples",level:3},{value:"Checklist rooms 2",id:"checklist-rooms-2",level:2},{value:"Checklist 1 month before Hackathon",id:"checklist-1-month-before-hackathon",level:2},{value:"Checklist 1 week before Hackathon",id:"checklist-1-week-before-hackathon",level:2},{value:"Checklist one day before Hackathon",id:"checklist-one-day-before-hackathon",level:2},{value:"Checklist Hackathon Day X",id:"checklist-hackathon-day-x",level:2},{value:"Checklist after Hackathon",id:"checklist-after-hackathon",level:2}];function a(e){const s={h1:"h1",h2:"h2",h3:"h3",header:"header",input:"input",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,n.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"hackathon-planning-checklist",children:"Hackathon planning checklist"})}),"\n",(0,t.jsx)(s.p,{children:"This checklist is designed to simplify the planning of hackathons and meetups. All items are suggestions and optionally adaptable\nto the situation."}),"\n",(0,t.jsx)(s.h2,{id:"checklist-6-months-before-hackathon",children:"Checklist 6 months before Hackathon"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{}),(0,t.jsx)(s.th,{children:"Date"}),(0,t.jsx)(s.th,{children:"Task"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Clarify sponsorship"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Clarify who is responsible for planning. Contact persons of the companies involved. These should then also be present at the hackathon."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Set a specific date."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Clarify responsibilities."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"First advertising in form of advertising in meetings, LinkedIn post, mailing list or similar."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Clarify which advertising measures are required (see checklist advertising)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Determine venue."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Set the theme for the hackathon and apply it to the design."})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-advertising",children:"Checklist advertising"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{}),(0,t.jsx)(s.th,{children:"Topic"}),(0,t.jsx)(s.th,{children:"Task"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{children:"Social Media"}),(0,t.jsx)(s.td,{children:"Create content plan."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Which accounts/people/companies have to be mentioned as well."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Which persons must agree to a publication."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Should hashtags be used, if yes which ones."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{children:"Newsletter"}),(0,t.jsx)(s.td,{children:"Create content plan with possible content and frequency."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{children:"Website"}),(0,t.jsx)(s.td,{children:"Content plan: Blogposts."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Info landing page."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Registration page."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Special newsletter or just regular."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{children:"Other placements"}),(0,t.jsx)(s.td,{children:"Spread the word in meetings or at other events."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{children:"Media"}),(0,t.jsx)(s.td,{children:"Should be changeable, specify target audience, language, sources."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{children:"Media suggestions"}),(0,t.jsx)(s.td,{children:"Video, images, PDF, texts, merch, graphics. Everything should be planned in advance precisely date, type, releases, scope, size, etc."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{children:"Graphics"}),(0,t.jsx)(s.td,{children:"Set design motto."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{children:"Key metrics"}),(0,t.jsx)(s.td,{children:"Should the success be tracked by key metrics, if so which ones."})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-5-months-before-hackathon",children:"Checklist 5 months before Hackathon"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{}),(0,t.jsx)(s.th,{children:"Date"}),(0,t.jsx)(s.th,{children:"Task"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Clarify if extra merch is desired and start looking for vendors. Order samples."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Discuss concrete advertising measures."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Check hotels (see checklist hotel)."})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-hotel",children:"Checklist hotel"}),"\n",(0,t.jsx)(s.h3,{id:"iportant-things",children:"Iportant things"}),"\n",(0,t.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Availabilities in the period."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Way from the hotel to the hackathon."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Parking at the hotel."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Way from train station to hotel."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Checkin / Checkout times."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Check barrier-free accessibility."]}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"nice-to-have-things",children:"Nice-to-have things"}),"\n",(0,t.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Bar in the hotel, for relaxed sitting together in the evening."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Clarify whether employees from on site are also allowed in the bar."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Clarify whether reservations must be made in the bar, if so, reserve for the evening before."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Possibility of contingent reservation."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-4-months-before-hackathon",children:"Checklist 4 months before Hackathon"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{}),(0,t.jsx)(s.th,{children:"Date"}),(0,t.jsx)(s.th,{children:"Task"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Determine hotel final and make recommendation. Possibly reserve contingent if the hotel offers it."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Find the location for the evening before (see checklist for evening before location)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Start organizing venue. (See checklist rooms 1)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Roughly plan evening event (consider volume level and space available)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Promotional drumbeat. Social media, website, meetings, newsletter."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Order special merch."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Organize merch in general (see merch checklist)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Start collecting statements that need to be sent around. (Privacy statements, photo statements, data center statements, security statements)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Rough sequence of events to be able to plan more precisely at a later date."})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-for-evening-before-location",children:"Checklist for evening before location"}),"\n",(0,t.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Volume level."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Consider food possibilities."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Enough space."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Availability."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","If intermediate change from A to B, then plan and include firmly in the plan."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","If it is necessary to choose two locations because of food, drink, coziness, distance to the hotel: plan both, ask for and book them."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Ask for flexibility in the reservation. If more people come as registered."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Plan times."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Price / performance ratio should fit."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Way from the hotel to the evening before location."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-rooms-1",children:"Checklist rooms 1"}),"\n",(0,t.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Space available (Enough space available for: Work area, meet-up area, no-photo area, break room, restrooms?)."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Provisional room plan."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","How long are the rooms available?"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Are there any legal/corporate issues to consider?"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Do declarations need to be signed to enter the premises?"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","List what hackathon relevant equipment is on site and if anything needs to be organized. For example, screens, whiteboards, power sockets if necessary,\ntables, chairs, wi-fi, etc."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-merch-examples",children:"Checklist merch (examples)"}),"\n",(0,t.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Ballpens"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Lanyards"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Notepads"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Stickers"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","ID card / name badge covers"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Name badges"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Snacks"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-3-months-before-hackathon",children:"Checklist 3 months before Hackathon"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{}),(0,t.jsx)(s.th,{children:"Date"}),(0,t.jsx)(s.th,{children:"Task"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Required declarations (photo/video usage rights, data center, premises, etc.) are available as a form. Have a look if you can have"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"them confirmed with the registration. Otherwise as a circular email to all who register with the registration confirmation. Well"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"visible. For the photo/video declaration: Give the option of refusing and explain the variant with the no-photo dot."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Promote again: Website, social media, newsletter, meetings, circular email, etc...."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Make reservations for pre-evening event."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Plan evening event and reserve location / tables (see checklist evening event)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Create a provisional schedule."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Eventually invite people separately. (Special guests)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Schedule start time and arrival time. Allow enough time for everyone to arrive."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Set presentation time and end time."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Define arrival time evening event. Leave enough time to change, but also do not define too long."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Schedule a fixed cleanup time."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Plan break time."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Activate login page."})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-evening-event",children:"Checklist evening event"}),"\n",(0,t.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Volume level (It should be possible to have relaxed conversations)"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Available space"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Price / performance ratio should be suitable"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Check availabilities"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Snacks should be possible"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Request flexibility with reservation (number of participants)"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Actions would be a nice-to-have, everyone has been sitting and working all day, so it's good to have a change."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Way from the hotel to the evening location."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-2-months-before-hackathon",children:"Checklist 2 months before Hackathon"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{}),(0,t.jsx)(s.th,{children:"Date"}),(0,t.jsx)(s.th,{children:"Task"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Start collecting goals and topics."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Work out goals and topics yourself."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Check results from the checklist rooms 1 again."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Go through checklist rooms 2."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Advertising (social media, mailing list, website, blog post, newsletter, room plan video, etc)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Go through checklists again in general, was anything forgotten?"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Plan food for the break."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Plan snacks / breakfast (See snacks checklist)."})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"snacks-checklist",children:"Snacks checklist"}),"\n",(0,t.jsx)(s.h3,{id:"breakfast-examples",children:"Breakfast examples"}),"\n",(0,t.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Sandwiches (rolls)"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Pretzel sandwiches"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Sandwiches (toast)"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Cocktail tomatoes"]}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"snack-exemples",children:"Snack exemples"}),"\n",(0,t.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ",'"Kinder Schokobons"']}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ",'"Kinder Schokoriegel"']}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ",'"Kinder Duplo"']}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Hanuta"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Gummy bears"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Apples"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Bananas"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Nuts"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Grapes"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Dried fruits"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Salted sticks"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Salted pretzels"]}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"vegan-snack-examples",children:"Vegan snack examples"}),"\n",(0,t.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ",'"Katjes Fruchtgummi"']}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ",'"Katjes Lakritz"']}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-rooms-2",children:"Checklist rooms 2"}),"\n",(0,t.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Create a room plan for publication. In it, work areas, break areas, no-photo area, meet-up places should be clearly\nvisible. Gladly also again as a video."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","If necessary route map."]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Is wifi available without any problems?"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Where will drinks be located?"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Where to set up snacks?"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Where the food for the break?"]}),"\n",(0,t.jsxs)(s.li,{className:"task-list-item",children:[(0,t.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Are there enough plates, cups, glasses, cutlery, napkins, and bowls for snacks?"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-1-month-before-hackathon",children:"Checklist 1 month before Hackathon"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{}),(0,t.jsx)(s.th,{children:"Date"}),(0,t.jsx)(s.th,{children:"Task"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Fix and publish the agenda."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Check the declarations once again, has every declaration been send, have any answered yet?"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Check reservations, expand if necessary."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Check whether all possible special features have been observed (location etc)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Pre-order food for in-between meals and for the lunch break."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Plan drinks, type and quantity (don't forget coffee, tea, milk, sugar)."})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-1-week-before-hackathon",children:"Checklist 1 week before Hackathon"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{}),(0,t.jsx)(s.th,{children:"Date"}),(0,t.jsx)(s.th,{children:"Task"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Print statements and forms."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Advertise again."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Make a list for the snacks (See for inspiration checklist snacks)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Pre-order the food, if necessary, check whether the quantity still fits with the registrations."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Depending on expand. Firmly plan transport / pickup / delivery."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Create a room plan with the topics, where, when, what takes place."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Organize drinks."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Determine the time when the helpers / organizers meet."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"If necessary create / organize lists and visitor cards."})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-one-day-before-hackathon",children:"Checklist one day before Hackathon"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{}),(0,t.jsx)(s.th,{children:"Date"}),(0,t.jsx)(s.th,{children:"Task"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Buy snacks."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Contact food supplier again if the delivery date is suitable."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Check technology for functionality."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Send around the room plan with the topics by email."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Prepare rooms if necessary / possible."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Put drinks in the refrigerator."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Provide coffee machine."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Provide dishes."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Label rooms."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Check visitor cards and lists for completeness."})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-hackathon-day-x",children:"Checklist Hackathon Day X"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{}),(0,t.jsx)(s.th,{children:"Time"}),(0,t.jsx)(s.th,{children:"Task"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Place snacks on the tables in small bowls or similar."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Distribute merchandise."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Have declarations and forms ready for late deciders."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Have lists and visitor cards ready if necessary."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Check drinks in an interval."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Make coffee if necessary."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Provide tea, coffee, milk, sugar."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Provide breakfast / snacks."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Pick up lunch."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:'Lunch "build up"'})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Cleanup"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Keep an eye on the process (keep times a little bit)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"See if everyone feels picked up, no one is bored."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Makes Photos."})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"checklist-after-hackathon",children:"Checklist after Hackathon"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{}),(0,t.jsx)(s.th,{children:"Date"}),(0,t.jsx)(s.th,{children:"Task"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Collect photos and provide them in a link for review and approval."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Create and send feedback sheet."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Create Blog Post Article."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Eventually create retro video."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Create social media posts. (After all approvals)."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Prepare debriefing."})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)("ul",{children:(0,t.jsx)("li",{children:"- [ ] "})})}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"Summarize and process feedback."})]})]})]})]})}function x(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},28453:(e,s,i)=>{i.d(s,{R:()=>d,x:()=>c});var l=i(96540);const t={},n=l.createContext(t);function d(e){const s=l.useContext(n);return l.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),l.createElement(n.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4a61a7c1.e4fe4d53.js b/assets/js/4a61a7c1.e4fe4d53.js new file mode 100644 index 0000000000..064233e6e9 --- /dev/null +++ b/assets/js/4a61a7c1.e4fe4d53.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[43705],{49837:(s,e,t)=>{t.r(e),t.d(e,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>i});const n=JSON.parse('{"id":"kaas/scs-0200","title":"scs-0200: Using Sonobuoy for KaaS conformance tests","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/kaas/scs-0200.md","sourceDirName":"kaas","slug":"/kaas/scs-0200","permalink":"/standards/kaas/scs-0200","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"KaaS Standards","permalink":"/standards/kaas/"},"next":{"title":"V1","permalink":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests"}}');var r=t(74848),a=t(28453);const o={},c="scs-0200: Using Sonobuoy for KaaS conformance tests",d={},i=[];function l(s){const e={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...s.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"scs-0200-using-sonobuoy-for-kaas-conformance-tests",children:"scs-0200: Using Sonobuoy for KaaS conformance tests"})}),"\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Version"}),(0,r.jsx)(e.th,{children:"Type"}),(0,r.jsx)(e.th,{children:"State"}),(0,r.jsx)(e.th,{children:"stabilized"}),(0,r.jsx)(e.th,{children:"deprecated"})]})}),(0,r.jsx)(e.tbody,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests",children:"scs-0200-v1"})}),(0,r.jsx)(e.td,{children:"Decision Record"}),(0,r.jsx)(e.td,{children:"Draft"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]})})]})]})}function h(s={}){const{wrapper:e}={...(0,a.R)(),...s.components};return e?(0,r.jsx)(e,{...s,children:(0,r.jsx)(l,{...s})}):l(s)}},28453:(s,e,t)=>{t.d(e,{R:()=>o,x:()=>c});var n=t(96540);const r={},a=n.createContext(r);function o(s){const e=n.useContext(a);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function c(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(r):s.components||r:o(s.components),n.createElement(a.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/4aabd97d.dbedceb2.js b/assets/js/4aabd97d.dbedceb2.js new file mode 100644 index 0000000000..8824e7a47d --- /dev/null +++ b/assets/js/4aabd97d.dbedceb2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[60183],{65729:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"scs-0214-v2-k8s-node-distribution","title":"Kubernetes Node Distribution and Availability","description":"Introduction","source":"@site/standards/scs-0214-v2-k8s-node-distribution.md","sourceDirName":".","slug":"/scs-0214-v2-k8s-node-distribution","permalink":"/standards/scs-0214-v2-k8s-node-distribution","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Kubernetes Node Distribution and Availability","type":"Standard","status":"Stable","stabilized_at":"2024-11-21T00:00:00.000Z","replaces":"scs-0214-v1-k8s-node-distribution.md","track":"KaaS"},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0214-v1-k8s-node-distribution"},"next":{"title":"W1","permalink":"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing"}}');var i=n(74848),o=n(28453);const r={title:"Kubernetes Node Distribution and Availability",type:"Standard",status:"Stable",stabilized_at:new Date("2024-11-21T00:00:00.000Z"),replaces:"scs-0214-v1-k8s-node-distribution.md",track:"KaaS"},a=void 0,l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Glossary",id:"glossary",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Decision",id:"decision",level:2},{value:"Previous standard versions",id:"previous-standard-versions",level:2}];function c(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"A Kubernetes instance is provided as a cluster, which consists of a set of machines,\nso-called nodes. A cluster is composed of a control plane and at least one worker node.\nThe control plane manages the worker nodes and therefore the pods in the cluster by making\ndecisions about scheduling, event detection and rights management. Inside the control plane,\nmultiple components exist, which can be duplicated and distributed over multiple nodes\ninside the cluster. Typically, no user workloads are run on these nodes in order to\nseparate the controller component from user workloads, which could pose a security risk."}),"\n",(0,i.jsx)(t.h3,{id:"glossary",children:"Glossary"}),"\n",(0,i.jsx)(t.p,{children:"The following terms are used throughout this document:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Term"}),(0,i.jsx)(t.th,{children:"Meaning"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Worker"}),(0,i.jsx)(t.td,{children:"Virtual or bare-metal machine, which hosts workloads of customers"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Control Plane"}),(0,i.jsx)(t.td,{children:"Virtual or bare-metal machine, which hosts the container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Machine"}),(0,i.jsx)(t.td,{children:"Virtual or bare-metal entity with computational capabilities"})]})]})]}),"\n",(0,i.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:'In normal day-to-day operation, it is not unusual for some operational failures, either\ndue to wear and tear of hardware, software misconfigurations, external problems or\nuser errors. Whichever was the source of such an outage, it always means down-time for\noperations and users and possible even data loss.\nTherefore, a Kubernetes cluster in a productive environment should be distributed over\nmultiple "failure zones" in order to provide fault-tolerance and high availability.\nThis is especially important for the control plane of the cluster, since it contains the\nstate of the whole cluster. A failure of this component could mean an unrecoverable failure\nof the whole cluster.'}),"\n",(0,i.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsxs)(t.p,{children:["Most design considerations of this standard follow the previously written Decision Record\n",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0213-v1-k8s-nodes-anti-affinity.md",children:"Kubernetes Nodes Anti Affinity"})," as well as the Kubernetes documents about\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/",children:"High Availability"})," and ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/best-practices/cluster-large/",children:"Best practices for large clusters"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"SCS wishes to prefer distributed, highly-available systems due to their obvious advantages\nlike fault-tolerance and data redundancy. But it also understands the costs and overhead\nfor the providers associated with this effort, since the infrastructure needs to have\nhardware which will just be used to provide fail-over safety or duplication."}),"\n",(0,i.jsxs)(t.p,{children:["The document ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/best-practices/cluster-large/",children:"Best practices for large clusters"})," describes the concept of a failure zone.\nThis term isn't defined any further, but can in this context be described as a number of\nphysical (computing) machines in such a vicinity to each other (either through physical\nor logical interconnection in some way), that specific problems inside this zone would put\nall these machines at risk of failure/shutdown. It is therefore necessary for important\ndata or services to not be present just on one failure zone.\nHow such a failure zone should be defined is dependent on the risk model of the service/data\nand its owner as well as the capabilities of the provider. Zones could be set from things\nlike single machines or racks up to whole datacenters or even regions, which could be\ncoupled by things like electrical grids. They're therefore purely logical entities, which\nshouldn't be defined further in this document."]}),"\n",(0,i.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(t.p,{children:"This standard formulates the requirement for the distribution of Kubernetes nodes in order\nto provide a fault-tolerant and available Kubernetes cluster infrastructure."}),"\n",(0,i.jsxs)(t.p,{children:["The control plane nodes MUST be distributed over multiple physical machines.\nKubernetes provides ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/best-practices/multiple-zones/",children:"best-practices"})," on this topic, which are also RECOMMENDED by SCS."]}),"\n",(0,i.jsx)(t.p,{children:'At least one control plane instance MUST be run in each "failure zone" used for the cluster,\nmore instances per "failure zone" are possible to provide fault-tolerance inside a zone.'}),"\n",(0,i.jsx)(t.p,{children:'Worker nodes are RECOMMENDED to be distributed over multiple zones. This policy makes\nit OPTIONAL to provide a worker node in each "failure zone", meaning that worker nodes\ncan also be scaled vertically first before scaling horizontally.'}),"\n",(0,i.jsx)(t.p,{children:"To provide metadata about the node distribution and possibly provide the ability\nto schedule workloads efficiently, which also enables testing of this standard,\nproviders MUST annotate their K8s nodes with the labels listed below.\nThese labels MUST be kept up to date with the current state of the deployment."}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.code,{children:"topology.kubernetes.io/zone"})}),"\n",(0,i.jsxs)(t.p,{children:["Corresponds with the label described in ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/labels-annotations-taints/#topologykubernetesiozone",children:"K8s labels documentation"}),".\nIt provides a logical zone of failure on the side of the provider, e.g. a server rack\nin the same electrical circuit or multiple machines bound to the internet through a\nsingular network structure. How this is defined exactly is up to the plans of the provider.\nThe field gets autopopulated most of the time by either the kubelet or external mechanisms\nlike the cloud controller."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.code,{children:"topology.kubernetes.io/region"})}),"\n",(0,i.jsxs)(t.p,{children:["Corresponds with the label described in ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/labels-annotations-taints/#topologykubernetesiozone",children:"K8s labels documentation"}),".\nIt describes the combination of one or more failure zones into a region or domain, therefore\nshowing a larger entity of logical failure zone. An example for this could be a building\ncontaining racks that are put into such a zone, since they're all prone to failure, if e.g.\nthe power for the building is cut. How this is defined exactly is also up to the provider.\nThe field gets autopopulated most of the time by either the kubelet or external mechanisms\nlike the cloud controller."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"previous-standard-versions",children:"Previous standard versions"}),"\n",(0,i.jsxs)(t.p,{children:["This is version 2 of the standard; it extends ",(0,i.jsx)(t.a,{href:"/standards/scs-0214-v1-k8s-node-distribution",children:"version 1"})," with the\nrequirements regarding node labeling."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var s=n(96540);const i={},o=s.createContext(i);function r(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4b015924.98e11af0.js b/assets/js/4b015924.98e11af0.js new file mode 100644 index 0000000000..7d302db5c0 --- /dev/null +++ b/assets/js/4b015924.98e11af0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[52076],{4937:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"iaas/guides/deploy-guide/services/network","title":"Network","description":"1. Open vSwitch (OVS)","source":"@site/docs/02-iaas/guides/deploy-guide/services/network.md","sourceDirName":"02-iaas/guides/deploy-guide/services","slug":"/iaas/guides/deploy-guide/services/network","permalink":"/docs/iaas/guides/deploy-guide/services/network","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/network.md","tags":[],"version":"current","sidebarPosition":15,"frontMatter":{"sidebar_label":"Network","sidebar_position":15},"sidebar":"docs","previous":{"title":"Kubernetes","permalink":"/docs/iaas/guides/deploy-guide/services/kubernetes"},"next":{"title":"Logging & Monitoring","permalink":"/docs/iaas/guides/deploy-guide/services/logging-monitoring"}}');var o=s(74848),t=s(28453);const r={sidebar_label:"Network",sidebar_position:15},d="Network",c={},l=[];function a(e){const n={code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"network",children:"Network"})}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Open vSwitch (OVS)"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply -a pull openvswitch\nosism apply openvswitch\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Open Virtual Network (OVN)"}),"\n",(0,o.jsxs)(n.p,{children:["In ",(0,o.jsx)(n.code,{children:"environments/kolla/configuration.yml"})," the parameter ",(0,o.jsx)(n.code,{children:"neutron_plugin_agent"})," is set to\n",(0,o.jsx)(n.code,{children:"ovn"}),". The parameter is set to ",(0,o.jsx)(n.code,{children:"ovn"})," by default in the Cookiecutter and is the OSISM default."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'# neutron\nneutron_plugin_agent: "ovn"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Before the deployment of OVN, the deployment of Open vSwitch must already have been done."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply -a pull ovn\nosism apply ovn\n"})}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>d});var i=s(96540);const o={},t=i.createContext(o);function r(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4d571bd0.0dba39e1.js b/assets/js/4d571bd0.0dba39e1.js new file mode 100644 index 0000000000..dc23f118a9 --- /dev/null +++ b/assets/js/4d571bd0.0dba39e1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[29226],{30822:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>s,metadata:()=>t,toc:()=>r});const t=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/aodh","title":"Aodh","description":"* Aodh admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/aodh.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/aodh","permalink":"/docs/iaas/guides/configuration-guide/openstack/aodh","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/aodh.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Aodh"},"sidebar":"docs","previous":{"title":"OpenStack","permalink":"/docs/iaas/guides/configuration-guide/openstack/"},"next":{"title":"Barbican","permalink":"/docs/iaas/guides/configuration-guide/openstack/barbican"}}');var i=o(74848),a=o(28453);const s={sidebar_label:"Aodh"},d="Aodh",c={},r=[];function u(e){const n={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"aodh",children:"Aodh"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/aodh/latest/admin/index.html",children:"Aodh admin guide"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/aodh/latest/configuration/index.html",children:"Aodh configuration guide"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/aodh/latest/configuration/aodh-config-options.html",children:"Aodh configuration reference"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>d});var t=o(96540);const i={},a=t.createContext(i);function s(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4e607b99.5f1183b2.js b/assets/js/4e607b99.5f1183b2.js new file mode 100644 index 0000000000..029baca382 --- /dev/null +++ b/assets/js/4e607b99.5f1183b2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[42441],{30968:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"tools/jitsi","title":"Jitsi","description":"We use a self-hosted Jitsi Meet instance for video conferencing.","source":"@site/community/tools/jitsi.md","sourceDirName":"tools","slug":"/tools/jitsi","permalink":"/community/tools/jitsi","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Tools","permalink":"/community/category/tools"},"next":{"title":"Matrix","permalink":"/community/tools/matrix"}}');var i=n(74848),s=n(28453);const r={},a="Jitsi",c={},l=[{value:"Usage",id:"usage",level:2}];function h(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"jitsi",children:"Jitsi"})}),"\n",(0,i.jsxs)(t.p,{children:["We use a self-hosted ",(0,i.jsx)(t.a,{href:"https://jitsi.org",children:"Jitsi Meet"})," instance for video conferencing.\nThanks go to Cleura for providing the server for it."]}),"\n",(0,i.jsxs)(t.p,{children:["The server uses an automated deployment based on the\n",(0,i.jsx)(t.a,{href:"https://github.com/garloff/heat-docker-jitsi-meet",children:"heat-docker-jitsi-meet"})," project."]}),"\n",(0,i.jsx)(t.p,{children:"Configuration is such everyone who knows the room can connect, unless the moderator\nsets a password/PIN. Opening a new room requires authentication. (Contact Kurt if\nyou need a password.)"}),"\n",(0,i.jsx)(t.p,{children:"Links to the meeting room (as well as dial-in information) are in the appointments\nin the public calendar."}),"\n",(0,i.jsx)(t.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsx)(t.p,{children:"Connect with a desktop browser (Chrome/Chromium or other blink based browser\nrecommended due to superior WebRTC implementation with SimulCast/SVC for VP8/VP9 --\nSafari & Firefox work, but cause higher data traffic). For mobile devices use\nthe Jitsi Meet App."}),"\n",(0,i.jsx)(t.p,{children:"Use the little arrows in the control bar at the bottom to select speaker, microphone\nand camera in case you lack audio/video. Occasionally, you can not hear all but\none participant; in this case reconnecting typically helps."}),"\n",(0,i.jsx)(t.p,{children:"We have an asterisk connected to some conference rooms to provide dial-in capabilities\nfor folks that lack internet connectivity (but have a working phone connection)."})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var o=n(96540);const i={},s=o.createContext(i);function r(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4e6fa974.da72c9e2.js b/assets/js/4e6fa974.da72c9e2.js new file mode 100644 index 0000000000..00e9ae4066 --- /dev/null +++ b/assets/js/4e6fa974.da72c9e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[70557],{2145:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"scs-0302-v1-domain-manager-role","title":"Domain Manager configuration for Keystone","description":"Introduction","source":"@site/standards/scs-0302-v1-domain-manager-role.md","sourceDirName":".","slug":"/scs-0302-v1-domain-manager-role","permalink":"/standards/scs-0302-v1-domain-manager-role","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Domain Manager configuration for Keystone","type":"Standard","status":"Stable","stabilized_at":"2024-11-13T00:00:00.000Z","track":"IAM"},"sidebar":"standards","previous":{"title":"scs-0302: Domain Manager configuration for Keystone","permalink":"/standards/iam/scs-0302"},"next":{"title":"W1","permalink":"/standards/scs-0302-w1-domain-manager-implementation-notes"}}');var s=i(74848),o=i(28453);const a={title:"Domain Manager configuration for Keystone",type:"Standard",status:"Stable",stabilized_at:new Date("2024-11-13T00:00:00.000Z"),track:"IAM"},r=void 0,d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Desired Workflow",id:"desired-workflow",level:3},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Re-using the existing <code>admin</code> role",id:"re-using-the-existing-admin-role",level:4},{value:"Introducing a new persona and role with API policy changes",id:"introducing-a-new-persona-and-role-with-api-policy-changes",level:4},{value:"Decision",id:"decision",level:2},{value:"For OpenStack Keystone 2024.2 or later",id:"for-openstack-keystone-20242-or-later",level:3},{value:"Note about upgrading from SCS Domain Manager to native integration",id:"note-about-upgrading-from-scs-domain-manager-to-native-integration",level:4},{value:"For OpenStack Keystone 2024.1 or below",id:"for-openstack-keystone-20241-or-below",level:3},{value:"Related Documents",id:"related-documents",level:2},{value:"Upstream contribution spec for the Domain Manager functionality",id:"upstream-contribution-spec-for-the-domain-manager-functionality",level:3},{value:""admin"-ness not properly scoped",id:"admin-ness-not-properly-scoped",level:3},{value:"Consistent and Secure Default RBAC",id:"consistent-and-secure-default-rbac",level:3},{value:"Conformance Tests",id:"conformance-tests",level:2},{value:"Appendix",id:"appendix",level:2},{value:"Decision Record",id:"decision-record",level:3},{value:"Change the naming of the Domain Manager role to align with upstream",id:"change-the-naming-of-the-domain-manager-role-to-align-with-upstream",level:4},{value:"Allow flexibility for the roles a Domain Manager can assign/revoke within domain",id:"allow-flexibility-for-the-roles-a-domain-manager-can-assignrevoke-within-domain",level:4},{value:"Extend domain management functionality to Keystone groups",id:"extend-domain-management-functionality-to-keystone-groups",level:4},{value:"Change the naming of the Domain Manager role",id:"change-the-naming-of-the-domain-manager-role",level:4}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.p,{children:["SCS Clouds should provide a way to grant Domain Manager rights to SCS Customers which provides IAM self-service capabilities within an OpenStack domain.\nSuch capabilities should enable the SCS customer to manage identity resources within their domain without involving the provider of the cloud.\nTo avoid conflict with the unscoped ",(0,s.jsx)(n.code,{children:"admin"}),' role in OpenStack we want to refer to this new persona as "Domain Manager", introducing the ',(0,s.jsx)(n.code,{children:"manager"})," role in the API for domains."]}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsx)(n.p,{children:'The Domain Manager functionality will be a native part of the official OpenStack beginning with release 2024.2 ("Dalmatian").'}),(0,s.jsxs)(n.p,{children:["To implement the Domain Manager in SCS clouds using an OpenStack release older than 2024.2, please refer to the supplemental ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0302-w1-domain-manager-implementation-notes.md",children:"implementation notes for this standard"}),".\nThe implementation notes document describes an alternative implementation that can be used for OpenStack 2024.1 and older releases."]})]}),"\n",(0,s.jsx)(n.h2,{id:"terminology",children:"Terminology"}),"\n",(0,s.jsx)(n.p,{children:"The following special terms are used throughout this standard document:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Term"}),(0,s.jsx)(n.th,{children:"Meaning"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"RBAC"}),(0,s.jsxs)(n.td,{children:["Role-Based Access Control",(0,s.jsx)(n.sup,{children:(0,s.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})," established by OpenStack Keystone"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"project"}),(0,s.jsx)(n.td,{children:"OpenStack project as per Keystone RBAC"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"user"}),(0,s.jsx)(n.td,{children:"OpenStack user as per Keystone RBAC"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"group"}),(0,s.jsx)(n.td,{children:"OpenStack group as per Keystone RBAC"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"role"}),(0,s.jsx)(n.td,{children:"OpenStack role as per Keystone RBAC"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"domain"}),(0,s.jsx)(n.td,{children:"OpenStack domain as per Keystone RBAC"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"IAM"}),(0,s.jsx)(n.td,{children:"identity and access management"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"persona"}),(0,s.jsx)(n.td,{children:"Abstract and conceptual role of a user in terms of IAM"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"IAM resources"}),(0,s.jsx)(n.td,{children:"projects, users, groups, roles, domains as managed by OpenStack Keystone"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"CSP"}),(0,s.jsx)(n.td,{children:"Cloud Service Provider, provider managing the OpenStack infrastructure"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"cloud admin"}),(0,s.jsxs)(n.td,{children:["OpenStack user belonging to the CSP that possesses the ",(0,s.jsx)(n.code,{children:"admin"})," role"]})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsxs)(n.p,{children:["In the default configuration of Keystone, only users with the ",(0,s.jsx)(n.code,{children:"admin"})," role may manage the IAM resources such as projects, groups and users and their relation through role assignments.\nThe ",(0,s.jsx)(n.code,{children:"admin"})," role in OpenStack Keystone is not properly scoped when assigned within a domain or project only as due to hard-coded architectural limitations in OpenStack, a user with the ",(0,s.jsx)(n.code,{children:"admin"})," role may escalate their privileges outside their assigned project or domain boundaries.\nThus, it is not possible to properly give customers a self-service functionality in regard to project, group and user management with the default configuration."]}),"\n",(0,s.jsxs)(n.p,{children:["To address this, this standard defines a new Domain Manager persona implemented using a domain-scoped ",(0,s.jsx)(n.code,{children:"manager"})," role in conjunction with appropriate Keystone API policy adjustments to establish a standardized extension to the default Keystone configuration allowing for IAM self-service capabilities for customers within domains."]}),"\n",(0,s.jsx)(n.h3,{id:"desired-workflow",children:"Desired Workflow"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"The cloud admin deploys the Domain Manager policy configuration for Keystone as per this standard if it is not already applied."}),"\n",(0,s.jsx)(n.li,{children:"The cloud admin creates the desired domains for the customers for which IAM self-service capabilities are desired."}),"\n",(0,s.jsxs)(n.li,{children:["The cloud admin creates one or more users within each of the applicable domains and assigns the ",(0,s.jsx)(n.code,{children:"manager"})," role for a certain domain to them. These users represent the Domain Managers of the corresponding domain."]}),"\n",(0,s.jsx)(n.li,{children:"The customer uses the Domain Manager users to manage (create, update, delete) users, projects, groups and corresponding role assignments within their domain."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"the Domain Manager persona MUST support managing projects, groups and users within a specific domain"}),"\n",(0,s.jsx)(n.li,{children:"the Domain Manager persona MUST be properly scoped to a domain, it MUST NOT gain access to resources outside its owning domain"}),"\n",(0,s.jsx)(n.li,{children:"the Domain Manager persona MUST NOT be able to manipulate existing roles or create new roles"}),"\n",(0,s.jsx)(n.li,{children:"the Domain Manager persona MUST only be able to assign specific non-administrative* roles to their managed users where the applicable roles are defined by the CSP"}),"\n",(0,s.jsx)(n.li,{children:"Domain Managers MUST NOT be able to abuse the role assignment functionalities to escalate their own privileges or those of other users beyond the roles defined by the CSP"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:['* "non-administrative" in this context means this excludes the role "',(0,s.jsx)(n.code,{children:"admin"}),'" and any comparable role that grants permissions beyond domain and tenant scope.\nSince the "',(0,s.jsx)(n.code,{children:"manager"}),'" role as defined in this standard is domain-scoped for a Domain Manager, it does not count as administrative.']}),"\n",(0,s.jsx)(n.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,s.jsxs)(n.h4,{id:"re-using-the-existing-admin-role",children:["Re-using the existing ",(0,s.jsx)(n.code,{children:"admin"})," role"]}),"\n",(0,s.jsxs)(n.p,{children:["As role assignments can be scoped to project, groups and domains the most obvious option would be to assign the existing ",(0,s.jsx)(n.code,{children:"admin"})," role to users representing Domain Managers in a scoped fashion."]}),"\n",(0,s.jsxs)(n.p,{children:["However, due to architectural limitations",(0,s.jsx)(n.sup,{children:(0,s.jsx)(n.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," of the existing OpenStack implementation of roles, the ",(0,s.jsx)(n.code,{children:"admin"})," role has a special meaning reaching beyond the RBAC checks done by Keystone and other OpenStack components.\nThis results in special permissions being granted to users possessing the role which ignore the project or domain scope of the role assignment.\nThis poses severe security risks as the proper scoping of the ",(0,s.jsx)(n.code,{children:"admin"})," role is impossible.\n",(0,s.jsx)(n.strong,{children:"Due to this, this approach was discarded early."})]}),"\n",(0,s.jsxs)(n.p,{children:["Upstream (OpenStack) is in the process of addressing this across the services, but it has not been fully implemented yet, especially for domains",(0,s.jsx)(n.sup,{children:(0,s.jsx)(n.a,{href:"#user-content-fn-3",id:"user-content-fnref-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"introducing-a-new-persona-and-role-with-api-policy-changes",children:"Introducing a new persona and role with API policy changes"}),"\n",(0,s.jsxs)(n.p,{children:["OpenStack Keystone allows for new roles to be created via its API by administrative users.\nAdditionally, each OpenStack API's RBAC can be adjusted through an API policy file (",(0,s.jsx)(n.code,{children:"policy.yaml"}),") through olso-policy",(0,s.jsx)(n.sup,{children:(0,s.jsx)(n.a,{href:"#user-content-fn-4",id:"user-content-fnref-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"4"})}),", Keystone included.\nThe possibility of managing users, projects, role assignments and so on is regulated through Keystone's RBAC configured by its API policy file."]}),"\n",(0,s.jsx)(n.p,{children:"This means that by creating a new role and extending Keystone's API policy configuration a new Domain Manager persona can be established that is limited to a specific subset of the Keystone API to be used to manage users, projects and role assignments within a domain."}),"\n",(0,s.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsxs)(n.p,{children:['A role named "',(0,s.jsx)(n.code,{children:"manager"}),'" MUST be present in the identity service.']}),"\n",(0,s.jsx)(n.p,{children:"The identity service MUST implement the Domain Manager functionality for this role.\nThe implementation details depend on the OpenStack Keystone version used.\nSee the sections below for reference."}),"\n",(0,s.jsx)(n.h3,{id:"for-openstack-keystone-20242-or-later",children:"For OpenStack Keystone 2024.2 or later"}),"\n",(0,s.jsxs)(n.p,{children:['For OpenStack Keystone 2024.2 or later the Domain Manager persona is already integrated natively.\nTo guarantee proper scope protection, the Identity API MUST be configured with "',(0,s.jsx)(n.code,{children:"enforce_scope"}),'" and "',(0,s.jsx)(n.code,{children:"enforce_new_defaults"}),'" enabled for the oslo.policy library.']}),"\n",(0,s.jsxs)(n.p,{children:["Example entries for the ",(0,s.jsx)(n.code,{children:"keystone.conf"})," configuration file:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[oslo_policy]\nenforce_new_defaults = True\nenforce_scope = True\n"})}),"\n",(0,s.jsxs)(n.p,{children:['The "',(0,s.jsx)(n.code,{children:"is_domain_managed_role"}),'" policy rule MAY be adjusted using a dedicated ',(0,s.jsx)(n.code,{children:"policy.yaml"})," file for the Identity API in order to adjust the set of roles a Domain Manager is able to assign/revoke.\nWhen doing so, the ",(0,s.jsx)(n.code,{children:"admin"})," role MUST NOT be added to this set."]}),"\n",(0,s.jsx)(n.h4,{id:"note-about-upgrading-from-scs-domain-manager-to-native-integration",children:"Note about upgrading from SCS Domain Manager to native integration"}),"\n",(0,s.jsxs)(n.p,{children:["In case the Identity API was upgraded from an older version where the policy-based Domain Manager implementation of SCS described in the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0302-w1-domain-manager-implementation-notes.md",children:"implementation notes for this standard"}),' was still in use, the policies described there MUST be removed.\nThe only exception to this is the "',(0,s.jsx)(n.code,{children:"is_domain_managed_role"}),'" rule in case any adjustments have been made to that rule and the CSP wants to preserve them.']}),"\n",(0,s.jsx)(n.h3,{id:"for-openstack-keystone-20241-or-below",children:"For OpenStack Keystone 2024.1 or below"}),"\n",(0,s.jsxs)(n.p,{children:["For OpenStack Keystone 2024.1 or below, the Domain Manager functionality MUST be implemented using API policies.\nFor details, refer to the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0302-w1-domain-manager-implementation-notes.md",children:"implementation notes for this standard"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:['For the release 2024.1 and below, changing the "',(0,s.jsx)(n.code,{children:"enforce_scope"}),'" and "',(0,s.jsx)(n.code,{children:"enforce_new_defaults"}),'" options for the Identity API is not necessary for the Domain Manager implementation.']}),"\n",(0,s.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsx)(n.h3,{id:"upstream-contribution-spec-for-the-domain-manager-functionality",children:"Upstream contribution spec for the Domain Manager functionality"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Description:"})," Upstream Identity service specification to introduce the Domain Manager functionality natively in OpenStack Keystone.\nAfter implementing the Domain Manager functionality as described in the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0302-w1-domain-manager-implementation-notes.md",children:"implementation notes for this standard"}),", the SCS project contributed the functionality to the official OpenStack project.\nThis eventually resulted in the feature being integrated natively in OpenStack Keystone starting with the 2024.2 release.\nThe specification was the starting point of the contribution."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Link:"})," ",(0,s.jsx)(n.a,{href:"https://specs.openstack.org/openstack/keystone-specs/specs/keystone/2024.1/domain-manager-persona.html",children:"OpenStack Identity Specs: Domain Manager Persona for domain-scoped self-service administration"})]}),"\n",(0,s.jsx)(n.h3,{id:"admin-ness-not-properly-scoped",children:'"admin"-ness not properly scoped'}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Description:"})," Upstream bug report about the underlying architectural issue of the ",(0,s.jsx)(n.code,{children:"admin"})," role not being properly scoped and giving system-level admin permissions regardless of whether the ",(0,s.jsx)(n.code,{children:"admin"})," role assignment was scoped to project or domain level.\nThis is the main reason for the ",(0,s.jsx)(n.code,{children:"admin"})," role being inappropriate to implement Domain Managers."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Link:"})," ",(0,s.jsx)(n.a,{href:"https://bugs.launchpad.net/keystone/+bug/968696",children:'Launchpad bug: "admin"-ness not properly scoped'})]}),"\n",(0,s.jsx)(n.h3,{id:"consistent-and-secure-default-rbac",children:"Consistent and Secure Default RBAC"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Description:"})," Upstream rework of the default role definitions and hierarchy across all OpenStack services.\nAims to introduce support for a scoped ",(0,s.jsx)(n.code,{children:"manager"})," role by 2024 but only focuses on project-level scoping for this role so far, not domain-level."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Link:"})," ",(0,s.jsx)(n.a,{href:"https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html",children:"OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC"})]}),"\n",(0,s.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsxs)(n.p,{children:["There is a test suite in ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iam/domain-manager/domain-manager-check.py",children:(0,s.jsx)(n.code,{children:"domain-manager-check.py"})}),".\nThe test suite connects to the OpenStack API using two sample domains and corresponding Domain Manager accounts.\nIt verifies the compliance to the standard and the proper domain-scoping as defined by the Keystone policy.\nPlease consult the associated ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iam/domain-manager/README.md",children:"README.md"})," for detailed setup and testing instructions."]}),"\n",(0,s.jsx)(n.h2,{id:"appendix",children:"Appendix"}),"\n",(0,s.jsx)(n.h3,{id:"decision-record",children:"Decision Record"}),"\n",(0,s.jsx)(n.h4,{id:"change-the-naming-of-the-domain-manager-role-to-align-with-upstream",children:"Change the naming of the Domain Manager role to align with upstream"}),"\n",(0,s.jsx)(n.p,{children:"Decision Date: 2024-03-13"}),"\n",(0,s.jsx)(n.p,{children:"Decision Maker: Team IaaS"}),"\n",(0,s.jsx)(n.p,{children:"Decision:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:'the Domain Manager role should be named "manager" not "domain-manager"'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Rationale:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:'upstream (OpenStack) will introduce a "manager" role with the upcoming RBAC rework'}),"\n",(0,s.jsx)(n.li,{children:'the "manager" role is intended to grant managing capabilities bound to the scope it is assigned for, e.g. projects; it would make sense to also integrate the Domain Manager approach here'}),"\n",(0,s.jsx)(n.li,{children:'during the process of contributing the Domain Manager functionality upstream we were asked to use the already defined "manager" role instead of introducing a new role; so the rename would then also be in line with the upstream contribution'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Links / Comments / References:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/minutes/blob/main/iaas/20240313.md#domain-manager-rolepersona-markus-hentsch",children:"Team IaaS meeting protocol entry"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://review.opendev.org/c/openstack/keystone-specs/+/903172/2/specs/keystone/2023.1/domain-manager-role.rst#20",children:'request from upstream to re-use existing "manager" role'})}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"allow-flexibility-for-the-roles-a-domain-manager-can-assignrevoke-within-domain",children:"Allow flexibility for the roles a Domain Manager can assign/revoke within domain"}),"\n",(0,s.jsx)(n.p,{children:"Decision Date: 2023-09-27"}),"\n",(0,s.jsx)(n.p,{children:"Decision Maker: Team IaaS, Team IAM"}),"\n",(0,s.jsx)(n.p,{children:"Decision:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:'the standard should not strictly limit the roles a Domain Manager can assign/revoke to/from other users within a domain to the "member" role'}),"\n",(0,s.jsx)(n.li,{children:"the standard should allow CSPs to define one or more roles for Domain Managers to manage"}),"\n",(0,s.jsx)(n.li,{children:"whether or not this includes the Domain Manager role itself is not to be predefined by the standard and should be up to the CSP to decide instead"}),"\n",(0,s.jsx)(n.li,{children:'the standard should only strictly prohibit adding the "admin" role to the list of roles manageable by Domain Managers'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Rationale:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"the available and configured roles might differ between CSPs and infrastructures"}),"\n",(0,s.jsx)(n.li,{children:"the Domain Manager standard should be flexible enough to adapt to different environments while still offering the intended functionality"}),"\n",(0,s.jsx)(n.li,{children:"there might be a tradeoff between self-service flexibility desired by customers and the security regulation a CSP wants to impose, thus allowing or prohibiting the designation of Domain Managers by customers themselves should be up to the CSP to decide"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Links / Comments / References:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://input.scs.community/2023-scs-team-iaas?view#Domain-Manager-Standard-markus-hentsch",children:"Team IaaS meeting protocol entry"})}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"extend-domain-management-functionality-to-keystone-groups",children:"Extend domain management functionality to Keystone groups"}),"\n",(0,s.jsx)(n.p,{children:"Decision Date: 2023-08-04"}),"\n",(0,s.jsx)(n.p,{children:"Decision Maker: SIG IAM"}),"\n",(0,s.jsx)(n.p,{children:"Decision:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"the Domain Manager Standard configuration should cover the groups functionality of Keystone, allowing domain manager to manage groups in domains"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Rationale:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"the groups functionality is a desired IAM feature for customers"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Links / Comments / References:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://input.scs.community/2023-scs-sig-iam#Domain-Admin-rights-for-SCS-IaaS-Customers-184",children:"SIG IAM meeting protocol entry"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/issues/issues/383",children:"action item issue"})}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"change-the-naming-of-the-domain-manager-role",children:"Change the naming of the Domain Manager role"}),"\n",(0,s.jsx)(n.p,{children:"Decision Date: 2023-08-04"}),"\n",(0,s.jsx)(n.p,{children:"Decision Maker: SIG IAM"}),"\n",(0,s.jsx)(n.p,{children:"Decision:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:'the Domain Manager role should be named "domain-manager" not "domain-admin".'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Rationale:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["avoid confusion with the unscoped admin role and to be inline with the upstream plan: ",(0,s.jsx)(n.a,{href:"https://specs.openstack.org/openstack/keystone-specs/specs/keystone/2023.1/default-service-role.html",children:"Default Service Role - Identity Specs"})]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Links / Comments / References:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://input.scs.community/2023-scs-sig-iam#Domain-Admin-rights-for-SCS-IaaS-Customers-184",children:"SIG IAM meeting protocol entry"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/issues/issues/184#issuecomment-1670985934",children:"issue comment about decision"})}),"\n"]}),"\n","\n",(0,s.jsxs)(n.section,{"data-footnotes":!0,className:"footnotes",children:[(0,s.jsx)(n.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{id:"user-content-fn-1",children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://static.opendev.org/docs/patrole/latest/rbac-overview.html",children:"OpenStack Documentation: Role-Based Access Control Overview"})," ",(0,s.jsx)(n.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{id:"user-content-fn-2",children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://bugs.launchpad.net/keystone/+bug/968696",children:'Launchpad bug: "admin"-ness not properly scoped'})," ",(0,s.jsx)(n.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{id:"user-content-fn-3",children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://docs.openstack.org/keystone/latest/contributor/services.html#domain-scope",children:"OpenStack Documentation: Keystone for Other Services - Domain Scope"})," ",(0,s.jsx)(n.a,{href:"#user-content-fnref-3","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{id:"user-content-fn-4",children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://docs.openstack.org/oslo.policy/latest/admin/index.html",children:"OpenStack Documentation: Administering Applications that use oslo.policy"})," ",(0,s.jsx)(n.a,{href:"#user-content-fnref-4","data-footnote-backref":"","aria-label":"Back to reference 4",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>r});var t=i(96540);const s={},o=t.createContext(s);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4edc808e.f6c7122c.js b/assets/js/4edc808e.f6c7122c.js new file mode 100644 index 0000000000..be61847dc1 --- /dev/null +++ b/assets/js/4edc808e.f6c7122c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[90308],{16215:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"index","title":"Introduction","description":"About","source":"@site/docs/index.mdx","sourceDirName":".","slug":"/","permalink":"/docs/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/index.mdx","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"Introduction","sidebar_position":1},"sidebar":"docs","next":{"title":"IaaS Layer","permalink":"/docs/category/iaas-layer"}}');var i=n(74848),o=n(28453),a=n(54368);const r={title:"Introduction",sidebar_position:1},l=void 0,c={},d=[{value:"About",id:"about",level:2},{value:"Architectural Overview",id:"architectural-overview",level:2},{value:"Use Cases and Deployment Examples",id:"use-cases-and-deployment-examples",level:2},{value:"IaaS Layer",id:"iaas-layer",level:3},{value:"Quick Start with Cloud-In-A-Box",id:"quick-start-with-cloud-in-a-box",level:4},{value:"Reference Implementation Testbed",id:"reference-implementation-testbed",level:4},{value:"Container Layer",id:"container-layer",level:3},{value:"Cluster Stacks",id:"cluster-stacks",level:4},{value:"Public SCS Clouds in production",id:"public-scs-clouds-in-production",level:3},{value:"Development of SCS",id:"development-of-scs",level:3},{value:"Issues and Bugs",id:"issues-and-bugs",level:3},{value:"Contribute and Connect",id:"contribute-and-connect",level:3},{value:"Releases and Roadmap",id:"releases-and-roadmap",level:3},{value:"Standards, Conformity and Certification",id:"standards-conformity-and-certification",level:2}];function h(e){const t={a:"a",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"about",children:"About"}),"\n",(0,i.jsx)(t.p,{children:"The Sovereign Cloud Stack combines the best of Cloud Computing in one unified standard.\nSCS is built, backed, and operated by an active open-source community worldwide."}),"\n",(0,i.jsx)(t.h2,{id:"architectural-overview",children:"Architectural Overview"}),"\n",(0,i.jsx)(a.A,{jsonFilePath:"data/architecturalOverviewData.json"}),"\n",(0,i.jsx)(t.h2,{id:"use-cases-and-deployment-examples",children:"Use Cases and Deployment Examples"}),"\n",(0,i.jsx)(t.h3,{id:"iaas-layer",children:"IaaS Layer"}),"\n",(0,i.jsx)(t.h4,{id:"quick-start-with-cloud-in-a-box",children:"Quick Start with Cloud-In-A-Box"}),"\n",(0,i.jsxs)(t.p,{children:["The fastest way to get in touch with SCS is to deploy a SCS cloud virtually. The Cloud-In-A-Box was built explicitly for this scenario. Check it out ",(0,i.jsx)(t.a,{href:"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box",children:"here"})]}),"\n",(0,i.jsx)(t.h4,{id:"reference-implementation-testbed",children:"Reference Implementation Testbed"}),"\n",(0,i.jsxs)(t.p,{children:["This means that you set up an SCS test installation including all the infrastructure\npieces such as database, message queueing, ceph, monitoring and logging, IAM, the\n",(0,i.jsx)(t.a,{href:"https://openstack.org/",children:"OpenStack"})," core services, and (soon) the Container layer\non top of an existing IaaS platform."]}),"\n",(0,i.jsxs)(t.p,{children:["The SCS IaaS reference implementation is based on ",(0,i.jsx)(t.a,{href:"https://osism.tech/",children:"OSISM"}),". Read on the\n",(0,i.jsx)(t.a,{href:"https://docs.osism.de/testbed/",children:"OSISM testbed docs"})," to learn how to get the\ntestbed running. Please read carefully through the\n",(0,i.jsx)(t.a,{href:"https://docs.osism.de/testbed/deployment.html",children:"deployment"})," section of the\nmanual."]}),"\n",(0,i.jsx)(t.h3,{id:"container-layer",children:"Container Layer"}),"\n",(0,i.jsx)(t.h4,{id:"cluster-stacks",children:"Cluster Stacks"}),"\n",(0,i.jsxs)(t.p,{children:["With the Cluster Stacks, in the V2 KaaS reference implementation, we provide an opinionated optimized configuration of Kubernetes clusters. Through better packaging, integrated testing, and bundled configuration, SCS-based Kubernetes clusters provide easier individualization.\nThroughout the R6 development cycle Cluster Stacks are taken from a technical preview to be ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/issues/milestone/8",children:"functional and available on top of the IaaS reference implementation"})," as well to replace the V1 KaaS reference implementation ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/",children:"k8s-cluster-api-provider"}),".\nThe Cluster Stacks can already be tried with the ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks-demo",children:"demo"})," repository. Although this is based on the not-production-ready Docker provider, the usage is the same for every provider."]}),"\n",(0,i.jsx)(t.h3,{id:"public-scs-clouds-in-production",children:"Public SCS Clouds in production"}),"\n",(0,i.jsxs)(t.p,{children:["Find the current list of scs compatible clouds ",(0,i.jsx)(t.a,{href:"https://docs.scs.community/standards/certification/overview#compliant-cloud-environments",children:"here"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"development-of-scs",children:"Development of SCS"}),"\n",(0,i.jsx)(t.p,{children:"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:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"CNCF projects,"}),"\n",(0,i.jsx)(t.li,{children:"OpenStack,"}),"\n",(0,i.jsx)(t.li,{children:"kolla-ansible,"}),"\n",(0,i.jsx)(t.li,{children:"OSISM and others."}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["All code not pushed upstream can be found in the ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack",children:"SCS Github organization"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"issues-and-bugs",children:"Issues and Bugs"}),"\n",(0,i.jsxs)(t.p,{children:["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 ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/issues",children:"issues repository"}),". We appreciate PRs as well as issues; please don't forget to sign off your contributions see ",(0,i.jsx)(t.a,{href:"https://docs.scs.community/community",children:"contributor guide"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"contribute-and-connect",children:"Contribute and Connect"}),"\n",(0,i.jsxs)(t.p,{children:["Please see the ",(0,i.jsx)(t.a,{href:"https://docs.scs.community/community",children:"SCS contributor guide"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"releases-and-roadmap",children:"Releases and Roadmap"}),"\n",(0,i.jsxs)(t.p,{children:["See our Release Notes ",(0,i.jsx)(t.a,{href:"https://docs.scs.community/docs/category/releases",children:"here"})]}),"\n",(0,i.jsx)(t.h2,{id:"standards-conformity-and-certification",children:"Standards, Conformity and Certification"}),"\n",(0,i.jsxs)(t.p,{children:["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 ",(0,i.jsx)(t.a,{href:"https://docs.scs.community/standards",children:"standards section"}),"."]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},54368:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var s=n(89839);const i="gradient_pRJN",o="border_XcL8",a="bottom_ufNC";var r=n(44586),l=n(74848);const c=e=>{const{topLayers:t}=e,n=(0,r.A)().globalData["global-data-plugin"].default.architecturalOverviewData;return n?(0,l.jsxs)("div",{className:`${i} ${o} row`,children:[!t&&(0,l.jsx)("div",{style:{display:"flex",margin:" 10px 0 4px 12px"},children:(0,l.jsx)("h5",{style:{marginBottom:0},children:"SCS Component Map"})}),(0,l.jsxs)("div",{style:{display:"flex",flexWrap:"wrap"},children:[(0,l.jsx)("div",{style:{padding:"8px 8px 8px 8px",margin:"0 0 0 0"},className:`${a} col col--3`,children:n.ops.map(((e,n)=>(0,l.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components},n)))}),(0,l.jsxs)("div",{className:"col col--6",style:{padding:"8px 8px 8px 8px",margin:"0 0 0 0"},children:[n.container.map(((e,i)=>(0,l.jsx)("div",{style:{marginBottom:e===n.container[0]?"8px":"0"},children:(0,l.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components})},i))),n.iaas.map(((e,n)=>(0,l.jsx)("div",{children:(0,l.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components})},n)))]}),(0,l.jsx)("div",{className:"col col--3",style:{padding:"8px 8px 8px 8px",margin:"0 0 0 0"},children:n.iam.map(((e,n)=>(0,l.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components},n)))})]})]}):(0,l.jsx)("div",{children:"No data available."})}},89839:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);const s="contentCard_uSpk",i="layerComponent_syzR",o="layerComponentWip_fSEJ";var a=n(28774),r=n(56347),l=n(74848);const c=e=>{const{title:t,body:n,url:c,buttonText:d,style:h,small:u,components:p}=e,m=(0,r.zy)();return(0,l.jsxs)("div",{style:h,className:`${s} card`,children:[(0,l.jsx)("div",{className:"card__header",children:u?(0,l.jsx)("h5",{style:{marginLeft:"-6px"},children:t}):(0,l.jsx)("h3",{children:t})}),(0,l.jsx)("div",{className:"card__body",children:(0,l.jsx)("p",{children:n})}),(0,l.jsx)("div",{style:{display:"flex",flexWrap:"wrap"},children:p&&p.map(((e,t)=>(0,l.jsx)(a.A,{to:e.url,children:(0,l.jsx)("div",{style:m.pathname==e.url?{color:"blue",backgroundColor:"#0066ff44"}:{},className:"true"==e.stable?i:o,children:e.title})},t)))}),d&&(0,l.jsx)("div",{className:"card__footer",children:(0,l.jsx)(a.A,{className:"button button--secondary button--md",to:c,children:d})})]})}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var s=n(96540);const i={},o=s.createContext(i);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4f2b2ca4.f39fe1fd.js b/assets/js/4f2b2ca4.f39fe1fd.js new file mode 100644 index 0000000000..2a4ebe4280 --- /dev/null +++ b/assets/js/4f2b2ca4.f39fe1fd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[87915],{48889:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Components","slug":"/category/components","permalink":"/docs/category/components","sidebar":"docs","navigation":{"previous":{"title":"Testbed Guide","permalink":"/docs/iaas/guides/other-guides/testbed"},"next":{"title":"Image Manager","permalink":"/docs/iaas/components/image-manager/"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/4f363fd8.38359925.js b/assets/js/4f363fd8.38359925.js new file mode 100644 index 0000000000..f1538f41ff --- /dev/null +++ b/assets/js/4f363fd8.38359925.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[14605],{82815:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/cinder","title":"Cinder","description":"* Cinder admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/cinder.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/cinder","permalink":"/docs/iaas/guides/configuration-guide/openstack/cinder","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/cinder.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Cinder"},"sidebar":"docs","previous":{"title":"Ceilometer","permalink":"/docs/iaas/guides/configuration-guide/openstack/ceilometer"},"next":{"title":"Designate","permalink":"/docs/iaas/guides/configuration-guide/openstack/designate"}}');var i=r(74848),s=r(28453);const o={sidebar_label:"Cinder"},c="Cinder",a={},d=[{value:"Pure Storage FlashArray",id:"pure-storage-flasharray",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"cinder",children:"Cinder"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/cinder/latest/admin/index.html",children:"Cinder admin guide"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/cinder/latest/configuration/index.html",children:"Cinder configuration guide"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/cinder/latest/configuration/block-storage/samples/cinder.conf.html",children:"Cinder configuration reference"})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"pure-storage-flasharray",children:"Pure Storage FlashArray"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://support.purestorage.com/bundle/m_openstack/page/Solutions/topics/concept/c_openstack_02.html",children:"https://support.purestorage.com/bundle/m_openstack/page/Solutions/topics/concept/c_openstack_02.html"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://support-be.purestorage.com/bundle/m_openstack/page/Solutions/OpenStack/OpenStack_Reference/library/resources/Pure_Storage_OpenStack_2023.2_Bobcat_Cinder_Driver_Best_Practices.pdf",children:"Pure Storage OpenStack (2023.2) Cinder Driver Best Practices"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://github.com/openstack/cinder/blob/master/cinder/volume/drivers/pure.py",children:"https://github.com/openstack/cinder/blob/master/cinder/volume/drivers/pure.py"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/cinder/latest/configuration/block-storage/drivers/pure-storage-driver.html",children:"https://docs.openstack.org/cinder/latest/configuration/block-storage/drivers/pure-storage-driver.html"})}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>c});var t=r(96540);const i={},s=t.createContext(i);function o(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/500c8deb.9b501f1f.js b/assets/js/500c8deb.9b501f1f.js new file mode 100644 index 0000000000..83b92af728 --- /dev/null +++ b/assets/js/500c8deb.9b501f1f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[73634],{8969:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>n,default:()=>d,frontMatter:()=>c,metadata:()=>r,toc:()=>i});const r=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","title":"Deep dive: User flow","description":"It is essential to understand the flow of what you have to do as a user and what happens in the background.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/architecture","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow.md","tags":[],"version":"current","frontMatter":{}}');var o=s(74848),a=s(28453);const c={},n="Deep dive: User flow",l={},i=[{value:"Steps to create a workload cluster",id:"steps-to-create-a-workload-cluster",level:2},{value:"Get the right cluster stacks",id:"get-the-right-cluster-stacks",level:3},{value:"Apply cluster stack resource",id:"apply-cluster-stack-resource",level:3},{value:"Use the ClusterClasses",id:"use-the-clusterclasses",level:3},{value:"Wait until cluster addons are ready",id:"wait-until-cluster-addons-are-ready",level:3},{value:"Recap - how do Cluster API and Cluster Stacks work together?",id:"recap---how-do-cluster-api-and-cluster-stacks-work-together",level:2}];function u(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"deep-dive-user-flow",children:"Deep dive: User flow"})}),"\n",(0,o.jsx)(t.p,{children:"It is essential to understand the flow of what you have to do as a user and what happens in the background."}),"\n",(0,o.jsxs)(t.p,{children:["The ",(0,o.jsx)(t.a,{href:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart",children:"Quickstart guide"})," goes over all small steps you have to do to. If you are just interested in getting started, then have a look there."]}),"\n",(0,o.jsx)(t.p,{children:"In the following, we will not go into the detail of every command, but will focus more on a high-level of what you have to do and of what happens in the background."}),"\n",(0,o.jsx)(t.h2,{id:"steps-to-create-a-workload-cluster",children:"Steps to create a workload cluster"}),"\n",(0,o.jsx)(t.h3,{id:"get-the-right-cluster-stacks",children:"Get the right cluster stacks"}),"\n",(0,o.jsx)(t.p,{children:"The first step would be to make sure that you have the cluster stacks implemented that you want to use. Usually, you will use cluster stacks that have been implemented by others for the provider that you want to use. However, you can also build your own cluster stacks."}),"\n",(0,o.jsx)(t.h3,{id:"apply-cluster-stack-resource",children:"Apply cluster stack resource"}),"\n",(0,o.jsxs)(t.p,{children:["If you have everything available, you can start your management cluster / bootstrap cluster. In this cluster, you have to apply the ",(0,o.jsx)(t.code,{children:"ClusterStack"})," custom resource with your individual desired configuration."]}),"\n",(0,o.jsx)(t.p,{children:"Depending on your configuration, you will have to wait until all steps are done in the background."}),"\n",(0,o.jsx)(t.p,{children:"The operator will perform all necessary steps to provide you with node images. If all node images are ready, it will apply the Cluster API resources that are required."}),"\n",(0,o.jsx)(t.p,{children:"At the end, you will have node images and Cluster API objects ready to use. There is only one step more to create a cluster."}),"\n",(0,o.jsx)(t.h3,{id:"use-the-clusterclasses",children:"Use the ClusterClasses"}),"\n",(0,o.jsxs)(t.p,{children:["That the previous step is done, you can see in the status of the ",(0,o.jsx)(t.code,{children:"ClusterStack"})," object. However, you can also just check if you have certain ",(0,o.jsx)(t.code,{children:"ClusterClass"})," objects. The ",(0,o.jsx)(t.code,{children:"ClusterClass"}),' objects will be applied by the Cluster Stack Operator as well. They follow a certain naming pattern. If you have the cluster stack "ferrol" for the docker provider and Kubernetes version 1.27 in version "v1", then you\'ll see a ',(0,o.jsx)(t.code,{children:"ClusterClass"}),' that has the name "docker-ferrol-1-27-v1".']}),"\n",(0,o.jsxs)(t.p,{children:["You can use this ",(0,o.jsx)(t.code,{children:"ClusterClass"})," by referencing it in a ",(0,o.jsx)(t.code,{children:"Cluster"})," object. For details, you can check out the official Cluster-API documentation."]}),"\n",(0,o.jsx)(t.h3,{id:"wait-until-cluster-addons-are-ready",children:"Wait until cluster addons are ready"}),"\n",(0,o.jsxs)(t.p,{children:["If you created a workload cluster by applying a ",(0,o.jsx)(t.code,{children:"Cluster"})," object, the cluster addons will be applied automatically. You just have to wait until everything is ready, e.g. that the CCM or CNI are installed."]}),"\n",(0,o.jsx)(t.h2,{id:"recap---how-do-cluster-api-and-cluster-stacks-work-together",children:"Recap - how do Cluster API and Cluster Stacks work together?"}),"\n",(0,o.jsxs)(t.p,{children:["The user triggers the flow by configuring and applying a ",(0,o.jsx)(t.code,{children:"ClusterStack"})," custom resource. This will trigger some work in the background, to make node images and Cluster API objects ready to use."]}),"\n",(0,o.jsxs)(t.p,{children:["This process is completed, when a ",(0,o.jsx)(t.code,{children:"ClusterClass"})," with a certain name is created. This ",(0,o.jsx)(t.code,{children:"ClusterClass"})," resource is used in order to create as many clusters as you want that look like the template specified in the ",(0,o.jsx)(t.code,{children:"ClusterClass"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["Upgrades of clusters are done by changing the reference to a new ",(0,o.jsx)(t.code,{children:"ClusterClass"}),", e.g. from ",(0,o.jsx)(t.code,{children:"docker-ferrol-1-27-v1"})," to ",(0,o.jsx)(t.code,{children:"docker-ferrol-1-27-v2"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["To sum up: The Cluster Stack Operator takes care of steps that you would otherwise have to do manually. It does not change anything in the normal Cluster API flow, expcept that it enforces the use of ",(0,o.jsx)(t.code,{children:"ClusterClasses"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>n});var r=s(96540);const o={},a=r.createContext(o);function c(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function n(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/50141.eccf700d.js b/assets/js/50141.eccf700d.js new file mode 100644 index 0000000000..c7a0582036 --- /dev/null +++ b/assets/js/50141.eccf700d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[50141],{50141:(e,t,s)=>{s.d(t,{diagram:()=>V});var o=s(27899),i=s(697),a=s(26312),r=s(86079),n=s(8995);s(74353),s(16750),s(42838),s(21176),s(14075);const d="rect",c="rectWithTitle",l="statediagram",p=`${l}-state`,b="transition",g=`${b} note-edge`,h=`${l}-note`,u=`${l}-cluster`,y=`${l}-cluster-alt`,f="parent",w="note",x="----",$=`${x}${w}`,m=`${x}${f}`,T="fill:none",S="fill: #333",k="text",v="normal";let D={},A=0;function B(e="",t=0,s="",o=x){return`state-${e}${null!==s&&s.length>0?`${o}${s}`:""}-${t}`}const L=(e,t,s,i,a,n)=>{const l=s.id,b=null==(x=i[l])?"":x.classes?x.classes.join(" "):"";var x;if("root"!==l){let t=d;!0===s.start&&(t="start"),!1===s.start&&(t="end"),s.type!==o.D&&(t=s.type),D[l]||(D[l]={id:l,shape:t,description:r.e.sanitizeText(l,(0,r.c)()),classes:`${b} ${p}`});const i=D[l];s.description&&(Array.isArray(i.description)?(i.shape=c,i.description.push(s.description)):i.description.length>0?(i.shape=c,i.description===l?i.description=[s.description]:i.description=[i.description,s.description]):(i.shape=d,i.description=s.description),i.description=r.e.sanitizeTextOrArray(i.description,(0,r.c)())),1===i.description.length&&i.shape===c&&(i.shape=d),!i.type&&s.doc&&(r.l.info("Setting cluster for ",l,E(s)),i.type="group",i.dir=E(s),i.shape=s.type===o.a?"divider":"roundedWithTitle",i.classes=i.classes+" "+u+" "+(n?y:""));const a={labelStyle:"",shape:i.shape,labelText:i.description,classes:i.classes,style:"",id:l,dir:i.dir,domId:B(l,A),type:i.type,padding:15,centerLabel:!0};if(s.note){const t={labelStyle:"",shape:"note",labelText:s.note.text,classes:h,style:"",id:l+$+"-"+A,domId:B(l,A,w),type:i.type,padding:15},o={labelStyle:"",shape:"noteGroup",labelText:s.note.text,classes:i.classes,style:"",id:l+m,domId:B(l,A,f),type:"group",padding:0};A++;const r=l+m;e.setNode(r,o),e.setNode(t.id,t),e.setNode(l,a),e.setParent(l,r),e.setParent(t.id,r);let n=l,d=t.id;"left of"===s.note.position&&(n=t.id,d=l),e.setEdge(n,d,{arrowhead:"none",arrowType:"",style:T,labelStyle:"",classes:g,arrowheadStyle:S,labelpos:"c",labelType:k,thickness:v})}else e.setNode(l,a)}t&&"root"!==t.id&&(r.l.trace("Setting node ",l," to be child of its parent ",t.id),e.setParent(l,t.id)),s.doc&&(r.l.trace("Adding nodes children "),C(e,s,s.doc,i,a,!n))},C=(e,t,s,i,a,n)=>{r.l.trace("items",s),s.forEach((s=>{switch(s.stmt){case o.b:case o.D:L(e,t,s,i,a,n);break;case o.S:{L(e,t,s.state1,i,a,n),L(e,t,s.state2,i,a,n);const o={id:"edge"+A,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:T,labelStyle:"",label:r.e.sanitizeText(s.description,(0,r.c)()),arrowheadStyle:S,labelpos:"c",labelType:k,thickness:v,classes:b};e.setEdge(s.state1.id,s.state2.id,o,A),A++}}}))},E=(e,t=o.c)=>{let s=t;if(e.doc)for(let o=0;o<e.doc.length;o++){const t=e.doc[o];"dir"===t.stmt&&(s=t.value)}return s},R={setConf:function(e){const t=Object.keys(e);for(const s of t)e[s]},getClasses:function(e,t){return t.db.extract(t.db.getRootDocV2()),t.db.getClasses()},draw:async function(e,t,s,o){r.l.info("Drawing state diagram (v2)",t),D={},o.db.getDirection();const{securityLevel:c,state:p}=(0,r.c)(),b=p.nodeSpacing||50,g=p.rankSpacing||50;r.l.info(o.db.getRootDocV2()),o.db.extract(o.db.getRootDocV2()),r.l.info(o.db.getRootDocV2());const h=o.db.getStates(),u=new i.T({multigraph:!0,compound:!0}).setGraph({rankdir:E(o.db.getRootDocV2()),nodesep:b,ranksep:g,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));let y;L(u,void 0,o.db.getRootDocV2(),h,o.db,!0),"sandbox"===c&&(y=(0,a.Ltv)("#i"+t));const f="sandbox"===c?(0,a.Ltv)(y.nodes()[0].contentDocument.body):(0,a.Ltv)("body"),w=f.select(`[id="${t}"]`),x=f.select("#"+t+" g");await(0,n.r)(x,u,["barb"],l,t);r.u.insertTitle(w,"statediagramTitleText",p.titleTopMargin,o.db.getDiagramTitle());const $=w.node().getBBox(),m=$.width+16,T=$.height+16;w.attr("class",l);const S=w.node().getBBox();(0,r.i)(w,T,m,p.useMaxWidth);const k=`${S.x-8} ${S.y-8} ${m} ${T}`;r.l.debug(`viewBox ${k}`),w.attr("viewBox",k);const v=document.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const i of v){const e=i.getBBox(),t=document.createElementNS("http://www.w3.org/2000/svg",d);t.setAttribute("rx",0),t.setAttribute("ry",0),t.setAttribute("width",e.width),t.setAttribute("height",e.height),i.insertBefore(t,i.firstChild)}}},V={parser:o.p,db:o.d,renderer:R,styles:o.s,init:e=>{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute,o.d.clear()}}}}]); \ No newline at end of file diff --git a/assets/js/502adbf6.4d5032e2.js b/assets/js/502adbf6.4d5032e2.js new file mode 100644 index 0000000000..95868551a5 --- /dev/null +++ b/assets/js/502adbf6.4d5032e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[48561],{42288:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>r,contentTitle:()=>a,default:()=>c,frontMatter:()=>t,metadata:()=>n,toc:()=>u});const n=JSON.parse('{"id":"iaas/guides/index","title":"Guides","description":"* The Concept Guide explains which components and modules make up OSISM. It also","source":"@site/docs/02-iaas/guides/index.md","sourceDirName":"02-iaas/guides","slug":"/iaas/guides/","permalink":"/docs/iaas/guides/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/index.md","tags":[],"version":"current","sidebarPosition":50,"frontMatter":{"sidebar_label":"Guides","sidebar_position":50},"sidebar":"docs","previous":{"title":"Ceph","permalink":"/docs/iaas/guides/troubleshooting-guide/ceph"},"next":{"title":"User Guide","permalink":"/docs/iaas/guides/user-guide/"}}');var d=s(74848),o=s(28453);const t={sidebar_label:"Guides",sidebar_position:50},a="Guides",r={},u=[];function l(e){const i={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,o.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(i.header,{children:(0,d.jsx)(i.h1,{id:"guides",children:"Guides"})}),"\n",(0,d.jsxs)(i.ul,{children:["\n",(0,d.jsxs)(i.li,{children:["The ",(0,d.jsx)(i.a,{href:"./concept-guide/",children:"Concept Guide"})," explains which components and modules make up OSISM. It also\nexplains the use cases."]}),"\n",(0,d.jsxs)(i.li,{children:["The ",(0,d.jsx)(i.a,{href:"./deploy-guide/",children:"Deploy Guide"})," explains how the nodes of a cluster are created and bootstrapped.\nIt also explains how the individual modules can be deployed."]}),"\n",(0,d.jsxs)(i.li,{children:["The ",(0,d.jsx)(i.a,{href:"./upgrade-guide/",children:"Upgrade Guide"})," explains how the individual modules can be upgraded."]}),"\n",(0,d.jsxs)(i.li,{children:["The ",(0,d.jsx)(i.a,{href:"./configuration-guide/",children:"Configuration Guide"})," explains how the individual modules can be\nconfigured."]}),"\n",(0,d.jsxs)(i.li,{children:["The ",(0,d.jsx)(i.a,{href:"./operations-guide/",children:"Operations Guide"})," explains how individual tasks can be done in\nday-to-day business in a running cluster."]}),"\n",(0,d.jsxs)(i.li,{children:["The ",(0,d.jsx)(i.a,{href:"./troubleshooting-guide/",children:"Troubleshooting Guide"})," explains how to resolve problems.\nIt is an extension of the Operations Guide."]}),"\n",(0,d.jsxs)(i.li,{children:["The ",(0,d.jsx)(i.a,{href:"./user-guide/",children:"User Guide"})," is intended for users of the individual components. It contains\nbest practices, as well as other information."]}),"\n"]})]})}function c(e={}){const{wrapper:i}={...(0,o.R)(),...e.components};return i?(0,d.jsx)(i,{...e,children:(0,d.jsx)(l,{...e})}):l(e)}},28453:(e,i,s)=>{s.d(i,{R:()=>t,x:()=>a});var n=s(96540);const d={},o=n.createContext(d);function t(e){const i=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:t(e.components),n.createElement(o.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/50971.384492b6.js b/assets/js/50971.384492b6.js new file mode 100644 index 0000000000..ea346bc2f0 --- /dev/null +++ b/assets/js/50971.384492b6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[50971],{50971:(t,e,n)=>{n.d(e,{diagram:()=>O});var i=n(86079),s=n(26312),r=n(3219),a=n(78041),o=n(75263),l=(n(74353),n(16750),n(42838),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[6,8,10,11,12,14,16,17,20,21],n=[1,9],i=[1,10],s=[1,11],r=[1,12],a=[1,13],o=[1,16],l=[1,17],c={trace:function(){},yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,period_statement:18,event_statement:19,period:20,event:21,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",20:"period",21:"event"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[18,1],[19,1]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.getCommonDb().setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 9:this.$=r[o].trim(),i.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=r[o].trim(),i.getCommonDb().setAccDescription(this.$);break;case 12:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 15:i.addTask(r[o],0,""),this.$=r[o];break;case 16:i.addEvent(r[o].substr(2)),this.$=r[o]}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:n,12:i,14:s,16:r,17:a,18:14,19:15,20:o,21:l},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:18,11:n,12:i,14:s,16:r,17:a,18:14,19:15,20:o,21:l},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,19]},{15:[1,20]},t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),t(e,[2,4]),t(e,[2,9]),t(e,[2,10])],defaultActions:{},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,o="",l=0,c=0,h=r.slice.call(arguments,1),d=Object.create(this.lexer),u={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(u.yy[p]=this.yy[p]);d.setInput(t,u.yy),u.yy.lexer=d,u.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var y=d.yylloc;r.push(y);var g=d.options&&d.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,m,_,b,x,k,v,w,S,$={};;){if(m=n[n.length-1],this.defaultActions[m]?_=this.defaultActions[m]:(null==f&&(S=void 0,"number"!=typeof(S=i.pop()||d.lex()||1)&&(S instanceof Array&&(S=(i=S).pop()),S=e.symbols_[S]||S),f=S),_=a[m]&&a[m][f]),void 0===_||!_.length||!_[0]){var E="";for(x in w=[],a[m])this.terminals_[x]&&x>2&&w.push("'"+this.terminals_[x]+"'");E=d.showPosition?"Parse error on line "+(l+1)+":\n"+d.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(E,{text:d.match,token:this.terminals_[f]||f,line:d.yylineno,loc:y,expected:w})}if(_[0]instanceof Array&&_.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+f);switch(_[0]){case 1:n.push(f),s.push(d.yytext),r.push(d.yylloc),n.push(_[1]),f=null,c=d.yyleng,o=d.yytext,l=d.yylineno,y=d.yylloc;break;case 2:if(k=this.productions_[_[1]][1],$.$=s[s.length-k],$._$={first_line:r[r.length-(k||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(k||1)].first_column,last_column:r[r.length-1].last_column},g&&($._$.range=[r[r.length-(k||1)].range[0],r[r.length-1].range[1]]),void 0!==(b=this.performAction.apply($,[o,c,l,u.yy,_[1],s,r].concat(h))))return b;k&&(n=n.slice(0,-1*k*2),s=s.slice(0,-1*k),r=r.slice(0,-1*k)),n.push(this.productions_[_[1]][0]),s.push($.$),r.push($._$),v=a[n[n.length-2]][n[n.length-1]],n.push(v);break;case 3:return!0}}return!0}},h={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:case 1:case 3:case 4:break;case 2:return 10;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),14;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 21;case 16:return 20;case 17:return 6;case 18:return"INVALID"}},rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:timeline\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?::\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18],inclusive:!0}}};function d(){this.yy={}}return c.lexer=h,d.prototype=c,c.Parser=d,new d}());l.parser=l;const c=l;let h="",d=0;const u=[],p=[],y=[],g=()=>i.L,f=function(){u.length=0,p.length=0,h="",y.length=0,(0,i.v)()},m=function(t){h=t,u.push(t)},_=function(){return u},b=function(){let t=w();let e=0;for(;!t&&e<100;)t=w(),e++;return p.push(...y),p},x=function(t,e,n){const i={id:d++,section:h,type:h,task:t,score:e||0,events:n?[n]:[]};y.push(i)},k=function(t){y.find((t=>t.id===d-1)).events.push(t)},v=function(t){const e={section:h,type:h,description:t,task:t,classes:[]};p.push(e)},w=function(){let t=!0;for(const[e,n]of y.entries())y[e].processed,t=t&&n.processed;return t},S={clear:f,getCommonDb:g,addSection:m,getSections:_,getTasks:b,addTask:x,addTaskOrg:v,addEvent:k},$=Object.freeze(Object.defineProperty({__proto__:null,addEvent:k,addSection:m,addTask:x,addTaskOrg:v,clear:f,default:S,getCommonDb:g,getSections:_,getTasks:b},Symbol.toStringTag,{value:"Module"}));!function(){function t(t,e,n,s,r,a,o,l){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",l).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,l,c){const{taskFontSize:h,taskFontFamily:d}=l,u=t.split(/<br\s*\/?>/gi);for(let p=0;p<u.length;p++){const t=p*h-h*(u.length-1)/2,l=e.append("text").attr("x",n+r/2).attr("y",s).attr("fill",c).style("text-anchor","middle").style("font-size",h).style("font-family",d);l.append("tspan").attr("x",n+r/2).attr("dy",t).text(u[p]),l.attr("y",s+a/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(l,o)}}function n(t,n,s,r,a,o,l,c){const h=n.append("switch"),d=h.append("foreignObject").attr("x",s).attr("y",r).attr("width",a).attr("height",o).attr("position","fixed").append("xhtml:div").style("display","table").style("height","100%").style("width","100%");d.append("div").attr("class","label").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,s,r,a,o,l,c),i(d,l)}function i(t,e){for(const n in e)n in e&&t.attr(n,e[n])}}();function E(t,e){t.each((function(){var t,n=(0,s.Ltv)(this),i=n.text().split(/(\s+|<br>)/).reverse(),r=[],a=n.attr("y"),o=parseFloat(n.attr("dy")),l=n.text(null).append("tspan").attr("x",0).attr("y",a).attr("dy",o+"em");for(let s=0;s<i.length;s++)t=i[i.length-1-s],r.push(t),l.text(r.join(" ").trim()),(l.node().getComputedTextLength()>e||"<br>"===t)&&(r.pop(),l.text(r.join(" ").trim()),r="<br>"===t?[""]:[t],l=n.append("tspan").attr("x",0).attr("y",a).attr("dy","1.1em").text(t))}))}const I=function(t,e,n){t.append("path").attr("id","node-"+e.id).attr("class","node-bkg node-"+e.type).attr("d",`M0 ${e.height-5} v${10-e.height} q0,-5 5,-5 h${e.width-10} q5,0 5,5 v${e.height-5} H0 Z`),t.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",e.height).attr("x2",e.width).attr("y2",e.height)},L=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},T=function(t,e,n,i){const s=n%12-1,r=t.append("g");e.section=s,r.attr("class",(e.class?e.class+" ":"")+"timeline-node section-"+s);const a=r.append("g"),o=r.append("g"),l=o.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(E,e.width).node().getBBox(),c=i.fontSize&&i.fontSize.replace?i.fontSize.replace("px",""):i.fontSize;return e.height=l.height+1.1*c*.5+e.padding,e.height=Math.max(e.height,e.maxHeight),e.width=e.width+2*e.padding,o.attr("transform","translate("+e.width/2+", "+e.padding/2+")"),I(a,e,s),e},A=function(t,e,n){const i=t.append("g"),s=i.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(E,e.width).node().getBBox(),r=n.fontSize&&n.fontSize.replace?n.fontSize.replace("px",""):n.fontSize;return i.remove(),s.height+1.1*r*.5+e.padding},C=function(t,e,n,s,r,a,o,l,c,h,d){var u;for(const p of e){const e={descr:p.task,section:n,number:n,width:150,padding:20,maxHeight:a};i.l.debug("taskNode",e);const l=t.append("g").attr("class","taskWrapper"),y=T(l,e,n,o).height;if(i.l.debug("taskHeight after draw",y),l.attr("transform",`translate(${s}, ${r})`),a=Math.max(a,y),p.events){const e=t.append("g").attr("class","lineWrapper");let i=a;r+=100,i+=M(t,p.events,n,s,r,o),r-=100,e.append("line").attr("x1",s+95).attr("y1",r+a).attr("x2",s+95).attr("y2",r+a+(d?a:h)+c+120).attr("stroke-width",2).attr("stroke","black").attr("marker-end","url(#arrowhead)").attr("stroke-dasharray","5,5")}s+=200,d&&!(null==(u=o.timeline)?void 0:u.disableMulticolor)&&n++}r-=10},M=function(t,e,n,s,r,a){let o=0;const l=r;r+=100;for(const c of e){const e={descr:c,section:n,number:n,width:150,padding:20,maxHeight:50};i.l.debug("eventNode",e);const l=t.append("g").attr("class","eventWrapper"),h=T(l,e,n,a).height;o+=h,l.attr("transform",`translate(${s}, ${r})`),r=r+10+h}return r=l,o},O={db:$,renderer:{setConf:()=>{},draw:function(t,e,n,r){var a,o;const l=(0,i.c)(),c=l.leftMargin??50;i.l.debug("timeline",r.db);const h=l.securityLevel;let d;"sandbox"===h&&(d=(0,s.Ltv)("#i"+e));const u=("sandbox"===h?(0,s.Ltv)(d.nodes()[0].contentDocument.body):(0,s.Ltv)("body")).select("#"+e);u.append("g");const p=r.db.getTasks(),y=r.db.getCommonDb().getDiagramTitle();i.l.debug("task",p),L(u);const g=r.db.getSections();i.l.debug("sections",g);let f=0,m=0,_=0,b=0,x=50+c,k=50;b=50;let v=0,w=!0;g.forEach((function(t){const e=A(u,{number:v,descr:t,section:v,width:150,padding:20,maxHeight:f},l);i.l.debug("sectionHeight before draw",e),f=Math.max(f,e+20)}));let S=0,$=0;i.l.debug("tasks.length",p.length);for(const[s,I]of p.entries()){const t={number:s,descr:I,section:I.section,width:150,padding:20,maxHeight:m},e=A(u,t,l);i.l.debug("taskHeight before draw",e),m=Math.max(m,e+20),S=Math.max(S,I.events.length);let n=0;for(let i=0;i<I.events.length;i++){const t={descr:I.events[i],section:I.section,number:I.section,width:150,padding:20,maxHeight:50};n+=A(u,t,l)}$=Math.max($,n)}i.l.debug("maxSectionHeight before draw",f),i.l.debug("maxTaskHeight before draw",m),g&&g.length>0?g.forEach((t=>{const e=p.filter((e=>e.section===t)),n={number:v,descr:t,section:v,width:200*Math.max(e.length,1)-50,padding:20,maxHeight:f};i.l.debug("sectionNode",n);const s=u.append("g"),r=T(s,n,v,l);i.l.debug("sectionNode output",r),s.attr("transform",`translate(${x}, 50)`),k+=f+50,e.length>0&&C(u,e,v,x,k,m,l,S,$,f,!1),x+=200*Math.max(e.length,1),k=50,v++})):(w=!1,C(u,p,v,x,k,m,l,S,$,f,!0));const E=u.node().getBBox();i.l.debug("bounds",E),y&&u.append("text").text(y).attr("x",E.width/2-c).attr("font-size","4ex").attr("font-weight","bold").attr("y",20),_=w?f+m+150:m+100;u.append("g").attr("class","lineWrapper").append("line").attr("x1",c).attr("y1",_).attr("x2",E.width+3*c).attr("y2",_).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)"),(0,i.o)(void 0,u,(null==(a=l.timeline)?void 0:a.padding)??50,(null==(o=l.timeline)?void 0:o.useMaxWidth)??!1)}},parser:c,styles:t=>`\n .edge {\n stroke-width: 3;\n }\n ${(t=>{let e="";for(let n=0;n<t.THEME_COLOR_LIMIT;n++)t["lineColor"+n]=t["lineColor"+n]||t["cScaleInv"+n],(0,r.A)(t["lineColor"+n])?t["lineColor"+n]=(0,a.A)(t["lineColor"+n],20):t["lineColor"+n]=(0,o.A)(t["lineColor"+n],20);for(let n=0;n<t.THEME_COLOR_LIMIT;n++){const i=""+(17-3*n);e+=`\n .section-${n-1} rect, .section-${n-1} path, .section-${n-1} circle, .section-${n-1} path {\n fill: ${t["cScale"+n]};\n }\n .section-${n-1} text {\n fill: ${t["cScaleLabel"+n]};\n }\n .node-icon-${n-1} {\n font-size: 40px;\n color: ${t["cScaleLabel"+n]};\n }\n .section-edge-${n-1}{\n stroke: ${t["cScale"+n]};\n }\n .edge-depth-${n-1}{\n stroke-width: ${i};\n }\n .section-${n-1} line {\n stroke: ${t["cScaleInv"+n]} ;\n stroke-width: 3;\n }\n\n .lineWrapper line{\n stroke: ${t["cScaleLabel"+n]} ;\n }\n\n .disabled, .disabled circle, .disabled text {\n fill: lightgray;\n }\n .disabled text {\n fill: #efefef;\n }\n `}return e})(t)}\n .section-root rect, .section-root path, .section-root circle {\n fill: ${t.git0};\n }\n .section-root text {\n fill: ${t.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .eventWrapper {\n filter: brightness(120%);\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/51169.37d3e1c7.js b/assets/js/51169.37d3e1c7.js new file mode 100644 index 0000000000..f7c4329e65 --- /dev/null +++ b/assets/js/51169.37d3e1c7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[51169],{73046:(t,e,r)=>{r.d(e,{T:()=>k});var n=r(48585),o=r(39142),i=r(89610),s=r(27422),u=r(11662),c=r(66401),a=r(8058),f=r(69592),h=r(13588),A=r(24326),d=r(62062),l=r(25707);const v=function(t){return t!=t};const b=function(t,e,r){for(var n=r-1,o=t.length;++n<o;)if(t[n]===e)return n;return-1};const _=function(t,e,r){return e==e?b(t,e,r):(0,l.A)(t,v,r)};const p=function(t,e){return!!(null==t?0:t.length)&&_(t,e,0)>-1};const g=function(t,e,r){for(var n=-1,o=null==t?0:t.length;++n<o;)if(r(e,t[n]))return!0;return!1};var j=r(64099),y=r(39857);const m=function(){};var w=r(29959),O=y.A&&1/(0,w.A)(new y.A([,-0]))[1]==1/0?function(t){return new y.A(t)}:m;const C=O;const E=function(t,e,r){var n=-1,o=p,i=t.length,s=!0,u=[],c=u;if(r)s=!1,o=g;else if(i>=200){var a=e?null:C(t);if(a)return(0,w.A)(a);s=!1,o=j.A,c=new d.A}else c=e?[]:u;t:for(;++n<i;){var f=t[n],h=e?e(f):f;if(f=r||0!==f?f:0,s&&h==h){for(var A=c.length;A--;)if(c[A]===h)continue t;e&&c.push(h),u.push(f)}else o(c,h,r)||(c!==u&&c.push(h),u.push(f))}return u};var L=r(53533);const N=(0,A.A)((function(t){return E((0,h.A)(t,1,L.A,!0))}));var D=r(38207),S=r(89463),F="\0",P="\0",M="\x01";class k{constructor(t={}){this._isDirected=!n.A(t,"directed")||t.directed,this._isMultigraph=!!n.A(t,"multigraph")&&t.multigraph,this._isCompound=!!n.A(t,"compound")&&t.compound,this._label=void 0,this._defaultNodeLabelFn=o.A(void 0),this._defaultEdgeLabelFn=o.A(void 0),this._nodes={},this._isCompound&&(this._parent={},this._children={},this._children[P]={}),this._in={},this._preds={},this._out={},this._sucs={},this._edgeObjs={},this._edgeLabels={}}isDirected(){return this._isDirected}isMultigraph(){return this._isMultigraph}isCompound(){return this._isCompound}setGraph(t){return this._label=t,this}graph(){return this._label}setDefaultNodeLabel(t){return i.A(t)||(t=o.A(t)),this._defaultNodeLabelFn=t,this}nodeCount(){return this._nodeCount}nodes(){return s.A(this._nodes)}sources(){var t=this;return u.A(this.nodes(),(function(e){return c.A(t._in[e])}))}sinks(){var t=this;return u.A(this.nodes(),(function(e){return c.A(t._out[e])}))}setNodes(t,e){var r=arguments,n=this;return a.A(t,(function(t){r.length>1?n.setNode(t,e):n.setNode(t)})),this}setNode(t,e){return n.A(this._nodes,t)?(arguments.length>1&&(this._nodes[t]=e),this):(this._nodes[t]=arguments.length>1?e:this._defaultNodeLabelFn(t),this._isCompound&&(this._parent[t]=P,this._children[t]={},this._children[P][t]=!0),this._in[t]={},this._preds[t]={},this._out[t]={},this._sucs[t]={},++this._nodeCount,this)}node(t){return this._nodes[t]}hasNode(t){return n.A(this._nodes,t)}removeNode(t){var e=this;if(n.A(this._nodes,t)){var r=function(t){e.removeEdge(e._edgeObjs[t])};delete this._nodes[t],this._isCompound&&(this._removeFromParentsChildList(t),delete this._parent[t],a.A(this.children(t),(function(t){e.setParent(t)})),delete this._children[t]),a.A(s.A(this._in[t]),r),delete this._in[t],delete this._preds[t],a.A(s.A(this._out[t]),r),delete this._out[t],delete this._sucs[t],--this._nodeCount}return this}setParent(t,e){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(f.A(e))e=P;else{for(var r=e+="";!f.A(r);r=this.parent(r))if(r===t)throw new Error("Setting "+e+" as parent of "+t+" would create a cycle");this.setNode(e)}return this.setNode(t),this._removeFromParentsChildList(t),this._parent[t]=e,this._children[e][t]=!0,this}_removeFromParentsChildList(t){delete this._children[this._parent[t]][t]}parent(t){if(this._isCompound){var e=this._parent[t];if(e!==P)return e}}children(t){if(f.A(t)&&(t=P),this._isCompound){var e=this._children[t];if(e)return s.A(e)}else{if(t===P)return this.nodes();if(this.hasNode(t))return[]}}predecessors(t){var e=this._preds[t];if(e)return s.A(e)}successors(t){var e=this._sucs[t];if(e)return s.A(e)}neighbors(t){var e=this.predecessors(t);if(e)return N(e,this.successors(t))}isLeaf(t){return 0===(this.isDirected()?this.successors(t):this.neighbors(t)).length}filterNodes(t){var e=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});e.setGraph(this.graph());var r=this;a.A(this._nodes,(function(r,n){t(n)&&e.setNode(n,r)})),a.A(this._edgeObjs,(function(t){e.hasNode(t.v)&&e.hasNode(t.w)&&e.setEdge(t,r.edge(t))}));var n={};function o(t){var i=r.parent(t);return void 0===i||e.hasNode(i)?(n[t]=i,i):i in n?n[i]:o(i)}return this._isCompound&&a.A(e.nodes(),(function(t){e.setParent(t,o(t))})),e}setDefaultEdgeLabel(t){return i.A(t)||(t=o.A(t)),this._defaultEdgeLabelFn=t,this}edgeCount(){return this._edgeCount}edges(){return D.A(this._edgeObjs)}setPath(t,e){var r=this,n=arguments;return S.A(t,(function(t,o){return n.length>1?r.setEdge(t,o,e):r.setEdge(t,o),o})),this}setEdge(){var t,e,r,o,i=!1,s=arguments[0];"object"==typeof s&&null!==s&&"v"in s?(t=s.v,e=s.w,r=s.name,2===arguments.length&&(o=arguments[1],i=!0)):(t=s,e=arguments[1],r=arguments[3],arguments.length>2&&(o=arguments[2],i=!0)),t=""+t,e=""+e,f.A(r)||(r=""+r);var u=U(this._isDirected,t,e,r);if(n.A(this._edgeLabels,u))return i&&(this._edgeLabels[u]=o),this;if(!f.A(r)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(t),this.setNode(e),this._edgeLabels[u]=i?o:this._defaultEdgeLabelFn(t,e,r);var c=function(t,e,r,n){var o=""+e,i=""+r;if(!t&&o>i){var s=o;o=i,i=s}var u={v:o,w:i};n&&(u.name=n);return u}(this._isDirected,t,e,r);return t=c.v,e=c.w,Object.freeze(c),this._edgeObjs[u]=c,x(this._preds[e],t),x(this._sucs[t],e),this._in[e][u]=c,this._out[t][u]=c,this._edgeCount++,this}edge(t,e,r){var n=1===arguments.length?z(this._isDirected,arguments[0]):U(this._isDirected,t,e,r);return this._edgeLabels[n]}hasEdge(t,e,r){var o=1===arguments.length?z(this._isDirected,arguments[0]):U(this._isDirected,t,e,r);return n.A(this._edgeLabels,o)}removeEdge(t,e,r){var n=1===arguments.length?z(this._isDirected,arguments[0]):U(this._isDirected,t,e,r),o=this._edgeObjs[n];return o&&(t=o.v,e=o.w,delete this._edgeLabels[n],delete this._edgeObjs[n],I(this._preds[e],t),I(this._sucs[t],e),delete this._in[e][n],delete this._out[t][n],this._edgeCount--),this}inEdges(t,e){var r=this._in[t];if(r){var n=D.A(r);return e?u.A(n,(function(t){return t.v===e})):n}}outEdges(t,e){var r=this._out[t];if(r){var n=D.A(r);return e?u.A(n,(function(t){return t.w===e})):n}}nodeEdges(t,e){var r=this.inEdges(t,e);if(r)return r.concat(this.outEdges(t,e))}}function x(t,e){t[e]?t[e]++:t[e]=1}function I(t,e){--t[e]||delete t[e]}function U(t,e,r,n){var o=""+e,i=""+r;if(!t&&o>i){var s=o;o=i,i=s}return o+M+i+M+(f.A(n)?F:n)}function z(t,e){return U(t,e.v,e.w,e.name)}k.prototype._nodeCount=0,k.prototype._edgeCount=0},697:(t,e,r)=>{r.d(e,{T:()=>n.T});var n=r(73046)},62062:(t,e,r)=>{r.d(e,{A:()=>u});var n=r(29471);const o=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this};const i=function(t){return this.__data__.has(t)};function s(t){var e=-1,r=null==t?0:t.length;for(this.__data__=new n.A;++e<r;)this.add(t[e])}s.prototype.add=s.prototype.push=o,s.prototype.has=i;const u=s},72641:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(t,e){for(var r=-1,n=null==t?0:t.length;++r<n&&!1!==e(t[r],r,t););return t}},2634:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(t,e){for(var r=-1,n=null==t?0:t.length,o=0,i=[];++r<n;){var s=t[r];e(s,r,t)&&(i[o++]=s)}return i}},45572:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(t,e){for(var r=-1,n=null==t?0:t.length,o=Array(n);++r<n;)o[r]=e(t[r],r,t);return o}},76912:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(t,e){for(var r=-1,n=e.length,o=t.length;++r<n;)t[o+r]=e[r];return t}},91641:(t,e,r)=>{r.d(e,{A:()=>Z});var n=r(11754),o=r(72641),i=r(52851),s=r(22031),u=r(27422);const c=function(t,e){return t&&(0,s.A)(e,(0,u.A)(e),t)};var a=r(55615);const f=function(t,e){return t&&(0,s.A)(e,(0,a.A)(e),t)};var h=r(80154),A=r(39759),d=r(14792);const l=function(t,e){return(0,s.A)(t,(0,d.A)(t),e)};var v=r(76912),b=r(15647),_=r(13153);const p=Object.getOwnPropertySymbols?function(t){for(var e=[];t;)(0,v.A)(e,(0,d.A)(t)),t=(0,b.A)(t);return e}:_.A;const g=function(t,e){return(0,s.A)(t,p(t),e)};var j=r(19042),y=r(33831);const m=function(t){return(0,y.A)(t,a.A,p)};var w=r(9779),O=Object.prototype.hasOwnProperty;const C=function(t){var e=t.length,r=new t.constructor(e);return e&&"string"==typeof t[0]&&O.call(t,"index")&&(r.index=t.index,r.input=t.input),r};var E=r(90565);const L=function(t,e){var r=e?(0,E.A)(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.byteLength)};var N=/\w*$/;const D=function(t){var e=new t.constructor(t.source,N.exec(t));return e.lastIndex=t.lastIndex,e};var S=r(241),F=S.A?S.A.prototype:void 0,P=F?F.valueOf:void 0;const M=function(t){return P?Object(P.call(t)):{}};var k=r(1801);const x=function(t,e,r){var n=t.constructor;switch(e){case"[object ArrayBuffer]":return(0,E.A)(t);case"[object Boolean]":case"[object Date]":return new n(+t);case"[object DataView]":return L(t,r);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return(0,k.A)(t,r);case"[object Map]":case"[object Set]":return new n;case"[object Number]":case"[object String]":return new n(t);case"[object RegExp]":return D(t);case"[object Symbol]":return M(t)}};var I=r(18598),U=r(92049),z=r(99912),B=r(53098);const $=function(t){return(0,B.A)(t)&&"[object Map]"==(0,w.A)(t)};var G=r(52789),R=r(64841),T=R.A&&R.A.isMap;const V=T?(0,G.A)(T):$;var W=r(23149);const q=function(t){return(0,B.A)(t)&&"[object Set]"==(0,w.A)(t)};var H=R.A&&R.A.isSet;const J=H?(0,G.A)(H):q;var K="[object Arguments]",Q="[object Function]",X="[object Object]",Y={};Y[K]=Y["[object Array]"]=Y["[object ArrayBuffer]"]=Y["[object DataView]"]=Y["[object Boolean]"]=Y["[object Date]"]=Y["[object Float32Array]"]=Y["[object Float64Array]"]=Y["[object Int8Array]"]=Y["[object Int16Array]"]=Y["[object Int32Array]"]=Y["[object Map]"]=Y["[object Number]"]=Y[X]=Y["[object RegExp]"]=Y["[object Set]"]=Y["[object String]"]=Y["[object Symbol]"]=Y["[object Uint8Array]"]=Y["[object Uint8ClampedArray]"]=Y["[object Uint16Array]"]=Y["[object Uint32Array]"]=!0,Y["[object Error]"]=Y[Q]=Y["[object WeakMap]"]=!1;const Z=function t(e,r,s,d,v,b){var _,p=1&r,y=2&r,O=4&r;if(s&&(_=v?s(e,d,v,b):s(e)),void 0!==_)return _;if(!(0,W.A)(e))return e;var E=(0,U.A)(e);if(E){if(_=C(e),!p)return(0,A.A)(e,_)}else{var L=(0,w.A)(e),N=L==Q||"[object GeneratorFunction]"==L;if((0,z.A)(e))return(0,h.A)(e,p);if(L==X||L==K||N&&!v){if(_=y||N?{}:(0,I.A)(e),!p)return y?g(e,f(_,e)):l(e,c(_,e))}else{if(!Y[L])return v?e:{};_=x(e,L,p)}}b||(b=new n.A);var D=b.get(e);if(D)return D;b.set(e,_),J(e)?e.forEach((function(n){_.add(t(n,r,s,n,e,b))})):V(e)&&e.forEach((function(n,o){_.set(o,t(n,r,s,o,e,b))}));var S=O?y?m:j.A:y?a.A:u.A,F=E?void 0:S(e);return(0,o.A)(F||e,(function(n,o){F&&(n=e[o=n]),(0,i.A)(_,o,t(n,r,s,o,e,b))})),_}},6240:(t,e,r)=>{r.d(e,{A:()=>i});var n=r(79841),o=r(38446);const i=function(t,e){return function(r,n){if(null==r)return r;if(!(0,o.A)(r))return t(r,n);for(var i=r.length,s=e?i:-1,u=Object(r);(e?s--:++s<i)&&!1!==n(u[s],s,u););return r}}(n.A)},25707:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(t,e,r,n){for(var o=t.length,i=r+(n?1:-1);n?i--:++i<o;)if(e(t[i],i,t))return i;return-1}},13588:(t,e,r)=>{r.d(e,{A:()=>a});var n=r(76912),o=r(241),i=r(52274),s=r(92049),u=o.A?o.A.isConcatSpreadable:void 0;const c=function(t){return(0,s.A)(t)||(0,i.A)(t)||!!(u&&t&&t[u])};const a=function t(e,r,o,i,s){var u=-1,a=e.length;for(o||(o=c),s||(s=[]);++u<a;){var f=e[u];r>0&&o(f)?r>1?t(f,r-1,o,i,s):(0,n.A)(s,f):i||(s[s.length]=f)}return s}},79841:(t,e,r)=>{r.d(e,{A:()=>i});var n=r(4574),o=r(27422);const i=function(t,e){return t&&(0,n.A)(t,e,o.A)}},66318:(t,e,r)=>{r.d(e,{A:()=>i});var n=r(7819),o=r(30901);const i=function(t,e){for(var r=0,i=(e=(0,n.A)(e,t)).length;null!=t&&r<i;)t=t[(0,o.A)(e[r++])];return r&&r==i?t:void 0}},33831:(t,e,r)=>{r.d(e,{A:()=>i});var n=r(76912),o=r(92049);const i=function(t,e,r){var i=e(t);return(0,o.A)(t)?i:(0,n.A)(i,r(t))}},49574:(t,e,r)=>{r.d(e,{A:()=>H});var n=r(11754),o=r(62062);const i=function(t,e){for(var r=-1,n=null==t?0:t.length;++r<n;)if(e(t[r],r,t))return!0;return!1};var s=r(64099);const u=function(t,e,r,n,u,c){var a=1&r,f=t.length,h=e.length;if(f!=h&&!(a&&h>f))return!1;var A=c.get(t),d=c.get(e);if(A&&d)return A==e&&d==t;var l=-1,v=!0,b=2&r?new o.A:void 0;for(c.set(t,e),c.set(e,t);++l<f;){var _=t[l],p=e[l];if(n)var g=a?n(p,_,l,e,t,c):n(_,p,l,t,e,c);if(void 0!==g){if(g)continue;v=!1;break}if(b){if(!i(e,(function(t,e){if(!(0,s.A)(b,e)&&(_===t||u(_,t,r,n,c)))return b.push(e)}))){v=!1;break}}else if(_!==p&&!u(_,p,r,n,c)){v=!1;break}}return c.delete(t),c.delete(e),v};var c=r(241),a=r(43988),f=r(66984);const h=function(t){var e=-1,r=Array(t.size);return t.forEach((function(t,n){r[++e]=[n,t]})),r};var A=r(29959),d=c.A?c.A.prototype:void 0,l=d?d.valueOf:void 0;const v=function(t,e,r,n,o,i,s){switch(r){case"[object DataView]":if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)return!1;t=t.buffer,e=e.buffer;case"[object ArrayBuffer]":return!(t.byteLength!=e.byteLength||!i(new a.A(t),new a.A(e)));case"[object Boolean]":case"[object Date]":case"[object Number]":return(0,f.A)(+t,+e);case"[object Error]":return t.name==e.name&&t.message==e.message;case"[object RegExp]":case"[object String]":return t==e+"";case"[object Map]":var c=h;case"[object Set]":var d=1&n;if(c||(c=A.A),t.size!=e.size&&!d)return!1;var v=s.get(t);if(v)return v==e;n|=2,s.set(t,e);var b=u(c(t),c(e),n,o,i,s);return s.delete(t),b;case"[object Symbol]":if(l)return l.call(t)==l.call(e)}return!1};var b=r(19042),_=Object.prototype.hasOwnProperty;const p=function(t,e,r,n,o,i){var s=1&r,u=(0,b.A)(t),c=u.length;if(c!=(0,b.A)(e).length&&!s)return!1;for(var a=c;a--;){var f=u[a];if(!(s?f in e:_.call(e,f)))return!1}var h=i.get(t),A=i.get(e);if(h&&A)return h==e&&A==t;var d=!0;i.set(t,e),i.set(e,t);for(var l=s;++a<c;){var v=t[f=u[a]],p=e[f];if(n)var g=s?n(p,v,f,e,t,i):n(v,p,f,t,e,i);if(!(void 0===g?v===p||o(v,p,r,n,i):g)){d=!1;break}l||(l="constructor"==f)}if(d&&!l){var j=t.constructor,y=e.constructor;j==y||!("constructor"in t)||!("constructor"in e)||"function"==typeof j&&j instanceof j&&"function"==typeof y&&y instanceof y||(d=!1)}return i.delete(t),i.delete(e),d};var g=r(9779),j=r(92049),y=r(99912),m=r(33858),w="[object Arguments]",O="[object Array]",C="[object Object]",E=Object.prototype.hasOwnProperty;const L=function(t,e,r,o,i,s){var c=(0,j.A)(t),a=(0,j.A)(e),f=c?O:(0,g.A)(t),h=a?O:(0,g.A)(e),A=(f=f==w?C:f)==C,d=(h=h==w?C:h)==C,l=f==h;if(l&&(0,y.A)(t)){if(!(0,y.A)(e))return!1;c=!0,A=!1}if(l&&!A)return s||(s=new n.A),c||(0,m.A)(t)?u(t,e,r,o,i,s):v(t,e,f,r,o,i,s);if(!(1&r)){var b=A&&E.call(t,"__wrapped__"),_=d&&E.call(e,"__wrapped__");if(b||_){var L=b?t.value():t,N=_?e.value():e;return s||(s=new n.A),i(L,N,r,o,s)}}return!!l&&(s||(s=new n.A),p(t,e,r,o,i,s))};var N=r(53098);const D=function t(e,r,n,o,i){return e===r||(null==e||null==r||!(0,N.A)(e)&&!(0,N.A)(r)?e!=e&&r!=r:L(e,r,n,o,t,i))};const S=function(t,e,r,o){var i=r.length,s=i,u=!o;if(null==t)return!s;for(t=Object(t);i--;){var c=r[i];if(u&&c[2]?c[1]!==t[c[0]]:!(c[0]in t))return!1}for(;++i<s;){var a=(c=r[i])[0],f=t[a],h=c[1];if(u&&c[2]){if(void 0===f&&!(a in t))return!1}else{var A=new n.A;if(o)var d=o(f,h,a,t,e,A);if(!(void 0===d?D(h,f,3,o,A):d))return!1}}return!0};var F=r(23149);const P=function(t){return t==t&&!(0,F.A)(t)};var M=r(27422);const k=function(t){for(var e=(0,M.A)(t),r=e.length;r--;){var n=e[r],o=t[n];e[r]=[n,o,P(o)]}return e};const x=function(t,e){return function(r){return null!=r&&(r[t]===e&&(void 0!==e||t in Object(r)))}};const I=function(t){var e=k(t);return 1==e.length&&e[0][2]?x(e[0][0],e[0][1]):function(r){return r===t||S(r,t,e)}};var U=r(66318);const z=function(t,e,r){var n=null==t?void 0:(0,U.A)(t,e);return void 0===n?r:n};var B=r(39188),$=r(86586),G=r(30901);const R=function(t,e){return(0,$.A)(t)&&P(e)?x((0,G.A)(t),e):function(r){var n=z(r,t);return void 0===n&&n===e?(0,B.A)(r,t):D(e,n,3)}};var T=r(29008),V=r(70805);const W=function(t){return function(e){return(0,U.A)(e,t)}};const q=function(t){return(0,$.A)(t)?(0,V.A)((0,G.A)(t)):W(t)};const H=function(t){return"function"==typeof t?t:null==t?T.A:"object"==typeof t?(0,j.A)(t)?R(t[0],t[1]):I(t):q(t)}},70805:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(t){return function(e){return null==e?void 0:e[t]}}},64099:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(t,e){return t.has(e)}},99922:(t,e,r)=>{r.d(e,{A:()=>o});var n=r(29008);const o=function(t){return"function"==typeof t?t:n.A}},7819:(t,e,r)=>{r.d(e,{A:()=>f});var n=r(92049),o=r(86586),i=r(46632);var s=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,u=/\\(\\)?/g;const c=function(t){var e=(0,i.A)(t,(function(t){return 500===r.size&&r.clear(),t})),r=e.cache;return e}((function(t){var e=[];return 46===t.charCodeAt(0)&&e.push(""),t.replace(s,(function(t,r,n,o){e.push(n?o.replace(u,"$1"):r||t)})),e}));var a=r(28894);const f=function(t,e){return(0,n.A)(t)?t:(0,o.A)(t,e)?[t]:c((0,a.A)(t))}},19042:(t,e,r)=>{r.d(e,{A:()=>s});var n=r(33831),o=r(14792),i=r(27422);const s=function(t){return(0,n.A)(t,i.A,o.A)}},14792:(t,e,r)=>{r.d(e,{A:()=>u});var n=r(2634),o=r(13153),i=Object.prototype.propertyIsEnumerable,s=Object.getOwnPropertySymbols;const u=s?function(t){return null==t?[]:(t=Object(t),(0,n.A)(s(t),(function(e){return i.call(t,e)})))}:o.A},85054:(t,e,r)=>{r.d(e,{A:()=>a});var n=r(7819),o=r(52274),i=r(92049),s=r(25353),u=r(5254),c=r(30901);const a=function(t,e,r){for(var a=-1,f=(e=(0,n.A)(e,t)).length,h=!1;++a<f;){var A=(0,c.A)(e[a]);if(!(h=null!=t&&r(t,A)))break;t=t[A]}return h||++a!=f?h:!!(f=null==t?0:t.length)&&(0,u.A)(f)&&(0,s.A)(A,f)&&((0,i.A)(t)||(0,o.A)(t))}},86586:(t,e,r)=>{r.d(e,{A:()=>u});var n=r(92049),o=r(61882),i=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,s=/^\w*$/;const u=function(t,e){if((0,n.A)(t))return!1;var r=typeof t;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=t&&!(0,o.A)(t))||(s.test(t)||!i.test(t)||null!=e&&t in Object(e))}},29959:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(t){var e=-1,r=Array(t.size);return t.forEach((function(t){r[++e]=t})),r}},30901:(t,e,r)=>{r.d(e,{A:()=>o});var n=r(61882);const o=function(t){if("string"==typeof t||(0,n.A)(t))return t;var e=t+"";return"0"==e&&1/t==-1/0?"-0":e}},11662:(t,e,r)=>{r.d(e,{A:()=>c});var n=r(2634),o=r(6240);const i=function(t,e){var r=[];return(0,o.A)(t,(function(t,n,o){e(t,n,o)&&r.push(t)})),r};var s=r(49574),u=r(92049);const c=function(t,e){return((0,u.A)(t)?n.A:i)(t,(0,s.A)(e,3))}},8058:(t,e,r)=>{r.d(e,{A:()=>u});var n=r(72641),o=r(6240),i=r(99922),s=r(92049);const u=function(t,e){return((0,s.A)(t)?n.A:o.A)(t,(0,i.A)(e))}},48585:(t,e,r)=>{r.d(e,{A:()=>s});var n=Object.prototype.hasOwnProperty;const o=function(t,e){return null!=t&&n.call(t,e)};var i=r(85054);const s=function(t,e){return null!=t&&(0,i.A)(t,e,o)}},39188:(t,e,r)=>{r.d(e,{A:()=>i});const n=function(t,e){return null!=t&&e in Object(t)};var o=r(85054);const i=function(t,e){return null!=t&&(0,o.A)(t,e,n)}},61882:(t,e,r)=>{r.d(e,{A:()=>i});var n=r(88496),o=r(53098);const i=function(t){return"symbol"==typeof t||(0,o.A)(t)&&"[object Symbol]"==(0,n.A)(t)}},69592:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(t){return void 0===t}},27422:(t,e,r)=>{r.d(e,{A:()=>s});var n=r(83607),o=r(69471),i=r(38446);const s=function(t){return(0,i.A)(t)?(0,n.A)(t):(0,o.A)(t)}},89463:(t,e,r)=>{r.d(e,{A:()=>c});const n=function(t,e,r,n){var o=-1,i=null==t?0:t.length;for(n&&i&&(r=t[++o]);++o<i;)r=e(r,t[o],o,t);return r};var o=r(6240),i=r(49574);const s=function(t,e,r,n,o){return o(t,(function(t,o,i){r=n?(n=!1,t):e(r,t,o,i)})),r};var u=r(92049);const c=function(t,e,r){var c=(0,u.A)(t)?n:s,a=arguments.length<3;return c(t,(0,i.A)(e,4),r,a,o.A)}},13153:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(){return[]}},28894:(t,e,r)=>{r.d(e,{A:()=>f});var n=r(241),o=r(45572),i=r(92049),s=r(61882),u=n.A?n.A.prototype:void 0,c=u?u.toString:void 0;const a=function t(e){if("string"==typeof e)return e;if((0,i.A)(e))return(0,o.A)(e,t)+"";if((0,s.A)(e))return c?c.call(e):"";var r=e+"";return"0"==r&&1/e==-1/0?"-0":r};const f=function(t){return null==t?"":a(t)}},38207:(t,e,r)=>{r.d(e,{A:()=>s});var n=r(45572);const o=function(t,e){return(0,n.A)(e,(function(e){return t[e]}))};var i=r(27422);const s=function(t){return null==t?[]:o(t,(0,i.A)(t))}}}]); \ No newline at end of file diff --git a/assets/js/5199876b.b6ef7c5d.js b/assets/js/5199876b.b6ef7c5d.js new file mode 100644 index 0000000000..b22011df1e --- /dev/null +++ b/assets/js/5199876b.b6ef7c5d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[23008],{83629:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>r,contentTitle:()=>d,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"iaas/guides/operations-guide/manager/get","title":"Get","description":"A get command is available in the OSISM CLI. This allows to gather specific information.","source":"@site/docs/02-iaas/guides/operations-guide/manager/get.md","sourceDirName":"02-iaas/guides/operations-guide/manager","slug":"/iaas/guides/operations-guide/manager/get","permalink":"/docs/iaas/guides/operations-guide/manager/get","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/manager/get.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Get"},"sidebar":"docs","previous":{"title":"Console","permalink":"/docs/iaas/guides/operations-guide/manager/console"},"next":{"title":"Logging","permalink":"/docs/iaas/guides/operations-guide/manager/log"}}');var i=n(74848),o=n(28453);const a={sidebar_label:"Get"},d="Get",r={},c=[{value:"Hosts",id:"hosts",level:2},{value:"Host variables",id:"host-variables",level:2},{value:"Host facts",id:"host-facts",level:2}];function l(e){const s={code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"get",children:"Get"})}),"\n",(0,i.jsxs)(s.p,{children:["A ",(0,i.jsx)(s.code,{children:"get"})," command is available in the OSISM CLI. This allows to gather specific information."]}),"\n",(0,i.jsx)(s.h2,{id:"hosts",children:"Hosts"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Get all hosts defined in the inventory"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"$ osism get hosts\n+-----------------------------------+\n| Host |\n|-----------------------------------|\n| testbed-manager.testbed.osism.xyz |\n| testbed-node-0.testbed.osism.xyz |\n| testbed-node-1.testbed.osism.xyz |\n| testbed-node-2.testbed.osism.xyz |\n+-----------------------------------+\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Get all hosts defined in the inventory that are member of a specific inventory group"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"$ osism get hosts -l manager\n+-----------------------------------+\n| Host |\n|-----------------------------------|\n| testbed-manager.testbed.osism.xyz |\n+-----------------------------------+\n\n$ osism get hosts -l control\n+----------------------------------+\n| Host |\n|----------------------------------|\n| testbed-node-0.testbed.osism.xyz |\n| testbed-node-1.testbed.osism.xyz |\n| testbed-node-2.testbed.osism.xyz |\n+----------------------------------+\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"host-variables",children:"Host variables"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Get all host vars of a specific node"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism get hostvars testbed-manager.testbed.osism.xyz\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Get a specific host var of a specific node"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"$ osism get hostvars testbed-manager.testbed.osism.xyz ansible_host\n+-----------------------------------+--------------+----------------+\n| Host | Variable | Value |\n+===================================+==============+================+\n| testbed-manager.testbed.osism.xyz | ansible_host | '192.168.16.5' |\n+-----------------------------------+--------------+----------------+\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"host-facts",children:"Host facts"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Get all facts of a specific node"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism get facts testbed-manager.testbed.osism.xyz\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Get a specific fact of a specific node"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"$ osism get facts testbed-manager.testbed.osism.xyz ansible_architecture\n+-----------------------------------+----------------------+----------+\n| Host | Fact | Value |\n+===================================+======================+==========+\n| testbed-manager.testbed.osism.xyz | ansible_architecture | 'x86_64' |\n+-----------------------------------+----------------------+----------+\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>d});var t=n(96540);const i={},o=t.createContext(i);function a(e){const s=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5201921d.508dd58e.js b/assets/js/5201921d.508dd58e.js new file mode 100644 index 0000000000..794cfe47d7 --- /dev/null +++ b/assets/js/5201921d.508dd58e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[95369],{25312:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Components","slug":"/category/components-1","permalink":"/docs/category/components-1","sidebar":"docs","navigation":{"previous":{"title":"Container Layer Introduction","permalink":"/docs/container/"},"next":{"title":"Cluster Stacks","permalink":"/docs/category/cluster-stacks"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/526893f8.2f4ff1f6.js b/assets/js/526893f8.2f4ff1f6.js new file mode 100644 index 0000000000..0c427b9350 --- /dev/null +++ b/assets/js/526893f8.2f4ff1f6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[82346],{1981:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"iaas/guides/user-guide/openstack/openstackclient","title":"Client","description":"OpenStackClient looks for a clouds.yaml configuration file in the following locations:","source":"@site/docs/02-iaas/guides/user-guide/openstack/openstackclient.md","sourceDirName":"02-iaas/guides/user-guide/openstack","slug":"/iaas/guides/user-guide/openstack/openstackclient","permalink":"/docs/iaas/guides/user-guide/openstack/openstackclient","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/openstack/openstackclient.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Client"},"sidebar":"docs","previous":{"title":"Install instance from ISO image","permalink":"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso"},"next":{"title":"Security groups","permalink":"/docs/iaas/guides/user-guide/openstack/security-groups"}}');var s=o(74848),i=o(28453);const r={sidebar_label:"Client"},a="Client",c={},l=[{value:"Migration from openrc to clouds.yaml",id:"migration-from-openrc-to-cloudsyaml",level:2},{value:"With an editor",id:"with-an-editor",level:2},{value:"With a script",id:"with-a-script",level:2},{value:"Python",id:"python",level:3},{value:"Bash",id:"bash",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"client",children:"Client"})}),"\n",(0,s.jsxs)(n.p,{children:["OpenStackClient looks for a ",(0,s.jsx)(n.code,{children:"clouds.yaml"})," configuration file in the following locations:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"current directory"}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"~/.config/openstack"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"/etc/openstack"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["With the OpenStack client you can specify the cloud profile specified in the ",(0,s.jsx)(n.code,{children:"clouds.yaml"}),"\nconfiguration file by providing the ",(0,s.jsx)(n.code,{children:"--os-cloud <cloud identifier>"})," parameter."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack --os-cloud openstack network list\n"})}),"\n",(0,s.jsx)(n.h2,{id:"migration-from-openrc-to-cloudsyaml",children:"Migration from openrc to clouds.yaml"}),"\n",(0,s.jsxs)(n.p,{children:["If you have your ",(0,s.jsx)(n.code,{children:"openrc"})," file but you need this information in a ",(0,s.jsx)(n.code,{children:"clouds.yaml"})," file,\nthis can easily be converted."]}),"\n",(0,s.jsx)(n.h2,{id:"with-an-editor",children:"With an editor"}),"\n",(0,s.jsxs)(n.p,{children:["Example content of a ",(0,s.jsx)(n.code,{children:"openrc"})," file downloaded from Horizon dashboard."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",metastring:'title="PROJECT-openrc.sh"',children:'#!/usr/bin/env bash\n# To use an OpenStack cloud you need to authenticate against the Identity\n# service named keystone, which returns a **Token** and **Service Catalog**.\n# The catalog contains the endpoints for all services the user/tenant has\n# access to - such as Compute, Image Service, Identity, Object Storage, Block\n# Storage, and Networking (code-named nova, glance, keystone, swift,\n# cinder, and neutron).\n#\n# *NOTE*: Using the 3 *Identity API* does not necessarily mean any other\n# OpenStack API is version 3. For example, your cloud provider may implement\n# Image API v1.1, Block Storage API v2, and Compute API v2.0. OS_AUTH_URL is\n# only for the Identity API served through keystone.\nexport OS_AUTH_URL=https://api.testbed.osism.xyz:5000/v3\n# With the addition of Keystone we have standardized on the term **project**\n# as the entity that owns the resources.\nexport OS_PROJECT_ID=PROJECT_ID\nexport OS_PROJECT_NAME="PROJECT"\nexport OS_USER_DOMAIN_NAME="DOMAIN"\nif [ -z "$OS_USER_DOMAIN_NAME" ]; then unset OS_USER_DOMAIN_NAME; fi\nexport OS_PROJECT_DOMAIN_ID="DOMAIN_ID"\nif [ -z "$OS_PROJECT_DOMAIN_ID" ]; then unset OS_PROJECT_DOMAIN_ID; fi\n# unset v2.0 items in case set\nunset OS_TENANT_ID\nunset OS_TENANT_NAME\n# In addition to the owning entity (tenant), OpenStack stores the entity\n# performing the action as the **user**.\nexport OS_USERNAME="USERNAME"\n# With Keystone you pass the keystone password.\necho "Please enter your OpenStack Password for project $OS_PROJECT_NAME as user $OS_USERNAME: "\nread -sr OS_PASSWORD_INPUT\nexport OS_PASSWORD=$OS_PASSWORD_INPUT\n# If your configuration has multiple regions, we set that information here.\n# OS_REGION_NAME is optional and only valid in certain environments.\nexport OS_REGION_NAME="RegionOne"\n# Don\'t leave a blank variable, unset it if it was empty\nif [ -z "$OS_REGION_NAME" ]; then unset OS_REGION_NAME; fi\nexport OS_INTERFACE=public\nexport OS_IDENTITY_API_VERSION=3\n'})}),"\n",(0,s.jsxs)(n.p,{children:["First you need to create a ",(0,s.jsx)(n.code,{children:"clouds.yaml"})," file. Take care of the indentation and\nuse spaces instead of tabs."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="clouds.yaml"',children:"clouds:\n openstack:\n auth:\n auth_url: <OS_AUTH_URL goes here>\n password: <OS_PASSWORD goes here, if not set, enter you password here>\n project_domain_name: <OS_PROJECT_DOMAIN_NAME goes here>\n project_name: <OS_PROJECT_NAME goes here>\n user_domain_name: <OS_USER_DOMAIN_NAME goes here>\n username: <OS_USERNAME goes here>\n region_name: <OS_REGION_NAME goes here>\n identity_api_version: <OS_IDENTITY_API_VERSION goes here>\n interface: <OS_INTERFACE goes here>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The final ",(0,s.jsx)(n.code,{children:"clouds.yaml"})," for your ",(0,s.jsx)(n.code,{children:"openrc"})," will then look like this one. The content\nfrom the previous ",(0,s.jsx)(n.code,{children:"PROJECT-openrc.sh"})," example was used here."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="clouds.yaml"',children:"clouds:\n openstack:\n auth:\n auth_url: https://api.testbed.osism.xyz:5000/v3\n password: PASSWORD\n project_domain_name: DOMAIN\n project_name: PROJECT\n user_domain_name: DOMAIN\n username: USERNAME\n region_name: RegionOne\n identity_api_version: 3\n interface: public\n"})}),"\n",(0,s.jsx)(n.h2,{id:"with-a-script",children:"With a script"}),"\n",(0,s.jsx)(n.h3,{id:"python",children:"Python"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",metastring:'title="clouds.py"',children:'import os\nimport yaml\n\nclouds = {\n "clouds":{\n "openstack": {\n "auth" : {\n "auth_url" : os.environ["OS_AUTH_URL"],\n "project_name": os.environ["OS_PROJECT_NAME"],\n "project_domain_name": os.environ["OS_PROJECT_DOMAIN_NAME"],\n "username": os.environ["OS_USERNAME"],\n "user_domain_name": os.environ["OS_USER_DOMAIN_NAME"],\n "password": os.environ["OS_PASSWORD"],\n },\n "region_name": os.environ["OS_REGION_NAME"],\n "identity_api_version": os.environ["OS_IDENTITY_API_VERSION"],\n "interface": "public"\n }\n }\n}\n\nprint(yaml.dump(clouds))\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Source: ",(0,s.jsx)(n.a,{href:"https://adam.younglogic.com/2022/03/generating-a-clouds-yaml-file",children:"Adam Young's Web Log"})]}),"\n",(0,s.jsxs)(n.p,{children:["First you need to source your ",(0,s.jsx)(n.code,{children:"openrc"})," file so that the ",(0,s.jsx)(n.code,{children:"OS_"})," variables are available."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"source PROJECT-openrc.sh\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Now you can execute the Python script and a ",(0,s.jsx)(n.code,{children:"clouds.yaml"})," will be written."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"python3 clouds.py > clouds.yaml\n"})}),"\n",(0,s.jsx)(n.h3,{id:"bash",children:"Bash"}),"\n",(0,s.jsxs)(n.p,{children:["You need to point the ",(0,s.jsx)(n.code,{children:"source"})," line to your ",(0,s.jsx)(n.code,{children:"openrc"})," file first. Then execute the Bash script.\nThis will create the ",(0,s.jsx)(n.code,{children:"clouds.yaml"})," file in your currect directory"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'#!/bin/bash\n\nsource PROJECT-openrc.sh\n\nPROJECT_ID=$(openstack project list | grep $OS_PROJECT_NAME | awk \'{print $2}\')\n\ncat << EOF > clouds.yaml\nclouds:\n openstack:\n auth:\n auth_url: $OS_AUTH_URL\n username: "$OS_USERNAME"\n password: "$OS_PASSWORD"\n project_name: "$OS_PROJECT_NAME"\n project_id: "$PROJECT_ID"\n user_domain_name: "$OS_USER_DOMAIN_NAME"\n region_name: "$OS_REGION_NAME"\n interface: "public"\n identity_api_version: $OS_IDENTITY_API_VERSION\nEOF\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Source: ",(0,s.jsx)(n.a,{href:"https://andreaskaris.github.io/blog/openstack/using_clouds_yaml",children:"Andreas Karis Blog"})]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>r,x:()=>a});var t=o(96540);const s={},i=t.createContext(s);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/526992cf.5d92f843.js b/assets/js/526992cf.5d92f843.js new file mode 100644 index 0000000000..4130da99d5 --- /dev/null +++ b/assets/js/526992cf.5d92f843.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[81475],{56815:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>c});const d=JSON.parse('{"id":"scs-0103-v1-standard-flavors","title":"SCS Standard Flavors and Properties","description":"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack\\nenvironments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific\\nconfigurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs:name-vN, scs:cpu-type,\\nand scs:diskN-type to detail the flavor\'s specifications. This standard facilitates guaranteed availability and\\nconsistency of flavors, simplifying the deployment process for DevOps teams.\\n","source":"@site/standards/scs-0103-v1-standard-flavors.md","sourceDirName":".","slug":"/scs-0103-v1-standard-flavors","permalink":"/standards/scs-0103-v1-standard-flavors","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Standard Flavors and Properties","type":"Standard","status":"Stable","stabilized_at":"2024-02-08T00:00:00.000Z","track":"IaaS","description":"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack\\nenvironments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific\\nconfigurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs:name-vN, scs:cpu-type,\\nand scs:diskN-type to detail the flavor\'s specifications. This standard facilitates guaranteed availability and\\nconsistency of flavors, simplifying the deployment process for DevOps teams.\\n"},"sidebar":"standards","previous":{"title":"scs-0103: SCS Standard Flavors and Properties","permalink":"/standards/iaas/scs-0103"},"next":{"title":"scs-0104: SCS Standard Images","permalink":"/standards/iaas/scs-0104"}}');var r=n(74848),t=n(28453);const i={title:"SCS Standard Flavors and Properties",type:"Standard",status:"Stable",stabilized_at:new Date("2024-02-08T00:00:00.000Z"),track:"IaaS",description:"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack\nenvironments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific\nconfigurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs:name-vN, scs:cpu-type,\nand scs:diskN-type to detail the flavor's specifications. This standard facilitates guaranteed availability and\nconsistency of flavors, simplifying the deployment process for DevOps teams.\n"},a=void 0,o={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Properties (extra_specs)",id:"properties-extra_specs",level:2},{value:"Standard SCS flavors",id:"standard-scs-flavors",level:2},{value:"Mandatory",id:"mandatory",level:3},{value:"Recommended",id:"recommended",level:3},{value:"Guarantees and properties",id:"guarantees-and-properties",level:3},{value:"Remarks",id:"remarks",level:3},{value:"Conformance Tests",id:"conformance-tests",level:2},{value:"Operational tooling",id:"operational-tooling",level:2},{value:"Previous standard versions",id:"previous-standard-versions",level:2}];function l(e){const s={a:"a",code:"code",div:"div",em:"em",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsxs)(s.p,{children:["This is v1.1 of the standard, which lifts the following restriction regarding the property ",(0,r.jsx)(s.code,{children:"scs:name-vN"}),':\nthis property may now be used on any flavor, rather than standard flavors only. In addition, the "vN" is\nnow interpreted as "name variant N" instead of "version N of the naming standard". Note that this change\nindeed preserves compliance, i.e., compliance with v1.0 implies compliance with v1.1.']}),"\n",(0,r.jsx)(s.h2,{id:"terminology",children:"Terminology"}),"\n",(0,r.jsxs)(s.p,{children:["extra_specs\nAdditional properties on an OpenStack flavor, see\n",(0,r.jsx)(s.a,{href:"https://docs.openstack.org/nova/2024.1/user/flavors.html#extra-specs",children:"OpenStack Nova user documentation"}),"\nand\n",(0,r.jsx)(s.a,{href:"https://docs.openstack.org/nova/2024.1/configuration/extra-specs.html",children:"OpenStack Nova configuration documentation"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"motivation",children:"Motivation"}),"\n",(0,r.jsx)(s.p,{children:"In OpenStack environments there is a need to define different flavors for instances.\nThe flavors are pre-defined by the operator, the customer can not change these.\nOpenStack providers thus typically offer a large selection of flavors."}),"\n",(0,r.jsxs)(s.p,{children:["While flavors can be discovered (",(0,r.jsx)(s.code,{children:"openstack flavor list"}),"), it is helpful for users (DevOps teams),\nto have a guaranteed set of flavors available on all SCS clouds, so these need not be discovered."]}),"\n",(0,r.jsx)(s.h2,{id:"properties-extra_specs",children:"Properties (extra_specs)"}),"\n",(0,r.jsx)(s.p,{children:"The following extra_specs are recognized, together with the respective semantics:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"scs:name-vN=NAME"})," (where ",(0,r.jsx)(s.code,{children:"N"})," is a positive integer, and ",(0,r.jsx)(s.code,{children:"NAME"})," is some string) means that\n",(0,r.jsx)(s.code,{children:"NAME"})," is a valid name for this flavor according to any major version of the ",(0,r.jsx)(s.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS standard on\nflavor naming"}),"."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"scs:cpu-type=shared-core"})," means that ",(0,r.jsx)(s.em,{children:"at least 20% of a core in >99% of the time"}),",\nmeasured over the course of one month (1% is 7,2 h/month). The ",(0,r.jsx)(s.code,{children:"cpu-type=shared-core"}),"\ncorresponds to the ",(0,r.jsx)(s.code,{children:"V"})," cpu modifier in the ",(0,r.jsx)(s.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"flavor-naming spec"}),",\nother options are ",(0,r.jsx)(s.code,{children:"crowded-core"})," (",(0,r.jsx)(s.code,{children:"L"}),"), ",(0,r.jsx)(s.code,{children:"dedicated-thread"})," (",(0,r.jsx)(s.code,{children:"T"}),") and ",(0,r.jsx)(s.code,{children:"dedicated-core"})," (",(0,r.jsx)(s.code,{children:"C"}),")."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"scs:diskN-type=ssd"})," (where ",(0,r.jsx)(s.code,{children:"N"})," is a non-negative integer, usually ",(0,r.jsx)(s.code,{children:"0"}),") means that the\nroot disk ",(0,r.jsx)(s.code,{children:"N"})," must support 1000 ",(0,r.jsx)(s.em,{children:"sequential"})," IOPS per VM, and it must be equipped with\npower-loss protection; see ",(0,r.jsx)(s.a,{href:"/standards/scs-0110-v1-ssd-flavors",children:"scs-0110-v1-ssd-flavors"}),".\nThe ",(0,r.jsx)(s.code,{children:"disk"}),"N",(0,r.jsx)(s.code,{children:"-type=ssd"})," setting corresponds to the ",(0,r.jsx)(s.code,{children:"s"})," disk modifier, other options\nare ",(0,r.jsx)(s.code,{children:"nvme"})," (",(0,r.jsx)(s.code,{children:"p"}),"), ",(0,r.jsx)(s.code,{children:"hdd"})," (",(0,r.jsx)(s.code,{children:"h"}),") and ",(0,r.jsx)(s.code,{children:"network"})," (",(0,r.jsx)(s.code,{children:"n"}),"). Only flavors without disk and\nthose with ",(0,r.jsx)(s.code,{children:"diskN-type=network"})," can be expected to support live-migration."]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Whenever ANY of these are present on ANY flavor, the corresponding semantics must be satisfied."}),"\n",(0,r.jsxs)(s.p,{children:["The extra_spec ",(0,r.jsx)(s.code,{children:"scs:name-vN"}),' is to be interpreted as "name variant N". This name scheme is designed to be\nbackwards compatible with v1.0 of this standard, where ',(0,r.jsx)(s.code,{children:"scs:name-vN"}),' is interpreted as\n"name according to naming standard vN". We abandon this former interpretation for two reasons:']}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsx)(s.li,{children:"the naming standards admit multiple (even many) names for the same flavor, and we want to provide a means\nof advertising more than one of them (said standards recommend using two: a short one and a long one),"}),"\n",(0,r.jsxs)(s.li,{children:["the same flavor name may be valid according to multiple versions at the same time, which would lead to\na pollution of the extra_specs with redundant properties; for instance, the name\n",(0,r.jsx)(s.code,{children:"SCS-4V-16"})," is valid for both ",(0,r.jsx)(s.a,{href:"/standards/scs-0100-v2-flavor-naming",children:"scs-0100-v2"})," and\n",(0,r.jsx)(s.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"scs-0100-v3"}),", and, since it does not use any extension, it will be valid\nfor any future version that only changes the extensions, such as the GPU vendor and architecture."]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:'Note that it is not required to use consecutive numbers to number the name variants.\nThis way, it becomes easier to remove a single variant (no "closing the gap" required).'}),"\n",(0,r.jsxs)(s.p,{children:["If extra_specs of the form ",(0,r.jsx)(s.code,{children:"scs:name-vN"})," are used to specify SCS flavor names, it is RECOMMENDED to include\nnames for the latest stable major version of the standard on flavor naming."]}),"\n",(0,r.jsx)(s.h2,{id:"standard-scs-flavors",children:"Standard SCS flavors"}),"\n",(0,r.jsx)(s.p,{children:"Following are flavors that must exist on standard SCS clouds (x86-64).\nNote that this statement does not preclude the existence of additional flavors."}),"\n",(0,r.jsx)(s.h3,{id:"mandatory",children:"Mandatory"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Recommended name"}),(0,r.jsx)(s.th,{children:"vCPUs"}),(0,r.jsx)(s.th,{children:"vCPU type"}),(0,r.jsx)(s.th,{children:"RAM [GiB]"}),(0,r.jsx)(s.th,{children:"Root disk [GB]"}),(0,r.jsx)(s.th,{children:"Disk type"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-1V-4"}),(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-2V-8"}),(0,r.jsx)(s.td,{children:"2"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"8"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-4V-16"}),(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"16"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-4V-16-100s"}),(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"16"}),(0,r.jsx)(s.td,{children:"100"}),(0,r.jsx)(s.td,{children:"ssd"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-8V-32"}),(0,r.jsx)(s.td,{children:"8"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"32"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-1V-2"}),(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"2"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-2V-4"}),(0,r.jsx)(s.td,{children:"2"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-2V-4-20s"}),(0,r.jsx)(s.td,{children:"2"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{children:"20"}),(0,r.jsx)(s.td,{children:"ssd"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-4V-8"}),(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"8"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-8V-16"}),(0,r.jsx)(s.td,{children:"8"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"16"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-16V-32"}),(0,r.jsx)(s.td,{children:"16"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"32"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-1V-8"}),(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"8"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-2V-16"}),(0,r.jsx)(s.td,{children:"2"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"16"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-4V-32"}),(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"32"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-1L-1"}),(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{children:"crowded-core"}),(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{})]})]})]}),"\n",(0,r.jsx)(s.h3,{id:"recommended",children:"Recommended"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Recommended name"}),(0,r.jsx)(s.th,{children:"vCPUs"}),(0,r.jsx)(s.th,{children:"vCPU type"}),(0,r.jsx)(s.th,{children:"RAM [GiB]"}),(0,r.jsx)(s.th,{children:"Root disk [GB]"}),(0,r.jsx)(s.th,{children:"Disk type"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-1V-4-10"}),(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{children:"10"}),(0,r.jsx)(s.td,{children:"(any)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-2V-8-20"}),(0,r.jsx)(s.td,{children:"2"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"8"}),(0,r.jsx)(s.td,{children:"20"}),(0,r.jsx)(s.td,{children:"(any)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-4V-16-50"}),(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"16"}),(0,r.jsx)(s.td,{children:"50"}),(0,r.jsx)(s.td,{children:"(any)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-8V-32-100"}),(0,r.jsx)(s.td,{children:"8"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"32"}),(0,r.jsx)(s.td,{children:"100"}),(0,r.jsx)(s.td,{children:"(any)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-1V-2-5"}),(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"2"}),(0,r.jsx)(s.td,{children:"5"}),(0,r.jsx)(s.td,{children:"(any)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-2V-4-10"}),(0,r.jsx)(s.td,{children:"2"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{children:"10"}),(0,r.jsx)(s.td,{children:"(any)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-4V-8-20"}),(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"8"}),(0,r.jsx)(s.td,{children:"20"}),(0,r.jsx)(s.td,{children:"(any)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-8V-16-50"}),(0,r.jsx)(s.td,{children:"8"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"16"}),(0,r.jsx)(s.td,{children:"50"}),(0,r.jsx)(s.td,{children:"(any)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-16V-32-100"}),(0,r.jsx)(s.td,{children:"16"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"32"}),(0,r.jsx)(s.td,{children:"100"}),(0,r.jsx)(s.td,{children:"(any)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-1V-8-20"}),(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"8"}),(0,r.jsx)(s.td,{children:"20"}),(0,r.jsx)(s.td,{children:"(any)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-2V-16-50"}),(0,r.jsx)(s.td,{children:"2"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"16"}),(0,r.jsx)(s.td,{children:"50"}),(0,r.jsx)(s.td,{children:"(any)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-4V-32-100"}),(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{children:"shared-core"}),(0,r.jsx)(s.td,{children:"32"}),(0,r.jsx)(s.td,{children:"100"}),(0,r.jsx)(s.td,{children:"(any)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-1L-1-5"}),(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{children:"crowded-core"}),(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{children:"5"}),(0,r.jsx)(s.td,{children:"(any)"})]})]})]}),"\n",(0,r.jsx)(s.h3,{id:"guarantees-and-properties",children:"Guarantees and properties"}),"\n",(0,r.jsx)(s.p,{children:"The figures given in the table (number of CPUs, amount of RAM, root disk size) must match\nprecisely the corresponding figures in the flavor."}),"\n",(0,r.jsxs)(s.p,{children:["In addition, the following properties must be set (in the ",(0,r.jsx)(s.code,{children:"extra_specs"}),"):"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"scs:name-v1"})," to the recommended name, but with each dash AFTER the first one replaced by a colon,"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"scs:name-v2"})," to the recommended name,"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"scs:cpu-type"})," to ",(0,r.jsx)(s.code,{children:"shared-core"})," or ",(0,r.jsx)(s.code,{children:"crowded-core"}),", reflecting the vCPU type,"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"scs:disk0-type"})," not set if no disk is provided, otherwise set to ",(0,r.jsx)(s.code,{children:"ssd"})," or some other\nvalue, reflecting the disk type."]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"remarks",children:"Remarks"}),"\n",(0,r.jsxs)(s.p,{children:["We expect the most used vCPU",(0,r.jsx)(s.div,{children:"GiB"})," ratio to be 1:4."]}),"\n",(0,r.jsxs)(s.p,{children:["Note that all vCPUs of SCS standard flavors are oversubscribed \u2014 the smallest ",(0,r.jsx)(s.code,{children:"1L-1"}),"\nflavor allows for heavy oversubscription (note the ",(0,r.jsx)(s.code,{children:"L"}),"), and thus can be offered very\ncheaply \u2014 imagine jump hosts ..."]}),"\n",(0,r.jsx)(s.p,{children:"The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM\ncompute hosts) to offer all flavors."}),"\n",(0,r.jsx)(s.p,{children:"Except for the two flavors with SSD root volume, disks types are not specified\n(and expected to be network disks (Ceph/Cinder) or local SATA/SAS disks typically)."}),"\n",(0,r.jsxs)(s.p,{children:["We only included a limited variation of disk sizes \u2014 this reflects that\nfor the standard networked cinder\ndisks, you can pass ",(0,r.jsx)(s.code,{children:"block_device_mapping_v2"})," on server (VM) creation to\nallocate a boot disk of any size you desire. We have scaled the few\nrecommended disk sizes with the amount of RAM. For each flavor there is\nalso one ",(0,r.jsx)(s.em,{children:"without"})," a pre-attached disk \u2014 these are meant to be used\nto boot from a volume (either created beforehand or allocated on-the-fly\nwith ",(0,r.jsx)(s.code,{children:"block_device_mapping_v2"}),", e.g.\n",(0,r.jsx)(s.code,{children:"openstack server create --flavor SCS-1V-2 --block-device-mapping sda=IMGUUID:image:12:true"}),"\nto create a bootable 12G cinder volume from image ",(0,r.jsx)(s.code,{children:"IMGUUID"})," that gets tied to the VM\ninstance life cycle.)"]}),"\n",(0,r.jsx)(s.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,r.jsxs)(s.p,{children:["The script ",(0,r.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/standard-flavors/flavors-openstack.py",children:(0,r.jsx)(s.code,{children:"flavors-openstack.py"})}),"\nwill read the lists of mandatory and recommended flavors\nfrom a yaml file provided as command-line argument, connect to an OpenStack installation,\nand check whether the flavors are present and their extra_specs are correct."]}),"\n",(0,r.jsx)(s.p,{children:"Missing flavors will be reported on various logging channels: error for mandatory, warning for\nrecommended flavors. Incorrect extra_specs will be reported as error in any case.\nThe return code will be non-zero if the test could not be performed or if any error was\nreported."}),"\n",(0,r.jsxs)(s.p,{children:["The script does not check whether a name given via the extra_spec ",(0,r.jsx)(s.code,{children:"scs:name-vN"})," is indeed valid according\nto any major version of the SCS standard on flavor naming."]}),"\n",(0,r.jsx)(s.h2,{id:"operational-tooling",children:"Operational tooling"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.a,{href:"https://github.com/osism/openstack-flavor-manager",children:"openstack-flavor-manager"})," is able to\ncreate all standard, mandatory SCS flavors for you. It takes input that can be generated by\n",(0,r.jsx)(s.code,{children:"flavor-manager-input.py"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"previous-standard-versions",children:"Previous standard versions"}),"\n",(0,r.jsxs)(s.p,{children:["The list of standard flavors used to be part of the flavor naming standard up until\n",(0,r.jsx)(s.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"version 3"}),". The following changes have been made to\nthe list in comparison with said standard:"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"the flavor names have been turned into recommendations, and"}),"\n",(0,r.jsx)(s.li,{children:"the properties have been introduced in order to help discoverability."}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["Note that the flavors with fixed size root disks have all moved to Recommended\nwith ",(0,r.jsx)(s.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"scs-0100-v3"}),".\nThis means that they are not a certification requirement any longer,\nbut we still recommend implementing these for backwards compatibility reasons.\nAlso in that standard, two flavors with SSD+ root disks have been added, as defined in\n",(0,r.jsx)(s.a,{href:"/standards/scs-0110-v1-ssd-flavors",children:"scs-0110-v1-ssd-flavors.md"})]})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>i,x:()=>a});var d=n(96540);const r={},t=d.createContext(r);function i(e){const s=d.useContext(t);return d.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),d.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/52ac6bcf.8a3524d7.js b/assets/js/52ac6bcf.8a3524d7.js new file mode 100644 index 0000000000..bd268a0975 --- /dev/null +++ b/assets/js/52ac6bcf.8a3524d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[47813],{10979:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>d,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"kaas/scs-0213","title":"scs-0213: Kubernetes Nodes Anti Affinity","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/kaas/scs-0213.md","sourceDirName":"kaas","slug":"/kaas/scs-0213","permalink":"/standards/kaas/scs-0213","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0212-v1-requirements-for-container-registries"},"next":{"title":"V1","permalink":"/standards/scs-0213-v1-k8s-nodes-anti-affinity"}}');var r=s(74848),i=s(28453);const d={},a="scs-0213: Kubernetes Nodes Anti Affinity",c={},o=[];function l(e){const t={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0213-kubernetes-nodes-anti-affinity",children:"scs-0213: Kubernetes Nodes Anti Affinity"})}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0213-v1-k8s-nodes-anti-affinity",children:"scs-0213-v1"})}),(0,r.jsx)(t.td,{children:"Decision Record"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>a});var n=s(96540);const r={},i=n.createContext(r);function d(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/531f0326.7a5db3da.js b/assets/js/531f0326.7a5db3da.js new file mode 100644 index 0000000000..9005ae663b --- /dev/null +++ b/assets/js/531f0326.7a5db3da.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[21249],{42559:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>c,default:()=>l,frontMatter:()=>r,metadata:()=>o,toc:()=>i});const o=JSON.parse('{"id":"operating-scs/components/status-page-deployment/docs/faq","title":"FAQ","description":"Dex needs a GitHub client secret. Where can I get it?","source":"@site/docs/04-operating-scs/components/status-page-deployment/docs/faq.md","sourceDirName":"04-operating-scs/components/status-page-deployment/docs","slug":"/operating-scs/components/status-page-deployment/docs/faq","permalink":"/docs/operating-scs/components/status-page-deployment/docs/faq","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-deployment/docs/faq.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Admin authentication","permalink":"/docs/operating-scs/components/status-page-deployment/docs/admin-authentication"},"next":{"title":"Web","permalink":"/docs/category/web"}}');var a=n(74848),s=n(28453);const r={},c="FAQ",d={},i=[{value:"Dex needs a GitHub client secret. Where can I get it?",id:"dex-needs-a-github-client-secret-where-can-i-get-it",level:2},{value:"I want to deploy on XY, can you do that?",id:"i-want-to-deploy-on-xy-can-you-do-that",level:2},{value:"I want to deploy another database, reverse proxy, ingress, AuthN, AuthZ, etc. Can you do that?",id:"i-want-to-deploy-another-database-reverse-proxy-ingress-authn-authz-etc-can-you-do-that",level:2},{value:"I want another web frontend and API server, can you do that?",id:"i-want-another-web-frontend-and-api-server-can-you-do-that",level:2}];function p(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"faq",children:"FAQ"})}),"\n",(0,a.jsx)(t.h2,{id:"dex-needs-a-github-client-secret-where-can-i-get-it",children:"Dex needs a GitHub client secret. Where can I get it?"}),"\n",(0,a.jsxs)(t.p,{children:["The examples are directly linked to the ",(0,a.jsx)(t.strong,{children:"SCS Gatekeeper"})," OAuth app that allows access for SovereignCloudStack members. It's recommended to create an own OAuth app in GitHub or any other supported provider. If you need quick and easy access as developer or tester, get in contact on matrix."]}),"\n",(0,a.jsx)(t.h2,{id:"i-want-to-deploy-on-xy-can-you-do-that",children:"I want to deploy on XY, can you do that?"}),"\n",(0,a.jsx)(t.p,{children:"Yes, all ways that are shown here to deploy the status page can be seen as examples and templates. Fork the repository and build your own deployment. Maybe start a pull request to share your way."}),"\n",(0,a.jsx)(t.h2,{id:"i-want-to-deploy-another-database-reverse-proxy-ingress-authn-authz-etc-can-you-do-that",children:"I want to deploy another database, reverse proxy, ingress, AuthN, AuthZ, etc. Can you do that?"}),"\n",(0,a.jsx)(t.p,{children:"Yes, see above."}),"\n",(0,a.jsx)(t.h2,{id:"i-want-another-web-frontend-and-api-server-can-you-do-that",children:"I want another web frontend and API server, can you do that?"}),"\n",(0,a.jsxs)(t.p,{children:["Currently no. The reference implementation only supplies one API server and one web frontend. You can implement your own, when conforming to ",(0,a.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi",children:"SovereignCloudStack/status-page-openapi"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(p,{...e})}):p(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>c});var o=n(96540);const a={},s=o.createContext(a);function r(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/53292.ed8f5a00.js b/assets/js/53292.ed8f5a00.js new file mode 100644 index 0000000000..b3dda1aea1 --- /dev/null +++ b/assets/js/53292.ed8f5a00.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[53292],{53292:(t,e,n)=>{n.d(e,{diagram:()=>nt});var a=n(86079),i=n(26312),s=n(79186),r=n(16750),l=(n(74353),n(42838),function(){var t=function(t,e,n,a){for(n=n||{},a=t.length;a--;n[t[a]]=e);return n},e=[1,24],n=[1,25],a=[1,26],i=[1,27],s=[1,28],r=[1,63],l=[1,64],o=[1,65],h=[1,66],d=[1,67],u=[1,68],p=[1,69],y=[1,29],f=[1,30],b=[1,31],g=[1,32],x=[1,33],_=[1,34],m=[1,35],E=[1,36],A=[1,37],S=[1,38],C=[1,39],k=[1,40],O=[1,41],v=[1,42],T=[1,43],w=[1,44],R=[1,45],D=[1,46],N=[1,47],P=[1,48],M=[1,50],j=[1,51],B=[1,52],L=[1,53],Y=[1,54],I=[1,55],U=[1,56],F=[1,57],X=[1,58],z=[1,59],W=[1,60],Q=[14,42],$=[14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],q=[12,14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],V=[1,82],G=[1,83],H=[1,84],K=[1,85],J=[12,14,42],Z=[12,14,33,42],tt=[12,14,33,42,76,77,79,80],et=[12,33],nt=[34,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],at={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,direction_tb:6,direction_bt:7,direction_rl:8,direction_lr:9,graphConfig:10,C4_CONTEXT:11,NEWLINE:12,statements:13,EOF:14,C4_CONTAINER:15,C4_COMPONENT:16,C4_DYNAMIC:17,C4_DEPLOYMENT:18,otherStatements:19,diagramStatements:20,otherStatement:21,title:22,accDescription:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,boundaryStatement:29,boundaryStartStatement:30,boundaryStopStatement:31,boundaryStart:32,LBRACE:33,ENTERPRISE_BOUNDARY:34,attributes:35,SYSTEM_BOUNDARY:36,BOUNDARY:37,CONTAINER_BOUNDARY:38,NODE:39,NODE_L:40,NODE_R:41,RBRACE:42,diagramStatement:43,PERSON:44,PERSON_EXT:45,SYSTEM:46,SYSTEM_DB:47,SYSTEM_QUEUE:48,SYSTEM_EXT:49,SYSTEM_EXT_DB:50,SYSTEM_EXT_QUEUE:51,CONTAINER:52,CONTAINER_DB:53,CONTAINER_QUEUE:54,CONTAINER_EXT:55,CONTAINER_EXT_DB:56,CONTAINER_EXT_QUEUE:57,COMPONENT:58,COMPONENT_DB:59,COMPONENT_QUEUE:60,COMPONENT_EXT:61,COMPONENT_EXT_DB:62,COMPONENT_EXT_QUEUE:63,REL:64,BIREL:65,REL_U:66,REL_D:67,REL_L:68,REL_R:69,REL_B:70,REL_INDEX:71,UPDATE_EL_STYLE:72,UPDATE_REL_STYLE:73,UPDATE_LAYOUT_CONFIG:74,attribute:75,STR:76,STR_KEY:77,STR_VALUE:78,ATTRIBUTE:79,ATTRIBUTE_EMPTY:80,$accept:0,$end:1},terminals_:{2:"error",6:"direction_tb",7:"direction_bt",8:"direction_rl",9:"direction_lr",11:"C4_CONTEXT",12:"NEWLINE",14:"EOF",15:"C4_CONTAINER",16:"C4_COMPONENT",17:"C4_DYNAMIC",18:"C4_DEPLOYMENT",22:"title",23:"accDescription",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"LBRACE",34:"ENTERPRISE_BOUNDARY",36:"SYSTEM_BOUNDARY",37:"BOUNDARY",38:"CONTAINER_BOUNDARY",39:"NODE",40:"NODE_L",41:"NODE_R",42:"RBRACE",44:"PERSON",45:"PERSON_EXT",46:"SYSTEM",47:"SYSTEM_DB",48:"SYSTEM_QUEUE",49:"SYSTEM_EXT",50:"SYSTEM_EXT_DB",51:"SYSTEM_EXT_QUEUE",52:"CONTAINER",53:"CONTAINER_DB",54:"CONTAINER_QUEUE",55:"CONTAINER_EXT",56:"CONTAINER_EXT_DB",57:"CONTAINER_EXT_QUEUE",58:"COMPONENT",59:"COMPONENT_DB",60:"COMPONENT_QUEUE",61:"COMPONENT_EXT",62:"COMPONENT_EXT_DB",63:"COMPONENT_EXT_QUEUE",64:"REL",65:"BIREL",66:"REL_U",67:"REL_D",68:"REL_L",69:"REL_R",70:"REL_B",71:"REL_INDEX",72:"UPDATE_EL_STYLE",73:"UPDATE_REL_STYLE",74:"UPDATE_LAYOUT_CONFIG",76:"STR",77:"STR_KEY",78:"STR_VALUE",79:"ATTRIBUTE",80:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[5,1],[5,1],[5,1],[5,1],[4,1],[10,4],[10,4],[10,4],[10,4],[10,4],[13,1],[13,1],[13,2],[19,1],[19,2],[19,3],[21,1],[21,1],[21,2],[21,2],[21,1],[29,3],[30,3],[30,3],[30,4],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[31,1],[20,1],[20,2],[20,3],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,1],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[35,1],[35,2],[75,1],[75,2],[75,1],[75,1]],performAction:function(t,e,n,a,i,s,r){var l=s.length-1;switch(i){case 3:a.setDirection("TB");break;case 4:a.setDirection("BT");break;case 5:a.setDirection("RL");break;case 6:a.setDirection("LR");break;case 8:case 9:case 10:case 11:case 12:a.setC4Type(s[l-3]);break;case 19:a.setTitle(s[l].substring(6)),this.$=s[l].substring(6);break;case 20:a.setAccDescription(s[l].substring(15)),this.$=s[l].substring(15);break;case 21:this.$=s[l].trim(),a.setTitle(this.$);break;case 22:case 23:this.$=s[l].trim(),a.setAccDescription(this.$);break;case 28:case 29:s[l].splice(2,0,"ENTERPRISE"),a.addPersonOrSystemBoundary(...s[l]),this.$=s[l];break;case 30:a.addPersonOrSystemBoundary(...s[l]),this.$=s[l];break;case 31:s[l].splice(2,0,"CONTAINER"),a.addContainerBoundary(...s[l]),this.$=s[l];break;case 32:a.addDeploymentNode("node",...s[l]),this.$=s[l];break;case 33:a.addDeploymentNode("nodeL",...s[l]),this.$=s[l];break;case 34:a.addDeploymentNode("nodeR",...s[l]),this.$=s[l];break;case 35:a.popBoundaryParseStack();break;case 39:a.addPersonOrSystem("person",...s[l]),this.$=s[l];break;case 40:a.addPersonOrSystem("external_person",...s[l]),this.$=s[l];break;case 41:a.addPersonOrSystem("system",...s[l]),this.$=s[l];break;case 42:a.addPersonOrSystem("system_db",...s[l]),this.$=s[l];break;case 43:a.addPersonOrSystem("system_queue",...s[l]),this.$=s[l];break;case 44:a.addPersonOrSystem("external_system",...s[l]),this.$=s[l];break;case 45:a.addPersonOrSystem("external_system_db",...s[l]),this.$=s[l];break;case 46:a.addPersonOrSystem("external_system_queue",...s[l]),this.$=s[l];break;case 47:a.addContainer("container",...s[l]),this.$=s[l];break;case 48:a.addContainer("container_db",...s[l]),this.$=s[l];break;case 49:a.addContainer("container_queue",...s[l]),this.$=s[l];break;case 50:a.addContainer("external_container",...s[l]),this.$=s[l];break;case 51:a.addContainer("external_container_db",...s[l]),this.$=s[l];break;case 52:a.addContainer("external_container_queue",...s[l]),this.$=s[l];break;case 53:a.addComponent("component",...s[l]),this.$=s[l];break;case 54:a.addComponent("component_db",...s[l]),this.$=s[l];break;case 55:a.addComponent("component_queue",...s[l]),this.$=s[l];break;case 56:a.addComponent("external_component",...s[l]),this.$=s[l];break;case 57:a.addComponent("external_component_db",...s[l]),this.$=s[l];break;case 58:a.addComponent("external_component_queue",...s[l]),this.$=s[l];break;case 60:a.addRel("rel",...s[l]),this.$=s[l];break;case 61:a.addRel("birel",...s[l]),this.$=s[l];break;case 62:a.addRel("rel_u",...s[l]),this.$=s[l];break;case 63:a.addRel("rel_d",...s[l]),this.$=s[l];break;case 64:a.addRel("rel_l",...s[l]),this.$=s[l];break;case 65:a.addRel("rel_r",...s[l]),this.$=s[l];break;case 66:a.addRel("rel_b",...s[l]),this.$=s[l];break;case 67:s[l].splice(0,1),a.addRel("rel",...s[l]),this.$=s[l];break;case 68:a.updateElStyle("update_el_style",...s[l]),this.$=s[l];break;case 69:a.updateRelStyle("update_rel_style",...s[l]),this.$=s[l];break;case 70:a.updateLayoutConfig("update_layout_config",...s[l]),this.$=s[l];break;case 71:this.$=[s[l]];break;case 72:s[l].unshift(s[l-1]),this.$=s[l];break;case 73:case 75:this.$=s[l].trim();break;case 74:let t={};t[s[l-1].trim()]=s[l].trim(),this.$=t;break;case 76:this.$=""}},table:[{3:1,4:2,5:3,6:[1,5],7:[1,6],8:[1,7],9:[1,8],10:4,11:[1,9],15:[1,10],16:[1,11],17:[1,12],18:[1,13]},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,7]},{1:[2,3]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{12:[1,14]},{12:[1,15]},{12:[1,16]},{12:[1,17]},{12:[1,18]},{13:19,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W},{13:70,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W},{13:71,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W},{13:72,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W},{13:73,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W},{14:[1,74]},t(Q,[2,13],{43:23,29:49,30:61,32:62,20:75,34:r,36:l,37:o,38:h,39:d,40:u,41:p,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W}),t(Q,[2,14]),t($,[2,16],{12:[1,76]}),t(Q,[2,36],{12:[1,77]}),t(q,[2,19]),t(q,[2,20]),{25:[1,78]},{27:[1,79]},t(q,[2,23]),{35:80,75:81,76:V,77:G,79:H,80:K},{35:86,75:81,76:V,77:G,79:H,80:K},{35:87,75:81,76:V,77:G,79:H,80:K},{35:88,75:81,76:V,77:G,79:H,80:K},{35:89,75:81,76:V,77:G,79:H,80:K},{35:90,75:81,76:V,77:G,79:H,80:K},{35:91,75:81,76:V,77:G,79:H,80:K},{35:92,75:81,76:V,77:G,79:H,80:K},{35:93,75:81,76:V,77:G,79:H,80:K},{35:94,75:81,76:V,77:G,79:H,80:K},{35:95,75:81,76:V,77:G,79:H,80:K},{35:96,75:81,76:V,77:G,79:H,80:K},{35:97,75:81,76:V,77:G,79:H,80:K},{35:98,75:81,76:V,77:G,79:H,80:K},{35:99,75:81,76:V,77:G,79:H,80:K},{35:100,75:81,76:V,77:G,79:H,80:K},{35:101,75:81,76:V,77:G,79:H,80:K},{35:102,75:81,76:V,77:G,79:H,80:K},{35:103,75:81,76:V,77:G,79:H,80:K},{35:104,75:81,76:V,77:G,79:H,80:K},t(J,[2,59]),{35:105,75:81,76:V,77:G,79:H,80:K},{35:106,75:81,76:V,77:G,79:H,80:K},{35:107,75:81,76:V,77:G,79:H,80:K},{35:108,75:81,76:V,77:G,79:H,80:K},{35:109,75:81,76:V,77:G,79:H,80:K},{35:110,75:81,76:V,77:G,79:H,80:K},{35:111,75:81,76:V,77:G,79:H,80:K},{35:112,75:81,76:V,77:G,79:H,80:K},{35:113,75:81,76:V,77:G,79:H,80:K},{35:114,75:81,76:V,77:G,79:H,80:K},{35:115,75:81,76:V,77:G,79:H,80:K},{20:116,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W},{12:[1,118],33:[1,117]},{35:119,75:81,76:V,77:G,79:H,80:K},{35:120,75:81,76:V,77:G,79:H,80:K},{35:121,75:81,76:V,77:G,79:H,80:K},{35:122,75:81,76:V,77:G,79:H,80:K},{35:123,75:81,76:V,77:G,79:H,80:K},{35:124,75:81,76:V,77:G,79:H,80:K},{35:125,75:81,76:V,77:G,79:H,80:K},{14:[1,126]},{14:[1,127]},{14:[1,128]},{14:[1,129]},{1:[2,8]},t(Q,[2,15]),t($,[2,17],{21:22,19:130,22:e,23:n,24:a,26:i,28:s}),t(Q,[2,37],{19:20,20:21,21:22,43:23,29:49,30:61,32:62,13:131,22:e,23:n,24:a,26:i,28:s,34:r,36:l,37:o,38:h,39:d,40:u,41:p,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W}),t(q,[2,21]),t(q,[2,22]),t(J,[2,39]),t(Z,[2,71],{75:81,35:132,76:V,77:G,79:H,80:K}),t(tt,[2,73]),{78:[1,133]},t(tt,[2,75]),t(tt,[2,76]),t(J,[2,40]),t(J,[2,41]),t(J,[2,42]),t(J,[2,43]),t(J,[2,44]),t(J,[2,45]),t(J,[2,46]),t(J,[2,47]),t(J,[2,48]),t(J,[2,49]),t(J,[2,50]),t(J,[2,51]),t(J,[2,52]),t(J,[2,53]),t(J,[2,54]),t(J,[2,55]),t(J,[2,56]),t(J,[2,57]),t(J,[2,58]),t(J,[2,60]),t(J,[2,61]),t(J,[2,62]),t(J,[2,63]),t(J,[2,64]),t(J,[2,65]),t(J,[2,66]),t(J,[2,67]),t(J,[2,68]),t(J,[2,69]),t(J,[2,70]),{31:134,42:[1,135]},{12:[1,136]},{33:[1,137]},t(et,[2,28]),t(et,[2,29]),t(et,[2,30]),t(et,[2,31]),t(et,[2,32]),t(et,[2,33]),t(et,[2,34]),{1:[2,9]},{1:[2,10]},{1:[2,11]},{1:[2,12]},t($,[2,18]),t(Q,[2,38]),t(Z,[2,72]),t(tt,[2,74]),t(J,[2,24]),t(J,[2,35]),t(nt,[2,25]),t(nt,[2,26],{12:[1,138]}),t(nt,[2,27])],defaultActions:{2:[2,1],3:[2,2],4:[2,7],5:[2,3],6:[2,4],7:[2,5],8:[2,6],74:[2,8],126:[2,9],127:[2,10],128:[2,11],129:[2,12]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],a=[],i=[null],s=[],r=this.table,l="",o=0,c=0,h=s.slice.call(arguments,1),d=Object.create(this.lexer),u={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(u.yy[p]=this.yy[p]);d.setInput(t,u.yy),u.yy.lexer=d,u.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var y=d.yylloc;s.push(y);var f=d.options&&d.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var b,g,x,_,m,E,A,S,C,k={};;){if(g=n[n.length-1],this.defaultActions[g]?x=this.defaultActions[g]:(null==b&&(C=void 0,"number"!=typeof(C=a.pop()||d.lex()||1)&&(C instanceof Array&&(C=(a=C).pop()),C=e.symbols_[C]||C),b=C),x=r[g]&&r[g][b]),void 0===x||!x.length||!x[0]){var O="";for(m in S=[],r[g])this.terminals_[m]&&m>2&&S.push("'"+this.terminals_[m]+"'");O=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+S.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(O,{text:d.match,token:this.terminals_[b]||b,line:d.yylineno,loc:y,expected:S})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+b);switch(x[0]){case 1:n.push(b),i.push(d.yytext),s.push(d.yylloc),n.push(x[1]),b=null,c=d.yyleng,l=d.yytext,o=d.yylineno,y=d.yylloc;break;case 2:if(E=this.productions_[x[1]][1],k.$=i[i.length-E],k._$={first_line:s[s.length-(E||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(E||1)].first_column,last_column:s[s.length-1].last_column},f&&(k._$.range=[s[s.length-(E||1)].range[0],s[s.length-1].range[1]]),void 0!==(_=this.performAction.apply(k,[l,c,o,u.yy,x[1],i,s].concat(h))))return _;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),s=s.slice(0,-1*E)),n.push(this.productions_[x[1]][0]),i.push(k.$),s.push(k._$),A=r[n[n.length-2]][n[n.length-1]],n.push(A);break;case 3:return!0}}return!0}},it={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var a=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===a.length?this.yylloc.first_column:0)+a[a.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,a,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var s in i)this[s]=i[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),s=0;s<i.length;s++)if((n=this._input.match(this.rules[i[s]]))&&(!e||n[0].length>e[0].length)){if(e=n,a=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,a){switch(n){case 0:return 6;case 1:return 7;case 2:return 8;case 3:return 9;case 4:return 22;case 5:return 23;case 6:return this.begin("acc_title"),24;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),26;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 73:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:case 16:case 70:break;case 14:c;break;case 15:return 12;case 17:return 11;case 18:return 15;case 19:return 16;case 20:return 17;case 21:return 18;case 22:return this.begin("person_ext"),45;case 23:return this.begin("person"),44;case 24:return this.begin("system_ext_queue"),51;case 25:return this.begin("system_ext_db"),50;case 26:return this.begin("system_ext"),49;case 27:return this.begin("system_queue"),48;case 28:return this.begin("system_db"),47;case 29:return this.begin("system"),46;case 30:return this.begin("boundary"),37;case 31:return this.begin("enterprise_boundary"),34;case 32:return this.begin("system_boundary"),36;case 33:return this.begin("container_ext_queue"),57;case 34:return this.begin("container_ext_db"),56;case 35:return this.begin("container_ext"),55;case 36:return this.begin("container_queue"),54;case 37:return this.begin("container_db"),53;case 38:return this.begin("container"),52;case 39:return this.begin("container_boundary"),38;case 40:return this.begin("component_ext_queue"),63;case 41:return this.begin("component_ext_db"),62;case 42:return this.begin("component_ext"),61;case 43:return this.begin("component_queue"),60;case 44:return this.begin("component_db"),59;case 45:return this.begin("component"),58;case 46:case 47:return this.begin("node"),39;case 48:return this.begin("node_l"),40;case 49:return this.begin("node_r"),41;case 50:return this.begin("rel"),64;case 51:return this.begin("birel"),65;case 52:case 53:return this.begin("rel_u"),66;case 54:case 55:return this.begin("rel_d"),67;case 56:case 57:return this.begin("rel_l"),68;case 58:case 59:return this.begin("rel_r"),69;case 60:return this.begin("rel_b"),70;case 61:return this.begin("rel_index"),71;case 62:return this.begin("update_el_style"),72;case 63:return this.begin("update_rel_style"),73;case 64:return this.begin("update_layout_config"),74;case 65:return"EOF_IN_STRUCT";case 66:return this.begin("attribute"),"ATTRIBUTE_EMPTY";case 67:this.begin("attribute");break;case 68:case 79:this.popState(),this.popState();break;case 69:case 71:return 80;case 72:this.begin("string");break;case 74:case 80:return"STR";case 75:this.begin("string_kv");break;case 76:return this.begin("string_kv_key"),"STR_KEY";case 77:this.popState(),this.begin("string_kv_value");break;case 78:return"STR_VALUE";case 81:return"LBRACE";case 82:return"RBRACE";case 83:return"SPACE";case 84:return"EOL";case 85:return 14}},rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:title\s[^#\n;]+)/,/^(?:accDescription\s[^#\n;]+)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:C4Context\b)/,/^(?:C4Container\b)/,/^(?:C4Component\b)/,/^(?:C4Dynamic\b)/,/^(?:C4Deployment\b)/,/^(?:Person_Ext\b)/,/^(?:Person\b)/,/^(?:SystemQueue_Ext\b)/,/^(?:SystemDb_Ext\b)/,/^(?:System_Ext\b)/,/^(?:SystemQueue\b)/,/^(?:SystemDb\b)/,/^(?:System\b)/,/^(?:Boundary\b)/,/^(?:Enterprise_Boundary\b)/,/^(?:System_Boundary\b)/,/^(?:ContainerQueue_Ext\b)/,/^(?:ContainerDb_Ext\b)/,/^(?:Container_Ext\b)/,/^(?:ContainerQueue\b)/,/^(?:ContainerDb\b)/,/^(?:Container\b)/,/^(?:Container_Boundary\b)/,/^(?:ComponentQueue_Ext\b)/,/^(?:ComponentDb_Ext\b)/,/^(?:Component_Ext\b)/,/^(?:ComponentQueue\b)/,/^(?:ComponentDb\b)/,/^(?:Component\b)/,/^(?:Deployment_Node\b)/,/^(?:Node\b)/,/^(?:Node_L\b)/,/^(?:Node_R\b)/,/^(?:Rel\b)/,/^(?:BiRel\b)/,/^(?:Rel_Up\b)/,/^(?:Rel_U\b)/,/^(?:Rel_Down\b)/,/^(?:Rel_D\b)/,/^(?:Rel_Left\b)/,/^(?:Rel_L\b)/,/^(?:Rel_Right\b)/,/^(?:Rel_R\b)/,/^(?:Rel_Back\b)/,/^(?:RelIndex\b)/,/^(?:UpdateElementStyle\b)/,/^(?:UpdateRelStyle\b)/,/^(?:UpdateLayoutConfig\b)/,/^(?:$)/,/^(?:[(][ ]*[,])/,/^(?:[(])/,/^(?:[)])/,/^(?:,,)/,/^(?:,)/,/^(?:[ ]*["]["])/,/^(?:[ ]*["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[ ]*[\$])/,/^(?:[^=]*)/,/^(?:[=][ ]*["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:[^,]+)/,/^(?:\{)/,/^(?:\})/,/^(?:[\s]+)/,/^(?:[\n\r]+)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},string_kv_value:{rules:[78,79],inclusive:!1},string_kv_key:{rules:[77],inclusive:!1},string_kv:{rules:[76],inclusive:!1},string:{rules:[73,74],inclusive:!1},attribute:{rules:[68,69,70,71,72,75,80],inclusive:!1},update_layout_config:{rules:[65,66,67,68],inclusive:!1},update_rel_style:{rules:[65,66,67,68],inclusive:!1},update_el_style:{rules:[65,66,67,68],inclusive:!1},rel_b:{rules:[65,66,67,68],inclusive:!1},rel_r:{rules:[65,66,67,68],inclusive:!1},rel_l:{rules:[65,66,67,68],inclusive:!1},rel_d:{rules:[65,66,67,68],inclusive:!1},rel_u:{rules:[65,66,67,68],inclusive:!1},rel_bi:{rules:[],inclusive:!1},rel:{rules:[65,66,67,68],inclusive:!1},node_r:{rules:[65,66,67,68],inclusive:!1},node_l:{rules:[65,66,67,68],inclusive:!1},node:{rules:[65,66,67,68],inclusive:!1},index:{rules:[],inclusive:!1},rel_index:{rules:[65,66,67,68],inclusive:!1},component_ext_queue:{rules:[],inclusive:!1},component_ext_db:{rules:[65,66,67,68],inclusive:!1},component_ext:{rules:[65,66,67,68],inclusive:!1},component_queue:{rules:[65,66,67,68],inclusive:!1},component_db:{rules:[65,66,67,68],inclusive:!1},component:{rules:[65,66,67,68],inclusive:!1},container_boundary:{rules:[65,66,67,68],inclusive:!1},container_ext_queue:{rules:[65,66,67,68],inclusive:!1},container_ext_db:{rules:[65,66,67,68],inclusive:!1},container_ext:{rules:[65,66,67,68],inclusive:!1},container_queue:{rules:[65,66,67,68],inclusive:!1},container_db:{rules:[65,66,67,68],inclusive:!1},container:{rules:[65,66,67,68],inclusive:!1},birel:{rules:[65,66,67,68],inclusive:!1},system_boundary:{rules:[65,66,67,68],inclusive:!1},enterprise_boundary:{rules:[65,66,67,68],inclusive:!1},boundary:{rules:[65,66,67,68],inclusive:!1},system_ext_queue:{rules:[65,66,67,68],inclusive:!1},system_ext_db:{rules:[65,66,67,68],inclusive:!1},system_ext:{rules:[65,66,67,68],inclusive:!1},system_queue:{rules:[65,66,67,68],inclusive:!1},system_db:{rules:[65,66,67,68],inclusive:!1},system:{rules:[65,66,67,68],inclusive:!1},person_ext:{rules:[65,66,67,68],inclusive:!1},person:{rules:[65,66,67,68],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,81,82,83,84,85],inclusive:!0}}};function st(){this.yy={}}return at.lexer=it,st.prototype=at,at.Parser=st,new st}());l.parser=l;const o=l;let h=[],d=[""],u="global",p="",y=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],f=[],b="",g=!1,x=4,_=2;var m;const E=function(t){return null==t?h:h.filter((e=>e.parentBoundary===t))},A=function(t){return null==t?y:y.filter((e=>e.parentBoundary===t))},S=function(){return g},C={addPersonOrSystem:function(t,e,n,a,i,s,r){if(null===e||null===n)return;let l={};const o=h.find((t=>t.alias===e));if(o&&e===o.alias?l=o:(l.alias=e,h.push(l)),l.label=null==n?{text:""}:{text:n},null==a)l.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]={text:e}}else l.descr={text:a};if("object"==typeof i){let[t,e]=Object.entries(i)[0];l[t]=e}else l.sprite=i;if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=e}else l.tags=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=e}else l.link=r;l.typeC4Shape={text:t},l.parentBoundary=u,l.wrap=S()},addPersonOrSystemBoundary:function(t,e,n,a,i){if(null===t||null===e)return;let s={};const r=y.find((e=>e.alias===t));if(r&&t===r.alias?s=r:(s.alias=t,y.push(s)),s.label=null==e?{text:""}:{text:e},null==n)s.type={text:"system"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];s[t]={text:e}}else s.type={text:n};if("object"==typeof a){let[t,e]=Object.entries(a)[0];s[t]=e}else s.tags=a;if("object"==typeof i){let[t,e]=Object.entries(i)[0];s[t]=e}else s.link=i;s.parentBoundary=u,s.wrap=S(),p=u,u=t,d.push(p)},addContainer:function(t,e,n,a,i,s,r,l){if(null===e||null===n)return;let o={};const c=h.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,h.push(o)),o.label=null==n?{text:""}:{text:n},null==a)o.techn={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.techn={text:a};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.sprite=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=S(),o.typeC4Shape={text:t},o.parentBoundary=u},addContainerBoundary:function(t,e,n,a,i){if(null===t||null===e)return;let s={};const r=y.find((e=>e.alias===t));if(r&&t===r.alias?s=r:(s.alias=t,y.push(s)),s.label=null==e?{text:""}:{text:e},null==n)s.type={text:"container"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];s[t]={text:e}}else s.type={text:n};if("object"==typeof a){let[t,e]=Object.entries(a)[0];s[t]=e}else s.tags=a;if("object"==typeof i){let[t,e]=Object.entries(i)[0];s[t]=e}else s.link=i;s.parentBoundary=u,s.wrap=S(),p=u,u=t,d.push(p)},addComponent:function(t,e,n,a,i,s,r,l){if(null===e||null===n)return;let o={};const c=h.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,h.push(o)),o.label=null==n?{text:""}:{text:n},null==a)o.techn={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.techn={text:a};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.sprite=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=S(),o.typeC4Shape={text:t},o.parentBoundary=u},addDeploymentNode:function(t,e,n,a,i,s,r,l){if(null===e||null===n)return;let o={};const c=y.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,y.push(o)),o.label=null==n?{text:""}:{text:n},null==a)o.type={text:"node"};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.type={text:a};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.nodeType=t,o.parentBoundary=u,o.wrap=S(),p=u,u=e,d.push(p)},popBoundaryParseStack:function(){u=p,d.pop(),p=d.pop(),d.push(p)},addRel:function(t,e,n,a,i,s,r,l,o){if(null==t||null==e||null==n||null==a)return;let c={};const h=f.find((t=>t.from===e&&t.to===n));if(h?c=h:f.push(c),c.type=t,c.from=e,c.to=n,c.label={text:a},null==i)c.techn={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];c[t]={text:e}}else c.techn={text:i};if(null==s)c.descr={text:""};else if("object"==typeof s){let[t,e]=Object.entries(s)[0];c[t]={text:e}}else c.descr={text:s};if("object"==typeof r){let[t,e]=Object.entries(r)[0];c[t]=e}else c.sprite=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];c[t]=e}else c.tags=l;if("object"==typeof o){let[t,e]=Object.entries(o)[0];c[t]=e}else c.link=o;c.wrap=S()},updateElStyle:function(t,e,n,a,i,s,r,l,o,c,d){let u=h.find((t=>t.alias===e));if(void 0!==u||(u=y.find((t=>t.alias===e)),void 0!==u)){if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];u[t]=e}else u.bgColor=n;if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];u[t]=e}else u.fontColor=a;if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];u[t]=e}else u.borderColor=i;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];u[t]=e}else u.shadowing=s;if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];u[t]=e}else u.shape=r;if(null!=l)if("object"==typeof l){let[t,e]=Object.entries(l)[0];u[t]=e}else u.sprite=l;if(null!=o)if("object"==typeof o){let[t,e]=Object.entries(o)[0];u[t]=e}else u.techn=o;if(null!=c)if("object"==typeof c){let[t,e]=Object.entries(c)[0];u[t]=e}else u.legendText=c;if(null!=d)if("object"==typeof d){let[t,e]=Object.entries(d)[0];u[t]=e}else u.legendSprite=d}},updateRelStyle:function(t,e,n,a,i,s,r){const l=f.find((t=>t.from===e&&t.to===n));if(void 0!==l){if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]=e}else l.textColor=a;if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];l[t]=e}else l.lineColor=i;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=parseInt(e)}else l.offsetX=parseInt(s);if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=parseInt(e)}else l.offsetY=parseInt(r)}},updateLayoutConfig:function(t,e,n){let a=x,i=_;if("object"==typeof e){const t=Object.values(e)[0];a=parseInt(t)}else a=parseInt(e);if("object"==typeof n){const t=Object.values(n)[0];i=parseInt(t)}else i=parseInt(n);a>=1&&(x=a),i>=1&&(_=i)},autoWrap:S,setWrap:function(t){g=t},getC4ShapeArray:E,getC4Shape:function(t){return h.find((e=>e.alias===t))},getC4ShapeKeys:function(t){return Object.keys(E(t))},getBoundaries:A,getBoundarys:A,getCurrentBoundaryParse:function(){return u},getParentBoundaryParse:function(){return p},getRels:function(){return f},getTitle:function(){return b},getC4Type:function(){return m},getC4ShapeInRow:function(){return x},getC4BoundaryInRow:function(){return _},setAccTitle:a.s,getAccTitle:a.g,getAccDescription:a.a,setAccDescription:a.b,getConfig:()=>(0,a.c)().c4,clear:function(){h=[],y=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],p="",u="global",d=[""],f=[],d=[""],b="",g=!1,x=4,_=2},LINETYPE:{SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25},ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},setTitle:function(t){let e=(0,a.d)(t,(0,a.c)());b=e},setC4Type:function(t){let e=(0,a.d)(t,(0,a.c)());m=e}},k=function(t,e){return(0,s.d)(t,e)},O=function(t,e,n,a,i,s){const l=t.append("image");l.attr("width",e),l.attr("height",n),l.attr("x",a),l.attr("y",i);let o=s.startsWith("data:image/png;base64")?s:(0,r.Jf)(s);l.attr("xlink:href",o)},v=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),T=function(){function t(t,e,n,a,s,r,l){i(e.append("text").attr("x",n+s/2).attr("y",a+r/2+5).style("text-anchor","middle").text(t),l)}function e(t,e,n,s,r,l,o,c){const{fontSize:h,fontFamily:d,fontWeight:u}=c,p=t.split(a.e.lineBreakRegex);for(let a=0;a<p.length;a++){const t=a*h-h*(p.length-1)/2,l=e.append("text").attr("x",n+r/2).attr("y",s).style("text-anchor","middle").attr("dominant-baseline","middle").style("font-size",h).style("font-weight",u).style("font-family",d);l.append("tspan").attr("dy",t).text(p[a]).attr("alignment-baseline","mathematical"),i(l,o)}}function n(t,n,a,s,r,l,o,c){const h=n.append("switch"),d=h.append("foreignObject").attr("x",a).attr("y",s).attr("width",r).attr("height",l).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");d.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,a,s,r,0,o,c),i(d,o)}function i(t,e){for(const n in e)e.hasOwnProperty(n)&&t.attr(n,e[n])}return function(a){return"fo"===a.textPlacement?n:"old"===a.textPlacement?t:e}}(),w=function(t,e,n){const a=t.append("g");let i=e.bgColor?e.bgColor:"none",s=e.borderColor?e.borderColor:"#444444",r=e.fontColor?e.fontColor:"black",l={"stroke-width":1,"stroke-dasharray":"7.0,7.0"};e.nodeType&&(l={"stroke-width":1});let o={x:e.x,y:e.y,fill:i,stroke:s,width:e.width,height:e.height,rx:2.5,ry:2.5,attrs:l};k(a,o);let c=n.boundaryFont();c.fontWeight="bold",c.fontSize=c.fontSize+2,c.fontColor=r,T(n)(e.label.text,a,e.x,e.y+e.label.Y,e.width,e.height,{fill:"#444444"},c),e.type&&""!==e.type.text&&(c=n.boundaryFont(),c.fontColor=r,T(n)(e.type.text,a,e.x,e.y+e.type.Y,e.width,e.height,{fill:"#444444"},c)),e.descr&&""!==e.descr.text&&(c=n.boundaryFont(),c.fontSize=c.fontSize-2,c.fontColor=r,T(n)(e.descr.text,a,e.x,e.y+e.descr.Y,e.width,e.height,{fill:"#444444"},c))},R=function(t,e,n){var a;let i=e.bgColor?e.bgColor:n[e.typeC4Shape.text+"_bg_color"],r=e.borderColor?e.borderColor:n[e.typeC4Shape.text+"_border_color"],l=e.fontColor?e.fontColor:"#FFFFFF",o="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";switch(e.typeC4Shape.text){case"person":o="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";break;case"external_person":o="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAB6ElEQVR4Xu2YLY+EMBCG9+dWr0aj0Wg0Go1Go0+j8Xdv2uTCvv1gpt0ebHKPuhDaeW4605Z9mJvx4AdXUyTUdd08z+u6flmWZRnHsWkafk9DptAwDPu+f0eAYtu2PEaGWuj5fCIZrBAC2eLBAnRCsEkkxmeaJp7iDJ2QMDdHsLg8SxKFEJaAo8lAXnmuOFIhTMpxxKATebo4UiFknuNo4OniSIXQyRxEA3YsnjGCVEjVXD7yLUAqxBGUyPv/Y4W2beMgGuS7kVQIBycH0fD+oi5pezQETxdHKmQKGk1eQEYldK+jw5GxPfZ9z7Mk0Qnhf1W1m3w//EUn5BDmSZsbR44QQLBEqrBHqOrmSKaQAxdnLArCrxZcM7A7ZKs4ioRq8LFC+NpC3WCBJsvpVw5edm9iEXFuyNfxXAgSwfrFQ1c0iNda8AdejvUgnktOtJQQxmcfFzGglc5WVCj7oDgFqU18boeFSs52CUh8LE8BIVQDT1ABrB0HtgSEYlX5doJnCwv9TXocKCaKbnwhdDKPq4lf3SwU3HLq4V/+WYhHVMa/3b4IlfyikAduCkcBc7mQ3/z/Qq/cTuikhkzB12Ae/mcJC9U+Vo8Ej1gWAtgbeGgFsAMHr50BIWOLCbezvhpBFUdY6EJuJ/QDW0XoMX60zZ0AAAAASUVORK5CYII="}const c=t.append("g");c.attr("class","person-man");const h=(0,s.g)();switch(e.typeC4Shape.text){case"person":case"external_person":case"system":case"external_system":case"container":case"external_container":case"component":case"external_component":h.x=e.x,h.y=e.y,h.fill=i,h.width=e.width,h.height=e.height,h.stroke=r,h.rx=2.5,h.ry=2.5,h.attrs={"stroke-width":.5},k(c,h);break;case"system_db":case"external_system_db":case"container_db":case"external_container_db":case"component_db":case"external_component_db":c.append("path").attr("fill",i).attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc0,-10 half,-10 half,-10c0,0 half,0 half,10l0,heightc0,10 -half,10 -half,10c0,0 -half,0 -half,-10l0,-height".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2).replaceAll("height",e.height)),c.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc0,10 half,10 half,10c0,0 half,0 half,-10".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2));break;case"system_queue":case"external_system_queue":case"container_queue":case"external_container_queue":case"component_queue":case"external_component_queue":c.append("path").attr("fill",i).attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startylwidth,0c5,0 5,half 5,halfc0,0 0,half -5,halfl-width,0c-5,0 -5,-half -5,-halfc0,0 0,-half 5,-half".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("width",e.width).replaceAll("half",e.height/2)),c.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc-5,0 -5,half -5,halfc0,half 5,half 5,half".replaceAll("startx",e.x+e.width).replaceAll("starty",e.y).replaceAll("half",e.height/2))}let d=v(n,e.typeC4Shape.text);switch(c.append("text").attr("fill",l).attr("font-family",d.fontFamily).attr("font-size",d.fontSize-2).attr("font-style","italic").attr("lengthAdjust","spacing").attr("textLength",e.typeC4Shape.width).attr("x",e.x+e.width/2-e.typeC4Shape.width/2).attr("y",e.y+e.typeC4Shape.Y).text("<<"+e.typeC4Shape.text+">>"),e.typeC4Shape.text){case"person":case"external_person":O(c,48,48,e.x+e.width/2-24,e.y+e.image.Y,o)}let u=n[e.typeC4Shape.text+"Font"]();return u.fontWeight="bold",u.fontSize=u.fontSize+2,u.fontColor=l,T(n)(e.label.text,c,e.x,e.y+e.label.Y,e.width,e.height,{fill:l},u),u=n[e.typeC4Shape.text+"Font"](),u.fontColor=l,e.techn&&""!==(null==(a=e.techn)?void 0:a.text)?T(n)(e.techn.text,c,e.x,e.y+e.techn.Y,e.width,e.height,{fill:l,"font-style":"italic"},u):e.type&&""!==e.type.text&&T(n)(e.type.text,c,e.x,e.y+e.type.Y,e.width,e.height,{fill:l,"font-style":"italic"},u),e.descr&&""!==e.descr.text&&(u=n.personFont(),u.fontColor=l,T(n)(e.descr.text,c,e.x,e.y+e.descr.Y,e.width,e.height,{fill:l},u)),e.height},D=(t,e,n)=>{const a=t.append("g");let i=0;for(let s of e){let t=s.textColor?s.textColor:"#444444",e=s.lineColor?s.lineColor:"#444444",r=s.offsetX?parseInt(s.offsetX):0,l=s.offsetY?parseInt(s.offsetY):0,o="";if(0===i){let t=a.append("line");t.attr("x1",s.startPoint.x),t.attr("y1",s.startPoint.y),t.attr("x2",s.endPoint.x),t.attr("y2",s.endPoint.y),t.attr("stroke-width","1"),t.attr("stroke",e),t.style("fill","none"),"rel_b"!==s.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==s.type&&"rel_b"!==s.type||t.attr("marker-start","url("+o+"#arrowend)"),i=-1}else{let t=a.append("path");t.attr("fill","none").attr("stroke-width","1").attr("stroke",e).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",s.startPoint.x).replaceAll("starty",s.startPoint.y).replaceAll("controlx",s.startPoint.x+(s.endPoint.x-s.startPoint.x)/2-(s.endPoint.x-s.startPoint.x)/4).replaceAll("controly",s.startPoint.y+(s.endPoint.y-s.startPoint.y)/2).replaceAll("stopx",s.endPoint.x).replaceAll("stopy",s.endPoint.y)),"rel_b"!==s.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==s.type&&"rel_b"!==s.type||t.attr("marker-start","url("+o+"#arrowend)")}let c=n.messageFont();T(n)(s.label.text,a,Math.min(s.startPoint.x,s.endPoint.x)+Math.abs(s.endPoint.x-s.startPoint.x)/2+r,Math.min(s.startPoint.y,s.endPoint.y)+Math.abs(s.endPoint.y-s.startPoint.y)/2+l,s.label.width,s.label.height,{fill:t},c),s.techn&&""!==s.techn.text&&(c=n.messageFont(),T(n)("["+s.techn.text+"]",a,Math.min(s.startPoint.x,s.endPoint.x)+Math.abs(s.endPoint.x-s.startPoint.x)/2+r,Math.min(s.startPoint.y,s.endPoint.y)+Math.abs(s.endPoint.y-s.startPoint.y)/2+n.messageFontSize+5+l,Math.max(s.label.width,s.techn.width),s.techn.height,{fill:t,"font-style":"italic"},c))}},N=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},P=function(t){t.append("defs").append("marker").attr("id","arrowend").attr("refX",1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z")},M=function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},j=function(t){const e=t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);e.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),e.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")},B=function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},L=function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},Y=function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")};let I=0,U=0,F=4,X=2;l.yy=C;let z={};class W{constructor(t){this.name="",this.data={},this.data.startx=void 0,this.data.stopx=void 0,this.data.starty=void 0,this.data.stopy=void 0,this.data.widthLimit=void 0,this.nextData={},this.nextData.startx=void 0,this.nextData.stopx=void 0,this.nextData.starty=void 0,this.nextData.stopy=void 0,this.nextData.cnt=0,Q(t.db.getConfig())}setData(t,e,n,a){this.nextData.startx=this.data.startx=t,this.nextData.stopx=this.data.stopx=e,this.nextData.starty=this.data.starty=n,this.nextData.stopy=this.data.stopy=a}updateVal(t,e,n,a){void 0===t[e]?t[e]=n:t[e]=a(n,t[e])}insert(t){this.nextData.cnt=this.nextData.cnt+1;let e=this.nextData.startx===this.nextData.stopx?this.nextData.stopx+t.margin:this.nextData.stopx+2*t.margin,n=e+t.width,a=this.nextData.starty+2*t.margin,i=a+t.height;(e>=this.data.widthLimit||n>=this.data.widthLimit||this.nextData.cnt>F)&&(e=this.nextData.startx+t.margin+z.nextLinePaddingX,a=this.nextData.stopy+2*t.margin,this.nextData.stopx=n=e+t.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=i=a+t.height,this.nextData.cnt=1),t.x=e,t.y=a,this.updateVal(this.data,"startx",e,Math.min),this.updateVal(this.data,"starty",a,Math.min),this.updateVal(this.data,"stopx",n,Math.max),this.updateVal(this.data,"stopy",i,Math.max),this.updateVal(this.nextData,"startx",e,Math.min),this.updateVal(this.nextData,"starty",a,Math.min),this.updateVal(this.nextData,"stopx",n,Math.max),this.updateVal(this.nextData,"stopy",i,Math.max)}init(t){this.name="",this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,widthLimit:void 0},this.nextData={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,cnt:0},Q(t.db.getConfig())}bumpLastMargin(t){this.data.stopx+=t,this.data.stopy+=t}}const Q=function(t){(0,a.f)(z,t),t.fontFamily&&(z.personFontFamily=z.systemFontFamily=z.messageFontFamily=t.fontFamily),t.fontSize&&(z.personFontSize=z.systemFontSize=z.messageFontSize=t.fontSize),t.fontWeight&&(z.personFontWeight=z.systemFontWeight=z.messageFontWeight=t.fontWeight)},$=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),q=t=>({fontFamily:t.boundaryFontFamily,fontSize:t.boundaryFontSize,fontWeight:t.boundaryFontWeight});function V(t,e,n,i,s){if(!e[t].width)if(n)e[t].text=(0,a.w)(e[t].text,s,i),e[t].textLines=e[t].text.split(a.e.lineBreakRegex).length,e[t].width=s,e[t].height=(0,a.j)(e[t].text,i);else{let n=e[t].text.split(a.e.lineBreakRegex);e[t].textLines=n.length;let s=0;e[t].height=0,e[t].width=0;for(const r of n)e[t].width=Math.max((0,a.h)(r,i),e[t].width),s=(0,a.j)(r,i),e[t].height=e[t].height+s}}const G=function(t,e,n){e.x=n.data.startx,e.y=n.data.starty,e.width=n.data.stopx-n.data.startx,e.height=n.data.stopy-n.data.starty,e.label.y=z.c4ShapeMargin-35;let i=e.wrap&&z.wrap,s=q(z);s.fontSize=s.fontSize+2,s.fontWeight="bold",V("label",e,i,s,(0,a.h)(e.label.text,s)),w(t,e,z)},H=function(t,e,n,i){let s=0;for(const r of i){s=0;const i=n[r];let l=$(z,i.typeC4Shape.text);switch(l.fontSize=l.fontSize-2,i.typeC4Shape.width=(0,a.h)("\xab"+i.typeC4Shape.text+"\xbb",l),i.typeC4Shape.height=l.fontSize+2,i.typeC4Shape.Y=z.c4ShapePadding,s=i.typeC4Shape.Y+i.typeC4Shape.height-4,i.image={width:0,height:0,Y:0},i.typeC4Shape.text){case"person":case"external_person":i.image.width=48,i.image.height=48,i.image.Y=s,s=i.image.Y+i.image.height}i.sprite&&(i.image.width=48,i.image.height=48,i.image.Y=s,s=i.image.Y+i.image.height);let o=i.wrap&&z.wrap,c=z.width-2*z.c4ShapePadding,h=$(z,i.typeC4Shape.text);if(h.fontSize=h.fontSize+2,h.fontWeight="bold",V("label",i,o,h,c),i.label.Y=s+8,s=i.label.Y+i.label.height,i.type&&""!==i.type.text){i.type.text="["+i.type.text+"]",V("type",i,o,$(z,i.typeC4Shape.text),c),i.type.Y=s+5,s=i.type.Y+i.type.height}else if(i.techn&&""!==i.techn.text){i.techn.text="["+i.techn.text+"]",V("techn",i,o,$(z,i.techn.text),c),i.techn.Y=s+5,s=i.techn.Y+i.techn.height}let d=s,u=i.label.width;if(i.descr&&""!==i.descr.text){V("descr",i,o,$(z,i.typeC4Shape.text),c),i.descr.Y=s+20,s=i.descr.Y+i.descr.height,u=Math.max(i.label.width,i.descr.width),d=s-5*i.descr.textLines}u+=z.c4ShapePadding,i.width=Math.max(i.width||z.width,u,z.width),i.height=Math.max(i.height||z.height,d,z.height),i.margin=i.margin||z.c4ShapeMargin,t.insert(i),R(e,i,z)}t.bumpLastMargin(z.c4ShapeMargin)};class K{constructor(t,e){this.x=t,this.y=e}}let J=function(t,e){let n=t.x,a=t.y,i=e.x,s=e.y,r=n+t.width/2,l=a+t.height/2,o=Math.abs(n-i),c=Math.abs(a-s),h=c/o,d=t.height/t.width,u=null;return a==s&&n<i?u=new K(n+t.width,l):a==s&&n>i?u=new K(n,l):n==i&&a<s?u=new K(r,a+t.height):n==i&&a>s&&(u=new K(r,a)),n>i&&a<s?u=d>=h?new K(n,l+h*t.width/2):new K(r-o/c*t.height/2,a+t.height):n<i&&a<s?u=d>=h?new K(n+t.width,l+h*t.width/2):new K(r+o/c*t.height/2,a+t.height):n<i&&a>s?u=d>=h?new K(n+t.width,l-h*t.width/2):new K(r+t.height/2*o/c,a):n>i&&a>s&&(u=d>=h?new K(n,l-t.width/2*h):new K(r-t.height/2*o/c,a)),u},Z=function(t,e){let n={x:0,y:0};n.x=e.x+e.width/2,n.y=e.y+e.height/2;let a=J(t,n);return n.x=t.x+t.width/2,n.y=t.y+t.height/2,{startPoint:a,endPoint:J(e,n)}};function tt(t,e,n,a,i){let s=new W(i);s.data.widthLimit=n.data.widthLimit/Math.min(X,a.length);for(let[r,l]of a.entries()){let a=0;l.image={width:0,height:0,Y:0},l.sprite&&(l.image.width=48,l.image.height=48,l.image.Y=a,a=l.image.Y+l.image.height);let o=l.wrap&&z.wrap,c=q(z);if(c.fontSize=c.fontSize+2,c.fontWeight="bold",V("label",l,o,c,s.data.widthLimit),l.label.Y=a+8,a=l.label.Y+l.label.height,l.type&&""!==l.type.text){l.type.text="["+l.type.text+"]",V("type",l,o,q(z),s.data.widthLimit),l.type.Y=a+5,a=l.type.Y+l.type.height}if(l.descr&&""!==l.descr.text){let t=q(z);t.fontSize=t.fontSize-2,V("descr",l,o,t,s.data.widthLimit),l.descr.Y=a+20,a=l.descr.Y+l.descr.height}if(0==r||r%X==0){let t=n.data.startx+z.diagramMarginX,e=n.data.stopy+z.diagramMarginY+a;s.setData(t,t,e,e)}else{let t=s.data.stopx!==s.data.startx?s.data.stopx+z.diagramMarginX:s.data.startx,e=s.data.starty;s.setData(t,t,e,e)}s.name=l.alias;let h=i.db.getC4ShapeArray(l.alias),d=i.db.getC4ShapeKeys(l.alias);d.length>0&&H(s,t,h,d),e=l.alias;let u=i.db.getBoundarys(e);u.length>0&&tt(t,e,s,u,i),"global"!==l.alias&&G(t,l,s),n.data.stopy=Math.max(s.data.stopy+z.c4ShapeMargin,n.data.stopy),n.data.stopx=Math.max(s.data.stopx+z.c4ShapeMargin,n.data.stopx),I=Math.max(I,n.data.stopx),U=Math.max(U,n.data.stopy)}}const et={drawPersonOrSystemArray:H,drawBoundary:G,setConf:Q,draw:function(t,e,n,s){z=(0,a.c)().c4;const r=(0,a.c)().securityLevel;let l;"sandbox"===r&&(l=(0,i.Ltv)("#i"+e));const o="sandbox"===r?(0,i.Ltv)(l.nodes()[0].contentDocument.body):(0,i.Ltv)("body");let c=s.db;s.db.setWrap(z.wrap),F=c.getC4ShapeInRow(),X=c.getC4BoundaryInRow(),a.l.debug(`C:${JSON.stringify(z,null,2)}`);const h="sandbox"===r?o.select(`[id="${e}"]`):(0,i.Ltv)(`[id="${e}"]`);L(h),B(h),Y(h);let d=new W(s);d.setData(z.diagramMarginX,z.diagramMarginX,z.diagramMarginY,z.diagramMarginY),d.data.widthLimit=screen.availWidth,I=z.diagramMarginX,U=z.diagramMarginY;const u=s.db.getTitle();tt(h,"",d,s.db.getBoundarys(""),s),N(h),P(h),j(h),M(h),function(t,e,n,i){let s=0;for(let l of e){s+=1;let t=l.wrap&&z.wrap,e={fontFamily:(r=z).messageFontFamily,fontSize:r.messageFontSize,fontWeight:r.messageFontWeight};"C4Dynamic"===i.db.getC4Type()&&(l.label.text=s+": "+l.label.text);let o=(0,a.h)(l.label.text,e);V("label",l,t,e,o),l.techn&&""!==l.techn.text&&(o=(0,a.h)(l.techn.text,e),V("techn",l,t,e,o)),l.descr&&""!==l.descr.text&&(o=(0,a.h)(l.descr.text,e),V("descr",l,t,e,o));let c=n(l.from),h=n(l.to),d=Z(c,h);l.startPoint=d.startPoint,l.endPoint=d.endPoint}var r;D(t,e,z)}(h,s.db.getRels(),s.db.getC4Shape,s),d.data.stopx=I,d.data.stopy=U;const p=d.data;let y=p.stopy-p.starty+2*z.diagramMarginY;const f=p.stopx-p.startx+2*z.diagramMarginX;u&&h.append("text").text(u).attr("x",(p.stopx-p.startx)/2-4*z.diagramMarginX).attr("y",p.starty+z.diagramMarginY),(0,a.i)(h,y,f,z.useMaxWidth);const b=u?60:0;h.attr("viewBox",p.startx-z.diagramMarginX+" -"+(z.diagramMarginY+b)+" "+f+" "+(y+b)),a.l.debug("models:",p)}},nt={parser:o,db:C,renderer:et,styles:t=>`.person {\n stroke: ${t.personBorder};\n fill: ${t.personBkg};\n }\n`,init:({c4:t,wrap:e})=>{et.setConf(t),C.setWrap(e)}}},79186:(t,e,n)=>{n.d(e,{a:()=>r,b:()=>c,c:()=>o,d:()=>s,e:()=>d,f:()=>l,g:()=>h});var a=n(16750),i=n(86079);const s=(t,e)=>{const n=t.append("rect");if(n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),e.name&&n.attr("name",e.name),void 0!==e.rx&&n.attr("rx",e.rx),void 0!==e.ry&&n.attr("ry",e.ry),void 0!==e.attrs)for(const a in e.attrs)n.attr(a,e.attrs[a]);return void 0!==e.class&&n.attr("class",e.class),n},r=(t,e)=>{const n={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};s(t,n).lower()},l=(t,e)=>{const n=e.text.replace(i.J," "),a=t.append("text");a.attr("x",e.x),a.attr("y",e.y),a.attr("class","legend"),a.style("text-anchor",e.anchor),void 0!==e.class&&a.attr("class",e.class);const s=a.append("tspan");return s.attr("x",e.x+2*e.textMargin),s.text(n),a},o=(t,e,n,i)=>{const s=t.append("image");s.attr("x",e),s.attr("y",n);const r=(0,a.Jf)(i);s.attr("xlink:href",r)},c=(t,e,n,i)=>{const s=t.append("use");s.attr("x",e),s.attr("y",n);const r=(0,a.Jf)(i);s.attr("xlink:href",`#${r}`)},h=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),d=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})}}]); \ No newline at end of file diff --git a/assets/js/53cbe722.bc1489ef.js b/assets/js/53cbe722.bc1489ef.js new file mode 100644 index 0000000000..140740d70d --- /dev/null +++ b/assets/js/53cbe722.bc1489ef.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[67768],{60210:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>p});const a=JSON.parse('{"id":"operating-scs/components/status-page-deployment/docs/admin-authentication","title":"Admin authentication","description":"As the write operations of the API server are protected by Oathkeeper and use identities provided by Dex an Administrator is considered to be a person that can authenticate on Dex.","source":"@site/docs/04-operating-scs/components/status-page-deployment/docs/admin-authentication.md","sourceDirName":"04-operating-scs/components/status-page-deployment/docs","slug":"/operating-scs/components/status-page-deployment/docs/admin-authentication","permalink":"/docs/operating-scs/components/status-page-deployment/docs/admin-authentication","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-deployment/docs/admin-authentication.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Contribute","permalink":"/docs/operating-scs/components/status-page-deployment/docs/contribute"},"next":{"title":"FAQ","permalink":"/docs/operating-scs/components/status-page-deployment/docs/faq"}}');var s=n(74848),i=n(28453);const o={},r="Admin authentication",d={},p=[];function c(e){const t={a:"a",h1:"h1",header:"header",mermaid:"mermaid",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"admin-authentication",children:"Admin authentication"})}),"\n",(0,s.jsxs)(t.p,{children:["As the write operations of the ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-api",children:"API server"})," are protected by ",(0,s.jsx)(t.a,{href:"https://www.ory.sh/docs/oathkeeper",children:"Oathkeeper"})," and use identities provided by ",(0,s.jsx)(t.a,{href:"https://dexidp.io/",children:"Dex"})," an Administrator is considered to be a person that can authenticate on Dex."]}),"\n",(0,s.jsx)(t.p,{children:"On the public SCS deployment, these persons are members of the SovereignCloudStack organization."}),"\n",(0,s.jsx)(t.p,{children:"This sequence diagram displays a simplified flow how an administrator authenticates himself with Dex and GitHub, to authorize using the write operations."}),"\n",(0,s.jsx)(t.mermaid,{value:"sequenceDiagram\nactor admin as Admin\nparticipant useragent as User Agent\nparticipant web as Web Frontend\nparticipant dex as Dex IdP\nparticipant idp as Upstream IdP\nparticipant oathkeeper as Oathkeeper\nparticipant api as API Server\nparticipant db as API Database\n\nadmin->>useragent: enters status page url\nuseragent->>web: request status page\nnote over web: simplified\nweb--\x3e>useragent: app view\nuseragent--\x3e>admin: presents app view\n\nrect rgba(0,127,255,0.8)\n note right of admin: Login\n admin->>useragent: enters login flow\n useragent->>web: login request\n web->>dex: login request\n dex->>idp: actual login\n idp--\x3e>dex: user info\n dex--\x3e>web: id-token\n web--\x3e>useragent: login successful\n useragent--\x3e>admin: login successful\nend\n\nrect rgba(64,127,0, 0.8)\n note right of admin: Authenticated Request\n admin->>useragent: enters operation\n useragent->>web: operation request\n web->>+oathkeeper: operation request with id-token\n oathkeeper->>dex: id-token verification\n dex--\x3e>oathkeeper: verified\n oathkeeper->>api: proxy operation request\n api->>db: request data\n db--\x3e>api: data\n api--\x3e>oathkeeper: data\n oathkeeper--\x3e>-web: data\n web--\x3e>useragent: data\n useragent--\x3e>admin: presents new data\nend"})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var a=n(96540);const s={},i=a.createContext(s);function o(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/53f25e30.1cfdd75b.js b/assets/js/53f25e30.1cfdd75b.js new file mode 100644 index 0000000000..5b1739e10b --- /dev/null +++ b/assets/js/53f25e30.1cfdd75b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[80332],{53478:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>s,toc:()=>u});const s=JSON.parse('{"id":"operating-scs/components/monitoring/docs/infrastructure_services","title":"Infrastructure service endpoints","description":"This page contains instructions on how to enable probing of infrastructure service endpoints using blackbox exporter.","source":"@site/docs/04-operating-scs/components/monitoring/docs/infrastructure_services.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/infrastructure_services","permalink":"/docs/operating-scs/components/monitoring/docs/infrastructure_services","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/infrastructure_services.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"K3s support","permalink":"/docs/operating-scs/components/monitoring/docs/k3s"},"next":{"title":"IaaS monitoring (experimental)","permalink":"/docs/operating-scs/components/monitoring/docs/iaas"}}');var o=t(74848),r=t(28453);const c={},i="Infrastructure service endpoints",a={},u=[];function d(e){const n={a:"a",code:"code",h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"infrastructure-service-endpoints",children:"Infrastructure service endpoints"})}),"\n",(0,o.jsxs)(n.p,{children:["This page contains instructions on how to enable probing of infrastructure service endpoints using ",(0,o.jsx)(n.a,{href:"https://github.com/prometheus/blackbox_exporter",children:"blackbox exporter"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"Infrastructure service endpoints can be probed using protocols such as HTTP, HTTPS, DNS, TCP, ICMP, and gRPC."}),"\n",(0,o.jsxs)(n.p,{children:["Blackbox exporter is a component of the ",(0,o.jsx)(n.a,{href:"https://github.com/dNationCloud/kubernetes-monitoring-stack",children:"monitoring stack"}),".\nTherefore, it can be deployed into the Observer cluster and configured simply by using the Helm chart values."]}),"\n",(0,o.jsxs)(n.p,{children:["To enable probing of infrastructure service endpoints with blackbox exporter, locate and uncomment the related section in ",(0,o.jsx)(n.code,{children:"values-observer.yaml"}),".\nThe sections related to blackbox exporter in the ",(0,o.jsx)(n.code,{children:"values-observer-scs.yaml"})," values file are already uncommented."]})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var s=t(96540);const o={},r=s.createContext(o);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/54451aca.cfaeb709.js b/assets/js/54451aca.cfaeb709.js new file mode 100644 index 0000000000..15ac2358f2 --- /dev/null +++ b/assets/js/54451aca.cfaeb709.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1591],{42287:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"kaas/scs-0219","title":"scs-0219: KaaS Networking Standard","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/kaas/scs-0219.md","sourceDirName":"kaas","slug":"/kaas/scs-0219","permalink":"/standards/kaas/scs-0219","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation"},"next":{"title":"V1","permalink":"/standards/scs-0219-v1-kaas-networking"}}');var r=s(74848),a=s(28453);const d={},i="scs-0219: KaaS Networking Standard",c={},l=[{value:"Supplement: Implementation Notes",id:"supplement-implementation-notes",level:2}];function o(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0219-kaas-networking-standard",children:"scs-0219: KaaS Networking Standard"})}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0219-v1-kaas-networking",children:"scs-0219-v1"})}),(0,r.jsx)(t.td,{children:"Standard"}),(0,r.jsx)(t.td,{children:"Stable"}),(0,r.jsx)(t.td,{children:"2024-11-21"}),(0,r.jsx)(t.td,{children:"-"})]})})]}),"\n",(0,r.jsx)(t.h2,{id:"supplement-implementation-notes",children:"Supplement: Implementation Notes"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0219-w1-kaas-networking",children:"w1"})}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>i});var n=s(96540);const r={},a=n.createContext(r);function d(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5447d460.3fb8c19c.js b/assets/js/5447d460.3fb8c19c.js new file mode 100644 index 0000000000..01dca3056e --- /dev/null +++ b/assets/js/5447d460.3fb8c19c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[83881],{30960:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>p,frontMatter:()=>o,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"certification/scopes-versions","title":"Scopes and versions","description":"SCS provides a certification framework consisting of six different kinds of certificates of varying scope.","source":"@site/standards/certification/scopes-versions.md","sourceDirName":"certification","slug":"/certification/scopes-versions","permalink":"/standards/certification/scopes-versions","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"overview","permalink":"/standards/certification/overview"},"next":{"title":"SCS-compatible IaaS","permalink":"/standards/scs-compatible-iaas"}}');var t=n(74848),r=n(28453);const o={},c="Scopes and versions",a={},d=[];function l(e){const s={em:"em",h1:"h1",header:"header",img:"img",li:"li",ol:"ol",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"scopes-and-versions",children:"Scopes and versions"})}),"\n",(0,t.jsx)(s.p,{children:"SCS provides a certification framework consisting of six different kinds of certificates of varying scope.\nThese scopes can be sorted into two dimensions:"}),"\n",(0,t.jsxs)(s.ol,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.em,{children:"certification level"}),", of which there are three:","\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"SCS-compatible"}),"\n",(0,t.jsx)(s.li,{children:"SCS-open"}),"\n",(0,t.jsx)(s.li,{children:"SCS-sovereign"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.em,{children:"cloud layer"}),", of which there are two:","\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"infastructure as a service (IaaS)"}),"\n",(0,t.jsx)(s.li,{children:"Kubernetes as a service (KaaS)"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(s.p,{children:["So, for instance, a certificate can have the scope ",(0,t.jsx)(s.em,{children:"SCS-compatible IaaS"})," or ",(0,t.jsx)(s.em,{children:"SCS-sovereign KaaS"}),"."]}),"\n",(0,t.jsx)(s.p,{children:"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."}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.img,{alt:"Alt text",src:n(39479).A+"",width:"2728",height:"742"})})]})}function p(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},39479:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/image-123702bb74539962d7c6839715583f29.png"},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>c});var i=n(96540);const t={},r=i.createContext(t);function o(e){const s=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5565c8ed.b7be1492.js b/assets/js/5565c8ed.b7be1492.js new file mode 100644 index 0000000000..bf56c5fb21 --- /dev/null +++ b/assets/js/5565c8ed.b7be1492.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[62016],{647:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>u,contentTitle:()=>a,default:()=>r,frontMatter:()=>d,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"iaas/guides/deploy-guide/examples/cloud-in-a-box","title":"Cloud in a Box","description":"This section has moved. You can now find the content in the","source":"@site/docs/02-iaas/guides/deploy-guide/examples/cloud-in-a-box.md","sourceDirName":"02-iaas/guides/deploy-guide/examples","slug":"/iaas/guides/deploy-guide/examples/cloud-in-a-box","permalink":"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/examples/cloud-in-a-box.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Cloud in a Box"},"sidebar":"docs","previous":{"title":"Examples","permalink":"/docs/iaas/guides/deploy-guide/examples/"},"next":{"title":"Testbed","permalink":"/docs/iaas/guides/deploy-guide/examples/testbed"}}');var i=n(74848),t=n(28453);const d={sidebar_label:"Cloud in a Box"},a="Cloud in a Box",u={},c=[];function l(e){const o={a:"a",h1:"h1",header:"header",p:"p",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(o.header,{children:(0,i.jsx)(o.h1,{id:"cloud-in-a-box",children:"Cloud in a Box"})}),"\n",(0,i.jsxs)(o.p,{children:["This section has moved. You can now find the content in the\n",(0,i.jsx)(o.a,{href:"../../other-guides",children:"Other Guides"})," as\n",(0,i.jsx)(o.a,{href:"../../other-guides/cloud-in-a-box",children:"Cloud in a Box Guide"}),"."]})]})}function r(e={}){const{wrapper:o}={...(0,t.R)(),...e.components};return o?(0,i.jsx)(o,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,o,n)=>{n.d(o,{R:()=>d,x:()=>a});var s=n(96540);const i={},t=s.createContext(i);function d(e){const o=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function a(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),s.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/55e21dcd.9036e01a.js b/assets/js/55e21dcd.9036e01a.js new file mode 100644 index 0000000000..6ce71718f4 --- /dev/null +++ b/assets/js/55e21dcd.9036e01a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[31810],{59684:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>g,frontMatter:()=>r,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"operating-scs/components/monitoring/docs/tracing","title":"Traces","description":"This page contains a guide on how to enable traces in Thanos. Traces are not enabled by default.","source":"@site/docs/04-operating-scs/components/monitoring/docs/tracing.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/tracing","permalink":"/docs/operating-scs/components/monitoring/docs/tracing","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/tracing.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"OAUTH","permalink":"/docs/operating-scs/components/monitoring/docs/oauth"},"next":{"title":"Tuning","permalink":"/docs/operating-scs/components/monitoring/docs/tuning"}}');var a=t(74848),s=t(28453);const r={},i="Traces",c={},l=[{value:"Example",id:"example",level:2},{value:"Usage",id:"usage",level:2}];function d(e){const n={code:"code",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"traces",children:"Traces"})}),"\n",(0,a.jsx)(n.p,{children:"This page contains a guide on how to enable traces in Thanos. Traces are not enabled by default."}),"\n",(0,a.jsxs)(n.p,{children:["Thanos supports different tracing backends that implements ",(0,a.jsx)(n.code,{children:"opentracing.Tracer"})," interface.\nAll clients could be configured by ",(0,a.jsx)(n.code,{children:"--tracing.config-file"})," parameter to reference to the configuration file or by ",(0,a.jsx)(n.code,{children:"--tracing.config"}),"\nparameter to put yaml config directly. Recommended way is to pass configuration directly as it gives an explicit static view of\nconfiguration for each component, and it also saves you the fuss of creating and managing additional files."]}),"\n",(0,a.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,a.jsx)(n.p,{children:"Here is the example of the configuration how to enable jaeger in Thanos. This configuration can be applied for multiple components e.g. query-frontend, query or thanos-sidecar."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:'thanos:\n queryFrontend:\n extraFlags:\n - |-\n --tracing.config="config":\n "sampler_param": 2\n "sampler_type": "ratelimiting"\n "service_name": "thanos-query-frontend"\n "agent_host": "jaeger-agent.<namespace>.svc"\n "agent_port": 5775\n "type": "JAEGER"\n'})}),"\n",(0,a.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,a.jsxs)(n.p,{children:["Once tracing is enabled, Thanos will generate traces for all gRPC and HTTP APIs thanks to generic \u201cmiddlewares\u201d.\nSome more interesting to observe APIs like query or query_range have more low-level spans with focused metadata showing\nlatency for important functionalities. For example, Jaeger view of query_range HTTP API call might look as follows:\n",(0,a.jsx)(n.img,{alt:"Jaeger-example",src:t(62122).A+"",width:"1843",height:"903"})]})]})}function g(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},62122:(e,n,t)=>{t.d(n,{A:()=>o});const o=t.p+"assets/images/jaeger-91a4b48820447709f604d72c396cacf8.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var o=t(96540);const a={},s=o.createContext(a);function r(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/56625.4f3f2239.js b/assets/js/56625.4f3f2239.js new file mode 100644 index 0000000000..6c0a3e3492 --- /dev/null +++ b/assets/js/56625.4f3f2239.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[56625],{75937:(e,t,i)=>{i.d(t,{A:()=>r});var s=i(72453),n=i(74886);const r=(e,t)=>s.A.lang.round(n.A.parse(e)[t])},50053:(e,t,i)=>{i.d(t,{A:()=>n});var s=i(91641);const n=function(e){return(0,s.A)(e,4)}},56625:(e,t,i)=>{i.d(t,{diagram:()=>X});var s,n,r=i(86079),l=i(50053),o=i(75937),a=i(25582),c=i(88146),h=i(697),u=i(26312),d=(i(74353),i(16750),i(42838),function(){var e=function(e,t,i,s){for(i=i||{},s=e.length;s--;i[e[s]]=t);return i},t=[1,7],i=[1,13],s=[1,14],n=[1,15],r=[1,19],l=[1,16],o=[1,17],a=[1,18],c=[8,30],h=[8,21,28,29,30,31,32,40,44,47],u=[1,23],d=[1,24],g=[8,15,16,21,28,29,30,31,32,40,44,47],y=[8,15,16,21,27,28,29,30,31,32,40,44,47],p=[1,49],b={trace:function(){},yy:{},symbols_:{error:2,spaceLines:3,SPACELINE:4,NL:5,separator:6,SPACE:7,EOF:8,start:9,BLOCK_DIAGRAM_KEY:10,document:11,stop:12,statement:13,link:14,LINK:15,START_LINK:16,LINK_LABEL:17,STR:18,nodeStatement:19,columnsStatement:20,SPACE_BLOCK:21,blockStatement:22,classDefStatement:23,cssClassStatement:24,styleStatement:25,node:26,SIZE:27,COLUMNS:28,"id-block":29,end:30,block:31,NODE_ID:32,nodeShapeNLabel:33,dirList:34,DIR:35,NODE_DSTART:36,NODE_DEND:37,BLOCK_ARROW_START:38,BLOCK_ARROW_END:39,classDef:40,CLASSDEF_ID:41,CLASSDEF_STYLEOPTS:42,DEFAULT:43,class:44,CLASSENTITY_IDS:45,STYLECLASS:46,style:47,STYLE_ENTITY_IDS:48,STYLE_DEFINITION_DATA:49,$accept:0,$end:1},terminals_:{2:"error",4:"SPACELINE",5:"NL",7:"SPACE",8:"EOF",10:"BLOCK_DIAGRAM_KEY",15:"LINK",16:"START_LINK",17:"LINK_LABEL",18:"STR",21:"SPACE_BLOCK",27:"SIZE",28:"COLUMNS",29:"id-block",30:"end",31:"block",32:"NODE_ID",35:"DIR",36:"NODE_DSTART",37:"NODE_DEND",38:"BLOCK_ARROW_START",39:"BLOCK_ARROW_END",40:"classDef",41:"CLASSDEF_ID",42:"CLASSDEF_STYLEOPTS",43:"DEFAULT",44:"class",45:"CLASSENTITY_IDS",46:"STYLECLASS",47:"style",48:"STYLE_ENTITY_IDS",49:"STYLE_DEFINITION_DATA"},productions_:[0,[3,1],[3,2],[3,2],[6,1],[6,1],[6,1],[9,3],[12,1],[12,1],[12,2],[12,2],[11,1],[11,2],[14,1],[14,4],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[19,3],[19,2],[19,1],[20,1],[22,4],[22,3],[26,1],[26,2],[34,1],[34,2],[33,3],[33,4],[23,3],[23,3],[24,3],[25,3]],performAction:function(e,t,i,s,n,r,l){var o=r.length-1;switch(n){case 4:s.getLogger().debug("Rule: separator (NL) ");break;case 5:s.getLogger().debug("Rule: separator (Space) ");break;case 6:s.getLogger().debug("Rule: separator (EOF) ");break;case 7:s.getLogger().debug("Rule: hierarchy: ",r[o-1]),s.setHierarchy(r[o-1]);break;case 8:s.getLogger().debug("Stop NL ");break;case 9:s.getLogger().debug("Stop EOF ");break;case 10:s.getLogger().debug("Stop NL2 ");break;case 11:s.getLogger().debug("Stop EOF2 ");break;case 12:s.getLogger().debug("Rule: statement: ",r[o]),"number"==typeof r[o].length?this.$=r[o]:this.$=[r[o]];break;case 13:s.getLogger().debug("Rule: statement #2: ",r[o-1]),this.$=[r[o-1]].concat(r[o]);break;case 14:s.getLogger().debug("Rule: link: ",r[o],e),this.$={edgeTypeStr:r[o],label:""};break;case 15:s.getLogger().debug("Rule: LABEL link: ",r[o-3],r[o-1],r[o]),this.$={edgeTypeStr:r[o],label:r[o-1]};break;case 18:const t=parseInt(r[o]),i=s.generateId();this.$={id:i,type:"space",label:"",width:t,children:[]};break;case 23:s.getLogger().debug("Rule: (nodeStatement link node) ",r[o-2],r[o-1],r[o]," typestr: ",r[o-1].edgeTypeStr);const n=s.edgeStrToEdgeData(r[o-1].edgeTypeStr);this.$=[{id:r[o-2].id,label:r[o-2].label,type:r[o-2].type,directions:r[o-2].directions},{id:r[o-2].id+"-"+r[o].id,start:r[o-2].id,end:r[o].id,label:r[o-1].label,type:"edge",directions:r[o].directions,arrowTypeEnd:n,arrowTypeStart:"arrow_open"},{id:r[o].id,label:r[o].label,type:s.typeStr2Type(r[o].typeStr),directions:r[o].directions}];break;case 24:s.getLogger().debug("Rule: nodeStatement (abc88 node size) ",r[o-1],r[o]),this.$={id:r[o-1].id,label:r[o-1].label,type:s.typeStr2Type(r[o-1].typeStr),directions:r[o-1].directions,widthInColumns:parseInt(r[o],10)};break;case 25:s.getLogger().debug("Rule: nodeStatement (node) ",r[o]),this.$={id:r[o].id,label:r[o].label,type:s.typeStr2Type(r[o].typeStr),directions:r[o].directions,widthInColumns:1};break;case 26:s.getLogger().debug("APA123",this?this:"na"),s.getLogger().debug("COLUMNS: ",r[o]),this.$={type:"column-setting",columns:"auto"===r[o]?-1:parseInt(r[o])};break;case 27:s.getLogger().debug("Rule: id-block statement : ",r[o-2],r[o-1]),s.generateId(),this.$={...r[o-2],type:"composite",children:r[o-1]};break;case 28:s.getLogger().debug("Rule: blockStatement : ",r[o-2],r[o-1],r[o]);const l=s.generateId();this.$={id:l,type:"composite",label:"",children:r[o-1]};break;case 29:s.getLogger().debug("Rule: node (NODE_ID separator): ",r[o]),this.$={id:r[o]};break;case 30:s.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ",r[o-1],r[o]),this.$={id:r[o-1],label:r[o].label,typeStr:r[o].typeStr,directions:r[o].directions};break;case 31:s.getLogger().debug("Rule: dirList: ",r[o]),this.$=[r[o]];break;case 32:s.getLogger().debug("Rule: dirList: ",r[o-1],r[o]),this.$=[r[o-1]].concat(r[o]);break;case 33:s.getLogger().debug("Rule: nodeShapeNLabel: ",r[o-2],r[o-1],r[o]),this.$={typeStr:r[o-2]+r[o],label:r[o-1]};break;case 34:s.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ",r[o-3],r[o-2]," #3:",r[o-1],r[o]),this.$={typeStr:r[o-3]+r[o],label:r[o-2],directions:r[o-1]};break;case 35:case 36:this.$={type:"classDef",id:r[o-1].trim(),css:r[o].trim()};break;case 37:this.$={type:"applyClass",id:r[o-1].trim(),styleClass:r[o].trim()};break;case 38:this.$={type:"applyStyles",id:r[o-1].trim(),stylesStr:r[o].trim()}}},table:[{9:1,10:[1,2]},{1:[3]},{11:3,13:4,19:5,20:6,21:t,22:8,23:9,24:10,25:11,26:12,28:i,29:s,31:n,32:r,40:l,44:o,47:a},{8:[1,20]},e(c,[2,12],{13:4,19:5,20:6,22:8,23:9,24:10,25:11,26:12,11:21,21:t,28:i,29:s,31:n,32:r,40:l,44:o,47:a}),e(h,[2,16],{14:22,15:u,16:d}),e(h,[2,17]),e(h,[2,18]),e(h,[2,19]),e(h,[2,20]),e(h,[2,21]),e(h,[2,22]),e(g,[2,25],{27:[1,25]}),e(h,[2,26]),{19:26,26:12,32:r},{11:27,13:4,19:5,20:6,21:t,22:8,23:9,24:10,25:11,26:12,28:i,29:s,31:n,32:r,40:l,44:o,47:a},{41:[1,28],43:[1,29]},{45:[1,30]},{48:[1,31]},e(y,[2,29],{33:32,36:[1,33],38:[1,34]}),{1:[2,7]},e(c,[2,13]),{26:35,32:r},{32:[2,14]},{17:[1,36]},e(g,[2,24]),{11:37,13:4,14:22,15:u,16:d,19:5,20:6,21:t,22:8,23:9,24:10,25:11,26:12,28:i,29:s,31:n,32:r,40:l,44:o,47:a},{30:[1,38]},{42:[1,39]},{42:[1,40]},{46:[1,41]},{49:[1,42]},e(y,[2,30]),{18:[1,43]},{18:[1,44]},e(g,[2,23]),{18:[1,45]},{30:[1,46]},e(h,[2,28]),e(h,[2,35]),e(h,[2,36]),e(h,[2,37]),e(h,[2,38]),{37:[1,47]},{34:48,35:p},{15:[1,50]},e(h,[2,27]),e(y,[2,33]),{39:[1,51]},{34:52,35:p,39:[2,31]},{32:[2,15]},e(y,[2,34]),{39:[2,32]}],defaultActions:{20:[2,7],23:[2,14],50:[2,15],52:[2,32]},parseError:function(e,t){if(!t.recoverable){var i=new Error(e);throw i.hash=t,i}this.trace(e)},parse:function(e){var t=this,i=[0],s=[],n=[null],r=[],l=this.table,o="",a=0,c=0,h=r.slice.call(arguments,1),u=Object.create(this.lexer),d={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(d.yy[g]=this.yy[g]);u.setInput(e,d.yy),d.yy.lexer=u,d.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var y=u.yylloc;r.push(y);var p=u.options&&u.options.ranges;"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var b,x,L,S,f,m,_,k,E,w={};;){if(x=i[i.length-1],this.defaultActions[x]?L=this.defaultActions[x]:(null==b&&(E=void 0,"number"!=typeof(E=s.pop()||u.lex()||1)&&(E instanceof Array&&(E=(s=E).pop()),E=t.symbols_[E]||E),b=E),L=l[x]&&l[x][b]),void 0===L||!L.length||!L[0]){var v="";for(f in k=[],l[x])this.terminals_[f]&&f>2&&k.push("'"+this.terminals_[f]+"'");v=u.showPosition?"Parse error on line "+(a+1)+":\n"+u.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(a+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(v,{text:u.match,token:this.terminals_[b]||b,line:u.yylineno,loc:y,expected:k})}if(L[0]instanceof Array&&L.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+b);switch(L[0]){case 1:i.push(b),n.push(u.yytext),r.push(u.yylloc),i.push(L[1]),b=null,c=u.yyleng,o=u.yytext,a=u.yylineno,y=u.yylloc;break;case 2:if(m=this.productions_[L[1]][1],w.$=n[n.length-m],w._$={first_line:r[r.length-(m||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(m||1)].first_column,last_column:r[r.length-1].last_column},p&&(w._$.range=[r[r.length-(m||1)].range[0],r[r.length-1].range[1]]),void 0!==(S=this.performAction.apply(w,[o,c,a,d.yy,L[1],n,r].concat(h))))return S;m&&(i=i.slice(0,-1*m*2),n=n.slice(0,-1*m),r=r.slice(0,-1*m)),i.push(this.productions_[L[1]][0]),n.push(w.$),r.push(w._$),_=l[i[i.length-2]][i[i.length-1]],i.push(_);break;case 3:return!0}}return!0}},x={EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,i=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===s.length?this.yylloc.first_column:0)+s[s.length-i.length].length-i[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var i,s,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(s=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],i=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var e,t,i,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;r<n.length;r++)if((i=this._input.match(this.rules[n[r]]))&&(!t||i[0].length>t[0].length)){if(t=i,s=r,this.options.backtrack_lexer){if(!1!==(e=this.test_match(i,n[r])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,n[s]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(e,t,i,s){switch(i){case 0:return 10;case 1:return e.getLogger().debug("Found space-block"),31;case 2:return e.getLogger().debug("Found nl-block"),31;case 3:return e.getLogger().debug("Found space-block"),29;case 4:e.getLogger().debug(".",t.yytext);break;case 5:e.getLogger().debug("_",t.yytext);break;case 6:return 5;case 7:return t.yytext=-1,28;case 8:return t.yytext=t.yytext.replace(/columns\s+/,""),e.getLogger().debug("COLUMNS (LEX)",t.yytext),28;case 9:case 77:case 78:case 100:this.pushState("md_string");break;case 10:return"MD_STR";case 11:case 35:case 80:this.popState();break;case 12:this.pushState("string");break;case 13:e.getLogger().debug("LEX: POPPING STR:",t.yytext),this.popState();break;case 14:return e.getLogger().debug("LEX: STR end:",t.yytext),"STR";case 15:return t.yytext=t.yytext.replace(/space\:/,""),e.getLogger().debug("SPACE NUM (LEX)",t.yytext),21;case 16:return t.yytext="1",e.getLogger().debug("COLUMNS (LEX)",t.yytext),21;case 17:return 43;case 18:return"LINKSTYLE";case 19:return"INTERPOLATE";case 20:return this.pushState("CLASSDEF"),40;case 21:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 22:return this.popState(),this.pushState("CLASSDEFID"),41;case 23:return this.popState(),42;case 24:return this.pushState("CLASS"),44;case 25:return this.popState(),this.pushState("CLASS_STYLE"),45;case 26:return this.popState(),46;case 27:return this.pushState("STYLE_STMNT"),47;case 28:return this.popState(),this.pushState("STYLE_DEFINITION"),48;case 29:return this.popState(),49;case 30:return this.pushState("acc_title"),"acc_title";case 31:return this.popState(),"acc_title_value";case 32:return this.pushState("acc_descr"),"acc_descr";case 33:return this.popState(),"acc_descr_value";case 34:this.pushState("acc_descr_multiline");break;case 36:return"acc_descr_multiline_value";case 37:return 30;case 38:case 39:case 41:case 42:case 45:return this.popState(),e.getLogger().debug("Lex: (("),"NODE_DEND";case 40:return this.popState(),e.getLogger().debug("Lex: ))"),"NODE_DEND";case 43:return this.popState(),e.getLogger().debug("Lex: (-"),"NODE_DEND";case 44:return this.popState(),e.getLogger().debug("Lex: -)"),"NODE_DEND";case 46:return this.popState(),e.getLogger().debug("Lex: ]]"),"NODE_DEND";case 47:return this.popState(),e.getLogger().debug("Lex: ("),"NODE_DEND";case 48:return this.popState(),e.getLogger().debug("Lex: ])"),"NODE_DEND";case 49:case 50:return this.popState(),e.getLogger().debug("Lex: /]"),"NODE_DEND";case 51:return this.popState(),e.getLogger().debug("Lex: )]"),"NODE_DEND";case 52:return this.popState(),e.getLogger().debug("Lex: )"),"NODE_DEND";case 53:return this.popState(),e.getLogger().debug("Lex: ]>"),"NODE_DEND";case 54:return this.popState(),e.getLogger().debug("Lex: ]"),"NODE_DEND";case 55:return e.getLogger().debug("Lexa: -)"),this.pushState("NODE"),36;case 56:return e.getLogger().debug("Lexa: (-"),this.pushState("NODE"),36;case 57:return e.getLogger().debug("Lexa: ))"),this.pushState("NODE"),36;case 58:case 60:case 61:case 62:case 65:return e.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;case 59:return e.getLogger().debug("Lex: ((("),this.pushState("NODE"),36;case 63:return e.getLogger().debug("Lexc: >"),this.pushState("NODE"),36;case 64:return e.getLogger().debug("Lexa: (["),this.pushState("NODE"),36;case 66:case 67:case 68:case 69:case 70:case 71:case 72:return this.pushState("NODE"),36;case 73:return e.getLogger().debug("Lexa: ["),this.pushState("NODE"),36;case 74:return this.pushState("BLOCK_ARROW"),e.getLogger().debug("LEX ARR START"),38;case 75:return e.getLogger().debug("Lex: NODE_ID",t.yytext),32;case 76:return e.getLogger().debug("Lex: EOF",t.yytext),8;case 79:return"NODE_DESCR";case 81:e.getLogger().debug("Lex: Starting string"),this.pushState("string");break;case 82:e.getLogger().debug("LEX ARR: Starting string"),this.pushState("string");break;case 83:return e.getLogger().debug("LEX: NODE_DESCR:",t.yytext),"NODE_DESCR";case 84:e.getLogger().debug("LEX POPPING"),this.popState();break;case 85:e.getLogger().debug("Lex: =>BAE"),this.pushState("ARROW_DIR");break;case 86:return t.yytext=t.yytext.replace(/^,\s*/,""),e.getLogger().debug("Lex (right): dir:",t.yytext),"DIR";case 87:return t.yytext=t.yytext.replace(/^,\s*/,""),e.getLogger().debug("Lex (left):",t.yytext),"DIR";case 88:return t.yytext=t.yytext.replace(/^,\s*/,""),e.getLogger().debug("Lex (x):",t.yytext),"DIR";case 89:return t.yytext=t.yytext.replace(/^,\s*/,""),e.getLogger().debug("Lex (y):",t.yytext),"DIR";case 90:return t.yytext=t.yytext.replace(/^,\s*/,""),e.getLogger().debug("Lex (up):",t.yytext),"DIR";case 91:return t.yytext=t.yytext.replace(/^,\s*/,""),e.getLogger().debug("Lex (down):",t.yytext),"DIR";case 92:return t.yytext="]>",e.getLogger().debug("Lex (ARROW_DIR end):",t.yytext),this.popState(),this.popState(),"BLOCK_ARROW_END";case 93:return e.getLogger().debug("Lex: LINK","#"+t.yytext+"#"),15;case 94:case 95:case 96:return e.getLogger().debug("Lex: LINK",t.yytext),15;case 97:case 98:case 99:return e.getLogger().debug("Lex: START_LINK",t.yytext),this.pushState("LLABEL"),16;case 101:return e.getLogger().debug("Lex: Starting string"),this.pushState("string"),"LINK_LABEL";case 102:return this.popState(),e.getLogger().debug("Lex: LINK","#"+t.yytext+"#"),15;case 103:case 104:return this.popState(),e.getLogger().debug("Lex: LINK",t.yytext),15;case 105:return e.getLogger().debug("Lex: COLON",t.yytext),t.yytext=t.yytext.slice(1),27}},rules:[/^(?:block-beta\b)/,/^(?:block\s+)/,/^(?:block\n+)/,/^(?:block:)/,/^(?:[\s]+)/,/^(?:[\n]+)/,/^(?:((\u000D\u000A)|(\u000A)))/,/^(?:columns\s+auto\b)/,/^(?:columns\s+[\d]+)/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:space[:]\d+)/,/^(?:space\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\s+)/,/^(?:DEFAULT\s+)/,/^(?:\w+\s+)/,/^(?:[^\n]*)/,/^(?:class\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:style\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:end\b\s*)/,/^(?:\(\(\()/,/^(?:\)\)\))/,/^(?:[\)]\))/,/^(?:\}\})/,/^(?:\})/,/^(?:\(-)/,/^(?:-\))/,/^(?:\(\()/,/^(?:\]\])/,/^(?:\()/,/^(?:\]\))/,/^(?:\\\])/,/^(?:\/\])/,/^(?:\)\])/,/^(?:[\)])/,/^(?:\]>)/,/^(?:[\]])/,/^(?:-\))/,/^(?:\(-)/,/^(?:\)\))/,/^(?:\))/,/^(?:\(\(\()/,/^(?:\(\()/,/^(?:\{\{)/,/^(?:\{)/,/^(?:>)/,/^(?:\(\[)/,/^(?:\()/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\[\\)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:\[)/,/^(?:<\[)/,/^(?:[^\(\[\n\-\)\{\}\s\<\>:]+)/,/^(?:$)/,/^(?:["][`])/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:\]>\s*\()/,/^(?:,?\s*right\s*)/,/^(?:,?\s*left\s*)/,/^(?:,?\s*x\s*)/,/^(?:,?\s*y\s*)/,/^(?:,?\s*up\s*)/,/^(?:,?\s*down\s*)/,/^(?:\)\s*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*~~[\~]+\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:["][`])/,/^(?:["])/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?::\d+)/],conditions:{STYLE_DEFINITION:{rules:[29],inclusive:!1},STYLE_STMNT:{rules:[28],inclusive:!1},CLASSDEFID:{rules:[23],inclusive:!1},CLASSDEF:{rules:[21,22],inclusive:!1},CLASS_STYLE:{rules:[26],inclusive:!1},CLASS:{rules:[25],inclusive:!1},LLABEL:{rules:[100,101,102,103,104],inclusive:!1},ARROW_DIR:{rules:[86,87,88,89,90,91,92],inclusive:!1},BLOCK_ARROW:{rules:[77,82,85],inclusive:!1},NODE:{rules:[38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,78,81],inclusive:!1},md_string:{rules:[10,11,79,80],inclusive:!1},space:{rules:[],inclusive:!1},string:{rules:[13,14,83,84],inclusive:!1},acc_descr_multiline:{rules:[35,36],inclusive:!1},acc_descr:{rules:[33],inclusive:!1},acc_title:{rules:[31],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,12,15,16,17,18,19,20,24,27,30,32,34,37,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,93,94,95,96,97,98,99,105],inclusive:!0}}};function L(){this.yy={}}return b.lexer=x,L.prototype=b,b.Parser=L,new L}());d.parser=d;const g=d;let y={},p=[],b={};const x="color",L="fill",S=(0,r.c)();let f={};const m=function(e,t=""){void 0===f[e]&&(f[e]={id:e,styles:[],textStyles:[]});const i=f[e];null!=t&&t.split(",").forEach((e=>{const t=e.replace(/([^;]*);/,"$1").trim();if(e.match(x)){const e=t.replace(L,"bgFill").replace(x,L);i.textStyles.push(e)}i.styles.push(t)}))},_=function(e,t=""){const i=y[e];null!=t&&(i.styles=t.split(","))},k=function(e,t){e.split(",").forEach((function(e){let i=y[e];if(void 0===i){const t=e.trim();y[t]={id:t,type:"na",children:[]},i=y[t]}i.classes||(i.classes=[]),i.classes.push(t)}))},E=(e,t)=>{const i=e.flat(),s=[];for(const o of i)if(o.label&&(o.label=(n=o.label,r.e.sanitizeText(n,S))),"classDef"!==o.type)if("applyClass"!==o.type)if("applyStyles"!==o.type)if("column-setting"===o.type)t.columns=o.columns||-1;else if("edge"===o.type)b[o.id]?b[o.id]++:b[o.id]=1,o.id=b[o.id]+"-"+o.id,p.push(o);else{o.label||("composite"===o.type?o.label="":o.label=o.id);const e=!y[o.id];if(e?y[o.id]=o:("na"!==o.type&&(y[o.id].type=o.type),o.label!==o.id&&(y[o.id].label=o.label)),o.children&&E(o.children,o),"space"===o.type){const e=o.width||1;for(let t=0;t<e;t++){const e=(0,l.A)(o);e.id=e.id+"-"+t,y[e.id]=e,s.push(e)}}else e&&s.push(o)}else(null==o?void 0:o.stylesStr)&&_(o.id,null==o?void 0:o.stylesStr);else k(o.id,(null==o?void 0:o.styleClass)||"");else m(o.id,o.css);var n;t.children=s};let w=[],v={id:"root",type:"composite",children:[],columns:-1};let D=0;const $={getConfig:()=>(0,r.F)().block,typeStr2Type:function(e){switch(r.l.debug("typeStr2Type",e),e){case"[]":return"square";case"()":return r.l.debug("we have a round"),"round";case"(())":return"circle";case">]":return"rect_left_inv_arrow";case"{}":return"diamond";case"{{}}":return"hexagon";case"([])":return"stadium";case"[[]]":return"subroutine";case"[()]":return"cylinder";case"((()))":return"doublecircle";case"[//]":return"lean_right";case"[\\\\]":return"lean_left";case"[/\\]":return"trapezoid";case"[\\/]":return"inv_trapezoid";case"<[]>":return"block_arrow";default:return"na"}},edgeTypeStr2Type:function(e){return r.l.debug("typeStr2Type",e),"=="===e?"thick":"normal"},edgeStrToEdgeData:function(e){switch(e.trim()){case"--x":return"arrow_cross";case"--o":return"arrow_circle";default:return"arrow_point"}},getLogger:()=>console,getBlocksFlat:()=>[...Object.values(y)],getBlocks:()=>w||[],getEdges:()=>p,setHierarchy:e=>{v.children=e,E(e,v),w=v.children},getBlock:e=>y[e],setBlock:e=>{y[e.id]=e},getColumns:e=>{const t=y[e];return t?t.columns?t.columns:t.children?t.children.length:-1:-1},getClasses:function(){return f},clear:()=>{r.l.debug("Clear called"),(0,r.v)(),v={id:"root",type:"composite",children:[],columns:-1},y={root:v},w=[],f={},p=[],b={}},generateId:()=>(D++,"id-"+Math.random().toString(36).substr(2,12)+"-"+D)},N=(e,t)=>{const i=o.A,s=i(e,"r"),n=i(e,"g"),r=i(e,"b");return a.A(s,n,r,t)},I=e=>`.label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .cluster-label text {\n fill: ${e.titleColor};\n }\n .cluster-label span,p {\n color: ${e.titleColor};\n }\n\n\n\n .label text,span,p {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${e.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${e.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${e.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${e.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${e.edgeLabelBackground};\n fill: ${e.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${N(e.edgeLabelBackground,.5)};\n // background-color:\n }\n\n .node .cluster {\n // fill: ${N(e.mainBkg,.5)};\n fill: ${N(e.clusterBkg,.5)};\n stroke: ${N(e.clusterBorder,.2)};\n box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${e.titleColor};\n }\n\n .cluster span,p {\n color: ${e.titleColor};\n }\n /* .cluster div {\n color: ${e.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${e.fontFamily};\n font-size: 12px;\n background: ${e.tertiaryColor};\n border: 1px solid ${e.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n }\n`;function T(e,t,i=!1){var s,n,l;const o=e;let a="default";((null==(s=null==o?void 0:o.classes)?void 0:s.length)||0)>0&&(a=((null==o?void 0:o.classes)||[]).join(" ")),a+=" flowchart-label";let c,h=0,u="";switch(o.type){case"round":h=5,u="rect";break;case"composite":h=0,u="composite",c=0;break;case"square":case"group":default:u="rect";break;case"diamond":u="question";break;case"hexagon":u="hexagon";break;case"block_arrow":u="block_arrow";break;case"odd":case"rect_left_inv_arrow":u="rect_left_inv_arrow";break;case"lean_right":u="lean_right";break;case"lean_left":u="lean_left";break;case"trapezoid":u="trapezoid";break;case"inv_trapezoid":u="inv_trapezoid";break;case"circle":u="circle";break;case"ellipse":u="ellipse";break;case"stadium":u="stadium";break;case"subroutine":u="subroutine";break;case"cylinder":u="cylinder";break;case"doublecircle":u="doublecircle"}const d=(0,r.k)((null==o?void 0:o.styles)||[]),g=o.label,y=o.size||{width:0,height:0,x:0,y:0};return{labelStyle:d.labelStyle,shape:u,labelText:g,rx:h,ry:h,class:a,style:d.style,id:o.id,directions:o.directions,width:y.width,height:y.height,x:y.x,y:y.y,positioned:i,intersect:void 0,type:o.type,padding:c??((null==(l=null==(n=(0,r.F)())?void 0:n.block)?void 0:l.padding)||0)}}async function z(e,t,i){const s=T(t,0,!1);if("group"===s.type)return;const n=await(0,c.e)(e,s),r=n.node().getBBox(),l=i.getBlock(s.id);l.size={width:r.width,height:r.height,x:0,y:0,node:n},i.setBlock(l),n.remove()}async function A(e,t,i){const s=T(t,0,!0);"space"!==i.getBlock(s.id).type&&(await(0,c.e)(e,s),t.intersect=null==s?void 0:s.intersect,(0,c.p)(s))}async function C(e,t,i,s){for(const n of t)await s(e,n,i),n.children&&await C(e,n.children,i,s)}const O=(null==(n=null==(s=(0,r.c)())?void 0:s.block)?void 0:n.padding)||8;function R(e,t){if(0===e||!Number.isInteger(e))throw new Error("Columns must be an integer !== 0.");if(t<0||!Number.isInteger(t))throw new Error("Position must be a non-negative integer."+t);if(e<0)return{px:t,py:0};if(1===e)return{px:0,py:t};return{px:t%e,py:Math.floor(t/e)}}const B=e=>{let t=0,i=0;for(const s of e.children){const{width:n,height:l,x:o,y:a}=s.size||{width:0,height:0,x:0,y:0};r.l.debug("getMaxChildSize abc95 child:",s.id,"width:",n,"height:",l,"x:",o,"y:",a,s.type),"space"!==s.type&&(n>t&&(t=n/(e.widthInColumns||1)),l>i&&(i=l))}return{width:t,height:i}};function F(e,t,i=0,s=0){var n,l,o,a,c,h,u,d,g,y,p;r.l.debug("setBlockSizes abc95 (start)",e.id,null==(n=null==e?void 0:e.size)?void 0:n.x,"block width =",null==e?void 0:e.size,"sieblingWidth",i),(null==(l=null==e?void 0:e.size)?void 0:l.width)||(e.size={width:i,height:s,x:0,y:0});let b=0,x=0;if((null==(o=e.children)?void 0:o.length)>0){for(const i of e.children)F(i,t);const n=B(e);b=n.width,x=n.height,r.l.debug("setBlockSizes abc95 maxWidth of",e.id,":s children is ",b,x);for(const t of e.children)t.size&&(r.l.debug(`abc95 Setting size of children of ${e.id} id=${t.id} ${b} ${x} ${t.size}`),t.size.width=b*(t.widthInColumns||1)+O*((t.widthInColumns||1)-1),t.size.height=x,t.size.x=0,t.size.y=0,r.l.debug(`abc95 updating size of ${e.id} children child:${t.id} maxWidth:${b} maxHeight:${x}`));for(const i of e.children)F(i,t,b,x);const l=e.columns||-1;let o=0;for(const t of e.children)o+=t.widthInColumns||1;let d=e.children.length;l>0&&l<o&&(d=l),e.widthInColumns;const g=Math.ceil(o/d);let y=d*(b+O)+O,p=g*(x+O)+O;if(y<i){r.l.debug(`Detected to small siebling: abc95 ${e.id} sieblingWidth ${i} sieblingHeight ${s} width ${y}`),y=i,p=s;const t=(i-d*O-O)/d,n=(s-g*O-O)/g;r.l.debug("Size indata abc88",e.id,"childWidth",t,"maxWidth",b),r.l.debug("Size indata abc88",e.id,"childHeight",n,"maxHeight",x),r.l.debug("Size indata abc88 xSize",d,"padding",O);for(const i of e.children)i.size&&(i.size.width=t,i.size.height=n,i.size.x=0,i.size.y=0)}if(r.l.debug(`abc95 (finale calc) ${e.id} xSize ${d} ySize ${g} columns ${l}${e.children.length} width=${Math.max(y,(null==(a=e.size)?void 0:a.width)||0)}`),y<((null==(c=null==e?void 0:e.size)?void 0:c.width)||0)){y=(null==(h=null==e?void 0:e.size)?void 0:h.width)||0;const t=l>0?Math.min(e.children.length,l):e.children.length;if(t>0){const i=(y-t*O-O)/t;r.l.debug("abc95 (growing to fit) width",e.id,y,null==(u=e.size)?void 0:u.width,i);for(const t of e.children)t.size&&(t.size.width=i)}}e.size={width:y,height:p,x:0,y:0}}r.l.debug("setBlockSizes abc94 (done)",e.id,null==(d=null==e?void 0:e.size)?void 0:d.x,null==(g=null==e?void 0:e.size)?void 0:g.width,null==(y=null==e?void 0:e.size)?void 0:y.y,null==(p=null==e?void 0:e.size)?void 0:p.height)}function P(e,t){var i,s,n,l,o,a,c,h,u,d,g,y,p,b,x,L,S;r.l.debug(`abc85 layout blocks (=>layoutBlocks) ${e.id} x: ${null==(i=null==e?void 0:e.size)?void 0:i.x} y: ${null==(s=null==e?void 0:e.size)?void 0:s.y} width: ${null==(n=null==e?void 0:e.size)?void 0:n.width}`);const f=e.columns||-1;if(r.l.debug("layoutBlocks columns abc95",e.id,"=>",f,e),e.children&&e.children.length>0){const t=(null==(o=null==(l=null==e?void 0:e.children[0])?void 0:l.size)?void 0:o.width)||0,i=e.children.length*t+(e.children.length-1)*O;r.l.debug("widthOfChildren 88",i,"posX");let s=0;r.l.debug("abc91 block?.size?.x",e.id,null==(a=null==e?void 0:e.size)?void 0:a.x);let n=(null==(c=null==e?void 0:e.size)?void 0:c.x)?(null==(h=null==e?void 0:e.size)?void 0:h.x)+(-(null==(u=null==e?void 0:e.size)?void 0:u.width)/2||0):-O,x=0;for(const l of e.children){const t=e;if(!l.size)continue;const{width:i,height:o}=l.size,{px:a,py:c}=R(f,s);if(c!=x&&(x=c,n=(null==(d=null==e?void 0:e.size)?void 0:d.x)?(null==(g=null==e?void 0:e.size)?void 0:g.x)+(-(null==(y=null==e?void 0:e.size)?void 0:y.width)/2||0):-O,r.l.debug("New row in layout for block",e.id," and child ",l.id,x)),r.l.debug(`abc89 layout blocks (child) id: ${l.id} Pos: ${s} (px, py) ${a},${c} (${null==(p=null==t?void 0:t.size)?void 0:p.x},${null==(b=null==t?void 0:t.size)?void 0:b.y}) parent: ${t.id} width: ${i}${O}`),t.size){const e=i/2;l.size.x=n+O+e,r.l.debug(`abc91 layout blocks (calc) px, pyid:${l.id} startingPos=X${n} new startingPosX${l.size.x} ${e} padding=${O} width=${i} halfWidth=${e} => x:${l.size.x} y:${l.size.y} ${l.widthInColumns} (width * (child?.w || 1)) / 2 ${i*((null==l?void 0:l.widthInColumns)||1)/2}`),n=l.size.x+e,l.size.y=t.size.y-t.size.height/2+c*(o+O)+o/2+O,r.l.debug(`abc88 layout blocks (calc) px, pyid:${l.id}startingPosX${n}${O}${e}=>x:${l.size.x}y:${l.size.y}${l.widthInColumns}(width * (child?.w || 1)) / 2${i*((null==l?void 0:l.widthInColumns)||1)/2}`)}l.children&&P(l),s+=(null==l?void 0:l.widthInColumns)||1,r.l.debug("abc88 columnsPos",l,s)}}r.l.debug(`layout blocks (<==layoutBlocks) ${e.id} x: ${null==(x=null==e?void 0:e.size)?void 0:x.x} y: ${null==(L=null==e?void 0:e.size)?void 0:L.y} width: ${null==(S=null==e?void 0:e.size)?void 0:S.width}`)}function Y(e,{minX:t,minY:i,maxX:s,maxY:n}={minX:0,minY:0,maxX:0,maxY:0}){if(e.size&&"root"!==e.id){const{x:r,y:l,width:o,height:a}=e.size;r-o/2<t&&(t=r-o/2),l-a/2<i&&(i=l-a/2),r+o/2>s&&(s=r+o/2),l+a/2>n&&(n=l+a/2)}if(e.children)for(const r of e.children)({minX:t,minY:i,maxX:s,maxY:n}=Y(r,{minX:t,minY:i,maxX:s,maxY:n}));return{minX:t,minY:i,maxX:s,maxY:n}}function K(e){const t=e.getBlock("root");if(!t)return;F(t,e,0,0),P(t),r.l.debug("getBlocks",JSON.stringify(t,null,2));const{minX:i,minY:s,maxX:n,maxY:l}=Y(t);return{x:i,y:s,width:n-i,height:l-s}}const X={parser:g,db:$,renderer:{draw:async function(e,t,i,s){const{securityLevel:n,block:l}=(0,r.F)(),o=s.db;let a;"sandbox"===n&&(a=(0,u.Ltv)("#i"+t));const d="sandbox"===n?(0,u.Ltv)(a.nodes()[0].contentDocument.body):(0,u.Ltv)("body"),g="sandbox"===n?d.select(`[id="${t}"]`):(0,u.Ltv)(`[id="${t}"]`);(0,c.a)(g,["point","circle","cross"],s.type,t);const y=o.getBlocks(),p=o.getBlocksFlat(),b=o.getEdges(),x=g.insert("g").attr("class","block");await async function(e,t,i){await C(e,t,i,z)}(x,y,o);const L=K(o);if(await async function(e,t,i){await C(e,t,i,A)}(x,y,o),await async function(e,t,i,s,n){const r=new h.T({multigraph:!0,compound:!0});r.setGraph({rankdir:"TB",nodesep:10,ranksep:10,marginx:8,marginy:8});for(const l of i)l.size&&r.setNode(l.id,{width:l.size.width,height:l.size.height,intersect:l.intersect});for(const l of t)if(l.start&&l.end){const t=s.getBlock(l.start),i=s.getBlock(l.end);if((null==t?void 0:t.size)&&(null==i?void 0:i.size)){const s=t.size,o=i.size,a=[{x:s.x,y:s.y},{x:s.x+(o.x-s.x)/2,y:s.y+(o.y-s.y)/2},{x:o.x,y:o.y}];await(0,c.h)(e,{v:l.start,w:l.end,name:l.id},{...l,arrowTypeEnd:l.arrowTypeEnd,arrowTypeStart:l.arrowTypeStart,points:a,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"},void 0,"block",r,n),l.label&&(await(0,c.f)(e,{...l,label:l.label,labelStyle:"stroke: #333; stroke-width: 1.5px;fill:none;",arrowTypeEnd:l.arrowTypeEnd,arrowTypeStart:l.arrowTypeStart,points:a,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"}),await(0,c.j)({...l,x:a[1].x,y:a[1].y},{originalPath:a}))}}}(x,b,p,o,t),L){const e=L,t=Math.max(1,Math.round(e.width/e.height*.125)),i=e.height+t+10,s=e.width+10,{useMaxWidth:n}=l;(0,r.i)(g,i,s,!!n),r.l.debug("Here Bounds",L,e),g.attr("viewBox",`${e.x-5} ${e.y-5} ${e.width+10} ${e.height+10}`)}(0,u.UMr)(u.zt)},getClasses:function(e,t){return t.db.getClasses()}},styles:I}}}]); \ No newline at end of file diff --git a/assets/js/56dd32bb.ad20d845.js b/assets/js/56dd32bb.ad20d845.js new file mode 100644 index 0000000000..d83cc8ede8 --- /dev/null +++ b/assets/js/56dd32bb.ad20d845.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[12473],{21687:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Pentesting IaaS","slug":"/category/pentesting-iaas","permalink":"/docs/category/pentesting-iaas","sidebar":"docs","navigation":{"previous":{"title":"Automated Pentesting","permalink":"/docs/category/automated-pentesting"},"next":{"title":"Overview","permalink":"/docs/operating-scs/components/automated-pentesting-iaas/overview"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/57b63ae3.f868e196.js b/assets/js/57b63ae3.f868e196.js new file mode 100644 index 0000000000..e5f10b217d --- /dev/null +++ b/assets/js/57b63ae3.f868e196.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9539],{57858:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>m,frontMatter:()=>l,metadata:()=>t,toc:()=>h});const t=JSON.parse('{"id":"iaas/guides/configuration-guide/manager","title":"Manager","description":"Stable release","source":"@site/docs/02-iaas/guides/configuration-guide/manager.mdx","sourceDirName":"02-iaas/guides/configuration-guide","slug":"/iaas/guides/configuration-guide/manager","permalink":"/docs/iaas/guides/configuration-guide/manager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/manager.mdx","tags":[],"version":"current","sidebarPosition":15,"frontMatter":{"sidebar_label":"Manager","sidebar_position":15},"sidebar":"docs","previous":{"title":"Inventory","permalink":"/docs/iaas/guides/configuration-guide/inventory"},"next":{"title":"Network","permalink":"/docs/iaas/guides/configuration-guide/network"}}');var a=r(74848),i=r(28453),s=r(11470),o=r(19365);const l={sidebar_label:"Manager",sidebar_position:15},c="Manager",d={},h=[{value:"Stable release",id:"stable-release",level:2},{value:"Working with Git branches",id:"working-with-git-branches",level:2},{value:"OpenSearch integration",id:"opensearch-integration",level:2},{value:"OpenStack broker integration",id:"openstack-broker-integration",level:2}];function u(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"manager",children:"Manager"})}),"\n",(0,a.jsx)(n.h2,{id:"stable-release",children:"Stable release"}),"\n",(0,a.jsx)(n.admonition,{type:"warning",children:(0,a.jsxs)(n.p,{children:["Always read the ",(0,a.jsx)(n.a,{href:"https://osism.tech/docs/release-notes/",children:"release notes"})," first to learn what has changed and what\nadjustments are necessary. Read the release notes even if you are only updating from e.g. 7.0.2 to 7.0.5."]})}),"\n",(0,a.jsx)(n.p,{children:"In the example, OSISM release 7.0.5 is used."}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Set the new manager version in the configuration repository."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:'MANAGER_VERSION="7.0.5"\nsed -i "~s,^manager_version:.*\\$,manager_version: ${MANAGER_VERSION}," environments/manager/configuration.yml\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["If ",(0,a.jsx)(n.code,{children:"openstack_version"})," or ",(0,a.jsx)(n.code,{children:"ceph_version"})," are set in ",(0,a.jsx)(n.code,{children:"environments/manager/configuration.yml"}),"\n(or anywhere else), they must be removed. If these are set, the stable release is not used for\nthese components."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Sync the image versions in the configuration repository."}),"\n",(0,a.jsxs)(s.A,{children:[(0,a.jsx)(o.A,{value:"osism-7",label:"OSISM >= 7.0.0",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"make sync\n"})})}),(0,a.jsxs)(o.A,{value:"osism-6",label:"OSISM < 7.0.0",children:[(0,a.jsxs)(n.p,{children:["If Gilt is not installed via the ",(0,a.jsx)(n.code,{children:"requirements.txt"})," of the manager environment it is\nimportant to use a version smaller v2. The v2 of Gilt is not yet usable."]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"python3 -m venv venv\nsource venv/bin/activate\npip install -r requirements.txt\n gilt overlay && gilt overlay\n"})}),(0,a.jsxs)(n.p,{children:["Optionally, this is normally not necessary, it is possible to reference a specific tag of the\n",(0,a.jsx)(n.a,{href:"https://github.com/osism/cfg-generics",children:"osism/cfg-generics"})," repository. To do this, first\ncheck which version of osism/cfg-generics is used in a particular release. The version is\ndefined in ",(0,a.jsx)(n.code,{children:"generics_version"})," in the ",(0,a.jsx)(n.code,{children:"base.yml"})," file in the ",(0,a.jsx)(n.code,{children:"osism/release"})," repository. For OSISM 6.0.0,\nfor example, this is version ",(0,a.jsx)(n.a,{href:"https://github.com/osism/release/blob/main/6.0.0/base.yml#L6",children:"v0.20230919.0"}),".\nThis version is then added to the file ",(0,a.jsx)(n.code,{children:"gilt.yml"})," in the configuration repository instead of\n",(0,a.jsx)(n.code,{children:"main"})," at ",(0,a.jsx)(n.code,{children:"version"}),". This change must be made again after each execution of ",(0,a.jsx)(n.code,{children:"gilt overlay"})," as\nit is overwritten by the call of ",(0,a.jsx)(n.code,{children:"gilt overlay"}),". This cannot be realized differently in the\ncurrent implementation of ",(0,a.jsx)(n.a,{href:"https://github.com/retr0h/gilt",children:"Gilt"}),"."]})]})]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Commit and push changes in the configuration repository. Since everyone here has their own\nworkflows for changes to the configuration repository, only a generic example for Git."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:'git commit -a -s -m "manager: use OSISM version ${MANAGER_VERSION?}"\ngit push\n'})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"working-with-git-branches",children:"Working with Git branches"}),"\n",(0,a.jsxs)(n.p,{children:["For example, for compliance and security reasons, many organizations prefer to prepare changes to\nproduction systems on dedicated Git branches, roll them out to the production environment\nusing the 4-eyes control principle and then finally transfer them to the ",(0,a.jsx)(n.code,{children:"main"})," branch through a\nreview and release process."]}),"\n",(0,a.jsxs)(n.p,{children:["A typical scenario is the ",(0,a.jsx)(n.a,{href:"/docs/iaas/guides/upgrade-guide/manager",children:"Manager Upgrade"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"OSISM offers the option of using specific Git branches on the manager."}),"\n",(0,a.jsx)(n.p,{children:"The Git branch can be changed in the following way:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Create a branch"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"git checkout -b YOUR-BRANCH-FOR-CHANGE-XYZ\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Set the branch name of your deployment branch with the variable ",(0,a.jsx)(n.code,{children:"configuration_git_version"})," in ",(0,a.jsx)(n.code,{children:"configuration.yml"}),".\nThis needs always to be changed on the manager node later if you merge the current branch to another target branch."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'BRANCH="$(git rev-parse --abbrev-ref HEAD)"\nsed -i "~s,^configuration_git_version:.*\\$,configuration_git_version: ${BRANCH}," environments/manager/configuration.yml\ngit commit -m "Starting to work on #<issue-id>" -s environments/manager/configuration.yml\ngit push\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Login to the manager and activate the branch\n(not needed when performing a initial manager install)"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd /opt/configuration\ngit fetch\ngit checkout YOUR-BRANCH-FOR-CHANGE-XYZ\nosism apply configuration\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.em,{children:"Recommended:"})," Rebuild inventories and update facts\n(On changing branches there are oft potential changes in the inventory structure)"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism reconciler sync\nosism apply facts\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Start your work on the topic and perfom a final review when the topic is complete"}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"opensearch-integration",children:"OpenSearch integration"}),"\n",(0,a.jsxs)(n.p,{children:["With the command ",(0,a.jsx)(n.code,{children:"osism log opensearch"})," it is possible to send SQL queries\nto the OpenSearch service. For the command to be functional, the OpenSearch\nintegration must be activated in the manager environment and the OpenSearch\naddress and port must be set."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/configuration.yml"',children:"manager_opensearch_enable: true\nmanager_opensearch_address: api-int.testbed.osism.xyz\nmanager_opensearch_port: 9200\nmanager_opensearch_protocol: https\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The integration can also be enabled later. ",(0,a.jsx)(n.code,{children:"osism update manager"})," is then\nexecuted after the configuration has been changed."]}),"\n",(0,a.jsx)(n.h2,{id:"openstack-broker-integration",children:"OpenStack broker integration"}),"\n",(0,a.jsxs)(n.p,{children:["If the Baremetal Service Integration in OSISM is used, the OpenStack Broker integration is\nrequired. The integration itself is activated by setting the parameter ",(0,a.jsx)(n.code,{children:"enable_listener"})," to ",(0,a.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["The hosts in the ",(0,a.jsx)(n.code,{children:"manager_listener_broker_hosts"})," list are the control nodes of OpenStack.\nThe user is set via ",(0,a.jsx)(n.code,{children:"manager_listener_broker_username"}),". On OpenStack's RabbitMQ broker, the user ",(0,a.jsx)(n.code,{children:"openstack"}),"\nis present by default."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/configuration.yml"',children:'enable_listener: true\nmanager_listener_broker_hosts:\n - 192.168.16.10\n - 192.168.16.11\n - 192.168.16.12\nmanager_listener_broker_username: openstack\nmanager_listener_broker_uri: "{% for host in manager_listener_broker_hosts %}amqp://{{ manager_listener_broker_username }}:{{ manager_listener_broker_password }}@{{ host }}:5672/{% if not loop.last %};{% endif %}{% endfor %}"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The password used when using the ",(0,a.jsx)(n.code,{children:"openstack"})," user is ",(0,a.jsx)(n.code,{children:"rabbitmq_password"})," from ",(0,a.jsx)(n.code,{children:"environments/kolla/secrets.yml"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/secrets.yml"',children:"manager_listener_broker_password: RABBITMQ_PASSWORD\n"})})]})}function m(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},19365:(e,n,r)=>{r.d(n,{A:()=>s});r(96540);var t=r(18215);const a={tabItem:"tabItem_Ymn6"};var i=r(74848);function s(e){let{children:n,hidden:r,className:s}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,t.A)(a.tabItem,s),hidden:r,children:n})}},11470:(e,n,r)=>{r.d(n,{A:()=>_});var t=r(96540),a=r(18215),i=r(23104),s=r(56347),o=r(205),l=r(57485),c=r(31682),d=r(70679);function h(e){return t.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,t.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:r}=e;return(0,t.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:r,attributes:t,default:a}}=e;return{value:n,label:r,attributes:t,default:a}}))}(r);return function(e){const n=(0,c.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,r])}function m(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function g(e){let{queryString:n=!1,groupId:r}=e;const a=(0,s.W6)(),i=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,l.aZ)(i),(0,t.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(a.location.search);n.set(i,e),a.replace({...a.location,search:n.toString()})}),[i,a])]}function p(e){const{defaultValue:n,queryString:r=!1,groupId:a}=e,i=u(e),[s,l]=(0,t.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!m({value:n,tabValues:r}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const t=r.find((e=>e.default))??r[0];if(!t)throw new Error("Unexpected error: 0 tabValues");return t.value}({defaultValue:n,tabValues:i}))),[c,h]=g({queryString:r,groupId:a}),[p,f]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,i]=(0,d.Dv)(r);return[a,(0,t.useCallback)((e=>{r&&i.set(e)}),[r,i])]}({groupId:a}),b=(()=>{const e=c??p;return m({value:e,tabValues:i})?e:null})();(0,o.A)((()=>{b&&l(b)}),[b]);return{selectedValue:s,selectValue:(0,t.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),h(e),f(e)}),[h,f,i]),tabValues:i}}var f=r(92303);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=r(74848);function v(e){let{className:n,block:r,selectedValue:t,selectValue:s,tabValues:o}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,i.a_)(),d=e=>{const n=e.currentTarget,r=l.indexOf(n),a=o[r].value;a!==t&&(c(n),s(a))},h=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;n=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;n=l[r]??l[l.length-1];break}}n?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.A)("tabs",{"tabs--block":r},n),children:o.map((e=>{let{value:n,label:r,attributes:i}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:t===n?0:-1,"aria-selected":t===n,ref:e=>l.push(e),onKeyDown:h,onClick:d,...i,className:(0,a.A)("tabs__item",b.tabItem,i?.className,{"tabs__item--active":t===n}),children:r??n},n)}))})}function j(e){let{lazy:n,children:r,selectedValue:i}=e;const s=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=s.find((e=>e.props.value===i));return e?(0,t.cloneElement)(e,{className:(0,a.A)("margin-top--md",e.props.className)}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:s.map(((e,n)=>(0,t.cloneElement)(e,{key:n,hidden:e.props.value!==i})))})}function y(e){const n=p(e);return(0,x.jsxs)("div",{className:(0,a.A)("tabs-container",b.tabList),children:[(0,x.jsx)(v,{...n,...e}),(0,x.jsx)(j,{...n,...e})]})}function _(e){const n=(0,f.A)();return(0,x.jsx)(y,{...e,children:h(e.children)},String(n))}},28453:(e,n,r)=>{r.d(n,{R:()=>s,x:()=>o});var t=r(96540);const a={},i=t.createContext(a);function s(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/582db9b7.0ca28036.js b/assets/js/582db9b7.0ca28036.js new file mode 100644 index 0000000000..3f1eaa5eab --- /dev/null +++ b/assets/js/582db9b7.0ca28036.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[18872],{29033:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Automated Pentesting","slug":"/category/automated-pentesting","permalink":"/docs/category/automated-pentesting","sidebar":"docs","navigation":{"previous":{"title":"Central API MVP","permalink":"/docs/operating-scs/components/central-api/poc-setup"},"next":{"title":"Pentesting IaaS","permalink":"/docs/category/pentesting-iaas"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/589280f5.5a1b93cc.js b/assets/js/589280f5.5a1b93cc.js new file mode 100644 index 0000000000..ed3ec9e881 --- /dev/null +++ b/assets/js/589280f5.5a1b93cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[53530],{55034:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>p,frontMatter:()=>t,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"iaas/guides/deploy-guide/services/infrastructure","title":"Infrastructure","description":"Common issues with deploying infrastructure services required by OpenStack","source":"@site/docs/02-iaas/guides/deploy-guide/services/infrastructure.md","sourceDirName":"02-iaas/guides/deploy-guide/services","slug":"/iaas/guides/deploy-guide/services/infrastructure","permalink":"/docs/iaas/guides/deploy-guide/services/infrastructure","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/infrastructure.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Infrastructure","sidebar_position":10},"sidebar":"docs","previous":{"title":"Services","permalink":"/docs/iaas/guides/deploy-guide/services/"},"next":{"title":"Kubernetes","permalink":"/docs/iaas/guides/deploy-guide/services/kubernetes"}}');var i=s(74848),o=s(28453);const t={sidebar_label:"Infrastructure",sidebar_position:10},d="Infrastructure",a={},c=[];function l(e){const n={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"infrastructure",children:"Infrastructure"})}),"\n",(0,i.jsxs)(n.p,{children:["Common issues with deploying infrastructure services required by OpenStack\nare documented in the ",(0,i.jsx)(n.a,{href:"/docs/iaas/guides/troubleshooting-guide/openstack",children:"OpenStack Troubleshooting Guide"}),"."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Optional: In order to reduce the active observation time for the deployment of the components,\nthe container images for the following services can be downloaded in advance with the argument ",(0,i.jsx)(n.code,{children:"-a pull"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull common\nosism apply -a pull loadbalancer\nosism apply -a pull redis\nosism apply -a pull memcached\nosism apply -a pull rabbitmq\nosism apply -a pull mariadb\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Cron, Fluentd & Kolla Toolbox"}),"\n",(0,i.jsxs)(n.p,{children:["The common role of Kolla is used to manage the services ",(0,i.jsx)(n.code,{children:"cron"}),", ",(0,i.jsx)(n.code,{children:"fluentd"}),"\nand ",(0,i.jsx)(n.code,{children:"kolla-toolbox"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["It is important to do this deployment before any other deployements in the Kolla\nenvironment, as parts of the other deployments depend on the ",(0,i.jsx)(n.code,{children:"kolla-toolbox"}),"\nservice."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply common\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Loadbalancer"}),"\n",(0,i.jsxs)(n.p,{children:["Have a look to the ",(0,i.jsx)(n.a,{href:"/docs/iaas/guides/configuration-guide/loadbalancer",children:"loadbalancer documentation"})," and configure it before deploying the service."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply loadbalancer\n"})}),"\n",(0,i.jsx)(n.p,{children:"It is important to do this deployment before any other deployements in the Kolla\nenvironment, as parts of the other deployments depend on the loadbalancer\nservice."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Redis"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply redis\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Memcached"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply memcached\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"RabbitMQ"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply rabbitmq\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"MariaDB"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply mariadb\n"})}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>d});var r=s(96540);const i={},o=r.createContext(i);function t(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/58af14fe.340fce71.js b/assets/js/58af14fe.340fce71.js new file mode 100644 index 0000000000..021e1e6351 --- /dev/null +++ b/assets/js/58af14fe.340fce71.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[43745],{36075:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>u});const a=JSON.parse('{"id":"iaas/guides/deploy-guide/services/rookify","title":"Migrate Ceph-Ansible via Rookify (technical preview)","description":"This is a technical preview and not recommended for production use yet.","source":"@site/docs/02-iaas/guides/deploy-guide/services/rookify.md","sourceDirName":"02-iaas/guides/deploy-guide/services","slug":"/iaas/guides/deploy-guide/services/rookify","permalink":"/docs/iaas/guides/deploy-guide/services/rookify","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/rookify.md","tags":[],"version":"current","sidebarPosition":51,"frontMatter":{"sidebar_label":"Migrate Ceph-Ansible via Rookify (technical preview)","sidebar_position":51},"sidebar":"docs","previous":{"title":"Ceph via Rook (technical preview)","permalink":"/docs/iaas/guides/deploy-guide/services/rook"},"next":{"title":"OpenStack","permalink":"/docs/iaas/guides/deploy-guide/services/openstack"}}');var n=r(74848),i=r(28453);r(11470),r(19365);const o={sidebar_label:"Migrate Ceph-Ansible via Rookify (technical preview)",sidebar_position:51},s="Migrate Ceph-Ansible via Rookify (technical preview)",l={},u=[];function c(e){const t={admonition:"admonition",h1:"h1",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"migrate-ceph-ansible-via-rookify-technical-preview",children:"Migrate Ceph-Ansible via Rookify (technical preview)"})}),"\n",(0,n.jsx)(t.admonition,{type:"warning",children:(0,n.jsx)(t.p,{children:"This is a technical preview and not recommended for production use yet."})}),"\n",(0,n.jsx)(t.p,{children:"Rookify is now also available in OSISM."})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},19365:(e,t,r)=>{r.d(t,{A:()=>o});r(96540);var a=r(18215);const n={tabItem:"tabItem_Ymn6"};var i=r(74848);function o(e){let{children:t,hidden:r,className:o}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,a.A)(n.tabItem,o),hidden:r,children:t})}},11470:(e,t,r)=>{r.d(t,{A:()=>x});var a=r(96540),n=r(18215),i=r(23104),o=r(56347),s=r(205),l=r(57485),u=r(31682),c=r(70679);function d(e){return a.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:t,children:r}=e;return(0,a.useMemo)((()=>{const e=t??function(e){return d(e).map((e=>{let{props:{value:t,label:r,attributes:a,default:n}}=e;return{value:t,label:r,attributes:a,default:n}}))}(r);return function(e){const t=(0,u.XI)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[t,r])}function f(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function h(e){let{queryString:t=!1,groupId:r}=e;const n=(0,o.W6)(),i=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:t,groupId:r});return[(0,l.aZ)(i),(0,a.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(n.location.search);t.set(i,e),n.replace({...n.location,search:t.toString()})}),[i,n])]}function b(e){const{defaultValue:t,queryString:r=!1,groupId:n}=e,i=p(e),[o,l]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(t){if(!f({value:t,tabValues:r}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const a=r.find((e=>e.default))??r[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:t,tabValues:i}))),[u,d]=h({queryString:r,groupId:n}),[b,m]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,i]=(0,c.Dv)(r);return[n,(0,a.useCallback)((e=>{r&&i.set(e)}),[r,i])]}({groupId:n}),v=(()=>{const e=u??b;return f({value:e,tabValues:i})?e:null})();(0,s.A)((()=>{v&&l(v)}),[v]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!f({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),m(e)}),[d,m,i]),tabValues:i}}var m=r(92303);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var g=r(74848);function y(e){let{className:t,block:r,selectedValue:a,selectValue:o,tabValues:s}=e;const l=[],{blockElementScrollPositionUntilNextRender:u}=(0,i.a_)(),c=e=>{const t=e.currentTarget,r=l.indexOf(t),n=s[r].value;n!==a&&(u(t),o(n))},d=e=>{let t=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;t=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;t=l[r]??l[l.length-1];break}}t?.focus()};return(0,g.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,n.A)("tabs",{"tabs--block":r},t),children:s.map((e=>{let{value:t,label:r,attributes:i}=e;return(0,g.jsx)("li",{role:"tab",tabIndex:a===t?0:-1,"aria-selected":a===t,ref:e=>l.push(e),onKeyDown:d,onClick:c,...i,className:(0,n.A)("tabs__item",v.tabItem,i?.className,{"tabs__item--active":a===t}),children:r??t},t)}))})}function k(e){let{lazy:t,children:r,selectedValue:i}=e;const o=(Array.isArray(r)?r:[r]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===i));return e?(0,a.cloneElement)(e,{className:(0,n.A)("margin-top--md",e.props.className)}):null}return(0,g.jsx)("div",{className:"margin-top--md",children:o.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==i})))})}function w(e){const t=b(e);return(0,g.jsxs)("div",{className:(0,n.A)("tabs-container",v.tabList),children:[(0,g.jsx)(y,{...t,...e}),(0,g.jsx)(k,{...t,...e})]})}function x(e){const t=(0,m.A)();return(0,g.jsx)(w,{...e,children:d(e.children)},String(t))}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>s});var a=r(96540);const n={},i=a.createContext(n);function o(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/59307471.7a3949d7.js b/assets/js/59307471.7a3949d7.js new file mode 100644 index 0000000000..0b2f3da63d --- /dev/null +++ b/assets/js/59307471.7a3949d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[42637],{35350:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"kaas/scs-0211","title":"scs-0211: SCS KaaS default storage class","description":"The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).","source":"@site/standards/kaas/scs-0211.md","sourceDirName":"kaas","slug":"/kaas/scs-0211","permalink":"/standards/kaas/scs-0211","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0210-w1-k8s-version-policy-implementation-testing"},"next":{"title":"V1","permalink":"/standards/scs-0211-v1-kaas-default-storage-class"}}');var n=t(74848),r=t(28453);const d={},i="scs-0211: SCS KaaS default storage class",l={},c=[{value:"Supplement: Implementation and Testing Notes",id:"supplement-implementation-and-testing-notes",level:2}];function o(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"scs-0211-scs-kaas-default-storage-class",children:"scs-0211: SCS KaaS default storage class"})}),"\n",(0,n.jsx)(s.p,{children:'The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).\nThe standard ensures that the default StorageClass, identified by the "storageclass.kubernetes.io/is-default-class"\nannotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or\nhost hardware failures.'}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Version"}),(0,n.jsx)(s.th,{children:"Type"}),(0,n.jsx)(s.th,{children:"State"}),(0,n.jsx)(s.th,{children:"stabilized"}),(0,n.jsx)(s.th,{children:"deprecated"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0211-v1-kaas-default-storage-class",children:"scs-0211-v1"})}),(0,n.jsx)(s.td,{children:"Standard"}),(0,n.jsx)(s.td,{children:"Stable"}),(0,n.jsx)(s.td,{children:"2023-02-13"}),(0,n.jsx)(s.td,{children:"-"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0211-v2-kaas-default-storage-class",children:"scs-0211-v2"})}),(0,n.jsx)(s.td,{children:"Standard"}),(0,n.jsx)(s.td,{children:"Draft"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]})]})]}),"\n",(0,n.jsx)(s.h2,{id:"supplement-implementation-and-testing-notes",children:"Supplement: Implementation and Testing Notes"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Version"}),(0,n.jsx)(s.th,{children:"State"}),(0,n.jsx)(s.th,{children:"stabilized"}),(0,n.jsx)(s.th,{children:"deprecated"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing",children:"w1"})}),(0,n.jsx)(s.td,{children:"Draft"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(o,{...e})}):o(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>d,x:()=>i});var a=t(96540);const n={},r=a.createContext(n);function d(e){const s=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:d(e.components),a.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5abd544f.b98c658e.js b/assets/js/5abd544f.b98c658e.js new file mode 100644 index 0000000000..ec882a730d --- /dev/null +++ b/assets/js/5abd544f.b98c658e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1822],{84856:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"ops/scs-0401","title":"scs-0401: Status page reference implementation decision","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/ops/scs-0401.md","sourceDirName":"ops","slug":"/ops/scs-0401","permalink":"/standards/ops/scs-0401","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0400-v1-status-page-create-decision"},"next":{"title":"V1","permalink":"/standards/scs-0401-v1-status-page-reference-implementation-decision"}}');var r=s(74848),c=s(28453);const i={},a="scs-0401: Status page reference implementation decision",d={},o=[];function l(e){const t={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0401-status-page-reference-implementation-decision",children:"scs-0401: Status page reference implementation decision"})}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0401-v1-status-page-reference-implementation-decision",children:"scs-0401-v1"})}),(0,r.jsx)(t.td,{children:"Decision Record"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>a});var n=s(96540);const r={},c=n.createContext(r);function i(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5af709c8.b61d63bd.js b/assets/js/5af709c8.b61d63bd.js new file mode 100644 index 0000000000..ac834ddcf3 --- /dev/null +++ b/assets/js/5af709c8.b61d63bd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[46008],{40264:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>a});const s=JSON.parse('{"id":"container/components/cluster-stacks/components/csctl/getting_started","title":"Getting started","description":"A Cluster Stack is full template of a Kubernetes cluster. A Cluster Stack can be configured on every provider that supports Cluster API.","source":"@site/docs/03-container/components/cluster-stacks/components/csctl/getting_started.md","sourceDirName":"03-container/components/cluster-stacks/components/csctl","slug":"/container/components/cluster-stacks/components/csctl/getting_started","permalink":"/docs/container/components/cluster-stacks/components/csctl/getting_started","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/csctl/getting_started.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Quickstart","permalink":"/docs/container/components/cluster-stacks/components/csctl/quickstart"},"next":{"title":"Developing and Testing csctl","permalink":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl"}}');var r=n(74848),c=n(28453);const o={},i="Getting started",l={},a=[{value:"Overview",id:"overview",level:2},{value:"Configuring csctl",id:"configuring-csctl",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"getting-started",children:"Getting started"})}),"\n",(0,r.jsxs)(t.p,{children:["A ",(0,r.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks",children:"Cluster Stack"})," is full template of a Kubernetes cluster. A Cluster Stack can be configured on every provider that supports Cluster API."]}),"\n",(0,r.jsx)(t.p,{children:"The Cluster Stack Operator facilitates using Cluster Stacks by automating all steps that users would have to do manually given they have a Cluster API management cluster."}),"\n",(0,r.jsx)(t.p,{children:"The csctl helps to generate all files and build node images based on provided scripts in a format that the Cluster Stack Operator can use."}),"\n",(0,r.jsx)(t.p,{children:"The csctl requires a certain directory structure and uses a special form of templating to insert the right versions in your configuration files (e.g. Helm charts)."}),"\n",(0,r.jsx)(t.h2,{id:"overview",children:"Overview"}),"\n",(0,r.jsx)(t.p,{children:"The directory structure is very important. If the directories are not configured properly, csctl will not be able to build the cluster-stack for you."}),"\n",(0,r.jsx)(t.p,{children:"You should must have the following content inside your directory:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"csctl.yaml: the configuration of csctl"}),"\n",(0,r.jsx)(t.li,{children:"cluster-addon directory: the directory containing the Helm chart for cluster addons (Chart.yaml, templates and Helm related files if required)"}),"\n",(0,r.jsx)(t.li,{children:"cluster-class directory: the directory containing the Helm chart for Cluster API resources, e.g. ClusterClass (Chart.yaml, templates and Helm related files if required)"}),"\n",(0,r.jsx)(t.li,{children:"node-image directory (optional): the directory containing config and associated scripts to build node images"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"configuring-csctl",children:"Configuring csctl"}),"\n",(0,r.jsxs)(t.p,{children:["The configuration of csctl has to be specified in the ",(0,r.jsx)(t.code,{children:"csctl.yaml"}),". It needs to follow this structure:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-yaml",children:"apiVersion: csctl.clusterstack.x-k8s.io/v1alpha1\nconfig:\n kubernetesVersion: v1.27.7\n clusterStackName: ferrol\n provider:\n type: <myprovider>\n apiVersion: <myprovider>.csctl.clusterstack.x-k8s.io/v1alpha1\n config:\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The apiVersion specifies the version of this configuration. Currently, there is only the version ",(0,r.jsx)(t.code,{children:"csctl.clusterstack.x-k8s.io/v1alpha1"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Furthermore, the Kubernetes version in the format ",(0,r.jsx)(t.code,{children:"v<major>.<minor>.<patch>"})," (e.g. 1.27.5) has to be specified as well as the name that should be given to the Cluster Stack."]}),"\n",(0,r.jsx)(t.p,{children:"Depending on your plugin, there might be a provider-specific configuration."})]})}function u(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>i});var s=n(96540);const r={},c=s.createContext(r);function o(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5b235e06.1e6a7888.js b/assets/js/5b235e06.1e6a7888.js new file mode 100644 index 0000000000..aacbd88a58 --- /dev/null +++ b/assets/js/5b235e06.1e6a7888.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[58523],{81586:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>u,default:()=>h,frontMatter:()=>n,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"iaas/guides/other-guides/contributor-guide","title":"Contributor Guide","description":"We welcome any issues, change requests or general feedback. Do not hestiate to open an issue.","source":"@site/docs/02-iaas/guides/other-guides/contributor-guide.md","sourceDirName":"02-iaas/guides/other-guides","slug":"/iaas/guides/other-guides/contributor-guide","permalink":"/docs/iaas/guides/other-guides/contributor-guide","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/contributor-guide.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Contributor Guide"},"sidebar":"docs","previous":{"title":"Running on a virtual machine","permalink":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine"},"next":{"title":"Developer Guide","permalink":"/docs/iaas/guides/other-guides/developer-guide/"}}');var o=s(74848),r=s(28453);const n={sidebar_label:"Contributor Guide"},u="Contributor Guide",a={},c=[];function d(e){const t={a:"a",h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"contributor-guide",children:"Contributor Guide"})}),"\n",(0,o.jsxs)(t.p,{children:["We welcome any issues, change requests or general feedback. Do not hestiate to ",(0,o.jsx)(t.a,{href:"https://github.com/osism/issues/issues/new",children:"open an issue"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["We use GitHub Issues to capture feature requests, feedback, bugs, etc. The tracker is available in the\n",(0,o.jsx)(t.a,{href:"https://github.com/osism/issues/issues",children:"osism/issues"})," repository. There are no specific requirements for the creation of an issue.\nError cases should be described in such a way that they are directly reproducible. The more outputs there are,\nthe better."]}),"\n",(0,o.jsxs)(t.p,{children:["We use GitHub pull requests for contributions. The use of pull requets is documented in the\nofficial ",(0,o.jsx)(t.a,{href:"https://docs.github.com/en/github/collaborating-with-pull-requests",children:"GitHub documentation"}),".\nThe process in detail for the creation of a fork, branch etc. is also documented in the\nofficial ",(0,o.jsx)(t.a,{href:"https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests",children:"GitHub documentation"}),".\nIt is recommended to use the ",(0,o.jsx)(t.a,{href:"https://cli.github.com",children:"GitHub CLI"}),". Makes many steps easier."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>n,x:()=>u});var i=s(96540);const o={},r=i.createContext(o);function n(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function u(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:n(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5b402526.b5a4ca2a.js b/assets/js/5b402526.b5a4ca2a.js new file mode 100644 index 0000000000..092b3c6cd0 --- /dev/null +++ b/assets/js/5b402526.b5a4ca2a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[51001],{94365:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>i,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"scs-0002-v1-standards-docs-org","title":"Standards, Docs and Organisation","description":"Introduction","source":"@site/standards/scs-0002-v1-standards-docs-org.md","sourceDirName":".","slug":"/scs-0002-v1-standards-docs-org","permalink":"/standards/scs-0002-v1-standards-docs-org","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Standards, Docs and Organisation","type":"Procedural","status":"Stable","stabilized_at":"2023-02-06T00:00:00.000Z","track":"Global"},"sidebar":"standards","previous":{"title":"scs-0002: Standards, Docs and Organisation","permalink":"/standards/global/scs-0002"},"next":{"title":"V2","permalink":"/standards/scs-0002-v2-standards-docs-org"}}');var o=s(74848),r=s(28453);const i={title:"Standards, Docs and Organisation",type:"Procedural",status:"Stable",stabilized_at:new Date("2023-02-06T00:00:00.000Z"),track:"Global"},c=void 0,a={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Suggested cleanup (step 1)",id:"suggested-cleanup-step-1",level:2}];function l(e){const n={code:"code",h2:"h2",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,o.jsxs)(n.p,{children:["The old Docs repository had a subdirectory ",(0,o.jsx)(n.code,{children:"Design-Docs/"})," which holds Docs on\nDesign Considerations, older Architecture Decision Records (ADRs) and even\nStandards. It also has a ",(0,o.jsx)(n.code,{children:"Design-Docs/tools/"})," subdirectory with conformance\nchecks and our overall conformance check driver (from PR#182)."]}),"\n",(0,o.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,o.jsx)(n.p,{children:"This directory structure is confusing in a number of ways:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"The conformance checks are hard to find."}),"\n",(0,o.jsx)(n.li,{children:"The mixture of document types requires searching at two or three places."}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"We want to improve this (while avoiding unnecessary churn)."}),"\n",(0,o.jsx)(n.h2,{id:"suggested-cleanup-step-1",children:"Suggested cleanup (step 1)"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Move ",(0,o.jsx)(n.code,{children:"Design-Docs/tools/"})," contents to ",(0,o.jsx)(n.code,{children:"Tests/"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Also create subdirectories then for layers and test, while the overall\nconformance check tool, certification specs and README remain in ",(0,o.jsx)(n.code,{children:"Tests/"}),"."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["Rename ",(0,o.jsx)(n.code,{children:"Design-Docs/"})," to ",(0,o.jsx)(n.code,{children:"Drafts/"}),".","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Use individual PRs to rewrite existing ADRs and Standards there to conform\nto our standards and move them over to ",(0,o.jsx)(n.code,{children:"Standards/"}),"."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Some documents with findings will remain in the ",(0,o.jsx)(n.code,{children:"Drafts"})," directory.\nWe may want to categorize these and have a folder e.g. for research results."]})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const o={},r=t.createContext(o);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5b909c46.3fcb1277.js b/assets/js/5b909c46.3fcb1277.js new file mode 100644 index 0000000000..0defb4e7e7 --- /dev/null +++ b/assets/js/5b909c46.3fcb1277.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[36707],{21081:(t,n,e)=>{e.r(n),e.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>m,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"tools/mailinglists","title":"Mailing Lists","description":"We have an announcements mailing list there announce@lists.scs.community and you","source":"@site/community/tools/mailinglists.md","sourceDirName":"tools","slug":"/tools/mailinglists","permalink":"/community/tools/mailinglists","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Matrix","permalink":"/community/tools/matrix"},"next":{"title":"Nextcloud","permalink":"/community/tools/nextcloud"}}');var i=e(74848),o=e(28453);const a={},c="Mailing Lists",r={},l=[];function u(t){const n={a:"a",code:"code",h1:"h1",header:"header",p:"p",...(0,o.R)(),...t.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"mailing-lists",children:"Mailing Lists"})}),"\n",(0,i.jsxs)(n.p,{children:["We have an announcements mailing list there ",(0,i.jsx)(n.code,{children:"announce@lists.scs.community"})," and you\ncan subscribe via the ",(0,i.jsx)(n.a,{href:"https://scs.sovereignit.de/mailman3/postorius/lists/",children:"mailman3 frontend"}),"\nalso without the SCS nextcloud account if you prefer."]})]})}function m(t={}){const{wrapper:n}={...(0,o.R)(),...t.components};return n?(0,i.jsx)(n,{...t,children:(0,i.jsx)(u,{...t})}):u(t)}},28453:(t,n,e)=>{e.d(n,{R:()=>a,x:()=>c});var s=e(96540);const i={},o=s.createContext(i);function a(t){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof t?t(n):{...n,...t}}),[n,t])}function c(t){let n;return n=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:a(t.components),s.createElement(o.Provider,{value:n},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/5bd7bc3b.e5b3ca33.js b/assets/js/5bd7bc3b.e5b3ca33.js new file mode 100644 index 0000000000..f1752426ea --- /dev/null +++ b/assets/js/5bd7bc3b.e5b3ca33.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[70643],{5549:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>d,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"iaas/guides/operations-guide/index","title":"Operations Guide","description":"Change Node states","source":"@site/docs/02-iaas/guides/operations-guide/index.md","sourceDirName":"02-iaas/guides/operations-guide","slug":"/iaas/guides/operations-guide/","permalink":"/docs/iaas/guides/operations-guide/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/index.md","tags":[],"version":"current","sidebarPosition":30,"frontMatter":{"sidebar_label":"Operations Guide","sidebar_position":30},"sidebar":"docs","previous":{"title":"Validations","permalink":"/docs/iaas/guides/configuration-guide/validations/"},"next":{"title":"Manager","permalink":"/docs/iaas/guides/operations-guide/manager/"}}');var t=s(74848),o=s(28453);const a={sidebar_label:"Operations Guide",sidebar_position:30},d="Operations Guide",r={},c=[{value:"Change Node states",id:"change-node-states",level:2},{value:"Maintenance",id:"maintenance",level:3},{value:"Bootstrap",id:"bootstrap",level:3},{value:"Manage services",id:"manage-services",level:2},{value:"Manage containers",id:"manage-containers",level:2},{value:"Reboot nodes",id:"reboot-nodes",level:2},{value:"Working with the OOB Board via IPMI",id:"working-with-the-oob-board-via-ipmi",level:2},{value:"Display the IP address",id:"display-the-ip-address",level:3}];function l(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"operations-guide",children:"Operations Guide"})}),"\n",(0,t.jsx)(n.h2,{id:"change-node-states",children:"Change Node states"}),"\n",(0,t.jsx)(n.p,{children:"A node can be in different states. Depending on the state, different actions\nare possible or are triggered."}),"\n",(0,t.jsx)(n.p,{children:"The individual states of a node can be retrieved via Ansible Facts and local\nfiles on the node itself."}),"\n",(0,t.jsx)(n.h3,{id:"maintenance",children:"Maintenance"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism set maintenance NODE\nosism noset maintenance NODE\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Ansible fact: ",(0,t.jsx)(n.code,{children:"ansible_local.osism.maintenance"})]}),"\n",(0,t.jsxs)(n.li,{children:["State file: ",(0,t.jsx)(n.code,{children:"/etc/osism/maintenance"})]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"bootstrap",children:"Bootstrap"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism set bootstrap NODE\nosism noset bootstrap NODE\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Ansible fact: ",(0,t.jsx)(n.code,{children:"ansible_local.osism.bootstrap"})]}),"\n",(0,t.jsxs)(n.li,{children:["State file: ",(0,t.jsx)(n.code,{children:"/etc/osism/bootstrap"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"manage-services",children:"Manage services"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply manage-service \\\n -e service_name=rsysloc \\\n -e service_state=restarted\n"})}),"\n",(0,t.jsx)(n.h2,{id:"manage-containers",children:"Manage containers"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply manage-container \\\n -e container_name=nova_compute \\\n -e container_action=restart\n"})}),"\n",(0,t.jsx)(n.h2,{id:"reboot-nodes",children:"Reboot nodes"}),"\n",(0,t.jsx)(n.p,{children:"When using reboot play, the node is rebooted directly. It is not ensured in\nadvance that there is no more payload on the node and no services etc. are\ndisabled."}),"\n",(0,t.jsxs)(n.p,{children:["Reboot node ",(0,t.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz"})," and wait until the reboot has\nbeen completed and the system is accessible again."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply reboot \\\n -e reboot_wait=True \\\n -e ireallymeanit=yes \\\n -l testbed-node-0.testbed.osism.xyz\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Reboot node ",(0,t.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz"})," and do not wait for the reboot\nto complete."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply reboot \\\n -e ireallymeanit=yes \\\n -l testbed-node-0.testbed.osism.xyz\n"})}),"\n",(0,t.jsx)(n.h2,{id:"working-with-the-oob-board-via-ipmi",children:"Working with the OOB Board via IPMI"}),"\n",(0,t.jsx)(n.h3,{id:"display-the-ip-address",children:"Display the IP address"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ sudo ipmitool lan print | grep 'IP Address'\nIP Address Source : DHCP Address\nIP Address : 10.10.0.100\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>d});var i=s(96540);const t={},o=i.createContext(t);function a(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c201b0a.496063fc.js b/assets/js/5c201b0a.496063fc.js new file mode 100644 index 0000000000..3f36618a66 --- /dev/null +++ b/assets/js/5c201b0a.496063fc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2621],{19169:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"releases/Release3","title":"Release Notes for SCS Release 3","description":"(Release Date: 2022-09-21)","source":"@site/docs/06-releases/Release3.md","sourceDirName":"06-releases","slug":"/releases/Release3","permalink":"/docs/releases/Release3","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release3.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Release Notes for SCS Release 2","permalink":"/docs/releases/Release2"},"next":{"title":"Release Notes for SCS Release 4","permalink":"/docs/releases/Release4"}}');var r=s(74848),i=s(28453);const a={},o="Release Notes for SCS Release 3",l={},d=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"New Features (Highlights)",id:"new-features-highlights",level:2},{value:"Operator focused improvements",id:"operator-focused-improvements",level:3},{value:"SCS Developer focused improvements (testbed and k8s cluster management)",id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Cluster Management",id:"cluster-management",level:3},{value:"OSISM",id:"osism",level:3},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Resolved Issues",id:"resolved-issues",level:2},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R3",id:"list-of-known-issues--restrictions-in-r3",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Thanks",id:"thanks",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"release-notes-for-scs-release-3",children:"Release Notes for SCS Release 3"})}),"\n",(0,r.jsx)(n.p,{children:"(Release Date: 2022-09-21)"}),"\n",(0,r.jsx)(n.h2,{id:"scope",children:"Scope"}),"\n",(0,r.jsx)(n.p,{children:"Main goals for Release 3 (R3) were user federation, increase in deployment and upgrade\nvelocity by improving automated test coverage as well as bringing disk encryption based on\ntang from the state of a technical preview to be fully supported."}),"\n",(0,r.jsx)(n.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["We support the latest ",(0,r.jsx)(n.a,{href:"https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.25.md",children:"Kubernetes 1.25"}),"\nreleases."]}),"\n",(0,r.jsxs)(n.li,{children:["The Kubernetes Cluster API is now available in a stable v1beta1\n",(0,r.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api/releases",children:"release 1.2.x"}),"\nwith the corresponding ",(0,r.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api/releases",children:"cluster-api-provider-openstack 0.6.x"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["The ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/",children:"Kubernetes Cluster API cluster management service"}),"\nhas seen major managability improvements.\nPlease consult the\n",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R3.md",children:"k8s cluster api provider release notes"}),"\nfor more details."]}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://releases.openstack.org/yoga/highlights.html",children:"OpenStack Yoga release"})}),"\n",(0,r.jsx)(n.li,{children:"Ceph Quincy is available, the default release of Ceph is still Pacific."}),"\n",(0,r.jsxs)(n.li,{children:["The base infrastructure is provided by\n",(0,r.jsx)(n.a,{href:"https://release.osism.tech/notes/4.0.0.html",children:"OSISM 4.0.0"}),"\nwhich in turn builds on top of kolla and kolla-ansible."]}),"\n",(0,r.jsx)(n.li,{children:"Disk encryption based on Network bound disk encryption (NBDE) is available."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"new-features-highlights",children:"New Features (Highlights)"}),"\n",(0,r.jsx)(n.h3,{id:"operator-focused-improvements",children:"Operator focused improvements"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Work is underway to supersede ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor",children:"openstack-health-monitor"}),"\nwith a comprehensive approach using scenarios with ansible playbooks\nthat has been developed and used by T-Systems for their Open Telekom Cloud.\nMeanwhile, openstack-health-monitor has seen the addition of data\ncollection with telegraf and influxdb as well as a good dashboard\nwith grafana."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["We have used our keystone to keycloak federation to use keycloak as identity\nbroker to federate identities from other (SCS) clouds' keycloaks.\nThis works well for the Web-Interface; we have still some work to do to also make it smooth\nalso for API/CLI usage. We have ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/IAM-federation/keystone-keycloak-federation.md",children:"documented the current status"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["We believe that Gaia-X self-descriptions should also contain a description of\ntechnical properties of services; higher-level services and workloads can than\ndeclare their requirements and be matched against lower level services / platforms.\nIn good platforms, most (or all) technical properties are discoverable. In the\nGaia-X Hackathon #4, we have worked on a demonstrator that characterizes some\naspects of an OpenStack-based IaaS platform and which produces self-descriptions\nthat can be submitted to the Gaia-X trust service, pass the tests and you can\nbe awared a verifiable credential. Code is available in the\n",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/gx-self-description-generator",children:"gx-self-description-generator repo"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",children:"SCS Developer focused improvements (testbed and k8s cluster management)"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Following significant discussions on how to standardize our cluster management solution,\nthere is a draft concept as part of R3 now, which will be further worked on during\nthe R4 cycle. See ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R3.md#cluster-standardization",children:"Cluster standardization"}),"\nsection of the release notes from k8s-cluster-api-provider.\nWhile our reference implementation uses the concepts and code from k8s cluster API on\ntop of our SCS reference implementation (OpenStack automated by OSISM), we want to\nassure that non-OpenStack IaaS and solutions that diverge from cluster-API have the possibility\nto be SCS compliant."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Workload clusters managed by our SCS cluster management solutions can now much\nmore easily receive k8s version upgrades, ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R3.md#simplified-rolling-node-upgrades-223",children:"as the cluster-template no longer needs\nto be touched for this"}),". There is an ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/doc/Upgrade-Guide.md",children:"Upgrade Guide"})," available now."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"LUKS encryption is now documented and enabled in the testbed by default."}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Further noteworthy improvements to testbed:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Public DNS for testbed is now available (",(0,r.jsx)(n.code,{children:"testbed.osism.xyz"}),"), allowing to access services\nvia TLS protected by a wildcard CA certificate."]}),"\n",(0,r.jsx)(n.li,{children:"The wireguard VPN service is deployed in the testbed by default."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["An overview over the used software versions is available from the\n",(0,r.jsx)(n.a,{href:"https://github.com/osism/release",children:"OSISM release"})," repository as input\nfor a complete SBOM. This allows to e.g. investigate the contents of the\nused (v4.0.0) images."]}),"\n",(0,r.jsx)(n.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,r.jsx)(n.h3,{id:"cluster-management",children:"Cluster Management"}),"\n",(0,r.jsxs)(n.p,{children:["Upgrade from R2 to R3 for cluster management and clusters:\nSee ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R3.md#incompatible-changes",children:"k8s-cluster-api-provider Release Notes"}),"\nfor more details. There is an Upgrade Guide written specifically to address the steps needed for upgrading\nyour cluster management and the workload clusters."]}),"\n",(0,r.jsx)(n.h3,{id:"osism",children:"OSISM"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["In ",(0,r.jsx)(n.code,{children:"environments/kolla/secrets.yml"})," the parameter ",(0,r.jsx)(n.code,{children:"neutron_ssh_key"})," must be\nadded."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"neutron_ssh_key:\n private_key:\n public_key:\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The ssh key can be generated as follows: ",(0,r.jsx)(n.code,{children:'ssh-keygen -t rsa -b 4096 -N "" -f id_rsa.neutron -C "" -m PEM'})]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"removals",children:"Removals"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The Cockpit service has been removed."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,r.jsxs)(n.p,{children:["Deprecations happen according to our ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Release-Policies.md#deprecation",children:"deprecation policy"}),"."]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Linux bridge support has been deprecated by the Neutron team and marked as experimental.\nIf Linux bridge is used in deployments, migrating to OpenVSwitch is recommended."}),"\n",(0,r.jsxs)(n.li,{children:["Debian dropped hddtemp (",(0,r.jsx)(n.a,{href:"https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1002484",children:"https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1002484"}),"),\ntherefore the ",(0,r.jsx)(n.code,{children:"hddtemp"})," service will be removed from the next OSISM release, as there is\nno package available for Ubuntu 22.04."]}),"\n",(0,r.jsx)(n.li,{children:"Heat will no longer be offered by default in the testbed in the future"}),"\n",(0,r.jsx)(n.li,{children:"The following services are currently not used and are deprecated and scheduled for removal as of now: Falco, Jenkins, Rundeck, Lynis, Trivy"}),"\n",(0,r.jsx)(n.li,{children:"The docker-compose CLI will be removed and replaced by the new compose plugin for Docker.\ndocker-compose is then no longer available and docker compose must be used instead"}),"\n",(0,r.jsxs)(n.li,{children:["The ",(0,r.jsx)(n.code,{children:"cleanup-elasticsearch"})," playbook is deprecated. In the future,\nthe ",(0,r.jsx)(n.code,{children:"elasticsearch-curator"})," service (part of Kolla) has to be used\nfor Elasticsearch cleanup."]}),"\n",(0,r.jsx)(n.li,{children:"All osism- scripts on the manager are deprecated and will be replaced by the new OSISM CLI. The scripts will be removed in the next release"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,r.jsx)(n.p,{children:"No severe security issues need to be highlighted since Release 2. However, by updating to the latest stable version of\nthe integrated open source components, we benefit from the upstream security fixes and thus recommend to upgrade all\nSCS environments. Please note that Release 2 maintenance by the SCS project team will end by the end of October."}),"\n",(0,r.jsx)(n.h2,{id:"resolved-issues",children:"Resolved Issues"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Certificates in k8s clusters are subject to expiration - typically after one year.\nWe ensure these are renewed on control-plane upgrades, but operators may need manual attention\nin case upgrades are not performed for extended periods of time. This is documented in\nthe k8s-cluster-api-provider's\n",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/doc/Maintenance_and_Troubleshooting.md",children:"Maintenance and Troubleshooting Guide"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,r.jsxs)(n.p,{children:["The clusters created with our cluster-API cluster management solution pass\nthe ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Image-Properties-Spec.md",children:"CNCF conformance tests"}),"\nas reported by ",(0,r.jsx)(n.a,{href:"https://sonobuoy.io/",children:"sonobuoy"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"https://openstack.org/",children:"OpenStack"})," layer passes the\n",(0,r.jsx)(n.a,{href:"https://openinfra.dev/",children:"OIF"})," trademark tests, so cloud providers\nleveraging the stack should easily be able to achieve the\n",(0,r.jsx)(n.a,{href:"https://www.openstack.org/brand/interop/",children:'"OpenStack powered compute"'}),"\ntrademark certification."]}),"\n",(0,r.jsxs)(n.p,{children:["Our partner plusserver has ",(0,r.jsx)(n.a,{href:"https://www.openstack.org/brand/interop/",children:"achieved"}),"\na ",(0,r.jsx)(n.a,{href:"https://www.bsi.bund.de/EN/Themen/Unternehmen-und-Organisationen/Informationen-und-Empfehlungen/Empfehlungen-nach-Angriffszielen/Cloud-Computing/Kriterienkatalog-C5/kriterienkatalog-c5_node.html",children:"BSI C5"}),"\nsecurity certification for their SCS implementation pluscloud open."]}),"\n",(0,r.jsxs)(n.p,{children:["We are working within ",(0,r.jsx)(n.a,{href:"https://gaia-x.eu/",children:"Gaia-X"})," to further the power\nof Gaia-X self-descriptions and are closely working with the\n",(0,r.jsx)(n.a,{href:"https://gxfs.de/",children:"GXFS project"}),"\nto jointly deliver a standard toolbox for Gaia-X compliant\ninfrastructure and service offerings."]}),"\n",(0,r.jsxs)(n.p,{children:["The SCS standards for ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/flavor-naming.md",children:"flavor naming"})," and\n",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Image-Properties-Spec.md",children:"image metadata"}),"\nare largely unchanged since R1. We have however\nmade progress in our reference implementation fully implementing\nthem without any further tweaks. The\n",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/tools/flavor-name-check.py",children:"conformance test for the flavor naming"}),"\nhas seen minor improvements; a\n",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/tools/image-md-check.py",children:"conformance test for the image metadata"}),"\nhas been added."]}),"\n",(0,r.jsx)(n.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Release-Numbering-Scheme.md",children:"Release Numbering scheme"})," -- unchanged from R0.\nWe have added the tag ",(0,r.jsx)(n.code,{children:"v4.0.0"})," to the relevant repositories to designate the ",(0,r.jsx)(n.code,{children:"SCS_RELEASE_R3"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Note that we will release R4 (v5.0.0) in March 2023 and stop providing maintenance\nupdates for R3 at the end of April 2023."}),"\n",(0,r.jsx)(n.h2,{id:"list-of-known-issues--restrictions-in-r3",children:"List of known issues & restrictions in R3"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Distributed Virtual Routing (DVR) is not officially supported by OSISM, not tested and not recommended."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,r.jsxs)(n.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,r.jsx)(n.a,{href:"https://scs.community/contribute/",children:"How to contribute page"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"thanks",children:"Thanks"}),"\n",(0,r.jsx)(n.p,{children:"The work for R3 has been done by many contributors from our community.\nWe have not collected detailed stats that would split out the individual contributor's\nand companies shares ... we may do so in the future. We are grateful to have such an\nactive and engaged community that has done so much work! Thanks to our contributors!"}),"\n",(0,r.jsx)(n.p,{children:"Of course we are leveraging a huge amount of open source technology that has been\ncreated by our friends in other communities, many of which are part of the\nCNCF, Linux Foudation, OIF, and others. We participate and contribute where\nwe can and definitely want to acknowledge the great work that we build upon."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>o});var t=s(96540);const r={},i=t.createContext(r);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c2c818b.1f3d21ad.js b/assets/js/5c2c818b.1f3d21ad.js new file mode 100644 index 0000000000..4abaa056ba --- /dev/null +++ b/assets/js/5c2c818b.1f3d21ad.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[57153],{98e3:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/tools/image-manager/index","title":"Image Manager","description":"The OpenStack Image Manager is a tool for managing all","source":"@site/docs/02-iaas/guides/operations-guide/openstack/tools/image-manager/index.md","sourceDirName":"02-iaas/guides/operations-guide/openstack/tools/image-manager","slug":"/iaas/guides/operations-guide/openstack/tools/image-manager/","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/image-manager/index.md","tags":[],"version":"current","sidebarPosition":50,"frontMatter":{"sidebar_label":"Image Manager","sidebar_position":50},"sidebar":"docs","previous":{"title":"Tools","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/"},"next":{"title":"Automated updates","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update"}}');var a=n(74848),t=n(28453);const r={sidebar_label:"Image Manager",sidebar_position:50},o="Image Manager",l={},d=[{value:"Requirements",id:"requirements",level:2},{value:"OpenStack Image Service (Glance)",id:"openstack-image-service-glance",level:3},{value:"Object storage backend",id:"object-storage-backend",level:3},{value:"Getting started",id:"getting-started",level:2},{value:"Image definitions",id:"image-definitions",level:2},{value:"SCS image standard",id:"scs-image-standard",level:3},{value:"Image with regular rebuilds",id:"image-with-regular-rebuilds",level:3},{value:"Image without regular rebuild",id:"image-without-regular-rebuild",level:3},{value:"Other properties",id:"other-properties",level:3},{value:"Image properties",id:"image-properties",level:4},{value:"Image tags",id:"image-tags",level:4},{value:"image status",id:"image-status",level:4},{value:"Image visibility",id:"image-visibility",level:4},{value:"Usage",id:"usage",level:2},{value:"Mirroring images",id:"mirroring-images",level:3},{value:"Updating images",id:"updating-images",level:3}];function c(e){const i={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.header,{children:(0,a.jsx)(i.h1,{id:"image-manager",children:"Image Manager"})}),"\n",(0,a.jsxs)(i.p,{children:["The ",(0,a.jsx)(i.a,{href:"https://pypi.org/project/openstack-image-manager/",children:"OpenStack Image Manager"})," is a tool for managing all\nimages on an OpenStack environment"]}),"\n",(0,a.jsx)(i.h2,{id:"requirements",children:"Requirements"}),"\n",(0,a.jsx)(i.p,{children:"This information is only relevant for the operator of an OpenStack environment. You can skip this section if\nyou want to use OpenStack Image Manager as a normal user and you are not an operator of an openStack environment."}),"\n",(0,a.jsx)(i.h3,{id:"openstack-image-service-glance",children:"OpenStack Image Service (Glance)"}),"\n",(0,a.jsx)(i.p,{children:"The OpenStack Image Service (Glance) is required to upload and discover data assets that are used by other\nservices."}),"\n",(0,a.jsx)(i.p,{children:"Since this script stores many images in a single project, the Glance quota must be set accordingly high or to unlimited."}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{className:"language-ini",children:"[DEFAULT]\nuser_storage_quota = 1TB\n"})}),"\n",(0,a.jsxs)(i.p,{children:["With most storage backends it makes sense to convert the imported images directly to RAW. So it is required for using Ceph and it's\nfeatures too. Recited from the Ceph documentation ",(0,a.jsx)(i.a,{href:"https://docs.ceph.com/en/latest/rbd/qemu-rbd/",children:"QEMU and block devices"})," and\n",(0,a.jsx)(i.a,{href:"https://docs.ceph.com/en/latest/rbd/rbd-openstack/",children:"Block devices and OpenStack"}),"."]}),"\n",(0,a.jsxs)(i.admonition,{type:"info",children:[(0,a.jsx)(i.p,{children:"The raw data format is really the only sensible format option to use with RBD. Technically, you could use other QEMU-supported formats\n(such as qcow2 or vmdk), but doing so would add additional overhead, and would also render the volume unsafe for virtual machine live\nmigration when caching (see below) is enabled."}),(0,a.jsx)(i.p,{children:"Important Ceph doesn't support QCOW2 for hosting a virtual machine disk. Thus if you want to boot virtual machines in Ceph (ephemeral\nbackend or boot from volume), the Glance image format must be RAW."}),(0,a.jsxs)(i.p,{children:["See the ",(0,a.jsx)(i.a,{href:"https://docs.openstack.org/glance/latest/configuration/sample-configuration.html",children:"OpenStack Glance documentation"}),"\nfor more details."]})]}),"\n",(0,a.jsx)(i.p,{children:"This requires the following parameter for the image import workflow."}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{className:"language-ini",children:"[taskflow_executor]\nconversion_format = raw\n\n[image_import_opts]\nimage_import_plugins = ['image_decompression', 'image_conversion']\n\n[image_conversion]\noutput_format = raw\n"})}),"\n",(0,a.jsx)(i.h3,{id:"object-storage-backend",children:"Object storage backend"}),"\n",(0,a.jsx)(i.p,{children:"If the mirror functionality is used, an object storage backend is required. The use of the mirror functionality\nis optional and is not used by default."}),"\n",(0,a.jsx)(i.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,a.jsxs)(i.p,{children:["This ",(0,a.jsx)(i.strong,{children:"Getting started"})," will upload a private image to your OpenStack environment with\nthe help of the OpenStack Image Manager."]}),"\n",(0,a.jsxs)(i.ol,{children:["\n",(0,a.jsxs)(i.li,{children:["\n",(0,a.jsxs)(i.p,{children:["Install the ",(0,a.jsx)(i.a,{href:"https://pypi.org/project/openstack-image-manager/",children:"openstack-image-manager"})," package with\n",(0,a.jsx)(i.a,{href:"https://pypi.org/project/pip/",children:"pip"}),"."]}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{className:"language-sh",children:"pip3 install openstack-image-manager\n"})}),"\n",(0,a.jsxs)(i.p,{children:["The installation can also be done via ",(0,a.jsx)(i.a,{href:"https://pypi.org/project/pipenv/",children:"pipenv"}),"."]}),"\n",(0,a.jsxs)(i.p,{children:["A ",(0,a.jsx)(i.code,{children:"Pipefile"})," file is created with this content. The ",(0,a.jsx)(i.a,{href:"https://pypi.org/project/openstack-image-manager/#history",children:"latest version of openstack-image-manager"}),"\nis used."]}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{className:"language-ini",children:'[[source]]\nurl = "https://pypi.org/simple"\nverify_ssl = true\nname = "pypi"\n\n[packages]\nopenstack-image-manager = "==0.20240403.0"\n\n[dev-packages]\n\n[requires]\npython_version = "3.10"\n'})}),"\n",(0,a.jsx)(i.p,{children:"The dependencies are then installed and the shell is prepared for use:"}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{className:"language-sh",children:"pipenv install\npipenv shell\n"})}),"\n"]}),"\n",(0,a.jsxs)(i.li,{children:["\n",(0,a.jsxs)(i.p,{children:["Create a image definition in the file ",(0,a.jsx)(i.code,{children:"getting-started.yml"})," in the local directory ",(0,a.jsx)(i.code,{children:"images"}),"."]}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{className:"language-yaml",children:"---\nimages:\n - name: MyCirros\n enable: true\n format: qcow2\n login: cirros\n password: gocubsgo\n min_disk: 1\n min_ram: 32\n status: active\n visibility: private\n multi: false\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_rng_model: virtio\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n hypervisor_type: qemu\n os_distro: cirros\n replace_frequency: never\n uuid_validity: none\n provided_until: none\n tags: []\n versions:\n - version: '0.6.2'\n url: https://github.com/cirros-dev/cirros/releases/download/0.6.2/cirros-0.6.2-x86_64-disk.img\n checksum: \"sha256:07e44a73e54c94d988028515403c1ed762055e01b83a767edf3c2b387f78ce00\"\n build_date: 2023-05-30\n - version: '0.6.3'\n url: https://github.com/cirros-dev/cirros/releases/download/0.6.3/cirros-0.6.3-x86_64-disk.img\n checksum: \"sha256:7d6355852aeb6dbcd191bcda7cd74f1536cfe5cbf8a10495a7283a8396e4b75b\"\n build_date: 2024-09-26\n"})}),"\n"]}),"\n",(0,a.jsxs)(i.li,{children:["\n",(0,a.jsxs)(i.p,{children:["Run the OpenStack Image Manager. It is assumed that a profile with the name ",(0,a.jsx)(i.code,{children:"openstack"})," exists in the\n",(0,a.jsx)(i.a,{href:"https://docs.openstack.org/python-openstackclient/latest/configuration/index.html#configuration-files",children:"clouds.yaml"}),"."]}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{className:"language-bash",children:'openstack-image-manager --cloud openstack --filter ".*Cirr.*" --images images/\n'})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(i.h2,{id:"image-definitions",children:"Image definitions"}),"\n",(0,a.jsxs)(i.p,{children:["The configuration consists of different parameter settings, such as values for\nminimum RAM or the visibility of the image. Have a look at the examples below\nfor all parameters. After a change to the configuration, validate it with\n",(0,a.jsx)(i.code,{children:"tox -- --dry-run"}),"."]}),"\n",(0,a.jsx)(i.h3,{id:"scs-image-standard",children:"SCS image standard"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsxs)(i.li,{children:["The value of ",(0,a.jsx)(i.code,{children:"login"})," is stored as ",(0,a.jsx)(i.code,{children:"image_original_user"})," in the metadata of an image."]}),"\n",(0,a.jsxs)(i.li,{children:["If ",(0,a.jsx)(i.code,{children:"image_description"})," is not set as meta information, ",(0,a.jsx)(i.code,{children:"image_description"})," is set to the name of the image."]}),"\n",(0,a.jsxs)(i.li,{children:["The value of ",(0,a.jsx)(i.code,{children:"build_date"})," of a specific version of an image is stored as ",(0,a.jsx)(i.code,{children:"image_build_date"})," in the metadata of an image."]}),"\n",(0,a.jsxs)(i.li,{children:["The value of ",(0,a.jsx)(i.code,{children:"url"})," of a specific version of an image is stored as ",(0,a.jsx)(i.code,{children:"image_source"})," in the metadata of an image."]}),"\n"]}),"\n",(0,a.jsx)(i.h3,{id:"image-with-regular-rebuilds",children:"Image with regular rebuilds"}),"\n",(0,a.jsx)(i.p,{children:"This type of image definition is used for images that are rebuilt at regular\nintervals. For example, this is the case for the daily builds of the Ubuntu\nimages."}),"\n",(0,a.jsxs)(i.p,{children:["The attribute ",(0,a.jsx)(i.code,{children:"multi: true"})," is set."]}),"\n",(0,a.jsxs)(i.p,{children:["With this type of image definition, the version of the distribution (or product,\nwhatever is contained in the image) used is already in the name of the image\ndefinition. The ",(0,a.jsx)(i.code,{children:"version"})," properties from the definition's ",(0,a.jsx)(i.code,{children:"versions"})," list\nare appended only to older iterations of the image as timestamp suffixes\nin parentheses upon each rotation (except for the latest entry)."]}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{className:"language-yaml",children:"images:\n - name: Ubuntu 24.04\n format: qcow2\n login: ubuntu\n min_disk: 8\n min_ram: 512\n status: active\n visibility: public\n multi: true\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n os_distro: ubuntu\n os_version: '24.04'\n tags: []\n versions:\n - version: '20240416'\n url: https://cloud-images.ubuntu.com/noble/20240416/noble-server-cloudimg-amd64.img\n - version: '20240422'\n url: https://cloud-images.ubuntu.com/noble/20240422/noble-server-cloudimg-amd64.img\n"})}),"\n",(0,a.jsx)(i.p,{children:"This configuration creates the following images:"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsx)(i.li,{children:(0,a.jsx)(i.strong,{children:"Ubuntu 24.04 (20240416)"})}),"\n",(0,a.jsx)(i.li,{children:(0,a.jsx)(i.strong,{children:"Ubuntu 24.04"})}),"\n"]}),"\n",(0,a.jsx)(i.p,{children:"If a newer build is added, the following rotation takes place:"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.strong,{children:"Ubuntu 24.04 (20240416)"})," does not change"]}),"\n",(0,a.jsxs)(i.li,{children:[(0,a.jsx)(i.strong,{children:"Ubuntu 24.04"})," becomes ",(0,a.jsx)(i.strong,{children:"Ubuntu 24.04 (20240422)"})]}),"\n",(0,a.jsxs)(i.li,{children:["the new image becomes ",(0,a.jsx)(i.strong,{children:"Ubuntu 24.04"})]}),"\n"]}),"\n",(0,a.jsxs)(i.p,{children:["By default the last three images will be visible. When a fourth image is added, the visibility of\nthe last image in the list is changed to ",(0,a.jsx)(i.code,{children:"community"})," and the image can be deleted in the future."]}),"\n",(0,a.jsx)(i.h3,{id:"image-without-regular-rebuild",children:"Image without regular rebuild"}),"\n",(0,a.jsx)(i.p,{children:"This type of image definition is used for images that are not rebuilt. For example,\nthis is the case for the flatcar images. For each release of Flatcar there is exactly\none image which will not be rebuilt in the future."}),"\n",(0,a.jsxs)(i.p,{children:["The attribute ",(0,a.jsx)(i.code,{children:"multi: false"})," is set."]}),"\n",(0,a.jsxs)(i.p,{children:["With this type of image definition, the version of the distribution (or product,\nwhatever is contained in the image) used is not in the name of the image definition.\nInstead, the ",(0,a.jsx)(i.code,{children:"version"})," properties from the image definition's ",(0,a.jsx)(i.code,{children:"versions"})," list\nare appended as static version suffixes to the images' names."]}),"\n",(0,a.jsx)(i.pre,{children:(0,a.jsx)(i.code,{className:"language-yaml",children:"images:\n - name: RancherOS\n format: qcow2\n login: rancher\n min_disk: 8\n min_ram: 2048\n status: active\n visibility: public\n multi: false\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n tags: []\n versions:\n - version: '1.3.0'\n url: https://github.com/rancher/os/releases/download/v1.3.0/rancheros-openstack.img\n - version: '1.4.0'\n url: https://github.com/rancher/os/releases/download/v1.4.0/rancheros-openstack.img\n - version: '1.4.1'\n url: https://github.com/rancher/os/releases/download/v1.4.1/rancheros-openstack.img\n"})}),"\n",(0,a.jsx)(i.p,{children:"This configuration creates the following images:"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsx)(i.li,{children:(0,a.jsx)(i.strong,{children:"RancherOS 1.3.0"})}),"\n",(0,a.jsx)(i.li,{children:(0,a.jsx)(i.strong,{children:"RancherOS 1.4.0"})}),"\n",(0,a.jsx)(i.li,{children:(0,a.jsx)(i.strong,{children:"RancherOS 1.4.1"})}),"\n"]}),"\n",(0,a.jsxs)(i.p,{children:["If a new version is added, no rotation takes place. The new version is added\nas ",(0,a.jsx)(i.strong,{children:"RancherOS x.y.z"}),". Here also the visibility of older images is not changed."]}),"\n",(0,a.jsx)(i.h3,{id:"other-properties",children:"Other properties"}),"\n",(0,a.jsx)(i.h4,{id:"image-properties",children:"Image properties"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsx)(i.li,{children:"Removal of properties is not yet possible"}),"\n",(0,a.jsx)(i.li,{children:"URL, name and format can not be changed"}),"\n",(0,a.jsxs)(i.li,{children:["Any keys can be added to ",(0,a.jsx)(i.code,{children:"meta"}),", these will be added to the image"]}),"\n",(0,a.jsxs)(i.li,{children:["Existing keys in ",(0,a.jsx)(i.code,{children:"meta"})," can be changed, the same applies to ",(0,a.jsx)(i.code,{children:"min_disk"}),"\nand ",(0,a.jsx)(i.code,{children:"min_ram"})]}),"\n"]}),"\n",(0,a.jsx)(i.h4,{id:"image-tags",children:"Image tags"}),"\n",(0,a.jsx)(i.h4,{id:"image-status",children:"image status"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsxs)(i.li,{children:["deactivation: change ",(0,a.jsx)(i.code,{children:"status"})," to ",(0,a.jsx)(i.code,{children:"deactivated"})]}),"\n",(0,a.jsxs)(i.li,{children:["reactivation: change ",(0,a.jsx)(i.code,{children:"status"})," to ",(0,a.jsx)(i.code,{children:"active"})]}),"\n"]}),"\n",(0,a.jsx)(i.h4,{id:"image-visibility",children:"Image visibility"}),"\n",(0,a.jsxs)(i.p,{children:["A full documentation about the visibility of images can be found in the ",(0,a.jsx)(i.strong,{children:"Image visibility"})," section in the\n",(0,a.jsx)(i.a,{href:"https://docs.openstack.org/api-ref/image/v2/index.html#general-information",children:"OpenStack Image Service API Documentation"}),"."]}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsxs)(i.li,{children:["public: set ",(0,a.jsx)(i.code,{children:"visibility"})," to ",(0,a.jsx)(i.code,{children:"public"})]}),"\n",(0,a.jsxs)(i.li,{children:["community: set ",(0,a.jsx)(i.code,{children:"visibility"})," to ",(0,a.jsx)(i.code,{children:"community"})]}),"\n",(0,a.jsxs)(i.li,{children:["shared: set ",(0,a.jsx)(i.code,{children:"visibility"})," to ",(0,a.jsx)(i.code,{children:"shared"})]}),"\n",(0,a.jsxs)(i.li,{children:["private: set ",(0,a.jsx)(i.code,{children:"visibility"})," to ",(0,a.jsx)(i.code,{children:"private"})]}),"\n"]}),"\n",(0,a.jsx)(i.h2,{id:"usage",children:"Usage"}),"\n",(0,a.jsx)(i.h3,{id:"mirroring-images",children:"Mirroring images"}),"\n",(0,a.jsx)(i.p,{children:"Since the upstreams often only keep their images for a short time, we mirror most of the images on REGIO.cloud.\nThis makes us independent of the availability of the images in the individual upstreams."}),"\n",(0,a.jsx)(i.h3,{id:"updating-images",children:"Updating images"}),"\n",(0,a.jsxs)(i.p,{children:["Some of the images are automatically updated by a ",(0,a.jsx)(i.a,{href:"update",children:"CI job"}),". The latest available build at the time of the CI job execution is mirrored and\nmade available as the current version."]}),"\n",(0,a.jsx)(i.p,{children:"Currently, the following images are updated once a week (every Sunday at 0 am):"}),"\n",(0,a.jsxs)(i.ul,{children:["\n",(0,a.jsx)(i.li,{children:"Almalinux"}),"\n",(0,a.jsx)(i.li,{children:"CentOS"}),"\n",(0,a.jsx)(i.li,{children:"Debian"}),"\n",(0,a.jsx)(i.li,{children:"Rockylinux"}),"\n",(0,a.jsx)(i.li,{children:"Ubuntu"}),"\n"]})]})}function h(e={}){const{wrapper:i}={...(0,t.R)(),...e.components};return i?(0,a.jsx)(i,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>r,x:()=>o});var s=n(96540);const a={},t=s.createContext(a);function r(e){const i=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function o(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(t.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c8ebdd1.b48f254f.js b/assets/js/5c8ebdd1.b48f254f.js new file mode 100644 index 0000000000..86ce152943 --- /dev/null +++ b/assets/js/5c8ebdd1.b48f254f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[23953],{20563:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"operating-scs/components/automated-pentesting-kaas/overview","title":"Overview","description":"Introdution","source":"@site/docs/04-operating-scs/components/automated-pentesting-kaas/overview.md","sourceDirName":"04-operating-scs/components/automated-pentesting-kaas","slug":"/operating-scs/components/automated-pentesting-kaas/overview","permalink":"/docs/operating-scs/components/automated-pentesting-kaas/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/automated-pentesting-kaas/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Pentesting KaaS","permalink":"/docs/category/pentesting-kaas"},"next":{"title":"Quickstart Guide","permalink":"/docs/operating-scs/components/automated-pentesting-kaas/quickstart"}}');var s=t(74848),r=t(28453);const a={},o="Overview",c={},l=[{value:"Introdution",id:"introdution",level:2},{value:"Kubernetes Security Concerns",id:"kubernetes-security-concerns",level:2},{value:"Infrastructure Security Challenges in Kubernetes:",id:"infrastructure-security-challenges-in-kubernetes",level:3},{value:"Application Security Challenges in Kubernetes:",id:"application-security-challenges-in-kubernetes",level:3},{value:"Infrastructure and application scanning",id:"infrastructure-and-application-scanning",level:2},{value:"Scanning Images with Trivy:",id:"scanning-images-with-trivy",level:3},{value:"Scanning Infrastructure with Trivy:",id:"scanning-infrastructure-with-trivy",level:3},{value:"Trivy Operator for Internal Scanning:",id:"trivy-operator-for-internal-scanning",level:3},{value:"Quickstart Guide",id:"quickstart-guide",level:2},{value:"Tools",id:"tools",level:2},{value:"Source",id:"source",level:2}];function u(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,s.jsx)(n.h2,{id:"introdution",children:"Introdution"}),"\n",(0,s.jsx)(n.p,{children:"When we talk about Kubernetes and cloud operations, we're discussing two scenarios with potential vulnerabilities. It's not like other situations where you can have a single focus; here, you need to be constantly vigilant about what's happening. As a platform for deploying applications, Kubernetes becomes a critical system.Modern cloud infrastructure security is a complex and critical aspect of maintaining robust and resilient cloud services. Moreover, as organizations increasingly rely on cloud environments for their operations, the security of these infrastructures becomes paramount"}),"\n",(0,s.jsx)(n.p,{children:"The Container-as-a-Service layer in SCS, is susceptible to various security threats. To address these concerns, continuous and automated security is essential when we working with applications."}),"\n",(0,s.jsx)(n.p,{children:"For this reason, the generated reports are also used to track all these issues, and continuous monitoring is applied to ensure the resolution of the vulnerabilities found."}),"\n",(0,s.jsx)(n.h2,{id:"kubernetes-security-concerns",children:"Kubernetes Security Concerns"}),"\n",(0,s.jsx)(n.p,{children:"Cloud infrastructure security involves protecting data, applications, and services from unauthorized access and threats security challenges, in Kubernetes, you must covering both infrastructure and application-related issues:"}),"\n",(0,s.jsx)(n.h3,{id:"infrastructure-security-challenges-in-kubernetes",children:"Infrastructure Security Challenges in Kubernetes:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Misconfigured Cluster Components"}),": Kubernetes clusters consist of various components like the API server, etcd, kubelet, and controller manager. Misconfigurations in these components can lead to unauthorized access, data leakage, and service disruptions."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Inadequate Network Policies"}),": Without proper network policies, unauthorized services might communicate with each other, leading to potential lateral movement of threats across the cluster."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Unsecured API Server"}),": The Kubernetes API server is the central control point for the entire cluster. Weak authentication and authorization mechanisms can expose the cluster to unauthorized access and potential exploits."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Insufficient TLS Encryption"}),": Communication between Kubernetes components, including the API server, etcd, and nodes, should be encrypted using TLS. Lack of proper encryption can lead to man-in-the-middle attacks and data interception."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Vulnerable etcd Configuration"}),": etcd stores all the cluster data, including secrets and configurations. If not properly secured, an attacker could gain access to sensitive information, potentially compromising the entire cluster."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Improper Use of Privileged Containers"}),": Running containers with elevated privileges or allowing access to the host filesystem can lead to a compromise of the host system or other containers."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Insecure Container Images"}),": Using container images from untrusted sources or without scanning them for vulnerabilities can introduce security risks into the cluster."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"application-security-challenges-in-kubernetes",children:"Application Security Challenges in Kubernetes:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Insecure Container Images"}),": Similar to infrastructure, deploying applications with unverified or outdated container images can introduce known vulnerabilities, increasing the attack surface."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Excessive Container Privileges"}),": Applications running with more privileges than necessary can lead to potential security breaches if the application is compromised."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Lack of Resource Quotas and Limits"}),": Without setting resource quotas and limits, a compromised application could exhaust cluster resources, leading to Denial of Service (DoS) attacks."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Improper Secret Management"}),": Storing application secrets (e.g., API keys, credentials) in unsecured locations or without proper encryption can expose them to unauthorized access."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Vulnerable Dependencies"}),": Applications often rely on third-party libraries and dependencies. Without regular updates and vulnerability scanning, these dependencies can introduce security risks."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Unsecured Service Exposures"}),": Exposing application services without proper security measures (like ingress controllers with TLS, firewalls, etc.) can make them vulnerable to external attacks."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Lack of Security Context and Policies"}),": Applications should be deployed with defined security contexts and policies to ensure they run with the least privilege necessary. Without these, applications are more susceptible to attacks."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In summary, securing Kubernetes requires a comprehensive approach that addresses both the infrastructure and the applications deployed on it. This includes proper configuration, encryption, privilege management, and regular security audits to identify and mitigate potential vulnerabilities."}),"\n",(0,s.jsx)(n.h2,{id:"infrastructure-and-application-scanning",children:"Infrastructure and application scanning"}),"\n",(0,s.jsx)(n.p,{children:"Here\u2019s an overview in English of what Trivy does when scanning images, infrastructure, and using the Trivy operator for internal scanning:"}),"\n",(0,s.jsx)(n.h3,{id:"scanning-images-with-trivy",children:"Scanning Images with Trivy:"}),"\n",(0,s.jsx)(n.p,{children:"When Trivy scans container images, it performs a deep inspection of the image layers. Internally, Trivy pulls the image from a container registry and unpacks it to examine the filesystem and all the packages installed within the image. It looks for known vulnerabilities by comparing the image's software packages against a database of known CVEs (Common Vulnerabilities and Exposures). Trivy supports various package managers (e.g., apt, yum, pip, npm) and can detect vulnerabilities in operating system packages as well as application dependencies. Trivy also checks for misconfigurations, such as insecure file permissions or exposed secrets, that could pose security risks."}),"\n",(0,s.jsx)(n.h3,{id:"scanning-infrastructure-with-trivy",children:"Scanning Infrastructure with Trivy:"}),"\n",(0,s.jsx)(n.p,{children:"For infrastructure-as-code (IaC) scanning, Trivy inspects configuration files like Terraform, Kubernetes manifests, Dockerfiles, and other IaC templates. Internally, it parses these files and checks them against a set of security rules and best practices. Trivy identifies misconfigurations that could lead to security issues, such as overly permissive access controls, unencrypted data storage, and insecure network configurations. The scanning process is rule-based, and the results highlight potential risks before the infrastructure is deployed, allowing teams to address them early in the development process."}),"\n",(0,s.jsx)(n.h3,{id:"trivy-operator-for-internal-scanning",children:"Trivy Operator for Internal Scanning:"}),"\n",(0,s.jsx)(n.p,{children:"The Trivy operator is designed to work within a Kubernetes cluster, performing continuous security scans of running workloads. Internally, the operator automatically scans Kubernetes resources, including pods, images, and configurations, as they are deployed or updated in the cluster. It integrates directly with Kubernetes, using Kubernetes events and controllers to trigger scans. The operator then reports on vulnerabilities, misconfigurations, and compliance issues directly within the cluster environment. The results can be surfaced via Kubernetes CRDs (Custom Resource Definitions) and integrated with other tools or CI/CD pipelines for further action."}),"\n",(0,s.jsx)(n.h2,{id:"quickstart-guide",children:"Quickstart Guide"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"/docs/operating-scs/components/automated-pentesting-kaas/quickstart",children:"the quickstart page"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"tools",children:"Tools"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"/docs/operating-scs/components/automated-pentesting-kaas/tools",children:"the tools page"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"source",children:"Source"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/security-k8s-scan-pipeline",children:"github.com/SovereignCloudStack/security-k8s-scan-pipeline"}),"."]})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var i=t(96540);const s={},r=i.createContext(s);function a(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5cc619f0.4875b8d9.js b/assets/js/5cc619f0.4875b8d9.js new file mode 100644 index 0000000000..4460e077af --- /dev/null +++ b/assets/js/5cc619f0.4875b8d9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[49648],{87866:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>C,contentTitle:()=>S,default:()=>I,frontMatter:()=>y,metadata:()=>s,toc:()=>T});const s=JSON.parse('{"id":"collaboration/index","title":"Collaboration","description":"We\u2019re an open community","source":"@site/community/collaboration/index.mdx","sourceDirName":"collaboration","slug":"/collaboration/","permalink":"/community/collaboration/","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"License considerations for SCS","permalink":"/community/license-considerations"},"next":{"title":"Team Iaas","permalink":"/community/collaboration/team-iaas"}}');var t=i(74848),a=i(28453),l=i(96540),r=i(17632),o=i(97950),c=i(11244),d=i(38680),h=i(95257);const u="link_wr7g",m="button_gV6k",p=e=>{const{title:n,href:i,handleClick:s}=e;return(0,t.jsx)("a",{className:u,href:i,children:(0,t.jsx)("button",{onClick:s,className:m,children:n})})},g="modal__zVM",x="modalContent_zbmJ",j="modalTitle_u975",b="modalDescription_H8cB",v="modalH2_DhYb",k="buttonBox_NbRn",w=e=>{const{calendarEvent:n,onClose:i,show:s}=e;return(0,t.jsx)(t.Fragment,{children:s&&n&&(0,t.jsx)("div",{className:g,onClick:i,children:(0,t.jsxs)("div",{className:x,children:[(0,t.jsx)("div",{className:j,children:(0,t.jsx)("h2",{className:v,children:n.title})}),(0,t.jsxs)("div",{className:b,children:[(0,t.jsx)("p",{children:n.extendedProps.description}),(0,t.jsx)("p",{children:n.extendedProps.location}),(0,t.jsx)("div",{className:k,children:(0,t.jsx)(p,{handleClick:e=>{e.stopPropagation()},title:"Join Meeting",href:n.extendedProps.location})})]})]})})})},f=()=>{const[e,n]=(0,l.useState)(!1),[i,s]=(0,l.useState)();return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.A,{slotDuration:"00:15:00",slotMinTime:"09:00:00",slotMaxTime:"18:00:00",navLinks:!0,nowIndicator:!0,height:"auto",expandRows:!1,eventClick:i=>(i=>{n(!e),s(i.event)})(i),plugins:[o.A,c.A,h.A,d.Ay],initialView:"timeGridWeek",weekends:!1,events:{url:"https://sovereigncloudstack.github.io/calendar/scs.ics",format:"ics"},headerToolbar:{left:"prev,next today",center:"title",right:"timeGridDay,timeGridWeek,dayGridMonth"}}),(0,t.jsx)("div",{children:(0,t.jsx)(w,{show:e,calendarEvent:i,onClose:()=>n(!1)})})]})},y={},S="Collaboration",C={},T=[{value:"We\u2019re an open community",id:"were-an-open-community",level:2},{value:"Collaborating with issues and pull requests",id:"collaborating-with-issues-and-pull-requests",level:2},{value:"Meetings",id:"meetings",level:2},{value:"Project updates",id:"project-updates",level:3},{value:"Sprint review/Backlog refinement/Sprint planning meetings",id:"sprint-reviewbacklog-refinementsprint-planning-meetings",level:3},{value:"Special interest groups (SIGs) and hacking sessions",id:"special-interest-groups-sigs-and-hacking-sessions",level:3}];function G(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"collaboration",children:"Collaboration"})}),"\n",(0,t.jsx)(n.h2,{id:"were-an-open-community",children:"We\u2019re an open community"}),"\n",(0,t.jsxs)(n.p,{children:["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 ",(0,t.jsx)(n.a,{href:"https://sovereigncloudstack.github.io/calendar/scs.ics",children:"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!"]}),"\n",(0,t.jsx)(f,{}),"\n",(0,t.jsx)(n.h2,{id:"collaborating-with-issues-and-pull-requests",children:"Collaborating with issues and pull requests"}),"\n",(0,t.jsxs)(n.p,{children:["We use the GitHub flow to track and discuss changes in issues, then propose and\nreview changes in pull requests. See the\n",(0,t.jsx)(n.a,{href:"https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests",children:"GitHub documentation"}),"\nfor more details."]}),"\n",(0,t.jsx)(n.h2,{id:"meetings",children:"Meetings"}),"\n",(0,t.jsx)(n.h3,{id:"project-updates",children:"Project updates"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Weekly with all teams on Thursday at 15:05 CEST (40 mins)"}),"\n",(0,t.jsx)(n.li,{children:"In some weeks we schedule an additional lightning talk at 15:40 CEST"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"sprint-reviewbacklog-refinementsprint-planning-meetings",children:"Sprint review/Backlog refinement/Sprint planning meetings"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Weekly Team meetings (~1hr) for currently 4 teams:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Team IaaS"}),"\n",(0,t.jsx)(n.li,{children:"Team Container"}),"\n",(0,t.jsx)(n.li,{children:"Team IAM & Security"}),"\n",(0,t.jsx)(n.li,{children:"Team Operations"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:"Please refer to the public calendar above for details."}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"special-interest-groups-sigs-and-hacking-sessions",children:"Special interest groups (SIGs) and hacking sessions"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["There are a number of SIG meetings and hacking sessions that meet weekly or bi-weekly","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"SIG Monitoring and Logging"}),"\n",(0,t.jsx)(n.li,{children:"SIG Standardization and Certification"}),"\n",(0,t.jsx)(n.li,{children:"SIG Documentation"}),"\n",(0,t.jsx)(n.li,{children:"SIG Community"}),"\n",(0,t.jsx)(n.li,{children:"SIG Central API"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:"Please refer to the public calendar above for details."}),"\n"]})]})}function I(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(G,{...e})}):G(e)}}}]); \ No newline at end of file diff --git a/assets/js/5d51a55a.1b9992ea.js b/assets/js/5d51a55a.1b9992ea.js new file mode 100644 index 0000000000..215a895d88 --- /dev/null +++ b/assets/js/5d51a55a.1b9992ea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5238],{8455:(e,l,n)=>{n.r(l),n.d(l,{assets:()=>i,contentTitle:()=>s,default:()=>r,frontMatter:()=>m,metadata:()=>a,toc:()=>p});const a=JSON.parse('{"id":"application-examples/opendesk-on-scs/configuration","title":"Configuration","description":"openDesk has many configuration options. You can view them and their default values in your copy of openDesk:","source":"@site/user-docs/application-examples/opendesk-on-scs/configuration.md","sourceDirName":"application-examples/opendesk-on-scs","slug":"/application-examples/opendesk-on-scs/configuration","permalink":"/user-docs/application-examples/opendesk-on-scs/configuration","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"userDocs","previous":{"title":"Getting started: Deployment from a local machine","permalink":"/user-docs/application-examples/opendesk-on-scs/getting_started"},"next":{"title":"User import","permalink":"/user-docs/application-examples/opendesk-on-scs/user-import"}}');var o=n(74848),t=n(28453);const m={},s="Configuration",i={},p=[{value:"Basic components",id:"basic-components",level:2},{value:"Apps",id:"apps",level:2}];function c(e){const l={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(l.header,{children:(0,o.jsx)(l.h1,{id:"configuration",children:"Configuration"})}),"\n",(0,o.jsx)(l.p,{children:"openDesk has many configuration options. You can view them and their default values in your copy of openDesk:"}),"\n",(0,o.jsx)(l.h2,{id:"basic-components",children:"Basic components"}),"\n",(0,o.jsxs)(l.p,{children:["For the configuration of the basic components please have a look at the ",(0,o.jsx)(l.code,{children:".yaml"})," files in ",(0,o.jsx)(l.code,{children:"helmfile/environments/default"}),"."]}),"\n",(0,o.jsx)(l.pre,{children:(0,o.jsx)(l.code,{className:"language-bash",children:"$ ls helmfile/environments/default\ncache.yaml\ncertificate.yaml\ncharts.yaml\ncluster.yaml\ndatabase.yaml\ndebug.yaml\nenterprise.yaml\nfunctional.yaml\nglobal.generated.yaml\nglobal.gotmpl\n_helper.yaml\nimages.yaml\ningress.yaml\nmonitoring.yaml\nobjectstores.yaml\nopendesk_main.gotmpl\npersistence.yaml\nreplicas.yaml\nrepositories.yaml\nresources.yaml\nsecrets.gotmpl\nsecurity.yaml\nselinux.yaml\nsmtp.gotmpl\ntheme.gotmpl\nturn.gotmpl\n"})}),"\n",(0,o.jsxs)(l.p,{children:["To overwrite a specific default setting, copy the snippet into you own ",(0,o.jsx)(l.code,{children:"values.yaml.gotmpl"})," file and change the values to your need."]}),"\n",(0,o.jsx)(l.h2,{id:"apps",children:"Apps"}),"\n",(0,o.jsxs)(l.p,{children:["The settings of the apps reside underneath ",(0,o.jsx)(l.code,{children:"helmfile/apps"})," (just like their helmfiles). As you see, the different apps have different numbers of values files. Review them carefully and edit your own ",(0,o.jsx)(l.code,{children:"values.yaml.gotmpl"})," to overwrite any default setting."]}),"\n",(0,o.jsx)(l.pre,{children:(0,o.jsx)(l.code,{className:"language-bash",children:"$ tree helmfile/apps/\nhelmfile/apps/\n\u251c\u2500\u2500 collabora\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values.yaml.gotmpl\n\u251c\u2500\u2500 cryptpad\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values.yaml.gotmpl\n\u251c\u2500\u2500 element\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-element.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-synapse-web.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-synapse.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values-well-known.yaml.gotmpl\n\u251c\u2500\u2500 intercom-service\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values.yaml.gotmpl\n\u251c\u2500\u2500 jitsi\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values-jitsi.yaml.gotmpl\n\u251c\u2500\u2500 migrations-post\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values.yaml.gotmpl\n\u251c\u2500\u2500 migrations-pre\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values.yaml.gotmpl\n\u251c\u2500\u2500 nextcloud\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-nextcloud-mgmt.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values-nextcloud.yaml.gotmpl\n\u251c\u2500\u2500 nubus\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-nubus.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-opendesk-customization.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-opendesk-images.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values-opendesk-keycloak-bootstrap.yaml.gotmpl\n\u251c\u2500\u2500 openproject\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values.yaml.gotmpl\n\u251c\u2500\u2500 openproject-bootstrap\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values.yaml.gotmpl\n\u251c\u2500\u2500 open-xchange\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-dovecot.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-openxchange-bootstrap.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-openxchange-enterprise-contact-picker.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values-openxchange.yaml.gotmpl\n\u251c\u2500\u2500 provisioning\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values-oxconnector.yaml.gotmpl\n\u251c\u2500\u2500 services\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 helmfile.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-certificates.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-clamav-distributed.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-clamav-simple.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-dkimpy.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-home.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-mariadb.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-memcached.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-minio.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-otterize.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-postfix.yaml.gotmpl\n\u2502\xa0\xa0 \u251c\u2500\u2500 values-postgresql.yaml.gotmpl\n\u2502\xa0\xa0 \u2514\u2500\u2500 values-redis.yaml.gotmpl\n\u2514\u2500\u2500 xwiki\n \u251c\u2500\u2500 helmfile-child.yaml.gotmpl\n \u251c\u2500\u2500 helmfile.yaml.gotmpl\n \u2514\u2500\u2500 values.yaml.gotmpl\n\n\n"})})]})}function r(e={}){const{wrapper:l}={...(0,t.R)(),...e.components};return l?(0,o.jsx)(l,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,l,n)=>{n.d(l,{R:()=>m,x:()=>s});var a=n(96540);const o={},t=a.createContext(o);function m(e){const l=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(l):{...l,...e}}),[l,e])}function s(e){let l;return l=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:m(e.components),a.createElement(t.Provider,{value:l},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5d54de92.a4e02751.js b/assets/js/5d54de92.a4e02751.js new file mode 100644 index 0000000000..5e6a6e9754 --- /dev/null +++ b/assets/js/5d54de92.a4e02751.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[67299],{43824:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"iaas/guides/operations-guide/ceph","title":"Ceph","description":"Where to find docs","source":"@site/docs/02-iaas/guides/operations-guide/ceph.md","sourceDirName":"02-iaas/guides/operations-guide","slug":"/iaas/guides/operations-guide/ceph","permalink":"/docs/iaas/guides/operations-guide/ceph","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/ceph.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Ceph"},"sidebar":"docs","previous":{"title":"Task","permalink":"/docs/iaas/guides/operations-guide/manager/task"},"next":{"title":"Infrastructure","permalink":"/docs/iaas/guides/operations-guide/infrastructure"}}');var i=s(74848),t=s(28453);const r={sidebar_label:"Ceph"},d="Ceph",a={},l=[{value:"Where to find docs",id:"where-to-find-docs",level:2},{value:"Advice on Ceph releases",id:"advice-on-ceph-releases",level:2},{value:"General maintenance",id:"general-maintenance",level:2},{value:"60 seconds cluster overview",id:"60-seconds-cluster-overview",level:3},{value:"Mute/Unmute a health warning",id:"muteunmute-a-health-warning",level:3},{value:"Disable/Enable (deep-)scrubbing",id:"disableenable-deep-scrubbing",level:3},{value:"Reboot a single node",id:"reboot-a-single-node",level:3},{value:"Gathering information about block devices",id:"gathering-information-about-block-devices",level:2},{value:"Enumerate typical storage devices and LVM",id:"enumerate-typical-storage-devices-and-lvm",level:3},{value:"SMART data for SATA/SAS and NVME devices",id:"smart-data-for-satasas-and-nvme-devices",level:3},{value:"Check format of a NVME device",id:"check-format-of-a-nvme-device",level:3},{value:"Format a NVME device to a different LBA format using nvme-cli",id:"format-a-nvme-device-to-a-different-lba-format-using-nvme-cli",level:3},{value:"Secure Erase a NVME drive using nvme-cli",id:"secure-erase-a-nvme-drive-using-nvme-cli",level:3},{value:"Secure Erase a SATA/SAS drive using hdparm",id:"secure-erase-a-satasas-drive-using-hdparm",level:3},{value:"OSD maintenance tasks",id:"osd-maintenance-tasks",level:2},{value:"Locate a specific OSD in the cluster",id:"locate-a-specific-osd-in-the-cluster",level:3},{value:"Get OSD metadata (global and single OSD)",id:"get-osd-metadata-global-and-single-osd",level:3},{value:"Add a new OSD",id:"add-a-new-osd",level:3},{value:"Replace a defect OSD",id:"replace-a-defect-osd",level:3},{value:"Remove a OSD",id:"remove-a-osd",level:3},{value:"Manual way",id:"manual-way",level:4},{value:"Remove a single OSD node",id:"remove-a-single-osd-node",level:3},{value:"Remove an OSD (temporarily e.g. when replacing a broken disk)",id:"remove-an-osd-temporarily-eg-when-replacing-a-broken-disk",level:3},{value:"Disable backfills/recovery completely",id:"disable-backfillsrecovery-completely",level:3},{value:"Rebalance OSDs",id:"rebalance-osds",level:3},{value:"Placement Group maintenance",id:"placement-group-maintenance",level:2},{value:"Dump placement groups",id:"dump-placement-groups",level:3},{value:"Query a PG about its status",id:"query-a-pg-about-its-status",level:3},{value:"Start (deep-)scrubbing of a placement group",id:"start-deep-scrubbing-of-a-placement-group",level:3},{value:"HEALTH_WARN - Large omap objects found...",id:"health_warn---large-omap-objects-found",level:3},{value:"Instruct a PG to repair in case of scrub errors (inconsistent PG)",id:"instruct-a-pg-to-repair-in-case-of-scrub-errors-inconsistent-pg",level:3},{value:"RADOS Pool maintenance",id:"rados-pool-maintenance",level:2},{value:"Get pools and their configuration",id:"get-pools-and-their-configuration",level:3},{value:"Dump all CRUSH rules",id:"dump-all-crush-rules",level:3},{value:"Get autoscaler status",id:"get-autoscaler-status",level:3},{value:"Create a replicated pool",id:"create-a-replicated-pool",level:3},{value:"Enabling an application on a pool",id:"enabling-an-application-on-a-pool",level:3},{value:"Delete a pool",id:"delete-a-pool",level:3},{value:"Set number of PGs for a pool",id:"set-number-of-pgs-for-a-pool",level:3},{value:"Create CRUSH rules for different storage classes",id:"create-crush-rules-for-different-storage-classes",level:3},{value:"Change CRUSH rule for a pool ("move pool")",id:"change-crush-rule-for-a-pool-move-pool",level:3},{value:"Advanced topics",id:"advanced-topics",level:2},{value:"Validating Ceph using OSISM playbooks",id:"validating-ceph-using-osism-playbooks",level:3},{value:"Shutdown a Ceph cluster",id:"shutdown-a-ceph-cluster",level:3},{value:"Restart a Ceph cluster after manual shutdown",id:"restart-a-ceph-cluster-after-manual-shutdown",level:3},{value:"Performance benchmark",id:"performance-benchmark",level:2},{value:"Where and how to get further help",id:"where-and-how-to-get-further-help",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"ceph",children:"Ceph"})}),"\n",(0,i.jsx)(n.h2,{id:"where-to-find-docs",children:"Where to find docs"}),"\n",(0,i.jsxs)(n.p,{children:["The official Ceph documentation is located on ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/",children:"https://docs.ceph.com/en/latest/rados/operations/"})]}),"\n",(0,i.jsxs)(n.p,{children:["It is ",(0,i.jsx)(n.strong,{children:"strongly advised"})," to use the documentation for the version being used."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Pacific - ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/pacific/rados/operations/",children:"https://docs.ceph.com/en/pacific/rados/operations/"})]}),"\n",(0,i.jsxs)(n.li,{children:["Quincy - ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/rados/operations/",children:"https://docs.ceph.com/en/quincy/rados/operations/"})]}),"\n",(0,i.jsxs)(n.li,{children:["Reef - ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/reef/rados/operations/",children:"https://docs.ceph.com/en/reef/rados/operations/"})]}),"\n"]}),"\n",(0,i.jsxs)(n.admonition,{type:"note",children:[(0,i.jsxs)(n.p,{children:["Do not take information in the documentation at face value.\nEspecially when it comes to advanced/rarely used/very new features it is ",(0,i.jsx)(n.strong,{children:"strongly advised"}),"\nto test any claims made in the documentation about any particular feature."]}),(0,i.jsx)(n.p,{children:"Never assume that things will work as written without actually testing it on a test setup\nas close to your real workload scenario as possible."})]}),"\n",(0,i.jsx)(n.h2,{id:"advice-on-ceph-releases",children:"Advice on Ceph releases"}),"\n",(0,i.jsxs)(n.p,{children:["The current Ceph releases and their support status can be found on ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/releases/",children:"https://docs.ceph.com/en/latest/releases/"})]}),"\n",(0,i.jsxs)(n.p,{children:["When a new Ceph stable version is released you are ",(0,i.jsx)(n.strong,{children:"strongly advised"}),"\nto not roll it out on any production cluster whatsoever.\nEven though its listed as \"stable\" it doesn't mean that this is actually true.\nEspecially avoid using .0 releases on anything remotely production\nunless you really, really now what you're doing and can live with a possible catastrophic failure."]}),"\n",(0,i.jsxs)(n.p,{children:["Be ",(0,i.jsx)(n.strong,{children:"very"})," conservative about what version you run on production systems."]}),"\n",(0,i.jsx)(n.p,{children:"Shiny new features aren't worth the risk of total or partial data loss/corruption."}),"\n",(0,i.jsx)(n.h2,{id:"general-maintenance",children:"General maintenance"}),"\n",(0,i.jsx)(n.h3,{id:"60-seconds-cluster-overview",children:"60 seconds cluster overview"}),"\n",(0,i.jsx)(n.p,{children:"The following commands can be used to quickly check the status of Ceph:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Print overall cluster status"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph -s\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Print detailed health information"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph health detail\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Display current OSD tree"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph osd tree\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Cluster storage usage by pool and storage class"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph df\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"List pools with detailed configuration"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph osd pool ls detail\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Get usage stats for OSDs"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph osd df {plain|tree} {class e.g. hdd|ssd}\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Watch Ceph health messages sequentially"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph -w\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"List daemon versions running in the cluster"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph versions\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Also you can run the following on each node running ceph-daemons,\nto provide further debug information about the environment:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# lscpu\n# cat /proc/cpuinfo # if lscpu isn't available\n# free -g\n# ip l\n# ethtool <device> # for each network adapter\n"})}),"\n",(0,i.jsx)(n.h3,{id:"muteunmute-a-health-warning",children:"Mute/Unmute a health warning"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph health mute <what> <duration>\n$ ceph health unmute <what>\n"})}),"\n",(0,i.jsx)(n.h3,{id:"disableenable-deep-scrubbing",children:"Disable/Enable (deep-)scrubbing"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd set noscrub\n$ ceph osd set nodeep-scrub\n$ ceph osd unset noscrub\n$ ceph osd unset nodeep-scrub\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"Use this sparingly only in emergency situations.\nSetting these flags will cause a HEALTH_WARN status,\nincrease risk of data corruption and also the risk of generating\na HEALTH_WARN due to PGs not being (deep-)scrubbed in time."})}),"\n",(0,i.jsx)(n.h3,{id:"reboot-a-single-node",children:"Reboot a single node"}),"\n",(0,i.jsxs)(n.p,{children:["The traditional way of doing this is by setting the ",(0,i.jsx)(n.code,{children:"noout"})," flag,\ndo the appropriate maintenance work and after the node is back online\nunset the flag like so:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph osd set noout\n"})}),"\n",(0,i.jsx)(n.p,{children:"After maintenance is done and host is back up:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph osd unset noout\n"})}),"\n",(0,i.jsx)(n.p,{children:"On versions Luminous or above you can set the flag individually for single\nOSDs or entire CRUSH buckets, which can be a safer option in case of prolonged\nmaintenance periods."}),"\n",(0,i.jsx)(n.p,{children:"Add noout for a OSD:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph osd add-noout osd.<ID>\n"})}),"\n",(0,i.jsx)(n.p,{children:"Remove noout for a OSD:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph osd rm-noout osd.<ID>\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Add noout for CRUSH bucket (e.g. host name as seen in ",(0,i.jsx)(n.code,{children:"ceph osd tree"}),"):"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph osd set-group noout <crush-bucket-name>\n"})}),"\n",(0,i.jsx)(n.p,{children:"Remove noout for CRUSH bucket:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ceph osd unset-group noout <crush-bucket-name>\n"})}),"\n",(0,i.jsx)(n.h2,{id:"gathering-information-about-block-devices",children:"Gathering information about block devices"}),"\n",(0,i.jsx)(n.h3,{id:"enumerate-typical-storage-devices-and-lvm",children:"Enumerate typical storage devices and LVM"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# lsblk\n# lsblk -S\n# lsscsi\n# nvme list\n# pvs\n# vgs\n# lvs\n"})}),"\n",(0,i.jsx)(n.h3,{id:"smart-data-for-satasas-and-nvme-devices",children:"SMART data for SATA/SAS and NVME devices"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# smartctl -a /dev/sdX\n# nvme smart-log /dev/nvmeXnY\n"})}),"\n",(0,i.jsx)(n.h3,{id:"check-format-of-a-nvme-device",children:"Check format of a NVME device"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# nvme id-ns -H /dev/nvmeXnY\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:'Check the last lines named "LBA Format".\nIt will show which formats are supported,\nwhich format is in use and which format offers the best performance\naccording to the vendor.'})}),"\n",(0,i.jsx)(n.h3,{id:"format-a-nvme-device-to-a-different-lba-format-using-nvme-cli",children:"Format a NVME device to a different LBA format using nvme-cli"}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"This will destroy all data on the device!"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# nvme format --lbaf=<id> /dev/nvmeXnY\n"})}),"\n",(0,i.jsx)(n.h3,{id:"secure-erase-a-nvme-drive-using-nvme-cli",children:"Secure Erase a NVME drive using nvme-cli"}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"This will destroy all data on the device!"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# nvme format -s2 /dev/nvmeXnY\n# blkdiscard /dev/nvmeXnY\n# nvme format -s1 /dev/nvmeXnY\n"})}),"\n",(0,i.jsx)(n.h3,{id:"secure-erase-a-satasas-drive-using-hdparm",children:"Secure Erase a SATA/SAS drive using hdparm"}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"This will destroy all data on the device!"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Gather device info:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# hdparm -I /dev/sdX\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Check that the output says ",(0,i.jsx)(n.strong,{children:'"not frozen"'})," and ",(0,i.jsx)(n.strong,{children:'"not locked"'}),",\nalso it should list support for enhanced erase and list time estimates\nfor ",(0,i.jsx)(n.strong,{children:"SECURITY ERASE UNIT"})," and/or ",(0,i.jsx)(n.strong,{children:"ENHANCED SECURITY ERASE UNIT"})]}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Set a master password for the disk (required, will be automatically removed after wipe)"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# hdparm --user-master wipeit --security-set-pass wipeit /dev/sdX\n# hdparm -I /dev/sdX\n"})}),"\n",(0,i.jsxs)(n.p,{children:['Check that "Security level" is now ',(0,i.jsx)(n.strong,{children:'"high"'})," and master password is now\n",(0,i.jsx)(n.strong,{children:'"enabled"'})," instead of ",(0,i.jsx)(n.strong,{children:'"not enabled"'})," before"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Wipe the device"}),"\n",(0,i.jsx)(n.p,{children:"If device supports enhanced security erase (better), use the following:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# hdparm --user-master wipeit --security-erase-enhanced wipeit /dev/sdX\n"})}),"\n",(0,i.jsx)(n.p,{children:"If not, use standard security erase:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# hdparm --user-master wipeit --security-erase wipeit /dev/sdX\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:['On some systems the system firmware might "freeze" the device,\nwhich makes it impossible to issue a secure erase or reformat the device.\nIn that case it might be necessary to either "unfreeze" the drive or\nto install the drive in another system where it can be unfrozen.\nAlso make sure that the device is ',(0,i.jsx)(n.em,{children:"actually"})," wiped. Its recommended to\nat least perform a blanking pass on HDDs with a tool like nwipe."]})}),"\n",(0,i.jsx)(n.h2,{id:"osd-maintenance-tasks",children:"OSD maintenance tasks"}),"\n",(0,i.jsx)(n.h3,{id:"locate-a-specific-osd-in-the-cluster",children:"Locate a specific OSD in the cluster"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd find osd.<ID>\n"})}),"\n",(0,i.jsx)(n.h3,{id:"get-osd-metadata-global-and-single-osd",children:"Get OSD metadata (global and single OSD)"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd metadata\n$ ceph osd metadata osd.<ID>\n"})}),"\n",(0,i.jsx)(n.p,{children:"Interesting fields:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"bluefs_db_rotational"}),"\n",(0,i.jsx)(n.li,{children:"bluefs_dedicated_db"}),"\n",(0,i.jsx)(n.li,{children:"bluefs_dedicated_wal"}),"\n",(0,i.jsx)(n.li,{children:"bluefs_wal_rotational"}),"\n",(0,i.jsx)(n.li,{children:"bluestore_bdev_rotational"}),"\n",(0,i.jsx)(n.li,{children:"device_ids"}),"\n",(0,i.jsx)(n.li,{children:"device_paths"}),"\n",(0,i.jsx)(n.li,{children:"devices"}),"\n",(0,i.jsx)(n.li,{children:"hostname"}),"\n",(0,i.jsx)(n.li,{children:"osd_objectstore"}),"\n",(0,i.jsx)(n.li,{children:"rotational"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"add-a-new-osd",children:"Add a new OSD"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Prepare the configuration for the new OSD first. Details on adding the configuration\nfor a new OSD in the ",(0,i.jsx)(n.a,{href:"../configuration-guide/ceph/#add-a-new-osd",children:"Ceph configuration guide"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Deploy the new OSD service on ",(0,i.jsx)(n.code,{children:"<nodename>"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply ceph-osds -l <nodename> -e ceph_handler_osds_restart=false\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"replace-a-defect-osd",children:"Replace a defect OSD"}),"\n",(0,i.jsx)(n.h3,{id:"remove-a-osd",children:"Remove a OSD"}),"\n",(0,i.jsx)(n.p,{children:"As with \u2018Remove a single OSD node\u2019. Except that the steps are only executed\nfor a single OSD and the node is not removed from the CRUSH map and the inventory.\nOnly the entries relating to the removed OSD are removed from the host vars."}),"\n",(0,i.jsx)(n.h4,{id:"manual-way",children:"Manual way"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd crush reweight osd.<ID> 0.0\n# Wait for rebalance to complete...\n$ ceph osd out osd.<ID>\n# systemctl stop ceph-osd@<ID>\n# systemctl disable ceph-osd@<ID>\n$ ceph osd purge osd.<ID> --yes-i-really-mean-it\n"})}),"\n",(0,i.jsx)(n.p,{children:"The LV and VG defined in the inventory for this OSD must also be removed. The\nOSD itself should be wiped."}),"\n",(0,i.jsx)(n.h3,{id:"remove-a-single-osd-node",children:"Remove a single OSD node"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Get all OSDs of the node"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd tree\nID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF\n-1 0.11691 root default\n-3 0.03897 host testbed-node-0\n 0 hdd 0.01949 osd.0 up 1.00000 1.00000\n 4 hdd 0.01949 osd.4 up 1.00000 1.00000\n-5 0.03897 host testbed-node-1\n 1 hdd 0.01949 osd.1 up 1.00000 1.00000\n 3 hdd 0.01949 osd.3 up 1.00000 1.00000\n-7 0.03897 host testbed-node-2\n 2 hdd 0.01949 osd.2 up 1.00000 1.00000\n 5 hdd 0.01949 osd.5 up 1.00000 1.00000\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Reduce the weighting of all OSDs on the node to 0. Do this for each OSD\nin a row and wait after each adjustment until the Ceph cluster is balanced.\nDepending on how large the Ceph cluster and the individual OSDs are, this\nmay take some time."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd crush reweight osd.2 0.0\n$ ceph osd crush reweight osd.5 0.0\n"})}),"\n",(0,i.jsx)(n.p,{children:"The Ceph OSDs that are to be removed then have a weight of 0."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd tree\nID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF\n-1 0.07794 root default\n-3 0.03897 host testbed-node-0\n 0 hdd 0.01949 osd.0 up 1.00000 1.00000\n 4 hdd 0.01949 osd.4 up 1.00000 1.00000\n-5 0.03897 host testbed-node-1\n 1 hdd 0.01949 osd.1 up 1.00000 1.00000\n 3 hdd 0.01949 osd.3 up 1.00000 1.00000\n-7 0 host testbed-node-2\n 2 hdd 0 osd.2 up 1.00000 1.00000\n 5 hdd 0 osd.5 up 1.00000 1.00000\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Remove the OSDs and everything that belongs to them from the node.\nThis is a disruptive action that cannot be undone. The devices used\nare also reset."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply ceph-shrink-osd -e ireallymeanit=yes -e osd_to_kill=2,5\n"})}),"\n",(0,i.jsx)(n.p,{children:"All OSDs were removed."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd tree\nID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF\n-1 0.07794 root default\n-3 0.03897 host testbed-node-0\n 0 hdd 0.01949 osd.0 up 1.00000 1.00000\n 4 hdd 0.01949 osd.4 up 1.00000 1.00000\n-5 0.03897 host testbed-node-1\n 1 hdd 0.01949 osd.1 up 1.00000 1.00000\n 3 hdd 0.01949 osd.3 up 1.00000 1.00000\n-7 0 host testbed-node-2\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Remove the node from the CRUSH map."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd crush remove testbed-node-2\nremoved item id -7 name 'testbed-node-2' from crush map\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Remove the node from all Ceph groups in the inventory."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Remove all Ceph-specific parameters from the host vars of the node from the\ninventory"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"remove-an-osd-temporarily-eg-when-replacing-a-broken-disk",children:"Remove an OSD (temporarily e.g. when replacing a broken disk)"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd out osd.<ID>\n# systemctl stop ceph-osd@<ID>\n# systemctl disable ceph-osd@<ID>\n"})}),"\n",(0,i.jsx)(n.h3,{id:"disable-backfillsrecovery-completely",children:"Disable backfills/recovery completely"}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"Use only in emergency situations!"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd set nobackfill\n$ ceph osd set norecovery\n$ ceph osd set norebalance\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Unset the flags with ",(0,i.jsx)(n.code,{children:"ceph osd unset <flag>"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"rebalance-osds",children:"Rebalance OSDs"}),"\n",(0,i.jsx)(n.h2,{id:"placement-group-maintenance",children:"Placement Group maintenance"}),"\n",(0,i.jsx)(n.h3,{id:"dump-placement-groups",children:"Dump placement groups"}),"\n",(0,i.jsx)(n.p,{children:"Usually only useful when parsing it, so here are two ways to get the data:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph pg dump\n$ ceph pg dump --format=json-pretty\n"})}),"\n",(0,i.jsx)(n.h3,{id:"query-a-pg-about-its-status",children:"Query a PG about its status"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph pg <pgid> query\n"})}),"\n",(0,i.jsx)(n.h3,{id:"start-deep-scrubbing-of-a-placement-group",children:"Start (deep-)scrubbing of a placement group"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph pg scrub <pgid>\n$ ceph pg deep-scrub <pgid>\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Instructing a PG to (deep-)scrub does not mean that it will do so immediately,\nit can take some time for the scrub to start."})}),"\n",(0,i.jsx)(n.h3,{id:"health_warn---large-omap-objects-found",children:"HEALTH_WARN - Large omap objects found..."}),"\n",(0,i.jsx)(n.p,{children:"Finding PGs which have large OMAP objects:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# ceph pg dump --format=json | jq '.pg_map.pg_stats[] |\nselect(.stat_sum.num_large_omap_objects != 0) |\n(.pgid, .stat_sum.num_large_omap_objects, .up, .acting)'\n"})}),"\n",(0,i.jsxs)(n.p,{children:["(Remove the line breaks between the single quotes or ",(0,i.jsx)(n.code,{children:"jq"})," might act weird!)"]}),"\n",(0,i.jsxs)(n.p,{children:["This will dump all PG IDs with large OMAP objects and their up/acting OSDs.\nYou then can grep the logs of these OSDs for ",(0,i.jsx)(n.strong,{children:'"Large omap object"'}),"\nto find the actual objects causing the health warning."]}),"\n",(0,i.jsx)(n.p,{children:"Also the PG ID before the dot is equal to the pool ID it belongs to."}),"\n",(0,i.jsx)(n.p,{children:"In case the logs have been rotated, instruct those OSDs to do a deep-scrub\nand watch the logs for the message to appear."}),"\n",(0,i.jsx)(n.p,{children:"From there you can investigate the issue further,\nmostly it'll be due to the index of a RGW bucket getting too big due to too many objects,\nthus resharding that bucket's index will be necessary."}),"\n",(0,i.jsx)(n.h3,{id:"instruct-a-pg-to-repair-in-case-of-scrub-errors-inconsistent-pg",children:"Instruct a PG to repair in case of scrub errors (inconsistent PG)"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph pg repair <pgid>\n"})}),"\n",(0,i.jsxs)(n.admonition,{type:"note",children:[(0,i.jsxs)(n.p,{children:["Recovery might not start immediately and might take some time.\nYou can query the status of the recovery through ",(0,i.jsx)(n.code,{children:"ceph pg <pgid> query"}),".\nBe sure to read the Ceph manual about this topic ",(0,i.jsx)(n.em,{children:"thoroughly"}),":"]}),(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshooting-pg/",children:"https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshooting-pg/"})})]}),"\n",(0,i.jsx)(n.h2,{id:"rados-pool-maintenance",children:"RADOS Pool maintenance"}),"\n",(0,i.jsxs)(n.admonition,{type:"note",children:[(0,i.jsx)(n.p,{children:"Read the RADOS pool operations documentation in detail before playing around with pools.\nEspecially when considering making changes to the CRUSH map.\nWrong decisions there can lead to data loss or other catastrophic failures."}),(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/pools/",children:"https://docs.ceph.com/en/latest/rados/operations/pools/"})})]}),"\n",(0,i.jsx)(n.h3,{id:"get-pools-and-their-configuration",children:"Get pools and their configuration"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd pool ls detail\n"})}),"\n",(0,i.jsx)(n.h3,{id:"dump-all-crush-rules",children:"Dump all CRUSH rules"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd crush rule dump\n"})}),"\n",(0,i.jsx)(n.h3,{id:"get-autoscaler-status",children:"Get autoscaler status"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd pool autoscale-status\n"})}),"\n",(0,i.jsx)(n.h3,{id:"create-a-replicated-pool",children:"Create a replicated pool"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd pool create <pool_name> <pg_num> <pgp_num> replicated [<crush_rule_name>]\n"})}),"\n",(0,i.jsx)(n.h3,{id:"enabling-an-application-on-a-pool",children:"Enabling an application on a pool"}),"\n",(0,i.jsx)(n.p,{children:"Required, otherwise a health warning will be raised after some time."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd pool application enable <pool_name> <application_name> # Syntax\n$ ceph osd pool application enable cinder rbd # Example\n"})}),"\n",(0,i.jsx)(n.p,{children:"Typical application names are: rbd, rgw, cephfs"}),"\n",(0,i.jsx)(n.h3,{id:"delete-a-pool",children:"Delete a pool"}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"This will delete all data in that pool. There is no undo/undelete."})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd pool delete <pool_name> <pool_name> --yes-i-really-really-mean-it\n"})}),"\n",(0,i.jsxs)(n.admonition,{type:"note",children:[(0,i.jsxs)(n.p,{children:["In order to be able to delete pools, it has to be enabled on the monitors\nby setting the ",(0,i.jsx)(n.code,{children:"mon_allow_pool_delete"})," flag to true. Default is false."]}),(0,i.jsxs)(n.p,{children:["See: ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/configuration/mon-config-ref",children:"https://docs.ceph.com/en/latest/rados/configuration/mon-config-ref"})]})]}),"\n",(0,i.jsx)(n.h3,{id:"set-number-of-pgs-for-a-pool",children:"Set number of PGs for a pool"}),"\n",(0,i.jsx)(n.p,{children:"If no autoscaling of PGs is used, it is very important to adapt the PGs per pool to the\nreal world when operating a Ceph cluster. If, for example, OSDs are exchanged, added, new\nnodes are added, etc., the number of PGs must also be taken into account."}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/pgcalc/",children:"PG Calc Tool"})," can be used\nto calculate a reasonable number of PGs per pool depending on all ODSs and pools."]}),"\n",(0,i.jsxs)(n.p,{children:["Further information on placement groups can be found in the\n",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/placement-groups/",children:"Ceph documentation"}),".\nYou should definitely read ",(0,i.jsx)(n.em,{children:"FACTORS RELEVANT TO SPECIFYING PG_NUM"})," and ",(0,i.jsx)(n.em,{children:"CHOOSING THE NUMBER OF PGS"}),"\nthere."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd pool set <poolname> pg_num <num_pgs>\n"})}),"\n",(0,i.jsxs)(n.admonition,{type:"note",children:[(0,i.jsx)(n.p,{children:"Num PGs must be a power of two! Be careful about changing number of PGs.\nChanging pg_num to a new value will gradually increase pgp_num on newer versions of Ceph."}),(0,i.jsx)(n.p,{children:"In older versions one also has to set pgp_num manually, either in increments or in one big leap."})]}),"\n",(0,i.jsx)(n.h3,{id:"create-crush-rules-for-different-storage-classes",children:"Create CRUSH rules for different storage classes"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd crush rule create-replicated replicated_hdd default host hdd\n$ ceph osd crush rule create-replicated replicated_ssd default host ssd\n$ ceph osd crush rule create-replicated replicated_nvme default host nvme\n"})}),"\n",(0,i.jsx)(n.h3,{id:"change-crush-rule-for-a-pool-move-pool",children:'Change CRUSH rule for a pool ("move pool")'}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd pool set <poolname> crush_rule <rule_name>\n"})}),"\n",(0,i.jsx)(n.p,{children:"This can be used to move a pool from e.g. HDD to SSD or NVME class\nor anything else that the new CRUSH rule specifies."}),"\n",(0,i.jsx)(n.h2,{id:"advanced-topics",children:"Advanced topics"}),"\n",(0,i.jsx)(n.h3,{id:"validating-ceph-using-osism-playbooks",children:"Validating Ceph using OSISM playbooks"}),"\n",(0,i.jsxs)(n.p,{children:["For Ceph, special playbooks were added to validate the deployment status of\nthe OSD, MON and MGR services. The commands for use are ",(0,i.jsx)(n.code,{children:"osism validate ceph-osds"}),",\n",(0,i.jsx)(n.code,{children:"osism validate ceph-mons"}),", and ",(0,i.jsx)(n.code,{children:"osism validate ceph-mgrs"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["These playbooks will validate that the deployed Ceph environment matches\nthe configuration and is overall in a healthy state. The playbooks will\ngenerate report files in JSON format on the first manager node in ",(0,i.jsx)(n.code,{children:"/opt/reports/validator"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"shutdown-a-ceph-cluster",children:"Shutdown a Ceph cluster"}),"\n",(0,i.jsx)(n.p,{children:"In order to fully shutdown a Ceph cluster safely, you first do the following steps:"}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"Take GOOD NOTES of the unit names and OSD IDs running on each node.\nYou will need them to restart the cluster later."})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Stop the workload that is using the cluster"}),"\n",(0,i.jsx)(n.p,{children:"This will vary depending on your environment and is not covered here."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Pause/Stop operations on the cluster by setting flags"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd set noout\n$ ceph osd set nobackfill\n$ ceph osd set norecover\n$ ceph osd set norebalance\n$ ceph osd set nodown\n$ ceph osd set pause\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Stop and disable the ",(0,i.jsx)(n.code,{children:"radosgw"})," services on all nodes (on each rgw node) (if RGW is used)"]}),"\n",(0,i.jsx)(n.p,{children:"Get the name of the unit (globs not supported for disable) and\nmake a note of the unit name for that node:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl | grep ceph-radosgw\n"})}),"\n",(0,i.jsx)(n.p,{children:"Then disable and stop the unit:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl disable --now ceph-radosgw@<name>.service\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Stop all CephFS file systems (if CephFS is used)"}),"\n",(0,i.jsx)(n.p,{children:"List all Ceph file systems"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph fs ls\n"})}),"\n",(0,i.jsx)(n.p,{children:"For each CephFS do:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph fs <file system name> down true\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["After that disable and stop all ",(0,i.jsx)(n.code,{children:"ceph-mds"})," services on all nodes (do this on each node)"]}),"\n",(0,i.jsx)(n.p,{children:"Get the name of the unit (globs not supported for disable) and\nmake a note of the unit name for that node:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl | grep ceph-mds\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl disable --now ceph-mds@<unit>.service\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Stop and disable the ",(0,i.jsx)(n.code,{children:"ceph-mgr"})," services on all nodes (do this on each node)"]}),"\n",(0,i.jsx)(n.p,{children:"Get the name of the unit (globs not supported for disable) and\nmake a note of the unit name for that node:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl | grep ceph-mgr\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl disable --now ceph-mgr@<unit>.service\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Stop and disable the ",(0,i.jsx)(n.code,{children:"ceph-osd"})," services on all nodes (do this on each node)"]}),"\n",(0,i.jsx)(n.p,{children:"Get the names of the units (globs not supported for disable) and\nmake a note of the unit names for that node (best to save it to a file):"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl | grep ceph-osd\n"})}),"\n",(0,i.jsx)(n.p,{children:"For each OSD unit execute:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl disable ceph-osd@<osd-id>.service\n"})}),"\n",(0,i.jsx)(n.p,{children:"Stop all OSDs at once:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl stop ceph-osd\\*.service\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Finally stop the ",(0,i.jsx)(n.code,{children:"ceph-mon"})," services on all nodes (do this on each node)"]}),"\n",(0,i.jsx)(n.p,{children:"Get the name of the unit (globs not supported for disable) and\nmake a note of the unit name for that node:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl | grep ceph-mon\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl disable --now ceph-mon@<unit>.service\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"restart-a-ceph-cluster-after-manual-shutdown",children:"Restart a Ceph cluster after manual shutdown"}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["You will need the notes taken during shutdown of the unit names.\nIt ",(0,i.jsx)(n.strong,{children:"can"})," be done without, but then it'll be way more work finding out the names."]})}),"\n",(0,i.jsx)(n.p,{children:"In order to restart a Ceph cluster after performing a manual shutdown like described\nin the section above, you do the following:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Enable & start the ",(0,i.jsx)(n.code,{children:"ceph-mon"})," services on all nodes (do this on each node)"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl enable --now ceph-mon@<unit-name>.service\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Enable & start the ",(0,i.jsx)(n.code,{children:"ceph-osd"})," services on all nodes (do this on each node)"]}),"\n",(0,i.jsx)(n.p,{children:"For each Ceph OSD on that node do:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl enable --now ceph-osd@<osd-id>.service\n"})}),"\n",(0,i.jsx)(n.p,{children:"Depending on the number of OSDs on that node it can take a while."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Enable & start the ",(0,i.jsx)(n.code,{children:"ceph-mgr"})," services on all nodes (do this on each node)"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl enable --now ceph-mgr@<unit-name>.service\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check the status of your cluster and wait for all OSDs to come online"}),"\n",(0,i.jsx)(n.p,{children:"You can watch the status periodically by running:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ watch ceph -s\n"})}),"\n",(0,i.jsx)(n.p,{children:"You should wait until all OSDs are up + in again, before removing flags."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Remove flags to unpause operations"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph osd unset pause\n$ ceph osd unset nodown\n$ ceph osd unset noout\n$ ceph osd unset nobackfill\n$ ceph osd unset norecover\n$ ceph osd unset norebalance\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Wait for cluster to resume operations"}),"\n",(0,i.jsx)(n.p,{children:'See step #4 of this SOP.\nNow you wait until the cluster seems "happy enough" to accept clients.\n(i.e. rebalancing finished etc.)\nMaybe it will complain about MDS being down, but that\'s normal for now.'}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Enable & start the ",(0,i.jsx)(n.code,{children:"ceph-mds"})," services on each node (if CephFS is used)"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl enable --now ceph-mds@<unit>.service\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Start CephFS file systems again"}),"\n",(0,i.jsx)(n.p,{children:"List all Ceph file systems"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph fs ls\n"})}),"\n",(0,i.jsx)(n.p,{children:"For each CephFS do:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ ceph fs <file system name> down false\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Enable & start the ",(0,i.jsx)(n.code,{children:"radosgw"})," services on each node (if RGW is used)"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# systemctl enable --now ceph-radosgw@<name>.service\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"performance-benchmark",children:"Performance benchmark"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# apt-get install -y fio\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'#!/usr/bin/env bash\n\nBENCH_DEVICE="$2"\nDATE=$(date +%s)\nIOENGINE="libaio"\nLOGPATH="$1"\nSIZE=1G\n\nmkdir -p $LOGPATH\n\nfor RW in "write" "randwrite" "read" "randread"\ndo\n for BS in "4K" "64K" "1M" "4M" "16M" "64M"\n do\n (\n echo "==== $RW - $BS - DIRECT ===="\n echo 3 > /proc/sys/vm/drop_caches\n fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json\n sync\n echo 3 > /proc/sys/vm/drop_caches\n echo "==== $RW - $BS - DIRECT IODEPTH 32 ===="\n fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --iodepth=32 --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-iod32-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json\n sync\n ) | tee $LOGPATH/$RW.$BS-$(basename $BENCH_DEVICE).$DATE.log\n echo\n done\ndone\n'})}),"\n",(0,i.jsx)(n.h2,{id:"where-and-how-to-get-further-help",children:"Where and how to get further help"}),"\n",(0,i.jsxs)(n.p,{children:["Join the ",(0,i.jsx)(n.strong,{children:"#ceph"})," IRC channel on ",(0,i.jsx)(n.strong,{children:"irc.oftc.net"}),', state the problem with as many details as possible\nincluding information about what steps have already been taken to solve the problem\nalso provide information from the command output from the "60 seconds cluster overview" above\nthrough a pastebin or a similar service. In order for people to be able\nto help, details and some patience are important.']})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>d});var o=s(96540);const i={},t=o.createContext(i);function r(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5e95c892.510adb24.js b/assets/js/5e95c892.510adb24.js new file mode 100644 index 0000000000..6b000ab1e4 --- /dev/null +++ b/assets/js/5e95c892.510adb24.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9647],{7121:(e,s,r)=>{r.r(s),r.d(s,{default:()=>l});r(96540);var c=r(18215),u=r(61213),a=r(17559),d=r(22831),n=r(59504),t=r(74848);function l(e){return(0,t.jsx)(u.e3,{className:(0,c.A)(a.G.wrapper.docsPages),children:(0,t.jsx)(n.A,{children:(0,d.v)(e.route.routes)})})}}}]); \ No newline at end of file diff --git a/assets/js/5f46a90e.dc07a7ac.js b/assets/js/5f46a90e.dc07a7ac.js new file mode 100644 index 0000000000..67c1d3399b --- /dev/null +++ b/assets/js/5f46a90e.dc07a7ac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[66947],{79421:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Container Registry","slug":"/category/container-registry","permalink":"/docs/category/container-registry","sidebar":"docs","navigation":{"previous":{"title":"Configuration","permalink":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration"},"next":{"title":"Quickstart","permalink":"/docs/container/components/container-registry/docs/quickstart"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/6019e202.bd6b2e0c.js b/assets/js/6019e202.bd6b2e0c.js new file mode 100644 index 0000000000..9bf616fdff --- /dev/null +++ b/assets/js/6019e202.bd6b2e0c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[50640],{76060:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","title":"Overview","description":"Architecture","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/architecture","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview"},"next":{"title":"Getting Started","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart"}}');var n=s(74848),o=s(28453);const a={},c="Overview",i={},l=[{value:"Architecture",id:"architecture",level:2},{value:"Cluster stacks",id:"cluster-stacks",level:2},{value:"Cluster Stack Operator",id:"cluster-stack-operator",level:2},{value:"Cluster Stack Provider Integrations",id:"cluster-stack-provider-integrations",level:2},{value:"Steps to make cluster stacks ready to use",id:"steps-to-make-cluster-stacks-ready-to-use",level:2},{value:"Defining a cluster stack",id:"defining-a-cluster-stack",level:3},{value:"Implementing a cluster stack",id:"implementing-a-cluster-stack",level:3},{value:"Implementing a Cluster Stack Provider Integration",id:"implementing-a-cluster-stack-provider-integration",level:3},{value:"Using everything",id:"using-everything",level:3}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,n.jsx)(t.h2,{id:"architecture",children:"Architecture"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Cluster Stacks",src:s(29320).A+"",width:"1718",height:"1024"})}),"\n",(0,n.jsx)(t.h2,{id:"cluster-stacks",children:"Cluster stacks"}),"\n",(0,n.jsx)(t.p,{children:"The cluster stacks are opinionated templates of clusters in which all configuration and all core components are defined. They can be implemented on any provider."}),"\n",(0,n.jsx)(t.p,{children:"There can be multiple cluster stacks that acknowledge the many ways in which a cluster can be set up. There is no right or wrong and cluster stacks make sure that the flexibility is not lost."}),"\n",(0,n.jsx)(t.p,{children:"At the same time, they offer ready-made templates for users, who do not have to spend a lot of thought on how to build clusters so that everything works well together."}),"\n",(0,n.jsx)(t.p,{children:"Cluster stacks are implemented by two Helm charts. The first one contains all Cluster API objects and is applied in the management cluster. The second Helm chart contains the cluster addons, i.e. the core components every cluster needs, and is installed in the workload clusters."}),"\n",(0,n.jsx)(t.p,{children:"Furthermore, there are node images that can look quite different depending on the provider."}),"\n",(0,n.jsx)(t.p,{children:"To sum up, there are three components of a cluster stack:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"Cluster addons: The cluster addons (CNI, CSI, CCM) have to be applied in each workload cluster that the user starts"}),"\n",(0,n.jsxs)(t.li,{children:["Cluster API objects: The ",(0,n.jsx)(t.code,{children:"ClusterClass"})," object makes it easier to use Cluster-API. The cluster stack contains a ",(0,n.jsx)(t.code,{children:"ClusterClass"})," object and other Cluster-API objects that are necessary in order to use the ",(0,n.jsx)(t.code,{children:"ClusterClass"}),". These objects have to be applied in the management cluster."]}),"\n",(0,n.jsx)(t.li,{children:"Node images: Node images can be provided to the user in different form. They are released and tested together with the other two components of the cluster stack."}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["More information about cluster stacks and their three parts can be found in ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks/blob/main/README.md",children:"https://github.com/SovereignCloudStack/cluster-stacks/blob/main/README.md"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"cluster-stack-operator",children:"Cluster Stack Operator"}),"\n",(0,n.jsx)(t.p,{children:"The Cluster Stack Operator takes care of all steps that have to be done in order to use a certain cluster stack implementation."}),"\n",(0,n.jsx)(t.p,{children:"It has to be installed in the management cluster and can be interacted with by applying custom resources. It extends the functionality of the Cluster API operators."}),"\n",(0,n.jsx)(t.p,{children:"The Cluster Stack Operator mainly applies the two Helm charts from a cluster stack implementation. It is also able to automatically fetch a remote Github repository to see whether there are new releases of a certain cluster stack."}),"\n",(0,n.jsx)(t.p,{children:"The first and second component of a cluster stack are handled by the Cluster Stack Operator."}),"\n",(0,n.jsxs)(t.p,{children:["The node images, on the other hand, have to be handled by separate provider integrations, similar to the ones that ",(0,n.jsx)(t.a,{href:"https://cluster-api.sigs.k8s.io/developer/providers/implementers-guide/overview",children:"Cluster-API uses"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"cluster-stack-provider-integrations",children:"Cluster Stack Provider Integrations"}),"\n",(0,n.jsxs)(t.p,{children:["The Cluster Stack Operator is accompanied by Cluster Stack Provider Integrations. A provider integration is also an operator that works together with the Cluster Stack Operator in a specific way, which is described in the docs about building ",(0,n.jsx)(t.a,{href:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration",children:"provider integrations"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"A provider integration makes sure that the node images are taken care of and made available to the user."}),"\n",(0,n.jsxs)(t.p,{children:["If there is no work to be done for node images, then the Cluster Stack Operator can work in ",(0,n.jsx)(t.code,{children:"noProvider"})," mode and this Cluster Stack Provider Integration can be omitted."]}),"\n",(0,n.jsx)(t.h2,{id:"steps-to-make-cluster-stacks-ready-to-use",children:"Steps to make cluster stacks ready to use"}),"\n",(0,n.jsx)(t.p,{children:"There are many steps that are needed in order to make cluster stacks ready to use. In order to understand the full flow better and to get an idea of how much work there is and how many personas are involved, we will give an overview of how to start from scratch with a new cluster stack and provider."}),"\n",(0,n.jsx)(t.p,{children:"We will assume that this operator exists, but that you want to use a new cluster stack and provider."}),"\n",(0,n.jsx)(t.h3,{id:"defining-a-cluster-stack",children:"Defining a cluster stack"}),"\n",(0,n.jsx)(t.p,{children:"First, you need to define your cluster stack. Which cluster addons do you need? How do your node images look like? You need to take these decisions and write them down."}),"\n",(0,n.jsx)(t.h3,{id:"implementing-a-cluster-stack",children:"Implementing a cluster stack"}),"\n",(0,n.jsx)(t.p,{children:"The next step is to implement your cluster stack for your provider. You can take existing implementations as reference, but need to think of how the provider-specific custom resources are called and how the respective Cluster API Provider Integration works."}),"\n",(0,n.jsx)(t.h3,{id:"implementing-a-cluster-stack-provider-integration",children:"Implementing a Cluster Stack Provider Integration"}),"\n",(0,n.jsx)(t.p,{children:"We assume that you need to do some manual tasks in order to make node images accessible on your provider. These steps should be implemented in a Cluster Stack Provider Integration, which of course has to work together with the details of how you implemented your cluster stack."}),"\n",(0,n.jsx)(t.h3,{id:"using-everything",children:"Using everything"}),"\n",(0,n.jsx)(t.p,{children:"Finally, you can use the new cluster stack you defined and implemented on the infrastructure of your provider. Enjoy!"})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},29320:(e,t,s)=>{s.d(t,{A:()=>r});const r=s.p+"assets/images/syself-cluster-stacks-web-61b777e4fdfc3357ad1f7f8e4b6e1864.png"},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>c});var r=s(96540);const n={},o=r.createContext(n);function a(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/604a51e1.853bf504.js b/assets/js/604a51e1.853bf504.js new file mode 100644 index 0000000000..d834acbc78 --- /dev/null +++ b/assets/js/604a51e1.853bf504.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[61976],{19186:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"scs-0119-v1-rook-decision","title":"Replacement of the deprecated ceph-ansible tool","description":"Abstract","source":"@site/standards/scs-0119-v1-rook-decision.md","sourceDirName":".","slug":"/scs-0119-v1-rook-decision","permalink":"/standards/scs-0119-v1-rook-decision","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Replacement of the deprecated ceph-ansible tool","type":"Decision Record","status":"Draft","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0119: Replacement of the deprecated ceph-ansible tool","permalink":"/standards/iaas/scs-0119"},"next":{"title":"scs-0120: Cluster-API images","permalink":"/standards/iaas/scs-0120"}}');var i=n(74848),s=n(28453);const r={title:"Replacement of the deprecated ceph-ansible tool",type:"Decision Record",status:"Draft",track:"IaaS"},a=void 0,l={},c=[{value:"Abstract",id:"abstract",level:2},{value:"Context",id:"context",level:2},{value:"Comparison of Features",id:"comparison-of-features",level:3},{value:"Feature Decision Table",id:"feature-decision-table",level:4},{value:"Evaluation in the Light of SCS Community Plans and Preferences",id:"evaluation-in-the-light-of-scs-community-plans-and-preferences",level:4},{value:"Decision",id:"decision",level:2},{value:"Consequences",id:"consequences",level:2}];function d(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"abstract",children:"Abstract"}),"\n",(0,i.jsxs)(t.p,{children:["This decision record evaluates the choice for a modern, future-proof deployment tool for the networked storage solution Ceph in the SCS reference implementation, ",(0,i.jsx)(t.a,{href:"https://osism.tech/",children:"OSISM"}),".\nThe new deployment tool aims to enhance Kubernetes integration within SCS, potentially allowing providers to manage the Ceph cluster with greater ease and efficiency."]}),"\n",(0,i.jsx)(t.h2,{id:"context",children:"Context"}),"\n",(0,i.jsxs)(t.p,{children:["The current reference implementation relies on ",(0,i.jsx)(t.code,{children:"ceph-ansible"}),", ",(0,i.jsx)(t.a,{href:"https://github.com/ceph/ceph-ansible/commit/a9d1ec844d24fcc3ddea7c030eff4cd6c414d23d",children:"which is now deprecated"}),". As a result, this decision record evaluates two alternatives: ",(0,i.jsx)(t.a,{href:"https://docs.ceph.com/en/latest/cephadm/",children:"Cephadm"})," and ",(0,i.jsx)(t.a,{href:"https://rook.io/docs/rook/latest-release/Getting-Started/intro/",children:"Rook"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["Both tools are designed to roll out and configure Ceph clusters, providing the capability to manage clusters throughout their lifecycle. This includes functionalities such as adding or removing OSDs, upgrading Ceph services, and managing CRUSH maps, as outlined in the ",(0,i.jsx)(t.a,{href:"#feature-decision-table",children:"Feature-Decision-Table"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"This decision record considers both the current and future needs of the reference implementation. The decision is guided by a comprehensive comparison of each tool's capabilities and limitations as well as the SCS communities needs and futures objectives."}),"\n",(0,i.jsx)(t.h3,{id:"comparison-of-features",children:"Comparison of Features"}),"\n",(0,i.jsx)(t.p,{children:"The tool selected in this decision MUST ensure:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"ease of migration"}),"\n",(0,i.jsx)(t.li,{children:"future-proofness"}),"\n",(0,i.jsx)(t.li,{children:"feature-completeness and feature-maturity"}),"\n",(0,i.jsx)(t.li,{children:"effective management of Ceph clusters"}),"\n"]}),"\n",(0,i.jsx)(t.h4,{id:"feature-decision-table",children:"Feature Decision Table"}),"\n",(0,i.jsx)(t.p,{children:"A comparative analysis of Cephadm and Rook highlights the following:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Feature"}),(0,i.jsx)(t.th,{children:"Supported in Cephadm"}),(0,i.jsx)(t.th,{children:"Supported in Rook"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Migrate from other setups"}),(0,i.jsxs)(t.td,{children:["\u2611 Adoption of clusters, that where built with ceph-ansible ",(0,i.jsx)(t.a,{href:"https://docs.ceph.com/en/quincy/cephadm/adoption/",children:"is officially supported"}),"."]}),(0,i.jsxs)(t.td,{children:["\u2610 Migration from other setups is not offically supported. See this ",(0,i.jsx)(t.a,{href:"https://github.com/rook/rook/discussions/12045",children:"issue"}),". Consequently, SCS develops a migration tool, named ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/rookify",children:"rookify"}),". Alternatively, Rook allows to use ",(0,i.jsx)(t.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/external-cluster/external-cluster/",children:"Ceph as an external cluster"}),"."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Connect RGW with OpenStack Keystone"}),(0,i.jsx)(t.td,{children:"\u2611"}),(0,i.jsx)(t.td,{children:"\u2611 Experimental"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Deploy specific Ceph versions"}),(0,i.jsx)(t.td,{children:"\u2611"}),(0,i.jsx)(t.td,{children:"\u2611"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Upgrade to specific Ceph versions"}),(0,i.jsx)(t.td,{children:"\u2611 Streamlined upgrade process."}),(0,i.jsxs)(t.td,{children:["\u2611 Rook, CSI and Ceph upgrades have to be aligned, there is a ",(0,i.jsx)(t.a,{href:"https://rook.io/docs/rook/latest-release/Upgrade/health-verification/",children:"guide"})," available for each Rook version."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Deploy Ceph Monitors"}),(0,i.jsx)(t.td,{children:"\u2611"}),(0,i.jsx)(t.td,{children:"\u2611"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Deploy Ceph Managers"}),(0,i.jsx)(t.td,{children:"\u2611"}),(0,i.jsx)(t.td,{children:"\u2611"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Deploy Ceph OSDs"}),(0,i.jsx)(t.td,{children:"\u2611"}),(0,i.jsx)(t.td,{children:"\u2611"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Deploy Ceph Object Gateway (RGW)"}),(0,i.jsx)(t.td,{children:"\u2611"}),(0,i.jsx)(t.td,{children:"\u2611"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Removal of nodes"}),(0,i.jsx)(t.td,{children:"\u2611"}),(0,i.jsx)(t.td,{children:"\u2611"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Purging of complete cluster"}),(0,i.jsx)(t.td,{children:"\u2611"}),(0,i.jsx)(t.td,{children:"\u2611"})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"\u2610 not supported (yet)\n\u2611 supported\n\u2611\u2611 better option\n\u2612 not supported on purpose"}),"\n",(0,i.jsx)(t.h4,{id:"evaluation-in-the-light-of-scs-community-plans-and-preferences",children:"Evaluation in the Light of SCS Community Plans and Preferences"}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Environment"}),": Cephadm is better suited for traditional or standalone environments. Conversely, Rook is tailored for Kubernetes. That being said, it's important to note that the current state of resource deployment and management on Kubernetes within the IaaS reference implementation is still in its early stages. This would make Rook one of the first components to utilise Kubernetes in OSISM."]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Deployment"}),": Cephadm uses containerization for Ceph components, whereas Rook fully embraces the Kubernetes ecosystem for deployment and management. Although containerization is already a core concept in the reference implementation, there is a strong push from the SCS community to adopt more Kubernetes."]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Configuration and Management"}),": Rook offers a more straightforward experience for those already utilizing Kubernetes, leveraging Kubernetes' features for automation and scaling. In contrast, Cephadm grants finer control over Ceph components, albeit necessitating more manual intervention. In both cases, this is something that needs to be partly abstracted by the reference implementation."]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Integration"}),": Rook provides better integration with cloud-native tools and environments, whereas Cephadm offers a more Ceph-centric management experience."]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Migration"}),": Rook does not currently provide any migration support, while Cephadm does offer this capability. However, the SCS community is highly supportive of developing a migration tool (Rookify) for Rook, as this would enhance SCS's influence by offering the first migration solution specifically for Rook providers."]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"SCS Community"}),": An important factor in our decision is the preferences and direction of the SCS community and its providers. There is a noticeable trend towards increased use of Kubernetes within the community. This indicates a preference for deployment tools that integrate well with Kubernetes environments."]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"SCS Future Goals"}),": The SCS community is open to building tools that provide open-source, publicly available solutions beyond the scope of SCS. This openness to development efforts that address limitations of the chosen tools, such as Rook, is also a key consideration in our decision."]}),"\n",(0,i.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(t.p,{children:"As OSISM will increasingly focus on a Kubernetes-centric approach for orchestration in the near future, adopting Rook is a more suitable and standardized approach. Moreover, many service providers within the SCS community (including several who deploy OSISM) already have experience with Kubernetes. Regarding the missing OpenStack Keystone integration, we are confident that colleagues, who work on this issue, will provide a solution in a timely manner. We expect that deploying Ceph with Rook will simplify deployment and configuration form the outset.\nIn order to allow for a migration from existing Ceph installations to Rook, we decided to develop a migration tool (called Rookify) for the reference implementation. If the development of Rookify goes beyond the targeted scope of the reference implementation the tool will add value to the Ceph as well as the Rook community."}),"\n",(0,i.jsx)(t.h2,{id:"consequences",children:"Consequences"}),"\n",(0,i.jsx)(t.p,{children:"Migrating an existing Ceph environment onto Kubernetes, as well as bringing together existing but independent Ceph and Kubernetes environments, will become straight forward without much manual interference needed.\nLandscapes that currently do not deploy a Kubernetes cluster have to adapt and provide a Kubernetes cluster in the future."})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var o=n(96540);const i={},s=o.createContext(i);function r(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/60fc342f.9123f07e.js b/assets/js/60fc342f.9123f07e.js new file mode 100644 index 0000000000..5005fd8083 --- /dev/null +++ b/assets/js/60fc342f.9123f07e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[99525],{16664:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>p,frontMatter:()=>t,metadata:()=>s,toc:()=>r});const s=JSON.parse('{"id":"iaas/guides/configuration-guide/commons/packages","title":"Packages","description":"With the osism.commons.packages role, it is possible to add packages on a node","source":"@site/docs/02-iaas/guides/configuration-guide/commons/packages.md","sourceDirName":"02-iaas/guides/configuration-guide/commons","slug":"/iaas/guides/configuration-guide/commons/packages","permalink":"/docs/iaas/guides/configuration-guide/commons/packages","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/packages.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Packages"},"sidebar":"docs","previous":{"title":"Certificates","permalink":"/docs/iaas/guides/configuration-guide/commons/certificates"},"next":{"title":"Resolvconf","permalink":"/docs/iaas/guides/configuration-guide/commons/resolvconf"}}');var a=i(74848),c=i(28453);const t={sidebar_label:"Packages"},o="Packages",d={},r=[{value:"Distribution specific packages",id:"distribution-specific-packages",level:2},{value:"Debian",id:"debian",level:3},{value:"CentOS",id:"centos",level:3},{value:"Upgrade of packages",id:"upgrade-of-packages",level:2}];function l(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"packages",children:"Packages"})}),"\n",(0,a.jsxs)(n.p,{children:["With the ",(0,a.jsx)(n.code,{children:"osism.commons.packages"})," role, it is possible to add packages on a node\nThe parameters should be used in the inventory or in the\n",(0,a.jsx)(n.code,{children:"environments/configuration.yml"})," file."]}),"\n",(0,a.jsxs)(n.p,{children:["The role is applied during the bootstrap. The role can be applied manually using\n",(0,a.jsx)(n.code,{children:"osism apply packages"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"The following packages are installed by default."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"required_packages_default:\n - curl\n - dmidecode\n - ethtool\n - iotop\n - jq\n - lsscsi\n - ltrace\n - mtr\n - nvme-cli\n - pciutils\n - rsyslog\n - socat\n - sysstat\n - tmux\n - tree\n - whois\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Additional packages can be added via the ",(0,a.jsx)(n.code,{children:"required_packages_extra"})," parameter."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"required_packages_extra: []\n"})}),"\n",(0,a.jsx)(n.h2,{id:"distribution-specific-packages",children:"Distribution specific packages"}),"\n",(0,a.jsx)(n.h3,{id:"debian",children:"Debian"}),"\n",(0,a.jsxs)(n.p,{children:["With Debian, the packages listed in ",(0,a.jsx)(n.code,{children:"required_packages_distribution"})," are installed by default."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"required_packages_distribution:\n - command-not-found\n - debconf\n - debsums\n - htop\n - iftop\n - iperf\n - multitail\n - ncdu\n - pv\n - python-is-python3\n - selinux-utils\n - ssh\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"apt_cache_valid_time"})," parameter can be used to set the ",(0,a.jsx)(n.code,{children:"cache_valid_time"})," paremter\nof the ",(0,a.jsx)(n.code,{children:"ansible.builtin.apt"})," module. The module updates the apt cache if it is older than\nthe ",(0,a.jsx)(n.code,{children:"cache_valid_time"}),". The parameter is set in seconds and defaults to ",(0,a.jsx)(n.code,{children:"3600"}),"."]}),"\n",(0,a.jsx)(n.h3,{id:"centos",children:"CentOS"}),"\n",(0,a.jsxs)(n.p,{children:["With CentOS, the packages listed in ",(0,a.jsx)(n.code,{children:"required_packages_distribution"})," are installed by default."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"required_packages_distribution:\n - libselinux-utils\n - openssh\n"})}),"\n",(0,a.jsx)(n.h2,{id:"upgrade-of-packages",children:"Upgrade of packages"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"upgrade_packages"})," parameter can be used to configure the upgrade of packages.\nThe parameter is set to ",(0,a.jsx)(n.code,{children:"true"})," by default."]})]})}function p(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>t,x:()=>o});var s=i(96540);const a={},c=s.createContext(a);function t(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:t(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/61171858.031dde5a.js b/assets/js/61171858.031dde5a.js new file mode 100644 index 0000000000..a943f30a8a --- /dev/null +++ b/assets/js/61171858.031dde5a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[51400],{16999:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>o,contentTitle:()=>a,default:()=>l,frontMatter:()=>i,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"iaas/guides/concept-guide/use-cases","title":"Use cases","description":"Hyper-converged infrastructure (HCI)","source":"@site/docs/02-iaas/guides/concept-guide/use-cases.md","sourceDirName":"02-iaas/guides/concept-guide","slug":"/iaas/guides/concept-guide/use-cases","permalink":"/docs/iaas/guides/concept-guide/use-cases","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/use-cases.md","tags":[],"version":"current","sidebarPosition":40,"frontMatter":{"sidebar_label":"Use cases","sidebar_position":40},"sidebar":"docs","previous":{"title":"Cluster design","permalink":"/docs/iaas/guides/concept-guide/design"},"next":{"title":"Hardware Bill of Materials","permalink":"/docs/iaas/guides/concept-guide/hardware-bom"}}');var r=t(74848),c=t(28453);const i={sidebar_label:"Use cases",sidebar_position:40},a="Use cases",o={},d=[{value:"Hyper-converged infrastructure (HCI)",id:"hyper-converged-infrastructure-hci",level:2}];function u(e){const s={h1:"h1",h2:"h2",header:"header",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"use-cases",children:"Use cases"})}),"\n",(0,r.jsx)(s.h2,{id:"hyper-converged-infrastructure-hci",children:"Hyper-converged infrastructure (HCI)"})]})}function l(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>a});var n=t(96540);const r={},c=n.createContext(r);function i(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/621db11d.bdeb36a5.js b/assets/js/621db11d.bdeb36a5.js new file mode 100644 index 0000000000..5d531e7390 --- /dev/null +++ b/assets/js/621db11d.bdeb36a5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[64212],{13250:(t,e,s)=>{s.r(e),s.d(e,{default:()=>m});s(96540);var a=s(18215),o=s(61213),r=s(17559),l=s(96461),u=s(28027),n=s(41463),i=s(51107),c=s(56913);const h={authorListItem:"authorListItem_n3yI"};var g=s(74848);function p(t){let{author:e}=t;return(0,g.jsx)("li",{className:h.authorListItem,children:(0,g.jsx)(c.A,{as:"h2",author:e,count:e.count})})}function d(t){let{authors:e}=t;return(0,g.jsx)("section",{className:(0,a.A)("margin-vert--lg",h.authorsListSection),children:(0,g.jsx)("ul",{children:e.map((t=>(0,g.jsx)(p,{author:t},t.key)))})})}function m(t){let{authors:e,sidebar:s}=t;const c=(0,l.uz)();return(0,g.jsxs)(o.e3,{className:(0,a.A)(r.G.wrapper.blogPages,r.G.page.blogAuthorsListPage),children:[(0,g.jsx)(o.be,{title:c}),(0,g.jsx)(n.A,{tag:"blog_authors_list"}),(0,g.jsxs)(u.A,{sidebar:s,children:[(0,g.jsx)(i.A,{as:"h1",children:c}),(0,g.jsx)(d,{authors:e})]})]})}},96461:(t,e,s)=>{s.d(e,{ZD:()=>l,uz:()=>u});s(96540);var a=s(21312),o=s(53465);s(74848);function r(){const{selectMessage:t}=(0,o.W)();return e=>t(e,(0,a.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:e}))}function l(t){const e=r();return(0,a.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:e(t.count),tagName:t.label})}const u=()=>(0,a.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"})}}]); \ No newline at end of file diff --git a/assets/js/62337dff.287ce250.js b/assets/js/62337dff.287ce250.js new file mode 100644 index 0000000000..c8969224e7 --- /dev/null +++ b/assets/js/62337dff.287ce250.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[89376],{61278:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>s,metadata:()=>a,toc:()=>d});const a=JSON.parse('{"id":"collaboration/team-iam","title":"Team IAM","description":"The Team IAM deals with topics around Identity and Access Management.","source":"@site/community/collaboration/team-iam.md","sourceDirName":"collaboration","slug":"/collaboration/team-iam","permalink":"/community/collaboration/team-iam","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Team Iaas","permalink":"/community/collaboration/team-iaas"},"next":{"title":"Team Container","permalink":"/community/collaboration/team-container"}}');var o=n(74848),r=n(28453);const s={},i="Team IAM",c={},d=[];function l(e){const t={h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"team-iam",children:"Team IAM"})}),"\n",(0,o.jsx)(t.p,{children:"The Team IAM deals with topics around Identity and Access Management."}),"\n",(0,o.jsx)(t.p,{children:"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)."}),"\n",(0,o.jsx)(t.p,{children:"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."})]})}function m(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>i});var a=n(96540);const o={},r=a.createContext(o);function s(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/631b9b66.f4f4c562.js b/assets/js/631b9b66.f4f4c562.js new file mode 100644 index 0000000000..b4dade78f0 --- /dev/null +++ b/assets/js/631b9b66.f4f4c562.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[71682],{84512:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"scs-0211-v2-kaas-default-storage-class","title":"SCS KaaS default storage class","description":"The SCS-0211 standard ensures that a default StorageClass with specific characteristics is available to KaaS users.\\n","source":"@site/standards/scs-0211-v2-kaas-default-storage-class.md","sourceDirName":".","slug":"/scs-0211-v2-kaas-default-storage-class","permalink":"/standards/scs-0211-v2-kaas-default-storage-class","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS KaaS default storage class","type":"Standard","status":"Draft","replaces":"scs-0211-v1-kaas-default-storage-class.md","track":"KaaS","description":"The SCS-0211 standard ensures that a default StorageClass with specific characteristics is available to KaaS users.\\n"},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0211-v1-kaas-default-storage-class"},"next":{"title":"W1","permalink":"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing"}}');var r=t(74848),n=t(28453);const o={title:"SCS KaaS default storage class",type:"Standard",status:"Draft",replaces:"scs-0211-v1-kaas-default-storage-class.md",track:"KaaS",description:"The SCS-0211 standard ensures that a default StorageClass with specific characteristics is available to KaaS users.\n"},i=void 0,l={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Decision",id:"decision",level:2},{value:"Recommended non-performance-related properties",id:"recommended-non-performance-related-properties",level:3},{value:"Required performance-related properties",id:"required-performance-related-properties",level:3},{value:"Previous standard versions",id:"previous-standard-versions",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function d(e){const s={a:"a",br:"br",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsx)(s.p,{children:"This is the standard v2 for SCS Release 7."}),"\n",(0,r.jsxs)(s.p,{children:["Cluster consumers can request persistent storage via ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims",children:(0,r.jsx)(s.code,{children:"PersistentVolumeClaims"})}),", which is provisioned\nautomatically by cloud-provided automation.\nStorage requirements may vary across use cases, so there is the concept of storage classes (",(0,r.jsx)(s.code,{children:"StorageClass"}),").\nStorage classes define some set of storage properties and consumers can choose one of these depending on the use case."]}),"\n",(0,r.jsx)(s.h2,{id:"motivation",children:"Motivation"}),"\n",(0,r.jsx)(s.p,{children:"A lot of third-party software, such as Helm charts, assume that a default storage class is configured.\nThus, for an out-of-the-box working experience, a SCS compliant Kubernetes cluster should come\npreconfigured with a sensible default storage class providing persistent storage."}),"\n",(0,r.jsx)(s.h2,{id:"decision",children:"Decision"}),"\n",(0,r.jsxs)(s.p,{children:["A freshly provisioned Kubernetes cluster MUST have a default storage class, i.e., a ",(0,r.jsx)(s.code,{children:"StorageClass"}),"\nobject that is annotated with ",(0,r.jsx)(s.code,{children:"storageclass.kubernetes.io/is-default-class=true"})," as described in the\n",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/",children:"Kubernetes documentation"}),".\nThe name of this storage class is not standardized."]}),"\n",(0,r.jsx)(s.h3,{id:"recommended-non-performance-related-properties",children:"Recommended non-performance-related properties"}),"\n",(0,r.jsx)(s.p,{children:"The following recommendations are not completely tested yet and therefore do not represent hard requirement criteria so far. Nevertheless, they are important prerequisites for ensuring data storage stability. Generally, these criteria are met by choosing the right provisioner such as Cinder CSI Provisioner. And this shall be cross-checked against a list of provisioners."}),"\n",(0,r.jsx)(s.p,{children:"If the persistent volumes (PV) provisioned by the provided default storage class are required to be failure-safe they MUST fulfill all\nof the following properties:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["MUST support the ",(0,r.jsx)(s.code,{children:"ReadWriteOnce"})," ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes",children:"access mode"}),"."]}),"\n",(0,r.jsx)(s.li,{children:"MUST NOT be bound to the lifecycle of a Kubernetes node."}),"\n",(0,r.jsxs)(s.li,{children:["MUST NOT be backed by local or ephemeral storage.",(0,r.jsx)(s.br,{}),"\n","This means:","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"MUST NOT be backed by local storage on the Kubernetes Node VM itself."}),"\n",(0,r.jsx)(s.li,{children:"MAY be backed by some kind of redundant storage within an AZ, across hosts."}),"\n",(0,r.jsx)(s.li,{children:"MAY be backed by some kind of redundant storage across AZ's."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Volumes that are not necessarily required to be failure-safe may be local/node-bound/non-redundant. This might be the case with fast to run applications that take care of data durability and availability on application level."}),"\n",(0,r.jsxs)(s.p,{children:["The provisioned storage class MAY support volume expansion (",(0,r.jsx)(s.code,{children:"allowVolumeExpansion=true"}),")."]}),"\n",(0,r.jsx)(s.h3,{id:"required-performance-related-properties",children:"Required performance-related properties"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.em,{children:"NO"})," fixed guarantees regarding latency/bandwidth/IOPS/etc.\nGenerally, customers should be able to expect low-tier performance without pricing surprises."]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"previous-standard-versions",children:"Previous standard versions"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/standards/scs-0211-v1-kaas-default-storage-class",children:"Version v1 of this standard"})," did not enforce the\nexistence of a default storage class in a newly created cluster."]}),"\n",(0,r.jsx)(s.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,r.jsxs)(s.p,{children:["Is currently under progress ",(0,r.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/pull/658",children:"stage: pull-request"}),"."]})]})}function u(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>o,x:()=>i});var a=t(96540);const r={},n=a.createContext(r);function o(e){const s=a.useContext(n);return a.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),a.createElement(n.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/63768f60.450b8941.js b/assets/js/63768f60.450b8941.js new file mode 100644 index 0000000000..82c4febcdd --- /dev/null +++ b/assets/js/63768f60.450b8941.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[86397],{16380:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>i});const r=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack","title":"clusterstack","description":"ClusterStack","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/reference","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack.md","tags":[],"version":"current","frontMatter":{}}');var c=s(74848),n=s(28453);const o={},l=void 0,a={},i=[{value:"ClusterStack",id:"clusterstack",level:2},{value:"Lifecycle of a ClusterStack",id:"lifecycle-of-a-clusterstack",level:3},{value:"Overview of ClusterStack.Spec",id:"overview-of-clusterstackspec",level:3},{value:"Example of the ClusterStack object",id:"example-of-the-clusterstack-object",level:3}];function d(e){const t={code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(t.h2,{id:"clusterstack",children:"ClusterStack"}),"\n",(0,c.jsxs)(t.p,{children:["The ",(0,c.jsx)(t.code,{children:"ClusterStack"})," object is the main resource for users to work with. It contains the most important details of a cluster stack and its releases (i.e. certain versions). In its status is the main source of information of the state of everything related to cluster stacks."]}),"\n",(0,c.jsx)(t.h3,{id:"lifecycle-of-a-clusterstack",children:"Lifecycle of a ClusterStack"}),"\n",(0,c.jsxs)(t.p,{children:["The ",(0,c.jsx)(t.code,{children:"ClusterStack"})," object has a sub-resource ",(0,c.jsx)(t.code,{children:"ClusterStackRelease"})," for every release that should be provided to the user, either by specifying them manually in the versions array, or automatically through the auto-subscribe functionality."]}),"\n",(0,c.jsxs)(t.p,{children:["The controller reconciles the two sources of information and checks whether for every release that should exist, there is actually one. It also deletes ",(0,c.jsx)(t.code,{children:"ClusterStackRelease"})," objects that are not required anymore."]}),"\n",(0,c.jsxs)(t.p,{children:["Additionally, it fetches information from the ",(0,c.jsx)(t.code,{children:"ClusterStackRelease"})," objects and populates its own state with it."]}),"\n",(0,c.jsxs)(t.p,{children:["In case that a provider integration is used, it will create ",(0,c.jsx)(t.code,{children:"ProviderClusterStackRelease"})," objects in addition to ",(0,c.jsx)(t.code,{children:"ClusterStackRelease"})," objects, based on the ",(0,c.jsx)(t.code,{children:"ProviderClusterStackReleaseTemplate"})," objects given as reference in ",(0,c.jsx)(t.code,{children:"spec.providerRef"}),"."]}),"\n",(0,c.jsx)(t.h3,{id:"overview-of-clusterstackspec",children:"Overview of ClusterStack.Spec"}),"\n",(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:"Key"}),(0,c.jsx)(t.th,{children:"Type"}),(0,c.jsx)(t.th,{children:"Default"}),(0,c.jsx)(t.th,{children:"Required"}),(0,c.jsx)(t.th,{children:"Description"})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:"provider"}),(0,c.jsx)(t.td,{children:"string"}),(0,c.jsx)(t.td,{}),(0,c.jsx)(t.td,{children:"yes"}),(0,c.jsx)(t.td,{children:'Name of the provider, e.g. "docker". It is used in various places, e.g. while fetching the respective release assets or while naming resources (ClusterStackReleases, ProviderClusterStackResources, etc.).'})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:"name"}),(0,c.jsx)(t.td,{children:"string"}),(0,c.jsx)(t.td,{}),(0,c.jsx)(t.td,{children:"yes"}),(0,c.jsx)(t.td,{children:"Name of the cluster stack. It is used as well for fetching release assets and other tasks."})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:"kubernetesVersion"}),(0,c.jsx)(t.td,{children:"string"}),(0,c.jsx)(t.td,{}),(0,c.jsx)(t.td,{children:"yes"}),(0,c.jsxs)(t.td,{children:["Kubernetes version in the format ",(0,c.jsx)(t.code,{children:"<majorVersion>.<minorVersion>"}),", e.g. 1.26. Specifies the Kubernetes minor version of the cluster stack that should be taken."]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:"channel"}),(0,c.jsx)(t.td,{children:"string"}),(0,c.jsx)(t.td,{children:"stable"}),(0,c.jsx)(t.td,{children:"no"}),(0,c.jsx)(t.td,{children:'Name of release channel that is used, e.g. stable channel ("v1", "v2", etc.) or beta channel (e.g. "v0-beta.1").'})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:"versions"}),(0,c.jsx)(t.td,{children:"[]string"}),(0,c.jsx)(t.td,{}),(0,c.jsx)(t.td,{children:"no"}),(0,c.jsx)(t.td,{children:"List of versions that the controller should make available of a cluster stack. Used only in case very specific versions are supposed to be used. Not required if always the latest versions should be made available."})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:"autoSubscribe"}),(0,c.jsx)(t.td,{children:"bool"}),(0,c.jsx)(t.td,{children:"true"}),(0,c.jsx)(t.td,{children:"no"}),(0,c.jsx)(t.td,{children:"Specifies whether the controller should automatically check whether there are new releases of the cluster stack and if so automatically download them."})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:"noProvider"}),(0,c.jsx)(t.td,{children:"bool"}),(0,c.jsx)(t.td,{children:"false"}),(0,c.jsx)(t.td,{children:"no"}),(0,c.jsx)(t.td,{children:"If set to true, the controller does not expect any provider-specific objects and just focuses on applying Cluster API objects in management cluster and cluster addons in all workload clusters."})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:"providerRef"}),(0,c.jsx)(t.td,{children:"object"}),(0,c.jsx)(t.td,{}),(0,c.jsx)(t.td,{children:"no"}),(0,c.jsx)(t.td,{children:"ProviderRef has to be specified if spec.noProvider is false. It references the ProviderClusterStackReleaseTemplate that contains all information to create the ProviderClusterStackRelease objects."})]})]})]}),"\n",(0,c.jsx)(t.h3,{id:"example-of-the-clusterstack-object",children:"Example of the ClusterStack object"}),"\n",(0,c.jsx)(t.p,{children:"You should create one of these objects for each of your bare metal servers that you want to use for your deployment."}),"\n",(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:"language-yaml",children:'apiVersion: clusterstack.x-k8s.io/v1alpha1\nkind: ClusterStack\nmetadata:\n name: clusterstack\n namespace: cluster\nspec:\n provider: docker\n name: ferrol\n kubernetesVersion: "1.27"\n channel: stable\n autoSubscribe: true\n noProvider: true\n'})})]})}function h(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>l});var r=s(96540);const c={},n=r.createContext(c);function o(e){const t=r.useContext(n);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),r.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/63c8fde6.2f7c854f.js b/assets/js/63c8fde6.2f7c854f.js new file mode 100644 index 0000000000..0affb5b6b4 --- /dev/null +++ b/assets/js/63c8fde6.2f7c854f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4168],{83139:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"scs-0101-v1-entropy","title":"SCS Entropy","description":"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations\\nsuch as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and\\nactivating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy\\naccessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into\\nvirtual instances and ensures the availability and quality of entropy in virtual environments, promoting system\\nsecurity and efficiency.\\n","source":"@site/standards/scs-0101-v1-entropy.md","sourceDirName":".","slug":"/scs-0101-v1-entropy","permalink":"/standards/scs-0101-v1-entropy","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Entropy","type":"Standard","status":"Stable","stabilized_at":"2024-02-08T00:00:00.000Z","track":"IaaS","description":"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations\\nsuch as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and\\nactivating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy\\naccessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into\\nvirtual instances and ensures the availability and quality of entropy in virtual environments, promoting system\\nsecurity and efficiency.\\n"},"sidebar":"standards","previous":{"title":"scs-0101: SCS Entropy","permalink":"/standards/iaas/scs-0101"},"next":{"title":"W1","permalink":"/standards/scs-0101-w1-entropy-implementation-testing"}}');var i=t(74848),r=t(28453);const o={title:"SCS Entropy",type:"Standard",status:"Stable",stabilized_at:new Date("2024-02-08T00:00:00.000Z"),track:"IaaS",description:"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations\nsuch as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and\nactivating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy\naccessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into\nvirtual instances and ensures the availability and quality of entropy in virtual environments, promoting system\nsecurity and efficiency.\n"},a=void 0,d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Entropy in information technology",id:"entropy-in-information-technology",level:3},{value:"Real-world uses of entropy",id:"real-world-uses-of-entropy",level:3},{value:"Sources of entropy",id:"sources-of-entropy",level:3},{value:"Entropy in virtual instances",id:"entropy-in-virtual-instances",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Entropy in SCS clouds",id:"entropy-in-scs-clouds",level:2},{value:"Flavors",id:"flavors",level:3},{value:"Images",id:"images",level:3},{value:"Compute nodes",id:"compute-nodes",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.h3,{id:"entropy-in-information-technology",children:"Entropy in information technology"}),"\n",(0,i.jsx)(n.p,{children:"Entropy is a concept that is widely used in the scope of information\ntechnology. It is a measurement of the amount of disorder or randomness in\na system. Entropy is used to measure the amount of information in a\nself-contained system, as well as the amount of incertitude that exists in this\nsystem."}),"\n",(0,i.jsx)(n.h3,{id:"real-world-uses-of-entropy",children:"Real-world uses of entropy"}),"\n",(0,i.jsxs)(n.p,{children:["Cryptography is a very prominent, albeit not the only application that\nheavily relies on entropy for operations such as creating secure keys.\nWhen the available ",(0,i.jsx)(n.em,{children:"entropy runs out"}),", said operations can stall and\ntake an abnormally long amount of time, which in turn can lead to\nmalfunctions, e.g., with OpenSSL or load balancers."]}),"\n",(0,i.jsx)(n.h3,{id:"sources-of-entropy",children:"Sources of entropy"}),"\n",(0,i.jsxs)(n.p,{children:["In ",(0,i.jsx)(n.em,{children:"traditional baremetal systems"})," the amount of incertitude is sourced\nfrom the randomness of the read/write cycles of the disk heads of a disk drive,\nbus timings, or keyboard timings, to name a few."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.em,{children:"More recent methods"})," of generating entropy include measuring IRQ jitter\n(available in Linux since kernel 5.4 or, before that, via a daemon such as\n",(0,i.jsx)(n.a,{href:"http://www.issihosts.com/haveged/",children:"HavegeD"}),") as well as dedicated CPU\ninstructions (available in virtually all major CPUs: RDSEED or RDRAND\non x86_64 and RNDR on arm64)."]}),"\n",(0,i.jsxs)(n.p,{children:["Finally, a dedicated device can be utilized \u2014 if present \u2014 that is\ncalled ",(0,i.jsx)(n.em,{children:"hardware random number generator"})," or HRNG for short. For instance,\nthe ",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Trusted_Platform_Module",children:"Trusted Platform Module"}),"\nincludes a HRNG. On Linux systems, the HRNG appears as ",(0,i.jsx)(n.code,{children:"/dev/hwrng"}),".\nNote that, while the dedicated CPU instructions can be construed as\na HRNG, they are not treated as such by the kernel, i.e., they ",(0,i.jsx)(n.em,{children:"do not"}),"\nappear as ",(0,i.jsx)(n.code,{children:"/dev/hwrng"}),"!"]}),"\n",(0,i.jsxs)(n.p,{children:["The Linux kernel combines multiple sources of entropy into a pool. To this\nend, it will use all the sources discussed so far with one exception:\nthe HRNG must be fed into the pool (if so desired) via the daemon ",(0,i.jsx)(n.code,{children:"rngd"}),".\nThe kernel converts the entropy from the pool into cryptographically\nsecure random numbers that appear under ",(0,i.jsx)(n.code,{children:"/dev/random"})," and ",(0,i.jsx)(n.code,{children:"/dev/urandom"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["With kernel 5.18, the algorithm that accomplishes\nsaid conversion has been drastically improved (see\n",(0,i.jsx)(n.a,{href:"https://web.archive.org/web/20230321040526/https://www.zx2c4.com/projects/linux-rng-5.17-5.18/",children:"linux-rng-5.17-18"}),"),\nso much so that running out of entropy is virtually ruled out.\nThese patches have now also arrived in the upstream LTS images."]}),"\n",(0,i.jsx)(n.h3,{id:"entropy-in-virtual-instances",children:"Entropy in virtual instances"}),"\n",(0,i.jsx)(n.p,{children:"Virtual instances or virtual machines do not have the traditional sources\nof entropy mentioned above. However, the more recent methods mentioned\nabove do work just fine (the CPU instructions are not privileged)."}),"\n",(0,i.jsxs)(n.p,{children:["Alternatively, a virtualized HRNG called ",(0,i.jsx)(n.code,{children:"virtio-rng"})," can be established\nthat injects entropy from the host into the instance, where this\nentropy can be sourced optionally from either the host's ",(0,i.jsx)(n.code,{children:"/dev/random"})," or\nsome HRNG in the host. This virtualized HRNG behaves just like a real\none, that is, it appears as ",(0,i.jsx)(n.code,{children:"/dev/hwrng"}),", and the daemon ",(0,i.jsx)(n.code,{children:"rngd"})," must\nbe used to feed it into the kernel's entropy pool."]}),"\n",(0,i.jsxs)(n.p,{children:["On a side note, the kernel exposes available HRNGs via the special\ndirectory ",(0,i.jsx)(n.code,{children:"/sys/devices/virtual/misc/hw_random"}),". In particular, the\nfile ",(0,i.jsx)(n.code,{children:"rng_available"})," lists available HRNGs while the file ",(0,i.jsx)(n.code,{children:"rng_current"}),"\ncontains the HRNG currently used."]}),"\n",(0,i.jsxs)(n.p,{children:["In summary, with current kernels and CPUs entropy in virtual instances\nis readily available to a sufficient degree. In addition, the host's\nentropy sources can be injected using ",(0,i.jsx)(n.code,{children:"virtio-rng"})," if so desired, e.g.,\nto enable access to a HRNG."]}),"\n",(0,i.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(n.p,{children:"As stated above, good sources of entropy are paramount for many\nimportant applications. This standard ensures that sufficient entropy\nwill be available in virtual instances."}),"\n",(0,i.jsx)(n.h2,{id:"entropy-in-scs-clouds",children:"Entropy in SCS clouds"}),"\n",(0,i.jsx)(n.h3,{id:"flavors",children:"Flavors"}),"\n",(0,i.jsx)(n.p,{children:"It is recommended that all flavors have the following attribute:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-console",children:"hw_rng:allowed=True\n"})}),"\n",(0,i.jsx)(n.p,{children:"The following attributes are optional:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-console",children:"hw_rng:rate_bytes - The allowed amount of bytes for the the guest\n to read from the host's entropy per period.\nhw_rng:rate_period - Sets the duration of a read period in seconds.\n"})}),"\n",(0,i.jsx)(n.h3,{id:"images",children:"Images"}),"\n",(0,i.jsxs)(n.p,{children:["It is recommended to use images having a kernel (patch level) version 5.18\nor up. This condition is already satisfied by every mandatory image defined\nin the ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0102-v1-image-metadata.md",children:"Image Metadata Standard"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["It is recommended that images activate the attribute ",(0,i.jsx)(n.code,{children:"hw_rng_model: virtio"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The daemon ",(0,i.jsx)(n.code,{children:"rngd"})," must be installed (usually from ",(0,i.jsx)(n.code,{children:"rng-tools"}),"\nor ",(0,i.jsx)(n.code,{children:"rng-utils"}),")."]}),"\n",(0,i.jsxs)(n.p,{children:["The user may choose to use the ",(0,i.jsx)(n.code,{children:"virtio-rng"})," device via ",(0,i.jsx)(n.code,{children:"rngd"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"compute-nodes",children:"Compute nodes"}),"\n",(0,i.jsx)(n.p,{children:"Compute nodes must use CPUs that offer instructions for accessing\nentropy (such as RDSEED or RDRAND on x86_64 or RNDR on arm64), and\nthese instructions may not be filtered by the hypervisor."}),"\n",(0,i.jsxs)(n.p,{children:["Compute nodes may provide a HRNG via ",(0,i.jsx)(n.code,{children:"rngd"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/640bb4cf.796304ba.js b/assets/js/640bb4cf.796304ba.js new file mode 100644 index 0000000000..53420d98ef --- /dev/null +++ b/assets/js/640bb4cf.796304ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6358],{79381:(e,n,d)=>{d.r(n),d.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>o,frontMatter:()=>i,metadata:()=>s,toc:()=>h});const s=JSON.parse('{"id":"scs-0100-w1-flavor-naming-implementation-testing","title":"SCS Flavor Naming Standard: Implementation and Testing Notes","description":"Introduction","source":"@site/standards/scs-0100-w1-flavor-naming-implementation-testing.md","sourceDirName":".","slug":"/scs-0100-w1-flavor-naming-implementation-testing","permalink":"/standards/scs-0100-w1-flavor-naming-implementation-testing","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Flavor Naming Standard: Implementation and Testing Notes","type":"Supplement","track":"IaaS","status":"Draft","supplements":["scs-0100-v1-flavor-naming.md","scs-0100-v2-flavor-naming.md","scs-0100-v3-flavor-naming.md"]},"sidebar":"standards","previous":{"title":"V3","permalink":"/standards/scs-0100-v3-flavor-naming"},"next":{"title":"scs-0101: SCS Entropy","permalink":"/standards/iaas/scs-0101"}}');var r=d(74848),t=d(28453);const i={title:"SCS Flavor Naming Standard: Implementation and Testing Notes",type:"Supplement",track:"IaaS",status:"Draft",supplements:["scs-0100-v1-flavor-naming.md","scs-0100-v2-flavor-naming.md","scs-0100-v3-flavor-naming.md"]},l=void 0,c={},h=[{value:"Introduction",id:"introduction",level:2},{value:"Implementation notes",id:"implementation-notes",level:2},{value:"Operational tooling",id:"operational-tooling",level:3},{value:"Syntax check",id:"syntax-check",level:4},{value:"Flavor creation",id:"flavor-creation",level:4},{value:"GPU table",id:"gpu-table",level:3},{value:"Nvidia (<code>N</code>)",id:"nvidia-n",level:4},{value:"Ampere (<code>a</code>)",id:"ampere-a",level:5},{value:"Ada Lovelave (<code>l</code>)",id:"ada-lovelave-l",level:5},{value:"Grace Hopper (<code>g</code>)",id:"grace-hopper-g",level:5},{value:"AMD Radeon (<code>A</code>)",id:"amd-radeon-a",level:4},{value:"CDNA 2 (<code>2</code>)",id:"cdna-2-2",level:5},{value:"CDNA 3 (<code>3</code>)",id:"cdna-3-3",level:5},{value:"intel Xe (<code>I</code>)",id:"intel-xe-i",level:4},{value:"Xe-HPC (Ponte Vecchio) (<code>3</code>)",id:"xe-hpc-ponte-vecchio-3",level:5},{value:"Automated tests",id:"automated-tests",level:2},{value:"Errors",id:"errors",level:3},{value:"Warnings",id:"warnings",level:3},{value:"Implementation",id:"implementation",level:3},{value:"Manual tests",id:"manual-tests",level:2}];function a(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsx)(n.p,{children:"The three major versions of the standard that exist so far are very similar, and deliberately so.\nTherefore, the procedures needed to implement or test them are very similar as well. Yet, this document\nwill only cover v3, because v1 and v2 are already obsolete by the time of writing."}),"\n",(0,r.jsx)(n.h2,{id:"implementation-notes",children:"Implementation notes"}),"\n",(0,r.jsxs)(n.p,{children:["Every flavor whose name starts with ",(0,r.jsx)(n.code,{children:"SCS-"})," must conform with the naming scheme laid down in the standard."]}),"\n",(0,r.jsx)(n.h3,{id:"operational-tooling",children:"Operational tooling"}),"\n",(0,r.jsx)(n.h4,{id:"syntax-check",children:"Syntax check"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Tests/iaas/flavor-naming",children:"test suite"}),"\ncomes with a handy\n",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Tests/iaas/flavor-naming/cli.py",children:"command-line utility"}),"\nthat can be used to validate flavor names, to interactively construct a flavor name\nvia a questionnaire, and to generate prose descriptions for given flavor names.\nSee the ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Tests/iaas/flavor-naming/README.md",children:"README"}),"\nfor more details."]}),"\n",(0,r.jsxs)(n.p,{children:["The functionality of this script is also (partially) exposed via the web page\n",(0,r.jsx)(n.a,{href:"https://flavors.scs.community/",children:"https://flavors.scs.community/"}),", which can both\nparse SCS flavors names as well as generate them."]}),"\n",(0,r.jsxs)(n.p,{children:["With the OpenStack tooling (",(0,r.jsx)(n.code,{children:"python3-openstackclient"}),", ",(0,r.jsx)(n.code,{children:"OS_CLOUD"}),") in place, you can call\n",(0,r.jsx)(n.code,{children:"cli.py -v parse v3 $(openstack flavor list -f value -c Name)"})," to get a report\non the syntax compliance of the flavor names of the cloud environment."]}),"\n",(0,r.jsx)(n.h4,{id:"flavor-creation",children:"Flavor creation"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"https://github.com/osism/openstack-flavor-manager",children:"OpenStack Flavor Manager from OSISM"}),"\nwill create a whole set of flavors in one go.\nTo that end, it provides different options: either the standard mandatory and\npossibly recommended flavors can be created, or the user can set a file containing his flavors."]}),"\n",(0,r.jsx)(n.h3,{id:"gpu-table",children:"GPU table"}),"\n",(0,r.jsx)(n.p,{children:"The most commonly used datacenter GPUs are listed here, showing what GPUs (or partitions\nof a GPU) result in what GPU part of the flavor name."}),"\n",(0,r.jsxs)(n.h4,{id:"nvidia-n",children:["Nvidia (",(0,r.jsx)(n.code,{children:"N"}),")"]}),"\n",(0,r.jsx)(n.p,{children:"We show the most popular recent generations here. Older one are of course possible as well."}),"\n",(0,r.jsxs)(n.h5,{id:"ampere-a",children:["Ampere (",(0,r.jsx)(n.code,{children:"a"}),")"]}),"\n",(0,r.jsx)(n.p,{children:"One Streaming Multiprocessor on Ampere has 64 (A30, A100) or 128 Cuda Cores (A10, A40)."}),"\n",(0,r.jsx)(n.p,{children:"GPUs without MIG (one SM has 128 Cuda Cores and 4 Tensor Cores):"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Nvidia GPU"}),(0,r.jsx)(n.th,{children:"Tensor C"}),(0,r.jsx)(n.th,{children:"Cuda Cores"}),(0,r.jsx)(n.th,{children:"SMs"}),(0,r.jsx)(n.th,{children:"VRAM"}),(0,r.jsx)(n.th,{children:"SCS name piece"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"A10"}),(0,r.jsx)(n.td,{children:"288"}),(0,r.jsx)(n.td,{children:"9216"}),(0,r.jsx)(n.td,{children:"72"}),(0,r.jsx)(n.td,{children:"24G GDDR6"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNa-72-24"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"A40"}),(0,r.jsx)(n.td,{children:"336"}),(0,r.jsx)(n.td,{children:"10752"}),(0,r.jsx)(n.td,{children:"84"}),(0,r.jsx)(n.td,{children:"48G GDDR6"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNa-84-48"})})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"GPUs with Multi-Instance-GPU (MIG), where GPUs can be partitioned and the partitions handed\nout as as pass-through PCIe devices to instances. One SM corresponds to 64 Cuda Cores and\n4 Tensor Cores."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Nvidia GPU"}),(0,r.jsx)(n.th,{children:"Fraction"}),(0,r.jsx)(n.th,{children:"Tensor C"}),(0,r.jsx)(n.th,{children:"Cuda Cores"}),(0,r.jsx)(n.th,{children:"SMs"}),(0,r.jsx)(n.th,{children:"VRAM"}),(0,r.jsx)(n.th,{children:"SCS GPU name"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"A30"}),(0,r.jsx)(n.td,{children:"1/1"}),(0,r.jsx)(n.td,{children:"224"}),(0,r.jsx)(n.td,{children:"3584"}),(0,r.jsx)(n.td,{children:"56"}),(0,r.jsx)(n.td,{children:"24G HBM2"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNa-56-24"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"A30"}),(0,r.jsx)(n.td,{children:"1/2"}),(0,r.jsx)(n.td,{children:"112"}),(0,r.jsx)(n.td,{children:"1792"}),(0,r.jsx)(n.td,{children:"28"}),(0,r.jsx)(n.td,{children:"12G HBM2"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNa-28-12"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"A30"}),(0,r.jsx)(n.td,{children:"1/4"}),(0,r.jsx)(n.td,{children:"56"}),(0,r.jsx)(n.td,{children:"896"}),(0,r.jsx)(n.td,{children:"14"}),(0,r.jsx)(n.td,{children:"6G HBM2"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNa-14-6"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"A30X"}),(0,r.jsx)(n.td,{children:"1/1"}),(0,r.jsx)(n.td,{children:"224"}),(0,r.jsx)(n.td,{children:"3584"}),(0,r.jsx)(n.td,{children:"56"}),(0,r.jsx)(n.td,{children:"24G HBM2e"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNa-56h-24h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"A100"}),(0,r.jsx)(n.td,{children:"1/1"}),(0,r.jsx)(n.td,{children:"432"}),(0,r.jsx)(n.td,{children:"6912"}),(0,r.jsx)(n.td,{children:"108"}),(0,r.jsx)(n.td,{children:"80G HBM2e"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNa-108h-80h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"A100"}),(0,r.jsx)(n.td,{children:"1/2"}),(0,r.jsx)(n.td,{children:"216"}),(0,r.jsx)(n.td,{children:"3456"}),(0,r.jsx)(n.td,{children:"54"}),(0,r.jsx)(n.td,{children:"40G HBM2e"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNa-54h-40h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"A100"}),(0,r.jsx)(n.td,{children:"1/4"}),(0,r.jsx)(n.td,{children:"108"}),(0,r.jsx)(n.td,{children:"1728"}),(0,r.jsx)(n.td,{children:"27"}),(0,r.jsx)(n.td,{children:"20G HBM2e"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNa-27h-20h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"A100"}),(0,r.jsx)(n.td,{children:"1/7"}),(0,r.jsx)(n.td,{children:"60+"}),(0,r.jsx)(n.td,{children:"960+"}),(0,r.jsx)(n.td,{children:"15+"}),(0,r.jsx)(n.td,{children:"10G HBM2e"}),(0,r.jsxs)(n.td,{children:[(0,r.jsx)(n.code,{children:"GNa-15h-10h"}),"+"]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"A100X"}),(0,r.jsx)(n.td,{children:"1/1"}),(0,r.jsx)(n.td,{children:"432"}),(0,r.jsx)(n.td,{children:"6912"}),(0,r.jsx)(n.td,{children:"108"}),(0,r.jsx)(n.td,{children:"80G HBM2e"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNa-108-80h"})})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"[+] The precise numbers for the 1/7 MIG configurations are not known by the author of\nthis document and need validation."}),"\n",(0,r.jsxs)(n.h5,{id:"ada-lovelave-l",children:["Ada Lovelave (",(0,r.jsx)(n.code,{children:"l"}),")"]}),"\n",(0,r.jsx)(n.p,{children:"No MIG support, 128 Cuda Cores and 4 Tensor Cores per SM."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Nvidia GPU"}),(0,r.jsx)(n.th,{children:"Tensor C"}),(0,r.jsx)(n.th,{children:"Cuda Cores"}),(0,r.jsx)(n.th,{children:"SMs"}),(0,r.jsx)(n.th,{children:"VRAM"}),(0,r.jsx)(n.th,{children:"SCS name piece"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"L4"}),(0,r.jsx)(n.td,{children:"232"}),(0,r.jsx)(n.td,{children:"7424"}),(0,r.jsx)(n.td,{children:"58"}),(0,r.jsx)(n.td,{children:"24G GDDR6"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNl-58-24"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"L40"}),(0,r.jsx)(n.td,{children:"568"}),(0,r.jsx)(n.td,{children:"18176"}),(0,r.jsx)(n.td,{children:"142"}),(0,r.jsx)(n.td,{children:"48G GDDR6"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNl-142-48"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"L40G"}),(0,r.jsx)(n.td,{children:"568"}),(0,r.jsx)(n.td,{children:"18176"}),(0,r.jsx)(n.td,{children:"142"}),(0,r.jsx)(n.td,{children:"48G GDDR6"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNl-142h-48"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"L40S"}),(0,r.jsx)(n.td,{children:"568"}),(0,r.jsx)(n.td,{children:"18176"}),(0,r.jsx)(n.td,{children:"142"}),(0,r.jsx)(n.td,{children:"48G GDDR6"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNl-142hh-48"})})]})]})]}),"\n",(0,r.jsxs)(n.h5,{id:"grace-hopper-g",children:["Grace Hopper (",(0,r.jsx)(n.code,{children:"g"}),")"]}),"\n",(0,r.jsx)(n.p,{children:"These have MIG support and 128 Cuda Cores and 4 Tensor Cores per SM."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Nvidia GPU"}),(0,r.jsx)(n.th,{children:"Fraction"}),(0,r.jsx)(n.th,{children:"Tensor C"}),(0,r.jsx)(n.th,{children:"Cuda Cores"}),(0,r.jsx)(n.th,{children:"SMs"}),(0,r.jsx)(n.th,{children:"VRAM"}),(0,r.jsx)(n.th,{children:"SCS GPU name"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"H100"}),(0,r.jsx)(n.td,{children:"1/1"}),(0,r.jsx)(n.td,{children:"528"}),(0,r.jsx)(n.td,{children:"16896"}),(0,r.jsx)(n.td,{children:"132"}),(0,r.jsx)(n.td,{children:"80G HBM3"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNg-132-80h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"H100"}),(0,r.jsx)(n.td,{children:"1/2"}),(0,r.jsx)(n.td,{children:"264"}),(0,r.jsx)(n.td,{children:"8448"}),(0,r.jsx)(n.td,{children:"66"}),(0,r.jsx)(n.td,{children:"40G HBM3"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNg-66-40h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"H100"}),(0,r.jsx)(n.td,{children:"1/4"}),(0,r.jsx)(n.td,{children:"132"}),(0,r.jsx)(n.td,{children:"4224"}),(0,r.jsx)(n.td,{children:"33"}),(0,r.jsx)(n.td,{children:"20G HBM3"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNg-33-20h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"H100"}),(0,r.jsx)(n.td,{children:"1/7"}),(0,r.jsx)(n.td,{children:"72+"}),(0,r.jsx)(n.td,{children:"2304+"}),(0,r.jsx)(n.td,{children:"18+"}),(0,r.jsx)(n.td,{children:"10G HBM3"}),(0,r.jsxs)(n.td,{children:[(0,r.jsx)(n.code,{children:"GNg-18-10h"}),"+"]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"H200"}),(0,r.jsx)(n.td,{children:"1/1"}),(0,r.jsx)(n.td,{children:"528"}),(0,r.jsx)(n.td,{children:"16896"}),(0,r.jsx)(n.td,{children:"132"}),(0,r.jsx)(n.td,{children:"141G HBM3e"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNg-132-141h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"H200"}),(0,r.jsx)(n.td,{children:"1/2"}),(0,r.jsx)(n.td,{children:"264"}),(0,r.jsx)(n.td,{children:"16896"}),(0,r.jsx)(n.td,{children:"66"}),(0,r.jsx)(n.td,{children:"70G HBM3e"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GNg-66-70h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"..."}),(0,r.jsx)(n.td,{}),(0,r.jsx)(n.td,{}),(0,r.jsx)(n.td,{}),(0,r.jsx)(n.td,{}),(0,r.jsx)(n.td,{}),(0,r.jsx)(n.td,{})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"[+] The precise numbers for the 1/7 MIG configurations are not known by the author of\nthis document and need validation."}),"\n",(0,r.jsxs)(n.h4,{id:"amd-radeon-a",children:["AMD Radeon (",(0,r.jsx)(n.code,{children:"A"}),")"]}),"\n",(0,r.jsxs)(n.h5,{id:"cdna-2-2",children:["CDNA 2 (",(0,r.jsx)(n.code,{children:"2"}),")"]}),"\n",(0,r.jsx)(n.p,{children:"One CU contains 64 Stream Processors."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"AMD Instinct"}),(0,r.jsx)(n.th,{children:"Stream Proc"}),(0,r.jsx)(n.th,{children:"CUs"}),(0,r.jsx)(n.th,{children:"VRAM"}),(0,r.jsx)(n.th,{children:"SCS name piece"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Inst MI210"}),(0,r.jsx)(n.td,{children:"6656"}),(0,r.jsx)(n.td,{children:"104"}),(0,r.jsx)(n.td,{children:"64G HBM2e"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GA2-104-64h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Inst MI250"}),(0,r.jsx)(n.td,{children:"13312"}),(0,r.jsx)(n.td,{children:"208"}),(0,r.jsx)(n.td,{children:"128G HBM2e"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GA2-208-128h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Inst MI250X"}),(0,r.jsx)(n.td,{children:"14080"}),(0,r.jsx)(n.td,{children:"229"}),(0,r.jsx)(n.td,{children:"128G HBM2e"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GA2-220-128h"})})]})]})]}),"\n",(0,r.jsxs)(n.h5,{id:"cdna-3-3",children:["CDNA 3 (",(0,r.jsx)(n.code,{children:"3"}),")"]}),"\n",(0,r.jsx)(n.p,{children:"SRIOV partitioning is possible, resulting in pass-through for\nup to 8 partitions, somewhat similar to Nvidia MIG. 4 Tensor\nCores and 64 Stream Processors per CU."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"AMD GPU"}),(0,r.jsx)(n.th,{children:"Tensor C"}),(0,r.jsx)(n.th,{children:"Stream Proc"}),(0,r.jsx)(n.th,{children:"CUs"}),(0,r.jsx)(n.th,{children:"VRAM"}),(0,r.jsx)(n.th,{children:"SCS name piece"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Inst MI300X"}),(0,r.jsx)(n.td,{children:"1216"}),(0,r.jsx)(n.td,{children:"19456"}),(0,r.jsx)(n.td,{children:"304"}),(0,r.jsx)(n.td,{children:"192G HBM3"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GA3-304-192h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Inst MI325X"}),(0,r.jsx)(n.td,{children:"1216"}),(0,r.jsx)(n.td,{children:"19456"}),(0,r.jsx)(n.td,{children:"304"}),(0,r.jsx)(n.td,{children:"288G HBM3"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GA3-304-288h"})})]})]})]}),"\n",(0,r.jsxs)(n.h4,{id:"intel-xe-i",children:["intel Xe (",(0,r.jsx)(n.code,{children:"I"}),")"]}),"\n",(0,r.jsxs)(n.h5,{id:"xe-hpc-ponte-vecchio-3",children:["Xe-HPC (Ponte Vecchio) (",(0,r.jsx)(n.code,{children:"3"}),")"]}),"\n",(0,r.jsx)(n.p,{children:"1 EU corresponds to one Tensor Core and contains 128 Shading Units."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"intel DC GPU"}),(0,r.jsx)(n.th,{children:"Tensor C"}),(0,r.jsx)(n.th,{children:"Shading U"}),(0,r.jsx)(n.th,{children:"EUs"}),(0,r.jsx)(n.th,{children:"VRAM"}),(0,r.jsx)(n.th,{children:"SCS name part"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Max 1100"}),(0,r.jsx)(n.td,{children:"56"}),(0,r.jsx)(n.td,{children:"7168"}),(0,r.jsx)(n.td,{children:"56"}),(0,r.jsx)(n.td,{children:"48G HBM2e"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GI3-56-48h"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Max 1550"}),(0,r.jsx)(n.td,{children:"128"}),(0,r.jsx)(n.td,{children:"16384"}),(0,r.jsx)(n.td,{children:"128"}),(0,r.jsx)(n.td,{children:"128G HBM2e"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"GI3-128-128h"})})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"automated-tests",children:"Automated tests"}),"\n",(0,r.jsx)(n.h3,{id:"errors",children:"Errors"}),"\n",(0,r.jsx)(n.p,{children:"The following items MUST be detected and reported as an error:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["any syntax error in a name starting with ",(0,r.jsx)(n.code,{children:"SCS-"}),","]}),"\n",(0,r.jsx)(n.li,{children:"any mismatch between any immediately discoverable property of a flavor (currently, CPU, RAM and disk size)\nand the meaning of its name (which is usually a lower bound), such as the CPU generation or hypervisor."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"In addition, the following items MAY be reported as an error:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"any mismatch between any non-immediately discoverable property of flavor and the meaning of its name."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"warnings",children:"Warnings"}),"\n",(0,r.jsx)(n.p,{children:"None so far."}),"\n",(0,r.jsx)(n.h3,{id:"implementation",children:"Implementation"}),"\n",(0,r.jsxs)(n.p,{children:["The script ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Tests/iaas/flavor-naming/flavor-names-openstack.py",children:(0,r.jsx)(n.code,{children:"flavor-names-openstack.py"})}),"\ntalks to the OpenStack API of the cloud specified by the ",(0,r.jsx)(n.code,{children:"OS_CLOUD"})," environment and queries properties and\nchecks the names for standards compliance."]}),"\n",(0,r.jsx)(n.h2,{id:"manual-tests",children:"Manual tests"}),"\n",(0,r.jsx)(n.p,{children:"To be determined."})]})}function o(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},28453:(e,n,d)=>{d.d(n,{R:()=>i,x:()=>l});var s=d(96540);const r={},t=s.createContext(r);function i(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/64529.568dd26f.js b/assets/js/64529.568dd26f.js new file mode 100644 index 0000000000..6b6327b35b --- /dev/null +++ b/assets/js/64529.568dd26f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[64529],{64529:(t,n,e)=>{e.d(n,{diagram:()=>H});var i=e(86079),s=e(26312);function r(t,n){let e;if(void 0===n)for(const i of t)null!=i&&(e>i||void 0===e&&i>=i)&&(e=i);else{let i=-1;for(let s of t)null!=(s=n(s,++i,t))&&(e>s||void 0===e&&s>=s)&&(e=s)}return e}function o(t){return t.target.depth}function c(t,n){return t.sourceLinks.length?t.depth:n-1}function l(t,n){let e=0;if(void 0===n)for(let i of t)(i=+i)&&(e+=i);else{let i=-1;for(let s of t)(s=+n(s,++i,t))&&(e+=s)}return e}function h(t,n){let e;if(void 0===n)for(const i of t)null!=i&&(e<i||void 0===e&&i>=i)&&(e=i);else{let i=-1;for(let s of t)null!=(s=n(s,++i,t))&&(e<s||void 0===e&&s>=s)&&(e=s)}return e}function a(t){return function(){return t}}function u(t,n){return y(t.source,n.source)||t.index-n.index}function f(t,n){return y(t.target,n.target)||t.index-n.index}function y(t,n){return t.y0-n.y0}function d(t){return t.value}function p(t){return t.index}function g(t){return t.nodes}function _(t){return t.links}function x(t,n){const e=t.get(n);if(!e)throw new Error("missing: "+n);return e}function k({nodes:t}){for(const n of t){let t=n.y0,e=t;for(const i of n.sourceLinks)i.y0=t+i.width/2,t+=i.width;for(const i of n.targetLinks)i.y1=e+i.width/2,e+=i.width}}function m(){let t,n,e,i=0,s=0,o=1,m=1,v=24,b=8,w=p,L=c,E=g,A=_,S=6;function M(){const c={nodes:E.apply(null,arguments),links:A.apply(null,arguments)};return function({nodes:t,links:n}){for(const[e,s]of t.entries())s.index=e,s.sourceLinks=[],s.targetLinks=[];const i=new Map(t.map(((n,e)=>[w(n,e,t),n])));for(const[e,s]of n.entries()){s.index=e;let{source:t,target:n}=s;"object"!=typeof t&&(t=s.source=x(i,t)),"object"!=typeof n&&(n=s.target=x(i,n)),t.sourceLinks.push(s),n.targetLinks.push(s)}if(null!=e)for(const{sourceLinks:s,targetLinks:r}of t)s.sort(e),r.sort(e)}(c),function({nodes:t}){for(const n of t)n.value=void 0===n.fixedValue?Math.max(l(n.sourceLinks,d),l(n.targetLinks,d)):n.fixedValue}(c),function({nodes:t}){const n=t.length;let e=new Set(t),i=new Set,s=0;for(;e.size;){for(const t of e){t.depth=s;for(const{target:n}of t.sourceLinks)i.add(n)}if(++s>n)throw new Error("circular link");e=i,i=new Set}}(c),function({nodes:t}){const n=t.length;let e=new Set(t),i=new Set,s=0;for(;e.size;){for(const t of e){t.height=s;for(const{source:n}of t.targetLinks)i.add(n)}if(++s>n)throw new Error("circular link");e=i,i=new Set}}(c),function(e){const c=function({nodes:t}){const e=h(t,(t=>t.depth))+1,s=(o-i-v)/(e-1),r=new Array(e);for(const n of t){const t=Math.max(0,Math.min(e-1,Math.floor(L.call(null,n,e))));n.layer=t,n.x0=i+t*s,n.x1=n.x0+v,r[t]?r[t].push(n):r[t]=[n]}if(n)for(const i of r)i.sort(n);return r}(e);t=Math.min(b,(m-s)/(h(c,(t=>t.length))-1)),function(n){const e=r(n,(n=>(m-s-(n.length-1)*t)/l(n,d)));for(const i of n){let n=s;for(const s of i){s.y0=n,s.y1=n+s.value*e,n=s.y1+t;for(const t of s.sourceLinks)t.width=t.value*e}n=(m-n+t)/(i.length+1);for(let t=0;t<i.length;++t){const e=i[t];e.y0+=n*(t+1),e.y1+=n*(t+1)}N(i)}}(c);for(let t=0;t<S;++t){const n=Math.pow(.99,t),e=Math.max(1-n,(t+1)/S);T(c,n,e),I(c,n,e)}}(c),k(c),c}function I(t,e,i){for(let s=1,r=t.length;s<r;++s){const r=t[s];for(const t of r){let n=0,i=0;for(const{source:e,value:r}of t.targetLinks){let s=r*(t.layer-e.layer);n+=$(e,t)*s,i+=s}if(!(i>0))continue;let s=(n/i-t.y0)*e;t.y0+=s,t.y1+=s,P(t)}void 0===n&&r.sort(y),O(r,i)}}function T(t,e,i){for(let s=t.length-2;s>=0;--s){const r=t[s];for(const t of r){let n=0,i=0;for(const{target:e,value:r}of t.sourceLinks){let s=r*(e.layer-t.layer);n+=j(t,e)*s,i+=s}if(!(i>0))continue;let s=(n/i-t.y0)*e;t.y0+=s,t.y1+=s,P(t)}void 0===n&&r.sort(y),O(r,i)}}function O(n,e){const i=n.length>>1,r=n[i];D(n,r.y0-t,i-1,e),C(n,r.y1+t,i+1,e),D(n,m,n.length-1,e),C(n,s,0,e)}function C(n,e,i,s){for(;i<n.length;++i){const r=n[i],o=(e-r.y0)*s;o>1e-6&&(r.y0+=o,r.y1+=o),e=r.y1+t}}function D(n,e,i,s){for(;i>=0;--i){const r=n[i],o=(r.y1-e)*s;o>1e-6&&(r.y0-=o,r.y1-=o),e=r.y0-t}}function P({sourceLinks:t,targetLinks:n}){if(void 0===e){for(const{source:{sourceLinks:t}}of n)t.sort(f);for(const{target:{targetLinks:n}}of t)n.sort(u)}}function N(t){if(void 0===e)for(const{sourceLinks:n,targetLinks:e}of t)n.sort(f),e.sort(u)}function $(n,e){let i=n.y0-(n.sourceLinks.length-1)*t/2;for(const{target:s,width:r}of n.sourceLinks){if(s===e)break;i+=r+t}for(const{source:t,width:s}of e.targetLinks){if(t===n)break;i-=s}return i}function j(n,e){let i=e.y0-(e.targetLinks.length-1)*t/2;for(const{source:s,width:r}of e.targetLinks){if(s===n)break;i+=r+t}for(const{target:t,width:s}of n.sourceLinks){if(t===e)break;i-=s}return i}return M.update=function(t){return k(t),t},M.nodeId=function(t){return arguments.length?(w="function"==typeof t?t:a(t),M):w},M.nodeAlign=function(t){return arguments.length?(L="function"==typeof t?t:a(t),M):L},M.nodeSort=function(t){return arguments.length?(n=t,M):n},M.nodeWidth=function(t){return arguments.length?(v=+t,M):v},M.nodePadding=function(n){return arguments.length?(b=t=+n,M):b},M.nodes=function(t){return arguments.length?(E="function"==typeof t?t:a(t),M):E},M.links=function(t){return arguments.length?(A="function"==typeof t?t:a(t),M):A},M.linkSort=function(t){return arguments.length?(e=t,M):e},M.size=function(t){return arguments.length?(i=s=0,o=+t[0],m=+t[1],M):[o-i,m-s]},M.extent=function(t){return arguments.length?(i=+t[0][0],o=+t[1][0],s=+t[0][1],m=+t[1][1],M):[[i,s],[o,m]]},M.iterations=function(t){return arguments.length?(S=+t,M):S},M}var v=Math.PI,b=2*v,w=1e-6,L=b-w;function E(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function A(){return new E}E.prototype=A.prototype={constructor:E,moveTo:function(t,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,n){this._+="L"+(this._x1=+t)+","+(this._y1=+n)},quadraticCurveTo:function(t,n,e,i){this._+="Q"+ +t+","+ +n+","+(this._x1=+e)+","+(this._y1=+i)},bezierCurveTo:function(t,n,e,i,s,r){this._+="C"+ +t+","+ +n+","+ +e+","+ +i+","+(this._x1=+s)+","+(this._y1=+r)},arcTo:function(t,n,e,i,s){t=+t,n=+n,e=+e,i=+i,s=+s;var r=this._x1,o=this._y1,c=e-t,l=i-n,h=r-t,a=o-n,u=h*h+a*a;if(s<0)throw new Error("negative radius: "+s);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=n);else if(u>w)if(Math.abs(a*c-l*h)>w&&s){var f=e-r,y=i-o,d=c*c+l*l,p=f*f+y*y,g=Math.sqrt(d),_=Math.sqrt(u),x=s*Math.tan((v-Math.acos((d+u-p)/(2*g*_)))/2),k=x/_,m=x/g;Math.abs(k-1)>w&&(this._+="L"+(t+k*h)+","+(n+k*a)),this._+="A"+s+","+s+",0,0,"+ +(a*f>h*y)+","+(this._x1=t+m*c)+","+(this._y1=n+m*l)}else this._+="L"+(this._x1=t)+","+(this._y1=n);else;},arc:function(t,n,e,i,s,r){t=+t,n=+n,r=!!r;var o=(e=+e)*Math.cos(i),c=e*Math.sin(i),l=t+o,h=n+c,a=1^r,u=r?i-s:s-i;if(e<0)throw new Error("negative radius: "+e);null===this._x1?this._+="M"+l+","+h:(Math.abs(this._x1-l)>w||Math.abs(this._y1-h)>w)&&(this._+="L"+l+","+h),e&&(u<0&&(u=u%b+b),u>L?this._+="A"+e+","+e+",0,1,"+a+","+(t-o)+","+(n-c)+"A"+e+","+e+",0,1,"+a+","+(this._x1=l)+","+(this._y1=h):u>w&&(this._+="A"+e+","+e+",0,"+ +(u>=v)+","+a+","+(this._x1=t+e*Math.cos(s))+","+(this._y1=n+e*Math.sin(s))))},rect:function(t,n,e,i){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)+"h"+ +e+"v"+ +i+"h"+-e+"Z"},toString:function(){return this._}};const S=A;var M=Array.prototype.slice;function I(t){return function(){return t}}function T(t){return t[0]}function O(t){return t[1]}function C(t){return t.source}function D(t){return t.target}function P(t){var n=C,e=D,i=T,s=O,r=null;function o(){var o,c=M.call(arguments),l=n.apply(this,c),h=e.apply(this,c);if(r||(r=o=S()),t(r,+i.apply(this,(c[0]=l,c)),+s.apply(this,c),+i.apply(this,(c[0]=h,c)),+s.apply(this,c)),o)return r=null,o+""||null}return o.source=function(t){return arguments.length?(n=t,o):n},o.target=function(t){return arguments.length?(e=t,o):e},o.x=function(t){return arguments.length?(i="function"==typeof t?t:I(+t),o):i},o.y=function(t){return arguments.length?(s="function"==typeof t?t:I(+t),o):s},o.context=function(t){return arguments.length?(r=null==t?null:t,o):r},o}function N(t,n,e,i,s){t.moveTo(n,e),t.bezierCurveTo(n=(n+i)/2,e,n,s,i,s)}function $(t){return[t.source.x1,t.y0]}function j(t){return[t.target.x0,t.y1]}function z(){return P(N).source($).target(j)}e(74353),e(16750),e(42838);var U=function(){var t=function(t,n,e,i){for(e=e||{},i=t.length;i--;e[t[i]]=n);return e},n=[1,9],e=[1,10],i=[1,5,10,12],s={trace:function(){},yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:function(t,n,e,i,s,r,o){var c=r.length-1;switch(s){case 7:const t=i.findOrCreateNode(r[c-4].trim().replaceAll('""','"')),n=i.findOrCreateNode(r[c-2].trim().replaceAll('""','"')),e=parseFloat(r[c].trim());i.addLink(t,n,e);break;case 8:case 9:case 11:this.$=r[c];break;case 10:this.$=r[c-1]}},table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:n,20:e},{1:[2,6],7:11,10:[1,12]},t(e,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(i,[2,8]),t(i,[2,9]),{19:[1,16]},t(i,[2,11]),{1:[2,1]},{1:[2,5]},t(e,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:n,20:e},{15:18,16:7,17:8,18:n,20:e},{18:[1,19]},t(e,[2,3]),{12:[1,20]},t(i,[2,10]),{15:21,16:7,17:8,18:n,20:e},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:function(t,n){if(!n.recoverable){var e=new Error(t);throw e.hash=n,e}this.trace(t)},parse:function(t){var n=this,e=[0],i=[],s=[null],r=[],o=this.table,c="",l=0,h=0,a=r.slice.call(arguments,1),u=Object.create(this.lexer),f={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(f.yy[y]=this.yy[y]);u.setInput(t,f.yy),f.yy.lexer=u,f.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var d=u.yylloc;r.push(d);var p=u.options&&u.options.ranges;"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var g,_,x,k,m,v,b,w,L,E={};;){if(_=e[e.length-1],this.defaultActions[_]?x=this.defaultActions[_]:(null==g&&(L=void 0,"number"!=typeof(L=i.pop()||u.lex()||1)&&(L instanceof Array&&(L=(i=L).pop()),L=n.symbols_[L]||L),g=L),x=o[_]&&o[_][g]),void 0===x||!x.length||!x[0]){var A="";for(m in w=[],o[_])this.terminals_[m]&&m>2&&w.push("'"+this.terminals_[m]+"'");A=u.showPosition?"Parse error on line "+(l+1)+":\n"+u.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[g]||g)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==g?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(A,{text:u.match,token:this.terminals_[g]||g,line:u.yylineno,loc:d,expected:w})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+g);switch(x[0]){case 1:e.push(g),s.push(u.yytext),r.push(u.yylloc),e.push(x[1]),g=null,h=u.yyleng,c=u.yytext,l=u.yylineno,d=u.yylloc;break;case 2:if(v=this.productions_[x[1]][1],E.$=s[s.length-v],E._$={first_line:r[r.length-(v||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(v||1)].first_column,last_column:r[r.length-1].last_column},p&&(E._$.range=[r[r.length-(v||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply(E,[c,h,l,f.yy,x[1],s,r].concat(a))))return k;v&&(e=e.slice(0,-1*v*2),s=s.slice(0,-1*v),r=r.slice(0,-1*v)),e.push(this.productions_[x[1]][0]),s.push(E.$),r.push(E._$),b=o[e[e.length-2]][e[e.length-1]],e.push(b);break;case 3:return!0}}return!0}},r={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===i.length?this.yylloc.first_column:0)+i[i.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"},test_match:function(t,n){var e,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,n,e,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((e=this._input.match(this.rules[s[r]]))&&(!n||e[0].length>n[0].length)){if(n=e,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,s[r])))return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?!1!==(t=this.test_match(n,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,n,e,i){switch(e){case 0:return this.pushState("csv"),4;case 1:return 10;case 2:return 5;case 3:return 12;case 4:return this.pushState("escaped_text"),18;case 5:return 20;case 6:return this.popState("escaped_text"),18;case 7:return 19}},rules:[/^(?:sankey-beta\b)/i,/^(?:$)/i,/^(?:((\u000D\u000A)|(\u000A)))/i,/^(?:(\u002C))/i,/^(?:(\u0022))/i,/^(?:([\u0020-\u0021\u0023-\u002B\u002D-\u007E])*)/i,/^(?:(\u0022)(?!(\u0022)))/i,/^(?:(([\u0020-\u0021\u0023-\u002B\u002D-\u007E])|(\u002C)|(\u000D)|(\u000A)|(\u0022)(\u0022))*)/i],conditions:{csv:{rules:[1,2,3,4,5,6,7],inclusive:!1},escaped_text:{rules:[6,7],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7],inclusive:!0}}};function o(){this.yy={}}return s.lexer=r,o.prototype=s,s.Parser=o,new o}();U.parser=U;const F=U;let W=[],q=[],G={};class V{constructor(t,n,e=0){this.source=t,this.target=n,this.value=e}}class X{constructor(t){this.ID=t}}const K={nodesMap:G,getConfig:()=>(0,i.c)().sankey,getNodes:()=>q,getLinks:()=>W,getGraph:()=>({nodes:q.map((t=>({id:t.ID}))),links:W.map((t=>({source:t.source.ID,target:t.target.ID,value:t.value})))}),addLink:(t,n,e)=>{W.push(new V(t,n,e))},findOrCreateNode:t=>(t=i.e.sanitizeText(t,(0,i.c)()),G[t]||(G[t]=new X(t),q.push(G[t])),G[t]),getAccTitle:i.g,setAccTitle:i.s,getAccDescription:i.a,setAccDescription:i.b,getDiagramTitle:i.t,setDiagramTitle:i.q,clear:()=>{W=[],q=[],G={},(0,i.v)()}},Q=class t{static next(n){return new t(n+ ++t.count)}constructor(t){this.id=t,this.href=`#${t}`}toString(){return"url("+this.href+")"}};Q.count=0;let Y=Q;const B={left:function(t){return t.depth},right:function(t,n){return n-1-t.height},center:function(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?r(t.sourceLinks,o)-1:0},justify:c},R={draw:function(t,n,e,r){const{securityLevel:o,sankey:c}=(0,i.c)(),l=i.K.sankey;let h;"sandbox"===o&&(h=(0,s.Ltv)("#i"+n));const a="sandbox"===o?(0,s.Ltv)(h.nodes()[0].contentDocument.body):(0,s.Ltv)("body"),u="sandbox"===o?a.select(`[id="${n}"]`):(0,s.Ltv)(`[id="${n}"]`),f=(null==c?void 0:c.width)??l.width,y=(null==c?void 0:c.height)??l.width,d=(null==c?void 0:c.useMaxWidth)??l.useMaxWidth,p=(null==c?void 0:c.nodeAlignment)??l.nodeAlignment,g=(null==c?void 0:c.prefix)??l.prefix,_=(null==c?void 0:c.suffix)??l.suffix,x=(null==c?void 0:c.showValues)??l.showValues,k=r.db.getGraph(),v=B[p];m().nodeId((t=>t.id)).nodeWidth(10).nodePadding(10+(x?15:0)).nodeAlign(v).extent([[0,0],[f,y]])(k);const b=(0,s.UMr)(s.zt);u.append("g").attr("class","nodes").selectAll(".node").data(k.nodes).join("g").attr("class","node").attr("id",(t=>(t.uid=Y.next("node-")).id)).attr("transform",(function(t){return"translate("+t.x0+","+t.y0+")"})).attr("x",(t=>t.x0)).attr("y",(t=>t.y0)).append("rect").attr("height",(t=>t.y1-t.y0)).attr("width",(t=>t.x1-t.x0)).attr("fill",(t=>b(t.id)));u.append("g").attr("class","node-labels").attr("font-family","sans-serif").attr("font-size",14).selectAll("text").data(k.nodes).join("text").attr("x",(t=>t.x0<f/2?t.x1+6:t.x0-6)).attr("y",(t=>(t.y1+t.y0)/2)).attr("dy",(x?"0":"0.35")+"em").attr("text-anchor",(t=>t.x0<f/2?"start":"end")).text((({id:t,value:n})=>x?`${t}\n${g}${Math.round(100*n)/100}${_}`:t));const w=u.append("g").attr("class","links").attr("fill","none").attr("stroke-opacity",.5).selectAll(".link").data(k.links).join("g").attr("class","link").style("mix-blend-mode","multiply"),L=(null==c?void 0:c.linkColor)||"gradient";if("gradient"===L){const t=w.append("linearGradient").attr("id",(t=>(t.uid=Y.next("linearGradient-")).id)).attr("gradientUnits","userSpaceOnUse").attr("x1",(t=>t.source.x1)).attr("x2",(t=>t.target.x0));t.append("stop").attr("offset","0%").attr("stop-color",(t=>b(t.source.id))),t.append("stop").attr("offset","100%").attr("stop-color",(t=>b(t.target.id)))}let E;switch(L){case"gradient":E=t=>t.uid;break;case"source":E=t=>b(t.source.id);break;case"target":E=t=>b(t.target.id);break;default:E=L}w.append("path").attr("d",z()).attr("stroke",E).attr("stroke-width",(t=>Math.max(1,t.width))),(0,i.o)(void 0,u,0,d)}},Z=F.parse.bind(F);F.parse=t=>Z((t=>t.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g,"").replaceAll(/([\n\r])+/g,"\n").trim())(t));const H={parser:F,db:K,renderer:R}}}]); \ No newline at end of file diff --git a/assets/js/64f9507b.2e07f353.js b/assets/js/64f9507b.2e07f353.js new file mode 100644 index 0000000000..27b30536c2 --- /dev/null +++ b/assets/js/64f9507b.2e07f353.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[55790],{62676:(s,e,t)=>{t.r(e),t.d(e,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"iaas/scs-0110","title":"scs-0110: SSD Flavors","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0110.md","sourceDirName":"iaas","slug":"/iaas/scs-0110","permalink":"/standards/iaas/scs-0110","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0104-w1-standard-images-implementation"},"next":{"title":"V1","permalink":"/standards/scs-0110-v1-ssd-flavors"}}');var r=t(74848),a=t(28453);const d={},c="scs-0110: SSD Flavors",i={},o=[];function l(s){const e={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...s.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"scs-0110-ssd-flavors",children:"scs-0110: SSD Flavors"})}),"\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Version"}),(0,r.jsx)(e.th,{children:"Type"}),(0,r.jsx)(e.th,{children:"State"}),(0,r.jsx)(e.th,{children:"stabilized"}),(0,r.jsx)(e.th,{children:"deprecated"})]})}),(0,r.jsx)(e.tbody,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0110-v1-ssd-flavors",children:"scs-0110-v1"})}),(0,r.jsx)(e.td,{children:"Decision Record"}),(0,r.jsx)(e.td,{children:"Stable"}),(0,r.jsx)(e.td,{children:"2023-06-14"}),(0,r.jsx)(e.td,{children:"-"})]})})]})]})}function h(s={}){const{wrapper:e}={...(0,a.R)(),...s.components};return e?(0,r.jsx)(e,{...s,children:(0,r.jsx)(l,{...s})}):l(s)}},28453:(s,e,t)=>{t.d(e,{R:()=>d,x:()=>c});var n=t(96540);const r={},a=n.createContext(r);function d(s){const e=n.useContext(a);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function c(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(r):s.components||r:d(s.components),n.createElement(a.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/65742e9f.f8247f2b.js b/assets/js/65742e9f.f8247f2b.js new file mode 100644 index 0000000000..ebc95d948e --- /dev/null +++ b/assets/js/65742e9f.f8247f2b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[45147],{99963:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"iam/SCS-example-setup-configuration-description","title":"Example setup configuration in SCS deployment explained","description":"The following document explains the idea behind the example configuration is done.","source":"@site/docs/05-iam/SCS-example-setup-configuration-description.md","sourceDirName":"05-iam","slug":"/iam/SCS-example-setup-configuration-description","permalink":"/docs/iam/SCS-example-setup-configuration-description","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/05-iam/SCS-example-setup-configuration-description.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Domain Manager setup and usage","permalink":"/docs/iam/domain-manager-setup-and-usage"},"next":{"title":"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)","permalink":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations"}}');var i=t(74848),r=t(28453);const s={},a="Example setup configuration in SCS deployment explained",c={},l=[];function d(e){const n={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"example-setup-configuration-in-scs-deployment-explained",children:"Example setup configuration in SCS deployment explained"})}),"\n",(0,i.jsxs)(n.p,{children:["The following document explains the idea behind the example configuration is done.\nThe playbook creates a proxy realm used to connect with ",(0,i.jsx)(n.code,{children:"Keystone"}),", a customer realm, the clients needed to connect the realms, the identity brokering for the customer realm, a login flow\nto be able to use the ",(0,i.jsx)(n.code,{children:"home-IdP-discovery"})," plugin to redirect to the correct customer realm and an example user.\nSCS operators can find the playbook that creates the setup ",(0,i.jsx)(n.a,{href:"https://github.com/osism/ansible-playbooks/blob/main/playbooks/infrastructure/keycloak-oidc-client-config.yml",children:"here"}),"."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["In the first place a proxy realm called ",(0,i.jsx)(n.code,{children:"osism"})," on the example deployment. That realm will\nbecome the realm that will be conected to ",(0,i.jsx)(n.code,{children:"Keystone"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["A customer realm called ",(0,i.jsx)(n.code,{children:"CustomerA"})," is created. On that realm a ",(0,i.jsx)(n.code,{children:"OIDC"})," client is created to hook\nup the realm to the proxy realm. This is done via ",(0,i.jsx)(n.code,{children:"Identity Brokering"})," in the proxy realm."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["An ",(0,i.jsx)(n.code,{children:"Identity provider"})," is configured in the ",(0,i.jsx)(n.code,{children:"osism"})," realm, this is configured to be connected to\nthe ",(0,i.jsx)(n.code,{children:"CustomerA"})," realm. For that, a set of mappers are created, the default ones are a ",(0,i.jsx)(n.code,{children:"hardcoded-attribute"}),"\nthat sets the domain where the user came from, and an ",(0,i.jsx)(n.code,{children:"attribute-importer"})," mapper for the ",(0,i.jsx)(n.code,{children:"openstack-default-project"})," that comes\nin the ",(0,i.jsx)(n.code,{children:"OIDC"})," claim from the customer realm."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["A new login flow has been created in the ",(0,i.jsx)(n.code,{children:"osism"})," realm, this login flow is needed to use the ",(0,i.jsx)(n.code,{children:"home-IdP-discovery"})," plugin."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Creation of an example user called ",(0,i.jsx)(n.code,{children:"Alice"}),"."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>a});var o=t(96540);const i={},r=o.createContext(i);function s(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/657efcba.b2a58c44.js b/assets/js/657efcba.b2a58c44.js new file mode 100644 index 0000000000..96afcb8a58 --- /dev/null +++ b/assets/js/657efcba.b2a58c44.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[61238],{5678:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>u,frontMatter:()=>c,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"container/components/container-registry/docs/quickstart","title":"Quickstart","description":"This guide shows you how to set up a working Harbor Container Registry that utilizes a Kubernetes cluster.","source":"@site/docs/03-container/components/container-registry/docs/quickstart.md","sourceDirName":"03-container/components/container-registry/docs","slug":"/container/components/container-registry/docs/quickstart","permalink":"/docs/container/components/container-registry/docs/quickstart","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/quickstart.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Container Registry","permalink":"/docs/category/container-registry"},"next":{"title":"SCS deployment","permalink":"/docs/container/components/container-registry/docs/scs-deployment"}}');var t=s(74848),i=s(28453);const c={},o="Quickstart",a={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install Harbor container registry",id:"install-harbor-container-registry",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,t.jsx)(n.p,{children:"This guide shows you how to set up a working Harbor Container Registry that utilizes a Kubernetes cluster."}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Kubernetes cluster v1.20+","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Use existing cluster","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"export KUBECONFIG=/path/to/kubeconfig\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Alternatively, spawn some dev cluster, e.g. using ",(0,t.jsx)(n.a,{href:"https://kind.sigs.k8s.io/docs/user/quick-start/",children:"KinD"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kind create cluster\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Flux CLI","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Installation documentation: ",(0,t.jsx)(n.a,{href:"https://fluxcd.io/flux/installation/#install-the-flux-cli",children:"https://fluxcd.io/flux/installation/#install-the-flux-cli"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s https://fluxcd.io/install.sh | sudo FLUX_VERSION=2.2.3 bash\nflux install\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"install-harbor-container-registry",children:"Install Harbor container registry"}),"\n",(0,t.jsxs)(n.p,{children:["Apply kustomization manifest in ",(0,t.jsx)(n.code,{children:"envs/dev"})," directory:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl apply -k envs/dev/\n"})}),"\n",(0,t.jsx)(n.p,{children:"Port-forward the Harbor container registry service:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl port-forward svc/harbor 8080:80\n"})}),"\n",(0,t.jsx)(n.p,{children:"Access the Harbor container registry UI and use Harbor's default credentials"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["username: ",(0,t.jsx)(n.code,{children:"admin"})]}),"\n",(0,t.jsxs)(n.li,{children:["password: ",(0,t.jsx)(n.code,{children:"Harbor12345"})]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"http://localhost:8080\n"})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>o});var r=s(96540);const t={},i=r.createContext(t);function c(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/65c1efe1.0d3c3932.js b/assets/js/65c1efe1.0d3c3932.js new file mode 100644 index 0000000000..9ee1cf8ea3 --- /dev/null +++ b/assets/js/65c1efe1.0d3c3932.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[55663],{92489:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>o});const r=JSON.parse('{"id":"kaas/scs-0212","title":"scs-0212: Requirements for container registries","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/kaas/scs-0212.md","sourceDirName":"kaas","slug":"/kaas/scs-0212","permalink":"/standards/kaas/scs-0212","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing"},"next":{"title":"V1","permalink":"/standards/scs-0212-v1-requirements-for-container-registries"}}');var n=s(74848),a=s(28453);const i={},c="scs-0212: Requirements for container registries",d={},o=[];function l(e){const t={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"scs-0212-requirements-for-container-registries",children:"scs-0212: Requirements for container registries"})}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0212-v1-requirements-for-container-registries",children:"scs-0212-v1"})}),(0,n.jsx)(t.td,{children:"Standard"}),(0,n.jsx)(t.td,{children:"Draft"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>c});var r=s(96540);const n={},a=r.createContext(n);function i(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/670b12e1.e4675d98.js b/assets/js/670b12e1.e4675d98.js new file mode 100644 index 0000000000..7b4a64f13a --- /dev/null +++ b/assets/js/670b12e1.e4675d98.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[63919],{51881:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>d,default:()=>h,frontMatter:()=>l,metadata:()=>o,toc:()=>a});const o=JSON.parse('{"id":"iaas/guides/operations-guide/manager/console","title":"Console","description":"A console command is available in the OSISM CLI. This allows specific parts of the","source":"@site/docs/02-iaas/guides/operations-guide/manager/console.md","sourceDirName":"02-iaas/guides/operations-guide/manager","slug":"/iaas/guides/operations-guide/manager/console","permalink":"/docs/iaas/guides/operations-guide/manager/console","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/manager/console.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Console"},"sidebar":"docs","previous":{"title":"Apply","permalink":"/docs/iaas/guides/operations-guide/manager/apply"},"next":{"title":"Get","permalink":"/docs/iaas/guides/operations-guide/manager/get"}}');var t=s(74848),i=s(28453);const l={sidebar_label:"Console"},d="Console",r={},a=[{value:"Ansible",id:"ansible",level:2},{value:"Clush",id:"clush",level:2},{value:"Container",id:"container",level:2},{value:"SSH",id:"ssh",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"console",children:"Console"})}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.code,{children:"console"})," command is available in the OSISM CLI. This allows specific parts of the\nenvironment to be operated interactively."]}),"\n",(0,t.jsx)(n.h2,{id:"ansible",children:"Ansible"}),"\n",(0,t.jsxs)(n.p,{children:["Used tool: ",(0,t.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/cli/ansible-console.html",children:"ansible-console"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ osism console --type ansible testbed-node-0\nWelcome to the ansible console. Type help or ? to list commands.\n\ndragon@testbed-node-0 (1)[f:5]$ !uptime\ntestbed-node-0 | CHANGED | rc=0 >>\n 18:14:15 up 80 days, 33 min, 0 users, load average: 4.00, 3.07, 2.67\ndragon@testbed-node-0 (1)[f:5]$\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Shortcut: ",(0,t.jsx)(n.code,{children:"osism console .testbed-node-0"})]}),"\n",(0,t.jsx)(n.h2,{id:"clush",children:"Clush"}),"\n",(0,t.jsxs)(n.p,{children:["Used tool: ",(0,t.jsx)(n.a,{href:"https://clustershell.readthedocs.io",children:"ClusterShell"})]}),"\n",(0,t.jsx)(n.p,{children:"The same groups as defined in the Ansible Inventory can be used."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ osism console --type clush control\nEnter 'quit' to leave this interactive mode\nWorking with nodes: testbed-node-[0-2]\nclush>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Shortcut: ",(0,t.jsx)(n.code,{children:"osism console :control"})]}),"\n",(0,t.jsx)(n.h2,{id:"container",children:"Container"}),"\n",(0,t.jsxs)(n.p,{children:["Used tool: ",(0,t.jsx)(n.a,{href:"https://python-prompt-toolkit.readthedocs.io/en/master/index.html",children:"Python Prompt Toolkit"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ osism console --type container testbed-node-0/fluentd\n(fluentd)[td-agent@testbed-node-0 /]$ ps ax\n PID TTY STAT TIME COMMAND\n 1 ? Ss 0:00 dumb-init --single-child -- kolla_start\n 7 ? Sl 24:28 /opt/td-agent/bin/ruby /usr/sbin/td-agent -o /var/log/kolla/fluentd/fluent\n 25 ? Sl 3519:55 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /usr/sbin/td-agent -o /var\n 238 pts/0 Ss 0:00 bash\n 247 pts/0 R+ 0:00 ps ax\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Shortcut: ",(0,t.jsx)(n.code,{children:"osism console testbed-node-0/fluentd"})]}),"\n",(0,t.jsx)(n.h2,{id:"ssh",children:"SSH"}),"\n",(0,t.jsxs)(n.p,{children:["Used tool: ",(0,t.jsx)(n.a,{href:"https://www.openssh.com",children:"OpenSSH"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ osism console --type ssh testbed-node-0\nYou have new mail.\nLast login: Wed Sep 27 18:15:39 2023 from 192.168.16.5\ndragon@testbed-node-0:~$ uptime\n 18:16:25 up 80 days, 35 min, 1 user, load average: 2.85, 3.04, 2.71\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Shortcut: ",(0,t.jsx)(n.code,{children:"osism console testbed-node-0"})]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>d});var o=s(96540);const t={},i=o.createContext(t);function l(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/67140352.53708a8c.js b/assets/js/67140352.53708a8c.js new file mode 100644 index 0000000000..b4e376f6bf --- /dev/null +++ b/assets/js/67140352.53708a8c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[93575],{997:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"iam/domain-manager-setup-and-usage","title":"Domain Manager setup and usage","description":"The following documentation refers to a SCS standard that is still in draft state.","source":"@site/docs/05-iam/domain-manager-setup-and-usage.md","sourceDirName":"05-iam","slug":"/iam/domain-manager-setup-and-usage","permalink":"/docs/iam/domain-manager-setup-and-usage","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/05-iam/domain-manager-setup-and-usage.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Guides","permalink":"/docs/category/guides-2"},"next":{"title":"Example setup configuration in SCS deployment explained","permalink":"/docs/iam/SCS-example-setup-configuration-description"}}');var o=a(74848),s=a(28453);const r={},t="Domain Manager setup and usage",d={},l=[{value:"Preface",id:"preface",level:2},{value:"Warning regarding the exposure of domain names",id:"warning-regarding-the-exposure-of-domain-names",level:3},{value:"Infrastructure configuration",id:"infrastructure-configuration",level:2},{value:"[Initial] Keystone API policy adjustments",id:"initial-keystone-api-policy-adjustments",level:3},{value:"[Initial] Keystone role creation",id:"initial-keystone-role-creation",level:3},{value:"[Runtime] Domain Manager managed roles adjustment",id:"runtime-domain-manager-managed-roles-adjustment",level:3},{value:"Administrative operation",id:"administrative-operation",level:2},{value:"Creating domains",id:"creating-domains",level:3},{value:"Creating a Domain Manager user",id:"creating-a-domain-manager-user",level:3},{value:"Assigning the Domain Manager role to an existing user",id:"assigning-the-domain-manager-role-to-an-existing-user",level:3},{value:"Revoking the Domain Manager role",id:"revoking-the-domain-manager-role",level:3},{value:"Domain Manager operation",id:"domain-manager-operation",level:2},{value:"Managing users within a domain",id:"managing-users-within-a-domain",level:3},{value:"Managing projects within a domain",id:"managing-projects-within-a-domain",level:3},{value:"Deleting projects",id:"deleting-projects",level:4},{value:"Managing groups within a domain",id:"managing-groups-within-a-domain",level:3},{value:"Managing group membership",id:"managing-group-membership",level:4},{value:"Managing role assignments within a domain",id:"managing-role-assignments-within-a-domain",level:3},{value:"Managing user role assignments",id:"managing-user-role-assignments",level:4},{value:"Managing group role assignments",id:"managing-group-role-assignments",level:4}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"domain-manager-setup-and-usage",children:"Domain Manager setup and usage"})}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsx)(n.p,{children:"The following documentation refers to a SCS standard that is still in draft state.\nIt is not meant for productive use yet but CSPs are encouraged to test-drive and provide feedback!"})}),"\n",(0,o.jsx)(n.h2,{id:"preface",children:"Preface"}),"\n",(0,o.jsxs)(n.p,{children:["SCS defines the ",(0,o.jsx)(n.strong,{children:"Domain Manager"})," standard, introducing a special persona to the OpenStack Keystone identity manager.\nThis persona offers a properly domain-scoped permission set to manage users, groups, projects and role assignments within a domain.\nIts intended use case is to offer extensive identity management self-service capabilities to tenants mapped to a domain."]}),"\n",(0,o.jsx)(n.p,{children:"This guide will explain setup, configuration and usage of the SCS Domain Manager standard."}),"\n",(0,o.jsx)(n.h3,{id:"warning-regarding-the-exposure-of-domain-names",children:"Warning regarding the exposure of domain names"}),"\n",(0,o.jsxs)(n.p,{children:["Due to architectural limitations currently existing in OpenStack Keystone, assigning the ",(0,o.jsx)(n.code,{children:"manager"})," role to users while the configuration of the SCS Domain Manager standard has been applied will ",(0,o.jsx)(n.strong,{children:"enable them to see the IDs and names of all existing domains"}),".\nThis includes domains other than their own, meaning that other tenant's identities might be exposed depending on the relation between them and the name of their domain.\nCSPs aiming to appoint Domain Manager users must be aware of this limitation and should exclusively ",(0,o.jsx)(n.strong,{children:"use pseudonymized domain names across the whole infrastructure"}),".\nIf CSPs strictly follow the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0301-v1-naming-conventions.md",children:"SCS naming conventions"})," for domains this is already addressed.\nIf this is not feasible for the CSP, they may opt to refrain from making use of the Domain Manager functionality at all, i.e. never assign the ",(0,o.jsx)(n.code,{children:"manager"})," role to tenant users."]}),"\n",(0,o.jsxs)(n.admonition,{type:"info",children:[(0,o.jsx)(n.p,{children:"This architectural limitation will be fixed in upcoming OpenStack and SCS releases."}),(0,o.jsxs)(n.p,{children:["See ",(0,o.jsx)(n.a,{href:"https://bugs.launchpad.net/keystone/+bug/2041611",children:"https://bugs.launchpad.net/keystone/+bug/2041611"})]})]}),"\n",(0,o.jsx)(n.h2,{id:"infrastructure-configuration",children:"Infrastructure configuration"}),"\n",(0,o.jsxs)(n.p,{children:["An initial infrastructure configuration of the Domain Manager persona must be completed before it can be used.\nThis includes adjusting the Keystone API policy configuration and the registration of the ",(0,o.jsx)(n.code,{children:"manager"})," role."]}),"\n",(0,o.jsx)(n.p,{children:'The following sections describe the configuration to be implemented on the infrastructure-level.\nThis requires infrastructure access and OpenStack admin rights.\nFor tasks marked with "[Initial]" the described procedure only has to happen once initially.\nFor tasks marked with "[Runtime]" the described procedure may be repeated later on to make adjustments.'}),"\n",(0,o.jsx)(n.h3,{id:"initial-keystone-api-policy-adjustments",children:"[Initial] Keystone API policy adjustments"}),"\n",(0,o.jsxs)(n.p,{children:['First, incorporate the Keystone API policy definitions as described in the SCS Domain Manager standard.\nThis is usually done in "',(0,o.jsx)(n.code,{children:"/etc/keystone/policy.yaml"}),'" of the Keystone API service.\nOtherwise, an entry called "',(0,o.jsx)(n.code,{children:"policy_file"}),'" under the "',(0,o.jsx)(n.code,{children:"[oslo_policy]"}),'" section of "',(0,o.jsx)(n.code,{children:"/etc/keystone/keystone.conf"}),'" might exist that points to a different policy file path.\nIn such case, adjust or create the file at the specified path.']}),"\n",(0,o.jsxs)(n.p,{children:['When incorporating the policy definitions from the standard make sure to properly merge it with existing policy definitions, if any exist.\nAlso choose the definition of manageable roles in the "',(0,o.jsx)(n.code,{children:"is_domain_managed_role"}),'" rule of the policy carefully according to your requirements and environment.\nSee the standard for more details on this rule.']}),"\n",(0,o.jsx)(n.p,{children:"Depending on the deployment method used, the adjustments may also need to be persisted in the corresponding infrastructure management solution, such as Ansible."}),"\n",(0,o.jsx)(n.h3,{id:"initial-keystone-role-creation",children:"[Initial] Keystone role creation"}),"\n",(0,o.jsxs)(n.p,{children:["The role ",(0,o.jsx)(n.code,{children:"manager"})," has to exist in Keystone.\nIf the role does not exist, it needs to be created in Keystone once.\nThis can be done with the OpenStackClient using the following command:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack role create manager\n"})}),"\n",(0,o.jsx)(n.h3,{id:"runtime-domain-manager-managed-roles-adjustment",children:"[Runtime] Domain Manager managed roles adjustment"}),"\n",(0,o.jsxs)(n.p,{children:['The list of roles that a Domain Manager can assign within a domain is configured using the "',(0,o.jsx)(n.code,{children:"is_domain_managed_role"}),'" rule of the policy definitions.\nThe SCS Domain Manager standard allows flexibility in defining the set of roles a Domain Manager may assign and revoke within a domain and enables adjustments at runtime',(0,o.jsx)(n.sup,{children:(0,o.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"."]}),"\n",(0,o.jsxs)(n.p,{children:['The set of roles can be adjusted independently from the rest of the policy by changing only the "',(0,o.jsx)(n.code,{children:"is_domain_managed_role"}),"\" line it Keystone's API policy file.\nChanges will apply to existing and future Domain Manager users.\nThis means that changes can be implemented at runtime",(0,o.jsx)(n.sup,{children:(0,o.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["The following example entry adjusts the rule to allow both ",(0,o.jsx)(n.code,{children:"member"})," and ",(0,o.jsx)(n.code,{children:"reader"})," roles to be managed by Domain Managers:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"'is_domain_managed_role': \"'member':%(target.role.name)s or 'reader':%(target.role.name)s\"\n"})}),"\n",(0,o.jsx)(n.p,{children:"Refer to the SCS Domain Manager standard for more information."}),"\n",(0,o.jsx)(n.h2,{id:"administrative-operation",children:"Administrative operation"}),"\n",(0,o.jsxs)(n.p,{children:["The following sections describe actions available to CSP operators that possess the ",(0,o.jsx)(n.code,{children:"admin"})," role."]}),"\n",(0,o.jsx)(n.h3,{id:"creating-domains",children:"Creating domains"}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsxs)(n.p,{children:["It is highly recommended to use pseudonymized domain names when creating domains, since Domain Managers will currently be able to see the names of all existing domains.\nSee ",(0,o.jsx)(n.a,{href:"#warning-regarding-the-exposure-of-domain-names",children:"Warning regarding the exposure of domain names"})," for more details."]})}),"\n",(0,o.jsx)(n.p,{children:"For each tenant for which a self-service area (i.e. a domain) is to be established, a domain should be created before creating any users, projects or groups for this tenant:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack domain create $DOMAIN\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Any creation of users, projects or group for a tenant should happen strictly within the tenant's domain by passing the \"",(0,o.jsx)(n.code,{children:"--domain"}),'" flag to the corresponding creation commands, regardless of whether the commands are executed by an administrator or a Domain Manager.\nSee the ',(0,o.jsx)(n.a,{href:"#domain-manager-operation",children:"Domain Manager operation"})," section further down for reference."]}),"\n",(0,o.jsx)(n.h3,{id:"creating-a-domain-manager-user",children:"Creating a Domain Manager user"}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsxs)(n.p,{children:["Creating the first Domain Manager users for a domain is an action reserved for CSP administrators.\nDepending on whether the ",(0,o.jsx)(n.code,{children:"manager"})," role has been approved as a domain-managed role in the policy configuration by the CSP, Domain Manager users may be able to appoint further Domain Managers within the domain on their own later on."]})}),"\n",(0,o.jsxs)(n.p,{children:["First, create the user for the Domain Manager.\nYou may create the Domain Manager user either directly in the target tenant's domain or in a different domain.\nThe domain a Domain Manager will effectively be able to manage solely depends on where its role assignment of the ",(0,o.jsx)(n.code,{children:"manager"})," role is scoped, not the domain the Domain Manager user was originally created in."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack user create --domain $MANAGER_DOMAIN $USER_NAME\n"})}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"$MANAGER_DOMAIN"})," can be the same as the tenant domain ",(0,o.jsx)(n.code,{children:"$DOMAIN"})," or an entirely different one, depending on the desired origin domain of the user.\nIn the following sections ",(0,o.jsx)(n.code,{children:"$DOMAIN"})," will denote the tenant domain that the user is intended to manage as the Domain Manager persona."]})}),"\n",(0,o.jsxs)(n.p,{children:["Next, assign the ",(0,o.jsx)(n.code,{children:"manager"})," role in a domain-scoped fashion to the tenant domain:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack role add --user $USER_NAME --domain $DOMAIN manager\n"})}),"\n",(0,o.jsx)(n.h3,{id:"assigning-the-domain-manager-role-to-an-existing-user",children:"Assigning the Domain Manager role to an existing user"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack role add --user $USER_NAME --domain $DOMAIN manager\n"})}),"\n",(0,o.jsx)(n.h3,{id:"revoking-the-domain-manager-role",children:"Revoking the Domain Manager role"}),"\n",(0,o.jsxs)(n.p,{children:["In case the ",(0,o.jsx)(n.code,{children:"manager"})," role is to be revoked from an existing Domain Manager user, the following command can be used:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack role remove --user $USER_NAME --domain $DOMAIN manager\n"})}),"\n",(0,o.jsx)(n.h2,{id:"domain-manager-operation",children:"Domain Manager operation"}),"\n",(0,o.jsxs)(n.p,{children:["The following sections describe actions available to Domain Managers that possess the ",(0,o.jsx)(n.code,{children:"manager"})," role."]}),"\n",(0,o.jsx)(n.h3,{id:"managing-users-within-a-domain",children:"Managing users within a domain"}),"\n",(0,o.jsx)(n.p,{children:"Creating a user within a domain:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack user create --domain $DOMAIN $USER_NAME\n"})}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:['The explicit domain-scoping is only required for the creation command, any other user-centric commands like "',(0,o.jsx)(n.code,{children:"user set"}),'" or "',(0,o.jsx)(n.code,{children:"user delete"}),'" do not require the "',(0,o.jsx)(n.code,{children:"--domain"}),'" flag and are automatically scoped to the domain for Domain Managers.']})}),"\n",(0,o.jsx)(n.h3,{id:"managing-projects-within-a-domain",children:"Managing projects within a domain"}),"\n",(0,o.jsx)(n.p,{children:"Creating a project within a domain:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack project create --domain $DOMAIN $PROJECT_NAME\n"})}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:['The explicit domain-scoping is only required for the creation command, any other project-centric commands like "',(0,o.jsx)(n.code,{children:"project set"}),'" or "',(0,o.jsx)(n.code,{children:"project delete"}),'" do not require the "',(0,o.jsx)(n.code,{children:"--domain"}),'" flag and are automatically scoped to the domain for Domain Managers.']})}),"\n",(0,o.jsx)(n.h4,{id:"deleting-projects",children:"Deleting projects"}),"\n",(0,o.jsx)(n.p,{children:"Note that before deleting projects, make sure that all cloud resources (servers, volumes etc.) belonging to that project have been removed beforehand.\nOtherwise such resources might become orphaned and inaccessible without involving the CSP."}),"\n",(0,o.jsx)(n.h3,{id:"managing-groups-within-a-domain",children:"Managing groups within a domain"}),"\n",(0,o.jsx)(n.p,{children:"Creating a group within a domain:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack group create --domain $DOMAIN $GROUP_NAME\n"})}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:['The explicit domain-scoping is only required for the creation command, any other group-centric commands like "',(0,o.jsx)(n.code,{children:"group set"}),'" or "',(0,o.jsx)(n.code,{children:"group delete"}),'" do not require the "',(0,o.jsx)(n.code,{children:"--domain"}),'" flag and are automatically scoped to the domain for Domain Managers.']})}),"\n",(0,o.jsx)(n.h4,{id:"managing-group-membership",children:"Managing group membership"}),"\n",(0,o.jsx)(n.p,{children:"Adding a user to a group:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack group add user $GROUP $USER\n"})}),"\n",(0,o.jsx)(n.p,{children:"Removing a user from a group:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack group remove user $GROUP $USER\n"})}),"\n",(0,o.jsx)(n.h3,{id:"managing-role-assignments-within-a-domain",children:"Managing role assignments within a domain"}),"\n",(0,o.jsxs)(n.p,{children:["Role assignments managed by a Domain Manager work as usual with the exception that the roles that can be assigned and revoked are limited to a defined set which is explicitly approved for Domain Managers by the CSP.\nThis may or may not include the ",(0,o.jsx)(n.code,{children:"manager"})," role itself, meaning that Domain Managers may either be able to appoint other Domain Managers by themselves or have to ask the CSP to do so."]}),"\n",(0,o.jsx)(n.h4,{id:"managing-user-role-assignments",children:"Managing user role assignments"}),"\n",(0,o.jsx)(n.p,{children:"Assigning a role to a user within a project:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack role add --project $PROJECT --user $USER $ROLE\n"})}),"\n",(0,o.jsx)(n.p,{children:"Assigning a role to a user domain-wide:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack role add --domain $DOMAIN --user $USER $ROLE\n"})}),"\n",(0,o.jsx)(n.p,{children:"Revoking a project-level role assignment from a user:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack role remove --project $PROJECT --user $USER $ROLE\n"})}),"\n",(0,o.jsx)(n.p,{children:"Revoking a domain-wide role assignment from a user:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack role remove --domain $DOMAIN --user $USER $ROLE\n"})}),"\n",(0,o.jsx)(n.h4,{id:"managing-group-role-assignments",children:"Managing group role assignments"}),"\n",(0,o.jsx)(n.p,{children:"Assigning a role to a group within a project:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack role add --project $PROJECT --group $GROUP $ROLE\n"})}),"\n",(0,o.jsx)(n.p,{children:"Assigning a role to a group domain-wide:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack role add --domain $DOMAIN --group $GROUP $ROLE\n"})}),"\n",(0,o.jsx)(n.p,{children:"Revoking a project-level role assignment from a group:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack role remove --project $PROJECT --group $GROUP $ROLE\n"})}),"\n",(0,o.jsx)(n.p,{children:"Revoking a domain-wide role assignment from a group:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"openstack role remove --domain $DOMAIN --group $GROUP $ROLE\n"})}),"\n","\n",(0,o.jsxs)(n.section,{"data-footnotes":!0,className:"footnotes",children:[(0,o.jsx)(n.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{id:"user-content-fn-1",children:["\n",(0,o.jsxs)(n.p,{children:['"at runtime" in this context means that the configuration may be changed repeatedly after the initial configuration of Keystone and take effect immediately.\nDepending on the infrastructure management solution and high-availability configuration the described adjustments may or may not require a restart of the Keystone API service or lead to a downtime of the service. ',(0,o.jsx)(n.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})," ",(0,o.jsxs)(n.a,{href:"#user-content-fnref-1-2","data-footnote-backref":"","aria-label":"Back to reference 1-2",className:"data-footnote-backref",children:["\u21a9",(0,o.jsx)(n.sup,{children:"2"})]})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>r,x:()=>t});var i=a(96540);const o={},s=i.createContext(o);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6738f543.435cfaa6.js b/assets/js/6738f543.435cfaa6.js new file mode 100644 index 0000000000..651ea1adbb --- /dev/null +++ b/assets/js/6738f543.435cfaa6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[92671],{56129:(s,d,e)=>{e.r(d),e.d(d,{TableCellStyleApplier:()=>h,assets:()=>l,contentTitle:()=>c,default:()=>o,frontMatter:()=>i,metadata:()=>r,toc:()=>x});const r=JSON.parse('{"id":"standards/overview","title":"Overview","description":"Standards are the core deliverable of SCS. By standardizing the open source software components of a cloud computing stack, their versions, how they are to be configured, deployed and utilized, SCS guarantees the reproducibility of a certain behavior of this technology.","source":"@site/standards/standards/overview.mdx","sourceDirName":"standards","slug":"/standards/overview","permalink":"/standards/standards/overview","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"Compliance Check Pipeline","permalink":"/standards/certification/pipeline"},"next":{"title":"Global Standards","permalink":"/standards/global/"}}');var n=e(74848),t=e(28453),a=e(96540);const i={},c="Overview",l={},h=()=>{const s={3:"#FBFDE2",4:"#E2EAFD",5:"#FDE2E2"},d={2:"#FBFDE2",3:"#E2EAFD",4:"#FDE2E2"};return(0,a.useEffect)((()=>{const e=(s,d)=>{const e=document.querySelector("#"+s);if(e){const s=e.nextElementSibling;s&&"table"===s.tagName.toLowerCase()&&s.querySelectorAll("tbody tr").forEach((s=>{s.querySelectorAll("td").forEach(((s,e)=>{d[e]&&"-"!==s.textContent.trim()&&(s.style.backgroundColor=d[e])}))}))}};e("color-table-cells-overview",s),e("color-table-cells-track-overview",d)}),[]),null},x=[];function j(s){const d={a:"a",em:"em",h1:"h1",header:"header",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(d.header,{children:(0,n.jsx)(d.h1,{id:"overview",children:"Overview"})}),"\n",(0,n.jsx)(d.p,{children:"Standards are the core deliverable of SCS. By standardizing the open source software components of a cloud computing stack, their versions, how they are to be configured, deployed and utilized, SCS guarantees the reproducibility of a certain behavior of this technology."}),"\n",(0,n.jsx)(d.p,{children:"SCS standards are discussed, developed and maintained in the community by the corresponding teams (see Track in the table below), which naturally include existing users of SCS."}),"\n",(0,n.jsx)("p",{children:"*Legend to the column headings and entries:"}),"\n",(0,n.jsxs)(d.ul,{children:["\n",(0,n.jsx)(d.li,{children:"Document states: Draft, Effective, Deprecated (and no longer effective)"}),"\n",(0,n.jsx)(d.li,{children:"Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future"}),"\n",(0,n.jsx)(d.li,{children:"Entries in the effective column marked with a \u2020 will turn deprecated in the near future"}),"\n"]}),"\n","\n","\n",(0,n.jsx)(h,{}),"\n",(0,n.jsx)("div",{id:"color-table-cells-overview"}),"\n",(0,n.jsxs)(d.table,{children:[(0,n.jsx)(d.thead,{children:(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.th,{children:"Standard"}),(0,n.jsx)(d.th,{children:"Track"}),(0,n.jsx)(d.th,{children:"Description"}),(0,n.jsx)(d.th,{children:"Draft"}),(0,n.jsx)(d.th,{children:"Effective"}),(0,n.jsx)(d.th,{children:"Deprecated*"})]})}),(0,n.jsxs)(d.tbody,{children:[(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/global/scs-0001",children:"scs-0001"})}),(0,n.jsx)(d.td,{children:"Global"}),(0,n.jsx)(d.td,{children:"Sovereign Cloud Standards"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0001-v1-sovereign-cloud-standards",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/global/scs-0002",children:"scs-0002"})}),(0,n.jsx)(d.td,{children:"Global"}),(0,n.jsx)(d.td,{children:"Standards, Docs and Organisation"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0002-v2-standards-docs-org",children:"v2"})}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0002-v1-standards-docs-org",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/global/scs-0003",children:"scs-0003"})}),(0,n.jsx)(d.td,{children:"Global"}),(0,n.jsx)(d.td,{children:"Sovereign Cloud Standards YAML"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/global/scs-0004",children:"scs-0004"})}),(0,n.jsx)(d.td,{children:"Global"}),(0,n.jsx)(d.td,{children:"Regulations for achieving SCS-compatible certification"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0004-v1-achieving-certification",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/global/scs-0005",children:"scs-0005"})}),(0,n.jsx)(d.td,{children:"Global"}),(0,n.jsx)(d.td,{children:"Governance of the SCS community"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0005-v1-project-governance",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0100",children:"scs-0100"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"SCS Flavor Naming Standard"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"v3"})}),(0,n.jsxs)(d.td,{children:[(0,n.jsx)(d.a,{href:"/standards/scs-0100-v1-flavor-naming",children:"v1"}),", ",(0,n.jsx)(d.a,{href:"/standards/scs-0100-v2-flavor-naming",children:"v2"})]})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0100-w1-flavor-naming-implementation-testing",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0101",children:"scs-0101"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"SCS Entropy"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0101-v1-entropy",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0101-w1-entropy-implementation-testing",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0102",children:"scs-0102"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"SCS Image Metadata"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0102-v1-image-metadata",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0102-w1-image-metadata-implementation-testing",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0103",children:"scs-0103"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"SCS Standard Flavors and Properties"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0103-v1-standard-flavors",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0104",children:"scs-0104"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"SCS Standard Images"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0104-v1-standard-images",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: Implementation Notes"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0104-w1-standard-images-implementation",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0110",children:"scs-0110"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"SSD Flavors"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0110-v1-ssd-flavors",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0111",children:"scs-0111"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"Decisions for the Volume Type Standard"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0111-v1-volume-type-decisions",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0112",children:"scs-0112"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"SONiC Support in SCS"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0112-v1-sonic",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0113",children:"scs-0113"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"Security Groups Decision Record"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0113-v1-security-groups-decision-record",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0114",children:"scs-0114"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"SCS Volume Types"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0114-v1-volume-type-standard",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0115",children:"scs-0115"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"Default Rules for Security Groups"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0115-v1-default-rules-for-security-groups",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0116",children:"scs-0116"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"SCS Key Manager Standard"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0116-v1-key-manager-standard",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0116-w1-key-manager-implementation-testing",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0117",children:"scs-0117"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"Volume Backup Functionality"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0117-v1-volume-backup-service",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0118",children:"scs-0118"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"SCS Taxonomy of Failsafe Levels"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0118-v1-taxonomy-of-failsafe-levels",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: Examples of Failure Cases and their impact on IaaS and KaaS resources"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0118-w1-example-impacts-of-failure-scenarios",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0119",children:"scs-0119"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"Replacement of the deprecated ceph-ansible tool"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0119-v1-rook-decision",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0120",children:"scs-0120"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"Cluster-API images"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0120-v1-capi-images",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0121",children:"scs-0121"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"SCS Availability Zones"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0121-v1-Availability-Zones-Standard",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0121-w1-Availability-Zones-Standard",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0122",children:"scs-0122"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.em,{children:"End-to-End Encryption between Customer Workloads"})}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0122-v1-node-to-node-encryption",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0123",children:"scs-0123"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"Mandatory and Supported IaaS Services"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0124",children:"scs-0124"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"Standard for the security of IaaS service software"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0124-v1-security-of-iaas-service-software",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: SCS Standard for the security of IaaS service software: Implementation and Testing Notes"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0124-w1-security-of-iaas-service-software",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iaas/scs-0125",children:"scs-0125"})}),(0,n.jsx)(d.td,{children:"IaaS"}),(0,n.jsx)(d.td,{children:"Secure Connections"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0125-v1-secure-connections",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/kaas/scs-0200",children:"scs-0200"})}),(0,n.jsx)(d.td,{children:"KaaS"}),(0,n.jsx)(d.td,{children:"Using Sonobuoy for KaaS conformance tests"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/kaas/scs-0210",children:"scs-0210"})}),(0,n.jsx)(d.td,{children:"KaaS"}),(0,n.jsx)(d.td,{children:"SCS K8S Version Policy"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0210-v2-k8s-version-policy",children:"v2"})}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0210-v1-k8s-new-version-policy",children:"v1"})})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0210-w1-k8s-version-policy-implementation-testing",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/kaas/scs-0211",children:"scs-0211"})}),(0,n.jsx)(d.td,{children:"KaaS"}),(0,n.jsx)(d.td,{children:"SCS KaaS default storage class"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0211-v2-kaas-default-storage-class",children:"v2"})}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0211-v1-kaas-default-storage-class",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/kaas/scs-0212",children:"scs-0212"})}),(0,n.jsx)(d.td,{children:"KaaS"}),(0,n.jsx)(d.td,{children:"Requirements for container registries"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0212-v1-requirements-for-container-registries",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/kaas/scs-0213",children:"scs-0213"})}),(0,n.jsx)(d.td,{children:"KaaS"}),(0,n.jsx)(d.td,{children:"Kubernetes Nodes Anti Affinity"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0213-v1-k8s-nodes-anti-affinity",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/kaas/scs-0214",children:"scs-0214"})}),(0,n.jsx)(d.td,{children:"KaaS"}),(0,n.jsx)(d.td,{children:"Kubernetes Node Distribution and Availability"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsxs)(d.td,{children:[(0,n.jsx)(d.a,{href:"/standards/scs-0214-v1-k8s-node-distribution",children:"v1"}),", ",(0,n.jsx)(d.a,{href:"/standards/scs-0214-v2-k8s-node-distribution",children:"v2"})]}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: Implementation and Testing Notes"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/kaas/scs-0215",children:"scs-0215"})}),(0,n.jsx)(d.td,{children:"KaaS"}),(0,n.jsx)(d.td,{children:"Robustness features for Kubernetes clusters"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0215-v1-robustness-features",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/kaas/scs-0216",children:"scs-0216"})}),(0,n.jsx)(d.td,{children:"KaaS"}),(0,n.jsx)(d.td,{children:"Requirements for testing cluster-stacks"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/kaas/scs-0217",children:"scs-0217"})}),(0,n.jsx)(d.td,{children:"KaaS"}),(0,n.jsx)(d.td,{children:"Kubernetes cluster hardening"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0217-v1-cluster-hardening",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/kaas/scs-0218",children:"scs-0218"})}),(0,n.jsx)(d.td,{children:"KaaS"}),(0,n.jsx)(d.td,{children:"Container registry for SCS standard implementation"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/kaas/scs-0219",children:"scs-0219"})}),(0,n.jsx)(d.td,{children:"KaaS"}),(0,n.jsx)(d.td,{children:"KaaS Networking Standard"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0219-v1-kaas-networking",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: Implementation Notes"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0219-w1-kaas-networking",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iam/scs-0300",children:"scs-0300"})}),(0,n.jsx)(d.td,{children:"IAM"}),(0,n.jsx)(d.td,{children:"Requirements for SSO identity federation"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0300-v1-requirements-for-sso-identity-federation",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iam/scs-0301",children:"scs-0301"})}),(0,n.jsx)(d.td,{children:"IAM"}),(0,n.jsx)(d.td,{children:"Naming for domains/groups/roles/project when onboarding new customers"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0301-v1-naming-conventions",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/iam/scs-0302",children:"scs-0302"})}),(0,n.jsx)(d.td,{children:"IAM"}),(0,n.jsx)(d.td,{children:"Domain Manager configuration for Keystone"}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0302-v1-domain-manager-role",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{}),(0,n.jsx)(d.td,{children:"Supplement: Domain Manager implementation notes"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0302-w1-domain-manager-implementation-notes",children:"w1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/ops/scs-0400",children:"scs-0400"})}),(0,n.jsx)(d.td,{children:"Ops"}),(0,n.jsx)(d.td,{children:"Status Page create decision"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0400-v1-status-page-create-decision",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/ops/scs-0401",children:"scs-0401"})}),(0,n.jsx)(d.td,{children:"Ops"}),(0,n.jsx)(d.td,{children:"Status page reference implementation decision"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0401-v1-status-page-reference-implementation-decision",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/ops/scs-0402",children:"scs-0402"})}),(0,n.jsx)(d.td,{children:"Ops"}),(0,n.jsx)(d.td,{children:"Status page OpenAPI decision"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0402-v1-status-page-openapi-spec-decision",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/ops/scs-0403",children:"scs-0403"})}),(0,n.jsx)(d.td,{children:"Ops"}),(0,n.jsx)(d.td,{children:"Architecture for the Cloud Service provider Observability System for the KaaS Layer"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0403-v1-csp-kaas-observability-stack",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/ops/scs-0410",children:"scs-0410"})}),(0,n.jsx)(d.td,{children:"Ops"}),(0,n.jsx)(d.td,{children:"Gnocchi as database for metering"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0410-v1-gnocchi-as-metering-database",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/ops/scs-0411",children:"scs-0411"})}),(0,n.jsx)(d.td,{children:"Ops"}),(0,n.jsx)(d.td,{children:"Push-based approach for providing usage data"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0411-v1-publishing_method_for_metering_data",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]}),(0,n.jsxs)(d.tr,{children:[(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/ops/scs-0412",children:"scs-0412"})}),(0,n.jsx)(d.td,{children:"Ops"}),(0,n.jsx)(d.td,{children:"Exposition of IaaS metering data as JSON"}),(0,n.jsx)(d.td,{children:(0,n.jsx)(d.a,{href:"/standards/scs-0412-v1-metering-json",children:"v1"})}),(0,n.jsx)(d.td,{children:"-"}),(0,n.jsx)(d.td,{children:"-"})]})]})]})]})}function o(s={}){const{wrapper:d}={...(0,t.R)(),...s.components};return d?(0,n.jsx)(d,{...s,children:(0,n.jsx)(j,{...s})}):j(s)}},28453:(s,d,e)=>{e.d(d,{R:()=>a,x:()=>i});var r=e(96540);const n={},t=r.createContext(n);function a(s){const d=r.useContext(t);return r.useMemo((function(){return"function"==typeof s?s(d):{...d,...s}}),[d,s])}function i(s){let d;return d=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:a(s.components),r.createElement(t.Provider,{value:d},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/67dad519.876abf01.js b/assets/js/67dad519.876abf01.js new file mode 100644 index 0000000000..b133ca5808 --- /dev/null +++ b/assets/js/67dad519.876abf01.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4980],{60486:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>a});const s=JSON.parse('{"id":"iaas/guides/deploy-guide/provisioning","title":"Provisioning of bare-metal nodes","description":"For the initial deployment of the management plane and the control plane of OSISM,","source":"@site/docs/02-iaas/guides/deploy-guide/provisioning.md","sourceDirName":"02-iaas/guides/deploy-guide","slug":"/iaas/guides/deploy-guide/provisioning","permalink":"/docs/iaas/guides/deploy-guide/provisioning","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/provisioning.md","tags":[],"version":"current","sidebarPosition":30,"frontMatter":{"sidebar_label":"Provisioning","sidebar_position":30},"sidebar":"docs","previous":{"title":"Manager","permalink":"/docs/iaas/guides/deploy-guide/manager"},"next":{"title":"Bootstrap","permalink":"/docs/iaas/guides/deploy-guide/bootstrap"}}');var o=i(74848),t=i(28453);const r={sidebar_label:"Provisioning",sidebar_position:30},l="Provisioning of bare-metal nodes",d={},a=[{value:"Automated Installation using Node Images",id:"automated-installation-using-node-images",level:2},{value:"Manual provisioning",id:"manual-provisioning",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"provisioning-of-bare-metal-nodes",children:"Provisioning of bare-metal nodes"})}),"\n",(0,o.jsx)(n.p,{children:"For the initial deployment of the management plane and the control plane of OSISM,\nthe nodes must be pre-provisioned with Ubuntu 22.04. Currently, only Ubuntu 22.04 is supported\nby OSISM."}),"\n",(0,o.jsx)(n.p,{children:"Data plane nodes can be automatically provisioned after the initial deployment and\ndo not need to be pre-provisioned."}),"\n",(0,o.jsxs)(n.p,{children:["It is recommended not to install the initial nodes of the management plane and the\ncontrol plane manually. An ISO image is provided for this purpose which automatically\nprovisions a node. The ISO images are available for download in the\n",(0,o.jsx)(n.a,{href:"https://github.com/osism/node-image",children:"osism/node-image"})," repository."]}),"\n",(0,o.jsx)(n.h2,{id:"automated-installation-using-node-images",children:"Automated Installation using Node Images"}),"\n",(0,o.jsx)(n.p,{children:"There are different variants of the ISO image. The variants differ in the disc layout."}),"\n",(0,o.jsxs)(n.p,{children:["The pre-build variants are described in the ",(0,o.jsx)(n.a,{href:"https://github.com/osism/node-image/blob/main/README.md",children:"osism/node-image"})," repository."]}),"\n",(0,o.jsx)(n.p,{children:"A good way to provision the nodes is to use virtual media mounts via the usually available Redfish\nfunctionality of the BMC of the servers used. In this way, the basic installation can be carried\nout without external dependencies such as adapting the switch configuration, DHCP, upstream connectivity, etc.\nIn many cases, this simplifies the process, makes it more automation-friendly and avoids potential sources of error."}),"\n",(0,o.jsxs)(n.p,{children:["OSISM also provides a ",(0,o.jsx)(n.a,{href:"https://github.com/osism/node-image?tab=readme-ov-file#creation-of-specific-images",children:"tool"})," to generate node images specific for you needs."]}),"\n",(0,o.jsx)(n.p,{children:"This makes particular sense for the node-provisioning in the following situations:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Make complex configurations like layer3 underlay"}),"\n",(0,o.jsx)(n.li,{children:"Add your SSH keys to the image"}),"\n",(0,o.jsx)(n.li,{children:"Configure a specific root password"}),"\n",(0,o.jsxs)(n.li,{children:["Change other characteristics of the setup","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Templates"}),"\n",(0,o.jsx)(n.li,{children:"Partitioning"}),"\n",(0,o.jsx)(n.li,{children:"Packages"}),"\n",(0,o.jsx)(n.li,{children:"..."}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.li,{children:"Develop new standard images"}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["The procedures for building custom images are described in the\n",(0,o.jsx)(n.a,{href:"https://github.com/osism/node-image/blob/main/README.md",children:"osism/node-image"})," repository."]}),"\n",(0,o.jsx)(n.h2,{id:"manual-provisioning",children:"Manual provisioning"}),"\n",(0,o.jsx)(n.p,{children:"If none of the provided variants is suitable, this section describes the manual\ninstallation with the help of the Ubuntu 22.04 live ISO image. The manual installation\nis possible without network connectivity."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Download the latest ISO image for Ubuntu 22.04 from ",(0,o.jsx)(n.a,{href:"https://www.releases.ubuntu.com/22.04/",children:"releases.ubuntu.com"}),".","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Use the ",(0,o.jsx)(n.code,{children:"ubuntu-22.04.1-live-server-amd64.iso"})," image."]}),"\n",(0,o.jsx)(n.li,{children:"The version number may be different, always use the latest available version of 22.04 LTS."}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"English"})," as language."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"Install Ubuntu Server"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"English as language"})," (again)."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose your location (e.g. ",(0,o.jsx)(n.code,{children:"Germany"}),")."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"en_US.UTF-8"})," as locale."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose the keyboard layout from a list, use ",(0,o.jsx)(n.code,{children:"English (US)"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose and configure the primary network interface.","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Depending on the environment, the network may not work at this point. Then select any interface\nand then select ",(0,o.jsx)(n.code,{children:"Do not configure the network at this time"})," in the next step."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["Set the hostname.","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The hostname is e.g. ",(0,o.jsx)(n.code,{children:"node"})," and not a FQDN like ",(0,o.jsx)(n.code,{children:"node.systems.osism.xyz"}),"."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["Set ",(0,o.jsx)(n.code,{children:"osism"})," as full name for the new user."]}),"\n",(0,o.jsxs)(n.li,{children:["Set ",(0,o.jsx)(n.code,{children:"osism"})," as the username for the account.","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The later used operator user ",(0,o.jsx)(n.code,{children:"dragon"})," is created during the bootstrap and ",(0,o.jsx)(n.strong,{children:"should not be created"})," during the installation.\nDo not use ",(0,o.jsx)(n.code,{children:"dragon"})," as username."]}),"\n",(0,o.jsx)(n.li,{children:"The account is only needed initially and can be deleted after completion of the bootstrap."}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.li,{children:"Set a password for the account."}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"Manual"})," as partitioning method and execute the partitioning according to company specifications","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"The use of a UEFI is recommended"}),"\n",(0,o.jsx)(n.li,{children:"The use of a RAID is recommended. We prefer the use of software RAIDs to make us less dependent on hardware.\nBut there is nothing against using hardware RAIDs."}),"\n",(0,o.jsxs)(n.li,{children:["The use of a LVM2 is recommended. ",(0,o.jsx)(n.code,{children:"system"})," is recommended as the name for the volume group."]}),"\n",(0,o.jsxs)(n.li,{children:["Dedicated disks may be provided for ",(0,o.jsx)(n.code,{children:"/var/lib/docker"})," on the controller nodes. In this case, do not\nuse an LV for ",(0,o.jsx)(n.code,{children:"/var/lib/docker"})," but the devices provided for it."]}),"\n",(0,o.jsx)(n.li,{children:"Do not configure devices that are not required for the operating system."}),"\n",(0,o.jsxs)(n.li,{children:["The use of own file systems for the following mountpoints is recommended. The size of the partitions/LVs\nis minimal. Depending on the node type, the partitions/LVs should be made larger.","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/"})," (10 GByte, logical volume ",(0,o.jsx)(n.code,{children:"root"}),")"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/home"})," (2 GByte, logical volume ",(0,o.jsx)(n.code,{children:"home"}),")"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/tmp"})," (5 GByte, logical volume ",(0,o.jsx)(n.code,{children:"tmp"}),")"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/var/lib/ceph"})," (50 GByte, logical volume ",(0,o.jsx)(n.code,{children:"ceph"}),") (optional for storage nodes)"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/var/lib/docker"})," (30 GByte, logical volume ",(0,o.jsx)(n.code,{children:"docker"}),", do not set the ",(0,o.jsx)(n.code,{children:"nosuid"})," flag on ",(0,o.jsx)(n.code,{children:"/var/lib/docker"}),")","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["When using XFS as the file system for ",(0,o.jsx)(n.code,{children:"/var/lib/docker"}),", note the following: Running on XFS without ",(0,o.jsx)(n.code,{children:"d_type"})," support\ncauses Docker to skip the attempt to use the ",(0,o.jsx)(n.code,{children:"overlay"})," or ",(0,o.jsx)(n.code,{children:"overlay2"})," driver."]}),"\n",(0,o.jsx)(n.li,{children:"100 GB should be used on a control node at the beginning."}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/var/lib/docker"})," must be extended later during operation depending on the node type. You do this\nin operation when you can see how many logs etc. are generated."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/var/log/audit"})," (1 GByte, logical volume ",(0,o.jsx)(n.code,{children:"audit"}),")"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/var"})," (10 GByte, logical volume ",(0,o.jsx)(n.code,{children:"var"}),")"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"swap"})," (8 GByte, logical volume ",(0,o.jsx)(n.code,{children:"swap"}),")"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"No automatic updates"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"OpenSSH server"})," as software to install.","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Do not install any other software component."})," Everything you need will be installed later by OSISM.\nIn particular, it is not necessary to install a desktop environment."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.li,{children:"After completion, restart the system."}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>l});var s=i(96540);const o={},t=s.createContext(o);function r(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/685813dc.ae72c5c6.js b/assets/js/685813dc.ae72c5c6.js new file mode 100644 index 0000000000..abfd4c5ec8 --- /dev/null +++ b/assets/js/685813dc.ae72c5c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[11953],{10726:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>t,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>i});const c=JSON.parse('{"id":"iaas/components/resource-manager","title":"Resource Manager","description":"Preparations","source":"@site/docs/02-iaas/components/resource-manager.md","sourceDirName":"02-iaas/components","slug":"/iaas/components/resource-manager","permalink":"/docs/iaas/components/resource-manager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/resource-manager.md","tags":[],"version":"current","sidebarPosition":52,"frontMatter":{"sidebar_label":"Resource Manager","sidebar_position":52}}');var r=a(74848),d=a(28453);const o={sidebar_label:"Resource Manager",sidebar_position:52},s="Resource Manager",t={},i=[{value:"Preparations",id:"preparations",level:2},{value:"Nova",id:"nova",level:2},{value:"Live migration",id:"live-migration",level:3},{value:"Evacuation",id:"evacuation",level:3},{value:"Octavia",id:"octavia",level:2},{value:"Amphora rotation",id:"amphora-rotation",level:3},{value:"Cinder",id:"cinder",level:2},{value:"Orphans",id:"orphans",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"resource-manager",children:"Resource Manager"})}),"\n",(0,r.jsx)(n.h2,{id:"preparations",children:"Preparations"}),"\n",(0,r.jsx)(n.p,{children:"Prepare use of the OpenStack Resource Manager."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/osism/openstack-resource-manager\ncd openstack-resource-manager\npipenv install\npipenv shell\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Prepare cloud profile ",(0,r.jsx)(n.code,{children:"admin"})," in ",(0,r.jsx)(n.code,{children:"clouds.yml"})," and ",(0,r.jsx)(n.code,{children:"secure.yml"})," (use ",(0,r.jsx)(n.code,{children:"clouds.yml.sample"})," and ",(0,r.jsx)(n.code,{children:"secure.yml.sample"}),"\nin the ",(0,r.jsx)(n.a,{href:"https://github.com/osism/openstack-resource-manager",children:"openstack-resource-manager"})," repository as sample files)."]}),"\n",(0,r.jsx)(n.h2,{id:"nova",children:"Nova"}),"\n",(0,r.jsx)(n.h3,{id:"live-migration",children:"Live migration"}),"\n",(0,r.jsxs)(n.p,{children:["Live migrate all instances from compute node ",(0,r.jsx)(n.code,{children:"SOURCE"})," to compute node ",(0,r.jsx)(n.code,{children:"TARGET"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"python3 src/host-action.py --yes --disable --action live-migrate --host SOURCE --input TARGET\n"})}),"\n",(0,r.jsx)(n.h3,{id:"evacuation",children:"Evacuation"}),"\n",(0,r.jsxs)(n.p,{children:["Evacuate all instances from compute node ",(0,r.jsx)(n.code,{children:"SOURCE"})," to compute node ",(0,r.jsx)(n.code,{children:"TARGET"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"python3 src/host-action.py --yes --action evacutate --host SOURCE --input TARGET\n"})}),"\n",(0,r.jsx)(n.h2,{id:"octavia",children:"Octavia"}),"\n",(0,r.jsx)(n.h3,{id:"amphora-rotation",children:"Amphora rotation"}),"\n",(0,r.jsx)(n.p,{children:"Rotation of amphorae older than 30 days."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ python3 src/amphora.py --rotate\n2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa is older than 30 days\n2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa of loadbalancer 9008d3d7-f593-4bc3-941c-a740c178148d is rotated by a loadbalancer failover\n"})}),"\n",(0,r.jsx)(n.h2,{id:"cinder",children:"Cinder"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ python3 src/volume.py\n2023-12-11 23:09:44 | INFO | Volume ad848454-ba1f-4c28-b9a8-edada17948b0 hangs in CREATING status for more than 2 hours\nDelete volume ad848454-ba1f-4c28-b9a8-edada17948b0 [yes/no]:\n"})}),"\n",(0,r.jsx)(n.h2,{id:"orphans",children:"Orphans"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ python3 src/orphan.py\n2023-12-11 23:11:16 | INFO | Checking nova / server\n2023-12-11 23:11:21 | INFO | Checking neutron / port\n2023-12-11 23:11:23 | INFO | Checking neutron / router\n2023-12-11 23:11:23 | INFO | Checking neutron / network\n2023-12-11 23:11:24 | INFO | Checking neutron / subnet\n2023-12-11 23:11:24 | INFO | Checking neutron / floatingip\n2023-12-11 23:11:24 | INFO | Checking neutron / rbacpolicy\n2023-12-11 23:11:24 | INFO | Checking neutron / securitygroup\n2023-12-11 23:11:26 | INFO | Checking neutron / securitygrouprule\n2023-12-11 23:11:27 | INFO | Checking glance / image\n2023-12-11 23:11:30 | INFO | Checking glance / imagemember\n[...]\n+---------------+-------------------+--------------------------------------+----------------------------------+\n| servicename | resourcename | resource_id | project_id |\n|---------------+-------------------+--------------------------------------+----------------------------------|\n| neutron | port | 561f8f76-18b0-470a-92cd-4336346b4b18 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | port | 6d1986e4-1e6d-4d4a-961d-97d372945bb1 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | port | 74f9bddc-9bfa-4d06-a147-ca87127e501e | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | port | f630a66b-7725-4a68-868b-caebbaf1c003 | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | router | c0c4e4aa-53ee-4fd1-8f53-84d52cf6c60b | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | router | c8f9a13b-adcd-4a8e-942b-338bcf4dde7c | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | network | 62d6ad2a-0cda-4d45-9325-963b8eb67000 | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | network | 63b8fea6-7d7b-40c3-9c31-bee4404a92d6 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | subnet | 0cd16262-330a-44ad-9160-daef84aded2d | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | subnet | 690dee14-ac12-464d-a911-a873c27ec818 | d33b0d15fd474131a335207216297a2a |\n| neutron | subnet | 854e7c55-62e2-4679-9b18-805460b998ce | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | rbacpolicy | 00d7c2a2-6674-4f40-9f95-176a7858fcca | c8e4393b6d064a26a31014f82939172f |\n| neutron | rbacpolicy | 0608c701-5b81-4712-989b-ba03cdcc255d | c8e4393b6d064a26a31014f82939172f |\n[...]\n| neutron | securitygrouprule | fd3c553f-168e-4c24-ab40-09aa934bab86 | 3a96207b719643ae9ea9a81d95116e9e |\n| neutron | securitygrouprule | fdf337be-971c-4d5d-88ca-d90cdb468e88 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | securitygrouprule | ff8162fe-f053-49c9-8659-078061ce3e23 | d0b0add9ede0452791f71cb900e35242 |\n| glance | imagemember | c7f2cb0c25d34c5d886ecaf483e5fda6 | c7f2cb0c25d34c5d886ecaf483e5fda6 |\n| glance | imagemember | d4d0a161f9024fc8b517b0375eb97c89 | d4d0a161f9024fc8b517b0375eb97c89 |\n| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |\n| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |\n| glance | imagemember | d33b0d15fd474131a335207216297a2a | d33b0d15fd474131a335207216297a2a |\n| cinder | volume | e7c4b05c-b76a-40cc-8381-03262e57eb94 | 9b5f7f8ed70d410c81e3f45bf4e36498 |\n+---------------+-------------------+--------------------------------------+----------------------------------+\n"})})]})}function u(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>o,x:()=>s});var c=a(96540);const r={},d=c.createContext(r);function o(e){const n=c.useContext(d);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),c.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6875c492.d1eb8b03.js b/assets/js/6875c492.d1eb8b03.js new file mode 100644 index 0000000000..42a4921b2e --- /dev/null +++ b/assets/js/6875c492.d1eb8b03.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[84813],{47713:(e,t,n)=>{n.d(t,{A:()=>r});n(96540);var s=n(21312),a=n(39022),i=n(74848);function r(e){const{metadata:t}=e,{previousPage:n,nextPage:r}=t;return(0,i.jsxs)("nav",{className:"pagination-nav","aria-label":(0,s.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[n&&(0,i.jsx)(a.A,{permalink:n,title:(0,i.jsx)(s.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),r&&(0,i.jsx)(a.A,{permalink:r,title:(0,i.jsx)(s.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}},82907:(e,t,n)=>{n.d(t,{A:()=>_});n(96540);var s=n(18215),a=n(44096),i=n(74848);function r(e){let{children:t,className:n}=e;return(0,i.jsx)("article",{className:n,children:t})}var l=n(28774);const o={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:n,isBlogPostPage:r}=(0,a.e7)(),{permalink:c,title:d}=n,u=r?"h1":"h2";return(0,i.jsx)(u,{className:(0,s.A)(o.title,t),children:r?d:(0,i.jsx)(l.A,{to:c,children:d})})}var d=n(21312),u=n(53465),g=n(36266);const m={container:"container_mt6G"};function h(e){let{readingTime:t}=e;const n=function(){const{selectMessage:e}=(0,u.W)();return t=>{const n=Math.ceil(t);return e(n,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:n}))}}();return(0,i.jsx)(i.Fragment,{children:n(t)})}function p(e){let{date:t,formattedDate:n}=e;return(0,i.jsx)("time",{dateTime:t,children:n})}function x(){return(0,i.jsx)(i.Fragment,{children:" \xb7 "})}function j(e){let{className:t}=e;const{metadata:n}=(0,a.e7)(),{date:r,readingTime:l}=n,o=(0,g.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,i.jsxs)("div",{className:(0,s.A)(m.container,"margin-vert--md",t),children:[(0,i.jsx)(p,{date:r,formattedDate:(c=r,o.format(new Date(c)))}),void 0!==l&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(x,{}),(0,i.jsx)(h,{readingTime:l})]})]});var c}var f=n(56913);const b={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function A(e){let{className:t}=e;const{metadata:{authors:n},assets:r}=(0,a.e7)();if(0===n.length)return null;const l=n.every((e=>{let{name:t}=e;return!t})),o=1===n.length;return(0,i.jsx)("div",{className:(0,s.A)("margin-top--md margin-bottom--sm",l?b.imageOnlyAuthorRow:"row",t),children:n.map(((e,t)=>(0,i.jsx)("div",{className:(0,s.A)(!l&&(o?"col col--12":"col col--6"),l?b.imageOnlyAuthorCol:b.authorCol),children:(0,i.jsx)(f.A,{author:{...e,imageURL:r.authorsImageUrls[t]??e.imageURL}})},t)))})}function T(){return(0,i.jsxs)("header",{children:[(0,i.jsx)(c,{}),(0,i.jsx)(j,{}),(0,i.jsx)(A,{})]})}var v=n(70440),N=n(11544);function w(e){let{children:t,className:n}=e;const{isBlogPostPage:r}=(0,a.e7)();return(0,i.jsx)("div",{id:r?v.LU:void 0,className:(0,s.A)("markdown",n),children:(0,i.jsx)(N.A,{children:t})})}var y=n(17559),P=n(4336),k=n(62053);function U(){return(0,i.jsx)("b",{children:(0,i.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function R(e){const{blogPostTitle:t,...n}=e;return(0,i.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...n,children:(0,i.jsx)(U,{})})}function B(){const{metadata:e,isBlogPostPage:t}=(0,a.e7)(),{tags:n,title:r,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,u=!t&&o,g=n.length>0;if(!(g||u||l))return null;if(t){const e=!!(l||d||c);return(0,i.jsxs)("footer",{className:"docusaurus-mt-lg",children:[g&&(0,i.jsx)("div",{className:(0,s.A)("row","margin-top--sm",y.G.blog.blogFooterEditMetaRow),children:(0,i.jsx)("div",{className:"col",children:(0,i.jsx)(k.A,{tags:n})})}),e&&(0,i.jsx)(P.A,{className:(0,s.A)("margin-top--sm",y.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,i.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[g&&(0,i.jsx)("div",{className:(0,s.A)("col",{"col--9":u}),children:(0,i.jsx)(k.A,{tags:n})}),u&&(0,i.jsx)("div",{className:(0,s.A)("col text--right",{"col--3":g}),children:(0,i.jsx)(R,{blogPostTitle:r,to:e.permalink})})]})}function _(e){let{children:t,className:n}=e;const l=function(){const{isBlogPostPage:e}=(0,a.e7)();return e?void 0:"margin-bottom--xl"}();return(0,i.jsxs)(r,{className:(0,s.A)(l,n),children:[(0,i.jsx)(T,{}),(0,i.jsx)(w,{children:t}),(0,i.jsx)(B,{})]})}},33892:(e,t,n)=>{n.d(t,{A:()=>r});n(96540);var s=n(44096),a=n(82907),i=n(74848);function r(e){let{items:t,component:n=a.A}=e;return(0,i.jsx)(i.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,i.jsx)(s.in,{content:t,children:(0,i.jsx)(n,{children:(0,i.jsx)(t,{})})},t.metadata.permalink)}))})}},33069:(e,t,n)=>{n.r(t),n.d(t,{default:()=>f});n(96540);var s=n(18215),a=n(21312),i=n(61213),r=n(17559),l=n(96461),o=n(28774),c=n(28027),d=n(47713),u=n(41463),g=n(33892),m=n(32234),h=n(51107),p=n(74848);function x(e){let{tag:t}=e;const n=(0,l.ZD)(t);return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(i.be,{title:n,description:t.description}),(0,p.jsx)(u.A,{tag:"blog_tags_posts"})]})}function j(e){let{tag:t,items:n,sidebar:s,listMetadata:i}=e;const r=(0,l.ZD)(t);return(0,p.jsxs)(c.A,{sidebar:s,children:[t.unlisted&&(0,p.jsx)(m.A,{}),(0,p.jsxs)("header",{className:"margin-bottom--xl",children:[(0,p.jsx)(h.A,{as:"h1",children:r}),t.description&&(0,p.jsx)("p",{children:t.description}),(0,p.jsx)(o.A,{href:t.allTagsPath,children:(0,p.jsx)(a.A,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page",children:"View All Tags"})})]}),(0,p.jsx)(g.A,{items:n}),(0,p.jsx)(d.A,{metadata:i})]})}function f(e){return(0,p.jsxs)(i.e3,{className:(0,s.A)(r.G.wrapper.blogPages,r.G.page.blogTagPostListPage),children:[(0,p.jsx)(x,{...e}),(0,p.jsx)(j,{...e})]})}},32234:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var s=n(18215),a=n(44084),i=n(17559),r=n(27293),l=n(74848);function o(e){let{className:t}=e;return(0,l.jsx)(r.A,{type:"caution",title:(0,l.jsx)(a.Rc,{}),className:(0,s.A)(t,i.G.common.unlistedBanner),children:(0,l.jsx)(a.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(a.AE,{}),(0,l.jsx)(o,{...e})]})}},96461:(e,t,n)=>{n.d(t,{ZD:()=>r,uz:()=>l});n(96540);var s=n(21312),a=n(53465);n(74848);function i(){const{selectMessage:e}=(0,a.W)();return t=>e(t,(0,s.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}function r(e){const t=i();return(0,s.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}const l=()=>(0,s.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"})},44084:(e,t,n)=>{n.d(t,{AE:()=>o,Rc:()=>r,TT:()=>d,Uh:()=>l,Yh:()=>c});n(96540);var s=n(21312),a=n(5260),i=n(74848);function r(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function o(){return(0,i.jsx)(a.A,{children:(0,i.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}}}]); \ No newline at end of file diff --git a/assets/js/699c0e5c.e586dad1.js b/assets/js/699c0e5c.e586dad1.js new file mode 100644 index 0000000000..7f87c61289 --- /dev/null +++ b/assets/js/699c0e5c.e586dad1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[83725],{1551:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"scs-0111-v1-volume-type-decisions","title":"Decisions for the Volume Type Standard","description":"Introduction","source":"@site/standards/scs-0111-v1-volume-type-decisions.md","sourceDirName":".","slug":"/scs-0111-v1-volume-type-decisions","permalink":"/standards/scs-0111-v1-volume-type-decisions","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Decisions for the Volume Type Standard","type":"Decision Record","status":"Draft","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0111: Decisions for the Volume Type Standard","permalink":"/standards/iaas/scs-0111"},"next":{"title":"scs-0112: SONiC Support in SCS","permalink":"/standards/iaas/scs-0112"}}');var n=s(74848),o=s(28453);const a={title:"Decisions for the Volume Type Standard",type:"Decision Record",status:"Draft",track:"IaaS"},r=void 0,d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Encryption",id:"encryption",level:4},{value:"Backend Name",id:"backend-name",level:4},{value:"Availability Zones",id:"availability-zones",level:4},{value:"Multiattach",id:"multiattach",level:4},{value:"Replication",id:"replication",level:4},{value:"QoS",id:"qos",level:4},{value:"Other Backend-specific Highlights",id:"other-backend-specific-highlights",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2}];function c(e){const t={a:"a",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsx)(t.p,{children:"Volumes in OpenStack are virtual drives. They are managed by the storage service Cinder, which abstracts creation and usage of many different storage backends. While it is possible to use a backend like lvm which can reside on the same host as the hypervisor, this decision record wants to make a more clear differentiation between volumes and the ephemeral storage of a virtual machine. For all SCS deployments we want to assume that volumes are always residing in a storage backend that is NOT on the same host as a hypervisor - in short terms: Volumes are network storage. Ephemeral storage on the other hand is the only storage residing on a compute host. It is created by creating a VM directly from an Image and is automatically lost as soon as the VM cease to exist. Volumes on the other hand have to be created from Images and only after that can be used for VMs. They are persistent and will remain in the last state a VM has written on them before they cease to exit. Being persistent and not relying on the host where the VM resides, Volumes can easily be attached to another VM in case of a node outage and VMs be migrated way more easily, because only metadata and data in RAM has to be shifted to another host, accelerating any migration or evacuation of a VM."}),"\n",(0,n.jsx)(t.p,{children:"Volume Types are used to classify volumes and provide a basic decision for what kind of volume should be created. These volume types can sometimes very be backend-specific, and it might be hard for a user to choose the most suitable volume type, if there is more than one default type. Nevertheless, most of the configuration is done in the backends themselves, so volume types only work as a rough classification."}),"\n",(0,n.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,n.jsx)(t.p,{children:"We want to standardize a few varieties of volume types. While a user can choose simple things like size when creating a volume, Volume Types define a few broader aspects of volume. Encryption of volumes for example is solely decided by the volume type. And whether the volume will be replicated is a mix between definition in the volume type and backend specific configuration, but it's visibility can only be reached in the volume type."}),"\n",(0,n.jsx)(t.p,{children:"In General: what the different volume types are capable of is highly dependent on both the used backend and the configurations of OpenStack. A few options are worth being at least recommended."}),"\n",(0,n.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,n.jsx)(t.p,{children:"We want to have a discoverable Standard. So there should be no naming conventions as per request by operators."}),"\n",(0,n.jsx)(t.p,{children:"This first decision will have impacts on upstream OpenStack development, as those things, that would be nice to discover, may not be currently discoverable by users or not at all."}),"\n",(0,n.jsx)(t.p,{children:"There are several aspects of volume types, which will be discussed in the following:"}),"\n",(0,n.jsx)(t.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,n.jsx)(t.h4,{id:"encryption",children:"Encryption"}),"\n",(0,n.jsx)(t.p,{children:"Encryption for volumes is an option which has to be configured within the volume type. As an admin it is possible to set encryption-provider, key size, cipher and control location. As an admin it is also currently possible to see these configurations in a volume type with list and show commands. A user should not see these parameters in detail, but a boolean value that describes whether encryption is used or not. Currently, this is not possible in upstream OpenStack."}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Conclusion"}),": This is a solid aspect to be standardized. But it will need work on OpenStack, to have a boolean value presented to the users."]}),"\n",(0,n.jsx)(t.h4,{id:"backend-name",children:"Backend Name"}),"\n",(0,n.jsx)(t.p,{children:"OpenStack Cinder works with a lot of different backends. They all have some kind of special features, which might be attractive for a user. But showing the name of the backend to users is also considered a security risk by Cinder developers. Overall it is always an option to make users aware of special features through the name and description of a volume type and sometimes even through extra_specs."}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Conclusion"}),": This should not be standardized."]}),"\n",(0,n.jsx)(t.h4,{id:"availability-zones",children:"Availability Zones"}),"\n",(0,n.jsx)(t.p,{children:"Availability Zones are used in Nova and Cinder separately to provide an often also physical separation of compute hosts or storage nodes. This leads to two options to consider:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Multiple Volume AZs: This might be used if there are different backends present in one IaaS structure. The different volume types are usually used for the different volume AZs. This makes migration between those AZs only be possible for administrators."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Volume Types that can be attached to multiple Nova Azs: This option can be seen in the extra specs of a volume type also by normal users. Another option is to use backend specific options, as for example with ceph that directly interacts with nova for this. In that case there will not be any visible extra specs for the users."}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"Another question is how many providers use one of these options or both."}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Conclusion"}),": The first part doesn't make much sense to standardize, as migration between the volume types can only be done by admins. However, the second part might be noteable, but due to the variety of configuration options very hard to standardize."]}),"\n",(0,n.jsx)(t.h4,{id:"multiattach",children:"Multiattach"}),"\n",(0,n.jsx)(t.p,{children:"It is possible in a few backends to attach a volume to multiple VMs. This has to be configured in the Volume Type and this information is also accessible for users. Nevertheless, this option also needs a lot of work from users, as those types of volumes have to have a file system, that is capable of multiattach. Many providers don't provide multiattach."}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Conclusion"}),": It might be noteable, that this already is a discoverable option."]}),"\n",(0,n.jsx)(t.h4,{id:"replication",children:"Replication"}),"\n",(0,n.jsx)(t.p,{children:"Replication states, whether there are multiple replicas of a volume. Thus answers the question, whether the data could survive a node outage. Again there are different ways to achieve replicated volumes. It can either be defined in the volume type and is discoverable also by normal users, or it is configured in the backend. The last option is usually used with ceph for example. This makes it hard to discover, whether a volume is replicated or not. Another point is the number of replicas, that exist."}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Conclusion"}),": Replication is a good option to be standardized. Whether this should be done as a boolean option or if the number of replicas is also something users need to know should still be discussed. Nevertheless, due to the different options to configure replication this will be quite complex."]}),"\n",(0,n.jsx)(t.h4,{id:"qos",children:"QoS"}),"\n",(0,n.jsx)(t.p,{children:"Quality of Service parameters can be stated in a volume qos object. These objects can then be associated to a volume type (or directly to a volume as an admin only option). But this is optional and thus even good or very good volume QoS parameters that are acquired through hardware configuration and storage parameters, might go by unmentioned.\nFurthermore, the indirection makes it harder to discover the qos for a volume type. Only admins will see the associated qos ID and will have to take a closer look at the qos after discovering the volume type. PLUS: there can only be one qos association for one volume type. But a qos can be used for multiple volumes."}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Conclusion"}),": The benefit of displaying qos parameters is clear, thus this option should be noted. But are volume qos objects widely used? If not, standardization process would be too much work."]}),"\n",(0,n.jsx)(t.h4,{id:"other-backend-specific-highlights",children:"Other Backend-specific Highlights"}),"\n",(0,n.jsx)(t.p,{children:"While every option above described things, that can at least be partly or for admins only visible in volume types, there are many different configuration options in hardware and backend providers can make use of. It is sadly not possible to get them into the volume type directly, but we recommend, that notable configurations are written into the description of a volume type to achieve transparency for the users."}),"\n",(0,n.jsx)(t.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"How often are the different options used by providers and users respectively? Especially important for qos and replication!"}),"\n",(0,n.jsx)(t.li,{children:"Regarding Replication: Is the number of replicas needed by users and is it okay for providers to provide this information?"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Aspect"}),(0,n.jsx)(t.th,{children:"Standardize?"}),(0,n.jsx)(t.th,{children:"Discoverability"}),(0,n.jsx)(t.th,{children:"other Things"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"encryption"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"Recommended"})}),(0,n.jsx)(t.td,{children:"work needed"}),(0,n.jsx)(t.td,{children:"extra_spec: encrypted=True/False"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Backend name"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"AZs"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"describe as optional and backend-dependend"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"multiattach"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"yes"}),(0,n.jsx)(t.td,{children:"describe as optional"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Replication"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"Recommended"})}),(0,n.jsx)(t.td,{children:"lot of work"}),(0,n.jsx)(t.td,{children:"either get from backend to OS or as extra_spec defined by deployer"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Number of Replicas, etc"}),(0,n.jsx)(t.td,{children:"?"}),(0,n.jsx)(t.td,{children:"lot of work"}),(0,n.jsx)(t.td,{children:"optional, work on it after Replication is standardized"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Volume QoS"}),(0,n.jsx)(t.td,{children:"?"}),(0,n.jsx)(t.td,{children:"admin only"}),(0,n.jsx)(t.td,{children:"needs further discussion, should be at least described as optional"})]})]})]}),"\n",(0,n.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://input.scs.community/JnaY5i70R_yc7JkSNVtlKQ",children:"This is an etherpad"})," with a further look into the Options and a few examples."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>r});var i=s(96540);const n={},o=i.createContext(n);function a(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6a0c14a5.d402eafd.js b/assets/js/6a0c14a5.d402eafd.js new file mode 100644 index 0000000000..60f649e147 --- /dev/null +++ b/assets/js/6a0c14a5.d402eafd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8834],{13357:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/tools/flavor-manager","title":"Flavor Manager","description":"Overview","source":"@site/docs/02-iaas/guides/operations-guide/openstack/tools/flavor-manager.md","sourceDirName":"02-iaas/guides/operations-guide/openstack/tools","slug":"/iaas/guides/operations-guide/openstack/tools/flavor-manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/flavor-manager.md","tags":[],"version":"current","sidebarPosition":51,"frontMatter":{"sidebar_label":"Flavor Manager","sidebar_position":51},"sidebar":"docs","previous":{"title":"Automated updates","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update"},"next":{"title":"Resource Manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager"}}');var r=a(74848),o=a(28453);const i={sidebar_label:"Flavor Manager",sidebar_position:51},t="Flavor Manager",d={},l=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Usage",id:"usage",level:2},{value:"Definitions",id:"definitions",level:2},{value:"Name parser and generator",id:"name-parser-and-generator",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"flavor-manager",children:"Flavor Manager"})}),"\n",(0,r.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,r.jsxs)(n.p,{children:["The OpenStack Flavor Manager manages the creation, modification, and removal of flavors.\nIt operates as a facilitator that orchestrates compute flavors in alignment\nwith the standard ",(0,r.jsx)(n.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS-0100: Flavor Naming"}),"\nby utilizing YAML files provided by the SCS project."]}),"\n",(0,r.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,r.jsxs)(n.p,{children:["The OpenStack Flavor Manager can be used via the OSISM CLI. This is the preferred way to use it.\nNo installation is then required. It is used via ",(0,r.jsx)(n.code,{children:"osism manage flavors"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["For use independent of OSISM install the ",(0,r.jsx)(n.code,{children:"openstack-flavor-manager"})," package with pip. It is likely\nthat additional dependencies such as ",(0,r.jsx)(n.code,{children:"pkg-config"})," or ",(0,r.jsx)(n.code,{children:"libssl-dev"})," must be installed in advance."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ pip install openstack-flavor-manager\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Or clone the repository ",(0,r.jsx)(n.a,{href:"https://github.com/osism/openstack-flavor-manager",children:"osism/openstack-flavor-manager"}),"\nand use the OpenStack Flavor Manager from source with tox."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ tox -- --help\n"})}),"\n",(0,r.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,r.jsxs)(n.p,{children:["There must be a ",(0,r.jsx)(n.code,{children:"clouds.yml"})," and a ",(0,r.jsx)(n.code,{children:"secure.yml"})," file in the directory where the OpenStack Flavor Manager\nwill be executed. When using the OSISM CLI, the files are expected in ",(0,r.jsx)(n.code,{children:"environments/openstack"}),"\nin your configuration repository."]}),"\n",(0,r.jsxs)(n.p,{children:["The cloud profile to be used can be specified via the optional ",(0,r.jsx)(n.code,{children:"--cloud"})," parameter.\nBy default the cloud profile with the name ",(0,r.jsx)(n.code,{children:"admin"})," is used. It must be possible to create and delete\nflavors with the used cloud credentials."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ openstack-flavor-manager --help\n\n Usage: openstack-flavor-manager [OPTIONS]\n\n\u256d\u2500 Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 --name TEXT Name of flavor definitions. [default: scs] \u2502\n\u2502 --debug Enable debug logging. \u2502\n\u2502 --cloud TEXT Cloud name in clouds.yaml. [default: admin] \u2502\n\u2502 --recommended Create recommended flavors. \u2502\n\u2502 --help Show this message and exit. \u2502\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n"})}),"\n",(0,r.jsxs)(n.p,{children:["To create the mandatory flavors by the ",(0,r.jsx)(n.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS-0100: Flavor Naming"}),"\nstandard, you run:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ openstack-flavor-manager\n"})}),"\n",(0,r.jsx)(n.p,{children:"To create the recommended flavors by the SCS Flavor Naming Standard, you run:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ openstack-flavor-manager --recommended\n"})}),"\n",(0,r.jsx)(n.p,{children:"The output should look like this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"2023-09-20 13:03:14 | INFO | Flavor SCS-1V-4 created\n2023-09-20 13:03:14 | INFO | Flavor SCS-2V-8 created\n2023-09-20 13:03:14 | INFO | Flavor SCS-4V-16 created\n2023-09-20 13:03:14 | INFO | Flavor SCS-8V-32 created\n...\n"})}),"\n",(0,r.jsx)(n.p,{children:"All recommended flavors are now be available in your OpenStack environment.\nCheck yourself by running:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ openstack --os-cloud admin flavor list\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ openstack --os-cloud admin flavor show SCS-2V-4-20s\n+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+\n| Field | Value |\n+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+\n| OS-FLV-DISABLED:disabled | False |\n| OS-FLV-EXT-DATA:ephemeral | 0 |\n| access_project_ids | None |\n| description | None |\n| disk | 20 |\n| id | 652e3a6c-330e-4ee3-922b-b49c3c093062 |\n| name | SCS-2V-4-20s |\n| os-flavor-access:is_public | True |\n| properties | hw_rng:allowed='true', scs:cpu-type='shared-core', scs:disk0-type='ssd', scs:name-v1='SCS-2V:4:20s', scs:name-v2='SCS-2V-4-20s' |\n| ram | 4096 |\n| rxtx_factor | 1.0 |\n| swap | 0 |\n| vcpus | 2 |\n+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+\n"})}),"\n",(0,r.jsx)(n.h2,{id:"definitions",children:"Definitions"}),"\n",(0,r.jsxs)(n.p,{children:["There are two flavor definitions available by default. One for\n",(0,r.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/iaas/SCS-Spec.MandatoryFlavors.verbose.yaml",children:"SCS"}),"\nand one for ",(0,r.jsx)(n.a,{href:"https://raw.githubusercontent.com/osism/openstack-flavor-manager/main/flavors.yaml",children:"OSISM"}),".\nEach definition has its own set of mandatory and recommended flavors. The definition of OSISM contains\nall definitions of SCS as well as some others."]}),"\n",(0,r.jsxs)(n.p,{children:["To run the OpenStack Flavor Manager with a specific definition, either ",(0,r.jsx)(n.code,{children:"scs"})," or ",(0,r.jsx)(n.code,{children:"osism"}),",\nuse the optional ",(0,r.jsx)(n.code,{children:"--name"})," parameter. By default the ",(0,r.jsx)(n.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS-0100: Flavor Naming"}),"\nstandard definition will be used."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ openstack-flavor-manager --name osism\n"})}),"\n",(0,r.jsx)(n.h2,{id:"name-parser-and-generator",children:"Name parser and generator"}),"\n",(0,r.jsxs)(n.p,{children:["A generator and parser for flavor names according to the SCS standard is available on\n",(0,r.jsx)(n.a,{href:"https://flavors.scs.community",children:"flavors.scs.community"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The flavor name ",(0,r.jsx)(n.code,{children:"SCS-2V-4-20s"})," is inserted in field ",(0,r.jsx)(n.code,{children:"Flavor name"}),":"]}),"\n",(0,r.jsx)("img",{src:a(54965).A,width:"50%"}),"\n",(0,r.jsxs)(n.p,{children:["The flavor ",(0,r.jsx)(n.code,{children:"SCS-2V-4-20s"})," translated is\n",(0,r.jsx)(n.code,{children:"2 generic x86-64 vCPUs with 4.0 GiB RAM and SSD 20GB root volume"}),":"]}),"\n",(0,r.jsx)("img",{src:a(69214).A,width:"50%"})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},54965:(e,n,a)=>{a.d(n,{A:()=>s});const s=a.p+"assets/images/flavors-1-bd8d085759b264b3e58020d1390803fd.png"},69214:(e,n,a)=>{a.d(n,{A:()=>s});const s=a.p+"assets/images/flavors-2-d9a87ab2a63ed62ace4303facc069b8b.png"},28453:(e,n,a)=>{a.d(n,{R:()=>i,x:()=>t});var s=a(96540);const r={},o=s.createContext(r);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6a49ee0a.b2514060.js b/assets/js/6a49ee0a.b2514060.js new file mode 100644 index 0000000000..6ceef281ec --- /dev/null +++ b/assets/js/6a49ee0a.b2514060.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[85066],{77861:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"operating-scs/components/status-page-deployment/docs/quickstart","title":"Quickstart","description":"To get a quickstart, please refer to the KinD or k3s guide.","source":"@site/docs/04-operating-scs/components/status-page-deployment/docs/quickstart.md","sourceDirName":"04-operating-scs/components/status-page-deployment/docs","slug":"/operating-scs/components/status-page-deployment/docs/quickstart","permalink":"/docs/operating-scs/components/status-page-deployment/docs/quickstart","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-deployment/docs/quickstart.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Requirements","permalink":"/docs/operating-scs/components/status-page-deployment/docs/requirements"},"next":{"title":"Configuration","permalink":"/docs/category/configuration"}}');var o=s(74848),c=s(28453);const r={},a="Quickstart",i={},d=[];function p(e){const t={code:"code",h1:"h1",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,o.jsxs)(t.p,{children:["To get a quickstart, please refer to the ",(0,o.jsx)(t.code,{children:"KinD"})," or ",(0,o.jsx)(t.code,{children:"k3s"})," guide."]}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.code,{children:"KinD"})," is recommended as a fast and easy way to get a local instance running in minutes."]})]})}function u(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>a});var n=s(96540);const o={},c=n.createContext(o);function r(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6ad9ab45.44339de7.js b/assets/js/6ad9ab45.44339de7.js new file mode 100644 index 0000000000..da1a308262 --- /dev/null +++ b/assets/js/6ad9ab45.44339de7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[58561],{94252:(s,e,t)=>{t.r(e),t.d(e,{assets:()=>o,contentTitle:()=>i,default:()=>p,frontMatter:()=>d,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"iaas/scs-0103","title":"scs-0103: SCS Standard Flavors and Properties","description":"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack","source":"@site/standards/iaas/scs-0103.md","sourceDirName":"iaas","slug":"/iaas/scs-0103","permalink":"/standards/iaas/scs-0103","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0102-w1-image-metadata-implementation-testing"},"next":{"title":"V1","permalink":"/standards/scs-0103-v1-standard-flavors"}}');var a=t(74848),r=t(28453);const d={},i="scs-0103: SCS Standard Flavors and Properties",o={},c=[];function l(s){const e={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...s.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.header,{children:(0,a.jsx)(e.h1,{id:"scs-0103-scs-standard-flavors-and-properties",children:"scs-0103: SCS Standard Flavors and Properties"})}),"\n",(0,a.jsxs)(e.p,{children:["The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack\nenvironments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific\nconfigurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs",":name-vN",", scs",":cpu-type",",\nand scs",":diskN-type"," to detail the flavor's specifications. This standard facilitates guaranteed availability and\nconsistency of flavors, simplifying the deployment process for DevOps teams."]}),"\n",(0,a.jsxs)(e.table,{children:[(0,a.jsx)(e.thead,{children:(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.th,{children:"Version"}),(0,a.jsx)(e.th,{children:"Type"}),(0,a.jsx)(e.th,{children:"State"}),(0,a.jsx)(e.th,{children:"stabilized"}),(0,a.jsx)(e.th,{children:"deprecated"})]})}),(0,a.jsx)(e.tbody,{children:(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.a,{href:"/standards/scs-0103-v1-standard-flavors",children:"scs-0103-v1"})}),(0,a.jsx)(e.td,{children:"Standard"}),(0,a.jsx)(e.td,{children:"Stable"}),(0,a.jsx)(e.td,{children:"2024-02-08"}),(0,a.jsx)(e.td,{children:"-"})]})})]})]})}function p(s={}){const{wrapper:e}={...(0,r.R)(),...s.components};return e?(0,a.jsx)(e,{...s,children:(0,a.jsx)(l,{...s})}):l(s)}},28453:(s,e,t)=>{t.d(e,{R:()=>d,x:()=>i});var n=t(96540);const a={},r=n.createContext(a);function d(s){const e=n.useContext(r);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function i(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(a):s.components||a:d(s.components),n.createElement(r.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/6bcd11f8.2746e1bc.js b/assets/js/6bcd11f8.2746e1bc.js new file mode 100644 index 0000000000..33a3db896a --- /dev/null +++ b/assets/js/6bcd11f8.2746e1bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[68502],{55850:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>t,toc:()=>r});const t=JSON.parse('{"id":"iaas/guides/concept-guide/components/keycloak","title":"Keycloak","description":"Lifecycle Management of Keycloak in OSISM","source":"@site/docs/02-iaas/guides/concept-guide/components/keycloak.md","sourceDirName":"02-iaas/guides/concept-guide/components","slug":"/iaas/guides/concept-guide/components/keycloak","permalink":"/docs/iaas/guides/concept-guide/components/keycloak","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/keycloak.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"K3S","permalink":"/docs/iaas/guides/concept-guide/components/k3s"},"next":{"title":"Netdata","permalink":"/docs/iaas/guides/concept-guide/components/netdata"}}');var c=o(74848),s=o(28453);const a={},i="Keycloak",d={},r=[{value:"Lifecycle Management of Keycloak in OSISM",id:"lifecycle-management-of-keycloak-in-osism",level:2}];function l(e){const n={h1:"h1",h2:"h2",header:"header",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"keycloak",children:"Keycloak"})}),"\n",(0,c.jsx)(n.h2,{id:"lifecycle-management-of-keycloak-in-osism",children:"Lifecycle Management of Keycloak in OSISM"})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>a,x:()=>i});var t=o(96540);const c={},s=t.createContext(c);function a(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6c33bb99.9dde0a6a.js b/assets/js/6c33bb99.9dde0a6a.js new file mode 100644 index 0000000000..35f74e9e06 --- /dev/null +++ b/assets/js/6c33bb99.9dde0a6a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[44810],{77488:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>t});const d=JSON.parse('{"id":"iaas/guides/configuration-guide/ceph","title":"Ceph","description":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/","source":"@site/docs/02-iaas/guides/configuration-guide/ceph.md","sourceDirName":"02-iaas/guides/configuration-guide","slug":"/iaas/guides/configuration-guide/ceph","permalink":"/docs/iaas/guides/configuration-guide/ceph","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/ceph.md","tags":[],"version":"current","sidebarPosition":30,"frontMatter":{"sidebar_label":"Ceph","sidebar_position":30},"sidebar":"docs","previous":{"title":"Loadbalancer","permalink":"/docs/iaas/guides/configuration-guide/loadbalancer"},"next":{"title":"OpenStack","permalink":"/docs/iaas/guides/configuration-guide/openstack/"}}');var i=s(74848),c=s(28453);const a={sidebar_label:"Ceph",sidebar_position:30},r="Ceph",o={},t=[{value:"Unique Identifier",id:"unique-identifier",level:2},{value:"Client",id:"client",level:2},{value:"Swappiness",id:"swappiness",level:2},{value:"RGW service",id:"rgw-service",level:2},{value:"Extra pools",id:"extra-pools",level:2},{value:"Extra keys",id:"extra-keys",level:2},{value:"OSD devices",id:"osd-devices",level:2},{value:"Full examples",id:"full-examples",level:3},{value:"Use of dedicated DB devices",id:"use-of-dedicated-db-devices",level:4},{value:"Use of partitions",id:"use-of-partitions",level:4},{value:"Add a new osd",id:"add-a-new-osd",level:3},{value:"Dashboard",id:"dashboard",level:2},{value:"Configuring the openstack loadbalancer to expose the ceph dashboard",id:"configuring-the-openstack-loadbalancer-to-expose-the-ceph-dashboard",level:3},{value:"Second Ceph cluster",id:"second-ceph-cluster",level:2},{value:"Resource limits",id:"resource-limits",level:2},{value:"CPU Pinning",id:"cpu-pinning",level:2},{value:"Use of RBDs for nodes",id:"use-of-rbds-for-nodes",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,c.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"ceph",children:"Ceph"})}),"\n",(0,i.jsxs)(n.p,{children:["The official Ceph documentation is located on ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/configuration/",children:"https://docs.ceph.com/en/latest/rados/configuration/"})]}),"\n",(0,i.jsxs)(n.p,{children:["It is ",(0,i.jsx)(n.strong,{children:"strongly advised"})," to use the documentation for the version being used."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Pacific - ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/pacific/rados/configuration/",children:"https://docs.ceph.com/en/pacific/rados/configuration/"})]}),"\n",(0,i.jsxs)(n.li,{children:["Quincy - ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/rados/configuration/",children:"https://docs.ceph.com/en/quincy/rados/configuration/"})]}),"\n",(0,i.jsxs)(n.li,{children:["Reef - ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/reef/rados/configuration/",children:"https://docs.ceph.com/en/reef/rados/configuration/"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"unique-identifier",children:"Unique Identifier"}),"\n",(0,i.jsxs)(n.p,{children:["The File System ID is a unique identifier for the cluster.\nThe identifier is set via the parameter ",(0,i.jsx)(n.code,{children:"fsid"})," in ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"}),"\nand must be unique. It can be generated with ",(0,i.jsx)(n.code,{children:"uuidgen"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:"fsid: c2120a4a-669c-4769-a32c-b7e9d7b848f4\n"})}),"\n",(0,i.jsx)(n.h2,{id:"client",children:"Client"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"client.admin"})," keyring is placed in the file ",(0,i.jsx)(n.code,{children:"environments/infrastructure/files/ceph/ceph.client.admin.keyring"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"swappiness",children:"Swappiness"}),"\n",(0,i.jsxs)(n.p,{children:["The swappiness is set via the ",(0,i.jsx)(n.code,{children:"os_tuning_params"})," dictionary. The dictionary can\nonly be completely overwritten via an entry in the file ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["By default, the dictionary looks like this. If the swappiness of ",(0,i.jsx)(n.code,{children:"10"})," is to be used, it is not\nnecessary to add the ",(0,i.jsx)(n.code,{children:"os_tuning_params"})," dictionary to the configuration repository. This is only\nnecessary if the swappiness is to be customised."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:'os_tuning_params:\n - { name: fs.file-max, value: 26234859 }\n - { name: vm.zone_reclaim_mode, value: 0 }\n - { name: vm.swappiness, value: 10 }\n - { name: vm.min_free_kbytes, value: "{{ vm_min_free_kbytes }}" }\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The sysctl paremeters are written to the file ",(0,i.jsx)(n.code,{children:"/etc/sysctl.d/ceph-tuning.conf"}),"\non the storage nodes."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# cat /etc/sysctl.d/ceph-tuning.conf\nfs.aio-max-nr=1048576\nfs.file-max=26234859\nvm.zone_reclaim_mode=0\nvm.swappiness=10\nvm.min_free_kbytes=4194303\n"})}),"\n",(0,i.jsx)(n.h2,{id:"rgw-service",children:"RGW service"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add following configuration in ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:'ceph_conf_overrides:\n "client.rgw.{{ hostvars[inventory_hostname][\'ansible_hostname\'] }}.rgw0":\n "rgw content length compat": "true"\n "rgw enable apis": "swift, s3, admin"\n "rgw keystone accepted roles": "member, admin"\n "rgw keystone accepted admin roles": "admin"\n "rgw keystone admin domain": "default"\n "rgw keystone admin password": "{{ ceph_rgw_keystone_password }}"\n "rgw keystone admin project": "service"\n "rgw keystone admin tenant": "service"\n "rgw keystone admin user": "ceph_rgw"\n "rgw keystone api version": "3"\n "rgw keystone url": "https://api-int.testbed.osism.xyz:5000"\n "rgw keystone verify ssl": "false"\n "rgw keystone implicit tenants": "true"\n "rgw s3 auth use keystone": "true"\n "rgw swift account in url": "true"\n "rgw swift versioning enabled": "true"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"ceph_conf_overrides"})," parameter already exists in ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"}),",\nexpand it and do not overwrite it."]}),"\n",(0,i.jsx)(n.p,{children:"If self-signed SSL certificates are used, two additional parameters must be set."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:' "rgw keystone verify ssl": "false"\n "rgw verify ssl": "false"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["For all possible configuration parameters visit the\n",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/radosgw/config-ref/",children:"Ceph configuration reference"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add the ",(0,i.jsx)(n.code,{children:"ceph_rgw_keystone_password"})," from ",(0,i.jsx)(n.code,{children:"environments/kolla/secrets.yml"})," to\n",(0,i.jsx)(n.code,{children:"environments/ceph/secrets.yml"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add following configuration in ",(0,i.jsx)(n.code,{children:"environments/kolla/configuration.yml"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:"enable_ceph_rgw: true\nenable_ceph_rgw_keystone: true\n\nceph_rgw_swift_compatibility: false\nceph_rgw_swift_account_in_url: true\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the nodes on which the RGW service is to be deployed, ",(0,i.jsx)(n.code,{children:"radowsgw_interface"})," ",(0,i.jsx)(n.strong,{children:"or"}),"\n",(0,i.jsx)(n.code,{children:"radosgw_address"})," must be set in the host vars for the nodes in the inventory.\nIf ",(0,i.jsx)(n.code,{children:"radowsgw_interface"})," is used, the first IPv4 address on this interface is used."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:"title=inventory/host_vars/testbed-node-0.testbed.osism.xyz/vars.yml",children:"##########################################################\n# ceph\n\nradosgw_address: 192.168.16.10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The nodes on which the RGW service is to be deployed can be defined in inventory group\n",(0,i.jsx)(n.code,{children:"ceph-rgw"}),". By default, the RGW services are deployed on the Ceph control nodes.."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"[ceph-rgw:children]\nceph-control\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"extra-pools",children:"Extra pools"}),"\n",(0,i.jsxs)(n.p,{children:["Extra pools can be defined via the ",(0,i.jsx)(n.code,{children:"openstack_pools_extra"})," parameter."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:'openstack_extra001_pool:\n name: extra001\n pg_num: "{{ openstack_pool_default_pg_num }}"\n pgp_num: "{{ openstack_pool_default_pg_num }}"\n rule_name: "replicated_rule"\n type: 1\n erasure_profile: ""\n expected_num_objects: ""\n application: "rbd"\n size: "{{ openstack_pool_default_size }}"\n min_size: "{{ openstack_pool_default_min_size }}"\n pg_autoscale_mode: false\n\nopenstack_pools_extra:\n - "{{ openstack_extra001_pool }}"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["If more than one Ceph cluster is managed with one manager, do not place the\nparameters in ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"})," but in a corresponding file."]}),"\n",(0,i.jsx)(n.p,{children:"The defaults for these parameters are defined in the osism/defaults repository\nas follows:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Default value"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"openstack_pool_default_min_size"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"openstack_pool_default_pg_num"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"64"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"openstack_pool_default_size"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"3"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["The extra pools can then be created by calling ",(0,i.jsx)(n.code,{children:"osism apply ceph-pools"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"extra-keys",children:"Extra keys"}),"\n",(0,i.jsxs)(n.p,{children:["Extra keys can be defined via the ",(0,i.jsx)(n.code,{children:"openstack_keys_extra"})," parameter."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:'openstack_extra001_key:\n - name: client.extra001\n caps:\n mon: "profile rbd"\n osd: "profile rbd pool={{ openstack_extra001_pool.name }}"\n mode: "0600"\n\nopenstack_keys_extra:\n - "{{ openstack_extra001_key }}"\n'})}),"\n",(0,i.jsx)(n.p,{children:"The key is also added in the manager environment to copy it to the correct location."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/configuration.yml"',children:'ceph_custom_keys:\n - src: ceph.client.extra001.keyring\n dest: "{{ configuration_directory }}/environments/infrastructure/files/ceph/ceph.client.extra001.keyring"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The extra keys can then be created by calling ",(0,i.jsx)(n.code,{children:"osism apply ceph-pools"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The extra keys can then be fetched and copied by calling ",(0,i.jsx)(n.code,{children:"osism apply ceph-copy-keys"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"osd-devices",children:"OSD devices"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["For each Ceph storage node edit the file ",(0,i.jsx)(n.code,{children:"inventory/host_vars/<nodename>.yml"}),"\nadd a configuration like the following to it. Ensure that no ",(0,i.jsx)(n.code,{children:"devices"})," parameter\nis present in the file."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Parameters"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["With the optional parameter ",(0,i.jsx)(n.code,{children:"ceph_osd_db_wal_devices_buffer_space_percent"})," it is possible to\nset the percentage of VGs to leave free. The parameter is not set by default. Can be helpful\nfor SSD performance of some older SSD models or to extend lifetime of SSDs in general."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_db_wal_devices_buffer_space_percent: 10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["It is possible to configure the devices to be used with the parameters ",(0,i.jsx)(n.code,{children:"ceph_osd_devices"}),",\n",(0,i.jsx)(n.code,{children:"ceph_db_devices"}),", ",(0,i.jsx)(n.code,{children:"ceph_wal_devices"}),", and ",(0,i.jsx)(n.code,{children:"ceph_db_wal_devices"}),". This is described below."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["It is always possible to use device names such as ",(0,i.jsx)(n.code,{children:"sda"})," or device IDs such as\n",(0,i.jsx)(n.code,{children:"disk/by-id/wwn-<something>"})," or ",(0,i.jsx)(n.code,{children:"disk/by-id/nvme-eui.<something>"}),". ",(0,i.jsx)(n.code,{children:"/dev/"})," is not\nprefixed and is added automatically."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"db_size"})," parameter is optional and defaults to ",(0,i.jsx)(n.code,{children:"(VG size - buffer space (if enabled)) / num_osds"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"wal_size"})," parameter is optional and defaults to ",(0,i.jsx)(n.code,{children:"2 GB"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"num_osds"})," parameter specifies the maximum number of OSDs that can be assigned to a WAL device or DB device."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The optional parameter ",(0,i.jsx)(n.code,{children:"wal_pv"})," can be used to set the device that is to be used as the WAL device."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The optional parameter ",(0,i.jsx)(n.code,{children:"db_pv"})," can be used to set the device that is to be used as the DB device."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OSD only"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sda"})," device will be used as an OSD device without WAL and DB device."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OSD + DB device"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"nvme0n1"})," device will be used as an DB device. It is possible to use this DB device for up to 6 OSDs. Each\nOSD is provided with 30 GB."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_db_devices:\n nvme0n1:\n num_osds: 6\n db_size: 30 GB\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sda"})," device will be used as an OSD device with ",(0,i.jsx)(n.code,{children:"nvme0n1"})," as DB device."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n db_pv: nvme0n1\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OSD + WAL device"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"nvme0n1"})," device will be used as an WAL device. It is possible to use this WAL device for up to 6 OSDs. Each\nOSD is provided with 2 GB."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_wal_devices:\n nvme0n1:\n num_osds: 6\n wal_size: 2 GB\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sda"})," device will be used as an OSD device with ",(0,i.jsx)(n.code,{children:"nvme0n1"})," as WAL device."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n wal_pv: nvme0n1\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OSD + DB device + WAL device (same device for DB + WAL)"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"nvme0n1"})," device will be used as an DB device and a WAL device. It is possible to use those devices for up\nto 6 OSDs."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_db_wal_devices:\n nvme0n1:\n num_osds: 6\n db_size: 30 GB\n wal_size: 2 GB\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sda"})," device will be used as an OSD device with ",(0,i.jsx)(n.code,{children:"nvme0n1"})," as DB device and ",(0,i.jsx)(n.code,{children:"nvme0n1"})," as WAL device."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n db_pv: nvme0n1\n wal_pv: nvme0n1\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OSD + DB device + WAL device (different device for DB + WAL)"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"nvme0n1"})," device will be used as an DB device. It is possible to use this DB device for up to 6 OSDs. Each\nOSD is provided with 30 GB."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_db_devices:\n nvme0n1:\n num_osds: 6\n db_size: 30 GB\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"nvme1n1"})," device will be used as an WAL device. It is possible to use this WAL device for up to 6 OSDs. Each\nOSD is provided with 2 GB."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_wal_devices:\n nvme1n1:\n num_osds: 6\n wal_size: 2 GB\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sda"})," device will be used as an OSD device with ",(0,i.jsx)(n.code,{children:"nvme0n1"})," as DB device and ",(0,i.jsx)(n.code,{children:"nvme1n1"})," as WAL device."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n db_pv: nvme0n1\n wal_pv: nvme1n1\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Push the configuration to your configuration repository and after that do the following"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply configuration\n$ osism reconciler sync\n$ osism apply facts\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"After the configuration has been pulled and facts updated,\nyou can run the LVM configuration playbook:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply ceph-configure-lvm-volumes\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This will generate a new configuration file for each node in ",(0,i.jsx)(n.code,{children:"/tmp"}),"\non the first manager node named ",(0,i.jsx)(n.code,{children:"<nodename>-ceph-lvm-configuration.yml"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Take the generated configuration file from ",(0,i.jsx)(n.code,{children:"/tmp"})," and ",(0,i.jsx)(n.strong,{children:"replace the previously\nconfiguration"})," for each node."]}),"\n",(0,i.jsxs)(n.p,{children:["In this example, the following content was in the host vars file before\n",(0,i.jsx)(n.code,{children:"osism apply ceph-configure-lvm-volumes"})," was called."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sdb:\n sdc:\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The following content has now been generated in the file in the ",(0,i.jsx)(n.code,{children:"/tmp"})," directory by running\n",(0,i.jsx)(n.code,{children:"osism apply ceph-configure-lvm-volumes"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sdb:\n osd_lvm_uuid: 196aad32-7cc4-5350-8a45-1b03f50fc9bb\n sdc:\n osd_lvm_uuid: c6df96be-1264-5815-9cb2-da5eb453a6de\nlvm_volumes:\n- data: osd-block-196aad32-7cc4-5350-8a45-1b03f50fc9bb\n data_vg: ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb\n- data: osd-block-c6df96be-1264-5815-9cb2-da5eb453a6de\n data_vg: ceph-c6df96be-1264-5815-9cb2-da5eb453a6de\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This content from the file in the ",(0,i.jsx)(n.code,{children:"/tmp"})," directory is added in the host vars file.\nThe previous ",(0,i.jsx)(n.code,{children:"ceph_osd_devices"})," is replaced with the new content."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Push the updated configuration ",(0,i.jsx)(n.strong,{children:"again"})," to your configuration repository and re-run:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply configuration\n$ osism reconciler sync\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Finally create the LVM devices."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply ceph-create-lvm-devices\n"})}),"\n",(0,i.jsx)(n.p,{children:"These PVs, VGs and LVs are created using the example from step 4."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ sudo pvs\n PV VG Fmt Attr PSize PFree\n /dev/sdb ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb lvm2 a-- <20.00g 0\n /dev/sdc ceph-c6df96be-1264-5815-9cb2-da5eb453a6de lvm2 a-- <20.00g 0\n\n$ sudo vgs\n VG #PV #LV #SN Attr VSize VFree\n ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb 1 1 0 wz--n- <20.00g 0\n ceph-c6df96be-1264-5815-9cb2-da5eb453a6de 1 1 0 wz--n- <20.00g 0\n\n$ sudo lvs\n LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert\n osd-block-196aad32-7cc4-5350-8a45-1b03f50fc9bb ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb -wi-a----- <20.00g\n osd-block-c6df96be-1264-5815-9cb2-da5eb453a6de ceph-c6df96be-1264-5815-9cb2-da5eb453a6de -wi-a----- <20.00g\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Everything is now ready for the deployment of the OSDs.\nDetails on deploying Ceph in the ",(0,i.jsx)(n.a,{href:"../deploy-guide/services/ceph",children:"Ceph deploy guide"}),"."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"full-examples",children:"Full examples"}),"\n",(0,i.jsx)(n.h4,{id:"use-of-dedicated-db-devices",children:"Use of dedicated DB devices"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"ceph_osd_devices"})," and ",(0,i.jsx)(n.code,{children:"ceph_db_devices"})," parameters with the following content are initially added\nin the host vars of the node. Devices ",(0,i.jsx)(n.code,{children:"/dev/sda"})," and ",(0,i.jsx)(n.code,{children:"/dev/sdb"})," are used as OSD devices. The device ",(0,i.jsx)(n.code,{children:"/dev/sdd"}),"\nis used as a DB device for up to 2 OSDs. For each OSD that uses ",(0,i.jsx)(n.code,{children:"/dev/sdd"})," as DB device, an LV volume of\n(in this case) 30 GByte is created. Please note that at least 30 GByte must be used for a DB device in production."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_db_devices:\n sdd:\n num_osds: 2\n db_size: 30 GB\n\nceph_osd_devices:\n sdb:\n db_pv: sdd\n sdc:\n db_pv: sdd\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then generate the required LVM2 device configuration with the ",(0,i.jsx)(n.code,{children:"ceph-configure-lvm-volumes"})," play."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply facts\nosism reconciler sync\nosism apply ceph-configure-lvm-volumes\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Check the ",(0,i.jsx)(n.code,{children:"/tmp"})," directory on the manager node for files like ",(0,i.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz-ceph-lvm-configuration.yml"}),".\nAdd this content to the host vars of the correspondingnode. The existing ",(0,i.jsx)(n.code,{children:"ceph_osd_devices"})," parameter is replaced."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"---\n#\n# This is Ceph LVM configuration for testbed-node-0.testbed.osism.xyz\n# generated by ceph-configure-lvm-volumes playbook.\n#\nceph_db_devices:\n sdd:\n db_size: 30 GB\n num_osds: 2\n vg_name: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb\nceph_osd_devices:\n sdb:\n db_pv: sdd\n osd_lvm_uuid: 75960289-2e0e-525d-8bb5-dd8552531ef5\n sdc:\n db_pv: sdd\n osd_lvm_uuid: ce2c2cb6-f911-52dd-b57f-4476bf7afe9f\nlvm_volumes:\n- data: osd-block-75960289-2e0e-525d-8bb5-dd8552531ef5\n data_vg: ceph-75960289-2e0e-525d-8bb5-dd8552531ef5\n db: osd-db-75960289-2e0e-525d-8bb5-dd8552531ef5\n db_vg: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb\n- data: osd-block-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f\n data_vg: ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f\n db: osd-db-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f\n db_vg: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Finally, create the necessary PVs, VGs and LVs. The parameter ",(0,i.jsx)(n.code,{children:"-e ignore_db_too_small=true"})," is only set\nhere in the example because we use less than 30 GByte for the size of the DB LV."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism reconciler sync\nosism apply ceph-create-lvm-devices -e ignore_db_too_small=true\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can check the PVs, VGs, and LVs on the node."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ sudo pvs\n PV VG Fmt Attr PSize PFree\n /dev/sdb ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 lvm2 a-- <20.00g 0\n /dev/sdc ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f lvm2 a-- <20.00g 0\n /dev/sdd ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb lvm2 a-- <20.00g <10.00g\n\n$ sudo vgs\n VG #PV #LV #SN Attr VSize VFree\n ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 1 1 0 wz--n- <20.00g 0\n ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f 1 1 0 wz--n- <20.00g 0\n ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb 1 2 0 wz--n- <20.00g <10.00g\n\n$ sudo lvs\n LV VG Attr LSize [...]\n osd-block-75960289-2e0e-525d-8bb5-dd8552531ef5 ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 -wi-a----- <20.00g\n osd-block-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f -wi-a----- <20.00g\n osd-db-75960289-2e0e-525d-8bb5-dd8552531ef5 ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb -wi-a----- 5.00g\n osd-db-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb -wi-a----- 5.00g\n"})}),"\n",(0,i.jsx)(n.h4,{id:"use-of-partitions",children:"Use of partitions"}),"\n",(0,i.jsx)(n.p,{children:"The use of partitions presented in this example is not recommended for use in production but only for POCs."}),"\n",(0,i.jsxs)(n.p,{children:["First create partitions that should be used for Ceph. In this example we use a block device ",(0,i.jsx)(n.code,{children:"/dev/sdb"}),"\nwith four partitions that will be used for Ceph OSDs."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ sudo fdisk -l /dev/sdb\nDisk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors\nDisk model: QEMU HARDDISK\nUnits: sectors of 1 * 512 = 512 bytes\nSector size (logical/physical): 512 bytes / 512 bytes\nI/O size (minimum/optimal): 512 bytes / 512 bytes\nDisklabel type: gpt\nDisk identifier: 709B8C6C-51E1-4644-9ED4-0604607FCCEE\n\nDevice Start End Sectors Size Type\n/dev/sdb1 2048 10487807 10485760 5G Linux filesystem\n/dev/sdb2 10487808 20973567 10485760 5G Linux filesystem\n/dev/sdb3 20973568 31459327 10485760 5G Linux filesystem\n/dev/sdb4 31459328 41943006 10483679 5G Linux filesystem\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"ceph_osd_devices"})," parameter with the following content is initially added in the host vars of the node.\nThe partitions ",(0,i.jsx)(n.code,{children:"/dev/sda1"}),", ",(0,i.jsx)(n.code,{children:"/dev/sdb1"}),", ",(0,i.jsx)(n.code,{children:"/dev/sdc1"})," and ",(0,i.jsx)(n.code,{children:"/dev/sdd1"}),", are to be used as OSD."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sdb1:\n sdb2:\n sdb3:\n sdb4:\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then generate the required LVM2 device configuration with the ",(0,i.jsx)(n.code,{children:"ceph-configure-lvm-volumes"})," play."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply facts\nosism reconciler sync\nosism apply ceph-configure-lvm-volumes\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Check the ",(0,i.jsx)(n.code,{children:"/tmp"})," directory on the manager node for files like ",(0,i.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz-ceph-lvm-configuration.yml"}),".\nAdd this content to the host vars of the correspondingnode. The existing ",(0,i.jsx)(n.code,{children:"ceph_osd_devices"})," parameter is replaced."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"---\n#\n# This is Ceph LVM configuration for testbed-node-0.testbed.osism.xyz\n# generated by ceph-configure-lvm-volumes playbook.\n#\nceph_osd_devices:\n sdb1:\n osd_lvm_uuid: 9e8799ae-c716-5212-8833-49f153ffbcef\n sdb2:\n osd_lvm_uuid: 8518d3a2-3194-5764-b55a-c51222b9b576\n sdb3:\n osd_lvm_uuid: a0da232a-e5b8-5823-8c42-8fb231442edc\n sdb4:\n osd_lvm_uuid: 56f7b5bc-82b0-5626-90a5-adf6078ceba6\nlvm_volumes:\n- data: osd-block-9e8799ae-c716-5212-8833-49f153ffbcef\n data_vg: ceph-9e8799ae-c716-5212-8833-49f153ffbcef\n- data: osd-block-8518d3a2-3194-5764-b55a-c51222b9b576\n data_vg: ceph-8518d3a2-3194-5764-b55a-c51222b9b576\n- data: osd-block-a0da232a-e5b8-5823-8c42-8fb231442edc\n data_vg: ceph-a0da232a-e5b8-5823-8c42-8fb231442edc\n- data: osd-block-56f7b5bc-82b0-5626-90a5-adf6078ceba6\n data_vg: ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6\n"})}),"\n",(0,i.jsx)(n.p,{children:"Finally, create the necessary PVs, VGs and LVs."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism reconciler sync\nosism apply ceph-create-lvm-devices\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can check the PVs, VGs, and LVs on the node."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ sudo pvs\n PV VG Fmt Attr PSize PFree\n /dev/sdb1 ceph-9e8799ae-c716-5212-8833-49f153ffbcef lvm2 a-- <5.00g 0\n /dev/sdb2 ceph-8518d3a2-3194-5764-b55a-c51222b9b576 lvm2 a-- <5.00g 0\n /dev/sdb3 ceph-a0da232a-e5b8-5823-8c42-8fb231442edc lvm2 a-- <5.00g 0\n /dev/sdb4 ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 lvm2 a-- <5.00g 0\n\n$ sudo vgs\n VG #PV #LV #SN Attr VSize VFree\n ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 1 1 0 wz--n- <5.00g 0\n ceph-8518d3a2-3194-5764-b55a-c51222b9b576 1 1 0 wz--n- <5.00g 0\n ceph-9e8799ae-c716-5212-8833-49f153ffbcef 1 1 0 wz--n- <5.00g 0\n ceph-a0da232a-e5b8-5823-8c42-8fb231442edc 1 1 0 wz--n- <5.00g 0\n\n$ sudo lvs\n LV VG Attr LSize [...]\n osd-block-56f7b5bc-82b0-5626-90a5-adf6078ceba6 ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 -wi-a----- <5.00g\n osd-block-8518d3a2-3194-5764-b55a-c51222b9b576 ceph-8518d3a2-3194-5764-b55a-c51222b9b576 -wi-a----- <5.00g\n osd-block-9e8799ae-c716-5212-8833-49f153ffbcef ceph-9e8799ae-c716-5212-8833-49f153ffbcef -wi-a----- <5.00g\n osd-block-a0da232a-e5b8-5823-8c42-8fb231442edc ceph-a0da232a-e5b8-5823-8c42-8fb231442edc -wi-a----- <5.00g\n"})}),"\n",(0,i.jsx)(n.h3,{id:"add-a-new-osd",children:"Add a new osd"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["There is the following existing configuration in ",(0,i.jsx)(n.code,{children:"inventory/host_vars/<nodename>.yml"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n osd_lvm_uuid: 71e54cfb-65e5-5109-8f09-2be6b661f39c\n sdb:\n osd_lvm_uuid: acb56e1f-0700-587f-95d4-fbe905491fea\nlvm_volumes:\n- data: osd-block-71e54cfb-65e5-5109-8f09-2be6b661f39c\n data_vg: ceph-71e54cfb-65e5-5109-8f09-2be6b661f39c\n- data: osd-block-acb56e1f-0700-587f-95d4-fbe905491fea\n data_vg: ceph-acb56e1f-0700-587f-95d4-fbe905491fea\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The block device ",(0,i.jsx)(n.code,{children:"sdc"})," should be added as new OSD on ",(0,i.jsx)(n.code,{children:"nodename"}),". Edit the existing\nconfiguration in ",(0,i.jsx)(n.code,{children:"inventory/host_vars/<nodename>.yml"})," and add ",(0,i.jsx)(n.code,{children:"sdc"})," to the list\n",(0,i.jsx)(n.code,{children:"ceph_osd_devices"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n osd_lvm_uuid: 71e54cfb-65e5-5109-8f09-2be6b661f39c\n sdb:\n osd_lvm_uuid: acb56e1f-0700-587f-95d4-fbe905491fea\n sdc:\nlvm_volumes:\n- data: osd-block-71e54cfb-65e5-5109-8f09-2be6b661f39c\n data_vg: ceph-71e54cfb-65e5-5109-8f09-2be6b661f39c\n- data: osd-block-acb56e1f-0700-587f-95d4-fbe905491fea\n data_vg: ceph-acb56e1f-0700-587f-95d4-fbe905491fea\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Commit changes in the configuration repository, sync the configuration repository on\nthe manager and reconcile the inventory with ",(0,i.jsx)(n.code,{children:"osism reconciler sync"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Regenerate the configuration with ",(0,i.jsx)(n.code,{children:"osism apply ceph-configure-lvm-volumes -l <nodename>"}),".\nSynchronise the contents of ",(0,i.jsx)(n.code,{children:"/tmp/<nodename>-ceph-lvm-configuration.yml"})," with those in\n",(0,i.jsx)(n.code,{children:"inventory/host_vars/<nodename>.yml"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n osd_lvm_uuid: 71e54cfb-65e5-5109-8f09-2be6b661f39c\n sdb:\n osd_lvm_uuid: acb56e1f-0700-587f-95d4-fbe905491fea\n sdc:\n osd_lvm_uuid: ad1a16cd-b35e-58d1-8e40-80a14597f583\nlvm_volumes:\n- data: osd-block-71e54cfb-65e5-5109-8f09-2be6b661f39c\n data_vg: ceph-71e54cfb-65e5-5109-8f09-2be6b661f39c\n- data: osd-block-acb56e1f-0700-587f-95d4-fbe905491fea\n data_vg: ceph-acb56e1f-0700-587f-95d4-fbe905491fea\n- data: osd-block-ad1a16cd-b35e-58d1-8e40-80a14597f583\n data_vg: ceph-ad1a16cd-b35e-58d1-8e40-80a14597f583\n"})}),"\n",(0,i.jsx)(n.p,{children:"Added in this case:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"[...]\n sdc:\n osd_lvm_uuid: ad1a16cd-b35e-58d1-8e40-80a14597f583\n[...]\n- data: osd-block-ad1a16cd-b35e-58d1-8e40-80a14597f583\n data_vg: ceph-ad1a16cd-b35e-58d1-8e40-80a14597f583\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Commit changes in the configuration repository, sync the configuration repository on\nthe manager and reconcile the inventory with ",(0,i.jsx)(n.code,{children:"osism reconciler sync"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Create new LVM devices."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"osism apply ceph-create-lvm-devices -l <nodename>\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Everything is now ready for the deployment of the new OSD.\nDetails on deploying the OSD service in the ",(0,i.jsx)(n.a,{href:"../operations-guide/ceph#add-a-new-osd",children:"Ceph operations guide"}),"."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"dashboard",children:"Dashboard"}),"\n",(0,i.jsxs)(n.p,{children:["Password for the admin user of the Ceph dashboard is set via ",(0,i.jsx)(n.code,{children:"ceph_dashboard_password"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/secrets.yml"',children:"ceph_dashboard_password: password\n"})}),"\n",(0,i.jsx)(n.p,{children:"User name of the admin user, port and listen IP address can be set via additional parameters."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:"ceph_dashboard_addr: 0.0.0.0\nceph_dashboard_port: 7000\nceph_dashboard_username: admin\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The Ceph dashboard is bootstrapped with the ",(0,i.jsx)(n.code,{children:"ceph-bootstrap-dashboard"})," play."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply ceph-bootstrap-dashboard\n"})}),"\n",(0,i.jsx)(n.h3,{id:"configuring-the-openstack-loadbalancer-to-expose-the-ceph-dashboard",children:"Configuring the openstack loadbalancer to expose the ceph dashboard"}),"\n",(0,i.jsx)(n.p,{children:"The ceph dashboard runs in an active/standby configuration. In its default standby instances will\nredirect to the active instance. Most deployments will want to use the openstack loadbalancer to\nexpose the ceph dashboard on the internal network and direct traffic directly to the active\ninstance."}),"\n",(0,i.jsxs)(n.p,{children:["In this scenario the dashboard should be configured to return an http error with status ",(0,i.jsx)(n.code,{children:"404"})," on\nstandby instances."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:"ceph_dashboard_standby_behaviour: error\nceph_dashboard_standby_error_status_code: 404\n"})}),"\n",(0,i.jsx)(n.p,{children:"Create a loadbalancer configuration"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-jinja2",metastring:'title="environments/kolla/files/overlays/haproxy/services.d/ceph_dashboard.cfg"',children:"\n{%- set internal_tls_bind_info = 'ssl crt /etc/haproxy/certificates/haproxy-internal.pem' if kolla_enable_tls_internal|bool else '' %}\n\nlisten ceph_dashboard\n option httpchk\n http-check expect status 200,404\n http-check disable-on-404\n {{ \"bind %s:%s %s\"|e|format(kolla_internal_vip_address, 8140, internal_tls_bind_info)|trim() }}\n{% for host in groups['ceph-mgr'] %}\n server {{ hostvars[host]['ansible_facts']['hostname'] }} {{ hostvars[host]['monitor_address'] }}:7000 check inter 2000 rise 2 fall 5\n{% endfor %}\n"})}),"\n",(0,i.jsx)(n.p,{children:"and apply it."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply -a reconfigure loadbalancer\n"})}),"\n",(0,i.jsx)(n.h2,{id:"second-ceph-cluster",children:"Second Ceph cluster"}),"\n",(0,i.jsxs)(n.p,{children:["With OSISM, it is possible to manage any number of independent Ceph clusters via a single OSISM\nmanager service using sub-environments. A sub environment is basically nothing more than another directory\nbelow the ",(0,i.jsx)(n.code,{children:"environments"})," directory of the configuration repository with a special name."]}),"\n",(0,i.jsxs)(n.p,{children:["A sub-environment for Ceph always has the name ",(0,i.jsx)(n.code,{children:"ceph.NAME"}),". The ",(0,i.jsx)(n.code,{children:"ceph.NAME"})," directory in the\nconfiguration repository then contains the ",(0,i.jsx)(n.code,{children:"configuration.yml"}),", ",(0,i.jsx)(n.code,{children:"images.yml"})," and ",(0,i.jsx)(n.code,{children:"secrets.yml"}),"\nfiles as usual."]}),"\n",(0,i.jsxs)(n.p,{children:["In this example, a sub-environment ",(0,i.jsx)(n.code,{children:"ceph.rgw"})," is created which is used for a Ceph cluster that\nwill only be used as an RGW cluster."]}),"\n",(0,i.jsxs)(n.p,{children:["In comparison to the normal ",(0,i.jsx)(n.code,{children:"ceph"})," environment, the groups to be used must be overwritten for a\nCeph sub-environment. In this case, two groups are defined: ",(0,i.jsx)(n.code,{children:"ceph.rgw"})," and ",(0,i.jsx)(n.code,{children:"ceph.rgw.empty"}),".\nAny other groups can be used, e.g. ",(0,i.jsx)(n.code,{children:"ceph.rgw.osd"}),". It is recommended to base the name of the\ngroups on the name of the sub-environments."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"ceph.rgw.empty"})," group is important because there are plays in ceph-ansible that are executed\nwhen nodes are in a specific group. To explicitly avoid this, certain groups are set to the empty\ngroup."]}),"\n",(0,i.jsxs)(n.p,{children:["All available group name parameters are listed in the ",(0,i.jsx)(n.a,{href:"https://github.com/osism/defaults/blob/main/all/099-ceph.yml",children:"[099-ceph.yml]"}),"\nfile of the ",(0,i.jsx)(n.a,{href:"https://github.com/osism/defaults",children:"osism/defaults"})," repository."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph.rgw/configuration.yml"',children:"##########################\n# groups\n\nceph_group_name: ceph.rgw\n\nclient_group_name: ceph.rgw\ngrafana_server_group_name: ceph.rgw\niscsi_gw_group_name: ceph.rgw.empty\nmds_group_name: ceph.rgw.empty\nmgr_group_name: ceph.rgw\nmon_group_name: ceph.rgw\nnfs_group_name: ceph.rgw.empty\nosd_group_name: ceph.rgw\nrbdmirror_group_name: ceph.rgw.empty\nrestapi_group_name: ceph.rgw.empty\nrgw_group_name: ceph.rgw\nrgwloadbalancer_group_name: ceph.rgw.empty\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The groups used are then added in the inventory in the ",(0,i.jsx)(n.code,{children:"10-custom"})," file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/10-custom"',children:"[ceph.rgw]\ntestbed-node-3.testbed.osism.xyz\ntestbed-node-4.testbed.osism.xyz\ntestbed-node-5.testbed.osism.xyz\n\n[ceph.rgw.empty]\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The sub environment can then be specified with all ",(0,i.jsx)(n.code,{children:"apply"})," commands of the OSISM CLI. For example,\nto deploy the Ceph mon services of the ",(0,i.jsx)(n.code,{children:"ceph.rgw"})," sub environment:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply --sub rgw ceph-osds\n"})}),"\n",(0,i.jsx)(n.h2,{id:"resource-limits",children:"Resource limits"}),"\n",(0,i.jsxs)(n.p,{children:["Resource limits for the individual Ceph services can be set via ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"}),".\nThe possible parameters and their defaults for memory limits and CPU limits are listed below."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Memory limits"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'ceph_mds_docker_memory_limit: "{{ ansible_facts[\'memtotal_mb\'] }}m"\nceph_mgr_docker_memory_limit: "{{ ansible_facts[\'memtotal_mb\'] }}m"\nceph_mon_docker_memory_limit: "{{ ansible_facts[\'memtotal_mb\'] }}m"\nceph_osd_docker_memory_limit: "{{ ansible_facts[\'memtotal_mb\'] }}m"\nceph_rbd_mirror_docker_memory_limit: "{{ ansible_facts[\'memtotal_mb\'] }}m"\nceph_rgw_docker_memory_limit: "4096m"\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"CPU limits"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_mds_docker_cpu_limit: 4\nceph_mgr_docker_cpu_limit: 1\nceph_mon_docker_cpu_limit: 1\nceph_osd_docker_cpu_limit: 4\nceph_rbd_mirror_docker_cpu_limit: 1\nceph_rgw_docker_cpu_limit: 8\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"cpu-pinning",children:"CPU Pinning"}),"\n",(0,i.jsxs)(n.p,{children:["CPU pinning and specifying the NUMA nodes to be used for the Ceph OSD and RGW services can be\nset via ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"}),".\nThe possible parameters and possible values are listed below. The parameters are not enabled\nby default."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Limit the specific CPUs or cores a container can use. A comma-separated list or\nhyphen-separated range of CPUs a container can use, if you have more than one CPU.\nThe first CPU is numbered 0. A valid value might be 0-3 (to use the first, second,\nthird, and fourth CPU) or 1,3 (to use the second and fourth CPU)."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# ceph_osd_docker_cpuset_cpus: "0,2,4,6,8,10,12,14,16"\n# ceph_rgw_docker_cpuset_cpus: "0,2,4,6,8,10,12,14,16"\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Memory nodes in which to allow execution (e.g. 0-3, 0,1). Only effective on NUMA systems."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# ceph_osd_docker_cpuset_mems: "0"\n# ceph_rgw_docker_cpuset_mems: "0"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Available NUMA nodes on a node can be displayed with ",(0,i.jsx)(n.a,{href:"https://github.com/numactl/numactl",children:"numactl"}),".\nIn this example, there are 2 NUMA nodes. The pinned CPUs should all be assigned to the\nspecified NUMA node."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# numactl --hardware\navailable: 2 nodes (0-1)\nnode 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59\nnode 0 size: 515581 MB\nnode 0 free: 511680 MB\nnode 1 cpus: 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79\nnode 1 size: 516078 MB\nnode 1 free: 511865 MB\nnode distances:\nnode 0 1\n 0: 10 20\n 1: 20 10\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"use-of-rbds-for-nodes",children:"Use of RBDs for nodes"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add an extra pool (see ",(0,i.jsx)(n.a,{href:"#extra-pools",children:"Extra pools"}),")."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add a key for the new pool (see ",(0,i.jsx)(n.a,{href:"#extra-keys",children:"Extra keys"}),")."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add nodes on which RBDs are to be used to the inventory group ",(0,i.jsx)(n.code,{children:"cephclient"}),". The file\n",(0,i.jsx)(n.code,{children:"99-overwrite"})," must be used for this. By default, the inventory group looks like this:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'file="inventory/99-overwrite"',children:"[cephclient:children]\nmanager\n"})}),"\n",(0,i.jsx)(n.p,{children:"It could look like this with the additional inventory group:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'file="inventory/99-overwrite"',children:"[cephclient:children]\nmanager\ntestbed-resource-nodes\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Prepare the configuration of the Ceph client. Get the keyring with\n",(0,i.jsx)(n.code,{children:"ceph auth get client.extra001"}),"."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'file="inventory/group_vars/testbed-resource-nodes.yml"',children:'---\ncephclient_install_type: package\ncephclient_keyring_name: client.extra001\ncephclient_keyring: |\n [client.extra001]\n key = AQBiHV9nAAAAABAAhtxl8rdW/EBvxiOGw4iMJw==\n caps mon = "profile rbd"\n caps osd = "profile rbd pool=extra001"\n'})}),"\n",(0,i.jsx)(n.p,{children:"For Ubuntu 24.04 nodes also add the following parameter. At the moment no Ceph packages\nare available for Ubuntu 24.04."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'cephclient_debian_repository: "deb https://download.ceph.com/debian-{{ cephclient_version }} jammy main"\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"5",children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Create new RBD in the new pool (run this command on the manager node).\nIn this example, the name of the node on which the RBD is to be used is\nused as the name for the RBD."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"rbd create testbed-node-5 --size 64 --pool extra001\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"On the node map the RBD as block device."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"sudo rbd map testbed-node-5 --pool extra001 --id extra001\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"On the node check the mapped block device."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"sudo rbd showmapped --id extra001\nid pool namespace image snap device\n0 extra001 testbed-node-5 - /dev/rbd0\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Done. ",(0,i.jsx)(n.code,{children:"/dev/rbd0"})," can now be used like a normal block device."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The file ",(0,i.jsx)(n.code,{children:"/etc/ceph/rbdmap"})," is used to persist the mapping. The service ",(0,i.jsx)(n.code,{children:"rbdmap.service"}),"\nmust be activated and started for this."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"extra001/testbed-node-5 id=extra001,keyring=/etc/ceph/ceph.client.extra001.keyring\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var d=s(96540);const i={},c=d.createContext(i);function a(e){const n=d.useContext(c);return d.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),d.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6c4198a1.92e8d0f7.js b/assets/js/6c4198a1.92e8d0f7.js new file mode 100644 index 0000000000..f74a7ea9b8 --- /dev/null +++ b/assets/js/6c4198a1.92e8d0f7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[87638],{49862:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"iaas/guides/deploy-guide/bootstrap","title":"Bootstrap","description":"The prerequisite for bootstraping the nodes of a cluster the Manager node has to be","source":"@site/docs/02-iaas/guides/deploy-guide/bootstrap.md","sourceDirName":"02-iaas/guides/deploy-guide","slug":"/iaas/guides/deploy-guide/bootstrap","permalink":"/docs/iaas/guides/deploy-guide/bootstrap","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/bootstrap.md","tags":[],"version":"current","sidebarPosition":40,"frontMatter":{"sidebar_label":"Bootstrap","sidebar_position":40},"sidebar":"docs","previous":{"title":"Provisioning","permalink":"/docs/iaas/guides/deploy-guide/provisioning"},"next":{"title":"Rookify (technical preview)","permalink":"/docs/iaas/guides/deploy-guide/rookify"}}');var i=n(74848),r=n(28453);const t={sidebar_label:"Bootstrap",sidebar_position:40},a="Bootstrap",d={},l=[];function c(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"bootstrap",children:"Bootstrap"})}),"\n",(0,i.jsxs)(s.admonition,{type:"info",children:[(0,i.jsxs)(s.p,{children:["The prerequisite for bootstraping the nodes of a cluster the Manager node has to be\nprepares. What a Manager node is and how to prepare it is documented in the\n",(0,i.jsx)(s.a,{href:"/docs/iaas/guides/deploy-guide/manager",children:"Manager chapter of the Deploy Guide"}),"."]}),(0,i.jsxs)(s.p,{children:["All the nodes must also have already been provisioned. How manual provisioning is done\nis documented in the ",(0,i.jsx)(s.a,{href:"/docs/iaas/guides/deploy-guide/provisioning",children:"Provisioning chapter of the Deploy Guide"}),"."]})]}),"\n",(0,i.jsxs)(s.p,{children:["Before the nodes can be bootstrapped, they must all have already been provisioned.\nThe guide for this can be found in the section ",(0,i.jsx)(s.a,{href:"/docs/iaas/guides/deploy-guide/provisioning",children:"Provisioning of bare-metal nodes"}),"."]}),"\n",(0,i.jsx)(s.p,{children:"The following steps are applied to bootstrap all nodes. After the completion of the bootstrap,\nthe nodes are already ready for use."}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Create operator user."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply operator -u osism\n"})}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["When using the ",(0,i.jsx)(s.a,{href:"https://github.com/osism/node-image",children:"osism/node-image"})," the user is ",(0,i.jsx)(s.code,{children:"osism"}),"\nand the password of this user is ",(0,i.jsx)(s.code,{children:"password"}),". If you install Ubuntu manually the user usually\nis ",(0,i.jsx)(s.code,{children:"ubuntu"}),". If you want to use any other user here, with exception of ",(0,i.jsx)(s.code,{children:"dragon"}),", that's no problem.\nThe later used operator user ",(0,i.jsx)(s.code,{children:"dragon"})," is created during the bootstrap and ",(0,i.jsx)(s.strong,{children:"should not be created"}),"\nduring the installation. Do not use ",(0,i.jsx)(s.code,{children:"dragon"})," as username. It is important that\nthis user has sudo rights. The password according to what you have set yourself."]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["The operator public SSH key has to be added in advance on all nodes to ",(0,i.jsx)(s.code,{children:"authorized_keys"})," file\nof the user specified with ",(0,i.jsx)(s.code,{children:"-u"}),". This key is stored as ",(0,i.jsx)(s.code,{children:"operator_public_key"})," in the file\n",(0,i.jsx)(s.code,{children:"environments/configuration.yml"}),"."]}),"\n",(0,i.jsxs)(s.p,{children:["Alternatively (not recommended), the password can be stored in plain text in a file ",(0,i.jsx)(s.code,{children:"/opt/configuration/secrets/conn_password"}),".\nThe parameter ",(0,i.jsx)(s.code,{children:"--conn-pass-file /opt/configuration/secrets/conn_password"})," must then also be specified:"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply operator -u osism \\\n --conn-pass-file /opt/configuration/secrets/conn_password\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["It is important that this user has sudo rights with ",(0,i.jsx)(s.code,{children:"NOPASSWD"}),"."]}),"\n",(0,i.jsxs)(s.p,{children:["Alternatively (not recommended), the password can be stored in plain text in a file ",(0,i.jsx)(s.code,{children:"/opt/configuration/secrets/become_password"}),".\nThe parameter ",(0,i.jsx)(s.code,{children:"--become-pass-file /opt/configuration/secrets/become_password"})," must then also be specified:"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply operator -u osism \\\n --become-pass-file /opt/configuration/secrets/become_password\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"If a password is required for both sudo and login, use both arguments at the same time."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply operator -u osism \\\n --become-pass-file /opt/configuration/secrets/become_password \\\n --conn-pass-file /opt/configuration/secrets/conn_password\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["When using the ",(0,i.jsx)(s.a,{href:"https://github.com/osism/node-image",children:"osism/node-image"})," the user is ",(0,i.jsx)(s.code,{children:"osism"})," and the password of this\nuser is ",(0,i.jsx)(s.code,{children:"password"}),". If you install Ubuntu manually the user usually is ",(0,i.jsx)(s.code,{children:"ubuntu"}),". The password according to what you\nhave set yourself"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Proxy deployment (optional). This is only necessary if you use the proxy on the manager to enable external access to\nthe nodes."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply squid\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Proxy configuration (optional). This is only necessary if you use the proxy on the manager to enable external access to\nthe nodes."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply proxy\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Network configuration. It is recommended to backup the existing network configuration."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply network\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Reboot (optional). The reboot at this point is recommended to ensure that the network configuration is working."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply reboot -l 'all:!manager' -e ireallymeanit=yes\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Check if all systems are reachable (you probably have to do this several times until all systems are accessible)."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply ping\n"})}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"System is currently rebooting and is not yet accessible via network."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:'fatal: [net003]: UNREACHABLE! => {"changed": false, "msg": "Connection timed\nout.", "unreachable": true}``\n'})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"System has already been rebooted and is not accessible via the network."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:'fatal: [net003]: UNREACHABLE! => {"changed": false, "msg": "EOF on stream;\nlast 100 lines received:\\nssh: connect to host 10.15.0.33 port 22: No route\nto host\\r", "unreachable": true}\n'})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Refresh facts."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply facts\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Bootstrap."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply bootstrap\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Reboot (non-optional). Since the kernel version often changes after the initial bootstrap,\nthe reboot should always be performed."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply reboot -l 'all:!manager' -e ireallymeanit=yes\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Check if all systems are reachable (you probably have to do this several times until all systems are accessible)."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply ping\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Prepare the SSH configuration of the manager node."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply sshconfig\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"Make all SSH public keys known."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply known-hosts\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:"Ready. All nodes are now bootstrapped and available to deploy services."})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>a});var o=n(96540);const i={},r=o.createContext(i);function t(e){const s=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),o.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6cdabe05.08192f0c.js b/assets/js/6cdabe05.08192f0c.js new file mode 100644 index 0000000000..d0d2a845c4 --- /dev/null +++ b/assets/js/6cdabe05.08192f0c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9701],{14069:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>f,frontMatter:()=>i,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"scs-0122-v1-node-to-node-encryption","title":"_End-to-End Encryption between Customer Workloads_","description":"Abstract","source":"@site/standards/scs-0122-v1-node-to-node-encryption.md","sourceDirName":".","slug":"/scs-0122-v1-node-to-node-encryption","permalink":"/standards/scs-0122-v1-node-to-node-encryption","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"_End-to-End Encryption between Customer Workloads_","type":"Decision Record","status":"Draft","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0122: _End-to-End Encryption between Customer Workloads_","permalink":"/standards/iaas/scs-0122"},"next":{"title":"scs-0123: Mandatory and Supported IaaS Services","permalink":"/standards/iaas/scs-0123"}}');var r=t(74848),o=t(28453);const i={title:"_End-to-End Encryption between Customer Workloads_",type:"Decision Record",status:"Draft",track:"IaaS"},s=void 0,c={},l=[{value:"Abstract",id:"abstract",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Context",id:"context",level:2},{value:"Motivation",id:"motivation",level:3},{value:"Potential threats in detail",id:"potential-threats-in-detail",level:3},{value:"Man in the Middle Attack",id:"man-in-the-middle-attack",level:4},{value:"Passive Attacks - Eavesdropping",id:"passive-attacks---eavesdropping",level:5},{value:"Active - Spoofing / Tampering",id:"active---spoofing--tampering",level:5},{value:"Preliminary considerations",id:"preliminary-considerations",level:3},{value:"Utilize existing solutions",id:"utilize-existing-solutions",level:4},{value:"Upstream integration",id:"upstream-integration",level:4},{value:"Address threat modeling issues",id:"address-threat-modeling-issues",level:4},{value:"Performance impact and ease of use",id:"performance-impact-and-ease-of-use",level:4},{value:"Avoid redundant encryption",id:"avoid-redundant-encryption",level:4},{value:"Exploration of technologies",id:"exploration-of-technologies",level:3},{value:"Networking in OpenStack",id:"networking-in-openstack",level:4},{value:"Encryption options",id:"encryption-options",level:4},{value:"MACsec",id:"macsec",level:5},{value:"eBPF-based encryption with Linux Kernel Crypto API",id:"ebpf-based-encryption-with-linux-kernel-crypto-api",level:5},{value:"IPsec",id:"ipsec",level:5},{value:"WireGuard",id:"wireguard",level:5},{value:"Solution proposals",id:"solution-proposals",level:3},{value:"TripleO with IPsec",id:"tripleo-with-ipsec",level:4},{value:"OVN + IPsec",id:"ovn--ipsec",level:4},{value:"Neutron + Cilium",id:"neutron--cilium",level:4},{value:"Neutron + Calico",id:"neutron--calico",level:4},{value:"Proof of concept implementations",id:"proof-of-concept-implementations",level:3},{value:"Neutron Plugin",id:"neutron-plugin",level:4},{value:"Manual setup",id:"manual-setup",level:4},{value:"Proof of concept (PoC) implementation",id:"proof-of-concept-poc-implementation",level:4},{value:"Architecture",id:"architecture",level:5},{value:"Challanges",id:"challanges",level:5},{value:"Additional infrastructure",id:"additional-infrastructure",level:5},{value:"Possible improvements",id:"possible-improvements",level:5},{value:"Decision",id:"decision",level:2},{value:"Utilize existing solutions",id:"utilize-existing-solutions-1",level:3},{value:"Address threat modeling issues",id:"address-threat-modeling-issues-1",level:3},{value:"Avoid redundant encryption",id:"avoid-redundant-encryption-1",level:3},{value:"Performance impact and ease of use",id:"performance-impact-and-ease-of-use-1",level:3},{value:"Upstream integration",id:"upstream-integration-1",level:3},{value:"References",id:"references",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",em:"em",h2:"h2",h3:"h3",h4:"h4",h5:"h5",img:"img",li:"li",ol:"ol",p:"p",section:"section",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"abstract",children:"Abstract"}),"\n",(0,r.jsx)(n.p,{children:"This document explores options for developing end-to-end (E2E) encryption for\nVMs, Magnum workloads, and container layers to enhance security between user\nservices. It includes a detailed review of various technologies, feedback from\nthe OpenStack community, and the decision-making process that led to selecting\nVXLANs with the OpenStack ML2 plugin and it's later abandonment in favour of\nnatural openvswitch-ipsec solution."}),"\n",(0,r.jsx)(n.h2,{id:"terminology",children:"Terminology"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Term"}),(0,r.jsx)(n.th,{children:"Meaning"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"CSP"}),(0,r.jsx)(n.td,{children:"Cloud service provider, in this document it includes also an operator of a private cloud"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"VM"}),(0,r.jsx)(n.td,{children:"Virtual machine, alternatively instance, is a virtualized compute resource that functions as a self-contained server for a customer"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Node"}),(0,r.jsx)(n.td,{children:"Machine under CSP administration which hosts cloud services and compute instances"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"context",children:"Context"}),"\n",(0,r.jsx)(n.h3,{id:"motivation",children:"Motivation"}),"\n",(0,r.jsx)(n.p,{children:"The security of customer/user workloads is one of CSPs main concerns. With\nlarger and more diverse cloud instances, parts of the underlying physical\ninfrastructure can be outside of CSPs direct control, either when\ninterconnecting datacenters via public internet or in the case of renting\ninfrastructure from third party. Many security breaches occur due to\nactions of malicious or negligent inhouse operators. While some burden lies\nwith customers, which should secure their own workloads, CSP should have the\noption to transparently protect the data pathways between instances, more so\nfor private clouds, where CSP and customer are the same entity or parts of the\nsame entity."}),"\n",(0,r.jsxs)(n.p,{children:["In RFC8926",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-rfc",id:"user-content-fnref-rfc","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})," it is stated:"]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:"A tenant system in a customer premises (private data center) may want to\nconnect to tenant systems on their tenant overlay network in a public cloud\ndata center, or a tenant may want to have its tenant systems located in\nmultiple geographically separated data centers for high availability. Geneve\ndata traffic between tenant systems across such separated networks should be\nprotected from threats when traversing public networks. Any Geneve overlay\ndata leaving the data center network beyond the operator's security domain\nSHOULD be secured by encryption mechanisms, such as IPsec or other VPN\ntechnologies, to protect the communications between the NVEs when they are\ngeographically separated over untrusted network links."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"We aren't considering the communication intra node, meaning inside one host\nnode between different VMs potentially of multiple tenants as this is a\nquestion of tenant isolation, not of networking security, and encryption here\nwould be possibly a redundant measure. Isolation of VMs is handled by OpenStack\non multiple levels - overlay tunneling protocols, routing rules on networking\nlevel, network namespaces on kernel level and hypervisor isolation mechanisms.\nAll the communication here is existing inside node and any malicious agent with\nhigh enough access to the node itself to observe/tamper with the internal\ncommunication traffic would pressumably have access to the encryption keys\nthemselves, rendering the encryption ineffective."}),"\n",(0,r.jsx)(n.h3,{id:"potential-threats-in-detail",children:"Potential threats in detail"}),"\n",(0,r.jsx)(n.p,{children:"We are assuming that:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"the customer workloads are not executed within secure enclaves (e.g. Security\nGuard Extensions (SGX)) and aren't using security measures like end-to-end\nencryption themselves, either relying with security on the CSP or in the case\nof a private cloud are run by the operator of the cloud"}),"\n",(0,r.jsx)(n.li,{children:"the CSP OpenStack administrators are deemed trustworthy since they possess\nroot access to the host nodes, with access to keys and certificates, enabling\nthem to bypass any form of internode communication encryption"}),"\n",(0,r.jsx)(n.li,{children:"a third party or an independent team manages physical network communication\nbetween nodes within a colocation setting or the communication passes unsafe\npublic infrastructure in the case of a single stretched instance spanning\nmultiple data centers"}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"man-in-the-middle-attack",children:"Man in the Middle Attack"}),"\n",(0,r.jsx)(n.p,{children:"Considering the assumptions and the objective to enforce end-to-end (E2E)\nencryption for user workloads, our primary security concern is averting\nman-in-the-middle (MITM) attacks. These can be categorized into two distinct\nforms: active and passive."}),"\n",(0,r.jsx)(n.h5,{id:"passive-attacks---eavesdropping",children:"Passive Attacks - Eavesdropping"}),"\n",(0,r.jsx)(n.p,{children:"Consider the scenario where an untrusted individual, such as a third party\nnetwork administrator, with physical access to the data center engages in\n'passive' covert surveillance, silently monitoring unencrypted traffic\nwithout interfering with data integrity or network operations."}),"\n",(0,r.jsx)(n.p,{children:"Wiretapping is a common technique employed in such espionage. It involves the\nunauthorized attachment to network cabling, enabling the covert observation of\ndata transit. This activity typically goes unnoticed as it does not disrupt\nthe flow of network traffic, although it may occasionally introduce minor\ntransmission errors."}),"\n",(0,r.jsx)(n.p,{children:"An alternative strategy involves deploying an interception device that\ncaptures and retransmits data, which could potentially introduce network\nlatency or, if deployed disruptively, cause connectivity interruptions. Such\ndevices can be concealed by synchronizing their installation with network\ndowntime, maintenance periods, or less conspicuous times like power outages.\nThey could also be strategically placed in less secure, more accessible\nlocations, such as inter-building network links. This applies to wiretapping\nas well."}),"\n",(0,r.jsx)(n.p,{children:"Furthermore, the vulnerability extends to network devices, where an attacker\ncould exploit unsecured management ports or leverage compromised remote\nmanagement tools (like IPMI) to gain unauthorized access. Such access points,\nespecially those not routinely monitored like backup VPNs, present additional\nsecurity risks."}),"\n",(0,r.jsx)(n.p,{children:"Below is a conceptual diagram depicting potential vulnerabilities in an\nOpenStack deployment across dual regions, highlighting how these passive\neavesdropping techniques could be facilitated."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{src:"https://github.com/SovereignCloudStack/issues/assets/1249759/f5b7edf3-d259-4b2a-8632-c877934f3e31",alt:"image"})}),"\n",(0,r.jsx)(n.h5,{id:"active---spoofing--tampering",children:"Active - Spoofing / Tampering"}),"\n",(0,r.jsx)(n.p,{children:"Active network attacks like spoofing and tampering exploit various access\npoints, often leveraging vulnerabilities uncovered during passive eavesdropping\nphases. These attacks actively manipulate or introduce unauthorized\ncommunications on the network."}),"\n",(0,r.jsx)(n.p,{children:"Spoofing involves an attacker masquerading as another device or user within the\nnetwork. This deception can manifest in several ways:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"ARP Spoofing:"})," The attacker sends forged ARP (Address Resolution Protocol)\nmessages onto the network. This can redirect network traffic flow to the\nattacker's machine, intercepting, modifying, or blocking data before it\nreaches its intended destination."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"DNS Spoofing:"})," By responding with falsified DNS replies, an attacker can\nreroute traffic to malicious sites, further compromising or data exfiltration."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"IP Spoofing:"})," The attacker disguises their network identity by falsifying\nIP address information in packets, tricking the network into accepting them\nas legitimate traffic. This can be particularly damaging if encryption is not\nenforced, enabling the attacker to interact with databases, invoke APIs, or\nexecute unauthorized commands while appearing as a trusted entity."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Moreover, when an active interception device is in place, attackers can extend\ntheir capabilities to traffic filtering. They might selectively delete or alter\nlogs and metrics to erase traces of their intrusion or fabricate system\nperformance data, thus obscuring the true nature of their activities."}),"\n",(0,r.jsx)(n.h3,{id:"preliminary-considerations",children:"Preliminary considerations"}),"\n",(0,r.jsxs)(n.p,{children:["Initially we wanted to create a plugin into Neutron",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ne",id:"user-content-fnref-ne","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," using eBPF",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-eb",id:"user-content-fnref-eb","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})})," to\nsecure the traffic automatically between VMs. We presented the idea in a\nteam IaaS call",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ia",id:"user-content-fnref-ia","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"4"})}),". After the initial round of feedback specific requirements\nemerged."]}),"\n",(0,r.jsx)(n.h4,{id:"utilize-existing-solutions",children:"Utilize existing solutions"}),"\n",(0,r.jsx)(n.p,{children:"Leverage existing technologies and frameworks as much as possible. This\napproach aims to reduce development time and ensure the solution is built on\nproven, reliable foundations. Potential technologies include:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.strong,{children:["OVS",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-sw",id:"user-content-fnref-sw","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"5"})})," + IPSec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})]}),": Provides an overlay network and has built-in\nsupport for encryption using IPsec. Leveraging OVS can minimize development\ntime since it is already integrated with OpenStack."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.strong,{children:["Neutron",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ne",id:"user-content-fnref-ne-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," with eBPF",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-eb",id:"user-content-fnref-eb-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})})]}),": Using eBPF",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-eb",id:"user-content-fnref-eb-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})})," could provide fine-grained\ncontrol over packet filtering and encryption directly in the kernel."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.strong,{children:["TripleO",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-to",id:"user-content-fnref-to","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"7"})})," (with IPsec)"]}),": TripleO",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-to",id:"user-content-fnref-to-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"7"})})," tool set for OpenStack deployment\nsupports IPsec tunnels between nodes."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.strong,{children:["Neutron",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ne",id:"user-content-fnref-ne-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," + Cilium",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ci",id:"user-content-fnref-ci","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"8"})})]}),": Cilium is an open source, cloud native\neBPF",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-eb",id:"user-content-fnref-eb-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),"-based networking solution, including transparent encryption tools."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsxs)(n.strong,{children:["Tailscale",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ta",id:"user-content-fnref-ta","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"9"})})]})," is a mesh VPN based on WireGuard",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-wg",id:"user-content-fnref-wg","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"10"})})," that simplifies the\nsetup of secure, encrypted networks. This could be a potential alternative\nto managing encrypted connections in OpenStack environments."]}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"upstream-integration",children:"Upstream integration"}),"\n",(0,r.jsxs)(n.p,{children:["Move as much of the development work upstream into existing OpenStack projects.\nThis will help ensure the solution is maintained by the wider OpenStack\ncommunity, reducing the risk of it becoming unmaintained or unusable in the\nfuture. This means to collaborate with the OpenStack community to contribute\nchanges upstream, particularly in projects like Neutron",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ne",id:"user-content-fnref-ne-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),", OVN",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ov",id:"user-content-fnref-ov","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"11"})}),",\nkolla",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-kl",id:"user-content-fnref-kl","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"12"})})," and ansible-kolla",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ka",id:"user-content-fnref-ka","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"13"})}),"."]}),"\n",(0,r.jsx)(n.h4,{id:"address-threat-modeling-issues",children:"Address threat modeling issues"}),"\n",(0,r.jsxs)(n.p,{children:['"We should not encrypt something just for the sake of encryption." The solution\nmust address the specific security issues identified in the\n',(0,r.jsx)(n.a,{href:"#potential-threats-in-detail",children:"threat modeling"}),". This ideally includes\nprotecting against both passive (eavesdropping) and active (spoofing,\ntampering) MITM attacks. Encryption mechanisms on all communication channels\nbetween VMs, containers, hosts prevents successfull eavesdropping,\nauthentication and integrity checks prevent spoofing and tampering. For example\nIPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})," provides mechanisms for both encyption and integrity verification."]}),"\n",(0,r.jsx)(n.h4,{id:"performance-impact-and-ease-of-use",children:"Performance impact and ease of use"}),"\n",(0,r.jsx)(n.p,{children:"Evaluate the performance impact of the encryption solution and ensure it is\nminimal. Performance benchmarking should be conducted to assess the impact of\nthe encryption solution on network throughput and latency. For local trusted\nscenarios opt out should be possible. The solution should also be easy to use\nand manage, both for administrators and ideally fully transparent for\nend-users. This may involve developing user-friendly interfaces and automated\ntools for key management and configuration."}),"\n",(0,r.jsx)(n.h4,{id:"avoid-redundant-encryption",children:"Avoid redundant encryption"}),"\n",(0,r.jsx)(n.p,{children:"If possible, develop a mechanism to detect and avoid encrypting traffic that is\nalready encrypted. This will help optimize performance and resource usage."}),"\n",(0,r.jsx)(n.p,{children:"By focusing on these detailed requirements and considerations, we aim to\ndevelop a robust, efficient, and sustainable E2E encryption solution for\nOpenStack environments. This solution will not only enhance security for user\nworkloads but also ensure long-term maintainability and ease of use."}),"\n",(0,r.jsx)(n.h3,{id:"exploration-of-technologies",children:"Exploration of technologies"}),"\n",(0,r.jsx)(n.p,{children:"Based on the result of the threat modeling and presentation, we explored the\nfollowing technologies and also reached out to the OpenStack mailing list for\nadditional comments."}),"\n",(0,r.jsx)(n.p,{children:"This section provides a brief explanation of OpenStack networking and design\ndecisions for encryption between customer workloads."}),"\n",(0,r.jsx)(n.h4,{id:"networking-in-openstack",children:"Networking in OpenStack"}),"\n",(0,r.jsxs)(n.p,{children:["The foundation of networking in OpenStack is the Neutron",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ne",id:"user-content-fnref-ne-5","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," project,\nproviding networking as a service (NaaS). It creates and manages network\nresources such as switches, routers, subnets, firewalls and load balancers,\nuses plugin architecture to support different physical network implementation\noptions and is accessible to admin or other services through API."]}),"\n",(0,r.jsxs)(n.p,{children:["Another integral part is the Open vSwitch (OVS)",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-sw",id:"user-content-fnref-sw-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"5"})})," - a widely adopted virtual\nswitch implementation, which is not strictly necessary, as Neutron is quite\nflexible with compenents used to implement the infrastructure, but tends to\nbe the agent of choice and is the current default agent for Neutron. It allows\nit to respond to environment changes, supporting accounting and monitoring\nprotocols and maintaining OVSDB state database. It manages virtual ports,\nbridges and tunnels on hosts."]}),"\n",(0,r.jsxs)(n.p,{children:["Open Virtual Networking (OVN",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ov",id:"user-content-fnref-ov-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"11"})}),") is a logical abstraction layer on top of OVS,\ndeveloped by the same community that became the default controller driver for\nNeutron. It manages logical networks insulated from underlying physical/virtual\nnetworks by encapsulation. It replaces the need for OVS agents running on each\nhost and supports L2 switching, distributed L3 routing, access control and load\nbalancing."]}),"\n",(0,r.jsx)(n.h4,{id:"encryption-options",children:"Encryption options"}),"\n",(0,r.jsxs)(n.h5,{id:"macsec",children:["MACsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ms",id:"user-content-fnref-ms","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"14"})})]}),"\n",(0,r.jsx)(n.p,{children:"A layer 2 security protocol, defined by an IEEE standard 802.1AE. It allows to\nsecure an ethernet link for almost all traffic, including control protocols\nlike DHCP and ARP. It is mostly implemented in hardware, in routers and\nswitches, but software implementations exist, notably a Linux kernel module."}),"\n",(0,r.jsxs)(n.h5,{id:"ebpf-based-encryption-with-linux-kernel-crypto-api",children:["eBPF",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-eb",id:"user-content-fnref-eb-5","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),"-based encryption with Linux Kernel Crypto API"]}),"\n",(0,r.jsxs)(n.p,{children:["A network packet specific filtering technology in Linux kernel called\nBerkeley Packet Filter (BPF) uses a specialized virtual machine inside\nkernel to run filters on the networking stack. eBPF is an extension of this\nprinciple to a general purpose stack which can run sandboxed programs in kernel\nwithout changes of kernel code or loading modules. High-performance networking\nobservability and security is a natural use-case with projects like Cilium",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ci",id:"user-content-fnref-ci-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"8"})}),"\nimplementing transparent in-kernel packet encryption with it. Linux kernel\nitself also provides an encryption framework called\nLinux Kernel Crypto API",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-lkc",id:"user-content-fnref-lkc","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"15"})})," which such solutions use."]}),"\n",(0,r.jsxs)(n.h5,{id:"ipsec",children:["IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})]}),"\n",(0,r.jsxs)(n.p,{children:["Internet Protocol security is a suite of protocols for network security on\nlayer 3, providing authentication and packets encryption used for example in\nVirtual Private Network (VPN) setups. It is an IETF",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ie",id:"user-content-fnref-ie","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"16"})})," specification with\nvarious open source and commercial implementations. For historical\nreasons",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ipwh",id:"user-content-fnref-ipwh","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"17"})})," it defines two main transmission protocols\nAuthentication Header (AH) and Encapsulating Security Payload (ESP) where only\nthe latter provides encryption in addition to authentication and integrity. The\nkey negotiations use the IKE(v1/v2) protocol to establish and maintain\nSecurity Associations (SA)."]}),"\n",(0,r.jsxs)(n.h5,{id:"wireguard",children:["WireGuard",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-wg",id:"user-content-fnref-wg-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"10"})})]}),"\n",(0,r.jsxs)(n.p,{children:["Aims to be a simple and fast open source secure network tunneling solution\nworking on layer 3, utilizing state-of-the-art cryptography while maintaining\nmuch simpler codebase and runtime setup as alternative solutions",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-wgwp",id:"user-content-fnref-wgwp","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"18"})}),". Focus\nis on fast in-kernel encryption. WireGuard",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-wg",id:"user-content-fnref-wg-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"10"})})," adds new network interfaces,\nmanagable by standard tooling (ifconfig, route,...) which act as tunneling\ninterfaces. Main mechanism, called ",(0,r.jsx)(n.em,{children:"Cryptokey routing"}),", are tables associating\npublic keys of endpoints with allowed IPs inside given tunnels. These behave as\nrouting tables when sending and access control lists (ACL) when receiving\npackets. All packets are sent over UDP. Built-in roaming is achieved by both\nserver and clients being able to update the peer list by examining from where\ncorrectly authenticated data originates."]}),"\n",(0,r.jsx)(n.h3,{id:"solution-proposals",children:"Solution proposals"}),"\n",(0,r.jsxs)(n.h4,{id:"tripleo-with-ipsec",children:["TripleO",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-to",id:"user-content-fnref-to-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"7"})})," with IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:"TripleO is a project aimed at installing, upgrading and operating OpenStack\nclouds using OpenStack's own cloud facilities as the foundation - building on\nNova, Ironic, Neutron and Heat to automate cloud management at datacenter\nscale"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"This project is retired as of February 2024, but its approach was considered\nfor adoption."}),"\n",(0,r.jsxs)(n.p,{children:["Its deployment allowed for IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-5","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})," encryption of node communication. When\nutilized, two types of tunnels were created in overcloud: node-to-node tunnels\nfor each two nodes on the same network, for all networks those nodes were on,\nand Virtual IP tunnels. Each node hosting the Virtual IP would open a tunnel\nfor any node in the specific network that can properly authenticate."]}),"\n",(0,r.jsxs)(n.h4,{id:"ovn--ipsec",children:["OVN",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ov",id:"user-content-fnref-ov-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"11"})})," + IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-6","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})]}),"\n",(0,r.jsxs)(n.p,{children:["There is support in the OVN",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ov",id:"user-content-fnref-ov-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"11"})})," project for IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-7","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})," encryption of tunnel\ntraffic",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-oit",id:"user-content-fnref-oit","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"19"})}),". A daemon running in each chassis automatically manages and\nmonitors IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-8","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})," tunnel states."]}),"\n",(0,r.jsxs)(n.h4,{id:"neutron--cilium",children:["Neutron",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ne",id:"user-content-fnref-ne-6","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," + Cilium",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ci",id:"user-content-fnref-ci-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"8"})})]}),"\n",(0,r.jsxs)(n.p,{children:["Another potential architecture involves a Neutron",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ne",id:"user-content-fnref-ne-7","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," plugin hooking an\neBPF",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-eb",id:"user-content-fnref-eb-6","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})})," proxy on each interface and moving internal traffic via an encrypted\nCilium",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ci",id:"user-content-fnref-ci-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"8"})})," mesh. Cilium uses IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-9","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})," or WireGuard[wg] to transparently\nencrypt node-to-node traffic. There were some attempts to integrate Cilium",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ci",id:"user-content-fnref-ci-5","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"8"})}),"\nwith OpenStack ",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-neci1",id:"user-content-fnref-neci1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"20"})}),", ",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-neci2",id:"user-content-fnref-neci2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"21"})}),", but we didn't find any concrete projects\nwhich would leverage the transparent encryption ability of Cilium",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ci",id:"user-content-fnref-ci-6","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"8"})})," in\nOpenStack environment. This path would pressumably require significant\ndevelopment."]}),"\n",(0,r.jsxs)(n.h4,{id:"neutron--calico",children:["Neutron",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ne",id:"user-content-fnref-ne-8","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," + Calico",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ca",id:"user-content-fnref-ca","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"22"})})]}),"\n",(0,r.jsxs)(n.p,{children:["The Calico",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ca",id:"user-content-fnref-ca-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"22"})})," project in its community open source version provides\nnode-to-node encryption using WireGuard",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-wg",id:"user-content-fnref-wg-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"10"})}),". Despite being primarily a\nKubernetes networking project, it provides an OpenStack integration",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-caos",id:"user-content-fnref-caos","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"23"})})," via\na Neutron",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ne",id:"user-content-fnref-ne-9","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," plugin and deploying the necessary subset of tools like etcd,\nCalico agent Felix, routing daemon BIRD and a DHCP agent."]}),"\n",(0,r.jsx)(n.h3,{id:"proof-of-concept-implementations",children:"Proof of concept implementations"}),"\n",(0,r.jsx)(n.h4,{id:"neutron-plugin",children:"Neutron Plugin"}),"\n",(0,r.jsx)(n.p,{children:"Initially the potential for developing a specialized Neutron plugin was\ninvestigated and a simple skeleton implementation for testing purposes was\ndevised."}),"\n",(0,r.jsxs)(n.p,{children:["Own development was later abandoned in favor of a more sustainable solution\nusing existing technologies as disussed in\n",(0,r.jsx)(n.a,{href:"#preliminary-considerations",children:"preliminary considerations"}),"."]}),"\n",(0,r.jsx)(n.h4,{id:"manual-setup",children:"Manual setup"}),"\n",(0,r.jsxs)(n.p,{children:["We created a working Proof of Concept with manually setting up VXLAN tunnels\nbetween nodes. While this solution ensures no impact on OpenStack and is easy\nto set up, it has limitations, such as unencrypted data transmission if the\nconnection breaks. To mitigate this, we proposed using a dedicated subnet\npresent only in the IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-10","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})," tunnels."]}),"\n",(0,r.jsxs)(n.p,{children:["We presented the idea to the kolla-ansible[^ak] project, but it was deemed out\nof scope. Instead, we were directed towards a native Open vSwitch solution\nsupporting IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-11","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})}),". This requires creating a new OpenStack service\n(working name: openstack-ipsec) and a role to manage chassis keys and run the\nopenstack-ipsec container on each node."]}),"\n",(0,r.jsx)(n.h4,{id:"proof-of-concept-poc-implementation",children:"Proof of concept (PoC) implementation"}),"\n",(0,r.jsxs)(n.p,{children:["In our second proof of concept, we decided to implement support for\nopenstack-ipsec. The initial step involved creating a new container image\nwithin the kolla",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-kl",id:"user-content-fnref-kl-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"12"})})," project specifically for this purpose."]}),"\n",(0,r.jsx)(n.h5,{id:"architecture",children:"Architecture"}),"\n",(0,r.jsxs)(n.p,{children:["When Neutron",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ne",id:"user-content-fnref-ne-10","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," uses OVN",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ov",id:"user-content-fnref-ov-5","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"11"})})," as controller it instructs it to create the\nnecessary virtual networking infrastructure (logical switches, routers, etc.),\nparticullary to create Geneve tunnels between compute nodes. These tunnels are\nused to carry traffic between instances on different compute nodes."]}),"\n",(0,r.jsxs)(n.p,{children:["In PoC setup Libreswan",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ls",id:"user-content-fnref-ls","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"24"})})," suite runs on each compute node and manages the\nIPSec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-12","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})," tunnels. It encrypts the traffic flowing over the Geneve tunnels,\nensuring that data is secure as it traverses the physical network. In setup\nphase it establishes IPSec tunnels between compute nodes by negotiating the\nnecessary security parameters (encryption, authentication, etc.). Once the\ntunnels are established, Libreswan",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ls",id:"user-content-fnref-ls-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"24"})})," monitors and manages them, ensuring\nthat the encryption keys are periodically refreshed and that the tunnels remain\nup. It also dynamically adds and removes tunnels based on changes of network\ntopology."]}),"\n",(0,r.jsxs)(n.p,{children:["A packet originating from a VM on one compute node and destined for a VM on\na different node is processed by OVS and encapsulated into a Geneve tunnel.\nBefore the Geneve-encapsulated packet leaves the compute node, it passes\nthrough the Libreswan process, which applies IPSec encryption. The encrypted\npacket traverses the physical network to the destination compute node. On the\ndestination node, Libreswan",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ls",id:"user-content-fnref-ls-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"24"})})," decrypts the packet, and OVN",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ov",id:"user-content-fnref-ov-6","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"11"})})," handles\ndecapsulation and forwards it to the target VM."]}),"\n",(0,r.jsx)(n.h5,{id:"challanges",children:"Challanges"}),"\n",(0,r.jsxs)(n.p,{children:["Implementing the openstack-ipsec image we encountered a significant challenge:\nthe ovs-ctl start-ovs-ipsec command could not run inside the container because\nit requires a running init.d or systemctl to start the IPsec daemon immediately\nafter OVS",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ov",id:"user-content-fnref-ov-7","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"11"})})," deploys the configuration. We attempted to use supervisor to\nmanage the processes within the container. However, this solution forced a\nmanual start of the IPsec daemon before ovs-ctl had the chance to create the\nappropriate configurations."]}),"\n",(0,r.jsx)(n.p,{children:"Another challenge was the requirement for both the IPsec daemon and ovs-ipsec\nto run within a single container. This added complexity to the container\nconfiguration and management, making it harder to ensure both services operated\ncorrectly and efficiently."}),"\n",(0,r.jsx)(n.h5,{id:"additional-infrastructure",children:"Additional infrastructure"}),"\n",(0,r.jsxs)(n.p,{children:["New ansible role for generating chassis keys and distributing them to the\nrespective machines was created. This utility also handles the configuration on\neach machine. Managing and creating production certificates is up to the user,\nwhich is also true for the backend TLS certificates in kolla-ansible",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ka",id:"user-content-fnref-ka-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"13"})}),".\nWhile this management should be handled within the same process, it currently\nposes a risk of downtime when certificates expire, as it requires careful\nmanagement and timely renewal of certificates."]}),"\n",(0,r.jsx)(n.p,{children:"The new container image was designed to include all necessary\ncomponents for openstack-ipsec. Using supervisor to manage the IPsec daemon\nwithin the container involved creating configuration files to ensure all\nservices start correctly. However, integrating supervisor introduced additional\ncomplexity and potential points of failure."}),"\n",(0,r.jsx)(n.h5,{id:"possible-improvements",children:"Possible improvements"}),"\n",(0,r.jsx)(n.p,{children:"PoC doesn't currently address the opt-out possibility for disabling the\nencryption for some specific group of nodes, where operator deems it\ndetrimental because of them being virtual or where security is already handled\nin some other layer of the stack. This could be implemented as a further\ncustomization available to the operator to encrypt only some subset of Geneve\ntunnels, either in blacklist or whitelist manner."}),"\n",(0,r.jsx)(n.p,{children:"Further refinement is needed to ensure ovs-ctl and the IPsec daemon start and\nconfigure correctly within the container environment. Exploring alternative\nprocess management tools or improving the configuration of supervisor could\nhelp achieve a more robust solution."}),"\n",(0,r.jsx)(n.p,{children:"Implementing automated certificate management could mitigate the risks\nassociated with manual certificate renewals. Tools like Certbot or integration\nwith existing Public Key Infrastructure (PKI) solutions might be beneficial."}),"\n",(0,r.jsx)(n.p,{children:"Engaging with the upstream Open vSwitch community to address containerization\nchallenges and improve support for running ovs-ctl within containers could lead\nto more sustainable solution."}),"\n",(0,r.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,r.jsxs)(n.p,{children:["The final proof of concept implementation demonstrated the feasibility of\nimplementing transparent IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-13","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})," encryption between nodes in an OVN",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ov",id:"user-content-fnref-ov-8","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"11"})}),"\nlogical networking setup in OpenStack.\nTo recapitulate our preliminary considerations:"]}),"\n",(0,r.jsx)(n.h3,{id:"utilize-existing-solutions-1",children:"Utilize existing solutions"}),"\n",(0,r.jsxs)(n.p,{children:["Implementation in kolla-ansible",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ka",id:"user-content-fnref-ka-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"13"})})," is unintrusive, provided by a\nself-contained new kolla",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-kl",id:"user-content-fnref-kl-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"12"})})," container, which only adds an IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-14","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})}),"\ntunneling support module to OVS",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-sw",id:"user-content-fnref-sw-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"5"})}),", which is already an integral part of\nOpenStack networking, and a mature open source toolkit - Libreswan",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ls",id:"user-content-fnref-ls-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"24"})}),". Also\nOVN",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ov",id:"user-content-fnref-ov-9","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"11"})})," has native support in OpenStack and became the default controller for\nNeutron",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ne",id:"user-content-fnref-ne-11","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"address-threat-modeling-issues-1",children:"Address threat modeling issues"}),"\n",(0,r.jsxs)(n.p,{children:["As disussed in ",(0,r.jsx)(n.a,{href:"#motivation",children:"motivation"})," and ",(0,r.jsx)(n.a,{href:"#potential-threats-in-detail",children:"threat\nmodelling"})," sections our concern lies with the\npotentially vulnerable physical infrastructure between nodes inside or between\ndata centers. In this case ensuring encryption and integrity of packets before\nleaving any node addresses these threats, while avoiding the complexity of\nsecuring the communication on the VM level, where frequent additions, deletions\nand migrations could render such system complicated and error prone. We also\ndon't needlessly encrypt VM communication inside one node."]}),"\n",(0,r.jsx)(n.h3,{id:"avoid-redundant-encryption-1",children:"Avoid redundant encryption"}),"\n",(0,r.jsxs)(n.p,{children:["As the encryption happens inside tunnels specific for inter-node workload\ncommunication, isolated on own network and also inside Geneve tunnels, no cloud\nservice data, which could be possibly encrypted on higher-levels (TLS) is\npossible here. As to the workload communication itself - detecting higher-layer\nencryption in a way that would allow IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-15","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})," to avoid redundant encryption\nis complex and would require custom modifications or non-standard solutions.\nIt's usually safer and more straightforward to allow the redundancy, ensuring\nsecurity at multiple layers, rather than trying to eliminate it."]}),"\n",(0,r.jsx)(n.h3,{id:"performance-impact-and-ease-of-use-1",children:"Performance impact and ease of use"}),"\n",(0,r.jsxs)(n.p,{children:["Setup is straightforward for the operator, there is just a flag to enable or\ndisable the IPsec",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ip",id:"user-content-fnref-ip-16","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})})," encryption inside Geneve tunnels and the need to set the\nNeutron",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ne",id:"user-content-fnref-ne-12","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," agent to OVN",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-ov",id:"user-content-fnref-ov-10","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"11"})}),". No other configuration is necessary. The only\nother administrative burden is the deployment of certificates to provided\nconfiguration directory on the control node."]}),"\n",(0,r.jsx)(n.p,{children:"Certificate management for this solution can and should be handled in the same\nway as for the backend service certificates which are part of the ongoing\nefforts to provide complete service communication encryption in kolla-ansible.\nCurrently the management of these certificates is partially left on external\nprocesses, but if a toolset or a process would be devised inside the project,\nthis solution would fit in."}),"\n",(0,r.jsx)(n.h3,{id:"upstream-integration-1",children:"Upstream integration"}),"\n",(0,r.jsx)(n.p,{children:"The potential for upstream adoption and long-term maintainability makes this a\npromising direction for securing inter-node communication in OpenStack\nenvironments."}),"\n",(0,r.jsx)(n.h2,{id:"references",children:"References"}),"\n","\n",(0,r.jsxs)(n.section,{"data-footnotes":!0,className:"footnotes",children:[(0,r.jsx)(n.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{id:"user-content-fn-rfc",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc8926#name-inter-data-center-traffic",children:"RFC8926"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-rfc","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-ne",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://docs.openstack.org/neutron/latest/",children:"Neutron"})," - networking as a service (NaaS) in OpenStack ",(0,r.jsx)(n.a,{href:"#user-content-fnref-ne","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ne-2","data-footnote-backref":"","aria-label":"Back to reference 2-2",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"2"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ne-3","data-footnote-backref":"","aria-label":"Back to reference 2-3",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"3"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ne-4","data-footnote-backref":"","aria-label":"Back to reference 2-4",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"4"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ne-5","data-footnote-backref":"","aria-label":"Back to reference 2-5",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"5"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ne-6","data-footnote-backref":"","aria-label":"Back to reference 2-6",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"6"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ne-7","data-footnote-backref":"","aria-label":"Back to reference 2-7",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"7"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ne-8","data-footnote-backref":"","aria-label":"Back to reference 2-8",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"8"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ne-9","data-footnote-backref":"","aria-label":"Back to reference 2-9",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"9"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ne-10","data-footnote-backref":"","aria-label":"Back to reference 2-10",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"10"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ne-11","data-footnote-backref":"","aria-label":"Back to reference 2-11",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"11"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ne-12","data-footnote-backref":"","aria-label":"Back to reference 2-12",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"12"})]})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-eb",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/EBPF",children:"eBPF"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-eb","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-eb-2","data-footnote-backref":"","aria-label":"Back to reference 3-2",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"2"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-eb-3","data-footnote-backref":"","aria-label":"Back to reference 3-3",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"3"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-eb-4","data-footnote-backref":"","aria-label":"Back to reference 3-4",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"4"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-eb-5","data-footnote-backref":"","aria-label":"Back to reference 3-5",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"5"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-eb-6","data-footnote-backref":"","aria-label":"Back to reference 3-6",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"6"})]})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-ia",children:["\n",(0,r.jsxs)(n.p,{children:["Team IaaS call ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/minutes/blob/main/iaas/20240214.md",children:"minutes"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-ia","data-footnote-backref":"","aria-label":"Back to reference 4",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-sw",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://www.openvswitch.org/",children:"open vSwitch"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-sw","data-footnote-backref":"","aria-label":"Back to reference 5",className:"data-footnote-backref",children:"\u21a9"})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-sw-2","data-footnote-backref":"","aria-label":"Back to reference 5-2",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"2"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-sw-3","data-footnote-backref":"","aria-label":"Back to reference 5-3",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"3"})]})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-ip",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/IPsec",children:"IPsec"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-ip","data-footnote-backref":"","aria-label":"Back to reference 6",className:"data-footnote-backref",children:"\u21a9"})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-2","data-footnote-backref":"","aria-label":"Back to reference 6-2",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"2"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-3","data-footnote-backref":"","aria-label":"Back to reference 6-3",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"3"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-4","data-footnote-backref":"","aria-label":"Back to reference 6-4",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"4"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-5","data-footnote-backref":"","aria-label":"Back to reference 6-5",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"5"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-6","data-footnote-backref":"","aria-label":"Back to reference 6-6",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"6"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-7","data-footnote-backref":"","aria-label":"Back to reference 6-7",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"7"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-8","data-footnote-backref":"","aria-label":"Back to reference 6-8",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"8"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-9","data-footnote-backref":"","aria-label":"Back to reference 6-9",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"9"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-10","data-footnote-backref":"","aria-label":"Back to reference 6-10",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"10"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-11","data-footnote-backref":"","aria-label":"Back to reference 6-11",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"11"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-12","data-footnote-backref":"","aria-label":"Back to reference 6-12",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"12"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-13","data-footnote-backref":"","aria-label":"Back to reference 6-13",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"13"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-14","data-footnote-backref":"","aria-label":"Back to reference 6-14",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"14"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-15","data-footnote-backref":"","aria-label":"Back to reference 6-15",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"15"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ip-16","data-footnote-backref":"","aria-label":"Back to reference 6-16",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"16"})]})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-to",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://docs.openstack.org/developer/tripleo-docs/",children:"TripleO"})," - OpenStack on OpenStack ",(0,r.jsx)(n.a,{href:"#user-content-fnref-to","data-footnote-backref":"","aria-label":"Back to reference 7",className:"data-footnote-backref",children:"\u21a9"})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-to-2","data-footnote-backref":"","aria-label":"Back to reference 7-2",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"2"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-to-3","data-footnote-backref":"","aria-label":"Back to reference 7-3",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"3"})]})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-ci",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://cilium.io/",children:"Cillium"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-ci","data-footnote-backref":"","aria-label":"Back to reference 8",className:"data-footnote-backref",children:"\u21a9"})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ci-2","data-footnote-backref":"","aria-label":"Back to reference 8-2",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"2"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ci-3","data-footnote-backref":"","aria-label":"Back to reference 8-3",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"3"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ci-4","data-footnote-backref":"","aria-label":"Back to reference 8-4",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"4"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ci-5","data-footnote-backref":"","aria-label":"Back to reference 8-5",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"5"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ci-6","data-footnote-backref":"","aria-label":"Back to reference 8-6",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"6"})]})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-ta",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://tailscale.com/solutions/devops",children:"Tailscale"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-ta","data-footnote-backref":"","aria-label":"Back to reference 9",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-wg",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://www.wireguard.com/",children:"WireGuard"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-wg","data-footnote-backref":"","aria-label":"Back to reference 10",className:"data-footnote-backref",children:"\u21a9"})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-wg-2","data-footnote-backref":"","aria-label":"Back to reference 10-2",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"2"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-wg-3","data-footnote-backref":"","aria-label":"Back to reference 10-3",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"3"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-wg-4","data-footnote-backref":"","aria-label":"Back to reference 10-4",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"4"})]})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-ov",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://www.ovn.org/en/",children:"Open Virtual Network"})," (OVN) ",(0,r.jsx)(n.a,{href:"#user-content-fnref-ov","data-footnote-backref":"","aria-label":"Back to reference 11",className:"data-footnote-backref",children:"\u21a9"})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ov-2","data-footnote-backref":"","aria-label":"Back to reference 11-2",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"2"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ov-3","data-footnote-backref":"","aria-label":"Back to reference 11-3",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"3"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ov-4","data-footnote-backref":"","aria-label":"Back to reference 11-4",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"4"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ov-5","data-footnote-backref":"","aria-label":"Back to reference 11-5",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"5"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ov-6","data-footnote-backref":"","aria-label":"Back to reference 11-6",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"6"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ov-7","data-footnote-backref":"","aria-label":"Back to reference 11-7",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"7"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ov-8","data-footnote-backref":"","aria-label":"Back to reference 11-8",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"8"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ov-9","data-footnote-backref":"","aria-label":"Back to reference 11-9",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"9"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ov-10","data-footnote-backref":"","aria-label":"Back to reference 11-10",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"10"})]})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-kl",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://opendev.org/openstack/kolla",children:"kolla"})," project ",(0,r.jsx)(n.a,{href:"#user-content-fnref-kl","data-footnote-backref":"","aria-label":"Back to reference 12",className:"data-footnote-backref",children:"\u21a9"})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-kl-2","data-footnote-backref":"","aria-label":"Back to reference 12-2",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"2"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-kl-3","data-footnote-backref":"","aria-label":"Back to reference 12-3",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"3"})]})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-ka",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://docs.openstack.org/kolla-ansible/latest/",children:"kolla-ansible"})," project ",(0,r.jsx)(n.a,{href:"#user-content-fnref-ka","data-footnote-backref":"","aria-label":"Back to reference 13",className:"data-footnote-backref",children:"\u21a9"})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ka-2","data-footnote-backref":"","aria-label":"Back to reference 13-2",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"2"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ka-3","data-footnote-backref":"","aria-label":"Back to reference 13-3",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"3"})]})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-ms",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/IEEE_802.1AE",children:"MACsec standard"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-ms","data-footnote-backref":"","aria-label":"Back to reference 14",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-lkc",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://www.kernel.org/doc/html/v4.10/crypto/index.html",children:"Linux Kernel Crypto API"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-lkc","data-footnote-backref":"","aria-label":"Back to reference 15",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-ie",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://www.ietf.org/",children:"Internet Engineering Task Force"})," (IETF) ",(0,r.jsx)(n.a,{href:"#user-content-fnref-ie","data-footnote-backref":"","aria-label":"Back to reference 16",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-ipwh",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://destcert.com/resources/why-the-is-ipsec-so-complicated/",children:"Why is IPsec so complicated"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-ipwh","data-footnote-backref":"","aria-label":"Back to reference 17",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-wgwp",children:["\n",(0,r.jsxs)(n.p,{children:["WireGuard ",(0,r.jsx)(n.a,{href:"https://www.wireguard.com/papers/wireguard.pdf",children:"white paper"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-wgwp","data-footnote-backref":"","aria-label":"Back to reference 18",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-oit",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://docs.ovn.org/en/latest/tutorials/ovn-ipsec.html",children:"OVN IPsec tutorial"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-oit","data-footnote-backref":"","aria-label":"Back to reference 19",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-neci1",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://gist.github.com/oblazek/466a9ae836f663f8349b71e76abaee7e",children:"Neutron + Cilium architecture example"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-neci1","data-footnote-backref":"","aria-label":"Back to reference 20",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-neci2",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/cilium/cilium/issues/13433",children:"Neutron + Cilium Proposal"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-neci2","data-footnote-backref":"","aria-label":"Back to reference 21",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-ca",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://docs.tigera.io/calico/latest/about",children:"Calico"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-ca","data-footnote-backref":"","aria-label":"Back to reference 22",className:"data-footnote-backref",children:"\u21a9"})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ca-2","data-footnote-backref":"","aria-label":"Back to reference 22-2",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"2"})]})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-caos",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://docs.tigera.io/calico/latest/getting-started/openstack/overview",children:"Calico for OpenStack"})," ",(0,r.jsx)(n.a,{href:"#user-content-fnref-caos","data-footnote-backref":"","aria-label":"Back to reference 23",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-ls",children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://libreswan.org/",children:"Libreswan"})," VPN software ",(0,r.jsx)(n.a,{href:"#user-content-fnref-ls","data-footnote-backref":"","aria-label":"Back to reference 24",className:"data-footnote-backref",children:"\u21a9"})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ls-2","data-footnote-backref":"","aria-label":"Back to reference 24-2",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"2"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ls-3","data-footnote-backref":"","aria-label":"Back to reference 24-3",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"3"})]})," ",(0,r.jsxs)(n.a,{href:"#user-content-fnref-ls-4","data-footnote-backref":"","aria-label":"Back to reference 24-4",className:"data-footnote-backref",children:["\u21a9",(0,r.jsx)(n.sup,{children:"4"})]})]}),"\n"]}),"\n"]}),"\n"]})]})}function f(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>s});var a=t(96540);const r={},o=a.createContext(r);function i(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6cdfddef.8a31cf20.js b/assets/js/6cdfddef.8a31cf20.js new file mode 100644 index 0000000000..90a8c0a094 --- /dev/null +++ b/assets/js/6cdfddef.8a31cf20.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[73281],{75478:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"operating-scs/components/monitoring/docs/status-page","title":"Status page monitoring","description":"Prerequisites","source":"@site/docs/04-operating-scs/components/monitoring/docs/status-page.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/status-page","permalink":"/docs/operating-scs/components/monitoring/docs/status-page","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/status-page.md","tags":[],"version":"current","frontMatter":{}}');var o=n(74848),i=n(28453);const a={},r="Status page monitoring",l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Local environment use case - KinD/K3s cluster deployed locally",id:"local-environment-use-case---kindk3s-cluster-deployed-locally",level:3},{value:"KinD",id:"kind",level:4},{value:"K3s",id:"k3s",level:4},{value:"OSISM use case - K3s cluster in OSISM deployment",id:"osism-use-case---k3s-cluster-in-osism-deployment",level:3},{value:"Deploy Status page monitoring",id:"deploy-status-page-monitoring",level:2},{value:"Access the Status page dashboards",id:"access-the-status-page-dashboards",level:3}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"status-page-monitoring",children:"Status page monitoring"})}),"\n",(0,o.jsx)(s.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsxs)(s.p,{children:["To test the Monitoring of the SCS Status page we expect running Kubernetes cluster that already contains\nSCS monitoring platform and Status page deployed in the dedicated ",(0,o.jsx)(s.code,{children:"status-page"})," namespace."]}),"\n",(0,o.jsx)(s.h3,{id:"local-environment-use-case---kindk3s-cluster-deployed-locally",children:"Local environment use case - KinD/K3s cluster deployed locally"}),"\n",(0,o.jsx)(s.h4,{id:"kind",children:"KinD"}),"\n",(0,o.jsxs)(s.p,{children:["Install the SCS monitoring solution into the KinD Kubernetes cluster following the instructions provided in\nthe ",(0,o.jsx)(s.a,{href:"/docs/operating-scs/components/monitoring/docs/quickstart",children:"quickstart guide"}),"."]}),"\n",(0,o.jsx)(s.h4,{id:"k3s",children:"K3s"}),"\n",(0,o.jsxs)(s.p,{children:["Install the SCS monitoring solution into the K3s Kubernetes cluster following the instructions provided in\nthe ",(0,o.jsx)(s.a,{href:"/docs/operating-scs/components/monitoring/docs/k3s",children:"k3s guide"}),"."]}),"\n",(0,o.jsx)(s.h3,{id:"osism-use-case---k3s-cluster-in-osism-deployment",children:"OSISM use case - K3s cluster in OSISM deployment"}),"\n",(0,o.jsxs)(s.p,{children:[(0,o.jsx)(s.a,{href:"https://osism.tech/docs/guides/deploy-guide/services/kubernetes",children:"OSISM"})," utilizes the k3s distribution of Kubernetes\nas a management cluster for the OSISM IaaS platform. This management cluster is then used as a host for\nthe SCS monitoring solution. Subsequently, the management cluster becomes an Observer cluster as it hosts\nthe SCS monitoring solution.\nFrom that point, the Observer cluster observes itself (i.e., k3s cluster control plane components and nodes) and is used\nfor observing the IaaS layer around the k3s cluster."]}),"\n",(0,o.jsxs)(s.p,{children:["In the case of the existing ",(0,o.jsx)(s.a,{href:"https://osism.tech/docs/release-notes/osism-7#703",children:"OSISM IaaS deployment >= 7.0.3"})," on\nbaremetal, ",(0,o.jsx)(s.a,{href:"https://osism.tech/docs/guides/other-guides/testbed",children:"testbed"})," or ",(0,o.jsx)(s.a,{href:"https://osism.tech/docs/guides/other-guides/cloud-in-a-box",children:"cloud in the box"}),"\nwe expect a management k3s Kubernetes cluster with the deployed SCS monitoring platform.\nIf your OSISM installation does not meet the above requirements, apply the following plays:"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"osism apply kubernetes\nosism apply kubernetes-monitoring\n"})}),"\n",(0,o.jsx)(s.h2,{id:"deploy-status-page-monitoring",children:"Deploy Status page monitoring"}),"\n",(0,o.jsx)(s.p,{children:"This step deploys the Grafana dashboards and instructs the monitoring stack to add the Status Page metrics targets into the Prometheus configuration:"}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack --reset-then-reuse-values -f status-page/status-page-values.yaml\n"})}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["Note: The ",(0,o.jsx)(s.code,{children:"--reset-then-reuse-values"})," option requires Helm v3.14.0 or later. Alternatively, you can use the original values\nby applying ",(0,o.jsx)(s.code,{children:"-f values-observer.yaml"}),", see full command: ",(0,o.jsx)(s.code,{children:"helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml -f status-page/status-page-values.yaml"})]}),"\n"]}),"\n",(0,o.jsx)(s.h3,{id:"access-the-status-page-dashboards",children:"Access the Status page dashboards"}),"\n",(0,o.jsx)(s.p,{children:"At this point, you should have the ability to access the Grafana UI, and Status page dashboards."}),"\n",(0,o.jsxs)(s.p,{children:["Log in to the Grafana UI and find the Status page dashboard in ",(0,o.jsx)(s.code,{children:"StatusPage"})," directory:"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"http://localhost:30000\n"})}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["Use the following credentials:","\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["username: ",(0,o.jsx)(s.code,{children:"admin"})]}),"\n",(0,o.jsxs)(s.li,{children:["password: ",(0,o.jsx)(s.code,{children:"pass"})]}),"\n"]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>r});var t=n(96540);const o={},i=t.createContext(o);function a(e){const s=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function r(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6d32cafb.e459fc70.js b/assets/js/6d32cafb.e459fc70.js new file mode 100644 index 0000000000..945442c3fa --- /dev/null +++ b/assets/js/6d32cafb.e459fc70.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[45978],{46910:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>d,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"iaas/guides/upgrade-guide/openstack","title":"OpenStack","description":"When upgrade the different OpenStack services, all containers must be","source":"@site/docs/02-iaas/guides/upgrade-guide/openstack.md","sourceDirName":"02-iaas/guides/upgrade-guide","slug":"/iaas/guides/upgrade-guide/openstack","permalink":"/docs/iaas/guides/upgrade-guide/openstack","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/openstack.md","tags":[],"version":"current","sidebarPosition":40,"frontMatter":{"sidebar_label":"OpenStack","sidebar_position":40},"sidebar":"docs","previous":{"title":"Logging & Monitoring","permalink":"/docs/iaas/guides/upgrade-guide/logging-monitoring"},"next":{"title":"Configuration Guide","permalink":"/docs/iaas/guides/configuration-guide/"}}');var a=s(74848),r=s(28453);const o={sidebar_label:"OpenStack",sidebar_position:40},d="OpenStack",t={},c=[];function p(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"openstack",children:"OpenStack"})}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsx)(n.p,{children:"When upgrade the different OpenStack services, all containers must be\nrestarted. When restarting the API services, there is a short downtime\nof the APIs. This downtime is usually less than 1 minute."})}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"OpenStack client"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply openstackclient\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Keystone"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull keystone\nosism apply -a upgrade keystone\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Glance"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull glance\nosism apply -a upgrade glance\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Designate"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull designate\nosism apply -a upgrade designate\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Placement"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull placement\nosism apply -a upgrade placement\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Cinder"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull cinder\nosism apply -a upgrade cinder\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Neutron"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull neutron\nosism apply -a upgrade neutron\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Nova"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull nova\nosism apply -a upgrade nova\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Octavia"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull octavia\nosism apply -a upgrade octavia\n"})}),"\n",(0,a.jsx)(n.p,{children:"9.1. Update amphora image"}),"\n",(0,a.jsx)(n.p,{children:"This step is only necessary if the Amphora Driver is used. If OVN is used as the driver,\nthis step is not necessary."}),"\n",(0,a.jsxs)(n.p,{children:["We provide regularly updated images for Octavia in\n",(0,a.jsx)(n.a,{href:"https://github.com/osism/openstack-octavia-amphora-image",children:"osism/openstack-octavia/amphora-image"}),".\nThe OSISM CLI can be used to upload the correct image depending on the OpenStack release\nused."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism manage image octavia\n"})}),"\n",(0,a.jsx)(n.p,{children:"9.2. Amphora rotation"}),"\n",(0,a.jsx)(n.p,{children:"This step is only necessary if the Amphora driver is used. If OVN is used as the driver,\nthis step is not necessary."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Horizon"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull horizon\nosism apply -a upgrade horizon\n"})}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>d});var i=s(96540);const a={},r=i.createContext(a);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6d890b23.e2d6a950.js b/assets/js/6d890b23.e2d6a950.js new file mode 100644 index 0000000000..2e3b5c43d2 --- /dev/null +++ b/assets/js/6d890b23.e2d6a950.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[84331],{6986:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"iaas/guides/operations-guide/manager/task","title":"Task","description":"List","source":"@site/docs/02-iaas/guides/operations-guide/manager/task.md","sourceDirName":"02-iaas/guides/operations-guide/manager","slug":"/iaas/guides/operations-guide/manager/task","permalink":"/docs/iaas/guides/operations-guide/manager/task","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/manager/task.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Task"},"sidebar":"docs","previous":{"title":"Logging","permalink":"/docs/iaas/guides/operations-guide/manager/log"},"next":{"title":"Ceph","permalink":"/docs/iaas/guides/operations-guide/ceph"}}');var a=t(74848),i=t(28453);const r={sidebar_label:"Task"},o="Task",d={},c=[{value:"List",id:"list",level:2},{value:"Broker reset",id:"broker-reset",level:2}];function l(e){const s={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(s.header,{children:(0,a.jsx)(s.h1,{id:"task",children:"Task"})}),"\n",(0,a.jsx)(s.h2,{id:"list",children:"List"}),"\n",(0,a.jsxs)(s.p,{children:["All running or scheduled tasks can be listed with ",(0,a.jsx)(s.code,{children:"osism task list"}),"."]}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{children:"+----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------+\n| Worker | ID | Name | Status | Start time | Arguments |\n|----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------|\n| celery@kolla-ansible | 8a553e69-c532-4ba0-a5d4-08a983bde692 | osism.tasks.kolla.run | ACTIVE | 2023-09-27 17:55:54.252250 | ['kolla', 'common', ['-e kolla_action=pull']] |\n| celery@osism-ansible | dba72dd5-1885-408f-9262-e0ded111a007 | osism.tasks.ansible.run | ACTIVE | 2023-09-27 18:00:31.215879 | ['generic', 'facts', []] |\n+----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------+\n"})}),"\n",(0,a.jsx)(s.h2,{id:"broker-reset",children:"Broker reset"}),"\n",(0,a.jsx)(s.p,{children:"Sometimes tasks get stuck. Due to the internal locks it is then not possible to re-execute\nplays with the same name. Also it is currently not possible to cancel already running tasks\n(is on the todo list). The only way to unblock the situation is to stop the manager service\nand start it again."}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{children:"cd /opt/manager\ndocker compose down\ndocker compose up -d\n"})}),"\n",(0,a.jsx)(s.p,{children:"In earlier versions of OSISM, the Redis service was not stateless. In these cases, it is\nnecessary to delete the Redis service volume before restarting the manager service."}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{children:"docker volume rm manager_redis\n"})})]})}function u(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,a.jsx)(s,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>o});var n=t(96540);const a={},i=n.createContext(a);function r(e){const s=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),n.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6d8acf16.f2bd0ec7.js b/assets/js/6d8acf16.f2bd0ec7.js new file mode 100644 index 0000000000..d2c42728d9 --- /dev/null +++ b/assets/js/6d8acf16.f2bd0ec7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[73374],{57607:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"operating-scs/components/monitoring/docs/tuning","title":"Tuning","description":"This page contains recommended parameters to set for the Thanos components to improve performance in terms of query time.","source":"@site/docs/04-operating-scs/components/monitoring/docs/tuning.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/tuning","permalink":"/docs/operating-scs/components/monitoring/docs/tuning","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/tuning.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Traces","permalink":"/docs/operating-scs/components/monitoring/docs/tracing"},"next":{"title":"SCS Health Monitor","permalink":"/docs/category/scs-health-monitor"}}');var s=o(74848),t=o(28453);const i={},a="Tuning",c={},l=[{value:"Query Frontend",id:"query-frontend",level:2},{value:"Compactor",id:"compactor",level:2},{value:"Query",id:"query",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"tuning",children:"Tuning"})}),"\n",(0,s.jsx)(n.p,{children:"This page contains recommended parameters to set for the Thanos components to improve performance in terms of query time.\nThe following parameters have already been incorporated into the upstream dNation monitoring repositories,\nand therefore are already included in the SCS observability deployment."}),"\n",(0,s.jsx)(n.h2,{id:"query-frontend",children:"Query Frontend"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'queryFrontend:\n extraFlags:\n - --query-range.split-interval=12h \n - --query-frontend.log-queries-longer-than=10s\n - --query-frontend.compress-responses\n - |-\n --query-range.response-cache-config="config":\n "max_size": "500MB"\n "max_size_items": 0\n "validity": 0s\n "type": "in-memory"\n'})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Notes on the parameters for query frontend:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"query-range.split-interval"})," - splits a long query into multiple short queries to improve query time. Default=24h."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"query-frontend.log-queries-longer-than=10s"})," - log queries running longer than 10s, which helps to identify new querries, which should be improved)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"query-frontend.compress-responses"})," - compress HTTP responses, helps with query time"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"query-range.response-cache-config"})," - cahcing is common solution to speed up response time(",(0,s.jsx)(n.a,{href:"https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/",children:"https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/"}),")"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"compactor",children:"Compactor"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"compactor:\n retentionResolutionRaw: 2d\n retentionResolution5m: 10d\n retentionResolution1h: 15d\n extraFlags:\n - --compact.concurrency=3\n - --downsample.concurrency=3\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Notes on the parameters for compactor:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"retentionResolutionRaw"})," - how long to retain raw samples in bucket. Minimum is two days, because just after 40 hours 5m downsampled data are created."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"retentionResolution5m"})," - how long to retain samples of resolution 1 (5 minutes) in bucket. Setting this to 0d will retain samples of this resolution forever. One hour downsampled data are created only after 10 days, so this is minimum if you want also 1h downsampled data."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"retentionResolution1h"})," - how long to retain samples of resolution 2 hour) in bucket."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delete-delay"})," - make sure you have set this parameter. It is time before a block marked for deletion is deleted from bucket. Note that deleting blocks immediately can cause query failures, if store gateway still has the block loaded, or compactor is ignoring the deletion because it's compacting the block at the same time. Default=48h."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"compact.concurrency"})," - number of goroutines to use when compacting groups(",(0,s.jsx)(n.a,{href:"https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/",children:"https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/"}),"). Default=1."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"downsample.concurrency"})," - number of goroutines to use when downsampling block(",(0,s.jsx)(n.a,{href:"https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/",children:"https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/"}),"). Default=1."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"query",children:"Query"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"query:\n extraFlags:\n - --query.auto-downsampling\n - --query.replica-label=prometheus_replica\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Notes on the parameters for query:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"query.auto-downsampling"})," - enable automatic adjustment (step / 5) to what source of data should be used in store gateways if no ",(0,s.jsx)(n.code,{children:"max_source_resolution"})," param is specified. Default step for range queries is equal to 1s and it is only used when step is not set in UI. Can be changed by setting ",(0,s.jsx)(n.code,{children:"--query.default-step"})," parameter. Hovewer, when you are using ",(0,s.jsx)(n.strong,{children:"Grafana"})," as your UI, the step is taken from ",(0,s.jsx)(n.code,{children:"min_step"}),". The preferred options is to set HTTP URL/FORM parameter ",(0,s.jsx)(n.code,{children:"max_source_resolution"})," to ",(0,s.jsx)(n.code,{children:"auto"}),", which selects downsample resolution automatically based on the query."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"query.replica-label"})," - labels to treat as a replica indicator along which data is deduplicated."]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>a});var r=o(96540);const s={},t=r.createContext(s);function i(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6db2ece2.082b688c.js b/assets/js/6db2ece2.082b688c.js new file mode 100644 index 0000000000..678df37b57 --- /dev/null +++ b/assets/js/6db2ece2.082b688c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[69356],{28191:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"iaas/guides/configuration-guide/inventory","title":"Inventory","description":"The inventory used for the environment is located in the inventory directory.","source":"@site/docs/02-iaas/guides/configuration-guide/inventory.md","sourceDirName":"02-iaas/guides/configuration-guide","slug":"/iaas/guides/configuration-guide/inventory","permalink":"/docs/iaas/guides/configuration-guide/inventory","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/inventory.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Inventory","sidebar_position":10},"sidebar":"docs","previous":{"title":"Configuration repository","permalink":"/docs/iaas/guides/configuration-guide/configuration-repository"},"next":{"title":"Manager","permalink":"/docs/iaas/guides/configuration-guide/manager"}}');var o=i(74848),t=i(28453);const s={sidebar_label:"Inventory",sidebar_position:10},a="Inventory",d={},c=[{value:"Manager",id:"manager",level:2},{value:"Reconciler",id:"reconciler",level:2},{value:"Host Vars",id:"host-vars",level:2},{value:"Group Vars",id:"group-vars",level:2},{value:"Define variable for all nodes",id:"define-variable-for-all-nodes",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",p:"p",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"inventory",children:"Inventory"})}),"\n",(0,o.jsxs)(n.p,{children:["The inventory used for the environment is located in the ",(0,o.jsx)(n.code,{children:"inventory"})," directory."]}),"\n",(0,o.jsxs)(n.p,{children:["How an inventory works is described in detail in the ",(0,o.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html",children:"Ansible documentation"}),".\nIn this chapter, we only deal with special features in the context of OSISM."]}),"\n",(0,o.jsx)(n.h2,{id:"manager",children:"Manager"}),"\n",(0,o.jsxs)(n.p,{children:["The manager has his own inventory which is used exclusively for the seed phase of the manager.\nIt is located in the directory ",(0,o.jsx)(n.code,{children:"environments/manager"}),". There is a ",(0,o.jsx)(n.code,{children:"hosts"})," file with only the\nmanager node in it."]}),"\n",(0,o.jsx)(n.h2,{id:"reconciler",children:"Reconciler"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{alt:"Inventory Reconciler",src:i(13519).A+"",width:"1366",height:"768"})}),"\n",(0,o.jsx)(n.h2,{id:"host-vars",children:"Host Vars"}),"\n",(0,o.jsx)(n.h2,{id:"group-vars",children:"Group Vars"}),"\n",(0,o.jsx)(n.h3,{id:"define-variable-for-all-nodes",children:"Define variable for all nodes"}),"\n",(0,o.jsxs)(n.p,{children:["The Ansible group ",(0,o.jsx)(n.code,{children:"all"})," is specifically used internally by OSISM, is reserved and is not supported\nfor additional variables. When variables are added in the configuration repository for the all group,\nthey are ignored. In OSISM the group ",(0,o.jsx)(n.code,{children:"generic"})," can be used to store variables for all nodes."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},13519:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/inventory-reconciler-acd822767003069a8935e016081383a5.png"},28453:(e,n,i)=>{i.d(n,{R:()=>s,x:()=>a});var r=i(96540);const o={},t=r.createContext(o);function s(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6ddb698c.2ddb76c9.js b/assets/js/6ddb698c.2ddb76c9.js new file mode 100644 index 0000000000..4fc5e6a7f1 --- /dev/null +++ b/assets/js/6ddb698c.2ddb76c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[65679],{87248:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"kaas/scs-0217","title":"scs-0217: Kubernetes cluster hardening","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/kaas/scs-0217.md","sourceDirName":"kaas","slug":"/kaas/scs-0217","permalink":"/standards/kaas/scs-0217","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks"},"next":{"title":"V1","permalink":"/standards/scs-0217-v1-cluster-hardening"}}');var r=s(74848),a=s(28453);const d={},c="scs-0217: Kubernetes cluster hardening",i={},l=[];function o(e){const t={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0217-kubernetes-cluster-hardening",children:"scs-0217: Kubernetes cluster hardening"})}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0217-v1-cluster-hardening",children:"scs-0217-v1"})}),(0,r.jsx)(t.td,{children:"Standard"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>c});var n=s(96540);const r={},a=n.createContext(r);function d(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6e45ed1a.7be08fca.js b/assets/js/6e45ed1a.7be08fca.js new file mode 100644 index 0000000000..cd24e96535 --- /dev/null +++ b/assets/js/6e45ed1a.7be08fca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[94604],{9249:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>r,contentTitle:()=>a,default:()=>f,frontMatter:()=>c,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"iaas/guides/configuration-guide/commons/certificates","title":"Certificates","description":"With the osism.commons.certificates role, it is possible to add custom CA certificates","source":"@site/docs/02-iaas/guides/configuration-guide/commons/certificates.md","sourceDirName":"02-iaas/guides/configuration-guide/commons","slug":"/iaas/guides/configuration-guide/commons/certificates","permalink":"/docs/iaas/guides/configuration-guide/commons/certificates","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/certificates.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Certificates"},"sidebar":"docs","previous":{"title":"Commons","permalink":"/docs/iaas/guides/configuration-guide/commons/"},"next":{"title":"Packages","permalink":"/docs/iaas/guides/configuration-guide/commons/packages"}}');var n=t(74848),o=t(28453);const c={sidebar_label:"Certificates"},a="Certificates",r={},d=[];function u(e){const i={a:"a",code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.header,{children:(0,n.jsx)(i.h1,{id:"certificates",children:"Certificates"})}),"\n",(0,n.jsxs)(i.p,{children:["With the ",(0,n.jsx)(i.code,{children:"osism.commons.certificates"})," role, it is possible to add custom CA certificates\non a node. The parameter should be used in the ",(0,n.jsx)(i.code,{children:"environments/configuration.yml"})," file."]}),"\n",(0,n.jsx)(i.pre,{children:(0,n.jsx)(i.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"certificates_ca:\n - name: custom.crt\n certificate: |\n -----BEGIN CERTIFICATE-----\n [...]\n -----END CERTIFICATE-----\n"})}),"\n",(0,n.jsxs)(i.p,{children:["The role is part of the bootstrap of a node. CA certificates can be added at a later\npoint in time via ",(0,n.jsx)(i.code,{children:"osism apply certificates"})," on a node."]}),"\n",(0,n.jsxs)(i.p,{children:["Further details on the use of self-signed certificates can be found in chapter\n",(0,n.jsx)(i.a,{href:"../loadbalancer#self-signed-certificates",children:"Self-signed certificates"}),"\nof the configuration guide."]})]})}function f(e={}){const{wrapper:i}={...(0,o.R)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,i,t)=>{t.d(i,{R:()=>c,x:()=>a});var s=t(96540);const n={},o=s.createContext(n);function c(e){const i=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),s.createElement(o.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6e84ad78.56a078df.js b/assets/js/6e84ad78.56a078df.js new file mode 100644 index 0000000000..464035edc8 --- /dev/null +++ b/assets/js/6e84ad78.56a078df.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[22270],{55572:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>d,default:()=>h,frontMatter:()=>c,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"iaas/scs-0120","title":"scs-0120: Cluster-API images","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0120.md","sourceDirName":"iaas","slug":"/iaas/scs-0120","permalink":"/standards/iaas/scs-0120","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0119-v1-rook-decision"},"next":{"title":"V1","permalink":"/standards/scs-0120-v1-capi-images"}}');var r=t(74848),a=t(28453);const c={},d="scs-0120: Cluster-API images",i={},o=[];function l(e){const s={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"scs-0120-cluster-api-images",children:"scs-0120: Cluster-API images"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0120-v1-capi-images",children:"scs-0120-v1"})}),(0,r.jsx)(s.td,{children:"Decision Record"}),(0,r.jsx)(s.td,{children:"Draft"}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>c,x:()=>d});var n=t(96540);const r={},a=n.createContext(r);function c(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6f1c571c.97bd125f.js b/assets/js/6f1c571c.97bd125f.js new file mode 100644 index 0000000000..f6d85722d0 --- /dev/null +++ b/assets/js/6f1c571c.97bd125f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[88071],{89111:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>r,contentTitle:()=>d,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"iaas/guides/deploy-guide/examples/index","title":"Examples","description":"","source":"@site/docs/02-iaas/guides/deploy-guide/examples/index.md","sourceDirName":"02-iaas/guides/deploy-guide/examples","slug":"/iaas/guides/deploy-guide/examples/","permalink":"/docs/iaas/guides/deploy-guide/examples/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/examples/index.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Examples"},"sidebar":"docs","previous":{"title":"OpenStack","permalink":"/docs/iaas/guides/deploy-guide/services/openstack"},"next":{"title":"Cloud in a Box","permalink":"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box"}}');var n=t(74848),i=t(28453);const o={sidebar_label:"Examples"},d="Examples",r={},l=[];function c(e){const s={h1:"h1",header:"header",...(0,i.R)(),...e.components};return(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"examples",children:"Examples"})})}function u(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>o,x:()=>d});var a=t(96540);const n={},i=a.createContext(n);function o(e){const s=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6f4a06ca.07e27793.js b/assets/js/6f4a06ca.07e27793.js new file mode 100644 index 0000000000..457f890af0 --- /dev/null +++ b/assets/js/6f4a06ca.07e27793.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[42372],{5957:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>d,default:()=>c,frontMatter:()=>o,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"iaas/guides/deploy-guide/manager","title":"Manager","description":"The prerequisite for deploying the Manager node is a Seed node. What a Seed node is","source":"@site/docs/02-iaas/guides/deploy-guide/manager.md","sourceDirName":"02-iaas/guides/deploy-guide","slug":"/iaas/guides/deploy-guide/manager","permalink":"/docs/iaas/guides/deploy-guide/manager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/manager.md","tags":[],"version":"current","sidebarPosition":20,"frontMatter":{"sidebar_label":"Manager","sidebar_position":20},"sidebar":"docs","previous":{"title":"Seed","permalink":"/docs/iaas/guides/deploy-guide/seed"},"next":{"title":"Provisioning","permalink":"/docs/iaas/guides/deploy-guide/provisioning"}}');var r=s(74848),i=s(28453);const o={sidebar_label:"Manager",sidebar_position:20},d="Manager",l={},a=[{value:"Deploy the manager service",id:"deploy-the-manager-service",level:2},{value:"Step 1: Create operator user",id:"step-1-create-operator-user",level:3},{value:"Step 2: Apply the network configuration",id:"step-2-apply-the-network-configuration",level:3},{value:"Step 3: Bootstrap the manager node",id:"step-3-bootstrap-the-manager-node",level:3},{value:"Step 4: Deploy the manager service",id:"step-4-deploy-the-manager-service",level:3},{value:"Step 5: Set vault password on the manager service",id:"step-5-set-vault-password-on-the-manager-service",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"manager",children:"Manager"})}),"\n",(0,r.jsx)(n.admonition,{type:"info",children:(0,r.jsxs)(n.p,{children:["The prerequisite for deploying the Manager node is a Seed node. What a Seed node is\nand how to prepare it is documented in the ",(0,r.jsx)(n.a,{href:"/docs/iaas/guides/deploy-guide/seed",children:"Seed chapter of the Deploy Guide"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["The Manager node serves as the central administration instance for managing the cloud environment.\nWith the help of Ansible and other OSISM-specific ",(0,r.jsx)(n.a,{href:"/docs/iaas/guides/concept-guide/",children:"components"}),", the entire\nlife cycle of the system is coordinated from here (installation, customization, upgrades, etc.)."]}),"\n",(0,r.jsx)(n.p,{children:"Requirements for the manager node:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The system should have the following hardware features","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"at least 64 GB RAM (We assume here that the monitoring services are also run on the manager.\nIf the manager node is only used for the sanager Service, 32 GByte is sufficient and\nwith 16 GByte it will probably also work."}),"\n",(0,r.jsx)(n.li,{children:"at least 256 GB hard disk space"}),"\n",(0,r.jsx)(n.li,{children:"the system should be initially and permanently accessible independently of the cloud environment\nitself from the seed node"}),"\n",(0,r.jsx)(n.li,{children:"the system should have direct access to the network areas of the individual server systems in the\ncloud environment"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["An Ubuntu version matching the OSISM version should be ",(0,r.jsx)(n.a,{href:"/docs/iaas/guides/deploy-guide/provisioning",children:"provisioned"})," on the system\n(typically the latest Ubuntu LTS version, a system based on one of the ",(0,r.jsx)(n.a,{href:"https://github.com/osism/node-image",children:"OSISM node images"}),"\nwould be ideal)"]}),"\n",(0,r.jsx)(n.li,{children:"No manual adjustments or installations should have been made on the system apart from the basic installation"}),"\n",(0,r.jsxs)(n.li,{children:["The system has to be accessible from the ",(0,r.jsx)(n.a,{href:"/docs/iaas/guides/deploy-guide/seed",children:"seed node"})," via SSH"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"deploy-the-manager-service",children:"Deploy the manager service"}),"\n",(0,r.jsxs)(n.p,{children:["Change into the ",(0,r.jsx)(n.code,{children:"environments/manager"})," directory of the configuration repository\non the seed node. The deployment of the seed node itself is documented in the\n",(0,r.jsx)(n.a,{href:"/docs/iaas/guides/deploy-guide/seed",children:"Deploy Guide for the seed node"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"cd environments/manager\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If you are working with Git branches, read ",(0,r.jsx)(n.a,{href:"/docs/iaas/guides/configuration-guide/manager",children:"the instructions"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-1-create-operator-user",children:"Step 1: Create operator user"}),"\n",(0,r.jsxs)(n.p,{children:["The operator user is created on each node. It is used as a service account for OSISM. All\ncontainers run with this user. Ansible also uses this user to access the nodes. Commands\non the manager node need to be run as this user. The name of the operator user is always ",(0,r.jsx)(n.code,{children:"dragon"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["With ",(0,r.jsx)(n.code,{children:"ANSIBLE_USER"})," the existing user account is set after the provsioning of the management\nnode. When using the ",(0,r.jsx)(n.a,{href:"https://github.com/osism/node-image",children:"osism/node-image"})," the user is ",(0,r.jsx)(n.code,{children:"osism"}),"\nand the password of this user is ",(0,r.jsx)(n.code,{children:"password"}),". If you install Ubuntu manually the user usually\nis ",(0,r.jsx)(n.code,{children:"ubuntu"}),". If you want to use any other user here, that's no problem. It is important that\nthis user has sudo rights. The password according to what you have set yourself."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"ANSIBLE_USER"})," parameter is only required when executing ",(0,r.jsx)(n.code,{children:"operator"})," play using the ",(0,r.jsx)(n.code,{children:"run.sh"}),"\nscript. After this step, the ",(0,r.jsx)(n.code,{children:"ANSIBLE_USER"})," is always set to ",(0,r.jsx)(n.code,{children:"dragon"})," in the ",(0,r.jsx)(n.code,{children:"run.sh"})," script.\nIt is therefore important to only set this parameter for exactly this step."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ANSIBLE_BECOME_ASK_PASS=True \\\nANSIBLE_ASK_VAULT_PASS=True \\\nANSIBLE_ASK_PASS=True \\\nANSIBLE_USER=osism \\\n./run.sh operator\n"})}),"\n",(0,r.jsxs)(n.p,{children:["When the ",(0,r.jsx)(n.code,{children:"./run.sh operator"})," is executed, the following prompts are displayed:"]}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{style:{textAlign:"left"},children:"Prompt"}),(0,r.jsx)(n.th,{style:{textAlign:"left"},children:"Value"}),(0,r.jsx)(n.th,{style:{textAlign:"left"},children:"Comment"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"SSH password:"})}),(0,r.jsxs)(n.td,{style:{textAlign:"left"},children:["Password so that the ",(0,r.jsx)(n.code,{children:"ANSIBLE_USER"})," can login"]}),(0,r.jsxs)(n.td,{style:{textAlign:"left"},children:["Enabled by ",(0,r.jsx)(n.code,{children:"ANSIBLE_ASK_PASS"})]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"BECOME password[defaults to SSH password]:"})}),(0,r.jsxs)(n.td,{style:{textAlign:"left"},children:["Password so that the ",(0,r.jsx)(n.code,{children:"ANSIBLE_USER"})," can use ",(0,r.jsx)(n.code,{children:"sudo"})]}),(0,r.jsxs)(n.td,{style:{textAlign:"left"},children:["Enabled by ",(0,r.jsx)(n.code,{children:"ANSIBLE_BECOME_ASK_PASS"})]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"Vault password:"})}),(0,r.jsxs)(n.td,{style:{textAlign:"left"},children:["Value of ",(0,r.jsx)(n.code,{children:"secrets/vaultpass"})]}),(0,r.jsxs)(n.td,{style:{textAlign:"left"},children:["Enabled by ",(0,r.jsx)(n.code,{children:"ANSIBLE_ASK_VAULT_PASS"})]})]})]})]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Useful information if something goes wrong in the step described"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["If a password is required to login to the manager node, ",(0,r.jsx)(n.code,{children:"ANSIBLE_ASK_PASS=True"})," must be set."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["If an SSH key is required to login to the manager node, the key has to be added on the manager\nnode to ",(0,r.jsx)(n.code,{children:"~/.ssh/authorized_keys"})," in the home directory of the user specified as ",(0,r.jsx)(n.code,{children:"ANSIBLE_USER"})," first."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["If the error ",(0,r.jsx)(n.code,{children:"ERROR! Attempting to decrypt but no vault secrets found"})," occurs, ",(0,r.jsx)(n.code,{children:"ANSIBLE_ASK_VAULT_PASS=True"}),"\nhas to be set."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["If the error ",(0,r.jsx)(n.code,{children:"/bin/sh: 1: /usr/bin/python: not found occurs"}),", Python has to be installed first on\nthe manager node:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ANSIBLE_USER=osism ./run.sh python3\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["If you receive the following error message ",(0,r.jsx)(n.code,{children:"ssh: Too many authentication failures"})," set\n",(0,r.jsx)(n.code,{children:"ANSIBLE_SSH_ARGS"})," environment variable to use only the operator ssh key for authentication."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:'export ANSIBLE_SSH_ARGS="-o IdentitiesOnly=yes"\n'})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["The warning message ",(0,r.jsx)(n.code,{children:"[WARNING]: running playbook inside collection osism.manager"})," can be ignored"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"If Ansible Vault is used, let Ansible ask for the Vault password:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"export ANSIBLE_ASK_VAULT_PASS=True\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Details on all parameters can be found in\n",(0,r.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/reference_appendices/config.html",children:"Ansible Configuration Settings"}),"\nin the Ansible documentation."]}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{style:{textAlign:"left"},children:"Environment variable"}),(0,r.jsx)(n.th,{style:{textAlign:"left"},children:"Type"}),(0,r.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"ANSIBLE_ASK_PASS"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Boolean"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"This controls whether an Ansible playbook should prompt for a login password. If using SSH keys for authentication, you probably do not need to change this setting."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"ANSIBLE_ASK_VAULT_PASS"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Boolean"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"This controls whether an Ansible playbook should prompt for a vault password."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"ANSIBLE_BECOME_ASK_PASS"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Boolean"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Toggle to prompt for privilege escalation password."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"ANSIBLE_SSH_ARGS"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"String"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"If set, this will override the Ansible default ssh arguments."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"ANSIBLE_USER"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"String"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"The user Ansible \u2018logs in\u2019 as."})]})]})]}),"\n",(0,r.jsxs)(n.p,{children:["To verify the proper creation of the operator user, use the private key file ",(0,r.jsx)(n.code,{children:"id_rsa.operator"}),". Make\nsure you purge all keys from ssh-agent identity cache using ",(0,r.jsx)(n.code,{children:"ssh-add -D"}),". You can print the list\nusing ",(0,r.jsx)(n.code,{children:"ssh-add -l"}),". The list should be empty."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ssh-add -D\nssh -o IdentitiesOnly=yes -i id_rsa.operator dragon@YOUR_MANAGER_NODE\n"})}),"\n",(0,r.jsx)(n.h3,{id:"step-2-apply-the-network-configuration",children:"Step 2: Apply the network configuration"}),"\n",(0,r.jsxs)(n.p,{children:["Most of the parameters required for Ansible (",(0,r.jsx)(n.code,{children:"ANSIBLE_BECOME_ASK_PASS"}),", ",(0,r.jsx)(n.code,{children:"ANSIBLE_ASK_PASS"}),", ",(0,r.jsx)(n.code,{children:"ANSIBLE_USER"}),", ...)\nin the previous step are no longer necessary. If Ansible Vault is used, however, ",(0,r.jsx)(n.code,{children:"ANSIBLE_ASK_VAULT_PASS"}),"\nmust still be set."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"export ANSIBLE_ASK_VAULT_PASS=True\n"})}),"\n",(0,r.jsxs)(n.p,{children:["To prevent recurring installation of Ansible Collections, ",(0,r.jsx)(n.code,{children:"export INSTALL_ANSIBLE_ROLES=False"})," can be set."]}),"\n",(0,r.jsx)(n.p,{children:"The network configuration, already present on a node should be backuped before this step.\nThen you can deploy the network configuration with the network role."}),"\n",(0,r.jsxs)(n.p,{children:["Have a look to the ",(0,r.jsx)(n.a,{href:"/docs/iaas/guides/configuration-guide/network",children:"network documentation"})," and configure it before running this playbook."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"./run.sh network\n"})}),"\n",(0,r.jsx)(n.p,{children:"Upon completion of the network configuration, a node reboot should be performed to ensure the configuration\nis functional and reboot safe. Since network services are not restarted automatically, later changes to the\nnetwork configuration are not effective without a manual apply of the network configuration or reboot of the\nnodes."}),"\n",(0,r.jsx)(n.h3,{id:"step-3-bootstrap-the-manager-node",children:"Step 3: Bootstrap the manager node"}),"\n",(0,r.jsxs)(n.p,{children:["Most of the parameters required for Ansible (",(0,r.jsx)(n.code,{children:"ANSIBLE_BECOME_ASK_PASS"}),", ",(0,r.jsx)(n.code,{children:"ANSIBLE_ASK_PASS"}),", ",(0,r.jsx)(n.code,{children:"ANSIBLE_USER"}),", ...)\nin the previous step are no longer necessary."]}),"\n",(0,r.jsxs)(n.p,{children:["If Ansible Vault is used, however, ",(0,r.jsx)(n.code,{children:"export ANSIBLE_ASK_VAULT_PASS=True"})," must still be set."]}),"\n",(0,r.jsxs)(n.p,{children:["To prevent recurring installation of Ansible Collections, ",(0,r.jsx)(n.code,{children:"export INSTALL_ANSIBLE_ROLES=False"})," can be set.\nThis is recommended."]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Bootstrap the manager node."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"./run.sh bootstrap\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Reboot the manager node."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"./run.sh reboot\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-4-deploy-the-manager-service",children:"Step 4: Deploy the manager service"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Transfer the configuration repository."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"./run.sh configuration\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Deploy the Traefik service. This is optional and only necessary if the Traefik service is to be used."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"./run.sh traefik\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Deploy the Netbox service. This is optional and only necessary if the Netbox service is to be used."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"./run.sh netbox\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Deploy the manager service.\nHave a look to the ",(0,r.jsx)(n.a,{href:"/docs/iaas/guides/configuration-guide/manager",children:"manager documentation"})," and configure it before running this playbook."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"./run.sh manager\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-5-set-vault-password-on-the-manager-service",children:"Step 5: Set vault password on the manager service"}),"\n",(0,r.jsxs)(n.p,{children:["Finally, the Ansible Vault password is made known on the manager node. Before that, log in to the manager node\nwith the ",(0,r.jsx)(n.code,{children:"dragon"})," user."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ssh -o IdentitiesOnly=yes -i id_rsa.operator dragon@YOUR_MANAGER_NODE\nosism set vault password\n"})}),"\n",(0,r.jsx)(n.p,{children:"Ready. The manager is now prepared, and you can continue with the bootstrap of the other nodes.\nThe seed node used until here is now no longer necessary."})]})}function c(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>d});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6fc3ae76.848f939b.js b/assets/js/6fc3ae76.848f939b.js new file mode 100644 index 0000000000..3ccba2b132 --- /dev/null +++ b/assets/js/6fc3ae76.848f939b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[644],{93774:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>d,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"iaas/scs-0125","title":"scs-0125: Secure Connections","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0125.md","sourceDirName":"iaas","slug":"/iaas/scs-0125","permalink":"/standards/iaas/scs-0125","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0124-w1-security-of-iaas-service-software"},"next":{"title":"V1","permalink":"/standards/scs-0125-v1-secure-connections"}}');var r=t(74848),c=t(28453);const a={},d="scs-0125: Secure Connections",i={},o=[];function l(e){const s={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"scs-0125-secure-connections",children:"scs-0125: Secure Connections"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0125-v1-secure-connections",children:"scs-0125-v1"})}),(0,r.jsx)(s.td,{children:"Standard"}),(0,r.jsx)(s.td,{children:"Draft"}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>a,x:()=>d});var n=t(96540);const r={},c=n.createContext(r);function a(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6fe5bbf3.525f7f31.js b/assets/js/6fe5bbf3.525f7f31.js new file mode 100644 index 0000000000..d71510cd2f --- /dev/null +++ b/assets/js/6fe5bbf3.525f7f31.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[18096],{18254:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"iaas/guides/configuration-guide/rook","title":"Ceph via Rook (technical preview)","description":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/","source":"@site/docs/02-iaas/guides/configuration-guide/rook.md","sourceDirName":"02-iaas/guides/configuration-guide","slug":"/iaas/guides/configuration-guide/rook","permalink":"/docs/iaas/guides/configuration-guide/rook","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/rook.md","tags":[],"version":"current","sidebarPosition":31,"frontMatter":{"sidebar_label":"Ceph via Rook (technical preview)","sidebar_position":31},"sidebar":"docs","previous":{"title":"Skyline","permalink":"/docs/iaas/guides/configuration-guide/openstack/skyline"},"next":{"title":"Rookify (technical preview)","permalink":"/docs/iaas/guides/configuration-guide/rookify"}}');var r=n(74848),t=n(28453);const a={sidebar_label:"Ceph via Rook (technical preview)",sidebar_position:31},i="Ceph via Rook (technical preview)",l={},c=[{value:"Unique Identifier",id:"unique-identifier",level:2},{value:"Client",id:"client",level:2},{value:"Network configuration",id:"network-configuration",level:2},{value:"Configuring <code>addressRanges</code>",id:"configuring-addressranges",level:3},{value:"Configuring encryption, compression, msgr2",id:"configuring-encryption-compression-msgr2",level:3},{value:"Flexible approach using <code>rook_network</code>",id:"flexible-approach-using-rook_network",level:3},{value:"RGW service - CephObjectStore CRD",id:"rgw-service---cephobjectstore-crd",level:2},{value:"Cephfs - CephFilesystem CRD",id:"cephfs---cephfilesystem-crd",level:2},{value:"Extra pools - CephBlockPool CRD",id:"extra-pools---cephblockpool-crd",level:2},{value:"Storage configuration",id:"storage-configuration",level:2},{value:"Deploy OSDs on all nodes and found devices",id:"deploy-osds-on-all-nodes-and-found-devices",level:3},{value:"Deploy OSDs on specific nodes and devices based on a device filter",id:"deploy-osds-on-specific-nodes-and-devices-based-on-a-device-filter",level:3},{value:"Deploy OSDs on specific nodes and devices based on device names",id:"deploy-osds-on-specific-nodes-and-devices-based-on-device-names",level:3},{value:"Flexible approach using <code>rook_storage</code>",id:"flexible-approach-using-rook_storage",level:3},{value:"Encrypted OSDs",id:"encrypted-osds",level:3},{value:"Dashboard",id:"dashboard",level:2},{value:"Enable dashboard and configure ssl and ports",id:"enable-dashboard-and-configure-ssl-and-ports",level:3},{value:"Rook Cluster Name",id:"rook-cluster-name",level:2},{value:"Kubernetes Namespaces",id:"kubernetes-namespaces",level:2},{value:"Number and Placement of Ceph Daemons",id:"number-and-placement-of-ceph-daemons",level:2},{value:"Crash Collector",id:"crash-collector",level:2},{value:"Log Collector",id:"log-collector",level:2},{value:"Ceph Config",id:"ceph-config",level:2},{value:"Second Ceph cluster",id:"second-ceph-cluster",level:2},{value:"Helm Value File",id:"helm-value-file",level:2}];function d(e){const o={a:"a",admonition:"admonition",code:"code",del:"del",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(o.header,{children:(0,r.jsx)(o.h1,{id:"ceph-via-rook-technical-preview",children:"Ceph via Rook (technical preview)"})}),"\n",(0,r.jsxs)(o.p,{children:["The official Ceph documentation is located on ",(0,r.jsx)(o.a,{href:"https://docs.ceph.com/en/latest/rados/configuration/",children:"https://docs.ceph.com/en/latest/rados/configuration/"})]}),"\n",(0,r.jsxs)(o.p,{children:["It is ",(0,r.jsx)(o.strong,{children:"strongly advised"})," to use the documentation for the version being used."]}),"\n",(0,r.jsxs)(o.ul,{children:["\n",(0,r.jsxs)(o.li,{children:["Quincy - ",(0,r.jsx)(o.a,{href:"https://docs.ceph.com/en/quincy/rados/configuration/",children:"https://docs.ceph.com/en/quincy/rados/configuration/"})]}),"\n",(0,r.jsxs)(o.li,{children:["Reef - ",(0,r.jsx)(o.a,{href:"https://docs.ceph.com/en/reef/rados/configuration/",children:"https://docs.ceph.com/en/reef/rados/configuration/"})]}),"\n"]}),"\n",(0,r.jsx)(o.h2,{id:"unique-identifier",children:"Unique Identifier"}),"\n",(0,r.jsx)(o.p,{children:"The File System ID is a unique identifier for the cluster."}),"\n",(0,r.jsxs)(o.p,{children:[(0,r.jsxs)(o.del,{children:["The identifier is set via the parameter ",(0,r.jsx)(o.code,{children:"fsid"})," in ",(0,r.jsx)(o.code,{children:"environments/rook/configuration.yml"})]}),"\n",(0,r.jsxs)(o.del,{children:["and must be unique. It can be generated with ",(0,r.jsx)(o.code,{children:"uuidgen"}),"."]})]}),"\n",(0,r.jsxs)(o.p,{children:["It is generated automatically by the ",(0,r.jsx)(o.a,{href:"/docs/iaas/guides/deploy-guide/services/rook",children:"Rook Deployment"}),"."]}),"\n",(0,r.jsxs)(o.p,{children:["TODO: To evaluate if we want and can pass a ",(0,r.jsx)(o.code,{children:"fsid"}),". This is no out-of-the-box Rook feature, though."]}),"\n",(0,r.jsx)(o.h2,{id:"client",children:"Client"}),"\n",(0,r.jsx)(o.p,{children:(0,r.jsxs)(o.del,{children:["The ",(0,r.jsx)(o.code,{children:"client.admin"})," keyring is placed in the file ",(0,r.jsx)(o.code,{children:"environments/infrastructure/files/ceph/ceph.client.admin.keyring"}),"."]})}),"\n",(0,r.jsx)(o.p,{children:"There is no real Ceph client installed on the manager node, but a wrapper to enter the Rook Toolbox can be installed."}),"\n",(0,r.jsx)(o.p,{children:"If the namespace of the rook cluster was changed this needs to be reflected as well as the install type of the client."}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/infrastructure/configuration.yml"',children:"cephclient_install_type: rook\n\ncephclient_rook_namespace: rook-ceph\n"})}),"\n",(0,r.jsx)(o.p,{children:"After successfully configuring the environment for the client, run the installation:"}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-bash",children:"osism apply cephclient\n"})}),"\n",(0,r.jsxs)(o.p,{children:["This will try to detect a prior installation of a Ceph client with the install type ",(0,r.jsx)(o.code,{children:"container"})," or ",(0,r.jsx)(o.code,{children:"package"})," and cleanup that previous installation."]}),"\n",(0,r.jsx)(o.h2,{id:"network-configuration",children:"Network configuration"}),"\n",(0,r.jsxs)(o.p,{children:["Some useful ansible variables for the options from the ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/?h=#network-configuration-settings",children:"Rook Network Configuration Settings"})," are available.\nIf you want complete flexibility, you can also use the ",(0,r.jsx)(o.code,{children:"rook_network"})," variable which abstracts all settings from ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest/CRDs/Cluster/ceph-cluster-crd/#network-configuration-settings",children:"Rook Network Configuration Settings"}),"."]}),"\n",(0,r.jsxs)(o.h3,{id:"configuring-addressranges",children:["Configuring ",(0,r.jsx)(o.code,{children:"addressRanges"})]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_network_public: "192.168.16.0/24"\nrook_network_cluster: "192.168.17.0/24"\n'})}),"\n",(0,r.jsx)(o.h3,{id:"configuring-encryption-compression-msgr2",children:"Configuring encryption, compression, msgr2"}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_network_encryption: true\nrook_network_compression: true\nrook_network_require_msgr2: false\n"})}),"\n",(0,r.jsxs)(o.h3,{id:"flexible-approach-using-rook_network",children:["Flexible approach using ",(0,r.jsx)(o.code,{children:"rook_network"})]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_network_encryption: true\nrook_network_compression: true\nrook_network_require_msgr2: false\nrook_network_public: "192.168.16.0/20"\nrook_network_cluster: "{{ rook_network_public }}"\nrook_network:\n connections:\n # Whether to encrypt the data in transit across the wire to prevent eavesdropping the data on the network.\n # The default is false. When encryption is enabled, all communication between clients and Ceph daemons, or between Ceph daemons will be encrypted.\n # When encryption is not enabled, clients still establish a strong initial authentication and data integrity is still validated with a crc check.\n # IMPORTANT: Encryption requires the 5.11 kernel for the latest nbd and cephfs drivers. Alternatively for testing only,\n # you can set the "mounter: rbd-nbd" in the rbd storage class, or "mounter: fuse" in the cephfs storage class.\n # The nbd and fuse drivers are *not* recommended in production since restarting the csi driver pod will disconnect the volumes.\n encryption:\n enabled: "{{ rook_network_encryption }}"\n # Whether to compress the data in transit across the wire. The default is false.\n # Requires Ceph Quincy (v17) or newer. Also see the kernel requirements above for encryption.\n compression:\n enabled: "{{ rook_network_compression }}"\n # Whether to require communication over msgr2. If true, the msgr v1 port (6789) will be disabled\n # and clients will be required to connect to the Ceph cluster with the v2 port (3300).\n # Requires a kernel that supports msgr v2 (kernel 5.11 or CentOS 8.4 or newer).\n requireMsgr2: "{{ rook_network_require_msgr2 }}"\n # enable host networking\n provider: host\n addressRanges:\n public:\n - "{{ rook_network_public }}"\n cluster:\n - "{{ rook_network_cluster }}"\n'})}),"\n",(0,r.jsx)(o.h2,{id:"rgw-service---cephobjectstore-crd",children:"RGW service - CephObjectStore CRD"}),"\n",(0,r.jsx)(o.admonition,{type:"info",children:(0,r.jsxs)(o.p,{children:["OpenStack integration between Keystone/Swift and Rook is currently missing upstream in Rook. Please have a look at ",(0,r.jsx)(o.a,{href:"https://github.com/orgs/SovereignCloudStack/projects/18/views/1?layout=board&pane=issue&itemId=63889060",children:"#1027"})," to get the current status of the integration in OSISM."]})}),"\n",(0,r.jsxs)(o.p,{children:["Have a look at ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest/CRDs/Object-Storage/ceph-object-store-crd/",children:"CephObjectStore CRD Spec"})," for details on how to configure the RGW service."]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_cephobjectstore_default_name: rgw\nrook_cephobjectstore_replicated_default_size: 3\nrook_cephobjectstore_erasurecoded_default_datachunks: 2\nrook_cephobjectstore_erasurecoded_default_codingchunks: 1\nrook_cephobjectstore_failuredomain: host\nrook_cephobjectstore_default_port: 8081\nrook_cephobjectstore_preservepoolsondelete: true\nrook_cephobjectstore_keystone_acceptedRoles: []\n # - admin\n # - member\nrook_cephobjectstore_keystone_implicitTenants: ""\nrook_cephobjectstore_keystone_revocationInterval: 1200\nrook_cephobjectstore_keystone_tokenCacheSize: 1000\nrook_cephobjectstore_keystone_url: ""\nrook_cephobjectstore_swift_accountInUrl: true\nrook_cephobjectstore_swift_urlPrefix: ""\nrook_cephobjectstore_swift_versioningEnabled: true\nrook_cephobjectstore_s3_authKeystone: true\nrook_cephobjectstore_s3_enable: true\n# name of the secret that provides admin user credentials needs to be in same namespace\nrook_cephobjectstore_keystone_serviceUserSecretName: ceph-rgw-usersecret\n# the following settings belong to the usersecret\nrook_cephobjectstore_keystone_auth_type: ""\nrook_cephobjectstore_keystone_identity_api_version: 3\nrook_cephobjectstore_keystone_password: ""\nrook_cephobjectstore_keystone_project_domain_name: "Default"\nrook_cephobjectstore_keystone_project_name: ""\nrook_cephobjectstore_keystone_user_domain_name: "Default"\nrook_cephobjectstore_keystone_username: ""\nrook_cephobjectstores:\n - name: "{{ rook_cephobjectstore_default_name }}"\n spec:\n metadataPool:\n failureDomain: "{{ rook_cephobjectstore_failuredomain }}"\n replicated:\n size: "{{ rook_cephobjectstore_replicated_default_size }}"\n # erasureCoded:\n # dataChunks: "{{ rook_cephobjectstore_erasurecoded_default_datachunks }}"\n # codingChunks: "{{ rook_cephobjectstore_erasurecoded_default_codingchunks }}"\n dataPool:\n failureDomain: "{{ rook_cephobjectstore_failuredomain }}"\n replicated:\n size: "{{ rook_cephobjectstore_replicated_default_size }}"\n # erasureCoded:\n # dataChunks: "{{ rook_cephobjectstore_erasurecoded_default_datachunks }}"\n # codingChunks: "{{ rook_cephobjectstore_erasurecoded_default_codingchunks }}"\n preservePoolsOnDelete: "{{ rook_cephobjectstore_preservepoolsondelete }}"\n gateway:\n port: "{{ rook_cephobjectstore_default_port }}"\n resources: "{{ rook_resources_cephobjecstore }}"\n # securePort: 443\n # sslCertificateRef:\n instances: 1\n priorityClassName: system-cluster-critical\n placement: "{{ rook_placement_cephobjectstore }}"\n annotations: "{{ rook_annotations_cephobjecstore }}"\n auth:\n keystone:\n acceptedRoles: "{{ rook_cephobjectstore_keystone_acceptedRoles }}"\n implicitTenants: "{{ rook_cephobjectstore_keystone_implicitTenants }}"\n revocationInterval: "{{ rook_cephobjectstore_keystone_revocationInterval }}"\n serviceUserSecretName: "{{ rook_cephobjectstore_keystone_serviceUserSecretName }}"\n tokenCacheSize: "{{ rook_cephobjectstore_keystone_tokenCacheSize }}"\n url: "{{ rook_cephobjectstore_keystone_url }}"\n protocols:\n swift:\n accountInUrl: "{{ rook_cephobjectstore_swift_accountInUrl }}"\n urlPrefix: "{{ rook_cephobjectstore_swift_urlPrefix }}"\n versioningEnabled: "{{ rook_cephobjectstore_swift_versioningEnabled }}"\n s3:\n authKeystone: "{{ rook_cephobjectstore_s3_authKeystone }}"\n enable: "{{ rook_cephobjectstore_s3_enable }}"\n storageClass:\n enabled: false\n'})}),"\n",(0,r.jsx)(o.h2,{id:"cephfs---cephfilesystem-crd",children:"Cephfs - CephFilesystem CRD"}),"\n",(0,r.jsxs)(o.p,{children:["Have a look at ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest/CRDs/Shared-Filesystem/ceph-filesystem-crd/",children:"CephFilesystem CRD Spec"})," for details on how to configure Cephfs."]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_cephfilesystem_default_name: cephfs\nrook_cephfilesystem_replicated_default_size: 3\nrook_cephfilesystem_erasurecoded_default_datachunks: 2\nrook_cephfilesystem_erasurecoded_default_codingchunks: 1\nrook_cephfilesystem_default_metadatapool_parameters_compression_mode: none\nrook_cephfilesystem_default_datapool_parameters_compression_mode: none\nrook_cephfilesystems:\n - name: "{{ rook_cephfilesystem_default_name }}"\n spec:\n metadataPool:\n failureDomain: host\n # The metadata pool spec must use replication.\n replicated:\n size: "{{ rook_cephfilesystem_replicated_default_size }}"\n requireSafeReplicaSize: true\n parameters:\n compression_mode: "{{ rook_cephfilesystem_default_datapool_parameters_compression_mode }}"\n # target_size_ratio: ".5"\n dataPools:\n - failureDomain: host\n # The data pool spec can use replication or erasure coding.\n replicated:\n size: "{{ rook_cephfilesystem_replicated_default_size }}"\n requireSafeReplicaSize: true\n # erasureCoded:\n # dataChunks: "{{ rook_cephfilesystem_erasurecoded_default_datachunks }}"\n # codingChunks: "{{ rook_cephfilesystem_erasurecoded_default_codingchunks }}"\n name: data0\n parameters:\n compression_mode: "{{ rook_cephfilesystem_default_datapool_parameters_compression_mode }}"\n # target_size_ratio: ".5"\n metadataServer:\n activeCount: "{{ rook_mds_count }}"\n activeStandby: true\n resources: "{{ rook_resources_cephfilesystem }}"\n priorityClassName: system-cluster-critical"\n placement: "{{ rook_placement_cephfilesystem }}"\n annotations: "{{ rook_annotations_cephfilesystem }}"\n storageClass:\n enabled: false\n'})}),"\n",(0,r.jsx)(o.h2,{id:"extra-pools---cephblockpool-crd",children:"Extra pools - CephBlockPool CRD"}),"\n",(0,r.jsxs)(o.p,{children:["Extra pools can be defined via the ",(0,r.jsx)(o.code,{children:"rook_cephblockpools"})," parameter. Be sure to also include the default pools.\nThey will use the default values from the ",(0,r.jsx)(o.code,{children:"rook_cephblockpool_*"})," variables."]}),"\n",(0,r.jsxs)(o.p,{children:["Have a look at ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Block-Storage/ceph-block-pool-crd/#spec",children:"CephBlockPool CRD Spec"})," for details."]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_cephblockpool_replicated_default_size: 3\nrook_cephblockpool_erasurecoded_default_datachunks: 2\nrook_cephblockpool_erasurecoded_default_codingchunks: 1\nrook_cephblockpool_default_min_size: "0"\nrook_cephblockpool_default_pg_num: "128"\nrook_cephblockpools:\n # default pools\n - name: backups\n spec:\n failureDomain: host\n replicated:\n size: "{{ rook_cephblockpool_replicated_default_size }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n - name: volumes\n spec:\n failureDomain: host\n replicated:\n size: "{{ rook_cephblockpool_replicated_default_size }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n - name: images\n spec:\n failureDomain: host\n replicated:\n size: "{{ rook_cephblockpool_replicated_default_size }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n - name: metrics\n spec:\n failureDomain: host\n replicated:\n size: "{{ rook_cephblockpool_replicated_default_size }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n - name: vms\n spec:\n failureDomain: host\n replicated:\n size: "{{ rook_cephblockpool_replicated_default_size }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n # extra pools\n - name: extra1\n spec:\n failureDomain: host\n replicated:\n size: "{{ rook_cephblockpool_replicated_default_size }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n - name: extra2\n spec:\n failureDomain: host\n erasureCoded:\n dataChunks: "{{ rook_cephblockpool_erasurecoded_default_datachunks }}"\n codingChunks: "{{ rook_cephblockpool_erasurecoded_default_codingchunks }}"\n parameters:\n min_size: "{{ rook_cephblockpool_default_min_size }}"\n pg_num: "{{ rook_cephblockpool_default_pg_num }}"\n pgp_num: "{{ rook_cephblockpool_default_pg_num }}"\n storageClass:\n enabled: false\n'})}),"\n",(0,r.jsx)(o.h2,{id:"storage-configuration",children:"Storage configuration"}),"\n",(0,r.jsx)(o.admonition,{type:"info",children:(0,r.jsx)(o.p,{children:"In the default setup, no OSD will be deployed (better safe than sorry approach)."})}),"\n",(0,r.jsxs)(o.p,{children:["You have to pass a storage configuration via ",(0,r.jsx)(o.code,{children:"environments/rook/configuration.yml"}),"."]}),"\n",(0,r.jsxs)(o.p,{children:["Some useful ansible variables for the options from the ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/#storage-selection-settings",children:"Rook Storage Selection Settings"})," are available.\nIf you want complete flexibility, you can also use the ",(0,r.jsx)(o.code,{children:"rook_storage"})," variable which abstracts all settings from ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/#storage-selection-settings",children:"Rook Storage Selection Settings"}),"."]}),"\n",(0,r.jsx)(o.h3,{id:"deploy-osds-on-all-nodes-and-found-devices",children:"Deploy OSDs on all nodes and found devices"}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_storage_useallnodes: true\nrook_storage_usealldevices: true\n"})}),"\n",(0,r.jsx)(o.h3,{id:"deploy-osds-on-specific-nodes-and-devices-based-on-a-device-filter",children:"Deploy OSDs on specific nodes and devices based on a device filter"}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_storage_useallnodes: false\nrook_storage_usealldevices: false\nrook_storage_devicefilter: "^sd[b-c]"\nrook_storage_nodes:\n - name: "testbed-node-0"\n - name: "testbed-node-1"\n - name: "testbed-node-2"\n'})}),"\n",(0,r.jsx)(o.h3,{id:"deploy-osds-on-specific-nodes-and-devices-based-on-device-names",children:"Deploy OSDs on specific nodes and devices based on device names"}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_storage_useallnodes: false\nrook_storage_usealldevices: false\nrook_storage_nodes:\n - name: "testbed-node-0"\n devices:\n - name: "/dev/sdb"\n - name: "/dev/sdc"\n - name: "/dev/sde"\n - name: "testbed-node-1"\n devices:\n - name: "/dev/sdf"\n - name: "/dev/sdg"\n - name: "/dev/sdh"\n - name: "testbed-node-2"\n devices:\n - name: "/dev/sdi"\n - name: "/dev/sdj"\n - name: "/dev/sdk"\n'})}),"\n",(0,r.jsxs)(o.h3,{id:"flexible-approach-using-rook_storage",children:["Flexible approach using ",(0,r.jsx)(o.code,{children:"rook_storage"})]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'# do not use all nodes\nrook_storage_useallnodes: false\n# do not use all found devices\nrook_storage_usealldevices: false\nrook_storage_config_osdsperdevice: "1"\n# enable device encryption\nrook_storage_config_encrypteddevice: "true"\n# define a device filter where to create OSDs\nrook_storage_devicefilter: ""\n# name nodes where to create OSDs\nrook_storage_nodes: []\n# - name: "testbed-node-0"\n# - name: "testbed-node-1"\n# - name: "testbed-node-2"\nrook_storage:\n useAllNodes: "{{ rook_storage_useallnodes }}"\n useAllDevices: "{{ rook_storage_usealldevices }}"\n config:\n crushRoot: "custom-root" # specify a non-default root label for the CRUSH map\n metadataDevice: "md0" # specify a non-rotational storage so ceph-volume will use it as block db device of bluestore.\n databaseSizeMB: "1024" # uncomment if the disks are smaller than 100 GB\n osdsPerDevice: "{{ rook_storage_config_osdsperdevice }}" # this value can be overridden at the node or device level\n encryptedDevice: "{{ rook_storage_config_encrypteddevice }}" # the default value for this option is "false"\n # # Individual nodes and their config can be specified as well, but \'useAllNodes\' above must be set to false. Then, only the named\n # # nodes below will be used as storage resources. Each node\'s \'name\' field should match their \'kubernetes.io/hostname\' label.\n nodes:\n - name: "172.17.4.201"\n devices: # specific devices to use for storage can be specified for each node\n - name: "sdb"\n - name: "nvme01" # multiple osds can be created on high performance devices\n config:\n osdsPerDevice: "5"\n - name: "/dev/disk/by-id/ata-ST4000DM004-XXXX" # devices can be specified using full udev paths\n config: # configuration can be specified at the node level which overrides the cluster level config\n - name: "172.17.4.301"\n deviceFilter: "^sd."\n'})}),"\n",(0,r.jsx)(o.h3,{id:"encrypted-osds",children:"Encrypted OSDs"}),"\n",(0,r.jsx)(o.p,{children:"OSDs are encrypted by default. Rook creates a LUKS on LVM setup for this. Encryption keys are managed by Ceph, as usual."}),"\n",(0,r.jsx)(o.admonition,{type:"info",children:(0,r.jsx)(o.p,{children:"Provisioning LUKS on already existing logical volumes is not supported currently by Rook."})}),"\n",(0,r.jsxs)(o.p,{children:["Have a look at the ",(0,r.jsx)(o.a,{href:"https://docs.ceph.com/en/latest/ceph-volume/lvm/encryption/",children:"Ceph documentation on LVM encryption"})," and the ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/?h=#osd-configuration-settings",children:"Rook OSD Configuration Settings"})," for details."]}),"\n",(0,r.jsxs)(o.p,{children:["If you want complete flexibility, look into the details of the ",(0,r.jsx)(o.a,{href:"#helm-value-file",children:"Helm Value File"}),"."]}),"\n",(0,r.jsx)(o.h2,{id:"dashboard",children:"Dashboard"}),"\n",(0,r.jsx)(o.p,{children:"Password for the admin user of the Ceph dashboard is automatically generated by rook and can be retrieved like this:"}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{children:"kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath=\"{['data']['password']}\" | base64 --decode && echo\n"})}),"\n",(0,r.jsxs)(o.p,{children:["Have a look at the ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/Storage-Configuration/Monitoring/ceph-dashboard/",children:"Rook Ceph Dashboard Documentation"})," for details."]}),"\n",(0,r.jsxs)(o.p,{children:["Some useful ansible variables for the options from the ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/Storage-Configuration/Monitoring/ceph-dashboard/",children:"Rook Ceph Dashboard Documentation"})," are available."]}),"\n",(0,r.jsx)(o.h3,{id:"enable-dashboard-and-configure-ssl-and-ports",children:"Enable dashboard and configure ssl and ports"}),"\n",(0,r.jsx)(o.p,{children:"The Ceph dashboard is deployed by default and also an LoadBalancer Service is created in Kubernetes."}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_dashboard_enabled: true\nrook_dashboard_ssl: true\nrook_dashboard_port: 7000\nrook_dashboard_port_external: 443\n"})}),"\n",(0,r.jsx)(o.h2,{id:"rook-cluster-name",children:"Rook Cluster Name"}),"\n",(0,r.jsx)(o.p,{children:"The name that will be used internally for the Ceph cluster can be changed. Most commonly the name is the same as the namespace since multiple clusters are not supported in the same namespace."}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_cluster_name: rook-ceph\n"})}),"\n",(0,r.jsx)(o.h2,{id:"kubernetes-namespaces",children:"Kubernetes Namespaces"}),"\n",(0,r.jsx)(o.p,{children:"The Kubernetes namespace that will be created for the Rook cluster can be changed. The services, pods, and other resources created by the operator will be added to this namespace. The common scenario is to create a single Rook cluster. If multiple clusters are created, they must not have conflicting devices or host paths."}),"\n",(0,r.jsxs)(o.p,{children:["By default, both for the operator and the rook cluster, the namespace ",(0,r.jsx)(o.code,{children:"rook-ceph"})," is used."]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_operator_namespace: rook-ceph\nrook_namespace: rook-ceph\n"})}),"\n",(0,r.jsx)(o.h2,{id:"number-and-placement-of-ceph-daemons",children:"Number and Placement of Ceph Daemons"}),"\n",(0,r.jsx)(o.p,{children:"The number and placement of Ceph daemons can be changed."}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_mon_count: 3\nrook_mds_count: 3\nrook_mgr_count: 3\n"})}),"\n",(0,r.jsxs)(o.p,{children:["Please read ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/#mon-settings",children:"Rook MON Settings"}),", ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/#mgr-settings",children:"Rook MGR Settings"})," and ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Shared-Filesystem/ceph-filesystem-crd/#metadata-server-settings",children:"Rook MDS Settings"})," to understand which configurations make sense."]}),"\n",(0,r.jsx)(o.p,{children:"The following inventory groups are defined with defaults and can be used to control the node affinity regarding the indicated Ceph components:"}),"\n",(0,r.jsxs)(o.ul,{children:["\n",(0,r.jsx)(o.li,{children:(0,r.jsx)(o.code,{children:"rook-mds"})}),"\n",(0,r.jsx)(o.li,{children:(0,r.jsx)(o.code,{children:"rook-mgr"})}),"\n",(0,r.jsx)(o.li,{children:(0,r.jsx)(o.code,{children:"rook-mon"})}),"\n",(0,r.jsx)(o.li,{children:(0,r.jsx)(o.code,{children:"rook-osd"})}),"\n",(0,r.jsx)(o.li,{children:(0,r.jsx)(o.code,{children:"rook-rgw"})}),"\n"]}),"\n",(0,r.jsx)(o.p,{children:"To customise those inventory groups it is possible to do so in the following format:"}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"[rook-mds:children]\nceph-control\n\n[rook-mgr:children]\nceph-control\n\n[rook-mon:children]\nceph-control\n\n[rook-osd:children]\nceph-resource\n\n[rook-rgw:children]\nceph-control\n"})}),"\n",(0,r.jsx)(o.p,{children:"Nodes assigned to those groups will be labeled and then be utilised during the scheduling of the pods with a configuration like the following for each component:"}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'nodeAffinity:\n requiredDuringSchedulingIgnoredDuringExecution:\n nodeSelectorTerms:\n - matchExpressions:\n - key: "node-role.osism.tech/{{ rook_placement_label_mon }}"\n operator: In\n values:\n - "true"\n'})}),"\n",(0,r.jsxs)(o.p,{children:["If you decide after the initial deployment to move Ceph components to different nodes you can do so modifying ",(0,r.jsx)(o.code,{children:"inventory/20-roles"})," and run ",(0,r.jsx)(o.code,{children:"osism apply rook-change-labels"})," afterwards."]}),"\n",(0,r.jsx)(o.h2,{id:"crash-collector",children:"Crash Collector"}),"\n",(0,r.jsxs)(o.p,{children:["The ",(0,r.jsx)(o.a,{href:"https://docs.ceph.com/en/quincy/mgr/crash/",children:"Ceph Crash Module"})," is enabled by default. You can also configure how long to retain the crash reports."]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_crashcollector:\n disable: false\n daysToRetrain: 7\n"})}),"\n",(0,r.jsx)(o.h2,{id:"log-collector",children:"Log Collector"}),"\n",(0,r.jsx)(o.p,{children:"The log collector will run as a side-car next to each Ceph daemon. The Ceph configuration option log_to_file will be turned on, meaning Ceph daemons will log on files in addition to still logging to container's stdout. These logs will be rotated."}),"\n",(0,r.jsxs)(o.p,{children:["See ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/#cluster-settings",children:"Rook Cluster Settings"})," for more details."]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_logcollector:\n enabled: true\n periodicity: daily # one of: hourly, daily, weekly, monthly\n maxLogSize: 500M # SUFFIX may be 'M' or 'G'. Must be at least 1M.\n"})}),"\n",(0,r.jsx)(o.h2,{id:"ceph-config",children:"Ceph Config"}),"\n",(0,r.jsx)(o.admonition,{type:"info",children:(0,r.jsx)(o.p,{children:"The Ceph Config feature is currently in an experimental state in the Rook project."})}),"\n",(0,r.jsxs)(o.p,{children:["Please read ",(0,r.jsx)(o.a,{href:"https://rook.github.io/docs/rook/latest-release/CRDs/Cluster/ceph-cluster-crd/#ceph-config",children:"Ceph Config"})," for details on how to use and what to expect from this feature."]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_cephconfig:\n global:\n # All values must be quoted so they are considered a string in YAML\n osd_pool_default_size: "3"\n mon_warn_on_pool_no_redundancy: "false"\n osd_crush_update_on_start: "false"\n # Make sure to quote special characters\n "osd.*":\n osd_max_scrubs: "10"\n'})}),"\n",(0,r.jsx)(o.h2,{id:"second-ceph-cluster",children:"Second Ceph cluster"}),"\n",(0,r.jsx)(o.p,{children:"In theory, this is completely customizable by deploying multiple helm releases. No evaluation has been done so far, though and this is currently not implemented in OSISM."}),"\n",(0,r.jsx)(o.h2,{id:"helm-value-file",children:"Helm Value File"}),"\n",(0,r.jsxs)(o.p,{children:["The ",(0,r.jsx)(o.a,{href:"https://github.com/osism/ansible-collection-services/tree/main/roles/rook",children:"OSISM Rook role"})," is an opinionated and sane default configuration. If you reach the limits of what is customizable via ansible variables or have a very custom setup, you can pass a custom or additional ",(0,r.jsx)(o.a,{href:"https://github.com/osism/ansible-collection-services/blob/main/roles/rook/templates/01-helm-values-all.yml.j2",children:(0,r.jsx)(o.code,{children:"values.yml"})})," files or even any ",(0,r.jsx)(o.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/specification/",children:"Rook CRD"})," to the role and it will be jinja2 templated and roled out to the kubernetes cluster."]}),"\n",(0,r.jsxs)(o.p,{children:["Just overwrite ",(0,r.jsx)(o.code,{children:"rook_configuration_directory"})," and place any ",(0,r.jsx)(o.code,{children:"*.yml.j2"})," files that you want to apply there."]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_template_directory: "{{ configuration_directory }}/environments/rook/files"\n'})}),"\n",(0,r.jsxs)(o.ul,{children:["\n",(0,r.jsxs)(o.li,{children:["Helm ",(0,r.jsx)(o.code,{children:"values.yml"})," files need to be named ",(0,r.jsx)(o.code,{children:"*-helm-values-*.yml.j2"})]}),"\n",(0,r.jsxs)(o.li,{children:["custom CRDs need to be named ",(0,r.jsx)(o.code,{children:"*-CRD-*.yml.j2"})]}),"\n"]}),"\n",(0,r.jsx)(o.p,{children:"It makes sense to also include the default templates and change them (to e.g. use already existing ansible variables) add your custom settings on top or change them to fit your use cases."}),"\n",(0,r.jsxs)(o.p,{children:["Get the default templates from the ",(0,r.jsx)(o.code,{children:"osism-ansible"})," container or download them from github."]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{children:'mkdir /opt/configuration/environments/rook/files\ncd /opt/configuration/environments/rook/files\nfor file in 01-helm-values-all.yml.j2 02-CRD-CephClient.yml.j2 ; do\n curl -O "https://raw.githubusercontent.com/osism/ansible-collection-services/main/roles/rook/templates/${file}"\ndone\n'})})]})}function h(e={}){const{wrapper:o}={...(0,t.R)(),...e.components};return o?(0,r.jsx)(o,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,o,n)=>{n.d(o,{R:()=>a,x:()=>i});var s=n(96540);const r={},t=s.createContext(r);function a(e){const o=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function i(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7023f74c.082ec029.js b/assets/js/7023f74c.082ec029.js new file mode 100644 index 0000000000..4e4d00b082 --- /dev/null +++ b/assets/js/7023f74c.082ec029.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[94869],{62779:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>o,contentTitle:()=>s,default:()=>u,frontMatter:()=>c,metadata:()=>n,toc:()=>r});const n=JSON.parse('{"id":"iaas/components/image-manager/update","title":"Image Manager update.py","description":"Overview","source":"@site/docs/02-iaas/components/image-manager/update.md","sourceDirName":"02-iaas/components/image-manager","slug":"/iaas/components/image-manager/update","permalink":"/docs/iaas/components/image-manager/update","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/image-manager/update.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"sidebar_label":"Automated updates","sidebar_position":1},"sidebar":"docs","previous":{"title":"Image Manager","permalink":"/docs/iaas/components/image-manager/"},"next":{"title":"Flavor Manager","permalink":"/docs/iaas/components/flavor-manager"}}');var i=t(74848),d=t(28453);const c={sidebar_label:"Automated updates",sidebar_position:1},s="Image Manager update.py",o={},r=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Usage",id:"usage",level:2}];function m(e){const a={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,d.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(a.header,{children:(0,i.jsx)(a.h1,{id:"image-manager-updatepy",children:"Image Manager update.py"})}),"\n",(0,i.jsx)(a.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsxs)(a.p,{children:["The OpenStack Image Manager ",(0,i.jsx)(a.code,{children:"update.py"})," Script updates the ",(0,i.jsx)(a.code,{children:"/etc/images/*.yaml"})," files to the always latest release of the distributions, set S3 mirror URLs and uploads the images to the mirror."]}),"\n",(0,i.jsx)(a.p,{children:"These updated yaml files are later processed by the Image Manger itself."}),"\n",(0,i.jsx)(a.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsxs)(a.p,{children:["Prepare to use the ",(0,i.jsx)(a.code,{children:"update.py"})," script."]}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{children:"git clone https://github.com/osism/openstack-image-manager/\ncd openstack-image-manager\npipenv install\npipenv shell\n"})}),"\n",(0,i.jsx)(a.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{children:"python contrib/update.py --help\n\n Usage: update.py [OPTIONS]\n\n\u256d\u2500 Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 --debug Enable debug logging \u2502\n\u2502 --dry-run Do not perform any changes \u2502\n\u2502 --minio-access-key TEXT Minio access key [env var: MINIO_ACCESS_KEY] [default: None] \u2502\n\u2502 --minio-secret-key TEXT Minio secret key [env var: MINIO_SECRET_KEY] [default: None] \u2502\n\u2502 --minio-server TEXT Minio server [env var: MINIO_SERVER] [default: swift.services.a.regiocloud.tech] \u2502\n\u2502 --minio-bucket TEXT Minio bucket [env var: MINIO_BUCKET] [default: openstack-images] \u2502\n\u2502 --swift-prefix TEXT Swift prefix [env var: SWIFT_PREFIX] [default: swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/] \u2502\n\u2502 --install-completion Install completion for the current shell. \u2502\n\u2502 --show-completion Show completion for the current shell, to copy it or customize the installation. \u2502\n\u2502 --help Show this message and exit. \u2502\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n"})}),"\n",(0,i.jsx)(a.admonition,{type:"note",children:(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"At this time the update.py expects all yaml files at /etc/images/, which can't be configured at the moment."}),"\n",(0,i.jsx)(a.li,{children:"Mirroring can't be disabled at the moment."}),"\n"]})}),"\n",(0,i.jsxs)(a.p,{children:["Best run this script by cron or a CI job, to update all distribution files periodically to the latest release and afterwards run ",(0,i.jsx)(a.a,{href:"../image-manager/",children:"Openstack Image Manager"}),".\nThe distribution image yaml files must exist before running the script, you can use the files from the Github repo at ",(0,i.jsx)(a.code,{children:"etc/images/"})," as template for your first run."]}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{children:"$ python contrib/update.py\n2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/centos.yml\n2024-04-24 09:29:44 | INFO | update_image:179 - Checking image CentOS Stream 9\n2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-HEREBE\\d+\\.\\dDRAGONS.x86_64.qcow2\n2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cloud.centos.org/centos/9-stream/x86_64/images/CHECKSUM\n2024-04-24 09:29:44 | INFO | get_latest_default:62 - Latest URL is now https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2\n2024-04-24 09:29:44 | INFO | get_latest_default:63 - Latest filename is now CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2\n2024-04-24 09:29:44 | INFO | update_image:192 - Checksum of current CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337\n2024-04-24 09:29:44 | INFO | update_image:208 - Our checksum is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337\n2024-04-24 09:29:44 | INFO | update_image:211 - Image CentOS Stream 9 is up-to-date, nothing to do\n2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/debian.yml\n2024-04-24 09:29:44 | INFO | update_image:179 - Checking image Debian 11\n2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bullseye/latest/debian-11-genericcloud-amd64.raw\n2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bullseye/latest/SHA512SUMS\n2024-04-24 09:29:45 | INFO | update_image:192 - Checksum of current debian-11-genericcloud-amd64-20240211-1654.raw is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4\n2024-04-24 09:29:45 | INFO | update_image:208 - Our checksum is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4\n2024-04-24 09:29:45 | INFO | update_image:211 - Image Debian 11 is up-to-date, nothing to do\n2024-04-24 09:29:45 | INFO | update_image:179 - Checking image Debian 12\n2024-04-24 09:29:45 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.raw\n2024-04-24 09:29:45 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS\n2024-04-24 09:29:46 | INFO | update_image:192 - Checksum of current debian-12-genericcloud-amd64-daily-20240424-1727.raw is sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e\n2024-04-24 09:29:46 | INFO | update_image:208 - Our checksum is sha512:5401f8c6361bb2a82c2c24b4b4606d95e77229152a80e61f9c613bc88e25de9257057d0ed68b0256b745c4059162a54970fe4a8daf456b2eb67b4f5db5c97fcc\n2024-04-24 09:29:46 | INFO | update_image:229 - New values are {'version': '20240424', 'build_date': datetime.date(2024, 4, 24), 'checksum': 'sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e', 'url': 'https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240424-1727/debian-12-genericcloud-amd64-daily-20240424-1727.raw'}\n2024-04-24 09:29:46 | INFO | main:300 - Processing file /etc/images/rockylinux.yml\n2024-04-24 09:29:46 | INFO | update_image:179 - Checking image Rocky 9\n2024-04-24 09:29:46 | INFO | update_image:182 - Latest download URL is https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2\n2024-04-24 09:29:46 | INFO | update_image:185 - Getting checksums from https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2.CHECKSUM\n2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current Rocky-9-GenericCloud.latest.x86_64.qcow2 is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651\n2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651\n2024-04-24 09:29:47 | INFO | update_image:211 - Image Rocky_9 is up-to-date, nothing to do\n2024-04-24 09:29:47 | INFO | main:300 - Processing file /etc/images/ubuntu.yml\n2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04\n2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img\n2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS\n2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current jammy-server-cloudimg-amd64.img is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710\n2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710\n2024-04-24 09:29:47 | INFO | update_image:211 - Image Ubuntu_22.04 is up-to-date, nothing to do\n2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04 Minimal\n2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64.img\n2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/minimal/releases/jammy/release/SHA256SUMS\n2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current ubuntu-22.04-minimal-cloudimg-amd64.img is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65\n2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65\n2024-04-24 09:29:48 | INFO | update_image:211 - Image Ubuntu 22.04 Minimal is up-to-date, nothing to do\n2024-04-24 09:29:48 | INFO | update_image:179 - Checking image Ubuntu 24.04\n2024-04-24 09:29:48 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img\n2024-04-24 09:29:48 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/noble/current/SHA256SUMS\n2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current noble-server-cloudimg-amd64.img is sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3\n2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:d7ba8d5d1d073f2dc8351973bf4f35157c846a0ea6ee16fb2a9f45a78953e4a7\n2024-04-24 09:29:48 | INFO | update_image:229 - New values are {'version': '20240423', 'build_date': datetime.date(2024, 4, 23), 'checksum': 'sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3', 'url': 'https://cloud-images.ubuntu.com/noble/20240423/noble-server-cloudimg-amd64.img'}\n"})}),"\n",(0,i.jsxs)(a.p,{children:["These yaml files are now extended with additional fields and the ",(0,i.jsx)(a.code,{children:"update.py"})," will take care of the versions, checksum, url and build date to the latest release in the yaml file on every run."]}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"latest_checksum_url - URL of the distros checksum file"}),"\n",(0,i.jsx)(a.li,{children:"latest_url - URL of the distros latest image"}),"\n",(0,i.jsx)(a.li,{children:"mirror_url - URL of the Image File at the local S3 Mirror"}),"\n"]}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{className:"language-yaml",metastring:'title="someexample.yaml"',children:"---\nimages:\n - name: Debian 12\n enable: true\n shortname: debian-12\n format: qcow2\n login: debian\n min_disk: 8\n min_ram: 512\n status: active\n visibility: public\n multi: true\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_rng_model: virtio\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n hypervisor_type: qemu\n os_distro: debian\n os_version: '12'\n replace_frequency: quarterly\n uuid_validity: last-3\n provided_until: none\n tags: []\n latest_checksum_url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS\n latest_url:\n https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.qcow2\n versions:\n - build_date: 2024-04-11\n checksum:\n sha512:3d6f26616e2c8b705993ddef874232887cebe42f1e70fcc020827ac88e8990177d537d34538c71ae2afd3b8baca953fff71eaa7ef71e752e82532c93dcdca436\n url:\n https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240411-1714/debian-12-genericcloud-amd64-daily-20240411-1714.qcow2\n mirror_url:\n https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-images/debian-12/20240411-debian-12.qcow2\n version: '20240411'\n\n"})})]})}function u(e={}){const{wrapper:a}={...(0,d.R)(),...e.components};return a?(0,i.jsx)(a,{...e,children:(0,i.jsx)(m,{...e})}):m(e)}},28453:(e,a,t)=>{t.d(a,{R:()=>c,x:()=>s});var n=t(96540);const i={},d=n.createContext(i);function c(e){const a=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function s(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),n.createElement(d.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/70b53392.154172c9.js b/assets/js/70b53392.154172c9.js new file mode 100644 index 0000000000..5a752bb312 --- /dev/null +++ b/assets/js/70b53392.154172c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[69110],{5879:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"scs-0403-v1-csp-kaas-observability-stack","title":"Architecture for the Cloud Service provider Observability System for the KaaS Layer","description":"Introduction","source":"@site/standards/scs-0403-v1-csp-kaas-observability-stack.md","sourceDirName":".","slug":"/scs-0403-v1-csp-kaas-observability-stack","permalink":"/standards/scs-0403-v1-csp-kaas-observability-stack","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Architecture for the Cloud Service provider Observability System for the KaaS Layer","type":"Decision Record","status":"Draft","track":"Ops"},"sidebar":"standards","previous":{"title":"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer","permalink":"/standards/ops/scs-0403"},"next":{"title":"scs-0410: Gnocchi as database for metering","permalink":"/standards/ops/scs-0410"}}');var r=s(74848),i=s(28453);const a={title:"Architecture for the Cloud Service provider Observability System for the KaaS Layer",type:"Decision Record",status:"Draft",track:"Ops"},o=void 0,l={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Requirements",id:"requirements",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Use of the dNation Observability Stack as a base",id:"use-of-the-dnation-observability-stack-as-a-base",level:4},{value:"Pull-based Architecture",id:"pull-based-architecture",level:4},{value:"Push-based Archtitecture",id:"push-based-archtitecture",level:4},{value:"Scope of the Observability Architecture",id:"scope-of-the-observability-architecture",level:4},{value:"Observing the Observability Infrastructure",id:"observing-the-observability-infrastructure",level:4},{value:"Alerting Rulesets",id:"alerting-rulesets",level:4},{value:"Decisions",id:"decisions",level:2},{value:"Reference",id:"reference",level:2},{value:"Outcome of the CSP Survey about Requirements for KaaS Observability",id:"outcome-of-the-csp-survey-about-requirements-for-kaas-observability",level:3}];function d(e){const t={a:"a",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsx)(t.p,{children:"Cloud Service Providers offer a variety of products to a customer. Those can include compute resources like virtual machines, networking, and identity and access management. As customers of those services build their applications upon those offered services the service provider needs to ensure a certain quality level of their offerings. This is done by observing the infrastructure. Observability systems leverage different types of telemetry data which include:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Metrics: Usually time series data about different parameters of a system which can include e.g. CPU usage, number of active requests, health status, etc."}),"\n",(0,r.jsx)(t.li,{children:"Logs: Messages of software events during runtime"}),"\n",(0,r.jsx)(t.li,{children:"Traces: A more developer-oriented form of logging to provide insights into an application or to analyze request flows in distributed systems."}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"Based on those data, an alerting system can be used to send out notifications to an Operations Team if a system behaves abnormally. Based on the telemetry data the Operations Team can find the issue, work on it, and mitigate future incidents."}),"\n",(0,r.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,r.jsx)(t.p,{children:"Currently, only the IaaS Layer of the SCS Reference Implementation has an Observability Stack consisting of tools like Prometheus, Grafana, and Alertmanager as well as several Exporters to extract monitoring data from the several OpenStack components and additional software that is involved in the Reference Implementation. As the Kubernetes as a Service Layer becomes more and more important and the work on the Cluster API approach to create customer clusters progresses further, an observability solution for this layer is also needed. CSP should be able to watch over customer clusters and intervene if a cluster gets in a malfunctioning state. For this, a toolset and architecture are needed which is proposed in this ADR."}),"\n",(0,r.jsx)(t.h2,{id:"requirements",children:"Requirements"}),"\n",(0,r.jsx)(t.p,{children:"A survey was conducted to gather the needs and requirements of a CSP when providing Kubernetes as a Service. The feedback of the survey led to the following requirement on a Kubernetes as a Service Observability System:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Telemetry Data that MUST be fetched:","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"CPU, RAM, Disk, Network"}),"\n",(0,r.jsx)(t.li,{children:"HTTP Connectivity Metrics"}),"\n",(0,r.jsx)(t.li,{children:"Control Plane and Pod metrics (States, Ready, etc.)"}),"\n",(0,r.jsx)(t.li,{children:"K8s certs metrics"}),"\n",(0,r.jsx)(t.li,{children:"Metrics of underlying node"}),"\n",(0,r.jsx)(t.li,{children:"Logs of control plane, kubelet and containerd"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["Telemetry Data that MAY be fetched:","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"K8s resources (exporters, kubestate metrics, cadvisor, parts of the kubelet)"}),"\n",(0,r.jsx)(t.li,{children:"Ingress controller exporter (http error rate, cert metrics like expiration date)"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["Telemetry Data that SHOULD NOT BE fetched:","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Any metrics or logs a CSP does not need to provide support with respect to their SLA with a Customer."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["Telemetry Data that MUST NOT be fetched:","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Secrets"}),"\n",(0,r.jsx)(t.li,{children:"Customer Specific Workload Metrics"}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.li,{children:"The Alerting Mechanism MUST include a default ruleset"}),"\n",(0,r.jsx)(t.li,{children:"The Observability Stack MUST run on the CSP Infrastructure"}),"\n",(0,r.jsx)(t.li,{children:"The Observability Stack MUST be High Available"}),"\n",(0,r.jsx)(t.li,{children:"The Observability Stack MUST be able to observe itself"}),"\n",(0,r.jsx)(t.li,{children:"Observed Clusters SHOULD have a low resource impact on the used software to provide telemetry data for the Observability Stack"}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,r.jsx)(t.h4,{id:"use-of-the-dnation-observability-stack-as-a-base",children:"Use of the dNation Observability Stack as a base"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"https://github.com/dNationCloud/kubernetes-monitoring",children:"dNation monitoring stack"})," offers a lot of basic capabilities needed on an observability stack for Kubernetes like Prometheus Operator, Grafana, Alertmanager, Loki, Promtail and Thanos."]}),"\n",(0,r.jsx)(t.h4,{id:"pull-based-architecture",children:"Pull-based Architecture"}),"\n",(0,r.jsx)(t.p,{children:"Each customer cluster has Thanos and Prometheus installed in addition to Thanos and Prometheus on the Observer Cluster. Metrics of a customer cluster are pulled from Thanos (Customer Cluster) for short term queries, as for long term queries the data of all Thanos instances is stored in an external Object Store of the CSP."}),"\n",(0,r.jsx)(t.h4,{id:"push-based-archtitecture",children:"Push-based Archtitecture"}),"\n",(0,r.jsx)(t.p,{children:"Here, Thanos and Prometheus are only used on the CSP side to store and manage all observability data. For the customer clusters only the Prometheus Agent will be used. Prometheus Agent will push all metrics of a Customer Cluster to the central Thanos instance and is preserved in an external Object Store. This introduces less complexity and resource consumption on the customer workload clusters."}),"\n",(0,r.jsx)(t.h4,{id:"scope-of-the-observability-architecture",children:"Scope of the Observability Architecture"}),"\n",(0,r.jsx)(t.p,{children:"The Observability Cluster and Architecture SHOULD be defined in a modular way so that it can be used to not only observe the Kubernetes Layer of an SCS Stack, but every aspect of an SCS Stack."}),"\n",(0,r.jsx)(t.h4,{id:"observing-the-observability-infrastructure",children:"Observing the Observability Infrastructure"}),"\n",(0,r.jsx)(t.p,{children:"For usage in production, it needs to be possible to observe the Observability Cluster itself."}),"\n",(0,r.jsx)(t.h4,{id:"alerting-rulesets",children:"Alerting Rulesets"}),"\n",(0,r.jsxs)(t.p,{children:["Use a mix of ",(0,r.jsx)(t.a,{href:"https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/alerts",children:"kubernetes-mixin alerts"})," and ",(0,r.jsx)(t.a,{href:"https://github.com/dNationCloud/kubernetes-monitoring/tree/main/jsonnet/rules",children:"dNation Alerts Ruleset"}),", as they offer an extensive and well reviewed set of default Alerts covering the important Parts of a Kubernetes Deployment (Nodes, Controlplane, K8s Resources, etc.)"]}),"\n",(0,r.jsx)(t.h2,{id:"decisions",children:"Decisions"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Base the MVP-0 Implementation on the dNation Kubernetes Monitoring Stack."}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.strong,{children:"Push-based"})," Architecture was chosen over the Pull-based Approach."]}),"\n",(0,r.jsx)(t.li,{children:"The Observability Stack will be created based on the dNation observability stack"}),"\n",(0,r.jsx)(t.li,{children:"The Observability Stack can be used as a standalone component to use with the Kubernetes Layer. It should be possible to observe other parts of an SCS Stack like the status of the OpenStack components, but this will not be mandatory."}),"\n",(0,r.jsx)(t.li,{children:"The Observability Stack should be designed that it is possible to provision two observer clusters side by side, observing each other. To do this is only a recommendation for production usage."}),"\n",(0,r.jsxs)(t.li,{children:["The MVP-0 will consist of the following features:","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Observability data from KaaS Clusters is scraped","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"K8s cluster that hosts observer deployment is deployed"}),"\n",(0,r.jsx)(t.li,{children:"S3 compatible bucket as a storage for long term metrics is configured"}),"\n",(0,r.jsx)(t.li,{children:"thanos query-frontend is deployed and configured"}),"\n",(0,r.jsx)(t.li,{children:"thanos query is deployed and configured"}),"\n",(0,r.jsx)(t.li,{children:"thanos receiver is deployed and configured (simple deployment, non HA, without router)"}),"\n",(0,r.jsx)(t.li,{children:"thanos ruler is deployed and configured"}),"\n",(0,r.jsx)(t.li,{children:"thanos compactor is deployed and configured"}),"\n",(0,r.jsx)(t.li,{children:"thanos bucket-web is deployed and configured"}),"\n",(0,r.jsx)(t.li,{children:"thanos storegateway is deployed and configured"}),"\n",(0,r.jsx)(t.li,{children:"prometheus server is deployed and configured"}),"\n",(0,r.jsx)(t.li,{children:"prometheus alertmanager is deployed and configured"}),"\n",(0,r.jsx)(t.li,{children:"prometheus black-box exporter is deployed and configured"}),"\n",(0,r.jsx)(t.li,{children:"kaas-metric-importer is deployed and configured (service aims to differentiate between intentional deletion of KaaS instances and failures in the KaaS monitoring agent)"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["Alerts are defined on the KaaS Clusters metrics","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"all prometheus alerts are working as expected"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["There exist Dashboards for KaaS Cluster Health","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"KaaS L0 dashboard counters are working correctly"}),"\n",(0,r.jsx)(t.li,{children:"Dedicated L0 dashboards are deployed for KaaS and for IaaS monitoring layers"}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.li,{children:"There exist Dashboards for SCS services endpoints health (BlackBox exporter)"}),"\n",(0,r.jsx)(t.li,{children:"There exist Dashboards for IaaS layer health"}),"\n",(0,r.jsxs)(t.li,{children:["Automatic Setup of Exporters for Observability of managed K8s clusters","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"KaaS service is mocked"}),"\n",(0,r.jsx)(t.li,{children:"VM that will host a mock of KaaS service is deployed"}),"\n",(0,r.jsx)(t.li,{children:"a script that deploys a multiple KinD clusters and register them in observer is created"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["Automatic Setup of Thanos sidecar for Observability of IaaS layer (testbed)","\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"IaaS service is mocked"}),"\n",(0,r.jsx)(t.li,{children:"OSISM testbed is deployed"}),"\n",(0,r.jsx)(t.li,{children:"implement an option to deploy thanos sidecar with some simple config in OSISM testbed"}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.li,{children:"There exist Dashboards for Harbor Registry Health"}),"\n",(0,r.jsx)(t.li,{children:"Alerts are defined on the Harbor Registry metrics"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"reference",children:"Reference"}),"\n",(0,r.jsx)(t.h3,{id:"outcome-of-the-csp-survey-about-requirements-for-kaas-observability",children:"Outcome of the CSP Survey about Requirements for KaaS Observability"}),"\n",(0,r.jsx)(t.p,{children:"A survey was conducted to gather the needs and requirements of a CSP when providing Kubernetes as a Service. The results of the Survey (Questions with answers) were the following:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"What is your understanding of a managed Kubernetes Offering:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Hassle-Free Installation and Maintenance (customer viewpoint); Providing control plane and worker nodes and responsibility for correct function but agnostic to workload"}),"\n",(0,r.jsx)(t.li,{children:"Day0, 1 and 2 (~planning, provisioning, operations) full lifecycle management or let customer manages some parts of that, depending on customer contract"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"What Type and Depth of observability is needed"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"CPU, RAM, HDD and Network usage, Health and Function of Cluster Nodes, control plane and if desired Customer Workload"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Do you have an observability infrastructure, if yes, how it is built"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Grafana/Thanos/Prometheus/Loki/Promtail/Alertmanger Stack, i.e. ",(0,r.jsx)(t.a,{href:"https://raw.githubusercontent.com/dNationCloud/kubernetes-monitoring-stack/main/thanos-deployment-architecture.svg",children:"Example Infrastructure"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Data Must haves"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"CPU, RAM, Disk, Network"}),"\n",(0,r.jsx)(t.li,{children:"HTTP Connectivity Metrics"}),"\n",(0,r.jsx)(t.li,{children:"Control Plane and Pod metrics (States, Ready, etc.)"}),"\n",(0,r.jsx)(t.li,{children:"Workload specific metrics"}),"\n",(0,r.jsx)(t.li,{children:"Node Stats"}),"\n",(0,r.jsx)(t.li,{children:"K8s resources (exporters, kubestate metrics, cadvisor, parts of the kubelet)"}),"\n",(0,r.jsx)(t.li,{children:"Ingress controller exporter (http error rate, cert metrics like expiration date)"}),"\n",(0,r.jsx)(t.li,{children:"K8s certs metrics"}),"\n",(0,r.jsx)(t.li,{children:"Metrics of underlying node"}),"\n",(0,r.jsx)(t.li,{children:"Logs of control plane, kubelet and containerd"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Must Not haves"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Secrets, otherwise as much as possible for anomaly detection over long time data"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Must have Alerts"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Dependent on SLAs and SLA Types, highly individual"}),"\n",(0,r.jsxs)(t.li,{children:["Use of ",(0,r.jsx)(t.a,{href:"https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/alerts",children:"kubernetes-mixin alerts"})," and ",(0,r.jsx)(t.a,{href:"https://github.com/dNationCloud/kubernetes-monitoring/tree/main/jsonnet/rules",children:"dNation Alerts Ruleset"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Must NOT Alert on"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Should not wake people, nothing that does not lead to Action items"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Observability from Within Or Outside KaaS. How does the architecture look like?"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Monitoring Infra on CSP Side"}),"\n",(0,r.jsx)(t.li,{children:"Data from Customer Clusters and Mon Infra on CSP and KaaS, get both data. KaaS Monitoring can also be used by customer"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Special Constraints"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"HA Setup in different Clusters on Different Sites"}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>o});var n=s(96540);const r={},i=n.createContext(r);function a(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/71acf54e.7bd75dcf.js b/assets/js/71acf54e.7bd75dcf.js new file mode 100644 index 0000000000..8a5ddb8c46 --- /dev/null +++ b/assets/js/71acf54e.7bd75dcf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[20309],{2390:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"iaas/guides/concept-guide/design","title":"Cluster design","description":"Parts of this chapter are based on the OpenStack Architecture Design Guide.","source":"@site/docs/02-iaas/guides/concept-guide/design.md","sourceDirName":"02-iaas/guides/concept-guide","slug":"/iaas/guides/concept-guide/design","permalink":"/docs/iaas/guides/concept-guide/design","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/design.md","tags":[],"version":"current","sidebarPosition":30,"frontMatter":{"sidebar_label":"Cluster design","sidebar_position":30},"sidebar":"docs","previous":{"title":"Nodes in a cluster","permalink":"/docs/iaas/guides/concept-guide/nodes"},"next":{"title":"Use cases","permalink":"/docs/iaas/guides/concept-guide/use-cases"}}');var r=i(74848),c=i(28453);const s={sidebar_label:"Cluster design",sidebar_position:30},a="Cluster design",o={},d=[{value:"Compute architecture",id:"compute-architecture",level:2},{value:"Control plane architecture",id:"control-plane-architecture",level:2},{value:"Storage architecture",id:"storage-architecture",level:2},{value:"Network architecture",id:"network-architecture",level:2},{value:"Identity architecture",id:"identity-architecture",level:2}];function u(e){const t={a:"a",admonition:"admonition",h1:"h1",h2:"h2",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"cluster-design",children:"Cluster design"})}),"\n",(0,r.jsx)(t.admonition,{type:"info",children:(0,r.jsxs)(t.p,{children:["Parts of this chapter are based on the ",(0,r.jsx)(t.a,{href:"https://docs.openstack.org/arch-design/index.html",children:"OpenStack Architecture Design Guide"}),".\nThe sources for this guide can be found in repostory ",(0,r.jsx)(t.a,{href:"https://github.com/openstack/arch-design",children:"openstack/arch-design"}),"\nand have been published under the Apache Licence 2.0."]})}),"\n",(0,r.jsx)(t.h2,{id:"compute-architecture",children:"Compute architecture"}),"\n",(0,r.jsx)(t.h2,{id:"control-plane-architecture",children:"Control plane architecture"}),"\n",(0,r.jsx)(t.h2,{id:"storage-architecture",children:"Storage architecture"}),"\n",(0,r.jsx)(t.h2,{id:"network-architecture",children:"Network architecture"}),"\n",(0,r.jsx)(t.h2,{id:"identity-architecture",children:"Identity architecture"})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>a});var n=i(96540);const r={},c=n.createContext(r);function s(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7217b34c.91fa3ac2.js b/assets/js/7217b34c.91fa3ac2.js new file mode 100644 index 0000000000..3589a50a8e --- /dev/null +++ b/assets/js/7217b34c.91fa3ac2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[46098],{11270:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>u,default:()=>g,frontMatter:()=>o,metadata:()=>a,toc:()=>r});const a=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/magnum","title":"Magnum","description":"* Magnum admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/magnum.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/magnum","permalink":"/docs/iaas/guides/configuration-guide/openstack/magnum","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/magnum.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Magnum"},"sidebar":"docs","previous":{"title":"Keystone","permalink":"/docs/iaas/guides/configuration-guide/openstack/keystone"},"next":{"title":"Manila","permalink":"/docs/iaas/guides/configuration-guide/openstack/manila"}}');var i=t(74848),s=t(28453);const o={sidebar_label:"Magnum"},u="Magnum",c={},r=[];function d(e){const n={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"magnum",children:"Magnum"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/magnum/latest/admin/index.html",children:"Magnum admin guide"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/magnum/latest/configuration/index.html",children:"Magnum configuration reference"})}),"\n"]})]})}function g(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>u});var a=t(96540);const i={},s=a.createContext(i);function o(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function u(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/732919ef.0cd1044f.js b/assets/js/732919ef.0cd1044f.js new file mode 100644 index 0000000000..ea2873334d --- /dev/null +++ b/assets/js/732919ef.0cd1044f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[32233],{3325:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Releases","slug":"/category/releases","permalink":"/docs/category/releases","sidebar":"docs","navigation":{"previous":{"title":"Hardware-Landscape","permalink":"/docs/turnkey-solution/hardware-landscape"},"next":{"title":"Release Notes for SCS Release 0","permalink":"/docs/releases/Release0"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/73512cb1.aecc1b98.js b/assets/js/73512cb1.aecc1b98.js new file mode 100644 index 0000000000..38fc8538e2 --- /dev/null +++ b/assets/js/73512cb1.aecc1b98.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[18897],{38004:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"scs-0218-v1-container-registry-for-scs-standard-implementation","title":"Container registry for SCS standard implementation","description":"Introduction","source":"@site/standards/scs-0218-v1-container-registry-for-scs-standard-implementation.md","sourceDirName":".","slug":"/scs-0218-v1-container-registry-for-scs-standard-implementation","permalink":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Container registry for SCS standard implementation","type":"Decision Record","status":"Draft","track":"KaaS"},"sidebar":"standards","previous":{"title":"scs-0218: Container registry for SCS standard implementation","permalink":"/standards/kaas/scs-0218"},"next":{"title":"scs-0219: KaaS Networking Standard","permalink":"/standards/kaas/scs-0219"}}');var r=s(74848),i=s(28453);const o={title:"Container registry for SCS standard implementation",type:"Decision Record",status:"Draft",track:"KaaS"},a=void 0,c={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Evaluated projects",id:"evaluated-projects",level:3},{value:"Deeper look into selected projects",id:"deeper-look-into-selected-projects",level:3},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2}];function l(e){const n={a:"a",h2:"h2",h3:"h3",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsx)(n.p,{children:"A container registry is an infrastructure service to enable storing and accessing container\nimages. Images can be pushed to the registry by e.g. Continuous integration pipelines and\nbe pulled from by runtime environments like Kubernetes clusters."}),"\n",(0,r.jsx)(n.p,{children:'In the standard document ["Requirements for container registries"], requirements for a\nregistry in the context of SCS were introduced. These are based on the principals, that\na usable project should be open source, active and feature-rich, especially with regard\nto security.'}),"\n",(0,r.jsx)(n.h2,{id:"terminology",children:"Terminology"}),"\n",(0,r.jsx)(n.p,{children:"Cloud Service Provider (abbr. CSP)\nEntity that provides scalable computing resources"}),"\n",(0,r.jsx)(n.p,{children:"Cloud Native Computing Foundation (abbr. CNCF)\nOrganization that hosts and develops open source projects for cloud native computing"}),"\n",(0,r.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,r.jsxs)(n.p,{children:['In order to provide a usable, complete experience for the SCS reference implementation, it must be decided\non a registry in accordance with requirements set by the ["Requirements for container registries"] standard\nas well as other dependencies set by the SCS project, including the ',(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Drafts/OSS-Health.md",children:"OSS requirements"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"This document should finally lead to a decision about the container registry used as a reference implementation of the SCS container registry."}),"\n",(0,r.jsx)(n.h3,{id:"evaluated-projects",children:"Evaluated projects"}),"\n",(0,r.jsxs)(n.p,{children:["A few open source projects were evaluated for this document in order to find suitable candidates\nfor the SCS reference implementation. These projects can be found in the following list of\nevaluated projects with their classified categories and comments. An initial assessment was\ndone with the checks for ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Drafts/OSS-Health.md",children:"OSS healthiness"}),'\nand a general overview of the features described in ["Requirements for container registries"], which enables\nclassifying the projects into one of three categories as follows:']}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["\u2714\ufe0f"," The project passed all OSS health checks and will be considered\nfurther as a valid candidate."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["\u2754"," The project passed almost all OSS health checks.\nThere is place for improvement, but the missing points are not crucial from the OSS\nhealth check perspective. The project will be considered further as a valid candidate."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["\u274c"," The project does not pass the OSS health checks. Some OSS health check\nshowstoppers have been found (e.g. open core software, not actively maintained).\nThe project is filtered at this stage and won't be considered further."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The following list contains these projects with a small assessment listed below them:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["\u2714\ufe0f"," ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor",children:"Harbor"})]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:['Harbor project meets all "four opens"',"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Source code is open and available under the ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor/blob/main/LICENSE",children:"Apache 2 license"})]}),"\n",(0,r.jsxs)(n.li,{children:["Community is ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor#community",children:"open"}),", structured and\nwell organized via ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/community",children:"workgroups"})," and\nvarious communications channels e.g. Slack, mailing lists, etc.\n(#harbor Slack channel contains 3k+ members)"]}),"\n",(0,r.jsxs)(n.li,{children:["The development process is open via GitHub issues and well described in the\n",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor/blob/main/CONTRIBUTING.md",children:"contributing"}),"\ndocument"]}),"\n",(0,r.jsxs)(n.li,{children:["The design process is open via GitHub issues. Proposals are ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/community/tree/main/proposals",children:"public"}),".\nThe decision process is well described as well. The project's roadmap is\navailable in the ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor/blob/main/ROADMAP.md",children:"roadmap"})," document"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Maturity is on the CNCF ",(0,r.jsx)(n.a,{href:"https://www.cncf.io/projects/harbor/",children:"graduation"})," level.\nCNCF graduated projects are considered to be stable, widely adopted and production-ready"]}),"\n",(0,r.jsxs)(n.li,{children:["Security","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The security disclosure and response policy is well described in the project's\n",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor/blob/main/SECURITY.md",children:"security"})," document"]}),"\n",(0,r.jsx)(n.li,{children:"The code is reviewed within a standard PR process"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Activity","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"250+ contributors, 4k+ forks, 13k+ GitHub stars"}),"\n",(0,r.jsxs)(n.li,{children:["The project has been ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor/blob/main/ADOPTERS.md",children:"adopted"}),"\nby many companies that run Harbor in their production environments"]}),"\n",(0,r.jsxs)(n.li,{children:["The project collaborates with other communities and projects\n(see ",(0,r.jsx)(n.a,{href:"https://goharbor.io/community/",children:"Partners of Harbor"})," section of the\nproject's website)"]}),"\n",(0,r.jsxs)(n.li,{children:["The project is visible and actively contributes to various conferences, e.g.\n",(0,r.jsx)(n.a,{href:"https://goharbor.io/blog/harbor-at-fosdem-2022/",children:"FOSDEM 22"}),",\n",(0,r.jsx)(n.a,{href:"https://www.youtube.com/watch?v=REgvBPH369M",children:"KubeCon Europe"}),", etc."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Lock-in risk assessment","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The project's ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/community/blob/main/MAINTAINERS.md",children:"maintainers"}),"\ndocument shows that there are a sufficient number of core\nmaintainers/contributors that differ over various companies, we therefore deem\nthe lock-in risk arising from a single point of failure to be low"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["\u2714\ufe0f"," ",(0,r.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2",children:"Dragonfly"})]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:['Dragonfly project meets all "four opens"',"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Source code is open and available under the ",(0,r.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2/blob/main/LICENSE",children:"Apache 2 license"})]}),"\n",(0,r.jsxs)(n.li,{children:["Community is ",(0,r.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2#community",children:"open"}),"\norganized via multiple channels e.g. Slack, mailing lists, etc.\n(#dragonfly Slack channel contains ~50 members)"]}),"\n",(0,r.jsxs)(n.li,{children:["The development process is open via GitHub issues and well described in the\n",(0,r.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2/blob/main/CONTRIBUTING.md",children:"contributing"})," document"]}),"\n",(0,r.jsxs)(n.li,{children:["The design process is open via GitHub issues. The project's roadmap is available in\nthe project's ",(0,r.jsx)(n.a,{href:"https://d7y.io/docs/others/roadmap/#2022-roadmap",children:"webpage"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Maturity is on the CNCF ",(0,r.jsx)(n.a,{href:"https://www.cncf.io/projects/dragonfly/",children:"incubating"})," level\nCNCF incubating project is considered stable and used in production by users with\nthe healthy pool of contributors"]}),"\n",(0,r.jsxs)(n.li,{children:["Security","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The security disclosure is handled via a dedicated email address"}),"\n",(0,r.jsx)(n.li,{children:"The code is reviewed within a standard PR process"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Activity","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"30+ contributors, 100+ forks, 1k+ GitHub stars"}),"\n",(0,r.jsxs)(n.li,{children:["The project has been ",(0,r.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2/blob/main/ADOPTERS.md",children:"adopted"}),"\nby many companies that run Harbor in their production environments"]}),"\n",(0,r.jsxs)(n.li,{children:["The project is visible and actively contributes to various conferences,\ne.g. ",(0,r.jsx)(n.a,{href:"https://www.youtube.com/watch?v=LcxBgmmeA80",children:"KubeCon North America"}),",\n",(0,r.jsx)(n.a,{href:"https://www.youtube.com/watch?v=MGNtPHQYP14",children:"KubeCon Europe"}),", etc."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Lock-in risk assessment","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The list of the project's ",(0,r.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2/blob/main/MAINTAINERS.md",children:"maintainers"}),"\nincludes contributors from various companies and the ",(0,r.jsx)(n.a,{href:"https://dragonfly.devstats.cncf.io/d/7/companies-contributing-in-repository-groups",children:"companies contributing dashboard"}),"\nshows that ~10 companies are actively contributing to a repository group"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["\u2754"," ",(0,r.jsx)(n.a,{href:"https://github.com/quay/quay",children:"Project Quay"})]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:['Project Quay meets all "four opens"',"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Source code is open and available under the ",(0,r.jsx)(n.a,{href:"https://github.com/quay/quay/blob/master/LICENSE",children:"Apache 2 license"})]}),"\n",(0,r.jsxs)(n.li,{children:["Community is ",(0,r.jsx)(n.a,{href:"https://github.com/quay/quay#community",children:"open"})," organized via mailing\nlist and IRC"]}),"\n",(0,r.jsxs)(n.li,{children:["Development process is open via ",(0,r.jsx)(n.a,{href:"https://issues.redhat.com/projects/PROJQUAY/issues",children:"JBoss JIRA"}),"\nissues and well described in the ",(0,r.jsx)(n.a,{href:"https://github.com/quay/quay/blob/master/GOVERNANCE.md",children:"governance"})," document"]}),"\n",(0,r.jsxs)(n.li,{children:["Design process is open via ",(0,r.jsx)(n.a,{href:"https://issues.redhat.com/projects/PROJQUAY/issues",children:"JBoss JIRA"}),"\nissues. The project's roadmap is available on the project's ",(0,r.jsx)(n.a,{href:"https://www.projectquay.io/#contribute",children:"webpage"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Maturity","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Project Quay is an open-source project that started ",(0,r.jsx)(n.a,{href:"https://github.com/quay/quay/commit/0349af754204375d74ac5833713b607398981ff7",children:"~9 years ago"}),".\nIt powers Red Hat enterprise products Red Hat Quay and Quay.io, which are used in\na productive way by many. Therefore, the project's maturity is at the good level"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Security","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The security disclosure is handled via a dedicated email address"}),"\n",(0,r.jsx)(n.li,{children:"The code is reviewed within a standard PR process"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Activity","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"50+ contributors, 200+ forks, 2k+ GitHub stars"}),"\n",(0,r.jsxs)(n.li,{children:["The project has been used by many ",(0,r.jsx)(n.a,{href:"https://www.projectquay.io",children:"companies"})," that\nrun Quay in their production environments"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Lock-in risk assessment","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The project's owners/maintainers list is not publicly available and is stored in\nthe ",(0,r.jsx)(n.a,{href:"https://github.com/quay/quay-docs#how-do-i-set-up",children:"downstream repository"}),".\nTherefore, it is hard to distinguish the risk of project failure caused by low\ndiversity across the companies. This should be improved."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["\u274c"," ",(0,r.jsx)(n.a,{href:"https://github.com/sapcc/keppel",children:"Keppel"})]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The project seems to be not widely used in a productive way and also the activity\naround is currently not on a good level (5+ contributors). The development\nprocess as well as the design process seem to be open, but neither of them are\ndocumented yet."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["\u274c"," ",(0,r.jsx)(n.a,{href:"https://github.com/sonatype/nexus-public",children:"Nexus"})]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Nexus is an ",(0,r.jsx)(n.strong,{children:"open core"})," software that offers paid ",(0,r.jsx)(n.a,{href:"https://www.sonatype.com/products/repository-oss-vs-pro-features",children:"pro version"})," with advanced features"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["\u274c"," ",(0,r.jsx)(n.a,{href:"https://jfrog.com/community/open-source/",children:"JFrog"})]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["JFrog Artifactory is shipped as an ",(0,r.jsx)(n.strong,{children:"open core"})," ",(0,r.jsx)(n.a,{href:"https://jfrog.com/community/open-source/",children:"software"}),"\nwith limited features. The software is primarily offered as a paid ",(0,r.jsx)(n.a,{href:"https://jfrog.com/pricing/#devops-onprem",children:"pro version"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["\u274c"," ",(0,r.jsx)(n.a,{href:"https://github.com/uber/kraken",children:"Kraken"})]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["It seems that the project is not actively maintained as is discussed in the related\nproject's ",(0,r.jsx)(n.a,{href:"https://github.com/uber/kraken/issues/313",children:"issue"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["\u274c"," ",(0,r.jsx)(n.a,{href:"https://github.com/SUSE/Portus",children:"Portus"})]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["It seems that the project is not actively maintained as is discussed in the related\nproject's ",(0,r.jsx)(n.a,{href:"https://github.com/SUSE/Portus/issues/2352",children:"issue"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"deeper-look-into-selected-projects",children:"Deeper look into selected projects"}),"\n",(0,r.jsx)(n.p,{children:"In the previous section, a wide range of open-source container registry projects (Quay, Harbor, Dragonfly,\nKeppel, Portus, Kraken, etc.) has been carefully evaluated based on the two main\nfactors: the open-source health and range of supported features."}),"\n",(0,r.jsx)(n.p,{children:"The open-source software health is crucial and container registry implementation should\npass it. It evaluates several important metrics of an open source software like whether the code/community/development/design\nis fully open or whether the project's maturity, security, and activity are on the desired\nlevel. This check also evaluates the lock-in risk due to possible single points of\nfailure or internal project conflicts and several other aspects.\nOverall, three projects passed the OSS health checks:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor",children:"Harbor"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://github.com/quay/quay",children:"Project Quay"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://github.com/quay/quay",children:"Dragonfly"})}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:'The above projects were then evaluated from the "supported features" perspective.\nThe document ["Requirements for container registries"] provides a "Required and desirable features check", which\nprovides desired feature sets for open-source container registry implementations according to\nSCS requirements (and nice-to-haves). The list of required features is quite long and contains\nfeatures that are primarily focused on security (authentication, vulnerability scanning, content trust, and validation, etc.),\nscalability (HA mode, registry replication, p2p integration, etc.) and visibility (monitoring).\nThese requirements should ensure that the selected container registry implementation\ncould be offered by CSPs as a secure and enterprise-ready solution.'}),"\n",(0,r.jsx)(n.p,{children:"The following section compares the selected projects Dragonfly, Quay, and Harbor."}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2",children:"Dragonfly"}),' is a healthy open-source project with a growing community\nand CNCF incubating maturity level. It is considered stable, and widely used by many\ncompanies in their production environments. We currently see that it is not as\nfeature-rich as Harbor or Quay, hence it is not considered the best choice here.\nIt seems, that its main aim (currently) is to offer (an efficient, stable, and secure)\ncontainer distribution solution based on p2p technology. This improves download\nefficiency and saves bandwidth across CSPs. It also offers integration possibilities\nthat allow one to use it as a p2p distribution network via a "preheat" API. This\nintegration was implemented in the Harbor project via Dragonfly "preheat" adapter, and\nboth parties may benefit from the integration. Harbor profits from Dragonfly\'s p2p\ndistribution capabilities and on the other hand the Dragonfly project profits from\nHarbor\'s feature-rich container registry "frontend".']}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/quay/quay",children:"Quay"})," is an open-source project maintained by Red Hat. Its OSS health is\non a good level, the surrounding community is growing, and we consider it to be quite\nmature as it powers enterprise solutions like Red Hat Quay and Quay.io.\nBesides this, there is still a place for OSS health improvement. It is hard to\ndistinguish the risk of project failure caused by low diversity across the companies\nbecause the project's owners/maintainers list is not publicly available and is stored in\nthe Red Hat private repository.\nIts feature set is impressive and this project fulfills all must-haves defined in\nthis document. Quay gives you security over your repositories with image\nvulnerability scanning (Clair integration), content validation (Cosign integration),\nand access controls. Harbor stands out here as it allows users to use also project Trivy\nfor vulnerability scanning. Project Quay also provides a scalable open-source\nplatform to host container images across any size organization. One drawback in\ncomparison to Harbor is that the proxy cache feature is still marked as a\n",(0,r.jsx)(n.a,{href:"https://docs.projectquay.io/use_quay.html#quay-as-cache-proxy",children:"Technology Preview"}),",\nhence this feature may not be completely production-ready yet. On the other hand,\nthe project Quay supports ",(0,r.jsx)(n.a,{href:"https://docs.projectquay.io/use_quay.html#build-support",children:"building Dockerfiles"}),"\nusing a set of workers on e.g. Kubernetes. Build triggers, such as GitHub webhooks\ncan be configured to automatically build new versions of repositories when new code is\ncommitted. This feature is not supported by the ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor/issues/6235",children:"Harbor project"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor",children:"Harbor"})," is an outstanding open-source, community-led project with fully open and\nwell-documented processes. Its large and thriving community powers the fast-growing\nfeature set and attracts more and more developers and companies to active contributions.\nHarbor's CNCF graduation in 2020 made it one of the best choices for enterprise\ncustomers that want to operate container registries securely and in a large scale.\nIts community size, landscape, and CNCF graduation make a significant difference in\ncomparison to Quay's open-source health capabilities.\nThe list of supported features is also impressive. This project fulfills all must-haves\ndefined in this document and overcome project Quay with a production-ready proxy cache\nfeature and more options that the user may use in case of image vulnerability scanning.\nIn addition, Harbor profits from p2p distribution capabilities via integration of p2p\nsolutions like Kraken and Dragonfly. It is worth mentioning that Harbor, by design,\noperates on a single storage backend (e.g. S3). It means that the storage of container\nimages is shared even when the Harbor instance serves multiple tenants. The same\napproach is used in Quay and Dragonfly projects, but e.g. Keppel uses multi-tenant-aware\nstorage drivers instead so that each customer gets their own separate storage backend.\nCSP that considers offering container registry \"as a service\" solution based on Harbor\nshould be aware of this shared storage backend architecture."]}),"\n",(0,r.jsx)(n.p,{children:"In the following table, the feature sets of the evaluated projects that passed the OSS health state\nare listed and matched against. This enables a better understanding of the decision-making for this document."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Features"}),(0,r.jsx)(n.th,{children:"Harbor"}),(0,r.jsx)(n.th,{children:"Quay"}),(0,r.jsx)(n.th,{children:"Dragonfly"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Audit Logs"}),(0,r.jsx)(n.td,{children:"\u2713"}),(0,r.jsx)(n.td,{children:"\u2713"}),(0,r.jsx)(n.td,{children:"\u2717"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Authentication of system identities"}),(0,r.jsx)(n.td,{children:"\u2713 Robot Accounts"}),(0,r.jsx)(n.td,{children:"\u2713 Robot Accounts"}),(0,r.jsx)(n.td,{children:"\u2717"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Authentication of users"}),(0,r.jsx)(n.td,{children:"\u2713 Local database, LDAP, OIDC, UAA"}),(0,r.jsx)(n.td,{children:"\u2713 Local database, LDAP, Keystone, JWT"}),(0,r.jsx)(n.td,{children:"\u2713 Local database"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Authorization"}),(0,r.jsx)(n.td,{children:"\u2713"}),(0,r.jsx)(n.td,{children:"\u2713"}),(0,r.jsx)(n.td,{children:"\u2713"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Automation"}),(0,r.jsx)(n.td,{children:"\u2713 Webhooks (HTTP, Slack)"}),(0,r.jsx)(n.td,{children:"\u2713 Webhooks (HTTP, Slack, E-mail ...), building images"}),(0,r.jsx)(n.td,{children:"\u2717"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Vulnerability scanning"}),(0,r.jsx)(n.td,{children:"\u2713 Trivy, Clair"}),(0,r.jsx)(n.td,{children:"\u2713 Clair"}),(0,r.jsx)(n.td,{children:"\u2717"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Content Trust and Validation"}),(0,r.jsx)(n.td,{children:"\u2713 Cosign"}),(0,r.jsx)(n.td,{children:"\u2713 Cosign"}),(0,r.jsx)(n.td,{children:"\u2717"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Multi-tenancy"}),(0,r.jsx)(n.td,{children:"\u2713 (not on the storage level)"}),(0,r.jsx)(n.td,{children:"\u2713 (not on the storage level)"}),(0,r.jsx)(n.td,{children:"\u2713 (not on the storage level)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Backup and restore"}),(0,r.jsx)(n.td,{children:"\u2713"}),(0,r.jsx)(n.td,{children:"\u2713"}),(0,r.jsx)(n.td,{children:"\u2717"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Monitoring"}),(0,r.jsx)(n.td,{children:"\u2713 Prometheus metrics, Tracing"}),(0,r.jsx)(n.td,{children:"\u2713 Prometheus metrics, Tracing (only for Clair)"}),(0,r.jsx)(n.td,{children:"\u2713 Prometheus metrics, Tracing"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"HA mode"}),(0,r.jsx)(n.td,{children:"\u2713"}),(0,r.jsx)(n.td,{children:"\u2713"}),(0,r.jsx)(n.td,{children:"\u2717"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Registry replication"}),(0,r.jsx)(n.td,{children:"\u2713"}),(0,r.jsx)(n.td,{children:"\u2713"}),(0,r.jsx)(n.td,{children:"\u2713"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Proxy cache"}),(0,r.jsx)(n.td,{children:"\u2713"}),(0,r.jsx)(n.td,{children:"\u2713 Feature is in the technology preview stage (non production ready)"}),(0,r.jsx)(n.td,{children:"\u2717"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Quota management"}),(0,r.jsx)(n.td,{children:"\u2713 Based on storage consumption"}),(0,r.jsx)(n.td,{children:"\u2713 Based on storage consumption"}),(0,r.jsx)(n.td,{children:"\u2717"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Garbage collection"}),(0,r.jsx)(n.td,{children:"\u2713 Non-blocking"}),(0,r.jsx)(n.td,{children:"\u2713 Non-blocking"}),(0,r.jsx)(n.td,{children:"\u2717"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Retention policy"}),(0,r.jsx)(n.td,{children:"\u2713 Multiple tag retention rules"}),(0,r.jsx)(n.td,{children:"\u2713 Only tag expiration rules"}),(0,r.jsx)(n.td,{children:"\u2717"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Additional supported artifacts"}),(0,r.jsx)(n.td,{children:"\u2717 (only OCI artifacts)"}),(0,r.jsx)(n.td,{children:"\u2717 (only OCI artifacts)"}),(0,r.jsx)(n.td,{children:"\u2713 Maven, YUM"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Integration possibilities"}),(0,r.jsx)(n.td,{children:"\u2713 Dragonfly (P2P), Kraken (P2P)"}),(0,r.jsx)(n.td,{children:"\u2717"}),(0,r.jsx)(n.td,{children:"\u2713 Harbor, Nydus, eStargz"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Deployment capabilities"}),(0,r.jsx)(n.td,{children:"\u2713 Docker-compose, Helm chart, Operator"}),(0,r.jsx)(n.td,{children:"\u2713 Docker-compose, Operator"}),(0,r.jsx)(n.td,{children:"\u2713 Docker-compose, Helm chart"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Administration capabilities"}),(0,r.jsx)(n.td,{children:"\u2713 Terraform, CRDs, Client libraries"}),(0,r.jsx)(n.td,{children:"\u2713 Ansible, Client libraries"}),(0,r.jsx)(n.td,{children:"\u2713 Client libraries"})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"Notes:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Automation: Harbor should support webhooks following CloudEvents spec in the ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor/issues/17748",children:"next release"})]}),"\n",(0,r.jsxs)(n.li,{children:["Content Trust and Validation: Harbor announced the deprecation of ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor/discussions/16612",children:"Notary"}),"\nintegration, hence it is not mentioned in the table"]}),"\n",(0,r.jsx)(n.li,{children:"Multi-tenancy: Harbor, Quay, as well as Dragonfly, operates on a single storage\nbackend (e.g. S3), i.e. the storage of container images is shared between tenants"}),"\n",(0,r.jsxs)(n.li,{children:["Additional supported artifacts: Harbor announced the deprecation of ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor/discussions/15057",children:"Chartmuseum"}),"\nintegration, hence it is not mentioned in the table"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,r.jsxs)(n.p,{children:['Based on the requirements laid out in ["Requirements for container registries"], the OSS health check\nand the possible software solutions presented in this document, it was decided to use the ',(0,r.jsx)(n.strong,{children:"Harbor"})," project\nas the container registry for the SCS reference implementation."]}),"\n",(0,r.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/standards/scs-0212-v1-requirements-for-container-registries",children:'"Requirements for container registries"'}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor",children:"harbor"}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2",children:"dragonfly"}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/quay/quay",children:"projectquay"})]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/73956345.997f14ed.js b/assets/js/73956345.997f14ed.js new file mode 100644 index 0000000000..68bd838d28 --- /dev/null +++ b/assets/js/73956345.997f14ed.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[26083],{47771:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>n,toc:()=>u});const n=JSON.parse('{"id":"iaas/overview/compute","title":"Compute","description":"TODO","source":"@site/docs/02-iaas/overview/compute.md","sourceDirName":"02-iaas/overview","slug":"/iaas/overview/compute","permalink":"/docs/iaas/overview/compute","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/overview/compute.md","tags":[],"version":"current","frontMatter":{}}');var r=o(74848),s=o(28453);const c={},i="Compute",a={},u=[];function d(e){const t={h1:"h1",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"compute",children:"Compute"})}),"\n",(0,r.jsx)(t.p,{children:"TODO"})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,o)=>{o.d(t,{R:()=>c,x:()=>i});var n=o(96540);const r={},s=n.createContext(r);function c(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/742db51e.d20d3503.js b/assets/js/742db51e.d20d3503.js new file mode 100644 index 0000000000..62705fdbf6 --- /dev/null +++ b/assets/js/742db51e.d20d3503.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[38781],{2950:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"kaas/scs-0218","title":"scs-0218: Container registry for SCS standard implementation","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/kaas/scs-0218.md","sourceDirName":"kaas","slug":"/kaas/scs-0218","permalink":"/standards/kaas/scs-0218","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0217-v1-cluster-hardening"},"next":{"title":"V1","permalink":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation"}}');var r=s(74848),a=s(28453);const d={},i="scs-0218: Container registry for SCS standard implementation",c={},o=[];function l(e){const t={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0218-container-registry-for-scs-standard-implementation",children:"scs-0218: Container registry for SCS standard implementation"})}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation",children:"scs-0218-v1"})}),(0,r.jsx)(t.td,{children:"Decision Record"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>i});var n=s(96540);const r={},a=n.createContext(r);function d(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/748dce39.f0c56a18.js b/assets/js/748dce39.f0c56a18.js new file mode 100644 index 0000000000..d01009eca8 --- /dev/null +++ b/assets/js/748dce39.f0c56a18.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[20082],{95437:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/keystone","title":"Keystone","description":"* List all users of a project who have been assigned the member role","source":"@site/docs/02-iaas/guides/operations-guide/openstack/keystone.md","sourceDirName":"02-iaas/guides/operations-guide/openstack","slug":"/iaas/guides/operations-guide/openstack/keystone","permalink":"/docs/iaas/guides/operations-guide/openstack/keystone","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/keystone.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Keystone"},"sidebar":"docs","previous":{"title":"Cinder","permalink":"/docs/iaas/guides/operations-guide/openstack/cinder"},"next":{"title":"Neutron","permalink":"/docs/iaas/guides/operations-guide/openstack/neutron"}}');var o=n(74848),r=n(28453);const i={sidebar_label:"Keystone"},a="Keystone",c={},d=[];function l(e){const s={code:"code",h1:"h1",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"keystone",children:"Keystone"})}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["List all users of a project who have been assigned the ",(0,o.jsx)(s.code,{children:"member"})," role"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"$ openstack --os-cloud admin role assignment list --names --role member --project test\n+--------+-----------+-------+-----------+--------+--------+-----------+\n| Role | User | Group | Project | Domain | System | Inherited |\n+--------+-----------+-------+-----------+--------+--------+-----------+\n| member | test@test | | test@test | | | False |\n+--------+-----------+-------+-----------+--------+--------+-----------+\n"})}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>i,x:()=>a});var t=n(96540);const o={},r=t.createContext(o);function i(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/749c6f3f.84e9f1ed.js b/assets/js/749c6f3f.84e9f1ed.js new file mode 100644 index 0000000000..3cdc30f47c --- /dev/null +++ b/assets/js/749c6f3f.84e9f1ed.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[48625],{75709:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"SCS Health Monitor","slug":"/category/scs-health-monitor","permalink":"/docs/category/scs-health-monitor","sidebar":"docs","navigation":{"previous":{"title":"Tuning","permalink":"/docs/operating-scs/components/monitoring/docs/tuning"},"next":{"title":"SCS Health Monitor","permalink":"/docs/operating-scs/components/scs-health-monitor/overview"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/755df717.1e39cd42.js b/assets/js/755df717.1e39cd42.js new file mode 100644 index 0000000000..687876866f --- /dev/null +++ b/assets/js/755df717.1e39cd42.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[25429],{41082:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>l,frontMatter:()=>r,metadata:()=>a,toc:()=>d});const a=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/barbican","title":"Barbican","description":"* Barbican admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/barbican.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/barbican","permalink":"/docs/iaas/guides/configuration-guide/openstack/barbican","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/barbican.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Barbican"},"sidebar":"docs","previous":{"title":"Aodh","permalink":"/docs/iaas/guides/configuration-guide/openstack/aodh"},"next":{"title":"Ceilometer","permalink":"/docs/iaas/guides/configuration-guide/openstack/ceilometer"}}');var t=i(74848),c=i(28453);const r={sidebar_label:"Barbican"},o="Barbican",s={},d=[];function u(e){const n={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"barbican",children:"Barbican"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/barbican/latest/admin/index.html",children:"Barbican admin guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/barbican/latest/configuration/index.html",children:"Barbican configuration guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/barbican/latest/configuration/config.html",children:"Barbican configuration reference"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>o});var a=i(96540);const t={},c=a.createContext(t);function r(e){const n=a.useContext(c);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),a.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/757d752e.d944558e.js b/assets/js/757d752e.d944558e.js new file mode 100644 index 0000000000..94dddb5575 --- /dev/null +++ b/assets/js/757d752e.d944558e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6337],{29377:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"operating-scs/components/scs-health-monitor/Workflow","title":"Kubernetes BDD Testing Framework Documentation","description":"Overview","source":"@site/docs/04-operating-scs/components/scs-health-monitor/Workflow.md","sourceDirName":"04-operating-scs/components/scs-health-monitor","slug":"/operating-scs/components/scs-health-monitor/Workflow","permalink":"/docs/operating-scs/components/scs-health-monitor/Workflow","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/scs-health-monitor/Workflow.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"SCS Health Monitor","permalink":"/docs/operating-scs/components/scs-health-monitor/overview"},"next":{"title":"Testflow-Infrastructure","permalink":"/docs/operating-scs/components/scs-health-monitor/Testflow"}}');var t=i(74848),r=i(28453);const o={},a="Kubernetes BDD Testing Framework Documentation",l={},c=[{value:"Overview",id:"overview",level:2},{value:"Usage",id:"usage",level:2},{value:"Configuration",id:"configuration",level:2},{value:"Kubernetes Configuration",id:"kubernetes-configuration",level:3},{value:"Helm Configuration",id:"helm-configuration",level:3},{value:"Running Tests",id:"running-tests",level:3},{value:"Running the Tests",id:"running-the-tests",level:3},{value:"Example Command to Run a Specific Feature File",id:"example-command-to-run-a-specific-feature-file",level:3},{value:"Adding New Features",id:"adding-new-features",level:3},{value:"Creating New Feature Files",id:"creating-new-feature-files",level:3},{value:"Modifying Existing Features",id:"modifying-existing-features",level:4},{value:"Setting Up Ingress",id:"setting-up-ingress",level:4},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Common Errors",id:"common-errors",level:3},{value:"Debugging Tips",id:"debugging-tips",level:4},{value:"Observability stack",id:"observability-stack",level:2},{value:"Adding fixes/new functionalities to the project flow:",id:"adding-fixesnew-functionalities-to-the-project-flow",level:2},{value:"Conclusion",id:"conclusion",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"kubernetes-bdd-testing-framework-documentation",children:"Kubernetes BDD Testing Framework Documentation"})}),"\n",(0,t.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,t.jsx)(n.p,{children:"This framework is designed to facilitate Behavior-Driven Development (BDD) for both cloud level testing\nand container level testing. The framework allows you to write human-readable tests that validate Kubernetes clusters,\npods, services, and other resources."}),"\n",(0,t.jsx)(n.p,{children:"Before you begin, ensure you have the following installed on your machine:"}),"\n",(0,t.jsx)(n.p,{children:"Python 3.8+\npip (Python package installer)\nkubectl (Kubernetes command-line tool)\nHelm (Kubernetes package manager)"}),"\n",(0,t.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Clone the Repository:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/SovereignCloudStack/scs-health-monitor\ncd scs-health-monitor\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsx)(n.li,{children:"Set Up a Virtual Environment:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"It's recommended to use a virtual environment to avoid conflicts with other Python packages."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# create python virtual environment\npython3 -m venv <environment_name>\n\n# activate the python virtual environment in windows command prompt\n<environment_name>/Scripts/activate \n\n# activate the python virtual environment in Unix or MacOS\nsource <environment_name>/bin/activate\n\n# install all the python dependencies\npython -m pip install -r requirements.txt \n"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsx)(n.li,{children:"Install Required Python Packages:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Install all necessary Python packages using pip."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install -r requirements.txt\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsx)(n.li,{children:"Install Additional Tools (Optional) or run script install_env.py:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"If you need to install and manage an NGINX Ingress controller, you'll need helm."}),"\n",(0,t.jsx)(n.p,{children:"For MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install helm\n"})}),"\n",(0,t.jsx)(n.p,{children:"For Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install helm\n"})}),"\n",(0,t.jsx)(n.p,{children:"For Windows:"}),"\n",(0,t.jsx)(n.p,{children:"The easeiest way is to use linux kernel for windows and proceed there."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.p,{children:["In this repository (under main directory) you have to create two files that will be referenced by ",(0,t.jsx)(n.code,{children:"env.yaml"})," and ",(0,t.jsx)(n.code,{children:"clouds.yaml"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"env.yaml:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:' OS_AUTH_TYPE: ""\n OS_AUTH_URL: ""\n OS_IDENTITY_API_VERSION: ""\n OS_REGION_NAME: ""\n OS_INTERFACE: ""\n OS_APPLICATION_CREDENTIAL_ID: ""\n OS_APPLICATION_CREDENTIAL_SECRET: ""\n OS_PROJECT_NAME: ""\n OS_USER_DOMAIN_NAME: ""\n OS_PROJECT_DOMAIN_NAME: "" \n\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"clouds.yaml:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"clouds:\n gx:\n region_name:\n auth_type:\n auth_url:\n identity_api_version:\n interface:\n application_credential_id:\n application_credential_secret:\n"})}),"\n",(0,t.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,t.jsx)(n.h3,{id:"kubernetes-configuration",children:"Kubernetes Configuration"}),"\n",(0,t.jsx)(n.p,{children:"Ensure that your Kubernetes configuration file (kubeconfig) is correctly set up. This file is typically located at\n~/.kube/config. The framework uses this configuration to interact with your Kubernetes cluster."}),"\n",(0,t.jsx)(n.p,{children:"If you want to use a specific context from your kubeconfig, you can set it using:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl config use-context scs-vp12\n"})}),"\n",(0,t.jsx)(n.h3,{id:"helm-configuration",children:"Helm Configuration"}),"\n",(0,t.jsx)(n.p,{children:"For Ingress management, you need to add the NGINX Ingress repository and install the Ingress controller."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"helm install nginx-ingress ingress-nginx/ingress-nginx --namespace ingress-nginx --create-namespace\n"})}),"\n",(0,t.jsx)(n.h3,{id:"running-tests",children:"Running Tests"}),"\n",(0,t.jsx)(n.p,{children:"Writing Test Scenarios"}),"\n",(0,t.jsx)(n.p,{children:"Tests are written in .feature files using Gherkin syntax. Each scenario represents a feature of the application you want to test."}),"\n",(0,t.jsx)(n.p,{children:"Example feature file (container_creation.feature):"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-gherkin",children:"\nFeature: Container Management\n\n Scenario: Creating a simple container\n Given a Kubernetes cluster\n When I create a container named test-container\n Then the container test-container should be running\n\n Scenario: Creating a service for the container\n Given a container running a web server named web-container\n When I create a service for the container named web-container on 80\n Then the service for web-container should be running\n When I send an HTTP request to web-container\n Then the response status code should be 200\n"})}),"\n",(0,t.jsx)(n.h3,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,t.jsx)(n.p,{children:"You can run the tests using the behave command from the root of your project:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"./scs-health-monitor behave\n"})}),"\n",(0,t.jsx)(n.p,{children:"This will execute all the scenarios defined in the .feature files within the features directory."}),"\n",(0,t.jsx)(n.h3,{id:"example-command-to-run-a-specific-feature-file",children:"Example Command to Run a Specific Feature File"}),"\n",(0,t.jsx)(n.p,{children:"To run a specific feature file, use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"./scs-health-monitor behave container_level_testing/features/container_creation_deletion.feature\n"})}),"\n",(0,t.jsx)(n.h3,{id:"adding-new-features",children:"Adding New Features"}),"\n",(0,t.jsx)(n.p,{children:"Creating New Step Definitions"}),"\n",(0,t.jsx)(n.p,{children:"To add new behavior or extend existing features, define new steps in the Python files located in container_level_testing/features/steps/. These files map Gherkin steps to Python code."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:"@given('describe what test is doing')\ndef name_of_the_test(context):\n ## Body of the test \n"})}),"\n",(0,t.jsx)(n.h3,{id:"creating-new-feature-files",children:"Creating New Feature Files"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Create a New Feature File:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Add a new .feature file in the features directory."}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsx)(n.li,{children:"Write Scenarios in Gherkin Syntax:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Define the behavior you want to test using Given-When-Then steps."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-gherkin",children:"Feature: New Kubernetes Feature\n\n Scenario: A new feature scenario\n Given name of the function \n When name of another function with logic\n Then step with assertion to verify if step before was succeded \n"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsx)(n.li,{children:"Implement the Step Definitions:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Add the corresponding step definitions in the appropriate .py file under features/steps/."}),"\n",(0,t.jsx)(n.h4,{id:"modifying-existing-features",children:"Modifying Existing Features"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Update the Feature File:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Modify the .feature file to reflect the new behavior or changes."}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsx)(n.li,{children:"Update the Step Definitions:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Modify the corresponding step definitions in the .py file."}),"\n",(0,t.jsx)(n.h4,{id:"setting-up-ingress",children:"Setting Up Ingress"}),"\n",(0,t.jsx)(n.p,{children:"To add ingress resources:"}),"\n",(0,t.jsx)(n.p,{children:"Create Ingress YAML:"}),"\n",(0,t.jsx)(n.p,{children:"Create an ingress resource file my-ingress.yaml with the desired settings."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"apiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n name: my-ingress\nspec:\n rules:\n - host: my-project.local\n http:\n paths:\n - path: /\n pathType: Prefix\n backend:\n service:\n name: my-service\n port:\n number: 80\n\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsx)(n.li,{children:"Apply the Ingress Resource:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Use the following command to apply the ingress resource:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f my-ingress.yaml\n"})}),"\n",(0,t.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,t.jsx)(n.h3,{id:"common-errors",children:"Common Errors"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Connection Errors: Ensure that Kubernetes and Ingress services are correctly configured and running."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Port Conflicts: Ensure that the specified ports are not already in use. Modify the nodePort or use dynamic assignment."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Timeouts: Adjust the timeout settings in the test code if the service or container takes longer to initialize."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"debugging-tips",children:"Debugging Tips"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Check Pod Logs:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl logs <pod-name>\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Check Service and Pod Status:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl get services\nkubectl get pods\n"})}),"\n",(0,t.jsx)(n.h2,{id:"observability-stack",children:"Observability stack"}),"\n",(0,t.jsxs)(n.p,{children:["For more informations about setting up Observability Stack, please use this\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor/blob/main/docs/ObservabilityStack/SetupObservabilityStack.md",children:"file"})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"adding-fixesnew-functionalities-to-the-project-flow",children:"Adding fixes/new functionalities to the project flow:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Create branch for issue ",(0,t.jsx)(n.code,{children:"git checkout -b SPACECAT-<issue_number>-<issue_name>"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Add the changes made ",(0,t.jsx)(n.code,{children:"git add -u"})," or ",(0,t.jsx)(n.code,{children:"git add <file_name>"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Commit the changes using ",(0,t.jsx)(n.code,{children:'git commit -s -m "message"'}),".","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'The "-s" flag is important, the commit won\'t go through otherwise'}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["To push the current branch and the changes and set the remote as upstream, use ",(0,t.jsx)(n.code,{children:"git push --set-upstream origin SPACECAT-<issue_number>-<issue_name>"}),".","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Alternatively push the changes if the branch already exists in the remote repository."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:"After work is done, create a pull request for the branch."}),"\n",(0,t.jsx)(n.li,{children:"Ask another team member to review the changes, when he approves the changes, merge the chages into main branch."}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,t.jsx)(n.p,{children:"This framework provides a robust, BDD-based approach to testing Kubernetes clusters and resources. By following the above instructions, you can extend, modify, and run tests tailored to your specific needs."}),"\n",(0,t.jsx)(n.p,{children:"Feel free to customize the framework to accommodate new Kubernetes features and application requirements."})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>a});var s=i(96540);const t={},r=s.createContext(t);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/760c57f4.e141c5f5.js b/assets/js/760c57f4.e141c5f5.js new file mode 100644 index 0000000000..ca9f26067d --- /dev/null +++ b/assets/js/760c57f4.e141c5f5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[14385],{65180:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>u,frontMatter:()=>l,metadata:()=>s,toc:()=>h});const s=JSON.parse('{"id":"iaas/guides/deploy-guide/services/ceph","title":"Ceph","description":"In OSISM it is also possible to integrate and use existing Ceph clusters. It","source":"@site/docs/02-iaas/guides/deploy-guide/services/ceph.mdx","sourceDirName":"02-iaas/guides/deploy-guide/services","slug":"/iaas/guides/deploy-guide/services/ceph","permalink":"/docs/iaas/guides/deploy-guide/services/ceph","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/ceph.mdx","tags":[],"version":"current","sidebarPosition":50,"frontMatter":{"sidebar_label":"Ceph","sidebar_position":50},"sidebar":"docs","previous":{"title":"Logging & Monitoring","permalink":"/docs/iaas/guides/deploy-guide/services/logging-monitoring"},"next":{"title":"Ceph via Rook (technical preview)","permalink":"/docs/iaas/guides/deploy-guide/services/rook"}}');var t=r(74848),i=r(28453),a=r(11470),o=r(19365);const l={sidebar_label:"Ceph",sidebar_position:50},c="Ceph",d={},h=[{value:"RGW service",id:"rgw-service",level:2},{value:"Avoiding service restarts",id:"avoiding-service-restarts",level:2},{value:"Throttling service restarts",id:"throttling-service-restarts",level:2}];function p(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"ceph",children:"Ceph"})}),"\n",(0,t.jsxs)(n.p,{children:["In OSISM it is also possible to integrate and use existing Ceph clusters. It\nis not necessary to deploy Ceph with OSISM. If Ceph is deployed with OSISM, it\nshould be noted that OSISM does not claim to provide all possible features of Ceph.\nCeph provided with OSISM is intended to provide the storage for Glance, Nova, Cinder\nand Manila. In a specific way that has been implemented by OSISM for years. It\nshould be checked in advance whether the way in OSISM the Ceph deployment and the\nprovided features are sufficient. If this is not the case, it is recommended to\ndeploy Ceph in a different way directly and independently of OSISM. For possible\nopen source projects, please refer to\n",(0,t.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/cephadm/index.html",children:"cephadm"})," and\n",(0,t.jsx)(n.a,{href:"https://rook.io",children:"Rook"}),"."]}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsxs)(n.p,{children:["Before starting the Ceph deployment, the configuration and preparation of the\nOSD devices must be completed. The steps that are required for this can be found in the\n",(0,t.jsx)(n.a,{href:"/docs/iaas/guides/configuration-guide/ceph#osd-devices",children:"Ceph Configuration Guide"}),"."]})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy services."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Deploy ",(0,t.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/man/8/ceph-mon/",children:"ceph-mon"})," services"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceph-mons\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy ceph-mgr services"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceph-mgrs\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Deploy ",(0,t.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/man/8/ceph-osd/",children:"ceph-osd"})," services"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceph-osds\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Generate pools and keys. This step is only necessary for OSISM >= 7.0.0."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceph-pools\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy ceph-crash services"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceph-crash\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.admonition,{type:"info",children:[(0,t.jsx)(n.p,{children:"It's all done step by step here. It is also possible to do this in a single step.\nThis speeds up the entire process and avoids unnecessary restarts of individual\nservices."}),(0,t.jsxs)(a.A,{children:[(0,t.jsxs)(o.A,{value:"osism-7",label:"OSISM >= 7.0.0",children:[(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceph\n"})}),(0,t.jsx)(n.p,{children:"Generate pools and keys."}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceph-pools\n"})})]}),(0,t.jsx)(o.A,{value:"osism-6",label:"OSISM < 7.0.0",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceph-base\n"})})})]})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Get ceph keys. This places the necessary keys in ",(0,t.jsx)(n.code,{children:"/opt/configuration"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply copy-ceph-keys\n"})}),"\n",(0,t.jsx)(n.p,{children:"After run, these keys must be permanently added to the configuration repository\nvia Git."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"environments/infrastructure/files/ceph/ceph.client.admin.keyring\nenvironments/kolla/files/overlays/gnocchi/ceph.client.gnocchi.keyring\nenvironments/kolla/files/overlays/nova/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/nova/ceph.client.nova.keyring\nenvironments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder-backup.keyring\nenvironments/kolla/files/overlays/cinder/cinder-volume/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/manila/ceph.client.manila.keyring\nenvironments/kolla/files/overlays/glance/ceph.client.glance.keyring\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If the ",(0,t.jsx)(n.code,{children:"osism apply copy-ceph-keys"})," fails because the keys are not found in the ",(0,t.jsx)(n.code,{children:"/share"}),"\ndirectory, this can be ignored. The keys of the predefined keys (e.g. for Manila) were\nthen not created as they are not used. If you only use Ceph and do not need the predefined\nkeys for OpenStack at all, you can also overwrite the ",(0,t.jsx)(n.code,{children:"ceph_kolla_keys"})," parameter to skip\nthese keys."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:"ceph_kolla_keys: []\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"After the Ceph keys have been persisted in the configuration repository, the Ceph\nclient can be deployed."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply cephclient\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Enable and prepare the use of the Ceph dashboard."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceph-bootstrap-dashboard\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"rgw-service",children:"RGW service"}),"\n",(0,t.jsx)(n.p,{children:"Deployment of the Ceph RGW Service is optional. How the Ceph RGW service can be deployed\nand integrated into OpenStack is described here."}),"\n",(0,t.jsxs)(n.admonition,{type:"info",children:[(0,t.jsxs)(n.p,{children:["If an initial deployment is performed and Ceph RGW is not added to an existing deployment,\nsteps 4 and 5 are ",(0,t.jsx)(n.strong,{children:"not"})," required."]}),(0,t.jsxs)(n.p,{children:["Step 3 is then performed ",(0,t.jsx)(n.strong,{children:"later after"})," the OpenStack Keystone service has been deployed."]})]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"/docs/iaas/guides/configuration-guide/ceph#rgw-service",children:"Configure the RGW service"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Apply role ",(0,t.jsx)(n.code,{children:"ceph-rgws"})," to deploy the Ceph RGW services."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceph-rgws\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Apply role ",(0,t.jsx)(n.code,{children:"kolla-ceph-rgw"})," to add the OpenStack endpoint.\nIf an initial deployment is performed and Ceph RGW is not added\nto an existing deployment run this step later after the OpenStack\nKeystone service has been deployed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply kolla-ceph-rgw\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Apply role ",(0,t.jsx)(n.code,{children:"loadbalancer"})," to add the HAProxy backend and frontend."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply loadbalancer\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Apply role ",(0,t.jsx)(n.code,{children:"horizon"})," to enable the Swift dashboard."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply horizon\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"avoiding-service-restarts",children:"Avoiding service restarts"}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsx)(n.p,{children:"Usable from OSISM 7.0.3 onwards."})}),"\n",(0,t.jsx)(n.p,{children:"If Ceph services are deployed sequentially, this can lead to unwanted service restarts.\nThis can also happen if, for example, new OSDs are added later or a new control node is\nadded."}),"\n",(0,t.jsx)(n.p,{children:"The Ceph RGW services are deployed here without restarting the Ceph OSD services."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceph-rgws -e ceph_handler_osds_restart=False\n"})}),"\n",(0,t.jsx)(n.p,{children:"The following parameters are available. Any number of parameters can be used with a single command."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"ceph_handler_crash_restart\nceph_handler_mdss_restart\nceph_handler_mgrs_restart\nceph_handler_mons_restart\nceph_handler_osds_restart\nceph_handler_rbdmirrors_restart\nceph_handler_rgws_restart\n"})}),"\n",(0,t.jsx)(n.h2,{id:"throttling-service-restarts",children:"Throttling service restarts"}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsx)(n.p,{children:"Usable from OSISM 7.0.3 onwards."})}),"\n",(0,t.jsx)(n.p,{children:"Sometimes service restarts are required. For example, if the configuration has changed\nor if new OSDs have been added. It may be necessary and useful to only restart the\nservices on a specific number of nodes at a specific time."}),"\n",(0,t.jsxs)(n.p,{children:["Further information on throttling can be found in the\n",(0,t.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_strategies.html#restricting-execution-with-throttle",children:"Ansible documentation"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The Ceph OSD services are deployed here. If there is a restart required of other OSDs\nthat are already running, these restarts are executed on a maximum of 2 nodes at the\nsame time. The OSD services themselves on a node are always restarted one after the other\nand never all at the same time."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceph-osds -e ceph_handler_osds_restart_throttle=2\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If the nodes are to be processed one after the other, ",(0,t.jsx)(n.code,{children:"ceph_handler_osds_restart_throttle=1"}),"\ncan be used."]}),"\n",(0,t.jsx)(n.p,{children:"The following parameters are available. Any number of parameters can be used with a single command."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"ceph_handler_crash_restart_throttle\nceph_handler_mdss_restart_throttle\nceph_handler_mgrs_restart_throttle\nceph_handler_mons_restart_throttle\nceph_handler_osds_restart_throttle\nceph_handler_rbdmirrors_restart_throttle\nceph_handler_rgws_restart_throttle\n"})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},19365:(e,n,r)=>{r.d(n,{A:()=>a});r(96540);var s=r(18215);const t={tabItem:"tabItem_Ymn6"};var i=r(74848);function a(e){let{children:n,hidden:r,className:a}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,s.A)(t.tabItem,a),hidden:r,children:n})}},11470:(e,n,r)=>{r.d(n,{A:()=>_});var s=r(96540),t=r(18215),i=r(23104),a=r(56347),o=r(205),l=r(57485),c=r(31682),d=r(70679);function h(e){return s.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:n,children:r}=e;return(0,s.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:r,attributes:s,default:t}}=e;return{value:n,label:r,attributes:s,default:t}}))}(r);return function(e){const n=(0,c.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,r])}function u(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:r}=e;const t=(0,a.W6)(),i=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,l.aZ)(i),(0,s.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(t.location.search);n.set(i,e),t.replace({...t.location,search:n.toString()})}),[i,t])]}function f(e){const{defaultValue:n,queryString:r=!1,groupId:t}=e,i=p(e),[a,l]=(0,s.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!u({value:n,tabValues:r}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const s=r.find((e=>e.default))??r[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:i}))),[c,h]=m({queryString:r,groupId:t}),[f,x]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,i]=(0,d.Dv)(r);return[t,(0,s.useCallback)((e=>{r&&i.set(e)}),[r,i])]}({groupId:t}),y=(()=>{const e=c??f;return u({value:e,tabValues:i})?e:null})();(0,o.A)((()=>{y&&l(y)}),[y]);return{selectedValue:a,selectValue:(0,s.useCallback)((e=>{if(!u({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),h(e),x(e)}),[h,x,i]),tabValues:i}}var x=r(92303);const y={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var v=r(74848);function g(e){let{className:n,block:r,selectedValue:s,selectValue:a,tabValues:o}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,i.a_)(),d=e=>{const n=e.currentTarget,r=l.indexOf(n),t=o[r].value;t!==s&&(c(n),a(t))},h=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;n=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;n=l[r]??l[l.length-1];break}}n?.focus()};return(0,v.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":r},n),children:o.map((e=>{let{value:n,label:r,attributes:i}=e;return(0,v.jsx)("li",{role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,ref:e=>l.push(e),onKeyDown:h,onClick:d,...i,className:(0,t.A)("tabs__item",y.tabItem,i?.className,{"tabs__item--active":s===n}),children:r??n},n)}))})}function j(e){let{lazy:n,children:r,selectedValue:i}=e;const a=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=a.find((e=>e.props.value===i));return e?(0,s.cloneElement)(e,{className:(0,t.A)("margin-top--md",e.props.className)}):null}return(0,v.jsx)("div",{className:"margin-top--md",children:a.map(((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==i})))})}function b(e){const n=f(e);return(0,v.jsxs)("div",{className:(0,t.A)("tabs-container",y.tabList),children:[(0,v.jsx)(g,{...n,...e}),(0,v.jsx)(j,{...n,...e})]})}function _(e){const n=(0,x.A)();return(0,v.jsx)(b,{...e,children:h(e.children)},String(n))}},28453:(e,n,r)=>{r.d(n,{R:()=>a,x:()=>o});var s=r(96540);const t={},i=s.createContext(t);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/767805d3.fde639bc.js b/assets/js/767805d3.fde639bc.js new file mode 100644 index 0000000000..f8cf7c515a --- /dev/null +++ b/assets/js/767805d3.fde639bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[18519],{61396:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>a});const i=JSON.parse('{"id":"iaas/guides/configuration-guide/configuration-repository","title":"Configuration Repository","description":"The configuration required for an OSISM managed cluster is stored in a single Git","source":"@site/docs/02-iaas/guides/configuration-guide/configuration-repository.md","sourceDirName":"02-iaas/guides/configuration-guide","slug":"/iaas/guides/configuration-guide/configuration-repository","permalink":"/docs/iaas/guides/configuration-guide/configuration-repository","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/configuration-repository.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Configuration repository","sidebar_position":10},"sidebar":"docs","previous":{"title":"Configuration Guide","permalink":"/docs/iaas/guides/configuration-guide/"},"next":{"title":"Inventory","permalink":"/docs/iaas/guides/configuration-guide/inventory"}}');var s=t(74848),r=t(28453);const o={sidebar_label:"Configuration repository",sidebar_position:10},l="Configuration Repository",d={},a=[{value:"Creating a new configuration repository",id:"creating-a-new-configuration-repository",level:2},{value:"Step 1: Preparation",id:"step-1-preparation",level:3},{value:"Step 2: Run Cookiecutter",id:"step-2-run-cookiecutter",level:3},{value:"Step 3: Upload the new configuration to the remote git repository",id:"step-3-upload-the-new-configuration-to-the-remote-git-repository",level:3},{value:"Step 4: Post-processing of the generated configuration",id:"step-4-post-processing-of-the-generated-configuration",level:3},{value:"Secrets",id:"secrets",level:4},{value:"Manager inventory",id:"manager-inventory",level:4},{value:"Global inventory",id:"global-inventory",level:4},{value:"DNS servers",id:"dns-servers",level:4},{value:"NTP servers",id:"ntp-servers",level:4},{value:"Certificates",id:"certificates",level:4},{value:"Using latest",id:"using-latest",level:2},{value:"Parameter reference",id:"parameter-reference",level:2},{value:"Configuration repository layout",id:"configuration-repository-layout",level:2},{value:"Synchronising the configuration repository",id:"synchronising-the-configuration-repository",level:2},{value:"Locks",id:"locks",level:2},{value:"Working with encrypted files",id:"working-with-encrypted-files",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"configuration-repository",children:"Configuration Repository"})}),"\n",(0,s.jsx)(n.p,{children:"The configuration required for an OSISM managed cluster is stored in a single Git\nmonorepo, the configuration repository."}),"\n",(0,s.jsx)(n.h2,{id:"creating-a-new-configuration-repository",children:"Creating a new configuration repository"}),"\n",(0,s.jsxs)(n.p,{children:["The initial content for this configuration repository is generated using the\n",(0,s.jsx)(n.a,{href:"https://github.com/osism/cfg-cookiecutter",children:"Cookiecutter"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Cookiecutter generates a simple initial configuration for your new cluster by prompting\nyou for the basic details of the new cluster."}),"\n",(0,s.jsxs)(n.p,{children:["The configuration repository is not created on the future Manager node. It is created on a\nlocal workstation. If the local workstation cannot be used for this purpose, a dedicated\nvirtual system can be used. For more information on this topic, refer to the\n",(0,s.jsx)(n.a,{href:"/docs/iaas/guides/deploy-guide/seed",children:"Seed Deploy Guide"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"step-1-preparation",children:"Step 1: Preparation"}),"\n",(0,s.jsxs)(n.p,{children:["First decide where to store your Git repository The content generated by the cookiecutter in\nthe ",(0,s.jsx)(n.code,{children:"output/configuration"})," directory is committed to a new Git repository. By default, the\nconfiguration repository is assumed to be on GitHub. This can also be GitLab or an internal\nGit service as well."]}),"\n",(0,s.jsxs)(n.p,{children:["Host and path to the Git repository are specified by the ",(0,s.jsx)(n.code,{children:"git_"})," parameters. These are\nrequested in step 2. The ",(0,s.jsx)(n.code,{children:"git_"})," parameters do not specify the path to the cookiecutter\nto use."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" [8/20] git_host (github.com):\n [9/20] git_port (22):\n [10/20] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY): regiocloud/configuration\n [11/20] git_username (git):\n [12/20] git_version (main):\n"})}),"\n",(0,s.jsxs)(n.p,{children:["In this case, the generated configuration in the ",(0,s.jsx)(n.code,{children:"output/configuration"})," directory is\nstored on GitHub in the ",(0,s.jsx)(n.code,{children:"regiocloud/configuration"})," repository."]}),"\n",(0,s.jsxs)(n.p,{children:["See the ",(0,s.jsx)(n.a,{href:"#parameter-reference",children:"parameter reference"})," for more details. The parameters\nlisted there will be queried during the execution of Cookiecutter."]}),"\n",(0,s.jsx)(n.h3,{id:"step-2-run-cookiecutter",children:"Step 2: Run Cookiecutter"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The directory ",(0,s.jsx)(n.code,{children:"output"})," is created and used as output volume. It is only necessary to create the empty\ndirectory here."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"mkdir output\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The Cookiecutter runs inside a container. ",(0,s.jsx)(n.a,{href:"https://docs.docker.com/engine/install/",children:"Docker must be usable on the system"}),"\nwhere the Cookiecutter will be used. It should also work with Podman."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'docker run \\\n -e TARGET_UID="$(id -u)" \\\n -e TARGET_GID="$(id -g)" \\\n -v $(pwd)/output:/output \\\n --rm -it quay.io/osism/cookiecutter\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A few parameters are requested. The parameters are documented in detail in the ",(0,s.jsx)(n.a,{href:"#parameter-reference",children:"parameter reference"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["If you want to use the ",(0,s.jsx)(n.code,{children:"latest"})," version, this is done using the ",(0,s.jsx)(n.code,{children:"manager_version"})," parameter. By default,\nthis is always set to the latest stable version."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"manager_version [7.0.4]: latest\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"manager_version"})," parameter is set to ",(0,s.jsx)(n.code,{children:"latest"})," it is also possible to explicitly\nset the ",(0,s.jsx)(n.code,{children:"openstack_version"})," and the ",(0,s.jsx)(n.code,{children:"ceph_version"})," explicitly."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"[1/19] with_ceph (1):\n[2/19] with_keycloak (0):\n[3/19] ceph_network(192.168.16.0/20):\n[4/19] ceph_version (quincy):\n[5/19] domain (osism.xyz):\n[6/19] fqdn_external (api.osism.xyz):\n[7/19] fqdn_internal (api-int.osism.xyz):\n[8/19] git_host (github.com):\n[9/19] git_port (22):\n[10/19] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY):\n[11/19] git_username (git):\n[12/19] git_version (main):\n[13/19] ip_external (192.168.16.254):\n[14/19] ip_internal (192.168.16.9):\n[15/19] manager_version (7.0.4):\n[16/19] name_server (149.112.112.112):\n[17/19] ntp_server (de.pool.ntp.org):\n[18/19] openstack_version (2023.2):\n[19/19] project_name (configuration):\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"step-3-upload-the-new-configuration-to-the-remote-git-repository",children:"Step 3: Upload the new configuration to the remote git repository"}),"\n",(0,s.jsxs)(n.p,{children:["Add the initial configuration state to the repository. How to add a deploy key on GitHub is documented in\n",(0,s.jsx)(n.a,{href:"https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys",children:"Managing deploy keys"}),".\nRead permissions are sufficient."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'$ git clone git@github.com:YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY.git YOUR_NEW_CONFIGURATION_REPOSITORY\n$ cp -r output/configuration/{*,.gitignore} YOUR_NEW_CONFIGURATION_REPOSITORY\n$ cd YOUR_NEW_CONFIGURATION_REPOSITORY\n$ git add -A .\n$ git commit -m "Initial commit after bootstrap"\n$ git push\n'})}),"\n",(0,s.jsx)(n.p,{children:"The content is now committed to the Git repository that was created earlier in the process."}),"\n",(0,s.jsxs)(n.admonition,{type:"warning",children:[(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"secrets"})," directory is not stored in the Git repository. Its contents can be\nstored in a trusted location."]}),(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"secrets"})," directory contains an SSH key pair which is used as the deploy key to\nmake the configuration repository available on the manager node later. Write access\nis not required. The public SSH key is stored in the ",(0,s.jsx)(n.code,{children:"secrets/id_rsa.configuration.pub"})," file."]})]}),"\n",(0,s.jsx)(n.h3,{id:"step-4-post-processing-of-the-generated-configuration",children:"Step 4: Post-processing of the generated configuration"}),"\n",(0,s.jsxs)(n.p,{children:["The configuration repository that is initially created with the Cookiecutter is not immediately usable.\nFor example, the inventory needs to be built. All other information can be found in the\n",(0,s.jsx)(n.a,{href:"../configuration-guide/",children:"Configuration Guide"}),". Use ",(0,s.jsx)(n.code,{children:"git"})," to version all your configuration changes."]}),"\n",(0,s.jsx)(n.p,{children:"The following 6 points must be changed after the initial creation of the configuration repository."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#secrets",children:"Secrets"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#manager-inventory",children:"Manager inventory"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#global-inventory",children:"Global inventory"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#dns-servers",children:"DNS servers"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#ntp-servers",children:"NTP servers"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#certificates",children:"Certificates"})}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"secrets",children:"Secrets"}),"\n",(0,s.jsxs)(n.p,{children:["The password for Ansible Vault encrypted files, is stored in ",(0,s.jsx)(n.code,{children:"secrets/vaultpass"}),". Since the ",(0,s.jsx)(n.code,{children:"secrets"})," directory\nis not added to the configuration repository, it is important to store it in a password vault of your choice."]}),"\n",(0,s.jsxs)(n.p,{children:["The password of the generated Keepass file is ",(0,s.jsx)(n.code,{children:"password"}),". This should be changed when using the Keepass file.\nIf possible, an existing password vault should be used."]}),"\n",(0,s.jsx)(n.h4,{id:"manager-inventory",children:"Manager inventory"}),"\n",(0,s.jsx)(n.p,{children:"The information required to perform the initial bootstrap of the manager node and the initial\ndeployment of the manager service from the seed Node is provided in the inventory of the manager\nenvironment."}),"\n",(0,s.jsxs)(n.p,{children:["In the Cookiecutter, a node ",(0,s.jsx)(n.code,{children:"node01"})," is defined as an example in the manager inventory as well as\nin the global inventory. The name of this node must be changed to match the name of the node used\nas manager in your own cluster."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Roles"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Manager role"}),"\n",(0,s.jsxs)(n.p,{children:["The name of the node on which the manager service is to be deployed is\nadded to inventory group ",(0,s.jsx)(n.code,{children:"manager"})," in file ",(0,s.jsx)(n.code,{children:"environments/manager/hosts"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Only the ",(0,s.jsx)(n.code,{children:"manager"})," inventory group is available in ",(0,s.jsx)(n.code,{children:"environments/manager/hosts"}),". There are no\nother groups there."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",metastring:'title="environments/manager/hosts"',children:"[manager]\nnode01\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Host vars"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ansible section"}),"\n",(0,s.jsx)(n.p,{children:"The IP address where the node can be reached via SSH from the manager node. If DHCP is used after the\ninitial provisioning to assign an initial IP address to the nodes, the address assigned via DHCP is\ninitially used here and later changed to the static IP address."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/host_vars/node01.yml"',children:"ansible_host: 192.168.16.10\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Generic section"}),"\n",(0,s.jsx)(n.p,{children:"The network interface on which the internal communication of the cluster will take place. If the\ninternal interface does not yet exist at the time the configuration is created, e.g. because it is a\nbond interface or VLAN interface that is only created by the static network configuration, it can be\nalready used here."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/host_vars/node01.yml"',children:"internal_interface: eno1\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Network section"}),"\n",(0,s.jsxs)(n.p,{children:["The static and complete network configuration of the node. Further details on creating the\nnetwork configuration in the ",(0,s.jsx)(n.a,{href:"../configuration-guide/network",children:"network configuration guide"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/host_vars/node01.yml"',children:'network_ethernets:\n eno1:\n addresses:\n - "192.168.16.10/20"\n gateway4: "192.168.16.1"\n mtu: 1500\n'})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"global-inventory",children:"Global inventory"}),"\n",(0,s.jsxs)(n.p,{children:["In the Cookiecutter, a node ",(0,s.jsx)(n.code,{children:"node01"})," is defined as an example in the manager inventory as well as\nin the global inventory. The name of this node must be changed to match the name of the node used\nas manager in your own cluster."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Roles"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Generic role"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:'# The "all" group is not used in OSISM. Therefore it is important\n# that all nodes are explicitly listed here.\n[generic]\nnode01\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Manager role"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes that act as manager (sometimes called deployment node)\n# are included in this group.\n[manager]\nnode01\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Monitoring role"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes which are intended for monitoring services belong to\n# this group\n[monitoring]\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Control role"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes that serve as controllers, so things like scheduler,\n# API or database run there, of the environment.\n[control]\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Compute role"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Virtual systems managed by OpenStack Nova are placed on\n# nodes in this group.\n[compute]\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Network role"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Network resources managed by OpenStack Neutron, such as\n# L3 routers, are placed on these nodes. This group has nothing\n# to do with the general network configuration.\n[network]\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ceph control role"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes that serve as controllers for Ceph, so things like the\n# Ceph Monitor service run here.\n[ceph-control]\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ceph resource role"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# The storage available in these systems is provided in the\n# form of OSDs for Ceph.\n[ceph-resource]\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ceph rgw role"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"[ceph-rgw:children]\nceph-control\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Host vars"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ansible section"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"# NOTE: Address where the node can be reached via SSH.\nansible_host: 192.168.16.10\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Generic section"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"internal_interface: eno1\n\n# NOTE: The address of the internal interface.\ninternal_address: 192.168.16.10\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Netdata section"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"netdata_host_type: client\n\n# NOTE: Uncomment this when this node should be a Netdata server.\n# netdata_host_type: server\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Network section"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:'# NOTE: This is the initial management interface. Further interfaces can be added.\n# DOCS: https://osism.tech/docs/guides/configuration-guide/network\n\nnetwork_ethernets:\n eno1:\n addresses:\n - "192.168.16.10/20"\n gateway4: "192.168.16.1"\n mtu: 1500\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Kolla section"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"network_interface: eno1\n\n# api_interface:\n# bifrost_network_interface:\n# dns_interface:\n# kolla_external_vip_interface:\n# migration_interface:\n# neutron_external_interface:\n# octavia_network_interface:\n# storage_interface:\n# tunnel_interface:\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ceph section"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"# NOTE: Uncomment this when this node is a part of the Ceph cluster.\n# monitor_address:\n# radosgw_address:\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"# NOTE: Uncomment this when this node should be a OSD node.\n# DOCS: https://osism.tech/docs/guides/configuration-guide/ceph#lvm-devices\n\n# ceph_osd_devices:\n# sdb:\n# sdc:\n# sdd:\n# sde:\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"dns-servers",children:"DNS servers"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"resolvconf_nameserver:\n - 8.8.8.8\n - 9.9.9.9\n"})}),"\n",(0,s.jsx)(n.h4,{id:"ntp-servers",children:"NTP servers"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"chrony_servers:\n - 1.de.pool.ntp.org\n - 2.de.pool.ntp.org\n - 3.de.pool.ntp.org\n - 4.de.pool.ntp.org\n"})}),"\n",(0,s.jsx)(n.h4,{id:"certificates",children:"Certificates"}),"\n",(0,s.jsxs)(n.p,{children:["The certificates must be created and added in the configuration repository in the files\n",(0,s.jsx)(n.code,{children:"environments/kolla/certificates/haproxy.pem"})," and ",(0,s.jsx)(n.code,{children:"environments/kolla/certificates/haproxy-internal.pem"}),". Further information in the ",(0,s.jsx)(n.a,{href:"/docs/iaas/guides/configuration-guide/loadbalancer",children:"Loadbalancer Configuration Guide"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"If no certificates are to be used, the encryption must be deactivated. This is not\nrecommended."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'kolla_enable_tls_external: "yes"\nkolla_enable_tls_internal: "yes"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"using-latest",children:"Using latest"}),"\n",(0,s.jsxs)(n.p,{children:["If you want to use the latest version, this is done using the ",(0,s.jsx)(n.code,{children:"manager_version"})," parameter. By default,\nthis is always set to the latest stable version."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"manager_version [7.0.0]: latest\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"manager_version"})," parameter is set to ",(0,s.jsx)(n.code,{children:"latest"})," it is also possible to explicitly\nset the ",(0,s.jsx)(n.code,{children:"openstack_version"})," and the ",(0,s.jsx)(n.code,{children:"ceph_version"})," explicitly."]}),"\n",(0,s.jsx)(n.h2,{id:"parameter-reference",children:"Parameter reference"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Description"}),(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"ceph_network"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Address range for Ceph's network"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"192.168.16.0/20"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"ceph_version"})}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:["The version of Ceph. When using a stable OSISM release (",(0,s.jsx)(n.code,{children:"manager_version != latest"}),"), this value is ignored"]}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"quincy"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"domain"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"The domain used by hostnames"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"osism.xyz"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"fqdn_external"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"External API FQDN"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"api.osism.xyz"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"fqdn_internal"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Internal API FQDN"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"api-int.osism.xyz"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"git_host"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Address of the used Git server"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"github.com"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"git_port"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Port of the used Git server"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"22"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"git_repository"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Path to the git configuration repository"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"YOUR_ORG/YOUR_CONFIGURATION_REPOSITORY"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"git_username"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Username of the git repository"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"git"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"git_version"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Git branch name"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"main"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"ip_external"})}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:["The external IP address of the API (resolves to ",(0,s.jsx)(n.code,{children:"fqdn_external"}),")"]}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"192.168.16.254"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"ip_internal"})}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:["The internal IP address of the API (resolves to ",(0,s.jsx)(n.code,{children:"fqdn_internal"}),")"]}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"192.168.16.9"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"manager_version"})}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:["The version of OSISM. An overview of available OSISM releases can be found ",(0,s.jsx)(n.a,{href:"https://osism.tech/docs/release-notes/",children:"here"})]}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"7.0.4"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"name_server"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Nameserver. Only one nameserver is set here because the query of multiple values in Cookiecutter is weird. Add more nameservers afterward."}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"149.112.112.112"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"ntp_server"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"NTP server. Only one NTP server is set here because the query of multiple values in Cookiecutter is weird. Add more NTP servers afterward."}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"de.pool.ntp.org"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"openstack_version"})}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:["The version of OpenStack. When using a stable OSISM release (",(0,s.jsx)(n.code,{children:"manager_version != latest"}),"), this value is ignored"]}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"2023.2"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"project_name"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Name of the configuration repository directory"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"configuration"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"with_ceph"})}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:[(0,s.jsx)(n.code,{children:"1"})," to use Ceph, ",(0,s.jsx)(n.code,{children:"0"})," to not use Ceph"]}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"1"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"with_keycloak"})}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:[(0,s.jsx)(n.code,{children:"1"})," to prepare Keycloak integration , ",(0,s.jsx)(n.code,{children:"0"})," to not prepare Keycloak integration"]}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"0"})})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"configuration-repository-layout",children:"Configuration repository layout"}),"\n",(0,s.jsxs)(n.p,{children:["A configuration repository always has the same layout. This section describes\nthe content available in a configuration repository. In the section\n",(0,s.jsx)(n.a,{href:"#creating-a-new-configuration-repository",children:"Creating a new configuration repository"})," is the creation\nof a new configuration repository documented."]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Directory/File"}),(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"environments"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"inventory"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"netbox"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"optional"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"requirements.txt"})}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:["In the ",(0,s.jsx)(n.code,{children:"requirements.txt"})," the necessary dependencies are listed to be able to execute Gilt."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"gilt.yml"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"Makefile"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"gilt.yaml"})}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:[(0,s.jsx)(n.a,{href:"https://gilt.readthedocs.io",children:"Gilt"})," is a Git layering tool. We use Gilt to maintain the image versions, Ansible configuration and scripts within the ",(0,s.jsx)(n.code,{children:"environments/manager"})," directory."]})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"synchronising-the-configuration-repository",children:"Synchronising the configuration repository"}),"\n",(0,s.jsxs)(n.p,{children:["Once the manager has been deployed and the configuration repository has been initially\ntransferred to the manager node, the configuration repository can be updated using\n",(0,s.jsx)(n.code,{children:"osism apply configuration"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"If local changes were made directly in the configuration repository on the manager node,\nthese are overwritten."}),"\n",(0,s.jsx)(n.h2,{id:"locks",children:"Locks"}),"\n",(0,s.jsx)(n.p,{children:"It is possible to lock parts of the configuration repository or the complete configuration\nrepository. It is then no longer possible to execute plays assigned to these parts in the\nlocked parts. This makes it possible to prevent the execution of plays in specific areas."}),"\n",(0,s.jsxs)(n.p,{children:["To lock an environment, a .lock file is created in the corresponding directory of the environment.\nFor example, the file ",(0,s.jsx)(n.code,{children:"environments/kolla/.lock"})," locks the Kolla environment."]}),"\n",(0,s.jsx)(n.p,{children:"If you try to execute a play in the Kolla environment, an error message is displayed."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ osism apply common\n2024-06-02 10:52:44 | INFO | Task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) was prepared for execution.\n2024-06-02 10:52:44 | INFO | It takes a moment until task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) has been started and output is visible here.\nERROR: The environment kolla is locked via the configuration repository.\n"})}),"\n",(0,s.jsxs)(n.p,{children:["File ",(0,s.jsx)(n.code,{children:"environments/.lock"})," is created to lock everything."]}),"\n",(0,s.jsx)(n.p,{children:"If you try to execute a play, an error message is displayed."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ osism apply facts\n2024-06-02 10:53:08 | INFO | Task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) was prepared for execution.\n2024-06-02 10:53:08 | INFO | It takes a moment until task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) has been started and output is visible here.\nERROR: The configuration repository is locked.\n"})}),"\n",(0,s.jsx)(n.h2,{id:"working-with-encrypted-files",children:"Working with encrypted files"}),"\n",(0,s.jsx)(n.p,{children:"To make it easier to work with encrypted files, the configuration repository has several make\ntargets that can be used to view encrypted files and to edit encrypted files."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Show secrets in all encrypted files."}),"\n",(0,s.jsxs)(n.p,{children:["This opens a pager, e.g. less, and you can search with ",(0,s.jsx)(n.code,{children:"/"})," for specific files, keys and passwords."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"make ansible_vault_show FILE=all\nmake ansible_vault_show FILE=environments/secrets.yml\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Change or add secrets in an encrypted file with the editor set in ",(0,s.jsx)(n.code,{children:" $EDITOR"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"make ansible_vault_edit FILE=environments/secrets.yml EDITOR=nano\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Re-encrypt all encrypted files with a new key."}),"\n",(0,s.jsxs)(n.p,{children:["This creates a new ",(0,s.jsx)(n.code,{children:"secrets/vaultpass"})," and creates backups of the old to\n",(0,s.jsx)(n.code,{children:"secrets/vaultpass_backup_<timestamp>"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"make ansible_vault_rekey\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>l});var i=t(96540);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/777b847b.7e264f36.js b/assets/js/777b847b.7e264f36.js new file mode 100644 index 0000000000..3474ff0d54 --- /dev/null +++ b/assets/js/777b847b.7e264f36.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[79001],{30406:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>l,default:()=>d,frontMatter:()=>o,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stacks/continuous-integration","title":"Continuous integration","description":"Project cluster-stacks use the SCS Zuul CI platform to","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stacks/continuous-integration.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stacks","slug":"/container/components/cluster-stacks/components/cluster-stacks/continuous-integration","permalink":"/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stacks/continuous-integration.md","tags":[],"version":"current","frontMatter":{}}');var i=s(74848),c=s(28453);const o={},l="Continuous integration",r={},a=[{value:"Configuration",id:"configuration",level:2},{value:"Pipelines",id:"pipelines",level:2},{value:"Jobs",id:"jobs",level:2},{value:"Secrets",id:"secrets",level:3},{value:"Job customization",id:"job-customization",level:3}];function u(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,c.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"continuous-integration",children:"Continuous integration"})}),"\n",(0,i.jsxs)(n.p,{children:["Project ",(0,i.jsx)(n.code,{children:"cluster-stacks"})," use the ",(0,i.jsx)(n.a,{href:"https://zuul.scs.community",children:"SCS Zuul"})," CI platform to\ndrive its continuous integration tests. The project is registered under the ",(0,i.jsx)(n.a,{href:"https://zuul.scs.community/t/SCS/projects",children:"SCS tenant"}),"\nand therefore is able to use a set of pre-defined pipelines, jobs, and ansible roles that the\nSCS Zuul instance defines and imports. If you want to explore currently available SCS pipelines,\nvisit the ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-config",children:"SCS zuul-config"})," project.\nIf you want to see the full list of jobs that are available, visit the ",(0,i.jsx)(n.a,{href:"https://zuul.scs.community/t/SCS/jobs",children:"SCS Zuul UI"}),".\nAnd if you are looking for some handy ansible role that SCS Zuul imports, visit the ",(0,i.jsx)(n.a,{href:"https://opendev.org/zuul/zuul-jobs/src/branch/master/roles",children:"source"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Refer to the SCS ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide.md",children:"Zuul users guide"})," and/or\n",(0,i.jsx)(n.a,{href:"https://zuul-ci.org/docs/",children:"Zuul docs"})," for further details on how to define and use Zuul\nCI/CD pipelines and jobs."]}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsxs)(n.p,{children:["[!NOTE]\nIf you are interested in the Zuul CI platform and want to deploy your own development instance of it,\nthen read the official ",(0,i.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/tutorials/quick-start.html",children:"quick-start"})," manual\nor visit ",(0,i.jsx)(n.a,{href:"https://github.com/matofederorg/zuul-config?tab=readme-ov-file#zuul-ci",children:"this"})," tutorial which aims a connect\nof Zuul CI platform with a GitHub organization."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["SCS Zuul automatically recognizes ",(0,i.jsx)(n.code,{children:".zuul.yaml"})," configuration file that is located in the\ncluster-stacks's root. This file informs Zuul about the project's ",(0,i.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/project.html#attr-project.default-branch",children:"default-branch"})," and\npreferred ",(0,i.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/project.html#attr-project.merge-mode",children:"merge-mode"}),".\nIt also references ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-config",children:"SCS Zuul pipelines"})," and\ntheir jobs used by the cluster-stacks project. Then, jobs link Ansible playbooks that contain\ntasks for actual CI testing."]}),"\n",(0,i.jsx)(n.p,{children:"See relevant CI configuration files:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-text",children:"\u251c\u2500\u2500 .zuul.yaml\n\u251c\u2500\u2500 playbooks\n\u2502 \u251c\u2500\u2500 dependencies.yaml\n\u2502 \u251c\u2500\u2500 openstack\n\u2502 \u2502 \u251c\u2500\u2500 e2e.yaml\n\u2502 \u2502 \u251c\u2500\u2500 templates\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 mgmt-cluster-config.yaml.j2\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 cluster.yaml.j2\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 cluster-stack-template.yaml.j2\n"})}),"\n",(0,i.jsx)(n.h2,{id:"pipelines",children:"Pipelines"}),"\n",(0,i.jsxs)(n.p,{children:["This section describes an ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-config/blob/main/zuul.d/gh_pipelines.yaml",children:"SCS Zuul pipelines"})," that are used by the cluster-stacks project."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"e2e-test"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["It is triggered by the ",(0,i.jsx)(n.code,{children:"e2e-test"})," label in the opened PR"]}),"\n",(0,i.jsxs)(n.li,{children:["It executes ",(0,i.jsx)(n.code,{children:"e2e-openstack-conformance"})," job"]}),"\n",(0,i.jsxs)(n.li,{children:["It applies the PR label ",(0,i.jsx)(n.code,{children:"successful-e2e-test"})," and leaves an informative PR comment when the ",(0,i.jsx)(n.code,{children:"e2e-openstack-conformance"})," job succeeded"]}),"\n",(0,i.jsxs)(n.li,{children:["It applies the PR label ",(0,i.jsx)(n.code,{children:"failed-e2e-test"})," and leaves an informative PR comment when the ",(0,i.jsx)(n.code,{children:"e2e-openstack-conformance"})," job failed"]}),"\n",(0,i.jsxs)(n.li,{children:["It applies the PR label ",(0,i.jsx)(n.code,{children:"cancelled-e2e-test"})," and leaves an informative PR comment when the ",(0,i.jsx)(n.code,{children:"e2e-openstack-conformance"})," job is canceled"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"unlabel-on-update-e2e-test"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["It is triggered by the PR update only when PR contains the ",(0,i.jsx)(n.code,{children:"successful-e2e-test"})," label"]}),"\n",(0,i.jsx)(n.li,{children:"It ensures that any PR update invalidates a previous successful e2e test"}),"\n",(0,i.jsxs)(n.li,{children:["It removes ",(0,i.jsx)(n.code,{children:"successful-e2e-test"})," label from the PR"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"e2e-quick-test"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["It is triggered by the ",(0,i.jsx)(n.code,{children:"e2e-quick-test"})," label in the opened PR"]}),"\n",(0,i.jsxs)(n.li,{children:["It executes ",(0,i.jsx)(n.code,{children:"e2e-openstack-quick"})," job"]}),"\n",(0,i.jsxs)(n.li,{children:["It applies the PR label ",(0,i.jsx)(n.code,{children:"successful-e2e-quick-test"})," and leaves an informative PR comment when the ",(0,i.jsx)(n.code,{children:"e2e-openstack-quick"})," job succeeded"]}),"\n",(0,i.jsxs)(n.li,{children:["It applies the PR label ",(0,i.jsx)(n.code,{children:"failed-e2e-quick-test"})," and leaves an informative PR comment when the ",(0,i.jsx)(n.code,{children:"e2e-openstack-quick"})," job failed"]}),"\n",(0,i.jsxs)(n.li,{children:["It applies the PR label ",(0,i.jsx)(n.code,{children:"cancelled-e2e-quick-test"})," and leaves an informative PR comment when the ",(0,i.jsx)(n.code,{children:"e2e-openstack-quick"})," job is canceled"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"unlabel-on-update-e2e-quick-test"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["It is triggered by the PR update only when PR contains the ",(0,i.jsx)(n.code,{children:"successful-e2e-quick-test"})," label"]}),"\n",(0,i.jsx)(n.li,{children:"It ensures that any PR update invalidates a previous successful e2e test"}),"\n",(0,i.jsxs)(n.li,{children:["It removes ",(0,i.jsx)(n.code,{children:"successful-e2e-quick-test"})," label from the PR"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jobs",children:"Jobs"}),"\n",(0,i.jsx)(n.p,{children:"This section describes Zuul jobs defined within the cluster-stacks project and linked in the above pipelines."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"e2e-openstack-conformance"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"It runs a sonobuoy conformance test against Kubernetes cluster spawned by a specific cluster-stack"}),"\n",(0,i.jsxs)(n.li,{children:["This job is a child job of ",(0,i.jsx)(n.code,{children:"openstack-access-base"})," that ensures OpenStack credentials\navailability in Zuul worker node. Parent job also defines a Zuul semaphore ",(0,i.jsx)(n.code,{children:"semaphore-openstack-access"}),",\nthat ensures that a maximum of three ",(0,i.jsx)(n.code,{children:"openstack-access-base"})," jobs (or their children) can run at a time"]}),"\n",(0,i.jsxs)(n.li,{children:["See a high level ",(0,i.jsx)(n.code,{children:"e2e-openstack-conformance"})," job steps:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Pre-run playbook ",(0,i.jsx)(n.code,{children:"dependencies.yaml"})," installs project prerequisites, e.g. clusterctl, KinD, csctl, etc."]}),"\n",(0,i.jsxs)(n.li,{children:["Main playbook ",(0,i.jsx)(n.code,{children:"e2e.yaml"})," spawns a k8s workload cluster using a specific cluster-stack in OpenStack, runs sonobuoy conformance test, SCS compliance test, and cleans created k8s workload cluster"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"e2e-openstack-quick"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"It runs a sonobuoy quick test against Kubernetes cluster spawned by a specific cluster-stack"}),"\n",(0,i.jsxs)(n.li,{children:["This job is a child job of ",(0,i.jsx)(n.code,{children:"openstack-access-base"})," that ensures OpenStack credentials\navailability in Zuul worker node. Parent job also defines a Zuul semaphore ",(0,i.jsx)(n.code,{children:"semaphore-openstack-access"}),",\nthat ensures that a maximum of three ",(0,i.jsx)(n.code,{children:"openstack-access-base"})," jobs (or their children) can run at a time"]}),"\n",(0,i.jsxs)(n.li,{children:["See a high level ",(0,i.jsx)(n.code,{children:"e2e-openstack-quick"})," job steps:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Pre-run playbook ",(0,i.jsx)(n.code,{children:"dependencies.yaml"})," installs project prerequisites, e.g. clusterctl, KinD, csctl, etc."]}),"\n",(0,i.jsxs)(n.li,{children:["Main playbook ",(0,i.jsx)(n.code,{children:"e2e.yaml"})," spawns a k8s workload cluster using a specific cluster-stack in OpenStack, runs sonobuoy quick test, SCS compliance test, and cleans created k8s workload cluster"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"secrets",children:"Secrets"}),"\n",(0,i.jsxs)(n.p,{children:["The parent job ",(0,i.jsx)(n.code,{children:"openstack-access-base"}),", from which e2e jobs inherit, defines the secret variable ",(0,i.jsx)(n.code,{children:"openstack-application-credential"}),".\nThis secret is stored directly in the ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-config/blob/main/zuul.d/secrets.yaml",children:"SCS/zuul-config repository"})," in an encrypted form. It contains OpenStack application credentials to access the OpenStack project dedicated to CI testing."]}),"\n",(0,i.jsxs)(n.p,{children:["This secret is encrypted by the SCS/zuul-config repository RSA key that has been generated by SCS Zuul instance.\nSo only SCS Zuul instance is able to decrypt it (read the ",(0,i.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/project-config.html#encryption",children:"docs"}),")."]}),"\n",(0,i.jsx)(n.p,{children:"If you want to re-generate the mentioned secret or add another one using SCS/zuul-config repository RSA key, follow the below instructions:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Install zuul-client"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"pip install zuul-client\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:'Encrypt "super-secret" string by the SCS/zuul-config repository public key from SCS Zuul'}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'echo -n "super-secret" | \\\n zuul-client --zuul-url https://zuul.scs.community encrypt \\\n --tenant SCS \\\n --project github.com/SovereignCloudStack/zuul-config\n'})}),"\n",(0,i.jsx)(n.h3,{id:"job-customization",children:"Job customization"}),"\n",(0,i.jsxs)(n.p,{children:["In a pull request (PR), you may want to run the end-to-end (e2e) test against the specific cluster-stack you are changing or adding, without modifying the ",(0,i.jsx)(n.code,{children:"cluster_stack"})," variable in the ",(0,i.jsx)(n.code,{children:"e2e.yaml"})," file in the repository."]}),"\n",(0,i.jsx)(n.p,{children:"To achieve this, include the following text in the body of the PR:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-text",children:' ```ZUUL_CONFIG\n cluster_stack = "openstack-alpha-1-29"\n'})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"\n> [!NOTE]\n> Please note that only cluster-stacks for OpenStack are currently supported.\n\n### FAQ\n\n#### How do developers/reviewers should proceed if they want to CI test this project?\n\nA developer initiates a PR as usual. If a reviewer deems that the PR requires e2e testing, they can apply a specific label to the PR. Currently, the following labels could be applied:\n\n- `e2e-test` (for comprehensive end-to-end (e2e) testing, including Kubernetes (k8s) workload cluster creation, execution of Sonobuoy conformance and SCS compliance tests, and cluster deletion.)\n- `e2e-quick-test` (for comprehensive end-to-end (e2e) testing, including Kubernetes (k8s) workload cluster creation, execution of Sonobuoy quick and SCS compliance tests, and cluster deletion.)\n\nAfter the e2e test has completed, the reviewer can examine the test results and respond accordingly, such as approving the PR if everything appears to be in order or requesting changes. Sonobuoy test results, along with a link to the e2e logs, are conveyed back to the PR via a comment. Additionally, the PR is labeled appropriately based on the overall e2e test results, using labels like\n`successful-e2e-test`, `successful-e2e-quick-test`, `failed-e2e-test`, or `failed-e2e-quick-test`.\n\n#### Why do we use PR `label` as an e2e pipeline trigger instead of e.g. PR `comment`?\n\nWe consider PR labels to be a more secure pipeline trigger compared to, for example, PR comments.\nPR labels can only be applied by developers with [triage](https://docs.github.com/en/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization#permissions-for-each-role) repository access or higher.\nIn contrast, PR comments can be added by anyone with a GitHub account.\n\nMembers of the SCS GitHub organization are automatically granted 'write' access to SCS repositories. Consequently, the PR label mechanism ensures that only SCS organization members can trigger e2e pipelines.\n\n#### How do we ensure that any PR update invalidates a previous successful e2e test?\n\nIn fact, two mechanisms ensure the invalidation of a previously successful test when a PR is updated.\n\nFirstly, the pipelines `unlabel-on-update-<e2e-test-name>` remove the `successful-<e2e-test-name>` label\nfrom the PR when it's updated after a successful e2e test has finished. If an e2e test is in progress and the PR is updated, the currently running e2e test is canceled, the `successful-<e2e-test-name>` label is removed (if it exists), and the `cancelled-<e2e-test-name>` label is applied along with an informative PR comment to inform the reviewer about the situation.\n"})})]})}function d(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var t=s(96540);const i={},c=t.createContext(i);function o(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/779440a1.5b3250e4.js b/assets/js/779440a1.5b3250e4.js new file mode 100644 index 0000000000..dee6a147fd --- /dev/null +++ b/assets/js/779440a1.5b3250e4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[22672],{8618:(s,t,e)=>{e.r(t),e.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"iaas/scs-0112","title":"scs-0112: SONiC Support in SCS","description":"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.","source":"@site/standards/iaas/scs-0112.md","sourceDirName":"iaas","slug":"/iaas/scs-0112","permalink":"/standards/iaas/scs-0112","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0111-v1-volume-type-decisions"},"next":{"title":"V1","permalink":"/standards/scs-0112-v1-sonic"}}');var r=e(74848),i=e(28453);const c={},a="scs-0112: SONiC Support in SCS",d={},o=[];function l(s){const t={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...s.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0112-sonic-support-in-scs",children:"scs-0112: SONiC Support in SCS"})}),"\n",(0,r.jsx)(t.p,{children:"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0112-v1-sonic",children:"scs-0112-v1"})}),(0,r.jsx)(t.td,{children:"Decision Record"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(s={}){const{wrapper:t}={...(0,i.R)(),...s.components};return t?(0,r.jsx)(t,{...s,children:(0,r.jsx)(l,{...s})}):l(s)}},28453:(s,t,e)=>{e.d(t,{R:()=>c,x:()=>a});var n=e(96540);const r={},i=n.createContext(r);function c(s){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof s?s(t):{...t,...s}}),[t,s])}function a(s){let t;return t=s.disableParentContext?"function"==typeof s.components?s.components(r):s.components||r:c(s.components),n.createElement(i.Provider,{value:t},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/7850b12c.6900b675.js b/assets/js/7850b12c.6900b675.js new file mode 100644 index 0000000000..4ba48e8724 --- /dev/null +++ b/assets/js/7850b12c.6900b675.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[30675],{64680:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>l,metadata:()=>i,toc:()=>a});const i=JSON.parse('{"id":"container/components/container-registry/docs/persistence","title":"Persistence","description":"This page briefly describes and provides pointers on how Harbor persists data when it is","source":"@site/docs/03-container/components/container-registry/docs/persistence.md","sourceDirName":"03-container/components/container-registry/docs","slug":"/container/components/container-registry/docs/persistence","permalink":"/docs/container/components/container-registry/docs/persistence","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/persistence.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Migration","permalink":"/docs/container/components/container-registry/docs/migration"},"next":{"title":"HA deployment","permalink":"/docs/container/components/container-registry/docs/ha-deployment"}}');var r=n(74848),t=n(28453);const l={},c="Persistence",o={},a=[{value:"Data Access Layer",id:"data-access-layer",level:2},{value:"Redis",id:"redis",level:3},{value:"Database (PostgreSQL)",id:"database-postgresql",level:3},{value:"OCI Distribution Registry",id:"oci-distribution-registry",level:3},{value:"Fundamental Services",id:"fundamental-services",level:2},{value:"Proxy, Core, Web Portal",id:"proxy-core-web-portal",level:3},{value:"Trivy",id:"trivy",level:3},{value:"JobService",id:"jobservice",level:3}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"persistence",children:"Persistence"})}),"\n",(0,r.jsxs)(s.p,{children:["This page briefly describes and provides pointers on how Harbor persists data when it is\ndeployed in a Kubernetes cluster environment. It points out the default persistence settings\nof ",(0,r.jsx)(s.a,{href:"https://github.com/goharbor/harbor-helm",children:"Harbor helm chart"})," as well as available options."]}),"\n",(0,r.jsxs)(s.p,{children:["Harbor, by design, consists of multiple (micro)services that could store their data\nvariously, based on the Harbor configuration, see the ",(0,r.jsx)(s.a,{href:"https://github.com/goharbor/harbor/wiki/Architecture-Overview-of-Harbor",children:"Architecture Overview of Harbor"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"data-access-layer",children:"Data Access Layer"}),"\n",(0,r.jsx)(s.h3,{id:"redis",children:"Redis"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Usage","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Key value storage used as a login session cache, a registry manifest cache, and a queue for the jobservice (e.g. see ",(0,r.jsx)(s.a,{href:"#trivy",children:"Trivy"}),")"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Default settings","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:['Deployed as an "internal" single node database into the same Kubernetes cluster as Harbor (helm value: ',(0,r.jsx)(s.code,{children:"redis.type.internal"}),")"]}),"\n",(0,r.jsx)(s.li,{children:"Deployed as a StatefulSet with 1 replica"}),"\n",(0,r.jsxs)(s.li,{children:["PV persistence is enabled by default (helm value: ",(0,r.jsx)(s.code,{children:"persistence.enabled.true"}),"), Redis POD mounts PV into the ",(0,r.jsx)(s.code,{children:"/var/lib/redis"})," directory"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Additional settings","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:['Harbor could be pointed to the "external" Redis (or Redis Sentinel) database (helm value: ',(0,r.jsx)(s.code,{children:"redis.type.external"}),")"]}),"\n",(0,r.jsxs)(s.li,{children:['"Internal" Redis could be deployed without any persistence, i.e. it could use ',(0,r.jsx)(s.code,{children:"emptyDir"})," (helm value: ",(0,r.jsx)(s.code,{children:"persistence.enabled.false"}),")"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Notes","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"https://github.com/goharbor/harbor/issues/13544",children:"What is the role of Redis in Harbor?"})}),"\n",(0,r.jsxs)(s.li,{children:["Redis data does not need to be backed up, see the ",(0,r.jsx)(s.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#limitations",children:"Limitations docs"})," for more details of the potential impact"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"database-postgresql",children:"Database (PostgreSQL)"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Usage","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Stores the related metadata of Harbor models, like projects, users, roles, replication policies, tag retention policies, scanners, charts, and images"}),"\n",(0,r.jsxs)(s.li,{children:["Could store ",(0,r.jsx)(s.a,{href:"#jobservice",children:"JobService"})," logs (helm value: ",(0,r.jsx)(s.code,{children:"jobservice.jobLoggers.[database]"}),")"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Default settings","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:['Deployed as an "internal" single node database into the same Kubernetes cluster as Harbor (helm value: ',(0,r.jsx)(s.code,{children:"database.type.internal"}),")"]}),"\n",(0,r.jsx)(s.li,{children:"Deployed as a StatefulSet with 1 replica"}),"\n",(0,r.jsxs)(s.li,{children:["PV persistence is enabled by default (helm value: ",(0,r.jsx)(s.code,{children:"persistence.enabled.true"}),"), PostgreSQL POD mounts PV into the ",(0,r.jsx)(s.code,{children:"/var/lib/postgresql/data"})," directory"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Additional settings","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:['Harbor could be pointed to the "external" database (PostgreSQL) (helm value: ',(0,r.jsx)(s.code,{children:"database.type.external"}),")"]}),"\n",(0,r.jsxs)(s.li,{children:['"Internal" database could be deployed without any persistence, i.e. it could use ',(0,r.jsx)(s.code,{children:"emptyDir"})," (helm value: ",(0,r.jsx)(s.code,{children:"persistence.enabled.false"}),")"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"oci-distribution-registry",children:"OCI Distribution Registry"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Usage","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Backend storage of container images and charts"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Default settings","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Images and charts are stored in ",(0,r.jsx)(s.code,{children:"registry"})," POD filesystem directory ",(0,r.jsx)(s.code,{children:"/storage"})," (helm value: ",(0,r.jsx)(s.code,{children:"persistence.imageChartStorage.type.filesystem"}),"), this directory is mounted to the PV"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Additional settings","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:['Various object storage backends: "azure", "gcs", "s3", "swift", "oss" (helm value: ',(0,r.jsx)(s.code,{children:"persistence.imageChartStorage.type.<backend>"}),")"]}),"\n",(0,r.jsxs)(s.li,{children:["Backend storage could be",(0,r.jsx)(s.code,{children:"emptyDir"})," (helm value: ",(0,r.jsx)(s.code,{children:"persistence.enabled.false"}),")"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"fundamental-services",children:"Fundamental Services"}),"\n",(0,r.jsx)(s.h3,{id:"proxy-core-web-portal",children:"Proxy, Core, Web Portal"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"These Harbor services are stateless"}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"trivy",children:"Trivy"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Usage","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"A 3rd party vulnerability scanner provided by Aqua Security"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Default settings","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Deployed as a StatefulSet with 1 replica"}),"\n",(0,r.jsxs)(s.li,{children:["PV persistence is enabled by default (helm value: ",(0,r.jsx)(s.code,{children:"persistence.enabled.true"}),"), Trivy POD mounts PV into the ",(0,r.jsx)(s.code,{children:"/home/scanner/.cache"})," directory"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Additional settings","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Trivy could be deployed without any persistence, i.e. it could use ",(0,r.jsx)(s.code,{children:"emptyDir"})," (helm value: ",(0,r.jsx)(s.code,{children:"persistence.enabled.false"}),")"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Notes","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"https://github.com/aquasecurity/harbor-scanner-trivy/issues/135#issuecomment-671259649",children:"What kind of data are stored in /home/scanner/.cache?"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"jobservice",children:"JobService"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Usage","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"General job execution queue service to let other components/services submit requests of running asynchronous tasks concurrently"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Default settings","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Deployed as a Deployment with 1 replica"}),"\n",(0,r.jsxs)(s.li,{children:["Store logs in the POD filesystem directory ",(0,r.jsx)(s.code,{children:"/var/log/jobs"})," (helm value: ",(0,r.jsx)(s.code,{children:"jobservice.jobLoggers.[file]"}),"), this directory is mounted to the PV"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Additional settings","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["JobService could be deployed without any persistence, i.e. it could use ",(0,r.jsx)(s.code,{children:"emptyDir"})," (helm value: ",(0,r.jsx)(s.code,{children:"persistence.enabled.false"}),")"]}),"\n",(0,r.jsxs)(s.li,{children:["Logs could be stored in ",(0,r.jsx)(s.a,{href:"#database-postgresql",children:"Harbor database"})," (helm value: ",(0,r.jsx)(s.code,{children:"jobservice.jobLoggers.[database]"}),") or just printed to the STDOUT (helm value: ",(0,r.jsx)(s.code,{children:"jobservice.jobLoggers.[stdout]"}),")"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>l,x:()=>c});var i=n(96540);const r={},t=i.createContext(r);function l(e){const s=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),i.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/78bb765a.7bfa1d7f.js b/assets/js/78bb765a.7bfa1d7f.js new file mode 100644 index 0000000000..a0e0f6ac5f --- /dev/null +++ b/assets/js/78bb765a.7bfa1d7f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[89295],{62285:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>n,toc:()=>p});const n=JSON.parse('{"id":"operating-scs/components/status-page-api/docs/requirements","title":"Requirements","description":"The status page API server requires a PostgreSQL database.","source":"@site/docs/04-operating-scs/components/status-page-api/docs/requirements.md","sourceDirName":"04-operating-scs/components/status-page-api/docs","slug":"/operating-scs/components/status-page-api/docs/requirements","permalink":"/docs/operating-scs/components/status-page-api/docs/requirements","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-api/docs/requirements.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/operating-scs/components/status-page-api/docs/overview"},"next":{"title":"Quickstart","permalink":"/docs/operating-scs/components/status-page-api/docs/quickstart"}}');var r=t(74848),o=t(28453);const a={},i="Requirements",c={},p=[];function u(e){const s={a:"a",h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"requirements",children:"Requirements"})}),"\n",(0,r.jsxs)(s.p,{children:["The status page API server requires a ",(0,r.jsx)(s.a,{href:"https://www.postgresql.org/",children:"PostgreSQL"})," database."]}),"\n",(0,r.jsxs)(s.p,{children:["When compiling the API server itself, a ",(0,r.jsx)(s.a,{href:"https://go.dev/doc/install",children:"Go installation"})," is required."]})]})}function d(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>a,x:()=>i});var n=t(96540);const r={},o=n.createContext(r);function a(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/79a28527.29cdea05.js b/assets/js/79a28527.29cdea05.js new file mode 100644 index 0000000000..f1a130f18f --- /dev/null +++ b/assets/js/79a28527.29cdea05.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[61902],{63441:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>s,toc:()=>p});const s=JSON.parse('{"id":"application-examples/opendesk-on-scs/user-import","title":"User import","description":"Once you have a complete deployment, you can add additional accounts via the administration interface.","source":"@site/user-docs/application-examples/opendesk-on-scs/user-import.md","sourceDirName":"application-examples/opendesk-on-scs","slug":"/application-examples/opendesk-on-scs/user-import","permalink":"/user-docs/application-examples/opendesk-on-scs/user-import","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"userDocs","previous":{"title":"Configuration","permalink":"/user-docs/application-examples/opendesk-on-scs/configuration"},"next":{"title":"Contribute","permalink":"/user-docs/application-examples/opendesk-on-scs/contribute"}}');var o=n(74848),r=n(28453);const a={},i="User import",c={},p=[];function d(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"user-import",children:"User import"})}),"\n",(0,o.jsxs)(t.p,{children:["Once you have a complete deployment, you can add additional accounts via the administration interface.\nFor this, you can use the administrative account ",(0,o.jsx)(t.code,{children:"default.admin"}),", whose credentials are provided after the deployment (see ",(0,o.jsx)(t.a,{href:"/user-docs/application-examples/opendesk-on-scs/getting_started",children:"First login"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["Alternatively, users can be created automatically from a source file.\nThe [openDesk User Importer](",(0,o.jsx)(t.a,{href:"https://gitlab.opencode.de/bmi/opendesk/components/platform-development/images/user-import/-/tree/main",children:"openDesk User Importer"}),") supports both random test users and predefined users from ods files.\nTo keep it simple you could also use the credentials from ",(0,o.jsx)(t.code,{children:"default.admin"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const o={},r=s.createContext(o);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7aa8d561.00a49cfb.js b/assets/js/7aa8d561.00a49cfb.js new file mode 100644 index 0000000000..c98236d25e --- /dev/null +++ b/assets/js/7aa8d561.00a49cfb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[11362],{23920:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"scs-0115-v1-default-rules-for-security-groups","title":"Default Rules for Security Groups","description":"Introduction","source":"@site/standards/scs-0115-v1-default-rules-for-security-groups.md","sourceDirName":".","slug":"/scs-0115-v1-default-rules-for-security-groups","permalink":"/standards/scs-0115-v1-default-rules-for-security-groups","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Default Rules for Security Groups","type":"Standard","status":"Stable","stabilized_at":"2024-11-13T00:00:00.000Z","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0115: Default Rules for Security Groups","permalink":"/standards/iaas/scs-0115"},"next":{"title":"scs-0116: SCS Key Manager Standard","permalink":"/standards/iaas/scs-0116"}}');var s=r(74848),a=r(28453);const o={title:"Default Rules for Security Groups",type:"Standard",status:"Stable",stabilized_at:new Date("2024-11-13T00:00:00.000Z"),track:"IaaS"},i=void 0,u={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Default Security Groups, Custom Security Groups and default Security Group Rules",id:"default-security-groups-custom-security-groups-and-default-security-group-rules",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Further Annotations",id:"further-annotations",level:3},{value:"Standard",id:"standard",level:2},{value:"Example",id:"example",level:3},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(t.p,{children:"Security Groups in IaaS (OpenStack) are part of the network security mechanisms provided for the users.\nThey resemble sets of virtual firewall rules allowing specific network traffic at a port of a VM that connects it to a network.\nThey are project-bound, which means that all Security Groups that are newly created are only available to the project in which they were created.\nThis is also the case for the default Security Group that is created for each project as soon as the project itself is created."}),"\n",(0,s.jsx)(t.h2,{id:"terminology",children:"Terminology"}),"\n",(0,s.jsx)(t.p,{children:"Security Group (abbr. SG)\nSet of ip table rules, used for tenant network security."}),"\n",(0,s.jsx)(t.p,{children:"Security Group Rule (abbr. SG Rule)\nA single ip table rule, that is part of a Security Group."}),"\n",(0,s.jsx)(t.p,{children:"Administrator (abbr. Admin)\nOperator = User of an OpenStack cloud with the admin role."}),"\n",(0,s.jsx)(t.h3,{id:"default-security-groups-custom-security-groups-and-default-security-group-rules",children:"Default Security Groups, Custom Security Groups and default Security Group Rules"}),"\n",(0,s.jsx)(t.p,{children:"To properly understand the concepts in this standard and avoid ambiguity, it is very important to distinguish between the following similar-sounding but different resources in the OpenStack Networking API:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"default Security Group"}),"\n",(0,s.jsx)(t.li,{children:"custom Security Group"}),"\n",(0,s.jsx)(t.li,{children:"default Security Group Rules"}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["A ",(0,s.jsx)(t.strong,{children:"default Security Group"}),' is a predefined Security Group which is automatically created once a project is created and is specific to that project.\nThis Security Group is called "default" and there exists only one per project.\nIt will automatically be assigned to VMs that have no other Security Group explicitly assigned to it, when a VM is created.']}),"\n",(0,s.jsxs)(t.p,{children:["A ",(0,s.jsx)(t.strong,{children:"custom Security Group"})," is any additional Security Group created within a project separate from the ",(0,s.jsx)(t.em,{children:"default Security Group"})," of the project."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.strong,{children:"default Security Group Rules"})," may target the ",(0,s.jsx)(t.em,{children:"default Security Groups"})," or the ",(0,s.jsx)(t.em,{children:"custom Security Groups"})," or both.\nThey resemble a rule template and each Security Group will be initially created with rules according to this template."]}),"\n",(0,s.jsx)(t.p,{children:"Although the rules of a Security Group may be adjusted freely after its creation, these default rule presets applied on initialization are predefined.\nIn recent OpenStack releases, both presets can be adjusted independently by administrators of the infrastructure."}),"\n",(0,s.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsxs)(t.p,{children:["The rules of a Security Group can be edited by default by any user with the member role within a project.\nBut when a Security Group is created it automatically incorporates a few Security Group rules that are configured as default rules.\nSince the 2023.2 release, the default set of Security Group rules can be adjusted.\nThis functionality is only available to administrators",(0,s.jsx)(t.sup,{children:(0,s.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),(0,s.jsx)(t.sup,{children:(0,s.jsx)(t.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),".\nIn combination with the OpenStack behavior that when a VM is created with no Security Group specified, the default Security Group of the project is automatically applied to the ports of the VM,\na user cannot be sure which firewall rules are applied to such a VM."]}),"\n",(0,s.jsx)(t.p,{children:"Therefore, this standard proposes default Security Group rules that MUST be set by administrators to avoid divergence in default network security between different IaaS environments."}),"\n",(0,s.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsx)(t.p,{children:"Up to the 2023.1 release (Antelope) the default Security Group rules are defined in the OpenStack code.\nWe should not require changing this behavior through code changes in deployments."}),"\n",(0,s.jsx)(t.p,{children:"Beginning with the 2023.2 release (Bobcat) the default Security Group rules can now be edited by administrators through an API.\nAll rules that should be present as default in Security Groups have to be configured by admins through this API."}),"\n",(0,s.jsx)(t.p,{children:"There are two ways to approach a standard for the default rules of Security Groups."}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"There could be a set of rules standardized that has to be configured by admins."})}),"\n",(0,s.jsx)(t.p,{children:"OpenStack's default rules for Security Groups already provide a good baseline for port security, because they allow all egress traffic and for the default Security Group only ingress traffic from the same group."}),"\n",(0,s.jsx)(t.p,{children:"Allowing more rules would not benefit the security level, while reducing or limiting the existing rules would barely improve it.\nNevertheless, a standard could hold up the current security level against possible future release with more open default rules.\nChanging the default rules will not change the rules of any existing Security Groups."}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"With the already strict OpenStack default rules users are required in most use cases to create and manage their own Security Groups."})}),"\n",(0,s.jsxs)(t.p,{children:["This has the benefit that users need to explicitly think about the port security of their VMs and may be less likely to apply Security Groups which rules open up more ports than needed.\nThere is also a guide from the SCS project on how to set up a Security Group that also focuses on having a good port security",(0,s.jsx)(t.sup,{children:(0,s.jsx)(t.a,{href:"#user-content-fn-3",id:"user-content-fnref-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),"."]}),"\n",(0,s.jsx)(t.p,{children:"With the default OpenStack behavior of having already strict rules, which in most cases require users to manage their own Security Groups, this standard should mandate a middle way:\nIt should allow adjusting the default rules, but only to a stricter version."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Allowing all outgoing traffic in the default rules in combination with blocking all incoming traffic would be strict enough from a security point of view.\nAnd it would make it necessary for users to check and change the rules of their Security Group to a meaningful set."}),"\n",(0,s.jsx)(t.h3,{id:"further-annotations",children:"Further Annotations"}),"\n",(0,s.jsx)(t.p,{children:"This standard should only be applied onto versions of OpenStack that implement the new endpoint for the default Security Group rules, which would only include 2023.2 or higher releases."}),"\n",(0,s.jsx)(t.p,{children:"It is possible to have different default Security Group rules for the default Security Group and custom Security Groups.\nAnd it is arguable to have a more strict standard for default rules for the default Security Group than for the custom Security Groups.\nBecause the latter ones are not automatically applied to a VM but are always edited by the users to apply to their requirements."}),"\n",(0,s.jsx)(t.p,{children:"The allowlisting concept of Security Group rules makes it hard to allow traffic with an exception to certain ports.\nIt would be possible to just define many rules to achieve what a blocklist would achieve.\nBut having many rules may confuse users, and they may not disable unnecessary default rules in their Security Groups."}),"\n",(0,s.jsx)(t.h2,{id:"standard",children:"Standard"}),"\n",(0,s.jsx)(t.p,{children:'The default Security Group rules for the default Security Groups SHOULD allow incoming traffic from the same Security Group.\nThe default Security Group rules for ALL Security Groups MUST NOT allow any other incoming traffic. Neither IPv4 nor IPv6.\nThis can be achieved through having ingress rules in the default Security Group rules that allow ingress traffic from the Remote Security Group "PARENT" but are only used in the default Security Group.'}),"\n",(0,s.jsx)(t.p,{children:"The default Security Group rules for ALL Security Groups SHOULD allow egress Traffic for both IPv4 and IPv6."}),"\n",(0,s.jsx)(t.h3,{id:"example",children:"Example"}),"\n",(0,s.jsx)(t.p,{children:"In the following table, there is only ingress traffic between the same default Security Groups allowed plus all egress traffic:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"$ openstack default security group rule list\n+--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+\n| ID | IP Protocol | Ethertype | IP Range | Port Range | Direction | Remote Security Group | Remote Address Group | Used in default Security Group | Used in custom Security Group |\n+--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+\n| 47b929fd-9b39-4f22-abc5- | None | IPv6 | ::/0 | | egress | None | None | True | True |\n| 7d4f64d10909 | | | | | | | | | |\n| 92a79600-5358-4fef-a390- | None | IPv4 | 0.0.0.0/0 | | egress | None | None | True | True |\n| 822665f46070 | | | | | | | | | |\n| 93e35d0c-2482-4ec1-9fbd- | None | IPv4 | 0.0.0.0/0 | | ingress | PARENT | None | True | False |\n| fd8c9a21a04e | | | | | | | | | |\n| ed5cd662-add2-4e42-b0a7- | None | IPv6 | ::/0 | | ingress | PARENT | None | True | False |\n| 3b585d348820 | | | | | | | | | |\n+--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+\n"})}),"\n",(0,s.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsxs)(t.p,{children:["The spec for introducing configurability for the default Security Groups Rules can be found ",(0,s.jsx)(t.a,{href:"https://specs.openstack.org/openstack/neutron-specs/specs/2023.2/configurable-default-sg-rules.html",children:"here"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["More about Security Groups as a resource in OpenStack can be found ",(0,s.jsx)(t.a,{href:"https://docs.openstack.org/nova/latest/user/security-groups.html",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The conformance tests should check for the absence of any ingress traffic rules except traffic from the same Security Group in the ",(0,s.jsx)(t.code,{children:"openstack default security group rule list"}),".\nAs having egress rules is allowed by this standard, but not forced and can be set in various ways, the tests should check for presence of any egress rules."]}),"\n","\n",(0,s.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,s.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://bugs.launchpad.net/neutron/+bug/1983053",children:"Tracking of development for editable default SG rules"})," ",(0,s.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{id:"user-content-fn-2",children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://docs.openstack.org/releasenotes/neutron/2023.2.html",children:"Release Notes of Neutron 2023.2"})," ",(0,s.jsx)(t.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{id:"user-content-fn-3",children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://docs.scs.community/docs/iaas/guides/user-guide/security-groups/",children:"Guide for Security Groups"})," ",(0,s.jsx)(t.a,{href:"#user-content-fnref-3","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>i});var n=r(96540);const s={},a=n.createContext(s);function o(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7ac7e960.7c05b3ea.js b/assets/js/7ac7e960.7c05b3ea.js new file mode 100644 index 0000000000..dad5269859 --- /dev/null +++ b/assets/js/7ac7e960.7c05b3ea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[61329],{22201:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"scs-0120-v1-capi-images","title":"Cluster-API images","description":"Abstract","source":"@site/standards/scs-0120-v1-capi-images.md","sourceDirName":".","slug":"/scs-0120-v1-capi-images","permalink":"/standards/scs-0120-v1-capi-images","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Cluster-API images","type":"Decision Record","status":"Draft","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0120: Cluster-API images","permalink":"/standards/iaas/scs-0120"},"next":{"title":"scs-0121: SCS Availability Zones","permalink":"/standards/iaas/scs-0121"}}');var i=n(74848),a=n(28453);const r={title:"Cluster-API images",type:"Decision Record",status:"Draft",track:"IaaS"},o=void 0,d={},l=[{value:"Abstract",id:"abstract",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Design considerations",id:"design-considerations",level:2},{value:"Decision",id:"decision",level:2},{value:"Consequences",id:"consequences",level:2},{value:"Open questions",id:"open-questions",level:2}];function c(e){const s={a:"a",em:"em",h2:"h2",li:"li",ol:"ol",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h2,{id:"abstract",children:"Abstract"}),"\n",(0,i.jsx)(s.p,{children:"The SCS reference implementation for the Kubernetes-as-a-service layer is built on top of Cluster API (CAPI), and therefore it depends on the corresponding VM images, which may or may not be present on the underlying infrastructure-as-a-service layer. Current tooling will make sure to upload the required image in case it's not present or outdated. However, these ad-hoc uploads will not be shared across environments, which may lead to waste of bandwidth (for transferring the image), storage (if images are not stored in a deduplicated manner), and not least time (because the upload does take multiple minutes). Needless to say, it may also lead to excessive greenhouse-gas emissions."}),"\n",(0,i.jsx)(s.p,{children:"This decision record investigates the pros and cons of making the CAPI images mandatory. Ultimately, the decision is made to keep them recommended; we stress, however, that providers who offer the images by default should advertise this fact."}),"\n",(0,i.jsx)(s.h2,{id:"terminology",children:"Terminology"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.em,{children:"Kubernetes as a service (KaaS)"}),": A service that offers provisioning Kubernetes clusters."]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.em,{children:"Cluster API (CAPI)"}),': "Cluster API is a Kubernetes sub-project focused on providing declarative APIs and tooling to simplify provisioning, upgrading, and operating multiple Kubernetes clusters." (',(0,i.jsx)(s.a,{href:"https://cluster-api.sigs.k8s.io/",children:"source"}),") This API can thus be used to implement KaaS."]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.em,{children:"CAPI image"}),": Virtual machine image that contains a standardized Kubernetes setup to be used for CAPI. The SCS reference implementation for KaaS depends on these images."]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.em,{children:"CSP"}),": Cloud-service provider"]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"design-considerations",children:"Design considerations"}),"\n",(0,i.jsx)(s.p,{children:"We consider the following two options:"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsx)(s.li,{children:"Make CAPI image mandatory."}),"\n",(0,i.jsx)(s.li,{children:"Keep CAPI image recommended."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:"For reasons of symmetry, it suffices to consider the pros and cons of the first option."}),"\n",(0,i.jsx)(s.p,{children:"Pros:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Save time, money, physical resources and power for both CSP and customer."}),"\n",(0,i.jsx)(s.li,{children:"Regardless of CSP taste, this KaaS tech is part of SCS."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:"Neutral:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"The CAPI image can be provided in an automated fashion that means virtually no burden to the CSP."}),"\n",(0,i.jsx)(s.li,{children:"The KaaS implementation will work either way."}),"\n",(0,i.jsx)(s.li,{children:"Willing CSPs may offer the image by default and advertise as much."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:"Cons:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Additional regulations would be necessary to guarantee quality and timeliness of image."}),"\n",(0,i.jsx)(s.li,{children:"Some CSPs may be opposed to being forced to offer a certain service, which may hurt the overall acceptance\nof the SCS standardization efforts."}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(s.p,{children:"Ultimately, we value the freedom of the CSPs (and the acceptance of the standardization efforts) highest;\nwilling CSPs are welcome to opt in, i.e., to provide up-to-date images and advertise as much."}),"\n",(0,i.jsxs)(s.p,{children:["Therefore we decide to ",(0,i.jsx)(s.em,{children:"keep the CAPI images recommended"}),"."]}),"\n",(0,i.jsx)(s.h2,{id:"consequences",children:"Consequences"}),"\n",(0,i.jsx)(s.p,{children:"None, as the status quo is being kept."}),"\n",(0,i.jsx)(s.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,i.jsx)(s.p,{children:"Some interesting potential future work does remain, however: to find a way to certify that a willing provider\ndoes indeed provide up-to-date images. It would be possible with today's methods to certify that a CAPI\nimage is present (the image_spec yaml file would have to be split up to obtain a separate test case), but\nwe there is no way to make sure that the image is up to date."})]})}function h(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>o});var t=n(96540);const i={},a=t.createContext(i);function r(e){const s=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7ace79c4.ce536d3f.js b/assets/js/7ace79c4.ce536d3f.js new file mode 100644 index 0000000000..18ceb334bb --- /dev/null +++ b/assets/js/7ace79c4.ce536d3f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[974],{88642:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"iaas/scs-0111","title":"scs-0111: Decisions for the Volume Type Standard","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0111.md","sourceDirName":"iaas","slug":"/iaas/scs-0111","permalink":"/standards/iaas/scs-0111","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0110-v1-ssd-flavors"},"next":{"title":"V1","permalink":"/standards/scs-0111-v1-volume-type-decisions"}}');var r=t(74848),d=t(28453);const a={},c="scs-0111: Decisions for the Volume Type Standard",i={},o=[];function l(e){const s={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"scs-0111-decisions-for-the-volume-type-standard",children:"scs-0111: Decisions for the Volume Type Standard"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0111-v1-volume-type-decisions",children:"scs-0111-v1"})}),(0,r.jsx)(s.td,{children:"Decision Record"}),(0,r.jsx)(s.td,{children:"Draft"}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,d.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>a,x:()=>c});var n=t(96540);const r={},d=n.createContext(r);function a(e){const s=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(d.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7b449e09.2c162399.js b/assets/js/7b449e09.2c162399.js new file mode 100644 index 0000000000..53c28d74f3 --- /dev/null +++ b/assets/js/7b449e09.2c162399.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[45123],{95763:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"scs-0002-v2-standards-docs-org","title":"SCS Documentation structure","description":"SCS-0002 outlines the standardized structure and maintenance processes for easily accessible and\\ncomprehensible content of the SCS project.\\n","source":"@site/standards/scs-0002-v2-standards-docs-org.md","sourceDirName":".","slug":"/scs-0002-v2-standards-docs-org","permalink":"/standards/scs-0002-v2-standards-docs-org","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Documentation structure","type":"Procedural","version":"2023-08-03-001","authors":"Max Wolfs","status":"Draft","track":"Global","replaces":"scs-0002-v1-standards-docs-org.md","description":"SCS-0002 outlines the standardized structure and maintenance processes for easily accessible and\\ncomprehensible content of the SCS project.\\n"},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0002-v1-standards-docs-org"},"next":{"title":"scs-0003: Sovereign Cloud Standards YAML","permalink":"/standards/global/scs-0003"}}');var o=t(74848),s=t(28453);const a={title:"SCS Documentation structure",type:"Procedural",version:"2023-08-03-001",authors:"Max Wolfs",status:"Draft",track:"Global",replaces:"scs-0002-v1-standards-docs-org.md",description:"SCS-0002 outlines the standardized structure and maintenance processes for easily accessible and\ncomprehensible content of the SCS project.\n"},r=void 0,c={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Distributed Documentation",id:"distributed-documentation",level:2},{value:"Methodology and Taxonomy",id:"methodology-and-taxonomy",level:2},{value:"Structure Template",id:"structure-template",level:2},{value:"Single Component/Component",id:"single-componentcomponent",level:3},{value:"Overview",id:"overview",level:4},{value:"Requirements",id:"requirements",level:4},{value:"Quickstart",id:"quickstart",level:4},{value:"Configuration",id:"configuration",level:4},{value:"Contribute",id:"contribute",level:4},{value:"Technical Implementation",id:"technical-implementation",level:3},{value:"Documentation Framework",id:"documentation-framework",level:4},{value:"Special Implementation Details",id:"special-implementation-details",level:4},{value:"Writing Style and Format \u2013 Style Guide",id:"writing-style-and-format--style-guide",level:3},{value:"Formatting and Linting",id:"formatting-and-linting",level:4},{value:"Diagrams, Charts, and Images",id:"diagrams-charts-and-images",level:4},{value:"Linting",id:"linting",level:4},{value:"Pre Commit",id:"pre-commit",level:5},{value:"GitHub Workflows",id:"github-workflows",level:5},{value:"Open Questions",id:"open-questions",level:3},{value:"Reference",id:"reference",level:3}];function l(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,o.jsx)(n.p,{children:"The Sovereign Cloud Stack (SCS) is a complex ecosystem, comprised of numerous Components and packages designed to accommodate a wide array of use cases. Given the unique functionalities of these components, the creation of a unified and comprehensible documentation presents a significant challenge. This procedural standard aims to define the structure and maintenance process for our documentation, thereby offering seamless and efficient access to users."}),"\n",(0,o.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,o.jsx)(n.p,{children:"SCS promotes a collaborative environment by actively contributing to upstream projects. The involvement of individuals and companies within our community significantly enhances the SCS Bill of Materials (BOM), further amplifying its complexity. Consequently, our documentation must:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Offer an overview and visual representation of the architectural model"}),"\n",(0,o.jsx)(n.li,{children:"Foster coherence by maintaining a consistent theme throughout the documentation"}),"\n",(0,o.jsx)(n.li,{children:"Facilitate a transparent and inclusive community environment"}),"\n",(0,o.jsx)(n.li,{children:"Describe various deployment examples and use cases"}),"\n",(0,o.jsx)(n.li,{children:"Reflect the SCS structure in the documentation's navigation"}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"distributed-documentation",children:"Distributed Documentation"}),"\n",(0,o.jsxs)(n.p,{children:["In line with the ",(0,o.jsx)(n.a,{href:"https://docs.openstack.org/doc-contrib-guide/",children:"OpenStack documentation approach"}),", most SCS Components and components maintain independent documentation. To keep this documentation up-to-date and eliminate manual duplication, we utilize a custom workflow that synchronizes individual documents during the static documentation page's build process."]}),"\n",(0,o.jsx)(n.h2,{id:"methodology-and-taxonomy",children:"Methodology and Taxonomy"}),"\n",(0,o.jsxs)(n.p,{children:["Addressing the complexity of SCS requires an effective documentation structure. Accordingly, we have adopted the ",(0,o.jsx)(n.a,{href:"https://diataxis.fr/",children:"Diataxis taxonomy"}),", categorizing the documentation into four distinct sections: Tutorials, Guides, References, and Explanations."]}),"\n",(0,o.jsx)(n.h2,{id:"structure-template",children:"Structure Template"}),"\n",(0,o.jsx)(n.p,{children:"The technical documentation and navigation should parallel the logical structure of the SCS Architecture. By doing so, users can better comprehend the information hierarchy and effectively visualize the SCS. The proposed structure is as follows:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-tree",children:"\u251c\u2500\u2500 Introduction\n\u251c\u2500\u2500 Getting Started\n\u2502 \u251c\u2500\u2500 Overview\n\u2502 \u251c\u2500\u2500 Virtualization\n\u2502 \u2514\u2500\u2500 Containerization\n\u251c\u2500\u2500 IaaS Layer\n\u2502 \u251c\u2500\u2500 Overview\n\u2502 \u2502 \u251c\u2500\u2500 Architecture\n\u2502 \u2502 \u251c\u2500\u2500 Compute\n\u2502 \u2502 \u251c\u2500\u2500 Storage\n\u2502 \u2502 \u251c\u2500\u2500 Knowledge\n\u2502 \u2502 \u2514\u2500\u2500 Network\n\u2502 \u251c\u2500\u2500 Deployment Examples\n\u2502 \u2502 \u251c\u2500\u2500 Example 1\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Hardware\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 Software\n\u2502 \u2502 \u251c\u2500\u2500 ...\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Hardware\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 Software\n\u2502 \u2502 \u2514\u2500\u2500 Example x\n\u2502 \u2502 \u251c\u2500\u2500 Hardware\n\u2502 \u2502 \u2514\u2500\u2500 Software\n\u2502 \u251c\u2500\u2500 Guides\n\u2502 \u2502 \u251c\u2500\u2500 Guide 1\n\u2502 \u2502 \u251c ...\n\u2502 \u2502 \u2514\u2500\u2500 Guide x\n\u2502 \u2514\u2500\u2500 Components\n\u2502 \u251c\u2500\u2500 Component 1\n\u2502 \u251c ...\n\u2502 \u2514\u2500\u2500 Component x\n\u251c\u2500\u2500 Container Layer\n\u2502 \u251c\u2500\u2500 Overview\n\u2502 \u2502 \u251c\u2500\u2500 Architecture\n\u2502 \u2502 \u2514\u2500\u2500 ...\n\u2502 \u251c\u2500\u2500 Prerequisites\n\u2502 \u2502 \u251c\u2500\u2500 Hardware\n\u2502 \u2502 \u251c\u2500\u2500 Software\n\u2502 \u2502 \u2514\u2500\u2500 Knowledge\n\u2502 \u251c\u2500\u2500 Guides\n\u2502 \u2502 \u251c\u2500\u2500 Guide 1\n\u2502 \u2502 \u251c\u2500\u2500 ...\n\u2502 \u2502 \u2514\u2500\u2500 Guide x\n\u2502 \u2514\u2500\u2500 Components\n\u2502 \u251c\u2500\u2500 k8s-cluster-api-provider\n\u2502 \u251c ...\n\u2502 \u2514\u2500\u2500 Component x\n\u251c\u2500\u2500 Operating SCS\n\u2502 \u251c\u2500\u2500 Overview\n\u2502 \u251c\u2500\u2500 Guides\n\u2502 \u2502 \u251c\u2500\u2500 Guide 1\n\u2502 \u2502 \u251c\u2500\u2500 ...\n\u2502 \u2502 \u2514\u2500\u2500 Guide x\n\u2502 \u251c\u2500\u2500 Monitoring\n\u2502 \u251c\u2500\u2500 Incident Management\n\u2502 \u251c\u2500\u2500 Audits\n\u2502 \u251c\u2500\u2500 Lifecycle Management: Patches/Updates & Upgrades\n\u2502 \u2514\u2500\u2500 Logging\n\u251c\u2500\u2500 Identity and Access Management (IAM)\n\u251c\u2500\u2500 Releases\n\u251c\u2500\u2500 Standards\n\u251c\u2500\u2500 FAQ\n\u2514\u2500\u2500 Glossary\n"})}),"\n",(0,o.jsx)(n.h3,{id:"single-componentcomponent",children:"Single Component/Component"}),"\n",(0,o.jsx)(n.p,{children:"The technical documentation and navigation should parallel the logical structure of the SCS Architecture. By doing so, users can better comprehend the information hierarchy and effectively visualize the SCS. The proposed structure is as follows:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-tree",children:"\u2502 \u251c\u2500\u2500 Component\n\u2502 \u2502 \u251c\u2500\u2500 overview.md\n\u2502 \u2502 \u2514\u2500\u2500 requirements.md\n\u2502 \u2502 \u251c\u2500\u2500 quickstart.md\n\u2502 \u2502 \u251c\u2500\u2500 configuration.md\n\u2502 \u2502 \u251c\u2500\u2500 contribute.md\n"})}),"\n",(0,o.jsx)(n.p,{children:"Each document serves a specific purpose:"}),"\n",(0,o.jsx)(n.h4,{id:"overview",children:"Overview"}),"\n",(0,o.jsx)(n.p,{children:'This document introduces the Component/component by addressing the basic "Why," "How," and "What" questions, and articulating the problems it solves in the broader SCS context answering the following questions:'}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"What is it and for what do I need this? What benefits does it have for users?"}),"\n",(0,o.jsx)(n.li,{children:"What organization/company does this belong to? (Link to company/organization)"}),"\n",(0,o.jsx)(n.li,{children:"Where am I \u2013 as module \u2013 within the bigger context of SCS?"}),"\n"]}),"\n",(0,o.jsx)(n.h4,{id:"requirements",children:"Requirements"}),"\n",(0,o.jsx)(n.p,{children:"This section enumerates the necessary prerequisites to utilize the component, including software, hardware, and any required technical knowledge. What are the minimal requirements needed for a quickstart?"}),"\n",(0,o.jsx)(n.h4,{id:"quickstart",children:"Quickstart"}),"\n",(0,o.jsx)(n.p,{children:"A concise guide providing users with a quick set up of the component, covering installation instructions, basic configuration, and initial steps. Caution: it is only for testing and not for production."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"What is the aim of this quickstart guide?"}),"\n",(0,o.jsx)(n.li,{children:"Rule: one line per command for easy copy&paste and one line for description where possible"}),"\n",(0,o.jsx)(n.li,{children:"Rule: only one working path for installation."}),"\n"]}),"\n",(0,o.jsx)(n.h4,{id:"configuration",children:"Configuration"}),"\n",(0,o.jsx)(n.p,{children:"This section elaborates on the configurable aspects of the component, such as options, parameters, or settings that users can modify to suit their needs."}),"\n",(0,o.jsx)(n.h4,{id:"contribute",children:"Contribute"}),"\n",(0,o.jsx)(n.p,{children:"This document provides instructions on how interested parties can contribute to the component's development. It includes information on issue submission, proposed changes, and participation in discussions."}),"\n",(0,o.jsx)(n.h3,{id:"technical-implementation",children:"Technical Implementation"}),"\n",(0,o.jsx)(n.p,{children:"SCS employs Docusaurus, a contemporary static website generator, to implement the Docs Standard. Docusaurus serves as an ideal platform for creating, managing, and deploying extensive documentation."}),"\n",(0,o.jsx)(n.h4,{id:"documentation-framework",children:"Documentation Framework"}),"\n",(0,o.jsx)(n.p,{children:"Docusaurus' robust toolkit assists in crafting and maintaining quality documentation. It offers comprehensive features such as Markdown support, customizable themes, and versioning, making it an excellent choice for our needs. This platform allows us to create user-friendly and visually engaging documentation."}),"\n",(0,o.jsx)(n.h4,{id:"special-implementation-details",children:"Special Implementation Details"}),"\n",(0,o.jsx)(n.p,{children:"The unique architecture of SCS necessitates a unique approach to documentation. To ensure seamless integration of reference documentation for Components and components developed for SCS, we have created a custom workflow. This workflow automatically syncs upstream repositories, pulling the most recent documentation at regular intervals."}),"\n",(0,o.jsxs)(n.p,{children:["We have accomplished this by utilizing a Node.js post-install script found ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs-page/blob/main/getDocs.js",children:"here"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"This script prompts the system to pull the latest docs every eight hours and build the static page. The workflow's specifications can be viewed here."}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.a,{href:"https://docs.scs.community/",children:"SCS documentation"})," is built by the tooling from the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs-page/",children:"docs-page"})," repository, pulling content from ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/",children:"docs repository"})," as well as many other components as defined in the docs.package.json ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs-page/blob/main/docs.package.json",children:"here"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"writing-style-and-format--style-guide",children:"Writing Style and Format \u2013 Style Guide"}),"\n",(0,o.jsx)(n.h4,{id:"formatting-and-linting",children:"Formatting and Linting"}),"\n",(0,o.jsx)(n.p,{children:"All documentation text files must be provided as markdown files with an .md extension. This prerequisite ensures uniformity across our documents, making them more accessible and comprehensible."}),"\n",(0,o.jsx)(n.h4,{id:"diagrams-charts-and-images",children:"Diagrams, Charts, and Images"}),"\n",(0,o.jsx)(n.p,{children:"When necessary, diagrams, charts, and images can be used to simplify complex information. They should be properly captioned and referenced in the text."}),"\n",(0,o.jsx)(n.h4,{id:"linting",children:"Linting"}),"\n",(0,o.jsx)(n.p,{children:"To maintain a clean and consistent content repository, we enforce linting on:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"All staged files before committing"}),"\n",(0,o.jsx)(n.li,{children:"All Pull Requests"}),"\n"]}),"\n",(0,o.jsx)(n.h5,{id:"pre-commit",children:"Pre Commit"}),"\n",(0,o.jsxs)(n.p,{children:["We run markdownlint against staged Git files using the Husky Git hook. This process is facilitated by ",(0,o.jsx)(n.a,{href:"https://github.com/okonet/lint-staged",children:"lint-staged"})," and ",(0,o.jsx)(n.a,{href:"https://github.com/typicode/husky",children:"husky"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["The markdown files are linted according to the rules specified by ",(0,o.jsx)(n.a,{href:"https://github.com/DavidAnson/markdownlint-cli2",children:"markdownlint-cli2"})," and formatted with ",(0,o.jsx)(n.a,{href:"https://github.com/prettier/prettier",children:"prettier"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["The linting rules are specified in the configuration file .markdownlint-cli2.jsonc. Additionally, ",(0,o.jsx)(n.a,{href:"https://github.com/OnkarRuikar/markdownlint",children:"markdownlint-rule-search-replace"})]}),"\n",(0,o.jsx)(n.h5,{id:"github-workflows",children:"GitHub Workflows"}),"\n",(0,o.jsx)(n.p,{children:"There are two actions running on every Pull Request on the main branch:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsx)(n.li,{children:"link-validator.yml validates every link in the markdown files."}),"\n",(0,o.jsx)(n.li,{children:"pr-markdownlint.yml checks all markdown files according to the rules defined within .markdownlint-cli2.jsonc."}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["The Style Guide can be found ",(0,o.jsx)(n.a,{href:"https://docs.scs.community/community/community/contribute/styleguide/",children:"here"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"open-questions",children:"Open Questions"}),"\n",(0,o.jsx)(n.p,{children:"--"}),"\n",(0,o.jsx)(n.h3,{id:"reference",children:"Reference"}),"\n",(0,o.jsx)(n.p,{children:"--"})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var i=t(96540);const o={},s=i.createContext(o);function a(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7b787d81.220d9003.js b/assets/js/7b787d81.220d9003.js new file mode 100644 index 0000000000..9f99f92d62 --- /dev/null +++ b/assets/js/7b787d81.220d9003.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[52257],{35254:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"releases/Release0","title":"Release Notes for SCS Release 0","description":"(Release Date: 2021-07-15)","source":"@site/docs/06-releases/Release0.md","sourceDirName":"06-releases","slug":"/releases/Release0","permalink":"/docs/releases/Release0","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release0.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Releases","permalink":"/docs/category/releases"},"next":{"title":"Release Notes for SCS Release 1","permalink":"/docs/releases/Release1"}}');var a=t(74848),o=t(28453);const r={},i="Release Notes for SCS Release 0",l={},c=[{value:"Scope",id:"scope",level:2},{value:"Features",id:"features",level:2},{value:"Get SCS",id:"get-scs",level:2},{value:"Known Bugs",id:"known-bugs",level:2},{value:"Technical Previews",id:"technical-previews",level:2},{value:"Release tagging",id:"release-tagging",level:2},{value:"Updates",id:"updates",level:2},{value:"Bug reporting",id:"bug-reporting",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"release-notes-for-scs-release-0",children:"Release Notes for SCS Release 0"})}),"\n",(0,a.jsx)(n.p,{children:"(Release Date: 2021-07-15)"}),"\n",(0,a.jsx)(n.h2,{id:"scope",children:"Scope"}),"\n",(0,a.jsx)(n.p,{children:"The main focus of R0 is to demonstrate the viability of our approach to a much broader\naudience by providing a well-documented testbed. This will allow anyone interested\nto study the system in real-life, test, contribute, compare, ... it."}),"\n",(0,a.jsx)(n.p,{children:"Also we learn performing the release process."}),"\n",(0,a.jsx)(n.h2,{id:"features",children:"Features"}),"\n",(0,a.jsx)(n.p,{children:"Fully automated virtual (testbed setup) with ansible (terraform bootstrap to create\nstorage, networking and VM resources for bootstrapping via cloud-init injected\nscripts that call ansible).)"}),"\n",(0,a.jsx)(n.p,{children:"The infrastructure, management and openstack services are all deployed in containers."}),"\n",(0,a.jsx)(n.p,{children:"Included tools for Operations: ARA, Netbox, Cockpit, Netdata, Skydive (opt-in),\nPatchman, phpMyAdmin, Elasticsearch (b/f license change), Kibana, Grafana, influxdb"}),"\n",(0,a.jsx)(n.p,{children:"Validation: Rally, Refstack"}),"\n",(0,a.jsx)(n.p,{children:"Infrastructure: Linux, KVM, ceph (pacific), OpenVSwitch, OVN, MariaDB, RabbitMQ, Redis,\nEtcd, HAproxy, Keepalived, Memcached, Keycloak"}),"\n",(0,a.jsx)(n.p,{children:"IaaS (OpenStack - Wallaby): keystone, nova, glance, cinder, neutron, octavia, horizon"}),"\n",(0,a.jsx)(n.p,{children:"Optional OpenStack services: designate, heat, gnocchi, ceilometer, aodh, panko, senlin,\nbarbican, manila, magnum"}),"\n",(0,a.jsxs)(n.p,{children:["See ",(0,a.jsx)(n.a,{href:"https://docs.osism.de/testbed/overview.html#software-bill-of-materials-sbom",children:"testbed SBOM"})," for\na complete list. The exact versions of the contained components can be retrieved from the\n",(0,a.jsx)(n.a,{href:"https://github.com/osism/release/tree/master/1.0.0",children:"release repo"})," of OSISM."]}),"\n",(0,a.jsx)(n.h2,{id:"get-scs",children:"Get SCS"}),"\n",(0,a.jsxs)(n.p,{children:["See ",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/README.md",children:"main README"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"known-bugs",children:"Known Bugs"}),"\n",(0,a.jsx)(n.p,{children:"Nothing major known yet."}),"\n",(0,a.jsx)(n.h2,{id:"technical-previews",children:"Technical Previews"}),"\n",(0,a.jsx)(n.p,{children:"While already in productive use (on bare metal) by two providers, the bare metal\nsetup currently has a few more manual steps than we would like. This will improve\nwith the next releases."}),"\n",(0,a.jsx)(n.p,{children:"We have worked hard on supporting identity federation (OIDC and SAML) during the last\nfew months. We have also spent significant effort on getting the k8s stack with\nk8s cluster API into a good shape. However, we have determined that we do not\nyet consider those two key pieces as production-ready. The goal is to change that\nfor R1 (see below)."}),"\n",(0,a.jsx)(n.p,{children:"For now, you can use the software to see where SCS is going and test our technical\npreview code. We really appreciate feedback we get on these pieces as well.\nHowever keep in mind that we do not guarantee to ship technical previews from\na Release as production-ready software in one of the next releases. We certainly\nhope to do so."}),"\n",(0,a.jsxs)(n.p,{children:["To test how our k8s aaS platform will look like, have a look at the\n",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"k8s-cluster-api-provider repository"}),"\nYou can follow the documentation to set up the k8s cluster API on an SCS\ncloud (or other well configured OpenStack clouds that support octavia)."]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor",children:"openstack-health-monitor"}),"\nis used by us to monitor that the API works and successfully creates working resources\nin finite time. We plan to integrate it with a dashboard and an alarming mechanism in\nthe next releases."]}),"\n",(0,a.jsx)(n.h2,{id:"release-tagging",children:"Release tagging"}),"\n",(0,a.jsxs)(n.p,{children:["See ",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Release-Numbering-Scheme.md",children:"Release Numbering scheme"}),".\nThe containers have version number v1.0.0 for R0."]}),"\n",(0,a.jsx)(n.h2,{id:"updates",children:"Updates"}),"\n",(0,a.jsxs)(n.p,{children:["Updating the software can conveniently be done from the manager node by running the\nansible playbooks again. Details are in the\n",(0,a.jsx)(n.a,{href:"https://docs.osism.tech/testbed/usage.html#update-services",children:"OSISM testbed documentation"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"bug-reporting",children:"Bug reporting"}),"\n",(0,a.jsxs)(n.p,{children:["See ",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/README.md",children:"main README"})," file."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var s=t(96540);const a={},o=s.createContext(a);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7bd33c3d.22c19cee.js b/assets/js/7bd33c3d.22c19cee.js new file mode 100644 index 0000000000..f474053771 --- /dev/null +++ b/assets/js/7bd33c3d.22c19cee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[40192],{84767:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>o});const s=JSON.parse('{"id":"cloud-resources/getting-started-openstack","title":"Getting Started with OpenStack","description":"Getting Started with OpenStack CLI","source":"@site/community/cloud-resources/getting-started-openstack.md","sourceDirName":"cloud-resources","slug":"/cloud-resources/getting-started-openstack","permalink":"/community/cloud-resources/getting-started-openstack","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Getting Started with OpenStack","version":"2023-08-04T00:00:00.000Z","author":"Ralf Heiringhoff, Eduard Itrich, Mathias Fechner"},"sidebar":"community","previous":{"title":"Test and development cloud resources","permalink":"/community/cloud-resources/"},"next":{"title":"Getting Started Gaia-X Demonstrator @ plusserver","permalink":"/community/cloud-resources/plusserver-gx-scs"}}');var i=t(74848),c=t(28453);const r={title:"Getting Started with OpenStack",version:new Date("2023-08-04T00:00:00.000Z"),author:"Ralf Heiringhoff, Eduard Itrich, Mathias Fechner"},a=void 0,l={},o=[{value:"Getting Started with OpenStack CLI",id:"getting-started-with-openstack-cli",level:2},{value:"OpenStackClient (CLI)",id:"openstackclient-cli",level:2},{value:"Object Storage (S3)",id:"object-storage-s3",level:2},{value:"References",id:"references",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h2:"h2",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,c.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"getting-started-with-openstack-cli",children:"Getting Started with OpenStack CLI"}),"\n",(0,i.jsx)(n.h2,{id:"openstackclient-cli",children:"OpenStackClient (CLI)"}),"\n",(0,i.jsx)(n.p,{children:"The OpenStackClient is installable via all major Linux Distributions:"}),"\n",(0,i.jsx)(n.p,{children:"for debian and ubuntu with apt:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo apt install python3-openstackclient\n"})}),"\n",(0,i.jsx)(n.p,{children:"for ubuntu with snap openstack CLI is installable too:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo snap install openstackclients\n"})}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"[!NOTE]\nVersions from Linux repository could be in a stable but old state."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Install it directly via ",(0,i.jsx)(n.a,{href:"https://pypi.org/project/python-openstackclient",children:"pypi"}),"\nfrom upstream is the recommend way."]}),"\n",(0,i.jsx)(n.p,{children:"Here for example RHEL:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo dnf install python3 python3-devel gcc python3-pip\n"})}),"\n",(0,i.jsx)(n.p,{children:"Here for example Debian and Ubuntu:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo apt install python3-minimal python3-pip python3-venv python3-dev build-essential\n"})}),"\n",(0,i.jsx)(n.p,{children:"Here as example for SUSE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo zypper in python3-pip python3-venv python3-dev\n"})}),"\n",(0,i.jsx)(n.p,{children:"Here for example with Apple's MacOS"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"brew install python3\n"})}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsxs)(n.p,{children:["[!NOTE]\nPython installation for windows systems please use the ",(0,i.jsx)(n.a,{href:"https://www.python.org/downloads/windows/",children:"python installation guide"}),"\nor recommend use the ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/de-de/windows/wsl/install",children:"Linux Subsystem WSL"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Python Virtualenv"}),"\n",(0,i.jsx)(n.p,{children:"It is also recommended to use virtual environments, here as an example for\nLinux and MacOS:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"python3 -m venv oscli\nsource oscli/bin/activate\npip install --upgrade pip\npip install python-openstackclient \\\npython-cinderclient \\\npython-designateclient \\\npython-glanceclient \\\npython-neutronclient \\\npython-novaclient \\\npython-octaviaclient \\\npython-barbicanclient\n\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For further Information see the OpenStack Project upstream website\n",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/python-openstackclient/latest/index.html",children:"python-openstackclient"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This repo holds examples for ",(0,i.jsx)(n.a,{target:"_blank","data-noBrokenLinkCheck":!0,href:t(31814).A+"",children:"clouds-public.yaml"})," + ",(0,i.jsx)(n.a,{target:"_blank","data-noBrokenLinkCheck":!0,href:t(14486).A+"",children:"clouds.yaml"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Alternatively you can download an OpenRC Environment file when you're logged\nin to Horizon:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["upper right side ","\u27a1\ufe0f"," ",(0,i.jsx)(n.code,{children:"<your login name>"})]}),"\n",(0,i.jsx)(n.li,{children:"OpenStack RC File"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"$ source ./<$yourfile>-openrc.sh\nPlease enter your OpenStack Password for project XXX as user YYY:\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack --help\n"})}),"\n",(0,i.jsxs)(n.p,{children:["when you're using clouds.yaml you can specify multiple endpoints and\nselect the specific endpoint by passing ",(0,i.jsx)(n.code,{children:"--os-cloud="})," to the\nopenstack cmdline or setting ",(0,i.jsx)(n.code,{children:"OS_CLOUD"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack --os-cloud MYCLOUD\n"})}),"\n",(0,i.jsx)(n.p,{children:"or"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"export OS_CLOUD=MYCLOUD\nopenstack\n"})}),"\n",(0,i.jsxs)(n.p,{children:["OpenStack Client in action inside of the OSISM testbed:\n",(0,i.jsx)(n.img,{alt:"Example OpenStackClient in testbed",src:t(77508).A+"",width:"2520",height:"1098"})]}),"\n",(0,i.jsx)(n.h2,{id:"object-storage-s3",children:"Object Storage (S3)"}),"\n",(0,i.jsxs)(n.p,{children:["Create AWS like credentials with ",(0,i.jsx)(n.code,{children:"openstack ec2 credentials create"}),".\nIf you use libs3, store the access field in ",(0,i.jsx)(n.code,{children:"S3_ACCESS_KEY_ID"})," and the secret\nfield in",(0,i.jsx)(n.code,{children:"S3_SECRET_ACCESS_KEY"})," and set ",(0,i.jsx)(n.code,{children:"S3_HOSTNAME=<Object Storage endpoint>"}),".\nYou will see the same buckets (containers) and objects whether you access your\nobject store via the swift or via the s3 protocol."]}),"\n",(0,i.jsx)(n.h2,{id:"references",children:"References"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://www.openstack.org",title:"OpenStack Site",children:"OpenStack"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack",title:"SovereignCloudStack on github",children:"SovereignCloudStack"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://github.com/osism",title:"OSISM on github",children:"OSISM"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/collections/openstack/cloud/index.html",title:"Ansible Module OpenStack",children:"ansible"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs",title:"OpenStack Terraform Provider",children:"terraform"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://cloudinit.readthedocs.io/en/latest/",title:"cloud-init documentation",children:"cloud-init"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},31814:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/files/clouds-public-e9ba939dfde1c0efe3a32ec6f5d1f612.yaml"},14486:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/files/clouds.yaml-9c0c983f9c293bc5adeae683d442174e.sample"},77508:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/getting_started_openstack_anim-d88d134eff244cf8891c5ca1efcfc65a.gif"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const i={},c=s.createContext(i);function r(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7bed4829.7e567bbb.js b/assets/js/7bed4829.7e567bbb.js new file mode 100644 index 0000000000..8e88b20fb3 --- /dev/null +++ b/assets/js/7bed4829.7e567bbb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[24984],{16347:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"container/components/container-registry/docs/backup_and_restore","title":"Backup and restore","description":"This page aims at providing a step-by-step guide for backup and restore Harbor","source":"@site/docs/03-container/components/container-registry/docs/backup_and_restore.md","sourceDirName":"03-container/components/container-registry/docs","slug":"/container/components/container-registry/docs/backup_and_restore","permalink":"/docs/container/components/container-registry/docs/backup_and_restore","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/backup_and_restore.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Upgrade","permalink":"/docs/container/components/container-registry/docs/upgrade"},"next":{"title":"Migration","permalink":"/docs/container/components/container-registry/docs/migration"}}');var t=s(74848),a=s(28453);const o={},i="Backup and restore",c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Kubernetes cluster",id:"kubernetes-cluster",level:3},{value:"S3 bucket and EC2 credentials",id:"s3-bucket-and-ec2-credentials",level:3},{value:"Velero client",id:"velero-client",level:3},{value:"Velero server",id:"velero-server",level:3},{value:"Backup and restore",id:"backup-and-restore-1",level:2},{value:"Backup Harbor Instance",id:"backup-harbor-instance",level:3},{value:"Restore Harbor Instance",id:"restore-harbor-instance",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"backup-and-restore",children:"Backup and restore"})}),"\n",(0,t.jsxs)(n.p,{children:["This page aims at providing a step-by-step guide for backup and restore ",(0,t.jsx)(n.a,{href:"https://goharbor.io/",children:"Harbor"}),"\ncontainer registry using ",(0,t.jsx)(n.a,{href:"https://velero.io/",children:"Velero"})," tool.\nIt extends the official ",(0,t.jsx)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/",children:"Harbor backup-restore docs page"}),"\nwith up-to-date commands, explanations, and an extensive prerequisites section. This\nguide references and uses Velero in ",(0,t.jsx)(n.a,{href:"https://github.com/vmware-tanzu/velero/releases/tag/v1.10.2",children:"v1.10.2"}),"\nas this is the latest stable version at the time of writing this guide."]}),"\n",(0,t.jsx)(n.p,{children:"It provides guidance and commands that readers are encouraged to try out by themselves\non Harbor deployment as described in the next sections. It does not aim at providing an\nexhaustive list of commands nor all the possible ways how to use them."}),"\n",(0,t.jsx)(n.p,{children:"The guide covers two strategies to save Harbor data:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Backup: a regular backup created by the ",(0,t.jsx)(n.a,{href:"https://restic.net/",children:"restic"})," integration in Velero as described in the related ",(0,t.jsx)(n.a,{href:"https://velero.io/docs/main/file-system-backup/",children:"docs"})]}),"\n",(0,t.jsxs)(n.li,{children:["Snapshot: a point-in-time snapshot be the Container Storage Interface (CSI) snapshot support in Velero as described in the related ",(0,t.jsx)(n.a,{href:"https://velero.io/docs/main/csi/",children:"docs"})]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Before you choose the right strategy for your Harbor deployment backup, make sure that you understand\n",(0,t.jsx)(n.a,{href:"https://www.terra-master.com/global/snapshot",children:"differences"})," between the backup and snapshot.\nIn general, for long-term protection of Harbor data, you may use backup and for\ntemporary protection of data (e.g. before Harbor upgrade) you may use snapshot."]}),"\n",(0,t.jsxs)(n.p,{children:["Note that this guide is not limited to Harbor deployments that utilize SCS environments,\nbut it is required to have a set of tools and services (e.g. Kubernetes CSI plugin with volume snapshot\nsupport, S3 compatible object store for backups) for successful backup and restore procedure\n(see the ",(0,t.jsx)(n.a,{href:"#prerequisites",children:"prerequisites"})," section). These tools and services come out of\nthe box when the SCS infrastructure and KaaS are used for Harbor deployment, hence it is\nconvenient to use them."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.h3,{id:"kubernetes-cluster",children:"Kubernetes cluster"}),"\n",(0,t.jsxs)(n.p,{children:["If you want to use ",(0,t.jsx)(n.code,{children:"snapshot"})," to back up Harbor data ensure the following:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Your cluster is Kubernetes version 1.20 or greater"}),"\n",(0,t.jsxs)(n.li,{children:["Your cluster is running a ",(0,t.jsx)(n.a,{href:"https://kubernetes-csi.github.io/docs/drivers.html",children:"CSI driver"}),"\ncapable of support volume snapshots at the ",(0,t.jsx)(n.a,{href:"https://kubernetes.io/blog/2020/12/10/kubernetes-1.20-volume-snapshot-moves-to-ga/",children:"v1 API level"}),".\nTo enable creating volume snapshots, the ",(0,t.jsx)(n.a,{href:"https://kubernetes-csi.github.io/docs/snapshot-controller.html",children:"snapshot-controller"}),"\nand its CRDs should be deployed in the Kubernetes cluster as well. The snapshot-controller\nis independent of any CSI Driver. These prerequisites come out of the box with the SCS KaaS solution."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["If you want to create Harbor ",(0,t.jsx)(n.code,{children:"backup"})," ensure the following:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Your cluster is Kubernetes version 1.16 or greater"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["If your cluster meets the above, export its kubeconfig path in env. variable ",(0,t.jsx)(n.code,{children:"KUBECONFIG"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"export KUBECONFIG=/path/to/kubeconfig\n"})}),"\n",(0,t.jsx)(n.h3,{id:"s3-bucket-and-ec2-credentials",children:"S3 bucket and EC2 credentials"}),"\n",(0,t.jsx)(n.p,{children:"This guide assumes that the public cloud's object store with S3-compatible API is available as\nthe storage backend for Velero. In this guide, we are using OpenStack Swift which\noffers S3-compatible API. Let's create an S3 bucket on Swift object storage and EC2 credentials\nthat will be later used by Velero."}),"\n",(0,t.jsx)(n.p,{children:"You should have access to your OpenStack project, and the OpenStack RC file that contains access\nvalues. Set the environment variables by sourcing the OpenStack RC file:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source <project>-openrc.sh\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Swift object store service does not support application credentials authentication\nto access S3 API. To authenticate in S3 API, you should generate and use the EC2 credentials\nmechanism.\nNote that EC2 credentials are associated with a user and are scoped only to a specific project.\nEC2 credentials are not protected by limited roles, expiration time, or\naccess rules, therefore they have the same access as the user who created them. If you\nwant to restrict EC2 credentials you could use application credentials for their creation,\nthen EC2 credentials should inherit a (potentially) limited subset of roles that creator\nowns (see ",(0,t.jsx)(n.a,{href:"https://opendev.org/openstack/keystone/commit/487c7276c7608fb11086b9875b0d7cc7cf594a5a",children:"this"})," for details)."]}),"\n",(0,t.jsx)(n.p,{children:"You can generate EC2 credentials as follows:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ openstack ec2 credentials create\n+------------+----------------------------------------------------------------------------------------------------------+\n| Field | Value |\n+------------+----------------------------------------------------------------------------------------------------------+\n| access | <aws_access_key_id> |\n| links | {'self': 'https://api.gx-scs.sovereignit.cloud:5000/v3/users/<user_id>/credentials/OS-EC2/<project_id>'} |\n| project_id | <project_id> |\n| secret | <aws_secret_access_key> |\n| trust_id | None |\n| user_id | <user_id> |\n+------------+----------------------------------------------------------------------------------------------------------+\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Write down ",(0,t.jsx)(n.code,{children:"aws_access_key_id"})," and ",(0,t.jsx)(n.code,{children:"aws_secret_access_key"})," values from the output of ",(0,t.jsx)(n.code,{children:"openstack ec2 credentials create"}),"\ncommand and store them in the ",(0,t.jsx)(n.code,{children:"~/.aws/credentials"})," file as follows:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"mkdir ~/.aws\ncat >~/.aws/credentials <<EOF\n[default]\naws_access_key_id = <aws_access_key_id>\naws_secret_access_key = <aws_secret_access_key>\nEOF\n"})}),"\n",(0,t.jsx)(n.p,{children:"This credential file is then used as an access and secret source for AWS CLI tool and also\nas a source for Velero. If your environment does not have AWS CLI installed, install it as follows:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip3 install awscli awscli-plugin-endpoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Finally, create a new bucket. Note that the following command contains ",(0,t.jsx)(n.code,{children:"endpoint-url"}),"\nargument that points AWS CLI to the GX-SCS OpenStack Swift object store API."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"aws --endpoint-url https://api.gx-scs.sovereignit.cloud:8080 s3 mb s3://velero-backup\n"})}),"\n",(0,t.jsx)(n.h3,{id:"velero-client",children:"Velero client"}),"\n",(0,t.jsxs)(n.p,{children:["In this guide, we are using ",(0,t.jsx)(n.a,{href:"https://velero.io/",children:"Velero"})," to back up and restore a Harbor instance.\nVelero is an open source tool to safely back up and restore, perform disaster recovery,\nand migrate Kubernetes cluster resources."]}),"\n",(0,t.jsxs)(n.p,{children:["Go through the ",(0,t.jsx)(n.a,{href:"https://velero.io/docs/main/basic-install/",children:"official docs"})," and\ninstall the Velero client on your desired environment. If your environment is Linux distribution\nyou can use the following steps and install the Velero client from the GitHub release binaries:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"wget https://github.com/vmware-tanzu/velero/releases/download/v1.10.2/velero-v1.10.2-linux-amd64.tar.gz \ntar -zxvf velero-v1.10.2-linux-amd64.tar.gz \nsudo mv velero-v1.10.2-linux-amd64/velero /usr/local/bin/\n"})}),"\n",(0,t.jsx)(n.h3,{id:"velero-server",children:"Velero server"}),"\n",(0,t.jsxs)(n.p,{children:["Install Velero server components along with the appropriate plugins, into the Kubernetes cluster.\nThis will create a namespace called ",(0,t.jsx)(n.code,{children:"velero"}),", and place a deployment named ",(0,t.jsx)(n.code,{children:"velero"})," in it.\nNote that the installation command sets the bucket ",(0,t.jsx)(n.code,{children:"velero-backup"})," that has been created a few steps\nearlier as well as EC2 credentials located in ",(0,t.jsx)(n.code,{children:"~/.aws/credentials"})," file. Also note that\nthe ",(0,t.jsx)(n.code,{children:"region"})," and ",(0,t.jsx)(n.code,{children:"s3Url"})," parameters are GX-SCS specific. For further details about installation\noptions, supported storage providers, and more visit the official Velero ",(0,t.jsx)(n.a,{href:"https://velero.io/docs/",children:"docs"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["If you want to use ",(0,t.jsx)(n.code,{children:"snapshot"})," to back up Harbor data:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Install Velero:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:' velero install \\\n --features=EnableCSI \\\n --provider aws \\\n --plugins velero/velero-plugin-for-aws:v1.6.1,velero/velero-plugin-for-csi:v0.4.2 \\\n --bucket velero-backup \\\n --secret-file ~/.aws/credentials \\\n --backup-location-config region=RegionOne,s3ForcePathStyle="true",s3Url=https://api.gx-scs.sovereignit.cloud:8080 \\\n --snapshot-location-config region=RegionOne,enableSharedConfig=true\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"In order to allow Velero to do Volume Snapshots, we need to deploy a new VolumeSnapshotClass. Create a velero-snapclass.yaml file as follows:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'cat > velero-snapclass.yaml << EOF\napiVersion: snapshot.storage.k8s.io/v1\ndeletionPolicy: Delete\ndriver: cinder.csi.openstack.org\nkind: VolumeSnapshotClass\nmetadata:\n name: csi-cinder-snapclass-in-use-v1-velero\n labels:\n velero.io/csi-volumesnapshot-class: "true"\nparameters:\n force-create: "true"\nEOF\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Apply the new class:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f velero-snapclass.yaml\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["If you want to create Harbor ",(0,t.jsx)(n.code,{children:"backup"})," with Restic:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Install Velero:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'velero install \\\n --provider aws \\\n --plugins velero/velero-plugin-for-aws:v1.6.1 \\\n --bucket velero-backup \\\n --secret-file ~/.aws/credentials \\\n --use-volume-snapshots=false \\\n --uploader-type=restic \\\n --use-node-agent \\\n --backup-location-config region=RegionOne,s3ForcePathStyle="true",s3Url=https://api.gx-scs.sovereignit.cloud:8080\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"backup-and-restore-1",children:"Backup and restore"}),"\n",(0,t.jsxs)(n.p,{children:["Note that the following backup steps mainly point to actions from an official ",(0,t.jsx)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore",children:"Backup And Restore Harbor With Velero"})," tutorial.\nIn this guide, find the added value from additional explanations/hints and up-to-date commands."]}),"\n",(0,t.jsxs)(n.p,{children:["Harbor, by design, consists of multiple (micro)services that could store their data\nvariously, based on the Harbor configuration. See the ",(0,t.jsx)(n.a,{href:"/docs/container/components/container-registry/docs/persistence",children:"Harbor persistence"}),'\ndocs for further information regarding the Harbor persistence layer. The following steps cover\ncases when Harbor persistence is enabled and the "internal" databases (PostgreSQL and Redis)\nare used.']}),"\n",(0,t.jsx)(n.p,{children:'Note that Redis key-value database is not backed up in both cases, i.e. when "internal"\nor "external" Redis instance is used. As a result, the user sessions of logged users\nthat are stored in Redis will be lost. Hence, after the restore, users should log in\nagain. This data loss should be a low impact on your restored Harbor instance.'}),"\n",(0,t.jsx)(n.p,{children:'PostgreSQL database should be backed up as it stores important metadata of Harbor models,\nlike projects, users, roles, etc. The backup and restore of "internal" PostgreSQL instance\nis covered by this guide. The "external" PostgreSQL backup is not supported by the\nofficial tutorial and is out of the scope of this guide as well.'}),"\n",(0,t.jsxs)(n.p,{children:["Also, keep an eye on the official backup and restore ",(0,t.jsx)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#limitations",children:"limitations"}),"\nsection to be aware of the potential impact on your Harbor instance. The limitation:\n",(0,t.jsx)(n.code,{children:"The upload purging process may cause backup failure"})," mentioned that it is better to\nincrease registry upload purging interval (it is a background process that periodically\nremoves orphaned files from the upload directories of the registry, see the ",(0,t.jsx)(n.a,{href:"https://docs.docker.com/registry/configuration/#uploadpurging",children:"docs"}),").\nThis interval is by ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor-helm/blob/master/values.yaml#L598",children:"default"}),"\nset to 24h (helm value: ",(0,t.jsx)(n.code,{children:"registry.upload_purging.interval"}),"). If you do not want to change\nthe registry configuration at all you should ensure that the backup will be performed in\nthe middle of two rounds of purging. This background process starts when the registry\ncontainer is initialized, therefore is a good idea to check logs of the registry container\nand determine when is a good time to do a backup, e.g. as follows:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'$ kubectl logs -l component=registry -c registry --tail -1 | grep -i purge\ntime="2023-04-17T09:02:08.320514706Z" level=info msg="Starting upload purge in 24h0m0s" go.version=go1.15.6 instance.id=xxx service=registry version=v2.7.1.m \ntime="2023-04-17T09:09:08.321004645Z" level=info msg="PurgeUploads starting: olderThan=2023-04-10 09:09:08.320738572 +0000 UTC m=-604379.969424455, actuallyDelete=true" \ntime="2023-04-17T09:09:08.331433127Z" level=info msg="Purge uploads finished. Num deleted=0, num errors=0" \n...\n'})}),"\n",(0,t.jsx)(n.h3,{id:"backup-harbor-instance",children:"Backup Harbor Instance"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsxs)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#set-harbor-to-readonly",children:["Set Harbor to the ",(0,t.jsx)(n.code,{children:"ReadOnly"})," mode"]})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Backup Harbor:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Using ",(0,t.jsx)(n.code,{children:"snapshot"})," to back up Harbor data:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Exclude the volume of Redis in backup, we need to label the Redis pod, PVC and PV with specific label:","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# label the Pod of Redis, replace the namespace and Pod name with yours\n kubectl -n default label pod/harbor-harbor-redis-0 velero.io/exclude-from-backup=true\n # label the PVC of Redis, replace the namespace and PVC name with yours\n kubectl -n default label pvc/data-harbor-harbor-redis-0 velero.io/exclude-from-backup=true\n # get the name of Redis PV, replace the namespace and PVC name with yours\n kubectl -n default get pvc data-harbor-harbor-redis-0 --template={{.spec.volumeName}}\n # label the PV of Redis, replace the pv-name with the one get from last command\n kubectl label pv/pv-name velero.io/exclude-from-backup=true\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Back up Harbor","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# replace the namespace and backup name with yours\nvelero backup create harbor-backup --include-namespaces default --snapshot-volumes --wait\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Using ",(0,t.jsx)(n.code,{children:"Restic"})," to back up Harbor data:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Exclude the volume of Redis in backup","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# replace the namespace and pod name with yours\nkubectl -n default annotate pod/harbor-harbor-redis-0 backup.velero.io/backup-volumes-excludes=data\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Back up Harbor","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"velero backup create harbor-backup --include-namespaces default --default-volumes-to-fs-backup --wait\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsxs)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#unset-readonly",children:["Unset Harbor from the ",(0,t.jsx)(n.code,{children:"ReadOnly"})," mode"]})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"restore-harbor-instance",children:"Restore Harbor Instance"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#restore-harbor-instance",children:"Restore Harbor Instance"})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>i});var r=s(96540);const t={},a=r.createContext(t);function o(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7cf96b3e.325281e7.js b/assets/js/7cf96b3e.325281e7.js new file mode 100644 index 0000000000..d81dc003bc --- /dev/null +++ b/assets/js/7cf96b3e.325281e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[65770],{49136:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"scs-0113-v1-security-groups-decision-record","title":"Security Groups Decision Record","description":"Introduction","source":"@site/standards/scs-0113-v1-security-groups-decision-record.md","sourceDirName":".","slug":"/scs-0113-v1-security-groups-decision-record","permalink":"/standards/scs-0113-v1-security-groups-decision-record","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Security Groups Decision Record","type":"Decision Record","status":"Draft","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0113: Security Groups Decision Record","permalink":"/standards/iaas/scs-0113"},"next":{"title":"scs-0114: SCS Volume Types","permalink":"/standards/iaas/scs-0114"}}');var n=t(74848),o=t(28453);const i={title:"Security Groups Decision Record",type:"Decision Record",status:"Draft",track:"IaaS"},a=void 0,c={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Context",id:"context",level:2},{value:"Reasons for and against a standard for security groups",id:"reasons-for-and-against-a-standard-for-security-groups",level:3},{value:"Technical limitations",id:"technical-limitations",level:3},{value:"Option 0: Pre-Requirement: default rules for the (default) security group",id:"option-0-pre-requirement-default-rules-for-the-default-security-group",level:3},{value:"Option 1: operator usage of network rbac",id:"option-1-operator-usage-of-network-rbac",level:3},{value:"Option 2: stay project-scoped",id:"option-2-stay-project-scoped",level:3},{value:"Option 3: security-focused guide",id:"option-3-security-focused-guide",level:3},{value:"Decisions",id:"decisions",level:2},{value:"Consequences",id:"consequences",level:2},{value:"Related Documents",id:"related-documents",level:2}];function u(e){const s={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",section:"section",sup:"sup",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsx)(s.p,{children:"Security Groups in IaaS (OpenStack) are sets of ip table rules, that are applied to ports which connect a virtual machine to a network.\nIn contrast to other resources like flavors or volume types that are always publicly accessible, or images that can be both public and private, security groups are always bound to the project level.\nThat creates some difficulties for a possible standard of Security Groups, which are discussed in this document."}),"\n",(0,n.jsx)(s.h2,{id:"terminology",children:"Terminology"}),"\n",(0,n.jsx)(s.p,{children:"Security Group\nA set of iptables rules that is applied to ports connecting a virtual machine and a network."}),"\n",(0,n.jsx)(s.p,{children:"Security Group Rule (abbr. Rule)\nThis references a single rule within a security group."}),"\n",(0,n.jsx)(s.p,{children:"RBAC\nRole Based Access Control used for policies and alike."}),"\n",(0,n.jsx)(s.p,{children:"network rbac / neutron rbac\nThese access controls will let administrators and users share neutron related resources with other projects."}),"\n",(0,n.jsx)(s.p,{children:"admin\nThe most powerful role in OpenStack. Only given to some Operators of the Cloud Infrastructure."}),"\n",(0,n.jsx)(s.h2,{id:"context",children:"Context"}),"\n",(0,n.jsxs)(s.p,{children:["While creating a virtual machine and also later on, one or more security groups can be added to it.\nWhen there is no security group specified the default security group will always be added.\nLike every other security group, the default group is also project bound.\nThat means, it can be edited as required by project members.\nBy design of OpenStack and when not changed, default rules in the default security group block all incoming traffic except from the same Security Group and only allow outgoing traffic",(0,n.jsx)(s.sup,{children:(0,n.jsx)(s.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"."]}),"\n",(0,n.jsx)(s.h3,{id:"reasons-for-and-against-a-standard-for-security-groups",children:"Reasons for and against a standard for security groups"}),"\n",(0,n.jsx)(s.p,{children:"Considering having most likely similar security groups within different projects, it might make sense to standardize a few security groups for often used cases like ssh, http, https and maybe icmp.\nWhat speaks for standardizing a certain set of security groups:"}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsx)(s.li,{children:"Having a set of correctly configured security groups could reduce misconfiguration from users"}),"\n",(0,n.jsx)(s.li,{children:"Re-using correctly configured security groups saves time for users"}),"\n",(0,n.jsx)(s.li,{children:"Auditing security groups would be way easier for operators when helping customers"}),"\n",(0,n.jsx)(s.li,{children:"The configuration for the Security Groups can be done by networking experts, which may result in a higher security level as when users without expertise configure them"}),"\n"]}),"\n",(0,n.jsx)(s.p,{children:"What are the downsides of having a set of standardized security groups:"}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsx)(s.li,{children:"A bug or misconfiguration is a single point of failure for ALL customers"}),"\n",(0,n.jsx)(s.li,{children:"Users might apply the wrong security group to their port or VM because they lack the domain knowledge, unknowingly opening themselves to attacks"}),"\n",(0,n.jsx)(s.li,{children:"Users will not inspect such default security groups: this may result in applying a wrong group and opening traffic too much"}),"\n",(0,n.jsx)(s.li,{children:"the central authority managing the groups does not necessarily know the use case of the user, the user/operator must know best what kind of security their workload needs. What is a necessary port for 99% of deployments might be a security disaster for my deployment"}),"\n",(0,n.jsx)(s.li,{children:"Providing default groups could have the effect of stopping customers to think about their specific security needs and instead just copying default groups and or rules"}),"\n"]}),"\n",(0,n.jsx)(s.p,{children:"This leads to a conclusion, that a set of default security groups is only more valuable than harmful for users:"}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsx)(s.li,{children:"when the rules in those groups are configured correctly"}),"\n",(0,n.jsx)(s.li,{children:"and when the users still have to think about their network security on their own for each VM they start"}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"technical-limitations",children:"Technical limitations"}),"\n",(0,n.jsx)(s.p,{children:"As security groups are project bound and there is no native way to them to be shared, we are left with three options:"}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsxs)(s.li,{children:["To use another endpoint ",(0,n.jsx)(s.code,{children:"network rbac"})," to share security groups among different projects."]}),"\n",(0,n.jsx)(s.li,{children:"To adhere to the project scope of security groups and only give documentation about recommended security groups to users."}),"\n",(0,n.jsx)(s.li,{children:"To only add a tutorial on how to create your own security group in general, how to detect what kind of network permissions your project needs for most frequent (linux) workloads and how to craft your own security groups in a secure way."}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"option-0-pre-requirement-default-rules-for-the-default-security-group",children:"Option 0: Pre-Requirement: default rules for the (default) security group"}),"\n",(0,n.jsx)(s.p,{children:"For every project that is created there will also be a project-specific default security group created.\nThe default rules for the default groups and all other newly created groups can be looked up like this:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"stack@devstack:~/devstack$ openstack default security group rule list\n+------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+\n| ID | IP Protocol | Ethertype | IP Range | Port Range | Direction | Remote Security Group | Remote Address Group | Used in default Security Group | Used in custom Security Group |\n+------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+\n| 47b929fd-9b39-4f22- | None | IPv6 | ::/0 | | egress | None | None | True | True |\n| abc5-7d4f64d10909 | | | | | | | | | |\n| 6ace51bb-5258-45ab- | None | IPv6 | ::/0 | | ingress | PARENT | None | True | False |\n| 9ba9-1efbebfb086b | | | | | | | | | |\n| 92a79600-5358-4fef- | None | IPv4 | 0.0.0.0/0 | | egress | None | None | True | True |\n| a390-822665f46070 | | | | | | | | | |\n| 997bb0c2-652e-4d1f- | None | IPv4 | 0.0.0.0/0 | | ingress | PARENT | None | True | False |\n| b910-e12c89f88b44 | | | | | | | | | |\n+------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Those rules can be edited, which may pose a security risk for customers consuming the default security group.\nThis should be addressed as a pre-requirement ",(0,n.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/issues/521",children:"here"}),"."]}),"\n",(0,n.jsx)(s.h3,{id:"option-1-operator-usage-of-network-rbac",children:"Option 1: operator usage of network rbac"}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.code,{children:"network rbac"})," endpoint",(0,n.jsx)(s.sup,{children:(0,n.jsx)(s.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," manages the possibility to share and access certain network-specific resources such as security groups.\nFor admins, it is possible to use this endpoint to share a security group with ALL projects within the cloud including ALL projects of ALL domains:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"stack@devstack:~/devstack$ openstack network rbac create --target-all-projects --action access_as_shared --type security_group group-for-everyone\n+-------------------+--------------------------------------+\n| Field | Value |\n+-------------------+--------------------------------------+\n| action | access_as_shared |\n| id | 394d8e71-143f-4c5b-a72f-cd10af3222df |\n| object_id | b6a3834a-f89c-47a9-9ed6-ca89e93701c4 |\n| object_type | security_group |\n| project_id | 15f2ab0eaa5b4372b759bde609e86224 |\n| target_project_id | * |\n+-------------------+--------------------------------------+\n"})}),"\n",(0,n.jsx)(s.p,{children:"This would fulfill our goal to grant access to predefined security groups for all projects and all groups received as shared do not count into the projects quota for security groups.\nBut there are a few downsides to this:"}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsx)(s.li,{children:"This should be strictly bound to the admin: no other user should be able to share security groups so to not confuse user."}),"\n",(0,n.jsxs)(s.li,{children:["The managing of those ",(0,n.jsx)(s.code,{children:"network rbac"})," objects can get out of hand pretty quickly, because there neither is an explicit name for such an object nor do the names of the shared objects appear:"]}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"stack@devstack:~/devstack$ openstack network rbac list --long\n+-----------------------------+----------------+-----------------------------+--------------------+\n| ID | Object Type | Object ID | Action |\n+-----------------------------+----------------+-----------------------------+--------------------+\n| 97507e4c-7413-4d61-ab21- | security_group | 110b1bea-f0e0-4fb7-9fc7- | access_as_shared |\n| 047fc23516dd | | cda1b6f927b0 | |\n| bc22a865-46f9-4cd2-80af- | security_group | 5f22e42e-95dc-4c0a-8651- | access_as_shared |\n| 3c249ba0e010 | | 57b1dfc8639f | |\n| 2467806f-5428-4506-8e23- | network | 02ef8579-9917-4a01-893d- | access_as_shared |\n| f4690db04e01 | | cb2f9f3d5f98 | |\n| ed40996e-218d-4daa-b222- | network | 73edb86b-d7ab-4db3-82b7- | access_as_external |\n| f3c603a5b8a6 | | 25fa8b012e40 | |\n| 45e0a707-af82-42a6-b93f- | subnetpool | cd7addd1-05d9-48a8-bc38- | access_as_shared |\n| efde18216f13 | | 4a581354983f | |\n| e514c2c8-65ac-4062-8b03- | subnetpool | ad1cc1ed-3261-4df2-8c73- | access_as_shared |\n| fe24f6fc4656 | | c3dd72d59061 | |\n+-----------------------------+----------------+-----------------------------+--------------------+\nstack@devstack:~/devstack$ openstack network rbac show bc22a865-46f9-4cd2-80af-3c249ba0e010\n+-------------------+--------------------------------------+\n| Field | Value |\n+-------------------+--------------------------------------+\n| action | access_as_shared |\n| id | bc22a865-46f9-4cd2-80af-3c249ba0e010 |\n| object_id | 5f22e42e-95dc-4c0a-8651-57b1dfc8639f |\n| object_type | security_group |\n| project_id | 15f2ab0eaa5b4372b759bde609e86224 |\n| target_project_id | * |\n+-------------------+--------------------------------------+\n"})}),"\n",(0,n.jsx)(s.p,{children:"The biggest downside: As soon as a security group is shared, everyone from every project, can edit the rules of this group."}),"\n",(0,n.jsx)(s.h3,{id:"option-2-stay-project-scoped",children:"Option 2: stay project-scoped"}),"\n",(0,n.jsx)(s.p,{children:"Using and adhering the project scope of the security groups has the consequence, that:"}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsx)(s.li,{children:"either an admin has to set up security groups for each project"}),"\n",(0,n.jsx)(s.li,{children:"or the SCS project only provides a guide on how to set up and use some recommended security groups."}),"\n"]}),"\n",(0,n.jsx)(s.p,{children:"As users are allowed to, will and should edit their security groups, there is no way to ensure, that a certain set of security groups with certain rules is always present in a project.\nSo packing an extra burden on admins is unreasonable.\nThe option to give a guide and recommend a few security groups however is a quite good option."}),"\n",(0,n.jsx)(s.h3,{id:"option-3-security-focused-guide",children:"Option 3: security-focused guide"}),"\n",(0,n.jsx)(s.p,{children:"Instead of providing users with a set of default groups or the knowledge about how to create default groups, there could be a guide created that focuses on the crafting of a security group in a secure way.\nThat would include identifying what kind of network permission a single VM needs and how to proceed after gathering all requirements of the customers workload."}),"\n",(0,n.jsx)(s.h2,{id:"decisions",children:"Decisions"}),"\n",(0,n.jsx)(s.p,{children:"The default Security Group Rules should be standardized as a pre-requirement (Option 0)."}),"\n",(0,n.jsxs)(s.p,{children:["Using the ",(0,n.jsx)(s.code,{children:"network rbac"})," endpoint (Option 1) would not solve the idea of having pre-defined and administrator audited Security Groups, because it is possible for any user to edit the rules of shared Security Groups.\nInstead, the project-scope of the Security Groups should by focused and a guide prepared, that gives insight about creating and using Security Groups with a few examples but with a clear security focus (Mix of Option 2 and 3)."]}),"\n",(0,n.jsx)(s.h2,{id:"consequences",children:"Consequences"}),"\n",(0,n.jsx)(s.p,{children:"Any CSP will have to follow the standard for the default Security Group Rules.\nThere are no consequences regarding Security Groups as it and users stay in full control and responsible for their own Security Groups"}),"\n",(0,n.jsx)(s.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/pull/525",children:"A PR to standardize default Security Group Rules"}),"\n",(0,n.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/docs/pull/142",children:"A PR to a first draft for a guide for security groups"})]}),"\n","\n",(0,n.jsxs)(s.section,{"data-footnotes":!0,className:"footnotes",children:[(0,n.jsx)(s.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsxs)(s.li,{id:"user-content-fn-1",children:["\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"https://github.com/openstack/neutron/blob/master/neutron/db/migration/alembic_migrations/versions/2023.2/expand/c33da356b165_security_group_default_rules.py",children:"Default Security Group Rules"})," ",(0,n.jsx)(s.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{id:"user-content-fn-2",children:["\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"https://docs.openstack.org/neutron/latest/admin/config-rbac.html",children:"Neutron RBAC"})," ",(0,n.jsx)(s.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>a});var r=t(96540);const n={},o=r.createContext(n);function i(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7d3935d1.c1d6c0c5.js b/assets/js/7d3935d1.c1d6c0c5.js new file mode 100644 index 0000000000..42169957f5 --- /dev/null +++ b/assets/js/7d3935d1.c1d6c0c5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2683],{1523:(e,r,s)=>{s.r(r),s.d(r,{assets:()=>u,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"iaas/guides/user-guide/security-groups/security-groups","title":"Best Practise: How to configure and use security groups","description":"Security groups in OpenStack are part of the network security mechanisms provided for the users.","source":"@site/docs/02-iaas/guides/user-guide/security-groups/security-groups.md","sourceDirName":"02-iaas/guides/user-guide/security-groups","slug":"/iaas/guides/user-guide/security-groups/","permalink":"/docs/iaas/guides/user-guide/security-groups/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/security-groups/security-groups.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"User Data Backups","permalink":"/docs/iaas/guides/user-guide/openstack/user-data-backups"},"next":{"title":"User Data Backups","permalink":"/docs/iaas/guides/user-guide/user-data-backups"}}');var i=s(74848),n=s(28453);const o={},a="Best Practise: How to configure and use security groups",u={},c=[{value:"Identify the requirements of your setup",id:"identify-the-requirements-of-your-setup",level:2},{value:"Further security considerations",id:"further-security-considerations",level:3},{value:"How to create security groups",id:"how-to-create-security-groups",level:2},{value:"Default security group",id:"default-security-group",level:3},{value:"Recommended security groups",id:"recommended-security-groups",level:3},{value:"How to use security groups",id:"how-to-use-security-groups",level:2}];function l(e){const r={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,n.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(r.header,{children:(0,i.jsx)(r.h1,{id:"best-practise-how-to-configure-and-use-security-groups",children:"Best Practise: How to configure and use security groups"})}),"\n",(0,i.jsx)(r.p,{children:"Security groups in OpenStack are part of the network security mechanisms provided for the users.\nThey resemble sets of simple firewall rules allowing specific network traffic at a Port of a VM that connects it to a network.\nThe rules allow specific network port numbers and protocols while also differentiating between ingress and egress directions.\nUsually security groups are assigned to the Port(s) when a virtual machine is created, but assignments can also be changed at runtime later on.\nMultiple security groups can be assigned to a VM or Port simultaneously and in such case they will be combined as the union of all their rules."}),"\n",(0,i.jsx)(r.admonition,{type:"caution",children:(0,i.jsxs)(r.p,{children:["Security groups are mutable resources.\nTheir rules can be adjusted at any time after creation.\n",(0,i.jsx)(r.strong,{children:"Changing the rules of a security group will immediately apply the changes to all Ports or VMs it is assigned to."}),"\nIt is advisable to always review resources which use a security group before making changes to it."]})}),"\n",(0,i.jsx)(r.h2,{id:"identify-the-requirements-of-your-setup",children:"Identify the requirements of your setup"}),"\n",(0,i.jsx)(r.p,{children:"Every virtual machine that is created may need different firewall rules.\nThese requirements can also change over time.\nAdding or removing security groups will allow users to adapt the firewall rules specifically to their virtual machines."}),"\n",(0,i.jsx)(r.p,{children:"To harden the firewall settings for your virtual machine you may follow these steps:"}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsx)(r.li,{children:"Before creating a virtual machine its purpose is usually already known. Use this information to identify all incoming and outgoing traffic rules that will be needed based on the communication patterns of the services it is meant to deploy. This includes communication protocols, port numbers, communication directions and optionally target/source address ranges."}),"\n",(0,i.jsx)(r.li,{children:"Look through already existing security groups and their rules. If a security group allows more traffic than needed it SHOULD NOT be used. If a security group contains only a subset of the required rules it MAY be used in combination with other security groups that contain rules which fulfill the remaining required traffic rules from point 1."}),"\n",(0,i.jsx)(r.li,{children:"If you were not successful in finding an appropriate combination of existing security groups or you need additional specific rules to cover all requirements, you MAY create one or more new Security Groups in which you can add the required rules."}),"\n",(0,i.jsx)(r.li,{children:"After ensuring the existence of one or more security groups that fulfill your requirements, you can create the VM with those security groups already specified in the creation command."}),"\n"]}),"\n",(0,i.jsx)(r.h3,{id:"further-security-considerations",children:"Further security considerations"}),"\n",(0,i.jsx)(r.p,{children:"When implementing network security requirements, firewall rules alone are not always sufficient and might need to be augmented with additional configuration or time-based constraints. Notable examples are:"}),"\n",(0,i.jsxs)(r.p,{children:[(0,i.jsx)(r.strong,{children:"SSH"}),"\nSSH is needed on many virtual machines to operate their guest operating system.\nIn a security group the port 22 can be opened for the TCP protocol to allow incoming SSH connections.\nBut that only should be done while also restricting the SSH configuration to public key authentication only (the recommended way) or having a strong username and password policy already applied to the operating system of the virtual machine.\nOtherwise default usernames and passwords which are often preconfigured in system images may be exploited through the exposed SSH port which enables attackers to compromise the virtual machine."]}),"\n",(0,i.jsxs)(r.p,{children:[(0,i.jsx)(r.strong,{children:"ICMP"}),"\nIt might be useful to be able to ping a virtual machine or use other ICMP requests.\nBut for some virtual machine configurations this is either not necessary at all or only temporarily needed.\nOne benefit of security groups among other things is the ability to be easily added to and removed from existing virtual machines.\nSo a dedicated security group allowing ICMP could be added temporarily to a virtual machine for debugging purposes and removed from it afterwards."]}),"\n",(0,i.jsx)(r.h2,{id:"how-to-create-security-groups",children:"How to create security groups"}),"\n",(0,i.jsx)(r.p,{children:"Security groups are managed within a project.\nSo every project will have a different set of security groups.\nThey can be added dynamically to each virtual machine, during their creation or afterwards.\nAdditionally, they may also be removed from VMs at any point."}),"\n",(0,i.jsx)(r.p,{children:"Every project has its own default security group, which rules can be edited.\nAdditionally other security groups can be added until the project's quota is exhausted.\nTo add a security group, use the following command:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group create $SECURITY_GROUP\n"})}),"\n",(0,i.jsx)(r.p,{children:"Within every security group rules can be added up unto a defined maximum of rules, that usually is about 100.\nRules can be added to security groups with the following command:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group rule create [...] $SECURITY_GROUP\n"})}),"\n",(0,i.jsx)(r.p,{children:"To delete rules from a security group, the rule id has to be used.\nIt is listed in the details of the rules section of the security group."}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group rule delete $RULE_ID\n"})}),"\n",(0,i.jsx)(r.h3,{id:"default-security-group",children:"Default security group"}),"\n",(0,i.jsx)(r.p,{children:"Unless specified otherwise, the default security group is assigned to all VMs or Ports at creation.\nTo use any other than the default security group at creation it is necessary to specify the desired security group(s) during the creation process."}),"\n",(0,i.jsx)(r.p,{children:"To review which rules are defined in a security group, the following command can be used:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group show default\n"})}),"\n",(0,i.jsx)(r.h3,{id:"recommended-security-groups",children:"Recommended security groups"}),"\n",(0,i.jsx)(r.p,{children:"While projects can use very different aspects in security group rules and thus the security groups will always differ between projects, there are some security groups that are widely used.\nThrough the nature of security groups being seen as a set of rules that can be combined, having some basic security groups that allow basic protocols is a commonly used setup.\nThis section will demonstrate how to create some security groups for commonly used protocols and ports."}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsx)(r.li,{children:"A security groups, that allows incoming SSH traffic:"}),"\n"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group create ssh\nopenstack security group rule create --ingress --protocol tcp --dst-port 22 ssh\n"})}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsx)(r.li,{children:"A security group, that allows incoming HTTP requests:"}),"\n"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group create http\nopenstack security group rule create --ingress --protocol tcp --dst-port 80 http\n"})}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsx)(r.li,{children:"A security group, that allows incoming HTTPS requests:"}),"\n"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group create https\nopenstack security group rule create --ingress --protocol tcp --dst-port 443 https\n"})}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsx)(r.li,{children:"A security group, that allows incoming ICMP requests:"}),"\n"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group create icmp\nopenstack security group rule create --protocol icmp icmp\n"})}),"\n",(0,i.jsx)(r.h2,{id:"how-to-use-security-groups",children:"How to use security groups"}),"\n",(0,i.jsx)(r.admonition,{type:"info",children:(0,i.jsx)(r.p,{children:"Security groups can be assigned to multiple resources simultaneously (such as VMs or Ports).\nThis means that security groups are reusable and don't need to be recreated for each applicable resource individually."})}),"\n",(0,i.jsxs)(r.p,{children:["Usually, initial security groups are added at the time of the creation of a VM.\nDuring creation, multiple security groups can also be added at the same time by repeating the ",(0,i.jsx)(r.code,{children:"--security-group"})," argument:"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack server create [...] --security-group $SECURITY_GROUP_1 --security-group $SECURITY_GROUP_2 $SERVER_NAME\n"})}),"\n",(0,i.jsx)(r.p,{children:"To add a security group to an existing VM, the following command can be used:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack server add security group $SERVER_NAME $SECURITY_GROUP\n"})}),"\n",(0,i.jsx)(r.p,{children:"To remove a security group from a VM, the following command can be used:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack server remove security group $SERVER_NAME $SECURITY_GROUP\n"})})]})}function d(e={}){const{wrapper:r}={...(0,n.R)(),...e.components};return r?(0,i.jsx)(r,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,r,s)=>{s.d(r,{R:()=>o,x:()=>a});var t=s(96540);const i={},n=t.createContext(i);function o(e){const r=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(n.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7e7cf0e4.d71bb551.js b/assets/js/7e7cf0e4.d71bb551.js new file mode 100644 index 0000000000..a8e5943071 --- /dev/null +++ b/assets/js/7e7cf0e4.d71bb551.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[74612],{79976:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>d,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"global/scs-0003","title":"scs-0003: Sovereign Cloud Standards YAML","description":"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,","source":"@site/standards/global/scs-0003.md","sourceDirName":"global","slug":"/global/scs-0003","permalink":"/standards/global/scs-0003","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V2","permalink":"/standards/scs-0002-v2-standards-docs-org"},"next":{"title":"V1","permalink":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml"}}');var r=t(74848),a=t(28453);const d={},o="scs-0003: Sovereign Cloud Standards YAML",i={},c=[];function l(e){const s={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"scs-0003-sovereign-cloud-standards-yaml",children:"scs-0003: Sovereign Cloud Standards YAML"})}),"\n",(0,r.jsx)(s.p,{children:"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,\ncategorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning\nin a machine-readable YAML format for clarity, traceability, and tool integration."}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",children:"scs-0003-v1"})}),(0,r.jsx)(s.td,{children:"Procedural"}),(0,r.jsx)(s.td,{children:"Draft"}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>d,x:()=>o});var n=t(96540);const r={},a=n.createContext(r);function d(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7eea03ab.50b38516.js b/assets/js/7eea03ab.50b38516.js new file mode 100644 index 0000000000..fe78d82a89 --- /dev/null +++ b/assets/js/7eea03ab.50b38516.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[56699],{2571:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Operating SCS","slug":"/category/operating-scs","permalink":"/docs/category/operating-scs","sidebar":"docs","navigation":{"previous":{"title":"HA deployment","permalink":"/docs/container/components/container-registry/docs/ha-deployment"},"next":{"title":"Components","permalink":"/docs/category/components-2"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/7f1a31c3.0547f437.js b/assets/js/7f1a31c3.0547f437.js new file mode 100644 index 0000000000..a48e3cc341 --- /dev/null +++ b/assets/js/7f1a31c3.0547f437.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[39464],{90300:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"releases/Release2","title":"Release Notes for SCS Release 2","description":"(Release Date: 2022-03-23)","source":"@site/docs/06-releases/Release2.md","sourceDirName":"06-releases","slug":"/releases/Release2","permalink":"/docs/releases/Release2","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release2.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Release Notes for SCS Release 1","permalink":"/docs/releases/Release1"},"next":{"title":"Release Notes for SCS Release 3","permalink":"/docs/releases/Release3"}}');var i=s(74848),r=s(28453);const o={},a="Release Notes for SCS Release 2",l={},d=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"New Features (Highlights)",id:"new-features-highlights",level:2},{value:"Operator focused improvements",id:"operator-focused-improvements",level:3},{value:"SCS Developer focused improvements (testbed)",id:"scs-developer-focused-improvements-testbed",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Cluster Management",id:"cluster-management",level:3},{value:"OSISM",id:"osism",level:3},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Resolved Issues",id:"resolved-issues",level:2},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R2",id:"list-of-known-issues--restrictions-in-r2",level:2},{value:"Future directions (selected Highlights)",id:"future-directions-selected-highlights",level:2},{value:"Contributing",id:"contributing",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"release-notes-for-scs-release-2",children:"Release Notes for SCS Release 2"})}),"\n",(0,i.jsx)(n.p,{children:"(Release Date: 2022-03-23)"}),"\n",(0,i.jsx)(n.h2,{id:"scope",children:"Scope"}),"\n",(0,i.jsx)(n.p,{children:"Main goals for Release 2 (R2) were massive improvements in bare\nmetal deployment and our cluster management layer gaining the\nability to handle many clusters independently with a number\nof optional services."}),"\n",(0,i.jsx)(n.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["We support the latest ",(0,i.jsx)(n.a,{href:"https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.22.md",children:"Kubernetes 1.22"})," and\n",(0,i.jsx)(n.a,{href:"https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.23.md",children:"1.23"})," releases."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The Kubernetes Cluster API is now available in a stable v1beta1\n",(0,i.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api/releases",children:"release 1.0.x"}),"\nwith the corresponding ",(0,i.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api/releases",children:"cluster-api-provider-openstack 0.5.x"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["There are a number of new standard services available for the\n",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/",children:"k8s capi"}),"\nmanaged clusters, amongst which cert-manager and flux. The clusters\nhave better default settings for the nginx-ingress, anti-affinity\nfor the nodes and the ability to chose cilium over calico and\nto have stable multi-controller node setups on clouds without\nlow-latency local storage.\nPlease consult the\n",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/master/Release-Notes-R2.md",children:"k8s capi provider release notes"}),"\nfor more details."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://releases.openstack.org/xena/highlights.html",children:"OpenStack Xena release"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"We have also enabled SPICE support in addition to noVNC to\naccess the graphical console of VMs."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The base infrastructure is provided by\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/release/blob/main/notes/3.0.0/NOTES.md",children:"OSISM 3.0.0"}),"\nwhich in turn build on top of kolla and kolla-ansible."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"new-features-highlights",children:"New Features (Highlights)"}),"\n",(0,i.jsx)(n.h3,{id:"operator-focused-improvements",children:"Operator focused improvements"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"The Cluster Management Node is now well prepared to manage numerous\nclusters with independent settings and different feature sets by\ncreating default settings and then keeping track of various workload\nclusters in own directories. Documentation has been vastly improved."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"The Cluster Management node now gets its artifacts directly from\ngit, making incremental updates to it a lot easier, thus also\navoiding to disrupt workload clusters through redeployed management\nnodes to roll out updates."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Added dashboards for the operators:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Homer"}),"\n",(0,i.jsx)(n.li,{children:"Flower"}),"\n",(0,i.jsx)(n.li,{children:"Grafana dashboards"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Work is underway to supersede ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor",children:"openstack-health-monitor"}),"\nwith a solution that is using tempest and rally. The health-monitor\nhas received improvements though and is at this point still fully\nsupported and recommended -- it has surfaced a number of issues with\ntest clouds, especially failed metadata services."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"User federation has been prepared to be ready for Gaia-X federation integration"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Keystone can consume users from Keycloak via OpenID-Connect"}),"\n",(0,i.jsx)(n.li,{children:"Keycloak uses the highly-available Galera database cluster now"}),"\n",(0,i.jsx)(n.li,{children:"mod_oauth2 support for Keystone"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Vast improvements in the SCS Deployment automation"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Full automation of bare metal deployment with Bifrost and Ironic"}),"\n",(0,i.jsx)(n.li,{children:"Using NetBox as central source of truth for the complete setup"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"New services available (opt-in)"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"ClamAV, dnsdist, cgit, FRRouting, Nexus, Tang"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Traefik centrally routes the connections to Nexus, NetBox, phpMyAdmin, Homer, Flower, ARA, cgit"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"scs-developer-focused-improvements-testbed",children:"SCS Developer focused improvements (testbed)"}),"\n",(0,i.jsx)(n.p,{children:"We now have scripts that allow us to connect to the workload cluster node network\nfor debugging purposes."}),"\n",(0,i.jsx)(n.p,{children:"The configuration of the testbed was minimized and the deployment was made more production-oriented."}),"\n",(0,i.jsx)(n.p,{children:"Further noteworthy improvements to testbed:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"TLS is implemented throughout the services also in testbed"}),"\n",(0,i.jsx)(n.li,{children:"Virtual BMC in testbed"}),"\n",(0,i.jsxs)(n.li,{children:["Public DNS for testbed (",(0,i.jsx)(n.code,{children:"testbed.osism.xyz"}),")"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"We have a Zuul CI framework running and started migrating CI testing from github actions to\nusing our Zuul infrastructure."}),"\n",(0,i.jsx)(n.p,{children:"Renovate is being used to keep the pinned versions up-to-date and consistent across the\nmany repositories."}),"\n",(0,i.jsxs)(n.p,{children:["An overview over the used software versions is available from the\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/release",children:"OSISM release"})," repository as input\nfor a complete SBOM. This allows to e.g. investigate the contents of the\nused (v3.0.0) images."]}),"\n",(0,i.jsx)(n.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,i.jsx)(n.h3,{id:"cluster-management",children:"Cluster Management"}),"\n",(0,i.jsxs)(n.p,{children:["The names of a few settings have changed since R1 -- if you have diverged from the defaults,\nthis may require adjusting the ",(0,i.jsx)(n.code,{children:"environment.tfvars"})," or the ",(0,i.jsx)(n.code,{children:"clusterctl.yaml"})," files.\nSee ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/master/Release-Notes-R2.md#incompatible-changes",children:"k8s-cluster-api-provider Release Notes"}),"\nfor more details."]}),"\n",(0,i.jsx)(n.p,{children:"The updating approach has fundamentally changed:\nIf you were used to deploy fresh management nodes regularly to\nbenefit from the upstream improvements, this need has been vastly reduced now,\nallowing for long-living management nodes and workload clusters managed by them."}),"\n",(0,i.jsx)(n.h3,{id:"osism",children:"OSISM"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Playbook generic-configuration.yml was deprecated. From now on, please use the playbook of\nthe same name in the manager environment (manager-configuration.yml). All configuration\nparameters from environments/configuration.yml should be moved to environments/manager/configuration.yml."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"In kolla-ansible the haproxy role was renamed to loadbalancer. Accordingly, loadbalancer must now be\nused for the deployment of HAProxy."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"removals",children:"Removals"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"OpenStack Victoria images are no longer built and thus no longer kept updated"}),"\n",(0,i.jsx)(n.li,{children:"Support for Zabbix has been removed, Prometheus will be used as the only monitoring stack in the future"}),"\n",(0,i.jsx)(n.li,{children:"Heimdall as a service was removed, as an alternative Homer is now available"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,i.jsxs)(n.p,{children:["Deprecations happen according to our ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Release-Policies.md#deprecation",children:"deprecation policy"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Cockpit is deprecated in favor of Boundary by HashiCorp or Teleport"}),"\n",(0,i.jsx)(n.li,{children:"ceph-ansible is deprecated in preparation for cephadm"}),"\n",(0,i.jsx)(n.li,{children:"All osism- scripts on the manager are deprecated and will be replaced by the new OSISM CLI. The scripts will be removed in the next release"}),"\n",(0,i.jsx)(n.li,{children:"The following services are currently not used and are deprecated and scheduled for removal as of now: Falco, Jenkins, Rundeck, Lynis, Trivy"}),"\n",(0,i.jsx)(n.li,{children:"Heat will no longer be offered by default in the testbed in the future"}),"\n",(0,i.jsx)(n.li,{children:"The docker-compose CLI will be removed and replaced by the new compose plugin for Docker.\ndocker-compose is then no longer available and docker compose must be used instead"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["The Elasticsearch container included in OSISM testbed was exposed to the log4j\nissue -- new images were provided for addressing this. See the\n",(0,i.jsx)(n.a,{href:"https://scs.community/de/security/2021/12/13/advisory-log4j/",children:"security advisory"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"resolved-issues",children:"Resolved Issues"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"The nginx-ingress loadbalancer could run into name conflicts before.\nThe loadbalancer now uses a health monitor to avoid routing to the wrong\nnodes, which typically resulted in 10s delays when connecting to the service\nbehind the ingress controller."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"cAdvisor has now reduced number of Prometheus metrics and labels exported by\ndefault - this will ease the load on the system.\nThis implies that corresponding time series data will no longer be created."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,i.jsxs)(n.p,{children:["The clusters created with our cluster-API cluster management solution pass\nthe ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Image-Properties-Spec.md",children:"CNCF conformance tests"}),"\nas reported by ",(0,i.jsx)(n.a,{href:"https://sonobuoy.io/",children:"sonobuoy"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"https://openstack.org/",children:"OpenStack"})," layer passes the\n",(0,i.jsx)(n.a,{href:"https://openinfra.dev/",children:"OIF"})," trademark tests, so cloud providers\nleveraging the stack should easily be able to achieve the\n",(0,i.jsx)(n.a,{href:"https://www.openstack.org/brand/interop/",children:'"OpenStack powered compute"'}),"\ntrademark certification."]}),"\n",(0,i.jsxs)(n.p,{children:["Our partner plusserver has ",(0,i.jsx)(n.a,{href:"https://www.openstack.org/brand/interop/",children:"achieved"}),"\na ",(0,i.jsx)(n.a,{href:"https://www.bsi.bund.de/EN/Topics/CloudComputing/Compliance_Criteria_Catalogue/Compliance_Criteria_Catalogue_node.html",children:"BSI C5"}),"\nsecurity certification for their SCS implementation pluscloud open."]}),"\n",(0,i.jsxs)(n.p,{children:["We are working within ",(0,i.jsx)(n.a,{href:"https://gaia-x.eu/",children:"Gaia-X"})," to further the power\nof Gaia-X self-descriptions and are closely working with the\n",(0,i.jsx)(n.a,{href:"https://gxfs.de/",children:"GXFS project"}),"\nto jointly deliver a standard toolbox for Gaia-X compliant\ninfrastructure and service offerings."]}),"\n",(0,i.jsxs)(n.p,{children:["The SCS standards for ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/flavor-naming.md",children:"flavor naming"})," and\n",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Image-Properties-Spec.md",children:"image metadata"}),"\nare largely unchanged since R1. We have however\nmade progress in our reference implementation fully implementing\nthem without any further tweaks."]}),"\n",(0,i.jsx)(n.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,i.jsxs)(n.p,{children:["See ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Release-Numbering-Scheme.md",children:"Release Numbering scheme"})," -- unchanged from R0.\nWe have added the tag ",(0,i.jsx)(n.code,{children:"v3.0.0"})," to the relevant repositories to designate the ",(0,i.jsx)(n.code,{children:"SCS_RELEASE_R2"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Note that we will release R3 (v4.0.0) in September 2022 and stop providing maintenance\nupdates for R2 at the end of October."}),"\n",(0,i.jsx)(n.h2,{id:"list-of-known-issues--restrictions-in-r2",children:"List of known issues & restrictions in R2"}),"\n",(0,i.jsx)(n.h2,{id:"future-directions-selected-highlights",children:"Future directions (selected Highlights)"}),"\n",(0,i.jsxs)(n.p,{children:["Alongside with R2 we published a blog post on some first thoughts on\n",(0,i.jsx)(n.a,{href:"https://scs.community/tech/2022/03/23/r2-and-future-directions/",children:"future directions towards R3"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(n.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,i.jsx)(n.a,{href:"https://scs.community/docs/contributor/",children:"contributor guide"}),".\nWe also have worked on a ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/pull/26",children:"Code of Conduct"}),"\nto document the expected behavior of contributors and how we deal with\ncases where individuals fail to meet the expectation."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const i={},r=t.createContext(i);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7f57b062.c96590ca.js b/assets/js/7f57b062.c96590ca.js new file mode 100644 index 0000000000..41d0a53585 --- /dev/null +++ b/assets/js/7f57b062.c96590ca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[35894],{36528:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>l,default:()=>d,frontMatter:()=>c,metadata:()=>t,toc:()=>o});const t=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","title":"Quickstart","description":"This quickstart guide contains steps to install the Cluster Stack Operator (CSO) utilizing the Cluster Stack Provider OpenStack (CSPO) to provide ClusterClasses which can be used with the Kubernetes Cluster API to create Kubernetes Clusters.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stacks/providers/openstack","slug":"/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","permalink":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Developing and Testing csctl","permalink":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl"},"next":{"title":"Configuration","permalink":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration"}}');var r=n(74848),a=n(28453);const c={},l="Quickstart",i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Initialize the management cluster",id:"initialize-the-management-cluster",level:2},{value:"CSO and CSPO variables preparation (CSP)",id:"cso-and-cspo-variables-preparation-csp",level:3},{value:"CSO and CSPO deployment (CSP)",id:"cso-and-cspo-deployment-csp",level:3},{value:"Define a namespace for a tenant (CSP/per tenant)",id:"define-a-namespace-for-a-tenant-cspper-tenant",level:2},{value:"Deploy CSP-helper chart",id:"deploy-csp-helper-chart",level:3},{value:"Create Cluster Stack definition (CSP/per tenant)",id:"create-cluster-stack-definition-cspper-tenant",level:2},{value:"Create the workload cluster resource (SCS-User/customer)",id:"create-the-workload-cluster-resource-scs-usercustomer",level:2},{value:"Check the workload cluster health",id:"check-the-workload-cluster-health",level:2}];function u(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,r.jsxs)(s.p,{children:["This quickstart guide contains steps to install the ",(0,r.jsx)(s.a,{href:"https://github.com/sovereignCloudStack/cluster-stack-operator/",children:"Cluster Stack Operator"})," (CSO) utilizing the ",(0,r.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks/tree/main/providers/openstack",children:"Cluster Stack Provider OpenStack"})," (CSPO) to provide ",(0,r.jsx)(s.a,{href:"https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20210526-cluster-class-and-managed-topologies.md",children:"ClusterClasses"})," which can be used with the ",(0,r.jsx)(s.a,{href:"https://cluster-api.sigs.k8s.io/",children:"Kubernetes Cluster API"})," to create Kubernetes Clusters."]}),"\n",(0,r.jsxs)(s.p,{children:["This section guides you through all the necessary steps to create a workload Kubernetes cluster on top of the OpenStack infrastructure. The guide describes a path that utilizes the ",(0,r.jsx)(s.code,{children:"clusterctl"})," CLI tool to manage the lifecycle of a CAPI management cluster and employs ",(0,r.jsx)(s.code,{children:"kind"})," to create a local non-production managemnt cluster."]}),"\n",(0,r.jsxs)(s.p,{children:["Note that it is a common practice to create a temporary, local ",(0,r.jsx)(s.a,{href:"https://cluster-api.sigs.k8s.io/reference/glossary#bootstrap-cluster",children:"bootstrap cluster"})," which is then used to provision a target ",(0,r.jsx)(s.a,{href:"https://cluster-api.sigs.k8s.io/reference/glossary#management-cluster",children:"management cluster"})," on the selected infrastructure."]}),"\n",(0,r.jsx)(s.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Install ",(0,r.jsx)(s.a,{href:"https://docs.docker.com/get-docker/",children:"Docker"})," and ",(0,r.jsx)(s.a,{href:"https://helm.sh/docs/intro/install/",children:"kind"})]}),"\n",(0,r.jsxs)(s.li,{children:["Install ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/tools/install-kubectl/",children:"kubectl"})]}),"\n",(0,r.jsxs)(s.li,{children:["Install ",(0,r.jsx)(s.a,{href:"https://helm.sh/docs/intro/install/",children:"Helm"})]}),"\n",(0,r.jsxs)(s.li,{children:["Install ",(0,r.jsx)(s.a,{href:"https://cluster-api.sigs.k8s.io/user/quick-start.html#install-clusterctl",children:"clusterctl"})]}),"\n",(0,r.jsxs)(s.li,{children:["Install ",(0,r.jsx)(s.a,{href:"https://go.dev/doc/install",children:"go"})]}),"\n",(0,r.jsxs)(s.li,{children:["Install ",(0,r.jsx)(s.a,{href:"https://jqlang.github.io/jq/",children:"jq"})]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"initialize-the-management-cluster",children:"Initialize the management cluster"}),"\n",(0,r.jsx)(s.p,{children:"Create the kind cluster:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"kind create cluster\n"})}),"\n",(0,r.jsxs)(s.p,{children:["Transform the Kubernetes cluster into a management cluster by using ",(0,r.jsx)(s.code,{children:"clusterctl init"})," and bootstrap it with CAPI and Cluster API Provider OpenStack (",(0,r.jsx)(s.a,{href:"https://github.com/kubernetes-sigs/cluster-api-provider-openstack",children:"CAPO"}),") components:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"export CLUSTER_TOPOLOGY=true\nexport EXP_CLUSTER_RESOURCE_SET=true\nexport EXP_RUNTIME_SDK=true\nclusterctl init --infrastructure openstack\n"})}),"\n",(0,r.jsx)(s.h3,{id:"cso-and-cspo-variables-preparation-csp",children:"CSO and CSPO variables preparation (CSP)"}),"\n",(0,r.jsx)(s.p,{children:"The CSO and CSPO must be directed to the Cluster Stacks repository housing releases for the OpenStack provider.\nModify and export the following environment variables if you wish to redirect CSO and CSPO to an alternative Git repository"}),"\n",(0,r.jsxs)(s.p,{children:["Be aware that GitHub enforces limitations on the number of API requests per unit of time. To overcome this,\nit is recommended to configure a ",(0,r.jsx)(s.a,{href:"https://github.com/settings/personal-access-tokens/new",children:"personal access token"})," for authenticated calls. This will significantly increase the rate limit for GitHub API requests.\nFine grained PAT with ",(0,r.jsx)(s.code,{children:"Public Repositories (read-only)"})," is enough."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"export GIT_PROVIDER_B64=Z2l0aHVi # github\nexport GIT_ORG_NAME_B64=U292ZXJlaWduQ2xvdWRTdGFjaw== # SovereignCloudStack\nexport GIT_REPOSITORY_NAME_B64=Y2x1c3Rlci1zdGFja3M= # cluster-stacks\nexport GIT_ACCESS_TOKEN_B64=$(echo -n '<my-personal-access-token>' | base64 -w0)\n"})}),"\n",(0,r.jsx)(s.h3,{id:"cso-and-cspo-deployment-csp",children:"CSO and CSPO deployment (CSP)"}),"\n",(0,r.jsxs)(s.p,{children:["Install the ",(0,r.jsx)(s.a,{href:"https://github.com/drone/envsubst",children:"envsubst"})," Go package. It is required to enable the expansion of variables specified in CSPO and CSO manifests."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"GOBIN=/tmp go install github.com/drone/envsubst/v2/cmd/envsubst@latest\n"})}),"\n",(0,r.jsx)(s.p,{children:"Get the latest CSO release version and apply CSO manifests to the management cluster."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"# Get the latest CSO release version and apply CSO manifests\ncurl -sSL https://github.com/SovereignCloudStack/cluster-stack-operator/releases/latest/download/cso-infrastructure-components.yaml | /tmp/envsubst | kubectl apply -f -\n"})}),"\n",(0,r.jsx)(s.p,{children:"Get the latest CSPO release version and apply CSPO manifests to the management cluster."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"# Get the latest CSPO release version and apply CSPO manifests\ncurl -sSL https://github.com/sovereignCloudStack/cluster-stack-provider-openstack/releases/latest/download/cspo-infrastructure-components.yaml | /tmp/envsubst | kubectl apply -f -\n"})}),"\n",(0,r.jsx)(s.h2,{id:"define-a-namespace-for-a-tenant-cspper-tenant",children:"Define a namespace for a tenant (CSP/per tenant)"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-sh",children:"export CS_NAMESPACE=my-tenant\n"})}),"\n",(0,r.jsx)(s.h3,{id:"deploy-csp-helper-chart",children:"Deploy CSP-helper chart"}),"\n",(0,r.jsx)(s.p,{children:"The csp-helper chart is meant to create per tenant credentials as well as the tenants namespace where all resources for this tenant will live in."}),"\n",(0,r.jsxs)(s.p,{children:["Cloud and secret name default to ",(0,r.jsx)(s.code,{children:"openstack"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["Example ",(0,r.jsx)(s.code,{children:"clouds.yaml"})]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:'clouds:\n openstack:\n auth:\n auth_url: https://api.gx-scs.sovereignit.cloud:5000/v3\n application_credential_id: ""\n application_credential_secret: ""\n region_name: "RegionOne"\n interface: "public"\n identity_api_version: 3\n auth_type: "v3applicationcredential"\n'})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'helm upgrade -i csp-helper-"${CS_NAMESPACE}" -n "${CS_NAMESPACE}" --create-namespace https://github.com/SovereignCloudStack/openstack-csp-helper/releases/latest/download/openstack-csp-helper.tgz -f path/to/clouds.yaml\n'})}),"\n",(0,r.jsx)(s.h2,{id:"create-cluster-stack-definition-cspper-tenant",children:"Create Cluster Stack definition (CSP/per tenant)"}),"\n",(0,r.jsx)(s.p,{children:"Configure the Cluster Stack you want to use:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-sh",children:'# the name of the cluster stack (must match a name of a directory in https://github.com/SovereignCloudStack/cluster-stacks/tree/main/providers/openstack)\nexport CS_NAME=scs\n\n# the kubernetes version of the cluster stack (must match a tag for the kubernetes version and the stack version)\nexport CS_K8S_VERSION=1.29\n\n# the version of the cluster stack (must match a tag for the kubernetes version and the stack version)\nexport CS_VERSION=v1\nexport CS_CHANNEL=stable\n\n# must match a cloud section name in the used clouds.yaml\nexport CS_CLOUDNAME=openstack\nexport CS_SECRETNAME="${CS_CLOUDNAME}"\n'})}),"\n",(0,r.jsxs)(s.p,{children:["This will use the cluster-stack as defined in the ",(0,r.jsx)(s.code,{children:"providers/openstack/scs"})," directory."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'cat >clusterstack.yaml <<EOF\napiVersion: clusterstack.x-k8s.io/v1alpha1\nkind: ClusterStack\nmetadata:\n name: clusterstack\n namespace: ${CS_NAMESPACE}\nspec:\n provider: openstack\n name: ${CS_NAME}\n kubernetesVersion: "${CS_K8S_VERSION}"\n channel: ${CS_CHANNEL}\n autoSubscribe: false\n providerRef:\n apiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1\n kind: OpenStackClusterStackReleaseTemplate\n name: cspotemplate\n versions:\n - ${CS_VERSION}\n---\napiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1\nkind: OpenStackClusterStackReleaseTemplate\nmetadata:\n name: cspotemplate\n namespace: ${CS_NAMESPACE}\nspec:\n template:\n spec:\n identityRef:\n kind: Secret\n name: ${CS_SECRETNAME}\nEOF\n\nkubectl apply -f clusterstack.yaml\n'})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"clusterstack.clusterstack.x-k8s.io/clusterstack created\nopenstackclusterstackreleasetemplate.infrastructure.clusterstack.x-k8s.io/cspotemplate created\n"})}),"\n",(0,r.jsx)(s.h2,{id:"create-the-workload-cluster-resource-scs-usercustomer",children:"Create the workload cluster resource (SCS-User/customer)"}),"\n",(0,r.jsx)(s.p,{children:"To create a workload cluster you must configure the following things:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'export CS_CLUSTER_NAME=cs-cluster\n# Note: if you need more than one POD_CIDR, please adjust the yaml file accordingly\nexport CS_POD_CIDR=192.168.0.0/16\n# Note: if you need more than one SERVICE_CIDR, please adjust the yaml file accordingly\nexport CS_SERVICE_CIDR=10.96.0.0/12\nexport CS_EXTERNAL_ID=ebfe5546-f09f-4f42-ab54-094e457d42ec # gx-scs\nexport CS_CLASS_NAME=openstack-"${CS_NAME}"-"${CS_K8S_VERSION/./-}"-"${CS_VERSION}"\nexport CS_K8S_PATCH_VERSION=6\n'})}),"\n",(0,r.jsxs)(s.p,{children:["Create and apply ",(0,r.jsx)(s.code,{children:"cluster.yaml"})," file to the management cluster."]}),"\n",(0,r.jsxs)(s.p,{children:["Depending on your cluster-class and cluster addons, some more variables may have to be provided in the ",(0,r.jsx)(s.code,{children:"spec.topology.variables"})," list.\nAn error message after applying the ",(0,r.jsx)(s.code,{children:"Cluster"})," resource will tell you if more variables are necessary."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'cat > cluster.yaml <<EOF\napiVersion: cluster.x-k8s.io/v1beta1\nkind: Cluster\nmetadata:\n name: ${CS_CLUSTER_NAME}\n namespace: ${CS_NAMESPACE}\n labels:\n managed-secret: cloud-config\nspec:\n clusterNetwork:\n pods:\n cidrBlocks:\n - ${CS_POD_CIDR}\n serviceDomain: cluster.local\n services:\n cidrBlocks:\n - ${CS_SERVICE_CIDR}\n topology:\n variables:\n - name: controller_flavor\n value: "SCS-2V-4-50"\n - name: worker_flavor\n value: "SCS-2V-4-50"\n - name: external_id\n value: ${CS_EXTERNAL_ID}\n class: ${CS_CLASS_NAME}\n controlPlane:\n replicas: 1\n version: v${CS_K8S_VERSION}.${CS_K8S_PATCH_VERSION}\n workers:\n machineDeployments:\n - class: default-worker\n failureDomain: nova\n name: default-worker\n replicas: 3\nEOF\n\nkubectl apply -f cluster.yaml\n'})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"cluster.cluster.x-k8s.io/cs-cluster created\n"})}),"\n",(0,r.jsxs)(s.p,{children:["Utilize a convenient CLI ",(0,r.jsx)(s.code,{children:"clusterctl"})," to investigate the health of the cluster:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"clusterctl -n ${CS_NAMESPACE} describe cluster ${CS_CLUSTER_NAME}\n"})}),"\n",(0,r.jsx)(s.p,{children:"Once the cluster is provisioned and in good health, you can retrieve its kubeconfig and establish communication with the newly created workload cluster:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'# Get the workload cluster kubeconfig\nclusterctl -n "${CS_NAMESPACE}" get kubeconfig ${CS_CLUSTER_NAME} > kubeconfig.yaml\n# Communicate with the workload cluster\nkubectl --kubeconfig kubeconfig.yaml get nodes\n'})}),"\n",(0,r.jsx)(s.h2,{id:"check-the-workload-cluster-health",children:"Check the workload cluster health"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"$ kubectl --kubeconfig kubeconfig.yaml get pods -A\nNAMESPACE NAME READY STATUS RESTARTS AGE\nkube-system cilium-8mzrx 1/1 Running 0 7m58s\nkube-system cilium-jdxqm 1/1 Running 0 6m43s\nkube-system cilium-operator-6bb4c7d6b6-c77tn 1/1 Running 0 7m57s\nkube-system cilium-operator-6bb4c7d6b6-l2df8 1/1 Running 0 7m58s\nkube-system cilium-p9tkv 1/1 Running 0 6m44s\nkube-system cilium-thbc8 1/1 Running 0 6m45s\nkube-system coredns-5dd5756b68-k68j4 1/1 Running 0 8m3s\nkube-system coredns-5dd5756b68-vjg9r 1/1 Running 0 8m3s\nkube-system etcd-cs-cluster-pwblg-xkptx 1/1 Running 0 8m3s\nkube-system kube-apiserver-cs-cluster-pwblg-xkptx 1/1 Running 0 8m3s\nkube-system kube-controller-manager-cs-cluster-pwblg-xkptx 1/1 Running 0 8m3s\nkube-system kube-proxy-54f8w 1/1 Running 0 6m44s\nkube-system kube-proxy-8z8kb 1/1 Running 0 6m43s\nkube-system kube-proxy-jht46 1/1 Running 0 8m3s\nkube-system kube-proxy-mt69p 1/1 Running 0 6m45s\nkube-system kube-scheduler-cs-cluster-pwblg-xkptx 1/1 Running 0 8m3s\nkube-system metrics-server-6578bd6756-vztzf 1/1 Running 0 7m57s\nkube-system openstack-cinder-csi-controllerplugin-776696786b-ksf77 6/6 Running 0 7m57s\nkube-system openstack-cinder-csi-nodeplugin-96dlg 3/3 Running 0 6m43s\nkube-system openstack-cinder-csi-nodeplugin-crhc4 3/3 Running 0 6m44s\nkube-system openstack-cinder-csi-nodeplugin-d7rzz 3/3 Running 0 7m58s\nkube-system openstack-cinder-csi-nodeplugin-nkgq6 3/3 Running 0 6m44s\nkube-system openstack-cloud-controller-manager-hp2n2 1/1 Running 0 7m9s\n"})})]})}function d(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>c,x:()=>l});var t=n(96540);const r={},a=t.createContext(r);function c(e){const s=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7fd33963.7807ee19.js b/assets/js/7fd33963.7807ee19.js new file mode 100644 index 0000000000..6cf7ff86db --- /dev/null +++ b/assets/js/7fd33963.7807ee19.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[78526],{61954:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>d,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>o});const r=JSON.parse('{"id":"kaas/scs-0216","title":"scs-0216: Requirements for testing cluster-stacks","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/kaas/scs-0216.md","sourceDirName":"kaas","slug":"/kaas/scs-0216","permalink":"/standards/kaas/scs-0216","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0215-v1-robustness-features"},"next":{"title":"V1","permalink":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks"}}');var n=t(74848),c=t(28453);const a={},d="scs-0216: Requirements for testing cluster-stacks",i={},o=[];function l(e){const s={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"scs-0216-requirements-for-testing-cluster-stacks",children:"scs-0216: Requirements for testing cluster-stacks"})}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Version"}),(0,n.jsx)(s.th,{children:"Type"}),(0,n.jsx)(s.th,{children:"State"}),(0,n.jsx)(s.th,{children:"stabilized"}),(0,n.jsx)(s.th,{children:"deprecated"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks",children:"scs-0216-v1"})}),(0,n.jsx)(s.td,{children:"Decision Record"}),(0,n.jsx)(s.td,{children:"Draft"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>a,x:()=>d});var r=t(96540);const n={},c=r.createContext(n);function a(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7fedb4ba.5431b26b.js b/assets/js/7fedb4ba.5431b26b.js new file mode 100644 index 0000000000..8cb96c4d9d --- /dev/null +++ b/assets/js/7fedb4ba.5431b26b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[42686],{47281:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"API","slug":"/category/api","permalink":"/docs/category/api","sidebar":"docs","navigation":{"previous":{"title":"Component Overview","permalink":"/docs/operating-scs/components/status-page-openapi/docs/component_overview"},"next":{"title":"Overview","permalink":"/docs/operating-scs/components/status-page-api/docs/overview"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/8092c627.8dbfdb0c.js b/assets/js/8092c627.8dbfdb0c.js new file mode 100644 index 0000000000..8c76e7688e --- /dev/null +++ b/assets/js/8092c627.8dbfdb0c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4880],{52766:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"iaas/guides/user-guide/user-data-backups","title":"User Data Backups","description":"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.","source":"@site/docs/02-iaas/guides/user-guide/user-data-backups.md","sourceDirName":"02-iaas/guides/user-guide","slug":"/iaas/guides/user-guide/user-data-backups","permalink":"/docs/iaas/guides/user-guide/user-data-backups","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/user-data-backups.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Best Practise: How to configure and use security groups","permalink":"/docs/iaas/guides/user-guide/security-groups/"},"next":{"title":"Other Guides","permalink":"/docs/iaas/guides/other-guides/"}}');var t=a(74848),s=a(28453);const r={},c="User Data Backups",o={},l=[{value:"Glossary",id:"glossary",level:2},{value:"Scope",id:"scope",level:2},{value:"Overview of applicable User Data",id:"overview-of-applicable-user-data",level:3},{value:"Image backup using download",id:"image-backup-using-download",level:2},{value:"Ephemeral Storage backup using Glance images",id:"ephemeral-storage-backup-using-glance-images",level:2},{value:"Volume data backup using Cinder Backup API",id:"volume-data-backup-using-cinder-backup-api",level:2},{value:"Backup of detached volumes",id:"backup-of-detached-volumes",level:3},{value:"Backup of attached volumes",id:"backup-of-attached-volumes",level:3},{value:"Volume data backup using Glance images",id:"volume-data-backup-using-glance-images",level:2},{value:"Glance image backups of detached volumes",id:"glance-image-backups-of-detached-volumes",level:3},{value:"Glance image backups of attached (in-use) volumes",id:"glance-image-backups-of-attached-in-use-volumes",level:3},{value:"Barbican secrets backup using download",id:"barbican-secrets-backup-using-download",level:2},{value:"Retrieving encryption keys from Barbican",id:"retrieving-encryption-keys-from-barbican",level:3},{value:"Restore",id:"restore",level:2},{value:"Restoring a backup of a Barbican secret",id:"restoring-a-backup-of-a-barbican-secret",level:3},{value:"Restoring a backup of an unencrypted image",id:"restoring-a-backup-of-an-unencrypted-image",level:3},{value:"Restoring a backup of an encrypted image",id:"restoring-a-backup-of-an-encrypted-image",level:3},{value:"Restoring a volume backup from an image",id:"restoring-a-volume-backup-from-an-image",level:3},{value:"Restoring a volume backup from the Cinder Backup service",id:"restoring-a-volume-backup-from-the-cinder-backup-service",level:3},{value:"Restoring to a new volume (Cinder Backup)",id:"restoring-to-a-new-volume-cinder-backup",level:4},{value:"Restoring on an existing volume (Cinder Backup)",id:"restoring-on-an-existing-volume-cinder-backup",level:4},{value:"Restoring an encrypted volume backup (Cinder Backup)",id:"restoring-an-encrypted-volume-backup-cinder-backup",level:4},{value:"Appendix",id:"appendix",level:2},{value:"Image creation action for servers with attached volumes",id:"image-creation-action-for-servers-with-attached-volumes",level:3},{value:"LUKS encryption key conversion to decrypt volume images",id:"luks-encryption-key-conversion-to-decrypt-volume-images",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"user-data-backups",children:"User Data Backups"})}),"\n",(0,t.jsx)(n.p,{children:"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks."}),"\n",(0,t.jsx)(n.h2,{id:"glossary",children:"Glossary"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Term"}),(0,t.jsx)(n.th,{children:"Explanation"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Virtual Machine"}),(0,t.jsxs)(n.td,{children:["Equals the ",(0,t.jsx)(n.code,{children:"server"})," resource in Nova."]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Ephemeral Storage"}),(0,t.jsx)(n.td,{children:"Disk storage directly supplied to a virtual machine by Nova. Different from volumes."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"(Glance) Image"}),(0,t.jsx)(n.td,{children:"IaaS resource usually storing raw disk data. Managed by the Glance service."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"(Cinder) Volume"}),(0,t.jsx)(n.td,{children:"IaaS resource representing block storage disk that can be attached as a virtual disk to virtual machines. Managed by the Cinder service."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"(Volume) Snapshot"}),(0,t.jsx)(n.td,{children:"Thinly-provisioned copy-on-write snapshots of volumes. Stored in the same Cinder storage backend as volumes."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Volume Type"}),(0,t.jsx)(n.td,{children:"Attribute of volumes determining storage details of a volume such as backend location or whether the volume will be encrypted."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"(Barbican) Secret"}),(0,t.jsx)(n.td,{children:"IaaS resource storing cryptographic assets such as encryption keys. Managed by the Barbican service."})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"scope",children:"Scope"}),"\n",(0,t.jsx)(n.p,{children:"User data in the context of this guide describes data accumulated in cloud resources of a user at runtime.\nThis concerns primarily storage data of virtual machines stored at at-rest.\nThis does not cover in-transit or in-use data such as network traffic, virtual machines' RAM contents or IaaS configuration and metadata of cloud resources."}),"\n",(0,t.jsx)(n.h3,{id:"overview-of-applicable-user-data",children:"Overview of applicable User Data"}),"\n",(0,t.jsx)(n.p,{children:"Given the mentioned scope, the following can be classified as user data:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"images stored in Glance"}),"\n",(0,t.jsxs)(n.li,{children:["virtual machine disks, either:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Ephemeral Storage stored in Nova"}),"\n",(0,t.jsx)(n.li,{children:"volumes stored in Cinder"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:"encryption keys stored as secrets in Barbican"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The following sections will describe backup procedures for each of those resources individually."}),"\n",(0,t.jsx)(n.h2,{id:"image-backup-using-download",children:"Image backup using download"}),"\n",(0,t.jsx)(n.p,{children:"Glance images may act as backup targets for other resources (such as volumes) but don't have a dedicated backup service for themselves."}),"\n",(0,t.jsx)(n.p,{children:"When an image is to be backed up, it can be downloaded from the Glance image service and stored outside of the IaaS infrastructure for backup purposes.\nIn this case it is the user's responsibility to establish the backup procedure and appropriate target storage."}),"\n",(0,t.jsxs)(n.admonition,{type:"caution",children:[(0,t.jsx)(n.p,{children:"When creating images from volumes with a volume type that uses encryption, the resulting image will contain the raw LUKS-encrypted blocks of the volume.\nWhen transferred outside of the IaaS infrastructure, this data is only useful as a backup together with the corresponding encryption key."}),(0,t.jsxs)(n.p,{children:["Such images can be identified by an attribute called ",(0,t.jsx)(n.code,{children:"cinder_encryption_key_id"})," in the ",(0,t.jsx)(n.code,{children:"properties"})," metadata field of the image.\nIt only exists for encrypted images and references the encryption key in Barbican.\nRefer to the ",(0,t.jsx)(n.a,{href:"#barbican-secrets-backup-using-download",children:"Barbican secrets section"})," for instructions on how to backup the key."]})]}),"\n",(0,t.jsx)(n.p,{children:"The API or the OpenStack client may be used to initiate the download, for example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack image save --file $TARGET_FILE_PATH $IMAGE_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.p,{children:"This or the underlying API request may be automated as part of a regular backup schedule involving the backup storage target on the user side."}),"\n",(0,t.jsx)(n.h2,{id:"ephemeral-storage-backup-using-glance-images",children:"Ephemeral Storage backup using Glance images"}),"\n",(0,t.jsxs)(n.admonition,{type:"caution",children:[(0,t.jsxs)(n.p,{children:["When using the ",(0,t.jsx)(n.code,{children:"createImage"})," Compute API action (e.g. via the ",(0,t.jsx)(n.code,{children:"openstack server image create"})," command) on a virtual machine that has volumes attached to it in addition to its Ephemeral Storage disk, the volumes will not be backed up into the image. Instead, a snapshot will be created for each attached volume and referenced in the image metadata. This does not replace genuine volume backups."]}),(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"#image-creation-action-for-servers-with-attached-volumes",children:"corresponding appendix section"})," for further details."]})]}),"\n",(0,t.jsxs)(n.p,{children:["Ephemeral Storage disks of virtual machines can be backed up to Glance images easily by using the ",(0,t.jsx)(n.code,{children:"createImage"})," Compute API action or the corresponding OpenStack client command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack server image create --name $IMAGE_NAME $SERVER_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.p,{children:"This will create a Glance image containing a one-to-one copy of the data on the Ephemeral Storage disk at the time of execution."}),"\n",(0,t.jsxs)(n.p,{children:["If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in ",(0,t.jsx)(n.a,{href:"#image-backup-using-download",children:"Image backup using download"})," may be used after the image creation."]}),"\n",(0,t.jsx)(n.h2,{id:"volume-data-backup-using-cinder-backup-api",children:"Volume data backup using Cinder Backup API"}),"\n",(0,t.jsx)(n.p,{children:"The following instructions only apply if the infrastructure offers the Cinder Backup API."}),"\n",(0,t.jsxs)(n.admonition,{type:"note",children:[(0,t.jsx)(n.p,{children:"Backups of volumes using a volume type that uses encryption will retain their encryption and a clone of the original encryption key is created in Barbican linked to the backup.\nThese backups can only be restored when the Barbican service is available and still has the corresponding copy of the encryption key."}),(0,t.jsxs)(n.p,{children:["Also, it is advised to take note of the exact volume type when creating a backup of an encrypted volume, because this information will be needed to restore the backup.\nSee ",(0,t.jsx)(n.a,{href:"#restoring-an-encrypted-volume-backup-cinder-backup",children:"restoring an encrypted volume backup"}),"."]})]}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsxs)(n.p,{children:["It might be difficult or even impossible for a user to transfer backups created by the Cinder Backup API outside of the IaaS infrastructure, depending on the backup backend.\nA more easily accessible backup of volumes can be created by using Glance images.\nSee the ",(0,t.jsx)(n.a,{href:"#volume-data-backup-using-glance-images",children:"section about volume data backup using Glance images"})," for details."]})}),"\n",(0,t.jsx)(n.h3,{id:"backup-of-detached-volumes",children:"Backup of detached volumes"}),"\n",(0,t.jsx)(n.p,{children:"Backups can be created using the Cinder Backup API or the corresponding OpenStack client commands:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create $VOLUME_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.p,{children:"Further backups of the same volume can subsequently be created as incremental backups using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create --incremental $VOLUME_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.h3,{id:"backup-of-attached-volumes",children:"Backup of attached volumes"}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"When creating backups of attached (in-use) volumes, the state of the full volume is captured at runtime. Backups created this way will be crash-consistent but not app-consistent."})}),"\n",(0,t.jsxs)(n.p,{children:["In case of attached (in-use) volumes, backups can only be created while also specfiying the ",(0,t.jsx)(n.code,{children:"force"})," parameter:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create --force $VOLUME_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.p,{children:"Further backups of the same volume can subsequently be created as incremental backups using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create --force --incremental $VOLUME_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.h2,{id:"volume-data-backup-using-glance-images",children:"Volume data backup using Glance images"}),"\n",(0,t.jsx)(n.p,{children:"In case the Cinder Backup storage is not available in the IaaS infrastructure, Glance images can be used as a backup target instead.\nSuch images may also subsequently be downloaded to transfer the backup outside of the IaaS infrastructure."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Glance image backups of Cinder volumes only allow full backup copies and do not offer incremental or differential backup mechanisms."})}),"\n",(0,t.jsx)(n.h3,{id:"glance-image-backups-of-detached-volumes",children:"Glance image backups of detached volumes"}),"\n",(0,t.jsxs)(n.p,{children:["Volumes not attached to virtual machines can be directly copied into an image.\nSuch volumes can be identified by their status being ",(0,t.jsx)(n.code,{children:"available"}),".\nTo backup a detached volume to a Glance image, directly use the corresponding image creation action:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack image create --volume $VOLUME_NAME_OR_ID $IMAGE_NAME\n"})}),"\n",(0,t.jsx)(n.p,{children:"After the image creation has finished, a full backup copy of the volume will reside in the Glance storage backend."}),"\n",(0,t.jsxs)(n.p,{children:["If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in ",(0,t.jsx)(n.a,{href:"#image-backup-using-download",children:"Image backup using download"})," may be used after the image creation."]}),"\n",(0,t.jsx)(n.h3,{id:"glance-image-backups-of-attached-in-use-volumes",children:"Glance image backups of attached (in-use) volumes"}),"\n",(0,t.jsx)(n.p,{children:"Cinder is unable to directly create Glance images from volumes which are attached to virtual machines.\nTo create backups of such volumes regardless, a detour using volume snapshots can be used which will be described below."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["When creating snapshots of attached (in-use) volumes, the ",(0,t.jsx)(n.code,{children:"force"})," parameter has to be used. These snapshots capture a state of the full volume at runtime. They will be crash-consistent but not app-consistent."]})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Create a snapshot of the target volume while including the ",(0,t.jsx)(n.code,{children:"force"})," parameter in the request:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"openstack volume snapshot create --volume $VOLUME_NAME_OR_ID $SNAPSHOT_NAME"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Create a new temporary volume based on the snapshot to act as backup source:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"openstack volume create --snapshot $SNAPSHOT_NAME $TEMP_VOLUME_NAME"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Wait until the volume creation is finished and the temporary volume reaches the ",(0,t.jsx)(n.code,{children:"available"})," status."]}),"\n",(0,t.jsxs)(n.li,{children:["Create a backup image of the temporary volume:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"openstack image create --volume $TEMP_VOLUME_NAME $IMAGE_NAME"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Wait until the image creation finishes and the target image reaches the ",(0,t.jsx)(n.code,{children:"active"})," status."]}),"\n",(0,t.jsxs)(n.li,{children:["Delete the temporary volume and snapshot:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"openstack volume delete $TEMP_VOLUME_NAME"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"openstack volume snapshot delete $SNAPSHOT_NAME"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"A full backup copy of the volume now resides in the Glance storage backend."}),"\n",(0,t.jsxs)(n.p,{children:["If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in ",(0,t.jsx)(n.a,{href:"#image-backup-using-download",children:"Image backup using download"})," may be used after the image creation."]}),"\n",(0,t.jsx)(n.h2,{id:"barbican-secrets-backup-using-download",children:"Barbican secrets backup using download"}),"\n",(0,t.jsx)(n.admonition,{type:"danger",children:(0,t.jsx)(n.p,{children:"Secrets downloaded from Barbican will be in plaintext, which means that the secret is unprotected once received from the API.\nBefore downloading secrets from Barbican make sure that a secure target environment is established for receiving and securely storing the secret's contents."})}),"\n",(0,t.jsx)(n.p,{children:"Barbican secrets can be downloaded in plaintext using the corresponding API or client command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'openstack secret get --file $TARGET_FILE_PATH --payload_content_type "application/octet-stream" $SECRET_ID\n'})}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsxs)(n.p,{children:["In case the secret needs to be restored into an OpenStack Barbican later on, it is recommended to also note down the following attributes shown by ",(0,t.jsx)(n.code,{children:"openstack secret get $SECRET_ID"}),":"]}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Algorithm"}),"\n",(0,t.jsx)(n.li,{children:"Bit length"}),"\n",(0,t.jsx)(n.li,{children:"Secret type"}),"\n",(0,t.jsx)(n.li,{children:"Mode"}),"\n"]})]}),"\n",(0,t.jsx)(n.h3,{id:"retrieving-encryption-keys-from-barbican",children:"Retrieving encryption keys from Barbican"}),"\n",(0,t.jsx)(n.p,{children:"In case of encrypted volumes (i.e. using a volume type with encryption), a corresponding encryption key is stored in Barbican.\nWhen an image is created from such a volume, the encryption key is duplicated in Barbican for the image.\nIn order to backup those keys, the corresponding secret must first be identified."}),"\n",(0,t.jsx)(n.p,{children:"For volumes, this is possible starting with the Volume API microversion 3.64:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume show --os-volume-api-version 3.64 $VOLUME_NAME_OR_ID\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The response will contain an ",(0,t.jsx)(n.code,{children:"encryption_key_id"})," field with the ID of the Barbican secret."]}),"\n",(0,t.jsxs)(n.p,{children:["For images, the secret reference is stored in the ",(0,t.jsx)(n.code,{children:"properties"})," field instead:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack image show -f value -c properties $IMAGE_NAME_OR_ID\n"})}),"\n",(0,t.jsxs)(n.p,{children:["In case of images created from encrypted volumes, the resulting output will have a nested ",(0,t.jsx)(n.code,{children:"cinder_encryption_key_id"})," field that contains the ID of the Barbican secret."]}),"\n",(0,t.jsxs)(n.p,{children:["The resulting IDs can be used to retrieve the corresponding key using the ",(0,t.jsx)(n.a,{href:"#barbican-secrets-backup-using-download",children:"Barbican instructions"})," above."]}),"\n",(0,t.jsxs)(n.admonition,{type:"caution",children:[(0,t.jsx)(n.p,{children:"Note that the key retrieved from the secret is not immediately usable as LUKS passphrase to the image data of the volume.\nOpenStack does some processing to the key before it is passed to the LUKS encryption, which must be mimicked accordingly in order to unlock the encryption outside of OpenStack!"}),(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"#luks-encryption-key-conversion-to-decrypt-volume-images",children:"example procedure for converting the LUKS key"})," in the appendix section."]})]}),"\n",(0,t.jsx)(n.h2,{id:"restore",children:"Restore"}),"\n",(0,t.jsx)(n.p,{children:"The following sections will illustrate how to restore the individual resource backups that have been documented above."}),"\n",(0,t.jsx)(n.h3,{id:"restoring-a-backup-of-a-barbican-secret",children:"Restoring a backup of a Barbican secret"}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Note that restoring a Barbican secret by re-uploading it via the Barbican API will lead to the secret receiving a new ID.\nExisting resources referencing an old secret ID cannot make use of the restored copy."})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack secret store --algorithm aes --bit-length 256 --mode cbc \\\n --secret-type symmetric --file $KEY_FILE_PATH --name $SECRET_NAME\n"})}),"\n",(0,t.jsx)(n.p,{children:"Notes:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Attributes like algorithm, bit length, mode and secret type are not verified by Barbican. Their main purpose is to classify the secret on a metadata level. Make sure to align the attributes with the original secret."}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"$KEY_FILE_PATH"})," is the local file path of the secret backup as created originally using the ",(0,t.jsx)(n.a,{href:"#barbican-secrets-backup-using-download",children:"instructions above"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"$SECRET_NAME"})," is entirely optional but helps identifying the restored secret later on and to distinguish it from secrets created by OpenStack itself. It is best to not put whitespace characters in the name, otherwise it has to be surrounded by quotes."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The successful registration of the restored secret can subsequently be verified using:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack secret list --name $SECRET_NAME\n"})}),"\n",(0,t.jsx)(n.h3,{id:"restoring-a-backup-of-an-unencrypted-image",children:"Restoring a backup of an unencrypted image"}),"\n",(0,t.jsx)(n.p,{children:"Unencrypted image backups can simply be restored using the regular image upload functionality and specifying the backup file:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack image create --file $IMAGE_FILE_PATH $IMAGE_NAME\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["In case the original image backup was not based on a volume originally, the image may have had a non-default disk or container format.\nIn this case, add the command parameters ",(0,t.jsx)(n.code,{children:"--container-format"})," and ",(0,t.jsx)(n.code,{children:"--disk-format"})," to the command accordingly."]})}),"\n",(0,t.jsx)(n.h3,{id:"restoring-a-backup-of-an-encrypted-image",children:"Restoring a backup of an encrypted image"}),"\n",(0,t.jsx)(n.p,{children:"The following section only applies to image backups that were originally created from images of encrypted volumes."}),"\n",(0,t.jsxs)(n.p,{children:["First, restore the corresponding secret of the image using the ",(0,t.jsx)(n.a,{href:"#restoring-a-backup-of-a-barbican-secret",children:"instructions above"}),".\nThe restored secret will receive a new ID in the form of a ",(0,t.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Universally_unique_identifier",children:"UUID"}),".\nNote down the ID of the restored secret and insert it in place of ",(0,t.jsx)(n.code,{children:"$SECRET_ID"})," in the command below."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack image create --file $IMAGE_FILE_PATH \\\n --property cinder_encryption_key_id=$SECRET_ID \\\n --property cinder_encryption_key_deletion_policy=on_image_deletion \\\n $IMAGE_NAME\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"cinder_encryption_key_deletion_policy"})," attribute is optional.\nIf not specified, the referenced secret will not be deleted on image deletion automatically.\nIn contrast, if set to ",(0,t.jsx)(n.code,{children:"on_image_deletion"}),", the referenced secret will be deleted as soon as the image referencing it is deleted."]}),"\n",(0,t.jsx)(n.h3,{id:"restoring-a-volume-backup-from-an-image",children:"Restoring a volume backup from an image"}),"\n",(0,t.jsx)(n.p,{children:"To restore a volume from an image backup, simply use the volume creation action and specify the image as source."}),"\n",(0,t.jsxs)(n.p,{children:["Depending on whether the original volume the image was created from was encrypted or not, the target volume type might need to be specified accordingly.\nWhether this is the case can be identified by inspecting the image's metadata using ",(0,t.jsx)(n.code,{children:"openstack image show $IMAGE_NAME_OR_ID"}),' and looking for a "cinder_encryption_key_id" field within "properties".\nIf it exists, the source volume of the image was encrypted.']}),"\n",(0,t.jsx)(n.p,{children:"To restore the image of an unencrypted volume:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume create --image $IMAGE_NAME_OR_ID \\\n --size $VOLUME_SIZE_IN_GB $VOLUME_NAME\n"})}),"\n",(0,t.jsx)(n.p,{children:"To restore the image of an encrypted volume:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume create --image $IMAGE_NAME_OR_ID \\\n --type $ENCRYPTED_VOLUME_TYPE \\\n --size $VOLUME_SIZE_IN_GB $VOLUME_NAME\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If restoring an encrypted image, make sure to specify ",(0,t.jsx)(n.code,{children:"$ENCRYPTED_VOLUME_TYPE"})," correctly and have it reference a volume type which also supports the encryption.\nOtherwise the volume will be unbootable or unusable by Nova instances."]}),"\n",(0,t.jsx)(n.h3,{id:"restoring-a-volume-backup-from-the-cinder-backup-service",children:"Restoring a volume backup from the Cinder Backup service"}),"\n",(0,t.jsx)(n.p,{children:"The Cinder Backup service offers dedicated API actions and commands for restoring volume backups created using the service.\nThese backups can be restored in one of two ways:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Letting the Cinder Backup service create a new volume based on the backup."}),"\n",(0,t.jsx)(n.li,{children:"Overwriting an existing volume with the backup data."}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["If the volume backup was originally created from a volume that used a non-default encrypted volume type, letting Cinder Backup create a new volume for backup restoration does not work and the volume type must match exactly.\nIn such case provision an empty volume with the correct type first and then restore the backup onto it ",(0,t.jsx)(n.a,{href:"#restoring-an-encrypted-volume-backup-cinder-backup",children:"as explained further down"}),"."]})}),"\n",(0,t.jsx)(n.h4,{id:"restoring-to-a-new-volume-cinder-backup",children:"Restoring to a new volume (Cinder Backup)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup restore $BACKUP_NAME_OR_ID $TARGET_NAME\n"})}),"\n",(0,t.jsxs)(n.p,{children:["... where ",(0,t.jsx)(n.code,{children:"$TARGET_NAME"})," is the desired name of the new volume to be created.\nMake sure that no volume with this name already exists.\nThe Cinder Backup service will create the volume with the same size as the backup indicates."]}),"\n",(0,t.jsx)(n.h4,{id:"restoring-on-an-existing-volume-cinder-backup",children:"Restoring on an existing volume (Cinder Backup)"}),"\n",(0,t.jsx)(n.p,{children:"As an alternative to creating a new volume as the restore target, the backup can also be restored on an existing volume:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup restore --force $BACKUP_NAME_OR_ID $VOLUME_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.p,{children:"... which will overwrite the data on the existing volume, regardless of whether it is empty or not!"}),"\n",(0,t.jsx)(n.p,{children:'The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.'}),"\n",(0,t.jsx)(n.h4,{id:"restoring-an-encrypted-volume-backup-cinder-backup",children:"Restoring an encrypted volume backup (Cinder Backup)"}),"\n",(0,t.jsx)(n.p,{children:'When restoring a volume backup of a volume that was using a non-default encrypted volume type, a new volume of that type needs to be created first and then the backup restored onto it.\nOtherwise, the restoration will fail with the target volume ending up in the "error_restoring" state.\nFor this procedure to succeed it is necessary to know the exact volume type of the volume the backup was created from.'}),"\n",(0,t.jsxs)(n.p,{children:["If the source volume of the backup still exists, the original volume type can be determined by inspecting the backup's ",(0,t.jsx)(n.code,{children:"volume_id"})," attribute and then using it to look up the corresponding volume and its ",(0,t.jsx)(n.code,{children:"type"})," attribute.\nThe following client command can be used for this (fill in the value for ",(0,t.jsx)(n.code,{children:"BACKUP_ID"}),"):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'export BACKUP_ID=...\n\nSOURCE_VOLUME_ID="$(openstack volume backup show $BACKUP_ID -f value -c volume_id)"\nopenstack volume show -f value -c type "$SOURCE_VOLUME_ID"\n'})}),"\n",(0,t.jsx)(n.p,{children:"This returns the name of the original volume type.\nIf the source volume does not exist anymore, rely on documentation about the backup to determine the type, if available."}),"\n",(0,t.jsxs)(n.p,{children:["First, create a new empty volume as the restore target and use the backup's ",(0,t.jsx)(n.code,{children:"size"})," metadata attribute to match the size of the volume to the backup:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume create --size $BACKUP_SIZE --type $VOLUME_TYPE $TARGET_NAME\n"})}),"\n",(0,t.jsxs)(n.p,{children:["... where ",(0,t.jsx)(n.code,{children:"$TARGET_NAME"})," is the desired name of the new volume."]}),"\n",(0,t.jsx)(n.p,{children:'Once the volume reaches "available" state, restore the backup onto it:'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup restore --force $BACKUP_NAME_OR_ID $TARGET_NAME\n"})}),"\n",(0,t.jsx)(n.p,{children:'The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.'}),"\n",(0,t.jsx)(n.h2,{id:"appendix",children:"Appendix"}),"\n",(0,t.jsx)(n.h3,{id:"image-creation-action-for-servers-with-attached-volumes",children:"Image creation action for servers with attached volumes"}),"\n",(0,t.jsxs)(n.p,{children:["When the ",(0,t.jsx)(n.code,{children:"createImage"})," action of the Compute API (",(0,t.jsx)(n.code,{children:"openstack server image create"}),") is used on virtual machines that have at least one volume attached, a snapshot will be created for each attached volume individually and referenced in the resulting image's metadata."]}),"\n",(0,t.jsx)(n.p,{children:"This happens regardless of whether the virtual machine has an Ephemeral Storage disk attached.\nIn case of an Ephemeral Storage disk, only the Ephemeral Storage is copied into the Glance image as a 1:1 copy."}),"\n",(0,t.jsxs)(n.p,{children:["In case of a virtual machine that has no Ephemeral Storage but only volumes, the ",(0,t.jsx)(n.code,{children:"createImage"})," action leads to a Glance image that only consists of metadata (including the resulting volume snapshot references) but carries no actual binary data."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Figure: createImage action flow involving Ephemeral Storage and/or volumes",src:a(75028).A+"",width:"1342",height:"1202"})}),"\n",(0,t.jsx)(n.h3,{id:"luks-encryption-key-conversion-to-decrypt-volume-images",children:"LUKS encryption key conversion to decrypt volume images"}),"\n",(0,t.jsx)(n.p,{children:"The volume encryption keys stored in Barbican are not directly used as LUKS passphrases by OpenStack because they are in binary format.\nOpenStack converts them to ASCII internally before passing them to the encryption layer.\nThis behavior needs to be reproduced if a decryption of a volume image is desired outside of OpenStack."}),"\n",(0,t.jsx)(n.admonition,{type:"danger",children:(0,t.jsx)(n.p,{children:"The instructions below will expose plaintext data of encryption keys and encrypted volume images.\nMake sure to only execute these steps in a secure and trusted environment."})}),"\n",(0,t.jsx)(n.p,{children:"First, download the image:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack image save --file image.raw $IMAGE_NAME_OR_ID\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Next, inspect the image metadata, determine the reference to the encryption key (",(0,t.jsx)(n.code,{children:"cinder_encryption_key_id"})," property) and download the encryption key:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'openstack image show -f value -c properties $IMAGE_NAME_OR_ID\n# (use the value of `cinder_encryption_key_id` as `$SECRET_ID` below)\nopenstack secret get --file image.key --payload_content_type "application/octet-stream" $SECRET_ID\n'})}),"\n",(0,t.jsx)(n.p,{children:"This will result in the following local files:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"image.raw"})," = the raw encrypted image downloaded from Glance"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"image.key"})," = the LUKS encryption key in binary format (plaintext)"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Since OpenStack internally uses Python's ",(0,t.jsx)(n.code,{children:"binascii.hexlify()"})," to convert the binary encryption key before passing it as a passphrase to the LUKS encryption, as a last step this conversion must be mimicked to unlock the encryption:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"python3 -c \"import binascii; \\\n f = open('image.key', 'rb'); \\\n print(binascii.hexlify(f.read()).decode('utf-8'))\" \\\n | sudo cryptsetup luksOpen ./image.raw decrypted_image\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The decrypted image is now accessible at ",(0,t.jsx)(n.code,{children:"/dev/mapper/decrypted_image"}),".\nNote that this is a live en-/decryption operation on the ",(0,t.jsx)(n.code,{children:"image.raw"})," file.\nThe image is not converted, the encryption is simply unlocked in-memory using LUKS and dm-crypt until the encryption is closed again."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"/dev/mapper/decrypted_image"})," can now be handled like a raw block device (e.g. mounted as a filesystem) or snapshotted in decrypted form."]}),"\n",(0,t.jsx)(n.p,{children:"To close the encryption execute:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo cryptsetup luksClose decrypted_image\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},75028:(e,n,a)=>{a.d(n,{A:()=>i});const i=a.p+"assets/images/user_data_backups_figure1-988dbd55659509cc1ddc9f68f2437648.png"},28453:(e,n,a)=>{a.d(n,{R:()=>r,x:()=>c});var i=a(96540);const t={},s=i.createContext(t);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/814f3328.1f680611.js b/assets/js/814f3328.1f680611.js new file mode 100644 index 0000000000..d54c2ed1d3 --- /dev/null +++ b/assets/js/814f3328.1f680611.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[67472],{55513:s=>{s.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"First Blog Post","permalink":"/blog/first-blog-post","unlisted":false,"date":"2022-10-28T00:00:00.000Z"}]}')}}]); \ No newline at end of file diff --git a/assets/js/81875c35.6b699ce6.js b/assets/js/81875c35.6b699ce6.js new file mode 100644 index 0000000000..c14265054b --- /dev/null +++ b/assets/js/81875c35.6b699ce6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[31669],{92725:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>r,contentTitle:()=>d,default:()=>o,frontMatter:()=>c,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"operating-scs/components/status-page-api/docs/example-requests","title":"Example requests","description":"Example request for common API requests.","source":"@site/docs/04-operating-scs/components/status-page-api/docs/example-requests.md","sourceDirName":"04-operating-scs/components/status-page-api/docs","slug":"/operating-scs/components/status-page-api/docs/example-requests","permalink":"/docs/operating-scs/components/status-page-api/docs/example-requests","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-api/docs/example-requests.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Requests","permalink":"/docs/operating-scs/components/status-page-api/docs/requests"},"next":{"title":"Contribute","permalink":"/docs/operating-scs/components/status-page-api/docs/contribute"}}');var a=s(74848),i=s(28453);const c={},d="Example requests",r={},l=[{value:"List phases",id:"list-phases",level:2},{value:"Create phases",id:"create-phases",level:2},{value:"List impact types",id:"list-impact-types",level:2},{value:"Create impact type",id:"create-impact-type",level:2},{value:"Get impact type",id:"get-impact-type",level:2},{value:"List severities",id:"list-severities",level:2},{value:"Create severity",id:"create-severity",level:2},{value:"Get severity",id:"get-severity",level:2},{value:"List components",id:"list-components",level:2},{value:"Create component",id:"create-component",level:2},{value:"Get component",id:"get-component",level:2},{value:"List incidents",id:"list-incidents",level:2},{value:"Create incident",id:"create-incident",level:2},{value:"Get incident",id:"get-incident",level:2},{value:"List incident update",id:"list-incident-update",level:2},{value:"Create incident update",id:"create-incident-update",level:2},{value:"Get incident update",id:"get-incident-update",level:2}];function p(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"example-requests",children:"Example requests"})}),"\n",(0,a.jsx)(t.p,{children:"Example request for common API requests."}),"\n",(0,a.jsxs)(t.p,{children:["Request can either be performed against the local API server at ",(0,a.jsx)(t.code,{children:"localhost:3000"})," or against the public release of the API server at ",(0,a.jsx)(t.a,{href:"https://status-api.k8s.scs.community/",children:"status-api.k8s.scs.community"}),". When using the public release authorization via bearer token must be included. Please refer to the ",(0,a.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-deployment",children:"status page deployment"}),".\nLocal instances of the API can use ",(0,a.jsx)(t.code,{children:"STATUS_PAGE_SWAGGER_UI_ENABLED=true"})," to perform request with swagger at ",(0,a.jsx)(t.code,{children:"localhost:3000/swagger"}),". Any instance of the API can be used with the included ",(0,a.jsx)(t.a,{href:"https://www.usebruno.com/",children:"Bruno"})," collection."]}),"\n",(0,a.jsx)(t.p,{children:"All examples include the public release with authorization header."}),"\n",(0,a.jsx)(t.h2,{id:"list-phases",children:"List phases"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\nhttps://status-api.k8s.scs.community/phases\n\n{"data":{"generation":1,"phases":["Scheduled","Investigation ongoing","Working on it","Potential fix deployed","Done"]}}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"create-phases",children:"Create phases"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\n-X POST \\\n-H \'Authorization: Bearer <your-id-token>\' \\\n-H \'Content-Type: application/json\' \\\n-d \'{"phases": ["Phase 1", "Phase 2", "Phase 3"]}\' \\\nhttps://status-api.k8s.scs.community/phases\n\n{"generation":2}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"list-impact-types",children:"List impact types"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\nhttps://status-api.k8s.scs.community/impacttypes\n\n{"data":[{"displayName":"Performance Degradation","id":"63645189-ffbc-4e6c-b991-99e14ade3edc"},{"displayName":"Connectivity Problems","id":"9fcf0039-9e24-45b0-b76a-80e6246a803b"},{"displayName":"Unknown","id":"6cadd69a-5702-4824-b7a6-d5509c54b8cb"}]}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"create-impact-type",children:"Create impact type"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"$ curl -sL \\\n-X 'POST' \\\n-H 'Authorization: Bearer <your-id-token>' \\\n-H 'Content-Type: application/json' \\\n-d '{\"displayName\": \"Test impact type\"}' \\\nhttps://status-api.k8s.scs.community/impacttypes\n\n{\"id\":\"52d178d2-0fe9-4654-834b-42502283454d\"}\n"})}),"\n",(0,a.jsx)(t.h2,{id:"get-impact-type",children:"Get impact type"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\nhttps://status-api.k8s.scs.community/impacttypes/52d178d2-0fe9-4654-834b-42502283454d\n\n{"data":{"displayName":"Test impact type","id":"52d178d2-0fe9-4654-834b-42502283454d"}}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"list-severities",children:"List severities"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\nhttps://status-api.k8s.scs.community/severities\n\n{"data":[{"displayName":"operational","value":25},{"displayName":"maintenance","value":50},{"displayName":"limited","value":75},{"displayName":"broken","value":100}]}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"create-severity",children:"Create severity"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"curl -sL \\\n-X POST \\\n-H 'Authorization: Bearer <your-id-token>' \\\n-H 'Content-Type: application/json' \\\n-d '{\"displayName\": \"test\",\"value\": 60}'\nhttps://status-api.k8s.scs.community/severities\n"})}),"\n",(0,a.jsx)(t.h2,{id:"get-severity",children:"Get severity"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\nhttps://status-api.k8s.scs.community/severities/test\n\n{"data":{"displayName":"test","value":60}}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"list-components",children:"List components"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\nhttps://status-api.k8s.scs.community/components\n\n{"data":[{"activelyAffectedBy":[],"displayName":"Storage","id":"871584dc-e425-4155-8fde-47ca588689f3","labels":{}},{"activelyAffectedBy":[],"displayName":"Network","id":"414d764f-0c94-4c4d-90e6-c97cce00cce3","labels":{}},...]}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"create-component",children:"Create component"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'curl -sL \\\n-X POST \\\n-H \'Authorization: Bearer <your-id-token>\' \\\n-H \'Content-Type: application/json\' \\\n-d \'{"displayName":"Test-Component"}\'\\\nhttps://status-api.k8s.scs.community/components\n\n{"id":"3ebed33a-a80c-4888-b3d3-2677e87c25e7"}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"get-component",children:"Get component"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\nhttps://status-api.k8s.scs.community/components/3ebed33a-a80c-4888-b3d3-2677e87c25e7\n\n{"data":{"activelyAffectedBy":[{"reference":"09f471bb-b0af-4528-a021-f23f31e2d1c9","severity":90,"type":"52d178d2-0fe9-4654-834b-42502283454d"}],"displayName":"Test-Component","id":"3ebed33a-a80c-4888-b3d3-2677e87c25e7"}}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"list-incidents",children:"List incidents"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\n\'http://localhost:3000/incidents?start=2024-04-01T10%3A10%3A10.010Z&end=2024-04-30T10%3A10%3A10.010Z\'\n\n{"data":[{"affects":[{"reference":"3ebed33a-a80c-4888-b3d3-2677e87c25e7","type":"52d178d2-0fe9-4654-834b-42502283454d"}],"beganAt":"2024-04-03T08:00:00+02:00","description":"A test incident.","displayName":"Test-Incident","endedAt":null,"id":"09f471bb-b0af-4528-a021-f23f31e2d1c9","phase":{"generation":0,"order":0},"updates":[]}]}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"create-incident",children:"Create incident"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\n-X POST \\\n-H \'Authorization: Bearer <your-id-token>\' \\\n-H \'Content-Type: application/json\' \\\n-d \'{"affects":[{"reference":"3ebed33a-a80c-4888-b3d3-2677e87c25e7","severity":90,"type":"52d178d2-0fe9-4654-834b-42502283454d"}],"beganAt":"2024-04-03T06:00:00.000Z","description":"A test incident.","displayName":"Test-Incident","phase":{}}\' \\\nhttps://status-api.k8s.scs.community/incidents\n\n{"id":"09f471bb-b0af-4528-a021-f23f31e2d1c9"}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"get-incident",children:"Get incident"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\nhttps://status-api.k8s.scs.community/incidents/09f471bb-b0af-4528-a021-f23f31e2d1c9\n\n{"data":{"affects":[{"reference":"3ebed33a-a80c-4888-b3d3-2677e87c25e7","type":"52d178d2-0fe9-4654-834b-42502283454d"}],"beganAt":"2024-04-03T08:00:00+02:00","description":"A test incident.","displayName":"Test-Incident","endedAt":null,"id":"09f471bb-b0af-4528-a021-f23f31e2d1c9","phase":{"generation":0,"order":0},"updates":[]}}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"list-incident-update",children:"List incident update"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\nhttps://status-api.k8s.scs.community/incidents/09f471bb-b0af-4528-a021-f23f31e2d1c9/updates\n\n{"data":[{"createdAt":"2024-04-03T08:15:00+02:00","description":"Example update for test incident","displayName":"Example Update","order":0}]}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"create-incident-update",children:"Create incident update"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\n-X POST \\\n-H \'Authorization: Bearer <your-id-token>\' \\\n-H \'Content-Type: application/json\' \\\n-d \'{"createdAt":"2024-04-03T06:15:00.000Z","description":"Example update for test incident","displayName":"Example Update"}\' \\\nhttps://status-api.k8s.scs.community/incidents/09f471bb-b0af-4528-a021-f23f31e2d1c9/updates\n\n{"order": 0}\n'})}),"\n",(0,a.jsx)(t.h2,{id:"get-incident-update",children:"Get incident update"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'$ curl -sL \\\nhttps://status-api.k8s.scs.community/incidents/09f471bb-b0af-4528-a021-f23f31e2d1c9/updates/0\n\n{"data":{"createdAt":"2024-04-03T08:15:00+02:00","description":"Example update for test incident","displayName":"Example Update","order":0}}\n'})})]})}function o(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(p,{...e})}):p(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>d});var n=s(96540);const a={},i=n.createContext(a);function c(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/82144.09311b61.js b/assets/js/82144.09311b61.js new file mode 100644 index 0000000000..eff4d5256a --- /dev/null +++ b/assets/js/82144.09311b61.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[82144],{82144:(t,e,n)=>{n.d(e,{diagram:()=>j});var i=n(86079),s=n(26312),r=n(79186),a=(n(74353),n(16750),n(42838),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[6,8,10,11,12,14,16,17,18],n=[1,9],i=[1,10],s=[1,11],r=[1,12],a=[1,13],o=[1,14],c={trace:function(){},yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 9:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 10:case 11:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 12:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 13:i.addTask(r[o-1],r[o]),this.$="task"}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:n,12:i,14:s,16:r,17:a,18:o},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:n,12:i,14:s,16:r,17:a,18:o},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,o="",c=0,l=0,h=r.slice.call(arguments,1),y=Object.create(this.lexer),u={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(u.yy[p]=this.yy[p]);y.setInput(t,u.yy),u.yy.lexer=y,u.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var d=y.yylloc;r.push(d);var f=y.options&&y.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var g,x,m,k,_,b,v,$,w,M={};;){if(x=n[n.length-1],this.defaultActions[x]?m=this.defaultActions[x]:(null==g&&(w=void 0,"number"!=typeof(w=i.pop()||y.lex()||1)&&(w instanceof Array&&(w=(i=w).pop()),w=e.symbols_[w]||w),g=w),m=a[x]&&a[x][g]),void 0===m||!m.length||!m[0]){var E="";for(_ in $=[],a[x])this.terminals_[_]&&_>2&&$.push("'"+this.terminals_[_]+"'");E=y.showPosition?"Parse error on line "+(c+1)+":\n"+y.showPosition()+"\nExpecting "+$.join(", ")+", got '"+(this.terminals_[g]||g)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==g?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(E,{text:y.match,token:this.terminals_[g]||g,line:y.yylineno,loc:d,expected:$})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+g);switch(m[0]){case 1:n.push(g),s.push(y.yytext),r.push(y.yylloc),n.push(m[1]),g=null,l=y.yyleng,o=y.yytext,c=y.yylineno,d=y.yylloc;break;case 2:if(b=this.productions_[m[1]][1],M.$=s[s.length-b],M._$={first_line:r[r.length-(b||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(b||1)].first_column,last_column:r[r.length-1].last_column},f&&(M._$.range=[r[r.length-(b||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply(M,[o,l,c,u.yy,m[1],s,r].concat(h))))return k;b&&(n=n.slice(0,-1*b*2),s=s.slice(0,-1*b),r=r.slice(0,-1*b)),n.push(this.productions_[m[1]][0]),s.push(M.$),r.push(M._$),v=a[n[n.length-2]][n[n.length-1]],n.push(v);break;case 3:return!0}}return!0}},l={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:case 1:case 3:case 4:break;case 2:return 10;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),14;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 18;case 16:return 19;case 17:return":";case 18:return 6;case 19:return"INVALID"}},rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18,19],inclusive:!0}}};function h(){this.yy={}}return c.lexer=l,h.prototype=c,c.Parser=h,new h}());a.parser=a;const o=a;let c="";const l=[],h=[],y=[],u=function(){let t=!0;for(const[e,n]of y.entries())y[e].processed,t=t&&n.processed;return t},p={getConfig:()=>(0,i.c)().journey,clear:function(){l.length=0,h.length=0,c="",y.length=0,(0,i.v)()},setDiagramTitle:i.q,getDiagramTitle:i.t,setAccTitle:i.s,getAccTitle:i.g,setAccDescription:i.b,getAccDescription:i.a,addSection:function(t){c=t,l.push(t)},getSections:function(){return l},getTasks:function(){let t=u();let e=0;for(;!t&&e<100;)t=u(),e++;return h.push(...y),h},addTask:function(t,e){const n=e.substr(1).split(":");let i=0,s=[];1===n.length?(i=Number(n[0]),s=[]):(i=Number(n[0]),s=n[1].split(","));const r=s.map((t=>t.trim())),a={section:c,type:c,people:r,task:t,score:i};y.push(a)},addTaskOrg:function(t){const e={section:c,type:c,description:t,task:t,classes:[]};h.push(e)},getActors:function(){return function(){const t=[];return h.forEach((e=>{e.people&&t.push(...e.people)})),[...new Set(t)].sort()}()}},d=t=>`.label {\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n color: ${t.textColor};\n }\n .mouth {\n stroke: #666;\n }\n\n line {\n stroke: ${t.textColor}\n }\n\n .legend {\n fill: ${t.textColor};\n }\n\n .label text {\n fill: #333;\n }\n .label {\n color: ${t.textColor}\n }\n\n .face {\n ${t.faceColor?`fill: ${t.faceColor}`:"fill: #FFF8DC"};\n stroke: #999;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 1.5px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n rect {\n opacity: 0.5;\n }\n text-align: center;\n }\n\n .cluster rect {\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .task-type-0, .section-type-0 {\n ${t.fillType0?`fill: ${t.fillType0}`:""};\n }\n .task-type-1, .section-type-1 {\n ${t.fillType0?`fill: ${t.fillType1}`:""};\n }\n .task-type-2, .section-type-2 {\n ${t.fillType0?`fill: ${t.fillType2}`:""};\n }\n .task-type-3, .section-type-3 {\n ${t.fillType0?`fill: ${t.fillType3}`:""};\n }\n .task-type-4, .section-type-4 {\n ${t.fillType0?`fill: ${t.fillType4}`:""};\n }\n .task-type-5, .section-type-5 {\n ${t.fillType0?`fill: ${t.fillType5}`:""};\n }\n .task-type-6, .section-type-6 {\n ${t.fillType0?`fill: ${t.fillType6}`:""};\n }\n .task-type-7, .section-type-7 {\n ${t.fillType0?`fill: ${t.fillType7}`:""};\n }\n\n .actor-0 {\n ${t.actor0?`fill: ${t.actor0}`:""};\n }\n .actor-1 {\n ${t.actor1?`fill: ${t.actor1}`:""};\n }\n .actor-2 {\n ${t.actor2?`fill: ${t.actor2}`:""};\n }\n .actor-3 {\n ${t.actor3?`fill: ${t.actor3}`:""};\n }\n .actor-4 {\n ${t.actor4?`fill: ${t.actor4}`:""};\n }\n .actor-5 {\n ${t.actor5?`fill: ${t.actor5}`:""};\n }\n`,f=function(t,e){return(0,r.d)(t,e)},g=function(t,e){const n=t.append("circle");return n.attr("cx",e.cx),n.attr("cy",e.cy),n.attr("class","actor-"+e.pos),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("r",e.r),void 0!==n.class&&n.attr("class",n.class),void 0!==e.title&&n.append("title").text(e.title),n},x=function(t,e){return(0,r.f)(t,e)};let m=-1;const k=function(){function t(t,e,n,s,r,a,o,c){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",c).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,c,l){const{taskFontSize:h,taskFontFamily:y}=c,u=t.split(/<br\s*\/?>/gi);for(let p=0;p<u.length;p++){const t=p*h-h*(u.length-1)/2,c=e.append("text").attr("x",n+r/2).attr("y",s).attr("fill",l).style("text-anchor","middle").style("font-size",h).style("font-family",y);c.append("tspan").attr("x",n+r/2).attr("dy",t).text(u[p]),c.attr("y",s+a/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(c,o)}}function n(t,n,s,r,a,o,c,l){const h=n.append("switch"),y=h.append("foreignObject").attr("x",s).attr("y",r).attr("width",a).attr("height",o).attr("position","fixed").append("xhtml:div").style("display","table").style("height","100%").style("width","100%");y.append("div").attr("class","label").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,s,r,a,o,c,l),i(y,c)}function i(t,e){for(const n in e)n in e&&t.attr(n,e[n])}return function(i){return"fo"===i.textPlacement?n:"old"===i.textPlacement?t:e}}(),_=g,b=function(t,e,n){const i=t.append("g"),s=(0,r.g)();s.x=e.x,s.y=e.y,s.fill=e.fill,s.width=n.width*e.taskCount+n.diagramMarginX*(e.taskCount-1),s.height=n.height,s.class="journey-section section-type-"+e.num,s.rx=3,s.ry=3,f(i,s),k(n)(e.text,i,s.x,s.y,s.width,s.height,{class:"journey-section section-type-"+e.num},n,e.colour)},v=x,$=function(t,e,n){const i=e.x+n.width/2,a=t.append("g");m++;a.append("line").attr("id","task"+m).attr("x1",i).attr("y1",e.y).attr("x2",i).attr("y2",450).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),function(t,e){const n=15,i=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",n).attr("stroke-width",2).attr("overflow","visible"),r=t.append("g");r.append("circle").attr("cx",e.cx-5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),r.append("circle").attr("cx",e.cx+5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),e.score>3?function(t){const i=(0,s.JLW)().startAngle(Math.PI/2).endAngle(Math.PI/2*3).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}(r):e.score<3?function(t){const i=(0,s.JLW)().startAngle(3*Math.PI/2).endAngle(Math.PI/2*5).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}(r):r.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}(a,{cx:i,cy:300+30*(5-e.score),score:e.score});const o=(0,r.g)();o.x=e.x,o.y=e.y,o.fill=e.fill,o.width=n.width,o.height=n.height,o.class="task task-type-"+e.num,o.rx=3,o.ry=3,f(a,o);let c=e.x+14;e.people.forEach((t=>{const n=e.actors[t].color,i={cx:c,cy:e.y,r:7,fill:n,stroke:"#000",title:t,pos:e.actors[t].position};g(a,i),c+=10})),k(n)(e.task,a,o.x,o.y,o.width,o.height,{class:"task"},n,e.colour)},w=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},M={};const E=(0,i.c)().journey,T=E.leftMargin,S={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},updateVal:function(t,e,n,i){void 0===t[e]?t[e]=n:t[e]=i(n,t[e])},updateBounds:function(t,e,n,s){const r=(0,i.c)().journey,a=this;let o=0;var c;this.sequenceItems.forEach((function(i){o++;const l=a.sequenceItems.length-o+1;a.updateVal(i,"starty",e-l*r.boxMargin,Math.min),a.updateVal(i,"stopy",s+l*r.boxMargin,Math.max),a.updateVal(S.data,"startx",t-l*r.boxMargin,Math.min),a.updateVal(S.data,"stopx",n+l*r.boxMargin,Math.max),"activation"!==c&&(a.updateVal(i,"startx",t-l*r.boxMargin,Math.min),a.updateVal(i,"stopx",n+l*r.boxMargin,Math.max),a.updateVal(S.data,"starty",e-l*r.boxMargin,Math.min),a.updateVal(S.data,"stopy",s+l*r.boxMargin,Math.max))}))},insert:function(t,e,n,i){const s=Math.min(t,n),r=Math.max(t,n),a=Math.min(e,i),o=Math.max(e,i);this.updateVal(S.data,"startx",s,Math.min),this.updateVal(S.data,"starty",a,Math.min),this.updateVal(S.data,"stopx",r,Math.max),this.updateVal(S.data,"stopy",o,Math.max),this.updateBounds(s,a,r,o)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return this.data}},A=E.sectionFills,I=E.sectionColours,P=function(t,e,n){const s=(0,i.c)().journey;let r="";const a=n+(2*s.height+s.diagramMarginY);let o=0,c="#CCC",l="black",h=0;for(const[i,y]of e.entries()){if(r!==y.section){c=A[o%A.length],h=o%A.length,l=I[o%I.length];let n=0;const a=y.section;for(let t=i;t<e.length&&e[t].section==a;t++)n+=1;const u={x:i*s.taskMargin+i*s.width+T,y:50,text:y.section,fill:c,num:h,colour:l,taskCount:n};b(t,u,s),r=y.section,o++}const n=y.people.reduce(((t,e)=>(M[e]&&(t[e]=M[e]),t)),{});y.x=i*s.taskMargin+i*s.width+T,y.y=a,y.width=s.diagramMarginX,y.height=s.diagramMarginY,y.colour=l,y.fill=c,y.num=h,y.actors=n,$(t,y,s),S.insert(y.x,y.y,y.x+y.width+s.taskMargin,450)}},C={setConf:function(t){Object.keys(t).forEach((function(e){E[e]=t[e]}))},draw:function(t,e,n,r){const a=(0,i.c)().journey,o=(0,i.c)().securityLevel;let c;"sandbox"===o&&(c=(0,s.Ltv)("#i"+e));const l="sandbox"===o?(0,s.Ltv)(c.nodes()[0].contentDocument.body):(0,s.Ltv)("body");S.init();const h=l.select("#"+e);w(h);const y=r.db.getTasks(),u=r.db.getDiagramTitle(),p=r.db.getActors();for(const i in M)delete M[i];let d=0;p.forEach((t=>{M[t]={color:a.actorColours[d%a.actorColours.length],position:d},d++})),function(t){const e=(0,i.c)().journey;let n=60;Object.keys(M).forEach((i=>{const s=M[i].color,r={cx:20,cy:n,r:7,fill:s,stroke:"#000",pos:M[i].position};_(t,r);const a={x:40,y:n+7,fill:"#666",text:i,textMargin:5|e.boxTextMargin};v(t,a),n+=20}))}(h),S.insert(0,0,T,50*Object.keys(M).length),P(h,y,0);const f=S.getBounds();u&&h.append("text").text(u).attr("x",T).attr("font-size","4ex").attr("font-weight","bold").attr("y",25);const g=f.stopy-f.starty+2*a.diagramMarginY,x=T+f.stopx+2*a.diagramMarginX;(0,i.i)(h,g,x,a.useMaxWidth),h.append("line").attr("x1",T).attr("y1",4*a.height).attr("x2",x-T-4).attr("y2",4*a.height).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");const m=u?70:0;h.attr("viewBox",`${f.startx} -25 ${x} ${g+m}`),h.attr("preserveAspectRatio","xMinYMin meet"),h.attr("height",g+m+25)}},j={parser:o,db:p,renderer:C,styles:d,init:t=>{C.setConf(t.journey),p.clear()}}},79186:(t,e,n)=>{n.d(e,{a:()=>a,b:()=>l,c:()=>c,d:()=>r,e:()=>y,f:()=>o,g:()=>h});var i=n(16750),s=n(86079);const r=(t,e)=>{const n=t.append("rect");if(n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),e.name&&n.attr("name",e.name),void 0!==e.rx&&n.attr("rx",e.rx),void 0!==e.ry&&n.attr("ry",e.ry),void 0!==e.attrs)for(const i in e.attrs)n.attr(i,e.attrs[i]);return void 0!==e.class&&n.attr("class",e.class),n},a=(t,e)=>{const n={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};r(t,n).lower()},o=(t,e)=>{const n=e.text.replace(s.J," "),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.attr("class","legend"),i.style("text-anchor",e.anchor),void 0!==e.class&&i.attr("class",e.class);const r=i.append("tspan");return r.attr("x",e.x+2*e.textMargin),r.text(n),i},c=(t,e,n,s)=>{const r=t.append("image");r.attr("x",e),r.attr("y",n);const a=(0,i.Jf)(s);r.attr("xlink:href",a)},l=(t,e,n,s)=>{const r=t.append("use");r.attr("x",e),r.attr("y",n);const a=(0,i.Jf)(s);r.attr("xlink:href",`#${a}`)},h=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),y=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})}}]); \ No newline at end of file diff --git a/assets/js/82237.b1e220fa.js b/assets/js/82237.b1e220fa.js new file mode 100644 index 0000000000..db62f244d4 --- /dev/null +++ b/assets/js/82237.b1e220fa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[82237],{23363:(e,t,n)=>{n.d(t,{A:()=>a});n(96540);var i=n(18215),o=n(21312),s=n(51107),r=n(74848);function a(e){let{className:t}=e;return(0,r.jsx)("main",{className:(0,i.A)("container margin-vert--xl",t),children:(0,r.jsx)("div",{className:"row",children:(0,r.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,r.jsx)(s.A,{as:"h1",className:"hero__title",children:(0,r.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,r.jsx)("p",{children:(0,r.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,r.jsx)("p",{children:(0,r.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}},82237:(e,t,n)=>{n.r(t),n.d(t,{default:()=>d});n(96540);var i=n(21312),o=n(61213),s=n(59504),r=n(23363),a=n(74848);function d(){const e=(0,i.T)({id:"theme.NotFound.title",message:"Page Not Found"});return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(o.be,{title:e}),(0,a.jsx)(s.A,{children:(0,a.jsx)(r.A,{})})]})}}}]); \ No newline at end of file diff --git a/assets/js/83100446.ccca8e9e.js b/assets/js/83100446.ccca8e9e.js new file mode 100644 index 0000000000..d516e4d481 --- /dev/null +++ b/assets/js/83100446.ccca8e9e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[46334],{40106:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>a,default:()=>p,frontMatter:()=>c,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"container/deployment-examples/a/index","title":"Overview","description":"TODO","source":"@site/docs/03-container/deployment-examples/a/index.md","sourceDirName":"03-container/deployment-examples/a","slug":"/container/deployment-examples/a/","permalink":"/docs/container/deployment-examples/a/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/deployment-examples/a/index.md","tags":[],"version":"current","frontMatter":{}}');var r=t(74848),s=t(28453);const c={},a="Overview",i={},d=[];function l(e){const n={h1:"h1",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(n.p,{children:"TODO"})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>a});var o=t(96540);const r={},s=o.createContext(r);function c(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8493ac52.68e06ebf.js b/assets/js/8493ac52.68e06ebf.js new file mode 100644 index 0000000000..882a803e03 --- /dev/null +++ b/assets/js/8493ac52.68e06ebf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[45054],{74829:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>l,metadata:()=>o,toc:()=>i});const o=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","title":"Developer Guide","description":"Developing Cluster Stack Provider OpenStack operator is quite straightforward. First, you need to install some basic prerequisites:","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs","slug":"/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Controllers","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers"},"next":{"title":"Overview","permalink":"/docs/container/components/cluster-stacks/components/csctl/overview"}}');var n=s(74848),c=s(28453);const l={},r="Developer Guide",a={},i=[{value:"Setting Tilt up",id:"setting-tilt-up",level:2},{value:"Developing with Tilt",id:"developing-with-tilt",level:2},{value:"Applying ClusterStack",id:"applying-clusterstack",level:3},{value:"Creating workload cluster",id:"creating-workload-cluster",level:3},{value:"Toggle between local_mode and remote mode",id:"toggle-between-local_mode-and-remote-mode",level:2}];function d(e){const t={a:"a",blockquote:"blockquote",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"developer-guide",children:"Developer Guide"})}),"\n",(0,n.jsx)(t.p,{children:"Developing Cluster Stack Provider OpenStack operator is quite straightforward. First, you need to install some basic prerequisites:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Docker"}),"\n",(0,n.jsx)(t.li,{children:"Go"}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"Next, configure your environment variables. Once that's done, you can initiate development using the local Kind cluster and the Tilt UI to create a workload cluster that comes pre-configured."}),"\n",(0,n.jsx)(t.h2,{id:"setting-tilt-up",children:"Setting Tilt up"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"Install Docker and Go. We expect you to run on a Linux OS."}),"\n",(0,n.jsxs)(t.li,{children:["Create an ",(0,n.jsx)(t.code,{children:".envrc"})," file and specify the values you need. See the ",(0,n.jsx)(t.code,{children:".envrc.sample"})," for details."]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"developing-with-tilt",children:"Developing with Tilt"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"tilt",src:s(8860).A+"",title:"Tilt",width:"1848",height:"902"})}),"\n",(0,n.jsx)(t.p,{children:"Operator development requires a lot of iteration, and the \u201cbuild, tag, push, update deployment\u201d workflow can be very tedious. Tilt makes this process much simpler by watching for updates and automatically building and deploying them. To build a kind cluster and to start Tilt, run:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"make tilt-up\n"})}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsxs)(t.p,{children:["To access the Tilt UI please go to: ",(0,n.jsx)(t.code,{children:"http://localhost:10351"})]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"You should make sure that everything in the UI looks green. If not, you can trigger the Tilt workflow again."}),"\n",(0,n.jsx)(t.h3,{id:"applying-clusterstack",children:"Applying ClusterStack"}),"\n",(0,n.jsxs)(t.p,{children:["When you start your tilt setup then the ClusterStack manifest gets copied from ",(0,n.jsx)(t.code,{children:"config/cspo"})," directory to root of your repository. In order to apply the ClusterStack to the running local development cluster, you can click on the tilt UI. There should a click on the top-right hand side that is named as ",(0,n.jsx)(t.code,{children:"apply-clusterstack"})," if you hover over it.\nOnce the ClusterStack is applied wait for the ClusterStack and ClusterStackRelease object to be ready. In case your ClusterStack shows that it is ready, you can deploy a workload cluster."]}),"\n",(0,n.jsx)(t.h3,{id:"creating-workload-cluster",children:"Creating workload cluster"}),"\n",(0,n.jsxs)(t.p,{children:["This could be done through the Tilt UI, by pressing the button in the top right corner ",(0,n.jsx)(t.code,{children:"Create Workload Cluster"}),". This triggers the ",(0,n.jsx)(t.code,{children:"make create-workload-cluster-openstack"}),", which uses the environment variables and the cluster-template."]}),"\n",(0,n.jsx)(t.p,{children:"To interact with your freshly created workload cluster, you can use these commands:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:'make get-kubeconfig-workload-cluster #KUBECONFIG for the workload cluster is placed here: ".workload-cluster-kubeconfig.yaml"\nexport KUBECONFIG=$PWD/.workload-cluster-kubeconfig.yaml\n'})}),"\n",(0,n.jsx)(t.p,{children:"In case you want to change some code, you can do so and see that Tilt triggers on save. It will update the container of the operator automatically."}),"\n",(0,n.jsxs)(t.p,{children:["If you want to change something in your ClusterStack or Cluster custom resources, you can have a look at ",(0,n.jsx)(t.code,{children:".cluster.yaml"})," and ",(0,n.jsx)(t.code,{children:".clusterstack.yaml"}),", which Tilt uses."]}),"\n",(0,n.jsxs)(t.p,{children:["To delete the ClusterStack you can click on the ",(0,n.jsx)(t.code,{children:"delete-clusterstack"})," button in the tilt UI."]}),"\n",(0,n.jsxs)(t.p,{children:["To tear down the workload cluster, click on the ",(0,n.jsx)(t.code,{children:"Delete Workload Cluster"})," button in the top right corner of the Tilt UI. This action triggers the execution of ",(0,n.jsx)(t.code,{children:"make delete-workload-cluster-openstack"}),". After a few minutes, the resources should be successfully deleted."]}),"\n",(0,n.jsx)(t.p,{children:"To tear down the kind cluster, use:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"make delete-bootstrap-cluster\n"})}),"\n",(0,n.jsxs)(t.p,{children:["If you have any trouble finding the right command, then you can use ",(0,n.jsx)(t.code,{children:"make help"})," to get a list of all available make targets."]}),"\n",(0,n.jsx)(t.h2,{id:"toggle-between-local_mode-and-remote-mode",children:"Toggle between local_mode and remote mode"}),"\n",(0,n.jsxs)(t.p,{children:["We can retrieve cluster-stacks in two modes. One way is to let the controller fetch it from repository which is remote mode and other is we mount the cluster-stacks inside the container at ",(0,n.jsx)(t.code,{children:"/tmp/downloads/cluster-stacks"})," directory."]}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsxs)(t.p,{children:["[!NOTE]",(0,n.jsx)(t.br,{}),"\n","Using remote mode is the default behavior."]}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["Switching between both modes is relatively simple if you're using Tilt. There is a file at the root of the repo ",(0,n.jsx)(t.code,{children:"tilt-settings.yaml.example"}),"\nMake a copy of that file with the name of ",(0,n.jsx)(t.code,{children:"tilt-settings.yaml"})]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"cp tilt-settings.yaml.example tilt-settings.yaml\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Now, open the file and set the ",(0,n.jsx)(t.code,{children:"local_mode"})," to ",(0,n.jsx)(t.code,{children:"true"})," to use cluster-stacks in local_mode. It should look the following content wise."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",children:"local_mode: true\n"})}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsx)(t.p,{children:"[!NOTE]\nIn this mode you need to have cluster-stacks present locally."}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"Downloading cluster-stacks can be achieved by many ways but below is a simple way to download it quickly."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"mkdir -p .release/openstack-scs-1-27-v1/\ncd .release/openstack-scs-1-27-v1\ngh release download --repo SovereignCloudStack/cluster-stacks openstack-scs-1-27-v1\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Change the repo and tag as per the requirement. You can also download it directly from browser and move it to ",(0,n.jsx)(t.code,{children:".release"})," directory."]}),"\n",(0,n.jsxs)(t.p,{children:["Please make sure the directory structure remains the same otherwise you'll not be able to start the tilt setup. Here's an example of structuring ",(0,n.jsx)(t.code,{children:"openstack-scs-1-27-v1"})," cluster-stack."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"$ tree .release/openstack-scs-1-27-v1/\n.release/openstack-scs-1-27-v1/\n\u251c\u2500\u2500 clusterstack.yaml\n\u251c\u2500\u2500 metadata.yaml\n\u2514\u2500\u2500 openstack-scs-1-27-cluster-class-v1.tgz\n"})}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsxs)(t.p,{children:["[!IMPORTANT]\nThere's an alternative way to get clusterstacks using ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/csctl",children:"csctl"}),". You can follow the README of csctl for specific instructions and a good quickstart."]}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["You can use ",(0,n.jsx)(t.code,{children:"csctl create"})," subcommand to create clusterstack locally. You'll need a csctl.yaml file in the cluster-stack configuration directory. Please read more about creating configuration file for csctl in the csctl docs."]})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},8860:(e,t,s)=>{s.d(t,{A:()=>o});const o=s.p+"assets/images/tilt-4af6fa61d9a6a82abdfa1c82985f182e.png"},28453:(e,t,s)=>{s.d(t,{R:()=>l,x:()=>r});var o=s(96540);const n={},c=o.createContext(n);function l(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:l(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/853df457.10d87070.js b/assets/js/853df457.10d87070.js new file mode 100644 index 0000000000..5fe85f3434 --- /dev/null +++ b/assets/js/853df457.10d87070.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4365],{85683:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>d,contentTitle:()=>r,default:()=>l,frontMatter:()=>a,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/tools/index","title":"Tools","description":"","source":"@site/docs/02-iaas/guides/operations-guide/openstack/tools/index.md","sourceDirName":"02-iaas/guides/operations-guide/openstack/tools","slug":"/iaas/guides/operations-guide/openstack/tools/","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/index.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Tools","sidebar_position":10},"sidebar":"docs","previous":{"title":"OpenStack","permalink":"/docs/iaas/guides/operations-guide/openstack/"},"next":{"title":"Image Manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/"}}');var n=s(74848),i=s(28453);const a={sidebar_label:"Tools",sidebar_position:10},r="Tools",d={},c=[];function u(e){const o={h1:"h1",header:"header",...(0,i.R)(),...e.components};return(0,n.jsx)(o.header,{children:(0,n.jsx)(o.h1,{id:"tools",children:"Tools"})})}function l(e={}){const{wrapper:o}={...(0,i.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,o,s)=>{s.d(o,{R:()=>a,x:()=>r});var t=s(96540);const n={},i=t.createContext(n);function a(e){const o=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function r(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),t.createElement(i.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/85628.087505cc.js b/assets/js/85628.087505cc.js new file mode 100644 index 0000000000..976972bdbb --- /dev/null +++ b/assets/js/85628.087505cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[85628],{85628:(e,t,l)=>{l.d(t,{diagram:()=>f});var n=l(21987),a=l(26312),o=l(697),i=l(86079),s=l(8995);l(74353),l(16750),l(42838),l(21176),l(14075);const d=e=>i.e.sanitizeText(e,(0,i.c)());let r={dividerMargin:10,padding:5,textHeight:10,curve:void 0};const c=function(e,t,l,n,a){const o=Object.keys(e);i.l.info("keys:",o),i.l.info(e),o.filter((t=>e[t].parent==a)).forEach((function(l){var o,s;const r=e[l],c=r.cssClasses.join(" "),p=(0,i.k)(r.styles),b=r.label??r.id,f={labelStyle:p.labelStyle,shape:"class_box",labelText:d(b),classData:r,rx:0,ry:0,class:c,style:p.style,id:r.id,domId:r.domId,tooltip:n.db.getTooltip(r.id,a)||"",haveCallback:r.haveCallback,link:r.link,width:"group"===r.type?500:void 0,type:r.type,padding:(null==(o=(0,i.c)().flowchart)?void 0:o.padding)??(null==(s=(0,i.c)().class)?void 0:s.padding)};t.setNode(r.id,f),a&&t.setParent(r.id,a),i.l.info("setNode",f)}))};function p(e){let t;switch(e){case 0:t="aggregation";break;case 1:t="extension";break;case 2:t="composition";break;case 3:t="dependency";break;case 4:t="lollipop";break;default:t="none"}return t}const b={setConf:function(e){r={...r,...e}},draw:async function(e,t,l,n){i.l.info("Drawing class - ",t);const b=(0,i.c)().flowchart??(0,i.c)().class,f=(0,i.c)().securityLevel;i.l.info("config:",b);const y=(null==b?void 0:b.nodeSpacing)??50,u=(null==b?void 0:b.rankSpacing)??50,g=new o.T({multigraph:!0,compound:!0}).setGraph({rankdir:n.db.getDirection(),nodesep:y,ranksep:u,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}})),h=n.db.getNamespaces(),v=n.db.getClasses(),w=n.db.getRelations(),k=n.db.getNotes();let x;i.l.info(w),function(e,t,l,n){const a=Object.keys(e);i.l.info("keys:",a),i.l.info(e),a.forEach((function(a){var o,s;const r=e[a],p={shape:"rect",id:r.id,domId:r.domId,labelText:d(r.id),labelStyle:"",style:"fill: none; stroke: black",padding:(null==(o=(0,i.c)().flowchart)?void 0:o.padding)??(null==(s=(0,i.c)().class)?void 0:s.padding)};t.setNode(r.id,p),c(r.classes,t,l,n,r.id),i.l.info("setNode",p)}))}(h,g,t,n),c(v,g,t,n),function(e,t){const l=(0,i.c)().flowchart;let n=0;e.forEach((function(e){var o;n++;const s={classes:"relation",pattern:1==e.relation.lineType?"dashed":"solid",id:`id_${e.id1}_${e.id2}_${n}`,arrowhead:"arrow_open"===e.type?"none":"normal",startLabelRight:"none"===e.relationTitle1?"":e.relationTitle1,endLabelLeft:"none"===e.relationTitle2?"":e.relationTitle2,arrowTypeStart:p(e.relation.type1),arrowTypeEnd:p(e.relation.type2),style:"fill:none",labelStyle:"",curve:(0,i.n)(null==l?void 0:l.curve,a.lUB)};if(i.l.info(s,e),void 0!==e.style){const t=(0,i.k)(e.style);s.style=t.style,s.labelStyle=t.labelStyle}e.text=e.title,void 0===e.text?void 0!==e.style&&(s.arrowheadStyle="fill: #333"):(s.arrowheadStyle="fill: #333",s.labelpos="c",(null==(o=(0,i.c)().flowchart)?void 0:o.htmlLabels)??(0,i.c)().htmlLabels?(s.labelType="html",s.label='<span class="edgeLabel">'+e.text+"</span>"):(s.labelType="text",s.label=e.text.replace(i.e.lineBreakRegex,"\n"),void 0===e.style&&(s.style=s.style||"stroke: #333; stroke-width: 1.5px;fill:none"),s.labelStyle=s.labelStyle.replace("color:","fill:"))),t.setEdge(e.id1,e.id2,s,n)}))}(w,g),function(e,t,l,n){i.l.info(e),e.forEach((function(e,o){var s,c;const p=e,b="",f="",y=p.text,u={labelStyle:b,shape:"note",labelText:d(y),noteData:p,rx:0,ry:0,class:"",style:f,id:p.id,domId:p.id,tooltip:"",type:"note",padding:(null==(s=(0,i.c)().flowchart)?void 0:s.padding)??(null==(c=(0,i.c)().class)?void 0:c.padding)};if(t.setNode(p.id,u),i.l.info("setNode",u),!p.class||!(p.class in n))return;const g=l+o,h={id:`edgeNote${g}`,classes:"relation",pattern:"dotted",arrowhead:"none",startLabelRight:"",endLabelLeft:"",arrowTypeStart:"none",arrowTypeEnd:"none",style:"fill:none",labelStyle:"",curve:(0,i.n)(r.curve,a.lUB)};t.setEdge(p.id,p.class,h,g)}))}(k,g,w.length+1,v),"sandbox"===f&&(x=(0,a.Ltv)("#i"+t));const m="sandbox"===f?(0,a.Ltv)(x.nodes()[0].contentDocument.body):(0,a.Ltv)("body"),T=m.select(`[id="${t}"]`),S=m.select("#"+t+" g");if(await(0,s.r)(S,g,["aggregation","extension","composition","dependency","lollipop"],"classDiagram",t),i.u.insertTitle(T,"classTitleText",(null==b?void 0:b.titleTopMargin)??5,n.db.getDiagramTitle()),(0,i.o)(g,T,null==b?void 0:b.diagramPadding,null==b?void 0:b.useMaxWidth),!(null==b?void 0:b.htmlLabels)){const e="sandbox"===f?x.nodes()[0].contentDocument:document,l=e.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const t of l){const l=t.getBBox(),n=e.createElementNS("http://www.w3.org/2000/svg","rect");n.setAttribute("rx",0),n.setAttribute("ry",0),n.setAttribute("width",l.width),n.setAttribute("height",l.height),t.insertBefore(n,t.firstChild)}}}},f={parser:n.p,db:n.d,renderer:b,styles:n.s,init:e=>{e.class||(e.class={}),e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute,n.d.clear()}}}}]); \ No newline at end of file diff --git a/assets/js/85f4c940.47e4267d.js b/assets/js/85f4c940.47e4267d.js new file mode 100644 index 0000000000..4c301629da --- /dev/null +++ b/assets/js/85f4c940.47e4267d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[34312],{83501:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"user-docs"}')}}]); \ No newline at end of file diff --git a/assets/js/86770.d286033f.js b/assets/js/86770.d286033f.js new file mode 100644 index 0000000000..8c42bbe37a --- /dev/null +++ b/assets/js/86770.d286033f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[86770],{86770:(t,e,a)=>{a.d(e,{diagram:()=>y});var r=a(21987),i=a(26312),n=a(21176),d=a(697),o=a(86079);a(74353),a(16750),a(42838);let s=0;const l=function(t){let e=t.id;return t.type&&(e+="<"+(0,o.x)(t.type)+">"),e},p=function(t,e,a,r){const{displayText:i,cssStyle:n}=e.getDisplayDetails(),d=t.append("tspan").attr("x",r.padding).text(i);""!==n&&d.attr("style",e.cssStyle),a||d.attr("dy",r.textHeight)},c=function(t,e,a,r){o.l.debug("Rendering class ",e,a);const i=e.id,n={id:i,label:e.id,width:0,height:0},d=t.append("g").attr("id",r.db.lookUpDomId(i)).attr("class","classGroup");let s;s=e.link?d.append("svg:a").attr("xlink:href",e.link).attr("target",e.linkTarget).append("text").attr("y",a.textHeight+a.padding).attr("x",0):d.append("text").attr("y",a.textHeight+a.padding).attr("x",0);let c=!0;e.annotations.forEach((function(t){const e=s.append("tspan").text("\xab"+t+"\xbb");c||e.attr("dy",a.textHeight),c=!1}));let g=l(e);const h=s.append("tspan").text(g).attr("class","title");c||h.attr("dy",a.textHeight);const f=s.node().getBBox().height;let x,u,y;if(e.members.length>0){x=d.append("line").attr("x1",0).attr("y1",a.padding+f+a.dividerMargin/2).attr("y2",a.padding+f+a.dividerMargin/2);const t=d.append("text").attr("x",a.padding).attr("y",f+a.dividerMargin+a.textHeight).attr("fill","white").attr("class","classText");c=!0,e.members.forEach((function(e){p(t,e,c,a),c=!1})),u=t.node().getBBox()}if(e.methods.length>0){y=d.append("line").attr("x1",0).attr("y1",a.padding+f+a.dividerMargin+u.height).attr("y2",a.padding+f+a.dividerMargin+u.height);const t=d.append("text").attr("x",a.padding).attr("y",f+2*a.dividerMargin+u.height+a.textHeight).attr("fill","white").attr("class","classText");c=!0,e.methods.forEach((function(e){p(t,e,c,a),c=!1}))}const b=d.node().getBBox();var m=" ";e.cssClasses.length>0&&(m+=e.cssClasses.join(" "));const k=d.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",b.width+2*a.padding).attr("height",b.height+a.padding+.5*a.dividerMargin).attr("class",m).node().getBBox().width;return s.node().childNodes.forEach((function(t){t.setAttribute("x",(k-t.getBBox().width)/2)})),e.tooltip&&s.insert("title").text(e.tooltip),x&&x.attr("x2",k),y&&y.attr("x2",k),n.width=k,n.height=b.height+a.padding+.5*a.dividerMargin,n},g=function(t,e,a,r,n){const d=function(t){switch(t){case n.db.relationType.AGGREGATION:return"aggregation";case n.db.relationType.EXTENSION:return"extension";case n.db.relationType.COMPOSITION:return"composition";case n.db.relationType.DEPENDENCY:return"dependency";case n.db.relationType.LOLLIPOP:return"lollipop"}};e.points=e.points.filter((t=>!Number.isNaN(t.y)));const l=e.points,p=(0,i.n8j)().x((function(t){return t.x})).y((function(t){return t.y})).curve(i.qrM),c=t.append("path").attr("d",p(l)).attr("id","edge"+s).attr("class","relation");let g,h,f="";r.arrowMarkerAbsolute&&(f=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,f=f.replace(/\(/g,"\\("),f=f.replace(/\)/g,"\\)")),1==a.relation.lineType&&c.attr("class","relation dashed-line"),10==a.relation.lineType&&c.attr("class","relation dotted-line"),"none"!==a.relation.type1&&c.attr("marker-start","url("+f+"#"+d(a.relation.type1)+"Start)"),"none"!==a.relation.type2&&c.attr("marker-end","url("+f+"#"+d(a.relation.type2)+"End)");const x=e.points.length;let u,y,b,m,k=o.u.calcLabelPosition(e.points);if(g=k.x,h=k.y,x%2!=0&&x>1){let t=o.u.calcCardinalityPosition("none"!==a.relation.type1,e.points,e.points[0]),r=o.u.calcCardinalityPosition("none"!==a.relation.type2,e.points,e.points[x-1]);o.l.debug("cardinality_1_point "+JSON.stringify(t)),o.l.debug("cardinality_2_point "+JSON.stringify(r)),u=t.x,y=t.y,b=r.x,m=r.y}if(void 0!==a.title){const e=t.append("g").attr("class","classLabel"),i=e.append("text").attr("class","label").attr("x",g).attr("y",h).attr("fill","red").attr("text-anchor","middle").text(a.title);window.label=i;const n=i.node().getBBox();e.insert("rect",":first-child").attr("class","box").attr("x",n.x-r.padding/2).attr("y",n.y-r.padding/2).attr("width",n.width+r.padding).attr("height",n.height+r.padding)}if(o.l.info("Rendering relation "+JSON.stringify(a)),void 0!==a.relationTitle1&&"none"!==a.relationTitle1){t.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",u).attr("y",y).attr("fill","black").attr("font-size","6").text(a.relationTitle1)}if(void 0!==a.relationTitle2&&"none"!==a.relationTitle2){t.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",b).attr("y",m).attr("fill","black").attr("font-size","6").text(a.relationTitle2)}s++},h=function(t,e,a,r){o.l.debug("Rendering note ",e,a);const i=e.id,n={id:i,text:e.text,width:0,height:0},d=t.append("g").attr("id",i).attr("class","classGroup");let s=d.append("text").attr("y",a.textHeight+a.padding).attr("x",0);const l=JSON.parse(`"${e.text}"`).split("\n");l.forEach((function(t){o.l.debug(`Adding line: ${t}`),s.append("tspan").text(t).attr("class","title").attr("dy",a.textHeight)}));const p=d.node().getBBox(),c=d.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",p.width+2*a.padding).attr("height",p.height+l.length*a.textHeight+a.padding+.5*a.dividerMargin).node().getBBox().width;return s.node().childNodes.forEach((function(t){t.setAttribute("x",(c-t.getBBox().width)/2)})),n.width=c,n.height=p.height+l.length*a.textHeight+a.padding+.5*a.dividerMargin,n};let f={};const x=function(t){const e=Object.entries(f).find((e=>e[1].label===t));if(e)return e[0]},u={draw:function(t,e,a,r){const s=(0,o.c)().class;f={},o.l.info("Rendering diagram "+t);const l=(0,o.c)().securityLevel;let p;"sandbox"===l&&(p=(0,i.Ltv)("#i"+e));const u="sandbox"===l?(0,i.Ltv)(p.nodes()[0].contentDocument.body):(0,i.Ltv)("body"),y=u.select(`[id='${e}']`);var b;(b=y).append("defs").append("marker").attr("id","extensionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),b.append("defs").append("marker").attr("id","extensionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z"),b.append("defs").append("marker").attr("id","compositionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","compositionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","aggregationStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","aggregationEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","dependencyStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z");const m=new d.T({multigraph:!0});m.setGraph({isMultiGraph:!0}),m.setDefaultEdgeLabel((function(){return{}}));const k=r.db.getClasses(),w=Object.keys(k);for(const i of w){const t=k[i],e=c(y,t,s,r);f[e.id]=e,m.setNode(e.id,e),o.l.info("Org height: "+e.height)}r.db.getRelations().forEach((function(t){o.l.info("tjoho"+x(t.id1)+x(t.id2)+JSON.stringify(t)),m.setEdge(x(t.id1),x(t.id2),{relation:t},t.title||"DEFAULT")}));r.db.getNotes().forEach((function(t){o.l.debug(`Adding note: ${JSON.stringify(t)}`);const e=h(y,t,s,r);f[e.id]=e,m.setNode(e.id,e),t.class&&t.class in k&&m.setEdge(t.id,x(t.class),{relation:{id1:t.id,id2:t.class,relation:{type1:"none",type2:"none",lineType:10}}},"DEFAULT")})),(0,n.Zp)(m),m.nodes().forEach((function(t){void 0!==t&&void 0!==m.node(t)&&(o.l.debug("Node "+t+": "+JSON.stringify(m.node(t))),u.select("#"+(r.db.lookUpDomId(t)||t)).attr("transform","translate("+(m.node(t).x-m.node(t).width/2)+","+(m.node(t).y-m.node(t).height/2)+" )"))})),m.edges().forEach((function(t){void 0!==t&&void 0!==m.edge(t)&&(o.l.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(m.edge(t))),g(y,m.edge(t),m.edge(t).relation,s,r))}));const L=y.node().getBBox(),v=L.width+40,E=L.height+40;(0,o.i)(y,E,v,s.useMaxWidth);const M=`${L.x-20} ${L.y-20} ${v} ${E}`;o.l.debug(`viewBox ${M}`),y.attr("viewBox",M)}},y={parser:r.p,db:r.d,renderer:u,styles:r.s,init:t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute,r.d.clear()}}}}]); \ No newline at end of file diff --git a/assets/js/8679ddc4.72ea5f42.js b/assets/js/8679ddc4.72ea5f42.js new file mode 100644 index 0000000000..c358874b9d --- /dev/null +++ b/assets/js/8679ddc4.72ea5f42.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6960],{29598:(e,i,o)=>{o.r(i),o.d(i,{assets:()=>d,contentTitle:()=>t,default:()=>g,frontMatter:()=>c,metadata:()=>n,toc:()=>a});const n=JSON.parse('{"id":"iaas/guides/configuration-guide/services/docker","title":"Docker","description":"With the osism.services.docker role, it is possible to manage Docker.","source":"@site/docs/02-iaas/guides/configuration-guide/services/docker.md","sourceDirName":"02-iaas/guides/configuration-guide/services","slug":"/iaas/guides/configuration-guide/services/docker","permalink":"/docs/iaas/guides/configuration-guide/services/docker","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/services/docker.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Docker"},"sidebar":"docs","previous":{"title":"Chrony","permalink":"/docs/iaas/guides/configuration-guide/services/chrony"},"next":{"title":"Tuned","permalink":"/docs/iaas/guides/configuration-guide/services/tuned"}}');var r=o(74848),s=o(28453);const c={sidebar_label:"Docker"},t="Docker",d={},a=[{value:"Configure logging drivers",id:"configure-logging-drivers",level:2}];function l(e){const i={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(i.header,{children:(0,r.jsx)(i.h1,{id:"docker",children:"Docker"})}),"\n",(0,r.jsxs)(i.p,{children:["With the ",(0,r.jsx)(i.code,{children:"osism.services.docker"})," role, it is possible to manage Docker."]}),"\n",(0,r.jsx)(i.h2,{id:"configure-logging-drivers",children:"Configure logging drivers"}),"\n",(0,r.jsxs)(i.p,{children:["Docker documentation: ",(0,r.jsx)(i.a,{href:"https://docs.docker.com/config/containers/logging/configure/",children:"https://docs.docker.com/config/containers/logging/configure/"})]}),"\n",(0,r.jsx)(i.p,{children:"The role currently supports the following parameters with their respective defaults."}),"\n",(0,r.jsx)(i.pre,{children:(0,r.jsx)(i.code,{className:"language-yaml",children:'docker_log_driver: "json-file"\ndocker_log_level: info\ndocker_log_opts:\n max-size: 10m\n max-file: 3\n'})}),"\n",(0,r.jsxs)(i.p,{children:["The log driver to be used can be configured with ",(0,r.jsx)(i.code,{children:"docker_log_driver"}),". By default,\n",(0,r.jsx)(i.a,{href:"https://docs.docker.com/config/containers/logging/json-file/",children:"json-file"})," is used.\nThe log driver writes all logs of a container to a JSON file\nin ",(0,r.jsx)(i.code,{children:"/var/lib/docker/containers"}),". All supported log drivers can be found in the\n",(0,r.jsx)(i.a,{href:"https://docs.docker.com/config/containers/logging/configure/#supported-logging-drivers",children:"Docker documentation"}),"."]}),"\n",(0,r.jsxs)(i.p,{children:["The log level can be configured via ",(0,r.jsx)(i.code,{children:"docker_log_level"}),"."]}),"\n",(0,r.jsxs)(i.p,{children:["Parameters for the log driver used can be set with the ",(0,r.jsx)(i.code,{children:"docker_log_opts"})," dictionary.\nBy default, the maximum size of a JSON file is set to 10 MByte with ",(0,r.jsx)(i.code,{children:"max-size: 10m"}),".\nIf it contains more, the file is rotated."]}),"\n",(0,r.jsxs)(i.p,{children:["Furthermore, ",(0,r.jsx)(i.code,{children:"max-file: 3"})," specifies that up to 3 files should be available."]}),"\n",(0,r.jsx)(i.p,{children:"Existing containers don't use the new logging configuration automatically."})]})}function g(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,r.jsx)(i,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,i,o)=>{o.d(i,{R:()=>c,x:()=>t});var n=o(96540);const r={},s=n.createContext(r);function c(e){const i=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function t(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(s.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/86bbda6f.ec6e62bf.js b/assets/js/86bbda6f.ec6e62bf.js new file mode 100644 index 0000000000..cbddd32573 --- /dev/null +++ b/assets/js/86bbda6f.ec6e62bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[10296],{87938:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"scs-0123-v1-mandatory-and-supported-IaaS-services","title":"Mandatory and Supported IaaS Services","description":"Introduction","source":"@site/standards/scs-0123-v1-mandatory-and-supported-IaaS-services.md","sourceDirName":".","slug":"/scs-0123-v1-mandatory-and-supported-IaaS-services","permalink":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Mandatory and Supported IaaS Services","type":"Standard","status":"Stable","stabilized_at":"2024-11-20T00:00:00.000Z","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0123: Mandatory and Supported IaaS Services","permalink":"/standards/iaas/scs-0123"},"next":{"title":"scs-0124: Standard for the security of IaaS service software","permalink":"/standards/iaas/scs-0124"}}');var r=s(74848),i=s(28453);const a={title:"Mandatory and Supported IaaS Services",type:"Standard",status:"Stable",stabilized_at:new Date("2024-11-20T00:00:00.000Z"),track:"IaaS"},d=void 0,o={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Mandatory IaaS APIs",id:"mandatory-iaas-apis",level:2},{value:"Supported IaaS APIs",id:"supported-iaas-apis",level:2},{value:"Unsupported IaaS APIs",id:"unsupported-iaas-apis",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",h2:"h2",li:"li",ol:"ol",p:"p",section:"section",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsxs)(t.p,{children:["To be SCS-compliant a Cloud Service Provider (CSP) has to fulfill all SCS standards.\nSome of those standards are broad and consider all APIs of all services on the IaaS-Layer like the consideration of a ",(0,r.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/issues/issues/396",children:"role standard"}),".\nThere exist many services on that layer and for a first step they need to be limited to have a clear scope for the standards and the Cloud Service Providers following them.\nFor this purpose, this standard will establish lists for mandatory services whose APIs have to be present in a SCS cloud as well as supported services, which APIs are considered by some standards and may even be tested for their integration but are optional in a sense that their omission will not violate SCS conformance."]}),"\n",(0,r.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,r.jsx)(t.p,{children:"There are many OpenStack APIs and their corresponding services that can be deployed on the IaaS level.\nThese services have differences in the quality of their implementation and liveness and some of them may be easily omitted when creating an IaaS deployment.\nTo fulfill all SCS-provided standards only a subset of these APIs are required.\nSome more but not all remaining OpenStack APIs are also supported additionally by the SCS project and may be part of its reference implementation.\nThis results in different levels of support for specific services.\nThis document will give readers insight about how the SCS classifies the OpenStack APIs accordingly.\nIf a cloud provides all mandatory and any number of supported OpenStack APIs, it can be tested for SCS-compliance.\nAny unsupported APIs will not be tested."}),"\n",(0,r.jsx)(t.h2,{id:"mandatory-iaas-apis",children:"Mandatory IaaS APIs"}),"\n",(0,r.jsx)(t.p,{children:"The following IaaS APIs MUST be present in SCS-compliant IaaS deployments and could be implemented with the corresponding OpenStack services:"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Mandatory API"}),(0,r.jsx)(t.th,{children:"corresponding OpenStack Service"}),(0,r.jsx)(t.th,{children:"description"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"block-storage"})}),(0,r.jsx)(t.td,{children:"Cinder"}),(0,r.jsx)(t.td,{children:"Block Storage service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"compute"})}),(0,r.jsx)(t.td,{children:"Nova"}),(0,r.jsx)(t.td,{children:"Compute service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"identity"})}),(0,r.jsx)(t.td,{children:"Keystone"}),(0,r.jsx)(t.td,{children:"Identity service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"image"})}),(0,r.jsx)(t.td,{children:"Glance"}),(0,r.jsx)(t.td,{children:"Image service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"load-balancer"})}),(0,r.jsx)(t.td,{children:"Octavia"}),(0,r.jsx)(t.td,{children:"Load-balancer service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"network"})}),(0,r.jsx)(t.td,{children:"Neutron"}),(0,r.jsx)(t.td,{children:"Networking service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"s3"})}),(0,r.jsx)(t.td,{children:"S3 API object storage"}),(0,r.jsx)(t.td,{children:"Object Storage service"})]})]})]}),"\n",(0,r.jsx)(t.admonition,{type:"caution",children:(0,r.jsx)(t.p,{children:"S3 API implementations may differ in certain offered features.\nCSPs must publicly describe the endpoints of their S3 solutions and which implementations they use in their deployment.\nUsers should always research whether a needed feature is supported in the offered implementation."})}),"\n",(0,r.jsxs)(t.p,{children:["The endpoints of services MUST be findable through the ",(0,r.jsx)(t.code,{children:"catalog list"})," of the identity API",(0,r.jsx)(t.sup,{children:(0,r.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"supported-iaas-apis",children:"Supported IaaS APIs"}),"\n",(0,r.jsx)(t.p,{children:"The following IaaS APIs MAY be present in SCS-compliant IaaS deployment, e.g. implemented thorugh the corresponding OpenStack services, and are considered in the SCS standards."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Supported API"}),(0,r.jsx)(t.th,{children:"corresponding OpenStack Service"}),(0,r.jsx)(t.th,{children:"description"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"bare-metal"})}),(0,r.jsx)(t.td,{children:"Ironic"}),(0,r.jsx)(t.td,{children:"Bare Metal provisioning service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"billing"})}),(0,r.jsx)(t.td,{children:"CloudKitty"}),(0,r.jsx)(t.td,{children:"Rating/Billing service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"dns"})}),(0,r.jsx)(t.td,{children:"Designate"}),(0,r.jsx)(t.td,{children:"DNS service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"ha"})}),(0,r.jsx)(t.td,{children:"Masakari"}),(0,r.jsx)(t.td,{children:"Instances High Availability service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"key-manager"})}),(0,r.jsx)(t.td,{children:"Barbican"}),(0,r.jsx)(t.td,{children:"Key Manager service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"object-store"})}),(0,r.jsx)(t.td,{children:"Swift"}),(0,r.jsx)(t.td,{children:"Object Store with different possible backends"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"orchestration"})}),(0,r.jsx)(t.td,{children:"Heat"}),(0,r.jsx)(t.td,{children:"Orchestration service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"shared-file-systems"})}),(0,r.jsx)(t.td,{children:"Manila"}),(0,r.jsx)(t.td,{children:"Shared File Systems service"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.strong,{children:"time-series-database"})}),(0,r.jsx)(t.td,{children:"Gnocchi"}),(0,r.jsx)(t.td,{children:"Time Series Database service"})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"unsupported-iaas-apis",children:"Unsupported IaaS APIs"}),"\n",(0,r.jsx)(t.p,{children:"All other OpenStack services, whose APIs are not mentioned in the mandatory or supported lists will not be tested for their compatibility and conformance in SCS clouds by the SCS community.\nThose services MAY be integrated into IaaS deployments by a Cloud Service Provider on their own responsibility but SCS will not assume they are present and potential issues that occur during deployment or usage have to be handled by the CSP on their own accord.\nThe SCS standard offers no guarantees for compatibility or reliability of services categorized as unsupported."}),"\n",(0,r.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.a,{href:"https://www.openstack.org/software/",children:"The OpenStack Services"})}),"\n",(0,r.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,r.jsxs)(t.p,{children:["The presence of the mandatory OpenStack APIs will be tested in ",(0,r.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/mandatory-services/mandatory-iaas-services.py",children:"this test-script"}),"\nThe test will further check whether the object-store endpoint is compatible to s3."]}),"\n","\n",(0,r.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,r.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://docs.openstack.org/keystone/latest/contributor/service-catalog.html",children:"Integrate into the service catalog of Keystone"})," ",(0,r.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>d});var n=s(96540);const r={},i=n.createContext(r);function a(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/86ee3414.73e5b2c8.js b/assets/js/86ee3414.73e5b2c8.js new file mode 100644 index 0000000000..52c586b21e --- /dev/null +++ b/assets/js/86ee3414.73e5b2c8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[63365],{59380:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"iaas/components/index","title":"Tools","description":"","source":"@site/docs/02-iaas/components/index.md","sourceDirName":"02-iaas/components","slug":"/iaas/components/","permalink":"/docs/iaas/components/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/index.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Tools","sidebar_position":10}}');var s=n(74848),r=n(28453);const i={sidebar_label:"Tools",sidebar_position:10},a="Tools",c={},d=[];function l(e){const o={h1:"h1",header:"header",...(0,r.R)(),...e.components};return(0,s.jsx)(o.header,{children:(0,s.jsx)(o.h1,{id:"tools",children:"Tools"})})}function u(e={}){const{wrapper:o}={...(0,r.R)(),...e.components};return o?(0,s.jsx)(o,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,o,n)=>{n.d(o,{R:()=>i,x:()=>a});var t=n(96540);const s={},r=t.createContext(s);function i(e){const o=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function a(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(r.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/87086dc6.e66910db.js b/assets/js/87086dc6.e66910db.js new file mode 100644 index 0000000000..e62ccb84db --- /dev/null +++ b/assets/js/87086dc6.e66910db.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[54725],{31045:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"IaaS Layer","slug":"/category/iaas-layer","permalink":"/docs/category/iaas-layer","sidebar":"docs","navigation":{"previous":{"title":"Introduction","permalink":"/docs/"},"next":{"title":"Concept Guide","permalink":"/docs/iaas/guides/concept-guide/"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/87293620.8eba45f7.js b/assets/js/87293620.8eba45f7.js new file mode 100644 index 0000000000..6f56babd77 --- /dev/null +++ b/assets/js/87293620.8eba45f7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[44850],{19592:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"collaboration/sig-central-api","title":"SIG Central API","description":"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.","source":"@site/community/collaboration/sig-central-api.md","sourceDirName":"collaboration","slug":"/collaboration/sig-central-api","permalink":"/community/collaboration/sig-central-api","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Team Ops","permalink":"/community/collaboration/team-ops"},"next":{"title":"SIG Community","permalink":"/community/collaboration/sig-community"}}');var a=t(74848),r=t(28453);const i={},s="SIG Central API",c={},l=[];function u(e){const n={h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"sig-central-api",children:"SIG Central API"})}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.p,{children:"We want to define a single point of managment with consistent experience for managing the entire infrastructure."}),"\n",(0,a.jsx)(n.p,{children:"We aim to establish an unified and central interface that provides customers\nof the SCS clouds with the ability to manage cloud resources and/or services."}),"\n",(0,a.jsx)(n.p,{children:"SIG explores the possibilities for a central API by creating a MVP."})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>s});var o=t(96540);const a={},r=o.createContext(a);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/88146.59c80a39.js b/assets/js/88146.59c80a39.js new file mode 100644 index 0000000000..579ecbbcb8 --- /dev/null +++ b/assets/js/88146.59c80a39.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[88146],{88146:(t,e,a)=>{a.d(e,{a:()=>l,b:()=>B,c:()=>d,d:()=>I,e:()=>M,f:()=>j,g:()=>C,h:()=>A,i:()=>x,j:()=>N,k:()=>R,l:()=>o,m:()=>Y,p:()=>_,s:()=>T,u:()=>h});var r=a(86079),n=a(26312),i=a(9312);const s={extension:(t,e,a)=>{r.l.trace("Making markers for ",a),t.append("defs").append("marker").attr("id",a+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",a+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},composition:(t,e,a)=>{t.append("defs").append("marker").attr("id",a+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",a+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},aggregation:(t,e,a)=>{t.append("defs").append("marker").attr("id",a+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",a+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},dependency:(t,e,a)=>{t.append("defs").append("marker").attr("id",a+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",a+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},lollipop:(t,e,a)=>{t.append("defs").append("marker").attr("id",a+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",a+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},point:(t,e,a)=>{t.append("marker").attr("id",a+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",6).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",a+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},circle:(t,e,a)=>{t.append("marker").attr("id",a+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",a+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},cross:(t,e,a)=>{t.append("marker").attr("id",a+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",a+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},barb:(t,e,a)=>{t.append("defs").append("marker").attr("id",a+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")}},l=(t,e,a,r)=>{e.forEach((e=>{s[e](t,a,r)}))};const d=(t,e,a,i)=>{let s=t||"";if("object"==typeof s&&(s=s[0]),(0,r.m)((0,r.c)().flowchart.htmlLabels)){s=s.replace(/\\n|\n/g,"<br />"),r.l.debug("vertexText"+s);let t=function(t){const e=(0,n.Ltv)(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),a=e.append("xhtml:div"),r=t.label,i=t.isNode?"nodeLabel":"edgeLabel";var s,l;return a.html('<span class="'+i+'" '+(t.labelStyle?'style="'+t.labelStyle+'"':"")+">"+r+"</span>"),s=a,(l=t.labelStyle)&&s.attr("style",l),a.style("display","inline-block"),a.style("white-space","nowrap"),a.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}({isNode:i,label:(0,r.M)(s).replace(/fa[blrs]?:fa-[\w-]+/g,(t=>`<i class='${t.replace(":"," ")}'></i>`)),labelStyle:e.replace("fill:","color:")});return t}{const t=document.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("style",e.replace("color:","fill:"));let r=[];r="string"==typeof s?s.split(/\\n|\n|<br\s*\/?>/gi):Array.isArray(s)?s:[];for(const e of r){const r=document.createElementNS("http://www.w3.org/2000/svg","tspan");r.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),r.setAttribute("dy","1em"),r.setAttribute("x","0"),a?r.setAttribute("class","title-row"):r.setAttribute("class","row"),r.textContent=e.trim(),t.appendChild(r)}return t}},o=async(t,e,a,s)=>{let l;const o=e.useHtmlLabels||(0,r.m)((0,r.c)().flowchart.htmlLabels);l=a||"node default";const h=t.insert("g").attr("class",l).attr("id",e.domId||e.id),c=h.insert("g").attr("class","label").attr("style",e.labelStyle);let y;y=void 0===e.labelText?"":"string"==typeof e.labelText?e.labelText:e.labelText[0];const p=c.node();let g;g="markdown"===e.labelType?(0,i.a)(c,(0,r.d)((0,r.M)(y),(0,r.c)()),{useHtmlLabels:o,width:e.width||(0,r.c)().flowchart.wrappingWidth,classes:"markdown-node-label"}):p.appendChild(d((0,r.d)((0,r.M)(y),(0,r.c)()),e.labelStyle,!1,s));let x=g.getBBox();const f=e.padding/2;if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=g.children[0],e=(0,n.Ltv)(g),a=t.getElementsByTagName("img");if(a){const t=""===y.replace(/<img[^>]*>/g,"").trim();await Promise.all([...a].map((e=>new Promise((a=>{function n(){if(e.style.display="flex",e.style.flexDirection="column",t){const t=(0,r.c)().fontSize?(0,r.c)().fontSize:window.getComputedStyle(document.body).fontSize,a=5,n=parseInt(t,10)*a+"px";e.style.minWidth=n,e.style.maxWidth=n}else e.style.width="100%";a(e)}setTimeout((()=>{e.complete&&n()})),e.addEventListener("error",n),e.addEventListener("load",n)})))))}x=t.getBoundingClientRect(),e.attr("width",x.width),e.attr("height",x.height)}return o?c.attr("transform","translate("+-x.width/2+", "+-x.height/2+")"):c.attr("transform","translate(0, "+-x.height/2+")"),e.centerLabel&&c.attr("transform","translate("+-x.width/2+", "+-x.height/2+")"),c.insert("rect",":first-child"),{shapeSvg:h,bbox:x,halfPadding:f,label:c}},h=(t,e)=>{const a=e.node().getBBox();t.width=a.width,t.height=a.height};function c(t,e,a,r){return t.insert("polygon",":first-child").attr("points",r.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+a/2+")")}function y(t,e,a,r){var n=t.x,i=t.y,s=n-r.x,l=i-r.y,d=Math.sqrt(e*e*l*l+a*a*s*s),o=Math.abs(e*a*s/d);r.x<n&&(o=-o);var h=Math.abs(e*a*l/d);return r.y<i&&(h=-h),{x:n+o,y:i+h}}function p(t,e,a,r){var n,i,s,l,d,o,h,c,y,p,x,f,u;if(n=e.y-t.y,s=t.x-e.x,d=e.x*t.y-t.x*e.y,y=n*a.x+s*a.y+d,p=n*r.x+s*r.y+d,!(0!==y&&0!==p&&g(y,p)||(i=r.y-a.y,l=a.x-r.x,o=r.x*a.y-a.x*r.y,h=i*t.x+l*t.y+o,c=i*e.x+l*e.y+o,0!==h&&0!==c&&g(h,c)||0==(x=n*l-i*s))))return f=Math.abs(x/2),{x:(u=s*o-l*d)<0?(u-f)/x:(u+f)/x,y:(u=i*d-n*o)<0?(u-f)/x:(u+f)/x}}function g(t,e){return t*e>0}const x=(t,e)=>{var a,r,n=t.x,i=t.y,s=e.x-n,l=e.y-i,d=t.width/2,o=t.height/2;return Math.abs(l)*d>Math.abs(s)*o?(l<0&&(o=-o),a=0===l?0:o*s/l,r=o):(s<0&&(d=-d),a=d,r=0===s?0:d*l/s),{x:n+a,y:i+r}},f={node:function(t,e){return t.intersect(e)},circle:function(t,e,a){return y(t,e,e,a)},ellipse:y,polygon:function(t,e,a){var r=t.x,n=t.y,i=[],s=Number.POSITIVE_INFINITY,l=Number.POSITIVE_INFINITY;"function"==typeof e.forEach?e.forEach((function(t){s=Math.min(s,t.x),l=Math.min(l,t.y)})):(s=Math.min(s,e.x),l=Math.min(l,e.y));for(var d=r-t.width/2-s,o=n-t.height/2-l,h=0;h<e.length;h++){var c=e[h],y=e[h<e.length-1?h+1:0],g=p(t,a,{x:d+c.x,y:o+c.y},{x:d+y.x,y:o+y.y});g&&i.push(g)}return i.length?(i.length>1&&i.sort((function(t,e){var r=t.x-a.x,n=t.y-a.y,i=Math.sqrt(r*r+n*n),s=e.x-a.x,l=e.y-a.y,d=Math.sqrt(s*s+l*l);return i<d?-1:i===d?0:1})),i[0]):t},rect:x},u=(t,e,a)=>{const r=(t=>{const e=new Set;for(const a of t)switch(a){case"x":e.add("right"),e.add("left");break;case"y":e.add("up"),e.add("down");break;default:e.add(a)}return e})(t),n=e.height+2*a.padding,i=n/2,s=e.width+2*i+a.padding,l=a.padding/2;return r.has("right")&&r.has("left")&&r.has("up")&&r.has("down")?[{x:0,y:0},{x:i,y:0},{x:s/2,y:2*l},{x:s-i,y:0},{x:s,y:0},{x:s,y:-n/3},{x:s+2*l,y:-n/2},{x:s,y:-2*n/3},{x:s,y:-n},{x:s-i,y:-n},{x:s/2,y:-n-2*l},{x:i,y:-n},{x:0,y:-n},{x:0,y:-2*n/3},{x:-2*l,y:-n/2},{x:0,y:-n/3}]:r.has("right")&&r.has("left")&&r.has("up")?[{x:i,y:0},{x:s-i,y:0},{x:s,y:-n/2},{x:s-i,y:-n},{x:i,y:-n},{x:0,y:-n/2}]:r.has("right")&&r.has("left")&&r.has("down")?[{x:0,y:0},{x:i,y:-n},{x:s-i,y:-n},{x:s,y:0}]:r.has("right")&&r.has("up")&&r.has("down")?[{x:0,y:0},{x:s,y:-i},{x:s,y:-n+i},{x:0,y:-n}]:r.has("left")&&r.has("up")&&r.has("down")?[{x:s,y:0},{x:0,y:-i},{x:0,y:-n+i},{x:s,y:-n}]:r.has("right")&&r.has("left")?[{x:i,y:0},{x:i,y:-l},{x:s-i,y:-l},{x:s-i,y:0},{x:s,y:-n/2},{x:s-i,y:-n},{x:s-i,y:-n+l},{x:i,y:-n+l},{x:i,y:-n},{x:0,y:-n/2}]:r.has("up")&&r.has("down")?[{x:s/2,y:0},{x:0,y:-l},{x:i,y:-l},{x:i,y:-n+l},{x:0,y:-n+l},{x:s/2,y:-n},{x:s,y:-n+l},{x:s-i,y:-n+l},{x:s-i,y:-l},{x:s,y:-l}]:r.has("right")&&r.has("up")?[{x:0,y:0},{x:s,y:-i},{x:0,y:-n}]:r.has("right")&&r.has("down")?[{x:0,y:0},{x:s,y:0},{x:0,y:-n}]:r.has("left")&&r.has("up")?[{x:s,y:0},{x:0,y:-i},{x:s,y:-n}]:r.has("left")&&r.has("down")?[{x:s,y:0},{x:0,y:0},{x:s,y:-n}]:r.has("right")?[{x:i,y:-l},{x:i,y:-l},{x:s-i,y:-l},{x:s-i,y:0},{x:s,y:-n/2},{x:s-i,y:-n},{x:s-i,y:-n+l},{x:i,y:-n+l},{x:i,y:-n+l}]:r.has("left")?[{x:i,y:0},{x:i,y:-l},{x:s-i,y:-l},{x:s-i,y:-n+l},{x:i,y:-n+l},{x:i,y:-n},{x:0,y:-n/2}]:r.has("up")?[{x:i,y:-l},{x:i,y:-n+l},{x:0,y:-n+l},{x:s/2,y:-n},{x:s,y:-n+l},{x:s-i,y:-n+l},{x:s-i,y:-l}]:r.has("down")?[{x:s/2,y:0},{x:0,y:-l},{x:i,y:-l},{x:i,y:-n+l},{x:s-i,y:-n+l},{x:s-i,y:-l},{x:s,y:-l}]:[{x:0,y:0}]},w=t=>t?" "+t:"",b=(t,e)=>`${e||"node default"}${w(t.classes)} ${w(t.class)}`,m=async(t,e)=>{const{shapeSvg:a,bbox:n}=await o(t,e,b(e,void 0),!0),i=n.width+e.padding+(n.height+e.padding),s=[{x:i/2,y:0},{x:i,y:-i/2},{x:i/2,y:-i},{x:0,y:-i/2}];r.l.info("Question main (Circle)");const l=c(a,i,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return r.l.warn("Intersect called"),f.polygon(e,s,t)},a};function k(t,e,a,n){const i=[],s=t=>{i.push(t,0)},l=t=>{i.push(0,t)};e.includes("t")?(r.l.debug("add top border"),s(a)):l(a),e.includes("r")?(r.l.debug("add right border"),s(n)):l(n),e.includes("b")?(r.l.debug("add bottom border"),s(a)):l(a),e.includes("l")?(r.l.debug("add left border"),s(n)):l(n),t.attr("stroke-dasharray",i.join(" "))}const v=(t,e,a)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id);let n=70,i=10;"LR"===a&&(n=10,i=70);const s=r.append("rect").attr("x",-1*n/2).attr("y",-1*i/2).attr("width",n).attr("height",i).attr("class","fork-join");return h(e,s),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(t){return f.rect(e,t)},r},L={rhombus:m,composite:async(t,e)=>{const{shapeSvg:a,bbox:n,halfPadding:i}=await o(t,e,"node "+e.classes,!0),s=a.insert("rect",":first-child"),l=e.positioned?e.width:n.width+e.padding,d=e.positioned?e.height:n.height+e.padding,c=e.positioned?-l/2:-n.width/2-i,y=e.positioned?-d/2:-n.height/2-i;if(s.attr("class","basic cluster composite label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",c).attr("y",y).attr("width",l).attr("height",d),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(k(s,e.props.borders,l,d),t.delete("borders")),t.forEach((t=>{r.l.warn(`Unknown node property ${t}`)}))}return h(e,s),e.intersect=function(t){return f.rect(e,t)},a},question:m,rect:async(t,e)=>{const{shapeSvg:a,bbox:n,halfPadding:i}=await o(t,e,"node "+e.classes+" "+e.class,!0),s=a.insert("rect",":first-child"),l=e.positioned?e.width:n.width+e.padding,d=e.positioned?e.height:n.height+e.padding,c=e.positioned?-l/2:-n.width/2-i,y=e.positioned?-d/2:-n.height/2-i;if(s.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",c).attr("y",y).attr("width",l).attr("height",d),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(k(s,e.props.borders,l,d),t.delete("borders")),t.forEach((t=>{r.l.warn(`Unknown node property ${t}`)}))}return h(e,s),e.intersect=function(t){return f.rect(e,t)},a},labelRect:async(t,e)=>{const{shapeSvg:a}=await o(t,e,"label",!0);r.l.trace("Classes = ",e.class);const n=a.insert("rect",":first-child");if(n.attr("width",0).attr("height",0),a.attr("class","label edgeLabel"),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(k(n,e.props.borders,0,0),t.delete("borders")),t.forEach((t=>{r.l.warn(`Unknown node property ${t}`)}))}return h(e,n),e.intersect=function(t){return f.rect(e,t)},a},rectWithTitle:(t,e)=>{let a;a=e.classes?"node "+e.classes:"node default";const i=t.insert("g").attr("class",a).attr("id",e.domId||e.id),s=i.insert("rect",":first-child"),l=i.insert("line"),o=i.insert("g").attr("class","label"),c=e.labelText.flat?e.labelText.flat():e.labelText;let y="";y="object"==typeof c?c[0]:c,r.l.info("Label text abc79",y,c,"object"==typeof c);const p=o.node().appendChild(d(y,e.labelStyle,!0,!0));let g={width:0,height:0};if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=p.children[0],e=(0,n.Ltv)(p);g=t.getBoundingClientRect(),e.attr("width",g.width),e.attr("height",g.height)}r.l.info("Text 2",c);const x=c.slice(1,c.length);let u=p.getBBox();const w=o.node().appendChild(d(x.join?x.join("<br/>"):x,e.labelStyle,!0,!0));if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=w.children[0],e=(0,n.Ltv)(w);g=t.getBoundingClientRect(),e.attr("width",g.width),e.attr("height",g.height)}const b=e.padding/2;return(0,n.Ltv)(w).attr("transform","translate( "+(g.width>u.width?0:(u.width-g.width)/2)+", "+(u.height+b+5)+")"),(0,n.Ltv)(p).attr("transform","translate( "+(g.width<u.width?0:-(u.width-g.width)/2)+", 0)"),g=o.node().getBBox(),o.attr("transform","translate("+-g.width/2+", "+(-g.height/2-b+3)+")"),s.attr("class","outer title-state").attr("x",-g.width/2-b).attr("y",-g.height/2-b).attr("width",g.width+e.padding).attr("height",g.height+e.padding),l.attr("class","divider").attr("x1",-g.width/2-b).attr("x2",g.width/2+b).attr("y1",-g.height/2-b+u.height+b).attr("y2",-g.height/2-b+u.height+b),h(e,s),e.intersect=function(t){return f.rect(e,t)},i},choice:(t,e)=>{const a=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),r=[{x:0,y:14},{x:14,y:0},{x:0,y:-14},{x:-14,y:0}];return a.insert("polygon",":first-child").attr("points",r.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),e.width=28,e.height=28,e.intersect=function(t){return f.circle(e,14,t)},a},circle:async(t,e)=>{const{shapeSvg:a,bbox:n,halfPadding:i}=await o(t,e,b(e,void 0),!0),s=a.insert("circle",":first-child");return s.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),r.l.info("Circle main"),h(e,s),e.intersect=function(t){return r.l.info("Circle intersect",e,n.width/2+i,t),f.circle(e,n.width/2+i,t)},a},doublecircle:async(t,e)=>{const{shapeSvg:a,bbox:n,halfPadding:i}=await o(t,e,b(e,void 0),!0),s=a.insert("g",":first-child"),l=s.insert("circle"),d=s.insert("circle");return s.attr("class",e.class),l.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i+5).attr("width",n.width+e.padding+10).attr("height",n.height+e.padding+10),d.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),r.l.info("DoubleCircle main"),h(e,l),e.intersect=function(t){return r.l.info("DoubleCircle intersect",e,n.width/2+i+5,t),f.circle(e,n.width/2+i+5,t)},a},stadium:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.height+e.padding,i=r.width+n/4+e.padding,s=a.insert("rect",":first-child").attr("style",e.style).attr("rx",n/2).attr("ry",n/2).attr("x",-i/2).attr("y",-n/2).attr("width",i).attr("height",n);return h(e,s),e.intersect=function(t){return f.rect(e,t)},a},hexagon:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.height+e.padding,i=n/4,s=r.width+2*i+e.padding,l=[{x:i,y:0},{x:s-i,y:0},{x:s,y:-n/2},{x:s-i,y:-n},{x:i,y:-n},{x:0,y:-n/2}],d=c(a,s,n,l);return d.attr("style",e.style),h(e,d),e.intersect=function(t){return f.polygon(e,l,t)},a},block_arrow:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,void 0,!0),n=r.height+2*e.padding,i=n/2,s=r.width+2*i+e.padding,l=u(e.directions,r,e),d=c(a,s,n,l);return d.attr("style",e.style),h(e,d),e.intersect=function(t){return f.polygon(e,l,t)},a},rect_left_inv_arrow:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:-i/2,y:0},{x:n,y:0},{x:n,y:-i},{x:-i/2,y:-i},{x:0,y:-i/2}];return c(a,n,i,s).attr("style",e.style),e.width=n+i,e.height=i,e.intersect=function(t){return f.polygon(e,s,t)},a},lean_right:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:-2*i/6,y:0},{x:n-i/6,y:0},{x:n+2*i/6,y:-i},{x:i/6,y:-i}],l=c(a,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return f.polygon(e,s,t)},a},lean_left:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:2*i/6,y:0},{x:n+i/6,y:0},{x:n-2*i/6,y:-i},{x:-i/6,y:-i}],l=c(a,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return f.polygon(e,s,t)},a},trapezoid:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:-2*i/6,y:0},{x:n+2*i/6,y:0},{x:n-i/6,y:-i},{x:i/6,y:-i}],l=c(a,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return f.polygon(e,s,t)},a},inv_trapezoid:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:i/6,y:0},{x:n-i/6,y:0},{x:n+2*i/6,y:-i},{x:-2*i/6,y:-i}],l=c(a,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return f.polygon(e,s,t)},a},rect_right_inv_arrow:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:0,y:0},{x:n+i/2,y:0},{x:n,y:-i/2},{x:n+i/2,y:-i},{x:0,y:-i}],l=c(a,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return f.polygon(e,s,t)},a},cylinder:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=n/2,s=i/(2.5+n/50),l=r.height+s+e.padding,d="M 0,"+s+" a "+i+","+s+" 0,0,0 "+n+" 0 a "+i+","+s+" 0,0,0 "+-n+" 0 l 0,"+l+" a "+i+","+s+" 0,0,0 "+n+" 0 l 0,"+-l,c=a.attr("label-offset-y",s).insert("path",":first-child").attr("style",e.style).attr("d",d).attr("transform","translate("+-n/2+","+-(l/2+s)+")");return h(e,c),e.intersect=function(t){const a=f.rect(e,t),r=a.x-e.x;if(0!=i&&(Math.abs(r)<e.width/2||Math.abs(r)==e.width/2&&Math.abs(a.y-e.y)>e.height/2-s)){let n=s*s*(1-r*r/(i*i));0!=n&&(n=Math.sqrt(n)),n=s-n,t.y-e.y>0&&(n=-n),a.y+=n}return a},a},start:(t,e)=>{const a=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),r=a.insert("circle",":first-child");return r.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),h(e,r),e.intersect=function(t){return f.circle(e,7,t)},a},end:(t,e)=>{const a=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),r=a.insert("circle",":first-child"),n=a.insert("circle",":first-child");return n.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),r.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),h(e,n),e.intersect=function(t){return f.circle(e,7,t)},a},note:async(t,e)=>{e.useHtmlLabels||(0,r.c)().flowchart.htmlLabels||(e.centerLabel=!0);const{shapeSvg:a,bbox:n,halfPadding:i}=await o(t,e,"node "+e.classes,!0);r.l.info("Classes = ",e.classes);const s=a.insert("rect",":first-child");return s.attr("rx",e.rx).attr("ry",e.ry).attr("x",-n.width/2-i).attr("y",-n.height/2-i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),h(e,s),e.intersect=function(t){return f.rect(e,t)},a},subroutine:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:0,y:0},{x:n,y:0},{x:n,y:-i},{x:0,y:-i},{x:0,y:0},{x:-8,y:0},{x:n+8,y:0},{x:n+8,y:-i},{x:-8,y:-i},{x:-8,y:0}],l=c(a,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return f.polygon(e,s,t)},a},fork:v,join:v,class_box:(t,e)=>{const a=e.padding/2;let i;i=e.classes?"node "+e.classes:"node default";const s=t.insert("g").attr("class",i).attr("id",e.domId||e.id),l=s.insert("rect",":first-child"),o=s.insert("line"),c=s.insert("line");let y=0,p=4;const g=s.insert("g").attr("class","label");let x=0;const u=e.classData.annotations&&e.classData.annotations[0],w=e.classData.annotations[0]?"\xab"+e.classData.annotations[0]+"\xbb":"",b=g.node().appendChild(d(w,e.labelStyle,!0,!0));let m=b.getBBox();if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=b.children[0],e=(0,n.Ltv)(b);m=t.getBoundingClientRect(),e.attr("width",m.width),e.attr("height",m.height)}e.classData.annotations[0]&&(p+=m.height+4,y+=m.width);let k=e.classData.label;void 0!==e.classData.type&&""!==e.classData.type&&((0,r.c)().flowchart.htmlLabels?k+="<"+e.classData.type+">":k+="<"+e.classData.type+">");const v=g.node().appendChild(d(k,e.labelStyle,!0,!0));(0,n.Ltv)(v).attr("class","classTitle");let L=v.getBBox();if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=v.children[0],e=(0,n.Ltv)(v);L=t.getBoundingClientRect(),e.attr("width",L.width),e.attr("height",L.height)}p+=L.height+4,L.width>y&&(y=L.width);const S=[];e.classData.members.forEach((t=>{const a=t.getDisplayDetails();let i=a.displayText;(0,r.c)().flowchart.htmlLabels&&(i=i.replace(/</g,"<").replace(/>/g,">"));const s=g.node().appendChild(d(i,a.cssStyle?a.cssStyle:e.labelStyle,!0,!0));let l=s.getBBox();if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=s.children[0],e=(0,n.Ltv)(s);l=t.getBoundingClientRect(),e.attr("width",l.width),e.attr("height",l.height)}l.width>y&&(y=l.width),p+=l.height+4,S.push(s)})),p+=8;const M=[];if(e.classData.methods.forEach((t=>{const a=t.getDisplayDetails();let i=a.displayText;(0,r.c)().flowchart.htmlLabels&&(i=i.replace(/</g,"<").replace(/>/g,">"));const s=g.node().appendChild(d(i,a.cssStyle?a.cssStyle:e.labelStyle,!0,!0));let l=s.getBBox();if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=s.children[0],e=(0,n.Ltv)(s);l=t.getBoundingClientRect(),e.attr("width",l.width),e.attr("height",l.height)}l.width>y&&(y=l.width),p+=l.height+4,M.push(s)})),p+=8,u){let t=(y-m.width)/2;(0,n.Ltv)(b).attr("transform","translate( "+(-1*y/2+t)+", "+-1*p/2+")"),x=m.height+4}let T=(y-L.width)/2;return(0,n.Ltv)(v).attr("transform","translate( "+(-1*y/2+T)+", "+(-1*p/2+x)+")"),x+=L.height+4,o.attr("class","divider").attr("x1",-y/2-a).attr("x2",y/2+a).attr("y1",-p/2-a+8+x).attr("y2",-p/2-a+8+x),x+=8,S.forEach((t=>{(0,n.Ltv)(t).attr("transform","translate( "+-y/2+", "+(-1*p/2+x+4)+")");const e=null==t?void 0:t.getBBox();x+=((null==e?void 0:e.height)??0)+4})),x+=8,c.attr("class","divider").attr("x1",-y/2-a).attr("x2",y/2+a).attr("y1",-p/2-a+8+x).attr("y2",-p/2-a+8+x),x+=8,M.forEach((t=>{(0,n.Ltv)(t).attr("transform","translate( "+-y/2+", "+(-1*p/2+x)+")");const e=null==t?void 0:t.getBBox();x+=((null==e?void 0:e.height)??0)+4})),l.attr("style",e.style).attr("class","outer title-state").attr("x",-y/2-a).attr("y",-p/2-a).attr("width",y+e.padding).attr("height",p+e.padding),h(e,l),e.intersect=function(t){return f.rect(e,t)},s}};let S={};const M=async(t,e,a)=>{let n,i;if(e.link){let s;"sandbox"===(0,r.c)().securityLevel?s="_top":e.linkTarget&&(s=e.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",e.link).attr("target",s),i=await L[e.shape](n,e,a)}else i=await L[e.shape](t,e,a),n=i;return e.tooltip&&i.attr("title",e.tooltip),e.class&&i.attr("class","node default "+e.class),n.attr("data-node","true"),n.attr("data-id",e.id),S[e.id]=n,e.haveCallback&&S[e.id].attr("class",S[e.id].attr("class")+" clickable"),n},T=(t,e)=>{S[e.id]=t},B=()=>{S={}},_=t=>{const e=S[t.id];r.l.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");const a=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+a-t.width/2)+", "+(t.y-t.height/2-8)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),a},C=({flowchart:t})=>{var e,a;const r=(null==(e=null==t?void 0:t.subGraphTitleMargin)?void 0:e.top)??0,n=(null==(a=null==t?void 0:t.subGraphTitleMargin)?void 0:a.bottom)??0;return{subGraphTitleTopMargin:r,subGraphTitleBottomMargin:n,subGraphTitleTotalMargin:r+n}},E={aggregation:18,extension:18,composition:18,dependency:6,lollipop:13.5,arrow_point:5.3};function $(t,e){if(void 0===t||void 0===e)return{angle:0,deltaX:0,deltaY:0};t=P(t),e=P(e);const[a,r]=[t.x,t.y],[n,i]=[e.x,e.y],s=n-a,l=i-r;return{angle:Math.atan(l/s),deltaX:s,deltaY:l}}const P=t=>Array.isArray(t)?{x:t[0],y:t[1]}:t,R=t=>({x:function(e,a,r){let n=0;if(0===a&&Object.hasOwn(E,t.arrowTypeStart)){const{angle:e,deltaX:a}=$(r[0],r[1]);n=E[t.arrowTypeStart]*Math.cos(e)*(a>=0?1:-1)}else if(a===r.length-1&&Object.hasOwn(E,t.arrowTypeEnd)){const{angle:e,deltaX:a}=$(r[r.length-1],r[r.length-2]);n=E[t.arrowTypeEnd]*Math.cos(e)*(a>=0?1:-1)}return P(e).x+n},y:function(e,a,r){let n=0;if(0===a&&Object.hasOwn(E,t.arrowTypeStart)){const{angle:e,deltaY:a}=$(r[0],r[1]);n=E[t.arrowTypeStart]*Math.abs(Math.sin(e))*(a>=0?1:-1)}else if(a===r.length-1&&Object.hasOwn(E,t.arrowTypeEnd)){const{angle:e,deltaY:a}=$(r[r.length-1],r[r.length-2]);n=E[t.arrowTypeEnd]*Math.abs(Math.sin(e))*(a>=0?1:-1)}return P(e).y+n}}),Y=(t,e,a,r,n)=>{e.arrowTypeStart&&W(t,"start",e.arrowTypeStart,a,r,n),e.arrowTypeEnd&&W(t,"end",e.arrowTypeEnd,a,r,n)},O={arrow_cross:"cross",arrow_point:"point",arrow_barb:"barb",arrow_circle:"circle",aggregation:"aggregation",extension:"extension",composition:"composition",dependency:"dependency",lollipop:"lollipop"},W=(t,e,a,n,i,s)=>{const l=O[a];if(!l)return void r.l.warn(`Unknown arrow type: ${a}`);const d="start"===e?"Start":"End";t.attr(`marker-${e}`,`url(${n}#${i}_${s}-${l}${d})`)};let X={},H={};const I=()=>{X={},H={}},j=(t,e)=>{const a=(0,r.m)((0,r.c)().flowchart.htmlLabels),s="markdown"===e.labelType?(0,i.a)(t,e.label,{style:e.labelStyle,useHtmlLabels:a,addSvgBackground:!0}):d(e.label,e.labelStyle),l=t.insert("g").attr("class","edgeLabel"),o=l.insert("g").attr("class","label");o.node().appendChild(s);let h,c=s.getBBox();if(a){const t=s.children[0],e=(0,n.Ltv)(s);c=t.getBoundingClientRect(),e.attr("width",c.width),e.attr("height",c.height)}if(o.attr("transform","translate("+-c.width/2+", "+-c.height/2+")"),X[e.id]=l,e.width=c.width,e.height=c.height,e.startLabelLeft){const a=d(e.startLabelLeft,e.labelStyle),r=t.insert("g").attr("class","edgeTerminals"),n=r.insert("g").attr("class","inner");h=n.node().appendChild(a);const i=a.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),H[e.id]||(H[e.id]={}),H[e.id].startLeft=r,D(h,e.startLabelLeft)}if(e.startLabelRight){const a=d(e.startLabelRight,e.labelStyle),r=t.insert("g").attr("class","edgeTerminals"),n=r.insert("g").attr("class","inner");h=r.node().appendChild(a),n.node().appendChild(a);const i=a.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),H[e.id]||(H[e.id]={}),H[e.id].startRight=r,D(h,e.startLabelRight)}if(e.endLabelLeft){const a=d(e.endLabelLeft,e.labelStyle),r=t.insert("g").attr("class","edgeTerminals"),n=r.insert("g").attr("class","inner");h=n.node().appendChild(a);const i=a.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),r.node().appendChild(a),H[e.id]||(H[e.id]={}),H[e.id].endLeft=r,D(h,e.endLabelLeft)}if(e.endLabelRight){const a=d(e.endLabelRight,e.labelStyle),r=t.insert("g").attr("class","edgeTerminals"),n=r.insert("g").attr("class","inner");h=n.node().appendChild(a);const i=a.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),r.node().appendChild(a),H[e.id]||(H[e.id]={}),H[e.id].endRight=r,D(h,e.endLabelRight)}return s};function D(t,e){(0,r.c)().flowchart.htmlLabels&&t&&(t.style.width=9*e.length+"px",t.style.height="12px")}const N=(t,e)=>{r.l.debug("Moving label abc88 ",t.id,t.label,X[t.id],e);let a=e.updatedPath?e.updatedPath:e.originalPath;const n=(0,r.c)(),{subGraphTitleTotalMargin:i}=C(n);if(t.label){const n=X[t.id];let s=t.x,l=t.y;if(a){const n=r.u.calcLabelPosition(a);r.l.debug("Moving label "+t.label+" from (",s,",",l,") to (",n.x,",",n.y,") abc88"),e.updatedPath&&(s=n.x,l=n.y)}n.attr("transform",`translate(${s}, ${l+i/2})`)}if(t.startLabelLeft){const e=H[t.id].startLeft;let n=t.x,i=t.y;if(a){const e=r.u.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",a);n=e.x,i=e.y}e.attr("transform",`translate(${n}, ${i})`)}if(t.startLabelRight){const e=H[t.id].startRight;let n=t.x,i=t.y;if(a){const e=r.u.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",a);n=e.x,i=e.y}e.attr("transform",`translate(${n}, ${i})`)}if(t.endLabelLeft){const e=H[t.id].endLeft;let n=t.x,i=t.y;if(a){const e=r.u.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",a);n=e.x,i=e.y}e.attr("transform",`translate(${n}, ${i})`)}if(t.endLabelRight){const e=H[t.id].endRight;let n=t.x,i=t.y;if(a){const e=r.u.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",a);n=e.x,i=e.y}e.attr("transform",`translate(${n}, ${i})`)}},U=(t,e)=>{r.l.debug("abc88 cutPathAtIntersect",t,e);let a=[],n=t[0],i=!1;return t.forEach((t=>{if(((t,e)=>{const a=t.x,r=t.y,n=Math.abs(e.x-a),i=Math.abs(e.y-r),s=t.width/2,l=t.height/2;return n>=s||i>=l})(e,t)||i)n=t,i||a.push(t);else{const s=((t,e,a)=>{r.l.debug(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(e)}\n insidePoint : ${JSON.stringify(a)}\n node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);const n=t.x,i=t.y,s=Math.abs(n-a.x),l=t.width/2;let d=a.x<e.x?l-s:l+s;const o=t.height/2,h=Math.abs(e.y-a.y),c=Math.abs(e.x-a.x);if(Math.abs(i-e.y)*l>Math.abs(n-e.x)*o){let t=a.y<e.y?e.y-o-i:i-o-e.y;d=c*t/h;const n={x:a.x<e.x?a.x+d:a.x-c+d,y:a.y<e.y?a.y+h-t:a.y-h+t};return 0===d&&(n.x=e.x,n.y=e.y),0===c&&(n.x=e.x),0===h&&(n.y=e.y),r.l.debug(`abc89 topp/bott calc, Q ${h}, q ${t}, R ${c}, r ${d}`,n),n}{d=a.x<e.x?e.x-l-n:n-l-e.x;let t=h*d/c,i=a.x<e.x?a.x+c-d:a.x-c+d,s=a.y<e.y?a.y+t:a.y-t;return r.l.debug(`sides calc abc89, Q ${h}, q ${t}, R ${c}, r ${d}`,{_x:i,_y:s}),0===d&&(i=e.x,s=e.y),0===c&&(i=e.x),0===h&&(s=e.y),{x:i,y:s}}})(e,n,t);let l=!1;a.forEach((t=>{l=l||t.x===s.x&&t.y===s.y})),a.some((t=>t.x===s.x&&t.y===s.y))||a.push(s),i=!0}})),a},A=function(t,e,a,i,s,l,d){let o=a.points;r.l.debug("abc88 InsertEdge: edge=",a,"e=",e);let h=!1;const c=l.node(e.v);var y=l.node(e.w);(null==y?void 0:y.intersect)&&(null==c?void 0:c.intersect)&&(o=o.slice(1,a.points.length-1),o.unshift(c.intersect(o[0])),o.push(y.intersect(o[o.length-1]))),a.toCluster&&(r.l.debug("to cluster abc88",i[a.toCluster]),o=U(a.points,i[a.toCluster].node),h=!0),a.fromCluster&&(r.l.debug("from cluster abc88",i[a.fromCluster]),o=U(o.reverse(),i[a.fromCluster].node).reverse(),h=!0);const p=o.filter((t=>!Number.isNaN(t.y)));let g=n.qrM;!a.curve||"graph"!==s&&"flowchart"!==s||(g=a.curve);const{x:x,y:f}=R(a),u=(0,n.n8j)().x(x).y(f).curve(g);let w;switch(a.thickness){case"normal":w="edge-thickness-normal";break;case"thick":case"invisible":w="edge-thickness-thick";break;default:w=""}switch(a.pattern){case"solid":w+=" edge-pattern-solid";break;case"dotted":w+=" edge-pattern-dotted";break;case"dashed":w+=" edge-pattern-dashed"}const b=t.append("path").attr("d",u(p)).attr("id",a.id).attr("class"," "+w+(a.classes?" "+a.classes:"")).attr("style",a.style);let m="";((0,r.c)().flowchart.arrowMarkerAbsolute||(0,r.c)().state.arrowMarkerAbsolute)&&(m=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,m=m.replace(/\(/g,"\\("),m=m.replace(/\)/g,"\\)")),Y(b,a,m,d,s);let k={};return h&&(k.updatedPath=o),k.originalPath=a.points,k}}}]); \ No newline at end of file diff --git a/assets/js/88684b71.89e9c6a0.js b/assets/js/88684b71.89e9c6a0.js new file mode 100644 index 0000000000..b4d2a413c6 --- /dev/null +++ b/assets/js/88684b71.89e9c6a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[22151],{50652:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"iaas/components/flavor-manager","title":"Flavor Manager","description":"Overview","source":"@site/docs/02-iaas/components/flavor-manager.md","sourceDirName":"02-iaas/components","slug":"/iaas/components/flavor-manager","permalink":"/docs/iaas/components/flavor-manager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/flavor-manager.md","tags":[],"version":"current","sidebarPosition":51,"frontMatter":{"sidebar_label":"Flavor Manager","sidebar_position":51},"sidebar":"docs","previous":{"title":"Automated updates","permalink":"/docs/iaas/components/image-manager/update"},"next":{"title":"Deployment Examples","permalink":"/docs/category/deployment-examples"}}');var r=a(74848),o=a(28453);const i={sidebar_label:"Flavor Manager",sidebar_position:51},t="Flavor Manager",d={},l=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Usage",id:"usage",level:2},{value:"Definitions",id:"definitions",level:2},{value:"Name parser and generator",id:"name-parser-and-generator",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"flavor-manager",children:"Flavor Manager"})}),"\n",(0,r.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,r.jsxs)(n.p,{children:["The OpenStack Flavor Manager manages the creation, modification, and removal of flavors.\nIt operates as a facilitator that orchestrates compute flavors in alignment\nwith the standard ",(0,r.jsx)(n.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS-0100: Flavor Naming"}),"\nby utilizing YAML files provided by the SCS project."]}),"\n",(0,r.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,r.jsxs)(n.p,{children:["The OpenStack Flavor Manager can be used via the OSISM CLI. This is the preferred way to use it.\nNo installation is then required. It is used via ",(0,r.jsx)(n.code,{children:"osism manage flavors"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["For use independent of OSISM install the ",(0,r.jsx)(n.code,{children:"openstack-flavor-manager"})," package with pip. It is likely\nthat additional dependencies such as ",(0,r.jsx)(n.code,{children:"pkg-config"})," or ",(0,r.jsx)(n.code,{children:"libssl-dev"})," must be installed in advance."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ pip install openstack-flavor-manager\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Or clone the repository ",(0,r.jsx)(n.a,{href:"https://github.com/osism/openstack-flavor-manager",children:"osism/openstack-flavor-manager"}),"\nand use the OpenStack Flavor Manager from source with tox."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ tox -- --help\n"})}),"\n",(0,r.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,r.jsxs)(n.p,{children:["There must be a ",(0,r.jsx)(n.code,{children:"clouds.yml"})," and a ",(0,r.jsx)(n.code,{children:"secure.yml"})," file in the directory where the OpenStack Flavor Manager\nwill be executed. When using the OSISM CLI, the files are expected in ",(0,r.jsx)(n.code,{children:"environments/openstack"}),"\nin your configuration repository."]}),"\n",(0,r.jsxs)(n.p,{children:["The cloud profile to be used can be specified via the optional ",(0,r.jsx)(n.code,{children:"--cloud"})," parameter.\nBy default the cloud profile with the name ",(0,r.jsx)(n.code,{children:"admin"})," is used. It must be possible to create and delete\nflavors with the used cloud credentials."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ openstack-flavor-manager --help\n\n Usage: openstack-flavor-manager [OPTIONS]\n\n\u256d\u2500 Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 --name TEXT Name of flavor definitions. [default: scs] \u2502\n\u2502 --debug Enable debug logging. \u2502\n\u2502 --cloud TEXT Cloud name in clouds.yaml. [default: admin] \u2502\n\u2502 --recommended Create recommended flavors. \u2502\n\u2502 --help Show this message and exit. \u2502\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n"})}),"\n",(0,r.jsxs)(n.p,{children:["To create the mandatory flavors by the ",(0,r.jsx)(n.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS-0100: Flavor Naming"}),"\nstandard, you run:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ openstack-flavor-manager\n"})}),"\n",(0,r.jsx)(n.p,{children:"To create the recommended flavors by the SCS Flavor Naming Standard, you run:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ openstack-flavor-manager --recommended\n"})}),"\n",(0,r.jsx)(n.p,{children:"The output should look like this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"2023-09-20 13:03:14 | INFO | Flavor SCS-1V-4 created\n2023-09-20 13:03:14 | INFO | Flavor SCS-2V-8 created\n2023-09-20 13:03:14 | INFO | Flavor SCS-4V-16 created\n2023-09-20 13:03:14 | INFO | Flavor SCS-8V-32 created\n...\n"})}),"\n",(0,r.jsx)(n.p,{children:"All recommended flavors are now be available in your OpenStack environment.\nCheck yourself by running:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ openstack --os-cloud admin flavor list\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ openstack --os-cloud admin flavor show SCS-2V-4-20s\n+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+\n| Field | Value |\n+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+\n| OS-FLV-DISABLED:disabled | False |\n| OS-FLV-EXT-DATA:ephemeral | 0 |\n| access_project_ids | None |\n| description | None |\n| disk | 20 |\n| id | 652e3a6c-330e-4ee3-922b-b49c3c093062 |\n| name | SCS-2V-4-20s |\n| os-flavor-access:is_public | True |\n| properties | hw_rng:allowed='true', scs:cpu-type='shared-core', scs:disk0-type='ssd', scs:name-v1='SCS-2V:4:20s', scs:name-v2='SCS-2V-4-20s' |\n| ram | 4096 |\n| rxtx_factor | 1.0 |\n| swap | 0 |\n| vcpus | 2 |\n+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+\n"})}),"\n",(0,r.jsx)(n.h2,{id:"definitions",children:"Definitions"}),"\n",(0,r.jsxs)(n.p,{children:["There are two flavor definitions available by default. One for\n",(0,r.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/iaas/SCS-Spec.MandatoryFlavors.verbose.yaml",children:"SCS"}),"\nand one for ",(0,r.jsx)(n.a,{href:"https://raw.githubusercontent.com/osism/openstack-flavor-manager/main/flavors.yaml",children:"OSISM"}),".\nEach definition has its own set of mandatory and recommended flavors. The definition of OSISM contains\nall definitions of SCS as well as some others."]}),"\n",(0,r.jsxs)(n.p,{children:["To run the OpenStack Flavor Manager with a specific definition, either ",(0,r.jsx)(n.code,{children:"scs"})," or ",(0,r.jsx)(n.code,{children:"osism"}),",\nuse the optional ",(0,r.jsx)(n.code,{children:"--name"})," parameter. By default the ",(0,r.jsx)(n.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS-0100: Flavor Naming"}),"\nstandard definition will be used."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ openstack-flavor-manager --name osism\n"})}),"\n",(0,r.jsx)(n.h2,{id:"name-parser-and-generator",children:"Name parser and generator"}),"\n",(0,r.jsxs)(n.p,{children:["A generator and parser for flavor names according to the SCS standard is available on\n",(0,r.jsx)(n.a,{href:"https://flavors.scs.community",children:"flavors.scs.community"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The flavor name ",(0,r.jsx)(n.code,{children:"SCS-2V-4-20s"})," is inserted in field ",(0,r.jsx)(n.code,{children:"Flavor name"}),":"]}),"\n",(0,r.jsx)("img",{src:a(77215).A,width:"50%"}),"\n",(0,r.jsxs)(n.p,{children:["The flavor ",(0,r.jsx)(n.code,{children:"SCS-2V-4-20s"})," translated is\n",(0,r.jsx)(n.code,{children:"2 generic x86-64 vCPUs with 4.0 GiB RAM and SSD 20GB root volume"}),":"]}),"\n",(0,r.jsx)("img",{src:a(91940).A,width:"50%"})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},77215:(e,n,a)=>{a.d(n,{A:()=>s});const s=a.p+"assets/images/flavors-1-bd8d085759b264b3e58020d1390803fd.png"},91940:(e,n,a)=>{a.d(n,{A:()=>s});const s=a.p+"assets/images/flavors-2-d9a87ab2a63ed62ace4303facc069b8b.png"},28453:(e,n,a)=>{a.d(n,{R:()=>i,x:()=>t});var s=a(96540);const r={},o=s.createContext(r);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/88f37d1b.f355f8d9.js b/assets/js/88f37d1b.f355f8d9.js new file mode 100644 index 0000000000..9cc8aa3541 --- /dev/null +++ b/assets/js/88f37d1b.f355f8d9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[96734],{57517:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>t,toc:()=>r});const t=JSON.parse('{"id":"iam/intra-SCS-federation-setup-description-for-osism-doc-operations","title":"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)","description":"The followig section is a reasonably detailed hands on description of how","source":"@site/docs/05-iam/intra-SCS-federation-setup-description-for-osism-doc-operations.md","sourceDirName":"05-iam","slug":"/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","permalink":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/05-iam/intra-SCS-federation-setup-description-for-osism-doc-operations.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Example setup configuration in SCS deployment explained","permalink":"/docs/iam/SCS-example-setup-configuration-description"},"next":{"title":"Turnkey Solution","permalink":"/docs/category/turnkey-solution"}}');var i=n(74848),c=n(28453);const s={},a="Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)",d={},r=[{value:"Detailed tutorial on how to configure Federation (OpenID Connect) between two Keycloak instances in two separate SCS domains",id:"detailed-tutorial-on-how-to-configure-federation-openid-connect-between-two-keycloak-instances-in-two-separate-scs-domains",level:2}];function l(e){const o={code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",...(0,c.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(o.header,{children:(0,i.jsx)(o.h1,{id:"proposal-for-documentation-for-keycloak-to-keycloak-federation-websso",children:"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)"})}),"\n",(0,i.jsxs)(o.p,{children:["The followig section is a reasonably detailed hands on description of how\nto configure a federation between two separate SCS compliant domains by means\nof Keycloak ",(0,i.jsx)(o.code,{children:"Identity Brokering"}),". If we decide to use Keycloak as a component\nto allow self service by tenants, then this documentation may be a useful addition\nto some tenant facing documentation (or for the SCS operators too)."]}),"\n",(0,i.jsx)(o.p,{children:"OTOH one could probably also script pretty much everything of this to allow\ntenants to use a CLI tool to automate the setup. For that purpose the documentation\nmay be useful to guide the implementation of such a scripted solution."}),"\n",(0,i.jsx)(o.h2,{id:"detailed-tutorial-on-how-to-configure-federation-openid-connect-between-two-keycloak-instances-in-two-separate-scs-domains",children:"Detailed tutorial on how to configure Federation (OpenID Connect) between two Keycloak instances in two separate SCS domains"}),"\n",(0,i.jsxs)(o.p,{children:['Assume you have two CSPs using SCS. The first one wants to grant access to users of the other.\nSo let\'s call the first domain "resource domain" and the second one "accounts domain".\nBoth domains need to agree upon a name for the "OIDC RP" (which Keycloak calls ',(0,i.jsx)(o.code,{children:"Clients"}),').\nThe Keycloak in the "resource domain" will be the OIDC RP and the Keycloak in the "accounts domain" will be the OIDC OP.\nAssuming the "resource domain" is called ',(0,i.jsx)(o.code,{children:"foo"}),' and the "accounts domain" is called bar, the name for the "OIDC RP" could be ',(0,i.jsx)(o.code,{children:"oidc-rp-foo"}),"."]}),"\n",(0,i.jsxs)(o.ol,{children:["\n",(0,i.jsxs)(o.li,{children:["\n",(0,i.jsxs)(o.p,{children:["In the accounts domain (",(0,i.jsx)(o.code,{children:"bar"}),") open Keycloak realm ",(0,i.jsx)(o.code,{children:"osism"}),", click on ",(0,i.jsx)(o.code,{children:"Clients"})," in the sidebar and click on ",(0,i.jsx)(o.code,{children:"Create client"}),".\nLeave the client type as ",(0,i.jsx)(o.code,{children:"OpenID Connect"})," and enter the ",(0,i.jsx)(o.code,{children:"Client ID"}),", e.g. ",(0,i.jsx)(o.code,{children:"oidc-rp-foo"}),".\nTurn on ",(0,i.jsx)(o.code,{children:"Client authentication"})," for it and click ",(0,i.jsx)(o.code,{children:"Save"}),"."]}),"\n",(0,i.jsxs)(o.p,{children:["On the ",(0,i.jsx)(o.code,{children:"Client details"})," page open the tab ",(0,i.jsx)(o.code,{children:"Credentials"})," and copy the ",(0,i.jsx)(o.code,{children:"Client secret"}),'. Communicate this to the operato of the "resource domain" ',(0,i.jsx)(o.code,{children:"foo"})," via a secure channel."]}),"\n"]}),"\n",(0,i.jsxs)(o.li,{children:["\n",(0,i.jsxs)(o.p,{children:["In the resource domain (",(0,i.jsx)(o.code,{children:"foo"}),") open Keycloak realm ",(0,i.jsx)(o.code,{children:"osism"}),", click on ",(0,i.jsx)(o.code,{children:"Identity providers"}),"\nand create a new provider definition of type ",(0,i.jsx)(o.code,{children:"OpenID Connect v1.0"}),". As ",(0,i.jsx)(o.code,{children:"Alias"})," choose a name,\ne.g. ",(0,i.jsx)(o.code,{children:"oidc-op-bar"}),". Don't copy the ",(0,i.jsx)(o.code,{children:"Redirect URI"})," given at the top yet, because is will change depending\non the chosen ",(0,i.jsx)(o.code,{children:"Alias"}),". Instead, scroll down to the mandatory field ",(0,i.jsx)(o.code,{children:"Discovery endpoint"})," and paste\nthe OpenID Connect metadata URL of the KEycloak realm ",(0,i.jsx)(o.code,{children:"osism"}),' in the "accounts domain" (',(0,i.jsx)(o.code,{children:"bar"}),').\nThe operator of the "accounts domain" (',(0,i.jsx)(o.code,{children:"bar"}),") may easily copy that URL from the ",(0,i.jsx)(o.code,{children:"Realm Settins"})," in the\nsidebar of his Keycloak instance, where the ",(0,i.jsx)(o.code,{children:"Endpoints"})," are listed on the bottom of that form.\nThe URL may have the format ",(0,i.jsx)(o.code,{children:"https://bar.com/auth/realms/osism/.well-known/openid-configuration"}),".\nOnce you leave that input field, Keycloak will attempt to fetch the metadata and extract the required\ndetails about protocol enspoints from the retrieved document. If this shows an error, it will give you\nan HTTP status code. If this shows an error code of 500, then this may be caused by a failure in\ncertificate verification. In that case you may want to check the output of ",(0,i.jsx)(o.code,{children:"docker logs keycloak"})," for\njava stack traces. If you find any, the top of those stack traces may indicate what kind of problem\noccurred to the java code. From here we will assume that the emtadata URL could be fecthed without\nany issues."]}),"\n",(0,i.jsxs)(o.p,{children:["Now, go to the bottom of that form and insert tjhe ",(0,i.jsx)(o.code,{children:"Client ID"})," (",(0,i.jsx)(o.code,{children:"oidc-rp-foo"}),") and the\n",(0,i.jsx)(o.code,{children:"Client secret"}),' that was provided by the operator of the "accounts domain" (',(0,i.jsx)(o.code,{children:"bar"}),").\nFinally click on ",(0,i.jsx)(o.code,{children:"Add"}),". From the ",(0,i.jsx)(o.code,{children:"Provider Details"})," page on the top for the ",(0,i.jsx)(o.code,{children:"Settings"})," tab copy the value of the\n",(0,i.jsx)(o.code,{children:"Redirect URI"}),' and communicate it back to the operator of the "accounts domain" (',(0,i.jsx)(o.code,{children:"bar"}),")."]}),"\n"]}),"\n",(0,i.jsxs)(o.li,{children:["\n",(0,i.jsxs)(o.p,{children:["In the accounts domain (",(0,i.jsx)(o.code,{children:"bar"}),") open Keycloak realm ",(0,i.jsx)(o.code,{children:"osism"}),", click on ",(0,i.jsx)(o.code,{children:"Clients"})," in the sidebar and click\non the name of the OIDC RP clinent that you created for domain ",(0,i.jsx)(o.code,{children:"foo"})," (e.g. ",(0,i.jsx)(o.code,{children:"oidc-rp-foo"}),").\nOn the ",(0,i.jsx)(o.code,{children:"Client details"})," page on the tab ",(0,i.jsx)(o.code,{children:"Settings"})," fill in the field ",(0,i.jsx)(o.code,{children:"Valid redirect URIs"})," with the value\nobtained from the resource domain (",(0,i.jsx)(o.code,{children:"foo"}),"), which should look similar to\n",(0,i.jsx)(o.code,{children:"https://foo.com/auth/realms/osism/broker/oidc-op-bar/endpoint"}),". Additionally the\n",(0,i.jsx)(o.code,{children:"Valid post logout redirect URIs"})," need to be set to something like ",(0,i.jsx)(o.code,{children:"https://foo.com/auth/realms/osism/*"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(o.li,{children:["\n",(0,i.jsxs)(o.p,{children:['To test federated login in the "resource domain" (',(0,i.jsx)(o.code,{children:"foo"}),") open the URL of the Keycloak admin console for\nthe realm ",(0,i.jsx)(o.code,{children:"osism"}),": ",(0,i.jsx)(o.code,{children:"https://foo.com/auth/admin/osism/console"})," (or ",(0,i.jsx)(o.code,{children:"https://foo.com/auth/realms/osism/protocol/openid-connect/auth?client_id=security-admin-console"}),").\nIgnore the top section of the login form titled\n",(0,i.jsx)(o.code,{children:"Sign in to your account"})," and choose one of the OIDC OP federation choises below the line ",(0,i.jsx)(o.code,{children:"Or sign in with"}),".\nIn this example it would be ",(0,i.jsx)(o.code,{children:"oidc-op-bar"}),'. This should redirect your browser to the authentication endpoint\nof the "accounts domain" (',(0,i.jsx)(o.code,{children:"https://bar.com/auth/realms/osism/protocol/openid-connect/auth?scope=openid&..."}),')\nwhere you should be able to log in with credentials that are valid in the "accounts domain" (',(0,i.jsx)(o.code,{children:"bar"}),').\nAfter successull authentication your broser should be redirected to admin console of the "resource domain",\nwhich may offer you a "first login flow" form where you can choose a username, email, firstname and lastname.\nThe details depend on the ',(0,i.jsx)(o.code,{children:"Mappers"})," that have been configured for the Identity Provider ",(0,i.jsx)(o.code,{children:"oidc-op-bar"}),".\nAfter that you will be presented with a Keycloak themed page with the error message ",(0,i.jsx)(o.code,{children:"Request failed with status code 403"}),",\nwhich is normal because the test account is not authorized to access any elements of the Keycloak admin console."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:o}={...(0,c.R)(),...e.components};return o?(0,i.jsx)(o,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,o,n)=>{n.d(o,{R:()=>s,x:()=>a});var t=n(96540);const i={},c=t.createContext(i);function s(e){const o=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function a(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(c.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/89176cae.fc177988.js b/assets/js/89176cae.fc177988.js new file mode 100644 index 0000000000..65d26c92c8 --- /dev/null +++ b/assets/js/89176cae.fc177988.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[45673],{92895:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>s,toc:()=>i});const s=JSON.parse('{"id":"standards/index","title":"Standards","description":"TODO","source":"@site/docs/07-standards/index.md","sourceDirName":"07-standards","slug":"/standards/","permalink":"/docs/standards/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/07-standards/index.md","tags":[],"version":"current","frontMatter":{}}');var r=n(74848),d=n(28453);const a={},o="Standards",c={},i=[];function u(t){const e={h1:"h1",header:"header",p:"p",...(0,d.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"standards",children:"Standards"})}),"\n",(0,r.jsx)(e.p,{children:"TODO"})]})}function l(t={}){const{wrapper:e}={...(0,d.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(u,{...t})}):u(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>a,x:()=>o});var s=n(96540);const r={},d=s.createContext(r);function a(t){const e=s.useContext(d);return s.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function o(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:a(t.components),s.createElement(d.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/8989.29b1d9c8.js b/assets/js/8989.29b1d9c8.js new file mode 100644 index 0000000000..1b93a7dbf9 --- /dev/null +++ b/assets/js/8989.29b1d9c8.js @@ -0,0 +1 @@ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8989],{97375:function(t){t.exports=function(){"use strict";return function(t,e){var n=e.prototype,i=n.format;n.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return i.bind(this)(t);var s=this.$utils(),r=(t||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,(function(t){switch(t){case"Q":return Math.ceil((e.$M+1)/3);case"Do":return n.ordinal(e.$D);case"gggg":return e.weekYear();case"GGGG":return e.isoWeekYear();case"wo":return n.ordinal(e.week(),"W");case"w":case"ww":return s.s(e.week(),"w"===t?1:2,"0");case"W":case"WW":return s.s(e.isoWeek(),"W"===t?1:2,"0");case"k":case"kk":return s.s(String(0===e.$H?24:e.$H),"k"===t?1:2,"0");case"X":return Math.floor(e.$d.getTime()/1e3);case"x":return e.$d.getTime();case"z":return"["+e.offsetName()+"]";case"zzz":return"["+e.offsetName("long")+"]";default:return t}}));return i.bind(this)(r)}}}()},90445:function(t){t.exports=function(){"use strict";var t={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},e=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,n=/\d\d/,i=/\d\d?/,s=/\d*[^-_:/,()\s\d]+/,r={},a=function(t){return(t=+t)+(t>68?1900:2e3)},o=function(t){return function(e){this[t]=+e}},c=[/[+-]\d\d:?(\d\d)?|Z/,function(t){(this.zone||(this.zone={})).offset=function(t){if(!t)return 0;if("Z"===t)return 0;var e=t.match(/([+-]|\d\d)/g),n=60*e[1]+(+e[2]||0);return 0===n?0:"+"===e[0]?-n:n}(t)}],l=function(t){var e=r[t];return e&&(e.indexOf?e:e.s.concat(e.f))},d=function(t,e){var n,i=r.meridiem;if(i){for(var s=1;s<=24;s+=1)if(t.indexOf(i(s,0,e))>-1){n=s>12;break}}else n=t===(e?"pm":"PM");return n},u={A:[s,function(t){this.afternoon=d(t,!1)}],a:[s,function(t){this.afternoon=d(t,!0)}],S:[/\d/,function(t){this.milliseconds=100*+t}],SS:[n,function(t){this.milliseconds=10*+t}],SSS:[/\d{3}/,function(t){this.milliseconds=+t}],s:[i,o("seconds")],ss:[i,o("seconds")],m:[i,o("minutes")],mm:[i,o("minutes")],H:[i,o("hours")],h:[i,o("hours")],HH:[i,o("hours")],hh:[i,o("hours")],D:[i,o("day")],DD:[n,o("day")],Do:[s,function(t){var e=r.ordinal,n=t.match(/\d+/);if(this.day=n[0],e)for(var i=1;i<=31;i+=1)e(i).replace(/\[|\]/g,"")===t&&(this.day=i)}],M:[i,o("month")],MM:[n,o("month")],MMM:[s,function(t){var e=l("months"),n=(l("monthsShort")||e.map((function(t){return t.slice(0,3)}))).indexOf(t)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[s,function(t){var e=l("months").indexOf(t)+1;if(e<1)throw new Error;this.month=e%12||e}],Y:[/[+-]?\d+/,o("year")],YY:[n,function(t){this.year=a(t)}],YYYY:[/\d{4}/,o("year")],Z:c,ZZ:c};function h(n){var i,s;i=n,s=r&&r.formats;for(var a=(n=i.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(e,n,i){var r=i&&i.toUpperCase();return n||s[i]||t[i]||s[r].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(t,e,n){return e||n.slice(1)}))}))).match(e),o=a.length,c=0;c<o;c+=1){var l=a[c],d=u[l],h=d&&d[0],f=d&&d[1];a[c]=f?{regex:h,parser:f}:l.replace(/^\[|\]$/g,"")}return function(t){for(var e={},n=0,i=0;n<o;n+=1){var s=a[n];if("string"==typeof s)i+=s.length;else{var r=s.regex,c=s.parser,l=t.slice(i),d=r.exec(l)[0];c.call(e,d),t=t.replace(d,"")}}return function(t){var e=t.afternoon;if(void 0!==e){var n=t.hours;e?n<12&&(t.hours+=12):12===n&&(t.hours=0),delete t.afternoon}}(e),e}}return function(t,e,n){n.p.customParseFormat=!0,t&&t.parseTwoDigitYear&&(a=t.parseTwoDigitYear);var i=e.prototype,s=i.parse;i.parse=function(t){var e=t.date,i=t.utc,a=t.args;this.$u=i;var o=a[1];if("string"==typeof o){var c=!0===a[2],l=!0===a[3],d=c||l,u=a[2];l&&(u=a[2]),r=this.$locale(),!c&&u&&(r=n.Ls[u]),this.$d=function(t,e,n){try{if(["x","X"].indexOf(e)>-1)return new Date(("X"===e?1e3:1)*t);var i=h(e)(t),s=i.year,r=i.month,a=i.day,o=i.hours,c=i.minutes,l=i.seconds,d=i.milliseconds,u=i.zone,f=new Date,y=a||(s||r?1:f.getDate()),m=s||f.getFullYear(),k=0;s&&!r||(k=r>0?r-1:f.getMonth());var p=o||0,g=c||0,b=l||0,v=d||0;return u?new Date(Date.UTC(m,k,y,p,g,b,v+60*u.offset*1e3)):n?new Date(Date.UTC(m,k,y,p,g,b,v)):new Date(m,k,y,p,g,b,v)}catch(t){return new Date("")}}(e,o,i),this.init(),u&&!0!==u&&(this.$L=this.locale(u).$L),d&&e!=this.format(o)&&(this.$d=new Date("")),r={}}else if(o instanceof Array)for(var f=o.length,y=1;y<=f;y+=1){a[1]=o[y-1];var m=n.apply(this,a);if(m.isValid()){this.$d=m.$d,this.$L=m.$L,this.init();break}y===f&&(this.$d=new Date(""))}else s.call(this,t)}}}()},68313:function(t){t.exports=function(){"use strict";var t="day";return function(e,n,i){var s=function(e){return e.add(4-e.isoWeekday(),t)},r=n.prototype;r.isoWeekYear=function(){return s(this).year()},r.isoWeek=function(e){if(!this.$utils().u(e))return this.add(7*(e-this.isoWeek()),t);var n,r,a,o=s(this),c=(n=this.isoWeekYear(),a=4-(r=(this.$u?i.utc:i)().year(n).startOf("year")).isoWeekday(),r.isoWeekday()>4&&(a+=7),r.add(a,t));return o.diff(c,"week")+1},r.isoWeekday=function(t){return this.$utils().u(t)?this.day()||7:this.day(this.day()%7?t:t-7)};var a=r.startOf;r.startOf=function(t,e){var n=this.$utils(),i=!!n.u(e)||e;return"isoweek"===n.p(t)?i?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):a.bind(this)(t,e)}}}()},8989:(t,e,n)=>{"use strict";n.d(e,{diagram:()=>q});var i=n(16750),s=n(74353),r=n(68313),a=n(90445),o=n(97375),c=n(86079),l=n(26312),d=(n(42838),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[6,8,10,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,30,32,33,35,37],n=[1,25],i=[1,26],s=[1,27],r=[1,28],a=[1,29],o=[1,30],c=[1,31],l=[1,9],d=[1,10],u=[1,11],h=[1,12],f=[1,13],y=[1,14],m=[1,15],k=[1,16],p=[1,18],g=[1,19],b=[1,20],v=[1,21],T=[1,22],x=[1,24],w=[1,32],_={trace:function(){},yy:{},symbols_:{error:2,start:3,gantt:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NL:10,weekday:11,weekday_monday:12,weekday_tuesday:13,weekday_wednesday:14,weekday_thursday:15,weekday_friday:16,weekday_saturday:17,weekday_sunday:18,dateFormat:19,inclusiveEndDates:20,topAxis:21,axisFormat:22,tickInterval:23,excludes:24,includes:25,todayMarker:26,title:27,acc_title:28,acc_title_value:29,acc_descr:30,acc_descr_value:31,acc_descr_multiline_value:32,section:33,clickStatement:34,taskTxt:35,taskData:36,click:37,callbackname:38,callbackargs:39,href:40,clickStatementDebug:41,$accept:0,$end:1},terminals_:{2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",12:"weekday_monday",13:"weekday_tuesday",14:"weekday_wednesday",15:"weekday_thursday",16:"weekday_friday",17:"weekday_saturday",18:"weekday_sunday",19:"dateFormat",20:"inclusiveEndDates",21:"topAxis",22:"axisFormat",23:"tickInterval",24:"excludes",25:"includes",26:"todayMarker",27:"title",28:"acc_title",29:"acc_title_value",30:"acc_descr",31:"acc_descr_value",32:"acc_descr_multiline_value",33:"section",35:"taskTxt",36:"taskData",37:"click",38:"callbackname",39:"callbackargs",40:"href"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[34,2],[34,3],[34,3],[34,4],[34,3],[34,4],[34,2],[41,2],[41,3],[41,3],[41,4],[41,3],[41,4],[41,2]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.setWeekday("monday");break;case 9:i.setWeekday("tuesday");break;case 10:i.setWeekday("wednesday");break;case 11:i.setWeekday("thursday");break;case 12:i.setWeekday("friday");break;case 13:i.setWeekday("saturday");break;case 14:i.setWeekday("sunday");break;case 15:i.setDateFormat(r[o].substr(11)),this.$=r[o].substr(11);break;case 16:i.enableInclusiveEndDates(),this.$=r[o].substr(18);break;case 17:i.TopAxis(),this.$=r[o].substr(8);break;case 18:i.setAxisFormat(r[o].substr(11)),this.$=r[o].substr(11);break;case 19:i.setTickInterval(r[o].substr(13)),this.$=r[o].substr(13);break;case 20:i.setExcludes(r[o].substr(9)),this.$=r[o].substr(9);break;case 21:i.setIncludes(r[o].substr(9)),this.$=r[o].substr(9);break;case 22:i.setTodayMarker(r[o].substr(12)),this.$=r[o].substr(12);break;case 24:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 25:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 26:case 27:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 28:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 30:i.addTask(r[o-1],r[o]),this.$="task";break;case 31:this.$=r[o-1],i.setClickEvent(r[o-1],r[o],null);break;case 32:this.$=r[o-2],i.setClickEvent(r[o-2],r[o-1],r[o]);break;case 33:this.$=r[o-2],i.setClickEvent(r[o-2],r[o-1],null),i.setLink(r[o-2],r[o]);break;case 34:this.$=r[o-3],i.setClickEvent(r[o-3],r[o-2],r[o-1]),i.setLink(r[o-3],r[o]);break;case 35:this.$=r[o-2],i.setClickEvent(r[o-2],r[o],null),i.setLink(r[o-2],r[o-1]);break;case 36:this.$=r[o-3],i.setClickEvent(r[o-3],r[o-1],r[o]),i.setLink(r[o-3],r[o-2]);break;case 37:this.$=r[o-1],i.setLink(r[o-1],r[o]);break;case 38:case 44:this.$=r[o-1]+" "+r[o];break;case 39:case 40:case 42:this.$=r[o-2]+" "+r[o-1]+" "+r[o];break;case 41:case 43:this.$=r[o-3]+" "+r[o-2]+" "+r[o-1]+" "+r[o]}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:n,13:i,14:s,15:r,16:a,17:o,18:c,19:l,20:d,21:u,22:h,23:f,24:y,25:m,26:k,27:p,28:g,30:b,32:v,33:T,34:23,35:x,37:w},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:33,11:17,12:n,13:i,14:s,15:r,16:a,17:o,18:c,19:l,20:d,21:u,22:h,23:f,24:y,25:m,26:k,27:p,28:g,30:b,32:v,33:T,34:23,35:x,37:w},t(e,[2,5]),t(e,[2,6]),t(e,[2,15]),t(e,[2,16]),t(e,[2,17]),t(e,[2,18]),t(e,[2,19]),t(e,[2,20]),t(e,[2,21]),t(e,[2,22]),t(e,[2,23]),t(e,[2,24]),{29:[1,34]},{31:[1,35]},t(e,[2,27]),t(e,[2,28]),t(e,[2,29]),{36:[1,36]},t(e,[2,8]),t(e,[2,9]),t(e,[2,10]),t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),{38:[1,37],40:[1,38]},t(e,[2,4]),t(e,[2,25]),t(e,[2,26]),t(e,[2,30]),t(e,[2,31],{39:[1,39],40:[1,40]}),t(e,[2,37],{38:[1,41]}),t(e,[2,32],{40:[1,42]}),t(e,[2,33]),t(e,[2,35],{39:[1,43]}),t(e,[2,34]),t(e,[2,36])],defaultActions:{},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,o="",c=0,l=0,d=r.slice.call(arguments,1),u=Object.create(this.lexer),h={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(h.yy[f]=this.yy[f]);u.setInput(t,h.yy),h.yy.lexer=u,h.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var y=u.yylloc;r.push(y);var m=u.options&&u.options.ranges;"function"==typeof h.yy.parseError?this.parseError=h.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var k,p,g,b,v,T,x,w,_,$={};;){if(p=n[n.length-1],this.defaultActions[p]?g=this.defaultActions[p]:(null==k&&(_=void 0,"number"!=typeof(_=i.pop()||u.lex()||1)&&(_ instanceof Array&&(_=(i=_).pop()),_=e.symbols_[_]||_),k=_),g=a[p]&&a[p][k]),void 0===g||!g.length||!g[0]){var D="";for(v in w=[],a[p])this.terminals_[v]&&v>2&&w.push("'"+this.terminals_[v]+"'");D=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[k]||k)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==k?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(D,{text:u.match,token:this.terminals_[k]||k,line:u.yylineno,loc:y,expected:w})}if(g[0]instanceof Array&&g.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+k);switch(g[0]){case 1:n.push(k),s.push(u.yytext),r.push(u.yylloc),n.push(g[1]),k=null,l=u.yyleng,o=u.yytext,c=u.yylineno,y=u.yylloc;break;case 2:if(T=this.productions_[g[1]][1],$.$=s[s.length-T],$._$={first_line:r[r.length-(T||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(T||1)].first_column,last_column:r[r.length-1].last_column},m&&($._$.range=[r[r.length-(T||1)].range[0],r[r.length-1].range[1]]),void 0!==(b=this.performAction.apply($,[o,l,c,h.yy,g[1],s,r].concat(d))))return b;T&&(n=n.slice(0,-1*T*2),s=s.slice(0,-1*T),r=r.slice(0,-1*T)),n.push(this.productions_[g[1]][0]),s.push($.$),r.push($._$),x=a[n[n.length-2]][n[n.length-1]],n.push(x);break;case 3:return!0}}return!0}},$={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),"open_directive";case 1:return this.begin("acc_title"),28;case 2:return this.popState(),"acc_title_value";case 3:return this.begin("acc_descr"),30;case 4:return this.popState(),"acc_descr_value";case 5:this.begin("acc_descr_multiline");break;case 6:case 15:case 18:case 21:case 24:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:case 9:case 10:case 12:case 13:break;case 11:return 10;case 14:this.begin("href");break;case 16:return 40;case 17:this.begin("callbackname");break;case 19:this.popState(),this.begin("callbackargs");break;case 20:return 38;case 22:return 39;case 23:this.begin("click");break;case 25:return 37;case 26:return 4;case 27:return 19;case 28:return 20;case 29:return 21;case 30:return 22;case 31:return 23;case 32:return 25;case 33:return 24;case 34:return 26;case 35:return 12;case 36:return 13;case 37:return 14;case 38:return 15;case 39:return 16;case 40:return 17;case 41:return 18;case 42:return"date";case 43:return 27;case 44:return"accDescription";case 45:return 33;case 46:return 35;case 47:return 36;case 48:return":";case 49:return 6;case 50:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:tickInterval\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:weekday\s+monday\b)/i,/^(?:weekday\s+tuesday\b)/i,/^(?:weekday\s+wednesday\b)/i,/^(?:weekday\s+thursday\b)/i,/^(?:weekday\s+friday\b)/i,/^(?:weekday\s+saturday\b)/i,/^(?:weekday\s+sunday\b)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^\n]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^\n]+)/i,/^(?:[^:\n]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},callbackargs:{rules:[21,22],inclusive:!1},callbackname:{rules:[18,19,20],inclusive:!1},href:{rules:[15,16],inclusive:!1},click:{rules:[24,25],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,17,23,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50],inclusive:!0}}};function D(){this.yy={}}return _.lexer=$,D.prototype=_,_.Parser=D,new D}());d.parser=d;const u=d;s.extend(r),s.extend(a),s.extend(o);let h,f="",y="",m="",k=[],p=[],g={},b=[],v=[],T="",x="";const w=["active","done","crit","milestone"];let _=[],$=!1,D=!1,C="sunday",S=0;const E=function(t,e,n,i){return!i.includes(t.format(e.trim()))&&(!!(t.isoWeekday()>=6&&n.includes("weekends"))||(!!n.includes(t.format("dddd").toLowerCase())||n.includes(t.format(e.trim()))))},A=function(t,e,n,i){if(!n.length||t.manualEndTime)return;let r,a;r=t.startTime instanceof Date?s(t.startTime):s(t.startTime,e,!0),r=r.add(1,"d"),a=t.endTime instanceof Date?s(t.endTime):s(t.endTime,e,!0);const[o,c]=M(r,a,e,n,i);t.endTime=o.toDate(),t.renderEndTime=c},M=function(t,e,n,i,s){let r=!1,a=null;for(;t<=e;)r||(a=e.toDate()),r=E(t,n,i,s),r&&(e=e.add(1,"d")),t=t.add(1,"d");return[e,a]},Y=function(t,e,n){n=n.trim();const i=/^after\s+(?<ids>[\d\w- ]+)/.exec(n);if(null!==i){let t=null;for(const n of i.groups.ids.split(" ")){let e=N(n);void 0!==e&&(!t||e.endTime>t.endTime)&&(t=e)}if(t)return t.endTime;const e=new Date;return e.setHours(0,0,0,0),e}let r=s(n,e.trim(),!0);if(r.isValid())return r.toDate();{c.l.debug("Invalid date:"+n),c.l.debug("With date format:"+e.trim());const t=new Date(n);if(void 0===t||isNaN(t.getTime())||t.getFullYear()<-1e4||t.getFullYear()>1e4)throw new Error("Invalid date:"+n);return t}},L=function(t){const e=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(t.trim());return null!==e?[Number.parseFloat(e[1]),e[2]]:[NaN,"ms"]},I=function(t,e,n,i=!1){n=n.trim();const r=/^until\s+(?<ids>[\d\w- ]+)/.exec(n);if(null!==r){let t=null;for(const n of r.groups.ids.split(" ")){let e=N(n);void 0!==e&&(!t||e.startTime<t.startTime)&&(t=e)}if(t)return t.startTime;const e=new Date;return e.setHours(0,0,0,0),e}let a=s(n,e.trim(),!0);if(a.isValid())return i&&(a=a.add(1,"d")),a.toDate();let o=s(t);const[c,l]=L(n);if(!Number.isNaN(c)){const t=o.add(c,l);t.isValid()&&(o=t)}return o.toDate()};let O=0;const W=function(t){return void 0===t?(O+=1,"task"+O):t};let F,P,B=[];const z={},N=function(t){const e=z[t];return B[e]},G=function(){const t=function(t){const e=B[t];let n="";switch(B[t].raw.startTime.type){case"prevTaskEnd":{const t=N(e.prevTaskId);e.startTime=t.endTime;break}case"getStartDate":n=Y(0,f,B[t].raw.startTime.startData),n&&(B[t].startTime=n)}return B[t].startTime&&(B[t].endTime=I(B[t].startTime,f,B[t].raw.endTime.data,$),B[t].endTime&&(B[t].processed=!0,B[t].manualEndTime=s(B[t].raw.endTime.data,"YYYY-MM-DD",!0).isValid(),A(B[t],f,p,k))),B[t].processed};let e=!0;for(const[n,i]of B.entries())t(n),e=e&&i.processed;return e},H=function(t,e){t.split(",").forEach((function(t){let n=N(t);void 0!==n&&n.classes.push(e)}))},j=function(t,e){_.push((function(){const n=document.querySelector(`[id="${t}"]`);null!==n&&n.addEventListener("click",(function(){e()}))}),(function(){const n=document.querySelector(`[id="${t}-text"]`);null!==n&&n.addEventListener("click",(function(){e()}))}))},U={getConfig:()=>(0,c.c)().gantt,clear:function(){b=[],v=[],T="",_=[],O=0,F=void 0,P=void 0,B=[],f="",y="",x="",h=void 0,m="",k=[],p=[],$=!1,D=!1,S=0,g={},(0,c.v)(),C="sunday"},setDateFormat:function(t){f=t},getDateFormat:function(){return f},enableInclusiveEndDates:function(){$=!0},endDatesAreInclusive:function(){return $},enableTopAxis:function(){D=!0},topAxisEnabled:function(){return D},setAxisFormat:function(t){y=t},getAxisFormat:function(){return y},setTickInterval:function(t){h=t},getTickInterval:function(){return h},setTodayMarker:function(t){m=t},getTodayMarker:function(){return m},setAccTitle:c.s,getAccTitle:c.g,setDiagramTitle:c.q,getDiagramTitle:c.t,setDisplayMode:function(t){x=t},getDisplayMode:function(){return x},setAccDescription:c.b,getAccDescription:c.a,addSection:function(t){T=t,b.push(t)},getSections:function(){return b},getTasks:function(){let t=G();let e=0;for(;!t&&e<10;)t=G(),e++;return v=B,v},addTask:function(t,e){const n={section:T,type:T,processed:!1,manualEndTime:!1,renderEndTime:null,raw:{data:e},task:t,classes:[]},i=function(t,e){let n;n=":"===e.substr(0,1)?e.substr(1,e.length):e;const i=n.split(","),s={};R(i,s,w);for(let r=0;r<i.length;r++)i[r]=i[r].trim();switch(i.length){case 1:s.id=W(),s.startTime={type:"prevTaskEnd",id:t},s.endTime={data:i[0]};break;case 2:s.id=W(),s.startTime={type:"getStartDate",startData:i[0]},s.endTime={data:i[1]};break;case 3:s.id=W(i[0]),s.startTime={type:"getStartDate",startData:i[1]},s.endTime={data:i[2]}}return s}(P,e);n.raw.startTime=i.startTime,n.raw.endTime=i.endTime,n.id=i.id,n.prevTaskId=P,n.active=i.active,n.done=i.done,n.crit=i.crit,n.milestone=i.milestone,n.order=S,S++;const s=B.push(n);P=n.id,z[n.id]=s-1},findTaskById:N,addTaskOrg:function(t,e){const n={section:T,type:T,description:t,task:t,classes:[]},i=function(t,e){let n;n=":"===e.substr(0,1)?e.substr(1,e.length):e;const i=n.split(","),r={};R(i,r,w);for(let s=0;s<i.length;s++)i[s]=i[s].trim();let a="";switch(i.length){case 1:r.id=W(),r.startTime=t.endTime,a=i[0];break;case 2:r.id=W(),r.startTime=Y(0,f,i[0]),a=i[1];break;case 3:r.id=W(i[0]),r.startTime=Y(0,f,i[1]),a=i[2]}return a&&(r.endTime=I(r.startTime,f,a,$),r.manualEndTime=s(a,"YYYY-MM-DD",!0).isValid(),A(r,f,p,k)),r}(F,e);n.startTime=i.startTime,n.endTime=i.endTime,n.id=i.id,n.active=i.active,n.done=i.done,n.crit=i.crit,n.milestone=i.milestone,F=n,v.push(n)},setIncludes:function(t){k=t.toLowerCase().split(/[\s,]+/)},getIncludes:function(){return k},setExcludes:function(t){p=t.toLowerCase().split(/[\s,]+/)},getExcludes:function(){return p},setClickEvent:function(t,e,n){t.split(",").forEach((function(t){!function(t,e,n){if("loose"!==(0,c.c)().securityLevel)return;if(void 0===e)return;let i=[];if("string"==typeof n){i=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t<i.length;t++){let e=i[t].trim();'"'===e.charAt(0)&&'"'===e.charAt(e.length-1)&&(e=e.substr(1,e.length-2)),i[t]=e}}0===i.length&&i.push(t),void 0!==N(t)&&j(t,(()=>{c.u.runFunc(e,...i)}))}(t,e,n)})),H(t,"clickable")},setLink:function(t,e){let n=e;"loose"!==(0,c.c)().securityLevel&&(n=(0,i.Jf)(e)),t.split(",").forEach((function(t){void 0!==N(t)&&(j(t,(()=>{window.open(n,"_self")})),g[t]=n)})),H(t,"clickable")},getLinks:function(){return g},bindFunctions:function(t){_.forEach((function(e){e(t)}))},parseDuration:L,isInvalidDate:E,setWeekday:function(t){C=t},getWeekday:function(){return C}};function R(t,e,n){let i=!0;for(;i;)i=!1,n.forEach((function(n){const s=new RegExp("^\\s*"+n+"\\s*$");t[0].match(s)&&(e[n]=!0,t.shift(1),i=!0)}))}const V={monday:l.ABi,tuesday:l.PGu,wednesday:l.GuW,thursday:l.Mol,friday:l.TUC,saturday:l.rGn,sunday:l.YPH},Z=(t,e)=>{let n=[...t].map((()=>-1/0)),i=[...t].sort(((t,e)=>t.startTime-e.startTime||t.order-e.order)),s=0;for(const r of i)for(let t=0;t<n.length;t++)if(r.startTime>=n[t]){n[t]=r.endTime,r.order=t+e,t>s&&(s=t);break}return s};let X;const q={parser:u,db:U,renderer:{setConf:function(){c.l.debug("Something is calling, setConf, remove the call")},draw:function(t,e,n,i){const r=(0,c.c)().gantt,a=(0,c.c)().securityLevel;let o;"sandbox"===a&&(o=(0,l.Ltv)("#i"+e));const d="sandbox"===a?(0,l.Ltv)(o.nodes()[0].contentDocument.body):(0,l.Ltv)("body"),u="sandbox"===a?o.nodes()[0].contentDocument:document,h=u.getElementById(e);X=h.parentElement.offsetWidth,void 0===X&&(X=1200),void 0!==r.useWidth&&(X=r.useWidth);const f=i.db.getTasks();let y=[];for(const s of f)y.push(s.type);y=function(t){const e={},n=[];for(let i=0,s=t.length;i<s;++i)Object.prototype.hasOwnProperty.call(e,t[i])||(e[t[i]]=!0,n.push(t[i]));return n}(y);const m={};let k=2*r.topPadding;if("compact"===i.db.getDisplayMode()||"compact"===r.displayMode){const t={};for(const n of f)void 0===t[n.section]?t[n.section]=[n]:t[n.section].push(n);let e=0;for(const n of Object.keys(t)){const i=Z(t[n],e)+1;e+=i,k+=i*(r.barHeight+r.barGap),m[n]=i}}else{k+=f.length*(r.barHeight+r.barGap);for(const t of y)m[t]=f.filter((e=>e.type===t)).length}h.setAttribute("viewBox","0 0 "+X+" "+k);const p=d.select(`[id="${e}"]`),g=(0,l.w7C)().domain([(0,l.jkA)(f,(function(t){return t.startTime})),(0,l.T9B)(f,(function(t){return t.endTime}))]).rangeRound([0,X-r.leftPadding-r.rightPadding]);f.sort((function(t,e){const n=t.startTime,i=e.startTime;let s=0;return n>i?s=1:n<i&&(s=-1),s})),function(t,n,a){const o=r.barHeight,d=o+r.barGap,h=r.topPadding,f=r.leftPadding;(0,l.m4Y)().domain([0,y.length]).range(["#00B9FA","#F95002"]).interpolate(l.bEH);(function(t,e,n,a,o,l,d,u){if(0===d.length&&0===u.length)return;let h,f;for(const{startTime:i,endTime:s}of l)(void 0===h||i<h)&&(h=i),(void 0===f||s>f)&&(f=s);if(!h||!f)return;if(s(f).diff(s(h),"year")>5)return void c.l.warn("The difference between the min and max time is more than 5 years. This will cause performance issues. Skipping drawing exclude days.");const y=i.db.getDateFormat(),m=[];let k=null,b=s(h);for(;b.valueOf()<=f;)i.db.isInvalidDate(b,y,d,u)?k?k.end=b:k={start:b,end:b}:k&&(m.push(k),k=null),b=b.add(1,"d");p.append("g").selectAll("rect").data(m).enter().append("rect").attr("id",(function(t){return"exclude-"+t.start.format("YYYY-MM-DD")})).attr("x",(function(t){return g(t.start)+n})).attr("y",r.gridLineStartPadding).attr("width",(function(t){const e=t.end.add(1,"day");return g(e)-g(t.start)})).attr("height",o-e-r.gridLineStartPadding).attr("transform-origin",(function(e,i){return(g(e.start)+n+.5*(g(e.end)-g(e.start))).toString()+"px "+(i*t+.5*o).toString()+"px"})).attr("class","exclude-range")})(d,h,f,0,a,t,i.db.getExcludes(),i.db.getIncludes()),function(t,e,n,s){let a=(0,l.l78)(g).tickSize(-s+e+r.gridLineStartPadding).tickFormat((0,l.DCK)(i.db.getAxisFormat()||r.axisFormat||"%Y-%m-%d"));const o=/^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/.exec(i.db.getTickInterval()||r.tickInterval);if(null!==o){const t=o[1],e=o[2],n=i.db.getWeekday()||r.weekday;switch(e){case"millisecond":a.ticks(l.t6C.every(t));break;case"second":a.ticks(l.ucG.every(t));break;case"minute":a.ticks(l.wXd.every(t));break;case"hour":a.ticks(l.Agd.every(t));break;case"day":a.ticks(l.UAC.every(t));break;case"week":a.ticks(V[n].every(t));break;case"month":a.ticks(l.Ui6.every(t))}}if(p.append("g").attr("class","grid").attr("transform","translate("+t+", "+(s-50)+")").call(a).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),i.db.topAxisEnabled()||r.topAxis){let n=(0,l.tlR)(g).tickSize(-s+e+r.gridLineStartPadding).tickFormat((0,l.DCK)(i.db.getAxisFormat()||r.axisFormat||"%Y-%m-%d"));if(null!==o){const t=o[1],e=o[2],s=i.db.getWeekday()||r.weekday;switch(e){case"millisecond":n.ticks(l.t6C.every(t));break;case"second":n.ticks(l.ucG.every(t));break;case"minute":n.ticks(l.wXd.every(t));break;case"hour":n.ticks(l.Agd.every(t));break;case"day":n.ticks(l.UAC.every(t));break;case"week":n.ticks(V[s].every(t));break;case"month":n.ticks(l.Ui6.every(t))}}p.append("g").attr("class","grid").attr("transform","translate("+t+", "+e+")").call(n).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}(f,h,0,a),function(t,n,s,a,o,d,u){const h=[...new Set(t.map((t=>t.order)))].map((e=>t.find((t=>t.order===e))));p.append("g").selectAll("rect").data(h).enter().append("rect").attr("x",0).attr("y",(function(t,e){return t.order*n+s-2})).attr("width",(function(){return u-r.rightPadding/2})).attr("height",n).attr("class",(function(t){for(const[e,n]of y.entries())if(t.type===n)return"section section"+e%r.numberSectionStyles;return"section section0"}));const f=p.append("g").selectAll("rect").data(t).enter(),m=i.db.getLinks();f.append("rect").attr("id",(function(t){return t.id})).attr("rx",3).attr("ry",3).attr("x",(function(t){return t.milestone?g(t.startTime)+a+.5*(g(t.endTime)-g(t.startTime))-.5*o:g(t.startTime)+a})).attr("y",(function(t,e){return t.order*n+s})).attr("width",(function(t){return t.milestone?o:g(t.renderEndTime||t.endTime)-g(t.startTime)})).attr("height",o).attr("transform-origin",(function(t,e){return e=t.order,(g(t.startTime)+a+.5*(g(t.endTime)-g(t.startTime))).toString()+"px "+(e*n+s+.5*o).toString()+"px"})).attr("class",(function(t){const e="task";let n="";t.classes.length>0&&(n=t.classes.join(" "));let i=0;for(const[a,o]of y.entries())t.type===o&&(i=a%r.numberSectionStyles);let s="";return t.active?t.crit?s+=" activeCrit":s=" active":t.done?s=t.crit?" doneCrit":" done":t.crit&&(s+=" crit"),0===s.length&&(s=" task"),t.milestone&&(s=" milestone "+s),s+=i,s+=" "+n,e+s})),f.append("text").attr("id",(function(t){return t.id+"-text"})).text((function(t){return t.task})).attr("font-size",r.fontSize).attr("x",(function(t){let e=g(t.startTime),n=g(t.renderEndTime||t.endTime);t.milestone&&(e+=.5*(g(t.endTime)-g(t.startTime))-.5*o),t.milestone&&(n=e+o);const i=this.getBBox().width;return i>n-e?n+i+1.5*r.leftPadding>u?e+a-5:n+a+5:(n-e)/2+e+a})).attr("y",(function(t,e){return t.order*n+r.barHeight/2+(r.fontSize/2-2)+s})).attr("text-height",o).attr("class",(function(t){const e=g(t.startTime);let n=g(t.endTime);t.milestone&&(n=e+o);const i=this.getBBox().width;let s="";t.classes.length>0&&(s=t.classes.join(" "));let a=0;for(const[o,l]of y.entries())t.type===l&&(a=o%r.numberSectionStyles);let c="";return t.active&&(c=t.crit?"activeCritText"+a:"activeText"+a),t.done?c=t.crit?c+" doneCritText"+a:c+" doneText"+a:t.crit&&(c=c+" critText"+a),t.milestone&&(c+=" milestoneText"),i>n-e?n+i+1.5*r.leftPadding>u?s+" taskTextOutsideLeft taskTextOutside"+a+" "+c:s+" taskTextOutsideRight taskTextOutside"+a+" "+c+" width-"+i:s+" taskText taskText"+a+" "+c+" width-"+i}));if("sandbox"===(0,c.c)().securityLevel){let t;t=(0,l.Ltv)("#i"+e);const n=t.nodes()[0].contentDocument;f.filter((function(t){return void 0!==m[t.id]})).each((function(t){var e=n.querySelector("#"+t.id),i=n.querySelector("#"+t.id+"-text");const s=e.parentNode;var r=n.createElement("a");r.setAttribute("xlink:href",m[t.id]),r.setAttribute("target","_top"),s.appendChild(r),r.appendChild(e),r.appendChild(i)}))}}(t,d,h,f,o,0,n),function(t,e){let n=0;const i=Object.keys(m).map((t=>[t,m[t]]));p.append("g").selectAll("text").data(i).enter().append((function(t){const e=t[0].split(c.e.lineBreakRegex),n=-(e.length-1)/2,i=u.createElementNS("http://www.w3.org/2000/svg","text");i.setAttribute("dy",n+"em");for(const[s,r]of e.entries()){const t=u.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttribute("alignment-baseline","central"),t.setAttribute("x","10"),s>0&&t.setAttribute("dy","1em"),t.textContent=r,i.appendChild(t)}return i})).attr("x",10).attr("y",(function(s,r){if(!(r>0))return s[1]*t/2+e;for(let a=0;a<r;a++)return n+=i[r-1][1],s[1]*t/2+n*t+e})).attr("font-size",r.sectionFontSize).attr("class",(function(t){for(const[e,n]of y.entries())if(t[0]===n)return"sectionTitle sectionTitle"+e%r.numberSectionStyles;return"sectionTitle"}))}(d,h),function(t,e,n,s){const a=i.db.getTodayMarker();if("off"===a)return;const o=p.append("g").attr("class","today"),c=new Date,l=o.append("line");l.attr("x1",g(c)+t).attr("x2",g(c)+t).attr("y1",r.titleTopMargin).attr("y2",s-r.titleTopMargin).attr("class","today"),""!==a&&l.attr("style",a.replace(/,/g,";"))}(f,0,0,a)}(f,X,k),(0,c.i)(p,k,X,r.useMaxWidth),p.append("text").text(i.db.getDiagramTitle()).attr("x",X/2).attr("y",r.titleTopMargin).attr("class","titleText")}},styles:t=>`\n .mermaid-main-font {\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n\n .exclude-range {\n fill: ${t.excludeBkgColor};\n }\n\n .section {\n stroke: none;\n opacity: 0.2;\n }\n\n .section0 {\n fill: ${t.sectionBkgColor};\n }\n\n .section2 {\n fill: ${t.sectionBkgColor2};\n }\n\n .section1,\n .section3 {\n fill: ${t.altSectionBkgColor};\n opacity: 0.2;\n }\n\n .sectionTitle0 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle1 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle2 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle3 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle {\n text-anchor: start;\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n\n\n /* Grid and axis */\n\n .grid .tick {\n stroke: ${t.gridColor};\n opacity: 0.8;\n shape-rendering: crispEdges;\n }\n\n .grid .tick text {\n font-family: ${t.fontFamily};\n fill: ${t.textColor};\n }\n\n .grid path {\n stroke-width: 0;\n }\n\n\n /* Today line */\n\n .today {\n fill: none;\n stroke: ${t.todayLineColor};\n stroke-width: 2px;\n }\n\n\n /* Task styling */\n\n /* Default task */\n\n .task {\n stroke-width: 2;\n }\n\n .taskText {\n text-anchor: middle;\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n\n .taskTextOutsideRight {\n fill: ${t.taskTextDarkColor};\n text-anchor: start;\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n\n .taskTextOutsideLeft {\n fill: ${t.taskTextDarkColor};\n text-anchor: end;\n }\n\n\n /* Special case clickable */\n\n .task.clickable {\n cursor: pointer;\n }\n\n .taskText.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideLeft.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideRight.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n\n /* Specific task settings for the sections*/\n\n .taskText0,\n .taskText1,\n .taskText2,\n .taskText3 {\n fill: ${t.taskTextColor};\n }\n\n .task0,\n .task1,\n .task2,\n .task3 {\n fill: ${t.taskBkgColor};\n stroke: ${t.taskBorderColor};\n }\n\n .taskTextOutside0,\n .taskTextOutside2\n {\n fill: ${t.taskTextOutsideColor};\n }\n\n .taskTextOutside1,\n .taskTextOutside3 {\n fill: ${t.taskTextOutsideColor};\n }\n\n\n /* Active task */\n\n .active0,\n .active1,\n .active2,\n .active3 {\n fill: ${t.activeTaskBkgColor};\n stroke: ${t.activeTaskBorderColor};\n }\n\n .activeText0,\n .activeText1,\n .activeText2,\n .activeText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Completed task */\n\n .done0,\n .done1,\n .done2,\n .done3 {\n stroke: ${t.doneTaskBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneText0,\n .doneText1,\n .doneText2,\n .doneText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Tasks on the critical line */\n\n .crit0,\n .crit1,\n .crit2,\n .crit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.critBkgColor};\n stroke-width: 2;\n }\n\n .activeCrit0,\n .activeCrit1,\n .activeCrit2,\n .activeCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.activeTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneCrit0,\n .doneCrit1,\n .doneCrit2,\n .doneCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n cursor: pointer;\n shape-rendering: crispEdges;\n }\n\n .milestone {\n transform: rotate(45deg) scale(0.8,0.8);\n }\n\n .milestoneText {\n font-style: italic;\n }\n .doneCritText0,\n .doneCritText1,\n .doneCritText2,\n .doneCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .activeCritText0,\n .activeCritText1,\n .activeCritText2,\n .activeCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .titleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.titleColor||t.textColor};\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/8995.d61fabd9.js b/assets/js/8995.d61fabd9.js new file mode 100644 index 0000000000..aac3f7eeab --- /dev/null +++ b/assets/js/8995.d61fabd9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8995],{14075:(e,t,n)=>{n.d(t,{M:()=>d});var r=n(69592),i=n(50053),a=n(74722);n(73046);function d(e){var t={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:o(e),edges:l(e)};return r.A(e.graph())||(t.value=i.A(e.graph())),t}function o(e){return a.A(e.nodes(),(function(t){var n=e.node(t),i=e.parent(t),a={v:t};return r.A(n)||(a.value=n),r.A(i)||(a.parent=i),a}))}function l(e){return a.A(e.edges(),(function(t){var n=e.edge(t),i={v:t.v,w:t.w};return r.A(t.name)||(i.name=t.name),r.A(n)||(i.value=n),i}))}},50053:(e,t,n)=>{n.d(t,{A:()=>i});var r=n(91641);const i=function(e){return(0,r.A)(e,4)}},8995:(e,t,n)=>{n.d(t,{r:()=>E});var r=n(21176),i=n(14075),a=n(88146),d=n(86079),o=n(697),l=n(9312),s=n(26312);let c={},h={},g={};const f=(e,t)=>(d.l.trace("In isDescendant",t," ",e," = ",h[t].includes(e)),!!h[t].includes(e)),u=(e,t,n,r)=>{d.l.warn("Copying children of ",e,"root",r,"data",t.node(e),r);const i=t.children(e)||[];e!==r&&i.push(e),d.l.warn("Copying (nodes) clusterId",e,"nodes",i),i.forEach((i=>{if(t.children(i).length>0)u(i,t,n,r);else{const a=t.node(i);d.l.info("cp ",i," to ",r," with parent ",e),n.setNode(i,a),r!==t.parent(i)&&(d.l.warn("Setting parent",i,t.parent(i)),n.setParent(i,t.parent(i))),e!==r&&i!==e?(d.l.debug("Setting parent",i,e),n.setParent(i,e)):(d.l.info("In copy ",e,"root",r,"data",t.node(e),r),d.l.debug("Not Setting parent for node=",i,"cluster!==rootId",e!==r,"node!==clusterId",i!==e));const o=t.edges(i);d.l.debug("Copying Edges",o),o.forEach((i=>{d.l.info("Edge",i);const a=t.edge(i.v,i.w,i.name);d.l.info("Edge data",a,r);try{((e,t)=>(d.l.info("Descendants of ",t," is ",h[t]),d.l.info("Edge is ",e),e.v!==t&&e.w!==t&&(h[t]?h[t].includes(e.v)||f(e.v,t)||f(e.w,t)||h[t].includes(e.w):(d.l.debug("Tilt, ",t,",not in descendants"),!1))))(i,r)?(d.l.info("Copying as ",i.v,i.w,a,i.name),n.setEdge(i.v,i.w,a,i.name),d.l.info("newGraph edges ",n.edges(),n.edge(n.edges()[0]))):d.l.info("Skipping copy of edge ",i.v,"--\x3e",i.w," rootId: ",r," clusterId:",e)}catch(o){d.l.error(o)}}))}d.l.debug("Removing node",i),t.removeNode(i)}))},w=(e,t)=>{const n=t.children(e);let r=[...n];for(const i of n)g[i]=e,r=[...r,...w(i,t)];return r},p=(e,t)=>{d.l.trace("Searching",e);const n=t.children(e);if(d.l.trace("Searching children of id ",e,n),n.length<1)return d.l.trace("This is a valid node",e),e;for(const r of n){const n=p(r,t);if(n)return d.l.trace("Found replacement for",e," => ",n),n}},v=e=>c[e]&&c[e].externalConnections&&c[e]?c[e].id:e,y=(e,t)=>{if(d.l.warn("extractor - ",t,i.M(e),e.children("D")),t>10)return void d.l.error("Bailing out");let n=e.nodes(),r=!1;for(const i of n){const t=e.children(i);r=r||t.length>0}if(r){d.l.debug("Nodes = ",n,t);for(const r of n)if(d.l.debug("Extracting node",r,c,c[r]&&!c[r].externalConnections,!e.parent(r),e.node(r),e.children("D")," Depth ",t),c[r])if(!c[r].externalConnections&&e.children(r)&&e.children(r).length>0){d.l.warn("Cluster without external connections, without a parent and with children",r,t);let n="TB"===e.graph().rankdir?"LR":"TB";c[r]&&c[r].clusterData&&c[r].clusterData.dir&&(n=c[r].clusterData.dir,d.l.warn("Fixing dir",c[r].clusterData.dir,n));const a=new o.T({multigraph:!0,compound:!0}).setGraph({rankdir:n,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));d.l.warn("Old graph before copy",i.M(e)),u(r,e,a,r),e.setNode(r,{clusterNode:!0,id:r,clusterData:c[r].clusterData,labelText:c[r].labelText,graph:a}),d.l.warn("New graph after copy node: (",r,")",i.M(a)),d.l.debug("Old graph after copy",i.M(e))}else d.l.warn("Cluster ** ",r," **not meeting the criteria !externalConnections:",!c[r].externalConnections," no parent: ",!e.parent(r)," children ",e.children(r)&&e.children(r).length>0,e.children("D"),t),d.l.debug(c);else d.l.debug("Not a cluster",r,t);n=e.nodes(),d.l.warn("New list of nodes",n);for(const r of n){const n=e.node(r);d.l.warn(" Now next level",r,n),n.clusterNode&&y(n.graph,t+1)}}else d.l.debug("Done, no node has children",e.nodes())},x=(e,t)=>{if(0===t.length)return[];let n=Object.assign(t);return t.forEach((t=>{const r=e.children(t),i=x(e,r);n=[...n,...i]})),n},m={rect:(e,t)=>{d.l.info("Creating subgraph rect for ",t.id,t);const n=(0,d.c)(),r=e.insert("g").attr("class","cluster"+(t.class?" "+t.class:"")).attr("id",t.id),i=r.insert("rect",":first-child"),o=(0,d.m)(n.flowchart.htmlLabels),c=r.insert("g").attr("class","cluster-label"),h="markdown"===t.labelType?(0,l.a)(c,t.labelText,{style:t.labelStyle,useHtmlLabels:o}):c.node().appendChild((0,a.c)(t.labelText,t.labelStyle,void 0,!0));let g=h.getBBox();if((0,d.m)(n.flowchart.htmlLabels)){const e=h.children[0],t=(0,s.Ltv)(h);g=e.getBoundingClientRect(),t.attr("width",g.width),t.attr("height",g.height)}const f=0*t.padding,u=f/2,w=t.width<=g.width+f?g.width+f:t.width;t.width<=g.width+f?t.diff=(g.width-t.width)/2-t.padding/2:t.diff=-t.padding/2,d.l.trace("Data ",t,JSON.stringify(t)),i.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-w/2).attr("y",t.y-t.height/2-u).attr("width",w).attr("height",t.height+f);const{subGraphTitleTopMargin:p}=(0,a.g)(n);o?c.attr("transform",`translate(${t.x-g.width/2}, ${t.y-t.height/2+p})`):c.attr("transform",`translate(${t.x}, ${t.y-t.height/2+p})`);const v=i.node().getBBox();return t.width=v.width,t.height=v.height,t.intersect=function(e){return(0,a.i)(t,e)},r},roundedWithTitle:(e,t)=>{const n=(0,d.c)(),r=e.insert("g").attr("class",t.classes).attr("id",t.id),i=r.insert("rect",":first-child"),o=r.insert("g").attr("class","cluster-label"),l=r.append("rect"),c=o.node().appendChild((0,a.c)(t.labelText,t.labelStyle,void 0,!0));let h=c.getBBox();if((0,d.m)(n.flowchart.htmlLabels)){const e=c.children[0],t=(0,s.Ltv)(c);h=e.getBoundingClientRect(),t.attr("width",h.width),t.attr("height",h.height)}h=c.getBBox();const g=0*t.padding,f=g/2,u=t.width<=h.width+t.padding?h.width+t.padding:t.width;t.width<=h.width+t.padding?t.diff=(h.width+0*t.padding-t.width)/2:t.diff=-t.padding/2,i.attr("class","outer").attr("x",t.x-u/2-f).attr("y",t.y-t.height/2-f).attr("width",u+g).attr("height",t.height+g),l.attr("class","inner").attr("x",t.x-u/2-f).attr("y",t.y-t.height/2-f+h.height-1).attr("width",u+g).attr("height",t.height+g-h.height-3);const{subGraphTitleTopMargin:w}=(0,a.g)(n);o.attr("transform",`translate(${t.x-h.width/2}, ${t.y-t.height/2-t.padding/3+((0,d.m)(n.flowchart.htmlLabels)?5:3)+w})`);const p=i.node().getBBox();return t.height=p.height,t.intersect=function(e){return(0,a.i)(t,e)},r},noteGroup:(e,t)=>{const n=e.insert("g").attr("class","note-cluster").attr("id",t.id),r=n.insert("rect",":first-child"),i=0*t.padding,d=i/2;r.attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-t.width/2-d).attr("y",t.y-t.height/2-d).attr("width",t.width+i).attr("height",t.height+i).attr("fill","none");const o=r.node().getBBox();return t.width=o.width,t.height=o.height,t.intersect=function(e){return(0,a.i)(t,e)},n},divider:(e,t)=>{const n=e.insert("g").attr("class",t.classes).attr("id",t.id),r=n.insert("rect",":first-child"),i=0*t.padding,d=i/2;r.attr("class","divider").attr("x",t.x-t.width/2-d).attr("y",t.y-t.height/2).attr("width",t.width+i).attr("height",t.height+i);const o=r.node().getBBox();return t.width=o.width,t.height=o.height,t.diff=-t.padding/2,t.intersect=function(e){return(0,a.i)(t,e)},n}};let b={};const C=async(e,t,n,o,l,s)=>{d.l.info("Graph in recursive render: XXX",i.M(t),l);const h=t.graph().rankdir;d.l.trace("Dir in recursive render - dir:",h);const g=e.insert("g").attr("class","root");t.nodes()?d.l.info("Recursive render XXX",t.nodes()):d.l.info("No nodes found for",t),t.edges().length>0&&d.l.trace("Recursive edges",t.edge(t.edges()[0]));const f=g.insert("g").attr("class","clusters"),u=g.insert("g").attr("class","edgePaths"),w=g.insert("g").attr("class","edgeLabels"),v=g.insert("g").attr("class","nodes");await Promise.all(t.nodes().map((async function(e){const r=t.node(e);if(void 0!==l){const n=JSON.parse(JSON.stringify(l.clusterData));d.l.info("Setting data for cluster XXX (",e,") ",n,l),t.setNode(l.id,n),t.parent(e)||(d.l.trace("Setting parent",e,l.id),t.setParent(e,l.id,n))}if(d.l.info("(Insert) Node XXX"+e+": "+JSON.stringify(t.node(e))),r&&r.clusterNode){d.l.info("Cluster identified",e,r.width,t.node(e));const i=await C(v,r.graph,n,o,t.node(e),s),l=i.elem;(0,a.u)(r,l),r.diff=i.diff||0,d.l.info("Node bounds (abc123)",e,r,r.width,r.x,r.y),(0,a.s)(l,r),d.l.warn("Recursive render complete ",l,r)}else t.children(e).length>0?(d.l.info("Cluster - the non recursive path XXX",e,r.id,r,t),d.l.info(p(r.id,t)),c[r.id]={id:p(r.id,t),node:r}):(d.l.info("Node - the non recursive path",e,r.id,r),await(0,a.e)(v,t.node(e),h))}))),t.edges().forEach((function(e){const n=t.edge(e.v,e.w,e.name);d.l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e)),d.l.info("Edge "+e.v+" -> "+e.w+": ",e," ",JSON.stringify(t.edge(e))),d.l.info("Fix",c,"ids:",e.v,e.w,"Translating: ",c[e.v],c[e.w]),(0,a.f)(w,n)})),t.edges().forEach((function(e){d.l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e))})),d.l.info("#############################################"),d.l.info("### Layout ###"),d.l.info("#############################################"),d.l.info(t),(0,r.Zp)(t),d.l.info("Graph after layout:",i.M(t));let y=0;const{subGraphTitleTotalMargin:E}=(0,a.g)(s);return(e=>x(e,e.children()))(t).forEach((function(e){const n=t.node(e);d.l.info("Position "+e+": "+JSON.stringify(t.node(e))),d.l.info("Position "+e+": ("+n.x,","+n.y,") width: ",n.width," height: ",n.height),n&&n.clusterNode?(n.y+=E,(0,a.p)(n)):t.children(e).length>0?(n.height+=E,((e,t)=>{d.l.trace("Inserting cluster");const n=t.shape||"rect";b[t.id]=m[n](e,t)})(f,n),c[n.id].node=n):(n.y+=E/2,(0,a.p)(n))})),t.edges().forEach((function(e){const r=t.edge(e);d.l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(r),r),r.points.forEach((e=>e.y+=E/2));const i=(0,a.h)(u,e,r,c,n,t,o);(0,a.j)(r,i)})),t.nodes().forEach((function(e){const n=t.node(e);d.l.info(e,n.type,n.diff),"group"===n.type&&(y=n.diff)})),{elem:g,diff:y}},E=async(e,t,n,r,o)=>{(0,a.a)(e,n,r,o),(0,a.b)(),(0,a.d)(),b={},h={},g={},c={},d.l.warn("Graph at first:",JSON.stringify(i.M(t))),((e,t)=>{if(!e||t>10)d.l.debug("Opting out, no graph ");else{d.l.debug("Opting in, graph "),e.nodes().forEach((function(t){e.children(t).length>0&&(d.l.warn("Cluster identified",t," Replacement id in edges: ",p(t,e)),h[t]=w(t,e),c[t]={id:p(t,e),clusterData:e.node(t)})})),e.nodes().forEach((function(t){const n=e.children(t),r=e.edges();n.length>0?(d.l.debug("Cluster identified",t,h),r.forEach((e=>{e.v!==t&&e.w!==t&&f(e.v,t)^f(e.w,t)&&(d.l.warn("Edge: ",e," leaves cluster ",t),d.l.warn("Descendants of XXX ",t,": ",h[t]),c[t].externalConnections=!0)}))):d.l.debug("Not a cluster ",t,h)}));for(let t of Object.keys(c)){const n=c[t].id,r=e.parent(n);r!==t&&c[r]&&!c[r].externalConnections&&(c[t].id=r)}e.edges().forEach((function(t){const n=e.edge(t);d.l.warn("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(t)),d.l.warn("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(e.edge(t)));let r=t.v,i=t.w;if(d.l.warn("Fix XXX",c,"ids:",t.v,t.w,"Translating: ",c[t.v]," --- ",c[t.w]),c[t.v]&&c[t.w]&&c[t.v]===c[t.w]){d.l.warn("Fixing and trixing link to self - removing XXX",t.v,t.w,t.name),d.l.warn("Fixing and trixing - removing XXX",t.v,t.w,t.name),r=v(t.v),i=v(t.w),e.removeEdge(t.v,t.w,t.name);const a=t.w+"---"+t.v;e.setNode(a,{domId:a,id:a,labelStyle:"",labelText:n.label,padding:0,shape:"labelRect",style:""});const o=structuredClone(n),l=structuredClone(n);o.label="",o.arrowTypeEnd="none",l.label="",o.fromCluster=t.v,l.toCluster=t.v,e.setEdge(r,a,o,t.name+"-cyclic-special"),e.setEdge(a,i,l,t.name+"-cyclic-special")}else if(c[t.v]||c[t.w]){if(d.l.warn("Fixing and trixing - removing XXX",t.v,t.w,t.name),r=v(t.v),i=v(t.w),e.removeEdge(t.v,t.w,t.name),r!==t.v){const i=e.parent(r);c[i].externalConnections=!0,n.fromCluster=t.v}if(i!==t.w){const r=e.parent(i);c[r].externalConnections=!0,n.toCluster=t.w}d.l.warn("Fix Replacing with XXX",r,i,t.name),e.setEdge(r,i,n,t.name)}})),d.l.warn("Adjusted Graph",i.M(e)),y(e,0),d.l.trace(c)}})(t),d.l.warn("Graph after:",JSON.stringify(i.M(t)));const l=(0,d.c)();await C(e,t,r,o,void 0,l)}}}]); \ No newline at end of file diff --git a/assets/js/89ad43f4.7fe772fe.js b/assets/js/89ad43f4.7fe772fe.js new file mode 100644 index 0000000000..e9a4bac344 --- /dev/null +++ b/assets/js/89ad43f4.7fe772fe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2884],{18648:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>c,contentTitle:()=>d,default:()=>u,frontMatter:()=>o,metadata:()=>n,toc:()=>a});const n=JSON.parse('{"id":"iaas/guides/deploy-guide/services/index","title":"Services","description":"The prerequisite for deploying the services of a cluster is the bootstrap of","source":"@site/docs/02-iaas/guides/deploy-guide/services/index.md","sourceDirName":"02-iaas/guides/deploy-guide/services","slug":"/iaas/guides/deploy-guide/services/","permalink":"/docs/iaas/guides/deploy-guide/services/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/index.md","tags":[],"version":"current","sidebarPosition":100,"frontMatter":{"sidebar_label":"Services","sidebar_position":100},"sidebar":"docs","previous":{"title":"Rookify (technical preview)","permalink":"/docs/iaas/guides/deploy-guide/rookify"},"next":{"title":"Infrastructure","permalink":"/docs/iaas/guides/deploy-guide/services/infrastructure"}}');var t=s(74848),r=s(28453);const o={sidebar_label:"Services",sidebar_position:100},d="Services",c={},a=[];function l(e){const i={a:"a",admonition:"admonition",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.header,{children:(0,t.jsx)(i.h1,{id:"services",children:"Services"})}),"\n",(0,t.jsx)(i.admonition,{type:"info",children:(0,t.jsxs)(i.p,{children:["The prerequisite for deploying the services of a cluster is the bootstrap of\nthe nodes. How to bootstrap the nodes is documented in the\n",(0,t.jsx)(i.a,{href:"/docs/iaas/guides/deploy-guide/bootstrap",children:"Bootstrap chapter of the Deploy Guide"}),"."]})}),"\n",(0,t.jsx)(i.p,{children:"When setting up a new cluster, the services are deployed in a specific order."}),"\n",(0,t.jsxs)(i.ol,{children:["\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"./infrastructure",children:"Infrastructure"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"./network",children:"Network"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"./logging-monitoring",children:"Logging & Monitoring"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"./ceph",children:"Ceph"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"./openstack",children:"OpenStack"})}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"In the examples, the pull of images (if supported by a role) is always run first. While\nthis is optional, it is recommended to speed up the execution of the deploy action in\nthe second step. This significantly reduces the time required for the deployment of new\nservices."})]})}function u(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,i,s)=>{s.d(i,{R:()=>o,x:()=>d});var n=s(96540);const t={},r=n.createContext(t);function o(e){const i=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function d(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),n.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8aade8b1.73db4d76.js b/assets/js/8aade8b1.73db4d76.js new file mode 100644 index 0000000000..b6fec67ed0 --- /dev/null +++ b/assets/js/8aade8b1.73db4d76.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6305],{33154:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/nova","title":"Nova","description":"Get all servers on a node","source":"@site/docs/02-iaas/guides/operations-guide/openstack/nova.md","sourceDirName":"02-iaas/guides/operations-guide/openstack","slug":"/iaas/guides/operations-guide/openstack/nova","permalink":"/docs/iaas/guides/operations-guide/openstack/nova","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/nova.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Nova"},"sidebar":"docs","previous":{"title":"Neutron","permalink":"/docs/iaas/guides/operations-guide/openstack/neutron"},"next":{"title":"Octavia","permalink":"/docs/iaas/guides/operations-guide/openstack/octavia"}}');var a=s(74848),t=s(28453);const r={sidebar_label:"Nova"},d="Nova",i={},c=[{value:"Get all servers on a node",id:"get-all-servers-on-a-node",level:2},{value:"Stop all servers running on a node",id:"stop-all-servers-running-on-a-node",level:2},{value:"Disable & enable a compute service",id:"disable--enable-a-compute-service",level:2},{value:"Force down & up a compute service",id:"force-down--up-a-compute-service",level:2},{value:"Huge pages",id:"huge-pages",level:2},{value:"Quality of Service (QoS)",id:"quality-of-service-qos",level:2},{value:"Host aggregates",id:"host-aggregates",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"nova",children:"Nova"})}),"\n",(0,a.jsx)(n.h2,{id:"get-all-servers-on-a-node",children:"Get all servers on a node"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"openstack --os-cloud admin server list --all-projects --host testbed-node-0\n"})}),"\n",(0,a.jsx)(n.h2,{id:"stop-all-servers-running-on-a-node",children:"Stop all servers running on a node"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"for server in $(openstack --os-cloud admin server list --all-projects --host testbed-node-0 --vm-state active -f value -c ID | tr -d '\\r'); do\n echo stopping server $server\n openstack --os-cloud admin server stop $server\n sleep 2\ndone\n"})}),"\n",(0,a.jsx)(n.h2,{id:"disable--enable-a-compute-service",children:"Disable & enable a compute service"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"openstack --os-cloud admin compute service set --disable --description MAINTENANCE testbed-node-0 nova-compute\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"openstack --os-cloud admin compute service list --long\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n| ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | up | 2023-12-14T14:20:24.000000 | MAINTENANCE | False |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"openstack --os-cloud admin compute service set --enable testbed-node-0 nova-compute\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"openstack --os-cloud admin compute service list\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+\n| ID | Binary | Host | Zone | Status | State | Updated At |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+\n| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | enabled | up | 2023-12-14T14:22:54.000000 |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+\n"})}),"\n",(0,a.jsx)(n.h2,{id:"force-down--up-a-compute-service",children:"Force down & up a compute service"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"openstack --os-cloud admin --os-compute-api-version 2.12 compute service set --down testbed-node-0 nova-compute\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"openstack --os-cloud admin compute service list --long\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n| ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | down | 2023-12-14T14:21:47.000000 | None | True |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"openstack --os-cloud admin --os-compute-api-version 2.12 compute service set --up testbed-node-0 nova-compute\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"openstack --os-cloud admin compute service list --long\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n| ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | up | 2023-12-14T14:20:24.000000 | None | False |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n"})}),"\n",(0,a.jsx)(n.h2,{id:"huge-pages",children:"Huge pages"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"$ grep Huge /proc/meminfo\nAnonHugePages: 0 kB\nShmemHugePages: 0 kB\nFileHugePages: 0 kB\nHugePages_Total: 0\nHugePages_Free: 0\nHugePages_Rsvd: 0\nHugePages_Surp: 0\nHugepagesize: 2048 kB\nHugetlb: 0 kB\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"$ sudo sudo hugeadm --pool-list\nlibhugetlbfs: ERROR: Line too long when parsing mounts\n Size Minimum Current Maximum Default\n 2097152 0 0 0 *\n1073741824 0 0 0\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:'/etc/default/grub\nGRUB_CMDLINE_LINUX="default_hugepagesz=1G hugepagesz=1G hugepages=512 transparent_hugepage=never"\n'})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"update-grub\nreboot\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"$ grep Huge /proc/meminfo\nAnonHugePages: 0 kB\nShmemHugePages: 0 kB\nFileHugePages: 0 kB\nHugePages_Total: 512\nHugePages_Free: 512\nHugePages_Rsvd: 0\nHugePages_Surp: 0\nHugepagesize: 1048576 kB\nHugetlb: 536870912 kB\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"$ sudo hugeadm --pool-list\nlibhugetlbfs: ERROR: Line too long when parsing mounts\n Size Minimum Current Maximum Default\n 2097152 0 0 0 *\n1073741824 512 512 512\n"})}),"\n",(0,a.jsx)(n.h2,{id:"quality-of-service-qos",children:"Quality of Service (QoS)"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/admin/resource-limits.html",children:"https://docs.openstack.org/nova/latest/admin/resource-limits.html"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"host-aggregates",children:"Host aggregates"}),"\n",(0,a.jsxs)(n.p,{children:["Host aggregates can be managed with the playbook. The playbook is used with\n",(0,a.jsx)(n.code,{children:"osism apply -e openstack host-aggregates"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Further arguments for host aggregates can be found in the\n",(0,a.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/collections/openstack/cloud/host_aggregate_module.html",children:"documentation for the openstack.cloud.host_aggregate"})," Ansible module."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/openstack/playbook-host-aggregates.yml"',children:'---\n- name: Manage host aggregates\n hosts: localhost\n connection: local\n\n vars:\n host_aggregates:\n - name: aggregate1\n hosts:\n - host1\n - host2\n - host3\n\n tasks:\n - name: Create host aggregate\n openstack.cloud.host_aggregate:\n cloud: admin\n state: present\n name: "{{ item.name }}"\n hosts: "{{ item.hosts }}"\n loop: "{{ host_aggregates }}"\n'})})]})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>d});var o=s(96540);const a={},t=o.createContext(a);function r(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8b8a137c.7fe34161.js b/assets/js/8b8a137c.7fe34161.js new file mode 100644 index 0000000000..7b1808892b --- /dev/null +++ b/assets/js/8b8a137c.7fe34161.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[37074],{19027:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>o});const s=JSON.parse('{"id":"iaas/guides/configuration-guide/network","title":"Network","description":"Netplan","source":"@site/docs/02-iaas/guides/configuration-guide/network.md","sourceDirName":"02-iaas/guides/configuration-guide","slug":"/iaas/guides/configuration-guide/network","permalink":"/docs/iaas/guides/configuration-guide/network","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/network.md","tags":[],"version":"current","sidebarPosition":15,"frontMatter":{"sidebar_label":"Network","sidebar_position":15},"sidebar":"docs","previous":{"title":"Manager","permalink":"/docs/iaas/guides/configuration-guide/manager"},"next":{"title":"Proxy","permalink":"/docs/iaas/guides/configuration-guide/proxy"}}');var r=t(74848),i=t(28453);const l={sidebar_label:"Network",sidebar_position:15},a="Network",d={},o=[{value:"Netplan",id:"netplan",level:2},{value:"Example",id:"example",level:3},{value:"Dispatcher scripts",id:"dispatcher-scripts",level:3},{value:"Dummy interfaces",id:"dummy-interfaces",level:3},{value:"<code>/etc/interfaces</code>",id:"etcinterfaces",level:2},{value:"IPv6 fabric underlay",id:"ipv6-fabric-underlay",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"network",children:"Network"})}),"\n",(0,r.jsx)(n.h2,{id:"netplan",children:"Netplan"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",metastring:'title="Since OSISM 6.1.0, the default network type is a netplan and no longer needs to be set explicitly"',children:"network_type: netplan\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The configuration is written to ",(0,r.jsx)(n.code,{children:"/etc/netplan/01-osism.yaml"})," by default. Can be changed\nvia the ",(0,r.jsx)(n.code,{children:"network_netplan_path"})," and ",(0,r.jsx)(n.code,{children:"network_netplan_file"})," parameters. The file permissions\nare ",(0,r.jsx)(n.code,{children:"0600"})," by default (cane be changed via the ",(0,r.jsx)(n.code,{children:"network_netplan_permissions"})," parameter).\nBy default, all other files in ",(0,r.jsx)(n.code,{children:"/etc/netplan"})," are removed. If you do not want this, you\ncan set ",(0,r.jsx)(n.code,{children:"network_netplan_remove_unmanaged_files"})," to ",(0,r.jsx)(n.code,{children:"false"}),". It is also possible to explicitly\nlist individual files that should not be deleted in ",(0,r.jsx)(n.code,{children:"network_netplan_managed_files_extra"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["An existing ",(0,r.jsx)(n.code,{children:"/etc/intefaces"})," file is replaced with a placeholder file. It is not possible\nto use ",(0,r.jsx)(n.code,{children:"/etc/interfaces"})," and Netplan in parallel."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",metastring:'title="This template is used as the base for the configuration"',children:"# This file describes the network interfaces available on your system\n# For more information, see netplan(5).\n---\nnetwork:\n version: {{ network_version }}\n renderer: {{ network_renderer }}\n\n bonds:\n {{ network_bonds|to_nice_yaml(indent=4)|indent(4) }}\n\n bridges:\n {{ network_bridges|to_nice_yaml(indent=4)|indent(4) }}\n\n ethernets:\n {{ network_ethernets|to_nice_yaml(indent=4)|indent(4) }}\n\n tunnels:\n {{ network_tunnels|to_nice_yaml(indent=4)|indent(4) }}\n\n vlans:\n {{ network_vlans|to_nice_yaml(indent=4)|indent(4) }}\n\n vrfs:\n {{ network_vrfs|to_nice_yaml(indent=4)|indent(4) }}\n"})}),"\n",(0,r.jsx)(n.p,{children:"The parameters listed in the following table can be used in the template."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,r.jsx)(n.th,{style:{textAlign:"left"},children:"Default"}),(0,r.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"network_version"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"2"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Defines what version of the configuration format is used. The only value supported at the moment is 2."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"network_renderer"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"networkd"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"Defines what network configuration tool will be used to set up your configuration."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"network_bonds"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"{}"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bonds",children:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bonds"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"network_bridges"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"{}"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bridges",children:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bridges"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"network_ethernets"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"{}"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-ethernets",children:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-ethernets"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"network_tunnels"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"{}"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-tunnels",children:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-tunnels"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"network_vlans"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"{}"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vlans",children:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vlans"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{style:{textAlign:"left"},children:"network_vrfs"}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.code,{children:"{}"})}),(0,r.jsx)(n.td,{style:{textAlign:"left"},children:(0,r.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vrfs",children:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vrfs"})})]})]})]}),"\n",(0,r.jsxs)(n.p,{children:["By default changes to the network configuration are not applied automatically. This is done on\npurpose to allow a manual check in advance. Changes to the network configuration can\nbe applied either by rebooting or by executing ",(0,r.jsx)(n.code,{children:"netplan apply"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ osism console --type clush all\nEnter 'quit' to leave this interactive mode\nWorking with nodes: testbed-manager.testbed.osism.xyz,testbed-node-[0-2].testbed.osism.xyz\nclush> sudo netplan apply\n"})}),"\n",(0,r.jsxs)(n.p,{children:["It is possible to execute the ",(0,r.jsx)(n.code,{children:"netplan apply"})," automatically via a handler when changes are made.\nThe parameter ",(0,r.jsx)(n.code,{children:"network_allow_service_restart"})," is used for this."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"network_allow_service_restart: true\n"})}),"\n",(0,r.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,r.jsxs)(n.p,{children:["The Netplan documentation contains a large number of example configurations. The following\nexample shows the use of ",(0,r.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/examples/#how-to-create-vlans",children:"How to create VLANs"})," with the osism.commons.network role."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'network_ethernets:\n mainif:\n match:\n macaddress: "de:ad:be:ef:ca:fe"\n set-name: mainif\n addresses: [ "10.3.0.5/23" ]\n nameservers:\n addresses: [ "8.8.8.8", "8.8.4.4" ]\n search: [ example.com ]\n routes:\n - to: default\n via: 10.3.0.1\n\nnetwork_vlans:\n vlan15:\n id: 15\n link: mainif\n addresses: [ "10.3.99.5/24" ]\n vlan10:\n id: 10\n link: mainif\n addresses: [ "10.3.98.5/24" ]\n nameservers:\n addresses: [ "127.0.0.1" ]\n search: [ domain1.example.com, domain2.example.com ]\n'})}),"\n",(0,r.jsx)(n.h3,{id:"dispatcher-scripts",children:"Dispatcher scripts"}),"\n",(0,r.jsx)(n.h3,{id:"dummy-interfaces",children:"Dummy interfaces"}),"\n",(0,r.jsxs)(n.p,{children:["Dummy devices are created with the help of\n",(0,r.jsx)(n.a,{href:"https://www.freedesktop.org/software/systemd/man/latest/systemd.netdev.html",children:"systemd.netdev"}),"\nand can then be used as a normal netowrk device in the Netplan configuration."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"network_dummy_interfaces:\n - dummy0\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The MTU is set to 9000 by default and can be set via ",(0,r.jsx)(n.code,{children:"network_dummy_interface_mtu"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"etcinterfaces",children:(0,r.jsx)(n.code,{children:"/etc/interfaces"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",metastring:'title="If /etc/interfaces is to be used, the network_type must be explicitly set in environments/configuration.yml"',children:"network_type: interfaces\n"})}),"\n",(0,r.jsx)(n.h2,{id:"ipv6-fabric-underlay",children:"IPv6 fabric underlay"}),"\n",(0,r.jsxs)(n.p,{children:["Example configuration for a node. The configuration is stored in the ",(0,r.jsx)(n.code,{children:"host_vars"})," file for the node in ",(0,r.jsx)(n.code,{children:"inventory"}),"\ndirectory in the configuration repository."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"##########################################################\n# ansible\n\nansible_host: 10.10.42.10\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"##########################################################\n# generic\n\ninternal_interface: dummy0\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"##########################################################\n# network\n\nnetwork_type: netplan\nnetwork_dummy_interfaces:\n - dummy0\nnetwork_ethernets:\n enp99s0f0np0:\n mtu: 9100\n enp99s0f1np1:\n mtu: 9100\n dummy0:\n addresses:\n - 10.10.42.10/32\n - 2001:db8::10:10:42:10/128\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"##########################################################\n# frr\n\nfrr_local_as: 4210042010\nfrr_loopback_v4: 10.10.42.10\nfrr_loopback_v6: 2001:db8::10:10:42:10\nfrr_uplinks:\n - interface: enp99s0f0np0\n remote_as: 65401\n - interface: enp99s0f1np1\n remote_as: 65402\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'##########################################################\n# kolla\n\nnetwork_interface: "{{ internal_interface }}"\n'})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>l,x:()=>a});var s=t(96540);const r={},i=s.createContext(r);function l(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8d25d5d4.7179def6.js b/assets/js/8d25d5d4.7179def6.js new file mode 100644 index 0000000000..cc5169a31d --- /dev/null +++ b/assets/js/8d25d5d4.7179def6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[64277],{49516:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>a,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"operations/iam/openstack-federation-via-oidc","title":"OpenStack Federation via OpenID-Connect","description":"Keystone supports federating authentication and authorization decisions via several mechanisms","source":"@site/contributor-docs/operations/iam/openstack-federation-via-oidc.md","sourceDirName":"operations/iam","slug":"/operations/iam/openstack-federation-via-oidc","permalink":"/contributor-docs/operations/iam/openstack-federation-via-oidc","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"OpenStack Federation via OpenID-Connect","type":null,"status":"Draft","track":"Global"},"sidebar":"devDocs","previous":{"title":"Identity Federation in SCS","permalink":"/contributor-docs/operations/iam/identity-federation-in-scs"},"next":{"title":"Zuul users guide","permalink":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide"}}');var s=n(74848),i=n(28453);const a={title:"OpenStack Federation via OpenID-Connect",type:null,status:"Draft",track:"Global"},r=void 0,c={},d=[{value:"1. Keystone",id:"1-keystone",level:2},{value:"1.1 Keycloak IdP realm discovery",id:"11-keycloak-idp-realm-discovery",level:3},{value:"1.2 Keystone mapping of token claims",id:"12-keystone-mapping-of-token-claims",level:3},{value:"1.3 Horizon WebSSO for federated users",id:"13-horizon-websso-for-federated-users",level:3},{value:"1.4 OpenStack CLI and API access for federated users",id:"14-openstack-cli-and-api-access-for-federated-users",level:3},{value:"1.5 SSO Federation between to SCS deployments",id:"15-sso-federation-between-to-scs-deployments",level:3}];function h(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(t.p,{children:["Keystone supports federating authentication and authorization decisions via several mechanisms\nas ",(0,s.jsx)(t.a,{href:"https://docs.openstack.org/keystone/latest/admin/federation/introduction.html",children:"documented by the project"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["In SCS OpenID Connect is used for federation between Keystone and the IdP, which is\n",(0,s.jsx)(t.a,{href:"https://docs.scs.community/standards/scs-0300-v1-requirements-for-sso-identity-federation",children:"currently provided by Keycloak"}),"\nin SCS."]}),"\n",(0,s.jsx)(t.p,{children:"The following sections describe the setup."}),"\n",(0,s.jsx)(t.h2,{id:"1-keystone",children:"1. Keystone"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://docs.openstack.org/keystone/latest/admin/federation/federated_identity.html",children:"Keystone supports federated identities"}),".\nTo allow SCS to consume identities managed in external IAM solutions,\nfederation protocols like OpenID Connect or SAML can be used.\nKeystone currently makes use of third party apache modules like\n",(0,s.jsx)(t.a,{href:"https://github.com/OpenIDC/mod_auth_openidc",children:"mod_auth_openidc"}),",\n",(0,s.jsx)(t.a,{href:"https://github.com/OpenIDC/mod_oauth2",children:"mod_oauth2"})," and\n",(0,s.jsx)(t.a,{href:"https://github.com/UNINETT/mod_auth_mellon",children:"mod_auth_mellon"})," to delegate\nauthentication to a SSO IdP (i.e. SAML IdP or OpenID Connect provider)."]}),"\n",(0,s.jsxs)(t.p,{children:["In OpenStack the apache modules are configured using the\n",(0,s.jsx)(t.a,{href:"https://github.com/openstack/kolla-ansible/tree/master/ansible/roles/keystone/templates",children:"wsgi-keystone.conf template"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"In SCS we make use of the OAuth 2.0 Authorization Code Grant flow between Keystone and Keycloak\nand use PKCE (RFC 7636) with the S256 challenge method."}),"\n",(0,s.jsx)(t.p,{children:"In addition to the usual SSL CA of the environment, Keycloak uses separate certificates to sign the OIDC tokens."}),"\n",(0,s.jsx)(t.p,{children:"Due to the way the Keystone container image runs apache (in the foreground) and keystone itself (as WSGI module),\nreconfiguring the apache URL locations on the fly is not possible currently without a downtime of several seconds.\nThat is the reason why SCS currently makes use of a single central proxy realm in Keycloak, to which Keystone\nconnects."}),"\n",(0,s.jsx)(t.h3,{id:"11-keycloak-idp-realm-discovery",children:"1.1 Keycloak IdP realm discovery"}),"\n",(0,s.jsxs)(t.p,{children:["Keycloak offers standard OIDC service discovery via ",(0,s.jsx)(t.code,{children:".well-known"})," documents to advertise its endpoints."]}),"\n",(0,s.jsx)(t.p,{children:"In SCS we want to represent each customer by a separate dedicated Keycloak realm, which can enventually be used\nfor customer self service and to federate out to customer owned IAM external solutions."}),"\n",(0,s.jsxs)(t.p,{children:["In the SCS testbed we currently experiment with the implications of using a single central proxy realm in Keycloak\nand chaining federation from there to customer specific realms, also hosted in the same Keycloak instance.\nTo make this usable, SCS makes use of the\n",(0,s.jsx)(t.a,{href:"https://github.com/sventorben/keycloak-home-idp-discovery",children:"Keycloak Home IdP Discovery"}),"\nextension."]}),"\n",(0,s.jsx)(t.h3,{id:"12-keystone-mapping-of-token-claims",children:"1.2 Keystone mapping of token claims"}),"\n",(0,s.jsxs)(t.p,{children:["Upon login of a user Keystone evaluates the credentials obtained from the ID token that the IdP issued.\nThese include group memberships and roles, which can be used to assign the user to a certain project.\nKeystone maps these external identities to internal (shadow) users.\nIt can either attempt to map the obtained information to a ",(0,s.jsx)(t.code,{children:"local"})," type user, which needs to be\nprovisioned before authentication by external tooling, or it can be instructed via the mapping to\ngenerate an ",(0,s.jsx)(t.code,{children:"ephemeral"})," type user. ",(0,s.jsx)(t.code,{children:"ephemeral"})," users are cleaned up automatically after some time\nof inactivity and with that, they lose access to projects, iff the access is granted indirectly\nvia group membership rather than directly to the user itself."]}),"\n",(0,s.jsxs)(t.p,{children:["Group memberships for ",(0,s.jsx)(t.code,{children:"ephemeral"})," users are only represented via their tokens, but not stored in the\nKeystone backend database."]}),"\n",(0,s.jsxs)(t.p,{children:["After successful authorization Keystone issues an OpenStack specific ",(0,s.jsx)(t.code,{children:"fernet"})," token to the user,\nwhich is the currency that is understood by other OpenStack services and can be used to access them."]}),"\n",(0,s.jsx)(t.p,{children:"In SCS we want to represent each customer by a sepatate dedicated OpenStack domain to host\ntheir projects and (shadow) user accounts."}),"\n",(0,s.jsxs)(t.p,{children:["The processing of information from the OIDC tokens is configured by two parts. The first part is the\n",(0,s.jsx)(t.code,{children:"rules.json"})," mapping which is described in the\n",(0,s.jsx)(t.a,{href:"https://docs.openstack.org/keystone/latest/admin/federation/mapping_combinations.html",children:"OpenStack federation mapping combinations"}),"\ndocument. This file is used to configure Keystones internal mapping engine\nand it needs to be attached to some OpenStack domain, which is named ",(0,s.jsx)(t.code,{children:"keycloak"})," by default in SCS."]}),"\n",(0,s.jsxs)(t.p,{children:["The second (static) part is the ",(0,s.jsx)(t.code,{children:"[auth]"})," and ",(0,s.jsx)(t.code,{children:"[mapped]"})," sections in ",(0,s.jsx)(t.code,{children:"keystone.conf"})," (see e.g.\n",(0,s.jsx)(t.a,{href:"https://github.com/osism/testbed/tree/main/environments/kolla/files/overlays/keystone",children:"the overlays currently used in the OSISM testbed"}),"\n)."]}),"\n",(0,s.jsx)(t.h3,{id:"13-horizon-websso-for-federated-users",children:"1.3 Horizon WebSSO for federated users"}),"\n",(0,s.jsx)(t.p,{children:"The Horizon dashboard supports login via OpenID Connect via Keystone endpoint.\nSCS adjusted the logout behavior to invalidate both, the OpenID Connect session\nwith the IdP and the Keystone token."}),"\n",(0,s.jsx)(t.h3,{id:"14-openstack-cli-and-api-access-for-federated-users",children:"1.4 OpenStack CLI and API access for federated users"}),"\n",(0,s.jsx)(t.p,{children:"To support OpenStack CLI and API access, SCS implemented support for the OIDC Device Authorization Grant\nin Keystone. On top we added support for PKCE (RFC 7636) in combination with that."}),"\n",(0,s.jsx)(t.h3,{id:"15-sso-federation-between-to-scs-deployments",children:"1.5 SSO Federation between to SCS deployments"}),"\n",(0,s.jsxs)(t.p,{children:["To show the potential of this approach to federation SCS created a\n",(0,s.jsx)(t.a,{href:"https://docs-staging.scs.community/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations",children:"Howto for OIDC federation between SCS deployments"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var o=n(96540);const s={},i=o.createContext(s);function a(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8db05b07.2b969d73.js b/assets/js/8db05b07.2b969d73.js new file mode 100644 index 0000000000..05bd823a94 --- /dev/null +++ b/assets/js/8db05b07.2b969d73.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[63663],{60758:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"iaas/components/openstack-health-monitor","title":"Setting up OpenStack health monitor on Debian","description":"Kurt Garloff, 2024-02-20","source":"@site/docs/02-iaas/components/openstack-health-monitor.md","sourceDirName":"02-iaas/components","slug":"/iaas/components/openstack-health-monitor","permalink":"/docs/iaas/components/openstack-health-monitor","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/openstack-health-monitor.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"OpenStack Health Monitor"}}');var s=t(74848),a=t(28453);const i={sidebar_label:"OpenStack Health Monitor"},r="Setting up OpenStack health monitor on Debian",l={},d=[{value:"Intro",id:"intro",level:2},{value:"Setting up the driver VM",id:"setting-up-the-driver-vm",level:2},{value:"Internal vs external monitoring",id:"internal-vs-external-monitoring",level:3},{value:"Unprivileged operation",id:"unprivileged-operation",level:3},{value:"Driver VM via openstack CLI",id:"driver-vm-via-openstack-cli",level:3},{value:"Configuring openstack CLI on the driver VM",id:"configuring-openstack-cli-on-the-driver-vm",level:3},{value:"Custom CA",id:"custom-ca",level:3},{value:"Your first <code>api_monitor.sh</code> iteration",id:"your-first-api_monitorsh-iteration",level:2},{value:"Resource impact and charging",id:"resource-impact-and-charging",level:3},{value:"Automating startup and cleanup",id:"automating-startup-and-cleanup",level:2},{value:"Changing parameters and restarting",id:"changing-parameters-and-restarting",level:3},{value:"Multiple instances",id:"multiple-instances",level:3},{value:"Alarming and Logs",id:"alarming-and-logs",level:2},{value:"eMail",id:"email",level:3},{value:"Log files",id:"log-files",level:3},{value:"Data collection and dashboard",id:"data-collection-and-dashboard",level:2},{value:"Telegraf",id:"telegraf",level:3},{value:"InfluxDB",id:"influxdb",level:3},{value:"Add <code>-S CLOUDNAME</code> to your <code>run_CLOUDNAME.sh</code> script",id:"add--s-cloudname-to-your-run_cloudnamesh-script",level:3},{value:"Caddy (Reverse Proxy)",id:"caddy-reverse-proxy",level:3},{value:"Install Caddy",id:"install-caddy",level:4},{value:"Allow HTTP traffic for oshm-driver",id:"allow-http-traffic-for-oshm-driver",level:4},{value:"Configure Caddy",id:"configure-caddy",level:4},{value:"Grafana",id:"grafana",level:3},{value:"Install Grafana",id:"install-grafana",level:4},{value:"Basic config",id:"basic-config",level:4},{value:"Enable influx database in grafana",id:"enable-influx-database-in-grafana",level:4},{value:"Importing the dashboard",id:"importing-the-dashboard",level:4},{value:"No data displayed?",id:"no-data-displayed",level:4},{value:"Dashboard features",id:"dashboard-features",level:4},{value:"GitHub OIDC Integration",id:"github-oidc-integration",level:4},{value:"Maintenance",id:"maintenance",level:2},{value:"Unattended upgrades",id:"unattended-upgrades",level:3},{value:"sshd setup",id:"sshd-setup",level:3},{value:"Updating openstack-health-monitor",id:"updating-openstack-health-monitor",level:3},{value:"Backup",id:"backup",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Debugging issues",id:"debugging-issues",level:3},{value:"Analyzing failures",id:"analyzing-failures",level:3},{value:"Cleaning things up",id:"cleaning-things-up",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"setting-up-openstack-health-monitor-on-debian",children:"Setting up OpenStack health monitor on Debian"})}),"\n",(0,s.jsx)(n.p,{children:"Kurt Garloff, 2024-02-20"}),"\n",(0,s.jsx)(n.h2,{id:"intro",children:"Intro"}),"\n",(0,s.jsxs)(n.p,{children:["The development of ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/",children:"openstack-health-monitor"})," was done on ",(0,s.jsx)(n.a,{href:"https://kfg.images.obs-website.eu-de.otc.t-systems.com/",children:"openSUSE 15.x images"}),", just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution."]}),"\n",(0,s.jsx)(n.p,{children:"Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here."}),"\n",(0,s.jsxs)(n.p,{children:["Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor",children:"successor project"})," for the increasingly hard to maintain shell code, this may not be worth the trouble."]}),"\n",(0,s.jsxs)(n.p,{children:["openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested.\nThe scenario is described in a bit more detail in the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"repository's README.md"})," file."]}),"\n",(0,s.jsxs)(n.p,{children:["The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/docs/category/monitoring",children:"monitoring section"})," of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up."]}),"\n",(0,s.jsx)(n.h2,{id:"setting-up-the-driver-vm",children:"Setting up the driver VM"}),"\n",(0,s.jsxs)(n.p,{children:["So we start a ",(0,s.jsx)(n.code,{children:"Debian 12"})," image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard;\nthe instructions use flavor names and image names from the SCS standards.\nFor many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack)."]}),"\n",(0,s.jsx)(n.h3,{id:"internal-vs-external-monitoring",children:"Internal vs external monitoring"}),"\n",(0,s.jsx)(n.p,{children:"There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor."}),"\n",(0,s.jsx)(n.p,{children:"The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems."}),"\n",(0,s.jsx)(n.h3,{id:"unprivileged-operation",children:"Unprivileged operation"}),"\n",(0,s.jsx)(n.p,{children:"Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own."}),"\n",(0,s.jsxs)(n.p,{children:["If ",(0,s.jsx)(n.code,{children:"openstack availability zone list --compute"})," fails for you without admin rights, please fix your openstack client, e.g. by applying the ",(0,s.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/openstack-health-monitor/main/docs/openstackclient-az-list-fallback-f3207bd.diff",children:"patch"})," I mentioned in ",(0,s.jsx)(n.a,{href:"https://storyboard.openstack.org/#!/story/2010989",children:"this issue"}),". (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Health-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)"]}),"\n",(0,s.jsx)(n.h3,{id:"driver-vm-via-openstack-cli",children:"Driver VM via openstack CLI"}),"\n",(0,s.jsxs)(n.p,{children:["The author prefers to setup the VM via ",(0,s.jsx)(n.code,{children:"openstack"})," CLI tooling. He has working entries for all clouds he uses in his ",(0,s.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})," and ",(0,s.jsx)(n.code,{children:"secure.yaml"})," and has exported the ",(0,s.jsx)(n.code,{children:"OS_CLOUD"})," environment variable to point to the cloud he is working on to set up the driver VM. The author uses the ",(0,s.jsx)(n.code,{children:"bash"})," shell. All of this of course could be scripted."]}),"\n",(0,s.jsx)(n.p,{children:"So here we go"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Create the network setup for a VM in a network ",(0,s.jsx)(n.code,{children:"oshm-network"})," with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network."]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"PUBLIC=$(openstack network list --external -f value -c Name)\nopenstack router create oshm-router\nopenstack router set --external-gateway $PUBLIC oshm-driver-router\nopenstack network create oshm-network\nopenstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet\nopenstack router add subnet oshm-router oshm-subnet\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsx)(n.li,{children:"Create a security group that allows ssh and ping access"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack security group create sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsx)(n.li,{children:"Being at it, we also create the security group for grafana"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack security group create grafana\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"To connect to the VM via ssh later, we create an SSH keypair"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key\nchmod og-r ~/.ssh/oshm-key.pem \n"})}),"\n",(0,s.jsxs)(n.p,{children:["Rather than creating a new key (and storing and protecting the private key), we could have passed ",(0,s.jsx)(n.code,{children:"--public-key"})," and used an existing keypair."]}),"\n",(0,s.jsxs)(n.ol,{start:"5",children:["\n",(0,s.jsx)(n.li,{children:"Look up Debian 12 image UUID."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"IMGUUID=$(openstack image list --name \"Debian 12\" -f value -c ID | tr -d '\\r')\necho $IMGUUID\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Sidenote: The ",(0,s.jsx)(n.code,{children:"tr"})," command is there to handle broken tooling that embeds a trailing ",(0,s.jsx)(n.code,{children:"\\r"})," in the output."]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsx)(n.li,{children:"Boot the driver VM"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing ",(0,s.jsx)(n.code,{children:"--block-device"}),". See ",(0,s.jsx)(n.a,{href:"https://scs.community/2023/08/21/diskless-flavors/",children:"diskless flavor blog article"}),". For flavors with local root disks, you could have used the ",(0,s.jsx)(n.code,{children:"--image $IMGUUID"})," parameter instead."]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:["Wait for it to boot (optional)\nYou can look at the boot log with ",(0,s.jsx)(n.code,{children:"openstack console log show oshm-driver"})," or connect to it via VNC at the URL given by ",(0,s.jsx)(n.code,{children:"openstack console url show oshm-driver"}),". You can of course also query openstack on the status ",(0,s.jsx)(n.code,{children:"openstack server list"})," or ",(0,s.jsx)(n.code,{children:"openstack server show oshm-driver"}),". You can also just create a simple loop:"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'declare -i ctr=0 RC=0\nwhile [ $ctr -le 120 ]; do\n STATUS="$(openstack server list --name oshm-driver -f value -c Status)"\n if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi \n if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi\n if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi\n sleep 2\n let ctr+=1\ndone\n# return $RC\nif [ $RC != 0 ]; then false; fi\n'})}),"\n",(0,s.jsxs)(n.ol,{start:"8",children:["\n",(0,s.jsx)(n.li,{children:"Attach a floating IP so it's reachable from the outside."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks | sed "s@^[^:]*:[^\']*\'\\([0-9\\.]*\\)\'.*\\$@\\1@")\nFIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)\necho $FIXEDIP $FIXEDPORT\nopenstack floating ip create --port $FIXEDPORT $PUBLIC\nFLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")\necho "Floating IP: $FLOATINGIP"\n'})}),"\n",(0,s.jsx)(n.p,{children:"Remember this floating IP address."}),"\n",(0,s.jsxs)(n.ol,{start:"9",children:["\n",(0,s.jsx)(n.li,{children:"Connect to it via ssh"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP\n"})}),"\n",(0,s.jsx)(n.p,{children:"On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"All the following commands are performed on the newly started driver VM."})}),"\n",(0,s.jsx)(n.h3,{id:"configuring-openstack-cli-on-the-driver-vm",children:"Configuring openstack CLI on the driver VM"}),"\n",(0,s.jsx)(n.p,{children:"We need to install the openstack client utilities."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"sudo apt-get update\nsudo apt-get install python3-openstackclient\nsudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Configure your cloud access in ",(0,s.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n interface: public\n identity-api-version: 3\n #region_name: REGION\n auth:\n auth_url: KEYSTONE_ENDPOINT\n project_id: PROJECT_UUID\n #alternatively project_name and project_domain_name\n user_domain_name: default\n # change to your real domain\n"})}),"\n",(0,s.jsxs)(n.p,{children:["and ",(0,s.jsx)(n.code,{children:"secure.yaml"})," (in the same directory)"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n auth:\n username: USERNAME\n password: PASSWORD\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"CLOUDNAME"})," can be freely chosen. This is the value passed to the openstack CLI with ",(0,s.jsx)(n.code,{children:"--os-cloud"})," or exported to your environment in ",(0,s.jsx)(n.code,{children:"OS_CLOUD"}),". The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample ",(0,s.jsx)(n.code,{children:"clouds.yaml"})," file that works (but lacks the password)."]}),"\n",(0,s.jsxs)(n.p,{children:["Protect your ",(0,s.jsx)(n.code,{children:"secure.yaml"})," from being read by others: ",(0,s.jsx)(n.code,{children:"chmod 0600 ~/.config/openstack/secure.yaml"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["If you are using application credentials instead of username, password to authenticate, you don't need to specify ",(0,s.jsx)(n.code,{children:"project_id"})," nor project's nor user's domain names in ",(0,s.jsx)(n.code,{children:"clouds.yaml"}),". Just (in ",(0,s.jsx)(n.code,{children:"secure.yaml"}),"):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'clouds:\n CLOUDNAME:\n auth_type: v3applicationcredential\n auth:\n application_credential_id: APPCRED_ID\n application_credential_secret: "APPCRED_SECRET"\n'})}),"\n",(0,s.jsx)(n.p,{children:"Configure this to be your default cloud:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"export OS_CLOUD=CLOUDNAME\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You might consider adding this to your ",(0,s.jsx)(n.code,{children:"~/.bashrc"})," for convenience. Being at it, you might want to add ",(0,s.jsx)(n.code,{children:"export CLIFF_FIT_WIDTH=1"})," there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste)."]}),"\n",(0,s.jsx)(n.p,{children:"Verify that your openstack CLI works:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack catalog list\nopenstack server list\n"})}),"\n",(0,s.jsx)(n.p,{children:"You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases."}),"\n",(0,s.jsx)(n.h3,{id:"custom-ca",children:"Custom CA"}),"\n",(0,s.jsxs)(n.p,{children:["If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in ",(0,s.jsx)(n.code,{children:"/etc/ssl/certs/ca-certificates.crt"}),". You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the ",(0,s.jsx)(n.code,{children:"debian"})," user."]}),"\n",(0,s.jsxs)(n.p,{children:["Add it to your ",(0,s.jsx)(n.code,{children:"clouds.yaml"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n cacert: /PATH/TO/CACERT.CRT\n [...]\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If you want to allow ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"export OS_CACERT=/PATH/TO/CACERT.CRT\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Consider adding this to your ",(0,s.jsx)(n.code,{children:"~/.bashrc"})," as well."]}),"\n",(0,s.jsxs)(n.h2,{id:"your-first-api_monitorsh-iteration",children:["Your first ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," iteration"]}),"\n",(0,s.jsx)(n.p,{children:"Checkout openstack-health-monitor:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install git bc jq netcat-traditional tmux zstd\ngit clone https://github.com/SovereignCloudStack/openstack-health-monitor\ncd openstack-health-monitor\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You may want to start a ",(0,s.jsx)(n.code,{children:"tmux"})," (or ",(0,s.jsx)(n.code,{children:"screen"}),") session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect."]}),"\n",(0,s.jsxs)(n.p,{children:["The script ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"})," file."]}),"\n",(0,s.jsxs)(n.p,{children:["It is good practice to use ",(0,s.jsx)(n.code,{children:"tmux"}),". This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to ",(0,s.jsx)(n.code,{children:"screen"})," over ",(0,s.jsx)(n.code,{children:"tmux"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'export IMG="Debian 12"\nexport JHIMG="Debian 12"\n./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Leave out the ",(0,s.jsx)(n.code,{children:"-LL"})," if you don't have a working loadbalancer service or replace ",(0,s.jsx)(n.code,{children:"-LL"})," with ",(0,s.jsx)(n.code,{children:"-LO"})," if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources)."]}),"\n",(0,s.jsxs)(n.p,{children:["Feel free to study the meaning of all the command line parameters by looking at the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"}),". (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)"]}),"\n",(0,s.jsxs)(n.p,{children:["This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs ",(0,s.jsx)(n.code,{children:"DOWN"}),", ",(0,s.jsx)(n.code,{children:"BUILD"}),", ",(0,s.jsx)(n.code,{children:"creating"})," are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual ",(0,s.jsx)(n.code,{children:"openstack RESOURCE list"})," and ",(0,s.jsx)(n.code,{children:"openstack RESOURCE show NAME"})," and ",(0,s.jsx)(n.code,{children:"RESOURCE"})," being something like ",(0,s.jsx)(n.code,{children:"router"}),", ",(0,s.jsx)(n.code,{children:"network"}),", ",(0,s.jsx)(n.code,{children:"subnet"}),", ",(0,s.jsx)(n.code,{children:"port"}),", ",(0,s.jsx)(n.code,{children:"volume"}),", ",(0,s.jsx)(n.code,{children:"server"}),", ",(0,s.jsx)(n.code,{children:"floating ip"}),", ",(0,s.jsx)(n.code,{children:"loadbalancer"}),", ",(0,s.jsx)(n.code,{children:"loadbalancer pool"}),", ",(0,s.jsx)(n.code,{children:"loadbalancer listener"}),", ",(0,s.jsx)(n.code,{children:"security group"}),", ",(0,s.jsx)(n.code,{children:"keypair"}),", ",(0,s.jsx)(n.code,{children:"image"}),", ...)"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," uses and ",(0,s.jsx)(n.code,{children:"APIMonitor_TIMESTAMP"})," prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong.\n",(0,s.jsx)(n.code,{children:"TIMESTAMP"})," is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time)."]}),"\n",(0,s.jsxs)(n.p,{children:["This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least ",(0,s.jsx)(n.code,{children:"-N 2"})," to test the ability of the router to route traffic between networks. So expect ",(0,s.jsx)(n.code,{children:"-n 6"})," to become ",(0,s.jsx)(n.code,{children:"-N 2 -n 6"})," for a very small single-AZ cloud or ",(0,s.jsx)(n.code,{children:"-n 12"})," for a large 3 AZ cloud region. So, re-run the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," with the target sizing."]}),"\n",(0,s.jsx)(n.h3,{id:"resource-impact-and-charging",children:"Resource impact and charging"}),"\n",(0,s.jsxs)(n.p,{children:["Note that ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," uses small flavors (",(0,s.jsx)(n.code,{children:"SCS-1V-2"})," for the N jump hosts and ",(0,s.jsx)(n.code,{children:"SCS-1L-1"})," for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors."]}),"\n",(0,s.jsxs)(n.p,{children:["If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," in a loop (which you will) with say 10 VMs (e.g. ",(0,s.jsx)(n.code,{children:"-N 2 -n 8"}),") in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference."]}),"\n",(0,s.jsxs)(n.p,{children:["Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of ",(0,s.jsx)(n.code,{children:"openstack volume list"}),", ",(0,s.jsx)(n.code,{children:"openstack volume show BROKEN_VOLUME"}),", ",(0,s.jsx)(n.code,{children:"openstack loadbalancer list"}),", ",(0,s.jsx)(n.code,{children:"openstack loadbalancer show BROKEN_LB"}),".)"]}),"\n",(0,s.jsxs)(n.p,{children:["Using ",(0,s.jsx)(n.code,{children:"-w -1"})," makes ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," wait for interactive input whenever an error occurs; this can be convenient for debugging."]}),"\n",(0,s.jsx)(n.p,{children:"Once you have single iterations working nicely, we can proceed."}),"\n",(0,s.jsx)(n.h2,{id:"automating-startup-and-cleanup",children:"Automating startup and cleanup"}),"\n",(0,s.jsxs)(n.p,{children:["Typically, we run ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'#!/bin/bash\n# run_CLOUDNAME.sh\n# Do some global settings\nexport IMG="Debian 12"\nexport JHIMG="Debian 12"\n#export OS_CACERT=/home/debian/ca-certificates.pem\n# Additional settings to override flavors or to\n# configure email addresses for sending alarms can be set here\n\n# Does openstack CLI work?\nopenstack server list >/dev/null || exit 1\n# Upload log files to this swift container (which you need to create)\n#export SWIFTCONTAINER=OS-HM-Logfiles\n\n# CLEANUP\necho "Finding resources from previous runs to clean up ..."\n# Find Floating IPs\nFIPLIST=""\nFIPS=$(openstack floating ip list -f value -c ID)\nfor fip in $FIPS; do\n FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")\n if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_\n"; fi\ndone\nFIPLIST=$(echo "$FIPLIST" | grep -v \'^$\' | sort -u)\n# Cleanup previous interrupted runs\nSERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nKEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nVOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nNETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nLOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nSECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)\necho CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS\nfor ENV in $FIPLIST; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV\n echo "******************************"\ndone\nTOCLEAN=$(echo "$SERVERS\n$KEYPAIR\n$VOLUMES\n$NETWORK\n$LOADBAL\n$ROUTERS\n$SECGRPS\n" | grep -v \'^$\' | sort -u)\nfor ENV in $TOCLEAN; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV\n echo "******************************"\ndone\n\n# Now run the monitor\n#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"\nexec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Compared to the previous run, we have explicitly set two networks here ",(0,s.jsx)(n.code,{children:"-N 2"})," and rely on the iterations being passed in as command line arguments. Add parameter ",(0,s.jsx)(n.code,{children:"-t"})," if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (",(0,s.jsx)(n.code,{children:"-LO"}),") in this example rather than the amphora based one (",(0,s.jsx)(n.code,{children:"-LL"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["You may use one of the existing ",(0,s.jsx)(n.code,{children:"run_XXXX.sh"})," scripts as example. Beware: eMail alerting with ",(0,s.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESS"})," and ",(0,s.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESS"})," (and limiting with ",(0,s.jsx)(n.code,{children:"-a"})," and ",(0,s.jsx)(n.code,{children:"-R"})," ) and reporting data to telegraf (option ",(0,s.jsx)(n.code,{children:"-S"}),") may be present in the samples. Make this script executable (",(0,s.jsx)(n.code,{children:"chmod +x run_CLOUDNAME.sh"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["We wrap a loop around this in ",(0,s.jsx)(n.code,{children:"run_in_loop.sh"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'#!/bin/bash\n# run_in_loop.sh\nrm stop-os-hm 2>/dev/null\nwhile true; do\n ./run_CLOUDNAME.sh -i 200\n if test -e stop-os-hm; then break; fi\n echo -n "Hit ^C to abort ..."\n sleep 15; echo\ndone\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Also make this executable (",(0,s.jsx)(n.code,{children:"chmod +x run_in_loop.sh"}),").\nTo run this automatically in a tmux window whenever the system starts, we follow the steps in the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/startup/README.md",children:"startup README.md"})]}),"\n",(0,s.jsxs)(n.p,{children:["Change ",(0,s.jsx)(n.code,{children:"OS_CLOUD"})," in ",(0,s.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"}),". (If you need to set ",(0,s.jsx)(n.code,{children:"OS_CACERT"}),", also add it in this file and pass it into the windows.)"]}),"\n",(0,s.jsx)(n.p,{children:"Activate everything:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"mkdir -p ~/.config/systemd/user/\ncp -p startup/apimon.service ~/.config/systemd/user/\nsystemctl --user enable apimon\nsystemctl --user start apimon\nsudo loginctl enable-linger debian\ntmux attach -t oshealthmon\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This assumes that you are using the user ",(0,s.jsx)(n.code,{children:"debian"})," for this monitoring and have checked out the repository at ",(0,s.jsx)(n.code,{children:"~/openstack-health-monitor/"}),". Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)"]}),"\n",(0,s.jsx)(n.h3,{id:"changing-parameters-and-restarting",children:"Changing parameters and restarting"}),"\n",(0,s.jsxs)(n.p,{children:["If you want to change the parameters passed to ",(0,s.jsx)(n.code,{children:"api_monitor.sh"}),", you best do this by editing ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),", potentially after testing it with one iteration before."]}),"\n",(0,s.jsxs)(n.p,{children:["To make the change effective, you can wait until the current 200 iterations are completed and the ",(0,s.jsx)(n.code,{children:"run_in_loop.sh"})," calls ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," again. You can also hit ",(0,s.jsx)(n.code,{children:"^C"})," in the tmux window that has",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ",(0,s.jsx)(n.code,{children:"^C"})," during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ",(0,s.jsx)(n.code,{children:"^C"})," twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ",(0,s.jsx)(n.code,{children:"./run_in_loop.sh"})," again."]}),"\n",(0,s.jsxs)(n.p,{children:["You can also issue the ",(0,s.jsx)(n.code,{children:"systemctl --user stop apimon"})," command; it will basically do the same thing: Send ",(0,s.jsx)(n.code,{children:"^C"})," and then wait for everything to be completed and tear down the tmux session.\nAfter waiting for that to complete, you can start it again with ",(0,s.jsx)(n.code,{children:"systemctl --user start apimon"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"multiple-instances",children:"Multiple instances"}),"\n",(0,s.jsxs)(n.p,{children:["You can run multiple instances of ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," on the same driver VM. In this case, you should rename ",(0,s.jsx)(n.code,{children:"run_in_loop.sh"})," to e.g. ",(0,s.jsx)(n.code,{children:"run_in_loop_CLOUDNAME1.sh"})," and call ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME1.sh"})," from there. Don't forget to adjust ",(0,s.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"})," and ",(0,s.jsx)(n.code,{children:"startup/kill-apimon-in-tmux.sh"})," to start more windows."]}),"\n",(0,s.jsxs)(n.p,{children:["It is not recommended to run multiple instances against the same OpenStack project however. While the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations."]}),"\n",(0,s.jsx)(n.h2,{id:"alarming-and-logs",children:"Alarming and Logs"}),"\n",(0,s.jsx)(n.h3,{id:"email",children:"eMail"}),"\n",(0,s.jsxs)(n.p,{children:["If wanted, the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the ",(0,s.jsx)(n.code,{children:"-a N"})," and ",(0,s.jsx)(n.code,{children:"-R"})," options. In order to enable sending emails from the driver VM, it needs to have ",(0,s.jsx)(n.code,{children:"postfix"})," (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly."]}),"\n",(0,s.jsxs)(n.p,{children:["Once you have configured ",(0,s.jsx)(n.code,{children:"postfix"}),", you can enable eMail notifications using the option ",(0,s.jsx)(n.code,{children:"-e"}),". Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ",(0,s.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESSES"})," and ",(0,s.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESSES"})," environment variables to ",(0,s.jsx)(n.code,{children:"api_monitor.sh"}),", e.g. by setting it in the ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"log-files",children:"Log files"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"api_monitor.sh"})," writes a log file with the name ",(0,s.jsx)(n.code,{children:"APIMonitor_TIMESTAMP.log"}),". It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (",(0,s.jsx)(n.code,{children:"TIMESTAMP"})," is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)"]}),"\n",(0,s.jsxs)(n.p,{children:["Note that ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties."]}),"\n",(0,s.jsxs)(n.p,{children:["The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable ",(0,s.jsx)(n.code,{children:"SWIFTCONTAINER"})," has been set (in ",(0,s.jsx)(n.code,{children:"run_COULDNAME.sh"}),") when starting ",(0,s.jsx)(n.code,{children:"api_monitor.sh"}),". the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: ",(0,s.jsx)(n.code,{children:"export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER"})]}),"\n",(0,s.jsxs)(n.p,{children:["After the 200 iterations, a ",(0,s.jsx)(n.code,{children:".psv"})," file (pipe-separated values) is created ",(0,s.jsx)(n.code,{children:"Stats.STARTTIME-ENDTIME.psv"})," (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured)."]}),"\n",(0,s.jsx)(n.h2,{id:"data-collection-and-dashboard",children:"Data collection and dashboard"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md",children:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md"})]}),"\n",(0,s.jsx)(n.h3,{id:"telegraf",children:"Telegraf"}),"\n",(0,s.jsx)(n.p,{children:"To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key\necho "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list\nsudo apt update\nsudo apt -y install telegraf\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the config file ",(0,s.jsx)(n.code,{children:"/etc/telegraf/telegraf.conf"}),", we enable"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:'[[inputs.influxdb_listener]]\n service_address = ":8186"\n\n[[outputs.influxdb]]\n urls = ["http://127.0.0.1:8086"]\n'})}),"\n",(0,s.jsxs)(n.p,{children:["and restart the service (",(0,s.jsx)(n.code,{children:"sudo systemctl restart telegraf"}),").\nEnable it on system startup: ",(0,s.jsx)(n.code,{children:"sudo systemctl enable telegraf"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"influxdb",children:"InfluxDB"}),"\n",(0,s.jsx)(n.p,{children:"We proceed to influxdb:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo apt-get install influxdb\n"})}),"\n",(0,s.jsxs)(n.p,{children:["In the configuration file ",(0,s.jsx)(n.code,{children:"/etc/influxdb/influxdb.conf"}),", ensure that the http interface on port 8086 is enabled."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:'[http]\n enabled = true\n bind-address = ":8086"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Restart influxdb as needed with ",(0,s.jsx)(n.code,{children:"sudo systemctl restart influxdb"}),".\nAlso enable it on system startup: ",(0,s.jsx)(n.code,{children:"sudo systemctl enable influxdb"}),"."]}),"\n",(0,s.jsxs)(n.h3,{id:"add--s-cloudname-to-your-run_cloudnamesh-script",children:["Add ",(0,s.jsx)(n.code,{children:"-S CLOUDNAME"})," to your ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script"]}),"\n",(0,s.jsxs)(n.p,{children:["You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter ",(0,s.jsx)(n.code,{children:"-S CLOUDNAME"})," to the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," call in ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),". Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete)."]}),"\n",(0,s.jsx)(n.h3,{id:"caddy-reverse-proxy",children:"Caddy (Reverse Proxy)"}),"\n",(0,s.jsxs)(n.p,{children:["We're going to deploy Grafana behind ",(0,s.jsx)(n.a,{href:"https://caddyserver.com/docs/",children:"Caddy"})," as a reverse proxy.\nCaddy is very easy to configure, comes with sensible defaults and can automatically provision TLS\ncertificates using Let's Encrypt."]}),"\n",(0,s.jsx)(n.h4,{id:"install-caddy",children:"Install Caddy"}),"\n",(0,s.jsxs)(n.p,{children:["We follow ",(0,s.jsx)(n.a,{href:"https://caddyserver.com/docs/install#debian-ubuntu-raspbian",children:"https://caddyserver.com/docs/install#debian-ubuntu-raspbian"})," to setup the stable APT repository:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl\ncurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg\ncurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list\n"})}),"\n",(0,s.jsx)(n.p,{children:"And install Caddy:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo apt update\nsudo apt install caddy\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Ensure it's started and starts at boot with ",(0,s.jsx)(n.code,{children:"sudo systemctl enable --now caddy"}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"allow-http-traffic-for-oshm-driver",children:"Allow HTTP traffic for oshm-driver"}),"\n",(0,s.jsxs)(n.p,{children:["Caddy needs TCP port ",(0,s.jsx)(n.code,{children:"80"})," opened to be able to process the Let's Encrypt HTTP challenge, so let's\nconfigure an appropriate security group for ",(0,s.jsx)(n.code,{children:"oshm-driver"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"openstack security group create http\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 80 http\nopenstack server add security group oshm-driver http\n"})}),"\n",(0,s.jsx)(n.h4,{id:"configure-caddy",children:"Configure Caddy"}),"\n",(0,s.jsxs)(n.p,{children:["Create a file ",(0,s.jsx)(n.code,{children:"/etc/caddy/Caddyfile"})," with the following contents:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"https://health.YOURCLOUD.osba.sovereignit.cloud:3000 {\n\treverse_proxy localhost:3003\n}\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Replace ",(0,s.jsx)(n.code,{children:"health.YOURCLOUD.osba.sovereignit.cloud"})," with your actual domain.\nYou can use a hostname of your liking, but Caddy will create TLS certificates for this host using\nthe HTTP challenge.\nThe ",(0,s.jsx)(n.code,{children:"sovereignit.cloud"})," domain is controlled by the SCS project team and has been used for a number\nof health mon instances."]}),"\n",(0,s.jsxs)(n.p,{children:["Reload Caddy with ",(0,s.jsx)(n.code,{children:"sudo systemctl reload caddy"}),". That's it."]}),"\n",(0,s.jsxs)(n.p,{children:["You should now be able to access ",(0,s.jsx)(n.code,{children:"https://health.YOURCLOUD.sovereignit.cloud:3000"})," and see a proxy error\npage because the Grafana service is not yet running (this is our next step).\nThe very first request will be a bit slower, because Caddy interacts with Let's Encrypt API to create\nthe TLS certificate behind the scenes."]}),"\n",(0,s.jsxs)(n.p,{children:["Caddy logs can be accessed with ",(0,s.jsx)(n.code,{children:"sudo journalctl -u caddy"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"grafana",children:"Grafana"}),"\n",(0,s.jsx)(n.h4,{id:"install-grafana",children:"Install Grafana"}),"\n",(0,s.jsxs)(n.p,{children:["We follow ",(0,s.jsx)(n.a,{href:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/",children:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/"})," and setup the stable APT repository:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'mkdir -p /etc/apt/keyrings\nwget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null\necho "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list\n'})}),"\n",(0,s.jsx)(n.p,{children:"And install it:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo apt update\nsudo apt -y install grafana\n"})}),"\n",(0,s.jsx)(n.h4,{id:"basic-config",children:"Basic config"}),"\n",(0,s.jsxs)(n.p,{children:["The config file ",(0,s.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," needs some adjustments."]}),"\n",(0,s.jsx)(n.p,{children:"We're going to deploy Grafana behind a reverse proxy (Caddy) and configure it as such."}),"\n",(0,s.jsxs)(n.p,{children:["Therefore, in the ",(0,s.jsx)(n.code,{children:"[server]"})," section:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[server]\nprotocol = http\nhttp_addr = 127.0.0.1\nhttp_port = 3003\ndomain = health.YOURCLOUD.sovereignit.cloud\nroot_url = https://%(domain)s:3000/\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Please replace ",(0,s.jsx)(n.code,{children:"health.YOURCLOUD.sovereignit.cloud"})," with your actual domain."]}),"\n",(0,s.jsxs)(n.p,{children:["Next, in the ",(0,s.jsx)(n.code,{children:"[security]"})," section, set:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[security]\nadmin_user = admin\nadmin_password = SOME_SECRET_PASS\nsecret_key = SOME_SECRET_KEY\ndata_source_proxy_whitelist = localhost:8088 localhost:8086\ncookie_secure = true\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Please replace ",(0,s.jsx)(n.code,{children:"SOME_SECRET_PASS"})," and ",(0,s.jsx)(n.code,{children:"SOME_SECRET_KEY"})," with secure passwords (for example, you can use ",(0,s.jsx)(n.code,{children:"pwgen -s 20"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["Finally, in the ",(0,s.jsx)(n.code,{children:"[users]"})," section, set:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[users]\nallow_sign_up = false\nallow_org_create = false\n"})}),"\n",(0,s.jsx)(n.p,{children:"The configuration file contains secrets and should be protected such that only root and group grafana\ncan read it:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo chown root:grafana /etc/grafana/grafana.ini\nsudo chmod 0640 /etc/grafana/grafana.ini\n"})}),"\n",(0,s.jsxs)(n.p,{children:["We do the OIDC connection in the section ",(0,s.jsx)(n.code,{children:"[auth.github]"})," ",(0,s.jsx)(n.a,{href:"#github-oidc-integration",children:"later"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["We can now restart the service: ",(0,s.jsx)(n.code,{children:"sudo systemctl restart grafana-server"}),".\nBeing at it, also enable it on system startup: ",(0,s.jsx)(n.code,{children:"sudo systemctl enable grafana-server"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You should now be able to access your dashboard on ",(0,s.jsx)(n.code,{children:"https://health.YOURCLOUD.sovereignit.cloud:3000"})," and log in\nvia the configured username ",(0,s.jsx)(n.code,{children:"admin"})," and your ",(0,s.jsx)(n.code,{children:"SOME_SECRET_PASS"})," password."]}),"\n",(0,s.jsx)(n.h4,{id:"enable-influx-database-in-grafana",children:"Enable influx database in grafana"}),"\n",(0,s.jsxs)(n.p,{children:["In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to ",(0,s.jsx)(n.code,{children:"http://localhost:8086"})," (despite this being the suggestion). Set the database name to ",(0,s.jsx)(n.code,{children:"telegraf"}),". Save&test should succeed."]}),"\n",(0,s.jsx)(n.h4,{id:"importing-the-dashboard",children:"Importing the dashboard"}),"\n",(0,s.jsxs)(n.p,{children:["Go to Home, Dashboards, New, Import.\nUpload the dashboard ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard.json",children:".json file"})," from the repository, user the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard-10.json",children:"Grafana-10 variant"})," if you use Grafana 10 or newer."]}),"\n",(0,s.jsx)(n.p,{children:"In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.)\nSave."}),"\n",(0,s.jsx)(n.p,{children:"Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable)."}),"\n",(0,s.jsx)(n.h4,{id:"no-data-displayed",children:"No data displayed?"}),"\n",(0,s.jsx)(n.p,{children:'Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.'}),"\n",(0,s.jsx)(n.p,{children:"One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved."}),"\n",(0,s.jsx)(n.h4,{id:"dashboard-features",children:"Dashboard features"}),"\n",(0,s.jsx)(n.p,{children:"Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended."}),"\n",(0,s.jsx)(n.p,{children:"The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously."}),"\n",(0,s.jsx)(n.p,{children:"You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term."}),"\n",(0,s.jsx)(n.h4,{id:"github-oidc-integration",children:"GitHub OIDC Integration"}),"\n",(0,s.jsx)(n.p,{children:"The SCS providers do allow all GitHub users that belong to the SovereignCloudStack organization to get Viewer\naccess to the dashboards.\nThis allows to exchange experience and to get a feeling for the achievable stability.\n(Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)"}),"\n",(0,s.jsxs)(n.p,{children:["OIDC integration is achieved by adjusting the ",(0,s.jsx)(n.code,{children:"[auth.github]"})," section in ",(0,s.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," as follows:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:'[auth.github]\nenabled = true\nclient_id = YOUR_CLIENT_ID\nclient_secret = YOUR_CLIENT_SECRET\nallowed_organizations = ["SovereignCloudStack"]\nrole_attribute_path = "\'Viewer\'"\nallow_assign_grafana_admin = false\nskip_org_role_sync = true\n'})}),"\n",(0,s.jsxs)(n.p,{children:["This config maps all users to the ",(0,s.jsx)(n.code,{children:"Viewer"})," role regardless of their role in the GitHub Org.\nPlease replace ",(0,s.jsx)(n.code,{children:"YOUR_CLIENT_ID"})," and ",(0,s.jsx)(n.code,{children:"YOUR_CLIENT_SECRET"})," with the OAuth2 credentials that the SCS Org GitHub admins\nprovided to you.\nFinally, don't forgot to restart Grafana with ",(0,s.jsx)(n.code,{children:"sudo systemctl restart grafana-server"})," after adjusting the config."]}),"\n",(0,s.jsxs)(n.p,{children:["More information can be found in the ",(0,s.jsx)(n.a,{href:"https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/github/",children:"Grafana documentation for GitHub OAuth2"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"maintenance",children:"Maintenance"}),"\n",(0,s.jsx)(n.p,{children:"The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained."}),"\n",(0,s.jsx)(n.h3,{id:"unattended-upgrades",children:"Unattended upgrades"}),"\n",(0,s.jsxs)(n.p,{children:["It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See ",(0,s.jsx)(n.a,{href:"https://wiki.debian.org/UnattendedUpgrades",children:"https://wiki.debian.org/UnattendedUpgrades"}),". If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and Caddy/Grafana (port 3000)."]}),"\n",(0,s.jsxs)(n.p,{children:["If you use ",(0,s.jsx)(n.code,{children:"unattended-upgrades"}),", you should review your settings in ",(0,s.jsx)(n.code,{children:"/etc/apt/apt.conf.d/50unattended-upgrades"}),",\nespecially ",(0,s.jsx)(n.code,{children:"Unattended-Upgrade::Origins-Pattern"}),". It controls which packages are upgraded. If you want Caddy to be\npart of the automated updates, add an entry like the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'Unattended-Upgrade::Origins-Pattern {\n // ...\n "origin=cloudsmith/caddy/stable";\n};\n'})}),"\n",(0,s.jsxs)(n.p,{children:["(This corresponds to ",(0,s.jsx)(n.code,{children:"o=cloudsmith/caddy/stable"})," in the output of ",(0,s.jsx)(n.code,{children:"apt-cache policy"}),")."]}),"\n",(0,s.jsx)(n.h3,{id:"sshd-setup",children:"sshd setup"}),"\n",(0,s.jsxs)(n.p,{children:["If you already use SSH keys to sign in to the driver VM, consider setting the following in your ",(0,s.jsx)(n.code,{children:"/etc/ssh/sshd_config"}),"\nif not already set:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"PasswordAuthentication no\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Debian's ",(0,s.jsx)(n.code,{children:"openssh-server"}),", by default, is also very open about its version, so you might consider disabling this via:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"DebianBanner no\n"})}),"\n",(0,s.jsx)(n.h3,{id:"updating-openstack-health-monitor",children:"Updating openstack-health-monitor"}),"\n",(0,s.jsxs)(n.p,{children:["You can just do a ",(0,s.jsx)(n.code,{children:"git update"})," in the ",(0,s.jsx)(n.code,{children:"openstack-health-monitor"})," directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ",(0,s.jsx)(n.code,{children:"^C"}),", see above in the restart section."]}),"\n",(0,s.jsx)(n.h3,{id:"backup",children:"Backup"}),"\n",(0,s.jsxs)(n.p,{children:["The system holds two things that you might consider valuable for long-term storage:\n(1) The log files. These are compressed and uploaded to object storage if you enable the ",(0,s.jsx)(n.code,{children:"SWIFTCONTAINER"})," setting, which probably means that these do not need any additional backing up then.\n(2) The influx time series data. Back up the data in ",(0,s.jsx)(n.code,{children:"/var/lib/influxdb"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, ",(0,s.jsx)(n.code,{children:"clouds.yaml"}),", etc. Be careful not to expose sensitive data by granting too generous access to your backed up files."]}),"\n",(0,s.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,s.jsx)(n.h3,{id:"debugging-issues",children:"Debugging issues"}),"\n",(0,s.jsx)(n.p,{children:"In case there is trouble with your cloud, the normal course of action to analyze is as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Look at the dashboard (see above)"}),"\n",(0,s.jsxs)(n.li,{children:["Connect to the driver VM and attach to the tmux session and look at the console output of ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})]}),"\n",(0,s.jsx)(n.li,{children:"Analyze the logfile (locally on the driver VM or grab it from the object storage)"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"analyzing-failures",children:"Analyzing failures"}),"\n",(0,s.jsxs)(n.p,{children:["When VM instances are created successfully, but then end up in ",(0,s.jsx)(n.code,{children:"ERROR"})," state, the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," does an explicit ",(0,s.jsx)(n.code,{children:"openstack server show"}),", so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files."]}),"\n",(0,s.jsxs)(n.p,{children:["Sometimes the VMs end up being ",(0,s.jsx)(n.code,{children:"ACTIVE"})," as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail."]}),"\n",(0,s.jsxs)(n.p,{children:["To gather more details, you can look at the console output ",(0,s.jsx)(n.code,{children:"openstack console log show VM"})," (where ",(0,s.jsx)(n.code,{children:"VM"})," is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ",(0,s.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_JH.pem debian@FIP"}),", whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ",(0,s.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP"}),". Replace ",(0,s.jsx)(n.code,{children:"XXXXX"})," with the number in your current APIMonitor prefix, ",(0,s.jsx)(n.code,{children:"FIP"})," with the floating IP address of the responsible JumpHost and ",(0,s.jsx)(n.code,{children:"debian"})," with the user name used by the images you boot. Use ",(0,s.jsx)(n.code,{children:"223"})," to connect to the second VM in the network, ",(0,s.jsx)(n.code,{children:"224"})," the third etc."]}),"\n",(0,s.jsxs)(n.p,{children:["When logged in, look at ",(0,s.jsx)(n.code,{children:"/var/log/cloud-init-output.log"})," and ",(0,s.jsx)(n.code,{children:"/var/log/cloud-init.log"}),". You can find the metadata in ",(0,s.jsx)(n.code,{children:"/var/lib/cloud/instance/"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You will not have much time to look around -- the still running ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," script does continue and clean things up again. So you might want to suspend it with ",(0,s.jsx)(n.code,{children:"^Z"})," (and continue it later with ",(0,s.jsx)(n.code,{children:"fg"}),"). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script as it would do cleanup against the running instance, but rather copy the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," command line from the bottom (without the ",(0,s.jsx)(n.code,{children:"exec"}),"), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach ",(0,s.jsx)(n.code,{children:"-w -1"})," to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work."]}),"\n",(0,s.jsx)(n.h3,{id:"cleaning-things-up",children:"Cleaning things up"}),"\n",(0,s.jsx)(n.p,{children:"If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard)."}),"\n",(0,s.jsx)(n.p,{children:"There are a few things that may need support from a cloud admin:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Volumes may end up permanently in a ",(0,s.jsx)(n.code,{children:"deleting"})," or ",(0,s.jsx)(n.code,{children:"reserved"})," state or may be ",(0,s.jsx)(n.code,{children:"in-use"}),", attached to a VM that has long gone. The admin needs to set the state to ",(0,s.jsx)(n.code,{children:"error"})," and then delete them."]}),"\n",(0,s.jsxs)(n.li,{children:["Loadbalancers may end up in a ",(0,s.jsx)(n.code,{children:"PENDING_XXX"})," state (",(0,s.jsx)(n.code,{children:"XXX"})," being ",(0,s.jsx)(n.code,{children:"CREATE"}),", ",(0,s.jsx)(n.code,{children:"UPDATE"})," or ",(0,s.jsx)(n.code,{children:"DELETE"}),") without ever changing. This also needs the cloud admin to set the status to ",(0,s.jsx)(n.code,{children:"ERROR"}),", so it can be cleaned up. amphorae are more prone to this than ovn LBs."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["The source of this document can be found in the ",(0,s.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/openstack-health-monitor/main/docs/Debian12-Install.md",children:"SovereignCloudStack/openstack-health-monitor"})," repository."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.em,{children:"Author: SCS Community, License: CC by Attribution 4.0 International"})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var o=t(96540);const s={},a=o.createContext(s);function i(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8e8909f7.44847530.js b/assets/js/8e8909f7.44847530.js new file mode 100644 index 0000000000..aec7fb851e --- /dev/null +++ b/assets/js/8e8909f7.44847530.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[19407],{17329:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/skyline","title":"Skyline","description":"Skyline APIServer","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/skyline.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/skyline","permalink":"/docs/iaas/guides/configuration-guide/openstack/skyline","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/skyline.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Skyline"},"sidebar":"docs","previous":{"title":"Placement","permalink":"/docs/iaas/guides/configuration-guide/openstack/placement"},"next":{"title":"Ceph via Rook (technical preview)","permalink":"/docs/iaas/guides/configuration-guide/rook"}}');var t=i(74848),o=i(28453);const r={sidebar_label:"Skyline"},l="Skyline",a={},c=[{value:"Skyline APIServer",id:"skyline-apiserver",level:2},{value:"Skyline Console",id:"skyline-console",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"skyline",children:"Skyline"})}),"\n",(0,t.jsx)(n.h2,{id:"skyline-apiserver",children:"Skyline APIServer"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/skyline-apiserver/latest/configuration/settings.html",children:"Skyline APIServer configuration reference"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"skyline-console",children:"Skyline Console"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/skyline-console/latest/admin/index.html",children:"Skyline Console admin guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/skyline-console/latest/configuration/skyline-console-settings.html",children:"Skyline Console configuration reference"})}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>l});var s=i(96540);const t={},o=s.createContext(t);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8ec565c1.b8273d7c.js b/assets/js/8ec565c1.b8273d7c.js new file mode 100644 index 0000000000..3fa481a5f1 --- /dev/null +++ b/assets/js/8ec565c1.b8273d7c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[46866],{23860:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>o,frontMatter:()=>d,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"iaas/scs-0116","title":"scs-0116: SCS Key Manager Standard","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0116.md","sourceDirName":"iaas","slug":"/iaas/scs-0116","permalink":"/standards/iaas/scs-0116","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0115-v1-default-rules-for-security-groups"},"next":{"title":"V1","permalink":"/standards/scs-0116-v1-key-manager-standard"}}');var r=s(74848),a=s(28453);const d={},i="scs-0116: SCS Key Manager Standard",c={},l=[{value:"Supplement: Implementation and Testing Notes",id:"supplement-implementation-and-testing-notes",level:2}];function h(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0116-scs-key-manager-standard",children:"scs-0116: SCS Key Manager Standard"})}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0116-v1-key-manager-standard",children:"scs-0116-v1"})}),(0,r.jsx)(t.td,{children:"Standard"}),(0,r.jsx)(t.td,{children:"Stable"}),(0,r.jsx)(t.td,{children:"2024-11-13"}),(0,r.jsx)(t.td,{children:"-"})]})})]}),"\n",(0,r.jsx)(t.h2,{id:"supplement-implementation-and-testing-notes",children:"Supplement: Implementation and Testing Notes"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0116-w1-key-manager-implementation-testing",children:"w1"})}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function o(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>i});var n=s(96540);const r={},a=n.createContext(r);function d(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8ed6f0f1.517c99d9.js b/assets/js/8ed6f0f1.517c99d9.js new file mode 100644 index 0000000000..02c40d2dd7 --- /dev/null +++ b/assets/js/8ed6f0f1.517c99d9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[71001],{25927:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"container/components/cluster-stacks/components/csctl/design","title":"CSCTL - Design document","description":"The Cluster Stack Operator facilitates the usage of cluster stacks by automating all steps that can be automated. It takes cluster stacks release assets that consist mainly of two Helm charts, one to deploy in the management cluster, the other one to deploy in the workload clusters, as well as provider-specific node image (build) information.","source":"@site/docs/03-container/components/cluster-stacks/components/csctl/design.md","sourceDirName":"03-container/components/cluster-stacks/components/csctl","slug":"/container/components/cluster-stacks/components/csctl/design","permalink":"/docs/container/components/cluster-stacks/components/csctl/design","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/csctl/design.md","tags":[],"version":"current","frontMatter":{}}');var n=s(74848),o=s(28453);const i={},a="CSCTL - Design document",l={},c=[{value:"User story 1: Developer releasing cluster stacks",id:"user-story-1-developer-releasing-cluster-stacks",level:3},{value:"User story 2: Developer versioning cluster stacks",id:"user-story-2-developer-versioning-cluster-stacks",level:3},{value:"User story 3: Multiple developers work in parallel on one cluster stack",id:"user-story-3-multiple-developers-work-in-parallel-on-one-cluster-stack",level:3},{value:"User story 4: Developer updating cluster stack that is used in production",id:"user-story-4-developer-updating-cluster-stack-that-is-used-in-production",level:3},{value:"User story 5: Automated testing of cluster stacks",id:"user-story-5-automated-testing-of-cluster-stacks",level:3},{value:"Two forms of templating",id:"two-forms-of-templating",level:3},{value:"Generic vs provider-specific work",id:"generic-vs-provider-specific-work",level:2},{value:"Generic work",id:"generic-work",level:2},{value:"Provider-specific work",id:"provider-specific-work",level:2},{value:"Configuration",id:"configuration",level:2},{value:"Configuration file",id:"configuration-file",level:3},{value:"Flags",id:"flags",level:3},{value:"Environment variables",id:"environment-variables",level:3},{value:"Commands of CLI tool",id:"commands-of-cli-tool",level:2},{value:"Modes",id:"modes",level:2},{value:"Stable",id:"stable",level:3},{value:"Hash",id:"hash",level:3},{value:"Beta",id:"beta",level:3},{value:"Custom (e.g. for PRs)",id:"custom-eg-for-prs",level:3}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"csctl---design-document",children:"CSCTL - Design document"})}),"\n",(0,n.jsx)(t.h1,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsx)(t.p,{children:"The Cluster Stack Operator facilitates the usage of cluster stacks by automating all steps that can be automated. It takes cluster stacks release assets that consist mainly of two Helm charts, one to deploy in the management cluster, the other one to deploy in the workload clusters, as well as provider-specific node image (build) information."}),"\n",(0,n.jsx)(t.p,{children:"Users can take existing releases of cluster stacks and the operator and will be able to create clusters easily."}),"\n",(0,n.jsx)(t.p,{children:"However, there is no clear and nice way to work on cluster stacks, test, and release them."}),"\n",(0,n.jsx)(t.p,{children:"This proposal will discuss a tool to improve the experience of developers implementing cluster stacks."}),"\n",(0,n.jsx)(t.h1,{id:"motivation",children:"Motivation"}),"\n",(0,n.jsx)(t.p,{children:"The current process of building cluster stacks is rather cumbersome and error-prone. There are multiple issues with the current approach:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"The release assets have to follow a very specific (naming) pattern, to be usable with the operator. Currently, they have to be created manually. There are no docs for this manual process."}),"\n",(0,n.jsx)(t.li,{children:"The cluster stacks can be versioned following the pattern v1, v2, \u2026 This is perfect from the user perspective, but not good for people implementing cluster stacks, as they can only do local tests by artificially creating a v2 and not releasing it."}),"\n",(0,n.jsx)(t.li,{children:"The versioning of the cluster stacks is not easy, as there are multiple versions involved. Cluster addons have their own version, for example. Currently, the versions have to be manually hard-coded in multiple places. This can be validated to some degree but is not developer-friendly and can still lead to mistakes."}),"\n"]}),"\n",(0,n.jsx)(t.h1,{id:"proposal",children:"Proposal"}),"\n",(0,n.jsx)(t.p,{children:"We propose a CLI tool called \u201ccsctl\u201d, which stands for cluster-stack-manager-ctl. This CLI tool should take over all manual work from a developer implementing cluster stacks that can be taken over. The developer should concentrate only on implementing the cluster stacks themselves."}),"\n",(0,n.jsx)(t.p,{children:"There will be still a certain way of dealing with \u201ccluster stack-specific\u201d jobs, e.g. following a certain templating pattern. This is necessary, as the configuration and Helm Charts that developers implement are very generic."}),"\n",(0,n.jsxs)(t.p,{children:["The tool should generate release assets, e.g. by using ",(0,n.jsx)(t.code,{children:"helm package"})," for the helm charts. It should be able to create these release assets for different use cases, e.g. for creating a stable release, for testing a certain commit, and for creating a beta release."]}),"\n",(0,n.jsx)(t.h1,{id:"user-stories",children:"User stories"}),"\n",(0,n.jsx)(t.h3,{id:"user-story-1-developer-releasing-cluster-stacks",children:"User story 1: Developer releasing cluster stacks"}),"\n",(0,n.jsx)(t.p,{children:"A developer who wants to release a cluster stack that was implemented can use the CLI tool to generate all release assets that are required. This should save much time compared to following a manual process."}),"\n",(0,n.jsx)(t.h3,{id:"user-story-2-developer-versioning-cluster-stacks",children:"User story 2: Developer versioning cluster stacks"}),"\n",(0,n.jsx)(t.p,{children:"A developer who has to think about how to version a cluster stack that was implemented can use the tool to do the job. This saves a lot of time, as the developer would have to manually check whether anything was updated for cluster addons or node images to find the appropriate version (\u201dDid anything change in the cluster addons so that they need a new version or not?\u201d)."}),"\n",(0,n.jsx)(t.h3,{id:"user-story-3-multiple-developers-work-in-parallel-on-one-cluster-stack",children:"User story 3: Multiple developers work in parallel on one cluster stack"}),"\n",(0,n.jsx)(t.p,{children:"If multiple developers work on one cluster stack, they might interfere with each other\u2019s work. Assuming that node images have to be built, then one developer would upload the node images in version \u201cv2\u201d, as the previous version was \u201cv1\u201d. The second developer has the same thought and would either overwrite the already uploaded node images of the colleague or not be able to upload the images since they exist already."}),"\n",(0,n.jsx)(t.p,{children:"The csctl allows both developers to have independent versioning based on a git commit hash."}),"\n",(0,n.jsx)(t.h3,{id:"user-story-4-developer-updating-cluster-stack-that-is-used-in-production",children:"User story 4: Developer updating cluster stack that is used in production"}),"\n",(0,n.jsx)(t.p,{children:"If a developer updates a cluster stack that is used in production, great care is needed. The csctl allows the developer to safely test cluster stacks, e.g. with a beta channel, without touching cluster stacks that are used in production.\nIf everything works well, a production release can be generated with csctl."}),"\n",(0,n.jsx)(t.h3,{id:"user-story-5-automated-testing-of-cluster-stacks",children:"User story 5: Automated testing of cluster stacks"}),"\n",(0,n.jsx)(t.p,{children:"Cluster stacks cannot be tested in the CI and with a normal Git PR flow. The csctl allows this testing of individual PRs and therefore enables automated testing via CI."}),"\n",(0,n.jsx)(t.h1,{id:"risks--mitigations",children:"Risks & Mitigations"}),"\n",(0,n.jsx)(t.h3,{id:"two-forms-of-templating",children:"Two forms of templating"}),"\n",(0,n.jsxs)(t.p,{children:["Helm charts use Go templating with the notation ",(0,n.jsx)(t.code,{children:"{{ .values.myvalue }}"}),". As a cluster stack consists usually of two Helm charts, this notation will be very common."]}),"\n",(0,n.jsxs)(t.p,{children:["However, the csctl requires a different form of templating, additionally to the one of Helm. This comes from the versioning of the cluster stacks themselves. The Cluster addon version, for example, has to be the version of the respective Helm chart. The same goes for the ",(0,n.jsx)(t.code,{children:"ClusterClass"})," object name."]}),"\n",(0,n.jsxs)(t.p,{children:["Users have to use the additional templating notation ",(0,n.jsx)(t.code,{children:"<< .ClusterAddonVersion >>"})," while implementing cluster stacks."]}),"\n",(0,n.jsx)(t.p,{children:"The alternative to using a different notation for cluster stack templating would be to use the same one as Helm. However, this will be confusing for users, as they cannot differentiate it. Therefore, we cannot suggest to follow that path."}),"\n",(0,n.jsx)(t.h1,{id:"design-details",children:"Design details"}),"\n",(0,n.jsx)(t.h2,{id:"generic-vs-provider-specific-work",children:"Generic vs provider-specific work"}),"\n",(0,n.jsx)(t.p,{children:"Just like the Cluster Stack Operator, the csctl also has a generic and a provider-specific part. The provider-specific part is optional."}),"\n",(0,n.jsxs)(t.p,{children:["The generic work is done with a CLI tool that exists in the repository csctl in SCS. The tool can be initialized with provider-specific binaries, similar to the way ",(0,n.jsx)(t.a,{href:"https://github.com/hashicorp/packer",children:"packer"})," does it."]}),"\n",(0,n.jsx)(t.h2,{id:"generic-work",children:"Generic work"}),"\n",(0,n.jsx)(t.p,{children:"The generic part of the csctl is"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"Calculate the right versions based on git commit hash or previous releases"}),"\n",(0,n.jsx)(t.li,{children:"Template everything with csctl templating (NOT Helm templating!!)"}),"\n",(0,n.jsx)(t.li,{children:"Package the ClusterClass Helm Chart"}),"\n",(0,n.jsx)(t.li,{children:"Package the ClusterAddon Helm Chart"}),"\n",(0,n.jsx)(t.li,{children:"Generate metadata.yaml"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"provider-specific-work",children:"Provider-specific work"}),"\n",(0,n.jsx)(t.p,{children:"The provider-specific part of csctl would do anything necessary to provide node images to users. One common task could be to use packer to build images and to upload them somewhere they can be accessed by users."}),"\n",(0,n.jsx)(t.p,{children:"Of course, one task would also be to find the right version for the node images (e.g. v2 if something changed since v1, or simply the git commit hash)"}),"\n",(0,n.jsx)(t.h2,{id:"configuration",children:"Configuration"}),"\n",(0,n.jsx)(t.p,{children:"There are multiple ways of configuring the csctl. They all have specific use cases and will be explained in the following"}),"\n",(0,n.jsx)(t.h3,{id:"configuration-file",children:"Configuration file"}),"\n",(0,n.jsxs)(t.p,{children:["There is a configuration file called ",(0,n.jsx)(t.code,{children:"csctl.yaml"})," which contains all values that will never have to be changed for a specific cluster stack. It follows this pattern:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",children:"apiVersion: csctl.clusterstack.x-k8s.io/v1alpha1\nconfig:\n kubernetesVersion: v1.27.7\n clusterStackName: ferrol\n provider:\n type: myprovider\n apiVersion: myprovider.csctl.clusterstack.x-k8s.io/v1alpha1\n\t\tconfig: xyz\n"})}),"\n",(0,n.jsx)(t.p,{children:"There is mainly the Kubernetes version, the name of the cluster stack, as well as the provider. Additionally, there is a provider-specific configuration. Both the generic and the provider-specific configuration is versioned."}),"\n",(0,n.jsx)(t.h3,{id:"flags",children:"Flags"}),"\n",(0,n.jsx)(t.p,{children:"Via flags the user can specifiy everything that is important but which might change, e.g. the mode \u201cstable\u201d or \u201chash\u201d, giving you release assets for a stable release or creating release assets based on the latest git commit hash."}),"\n",(0,n.jsx)(t.h3,{id:"environment-variables",children:"Environment variables"}),"\n",(0,n.jsx)(t.p,{children:"Environment variables can be used, for example, to specify tokens and passwords. csctl has to validate that all required environment variables have been specified."}),"\n",(0,n.jsx)(t.h2,{id:"commands-of-cli-tool",children:"Commands of CLI tool"}),"\n",(0,n.jsxs)(t.p,{children:["Multiple commands can make sense for developers. The most important one is the ",(0,n.jsx)(t.code,{children:"create"})," command that creates release assets, as well as ",(0,n.jsx)(t.code,{children:"provider install"})," to install the binary of a provider that carries out all provider-specific work."]}),"\n",(0,n.jsx)(t.p,{children:"This is a full list:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",children:"subcommands:\nprovider\t\t\tIs used for the provider lifecycle\t\t\t\ncreate \t\t\t\tcreates release assets of a cluster stack.\ngenerate\t\t\tGenerates a specific resource from a cluster stack\nlist \t\t\t\t show all cluster-stacks from a repo\nversion\t\t\t\tshows the version of this cli tool\nhelp\t\t\t\t print a overview of available flags etc.\n\nsubcommands for provider:\ninstall\t\t\t\tInstalls a cluster-stack-release-provider at a version\ninstalled\t\t\tLists installed csctl release providers\nremove\t\t\t\tremoves a csctl release provider at a version `csctl provider remove docker <version>`\n"})}),"\n",(0,n.jsx)(t.h2,{id:"modes",children:"Modes"}),"\n",(0,n.jsx)(t.p,{children:"There are multiple modes to create release assets following different versioning patterns."}),"\n",(0,n.jsx)(t.h3,{id:"stable",children:"Stable"}),"\n",(0,n.jsx)(t.p,{children:"The stable mode requires the developer to specify an existing GitHub repository (in the future other ways of storing release assets are possible) via environment variables. The csctl will search for the latest release fitting to the configuration of provider, cluster stack name, and Kubernetes version (e.g. docker-ferrol-1-27-vXXX). Then it will download the required release assets and check whether anything has changed in the cluster addon and node image section. Depending on that information it will calculate the next version, e.g. v2 after v1, or will leave the version the same if nothing changed."}),"\n",(0,n.jsx)(t.h3,{id:"hash",children:"Hash"}),"\n",(0,n.jsxs)(t.p,{children:["The hash mode is useful for developing cluster stacks. It will use the hash of the last git commit and generate a version of the form ",(0,n.jsx)(t.code,{children:"v0-hash.<hash>"}),". following semver."]}),"\n",(0,n.jsx)(t.p,{children:"This version will be used for cluster class, cluster add-ons, and node images. Unlike the stable version, the versions in hash mode always update to the latest commit and do not depend on any previous release."}),"\n",(0,n.jsx)(t.h3,{id:"beta",children:"Beta"}),"\n",(0,n.jsxs)(t.p,{children:["The beta mode is similar to the stable mode, except that it generates releases following the version pattern ",(0,n.jsx)(t.code,{children:"v0-beta.0"}),", ",(0,n.jsx)(t.code,{children:"v0-beta.1"}),", etc."]}),"\n",(0,n.jsx)(t.h3,{id:"custom-eg-for-prs",children:"Custom (e.g. for PRs)"}),"\n",(0,n.jsx)(t.p,{children:"The custom mode is designed for PR purposes and supports automated testing. It accommodates versions formatted as v0.custom-pr123. Crucially, these versions must adhere to semantic versioning standards (semver) and are specifically intended as inputs for the csctl tool."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>a});var r=s(96540);const n={},o=r.createContext(n);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8fc094a7.9c1360a7.js b/assets/js/8fc094a7.9c1360a7.js new file mode 100644 index 0000000000..564ad138d7 --- /dev/null +++ b/assets/js/8fc094a7.9c1360a7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[46251],{75252:(e,a,n)=>{n.r(a),n.d(a,{assets:()=>d,contentTitle:()=>o,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"iaas/guides/operations-guide/manager/index","title":"Manager","description":"OSISM orchestrator","source":"@site/docs/02-iaas/guides/operations-guide/manager/index.md","sourceDirName":"02-iaas/guides/operations-guide/manager","slug":"/iaas/guides/operations-guide/manager/","permalink":"/docs/iaas/guides/operations-guide/manager/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/manager/index.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Manager","sidebar_position":10},"sidebar":"docs","previous":{"title":"Operations Guide","permalink":"/docs/iaas/guides/operations-guide/"},"next":{"title":"Apply","permalink":"/docs/iaas/guides/operations-guide/manager/apply"}}');var t=n(74848),i=n(28453);const r={sidebar_label:"Manager",sidebar_position:10},o="Manager",d={},c=[];function u(e){const a={h1:"h1",header:"header",img:"img",p:"p",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(a.header,{children:(0,t.jsx)(a.h1,{id:"manager",children:"Manager"})}),"\n",(0,t.jsx)(a.p,{children:(0,t.jsx)(a.img,{alt:"OSISM orchestrator",src:n(5479).A+"",width:"1303",height:"591"})})]})}function p(e={}){const{wrapper:a}={...(0,i.R)(),...e.components};return a?(0,t.jsx)(a,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},5479:(e,a,n)=>{n.d(a,{A:()=>s});const s=n.p+"assets/images/python-osism.drawio-19e90813de60b4afa58bc7ee4a3aeae8.png"},28453:(e,a,n)=>{n.d(a,{R:()=>r,x:()=>o});var s=n(96540);const t={},i=s.createContext(t);function r(e){const a=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function o(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),s.createElement(i.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/90489.a37158f4.js b/assets/js/90489.a37158f4.js new file mode 100644 index 0000000000..2a6b09bc12 --- /dev/null +++ b/assets/js/90489.a37158f4.js @@ -0,0 +1,2 @@ +/*! For license information please see 90489.a37158f4.js.LICENSE.txt */ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[90489],{90489:(t,e,n)=>{"use strict";t.exports=n(810)},2542:(t,e,n)=>{"use strict";var i=n(46573),s={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none",opacity:"1"},input:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},inputWithNoHint:{position:"relative",verticalAlign:"top"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"},suggestions:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"},ltr:{left:"0",right:"auto"},rtl:{left:"auto",right:"0"},defaultClasses:{root:"algolia-autocomplete",prefix:"aa",noPrefix:!1,dropdownMenu:"dropdown-menu",input:"input",hint:"hint",suggestions:"suggestions",suggestion:"suggestion",cursor:"cursor",dataset:"dataset",empty:"empty"},appendTo:{wrapper:{position:"absolute",zIndex:"100",display:"none"},input:{},inputWithNoHint:{},dropdown:{display:"block"}}};i.isMsie()&&i.mixin(s.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),i.isMsie()&&i.isMsie()<=7&&i.mixin(s.input,{marginTop:"-1px"}),t.exports=s},10897:(t,e,n)=>{"use strict";var i="aaDataset",s="aaValue",r="aaDatum",o=n(46573),a=n(61348),u=n(99272),c=n(2542),l=n(84436);function h(t){var e;(t=t||{}).templates=t.templates||{},t.source||o.error("missing source"),t.name&&(e=t.name,!/^[_a-zA-Z0-9-]+$/.test(e))&&o.error("invalid dataset name: "+t.name),this.query=null,this._isEmpty=!0,this.highlight=!!t.highlight,this.name=void 0===t.name||null===t.name?o.getUniqueId():t.name,this.source=t.source,this.displayFn=function(t){return t=t||"value",o.isFunction(t)?t:e;function e(e){return e[t]}}(t.display||t.displayKey),this.debounce=t.debounce,this.cache=!1!==t.cache,this.templates=function(t,e){return{empty:t.empty&&o.templatify(t.empty),header:t.header&&o.templatify(t.header),footer:t.footer&&o.templatify(t.footer),suggestion:t.suggestion||n};function n(t){return"<p>"+e(t)+"</p>"}}(t.templates,this.displayFn),this.css=o.mixin({},c,t.appendTo?c.appendTo:{}),this.cssClasses=t.cssClasses=o.mixin({},c.defaultClasses,t.cssClasses||{}),this.cssClasses.prefix=t.cssClasses.formattedPrefix||o.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix);var n=o.className(this.cssClasses.prefix,this.cssClasses.dataset);this.$el=t.$menu&&t.$menu.find(n+"-"+this.name).length>0?a.element(t.$menu.find(n+"-"+this.name)[0]):a.element(u.dataset.replace("%CLASS%",this.name).replace("%PREFIX%",this.cssClasses.prefix).replace("%DATASET%",this.cssClasses.dataset)),this.$menu=t.$menu,this.clearCachedSuggestions()}h.extractDatasetName=function(t){return a.element(t).data(i)},h.extractValue=function(t){return a.element(t).data(s)},h.extractDatum=function(t){var e=a.element(t).data(r);return"string"==typeof e&&(e=JSON.parse(e)),e},o.mixin(h.prototype,l,{_render:function(t,e){if(this.$el){var n,c=this,l=[].slice.call(arguments,2);if(this.$el.empty(),n=e&&e.length,this._isEmpty=!n,!n&&this.templates.empty)this.$el.html(function(){var e=[].slice.call(arguments,0);return e=[{query:t,isEmpty:!0}].concat(e),c.templates.empty.apply(this,e)}.apply(this,l)).prepend(c.templates.header?h.apply(this,l):null).append(c.templates.footer?p.apply(this,l):null);else if(n)this.$el.html(function(){var t,n,l=[].slice.call(arguments,0),h=this,p=u.suggestions.replace("%PREFIX%",this.cssClasses.prefix).replace("%SUGGESTIONS%",this.cssClasses.suggestions);return t=a.element(p).css(this.css.suggestions),n=o.map(e,f),t.append.apply(t,n),t;function f(t){var e,n=u.suggestion.replace("%PREFIX%",h.cssClasses.prefix).replace("%SUGGESTION%",h.cssClasses.suggestion);return(e=a.element(n).attr({role:"option",id:["option",Math.floor(1e8*Math.random())].join("-")}).append(c.templates.suggestion.apply(this,[t].concat(l)))).data(i,c.name),e.data(s,c.displayFn(t)||void 0),e.data(r,JSON.stringify(t)),e.children().each((function(){a.element(this).css(h.css.suggestionChild)})),e}}.apply(this,l)).prepend(c.templates.header?h.apply(this,l):null).append(c.templates.footer?p.apply(this,l):null);else if(e&&!Array.isArray(e))throw new TypeError("suggestions must be an array");this.$menu&&this.$menu.addClass(this.cssClasses.prefix+(n?"with":"without")+"-"+this.name).removeClass(this.cssClasses.prefix+(n?"without":"with")+"-"+this.name),this.trigger("rendered",t)}function h(){var e=[].slice.call(arguments,0);return e=[{query:t,isEmpty:!n}].concat(e),c.templates.header.apply(this,e)}function p(){var e=[].slice.call(arguments,0);return e=[{query:t,isEmpty:!n}].concat(e),c.templates.footer.apply(this,e)}},getRoot:function(){return this.$el},update:function(t){function e(e){if(!this.canceled&&t===this.query){var n=[].slice.call(arguments,1);this.cacheSuggestions(t,e,n),this._render.apply(this,[t,e].concat(n))}}if(this.query=t,this.canceled=!1,this.shouldFetchFromCache(t))e.apply(this,[this.cachedSuggestions].concat(this.cachedRenderExtraArgs));else{var n=this,i=function(){n.canceled||n.source(t,e.bind(n))};if(this.debounce){clearTimeout(this.debounceTimeout),this.debounceTimeout=setTimeout((function(){n.debounceTimeout=null,i()}),this.debounce)}else i()}},cacheSuggestions:function(t,e,n){this.cachedQuery=t,this.cachedSuggestions=e,this.cachedRenderExtraArgs=n},shouldFetchFromCache:function(t){return this.cache&&this.cachedQuery===t&&this.cachedSuggestions&&this.cachedSuggestions.length},clearCachedSuggestions:function(){delete this.cachedQuery,delete this.cachedSuggestions,delete this.cachedRenderExtraArgs},cancel:function(){this.canceled=!0},clear:function(){this.$el&&(this.cancel(),this.$el.empty(),this.trigger("rendered",""))},isEmpty:function(){return this._isEmpty},destroy:function(){this.clearCachedSuggestions(),this.$el=null}}),t.exports=h},21540:(t,e,n)=>{"use strict";var i=n(46573),s=n(61348),r=n(84436),o=n(10897),a=n(2542);function u(t){var e,n,r,o=this;(t=t||{}).menu||i.error("menu is required"),i.isArray(t.datasets)||i.isObject(t.datasets)||i.error("1 or more datasets required"),t.datasets||i.error("datasets is required"),this.isOpen=!1,this.isEmpty=!0,this.minLength=t.minLength||0,this.templates={},this.appendTo=t.appendTo||!1,this.css=i.mixin({},a,t.appendTo?a.appendTo:{}),this.cssClasses=t.cssClasses=i.mixin({},a.defaultClasses,t.cssClasses||{}),this.cssClasses.prefix=t.cssClasses.formattedPrefix||i.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix),e=i.bind(this._onSuggestionClick,this),n=i.bind(this._onSuggestionMouseEnter,this),r=i.bind(this._onSuggestionMouseLeave,this);var c=i.className(this.cssClasses.prefix,this.cssClasses.suggestion);this.$menu=s.element(t.menu).on("mouseenter.aa",c,n).on("mouseleave.aa",c,r).on("click.aa",c,e),this.$container=t.appendTo?t.wrapper:this.$menu,t.templates&&t.templates.header&&(this.templates.header=i.templatify(t.templates.header),this.$menu.prepend(this.templates.header())),t.templates&&t.templates.empty&&(this.templates.empty=i.templatify(t.templates.empty),this.$empty=s.element('<div class="'+i.className(this.cssClasses.prefix,this.cssClasses.empty,!0)+'"></div>'),this.$menu.append(this.$empty),this.$empty.hide()),this.datasets=i.map(t.datasets,(function(e){return function(t,e,n){return new u.Dataset(i.mixin({$menu:t,cssClasses:n},e))}(o.$menu,e,t.cssClasses)})),i.each(this.datasets,(function(t){var e=t.getRoot();e&&0===e.parent().length&&o.$menu.append(e),t.onSync("rendered",o._onRendered,o)})),t.templates&&t.templates.footer&&(this.templates.footer=i.templatify(t.templates.footer),this.$menu.append(this.templates.footer()));var l=this;s.element(window).resize((function(){l._redraw()}))}i.mixin(u.prototype,r,{_onSuggestionClick:function(t){this.trigger("suggestionClicked",s.element(t.currentTarget))},_onSuggestionMouseEnter:function(t){var e=s.element(t.currentTarget);if(!e.hasClass(i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0))){this._removeCursor();var n=this;setTimeout((function(){n._setCursor(e,!1)}),0)}},_onSuggestionMouseLeave:function(t){if(t.relatedTarget&&s.element(t.relatedTarget).closest("."+i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0)).length>0)return;this._removeCursor(),this.trigger("cursorRemoved")},_onRendered:function(t,e){if(this.isEmpty=i.every(this.datasets,(function(t){return t.isEmpty()})),this.isEmpty)if(e.length>=this.minLength&&this.trigger("empty"),this.$empty)if(e.length<this.minLength)this._hide();else{var n=this.templates.empty({query:this.datasets[0]&&this.datasets[0].query});this.$empty.html(n),this.$empty.show(),this._show()}else i.any(this.datasets,(function(t){return t.templates&&t.templates.empty}))?e.length<this.minLength?this._hide():this._show():this._hide();else this.isOpen&&(this.$empty&&(this.$empty.empty(),this.$empty.hide()),e.length>=this.minLength?this._show():this._hide());this.trigger("datasetRendered")},_hide:function(){this.$container.hide()},_show:function(){this.$container.css("display","block"),this._redraw(),this.trigger("shown")},_redraw:function(){this.isOpen&&this.appendTo&&this.trigger("redrawn")},_getSuggestions:function(){return this.$menu.find(i.className(this.cssClasses.prefix,this.cssClasses.suggestion))},_getCursor:function(){return this.$menu.find(i.className(this.cssClasses.prefix,this.cssClasses.cursor)).first()},_setCursor:function(t,e){t.first().addClass(i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0)).attr("aria-selected","true"),this.trigger("cursorMoved",e)},_removeCursor:function(){this._getCursor().removeClass(i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0)).removeAttr("aria-selected")},_moveCursor:function(t){var e,n,i,s;this.isOpen&&(n=this._getCursor(),e=this._getSuggestions(),this._removeCursor(),-1!==(i=((i=e.index(n)+t)+1)%(e.length+1)-1)?(i<-1&&(i=e.length-1),this._setCursor(s=e.eq(i),!0),this._ensureVisible(s)):this.trigger("cursorRemoved"))},_ensureVisible:function(t){var e,n,i,s;n=(e=t.position().top)+t.height()+parseInt(t.css("margin-top"),10)+parseInt(t.css("margin-bottom"),10),i=this.$menu.scrollTop(),s=this.$menu.height()+parseInt(this.$menu.css("padding-top"),10)+parseInt(this.$menu.css("padding-bottom"),10),e<0?this.$menu.scrollTop(i+e):s<n&&this.$menu.scrollTop(i+(n-s))},close:function(){this.isOpen&&(this.isOpen=!1,this._removeCursor(),this._hide(),this.trigger("closed"))},open:function(){this.isOpen||(this.isOpen=!0,this.isEmpty||this._show(),this.trigger("opened"))},setLanguageDirection:function(t){this.$menu.css("ltr"===t?this.css.ltr:this.css.rtl)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(1)},getDatumForSuggestion:function(t){var e=null;return t.length&&(e={raw:o.extractDatum(t),value:o.extractValue(t),datasetName:o.extractDatasetName(t)}),e},getCurrentCursor:function(){return this._getCursor().first()},getDatumForCursor:function(){return this.getDatumForSuggestion(this._getCursor().first())},getDatumForTopSuggestion:function(){return this.getDatumForSuggestion(this._getSuggestions().first())},cursorTopSuggestion:function(){this._setCursor(this._getSuggestions().first(),!1)},update:function(t){i.each(this.datasets,(function(e){e.update(t)}))},empty:function(){i.each(this.datasets,(function(t){t.clear()})),this.isEmpty=!0},isVisible:function(){return this.isOpen&&!this.isEmpty},destroy:function(){this.$menu.off(".aa"),this.$menu=null,i.each(this.datasets,(function(t){t.destroy()}))}}),u.Dataset=o,t.exports=u},52324:(t,e,n)=>{"use strict";var i=n(46573),s=n(61348);function r(t){t&&t.el||i.error("EventBus initialized without el"),this.$el=s.element(t.el)}i.mixin(r.prototype,{trigger:function(t,e,n,s){var r=i.Event("autocomplete:"+t);return this.$el.trigger(r,[e,n,s]),r}}),t.exports=r},84436:(t,e,n)=>{"use strict";var i=n(90874),s=/\s+/;function r(t,e,n,i){var r;if(!n)return this;for(e=e.split(s),n=i?function(t,e){return t.bind?t.bind(e):function(){t.apply(e,[].slice.call(arguments,0))}}(n,i):n,this._callbacks=this._callbacks||{};r=e.shift();)this._callbacks[r]=this._callbacks[r]||{sync:[],async:[]},this._callbacks[r][t].push(n);return this}function o(t,e,n){return function(){for(var i,s=0,r=t.length;!i&&s<r;s+=1)i=!1===t[s].apply(e,n);return!i}}t.exports={onSync:function(t,e,n){return r.call(this,"sync",t,e,n)},onAsync:function(t,e,n){return r.call(this,"async",t,e,n)},off:function(t){var e;if(!this._callbacks)return this;t=t.split(s);for(;e=t.shift();)delete this._callbacks[e];return this},trigger:function(t){var e,n,r,a,u;if(!this._callbacks)return this;t=t.split(s),r=[].slice.call(arguments,1);for(;(e=t.shift())&&(n=this._callbacks[e]);)a=o(n.sync,this,[e].concat(r)),u=o(n.async,this,[e].concat(r)),a()&&i(u);return this}}},99272:t=>{"use strict";t.exports={wrapper:'<span class="%ROOT%"></span>',dropdown:'<span class="%PREFIX%%DROPDOWN_MENU%"></span>',dataset:'<div class="%PREFIX%%DATASET%-%CLASS%"></div>',suggestions:'<span class="%PREFIX%%SUGGESTIONS%"></span>',suggestion:'<div class="%PREFIX%%SUGGESTION%"></div>'}},49629:(t,e,n)=>{"use strict";var i;i={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"};var s=n(46573),r=n(61348),o=n(84436);function a(t){var e,n,o,a,u,c=this;(t=t||{}).input||s.error("input is missing"),e=s.bind(this._onBlur,this),n=s.bind(this._onFocus,this),o=s.bind(this._onKeydown,this),a=s.bind(this._onInput,this),this.$hint=r.element(t.hint),this.$input=r.element(t.input).on("blur.aa",e).on("focus.aa",n).on("keydown.aa",o),0===this.$hint.length&&(this.setHint=this.getHint=this.clearHint=this.clearHintIfInvalid=s.noop),s.isMsie()?this.$input.on("keydown.aa keypress.aa cut.aa paste.aa",(function(t){i[t.which||t.keyCode]||s.defer(s.bind(c._onInput,c,t))})):this.$input.on("input.aa",a),this.query=this.$input.val(),this.$overflowHelper=(u=this.$input,r.element('<pre aria-hidden="true"></pre>').css({position:"absolute",visibility:"hidden",whiteSpace:"pre",fontFamily:u.css("font-family"),fontSize:u.css("font-size"),fontStyle:u.css("font-style"),fontVariant:u.css("font-variant"),fontWeight:u.css("font-weight"),wordSpacing:u.css("word-spacing"),letterSpacing:u.css("letter-spacing"),textIndent:u.css("text-indent"),textRendering:u.css("text-rendering"),textTransform:u.css("text-transform")}).insertAfter(u))}function u(t){return t.altKey||t.ctrlKey||t.metaKey||t.shiftKey}a.normalizeQuery=function(t){return(t||"").replace(/^\s*/g,"").replace(/\s{2,}/g," ")},s.mixin(a.prototype,o,{_onBlur:function(){this.resetInputValue(),this.$input.removeAttr("aria-activedescendant"),this.trigger("blurred")},_onFocus:function(){this.trigger("focused")},_onKeydown:function(t){var e=i[t.which||t.keyCode];this._managePreventDefault(e,t),e&&this._shouldTrigger(e,t)&&this.trigger(e+"Keyed",t)},_onInput:function(){this._checkInputValue()},_managePreventDefault:function(t,e){var n,i,s;switch(t){case"tab":i=this.getHint(),s=this.getInputValue(),n=i&&i!==s&&!u(e);break;case"up":case"down":n=!u(e);break;default:n=!1}n&&e.preventDefault()},_shouldTrigger:function(t,e){var n;if("tab"===t)n=!u(e);else n=!0;return n},_checkInputValue:function(){var t,e,n,i,s;t=this.getInputValue(),i=t,s=this.query,n=!(!(e=a.normalizeQuery(i)===a.normalizeQuery(s))||!this.query)&&this.query.length!==t.length,this.query=t,e?n&&this.trigger("whitespaceChanged",this.query):this.trigger("queryChanged",this.query)},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return this.query},setQuery:function(t){this.query=t},getInputValue:function(){return this.$input.val()},setInputValue:function(t,e){void 0===t&&(t=this.query),this.$input.val(t),e?this.clearHint():this._checkInputValue()},expand:function(){this.$input.attr("aria-expanded","true")},collapse:function(){this.$input.attr("aria-expanded","false")},setActiveDescendant:function(t){this.$input.attr("aria-activedescendant",t)},removeActiveDescendant:function(){this.$input.removeAttr("aria-activedescendant")},resetInputValue:function(){this.setInputValue(this.query,!0)},getHint:function(){return this.$hint.val()},setHint:function(t){this.$hint.val(t)},clearHint:function(){this.setHint("")},clearHintIfInvalid:function(){var t,e,n;n=(t=this.getInputValue())!==(e=this.getHint())&&0===e.indexOf(t),""!==t&&n&&!this.hasOverflow()||this.clearHint()},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},hasOverflow:function(){var t=this.$input.width()-2;return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>=t},isCursorAtEnd:function(){var t,e,n;return t=this.$input.val().length,e=this.$input[0].selectionStart,s.isNumber(e)?e===t:!document.selection||((n=document.selection.createRange()).moveStart("character",-t),t===n.text.length)},destroy:function(){this.$hint.off(".aa"),this.$input.off(".aa"),this.$hint=this.$input=this.$overflowHelper=null}}),t.exports=a},37360:(t,e,n)=>{"use strict";var i="aaAttrs",s=n(46573),r=n(61348),o=n(52324),a=n(49629),u=n(21540),c=n(99272),l=n(2542);function h(t){var e,n;if((t=t||{}).input||s.error("missing input"),this.isActivated=!1,this.debug=!!t.debug,this.autoselect=!!t.autoselect,this.autoselectOnBlur=!!t.autoselectOnBlur,this.openOnFocus=!!t.openOnFocus,this.minLength=s.isNumber(t.minLength)?t.minLength:1,this.autoWidth=void 0===t.autoWidth||!!t.autoWidth,this.clearOnSelected=!!t.clearOnSelected,this.tabAutocomplete=void 0===t.tabAutocomplete||!!t.tabAutocomplete,t.hint=!!t.hint,t.hint&&t.appendTo)throw new Error("[autocomplete.js] hint and appendTo options can't be used at the same time");this.css=t.css=s.mixin({},l,t.appendTo?l.appendTo:{}),this.cssClasses=t.cssClasses=s.mixin({},l.defaultClasses,t.cssClasses||{}),this.cssClasses.prefix=t.cssClasses.formattedPrefix=s.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix),this.listboxId=t.listboxId=[this.cssClasses.root,"listbox",s.getUniqueId()].join("-");var a=function(t){var e,n,o,a;e=r.element(t.input),n=r.element(c.wrapper.replace("%ROOT%",t.cssClasses.root)).css(t.css.wrapper),t.appendTo||"block"!==e.css("display")||"table"!==e.parent().css("display")||n.css("display","table-cell");var u=c.dropdown.replace("%PREFIX%",t.cssClasses.prefix).replace("%DROPDOWN_MENU%",t.cssClasses.dropdownMenu);o=r.element(u).css(t.css.dropdown).attr({role:"listbox",id:t.listboxId}),t.templates&&t.templates.dropdownMenu&&o.html(s.templatify(t.templates.dropdownMenu)());a=e.clone().css(t.css.hint).css(function(t){return{backgroundAttachment:t.css("background-attachment"),backgroundClip:t.css("background-clip"),backgroundColor:t.css("background-color"),backgroundImage:t.css("background-image"),backgroundOrigin:t.css("background-origin"),backgroundPosition:t.css("background-position"),backgroundRepeat:t.css("background-repeat"),backgroundSize:t.css("background-size")}}(e)),a.val("").addClass(s.className(t.cssClasses.prefix,t.cssClasses.hint,!0)).removeAttr("id name placeholder required").prop("readonly",!0).attr({"aria-hidden":"true",autocomplete:"off",spellcheck:"false",tabindex:-1}),a.removeData&&a.removeData();e.data(i,{"aria-autocomplete":e.attr("aria-autocomplete"),"aria-expanded":e.attr("aria-expanded"),"aria-owns":e.attr("aria-owns"),autocomplete:e.attr("autocomplete"),dir:e.attr("dir"),role:e.attr("role"),spellcheck:e.attr("spellcheck"),style:e.attr("style"),type:e.attr("type")}),e.addClass(s.className(t.cssClasses.prefix,t.cssClasses.input,!0)).attr({autocomplete:"off",spellcheck:!1,role:"combobox","aria-autocomplete":t.datasets&&t.datasets[0]&&t.datasets[0].displayKey?"both":"list","aria-expanded":"false","aria-label":t.ariaLabel,"aria-owns":t.listboxId}).css(t.hint?t.css.input:t.css.inputWithNoHint);try{e.attr("dir")||e.attr("dir","auto")}catch(l){}return n=t.appendTo?n.appendTo(r.element(t.appendTo).eq(0)).eq(0):e.wrap(n).parent(),n.prepend(t.hint?a:null).append(o),{wrapper:n,input:e,hint:a,menu:o}}(t);this.$node=a.wrapper;var u=this.$input=a.input;e=a.menu,n=a.hint,t.dropdownMenuContainer&&r.element(t.dropdownMenuContainer).css("position","relative").append(e.css("top","0")),u.on("blur.aa",(function(t){var n=document.activeElement;s.isMsie()&&(e[0]===n||e[0].contains(n))&&(t.preventDefault(),t.stopImmediatePropagation(),s.defer((function(){u.focus()})))})),e.on("mousedown.aa",(function(t){t.preventDefault()})),this.eventBus=t.eventBus||new o({el:u}),this.dropdown=new h.Dropdown({appendTo:t.appendTo,wrapper:this.$node,menu:e,datasets:t.datasets,templates:t.templates,cssClasses:t.cssClasses,minLength:this.minLength}).onSync("suggestionClicked",this._onSuggestionClicked,this).onSync("cursorMoved",this._onCursorMoved,this).onSync("cursorRemoved",this._onCursorRemoved,this).onSync("opened",this._onOpened,this).onSync("closed",this._onClosed,this).onSync("shown",this._onShown,this).onSync("empty",this._onEmpty,this).onSync("redrawn",this._onRedrawn,this).onAsync("datasetRendered",this._onDatasetRendered,this),this.input=new h.Input({input:u,hint:n}).onSync("focused",this._onFocused,this).onSync("blurred",this._onBlurred,this).onSync("enterKeyed",this._onEnterKeyed,this).onSync("tabKeyed",this._onTabKeyed,this).onSync("escKeyed",this._onEscKeyed,this).onSync("upKeyed",this._onUpKeyed,this).onSync("downKeyed",this._onDownKeyed,this).onSync("leftKeyed",this._onLeftKeyed,this).onSync("rightKeyed",this._onRightKeyed,this).onSync("queryChanged",this._onQueryChanged,this).onSync("whitespaceChanged",this._onWhitespaceChanged,this),this._bindKeyboardShortcuts(t),this._setLanguageDirection()}s.mixin(h.prototype,{_bindKeyboardShortcuts:function(t){if(t.keyboardShortcuts){var e=this.$input,n=[];s.each(t.keyboardShortcuts,(function(t){"string"==typeof t&&(t=t.toUpperCase().charCodeAt(0)),n.push(t)})),r.element(document).keydown((function(t){var i=t.target||t.srcElement,s=i.tagName;if(!i.isContentEditable&&"INPUT"!==s&&"SELECT"!==s&&"TEXTAREA"!==s){var r=t.which||t.keyCode;-1!==n.indexOf(r)&&(e.focus(),t.stopPropagation(),t.preventDefault())}}))}},_onSuggestionClicked:function(t,e){var n;(n=this.dropdown.getDatumForSuggestion(e))&&this._select(n,{selectionMethod:"click"})},_onCursorMoved:function(t,e){var n=this.dropdown.getDatumForCursor(),i=this.dropdown.getCurrentCursor().attr("id");this.input.setActiveDescendant(i),n&&(e&&this.input.setInputValue(n.value,!0),this.eventBus.trigger("cursorchanged",n.raw,n.datasetName))},_onCursorRemoved:function(){this.input.resetInputValue(),this._updateHint(),this.eventBus.trigger("cursorremoved")},_onDatasetRendered:function(){this._updateHint(),this.eventBus.trigger("updated")},_onOpened:function(){this._updateHint(),this.input.expand(),this.eventBus.trigger("opened")},_onEmpty:function(){this.eventBus.trigger("empty")},_onRedrawn:function(){this.$node.css("top","0px"),this.$node.css("left","0px");var t=this.$input[0].getBoundingClientRect();this.autoWidth&&this.$node.css("width",t.width+"px");var e=this.$node[0].getBoundingClientRect(),n=t.bottom-e.top;this.$node.css("top",n+"px");var i=t.left-e.left;this.$node.css("left",i+"px"),this.eventBus.trigger("redrawn")},_onShown:function(){this.eventBus.trigger("shown"),this.autoselect&&this.dropdown.cursorTopSuggestion()},_onClosed:function(){this.input.clearHint(),this.input.removeActiveDescendant(),this.input.collapse(),this.eventBus.trigger("closed")},_onFocused:function(){if(this.isActivated=!0,this.openOnFocus){var t=this.input.getQuery();t.length>=this.minLength?this.dropdown.update(t):this.dropdown.empty(),this.dropdown.open()}},_onBlurred:function(){var t,e;t=this.dropdown.getDatumForCursor(),e=this.dropdown.getDatumForTopSuggestion();var n={selectionMethod:"blur"};this.debug||(this.autoselectOnBlur&&t?this._select(t,n):this.autoselectOnBlur&&e?this._select(e,n):(this.isActivated=!1,this.dropdown.empty(),this.dropdown.close()))},_onEnterKeyed:function(t,e){var n,i;n=this.dropdown.getDatumForCursor(),i=this.dropdown.getDatumForTopSuggestion();var s={selectionMethod:"enterKey"};n?(this._select(n,s),e.preventDefault()):this.autoselect&&i&&(this._select(i,s),e.preventDefault())},_onTabKeyed:function(t,e){if(this.tabAutocomplete){var n;(n=this.dropdown.getDatumForCursor())?(this._select(n,{selectionMethod:"tabKey"}),e.preventDefault()):this._autocomplete(!0)}else this.dropdown.close()},_onEscKeyed:function(){this.dropdown.close(),this.input.resetInputValue()},_onUpKeyed:function(){var t=this.input.getQuery();this.dropdown.isEmpty&&t.length>=this.minLength?this.dropdown.update(t):this.dropdown.moveCursorUp(),this.dropdown.open()},_onDownKeyed:function(){var t=this.input.getQuery();this.dropdown.isEmpty&&t.length>=this.minLength?this.dropdown.update(t):this.dropdown.moveCursorDown(),this.dropdown.open()},_onLeftKeyed:function(){"rtl"===this.dir&&this._autocomplete()},_onRightKeyed:function(){"ltr"===this.dir&&this._autocomplete()},_onQueryChanged:function(t,e){this.input.clearHintIfInvalid(),e.length>=this.minLength?this.dropdown.update(e):this.dropdown.empty(),this.dropdown.open(),this._setLanguageDirection()},_onWhitespaceChanged:function(){this._updateHint(),this.dropdown.open()},_setLanguageDirection:function(){var t=this.input.getLanguageDirection();this.dir!==t&&(this.dir=t,this.$node.css("direction",t),this.dropdown.setLanguageDirection(t))},_updateHint:function(){var t,e,n,i,r;(t=this.dropdown.getDatumForTopSuggestion())&&this.dropdown.isVisible()&&!this.input.hasOverflow()?(e=this.input.getInputValue(),n=a.normalizeQuery(e),i=s.escapeRegExChars(n),(r=new RegExp("^(?:"+i+")(.+$)","i").exec(t.value))?this.input.setHint(e+r[1]):this.input.clearHint()):this.input.clearHint()},_autocomplete:function(t){var e,n,i,s;e=this.input.getHint(),n=this.input.getQuery(),i=t||this.input.isCursorAtEnd(),e&&n!==e&&i&&((s=this.dropdown.getDatumForTopSuggestion())&&this.input.setInputValue(s.value),this.eventBus.trigger("autocompleted",s.raw,s.datasetName))},_select:function(t,e){void 0!==t.value&&this.input.setQuery(t.value),this.clearOnSelected?this.setVal(""):this.input.setInputValue(t.value,!0),this._setLanguageDirection(),!1===this.eventBus.trigger("selected",t.raw,t.datasetName,e).isDefaultPrevented()&&(this.dropdown.close(),s.defer(s.bind(this.dropdown.empty,this.dropdown)))},open:function(){if(!this.isActivated){var t=this.input.getInputValue();t.length>=this.minLength?this.dropdown.update(t):this.dropdown.empty()}this.dropdown.open()},close:function(){this.dropdown.close()},setVal:function(t){t=s.toStr(t),this.isActivated?this.input.setInputValue(t):(this.input.setQuery(t),this.input.setInputValue(t,!0)),this._setLanguageDirection()},getVal:function(){return this.input.getQuery()},destroy:function(){this.input.destroy(),this.dropdown.destroy(),function(t,e){var n=t.find(s.className(e.prefix,e.input));s.each(n.data(i),(function(t,e){void 0===t?n.removeAttr(e):n.attr(e,t)})),n.detach().removeClass(s.className(e.prefix,e.input,!0)).insertAfter(t),n.removeData&&n.removeData(i);t.remove()}(this.$node,this.cssClasses),this.$node=null},getWrapper:function(){return this.dropdown.$container[0]}}),h.Dropdown=u,h.Input=a,h.sources=n(36353),t.exports=h},61348:t=>{"use strict";t.exports={element:null}},19715:t=>{"use strict";t.exports=function(t){var e=t.match(/Algolia for JavaScript \((\d+\.)(\d+\.)(\d+)\)/)||t.match(/Algolia for vanilla JavaScript (\d+\.)(\d+\.)(\d+)/);if(e)return[e[1],e[2],e[3]]}},46573:(t,e,n)=>{"use strict";var i,s=n(68937),r=n(61348);function o(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}t.exports={isArray:null,isFunction:null,isObject:null,bind:null,each:null,map:null,mixin:null,isMsie:function(t){if(void 0===t&&(t=navigator.userAgent),/(msie|trident)/i.test(t)){var e=t.match(/(msie |rv:)(\d+(.\d+)?)/i);if(e)return e[2]}return!1},escapeRegExChars:function(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isNumber:function(t){return"number"==typeof t},toStr:function(t){return null==t?"":t+""},cloneDeep:function(t){var e=this.mixin({},t),n=this;return this.each(e,(function(t,i){t&&(n.isArray(t)?e[i]=[].concat(t):n.isObject(t)&&(e[i]=n.cloneDeep(t)))})),e},error:function(t){throw new Error(t)},every:function(t,e){var n=!0;return t?(this.each(t,(function(i,s){n&&(n=e.call(null,i,s,t)&&n)})),!!n):n},any:function(t,e){var n=!1;return t?(this.each(t,(function(i,s){if(e.call(null,i,s,t))return n=!0,!1})),n):n},getUniqueId:(i=0,function(){return i++}),templatify:function(t){if(this.isFunction(t))return t;var e=r.element(t);return"SCRIPT"===e.prop("tagName")?function(){return e.text()}:function(){return String(t)}},defer:function(t){setTimeout(t,0)},noop:function(){},formatPrefix:function(t,e){return e?"":t+"-"},className:function(t,e,n){return n?t+e:"."+s(t+e,{isIdentifier:!0})},escapeHighlightedString:function(t,e,n){e=e||"<em>";var i=document.createElement("div");i.appendChild(document.createTextNode(e)),n=n||"</em>";var s=document.createElement("div");s.appendChild(document.createTextNode(n));var r=document.createElement("div");return r.appendChild(document.createTextNode(t)),r.innerHTML.replace(RegExp(o(i.innerHTML),"g"),e).replace(RegExp(o(s.innerHTML),"g"),n)}}},16903:(t,e,n)=>{"use strict";var i=n(46573),s=n(92281),r=n(19715);var o,a,u=(o=[],a=window.Promise.resolve(),function(t,e){return function(n,s){(function(t,e){return window.Promise.resolve().then((function(){return o.length&&(a=t.search(o),o=[]),a})).then((function(t){if(t)return t.results[e]}))})(t.as,o.push({indexName:t.indexName,query:n,params:e})-1).then((function(t){t&&s(t.hits,t)})).catch((function(t){i.error(t.message)}))}});t.exports=function(t,e){var n=r(t.as._ua);if(n&&n[0]>=3&&n[1]>20){var i="autocomplete.js "+s;-1===t.as._ua.indexOf(i)&&(t.as._ua+="; "+i)}return u(t,e)}},36353:(t,e,n)=>{"use strict";t.exports={hits:n(16903),popularIn:n(46839)}},46839:(t,e,n)=>{"use strict";var i=n(46573),s=n(92281),r=n(19715);t.exports=function(t,e,n,o){var a=r(t.as._ua);if(a&&a[0]>=3&&a[1]>20&&((e=e||{}).additionalUA="autocomplete.js "+s),!n.source)return i.error("Missing 'source' key");var u=i.isFunction(n.source)?n.source:function(t){return t[n.source]};if(!n.index)return i.error("Missing 'index' key");var c=n.index;return o=o||{},function(a,l){t.search(a,e,(function(t,a){if(t)i.error(t.message);else{if(a.hits.length>0){var h=a.hits[0],p=i.mixin({hitsPerPage:0},n);delete p.source,delete p.index;var f=r(c.as._ua);return f&&f[0]>=3&&f[1]>20&&(e.additionalUA="autocomplete.js "+s),void c.search(u(h),p,(function(t,e){if(t)i.error(t.message);else{var n=[];if(o.includeAll){var s=o.allTitle||"All departments";n.push(i.mixin({facet:{value:s,count:e.nbHits}},i.cloneDeep(h)))}i.each(e.facets,(function(t,e){i.each(t,(function(t,s){n.push(i.mixin({facet:{facet:e,value:s,count:t}},i.cloneDeep(h)))}))}));for(var r=1;r<a.hits.length;++r)n.push(a.hits[r]);l(n,a)}}))}l([])}}))}}},810:(t,e,n)=>{"use strict";var i=n(59539);n(61348).element=i;var s=n(46573);s.isArray=i.isArray,s.isFunction=i.isFunction,s.isObject=i.isPlainObject,s.bind=i.proxy,s.each=function(t,e){i.each(t,(function(t,n){return e(n,t)}))},s.map=i.map,s.mixin=i.extend,s.Event=i.Event;var r="aaAutocomplete",o=n(37360),a=n(52324);function u(t,e,n,u){n=s.isArray(n)?n:[].slice.call(arguments,2);var c=i(t).each((function(t,s){var c=i(s),l=new a({el:c}),h=u||new o({input:c,eventBus:l,dropdownMenuContainer:e.dropdownMenuContainer,hint:void 0===e.hint||!!e.hint,minLength:e.minLength,autoselect:e.autoselect,autoselectOnBlur:e.autoselectOnBlur,tabAutocomplete:e.tabAutocomplete,openOnFocus:e.openOnFocus,templates:e.templates,debug:e.debug,clearOnSelected:e.clearOnSelected,cssClasses:e.cssClasses,datasets:n,keyboardShortcuts:e.keyboardShortcuts,appendTo:e.appendTo,autoWidth:e.autoWidth,ariaLabel:e.ariaLabel||s.getAttribute("aria-label")});c.data(r,h)}));return c.autocomplete={},s.each(["open","close","getVal","setVal","destroy","getWrapper"],(function(t){c.autocomplete[t]=function(){var e,n=arguments;return c.each((function(s,o){var a=i(o).data(r);e=a[t].apply(a,n)})),e}})),c}u.sources=o.sources,u.escapeHighlightedString=s.escapeHighlightedString;var c="autocomplete"in window,l=window.autocomplete;u.noConflict=function(){return c?window.autocomplete=l:delete window.autocomplete,u},t.exports=u},92281:t=>{t.exports="0.38.1"},59539:t=>{var e;e=window,t.exports=function(t){var e,n,i=function(){var e,n,i,s,r,o,a=[],u=a.concat,c=a.filter,l=a.slice,h=t.document,p={},f={},d={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},g=/^\s*<(\w+|!)[^>]*>/,m=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,y=/^(?:body|html)$/i,w=/([A-Z])/g,b=["val","css","html","text","data","width","height","offset"],C=["after","prepend","before","append"],x=h.createElement("table"),_=h.createElement("tr"),S={tr:h.createElement("tbody"),tbody:x,thead:x,tfoot:x,td:_,th:_,"*":h.createElement("div")},E=/complete|loaded|interactive/,A=/^[\w-]*$/,$={},T=$.toString,O={},D=h.createElement("div"),N={tabindex:"tabIndex",readonly:"readOnly",for:"htmlFor",class:"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},k=Array.isArray||function(t){return t instanceof Array};function I(t){return null==t?String(t):$[T.call(t)]||"object"}function P(t){return"function"==I(t)}function L(t){return null!=t&&t==t.window}function M(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE}function F(t){return"object"==I(t)}function R(t){return F(t)&&!L(t)&&Object.getPrototypeOf(t)==Object.prototype}function q(t){var e=!!t&&"length"in t&&t.length,n=i.type(t);return"function"!=n&&!L(t)&&("array"==n||0===e||"number"==typeof e&&e>0&&e-1 in t)}function V(t){return c.call(t,(function(t){return null!=t}))}function H(t){return t.length>0?i.fn.concat.apply([],t):t}function B(t){return t.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function K(t){return t in f?f[t]:f[t]=new RegExp("(^|\\s)"+t+"(\\s|$)")}function j(t,e){return"number"!=typeof e||d[B(t)]?e:e+"px"}function z(t){var e,n;return p[t]||(e=h.createElement(t),h.body.appendChild(e),n=getComputedStyle(e,"").getPropertyValue("display"),e.parentNode.removeChild(e),"none"==n&&(n="block"),p[t]=n),p[t]}function U(t){return"children"in t?l.call(t.children):i.map(t.childNodes,(function(t){if(1==t.nodeType)return t}))}function Q(t,e){var n,i=t?t.length:0;for(n=0;n<i;n++)this[n]=t[n];this.length=i,this.selector=e||""}function W(t,i,s){for(n in i)s&&(R(i[n])||k(i[n]))?(R(i[n])&&!R(t[n])&&(t[n]={}),k(i[n])&&!k(t[n])&&(t[n]=[]),W(t[n],i[n],s)):i[n]!==e&&(t[n]=i[n])}function Z(t,e){return null==e?i(t):i(t).filter(e)}function X(t,e,n,i){return P(e)?e.call(t,n,i):e}function G(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function J(t,n){var i=t.className||"",s=i&&i.baseVal!==e;if(n===e)return s?i.baseVal:i;s?i.baseVal=n:t.className=n}function Y(t){try{return t?"true"==t||"false"!=t&&("null"==t?null:+t+""==t?+t:/^[\[\{]/.test(t)?i.parseJSON(t):t):t}catch(e){return t}}function tt(t,e){e(t);for(var n=0,i=t.childNodes.length;n<i;n++)tt(t.childNodes[n],e)}return O.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var n=t.matches||t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var i,s=t.parentNode,r=!s;return r&&(s=D).appendChild(t),i=~O.qsa(s,e).indexOf(t),r&&D.removeChild(t),i},r=function(t){return t.replace(/-+(.)?/g,(function(t,e){return e?e.toUpperCase():""}))},o=function(t){return c.call(t,(function(e,n){return t.indexOf(e)==n}))},O.fragment=function(t,n,s){var r,o,a;return m.test(t)&&(r=i(h.createElement(RegExp.$1))),r||(t.replace&&(t=t.replace(v,"<$1></$2>")),n===e&&(n=g.test(t)&&RegExp.$1),n in S||(n="*"),(a=S[n]).innerHTML=""+t,r=i.each(l.call(a.childNodes),(function(){a.removeChild(this)}))),R(s)&&(o=i(r),i.each(s,(function(t,e){b.indexOf(t)>-1?o[t](e):o.attr(t,e)}))),r},O.Z=function(t,e){return new Q(t,e)},O.isZ=function(t){return t instanceof O.Z},O.init=function(t,n){var s;if(!t)return O.Z();if("string"==typeof t)if("<"==(t=t.trim())[0]&&g.test(t))s=O.fragment(t,RegExp.$1,n),t=null;else{if(n!==e)return i(n).find(t);s=O.qsa(h,t)}else{if(P(t))return i(h).ready(t);if(O.isZ(t))return t;if(k(t))s=V(t);else if(F(t))s=[t],t=null;else if(g.test(t))s=O.fragment(t.trim(),RegExp.$1,n),t=null;else{if(n!==e)return i(n).find(t);s=O.qsa(h,t)}}return O.Z(s,t)},(i=function(t,e){return O.init(t,e)}).extend=function(t){var e,n=l.call(arguments,1);return"boolean"==typeof t&&(e=t,t=n.shift()),n.forEach((function(n){W(t,n,e)})),t},O.qsa=function(t,e){var n,i="#"==e[0],s=!i&&"."==e[0],r=i||s?e.slice(1):e,o=A.test(r);return t.getElementById&&o&&i?(n=t.getElementById(r))?[n]:[]:1!==t.nodeType&&9!==t.nodeType&&11!==t.nodeType?[]:l.call(o&&!i&&t.getElementsByClassName?s?t.getElementsByClassName(r):t.getElementsByTagName(e):t.querySelectorAll(e))},i.contains=h.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},i.type=I,i.isFunction=P,i.isWindow=L,i.isArray=k,i.isPlainObject=R,i.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},i.isNumeric=function(t){var e=Number(t),n=typeof t;return null!=t&&"boolean"!=n&&("string"!=n||t.length)&&!isNaN(e)&&isFinite(e)||!1},i.inArray=function(t,e,n){return a.indexOf.call(e,t,n)},i.camelCase=r,i.trim=function(t){return null==t?"":String.prototype.trim.call(t)},i.uuid=0,i.support={},i.expr={},i.noop=function(){},i.map=function(t,e){var n,i,s,r=[];if(q(t))for(i=0;i<t.length;i++)null!=(n=e(t[i],i))&&r.push(n);else for(s in t)null!=(n=e(t[s],s))&&r.push(n);return H(r)},i.each=function(t,e){var n,i;if(q(t)){for(n=0;n<t.length;n++)if(!1===e.call(t[n],n,t[n]))return t}else for(i in t)if(!1===e.call(t[i],i,t[i]))return t;return t},i.grep=function(t,e){return c.call(t,e)},t.JSON&&(i.parseJSON=JSON.parse),i.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),(function(t,e){$["[object "+e+"]"]=e.toLowerCase()})),i.fn={constructor:O.Z,length:0,forEach:a.forEach,reduce:a.reduce,push:a.push,sort:a.sort,splice:a.splice,indexOf:a.indexOf,concat:function(){var t,e,n=[];for(t=0;t<arguments.length;t++)e=arguments[t],n[t]=O.isZ(e)?e.toArray():e;return u.apply(O.isZ(this)?this.toArray():this,n)},map:function(t){return i(i.map(this,(function(e,n){return t.call(e,n,e)})))},slice:function(){return i(l.apply(this,arguments))},ready:function(t){return E.test(h.readyState)&&h.body?t(i):h.addEventListener("DOMContentLoaded",(function(){t(i)}),!1),this},get:function(t){return t===e?l.call(this):this[t>=0?t:t+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each((function(){null!=this.parentNode&&this.parentNode.removeChild(this)}))},each:function(t){return a.every.call(this,(function(e,n){return!1!==t.call(e,n,e)})),this},filter:function(t){return P(t)?this.not(this.not(t)):i(c.call(this,(function(e){return O.matches(e,t)})))},add:function(t,e){return i(o(this.concat(i(t,e))))},is:function(t){return this.length>0&&O.matches(this[0],t)},not:function(t){var n=[];if(P(t)&&t.call!==e)this.each((function(e){t.call(this,e)||n.push(this)}));else{var s="string"==typeof t?this.filter(t):q(t)&&P(t.item)?l.call(t):i(t);this.forEach((function(t){s.indexOf(t)<0&&n.push(t)}))}return i(n)},has:function(t){return this.filter((function(){return F(t)?i.contains(this,t):i(this).find(t).size()}))},eq:function(t){return-1===t?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!F(t)?t:i(t)},last:function(){var t=this[this.length-1];return t&&!F(t)?t:i(t)},find:function(t){var e=this;return t?"object"==typeof t?i(t).filter((function(){var t=this;return a.some.call(e,(function(e){return i.contains(e,t)}))})):1==this.length?i(O.qsa(this[0],t)):this.map((function(){return O.qsa(this,t)})):i()},closest:function(t,e){var n=[],s="object"==typeof t&&i(t);return this.each((function(i,r){for(;r&&!(s?s.indexOf(r)>=0:O.matches(r,t));)r=r!==e&&!M(r)&&r.parentNode;r&&n.indexOf(r)<0&&n.push(r)})),i(n)},parents:function(t){for(var e=[],n=this;n.length>0;)n=i.map(n,(function(t){if((t=t.parentNode)&&!M(t)&&e.indexOf(t)<0)return e.push(t),t}));return Z(e,t)},parent:function(t){return Z(o(this.pluck("parentNode")),t)},children:function(t){return Z(this.map((function(){return U(this)})),t)},contents:function(){return this.map((function(){return this.contentDocument||l.call(this.childNodes)}))},siblings:function(t){return Z(this.map((function(t,e){return c.call(U(e.parentNode),(function(t){return t!==e}))})),t)},empty:function(){return this.each((function(){this.innerHTML=""}))},pluck:function(t){return i.map(this,(function(e){return e[t]}))},show:function(){return this.each((function(){"none"==this.style.display&&(this.style.display=""),"none"==getComputedStyle(this,"").getPropertyValue("display")&&(this.style.display=z(this.nodeName))}))},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var e=P(t);if(this[0]&&!e)var n=i(t).get(0),s=n.parentNode||this.length>1;return this.each((function(r){i(this).wrapAll(e?t.call(this,r):s?n.cloneNode(!0):n)}))},wrapAll:function(t){if(this[0]){var e;for(i(this[0]).before(t=i(t));(e=t.children()).length;)t=e.first();i(t).append(this)}return this},wrapInner:function(t){var e=P(t);return this.each((function(n){var s=i(this),r=s.contents(),o=e?t.call(this,n):t;r.length?r.wrapAll(o):s.append(o)}))},unwrap:function(){return this.parent().each((function(){i(this).replaceWith(i(this).children())})),this},clone:function(){return this.map((function(){return this.cloneNode(!0)}))},hide:function(){return this.css("display","none")},toggle:function(t){return this.each((function(){var n=i(this);(t===e?"none"==n.css("display"):t)?n.show():n.hide()}))},prev:function(t){return i(this.pluck("previousElementSibling")).filter(t||"*")},next:function(t){return i(this.pluck("nextElementSibling")).filter(t||"*")},html:function(t){return 0 in arguments?this.each((function(e){var n=this.innerHTML;i(this).empty().append(X(this,t,e,n))})):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each((function(e){var n=X(this,t,e,this.textContent);this.textContent=null==n?"":""+n})):0 in this?this.pluck("textContent").join(""):null},attr:function(t,i){var s;return"string"!=typeof t||1 in arguments?this.each((function(e){if(1===this.nodeType)if(F(t))for(n in t)G(this,n,t[n]);else G(this,t,X(this,i,e,this.getAttribute(t)))})):0 in this&&1==this[0].nodeType&&null!=(s=this[0].getAttribute(t))?s:e},removeAttr:function(t){return this.each((function(){1===this.nodeType&&t.split(" ").forEach((function(t){G(this,t)}),this)}))},prop:function(t,e){return t=N[t]||t,1 in arguments?this.each((function(n){this[t]=X(this,e,n,this[t])})):this[0]&&this[0][t]},removeProp:function(t){return t=N[t]||t,this.each((function(){delete this[t]}))},data:function(t,n){var i="data-"+t.replace(w,"-$1").toLowerCase(),s=1 in arguments?this.attr(i,n):this.attr(i);return null!==s?Y(s):e},val:function(t){return 0 in arguments?(null==t&&(t=""),this.each((function(e){this.value=X(this,t,e,this.value)}))):this[0]&&(this[0].multiple?i(this[0]).find("option").filter((function(){return this.selected})).pluck("value"):this[0].value)},offset:function(e){if(e)return this.each((function(t){var n=i(this),s=X(this,e,t,n.offset()),r=n.offsetParent().offset(),o={top:s.top-r.top,left:s.left-r.left};"static"==n.css("position")&&(o.position="relative"),n.css(o)}));if(!this.length)return null;if(h.documentElement!==this[0]&&!i.contains(h.documentElement,this[0]))return{top:0,left:0};var n=this[0].getBoundingClientRect();return{left:n.left+t.pageXOffset,top:n.top+t.pageYOffset,width:Math.round(n.width),height:Math.round(n.height)}},css:function(t,e){if(arguments.length<2){var s=this[0];if("string"==typeof t){if(!s)return;return s.style[r(t)]||getComputedStyle(s,"").getPropertyValue(t)}if(k(t)){if(!s)return;var o={},a=getComputedStyle(s,"");return i.each(t,(function(t,e){o[e]=s.style[r(e)]||a.getPropertyValue(e)})),o}}var u="";if("string"==I(t))e||0===e?u=B(t)+":"+j(t,e):this.each((function(){this.style.removeProperty(B(t))}));else for(n in t)t[n]||0===t[n]?u+=B(n)+":"+j(n,t[n])+";":this.each((function(){this.style.removeProperty(B(n))}));return this.each((function(){this.style.cssText+=";"+u}))},index:function(t){return t?this.indexOf(i(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return!!t&&a.some.call(this,(function(t){return this.test(J(t))}),K(t))},addClass:function(t){return t?this.each((function(e){if("className"in this){s=[];var n=J(this);X(this,t,e,n).split(/\s+/g).forEach((function(t){i(this).hasClass(t)||s.push(t)}),this),s.length&&J(this,n+(n?" ":"")+s.join(" "))}})):this},removeClass:function(t){return this.each((function(n){if("className"in this){if(t===e)return J(this,"");s=J(this),X(this,t,n,s).split(/\s+/g).forEach((function(t){s=s.replace(K(t)," ")})),J(this,s.trim())}}))},toggleClass:function(t,n){return t?this.each((function(s){var r=i(this);X(this,t,s,J(this)).split(/\s+/g).forEach((function(t){(n===e?!r.hasClass(t):n)?r.addClass(t):r.removeClass(t)}))})):this},scrollTop:function(t){if(this.length){var n="scrollTop"in this[0];return t===e?n?this[0].scrollTop:this[0].pageYOffset:this.each(n?function(){this.scrollTop=t}:function(){this.scrollTo(this.scrollX,t)})}},scrollLeft:function(t){if(this.length){var n="scrollLeft"in this[0];return t===e?n?this[0].scrollLeft:this[0].pageXOffset:this.each(n?function(){this.scrollLeft=t}:function(){this.scrollTo(t,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),n=this.offset(),s=y.test(e[0].nodeName)?{top:0,left:0}:e.offset();return n.top-=parseFloat(i(t).css("margin-top"))||0,n.left-=parseFloat(i(t).css("margin-left"))||0,s.top+=parseFloat(i(e[0]).css("border-top-width"))||0,s.left+=parseFloat(i(e[0]).css("border-left-width"))||0,{top:n.top-s.top,left:n.left-s.left}}},offsetParent:function(){return this.map((function(){for(var t=this.offsetParent||h.body;t&&!y.test(t.nodeName)&&"static"==i(t).css("position");)t=t.offsetParent;return t}))}},i.fn.detach=i.fn.remove,["width","height"].forEach((function(t){var n=t.replace(/./,(function(t){return t[0].toUpperCase()}));i.fn[t]=function(s){var r,o=this[0];return s===e?L(o)?o["inner"+n]:M(o)?o.documentElement["scroll"+n]:(r=this.offset())&&r[t]:this.each((function(e){(o=i(this)).css(t,X(this,s,e,o[t]()))}))}})),C.forEach((function(n,s){var r=s%2;i.fn[n]=function(){var n,o,a=i.map(arguments,(function(t){var s=[];return"array"==(n=I(t))?(t.forEach((function(t){return t.nodeType!==e?s.push(t):i.zepto.isZ(t)?s=s.concat(t.get()):void(s=s.concat(O.fragment(t)))})),s):"object"==n||null==t?t:O.fragment(t)})),u=this.length>1;return a.length<1?this:this.each((function(e,n){o=r?n:n.parentNode,n=0==s?n.nextSibling:1==s?n.firstChild:2==s?n:null;var c=i.contains(h.documentElement,o);a.forEach((function(e){if(u)e=e.cloneNode(!0);else if(!o)return i(e).remove();o.insertBefore(e,n),c&&tt(e,(function(e){if(!(null==e.nodeName||"SCRIPT"!==e.nodeName.toUpperCase()||e.type&&"text/javascript"!==e.type||e.src)){var n=e.ownerDocument?e.ownerDocument.defaultView:t;n.eval.call(n,e.innerHTML)}}))}))}))},i.fn[r?n+"To":"insert"+(s?"Before":"After")]=function(t){return i(t)[n](this),this}})),O.Z.prototype=Q.prototype=i.fn,O.uniq=o,O.deserializeValue=Y,i.zepto=O,i}();return function(e){var n,i=1,s=Array.prototype.slice,r=e.isFunction,o=function(t){return"string"==typeof t},a={},u={},c="onfocusin"in t,l={focus:"focusin",blur:"focusout"},h={mouseenter:"mouseover",mouseleave:"mouseout"};function p(t){return t._zid||(t._zid=i++)}function f(t,e,n,i){if((e=d(e)).ns)var s=g(e.ns);return(a[p(t)]||[]).filter((function(t){return t&&(!e.e||t.e==e.e)&&(!e.ns||s.test(t.ns))&&(!n||p(t.fn)===p(n))&&(!i||t.sel==i)}))}function d(t){var e=(""+t).split(".");return{e:e[0],ns:e.slice(1).sort().join(" ")}}function g(t){return new RegExp("(?:^| )"+t.replace(" "," .* ?")+"(?: |$)")}function m(t,e){return t.del&&!c&&t.e in l||!!e}function v(t){return h[t]||c&&l[t]||t}function y(t,i,s,r,o,u,c){var l=p(t),f=a[l]||(a[l]=[]);i.split(/\s/).forEach((function(i){if("ready"==i)return e(document).ready(s);var a=d(i);a.fn=s,a.sel=o,a.e in h&&(s=function(t){var n=t.relatedTarget;if(!n||n!==this&&!e.contains(this,n))return a.fn.apply(this,arguments)}),a.del=u;var l=u||s;a.proxy=function(e){if(!(e=S(e)).isImmediatePropagationStopped()){try{var i=Object.getOwnPropertyDescriptor(e,"data");i&&!i.writable||(e.data=r)}catch(e){}var s=l.apply(t,e._args==n?[e]:[e].concat(e._args));return!1===s&&(e.preventDefault(),e.stopPropagation()),s}},a.i=f.length,f.push(a),"addEventListener"in t&&t.addEventListener(v(a.e),a.proxy,m(a,c))}))}function w(t,e,n,i,s){var r=p(t);(e||"").split(/\s/).forEach((function(e){f(t,e,n,i).forEach((function(e){delete a[r][e.i],"removeEventListener"in t&&t.removeEventListener(v(e.e),e.proxy,m(e,s))}))}))}u.click=u.mousedown=u.mouseup=u.mousemove="MouseEvents",e.event={add:y,remove:w},e.proxy=function(t,n){var i=2 in arguments&&s.call(arguments,2);if(r(t)){var a=function(){return t.apply(n,i?i.concat(s.call(arguments)):arguments)};return a._zid=p(t),a}if(o(n))return i?(i.unshift(t[n],t),e.proxy.apply(null,i)):e.proxy(t[n],t);throw new TypeError("expected function")},e.fn.bind=function(t,e,n){return this.on(t,e,n)},e.fn.unbind=function(t,e){return this.off(t,e)},e.fn.one=function(t,e,n,i){return this.on(t,e,n,i,1)};var b=function(){return!0},C=function(){return!1},x=/^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/,_={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};function S(t,i){if(i||!t.isDefaultPrevented){i||(i=t),e.each(_,(function(e,n){var s=i[e];t[e]=function(){return this[n]=b,s&&s.apply(i,arguments)},t[n]=C}));try{t.timeStamp||(t.timeStamp=Date.now())}catch(s){}(i.defaultPrevented!==n?i.defaultPrevented:"returnValue"in i?!1===i.returnValue:i.getPreventDefault&&i.getPreventDefault())&&(t.isDefaultPrevented=b)}return t}function E(t){var e,i={originalEvent:t};for(e in t)x.test(e)||t[e]===n||(i[e]=t[e]);return S(i,t)}e.fn.delegate=function(t,e,n){return this.on(e,t,n)},e.fn.undelegate=function(t,e,n){return this.off(e,t,n)},e.fn.live=function(t,n){return e(document.body).delegate(this.selector,t,n),this},e.fn.die=function(t,n){return e(document.body).undelegate(this.selector,t,n),this},e.fn.on=function(t,i,a,u,c){var l,h,p=this;return t&&!o(t)?(e.each(t,(function(t,e){p.on(t,i,a,e,c)})),p):(o(i)||r(u)||!1===u||(u=a,a=i,i=n),u!==n&&!1!==a||(u=a,a=n),!1===u&&(u=C),p.each((function(n,r){c&&(l=function(t){return w(r,t.type,u),u.apply(this,arguments)}),i&&(h=function(t){var n,o=e(t.target).closest(i,r).get(0);if(o&&o!==r)return n=e.extend(E(t),{currentTarget:o,liveFired:r}),(l||u).apply(o,[n].concat(s.call(arguments,1)))}),y(r,t,u,a,i,h||l)})))},e.fn.off=function(t,i,s){var a=this;return t&&!o(t)?(e.each(t,(function(t,e){a.off(t,i,e)})),a):(o(i)||r(s)||!1===s||(s=i,i=n),!1===s&&(s=C),a.each((function(){w(this,t,s,i)})))},e.fn.trigger=function(t,n){return(t=o(t)||e.isPlainObject(t)?e.Event(t):S(t))._args=n,this.each((function(){t.type in l&&"function"==typeof this[t.type]?this[t.type]():"dispatchEvent"in this?this.dispatchEvent(t):e(this).triggerHandler(t,n)}))},e.fn.triggerHandler=function(t,n){var i,s;return this.each((function(r,a){(i=E(o(t)?e.Event(t):t))._args=n,i.target=a,e.each(f(a,t.type||t),(function(t,e){if(s=e.proxy(i),i.isImmediatePropagationStopped())return!1}))})),s},"focusin focusout focus blur load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach((function(t){e.fn[t]=function(e){return 0 in arguments?this.bind(t,e):this.trigger(t)}})),e.Event=function(t,e){o(t)||(t=(e=t).type);var n=document.createEvent(u[t]||"Events"),i=!0;if(e)for(var s in e)"bubbles"==s?i=!!e[s]:n[s]=e[s];return n.initEvent(t,i,!0),S(n)}}(i),n=[],i.fn.remove=function(){return this.each((function(){this.parentNode&&("IMG"===this.tagName&&(n.push(this),this.src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=",e&&clearTimeout(e),e=setTimeout((function(){n=[]}),6e4)),this.parentNode.removeChild(this))}))},function(t){var e={},n=t.fn.data,i=t.camelCase,s=t.expando="Zepto"+ +new Date,r=[];function o(r,o){var u=r[s],c=u&&e[u];if(void 0===o)return c||a(r);if(c){if(o in c)return c[o];var l=i(o);if(l in c)return c[l]}return n.call(t(r),o)}function a(n,r,o){var a=n[s]||(n[s]=++t.uuid),c=e[a]||(e[a]=u(n));return void 0!==r&&(c[i(r)]=o),c}function u(e){var n={};return t.each(e.attributes||r,(function(e,s){0==s.name.indexOf("data-")&&(n[i(s.name.replace("data-",""))]=t.zepto.deserializeValue(s.value))})),n}t.fn.data=function(e,n){return void 0===n?t.isPlainObject(e)?this.each((function(n,i){t.each(e,(function(t,e){a(i,t,e)}))})):0 in this?o(this[0],e):void 0:this.each((function(){a(this,e,n)}))},t.data=function(e,n,i){return t(e).data(n,i)},t.hasData=function(n){var i=n[s],r=i&&e[i];return!!r&&!t.isEmptyObject(r)},t.fn.removeData=function(n){return"string"==typeof n&&(n=n.split(/\s+/)),this.each((function(){var r=this[s],o=r&&e[r];o&&t.each(n||o,(function(t){delete o[n?i(this):t]}))}))},["remove","empty"].forEach((function(e){var n=t.fn[e];t.fn[e]=function(){var t=this.find("*");return"remove"===e&&(t=t.add(this)),t.removeData(),n.call(this)}}))}(i),i}(e)},68937:t=>{"use strict";var e={}.hasOwnProperty,n=/[ -,\.\/:-@\[-\^`\{-~]/,i=/[ -,\.\/:-@\[\]\^`\{-~]/,s=/(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g,r=function t(r,o){"single"!=(o=function(t,n){if(!t)return n;var i={};for(var s in n)i[s]=e.call(t,s)?t[s]:n[s];return i}(o,t.options)).quotes&&"double"!=o.quotes&&(o.quotes="single");for(var a="double"==o.quotes?'"':"'",u=o.isIdentifier,c=r.charAt(0),l="",h=0,p=r.length;h<p;){var f=r.charAt(h++),d=f.charCodeAt(),g=void 0;if(d<32||d>126){if(d>=55296&&d<=56319&&h<p){var m=r.charCodeAt(h++);56320==(64512&m)?d=((1023&d)<<10)+(1023&m)+65536:h--}g="\\"+d.toString(16).toUpperCase()+" "}else g=o.escapeEverything?n.test(f)?"\\"+f:"\\"+d.toString(16).toUpperCase()+" ":/[\t\n\f\r\x0B]/.test(f)?"\\"+d.toString(16).toUpperCase()+" ":"\\"==f||!u&&('"'==f&&a==f||"'"==f&&a==f)||u&&i.test(f)?"\\"+f:f;l+=g}return u&&(/^-[-\d]/.test(l)?l="\\-"+l.slice(1):/\d/.test(c)&&(l="\\3"+c+" "+l.slice(1))),l=l.replace(s,(function(t,e,n){return e&&e.length%2?t:(e||"")+n})),!u&&o.wrap?a+l+a:l};r.options={escapeEverything:!1,isIdentifier:!1,quotes:"single",wrap:!1},r.version="3.0.0",t.exports=r},90874:(t,e,n)=>{"use strict";var i,s,r,o=[n(45741),n(91856),n(41015),n(16486),n(45723),n(26345)],a=-1,u=[],c=!1;function l(){i&&s&&(i=!1,s.length?u=s.concat(u):a=-1,u.length&&h())}function h(){if(!i){c=!1,i=!0;for(var t=u.length,e=setTimeout(l);t;){for(s=u,u=[];s&&++a<t;)s[a].run();a=-1,t=u.length}s=null,a=-1,i=!1,clearTimeout(e)}}for(var p=-1,f=o.length;++p<f;)if(o[p]&&o[p].test&&o[p].test()){r=o[p].install(h);break}function d(t,e){this.fun=t,this.array=e}d.prototype.run=function(){var t=this.fun,e=this.array;switch(e.length){case 0:return t();case 1:return t(e[0]);case 2:return t(e[0],e[1]);case 3:return t(e[0],e[1],e[2]);default:return t.apply(null,e)}},t.exports=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];u.push(new d(t,e)),c||i||(c=!0,r())}},16486:(t,e,n)=>{"use strict";e.test=function(){return!n.g.setImmediate&&void 0!==n.g.MessageChannel},e.install=function(t){var e=new n.g.MessageChannel;return e.port1.onmessage=t,function(){e.port2.postMessage(0)}}},41015:(t,e,n)=>{"use strict";var i=n.g.MutationObserver||n.g.WebKitMutationObserver;e.test=function(){return i},e.install=function(t){var e=0,s=new i(t),r=n.g.document.createTextNode("");return s.observe(r,{characterData:!0}),function(){r.data=e=++e%2}}},91856:(t,e,n)=>{"use strict";e.test=function(){return"function"==typeof n.g.queueMicrotask},e.install=function(t){return function(){n.g.queueMicrotask(t)}}},45723:(t,e,n)=>{"use strict";e.test=function(){return"document"in n.g&&"onreadystatechange"in n.g.document.createElement("script")},e.install=function(t){return function(){var e=n.g.document.createElement("script");return e.onreadystatechange=function(){t(),e.onreadystatechange=null,e.parentNode.removeChild(e),e=null},n.g.document.documentElement.appendChild(e),t}}},26345:(t,e)=>{"use strict";e.test=function(){return!0},e.install=function(t){return function(){setTimeout(t,0)}}}}]); \ No newline at end of file diff --git a/assets/js/90489.a37158f4.js.LICENSE.txt b/assets/js/90489.a37158f4.js.LICENSE.txt new file mode 100644 index 0000000000..4f7ccd8a76 --- /dev/null +++ b/assets/js/90489.a37158f4.js.LICENSE.txt @@ -0,0 +1 @@ +/*! https://mths.be/cssesc v3.0.0 by @mathias */ diff --git a/assets/js/9099a3d2.0a60597a.js b/assets/js/9099a3d2.0a60597a.js new file mode 100644 index 0000000000..37406ba788 --- /dev/null +++ b/assets/js/9099a3d2.0a60597a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[96172],{77401:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>t,default:()=>a,frontMatter:()=>c,metadata:()=>r,toc:()=>h});const r=JSON.parse('{"id":"central-services/plusserver-gx-scs","title":"Central services","description":"This document gives an overview of what SCS central services are deployed and who is responsible for them in plusserver gx-scs infrastructure.","source":"@site/community/central-services/plusserver-gx-scs.md","sourceDirName":"central-services","slug":"/central-services/plusserver-gx-scs","permalink":"/community/central-services/plusserver-gx-scs","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{}}');var i=s(74848),l=s(28453);const c={},t="Central services",o={},h=[{value:"Project p500924-harbor",id:"project-p500924-harbor",level:2},{value:"K8s clusters",id:"k8s-clusters",level:3},{value:"Harbor",id:"harbor",level:4},{value:"Project p500924-sig-monitoring1",id:"project-p500924-sig-monitoring1",level:2},{value:"K8s clusters",id:"k8s-clusters-1",level:3},{value:"Monitoring",id:"monitoring",level:4}];function d(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",ul:"ul",...(0,l.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"central-services",children:"Central services"})}),"\n",(0,i.jsx)(n.p,{children:"This document gives an overview of what SCS central services are deployed and who is responsible for them in plusserver gx-scs infrastructure."}),"\n",(0,i.jsx)(n.h2,{id:"project-p500924-harbor",children:"Project p500924-harbor"}),"\n",(0,i.jsx)(n.h3,{id:"k8s-clusters",children:"K8s clusters"}),"\n",(0,i.jsx)(n.h4,{id:"harbor",children:"Harbor"}),"\n",(0,i.jsxs)(n.p,{children:["Responsibility: ",(0,i.jsx)(n.a,{href:"https://github.com/orgs/SovereignCloudStack/teams/vp06c",children:"@SovereignCloudStack/vp06c"})]}),"\n",(0,i.jsx)(n.p,{children:"Services:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://registry.scs.community/",children:"SCS Registry"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-harbor/tree/main/envs/public",children:"k8s-harbor"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Utilization:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Instances: 7"}),"\n",(0,i.jsx)(n.li,{children:"VCPUs: 32"}),"\n",(0,i.jsx)(n.li,{children:"RAM: 64GB"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Spec:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"version: v7.0.0 - R6"}),"\n",(0,i.jsxs)(n.li,{children:["management cluster:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"1 instance: SCS-2V:4:20"}),"\n",(0,i.jsx)(n.li,{children:"image: Ubuntu 22.04 (20230416)"}),"\n",(0,i.jsx)(n.li,{children:"k8s: v1.25.3 - KinD"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["workload cluster:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["6 instances:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"3 control-planes: SCS-2V-4-20s"}),"\n",(0,i.jsx)(n.li,{children:"3 workers: SCS-8V:16:100"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:"image: ubuntu-capi-image-v1.28.7"}),"\n",(0,i.jsx)(n.li,{children:"k8s: v1.28.7"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"project-p500924-sig-monitoring1",children:"Project p500924-sig-monitoring1"}),"\n",(0,i.jsx)(n.h3,{id:"k8s-clusters-1",children:"K8s clusters"}),"\n",(0,i.jsx)(n.h4,{id:"monitoring",children:"Monitoring"}),"\n",(0,i.jsxs)(n.p,{children:["Responsibility: ",(0,i.jsx)(n.a,{href:"https://github.com/orgs/SovereignCloudStack/teams/vp06c",children:"@SovereignCloudStack/vp06c"})]}),"\n",(0,i.jsx)(n.p,{children:"Services:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-observability",children:"k8s-observability"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Utilization:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Instances: 7"}),"\n",(0,i.jsx)(n.li,{children:"VCPUs: 32"}),"\n",(0,i.jsx)(n.li,{children:"RAM: 64GB"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Spec:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"version: v7.0.0 - R6"}),"\n",(0,i.jsxs)(n.li,{children:["management cluster:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"1 instance: SCS-2V:4:20"}),"\n",(0,i.jsx)(n.li,{children:"image: Ubuntu 22.04 (20240125)"}),"\n",(0,i.jsx)(n.li,{children:"k8s: v1.27.3 - KinD"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["workload cluster:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["6 instances:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"3 control-planes: SCS-2V-4-20s"}),"\n",(0,i.jsx)(n.li,{children:"3 workers: SCS-8V:16:100"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:"image: ubuntu-capi-image-v1.28.7"}),"\n",(0,i.jsx)(n.li,{children:"k8s: v1.28.7"}),"\n"]}),"\n"]}),"\n"]})]})}function a(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>t});var r=s(96540);const i={},l=r.createContext(i);function c(e){const n=r.useContext(l);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),r.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/90c33bef.0e31e6ea.js b/assets/js/90c33bef.0e31e6ea.js new file mode 100644 index 0000000000..f9e82a124a --- /dev/null +++ b/assets/js/90c33bef.0e31e6ea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[79692],{8602:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>l,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>o});const r=JSON.parse('{"id":"scs-0118-v1-taxonomy-of-failsafe-levels","title":"SCS Taxonomy of Failsafe Levels","description":"Abstract","source":"@site/standards/scs-0118-v1-taxonomy-of-failsafe-levels.md","sourceDirName":".","slug":"/scs-0118-v1-taxonomy-of-failsafe-levels","permalink":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Taxonomy of Failsafe Levels","type":"Decision Record","status":"Draft","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0118: SCS Taxonomy of Failsafe Levels","permalink":"/standards/iaas/scs-0118"},"next":{"title":"W1","permalink":"/standards/scs-0118-w1-example-impacts-of-failure-scenarios"}}');var n=t(74848),a=t(28453);const i={title:"SCS Taxonomy of Failsafe Levels",type:"Decision Record",status:"Draft",track:"IaaS"},d=void 0,l={},o=[{value:"Abstract",id:"abstract",level:2},{value:"Glossary",id:"glossary",level:2},{value:"Context",id:"context",level:2},{value:"Goal of this Decision Record",id:"goal-of-this-decision-record",level:3},{value:"Differentiation between failsafe levels and high availability, disaster recovery, redundancy and backups",id:"differentiation-between-failsafe-levels-and-high-availability-disaster-recovery-redundancy-and-backups",level:3},{value:"Failsafe Levels and RTO",id:"failsafe-levels-and-rto",level:3},{value:"Decision",id:"decision",level:2},{value:"Failsafe Levels",id:"failsafe-levels",level:3},{value:"Failure Scenarios",id:"failure-scenarios",level:3},{value:"Hardware Related",id:"hardware-related",level:4},{value:"Environmental",id:"environmental",level:4},{value:"Software Related",id:"software-related",level:4},{value:"Human Interference",id:"human-interference",level:4},{value:"Consequences",id:"consequences",level:2},{value:"Affected Resources",id:"affected-resources",level:3},{value:"IaaS Layer (OpenStack Resources)",id:"iaas-layer-openstack-resources",level:4},{value:"KaaS Layer (Kubernetes Resources)",id:"kaas-layer-kubernetes-resources",level:4}];function c(e){const s={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h2,{id:"abstract",children:"Abstract"}),"\n",(0,n.jsx)(s.p,{children:"When talking about redundancy and backups in the context of cloud infrastructures, the scope under which circumstances these concepts apply to various resources is neither homogenous nor intuitive.\nThere does exist very detailed lists of risks and what consequences there are for each risk, but this Decision Record should give a high-level view on the topic.\nSo that in each standard that referenced redundancy, it can easily be seen how far this redundancy goes in that certain circumstance.\nReaders of such standards should be able to know at one glance, whether the achieved failure safeness is on a basic level or a higher one and whether there would be additional actions needed to protect the data."}),"\n",(0,n.jsx)(s.p,{children:"This is why this decision record aims to define different levels of failure safety.\nThese levels can then be used in standards to clearly set the scope that certain procedures in e.g. OpenStack offer."}),"\n",(0,n.jsx)(s.h2,{id:"glossary",children:"Glossary"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Term"}),(0,n.jsx)(s.th,{children:"Explanation"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Availability Zone"}),(0,n.jsx)(s.td,{children:"(also: AZ) internal representation of physical grouping of service hosts, which also lead to internal grouping of resources."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"BSI"}),(0,n.jsx)(s.td,{children:"German Federal Office for Information Security (Bundesamt f\xfcr Sicherheit in der Informationstechnik)."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"CSP"}),(0,n.jsx)(s.td,{children:"Cloud Service Provider, provider managing the OpenStack infrastructure."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Compute"}),(0,n.jsx)(s.td,{children:"A generic name for the IaaS service, that manages virtual machines (e.g. Nova in OpenStack)."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Network"}),(0,n.jsx)(s.td,{children:"A generic name for the IaaS service, that manages network resources (e.g. Neutron in OpenStack)."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Storage"}),(0,n.jsx)(s.td,{children:"A generic name for the IaaS service, that manages the storage backends and virtual devices (e.g. Cinder in OpenStack)."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"RTO"}),(0,n.jsx)(s.td,{children:"Recovery Time Objective, the acceptable time needed to restore a ressource."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Disk"}),(0,n.jsx)(s.td,{children:"A physical disk drive (e.g. HDD, SSD) in the infrastructure."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Host"}),(0,n.jsx)(s.td,{children:"A physical machine in the infrastructure providing computational, storage and/or network connectivity capabilities."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Cyber attack/threat"}),(0,n.jsx)(s.td,{children:"Attacks on the infrastructure through the means of electronic access."})]})]})]}),"\n",(0,n.jsx)(s.h2,{id:"context",children:"Context"}),"\n",(0,n.jsx)(s.p,{children:"Some standards provided by the SCS project will talk about or require procedures to back up resources or have redundancy for resources.\nThis decision record should discuss, which failure threats exist within an IaaS and KaaS deployment and will classify them into several levels according to their impact and possible handling mechanisms.\nIn consequence these levels should be used in standards concerning redundancy or failure safety."}),"\n",(0,n.jsxs)(s.p,{children:["Based on our research, no similar standardized classification scheme seems to exist currently.\nSomething close but also very detailed is the ",(0,n.jsx)(s.a,{href:"https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Grundschutz/BSI_Standards/standard_200_3.pdf?__blob=publicationFile&v=2",children:"BSI-Standard 200-3 (german)"})," published by the German Federal Office for Information Security.\nAs we want to focus on IaaS and K8s resources and also have an easily understandable structure that can be applied in standards covering replication, redundancy and backups, this document is too detailed."]}),"\n",(0,n.jsx)(s.h3,{id:"goal-of-this-decision-record",children:"Goal of this Decision Record"}),"\n",(0,n.jsx)(s.p,{children:"The SCS wants to classify levels of failure cases according to their impact and the respective measures CSPs can implement to prepare for each level.\nStandards that deal with redundancy or backups or recovery SHOULD refer to the levels of this standard.\nThus every reader knows, up to which level of failsafeness the implementation of the standard works.\nReader then should be able to abstract what kind of other measures they have to apply, to reach the failsafe lavel they want to reach."}),"\n",(0,n.jsx)(s.admonition,{type:"caution",children:(0,n.jsx)(s.p,{children:"This document will not be a replacement for a risk analysis.\nEvery CSP and every Customer (user of IaaS or KaaS resources) need to do a risk analysis of their own.\nAlso the differentiation of failure cases in classes, may not be an ideal basis for Business Continuity Planning.\nIt may be used to get general hints and directions though."})}),"\n",(0,n.jsx)(s.h3,{id:"differentiation-between-failsafe-levels-and-high-availability-disaster-recovery-redundancy-and-backups",children:"Differentiation between failsafe levels and high availability, disaster recovery, redundancy and backups"}),"\n",(0,n.jsx)(s.p,{children:"The levels of failsafeness defined in this decision record classify the possibilities and impacts of failure cases (such as data loss) and the possible measures.\nHigh Availability, disaster recovery, redundancy and backups are all measures that can and should be applied to IaaS and KaaS deployments by both CSPs and Users to reduce the possibility and impact of data loss.\nSo with this document every reader can see to what level of failsafeness their measures protect user data."}),"\n",(0,n.jsx)(s.p,{children:"To differentiate also between the named measures the following table can be used:"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Term"}),(0,n.jsx)(s.th,{children:"Explanation"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"High Availability"}),(0,n.jsx)(s.td,{children:"Refers to the availability of resources over an extended period of time unaffected by smaller hardware issues. E.g. achievable through having several instances of resources."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Disaster Recovery"}),(0,n.jsx)(s.td,{children:"Measures taken after an incident to recover data, IaaS resource and maybe even physical resources."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Redundancy"}),(0,n.jsx)(s.td,{children:"Having more than one (or two) instances of each resource, to be able to switch to the second resource (could also be a data mirror) in case of a failure."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Backup"}),(0,n.jsx)(s.td,{children:"A specific copy of user data, that presents all data points at a given time. Usually managed by users themself, read only and never stored in the same place as the original data."})]})]})]}),"\n",(0,n.jsx)(s.h3,{id:"failsafe-levels-and-rto",children:"Failsafe Levels and RTO"}),"\n",(0,n.jsx)(s.p,{children:"As this documents classifies failure case with very broad impacts and it is written in regards of mostly IaaS and KaaS, there cannot be one simple RTO set.\nThe RTOs will differ for each resource and also between IaaS and KaaS level.\nIt should be taken into consideration that the measure to achieve the RTOs for IaaS and KaaS means to make user data available again through measures within the infrastructure.\nBut this will not be effective, when there is no backup of the user data or a redundancy of it already in place.\nSo the different failsafe levels, measures and impacts will be needed to define realistic RTOs.\nFor example a storage disk that has a failure will not result in a volume gein unavailable and needing a defined RTO, when the storage backend uses internal replication and still has two replicas of the user data.\nWhile in the worst case of a natural disaster, most likely a severe fire, the whole deployment will be lost and if there were no off-site backups done by users any defined RTO will never be met, because the data cannot be recovered anymore."}),"\n",(0,n.jsx)(s.h2,{id:"decision",children:"Decision"}),"\n",(0,n.jsx)(s.h3,{id:"failsafe-levels",children:"Failsafe Levels"}),"\n",(0,n.jsxs)(s.p,{children:["This Decision Record defines ",(0,n.jsx)(s.strong,{children:"four"})," failsafe levels, each of which describe what kind of failures have to\nbe tolerated by a provided service."]}),"\n",(0,n.jsx)(s.admonition,{type:"caution",children:(0,n.jsx)(s.p,{children:"This table only contains examples of failure cases.\nThis should not be used as a replacement for a risk analysis."})}),"\n",(0,n.jsxs)(s.p,{children:["In general, the lowest, ",(0,n.jsx)(s.strong,{children:"level 1"}),", describes isolated/local failures which can occur very frequently, whereas\nthe highest, ",(0,n.jsx)(s.strong,{children:"level 4"}),", describes relatively unlikely failures that impact a whole or even multiple datacenter(s):"]}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Level"}),(0,n.jsx)(s.th,{children:"Probability"}),(0,n.jsx)(s.th,{children:"Impact"}),(0,n.jsx)(s.th,{children:"Examples"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"1"}),(0,n.jsx)(s.td,{children:"Very High"}),(0,n.jsx)(s.td,{children:"small Hardware Issue"}),(0,n.jsx)(s.td,{children:"Disk failure, RAM failure, small software bug"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"2"}),(0,n.jsx)(s.td,{children:"High"}),(0,n.jsx)(s.td,{children:"Rack-wide"}),(0,n.jsx)(s.td,{children:"Rack outage, power outage, small fire"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"3"}),(0,n.jsx)(s.td,{children:"Medium"}),(0,n.jsx)(s.td,{children:"site-wide (temporary)"}),(0,n.jsx)(s.td,{children:"Regional power outage, huge fire, orchestrated cyber attack"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{children:"Low"}),(0,n.jsx)(s.td,{children:"site destruction"}),(0,n.jsx)(s.td,{children:"Natural disaster"})]})]})]}),"\n",(0,n.jsx)(s.p,{children:"For example, a provided service with failsafe level 2 tolerates a rack outage (because there is some kind of\nredundancy in place.)"}),"\n",(0,n.jsxs)(s.p,{children:["There are some ",(0,n.jsx)(s.em,{children:"general"})," consequences, that can be addressed by CSPs and users in the following ways:"]}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Level"}),(0,n.jsx)(s.th,{children:"consequences for CSPs"}),(0,n.jsx)(s.th,{children:"consequences for Users"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"1. Level"}),(0,n.jsx)(s.td,{children:"CSPs MUST operate replicas for important components (e.g. replicated volume back-end, replicated database, ...)."}),(0,n.jsx)(s.td,{children:"Users SHOULD backup their data themself and place it on an other host."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"2. Level"}),(0,n.jsx)(s.td,{children:"CSPs MUST have redundancy for important components (e.g. HA for API services, redundant power supply, ...)."}),(0,n.jsx)(s.td,{children:"Users MUST backup their data themselves and place it on an other host."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"3. Level"}),(0,n.jsx)(s.td,{children:"CSPs SHOULD operate hardware in dedicated Availability Zones."}),(0,n.jsx)(s.td,{children:"Users SHOULD backup their data, in different AZs or even other deployments."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"4. Level"}),(0,n.jsx)(s.td,{children:"CSPs may not be able to save user data from such catastrophes."}),(0,n.jsx)(s.td,{children:"Users MUST have a backup of their data in a different geographic location."})]})]})]}),"\n",(0,n.jsx)(s.admonition,{type:"caution",children:(0,n.jsxs)(s.p,{children:["The columns ",(0,n.jsx)(s.strong,{children:"consequences for CSPs / Users"})," only show examples of actions that may provide this class of failure safety for a certain resource.\nCustomers should always check, what they can do to protect their data and not rely solely on the CSP."]})}),"\n",(0,n.jsx)(s.p,{children:"More specific guidance on what these levels mean on the IaaS and KaaS layers will be provided in the sections\nfurther down.\nBut beforehand, we will describe the considered failure scenarios and the resources that may be affected."}),"\n",(0,n.jsx)(s.h3,{id:"failure-scenarios",children:"Failure Scenarios"}),"\n",(0,n.jsx)(s.p,{children:"The following failure scenarios have been considered for the proposed failsafe levels.\nFor each failure scenario, we estimate the probability of occurence and the (worst case) damage caused by the scenario.\nFurthermore, the corresponding minimum failsafe level covering that failure scenario is given.\nThe following table give a coarse view over the probabilities, that are used to describe the occurance of failure cases:"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Probability"}),(0,n.jsx)(s.th,{children:"Meaning"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Very Low"}),(0,n.jsx)(s.td,{children:"Occurs at most once a decade OR needs extremly unlikely circumstances."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Low"}),(0,n.jsx)(s.td,{children:"Occurs at most once a year OR needs very unlikely circumstances."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Medium"}),(0,n.jsx)(s.td,{children:"Occurs more than one time a year, up to one time a month."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"High"}),(0,n.jsx)(s.td,{children:"Occurs more than once a month and up to a daily basis."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Very High"}),(0,n.jsx)(s.td,{children:"Occurs within minutes."})]})]})]}),"\n",(0,n.jsx)(s.h4,{id:"hardware-related",children:"Hardware Related"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Failure Scenario"}),(0,n.jsx)(s.th,{children:"Probability"}),(0,n.jsx)(s.th,{children:"Consequences"}),(0,n.jsx)(s.th,{children:"Failsafe Level Coverage"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Disk Failure"}),(0,n.jsx)(s.td,{children:"High"}),(0,n.jsx)(s.td,{children:"Permanent data loss in this disk. Impact depends on type of lost data (data base, user data)"}),(0,n.jsx)(s.td,{children:"L1"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Host Failure (without disks)"}),(0,n.jsx)(s.td,{children:"Medium to High"}),(0,n.jsx)(s.td,{children:"Permanent loss of functionality and connectivity of host (impact depends on type of host)"}),(0,n.jsx)(s.td,{children:"L1"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Host Failure"}),(0,n.jsx)(s.td,{children:"Medium to High"}),(0,n.jsx)(s.td,{children:"Data loss in RAM and temporary loss of functionality and connectivity of host (impact depends on type of host)"}),(0,n.jsx)(s.td,{children:"L1"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Rack Outage"}),(0,n.jsx)(s.td,{children:"Medium"}),(0,n.jsx)(s.td,{children:"Outage of all nodes in rack"}),(0,n.jsx)(s.td,{children:"L2"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Network router/switch outage"}),(0,n.jsx)(s.td,{children:"Medium"}),(0,n.jsx)(s.td,{children:"Temporary loss of service, loss of connectivity, network partitioning"}),(0,n.jsx)(s.td,{children:"L2"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Loss of network uplink"}),(0,n.jsx)(s.td,{children:"Medium"}),(0,n.jsx)(s.td,{children:"Temporary loss of service, loss of connectivity"}),(0,n.jsx)(s.td,{children:"L3"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Power Outage (Data Center supply)"}),(0,n.jsx)(s.td,{children:"Medium"}),(0,n.jsx)(s.td,{children:"Temporary outage of all nodes in all racks"}),(0,n.jsx)(s.td,{children:"L3"})]})]})]}),"\n",(0,n.jsx)(s.h4,{id:"environmental",children:"Environmental"}),"\n",(0,n.jsx)(s.p,{children:"Note that probability for these scenarios is dependent on the location."}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Failure Scenario"}),(0,n.jsx)(s.th,{children:"Probability"}),(0,n.jsx)(s.th,{children:"Consequences"}),(0,n.jsx)(s.th,{children:"Failsafe Level Coverage"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Fire"}),(0,n.jsx)(s.td,{children:"Low"}),(0,n.jsx)(s.td,{children:"permanent Disk and Host loss in the affected zone"}),(0,n.jsx)(s.td,{children:"L3"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Flood"}),(0,n.jsx)(s.td,{children:"Very Low"}),(0,n.jsx)(s.td,{children:"permanent Disk and Host loss in the affected region"}),(0,n.jsx)(s.td,{children:"L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Earthquake"}),(0,n.jsx)(s.td,{children:"Very Low"}),(0,n.jsx)(s.td,{children:"permanent Disk and Host loss in the affected region"}),(0,n.jsx)(s.td,{children:"L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Storm/Tornado"}),(0,n.jsx)(s.td,{children:"Low"}),(0,n.jsx)(s.td,{children:"permanent Disk and Host loss in the affected region"}),(0,n.jsx)(s.td,{children:"L4"})]})]})]}),"\n",(0,n.jsx)(s.p,{children:"As we consider mainly deployments in central Europe, the probability of earthquakes is low and in the rare case of such an event the severity is also low compared to other regions in the world (e.g. the pacific ring of fire).\nThe event of a flood will most likely come from overflowing rivers instead of storm floods from a sea.\nThere can be measures taken, to reduce the probability and severity of a flooding event in central Europe due to simply choosing a different location for a deployment."}),"\n",(0,n.jsx)(s.h4,{id:"software-related",children:"Software Related"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Failure Scenario"}),(0,n.jsx)(s.th,{children:"Probability"}),(0,n.jsx)(s.th,{children:"Consequences"}),(0,n.jsx)(s.th,{children:"Failsafe Level Coverage"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Software bug (major)"}),(0,n.jsx)(s.td,{children:"Low to Medium"}),(0,n.jsx)(s.td,{children:"permanent loss or compromise of data that trigger the bug up to data on the whole deployment"}),(0,n.jsx)(s.td,{children:"L3"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Software bug (minor)"}),(0,n.jsx)(s.td,{children:"Medium to High"}),(0,n.jsx)(s.td,{children:"temporary or partial loss or compromise of data"}),(0,n.jsx)(s.td,{children:"L1"})]})]})]}),"\n",(0,n.jsxs)(s.p,{children:["Many software components have lots of lines of code and cannot be proven correct in their whole functionality.\nThey are tested instead with at best enough test cases to check every interaction.\nStill bugs can and will occur in software.\nMost of them are rather small issues, that might even seem like a feature to some.\nAn exmple for this would be: ",(0,n.jsx)(s.a,{href:"https://bugs.launchpad.net/neutron/+bug/2060808",children:"whether a floating IP in OpenStack could be assigned to a VM even if it is already bound to another VM"}),".\nBugs like this do not affect a whole deployment, when they are triggered, but just specific data or resources.\nNevertheless those bugs can be a daily struggle.\nThis is the reason, the probability of such minor bugs may be pretty high, but the consequences would either be just temporary or would only result in small losses or compromisation."]}),"\n",(0,n.jsxs)(s.p,{children:["On the other hand major bugs, which might be used to compromise data, that is not in direct connection to the triggered bug, occur only a few times a year.\nThis can be seen e.g. in the ",(0,n.jsx)(s.a,{href:"https://security.openstack.org/ossalist.html",children:"OpenStack Security Advisories"}),", where there were only 3 major bugs found in 2023.\nWhile these bugs might appear only rarely their consequences are immense.\nThey might be the reason for a whole deployment to be compromised or shut down.\nCSPs should be in contact with people triaging and patching such bugs, to be informed early and to be able to update their deployments, before the bug is openly announced."]}),"\n",(0,n.jsx)(s.h4,{id:"human-interference",children:"Human Interference"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Failure Scenario"}),(0,n.jsx)(s.th,{children:"Probability"}),(0,n.jsx)(s.th,{children:"Consequences"}),(0,n.jsx)(s.th,{children:"Failsafe Level Coverage"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Minor operating error"}),(0,n.jsx)(s.td,{children:"High"}),(0,n.jsx)(s.td,{children:"Temporary outage"}),(0,n.jsx)(s.td,{children:"L1"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Major operating error"}),(0,n.jsx)(s.td,{children:"Low"}),(0,n.jsx)(s.td,{children:"Permanent loss of data"}),(0,n.jsx)(s.td,{children:"L3"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Cyber attack (minor)"}),(0,n.jsx)(s.td,{children:"Very High"}),(0,n.jsx)(s.td,{children:"permanent loss or compromise of data on affected Disk and Host"}),(0,n.jsx)(s.td,{children:"L1"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Cyber attack (major)"}),(0,n.jsx)(s.td,{children:"Medium"}),(0,n.jsx)(s.td,{children:"permanent loss or compromise of data on affected Disk and Host"}),(0,n.jsx)(s.td,{children:"L3"})]})]})]}),"\n",(0,n.jsx)(s.p,{children:"Mistakes in maintaining a data center will always happen.\nTo reduce the probability of such a mistake, measures are needed to reduce human error, which is more an issue of sociology and psychology instead of computer science.\nOn the other side an attack on an infrastructure cannot be avoided by this.\nInstead every deployment needs to be prepared for an attack all the time, e.g. through security updates.\nThe severity of Cyber attacks can also vary broadly: from denial-of-service attacks, which should only be a temporary issue, up until coordinated attacks to steal or destroy data, which could also affect a whole deployment.\nThe easier an attack is, the more frequently it will be used by various persons and organizations up to be just daily business.\nMajor attacks are often orchestrated and require specific knowledge e.g. of Day-0 Bugs or the attacked infrastructure.\nDue to that nature their occurance is less likely, but the damage done can be far more severe."}),"\n",(0,n.jsx)(s.h2,{id:"consequences",children:"Consequences"}),"\n",(0,n.jsx)(s.p,{children:"Using the definition of levels established in this decision record throughout all SCS standards would allow readers to understand up to which level certain procedures or aspects of resources (e.g. volume types or a backend requiring redundancy) would protect their data and/or resource availability."}),"\n",(0,n.jsx)(s.h3,{id:"affected-resources",children:"Affected Resources"}),"\n",(0,n.jsx)(s.h4,{id:"iaas-layer-openstack-resources",children:"IaaS Layer (OpenStack Resources)"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Resource"}),(0,n.jsx)(s.th,{children:"Explanation"}),(0,n.jsx)(s.th,{children:"Affected by Level"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Ephemeral VM"}),(0,n.jsxs)(s.td,{children:["Equals the ",(0,n.jsx)(s.code,{children:"server"})," resource in Nova, booting from ephemeral storage."]}),(0,n.jsx)(s.td,{children:"L1, L2, L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Volume-based VM"}),(0,n.jsxs)(s.td,{children:["Equals the ",(0,n.jsx)(s.code,{children:"server"})," resource in Nova, booting from a volume."]}),(0,n.jsx)(s.td,{children:"L2, L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Ephemeral Storage"}),(0,n.jsx)(s.td,{children:"Disk storage directly supplied to a virtual machine by Nova. Different from volumes."}),(0,n.jsx)(s.td,{children:"L1, L2, L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Ironic Machine"}),(0,n.jsxs)(s.td,{children:["A physical host managed by Ironic or as a ",(0,n.jsx)(s.code,{children:"server"})," resource in Nova."]}),(0,n.jsx)(s.td,{children:"L1, L2, L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"(Glance) Image"}),(0,n.jsx)(s.td,{children:"IaaS resource usually storing raw disk data. Managed by the Glance service."}),(0,n.jsx)(s.td,{children:"(L1), L2, L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"(Cinder) Volume"}),(0,n.jsx)(s.td,{children:"IaaS resource representing block storage disk that can be attached as a virtual disk to virtual machines. Managed by the Cinder service."}),(0,n.jsx)(s.td,{children:"(L1, L2), L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"(Volume) Snapshot"}),(0,n.jsx)(s.td,{children:"Thinly-provisioned copy-on-write snapshots of volumes. Stored in the same Cinder storage backend as volumes."}),(0,n.jsx)(s.td,{children:"(L1, L2), L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Volume Type"}),(0,n.jsx)(s.td,{children:"Attribute of volumes determining storage details of a volume such as backend location or whether the volume will be encrypted."}),(0,n.jsx)(s.td,{children:"L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"(Barbican) Secret"}),(0,n.jsx)(s.td,{children:"IaaS resource storing cryptographic assets such as encryption keys. Managed by the Barbican service."}),(0,n.jsx)(s.td,{children:"L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Key Encryption Key"}),(0,n.jsx)(s.td,{children:"IaaS resource, used to encrypt other keys to be able to store them encrypted in a database."}),(0,n.jsx)(s.td,{children:"L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Floating IP"}),(0,n.jsx)(s.td,{children:"IaaS resource, an IP that is usually routed and accessible from external networks."}),(0,n.jsx)(s.td,{children:"L3, L4"})]})]})]}),"\n",(0,n.jsx)(s.h4,{id:"kaas-layer-kubernetes-resources",children:"KaaS Layer (Kubernetes Resources)"}),"\n",(0,n.jsxs)(s.p,{children:["A detailed list of consequnces for certain failures can be found in the ",(0,n.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/debug/debug-cluster/",children:"Kubernetes docs"}),".\nThe following table gives an overview about certain resources on the KaaS Layer and in which failsafe classes they are affected:"]}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Resource(s)"}),(0,n.jsx)(s.th,{children:"Explanation"}),(0,n.jsx)(s.th,{children:"Affected by Level"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Pod"}),(0,n.jsx)(s.td,{children:"Kubernetes object that represents a workload to be executed, consisting of one or more containers."}),(0,n.jsx)(s.td,{children:"L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Container"}),(0,n.jsx)(s.td,{children:"A lightweight and portable executable image that contains software and all of its dependencies."}),(0,n.jsx)(s.td,{children:"L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Deployment, StatefulSet"}),(0,n.jsx)(s.td,{children:"Kubernetes objects that manage a set of Pods."}),(0,n.jsx)(s.td,{children:"L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Job"}),(0,n.jsx)(s.td,{children:"Application workload that runs once."}),(0,n.jsx)(s.td,{children:"L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"CronJob"}),(0,n.jsx)(s.td,{children:"Application workload that runs once, but repeatedly at specific intervals."}),(0,n.jsx)(s.td,{children:"L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"ConfigMap, Secret"}),(0,n.jsx)(s.td,{children:"Objects holding static application configuration data."}),(0,n.jsx)(s.td,{children:"L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Service"}),(0,n.jsx)(s.td,{children:"Makes a Pod's network service accessible inside a cluster."}),(0,n.jsx)(s.td,{children:"(L2), L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Ingress"}),(0,n.jsx)(s.td,{children:"Makes a Service externally accessible."}),(0,n.jsx)(s.td,{children:"L2, L3, L4"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"PersistentVolume (PV)"}),(0,n.jsx)(s.td,{children:"Persistent storage that can be bound and mounted to a pod."}),(0,n.jsx)(s.td,{children:"L1, L2, L3, L4"})]})]})]}),"\n",(0,n.jsxs)(s.p,{children:["Also see ",(0,n.jsx)(s.a,{href:"https://kubernetes.io/docs/reference/glossary/",children:"Kubernetes Glossary"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>d});var r=t(96540);const n={},a=r.createContext(n);function i(e){const s=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),r.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/915e2cf4.f9eacce0.js b/assets/js/915e2cf4.f9eacce0.js new file mode 100644 index 0000000000..a26647f6d3 --- /dev/null +++ b/assets/js/915e2cf4.f9eacce0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[89260],{16442:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"iaas/guides/user-guide/openstack/user-data-backups","title":"User Data Backups","description":"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.","source":"@site/docs/02-iaas/guides/user-guide/openstack/user-data-backups.md","sourceDirName":"02-iaas/guides/user-guide/openstack","slug":"/iaas/guides/user-guide/openstack/user-data-backups","permalink":"/docs/iaas/guides/user-guide/openstack/user-data-backups","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/openstack/user-data-backups.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"User Data Backups"},"sidebar":"docs","previous":{"title":"Security groups","permalink":"/docs/iaas/guides/user-guide/openstack/security-groups"},"next":{"title":"Best Practise: How to configure and use security groups","permalink":"/docs/iaas/guides/user-guide/security-groups/"}}');var t=a(74848),s=a(28453);const r={sidebar_label:"User Data Backups"},c="User Data Backups",o={},l=[{value:"Glossary",id:"glossary",level:2},{value:"Scope",id:"scope",level:2},{value:"Overview of applicable User Data",id:"overview-of-applicable-user-data",level:3},{value:"Image backup using download",id:"image-backup-using-download",level:2},{value:"Ephemeral Storage backup using Glance images",id:"ephemeral-storage-backup-using-glance-images",level:2},{value:"Volume data backup using Cinder Backup API",id:"volume-data-backup-using-cinder-backup-api",level:2},{value:"Backup of detached volumes",id:"backup-of-detached-volumes",level:3},{value:"Backup of attached volumes",id:"backup-of-attached-volumes",level:3},{value:"Volume data backup using Glance images",id:"volume-data-backup-using-glance-images",level:2},{value:"Glance image backups of detached volumes",id:"glance-image-backups-of-detached-volumes",level:3},{value:"Glance image backups of attached (in-use) volumes",id:"glance-image-backups-of-attached-in-use-volumes",level:3},{value:"Barbican secrets backup using download",id:"barbican-secrets-backup-using-download",level:2},{value:"Retrieving encryption keys from Barbican",id:"retrieving-encryption-keys-from-barbican",level:3},{value:"Restore",id:"restore",level:2},{value:"Restoring a backup of a Barbican secret",id:"restoring-a-backup-of-a-barbican-secret",level:3},{value:"Restoring a backup of an unencrypted image",id:"restoring-a-backup-of-an-unencrypted-image",level:3},{value:"Restoring a backup of an encrypted image",id:"restoring-a-backup-of-an-encrypted-image",level:3},{value:"Restoring a volume backup from an image",id:"restoring-a-volume-backup-from-an-image",level:3},{value:"Restoring a volume backup from the Cinder Backup service",id:"restoring-a-volume-backup-from-the-cinder-backup-service",level:3},{value:"Restoring to a new volume (Cinder Backup)",id:"restoring-to-a-new-volume-cinder-backup",level:4},{value:"Restoring on an existing volume (Cinder Backup)",id:"restoring-on-an-existing-volume-cinder-backup",level:4},{value:"Restoring an encrypted volume backup (Cinder Backup)",id:"restoring-an-encrypted-volume-backup-cinder-backup",level:4},{value:"Appendix",id:"appendix",level:2},{value:"Image creation action for servers with attached volumes",id:"image-creation-action-for-servers-with-attached-volumes",level:3},{value:"LUKS encryption key conversion to decrypt volume images",id:"luks-encryption-key-conversion-to-decrypt-volume-images",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"user-data-backups",children:"User Data Backups"})}),"\n",(0,t.jsx)(n.p,{children:"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks."}),"\n",(0,t.jsx)(n.h2,{id:"glossary",children:"Glossary"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Term"}),(0,t.jsx)(n.th,{children:"Explanation"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Virtual Machine"}),(0,t.jsxs)(n.td,{children:["Equals the ",(0,t.jsx)(n.code,{children:"server"})," resource in Nova."]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Ephemeral Storage"}),(0,t.jsx)(n.td,{children:"Disk storage directly supplied to a virtual machine by Nova. Different from volumes."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"(Glance) Image"}),(0,t.jsx)(n.td,{children:"IaaS resource usually storing raw disk data. Managed by the Glance service."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"(Cinder) Volume"}),(0,t.jsx)(n.td,{children:"IaaS resource representing block storage disk that can be attached as a virtual disk to virtual machines. Managed by the Cinder service."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"(Volume) Snapshot"}),(0,t.jsx)(n.td,{children:"Thinly-provisioned copy-on-write snapshots of volumes. Stored in the same Cinder storage backend as volumes."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Volume Type"}),(0,t.jsx)(n.td,{children:"Attribute of volumes determining storage details of a volume such as backend location or whether the volume will be encrypted."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"(Barbican) Secret"}),(0,t.jsx)(n.td,{children:"IaaS resource storing cryptographic assets such as encryption keys. Managed by the Barbican service."})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"scope",children:"Scope"}),"\n",(0,t.jsx)(n.p,{children:"User data in the context of this guide describes data accumulated in cloud resources of a user at runtime.\nThis concerns primarily storage data of virtual machines stored at at-rest.\nThis does not cover in-transit or in-use data such as network traffic, virtual machines' RAM contents or IaaS configuration and metadata of cloud resources."}),"\n",(0,t.jsx)(n.h3,{id:"overview-of-applicable-user-data",children:"Overview of applicable User Data"}),"\n",(0,t.jsx)(n.p,{children:"Given the mentioned scope, the following can be classified as user data:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"images stored in Glance"}),"\n",(0,t.jsxs)(n.li,{children:["virtual machine disks, either:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Ephemeral Storage stored in Nova"}),"\n",(0,t.jsx)(n.li,{children:"volumes stored in Cinder"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:"encryption keys stored as secrets in Barbican"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The following sections will describe backup procedures for each of those resources individually."}),"\n",(0,t.jsx)(n.h2,{id:"image-backup-using-download",children:"Image backup using download"}),"\n",(0,t.jsx)(n.p,{children:"Glance images may act as backup targets for other resources (such as volumes) but don't have a dedicated backup service for themselves."}),"\n",(0,t.jsx)(n.p,{children:"When an image is to be backed up, it can be downloaded from the Glance image service and stored outside of the IaaS infrastructure for backup purposes.\nIn this case it is the user's responsibility to establish the backup procedure and appropriate target storage."}),"\n",(0,t.jsxs)(n.admonition,{type:"caution",children:[(0,t.jsx)(n.p,{children:"When creating images from volumes with a volume type that uses encryption, the resulting image will contain the raw LUKS-encrypted blocks of the volume.\nWhen transferred outside of the IaaS infrastructure, this data is only useful as a backup together with the corresponding encryption key."}),(0,t.jsxs)(n.p,{children:["Such images can be identified by an attribute called ",(0,t.jsx)(n.code,{children:"cinder_encryption_key_id"})," in the ",(0,t.jsx)(n.code,{children:"properties"})," metadata field of the image.\nIt only exists for encrypted images and references the encryption key in Barbican.\nRefer to the ",(0,t.jsx)(n.a,{href:"#barbican-secrets-backup-using-download",children:"Barbican secrets section"})," for instructions on how to backup the key."]})]}),"\n",(0,t.jsx)(n.p,{children:"The API or the OpenStack client may be used to initiate the download, for example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack image save --file $TARGET_FILE_PATH $IMAGE_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.p,{children:"This or the underlying API request may be automated as part of a regular backup schedule involving the backup storage target on the user side."}),"\n",(0,t.jsx)(n.h2,{id:"ephemeral-storage-backup-using-glance-images",children:"Ephemeral Storage backup using Glance images"}),"\n",(0,t.jsxs)(n.admonition,{type:"caution",children:[(0,t.jsxs)(n.p,{children:["When using the ",(0,t.jsx)(n.code,{children:"createImage"})," Compute API action (e.g. via the ",(0,t.jsx)(n.code,{children:"openstack server image create"})," command) on a virtual machine that has volumes attached to it in addition to its Ephemeral Storage disk, the volumes will not be backed up into the image. Instead, a snapshot will be created for each attached volume and referenced in the image metadata. This does not replace genuine volume backups."]}),(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"#image-creation-action-for-servers-with-attached-volumes",children:"corresponding appendix section"})," for further details."]})]}),"\n",(0,t.jsxs)(n.p,{children:["Ephemeral Storage disks of virtual machines can be backed up to Glance images easily by using the ",(0,t.jsx)(n.code,{children:"createImage"})," Compute API action or the corresponding OpenStack client command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack server image create --name $IMAGE_NAME $SERVER_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.p,{children:"This will create a Glance image containing a one-to-one copy of the data on the Ephemeral Storage disk at the time of execution."}),"\n",(0,t.jsxs)(n.p,{children:["If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in ",(0,t.jsx)(n.a,{href:"#image-backup-using-download",children:"Image backup using download"})," may be used after the image creation."]}),"\n",(0,t.jsx)(n.h2,{id:"volume-data-backup-using-cinder-backup-api",children:"Volume data backup using Cinder Backup API"}),"\n",(0,t.jsx)(n.p,{children:"The following instructions only apply if the infrastructure offers the Cinder Backup API."}),"\n",(0,t.jsxs)(n.admonition,{type:"note",children:[(0,t.jsx)(n.p,{children:"Backups of volumes using a volume type that uses encryption will retain their encryption and a clone of the original encryption key is created in Barbican linked to the backup.\nThese backups can only be restored when the Barbican service is available and still has the corresponding copy of the encryption key."}),(0,t.jsxs)(n.p,{children:["Also, it is advised to take note of the exact volume type when creating a backup of an encrypted volume, because this information will be needed to restore the backup.\nSee ",(0,t.jsx)(n.a,{href:"#restoring-an-encrypted-volume-backup-cinder-backup",children:"restoring an encrypted volume backup"}),"."]})]}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsxs)(n.p,{children:["It might be difficult or even impossible for a user to transfer backups created by the Cinder Backup API outside of the IaaS infrastructure, depending on the backup backend.\nA more easily accessible backup of volumes can be created by using Glance images.\nSee the ",(0,t.jsx)(n.a,{href:"#volume-data-backup-using-glance-images",children:"section about volume data backup using Glance images"})," for details."]})}),"\n",(0,t.jsx)(n.h3,{id:"backup-of-detached-volumes",children:"Backup of detached volumes"}),"\n",(0,t.jsx)(n.p,{children:"Backups can be created using the Cinder Backup API or the corresponding OpenStack client commands:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create $VOLUME_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.p,{children:"Further backups of the same volume can subsequently be created as incremental backups using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create --incremental $VOLUME_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.h3,{id:"backup-of-attached-volumes",children:"Backup of attached volumes"}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"When creating backups of attached (in-use) volumes, the state of the full volume is captured at runtime. Backups created this way will be crash-consistent but not app-consistent."})}),"\n",(0,t.jsxs)(n.p,{children:["In case of attached (in-use) volumes, backups can only be created while also specfiying the ",(0,t.jsx)(n.code,{children:"force"})," parameter:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create --force $VOLUME_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.p,{children:"Further backups of the same volume can subsequently be created as incremental backups using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create --force --incremental $VOLUME_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.h2,{id:"volume-data-backup-using-glance-images",children:"Volume data backup using Glance images"}),"\n",(0,t.jsx)(n.p,{children:"In case the Cinder Backup storage is not available in the IaaS infrastructure, Glance images can be used as a backup target instead.\nSuch images may also subsequently be downloaded to transfer the backup outside of the IaaS infrastructure."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Glance image backups of Cinder volumes only allow full backup copies and do not offer incremental or differential backup mechanisms."})}),"\n",(0,t.jsx)(n.h3,{id:"glance-image-backups-of-detached-volumes",children:"Glance image backups of detached volumes"}),"\n",(0,t.jsxs)(n.p,{children:["Volumes not attached to virtual machines can be directly copied into an image.\nSuch volumes can be identified by their status being ",(0,t.jsx)(n.code,{children:"available"}),".\nTo backup a detached volume to a Glance image, directly use the corresponding image creation action:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack image create --volume $VOLUME_NAME_OR_ID $IMAGE_NAME\n"})}),"\n",(0,t.jsx)(n.p,{children:"After the image creation has finished, a full backup copy of the volume will reside in the Glance storage backend."}),"\n",(0,t.jsxs)(n.p,{children:["If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in ",(0,t.jsx)(n.a,{href:"#image-backup-using-download",children:"Image backup using download"})," may be used after the image creation."]}),"\n",(0,t.jsx)(n.h3,{id:"glance-image-backups-of-attached-in-use-volumes",children:"Glance image backups of attached (in-use) volumes"}),"\n",(0,t.jsx)(n.p,{children:"Cinder is unable to directly create Glance images from volumes which are attached to virtual machines.\nTo create backups of such volumes regardless, a detour using volume snapshots can be used which will be described below."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["When creating snapshots of attached (in-use) volumes, the ",(0,t.jsx)(n.code,{children:"force"})," parameter has to be used. These snapshots capture a state of the full volume at runtime. They will be crash-consistent but not app-consistent."]})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Create a snapshot of the target volume while including the ",(0,t.jsx)(n.code,{children:"force"})," parameter in the request:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"openstack volume snapshot create --volume $VOLUME_NAME_OR_ID $SNAPSHOT_NAME"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Create a new temporary volume based on the snapshot to act as backup source:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"openstack volume create --snapshot $SNAPSHOT_NAME $TEMP_VOLUME_NAME"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Wait until the volume creation is finished and the temporary volume reaches the ",(0,t.jsx)(n.code,{children:"available"})," status."]}),"\n",(0,t.jsxs)(n.li,{children:["Create a backup image of the temporary volume:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"openstack image create --volume $TEMP_VOLUME_NAME $IMAGE_NAME"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Wait until the image creation finishes and the target image reaches the ",(0,t.jsx)(n.code,{children:"active"})," status."]}),"\n",(0,t.jsxs)(n.li,{children:["Delete the temporary volume and snapshot:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"openstack volume delete $TEMP_VOLUME_NAME"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"openstack volume snapshot delete $SNAPSHOT_NAME"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"A full backup copy of the volume now resides in the Glance storage backend."}),"\n",(0,t.jsxs)(n.p,{children:["If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in ",(0,t.jsx)(n.a,{href:"#image-backup-using-download",children:"Image backup using download"})," may be used after the image creation."]}),"\n",(0,t.jsx)(n.h2,{id:"barbican-secrets-backup-using-download",children:"Barbican secrets backup using download"}),"\n",(0,t.jsx)(n.admonition,{type:"danger",children:(0,t.jsx)(n.p,{children:"Secrets downloaded from Barbican will be in plaintext, which means that the secret is unprotected once received from the API.\nBefore downloading secrets from Barbican make sure that a secure target environment is established for receiving and securely storing the secret's contents."})}),"\n",(0,t.jsx)(n.p,{children:"Barbican secrets can be downloaded in plaintext using the corresponding API or client command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'openstack secret get --file $TARGET_FILE_PATH --payload_content_type "application/octet-stream" $SECRET_ID\n'})}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsxs)(n.p,{children:["In case the secret needs to be restored into an OpenStack Barbican later on, it is recommended to also note down the following attributes shown by ",(0,t.jsx)(n.code,{children:"openstack secret get $SECRET_ID"}),":"]}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Algorithm"}),"\n",(0,t.jsx)(n.li,{children:"Bit length"}),"\n",(0,t.jsx)(n.li,{children:"Secret type"}),"\n",(0,t.jsx)(n.li,{children:"Mode"}),"\n"]})]}),"\n",(0,t.jsx)(n.h3,{id:"retrieving-encryption-keys-from-barbican",children:"Retrieving encryption keys from Barbican"}),"\n",(0,t.jsx)(n.p,{children:"In case of encrypted volumes (i.e. using a volume type with encryption), a corresponding encryption key is stored in Barbican.\nWhen an image is created from such a volume, the encryption key is duplicated in Barbican for the image.\nIn order to backup those keys, the corresponding secret must first be identified."}),"\n",(0,t.jsx)(n.p,{children:"For volumes, this is possible starting with the Volume API microversion 3.64:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume show --os-volume-api-version 3.64 $VOLUME_NAME_OR_ID\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The response will contain an ",(0,t.jsx)(n.code,{children:"encryption_key_id"})," field with the ID of the Barbican secret."]}),"\n",(0,t.jsxs)(n.p,{children:["For images, the secret reference is stored in the ",(0,t.jsx)(n.code,{children:"properties"})," field instead:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack image show -f value -c properties $IMAGE_NAME_OR_ID\n"})}),"\n",(0,t.jsxs)(n.p,{children:["In case of images created from encrypted volumes, the resulting output will have a nested ",(0,t.jsx)(n.code,{children:"cinder_encryption_key_id"})," field that contains the ID of the Barbican secret."]}),"\n",(0,t.jsxs)(n.p,{children:["The resulting IDs can be used to retrieve the corresponding key using the ",(0,t.jsx)(n.a,{href:"#barbican-secrets-backup-using-download",children:"Barbican instructions"})," above."]}),"\n",(0,t.jsxs)(n.admonition,{type:"caution",children:[(0,t.jsx)(n.p,{children:"Note that the key retrieved from the secret is not immediately usable as LUKS passphrase to the image data of the volume.\nOpenStack does some processing to the key before it is passed to the LUKS encryption, which must be mimicked accordingly in order to unlock the encryption outside of OpenStack!"}),(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"#luks-encryption-key-conversion-to-decrypt-volume-images",children:"example procedure for converting the LUKS key"})," in the appendix section."]})]}),"\n",(0,t.jsx)(n.h2,{id:"restore",children:"Restore"}),"\n",(0,t.jsx)(n.p,{children:"The following sections will illustrate how to restore the individual resource backups that have been documented above."}),"\n",(0,t.jsx)(n.h3,{id:"restoring-a-backup-of-a-barbican-secret",children:"Restoring a backup of a Barbican secret"}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Note that restoring a Barbican secret by re-uploading it via the Barbican API will lead to the secret receiving a new ID.\nExisting resources referencing an old secret ID cannot make use of the restored copy."})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack secret store --algorithm aes --bit-length 256 --mode cbc \\\n --secret-type symmetric --file $KEY_FILE_PATH --name $SECRET_NAME\n"})}),"\n",(0,t.jsx)(n.p,{children:"Notes:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Attributes like algorithm, bit length, mode and secret type are not verified by Barbican. Their main purpose is to classify the secret on a metadata level. Make sure to align the attributes with the original secret."}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"$KEY_FILE_PATH"})," is the local file path of the secret backup as created originally using the ",(0,t.jsx)(n.a,{href:"#barbican-secrets-backup-using-download",children:"instructions above"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"$SECRET_NAME"})," is entirely optional but helps identifying the restored secret later on and to distinguish it from secrets created by OpenStack itself. It is best to not put whitespace characters in the name, otherwise it has to be surrounded by quotes."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The successful registration of the restored secret can subsequently be verified using:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack secret list --name $SECRET_NAME\n"})}),"\n",(0,t.jsx)(n.h3,{id:"restoring-a-backup-of-an-unencrypted-image",children:"Restoring a backup of an unencrypted image"}),"\n",(0,t.jsx)(n.p,{children:"Unencrypted image backups can simply be restored using the regular image upload functionality and specifying the backup file:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack image create --file $IMAGE_FILE_PATH $IMAGE_NAME\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["In case the original image backup was not based on a volume originally, the image may have had a non-default disk or container format.\nIn this case, add the command parameters ",(0,t.jsx)(n.code,{children:"--container-format"})," and ",(0,t.jsx)(n.code,{children:"--disk-format"})," to the command accordingly."]})}),"\n",(0,t.jsx)(n.h3,{id:"restoring-a-backup-of-an-encrypted-image",children:"Restoring a backup of an encrypted image"}),"\n",(0,t.jsx)(n.p,{children:"The following section only applies to image backups that were originally created from images of encrypted volumes."}),"\n",(0,t.jsxs)(n.p,{children:["First, restore the corresponding secret of the image using the ",(0,t.jsx)(n.a,{href:"#restoring-a-backup-of-a-barbican-secret",children:"instructions above"}),".\nThe restored secret will receive a new ID in the form of a ",(0,t.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Universally_unique_identifier",children:"UUID"}),".\nNote down the ID of the restored secret and insert it in place of ",(0,t.jsx)(n.code,{children:"$SECRET_ID"})," in the command below."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack image create --file $IMAGE_FILE_PATH \\\n --property cinder_encryption_key_id=$SECRET_ID \\\n --property cinder_encryption_key_deletion_policy=on_image_deletion \\\n $IMAGE_NAME\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"cinder_encryption_key_deletion_policy"})," attribute is optional.\nIf not specified, the referenced secret will not be deleted on image deletion automatically.\nIn contrast, if set to ",(0,t.jsx)(n.code,{children:"on_image_deletion"}),", the referenced secret will be deleted as soon as the image referencing it is deleted."]}),"\n",(0,t.jsx)(n.h3,{id:"restoring-a-volume-backup-from-an-image",children:"Restoring a volume backup from an image"}),"\n",(0,t.jsx)(n.p,{children:"To restore a volume from an image backup, simply use the volume creation action and specify the image as source."}),"\n",(0,t.jsxs)(n.p,{children:["Depending on whether the original volume the image was created from was encrypted or not, the target volume type might need to be specified accordingly.\nWhether this is the case can be identified by inspecting the image's metadata using ",(0,t.jsx)(n.code,{children:"openstack image show $IMAGE_NAME_OR_ID"}),' and looking for a "cinder_encryption_key_id" field within "properties".\nIf it exists, the source volume of the image was encrypted.']}),"\n",(0,t.jsx)(n.p,{children:"To restore the image of an unencrypted volume:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume create --image $IMAGE_NAME_OR_ID \\\n --size $VOLUME_SIZE_IN_GB $VOLUME_NAME\n"})}),"\n",(0,t.jsx)(n.p,{children:"To restore the image of an encrypted volume:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume create --image $IMAGE_NAME_OR_ID \\\n --type $ENCRYPTED_VOLUME_TYPE \\\n --size $VOLUME_SIZE_IN_GB $VOLUME_NAME\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If restoring an encrypted image, make sure to specify ",(0,t.jsx)(n.code,{children:"$ENCRYPTED_VOLUME_TYPE"})," correctly and have it reference a volume type which also supports the encryption.\nOtherwise the volume will be unbootable or unusable by Nova instances."]}),"\n",(0,t.jsx)(n.h3,{id:"restoring-a-volume-backup-from-the-cinder-backup-service",children:"Restoring a volume backup from the Cinder Backup service"}),"\n",(0,t.jsx)(n.p,{children:"The Cinder Backup service offers dedicated API actions and commands for restoring volume backups created using the service.\nThese backups can be restored in one of two ways:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Letting the Cinder Backup service create a new volume based on the backup."}),"\n",(0,t.jsx)(n.li,{children:"Overwriting an existing volume with the backup data."}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["If the volume backup was originally created from a volume that used a non-default encrypted volume type, letting Cinder Backup create a new volume for backup restoration does not work and the volume type must match exactly.\nIn such case provision an empty volume with the correct type first and then restore the backup onto it ",(0,t.jsx)(n.a,{href:"#restoring-an-encrypted-volume-backup-cinder-backup",children:"as explained further down"}),"."]})}),"\n",(0,t.jsx)(n.h4,{id:"restoring-to-a-new-volume-cinder-backup",children:"Restoring to a new volume (Cinder Backup)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup restore $BACKUP_NAME_OR_ID $TARGET_NAME\n"})}),"\n",(0,t.jsxs)(n.p,{children:["... where ",(0,t.jsx)(n.code,{children:"$TARGET_NAME"})," is the desired name of the new volume to be created.\nMake sure that no volume with this name already exists.\nThe Cinder Backup service will create the volume with the same size as the backup indicates."]}),"\n",(0,t.jsx)(n.h4,{id:"restoring-on-an-existing-volume-cinder-backup",children:"Restoring on an existing volume (Cinder Backup)"}),"\n",(0,t.jsx)(n.p,{children:"As an alternative to creating a new volume as the restore target, the backup can also be restored on an existing volume:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup restore --force $BACKUP_NAME_OR_ID $VOLUME_NAME_OR_ID\n"})}),"\n",(0,t.jsx)(n.p,{children:"... which will overwrite the data on the existing volume, regardless of whether it is empty or not!"}),"\n",(0,t.jsx)(n.p,{children:'The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.'}),"\n",(0,t.jsx)(n.h4,{id:"restoring-an-encrypted-volume-backup-cinder-backup",children:"Restoring an encrypted volume backup (Cinder Backup)"}),"\n",(0,t.jsx)(n.p,{children:'When restoring a volume backup of a volume that was using a non-default encrypted volume type, a new volume of that type needs to be created first and then the backup restored onto it.\nOtherwise, the restoration will fail with the target volume ending up in the "error_restoring" state.\nFor this procedure to succeed it is necessary to know the exact volume type of the volume the backup was created from.'}),"\n",(0,t.jsxs)(n.p,{children:["If the source volume of the backup still exists, the original volume type can be determined by inspecting the backup's ",(0,t.jsx)(n.code,{children:"volume_id"})," attribute and then using it to look up the corresponding volume and its ",(0,t.jsx)(n.code,{children:"type"})," attribute.\nThe following client command can be used for this (fill in the value for ",(0,t.jsx)(n.code,{children:"BACKUP_ID"}),"):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'export BACKUP_ID=...\n\nSOURCE_VOLUME_ID="$(openstack volume backup show $BACKUP_ID -f value -c volume_id)"\nopenstack volume show -f value -c type "$SOURCE_VOLUME_ID"\n'})}),"\n",(0,t.jsx)(n.p,{children:"This returns the name of the original volume type.\nIf the source volume does not exist anymore, rely on documentation about the backup to determine the type, if available."}),"\n",(0,t.jsxs)(n.p,{children:["First, create a new empty volume as the restore target and use the backup's ",(0,t.jsx)(n.code,{children:"size"})," metadata attribute to match the size of the volume to the backup:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume create --size $BACKUP_SIZE --type $VOLUME_TYPE $TARGET_NAME\n"})}),"\n",(0,t.jsxs)(n.p,{children:["... where ",(0,t.jsx)(n.code,{children:"$TARGET_NAME"})," is the desired name of the new volume."]}),"\n",(0,t.jsx)(n.p,{children:'Once the volume reaches "available" state, restore the backup onto it:'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack volume backup restore --force $BACKUP_NAME_OR_ID $TARGET_NAME\n"})}),"\n",(0,t.jsx)(n.p,{children:'The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.'}),"\n",(0,t.jsx)(n.h2,{id:"appendix",children:"Appendix"}),"\n",(0,t.jsx)(n.h3,{id:"image-creation-action-for-servers-with-attached-volumes",children:"Image creation action for servers with attached volumes"}),"\n",(0,t.jsxs)(n.p,{children:["When the ",(0,t.jsx)(n.code,{children:"createImage"})," action of the Compute API (",(0,t.jsx)(n.code,{children:"openstack server image create"}),") is used on virtual machines that have at least one volume attached, a snapshot will be created for each attached volume individually and referenced in the resulting image's metadata."]}),"\n",(0,t.jsx)(n.p,{children:"This happens regardless of whether the virtual machine has an Ephemeral Storage disk attached.\nIn case of an Ephemeral Storage disk, only the Ephemeral Storage is copied into the Glance image as a 1:1 copy."}),"\n",(0,t.jsxs)(n.p,{children:["In case of a virtual machine that has no Ephemeral Storage but only volumes, the ",(0,t.jsx)(n.code,{children:"createImage"})," action leads to a Glance image that only consists of metadata (including the resulting volume snapshot references) but carries no actual binary data."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Figure: createImage action flow involving Ephemeral Storage and/or volumes",src:a(41131).A+"",width:"1342",height:"1202"})}),"\n",(0,t.jsx)(n.h3,{id:"luks-encryption-key-conversion-to-decrypt-volume-images",children:"LUKS encryption key conversion to decrypt volume images"}),"\n",(0,t.jsx)(n.p,{children:"The volume encryption keys stored in Barbican are not directly used as LUKS passphrases by OpenStack because they are in binary format.\nOpenStack converts them to ASCII internally before passing them to the encryption layer.\nThis behavior needs to be reproduced if a decryption of a volume image is desired outside of OpenStack."}),"\n",(0,t.jsx)(n.admonition,{type:"danger",children:(0,t.jsx)(n.p,{children:"The instructions below will expose plaintext data of encryption keys and encrypted volume images.\nMake sure to only execute these steps in a secure and trusted environment."})}),"\n",(0,t.jsx)(n.p,{children:"First, download the image:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack image save --file image.raw $IMAGE_NAME_OR_ID\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Next, inspect the image metadata, determine the reference to the encryption key (",(0,t.jsx)(n.code,{children:"cinder_encryption_key_id"})," property) and download the encryption key:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'openstack image show -f value -c properties $IMAGE_NAME_OR_ID\n# (use the value of `cinder_encryption_key_id` as `$SECRET_ID` below)\nopenstack secret get --file image.key --payload_content_type "application/octet-stream" $SECRET_ID\n'})}),"\n",(0,t.jsx)(n.p,{children:"This will result in the following local files:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"image.raw"})," = the raw encrypted image downloaded from Glance"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"image.key"})," = the LUKS encryption key in binary format (plaintext)"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Since OpenStack internally uses Python's ",(0,t.jsx)(n.code,{children:"binascii.hexlify()"})," to convert the binary encryption key before passing it as a passphrase to the LUKS encryption, as a last step this conversion must be mimicked to unlock the encryption:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"python3 -c \"import binascii; \\\n f = open('image.key', 'rb'); \\\n print(binascii.hexlify(f.read()).decode('utf-8'))\" \\\n | sudo cryptsetup luksOpen ./image.raw decrypted_image\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The decrypted image is now accessible at ",(0,t.jsx)(n.code,{children:"/dev/mapper/decrypted_image"}),".\nNote that this is a live en-/decryption operation on the ",(0,t.jsx)(n.code,{children:"image.raw"})," file.\nThe image is not converted, the encryption is simply unlocked in-memory using LUKS and dm-crypt until the encryption is closed again."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"/dev/mapper/decrypted_image"})," can now be handled like a raw block device (e.g. mounted as a filesystem) or snapshotted in decrypted form."]}),"\n",(0,t.jsx)(n.p,{children:"To close the encryption execute:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo cryptsetup luksClose decrypted_image\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsxs)(n.em,{children:["The source of this document can be found in the ",(0,t.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/docs/main/docs/02-iaas/guides/user-guide/user-data-backups.md",children:"SovereignCloudStack/docs"})," repository."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.em,{children:"Author: SCS Community, License: CC by Attribution 4.0 International"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},41131:(e,n,a)=>{a.d(n,{A:()=>i});const i=a.p+"assets/images/user_data_backups_figure1-988dbd55659509cc1ddc9f68f2437648.png"},28453:(e,n,a)=>{a.d(n,{R:()=>r,x:()=>c});var i=a(96540);const t={},s=i.createContext(t);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/926668e5.2343e730.js b/assets/js/926668e5.2343e730.js new file mode 100644 index 0000000000..0ea1957451 --- /dev/null +++ b/assets/js/926668e5.2343e730.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[91770],{99747:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>d,default:()=>h,frontMatter:()=>c,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"iaas/scs-0119","title":"scs-0119: Replacement of the deprecated ceph-ansible tool","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0119.md","sourceDirName":"iaas","slug":"/iaas/scs-0119","permalink":"/standards/iaas/scs-0119","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0118-w1-example-impacts-of-failure-scenarios"},"next":{"title":"V1","permalink":"/standards/scs-0119-v1-rook-decision"}}');var r=s(74848),a=s(28453);const c={},d="scs-0119: Replacement of the deprecated ceph-ansible tool",i={},o=[];function l(e){const t={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0119-replacement-of-the-deprecated-ceph-ansible-tool",children:"scs-0119: Replacement of the deprecated ceph-ansible tool"})}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0119-v1-rook-decision",children:"scs-0119-v1"})}),(0,r.jsx)(t.td,{children:"Decision Record"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>d});var n=s(96540);const r={},a=n.createContext(r);function c(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/92704.fd1e7d31.js b/assets/js/92704.fd1e7d31.js new file mode 100644 index 0000000000..89ad45d6af --- /dev/null +++ b/assets/js/92704.fd1e7d31.js @@ -0,0 +1,2 @@ +/*! For license information please see 92704.fd1e7d31.js.LICENSE.txt */ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[92704],{87799:function(e,t,n){var r;r=function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=7)}([function(t,n){t.exports=e},function(e,t,n){"use strict";var r=n(0).FDLayoutConstants;function i(){}for(var a in r)i[a]=r[a];i.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,i.DEFAULT_RADIAL_SEPARATION=r.DEFAULT_EDGE_LENGTH,i.DEFAULT_COMPONENT_SEPERATION=60,i.TILE=!0,i.TILING_PADDING_VERTICAL=10,i.TILING_PADDING_HORIZONTAL=10,i.TREE_REDUCTION_ON_INCREMENTAL=!1,e.exports=i},function(e,t,n){"use strict";var r=n(0).FDLayoutEdge;function i(e,t,n){r.call(this,e,t,n)}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];e.exports=i},function(e,t,n){"use strict";var r=n(0).LGraph;function i(e,t,n){r.call(this,e,t,n)}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];e.exports=i},function(e,t,n){"use strict";var r=n(0).LGraphManager;function i(e){r.call(this,e)}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];e.exports=i},function(e,t,n){"use strict";var r=n(0).FDLayoutNode,i=n(0).IMath;function a(e,t,n,i){r.call(this,e,t,n,i)}for(var o in a.prototype=Object.create(r.prototype),r)a[o]=r[o];a.prototype.move=function(){var e=this.graphManager.getLayout();this.displacementX=e.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY=e.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren,Math.abs(this.displacementX)>e.coolingFactor*e.maxNodeDisplacement&&(this.displacementX=e.coolingFactor*e.maxNodeDisplacement*i.sign(this.displacementX)),Math.abs(this.displacementY)>e.coolingFactor*e.maxNodeDisplacement&&(this.displacementY=e.coolingFactor*e.maxNodeDisplacement*i.sign(this.displacementY)),null==this.child||0==this.child.getNodes().length?this.moveBy(this.displacementX,this.displacementY):this.propogateDisplacementToChildren(this.displacementX,this.displacementY),e.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},a.prototype.propogateDisplacementToChildren=function(e,t){for(var n,r=this.getChild().getNodes(),i=0;i<r.length;i++)null==(n=r[i]).getChild()?(n.moveBy(e,t),n.displacementX+=e,n.displacementY+=t):n.propogateDisplacementToChildren(e,t)},a.prototype.setPred1=function(e){this.pred1=e},a.prototype.getPred1=function(){return pred1},a.prototype.getPred2=function(){return pred2},a.prototype.setNext=function(e){this.next=e},a.prototype.getNext=function(){return next},a.prototype.setProcessed=function(e){this.processed=e},a.prototype.isProcessed=function(){return processed},e.exports=a},function(e,t,n){"use strict";var r=n(0).FDLayout,i=n(4),a=n(3),o=n(5),s=n(2),l=n(1),u=n(0).FDLayoutConstants,c=n(0).LayoutConstants,h=n(0).Point,d=n(0).PointD,p=n(0).Layout,g=n(0).Integer,f=n(0).IGeometry,v=n(0).LGraph,y=n(0).Transform;function m(){r.call(this),this.toBeTiled={}}for(var b in m.prototype=Object.create(r.prototype),r)m[b]=r[b];m.prototype.newGraphManager=function(){var e=new i(this);return this.graphManager=e,e},m.prototype.newGraph=function(e){return new a(null,this.graphManager,e)},m.prototype.newNode=function(e){return new o(this.graphManager,e)},m.prototype.newEdge=function(e){return new s(null,null,e)},m.prototype.initParameters=function(){r.prototype.initParameters.call(this,arguments),this.isSubLayout||(l.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=l.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=l.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.springConstant=u.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=u.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=u.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=u.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=u.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=u.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1,this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/u.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=u.CONVERGENCE_CHECK_PERIOD/this.maxIterations,this.coolingAdjuster=1)},m.prototype.layout=function(){return c.DEFAULT_CREATE_BENDS_AS_NEEDED&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},m.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental)l.TREE_REDUCTION_ON_INCREMENTAL&&(this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation(),t=new Set(this.getAllNodes()),n=this.nodesWithGravity.filter((function(e){return t.has(e)})),this.graphManager.setAllNodesToApplyGravitation(n));else{var e=this.getFlatForest();if(e.length>0)this.positionNodesRadially(e);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var t=new Set(this.getAllNodes()),n=this.nodesWithGravity.filter((function(e){return t.has(e)}));this.graphManager.setAllNodesToApplyGravitation(n),this.positionNodesRandomly()}}return this.initSpringEmbedder(),this.runSpringEmbedder(),!0},m.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}if(this.totalIterations%u.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged()){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}this.coolingCycle++,0==this.layoutQuality?this.coolingAdjuster=this.coolingCycle:1==this.layoutQuality&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var e=new Set(this.getAllNodes()),t=this.nodesWithGravity.filter((function(t){return e.has(t)}));this.graphManager.setAllNodesToApplyGravitation(t),this.graphManager.updateBounds(),this.updateGrid(),this.coolingFactor=u.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),this.coolingFactor=u.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var n=!this.isTreeGrowing&&!this.isGrowthFinished,r=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(n,r),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},m.prototype.getPositionsData=function(){for(var e=this.graphManager.getAllNodes(),t={},n=0;n<e.length;n++){var r=e[n].rect,i=e[n].id;t[i]={id:i,x:r.getCenterX(),y:r.getCenterY(),w:r.width,h:r.height}}return t},m.prototype.runSpringEmbedder=function(){this.initialAnimationPeriod=25,this.animationPeriod=this.initialAnimationPeriod;var e=!1;if("during"===u.ANIMATE)this.emit("layoutstarted");else{for(;!e;)e=this.tick();this.graphManager.updateBounds()}},m.prototype.calculateNodesToApplyGravitationTo=function(){var e,t,n=[],r=this.graphManager.getGraphs(),i=r.length;for(t=0;t<i;t++)(e=r[t]).updateConnected(),e.isConnected||(n=n.concat(e.getNodes()));return n},m.prototype.createBendpoints=function(){var e=[];e=e.concat(this.graphManager.getAllEdges());var t,n=new Set;for(t=0;t<e.length;t++){var r=e[t];if(!n.has(r)){var i=r.getSource(),a=r.getTarget();if(i==a)r.getBendpoints().push(new d),r.getBendpoints().push(new d),this.createDummyNodesForBendpoints(r),n.add(r);else{var o=[];if(o=(o=o.concat(i.getEdgeListToNode(a))).concat(a.getEdgeListToNode(i)),!n.has(o[0])){var s;if(o.length>1)for(s=0;s<o.length;s++){var l=o[s];l.getBendpoints().push(new d),this.createDummyNodesForBendpoints(l)}o.forEach((function(e){n.add(e)}))}}}if(n.size==e.length)break}},m.prototype.positionNodesRadially=function(e){for(var t=new h(0,0),n=Math.ceil(Math.sqrt(e.length)),r=0,i=0,a=0,o=new d(0,0),s=0;s<e.length;s++){s%n==0&&(a=0,i=r,0!=s&&(i+=l.DEFAULT_COMPONENT_SEPERATION),r=0);var u=e[s],g=p.findCenterOfTree(u);t.x=a,t.y=i,(o=m.radialLayout(u,g,t)).y>r&&(r=Math.floor(o.y)),a=Math.floor(o.x+l.DEFAULT_COMPONENT_SEPERATION)}this.transform(new d(c.WORLD_CENTER_X-o.x/2,c.WORLD_CENTER_Y-o.y/2))},m.radialLayout=function(e,t,n){var r=Math.max(this.maxDiagonalInTree(e),l.DEFAULT_RADIAL_SEPARATION);m.branchRadialLayout(t,null,0,359,0,r);var i=v.calculateBounds(e),a=new y;a.setDeviceOrgX(i.getMinX()),a.setDeviceOrgY(i.getMinY()),a.setWorldOrgX(n.x),a.setWorldOrgY(n.y);for(var o=0;o<e.length;o++)e[o].transform(a);var s=new d(i.getMaxX(),i.getMaxY());return a.inverseTransformPoint(s)},m.branchRadialLayout=function(e,t,n,r,i,a){var o=(r-n+1)/2;o<0&&(o+=180);var s=(o+n)%360*f.TWO_PI/360,l=(Math.cos(s),i*Math.cos(s)),u=i*Math.sin(s);e.setCenter(l,u);var c=[],h=(c=c.concat(e.getEdges())).length;null!=t&&h--;for(var d,p=0,g=c.length,v=e.getEdgesBetween(t);v.length>1;){var y=v[0];v.splice(0,1);var b=c.indexOf(y);b>=0&&c.splice(b,1),g--,h--}d=null!=t?(c.indexOf(v[0])+1)%g:0;for(var x=Math.abs(r-n)/h,w=d;p!=h;w=++w%g){var E=c[w].getOtherEnd(e);if(E!=t){var _=(n+p*x)%360,T=(_+x)%360;m.branchRadialLayout(E,e,_,T,i+a,a),p++}}},m.maxDiagonalInTree=function(e){for(var t=g.MIN_VALUE,n=0;n<e.length;n++){var r=e[n].getDiagonal();r>t&&(t=r)}return t},m.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},m.prototype.groupZeroDegreeMembers=function(){var e=this,t={};this.memberGroups={},this.idToDummyNode={};for(var n=[],r=this.graphManager.getAllNodes(),i=0;i<r.length;i++){var a=(s=r[i]).getParent();0!==this.getNodeDegreeWithChildren(s)||null!=a.id&&this.getToBeTiled(a)||n.push(s)}for(i=0;i<n.length;i++){var s,l=(s=n[i]).getParent().id;void 0===t[l]&&(t[l]=[]),t[l]=t[l].concat(s)}Object.keys(t).forEach((function(n){if(t[n].length>1){var r="DummyCompound_"+n;e.memberGroups[r]=t[n];var i=t[n][0].getParent(),a=new o(e.graphManager);a.id=r,a.paddingLeft=i.paddingLeft||0,a.paddingRight=i.paddingRight||0,a.paddingBottom=i.paddingBottom||0,a.paddingTop=i.paddingTop||0,e.idToDummyNode[r]=a;var s=e.getGraphManager().add(e.newGraph(),a),l=i.getChild();l.add(a);for(var u=0;u<t[n].length;u++){var c=t[n][u];l.remove(c),s.add(c)}}}))},m.prototype.clearCompounds=function(){var e={},t={};this.performDFSOnCompounds();for(var n=0;n<this.compoundOrder.length;n++)t[this.compoundOrder[n].id]=this.compoundOrder[n],e[this.compoundOrder[n].id]=[].concat(this.compoundOrder[n].getChild().getNodes()),this.graphManager.remove(this.compoundOrder[n].getChild()),this.compoundOrder[n].child=null;this.graphManager.resetAllNodes(),this.tileCompoundMembers(e,t)},m.prototype.clearZeroDegreeMembers=function(){var e=this,t=this.tiledZeroDegreePack=[];Object.keys(this.memberGroups).forEach((function(n){var r=e.idToDummyNode[n];t[n]=e.tileNodes(e.memberGroups[n],r.paddingLeft+r.paddingRight),r.rect.width=t[n].width,r.rect.height=t[n].height}))},m.prototype.repopulateCompounds=function(){for(var e=this.compoundOrder.length-1;e>=0;e--){var t=this.compoundOrder[e],n=t.id,r=t.paddingLeft,i=t.paddingTop;this.adjustLocations(this.tiledMemberPack[n],t.rect.x,t.rect.y,r,i)}},m.prototype.repopulateZeroDegreeMembers=function(){var e=this,t=this.tiledZeroDegreePack;Object.keys(t).forEach((function(n){var r=e.idToDummyNode[n],i=r.paddingLeft,a=r.paddingTop;e.adjustLocations(t[n],r.rect.x,r.rect.y,i,a)}))},m.prototype.getToBeTiled=function(e){var t=e.id;if(null!=this.toBeTiled[t])return this.toBeTiled[t];var n=e.getChild();if(null==n)return this.toBeTiled[t]=!1,!1;for(var r=n.getNodes(),i=0;i<r.length;i++){var a=r[i];if(this.getNodeDegree(a)>0)return this.toBeTiled[t]=!1,!1;if(null!=a.getChild()){if(!this.getToBeTiled(a))return this.toBeTiled[t]=!1,!1}else this.toBeTiled[a.id]=!1}return this.toBeTiled[t]=!0,!0},m.prototype.getNodeDegree=function(e){e.id;for(var t=e.getEdges(),n=0,r=0;r<t.length;r++){var i=t[r];i.getSource().id!==i.getTarget().id&&(n+=1)}return n},m.prototype.getNodeDegreeWithChildren=function(e){var t=this.getNodeDegree(e);if(null==e.getChild())return t;for(var n=e.getChild().getNodes(),r=0;r<n.length;r++){var i=n[r];t+=this.getNodeDegreeWithChildren(i)}return t},m.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},m.prototype.fillCompexOrderByDFS=function(e){for(var t=0;t<e.length;t++){var n=e[t];null!=n.getChild()&&this.fillCompexOrderByDFS(n.getChild().getNodes()),this.getToBeTiled(n)&&this.compoundOrder.push(n)}},m.prototype.adjustLocations=function(e,t,n,r,i){n+=i;for(var a=t+=r,o=0;o<e.rows.length;o++){var s=e.rows[o];t=a;for(var l=0,u=0;u<s.length;u++){var c=s[u];c.rect.x=t,c.rect.y=n,t+=c.rect.width+e.horizontalPadding,c.rect.height>l&&(l=c.rect.height)}n+=l+e.verticalPadding}},m.prototype.tileCompoundMembers=function(e,t){var n=this;this.tiledMemberPack=[],Object.keys(e).forEach((function(r){var i=t[r];n.tiledMemberPack[r]=n.tileNodes(e[r],i.paddingLeft+i.paddingRight),i.rect.width=n.tiledMemberPack[r].width,i.rect.height=n.tiledMemberPack[r].height}))},m.prototype.tileNodes=function(e,t){var n={rows:[],rowWidth:[],rowHeight:[],width:0,height:t,verticalPadding:l.TILING_PADDING_VERTICAL,horizontalPadding:l.TILING_PADDING_HORIZONTAL};e.sort((function(e,t){return e.rect.width*e.rect.height>t.rect.width*t.rect.height?-1:e.rect.width*e.rect.height<t.rect.width*t.rect.height?1:0}));for(var r=0;r<e.length;r++){var i=e[r];0==n.rows.length?this.insertNodeToRow(n,i,0,t):this.canAddHorizontal(n,i.rect.width,i.rect.height)?this.insertNodeToRow(n,i,this.getShortestRowIndex(n),t):this.insertNodeToRow(n,i,n.rows.length,t),this.shiftToLastRow(n)}return n},m.prototype.insertNodeToRow=function(e,t,n,r){var i=r;n==e.rows.length&&(e.rows.push([]),e.rowWidth.push(i),e.rowHeight.push(0));var a=e.rowWidth[n]+t.rect.width;e.rows[n].length>0&&(a+=e.horizontalPadding),e.rowWidth[n]=a,e.width<a&&(e.width=a);var o=t.rect.height;n>0&&(o+=e.verticalPadding);var s=0;o>e.rowHeight[n]&&(s=e.rowHeight[n],e.rowHeight[n]=o,s=e.rowHeight[n]-s),e.height+=s,e.rows[n].push(t)},m.prototype.getShortestRowIndex=function(e){for(var t=-1,n=Number.MAX_VALUE,r=0;r<e.rows.length;r++)e.rowWidth[r]<n&&(t=r,n=e.rowWidth[r]);return t},m.prototype.getLongestRowIndex=function(e){for(var t=-1,n=Number.MIN_VALUE,r=0;r<e.rows.length;r++)e.rowWidth[r]>n&&(t=r,n=e.rowWidth[r]);return t},m.prototype.canAddHorizontal=function(e,t,n){var r=this.getShortestRowIndex(e);if(r<0)return!0;var i=e.rowWidth[r];if(i+e.horizontalPadding+t<=e.width)return!0;var a,o,s=0;return e.rowHeight[r]<n&&r>0&&(s=n+e.verticalPadding-e.rowHeight[r]),a=e.width-i>=t+e.horizontalPadding?(e.height+s)/(i+t+e.horizontalPadding):(e.height+s)/e.width,s=n+e.verticalPadding,(o=e.width<t?(e.height+s)/t:(e.height+s)/e.width)<1&&(o=1/o),a<1&&(a=1/a),a<o},m.prototype.shiftToLastRow=function(e){var t=this.getLongestRowIndex(e),n=e.rowWidth.length-1,r=e.rows[t],i=r[r.length-1],a=i.width+e.horizontalPadding;if(e.width-e.rowWidth[n]>a&&t!=n){r.splice(-1,1),e.rows[n].push(i),e.rowWidth[t]=e.rowWidth[t]-a,e.rowWidth[n]=e.rowWidth[n]+a,e.width=e.rowWidth[instance.getLongestRowIndex(e)];for(var o=Number.MIN_VALUE,s=0;s<r.length;s++)r[s].height>o&&(o=r[s].height);t>0&&(o+=e.verticalPadding);var l=e.rowHeight[t]+e.rowHeight[n];e.rowHeight[t]=o,e.rowHeight[n]<i.height+e.verticalPadding&&(e.rowHeight[n]=i.height+e.verticalPadding);var u=e.rowHeight[t]+e.rowHeight[n];e.height+=u-l,this.shiftToLastRow(e)}},m.prototype.tilingPreLayout=function(){l.TILE&&(this.groupZeroDegreeMembers(),this.clearCompounds(),this.clearZeroDegreeMembers())},m.prototype.tilingPostLayout=function(){l.TILE&&(this.repopulateZeroDegreeMembers(),this.repopulateCompounds())},m.prototype.reduceTrees=function(){for(var e,t=[],n=!0;n;){var r=this.graphManager.getAllNodes(),i=[];n=!1;for(var a=0;a<r.length;a++)1!=(e=r[a]).getEdges().length||e.getEdges()[0].isInterGraph||null!=e.getChild()||(i.push([e,e.getEdges()[0],e.getOwner()]),n=!0);if(1==n){for(var o=[],s=0;s<i.length;s++)1==i[s][0].getEdges().length&&(o.push(i[s]),i[s][0].getOwner().remove(i[s][0]));t.push(o),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()}}this.prunedNodesAll=t},m.prototype.growTree=function(e){for(var t,n=e[e.length-1],r=0;r<n.length;r++)t=n[r],this.findPlaceforPrunedNode(t),t[2].add(t[0]),t[2].add(t[1],t[1].source,t[1].target);e.splice(e.length-1,1),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()},m.prototype.findPlaceforPrunedNode=function(e){var t,n,r=e[0],i=(n=r==e[1].source?e[1].target:e[1].source).startX,a=n.finishX,o=n.startY,s=n.finishY,l=[0,0,0,0];if(o>0)for(var c=i;c<=a;c++)l[0]+=this.grid[c][o-1].length+this.grid[c][o].length-1;if(a<this.grid.length-1)for(c=o;c<=s;c++)l[1]+=this.grid[a+1][c].length+this.grid[a][c].length-1;if(s<this.grid[0].length-1)for(c=i;c<=a;c++)l[2]+=this.grid[c][s+1].length+this.grid[c][s].length-1;if(i>0)for(c=o;c<=s;c++)l[3]+=this.grid[i-1][c].length+this.grid[i][c].length-1;for(var h,d,p=g.MAX_VALUE,f=0;f<l.length;f++)l[f]<p?(p=l[f],h=1,d=f):l[f]==p&&h++;if(3==h&&0==p)0==l[0]&&0==l[1]&&0==l[2]?t=1:0==l[0]&&0==l[1]&&0==l[3]?t=0:0==l[0]&&0==l[2]&&0==l[3]?t=3:0==l[1]&&0==l[2]&&0==l[3]&&(t=2);else if(2==h&&0==p){var v=Math.floor(2*Math.random());t=0==l[0]&&0==l[1]?0==v?0:1:0==l[0]&&0==l[2]?0==v?0:2:0==l[0]&&0==l[3]?0==v?0:3:0==l[1]&&0==l[2]?0==v?1:2:0==l[1]&&0==l[3]?0==v?1:3:0==v?2:3}else t=4==h&&0==p?v=Math.floor(4*Math.random()):d;0==t?r.setCenter(n.getCenterX(),n.getCenterY()-n.getHeight()/2-u.DEFAULT_EDGE_LENGTH-r.getHeight()/2):1==t?r.setCenter(n.getCenterX()+n.getWidth()/2+u.DEFAULT_EDGE_LENGTH+r.getWidth()/2,n.getCenterY()):2==t?r.setCenter(n.getCenterX(),n.getCenterY()+n.getHeight()/2+u.DEFAULT_EDGE_LENGTH+r.getHeight()/2):r.setCenter(n.getCenterX()-n.getWidth()/2-u.DEFAULT_EDGE_LENGTH-r.getWidth()/2,n.getCenterY())},e.exports=m},function(e,t,n){"use strict";var r={};r.layoutBase=n(0),r.CoSEConstants=n(1),r.CoSEEdge=n(2),r.CoSEGraph=n(3),r.CoSEGraphManager=n(4),r.CoSELayout=n(6),r.CoSENode=n(5),e.exports=r}])},e.exports=r(n(23143))},43457:function(e,t,n){var r;r=function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(t,n){t.exports=e},function(e,t,n){"use strict";var r=n(0).layoutBase.LayoutConstants,i=n(0).layoutBase.FDLayoutConstants,a=n(0).CoSEConstants,o=n(0).CoSELayout,s=n(0).CoSENode,l=n(0).layoutBase.PointD,u=n(0).layoutBase.DimensionD,c={ready:function(){},stop:function(){},quality:"default",nodeDimensionsIncludeLabels:!1,refresh:30,fit:!0,padding:10,randomize:!0,nodeRepulsion:4500,idealEdgeLength:50,edgeElasticity:.45,nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,animate:"end",animationDuration:500,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.5};function h(e){this.options=function(e,t){var n={};for(var r in e)n[r]=e[r];for(var r in t)n[r]=t[r];return n}(c,e),d(this.options)}var d=function(e){null!=e.nodeRepulsion&&(a.DEFAULT_REPULSION_STRENGTH=i.DEFAULT_REPULSION_STRENGTH=e.nodeRepulsion),null!=e.idealEdgeLength&&(a.DEFAULT_EDGE_LENGTH=i.DEFAULT_EDGE_LENGTH=e.idealEdgeLength),null!=e.edgeElasticity&&(a.DEFAULT_SPRING_STRENGTH=i.DEFAULT_SPRING_STRENGTH=e.edgeElasticity),null!=e.nestingFactor&&(a.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=e.nestingFactor),null!=e.gravity&&(a.DEFAULT_GRAVITY_STRENGTH=i.DEFAULT_GRAVITY_STRENGTH=e.gravity),null!=e.numIter&&(a.MAX_ITERATIONS=i.MAX_ITERATIONS=e.numIter),null!=e.gravityRange&&(a.DEFAULT_GRAVITY_RANGE_FACTOR=i.DEFAULT_GRAVITY_RANGE_FACTOR=e.gravityRange),null!=e.gravityCompound&&(a.DEFAULT_COMPOUND_GRAVITY_STRENGTH=i.DEFAULT_COMPOUND_GRAVITY_STRENGTH=e.gravityCompound),null!=e.gravityRangeCompound&&(a.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=e.gravityRangeCompound),null!=e.initialEnergyOnIncremental&&(a.DEFAULT_COOLING_FACTOR_INCREMENTAL=i.DEFAULT_COOLING_FACTOR_INCREMENTAL=e.initialEnergyOnIncremental),"draft"==e.quality?r.QUALITY=0:"proof"==e.quality?r.QUALITY=2:r.QUALITY=1,a.NODE_DIMENSIONS_INCLUDE_LABELS=i.NODE_DIMENSIONS_INCLUDE_LABELS=r.NODE_DIMENSIONS_INCLUDE_LABELS=e.nodeDimensionsIncludeLabels,a.DEFAULT_INCREMENTAL=i.DEFAULT_INCREMENTAL=r.DEFAULT_INCREMENTAL=!e.randomize,a.ANIMATE=i.ANIMATE=r.ANIMATE=e.animate,a.TILE=e.tile,a.TILING_PADDING_VERTICAL="function"==typeof e.tilingPaddingVertical?e.tilingPaddingVertical.call():e.tilingPaddingVertical,a.TILING_PADDING_HORIZONTAL="function"==typeof e.tilingPaddingHorizontal?e.tilingPaddingHorizontal.call():e.tilingPaddingHorizontal};h.prototype.run=function(){var e,t,n=this.options,r=(this.idToLNode={},this.layout=new o),i=this;i.stopped=!1,this.cy=this.options.cy,this.cy.trigger({type:"layoutstart",layout:this});var a=r.newGraphManager();this.gm=a;var s=this.options.eles.nodes(),l=this.options.eles.edges();this.root=a.addRoot(),this.processChildrenList(this.root,this.getTopMostNodes(s),r);for(var u=0;u<l.length;u++){var c=l[u],h=this.idToLNode[c.data("source")],d=this.idToLNode[c.data("target")];h!==d&&0==h.getEdgesBetween(d).length&&(a.add(r.newEdge(),h,d).id=c.id())}var p=function(e,t){"number"==typeof e&&(e=t);var n=e.data("id"),r=i.idToLNode[n];return{x:r.getRect().getCenterX(),y:r.getRect().getCenterY()}},g=function a(){for(var o,s=function(){n.fit&&n.cy.fit(n.eles,n.padding),e||(e=!0,i.cy.one("layoutready",n.ready),i.cy.trigger({type:"layoutready",layout:i}))},l=i.options.refresh,u=0;u<l&&!o;u++)o=i.stopped||i.layout.tick();if(o)return r.checkLayoutSuccess()&&!r.isSubLayout&&r.doPostLayout(),r.tilingPostLayout&&r.tilingPostLayout(),r.isLayoutFinished=!0,i.options.eles.nodes().positions(p),s(),i.cy.one("layoutstop",i.options.stop),i.cy.trigger({type:"layoutstop",layout:i}),t&&cancelAnimationFrame(t),void(e=!1);var c=i.layout.getPositionsData();n.eles.nodes().positions((function(e,t){if("number"==typeof e&&(e=t),!e.isParent()){for(var n=e.id(),r=c[n],i=e;null==r&&(r=c[i.data("parent")]||c["DummyCompound_"+i.data("parent")],c[n]=r,null!=(i=i.parent()[0])););return null!=r?{x:r.x,y:r.y}:{x:e.position("x"),y:e.position("y")}}})),s(),t=requestAnimationFrame(a)};return r.addListener("layoutstarted",(function(){"during"===i.options.animate&&(t=requestAnimationFrame(g))})),r.runLayout(),"during"!==this.options.animate&&(i.options.eles.nodes().not(":parent").layoutPositions(i,i.options,p),e=!1),this},h.prototype.getTopMostNodes=function(e){for(var t={},n=0;n<e.length;n++)t[e[n].id()]=!0;var r=e.filter((function(e,n){"number"==typeof e&&(e=n);for(var r=e.parent()[0];null!=r;){if(t[r.id()])return!1;r=r.parent()[0]}return!0}));return r},h.prototype.processChildrenList=function(e,t,n){for(var r=t.length,i=0;i<r;i++){var a,o,c=t[i],h=c.children(),d=c.layoutDimensions({nodeDimensionsIncludeLabels:this.options.nodeDimensionsIncludeLabels});if((a=null!=c.outerWidth()&&null!=c.outerHeight()?e.add(new s(n.graphManager,new l(c.position("x")-d.w/2,c.position("y")-d.h/2),new u(parseFloat(d.w),parseFloat(d.h)))):e.add(new s(this.graphManager))).id=c.data("id"),a.paddingLeft=parseInt(c.css("padding")),a.paddingTop=parseInt(c.css("padding")),a.paddingRight=parseInt(c.css("padding")),a.paddingBottom=parseInt(c.css("padding")),this.options.nodeDimensionsIncludeLabels&&c.isParent()){var p=c.boundingBox({includeLabels:!0,includeNodes:!1}).w,g=c.boundingBox({includeLabels:!0,includeNodes:!1}).h,f=c.css("text-halign");a.labelWidth=p,a.labelHeight=g,a.labelPos=f}this.idToLNode[c.data("id")]=a,isNaN(a.rect.x)&&(a.rect.x=0),isNaN(a.rect.y)&&(a.rect.y=0),null!=h&&h.length>0&&(o=n.getGraphManager().add(n.newGraph(),a),this.processChildrenList(o,h,n))}},h.prototype.stop=function(){return this.stopped=!0,this};var p=function(e){e("layout","cose-bilkent",h)};"undefined"!=typeof cytoscape&&p(cytoscape),e.exports=p}])},e.exports=r(n(87799))},44726:(e,t,n)=>{"use strict";var r=n(38221),i=n(65731),a=n(58156),o=n(63560),s=n(42072);function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=l(r),c=l(i),h=l(a),d=l(o),p=l(s);function g(e){return g="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},g(e)}function f(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function v(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function y(e,t,n){return t&&v(e.prototype,t),n&&v(e,n),Object.defineProperty(e,"prototype",{writable:!1}),e}function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function b(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var r,i,a=[],o=!0,s=!1;try{for(n=n.call(e);!(o=(r=n.next()).done)&&(a.push(r.value),!t||a.length!==t);o=!0);}catch(l){s=!0,i=l}finally{try{o||null==n.return||n.return()}finally{if(s)throw i}}return a}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return x(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return x(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var w="undefined"==typeof window?null:window,E=w?w.navigator:null;w&&w.document;var _=g(""),T=g({}),D=g((function(){})),C="undefined"==typeof HTMLElement?"undefined":g(HTMLElement),N=function(e){return e&&e.instanceString&&L(e.instanceString)?e.instanceString():null},A=function(e){return null!=e&&g(e)==_},L=function(e){return null!=e&&g(e)===D},k=function(e){return!O(e)&&(Array.isArray?Array.isArray(e):null!=e&&e instanceof Array)},S=function(e){return null!=e&&g(e)===T&&!k(e)&&e.constructor===Object},I=function(e){return null!=e&&g(e)===g(1)&&!isNaN(e)},M=function(e){return"undefined"===C?void 0:null!=e&&e instanceof HTMLElement},O=function(e){return P(e)||R(e)},P=function(e){return"collection"===N(e)&&e._private.single},R=function(e){return"collection"===N(e)&&!e._private.single},B=function(e){return"core"===N(e)},F=function(e){return"stylesheet"===N(e)},z=function(e){return null==e||!(""!==e&&!e.match(/^\s+$/))},G=function(e){return function(e){return null!=e&&g(e)===T}(e)&&L(e.then)},Y=function(e,t){t||(t=function(){if(1===arguments.length)return arguments[0];if(0===arguments.length)return"undefined";for(var e=[],t=0;t<arguments.length;t++)e.push(arguments[t]);return e.join("$")});var n=function n(){var r,i=arguments,a=t.apply(this,i),o=n.cache;return(r=o[a])||(r=o[a]=e.apply(this,i)),r};return n.cache={},n},X=Y((function(e){return e.replace(/([A-Z])/g,(function(e){return"-"+e.toLowerCase()}))})),V=Y((function(e){return e.replace(/(-\w)/g,(function(e){return e[1].toUpperCase()}))})),U=Y((function(e,t){return e+t[0].toUpperCase()+t.substring(1)}),(function(e,t){return e+"$"+t})),j=function(e){return z(e)?e:e.charAt(0).toUpperCase()+e.substring(1)},q="(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))",H="rgb[a]?\\(("+q+"[%]?)\\s*,\\s*("+q+"[%]?)\\s*,\\s*("+q+"[%]?)(?:\\s*,\\s*("+q+"))?\\)",W="rgb[a]?\\((?:"+q+"[%]?)\\s*,\\s*(?:"+q+"[%]?)\\s*,\\s*(?:"+q+"[%]?)(?:\\s*,\\s*(?:"+q+"))?\\)",$="hsl[a]?\\(("+q+")\\s*,\\s*("+q+"[%])\\s*,\\s*("+q+"[%])(?:\\s*,\\s*("+q+"))?\\)",K="hsl[a]?\\((?:"+q+")\\s*,\\s*(?:"+q+"[%])\\s*,\\s*(?:"+q+"[%])(?:\\s*,\\s*(?:"+q+"))?\\)",Z=function(e,t){return e<t?-1:e>t?1:0},Q=null!=Object.assign?Object.assign.bind(Object):function(e){for(var t=arguments,n=1;n<t.length;n++){var r=t[n];if(null!=r)for(var i=Object.keys(r),a=0;a<i.length;a++){var o=i[a];e[o]=r[o]}}return e},J=function(e){return(k(e)?e:null)||function(e){return ee[e.toLowerCase()]}(e)||function(e){if((4===e.length||7===e.length)&&"#"===e[0]){var t,n,r,i=16;return 4===e.length?(t=parseInt(e[1]+e[1],i),n=parseInt(e[2]+e[2],i),r=parseInt(e[3]+e[3],i)):(t=parseInt(e[1]+e[2],i),n=parseInt(e[3]+e[4],i),r=parseInt(e[5]+e[6],i)),[t,n,r]}}(e)||function(e){var t,n=new RegExp("^"+H+"$").exec(e);if(n){t=[];for(var r=[],i=1;i<=3;i++){var a=n[i];if("%"===a[a.length-1]&&(r[i]=!0),a=parseFloat(a),r[i]&&(a=a/100*255),a<0||a>255)return;t.push(Math.floor(a))}var o=r[1]||r[2]||r[3],s=r[1]&&r[2]&&r[3];if(o&&!s)return;var l=n[4];if(void 0!==l){if((l=parseFloat(l))<0||l>1)return;t.push(l)}}return t}(e)||function(e){var t,n,r,i,a,o,s,l;function u(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var c=new RegExp("^"+$+"$").exec(e);if(c){if((n=parseInt(c[1]))<0?n=(360- -1*n%360)%360:n>360&&(n%=360),n/=360,(r=parseFloat(c[2]))<0||r>100)return;if(r/=100,(i=parseFloat(c[3]))<0||i>100)return;if(i/=100,void 0!==(a=c[4])&&((a=parseFloat(a))<0||a>1))return;if(0===r)o=s=l=Math.round(255*i);else{var h=i<.5?i*(1+r):i+r-i*r,d=2*i-h;o=Math.round(255*u(d,h,n+1/3)),s=Math.round(255*u(d,h,n)),l=Math.round(255*u(d,h,n-1/3))}t=[o,s,l,a]}return t}(e)},ee={transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},te=function(e){for(var t=e.map,n=e.keys,r=n.length,i=0;i<r;i++){var a=n[i];if(S(a))throw Error("Tried to set map with object key");i<n.length-1?(null==t[a]&&(t[a]={}),t=t[a]):t[a]=e.value}},ne=function(e){for(var t=e.map,n=e.keys,r=n.length,i=0;i<r;i++){var a=n[i];if(S(a))throw Error("Tried to get map with object key");if(null==(t=t[a]))return t}return t},re=w?w.performance:null,ie=re&&re.now?function(){return re.now()}:function(){return Date.now()},ae=function(){if(w){if(w.requestAnimationFrame)return function(e){w.requestAnimationFrame(e)};if(w.mozRequestAnimationFrame)return function(e){w.mozRequestAnimationFrame(e)};if(w.webkitRequestAnimationFrame)return function(e){w.webkitRequestAnimationFrame(e)};if(w.msRequestAnimationFrame)return function(e){w.msRequestAnimationFrame(e)}}return function(e){e&&setTimeout((function(){e(ie())}),1e3/60)}}(),oe=function(e){return ae(e)},se=ie,le=9261,ue=5381,ce=function(e){for(var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:le;!(t=e.next()).done;)n=65599*n+t.value|0;return n},he=function(e){return 65599*(arguments.length>1&&void 0!==arguments[1]?arguments[1]:le)+e|0},de=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:ue;return(t<<5)+t+e|0},pe=function(e){return 2097152*e[0]+e[1]},ge=function(e,t){return[he(e[0],t[0]),de(e[1],t[1])]},fe=function(e,t){var n={value:0,done:!1},r=0,i=e.length;return ce({next:function(){return r<i?n.value=e.charCodeAt(r++):n.done=!0,n}},t)},ve=function(){return ye(arguments)},ye=function(e){for(var t,n=0;n<e.length;n++){var r=e[n];t=0===n?fe(r):fe(r,t)}return t},me=!0,be=null!=console.warn,xe=null!=console.trace,we=Number.MAX_SAFE_INTEGER||9007199254740991,Ee=function(){return!0},_e=function(){return!1},Te=function(){return 0},De=function(){},Ce=function(e){throw new Error(e)},Ne=function(e){if(void 0===e)return me;me=!!e},Ae=function(e){Ne()&&(be?console.warn(e):(console.log(e),xe&&console.trace()))},Le=function(e){return null==e?e:k(e)?e.slice():S(e)?function(e){return Q({},e)}(e):e},ke=function(e,t){for(t=e="";e++<36;t+=51*e&52?(15^e?8^Math.random()*(20^e?16:4):4).toString(16):"-");return t},Se={},Ie=function(){return Se},Me=function(e){var t=Object.keys(e);return function(n){for(var r={},i=0;i<t.length;i++){var a=t[i],o=null==n?void 0:n[a];r[a]=void 0===o?e[a]:o}return r}},Oe=function(e,t,n){for(var r=e.length-1;r>=0&&(e[r]!==t||(e.splice(r,1),!n));r--);},Pe=function(e){e.splice(0,e.length)},Re=function(e,t,n){return n&&(t=U(n,t)),e[t]},Be=function(e,t,n,r){n&&(t=U(n,t)),e[t]=r},Fe="undefined"!=typeof Map?Map:function(){function e(){f(this,e),this._obj={}}return y(e,[{key:"set",value:function(e,t){return this._obj[e]=t,this}},{key:"delete",value:function(e){return this._obj[e]=void 0,this}},{key:"clear",value:function(){this._obj={}}},{key:"has",value:function(e){return void 0!==this._obj[e]}},{key:"get",value:function(e){return this._obj[e]}}]),e}(),ze=function(){function e(t){if(f(this,e),this._obj=Object.create(null),this.size=0,null!=t){var n;n=null!=t.instanceString&&t.instanceString()===this.instanceString()?t.toArray():t;for(var r=0;r<n.length;r++)this.add(n[r])}}return y(e,[{key:"instanceString",value:function(){return"set"}},{key:"add",value:function(e){var t=this._obj;1!==t[e]&&(t[e]=1,this.size++)}},{key:"delete",value:function(e){var t=this._obj;1===t[e]&&(t[e]=0,this.size--)}},{key:"clear",value:function(){this._obj=Object.create(null)}},{key:"has",value:function(e){return 1===this._obj[e]}},{key:"toArray",value:function(){var e=this;return Object.keys(this._obj).filter((function(t){return e.has(t)}))}},{key:"forEach",value:function(e,t){return this.toArray().forEach(e,t)}}]),e}(),Ge="undefined"!==("undefined"==typeof Set?"undefined":g(Set))?Set:ze,Ye=function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(void 0!==e&&void 0!==t&&B(e)){var r=t.group;if(null==r&&(r=t.data&&null!=t.data.source&&null!=t.data.target?"edges":"nodes"),"nodes"===r||"edges"===r){this.length=1,this[0]=this;var i=this._private={cy:e,single:!0,data:t.data||{},position:t.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:r,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!t.selected,selectable:void 0===t.selectable||!!t.selectable,locked:!!t.locked,grabbed:!1,grabbable:void 0===t.grabbable||!!t.grabbable,pannable:void 0===t.pannable?"edges"===r:!!t.pannable,active:!1,classes:new Ge,animation:{current:[],queue:[]},rscratch:{},scratch:t.scratch||{},edges:[],children:[],parent:t.parent&&t.parent.isNode()?t.parent:null,traversalCache:{},backgrounding:!1,bbCache:null,bbCacheShift:{x:0,y:0},bodyBounds:null,overlayBounds:null,labelBounds:{all:null,source:null,target:null,main:null},arrowBounds:{source:null,target:null,"mid-source":null,"mid-target":null}};if(null==i.position.x&&(i.position.x=0),null==i.position.y&&(i.position.y=0),t.renderedPosition){var a=t.renderedPosition,o=e.pan(),s=e.zoom();i.position={x:(a.x-o.x)/s,y:(a.y-o.y)/s}}var l=[];k(t.classes)?l=t.classes:A(t.classes)&&(l=t.classes.split(/\s+/));for(var u=0,c=l.length;u<c;u++){var h=l[u];h&&""!==h&&i.classes.add(h)}this.createEmitter();var d=t.style||t.css;d&&(Ae("Setting a `style` bypass at element creation should be done only when absolutely necessary. Try to use the stylesheet instead."),this.style(d)),(void 0===n||n)&&this.restore()}else Ce("An element must be of type `nodes` or `edges`; you specified `"+r+"`")}else Ce("An element must have a core reference and parameters set")},Xe=function(e){return e={bfs:e.bfs||!e.dfs,dfs:e.dfs||!e.bfs},function(t,n,r){var i;S(t)&&!O(t)&&(t=(i=t).roots||i.root,n=i.visit,r=i.directed),r=2!==arguments.length||L(n)?r:n,n=L(n)?n:function(){};for(var a,o=this._private.cy,s=t=A(t)?this.filter(t):t,l=[],u=[],c={},h={},d={},p=0,g=this.byGroup(),f=g.nodes,v=g.edges,y=0;y<s.length;y++){var m=s[y],b=m.id();m.isNode()&&(l.unshift(m),e.bfs&&(d[b]=!0,u.push(m)),h[b]=0)}for(var x=function(){var t=e.bfs?l.shift():l.pop(),i=t.id();if(e.dfs){if(d[i])return"continue";d[i]=!0,u.push(t)}var o,s=h[i],g=c[i],y=null!=g?g.source():null,m=null!=g?g.target():null,b=null==g?void 0:t.same(y)?m[0]:y[0];if(!0===(o=n(t,g,b,p++,s)))return a=t,"break";if(!1===o)return"break";for(var x=t.connectedEdges().filter((function(e){return(!r||e.source().same(t))&&v.has(e)})),w=0;w<x.length;w++){var E=x[w],_=E.connectedNodes().filter((function(e){return!e.same(t)&&f.has(e)})),T=_.id();0===_.length||d[T]||(_=_[0],l.push(_),e.bfs&&(d[T]=!0,u.push(_)),c[T]=E,h[T]=h[i]+1)}};0!==l.length;){var w=x();if("continue"!==w&&"break"===w)break}for(var E=o.collection(),_=0;_<u.length;_++){var T=u[_],D=c[T.id()];null!=D&&E.push(D),E.push(T)}return{path:o.collection(E),found:o.collection(a)}}},Ve={breadthFirstSearch:Xe({bfs:!0}),depthFirstSearch:Xe({dfs:!0})};Ve.bfs=Ve.breadthFirstSearch,Ve.dfs=Ve.depthFirstSearch;var Ue=Me({root:null,weight:function(e){return 1},directed:!1}),je={dijkstra:function(e){if(!S(e)){var t=arguments;e={root:t[0],weight:t[1],directed:t[2]}}var n=Ue(e),r=n.root,i=n.weight,a=n.directed,o=this,s=i,l=A(r)?this.filter(r)[0]:r[0],u={},h={},d={},p=this.byGroup(),g=p.nodes,f=p.edges;f.unmergeBy((function(e){return e.isLoop()}));for(var v=function(e){return u[e.id()]},y=function(e,t){u[e.id()]=t,m.updateItem(e)},m=new c.default((function(e,t){return v(e)-v(t)})),b=0;b<g.length;b++){var x=g[b];u[x.id()]=x.same(l)?0:1/0,m.push(x)}for(var w=function(e,t){for(var n,r=(a?e.edgesTo(t):e.edgesWith(t)).intersect(f),i=1/0,o=0;o<r.length;o++){var l=r[o],u=s(l);(u<i||!n)&&(i=u,n=l)}return{edge:n,dist:i}};m.size()>0;){var E=m.pop(),_=v(E),T=E.id();if(d[T]=_,_!==1/0)for(var D=E.neighborhood().intersect(g),C=0;C<D.length;C++){var N=D[C],L=N.id(),k=w(E,N),I=_+k.dist;I<v(N)&&(y(N,I),h[L]={node:E,edge:k.edge})}}return{distanceTo:function(e){var t=A(e)?g.filter(e)[0]:e[0];return d[t.id()]},pathTo:function(e){var t=A(e)?g.filter(e)[0]:e[0],n=[],r=t,i=r.id();if(t.length>0)for(n.unshift(t);h[i];){var a=h[i];n.unshift(a.edge),n.unshift(a.node),i=(r=a.node).id()}return o.spawn(n)}}}},qe={kruskal:function(e){e=e||function(e){return 1};for(var t=this.byGroup(),n=t.nodes,r=t.edges,i=n.length,a=new Array(i),o=n,s=function(e){for(var t=0;t<a.length;t++){if(a[t].has(e))return t}},l=0;l<i;l++)a[l]=this.spawn(n[l]);for(var u=r.sort((function(t,n){return e(t)-e(n)})),c=0;c<u.length;c++){var h=u[c],d=h.source()[0],p=h.target()[0],g=s(d),f=s(p),v=a[g],y=a[f];g!==f&&(o.merge(h),v.merge(y),a.splice(f,1))}return o}},He=Me({root:null,goal:null,weight:function(e){return 1},heuristic:function(e){return 0},directed:!1}),We={aStar:function(e){var t=this.cy(),n=He(e),r=n.root,i=n.goal,a=n.heuristic,o=n.directed,s=n.weight;r=t.collection(r)[0],i=t.collection(i)[0];var l,u,h=r.id(),d=i.id(),p={},g={},f={},v=new c.default((function(e,t){return g[e.id()]-g[t.id()]})),y=new Ge,m={},b={},x=function(e,t){v.push(e),y.add(t)};x(r,h),p[h]=0,g[h]=a(r);for(var w,E=0;v.size()>0;){if(l=v.pop(),u=l.id(),y.delete(u),E++,u===d){for(var _=[],T=i,D=d,C=b[D];_.unshift(T),null!=C&&_.unshift(C),null!=(T=m[D]);)C=b[D=T.id()];return{found:!0,distance:p[u],path:this.spawn(_),steps:E}}f[u]=!0;for(var N=l._private.edges,A=0;A<N.length;A++){var L=N[A];if(this.hasElementWithId(L.id())&&(!o||L.data("source")===u)){var k=L.source(),S=L.target(),I=k.id()!==u?k:S,M=I.id();if(this.hasElementWithId(M)&&!f[M]){var O=p[u]+s(L);w=M,y.has(w)?O<p[M]&&(p[M]=O,g[M]=O+a(I),m[M]=l,b[M]=L):(p[M]=O,g[M]=O+a(I),x(I,M),m[M]=l,b[M]=L)}}}}return{found:!1,distance:void 0,path:void 0,steps:E}}},$e=Me({weight:function(e){return 1},directed:!1}),Ke={floydWarshall:function(e){for(var t=this.cy(),n=$e(e),r=n.weight,i=n.directed,a=r,o=this.byGroup(),s=o.nodes,l=o.edges,u=s.length,c=u*u,h=function(e){return s.indexOf(e)},d=function(e){return s[e]},p=new Array(c),g=0;g<c;g++){var f=g%u,v=(g-f)/u;p[g]=v===f?0:1/0}for(var y=new Array(c),m=new Array(c),b=0;b<l.length;b++){var x=l[b],w=x.source()[0],E=x.target()[0];if(w!==E){var _=h(w),T=h(E),D=_*u+T,C=a(x);if(p[D]>C&&(p[D]=C,y[D]=T,m[D]=x),!i){var N=T*u+_;!i&&p[N]>C&&(p[N]=C,y[N]=_,m[N]=x)}}}for(var L=0;L<u;L++)for(var k=0;k<u;k++)for(var S=k*u+L,I=0;I<u;I++){var M=k*u+I,O=L*u+I;p[S]+p[O]<p[M]&&(p[M]=p[S]+p[O],y[M]=y[S])}var P=function(e){return h(function(e){return(A(e)?t.filter(e):e)[0]}(e))},R={distance:function(e,t){var n=P(e),r=P(t);return p[n*u+r]},path:function(e,n){var r=P(e),i=P(n),a=d(r);if(r===i)return a.collection();if(null==y[r*u+i])return t.collection();var o,s=t.collection(),l=r;for(s.merge(a);r!==i;)l=r,r=y[r*u+i],o=m[l*u+r],s.merge(o),s.merge(d(r));return s}};return R}},Ze=Me({weight:function(e){return 1},directed:!1,root:null}),Qe={bellmanFord:function(e){var t=this,n=Ze(e),r=n.weight,i=n.directed,a=n.root,o=r,s=this,l=this.cy(),u=this.byGroup(),c=u.edges,h=u.nodes,d=h.length,p=new Fe,g=!1,f=[];a=l.collection(a)[0],c.unmergeBy((function(e){return e.isLoop()}));for(var v=c.length,y=function(e){var t=p.get(e.id());return t||(t={},p.set(e.id(),t)),t},m=function(e){return(A(e)?l.$(e):e)[0]},b=0;b<d;b++){var x=h[b],w=y(x);x.same(a)?w.dist=0:w.dist=1/0,w.pred=null,w.edge=null}for(var E=!1,_=function(e,t,n,r,i,a){var o=r.dist+a;o<i.dist&&!n.same(r.edge)&&(i.dist=o,i.pred=e,i.edge=n,E=!0)},T=1;T<d;T++){E=!1;for(var D=0;D<v;D++){var C=c[D],N=C.source(),L=C.target(),k=o(C),S=y(N),I=y(L);_(N,0,C,S,I,k),i||_(L,0,C,I,S,k)}if(!E)break}if(E)for(var M=[],O=0;O<v;O++){var P=c[O],R=P.source(),B=P.target(),F=o(P),z=y(R).dist,G=y(B).dist;if(z+F<G||!i&&G+F<z){if(g||(Ae("Graph contains a negative weight cycle for Bellman-Ford"),g=!0),!1===e.findNegativeWeightCycles)break;var Y=[];z+F<G&&Y.push(R),!i&&G+F<z&&Y.push(B);for(var X=Y.length,V=0;V<X;V++){var U=Y[V],j=[U];j.push(y(U).edge);for(var q=y(U).pred;-1===j.indexOf(q);)j.push(q),j.push(y(q).edge),q=y(q).pred;for(var H=(j=j.slice(j.indexOf(q)))[0].id(),W=0,$=2;$<j.length;$+=2)j[$].id()<H&&(H=j[$].id(),W=$);(j=j.slice(W).concat(j.slice(0,W))).push(j[0]);var K=j.map((function(e){return e.id()})).join(",");-1===M.indexOf(K)&&(f.push(s.spawn(j)),M.push(K))}}}return{distanceTo:function(e){return y(m(e)).dist},pathTo:function(e){for(var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:a,r=[],i=m(e);;){if(null==i)return t.spawn();var o=y(i),l=o.edge,u=o.pred;if(r.unshift(i[0]),i.same(n)&&r.length>0)break;null!=l&&r.unshift(l),i=u}return s.spawn(r)},hasNegativeWeightCycle:g,negativeWeightCycles:f}}},Je=Math.sqrt(2),et=function(e,t,n){0===n.length&&Ce("Karger-Stein must be run on a connected (sub)graph");for(var r=n[e],i=r[1],a=r[2],o=t[i],s=t[a],l=n,u=l.length-1;u>=0;u--){var c=l[u],h=c[1],d=c[2];(t[h]===o&&t[d]===s||t[h]===s&&t[d]===o)&&l.splice(u,1)}for(var p=0;p<l.length;p++){var g=l[p];g[1]===s?(l[p]=g.slice(),l[p][1]=o):g[2]===s&&(l[p]=g.slice(),l[p][2]=o)}for(var f=0;f<t.length;f++)t[f]===s&&(t[f]=o);return l},tt=function(e,t,n,r){for(;n>r;){var i=Math.floor(Math.random()*t.length);t=et(i,e,t),n--}return t},nt={kargerStein:function(){var e=this,t=this.byGroup(),n=t.nodes,r=t.edges;r.unmergeBy((function(e){return e.isLoop()}));var i=n.length,a=r.length,o=Math.ceil(Math.pow(Math.log(i)/Math.LN2,2)),s=Math.floor(i/Je);if(!(i<2)){for(var l=[],u=0;u<a;u++){var c=r[u];l.push([u,n.indexOf(c.source()),n.indexOf(c.target())])}for(var h=1/0,d=[],p=new Array(i),g=new Array(i),f=new Array(i),v=function(e,t){for(var n=0;n<i;n++)t[n]=e[n]},y=0;y<=o;y++){for(var m=0;m<i;m++)g[m]=m;var b=tt(g,l.slice(),i,s),x=b.slice();v(g,f);var w=tt(g,b,s,2),E=tt(f,x,s,2);w.length<=E.length&&w.length<h?(h=w.length,d=w,v(g,p)):E.length<=w.length&&E.length<h&&(h=E.length,d=E,v(f,p))}for(var _=this.spawn(d.map((function(e){return r[e[0]]}))),T=this.spawn(),D=this.spawn(),C=p[0],N=0;N<p.length;N++){var A=p[N],L=n[N];A===C?T.merge(L):D.merge(L)}var k=function(t){var n=e.spawn();return t.forEach((function(t){n.merge(t),t.connectedEdges().forEach((function(t){e.contains(t)&&!_.contains(t)&&n.merge(t)}))})),n},S=[k(T),k(D)];return{cut:_,components:S,partition1:T,partition2:D}}Ce("At least 2 nodes are required for Karger-Stein algorithm")}},rt=function(e,t,n){return{x:e.x*t+n.x,y:e.y*t+n.y}},it=function(e,t,n){return{x:(e.x-n.x)/t,y:(e.y-n.y)/t}},at=function(e){return{x:e[0],y:e[1]}},ot=function(e,t){return Math.atan2(t,e)-Math.PI/2},st=Math.log2||function(e){return Math.log(e)/Math.log(2)},lt=function(e){return e>0?1:e<0?-1:0},ut=function(e,t){return Math.sqrt(ct(e,t))},ct=function(e,t){var n=t.x-e.x,r=t.y-e.y;return n*n+r*r},ht=function(e){for(var t=e.length,n=0,r=0;r<t;r++)n+=e[r];for(var i=0;i<t;i++)e[i]=e[i]/n;return e},dt=function(e,t,n,r){return(1-r)*(1-r)*e+2*(1-r)*r*t+r*r*n},pt=function(e,t,n,r){return{x:dt(e.x,t.x,n.x,r),y:dt(e.y,t.y,n.y,r)}},gt=function(e,t,n){return Math.max(e,Math.min(n,t))},ft=function(e){if(null==e)return{x1:1/0,y1:1/0,x2:-1/0,y2:-1/0,w:0,h:0};if(null!=e.x1&&null!=e.y1){if(null!=e.x2&&null!=e.y2&&e.x2>=e.x1&&e.y2>=e.y1)return{x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,w:e.x2-e.x1,h:e.y2-e.y1};if(null!=e.w&&null!=e.h&&e.w>=0&&e.h>=0)return{x1:e.x1,y1:e.y1,x2:e.x1+e.w,y2:e.y1+e.h,w:e.w,h:e.h}}},vt=function(e,t){e.x1=Math.min(e.x1,t.x1),e.x2=Math.max(e.x2,t.x2),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,t.y1),e.y2=Math.max(e.y2,t.y2),e.h=e.y2-e.y1},yt=function(e,t,n){e.x1=Math.min(e.x1,t),e.x2=Math.max(e.x2,t),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,n),e.y2=Math.max(e.y2,n),e.h=e.y2-e.y1},mt=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e.x1-=t,e.x2+=t,e.y1-=t,e.y2+=t,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},bt=function(e){var t,n,r,i,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[0];if(1===a.length)t=n=r=i=a[0];else if(2===a.length)t=r=a[0],i=n=a[1];else if(4===a.length){var o=b(a,4);t=o[0],n=o[1],r=o[2],i=o[3]}return e.x1-=i,e.x2+=n,e.y1-=t,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},xt=function(e,t){e.x1=t.x1,e.y1=t.y1,e.x2=t.x2,e.y2=t.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},wt=function(e,t){return!(e.x1>t.x2)&&(!(t.x1>e.x2)&&(!(e.x2<t.x1)&&(!(t.x2<e.x1)&&(!(e.y2<t.y1)&&(!(t.y2<e.y1)&&(!(e.y1>t.y2)&&!(t.y1>e.y2)))))))},Et=function(e,t,n){return e.x1<=t&&t<=e.x2&&e.y1<=n&&n<=e.y2},_t=function(e,t){return Et(e,t.x1,t.y1)&&Et(e,t.x2,t.y2)},Tt=function(e,t,n,r,i,a,o){var s,l=Xt(i,a),u=i/2,c=a/2,h=r-c-o;if((s=Rt(e,t,n,r,n-u+l-o,h,n+u-l+o,h,!1)).length>0)return s;var d=n+u+o;if((s=Rt(e,t,n,r,d,r-c+l-o,d,r+c-l+o,!1)).length>0)return s;var p=r+c+o;if((s=Rt(e,t,n,r,n-u+l-o,p,n+u-l+o,p,!1)).length>0)return s;var g,f=n-u-o;if((s=Rt(e,t,n,r,f,r-c+l-o,f,r+c-l+o,!1)).length>0)return s;var v=n-u+l,y=r-c+l;if((g=Ot(e,t,n,r,v,y,l+o)).length>0&&g[0]<=v&&g[1]<=y)return[g[0],g[1]];var m=n+u-l,b=r-c+l;if((g=Ot(e,t,n,r,m,b,l+o)).length>0&&g[0]>=m&&g[1]<=b)return[g[0],g[1]];var x=n+u-l,w=r+c-l;if((g=Ot(e,t,n,r,x,w,l+o)).length>0&&g[0]>=x&&g[1]>=w)return[g[0],g[1]];var E=n-u+l,_=r+c-l;return(g=Ot(e,t,n,r,E,_,l+o)).length>0&&g[0]<=E&&g[1]>=_?[g[0],g[1]]:[]},Dt=function(e,t,n,r,i,a,o){var s=o,l=Math.min(n,i),u=Math.max(n,i),c=Math.min(r,a),h=Math.max(r,a);return l-s<=e&&e<=u+s&&c-s<=t&&t<=h+s},Ct=function(e,t,n,r,i,a,o,s,l){var u=Math.min(n,o,i)-l,c=Math.max(n,o,i)+l,h=Math.min(r,s,a)-l,d=Math.max(r,s,a)+l;return!(e<u||e>c||t<h||t>d)},Nt=function(e,t,n,r,i,a,o,s){var l=[];!function(e,t,n,r,i){var a,o,s,l,u,c,h,d;0===e&&(e=1e-5),s=-27*(r/=e)+(t/=e)*(9*(n/=e)-t*t*2),a=(o=(3*n-t*t)/9)*o*o+(s/=54)*s,i[1]=0,h=t/3,a>0?(u=(u=s+Math.sqrt(a))<0?-Math.pow(-u,1/3):Math.pow(u,1/3),c=(c=s-Math.sqrt(a))<0?-Math.pow(-c,1/3):Math.pow(c,1/3),i[0]=-h+u+c,h+=(u+c)/2,i[4]=i[2]=-h,h=Math.sqrt(3)*(-c+u)/2,i[3]=h,i[5]=-h):(i[5]=i[3]=0,0===a?(d=s<0?-Math.pow(-s,1/3):Math.pow(s,1/3),i[0]=2*d-h,i[4]=i[2]=-(d+h)):(l=(o=-o)*o*o,l=Math.acos(s/Math.sqrt(l)),d=2*Math.sqrt(o),i[0]=-h+d*Math.cos(l/3),i[2]=-h+d*Math.cos((l+2*Math.PI)/3),i[4]=-h+d*Math.cos((l+4*Math.PI)/3)))}(1*n*n-4*n*i+2*n*o+4*i*i-4*i*o+o*o+r*r-4*r*a+2*r*s+4*a*a-4*a*s+s*s,9*n*i-3*n*n-3*n*o-6*i*i+3*i*o+9*r*a-3*r*r-3*r*s-6*a*a+3*a*s,3*n*n-6*n*i+n*o-n*e+2*i*i+2*i*e-o*e+3*r*r-6*r*a+r*s-r*t+2*a*a+2*a*t-s*t,1*n*i-n*n+n*e-i*e+r*a-r*r+r*t-a*t,l);for(var u=[],c=0;c<6;c+=2)Math.abs(l[c+1])<1e-7&&l[c]>=0&&l[c]<=1&&u.push(l[c]);u.push(1),u.push(0);for(var h,d,p,g=-1,f=0;f<u.length;f++)h=Math.pow(1-u[f],2)*n+2*(1-u[f])*u[f]*i+u[f]*u[f]*o,d=Math.pow(1-u[f],2)*r+2*(1-u[f])*u[f]*a+u[f]*u[f]*s,p=Math.pow(h-e,2)+Math.pow(d-t,2),g>=0?p<g&&(g=p):g=p;return g},At=function(e,t,n,r,i,a){var o=[e-n,t-r],s=[i-n,a-r],l=s[0]*s[0]+s[1]*s[1],u=o[0]*o[0]+o[1]*o[1],c=o[0]*s[0]+o[1]*s[1],h=c*c/l;return c<0?u:h>l?(e-i)*(e-i)+(t-a)*(t-a):u-h},Lt=function(e,t,n){for(var r,i,a,o,s=0,l=0;l<n.length/2;l++)if(r=n[2*l],i=n[2*l+1],l+1<n.length/2?(a=n[2*(l+1)],o=n[2*(l+1)+1]):(a=n[2*(l+1-n.length/2)],o=n[2*(l+1-n.length/2)+1]),r==e&&a==e);else{if(!(r>=e&&e>=a||r<=e&&e<=a))continue;(e-r)/(a-r)*(o-i)+i>t&&s++}return s%2!=0},kt=function(e,t,n,r,i,a,o,s,l){var u,c=new Array(n.length);null!=s[0]?(u=Math.atan(s[1]/s[0]),s[0]<0?u+=Math.PI/2:u=-u-Math.PI/2):u=s;for(var h,d=Math.cos(-u),p=Math.sin(-u),g=0;g<c.length/2;g++)c[2*g]=a/2*(n[2*g]*d-n[2*g+1]*p),c[2*g+1]=o/2*(n[2*g+1]*d+n[2*g]*p),c[2*g]+=r,c[2*g+1]+=i;if(l>0){var f=It(c,-l);h=St(f)}else h=c;return Lt(e,t,h)},St=function(e){for(var t,n,r,i,a,o,s,l,u=new Array(e.length/2),c=0;c<e.length/4;c++){t=e[4*c],n=e[4*c+1],r=e[4*c+2],i=e[4*c+3],c<e.length/4-1?(a=e[4*(c+1)],o=e[4*(c+1)+1],s=e[4*(c+1)+2],l=e[4*(c+1)+3]):(a=e[0],o=e[1],s=e[2],l=e[3]);var h=Rt(t,n,r,i,a,o,s,l,!0);u[2*c]=h[0],u[2*c+1]=h[1]}return u},It=function(e,t){for(var n,r,i,a,o=new Array(2*e.length),s=0;s<e.length/2;s++){n=e[2*s],r=e[2*s+1],s<e.length/2-1?(i=e[2*(s+1)],a=e[2*(s+1)+1]):(i=e[0],a=e[1]);var l=a-r,u=-(i-n),c=Math.sqrt(l*l+u*u),h=l/c,d=u/c;o[4*s]=n+h*t,o[4*s+1]=r+d*t,o[4*s+2]=i+h*t,o[4*s+3]=a+d*t}return o},Mt=function(e,t,n,r,i,a,o){return e-=i,t-=a,(e/=n/2+o)*e+(t/=r/2+o)*t<=1},Ot=function(e,t,n,r,i,a,o){var s=[n-e,r-t],l=[e-i,t-a],u=s[0]*s[0]+s[1]*s[1],c=2*(l[0]*s[0]+l[1]*s[1]),h=c*c-4*u*(l[0]*l[0]+l[1]*l[1]-o*o);if(h<0)return[];var d=(-c+Math.sqrt(h))/(2*u),p=(-c-Math.sqrt(h))/(2*u),g=Math.min(d,p),f=Math.max(d,p),v=[];if(g>=0&&g<=1&&v.push(g),f>=0&&f<=1&&v.push(f),0===v.length)return[];var y=v[0]*s[0]+e,m=v[0]*s[1]+t;return v.length>1?v[0]==v[1]?[y,m]:[y,m,v[1]*s[0]+e,v[1]*s[1]+t]:[y,m]},Pt=function(e,t,n){return t<=e&&e<=n||n<=e&&e<=t?e:e<=t&&t<=n||n<=t&&t<=e?t:n},Rt=function(e,t,n,r,i,a,o,s,l){var u=e-i,c=n-e,h=o-i,d=t-a,p=r-t,g=s-a,f=h*d-g*u,v=c*d-p*u,y=g*c-h*p;if(0!==y){var m=f/y,b=v/y,x=-.001;return x<=m&&m<=1.001&&x<=b&&b<=1.001||l?[e+m*c,t+m*p]:[]}return 0===f||0===v?Pt(e,n,o)===o?[o,s]:Pt(e,n,i)===i?[i,a]:Pt(i,o,n)===n?[n,r]:[]:[]},Bt=function(e,t,n,r,i,a,o,s){var l,u,c,h,d,p,g=[],f=new Array(n.length),v=!0;if(null==a&&(v=!1),v){for(var y=0;y<f.length/2;y++)f[2*y]=n[2*y]*a+r,f[2*y+1]=n[2*y+1]*o+i;if(s>0){var m=It(f,-s);u=St(m)}else u=f}else u=n;for(var b=0;b<u.length/2;b++)c=u[2*b],h=u[2*b+1],b<u.length/2-1?(d=u[2*(b+1)],p=u[2*(b+1)+1]):(d=u[0],p=u[1]),0!==(l=Rt(e,t,r,i,c,h,d,p)).length&&g.push(l[0],l[1]);return g},Ft=function(e,t,n){var r=[e[0]-t[0],e[1]-t[1]],i=Math.sqrt(r[0]*r[0]+r[1]*r[1]),a=(i-n)/i;return a<0&&(a=1e-5),[t[0]+a*r[0],t[1]+a*r[1]]},zt=function(e,t){var n=Yt(e,t);return n=Gt(n)},Gt=function(e){for(var t,n,r=e.length/2,i=1/0,a=1/0,o=-1/0,s=-1/0,l=0;l<r;l++)t=e[2*l],n=e[2*l+1],i=Math.min(i,t),o=Math.max(o,t),a=Math.min(a,n),s=Math.max(s,n);for(var u=2/(o-i),c=2/(s-a),h=0;h<r;h++)t=e[2*h]=e[2*h]*u,n=e[2*h+1]=e[2*h+1]*c,i=Math.min(i,t),o=Math.max(o,t),a=Math.min(a,n),s=Math.max(s,n);if(a<-1)for(var d=0;d<r;d++)n=e[2*d+1]=e[2*d+1]+(-1-a);return e},Yt=function(e,t){var n=1/e*2*Math.PI,r=e%2==0?Math.PI/2+n/2:Math.PI/2;r+=t;for(var i,a=new Array(2*e),o=0;o<e;o++)i=o*n+r,a[2*o]=Math.cos(i),a[2*o+1]=Math.sin(-i);return a},Xt=function(e,t){return Math.min(e/4,t/4,8)},Vt=function(e,t){return Math.min(e/10,t/10,8)},Ut=function(e,t){return{heightOffset:Math.min(15,.05*t),widthOffset:Math.min(100,.25*e),ctrlPtOffsetPct:.05}},jt=Me({dampingFactor:.8,precision:1e-6,iterations:200,weight:function(e){return 1}}),qt={pageRank:function(e){for(var t=jt(e),n=t.dampingFactor,r=t.precision,i=t.iterations,a=t.weight,o=this._private.cy,s=this.byGroup(),l=s.nodes,u=s.edges,c=l.length,h=c*c,d=u.length,p=new Array(h),g=new Array(c),f=(1-n)/c,v=0;v<c;v++){for(var y=0;y<c;y++){p[v*c+y]=0}g[v]=0}for(var m=0;m<d;m++){var b=u[m],x=b.data("source"),w=b.data("target");if(x!==w){var E=l.indexOfId(x),_=l.indexOfId(w),T=a(b);p[_*c+E]+=T,g[E]+=T}}for(var D=1/c+f,C=0;C<c;C++)if(0===g[C])for(var N=0;N<c;N++){p[N*c+C]=D}else for(var A=0;A<c;A++){var L=A*c+C;p[L]=p[L]/g[C]+f}for(var k,S=new Array(c),I=new Array(c),M=0;M<c;M++)S[M]=1;for(var O=0;O<i;O++){for(var P=0;P<c;P++)I[P]=0;for(var R=0;R<c;R++)for(var B=0;B<c;B++){var F=R*c+B;I[R]+=p[F]*S[B]}ht(I),k=S,S=I,I=k;for(var z=0,G=0;G<c;G++){var Y=k[G]-S[G];z+=Y*Y}if(z<r)break}return{rank:function(e){return e=o.collection(e)[0],S[l.indexOf(e)]}}}},Ht=Me({root:null,weight:function(e){return 1},directed:!1,alpha:0}),Wt={degreeCentralityNormalized:function(e){e=Ht(e);var t=this.cy(),n=this.nodes(),r=n.length;if(e.directed){for(var i={},a={},o=0,s=0,l=0;l<r;l++){var u=n[l],c=u.id();e.root=u;var h=this.degreeCentrality(e);o<h.indegree&&(o=h.indegree),s<h.outdegree&&(s=h.outdegree),i[c]=h.indegree,a[c]=h.outdegree}return{indegree:function(e){return 0==o?0:(A(e)&&(e=t.filter(e)),i[e.id()]/o)},outdegree:function(e){return 0===s?0:(A(e)&&(e=t.filter(e)),a[e.id()]/s)}}}for(var d={},p=0,g=0;g<r;g++){var f=n[g];e.root=f;var v=this.degreeCentrality(e);p<v.degree&&(p=v.degree),d[f.id()]=v.degree}return{degree:function(e){return 0===p?0:(A(e)&&(e=t.filter(e)),d[e.id()]/p)}}},degreeCentrality:function(e){e=Ht(e);var t=this.cy(),n=this,r=e,i=r.root,a=r.weight,o=r.directed,s=r.alpha;if(i=t.collection(i)[0],o){for(var l=i.connectedEdges(),u=l.filter((function(e){return e.target().same(i)&&n.has(e)})),c=l.filter((function(e){return e.source().same(i)&&n.has(e)})),h=u.length,d=c.length,p=0,g=0,f=0;f<u.length;f++)p+=a(u[f]);for(var v=0;v<c.length;v++)g+=a(c[v]);return{indegree:Math.pow(h,1-s)*Math.pow(p,s),outdegree:Math.pow(d,1-s)*Math.pow(g,s)}}for(var y=i.connectedEdges().intersection(n),m=y.length,b=0,x=0;x<y.length;x++)b+=a(y[x]);return{degree:Math.pow(m,1-s)*Math.pow(b,s)}}};Wt.dc=Wt.degreeCentrality,Wt.dcn=Wt.degreeCentralityNormalised=Wt.degreeCentralityNormalized;var $t=Me({harmonic:!0,weight:function(){return 1},directed:!1,root:null}),Kt={closenessCentralityNormalized:function(e){for(var t=$t(e),n=t.harmonic,r=t.weight,i=t.directed,a=this.cy(),o={},s=0,l=this.nodes(),u=this.floydWarshall({weight:r,directed:i}),c=0;c<l.length;c++){for(var h=0,d=l[c],p=0;p<l.length;p++)if(c!==p){var g=u.distance(d,l[p]);h+=n?1/g:g}n||(h=1/h),s<h&&(s=h),o[d.id()]=h}return{closeness:function(e){return 0==s?0:(e=A(e)?a.filter(e)[0].id():e.id(),o[e]/s)}}},closenessCentrality:function(e){var t=$t(e),n=t.root,r=t.weight,i=t.directed,a=t.harmonic;n=this.filter(n)[0];for(var o=this.dijkstra({root:n,weight:r,directed:i}),s=0,l=this.nodes(),u=0;u<l.length;u++){var c=l[u];if(!c.same(n)){var h=o.distanceTo(c);s+=a?1/h:h}}return a?s:1/s}};Kt.cc=Kt.closenessCentrality,Kt.ccn=Kt.closenessCentralityNormalised=Kt.closenessCentralityNormalized;var Zt=Me({weight:null,directed:!1}),Qt={betweennessCentrality:function(e){for(var t=Zt(e),n=t.directed,r=t.weight,i=null!=r,a=this.cy(),o=this.nodes(),s={},l={},u=0,h=function(e,t){l[e]=t,t>u&&(u=t)},d=function(e){return l[e]},p=0;p<o.length;p++){var g=o[p],f=g.id();s[f]=n?g.outgoers().nodes():g.openNeighborhood().nodes(),h(f,0)}for(var v=function(e){for(var t=o[e].id(),n=[],l={},u={},p={},g=new c.default((function(e,t){return p[e]-p[t]})),f=0;f<o.length;f++){var v=o[f].id();l[v]=[],u[v]=0,p[v]=1/0}for(u[t]=1,p[t]=0,g.push(t);!g.empty();){var y=g.pop();if(n.push(y),i)for(var m=0;m<s[y].length;m++){var b=s[y][m],x=a.getElementById(y),w=void 0;w=x.edgesTo(b).length>0?x.edgesTo(b)[0]:b.edgesTo(x)[0];var E=r(w);b=b.id(),p[b]>p[y]+E&&(p[b]=p[y]+E,g.nodes.indexOf(b)<0?g.push(b):g.updateItem(b),u[b]=0,l[b]=[]),p[b]==p[y]+E&&(u[b]=u[b]+u[y],l[b].push(y))}else for(var _=0;_<s[y].length;_++){var T=s[y][_].id();p[T]==1/0&&(g.push(T),p[T]=p[y]+1),p[T]==p[y]+1&&(u[T]=u[T]+u[y],l[T].push(y))}}for(var D={},C=0;C<o.length;C++)D[o[C].id()]=0;for(;n.length>0;){for(var N=n.pop(),A=0;A<l[N].length;A++){var L=l[N][A];D[L]=D[L]+u[L]/u[N]*(1+D[N])}N!=o[e].id()&&h(N,d(N)+D[N])}},y=0;y<o.length;y++)v(y);var m={betweenness:function(e){var t=a.collection(e).id();return d(t)},betweennessNormalized:function(e){if(0==u)return 0;var t=a.collection(e).id();return d(t)/u}};return m.betweennessNormalised=m.betweennessNormalized,m}};Qt.bc=Qt.betweennessCentrality;var Jt=Me({expandFactor:2,inflateFactor:2,multFactor:1,maxIterations:20,attributes:[function(e){return 1}]}),en=function(e,t){for(var n=0,r=0;r<t.length;r++)n+=t[r](e);return n},tn=function(e,t){for(var n,r=0;r<t;r++){n=0;for(var i=0;i<t;i++)n+=e[i*t+r];for(var a=0;a<t;a++)e[a*t+r]=e[a*t+r]/n}},nn=function(e,t,n){for(var r=new Array(n*n),i=0;i<n;i++){for(var a=0;a<n;a++)r[i*n+a]=0;for(var o=0;o<n;o++)for(var s=0;s<n;s++)r[i*n+s]+=e[i*n+o]*t[o*n+s]}return r},rn=function(e,t,n){for(var r=e.slice(0),i=1;i<n;i++)e=nn(e,r,t);return e},an=function(e,t,n){for(var r=new Array(t*t),i=0;i<t*t;i++)r[i]=Math.pow(e[i],n);return tn(r,t),r},on=function(e,t,n,r){for(var i=0;i<n;i++){if(Math.round(e[i]*Math.pow(10,r))/Math.pow(10,r)!==Math.round(t[i]*Math.pow(10,r))/Math.pow(10,r))return!1}return!0},sn=function(e,t){for(var n=0;n<e.length;n++)if(!t[n]||e[n].id()!==t[n].id())return!1;return!0},ln=function(e){for(var t=this.nodes(),n=this.edges(),r=this.cy(),i=function(e){return Jt(e)}(e),a={},o=0;o<t.length;o++)a[t[o].id()]=o;for(var s,l=t.length,u=l*l,c=new Array(u),h=0;h<u;h++)c[h]=0;for(var d=0;d<n.length;d++){var p=n[d],g=a[p.source().id()],f=a[p.target().id()],v=en(p,i.attributes);c[g*l+f]+=v,c[f*l+g]+=v}!function(e,t,n){for(var r=0;r<t;r++)e[r*t+r]=n}(c,l,i.multFactor),tn(c,l);for(var y=!0,m=0;y&&m<i.maxIterations;)y=!1,s=rn(c,l,i.expandFactor),c=an(s,l,i.inflateFactor),on(c,s,u,4)||(y=!0),m++;var b=function(e,t,n,r){for(var i=[],a=0;a<t;a++){for(var o=[],s=0;s<t;s++)Math.round(1e3*e[a*t+s])/1e3>0&&o.push(n[s]);0!==o.length&&i.push(r.collection(o))}return i}(c,l,t,r);return b=function(e){for(var t=0;t<e.length;t++)for(var n=0;n<e.length;n++)t!=n&&sn(e[t],e[n])&&e.splice(n,1);return e}(b),b},un={markovClustering:ln,mcl:ln},cn=function(e){return e},hn=function(e,t){return Math.abs(t-e)},dn=function(e,t,n){return e+hn(t,n)},pn=function(e,t,n){return e+Math.pow(n-t,2)},gn=function(e){return Math.sqrt(e)},fn=function(e,t,n){return Math.max(e,hn(t,n))},vn=function(e,t,n,r,i){for(var a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:cn,o=r,s=0;s<e;s++)o=i(o,t(s),n(s));return a(o)},yn={euclidean:function(e,t,n){return e>=2?vn(e,t,n,0,pn,gn):vn(e,t,n,0,dn)},squaredEuclidean:function(e,t,n){return vn(e,t,n,0,pn)},manhattan:function(e,t,n){return vn(e,t,n,0,dn)},max:function(e,t,n){return vn(e,t,n,-1/0,fn)}};function mn(e,t,n,r,i,a){var o;return o=L(e)?e:yn[e]||yn.euclidean,0===t&&L(e)?o(i,a):o(t,n,r,i,a)}yn["squared-euclidean"]=yn.squaredEuclidean,yn.squaredeuclidean=yn.squaredEuclidean;var bn=Me({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),xn=function(e){return bn(e)},wn=function(e,t,n,r,i){var a="kMedoids"!==i?function(e){return n[e]}:function(e){return r[e](n)},o=n,s=t;return mn(e,r.length,a,(function(e){return r[e](t)}),o,s)},En=function(e,t,n){for(var r=n.length,i=new Array(r),a=new Array(r),o=new Array(t),s=null,l=0;l<r;l++)i[l]=e.min(n[l]).value,a[l]=e.max(n[l]).value;for(var u=0;u<t;u++){s=[];for(var c=0;c<r;c++)s[c]=Math.random()*(a[c]-i[c])+i[c];o[u]=s}return o},_n=function(e,t,n,r,i){for(var a=1/0,o=0,s=0;s<t.length;s++){var l=wn(n,e,t[s],r,i);l<a&&(a=l,o=s)}return o},Tn=function(e,t,n){for(var r=[],i=null,a=0;a<t.length;a++)n[(i=t[a]).id()]===e&&r.push(i);return r},Dn=function(e,t,n){for(var r=0;r<e.length;r++)for(var i=0;i<e[r].length;i++){if(Math.abs(e[r][i]-t[r][i])>n)return!1}return!0},Cn=function(e,t,n){for(var r=0;r<n;r++)if(e===t[r])return!0;return!1},Nn=function(e,t){var n=new Array(t);if(e.length<50)for(var r=0;r<t;r++){for(var i=e[Math.floor(Math.random()*e.length)];Cn(i,n,r);)i=e[Math.floor(Math.random()*e.length)];n[r]=i}else for(var a=0;a<t;a++)n[a]=e[Math.floor(Math.random()*e.length)];return n},An=function(e,t,n){for(var r=0,i=0;i<t.length;i++)r+=wn("manhattan",t[i],e,n,"kMedoids");return r},Ln=function(e,t,n,r,i){for(var a,o,s=0;s<t.length;s++)for(var l=0;l<e.length;l++)r[s][l]=Math.pow(n[s][l],i.m);for(var u=0;u<e.length;u++)for(var c=0;c<i.attributes.length;c++){a=0,o=0;for(var h=0;h<t.length;h++)a+=r[h][u]*i.attributes[c](t[h]),o+=r[h][u];e[u][c]=a/o}},kn=function(e,t,n,r,i){for(var a=0;a<e.length;a++)t[a]=e[a].slice();for(var o,s,l,u=2/(i.m-1),c=0;c<n.length;c++)for(var h=0;h<r.length;h++){o=0;for(var d=0;d<n.length;d++)s=wn(i.distance,r[h],n[c],i.attributes,"cmeans"),l=wn(i.distance,r[h],n[d],i.attributes,"cmeans"),o+=Math.pow(s/l,u);e[h][c]=1/o}},Sn=function(e){var t,n,r,i,a,o=this.cy(),s=this.nodes(),l=xn(e);i=new Array(s.length);for(var u=0;u<s.length;u++)i[u]=new Array(l.k);r=new Array(s.length);for(var c=0;c<s.length;c++)r[c]=new Array(l.k);for(var h=0;h<s.length;h++){for(var d=0,p=0;p<l.k;p++)r[h][p]=Math.random(),d+=r[h][p];for(var g=0;g<l.k;g++)r[h][g]=r[h][g]/d}n=new Array(l.k);for(var f=0;f<l.k;f++)n[f]=new Array(l.attributes.length);a=new Array(s.length);for(var v=0;v<s.length;v++)a[v]=new Array(l.k);for(var y=!0,m=0;y&&m<l.maxIterations;)y=!1,Ln(n,s,r,a,l),kn(r,i,n,s,l),Dn(r,i,l.sensitivityThreshold)||(y=!0),m++;return t=function(e,t,n,r){for(var i,a,o=new Array(n.k),s=0;s<o.length;s++)o[s]=[];for(var l=0;l<t.length;l++){i=-1/0,a=-1;for(var u=0;u<t[0].length;u++)t[l][u]>i&&(i=t[l][u],a=u);o[a].push(e[l])}for(var c=0;c<o.length;c++)o[c]=r.collection(o[c]);return o}(s,r,l,o),{clusters:t,degreeOfMembership:r}},In={kMeans:function(e){var t,n=this.cy(),r=this.nodes(),i=null,a=xn(e),o=new Array(a.k),s={};a.testMode?"number"==typeof a.testCentroids?(a.testCentroids,t=En(r,a.k,a.attributes)):t="object"===g(a.testCentroids)?a.testCentroids:En(r,a.k,a.attributes):t=En(r,a.k,a.attributes);for(var l,u,c,h=!0,d=0;h&&d<a.maxIterations;){for(var p=0;p<r.length;p++)s[(i=r[p]).id()]=_n(i,t,a.distance,a.attributes,"kMeans");h=!1;for(var f=0;f<a.k;f++){var v=Tn(f,r,s);if(0!==v.length){for(var y=a.attributes.length,m=t[f],b=new Array(y),x=new Array(y),w=0;w<y;w++){x[w]=0;for(var E=0;E<v.length;E++)i=v[E],x[w]+=a.attributes[w](i);b[w]=x[w]/v.length,l=b[w],u=m[w],c=a.sensitivityThreshold,Math.abs(u-l)<=c||(h=!0)}t[f]=b,o[f]=n.collection(v)}}d++}return o},kMedoids:function(e){var t,n,r=this.cy(),i=this.nodes(),a=null,o=xn(e),s=new Array(o.k),l={},u=new Array(o.k);o.testMode?"number"==typeof o.testCentroids||(t="object"===g(o.testCentroids)?o.testCentroids:Nn(i,o.k)):t=Nn(i,o.k);for(var c=!0,h=0;c&&h<o.maxIterations;){for(var d=0;d<i.length;d++)l[(a=i[d]).id()]=_n(a,t,o.distance,o.attributes,"kMedoids");c=!1;for(var p=0;p<t.length;p++){var f=Tn(p,i,l);if(0!==f.length){u[p]=An(t[p],f,o.attributes);for(var v=0;v<f.length;v++)(n=An(f[v],f,o.attributes))<u[p]&&(u[p]=n,t[p]=f[v],c=!0);s[p]=r.collection(f)}}h++}return s},fuzzyCMeans:Sn,fcm:Sn},Mn=Me({distance:"euclidean",linkage:"min",mode:"threshold",threshold:1/0,addDendrogram:!1,dendrogramDepth:0,attributes:[]}),On={single:"min",complete:"max"},Pn=function(e,t,n,r,i){for(var a,o=0,s=1/0,l=i.attributes,u=function(e,t){return mn(i.distance,l.length,(function(t){return l[t](e)}),(function(e){return l[e](t)}),e,t)},c=0;c<e.length;c++){var h=e[c].key,d=n[h][r[h]];d<s&&(o=h,s=d)}if("threshold"===i.mode&&s>=i.threshold||"dendrogram"===i.mode&&1===e.length)return!1;var p,g=t[o],f=t[r[o]];p="dendrogram"===i.mode?{left:g,right:f,key:g.key}:{value:g.value.concat(f.value),key:g.key},e[g.index]=p,e.splice(f.index,1),t[g.key]=p;for(var v=0;v<e.length;v++){var y=e[v];g.key===y.key?a=1/0:"min"===i.linkage?(a=n[g.key][y.key],n[g.key][y.key]>n[f.key][y.key]&&(a=n[f.key][y.key])):"max"===i.linkage?(a=n[g.key][y.key],n[g.key][y.key]<n[f.key][y.key]&&(a=n[f.key][y.key])):a="mean"===i.linkage?(n[g.key][y.key]*g.size+n[f.key][y.key]*f.size)/(g.size+f.size):"dendrogram"===i.mode?u(y.value,g.value):u(y.value[0],g.value[0]),n[g.key][y.key]=n[y.key][g.key]=a}for(var m=0;m<e.length;m++){var b=e[m].key;if(r[b]===g.key||r[b]===f.key){for(var x=b,w=0;w<e.length;w++){var E=e[w].key;n[b][E]<n[b][x]&&(x=E)}r[b]=x}e[m].index=m}return g.key=f.key=g.index=f.index=null,!0},Rn=function e(t,n,r){t&&(t.value?n.push(t.value):(t.left&&e(t.left,n),t.right&&e(t.right,n)))},Bn=function e(t,n){if(!t)return"";if(t.left&&t.right){var r=e(t.left,n),i=e(t.right,n),a=n.add({group:"nodes",data:{id:r+","+i}});return n.add({group:"edges",data:{source:r,target:a.id()}}),n.add({group:"edges",data:{source:i,target:a.id()}}),a.id()}return t.value?t.value.id():void 0},Fn=function e(t,n,r){if(!t)return[];var i=[],a=[],o=[];return 0===n?(t.left&&Rn(t.left,i),t.right&&Rn(t.right,a),o=i.concat(a),[r.collection(o)]):1===n?t.value?[r.collection(t.value)]:(t.left&&Rn(t.left,i),t.right&&Rn(t.right,a),[r.collection(i),r.collection(a)]):t.value?[r.collection(t.value)]:(t.left&&(i=e(t.left,n-1,r)),t.right&&(a=e(t.right,n-1,r)),i.concat(a))},zn=function(e){for(var t=this.cy(),n=this.nodes(),r=function(e){var t=Mn(e),n=On[t.linkage];return null!=n&&(t.linkage=n),t}(e),i=r.attributes,a=function(e,t){return mn(r.distance,i.length,(function(t){return i[t](e)}),(function(e){return i[e](t)}),e,t)},o=[],s=[],l=[],u=[],c=0;c<n.length;c++){var h={value:"dendrogram"===r.mode?n[c]:[n[c]],key:c,index:c};o[c]=h,u[c]=h,s[c]=[],l[c]=0}for(var d=0;d<o.length;d++)for(var p=0;p<=d;p++){var g=void 0;g="dendrogram"===r.mode?d===p?1/0:a(o[d].value,o[p].value):d===p?1/0:a(o[d].value[0],o[p].value[0]),s[d][p]=g,s[p][d]=g,g<s[d][l[d]]&&(l[d]=p)}for(var f,v=Pn(o,u,s,l,r);v;)v=Pn(o,u,s,l,r);return"dendrogram"===r.mode?(f=Fn(o[0],r.dendrogramDepth,t),r.addDendrogram&&Bn(o[0],t)):(f=new Array(o.length),o.forEach((function(e,n){e.key=e.index=null,f[n]=t.collection(e.value)}))),f},Gn={hierarchicalClustering:zn,hca:zn},Yn=Me({distance:"euclidean",preference:"median",damping:.8,maxIterations:1e3,minIterations:100,attributes:[]}),Xn=function(e,t,n,r){var i=function(e,t){return r[t](e)};return-mn(e,r.length,(function(e){return i(t,e)}),(function(e){return i(n,e)}),t,n)},Vn=function(e,t){var n=null;return n="median"===t?function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];arguments.length>3&&void 0!==arguments[3]&&!arguments[3]?(n<e.length&&e.splice(n,e.length-n),t>0&&e.splice(0,t)):e=e.slice(t,n);for(var a=0,o=e.length-1;o>=0;o--){var s=e[o];i?isFinite(s)||(e[o]=-1/0,a++):e.splice(o,1)}r&&e.sort((function(e,t){return e-t}));var l=e.length,u=Math.floor(l/2);return l%2!=0?e[u+1+a]:(e[u-1+a]+e[u+a])/2}(e):"mean"===t?function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=0,i=0,a=t;a<n;a++){var o=e[a];isFinite(o)&&(r+=o,i++)}return r/i}(e):"min"===t?function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=1/0,i=t;i<n;i++){var a=e[i];isFinite(a)&&(r=Math.min(a,r))}return r}(e):"max"===t?function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=-1/0,i=t;i<n;i++){var a=e[i];isFinite(a)&&(r=Math.max(a,r))}return r}(e):t,n},Un=function(e,t,n){for(var r=[],i=0;i<e;i++){for(var a=-1,o=-1/0,s=0;s<n.length;s++){var l=n[s];t[i*e+l]>o&&(a=l,o=t[i*e+l])}a>0&&r.push(a)}for(var u=0;u<n.length;u++)r[n[u]]=n[u];return r},jn=function(e){for(var t,n,r,i,a,o,s=this.cy(),l=this.nodes(),u=function(e){var t=e.damping,n=e.preference;.5<=t&&t<1||Ce("Damping must range on [0.5, 1). Got: ".concat(t));var r=["median","mean","min","max"];return r.some((function(e){return e===n}))||I(n)||Ce("Preference must be one of [".concat(r.map((function(e){return"'".concat(e,"'")})).join(", "),"] or a number. Got: ").concat(n)),Yn(e)}(e),c={},h=0;h<l.length;h++)c[l[h].id()]=h;n=(t=l.length)*t,r=new Array(n);for(var d=0;d<n;d++)r[d]=-1/0;for(var p=0;p<t;p++)for(var g=0;g<t;g++)p!==g&&(r[p*t+g]=Xn(u.distance,l[p],l[g],u.attributes));i=Vn(r,u.preference);for(var f=0;f<t;f++)r[f*t+f]=i;a=new Array(n);for(var v=0;v<n;v++)a[v]=0;o=new Array(n);for(var y=0;y<n;y++)o[y]=0;for(var m=new Array(t),b=new Array(t),x=new Array(t),w=0;w<t;w++)m[w]=0,b[w]=0,x[w]=0;for(var E,_=new Array(t*u.minIterations),T=0;T<_.length;T++)_[T]=0;for(E=0;E<u.maxIterations;E++){for(var D=0;D<t;D++){for(var C=-1/0,N=-1/0,A=-1,L=0,k=0;k<t;k++)m[k]=a[D*t+k],(L=o[D*t+k]+r[D*t+k])>=C?(N=C,C=L,A=k):L>N&&(N=L);for(var S=0;S<t;S++)a[D*t+S]=(1-u.damping)*(r[D*t+S]-C)+u.damping*m[S];a[D*t+A]=(1-u.damping)*(r[D*t+A]-N)+u.damping*m[A]}for(var M=0;M<t;M++){for(var O=0,P=0;P<t;P++)m[P]=o[P*t+M],b[P]=Math.max(0,a[P*t+M]),O+=b[P];O-=b[M],b[M]=a[M*t+M],O+=b[M];for(var R=0;R<t;R++)o[R*t+M]=(1-u.damping)*Math.min(0,O-b[R])+u.damping*m[R];o[M*t+M]=(1-u.damping)*(O-b[M])+u.damping*m[M]}for(var B=0,F=0;F<t;F++){var z=o[F*t+F]+a[F*t+F]>0?1:0;_[E%u.minIterations*t+F]=z,B+=z}if(B>0&&(E>=u.minIterations-1||E==u.maxIterations-1)){for(var G=0,Y=0;Y<t;Y++){x[Y]=0;for(var X=0;X<u.minIterations;X++)x[Y]+=_[X*t+Y];0!==x[Y]&&x[Y]!==u.minIterations||G++}if(G===t)break}}for(var V=function(e,t,n){for(var r=[],i=0;i<e;i++)t[i*e+i]+n[i*e+i]>0&&r.push(i);return r}(t,a,o),U=function(e,t,n){for(var r=Un(e,t,n),i=0;i<n.length;i++){for(var a=[],o=0;o<r.length;o++)r[o]===n[i]&&a.push(o);for(var s=-1,l=-1/0,u=0;u<a.length;u++){for(var c=0,h=0;h<a.length;h++)c+=t[a[h]*e+a[u]];c>l&&(s=u,l=c)}n[i]=a[s]}return Un(e,t,n)}(t,r,V),j={},q=0;q<V.length;q++)j[V[q]]=[];for(var H=0;H<l.length;H++){var W=U[c[l[H].id()]];null!=W&&j[W].push(l[H])}for(var $=new Array(V.length),K=0;K<V.length;K++)$[K]=s.collection(j[V[K]]);return $},qn={affinityPropagation:jn,ap:jn},Hn=Me({root:void 0,directed:!1}),Wn=function(){var e=this,t={},n=0,r=0,i=[],a=[],o={},s=function s(l,u,c){l===c&&(r+=1),t[u]={id:n,low:n++,cutVertex:!1};var h,d,p,g,f=e.getElementById(u).connectedEdges().intersection(e);0===f.size()?i.push(e.spawn(e.getElementById(u))):f.forEach((function(n){h=n.source().id(),d=n.target().id(),(p=h===u?d:h)!==c&&(g=n.id(),o[g]||(o[g]=!0,a.push({x:u,y:p,edge:n})),p in t?t[u].low=Math.min(t[u].low,t[p].id):(s(l,p,u),t[u].low=Math.min(t[u].low,t[p].low),t[u].id<=t[p].low&&(t[u].cutVertex=!0,function(n,r){for(var o=a.length-1,s=[],l=e.spawn();a[o].x!=n||a[o].y!=r;)s.push(a.pop().edge),o--;s.push(a.pop().edge),s.forEach((function(n){var r=n.connectedNodes().intersection(e);l.merge(n),r.forEach((function(n){var r=n.id(),i=n.connectedEdges().intersection(e);l.merge(n),t[r].cutVertex?l.merge(i.filter((function(e){return e.isLoop()}))):l.merge(i)}))})),i.push(l)}(u,p))))}))};e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||(r=0,s(n,n),t[n].cutVertex=r>1)}}));var l=Object.keys(t).filter((function(e){return t[e].cutVertex})).map((function(t){return e.getElementById(t)}));return{cut:e.spawn(l),components:i}},$n=function(){var e=this,t={},n=0,r=[],i=[],a=e.spawn(e),o=function o(s){if(i.push(s),t[s]={index:n,low:n++,explored:!1},e.getElementById(s).connectedEdges().intersection(e).forEach((function(e){var n=e.target().id();n!==s&&(n in t||o(n),t[n].explored||(t[s].low=Math.min(t[s].low,t[n].low)))})),t[s].index===t[s].low){for(var l=e.spawn();;){var u=i.pop();if(l.merge(e.getElementById(u)),t[u].low=t[s].index,t[u].explored=!0,u===s)break}var c=l.edgesWith(l),h=l.merge(c);r.push(h),a=a.difference(h)}};return e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||o(n)}})),{cut:a,components:r}},Kn={};[Ve,je,qe,We,Ke,Qe,nt,qt,Wt,Kt,Qt,un,In,Gn,qn,{hierholzer:function(e){if(!S(e)){var t=arguments;e={root:t[0],directed:t[1]}}var n,r,i,a=Hn(e),o=a.root,s=a.directed,l=this,u=!1;o&&(i=A(o)?this.filter(o)[0].id():o[0].id());var c={},h={};s?l.forEach((function(e){var t=e.id();if(e.isNode()){var i=e.indegree(!0),a=e.outdegree(!0),o=i-a,s=a-i;1==o?n?u=!0:n=t:1==s?r?u=!0:r=t:(s>1||o>1)&&(u=!0),c[t]=[],e.outgoers().forEach((function(e){e.isEdge()&&c[t].push(e.id())}))}else h[t]=[void 0,e.target().id()]})):l.forEach((function(e){var t=e.id();e.isNode()?(e.degree(!0)%2&&(n?r?u=!0:r=t:n=t),c[t]=[],e.connectedEdges().forEach((function(e){return c[t].push(e.id())}))):h[t]=[e.source().id(),e.target().id()]}));var d={found:!1,trail:void 0};if(u)return d;if(r&&n)if(s){if(i&&r!=i)return d;i=r}else{if(i&&r!=i&&n!=i)return d;i||(i=r)}else i||(i=l[0].id());var p=function(e){for(var t,n,r,i=e,a=[e];c[i].length;)t=c[i].shift(),n=h[t][0],i!=(r=h[t][1])?(c[r]=c[r].filter((function(e){return e!=t})),i=r):s||i==n||(c[n]=c[n].filter((function(e){return e!=t})),i=n),a.unshift(t),a.unshift(i);return a},g=[],f=[];for(f=p(i);1!=f.length;)0==c[f[0]].length?(g.unshift(l.getElementById(f.shift())),g.unshift(l.getElementById(f.shift()))):f=p(f.shift()).concat(f);for(var v in g.unshift(l.getElementById(f.shift())),c)if(c[v].length)return d;return d.found=!0,d.trail=this.spawn(g,!0),d}},{hopcroftTarjanBiconnected:Wn,htbc:Wn,htb:Wn,hopcroftTarjanBiconnectedComponents:Wn},{tarjanStronglyConnected:$n,tsc:$n,tscc:$n,tarjanStronglyConnectedComponents:$n}].forEach((function(e){Q(Kn,e)}));var Zn=function e(t){if(!(this instanceof e))return new e(t);this.id="Thenable/1.0.7",this.state=0,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},"function"==typeof t&&t.call(this,this.fulfill.bind(this),this.reject.bind(this))};Zn.prototype={fulfill:function(e){return Qn(this,1,"fulfillValue",e)},reject:function(e){return Qn(this,2,"rejectReason",e)},then:function(e,t){var n=this,r=new Zn;return n.onFulfilled.push(tr(e,r,"fulfill")),n.onRejected.push(tr(t,r,"reject")),Jn(n),r.proxy}};var Qn=function(e,t,n,r){return 0===e.state&&(e.state=t,e[n]=r,Jn(e)),e},Jn=function(e){1===e.state?er(e,"onFulfilled",e.fulfillValue):2===e.state&&er(e,"onRejected",e.rejectReason)},er=function(e,t,n){if(0!==e[t].length){var r=e[t];e[t]=[];var i=function(){for(var e=0;e<r.length;e++)r[e](n)};"function"==typeof setImmediate?setImmediate(i):setTimeout(i,0)}},tr=function(e,t,n){return function(r){if("function"!=typeof e)t[n].call(t,r);else{var i;try{i=e(r)}catch(a){return void t.reject(a)}nr(t,i)}}},nr=function e(t,n){if(t!==n&&t.proxy!==n){var r;if("object"===g(n)&&null!==n||"function"==typeof n)try{r=n.then}catch(a){return void t.reject(a)}if("function"!=typeof r)t.fulfill(n);else{var i=!1;try{r.call(n,(function(r){i||(i=!0,r===n?t.reject(new TypeError("circular thenable chain")):e(t,r))}),(function(e){i||(i=!0,t.reject(e))}))}catch(a){i||t.reject(a)}}}else t.reject(new TypeError("cannot resolve promise with itself"))};Zn.all=function(e){return new Zn((function(t,n){for(var r=new Array(e.length),i=0,a=function(n,a){r[n]=a,++i===e.length&&t(r)},o=0;o<e.length;o++)!function(t){var r=e[t];null!=r&&null!=r.then?r.then((function(e){a(t,e)}),(function(e){n(e)})):a(t,r)}(o)}))},Zn.resolve=function(e){return new Zn((function(t,n){t(e)}))},Zn.reject=function(e){return new Zn((function(t,n){n(e)}))};var rr="undefined"!=typeof Promise?Promise:Zn,ir=function(e,t,n){var r=B(e),i=!r,a=this._private=Q({duration:1e3},t,n);if(a.target=e,a.style=a.style||a.css,a.started=!1,a.playing=!1,a.hooked=!1,a.applying=!1,a.progress=0,a.completes=[],a.frames=[],a.complete&&L(a.complete)&&a.completes.push(a.complete),i){var o=e.position();a.startPosition=a.startPosition||{x:o.x,y:o.y},a.startStyle=a.startStyle||e.cy().style().getAnimationStartStyle(e,a.style)}if(r){var s=e.pan();a.startPan={x:s.x,y:s.y},a.startZoom=e.zoom()}this.length=1,this[0]=this},ar=ir.prototype;Q(ar,{instanceString:function(){return"animation"},hook:function(){var e=this._private;if(!e.hooked){var t=e.target._private.animation;(e.queue?t.queue:t.current).push(this),O(e.target)&&e.target.cy().addToAnimationPool(e.target),e.hooked=!0}return this},play:function(){var e=this._private;return 1===e.progress&&(e.progress=0),e.playing=!0,e.started=!1,e.stopped=!1,this.hook(),this},playing:function(){return this._private.playing},apply:function(){var e=this._private;return e.applying=!0,e.started=!1,e.stopped=!1,this.hook(),this},applying:function(){return this._private.applying},pause:function(){var e=this._private;return e.playing=!1,e.started=!1,this},stop:function(){var e=this._private;return e.playing=!1,e.started=!1,e.stopped=!0,this},rewind:function(){return this.progress(0)},fastforward:function(){return this.progress(1)},time:function(e){var t=this._private;return void 0===e?t.progress*t.duration:this.progress(e/t.duration)},progress:function(e){var t=this._private,n=t.playing;return void 0===e?t.progress:(n&&this.pause(),t.progress=e,t.started=!1,n&&this.play(),this)},completed:function(){return 1===this._private.progress},reverse:function(){var e=this._private,t=e.playing;t&&this.pause(),e.progress=1-e.progress,e.started=!1;var n=function(t,n){var r=e[t];null!=r&&(e[t]=e[n],e[n]=r)};if(n("zoom","startZoom"),n("pan","startPan"),n("position","startPosition"),e.style)for(var r=0;r<e.style.length;r++){var i=e.style[r],a=i.name,o=e.startStyle[a];e.startStyle[a]=i,e.style[r]=o}return t&&this.play(),this},promise:function(e){var t,n=this._private;if("frame"===e)t=n.frames;else t=n.completes;return new rr((function(e,n){t.push((function(){e()}))}))}}),ar.complete=ar.completed,ar.run=ar.play,ar.running=ar.playing;var or={animated:function(){return function(){var e=this,t=void 0!==e.length?e:[e];if(!(this._private.cy||this).styleEnabled())return!1;var n=t[0];return n?n._private.animation.current.length>0:void 0}},clearQueue:function(){return function(){var e=this,t=void 0!==e.length?e:[e];if(!(this._private.cy||this).styleEnabled())return this;for(var n=0;n<t.length;n++){t[n]._private.animation.queue=[]}return this}},delay:function(){return function(e,t){return(this._private.cy||this).styleEnabled()?this.animate({delay:e,duration:e,complete:t}):this}},delayAnimation:function(){return function(e,t){return(this._private.cy||this).styleEnabled()?this.animation({delay:e,duration:e,complete:t}):this}},animation:function(){return function(e,t){var n=this,r=void 0!==n.length,i=r?n:[n],a=this._private.cy||this,o=!r,s=!o;if(!a.styleEnabled())return this;var l=a.style();if(e=Q({},e,t),0===Object.keys(e).length)return new ir(i[0],e);switch(void 0===e.duration&&(e.duration=400),e.duration){case"slow":e.duration=600;break;case"fast":e.duration=200}if(s&&(e.style=l.getPropsList(e.style||e.css),e.css=void 0),s&&null!=e.renderedPosition){var u=e.renderedPosition,c=a.pan(),h=a.zoom();e.position=it(u,h,c)}if(o&&null!=e.panBy){var d=e.panBy,p=a.pan();e.pan={x:p.x+d.x,y:p.y+d.y}}var g=e.center||e.centre;if(o&&null!=g){var f=a.getCenterPan(g.eles,e.zoom);null!=f&&(e.pan=f)}if(o&&null!=e.fit){var v=e.fit,y=a.getFitViewport(v.eles||v.boundingBox,v.padding);null!=y&&(e.pan=y.pan,e.zoom=y.zoom)}if(o&&S(e.zoom)){var m=a.getZoomedViewport(e.zoom);null!=m?(m.zoomed&&(e.zoom=m.zoom),m.panned&&(e.pan=m.pan)):e.zoom=null}return new ir(i[0],e)}},animate:function(){return function(e,t){var n=this,r=void 0!==n.length?n:[n];if(!(this._private.cy||this).styleEnabled())return this;t&&(e=Q({},e,t));for(var i=0;i<r.length;i++){var a=r[i],o=a.animated()&&(void 0===e.queue||e.queue);a.animation(e,o?{queue:!0}:void 0).play()}return this}},stop:function(){return function(e,t){var n=this,r=void 0!==n.length?n:[n],i=this._private.cy||this;if(!i.styleEnabled())return this;for(var a=0;a<r.length;a++){for(var o=r[a]._private,s=o.animation.current,l=0;l<s.length;l++){var u=s[l]._private;t&&(u.duration=0)}e&&(o.animation.queue=[]),t||(o.animation.current=[])}return i.notify("draw"),this}}},sr={data:function(e){return e=Q({},{field:"data",bindingEvent:"data",allowBinding:!1,allowSetting:!1,allowGetting:!1,settingEvent:"data",settingTriggersEvent:!1,triggerFnName:"trigger",immutableKeys:{},updateStyle:!1,beforeGet:function(e){},beforeSet:function(e,t){},onSet:function(e){},canSet:function(e){return!0}},e),function(t,n){var r=e,i=this,a=void 0!==i.length,o=a?i:[i],s=a?i[0]:i;if(A(t)){var l,u=-1!==t.indexOf(".")&&p.default(t);if(r.allowGetting&&void 0===n)return s&&(r.beforeGet(s),l=u&&void 0===s._private[r.field][t]?h.default(s._private[r.field],u):s._private[r.field][t]),l;if(r.allowSetting&&void 0!==n&&!r.immutableKeys[t]){var c=m({},t,n);r.beforeSet(i,c);for(var g=0,f=o.length;g<f;g++){var v=o[g];r.canSet(v)&&(u&&void 0===s._private[r.field][t]?d.default(v._private[r.field],u,n):v._private[r.field][t]=n)}r.updateStyle&&i.updateStyle(),r.onSet(i),r.settingTriggersEvent&&i[r.triggerFnName](r.settingEvent)}}else if(r.allowSetting&&S(t)){var y,b,x=t,w=Object.keys(x);r.beforeSet(i,x);for(var E=0;E<w.length;E++){if(b=x[y=w[E]],!r.immutableKeys[y])for(var _=0;_<o.length;_++){var T=o[_];r.canSet(T)&&(T._private[r.field][y]=b)}}r.updateStyle&&i.updateStyle(),r.onSet(i),r.settingTriggersEvent&&i[r.triggerFnName](r.settingEvent)}else if(r.allowBinding&&L(t)){var D=t;i.on(r.bindingEvent,D)}else if(r.allowGetting&&void 0===t){var C;return s&&(r.beforeGet(s),C=s._private[r.field]),C}return i}},removeData:function(e){return e=Q({},{field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!1,immutableKeys:{}},e),function(t){var n=e,r=this,i=void 0!==r.length?r:[r];if(A(t)){for(var a=t.split(/\s+/),o=a.length,s=0;s<o;s++){var l=a[s];if(!z(l))if(!n.immutableKeys[l])for(var u=0,c=i.length;u<c;u++)i[u]._private[n.field][l]=void 0}n.triggerEvent&&r[n.triggerFnName](n.event)}else if(void 0===t){for(var h=0,d=i.length;h<d;h++)for(var p=i[h]._private[n.field],g=Object.keys(p),f=0;f<g.length;f++){var v=g[f];!n.immutableKeys[v]&&(p[v]=void 0)}n.triggerEvent&&r[n.triggerFnName](n.event)}return r}}},lr={eventAliasesOn:function(e){var t=e;t.addListener=t.listen=t.bind=t.on,t.unlisten=t.unbind=t.off=t.removeListener,t.trigger=t.emit,t.pon=t.promiseOn=function(e,t){var n=this,r=Array.prototype.slice.call(arguments,0);return new rr((function(e,t){var i=r.concat([function(t){n.off.apply(n,a),e(t)}]),a=i.concat([]);n.on.apply(n,i)}))}}},ur={};[or,sr,lr].forEach((function(e){Q(ur,e)}));var cr={animate:ur.animate(),animation:ur.animation(),animated:ur.animated(),clearQueue:ur.clearQueue(),delay:ur.delay(),delayAnimation:ur.delayAnimation(),stop:ur.stop()},hr={classes:function(e){var t=this;if(void 0===e){var n=[];return t[0]._private.classes.forEach((function(e){return n.push(e)})),n}k(e)||(e=(e||"").match(/\S+/g)||[]);for(var r=[],i=new Ge(e),a=0;a<t.length;a++){for(var o=t[a],s=o._private,l=s.classes,u=!1,c=0;c<e.length;c++){var h=e[c];if(!l.has(h)){u=!0;break}}u||(u=l.size!==e.length),u&&(s.classes=i,r.push(o))}return r.length>0&&this.spawn(r).updateStyle().emit("class"),t},addClass:function(e){return this.toggleClass(e,!0)},hasClass:function(e){var t=this[0];return null!=t&&t._private.classes.has(e)},toggleClass:function(e,t){k(e)||(e=e.match(/\S+/g)||[]);for(var n=this,r=void 0===t,i=[],a=0,o=n.length;a<o;a++)for(var s=n[a],l=s._private.classes,u=!1,c=0;c<e.length;c++){var h=e[c],d=l.has(h),p=!1;t||r&&!d?(l.add(h),p=!0):(!t||r&&d)&&(l.delete(h),p=!0),!u&&p&&(i.push(s),u=!0)}return i.length>0&&this.spawn(i).updateStyle().emit("class"),n},removeClass:function(e){return this.toggleClass(e,!1)},flashClass:function(e,t){var n=this;if(null==t)t=250;else if(0===t)return n;return n.addClass(e),setTimeout((function(){n.removeClass(e)}),t),n}};hr.className=hr.classNames=hr.classes;var dr={metaChar:"[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",comparatorOp:"=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",boolOp:"\\?|\\!|\\^",string:"\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*'",number:q,meta:"degree|indegree|outdegree",separator:"\\s*,\\s*",descendant:"\\s+",child:"\\s+>\\s+",subject:"\\$",group:"node|edge|\\*",directedEdge:"\\s+->\\s+",undirectedEdge:"\\s+<->\\s+"};dr.variable="(?:[\\w-.]|(?:\\\\"+dr.metaChar+"))+",dr.className="(?:[\\w-]|(?:\\\\"+dr.metaChar+"))+",dr.value=dr.string+"|"+dr.number,dr.id=dr.variable,function(){var e,t,n;for(e=dr.comparatorOp.split("|"),n=0;n<e.length;n++)t=e[n],dr.comparatorOp+="|@"+t;for(e=dr.comparatorOp.split("|"),n=0;n<e.length;n++)(t=e[n]).indexOf("!")>=0||"="!==t&&(dr.comparatorOp+="|\\!"+t)}();var pr=0,gr=1,fr=2,vr=3,yr=4,mr=5,br=6,xr=7,wr=8,Er=9,_r=10,Tr=11,Dr=12,Cr=13,Nr=14,Ar=15,Lr=16,kr=17,Sr=18,Ir=19,Mr=20,Or=[{selector:":selected",matches:function(e){return e.selected()}},{selector:":unselected",matches:function(e){return!e.selected()}},{selector:":selectable",matches:function(e){return e.selectable()}},{selector:":unselectable",matches:function(e){return!e.selectable()}},{selector:":locked",matches:function(e){return e.locked()}},{selector:":unlocked",matches:function(e){return!e.locked()}},{selector:":visible",matches:function(e){return e.visible()}},{selector:":hidden",matches:function(e){return!e.visible()}},{selector:":transparent",matches:function(e){return e.transparent()}},{selector:":grabbed",matches:function(e){return e.grabbed()}},{selector:":free",matches:function(e){return!e.grabbed()}},{selector:":removed",matches:function(e){return e.removed()}},{selector:":inside",matches:function(e){return!e.removed()}},{selector:":grabbable",matches:function(e){return e.grabbable()}},{selector:":ungrabbable",matches:function(e){return!e.grabbable()}},{selector:":animated",matches:function(e){return e.animated()}},{selector:":unanimated",matches:function(e){return!e.animated()}},{selector:":parent",matches:function(e){return e.isParent()}},{selector:":childless",matches:function(e){return e.isChildless()}},{selector:":child",matches:function(e){return e.isChild()}},{selector:":orphan",matches:function(e){return e.isOrphan()}},{selector:":nonorphan",matches:function(e){return e.isChild()}},{selector:":compound",matches:function(e){return e.isNode()?e.isParent():e.source().isParent()||e.target().isParent()}},{selector:":loop",matches:function(e){return e.isLoop()}},{selector:":simple",matches:function(e){return e.isSimple()}},{selector:":active",matches:function(e){return e.active()}},{selector:":inactive",matches:function(e){return!e.active()}},{selector:":backgrounding",matches:function(e){return e.backgrounding()}},{selector:":nonbackgrounding",matches:function(e){return!e.backgrounding()}}].sort((function(e,t){return function(e,t){return-1*Z(e,t)}(e.selector,t.selector)})),Pr=function(){for(var e,t={},n=0;n<Or.length;n++)t[(e=Or[n]).selector]=e.matches;return t}(),Rr="("+Or.map((function(e){return e.selector})).join("|")+")",Br=function(e){return e.replace(new RegExp("\\\\("+dr.metaChar+")","g"),(function(e,t){return t}))},Fr=function(e,t,n){e[e.length-1]=n},zr=[{name:"group",query:!0,regex:"("+dr.group+")",populate:function(e,t,n){var r=b(n,1)[0];t.checks.push({type:pr,value:"*"===r?r:r+"s"})}},{name:"state",query:!0,regex:Rr,populate:function(e,t,n){var r=b(n,1)[0];t.checks.push({type:xr,value:r})}},{name:"id",query:!0,regex:"\\#("+dr.id+")",populate:function(e,t,n){var r=b(n,1)[0];t.checks.push({type:wr,value:Br(r)})}},{name:"className",query:!0,regex:"\\.("+dr.className+")",populate:function(e,t,n){var r=b(n,1)[0];t.checks.push({type:Er,value:Br(r)})}},{name:"dataExists",query:!0,regex:"\\[\\s*("+dr.variable+")\\s*\\]",populate:function(e,t,n){var r=b(n,1)[0];t.checks.push({type:yr,field:Br(r)})}},{name:"dataCompare",query:!0,regex:"\\[\\s*("+dr.variable+")\\s*("+dr.comparatorOp+")\\s*("+dr.value+")\\s*\\]",populate:function(e,t,n){var r=b(n,3),i=r[0],a=r[1],o=r[2];o=null!=new RegExp("^"+dr.string+"$").exec(o)?o.substring(1,o.length-1):parseFloat(o),t.checks.push({type:vr,field:Br(i),operator:a,value:o})}},{name:"dataBool",query:!0,regex:"\\[\\s*("+dr.boolOp+")\\s*("+dr.variable+")\\s*\\]",populate:function(e,t,n){var r=b(n,2),i=r[0],a=r[1];t.checks.push({type:mr,field:Br(a),operator:i})}},{name:"metaCompare",query:!0,regex:"\\[\\[\\s*("+dr.meta+")\\s*("+dr.comparatorOp+")\\s*("+dr.number+")\\s*\\]\\]",populate:function(e,t,n){var r=b(n,3),i=r[0],a=r[1],o=r[2];t.checks.push({type:br,field:Br(i),operator:a,value:parseFloat(o)})}},{name:"nextQuery",separator:!0,regex:dr.separator,populate:function(e,t){var n=e.currentSubject,r=e.edgeCount,i=e.compoundCount,a=e[e.length-1];return null!=n&&(a.subject=n,e.currentSubject=null),a.edgeCount=r,a.compoundCount=i,e.edgeCount=0,e.compoundCount=0,e[e.length++]={checks:[]}}},{name:"directedEdge",separator:!0,regex:dr.directedEdge,populate:function(e,t){if(null==e.currentSubject){var n={checks:[]},r=t,i={checks:[]};return n.checks.push({type:Tr,source:r,target:i}),Fr(e,0,n),e.edgeCount++,i}var a={checks:[]},o=t,s={checks:[]};return a.checks.push({type:Dr,source:o,target:s}),Fr(e,0,a),e.edgeCount++,s}},{name:"undirectedEdge",separator:!0,regex:dr.undirectedEdge,populate:function(e,t){if(null==e.currentSubject){var n={checks:[]},r=t,i={checks:[]};return n.checks.push({type:_r,nodes:[r,i]}),Fr(e,0,n),e.edgeCount++,i}var a={checks:[]},o=t,s={checks:[]};return a.checks.push({type:Nr,node:o,neighbor:s}),Fr(e,0,a),s}},{name:"child",separator:!0,regex:dr.child,populate:function(e,t){if(null==e.currentSubject){var n={checks:[]},r={checks:[]},i=e[e.length-1];return n.checks.push({type:Ar,parent:i,child:r}),Fr(e,0,n),e.compoundCount++,r}if(e.currentSubject===t){var a={checks:[]},o=e[e.length-1],s={checks:[]},l={checks:[]},u={checks:[]},c={checks:[]};return a.checks.push({type:Ir,left:o,right:s,subject:l}),l.checks=t.checks,t.checks=[{type:Mr}],c.checks.push({type:Mr}),s.checks.push({type:kr,parent:c,child:u}),Fr(e,0,a),e.currentSubject=l,e.compoundCount++,u}var h={checks:[]},d={checks:[]},p=[{type:kr,parent:h,child:d}];return h.checks=t.checks,t.checks=p,e.compoundCount++,d}},{name:"descendant",separator:!0,regex:dr.descendant,populate:function(e,t){if(null==e.currentSubject){var n={checks:[]},r={checks:[]},i=e[e.length-1];return n.checks.push({type:Lr,ancestor:i,descendant:r}),Fr(e,0,n),e.compoundCount++,r}if(e.currentSubject===t){var a={checks:[]},o=e[e.length-1],s={checks:[]},l={checks:[]},u={checks:[]},c={checks:[]};return a.checks.push({type:Ir,left:o,right:s,subject:l}),l.checks=t.checks,t.checks=[{type:Mr}],c.checks.push({type:Mr}),s.checks.push({type:Sr,ancestor:c,descendant:u}),Fr(e,0,a),e.currentSubject=l,e.compoundCount++,u}var h={checks:[]},d={checks:[]},p=[{type:Sr,ancestor:h,descendant:d}];return h.checks=t.checks,t.checks=p,e.compoundCount++,d}},{name:"subject",modifier:!0,regex:dr.subject,populate:function(e,t){if(null!=e.currentSubject&&e.currentSubject!==t)return Ae("Redefinition of subject in selector `"+e.toString()+"`"),!1;e.currentSubject=t;var n=e[e.length-1].checks[0],r=null==n?null:n.type;r===Tr?n.type=Cr:r===_r&&(n.type=Nr,n.node=n.nodes[1],n.neighbor=n.nodes[0],n.nodes=null)}}];zr.forEach((function(e){return e.regexObj=new RegExp("^"+e.regex)}));var Gr=function(e){for(var t,n,r,i=0;i<zr.length;i++){var a=zr[i],o=a.name,s=e.match(a.regexObj);if(null!=s){n=s,t=a,r=o;var l=s[0];e=e.substring(l.length);break}}return{expr:t,match:n,name:r,remaining:e}},Yr={parse:function(e){var t=this,n=t.inputText=e,r=t[0]={checks:[]};for(t.length=1,n=function(e){var t=e.match(/^\s+/);if(t){var n=t[0];e=e.substring(n.length)}return e}(n);;){var i=Gr(n);if(null==i.expr)return Ae("The selector `"+e+"`is invalid"),!1;var a=i.match.slice(1),o=i.expr.populate(t,r,a);if(!1===o)return!1;if(null!=o&&(r=o),(n=i.remaining).match(/^\s*$/))break}var s=t[t.length-1];null!=t.currentSubject&&(s.subject=t.currentSubject),s.edgeCount=t.edgeCount,s.compoundCount=t.compoundCount;for(var l=0;l<t.length;l++){var u=t[l];if(u.compoundCount>0&&u.edgeCount>0)return Ae("The selector `"+e+"` is invalid because it uses both a compound selector and an edge selector"),!1;if(u.edgeCount>1)return Ae("The selector `"+e+"` is invalid because it uses multiple edge selectors"),!1;1===u.edgeCount&&Ae("The selector `"+e+"` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.")}return!0},toString:function(){if(null!=this.toStringCache)return this.toStringCache;for(var e=function(e){return null==e?"":e},t=function(t){return A(t)?'"'+t+'"':e(t)},n=function(e){return" "+e+" "},r=function(r,a){var o=r.type,s=r.value;switch(o){case pr:var l=e(s);return l.substring(0,l.length-1);case vr:var u=r.field,c=r.operator;return"["+u+n(e(c))+t(s)+"]";case mr:var h=r.operator,d=r.field;return"["+e(h)+d+"]";case yr:return"["+r.field+"]";case br:var p=r.operator;return"[["+r.field+n(e(p))+t(s)+"]]";case xr:return s;case wr:return"#"+s;case Er:return"."+s;case kr:case Ar:return i(r.parent,a)+n(">")+i(r.child,a);case Sr:case Lr:return i(r.ancestor,a)+" "+i(r.descendant,a);case Ir:var g=i(r.left,a),f=i(r.subject,a),v=i(r.right,a);return g+(g.length>0?" ":"")+f+v;case Mr:return""}},i=function(e,t){return e.checks.reduce((function(n,i,a){return n+(t===e&&0===a?"$":"")+r(i,t)}),"")},a="",o=0;o<this.length;o++){var s=this[o];a+=i(s,s.subject),this.length>1&&o<this.length-1&&(a+=", ")}return this.toStringCache=a,a}},Xr=function(e,t,n){var r,i,a,o=A(e),s=I(e),l=A(n),u=!1,c=!1,h=!1;switch(t.indexOf("!")>=0&&(t=t.replace("!",""),c=!0),t.indexOf("@")>=0&&(t=t.replace("@",""),u=!0),(o||l||u)&&(i=o||s?""+e:"",a=""+n),u&&(e=i=i.toLowerCase(),n=a=a.toLowerCase()),t){case"*=":r=i.indexOf(a)>=0;break;case"$=":r=i.indexOf(a,i.length-a.length)>=0;break;case"^=":r=0===i.indexOf(a);break;case"=":r=e===n;break;case">":h=!0,r=e>n;break;case">=":h=!0,r=e>=n;break;case"<":h=!0,r=e<n;break;case"<=":h=!0,r=e<=n;break;default:r=!1}return!c||null==e&&h||(r=!r),r},Vr=function(e,t){return e.data(t)},Ur=[],jr=function(e,t){return e.checks.every((function(e){return Ur[e.type](e,t)}))};Ur[pr]=function(e,t){var n=e.value;return"*"===n||n===t.group()},Ur[xr]=function(e,t){return function(e,t){return Pr[e](t)}(e.value,t)},Ur[wr]=function(e,t){var n=e.value;return t.id()===n},Ur[Er]=function(e,t){var n=e.value;return t.hasClass(n)},Ur[br]=function(e,t){var n=e.field,r=e.operator,i=e.value;return Xr(function(e,t){return e[t]()}(t,n),r,i)},Ur[vr]=function(e,t){var n=e.field,r=e.operator,i=e.value;return Xr(Vr(t,n),r,i)},Ur[mr]=function(e,t){var n=e.field,r=e.operator;return function(e,t){switch(t){case"?":return!!e;case"!":return!e;case"^":return void 0===e}}(Vr(t,n),r)},Ur[yr]=function(e,t){var n=e.field;return e.operator,void 0!==Vr(t,n)},Ur[_r]=function(e,t){var n=e.nodes[0],r=e.nodes[1],i=t.source(),a=t.target();return jr(n,i)&&jr(r,a)||jr(r,i)&&jr(n,a)},Ur[Nr]=function(e,t){return jr(e.node,t)&&t.neighborhood().some((function(t){return t.isNode()&&jr(e.neighbor,t)}))},Ur[Tr]=function(e,t){return jr(e.source,t.source())&&jr(e.target,t.target())},Ur[Dr]=function(e,t){return jr(e.source,t)&&t.outgoers().some((function(t){return t.isNode()&&jr(e.target,t)}))},Ur[Cr]=function(e,t){return jr(e.target,t)&&t.incomers().some((function(t){return t.isNode()&&jr(e.source,t)}))},Ur[Ar]=function(e,t){return jr(e.child,t)&&jr(e.parent,t.parent())},Ur[kr]=function(e,t){return jr(e.parent,t)&&t.children().some((function(t){return jr(e.child,t)}))},Ur[Lr]=function(e,t){return jr(e.descendant,t)&&t.ancestors().some((function(t){return jr(e.ancestor,t)}))},Ur[Sr]=function(e,t){return jr(e.ancestor,t)&&t.descendants().some((function(t){return jr(e.descendant,t)}))},Ur[Ir]=function(e,t){return jr(e.subject,t)&&jr(e.left,t)&&jr(e.right,t)},Ur[Mr]=function(){return!0},Ur[gr]=function(e,t){return e.value.has(t)},Ur[fr]=function(e,t){return(0,e.value)(t)};var qr={matches:function(e){for(var t=0;t<this.length;t++){var n=this[t];if(jr(n,e))return!0}return!1},filter:function(e){var t=this;if(1===t.length&&1===t[0].checks.length&&t[0].checks[0].type===wr)return e.getElementById(t[0].checks[0].value).collection();var n=function(e){for(var n=0;n<t.length;n++){var r=t[n];if(jr(r,e))return!0}return!1};return null==t.text()&&(n=function(){return!0}),e.filter(n)}},Hr=function(e){this.inputText=e,this.currentSubject=null,this.compoundCount=0,this.edgeCount=0,this.length=0,null==e||A(e)&&e.match(/^\s*$/)||(O(e)?this.addQuery({checks:[{type:gr,value:e.collection()}]}):L(e)?this.addQuery({checks:[{type:fr,value:e}]}):A(e)?this.parse(e)||(this.invalid=!0):Ce("A selector must be created from a string; found "))},Wr=Hr.prototype;[Yr,qr].forEach((function(e){return Q(Wr,e)})),Wr.text=function(){return this.inputText},Wr.size=function(){return this.length},Wr.eq=function(e){return this[e]},Wr.sameText=function(e){return!this.invalid&&!e.invalid&&this.text()===e.text()},Wr.addQuery=function(e){this[this.length++]=e},Wr.selector=Wr.toString;var $r={allAre:function(e){var t=new Hr(e);return this.every((function(e){return t.matches(e)}))},is:function(e){var t=new Hr(e);return this.some((function(e){return t.matches(e)}))},some:function(e,t){for(var n=0;n<this.length;n++){if(t?e.apply(t,[this[n],n,this]):e(this[n],n,this))return!0}return!1},every:function(e,t){for(var n=0;n<this.length;n++){if(!(t?e.apply(t,[this[n],n,this]):e(this[n],n,this)))return!1}return!0},same:function(e){if(this===e)return!0;e=this.cy().collection(e);var t=this.length;return t===e.length&&(1===t?this[0]===e[0]:this.every((function(t){return e.hasElementWithId(t.id())})))},anySame:function(e){return e=this.cy().collection(e),this.some((function(t){return e.hasElementWithId(t.id())}))},allAreNeighbors:function(e){e=this.cy().collection(e);var t=this.neighborhood();return e.every((function(e){return t.hasElementWithId(e.id())}))},contains:function(e){e=this.cy().collection(e);var t=this;return e.every((function(e){return t.hasElementWithId(e.id())}))}};$r.allAreNeighbours=$r.allAreNeighbors,$r.has=$r.contains,$r.equal=$r.equals=$r.same;var Kr,Zr,Qr=function(e,t){return function(n,r,i,a){var o,s=n,l=this;if(null==s?o="":O(s)&&1===s.length&&(o=s.id()),1===l.length&&o){var u=l[0]._private,c=u.traversalCache=u.traversalCache||{},h=c[t]=c[t]||[],d=fe(o),p=h[d];return p||(h[d]=e.call(l,n,r,i,a))}return e.call(l,n,r,i,a)}},Jr={parent:function(e){var t=[];if(1===this.length){var n=this[0]._private.parent;if(n)return n}for(var r=0;r<this.length;r++){var i=this[r]._private.parent;i&&t.push(i)}return this.spawn(t,!0).filter(e)},parents:function(e){for(var t=[],n=this.parent();n.nonempty();){for(var r=0;r<n.length;r++){var i=n[r];t.push(i)}n=n.parent()}return this.spawn(t,!0).filter(e)},commonAncestors:function(e){for(var t,n=0;n<this.length;n++){var r=this[n].parents();t=(t=t||r).intersect(r)}return t.filter(e)},orphans:function(e){return this.stdFilter((function(e){return e.isOrphan()})).filter(e)},nonorphans:function(e){return this.stdFilter((function(e){return e.isChild()})).filter(e)},children:Qr((function(e){for(var t=[],n=0;n<this.length;n++)for(var r=this[n]._private.children,i=0;i<r.length;i++)t.push(r[i]);return this.spawn(t,!0).filter(e)}),"children"),siblings:function(e){return this.parent().children().not(this).filter(e)},isParent:function(){var e=this[0];if(e)return e.isNode()&&0!==e._private.children.length},isChildless:function(){var e=this[0];if(e)return e.isNode()&&0===e._private.children.length},isChild:function(){var e=this[0];if(e)return e.isNode()&&null!=e._private.parent},isOrphan:function(){var e=this[0];if(e)return e.isNode()&&null==e._private.parent},descendants:function(e){var t=[];return function e(n){for(var r=0;r<n.length;r++){var i=n[r];t.push(i),i.children().nonempty()&&e(i.children())}}(this.children()),this.spawn(t,!0).filter(e)}};function ei(e,t,n,r){for(var i=[],a=new Ge,o=e.cy().hasCompoundNodes(),s=0;s<e.length;s++){var l=e[s];n?i.push(l):o&&r(i,a,l)}for(;i.length>0;){var u=i.shift();t(u),a.add(u.id()),o&&r(i,a,u)}return e}function ti(e,t,n){if(n.isParent())for(var r=n._private.children,i=0;i<r.length;i++){var a=r[i];t.has(a.id())||e.push(a)}}function ni(e,t,n){if(n.isChild()){var r=n._private.parent;t.has(r.id())||e.push(r)}}function ri(e,t,n){ni(e,t,n),ti(e,t,n)}Jr.forEachDown=function(e){return ei(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],ti)},Jr.forEachUp=function(e){return ei(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],ni)},Jr.forEachUpAndDown=function(e){return ei(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],ri)},Jr.ancestors=Jr.parents,(Kr=Zr={data:ur.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),removeData:ur.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),scratch:ur.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:ur.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),rscratch:ur.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:ur.removeData({field:"rscratch",triggerEvent:!1}),id:function(){var e=this[0];if(e)return e._private.data.id}}).attr=Kr.data,Kr.removeAttr=Kr.removeData;var ii,ai,oi=Zr,si={};function li(e){return function(t){var n=this;if(void 0===t&&(t=!0),0!==n.length&&n.isNode()&&!n.removed()){for(var r=0,i=n[0],a=i._private.edges,o=0;o<a.length;o++){var s=a[o];!t&&s.isLoop()||(r+=e(i,s))}return r}}}function ui(e,t){return function(n){for(var r,i=this.nodes(),a=0;a<i.length;a++){var o=i[a][e](n);void 0===o||void 0!==r&&!t(o,r)||(r=o)}return r}}Q(si,{degree:li((function(e,t){return t.source().same(t.target())?2:1})),indegree:li((function(e,t){return t.target().same(e)?1:0})),outdegree:li((function(e,t){return t.source().same(e)?1:0}))}),Q(si,{minDegree:ui("degree",(function(e,t){return e<t})),maxDegree:ui("degree",(function(e,t){return e>t})),minIndegree:ui("indegree",(function(e,t){return e<t})),maxIndegree:ui("indegree",(function(e,t){return e>t})),minOutdegree:ui("outdegree",(function(e,t){return e<t})),maxOutdegree:ui("outdegree",(function(e,t){return e>t}))}),Q(si,{totalDegree:function(e){for(var t=0,n=this.nodes(),r=0;r<n.length;r++)t+=n[r].degree(e);return t}});var ci=function(e,t,n){for(var r=0;r<e.length;r++){var i=e[r];if(!i.locked()){var a=i._private.position,o={x:null!=t.x?t.x-a.x:0,y:null!=t.y?t.y-a.y:0};!i.isParent()||0===o.x&&0===o.y||i.children().shift(o,n),i.dirtyBoundingBoxCache()}}},hi={field:"position",bindingEvent:"position",allowBinding:!0,allowSetting:!0,settingEvent:"position",settingTriggersEvent:!0,triggerFnName:"emitAndNotify",allowGetting:!0,validKeys:["x","y"],beforeGet:function(e){e.updateCompoundBounds()},beforeSet:function(e,t){ci(e,t,!1)},onSet:function(e){e.dirtyCompoundBoundsCache()},canSet:function(e){return!e.locked()}};ii=ai={position:ur.data(hi),silentPosition:ur.data(Q({},hi,{allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!1,beforeSet:function(e,t){ci(e,t,!0)},onSet:function(e){e.dirtyCompoundBoundsCache()}})),positions:function(e,t){if(S(e))t?this.silentPosition(e):this.position(e);else if(L(e)){var n=e,r=this.cy();r.startBatch();for(var i=0;i<this.length;i++){var a,o=this[i];(a=n(o,i))&&(t?o.silentPosition(a):o.position(a))}r.endBatch()}return this},silentPositions:function(e){return this.positions(e,!0)},shift:function(e,t,n){var r;if(S(e)?(r={x:I(e.x)?e.x:0,y:I(e.y)?e.y:0},n=t):A(e)&&I(t)&&((r={x:0,y:0})[e]=t),null!=r){var i=this.cy();i.startBatch();for(var a=0;a<this.length;a++){var o=this[a];if(!(i.hasCompoundNodes()&&o.isChild()&&o.ancestors().anySame(this))){var s=o.position(),l={x:s.x+r.x,y:s.y+r.y};n?o.silentPosition(l):o.position(l)}}i.endBatch()}return this},silentShift:function(e,t){return S(e)?this.shift(e,!0):A(e)&&I(t)&&this.shift(e,t,!0),this},renderedPosition:function(e,t){var n=this[0],r=this.cy(),i=r.zoom(),a=r.pan(),o=S(e)?e:void 0,s=void 0!==o||void 0!==t&&A(e);if(n&&n.isNode()){if(!s){var l=n.position();return o=rt(l,i,a),void 0===e?o:o[e]}for(var u=0;u<this.length;u++){var c=this[u];void 0!==t?c.position(e,(t-a[e])/i):void 0!==o&&c.position(it(o,i,a))}}else if(!s)return;return this},relativePosition:function(e,t){var n=this[0],r=this.cy(),i=S(e)?e:void 0,a=void 0!==i||void 0!==t&&A(e),o=r.hasCompoundNodes();if(n&&n.isNode()){if(!a){var s=n.position(),l=o?n.parent():null,u=l&&l.length>0,c=u;u&&(l=l[0]);var h=c?l.position():{x:0,y:0};return i={x:s.x-h.x,y:s.y-h.y},void 0===e?i:i[e]}for(var d=0;d<this.length;d++){var p=this[d],g=o?p.parent():null,f=g&&g.length>0,v=f;f&&(g=g[0]);var y=v?g.position():{x:0,y:0};void 0!==t?p.position(e,t+y[e]):void 0!==i&&p.position({x:i.x+y.x,y:i.y+y.y})}}else if(!a)return;return this}},ii.modelPosition=ii.point=ii.position,ii.modelPositions=ii.points=ii.positions,ii.renderedPoint=ii.renderedPosition,ii.relativePoint=ii.relativePosition;var di,pi,gi=ai;di=pi={},pi.renderedBoundingBox=function(e){var t=this.boundingBox(e),n=this.cy(),r=n.zoom(),i=n.pan(),a=t.x1*r+i.x,o=t.x2*r+i.x,s=t.y1*r+i.y,l=t.y2*r+i.y;return{x1:a,x2:o,y1:s,y2:l,w:o-a,h:l-s}},pi.dirtyCompoundBoundsCache=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();return t.styleEnabled()&&t.hasCompoundNodes()?(this.forEachUp((function(t){if(t.isParent()){var n=t._private;n.compoundBoundsClean=!1,n.bbCache=null,e||t.emitAndNotify("bounds")}})),this):this},pi.updateCompoundBounds=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();if(!t.styleEnabled()||!t.hasCompoundNodes())return this;if(!e&&t.batching())return this;function n(e){if(e.isParent()){var t=e._private,n=e.children(),r="include"===e.pstyle("compound-sizing-wrt-labels").value,i={width:{val:e.pstyle("min-width").pfValue,left:e.pstyle("min-width-bias-left"),right:e.pstyle("min-width-bias-right")},height:{val:e.pstyle("min-height").pfValue,top:e.pstyle("min-height-bias-top"),bottom:e.pstyle("min-height-bias-bottom")}},a=n.boundingBox({includeLabels:r,includeOverlays:!1,useCache:!1}),o=t.position;0!==a.w&&0!==a.h||((a={w:e.pstyle("width").pfValue,h:e.pstyle("height").pfValue}).x1=o.x-a.w/2,a.x2=o.x+a.w/2,a.y1=o.y-a.h/2,a.y2=o.y+a.h/2);var s=i.width.left.value;"px"===i.width.left.units&&i.width.val>0&&(s=100*s/i.width.val);var l=i.width.right.value;"px"===i.width.right.units&&i.width.val>0&&(l=100*l/i.width.val);var u=i.height.top.value;"px"===i.height.top.units&&i.height.val>0&&(u=100*u/i.height.val);var c=i.height.bottom.value;"px"===i.height.bottom.units&&i.height.val>0&&(c=100*c/i.height.val);var h=y(i.width.val-a.w,s,l),d=h.biasDiff,p=h.biasComplementDiff,g=y(i.height.val-a.h,u,c),f=g.biasDiff,v=g.biasComplementDiff;t.autoPadding=function(e,t,n,r){if("%"!==n.units)return"px"===n.units?n.pfValue:0;switch(r){case"width":return e>0?n.pfValue*e:0;case"height":return t>0?n.pfValue*t:0;case"average":return e>0&&t>0?n.pfValue*(e+t)/2:0;case"min":return e>0&&t>0?e>t?n.pfValue*t:n.pfValue*e:0;case"max":return e>0&&t>0?e>t?n.pfValue*e:n.pfValue*t:0;default:return 0}}(a.w,a.h,e.pstyle("padding"),e.pstyle("padding-relative-to").value),t.autoWidth=Math.max(a.w,i.width.val),o.x=(-d+a.x1+a.x2+p)/2,t.autoHeight=Math.max(a.h,i.height.val),o.y=(-f+a.y1+a.y2+v)/2}function y(e,t,n){var r=0,i=0,a=t+n;return e>0&&a>0&&(r=t/a*e,i=n/a*e),{biasDiff:r,biasComplementDiff:i}}}for(var r=0;r<this.length;r++){var i=this[r],a=i._private;a.compoundBoundsClean&&!e||(n(i),t.batching()||(a.compoundBoundsClean=!0))}return this};var fi=function(e){return e===1/0||e===-1/0?0:e},vi=function(e,t,n,r,i){r-t!=0&&i-n!=0&&null!=t&&null!=n&&null!=r&&null!=i&&(e.x1=t<e.x1?t:e.x1,e.x2=r>e.x2?r:e.x2,e.y1=n<e.y1?n:e.y1,e.y2=i>e.y2?i:e.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1)},yi=function(e,t){return null==t?e:vi(e,t.x1,t.y1,t.x2,t.y2)},mi=function(e,t,n){return Re(e,t,n)},bi=function(e,t,n){if(!t.cy().headless()){var r,i,a=t._private,o=a.rstyle,s=o.arrowWidth/2;if("none"!==t.pstyle(n+"-arrow-shape").value){"source"===n?(r=o.srcX,i=o.srcY):"target"===n?(r=o.tgtX,i=o.tgtY):(r=o.midX,i=o.midY);var l=a.arrowBounds=a.arrowBounds||{},u=l[n]=l[n]||{};u.x1=r-s,u.y1=i-s,u.x2=r+s,u.y2=i+s,u.w=u.x2-u.x1,u.h=u.y2-u.y1,mt(u,1),vi(e,u.x1,u.y1,u.x2,u.y2)}}},xi=function(e,t,n){if(!t.cy().headless()){var r;r=n?n+"-":"";var i=t._private,a=i.rstyle;if(t.pstyle(r+"label").strValue){var o,s,l,u,c=t.pstyle("text-halign"),h=t.pstyle("text-valign"),d=mi(a,"labelWidth",n),p=mi(a,"labelHeight",n),g=mi(a,"labelX",n),f=mi(a,"labelY",n),v=t.pstyle(r+"text-margin-x").pfValue,y=t.pstyle(r+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle(r+"text-rotation"),x=t.pstyle("text-outline-width").pfValue,w=t.pstyle("text-border-width").pfValue/2,E=t.pstyle("text-background-padding").pfValue,_=p,T=d,D=T/2,C=_/2;if(m)o=g-D,s=g+D,l=f-C,u=f+C;else{switch(c.value){case"left":o=g-T,s=g;break;case"center":o=g-D,s=g+D;break;case"right":o=g,s=g+T}switch(h.value){case"top":l=f-_,u=f;break;case"center":l=f-C,u=f+C;break;case"bottom":l=f,u=f+_}}o+=v-Math.max(x,w)-E-2,s+=v+Math.max(x,w)+E+2,l+=y-Math.max(x,w)-E-2,u+=y+Math.max(x,w)+E+2;var N=n||"main",A=i.labelBounds,L=A[N]=A[N]||{};L.x1=o,L.y1=l,L.x2=s,L.y2=u,L.w=s-o,L.h=u-l;var k=m&&"autorotate"===b.strValue,S=null!=b.pfValue&&0!==b.pfValue;if(k||S){var I=k?mi(i.rstyle,"labelAngle",n):b.pfValue,M=Math.cos(I),O=Math.sin(I),P=(o+s)/2,R=(l+u)/2;if(!m){switch(c.value){case"left":P=s;break;case"right":P=o}switch(h.value){case"top":R=u;break;case"bottom":R=l}}var B=function(e,t){return{x:(e-=P)*M-(t-=R)*O+P,y:e*O+t*M+R}},F=B(o,l),z=B(o,u),G=B(s,l),Y=B(s,u);o=Math.min(F.x,z.x,G.x,Y.x),s=Math.max(F.x,z.x,G.x,Y.x),l=Math.min(F.y,z.y,G.y,Y.y),u=Math.max(F.y,z.y,G.y,Y.y)}var X=N+"Rot",V=A[X]=A[X]||{};V.x1=o,V.y1=l,V.x2=s,V.y2=u,V.w=s-o,V.h=u-l,vi(e,o,l,s,u),vi(i.labelBounds.all,o,l,s,u)}return e}},wi=function(e,t){var n,r,i,a,o,s,l,u=e._private.cy,c=u.styleEnabled(),h=u.headless(),d=ft(),p=e._private,g=e.isNode(),f=e.isEdge(),v=p.rstyle,y=g&&c?e.pstyle("bounds-expansion").pfValue:[0],m=function(e){return"none"!==e.pstyle("display").value},b=!c||m(e)&&(!f||m(e.source())&&m(e.target()));if(b){var x=0;c&&t.includeOverlays&&0!==e.pstyle("overlay-opacity").value&&(x=e.pstyle("overlay-padding").value);var w=0;c&&t.includeUnderlays&&0!==e.pstyle("underlay-opacity").value&&(w=e.pstyle("underlay-padding").value);var E=Math.max(x,w),_=0;if(c&&(_=e.pstyle("width").pfValue/2),g&&t.includeNodes){var T=e.position();o=T.x,s=T.y;var D=e.outerWidth()/2,C=e.outerHeight()/2;vi(d,n=o-D,i=s-C,r=o+D,a=s+C),c&&t.includeOutlines&&function(e,t){if(!t.cy().headless()){var n,r,i,a=t.pstyle("outline-opacity").value,o=t.pstyle("outline-width").value;if(a>0&&o>0){var s=t.pstyle("outline-offset").value,l=t.pstyle("shape").value,u=o+s,c=(e.w+2*u)/e.w,h=(e.h+2*u)/e.h,d=0;["diamond","pentagon","round-triangle"].includes(l)?(c=(e.w+2.4*u)/e.w,d=-u/3.6):["concave-hexagon","rhomboid","right-rhomboid"].includes(l)?c=(e.w+2.4*u)/e.w:"star"===l?(c=(e.w+2.8*u)/e.w,h=(e.h+2.6*u)/e.h,d=-u/3.8):"triangle"===l?(c=(e.w+2.8*u)/e.w,h=(e.h+2.4*u)/e.h,d=-u/1.4):"vee"===l&&(c=(e.w+4.4*u)/e.w,h=(e.h+3.8*u)/e.h,d=.5*-u);var p=e.h*h-e.h,g=e.w*c-e.w;if(bt(e,[Math.ceil(p/2),Math.ceil(g/2)]),0!==d){var f=(r=0,i=d,{x1:(n=e).x1+r,x2:n.x2+r,y1:n.y1+i,y2:n.y2+i,w:n.w,h:n.h});vt(e,f)}}}}(d,e)}else if(f&&t.includeEdges)if(c&&!h){var N=e.pstyle("curve-style").strValue;if(n=Math.min(v.srcX,v.midX,v.tgtX),r=Math.max(v.srcX,v.midX,v.tgtX),i=Math.min(v.srcY,v.midY,v.tgtY),a=Math.max(v.srcY,v.midY,v.tgtY),vi(d,n-=_,i-=_,r+=_,a+=_),"haystack"===N){var A=v.haystackPts;if(A&&2===A.length){if(n=A[0].x,i=A[0].y,n>(r=A[1].x)){var L=n;n=r,r=L}if(i>(a=A[1].y)){var k=i;i=a,a=k}vi(d,n-_,i-_,r+_,a+_)}}else if("bezier"===N||"unbundled-bezier"===N||"segments"===N||"taxi"===N){var S;switch(N){case"bezier":case"unbundled-bezier":S=v.bezierPts;break;case"segments":case"taxi":S=v.linePts}if(null!=S)for(var I=0;I<S.length;I++){var M=S[I];n=M.x-_,r=M.x+_,i=M.y-_,a=M.y+_,vi(d,n,i,r,a)}}}else{var O=e.source().position(),P=e.target().position();if((n=O.x)>(r=P.x)){var R=n;n=r,r=R}if((i=O.y)>(a=P.y)){var B=i;i=a,a=B}vi(d,n-=_,i-=_,r+=_,a+=_)}if(c&&t.includeEdges&&f&&(bi(d,e,"mid-source"),bi(d,e,"mid-target"),bi(d,e,"source"),bi(d,e,"target")),c)if("yes"===e.pstyle("ghost").value){var F=e.pstyle("ghost-offset-x").pfValue,z=e.pstyle("ghost-offset-y").pfValue;vi(d,d.x1+F,d.y1+z,d.x2+F,d.y2+z)}var G=p.bodyBounds=p.bodyBounds||{};xt(G,d),bt(G,y),mt(G,1),c&&(n=d.x1,r=d.x2,i=d.y1,a=d.y2,vi(d,n-E,i-E,r+E,a+E));var Y=p.overlayBounds=p.overlayBounds||{};xt(Y,d),bt(Y,y),mt(Y,1);var X=p.labelBounds=p.labelBounds||{};null!=X.all?((l=X.all).x1=1/0,l.y1=1/0,l.x2=-1/0,l.y2=-1/0,l.w=0,l.h=0):X.all=ft(),c&&t.includeLabels&&(t.includeMainLabels&&xi(d,e,null),f&&(t.includeSourceLabels&&xi(d,e,"source"),t.includeTargetLabels&&xi(d,e,"target")))}return d.x1=fi(d.x1),d.y1=fi(d.y1),d.x2=fi(d.x2),d.y2=fi(d.y2),d.w=fi(d.x2-d.x1),d.h=fi(d.y2-d.y1),d.w>0&&d.h>0&&b&&(bt(d,y),mt(d,1)),d},Ei=function(e){var t=0,n=function(e){return(e?1:0)<<t++},r=0;return r+=n(e.incudeNodes),r+=n(e.includeEdges),r+=n(e.includeLabels),r+=n(e.includeMainLabels),r+=n(e.includeSourceLabels),r+=n(e.includeTargetLabels),r+=n(e.includeOverlays),r+=n(e.includeOutlines)},_i=function(e){if(e.isEdge()){var t=e.source().position(),n=e.target().position(),r=function(e){return Math.round(e)};return function(e,t){var n={value:0,done:!1},r=0,i=e.length;return ce({next:function(){return r<i?n.value=e[r++]:n.done=!0,n}},t)}([r(t.x),r(t.y),r(n.x),r(n.y)])}return 0},Ti=function(e,t){var n,r=e._private,i=e.isEdge(),a=(null==t?Ci:Ei(t))===Ci,o=_i(e),s=r.bbCachePosKey===o,l=t.useCache&&s,u=function(e){return null==e._private.bbCache||e._private.styleDirty};if(!l||u(e)||i&&u(e.source())||u(e.target())?(s||e.recalculateRenderedStyle(l),n=wi(e,Di),r.bbCache=n,r.bbCachePosKey=o):n=r.bbCache,!a){var c=e.isNode();n=ft(),(t.includeNodes&&c||t.includeEdges&&!c)&&(t.includeOverlays?yi(n,r.overlayBounds):yi(n,r.bodyBounds)),t.includeLabels&&(t.includeMainLabels&&(!i||t.includeSourceLabels&&t.includeTargetLabels)?yi(n,r.labelBounds.all):(t.includeMainLabels&&yi(n,r.labelBounds.mainRot),t.includeSourceLabels&&yi(n,r.labelBounds.sourceRot),t.includeTargetLabels&&yi(n,r.labelBounds.targetRot))),n.w=n.x2-n.x1,n.h=n.y2-n.y1}return n},Di={includeNodes:!0,includeEdges:!0,includeLabels:!0,includeMainLabels:!0,includeSourceLabels:!0,includeTargetLabels:!0,includeOverlays:!0,includeUnderlays:!0,includeOutlines:!0,useCache:!0},Ci=Ei(Di),Ni=Me(Di);pi.boundingBox=function(e){var t;if(1!==this.length||null==this[0]._private.bbCache||this[0]._private.styleDirty||void 0!==e&&void 0!==e.useCache&&!0!==e.useCache){t=ft();var n=Ni(e=e||Di),r=this;if(r.cy().styleEnabled())for(var i=0;i<r.length;i++){var a=r[i],o=a._private,s=_i(a),l=o.bbCachePosKey===s,u=n.useCache&&l&&!o.styleDirty;a.recalculateRenderedStyle(u)}this.updateCompoundBounds(!e.useCache);for(var c=0;c<r.length;c++){var h=r[c];yi(t,Ti(h,n))}}else e=void 0===e?Di:Ni(e),t=Ti(this[0],e);return t.x1=fi(t.x1),t.y1=fi(t.y1),t.x2=fi(t.x2),t.y2=fi(t.y2),t.w=fi(t.x2-t.x1),t.h=fi(t.y2-t.y1),t},pi.dirtyBoundingBoxCache=function(){for(var e=0;e<this.length;e++){var t=this[e]._private;t.bbCache=null,t.bbCachePosKey=null,t.bodyBounds=null,t.overlayBounds=null,t.labelBounds.all=null,t.labelBounds.source=null,t.labelBounds.target=null,t.labelBounds.main=null,t.labelBounds.sourceRot=null,t.labelBounds.targetRot=null,t.labelBounds.mainRot=null,t.arrowBounds.source=null,t.arrowBounds.target=null,t.arrowBounds["mid-source"]=null,t.arrowBounds["mid-target"]=null}return this.emitAndNotify("bounds"),this},pi.boundingBoxAt=function(e){var t=this.nodes(),n=this.cy(),r=n.hasCompoundNodes(),i=n.collection();if(r&&(i=t.filter((function(e){return e.isParent()})),t=t.not(i)),S(e)){var a=e;e=function(){return a}}n.startBatch(),t.forEach((function(t,n){return t._private.bbAtOldPos=e(t,n)})).silentPositions(e),r&&(i.dirtyCompoundBoundsCache(),i.dirtyBoundingBoxCache(),i.updateCompoundBounds(!0));var o=function(e){return{x1:e.x1,x2:e.x2,w:e.w,y1:e.y1,y2:e.y2,h:e.h}}(this.boundingBox({useCache:!1}));return t.silentPositions((function(e){return e._private.bbAtOldPos})),r&&(i.dirtyCompoundBoundsCache(),i.dirtyBoundingBoxCache(),i.updateCompoundBounds(!0)),n.endBatch(),o},di.boundingbox=di.bb=di.boundingBox,di.renderedBoundingbox=di.renderedBoundingBox;var Ai,Li,ki=pi;Ai=Li={};var Si=function(e){e.uppercaseName=j(e.name),e.autoName="auto"+e.uppercaseName,e.labelName="label"+e.uppercaseName,e.outerName="outer"+e.uppercaseName,e.uppercaseOuterName=j(e.outerName),Ai[e.name]=function(){var t=this[0],n=t._private,r=n.cy._private.styleEnabled;if(t){if(r){if(t.isParent())return t.updateCompoundBounds(),n[e.autoName]||0;var i=t.pstyle(e.name);return"label"===i.strValue?(t.recalculateRenderedStyle(),n.rstyle[e.labelName]||0):i.pfValue}return 1}},Ai["outer"+e.uppercaseName]=function(){var t=this[0],n=t._private.cy._private.styleEnabled;if(t)return n?t[e.name]()+t.pstyle("border-width").pfValue+2*t.padding():1},Ai["rendered"+e.uppercaseName]=function(){var t=this[0];if(t)return t[e.name]()*this.cy().zoom()},Ai["rendered"+e.uppercaseOuterName]=function(){var t=this[0];if(t)return t[e.outerName]()*this.cy().zoom()}};Si({name:"width"}),Si({name:"height"}),Li.padding=function(){var e=this[0],t=e._private;return e.isParent()?(e.updateCompoundBounds(),void 0!==t.autoPadding?t.autoPadding:e.pstyle("padding").pfValue):e.pstyle("padding").pfValue},Li.paddedHeight=function(){var e=this[0];return e.height()+2*e.padding()},Li.paddedWidth=function(){var e=this[0];return e.width()+2*e.padding()};var Ii=Li,Mi={controlPoints:{get:function(e){return e.renderer().getControlPoints(e)},mult:!0},segmentPoints:{get:function(e){return e.renderer().getSegmentPoints(e)},mult:!0},sourceEndpoint:{get:function(e){return e.renderer().getSourceEndpoint(e)}},targetEndpoint:{get:function(e){return e.renderer().getTargetEndpoint(e)}},midpoint:{get:function(e){return e.renderer().getEdgeMidpoint(e)}}},Oi=Object.keys(Mi).reduce((function(e,t){var n=Mi[t],r=function(e){return"rendered"+e[0].toUpperCase()+e.substr(1)}(t);return e[t]=function(){return function(e,t){if(e.isEdge())return t(e)}(this,n.get)},n.mult?e[r]=function(){return function(e,t){if(e.isEdge()){var n=e.cy(),r=n.pan(),i=n.zoom();return t(e).map((function(e){return rt(e,i,r)}))}}(this,n.get)}:e[r]=function(){return function(e,t){if(e.isEdge()){var n=e.cy();return rt(t(e),n.zoom(),n.pan())}}(this,n.get)},e}),{}),Pi=Q({},gi,ki,Ii,Oi),Ri=function(e,t){this.recycle(e,t)};function Bi(){return!1}function Fi(){return!0}Ri.prototype={instanceString:function(){return"event"},recycle:function(e,t){if(this.isImmediatePropagationStopped=this.isPropagationStopped=this.isDefaultPrevented=Bi,null!=e&&e.preventDefault?(this.type=e.type,this.isDefaultPrevented=e.defaultPrevented?Fi:Bi):null!=e&&e.type?t=e:this.type=e,null!=t&&(this.originalEvent=t.originalEvent,this.type=null!=t.type?t.type:this.type,this.cy=t.cy,this.target=t.target,this.position=t.position,this.renderedPosition=t.renderedPosition,this.namespace=t.namespace,this.layout=t.layout),null!=this.cy&&null!=this.position&&null==this.renderedPosition){var n=this.position,r=this.cy.zoom(),i=this.cy.pan();this.renderedPosition={x:n.x*r+i.x,y:n.y*r+i.y}}this.timeStamp=e&&e.timeStamp||Date.now()},preventDefault:function(){this.isDefaultPrevented=Fi;var e=this.originalEvent;e&&e.preventDefault&&e.preventDefault()},stopPropagation:function(){this.isPropagationStopped=Fi;var e=this.originalEvent;e&&e.stopPropagation&&e.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Fi,this.stopPropagation()},isDefaultPrevented:Bi,isPropagationStopped:Bi,isImmediatePropagationStopped:Bi};var zi=/^([^.]+)(\.(?:[^.]+))?$/,Gi={qualifierCompare:function(e,t){return e===t},eventMatches:function(){return!0},addEventFields:function(){},callbackContext:function(e){return e},beforeEmit:function(){},afterEmit:function(){},bubble:function(){return!1},parent:function(){return null},context:null},Yi=Object.keys(Gi),Xi={};function Vi(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Xi,t=arguments.length>1?arguments[1]:void 0,n=0;n<Yi.length;n++){var r=Yi[n];this[r]=e[r]||Gi[r]}this.context=t||this.context,this.listeners=[],this.emitting=0}var Ui=Vi.prototype,ji=function(e,t,n,r,i,a,o){L(r)&&(i=r,r=null),o&&(a=null==a?o:Q({},a,o));for(var s=k(n)?n:n.split(/\s+/),l=0;l<s.length;l++){var u=s[l];if(!z(u)){var c=u.match(zi);if(c)if(!1===t(e,u,c[1],c[2]?c[2]:null,r,i,a))break}}},qi=function(e,t){return e.addEventFields(e.context,t),new Ri(t.type,t)},Hi=function(e,t,n){if("event"!==N(n))if(S(n))t(e,qi(e,n));else for(var r=k(n)?n:n.split(/\s+/),i=0;i<r.length;i++){var a=r[i];if(!z(a)){var o=a.match(zi);if(o){var s=o[1],l=o[2]?o[2]:null;t(e,qi(e,{type:s,namespace:l,target:e.context}))}}}else t(e,n)};Ui.on=Ui.addListener=function(e,t,n,r,i){return ji(this,(function(e,t,n,r,i,a,o){L(a)&&e.listeners.push({event:t,callback:a,type:n,namespace:r,qualifier:i,conf:o})}),e,t,n,r,i),this},Ui.one=function(e,t,n,r){return this.on(e,t,n,r,{one:!0})},Ui.removeListener=Ui.off=function(e,t,n,r){var i=this;0!==this.emitting&&(this.listeners=this.listeners.slice());for(var a=this.listeners,o=function(o){var s=a[o];ji(i,(function(t,n,r,i,l,u){if((s.type===r||"*"===e)&&(!i&&".*"!==s.namespace||s.namespace===i)&&(!l||t.qualifierCompare(s.qualifier,l))&&(!u||s.callback===u))return a.splice(o,1),!1}),e,t,n,r)},s=a.length-1;s>=0;s--)o(s);return this},Ui.removeAllListeners=function(){return this.removeListener("*")},Ui.emit=Ui.trigger=function(e,t,n){var r=this.listeners,i=r.length;return this.emitting++,k(t)||(t=[t]),Hi(this,(function(e,a){null!=n&&(r=[{event:a.event,type:a.type,namespace:a.namespace,callback:n}],i=r.length);for(var o=function(n){var i=r[n];if(i.type===a.type&&(!i.namespace||i.namespace===a.namespace||".*"===i.namespace)&&e.eventMatches(e.context,i,a)){var o=[a];null!=t&&function(e,t){for(var n=0;n<t.length;n++){var r=t[n];e.push(r)}}(o,t),e.beforeEmit(e.context,i,a),i.conf&&i.conf.one&&(e.listeners=e.listeners.filter((function(e){return e!==i})));var s=e.callbackContext(e.context,i,a),l=i.callback.apply(s,o);e.afterEmit(e.context,i,a),!1===l&&(a.stopPropagation(),a.preventDefault())}},s=0;s<i;s++)o(s);e.bubble(e.context)&&!a.isPropagationStopped()&&e.parent(e.context).emit(a,t)}),e),this.emitting--,this};var Wi={qualifierCompare:function(e,t){return null==e||null==t?null==e&&null==t:e.sameText(t)},eventMatches:function(e,t,n){var r=t.qualifier;return null==r||e!==n.target&&P(n.target)&&r.matches(n.target)},addEventFields:function(e,t){t.cy=e.cy(),t.target=e},callbackContext:function(e,t,n){return null!=t.qualifier?n.target:e},beforeEmit:function(e,t){t.conf&&t.conf.once&&t.conf.onceCollection.removeListener(t.event,t.qualifier,t.callback)},bubble:function(){return!0},parent:function(e){return e.isChild()?e.parent():e.cy()}},$i=function(e){return A(e)?new Hr(e):e},Ki={createEmitter:function(){for(var e=0;e<this.length;e++){var t=this[e],n=t._private;n.emitter||(n.emitter=new Vi(Wi,t))}return this},emitter:function(){return this._private.emitter},on:function(e,t,n){for(var r=$i(t),i=0;i<this.length;i++){this[i].emitter().on(e,r,n)}return this},removeListener:function(e,t,n){for(var r=$i(t),i=0;i<this.length;i++){this[i].emitter().removeListener(e,r,n)}return this},removeAllListeners:function(){for(var e=0;e<this.length;e++){this[e].emitter().removeAllListeners()}return this},one:function(e,t,n){for(var r=$i(t),i=0;i<this.length;i++){this[i].emitter().one(e,r,n)}return this},once:function(e,t,n){for(var r=$i(t),i=0;i<this.length;i++){this[i].emitter().on(e,r,n,{once:!0,onceCollection:this})}},emit:function(e,t){for(var n=0;n<this.length;n++){this[n].emitter().emit(e,t)}return this},emitAndNotify:function(e,t){if(0!==this.length)return this.cy().notify(e,this),this.emit(e,t),this}};ur.eventAliasesOn(Ki);var Zi={nodes:function(e){return this.filter((function(e){return e.isNode()})).filter(e)},edges:function(e){return this.filter((function(e){return e.isEdge()})).filter(e)},byGroup:function(){for(var e=this.spawn(),t=this.spawn(),n=0;n<this.length;n++){var r=this[n];r.isNode()?e.push(r):t.push(r)}return{nodes:e,edges:t}},filter:function(e,t){if(void 0===e)return this;if(A(e)||O(e))return new Hr(e).filter(this);if(L(e)){for(var n=this.spawn(),r=this,i=0;i<r.length;i++){var a=r[i];(t?e.apply(t,[a,i,r]):e(a,i,r))&&n.push(a)}return n}return this.spawn()},not:function(e){if(e){A(e)&&(e=this.filter(e));for(var t=this.spawn(),n=0;n<this.length;n++){var r=this[n];e.has(r)||t.push(r)}return t}return this},absoluteComplement:function(){return this.cy().mutableElements().not(this)},intersect:function(e){if(A(e)){var t=e;return this.filter(t)}for(var n=this.spawn(),r=e,i=this.length<e.length,a=i?this:r,o=i?r:this,s=0;s<a.length;s++){var l=a[s];o.has(l)&&n.push(l)}return n},xor:function(e){var t=this._private.cy;A(e)&&(e=t.$(e));var n=this.spawn(),r=e,i=function(e,t){for(var r=0;r<e.length;r++){var i=e[r],a=i._private.data.id;t.hasElementWithId(a)||n.push(i)}};return i(this,r),i(r,this),n},diff:function(e){var t=this._private.cy;A(e)&&(e=t.$(e));var n=this.spawn(),r=this.spawn(),i=this.spawn(),a=e,o=function(e,t,n){for(var r=0;r<e.length;r++){var a=e[r],o=a._private.data.id;t.hasElementWithId(o)?i.merge(a):n.push(a)}};return o(this,a,n),o(a,this,r),{left:n,right:r,both:i}},add:function(e){var t=this._private.cy;if(!e)return this;if(A(e)){var n=e;e=t.mutableElements().filter(n)}for(var r=this.spawnSelf(),i=0;i<e.length;i++){var a=e[i],o=!this.has(a);o&&r.push(a)}return r},merge:function(e){var t=this._private,n=t.cy;if(!e)return this;if(e&&A(e)){var r=e;e=n.mutableElements().filter(r)}for(var i=t.map,a=0;a<e.length;a++){var o=e[a],s=o._private.data.id;if(!i.has(s)){var l=this.length++;this[l]=o,i.set(s,{ele:o,index:l})}}return this},unmergeAt:function(e){var t=this[e].id(),n=this._private.map;this[e]=void 0,n.delete(t);var r=e===this.length-1;if(this.length>1&&!r){var i=this.length-1,a=this[i],o=a._private.data.id;this[i]=void 0,this[e]=a,n.set(o,{ele:a,index:e})}return this.length--,this},unmergeOne:function(e){e=e[0];var t=this._private,n=e._private.data.id,r=t.map.get(n);if(!r)return this;var i=r.index;return this.unmergeAt(i),this},unmerge:function(e){var t=this._private.cy;if(!e)return this;if(e&&A(e)){var n=e;e=t.mutableElements().filter(n)}for(var r=0;r<e.length;r++)this.unmergeOne(e[r]);return this},unmergeBy:function(e){for(var t=this.length-1;t>=0;t--){e(this[t])&&this.unmergeAt(t)}return this},map:function(e,t){for(var n=[],r=this,i=0;i<r.length;i++){var a=r[i],o=t?e.apply(t,[a,i,r]):e(a,i,r);n.push(o)}return n},reduce:function(e,t){for(var n=t,r=this,i=0;i<r.length;i++)n=e(n,r[i],i,r);return n},max:function(e,t){for(var n,r=-1/0,i=this,a=0;a<i.length;a++){var o=i[a],s=t?e.apply(t,[o,a,i]):e(o,a,i);s>r&&(r=s,n=o)}return{value:r,ele:n}},min:function(e,t){for(var n,r=1/0,i=this,a=0;a<i.length;a++){var o=i[a],s=t?e.apply(t,[o,a,i]):e(o,a,i);s<r&&(r=s,n=o)}return{value:r,ele:n}}},Qi=Zi;Qi.u=Qi["|"]=Qi["+"]=Qi.union=Qi.or=Qi.add,Qi["\\"]=Qi["!"]=Qi["-"]=Qi.difference=Qi.relativeComplement=Qi.subtract=Qi.not,Qi.n=Qi["&"]=Qi["."]=Qi.and=Qi.intersection=Qi.intersect,Qi["^"]=Qi["(+)"]=Qi["(-)"]=Qi.symmetricDifference=Qi.symdiff=Qi.xor,Qi.fnFilter=Qi.filterFn=Qi.stdFilter=Qi.filter,Qi.complement=Qi.abscomp=Qi.absoluteComplement;var Ji=function(e,t){var n=e.cy().hasCompoundNodes();function r(e){var t=e.pstyle("z-compound-depth");return"auto"===t.value?n?e.zDepth():0:"bottom"===t.value?-1:"top"===t.value?we:0}var i=r(e)-r(t);if(0!==i)return i;function a(e){return"auto"===e.pstyle("z-index-compare").value&&e.isNode()?1:0}var o=a(e)-a(t);if(0!==o)return o;var s=e.pstyle("z-index").value-t.pstyle("z-index").value;return 0!==s?s:e.poolIndex()-t.poolIndex()},ea={forEach:function(e,t){if(L(e))for(var n=this.length,r=0;r<n;r++){var i=this[r];if(!1===(t?e.apply(t,[i,r,this]):e(i,r,this)))break}return this},toArray:function(){for(var e=[],t=0;t<this.length;t++)e.push(this[t]);return e},slice:function(e,t){var n=[],r=this.length;null==t&&(t=r),null==e&&(e=0),e<0&&(e=r+e),t<0&&(t=r+t);for(var i=e;i>=0&&i<t&&i<r;i++)n.push(this[i]);return this.spawn(n)},size:function(){return this.length},eq:function(e){return this[e]||this.spawn()},first:function(){return this[0]||this.spawn()},last:function(){return this[this.length-1]||this.spawn()},empty:function(){return 0===this.length},nonempty:function(){return!this.empty()},sort:function(e){if(!L(e))return this;var t=this.toArray().sort(e);return this.spawn(t)},sortByZIndex:function(){return this.sort(Ji)},zDepth:function(){var e=this[0];if(e){var t=e._private;if("nodes"===t.group){var n=t.data.parent?e.parents().size():0;return e.isParent()?n:we-1}var r=t.source,i=t.target,a=r.zDepth(),o=i.zDepth();return Math.max(a,o,0)}}};ea.each=ea.forEach;var ta;ta="undefined",("undefined"==typeof Symbol?"undefined":g(Symbol))!=ta&&g(Symbol.iterator)!=ta&&(ea[Symbol.iterator]=function(){var e=this,t={value:void 0,done:!1},n=0,r=this.length;return m({next:function(){return n<r?t.value=e[n++]:(t.value=void 0,t.done=!0),t}},Symbol.iterator,(function(){return this}))});var na=Me({nodeDimensionsIncludeLabels:!1}),ra={layoutDimensions:function(e){var t;if(e=na(e),this.takesUpSpace())if(e.nodeDimensionsIncludeLabels){var n=this.boundingBox();t={w:n.w,h:n.h}}else t={w:this.outerWidth(),h:this.outerHeight()};else t={w:0,h:0};return 0!==t.w&&0!==t.h||(t.w=t.h=1),t},layoutPositions:function(e,t,n){var r=this.nodes().filter((function(e){return!e.isParent()})),i=this.cy(),a=t.eles,o=function(e){return e.id()},s=Y(n,o);e.emit({type:"layoutstart",layout:e}),e.animations=[];var l=t.spacingFactor&&1!==t.spacingFactor,u=function(){if(!l)return null;for(var e=ft(),t=0;t<r.length;t++){var n=r[t],i=s(n,t);yt(e,i.x,i.y)}return e}(),c=Y((function(e,n){var r=s(e,n);l&&(r=function(e,t,n){var r=t.x1+t.w/2,i=t.y1+t.h/2;return{x:r+(n.x-r)*e,y:i+(n.y-i)*e}}(Math.abs(t.spacingFactor),u,r));return null!=t.transform&&(r=t.transform(e,r)),r}),o);if(t.animate){for(var h=0;h<r.length;h++){var d=r[h],p=c(d,h);if(null==t.animateFilter||t.animateFilter(d,h)){var g=d.animation({position:p,duration:t.animationDuration,easing:t.animationEasing});e.animations.push(g)}else d.position(p)}if(t.fit){var f=i.animation({fit:{boundingBox:a.boundingBoxAt(c),padding:t.padding},duration:t.animationDuration,easing:t.animationEasing});e.animations.push(f)}else if(void 0!==t.zoom&&void 0!==t.pan){var v=i.animation({zoom:t.zoom,pan:t.pan,duration:t.animationDuration,easing:t.animationEasing});e.animations.push(v)}e.animations.forEach((function(e){return e.play()})),e.one("layoutready",t.ready),e.emit({type:"layoutready",layout:e}),rr.all(e.animations.map((function(e){return e.promise()}))).then((function(){e.one("layoutstop",t.stop),e.emit({type:"layoutstop",layout:e})}))}else r.positions(c),t.fit&&i.fit(t.eles,t.padding),null!=t.zoom&&i.zoom(t.zoom),t.pan&&i.pan(t.pan),e.one("layoutready",t.ready),e.emit({type:"layoutready",layout:e}),e.one("layoutstop",t.stop),e.emit({type:"layoutstop",layout:e});return this},layout:function(e){return this.cy().makeLayout(Q({},e,{eles:this}))}};function ia(e,t,n){var r,i=n._private,a=i.styleCache=i.styleCache||[];return null!=(r=a[e])?r:r=a[e]=t(n)}function aa(e,t){return e=fe(e),function(n){return ia(e,t,n)}}function oa(e,t){e=fe(e);var n=function(e){return t.call(e)};return function(){var t=this[0];if(t)return ia(e,n,t)}}ra.createLayout=ra.makeLayout=ra.layout;var sa={recalculateRenderedStyle:function(e){var t=this.cy(),n=t.renderer(),r=t.styleEnabled();return n&&r&&n.recalculateRenderedStyle(this,e),this},dirtyStyleCache:function(){var e,t=this.cy(),n=function(e){return e._private.styleCache=null};t.hasCompoundNodes()?((e=this.spawnSelf().merge(this.descendants()).merge(this.parents())).merge(e.connectedEdges()),e.forEach(n)):this.forEach((function(e){n(e),e.connectedEdges().forEach(n)}));return this},updateStyle:function(e){var t=this._private.cy;if(!t.styleEnabled())return this;if(t.batching())return t._private.batchStyleEles.merge(this),this;var n=this;e=!(!e&&void 0!==e),t.hasCompoundNodes()&&(n=this.spawnSelf().merge(this.descendants()).merge(this.parents()));var r=n;return e?r.emitAndNotify("style"):r.emit("style"),n.forEach((function(e){return e._private.styleDirty=!0})),this},cleanStyle:function(){var e=this.cy();if(e.styleEnabled())for(var t=0;t<this.length;t++){var n=this[t];n._private.styleDirty&&(n._private.styleDirty=!1,e.style().apply(n))}},parsedStyle:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this[0],r=n.cy();if(r.styleEnabled()&&n){this.cleanStyle();var i=n._private.style[e];return null!=i?i:t?r.style().getDefaultProperty(e):null}},numericStyle:function(e){var t=this[0];if(t.cy().styleEnabled()&&t){var n=t.pstyle(e);return void 0!==n.pfValue?n.pfValue:n.value}},numericStyleUnits:function(e){var t=this[0];if(t.cy().styleEnabled())return t?t.pstyle(e).units:void 0},renderedStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=this[0];return n?t.style().getRenderedStyle(n,e):void 0},style:function(e,t){var n=this.cy();if(!n.styleEnabled())return this;var r=!1,i=n.style();if(S(e)){var a=e;i.applyBypass(this,a,r),this.emitAndNotify("style")}else if(A(e)){if(void 0===t){var o=this[0];return o?i.getStylePropertyValue(o,e):void 0}i.applyBypass(this,e,t,r),this.emitAndNotify("style")}else if(void 0===e){var s=this[0];return s?i.getRawStyle(s):void 0}return this},removeStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=!1,r=t.style(),i=this;if(void 0===e)for(var a=0;a<i.length;a++){var o=i[a];r.removeAllBypasses(o,n)}else{e=e.split(/\s+/);for(var s=0;s<i.length;s++){var l=i[s];r.removeBypasses(l,e,n)}}return this.emitAndNotify("style"),this},show:function(){return this.css("display","element"),this},hide:function(){return this.css("display","none"),this},effectiveOpacity:function(){var e=this.cy();if(!e.styleEnabled())return 1;var t=e.hasCompoundNodes(),n=this[0];if(n){var r=n._private,i=n.pstyle("opacity").value;if(!t)return i;var a=r.data.parent?n.parents():null;if(a)for(var o=0;o<a.length;o++){i*=a[o].pstyle("opacity").value}return i}},transparent:function(){if(!this.cy().styleEnabled())return!1;var e=this[0],t=e.cy().hasCompoundNodes();return e?t?0===e.effectiveOpacity():0===e.pstyle("opacity").value:void 0},backgrounding:function(){return!!this.cy().styleEnabled()&&!!this[0]._private.backgrounding}};function la(e,t){var n=e._private.data.parent?e.parents():null;if(n)for(var r=0;r<n.length;r++){if(!t(n[r]))return!1}return!0}function ua(e){var t=e.ok,n=e.edgeOkViaNode||e.ok,r=e.parentOk||e.ok;return function(){var e=this.cy();if(!e.styleEnabled())return!0;var i=this[0],a=e.hasCompoundNodes();if(i){var o=i._private;if(!t(i))return!1;if(i.isNode())return!a||la(i,r);var s=o.source,l=o.target;return n(s)&&(!a||la(s,n))&&(s===l||n(l)&&(!a||la(l,n)))}}}var ca=aa("eleTakesUpSpace",(function(e){return"element"===e.pstyle("display").value&&0!==e.width()&&(!e.isNode()||0!==e.height())}));sa.takesUpSpace=oa("takesUpSpace",ua({ok:ca}));var ha=aa("eleInteractive",(function(e){return"yes"===e.pstyle("events").value&&"visible"===e.pstyle("visibility").value&&ca(e)})),da=aa("parentInteractive",(function(e){return"visible"===e.pstyle("visibility").value&&ca(e)}));sa.interactive=oa("interactive",ua({ok:ha,parentOk:da,edgeOkViaNode:ca})),sa.noninteractive=function(){var e=this[0];if(e)return!e.interactive()};var pa=aa("eleVisible",(function(e){return"visible"===e.pstyle("visibility").value&&0!==e.pstyle("opacity").pfValue&&ca(e)})),ga=ca;sa.visible=oa("visible",ua({ok:pa,edgeOkViaNode:ga})),sa.hidden=function(){var e=this[0];if(e)return!e.visible()},sa.isBundledBezier=oa("isBundledBezier",(function(){return!!this.cy().styleEnabled()&&(!this.removed()&&"bezier"===this.pstyle("curve-style").value&&this.takesUpSpace())})),sa.bypass=sa.css=sa.style,sa.renderedCss=sa.renderedStyle,sa.removeBypass=sa.removeCss=sa.removeStyle,sa.pstyle=sa.parsedStyle;var fa={};function va(e){return function(){var t=arguments,n=[];if(2===t.length){var r=t[0],i=t[1];this.on(e.event,r,i)}else if(1===t.length&&L(t[0])){var a=t[0];this.on(e.event,a)}else if(0===t.length||1===t.length&&k(t[0])){for(var o=1===t.length?t[0]:null,s=0;s<this.length;s++){var l=this[s],u=!e.ableField||l._private[e.ableField],c=l._private[e.field]!=e.value;if(e.overrideAble){var h=e.overrideAble(l);if(void 0!==h&&(u=h,!h))return this}u&&(l._private[e.field]=e.value,c&&n.push(l))}var d=this.spawn(n);d.updateStyle(),d.emit(e.event),o&&d.emit(o)}return this}}function ya(e){fa[e.field]=function(){var t=this[0];if(t){if(e.overrideField){var n=e.overrideField(t);if(void 0!==n)return n}return t._private[e.field]}},fa[e.on]=va({event:e.on,field:e.field,ableField:e.ableField,overrideAble:e.overrideAble,value:!0}),fa[e.off]=va({event:e.off,field:e.field,ableField:e.ableField,overrideAble:e.overrideAble,value:!1})}ya({field:"locked",overrideField:function(e){return!!e.cy().autolock()||void 0},on:"lock",off:"unlock"}),ya({field:"grabbable",overrideField:function(e){return!e.cy().autoungrabify()&&!e.pannable()&&void 0},on:"grabify",off:"ungrabify"}),ya({field:"selected",ableField:"selectable",overrideAble:function(e){return!e.cy().autounselectify()&&void 0},on:"select",off:"unselect"}),ya({field:"selectable",overrideField:function(e){return!e.cy().autounselectify()&&void 0},on:"selectify",off:"unselectify"}),fa.deselect=fa.unselect,fa.grabbed=function(){var e=this[0];if(e)return e._private.grabbed},ya({field:"active",on:"activate",off:"unactivate"}),ya({field:"pannable",on:"panify",off:"unpanify"}),fa.inactive=function(){var e=this[0];if(e)return!e._private.active};var ma={},ba=function(e){return function(t){for(var n=[],r=0;r<this.length;r++){var i=this[r];if(i.isNode()){for(var a=!1,o=i.connectedEdges(),s=0;s<o.length;s++){var l=o[s],u=l.source(),c=l.target();if(e.noIncomingEdges&&c===i&&u!==i||e.noOutgoingEdges&&u===i&&c!==i){a=!0;break}}a||n.push(i)}}return this.spawn(n,!0).filter(t)}},xa=function(e){return function(t){for(var n=[],r=0;r<this.length;r++){var i=this[r];if(i.isNode())for(var a=i.connectedEdges(),o=0;o<a.length;o++){var s=a[o],l=s.source(),u=s.target();e.outgoing&&l===i?(n.push(s),n.push(u)):e.incoming&&u===i&&(n.push(s),n.push(l))}}return this.spawn(n,!0).filter(t)}},wa=function(e){return function(t){for(var n=this,r=[],i={};;){var a=e.outgoing?n.outgoers():n.incomers();if(0===a.length)break;for(var o=!1,s=0;s<a.length;s++){var l=a[s],u=l.id();i[u]||(i[u]=!0,r.push(l),o=!0)}if(!o)break;n=a}return this.spawn(r,!0).filter(t)}};function Ea(e){return function(t){for(var n=[],r=0;r<this.length;r++){var i=this[r]._private[e.attr];i&&n.push(i)}return this.spawn(n,!0).filter(t)}}function _a(e){return function(t){var n=[],r=this._private.cy,i=e||{};A(t)&&(t=r.$(t));for(var a=0;a<t.length;a++)for(var o=t[a]._private.edges,s=0;s<o.length;s++){var l=o[s],u=l._private.data,c=this.hasElementWithId(u.source)&&t.hasElementWithId(u.target),h=t.hasElementWithId(u.source)&&this.hasElementWithId(u.target);if(c||h){if(i.thisIsSrc||i.thisIsTgt){if(i.thisIsSrc&&!c)continue;if(i.thisIsTgt&&!h)continue}n.push(l)}}return this.spawn(n,!0)}}function Ta(e){return e=Q({},{codirected:!1},e),function(t){for(var n=[],r=this.edges(),i=e,a=0;a<r.length;a++)for(var o=r[a]._private,s=o.source,l=s._private.data.id,u=o.data.target,c=s._private.edges,h=0;h<c.length;h++){var d=c[h],p=d._private.data,g=p.target,f=p.source,v=g===u&&f===l,y=l===g&&u===f;(i.codirected&&v||!i.codirected&&(v||y))&&n.push(d)}return this.spawn(n,!0).filter(t)}}ma.clearTraversalCache=function(){for(var e=0;e<this.length;e++)this[e]._private.traversalCache=null},Q(ma,{roots:ba({noIncomingEdges:!0}),leaves:ba({noOutgoingEdges:!0}),outgoers:Qr(xa({outgoing:!0}),"outgoers"),successors:wa({outgoing:!0}),incomers:Qr(xa({incoming:!0}),"incomers"),predecessors:wa({incoming:!0})}),Q(ma,{neighborhood:Qr((function(e){for(var t=[],n=this.nodes(),r=0;r<n.length;r++)for(var i=n[r],a=i.connectedEdges(),o=0;o<a.length;o++){var s=a[o],l=s.source(),u=s.target(),c=i===l?u:l;c.length>0&&t.push(c[0]),t.push(s[0])}return this.spawn(t,!0).filter(e)}),"neighborhood"),closedNeighborhood:function(e){return this.neighborhood().add(this).filter(e)},openNeighborhood:function(e){return this.neighborhood(e)}}),ma.neighbourhood=ma.neighborhood,ma.closedNeighbourhood=ma.closedNeighborhood,ma.openNeighbourhood=ma.openNeighborhood,Q(ma,{source:Qr((function(e){var t,n=this[0];return n&&(t=n._private.source||n.cy().collection()),t&&e?t.filter(e):t}),"source"),target:Qr((function(e){var t,n=this[0];return n&&(t=n._private.target||n.cy().collection()),t&&e?t.filter(e):t}),"target"),sources:Ea({attr:"source"}),targets:Ea({attr:"target"})}),Q(ma,{edgesWith:Qr(_a(),"edgesWith"),edgesTo:Qr(_a({thisIsSrc:!0}),"edgesTo")}),Q(ma,{connectedEdges:Qr((function(e){for(var t=[],n=0;n<this.length;n++){var r=this[n];if(r.isNode())for(var i=r._private.edges,a=0;a<i.length;a++){var o=i[a];t.push(o)}}return this.spawn(t,!0).filter(e)}),"connectedEdges"),connectedNodes:Qr((function(e){for(var t=[],n=0;n<this.length;n++){var r=this[n];r.isEdge()&&(t.push(r.source()[0]),t.push(r.target()[0]))}return this.spawn(t,!0).filter(e)}),"connectedNodes"),parallelEdges:Qr(Ta(),"parallelEdges"),codirectedEdges:Qr(Ta({codirected:!0}),"codirectedEdges")}),Q(ma,{components:function(e){var t=this,n=t.cy(),r=n.collection(),i=null==e?t.nodes():e.nodes(),a=[];null!=e&&i.empty()&&(i=e.sources());var o=function(e,t){r.merge(e),i.unmerge(e),t.merge(e)};if(i.empty())return t.spawn();var s=function(){var e=n.collection();a.push(e);var r=i[0];o(r,e),t.bfs({directed:!1,roots:r,visit:function(t){return o(t,e)}}),e.forEach((function(n){n.connectedEdges().forEach((function(n){t.has(n)&&e.has(n.source())&&e.has(n.target())&&e.merge(n)}))}))};do{s()}while(i.length>0);return a},component:function(){var e=this[0];return e.cy().mutableElements().components(e)[0]}}),ma.componentsOf=ma.components;var Da=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(void 0!==e){var i=new Fe,a=!1;if(t){if(t.length>0&&S(t[0])&&!P(t[0])){a=!0;for(var o=[],s=new Ge,l=0,u=t.length;l<u;l++){var c=t[l];null==c.data&&(c.data={});var h=c.data;if(null==h.id)h.id=ke();else if(e.hasElementWithId(h.id)||s.has(h.id))continue;var d=new Ye(e,c,!1);o.push(d),s.add(h.id)}t=o}}else t=[];this.length=0;for(var p=0,g=t.length;p<g;p++){var f=t[p][0];if(null!=f){var v=f._private.data.id;n&&i.has(v)||(n&&i.set(v,{index:this.length,ele:f}),this[this.length]=f,this.length++)}}this._private={eles:this,cy:e,get map(){return null==this.lazyMap&&this.rebuildMap(),this.lazyMap},set map(e){this.lazyMap=e},rebuildMap:function(){for(var e=this.lazyMap=new Fe,t=this.eles,n=0;n<t.length;n++){var r=t[n];e.set(r.id(),{index:n,ele:r})}}},n&&(this._private.map=i),a&&!r&&this.restore()}else Ce("A collection must have a reference to the core")},Ca=Ye.prototype=Da.prototype=Object.create(Array.prototype);Ca.instanceString=function(){return"collection"},Ca.spawn=function(e,t){return new Da(this.cy(),e,t)},Ca.spawnSelf=function(){return this.spawn(this)},Ca.cy=function(){return this._private.cy},Ca.renderer=function(){return this._private.cy.renderer()},Ca.element=function(){return this[0]},Ca.collection=function(){return R(this)?this:new Da(this._private.cy,[this])},Ca.unique=function(){return new Da(this._private.cy,this,!0)},Ca.hasElementWithId=function(e){return e=""+e,this._private.map.has(e)},Ca.getElementById=function(e){e=""+e;var t=this._private.cy,n=this._private.map.get(e);return n?n.ele:new Da(t)},Ca.$id=Ca.getElementById,Ca.poolIndex=function(){var e=this._private.cy._private.elements,t=this[0]._private.data.id;return e._private.map.get(t).index},Ca.indexOf=function(e){var t=e[0]._private.data.id;return this._private.map.get(t).index},Ca.indexOfId=function(e){return e=""+e,this._private.map.get(e).index},Ca.json=function(e){var t=this.element(),n=this.cy();if(null==t&&e)return this;if(null!=t){var r=t._private;if(S(e)){if(n.startBatch(),e.data){t.data(e.data);var i=r.data;if(t.isEdge()){var a=!1,o={},s=e.data.source,l=e.data.target;null!=s&&s!=i.source&&(o.source=""+s,a=!0),null!=l&&l!=i.target&&(o.target=""+l,a=!0),a&&(t=t.move(o))}else{var u="parent"in e.data,c=e.data.parent;!u||null==c&&null==i.parent||c==i.parent||(void 0===c&&(c=null),null!=c&&(c=""+c),t=t.move({parent:c}))}}e.position&&t.position(e.position);var h=function(n,i,a){var o=e[n];null!=o&&o!==r[n]&&(o?t[i]():t[a]())};return h("removed","remove","restore"),h("selected","select","unselect"),h("selectable","selectify","unselectify"),h("locked","lock","unlock"),h("grabbable","grabify","ungrabify"),h("pannable","panify","unpanify"),null!=e.classes&&t.classes(e.classes),n.endBatch(),this}if(void 0===e){var d={data:Le(r.data),position:Le(r.position),group:r.group,removed:r.removed,selected:r.selected,selectable:r.selectable,locked:r.locked,grabbable:r.grabbable,pannable:r.pannable,classes:null};d.classes="";var p=0;return r.classes.forEach((function(e){return d.classes+=0==p++?e:" "+e})),d}}},Ca.jsons=function(){for(var e=[],t=0;t<this.length;t++){var n=this[t].json();e.push(n)}return e},Ca.clone=function(){for(var e=this.cy(),t=[],n=0;n<this.length;n++){var r=this[n].json(),i=new Ye(e,r,!1);t.push(i)}return new Da(e,t)},Ca.copy=Ca.clone,Ca.restore=function(){for(var e,t,n=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=this,a=i.cy(),o=a._private,s=[],l=[],u=0,c=i.length;u<c;u++){var h=i[u];r&&!h.removed()||(h.isNode()?s.push(h):l.push(h))}e=s.concat(l);var d=function(){e.splice(t,1),t--};for(t=0;t<e.length;t++){var p=e[t],g=p._private,f=g.data;if(p.clearTraversalCache(),r||g.removed)if(void 0===f.id)f.id=ke();else if(I(f.id))f.id=""+f.id;else{if(z(f.id)||!A(f.id)){Ce("Can not create element with invalid string ID `"+f.id+"`"),d();continue}if(a.hasElementWithId(f.id)){Ce("Can not create second element with ID `"+f.id+"`"),d();continue}}else;var v=f.id;if(p.isNode()){var y=g.position;null==y.x&&(y.x=0),null==y.y&&(y.y=0)}if(p.isEdge()){for(var m=p,b=["source","target"],x=b.length,w=!1,E=0;E<x;E++){var _=b[E],T=f[_];I(T)&&(T=f[_]=""+f[_]),null==T||""===T?(Ce("Can not create edge `"+v+"` with unspecified "+_),w=!0):a.hasElementWithId(T)||(Ce("Can not create edge `"+v+"` with nonexistant "+_+" `"+T+"`"),w=!0)}if(w){d();continue}var D=a.getElementById(f.source),C=a.getElementById(f.target);D.same(C)?D._private.edges.push(m):(D._private.edges.push(m),C._private.edges.push(m)),m._private.source=D,m._private.target=C}g.map=new Fe,g.map.set(v,{ele:p,index:0}),g.removed=!1,r&&a.addToPool(p)}for(var N=0;N<s.length;N++){var L=s[N],k=L._private.data;I(k.parent)&&(k.parent=""+k.parent);var S=k.parent;if(null!=S||L._private.parent){var M=L._private.parent?a.collection().merge(L._private.parent):a.getElementById(S);if(M.empty())k.parent=void 0;else if(M[0].removed())Ae("Node added with missing parent, reference to parent removed"),k.parent=void 0,L._private.parent=null;else{for(var O=!1,P=M;!P.empty();){if(L.same(P)){O=!0,k.parent=void 0;break}P=P.parent()}O||(M[0]._private.children.push(L),L._private.parent=M[0],o.hasCompoundNodes=!0)}}}if(e.length>0){for(var R=e.length===i.length?i:new Da(a,e),B=0;B<R.length;B++){var F=R[B];F.isNode()||(F.parallelEdges().clearTraversalCache(),F.source().clearTraversalCache(),F.target().clearTraversalCache())}(o.hasCompoundNodes?a.collection().merge(R).merge(R.connectedNodes()).merge(R.parent()):R).dirtyCompoundBoundsCache().dirtyBoundingBoxCache().updateStyle(n),n?R.emitAndNotify("add"):r&&R.emit("add")}return i},Ca.removed=function(){var e=this[0];return e&&e._private.removed},Ca.inside=function(){var e=this[0];return e&&!e._private.removed},Ca.remove=function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this,r=[],i={},a=n._private.cy;function o(e){var n=i[e.id()];t&&e.removed()||n||(i[e.id()]=!0,e.isNode()?(r.push(e),function(e){for(var t=e._private.edges,n=0;n<t.length;n++)o(t[n])}(e),function(e){for(var t=e._private.children,n=0;n<t.length;n++)o(t[n])}(e)):r.unshift(e))}for(var s=0,l=n.length;s<l;s++){o(n[s])}function u(e,t){var n=e._private.edges;Oe(n,t),e.clearTraversalCache()}function c(e){e.clearTraversalCache()}var h=[];function d(e,t){t=t[0];var n=(e=e[0])._private.children,r=e.id();Oe(n,t),t._private.parent=null,h.ids[r]||(h.ids[r]=!0,h.push(e))}h.ids={},n.dirtyCompoundBoundsCache(),t&&a.removeFromPool(r);for(var p=0;p<r.length;p++){var g=r[p];if(g.isEdge()){var f=g.source()[0],v=g.target()[0];u(f,g),u(v,g);for(var y=g.parallelEdges(),m=0;m<y.length;m++){var b=y[m];c(b),b.isBundledBezier()&&b.dirtyBoundingBoxCache()}}else{var x=g.parent();0!==x.length&&d(x,g)}t&&(g._private.removed=!0)}var w=a._private.elements;a._private.hasCompoundNodes=!1;for(var E=0;E<w.length;E++){if(w[E].isParent()){a._private.hasCompoundNodes=!0;break}}var _=new Da(this.cy(),r);_.size()>0&&(e?_.emitAndNotify("remove"):t&&_.emit("remove"));for(var T=0;T<h.length;T++){var D=h[T];t&&D.removed()||D.updateStyle()}return _},Ca.move=function(e){var t=this._private.cy,n=this,r=!1,i=!1,a=function(e){return null==e?e:""+e};if(void 0!==e.source||void 0!==e.target){var o=a(e.source),s=a(e.target),l=null!=o&&t.hasElementWithId(o),u=null!=s&&t.hasElementWithId(s);(l||u)&&(t.batch((function(){n.remove(r,i),n.emitAndNotify("moveout");for(var e=0;e<n.length;e++){var t=n[e],a=t._private.data;t.isEdge()&&(l&&(a.source=o),u&&(a.target=s))}n.restore(r,i)})),n.emitAndNotify("move"))}else if(void 0!==e.parent){var c=a(e.parent);if(null===c||t.hasElementWithId(c)){var h=null===c?void 0:c;t.batch((function(){var e=n.remove(r,i);e.emitAndNotify("moveout");for(var t=0;t<n.length;t++){var a=n[t],o=a._private.data;a.isNode()&&(o.parent=h)}e.restore(r,i)})),n.emitAndNotify("move")}}return this},[Kn,cr,hr,$r,Jr,oi,si,Pi,Ki,Zi,{isNode:function(){return"nodes"===this.group()},isEdge:function(){return"edges"===this.group()},isLoop:function(){return this.isEdge()&&this.source()[0]===this.target()[0]},isSimple:function(){return this.isEdge()&&this.source()[0]!==this.target()[0]},group:function(){var e=this[0];if(e)return e._private.group}},ea,ra,sa,fa,ma].forEach((function(e){Q(Ca,e)}));var Na={add:function(e){var t,n=this;if(O(e)){var r=e;if(r._private.cy===n)t=r.restore();else{for(var i=[],a=0;a<r.length;a++){var o=r[a];i.push(o.json())}t=new Da(n,i)}}else if(k(e)){t=new Da(n,e)}else if(S(e)&&(k(e.nodes)||k(e.edges))){for(var s=e,l=[],u=["nodes","edges"],c=0,h=u.length;c<h;c++){var d=u[c],p=s[d];if(k(p))for(var g=0,f=p.length;g<f;g++){var v=Q({group:d},p[g]);l.push(v)}}t=new Da(n,l)}else{t=new Ye(n,e).collection()}return t},remove:function(e){if(O(e));else if(A(e)){var t=e;e=this.$(t)}return e.remove()}};function Aa(e,t,n,r){var i=4,a=1e-7,o=10,s=11,l=1/(s-1),u="undefined"!=typeof Float32Array;if(4!==arguments.length)return!1;for(var c=0;c<4;++c)if("number"!=typeof arguments[c]||isNaN(arguments[c])||!isFinite(arguments[c]))return!1;e=Math.min(e,1),n=Math.min(n,1),e=Math.max(e,0),n=Math.max(n,0);var h=u?new Float32Array(s):new Array(s);function d(e,t){return 1-3*t+3*e}function p(e,t){return 3*t-6*e}function g(e){return 3*e}function f(e,t,n){return((d(t,n)*e+p(t,n))*e+g(t))*e}function v(e,t,n){return 3*d(t,n)*e*e+2*p(t,n)*e+g(t)}function y(t){for(var r=0,u=1,c=s-1;u!==c&&h[u]<=t;++u)r+=l;--u;var d=r+(t-h[u])/(h[u+1]-h[u])*l,p=v(d,e,n);return p>=.001?function(t,r){for(var a=0;a<i;++a){var o=v(r,e,n);if(0===o)return r;r-=(f(r,e,n)-t)/o}return r}(t,d):0===p?d:function(t,r,i){var s,l,u=0;do{(s=f(l=r+(i-r)/2,e,n)-t)>0?i=l:r=l}while(Math.abs(s)>a&&++u<o);return l}(t,r,r+l)}var m=!1;function b(){m=!0,e===t&&n===r||function(){for(var t=0;t<s;++t)h[t]=f(t*l,e,n)}()}var x=function(i){return m||b(),e===t&&n===r?i:0===i?0:1===i?1:f(y(i),t,r)};x.getControlPoints=function(){return[{x:e,y:t},{x:n,y:r}]};var w="generateBezier("+[e,t,n,r]+")";return x.toString=function(){return w},x}var La=function(){function e(e){return-e.tension*e.x-e.friction*e.v}function t(t,n,r){var i={x:t.x+r.dx*n,v:t.v+r.dv*n,tension:t.tension,friction:t.friction};return{dx:i.v,dv:e(i)}}function n(n,r){var i={dx:n.v,dv:e(n)},a=t(n,.5*r,i),o=t(n,.5*r,a),s=t(n,r,o),l=1/6*(i.dx+2*(a.dx+o.dx)+s.dx),u=1/6*(i.dv+2*(a.dv+o.dv)+s.dv);return n.x=n.x+l*r,n.v=n.v+u*r,n}return function e(t,r,i){var a,o,s,l={x:-1,v:0,tension:null,friction:null},u=[0],c=0,h=1e-4;for(t=parseFloat(t)||500,r=parseFloat(r)||20,i=i||null,l.tension=t,l.friction=r,o=(a=null!==i)?(c=e(t,r))/i*.016:.016;s=n(s||l,o),u.push(1+s.x),c+=16,Math.abs(s.x)>h&&Math.abs(s.v)>h;);return a?function(e){return u[e*(u.length-1)|0]}:c}}(),ka=function(e,t,n,r){var i=Aa(e,t,n,r);return function(e,t,n){return e+(t-e)*i(n)}},Sa={linear:function(e,t,n){return e+(t-e)*n},ease:ka(.25,.1,.25,1),"ease-in":ka(.42,0,1,1),"ease-out":ka(0,0,.58,1),"ease-in-out":ka(.42,0,.58,1),"ease-in-sine":ka(.47,0,.745,.715),"ease-out-sine":ka(.39,.575,.565,1),"ease-in-out-sine":ka(.445,.05,.55,.95),"ease-in-quad":ka(.55,.085,.68,.53),"ease-out-quad":ka(.25,.46,.45,.94),"ease-in-out-quad":ka(.455,.03,.515,.955),"ease-in-cubic":ka(.55,.055,.675,.19),"ease-out-cubic":ka(.215,.61,.355,1),"ease-in-out-cubic":ka(.645,.045,.355,1),"ease-in-quart":ka(.895,.03,.685,.22),"ease-out-quart":ka(.165,.84,.44,1),"ease-in-out-quart":ka(.77,0,.175,1),"ease-in-quint":ka(.755,.05,.855,.06),"ease-out-quint":ka(.23,1,.32,1),"ease-in-out-quint":ka(.86,0,.07,1),"ease-in-expo":ka(.95,.05,.795,.035),"ease-out-expo":ka(.19,1,.22,1),"ease-in-out-expo":ka(1,0,0,1),"ease-in-circ":ka(.6,.04,.98,.335),"ease-out-circ":ka(.075,.82,.165,1),"ease-in-out-circ":ka(.785,.135,.15,.86),spring:function(e,t,n){if(0===n)return Sa.linear;var r=La(e,t,n);return function(e,t,n){return e+(t-e)*r(n)}},"cubic-bezier":ka};function Ia(e,t,n,r,i){if(1===r)return n;if(t===n)return n;var a=i(t,n,r);return null==e||((e.roundValue||e.color)&&(a=Math.round(a)),void 0!==e.min&&(a=Math.max(a,e.min)),void 0!==e.max&&(a=Math.min(a,e.max))),a}function Ma(e,t){return null!=e.pfValue||null!=e.value?null==e.pfValue||null!=t&&"%"===t.type.units?e.value:e.pfValue:e}function Oa(e,t,n,r,i){var a=null!=i?i.type:null;n<0?n=0:n>1&&(n=1);var o=Ma(e,i),s=Ma(t,i);if(I(o)&&I(s))return Ia(a,o,s,n,r);if(k(o)&&k(s)){for(var l=[],u=0;u<s.length;u++){var c=o[u],h=s[u];if(null!=c&&null!=h){var d=Ia(a,c,h,n,r);l.push(d)}else l.push(h)}return l}}function Pa(e,t,n,r){var i=!r,a=e._private,o=t._private,s=o.easing,l=o.startTime,u=(r?e:e.cy()).style();if(!o.easingImpl)if(null==s)o.easingImpl=Sa.linear;else{var c,h,d;if(A(s))c=u.parse("transition-timing-function",s).value;else c=s;A(c)?(h=c,d=[]):(h=c[1],d=c.slice(2).map((function(e){return+e}))),d.length>0?("spring"===h&&d.push(o.duration),o.easingImpl=Sa[h].apply(null,d)):o.easingImpl=Sa[h]}var p,g=o.easingImpl;if(p=0===o.duration?1:(n-l)/o.duration,o.applying&&(p=o.progress),p<0?p=0:p>1&&(p=1),null==o.delay){var f=o.startPosition,v=o.position;if(v&&i&&!e.locked()){var y={};Ra(f.x,v.x)&&(y.x=Oa(f.x,v.x,p,g)),Ra(f.y,v.y)&&(y.y=Oa(f.y,v.y,p,g)),e.position(y)}var m=o.startPan,b=o.pan,x=a.pan,w=null!=b&&r;w&&(Ra(m.x,b.x)&&(x.x=Oa(m.x,b.x,p,g)),Ra(m.y,b.y)&&(x.y=Oa(m.y,b.y,p,g)),e.emit("pan"));var E=o.startZoom,_=o.zoom,T=null!=_&&r;T&&(Ra(E,_)&&(a.zoom=gt(a.minZoom,Oa(E,_,p,g),a.maxZoom)),e.emit("zoom")),(w||T)&&e.emit("viewport");var D=o.style;if(D&&D.length>0&&i){for(var C=0;C<D.length;C++){var N=D[C],L=N.name,k=N,S=o.startStyle[L],I=Oa(S,k,p,g,u.properties[S.name]);u.overrideBypass(e,L,I)}e.emit("style")}}return o.progress=p,p}function Ra(e,t){return null!=e&&null!=t&&(!(!I(e)||!I(t))||!(!e||!t))}function Ba(e,t,n,r){var i=t._private;i.started=!0,i.startTime=n-i.progress*i.duration}function Fa(e,t){var n=t._private.aniEles,r=[];function i(t,n){var i=t._private,a=i.animation.current,o=i.animation.queue,s=!1;if(0===a.length){var l=o.shift();l&&a.push(l)}for(var u=function(e){for(var t=e.length-1;t>=0;t--){(0,e[t])()}e.splice(0,e.length)},c=a.length-1;c>=0;c--){var h=a[c],d=h._private;d.stopped?(a.splice(c,1),d.hooked=!1,d.playing=!1,d.started=!1,u(d.frames)):(d.playing||d.applying)&&(d.playing&&d.applying&&(d.applying=!1),d.started||Ba(0,h,e),Pa(t,h,e,n),d.applying&&(d.applying=!1),u(d.frames),null!=d.step&&d.step(e),h.completed()&&(a.splice(c,1),d.hooked=!1,d.playing=!1,d.started=!1,u(d.completes)),s=!0)}return n||0!==a.length||0!==o.length||r.push(t),s}for(var a=!1,o=0;o<n.length;o++){var s=i(n[o]);a=a||s}var l=i(t,!0);(a||l)&&(n.length>0?t.notify("draw",n):t.notify("draw")),n.unmerge(r),t.emit("step")}var za={animate:ur.animate(),animation:ur.animation(),animated:ur.animated(),clearQueue:ur.clearQueue(),delay:ur.delay(),delayAnimation:ur.delayAnimation(),stop:ur.stop(),addToAnimationPool:function(e){this.styleEnabled()&&this._private.aniEles.merge(e)},stopAnimationLoop:function(){this._private.animationsRunning=!1},startAnimationLoop:function(){var e=this;if(e._private.animationsRunning=!0,e.styleEnabled()){var t=e.renderer();t&&t.beforeRender?t.beforeRender((function(t,n){Fa(n,e)}),t.beforeRenderPriorities.animations):function t(){e._private.animationsRunning&&oe((function(n){Fa(n,e),t()}))}()}}},Ga={qualifierCompare:function(e,t){return null==e||null==t?null==e&&null==t:e.sameText(t)},eventMatches:function(e,t,n){var r=t.qualifier;return null==r||e!==n.target&&P(n.target)&&r.matches(n.target)},addEventFields:function(e,t){t.cy=e,t.target=e},callbackContext:function(e,t,n){return null!=t.qualifier?n.target:e}},Ya=function(e){return A(e)?new Hr(e):e},Xa={createEmitter:function(){var e=this._private;return e.emitter||(e.emitter=new Vi(Ga,this)),this},emitter:function(){return this._private.emitter},on:function(e,t,n){return this.emitter().on(e,Ya(t),n),this},removeListener:function(e,t,n){return this.emitter().removeListener(e,Ya(t),n),this},removeAllListeners:function(){return this.emitter().removeAllListeners(),this},one:function(e,t,n){return this.emitter().one(e,Ya(t),n),this},once:function(e,t,n){return this.emitter().one(e,Ya(t),n),this},emit:function(e,t){return this.emitter().emit(e,t),this},emitAndNotify:function(e,t){return this.emit(e),this.notify(e,t),this}};ur.eventAliasesOn(Xa);var Va={png:function(e){return e=e||{},this._private.renderer.png(e)},jpg:function(e){var t=this._private.renderer;return(e=e||{}).bg=e.bg||"#fff",t.jpg(e)}};Va.jpeg=Va.jpg;var Ua={layout:function(e){var t=this;if(null!=e)if(null!=e.name){var n=e.name,r=t.extension("layout",n);if(null!=r){var i;i=A(e.eles)?t.$(e.eles):null!=e.eles?e.eles:t.$();var a=new r(Q({},e,{cy:t,eles:i}));return a}Ce("No such layout `"+n+"` found. Did you forget to import it and `cytoscape.use()` it?")}else Ce("A `name` must be specified to make a layout");else Ce("Layout options must be specified to make a layout")}};Ua.createLayout=Ua.makeLayout=Ua.layout;var ja={notify:function(e,t){var n=this._private;if(this.batching()){n.batchNotifications=n.batchNotifications||{};var r=n.batchNotifications[e]=n.batchNotifications[e]||this.collection();null!=t&&r.merge(t)}else if(n.notificationsEnabled){var i=this.renderer();!this.destroyed()&&i&&i.notify(e,t)}},notifications:function(e){var t=this._private;return void 0===e?t.notificationsEnabled:(t.notificationsEnabled=!!e,this)},noNotifications:function(e){this.notifications(!1),e(),this.notifications(!0)},batching:function(){return this._private.batchCount>0},startBatch:function(){var e=this._private;return null==e.batchCount&&(e.batchCount=0),0===e.batchCount&&(e.batchStyleEles=this.collection(),e.batchNotifications={}),e.batchCount++,this},endBatch:function(){var e=this._private;if(0===e.batchCount)return this;if(e.batchCount--,0===e.batchCount){e.batchStyleEles.updateStyle();var t=this.renderer();Object.keys(e.batchNotifications).forEach((function(n){var r=e.batchNotifications[n];r.empty()?t.notify(n):t.notify(n,r)}))}return this},batch:function(e){return this.startBatch(),e(),this.endBatch(),this},batchData:function(e){var t=this;return this.batch((function(){for(var n=Object.keys(e),r=0;r<n.length;r++){var i=n[r],a=e[i];t.getElementById(i).data(a)}}))}},qa=Me({hideEdgesOnViewport:!1,textureOnViewport:!1,motionBlur:!1,motionBlurOpacity:.05,pixelRatio:void 0,desktopTapThreshold:4,touchTapThreshold:8,wheelSensitivity:1,debug:!1,showFps:!1}),Ha={renderTo:function(e,t,n,r){return this._private.renderer.renderTo(e,t,n,r),this},renderer:function(){return this._private.renderer},forceRender:function(){return this.notify("draw"),this},resize:function(){return this.invalidateSize(),this.emitAndNotify("resize"),this},initRenderer:function(e){var t=this,n=t.extension("renderer",e.name);if(null!=n){void 0!==e.wheelSensitivity&&Ae("You have set a custom wheel sensitivity. This will make your app zoom unnaturally when using mainstream mice. You should change this value from the default only if you can guarantee that all your users will use the same hardware and OS configuration as your current machine.");var r=qa(e);r.cy=t,t._private.renderer=new n(r),this.notify("init")}else Ce("Can not initialise: No such renderer `".concat(e.name,"` found. Did you forget to import it and `cytoscape.use()` it?"))},destroyRenderer:function(){var e=this;e.notify("destroy");var t=e.container();if(t)for(t._cyreg=null;t.childNodes.length>0;)t.removeChild(t.childNodes[0]);e._private.renderer=null,e.mutableElements().forEach((function(e){var t=e._private;t.rscratch={},t.rstyle={},t.animation.current=[],t.animation.queue=[]}))},onRender:function(e){return this.on("render",e)},offRender:function(e){return this.off("render",e)}};Ha.invalidateDimensions=Ha.resize;var Wa={collection:function(e,t){return A(e)?this.$(e):O(e)?e.collection():k(e)?(t||(t={}),new Da(this,e,t.unique,t.removed)):new Da(this)},nodes:function(e){var t=this.$((function(e){return e.isNode()}));return e?t.filter(e):t},edges:function(e){var t=this.$((function(e){return e.isEdge()}));return e?t.filter(e):t},$:function(e){var t=this._private.elements;return e?t.filter(e):t.spawnSelf()},mutableElements:function(){return this._private.elements}};Wa.elements=Wa.filter=Wa.$;var $a={},Ka="t";$a.apply=function(e){for(var t=this,n=t._private.cy.collection(),r=0;r<e.length;r++){var i=e[r],a=t.getContextMeta(i);if(!a.empty){var o=t.getContextStyle(a),s=t.applyContextStyle(a,o,i);i._private.appliedInitStyle?t.updateTransitions(i,s.diffProps):i._private.appliedInitStyle=!0,t.updateStyleHints(i)&&n.push(i)}}return n},$a.getPropertiesDiff=function(e,t){var n=this,r=n._private.propDiffs=n._private.propDiffs||{},i=e+"-"+t,a=r[i];if(a)return a;for(var o=[],s={},l=0;l<n.length;l++){var u=n[l],c=e[l]===Ka,h=t[l]===Ka,d=c!==h,p=u.mappedProperties.length>0;if(d||h&&p){var g=void 0;d&&p||d?g=u.properties:p&&(g=u.mappedProperties);for(var f=0;f<g.length;f++){for(var v=g[f],y=v.name,m=!1,b=l+1;b<n.length;b++){var x=n[b];if(t[b]===Ka&&(m=null!=x.properties[v.name]))break}s[y]||m||(s[y]=!0,o.push(y))}}}return r[i]=o,o},$a.getContextMeta=function(e){for(var t,n=this,r="",i=e._private.styleCxtKey||"",a=0;a<n.length;a++){var o=n[a];r+=o.selector&&o.selector.matches(e)?Ka:"f"}return t=n.getPropertiesDiff(i,r),e._private.styleCxtKey=r,{key:r,diffPropNames:t,empty:0===t.length}},$a.getContextStyle=function(e){var t=e.key,n=this._private.contextStyles=this._private.contextStyles||{};if(n[t])return n[t];for(var r={_private:{key:t}},i=0;i<this.length;i++){var a=this[i];if(t[i]===Ka)for(var o=0;o<a.properties.length;o++){var s=a.properties[o];r[s.name]=s}}return n[t]=r,r},$a.applyContextStyle=function(e,t,n){for(var r=e.diffPropNames,i={},a=this.types,o=0;o<r.length;o++){var s=r[o],l=t[s],u=n.pstyle(s);if(!l){if(!u)continue;l=u.bypass?{name:s,deleteBypassed:!0}:{name:s,delete:!0}}if(u!==l){if(l.mapped===a.fn&&null!=u&&null!=u.mapping&&u.mapping.value===l.value){var c=u.mapping;if((c.fnValue=l.value(n))===c.prevFnValue)continue}var h=i[s]={prev:u};this.applyParsedProperty(n,l),h.next=n.pstyle(s),h.next&&h.next.bypass&&(h.next=h.next.bypassed)}}return{diffProps:i}},$a.updateStyleHints=function(e){var t=e._private,n=this,r=n.propertyGroupNames,i=n.propertyGroupKeys,a=function(e,t,r){return n.getPropertiesHash(e,t,r)},o=t.styleKey;if(e.removed())return!1;var s="nodes"===t.group,l=e._private.style;r=Object.keys(l);for(var u=0;u<i.length;u++){var c=i[u];t.styleKeys[c]=[le,ue]}for(var h,d=function(e,n){return t.styleKeys[n][0]=he(e,t.styleKeys[n][0])},p=function(e,n){return t.styleKeys[n][1]=de(e,t.styleKeys[n][1])},g=function(e,t){d(e,t),p(e,t)},f=function(e,t){for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);d(r,t),p(r,t)}},v=0;v<r.length;v++){var y=r[v],m=l[y];if(null!=m){var b=this.properties[y],x=b.type,w=b.groupKey,E=void 0;null!=b.hashOverride?E=b.hashOverride(e,m):null!=m.pfValue&&(E=m.pfValue);var _=null==b.enums?m.value:null,T=null!=E,D=T||null!=_,C=m.units;if(x.number&&D&&!x.multiple)g(-128<(h=T?E:_)&&h<128&&Math.floor(h)!==h?2e9-(1024*h|0):h,w),T||null==C||f(C,w);else f(m.strValue,w)}}for(var N,A,L=[le,ue],k=0;k<i.length;k++){var S=i[k],I=t.styleKeys[S];L[0]=he(I[0],L[0]),L[1]=de(I[1],L[1])}t.styleKey=(N=L[0],A=L[1],2097152*N+A);var M=t.styleKeys;t.labelDimsKey=pe(M.labelDimensions);var O=a(e,["label"],M.labelDimensions);if(t.labelKey=pe(O),t.labelStyleKey=pe(ge(M.commonLabel,O)),!s){var P=a(e,["source-label"],M.labelDimensions);t.sourceLabelKey=pe(P),t.sourceLabelStyleKey=pe(ge(M.commonLabel,P));var R=a(e,["target-label"],M.labelDimensions);t.targetLabelKey=pe(R),t.targetLabelStyleKey=pe(ge(M.commonLabel,R))}if(s){var B=t.styleKeys,F=B.nodeBody,z=B.nodeBorder,G=B.nodeOutline,Y=B.backgroundImage,X=B.compound,V=B.pie,U=[F,z,G,Y,X,V].filter((function(e){return null!=e})).reduce(ge,[le,ue]);t.nodeKey=pe(U),t.hasPie=null!=V&&V[0]!==le&&V[1]!==ue}return o!==t.styleKey},$a.clearStyleHints=function(e){var t=e._private;t.styleCxtKey="",t.styleKeys={},t.styleKey=null,t.labelKey=null,t.labelStyleKey=null,t.sourceLabelKey=null,t.sourceLabelStyleKey=null,t.targetLabelKey=null,t.targetLabelStyleKey=null,t.nodeKey=null,t.hasPie=null},$a.applyParsedProperty=function(e,t){var n,r=this,i=t,a=e._private.style,o=r.types,s=r.properties[i.name].type,l=i.bypass,u=a[i.name],c=u&&u.bypass,h=e._private,d="mapping",p=function(e){return null==e?null:null!=e.pfValue?e.pfValue:e.value},g=function(){var t=p(u),n=p(i);r.checkTriggers(e,i.name,t,n)};if("curve-style"===t.name&&e.isEdge()&&("bezier"!==t.value&&e.isLoop()||"haystack"===t.value&&(e.source().isParent()||e.target().isParent()))&&(i=t=this.parse(t.name,"bezier",l)),i.delete)return a[i.name]=void 0,g(),!0;if(i.deleteBypassed)return u?!!u.bypass&&(u.bypassed=void 0,g(),!0):(g(),!0);if(i.deleteBypass)return u?!!u.bypass&&(a[i.name]=u.bypassed,g(),!0):(g(),!0);var f=function(){Ae("Do not assign mappings to elements without corresponding data (i.e. ele `"+e.id()+"` has no mapping for property `"+i.name+"` with data field `"+i.field+"`); try a `["+i.field+"]` selector to limit scope to elements with `"+i.field+"` defined")};switch(i.mapped){case o.mapData:for(var v,y=i.field.split("."),m=h.data,b=0;b<y.length&&m;b++){m=m[y[b]]}if(null==m)return f(),!1;if(!I(m))return Ae("Do not use continuous mappers without specifying numeric data (i.e. `"+i.field+": "+m+"` for `"+e.id()+"` is non-numeric)"),!1;var x=i.fieldMax-i.fieldMin;if((v=0===x?0:(m-i.fieldMin)/x)<0?v=0:v>1&&(v=1),s.color){var w=i.valueMin[0],E=i.valueMax[0],_=i.valueMin[1],T=i.valueMax[1],D=i.valueMin[2],C=i.valueMax[2],N=null==i.valueMin[3]?1:i.valueMin[3],A=null==i.valueMax[3]?1:i.valueMax[3],L=[Math.round(w+(E-w)*v),Math.round(_+(T-_)*v),Math.round(D+(C-D)*v),Math.round(N+(A-N)*v)];n={bypass:i.bypass,name:i.name,value:L,strValue:"rgb("+L[0]+", "+L[1]+", "+L[2]+")"}}else{if(!s.number)return!1;var k=i.valueMin+(i.valueMax-i.valueMin)*v;n=this.parse(i.name,k,i.bypass,d)}if(!n)return f(),!1;n.mapping=i,i=n;break;case o.data:for(var S=i.field.split("."),M=h.data,O=0;O<S.length&&M;O++){M=M[S[O]]}if(null!=M&&(n=this.parse(i.name,M,i.bypass,d)),!n)return f(),!1;n.mapping=i,i=n;break;case o.fn:var P=i.value,R=null!=i.fnValue?i.fnValue:P(e);if(i.prevFnValue=R,null==R)return Ae("Custom function mappers may not return null (i.e. `"+i.name+"` for ele `"+e.id()+"` is null)"),!1;if(!(n=this.parse(i.name,R,i.bypass,d)))return Ae("Custom function mappers may not return invalid values for the property type (i.e. `"+i.name+"` for ele `"+e.id()+"` is invalid)"),!1;n.mapping=Le(i),i=n;break;case void 0:break;default:return!1}return l?(i.bypassed=c?u.bypassed:u,a[i.name]=i):c?u.bypassed=i:a[i.name]=i,g(),!0},$a.cleanElements=function(e,t){for(var n=0;n<e.length;n++){var r=e[n];if(this.clearStyleHints(r),r.dirtyCompoundBoundsCache(),r.dirtyBoundingBoxCache(),t)for(var i=r._private.style,a=Object.keys(i),o=0;o<a.length;o++){var s=a[o],l=i[s];null!=l&&(l.bypass?l.bypassed=null:i[s]=null)}else r._private.style={}}},$a.update=function(){this._private.cy.mutableElements().updateStyle()},$a.updateTransitions=function(e,t){var n=this,r=e._private,i=e.pstyle("transition-property").value,a=e.pstyle("transition-duration").pfValue,o=e.pstyle("transition-delay").pfValue;if(i.length>0&&a>0){for(var s={},l=!1,u=0;u<i.length;u++){var c=i[u],h=e.pstyle(c),d=t[c];if(d){var p=d.prev,g=null!=d.next?d.next:h,f=!1,v=void 0,y=1e-6;p&&(I(p.pfValue)&&I(g.pfValue)?(f=g.pfValue-p.pfValue,v=p.pfValue+y*f):I(p.value)&&I(g.value)?(f=g.value-p.value,v=p.value+y*f):k(p.value)&&k(g.value)&&(f=p.value[0]!==g.value[0]||p.value[1]!==g.value[1]||p.value[2]!==g.value[2],v=p.strValue),f&&(s[c]=g.strValue,this.applyBypass(e,c,v),l=!0))}}if(!l)return;r.transitioning=!0,new rr((function(t){o>0?e.delayAnimation(o).play().promise().then(t):t()})).then((function(){return e.animation({style:s,duration:a,easing:e.pstyle("transition-timing-function").value,queue:!1}).play().promise()})).then((function(){n.removeBypasses(e,i),e.emitAndNotify("style"),r.transitioning=!1}))}else r.transitioning&&(this.removeBypasses(e,i),e.emitAndNotify("style"),r.transitioning=!1)},$a.checkTrigger=function(e,t,n,r,i,a){var o=this.properties[t],s=i(o);null!=s&&s(n,r)&&a(o)},$a.checkZOrderTrigger=function(e,t,n,r){var i=this;this.checkTrigger(e,t,n,r,(function(e){return e.triggersZOrder}),(function(){i._private.cy.notify("zorder",e)}))},$a.checkBoundsTrigger=function(e,t,n,r){this.checkTrigger(e,t,n,r,(function(e){return e.triggersBounds}),(function(i){e.dirtyCompoundBoundsCache(),e.dirtyBoundingBoxCache(),!i.triggersBoundsOfParallelBeziers||"curve-style"!==t||"bezier"!==n&&"bezier"!==r||e.parallelEdges().forEach((function(e){e.isBundledBezier()&&e.dirtyBoundingBoxCache()})),!i.triggersBoundsOfConnectedEdges||"display"!==t||"none"!==n&&"none"!==r||e.connectedEdges().forEach((function(e){e.dirtyBoundingBoxCache()}))}))},$a.checkTriggers=function(e,t,n,r){e.dirtyStyleCache(),this.checkZOrderTrigger(e,t,n,r),this.checkBoundsTrigger(e,t,n,r)};var Za={applyBypass:function(e,t,n,r){var i=[];if("*"===t||"**"===t){if(void 0!==n)for(var a=0;a<this.properties.length;a++){var o=this.properties[a].name,s=this.parse(o,n,!0);s&&i.push(s)}}else if(A(t)){var l=this.parse(t,n,!0);l&&i.push(l)}else{if(!S(t))return!1;var u=t;r=n;for(var c=Object.keys(u),h=0;h<c.length;h++){var d=c[h],p=u[d];if(void 0===p&&(p=u[V(d)]),void 0!==p){var g=this.parse(d,p,!0);g&&i.push(g)}}}if(0===i.length)return!1;for(var f=!1,v=0;v<e.length;v++){for(var y=e[v],m={},b=void 0,x=0;x<i.length;x++){var w=i[x];if(r){var E=y.pstyle(w.name);b=m[w.name]={prev:E}}f=this.applyParsedProperty(y,Le(w))||f,r&&(b.next=y.pstyle(w.name))}f&&this.updateStyleHints(y),r&&this.updateTransitions(y,m,true)}return f},overrideBypass:function(e,t,n){t=X(t);for(var r=0;r<e.length;r++){var i=e[r],a=i._private.style[t],o=this.properties[t].type,s=o.color,l=o.mutiple,u=a?null!=a.pfValue?a.pfValue:a.value:null;a&&a.bypass?(a.value=n,null!=a.pfValue&&(a.pfValue=n),a.strValue=s?"rgb("+n.join(",")+")":l?n.join(" "):""+n,this.updateStyleHints(i)):this.applyBypass(i,t,n),this.checkTriggers(i,t,u,n)}},removeAllBypasses:function(e,t){return this.removeBypasses(e,this.propertyNames,t)},removeBypasses:function(e,t,n){for(var r=0;r<e.length;r++){for(var i=e[r],a={},o=0;o<t.length;o++){var s=t[o],l=this.properties[s],u=i.pstyle(l.name);if(u&&u.bypass){var c=this.parse(s,"",!0),h=a[l.name]={prev:u};this.applyParsedProperty(i,c),h.next=i.pstyle(l.name)}}this.updateStyleHints(i),n&&this.updateTransitions(i,a,true)}}},Qa={getEmSizeInPixels:function(){var e=this.containerCss("font-size");return null!=e?parseFloat(e):1},containerCss:function(e){var t=this._private.cy,n=t.container(),r=t.window();if(r&&n&&r.getComputedStyle)return r.getComputedStyle(n).getPropertyValue(e)}},Ja={getRenderedStyle:function(e,t){return t?this.getStylePropertyValue(e,t,!0):this.getRawStyle(e,!0)},getRawStyle:function(e,t){var n=this;if(e=e[0]){for(var r={},i=0;i<n.properties.length;i++){var a=n.properties[i],o=n.getStylePropertyValue(e,a.name,t);null!=o&&(r[a.name]=o,r[V(a.name)]=o)}return r}},getIndexedStyle:function(e,t,n,r){var i=e.pstyle(t)[n][r];return null!=i?i:e.cy().style().getDefaultProperty(t)[n][0]},getStylePropertyValue:function(e,t,n){if(e=e[0]){var r=this.properties[t];r.alias&&(r=r.pointsTo);var i=r.type,a=e.pstyle(r.name);if(a){var o=a.value,s=a.units,l=a.strValue;if(n&&i.number&&null!=o&&I(o)){var u=e.cy().zoom(),c=function(e){return e*u},h=function(e,t){return c(e)+t},d=k(o);return(d?s.every((function(e){return null!=e})):null!=s)?d?o.map((function(e,t){return h(e,s[t])})).join(" "):h(o,s):d?o.map((function(e){return A(e)?e:""+c(e)})).join(" "):""+c(o)}if(null!=l)return l}return null}},getAnimationStartStyle:function(e,t){for(var n={},r=0;r<t.length;r++){var i=t[r].name,a=e.pstyle(i);void 0!==a&&(a=S(a)?this.parse(i,a.strValue):this.parse(i,a)),a&&(n[i]=a)}return n},getPropsList:function(e){var t=[],n=e,r=this.properties;if(n)for(var i=Object.keys(n),a=0;a<i.length;a++){var o=i[a],s=n[o],l=r[o]||r[X(o)],u=this.parse(l.name,s);u&&t.push(u)}return t},getNonDefaultPropertiesHash:function(e,t,n){var r,i,a,o,s,l,u=n.slice();for(s=0;s<t.length;s++)if(r=t[s],null!=(i=e.pstyle(r,!1)))if(null!=i.pfValue)u[0]=he(o,u[0]),u[1]=de(o,u[1]);else for(a=i.strValue,l=0;l<a.length;l++)o=a.charCodeAt(l),u[0]=he(o,u[0]),u[1]=de(o,u[1]);return u}};Ja.getPropertiesHash=Ja.getNonDefaultPropertiesHash;var eo={appendFromJson:function(e){for(var t=this,n=0;n<e.length;n++){var r=e[n],i=r.selector,a=r.style||r.css,o=Object.keys(a);t.selector(i);for(var s=0;s<o.length;s++){var l=o[s],u=a[l];t.css(l,u)}}return t},fromJson:function(e){var t=this;return t.resetToDefault(),t.appendFromJson(e),t},json:function(){for(var e=[],t=this.defaultLength;t<this.length;t++){for(var n=this[t],r=n.selector,i=n.properties,a={},o=0;o<i.length;o++){var s=i[o];a[s.name]=s.strValue}e.push({selector:r?r.toString():"core",style:a})}return e}},to={appendFromString:function(e){var t,n,r,i=this,a=""+e;function o(){a=a.length>t.length?a.substr(t.length):""}function s(){n=n.length>r.length?n.substr(r.length):""}for(a=a.replace(/[/][*](\s|.)+?[*][/]/g,"");;){if(a.match(/^\s*$/))break;var l=a.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!l){Ae("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+a);break}t=l[0];var u=l[1];if("core"!==u)if(new Hr(u).invalid){Ae("Skipping parsing of block: Invalid selector found in string stylesheet: "+u),o();continue}var c=l[2],h=!1;n=c;for(var d=[];;){if(n.match(/^\s*$/))break;var p=n.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);if(!p){Ae("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+c),h=!0;break}r=p[0];var g=p[1],f=p[2];if(this.properties[g])i.parse(g,f)?(d.push({name:g,val:f}),s()):(Ae("Skipping property: Invalid property definition in: "+r),s());else Ae("Skipping property: Invalid property name in: "+r),s()}if(h){o();break}i.selector(u);for(var v=0;v<d.length;v++){var y=d[v];i.css(y.name,y.val)}o()}return i},fromString:function(e){var t=this;return t.resetToDefault(),t.appendFromString(e),t}},no={};!function(){var e=q,t=W,n=K,r=function(e){return"^"+e+"\\s*\\(\\s*([\\w\\.]+)\\s*\\)$"},i=function(r){var i=e+"|\\w+|"+t+"|"+n+"|\\#[0-9a-fA-F]{3}|\\#[0-9a-fA-F]{6}";return"^"+r+"\\s*\\(([\\w\\.]+)\\s*\\,\\s*("+e+")\\s*\\,\\s*("+e+")\\s*,\\s*("+i+")\\s*\\,\\s*("+i+")\\)$"},a=["^url\\s*\\(\\s*['\"]?(.+?)['\"]?\\s*\\)$","^(none)$","^(.+)$"];no.types={time:{number:!0,min:0,units:"s|ms",implicitUnits:"ms"},percent:{number:!0,min:0,max:100,units:"%",implicitUnits:"%"},percentages:{number:!0,min:0,max:100,units:"%",implicitUnits:"%",multiple:!0},zeroOneNumber:{number:!0,min:0,max:1,unitless:!0},zeroOneNumbers:{number:!0,min:0,max:1,unitless:!0,multiple:!0},nOneOneNumber:{number:!0,min:-1,max:1,unitless:!0},nonNegativeInt:{number:!0,min:0,integer:!0,unitless:!0},nonNegativeNumber:{number:!0,min:0,unitless:!0},position:{enums:["parent","origin"]},nodeSize:{number:!0,min:0,enums:["label"]},number:{number:!0,unitless:!0},numbers:{number:!0,unitless:!0,multiple:!0},positiveNumber:{number:!0,unitless:!0,min:0,strictMin:!0},size:{number:!0,min:0},bidirectionalSize:{number:!0},bidirectionalSizeMaybePercent:{number:!0,allowPercent:!0},bidirectionalSizes:{number:!0,multiple:!0},sizeMaybePercent:{number:!0,min:0,allowPercent:!0},axisDirection:{enums:["horizontal","leftward","rightward","vertical","upward","downward","auto"]},paddingRelativeTo:{enums:["width","height","average","min","max"]},bgWH:{number:!0,min:0,allowPercent:!0,enums:["auto"],multiple:!0},bgPos:{number:!0,allowPercent:!0,multiple:!0},bgRelativeTo:{enums:["inner","include-padding"],multiple:!0},bgRepeat:{enums:["repeat","repeat-x","repeat-y","no-repeat"],multiple:!0},bgFit:{enums:["none","contain","cover"],multiple:!0},bgCrossOrigin:{enums:["anonymous","use-credentials","null"],multiple:!0},bgClip:{enums:["none","node"],multiple:!0},bgContainment:{enums:["inside","over"],multiple:!0},color:{color:!0},colors:{color:!0,multiple:!0},fill:{enums:["solid","linear-gradient","radial-gradient"]},bool:{enums:["yes","no"]},bools:{enums:["yes","no"],multiple:!0},lineStyle:{enums:["solid","dotted","dashed"]},lineCap:{enums:["butt","round","square"]},borderStyle:{enums:["solid","dotted","dashed","double"]},curveStyle:{enums:["bezier","unbundled-bezier","haystack","segments","straight","straight-triangle","taxi"]},fontFamily:{regex:'^([\\w- \\"]+(?:\\s*,\\s*[\\w- \\"]+)*)$'},fontStyle:{enums:["italic","normal","oblique"]},fontWeight:{enums:["normal","bold","bolder","lighter","100","200","300","400","500","600","800","900",100,200,300,400,500,600,700,800,900]},textDecoration:{enums:["none","underline","overline","line-through"]},textTransform:{enums:["none","uppercase","lowercase"]},textWrap:{enums:["none","wrap","ellipsis"]},textOverflowWrap:{enums:["whitespace","anywhere"]},textBackgroundShape:{enums:["rectangle","roundrectangle","round-rectangle"]},nodeShape:{enums:["rectangle","roundrectangle","round-rectangle","cutrectangle","cut-rectangle","bottomroundrectangle","bottom-round-rectangle","barrel","ellipse","triangle","round-triangle","square","pentagon","round-pentagon","hexagon","round-hexagon","concavehexagon","concave-hexagon","heptagon","round-heptagon","octagon","round-octagon","tag","round-tag","star","diamond","round-diamond","vee","rhomboid","right-rhomboid","polygon"]},overlayShape:{enums:["roundrectangle","round-rectangle","ellipse"]},compoundIncludeLabels:{enums:["include","exclude"]},arrowShape:{enums:["tee","triangle","triangle-tee","circle-triangle","triangle-cross","triangle-backcurve","vee","square","circle","diamond","chevron","none"]},arrowFill:{enums:["filled","hollow"]},arrowWidth:{number:!0,units:"%|px|em",implicitUnits:"px",enums:["match-line"]},display:{enums:["element","none"]},visibility:{enums:["hidden","visible"]},zCompoundDepth:{enums:["bottom","orphan","auto","top"]},zIndexCompare:{enums:["auto","manual"]},valign:{enums:["top","center","bottom"]},halign:{enums:["left","center","right"]},justification:{enums:["left","center","right","auto"]},text:{string:!0},data:{mapping:!0,regex:r("data")},layoutData:{mapping:!0,regex:r("layoutData")},scratch:{mapping:!0,regex:r("scratch")},mapData:{mapping:!0,regex:i("mapData")},mapLayoutData:{mapping:!0,regex:i("mapLayoutData")},mapScratch:{mapping:!0,regex:i("mapScratch")},fn:{mapping:!0,fn:!0},url:{regexes:a,singleRegexMatchValue:!0},urls:{regexes:a,singleRegexMatchValue:!0,multiple:!0},propList:{propList:!0},angle:{number:!0,units:"deg|rad",implicitUnits:"rad"},textRotation:{number:!0,units:"deg|rad",implicitUnits:"rad",enums:["none","autorotate"]},polygonPointList:{number:!0,multiple:!0,evenMultiple:!0,min:-1,max:1,unitless:!0},edgeDistances:{enums:["intersection","node-position","endpoints"]},edgeEndpoint:{number:!0,multiple:!0,units:"%|px|em|deg|rad",implicitUnits:"px",enums:["inside-to-node","outside-to-node","outside-to-node-or-label","outside-to-line","outside-to-line-or-label"],singleEnum:!0,validate:function(e,t){switch(e.length){case 2:return"deg"!==t[0]&&"rad"!==t[0]&&"deg"!==t[1]&&"rad"!==t[1];case 1:return A(e[0])||"deg"===t[0]||"rad"===t[0];default:return!1}}},easing:{regexes:["^(spring)\\s*\\(\\s*("+e+")\\s*,\\s*("+e+")\\s*\\)$","^(cubic-bezier)\\s*\\(\\s*("+e+")\\s*,\\s*("+e+")\\s*,\\s*("+e+")\\s*,\\s*("+e+")\\s*\\)$"],enums:["linear","ease","ease-in","ease-out","ease-in-out","ease-in-sine","ease-out-sine","ease-in-out-sine","ease-in-quad","ease-out-quad","ease-in-out-quad","ease-in-cubic","ease-out-cubic","ease-in-out-cubic","ease-in-quart","ease-out-quart","ease-in-out-quart","ease-in-quint","ease-out-quint","ease-in-out-quint","ease-in-expo","ease-out-expo","ease-in-out-expo","ease-in-circ","ease-out-circ","ease-in-out-circ"]},gradientDirection:{enums:["to-bottom","to-top","to-left","to-right","to-bottom-right","to-bottom-left","to-top-right","to-top-left","to-right-bottom","to-left-bottom","to-right-top","to-left-top"]},boundsExpansion:{number:!0,multiple:!0,min:0,validate:function(e){var t=e.length;return 1===t||2===t||4===t}}};var o={zeroNonZero:function(e,t){return(null==e||null==t)&&e!==t||(0==e&&0!=t||0!=e&&0==t)},any:function(e,t){return e!=t},emptyNonEmpty:function(e,t){var n=z(e),r=z(t);return n&&!r||!n&&r}},s=no.types,l=[{name:"label",type:s.text,triggersBounds:o.any,triggersZOrder:o.emptyNonEmpty},{name:"text-rotation",type:s.textRotation,triggersBounds:o.any},{name:"text-margin-x",type:s.bidirectionalSize,triggersBounds:o.any},{name:"text-margin-y",type:s.bidirectionalSize,triggersBounds:o.any}],u=[{name:"source-label",type:s.text,triggersBounds:o.any},{name:"source-text-rotation",type:s.textRotation,triggersBounds:o.any},{name:"source-text-margin-x",type:s.bidirectionalSize,triggersBounds:o.any},{name:"source-text-margin-y",type:s.bidirectionalSize,triggersBounds:o.any},{name:"source-text-offset",type:s.size,triggersBounds:o.any}],c=[{name:"target-label",type:s.text,triggersBounds:o.any},{name:"target-text-rotation",type:s.textRotation,triggersBounds:o.any},{name:"target-text-margin-x",type:s.bidirectionalSize,triggersBounds:o.any},{name:"target-text-margin-y",type:s.bidirectionalSize,triggersBounds:o.any},{name:"target-text-offset",type:s.size,triggersBounds:o.any}],h=[{name:"font-family",type:s.fontFamily,triggersBounds:o.any},{name:"font-style",type:s.fontStyle,triggersBounds:o.any},{name:"font-weight",type:s.fontWeight,triggersBounds:o.any},{name:"font-size",type:s.size,triggersBounds:o.any},{name:"text-transform",type:s.textTransform,triggersBounds:o.any},{name:"text-wrap",type:s.textWrap,triggersBounds:o.any},{name:"text-overflow-wrap",type:s.textOverflowWrap,triggersBounds:o.any},{name:"text-max-width",type:s.size,triggersBounds:o.any},{name:"text-outline-width",type:s.size,triggersBounds:o.any},{name:"line-height",type:s.positiveNumber,triggersBounds:o.any}],d=[{name:"text-valign",type:s.valign,triggersBounds:o.any},{name:"text-halign",type:s.halign,triggersBounds:o.any},{name:"color",type:s.color},{name:"text-outline-color",type:s.color},{name:"text-outline-opacity",type:s.zeroOneNumber},{name:"text-background-color",type:s.color},{name:"text-background-opacity",type:s.zeroOneNumber},{name:"text-background-padding",type:s.size,triggersBounds:o.any},{name:"text-border-opacity",type:s.zeroOneNumber},{name:"text-border-color",type:s.color},{name:"text-border-width",type:s.size,triggersBounds:o.any},{name:"text-border-style",type:s.borderStyle,triggersBounds:o.any},{name:"text-background-shape",type:s.textBackgroundShape,triggersBounds:o.any},{name:"text-justification",type:s.justification}],p=[{name:"events",type:s.bool,triggersZOrder:o.any},{name:"text-events",type:s.bool,triggersZOrder:o.any}],g=[{name:"display",type:s.display,triggersZOrder:o.any,triggersBounds:o.any,triggersBoundsOfConnectedEdges:!0},{name:"visibility",type:s.visibility,triggersZOrder:o.any},{name:"opacity",type:s.zeroOneNumber,triggersZOrder:o.zeroNonZero},{name:"text-opacity",type:s.zeroOneNumber},{name:"min-zoomed-font-size",type:s.size},{name:"z-compound-depth",type:s.zCompoundDepth,triggersZOrder:o.any},{name:"z-index-compare",type:s.zIndexCompare,triggersZOrder:o.any},{name:"z-index",type:s.number,triggersZOrder:o.any}],f=[{name:"overlay-padding",type:s.size,triggersBounds:o.any},{name:"overlay-color",type:s.color},{name:"overlay-opacity",type:s.zeroOneNumber,triggersBounds:o.zeroNonZero},{name:"overlay-shape",type:s.overlayShape,triggersBounds:o.any}],v=[{name:"underlay-padding",type:s.size,triggersBounds:o.any},{name:"underlay-color",type:s.color},{name:"underlay-opacity",type:s.zeroOneNumber,triggersBounds:o.zeroNonZero},{name:"underlay-shape",type:s.overlayShape,triggersBounds:o.any}],y=[{name:"transition-property",type:s.propList},{name:"transition-duration",type:s.time},{name:"transition-delay",type:s.time},{name:"transition-timing-function",type:s.easing}],m=function(e,t){return"label"===t.value?-e.poolIndex():t.pfValue},b=[{name:"height",type:s.nodeSize,triggersBounds:o.any,hashOverride:m},{name:"width",type:s.nodeSize,triggersBounds:o.any,hashOverride:m},{name:"shape",type:s.nodeShape,triggersBounds:o.any},{name:"shape-polygon-points",type:s.polygonPointList,triggersBounds:o.any},{name:"background-color",type:s.color},{name:"background-fill",type:s.fill},{name:"background-opacity",type:s.zeroOneNumber},{name:"background-blacken",type:s.nOneOneNumber},{name:"background-gradient-stop-colors",type:s.colors},{name:"background-gradient-stop-positions",type:s.percentages},{name:"background-gradient-direction",type:s.gradientDirection},{name:"padding",type:s.sizeMaybePercent,triggersBounds:o.any},{name:"padding-relative-to",type:s.paddingRelativeTo,triggersBounds:o.any},{name:"bounds-expansion",type:s.boundsExpansion,triggersBounds:o.any}],x=[{name:"border-color",type:s.color},{name:"border-opacity",type:s.zeroOneNumber},{name:"border-width",type:s.size,triggersBounds:o.any},{name:"border-style",type:s.borderStyle}],w=[{name:"outline-color",type:s.color},{name:"outline-opacity",type:s.zeroOneNumber},{name:"outline-width",type:s.size,triggersBounds:o.any},{name:"outline-style",type:s.borderStyle},{name:"outline-offset",type:s.size,triggersBounds:o.any}],E=[{name:"background-image",type:s.urls},{name:"background-image-crossorigin",type:s.bgCrossOrigin},{name:"background-image-opacity",type:s.zeroOneNumbers},{name:"background-image-containment",type:s.bgContainment},{name:"background-image-smoothing",type:s.bools},{name:"background-position-x",type:s.bgPos},{name:"background-position-y",type:s.bgPos},{name:"background-width-relative-to",type:s.bgRelativeTo},{name:"background-height-relative-to",type:s.bgRelativeTo},{name:"background-repeat",type:s.bgRepeat},{name:"background-fit",type:s.bgFit},{name:"background-clip",type:s.bgClip},{name:"background-width",type:s.bgWH},{name:"background-height",type:s.bgWH},{name:"background-offset-x",type:s.bgPos},{name:"background-offset-y",type:s.bgPos}],_=[{name:"position",type:s.position,triggersBounds:o.any},{name:"compound-sizing-wrt-labels",type:s.compoundIncludeLabels,triggersBounds:o.any},{name:"min-width",type:s.size,triggersBounds:o.any},{name:"min-width-bias-left",type:s.sizeMaybePercent,triggersBounds:o.any},{name:"min-width-bias-right",type:s.sizeMaybePercent,triggersBounds:o.any},{name:"min-height",type:s.size,triggersBounds:o.any},{name:"min-height-bias-top",type:s.sizeMaybePercent,triggersBounds:o.any},{name:"min-height-bias-bottom",type:s.sizeMaybePercent,triggersBounds:o.any}],T=[{name:"line-style",type:s.lineStyle},{name:"line-color",type:s.color},{name:"line-fill",type:s.fill},{name:"line-cap",type:s.lineCap},{name:"line-opacity",type:s.zeroOneNumber},{name:"line-dash-pattern",type:s.numbers},{name:"line-dash-offset",type:s.number},{name:"line-gradient-stop-colors",type:s.colors},{name:"line-gradient-stop-positions",type:s.percentages},{name:"curve-style",type:s.curveStyle,triggersBounds:o.any,triggersBoundsOfParallelBeziers:!0},{name:"haystack-radius",type:s.zeroOneNumber,triggersBounds:o.any},{name:"source-endpoint",type:s.edgeEndpoint,triggersBounds:o.any},{name:"target-endpoint",type:s.edgeEndpoint,triggersBounds:o.any},{name:"control-point-step-size",type:s.size,triggersBounds:o.any},{name:"control-point-distances",type:s.bidirectionalSizes,triggersBounds:o.any},{name:"control-point-weights",type:s.numbers,triggersBounds:o.any},{name:"segment-distances",type:s.bidirectionalSizes,triggersBounds:o.any},{name:"segment-weights",type:s.numbers,triggersBounds:o.any},{name:"taxi-turn",type:s.bidirectionalSizeMaybePercent,triggersBounds:o.any},{name:"taxi-turn-min-distance",type:s.size,triggersBounds:o.any},{name:"taxi-direction",type:s.axisDirection,triggersBounds:o.any},{name:"edge-distances",type:s.edgeDistances,triggersBounds:o.any},{name:"arrow-scale",type:s.positiveNumber,triggersBounds:o.any},{name:"loop-direction",type:s.angle,triggersBounds:o.any},{name:"loop-sweep",type:s.angle,triggersBounds:o.any},{name:"source-distance-from-node",type:s.size,triggersBounds:o.any},{name:"target-distance-from-node",type:s.size,triggersBounds:o.any}],D=[{name:"ghost",type:s.bool,triggersBounds:o.any},{name:"ghost-offset-x",type:s.bidirectionalSize,triggersBounds:o.any},{name:"ghost-offset-y",type:s.bidirectionalSize,triggersBounds:o.any},{name:"ghost-opacity",type:s.zeroOneNumber}],C=[{name:"selection-box-color",type:s.color},{name:"selection-box-opacity",type:s.zeroOneNumber},{name:"selection-box-border-color",type:s.color},{name:"selection-box-border-width",type:s.size},{name:"active-bg-color",type:s.color},{name:"active-bg-opacity",type:s.zeroOneNumber},{name:"active-bg-size",type:s.size},{name:"outside-texture-bg-color",type:s.color},{name:"outside-texture-bg-opacity",type:s.zeroOneNumber}],N=[];no.pieBackgroundN=16,N.push({name:"pie-size",type:s.sizeMaybePercent});for(var L=1;L<=no.pieBackgroundN;L++)N.push({name:"pie-"+L+"-background-color",type:s.color}),N.push({name:"pie-"+L+"-background-size",type:s.percent}),N.push({name:"pie-"+L+"-background-opacity",type:s.zeroOneNumber});var k=[],S=no.arrowPrefixes=["source","mid-source","target","mid-target"];[{name:"arrow-shape",type:s.arrowShape,triggersBounds:o.any},{name:"arrow-color",type:s.color},{name:"arrow-fill",type:s.arrowFill},{name:"arrow-width",type:s.arrowWidth}].forEach((function(e){S.forEach((function(t){var n=t+"-"+e.name,r=e.type,i=e.triggersBounds;k.push({name:n,type:r,triggersBounds:i})}))}),{});var I=no.properties=[].concat(p,y,g,f,v,D,d,h,l,u,c,b,x,w,E,N,_,T,k,C),M=no.propertyGroups={behavior:p,transition:y,visibility:g,overlay:f,underlay:v,ghost:D,commonLabel:d,labelDimensions:h,mainLabel:l,sourceLabel:u,targetLabel:c,nodeBody:b,nodeBorder:x,nodeOutline:w,backgroundImage:E,pie:N,compound:_,edgeLine:T,edgeArrow:k,core:C},O=no.propertyGroupNames={};(no.propertyGroupKeys=Object.keys(M)).forEach((function(e){O[e]=M[e].map((function(e){return e.name})),M[e].forEach((function(t){return t.groupKey=e}))}));var P=no.aliases=[{name:"content",pointsTo:"label"},{name:"control-point-distance",pointsTo:"control-point-distances"},{name:"control-point-weight",pointsTo:"control-point-weights"},{name:"edge-text-rotation",pointsTo:"text-rotation"},{name:"padding-left",pointsTo:"padding"},{name:"padding-right",pointsTo:"padding"},{name:"padding-top",pointsTo:"padding"},{name:"padding-bottom",pointsTo:"padding"}];no.propertyNames=I.map((function(e){return e.name}));for(var R=0;R<I.length;R++){var B=I[R];I[B.name]=B}for(var F=0;F<P.length;F++){var G=P[F],Y=I[G.pointsTo],X={name:G.name,alias:!0,pointsTo:Y};I.push(X),I[G.name]=X}}(),no.getDefaultProperty=function(e){return this.getDefaultProperties()[e]},no.getDefaultProperties=function(){var e=this._private;if(null!=e.defaultProperties)return e.defaultProperties;for(var t=Q({"selection-box-color":"#ddd","selection-box-opacity":.65,"selection-box-border-color":"#aaa","selection-box-border-width":1,"active-bg-color":"black","active-bg-opacity":.15,"active-bg-size":30,"outside-texture-bg-color":"#000","outside-texture-bg-opacity":.125,events:"yes","text-events":"no","text-valign":"top","text-halign":"center","text-justification":"auto","line-height":1,color:"#000","text-outline-color":"#000","text-outline-width":0,"text-outline-opacity":1,"text-opacity":1,"text-decoration":"none","text-transform":"none","text-wrap":"none","text-overflow-wrap":"whitespace","text-max-width":9999,"text-background-color":"#000","text-background-opacity":0,"text-background-shape":"rectangle","text-background-padding":0,"text-border-opacity":0,"text-border-width":0,"text-border-style":"solid","text-border-color":"#000","font-family":"Helvetica Neue, Helvetica, sans-serif","font-style":"normal","font-weight":"normal","font-size":16,"min-zoomed-font-size":0,"text-rotation":"none","source-text-rotation":"none","target-text-rotation":"none",visibility:"visible",display:"element",opacity:1,"z-compound-depth":"auto","z-index-compare":"auto","z-index":0,label:"","text-margin-x":0,"text-margin-y":0,"source-label":"","source-text-offset":0,"source-text-margin-x":0,"source-text-margin-y":0,"target-label":"","target-text-offset":0,"target-text-margin-x":0,"target-text-margin-y":0,"overlay-opacity":0,"overlay-color":"#000","overlay-padding":10,"overlay-shape":"round-rectangle","underlay-opacity":0,"underlay-color":"#000","underlay-padding":10,"underlay-shape":"round-rectangle","transition-property":"none","transition-duration":0,"transition-delay":0,"transition-timing-function":"linear","background-blacken":0,"background-color":"#999","background-fill":"solid","background-opacity":1,"background-image":"none","background-image-crossorigin":"anonymous","background-image-opacity":1,"background-image-containment":"inside","background-image-smoothing":"yes","background-position-x":"50%","background-position-y":"50%","background-offset-x":0,"background-offset-y":0,"background-width-relative-to":"include-padding","background-height-relative-to":"include-padding","background-repeat":"no-repeat","background-fit":"none","background-clip":"node","background-width":"auto","background-height":"auto","border-color":"#000","border-opacity":1,"border-width":0,"border-style":"solid","outline-color":"#999","outline-opacity":1,"outline-width":0,"outline-offset":0,"outline-style":"solid",height:30,width:30,shape:"ellipse","shape-polygon-points":"-1, -1, 1, -1, 1, 1, -1, 1","bounds-expansion":0,"background-gradient-direction":"to-bottom","background-gradient-stop-colors":"#999","background-gradient-stop-positions":"0%",ghost:"no","ghost-offset-y":0,"ghost-offset-x":0,"ghost-opacity":0,padding:0,"padding-relative-to":"width",position:"origin","compound-sizing-wrt-labels":"include","min-width":0,"min-width-bias-left":0,"min-width-bias-right":0,"min-height":0,"min-height-bias-top":0,"min-height-bias-bottom":0},{"pie-size":"100%"},[{name:"pie-{{i}}-background-color",value:"black"},{name:"pie-{{i}}-background-size",value:"0%"},{name:"pie-{{i}}-background-opacity",value:1}].reduce((function(e,t){for(var n=1;n<=no.pieBackgroundN;n++){var r=t.name.replace("{{i}}",n),i=t.value;e[r]=i}return e}),{}),{"line-style":"solid","line-color":"#999","line-fill":"solid","line-cap":"butt","line-opacity":1,"line-gradient-stop-colors":"#999","line-gradient-stop-positions":"0%","control-point-step-size":40,"control-point-weights":.5,"segment-weights":.5,"segment-distances":20,"taxi-turn":"50%","taxi-turn-min-distance":10,"taxi-direction":"auto","edge-distances":"intersection","curve-style":"haystack","haystack-radius":0,"arrow-scale":1,"loop-direction":"-45deg","loop-sweep":"-90deg","source-distance-from-node":0,"target-distance-from-node":0,"source-endpoint":"outside-to-node","target-endpoint":"outside-to-node","line-dash-pattern":[6,3],"line-dash-offset":0},[{name:"arrow-shape",value:"none"},{name:"arrow-color",value:"#999"},{name:"arrow-fill",value:"filled"},{name:"arrow-width",value:1}].reduce((function(e,t){return no.arrowPrefixes.forEach((function(n){var r=n+"-"+t.name,i=t.value;e[r]=i})),e}),{})),n={},r=0;r<this.properties.length;r++){var i=this.properties[r];if(!i.pointsTo){var a=i.name,o=t[a],s=this.parse(a,o);n[a]=s}}return e.defaultProperties=n,e.defaultProperties},no.addDefaultStylesheet=function(){this.selector(":parent").css({shape:"rectangle",padding:10,"background-color":"#eee","border-color":"#ccc","border-width":1}).selector("edge").css({width:3}).selector(":loop").css({"curve-style":"bezier"}).selector("edge:compound").css({"curve-style":"bezier","source-endpoint":"outside-to-line","target-endpoint":"outside-to-line"}).selector(":selected").css({"background-color":"#0169D9","line-color":"#0169D9","source-arrow-color":"#0169D9","target-arrow-color":"#0169D9","mid-source-arrow-color":"#0169D9","mid-target-arrow-color":"#0169D9"}).selector(":parent:selected").css({"background-color":"#CCE1F9","border-color":"#aec8e5"}).selector(":active").css({"overlay-color":"black","overlay-padding":10,"overlay-opacity":.25}),this.defaultLength=this.length};var ro={parse:function(e,t,n,r){var i=this;if(L(t))return i.parseImplWarn(e,t,n,r);var a,o=ve(e,""+t,n?"t":"f","mapping"===r||!0===r||!1===r||null==r?"dontcare":r),s=i.propCache=i.propCache||[];return(a=s[o])||(a=s[o]=i.parseImplWarn(e,t,n,r)),(n||"mapping"===r)&&(a=Le(a))&&(a.value=Le(a.value)),a},parseImplWarn:function(e,t,n,r){var i=this.parseImpl(e,t,n,r);return i||null==t||Ae("The style property `".concat(e,": ").concat(t,"` is invalid")),!i||"width"!==i.name&&"height"!==i.name||"label"!==t||Ae("The style value of `label` is deprecated for `"+i.name+"`"),i}};ro.parseImpl=function(e,t,n,r){var i=this;e=X(e);var a=i.properties[e],o=t,s=i.types;if(!a)return null;if(void 0===t)return null;a.alias&&(a=a.pointsTo,e=a.name);var l=A(t);l&&(t=t.trim());var u,c,h=a.type;if(!h)return null;if(n&&(""===t||null===t))return{name:e,value:t,bypass:!0,deleteBypass:!0};if(L(t))return{name:e,value:t,strValue:"fn",mapped:s.fn,bypass:n};if(!l||r||t.length<7||"a"!==t[1]);else{if(t.length>=7&&"d"===t[0]&&(u=new RegExp(s.data.regex).exec(t))){if(n)return!1;var d=s.data;return{name:e,value:u,strValue:""+t,mapped:d,field:u[1],bypass:n}}if(t.length>=10&&"m"===t[0]&&(c=new RegExp(s.mapData.regex).exec(t))){if(n)return!1;if(h.multiple)return!1;var p=s.mapData;if(!h.color&&!h.number)return!1;var g=this.parse(e,c[4]);if(!g||g.mapped)return!1;var f=this.parse(e,c[5]);if(!f||f.mapped)return!1;if(g.pfValue===f.pfValue||g.strValue===f.strValue)return Ae("`"+e+": "+t+"` is not a valid mapper because the output range is zero; converting to `"+e+": "+g.strValue+"`"),this.parse(e,g.strValue);if(h.color){var v=g.value,y=f.value;if(!(v[0]!==y[0]||v[1]!==y[1]||v[2]!==y[2]||v[3]!==y[3]&&(null!=v[3]&&1!==v[3]||null!=y[3]&&1!==y[3])))return!1}return{name:e,value:c,strValue:""+t,mapped:p,field:c[1],fieldMin:parseFloat(c[2]),fieldMax:parseFloat(c[3]),valueMin:g.value,valueMax:f.value,bypass:n}}}if(h.multiple&&"multiple"!==r){var m;if(m=l?t.split(/\s+/):k(t)?t:[t],h.evenMultiple&&m.length%2!=0)return null;for(var b=[],x=[],w=[],E="",_=!1,T=0;T<m.length;T++){var D=i.parse(e,m[T],n,"multiple");_=_||A(D.value),b.push(D.value),w.push(null!=D.pfValue?D.pfValue:D.value),x.push(D.units),E+=(T>0?" ":"")+D.strValue}return h.validate&&!h.validate(b,x)?null:h.singleEnum&&_?1===b.length&&A(b[0])?{name:e,value:b[0],strValue:b[0],bypass:n}:null:{name:e,value:b,pfValue:w,strValue:E,bypass:n,units:x}}var C,N,S=function(){for(var r=0;r<h.enums.length;r++){if(h.enums[r]===t)return{name:e,value:t,strValue:""+t,bypass:n}}return null};if(h.number){var M,O="px";if(h.units&&(M=h.units),h.implicitUnits&&(O=h.implicitUnits),!h.unitless)if(l){var P="px|em"+(h.allowPercent?"|\\%":"");M&&(P=M);var R=t.match("^("+q+")("+P+")?$");R&&(t=R[1],M=R[2]||O)}else M&&!h.implicitUnits||(M=O);if(t=parseFloat(t),isNaN(t)&&void 0===h.enums)return null;if(isNaN(t)&&void 0!==h.enums)return t=o,S();if(h.integer&&(!I(N=t)||Math.floor(N)!==N))return null;if(void 0!==h.min&&(t<h.min||h.strictMin&&t===h.min)||void 0!==h.max&&(t>h.max||h.strictMax&&t===h.max))return null;var B={name:e,value:t,strValue:""+t+(M||""),units:M,bypass:n};return h.unitless||"px"!==M&&"em"!==M?B.pfValue=t:B.pfValue="px"!==M&&M?this.getEmSizeInPixels()*t:t,"ms"!==M&&"s"!==M||(B.pfValue="ms"===M?t:1e3*t),"deg"!==M&&"rad"!==M||(B.pfValue="rad"===M?t:(C=t,Math.PI*C/180)),"%"===M&&(B.pfValue=t/100),B}if(h.propList){var F=[],z=""+t;if("none"===z);else{for(var G=z.split(/\s*,\s*|\s+/),Y=0;Y<G.length;Y++){var V=G[Y].trim();i.properties[V]?F.push(V):Ae("`"+V+"` is not a valid property name")}if(0===F.length)return null}return{name:e,value:F,strValue:0===F.length?"none":F.join(" "),bypass:n}}if(h.color){var U=J(t);return U?{name:e,value:U,pfValue:U,strValue:"rgb("+U[0]+","+U[1]+","+U[2]+")",bypass:n}:null}if(h.regex||h.regexes){if(h.enums){var j=S();if(j)return j}for(var H=h.regexes?h.regexes:[h.regex],W=0;W<H.length;W++){var $=new RegExp(H[W]).exec(t);if($)return{name:e,value:h.singleRegexMatchValue?$[1]:$,strValue:""+t,bypass:n}}return null}return h.string?{name:e,value:""+t,strValue:""+t,bypass:n}:h.enums?S():null};var io=function e(t){if(!(this instanceof e))return new e(t);B(t)?(this._private={cy:t,coreStyle:{}},this.length=0,this.resetToDefault()):Ce("A style must have a core reference")},ao=io.prototype;ao.instanceString=function(){return"style"},ao.clear=function(){for(var e=this._private,t=e.cy.elements(),n=0;n<this.length;n++)this[n]=void 0;return this.length=0,e.contextStyles={},e.propDiffs={},this.cleanElements(t,!0),t.forEach((function(e){var t=e[0]._private;t.styleDirty=!0,t.appliedInitStyle=!1})),this},ao.resetToDefault=function(){return this.clear(),this.addDefaultStylesheet(),this},ao.core=function(e){return this._private.coreStyle[e]||this.getDefaultProperty(e)},ao.selector=function(e){var t="core"===e?null:new Hr(e),n=this.length++;return this[n]={selector:t,properties:[],mappedProperties:[],index:n},this},ao.css=function(){var e=arguments;if(1===e.length)for(var t=e[0],n=0;n<this.properties.length;n++){var r=this.properties[n],i=t[r.name];void 0===i&&(i=t[V(r.name)]),void 0!==i&&this.cssRule(r.name,i)}else 2===e.length&&this.cssRule(e[0],e[1]);return this},ao.style=ao.css,ao.cssRule=function(e,t){var n=this.parse(e,t);if(n){var r=this.length-1;this[r].properties.push(n),this[r].properties[n.name]=n,n.name.match(/pie-(\d+)-background-size/)&&n.value&&(this._private.hasPie=!0),n.mapped&&this[r].mappedProperties.push(n),!this[r].selector&&(this._private.coreStyle[n.name]=n)}return this},ao.append=function(e){return F(e)?e.appendToStyle(this):k(e)?this.appendFromJson(e):A(e)&&this.appendFromString(e),this},io.fromJson=function(e,t){var n=new io(e);return n.fromJson(t),n},io.fromString=function(e,t){return new io(e).fromString(t)},[$a,Za,Qa,Ja,eo,to,no,ro].forEach((function(e){Q(ao,e)})),io.types=ao.types,io.properties=ao.properties,io.propertyGroups=ao.propertyGroups,io.propertyGroupNames=ao.propertyGroupNames,io.propertyGroupKeys=ao.propertyGroupKeys;var oo={style:function(e){e&&this.setStyle(e).update();return this._private.style},setStyle:function(e){var t=this._private;return F(e)?t.style=e.generateStyle(this):k(e)?t.style=io.fromJson(this,e):A(e)?t.style=io.fromString(this,e):t.style=io(this),t.style},updateStyle:function(){this.mutableElements().updateStyle()}},so={autolock:function(e){return void 0===e?this._private.autolock:(this._private.autolock=!!e,this)},autoungrabify:function(e){return void 0===e?this._private.autoungrabify:(this._private.autoungrabify=!!e,this)},autounselectify:function(e){return void 0===e?this._private.autounselectify:(this._private.autounselectify=!!e,this)},selectionType:function(e){var t=this._private;return null==t.selectionType&&(t.selectionType="single"),void 0===e?t.selectionType:("additive"!==e&&"single"!==e||(t.selectionType=e),this)},panningEnabled:function(e){return void 0===e?this._private.panningEnabled:(this._private.panningEnabled=!!e,this)},userPanningEnabled:function(e){return void 0===e?this._private.userPanningEnabled:(this._private.userPanningEnabled=!!e,this)},zoomingEnabled:function(e){return void 0===e?this._private.zoomingEnabled:(this._private.zoomingEnabled=!!e,this)},userZoomingEnabled:function(e){return void 0===e?this._private.userZoomingEnabled:(this._private.userZoomingEnabled=!!e,this)},boxSelectionEnabled:function(e){return void 0===e?this._private.boxSelectionEnabled:(this._private.boxSelectionEnabled=!!e,this)},pan:function(){var e,t,n,r,i,a=arguments,o=this._private.pan;switch(a.length){case 0:return o;case 1:if(A(a[0]))return o[e=a[0]];if(S(a[0])){if(!this._private.panningEnabled)return this;r=(n=a[0]).x,i=n.y,I(r)&&(o.x=r),I(i)&&(o.y=i),this.emit("pan viewport")}break;case 2:if(!this._private.panningEnabled)return this;t=a[1],"x"!==(e=a[0])&&"y"!==e||!I(t)||(o[e]=t),this.emit("pan viewport")}return this.notify("viewport"),this},panBy:function(e,t){var n,r,i,a,o,s=arguments,l=this._private.pan;if(!this._private.panningEnabled)return this;switch(s.length){case 1:S(e)&&(a=(i=s[0]).x,o=i.y,I(a)&&(l.x+=a),I(o)&&(l.y+=o),this.emit("pan viewport"));break;case 2:r=t,"x"!==(n=e)&&"y"!==n||!I(r)||(l[n]+=r),this.emit("pan viewport")}return this.notify("viewport"),this},fit:function(e,t){var n=this.getFitViewport(e,t);if(n){var r=this._private;r.zoom=n.zoom,r.pan=n.pan,this.emit("pan zoom viewport"),this.notify("viewport")}return this},getFitViewport:function(e,t){if(I(e)&&void 0===t&&(t=e,e=void 0),this._private.panningEnabled&&this._private.zoomingEnabled){var n,r;if(A(e)){var i=e;e=this.$(i)}else if(S(r=e)&&I(r.x1)&&I(r.x2)&&I(r.y1)&&I(r.y2)){var a=e;(n={x1:a.x1,y1:a.y1,x2:a.x2,y2:a.y2}).w=n.x2-n.x1,n.h=n.y2-n.y1}else O(e)||(e=this.mutableElements());if(!O(e)||!e.empty()){n=n||e.boundingBox();var o,s=this.width(),l=this.height();if(t=I(t)?t:0,!isNaN(s)&&!isNaN(l)&&s>0&&l>0&&!isNaN(n.w)&&!isNaN(n.h)&&n.w>0&&n.h>0)return{zoom:o=(o=(o=Math.min((s-2*t)/n.w,(l-2*t)/n.h))>this._private.maxZoom?this._private.maxZoom:o)<this._private.minZoom?this._private.minZoom:o,pan:{x:(s-o*(n.x1+n.x2))/2,y:(l-o*(n.y1+n.y2))/2}}}}},zoomRange:function(e,t){var n=this._private;if(null==t){var r=e;e=r.min,t=r.max}return I(e)&&I(t)&&e<=t?(n.minZoom=e,n.maxZoom=t):I(e)&&void 0===t&&e<=n.maxZoom?n.minZoom=e:I(t)&&void 0===e&&t>=n.minZoom&&(n.maxZoom=t),this},minZoom:function(e){return void 0===e?this._private.minZoom:this.zoomRange({min:e})},maxZoom:function(e){return void 0===e?this._private.maxZoom:this.zoomRange({max:e})},getZoomedViewport:function(e){var t,n,r=this._private,i=r.pan,a=r.zoom,o=!1;if(r.zoomingEnabled||(o=!0),I(e)?n=e:S(e)&&(n=e.level,null!=e.position?t=rt(e.position,a,i):null!=e.renderedPosition&&(t=e.renderedPosition),null==t||r.panningEnabled||(o=!0)),n=(n=n>r.maxZoom?r.maxZoom:n)<r.minZoom?r.minZoom:n,o||!I(n)||n===a||null!=t&&(!I(t.x)||!I(t.y)))return null;if(null!=t){var s=i,l=a,u=n;return{zoomed:!0,panned:!0,zoom:u,pan:{x:-u/l*(t.x-s.x)+t.x,y:-u/l*(t.y-s.y)+t.y}}}return{zoomed:!0,panned:!1,zoom:n,pan:i}},zoom:function(e){if(void 0===e)return this._private.zoom;var t=this.getZoomedViewport(e),n=this._private;return null!=t&&t.zoomed?(n.zoom=t.zoom,t.panned&&(n.pan.x=t.pan.x,n.pan.y=t.pan.y),this.emit("zoom"+(t.panned?" pan":"")+" viewport"),this.notify("viewport"),this):this},viewport:function(e){var t=this._private,n=!0,r=!0,i=[],a=!1,o=!1;if(!e)return this;if(I(e.zoom)||(n=!1),S(e.pan)||(r=!1),!n&&!r)return this;if(n){var s=e.zoom;s<t.minZoom||s>t.maxZoom||!t.zoomingEnabled?a=!0:(t.zoom=s,i.push("zoom"))}if(r&&(!a||!e.cancelOnFailedZoom)&&t.panningEnabled){var l=e.pan;I(l.x)&&(t.pan.x=l.x,o=!1),I(l.y)&&(t.pan.y=l.y,o=!1),o||i.push("pan")}return i.length>0&&(i.push("viewport"),this.emit(i.join(" ")),this.notify("viewport")),this},center:function(e){var t=this.getCenterPan(e);return t&&(this._private.pan=t,this.emit("pan viewport"),this.notify("viewport")),this},getCenterPan:function(e,t){if(this._private.panningEnabled){if(A(e)){var n=e;e=this.mutableElements().filter(n)}else O(e)||(e=this.mutableElements());if(0!==e.length){var r=e.boundingBox(),i=this.width(),a=this.height();return{x:(i-(t=void 0===t?this._private.zoom:t)*(r.x1+r.x2))/2,y:(a-t*(r.y1+r.y2))/2}}}},reset:function(){return this._private.panningEnabled&&this._private.zoomingEnabled?(this.viewport({pan:{x:0,y:0},zoom:1}),this):this},invalidateSize:function(){this._private.sizeCache=null},size:function(){var e,t,n=this._private,r=n.container,i=this;return n.sizeCache=n.sizeCache||(r?(e=i.window().getComputedStyle(r),t=function(t){return parseFloat(e.getPropertyValue(t))},{width:r.clientWidth-t("padding-left")-t("padding-right"),height:r.clientHeight-t("padding-top")-t("padding-bottom")}):{width:1,height:1})},width:function(){return this.size().width},height:function(){return this.size().height},extent:function(){var e=this._private.pan,t=this._private.zoom,n=this.renderedExtent(),r={x1:(n.x1-e.x)/t,x2:(n.x2-e.x)/t,y1:(n.y1-e.y)/t,y2:(n.y2-e.y)/t};return r.w=r.x2-r.x1,r.h=r.y2-r.y1,r},renderedExtent:function(){var e=this.width(),t=this.height();return{x1:0,y1:0,x2:e,y2:t,w:e,h:t}},multiClickDebounceTime:function(e){return e?(this._private.multiClickDebounceTime=e,this):this._private.multiClickDebounceTime}};so.centre=so.center,so.autolockNodes=so.autolock,so.autoungrabifyNodes=so.autoungrabify;var lo={data:ur.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeData:ur.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),scratch:ur.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:ur.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0})};lo.attr=lo.data,lo.removeAttr=lo.removeData;var uo=function(e){var t=this,n=(e=Q({},e)).container;n&&!M(n)&&M(n[0])&&(n=n[0]);var r=n?n._cyreg:null;(r=r||{})&&r.cy&&(r.cy.destroy(),r={});var i=r.readies=r.readies||[];n&&(n._cyreg=r),r.cy=t;var a=void 0!==w&&void 0!==n&&!e.headless,o=e;o.layout=Q({name:a?"grid":"null"},o.layout),o.renderer=Q({name:a?"canvas":"null"},o.renderer);var s=function(e,t,n){return void 0!==t?t:void 0!==n?n:e},l=this._private={container:n,ready:!1,options:o,elements:new Da(this),listeners:[],aniEles:new Da(this),data:o.data||{},scratch:{},layout:null,renderer:null,destroyed:!1,notificationsEnabled:!0,minZoom:1e-50,maxZoom:1e50,zoomingEnabled:s(!0,o.zoomingEnabled),userZoomingEnabled:s(!0,o.userZoomingEnabled),panningEnabled:s(!0,o.panningEnabled),userPanningEnabled:s(!0,o.userPanningEnabled),boxSelectionEnabled:s(!0,o.boxSelectionEnabled),autolock:s(!1,o.autolock,o.autolockNodes),autoungrabify:s(!1,o.autoungrabify,o.autoungrabifyNodes),autounselectify:s(!1,o.autounselectify),styleEnabled:void 0===o.styleEnabled?a:o.styleEnabled,zoom:I(o.zoom)?o.zoom:1,pan:{x:S(o.pan)&&I(o.pan.x)?o.pan.x:0,y:S(o.pan)&&I(o.pan.y)?o.pan.y:0},animation:{current:[],queue:[]},hasCompoundNodes:!1,multiClickDebounceTime:s(250,o.multiClickDebounceTime)};this.createEmitter(),this.selectionType(o.selectionType),this.zoomRange({min:o.minZoom,max:o.maxZoom});l.styleEnabled&&t.setStyle([]);var u=Q({},o,o.renderer);t.initRenderer(u);!function(e,t){if(e.some(G))return rr.all(e).then(t);t(e)}([o.style,o.elements],(function(e){var n=e[0],a=e[1];l.styleEnabled&&t.style().append(n),function(e,n,r){t.notifications(!1);var i=t.mutableElements();i.length>0&&i.remove(),null!=e&&(S(e)||k(e))&&t.add(e),t.one("layoutready",(function(e){t.notifications(!0),t.emit(e),t.one("load",n),t.emitAndNotify("load")})).one("layoutstop",(function(){t.one("done",r),t.emit("done")}));var a=Q({},t._private.options.layout);a.eles=t.elements(),t.layout(a).run()}(a,(function(){t.startAnimationLoop(),l.ready=!0,L(o.ready)&&t.on("ready",o.ready);for(var e=0;e<i.length;e++){var n=i[e];t.on("ready",n)}r&&(r.readies=[]),t.emit("ready")}),o.done)}))},co=uo.prototype;Q(co,{instanceString:function(){return"core"},isReady:function(){return this._private.ready},destroyed:function(){return this._private.destroyed},ready:function(e){return this.isReady()?this.emitter().emit("ready",[],e):this.on("ready",e),this},destroy:function(){var e=this;if(!e.destroyed())return e.stopAnimationLoop(),e.destroyRenderer(),this.emit("destroy"),e._private.destroyed=!0,e},hasElementWithId:function(e){return this._private.elements.hasElementWithId(e)},getElementById:function(e){return this._private.elements.getElementById(e)},hasCompoundNodes:function(){return this._private.hasCompoundNodes},headless:function(){return this._private.renderer.isHeadless()},styleEnabled:function(){return this._private.styleEnabled},addToPool:function(e){return this._private.elements.merge(e),this},removeFromPool:function(e){return this._private.elements.unmerge(e),this},container:function(){return this._private.container||null},window:function(){if(null==this._private.container)return w;var e=this._private.container.ownerDocument;return void 0===e||null==e?w:e.defaultView||w},mount:function(e){if(null!=e){var t=this,n=t._private,r=n.options;return!M(e)&&M(e[0])&&(e=e[0]),t.stopAnimationLoop(),t.destroyRenderer(),n.container=e,n.styleEnabled=!0,t.invalidateSize(),t.initRenderer(Q({},r,r.renderer,{name:"null"===r.renderer.name?"canvas":r.renderer.name})),t.startAnimationLoop(),t.style(r.style),t.emit("mount"),t}},unmount:function(){var e=this;return e.stopAnimationLoop(),e.destroyRenderer(),e.initRenderer({name:"null"}),e.emit("unmount"),e},options:function(){return Le(this._private.options)},json:function(e){var t=this,n=t._private,r=t.mutableElements();if(S(e)){if(t.startBatch(),e.elements){var i={},a=function(e,n){for(var r=[],a=[],o=0;o<e.length;o++){var s=e[o];if(s.data.id){var l=""+s.data.id,u=t.getElementById(l);i[l]=!0,0!==u.length?a.push({ele:u,json:s}):n?(s.group=n,r.push(s)):r.push(s)}else Ae("cy.json() cannot handle elements without an ID attribute")}t.add(r);for(var c=0;c<a.length;c++){var h=a[c],d=h.ele,p=h.json;d.json(p)}};if(k(e.elements))a(e.elements);else for(var o=["nodes","edges"],s=0;s<o.length;s++){var l=o[s],u=e.elements[l];k(u)&&a(u,l)}var c=t.collection();r.filter((function(e){return!i[e.id()]})).forEach((function(e){e.isParent()?c.merge(e):e.remove()})),c.forEach((function(e){return e.children().move({parent:null})})),c.forEach((function(e){return function(e){return t.getElementById(e.id())}(e).remove()}))}e.style&&t.style(e.style),null!=e.zoom&&e.zoom!==n.zoom&&t.zoom(e.zoom),e.pan&&(e.pan.x===n.pan.x&&e.pan.y===n.pan.y||t.pan(e.pan)),e.data&&t.data(e.data);for(var h=["minZoom","maxZoom","zoomingEnabled","userZoomingEnabled","panningEnabled","userPanningEnabled","boxSelectionEnabled","autolock","autoungrabify","autounselectify","multiClickDebounceTime"],d=0;d<h.length;d++){var p=h[d];null!=e[p]&&t[p](e[p])}return t.endBatch(),this}var g={};!!e?g.elements=this.elements().map((function(e){return e.json()})):(g.elements={},r.forEach((function(e){var t=e.group();g.elements[t]||(g.elements[t]=[]),g.elements[t].push(e.json())}))),this._private.styleEnabled&&(g.style=t.style().json()),g.data=Le(t.data());var f=n.options;return g.zoomingEnabled=n.zoomingEnabled,g.userZoomingEnabled=n.userZoomingEnabled,g.zoom=n.zoom,g.minZoom=n.minZoom,g.maxZoom=n.maxZoom,g.panningEnabled=n.panningEnabled,g.userPanningEnabled=n.userPanningEnabled,g.pan=Le(n.pan),g.boxSelectionEnabled=n.boxSelectionEnabled,g.renderer=Le(f.renderer),g.hideEdgesOnViewport=f.hideEdgesOnViewport,g.textureOnViewport=f.textureOnViewport,g.wheelSensitivity=f.wheelSensitivity,g.motionBlur=f.motionBlur,g.multiClickDebounceTime=f.multiClickDebounceTime,g}}),co.$id=co.getElementById,[Na,za,Xa,Va,Ua,ja,Ha,Wa,oo,so,lo].forEach((function(e){Q(co,e)}));var ho={fit:!0,directed:!1,padding:30,circle:!1,grid:!1,spacingFactor:1.75,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,roots:void 0,depthSort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}},po={maximal:!1,acyclic:!1},go=function(e){return e.scratch("breadthfirst")},fo=function(e,t){return e.scratch("breadthfirst",t)};function vo(e){this.options=Q({},ho,po,e)}vo.prototype.run=function(){var e,t=this.options,n=t,r=t.cy,i=n.eles,a=i.nodes().filter((function(e){return!e.isParent()})),o=i,s=n.directed,l=n.acyclic||n.maximal||n.maximalAdjustments>0,u=ft(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()});if(O(n.roots))e=n.roots;else if(k(n.roots)){for(var c=[],h=0;h<n.roots.length;h++){var d=n.roots[h],p=r.getElementById(d);c.push(p)}e=r.collection(c)}else if(A(n.roots))e=r.$(n.roots);else if(s)e=a.roots();else{var g=i.components();e=r.collection();for(var f=function(t){var n=g[t],r=n.maxDegree(!1),i=n.filter((function(e){return e.degree(!1)===r}));e=e.add(i)},v=0;v<g.length;v++)f(v)}var y=[],m={},b=function(e,t){null==y[t]&&(y[t]=[]);var n=y[t].length;y[t].push(e),fo(e,{index:n,depth:t})};o.bfs({roots:e,directed:n.directed,visit:function(e,t,n,r,i){var a=e[0],o=a.id();b(a,i),m[o]=!0}});for(var x=[],w=0;w<a.length;w++){var E=a[w];m[E.id()]||x.push(E)}var _=function(e){for(var t=y[e],n=0;n<t.length;n++){var r=t[n];null!=r?fo(r,{depth:e,index:n}):(t.splice(n,1),n--)}},T=function(){for(var e=0;e<y.length;e++)_(e)},D=function(e,t){for(var r=go(e),a=e.incomers().filter((function(e){return e.isNode()&&i.has(e)})),o=-1,s=e.id(),l=0;l<a.length;l++){var u=a[l],c=go(u);o=Math.max(o,c.depth)}if(r.depth<=o){if(!n.acyclic&&t[s])return null;var h=o+1;return function(e,t){var n=go(e),r=n.depth,i=n.index;y[r][i]=null,b(e,t)}(e,h),t[s]=h,!0}return!1};if(s&&l){var C=[],N={},L=function(e){return C.push(e)};for(a.forEach((function(e){return C.push(e)}));C.length>0;){var S=C.shift(),I=D(S,N);if(I)S.outgoers().filter((function(e){return e.isNode()&&i.has(e)})).forEach(L);else if(null===I){Ae("Detected double maximal shift for node `"+S.id()+"`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.");break}}}T();var M=0;if(n.avoidOverlap)for(var P=0;P<a.length;P++){var R=a[P].layoutDimensions(n),B=R.w,F=R.h;M=Math.max(M,B,F)}var z={},G=function(e){if(z[e.id()])return z[e.id()];for(var t=go(e).depth,n=e.neighborhood(),r=0,i=0,o=0;o<n.length;o++){var s=n[o];if(!s.isEdge()&&!s.isParent()&&a.has(s)){var l=go(s);if(null!=l){var u=l.index,c=l.depth;if(null!=u&&null!=c){var h=y[c].length;c<t&&(r+=u/h,i++)}}}}return r/=i=Math.max(1,i),0===i&&(r=0),z[e.id()]=r,r},Y=function(e,t){var n=G(e)-G(t);return 0===n?Z(e.id(),t.id()):n};void 0!==n.depthSort&&(Y=n.depthSort);for(var X=0;X<y.length;X++)y[X].sort(Y),_(X);for(var V=[],U=0;U<x.length;U++)V.push(x[U]);y.unshift(V),T();for(var j=0,q=0;q<y.length;q++)j=Math.max(y[q].length,j);var H=u.x1+u.w/2,W=u.x1+u.h/2,$=y.reduce((function(e,t){return Math.max(e,t.length)}),0);return i.nodes().layoutPositions(this,n,(function(e){var t=go(e),r=t.depth,i=t.index,a=y[r].length,o=Math.max(u.w/((n.grid?$:a)+1),M),s=Math.max(u.h/(y.length+1),M),l=Math.min(u.w/2/y.length,u.h/2/y.length);if(l=Math.max(l,M),n.circle){var c=l*r+l-(y.length>0&&y[0].length<=3?l/2:0),h=2*Math.PI/y[r].length*i;return 0===r&&1===y[0].length&&(c=1),{x:H+c*Math.cos(h),y:W+c*Math.sin(h)}}return{x:H+(i+1-(a+1)/2)*o,y:(r+1)*s}})),this};var yo={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,radius:void 0,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function mo(e){this.options=Q({},yo,e)}mo.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,i=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,a=r.nodes().not(":parent");t.sort&&(a=a.sort(t.sort));for(var o,s=ft(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()}),l=s.x1+s.w/2,u=s.y1+s.h/2,c=(void 0===t.sweep?2*Math.PI-2*Math.PI/a.length:t.sweep)/Math.max(1,a.length-1),h=0,d=0;d<a.length;d++){var p=a[d].layoutDimensions(t),g=p.w,f=p.h;h=Math.max(h,g,f)}if(o=I(t.radius)?t.radius:a.length<=1?0:Math.min(s.h,s.w)/2-h,a.length>1&&t.avoidOverlap){h*=1.75;var v=Math.cos(c)-Math.cos(0),y=Math.sin(c)-Math.sin(0),m=Math.sqrt(h*h/(v*v+y*y));o=Math.max(m,o)}return r.nodes().layoutPositions(this,t,(function(e,n){var r=t.startAngle+n*c*(i?1:-1),a=o*Math.cos(r),s=o*Math.sin(r);return{x:l+a,y:u+s}})),this};var bo,xo={fit:!0,padding:30,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,equidistant:!1,minNodeSpacing:10,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,height:void 0,width:void 0,spacingFactor:void 0,concentric:function(e){return e.degree()},levelWidth:function(e){return e.maxDegree()/4},animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function wo(e){this.options=Q({},xo,e)}wo.prototype.run=function(){for(var e=this.options,t=e,n=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,r=e.cy,i=t.eles,a=i.nodes().not(":parent"),o=ft(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()}),s=o.x1+o.w/2,l=o.y1+o.h/2,u=[],c=0,h=0;h<a.length;h++){var d,p=a[h];d=t.concentric(p),u.push({value:d,node:p}),p._private.scratch.concentric=d}a.updateStyle();for(var g=0;g<a.length;g++){var f=a[g].layoutDimensions(t);c=Math.max(c,f.w,f.h)}u.sort((function(e,t){return t.value-e.value}));for(var v=t.levelWidth(a),y=[[]],m=y[0],b=0;b<u.length;b++){var x=u[b];if(m.length>0)Math.abs(m[0].value-x.value)>=v&&(m=[],y.push(m));m.push(x)}var w=c+t.minNodeSpacing;if(!t.avoidOverlap){var E=y.length>0&&y[0].length>1,_=(Math.min(o.w,o.h)/2-w)/(y.length+E?1:0);w=Math.min(w,_)}for(var T=0,D=0;D<y.length;D++){var C=y[D],N=void 0===t.sweep?2*Math.PI-2*Math.PI/C.length:t.sweep,A=C.dTheta=N/Math.max(1,C.length-1);if(C.length>1&&t.avoidOverlap){var L=Math.cos(A)-Math.cos(0),k=Math.sin(A)-Math.sin(0),S=Math.sqrt(w*w/(L*L+k*k));T=Math.max(S,T)}C.r=T,T+=w}if(t.equidistant){for(var I=0,M=0,O=0;O<y.length;O++){var P=y[O].r-M;I=Math.max(I,P)}M=0;for(var R=0;R<y.length;R++){var B=y[R];0===R&&(M=B.r),B.r=M,M+=I}}for(var F={},z=0;z<y.length;z++)for(var G=y[z],Y=G.dTheta,X=G.r,V=0;V<G.length;V++){var U=G[V],j=t.startAngle+(n?1:-1)*Y*V,q={x:s+X*Math.cos(j),y:l+X*Math.sin(j)};F[U.node.id()]=q}return i.nodes().layoutPositions(this,t,(function(e){var t=e.id();return F[t]})),this};var Eo={ready:function(){},stop:function(){},animate:!0,animationEasing:void 0,animationDuration:void 0,animateFilter:function(e,t){return!0},animationThreshold:250,refresh:20,fit:!0,padding:30,boundingBox:void 0,nodeDimensionsIncludeLabels:!1,randomize:!1,componentSpacing:40,nodeRepulsion:function(e){return 2048},nodeOverlap:4,idealEdgeLength:function(e){return 32},edgeElasticity:function(e){return 32},nestingFactor:1.2,gravity:1,numIter:1e3,initialTemp:1e3,coolingFactor:.99,minTemp:1};function _o(e){this.options=Q({},Eo,e),this.options.layout=this;var t=this.options.eles.nodes(),n=this.options.eles.edges().filter((function(e){var n=e.source().data("id"),r=e.target().data("id"),i=t.some((function(e){return e.data("id")===n})),a=t.some((function(e){return e.data("id")===r}));return!i||!a}));this.options.eles=this.options.eles.not(n)}_o.prototype.run=function(){var e=this.options,t=e.cy,n=this;n.stopped=!1,!0!==e.animate&&!1!==e.animate||n.emit({type:"layoutstart",layout:n}),bo=!0===e.debug;var r=To(t,n,e);bo&&undefined(r),e.randomize&&No(r);var i=se(),a=function(){Lo(r,t,e),!0===e.fit&&t.fit(e.padding)},o=function(t){return!(n.stopped||t>=e.numIter)&&(ko(r,e),r.temperature=r.temperature*e.coolingFactor,!(r.temperature<e.minTemp))},s=function(){if(!0===e.animate||!1===e.animate)a(),n.one("layoutstop",e.stop),n.emit({type:"layoutstop",layout:n});else{var t=e.eles.nodes(),i=Ao(r,e,t);t.layoutPositions(n,e,i)}},l=0,u=!0;if(!0===e.animate){!function t(){for(var n=0;u&&n<e.refresh;)u=o(l),l++,n++;u?(se()-i>=e.animationThreshold&&a(),oe(t)):(Xo(r,e),s())}()}else{for(;u;)u=o(l),l++;Xo(r,e),s()}return this},_o.prototype.stop=function(){return this.stopped=!0,this.thread&&this.thread.stop(),this.emit("layoutstop"),this},_o.prototype.destroy=function(){return this.thread&&this.thread.stop(),this};var To=function(e,t,n){for(var r=n.eles.edges(),i=n.eles.nodes(),a=ft(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:e.width(),h:e.height()}),o={isCompound:e.hasCompoundNodes(),layoutNodes:[],idToIndex:{},nodeSize:i.size(),graphSet:[],indexToGraph:[],layoutEdges:[],edgeSize:r.size(),temperature:n.initialTemp,clientWidth:a.w,clientHeight:a.h,boundingBox:a},s=n.eles.components(),l={},u=0;u<s.length;u++)for(var c=s[u],h=0;h<c.length;h++){l[c[h].id()]=u}for(u=0;u<o.nodeSize;u++){var d=(y=i[u]).layoutDimensions(n);(O={}).isLocked=y.locked(),O.id=y.data("id"),O.parentId=y.data("parent"),O.cmptId=l[y.id()],O.children=[],O.positionX=y.position("x"),O.positionY=y.position("y"),O.offsetX=0,O.offsetY=0,O.height=d.w,O.width=d.h,O.maxX=O.positionX+O.width/2,O.minX=O.positionX-O.width/2,O.maxY=O.positionY+O.height/2,O.minY=O.positionY-O.height/2,O.padLeft=parseFloat(y.style("padding")),O.padRight=parseFloat(y.style("padding")),O.padTop=parseFloat(y.style("padding")),O.padBottom=parseFloat(y.style("padding")),O.nodeRepulsion=L(n.nodeRepulsion)?n.nodeRepulsion(y):n.nodeRepulsion,o.layoutNodes.push(O),o.idToIndex[O.id]=u}var p=[],g=0,f=-1,v=[];for(u=0;u<o.nodeSize;u++){var y,m=(y=o.layoutNodes[u]).parentId;null!=m?o.layoutNodes[o.idToIndex[m]].children.push(y.id):(p[++f]=y.id,v.push(y.id))}for(o.graphSet.push(v);g<=f;){var b=p[g++],x=o.idToIndex[b],w=o.layoutNodes[x].children;if(w.length>0){o.graphSet.push(w);for(u=0;u<w.length;u++)p[++f]=w[u]}}for(u=0;u<o.graphSet.length;u++){var E=o.graphSet[u];for(h=0;h<E.length;h++){var _=o.idToIndex[E[h]];o.indexToGraph[_]=u}}for(u=0;u<o.edgeSize;u++){var T=r[u],D={};D.id=T.data("id"),D.sourceId=T.data("source"),D.targetId=T.data("target");var C=L(n.idealEdgeLength)?n.idealEdgeLength(T):n.idealEdgeLength,N=L(n.edgeElasticity)?n.edgeElasticity(T):n.edgeElasticity,A=o.idToIndex[D.sourceId],k=o.idToIndex[D.targetId];if(o.indexToGraph[A]!=o.indexToGraph[k]){for(var S=Do(D.sourceId,D.targetId,o),I=o.graphSet[S],M=0,O=o.layoutNodes[A];-1===I.indexOf(O.id);)O=o.layoutNodes[o.idToIndex[O.parentId]],M++;for(O=o.layoutNodes[k];-1===I.indexOf(O.id);)O=o.layoutNodes[o.idToIndex[O.parentId]],M++;C*=M*n.nestingFactor}D.idealLength=C,D.elasticity=N,o.layoutEdges.push(D)}return o},Do=function(e,t,n){var r=Co(e,t,0,n);return 2>r.count?0:r.graph},Co=function e(t,n,r,i){var a=i.graphSet[r];if(-1<a.indexOf(t)&&-1<a.indexOf(n))return{count:2,graph:r};for(var o=0,s=0;s<a.length;s++){var l=a[s],u=i.idToIndex[l],c=i.layoutNodes[u].children;if(0!==c.length){var h=e(t,n,i.indexToGraph[i.idToIndex[c[0]]],i);if(0!==h.count){if(1!==h.count)return h;if(2===++o)break}}}return{count:o,graph:r}},No=function(e,t){for(var n=e.clientWidth,r=e.clientHeight,i=0;i<e.nodeSize;i++){var a=e.layoutNodes[i];0!==a.children.length||a.isLocked||(a.positionX=Math.random()*n,a.positionY=Math.random()*r)}},Ao=function(e,t,n){var r=e.boundingBox,i={x1:1/0,x2:-1/0,y1:1/0,y2:-1/0};return t.boundingBox&&(n.forEach((function(t){var n=e.layoutNodes[e.idToIndex[t.data("id")]];i.x1=Math.min(i.x1,n.positionX),i.x2=Math.max(i.x2,n.positionX),i.y1=Math.min(i.y1,n.positionY),i.y2=Math.max(i.y2,n.positionY)})),i.w=i.x2-i.x1,i.h=i.y2-i.y1),function(n,a){var o=e.layoutNodes[e.idToIndex[n.data("id")]];if(t.boundingBox){var s=(o.positionX-i.x1)/i.w,l=(o.positionY-i.y1)/i.h;return{x:r.x1+s*r.w,y:r.y1+l*r.h}}return{x:o.positionX,y:o.positionY}}},Lo=function(e,t,n){var r=n.layout,i=n.eles.nodes(),a=Ao(e,n,i);i.positions(a),!0!==e.ready&&(e.ready=!0,r.one("layoutready",n.ready),r.emit({type:"layoutready",layout:this}))},ko=function(e,t,n){So(e,t),Ro(e),Bo(e,t),Fo(e),zo(e)},So=function(e,t){for(var n=0;n<e.graphSet.length;n++)for(var r=e.graphSet[n],i=r.length,a=0;a<i;a++)for(var o=e.layoutNodes[e.idToIndex[r[a]]],s=a+1;s<i;s++){var l=e.layoutNodes[e.idToIndex[r[s]]];Mo(o,l,e,t)}},Io=function(e){return-e+2*e*Math.random()},Mo=function(e,t,n,r){if(e.cmptId===t.cmptId||n.isCompound){var i=t.positionX-e.positionX,a=t.positionY-e.positionY;0===i&&0===a&&(i=Io(1),a=Io(1));var o=Oo(e,t,i,a);if(o>0)var s=(u=r.nodeOverlap*o)*i/(f=Math.sqrt(i*i+a*a)),l=u*a/f;else{var u,c=Po(e,i,a),h=Po(t,-1*i,-1*a),d=h.x-c.x,p=h.y-c.y,g=d*d+p*p,f=Math.sqrt(g);s=(u=(e.nodeRepulsion+t.nodeRepulsion)/g)*d/f,l=u*p/f}e.isLocked||(e.offsetX-=s,e.offsetY-=l),t.isLocked||(t.offsetX+=s,t.offsetY+=l)}},Oo=function(e,t,n,r){if(n>0)var i=e.maxX-t.minX;else i=t.maxX-e.minX;if(r>0)var a=e.maxY-t.minY;else a=t.maxY-e.minY;return i>=0&&a>=0?Math.sqrt(i*i+a*a):0},Po=function(e,t,n){var r=e.positionX,i=e.positionY,a=e.height||1,o=e.width||1,s=n/t,l=a/o,u={};return 0===t&&0<n||0===t&&0>n?(u.x=r,u.y=i+a/2,u):0<t&&-1*l<=s&&s<=l?(u.x=r+o/2,u.y=i+o*n/2/t,u):0>t&&-1*l<=s&&s<=l?(u.x=r-o/2,u.y=i-o*n/2/t,u):0<n&&(s<=-1*l||s>=l)?(u.x=r+a*t/2/n,u.y=i+a/2,u):0>n&&(s<=-1*l||s>=l)?(u.x=r-a*t/2/n,u.y=i-a/2,u):u},Ro=function(e,t){for(var n=0;n<e.edgeSize;n++){var r=e.layoutEdges[n],i=e.idToIndex[r.sourceId],a=e.layoutNodes[i],o=e.idToIndex[r.targetId],s=e.layoutNodes[o],l=s.positionX-a.positionX,u=s.positionY-a.positionY;if(0!==l||0!==u){var c=Po(a,l,u),h=Po(s,-1*l,-1*u),d=h.x-c.x,p=h.y-c.y,g=Math.sqrt(d*d+p*p),f=Math.pow(r.idealLength-g,2)/r.elasticity;if(0!==g)var v=f*d/g,y=f*p/g;else v=0,y=0;a.isLocked||(a.offsetX+=v,a.offsetY+=y),s.isLocked||(s.offsetX-=v,s.offsetY-=y)}}},Bo=function(e,t){if(0!==t.gravity)for(var n=0;n<e.graphSet.length;n++){var r=e.graphSet[n],i=r.length;if(0===n)var a=e.clientHeight/2,o=e.clientWidth/2;else{var s=e.layoutNodes[e.idToIndex[r[0]]],l=e.layoutNodes[e.idToIndex[s.parentId]];a=l.positionX,o=l.positionY}for(var u=0;u<i;u++){var c=e.layoutNodes[e.idToIndex[r[u]]];if(!c.isLocked){var h=a-c.positionX,d=o-c.positionY,p=Math.sqrt(h*h+d*d);if(p>1){var g=t.gravity*h/p,f=t.gravity*d/p;c.offsetX+=g,c.offsetY+=f}}}}},Fo=function(e,t){var n=[],r=0,i=-1;for(n.push.apply(n,e.graphSet[0]),i+=e.graphSet[0].length;r<=i;){var a=n[r++],o=e.idToIndex[a],s=e.layoutNodes[o],l=s.children;if(0<l.length&&!s.isLocked){for(var u=s.offsetX,c=s.offsetY,h=0;h<l.length;h++){var d=e.layoutNodes[e.idToIndex[l[h]]];d.offsetX+=u,d.offsetY+=c,n[++i]=l[h]}s.offsetX=0,s.offsetY=0}}},zo=function(e,t){for(var n=0;n<e.nodeSize;n++){0<(i=e.layoutNodes[n]).children.length&&(i.maxX=void 0,i.minX=void 0,i.maxY=void 0,i.minY=void 0)}for(n=0;n<e.nodeSize;n++){if(!(0<(i=e.layoutNodes[n]).children.length||i.isLocked)){var r=Go(i.offsetX,i.offsetY,e.temperature);i.positionX+=r.x,i.positionY+=r.y,i.offsetX=0,i.offsetY=0,i.minX=i.positionX-i.width,i.maxX=i.positionX+i.width,i.minY=i.positionY-i.height,i.maxY=i.positionY+i.height,Yo(i,e)}}for(n=0;n<e.nodeSize;n++){var i;0<(i=e.layoutNodes[n]).children.length&&!i.isLocked&&(i.positionX=(i.maxX+i.minX)/2,i.positionY=(i.maxY+i.minY)/2,i.width=i.maxX-i.minX,i.height=i.maxY-i.minY)}},Go=function(e,t,n){var r=Math.sqrt(e*e+t*t);if(r>n)var i={x:n*e/r,y:n*t/r};else i={x:e,y:t};return i},Yo=function e(t,n){var r=t.parentId;if(null!=r){var i=n.layoutNodes[n.idToIndex[r]],a=!1;return(null==i.maxX||t.maxX+i.padRight>i.maxX)&&(i.maxX=t.maxX+i.padRight,a=!0),(null==i.minX||t.minX-i.padLeft<i.minX)&&(i.minX=t.minX-i.padLeft,a=!0),(null==i.maxY||t.maxY+i.padBottom>i.maxY)&&(i.maxY=t.maxY+i.padBottom,a=!0),(null==i.minY||t.minY-i.padTop<i.minY)&&(i.minY=t.minY-i.padTop,a=!0),a?e(i,n):void 0}},Xo=function(e,t){for(var n=e.layoutNodes,r=[],i=0;i<n.length;i++){var a=n[i],o=a.cmptId;(r[o]=r[o]||[]).push(a)}var s=0;for(i=0;i<r.length;i++){if(f=r[i]){f.x1=1/0,f.x2=-1/0,f.y1=1/0,f.y2=-1/0;for(var l=0;l<f.length;l++){var u=f[l];f.x1=Math.min(f.x1,u.positionX-u.width/2),f.x2=Math.max(f.x2,u.positionX+u.width/2),f.y1=Math.min(f.y1,u.positionY-u.height/2),f.y2=Math.max(f.y2,u.positionY+u.height/2)}f.w=f.x2-f.x1,f.h=f.y2-f.y1,s+=f.w*f.h}}r.sort((function(e,t){return t.w*t.h-e.w*e.h}));var c=0,h=0,d=0,p=0,g=Math.sqrt(s)*e.clientWidth/e.clientHeight;for(i=0;i<r.length;i++){var f;if(f=r[i]){for(l=0;l<f.length;l++){(u=f[l]).isLocked||(u.positionX+=c-f.x1,u.positionY+=h-f.y1)}c+=f.w+t.componentSpacing,d+=f.w+t.componentSpacing,p=Math.max(p,f.h),d>g&&(h+=p+t.componentSpacing,c=0,d=0,p=0)}}},Vo={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,avoidOverlapPadding:10,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,condense:!1,rows:void 0,cols:void 0,position:function(e){},sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Uo(e){this.options=Q({},Vo,e)}Uo.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,i=r.nodes().not(":parent");t.sort&&(i=i.sort(t.sort));var a=ft(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()});if(0===a.h||0===a.w)r.nodes().layoutPositions(this,t,(function(e){return{x:a.x1,y:a.y1}}));else{var o=i.size(),s=Math.sqrt(o*a.h/a.w),l=Math.round(s),u=Math.round(a.w/a.h*s),c=function(e){if(null==e)return Math.min(l,u);Math.min(l,u)==l?l=e:u=e},h=function(e){if(null==e)return Math.max(l,u);Math.max(l,u)==l?l=e:u=e},d=t.rows,p=null!=t.cols?t.cols:t.columns;if(null!=d&&null!=p)l=d,u=p;else if(null!=d&&null==p)l=d,u=Math.ceil(o/l);else if(null==d&&null!=p)u=p,l=Math.ceil(o/u);else if(u*l>o){var g=c(),f=h();(g-1)*f>=o?c(g-1):(f-1)*g>=o&&h(f-1)}else for(;u*l<o;){var v=c(),y=h();(y+1)*v>=o?h(y+1):c(v+1)}var m=a.w/u,b=a.h/l;if(t.condense&&(m=0,b=0),t.avoidOverlap)for(var x=0;x<i.length;x++){var w=i[x],E=w._private.position;null!=E.x&&null!=E.y||(E.x=0,E.y=0);var _=w.layoutDimensions(t),T=t.avoidOverlapPadding,D=_.w+T,C=_.h+T;m=Math.max(m,D),b=Math.max(b,C)}for(var N={},A=function(e,t){return!!N["c-"+e+"-"+t]},L=function(e,t){N["c-"+e+"-"+t]=!0},k=0,S=0,I=function(){++S>=u&&(S=0,k++)},M={},O=0;O<i.length;O++){var P=i[O],R=t.position(P);if(R&&(void 0!==R.row||void 0!==R.col)){var B={row:R.row,col:R.col};if(void 0===B.col)for(B.col=0;A(B.row,B.col);)B.col++;else if(void 0===B.row)for(B.row=0;A(B.row,B.col);)B.row++;M[P.id()]=B,L(B.row,B.col)}}i.layoutPositions(this,t,(function(e,t){var n,r;if(e.locked()||e.isParent())return!1;var i=M[e.id()];if(i)n=i.col*m+m/2+a.x1,r=i.row*b+b/2+a.y1;else{for(;A(k,S);)I();n=S*m+m/2+a.x1,r=k*b+b/2+a.y1,L(k,S),I()}return{x:n,y:r}}))}return this};var jo={ready:function(){},stop:function(){}};function qo(e){this.options=Q({},jo,e)}qo.prototype.run=function(){var e=this.options,t=e.eles,n=this;return e.cy,n.emit("layoutstart"),t.nodes().positions((function(){return{x:0,y:0}})),n.one("layoutready",e.ready),n.emit("layoutready"),n.one("layoutstop",e.stop),n.emit("layoutstop"),this},qo.prototype.stop=function(){return this};var Ho={positions:void 0,zoom:void 0,pan:void 0,fit:!0,padding:30,spacingFactor:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Wo(e){this.options=Q({},Ho,e)}Wo.prototype.run=function(){var e=this.options,t=e.eles.nodes(),n=L(e.positions);return t.layoutPositions(this,e,(function(t,r){var i=function(t){if(null==e.positions)return function(e){return{x:e.x,y:e.y}}(t.position());if(n)return e.positions(t);var r=e.positions[t._private.data.id];return null==r?null:r}(t);return!t.locked()&&null!=i&&i})),this};var $o={fit:!0,padding:30,boundingBox:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Ko(e){this.options=Q({},$o,e)}Ko.prototype.run=function(){var e=this.options,t=e.cy,n=e.eles,r=ft(e.boundingBox?e.boundingBox:{x1:0,y1:0,w:t.width(),h:t.height()});return n.nodes().layoutPositions(this,e,(function(e,t){return{x:r.x1+Math.round(Math.random()*r.w),y:r.y1+Math.round(Math.random()*r.h)}})),this};var Zo=[{name:"breadthfirst",impl:vo},{name:"circle",impl:mo},{name:"concentric",impl:wo},{name:"cose",impl:_o},{name:"grid",impl:Uo},{name:"null",impl:qo},{name:"preset",impl:Wo},{name:"random",impl:Ko}];function Qo(e){this.options=e,this.notifications=0}var Jo=function(){},es=function(){throw new Error("A headless instance can not render images")};Qo.prototype={recalculateRenderedStyle:Jo,notify:function(){this.notifications++},init:Jo,isHeadless:function(){return!0},png:es,jpg:es};var ts={arrowShapeWidth:.3,registerArrowShapes:function(){var e=this.arrowShapes={},t=this,n=function(e,t,n,r,i,a,o){var s=i.x-n/2-o,l=i.x+n/2+o,u=i.y-n/2-o,c=i.y+n/2+o;return s<=e&&e<=l&&u<=t&&t<=c},r=function(e,t,n,r,i){var a=e*Math.cos(r)-t*Math.sin(r),o=(e*Math.sin(r)+t*Math.cos(r))*n;return{x:a*n+i.x,y:o+i.y}},i=function(e,t,n,i){for(var a=[],o=0;o<e.length;o+=2){var s=e[o],l=e[o+1];a.push(r(s,l,t,n,i))}return a},a=function(e){for(var t=[],n=0;n<e.length;n++){var r=e[n];t.push(r.x,r.y)}return t},o=function(e){return e.pstyle("width").pfValue*e.pstyle("arrow-scale").pfValue*2},s=function(r,s){A(s)&&(s=e[s]),e[r]=Q({name:r,points:[-.15,-.3,.15,-.3,.15,.3,-.15,.3],collide:function(e,t,n,r,o,s){var l=a(i(this.points,n+2*s,r,o));return Lt(e,t,l)},roughCollide:n,draw:function(e,n,r,a){var o=i(this.points,n,r,a);t.arrowShapeImpl("polygon")(e,o)},spacing:function(e){return 0},gap:o},s)};s("none",{collide:_e,roughCollide:_e,draw:De,spacing:Te,gap:Te}),s("triangle",{points:[-.15,-.3,0,0,.15,-.3]}),s("arrow","triangle"),s("triangle-backcurve",{points:e.triangle.points,controlPoint:[0,-.15],roughCollide:n,draw:function(e,n,a,o,s){var l=i(this.points,n,a,o),u=this.controlPoint,c=r(u[0],u[1],n,a,o);t.arrowShapeImpl(this.name)(e,l,c)},gap:function(e){return.8*o(e)}}),s("triangle-tee",{points:[0,0,.15,-.3,-.15,-.3,0,0],pointsTee:[-.15,-.4,-.15,-.5,.15,-.5,.15,-.4],collide:function(e,t,n,r,o,s,l){var u=a(i(this.points,n+2*l,r,o)),c=a(i(this.pointsTee,n+2*l,r,o));return Lt(e,t,u)||Lt(e,t,c)},draw:function(e,n,r,a,o){var s=i(this.points,n,r,a),l=i(this.pointsTee,n,r,a);t.arrowShapeImpl(this.name)(e,s,l)}}),s("circle-triangle",{radius:.15,pointsTr:[0,-.15,.15,-.45,-.15,-.45,0,-.15],collide:function(e,t,n,r,o,s,l){var u=o,c=Math.pow(u.x-e,2)+Math.pow(u.y-t,2)<=Math.pow((n+2*l)*this.radius,2),h=a(i(this.points,n+2*l,r,o));return Lt(e,t,h)||c},draw:function(e,n,r,a,o){var s=i(this.pointsTr,n,r,a);t.arrowShapeImpl(this.name)(e,s,a.x,a.y,this.radius*n)},spacing:function(e){return t.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.radius}}),s("triangle-cross",{points:[0,0,.15,-.3,-.15,-.3,0,0],baseCrossLinePts:[-.15,-.4,-.15,-.4,.15,-.4,.15,-.4],crossLinePts:function(e,t){var n=this.baseCrossLinePts.slice(),r=t/e;return n[3]=n[3]-r,n[5]=n[5]-r,n},collide:function(e,t,n,r,o,s,l){var u=a(i(this.points,n+2*l,r,o)),c=a(i(this.crossLinePts(n,s),n+2*l,r,o));return Lt(e,t,u)||Lt(e,t,c)},draw:function(e,n,r,a,o){var s=i(this.points,n,r,a),l=i(this.crossLinePts(n,o),n,r,a);t.arrowShapeImpl(this.name)(e,s,l)}}),s("vee",{points:[-.15,-.3,0,0,.15,-.3,0,-.15],gap:function(e){return.525*o(e)}}),s("circle",{radius:.15,collide:function(e,t,n,r,i,a,o){var s=i;return Math.pow(s.x-e,2)+Math.pow(s.y-t,2)<=Math.pow((n+2*o)*this.radius,2)},draw:function(e,n,r,i,a){t.arrowShapeImpl(this.name)(e,i.x,i.y,this.radius*n)},spacing:function(e){return t.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.radius}}),s("tee",{points:[-.15,0,-.15,-.1,.15,-.1,.15,0],spacing:function(e){return 1},gap:function(e){return 1}}),s("square",{points:[-.15,0,.15,0,.15,-.3,-.15,-.3]}),s("diamond",{points:[-.15,-.15,0,-.3,.15,-.15,0,0],gap:function(e){return e.pstyle("width").pfValue*e.pstyle("arrow-scale").value}}),s("chevron",{points:[0,0,-.15,-.15,-.1,-.2,0,-.1,.1,-.2,.15,-.15],gap:function(e){return.95*e.pstyle("width").pfValue*e.pstyle("arrow-scale").value}})}},ns={projectIntoViewport:function(e,t){var n=this.cy,r=this.findContainerClientCoords(),i=r[0],a=r[1],o=r[4],s=n.pan(),l=n.zoom();return[((e-i)/o-s.x)/l,((t-a)/o-s.y)/l]},findContainerClientCoords:function(){if(this.containerBB)return this.containerBB;var e=this.container,t=e.getBoundingClientRect(),n=this.cy.window().getComputedStyle(e),r=function(e){return parseFloat(n.getPropertyValue(e))},i=r("padding-left"),a=r("padding-right"),o=r("padding-top"),s=r("padding-bottom"),l=r("border-left-width"),u=r("border-right-width"),c=r("border-top-width"),h=(r("border-bottom-width"),e.clientWidth),d=e.clientHeight,p=i+a,g=o+s,f=l+u,v=t.width/(h+f),y=h-p,m=d-g,b=t.left+i+l,x=t.top+o+c;return this.containerBB=[b,x,y,m,v]},invalidateContainerClientCoordsCache:function(){this.containerBB=null},findNearestElement:function(e,t,n,r){return this.findNearestElements(e,t,n,r)[0]},findNearestElements:function(e,t,n,r){var i,a,o=this,s=this,l=s.getCachedZSortedEles(),u=[],c=s.cy.zoom(),h=s.cy.hasCompoundNodes(),d=(r?24:8)/c,p=(r?8:2)/c,g=(r?8:2)/c,f=1/0;function v(e,t){if(e.isNode()){if(a)return;a=e,u.push(e)}if(e.isEdge()&&(null==t||t<f))if(i){if(i.pstyle("z-compound-depth").value===e.pstyle("z-compound-depth").value&&i.pstyle("z-compound-depth").value===e.pstyle("z-compound-depth").value)for(var n=0;n<u.length;n++)if(u[n].isEdge()){u[n]=e,i=e,f=null!=t?t:f;break}}else u.push(e),i=e,f=null!=t?t:f}function y(n){var r=n.outerWidth()+2*p,i=n.outerHeight()+2*p,a=r/2,l=i/2,u=n.position();if(u.x-a<=e&&e<=u.x+a&&u.y-l<=t&&t<=u.y+l&&s.nodeShapes[o.getNodeShape(n)].checkPoint(e,t,0,r,i,u.x,u.y))return v(n,0),!0}function m(n){var r,i=n._private,a=i.rscratch,l=n.pstyle("width").pfValue,c=n.pstyle("arrow-scale").value,p=l/2+d,g=p*p,f=2*p,m=i.source,b=i.target;if("segments"===a.edgeType||"straight"===a.edgeType||"haystack"===a.edgeType){for(var x=a.allpts,w=0;w+3<x.length;w+=2)if(Dt(e,t,x[w],x[w+1],x[w+2],x[w+3],f)&&g>(r=At(e,t,x[w],x[w+1],x[w+2],x[w+3])))return v(n,r),!0}else if("bezier"===a.edgeType||"multibezier"===a.edgeType||"self"===a.edgeType||"compound"===a.edgeType)for(x=a.allpts,w=0;w+5<a.allpts.length;w+=4)if(Ct(e,t,x[w],x[w+1],x[w+2],x[w+3],x[w+4],x[w+5],f)&&g>(r=Nt(e,t,x[w],x[w+1],x[w+2],x[w+3],x[w+4],x[w+5])))return v(n,r),!0;m=m||i.source,b=b||i.target;var E=o.getArrowWidth(l,c),_=[{name:"source",x:a.arrowStartX,y:a.arrowStartY,angle:a.srcArrowAngle},{name:"target",x:a.arrowEndX,y:a.arrowEndY,angle:a.tgtArrowAngle},{name:"mid-source",x:a.midX,y:a.midY,angle:a.midsrcArrowAngle},{name:"mid-target",x:a.midX,y:a.midY,angle:a.midtgtArrowAngle}];for(w=0;w<_.length;w++){var T=_[w],D=s.arrowShapes[n.pstyle(T.name+"-arrow-shape").value],C=n.pstyle("width").pfValue;if(D.roughCollide(e,t,E,T.angle,{x:T.x,y:T.y},C,d)&&D.collide(e,t,E,T.angle,{x:T.x,y:T.y},C,d))return v(n),!0}h&&u.length>0&&(y(m),y(b))}function b(e,t,n){return Re(e,t,n)}function x(n,r){var i,a=n._private,o=g;i=r?r+"-":"",n.boundingBox();var s=a.labelBounds[r||"main"],l=n.pstyle(i+"label").value;if("yes"===n.pstyle("text-events").strValue&&l){var u=b(a.rscratch,"labelX",r),c=b(a.rscratch,"labelY",r),h=b(a.rscratch,"labelAngle",r),d=n.pstyle(i+"text-margin-x").pfValue,p=n.pstyle(i+"text-margin-y").pfValue,f=s.x1-o-d,y=s.x2+o-d,m=s.y1-o-p,x=s.y2+o-p;if(h){var w=Math.cos(h),E=Math.sin(h),_=function(e,t){return{x:(e-=u)*w-(t-=c)*E+u,y:e*E+t*w+c}},T=_(f,m),D=_(f,x),C=_(y,m),N=_(y,x),A=[T.x+d,T.y+p,C.x+d,C.y+p,N.x+d,N.y+p,D.x+d,D.y+p];if(Lt(e,t,A))return v(n),!0}else if(Et(s,e,t))return v(n),!0}}n&&(l=l.interactive);for(var w=l.length-1;w>=0;w--){var E=l[w];E.isNode()?y(E)||x(E):m(E)||x(E)||x(E,"source")||x(E,"target")}return u},getAllInBox:function(e,t,n,r){for(var i,a,o=this.getCachedZSortedEles().interactive,s=[],l=Math.min(e,n),u=Math.max(e,n),c=Math.min(t,r),h=Math.max(t,r),d=ft({x1:e=l,y1:t=c,x2:n=u,y2:r=h}),p=0;p<o.length;p++){var g=o[p];if(g.isNode()){var f=g,v=f.boundingBox({includeNodes:!0,includeEdges:!1,includeLabels:!1});wt(d,v)&&!_t(v,d)&&s.push(f)}else{var y=g,m=y._private,b=m.rscratch;if(null!=b.startX&&null!=b.startY&&!Et(d,b.startX,b.startY))continue;if(null!=b.endX&&null!=b.endY&&!Et(d,b.endX,b.endY))continue;if("bezier"===b.edgeType||"multibezier"===b.edgeType||"self"===b.edgeType||"compound"===b.edgeType||"segments"===b.edgeType||"haystack"===b.edgeType){for(var x=m.rstyle.bezierPts||m.rstyle.linePts||m.rstyle.haystackPts,w=!0,E=0;E<x.length;E++)if(i=d,a=x[E],!Et(i,a.x,a.y)){w=!1;break}w&&s.push(y)}else"haystack"!==b.edgeType&&"straight"!==b.edgeType||s.push(y)}}return s}},rs={calculateArrowAngles:function(e){var t,n,r,i,a,o,s=e._private.rscratch,l="haystack"===s.edgeType,u="bezier"===s.edgeType,c="multibezier"===s.edgeType,h="segments"===s.edgeType,d="compound"===s.edgeType,p="self"===s.edgeType;if(l?(r=s.haystackPts[0],i=s.haystackPts[1],a=s.haystackPts[2],o=s.haystackPts[3]):(r=s.arrowStartX,i=s.arrowStartY,a=s.arrowEndX,o=s.arrowEndY),f=s.midX,v=s.midY,h)t=r-s.segpts[0],n=i-s.segpts[1];else if(c||d||p||u){var g=s.allpts;t=r-dt(g[0],g[2],g[4],.1),n=i-dt(g[1],g[3],g[5],.1)}else t=r-f,n=i-v;s.srcArrowAngle=ot(t,n);var f=s.midX,v=s.midY;if(l&&(f=(r+a)/2,v=(i+o)/2),t=a-r,n=o-i,h)if((g=s.allpts).length/2%2==0){var y=(m=g.length/2)-2;t=g[m]-g[y],n=g[m+1]-g[y+1]}else{y=(m=g.length/2-1)-2;var m,b=m+2;t=g[m]-g[y],n=g[m+1]-g[y+1]}else if(c||d||p){var x,w,E,_,g=s.allpts;if(s.ctrlpts.length/2%2==0){var T=(D=(C=g.length/2-1)+2)+2;x=dt(g[C],g[D],g[T],0),w=dt(g[C+1],g[D+1],g[T+1],0),E=dt(g[C],g[D],g[T],1e-4),_=dt(g[C+1],g[D+1],g[T+1],1e-4)}else{var D,C;T=(D=g.length/2-1)+2;x=dt(g[C=D-2],g[D],g[T],.4999),w=dt(g[C+1],g[D+1],g[T+1],.4999),E=dt(g[C],g[D],g[T],.5),_=dt(g[C+1],g[D+1],g[T+1],.5)}t=E-x,n=_-w}(s.midtgtArrowAngle=ot(t,n),s.midDispX=t,s.midDispY=n,t*=-1,n*=-1,h)&&((g=s.allpts).length/2%2==0||(t=-(g[b=(m=g.length/2-1)+2]-g[m]),n=-(g[b+1]-g[m+1])));if(s.midsrcArrowAngle=ot(t,n),h)t=a-s.segpts[s.segpts.length-2],n=o-s.segpts[s.segpts.length-1];else if(c||d||p||u){var N=(g=s.allpts).length;t=a-dt(g[N-6],g[N-4],g[N-2],.9),n=o-dt(g[N-5],g[N-3],g[N-1],.9)}else t=a-f,n=o-v;s.tgtArrowAngle=ot(t,n)}};rs.getArrowWidth=rs.getArrowHeight=function(e,t){var n=this.arrowWidthCache=this.arrowWidthCache||{},r=n[e+", "+t];return r||(r=Math.max(Math.pow(13.37*e,.9),29)*t,n[e+", "+t]=r,r)};var is={};function as(e){var t=[];if(null!=e){for(var n=0;n<e.length;n+=2){var r=e[n],i=e[n+1];t.push({x:r,y:i})}return t}}is.findMidptPtsEtc=function(e,t){var n,r=t.posPts,i=t.intersectionPts,a=t.vectorNormInverse,o=e.pstyle("source-endpoint"),s=e.pstyle("target-endpoint"),l=null!=o.units&&null!=s.units;switch(e.pstyle("edge-distances").value){case"node-position":n=r;break;case"intersection":n=i;break;case"endpoints":if(l){var u=b(this.manualEndptToPx(e.source()[0],o),2),c=u[0],h=u[1],d=b(this.manualEndptToPx(e.target()[0],s),2),p=d[0],g=d[1],f={x1:c,y1:h,x2:p,y2:g};a=function(e,t,n,r){var i=r-t,a=n-e,o=Math.sqrt(a*a+i*i);return{x:-i/o,y:a/o}}(c,h,p,g),n=f}else Ae("Edge ".concat(e.id()," has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint. Falling back on edge-distances:intersection (default).")),n=i}return{midptPts:n,vectorNormInverse:a}},is.findHaystackPoints=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=n._private,i=r.rscratch;if(!i.haystack){var a=2*Math.random()*Math.PI;i.source={x:Math.cos(a),y:Math.sin(a)},a=2*Math.random()*Math.PI,i.target={x:Math.cos(a),y:Math.sin(a)}}var o=r.source,s=r.target,l=o.position(),u=s.position(),c=o.width(),h=s.width(),d=o.height(),p=s.height(),g=n.pstyle("haystack-radius").value/2;i.haystackPts=i.allpts=[i.source.x*c*g+l.x,i.source.y*d*g+l.y,i.target.x*h*g+u.x,i.target.y*p*g+u.y],i.midX=(i.allpts[0]+i.allpts[2])/2,i.midY=(i.allpts[1]+i.allpts[3])/2,i.edgeType="haystack",i.haystack=!0,this.storeEdgeProjections(n),this.calculateArrowAngles(n),this.recalculateEdgeLabelProjections(n),this.calculateLabelAngles(n)}},is.findSegmentsPoints=function(e,t){var n=e._private.rscratch,r=e.pstyle("segment-weights"),i=e.pstyle("segment-distances"),a=Math.min(r.pfValue.length,i.pfValue.length);n.edgeType="segments",n.segpts=[];for(var o=0;o<a;o++){var s=r.pfValue[o],l=i.pfValue[o],u=1-s,c=s,h=this.findMidptPtsEtc(e,t),d=h.midptPts,p=h.vectorNormInverse,g={x:d.x1*u+d.x2*c,y:d.y1*u+d.y2*c};n.segpts.push(g.x+p.x*l,g.y+p.y*l)}},is.findLoopPoints=function(e,t,n,r){var i=e._private.rscratch,a=t.dirCounts,o=t.srcPos,s=e.pstyle("control-point-distances"),l=s?s.pfValue[0]:void 0,u=e.pstyle("loop-direction").pfValue,c=e.pstyle("loop-sweep").pfValue,h=e.pstyle("control-point-step-size").pfValue;i.edgeType="self";var d=n,p=h;r&&(d=0,p=l);var g=u-Math.PI/2,f=g-c/2,v=g+c/2,y=String(u+"_"+c);d=void 0===a[y]?a[y]=0:++a[y],i.ctrlpts=[o.x+1.4*Math.cos(f)*p*(d/3+1),o.y+1.4*Math.sin(f)*p*(d/3+1),o.x+1.4*Math.cos(v)*p*(d/3+1),o.y+1.4*Math.sin(v)*p*(d/3+1)]},is.findCompoundLoopPoints=function(e,t,n,r){var i=e._private.rscratch;i.edgeType="compound";var a=t.srcPos,o=t.tgtPos,s=t.srcW,l=t.srcH,u=t.tgtW,c=t.tgtH,h=e.pstyle("control-point-step-size").pfValue,d=e.pstyle("control-point-distances"),p=d?d.pfValue[0]:void 0,g=n,f=h;r&&(g=0,f=p);var v={x:a.x-s/2,y:a.y-l/2},y={x:o.x-u/2,y:o.y-c/2},m={x:Math.min(v.x,y.x),y:Math.min(v.y,y.y)},b=Math.max(.5,Math.log(.01*s)),x=Math.max(.5,Math.log(.01*u));i.ctrlpts=[m.x,m.y-(1+Math.pow(50,1.12)/100)*f*(g/3+1)*b,m.x-(1+Math.pow(50,1.12)/100)*f*(g/3+1)*x,m.y]},is.findStraightEdgePoints=function(e){e._private.rscratch.edgeType="straight"},is.findBezierPoints=function(e,t,n,r,i){var a=e._private.rscratch,o=e.pstyle("control-point-step-size").pfValue,s=e.pstyle("control-point-distances"),l=e.pstyle("control-point-weights"),u=s&&l?Math.min(s.value.length,l.value.length):1,c=s?s.pfValue[0]:void 0,h=l.value[0],d=r;a.edgeType=d?"multibezier":"bezier",a.ctrlpts=[];for(var p=0;p<u;p++){var g=(.5-t.eles.length/2+n)*o*(i?-1:1),f=void 0,v=lt(g);d&&(c=s?s.pfValue[p]:o,h=l.value[p]);var y=void 0!==(f=r?c:void 0!==c?v*c:void 0)?f:g,m=1-h,b=h,x=this.findMidptPtsEtc(e,t),w=x.midptPts,E=x.vectorNormInverse,_={x:w.x1*m+w.x2*b,y:w.y1*m+w.y2*b};a.ctrlpts.push(_.x+E.x*y,_.y+E.y*y)}},is.findTaxiPoints=function(e,t){var n=e._private.rscratch;n.edgeType="segments";var r="vertical",i="horizontal",a="leftward",o="rightward",s="downward",l="upward",u=t.posPts,c=t.srcW,h=t.srcH,d=t.tgtW,p=t.tgtH,g="node-position"!==e.pstyle("edge-distances").value,f=e.pstyle("taxi-direction").value,v=f,y=e.pstyle("taxi-turn"),m="%"===y.units,b=y.pfValue,x=b<0,w=e.pstyle("taxi-turn-min-distance").pfValue,E=g?(c+d)/2:0,_=g?(h+p)/2:0,T=u.x2-u.x1,D=u.y2-u.y1,C=function(e,t){return e>0?Math.max(e-t,0):Math.min(e+t,0)},N=C(T,E),A=C(D,_),L=!1;"auto"===v?f=Math.abs(N)>Math.abs(A)?i:r:v===l||v===s?(f=r,L=!0):v!==a&&v!==o||(f=i,L=!0);var k,S=f===r,I=S?A:N,M=S?D:T,O=lt(M),P=!1;(L&&(m||x)||!(v===s&&M<0||v===l&&M>0||v===a&&M>0||v===o&&M<0)||(I=(O*=-1)*Math.abs(I),P=!0),m)?k=(b<0?1+b:b)*I:k=(b<0?I:0)+b*O;var R=function(e){return Math.abs(e)<w||Math.abs(e)>=Math.abs(I)},B=R(k),F=R(Math.abs(I)-Math.abs(k));if((B||F)&&!P)if(S){var z=Math.abs(M)<=h/2,G=Math.abs(T)<=d/2;if(z){var Y=(u.x1+u.x2)/2,X=u.y1,V=u.y2;n.segpts=[Y,X,Y,V]}else if(G){var U=(u.y1+u.y2)/2,j=u.x1,q=u.x2;n.segpts=[j,U,q,U]}else n.segpts=[u.x1,u.y2]}else{var H=Math.abs(M)<=c/2,W=Math.abs(D)<=p/2;if(H){var $=(u.y1+u.y2)/2,K=u.x1,Z=u.x2;n.segpts=[K,$,Z,$]}else if(W){var Q=(u.x1+u.x2)/2,J=u.y1,ee=u.y2;n.segpts=[Q,J,Q,ee]}else n.segpts=[u.x2,u.y1]}else if(S){var te=u.y1+k+(g?h/2*O:0),ne=u.x1,re=u.x2;n.segpts=[ne,te,re,te]}else{var ie=u.x1+k+(g?c/2*O:0),ae=u.y1,oe=u.y2;n.segpts=[ie,ae,ie,oe]}},is.tryToCorrectInvalidPoints=function(e,t){var n=e._private.rscratch;if("bezier"===n.edgeType){var r=t.srcPos,i=t.tgtPos,a=t.srcW,o=t.srcH,s=t.tgtW,l=t.tgtH,u=t.srcShape,c=t.tgtShape,h=!I(n.startX)||!I(n.startY),d=!I(n.arrowStartX)||!I(n.arrowStartY),p=!I(n.endX)||!I(n.endY),g=!I(n.arrowEndX)||!I(n.arrowEndY),f=3*(this.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.arrowShapeWidth),v=ut({x:n.ctrlpts[0],y:n.ctrlpts[1]},{x:n.startX,y:n.startY}),y=v<f,m=ut({x:n.ctrlpts[0],y:n.ctrlpts[1]},{x:n.endX,y:n.endY}),b=m<f,x=!1;if(h||d||y){x=!0;var w={x:n.ctrlpts[0]-r.x,y:n.ctrlpts[1]-r.y},E=Math.sqrt(w.x*w.x+w.y*w.y),_={x:w.x/E,y:w.y/E},T=Math.max(a,o),D={x:n.ctrlpts[0]+2*_.x*T,y:n.ctrlpts[1]+2*_.y*T},C=u.intersectLine(r.x,r.y,a,o,D.x,D.y,0);y?(n.ctrlpts[0]=n.ctrlpts[0]+_.x*(f-v),n.ctrlpts[1]=n.ctrlpts[1]+_.y*(f-v)):(n.ctrlpts[0]=C[0]+_.x*f,n.ctrlpts[1]=C[1]+_.y*f)}if(p||g||b){x=!0;var N={x:n.ctrlpts[0]-i.x,y:n.ctrlpts[1]-i.y},A=Math.sqrt(N.x*N.x+N.y*N.y),L={x:N.x/A,y:N.y/A},k=Math.max(a,o),S={x:n.ctrlpts[0]+2*L.x*k,y:n.ctrlpts[1]+2*L.y*k},M=c.intersectLine(i.x,i.y,s,l,S.x,S.y,0);b?(n.ctrlpts[0]=n.ctrlpts[0]+L.x*(f-m),n.ctrlpts[1]=n.ctrlpts[1]+L.y*(f-m)):(n.ctrlpts[0]=M[0]+L.x*f,n.ctrlpts[1]=M[1]+L.y*f)}x&&this.findEndpoints(e)}},is.storeAllpts=function(e){var t=e._private.rscratch;if("multibezier"===t.edgeType||"bezier"===t.edgeType||"self"===t.edgeType||"compound"===t.edgeType){t.allpts=[],t.allpts.push(t.startX,t.startY);for(var n=0;n+1<t.ctrlpts.length;n+=2)t.allpts.push(t.ctrlpts[n],t.ctrlpts[n+1]),n+3<t.ctrlpts.length&&t.allpts.push((t.ctrlpts[n]+t.ctrlpts[n+2])/2,(t.ctrlpts[n+1]+t.ctrlpts[n+3])/2);var r;t.allpts.push(t.endX,t.endY),t.ctrlpts.length/2%2==0?(r=t.allpts.length/2-1,t.midX=t.allpts[r],t.midY=t.allpts[r+1]):(r=t.allpts.length/2-3,.5,t.midX=dt(t.allpts[r],t.allpts[r+2],t.allpts[r+4],.5),t.midY=dt(t.allpts[r+1],t.allpts[r+3],t.allpts[r+5],.5))}else if("straight"===t.edgeType)t.allpts=[t.startX,t.startY,t.endX,t.endY],t.midX=(t.startX+t.endX+t.arrowStartX+t.arrowEndX)/4,t.midY=(t.startY+t.endY+t.arrowStartY+t.arrowEndY)/4;else if("segments"===t.edgeType)if(t.allpts=[],t.allpts.push(t.startX,t.startY),t.allpts.push.apply(t.allpts,t.segpts),t.allpts.push(t.endX,t.endY),t.segpts.length%4==0){var i=t.segpts.length/2,a=i-2;t.midX=(t.segpts[a]+t.segpts[i])/2,t.midY=(t.segpts[a+1]+t.segpts[i+1])/2}else{var o=t.segpts.length/2-1;t.midX=t.segpts[o],t.midY=t.segpts[o+1]}},is.checkForInvalidEdgeWarning=function(e){var t=e[0]._private.rscratch;t.nodesOverlap||I(t.startX)&&I(t.startY)&&I(t.endX)&&I(t.endY)?t.loggedErr=!1:t.loggedErr||(t.loggedErr=!0,Ae("Edge `"+e.id()+"` has invalid endpoints and so it is impossible to draw. Adjust your edge style (e.g. control points) accordingly or use an alternative edge type. This is expected behaviour when the source node and the target node overlap."))},is.findEdgeControlPoints=function(e){var t=this;if(e&&0!==e.length){for(var n=this,r=n.cy.hasCompoundNodes(),i={map:new Fe,get:function(e){var t=this.map.get(e[0]);return null!=t?t.get(e[1]):null},set:function(e,t){var n=this.map.get(e[0]);null==n&&(n=new Fe,this.map.set(e[0],n)),n.set(e[1],t)}},a=[],o=[],s=0;s<e.length;s++){var l=e[s],u=l._private,c=l.pstyle("curve-style").value;if(!l.removed()&&l.takesUpSpace())if("haystack"!==c){var h="unbundled-bezier"===c||"segments"===c||"straight"===c||"straight-triangle"===c||"taxi"===c,d="unbundled-bezier"===c||"bezier"===c,p=u.source,g=u.target,f=[p.poolIndex(),g.poolIndex()].sort(),v=i.get(f);null==v&&(v={eles:[]},i.set(f,v),a.push(f)),v.eles.push(l),h&&(v.hasUnbundled=!0),d&&(v.hasBezier=!0)}else o.push(l)}for(var y=function(e){var o=a[e],s=i.get(o),l=void 0;if(!s.hasUnbundled){var u=s.eles[0].parallelEdges().filter((function(e){return e.isBundledBezier()}));Pe(s.eles),u.forEach((function(e){return s.eles.push(e)})),s.eles.sort((function(e,t){return e.poolIndex()-t.poolIndex()}))}var c=s.eles[0],h=c.source(),d=c.target();if(h.poolIndex()>d.poolIndex()){var p=h;h=d,d=p}var g=s.srcPos=h.position(),f=s.tgtPos=d.position(),v=s.srcW=h.outerWidth(),y=s.srcH=h.outerHeight(),m=s.tgtW=d.outerWidth(),b=s.tgtH=d.outerHeight(),x=s.srcShape=n.nodeShapes[t.getNodeShape(h)],w=s.tgtShape=n.nodeShapes[t.getNodeShape(d)];s.dirCounts={north:0,west:0,south:0,east:0,northwest:0,southwest:0,northeast:0,southeast:0};for(var E=0;E<s.eles.length;E++){var _=s.eles[E],T=_[0]._private.rscratch,D=_.pstyle("curve-style").value,C="unbundled-bezier"===D||"segments"===D||"taxi"===D,N=!h.same(_.source());if(!s.calculatedIntersection&&h!==d&&(s.hasBezier||s.hasUnbundled)){s.calculatedIntersection=!0;var A=x.intersectLine(g.x,g.y,v,y,f.x,f.y,0),L=s.srcIntn=A,k=w.intersectLine(f.x,f.y,m,b,g.x,g.y,0),S=s.tgtIntn=k,M=s.intersectionPts={x1:A[0],x2:k[0],y1:A[1],y2:k[1]},O=s.posPts={x1:g.x,x2:f.x,y1:g.y,y2:f.y},P=k[1]-A[1],R=k[0]-A[0],B=Math.sqrt(R*R+P*P),F=s.vector={x:R,y:P},z=s.vectorNorm={x:F.x/B,y:F.y/B},G={x:-z.y,y:z.x};s.nodesOverlap=!I(B)||w.checkPoint(A[0],A[1],0,m,b,f.x,f.y)||x.checkPoint(k[0],k[1],0,v,y,g.x,g.y),s.vectorNormInverse=G,l={nodesOverlap:s.nodesOverlap,dirCounts:s.dirCounts,calculatedIntersection:!0,hasBezier:s.hasBezier,hasUnbundled:s.hasUnbundled,eles:s.eles,srcPos:f,tgtPos:g,srcW:m,srcH:b,tgtW:v,tgtH:y,srcIntn:S,tgtIntn:L,srcShape:w,tgtShape:x,posPts:{x1:O.x2,y1:O.y2,x2:O.x1,y2:O.y1},intersectionPts:{x1:M.x2,y1:M.y2,x2:M.x1,y2:M.y1},vector:{x:-F.x,y:-F.y},vectorNorm:{x:-z.x,y:-z.y},vectorNormInverse:{x:-G.x,y:-G.y}}}var Y=N?l:s;T.nodesOverlap=Y.nodesOverlap,T.srcIntn=Y.srcIntn,T.tgtIntn=Y.tgtIntn,r&&(h.isParent()||h.isChild()||d.isParent()||d.isChild())&&(h.parents().anySame(d)||d.parents().anySame(h)||h.same(d)&&h.isParent())?t.findCompoundLoopPoints(_,Y,E,C):h===d?t.findLoopPoints(_,Y,E,C):"segments"===D?t.findSegmentsPoints(_,Y):"taxi"===D?t.findTaxiPoints(_,Y):"straight"===D||!C&&s.eles.length%2==1&&E===Math.floor(s.eles.length/2)?t.findStraightEdgePoints(_):t.findBezierPoints(_,Y,E,C,N),t.findEndpoints(_),t.tryToCorrectInvalidPoints(_,Y),t.checkForInvalidEdgeWarning(_),t.storeAllpts(_),t.storeEdgeProjections(_),t.calculateArrowAngles(_),t.recalculateEdgeLabelProjections(_),t.calculateLabelAngles(_)}},m=0;m<a.length;m++)y(m);this.findHaystackPoints(o)}},is.getSegmentPoints=function(e){var t=e[0]._private.rscratch;if("segments"===t.edgeType)return this.recalculateRenderedStyle(e),as(t.segpts)},is.getControlPoints=function(e){var t=e[0]._private.rscratch,n=t.edgeType;if("bezier"===n||"multibezier"===n||"self"===n||"compound"===n)return this.recalculateRenderedStyle(e),as(t.ctrlpts)},is.getEdgeMidpoint=function(e){var t=e[0]._private.rscratch;return this.recalculateRenderedStyle(e),{x:t.midX,y:t.midY}};var os={manualEndptToPx:function(e,t){var n=e.position(),r=e.outerWidth(),i=e.outerHeight();if(2===t.value.length){var a=[t.pfValue[0],t.pfValue[1]];return"%"===t.units[0]&&(a[0]=a[0]*r),"%"===t.units[1]&&(a[1]=a[1]*i),a[0]+=n.x,a[1]+=n.y,a}var o=t.pfValue[0];o=-Math.PI/2+o;var s=2*Math.max(r,i),l=[n.x+Math.cos(o)*s,n.y+Math.sin(o)*s];return this.nodeShapes[this.getNodeShape(e)].intersectLine(n.x,n.y,r,i,l[0],l[1],0)},findEndpoints:function(e){var t,n,r,i,a,o=this,s=e.source()[0],l=e.target()[0],u=s.position(),c=l.position(),h=e.pstyle("target-arrow-shape").value,d=e.pstyle("source-arrow-shape").value,p=e.pstyle("target-distance-from-node").pfValue,g=e.pstyle("source-distance-from-node").pfValue,f=e.pstyle("curve-style").value,v=e._private.rscratch,y=v.edgeType,m="self"===y||"compound"===y,b="bezier"===y||"multibezier"===y||m,x="bezier"!==y,w="straight"===y||"segments"===y,E="segments"===y,_=b||x||w,T=m||"taxi"===f,D=e.pstyle("source-endpoint"),C=T?"outside-to-node":D.value,N=e.pstyle("target-endpoint"),A=T?"outside-to-node":N.value;if(v.srcManEndpt=D,v.tgtManEndpt=N,b){var L=[v.ctrlpts[0],v.ctrlpts[1]];n=x?[v.ctrlpts[v.ctrlpts.length-2],v.ctrlpts[v.ctrlpts.length-1]]:L,r=L}else if(w){var k=E?v.segpts.slice(0,2):[c.x,c.y];n=E?v.segpts.slice(v.segpts.length-2):[u.x,u.y],r=k}if("inside-to-node"===A)t=[c.x,c.y];else if(N.units)t=this.manualEndptToPx(l,N);else if("outside-to-line"===A)t=v.tgtIntn;else if("outside-to-node"===A||"outside-to-node-or-label"===A?i=n:"outside-to-line"!==A&&"outside-to-line-or-label"!==A||(i=[u.x,u.y]),t=o.nodeShapes[this.getNodeShape(l)].intersectLine(c.x,c.y,l.outerWidth(),l.outerHeight(),i[0],i[1],0),"outside-to-node-or-label"===A||"outside-to-line-or-label"===A){var S=l._private.rscratch,M=S.labelWidth,O=S.labelHeight,P=S.labelX,R=S.labelY,B=M/2,F=O/2,z=l.pstyle("text-valign").value;"top"===z?R-=F:"bottom"===z&&(R+=F);var G=l.pstyle("text-halign").value;"left"===G?P-=B:"right"===G&&(P+=B);var Y=Bt(i[0],i[1],[P-B,R-F,P+B,R-F,P+B,R+F,P-B,R+F],c.x,c.y);if(Y.length>0){var X=u,V=ct(X,at(t)),U=ct(X,at(Y)),j=V;if(U<V&&(t=Y,j=U),Y.length>2)ct(X,{x:Y[2],y:Y[3]})<j&&(t=[Y[2],Y[3]])}}var q=Ft(t,n,o.arrowShapes[h].spacing(e)+p),H=Ft(t,n,o.arrowShapes[h].gap(e)+p);if(v.endX=H[0],v.endY=H[1],v.arrowEndX=q[0],v.arrowEndY=q[1],"inside-to-node"===C)t=[u.x,u.y];else if(D.units)t=this.manualEndptToPx(s,D);else if("outside-to-line"===C)t=v.srcIntn;else if("outside-to-node"===C||"outside-to-node-or-label"===C?a=r:"outside-to-line"!==C&&"outside-to-line-or-label"!==C||(a=[c.x,c.y]),t=o.nodeShapes[this.getNodeShape(s)].intersectLine(u.x,u.y,s.outerWidth(),s.outerHeight(),a[0],a[1],0),"outside-to-node-or-label"===C||"outside-to-line-or-label"===C){var W=s._private.rscratch,$=W.labelWidth,K=W.labelHeight,Z=W.labelX,Q=W.labelY,J=$/2,ee=K/2,te=s.pstyle("text-valign").value;"top"===te?Q-=ee:"bottom"===te&&(Q+=ee);var ne=s.pstyle("text-halign").value;"left"===ne?Z-=J:"right"===ne&&(Z+=J);var re=Bt(a[0],a[1],[Z-J,Q-ee,Z+J,Q-ee,Z+J,Q+ee,Z-J,Q+ee],u.x,u.y);if(re.length>0){var ie=c,ae=ct(ie,at(t)),oe=ct(ie,at(re)),se=ae;if(oe<ae&&(t=[re[0],re[1]],se=oe),re.length>2)ct(ie,{x:re[2],y:re[3]})<se&&(t=[re[2],re[3]])}}var le=Ft(t,r,o.arrowShapes[d].spacing(e)+g),ue=Ft(t,r,o.arrowShapes[d].gap(e)+g);v.startX=ue[0],v.startY=ue[1],v.arrowStartX=le[0],v.arrowStartY=le[1],_&&(I(v.startX)&&I(v.startY)&&I(v.endX)&&I(v.endY)?v.badLine=!1:v.badLine=!0)},getSourceEndpoint:function(e){var t=e[0]._private.rscratch;return this.recalculateRenderedStyle(e),"haystack"===t.edgeType?{x:t.haystackPts[0],y:t.haystackPts[1]}:{x:t.arrowStartX,y:t.arrowStartY}},getTargetEndpoint:function(e){var t=e[0]._private.rscratch;return this.recalculateRenderedStyle(e),"haystack"===t.edgeType?{x:t.haystackPts[2],y:t.haystackPts[3]}:{x:t.arrowEndX,y:t.arrowEndY}}},ss={};function ls(e,t,n){for(var r=function(e,t,n,r){return dt(e,t,n,r)},i=t._private.rstyle.bezierPts,a=0;a<e.bezierProjPcts.length;a++){var o=e.bezierProjPcts[a];i.push({x:r(n[0],n[2],n[4],o),y:r(n[1],n[3],n[5],o)})}}ss.storeEdgeProjections=function(e){var t=e._private,n=t.rscratch,r=n.edgeType;if(t.rstyle.bezierPts=null,t.rstyle.linePts=null,t.rstyle.haystackPts=null,"multibezier"===r||"bezier"===r||"self"===r||"compound"===r){t.rstyle.bezierPts=[];for(var i=0;i+5<n.allpts.length;i+=4)ls(this,e,n.allpts.slice(i,i+6))}else if("segments"===r){var a=t.rstyle.linePts=[];for(i=0;i+1<n.allpts.length;i+=2)a.push({x:n.allpts[i],y:n.allpts[i+1]})}else if("haystack"===r){var o=n.haystackPts;t.rstyle.haystackPts=[{x:o[0],y:o[1]},{x:o[2],y:o[3]}]}t.rstyle.arrowWidth=this.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.arrowShapeWidth},ss.recalculateEdgeProjections=function(e){this.findEdgeControlPoints(e)};var us={recalculateNodeLabelProjection:function(e){var t=e.pstyle("label").strValue;if(!z(t)){var n,r,i=e._private,a=e.width(),o=e.height(),s=e.padding(),l=e.position(),u=e.pstyle("text-halign").strValue,c=e.pstyle("text-valign").strValue,h=i.rscratch,d=i.rstyle;switch(u){case"left":n=l.x-a/2-s;break;case"right":n=l.x+a/2+s;break;default:n=l.x}switch(c){case"top":r=l.y-o/2-s;break;case"bottom":r=l.y+o/2+s;break;default:r=l.y}h.labelX=n,h.labelY=r,d.labelX=n,d.labelY=r,this.calculateLabelAngles(e),this.applyLabelDimensions(e)}}},cs=function(e,t){var n=Math.atan(t/e);return 0===e&&n<0&&(n*=-1),n},hs=function(e,t){var n=t.x-e.x,r=t.y-e.y;return cs(n,r)};us.recalculateEdgeLabelProjections=function(e){var t,n=e._private,r=n.rscratch,i=this,a={mid:e.pstyle("label").strValue,source:e.pstyle("source-label").strValue,target:e.pstyle("target-label").strValue};if(a.mid||a.source||a.target){t={x:r.midX,y:r.midY};var o=function(e,t,r){Be(n.rscratch,e,t,r),Be(n.rstyle,e,t,r)};o("labelX",null,t.x),o("labelY",null,t.y);var s=cs(r.midDispX,r.midDispY);o("labelAutoAngle",null,s);var l=function e(){if(e.cache)return e.cache;for(var t=[],a=0;a+5<r.allpts.length;a+=4){var o={x:r.allpts[a],y:r.allpts[a+1]},s={x:r.allpts[a+2],y:r.allpts[a+3]},l={x:r.allpts[a+4],y:r.allpts[a+5]};t.push({p0:o,p1:s,p2:l,startDist:0,length:0,segments:[]})}var u=n.rstyle.bezierPts,c=i.bezierProjPcts.length;function h(e,t,n,r,i){var a=ut(t,n),o=e.segments[e.segments.length-1],s={p0:t,p1:n,t0:r,t1:i,startDist:o?o.startDist+o.length:0,length:a};e.segments.push(s),e.length+=a}for(var d=0;d<t.length;d++){var p=t[d],g=t[d-1];g&&(p.startDist=g.startDist+g.length),h(p,p.p0,u[d*c],0,i.bezierProjPcts[0]);for(var f=0;f<c-1;f++)h(p,u[d*c+f],u[d*c+f+1],i.bezierProjPcts[f],i.bezierProjPcts[f+1]);h(p,u[d*c+c-1],p.p2,i.bezierProjPcts[c-1],1)}return e.cache=t},u=function(n){var i,s="source"===n;if(a[n]){var u=e.pstyle(n+"-text-offset").pfValue;switch(r.edgeType){case"self":case"compound":case"bezier":case"multibezier":for(var c,h=l(),d=0,p=0,g=0;g<h.length;g++){for(var f=h[s?g:h.length-1-g],v=0;v<f.segments.length;v++){var y=f.segments[s?v:f.segments.length-1-v],m=g===h.length-1&&v===f.segments.length-1;if(d=p,(p+=y.length)>=u||m){c={cp:f,segment:y};break}}if(c)break}var b=c.cp,x=c.segment,w=(u-d)/x.length,E=x.t1-x.t0,_=s?x.t0+E*w:x.t1-E*w;_=gt(0,_,1),t=pt(b.p0,b.p1,b.p2,_),i=function(e,t,n,r){var i=gt(0,r-.001,1),a=gt(0,r+.001,1),o=pt(e,t,n,i),s=pt(e,t,n,a);return hs(o,s)}(b.p0,b.p1,b.p2,_);break;case"straight":case"segments":case"haystack":for(var T,D,C,N,A=0,L=r.allpts.length,k=0;k+3<L&&(s?(C={x:r.allpts[k],y:r.allpts[k+1]},N={x:r.allpts[k+2],y:r.allpts[k+3]}):(C={x:r.allpts[L-2-k],y:r.allpts[L-1-k]},N={x:r.allpts[L-4-k],y:r.allpts[L-3-k]}),D=A,!((A+=T=ut(C,N))>=u));k+=2);var S=(u-D)/T;S=gt(0,S,1),t=function(e,t,n,r){var i=t.x-e.x,a=t.y-e.y,o=ut(e,t),s=i/o,l=a/o;return n=null==n?0:n,r=null!=r?r:n*o,{x:e.x+s*r,y:e.y+l*r}}(C,N,S),i=hs(C,N)}o("labelX",n,t.x),o("labelY",n,t.y),o("labelAutoAngle",n,i)}};u("source"),u("target"),this.applyLabelDimensions(e)}},us.applyLabelDimensions=function(e){this.applyPrefixedLabelDimensions(e),e.isEdge()&&(this.applyPrefixedLabelDimensions(e,"source"),this.applyPrefixedLabelDimensions(e,"target"))},us.applyPrefixedLabelDimensions=function(e,t){var n=e._private,r=this.getLabelText(e,t),i=this.calculateLabelDimensions(e,r),a=e.pstyle("line-height").pfValue,o=e.pstyle("text-wrap").strValue,s=Re(n.rscratch,"labelWrapCachedLines",t)||[],l="wrap"!==o?1:Math.max(s.length,1),u=i.height/l,c=u*a,h=i.width,d=i.height+(l-1)*(a-1)*u;Be(n.rstyle,"labelWidth",t,h),Be(n.rscratch,"labelWidth",t,h),Be(n.rstyle,"labelHeight",t,d),Be(n.rscratch,"labelHeight",t,d),Be(n.rscratch,"labelLineHeight",t,c)},us.getLabelText=function(e,t){var n=e._private,r=t?t+"-":"",i=e.pstyle(r+"label").strValue,a=e.pstyle("text-transform").value,o=function(e,r){return r?(Be(n.rscratch,e,t,r),r):Re(n.rscratch,e,t)};if(!i)return"";"none"==a||("uppercase"==a?i=i.toUpperCase():"lowercase"==a&&(i=i.toLowerCase()));var s=e.pstyle("text-wrap").value;if("wrap"===s){var l=o("labelKey");if(null!=l&&o("labelWrapKey")===l)return o("labelWrapCachedText");for(var u=i.split("\n"),c=e.pstyle("text-max-width").pfValue,h="anywhere"===e.pstyle("text-overflow-wrap").value,d=[],p=/[\s\u200b]+/,g=h?"":" ",f=0;f<u.length;f++){var v=u[f],y=this.calculateLabelDimensions(e,v).width;if(h){var m=v.split("").join("\u200b");v=m}if(y>c){for(var b=v.split(p),x="",w=0;w<b.length;w++){var E=b[w],_=0===x.length?E:x+g+E;this.calculateLabelDimensions(e,_).width<=c?x+=E+g:(x&&d.push(x),x=E+g)}x.match(/^[\s\u200b]+$/)||d.push(x)}else d.push(v)}o("labelWrapCachedLines",d),i=o("labelWrapCachedText",d.join("\n")),o("labelWrapKey",l)}else if("ellipsis"===s){var T=e.pstyle("text-max-width").pfValue,D="",C=!1;if(this.calculateLabelDimensions(e,i).width<T)return i;for(var N=0;N<i.length;N++){if(this.calculateLabelDimensions(e,D+i[N]+"\u2026").width>T)break;D+=i[N],N===i.length-1&&(C=!0)}return C||(D+="\u2026"),D}return i},us.getLabelJustification=function(e){var t=e.pstyle("text-justification").strValue,n=e.pstyle("text-halign").strValue;if("auto"!==t)return t;if(!e.isNode())return"center";switch(n){case"left":return"right";case"right":return"left";default:return"center"}},us.calculateLabelDimensions=function(e,t){var n=fe(t,e._private.labelDimsKey),r=this.labelDimCache||(this.labelDimCache=[]),i=r[n];if(null!=i)return i;var a=e.pstyle("font-style").strValue,o=e.pstyle("font-size").pfValue,s=e.pstyle("font-family").strValue,l=e.pstyle("font-weight").strValue,u=this.labelCalcCanvas,c=this.labelCalcCanvasContext;if(!u){u=this.labelCalcCanvas=document.createElement("canvas"),c=this.labelCalcCanvasContext=u.getContext("2d");var h=u.style;h.position="absolute",h.left="-9999px",h.top="-9999px",h.zIndex="-1",h.visibility="hidden",h.pointerEvents="none"}c.font="".concat(a," ").concat(l," ").concat(o,"px ").concat(s);for(var d=0,p=0,g=t.split("\n"),f=0;f<g.length;f++){var v=g[f],y=c.measureText(v),m=Math.ceil(y.width),b=o;d=Math.max(m,d),p+=b}return d+=0,p+=0,r[n]={width:d,height:p}},us.calculateLabelAngle=function(e,t){var n=e._private.rscratch,r=e.isEdge(),i=t?t+"-":"",a=e.pstyle(i+"text-rotation"),o=a.strValue;return"none"===o?0:r&&"autorotate"===o?n.labelAutoAngle:"autorotate"===o?0:a.pfValue},us.calculateLabelAngles=function(e){var t=this,n=e.isEdge(),r=e._private.rscratch;r.labelAngle=t.calculateLabelAngle(e),n&&(r.sourceLabelAngle=t.calculateLabelAngle(e,"source"),r.targetLabelAngle=t.calculateLabelAngle(e,"target"))};var ds={},ps=!1;ds.getNodeShape=function(e){var t=e.pstyle("shape").value;if("cutrectangle"===t&&(e.width()<28||e.height()<28))return ps||(Ae("The `cutrectangle` node shape can not be used at small sizes so `rectangle` is used instead"),ps=!0),"rectangle";if(e.isParent())return"rectangle"===t||"roundrectangle"===t||"round-rectangle"===t||"cutrectangle"===t||"cut-rectangle"===t||"barrel"===t?t:"rectangle";if("polygon"===t){var n=e.pstyle("shape-polygon-points").value;return this.nodeShapes.makePolygon(n).name}return t};var gs={registerCalculationListeners:function(){var e=this.cy,t=e.collection(),n=this,r=function(e){var n=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(t.merge(e),n)for(var r=0;r<e.length;r++){var i=e[r]._private.rstyle;i.clean=!1,i.cleanConnected=!1}};n.binder(e).on("bounds.* dirty.*",(function(e){var t=e.target;r(t)})).on("style.* background.*",(function(e){var t=e.target;r(t,!1)}));var i=function(i){if(i){var a=n.onUpdateEleCalcsFns;t.cleanStyle();for(var o=0;o<t.length;o++){var s=t[o],l=s._private.rstyle;s.isNode()&&!l.cleanConnected&&(r(s.connectedEdges()),l.cleanConnected=!0)}if(a)for(var u=0;u<a.length;u++){(0,a[u])(i,t)}n.recalculateRenderedStyle(t),t=e.collection()}};n.flushRenderedStyleQueue=function(){i(!0)},n.beforeRender(i,n.beforeRenderPriorities.eleCalcs)},onUpdateEleCalcs:function(e){(this.onUpdateEleCalcsFns=this.onUpdateEleCalcsFns||[]).push(e)},recalculateRenderedStyle:function(e,t){var n=function(e){return e._private.rstyle.cleanConnected},r=[],i=[];if(!this.destroyed){void 0===t&&(t=!0);for(var a=0;a<e.length;a++){var o=e[a],s=o._private,l=s.rstyle;!o.isEdge()||n(o.source())&&n(o.target())||(l.clean=!1),t&&l.clean||o.removed()||"none"!==o.pstyle("display").value&&("nodes"===s.group?i.push(o):r.push(o),l.clean=!0)}for(var u=0;u<i.length;u++){var c=i[u],h=c._private.rstyle,d=c.position();this.recalculateNodeLabelProjection(c),h.nodeX=d.x,h.nodeY=d.y,h.nodeW=c.pstyle("width").pfValue,h.nodeH=c.pstyle("height").pfValue}this.recalculateEdgeProjections(r);for(var p=0;p<r.length;p++){var g=r[p]._private,f=g.rstyle,v=g.rscratch;f.srcX=v.arrowStartX,f.srcY=v.arrowStartY,f.tgtX=v.arrowEndX,f.tgtY=v.arrowEndY,f.midX=v.midX,f.midY=v.midY,f.labelAngle=v.labelAngle,f.sourceLabelAngle=v.sourceLabelAngle,f.targetLabelAngle=v.targetLabelAngle}}}},fs={updateCachedGrabbedEles:function(){var e=this.cachedZSortedEles;if(e){e.drag=[],e.nondrag=[];for(var t=[],n=0;n<e.length;n++){var r=(i=e[n])._private.rscratch;i.grabbed()&&!i.isParent()?t.push(i):r.inDragLayer?e.drag.push(i):e.nondrag.push(i)}for(n=0;n<t.length;n++){var i=t[n];e.drag.push(i)}}},invalidateCachedZSortedEles:function(){this.cachedZSortedEles=null},getCachedZSortedEles:function(e){if(e||!this.cachedZSortedEles){var t=this.cy.mutableElements().toArray();t.sort(Ji),t.interactive=t.filter((function(e){return e.interactive()})),this.cachedZSortedEles=t,this.updateCachedGrabbedEles()}else t=this.cachedZSortedEles;return t}},vs={};[ns,rs,is,os,ss,us,ds,gs,fs].forEach((function(e){Q(vs,e)}));var ys={getCachedImage:function(e,t,n){var r=this.imageCache=this.imageCache||{},i=r[e];if(i)return i.image.complete||i.image.addEventListener("load",n),i.image;var a=(i=r[e]=r[e]||{}).image=new Image;a.addEventListener("load",n),a.addEventListener("error",(function(){a.error=!0}));var o="data:";return e.substring(0,5).toLowerCase()===o||(t="null"===t?null:t,a.crossOrigin=t),a.src=e,a}},ms={registerBinding:function(e,t,n,r){var i=Array.prototype.slice.apply(arguments,[1]),a=this.binder(e);return a.on.apply(a,i)}};ms.binder=function(e){var t,n=this,r=n.cy.window(),i=e===r||e===r.document||e===r.document.body||(t=e,"undefined"!=typeof HTMLElement&&t instanceof HTMLElement);if(null==n.supportsPassiveEvents){var a=!1;try{var o=Object.defineProperty({},"passive",{get:function(){return a=!0,!0}});r.addEventListener("test",null,o)}catch(l){}n.supportsPassiveEvents=a}var s=function(t,r,a){var o=Array.prototype.slice.call(arguments);return i&&n.supportsPassiveEvents&&(o[2]={capture:null!=a&&a,passive:!1,once:!1}),n.bindings.push({target:e,args:o}),(e.addEventListener||e.on).apply(e,o),this};return{on:s,addEventListener:s,addListener:s,bind:s}},ms.nodeIsDraggable=function(e){return e&&e.isNode()&&!e.locked()&&e.grabbable()},ms.nodeIsGrabbable=function(e){return this.nodeIsDraggable(e)&&e.interactive()},ms.load=function(){var e=this,t=e.cy.window(),n=function(e){return e.selected()},r=function(t,n,r,i){null==t&&(t=e.cy);for(var a=0;a<n.length;a++){var o=n[a];t.emit({originalEvent:r,type:o,position:i})}},i=function(e){return e.shiftKey||e.metaKey||e.ctrlKey},a=function(t,n){var r=!0;if(e.cy.hasCompoundNodes()&&t&&t.pannable())for(var i=0;n&&i<n.length;i++){if((t=n[i]).isNode()&&t.isParent()&&!t.pannable()){r=!1;break}}else r=!0;return r},o=function(e){e[0]._private.rscratch.inDragLayer=!0},s=function(e){e[0]._private.rscratch.isGrabTarget=!0},l=function(e,t){var n=t.addToList;n.has(e)||!e.grabbable()||e.locked()||(n.merge(e),function(e){e[0]._private.grabbed=!0}(e))},c=function(t,n){n=n||{};var r=t.cy().hasCompoundNodes();n.inDragLayer&&(t.forEach(o),t.neighborhood().stdFilter((function(e){return!r||e.isEdge()})).forEach(o)),n.addToList&&t.forEach((function(e){l(e,n)})),function(e,t){if(e.cy().hasCompoundNodes()&&(null!=t.inDragLayer||null!=t.addToList)){var n=e.descendants();t.inDragLayer&&(n.forEach(o),n.connectedEdges().forEach(o)),t.addToList&&l(n,t)}}(t,n),p(t,{inDragLayer:n.inDragLayer}),e.updateCachedGrabbedEles()},h=c,d=function(t){t&&(e.getCachedZSortedEles().forEach((function(e){!function(e){e[0]._private.grabbed=!1}(e),function(e){e[0]._private.rscratch.inDragLayer=!1}(e),function(e){e[0]._private.rscratch.isGrabTarget=!1}(e)})),e.updateCachedGrabbedEles())},p=function(e,t){if((null!=t.inDragLayer||null!=t.addToList)&&e.cy().hasCompoundNodes()){var n=e.ancestors().orphans();if(!n.same(e)){var r=n.descendants().spawnSelf().merge(n).unmerge(e).unmerge(e.descendants()),i=r.connectedEdges();t.inDragLayer&&(i.forEach(o),r.forEach(o)),t.addToList&&r.forEach((function(e){l(e,t)}))}}},g=function(){null!=document.activeElement&&null!=document.activeElement.blur&&document.activeElement.blur()},f="undefined"!=typeof MutationObserver,v="undefined"!=typeof ResizeObserver;f?(e.removeObserver=new MutationObserver((function(t){for(var n=0;n<t.length;n++){var r=t[n].removedNodes;if(r)for(var i=0;i<r.length;i++){if(r[i]===e.container){e.destroy();break}}}})),e.container.parentNode&&e.removeObserver.observe(e.container.parentNode,{childList:!0})):e.registerBinding(e.container,"DOMNodeRemoved",(function(t){e.destroy()}));var y=u.default((function(){e.cy.resize()}),100);f&&(e.styleObserver=new MutationObserver(y),e.styleObserver.observe(e.container,{attributes:!0})),e.registerBinding(t,"resize",y),v&&(e.resizeObserver=new ResizeObserver(y),e.resizeObserver.observe(e.container));var m=function(){e.invalidateContainerClientCoordsCache()};!function(e,t){for(;null!=e;)t(e),e=e.parentNode}(e.container,(function(t){e.registerBinding(t,"transitionend",m),e.registerBinding(t,"animationend",m),e.registerBinding(t,"scroll",m)})),e.registerBinding(e.container,"contextmenu",(function(e){e.preventDefault()}));var b,x,w,E=function(t){for(var n=e.findContainerClientCoords(),r=n[0],i=n[1],a=n[2],o=n[3],s=t.touches?t.touches:[t],l=!1,u=0;u<s.length;u++){var c=s[u];if(r<=c.clientX&&c.clientX<=r+a&&i<=c.clientY&&c.clientY<=i+o){l=!0;break}}if(!l)return!1;for(var h=e.container,d=t.target.parentNode,p=!1;d;){if(d===h){p=!0;break}d=d.parentNode}return!!p};e.registerBinding(e.container,"mousedown",(function(t){if(E(t)){t.preventDefault(),g(),e.hoverData.capture=!0,e.hoverData.which=t.which;var n=e.cy,i=[t.clientX,t.clientY],a=e.projectIntoViewport(i[0],i[1]),o=e.selection,l=e.findNearestElements(a[0],a[1],!0,!1),u=l[0],d=e.dragData.possibleDragElements;e.hoverData.mdownPos=a,e.hoverData.mdownGPos=i;if(3==t.which){e.hoverData.cxtStarted=!0;var p={originalEvent:t,type:"cxttapstart",position:{x:a[0],y:a[1]}};u?(u.activate(),u.emit(p),e.hoverData.down=u):n.emit(p),e.hoverData.downTime=(new Date).getTime(),e.hoverData.cxtDragged=!1}else if(1==t.which){if(u&&u.activate(),null!=u&&e.nodeIsGrabbable(u)){var f=function(e){return{originalEvent:t,type:e,position:{x:a[0],y:a[1]}}};if(s(u),u.selected()){d=e.dragData.possibleDragElements=n.collection();var v=n.$((function(t){return t.isNode()&&t.selected()&&e.nodeIsGrabbable(t)}));c(v,{addToList:d}),u.emit(f("grabon")),v.forEach((function(e){e.emit(f("grab"))}))}else d=e.dragData.possibleDragElements=n.collection(),h(u,{addToList:d}),u.emit(f("grabon")).emit(f("grab"));e.redrawHint("eles",!0),e.redrawHint("drag",!0)}e.hoverData.down=u,e.hoverData.downs=l,e.hoverData.downTime=(new Date).getTime(),r(u,["mousedown","tapstart","vmousedown"],t,{x:a[0],y:a[1]}),null==u?(o[4]=1,e.data.bgActivePosistion={x:a[0],y:a[1]},e.redrawHint("select",!0),e.redraw()):u.pannable()&&(o[4]=1),e.hoverData.tapholdCancelled=!1,clearTimeout(e.hoverData.tapholdTimeout),e.hoverData.tapholdTimeout=setTimeout((function(){if(!e.hoverData.tapholdCancelled){var r=e.hoverData.down;r?r.emit({originalEvent:t,type:"taphold",position:{x:a[0],y:a[1]}}):n.emit({originalEvent:t,type:"taphold",position:{x:a[0],y:a[1]}})}}),e.tapholdDuration)}o[0]=o[2]=a[0],o[1]=o[3]=a[1]}}),!1),e.registerBinding(t,"mousemove",(function(t){if(e.hoverData.capture||E(t)){var n=!1,o=e.cy,s=o.zoom(),l=[t.clientX,t.clientY],u=e.projectIntoViewport(l[0],l[1]),h=e.hoverData.mdownPos,p=e.hoverData.mdownGPos,g=e.selection,f=null;e.hoverData.draggingEles||e.hoverData.dragging||e.hoverData.selecting||(f=e.findNearestElement(u[0],u[1],!0,!1));var v,y=e.hoverData.last,m=e.hoverData.down,b=[u[0]-g[2],u[1]-g[3]],x=e.dragData.possibleDragElements;if(p){var w=l[0]-p[0],_=w*w,T=l[1]-p[1],D=_+T*T;e.hoverData.isOverThresholdDrag=v=D>=e.desktopTapThreshold2}var C=i(t);v&&(e.hoverData.tapholdCancelled=!0);n=!0,r(f,["mousemove","vmousemove","tapdrag"],t,{x:u[0],y:u[1]});var N=function(){e.data.bgActivePosistion=void 0,e.hoverData.selecting||o.emit({originalEvent:t,type:"boxstart",position:{x:u[0],y:u[1]}}),g[4]=1,e.hoverData.selecting=!0,e.redrawHint("select",!0),e.redraw()};if(3===e.hoverData.which){if(v){var A={originalEvent:t,type:"cxtdrag",position:{x:u[0],y:u[1]}};m?m.emit(A):o.emit(A),e.hoverData.cxtDragged=!0,e.hoverData.cxtOver&&f===e.hoverData.cxtOver||(e.hoverData.cxtOver&&e.hoverData.cxtOver.emit({originalEvent:t,type:"cxtdragout",position:{x:u[0],y:u[1]}}),e.hoverData.cxtOver=f,f&&f.emit({originalEvent:t,type:"cxtdragover",position:{x:u[0],y:u[1]}}))}}else if(e.hoverData.dragging){if(n=!0,o.panningEnabled()&&o.userPanningEnabled()){var L;if(e.hoverData.justStartedPan){var k=e.hoverData.mdownPos;L={x:(u[0]-k[0])*s,y:(u[1]-k[1])*s},e.hoverData.justStartedPan=!1}else L={x:b[0]*s,y:b[1]*s};o.panBy(L),o.emit("dragpan"),e.hoverData.dragged=!0}u=e.projectIntoViewport(t.clientX,t.clientY)}else if(1!=g[4]||null!=m&&!m.pannable()){if(m&&m.pannable()&&m.active()&&m.unactivate(),m&&m.grabbed()||f==y||(y&&r(y,["mouseout","tapdragout"],t,{x:u[0],y:u[1]}),f&&r(f,["mouseover","tapdragover"],t,{x:u[0],y:u[1]}),e.hoverData.last=f),m)if(v){if(o.boxSelectionEnabled()&&C)m&&m.grabbed()&&(d(x),m.emit("freeon"),x.emit("free"),e.dragData.didDrag&&(m.emit("dragfreeon"),x.emit("dragfree"))),N();else if(m&&m.grabbed()&&e.nodeIsDraggable(m)){var S=!e.dragData.didDrag;S&&e.redrawHint("eles",!0),e.dragData.didDrag=!0,e.hoverData.draggingEles||c(x,{inDragLayer:!0});var M={x:0,y:0};if(I(b[0])&&I(b[1])&&(M.x+=b[0],M.y+=b[1],S)){var O=e.hoverData.dragDelta;O&&I(O[0])&&I(O[1])&&(M.x+=O[0],M.y+=O[1])}e.hoverData.draggingEles=!0,x.silentShift(M).emit("position drag"),e.redrawHint("drag",!0),e.redraw()}}else!function(){var t=e.hoverData.dragDelta=e.hoverData.dragDelta||[];0===t.length?(t.push(b[0]),t.push(b[1])):(t[0]+=b[0],t[1]+=b[1])}();n=!0}else if(v){if(e.hoverData.dragging||!o.boxSelectionEnabled()||!C&&o.panningEnabled()&&o.userPanningEnabled()){if(!e.hoverData.selecting&&o.panningEnabled()&&o.userPanningEnabled()){a(m,e.hoverData.downs)&&(e.hoverData.dragging=!0,e.hoverData.justStartedPan=!0,g[4]=0,e.data.bgActivePosistion=at(h),e.redrawHint("select",!0),e.redraw())}}else N();m&&m.pannable()&&m.active()&&m.unactivate()}return g[2]=u[0],g[3]=u[1],n?(t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),!1):void 0}}),!1),e.registerBinding(t,"mouseup",(function(t){if(e.hoverData.capture){e.hoverData.capture=!1;var a=e.cy,o=e.projectIntoViewport(t.clientX,t.clientY),s=e.selection,l=e.findNearestElement(o[0],o[1],!0,!1),u=e.dragData.possibleDragElements,c=e.hoverData.down,h=i(t);if(e.data.bgActivePosistion&&(e.redrawHint("select",!0),e.redraw()),e.hoverData.tapholdCancelled=!0,e.data.bgActivePosistion=void 0,c&&c.unactivate(),3===e.hoverData.which){var p={originalEvent:t,type:"cxttapend",position:{x:o[0],y:o[1]}};if(c?c.emit(p):a.emit(p),!e.hoverData.cxtDragged){var g={originalEvent:t,type:"cxttap",position:{x:o[0],y:o[1]}};c?c.emit(g):a.emit(g)}e.hoverData.cxtDragged=!1,e.hoverData.which=null}else if(1===e.hoverData.which){if(r(l,["mouseup","tapend","vmouseup"],t,{x:o[0],y:o[1]}),e.dragData.didDrag||e.hoverData.dragged||e.hoverData.selecting||e.hoverData.isOverThresholdDrag||(r(c,["click","tap","vclick"],t,{x:o[0],y:o[1]}),x=!1,t.timeStamp-w<=a.multiClickDebounceTime()?(b&&clearTimeout(b),x=!0,w=null,r(c,["dblclick","dbltap","vdblclick"],t,{x:o[0],y:o[1]})):(b=setTimeout((function(){x||r(c,["oneclick","onetap","voneclick"],t,{x:o[0],y:o[1]})}),a.multiClickDebounceTime()),w=t.timeStamp)),null!=c||e.dragData.didDrag||e.hoverData.selecting||e.hoverData.dragged||i(t)||(a.$(n).unselect(["tapunselect"]),u.length>0&&e.redrawHint("eles",!0),e.dragData.possibleDragElements=u=a.collection()),l!=c||e.dragData.didDrag||e.hoverData.selecting||null!=l&&l._private.selectable&&(e.hoverData.dragging||("additive"===a.selectionType()||h?l.selected()?l.unselect(["tapunselect"]):l.select(["tapselect"]):h||(a.$(n).unmerge(l).unselect(["tapunselect"]),l.select(["tapselect"]))),e.redrawHint("eles",!0)),e.hoverData.selecting){var f=a.collection(e.getAllInBox(s[0],s[1],s[2],s[3]));e.redrawHint("select",!0),f.length>0&&e.redrawHint("eles",!0),a.emit({type:"boxend",originalEvent:t,position:{x:o[0],y:o[1]}});var v=function(e){return e.selectable()&&!e.selected()};"additive"===a.selectionType()||h||a.$(n).unmerge(f).unselect(),f.emit("box").stdFilter(v).select().emit("boxselect"),e.redraw()}if(e.hoverData.dragging&&(e.hoverData.dragging=!1,e.redrawHint("select",!0),e.redrawHint("eles",!0),e.redraw()),!s[4]){e.redrawHint("drag",!0),e.redrawHint("eles",!0);var y=c&&c.grabbed();d(u),y&&(c.emit("freeon"),u.emit("free"),e.dragData.didDrag&&(c.emit("dragfreeon"),u.emit("dragfree")))}}s[4]=0,e.hoverData.down=null,e.hoverData.cxtStarted=!1,e.hoverData.draggingEles=!1,e.hoverData.selecting=!1,e.hoverData.isOverThresholdDrag=!1,e.dragData.didDrag=!1,e.hoverData.dragged=!1,e.hoverData.dragDelta=[],e.hoverData.mdownPos=null,e.hoverData.mdownGPos=null}}),!1);var _,T,D,C,N,A,L,k,S,M,O,P,R,B=function(t){if(!e.scrollingPage){var n=e.cy,r=n.zoom(),i=n.pan(),a=e.projectIntoViewport(t.clientX,t.clientY),o=[a[0]*r+i.x,a[1]*r+i.y];if(e.hoverData.draggingEles||e.hoverData.dragging||e.hoverData.cxtStarted||0!==e.selection[4])t.preventDefault();else if(n.panningEnabled()&&n.userPanningEnabled()&&n.zoomingEnabled()&&n.userZoomingEnabled()){var s;t.preventDefault(),e.data.wheelZooming=!0,clearTimeout(e.data.wheelTimeout),e.data.wheelTimeout=setTimeout((function(){e.data.wheelZooming=!1,e.redrawHint("eles",!0),e.redraw()}),150),s=null!=t.deltaY?t.deltaY/-250:null!=t.wheelDeltaY?t.wheelDeltaY/1e3:t.wheelDelta/1e3,s*=e.wheelSensitivity,1===t.deltaMode&&(s*=33);var l=n.zoom()*Math.pow(10,s);"gesturechange"===t.type&&(l=e.gestureStartZoom*t.scale),n.zoom({level:l,renderedPosition:{x:o[0],y:o[1]}}),n.emit("gesturechange"===t.type?"pinchzoom":"scrollzoom")}}};e.registerBinding(e.container,"wheel",B,!0),e.registerBinding(t,"scroll",(function(t){e.scrollingPage=!0,clearTimeout(e.scrollingPageTimeout),e.scrollingPageTimeout=setTimeout((function(){e.scrollingPage=!1}),250)}),!0),e.registerBinding(e.container,"gesturestart",(function(t){e.gestureStartZoom=e.cy.zoom(),e.hasTouchStarted||t.preventDefault()}),!0),e.registerBinding(e.container,"gesturechange",(function(t){e.hasTouchStarted||B(t)}),!0),e.registerBinding(e.container,"mouseout",(function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseout",position:{x:n[0],y:n[1]}})}),!1),e.registerBinding(e.container,"mouseover",(function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseover",position:{x:n[0],y:n[1]}})}),!1);var F,z,G,Y,X,V,U,j=function(e,t,n,r){return Math.sqrt((n-e)*(n-e)+(r-t)*(r-t))},q=function(e,t,n,r){return(n-e)*(n-e)+(r-t)*(r-t)};if(e.registerBinding(e.container,"touchstart",F=function(t){if(e.hasTouchStarted=!0,E(t)){g(),e.touchData.capture=!0,e.data.bgActivePosistion=void 0;var n=e.cy,i=e.touchData.now,a=e.touchData.earlier;if(t.touches[0]){var o=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);i[0]=o[0],i[1]=o[1]}if(t.touches[1]){o=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);i[2]=o[0],i[3]=o[1]}if(t.touches[2]){o=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);i[4]=o[0],i[5]=o[1]}if(t.touches[1]){e.touchData.singleTouchMoved=!0,d(e.dragData.touchDragEles);var l=e.findContainerClientCoords();S=l[0],M=l[1],O=l[2],P=l[3],_=t.touches[0].clientX-S,T=t.touches[0].clientY-M,D=t.touches[1].clientX-S,C=t.touches[1].clientY-M,R=0<=_&&_<=O&&0<=D&&D<=O&&0<=T&&T<=P&&0<=C&&C<=P;var u=n.pan(),p=n.zoom();N=j(_,T,D,C),A=q(_,T,D,C),k=[((L=[(_+D)/2,(T+C)/2])[0]-u.x)/p,(L[1]-u.y)/p];if(A<4e4&&!t.touches[2]){var f=e.findNearestElement(i[0],i[1],!0,!0),v=e.findNearestElement(i[2],i[3],!0,!0);return f&&f.isNode()?(f.activate().emit({originalEvent:t,type:"cxttapstart",position:{x:i[0],y:i[1]}}),e.touchData.start=f):v&&v.isNode()?(v.activate().emit({originalEvent:t,type:"cxttapstart",position:{x:i[0],y:i[1]}}),e.touchData.start=v):n.emit({originalEvent:t,type:"cxttapstart",position:{x:i[0],y:i[1]}}),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!0,e.touchData.cxtDragged=!1,e.data.bgActivePosistion=void 0,void e.redraw()}}if(t.touches[2])n.boxSelectionEnabled()&&t.preventDefault();else if(t.touches[1]);else if(t.touches[0]){var y=e.findNearestElements(i[0],i[1],!0,!0),m=y[0];if(null!=m&&(m.activate(),e.touchData.start=m,e.touchData.starts=y,e.nodeIsGrabbable(m))){var b=e.dragData.touchDragEles=n.collection(),x=null;e.redrawHint("eles",!0),e.redrawHint("drag",!0),m.selected()?(x=n.$((function(t){return t.selected()&&e.nodeIsGrabbable(t)})),c(x,{addToList:b})):h(m,{addToList:b}),s(m);var w=function(e){return{originalEvent:t,type:e,position:{x:i[0],y:i[1]}}};m.emit(w("grabon")),x?x.forEach((function(e){e.emit(w("grab"))})):m.emit(w("grab"))}r(m,["touchstart","tapstart","vmousedown"],t,{x:i[0],y:i[1]}),null==m&&(e.data.bgActivePosistion={x:o[0],y:o[1]},e.redrawHint("select",!0),e.redraw()),e.touchData.singleTouchMoved=!1,e.touchData.singleTouchStartTime=+new Date,clearTimeout(e.touchData.tapholdTimeout),e.touchData.tapholdTimeout=setTimeout((function(){!1!==e.touchData.singleTouchMoved||e.pinching||e.touchData.selecting||r(e.touchData.start,["taphold"],t,{x:i[0],y:i[1]})}),e.tapholdDuration)}if(t.touches.length>=1){for(var I=e.touchData.startPosition=[null,null,null,null,null,null],B=0;B<i.length;B++)I[B]=a[B]=i[B];var F=t.touches[0];e.touchData.startGPosition=[F.clientX,F.clientY]}}},!1),e.registerBinding(window,"touchmove",z=function(t){var n=e.touchData.capture;if(n||E(t)){var i=e.selection,o=e.cy,s=e.touchData.now,l=e.touchData.earlier,u=o.zoom();if(t.touches[0]){var h=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);s[0]=h[0],s[1]=h[1]}if(t.touches[1]){h=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);s[2]=h[0],s[3]=h[1]}if(t.touches[2]){h=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);s[4]=h[0],s[5]=h[1]}var p,g=e.touchData.startGPosition;if(n&&t.touches[0]&&g){for(var f=[],v=0;v<s.length;v++)f[v]=s[v]-l[v];var y=t.touches[0].clientX-g[0],m=y*y,b=t.touches[0].clientY-g[1];p=m+b*b>=e.touchTapThreshold2}if(n&&e.touchData.cxt){t.preventDefault();var x=t.touches[0].clientX-S,w=t.touches[0].clientY-M,L=t.touches[1].clientX-S,O=t.touches[1].clientY-M,P=q(x,w,L,O);if(P/A>=2.25||P>=22500){e.touchData.cxt=!1,e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var B={originalEvent:t,type:"cxttapend",position:{x:s[0],y:s[1]}};e.touchData.start?(e.touchData.start.unactivate().emit(B),e.touchData.start=null):o.emit(B)}}if(n&&e.touchData.cxt){B={originalEvent:t,type:"cxtdrag",position:{x:s[0],y:s[1]}};e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.touchData.start?e.touchData.start.emit(B):o.emit(B),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxtDragged=!0;var F=e.findNearestElement(s[0],s[1],!0,!0);e.touchData.cxtOver&&F===e.touchData.cxtOver||(e.touchData.cxtOver&&e.touchData.cxtOver.emit({originalEvent:t,type:"cxtdragout",position:{x:s[0],y:s[1]}}),e.touchData.cxtOver=F,F&&F.emit({originalEvent:t,type:"cxtdragover",position:{x:s[0],y:s[1]}}))}else if(n&&t.touches[2]&&o.boxSelectionEnabled())t.preventDefault(),e.data.bgActivePosistion=void 0,this.lastThreeTouch=+new Date,e.touchData.selecting||o.emit({originalEvent:t,type:"boxstart",position:{x:s[0],y:s[1]}}),e.touchData.selecting=!0,e.touchData.didSelect=!0,i[4]=1,i&&0!==i.length&&void 0!==i[0]?(i[2]=(s[0]+s[2]+s[4])/3,i[3]=(s[1]+s[3]+s[5])/3):(i[0]=(s[0]+s[2]+s[4])/3,i[1]=(s[1]+s[3]+s[5])/3,i[2]=(s[0]+s[2]+s[4])/3+1,i[3]=(s[1]+s[3]+s[5])/3+1),e.redrawHint("select",!0),e.redraw();else if(n&&t.touches[1]&&!e.touchData.didSelect&&o.zoomingEnabled()&&o.panningEnabled()&&o.userZoomingEnabled()&&o.userPanningEnabled()){if(t.preventDefault(),e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),ee=e.dragData.touchDragEles){e.redrawHint("drag",!0);for(var z=0;z<ee.length;z++){var G=ee[z]._private;G.grabbed=!1,G.rscratch.inDragLayer=!1}}var Y=e.touchData.start,X=(x=t.touches[0].clientX-S,w=t.touches[0].clientY-M,L=t.touches[1].clientX-S,O=t.touches[1].clientY-M,j(x,w,L,O)),V=X/N;if(R){var U=(x-_+(L-D))/2,H=(w-T+(O-C))/2,W=o.zoom(),$=W*V,K=o.pan(),Z=k[0]*W+K.x,Q=k[1]*W+K.y,J={x:-$/W*(Z-K.x-U)+Z,y:-$/W*(Q-K.y-H)+Q};if(Y&&Y.active()){var ee=e.dragData.touchDragEles;d(ee),e.redrawHint("drag",!0),e.redrawHint("eles",!0),Y.unactivate().emit("freeon"),ee.emit("free"),e.dragData.didDrag&&(Y.emit("dragfreeon"),ee.emit("dragfree"))}o.viewport({zoom:$,pan:J,cancelOnFailedZoom:!0}),o.emit("pinchzoom"),N=X,_=x,T=w,D=L,C=O,e.pinching=!0}if(t.touches[0]){h=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);s[0]=h[0],s[1]=h[1]}if(t.touches[1]){h=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);s[2]=h[0],s[3]=h[1]}if(t.touches[2]){h=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);s[4]=h[0],s[5]=h[1]}}else if(t.touches[0]&&!e.touchData.didSelect){var te=e.touchData.start,ne=e.touchData.last;if(e.hoverData.draggingEles||e.swipePanning||(F=e.findNearestElement(s[0],s[1],!0,!0)),n&&null!=te&&t.preventDefault(),n&&null!=te&&e.nodeIsDraggable(te))if(p){ee=e.dragData.touchDragEles;var re=!e.dragData.didDrag;re&&c(ee,{inDragLayer:!0}),e.dragData.didDrag=!0;var ie={x:0,y:0};if(I(f[0])&&I(f[1]))if(ie.x+=f[0],ie.y+=f[1],re)e.redrawHint("eles",!0),(ae=e.touchData.dragDelta)&&I(ae[0])&&I(ae[1])&&(ie.x+=ae[0],ie.y+=ae[1]);e.hoverData.draggingEles=!0,ee.silentShift(ie).emit("position drag"),e.redrawHint("drag",!0),e.touchData.startPosition[0]==l[0]&&e.touchData.startPosition[1]==l[1]&&e.redrawHint("eles",!0),e.redraw()}else{var ae;0===(ae=e.touchData.dragDelta=e.touchData.dragDelta||[]).length?(ae.push(f[0]),ae.push(f[1])):(ae[0]+=f[0],ae[1]+=f[1])}if(r(te||F,["touchmove","tapdrag","vmousemove"],t,{x:s[0],y:s[1]}),te&&te.grabbed()||F==ne||(ne&&ne.emit({originalEvent:t,type:"tapdragout",position:{x:s[0],y:s[1]}}),F&&F.emit({originalEvent:t,type:"tapdragover",position:{x:s[0],y:s[1]}})),e.touchData.last=F,n)for(z=0;z<s.length;z++)s[z]&&e.touchData.startPosition[z]&&p&&(e.touchData.singleTouchMoved=!0);if(n&&(null==te||te.pannable())&&o.panningEnabled()&&o.userPanningEnabled()){a(te,e.touchData.starts)&&(t.preventDefault(),e.data.bgActivePosistion||(e.data.bgActivePosistion=at(e.touchData.startPosition)),e.swipePanning?(o.panBy({x:f[0]*u,y:f[1]*u}),o.emit("dragpan")):p&&(e.swipePanning=!0,o.panBy({x:y*u,y:b*u}),o.emit("dragpan"),te&&(te.unactivate(),e.redrawHint("select",!0),e.touchData.start=null)));h=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);s[0]=h[0],s[1]=h[1]}}for(v=0;v<s.length;v++)l[v]=s[v];n&&t.touches.length>0&&!e.hoverData.draggingEles&&!e.swipePanning&&null!=e.data.bgActivePosistion&&(e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.redraw())}},!1),e.registerBinding(t,"touchcancel",G=function(t){var n=e.touchData.start;e.touchData.capture=!1,n&&n.unactivate()}),e.registerBinding(t,"touchend",Y=function(t){var i=e.touchData.start;if(e.touchData.capture){0===t.touches.length&&(e.touchData.capture=!1),t.preventDefault();var a=e.selection;e.swipePanning=!1,e.hoverData.draggingEles=!1;var o,s=e.cy,l=s.zoom(),u=e.touchData.now,c=e.touchData.earlier;if(t.touches[0]){var h=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);u[0]=h[0],u[1]=h[1]}if(t.touches[1]){h=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);u[2]=h[0],u[3]=h[1]}if(t.touches[2]){h=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);u[4]=h[0],u[5]=h[1]}if(i&&i.unactivate(),e.touchData.cxt){if(o={originalEvent:t,type:"cxttapend",position:{x:u[0],y:u[1]}},i?i.emit(o):s.emit(o),!e.touchData.cxtDragged){var p={originalEvent:t,type:"cxttap",position:{x:u[0],y:u[1]}};i?i.emit(p):s.emit(p)}return e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!1,e.touchData.start=null,void e.redraw()}if(!t.touches[2]&&s.boxSelectionEnabled()&&e.touchData.selecting){e.touchData.selecting=!1;var g=s.collection(e.getAllInBox(a[0],a[1],a[2],a[3]));a[0]=void 0,a[1]=void 0,a[2]=void 0,a[3]=void 0,a[4]=0,e.redrawHint("select",!0),s.emit({type:"boxend",originalEvent:t,position:{x:u[0],y:u[1]}});g.emit("box").stdFilter((function(e){return e.selectable()&&!e.selected()})).select().emit("boxselect"),g.nonempty()&&e.redrawHint("eles",!0),e.redraw()}if(null!=i&&i.unactivate(),t.touches[2])e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);else if(t.touches[1]);else if(t.touches[0]);else if(!t.touches[0]){e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var f=e.dragData.touchDragEles;if(null!=i){var v=i._private.grabbed;d(f),e.redrawHint("drag",!0),e.redrawHint("eles",!0),v&&(i.emit("freeon"),f.emit("free"),e.dragData.didDrag&&(i.emit("dragfreeon"),f.emit("dragfree"))),r(i,["touchend","tapend","vmouseup","tapdragout"],t,{x:u[0],y:u[1]}),i.unactivate(),e.touchData.start=null}else{var y=e.findNearestElement(u[0],u[1],!0,!0);r(y,["touchend","tapend","vmouseup","tapdragout"],t,{x:u[0],y:u[1]})}var m=e.touchData.startPosition[0]-u[0],b=m*m,x=e.touchData.startPosition[1]-u[1],w=(b+x*x)*l*l;e.touchData.singleTouchMoved||(i||s.$(":selected").unselect(["tapunselect"]),r(i,["tap","vclick"],t,{x:u[0],y:u[1]}),X=!1,t.timeStamp-U<=s.multiClickDebounceTime()?(V&&clearTimeout(V),X=!0,U=null,r(i,["dbltap","vdblclick"],t,{x:u[0],y:u[1]})):(V=setTimeout((function(){X||r(i,["onetap","voneclick"],t,{x:u[0],y:u[1]})}),s.multiClickDebounceTime()),U=t.timeStamp)),null!=i&&!e.dragData.didDrag&&i._private.selectable&&w<e.touchTapThreshold2&&!e.pinching&&("single"===s.selectionType()?(s.$(n).unmerge(i).unselect(["tapunselect"]),i.select(["tapselect"])):i.selected()?i.unselect(["tapunselect"]):i.select(["tapselect"]),e.redrawHint("eles",!0)),e.touchData.singleTouchMoved=!0}for(var E=0;E<u.length;E++)c[E]=u[E];e.dragData.didDrag=!1,0===t.touches.length&&(e.touchData.dragDelta=[],e.touchData.startPosition=[null,null,null,null,null,null],e.touchData.startGPosition=null,e.touchData.didSelect=!1),t.touches.length<2&&(1===t.touches.length&&(e.touchData.startGPosition=[t.touches[0].clientX,t.touches[0].clientY]),e.pinching=!1,e.redrawHint("eles",!0),e.redraw())}},!1),"undefined"==typeof TouchEvent){var H=[],W=function(e){return{clientX:e.clientX,clientY:e.clientY,force:1,identifier:e.pointerId,pageX:e.pageX,pageY:e.pageY,radiusX:e.width/2,radiusY:e.height/2,screenX:e.screenX,screenY:e.screenY,target:e.target}},$=function(e){H.push(function(e){return{event:e,touch:W(e)}}(e))},K=function(e){for(var t=0;t<H.length;t++){if(H[t].event.pointerId===e.pointerId)return void H.splice(t,1)}},Z=function(e){e.touches=H.map((function(e){return e.touch}))},Q=function(e){return"mouse"===e.pointerType||4===e.pointerType};e.registerBinding(e.container,"pointerdown",(function(e){Q(e)||(e.preventDefault(),$(e),Z(e),F(e))})),e.registerBinding(e.container,"pointerup",(function(e){Q(e)||(K(e),Z(e),Y(e))})),e.registerBinding(e.container,"pointercancel",(function(e){Q(e)||(K(e),Z(e),G())})),e.registerBinding(e.container,"pointermove",(function(e){Q(e)||(e.preventDefault(),function(e){var t=H.filter((function(t){return t.event.pointerId===e.pointerId}))[0];t.event=e,t.touch=W(e)}(e),Z(e),z(e))}))}};var bs={generatePolygon:function(e,t){return this.nodeShapes[e]={renderer:this,name:e,points:t,draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl("polygon",e,t,n,r,i,this.points)},intersectLine:function(e,t,n,r,i,a,o){return Bt(i,a,this.points,e,t,n/2,r/2,o)},checkPoint:function(e,t,n,r,i,a,o){return kt(e,t,this.points,a,o,r,i,[0,-1],n)}}}};bs.generateEllipse=function(){return this.nodeShapes.ellipse={renderer:this,name:"ellipse",draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},intersectLine:function(e,t,n,r,i,a,o){return function(e,t,n,r,i,a){var o=n-e,s=r-t;o/=i,s/=a;var l=Math.sqrt(o*o+s*s),u=l-1;if(u<0)return[];var c=u/l;return[(n-e)*c+e,(r-t)*c+t]}(i,a,e,t,n/2+o,r/2+o)},checkPoint:function(e,t,n,r,i,a,o){return Mt(e,t,r,i,a,o,n)}}},bs.generateRoundPolygon=function(e,t){for(var n=new Array(2*t.length),r=0;r<t.length/2;r++){var i=2*r,a=void 0;a=r<t.length/2-1?2*(r+1):0,n[4*r]=t[i],n[4*r+1]=t[i+1];var o=t[a]-t[i],s=t[a+1]-t[i+1],l=Math.sqrt(o*o+s*s);n[4*r+2]=o/l,n[4*r+3]=s/l}return this.nodeShapes[e]={renderer:this,name:e,points:n,draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl("round-polygon",e,t,n,r,i,this.points)},intersectLine:function(e,t,n,r,i,a,o){return function(e,t,n,r,i,a,o,s){for(var l,u=[],c=new Array(n.length),h=a/2,d=o/2,p=Vt(a,o),g=0;g<n.length/4;g++){var f,v=void 0;v=0===g?n.length-2:4*g-2,f=4*g+2;var y=r+h*n[4*g],m=i+d*n[4*g+1],b=-n[v]*n[f]-n[v+1]*n[f+1],x=p/Math.tan(Math.acos(b)/2),w=y-x*n[v],E=m-x*n[v+1],_=y+x*n[f],T=m+x*n[f+1];0===g?(c[n.length-2]=w,c[n.length-1]=E):(c[4*g-2]=w,c[4*g-1]=E),c[4*g]=_,c[4*g+1]=T;var D=n[v+1],C=-n[v];D*n[f]+C*n[f+1]<0&&(D*=-1,C*=-1),0!==(l=Ot(e,t,r,i,w+D*p,E+C*p,p)).length&&u.push(l[0],l[1])}for(var N=0;N<c.length/4;N++)0!==(l=Rt(e,t,r,i,c[4*N],c[4*N+1],c[4*N+2],c[4*N+3],!1)).length&&u.push(l[0],l[1]);if(u.length>2){for(var A=[u[0],u[1]],L=Math.pow(A[0]-e,2)+Math.pow(A[1]-t,2),k=1;k<u.length/2;k++){var S=Math.pow(u[2*k]-e,2)+Math.pow(u[2*k+1]-t,2);S<=L&&(A[0]=u[2*k],A[1]=u[2*k+1],L=S)}return A}return u}(i,a,this.points,e,t,n,r)},checkPoint:function(e,t,n,r,i,a,o){return function(e,t,n,r,i,a,o){for(var s=new Array(n.length),l=a/2,u=o/2,c=Vt(a,o),h=c*c,d=0;d<n.length/4;d++){var p,g=void 0;g=0===d?n.length-2:4*d-2,p=4*d+2;var f=r+l*n[4*d],v=i+u*n[4*d+1],y=-n[g]*n[p]-n[g+1]*n[p+1],m=c/Math.tan(Math.acos(y)/2),b=f-m*n[g],x=v-m*n[g+1],w=f+m*n[p],E=v+m*n[p+1];s[4*d]=b,s[4*d+1]=x,s[4*d+2]=w,s[4*d+3]=E;var _=n[g+1],T=-n[g];_*n[p]+T*n[p+1]<0&&(_*=-1,T*=-1);var D=b+_*c,C=x+T*c;if(Math.pow(D-e,2)+Math.pow(C-t,2)<=h)return!0}return Lt(e,t,s)}(e,t,this.points,a,o,r,i)}}},bs.generateRoundRectangle=function(){return this.nodeShapes["round-rectangle"]=this.nodeShapes.roundrectangle={renderer:this,name:"round-rectangle",points:zt(4,0),draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},intersectLine:function(e,t,n,r,i,a,o){return Tt(i,a,e,t,n,r,o)},checkPoint:function(e,t,n,r,i,a,o){var s=Xt(r,i),l=2*s;return!!kt(e,t,this.points,a,o,r,i-l,[0,-1],n)||(!!kt(e,t,this.points,a,o,r-l,i,[0,-1],n)||(!!Mt(e,t,l,l,a-r/2+s,o-i/2+s,n)||(!!Mt(e,t,l,l,a+r/2-s,o-i/2+s,n)||(!!Mt(e,t,l,l,a+r/2-s,o+i/2-s,n)||!!Mt(e,t,l,l,a-r/2+s,o+i/2-s,n)))))}}},bs.generateCutRectangle=function(){return this.nodeShapes["cut-rectangle"]=this.nodeShapes.cutrectangle={renderer:this,name:"cut-rectangle",cornerLength:8,points:zt(4,0),draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},generateCutTrianglePts:function(e,t,n,r){var i=this.cornerLength,a=t/2,o=e/2,s=n-o,l=n+o,u=r-a,c=r+a;return{topLeft:[s,u+i,s+i,u,s+i,u+i],topRight:[l-i,u,l,u+i,l-i,u+i],bottomRight:[l,c-i,l-i,c,l-i,c-i],bottomLeft:[s+i,c,s,c-i,s+i,c-i]}},intersectLine:function(e,t,n,r,i,a,o){var s=this.generateCutTrianglePts(n+2*o,r+2*o,e,t),l=[].concat.apply([],[s.topLeft.splice(0,4),s.topRight.splice(0,4),s.bottomRight.splice(0,4),s.bottomLeft.splice(0,4)]);return Bt(i,a,l,e,t)},checkPoint:function(e,t,n,r,i,a,o){if(kt(e,t,this.points,a,o,r,i-2*this.cornerLength,[0,-1],n))return!0;if(kt(e,t,this.points,a,o,r-2*this.cornerLength,i,[0,-1],n))return!0;var s=this.generateCutTrianglePts(r,i,a,o);return Lt(e,t,s.topLeft)||Lt(e,t,s.topRight)||Lt(e,t,s.bottomRight)||Lt(e,t,s.bottomLeft)}}},bs.generateBarrel=function(){return this.nodeShapes.barrel={renderer:this,name:"barrel",points:zt(4,0),draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},intersectLine:function(e,t,n,r,i,a,o){var s=this.generateBarrelBezierPts(n+2*o,r+2*o,e,t),l=function(e){var t=pt({x:e[0],y:e[1]},{x:e[2],y:e[3]},{x:e[4],y:e[5]},.15),n=pt({x:e[0],y:e[1]},{x:e[2],y:e[3]},{x:e[4],y:e[5]},.5),r=pt({x:e[0],y:e[1]},{x:e[2],y:e[3]},{x:e[4],y:e[5]},.85);return[e[0],e[1],t.x,t.y,n.x,n.y,r.x,r.y,e[4],e[5]]},u=[].concat(l(s.topLeft),l(s.topRight),l(s.bottomRight),l(s.bottomLeft));return Bt(i,a,u,e,t)},generateBarrelBezierPts:function(e,t,n,r){var i=t/2,a=e/2,o=n-a,s=n+a,l=r-i,u=r+i,c=Ut(e,t),h=c.heightOffset,d=c.widthOffset,p=c.ctrlPtOffsetPct*e,g={topLeft:[o,l+h,o+p,l,o+d,l],topRight:[s-d,l,s-p,l,s,l+h],bottomRight:[s,u-h,s-p,u,s-d,u],bottomLeft:[o+d,u,o+p,u,o,u-h]};return g.topLeft.isTop=!0,g.topRight.isTop=!0,g.bottomLeft.isBottom=!0,g.bottomRight.isBottom=!0,g},checkPoint:function(e,t,n,r,i,a,o){var s=Ut(r,i),l=s.heightOffset,u=s.widthOffset;if(kt(e,t,this.points,a,o,r,i-2*l,[0,-1],n))return!0;if(kt(e,t,this.points,a,o,r-2*u,i,[0,-1],n))return!0;for(var c=this.generateBarrelBezierPts(r,i,a,o),h=function(e,t,n){var r,i,a=n[4],o=n[2],s=n[0],l=n[5],u=n[1],c=Math.min(a,s),h=Math.max(a,s),d=Math.min(l,u),p=Math.max(l,u);if(c<=e&&e<=h&&d<=t&&t<=p){var g=[(r=a)-2*(i=o)+s,2*(i-r),r],f=function(e,t,n,r){var i=t*t-4*e*(n-=r);if(i<0)return[];var a=Math.sqrt(i),o=2*e;return[(-t+a)/o,(-t-a)/o]}(g[0],g[1],g[2],e).filter((function(e){return 0<=e&&e<=1}));if(f.length>0)return f[0]}return null},d=Object.keys(c),p=0;p<d.length;p++){var g=c[d[p]],f=h(e,t,g);if(null!=f){var v=g[5],y=g[3],m=g[1],b=dt(v,y,m,f);if(g.isTop&&b<=t)return!0;if(g.isBottom&&t<=b)return!0}}return!1}}},bs.generateBottomRoundrectangle=function(){return this.nodeShapes["bottom-round-rectangle"]=this.nodeShapes.bottomroundrectangle={renderer:this,name:"bottom-round-rectangle",points:zt(4,0),draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},intersectLine:function(e,t,n,r,i,a,o){var s=t-(r/2+o),l=Rt(i,a,e,t,e-(n/2+o),s,e+(n/2+o),s,!1);return l.length>0?l:Tt(i,a,e,t,n,r,o)},checkPoint:function(e,t,n,r,i,a,o){var s=Xt(r,i),l=2*s;if(kt(e,t,this.points,a,o,r,i-l,[0,-1],n))return!0;if(kt(e,t,this.points,a,o,r-l,i,[0,-1],n))return!0;var u=r/2+2*n,c=i/2+2*n;return!!Lt(e,t,[a-u,o-c,a-u,o,a+u,o,a+u,o-c])||(!!Mt(e,t,l,l,a+r/2-s,o+i/2-s,n)||!!Mt(e,t,l,l,a-r/2+s,o+i/2-s,n))}}},bs.registerNodeShapes=function(){var e=this.nodeShapes={},t=this;this.generateEllipse(),this.generatePolygon("triangle",zt(3,0)),this.generateRoundPolygon("round-triangle",zt(3,0)),this.generatePolygon("rectangle",zt(4,0)),e.square=e.rectangle,this.generateRoundRectangle(),this.generateCutRectangle(),this.generateBarrel(),this.generateBottomRoundrectangle();var n=[0,1,1,0,0,-1,-1,0];this.generatePolygon("diamond",n),this.generateRoundPolygon("round-diamond",n),this.generatePolygon("pentagon",zt(5,0)),this.generateRoundPolygon("round-pentagon",zt(5,0)),this.generatePolygon("hexagon",zt(6,0)),this.generateRoundPolygon("round-hexagon",zt(6,0)),this.generatePolygon("heptagon",zt(7,0)),this.generateRoundPolygon("round-heptagon",zt(7,0)),this.generatePolygon("octagon",zt(8,0)),this.generateRoundPolygon("round-octagon",zt(8,0));var r=new Array(20),i=Yt(5,0),a=Yt(5,Math.PI/5),o=.5*(3-Math.sqrt(5));o*=1.57;for(var s=0;s<a.length/2;s++)a[2*s]*=o,a[2*s+1]*=o;for(s=0;s<5;s++)r[4*s]=i[2*s],r[4*s+1]=i[2*s+1],r[4*s+2]=a[2*s],r[4*s+3]=a[2*s+1];r=Gt(r),this.generatePolygon("star",r),this.generatePolygon("vee",[-1,-1,0,-.333,1,-1,0,1]),this.generatePolygon("rhomboid",[-1,-1,.333,-1,1,1,-.333,1]),this.generatePolygon("right-rhomboid",[-.333,-1,1,-1,.333,1,-1,1]),this.nodeShapes.concavehexagon=this.generatePolygon("concave-hexagon",[-1,-.95,-.75,0,-1,.95,1,.95,.75,0,1,-.95]);var l=[-1,-1,.25,-1,1,0,.25,1,-1,1];this.generatePolygon("tag",l),this.generateRoundPolygon("round-tag",l),e.makePolygon=function(e){var n,r="polygon-"+e.join("$");return(n=this[r])?n:t.generatePolygon(r,e)}};var xs={timeToRender:function(){return this.redrawTotalTime/this.redrawCount},redraw:function(e){e=e||Ie();var t=this;void 0===t.averageRedrawTime&&(t.averageRedrawTime=0),void 0===t.lastRedrawTime&&(t.lastRedrawTime=0),void 0===t.lastDrawTime&&(t.lastDrawTime=0),t.requestedFrame=!0,t.renderOptions=e},beforeRender:function(e,t){if(!this.destroyed){null==t&&Ce("Priority is not optional for beforeRender");var n=this.beforeRenderCallbacks;n.push({fn:e,priority:t}),n.sort((function(e,t){return t.priority-e.priority}))}}},ws=function(e,t,n){for(var r=e.beforeRenderCallbacks,i=0;i<r.length;i++)r[i].fn(t,n)};xs.startRenderLoop=function(){var e=this,t=e.cy;if(!e.renderLoopStarted){e.renderLoopStarted=!0;oe((function n(r){if(!e.destroyed){if(t.batching());else if(e.requestedFrame&&!e.skipFrame){ws(e,!0,r);var i=se();e.render(e.renderOptions);var a=e.lastDrawTime=se();void 0===e.averageRedrawTime&&(e.averageRedrawTime=a-i),void 0===e.redrawCount&&(e.redrawCount=0),e.redrawCount++,void 0===e.redrawTotalTime&&(e.redrawTotalTime=0);var o=a-i;e.redrawTotalTime+=o,e.lastRedrawTime=o,e.averageRedrawTime=e.averageRedrawTime/2+o/2,e.requestedFrame=!1}else ws(e,!1,r);e.skipFrame=!1,oe(n)}}))}};var Es=function(e){this.init(e)},_s=Es.prototype;_s.clientFunctions=["redrawHint","render","renderTo","matchCanvasSize","nodeShapeImpl","arrowShapeImpl"],_s.init=function(e){var t=this;t.options=e,t.cy=e.cy;var n=t.container=e.cy.container(),r=t.cy.window();if(r){var i=r.document,a=i.head,o="__________cytoscape_stylesheet",s="__________cytoscape_container",l=null!=i.getElementById(o);if(n.className.indexOf(s)<0&&(n.className=(n.className||"")+" "+s),!l){var u=i.createElement("style");u.id=o,u.textContent="."+s+" { position: relative; }",a.insertBefore(u,a.children[0])}"static"===r.getComputedStyle(n).getPropertyValue("position")&&Ae("A Cytoscape container has style position:static and so can not use UI extensions properly")}t.selection=[void 0,void 0,void 0,void 0,0],t.bezierProjPcts=[.05,.225,.4,.5,.6,.775,.95],t.hoverData={down:null,last:null,downTime:null,triggerMode:null,dragging:!1,initialPan:[null,null],capture:!1},t.dragData={possibleDragElements:[]},t.touchData={start:null,capture:!1,startPosition:[null,null,null,null,null,null],singleTouchStartTime:null,singleTouchMoved:!0,now:[null,null,null,null,null,null],earlier:[null,null,null,null,null,null]},t.redraws=0,t.showFps=e.showFps,t.debug=e.debug,t.hideEdgesOnViewport=e.hideEdgesOnViewport,t.textureOnViewport=e.textureOnViewport,t.wheelSensitivity=e.wheelSensitivity,t.motionBlurEnabled=e.motionBlur,t.forcedPixelRatio=I(e.pixelRatio)?e.pixelRatio:null,t.motionBlur=e.motionBlur,t.motionBlurOpacity=e.motionBlurOpacity,t.motionBlurTransparency=1-t.motionBlurOpacity,t.motionBlurPxRatio=1,t.mbPxRBlurry=1,t.minMbLowQualFrames=4,t.fullQualityMb=!1,t.clearedForMotionBlur=[],t.desktopTapThreshold=e.desktopTapThreshold,t.desktopTapThreshold2=e.desktopTapThreshold*e.desktopTapThreshold,t.touchTapThreshold=e.touchTapThreshold,t.touchTapThreshold2=e.touchTapThreshold*e.touchTapThreshold,t.tapholdDuration=500,t.bindings=[],t.beforeRenderCallbacks=[],t.beforeRenderPriorities={animations:400,eleCalcs:300,eleTxrDeq:200,lyrTxrDeq:150,lyrTxrSkip:100},t.registerNodeShapes(),t.registerArrowShapes(),t.registerCalculationListeners()},_s.notify=function(e,t){var n=this,r=n.cy;this.destroyed||("init"!==e?"destroy"!==e?(("add"===e||"remove"===e||"move"===e&&r.hasCompoundNodes()||"load"===e||"zorder"===e||"mount"===e)&&n.invalidateCachedZSortedEles(),"viewport"===e&&n.redrawHint("select",!0),"load"!==e&&"resize"!==e&&"mount"!==e||(n.invalidateContainerClientCoordsCache(),n.matchCanvasSize(n.container)),n.redrawHint("eles",!0),n.redrawHint("drag",!0),this.startRenderLoop(),this.redraw()):n.destroy():n.load())},_s.destroy=function(){var e=this;e.destroyed=!0,e.cy.stopAnimationLoop();for(var t=0;t<e.bindings.length;t++){var n=e.bindings[t],r=n.target;(r.off||r.removeEventListener).apply(r,n.args)}if(e.bindings=[],e.beforeRenderCallbacks=[],e.onUpdateEleCalcsFns=[],e.removeObserver&&e.removeObserver.disconnect(),e.styleObserver&&e.styleObserver.disconnect(),e.resizeObserver&&e.resizeObserver.disconnect(),e.labelCalcDiv)try{document.body.removeChild(e.labelCalcDiv)}catch(i){}},_s.isHeadless=function(){return!1},[ts,vs,ys,ms,bs,xs].forEach((function(e){Q(_s,e)}));var Ts=1e3/60,Ds=function(e){return function(){var t=this,n=this.renderer;if(!t.dequeueingSetup){t.dequeueingSetup=!0;var r=u.default((function(){n.redrawHint("eles",!0),n.redrawHint("drag",!0),n.redraw()}),e.deqRedrawThreshold),i=e.priority||De;n.beforeRender((function(i,a){var o=se(),s=n.averageRedrawTime,l=n.lastRedrawTime,u=[],c=n.cy.extent(),h=n.getPixelRatio();for(i||n.flushRenderedStyleQueue();;){var d=se(),p=d-o,g=d-a;if(l<Ts){var f=Ts-(i?s:0);if(g>=e.deqFastCost*f)break}else if(i){if(p>=e.deqCost*l||p>=e.deqAvgCost*s)break}else if(g>=e.deqNoDrawCost*Ts)break;var v=e.deq(t,h,c);if(!(v.length>0))break;for(var y=0;y<v.length;y++)u.push(v[y])}u.length>0&&(e.onDeqd(t,u),!i&&e.shouldRedraw(t,u,h,c)&&r())}),i(t))}}},Cs=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:_e;f(this,e),this.idsByKey=new Fe,this.keyForId=new Fe,this.cachesByLvl=new Fe,this.lvls=[],this.getKey=t,this.doesEleInvalidateKey=n}return y(e,[{key:"getIdsFor",value:function(e){null==e&&Ce("Can not get id list for null key");var t=this.idsByKey,n=this.idsByKey.get(e);return n||(n=new Ge,t.set(e,n)),n}},{key:"addIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).add(t)}},{key:"deleteIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).delete(t)}},{key:"getNumberOfIdsForKey",value:function(e){return null==e?0:this.getIdsFor(e).size}},{key:"updateKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t),r=this.getKey(e);this.deleteIdForKey(n,t),this.addIdForKey(r,t),this.keyForId.set(t,r)}},{key:"deleteKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteIdForKey(n,t),this.keyForId.delete(t)}},{key:"keyHasChangedFor",value:function(e){var t=e.id();return this.keyForId.get(t)!==this.getKey(e)}},{key:"isInvalid",value:function(e){return this.keyHasChangedFor(e)||this.doesEleInvalidateKey(e)}},{key:"getCachesAt",value:function(e){var t=this.cachesByLvl,n=this.lvls,r=t.get(e);return r||(r=new Fe,t.set(e,r),n.push(e)),r}},{key:"getCache",value:function(e,t){return this.getCachesAt(t).get(e)}},{key:"get",value:function(e,t){var n=this.getKey(e),r=this.getCache(n,t);return null!=r&&this.updateKeyMappingFor(e),r}},{key:"getForCachedKey",value:function(e,t){var n=this.keyForId.get(e.id());return this.getCache(n,t)}},{key:"hasCache",value:function(e,t){return this.getCachesAt(t).has(e)}},{key:"has",value:function(e,t){var n=this.getKey(e);return this.hasCache(n,t)}},{key:"setCache",value:function(e,t,n){n.key=e,this.getCachesAt(t).set(e,n)}},{key:"set",value:function(e,t,n){var r=this.getKey(e);this.setCache(r,t,n),this.updateKeyMappingFor(e)}},{key:"deleteCache",value:function(e,t){this.getCachesAt(t).delete(e)}},{key:"delete",value:function(e,t){var n=this.getKey(e);this.deleteCache(n,t)}},{key:"invalidateKey",value:function(e){var t=this;this.lvls.forEach((function(n){return t.deleteCache(e,n)}))}},{key:"invalidate",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteKeyMappingFor(e);var r=this.doesEleInvalidateKey(e);return r&&this.invalidateKey(n),r||0===this.getNumberOfIdsForKey(n)}}]),e}(),Ns={dequeue:"dequeue",downscale:"downscale",highQuality:"highQuality"},As=Me({getKey:null,doesEleInvalidateKey:_e,drawElement:null,getBoundingBox:null,getRotationPoint:null,getRotationOffset:null,isVisible:Ee,allowEdgeTxrCaching:!0,allowParentTxrCaching:!0}),Ls=function(e,t){var n=this;n.renderer=e,n.onDequeues=[];var r=As(t);Q(n,r),n.lookup=new Cs(r.getKey,r.doesEleInvalidateKey),n.setupDequeueing()},ks=Ls.prototype;ks.reasons=Ns,ks.getTextureQueue=function(e){var t=this;return t.eleImgCaches=t.eleImgCaches||{},t.eleImgCaches[e]=t.eleImgCaches[e]||[]},ks.getRetiredTextureQueue=function(e){var t=this.eleImgCaches.retired=this.eleImgCaches.retired||{};return t[e]=t[e]||[]},ks.getElementQueue=function(){return this.eleCacheQueue=this.eleCacheQueue||new c.default((function(e,t){return t.reqs-e.reqs}))},ks.getElementKeyToQueue=function(){return this.eleKeyToCacheQueue=this.eleKeyToCacheQueue||{}},ks.getElement=function(e,t,n,r,i){var a=this,o=this.renderer,s=o.cy.zoom(),l=this.lookup;if(!t||0===t.w||0===t.h||isNaN(t.w)||isNaN(t.h)||!e.visible()||e.removed())return null;if(!a.allowEdgeTxrCaching&&e.isEdge()||!a.allowParentTxrCaching&&e.isParent())return null;if(null==r&&(r=Math.ceil(st(s*n))),r<-4)r=-4;else if(s>=7.99||r>3)return null;var u=Math.pow(2,r),c=t.h*u,h=t.w*u,d=o.eleTextBiggerThanMin(e,u);if(!this.isVisible(e,d))return null;var p,g=l.get(e,r);if(g&&g.invalidated&&(g.invalidated=!1,g.texture.invalidatedWidth-=g.width),g)return g;if(p=c<=25?25:c<=50?50:50*Math.ceil(c/50),c>1024||h>1024)return null;var f=a.getTextureQueue(p),v=f[f.length-2],y=function(){return a.recycleTexture(p,h)||a.addTexture(p,h)};v||(v=f[f.length-1]),v||(v=y()),v.width-v.usedWidth<h&&(v=y());for(var m,b=function(e){return e&&e.scaledLabelShown===d},x=i&&i===Ns.dequeue,w=i&&i===Ns.highQuality,E=i&&i===Ns.downscale,_=r+1;_<=3;_++){var T=l.get(e,_);if(T){m=T;break}}var D=m&&m.level===r+1?m:null,C=function(){v.context.drawImage(D.texture.canvas,D.x,0,D.width,D.height,v.usedWidth,0,h,c)};if(v.context.setTransform(1,0,0,1,0,0),v.context.clearRect(v.usedWidth,0,h,p),b(D))C();else if(b(m)){if(!w)return a.queueElement(e,m.level-1),m;for(var N=m.level;N>r;N--)D=a.getElement(e,t,n,N,Ns.downscale);C()}else{var A;if(!x&&!w&&!E)for(var L=r-1;L>=-4;L--){var k=l.get(e,L);if(k){A=k;break}}if(b(A))return a.queueElement(e,r),A;v.context.translate(v.usedWidth,0),v.context.scale(u,u),this.drawElement(v.context,e,t,d,!1),v.context.scale(1/u,1/u),v.context.translate(-v.usedWidth,0)}return g={x:v.usedWidth,texture:v,level:r,scale:u,width:h,height:c,scaledLabelShown:d},v.usedWidth+=Math.ceil(h+8),v.eleCaches.push(g),l.set(e,r,g),a.checkTextureFullness(v),g},ks.invalidateElements=function(e){for(var t=0;t<e.length;t++)this.invalidateElement(e[t])},ks.invalidateElement=function(e){var t=this,n=t.lookup,r=[];if(n.isInvalid(e)){for(var i=-4;i<=3;i++){var a=n.getForCachedKey(e,i);a&&r.push(a)}if(n.invalidate(e))for(var o=0;o<r.length;o++){var s=r[o],l=s.texture;l.invalidatedWidth+=s.width,s.invalidated=!0,t.checkTextureUtility(l)}t.removeFromQueue(e)}},ks.checkTextureUtility=function(e){e.invalidatedWidth>=.2*e.width&&this.retireTexture(e)},ks.checkTextureFullness=function(e){var t=this.getTextureQueue(e.height);e.usedWidth/e.width>.8&&e.fullnessChecks>=10?Oe(t,e):e.fullnessChecks++},ks.retireTexture=function(e){var t=e.height,n=this.getTextureQueue(t),r=this.lookup;Oe(n,e),e.retired=!0;for(var i=e.eleCaches,a=0;a<i.length;a++){var o=i[a];r.deleteCache(o.key,o.level)}Pe(i),this.getRetiredTextureQueue(t).push(e)},ks.addTexture=function(e,t){var n={};return this.getTextureQueue(e).push(n),n.eleCaches=[],n.height=e,n.width=Math.max(1024,t),n.usedWidth=0,n.invalidatedWidth=0,n.fullnessChecks=0,n.canvas=this.renderer.makeOffscreenCanvas(n.width,n.height),n.context=n.canvas.getContext("2d"),n},ks.recycleTexture=function(e,t){for(var n=this.getTextureQueue(e),r=this.getRetiredTextureQueue(e),i=0;i<r.length;i++){var a=r[i];if(a.width>=t)return a.retired=!1,a.usedWidth=0,a.invalidatedWidth=0,a.fullnessChecks=0,Pe(a.eleCaches),a.context.setTransform(1,0,0,1,0,0),a.context.clearRect(0,0,a.width,a.height),Oe(r,a),n.push(a),a}},ks.queueElement=function(e,t){var n=this.getElementQueue(),r=this.getElementKeyToQueue(),i=this.getKey(e),a=r[i];if(a)a.level=Math.max(a.level,t),a.eles.merge(e),a.reqs++,n.updateItem(a);else{var o={eles:e.spawn().merge(e),level:t,reqs:1,key:i};n.push(o),r[i]=o}},ks.dequeue=function(e){for(var t=this,n=t.getElementQueue(),r=t.getElementKeyToQueue(),i=[],a=t.lookup,o=0;o<1&&n.size()>0;o++){var s=n.pop(),l=s.key,u=s.eles[0],c=a.hasCache(u,s.level);if(r[l]=null,!c){i.push(s);var h=t.getBoundingBox(u);t.getElement(u,h,e,s.level,Ns.dequeue)}}return i},ks.removeFromQueue=function(e){var t=this.getElementQueue(),n=this.getElementKeyToQueue(),r=this.getKey(e),i=n[r];null!=i&&(1===i.eles.length?(i.reqs=we,t.updateItem(i),t.pop(),n[r]=null):i.eles.unmerge(e))},ks.onDequeue=function(e){this.onDequeues.push(e)},ks.offDequeue=function(e){Oe(this.onDequeues,e)},ks.setupDequeueing=Ds({deqRedrawThreshold:100,deqCost:.15,deqAvgCost:.1,deqNoDrawCost:.9,deqFastCost:.9,deq:function(e,t,n){return e.dequeue(t,n)},onDeqd:function(e,t){for(var n=0;n<e.onDequeues.length;n++){(0,e.onDequeues[n])(t)}},shouldRedraw:function(e,t,n,r){for(var i=0;i<t.length;i++)for(var a=t[i].eles,o=0;o<a.length;o++){var s=a[o].boundingBox();if(wt(s,r))return!0}return!1},priority:function(e){return e.renderer.beforeRenderPriorities.eleTxrDeq}});var Ss=function(e){var t=this,n=t.renderer=e,r=n.cy;t.layersByLevel={},t.firstGet=!0,t.lastInvalidationTime=se()-500,t.skipping=!1,t.eleTxrDeqs=r.collection(),t.scheduleElementRefinement=u.default((function(){t.refineElementTextures(t.eleTxrDeqs),t.eleTxrDeqs.unmerge(t.eleTxrDeqs)}),50),n.beforeRender((function(e,n){n-t.lastInvalidationTime<=250?t.skipping=!0:t.skipping=!1}),n.beforeRenderPriorities.lyrTxrSkip);t.layersQueue=new c.default((function(e,t){return t.reqs-e.reqs})),t.setupDequeueing()},Is=Ss.prototype,Ms=0,Os=Math.pow(2,53)-1;Is.makeLayer=function(e,t){var n=Math.pow(2,t),r=Math.ceil(e.w*n),i=Math.ceil(e.h*n),a=this.renderer.makeOffscreenCanvas(r,i),o={id:Ms=++Ms%Os,bb:e,level:t,width:r,height:i,canvas:a,context:a.getContext("2d"),eles:[],elesQueue:[],reqs:0},s=o.context,l=-o.bb.x1,u=-o.bb.y1;return s.scale(n,n),s.translate(l,u),o},Is.getLayers=function(e,t,n){var r=this,i=r.renderer.cy.zoom(),a=r.firstGet;if(r.firstGet=!1,null==n)if((n=Math.ceil(st(i*t)))<-4)n=-4;else if(i>=3.99||n>2)return null;r.validateLayersElesOrdering(n,e);var o,s,l=r.layersByLevel,u=Math.pow(2,n),c=l[n]=l[n]||[];if(r.levelIsComplete(n,e))return c;!function(){var t=function(t){if(r.validateLayersElesOrdering(t,e),r.levelIsComplete(t,e))return s=l[t],!0},i=function(e){if(!s)for(var r=n+e;-4<=r&&r<=2&&!t(r);r+=e);};i(1),i(-1);for(var a=c.length-1;a>=0;a--){var o=c[a];o.invalid&&Oe(c,o)}}();var h=function(t){var i=(t=t||{}).after;if(function(){if(!o){o=ft();for(var t=0;t<e.length;t++)vt(o,e[t].boundingBox())}}(),o.w*u*(o.h*u)>16e6)return null;var a=r.makeLayer(o,n);if(null!=i){var s=c.indexOf(i)+1;c.splice(s,0,a)}else(void 0===t.insert||t.insert)&&c.unshift(a);return a};if(r.skipping&&!a)return null;for(var d=null,p=e.length/1,g=!a,f=0;f<e.length;f++){var v=e[f],y=v._private.rscratch,m=y.imgLayerCaches=y.imgLayerCaches||{},b=m[n];if(b)d=b;else{if((!d||d.eles.length>=p||!_t(d.bb,v.boundingBox()))&&!(d=h({insert:!0,after:d})))return null;s||g?r.queueLayer(d,v):r.drawEleInLayer(d,v,n,t),d.eles.push(v),m[n]=d}}return s||(g?null:c)},Is.getEleLevelForLayerLevel=function(e,t){return e},Is.drawEleInLayer=function(e,t,n,r){var i=this.renderer,a=e.context,o=t.boundingBox();0!==o.w&&0!==o.h&&t.visible()&&(n=this.getEleLevelForLayerLevel(n,r),i.setImgSmoothing(a,!1),i.drawCachedElement(a,t,null,null,n,true),i.setImgSmoothing(a,!0))},Is.levelIsComplete=function(e,t){var n=this.layersByLevel[e];if(!n||0===n.length)return!1;for(var r=0,i=0;i<n.length;i++){var a=n[i];if(a.reqs>0)return!1;if(a.invalid)return!1;r+=a.eles.length}return r===t.length},Is.validateLayersElesOrdering=function(e,t){var n=this.layersByLevel[e];if(n)for(var r=0;r<n.length;r++){for(var i=n[r],a=-1,o=0;o<t.length;o++)if(i.eles[0]===t[o]){a=o;break}if(a<0)this.invalidateLayer(i);else{var s=a;for(o=0;o<i.eles.length;o++)if(i.eles[o]!==t[s+o]){this.invalidateLayer(i);break}}}},Is.updateElementsInLayers=function(e,t){for(var n=P(e[0]),r=0;r<e.length;r++)for(var i=n?null:e[r],a=n?e[r]:e[r].ele,o=a._private.rscratch,s=o.imgLayerCaches=o.imgLayerCaches||{},l=-4;l<=2;l++){var u=s[l];u&&(i&&this.getEleLevelForLayerLevel(u.level)!==i.level||t(u,a,i))}},Is.haveLayers=function(){for(var e=!1,t=-4;t<=2;t++){var n=this.layersByLevel[t];if(n&&n.length>0){e=!0;break}}return e},Is.invalidateElements=function(e){var t=this;0!==e.length&&(t.lastInvalidationTime=se(),0!==e.length&&t.haveLayers()&&t.updateElementsInLayers(e,(function(e,n,r){t.invalidateLayer(e)})))},Is.invalidateLayer=function(e){if(this.lastInvalidationTime=se(),!e.invalid){var t=e.level,n=e.eles,r=this.layersByLevel[t];Oe(r,e),e.elesQueue=[],e.invalid=!0,e.replacement&&(e.replacement.invalid=!0);for(var i=0;i<n.length;i++){var a=n[i]._private.rscratch.imgLayerCaches;a&&(a[t]=null)}}},Is.refineElementTextures=function(e){var t=this;t.updateElementsInLayers(e,(function(e,n,r){var i=e.replacement;if(i||((i=e.replacement=t.makeLayer(e.bb,e.level)).replaces=e,i.eles=e.eles),!i.reqs)for(var a=0;a<i.eles.length;a++)t.queueLayer(i,i.eles[a])}))},Is.enqueueElementRefinement=function(e){this.eleTxrDeqs.merge(e),this.scheduleElementRefinement()},Is.queueLayer=function(e,t){var n=this.layersQueue,r=e.elesQueue,i=r.hasId=r.hasId||{};if(!e.replacement){if(t){if(i[t.id()])return;r.push(t),i[t.id()]=!0}e.reqs?(e.reqs++,n.updateItem(e)):(e.reqs=1,n.push(e))}},Is.dequeue=function(e){for(var t=this,n=t.layersQueue,r=[],i=0;i<1&&0!==n.size();){var a=n.peek();if(a.replacement)n.pop();else if(a.replaces&&a!==a.replaces.replacement)n.pop();else if(a.invalid)n.pop();else{var o=a.elesQueue.shift();o&&(t.drawEleInLayer(a,o,a.level,e),i++),0===r.length&&r.push(!0),0===a.elesQueue.length&&(n.pop(),a.reqs=0,a.replaces&&t.applyLayerReplacement(a),t.requestRedraw())}}return r},Is.applyLayerReplacement=function(e){var t=this.layersByLevel[e.level],n=e.replaces,r=t.indexOf(n);if(!(r<0||n.invalid)){t[r]=e;for(var i=0;i<e.eles.length;i++){var a=e.eles[i]._private,o=a.imgLayerCaches=a.imgLayerCaches||{};o&&(o[e.level]=e)}this.requestRedraw()}},Is.requestRedraw=u.default((function(){var e=this.renderer;e.redrawHint("eles",!0),e.redrawHint("drag",!0),e.redraw()}),100),Is.setupDequeueing=Ds({deqRedrawThreshold:50,deqCost:.15,deqAvgCost:.1,deqNoDrawCost:.9,deqFastCost:.9,deq:function(e,t){return e.dequeue(t)},onDeqd:De,shouldRedraw:Ee,priority:function(e){return e.renderer.beforeRenderPriorities.lyrTxrDeq}});var Ps,Rs={};function Bs(e,t){for(var n=0;n<t.length;n++){var r=t[n];e.lineTo(r.x,r.y)}}function Fs(e,t,n){for(var r,i=0;i<t.length;i++){var a=t[i];0===i&&(r=a),e.lineTo(a.x,a.y)}e.quadraticCurveTo(n.x,n.y,r.x,r.y)}function zs(e,t,n){e.beginPath&&e.beginPath();for(var r=t,i=0;i<r.length;i++){var a=r[i];e.lineTo(a.x,a.y)}var o=n,s=n[0];e.moveTo(s.x,s.y);for(i=1;i<o.length;i++){a=o[i];e.lineTo(a.x,a.y)}e.closePath&&e.closePath()}function Gs(e,t,n,r,i){e.beginPath&&e.beginPath(),e.arc(n,r,i,0,2*Math.PI,!1);var a=t,o=a[0];e.moveTo(o.x,o.y);for(var s=0;s<a.length;s++){var l=a[s];e.lineTo(l.x,l.y)}e.closePath&&e.closePath()}function Ys(e,t,n,r){e.arc(t,n,r,0,2*Math.PI,!1)}Rs.arrowShapeImpl=function(e){return(Ps||(Ps={polygon:Bs,"triangle-backcurve":Fs,"triangle-tee":zs,"circle-triangle":Gs,"triangle-cross":zs,circle:Ys}))[e]};var Xs={drawElement:function(e,t,n,r,i,a){t.isNode()?this.drawNode(e,t,n,r,i,a):this.drawEdge(e,t,n,r,i,a)},drawElementOverlay:function(e,t){t.isNode()?this.drawNodeOverlay(e,t):this.drawEdgeOverlay(e,t)},drawElementUnderlay:function(e,t){t.isNode()?this.drawNodeUnderlay(e,t):this.drawEdgeUnderlay(e,t)},drawCachedElementPortion:function(e,t,n,r,i,a,o,s){var l=this,u=n.getBoundingBox(t);if(0!==u.w&&0!==u.h){var c=n.getElement(t,u,r,i,a);if(null!=c){var h=s(l,t);if(0===h)return;var d,p,g,f,v,y,m=o(l,t),b=u.x1,x=u.y1,w=u.w,E=u.h;if(0!==m){var _=n.getRotationPoint(t);g=_.x,f=_.y,e.translate(g,f),e.rotate(m),(v=l.getImgSmoothing(e))||l.setImgSmoothing(e,!0);var T=n.getRotationOffset(t);d=T.x,p=T.y}else d=b,p=x;1!==h&&(y=e.globalAlpha,e.globalAlpha=y*h),e.drawImage(c.texture.canvas,c.x,0,c.width,c.height,d,p,w,E),1!==h&&(e.globalAlpha=y),0!==m&&(e.rotate(-m),e.translate(-g,-f),v||l.setImgSmoothing(e,!1))}else n.drawElement(e,t)}}},Vs=function(){return 0},Us=function(e,t){return e.getTextAngle(t,null)},js=function(e,t){return e.getTextAngle(t,"source")},qs=function(e,t){return e.getTextAngle(t,"target")},Hs=function(e,t){return t.effectiveOpacity()},Ws=function(e,t){return t.pstyle("text-opacity").pfValue*t.effectiveOpacity()};Xs.drawCachedElement=function(e,t,n,r,i,a){var o=this,s=o.data,l=s.eleTxrCache,u=s.lblTxrCache,c=s.slbTxrCache,h=s.tlbTxrCache,d=t.boundingBox(),p=!0===a?l.reasons.highQuality:null;if(0!==d.w&&0!==d.h&&t.visible()&&(!r||wt(d,r))){var g=t.isEdge(),f=t.element()._private.rscratch.badLine;o.drawElementUnderlay(e,t),o.drawCachedElementPortion(e,t,l,n,i,p,Vs,Hs),g&&f||o.drawCachedElementPortion(e,t,u,n,i,p,Us,Ws),g&&!f&&(o.drawCachedElementPortion(e,t,c,n,i,p,js,Ws),o.drawCachedElementPortion(e,t,h,n,i,p,qs,Ws)),o.drawElementOverlay(e,t)}},Xs.drawElements=function(e,t){for(var n=0;n<t.length;n++){var r=t[n];this.drawElement(e,r)}},Xs.drawCachedElements=function(e,t,n,r){for(var i=0;i<t.length;i++){var a=t[i];this.drawCachedElement(e,a,n,r)}},Xs.drawCachedNodes=function(e,t,n,r){for(var i=0;i<t.length;i++){var a=t[i];a.isNode()&&this.drawCachedElement(e,a,n,r)}},Xs.drawLayeredElements=function(e,t,n,r){var i=this.data.lyrTxrCache.getLayers(t,n);if(i)for(var a=0;a<i.length;a++){var o=i[a],s=o.bb;0!==s.w&&0!==s.h&&e.drawImage(o.canvas,s.x1,s.y1,s.w,s.h)}else this.drawCachedElements(e,t,n,r)};var $s={drawEdge:function(e,t,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],i=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],o=this,s=t._private.rscratch;if((!a||t.visible())&&!s.badLine&&null!=s.allpts&&!isNaN(s.allpts[0])){var l;n&&(l=n,e.translate(-l.x1,-l.y1));var u=a?t.pstyle("opacity").value:1,c=a?t.pstyle("line-opacity").value:1,h=t.pstyle("curve-style").value,d=t.pstyle("line-style").value,p=t.pstyle("width").pfValue,g=t.pstyle("line-cap").value,f=u*c,v=u*c,y=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:f;"straight-triangle"===h?(o.eleStrokeStyle(e,t,n),o.drawEdgeTrianglePath(t,e,s.allpts)):(e.lineWidth=p,e.lineCap=g,o.eleStrokeStyle(e,t,n),o.drawEdgePath(t,e,s.allpts,d),e.lineCap="butt")},m=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:v;o.drawArrowheads(e,t,n)};if(e.lineJoin="round","yes"===t.pstyle("ghost").value){var b=t.pstyle("ghost-offset-x").pfValue,x=t.pstyle("ghost-offset-y").pfValue,w=t.pstyle("ghost-opacity").value,E=f*w;e.translate(b,x),y(E),m(E),e.translate(-b,-x)}i&&o.drawEdgeUnderlay(e,t),y(),m(),i&&o.drawEdgeOverlay(e,t),o.drawElementText(e,t,null,r),n&&e.translate(l.x1,l.y1)}}},Ks=function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(t,n){if(n.visible()){var r=n.pstyle("".concat(e,"-opacity")).value;if(0!==r){var i=this,a=i.usePaths(),o=n._private.rscratch,s=2*n.pstyle("".concat(e,"-padding")).pfValue,l=n.pstyle("".concat(e,"-color")).value;t.lineWidth=s,"self"!==o.edgeType||a?t.lineCap="round":t.lineCap="butt",i.colorStrokeStyle(t,l[0],l[1],l[2],r),i.drawEdgePath(n,t,o.allpts,"solid")}}}};$s.drawEdgeOverlay=Ks("overlay"),$s.drawEdgeUnderlay=Ks("underlay"),$s.drawEdgePath=function(e,t,n,r){var i,a=e._private.rscratch,o=t,s=!1,l=this.usePaths(),u=e.pstyle("line-dash-pattern").pfValue,c=e.pstyle("line-dash-offset").pfValue;if(l){var h=n.join("$");a.pathCacheKey&&a.pathCacheKey===h?(i=t=a.pathCache,s=!0):(i=t=new Path2D,a.pathCacheKey=h,a.pathCache=i)}if(o.setLineDash)switch(r){case"dotted":o.setLineDash([1,1]);break;case"dashed":o.setLineDash(u),o.lineDashOffset=c;break;case"solid":o.setLineDash([])}if(!s&&!a.badLine)switch(t.beginPath&&t.beginPath(),t.moveTo(n[0],n[1]),a.edgeType){case"bezier":case"self":case"compound":case"multibezier":for(var d=2;d+3<n.length;d+=4)t.quadraticCurveTo(n[d],n[d+1],n[d+2],n[d+3]);break;case"straight":case"segments":case"haystack":for(var p=2;p+1<n.length;p+=2)t.lineTo(n[p],n[p+1])}t=o,l?t.stroke(i):t.stroke(),t.setLineDash&&t.setLineDash([])},$s.drawEdgeTrianglePath=function(e,t,n){t.fillStyle=t.strokeStyle;for(var r=e.pstyle("width").pfValue,i=0;i+1<n.length;i+=2){var a=[n[i+2]-n[i],n[i+3]-n[i+1]],o=Math.sqrt(a[0]*a[0]+a[1]*a[1]),s=[a[1]/o,-a[0]/o],l=[s[0]*r/2,s[1]*r/2];t.beginPath(),t.moveTo(n[i]-l[0],n[i+1]-l[1]),t.lineTo(n[i]+l[0],n[i+1]+l[1]),t.lineTo(n[i+2],n[i+3]),t.closePath(),t.fill()}},$s.drawArrowheads=function(e,t,n){var r=t._private.rscratch,i="haystack"===r.edgeType;i||this.drawArrowhead(e,t,"source",r.arrowStartX,r.arrowStartY,r.srcArrowAngle,n),this.drawArrowhead(e,t,"mid-target",r.midX,r.midY,r.midtgtArrowAngle,n),this.drawArrowhead(e,t,"mid-source",r.midX,r.midY,r.midsrcArrowAngle,n),i||this.drawArrowhead(e,t,"target",r.arrowEndX,r.arrowEndY,r.tgtArrowAngle,n)},$s.drawArrowhead=function(e,t,n,r,i,a,o){if(!(isNaN(r)||null==r||isNaN(i)||null==i||isNaN(a)||null==a)){var s=this,l=t.pstyle(n+"-arrow-shape").value;if("none"!==l){var u="hollow"===t.pstyle(n+"-arrow-fill").value?"both":"filled",c=t.pstyle(n+"-arrow-fill").value,h=t.pstyle("width").pfValue,d=t.pstyle(n+"-arrow-width"),p="match-line"===d.value?h:d.pfValue;"%"===d.units&&(p*=h);var g=t.pstyle("opacity").value;void 0===o&&(o=g);var f=e.globalCompositeOperation;1===o&&"hollow"!==c||(e.globalCompositeOperation="destination-out",s.colorFillStyle(e,255,255,255,1),s.colorStrokeStyle(e,255,255,255,1),s.drawArrowShape(t,e,u,h,l,p,r,i,a),e.globalCompositeOperation=f);var v=t.pstyle(n+"-arrow-color").value;s.colorFillStyle(e,v[0],v[1],v[2],o),s.colorStrokeStyle(e,v[0],v[1],v[2],o),s.drawArrowShape(t,e,c,h,l,p,r,i,a)}}},$s.drawArrowShape=function(e,t,n,r,i,a,o,s,l){var u,c=this,h=this.usePaths()&&"triangle-cross"!==i,d=!1,p=t,g={x:o,y:s},f=e.pstyle("arrow-scale").value,v=this.getArrowWidth(r,f),y=c.arrowShapes[i];if(h){var m=c.arrowPathCache=c.arrowPathCache||[],b=fe(i),x=m[b];null!=x?(u=t=x,d=!0):(u=t=new Path2D,m[b]=u)}d||(t.beginPath&&t.beginPath(),h?y.draw(t,1,0,{x:0,y:0},1):y.draw(t,v,l,g,r),t.closePath&&t.closePath()),t=p,h&&(t.translate(o,s),t.rotate(l),t.scale(v,v)),"filled"!==n&&"both"!==n||(h?t.fill(u):t.fill()),"hollow"!==n&&"both"!==n||(t.lineWidth=a/(h?v:1),t.lineJoin="miter",h?t.stroke(u):t.stroke()),h&&(t.scale(1/v,1/v),t.rotate(-l),t.translate(-o,-s))};var Zs={safeDrawImage:function(e,t,n,r,i,a,o,s,l,u){if(!(i<=0||a<=0||l<=0||u<=0))try{e.drawImage(t,n,r,i,a,o,s,l,u)}catch(c){Ae(c)}},drawInscribedImage:function(e,t,n,r,i){var a=this,o=n.position(),s=o.x,l=o.y,u=n.cy().style(),c=u.getIndexedStyle.bind(u),h=c(n,"background-fit","value",r),d=c(n,"background-repeat","value",r),p=n.width(),g=n.height(),f=2*n.padding(),v=p+("inner"===c(n,"background-width-relative-to","value",r)?0:f),y=g+("inner"===c(n,"background-height-relative-to","value",r)?0:f),m=n._private.rscratch,b="node"===c(n,"background-clip","value",r),x=c(n,"background-image-opacity","value",r)*i,w=c(n,"background-image-smoothing","value",r),E=t.width||t.cachedW,_=t.height||t.cachedH;null!=E&&null!=_||(document.body.appendChild(t),E=t.cachedW=t.width||t.offsetWidth,_=t.cachedH=t.height||t.offsetHeight,document.body.removeChild(t));var T=E,D=_;if("auto"!==c(n,"background-width","value",r)&&(T="%"===c(n,"background-width","units",r)?c(n,"background-width","pfValue",r)*v:c(n,"background-width","pfValue",r)),"auto"!==c(n,"background-height","value",r)&&(D="%"===c(n,"background-height","units",r)?c(n,"background-height","pfValue",r)*y:c(n,"background-height","pfValue",r)),0!==T&&0!==D){if("contain"===h)T*=C=Math.min(v/T,y/D),D*=C;else if("cover"===h){var C;T*=C=Math.max(v/T,y/D),D*=C}var N=s-v/2,A=c(n,"background-position-x","units",r),L=c(n,"background-position-x","pfValue",r);N+="%"===A?(v-T)*L:L;var k=c(n,"background-offset-x","units",r),S=c(n,"background-offset-x","pfValue",r);N+="%"===k?(v-T)*S:S;var I=l-y/2,M=c(n,"background-position-y","units",r),O=c(n,"background-position-y","pfValue",r);I+="%"===M?(y-D)*O:O;var P=c(n,"background-offset-y","units",r),R=c(n,"background-offset-y","pfValue",r);I+="%"===P?(y-D)*R:R,m.pathCache&&(N-=s,I-=l,s=0,l=0);var B=e.globalAlpha;e.globalAlpha=x;var F=a.getImgSmoothing(e),z=!1;if("no"===w&&F?(a.setImgSmoothing(e,!1),z=!0):"yes"!==w||F||(a.setImgSmoothing(e,!0),z=!0),"no-repeat"===d)b&&(e.save(),m.pathCache?e.clip(m.pathCache):(a.nodeShapes[a.getNodeShape(n)].draw(e,s,l,v,y),e.clip())),a.safeDrawImage(e,t,0,0,E,_,N,I,T,D),b&&e.restore();else{var G=e.createPattern(t,d);e.fillStyle=G,a.nodeShapes[a.getNodeShape(n)].draw(e,s,l,v,y),e.translate(N,I),e.fill(),e.translate(-N,-I)}e.globalAlpha=B,z&&a.setImgSmoothing(e,F)}}},Qs={};function Js(e,t,n,r,i){var a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:5,o=arguments.length>6?arguments[6]:void 0;e.beginPath(),e.moveTo(t+a,n),e.lineTo(t+r-a,n),e.quadraticCurveTo(t+r,n,t+r,n+a),e.lineTo(t+r,n+i-a),e.quadraticCurveTo(t+r,n+i,t+r-a,n+i),e.lineTo(t+a,n+i),e.quadraticCurveTo(t,n+i,t,n+i-a),e.lineTo(t,n+a),e.quadraticCurveTo(t,n,t+a,n),e.closePath(),o?e.stroke():e.fill()}Qs.eleTextBiggerThanMin=function(e,t){if(!t){var n=e.cy().zoom(),r=this.getPixelRatio(),i=Math.ceil(st(n*r));t=Math.pow(2,i)}return!(e.pstyle("font-size").pfValue*t<e.pstyle("min-zoomed-font-size").pfValue)},Qs.drawElementText=function(e,t,n,r,i){var a=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],o=this;if(null==r){if(a&&!o.eleTextBiggerThanMin(t))return}else if(!1===r)return;if(t.isNode()){var s=t.pstyle("label");if(!s||!s.value)return;var l=o.getLabelJustification(t);e.textAlign=l,e.textBaseline="bottom"}else{var u=t.element()._private.rscratch.badLine,c=t.pstyle("label"),h=t.pstyle("source-label"),d=t.pstyle("target-label");if(u||(!c||!c.value)&&(!h||!h.value)&&(!d||!d.value))return;e.textAlign="center",e.textBaseline="bottom"}var p,g=!n;n&&(p=n,e.translate(-p.x1,-p.y1)),null==i?(o.drawText(e,t,null,g,a),t.isEdge()&&(o.drawText(e,t,"source",g,a),o.drawText(e,t,"target",g,a))):o.drawText(e,t,i,g,a),n&&e.translate(p.x1,p.y1)},Qs.getFontCache=function(e){var t;this.fontCaches=this.fontCaches||[];for(var n=0;n<this.fontCaches.length;n++)if((t=this.fontCaches[n]).context===e)return t;return t={context:e},this.fontCaches.push(t),t},Qs.setupTextStyle=function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],r=t.pstyle("font-style").strValue,i=t.pstyle("font-size").pfValue+"px",a=t.pstyle("font-family").strValue,o=t.pstyle("font-weight").strValue,s=n?t.effectiveOpacity()*t.pstyle("text-opacity").value:1,l=t.pstyle("text-outline-opacity").value*s,u=t.pstyle("color").value,c=t.pstyle("text-outline-color").value;e.font=r+" "+o+" "+i+" "+a,e.lineJoin="round",this.colorFillStyle(e,u[0],u[1],u[2],s),this.colorStrokeStyle(e,c[0],c[1],c[2],l)},Qs.getTextAngle=function(e,t){var n=e._private.rscratch,r=t?t+"-":"",i=e.pstyle(r+"text-rotation"),a=Re(n,"labelAngle",t);return"autorotate"===i.strValue?e.isEdge()?a:0:"none"===i.strValue?0:i.pfValue},Qs.drawText=function(e,t,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],i=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=t._private.rscratch,o=i?t.effectiveOpacity():1;if(!i||0!==o&&0!==t.pstyle("text-opacity").value){"main"===n&&(n=null);var s,l,u=Re(a,"labelX",n),c=Re(a,"labelY",n),h=this.getLabelText(t,n);if(null!=h&&""!==h&&!isNaN(u)&&!isNaN(c)){this.setupTextStyle(e,t,i);var d,p=n?n+"-":"",g=Re(a,"labelWidth",n),f=Re(a,"labelHeight",n),v=t.pstyle(p+"text-margin-x").pfValue,y=t.pstyle(p+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle("text-halign").value,x=t.pstyle("text-valign").value;switch(m&&(b="center",x="center"),u+=v,c+=y,0!==(d=r?this.getTextAngle(t,n):0)&&(s=u,l=c,e.translate(s,l),e.rotate(d),u=0,c=0),x){case"top":break;case"center":c+=f/2;break;case"bottom":c+=f}var w=t.pstyle("text-background-opacity").value,E=t.pstyle("text-border-opacity").value,_=t.pstyle("text-border-width").pfValue,T=t.pstyle("text-background-padding").pfValue,D=0===t.pstyle("text-background-shape").strValue.indexOf("round");if(w>0||_>0&&E>0){var C=u-T;switch(b){case"left":C-=g;break;case"center":C-=g/2}var N=c-f-T,A=g+2*T,L=f+2*T;if(w>0){var k=e.fillStyle,S=t.pstyle("text-background-color").value;e.fillStyle="rgba("+S[0]+","+S[1]+","+S[2]+","+w*o+")",D?Js(e,C,N,A,L,2):e.fillRect(C,N,A,L),e.fillStyle=k}if(_>0&&E>0){var I=e.strokeStyle,M=e.lineWidth,O=t.pstyle("text-border-color").value,P=t.pstyle("text-border-style").value;if(e.strokeStyle="rgba("+O[0]+","+O[1]+","+O[2]+","+E*o+")",e.lineWidth=_,e.setLineDash)switch(P){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"double":e.lineWidth=_/4,e.setLineDash([]);break;case"solid":e.setLineDash([])}if(D?Js(e,C,N,A,L,2,"stroke"):e.strokeRect(C,N,A,L),"double"===P){var R=_/2;D?Js(e,C+R,N+R,A-2*R,L-2*R,2,"stroke"):e.strokeRect(C+R,N+R,A-2*R,L-2*R)}e.setLineDash&&e.setLineDash([]),e.lineWidth=M,e.strokeStyle=I}}var B=2*t.pstyle("text-outline-width").pfValue;if(B>0&&(e.lineWidth=B),"wrap"===t.pstyle("text-wrap").value){var F=Re(a,"labelWrapCachedLines",n),z=Re(a,"labelLineHeight",n),G=g/2,Y=this.getLabelJustification(t);switch("auto"===Y||("left"===b?"left"===Y?u+=-g:"center"===Y&&(u+=-G):"center"===b?"left"===Y?u+=-G:"right"===Y&&(u+=G):"right"===b&&("center"===Y?u+=G:"right"===Y&&(u+=g))),x){case"top":case"center":case"bottom":c-=(F.length-1)*z}for(var X=0;X<F.length;X++)B>0&&e.strokeText(F[X],u,c),e.fillText(F[X],u,c),c+=z}else B>0&&e.strokeText(h,u,c),e.fillText(h,u,c);0!==d&&(e.rotate(-d),e.translate(-s,-l))}}};var el={drawNode:function(e,t,n){var r,i,a=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],o=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],s=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],l=this,u=t._private,c=u.rscratch,h=t.position();if(I(h.x)&&I(h.y)&&(!s||t.visible())){var d,p,g=s?t.effectiveOpacity():1,f=l.usePaths(),v=!1,y=t.padding();r=t.width()+2*y,i=t.height()+2*y,n&&(p=n,e.translate(-p.x1,-p.y1));for(var m=t.pstyle("background-image").value,b=new Array(m.length),x=new Array(m.length),w=0,E=0;E<m.length;E++){var _=m[E];if(b[E]=null!=_&&"none"!==_){var T=t.cy().style().getIndexedStyle(t,"background-image-crossorigin","value",E);w++,x[E]=l.getCachedImage(_,T,(function(){u.backgroundTimestamp=Date.now(),t.emitAndNotify("background")}))}}var D=t.pstyle("background-blacken").value,C=t.pstyle("border-width").pfValue,N=t.pstyle("background-opacity").value*g,A=t.pstyle("border-color").value,L=t.pstyle("border-style").value,k=t.pstyle("border-opacity").value*g,S=t.pstyle("outline-width").pfValue,M=t.pstyle("outline-color").value,O=t.pstyle("outline-style").value,P=t.pstyle("outline-opacity").value*g,R=t.pstyle("outline-offset").value;e.lineJoin="miter";var B=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:N;l.eleFillStyle(e,t,n)},F=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:k;l.colorStrokeStyle(e,A[0],A[1],A[2],t)},z=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:P;l.colorStrokeStyle(e,M[0],M[1],M[2],t)},G=function(e,t,n,r){var i,a=l.nodePathCache=l.nodePathCache||[],o=ve("polygon"===n?n+","+r.join(","):n,""+t,""+e),s=a[o],u=!1;return null!=s?(i=s,u=!0,c.pathCache=i):(i=new Path2D,a[o]=c.pathCache=i),{path:i,cacheHit:u}},Y=t.pstyle("shape").strValue,X=t.pstyle("shape-polygon-points").pfValue;if(f){e.translate(h.x,h.y);var V=G(r,i,Y,X);d=V.path,v=V.cacheHit}var U=function(){if(!v){var n=h;f&&(n={x:0,y:0}),l.nodeShapes[l.getNodeShape(t)].draw(d||e,n.x,n.y,r,i)}f?e.fill(d):e.fill()},j=function(){for(var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:g,r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=u.backgrounding,a=0,o=0;o<x.length;o++){var s=t.cy().style().getIndexedStyle(t,"background-image-containment","value",o);r&&"over"===s||!r&&"inside"===s?a++:b[o]&&x[o].complete&&!x[o].error&&(a++,l.drawInscribedImage(e,x[o],t,o,n))}u.backgrounding=!(a===w),i!==u.backgrounding&&t.updateStyle(!1)},q=function(){var n=arguments.length>0&&void 0!==arguments[0]&&arguments[0],a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:g;l.hasPie(t)&&(l.drawPie(e,t,a),n&&(f||l.nodeShapes[l.getNodeShape(t)].draw(e,h.x,h.y,r,i)))},H=function(){var t=(D>0?D:-D)*(arguments.length>0&&void 0!==arguments[0]?arguments[0]:g),n=D>0?0:255;0!==D&&(l.colorFillStyle(e,n,n,n,t),f?e.fill(d):e.fill())},W=function(){if(C>0){if(e.lineWidth=C,e.lineCap="butt",e.setLineDash)switch(L){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"solid":case"double":e.setLineDash([])}if(f?e.stroke(d):e.stroke(),"double"===L){e.lineWidth=C/3;var t=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",f?e.stroke(d):e.stroke(),e.globalCompositeOperation=t}e.setLineDash&&e.setLineDash([])}},$=function(){if(S>0){if(e.lineWidth=S,e.lineCap="butt",e.setLineDash)switch(O){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"solid":case"double":e.setLineDash([])}var n=h;f&&(n={x:0,y:0});var a,o=l.getNodeShape(t),s=(r+C+(S+R))/r,u=(i+C+(S+R))/i,c=r*s,d=i*u,p=l.nodeShapes[o].points;if(f)a=G(c,d,o,p).path;if("ellipse"===o)l.drawEllipsePath(a||e,n.x,n.y,c,d);else if(["round-diamond","round-heptagon","round-hexagon","round-octagon","round-pentagon","round-polygon","round-triangle","round-tag"].includes(o)){var g=0,v=0,y=0;"round-diamond"===o?g=1.4*(C+R+S):"round-heptagon"===o?(g=1.075*(C+R+S),y=-(C/2+R+S)/35):"round-hexagon"===o?g=1.12*(C+R+S):"round-pentagon"===o?(g=1.13*(C+R+S),y=-(C/2+R+S)/15):"round-tag"===o?(g=1.12*(C+R+S),v=.07*(C/2+S+R)):"round-triangle"===o&&(g=(C+R+S)*(Math.PI/2),y=-(C+R/2+S)/Math.PI),0!==g&&(s=(r+g)/r,u=(i+g)/i),l.drawRoundPolygonPath(a||e,n.x+v,n.y+y,r*s,i*u,p)}else if(["roundrectangle","round-rectangle"].includes(o))l.drawRoundRectanglePath(a||e,n.x,n.y,c,d);else if(["cutrectangle","cut-rectangle"].includes(o))l.drawCutRectanglePath(a||e,n.x,n.y,c,d);else if(["bottomroundrectangle","bottom-round-rectangle"].includes(o))l.drawBottomRoundRectanglePath(a||e,n.x,n.y,c,d);else if("barrel"===o)l.drawBarrelPath(a||e,n.x,n.y,c,d);else if(o.startsWith("polygon")||["rhomboid","right-rhomboid","round-tag","tag","vee"].includes(o)){p=St(It(p,(C+S+R)/r)),l.drawPolygonPath(a||e,n.x,n.y,r,i,p)}else{p=St(It(p,-((C+S+R)/r))),l.drawPolygonPath(a||e,n.x,n.y,r,i,p)}if(f?e.stroke(a):e.stroke(),"double"===O){e.lineWidth=C/3;var m=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",f?e.stroke(a):e.stroke(),e.globalCompositeOperation=m}e.setLineDash&&e.setLineDash([])}};if("yes"===t.pstyle("ghost").value){var K=t.pstyle("ghost-offset-x").pfValue,Z=t.pstyle("ghost-offset-y").pfValue,Q=t.pstyle("ghost-opacity").value,J=Q*g;e.translate(K,Z),z(),$(),B(Q*N),U(),j(J,!0),F(Q*k),W(),q(0!==D||0!==C),j(J,!1),H(J),e.translate(-K,-Z)}f&&e.translate(-h.x,-h.y),o&&l.drawNodeUnderlay(e,t,h,r,i),f&&e.translate(h.x,h.y),z(),$(),B(),U(),j(g,!0),F(),W(),q(0!==D||0!==C),j(g,!1),H(),f&&e.translate(-h.x,-h.y),l.drawElementText(e,t,null,a),o&&l.drawNodeOverlay(e,t,h,r,i),n&&e.translate(p.x1,p.y1)}}},tl=function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(t,n,r,i,a){if(n.visible()){var o=n.pstyle("".concat(e,"-padding")).pfValue,s=n.pstyle("".concat(e,"-opacity")).value,l=n.pstyle("".concat(e,"-color")).value,u=n.pstyle("".concat(e,"-shape")).value;if(s>0){if(r=r||n.position(),null==i||null==a){var c=n.padding();i=n.width()+2*c,a=n.height()+2*c}this.colorFillStyle(t,l[0],l[1],l[2],s),this.nodeShapes[u].draw(t,r.x,r.y,i+2*o,a+2*o),t.fill()}}}};el.drawNodeOverlay=tl("overlay"),el.drawNodeUnderlay=tl("underlay"),el.hasPie=function(e){return(e=e[0])._private.hasPie},el.drawPie=function(e,t,n,r){t=t[0],r=r||t.position();var i=t.cy().style(),a=t.pstyle("pie-size"),o=r.x,s=r.y,l=t.width(),u=t.height(),c=Math.min(l,u)/2,h=0;this.usePaths()&&(o=0,s=0),"%"===a.units?c*=a.pfValue:void 0!==a.pfValue&&(c=a.pfValue/2);for(var d=1;d<=i.pieBackgroundN;d++){var p=t.pstyle("pie-"+d+"-background-size").value,g=t.pstyle("pie-"+d+"-background-color").value,f=t.pstyle("pie-"+d+"-background-opacity").value*n,v=p/100;v+h>1&&(v=1-h);var y=1.5*Math.PI+2*Math.PI*h,m=y+2*Math.PI*v;0===p||h>=1||h+v>1||(e.beginPath(),e.moveTo(o,s),e.arc(o,s,c,y,m),e.closePath(),this.colorFillStyle(e,g[0],g[1],g[2],f),e.fill(),h+=v)}};var nl={};nl.getPixelRatio=function(){var e=this.data.contexts[0];if(null!=this.forcedPixelRatio)return this.forcedPixelRatio;var t=e.backingStorePixelRatio||e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1;return(window.devicePixelRatio||1)/t},nl.paintCache=function(e){for(var t,n=this.paintCaches=this.paintCaches||[],r=!0,i=0;i<n.length;i++)if((t=n[i]).context===e){r=!1;break}return r&&(t={context:e},n.push(t)),t},nl.createGradientStyleFor=function(e,t,n,r,i){var a,o=this.usePaths(),s=n.pstyle(t+"-gradient-stop-colors").value,l=n.pstyle(t+"-gradient-stop-positions").pfValue;if("radial-gradient"===r)if(n.isEdge()){var u=n.sourceEndpoint(),c=n.targetEndpoint(),h=n.midpoint(),d=ut(u,h),p=ut(c,h);a=e.createRadialGradient(h.x,h.y,0,h.x,h.y,Math.max(d,p))}else{var g=o?{x:0,y:0}:n.position(),f=n.paddedWidth(),v=n.paddedHeight();a=e.createRadialGradient(g.x,g.y,0,g.x,g.y,Math.max(f,v))}else if(n.isEdge()){var y=n.sourceEndpoint(),m=n.targetEndpoint();a=e.createLinearGradient(y.x,y.y,m.x,m.y)}else{var b=o?{x:0,y:0}:n.position(),x=n.paddedWidth()/2,w=n.paddedHeight()/2;switch(n.pstyle("background-gradient-direction").value){case"to-bottom":a=e.createLinearGradient(b.x,b.y-w,b.x,b.y+w);break;case"to-top":a=e.createLinearGradient(b.x,b.y+w,b.x,b.y-w);break;case"to-left":a=e.createLinearGradient(b.x+x,b.y,b.x-x,b.y);break;case"to-right":a=e.createLinearGradient(b.x-x,b.y,b.x+x,b.y);break;case"to-bottom-right":case"to-right-bottom":a=e.createLinearGradient(b.x-x,b.y-w,b.x+x,b.y+w);break;case"to-top-right":case"to-right-top":a=e.createLinearGradient(b.x-x,b.y+w,b.x+x,b.y-w);break;case"to-bottom-left":case"to-left-bottom":a=e.createLinearGradient(b.x+x,b.y-w,b.x-x,b.y+w);break;case"to-top-left":case"to-left-top":a=e.createLinearGradient(b.x+x,b.y+w,b.x-x,b.y-w)}}if(!a)return null;for(var E=l.length===s.length,_=s.length,T=0;T<_;T++)a.addColorStop(E?l[T]:T/(_-1),"rgba("+s[T][0]+","+s[T][1]+","+s[T][2]+","+i+")");return a},nl.gradientFillStyle=function(e,t,n,r){var i=this.createGradientStyleFor(e,"background",t,n,r);if(!i)return null;e.fillStyle=i},nl.colorFillStyle=function(e,t,n,r,i){e.fillStyle="rgba("+t+","+n+","+r+","+i+")"},nl.eleFillStyle=function(e,t,n){var r=t.pstyle("background-fill").value;if("linear-gradient"===r||"radial-gradient"===r)this.gradientFillStyle(e,t,r,n);else{var i=t.pstyle("background-color").value;this.colorFillStyle(e,i[0],i[1],i[2],n)}},nl.gradientStrokeStyle=function(e,t,n,r){var i=this.createGradientStyleFor(e,"line",t,n,r);if(!i)return null;e.strokeStyle=i},nl.colorStrokeStyle=function(e,t,n,r,i){e.strokeStyle="rgba("+t+","+n+","+r+","+i+")"},nl.eleStrokeStyle=function(e,t,n){var r=t.pstyle("line-fill").value;if("linear-gradient"===r||"radial-gradient"===r)this.gradientStrokeStyle(e,t,r,n);else{var i=t.pstyle("line-color").value;this.colorStrokeStyle(e,i[0],i[1],i[2],n)}},nl.matchCanvasSize=function(e){var t=this,n=t.data,r=t.findContainerClientCoords(),i=r[2],a=r[3],o=t.getPixelRatio(),s=t.motionBlurPxRatio;e!==t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_NODE]&&e!==t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_DRAG]||(o=s);var l,u=i*o,c=a*o;if(u!==t.canvasWidth||c!==t.canvasHeight){t.fontCaches=null;var h=n.canvasContainer;h.style.width=i+"px",h.style.height=a+"px";for(var d=0;d<t.CANVAS_LAYERS;d++)(l=n.canvases[d]).width=u,l.height=c,l.style.width=i+"px",l.style.height=a+"px";for(d=0;d<t.BUFFER_COUNT;d++)(l=n.bufferCanvases[d]).width=u,l.height=c,l.style.width=i+"px",l.style.height=a+"px";t.textureMult=1,o<=1&&(l=n.bufferCanvases[t.TEXTURE_BUFFER],t.textureMult=2,l.width=u*t.textureMult,l.height=c*t.textureMult),t.canvasWidth=u,t.canvasHeight=c}},nl.renderTo=function(e,t,n,r){this.render({forcedContext:e,forcedZoom:t,forcedPan:n,drawAllLayers:!0,forcedPxRatio:r})},nl.render=function(e){var t=(e=e||Ie()).forcedContext,n=e.drawAllLayers,r=e.drawOnlyNodeLayer,i=e.forcedZoom,a=e.forcedPan,o=this,s=void 0===e.forcedPxRatio?this.getPixelRatio():e.forcedPxRatio,l=o.cy,u=o.data,c=u.canvasNeedsRedraw,h=o.textureOnViewport&&!t&&(o.pinching||o.hoverData.dragging||o.swipePanning||o.data.wheelZooming),d=void 0!==e.motionBlur?e.motionBlur:o.motionBlur,p=o.motionBlurPxRatio,g=l.hasCompoundNodes(),f=o.hoverData.draggingEles,v=!(!o.hoverData.selecting&&!o.touchData.selecting),y=d=d&&!t&&o.motionBlurEnabled&&!v;t||(o.prevPxRatio!==s&&(o.invalidateContainerClientCoordsCache(),o.matchCanvasSize(o.container),o.redrawHint("eles",!0),o.redrawHint("drag",!0)),o.prevPxRatio=s),!t&&o.motionBlurTimeout&&clearTimeout(o.motionBlurTimeout),d&&(null==o.mbFrames&&(o.mbFrames=0),o.mbFrames++,o.mbFrames<3&&(y=!1),o.mbFrames>o.minMbLowQualFrames&&(o.motionBlurPxRatio=o.mbPxRBlurry)),o.clearingMotionBlur&&(o.motionBlurPxRatio=1),o.textureDrawLastFrame&&!h&&(c[o.NODE]=!0,c[o.SELECT_BOX]=!0);var m=l.style(),b=l.zoom(),x=void 0!==i?i:b,w=l.pan(),E={x:w.x,y:w.y},_={zoom:b,pan:{x:w.x,y:w.y}},T=o.prevViewport;void 0===T||_.zoom!==T.zoom||_.pan.x!==T.pan.x||_.pan.y!==T.pan.y||f&&!g||(o.motionBlurPxRatio=1),a&&(E=a),x*=s,E.x*=s,E.y*=s;var D=o.getCachedZSortedEles();function C(e,t,n,r,i){var a=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",o.colorFillStyle(e,255,255,255,o.motionBlurTransparency),e.fillRect(t,n,r,i),e.globalCompositeOperation=a}function N(e,r){var s,l,c,h;o.clearingMotionBlur||e!==u.bufferContexts[o.MOTIONBLUR_BUFFER_NODE]&&e!==u.bufferContexts[o.MOTIONBLUR_BUFFER_DRAG]?(s=E,l=x,c=o.canvasWidth,h=o.canvasHeight):(s={x:w.x*p,y:w.y*p},l=b*p,c=o.canvasWidth*p,h=o.canvasHeight*p),e.setTransform(1,0,0,1,0,0),"motionBlur"===r?C(e,0,0,c,h):t||void 0!==r&&!r||e.clearRect(0,0,c,h),n||(e.translate(s.x,s.y),e.scale(l,l)),a&&e.translate(a.x,a.y),i&&e.scale(i,i)}if(h||(o.textureDrawLastFrame=!1),h){if(o.textureDrawLastFrame=!0,!o.textureCache){o.textureCache={},o.textureCache.bb=l.mutableElements().boundingBox(),o.textureCache.texture=o.data.bufferCanvases[o.TEXTURE_BUFFER];var A=o.data.bufferContexts[o.TEXTURE_BUFFER];A.setTransform(1,0,0,1,0,0),A.clearRect(0,0,o.canvasWidth*o.textureMult,o.canvasHeight*o.textureMult),o.render({forcedContext:A,drawOnlyNodeLayer:!0,forcedPxRatio:s*o.textureMult}),(_=o.textureCache.viewport={zoom:l.zoom(),pan:l.pan(),width:o.canvasWidth,height:o.canvasHeight}).mpan={x:(0-_.pan.x)/_.zoom,y:(0-_.pan.y)/_.zoom}}c[o.DRAG]=!1,c[o.NODE]=!1;var L=u.contexts[o.NODE],k=o.textureCache.texture;_=o.textureCache.viewport;L.setTransform(1,0,0,1,0,0),d?C(L,0,0,_.width,_.height):L.clearRect(0,0,_.width,_.height);var S=m.core("outside-texture-bg-color").value,I=m.core("outside-texture-bg-opacity").value;o.colorFillStyle(L,S[0],S[1],S[2],I),L.fillRect(0,0,_.width,_.height);b=l.zoom();N(L,!1),L.clearRect(_.mpan.x,_.mpan.y,_.width/_.zoom/s,_.height/_.zoom/s),L.drawImage(k,_.mpan.x,_.mpan.y,_.width/_.zoom/s,_.height/_.zoom/s)}else o.textureOnViewport&&!t&&(o.textureCache=null);var M=l.extent(),O=o.pinching||o.hoverData.dragging||o.swipePanning||o.data.wheelZooming||o.hoverData.draggingEles||o.cy.animated(),P=o.hideEdgesOnViewport&&O,R=[];if(R[o.NODE]=!c[o.NODE]&&d&&!o.clearedForMotionBlur[o.NODE]||o.clearingMotionBlur,R[o.NODE]&&(o.clearedForMotionBlur[o.NODE]=!0),R[o.DRAG]=!c[o.DRAG]&&d&&!o.clearedForMotionBlur[o.DRAG]||o.clearingMotionBlur,R[o.DRAG]&&(o.clearedForMotionBlur[o.DRAG]=!0),c[o.NODE]||n||r||R[o.NODE]){var B=d&&!R[o.NODE]&&1!==p;N(L=t||(B?o.data.bufferContexts[o.MOTIONBLUR_BUFFER_NODE]:u.contexts[o.NODE]),d&&!B?"motionBlur":void 0),P?o.drawCachedNodes(L,D.nondrag,s,M):o.drawLayeredElements(L,D.nondrag,s,M),o.debug&&o.drawDebugPoints(L,D.nondrag),n||d||(c[o.NODE]=!1)}if(!r&&(c[o.DRAG]||n||R[o.DRAG])){B=d&&!R[o.DRAG]&&1!==p;N(L=t||(B?o.data.bufferContexts[o.MOTIONBLUR_BUFFER_DRAG]:u.contexts[o.DRAG]),d&&!B?"motionBlur":void 0),P?o.drawCachedNodes(L,D.drag,s,M):o.drawCachedElements(L,D.drag,s,M),o.debug&&o.drawDebugPoints(L,D.drag),n||d||(c[o.DRAG]=!1)}if(o.showFps||!r&&c[o.SELECT_BOX]&&!n){if(N(L=t||u.contexts[o.SELECT_BOX]),1==o.selection[4]&&(o.hoverData.selecting||o.touchData.selecting)){b=o.cy.zoom();var F=m.core("selection-box-border-width").value/b;L.lineWidth=F,L.fillStyle="rgba("+m.core("selection-box-color").value[0]+","+m.core("selection-box-color").value[1]+","+m.core("selection-box-color").value[2]+","+m.core("selection-box-opacity").value+")",L.fillRect(o.selection[0],o.selection[1],o.selection[2]-o.selection[0],o.selection[3]-o.selection[1]),F>0&&(L.strokeStyle="rgba("+m.core("selection-box-border-color").value[0]+","+m.core("selection-box-border-color").value[1]+","+m.core("selection-box-border-color").value[2]+","+m.core("selection-box-opacity").value+")",L.strokeRect(o.selection[0],o.selection[1],o.selection[2]-o.selection[0],o.selection[3]-o.selection[1]))}if(u.bgActivePosistion&&!o.hoverData.selecting){b=o.cy.zoom();var z=u.bgActivePosistion;L.fillStyle="rgba("+m.core("active-bg-color").value[0]+","+m.core("active-bg-color").value[1]+","+m.core("active-bg-color").value[2]+","+m.core("active-bg-opacity").value+")",L.beginPath(),L.arc(z.x,z.y,m.core("active-bg-size").pfValue/b,0,2*Math.PI),L.fill()}var G=o.lastRedrawTime;if(o.showFps&&G){G=Math.round(G);var Y=Math.round(1e3/G);L.setTransform(1,0,0,1,0,0),L.fillStyle="rgba(255, 0, 0, 0.75)",L.strokeStyle="rgba(255, 0, 0, 0.75)",L.lineWidth=1,L.fillText("1 frame = "+G+" ms = "+Y+" fps",0,20);L.strokeRect(0,30,250,20),L.fillRect(0,30,250*Math.min(Y/60,1),20)}n||(c[o.SELECT_BOX]=!1)}if(d&&1!==p){var X=u.contexts[o.NODE],V=o.data.bufferCanvases[o.MOTIONBLUR_BUFFER_NODE],U=u.contexts[o.DRAG],j=o.data.bufferCanvases[o.MOTIONBLUR_BUFFER_DRAG],q=function(e,t,n){e.setTransform(1,0,0,1,0,0),n||!y?e.clearRect(0,0,o.canvasWidth,o.canvasHeight):C(e,0,0,o.canvasWidth,o.canvasHeight);var r=p;e.drawImage(t,0,0,o.canvasWidth*r,o.canvasHeight*r,0,0,o.canvasWidth,o.canvasHeight)};(c[o.NODE]||R[o.NODE])&&(q(X,V,R[o.NODE]),c[o.NODE]=!1),(c[o.DRAG]||R[o.DRAG])&&(q(U,j,R[o.DRAG]),c[o.DRAG]=!1)}o.prevViewport=_,o.clearingMotionBlur&&(o.clearingMotionBlur=!1,o.motionBlurCleared=!0,o.motionBlur=!0),d&&(o.motionBlurTimeout=setTimeout((function(){o.motionBlurTimeout=null,o.clearedForMotionBlur[o.NODE]=!1,o.clearedForMotionBlur[o.DRAG]=!1,o.motionBlur=!1,o.clearingMotionBlur=!h,o.mbFrames=0,c[o.NODE]=!0,c[o.DRAG]=!0,o.redraw()}),100)),t||l.emit("render")};for(var rl={drawPolygonPath:function(e,t,n,r,i,a){var o=r/2,s=i/2;e.beginPath&&e.beginPath(),e.moveTo(t+o*a[0],n+s*a[1]);for(var l=1;l<a.length/2;l++)e.lineTo(t+o*a[2*l],n+s*a[2*l+1]);e.closePath()},drawRoundPolygonPath:function(e,t,n,r,i,a){var o=r/2,s=i/2,l=Vt(r,i);e.beginPath&&e.beginPath();for(var u=0;u<a.length/4;u++){var c,h=void 0;h=0===u?a.length-2:4*u-2,c=4*u+2;var d=t+o*a[4*u],p=n+s*a[4*u+1],g=-a[h]*a[c]-a[h+1]*a[c+1],f=l/Math.tan(Math.acos(g)/2),v=d-f*a[h],y=p-f*a[h+1],m=d+f*a[c],b=p+f*a[c+1];0===u?e.moveTo(v,y):e.lineTo(v,y),e.arcTo(d,p,m,b,l)}e.closePath()},drawRoundRectanglePath:function(e,t,n,r,i){var a=r/2,o=i/2,s=Xt(r,i);e.beginPath&&e.beginPath(),e.moveTo(t,n-o),e.arcTo(t+a,n-o,t+a,n,s),e.arcTo(t+a,n+o,t,n+o,s),e.arcTo(t-a,n+o,t-a,n,s),e.arcTo(t-a,n-o,t,n-o,s),e.lineTo(t,n-o),e.closePath()},drawBottomRoundRectanglePath:function(e,t,n,r,i){var a=r/2,o=i/2,s=Xt(r,i);e.beginPath&&e.beginPath(),e.moveTo(t,n-o),e.lineTo(t+a,n-o),e.lineTo(t+a,n),e.arcTo(t+a,n+o,t,n+o,s),e.arcTo(t-a,n+o,t-a,n,s),e.lineTo(t-a,n-o),e.lineTo(t,n-o),e.closePath()},drawCutRectanglePath:function(e,t,n,r,i){var a=r/2,o=i/2;e.beginPath&&e.beginPath(),e.moveTo(t-a+8,n-o),e.lineTo(t+a-8,n-o),e.lineTo(t+a,n-o+8),e.lineTo(t+a,n+o-8),e.lineTo(t+a-8,n+o),e.lineTo(t-a+8,n+o),e.lineTo(t-a,n+o-8),e.lineTo(t-a,n-o+8),e.closePath()},drawBarrelPath:function(e,t,n,r,i){var a=r/2,o=i/2,s=t-a,l=t+a,u=n-o,c=n+o,h=Ut(r,i),d=h.widthOffset,p=h.heightOffset,g=h.ctrlPtOffsetPct*d;e.beginPath&&e.beginPath(),e.moveTo(s,u+p),e.lineTo(s,c-p),e.quadraticCurveTo(s+g,c,s+d,c),e.lineTo(l-d,c),e.quadraticCurveTo(l-g,c,l,c-p),e.lineTo(l,u+p),e.quadraticCurveTo(l-g,u,l-d,u),e.lineTo(s+d,u),e.quadraticCurveTo(s+g,u,s,u+p),e.closePath()}},il=Math.sin(0),al=Math.cos(0),ol={},sl={},ll=Math.PI/40,ul=0*Math.PI;ul<2*Math.PI;ul+=ll)ol[ul]=Math.sin(ul),sl[ul]=Math.cos(ul);rl.drawEllipsePath=function(e,t,n,r,i){if(e.beginPath&&e.beginPath(),e.ellipse)e.ellipse(t,n,r/2,i/2,0,0,2*Math.PI);else for(var a,o,s=r/2,l=i/2,u=0*Math.PI;u<2*Math.PI;u+=ll)a=t-s*ol[u]*il+s*sl[u]*al,o=n+l*sl[u]*il+l*ol[u]*al,0===u?e.moveTo(a,o):e.lineTo(a,o);e.closePath()};var cl={};function hl(e){var t=e.indexOf(",");return e.substr(t+1)}function dl(e,t,n){var r=function(){return t.toDataURL(n,e.quality)};switch(e.output){case"blob-promise":return new rr((function(r,i){try{t.toBlob((function(e){null!=e?r(e):i(new Error("`canvas.toBlob()` sent a null value in its callback"))}),n,e.quality)}catch(a){i(a)}}));case"blob":return function(e,t){for(var n=atob(e),r=new ArrayBuffer(n.length),i=new Uint8Array(r),a=0;a<n.length;a++)i[a]=n.charCodeAt(a);return new Blob([r],{type:t})}(hl(r()),n);case"base64":return hl(r());default:return r()}}cl.createBuffer=function(e,t){var n=document.createElement("canvas");return n.width=e,n.height=t,[n,n.getContext("2d")]},cl.bufferCanvasImage=function(e){var t=this.cy,n=t.mutableElements().boundingBox(),r=this.findContainerClientCoords(),i=e.full?Math.ceil(n.w):r[2],a=e.full?Math.ceil(n.h):r[3],o=I(e.maxWidth)||I(e.maxHeight),s=this.getPixelRatio(),l=1;if(void 0!==e.scale)i*=e.scale,a*=e.scale,l=e.scale;else if(o){var u=1/0,c=1/0;I(e.maxWidth)&&(u=l*e.maxWidth/i),I(e.maxHeight)&&(c=l*e.maxHeight/a),i*=l=Math.min(u,c),a*=l}o||(i*=s,a*=s,l*=s);var h=document.createElement("canvas");h.width=i,h.height=a,h.style.width=i+"px",h.style.height=a+"px";var d=h.getContext("2d");if(i>0&&a>0){d.clearRect(0,0,i,a),d.globalCompositeOperation="source-over";var p=this.getCachedZSortedEles();if(e.full)d.translate(-n.x1*l,-n.y1*l),d.scale(l,l),this.drawElements(d,p),d.scale(1/l,1/l),d.translate(n.x1*l,n.y1*l);else{var g=t.pan(),f={x:g.x*l,y:g.y*l};l*=t.zoom(),d.translate(f.x,f.y),d.scale(l,l),this.drawElements(d,p),d.scale(1/l,1/l),d.translate(-f.x,-f.y)}e.bg&&(d.globalCompositeOperation="destination-over",d.fillStyle=e.bg,d.rect(0,0,i,a),d.fill())}return h},cl.png=function(e){return dl(e,this.bufferCanvasImage(e),"image/png")},cl.jpg=function(e){return dl(e,this.bufferCanvasImage(e),"image/jpeg")};var pl={nodeShapeImpl:function(e,t,n,r,i,a,o){switch(e){case"ellipse":return this.drawEllipsePath(t,n,r,i,a);case"polygon":return this.drawPolygonPath(t,n,r,i,a,o);case"round-polygon":return this.drawRoundPolygonPath(t,n,r,i,a,o);case"roundrectangle":case"round-rectangle":return this.drawRoundRectanglePath(t,n,r,i,a);case"cutrectangle":case"cut-rectangle":return this.drawCutRectanglePath(t,n,r,i,a);case"bottomroundrectangle":case"bottom-round-rectangle":return this.drawBottomRoundRectanglePath(t,n,r,i,a);case"barrel":return this.drawBarrelPath(t,n,r,i,a)}}},gl=vl,fl=vl.prototype;function vl(e){var t=this;t.data={canvases:new Array(fl.CANVAS_LAYERS),contexts:new Array(fl.CANVAS_LAYERS),canvasNeedsRedraw:new Array(fl.CANVAS_LAYERS),bufferCanvases:new Array(fl.BUFFER_COUNT),bufferContexts:new Array(fl.CANVAS_LAYERS)};var n="-webkit-tap-highlight-color",r="rgba(0,0,0,0)";t.data.canvasContainer=document.createElement("div");var i=t.data.canvasContainer.style;t.data.canvasContainer.style[n]=r,i.position="relative",i.zIndex="0",i.overflow="hidden";var a=e.cy.container();a.appendChild(t.data.canvasContainer),a.style[n]=r;var o={"-webkit-user-select":"none","-moz-user-select":"-moz-none","user-select":"none","-webkit-tap-highlight-color":"rgba(0,0,0,0)","outline-style":"none"};E&&E.userAgent.match(/msie|trident|edge/i)&&(o["-ms-touch-action"]="none",o["touch-action"]="none");for(var s=0;s<fl.CANVAS_LAYERS;s++){var l=t.data.canvases[s]=document.createElement("canvas");t.data.contexts[s]=l.getContext("2d"),Object.keys(o).forEach((function(e){l.style[e]=o[e]})),l.style.position="absolute",l.setAttribute("data-id","layer"+s),l.style.zIndex=String(fl.CANVAS_LAYERS-s),t.data.canvasContainer.appendChild(l),t.data.canvasNeedsRedraw[s]=!1}t.data.topCanvas=t.data.canvases[0],t.data.canvases[fl.NODE].setAttribute("data-id","layer"+fl.NODE+"-node"),t.data.canvases[fl.SELECT_BOX].setAttribute("data-id","layer"+fl.SELECT_BOX+"-selectbox"),t.data.canvases[fl.DRAG].setAttribute("data-id","layer"+fl.DRAG+"-drag");for(s=0;s<fl.BUFFER_COUNT;s++)t.data.bufferCanvases[s]=document.createElement("canvas"),t.data.bufferContexts[s]=t.data.bufferCanvases[s].getContext("2d"),t.data.bufferCanvases[s].style.position="absolute",t.data.bufferCanvases[s].setAttribute("data-id","buffer"+s),t.data.bufferCanvases[s].style.zIndex=String(-s-1),t.data.bufferCanvases[s].style.visibility="hidden";t.pathsEnabled=!0;var u=ft(),c=function(e){return{x:-e.w/2,y:-e.h/2}},h=function(e){return e.boundingBox(),e[0]._private.bodyBounds},d=function(e){return e.boundingBox(),e[0]._private.labelBounds.main||u},p=function(e){return e.boundingBox(),e[0]._private.labelBounds.source||u},g=function(e){return e.boundingBox(),e[0]._private.labelBounds.target||u},f=function(e,t){return t},v=function(e,t,n){var r=e?e+"-":"";return{x:t.x+n.pstyle(r+"text-margin-x").pfValue,y:t.y+n.pstyle(r+"text-margin-y").pfValue}},y=function(e,t,n){var r=e[0]._private.rscratch;return{x:r[t],y:r[n]}},m=t.data.eleTxrCache=new Ls(t,{getKey:function(e){return e[0]._private.nodeKey},doesEleInvalidateKey:function(e){var t=e[0]._private;return!(t.oldBackgroundTimestamp===t.backgroundTimestamp)},drawElement:function(e,n,r,i,a){return t.drawElement(e,n,r,!1,!1,a)},getBoundingBox:h,getRotationPoint:function(e){return{x:((t=h(e)).x1+t.x2)/2,y:(t.y1+t.y2)/2};var t},getRotationOffset:function(e){return c(h(e))},allowEdgeTxrCaching:!1,allowParentTxrCaching:!1}),b=t.data.lblTxrCache=new Ls(t,{getKey:function(e){return e[0]._private.labelStyleKey},drawElement:function(e,n,r,i,a){return t.drawElementText(e,n,r,i,"main",a)},getBoundingBox:d,getRotationPoint:function(e){return v("",y(e,"labelX","labelY"),e)},getRotationOffset:function(e){var t=d(e),n=c(d(e));if(e.isNode()){switch(e.pstyle("text-halign").value){case"left":n.x=-t.w;break;case"right":n.x=0}switch(e.pstyle("text-valign").value){case"top":n.y=-t.h;break;case"bottom":n.y=0}}return n},isVisible:f}),x=t.data.slbTxrCache=new Ls(t,{getKey:function(e){return e[0]._private.sourceLabelStyleKey},drawElement:function(e,n,r,i,a){return t.drawElementText(e,n,r,i,"source",a)},getBoundingBox:p,getRotationPoint:function(e){return v("source",y(e,"sourceLabelX","sourceLabelY"),e)},getRotationOffset:function(e){return c(p(e))},isVisible:f}),w=t.data.tlbTxrCache=new Ls(t,{getKey:function(e){return e[0]._private.targetLabelStyleKey},drawElement:function(e,n,r,i,a){return t.drawElementText(e,n,r,i,"target",a)},getBoundingBox:g,getRotationPoint:function(e){return v("target",y(e,"targetLabelX","targetLabelY"),e)},getRotationOffset:function(e){return c(g(e))},isVisible:f}),_=t.data.lyrTxrCache=new Ss(t);t.onUpdateEleCalcs((function(e,t){m.invalidateElements(t),b.invalidateElements(t),x.invalidateElements(t),w.invalidateElements(t),_.invalidateElements(t);for(var n=0;n<t.length;n++){var r=t[n]._private;r.oldBackgroundTimestamp=r.backgroundTimestamp}}));var T=function(e){for(var t=0;t<e.length;t++)_.enqueueElementRefinement(e[t].ele)};m.onDequeue(T),b.onDequeue(T),x.onDequeue(T),w.onDequeue(T)}fl.CANVAS_LAYERS=3,fl.SELECT_BOX=0,fl.DRAG=1,fl.NODE=2,fl.BUFFER_COUNT=3,fl.TEXTURE_BUFFER=0,fl.MOTIONBLUR_BUFFER_NODE=1,fl.MOTIONBLUR_BUFFER_DRAG=2,fl.redrawHint=function(e,t){var n=this;switch(e){case"eles":n.data.canvasNeedsRedraw[fl.NODE]=t;break;case"drag":n.data.canvasNeedsRedraw[fl.DRAG]=t;break;case"select":n.data.canvasNeedsRedraw[fl.SELECT_BOX]=t}};var yl="undefined"!=typeof Path2D;fl.path2dEnabled=function(e){if(void 0===e)return this.pathsEnabled;this.pathsEnabled=!!e},fl.usePaths=function(){return yl&&this.pathsEnabled},fl.setImgSmoothing=function(e,t){null!=e.imageSmoothingEnabled?e.imageSmoothingEnabled=t:(e.webkitImageSmoothingEnabled=t,e.mozImageSmoothingEnabled=t,e.msImageSmoothingEnabled=t)},fl.getImgSmoothing=function(e){return null!=e.imageSmoothingEnabled?e.imageSmoothingEnabled:e.webkitImageSmoothingEnabled||e.mozImageSmoothingEnabled||e.msImageSmoothingEnabled},fl.makeOffscreenCanvas=function(e,t){var n;return"undefined"!==("undefined"==typeof OffscreenCanvas?"undefined":g(OffscreenCanvas))?n=new OffscreenCanvas(e,t):((n=document.createElement("canvas")).width=e,n.height=t),n},[Rs,Xs,$s,Zs,Qs,el,nl,rl,cl,pl].forEach((function(e){Q(fl,e)}));var ml=[{type:"layout",extensions:Zo},{type:"renderer",extensions:[{name:"null",impl:Qo},{name:"base",impl:Es},{name:"canvas",impl:gl}]}],bl={},xl={};function wl(e,t,n){var r=n,i=function(n){Ae("Can not register `"+t+"` for `"+e+"` since `"+n+"` already exists in the prototype and can not be overridden")};if("core"===e){if(uo.prototype[t])return i(t);uo.prototype[t]=n}else if("collection"===e){if(Da.prototype[t])return i(t);Da.prototype[t]=n}else if("layout"===e){for(var a=function(e){this.options=e,n.call(this,e),S(this._private)||(this._private={}),this._private.cy=e.cy,this._private.listeners=[],this.createEmitter()},o=a.prototype=Object.create(n.prototype),s=[],l=0;l<s.length;l++){var u=s[l];o[u]=o[u]||function(){return this}}o.start&&!o.run?o.run=function(){return this.start(),this}:!o.start&&o.run&&(o.start=function(){return this.run(),this});var c=n.prototype.stop;o.stop=function(){var e=this.options;if(e&&e.animate){var t=this.animations;if(t)for(var n=0;n<t.length;n++)t[n].stop()}return c?c.call(this):this.emit("layoutstop"),this},o.destroy||(o.destroy=function(){return this}),o.cy=function(){return this._private.cy};var h=function(e){return e._private.cy},d={addEventFields:function(e,t){t.layout=e,t.cy=h(e),t.target=e},bubble:function(){return!0},parent:function(e){return h(e)}};Q(o,{createEmitter:function(){return this._private.emitter=new Vi(d,this),this},emitter:function(){return this._private.emitter},on:function(e,t){return this.emitter().on(e,t),this},one:function(e,t){return this.emitter().one(e,t),this},once:function(e,t){return this.emitter().one(e,t),this},removeListener:function(e,t){return this.emitter().removeListener(e,t),this},removeAllListeners:function(){return this.emitter().removeAllListeners(),this},emit:function(e,t){return this.emitter().emit(e,t),this}}),ur.eventAliasesOn(o),r=a}else if("renderer"===e&&"null"!==t&&"base"!==t){var p=El("renderer","base"),g=p.prototype,f=n,v=n.prototype,y=function(){p.apply(this,arguments),f.apply(this,arguments)},m=y.prototype;for(var b in g){var x=g[b];if(null!=v[b])return i(b);m[b]=x}for(var w in v)m[w]=v[w];g.clientFunctions.forEach((function(e){m[e]=m[e]||function(){Ce("Renderer does not implement `renderer."+e+"()` on its prototype")}})),r=y}else if("__proto__"===e||"constructor"===e||"prototype"===e)return Ce(e+" is an illegal type to be registered, possibly lead to prototype pollutions");return te({map:bl,keys:[e,t],value:r})}function El(e,t){return ne({map:bl,keys:[e,t]})}function _l(e,t,n,r,i){return te({map:xl,keys:[e,t,n,r],value:i})}function Tl(e,t,n,r){return ne({map:xl,keys:[e,t,n,r]})}var Dl=function(){return 2===arguments.length?El.apply(null,arguments):3===arguments.length?wl.apply(null,arguments):4===arguments.length?Tl.apply(null,arguments):5===arguments.length?_l.apply(null,arguments):void Ce("Invalid extension access syntax")};uo.prototype.extension=Dl,ml.forEach((function(e){e.extensions.forEach((function(t){wl(e.type,t.name,t.impl)}))}));var Cl=function e(){if(!(this instanceof e))return new e;this.length=0},Nl=Cl.prototype;Nl.instanceString=function(){return"stylesheet"},Nl.selector=function(e){return this[this.length++]={selector:e,properties:[]},this},Nl.css=function(e,t){var n=this.length-1;if(A(e))this[n].properties.push({name:e,value:t});else if(S(e))for(var r=e,i=Object.keys(r),a=0;a<i.length;a++){var o=i[a],s=r[o];if(null!=s){var l=io.properties[o]||io.properties[V(o)];if(null!=l){var u=l.name,c=s;this[n].properties.push({name:u,value:c})}}}return this},Nl.style=Nl.css,Nl.generateStyle=function(e){var t=new io(e);return this.appendToStyle(t)},Nl.appendToStyle=function(e){for(var t=0;t<this.length;t++){var n=this[t],r=n.selector,i=n.properties;e.selector(r);for(var a=0;a<i.length;a++){var o=i[a];e.css(o.name,o.value)}}return e};var Al=function(e){return void 0===e&&(e={}),S(e)?new uo(e):A(e)?Dl.apply(Dl,arguments):void 0};Al.use=function(e){var t=Array.prototype.slice.call(arguments,1);return t.unshift(Al),e.apply(null,t),this},Al.warnings=function(e){return Ne(e)},Al.version="3.28.1",Al.stylesheet=Al.Stylesheet=Cl,e.exports=Al},65731:(e,t,n)=>{e.exports=n(34297)},34297:function(e,t){var n,r,i;(function(){var a,o,s,l,u,c,h,d,p,g,f,v,y,m,b;s=Math.floor,g=Math.min,o=function(e,t){return e<t?-1:e>t?1:0},p=function(e,t,n,r,i){var a;if(null==n&&(n=0),null==i&&(i=o),n<0)throw new Error("lo must be non-negative");for(null==r&&(r=e.length);n<r;)i(t,e[a=s((n+r)/2)])<0?r=a:n=a+1;return[].splice.apply(e,[n,n-n].concat(t)),t},c=function(e,t,n){return null==n&&(n=o),e.push(t),m(e,0,e.length-1,n)},u=function(e,t){var n,r;return null==t&&(t=o),n=e.pop(),e.length?(r=e[0],e[0]=n,b(e,0,t)):r=n,r},d=function(e,t,n){var r;return null==n&&(n=o),r=e[0],e[0]=t,b(e,0,n),r},h=function(e,t,n){var r;return null==n&&(n=o),e.length&&n(e[0],t)<0&&(t=(r=[e[0],t])[0],e[0]=r[1],b(e,0,n)),t},l=function(e,t){var n,r,i,a,l,u;for(null==t&&(t=o),a=function(){u=[];for(var t=0,n=s(e.length/2);0<=n?t<n:t>n;0<=n?t++:t--)u.push(t);return u}.apply(this).reverse(),l=[],r=0,i=a.length;r<i;r++)n=a[r],l.push(b(e,n,t));return l},y=function(e,t,n){var r;if(null==n&&(n=o),-1!==(r=e.indexOf(t)))return m(e,0,r,n),b(e,r,n)},f=function(e,t,n){var r,i,a,s,u;if(null==n&&(n=o),!(i=e.slice(0,t)).length)return i;for(l(i,n),a=0,s=(u=e.slice(t)).length;a<s;a++)r=u[a],h(i,r,n);return i.sort(n).reverse()},v=function(e,t,n){var r,i,a,s,c,h,d,f,v;if(null==n&&(n=o),10*t<=e.length){if(!(a=e.slice(0,t).sort(n)).length)return a;for(i=a[a.length-1],s=0,h=(d=e.slice(t)).length;s<h;s++)n(r=d[s],i)<0&&(p(a,r,0,null,n),a.pop(),i=a[a.length-1]);return a}for(l(e,n),v=[],c=0,f=g(t,e.length);0<=f?c<f:c>f;0<=f?++c:--c)v.push(u(e,n));return v},m=function(e,t,n,r){var i,a,s;for(null==r&&(r=o),i=e[n];n>t&&r(i,a=e[s=n-1>>1])<0;)e[n]=a,n=s;return e[n]=i},b=function(e,t,n){var r,i,a,s,l;for(null==n&&(n=o),i=e.length,l=t,a=e[t],r=2*t+1;r<i;)(s=r+1)<i&&!(n(e[r],e[s])<0)&&(r=s),e[t]=e[r],r=2*(t=r)+1;return e[t]=a,m(e,l,t,n)},a=function(){function e(e){this.cmp=null!=e?e:o,this.nodes=[]}return e.push=c,e.pop=u,e.replace=d,e.pushpop=h,e.heapify=l,e.updateItem=y,e.nlargest=f,e.nsmallest=v,e.prototype.push=function(e){return c(this.nodes,e,this.cmp)},e.prototype.pop=function(){return u(this.nodes,this.cmp)},e.prototype.peek=function(){return this.nodes[0]},e.prototype.contains=function(e){return-1!==this.nodes.indexOf(e)},e.prototype.replace=function(e){return d(this.nodes,e,this.cmp)},e.prototype.pushpop=function(e){return h(this.nodes,e,this.cmp)},e.prototype.heapify=function(){return l(this.nodes,this.cmp)},e.prototype.updateItem=function(e){return y(this.nodes,e,this.cmp)},e.prototype.clear=function(){return this.nodes=[]},e.prototype.empty=function(){return 0===this.nodes.length},e.prototype.size=function(){return this.nodes.length},e.prototype.clone=function(){var t;return(t=new e).nodes=this.nodes.slice(0),t},e.prototype.toArray=function(){return this.nodes.slice(0)},e.prototype.insert=e.prototype.push,e.prototype.top=e.prototype.peek,e.prototype.front=e.prototype.peek,e.prototype.has=e.prototype.contains,e.prototype.copy=e.prototype.clone,e}(),r=[],void 0===(i="function"==typeof(n=function(){return a})?n.apply(t,r):n)||(e.exports=i)}).call(this)},23143:function(e){var t;t=function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=26)}([function(e,t,n){"use strict";function r(){}r.QUALITY=1,r.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,r.DEFAULT_INCREMENTAL=!1,r.DEFAULT_ANIMATION_ON_LAYOUT=!0,r.DEFAULT_ANIMATION_DURING_LAYOUT=!1,r.DEFAULT_ANIMATION_PERIOD=50,r.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,r.DEFAULT_GRAPH_MARGIN=15,r.NODE_DIMENSIONS_INCLUDE_LABELS=!1,r.SIMPLE_NODE_SIZE=40,r.SIMPLE_NODE_HALF_SIZE=r.SIMPLE_NODE_SIZE/2,r.EMPTY_COMPOUND_NODE_SIZE=40,r.MIN_EDGE_LENGTH=1,r.WORLD_BOUNDARY=1e6,r.INITIAL_WORLD_BOUNDARY=r.WORLD_BOUNDARY/1e3,r.WORLD_CENTER_X=1200,r.WORLD_CENTER_Y=900,e.exports=r},function(e,t,n){"use strict";var r=n(2),i=n(8),a=n(9);function o(e,t,n){r.call(this,n),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=n,this.bendpoints=[],this.source=e,this.target=t}for(var s in o.prototype=Object.create(r.prototype),r)o[s]=r[s];o.prototype.getSource=function(){return this.source},o.prototype.getTarget=function(){return this.target},o.prototype.isInterGraph=function(){return this.isInterGraph},o.prototype.getLength=function(){return this.length},o.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},o.prototype.getBendpoints=function(){return this.bendpoints},o.prototype.getLca=function(){return this.lca},o.prototype.getSourceInLca=function(){return this.sourceInLca},o.prototype.getTargetInLca=function(){return this.targetInLca},o.prototype.getOtherEnd=function(e){if(this.source===e)return this.target;if(this.target===e)return this.source;throw"Node is not incident with this edge"},o.prototype.getOtherEndInGraph=function(e,t){for(var n=this.getOtherEnd(e),r=t.getGraphManager().getRoot();;){if(n.getOwner()==t)return n;if(n.getOwner()==r)break;n=n.getOwner().getParent()}return null},o.prototype.updateLength=function(){var e=new Array(4);this.isOverlapingSourceAndTarget=i.getIntersection(this.target.getRect(),this.source.getRect(),e),this.isOverlapingSourceAndTarget||(this.lengthX=e[0]-e[2],this.lengthY=e[1]-e[3],Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},o.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},e.exports=o},function(e,t,n){"use strict";e.exports=function(e){this.vGraphObject=e}},function(e,t,n){"use strict";var r=n(2),i=n(10),a=n(13),o=n(0),s=n(16),l=n(4);function u(e,t,n,o){null==n&&null==o&&(o=t),r.call(this,o),null!=e.graphManager&&(e=e.graphManager),this.estimatedSize=i.MIN_VALUE,this.inclusionTreeDepth=i.MAX_VALUE,this.vGraphObject=o,this.edges=[],this.graphManager=e,this.rect=null!=n&&null!=t?new a(t.x,t.y,n.width,n.height):new a}for(var c in u.prototype=Object.create(r.prototype),r)u[c]=r[c];u.prototype.getEdges=function(){return this.edges},u.prototype.getChild=function(){return this.child},u.prototype.getOwner=function(){return this.owner},u.prototype.getWidth=function(){return this.rect.width},u.prototype.setWidth=function(e){this.rect.width=e},u.prototype.getHeight=function(){return this.rect.height},u.prototype.setHeight=function(e){this.rect.height=e},u.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},u.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},u.prototype.getCenter=function(){return new l(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},u.prototype.getLocation=function(){return new l(this.rect.x,this.rect.y)},u.prototype.getRect=function(){return this.rect},u.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},u.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},u.prototype.setRect=function(e,t){this.rect.x=e.x,this.rect.y=e.y,this.rect.width=t.width,this.rect.height=t.height},u.prototype.setCenter=function(e,t){this.rect.x=e-this.rect.width/2,this.rect.y=t-this.rect.height/2},u.prototype.setLocation=function(e,t){this.rect.x=e,this.rect.y=t},u.prototype.moveBy=function(e,t){this.rect.x+=e,this.rect.y+=t},u.prototype.getEdgeListToNode=function(e){var t=[],n=this;return n.edges.forEach((function(r){if(r.target==e){if(r.source!=n)throw"Incorrect edge source!";t.push(r)}})),t},u.prototype.getEdgesBetween=function(e){var t=[],n=this;return n.edges.forEach((function(r){if(r.source!=n&&r.target!=n)throw"Incorrect edge source and/or target";r.target!=e&&r.source!=e||t.push(r)})),t},u.prototype.getNeighborsList=function(){var e=new Set,t=this;return t.edges.forEach((function(n){if(n.source==t)e.add(n.target);else{if(n.target!=t)throw"Incorrect incidency!";e.add(n.source)}})),e},u.prototype.withChildren=function(){var e=new Set;if(e.add(this),null!=this.child)for(var t=this.child.getNodes(),n=0;n<t.length;n++)t[n].withChildren().forEach((function(t){e.add(t)}));return e},u.prototype.getNoOfChildren=function(){var e=0;if(null==this.child)e=1;else for(var t=this.child.getNodes(),n=0;n<t.length;n++)e+=t[n].getNoOfChildren();return 0==e&&(e=1),e},u.prototype.getEstimatedSize=function(){if(this.estimatedSize==i.MIN_VALUE)throw"assert failed";return this.estimatedSize},u.prototype.calcEstimatedSize=function(){return null==this.child?this.estimatedSize=(this.rect.width+this.rect.height)/2:(this.estimatedSize=this.child.calcEstimatedSize(),this.rect.width=this.estimatedSize,this.rect.height=this.estimatedSize,this.estimatedSize)},u.prototype.scatter=function(){var e,t,n=-o.INITIAL_WORLD_BOUNDARY,r=o.INITIAL_WORLD_BOUNDARY;e=o.WORLD_CENTER_X+s.nextDouble()*(r-n)+n;var i=-o.INITIAL_WORLD_BOUNDARY,a=o.INITIAL_WORLD_BOUNDARY;t=o.WORLD_CENTER_Y+s.nextDouble()*(a-i)+i,this.rect.x=e,this.rect.y=t},u.prototype.updateBounds=function(){if(null==this.getChild())throw"assert failed";if(0!=this.getChild().getNodes().length){var e=this.getChild();if(e.updateBounds(!0),this.rect.x=e.getLeft(),this.rect.y=e.getTop(),this.setWidth(e.getRight()-e.getLeft()),this.setHeight(e.getBottom()-e.getTop()),o.NODE_DIMENSIONS_INCLUDE_LABELS){var t=e.getRight()-e.getLeft(),n=e.getBottom()-e.getTop();this.labelWidth>t&&(this.rect.x-=(this.labelWidth-t)/2,this.setWidth(this.labelWidth)),this.labelHeight>n&&("center"==this.labelPos?this.rect.y-=(this.labelHeight-n)/2:"top"==this.labelPos&&(this.rect.y-=this.labelHeight-n),this.setHeight(this.labelHeight))}}},u.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==i.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},u.prototype.transform=function(e){var t=this.rect.x;t>o.WORLD_BOUNDARY?t=o.WORLD_BOUNDARY:t<-o.WORLD_BOUNDARY&&(t=-o.WORLD_BOUNDARY);var n=this.rect.y;n>o.WORLD_BOUNDARY?n=o.WORLD_BOUNDARY:n<-o.WORLD_BOUNDARY&&(n=-o.WORLD_BOUNDARY);var r=new l(t,n),i=e.inverseTransformPoint(r);this.setLocation(i.x,i.y)},u.prototype.getLeft=function(){return this.rect.x},u.prototype.getRight=function(){return this.rect.x+this.rect.width},u.prototype.getTop=function(){return this.rect.y},u.prototype.getBottom=function(){return this.rect.y+this.rect.height},u.prototype.getParent=function(){return null==this.owner?null:this.owner.getParent()},e.exports=u},function(e,t,n){"use strict";function r(e,t){null==e&&null==t?(this.x=0,this.y=0):(this.x=e,this.y=t)}r.prototype.getX=function(){return this.x},r.prototype.getY=function(){return this.y},r.prototype.setX=function(e){this.x=e},r.prototype.setY=function(e){this.y=e},r.prototype.getDifference=function(e){return new DimensionD(this.x-e.x,this.y-e.y)},r.prototype.getCopy=function(){return new r(this.x,this.y)},r.prototype.translate=function(e){return this.x+=e.width,this.y+=e.height,this},e.exports=r},function(e,t,n){"use strict";var r=n(2),i=n(10),a=n(0),o=n(6),s=n(3),l=n(1),u=n(13),c=n(12),h=n(11);function d(e,t,n){r.call(this,n),this.estimatedSize=i.MIN_VALUE,this.margin=a.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=e,null!=t&&t instanceof o?this.graphManager=t:null!=t&&t instanceof Layout&&(this.graphManager=t.graphManager)}for(var p in d.prototype=Object.create(r.prototype),r)d[p]=r[p];d.prototype.getNodes=function(){return this.nodes},d.prototype.getEdges=function(){return this.edges},d.prototype.getGraphManager=function(){return this.graphManager},d.prototype.getParent=function(){return this.parent},d.prototype.getLeft=function(){return this.left},d.prototype.getRight=function(){return this.right},d.prototype.getTop=function(){return this.top},d.prototype.getBottom=function(){return this.bottom},d.prototype.isConnected=function(){return this.isConnected},d.prototype.add=function(e,t,n){if(null==t&&null==n){var r=e;if(null==this.graphManager)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(r)>-1)throw"Node already in graph!";return r.owner=this,this.getNodes().push(r),r}var i=e;if(!(this.getNodes().indexOf(t)>-1&&this.getNodes().indexOf(n)>-1))throw"Source or target not in graph!";if(t.owner!=n.owner||t.owner!=this)throw"Both owners must be this graph!";return t.owner!=n.owner?null:(i.source=t,i.target=n,i.isInterGraph=!1,this.getEdges().push(i),t.edges.push(i),n!=t&&n.edges.push(i),i)},d.prototype.remove=function(e){var t=e;if(e instanceof s){if(null==t)throw"Node is null!";if(null==t.owner||t.owner!=this)throw"Owner graph is invalid!";if(null==this.graphManager)throw"Owner graph manager is invalid!";for(var n=t.edges.slice(),r=n.length,i=0;i<r;i++)(a=n[i]).isInterGraph?this.graphManager.remove(a):a.source.owner.remove(a);if(-1==(o=this.nodes.indexOf(t)))throw"Node not in owner node list!";this.nodes.splice(o,1)}else if(e instanceof l){var a;if(null==(a=e))throw"Edge is null!";if(null==a.source||null==a.target)throw"Source and/or target is null!";if(null==a.source.owner||null==a.target.owner||a.source.owner!=this||a.target.owner!=this)throw"Source and/or target owner is invalid!";var o,u=a.source.edges.indexOf(a),c=a.target.edges.indexOf(a);if(!(u>-1&&c>-1))throw"Source and/or target doesn't know this edge!";if(a.source.edges.splice(u,1),a.target!=a.source&&a.target.edges.splice(c,1),-1==(o=a.source.owner.getEdges().indexOf(a)))throw"Not in owner's edge list!";a.source.owner.getEdges().splice(o,1)}},d.prototype.updateLeftTop=function(){for(var e,t,n,r=i.MAX_VALUE,a=i.MAX_VALUE,o=this.getNodes(),s=o.length,l=0;l<s;l++){var u=o[l];r>(e=u.getTop())&&(r=e),a>(t=u.getLeft())&&(a=t)}return r==i.MAX_VALUE?null:(n=null!=o[0].getParent().paddingLeft?o[0].getParent().paddingLeft:this.margin,this.left=a-n,this.top=r-n,new c(this.left,this.top))},d.prototype.updateBounds=function(e){for(var t,n,r,a,o,s=i.MAX_VALUE,l=-i.MAX_VALUE,c=i.MAX_VALUE,h=-i.MAX_VALUE,d=this.nodes,p=d.length,g=0;g<p;g++){var f=d[g];e&&null!=f.child&&f.updateBounds(),s>(t=f.getLeft())&&(s=t),l<(n=f.getRight())&&(l=n),c>(r=f.getTop())&&(c=r),h<(a=f.getBottom())&&(h=a)}var v=new u(s,c,l-s,h-c);s==i.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),o=null!=d[0].getParent().paddingLeft?d[0].getParent().paddingLeft:this.margin,this.left=v.x-o,this.right=v.x+v.width+o,this.top=v.y-o,this.bottom=v.y+v.height+o},d.calculateBounds=function(e){for(var t,n,r,a,o=i.MAX_VALUE,s=-i.MAX_VALUE,l=i.MAX_VALUE,c=-i.MAX_VALUE,h=e.length,d=0;d<h;d++){var p=e[d];o>(t=p.getLeft())&&(o=t),s<(n=p.getRight())&&(s=n),l>(r=p.getTop())&&(l=r),c<(a=p.getBottom())&&(c=a)}return new u(o,l,s-o,c-l)},d.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},d.prototype.getEstimatedSize=function(){if(this.estimatedSize==i.MIN_VALUE)throw"assert failed";return this.estimatedSize},d.prototype.calcEstimatedSize=function(){for(var e=0,t=this.nodes,n=t.length,r=0;r<n;r++)e+=t[r].calcEstimatedSize();return this.estimatedSize=0==e?a.EMPTY_COMPOUND_NODE_SIZE:e/Math.sqrt(this.nodes.length),this.estimatedSize},d.prototype.updateConnected=function(){var e=this;if(0!=this.nodes.length){var t,n,r=new h,i=new Set,a=this.nodes[0];for(a.withChildren().forEach((function(e){r.push(e),i.add(e)}));0!==r.length;)for(var o=(t=(a=r.shift()).getEdges()).length,s=0;s<o;s++)null==(n=t[s].getOtherEndInGraph(a,this))||i.has(n)||n.withChildren().forEach((function(e){r.push(e),i.add(e)}));if(this.isConnected=!1,i.size>=this.nodes.length){var l=0;i.forEach((function(t){t.owner==e&&l++})),l==this.nodes.length&&(this.isConnected=!0)}}else this.isConnected=!0},e.exports=d},function(e,t,n){"use strict";var r,i=n(1);function a(e){r=n(5),this.layout=e,this.graphs=[],this.edges=[]}a.prototype.addRoot=function(){var e=this.layout.newGraph(),t=this.layout.newNode(null),n=this.add(e,t);return this.setRootGraph(n),this.rootGraph},a.prototype.add=function(e,t,n,r,i){if(null==n&&null==r&&null==i){if(null==e)throw"Graph is null!";if(null==t)throw"Parent node is null!";if(this.graphs.indexOf(e)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(e),null!=e.parent)throw"Already has a parent!";if(null!=t.child)throw"Already has a child!";return e.parent=t,t.child=e,e}i=n,n=e;var a=(r=t).getOwner(),o=i.getOwner();if(null==a||a.getGraphManager()!=this)throw"Source not in this graph mgr!";if(null==o||o.getGraphManager()!=this)throw"Target not in this graph mgr!";if(a==o)return n.isInterGraph=!1,a.add(n,r,i);if(n.isInterGraph=!0,n.source=r,n.target=i,this.edges.indexOf(n)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(n),null==n.source||null==n.target)throw"Edge source and/or target is null!";if(-1!=n.source.edges.indexOf(n)||-1!=n.target.edges.indexOf(n))throw"Edge already in source and/or target incidency list!";return n.source.edges.push(n),n.target.edges.push(n),n},a.prototype.remove=function(e){if(e instanceof r){var t=e;if(t.getGraphManager()!=this)throw"Graph not in this graph mgr";if(t!=this.rootGraph&&(null==t.parent||t.parent.graphManager!=this))throw"Invalid parent node!";for(var n,a=[],o=(a=a.concat(t.getEdges())).length,s=0;s<o;s++)n=a[s],t.remove(n);var l,u=[];for(o=(u=u.concat(t.getNodes())).length,s=0;s<o;s++)l=u[s],t.remove(l);t==this.rootGraph&&this.setRootGraph(null);var c=this.graphs.indexOf(t);this.graphs.splice(c,1),t.parent=null}else if(e instanceof i){if(null==(n=e))throw"Edge is null!";if(!n.isInterGraph)throw"Not an inter-graph edge!";if(null==n.source||null==n.target)throw"Source and/or target is null!";if(-1==n.source.edges.indexOf(n)||-1==n.target.edges.indexOf(n))throw"Source and/or target doesn't know this edge!";if(c=n.source.edges.indexOf(n),n.source.edges.splice(c,1),c=n.target.edges.indexOf(n),n.target.edges.splice(c,1),null==n.source.owner||null==n.source.owner.getGraphManager())throw"Edge owner graph or owner graph manager is null!";if(-1==n.source.owner.getGraphManager().edges.indexOf(n))throw"Not in owner graph manager's edge list!";c=n.source.owner.getGraphManager().edges.indexOf(n),n.source.owner.getGraphManager().edges.splice(c,1)}},a.prototype.updateBounds=function(){this.rootGraph.updateBounds(!0)},a.prototype.getGraphs=function(){return this.graphs},a.prototype.getAllNodes=function(){if(null==this.allNodes){for(var e=[],t=this.getGraphs(),n=t.length,r=0;r<n;r++)e=e.concat(t[r].getNodes());this.allNodes=e}return this.allNodes},a.prototype.resetAllNodes=function(){this.allNodes=null},a.prototype.resetAllEdges=function(){this.allEdges=null},a.prototype.resetAllNodesToApplyGravitation=function(){this.allNodesToApplyGravitation=null},a.prototype.getAllEdges=function(){if(null==this.allEdges){for(var e=[],t=this.getGraphs(),n=(t.length,0);n<t.length;n++)e=e.concat(t[n].getEdges());e=e.concat(this.edges),this.allEdges=e}return this.allEdges},a.prototype.getAllNodesToApplyGravitation=function(){return this.allNodesToApplyGravitation},a.prototype.setAllNodesToApplyGravitation=function(e){if(null!=this.allNodesToApplyGravitation)throw"assert failed";this.allNodesToApplyGravitation=e},a.prototype.getRoot=function(){return this.rootGraph},a.prototype.setRootGraph=function(e){if(e.getGraphManager()!=this)throw"Root not in this graph mgr!";this.rootGraph=e,null==e.parent&&(e.parent=this.layout.newNode("Root node"))},a.prototype.getLayout=function(){return this.layout},a.prototype.isOneAncestorOfOther=function(e,t){if(null==e||null==t)throw"assert failed";if(e==t)return!0;for(var n,r=e.getOwner();null!=(n=r.getParent());){if(n==t)return!0;if(null==(r=n.getOwner()))break}for(r=t.getOwner();null!=(n=r.getParent());){if(n==e)return!0;if(null==(r=n.getOwner()))break}return!1},a.prototype.calcLowestCommonAncestors=function(){for(var e,t,n,r,i,a=this.getAllEdges(),o=a.length,s=0;s<o;s++)if(t=(e=a[s]).source,n=e.target,e.lca=null,e.sourceInLca=t,e.targetInLca=n,t!=n){for(r=t.getOwner();null==e.lca;){for(e.targetInLca=n,i=n.getOwner();null==e.lca;){if(i==r){e.lca=i;break}if(i==this.rootGraph)break;if(null!=e.lca)throw"assert failed";e.targetInLca=i.getParent(),i=e.targetInLca.getOwner()}if(r==this.rootGraph)break;null==e.lca&&(e.sourceInLca=r.getParent(),r=e.sourceInLca.getOwner())}if(null==e.lca)throw"assert failed"}else e.lca=t.getOwner()},a.prototype.calcLowestCommonAncestor=function(e,t){if(e==t)return e.getOwner();for(var n=e.getOwner();null!=n;){for(var r=t.getOwner();null!=r;){if(r==n)return r;r=r.getParent().getOwner()}n=n.getParent().getOwner()}return n},a.prototype.calcInclusionTreeDepths=function(e,t){var n;null==e&&null==t&&(e=this.rootGraph,t=1);for(var r=e.getNodes(),i=r.length,a=0;a<i;a++)(n=r[a]).inclusionTreeDepth=t,null!=n.child&&this.calcInclusionTreeDepths(n.child,t+1)},a.prototype.includesInvalidEdge=function(){for(var e,t=this.edges.length,n=0;n<t;n++)if(e=this.edges[n],this.isOneAncestorOfOther(e.source,e.target))return!0;return!1},e.exports=a},function(e,t,n){"use strict";var r=n(0);function i(){}for(var a in r)i[a]=r[a];i.MAX_ITERATIONS=2500,i.DEFAULT_EDGE_LENGTH=50,i.DEFAULT_SPRING_STRENGTH=.45,i.DEFAULT_REPULSION_STRENGTH=4500,i.DEFAULT_GRAVITY_STRENGTH=.4,i.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,i.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,i.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,i.COOLING_ADAPTATION_FACTOR=.33,i.ADAPTATION_LOWER_NODE_LIMIT=1e3,i.ADAPTATION_UPPER_NODE_LIMIT=5e3,i.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,i.MAX_NODE_DISPLACEMENT=3*i.MAX_NODE_DISPLACEMENT_INCREMENTAL,i.MIN_REPULSION_DIST=i.DEFAULT_EDGE_LENGTH/10,i.CONVERGENCE_CHECK_PERIOD=100,i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,i.MIN_EDGE_LENGTH=1,i.GRID_CALCULATION_CHECK_PERIOD=10,e.exports=i},function(e,t,n){"use strict";var r=n(12);function i(){}i.calcSeparationAmount=function(e,t,n,r){if(!e.intersects(t))throw"assert failed";var i=new Array(2);this.decideDirectionsForOverlappingNodes(e,t,i),n[0]=Math.min(e.getRight(),t.getRight())-Math.max(e.x,t.x),n[1]=Math.min(e.getBottom(),t.getBottom())-Math.max(e.y,t.y),e.getX()<=t.getX()&&e.getRight()>=t.getRight()?n[0]+=Math.min(t.getX()-e.getX(),e.getRight()-t.getRight()):t.getX()<=e.getX()&&t.getRight()>=e.getRight()&&(n[0]+=Math.min(e.getX()-t.getX(),t.getRight()-e.getRight())),e.getY()<=t.getY()&&e.getBottom()>=t.getBottom()?n[1]+=Math.min(t.getY()-e.getY(),e.getBottom()-t.getBottom()):t.getY()<=e.getY()&&t.getBottom()>=e.getBottom()&&(n[1]+=Math.min(e.getY()-t.getY(),t.getBottom()-e.getBottom()));var a=Math.abs((t.getCenterY()-e.getCenterY())/(t.getCenterX()-e.getCenterX()));t.getCenterY()===e.getCenterY()&&t.getCenterX()===e.getCenterX()&&(a=1);var o=a*n[0],s=n[1]/a;n[0]<s?s=n[0]:o=n[1],n[0]=-1*i[0]*(s/2+r),n[1]=-1*i[1]*(o/2+r)},i.decideDirectionsForOverlappingNodes=function(e,t,n){e.getCenterX()<t.getCenterX()?n[0]=-1:n[0]=1,e.getCenterY()<t.getCenterY()?n[1]=-1:n[1]=1},i.getIntersection2=function(e,t,n){var r=e.getCenterX(),i=e.getCenterY(),a=t.getCenterX(),o=t.getCenterY();if(e.intersects(t))return n[0]=r,n[1]=i,n[2]=a,n[3]=o,!0;var s=e.getX(),l=e.getY(),u=e.getRight(),c=e.getX(),h=e.getBottom(),d=e.getRight(),p=e.getWidthHalf(),g=e.getHeightHalf(),f=t.getX(),v=t.getY(),y=t.getRight(),m=t.getX(),b=t.getBottom(),x=t.getRight(),w=t.getWidthHalf(),E=t.getHeightHalf(),_=!1,T=!1;if(r===a){if(i>o)return n[0]=r,n[1]=l,n[2]=a,n[3]=b,!1;if(i<o)return n[0]=r,n[1]=h,n[2]=a,n[3]=v,!1}else if(i===o){if(r>a)return n[0]=s,n[1]=i,n[2]=y,n[3]=o,!1;if(r<a)return n[0]=u,n[1]=i,n[2]=f,n[3]=o,!1}else{var D=e.height/e.width,C=t.height/t.width,N=(o-i)/(a-r),A=void 0,L=void 0,k=void 0,S=void 0,I=void 0,M=void 0;if(-D===N?r>a?(n[0]=c,n[1]=h,_=!0):(n[0]=u,n[1]=l,_=!0):D===N&&(r>a?(n[0]=s,n[1]=l,_=!0):(n[0]=d,n[1]=h,_=!0)),-C===N?a>r?(n[2]=m,n[3]=b,T=!0):(n[2]=y,n[3]=v,T=!0):C===N&&(a>r?(n[2]=f,n[3]=v,T=!0):(n[2]=x,n[3]=b,T=!0)),_&&T)return!1;if(r>a?i>o?(A=this.getCardinalDirection(D,N,4),L=this.getCardinalDirection(C,N,2)):(A=this.getCardinalDirection(-D,N,3),L=this.getCardinalDirection(-C,N,1)):i>o?(A=this.getCardinalDirection(-D,N,1),L=this.getCardinalDirection(-C,N,3)):(A=this.getCardinalDirection(D,N,2),L=this.getCardinalDirection(C,N,4)),!_)switch(A){case 1:S=l,k=r+-g/N,n[0]=k,n[1]=S;break;case 2:k=d,S=i+p*N,n[0]=k,n[1]=S;break;case 3:S=h,k=r+g/N,n[0]=k,n[1]=S;break;case 4:k=c,S=i+-p*N,n[0]=k,n[1]=S}if(!T)switch(L){case 1:M=v,I=a+-E/N,n[2]=I,n[3]=M;break;case 2:I=x,M=o+w*N,n[2]=I,n[3]=M;break;case 3:M=b,I=a+E/N,n[2]=I,n[3]=M;break;case 4:I=m,M=o+-w*N,n[2]=I,n[3]=M}}return!1},i.getCardinalDirection=function(e,t,n){return e>t?n:1+n%4},i.getIntersection=function(e,t,n,i){if(null==i)return this.getIntersection2(e,t,n);var a,o,s,l,u,c,h,d=e.x,p=e.y,g=t.x,f=t.y,v=n.x,y=n.y,m=i.x,b=i.y;return 0==(h=(a=f-p)*(l=v-m)-(o=b-y)*(s=d-g))?null:new r((s*(c=m*y-v*b)-l*(u=g*p-d*f))/h,(o*u-a*c)/h)},i.angleOfVector=function(e,t,n,r){var i=void 0;return e!==n?(i=Math.atan((r-t)/(n-e)),n<e?i+=Math.PI:r<t&&(i+=this.TWO_PI)):i=r<t?this.ONE_AND_HALF_PI:this.HALF_PI,i},i.doIntersect=function(e,t,n,r){var i=e.x,a=e.y,o=t.x,s=t.y,l=n.x,u=n.y,c=r.x,h=r.y,d=(o-i)*(h-u)-(c-l)*(s-a);if(0===d)return!1;var p=((h-u)*(c-i)+(l-c)*(h-a))/d,g=((a-s)*(c-i)+(o-i)*(h-a))/d;return 0<p&&p<1&&0<g&&g<1},i.HALF_PI=.5*Math.PI,i.ONE_AND_HALF_PI=1.5*Math.PI,i.TWO_PI=2*Math.PI,i.THREE_PI=3*Math.PI,e.exports=i},function(e,t,n){"use strict";function r(){}r.sign=function(e){return e>0?1:e<0?-1:0},r.floor=function(e){return e<0?Math.ceil(e):Math.floor(e)},r.ceil=function(e){return e<0?Math.floor(e):Math.ceil(e)},e.exports=r},function(e,t,n){"use strict";function r(){}r.MAX_VALUE=2147483647,r.MIN_VALUE=-2147483648,e.exports=r},function(e,t,n){"use strict";var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=function(e){return{value:e,next:null,prev:null}},a=function(e,t,n,r){return null!==e?e.next=t:r.head=t,null!==n?n.prev=t:r.tail=t,t.prev=e,t.next=n,r.length++,t},o=function(e,t){var n=e.prev,r=e.next;return null!==n?n.next=r:t.head=r,null!==r?r.prev=n:t.tail=n,e.prev=e.next=null,t.length--,e},s=function(){function e(t){var n=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.length=0,this.head=null,this.tail=null,null!=t&&t.forEach((function(e){return n.push(e)}))}return r(e,[{key:"size",value:function(){return this.length}},{key:"insertBefore",value:function(e,t){return a(t.prev,i(e),t,this)}},{key:"insertAfter",value:function(e,t){return a(t,i(e),t.next,this)}},{key:"insertNodeBefore",value:function(e,t){return a(t.prev,e,t,this)}},{key:"insertNodeAfter",value:function(e,t){return a(t,e,t.next,this)}},{key:"push",value:function(e){return a(this.tail,i(e),null,this)}},{key:"unshift",value:function(e){return a(null,i(e),this.head,this)}},{key:"remove",value:function(e){return o(e,this)}},{key:"pop",value:function(){return o(this.tail,this).value}},{key:"popNode",value:function(){return o(this.tail,this)}},{key:"shift",value:function(){return o(this.head,this).value}},{key:"shiftNode",value:function(){return o(this.head,this)}},{key:"get_object_at",value:function(e){if(e<=this.length()){for(var t=1,n=this.head;t<e;)n=n.next,t++;return n.value}}},{key:"set_object_at",value:function(e,t){if(e<=this.length()){for(var n=1,r=this.head;n<e;)r=r.next,n++;r.value=t}}}]),e}();e.exports=s},function(e,t,n){"use strict";function r(e,t,n){this.x=null,this.y=null,null==e&&null==t&&null==n?(this.x=0,this.y=0):"number"==typeof e&&"number"==typeof t&&null==n?(this.x=e,this.y=t):"Point"==e.constructor.name&&null==t&&null==n&&(n=e,this.x=n.x,this.y=n.y)}r.prototype.getX=function(){return this.x},r.prototype.getY=function(){return this.y},r.prototype.getLocation=function(){return new r(this.x,this.y)},r.prototype.setLocation=function(e,t,n){"Point"==e.constructor.name&&null==t&&null==n?(n=e,this.setLocation(n.x,n.y)):"number"==typeof e&&"number"==typeof t&&null==n&&(parseInt(e)==e&&parseInt(t)==t?this.move(e,t):(this.x=Math.floor(e+.5),this.y=Math.floor(t+.5)))},r.prototype.move=function(e,t){this.x=e,this.y=t},r.prototype.translate=function(e,t){this.x+=e,this.y+=t},r.prototype.equals=function(e){if("Point"==e.constructor.name){var t=e;return this.x==t.x&&this.y==t.y}return this==e},r.prototype.toString=function(){return(new r).constructor.name+"[x="+this.x+",y="+this.y+"]"},e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){this.x=0,this.y=0,this.width=0,this.height=0,null!=e&&null!=t&&null!=n&&null!=r&&(this.x=e,this.y=t,this.width=n,this.height=r)}r.prototype.getX=function(){return this.x},r.prototype.setX=function(e){this.x=e},r.prototype.getY=function(){return this.y},r.prototype.setY=function(e){this.y=e},r.prototype.getWidth=function(){return this.width},r.prototype.setWidth=function(e){this.width=e},r.prototype.getHeight=function(){return this.height},r.prototype.setHeight=function(e){this.height=e},r.prototype.getRight=function(){return this.x+this.width},r.prototype.getBottom=function(){return this.y+this.height},r.prototype.intersects=function(e){return!(this.getRight()<e.x||this.getBottom()<e.y||e.getRight()<this.x||e.getBottom()<this.y)},r.prototype.getCenterX=function(){return this.x+this.width/2},r.prototype.getMinX=function(){return this.getX()},r.prototype.getMaxX=function(){return this.getX()+this.width},r.prototype.getCenterY=function(){return this.y+this.height/2},r.prototype.getMinY=function(){return this.getY()},r.prototype.getMaxY=function(){return this.getY()+this.height},r.prototype.getWidthHalf=function(){return this.width/2},r.prototype.getHeightHalf=function(){return this.height/2},e.exports=r},function(e,t,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function i(){}i.lastID=0,i.createID=function(e){return i.isPrimitive(e)?e:(null!=e.uniqueID||(e.uniqueID=i.getString(),i.lastID++),e.uniqueID)},i.getString=function(e){return null==e&&(e=i.lastID),"Object#"+e},i.isPrimitive=function(e){var t=void 0===e?"undefined":r(e);return null==e||"object"!=t&&"function"!=t},e.exports=i},function(e,t,n){"use strict";function r(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}var i=n(0),a=n(6),o=n(3),s=n(1),l=n(5),u=n(4),c=n(17),h=n(27);function d(e){h.call(this),this.layoutQuality=i.QUALITY,this.createBendsAsNeeded=i.DEFAULT_CREATE_BENDS_AS_NEEDED,this.incremental=i.DEFAULT_INCREMENTAL,this.animationOnLayout=i.DEFAULT_ANIMATION_ON_LAYOUT,this.animationDuringLayout=i.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=i.DEFAULT_ANIMATION_PERIOD,this.uniformLeafNodeSizes=i.DEFAULT_UNIFORM_LEAF_NODE_SIZES,this.edgeToDummyNodes=new Map,this.graphManager=new a(this),this.isLayoutFinished=!1,this.isSubLayout=!1,this.isRemoteUse=!1,null!=e&&(this.isRemoteUse=e)}d.RANDOM_SEED=1,d.prototype=Object.create(h.prototype),d.prototype.getGraphManager=function(){return this.graphManager},d.prototype.getAllNodes=function(){return this.graphManager.getAllNodes()},d.prototype.getAllEdges=function(){return this.graphManager.getAllEdges()},d.prototype.getAllNodesToApplyGravitation=function(){return this.graphManager.getAllNodesToApplyGravitation()},d.prototype.newGraphManager=function(){var e=new a(this);return this.graphManager=e,e},d.prototype.newGraph=function(e){return new l(null,this.graphManager,e)},d.prototype.newNode=function(e){return new o(this.graphManager,e)},d.prototype.newEdge=function(e){return new s(null,null,e)},d.prototype.checkLayoutSuccess=function(){return null==this.graphManager.getRoot()||0==this.graphManager.getRoot().getNodes().length||this.graphManager.includesInvalidEdge()},d.prototype.runLayout=function(){var e;return this.isLayoutFinished=!1,this.tilingPreLayout&&this.tilingPreLayout(),this.initParameters(),e=!this.checkLayoutSuccess()&&this.layout(),"during"!==i.ANIMATE&&(e&&(this.isSubLayout||this.doPostLayout()),this.tilingPostLayout&&this.tilingPostLayout(),this.isLayoutFinished=!0,e)},d.prototype.doPostLayout=function(){this.incremental||this.transform(),this.update()},d.prototype.update2=function(){if(this.createBendsAsNeeded&&(this.createBendpointsFromDummyNodes(),this.graphManager.resetAllEdges()),!this.isRemoteUse){for(var e=this.graphManager.getAllEdges(),t=0;t<e.length;t++)e[t];var n=this.graphManager.getRoot().getNodes();for(t=0;t<n.length;t++)n[t];this.update(this.graphManager.getRoot())}},d.prototype.update=function(e){if(null==e)this.update2();else if(e instanceof o){var t=e;if(null!=t.getChild())for(var n=t.getChild().getNodes(),r=0;r<n.length;r++)update(n[r]);null!=t.vGraphObject&&t.vGraphObject.update(t)}else if(e instanceof s){var i=e;null!=i.vGraphObject&&i.vGraphObject.update(i)}else if(e instanceof l){var a=e;null!=a.vGraphObject&&a.vGraphObject.update(a)}},d.prototype.initParameters=function(){this.isSubLayout||(this.layoutQuality=i.QUALITY,this.animationDuringLayout=i.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=i.DEFAULT_ANIMATION_PERIOD,this.animationOnLayout=i.DEFAULT_ANIMATION_ON_LAYOUT,this.incremental=i.DEFAULT_INCREMENTAL,this.createBendsAsNeeded=i.DEFAULT_CREATE_BENDS_AS_NEEDED,this.uniformLeafNodeSizes=i.DEFAULT_UNIFORM_LEAF_NODE_SIZES),this.animationDuringLayout&&(this.animationOnLayout=!1)},d.prototype.transform=function(e){if(null==e)this.transform(new u(0,0));else{var t=new c,n=this.graphManager.getRoot().updateLeftTop();if(null!=n){t.setWorldOrgX(e.x),t.setWorldOrgY(e.y),t.setDeviceOrgX(n.x),t.setDeviceOrgY(n.y);for(var r=this.getAllNodes(),i=0;i<r.length;i++)r[i].transform(t)}}},d.prototype.positionNodesRandomly=function(e){if(null==e)this.positionNodesRandomly(this.getGraphManager().getRoot()),this.getGraphManager().getRoot().updateBounds(!0);else for(var t,n,r=e.getNodes(),i=0;i<r.length;i++)null==(n=(t=r[i]).getChild())||0==n.getNodes().length?t.scatter():(this.positionNodesRandomly(n),t.updateBounds())},d.prototype.getFlatForest=function(){for(var e=[],t=!0,n=this.graphManager.getRoot().getNodes(),i=!0,a=0;a<n.length;a++)null!=n[a].getChild()&&(i=!1);if(!i)return e;var o=new Set,s=[],l=new Map,u=[];for(u=u.concat(n);u.length>0&&t;){for(s.push(u[0]);s.length>0&&t;){var c=s[0];s.splice(0,1),o.add(c);var h=c.getEdges();for(a=0;a<h.length;a++){var d=h[a].getOtherEnd(c);if(l.get(c)!=d){if(o.has(d)){t=!1;break}s.push(d),l.set(d,c)}}}if(t){var p=[].concat(r(o));for(e.push(p),a=0;a<p.length;a++){var g=p[a],f=u.indexOf(g);f>-1&&u.splice(f,1)}o=new Set,l=new Map}else e=[]}return e},d.prototype.createDummyNodesForBendpoints=function(e){for(var t=[],n=e.source,r=this.graphManager.calcLowestCommonAncestor(e.source,e.target),i=0;i<e.bendpoints.length;i++){var a=this.newNode(null);a.setRect(new Point(0,0),new Dimension(1,1)),r.add(a);var o=this.newEdge(null);this.graphManager.add(o,n,a),t.add(a),n=a}return o=this.newEdge(null),this.graphManager.add(o,n,e.target),this.edgeToDummyNodes.set(e,t),e.isInterGraph()?this.graphManager.remove(e):r.remove(e),t},d.prototype.createBendpointsFromDummyNodes=function(){var e=[];e=e.concat(this.graphManager.getAllEdges()),e=[].concat(r(this.edgeToDummyNodes.keys())).concat(e);for(var t=0;t<e.length;t++){var n=e[t];if(n.bendpoints.length>0){for(var i=this.edgeToDummyNodes.get(n),a=0;a<i.length;a++){var o=i[a],s=new u(o.getCenterX(),o.getCenterY()),l=n.bendpoints.get(a);l.x=s.x,l.y=s.y,o.getOwner().remove(o)}this.graphManager.add(n,n.source,n.target)}}},d.transform=function(e,t,n,r){if(null!=n&&null!=r){var i=t;return e<=50?i-=(t-t/n)/50*(50-e):i+=(t*r-t)/50*(e-50),i}var a,o;return e<=50?(a=9*t/500,o=t/10):(a=9*t/50,o=-8*t),a*e+o},d.findCenterOfTree=function(e){var t=[];t=t.concat(e);var n=[],r=new Map,i=!1,a=null;1!=t.length&&2!=t.length||(i=!0,a=t[0]);for(var o=0;o<t.length;o++){var s=(c=t[o]).getNeighborsList().size;r.set(c,c.getNeighborsList().size),1==s&&n.push(c)}var l=[];for(l=l.concat(n);!i;){var u=[];for(u=u.concat(l),l=[],o=0;o<t.length;o++){var c=t[o],h=t.indexOf(c);h>=0&&t.splice(h,1),c.getNeighborsList().forEach((function(e){if(n.indexOf(e)<0){var t=r.get(e)-1;1==t&&l.push(e),r.set(e,t)}}))}n=n.concat(l),1!=t.length&&2!=t.length||(i=!0,a=t[0])}return a},d.prototype.setGraphManager=function(e){this.graphManager=e},e.exports=d},function(e,t,n){"use strict";function r(){}r.seed=1,r.x=0,r.nextDouble=function(){return r.x=1e4*Math.sin(r.seed++),r.x-Math.floor(r.x)},e.exports=r},function(e,t,n){"use strict";var r=n(4);function i(e,t){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}i.prototype.getWorldOrgX=function(){return this.lworldOrgX},i.prototype.setWorldOrgX=function(e){this.lworldOrgX=e},i.prototype.getWorldOrgY=function(){return this.lworldOrgY},i.prototype.setWorldOrgY=function(e){this.lworldOrgY=e},i.prototype.getWorldExtX=function(){return this.lworldExtX},i.prototype.setWorldExtX=function(e){this.lworldExtX=e},i.prototype.getWorldExtY=function(){return this.lworldExtY},i.prototype.setWorldExtY=function(e){this.lworldExtY=e},i.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},i.prototype.setDeviceOrgX=function(e){this.ldeviceOrgX=e},i.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},i.prototype.setDeviceOrgY=function(e){this.ldeviceOrgY=e},i.prototype.getDeviceExtX=function(){return this.ldeviceExtX},i.prototype.setDeviceExtX=function(e){this.ldeviceExtX=e},i.prototype.getDeviceExtY=function(){return this.ldeviceExtY},i.prototype.setDeviceExtY=function(e){this.ldeviceExtY=e},i.prototype.transformX=function(e){var t=0,n=this.lworldExtX;return 0!=n&&(t=this.ldeviceOrgX+(e-this.lworldOrgX)*this.ldeviceExtX/n),t},i.prototype.transformY=function(e){var t=0,n=this.lworldExtY;return 0!=n&&(t=this.ldeviceOrgY+(e-this.lworldOrgY)*this.ldeviceExtY/n),t},i.prototype.inverseTransformX=function(e){var t=0,n=this.ldeviceExtX;return 0!=n&&(t=this.lworldOrgX+(e-this.ldeviceOrgX)*this.lworldExtX/n),t},i.prototype.inverseTransformY=function(e){var t=0,n=this.ldeviceExtY;return 0!=n&&(t=this.lworldOrgY+(e-this.ldeviceOrgY)*this.lworldExtY/n),t},i.prototype.inverseTransformPoint=function(e){return new r(this.inverseTransformX(e.x),this.inverseTransformY(e.y))},e.exports=i},function(e,t,n){"use strict";var r=n(15),i=n(7),a=n(0),o=n(8),s=n(9);function l(){r.call(this),this.useSmartIdealEdgeLengthCalculation=i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.idealEdgeLength=i.DEFAULT_EDGE_LENGTH,this.springConstant=i.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=i.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=i.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=i.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=i.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*i.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=i.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=i.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=i.MAX_ITERATIONS}for(var u in l.prototype=Object.create(r.prototype),r)l[u]=r[u];l.prototype.initParameters=function(){r.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},l.prototype.calcIdealEdgeLengths=function(){for(var e,t,n,r,o,s,l=this.getGraphManager().getAllEdges(),u=0;u<l.length;u++)(e=l[u]).idealLength=this.idealEdgeLength,e.isInterGraph&&(n=e.getSource(),r=e.getTarget(),o=e.getSourceInLca().getEstimatedSize(),s=e.getTargetInLca().getEstimatedSize(),this.useSmartIdealEdgeLengthCalculation&&(e.idealLength+=o+s-2*a.SIMPLE_NODE_SIZE),t=e.getLca().getInclusionTreeDepth(),e.idealLength+=i.DEFAULT_EDGE_LENGTH*i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR*(n.getInclusionTreeDepth()+r.getInclusionTreeDepth()-2*t))},l.prototype.initSpringEmbedder=function(){var e=this.getAllNodes().length;this.incremental?(e>i.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*i.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(e-i.ADAPTATION_LOWER_NODE_LIMIT)/(i.ADAPTATION_UPPER_NODE_LIMIT-i.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-i.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=i.MAX_NODE_DISPLACEMENT_INCREMENTAL):(e>i.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(i.COOLING_ADAPTATION_FACTOR,1-(e-i.ADAPTATION_LOWER_NODE_LIMIT)/(i.ADAPTATION_UPPER_NODE_LIMIT-i.ADAPTATION_LOWER_NODE_LIMIT)*(1-i.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=i.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(5*this.getAllNodes().length,this.maxIterations),this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},l.prototype.calcSpringForces=function(){for(var e,t=this.getAllEdges(),n=0;n<t.length;n++)e=t[n],this.calcSpringForce(e,e.idealLength)},l.prototype.calcRepulsionForces=function(){var e,t,n,r,a,o=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],s=arguments.length>1&&void 0!==arguments[1]&&arguments[1],l=this.getAllNodes();if(this.useFRGridVariant)for(this.totalIterations%i.GRID_CALCULATION_CHECK_PERIOD==1&&o&&this.updateGrid(),a=new Set,e=0;e<l.length;e++)n=l[e],this.calculateRepulsionForceOfANode(n,a,o,s),a.add(n);else for(e=0;e<l.length;e++)for(n=l[e],t=e+1;t<l.length;t++)r=l[t],n.getOwner()==r.getOwner()&&this.calcRepulsionForce(n,r)},l.prototype.calcGravitationalForces=function(){for(var e,t=this.getAllNodesToApplyGravitation(),n=0;n<t.length;n++)e=t[n],this.calcGravitationalForce(e)},l.prototype.moveNodes=function(){for(var e=this.getAllNodes(),t=0;t<e.length;t++)e[t].move()},l.prototype.calcSpringForce=function(e,t){var n,r,i,a,o=e.getSource(),s=e.getTarget();if(this.uniformLeafNodeSizes&&null==o.getChild()&&null==s.getChild())e.updateLengthSimple();else if(e.updateLength(),e.isOverlapingSourceAndTarget)return;0!=(n=e.getLength())&&(i=(r=this.springConstant*(n-t))*(e.lengthX/n),a=r*(e.lengthY/n),o.springForceX+=i,o.springForceY+=a,s.springForceX-=i,s.springForceY-=a)},l.prototype.calcRepulsionForce=function(e,t){var n,r,a,l,u,c,h,d=e.getRect(),p=t.getRect(),g=new Array(2),f=new Array(4);if(d.intersects(p)){o.calcSeparationAmount(d,p,g,i.DEFAULT_EDGE_LENGTH/2),c=2*g[0],h=2*g[1];var v=e.noOfChildren*t.noOfChildren/(e.noOfChildren+t.noOfChildren);e.repulsionForceX-=v*c,e.repulsionForceY-=v*h,t.repulsionForceX+=v*c,t.repulsionForceY+=v*h}else this.uniformLeafNodeSizes&&null==e.getChild()&&null==t.getChild()?(n=p.getCenterX()-d.getCenterX(),r=p.getCenterY()-d.getCenterY()):(o.getIntersection(d,p,f),n=f[2]-f[0],r=f[3]-f[1]),Math.abs(n)<i.MIN_REPULSION_DIST&&(n=s.sign(n)*i.MIN_REPULSION_DIST),Math.abs(r)<i.MIN_REPULSION_DIST&&(r=s.sign(r)*i.MIN_REPULSION_DIST),a=n*n+r*r,l=Math.sqrt(a),c=(u=this.repulsionConstant*e.noOfChildren*t.noOfChildren/a)*n/l,h=u*r/l,e.repulsionForceX-=c,e.repulsionForceY-=h,t.repulsionForceX+=c,t.repulsionForceY+=h},l.prototype.calcGravitationalForce=function(e){var t,n,r,i,a,o,s,l;n=((t=e.getOwner()).getRight()+t.getLeft())/2,r=(t.getTop()+t.getBottom())/2,i=e.getCenterX()-n,a=e.getCenterY()-r,o=Math.abs(i)+e.getWidth()/2,s=Math.abs(a)+e.getHeight()/2,e.getOwner()==this.graphManager.getRoot()?(o>(l=t.getEstimatedSize()*this.gravityRangeFactor)||s>l)&&(e.gravitationForceX=-this.gravityConstant*i,e.gravitationForceY=-this.gravityConstant*a):(o>(l=t.getEstimatedSize()*this.compoundGravityRangeFactor)||s>l)&&(e.gravitationForceX=-this.gravityConstant*i*this.compoundGravityConstant,e.gravitationForceY=-this.gravityConstant*a*this.compoundGravityConstant)},l.prototype.isConverged=function(){var e,t=!1;return this.totalIterations>this.maxIterations/3&&(t=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),e=this.totalDisplacement<this.totalDisplacementThreshold,this.oldTotalDisplacement=this.totalDisplacement,e||t},l.prototype.animate=function(){this.animationDuringLayout&&!this.isSubLayout&&(this.notAnimatedIterations==this.animationPeriod?(this.update(),this.notAnimatedIterations=0):this.notAnimatedIterations++)},l.prototype.calcNoOfChildrenForAllNodes=function(){for(var e,t=this.graphManager.getAllNodes(),n=0;n<t.length;n++)(e=t[n]).noOfChildren=e.getNoOfChildren()},l.prototype.calcGrid=function(e){var t,n;t=parseInt(Math.ceil((e.getRight()-e.getLeft())/this.repulsionRange)),n=parseInt(Math.ceil((e.getBottom()-e.getTop())/this.repulsionRange));for(var r=new Array(t),i=0;i<t;i++)r[i]=new Array(n);for(i=0;i<t;i++)for(var a=0;a<n;a++)r[i][a]=new Array;return r},l.prototype.addNodeToGrid=function(e,t,n){var r,i,a,o;r=parseInt(Math.floor((e.getRect().x-t)/this.repulsionRange)),i=parseInt(Math.floor((e.getRect().width+e.getRect().x-t)/this.repulsionRange)),a=parseInt(Math.floor((e.getRect().y-n)/this.repulsionRange)),o=parseInt(Math.floor((e.getRect().height+e.getRect().y-n)/this.repulsionRange));for(var s=r;s<=i;s++)for(var l=a;l<=o;l++)this.grid[s][l].push(e),e.setGridCoordinates(r,i,a,o)},l.prototype.updateGrid=function(){var e,t,n=this.getAllNodes();for(this.grid=this.calcGrid(this.graphManager.getRoot()),e=0;e<n.length;e++)t=n[e],this.addNodeToGrid(t,this.graphManager.getRoot().getLeft(),this.graphManager.getRoot().getTop())},l.prototype.calculateRepulsionForceOfANode=function(e,t,n,r){if(this.totalIterations%i.GRID_CALCULATION_CHECK_PERIOD==1&&n||r){var a,o=new Set;e.surrounding=new Array;for(var s=this.grid,l=e.startX-1;l<e.finishX+2;l++)for(var u=e.startY-1;u<e.finishY+2;u++)if(!(l<0||u<0||l>=s.length||u>=s[0].length))for(var c=0;c<s[l][u].length;c++)if(a=s[l][u][c],e.getOwner()==a.getOwner()&&e!=a&&!t.has(a)&&!o.has(a)){var h=Math.abs(e.getCenterX()-a.getCenterX())-(e.getWidth()/2+a.getWidth()/2),d=Math.abs(e.getCenterY()-a.getCenterY())-(e.getHeight()/2+a.getHeight()/2);h<=this.repulsionRange&&d<=this.repulsionRange&&o.add(a)}e.surrounding=[].concat(function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}(o))}for(l=0;l<e.surrounding.length;l++)this.calcRepulsionForce(e,e.surrounding[l])},l.prototype.calcRepulsionRange=function(){return 0},e.exports=l},function(e,t,n){"use strict";var r=n(1),i=n(7);function a(e,t,n){r.call(this,e,t,n),this.idealLength=i.DEFAULT_EDGE_LENGTH}for(var o in a.prototype=Object.create(r.prototype),r)a[o]=r[o];e.exports=a},function(e,t,n){"use strict";var r=n(3);function i(e,t,n,i){r.call(this,e,t,n,i),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0,this.startX=0,this.finishX=0,this.startY=0,this.finishY=0,this.surrounding=[]}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];i.prototype.setGridCoordinates=function(e,t,n,r){this.startX=e,this.finishX=t,this.startY=n,this.finishY=r},e.exports=i},function(e,t,n){"use strict";function r(e,t){this.width=0,this.height=0,null!==e&&null!==t&&(this.height=t,this.width=e)}r.prototype.getWidth=function(){return this.width},r.prototype.setWidth=function(e){this.width=e},r.prototype.getHeight=function(){return this.height},r.prototype.setHeight=function(e){this.height=e},e.exports=r},function(e,t,n){"use strict";var r=n(14);function i(){this.map={},this.keys=[]}i.prototype.put=function(e,t){var n=r.createID(e);this.contains(n)||(this.map[n]=t,this.keys.push(e))},i.prototype.contains=function(e){return r.createID(e),null!=this.map[e]},i.prototype.get=function(e){var t=r.createID(e);return this.map[t]},i.prototype.keySet=function(){return this.keys},e.exports=i},function(e,t,n){"use strict";var r=n(14);function i(){this.set={}}i.prototype.add=function(e){var t=r.createID(e);this.contains(t)||(this.set[t]=e)},i.prototype.remove=function(e){delete this.set[r.createID(e)]},i.prototype.clear=function(){this.set={}},i.prototype.contains=function(e){return this.set[r.createID(e)]==e},i.prototype.isEmpty=function(){return 0===this.size()},i.prototype.size=function(){return Object.keys(this.set).length},i.prototype.addAllTo=function(e){for(var t=Object.keys(this.set),n=t.length,r=0;r<n;r++)e.push(this.set[t[r]])},i.prototype.size=function(){return Object.keys(this.set).length},i.prototype.addAll=function(e){for(var t=e.length,n=0;n<t;n++){var r=e[n];this.add(r)}},e.exports=i},function(e,t,n){"use strict";var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=n(11),a=function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),null===n&&void 0===n||(this.compareFunction=this._defaultCompareFunction);var r=void 0;r=t instanceof i?t.size():t.length,this._quicksort(t,0,r-1)}return r(e,[{key:"_quicksort",value:function(e,t,n){if(t<n){var r=this._partition(e,t,n);this._quicksort(e,t,r),this._quicksort(e,r+1,n)}}},{key:"_partition",value:function(e,t,n){for(var r=this._get(e,t),i=t,a=n;;){for(;this.compareFunction(r,this._get(e,a));)a--;for(;this.compareFunction(this._get(e,i),r);)i++;if(!(i<a))return a;this._swap(e,i,a),i++,a--}}},{key:"_get",value:function(e,t){return e instanceof i?e.get_object_at(t):e[t]}},{key:"_set",value:function(e,t,n){e instanceof i?e.set_object_at(t,n):e[t]=n}},{key:"_swap",value:function(e,t,n){var r=this._get(e,t);this._set(e,t,this._get(e,n)),this._set(e,n,r)}},{key:"_defaultCompareFunction",value:function(e,t){return t>e}}]),e}();e.exports=a},function(e,t,n){"use strict";var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=function(){function e(t,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:-1,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.sequence1=t,this.sequence2=n,this.match_score=r,this.mismatch_penalty=i,this.gap_penalty=a,this.iMax=t.length+1,this.jMax=n.length+1,this.grid=new Array(this.iMax);for(var o=0;o<this.iMax;o++){this.grid[o]=new Array(this.jMax);for(var s=0;s<this.jMax;s++)this.grid[o][s]=0}this.tracebackGrid=new Array(this.iMax);for(var l=0;l<this.iMax;l++){this.tracebackGrid[l]=new Array(this.jMax);for(var u=0;u<this.jMax;u++)this.tracebackGrid[l][u]=[null,null,null]}this.alignments=[],this.score=-1,this.computeGrids()}return r(e,[{key:"getScore",value:function(){return this.score}},{key:"getAlignments",value:function(){return this.alignments}},{key:"computeGrids",value:function(){for(var e=1;e<this.jMax;e++)this.grid[0][e]=this.grid[0][e-1]+this.gap_penalty,this.tracebackGrid[0][e]=[!1,!1,!0];for(var t=1;t<this.iMax;t++)this.grid[t][0]=this.grid[t-1][0]+this.gap_penalty,this.tracebackGrid[t][0]=[!1,!0,!1];for(var n=1;n<this.iMax;n++)for(var r=1;r<this.jMax;r++){var i=[this.sequence1[n-1]===this.sequence2[r-1]?this.grid[n-1][r-1]+this.match_score:this.grid[n-1][r-1]+this.mismatch_penalty,this.grid[n-1][r]+this.gap_penalty,this.grid[n][r-1]+this.gap_penalty],a=this.arrayAllMaxIndexes(i);this.grid[n][r]=i[a[0]],this.tracebackGrid[n][r]=[a.includes(0),a.includes(1),a.includes(2)]}this.score=this.grid[this.iMax-1][this.jMax-1]}},{key:"alignmentTraceback",value:function(){var e=[];for(e.push({pos:[this.sequence1.length,this.sequence2.length],seq1:"",seq2:""});e[0];){var t=e[0],n=this.tracebackGrid[t.pos[0]][t.pos[1]];n[0]&&e.push({pos:[t.pos[0]-1,t.pos[1]-1],seq1:this.sequence1[t.pos[0]-1]+t.seq1,seq2:this.sequence2[t.pos[1]-1]+t.seq2}),n[1]&&e.push({pos:[t.pos[0]-1,t.pos[1]],seq1:this.sequence1[t.pos[0]-1]+t.seq1,seq2:"-"+t.seq2}),n[2]&&e.push({pos:[t.pos[0],t.pos[1]-1],seq1:"-"+t.seq1,seq2:this.sequence2[t.pos[1]-1]+t.seq2}),0===t.pos[0]&&0===t.pos[1]&&this.alignments.push({sequence1:t.seq1,sequence2:t.seq2}),e.shift()}return this.alignments}},{key:"getAllIndexes",value:function(e,t){for(var n=[],r=-1;-1!==(r=e.indexOf(t,r+1));)n.push(r);return n}},{key:"arrayAllMaxIndexes",value:function(e){return this.getAllIndexes(e,Math.max.apply(null,e))}}]),e}();e.exports=i},function(e,t,n){"use strict";var r=function(){};r.FDLayout=n(18),r.FDLayoutConstants=n(7),r.FDLayoutEdge=n(19),r.FDLayoutNode=n(20),r.DimensionD=n(21),r.HashMap=n(22),r.HashSet=n(23),r.IGeometry=n(8),r.IMath=n(9),r.Integer=n(10),r.Point=n(12),r.PointD=n(4),r.RandomSeed=n(16),r.RectangleD=n(13),r.Transform=n(17),r.UniqueIDGeneretor=n(14),r.Quicksort=n(24),r.LinkedList=n(11),r.LGraphObject=n(2),r.LGraph=n(5),r.LEdge=n(1),r.LGraphManager=n(6),r.LNode=n(3),r.Layout=n(15),r.LayoutConstants=n(0),r.NeedlemanWunsch=n(25),e.exports=r},function(e,t,n){"use strict";function r(){this.listeners=[]}var i=r.prototype;i.addListener=function(e,t){this.listeners.push({event:e,callback:t})},i.removeListener=function(e,t){for(var n=this.listeners.length;n>=0;n--){var r=this.listeners[n];r.event===e&&r.callback===t&&this.listeners.splice(n,1)}},i.emit=function(e,t){for(var n=0;n<this.listeners.length;n++){var r=this.listeners[n];e===r.event&&r.callback(t)}},e.exports=r}])},e.exports=t()},21549:(e,t,n)=>{var r=n(22032),i=n(63862),a=n(66721),o=n(12749),s=n(35749);function l(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}l.prototype.clear=r,l.prototype.delete=i,l.prototype.get=a,l.prototype.has=o,l.prototype.set=s,e.exports=l},80079:(e,t,n)=>{var r=n(63702),i=n(70080),a=n(24739),o=n(48655),s=n(31175);function l(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}l.prototype.clear=r,l.prototype.delete=i,l.prototype.get=a,l.prototype.has=o,l.prototype.set=s,e.exports=l},68223:(e,t,n)=>{var r=n(56110)(n(9325),"Map");e.exports=r},53661:(e,t,n)=>{var r=n(63040),i=n(17670),a=n(90289),o=n(4509),s=n(72949);function l(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}l.prototype.clear=r,l.prototype.delete=i,l.prototype.get=a,l.prototype.has=o,l.prototype.set=s,e.exports=l},51873:(e,t,n)=>{var r=n(9325).Symbol;e.exports=r},34932:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length,i=Array(r);++n<r;)i[n]=t(e[n],n,e);return i}},16547:(e,t,n)=>{var r=n(43360),i=n(75288),a=Object.prototype.hasOwnProperty;e.exports=function(e,t,n){var o=e[t];a.call(e,t)&&i(o,n)&&(void 0!==n||t in e)||r(e,t,n)}},26025:(e,t,n)=>{var r=n(75288);e.exports=function(e,t){for(var n=e.length;n--;)if(r(e[n][0],t))return n;return-1}},43360:(e,t,n)=>{var r=n(93243);e.exports=function(e,t,n){"__proto__"==t&&r?r(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0}):e[t]=n}},47422:(e,t,n)=>{var r=n(31769),i=n(77797);e.exports=function(e,t){for(var n=0,a=(t=r(t,e)).length;null!=e&&n<a;)e=e[i(t[n++])];return n&&n==a?e:void 0}},72552:(e,t,n)=>{var r=n(51873),i=n(659),a=n(59350),o=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":o&&o in Object(e)?i(e):a(e)}},45083:(e,t,n)=>{var r=n(1882),i=n(87296),a=n(23805),o=n(47473),s=/^\[object .+?Constructor\]$/,l=Function.prototype,u=Object.prototype,c=l.toString,h=u.hasOwnProperty,d=RegExp("^"+c.call(h).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");e.exports=function(e){return!(!a(e)||i(e))&&(r(e)?d:s).test(o(e))}},73170:(e,t,n)=>{var r=n(16547),i=n(31769),a=n(30361),o=n(23805),s=n(77797);e.exports=function(e,t,n,l){if(!o(e))return e;for(var u=-1,c=(t=i(t,e)).length,h=c-1,d=e;null!=d&&++u<c;){var p=s(t[u]),g=n;if("__proto__"===p||"constructor"===p||"prototype"===p)return e;if(u!=h){var f=d[p];void 0===(g=l?l(f,p,d):void 0)&&(g=o(f)?f:a(t[u+1])?[]:{})}r(d,p,g),d=d[p]}return e}},77556:(e,t,n)=>{var r=n(51873),i=n(34932),a=n(56449),o=n(44394),s=r?r.prototype:void 0,l=s?s.toString:void 0;e.exports=function e(t){if("string"==typeof t)return t;if(a(t))return i(t,e)+"";if(o(t))return l?l.call(t):"";var n=t+"";return"0"==n&&1/t==-1/0?"-0":n}},54128:(e,t,n)=>{var r=n(31800),i=/^\s+/;e.exports=function(e){return e?e.slice(0,r(e)+1).replace(i,""):e}},31769:(e,t,n)=>{var r=n(56449),i=n(28586),a=n(61802),o=n(13222);e.exports=function(e,t){return r(e)?e:i(e,t)?[e]:a(o(e))}},23007:e=>{e.exports=function(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n<r;)t[n]=e[n];return t}},55481:(e,t,n)=>{var r=n(9325)["__core-js_shared__"];e.exports=r},93243:(e,t,n)=>{var r=n(56110),i=function(){try{var e=r(Object,"defineProperty");return e({},"",{}),e}catch(t){}}();e.exports=i},34840:(e,t,n)=>{var r="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g;e.exports=r},12651:(e,t,n)=>{var r=n(74218);e.exports=function(e,t){var n=e.__data__;return r(t)?n["string"==typeof t?"string":"hash"]:n.map}},56110:(e,t,n)=>{var r=n(45083),i=n(10392);e.exports=function(e,t){var n=i(e,t);return r(n)?n:void 0}},659:(e,t,n)=>{var r=n(51873),i=Object.prototype,a=i.hasOwnProperty,o=i.toString,s=r?r.toStringTag:void 0;e.exports=function(e){var t=a.call(e,s),n=e[s];try{e[s]=void 0;var r=!0}catch(l){}var i=o.call(e);return r&&(t?e[s]=n:delete e[s]),i}},10392:e=>{e.exports=function(e,t){return null==e?void 0:e[t]}},22032:(e,t,n)=>{var r=n(81042);e.exports=function(){this.__data__=r?r(null):{},this.size=0}},63862:e=>{e.exports=function(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}},66721:(e,t,n)=>{var r=n(81042),i=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;if(r){var n=t[e];return"__lodash_hash_undefined__"===n?void 0:n}return i.call(t,e)?t[e]:void 0}},12749:(e,t,n)=>{var r=n(81042),i=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;return r?void 0!==t[e]:i.call(t,e)}},35749:(e,t,n)=>{var r=n(81042);e.exports=function(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=r&&void 0===t?"__lodash_hash_undefined__":t,this}},30361:e=>{var t=/^(?:0|[1-9]\d*)$/;e.exports=function(e,n){var r=typeof e;return!!(n=null==n?9007199254740991:n)&&("number"==r||"symbol"!=r&&t.test(e))&&e>-1&&e%1==0&&e<n}},28586:(e,t,n)=>{var r=n(56449),i=n(44394),a=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,o=/^\w*$/;e.exports=function(e,t){if(r(e))return!1;var n=typeof e;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=e&&!i(e))||(o.test(e)||!a.test(e)||null!=t&&e in Object(t))}},74218:e=>{e.exports=function(e){var t=typeof e;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==e:null===e}},87296:(e,t,n)=>{var r,i=n(55481),a=(r=/[^.]+$/.exec(i&&i.keys&&i.keys.IE_PROTO||""))?"Symbol(src)_1."+r:"";e.exports=function(e){return!!a&&a in e}},63702:e=>{e.exports=function(){this.__data__=[],this.size=0}},70080:(e,t,n)=>{var r=n(26025),i=Array.prototype.splice;e.exports=function(e){var t=this.__data__,n=r(t,e);return!(n<0)&&(n==t.length-1?t.pop():i.call(t,n,1),--this.size,!0)}},24739:(e,t,n)=>{var r=n(26025);e.exports=function(e){var t=this.__data__,n=r(t,e);return n<0?void 0:t[n][1]}},48655:(e,t,n)=>{var r=n(26025);e.exports=function(e){return r(this.__data__,e)>-1}},31175:(e,t,n)=>{var r=n(26025);e.exports=function(e,t){var n=this.__data__,i=r(n,e);return i<0?(++this.size,n.push([e,t])):n[i][1]=t,this}},63040:(e,t,n)=>{var r=n(21549),i=n(80079),a=n(68223);e.exports=function(){this.size=0,this.__data__={hash:new r,map:new(a||i),string:new r}}},17670:(e,t,n)=>{var r=n(12651);e.exports=function(e){var t=r(this,e).delete(e);return this.size-=t?1:0,t}},90289:(e,t,n)=>{var r=n(12651);e.exports=function(e){return r(this,e).get(e)}},4509:(e,t,n)=>{var r=n(12651);e.exports=function(e){return r(this,e).has(e)}},72949:(e,t,n)=>{var r=n(12651);e.exports=function(e,t){var n=r(this,e),i=n.size;return n.set(e,t),this.size+=n.size==i?0:1,this}},62224:(e,t,n)=>{var r=n(50104);e.exports=function(e){var t=r(e,(function(e){return 500===n.size&&n.clear(),e})),n=t.cache;return t}},81042:(e,t,n)=>{var r=n(56110)(Object,"create");e.exports=r},59350:e=>{var t=Object.prototype.toString;e.exports=function(e){return t.call(e)}},9325:(e,t,n)=>{var r=n(34840),i="object"==typeof self&&self&&self.Object===Object&&self,a=r||i||Function("return this")();e.exports=a},61802:(e,t,n)=>{var r=n(62224),i=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,a=/\\(\\)?/g,o=r((function(e){var t=[];return 46===e.charCodeAt(0)&&t.push(""),e.replace(i,(function(e,n,r,i){t.push(r?i.replace(a,"$1"):n||e)})),t}));e.exports=o},77797:(e,t,n)=>{var r=n(44394);e.exports=function(e){if("string"==typeof e||r(e))return e;var t=e+"";return"0"==t&&1/e==-1/0?"-0":t}},47473:e=>{var t=Function.prototype.toString;e.exports=function(e){if(null!=e){try{return t.call(e)}catch(n){}try{return e+""}catch(n){}}return""}},31800:e=>{var t=/\s/;e.exports=function(e){for(var n=e.length;n--&&t.test(e.charAt(n)););return n}},38221:(e,t,n)=>{var r=n(23805),i=n(10124),a=n(99374),o=Math.max,s=Math.min;e.exports=function(e,t,n){var l,u,c,h,d,p,g=0,f=!1,v=!1,y=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function m(t){var n=l,r=u;return l=u=void 0,g=t,h=e.apply(r,n)}function b(e){var n=e-p;return void 0===p||n>=t||n<0||v&&e-g>=c}function x(){var e=i();if(b(e))return w(e);d=setTimeout(x,function(e){var n=t-(e-p);return v?s(n,c-(e-g)):n}(e))}function w(e){return d=void 0,y&&l?m(e):(l=u=void 0,h)}function E(){var e=i(),n=b(e);if(l=arguments,u=this,p=e,n){if(void 0===d)return function(e){return g=e,d=setTimeout(x,t),f?m(e):h}(p);if(v)return clearTimeout(d),d=setTimeout(x,t),m(p)}return void 0===d&&(d=setTimeout(x,t)),h}return t=a(t)||0,r(n)&&(f=!!n.leading,c=(v="maxWait"in n)?o(a(n.maxWait)||0,t):c,y="trailing"in n?!!n.trailing:y),E.cancel=function(){void 0!==d&&clearTimeout(d),g=0,l=p=u=d=void 0},E.flush=function(){return void 0===d?h:w(i())},E}},75288:e=>{e.exports=function(e,t){return e===t||e!=e&&t!=t}},58156:(e,t,n)=>{var r=n(47422);e.exports=function(e,t,n){var i=null==e?void 0:r(e,t);return void 0===i?n:i}},56449:e=>{var t=Array.isArray;e.exports=t},1882:(e,t,n)=>{var r=n(72552),i=n(23805);e.exports=function(e){if(!i(e))return!1;var t=r(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t}},23805:e=>{e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},40346:e=>{e.exports=function(e){return null!=e&&"object"==typeof e}},44394:(e,t,n)=>{var r=n(72552),i=n(40346);e.exports=function(e){return"symbol"==typeof e||i(e)&&"[object Symbol]"==r(e)}},50104:(e,t,n)=>{var r=n(53661);function i(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new TypeError("Expected a function");var n=function(){var r=arguments,i=t?t.apply(this,r):r[0],a=n.cache;if(a.has(i))return a.get(i);var o=e.apply(this,r);return n.cache=a.set(i,o)||a,o};return n.cache=new(i.Cache||r),n}i.Cache=r,e.exports=i},10124:(e,t,n)=>{var r=n(9325);e.exports=function(){return r.Date.now()}},63560:(e,t,n)=>{var r=n(73170);e.exports=function(e,t,n){return null==e?e:r(e,t,n)}},99374:(e,t,n)=>{var r=n(54128),i=n(23805),a=n(44394),o=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,l=/^0o[0-7]+$/i,u=parseInt;e.exports=function(e){if("number"==typeof e)return e;if(a(e))return NaN;if(i(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=i(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=r(e);var n=s.test(e);return n||l.test(e)?u(e.slice(2),n?2:8):o.test(e)?NaN:+e}},42072:(e,t,n)=>{var r=n(34932),i=n(23007),a=n(56449),o=n(44394),s=n(61802),l=n(77797),u=n(13222);e.exports=function(e){return a(e)?r(e,l):o(e)?[e]:i(s(u(e)))}},13222:(e,t,n)=>{var r=n(77556);e.exports=function(e){return null==e?"":r(e)}},92704:(e,t,n)=>{"use strict";n.d(t,{diagram:()=>w});var r=n(86079),i=n(44726),a=n(43457),o=n(26312),s=n(9312),l=n(3219),u=n(78041),c=n(75263),h=(n(74353),n(16750),n(42838),function(){var e=function(e,t,n,r){for(n=n||{},r=e.length;r--;n[e[r]]=t);return n},t=[1,4],n=[1,13],r=[1,12],i=[1,15],a=[1,16],o=[1,20],s=[1,19],l=[6,7,8],u=[1,26],c=[1,24],h=[1,25],d=[6,7,11],p=[1,6,13,15,16,19,22],g=[1,33],f=[1,34],v=[1,6,7,11,13,15,16,19,22],y={trace:function(){},yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,MINDMAP:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,ICON:15,CLASS:16,nodeWithId:17,nodeWithoutId:18,NODE_DSTART:19,NODE_DESCR:20,NODE_DEND:21,NODE_ID:22,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"MINDMAP",11:"EOF",13:"SPACELIST",15:"ICON",16:"CLASS",19:"NODE_DSTART",20:"NODE_DESCR",21:"NODE_DEND",22:"NODE_ID"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,2],[12,2],[12,2],[12,1],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[18,3],[17,1],[17,4]],performAction:function(e,t,n,r,i,a,o){var s=a.length-1;switch(i){case 6:case 7:return r;case 8:r.getLogger().trace("Stop NL ");break;case 9:r.getLogger().trace("Stop EOF ");break;case 11:r.getLogger().trace("Stop NL2 ");break;case 12:r.getLogger().trace("Stop EOF2 ");break;case 15:r.getLogger().info("Node: ",a[s].id),r.addNode(a[s-1].length,a[s].id,a[s].descr,a[s].type);break;case 16:r.getLogger().trace("Icon: ",a[s]),r.decorateNode({icon:a[s]});break;case 17:case 21:r.decorateNode({class:a[s]});break;case 18:r.getLogger().trace("SPACELIST");break;case 19:r.getLogger().trace("Node: ",a[s].id),r.addNode(0,a[s].id,a[s].descr,a[s].type);break;case 20:r.decorateNode({icon:a[s]});break;case 25:r.getLogger().trace("node found ..",a[s-2]),this.$={id:a[s-1],descr:a[s-1],type:r.getType(a[s-2],a[s])};break;case 26:this.$={id:a[s],descr:a[s],type:r.nodeType.DEFAULT};break;case 27:r.getLogger().trace("node found ..",a[s-3]),this.$={id:a[s-3],descr:a[s-1],type:r.getType(a[s-2],a[s])}}},table:[{3:1,4:2,5:3,6:[1,5],8:t},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:t},{6:n,7:[1,10],9:9,12:11,13:r,14:14,15:i,16:a,17:17,18:18,19:o,22:s},e(l,[2,3]),{1:[2,2]},e(l,[2,4]),e(l,[2,5]),{1:[2,6],6:n,12:21,13:r,14:14,15:i,16:a,17:17,18:18,19:o,22:s},{6:n,9:22,12:11,13:r,14:14,15:i,16:a,17:17,18:18,19:o,22:s},{6:u,7:c,10:23,11:h},e(d,[2,22],{17:17,18:18,14:27,15:[1,28],16:[1,29],19:o,22:s}),e(d,[2,18]),e(d,[2,19]),e(d,[2,20]),e(d,[2,21]),e(d,[2,23]),e(d,[2,24]),e(d,[2,26],{19:[1,30]}),{20:[1,31]},{6:u,7:c,10:32,11:h},{1:[2,7],6:n,12:21,13:r,14:14,15:i,16:a,17:17,18:18,19:o,22:s},e(p,[2,14],{7:g,11:f}),e(v,[2,8]),e(v,[2,9]),e(v,[2,10]),e(d,[2,15]),e(d,[2,16]),e(d,[2,17]),{20:[1,35]},{21:[1,36]},e(p,[2,13],{7:g,11:f}),e(v,[2,11]),e(v,[2,12]),{21:[1,37]},e(d,[2,25]),e(d,[2,27])],defaultActions:{2:[2,1],6:[2,2]},parseError:function(e,t){if(!t.recoverable){var n=new Error(e);throw n.hash=t,n}this.trace(e)},parse:function(e){var t=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",l=0,u=0,c=a.slice.call(arguments,1),h=Object.create(this.lexer),d={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(d.yy[p]=this.yy[p]);h.setInput(e,d.yy),d.yy.lexer=h,d.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var g=h.yylloc;a.push(g);var f=h.options&&h.options.ranges;"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var v,y,m,b,x,w,E,_,T,D={};;){if(y=n[n.length-1],this.defaultActions[y]?m=this.defaultActions[y]:(null==v&&(T=void 0,"number"!=typeof(T=r.pop()||h.lex()||1)&&(T instanceof Array&&(T=(r=T).pop()),T=t.symbols_[T]||T),v=T),m=o[y]&&o[y][v]),void 0===m||!m.length||!m[0]){var C="";for(x in _=[],o[y])this.terminals_[x]&&x>2&&_.push("'"+this.terminals_[x]+"'");C=h.showPosition?"Parse error on line "+(l+1)+":\n"+h.showPosition()+"\nExpecting "+_.join(", ")+", got '"+(this.terminals_[v]||v)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==v?"end of input":"'"+(this.terminals_[v]||v)+"'"),this.parseError(C,{text:h.match,token:this.terminals_[v]||v,line:h.yylineno,loc:g,expected:_})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+y+", token: "+v);switch(m[0]){case 1:n.push(v),i.push(h.yytext),a.push(h.yylloc),n.push(m[1]),v=null,u=h.yyleng,s=h.yytext,l=h.yylineno,g=h.yylloc;break;case 2:if(w=this.productions_[m[1]][1],D.$=i[i.length-w],D._$={first_line:a[a.length-(w||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(w||1)].first_column,last_column:a[a.length-1].last_column},f&&(D._$.range=[a[a.length-(w||1)].range[0],a[a.length-1].range[1]]),void 0!==(b=this.performAction.apply(D,[s,u,l,d.yy,m[1],i,a].concat(c))))return b;w&&(n=n.slice(0,-1*w*2),i=i.slice(0,-1*w),a=a.slice(0,-1*w)),n.push(this.productions_[m[1]][0]),i.push(D.$),a.push(D._$),E=o[n[n.length-2]][n[n.length-1]],n.push(E);break;case 3:return!0}}return!0}},m={EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,n=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],n=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var e,t,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;a<i.length;a++)if((n=this._input.match(this.rules[i[a]]))&&(!t||n[0].length>t[0].length)){if(t=n,r=a,this.options.backtrack_lexer){if(!1!==(e=this.test_match(n,i[a])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,i[r]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(e,t,n,r){switch(n){case 0:return e.getLogger().trace("Found comment",t.yytext),6;case 1:return 8;case 2:this.begin("CLASS");break;case 3:return this.popState(),16;case 4:case 23:case 26:this.popState();break;case 5:e.getLogger().trace("Begin icon"),this.begin("ICON");break;case 6:return e.getLogger().trace("SPACELINE"),6;case 7:return 7;case 8:return 15;case 9:e.getLogger().trace("end icon"),this.popState();break;case 10:return e.getLogger().trace("Exploding node"),this.begin("NODE"),19;case 11:return e.getLogger().trace("Cloud"),this.begin("NODE"),19;case 12:return e.getLogger().trace("Explosion Bang"),this.begin("NODE"),19;case 13:return e.getLogger().trace("Cloud Bang"),this.begin("NODE"),19;case 14:case 15:case 16:case 17:return this.begin("NODE"),19;case 18:return 13;case 19:return 22;case 20:return 11;case 21:this.begin("NSTR2");break;case 22:return"NODE_DESCR";case 24:e.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 25:return e.getLogger().trace("description:",t.yytext),"NODE_DESCR";case 27:return this.popState(),e.getLogger().trace("node end ))"),"NODE_DEND";case 28:return this.popState(),e.getLogger().trace("node end )"),"NODE_DEND";case 29:return this.popState(),e.getLogger().trace("node end ...",t.yytext),"NODE_DEND";case 30:case 33:case 34:return this.popState(),e.getLogger().trace("node end (("),"NODE_DEND";case 31:case 32:return this.popState(),e.getLogger().trace("node end (-"),"NODE_DEND";case 35:case 36:return e.getLogger().trace("Long description:",t.yytext),20}},rules:[/^(?:\s*%%.*)/i,/^(?:mindmap\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{CLASS:{rules:[3,4],inclusive:!1},ICON:{rules:[8,9],inclusive:!1},NSTR2:{rules:[22,23],inclusive:!1},NSTR:{rules:[25,26],inclusive:!1},NODE:{rules:[21,24,27,28,29,30,31,32,33,34,35,36],inclusive:!1},INITIAL:{rules:[0,1,2,5,6,7,10,11,12,13,14,15,16,17,18,19,20],inclusive:!0}}};function b(){this.yy={}}return y.lexer=m,b.prototype=y,y.Parser=b,new b}());h.parser=h;const d=h;let p=[],g=0,f={};const v={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},y={clear:()=>{p=[],g=0,f={}},addNode:(e,t,n,i)=>{var a,o;r.l.info("addNode",e,t,n,i);const s=(0,r.c)();let l=(null==(a=s.mindmap)?void 0:a.padding)??r.B.mindmap.padding;switch(i){case v.ROUNDED_RECT:case v.RECT:case v.HEXAGON:l*=2}const u={id:g++,nodeId:(0,r.d)(t,s),level:e,descr:(0,r.d)(n,s),type:i,children:[],width:(null==(o=s.mindmap)?void 0:o.maxNodeWidth)??r.B.mindmap.maxNodeWidth,padding:l},c=function(e){for(let t=p.length-1;t>=0;t--)if(p[t].level<e)return p[t];return null}(e);if(c)c.children.push(u),p.push(u);else{if(0!==p.length)throw new Error('There can be only one root. No parent could be found for ("'+u.descr+'")');p.push(u)}},getMindmap:()=>p.length>0?p[0]:null,nodeType:v,getType:(e,t)=>{switch(r.l.debug("In get type",e,t),e){case"[":return v.RECT;case"(":return")"===t?v.ROUNDED_RECT:v.CLOUD;case"((":return v.CIRCLE;case")":return v.CLOUD;case"))":return v.BANG;case"{{":return v.HEXAGON;default:return v.DEFAULT}},setElementForId:(e,t)=>{f[e]=t},decorateNode:e=>{if(!e)return;const t=(0,r.c)(),n=p[p.length-1];e.icon&&(n.icon=(0,r.d)(e.icon,t)),e.class&&(n.class=(0,r.d)(e.class,t))},type2Str:e=>{switch(e){case v.DEFAULT:return"no-border";case v.RECT:return"rect";case v.ROUNDED_RECT:return"rounded-rect";case v.CIRCLE:return"circle";case v.CLOUD:return"cloud";case v.BANG:return"bang";case v.HEXAGON:return"hexgon";default:return"no-border"}},getLogger:()=>r.l,getElementById:e=>f[e]};function m(e,t,n,i,a){!function(e,t,n,i,a){const o=a.htmlLabels,l=i%11,u=t.append("g");n.section=l;let c="section-"+l;l<0&&(c+=" section-root"),u.attr("class",(n.class?n.class+" ":"")+"mindmap-node "+c);const h=u.append("g"),d=u.append("g"),p=n.descr.replace(/(<br\/*>)/g,"\n");(0,s.a)(d,p,{useHtmlLabels:o,width:n.width,classes:"mindmap-node-label"}),o||d.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle");const g=d.node().getBBox(),[f]=(0,r.D)(a.fontSize);if(n.height=g.height+1.1*f*.5+n.padding,n.width=g.width+2*n.padding,n.icon)if(n.type===e.nodeType.CIRCLE)n.height+=50,n.width+=50,u.append("foreignObject").attr("height","50px").attr("width",n.width).attr("style","text-align: center;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+l+" "+n.icon),d.attr("transform","translate("+n.width/2+", "+(n.height/2-1.5*n.padding)+")");else{n.width+=50;const e=n.height;n.height=Math.max(e,60);const t=Math.abs(n.height-e);u.append("foreignObject").attr("width","60px").attr("height",n.height).attr("style","text-align: center;margin-top:"+t/2+"px;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+l+" "+n.icon),d.attr("transform","translate("+(25+n.width/2)+", "+(t/2+n.padding/2)+")")}else if(o){const e=(n.width-g.width)/2,t=(n.height-g.height)/2;d.attr("transform","translate("+e+", "+t+")")}else{const e=n.width/2,t=n.padding/2;d.attr("transform","translate("+e+", "+t+")")}switch(n.type){case e.nodeType.DEFAULT:!function(e,t,n,r){t.append("path").attr("id","node-"+n.id).attr("class","node-bkg node-"+e.type2Str(n.type)).attr("d",`M0 ${n.height-5} v${10-n.height} q0,-5 5,-5 h${n.width-10} q5,0 5,5 v${n.height-5} H0 Z`),t.append("line").attr("class","node-line-"+r).attr("x1",0).attr("y1",n.height).attr("x2",n.width).attr("y2",n.height)}(e,h,n,l);break;case e.nodeType.ROUNDED_RECT:!function(e,t,n){t.append("rect").attr("id","node-"+n.id).attr("class","node-bkg node-"+e.type2Str(n.type)).attr("height",n.height).attr("rx",n.padding).attr("ry",n.padding).attr("width",n.width)}(e,h,n);break;case e.nodeType.RECT:!function(e,t,n){t.append("rect").attr("id","node-"+n.id).attr("class","node-bkg node-"+e.type2Str(n.type)).attr("height",n.height).attr("width",n.width)}(e,h,n);break;case e.nodeType.CIRCLE:h.attr("transform","translate("+n.width/2+", "+ +n.height/2+")"),function(e,t,n){t.append("circle").attr("id","node-"+n.id).attr("class","node-bkg node-"+e.type2Str(n.type)).attr("r",n.width/2)}(e,h,n);break;case e.nodeType.CLOUD:!function(e,t,n){const r=n.width,i=n.height,a=.15*r,o=.25*r,s=.35*r,l=.2*r;t.append("path").attr("id","node-"+n.id).attr("class","node-bkg node-"+e.type2Str(n.type)).attr("d",`M0 0 a${a},${a} 0 0,1 ${.25*r},${-1*r*.1}\n a${s},${s} 1 0,1 ${.4*r},${-1*r*.1}\n a${o},${o} 1 0,1 ${.35*r},${1*r*.2}\n\n a${a},${a} 1 0,1 ${.15*r},${1*i*.35}\n a${l},${l} 1 0,1 ${-1*r*.15},${1*i*.65}\n\n a${o},${a} 1 0,1 ${-1*r*.25},${.15*r}\n a${s},${s} 1 0,1 ${-1*r*.5},0\n a${a},${a} 1 0,1 ${-1*r*.25},${-1*r*.15}\n\n a${a},${a} 1 0,1 ${-1*r*.1},${-1*i*.35}\n a${l},${l} 1 0,1 ${.1*r},${-1*i*.65}\n\n H0 V0 Z`)}(e,h,n);break;case e.nodeType.BANG:!function(e,t,n){const r=n.width,i=n.height,a=.15*r;t.append("path").attr("id","node-"+n.id).attr("class","node-bkg node-"+e.type2Str(n.type)).attr("d",`M0 0 a${a},${a} 1 0,0 ${.25*r},${-1*i*.1}\n a${a},${a} 1 0,0 ${.25*r},0\n a${a},${a} 1 0,0 ${.25*r},0\n a${a},${a} 1 0,0 ${.25*r},${1*i*.1}\n\n a${a},${a} 1 0,0 ${.15*r},${1*i*.33}\n a${.8*a},${.8*a} 1 0,0 0,${1*i*.34}\n a${a},${a} 1 0,0 ${-1*r*.15},${1*i*.33}\n\n a${a},${a} 1 0,0 ${-1*r*.25},${.15*i}\n a${a},${a} 1 0,0 ${-1*r*.25},0\n a${a},${a} 1 0,0 ${-1*r*.25},0\n a${a},${a} 1 0,0 ${-1*r*.25},${-1*i*.15}\n\n a${a},${a} 1 0,0 ${-1*r*.1},${-1*i*.33}\n a${.8*a},${.8*a} 1 0,0 0,${-1*i*.34}\n a${a},${a} 1 0,0 ${.1*r},${-1*i*.33}\n\n H0 V0 Z`)}(e,h,n);break;case e.nodeType.HEXAGON:!function(e,t,n){const r=n.height,i=r/4,a=n.width-n.padding+2*i;!function(e,t,n,r,i){e.insert("polygon",":first-child").attr("points",r.map((function(e){return e.x+","+e.y})).join(" ")).attr("transform","translate("+(i.width-t)/2+", "+n+")")}(t,a,r,[{x:i,y:0},{x:a-i,y:0},{x:a,y:-r/2},{x:a-i,y:-r},{x:i,y:-r},{x:0,y:-r/2}],n)}(0,h,n)}e.setElementForId(n.id,u),n.height}(e,t,n,i,a),n.children&&n.children.forEach(((n,r)=>{m(e,t,n,i<0?r:i,a)}))}function b(e,t,n,r){t.add({group:"nodes",data:{id:e.id.toString(),labelText:e.descr,height:e.height,width:e.width,level:r,nodeId:e.id,padding:e.padding,type:e.type},position:{x:e.x,y:e.y}}),e.children&&e.children.forEach((i=>{b(i,t,n,r+1),t.add({group:"edges",data:{id:`${e.id}_${i.id}`,source:e.id,target:i.id,depth:r,section:i.section}})}))}function x(e,t){return new Promise((n=>{const a=(0,o.Ltv)("body").append("div").attr("id","cy").attr("style","display:none"),s=i({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"bezier"}}]});a.remove(),b(e,s,t,0),s.nodes().forEach((function(e){e.layoutDimensions=()=>{const t=e.data();return{w:t.width,h:t.height}}})),s.layout({name:"cose-bilkent",quality:"proof",styleEnabled:!1,animate:!1}).run(),s.ready((e=>{r.l.info("Ready",e),n(s)}))}))}i.use(a);const w={db:y,renderer:{draw:async(e,t,n,i)=>{var a,o;r.l.debug("Rendering mindmap diagram\n"+e);const s=i.db,l=s.getMindmap();if(!l)return;const u=(0,r.c)();u.htmlLabels=!1;const c=(0,r.A)(t),h=c.append("g");h.attr("class","mindmap-edges");const d=c.append("g");d.attr("class","mindmap-nodes"),m(s,d,l,-1,u);const p=await x(l,u);!function(e,t){t.edges().map(((t,n)=>{const i=t.data();if(t[0]._private.bodyBounds){const a=t[0]._private.rscratch;r.l.trace("Edge: ",n,i),e.insert("path").attr("d",`M ${a.startX},${a.startY} L ${a.midX},${a.midY} L${a.endX},${a.endY} `).attr("class","edge section-edge-"+i.section+" edge-depth-"+i.depth)}}))}(h,p),function(e,t){t.nodes().map(((t,n)=>{const i=t.data();i.x=t.position().x,i.y=t.position().y,function(e,t){const n=e.getElementById(t.id),r=t.x||0,i=t.y||0;n.attr("transform","translate("+r+","+i+")")}(e,i);const a=e.getElementById(i.nodeId);r.l.info("Id:",n,"Position: (",t.position().x,", ",t.position().y,")",i),a.attr("transform",`translate(${t.position().x-i.width/2}, ${t.position().y-i.height/2})`),a.attr("attr",`apa-${n})`)}))}(s,p),(0,r.o)(void 0,c,(null==(a=u.mindmap)?void 0:a.padding)??r.B.mindmap.padding,(null==(o=u.mindmap)?void 0:o.useMaxWidth)??r.B.mindmap.useMaxWidth)}},parser:d,styles:e=>`\n .edge {\n stroke-width: 3;\n }\n ${(e=>{let t="";for(let n=0;n<e.THEME_COLOR_LIMIT;n++)e["lineColor"+n]=e["lineColor"+n]||e["cScaleInv"+n],(0,l.A)(e["lineColor"+n])?e["lineColor"+n]=(0,u.A)(e["lineColor"+n],20):e["lineColor"+n]=(0,c.A)(e["lineColor"+n],20);for(let n=0;n<e.THEME_COLOR_LIMIT;n++){const r=""+(17-3*n);t+=`\n .section-${n-1} rect, .section-${n-1} path, .section-${n-1} circle, .section-${n-1} polygon, .section-${n-1} path {\n fill: ${e["cScale"+n]};\n }\n .section-${n-1} text {\n fill: ${e["cScaleLabel"+n]};\n }\n .node-icon-${n-1} {\n font-size: 40px;\n color: ${e["cScaleLabel"+n]};\n }\n .section-edge-${n-1}{\n stroke: ${e["cScale"+n]};\n }\n .edge-depth-${n-1}{\n stroke-width: ${r};\n }\n .section-${n-1} line {\n stroke: ${e["cScaleInv"+n]} ;\n stroke-width: 3;\n }\n\n .disabled, .disabled circle, .disabled text {\n fill: lightgray;\n }\n .disabled text {\n fill: #efefef;\n }\n `}return t})(e)}\n .section-root rect, .section-root path, .section-root circle, .section-root polygon {\n fill: ${e.git0};\n }\n .section-root text {\n fill: ${e.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .mindmap-node-label {\n dy: 1em;\n alignment-baseline: middle;\n text-anchor: middle;\n dominant-baseline: middle;\n text-align: center;\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/92704.fd1e7d31.js.LICENSE.txt b/assets/js/92704.fd1e7d31.js.LICENSE.txt new file mode 100644 index 0000000000..a9f6f12447 --- /dev/null +++ b/assets/js/92704.fd1e7d31.js.LICENSE.txt @@ -0,0 +1,9 @@ +/*! +Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable +Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com) +Licensed under The MIT License (http://opensource.org/licenses/MIT) +*/ + +/*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */ + +/*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */ diff --git a/assets/js/9278f3d6.53a89b33.js b/assets/js/9278f3d6.53a89b33.js new file mode 100644 index 0000000000..949ccafcc2 --- /dev/null +++ b/assets/js/9278f3d6.53a89b33.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[20904],{74436:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"scs-0213-v1-k8s-nodes-anti-affinity","title":"Kubernetes Nodes Anti Affinity","description":"Introduction","source":"@site/standards/scs-0213-v1-k8s-nodes-anti-affinity.md","sourceDirName":".","slug":"/scs-0213-v1-k8s-nodes-anti-affinity","permalink":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Kubernetes Nodes Anti Affinity","type":"Decision Record","status":"Draft","track":"KaaS"},"sidebar":"standards","previous":{"title":"scs-0213: Kubernetes Nodes Anti Affinity","permalink":"/standards/kaas/scs-0213"},"next":{"title":"scs-0214: Kubernetes Node Distribution and Availability","permalink":"/standards/kaas/scs-0214"}}');var s=t(74848),o=t(28453);const r={title:"Kubernetes Nodes Anti Affinity",type:"Decision Record",status:"Draft",track:"KaaS"},a=void 0,l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Glossary",id:"glossary",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Design considerations",id:"design-considerations",level:2},{value:"Decision",id:"decision",level:2},{value:"Documents",id:"documents",level:2}];function c(e){const n={a:"a",h2:"h2",h3:"h3",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"A Kubernetes instance is provided as a cluster, which consists of a set of worker machines, also called nodes.\nA cluster is composed of a control plane and at least one worker node.\nThe control plane manages the worker nodes and therefore the pods in the cluster by making\ndecisions about scheduling, event detection and global decisions. Inside the control plane,\nmultiple components exist, which can be duplicated and distributed over multiple machines\ninside the cluster. Typically, no user containers are run on these machines in order to\nseparate the control plane from the live system."}),"\n",(0,s.jsx)(n.h3,{id:"glossary",children:"Glossary"}),"\n",(0,s.jsx)(n.p,{children:"The following special terms are used throughout this decision record document:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Term"}),(0,s.jsx)(n.th,{children:"Meaning"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Worker"}),(0,s.jsx)(n.td,{children:"Virtual or bare-metal machine, which hosts workloads of customers"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Control Plane"}),(0,s.jsx)(n.td,{children:"Virtual or bare-metal machine, which hosts the container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Machine"}),(0,s.jsx)(n.td,{children:"Virtual or bare-metal entity with computational capabilities"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(n.p,{children:"In a productive environment, the control plane usually runs across multiple machines and\na cluster usually contains multiple worker nodes in order to provide fault-tolerance and\nhigh availability."}),"\n",(0,s.jsx)(n.p,{children:"In order to ensure availability and scaling of workloads, even if some nodes in the cluster\ncould fail, they should be distributed over multiple nodes on different machines.\nThis can be steered with the Affinity or Anti Affinity features, which are separated by\nKubernetes into two features:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Node Affinity"}),"\n",(0,s.jsx)(n.p,{children:"The Node Affinity feature allows to match pods according to logical matches of\nkey-value-pairs referring to labels of nodes.\nThese can be defined with different weights or preferences in order to allow fine-grained\nselection of nodes. The feature works similar to the Kubernetes nodeSelector.\nIt is defined in the PodSpec using the nodeAffinity field in the affinity section."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Pod Affinity"}),"\n",(0,s.jsx)(n.p,{children:"Pod Affinity or Pod Anti Affinity allows the constraint of pod scheduling based on the\nlabels of pods already running on a node.\nThis means the constraint will match other pods on a node according to their labels key-value-pairs\nand then either schedule the pod to the same (Affinity) or another (Anti Affinity) node.\nThis feature is also defined in the PodSpec using the podAffinity and podAntiAffinity\nfields in the affinity section. [3]"}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:'Both features allow the usage of "required" or "preferred" keywords, which create\n"hard" or "soft" affinities. By using a hard affinity, a pod would need to be scheduled\naccording to the rules set. If this possibility is not given, the pod can\'t be scheduled.\nA soft affinity would allow scheduling even if the requirements are not fulfilled, but\nthey would be preferred if possible.'}),"\n",(0,s.jsx)(n.p,{children:"These features allow efficient resource usage (e.g. by scheduling workloads to evenly\ndistribute across nodes) and provide fault-tolerance and therefore high availability.\nBut they also require more work during the setup of a service architecture, since nodes\nand pods need to be labelled and described consistently."}),"\n",(0,s.jsx)(n.p,{children:"In the case of SCS, affinity of the workloads themselves is not relevant, since this\nfeature is mostly used by the customers of the providers.\nInstead, the expected standard should enable the Kubernetes cluster to handle Anti Affinity\nrules with a real physical separation as well as distributing the control plane over\nmultiple machines in order to provide fault-tolerance during system outages.\nIf the control plane survives an outage, a Kubernetes cluster can recover later on."}),"\n",(0,s.jsx)(n.h2,{id:"design-considerations",children:"Design considerations"}),"\n",(0,s.jsx)(n.p,{children:"SCS plans to require a Hard Anti Affinity and/or Redundancy for the control plane and\na Soft Anti Affinity for workers. This means, that Anti Affinity would be required for\nthe control planes and their pods and only optional (but encouraged) for workers."}),"\n",(0,s.jsx)(n.p,{children:"In order to achieve the goals for these components, meaning availability and fault tolerance\nfor the control plane, an outage resistant cluster, and the availability\npromise given with Anti Affinity for pods on the worker nodes, a separation of nodes\non the hardware level would need to be achieved."}),"\n",(0,s.jsx)(n.p,{children:'For the control plane, a reference to the "Kubernetes High Availability" [1]\ncan be useful, since it provides two ways to set up a highly available cluster.\nBoth approaches are very similar. The "Stacked Control Plane" [2] requires less infrastructure,\nbut also runs the risk of failed coupling, where if one node fails, the redundancy could be\ncompromised due to the loss of a complete control plane instance.\nThe "External ETCD" solves this problem, but also requires double the infrastructure, due\nto the externally incorporated etcd clusters.'}),"\n",(0,s.jsx)(n.p,{children:'This also shows, that the wording "anti affinity" as used with Kubernetes pods is probably\nslightly misleading in the context of a Kubernetes control plane. It may consist of multiple\npods with individual tasks, but distributing them over different nodes through Anti Affinity\nwould probably still cascade the whole control plane into a complete failure, if one of\nthe used nodes goes down. It could be possible to replicate specific important pods and\nassign them to different nodes, but at this point, a redundant setup like presented in [1] could be used.\nSo Anti Affinity in this context probably means more like distribution over multiple\nphysical machines, which needs to be planned beforehand on the machine/server level.'}),"\n",(0,s.jsx)(n.p,{children:'Therefore, would it be preferred for the control plane to use a redundant setup, which\nis separated over different physical machines, meaning at least half of the control plane\nnodes runs on a different physical machine as the rest. The currently used ClusterAPI\nenables this by establishing the concept of "failure domains". These are used to control\nthe placement of k8s nodes and distribute them over multiple physical machines.\nFor example, a High Availability K8s cluster with three control plane nodes could be\ndistributed over three different availability zones (and therefore 3 different\nphysical machines) in order to survive the failure of one availability zone. [5]'}),"\n",(0,s.jsx)(n.p,{children:"For worker nodes, the whole idea of Anti Affinity is more of a preferable situation.\nThe nodes themselves should at best be distributed over different machines, but this\nis not a requirement, especially since smaller providers wouldn't have the capacity to\nprovide enough machines for these distributed Kubernetes clusters. Since customers that\nuse the Affinity or Topology spread constraint [4] features would be especially interested\nin the worker nodes that host their workloads, it should be ensured that a good labeling\nsystem is provided for the nodes in order to see if two nodes are hosted on the same machine."}),"\n",(0,s.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsx)(n.p,{children:"The future standard should define a few important things in order to provide a solid base\nfor the usage and advantages of workloads with Anti Affinity rules."}),"\n",(0,s.jsx)(n.p,{children:"Control planes SHOULD be made redundant in order to provide fault-tolerance and security\nagainst fatal errors on this layer, in the case of node failures. How this redundancy\nis achieved SHOULD be left to the providers, but since failure must be avoided, it is\nREQUIRED to at least duplicate control plane components. Half of every component SHOULD\nbe located on a different node on a different physical machine than the other half\nof them. This should provide at least the minimum requirements for a fault-tolerant control plane.\nFor the standard, there is also a possibility to define multiple stages of distributed infrastructure\nand only make sensible ones a requirement and the rest optional, e.g."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"non-distributed clusters"}),"\n",(0,s.jsxs)(n.li,{children:["High-Availability clusters that are","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"distributed over multiple machines/availability zones"}),"\n",(0,s.jsx)(n.li,{children:"distributed over multiple clouds"}),"\n",(0,s.jsx)(n.li,{children:"distributed over multiple physical locations/datacenters"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The worker nodes are RECOMMENDED to be distributed over different machines. In order to\nprovide clear information to the users, the nodes should be labeled to reflect the\nmapping to the underlying clusters. The labels can be obfuscated in order to not reveal\nthe underlying structures to customers and users. It should be noted, that it is NOT REQUIRED\nto have this anti affinity for the worker nodes due to the requirements of infrastructure\nand complexity associated with this."}),"\n",(0,s.jsx)(n.h2,{id:"documents",children:"Documents"}),"\n",(0,s.jsxs)(n.p,{children:["Kubernetes High Availability Documentation ",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/",children:"1"}),"\nKubernetes High Availability - Stacked ETCD ",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/#stacked-etcd-topology",children:"2"}),"\nAffinity and Anti-Affinity ",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity",children:"3"}),"\nTopology Spread Constraints ",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/",children:"4"}),"\nSCS Multi AZ and Multi Cloud Environments ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/doc/usage/multi-az-and-multi-cloud-environments.md",children:"5"})]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/929c4e1b.d3bd3dc5.js b/assets/js/929c4e1b.d3bd3dc5.js new file mode 100644 index 0000000000..c27df939ac --- /dev/null +++ b/assets/js/929c4e1b.d3bd3dc5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[83802],{34787:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>l,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"index","title":"Introduction","description":"The Sovereign Cloud Stack (SCS) is a community-driven project that curates a set of standards\u2014including both existing standards, such as the OpenInfra interoperability guides or the CNCF Kubernetes conformance, and newly created ones\u2014to enable and ensure compatibility, openness, and sovereignty of cloud services across a wide range of providers, particularly small and medium businesses.","source":"@site/standards/index.md","sourceDirName":".","slug":"/","permalink":"/standards/","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","next":{"title":"overview","permalink":"/standards/certification/overview"}}');var r=t(74848),a=t(28453);const i={},o="Introduction",d={},c=[];function u(e){const n={a:"a",h1:"h1",header:"header",img:"img",p:"p",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"introduction",children:"Introduction"})}),"\n",(0,r.jsx)(n.p,{children:"The Sovereign Cloud Stack (SCS) is a community-driven project that curates a set of standards\u2014including both existing standards, such as the OpenInfra interoperability guides or the CNCF Kubernetes conformance, and newly created ones\u2014to enable and ensure compatibility, openness, and sovereignty of cloud services across a wide range of providers, particularly small and medium businesses."}),"\n",(0,r.jsx)(n.p,{children:"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."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Alt text",src:t(77704).A+"",width:"835",height:"711"})}),"\n",(0,r.jsxs)(n.p,{children:["Learn more about these scopes as well as the currently certified clouds under ",(0,r.jsx)(n.a,{href:"/standards/certification/overview",children:"Certification"}),". More details on individual standards can be found under ",(0,r.jsx)(n.a,{href:"/standards/standards/overview",children:"Standards"}),"."]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},77704:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/image-01d5564077ed43bda1d921e522df7dd7.png"},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>o});var s=t(96540);const r={},a=s.createContext(r);function i(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/931040e8.f6c51dd2.js b/assets/js/931040e8.f6c51dd2.js new file mode 100644 index 0000000000..be4468bf07 --- /dev/null +++ b/assets/js/931040e8.f6c51dd2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[57743],{53800:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>u,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"contribute/styleguide","title":"Styleguide","description":"Admonitions","source":"@site/community/contribute/styleguide.md","sourceDirName":"contribute","slug":"/contribute/styleguide","permalink":"/community/contribute/styleguide","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Installation","permalink":"/community/contribute/local-docusaurus-development-guide"}}');var s=o(74848),i=o(28453);const r={},d="Styleguide",a={},c=[{value:"Admonitions",id:"admonitions",level:2},{value:"Blockquotes",id:"blockquotes",level:2},{value:"Codeblocks",id:"codeblocks",level:2}];function l(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"styleguide",children:"Styleguide"})}),"\n",(0,s.jsx)(n.h2,{id:"admonitions",children:"Admonitions"}),"\n",(0,s.jsx)(n.p,{children:"We adopt the default Admonition colors for Note, Tip, Info, Caution, Danger by docusaurus:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"https://docusaurus-archive-october-2023.netlify.app/docs/markdown-features/admonitions",children:"Docusaurus Admonitons"})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Some ",(0,s.jsx)(n.strong,{children:"content"})," with ",(0,s.jsx)(n.em,{children:"Markdown"})," ",(0,s.jsx)(n.code,{children:"syntax"}),"."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["Some ",(0,s.jsx)(n.strong,{children:"content"})," with ",(0,s.jsx)(n.em,{children:"Markdown"})," ",(0,s.jsx)(n.code,{children:"syntax"}),"."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["Some ",(0,s.jsx)(n.strong,{children:"content"})," with ",(0,s.jsx)(n.em,{children:"Markdown"})," ",(0,s.jsx)(n.code,{children:"syntax"}),"."]})}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsxs)(n.p,{children:["Some ",(0,s.jsx)(n.strong,{children:"content"})," with ",(0,s.jsx)(n.em,{children:"Markdown"})," ",(0,s.jsx)(n.code,{children:"syntax"}),"."]})}),"\n",(0,s.jsx)(n.admonition,{type:"danger",children:(0,s.jsxs)(n.p,{children:["Some ",(0,s.jsx)(n.strong,{children:"content"})," with ",(0,s.jsx)(n.em,{children:"Markdown"})," ",(0,s.jsx)(n.code,{children:"syntax"}),"."]})}),"\n",(0,s.jsx)(n.h2,{id:"blockquotes",children:"Blockquotes"}),"\n",(0,s.jsxs)(n.p,{children:["Blockquotes should be handled with standard markdown ",(0,s.jsx)(n.code,{children:">"})]}),"\n",(0,s.jsx)(n.p,{children:"Example Blockquote:"}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"The raw data format is really the only sensible format option to use with RBD. asdasdasdasd asd asd a\nTechnically, you could use other QEMU-supported formats\n(such as qcow2 or vmdk), but doing so would add additional overhead, and would\nalso render the volume unsafe for virtual machine live\nmigration when caching (see below) is enabled."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"codeblocks",children:"Codeblocks"}),"\n",(0,s.jsxs)(n.p,{children:["We support markdown language features for Codeblocks.\nIt is mandatory to define the language to be quoted, when using codeblocks.\nSyntax Highlighting is also supported by ",(0,s.jsx)(n.a,{href:"https://docusaurus-archive-october-2023.netlify.app/docs/markdown-features/code-blocks#supported-languages",children:"Docusaurus via Prism"}),".\nWe are using the GitHub language themeing as default."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",metastring:'title="Python example"',children:"def code_block():\n # Everything in this function is part of the same code block\n print (1)\n print (2)\n\nfor i in range(4):\n # Everyting in this loop is part of the same code block\n print (i)\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",metastring:'title="Javascript example"',children:"const code_block = () => {\n console.log('inside code_block')\n}\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="YAML example"',children:"---\ndoe: 'a deer, a female deer'\nray: 'a drop of golden sun'\npi: 3.14159\nxmas: true\nfrench-hens: 3\ncalling-birds:\n - huey\n - dewey\n - louie\n - fred\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ruby",metastring:'title="Ruby example"',children:"require 'redcarpet'\nmarkdown = Redcarpet.new(\"Hello World!\")\nputs markdown.to_html\n"})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>r,x:()=>d});var t=o(96540);const s={},i=t.createContext(s);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9312.1b4382f8.js b/assets/js/9312.1b4382f8.js new file mode 100644 index 0000000000..4dfb341c5b --- /dev/null +++ b/assets/js/9312.1b4382f8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9312],{9312:(e,n,t)=>{t.d(n,{a:()=>dn,c:()=>an});var r={};t.r(r),t.d(r,{attentionMarkers:()=>je,contentInitial:()=>Be,disable:()=>He,document:()=>De,flow:()=>Me,flowInitial:()=>_e,insideSpan:()=>Oe,string:()=>Le,text:()=>Pe});var i=t(86079);const u={};function o(e,n,t){if(function(e){return Boolean(e&&"object"==typeof e)}(e)){if("value"in e)return"html"!==e.type||t?e.value:"";if(n&&"alt"in e&&e.alt)return e.alt;if("children"in e)return c(e.children,n,t)}return Array.isArray(e)?c(e,n,t):""}function c(e,n,t){const r=[];let i=-1;for(;++i<e.length;)r[i]=o(e[i],n,t);return r.join("")}function s(e,n,t,r){const i=e.length;let u,o=0;if(n=n<0?-n>i?0:i+n:n>i?i:n,t=t>0?t:0,r.length<1e4)u=Array.from(r),u.unshift(n,t),e.splice(...u);else for(t&&e.splice(n,t);o<r.length;)u=r.slice(o,o+1e4),u.unshift(n,0),e.splice(...u),o+=1e4,n+=1e4}function l(e,n){return e.length>0?(s(e,e.length,0,n),e):n}const a={}.hasOwnProperty;function f(e,n){let t;for(t in n){const r=(a.call(e,t)?e[t]:void 0)||(e[t]={}),i=n[t];let u;if(i)for(u in i){a.call(r,u)||(r[u]=[]);const e=i[u];d(r[u],Array.isArray(e)?e:e?[e]:[])}}}function d(e,n){let t=-1;const r=[];for(;++t<n.length;)("after"===n[t].add?e:r).push(n[t]);s(e,0,0,r)}const h=A(/[A-Za-z]/),p=A(/[\dA-Za-z]/),m=A(/[#-'*+\--9=?A-Z^-~]/);function g(e){return null!==e&&(e<32||127===e)}const x=A(/\d/),k=A(/[\dA-Fa-f]/),y=A(/[!-/:-@[-`{-~]/);function F(e){return null!==e&&e<-2}function v(e){return null!==e&&(e<0||32===e)}function b(e){return-2===e||-1===e||32===e}const S=A(/[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/),E=A(/\s/);function A(e){return function(n){return null!==n&&e.test(String.fromCharCode(n))}}function I(e,n,t,r){const i=r?r-1:Number.POSITIVE_INFINITY;let u=0;return function(r){if(b(r))return e.enter(t),o(r);return n(r)};function o(r){return b(r)&&u++<i?(e.consume(r),o):(e.exit(t),n(r))}}const w={tokenize:function(e){const n=e.attempt(this.parser.constructs.contentInitial,(function(t){if(null===t)return void e.consume(t);return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),I(e,n,"linePrefix")}),(function(n){return e.enter("paragraph"),r(n)}));let t;return n;function r(n){const r=e.enter("chunkText",{contentType:"text",previous:t});return t&&(t.next=r),t=r,i(n)}function i(n){return null===n?(e.exit("chunkText"),e.exit("paragraph"),void e.consume(n)):F(n)?(e.consume(n),e.exit("chunkText"),r):(e.consume(n),i)}}};const C={tokenize:function(e){const n=this,t=[];let r,i,u,o=0;return c;function c(r){if(o<t.length){const i=t[o];return n.containerState=i[1],e.attempt(i[0].continuation,l,a)(r)}return a(r)}function l(e){if(o++,n.containerState._closeFlow){n.containerState._closeFlow=void 0,r&&y();const t=n.events.length;let i,u=t;for(;u--;)if("exit"===n.events[u][0]&&"chunkFlow"===n.events[u][1].type){i=n.events[u][1].end;break}k(o);let c=t;for(;c<n.events.length;)n.events[c][1].end=Object.assign({},i),c++;return s(n.events,u+1,0,n.events.slice(t)),n.events.length=c,a(e)}return c(e)}function a(i){if(o===t.length){if(!r)return h(i);if(r.currentConstruct&&r.currentConstruct.concrete)return m(i);n.interrupt=Boolean(r.currentConstruct&&!r._gfmTableDynamicInterruptHack)}return n.containerState={},e.check(T,f,d)(i)}function f(e){return r&&y(),k(o),h(e)}function d(e){return n.parser.lazy[n.now().line]=o!==t.length,u=n.now().offset,m(e)}function h(t){return n.containerState={},e.attempt(T,p,m)(t)}function p(e){return o++,t.push([n.currentConstruct,n.containerState]),h(e)}function m(t){return null===t?(r&&y(),k(0),void e.consume(t)):(r=r||n.parser.flow(n.now()),e.enter("chunkFlow",{contentType:"flow",previous:i,_tokenizer:r}),g(t))}function g(t){return null===t?(x(e.exit("chunkFlow"),!0),k(0),void e.consume(t)):F(t)?(e.consume(t),x(e.exit("chunkFlow")),o=0,n.interrupt=void 0,c):(e.consume(t),g)}function x(e,t){const c=n.sliceStream(e);if(t&&c.push(null),e.previous=i,i&&(i.next=e),i=e,r.defineSkip(e.start),r.write(c),n.parser.lazy[e.start.line]){let e=r.events.length;for(;e--;)if(r.events[e][1].start.offset<u&&(!r.events[e][1].end||r.events[e][1].end.offset>u))return;const t=n.events.length;let i,c,l=t;for(;l--;)if("exit"===n.events[l][0]&&"chunkFlow"===n.events[l][1].type){if(i){c=n.events[l][1].end;break}i=!0}for(k(o),e=t;e<n.events.length;)n.events[e][1].end=Object.assign({},c),e++;s(n.events,l+1,0,n.events.slice(t)),n.events.length=e}}function k(r){let i=t.length;for(;i-- >r;){const r=t[i];n.containerState=r[1],r[0].exit.call(n,e)}t.length=r}function y(){r.write([null]),i=void 0,r=void 0,n.containerState._closeFlow=void 0}}},T={tokenize:function(e,n,t){return I(e,e.attempt(this.parser.constructs.document,n,t),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}};const z={tokenize:function(e,n,t){return function(n){return b(n)?I(e,r,"linePrefix")(n):r(n)};function r(e){return null===e||F(e)?n(e):t(e)}},partial:!0};function D(e){const n={};let t,r,i,u,o,c,l,a=-1;for(;++a<e.length;){for(;a in n;)a=n[a];if(t=e[a],a&&"chunkFlow"===t[1].type&&"listItemPrefix"===e[a-1][1].type&&(c=t[1]._tokenizer.events,i=0,i<c.length&&"lineEndingBlank"===c[i][1].type&&(i+=2),i<c.length&&"content"===c[i][1].type))for(;++i<c.length&&"content"!==c[i][1].type;)"chunkText"===c[i][1].type&&(c[i][1]._isInFirstContentOfListItem=!0,i++);if("enter"===t[0])t[1].contentType&&(Object.assign(n,B(e,a)),a=n[a],l=!0);else if(t[1]._container){for(i=a,r=void 0;i--&&(u=e[i],"lineEnding"===u[1].type||"lineEndingBlank"===u[1].type);)"enter"===u[0]&&(r&&(e[r][1].type="lineEndingBlank"),u[1].type="lineEnding",r=i);r&&(t[1].end=Object.assign({},e[r][1].start),o=e.slice(r,a),o.unshift(t),s(e,r,a-r+1,o))}}return!l}function B(e,n){const t=e[n][1],r=e[n][2];let i=n-1;const u=[],o=t._tokenizer||r.parser[t.contentType](t.start),c=o.events,l=[],a={};let f,d,h=-1,p=t,m=0,g=0;const x=[g];for(;p;){for(;e[++i][1]!==p;);u.push(i),p._tokenizer||(f=r.sliceStream(p),p.next||f.push(null),d&&o.defineSkip(p.start),p._isInFirstContentOfListItem&&(o._gfmTasklistFirstContentOfListItem=!0),o.write(f),p._isInFirstContentOfListItem&&(o._gfmTasklistFirstContentOfListItem=void 0)),d=p,p=p.next}for(p=t;++h<c.length;)"exit"===c[h][0]&&"enter"===c[h-1][0]&&c[h][1].type===c[h-1][1].type&&c[h][1].start.line!==c[h][1].end.line&&(g=h+1,x.push(g),p._tokenizer=void 0,p.previous=void 0,p=p.next);for(o.events=[],p?(p._tokenizer=void 0,p.previous=void 0):x.pop(),h=x.length;h--;){const n=c.slice(x[h],x[h+1]),t=u.pop();l.unshift([t,t+n.length-1]),s(e,t,2,n)}for(h=-1;++h<l.length;)a[m+l[h][0]]=m+l[h][1],m+=l[h][1]-l[h][0]-1;return a}const _={tokenize:function(e,n){let t;return function(n){return e.enter("content"),t=e.enter("chunkContent",{contentType:"content"}),r(n)};function r(n){return null===n?i(n):F(n)?e.check(M,u,i)(n):(e.consume(n),r)}function i(t){return e.exit("chunkContent"),e.exit("content"),n(t)}function u(n){return e.consume(n),e.exit("chunkContent"),t.next=e.enter("chunkContent",{contentType:"content",previous:t}),t=t.next,r}},resolve:function(e){return D(e),e}},M={tokenize:function(e,n,t){const r=this;return function(n){return e.exit("chunkContent"),e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),I(e,i,"linePrefix")};function i(i){if(null===i||F(i))return t(i);const u=r.events[r.events.length-1];return!r.parser.constructs.disable.null.includes("codeIndented")&&u&&"linePrefix"===u[1].type&&u[2].sliceSerialize(u[1],!0).length>=4?n(i):e.interrupt(r.parser.constructs.flow,t,n)(i)}},partial:!0};const L={tokenize:function(e){const n=this,t=e.attempt(z,(function(r){if(null===r)return void e.consume(r);return e.enter("lineEndingBlank"),e.consume(r),e.exit("lineEndingBlank"),n.currentConstruct=void 0,t}),e.attempt(this.parser.constructs.flowInitial,r,I(e,e.attempt(this.parser.constructs.flow,r,e.attempt(_,r)),"linePrefix")));return t;function r(r){if(null!==r)return e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),n.currentConstruct=void 0,t;e.consume(r)}}};const P={resolveAll:R()},O=H("string"),j=H("text");function H(e){return{tokenize:function(n){const t=this,r=this.parser.constructs[e],i=n.attempt(r,u,o);return u;function u(e){return s(e)?i(e):o(e)}function o(e){if(null!==e)return n.enter("data"),n.consume(e),c;n.consume(e)}function c(e){return s(e)?(n.exit("data"),i(e)):(n.consume(e),c)}function s(e){if(null===e)return!0;const n=r[e];let i=-1;if(n)for(;++i<n.length;){const e=n[i];if(!e.previous||e.previous.call(t,t.previous))return!0}return!1}},resolveAll:R("text"===e?q:void 0)}}function R(e){return function(n,t){let r,i=-1;for(;++i<=n.length;)void 0===r?n[i]&&"data"===n[i][1].type&&(r=i,i++):n[i]&&"data"===n[i][1].type||(i!==r+2&&(n[r][1].end=n[i-1][1].end,n.splice(r+2,i-r-2),i=r+2),r=void 0);return e?e(n,t):n}}function q(e,n){let t=0;for(;++t<=e.length;)if((t===e.length||"lineEnding"===e[t][1].type)&&"data"===e[t-1][1].type){const r=e[t-1][1],i=n.sliceStream(r);let u,o=i.length,c=-1,s=0;for(;o--;){const e=i[o];if("string"==typeof e){for(c=e.length;32===e.charCodeAt(c-1);)s++,c--;if(c)break;c=-1}else if(-2===e)u=!0,s++;else if(-1!==e){o++;break}}if(s){const i={type:t===e.length||u||s<2?"lineSuffix":"hardBreakTrailing",start:{line:r.end.line,column:r.end.column-s,offset:r.end.offset-s,_index:r.start._index+o,_bufferIndex:o?c:r.start._bufferIndex+c},end:Object.assign({},r.end)};r.end=Object.assign({},i.start),r.start.offset===r.end.offset?Object.assign(r,i):(e.splice(t,0,["enter",i,n],["exit",i,n]),t+=2)}t++}return e}function V(e,n,t){const r=[];let i=-1;for(;++i<e.length;){const u=e[i].resolveAll;u&&!r.includes(u)&&(n=u(n,t),r.push(u))}return n}function Q(e,n,t){let r=Object.assign(t?Object.assign({},t):{line:1,column:1,offset:0},{_index:0,_bufferIndex:-1});const i={},u=[];let o=[],c=[],a=!0;const f={consume:function(e){F(e)?(r.line++,r.column=1,r.offset+=-3===e?2:1,S()):-1!==e&&(r.column++,r.offset++);r._bufferIndex<0?r._index++:(r._bufferIndex++,r._bufferIndex===o[r._index].length&&(r._bufferIndex=-1,r._index++));d.previous=e,a=!0},enter:function(e,n){const t=n||{};return t.type=e,t.start=g(),d.events.push(["enter",t,d]),c.push(t),t},exit:function(e){const n=c.pop();return n.end=g(),d.events.push(["exit",n,d]),n},attempt:v((function(e,n){b(e,n.from)})),check:v(y),interrupt:v(y,{interrupt:!0})},d={previous:null,code:null,containerState:{},events:[],parser:e,sliceStream:m,sliceSerialize:function(e,n){return function(e,n){let t=-1;const r=[];let i;for(;++t<e.length;){const u=e[t];let o;if("string"==typeof u)o=u;else switch(u){case-5:o="\r";break;case-4:o="\n";break;case-3:o="\r\n";break;case-2:o=n?" ":"\t";break;case-1:if(!n&&i)continue;o=" ";break;default:o=String.fromCharCode(u)}i=-2===u,r.push(o)}return r.join("")}(m(e),n)},now:g,defineSkip:function(e){i[e.line]=e.column,S()},write:function(e){if(o=l(o,e),x(),null!==o[o.length-1])return[];return b(n,0),d.events=V(u,d.events,d),d.events}};let h,p=n.tokenize.call(d,f);return n.resolveAll&&u.push(n),d;function m(e){return function(e,n){const t=n.start._index,r=n.start._bufferIndex,i=n.end._index,u=n.end._bufferIndex;let o;if(t===i)o=[e[t].slice(r,u)];else{if(o=e.slice(t,i),r>-1){const e=o[0];"string"==typeof e?o[0]=e.slice(r):o.shift()}u>0&&o.push(e[i].slice(0,u))}return o}(o,e)}function g(){const{line:e,column:n,offset:t,_index:i,_bufferIndex:u}=r;return{line:e,column:n,offset:t,_index:i,_bufferIndex:u}}function x(){let e;for(;r._index<o.length;){const n=o[r._index];if("string"==typeof n)for(e=r._index,r._bufferIndex<0&&(r._bufferIndex=0);r._index===e&&r._bufferIndex<n.length;)k(n.charCodeAt(r._bufferIndex));else k(n)}}function k(e){a=void 0,h=e,p=p(e)}function y(e,n){n.restore()}function v(e,n){return function(t,i,u){let o,s,l,h;return Array.isArray(t)?p(t):"tokenize"in t?p([t]):function(e){return n;function n(n){const t=null!==n&&e[n],r=null!==n&&e.null;return p([...Array.isArray(t)?t:t?[t]:[],...Array.isArray(r)?r:r?[r]:[]])(n)}}(t);function p(e){return o=e,s=0,0===e.length?u:m(e[s])}function m(e){return function(t){h=function(){const e=g(),n=d.previous,t=d.currentConstruct,i=d.events.length,u=Array.from(c);return{restore:o,from:i};function o(){r=e,d.previous=n,d.currentConstruct=t,d.events.length=i,c=u,S()}}(),l=e,e.partial||(d.currentConstruct=e);if(e.name&&d.parser.constructs.disable.null.includes(e.name))return k(t);return e.tokenize.call(n?Object.assign(Object.create(d),n):d,f,x,k)(t)}}function x(n){return a=!0,e(l,h),i}function k(e){return a=!0,h.restore(),++s<o.length?m(o[s]):u}}}function b(e,n){e.resolveAll&&!u.includes(e)&&u.push(e),e.resolve&&s(d.events,n,d.events.length-n,e.resolve(d.events.slice(n),d)),e.resolveTo&&(d.events=e.resolveTo(d.events,d))}function S(){r.line in i&&r.column<2&&(r.column=i[r.line],r.offset+=i[r.line]-1)}}const N={name:"thematicBreak",tokenize:function(e,n,t){let r,i=0;return function(n){return e.enter("thematicBreak"),function(e){return r=e,u(e)}(n)};function u(u){return u===r?(e.enter("thematicBreakSequence"),o(u)):i>=3&&(null===u||F(u))?(e.exit("thematicBreak"),n(u)):t(u)}function o(n){return n===r?(e.consume(n),i++,o):(e.exit("thematicBreakSequence"),b(n)?I(e,u,"whitespace")(n):u(n))}}};const U={name:"list",tokenize:function(e,n,t){const r=this,i=r.events[r.events.length-1];let u=i&&"linePrefix"===i[1].type?i[2].sliceSerialize(i[1],!0).length:0,o=0;return function(n){const i=r.containerState.type||(42===n||43===n||45===n?"listUnordered":"listOrdered");if("listUnordered"===i?!r.containerState.marker||n===r.containerState.marker:x(n)){if(r.containerState.type||(r.containerState.type=i,e.enter(i,{_container:!0})),"listUnordered"===i)return e.enter("listItemPrefix"),42===n||45===n?e.check(N,t,s)(n):s(n);if(!r.interrupt||49===n)return e.enter("listItemPrefix"),e.enter("listItemValue"),c(n)}return t(n)};function c(n){return x(n)&&++o<10?(e.consume(n),c):(!r.interrupt||o<2)&&(r.containerState.marker?n===r.containerState.marker:41===n||46===n)?(e.exit("listItemValue"),s(n)):t(n)}function s(n){return e.enter("listItemMarker"),e.consume(n),e.exit("listItemMarker"),r.containerState.marker=r.containerState.marker||n,e.check(z,r.interrupt?t:l,e.attempt($,f,a))}function l(e){return r.containerState.initialBlankLine=!0,u++,f(e)}function a(n){return b(n)?(e.enter("listItemPrefixWhitespace"),e.consume(n),e.exit("listItemPrefixWhitespace"),f):t(n)}function f(t){return r.containerState.size=u+r.sliceSerialize(e.exit("listItemPrefix"),!0).length,n(t)}},continuation:{tokenize:function(e,n,t){const r=this;return r.containerState._closeFlow=void 0,e.check(z,(function(t){return r.containerState.furtherBlankLines=r.containerState.furtherBlankLines||r.containerState.initialBlankLine,I(e,n,"listItemIndent",r.containerState.size+1)(t)}),(function(t){if(r.containerState.furtherBlankLines||!b(t))return r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,i(t);return r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,e.attempt(W,n,i)(t)}));function i(i){return r.containerState._closeFlow=!0,r.interrupt=void 0,I(e,e.attempt(U,n,t),"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(i)}}},exit:function(e){e.exit(this.containerState.type)}},$={tokenize:function(e,n,t){const r=this;return I(e,(function(e){const i=r.events[r.events.length-1];return!b(e)&&i&&"listItemPrefixWhitespace"===i[1].type?n(e):t(e)}),"listItemPrefixWhitespace",r.parser.constructs.disable.null.includes("codeIndented")?void 0:5)},partial:!0},W={tokenize:function(e,n,t){const r=this;return I(e,(function(e){const i=r.events[r.events.length-1];return i&&"listItemIndent"===i[1].type&&i[2].sliceSerialize(i[1],!0).length===r.containerState.size?n(e):t(e)}),"listItemIndent",r.containerState.size+1)},partial:!0};const Z={name:"blockQuote",tokenize:function(e,n,t){const r=this;return function(n){if(62===n){const t=r.containerState;return t.open||(e.enter("blockQuote",{_container:!0}),t.open=!0),e.enter("blockQuotePrefix"),e.enter("blockQuoteMarker"),e.consume(n),e.exit("blockQuoteMarker"),i}return t(n)};function i(t){return b(t)?(e.enter("blockQuotePrefixWhitespace"),e.consume(t),e.exit("blockQuotePrefixWhitespace"),e.exit("blockQuotePrefix"),n):(e.exit("blockQuotePrefix"),n(t))}},continuation:{tokenize:function(e,n,t){const r=this;return function(n){if(b(n))return I(e,i,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(n);return i(n)};function i(r){return e.attempt(Z,n,t)(r)}}},exit:function(e){e.exit("blockQuote")}};function Y(e,n,t,r,i,u,o,c,s){const l=s||Number.POSITIVE_INFINITY;let a=0;return function(n){if(60===n)return e.enter(r),e.enter(i),e.enter(u),e.consume(n),e.exit(u),f;if(null===n||32===n||41===n||g(n))return t(n);return e.enter(r),e.enter(o),e.enter(c),e.enter("chunkString",{contentType:"string"}),p(n)};function f(t){return 62===t?(e.enter(u),e.consume(t),e.exit(u),e.exit(i),e.exit(r),n):(e.enter(c),e.enter("chunkString",{contentType:"string"}),d(t))}function d(n){return 62===n?(e.exit("chunkString"),e.exit(c),f(n)):null===n||60===n||F(n)?t(n):(e.consume(n),92===n?h:d)}function h(n){return 60===n||62===n||92===n?(e.consume(n),d):d(n)}function p(i){return a||null!==i&&41!==i&&!v(i)?a<l&&40===i?(e.consume(i),a++,p):41===i?(e.consume(i),a--,p):null===i||32===i||40===i||g(i)?t(i):(e.consume(i),92===i?m:p):(e.exit("chunkString"),e.exit(c),e.exit(o),e.exit(r),n(i))}function m(n){return 40===n||41===n||92===n?(e.consume(n),p):p(n)}}function G(e,n,t,r,i,u){const o=this;let c,s=0;return function(n){return e.enter(r),e.enter(i),e.consume(n),e.exit(i),e.enter(u),l};function l(f){return s>999||null===f||91===f||93===f&&!c||94===f&&!s&&"_hiddenFootnoteSupport"in o.parser.constructs?t(f):93===f?(e.exit(u),e.enter(i),e.consume(f),e.exit(i),e.exit(r),n):F(f)?(e.enter("lineEnding"),e.consume(f),e.exit("lineEnding"),l):(e.enter("chunkString",{contentType:"string"}),a(f))}function a(n){return null===n||91===n||93===n||F(n)||s++>999?(e.exit("chunkString"),l(n)):(e.consume(n),c||(c=!b(n)),92===n?f:a)}function f(n){return 91===n||92===n||93===n?(e.consume(n),s++,a):a(n)}}function J(e,n,t,r,i,u){let o;return function(n){if(34===n||39===n||40===n)return e.enter(r),e.enter(i),e.consume(n),e.exit(i),o=40===n?41:n,c;return t(n)};function c(t){return t===o?(e.enter(i),e.consume(t),e.exit(i),e.exit(r),n):(e.enter(u),s(t))}function s(n){return n===o?(e.exit(u),c(o)):null===n?t(n):F(n)?(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),I(e,s,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),l(n))}function l(n){return n===o||null===n||F(n)?(e.exit("chunkString"),s(n)):(e.consume(n),92===n?a:l)}function a(n){return n===o||92===n?(e.consume(n),l):l(n)}}function K(e,n){let t;return function r(i){if(F(i))return e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),t=!0,r;if(b(i))return I(e,r,t?"linePrefix":"lineSuffix")(i);return n(i)}}function X(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const ee={name:"definition",tokenize:function(e,n,t){const r=this;let i;return function(n){return e.enter("definition"),function(n){return G.call(r,e,u,t,"definitionLabel","definitionLabelMarker","definitionLabelString")(n)}(n)};function u(n){return i=X(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)),58===n?(e.enter("definitionMarker"),e.consume(n),e.exit("definitionMarker"),o):t(n)}function o(n){return v(n)?K(e,c)(n):c(n)}function c(n){return Y(e,s,t,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(n)}function s(n){return e.attempt(ne,l,l)(n)}function l(n){return b(n)?I(e,a,"whitespace")(n):a(n)}function a(u){return null===u||F(u)?(e.exit("definition"),r.parser.defined.push(i),n(u)):t(u)}}},ne={tokenize:function(e,n,t){return function(n){return v(n)?K(e,r)(n):t(n)};function r(n){return J(e,i,t,"definitionTitle","definitionTitleMarker","definitionTitleString")(n)}function i(n){return b(n)?I(e,u,"whitespace")(n):u(n)}function u(e){return null===e||F(e)?n(e):t(e)}},partial:!0};const te={name:"codeIndented",tokenize:function(e,n,t){const r=this;return function(n){return e.enter("codeIndented"),I(e,i,"linePrefix",5)(n)};function i(e){const n=r.events[r.events.length-1];return n&&"linePrefix"===n[1].type&&n[2].sliceSerialize(n[1],!0).length>=4?u(e):t(e)}function u(n){return null===n?c(n):F(n)?e.attempt(re,u,c)(n):(e.enter("codeFlowValue"),o(n))}function o(n){return null===n||F(n)?(e.exit("codeFlowValue"),u(n)):(e.consume(n),o)}function c(t){return e.exit("codeIndented"),n(t)}}},re={tokenize:function(e,n,t){const r=this;return i;function i(n){return r.parser.lazy[r.now().line]?t(n):F(n)?(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),i):I(e,u,"linePrefix",5)(n)}function u(e){const u=r.events[r.events.length-1];return u&&"linePrefix"===u[1].type&&u[2].sliceSerialize(u[1],!0).length>=4?n(e):F(e)?i(e):t(e)}},partial:!0};const ie={name:"headingAtx",tokenize:function(e,n,t){let r=0;return function(n){return e.enter("atxHeading"),function(n){return e.enter("atxHeadingSequence"),i(n)}(n)};function i(n){return 35===n&&r++<6?(e.consume(n),i):null===n||v(n)?(e.exit("atxHeadingSequence"),u(n)):t(n)}function u(t){return 35===t?(e.enter("atxHeadingSequence"),o(t)):null===t||F(t)?(e.exit("atxHeading"),n(t)):b(t)?I(e,u,"whitespace")(t):(e.enter("atxHeadingText"),c(t))}function o(n){return 35===n?(e.consume(n),o):(e.exit("atxHeadingSequence"),u(n))}function c(n){return null===n||35===n||v(n)?(e.exit("atxHeadingText"),u(n)):(e.consume(n),c)}},resolve:function(e,n){let t,r,i=e.length-2,u=3;"whitespace"===e[u][1].type&&(u+=2);i-2>u&&"whitespace"===e[i][1].type&&(i-=2);"atxHeadingSequence"===e[i][1].type&&(u===i-1||i-4>u&&"whitespace"===e[i-2][1].type)&&(i-=u+1===i?2:4);i>u&&(t={type:"atxHeadingText",start:e[u][1].start,end:e[i][1].end},r={type:"chunkText",start:e[u][1].start,end:e[i][1].end,contentType:"text"},s(e,u,i-u+1,[["enter",t,n],["enter",r,n],["exit",r,n],["exit",t,n]]));return e}};const ue={name:"setextUnderline",tokenize:function(e,n,t){const r=this;let i;return function(n){let o,c=r.events.length;for(;c--;)if("lineEnding"!==r.events[c][1].type&&"linePrefix"!==r.events[c][1].type&&"content"!==r.events[c][1].type){o="paragraph"===r.events[c][1].type;break}if(!r.parser.lazy[r.now().line]&&(r.interrupt||o))return e.enter("setextHeadingLine"),i=n,function(n){return e.enter("setextHeadingLineSequence"),u(n)}(n);return t(n)};function u(n){return n===i?(e.consume(n),u):(e.exit("setextHeadingLineSequence"),b(n)?I(e,o,"lineSuffix")(n):o(n))}function o(r){return null===r||F(r)?(e.exit("setextHeadingLine"),n(r)):t(r)}},resolveTo:function(e,n){let t,r,i,u=e.length;for(;u--;)if("enter"===e[u][0]){if("content"===e[u][1].type){t=u;break}"paragraph"===e[u][1].type&&(r=u)}else"content"===e[u][1].type&&e.splice(u,1),i||"definition"!==e[u][1].type||(i=u);const o={type:"setextHeading",start:Object.assign({},e[r][1].start),end:Object.assign({},e[e.length-1][1].end)};e[r][1].type="setextHeadingText",i?(e.splice(r,0,["enter",o,n]),e.splice(i+1,0,["exit",e[t][1],n]),e[t][1].end=Object.assign({},e[i][1].end)):e[t][1]=o;return e.push(["exit",o,n]),e}};const oe=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],ce=["pre","script","style","textarea"],se={name:"htmlFlow",tokenize:function(e,n,t){const r=this;let i,u,o,c,s;return function(n){return function(n){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(n),l}(n)};function l(c){return 33===c?(e.consume(c),a):47===c?(e.consume(c),u=!0,m):63===c?(e.consume(c),i=3,r.interrupt?n:H):h(c)?(e.consume(c),o=String.fromCharCode(c),g):t(c)}function a(u){return 45===u?(e.consume(u),i=2,f):91===u?(e.consume(u),i=5,c=0,d):h(u)?(e.consume(u),i=4,r.interrupt?n:H):t(u)}function f(i){return 45===i?(e.consume(i),r.interrupt?n:H):t(i)}function d(i){const u="CDATA[";return i===u.charCodeAt(c++)?(e.consume(i),6===c?r.interrupt?n:D:d):t(i)}function m(n){return h(n)?(e.consume(n),o=String.fromCharCode(n),g):t(n)}function g(c){if(null===c||47===c||62===c||v(c)){const s=47===c,l=o.toLowerCase();return s||u||!ce.includes(l)?oe.includes(o.toLowerCase())?(i=6,s?(e.consume(c),x):r.interrupt?n(c):D(c)):(i=7,r.interrupt&&!r.parser.lazy[r.now().line]?t(c):u?k(c):y(c)):(i=1,r.interrupt?n(c):D(c))}return 45===c||p(c)?(e.consume(c),o+=String.fromCharCode(c),g):t(c)}function x(i){return 62===i?(e.consume(i),r.interrupt?n:D):t(i)}function k(n){return b(n)?(e.consume(n),k):T(n)}function y(n){return 47===n?(e.consume(n),T):58===n||95===n||h(n)?(e.consume(n),S):b(n)?(e.consume(n),y):T(n)}function S(n){return 45===n||46===n||58===n||95===n||p(n)?(e.consume(n),S):E(n)}function E(n){return 61===n?(e.consume(n),A):b(n)?(e.consume(n),E):y(n)}function A(n){return null===n||60===n||61===n||62===n||96===n?t(n):34===n||39===n?(e.consume(n),s=n,I):b(n)?(e.consume(n),A):w(n)}function I(n){return n===s?(e.consume(n),s=null,C):null===n||F(n)?t(n):(e.consume(n),I)}function w(n){return null===n||34===n||39===n||47===n||60===n||61===n||62===n||96===n||v(n)?E(n):(e.consume(n),w)}function C(e){return 47===e||62===e||b(e)?y(e):t(e)}function T(n){return 62===n?(e.consume(n),z):t(n)}function z(n){return null===n||F(n)?D(n):b(n)?(e.consume(n),z):t(n)}function D(n){return 45===n&&2===i?(e.consume(n),L):60===n&&1===i?(e.consume(n),P):62===n&&4===i?(e.consume(n),R):63===n&&3===i?(e.consume(n),H):93===n&&5===i?(e.consume(n),j):!F(n)||6!==i&&7!==i?null===n||F(n)?(e.exit("htmlFlowData"),B(n)):(e.consume(n),D):(e.exit("htmlFlowData"),e.check(le,q,B)(n))}function B(n){return e.check(ae,_,q)(n)}function _(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),M}function M(n){return null===n||F(n)?B(n):(e.enter("htmlFlowData"),D(n))}function L(n){return 45===n?(e.consume(n),H):D(n)}function P(n){return 47===n?(e.consume(n),o="",O):D(n)}function O(n){if(62===n){const t=o.toLowerCase();return ce.includes(t)?(e.consume(n),R):D(n)}return h(n)&&o.length<8?(e.consume(n),o+=String.fromCharCode(n),O):D(n)}function j(n){return 93===n?(e.consume(n),H):D(n)}function H(n){return 62===n?(e.consume(n),R):45===n&&2===i?(e.consume(n),H):D(n)}function R(n){return null===n||F(n)?(e.exit("htmlFlowData"),q(n)):(e.consume(n),R)}function q(t){return e.exit("htmlFlow"),n(t)}},resolveTo:function(e){let n=e.length;for(;n--&&("enter"!==e[n][0]||"htmlFlow"!==e[n][1].type););n>1&&"linePrefix"===e[n-2][1].type&&(e[n][1].start=e[n-2][1].start,e[n+1][1].start=e[n-2][1].start,e.splice(n-2,2));return e},concrete:!0},le={tokenize:function(e,n,t){return function(r){return e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),e.attempt(z,n,t)}},partial:!0},ae={tokenize:function(e,n,t){const r=this;return function(n){if(F(n))return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),i;return t(n)};function i(e){return r.parser.lazy[r.now().line]?t(e):n(e)}},partial:!0};const fe={tokenize:function(e,n,t){const r=this;return function(n){if(null===n)return t(n);return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),i};function i(e){return r.parser.lazy[r.now().line]?t(e):n(e)}},partial:!0},de={name:"codeFenced",tokenize:function(e,n,t){const r=this,i={tokenize:function(e,n,t){let i=0;return o;function o(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),s}function s(n){return e.enter("codeFencedFence"),b(n)?I(e,l,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(n):l(n)}function l(n){return n===u?(e.enter("codeFencedFenceSequence"),a(n)):t(n)}function a(n){return n===u?(i++,e.consume(n),a):i>=c?(e.exit("codeFencedFenceSequence"),b(n)?I(e,f,"whitespace")(n):f(n)):t(n)}function f(r){return null===r||F(r)?(e.exit("codeFencedFence"),n(r)):t(r)}},partial:!0};let u,o=0,c=0;return function(n){return function(n){const t=r.events[r.events.length-1];return o=t&&"linePrefix"===t[1].type?t[2].sliceSerialize(t[1],!0).length:0,u=n,e.enter("codeFenced"),e.enter("codeFencedFence"),e.enter("codeFencedFenceSequence"),s(n)}(n)};function s(n){return n===u?(c++,e.consume(n),s):c<3?t(n):(e.exit("codeFencedFenceSequence"),b(n)?I(e,l,"whitespace")(n):l(n))}function l(t){return null===t||F(t)?(e.exit("codeFencedFence"),r.interrupt?n(t):e.check(fe,h,k)(t)):(e.enter("codeFencedFenceInfo"),e.enter("chunkString",{contentType:"string"}),a(t))}function a(n){return null===n||F(n)?(e.exit("chunkString"),e.exit("codeFencedFenceInfo"),l(n)):b(n)?(e.exit("chunkString"),e.exit("codeFencedFenceInfo"),I(e,f,"whitespace")(n)):96===n&&n===u?t(n):(e.consume(n),a)}function f(n){return null===n||F(n)?l(n):(e.enter("codeFencedFenceMeta"),e.enter("chunkString",{contentType:"string"}),d(n))}function d(n){return null===n||F(n)?(e.exit("chunkString"),e.exit("codeFencedFenceMeta"),l(n)):96===n&&n===u?t(n):(e.consume(n),d)}function h(n){return e.attempt(i,k,p)(n)}function p(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),m}function m(n){return o>0&&b(n)?I(e,g,"linePrefix",o+1)(n):g(n)}function g(n){return null===n||F(n)?e.check(fe,h,k)(n):(e.enter("codeFlowValue"),x(n))}function x(n){return null===n||F(n)?(e.exit("codeFlowValue"),g(n)):(e.consume(n),x)}function k(t){return e.exit("codeFenced"),n(t)}},concrete:!0};const he=document.createElement("i");function pe(e){const n="&"+e+";";he.innerHTML=n;const t=he.textContent;return(59!==t.charCodeAt(t.length-1)||"semi"===e)&&(t!==n&&t)}const me={name:"characterReference",tokenize:function(e,n,t){const r=this;let i,u,o=0;return function(n){return e.enter("characterReference"),e.enter("characterReferenceMarker"),e.consume(n),e.exit("characterReferenceMarker"),c};function c(n){return 35===n?(e.enter("characterReferenceMarkerNumeric"),e.consume(n),e.exit("characterReferenceMarkerNumeric"),s):(e.enter("characterReferenceValue"),i=31,u=p,l(n))}function s(n){return 88===n||120===n?(e.enter("characterReferenceMarkerHexadecimal"),e.consume(n),e.exit("characterReferenceMarkerHexadecimal"),e.enter("characterReferenceValue"),i=6,u=k,l):(e.enter("characterReferenceValue"),i=7,u=x,l(n))}function l(c){if(59===c&&o){const i=e.exit("characterReferenceValue");return u!==p||pe(r.sliceSerialize(i))?(e.enter("characterReferenceMarker"),e.consume(c),e.exit("characterReferenceMarker"),e.exit("characterReference"),n):t(c)}return u(c)&&o++<i?(e.consume(c),l):t(c)}}};const ge={name:"characterEscape",tokenize:function(e,n,t){return function(n){return e.enter("characterEscape"),e.enter("escapeMarker"),e.consume(n),e.exit("escapeMarker"),r};function r(r){return y(r)?(e.enter("characterEscapeValue"),e.consume(r),e.exit("characterEscapeValue"),e.exit("characterEscape"),n):t(r)}}};const xe={name:"lineEnding",tokenize:function(e,n){return function(t){return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),I(e,n,"linePrefix")}}};const ke={name:"labelEnd",tokenize:function(e,n,t){const r=this;let i,u,o=r.events.length;for(;o--;)if(("labelImage"===r.events[o][1].type||"labelLink"===r.events[o][1].type)&&!r.events[o][1]._balanced){i=r.events[o][1];break}return function(n){if(!i)return t(n);if(i._inactive)return a(n);return u=r.parser.defined.includes(X(r.sliceSerialize({start:i.end,end:r.now()}))),e.enter("labelEnd"),e.enter("labelMarker"),e.consume(n),e.exit("labelMarker"),e.exit("labelEnd"),c};function c(n){return 40===n?e.attempt(ye,l,u?l:a)(n):91===n?e.attempt(Fe,l,u?s:a)(n):u?l(n):a(n)}function s(n){return e.attempt(ve,l,a)(n)}function l(e){return n(e)}function a(e){return i._balanced=!0,t(e)}},resolveTo:function(e,n){let t,r,i,u,o=e.length,c=0;for(;o--;)if(t=e[o][1],r){if("link"===t.type||"labelLink"===t.type&&t._inactive)break;"enter"===e[o][0]&&"labelLink"===t.type&&(t._inactive=!0)}else if(i){if("enter"===e[o][0]&&("labelImage"===t.type||"labelLink"===t.type)&&!t._balanced&&(r=o,"labelLink"!==t.type)){c=2;break}}else"labelEnd"===t.type&&(i=o);const a={type:"labelLink"===e[r][1].type?"link":"image",start:Object.assign({},e[r][1].start),end:Object.assign({},e[e.length-1][1].end)},f={type:"label",start:Object.assign({},e[r][1].start),end:Object.assign({},e[i][1].end)},d={type:"labelText",start:Object.assign({},e[r+c+2][1].end),end:Object.assign({},e[i-2][1].start)};return u=[["enter",a,n],["enter",f,n]],u=l(u,e.slice(r+1,r+c+3)),u=l(u,[["enter",d,n]]),u=l(u,V(n.parser.constructs.insideSpan.null,e.slice(r+c+4,i-3),n)),u=l(u,[["exit",d,n],e[i-2],e[i-1],["exit",f,n]]),u=l(u,e.slice(i+1)),u=l(u,[["exit",a,n]]),s(e,r,e.length,u),e},resolveAll:function(e){let n=-1;for(;++n<e.length;){const t=e[n][1];"labelImage"!==t.type&&"labelLink"!==t.type&&"labelEnd"!==t.type||(e.splice(n+1,"labelImage"===t.type?4:2),t.type="data",n++)}return e}},ye={tokenize:function(e,n,t){return function(n){return e.enter("resource"),e.enter("resourceMarker"),e.consume(n),e.exit("resourceMarker"),r};function r(n){return v(n)?K(e,i)(n):i(n)}function i(n){return 41===n?l(n):Y(e,u,o,"resourceDestination","resourceDestinationLiteral","resourceDestinationLiteralMarker","resourceDestinationRaw","resourceDestinationString",32)(n)}function u(n){return v(n)?K(e,c)(n):l(n)}function o(e){return t(e)}function c(n){return 34===n||39===n||40===n?J(e,s,t,"resourceTitle","resourceTitleMarker","resourceTitleString")(n):l(n)}function s(n){return v(n)?K(e,l)(n):l(n)}function l(r){return 41===r?(e.enter("resourceMarker"),e.consume(r),e.exit("resourceMarker"),e.exit("resource"),n):t(r)}}},Fe={tokenize:function(e,n,t){const r=this;return function(n){return G.call(r,e,i,u,"reference","referenceMarker","referenceString")(n)};function i(e){return r.parser.defined.includes(X(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)))?n(e):t(e)}function u(e){return t(e)}}},ve={tokenize:function(e,n,t){return function(n){return e.enter("reference"),e.enter("referenceMarker"),e.consume(n),e.exit("referenceMarker"),r};function r(r){return 93===r?(e.enter("referenceMarker"),e.consume(r),e.exit("referenceMarker"),e.exit("reference"),n):t(r)}}};const be={name:"labelStartImage",tokenize:function(e,n,t){const r=this;return function(n){return e.enter("labelImage"),e.enter("labelImageMarker"),e.consume(n),e.exit("labelImageMarker"),i};function i(n){return 91===n?(e.enter("labelMarker"),e.consume(n),e.exit("labelMarker"),e.exit("labelImage"),u):t(n)}function u(e){return 94===e&&"_hiddenFootnoteSupport"in r.parser.constructs?t(e):n(e)}},resolveAll:ke.resolveAll};function Se(e){return null===e||v(e)||E(e)?1:S(e)?2:void 0}const Ee={name:"attention",tokenize:function(e,n){const t=this.parser.constructs.attentionMarkers.null,r=this.previous,i=Se(r);let u;return function(n){return u=n,e.enter("attentionSequence"),o(n)};function o(c){if(c===u)return e.consume(c),o;const s=e.exit("attentionSequence"),l=Se(c),a=!l||2===l&&i||t.includes(c),f=!i||2===i&&l||t.includes(r);return s._open=Boolean(42===u?a:a&&(i||!f)),s._close=Boolean(42===u?f:f&&(l||!a)),n(c)}},resolveAll:function(e,n){let t,r,i,u,o,c,a,f,d=-1;for(;++d<e.length;)if("enter"===e[d][0]&&"attentionSequence"===e[d][1].type&&e[d][1]._close)for(t=d;t--;)if("exit"===e[t][0]&&"attentionSequence"===e[t][1].type&&e[t][1]._open&&n.sliceSerialize(e[t][1]).charCodeAt(0)===n.sliceSerialize(e[d][1]).charCodeAt(0)){if((e[t][1]._close||e[d][1]._open)&&(e[d][1].end.offset-e[d][1].start.offset)%3&&!((e[t][1].end.offset-e[t][1].start.offset+e[d][1].end.offset-e[d][1].start.offset)%3))continue;c=e[t][1].end.offset-e[t][1].start.offset>1&&e[d][1].end.offset-e[d][1].start.offset>1?2:1;const h=Object.assign({},e[t][1].end),p=Object.assign({},e[d][1].start);Ae(h,-c),Ae(p,c),u={type:c>1?"strongSequence":"emphasisSequence",start:h,end:Object.assign({},e[t][1].end)},o={type:c>1?"strongSequence":"emphasisSequence",start:Object.assign({},e[d][1].start),end:p},i={type:c>1?"strongText":"emphasisText",start:Object.assign({},e[t][1].end),end:Object.assign({},e[d][1].start)},r={type:c>1?"strong":"emphasis",start:Object.assign({},u.start),end:Object.assign({},o.end)},e[t][1].end=Object.assign({},u.start),e[d][1].start=Object.assign({},o.end),a=[],e[t][1].end.offset-e[t][1].start.offset&&(a=l(a,[["enter",e[t][1],n],["exit",e[t][1],n]])),a=l(a,[["enter",r,n],["enter",u,n],["exit",u,n],["enter",i,n]]),a=l(a,V(n.parser.constructs.insideSpan.null,e.slice(t+1,d),n)),a=l(a,[["exit",i,n],["enter",o,n],["exit",o,n],["exit",r,n]]),e[d][1].end.offset-e[d][1].start.offset?(f=2,a=l(a,[["enter",e[d][1],n],["exit",e[d][1],n]])):f=0,s(e,t-1,d-t+3,a),d=t+a.length-f-2;break}d=-1;for(;++d<e.length;)"attentionSequence"===e[d][1].type&&(e[d][1].type="data");return e}};function Ae(e,n){e.column+=n,e.offset+=n,e._bufferIndex+=n}const Ie={name:"autolink",tokenize:function(e,n,t){let r=0;return function(n){return e.enter("autolink"),e.enter("autolinkMarker"),e.consume(n),e.exit("autolinkMarker"),e.enter("autolinkProtocol"),i};function i(n){return h(n)?(e.consume(n),u):s(n)}function u(e){return 43===e||45===e||46===e||p(e)?(r=1,o(e)):s(e)}function o(n){return 58===n?(e.consume(n),r=0,c):(43===n||45===n||46===n||p(n))&&r++<32?(e.consume(n),o):(r=0,s(n))}function c(r){return 62===r?(e.exit("autolinkProtocol"),e.enter("autolinkMarker"),e.consume(r),e.exit("autolinkMarker"),e.exit("autolink"),n):null===r||32===r||60===r||g(r)?t(r):(e.consume(r),c)}function s(n){return 64===n?(e.consume(n),l):m(n)?(e.consume(n),s):t(n)}function l(e){return p(e)?a(e):t(e)}function a(t){return 46===t?(e.consume(t),r=0,l):62===t?(e.exit("autolinkProtocol").type="autolinkEmail",e.enter("autolinkMarker"),e.consume(t),e.exit("autolinkMarker"),e.exit("autolink"),n):f(t)}function f(n){if((45===n||p(n))&&r++<63){const t=45===n?f:a;return e.consume(n),t}return t(n)}}};const we={name:"htmlText",tokenize:function(e,n,t){const r=this;let i,u,o;return function(n){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(n),c};function c(n){return 33===n?(e.consume(n),s):47===n?(e.consume(n),A):63===n?(e.consume(n),S):h(n)?(e.consume(n),T):t(n)}function s(n){return 45===n?(e.consume(n),l):91===n?(e.consume(n),u=0,m):h(n)?(e.consume(n),y):t(n)}function l(n){return 45===n?(e.consume(n),d):t(n)}function a(n){return null===n?t(n):45===n?(e.consume(n),f):F(n)?(o=a,j(n)):(e.consume(n),a)}function f(n){return 45===n?(e.consume(n),d):a(n)}function d(e){return 62===e?O(e):45===e?f(e):a(e)}function m(n){const r="CDATA[";return n===r.charCodeAt(u++)?(e.consume(n),6===u?g:m):t(n)}function g(n){return null===n?t(n):93===n?(e.consume(n),x):F(n)?(o=g,j(n)):(e.consume(n),g)}function x(n){return 93===n?(e.consume(n),k):g(n)}function k(n){return 62===n?O(n):93===n?(e.consume(n),k):g(n)}function y(n){return null===n||62===n?O(n):F(n)?(o=y,j(n)):(e.consume(n),y)}function S(n){return null===n?t(n):63===n?(e.consume(n),E):F(n)?(o=S,j(n)):(e.consume(n),S)}function E(e){return 62===e?O(e):S(e)}function A(n){return h(n)?(e.consume(n),w):t(n)}function w(n){return 45===n||p(n)?(e.consume(n),w):C(n)}function C(n){return F(n)?(o=C,j(n)):b(n)?(e.consume(n),C):O(n)}function T(n){return 45===n||p(n)?(e.consume(n),T):47===n||62===n||v(n)?z(n):t(n)}function z(n){return 47===n?(e.consume(n),O):58===n||95===n||h(n)?(e.consume(n),D):F(n)?(o=z,j(n)):b(n)?(e.consume(n),z):O(n)}function D(n){return 45===n||46===n||58===n||95===n||p(n)?(e.consume(n),D):B(n)}function B(n){return 61===n?(e.consume(n),_):F(n)?(o=B,j(n)):b(n)?(e.consume(n),B):z(n)}function _(n){return null===n||60===n||61===n||62===n||96===n?t(n):34===n||39===n?(e.consume(n),i=n,M):F(n)?(o=_,j(n)):b(n)?(e.consume(n),_):(e.consume(n),L)}function M(n){return n===i?(e.consume(n),i=void 0,P):null===n?t(n):F(n)?(o=M,j(n)):(e.consume(n),M)}function L(n){return null===n||34===n||39===n||60===n||61===n||96===n?t(n):47===n||62===n||v(n)?z(n):(e.consume(n),L)}function P(e){return 47===e||62===e||v(e)?z(e):t(e)}function O(r){return 62===r?(e.consume(r),e.exit("htmlTextData"),e.exit("htmlText"),n):t(r)}function j(n){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),H}function H(n){return b(n)?I(e,R,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(n):R(n)}function R(n){return e.enter("htmlTextData"),o(n)}}};const Ce={name:"labelStartLink",tokenize:function(e,n,t){const r=this;return function(n){return e.enter("labelLink"),e.enter("labelMarker"),e.consume(n),e.exit("labelMarker"),e.exit("labelLink"),i};function i(e){return 94===e&&"_hiddenFootnoteSupport"in r.parser.constructs?t(e):n(e)}},resolveAll:ke.resolveAll};const Te={name:"hardBreakEscape",tokenize:function(e,n,t){return function(n){return e.enter("hardBreakEscape"),e.consume(n),r};function r(r){return F(r)?(e.exit("hardBreakEscape"),n(r)):t(r)}}};const ze={name:"codeText",tokenize:function(e,n,t){let r,i,u=0;return function(n){return e.enter("codeText"),e.enter("codeTextSequence"),o(n)};function o(n){return 96===n?(e.consume(n),u++,o):(e.exit("codeTextSequence"),c(n))}function c(n){return null===n?t(n):32===n?(e.enter("space"),e.consume(n),e.exit("space"),c):96===n?(i=e.enter("codeTextSequence"),r=0,l(n)):F(n)?(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),c):(e.enter("codeTextData"),s(n))}function s(n){return null===n||32===n||96===n||F(n)?(e.exit("codeTextData"),c(n)):(e.consume(n),s)}function l(t){return 96===t?(e.consume(t),r++,l):r===u?(e.exit("codeTextSequence"),e.exit("codeText"),n(t)):(i.type="codeTextData",s(t))}},resolve:function(e){let n,t,r=e.length-4,i=3;if(!("lineEnding"!==e[i][1].type&&"space"!==e[i][1].type||"lineEnding"!==e[r][1].type&&"space"!==e[r][1].type))for(n=i;++n<r;)if("codeTextData"===e[n][1].type){e[i][1].type="codeTextPadding",e[r][1].type="codeTextPadding",i+=2,r-=2;break}n=i-1,r++;for(;++n<=r;)void 0===t?n!==r&&"lineEnding"!==e[n][1].type&&(t=n):n!==r&&"lineEnding"!==e[n][1].type||(e[t][1].type="codeTextData",n!==t+2&&(e[t][1].end=e[n-1][1].end,e.splice(t+2,n-t-2),r-=n-t-2,n=t+2),t=void 0);return e},previous:function(e){return 96!==e||"characterEscape"===this.events[this.events.length-1][1].type}};const De={42:U,43:U,45:U,48:U,49:U,50:U,51:U,52:U,53:U,54:U,55:U,56:U,57:U,62:Z},Be={91:ee},_e={[-2]:te,[-1]:te,32:te},Me={35:ie,42:N,45:[ue,N],60:se,61:ue,95:N,96:de,126:de},Le={38:me,92:ge},Pe={[-5]:xe,[-4]:xe,[-3]:xe,33:be,38:me,42:Ee,60:[Ie,we],91:Ce,92:[Te,ge],93:ke,95:Ee,96:ze},Oe={null:[Ee,P]},je={null:[42,95]},He={null:[]};function Re(e){const n=function(e){const n={};let t=-1;for(;++t<e.length;)f(n,e[t]);return n}([r,...(e||{}).extensions||[]]),t={defined:[],lazy:{},constructs:n,content:i(w),document:i(C),flow:i(L),string:i(O),text:i(j)};return t;function i(e){return function(n){return Q(t,e,n)}}}const qe=/[\0\t\n\r]/g;function Ve(e,n){const t=Number.parseInt(e,n);return t<9||11===t||t>13&&t<32||t>126&&t<160||t>55295&&t<57344||t>64975&&t<65008||!(65535&~t)||65534==(65535&t)||t>1114111?"\ufffd":String.fromCharCode(t)}const Qe=/\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi;function Ne(e,n,t){if(n)return n;if(35===t.charCodeAt(0)){const e=t.charCodeAt(1),n=120===e||88===e;return Ve(t.slice(n?2:1),n?16:10)}return pe(t)||e}function Ue(e){return e&&"object"==typeof e?"position"in e||"type"in e?We(e.position):"start"in e||"end"in e?We(e):"line"in e||"column"in e?$e(e):"":""}function $e(e){return Ze(e&&e.line)+":"+Ze(e&&e.column)}function We(e){return $e(e&&e.start)+"-"+$e(e&&e.end)}function Ze(e){return e&&"number"==typeof e?e:1}const Ye={}.hasOwnProperty,Ge=function(e,n,t){return"string"!=typeof n&&(t=n,n=void 0),function(e){const n={transforms:[],canContainEols:["emphasis","fragment","heading","paragraph","strong"],enter:{autolink:l(ue),autolinkProtocol:T,autolinkEmail:T,atxHeading:l(ne),blockQuote:l(Y),characterEscape:T,characterReference:T,codeFenced:l(G),codeFencedFenceInfo:a,codeFencedFenceMeta:a,codeIndented:l(G,a),codeText:l(J,a),codeTextData:T,data:T,codeFlowValue:T,definition:l(K),definitionDestinationString:a,definitionLabelString:a,definitionTitleString:a,emphasis:l(ee),hardBreakEscape:l(te),hardBreakTrailing:l(te),htmlFlow:l(re,a),htmlFlowData:T,htmlText:l(re,a),htmlTextData:T,image:l(ie),label:a,link:l(ue),listItem:l(ce),listItemValue:g,listOrdered:l(oe,m),listUnordered:l(oe),paragraph:l(se),reference:Q,referenceString:a,resourceDestinationString:a,resourceTitleString:a,setextHeading:l(ne),strong:l(le),thematicBreak:l(fe)},exit:{atxHeading:d(),atxHeadingSequence:A,autolink:d(),autolinkEmail:Z,autolinkProtocol:W,blockQuote:d(),characterEscapeValue:z,characterReferenceMarkerHexadecimal:U,characterReferenceMarkerNumeric:U,characterReferenceValue:$,codeFenced:d(F),codeFencedFence:y,codeFencedFenceInfo:x,codeFencedFenceMeta:k,codeFlowValue:z,codeIndented:d(v),codeText:d(L),codeTextData:z,data:z,definition:d(),definitionDestinationString:E,definitionLabelString:b,definitionTitleString:S,emphasis:d(),hardBreakEscape:d(B),hardBreakTrailing:d(B),htmlFlow:d(_),htmlFlowData:z,htmlText:d(M),htmlTextData:z,image:d(O),label:H,labelText:j,lineEnding:D,link:d(P),listItem:d(),listOrdered:d(),listUnordered:d(),paragraph:d(),referenceString:N,resourceDestinationString:R,resourceTitleString:q,resource:V,setextHeading:d(C),setextHeadingLineSequence:w,setextHeadingText:I,strong:d(),thematicBreak:d()}};Ke(n,(e||{}).mdastExtensions||[]);const t={};return r;function r(e){let t={type:"root",children:[]};const r={stack:[t],tokenStack:[],config:n,enter:f,exit:h,buffer:a,resume:p,setData:c,getData:s},u=[];let o=-1;for(;++o<e.length;)if("listOrdered"===e[o][1].type||"listUnordered"===e[o][1].type)if("enter"===e[o][0])u.push(o);else{o=i(e,u.pop(),o)}for(o=-1;++o<e.length;){const t=n[e[o][0]];Ye.call(t,e[o][1].type)&&t[e[o][1].type].call(Object.assign({sliceSerialize:e[o][2].sliceSerialize},r),e[o][1])}if(r.tokenStack.length>0){const e=r.tokenStack[r.tokenStack.length-1];(e[1]||en).call(r,void 0,e[0])}for(t.position={start:Je(e.length>0?e[0][1].start:{line:1,column:1,offset:0}),end:Je(e.length>0?e[e.length-2][1].end:{line:1,column:1,offset:0})},o=-1;++o<n.transforms.length;)t=n.transforms[o](t)||t;return t}function i(e,n,t){let r,i,u,o,c=n-1,s=-1,l=!1;for(;++c<=t;){const n=e[c];if("listUnordered"===n[1].type||"listOrdered"===n[1].type||"blockQuote"===n[1].type?("enter"===n[0]?s++:s--,o=void 0):"lineEndingBlank"===n[1].type?"enter"===n[0]&&(!r||o||s||u||(u=c),o=void 0):"linePrefix"===n[1].type||"listItemValue"===n[1].type||"listItemMarker"===n[1].type||"listItemPrefix"===n[1].type||"listItemPrefixWhitespace"===n[1].type||(o=void 0),!s&&"enter"===n[0]&&"listItemPrefix"===n[1].type||-1===s&&"exit"===n[0]&&("listUnordered"===n[1].type||"listOrdered"===n[1].type)){if(r){let o=c;for(i=void 0;o--;){const n=e[o];if("lineEnding"===n[1].type||"lineEndingBlank"===n[1].type){if("exit"===n[0])continue;i&&(e[i][1].type="lineEndingBlank",l=!0),n[1].type="lineEnding",i=o}else if("linePrefix"!==n[1].type&&"blockQuotePrefix"!==n[1].type&&"blockQuotePrefixWhitespace"!==n[1].type&&"blockQuoteMarker"!==n[1].type&&"listItemIndent"!==n[1].type)break}u&&(!i||u<i)&&(r._spread=!0),r.end=Object.assign({},i?e[i][1].start:n[1].end),e.splice(i||c,0,["exit",r,n[2]]),c++,t++}"listItemPrefix"===n[1].type&&(r={type:"listItem",_spread:!1,start:Object.assign({},n[1].start),end:void 0},e.splice(c,0,["enter",r,n[2]]),c++,t++,u=void 0,o=!0)}}return e[n][1]._spread=l,t}function c(e,n){t[e]=n}function s(e){return t[e]}function l(e,n){return t;function t(t){f.call(this,e(t),t),n&&n.call(this,t)}}function a(){this.stack.push({type:"fragment",children:[]})}function f(e,n,t){return this.stack[this.stack.length-1].children.push(e),this.stack.push(e),this.tokenStack.push([n,t]),e.position={start:Je(n.start)},e}function d(e){return n;function n(n){e&&e.call(this,n),h.call(this,n)}}function h(e,n){const t=this.stack.pop(),r=this.tokenStack.pop();if(!r)throw new Error("Cannot close `"+e.type+"` ("+Ue({start:e.start,end:e.end})+"): it\u2019s not open");if(r[0].type!==e.type)if(n)n.call(this,e,r[0]);else{(r[1]||en).call(this,e,r[0])}return t.position.end=Je(e.end),t}function p(){return function(e,n){const t=n||u;return o(e,"boolean"!=typeof t.includeImageAlt||t.includeImageAlt,"boolean"!=typeof t.includeHtml||t.includeHtml)}(this.stack.pop())}function m(){c("expectingFirstListItemValue",!0)}function g(e){if(s("expectingFirstListItemValue")){this.stack[this.stack.length-2].start=Number.parseInt(this.sliceSerialize(e),10),c("expectingFirstListItemValue")}}function x(){const e=this.resume();this.stack[this.stack.length-1].lang=e}function k(){const e=this.resume();this.stack[this.stack.length-1].meta=e}function y(){s("flowCodeInside")||(this.buffer(),c("flowCodeInside",!0))}function F(){const e=this.resume();this.stack[this.stack.length-1].value=e.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g,""),c("flowCodeInside")}function v(){const e=this.resume();this.stack[this.stack.length-1].value=e.replace(/(\r?\n|\r)$/g,"")}function b(e){const n=this.resume(),t=this.stack[this.stack.length-1];t.label=n,t.identifier=X(this.sliceSerialize(e)).toLowerCase()}function S(){const e=this.resume();this.stack[this.stack.length-1].title=e}function E(){const e=this.resume();this.stack[this.stack.length-1].url=e}function A(e){const n=this.stack[this.stack.length-1];if(!n.depth){const t=this.sliceSerialize(e).length;n.depth=t}}function I(){c("setextHeadingSlurpLineEnding",!0)}function w(e){this.stack[this.stack.length-1].depth=61===this.sliceSerialize(e).charCodeAt(0)?1:2}function C(){c("setextHeadingSlurpLineEnding")}function T(e){const n=this.stack[this.stack.length-1];let t=n.children[n.children.length-1];t&&"text"===t.type||(t=ae(),t.position={start:Je(e.start)},n.children.push(t)),this.stack.push(t)}function z(e){const n=this.stack.pop();n.value+=this.sliceSerialize(e),n.position.end=Je(e.end)}function D(e){const t=this.stack[this.stack.length-1];if(s("atHardBreak")){return t.children[t.children.length-1].position.end=Je(e.end),void c("atHardBreak")}!s("setextHeadingSlurpLineEnding")&&n.canContainEols.includes(t.type)&&(T.call(this,e),z.call(this,e))}function B(){c("atHardBreak",!0)}function _(){const e=this.resume();this.stack[this.stack.length-1].value=e}function M(){const e=this.resume();this.stack[this.stack.length-1].value=e}function L(){const e=this.resume();this.stack[this.stack.length-1].value=e}function P(){const e=this.stack[this.stack.length-1];if(s("inReference")){const n=s("referenceType")||"shortcut";e.type+="Reference",e.referenceType=n,delete e.url,delete e.title}else delete e.identifier,delete e.label;c("referenceType")}function O(){const e=this.stack[this.stack.length-1];if(s("inReference")){const n=s("referenceType")||"shortcut";e.type+="Reference",e.referenceType=n,delete e.url,delete e.title}else delete e.identifier,delete e.label;c("referenceType")}function j(e){const n=this.sliceSerialize(e),t=this.stack[this.stack.length-2];t.label=function(e){return e.replace(Qe,Ne)}(n),t.identifier=X(n).toLowerCase()}function H(){const e=this.stack[this.stack.length-1],n=this.resume(),t=this.stack[this.stack.length-1];if(c("inReference",!0),"link"===t.type){const n=e.children;t.children=n}else t.alt=n}function R(){const e=this.resume();this.stack[this.stack.length-1].url=e}function q(){const e=this.resume();this.stack[this.stack.length-1].title=e}function V(){c("inReference")}function Q(){c("referenceType","collapsed")}function N(e){const n=this.resume(),t=this.stack[this.stack.length-1];t.label=n,t.identifier=X(this.sliceSerialize(e)).toLowerCase(),c("referenceType","full")}function U(e){c("characterReferenceType",e.type)}function $(e){const n=this.sliceSerialize(e),t=s("characterReferenceType");let r;if(t)r=Ve(n,"characterReferenceMarkerNumeric"===t?10:16),c("characterReferenceType");else{r=pe(n)}const i=this.stack.pop();i.value+=r,i.position.end=Je(e.end)}function W(e){z.call(this,e);this.stack[this.stack.length-1].url=this.sliceSerialize(e)}function Z(e){z.call(this,e);this.stack[this.stack.length-1].url="mailto:"+this.sliceSerialize(e)}function Y(){return{type:"blockquote",children:[]}}function G(){return{type:"code",lang:null,meta:null,value:""}}function J(){return{type:"inlineCode",value:""}}function K(){return{type:"definition",identifier:"",label:null,title:null,url:""}}function ee(){return{type:"emphasis",children:[]}}function ne(){return{type:"heading",depth:void 0,children:[]}}function te(){return{type:"break"}}function re(){return{type:"html",value:""}}function ie(){return{type:"image",title:null,url:"",alt:null}}function ue(){return{type:"link",title:null,url:"",children:[]}}function oe(e){return{type:"list",ordered:"listOrdered"===e.type,start:null,spread:e._spread,children:[]}}function ce(e){return{type:"listItem",spread:e._spread,checked:null,children:[]}}function se(){return{type:"paragraph",children:[]}}function le(){return{type:"strong",children:[]}}function ae(){return{type:"text",value:""}}function fe(){return{type:"thematicBreak"}}}(t)(function(e){for(;!D(e););return e}(Re(t).document().write(function(){let e,n=1,t="",r=!0;return function(i,u,o){const c=[];let s,l,a,f,d;for(i=t+i.toString(u),a=0,t="",r&&(65279===i.charCodeAt(0)&&a++,r=void 0);a<i.length;){if(qe.lastIndex=a,s=qe.exec(i),f=s&&void 0!==s.index?s.index:i.length,d=i.charCodeAt(f),!s){t=i.slice(a);break}if(10===d&&a===f&&e)c.push(-3),e=void 0;else switch(e&&(c.push(-5),e=void 0),a<f&&(c.push(i.slice(a,f)),n+=f-a),d){case 0:c.push(65533),n++;break;case 9:for(l=4*Math.ceil(n/4),c.push(-2);n++<l;)c.push(-1);break;case 10:c.push(-4),n=1;break;default:e=!0,n=1}a=f+1}return o&&(e&&c.push(-5),t&&c.push(t),c.push(null)),c}}()(e,n,!0))))};function Je(e){return{line:e.line,column:e.column,offset:e.offset}}function Ke(e,n){let t=-1;for(;++t<n.length;){const r=n[t];Array.isArray(r)?Ke(e,r):Xe(e,r)}}function Xe(e,n){let t;for(t in n)if(Ye.call(n,t))if("canContainEols"===t){const r=n[t];r&&e[t].push(...r)}else if("transforms"===t){const r=n[t];r&&e[t].push(...r)}else if("enter"===t||"exit"===t){const r=n[t];r&&Object.assign(e[t],r)}}function en(e,n){throw e?new Error("Cannot close `"+e.type+"` ("+Ue({start:e.start,end:e.end})+"): a different token (`"+n.type+"`, "+Ue({start:n.start,end:n.end})+") is open"):new Error("Cannot close document, a token (`"+n.type+"`, "+Ue({start:n.start,end:n.end})+") is still open")}var nn=t(60513);function tn(e){const n=function(e){const n=e.replace(/\n{2,}/g,"\n");return(0,nn.T)(n)}(e),{children:t}=Ge(n),r=[[]];let i=0;function u(e,n="normal"){if("text"===e.type){e.value.split("\n").forEach(((e,t)=>{0!==t&&(i++,r.push([])),e.split(" ").forEach((e=>{e&&r[i].push({content:e,type:n})}))}))}else"strong"!==e.type&&"emphasis"!==e.type||e.children.forEach((n=>{u(n,e.type)}))}return t.forEach((e=>{"paragraph"===e.type&&e.children.forEach((e=>{u(e)}))})),r}function rn(e,n){var t;return un(e,[],(t=n.content,Intl.Segmenter?[...(new Intl.Segmenter).segment(t)].map((e=>e.segment)):[...t]),n.type)}function un(e,n,t,r){if(0===t.length)return[{content:n.join(""),type:r},{content:"",type:r}];const[i,...u]=t,o=[...n,i];return e([{content:o.join(""),type:r}])?un(e,o,u,r):(0===n.length&&i&&(n.push(i),t.shift()),[{content:n.join(""),type:r},{content:t.join(""),type:r}])}function on(e,n){if(e.some((({content:e})=>e.includes("\n"))))throw new Error("splitLineToFitWidth does not support newlines in the line");return cn(e,n)}function cn(e,n,t=[],r=[]){if(0===e.length)return r.length>0&&t.push(r),t.length>0?t:[];let i="";" "===e[0].content&&(i=" ",e.shift());const u=e.shift()??{content:" ",type:"normal"},o=[...r];if(""!==i&&o.push({content:i,type:"normal"}),o.push(u),n(o))return cn(e,n,t,o);if(r.length>0)t.push(r),e.unshift(u);else if(u.content){const[r,i]=rn(n,u);t.push([r]),i.content&&e.unshift(i)}return cn(e,n,t)}function sn(e,n,t){return e.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",n*t-.1+"em").attr("dy",t+"em")}function ln(e,n,t){const r=e.append("text"),i=sn(r,1,n);fn(i,t);const u=i.node().getComputedTextLength();return r.remove(),u}function an(e,n,t){var r;const i=e.append("text"),u=sn(i,1,n);fn(u,[{content:t,type:"normal"}]);const o=null==(r=u.node())?void 0:r.getBoundingClientRect();return o&&i.remove(),o}function fn(e,n){e.text(""),n.forEach(((n,t)=>{const r=e.append("tspan").attr("font-style","emphasis"===n.type?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight","strong"===n.type?"bold":"normal");0===t?r.text(n.content):r.text(" "+n.content)}))}const dn=(e,n="",{style:t="",isTitle:r=!1,classes:u="",useHtmlLabels:o=!0,isNode:c=!0,width:s=200,addSvgBackground:l=!1}={})=>{if(i.l.info("createText",n,t,r,u,o,c,l),o){const r=function(e){const{children:n}=Ge(e);return n.map((function e(n){return"text"===n.type?n.value.replace(/\n/g,"<br/>"):"strong"===n.type?`<strong>${n.children.map(e).join("")}</strong>`:"emphasis"===n.type?`<em>${n.children.map(e).join("")}</em>`:"paragraph"===n.type?`<p>${n.children.map(e).join("")}</p>`:`Unsupported markdown: ${n.type}`})).join("")}(n),o=function(e,n,t,r,i=!1){const u=e.append("foreignObject"),o=u.append("xhtml:div"),c=n.label,s=n.isNode?"nodeLabel":"edgeLabel";var l,a;o.html(`\n <span class="${s} ${r}" `+(n.labelStyle?'style="'+n.labelStyle+'"':"")+">"+c+"</span>"),l=o,(a=n.labelStyle)&&l.attr("style",a),o.style("display","table-cell"),o.style("white-space","nowrap"),o.style("max-width",t+"px"),o.attr("xmlns","http://www.w3.org/1999/xhtml"),i&&o.attr("class","labelBkg");let f=o.node().getBoundingClientRect();return f.width===t&&(o.style("display","table"),o.style("white-space","break-spaces"),o.style("width",t+"px"),f=o.node().getBoundingClientRect()),u.style("width",f.width),u.style("height",f.height),u.node()}(e,{isNode:c,label:(0,i.M)(r).replace(/fa[blrs]?:fa-[\w-]+/g,(e=>`<i class='${e.replace(":"," ")}'></i>`)),labelStyle:t.replace("fill:","color:")},s,u,l);return o}{const t=function(e,n,t,r=!1){const i=n.append("g"),u=i.insert("rect").attr("class","background"),o=i.append("text").attr("y","-10.1");let c=0;for(const s of t){const n=n=>ln(i,1.1,n)<=e,t=n(s)?[s]:on(s,n);for(const e of t)fn(sn(o,c,1.1),e),c++}if(r){const e=o.node().getBBox(),n=2;return u.attr("x",-n).attr("y",-n).attr("width",e.width+2*n).attr("height",e.height+2*n),i.node()}return o.node()}(s,e,tn(n),l);return t}}}}]); \ No newline at end of file diff --git a/assets/js/94564.9666d094.js b/assets/js/94564.9666d094.js new file mode 100644 index 0000000000..fd7f627e7f --- /dev/null +++ b/assets/js/94564.9666d094.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[94564],{94564:(t,i,e)=>{e.d(i,{diagram:()=>d});var a=e(86079),n=e(26312),r=(e(74353),e(16750),e(42838),function(){var t=function(t,i,e,a){for(e=e||{},a=t.length;a--;e[t[a]]=i);return e},i=[1,3],e=[1,4],a=[1,5],n=[1,6],r=[1,7],s=[1,5,13,15,17,19,20,25,27,28,29,30,31,32,33,34,37,38,40,41,42,43,44,45,46,47,48,49,50],l=[1,5,6,13,15,17,19,20,25,27,28,29,30,31,32,33,34,37,38,40,41,42,43,44,45,46,47,48,49,50],o=[32,33,34],h=[2,7],c=[1,13],d=[1,17],u=[1,18],x=[1,19],g=[1,20],f=[1,21],y=[1,22],p=[1,23],q=[1,24],T=[1,25],m=[1,26],A=[1,27],_=[1,30],b=[1,31],S=[1,32],k=[1,33],F=[1,34],P=[1,35],v=[1,36],L=[1,37],C=[1,38],z=[1,39],B=[1,40],E=[1,41],D=[1,42],I=[1,57],w=[1,58],R=[5,22,26,32,33,34,40,41,42,43,44,45,46,47,48,49,50,51],W={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,SPACE:5,QUADRANT:6,document:7,line:8,statement:9,axisDetails:10,quadrantDetails:11,points:12,title:13,title_value:14,acc_title:15,acc_title_value:16,acc_descr:17,acc_descr_value:18,acc_descr_multiline_value:19,section:20,text:21,point_start:22,point_x:23,point_y:24,"X-AXIS":25,"AXIS-TEXT-DELIMITER":26,"Y-AXIS":27,QUADRANT_1:28,QUADRANT_2:29,QUADRANT_3:30,QUADRANT_4:31,NEWLINE:32,SEMI:33,EOF:34,alphaNumToken:35,textNoTagsToken:36,STR:37,MD_STR:38,alphaNum:39,PUNCTUATION:40,AMP:41,NUM:42,ALPHA:43,COMMA:44,PLUS:45,EQUALS:46,MULT:47,DOT:48,BRKT:49,UNDERSCORE:50,MINUS:51,$accept:0,$end:1},terminals_:{2:"error",5:"SPACE",6:"QUADRANT",13:"title",14:"title_value",15:"acc_title",16:"acc_title_value",17:"acc_descr",18:"acc_descr_value",19:"acc_descr_multiline_value",20:"section",22:"point_start",23:"point_x",24:"point_y",25:"X-AXIS",26:"AXIS-TEXT-DELIMITER",27:"Y-AXIS",28:"QUADRANT_1",29:"QUADRANT_2",30:"QUADRANT_3",31:"QUADRANT_4",32:"NEWLINE",33:"SEMI",34:"EOF",37:"STR",38:"MD_STR",40:"PUNCTUATION",41:"AMP",42:"NUM",43:"ALPHA",44:"COMMA",45:"PLUS",46:"EQUALS",47:"MULT",48:"DOT",49:"BRKT",50:"UNDERSCORE",51:"MINUS"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[9,0],[9,2],[9,1],[9,1],[9,1],[9,2],[9,2],[9,2],[9,1],[9,1],[12,4],[10,4],[10,3],[10,2],[10,4],[10,3],[10,2],[11,2],[11,2],[11,2],[11,2],[4,1],[4,1],[4,1],[21,1],[21,2],[21,1],[21,1],[39,1],[39,2],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[36,1],[36,1],[36,1]],performAction:function(t,i,e,a,n,r,s){var l=r.length-1;switch(n){case 12:this.$=r[l].trim(),a.setDiagramTitle(this.$);break;case 13:this.$=r[l].trim(),a.setAccTitle(this.$);break;case 14:case 15:this.$=r[l].trim(),a.setAccDescription(this.$);break;case 16:a.addSection(r[l].substr(8)),this.$=r[l].substr(8);break;case 17:a.addPoint(r[l-3],r[l-1],r[l]);break;case 18:a.setXAxisLeftText(r[l-2]),a.setXAxisRightText(r[l]);break;case 19:r[l-1].text+=" \u27f6 ",a.setXAxisLeftText(r[l-1]);break;case 20:a.setXAxisLeftText(r[l]);break;case 21:a.setYAxisBottomText(r[l-2]),a.setYAxisTopText(r[l]);break;case 22:r[l-1].text+=" \u27f6 ",a.setYAxisBottomText(r[l-1]);break;case 23:a.setYAxisBottomText(r[l]);break;case 24:a.setQuadrant1Text(r[l]);break;case 25:a.setQuadrant2Text(r[l]);break;case 26:a.setQuadrant3Text(r[l]);break;case 27:a.setQuadrant4Text(r[l]);break;case 31:case 33:this.$={text:r[l],type:"text"};break;case 32:this.$={text:r[l-1].text+""+r[l],type:r[l-1].type};break;case 34:this.$={text:r[l],type:"markdown"};break;case 35:this.$=r[l];break;case 36:this.$=r[l-1]+""+r[l]}},table:[{3:1,4:2,5:i,6:e,32:a,33:n,34:r},{1:[3]},{3:8,4:2,5:i,6:e,32:a,33:n,34:r},{3:9,4:2,5:i,6:e,32:a,33:n,34:r},t(s,[2,4],{7:10}),t(l,[2,28]),t(l,[2,29]),t(l,[2,30]),{1:[2,1]},{1:[2,2]},t(o,h,{8:11,9:12,10:14,11:15,12:16,21:28,35:29,1:[2,3],5:c,13:d,15:u,17:x,19:g,20:f,25:y,27:p,28:q,29:T,30:m,31:A,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D}),t(s,[2,5]),{4:43,32:a,33:n,34:r},t(o,h,{10:14,11:15,12:16,21:28,35:29,9:44,5:c,13:d,15:u,17:x,19:g,20:f,25:y,27:p,28:q,29:T,30:m,31:A,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D}),t(o,[2,9]),t(o,[2,10]),t(o,[2,11]),{14:[1,45]},{16:[1,46]},{18:[1,47]},t(o,[2,15]),t(o,[2,16]),{21:48,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D},{21:49,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D},{21:50,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D},{21:51,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D},{21:52,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D},{21:53,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D},{5:I,22:[1,54],35:56,36:55,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w},t(R,[2,31]),t(R,[2,33]),t(R,[2,34]),t(R,[2,37]),t(R,[2,38]),t(R,[2,39]),t(R,[2,40]),t(R,[2,41]),t(R,[2,42]),t(R,[2,43]),t(R,[2,44]),t(R,[2,45]),t(R,[2,46]),t(R,[2,47]),t(s,[2,6]),t(o,[2,8]),t(o,[2,12]),t(o,[2,13]),t(o,[2,14]),t(o,[2,20],{36:55,35:56,5:I,26:[1,59],40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,23],{36:55,35:56,5:I,26:[1,60],40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,24],{36:55,35:56,5:I,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,25],{36:55,35:56,5:I,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,26],{36:55,35:56,5:I,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,27],{36:55,35:56,5:I,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),{23:[1,61]},t(R,[2,32]),t(R,[2,48]),t(R,[2,49]),t(R,[2,50]),t(o,[2,19],{35:29,21:62,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D}),t(o,[2,22],{35:29,21:63,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D}),{24:[1,64]},t(o,[2,18],{36:55,35:56,5:I,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,21],{36:55,35:56,5:I,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,17])],defaultActions:{8:[2,1],9:[2,2]},parseError:function(t,i){if(!i.recoverable){var e=new Error(t);throw e.hash=i,e}this.trace(t)},parse:function(t){var i=this,e=[0],a=[],n=[null],r=[],s=this.table,l="",o=0,h=0,c=r.slice.call(arguments,1),d=Object.create(this.lexer),u={yy:{}};for(var x in this.yy)Object.prototype.hasOwnProperty.call(this.yy,x)&&(u.yy[x]=this.yy[x]);d.setInput(t,u.yy),u.yy.lexer=d,u.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var g=d.yylloc;r.push(g);var f=d.options&&d.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var y,p,q,T,m,A,_,b,S,k={};;){if(p=e[e.length-1],this.defaultActions[p]?q=this.defaultActions[p]:(null==y&&(S=void 0,"number"!=typeof(S=a.pop()||d.lex()||1)&&(S instanceof Array&&(S=(a=S).pop()),S=i.symbols_[S]||S),y=S),q=s[p]&&s[p][y]),void 0===q||!q.length||!q[0]){var F="";for(m in b=[],s[p])this.terminals_[m]&&m>2&&b.push("'"+this.terminals_[m]+"'");F=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+b.join(", ")+", got '"+(this.terminals_[y]||y)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==y?"end of input":"'"+(this.terminals_[y]||y)+"'"),this.parseError(F,{text:d.match,token:this.terminals_[y]||y,line:d.yylineno,loc:g,expected:b})}if(q[0]instanceof Array&&q.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+y);switch(q[0]){case 1:e.push(y),n.push(d.yytext),r.push(d.yylloc),e.push(q[1]),y=null,h=d.yyleng,l=d.yytext,o=d.yylineno,g=d.yylloc;break;case 2:if(A=this.productions_[q[1]][1],k.$=n[n.length-A],k._$={first_line:r[r.length-(A||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(A||1)].first_column,last_column:r[r.length-1].last_column},f&&(k._$.range=[r[r.length-(A||1)].range[0],r[r.length-1].range[1]]),void 0!==(T=this.performAction.apply(k,[l,h,o,u.yy,q[1],n,r].concat(c))))return T;A&&(e=e.slice(0,-1*A*2),n=n.slice(0,-1*A),r=r.slice(0,-1*A)),e.push(this.productions_[q[1]][0]),n.push(k.$),r.push(k._$),_=s[e[e.length-2]][e[e.length-1]],e.push(_);break;case 3:return!0}}return!0}},N={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)},setInput:function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var i=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var a=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===a.length?this.yylloc.first_column:0)+a[a.length-e.length].length-e[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"},test_match:function(t,i){var e,a,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,e,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;r<n.length;r++)if((e=this._input.match(this.rules[n[r]]))&&(!i||e[0].length>i[0].length)){if(i=e,a=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,n[r])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,n[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,e,a){switch(e){case 0:case 1:case 3:break;case 2:return 32;case 4:return this.begin("title"),13;case 5:return this.popState(),"title_value";case 6:return this.begin("acc_title"),15;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),17;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 22:case 24:case 28:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 25;case 14:return 27;case 15:return 26;case 16:return 28;case 17:return 29;case 18:return 30;case 19:return 31;case 20:this.begin("md_string");break;case 21:return"MD_STR";case 23:this.begin("string");break;case 25:return"STR";case 26:return this.begin("point_start"),22;case 27:return this.begin("point_x"),23;case 29:this.popState(),this.begin("point_y");break;case 30:return this.popState(),24;case 31:return 6;case 32:return 43;case 33:return"COLON";case 34:return 45;case 35:return 44;case 36:case 37:return 46;case 38:return 47;case 39:return 49;case 40:return 50;case 41:return 48;case 42:return 41;case 43:return 51;case 44:return 42;case 45:return 5;case 46:return 33;case 47:return 40;case 48:return 34}},rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?: *x-axis *)/i,/^(?: *y-axis *)/i,/^(?: *--+> *)/i,/^(?: *quadrant-1 *)/i,/^(?: *quadrant-2 *)/i,/^(?: *quadrant-3 *)/i,/^(?: *quadrant-4 *)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\s*:\s*\[\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?:\s*\] *)/i,/^(?:\s*,\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?: *quadrantChart *)/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s)/i,/^(?:;)/i,/^(?:[!"#$%&'*+,-.`?\\_/])/i,/^(?:$)/i],conditions:{point_y:{rules:[30],inclusive:!1},point_x:{rules:[29],inclusive:!1},point_start:{rules:[27,28],inclusive:!1},acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},title:{rules:[5],inclusive:!1},md_string:{rules:[21,22],inclusive:!1},string:{rules:[24,25],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,6,8,10,13,14,15,16,17,18,19,20,23,26,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],inclusive:!0}}};function U(){this.yy={}}return W.lexer=N,U.prototype=W,W.Parser=U,new U}());r.parser=r;const s=r,l=(0,a.E)();const o=(0,a.c)();function h(t){return(0,a.d)(t.trim(),o)}const c=new class{constructor(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData()}getDefaultData(){return{titleText:"",quadrant1Text:"",quadrant2Text:"",quadrant3Text:"",quadrant4Text:"",xAxisLeftText:"",xAxisRightText:"",yAxisBottomText:"",yAxisTopText:"",points:[]}}getDefaultConfig(){var t,i,e,n,r,s,l,o,h,c,d,u,x,g,f,y,p,q;return{showXAxis:!0,showYAxis:!0,showTitle:!0,chartHeight:(null==(t=a.B.quadrantChart)?void 0:t.chartWidth)||500,chartWidth:(null==(i=a.B.quadrantChart)?void 0:i.chartHeight)||500,titlePadding:(null==(e=a.B.quadrantChart)?void 0:e.titlePadding)||10,titleFontSize:(null==(n=a.B.quadrantChart)?void 0:n.titleFontSize)||20,quadrantPadding:(null==(r=a.B.quadrantChart)?void 0:r.quadrantPadding)||5,xAxisLabelPadding:(null==(s=a.B.quadrantChart)?void 0:s.xAxisLabelPadding)||5,yAxisLabelPadding:(null==(l=a.B.quadrantChart)?void 0:l.yAxisLabelPadding)||5,xAxisLabelFontSize:(null==(o=a.B.quadrantChart)?void 0:o.xAxisLabelFontSize)||16,yAxisLabelFontSize:(null==(h=a.B.quadrantChart)?void 0:h.yAxisLabelFontSize)||16,quadrantLabelFontSize:(null==(c=a.B.quadrantChart)?void 0:c.quadrantLabelFontSize)||16,quadrantTextTopPadding:(null==(d=a.B.quadrantChart)?void 0:d.quadrantTextTopPadding)||5,pointTextPadding:(null==(u=a.B.quadrantChart)?void 0:u.pointTextPadding)||5,pointLabelFontSize:(null==(x=a.B.quadrantChart)?void 0:x.pointLabelFontSize)||12,pointRadius:(null==(g=a.B.quadrantChart)?void 0:g.pointRadius)||5,xAxisPosition:(null==(f=a.B.quadrantChart)?void 0:f.xAxisPosition)||"top",yAxisPosition:(null==(y=a.B.quadrantChart)?void 0:y.yAxisPosition)||"left",quadrantInternalBorderStrokeWidth:(null==(p=a.B.quadrantChart)?void 0:p.quadrantInternalBorderStrokeWidth)||1,quadrantExternalBorderStrokeWidth:(null==(q=a.B.quadrantChart)?void 0:q.quadrantExternalBorderStrokeWidth)||2}}getDefaultThemeConfig(){return{quadrant1Fill:l.quadrant1Fill,quadrant2Fill:l.quadrant2Fill,quadrant3Fill:l.quadrant3Fill,quadrant4Fill:l.quadrant4Fill,quadrant1TextFill:l.quadrant1TextFill,quadrant2TextFill:l.quadrant2TextFill,quadrant3TextFill:l.quadrant3TextFill,quadrant4TextFill:l.quadrant4TextFill,quadrantPointFill:l.quadrantPointFill,quadrantPointTextFill:l.quadrantPointTextFill,quadrantXAxisTextFill:l.quadrantXAxisTextFill,quadrantYAxisTextFill:l.quadrantYAxisTextFill,quadrantTitleFill:l.quadrantTitleFill,quadrantInternalBorderStrokeFill:l.quadrantInternalBorderStrokeFill,quadrantExternalBorderStrokeFill:l.quadrantExternalBorderStrokeFill}}clear(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData(),a.l.info("clear called")}setData(t){this.data={...this.data,...t}}addPoints(t){this.data.points=[...t,...this.data.points]}setConfig(t){a.l.trace("setConfig called with: ",t),this.config={...this.config,...t}}setThemeConfig(t){a.l.trace("setThemeConfig called with: ",t),this.themeConfig={...this.themeConfig,...t}}calculateSpace(t,i,e,a){const n=2*this.config.xAxisLabelPadding+this.config.xAxisLabelFontSize,r={top:"top"===t&&i?n:0,bottom:"bottom"===t&&i?n:0},s=2*this.config.yAxisLabelPadding+this.config.yAxisLabelFontSize,l={left:"left"===this.config.yAxisPosition&&e?s:0,right:"right"===this.config.yAxisPosition&&e?s:0},o=this.config.titleFontSize+2*this.config.titlePadding,h={top:a?o:0},c=this.config.quadrantPadding+l.left,d=this.config.quadrantPadding+r.top+h.top,u=this.config.chartWidth-2*this.config.quadrantPadding-l.left-l.right,x=this.config.chartHeight-2*this.config.quadrantPadding-r.top-r.bottom-h.top;return{xAxisSpace:r,yAxisSpace:l,titleSpace:h,quadrantSpace:{quadrantLeft:c,quadrantTop:d,quadrantWidth:u,quadrantHalfWidth:u/2,quadrantHeight:x,quadrantHalfHeight:x/2}}}getAxisLabels(t,i,e,a){const{quadrantSpace:n,titleSpace:r}=a,{quadrantHalfHeight:s,quadrantHeight:l,quadrantLeft:o,quadrantHalfWidth:h,quadrantTop:c,quadrantWidth:d}=n,u=Boolean(this.data.xAxisRightText),x=Boolean(this.data.yAxisTopText),g=[];return this.data.xAxisLeftText&&i&&g.push({text:this.data.xAxisLeftText,fill:this.themeConfig.quadrantXAxisTextFill,x:o+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+r.top:this.config.xAxisLabelPadding+c+l+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.xAxisRightText&&i&&g.push({text:this.data.xAxisRightText,fill:this.themeConfig.quadrantXAxisTextFill,x:o+h+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+r.top:this.config.xAxisLabelPadding+c+l+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.yAxisBottomText&&e&&g.push({text:this.data.yAxisBottomText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+o+d+this.config.quadrantPadding,y:c+l-(x?s/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:x?"center":"left",horizontalPos:"top",rotation:-90}),this.data.yAxisTopText&&e&&g.push({text:this.data.yAxisTopText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+o+d+this.config.quadrantPadding,y:c+s-(x?s/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:x?"center":"left",horizontalPos:"top",rotation:-90}),g}getQuadrants(t){const{quadrantSpace:i}=t,{quadrantHalfHeight:e,quadrantLeft:a,quadrantHalfWidth:n,quadrantTop:r}=i,s=[{text:{text:this.data.quadrant1Text,fill:this.themeConfig.quadrant1TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:r,width:n,height:e,fill:this.themeConfig.quadrant1Fill},{text:{text:this.data.quadrant2Text,fill:this.themeConfig.quadrant2TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:r,width:n,height:e,fill:this.themeConfig.quadrant2Fill},{text:{text:this.data.quadrant3Text,fill:this.themeConfig.quadrant3TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:r+e,width:n,height:e,fill:this.themeConfig.quadrant3Fill},{text:{text:this.data.quadrant4Text,fill:this.themeConfig.quadrant4TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:r+e,width:n,height:e,fill:this.themeConfig.quadrant4Fill}];for(const l of s)l.text.x=l.x+l.width/2,0===this.data.points.length?(l.text.y=l.y+l.height/2,l.text.horizontalPos="middle"):(l.text.y=l.y+this.config.quadrantTextTopPadding,l.text.horizontalPos="top");return s}getQuadrantPoints(t){const{quadrantSpace:i}=t,{quadrantHeight:e,quadrantLeft:a,quadrantTop:r,quadrantWidth:s}=i,l=(0,n.m4Y)().domain([0,1]).range([a,s+a]),o=(0,n.m4Y)().domain([0,1]).range([e+r,r]);return this.data.points.map((t=>({x:l(t.x),y:o(t.y),fill:this.themeConfig.quadrantPointFill,radius:this.config.pointRadius,text:{text:t.text,fill:this.themeConfig.quadrantPointTextFill,x:l(t.x),y:o(t.y)+this.config.pointTextPadding,verticalPos:"center",horizontalPos:"top",fontSize:this.config.pointLabelFontSize,rotation:0}})))}getBorders(t){const i=this.config.quadrantExternalBorderStrokeWidth/2,{quadrantSpace:e}=t,{quadrantHalfHeight:a,quadrantHeight:n,quadrantLeft:r,quadrantHalfWidth:s,quadrantTop:l,quadrantWidth:o}=e;return[{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r-i,y1:l,x2:r+o+i,y2:l},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r+o,y1:l+i,x2:r+o,y2:l+n-i},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r-i,y1:l+n,x2:r+o+i,y2:l+n},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r,y1:l+i,x2:r,y2:l+n-i},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:r+s,y1:l+i,x2:r+s,y2:l+n-i},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:r+i,y1:l+a,x2:r+o-i,y2:l+a}]}getTitle(t){if(t)return{text:this.data.titleText,fill:this.themeConfig.quadrantTitleFill,fontSize:this.config.titleFontSize,horizontalPos:"top",verticalPos:"center",rotation:0,y:this.config.titlePadding,x:this.config.chartWidth/2}}build(){const t=this.config.showXAxis&&!(!this.data.xAxisLeftText&&!this.data.xAxisRightText),i=this.config.showYAxis&&!(!this.data.yAxisTopText&&!this.data.yAxisBottomText),e=this.config.showTitle&&!!this.data.titleText,a=this.data.points.length>0?"bottom":this.config.xAxisPosition,n=this.calculateSpace(a,t,i,e);return{points:this.getQuadrantPoints(n),quadrants:this.getQuadrants(n),axisLabels:this.getAxisLabels(a,t,i,n),borderLines:this.getBorders(n),title:this.getTitle(e)}}};const d={parser:s,db:{setWidth:function(t){c.setConfig({chartWidth:t})},setHeight:function(t){c.setConfig({chartHeight:t})},setQuadrant1Text:function(t){c.setData({quadrant1Text:h(t.text)})},setQuadrant2Text:function(t){c.setData({quadrant2Text:h(t.text)})},setQuadrant3Text:function(t){c.setData({quadrant3Text:h(t.text)})},setQuadrant4Text:function(t){c.setData({quadrant4Text:h(t.text)})},setXAxisLeftText:function(t){c.setData({xAxisLeftText:h(t.text)})},setXAxisRightText:function(t){c.setData({xAxisRightText:h(t.text)})},setYAxisTopText:function(t){c.setData({yAxisTopText:h(t.text)})},setYAxisBottomText:function(t){c.setData({yAxisBottomText:h(t.text)})},addPoint:function(t,i,e){c.addPoints([{x:i,y:e,text:h(t.text)}])},getQuadrantData:function(){const t=(0,a.c)(),{themeVariables:i,quadrantChart:e}=t;return e&&c.setConfig(e),c.setThemeConfig({quadrant1Fill:i.quadrant1Fill,quadrant2Fill:i.quadrant2Fill,quadrant3Fill:i.quadrant3Fill,quadrant4Fill:i.quadrant4Fill,quadrant1TextFill:i.quadrant1TextFill,quadrant2TextFill:i.quadrant2TextFill,quadrant3TextFill:i.quadrant3TextFill,quadrant4TextFill:i.quadrant4TextFill,quadrantPointFill:i.quadrantPointFill,quadrantPointTextFill:i.quadrantPointTextFill,quadrantXAxisTextFill:i.quadrantXAxisTextFill,quadrantYAxisTextFill:i.quadrantYAxisTextFill,quadrantExternalBorderStrokeFill:i.quadrantExternalBorderStrokeFill,quadrantInternalBorderStrokeFill:i.quadrantInternalBorderStrokeFill,quadrantTitleFill:i.quadrantTitleFill}),c.setData({titleText:(0,a.t)()}),c.build()},clear:function(){c.clear(),(0,a.v)()},setAccTitle:a.s,getAccTitle:a.g,setDiagramTitle:a.q,getDiagramTitle:a.t,getAccDescription:a.a,setAccDescription:a.b},renderer:{draw:(t,i,e,r)=>{var s,l,o;function h(t){return"top"===t?"hanging":"middle"}function c(t){return"left"===t?"start":"middle"}function d(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}const u=(0,a.c)();a.l.debug("Rendering quadrant chart\n"+t);const x=u.securityLevel;let g;"sandbox"===x&&(g=(0,n.Ltv)("#i"+i));const f=("sandbox"===x?(0,n.Ltv)(g.nodes()[0].contentDocument.body):(0,n.Ltv)("body")).select(`[id="${i}"]`),y=f.append("g").attr("class","main"),p=(null==(s=u.quadrantChart)?void 0:s.chartWidth)||500,q=(null==(l=u.quadrantChart)?void 0:l.chartHeight)||500;(0,a.i)(f,q,p,(null==(o=u.quadrantChart)?void 0:o.useMaxWidth)||!0),f.attr("viewBox","0 0 "+p+" "+q),r.db.setHeight(q),r.db.setWidth(p);const T=r.db.getQuadrantData(),m=y.append("g").attr("class","quadrants"),A=y.append("g").attr("class","border"),_=y.append("g").attr("class","data-points"),b=y.append("g").attr("class","labels"),S=y.append("g").attr("class","title");T.title&&S.append("text").attr("x",0).attr("y",0).attr("fill",T.title.fill).attr("font-size",T.title.fontSize).attr("dominant-baseline",h(T.title.horizontalPos)).attr("text-anchor",c(T.title.verticalPos)).attr("transform",d(T.title)).text(T.title.text),T.borderLines&&A.selectAll("line").data(T.borderLines).enter().append("line").attr("x1",(t=>t.x1)).attr("y1",(t=>t.y1)).attr("x2",(t=>t.x2)).attr("y2",(t=>t.y2)).style("stroke",(t=>t.strokeFill)).style("stroke-width",(t=>t.strokeWidth));const k=m.selectAll("g.quadrant").data(T.quadrants).enter().append("g").attr("class","quadrant");k.append("rect").attr("x",(t=>t.x)).attr("y",(t=>t.y)).attr("width",(t=>t.width)).attr("height",(t=>t.height)).attr("fill",(t=>t.fill)),k.append("text").attr("x",0).attr("y",0).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>h(t.text.horizontalPos))).attr("text-anchor",(t=>c(t.text.verticalPos))).attr("transform",(t=>d(t.text))).text((t=>t.text.text));b.selectAll("g.label").data(T.axisLabels).enter().append("g").attr("class","label").append("text").attr("x",0).attr("y",0).text((t=>t.text)).attr("fill",(t=>t.fill)).attr("font-size",(t=>t.fontSize)).attr("dominant-baseline",(t=>h(t.horizontalPos))).attr("text-anchor",(t=>c(t.verticalPos))).attr("transform",(t=>d(t)));const F=_.selectAll("g.data-point").data(T.points).enter().append("g").attr("class","data-point");F.append("circle").attr("cx",(t=>t.x)).attr("cy",(t=>t.y)).attr("r",(t=>t.radius)).attr("fill",(t=>t.fill)),F.append("text").attr("x",0).attr("y",0).text((t=>t.text.text)).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>h(t.text.horizontalPos))).attr("text-anchor",(t=>c(t.text.verticalPos))).attr("transform",(t=>d(t.text)))}},styles:()=>""}}}]); \ No newline at end of file diff --git a/assets/js/946bf800.dcf10896.js b/assets/js/946bf800.dcf10896.js new file mode 100644 index 0000000000..c81254d282 --- /dev/null +++ b/assets/js/946bf800.dcf10896.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[98842],{25851:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Components","slug":"/category/components-2","permalink":"/docs/category/components-2","sidebar":"docs","navigation":{"previous":{"title":"Operating SCS","permalink":"/docs/category/operating-scs"},"next":{"title":"Status Page","permalink":"/docs/category/status-page"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/9490f32b.4fd635b9.js b/assets/js/9490f32b.4fd635b9.js new file mode 100644 index 0000000000..edda6a1aa4 --- /dev/null +++ b/assets/js/9490f32b.4fd635b9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[83874],{4943:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>u,frontMatter:()=>c,metadata:()=>a,toc:()=>d});const a=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/glance","title":"Glance","description":"* Glance admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/glance.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/glance","permalink":"/docs/iaas/guides/configuration-guide/openstack/glance","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/glance.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Glance"},"sidebar":"docs","previous":{"title":"Designate","permalink":"/docs/iaas/guides/configuration-guide/openstack/designate"},"next":{"title":"Heat","permalink":"/docs/iaas/guides/configuration-guide/openstack/heat"}}');var i=t(74848),s=t(28453);const c={sidebar_label:"Glance"},o="Glance",r={},d=[];function l(e){const n={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"glance",children:"Glance"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/glance/latest/admin/index.html",children:"Glance admin guide"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/glance/latest/configuration/index.html",children:"Glance configuration reference"})}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var a=t(96540);const i={},s=a.createContext(i);function c(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/94b13e0d.62b81f20.js b/assets/js/94b13e0d.62b81f20.js new file mode 100644 index 0000000000..a70baeb00f --- /dev/null +++ b/assets/js/94b13e0d.62b81f20.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[96707],{76148:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","title":"Setting up OpenStack health monitor on Debian","description":"Kurt Garloff, 2024-02-20","source":"@site/docs/02-iaas/guides/operations-guide/openstack/tools/openstack-health-monitor.md","sourceDirName":"02-iaas/guides/operations-guide/openstack/tools","slug":"/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/openstack-health-monitor.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"OpenStack Health Monitor"},"sidebar":"docs","previous":{"title":"Simple Stress","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress"},"next":{"title":"Cinder","permalink":"/docs/iaas/guides/operations-guide/openstack/cinder"}}');var s=t(74848),a=t(28453);const i={sidebar_label:"OpenStack Health Monitor"},r="Setting up OpenStack health monitor on Debian",d={},l=[{value:"Intro",id:"intro",level:2},{value:"Setting up the driver VM",id:"setting-up-the-driver-vm",level:2},{value:"Internal vs external monitoring",id:"internal-vs-external-monitoring",level:3},{value:"Unprivileged operation",id:"unprivileged-operation",level:3},{value:"Driver VM via openstack CLI",id:"driver-vm-via-openstack-cli",level:3},{value:"Configuring openstack CLI on the driver VM",id:"configuring-openstack-cli-on-the-driver-vm",level:3},{value:"Custom CA",id:"custom-ca",level:3},{value:"Your first <code>api_monitor.sh</code> iteration",id:"your-first-api_monitorsh-iteration",level:2},{value:"Resource impact and charging",id:"resource-impact-and-charging",level:3},{value:"Automating startup and cleanup",id:"automating-startup-and-cleanup",level:2},{value:"Changing parameters and restarting",id:"changing-parameters-and-restarting",level:3},{value:"Multiple instances",id:"multiple-instances",level:3},{value:"Alarming and Logs",id:"alarming-and-logs",level:2},{value:"eMail",id:"email",level:3},{value:"Log files",id:"log-files",level:3},{value:"Data collection and dashboard",id:"data-collection-and-dashboard",level:2},{value:"Telegraf",id:"telegraf",level:3},{value:"InfluxDB",id:"influxdb",level:3},{value:"Add <code>-S CLOUDNAME</code> to your <code>run_CLOUDNAME.sh</code> script",id:"add--s-cloudname-to-your-run_cloudnamesh-script",level:3},{value:"Caddy (Reverse Proxy)",id:"caddy-reverse-proxy",level:3},{value:"Install Caddy",id:"install-caddy",level:4},{value:"Allow HTTP traffic for oshm-driver",id:"allow-http-traffic-for-oshm-driver",level:4},{value:"Configure Caddy",id:"configure-caddy",level:4},{value:"Grafana",id:"grafana",level:3},{value:"Install Grafana",id:"install-grafana",level:4},{value:"Basic config",id:"basic-config",level:4},{value:"Enable influx database in grafana",id:"enable-influx-database-in-grafana",level:4},{value:"Importing the dashboard",id:"importing-the-dashboard",level:4},{value:"No data displayed?",id:"no-data-displayed",level:4},{value:"Dashboard features",id:"dashboard-features",level:4},{value:"GitHub OIDC Integration",id:"github-oidc-integration",level:4},{value:"Maintenance",id:"maintenance",level:2},{value:"Unattended upgrades",id:"unattended-upgrades",level:3},{value:"sshd setup",id:"sshd-setup",level:3},{value:"Updating openstack-health-monitor",id:"updating-openstack-health-monitor",level:3},{value:"Backup",id:"backup",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Debugging issues",id:"debugging-issues",level:3},{value:"Analyzing failures",id:"analyzing-failures",level:3},{value:"Cleaning things up",id:"cleaning-things-up",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"setting-up-openstack-health-monitor-on-debian",children:"Setting up OpenStack health monitor on Debian"})}),"\n",(0,s.jsx)(n.p,{children:"Kurt Garloff, 2024-02-20"}),"\n",(0,s.jsx)(n.h2,{id:"intro",children:"Intro"}),"\n",(0,s.jsxs)(n.p,{children:["The development of ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/",children:"openstack-health-monitor"})," was done on ",(0,s.jsx)(n.a,{href:"https://kfg.images.obs-website.eu-de.otc.t-systems.com/",children:"openSUSE 15.x images"}),", just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution."]}),"\n",(0,s.jsx)(n.p,{children:"Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here."}),"\n",(0,s.jsxs)(n.p,{children:["Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor",children:"successor project"})," for the increasingly hard to maintain shell code, this may not be worth the trouble."]}),"\n",(0,s.jsxs)(n.p,{children:["openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested.\nThe scenario is described in a bit more detail in the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"repository's README.md"})," file."]}),"\n",(0,s.jsxs)(n.p,{children:["The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/docs/category/monitoring",children:"monitoring section"})," of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up."]}),"\n",(0,s.jsx)(n.h2,{id:"setting-up-the-driver-vm",children:"Setting up the driver VM"}),"\n",(0,s.jsxs)(n.p,{children:["So we start a ",(0,s.jsx)(n.code,{children:"Debian 12"})," image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard;\nthe instructions use flavor names and image names from the SCS standards.\nFor many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack)."]}),"\n",(0,s.jsx)(n.h3,{id:"internal-vs-external-monitoring",children:"Internal vs external monitoring"}),"\n",(0,s.jsx)(n.p,{children:"There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor."}),"\n",(0,s.jsx)(n.p,{children:"The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems."}),"\n",(0,s.jsx)(n.h3,{id:"unprivileged-operation",children:"Unprivileged operation"}),"\n",(0,s.jsx)(n.p,{children:"Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own."}),"\n",(0,s.jsxs)(n.p,{children:["If ",(0,s.jsx)(n.code,{children:"openstack availability zone list --compute"})," fails for you without admin rights, please fix your openstack client, e.g. by applying the ",(0,s.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/openstack-health-monitor/main/docs/openstackclient-az-list-fallback-f3207bd.diff",children:"patch"})," I mentioned in ",(0,s.jsx)(n.a,{href:"https://storyboard.openstack.org/#!/story/2010989",children:"this issue"}),". (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Health-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)"]}),"\n",(0,s.jsx)(n.h3,{id:"driver-vm-via-openstack-cli",children:"Driver VM via openstack CLI"}),"\n",(0,s.jsxs)(n.p,{children:["The author prefers to setup the VM via ",(0,s.jsx)(n.code,{children:"openstack"})," CLI tooling. He has working entries for all clouds he uses in his ",(0,s.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})," and ",(0,s.jsx)(n.code,{children:"secure.yaml"})," and has exported the ",(0,s.jsx)(n.code,{children:"OS_CLOUD"})," environment variable to point to the cloud he is working on to set up the driver VM. The author uses the ",(0,s.jsx)(n.code,{children:"bash"})," shell. All of this of course could be scripted."]}),"\n",(0,s.jsx)(n.p,{children:"So here we go"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Create the network setup for a VM in a network ",(0,s.jsx)(n.code,{children:"oshm-network"})," with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network."]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"PUBLIC=$(openstack network list --external -f value -c Name)\nopenstack router create oshm-router\nopenstack router set --external-gateway $PUBLIC oshm-driver-router\nopenstack network create oshm-network\nopenstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet\nopenstack router add subnet oshm-router oshm-subnet\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsx)(n.li,{children:"Create a security group that allows ssh and ping access"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack security group create sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsx)(n.li,{children:"Being at it, we also create the security group for grafana"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack security group create grafana\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"To connect to the VM via ssh later, we create an SSH keypair"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key\nchmod og-r ~/.ssh/oshm-key.pem \n"})}),"\n",(0,s.jsxs)(n.p,{children:["Rather than creating a new key (and storing and protecting the private key), we could have passed ",(0,s.jsx)(n.code,{children:"--public-key"})," and used an existing keypair."]}),"\n",(0,s.jsxs)(n.ol,{start:"5",children:["\n",(0,s.jsx)(n.li,{children:"Look up Debian 12 image UUID."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"IMGUUID=$(openstack image list --name \"Debian 12\" -f value -c ID | tr -d '\\r')\necho $IMGUUID\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Sidenote: The ",(0,s.jsx)(n.code,{children:"tr"})," command is there to handle broken tooling that embeds a trailing ",(0,s.jsx)(n.code,{children:"\\r"})," in the output."]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsx)(n.li,{children:"Boot the driver VM"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing ",(0,s.jsx)(n.code,{children:"--block-device"}),". See ",(0,s.jsx)(n.a,{href:"https://scs.community/2023/08/21/diskless-flavors/",children:"diskless flavor blog article"}),". For flavors with local root disks, you could have used the ",(0,s.jsx)(n.code,{children:"--image $IMGUUID"})," parameter instead."]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:["Wait for it to boot (optional)\nYou can look at the boot log with ",(0,s.jsx)(n.code,{children:"openstack console log show oshm-driver"})," or connect to it via VNC at the URL given by ",(0,s.jsx)(n.code,{children:"openstack console url show oshm-driver"}),". You can of course also query openstack on the status ",(0,s.jsx)(n.code,{children:"openstack server list"})," or ",(0,s.jsx)(n.code,{children:"openstack server show oshm-driver"}),". You can also just create a simple loop:"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'declare -i ctr=0 RC=0\nwhile [ $ctr -le 120 ]; do\n STATUS="$(openstack server list --name oshm-driver -f value -c Status)"\n if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi \n if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi\n if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi\n sleep 2\n let ctr+=1\ndone\n# return $RC\nif [ $RC != 0 ]; then false; fi\n'})}),"\n",(0,s.jsxs)(n.ol,{start:"8",children:["\n",(0,s.jsx)(n.li,{children:"Attach a floating IP so it's reachable from the outside."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks | sed "s@^[^:]*:[^\']*\'\\([0-9\\.]*\\)\'.*\\$@\\1@")\nFIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)\necho $FIXEDIP $FIXEDPORT\nopenstack floating ip create --port $FIXEDPORT $PUBLIC\nFLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")\necho "Floating IP: $FLOATINGIP"\n'})}),"\n",(0,s.jsx)(n.p,{children:"Remember this floating IP address."}),"\n",(0,s.jsxs)(n.ol,{start:"9",children:["\n",(0,s.jsx)(n.li,{children:"Connect to it via ssh"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP\n"})}),"\n",(0,s.jsx)(n.p,{children:"On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"All the following commands are performed on the newly started driver VM."})}),"\n",(0,s.jsx)(n.h3,{id:"configuring-openstack-cli-on-the-driver-vm",children:"Configuring openstack CLI on the driver VM"}),"\n",(0,s.jsx)(n.p,{children:"We need to install the openstack client utilities."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"sudo apt-get update\nsudo apt-get install python3-openstackclient\nsudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Configure your cloud access in ",(0,s.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n interface: public\n identity-api-version: 3\n #region_name: REGION\n auth:\n auth_url: KEYSTONE_ENDPOINT\n project_id: PROJECT_UUID\n #alternatively project_name and project_domain_name\n user_domain_name: default\n # change to your real domain\n"})}),"\n",(0,s.jsxs)(n.p,{children:["and ",(0,s.jsx)(n.code,{children:"secure.yaml"})," (in the same directory)"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n auth:\n username: USERNAME\n password: PASSWORD\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"CLOUDNAME"})," can be freely chosen. This is the value passed to the openstack CLI with ",(0,s.jsx)(n.code,{children:"--os-cloud"})," or exported to your environment in ",(0,s.jsx)(n.code,{children:"OS_CLOUD"}),". The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample ",(0,s.jsx)(n.code,{children:"clouds.yaml"})," file that works (but lacks the password)."]}),"\n",(0,s.jsxs)(n.p,{children:["Protect your ",(0,s.jsx)(n.code,{children:"secure.yaml"})," from being read by others: ",(0,s.jsx)(n.code,{children:"chmod 0600 ~/.config/openstack/secure.yaml"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["If you are using application credentials instead of username, password to authenticate, you don't need to specify ",(0,s.jsx)(n.code,{children:"project_id"})," nor project's nor user's domain names in ",(0,s.jsx)(n.code,{children:"clouds.yaml"}),". Just (in ",(0,s.jsx)(n.code,{children:"secure.yaml"}),"):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'clouds:\n CLOUDNAME:\n auth_type: v3applicationcredential\n auth:\n application_credential_id: APPCRED_ID\n application_credential_secret: "APPCRED_SECRET"\n'})}),"\n",(0,s.jsx)(n.p,{children:"Configure this to be your default cloud:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"export OS_CLOUD=CLOUDNAME\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You might consider adding this to your ",(0,s.jsx)(n.code,{children:"~/.bashrc"})," for convenience. Being at it, you might want to add ",(0,s.jsx)(n.code,{children:"export CLIFF_FIT_WIDTH=1"})," there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste)."]}),"\n",(0,s.jsx)(n.p,{children:"Verify that your openstack CLI works:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack catalog list\nopenstack server list\n"})}),"\n",(0,s.jsx)(n.p,{children:"You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases."}),"\n",(0,s.jsx)(n.h3,{id:"custom-ca",children:"Custom CA"}),"\n",(0,s.jsxs)(n.p,{children:["If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in ",(0,s.jsx)(n.code,{children:"/etc/ssl/certs/ca-certificates.crt"}),". You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the ",(0,s.jsx)(n.code,{children:"debian"})," user."]}),"\n",(0,s.jsxs)(n.p,{children:["Add it to your ",(0,s.jsx)(n.code,{children:"clouds.yaml"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n cacert: /PATH/TO/CACERT.CRT\n [...]\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If you want to allow ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"export OS_CACERT=/PATH/TO/CACERT.CRT\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Consider adding this to your ",(0,s.jsx)(n.code,{children:"~/.bashrc"})," as well."]}),"\n",(0,s.jsxs)(n.h2,{id:"your-first-api_monitorsh-iteration",children:["Your first ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," iteration"]}),"\n",(0,s.jsx)(n.p,{children:"Checkout openstack-health-monitor:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install git bc jq netcat-traditional tmux zstd\ngit clone https://github.com/SovereignCloudStack/openstack-health-monitor\ncd openstack-health-monitor\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You may want to start a ",(0,s.jsx)(n.code,{children:"tmux"})," (or ",(0,s.jsx)(n.code,{children:"screen"}),") session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect."]}),"\n",(0,s.jsxs)(n.p,{children:["The script ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"})," file."]}),"\n",(0,s.jsxs)(n.p,{children:["It is good practice to use ",(0,s.jsx)(n.code,{children:"tmux"}),". This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to ",(0,s.jsx)(n.code,{children:"screen"})," over ",(0,s.jsx)(n.code,{children:"tmux"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'export IMG="Debian 12"\nexport JHIMG="Debian 12"\n./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Leave out the ",(0,s.jsx)(n.code,{children:"-LL"})," if you don't have a working loadbalancer service or replace ",(0,s.jsx)(n.code,{children:"-LL"})," with ",(0,s.jsx)(n.code,{children:"-LO"})," if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources)."]}),"\n",(0,s.jsxs)(n.p,{children:["Feel free to study the meaning of all the command line parameters by looking at the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"}),". (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)"]}),"\n",(0,s.jsxs)(n.p,{children:["This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs ",(0,s.jsx)(n.code,{children:"DOWN"}),", ",(0,s.jsx)(n.code,{children:"BUILD"}),", ",(0,s.jsx)(n.code,{children:"creating"})," are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual ",(0,s.jsx)(n.code,{children:"openstack RESOURCE list"})," and ",(0,s.jsx)(n.code,{children:"openstack RESOURCE show NAME"})," and ",(0,s.jsx)(n.code,{children:"RESOURCE"})," being something like ",(0,s.jsx)(n.code,{children:"router"}),", ",(0,s.jsx)(n.code,{children:"network"}),", ",(0,s.jsx)(n.code,{children:"subnet"}),", ",(0,s.jsx)(n.code,{children:"port"}),", ",(0,s.jsx)(n.code,{children:"volume"}),", ",(0,s.jsx)(n.code,{children:"server"}),", ",(0,s.jsx)(n.code,{children:"floating ip"}),", ",(0,s.jsx)(n.code,{children:"loadbalancer"}),", ",(0,s.jsx)(n.code,{children:"loadbalancer pool"}),", ",(0,s.jsx)(n.code,{children:"loadbalancer listener"}),", ",(0,s.jsx)(n.code,{children:"security group"}),", ",(0,s.jsx)(n.code,{children:"keypair"}),", ",(0,s.jsx)(n.code,{children:"image"}),", ...)"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," uses and ",(0,s.jsx)(n.code,{children:"APIMonitor_TIMESTAMP"})," prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong.\n",(0,s.jsx)(n.code,{children:"TIMESTAMP"})," is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time)."]}),"\n",(0,s.jsxs)(n.p,{children:["This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least ",(0,s.jsx)(n.code,{children:"-N 2"})," to test the ability of the router to route traffic between networks. So expect ",(0,s.jsx)(n.code,{children:"-n 6"})," to become ",(0,s.jsx)(n.code,{children:"-N 2 -n 6"})," for a very small single-AZ cloud or ",(0,s.jsx)(n.code,{children:"-n 12"})," for a large 3 AZ cloud region. So, re-run the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," with the target sizing."]}),"\n",(0,s.jsx)(n.h3,{id:"resource-impact-and-charging",children:"Resource impact and charging"}),"\n",(0,s.jsxs)(n.p,{children:["Note that ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," uses small flavors (",(0,s.jsx)(n.code,{children:"SCS-1V-2"})," for the N jump hosts and ",(0,s.jsx)(n.code,{children:"SCS-1L-1"})," for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors."]}),"\n",(0,s.jsxs)(n.p,{children:["If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," in a loop (which you will) with say 10 VMs (e.g. ",(0,s.jsx)(n.code,{children:"-N 2 -n 8"}),") in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference."]}),"\n",(0,s.jsxs)(n.p,{children:["Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of ",(0,s.jsx)(n.code,{children:"openstack volume list"}),", ",(0,s.jsx)(n.code,{children:"openstack volume show BROKEN_VOLUME"}),", ",(0,s.jsx)(n.code,{children:"openstack loadbalancer list"}),", ",(0,s.jsx)(n.code,{children:"openstack loadbalancer show BROKEN_LB"}),".)"]}),"\n",(0,s.jsxs)(n.p,{children:["Using ",(0,s.jsx)(n.code,{children:"-w -1"})," makes ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," wait for interactive input whenever an error occurs; this can be convenient for debugging."]}),"\n",(0,s.jsx)(n.p,{children:"Once you have single iterations working nicely, we can proceed."}),"\n",(0,s.jsx)(n.h2,{id:"automating-startup-and-cleanup",children:"Automating startup and cleanup"}),"\n",(0,s.jsxs)(n.p,{children:["Typically, we run ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'#!/bin/bash\n# run_CLOUDNAME.sh\n# Do some global settings\nexport IMG="Debian 12"\nexport JHIMG="Debian 12"\n#export OS_CACERT=/home/debian/ca-certificates.pem\n# Additional settings to override flavors or to\n# configure email addresses for sending alarms can be set here\n\n# Does openstack CLI work?\nopenstack server list >/dev/null || exit 1\n# Upload log files to this swift container (which you need to create)\n#export SWIFTCONTAINER=OS-HM-Logfiles\n\n# CLEANUP\necho "Finding resources from previous runs to clean up ..."\n# Find Floating IPs\nFIPLIST=""\nFIPS=$(openstack floating ip list -f value -c ID)\nfor fip in $FIPS; do\n FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")\n if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_\n"; fi\ndone\nFIPLIST=$(echo "$FIPLIST" | grep -v \'^$\' | sort -u)\n# Cleanup previous interrupted runs\nSERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nKEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nVOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nNETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nLOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nSECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)\necho CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS\nfor ENV in $FIPLIST; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV\n echo "******************************"\ndone\nTOCLEAN=$(echo "$SERVERS\n$KEYPAIR\n$VOLUMES\n$NETWORK\n$LOADBAL\n$ROUTERS\n$SECGRPS\n" | grep -v \'^$\' | sort -u)\nfor ENV in $TOCLEAN; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV\n echo "******************************"\ndone\n\n# Now run the monitor\n#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"\nexec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Compared to the previous run, we have explicitly set two networks here ",(0,s.jsx)(n.code,{children:"-N 2"})," and rely on the iterations being passed in as command line arguments. Add parameter ",(0,s.jsx)(n.code,{children:"-t"})," if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (",(0,s.jsx)(n.code,{children:"-LO"}),") in this example rather than the amphora based one (",(0,s.jsx)(n.code,{children:"-LL"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["You may use one of the existing ",(0,s.jsx)(n.code,{children:"run_XXXX.sh"})," scripts as example. Beware: eMail alerting with ",(0,s.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESS"})," and ",(0,s.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESS"})," (and limiting with ",(0,s.jsx)(n.code,{children:"-a"})," and ",(0,s.jsx)(n.code,{children:"-R"})," ) and reporting data to telegraf (option ",(0,s.jsx)(n.code,{children:"-S"}),") may be present in the samples. Make this script executable (",(0,s.jsx)(n.code,{children:"chmod +x run_CLOUDNAME.sh"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["We wrap a loop around this in ",(0,s.jsx)(n.code,{children:"run_in_loop.sh"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'#!/bin/bash\n# run_in_loop.sh\nrm stop-os-hm 2>/dev/null\nwhile true; do\n ./run_CLOUDNAME.sh -i 200\n if test -e stop-os-hm; then break; fi\n echo -n "Hit ^C to abort ..."\n sleep 15; echo\ndone\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Also make this executable (",(0,s.jsx)(n.code,{children:"chmod +x run_in_loop.sh"}),").\nTo run this automatically in a tmux window whenever the system starts, we follow the steps in the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/startup/README.md",children:"startup README.md"})]}),"\n",(0,s.jsxs)(n.p,{children:["Change ",(0,s.jsx)(n.code,{children:"OS_CLOUD"})," in ",(0,s.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"}),". (If you need to set ",(0,s.jsx)(n.code,{children:"OS_CACERT"}),", also add it in this file and pass it into the windows.)"]}),"\n",(0,s.jsx)(n.p,{children:"Activate everything:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"mkdir -p ~/.config/systemd/user/\ncp -p startup/apimon.service ~/.config/systemd/user/\nsystemctl --user enable apimon\nsystemctl --user start apimon\nsudo loginctl enable-linger debian\ntmux attach -t oshealthmon\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This assumes that you are using the user ",(0,s.jsx)(n.code,{children:"debian"})," for this monitoring and have checked out the repository at ",(0,s.jsx)(n.code,{children:"~/openstack-health-monitor/"}),". Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)"]}),"\n",(0,s.jsx)(n.h3,{id:"changing-parameters-and-restarting",children:"Changing parameters and restarting"}),"\n",(0,s.jsxs)(n.p,{children:["If you want to change the parameters passed to ",(0,s.jsx)(n.code,{children:"api_monitor.sh"}),", you best do this by editing ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),", potentially after testing it with one iteration before."]}),"\n",(0,s.jsxs)(n.p,{children:["To make the change effective, you can wait until the current 200 iterations are completed and the ",(0,s.jsx)(n.code,{children:"run_in_loop.sh"})," calls ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," again. You can also hit ",(0,s.jsx)(n.code,{children:"^C"})," in the tmux window that has",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ",(0,s.jsx)(n.code,{children:"^C"})," during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ",(0,s.jsx)(n.code,{children:"^C"})," twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ",(0,s.jsx)(n.code,{children:"./run_in_loop.sh"})," again."]}),"\n",(0,s.jsxs)(n.p,{children:["You can also issue the ",(0,s.jsx)(n.code,{children:"systemctl --user stop apimon"})," command; it will basically do the same thing: Send ",(0,s.jsx)(n.code,{children:"^C"})," and then wait for everything to be completed and tear down the tmux session.\nAfter waiting for that to complete, you can start it again with ",(0,s.jsx)(n.code,{children:"systemctl --user start apimon"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"multiple-instances",children:"Multiple instances"}),"\n",(0,s.jsxs)(n.p,{children:["You can run multiple instances of ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," on the same driver VM. In this case, you should rename ",(0,s.jsx)(n.code,{children:"run_in_loop.sh"})," to e.g. ",(0,s.jsx)(n.code,{children:"run_in_loop_CLOUDNAME1.sh"})," and call ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME1.sh"})," from there. Don't forget to adjust ",(0,s.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"})," and ",(0,s.jsx)(n.code,{children:"startup/kill-apimon-in-tmux.sh"})," to start more windows."]}),"\n",(0,s.jsxs)(n.p,{children:["It is not recommended to run multiple instances against the same OpenStack project however. While the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations."]}),"\n",(0,s.jsx)(n.h2,{id:"alarming-and-logs",children:"Alarming and Logs"}),"\n",(0,s.jsx)(n.h3,{id:"email",children:"eMail"}),"\n",(0,s.jsxs)(n.p,{children:["If wanted, the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the ",(0,s.jsx)(n.code,{children:"-a N"})," and ",(0,s.jsx)(n.code,{children:"-R"})," options. In order to enable sending emails from the driver VM, it needs to have ",(0,s.jsx)(n.code,{children:"postfix"})," (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly."]}),"\n",(0,s.jsxs)(n.p,{children:["Once you have configured ",(0,s.jsx)(n.code,{children:"postfix"}),", you can enable eMail notifications using the option ",(0,s.jsx)(n.code,{children:"-e"}),". Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ",(0,s.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESSES"})," and ",(0,s.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESSES"})," environment variables to ",(0,s.jsx)(n.code,{children:"api_monitor.sh"}),", e.g. by setting it in the ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"log-files",children:"Log files"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"api_monitor.sh"})," writes a log file with the name ",(0,s.jsx)(n.code,{children:"APIMonitor_TIMESTAMP.log"}),". It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (",(0,s.jsx)(n.code,{children:"TIMESTAMP"})," is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)"]}),"\n",(0,s.jsxs)(n.p,{children:["Note that ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties."]}),"\n",(0,s.jsxs)(n.p,{children:["The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable ",(0,s.jsx)(n.code,{children:"SWIFTCONTAINER"})," has been set (in ",(0,s.jsx)(n.code,{children:"run_COULDNAME.sh"}),") when starting ",(0,s.jsx)(n.code,{children:"api_monitor.sh"}),". the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: ",(0,s.jsx)(n.code,{children:"export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER"})]}),"\n",(0,s.jsxs)(n.p,{children:["After the 200 iterations, a ",(0,s.jsx)(n.code,{children:".psv"})," file (pipe-separated values) is created ",(0,s.jsx)(n.code,{children:"Stats.STARTTIME-ENDTIME.psv"})," (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured)."]}),"\n",(0,s.jsx)(n.h2,{id:"data-collection-and-dashboard",children:"Data collection and dashboard"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md",children:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md"})]}),"\n",(0,s.jsx)(n.h3,{id:"telegraf",children:"Telegraf"}),"\n",(0,s.jsx)(n.p,{children:"To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key\necho "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list\nsudo apt update\nsudo apt -y install telegraf\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the config file ",(0,s.jsx)(n.code,{children:"/etc/telegraf/telegraf.conf"}),", we enable"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:'[[inputs.influxdb_listener]]\n service_address = ":8186"\n\n[[outputs.influxdb]]\n urls = ["http://127.0.0.1:8086"]\n'})}),"\n",(0,s.jsxs)(n.p,{children:["and restart the service (",(0,s.jsx)(n.code,{children:"sudo systemctl restart telegraf"}),").\nEnable it on system startup: ",(0,s.jsx)(n.code,{children:"sudo systemctl enable telegraf"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"influxdb",children:"InfluxDB"}),"\n",(0,s.jsx)(n.p,{children:"We proceed to influxdb:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo apt-get install influxdb\n"})}),"\n",(0,s.jsxs)(n.p,{children:["In the configuration file ",(0,s.jsx)(n.code,{children:"/etc/influxdb/influxdb.conf"}),", ensure that the http interface on port 8086 is enabled."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:'[http]\n enabled = true\n bind-address = ":8086"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Restart influxdb as needed with ",(0,s.jsx)(n.code,{children:"sudo systemctl restart influxdb"}),".\nAlso enable it on system startup: ",(0,s.jsx)(n.code,{children:"sudo systemctl enable influxdb"}),"."]}),"\n",(0,s.jsxs)(n.h3,{id:"add--s-cloudname-to-your-run_cloudnamesh-script",children:["Add ",(0,s.jsx)(n.code,{children:"-S CLOUDNAME"})," to your ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script"]}),"\n",(0,s.jsxs)(n.p,{children:["You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter ",(0,s.jsx)(n.code,{children:"-S CLOUDNAME"})," to the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," call in ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),". Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete)."]}),"\n",(0,s.jsx)(n.h3,{id:"caddy-reverse-proxy",children:"Caddy (Reverse Proxy)"}),"\n",(0,s.jsxs)(n.p,{children:["We're going to deploy Grafana behind ",(0,s.jsx)(n.a,{href:"https://caddyserver.com/docs/",children:"Caddy"})," as a reverse proxy.\nCaddy is very easy to configure, comes with sensible defaults and can automatically provision TLS\ncertificates using Let's Encrypt."]}),"\n",(0,s.jsx)(n.h4,{id:"install-caddy",children:"Install Caddy"}),"\n",(0,s.jsxs)(n.p,{children:["We follow ",(0,s.jsx)(n.a,{href:"https://caddyserver.com/docs/install#debian-ubuntu-raspbian",children:"https://caddyserver.com/docs/install#debian-ubuntu-raspbian"})," to setup the stable APT repository:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl\ncurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg\ncurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list\n"})}),"\n",(0,s.jsx)(n.p,{children:"And install Caddy:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo apt update\nsudo apt install caddy\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Ensure it's started and starts at boot with ",(0,s.jsx)(n.code,{children:"sudo systemctl enable --now caddy"}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"allow-http-traffic-for-oshm-driver",children:"Allow HTTP traffic for oshm-driver"}),"\n",(0,s.jsxs)(n.p,{children:["Caddy needs TCP port ",(0,s.jsx)(n.code,{children:"80"})," opened to be able to process the Let's Encrypt HTTP challenge, so let's\nconfigure an appropriate security group for ",(0,s.jsx)(n.code,{children:"oshm-driver"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"openstack security group create http\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 80 http\nopenstack server add security group oshm-driver http\n"})}),"\n",(0,s.jsx)(n.h4,{id:"configure-caddy",children:"Configure Caddy"}),"\n",(0,s.jsxs)(n.p,{children:["Create a file ",(0,s.jsx)(n.code,{children:"/etc/caddy/Caddyfile"})," with the following contents:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"https://health.YOURCLOUD.osba.sovereignit.cloud:3000 {\n\treverse_proxy localhost:3003\n}\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Replace ",(0,s.jsx)(n.code,{children:"health.YOURCLOUD.osba.sovereignit.cloud"})," with your actual domain.\nYou can use a hostname of your liking, but Caddy will create TLS certificates for this host using\nthe HTTP challenge.\nThe ",(0,s.jsx)(n.code,{children:"sovereignit.cloud"})," domain is controlled by the SCS project team and has been used for a number\nof health mon instances."]}),"\n",(0,s.jsxs)(n.p,{children:["Reload Caddy with ",(0,s.jsx)(n.code,{children:"sudo systemctl reload caddy"}),". That's it."]}),"\n",(0,s.jsxs)(n.p,{children:["You should now be able to access ",(0,s.jsx)(n.code,{children:"https://health.YOURCLOUD.sovereignit.cloud:3000"})," and see a proxy error\npage because the Grafana service is not yet running (this is our next step).\nThe very first request will be a bit slower, because Caddy interacts with Let's Encrypt API to create\nthe TLS certificate behind the scenes."]}),"\n",(0,s.jsxs)(n.p,{children:["Caddy logs can be accessed with ",(0,s.jsx)(n.code,{children:"sudo journalctl -u caddy"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"grafana",children:"Grafana"}),"\n",(0,s.jsx)(n.h4,{id:"install-grafana",children:"Install Grafana"}),"\n",(0,s.jsxs)(n.p,{children:["We follow ",(0,s.jsx)(n.a,{href:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/",children:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/"})," and setup the stable APT repository:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'mkdir -p /etc/apt/keyrings\nwget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null\necho "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list\n'})}),"\n",(0,s.jsx)(n.p,{children:"And install it:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo apt update\nsudo apt -y install grafana\n"})}),"\n",(0,s.jsx)(n.h4,{id:"basic-config",children:"Basic config"}),"\n",(0,s.jsxs)(n.p,{children:["The config file ",(0,s.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," needs some adjustments."]}),"\n",(0,s.jsx)(n.p,{children:"We're going to deploy Grafana behind a reverse proxy (Caddy) and configure it as such."}),"\n",(0,s.jsxs)(n.p,{children:["Therefore, in the ",(0,s.jsx)(n.code,{children:"[server]"})," section:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[server]\nprotocol = http\nhttp_addr = 127.0.0.1\nhttp_port = 3003\ndomain = health.YOURCLOUD.sovereignit.cloud\nroot_url = https://%(domain)s:3000/\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Please replace ",(0,s.jsx)(n.code,{children:"health.YOURCLOUD.sovereignit.cloud"})," with your actual domain."]}),"\n",(0,s.jsxs)(n.p,{children:["Next, in the ",(0,s.jsx)(n.code,{children:"[security]"})," section, set:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[security]\nadmin_user = admin\nadmin_password = SOME_SECRET_PASS\nsecret_key = SOME_SECRET_KEY\ndata_source_proxy_whitelist = localhost:8088 localhost:8086\ncookie_secure = true\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Please replace ",(0,s.jsx)(n.code,{children:"SOME_SECRET_PASS"})," and ",(0,s.jsx)(n.code,{children:"SOME_SECRET_KEY"})," with secure passwords (for example, you can use ",(0,s.jsx)(n.code,{children:"pwgen -s 20"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["Finally, in the ",(0,s.jsx)(n.code,{children:"[users]"})," section, set:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[users]\nallow_sign_up = false\nallow_org_create = false\n"})}),"\n",(0,s.jsx)(n.p,{children:"The configuration file contains secrets and should be protected such that only root and group grafana\ncan read it:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo chown root:grafana /etc/grafana/grafana.ini\nsudo chmod 0640 /etc/grafana/grafana.ini\n"})}),"\n",(0,s.jsxs)(n.p,{children:["We do the OIDC connection in the section ",(0,s.jsx)(n.code,{children:"[auth.github]"})," ",(0,s.jsx)(n.a,{href:"#github-oidc-integration",children:"later"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["We can now restart the service: ",(0,s.jsx)(n.code,{children:"sudo systemctl restart grafana-server"}),".\nBeing at it, also enable it on system startup: ",(0,s.jsx)(n.code,{children:"sudo systemctl enable grafana-server"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You should now be able to access your dashboard on ",(0,s.jsx)(n.code,{children:"https://health.YOURCLOUD.sovereignit.cloud:3000"})," and log in\nvia the configured username ",(0,s.jsx)(n.code,{children:"admin"})," and your ",(0,s.jsx)(n.code,{children:"SOME_SECRET_PASS"})," password."]}),"\n",(0,s.jsx)(n.h4,{id:"enable-influx-database-in-grafana",children:"Enable influx database in grafana"}),"\n",(0,s.jsxs)(n.p,{children:["In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to ",(0,s.jsx)(n.code,{children:"http://localhost:8086"})," (despite this being the suggestion). Set the database name to ",(0,s.jsx)(n.code,{children:"telegraf"}),". Save&test should succeed."]}),"\n",(0,s.jsx)(n.h4,{id:"importing-the-dashboard",children:"Importing the dashboard"}),"\n",(0,s.jsxs)(n.p,{children:["Go to Home, Dashboards, New, Import.\nUpload the dashboard ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard.json",children:".json file"})," from the repository, user the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard-10.json",children:"Grafana-10 variant"})," if you use Grafana 10 or newer."]}),"\n",(0,s.jsx)(n.p,{children:"In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.)\nSave."}),"\n",(0,s.jsx)(n.p,{children:"Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable)."}),"\n",(0,s.jsx)(n.h4,{id:"no-data-displayed",children:"No data displayed?"}),"\n",(0,s.jsx)(n.p,{children:'Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.'}),"\n",(0,s.jsx)(n.p,{children:"One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved."}),"\n",(0,s.jsx)(n.h4,{id:"dashboard-features",children:"Dashboard features"}),"\n",(0,s.jsx)(n.p,{children:"Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended."}),"\n",(0,s.jsx)(n.p,{children:"The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously."}),"\n",(0,s.jsx)(n.p,{children:"You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term."}),"\n",(0,s.jsx)(n.h4,{id:"github-oidc-integration",children:"GitHub OIDC Integration"}),"\n",(0,s.jsx)(n.p,{children:"The SCS providers do allow all GitHub users that belong to the SovereignCloudStack organization to get Viewer\naccess to the dashboards.\nThis allows to exchange experience and to get a feeling for the achievable stability.\n(Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)"}),"\n",(0,s.jsxs)(n.p,{children:["OIDC integration is achieved by adjusting the ",(0,s.jsx)(n.code,{children:"[auth.github]"})," section in ",(0,s.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," as follows:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:'[auth.github]\nenabled = true\nclient_id = YOUR_CLIENT_ID\nclient_secret = YOUR_CLIENT_SECRET\nallowed_organizations = ["SovereignCloudStack"]\nrole_attribute_path = "\'Viewer\'"\nallow_assign_grafana_admin = false\nskip_org_role_sync = true\n'})}),"\n",(0,s.jsxs)(n.p,{children:["This config maps all users to the ",(0,s.jsx)(n.code,{children:"Viewer"})," role regardless of their role in the GitHub Org.\nPlease replace ",(0,s.jsx)(n.code,{children:"YOUR_CLIENT_ID"})," and ",(0,s.jsx)(n.code,{children:"YOUR_CLIENT_SECRET"})," with the OAuth2 credentials that the SCS Org GitHub admins\nprovided to you.\nFinally, don't forgot to restart Grafana with ",(0,s.jsx)(n.code,{children:"sudo systemctl restart grafana-server"})," after adjusting the config."]}),"\n",(0,s.jsxs)(n.p,{children:["More information can be found in the ",(0,s.jsx)(n.a,{href:"https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/github/",children:"Grafana documentation for GitHub OAuth2"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"maintenance",children:"Maintenance"}),"\n",(0,s.jsx)(n.p,{children:"The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained."}),"\n",(0,s.jsx)(n.h3,{id:"unattended-upgrades",children:"Unattended upgrades"}),"\n",(0,s.jsxs)(n.p,{children:["It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See ",(0,s.jsx)(n.a,{href:"https://wiki.debian.org/UnattendedUpgrades",children:"https://wiki.debian.org/UnattendedUpgrades"}),". If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and Caddy/Grafana (port 3000)."]}),"\n",(0,s.jsxs)(n.p,{children:["If you use ",(0,s.jsx)(n.code,{children:"unattended-upgrades"}),", you should review your settings in ",(0,s.jsx)(n.code,{children:"/etc/apt/apt.conf.d/50unattended-upgrades"}),",\nespecially ",(0,s.jsx)(n.code,{children:"Unattended-Upgrade::Origins-Pattern"}),". It controls which packages are upgraded. If you want Caddy to be\npart of the automated updates, add an entry like the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'Unattended-Upgrade::Origins-Pattern {\n // ...\n "origin=cloudsmith/caddy/stable";\n};\n'})}),"\n",(0,s.jsxs)(n.p,{children:["(This corresponds to ",(0,s.jsx)(n.code,{children:"o=cloudsmith/caddy/stable"})," in the output of ",(0,s.jsx)(n.code,{children:"apt-cache policy"}),")."]}),"\n",(0,s.jsx)(n.h3,{id:"sshd-setup",children:"sshd setup"}),"\n",(0,s.jsxs)(n.p,{children:["If you already use SSH keys to sign in to the driver VM, consider setting the following in your ",(0,s.jsx)(n.code,{children:"/etc/ssh/sshd_config"}),"\nif not already set:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"PasswordAuthentication no\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Debian's ",(0,s.jsx)(n.code,{children:"openssh-server"}),", by default, is also very open about its version, so you might consider disabling this via:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"DebianBanner no\n"})}),"\n",(0,s.jsx)(n.h3,{id:"updating-openstack-health-monitor",children:"Updating openstack-health-monitor"}),"\n",(0,s.jsxs)(n.p,{children:["You can just do a ",(0,s.jsx)(n.code,{children:"git update"})," in the ",(0,s.jsx)(n.code,{children:"openstack-health-monitor"})," directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ",(0,s.jsx)(n.code,{children:"^C"}),", see above in the restart section."]}),"\n",(0,s.jsx)(n.h3,{id:"backup",children:"Backup"}),"\n",(0,s.jsxs)(n.p,{children:["The system holds two things that you might consider valuable for long-term storage:\n(1) The log files. These are compressed and uploaded to object storage if you enable the ",(0,s.jsx)(n.code,{children:"SWIFTCONTAINER"})," setting, which probably means that these do not need any additional backing up then.\n(2) The influx time series data. Back up the data in ",(0,s.jsx)(n.code,{children:"/var/lib/influxdb"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, ",(0,s.jsx)(n.code,{children:"clouds.yaml"}),", etc. Be careful not to expose sensitive data by granting too generous access to your backed up files."]}),"\n",(0,s.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,s.jsx)(n.h3,{id:"debugging-issues",children:"Debugging issues"}),"\n",(0,s.jsx)(n.p,{children:"In case there is trouble with your cloud, the normal course of action to analyze is as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Look at the dashboard (see above)"}),"\n",(0,s.jsxs)(n.li,{children:["Connect to the driver VM and attach to the tmux session and look at the console output of ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})]}),"\n",(0,s.jsx)(n.li,{children:"Analyze the logfile (locally on the driver VM or grab it from the object storage)"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"analyzing-failures",children:"Analyzing failures"}),"\n",(0,s.jsxs)(n.p,{children:["When VM instances are created successfully, but then end up in ",(0,s.jsx)(n.code,{children:"ERROR"})," state, the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," does an explicit ",(0,s.jsx)(n.code,{children:"openstack server show"}),", so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files."]}),"\n",(0,s.jsxs)(n.p,{children:["Sometimes the VMs end up being ",(0,s.jsx)(n.code,{children:"ACTIVE"})," as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail."]}),"\n",(0,s.jsxs)(n.p,{children:["To gather more details, you can look at the console output ",(0,s.jsx)(n.code,{children:"openstack console log show VM"})," (where ",(0,s.jsx)(n.code,{children:"VM"})," is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ",(0,s.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_JH.pem debian@FIP"}),", whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ",(0,s.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP"}),". Replace ",(0,s.jsx)(n.code,{children:"XXXXX"})," with the number in your current APIMonitor prefix, ",(0,s.jsx)(n.code,{children:"FIP"})," with the floating IP address of the responsible JumpHost and ",(0,s.jsx)(n.code,{children:"debian"})," with the user name used by the images you boot. Use ",(0,s.jsx)(n.code,{children:"223"})," to connect to the second VM in the network, ",(0,s.jsx)(n.code,{children:"224"})," the third etc."]}),"\n",(0,s.jsxs)(n.p,{children:["When logged in, look at ",(0,s.jsx)(n.code,{children:"/var/log/cloud-init-output.log"})," and ",(0,s.jsx)(n.code,{children:"/var/log/cloud-init.log"}),". You can find the metadata in ",(0,s.jsx)(n.code,{children:"/var/lib/cloud/instance/"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You will not have much time to look around -- the still running ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," script does continue and clean things up again. So you might want to suspend it with ",(0,s.jsx)(n.code,{children:"^Z"})," (and continue it later with ",(0,s.jsx)(n.code,{children:"fg"}),"). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script as it would do cleanup against the running instance, but rather copy the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," command line from the bottom (without the ",(0,s.jsx)(n.code,{children:"exec"}),"), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach ",(0,s.jsx)(n.code,{children:"-w -1"})," to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work."]}),"\n",(0,s.jsx)(n.h3,{id:"cleaning-things-up",children:"Cleaning things up"}),"\n",(0,s.jsx)(n.p,{children:"If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard)."}),"\n",(0,s.jsx)(n.p,{children:"There are a few things that may need support from a cloud admin:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Volumes may end up permanently in a ",(0,s.jsx)(n.code,{children:"deleting"})," or ",(0,s.jsx)(n.code,{children:"reserved"})," state or may be ",(0,s.jsx)(n.code,{children:"in-use"}),", attached to a VM that has long gone. The admin needs to set the state to ",(0,s.jsx)(n.code,{children:"error"})," and then delete them."]}),"\n",(0,s.jsxs)(n.li,{children:["Loadbalancers may end up in a ",(0,s.jsx)(n.code,{children:"PENDING_XXX"})," state (",(0,s.jsx)(n.code,{children:"XXX"})," being ",(0,s.jsx)(n.code,{children:"CREATE"}),", ",(0,s.jsx)(n.code,{children:"UPDATE"})," or ",(0,s.jsx)(n.code,{children:"DELETE"}),") without ever changing. This also needs the cloud admin to set the status to ",(0,s.jsx)(n.code,{children:"ERROR"}),", so it can be cleaned up. amphorae are more prone to this than ovn LBs."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsxs)(n.em,{children:["The source of this document can be found in the ",(0,s.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/openstack-health-monitor/main/docs/Debian12-Install.md",children:"SovereignCloudStack/openstack-health-monitor"})," repository."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.em,{children:"Author: SCS Community, License: CC by Attribution 4.0 International"})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var o=t(96540);const s={},a=o.createContext(s);function i(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/94f31572.a38e1964.js b/assets/js/94f31572.a38e1964.js new file mode 100644 index 0000000000..d09f7751fe --- /dev/null +++ b/assets/js/94f31572.a38e1964.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[69752],{59299:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"faq/index","title":"Frequently Asked Questions","description":"What does SCS stand for?","source":"@site/docs/08-faq/index.mdx","sourceDirName":"08-faq","slug":"/faq/","permalink":"/docs/faq/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/08-faq/index.mdx","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Release Notes for SCS Release 7","permalink":"/docs/releases/Release7"},"next":{"title":"Glossary","permalink":"/docs/glossary"}}');var a=s(74848),o=s(28453);const i={},r="Frequently Asked Questions",d={},c=[{value:"What does SCS stand for?",id:"what-does-scs-stand-for",level:2},{value:"Who is SCS intended for?",id:"who-is-scs-intended-for",level:2},{value:"Who or what is behind SCS?",id:"who-or-what-is-behind-scs",level:2},{value:"Why is there a need for a standardized cloud environment?",id:"why-is-there-a-need-for-a-standardized-cloud-environment",level:2},{value:"Where can I find the SCS standards?",id:"where-can-i-find-the-scs-standards",level:2},{value:"How is the SCS different from other cloud environments (e.g. AWS, Azure,...)?",id:"how-is-the-scs-different-from-other-cloud-environments-eg-aws-azure",level:2},{value:"My company already has a cloud environment. Can we still use the SCS?",id:"my-company-already-has-a-cloud-environment-can-we-still-use-the-scs",level:2},{value:"What does reference implementation mean?",id:"what-does-reference-implementation-mean",level:2},{value:"Do I need to use the reference implementation to be SCS compliant?",id:"do-i-need-to-use-the-reference-implementation-to-be-scs-compliant",level:2},{value:"Do I have to use all layers of the reference implementation (IaaS, CaaS)?",id:"do-i-have-to-use-all-layers-of-the-reference-implementation-iaas-caas",level:2},{value:"What does IaaS mean?",id:"what-does-iaas-mean",level:2},{value:"How is the IaaS layer structured?",id:"how-is-the-iaas-layer-structured",level:2},{value:"What does CaaS mean? (Container Layer)",id:"what-does-caas-mean-container-layer",level:2},{value:"I want to try out the SCS! Where do I start?",id:"i-want-to-try-out-the-scs-where-do-i-start",level:2},{value:"I want to use an SCS Cloud! How do I get started?",id:"i-want-to-use-an-scs-cloud-how-do-i-get-started",level:2},{value:"I want to use the SCS in my company and build my own cloud! Where do I start?",id:"i-want-to-use-the-scs-in-my-company-and-build-my-own-cloud-where-do-i-start",level:2},{value:"I have a technical problem. Where can I find help?",id:"i-have-a-technical-problem-where-can-i-find-help",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"frequently-asked-questions",children:"Frequently Asked Questions"})}),"\n",(0,a.jsx)(n.h2,{id:"what-does-scs-stand-for",children:"What does SCS stand for?"}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.h2,{id:"who-is-scs-intended-for",children:"Who is SCS intended for?"}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.h2,{id:"who-or-what-is-behind-scs",children:"Who or what is behind SCS?"}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.h2,{id:"why-is-there-a-need-for-a-standardized-cloud-environment",children:"Why is there a need for a standardized cloud environment?"}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.h2,{id:"where-can-i-find-the-scs-standards",children:"Where can I find the SCS standards?"}),"\n",(0,a.jsxs)(n.p,{children:["The SCS standards are available on the standards pages within our documentation page. ",(0,a.jsx)(n.a,{href:"https://docs.scs.community/standards",children:"Find them here"})]}),"\n",(0,a.jsx)(n.h2,{id:"how-is-the-scs-different-from-other-cloud-environments-eg-aws-azure",children:"How is the SCS different from other cloud environments (e.g. AWS, Azure,...)?"}),"\n",(0,a.jsx)(n.p,{children:"Unlike proprietary clouds, SCS emphasizes standardization, ensuring interoperability and reduced dependency on one provider."}),"\n",(0,a.jsx)(n.h2,{id:"my-company-already-has-a-cloud-environment-can-we-still-use-the-scs",children:"My company already has a cloud environment. Can we still use the SCS?"}),"\n",(0,a.jsx)(n.p,{children:"Yes, SCS can complement existing environments, enhancing standardization and interoperability."}),"\n",(0,a.jsx)(n.h2,{id:"what-does-reference-implementation-mean",children:"What does reference implementation mean?"}),"\n",(0,a.jsx)(n.p,{children:"Reference implementation is a concrete example or blueprint of how the SCS standards can be implemented."}),"\n",(0,a.jsx)(n.h2,{id:"do-i-need-to-use-the-reference-implementation-to-be-scs-compliant",children:"Do I need to use the reference implementation to be SCS compliant?"}),"\n",(0,a.jsxs)(n.p,{children:["No, while the reference implementation is a guide, compliance requires adhering to SCS standards, not the exact blueprint of the reference implementation. ",(0,a.jsx)(n.a,{href:"https://docs.scs.community/standards/",children:"Check the standards page on how to be SCS-compatible"})]}),"\n",(0,a.jsx)(n.h2,{id:"do-i-have-to-use-all-layers-of-the-reference-implementation-iaas-caas",children:"Do I have to use all layers of the reference implementation (IaaS, CaaS)?"}),"\n",(0,a.jsx)(n.p,{children:"No, you can choose layers based on your needs and still be SCS compliant."}),"\n",(0,a.jsx)(n.h2,{id:"what-does-iaas-mean",children:"What does IaaS mean?"}),"\n",(0,a.jsx)(n.p,{children:"IaaS stands for Infrastructure as a Service, providing virtualized computing resources over the internet."}),"\n",(0,a.jsx)(n.h2,{id:"how-is-the-iaas-layer-structured",children:"How is the IaaS layer structured?"}),"\n",(0,a.jsxs)(n.p,{children:["IaaS typically comprises virtual machines, storage, and network resources, all offered as scalable services. ",(0,a.jsx)(n.a,{href:"https://docs.scs.community/docs/category/iaas-layer",children:"Find the architecture here"})]}),"\n",(0,a.jsx)(n.h2,{id:"what-does-caas-mean-container-layer",children:"What does CaaS mean? (Container Layer)"}),"\n",(0,a.jsx)(n.p,{children:"CaaS refers to Container as a Service, where providers offer container orchestration platforms."}),"\n",(0,a.jsx)(n.h2,{id:"i-want-to-try-out-the-scs-where-do-i-start",children:"I want to try out the SCS! Where do I start?"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"As a user"}),":"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Existing SCS Clouds: Explore and test on any of the cloud providers offering SCS. ",(0,a.jsx)(n.a,{href:"https://docs.scs.community/standards/certification/overview#compliant-cloud-environments",children:"Choose one from here"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"As a Cloud Service Provider"}),":"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Cloud in a Box"}),": Start with our pre-packaged solutions. ",(0,a.jsx)(n.a,{href:"https://docs.scs.community/docs/iaas/deployment-examples/cloud-in-a-box/advanced-guides/cloud-in-a-box",children:"Link to Ciab"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Testbed"}),": Use the SCS test environment to experiment. ",(0,a.jsx)(n.a,{href:"https://docs.scs.community/docs/iaas/deployment-examples/cloud-in-a-box/advanced-guides/testbed",children:"Link to Testbed/deployment example"})]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"i-want-to-use-an-scs-cloud-how-do-i-get-started",children:"I want to use an SCS Cloud! How do I get started?"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"As a user"}),":"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Browse our ",(0,a.jsx)(n.a,{href:"https://docs.scs.community/standards/certification/overview#compliant-cloud-environments",children:"list of providers"})," and choose one that fits your needs."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"As a Cloud Service Provider"}),":"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Adopt SCS standards and utilize our ",(0,a.jsx)(n.a,{href:"https://docs.scs.community/docs/category/components",children:"resources and tools"})," to integrate them."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"i-want-to-use-the-scs-in-my-company-and-build-my-own-cloud-where-do-i-start",children:"I want to use the SCS in my company and build my own cloud! Where do I start?"}),"\n",(0,a.jsxs)(n.p,{children:["Start by understanding SCS standards and then move on to the reference implementation. ",(0,a.jsx)(n.a,{href:"https://docs.scs.community/standards/",children:"Link to guide"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"i-have-a-technical-problem-where-can-i-find-help",children:"I have a technical problem. Where can I find help?"}),"\n",(0,a.jsxs)(n.p,{children:["Refer to our support section or check our community channels for assistance. ",(0,a.jsx)(n.a,{href:"https://docs.scs.community/community",children:"Link to community"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>r});var t=s(96540);const a={},o=t.createContext(a);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/950c7487.4bf72790.js b/assets/js/950c7487.4bf72790.js new file mode 100644 index 0000000000..df24b20e9d --- /dev/null +++ b/assets/js/950c7487.4bf72790.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[42456],{92599:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"operations/operations/zuul-ci-cd-quickstart-user-guide","title":"Zuul users guide","description":"Prerequisites","source":"@site/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide.md","sourceDirName":"operations/operations","slug":"/operations/operations/zuul-ci-cd-quickstart-user-guide","permalink":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"devDocs","previous":{"title":"OpenStack Federation via OpenID-Connect","permalink":"/contributor-docs/operations/iam/openstack-federation-via-oidc"}}');var s=t(74848),o=t(28453);const r={},l="Zuul users guide",a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Who is it for?",id:"who-is-it-for",level:2},{value:"Where do I start?",id:"where-do-i-start",level:2},{value:"Where to save the Zuul relevant data?",id:"where-to-save-the-zuul-relevant-data",level:2},{value:"Projects",id:"projects",level:3},{value:"Pipelines",id:"pipelines",level:3},{value:"1. check",id:"1-check",level:4},{value:"2. gate",id:"2-gate",level:4},{value:"3. post",id:"3-post",level:4},{value:"4. tag",id:"4-tag",level:4},{value:"5. e2e-test",id:"5-e2e-test",level:4},{value:"6. e2e-quick-test",id:"6-e2e-quick-test",level:4},{value:"7. unlabel-on-update-e2e-test",id:"7-unlabel-on-update-e2e-test",level:4},{value:"8. unlabel-on-update-e2e-quick-test",id:"8-unlabel-on-update-e2e-quick-test",level:4},{value:"9. periodic-hourly",id:"9-periodic-hourly",level:4},{value:"10. periodic-daily",id:"10-periodic-daily",level:4},{value:"11. compliance_check",id:"11-compliance_check",level:4},{value:"Reports",id:"reports",level:3},{value:"Jobs",id:"jobs",level:3},{value:"What about secrets?",id:"what-about-secrets",level:4},{value:"Let's put it all together",id:"lets-put-it-all-together",level:4}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"zuul-users-guide",children:"Zuul users guide"})}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Repository is known by ",(0,s.jsx)(n.a,{href:"https://zuul.scs.community",children:"SCS Zuul"})]}),"\n",(0,s.jsx)(n.li,{children:"Basic ansible knowledge"}),"\n",(0,s.jsx)(n.li,{children:"Basic yaml knowledge"}),"\n",(0,s.jsxs)(n.li,{children:["zuul-client installed (Only if you want to create secrets. ",(0,s.jsx)(n.a,{href:"#what-about-secrets",children:"See also"}),")"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Check ",(0,s.jsx)(n.a,{href:"https://zuul.scs.community/t/SCS/projects",children:"SCS Zuul projects"})," for your repository to\nbe available. If it is missing you need an administrator to get your repository\nconfigured to Zuul."]}),"\n",(0,s.jsx)(n.h2,{id:"who-is-it-for",children:"Who is it for?"}),"\n",(0,s.jsx)(n.p,{children:"You may have heard about Zuul and may ask yourself if it is capable to support you.\nBasically everything you use ansible for can be done using Zuul. That is not always\na good thing since you may get careless and your workload will exceed the CI/CD concept."}),"\n",(0,s.jsx)(n.p,{children:"If you find yourself doing things under the following list you are at the right place."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Code testing"}),"\n",(0,s.jsx)(n.li,{children:"Deployment tests using IaC"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"If you want to, let's say, monitor something using Zuul, that is possible but not the\nintended use case."}),"\n",(0,s.jsx)(n.h2,{id:"where-do-i-start",children:"Where do I start?"}),"\n",(0,s.jsx)(n.p,{children:"Right in your project's repository! The only prerequisite is that\nyour repository you want Zuul to work on is known by Zuul. This is done by the Zuul's\ntenant configuration. To update this configuration you need access to the Zuul instance\nor ask an administrator for help."}),"\n",(0,s.jsx)(n.p,{children:'We assume that Zuul knows about your repository so we can get started. There are three\ntopics that you should know about. To get jobs running you need the "job" itself. Jobs run\nwithin a "pipeline". The third important thing is to provide a "project" definition.'}),"\n",(0,s.jsx)(n.h2,{id:"where-to-save-the-zuul-relevant-data",children:"Where to save the Zuul relevant data?"}),"\n",(0,s.jsx)(n.p,{children:'Zuul will parse all branches of the untrusted repositories that Zuul knows about.\nYour repository is most likely an untrusted one since only the configuration repositories should\nhave the "trusted" state.\nSo it doesn\'t matter whether you have just one branch containing Zuul files or all branches. Zuul\nis looking for the following pathes on your repositories root.'}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"./zuul.yaml # everything is in here\n\n./.zuul.yaml # ... or here\n\n./zuul.d/ # use directory style to get a bit of a structure\n\u251c\u2500\u2500 jobs.yaml\n\u2514\u2500\u2500 project.yaml\n\n./.zuul.d/ # the same as before just hidden\n\u251c\u2500\u2500 jobs.yaml\n\u2514\u2500\u2500 project.yaml\n"})}),"\n",(0,s.jsx)(n.p,{children:"Just use exactly one of the four possibilities."}),"\n",(0,s.jsxs)(n.p,{children:["If using the directory style configuration all ",(0,s.jsx)(n.code,{children:"yaml"})," files within this directory will be\nprocessed. If your projects configuration is small enough you may put all information in\na single file called ",(0,s.jsx)(n.code,{children:"zuul.yaml"}),". It is also possible to create the file or the directory\nwith a leading dot to hide them for non zuul related work within the repository."]}),"\n",(0,s.jsx)(n.h3,{id:"projects",children:"Projects"}),"\n",(0,s.jsx)(n.p,{children:"If Zuul is configured to observe your repository it will have a look at your projects\ndefinition. Minimal example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'- project:\n name: my-org/my-repo\n default-branch: main\n merge-mode: "squash-merge"\n my_pipeline1:\n jobs:\n - my_job1\n - my_job2\n ......\n my_pipeline2:\n jobs:\n - my_jobs\n ...\n\n'})}),"\n",(0,s.jsx)(n.p,{children:"By default Zuul will observe all branches for such files. We have to set the repository name\nthat have to match the exact value that was set for Zuul. Set a default-branch where actions\nthat don't match an explicit branch are executed on. Set the merge-mode that Zuul has to use.\nBut beware that not all issue tracker support all methods. For github squash-merge will work."}),"\n",(0,s.jsxs)(n.p,{children:["After these three properties add the pipelines you want to use to the project definition.\nWith the ",(0,s.jsx)(n.code,{children:"jobs"})," list you define which jobs to run in which pipeline."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/project.html",children:"See official documentation"})}),"\n",(0,s.jsx)(n.h3,{id:"pipelines",children:"Pipelines"}),"\n",(0,s.jsx)(n.p,{children:"Every Zuul instance will have at least one repository that is used for configuration. There\nyou will find the available pipelines. Pipelines are used to run your jobs on a periodic or\nevent driven base. Pipelines can be used to run other pipelines and to keep your jobs in a\ndefined order if you need this."}),"\n",(0,s.jsxs)(n.p,{children:["Have a look at the configuration repository to utilize the pipelines for your repository.\nSee available ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-config/blob/main/zuul.d/gh_pipelines.yaml",children:"pipelines"}),' for SCS.\nYou are not able to define new pipelines outside of a so called "configuration" repository. Since,\nby default your repo is considered "untrusted". So in the first place you don\'t need to\nthink about, how to create a pipeline. Just use one that fits your needs as close as possible. Next you will\nfind an enumeration and a small description about the available pipelines in SCS Zuul.']}),"\n",(0,s.jsx)(n.p,{children:"Pipelines available in SCS Zuul:"}),"\n",(0,s.jsx)(n.h4,{id:"1-check",children:"1. check"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,s.jsx)(n.li,{children:"runs if a pull request is created, changed or reopened"}),"\n",(0,s.jsxs)(n.li,{children:["re-runs if a comment contains ",(0,s.jsx)(n.code,{children:"recheck"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"2-gate",children:"2. gate"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,s.jsx)(n.li,{children:"trigger events: pull_request_review, pull_request, check_run"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"3-post",children:"3. post"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,s.jsx)(n.li,{children:"trigger event: post"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"4-tag",children:"4. tag"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,s.jsx)(n.li,{children:"trigger event: push"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"5-e2e-test",children:"5. e2e-test"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,s.jsx)(n.li,{children:"trigger event: pull_request"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"6-e2e-quick-test",children:"6. e2e-quick-test"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,s.jsx)(n.li,{children:"trigger event: pull_request"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"7-unlabel-on-update-e2e-test",children:"7. unlabel-on-update-e2e-test"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,s.jsx)(n.li,{children:"trigger event: pull_request"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"8-unlabel-on-update-e2e-quick-test",children:"8. unlabel-on-update-e2e-quick-test"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,s.jsx)(n.li,{children:"trigger event: pull_request"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"9-periodic-hourly",children:"9. periodic-hourly"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"time based pipeline that runs every hour"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"10-periodic-daily",children:"10. periodic-daily"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"time based pipeline that runs every day at 3 o'clock am."}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"11-compliance_check",children:"11. compliance_check"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"time based pipeline that runs every 15 minutes"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["If you want to know more about pipelines: ",(0,s.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/pipeline.html",children:"See official documentation"})]}),"\n",(0,s.jsx)(n.h3,{id:"reports",children:"Reports"}),"\n",(0,s.jsxs)(n.p,{children:["The SCS Zuul instance can transmit build reports through an MQTT connection\nto the dedicated Matrix chat room ",(0,s.jsx)(n.code,{children:"SCS | Zuul Reports"}),". Currently, this MQTT reporting\nfeature is activated for periodic pipelines (periodic-hourly, periodic-daily,\ncompliance_check), and reports are dispatched solely in the event of\nfailures occurring in builds triggered by the mentioned pipelines."]}),"\n",(0,s.jsxs)(n.p,{children:["See an example pipeline that reports failed result to the ",(0,s.jsx)(n.code,{children:"SCS | Zuul Reports"})," Matrix room:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'- pipeline:\n name: pipeline-that-reports-to-matrix\n description: |\n In the event of a failure, this pipeline transmits reports to\n the SCS | Zuul Reports Matrix chat room.\n failure:\n mqtt:\n topic: "zuul/{pipeline}/{project}/{branch}/{change}"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Visit the ",(0,s.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/pipeline.html#reporters",children:"official Zuul documentation"}),"\nand explore the configuration options available for Zuul's reporters."]}),"\n",(0,s.jsx)(n.h3,{id:"jobs",children:"Jobs"}),"\n",(0,s.jsxs)(n.p,{children:["All jobs that your Zuul instances knows of can be used for your own purposes.\nCall them directly or implement a job that uses an existing job as parent.\nDidn't find the right job? Than we have to create a new one. Existing jobs\ncan be found in the web ui of your Zuul instance: ",(0,s.jsx)(n.a,{href:"https://zuul.scs.community/t/SCS/jobs",children:"Example"})]}),"\n",(0,s.jsx)(n.p,{children:"First have a look on a basic job example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"- job:\n name: base\n parent: null\n description: |\n The recommended base job.\n\n All jobs ultimately inherit from this. It runs a pre-playbook\n which copies all of the job's prepared git repos on to all of\n the nodes in the nodeset.\n\n It also sets a default timeout value (which may be overidden).\n pre-run: playbooks/base/pre.yaml\n post-run:\n - playbooks/base/post.yaml\n - playbooks/base/post-logs.yaml\n roles:\n - zuul: zuul/zuul-jobs\n timeout: 1800\n nodeset:\n nodes:\n - name: ubuntu-jammy\n label: ubuntu-jammy\n"})}),"\n",(0,s.jsx)(n.p,{children:'Each job needs a name that has to be unique within the whole tenant.\nA useful convention to achieve this is to prepend the name of the repository.\nEach job need to define whether there is parent job or not.\nJobs without a parent are called "base" jobs. Usually you don\'t want to implement base jobs since\nthere are already some base jobs that implement often used stuff. A description may not be mandatory\nbut is obviously useful.'}),"\n",(0,s.jsxs)(n.p,{children:["Necessary for Zuul to do anything you just need to add a ",(0,s.jsx)(n.code,{children:"run"})," or ",(0,s.jsx)(n.code,{children:"roles"})," property. Within a job that is\nlike a ",(0,s.jsx)(n.code,{children:"noop"})," job or just printing something to stdout that is everything you need to run your first job.\nSince anything we want to do requires a little bit more you have to define a nodeset. The nodes\nare used to run your playbooks on. In 99,9% you will need this too."]}),"\n",(0,s.jsxs)(n.p,{children:["The properties ",(0,s.jsx)(n.code,{children:"pre-run"})," and ",(0,s.jsx)(n.code,{children:"post-run"})," are useful for bootstrap and cleanup. If your actual job wants to create\nbootstrap some infrastructure you can to this in the ",(0,s.jsx)(n.code,{children:"pre-run"}),". Using an cloud provider you want to release\nno longer used resources. That can be done in the ",(0,s.jsx)(n.code,{children:"post-run"}),'. If you are using a parent job it is likely\nthat the parent job may has pre- and post-run playbooks. In this case your pre- and post-run playbooks are\n"nested". Example:']}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"pre-run parent"}),"\n",(0,s.jsx)(n.li,{children:"pre-run my job"}),"\n",(0,s.jsx)(n.li,{children:"post-run my job"}),"\n",(0,s.jsx)(n.li,{children:"post-run parent"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"If your job exceeds the defined timeout, the job is considered as failed."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/job.html",children:"See official documentation"})}),"\n",(0,s.jsx)(n.h4,{id:"what-about-secrets",children:"What about secrets?"}),"\n",(0,s.jsx)(n.p,{children:"Right now you should be able to run basic tasks. But what if you try to test something\nthat needs credentials to connect to an outside service? Or you have to address additional\nressources in an openstack environment and you have to use something like app credentials?"}),"\n",(0,s.jsx)(n.p,{children:"That is where job secrets are used. Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"- job:\n name: SOME_JOB\n parent: base\n description: |\n A job basic job used as example\n secrets:\n - name: clouds_conf\n secret: app_credential_cloud_conf\n run: playbooks/my-playbook.yaml\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Secrets for a job are simply defined by the keyword ",(0,s.jsx)(n.code,{children:"secrets"}),".\nEach secret needs a name that can be used in your playbooks.\nThe property ",(0,s.jsx)(n.code,{children:"secret"})," references the secret that is defined within your project."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"ATTENTION!"})," If your job is using a secret ",(0,s.jsx)(n.code,{children:"job.post-review"})," is automatically\nset to ",(0,s.jsx)(n.code,{children:"true"}),". For untrusted projects, that means that your job is only called\nin piplines that have the ",(0,s.jsx)(n.code,{children:"pipeline.post-review"})," flag set to ",(0,s.jsx)(n.code,{children:"true"}),". In SCS context\nthat means you may run these jobs only with the pipelines ",(0,s.jsx)(n.code,{children:"tag"})," and ",(0,s.jsx)(n.code,{children:"post"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["If you want to run jobs on pipelines that have ",(0,s.jsx)(n.code,{children:"post-review"})," set to ",(0,s.jsx)(n.code,{children:"false"}),", which\nis default, and your job needs a secret, the secret may be defined in the zuul-config repository."]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"- secret:\n name: app_credential_cloud_conf\n data:\n credentials: my-secret-value\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Within ",(0,s.jsx)(n.code,{children:"my-playbook.yaml"})," you can reference the secret value using ",(0,s.jsx)(n.code,{children:'"{{ clouds_conf.credentials }}"'}),".\nIn this example ",(0,s.jsx)(n.code,{children:"my-secret-value"})," is clear readable text. That is not something we want to keep\nsecrets. But how do you encrypt secrets in a way that they are secure and also can be decrypted by\nZuul?"]}),"\n",(0,s.jsx)(n.p,{children:"For this purpose Zuul creates its own public/private key pair for each project. Everyone may use the\npublic key to create secrets. But only Zuul will be able to decrypt these values. To avoid the user\nto be responsible for the correct encryption there is an zuul-client tool that will do this for you."}),"\n",(0,s.jsx)(n.p,{children:"Example (reading from stdin and writing to stdout):"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"zuul-client --zuul-url ZUUL_URL encrypt --tenant SCS --project SovereignCloudStack/REPO\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Add ",(0,s.jsx)(n.code,{children:"--infile INFILE"})," or ",(0,s.jsx)(n.code,{children:"--outfile OUTFILE"})," if you prefer to work with files directly."]}),"\n",(0,s.jsx)(n.p,{children:"The output might look like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"- secret:\n name: <name>\n data:\n <fieldname>: !encrypted/pkcs1-oaep\n - IGZ2Wu47R9mEY4fjetbxSAUGNaz4HR1mjk9lCLq3HsUMjHGj9YPlb2MvnPQw1LCJSvpaK\n ogth7hi2zYwrs5tNAik/qlVSB7AM+LQRP7lmlM4JmD6WOyR7DisHu7oMD1Gqem2ZuMggA\n DIBn5+DeBIvnwihDOcS+BKPTVMEtXOJNkuObZHE8DweB/RQIGUvjyeq5yoAmz/y+qGVqe\n 0Vk4pTYFIBgk5DMzwVnDzDkqs/QokoOupMUoBcpapmM11do4ymjbDpeINjayoro6VXTtX\n Mkk9fDv9wuJIQTuyHAOfMD+UYS/HqVSF/Hm9ScUvfhw02gTdzKCxliWhFHJOj7RbdUUMK\n OYYcUkNp5cXZUYFnflMhxVEnzREbdAIklNPfoHOizsxLPaUZ9yk6XcFRflFfMvqBtUS00\n LCx0Uh906NwdaEUrv2ZdrN123rwfwfw4333232rDFDFfsdfddsfdDFSFSdqrrtwms5Mi0\n szUBaM4j+Mayep+41vl0cpsLU91GzXEATWMaPIN8OnEHF6qQIv0wB6VaKd5aeAyERisb3\n wFdjEo4faLO70RWzR33k+4xqAYNIIFyTMpWJz21CUSfoYG8ygL6t7RJGgyjA+0KsVEyj+\n ewEtiaUOLYyD7pXtqdw1HgzjqiXnfxk+wSv/y5y/TGGYpQj8zU76jS7Zj0ft/0=\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You may use this content or the file to provide it as a secret. You just have to update the ",(0,s.jsx)(n.code,{children:"<name>"})," and the\n",(0,s.jsx)(n.code,{children:"<fieldname>"})," part."]}),"\n",(0,s.jsxs)(n.p,{children:["The secret name has to be unique across all projects. Because of this, we have a naming convention in the\n",(0,s.jsx)(n.code,{children:"SovereignCloudStack"})," organisation that ensures that a secret has a unique name."]}),"\n",(0,s.jsxs)(n.p,{children:["Our convention is as follows. There is only one secret per Zuul configuration per project (for exceptions,\nsee below). This secret always has a name in the form\n",(0,s.jsx)(n.code,{children:"SECRET_REPOSITORY_NAME"}),". For instance, if a secret in the ",(0,s.jsx)(n.code,{children:"SovereignCloudStack/k8s-cluster-api-provider"}),"\nrepository is\nto be used, it is given the name ",(0,s.jsx)(n.code,{children:"SECRET_K8S_CLUSTER_API_PROVIDER"}),". The name of the repository is\nalways written in capital letters. A dash is replaced with an underscore. Any number of values\n(",(0,s.jsx)(n.code,{children:"<fieldname>: !encrypted/pkcs1-oaep"}),") can then be assigned to this one secret."]}),"\n",(0,s.jsxs)(n.p,{children:["In certain cases, it can be undesireable to expose all secret information to all jobs in a project.\nThen additional secrets may be used, whose names have to be formed by appending an underscore and some\nupper-case prefix to the name of the primary secret. For instance, we might use the\nname ",(0,s.jsx)(n.code,{children:"SECRET_REPOSITORY_NAME_FOOBAR"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Official documentation:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/secret.html#secret",children:"Secrets documentation"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/project-config.html#encryption",children:"Encryption documentation"})}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"lets-put-it-all-together",children:"Let's put it all together"}),"\n",(0,s.jsxs)(n.p,{children:["For a basic but working example the following content may be written into a ",(0,s.jsx)(n.code,{children:"zuul.yaml"})," file."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'# zuul.yaml content\n---\n- secret:\n name: SECRET_REPOSITORY_NAME\n data:\n secretValue1: !encrypted/pkcs1-oaep\n - <ENCRYPTED_DATA>\n secretValue2: !encrypted/pkcs1-oaep\n - <ENCRYPTED_DATA>\n secretValue3: !encrypted/pkcs1-oaep\n - <ENCRYPTED_DATA>\n\n- job:\n name: myFirstTestJob\n parent: base\n secrets:\n - name: secretName # The name of the secret that is used within "playbooks/testPlaybook.yaml"\n secret: SECRET_REPOSITORY_NAME\n run: playbooks/testPlaybook.yaml\n\n- job:\n name: mySecondTestJob\n parent: base\n run: playbooks/testPlaybookTwo.yaml\n\n- project:\n tag:\n jobs:\n - myFirstTestJob\n check:\n jobs:\n - mySecondTestJob\n'})}),"\n",(0,s.jsxs)(n.p,{children:["This will run the job ",(0,s.jsx)(n.code,{children:"myFirstTestJob"})," whenever the ",(0,s.jsx)(n.code,{children:"tag"})," pipeline is triggered, and\n",(0,s.jsx)(n.code,{children:"mySecondTestJob"})," whenever ",(0,s.jsx)(n.code,{children:"check"})," is triggered."]}),"\n",(0,s.jsxs)(n.p,{children:["Within SCS the ",(0,s.jsx)(n.code,{children:"check"})," pipeline is always triggered if you open, change or reopen a pull request.\nThis pipeline can also be triggered manually if you write a comment on an already\nexisting pull request and place the string ",(0,s.jsx)(n.code,{children:"recheck"})," in it."]}),"\n",(0,s.jsxs)(n.p,{children:["Recall that the first test job cannot run on the same pipeline because it uses a secret.\nThe ",(0,s.jsx)(n.code,{children:"tag"})," pipeline is run whenever a new tag is created."]}),"\n",(0,s.jsx)(n.p,{children:"The path to you playbook is always the full path within the repository. The playbook\ncontains the tasks you actually want to run on all or a specific subset of nodes.\nExample playbook:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"# playbooks/testPlaybook.yaml content\n---\n- hosts: all\n tasks:\n - debug:\n msg: 'Debug print my secrets! {{ secretName.secretValue1 }}' # do not do this as it will expose your secrets\n"})})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>l});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/95163.5c1563b3.js b/assets/js/95163.5c1563b3.js new file mode 100644 index 0000000000..15619370ab --- /dev/null +++ b/assets/js/95163.5c1563b3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[95163],{95163:(t,e,a)=>{a.d(e,{diagram:()=>b});var i=a(27899),n=a(26312),d=a(21176),r=a(697),s=a(86079);a(74353),a(16750),a(42838);const o={},c=(t,e)=>{o[t]=e},g=(t,e)=>{const a=t.append("text").attr("x",2*(0,s.c)().state.padding).attr("y",(0,s.c)().state.textHeight+1.3*(0,s.c)().state.padding).attr("font-size",(0,s.c)().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),i=a.height,n=t.append("text").attr("x",(0,s.c)().state.padding).attr("y",i+.4*(0,s.c)().state.padding+(0,s.c)().state.dividerMargin+(0,s.c)().state.textHeight).attr("class","state-description");let d=!0,r=!0;e.descriptions.forEach((function(t){d||(!function(t,e,a){const i=t.append("tspan").attr("x",2*(0,s.c)().state.padding).text(e);a||i.attr("dy",(0,s.c)().state.textHeight)}(n,t,r),r=!1),d=!1}));const o=t.append("line").attr("x1",(0,s.c)().state.padding).attr("y1",(0,s.c)().state.padding+i+(0,s.c)().state.dividerMargin/2).attr("y2",(0,s.c)().state.padding+i+(0,s.c)().state.dividerMargin/2).attr("class","descr-divider"),c=n.node().getBBox(),g=Math.max(c.width,a.width);return o.attr("x2",g+3*(0,s.c)().state.padding),t.insert("rect",":first-child").attr("x",(0,s.c)().state.padding).attr("y",(0,s.c)().state.padding).attr("width",g+2*(0,s.c)().state.padding).attr("height",c.height+i+2*(0,s.c)().state.padding).attr("rx",(0,s.c)().state.radius),t},p=(t,e,a)=>{const i=(0,s.c)().state.padding,n=2*(0,s.c)().state.padding,d=t.node().getBBox(),r=d.width,o=d.x,c=t.append("text").attr("x",0).attr("y",(0,s.c)().state.titleShift).attr("font-size",(0,s.c)().state.fontSize).attr("class","state-title").text(e.id),g=c.node().getBBox().width+n;let p,h=Math.max(g,r);h===r&&(h+=n);const l=t.node().getBBox();e.doc,p=o-i,g>r&&(p=(r-h)/2+i),Math.abs(o-l.x)<i&&g>r&&(p=o-(g-r)/2);const x=1-(0,s.c)().state.textHeight;return t.insert("rect",":first-child").attr("x",p).attr("y",x).attr("class",a?"alt-composit":"composit").attr("width",h).attr("height",l.height+(0,s.c)().state.textHeight+(0,s.c)().state.titleShift+1).attr("rx","0"),c.attr("x",p+i),g<=r&&c.attr("x",o+(h-n)/2-g/2+i),t.insert("rect",":first-child").attr("x",p).attr("y",(0,s.c)().state.titleShift-(0,s.c)().state.textHeight-(0,s.c)().state.padding).attr("width",h).attr("height",3*(0,s.c)().state.textHeight).attr("rx",(0,s.c)().state.radius),t.insert("rect",":first-child").attr("x",p).attr("y",(0,s.c)().state.titleShift-(0,s.c)().state.textHeight-(0,s.c)().state.padding).attr("width",h).attr("height",l.height+3+2*(0,s.c)().state.textHeight).attr("rx",(0,s.c)().state.radius),t},h=(t,e)=>{e.attr("class","state-note");const a=e.append("rect").attr("x",0).attr("y",(0,s.c)().state.padding),i=e.append("g"),{textWidth:n,textHeight:d}=((t,e,a,i)=>{let n=0;const d=i.append("text");d.style("text-anchor","start"),d.attr("class","noteText");let r=t.replace(/\r\n/g,"<br/>");r=r.replace(/\n/g,"<br/>");const o=r.split(s.e.lineBreakRegex);let c=1.25*(0,s.c)().state.noteMargin;for(const g of o){const t=g.trim();if(t.length>0){const i=d.append("tspan");i.text(t),0===c&&(c+=i.node().getBBox().height),n+=c,i.attr("x",e+(0,s.c)().state.noteMargin),i.attr("y",a+n+1.25*(0,s.c)().state.noteMargin)}}return{textWidth:d.node().getBBox().width,textHeight:n}})(t,0,0,i);return a.attr("height",d+2*(0,s.c)().state.noteMargin),a.attr("width",n+2*(0,s.c)().state.noteMargin),a},l=function(t,e){const a=e.id,i={id:a,label:e.id,width:0,height:0},n=t.append("g").attr("id",a).attr("class","stateGroup");"start"===e.type&&(t=>{t.append("circle").attr("class","start-state").attr("r",(0,s.c)().state.sizeUnit).attr("cx",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit).attr("cy",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit)})(n),"end"===e.type&&(t=>{t.append("circle").attr("class","end-state-outer").attr("r",(0,s.c)().state.sizeUnit+(0,s.c)().state.miniPadding).attr("cx",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+(0,s.c)().state.miniPadding).attr("cy",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+(0,s.c)().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",(0,s.c)().state.sizeUnit).attr("cx",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+2).attr("cy",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+2)})(n),"fork"!==e.type&&"join"!==e.type||((t,e)=>{let a=(0,s.c)().state.forkWidth,i=(0,s.c)().state.forkHeight;if(e.parentId){let t=a;a=i,i=t}t.append("rect").style("stroke","black").style("fill","black").attr("width",a).attr("height",i).attr("x",(0,s.c)().state.padding).attr("y",(0,s.c)().state.padding)})(n,e),"note"===e.type&&h(e.note.text,n),"divider"===e.type&&(t=>{t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",(0,s.c)().state.textHeight).attr("class","divider").attr("x2",2*(0,s.c)().state.textHeight).attr("y1",0).attr("y2",0)})(n),"default"===e.type&&0===e.descriptions.length&&((t,e)=>{const a=t.append("text").attr("x",2*(0,s.c)().state.padding).attr("y",(0,s.c)().state.textHeight+2*(0,s.c)().state.padding).attr("font-size",(0,s.c)().state.fontSize).attr("class","state-title").text(e.id),i=a.node().getBBox();t.insert("rect",":first-child").attr("x",(0,s.c)().state.padding).attr("y",(0,s.c)().state.padding).attr("width",i.width+2*(0,s.c)().state.padding).attr("height",i.height+2*(0,s.c)().state.padding).attr("rx",(0,s.c)().state.radius)})(n,e),"default"===e.type&&e.descriptions.length>0&&g(n,e);const d=n.node().getBBox();return i.width=d.width+2*(0,s.c)().state.padding,i.height=d.height+2*(0,s.c)().state.padding,c(a,i),i};let x=0;let u;const f={},y=(t,e,a,o,c,g,h)=>{const w=new r.T({compound:!0,multigraph:!0});let b,B=!0;for(b=0;b<t.length;b++)if("relation"===t[b].stmt){B=!1;break}a?w.setGraph({rankdir:"LR",multigraph:!0,compound:!0,ranker:"tight-tree",ranksep:B?1:u.edgeLengthFactor,nodeSep:B?1:50,isMultiGraph:!0}):w.setGraph({rankdir:"TB",multigraph:!0,compound:!0,ranksep:B?1:u.edgeLengthFactor,nodeSep:B?1:50,ranker:"tight-tree",isMultiGraph:!0}),w.setDefaultEdgeLabel((function(){return{}})),h.db.extract(t);const m=h.db.getStates(),k=h.db.getRelations(),N=Object.keys(m);for(const i of N){const t=m[i];let n;if(a&&(t.parentId=a),t.doc){let a=e.append("g").attr("id",t.id).attr("class","stateGroup");n=y(t.doc,a,t.id,!o,c,g,h);{a=p(a,t,o);let e=a.node().getBBox();n.width=e.width,n.height=e.height+u.padding/2,f[t.id]={y:u.compositTitleSize}}}else n=l(e,t);if(t.note){const a={descriptions:[],id:t.id+"-note",note:t.note,type:"note"},i=l(e,a);"left of"===t.note.position?(w.setNode(n.id+"-note",i),w.setNode(n.id,n)):(w.setNode(n.id,n),w.setNode(n.id+"-note",i)),w.setParent(n.id,n.id+"-group"),w.setParent(n.id+"-note",n.id+"-group")}else w.setNode(n.id,n)}s.l.debug("Count=",w.nodeCount(),w);let E=0;k.forEach((function(t){var e;E++,s.l.debug("Setting edge",t),w.setEdge(t.id1,t.id2,{relation:t,width:(e=t.title,e?e.length*u.fontSizeFactor:1),height:u.labelHeight*s.e.getRows(t.title).length,labelpos:"c"},"id"+E)})),(0,d.Zp)(w),s.l.debug("Graph after layout",w.nodes());const v=e.node();w.nodes().forEach((function(t){if(void 0!==t&&void 0!==w.node(t)){s.l.warn("Node "+t+": "+JSON.stringify(w.node(t))),c.select("#"+v.id+" #"+t).attr("transform","translate("+(w.node(t).x-w.node(t).width/2)+","+(w.node(t).y+(f[t]?f[t].y:0)-w.node(t).height/2)+" )"),c.select("#"+v.id+" #"+t).attr("data-x-shift",w.node(t).x-w.node(t).width/2);g.querySelectorAll("#"+v.id+" #"+t+" .divider").forEach((t=>{const e=t.parentElement;let a=0,i=0;e&&(e.parentElement&&(a=e.parentElement.getBBox().width),i=parseInt(e.getAttribute("data-x-shift"),10),Number.isNaN(i)&&(i=0)),t.setAttribute("x1",0-i+8),t.setAttribute("x2",a-i-8)}))}else s.l.debug("No Node "+t+": "+JSON.stringify(w.node(t)))}));let M=v.getBBox();w.edges().forEach((function(t){void 0!==t&&void 0!==w.edge(t)&&(s.l.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(w.edge(t))),function(t,e,a){e.points=e.points.filter((t=>!Number.isNaN(t.y)));const d=e.points,r=(0,n.n8j)().x((function(t){return t.x})).y((function(t){return t.y})).curve(n.qrM),o=t.append("path").attr("d",r(d)).attr("id","edge"+x).attr("class","transition");let c="";if((0,s.c)().state.arrowMarkerAbsolute&&(c=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,c=c.replace(/\(/g,"\\("),c=c.replace(/\)/g,"\\)")),o.attr("marker-end","url("+c+"#"+function(t){switch(t){case i.d.relationType.AGGREGATION:return"aggregation";case i.d.relationType.EXTENSION:return"extension";case i.d.relationType.COMPOSITION:return"composition";case i.d.relationType.DEPENDENCY:return"dependency"}}(i.d.relationType.DEPENDENCY)+"End)"),void 0!==a.title){const i=t.append("g").attr("class","stateLabel"),{x:n,y:d}=s.u.calcLabelPosition(e.points),r=s.e.getRows(a.title);let o=0;const c=[];let g=0,p=0;for(let t=0;t<=r.length;t++){const e=i.append("text").attr("text-anchor","middle").text(r[t]).attr("x",n).attr("y",d+o),a=e.node().getBBox();if(g=Math.max(g,a.width),p=Math.min(p,a.x),s.l.info(a.x,n,d+o),0===o){const t=e.node().getBBox();o=t.height,s.l.info("Title height",o,d)}c.push(e)}let h=o*r.length;if(r.length>1){const t=(r.length-1)*o*.5;c.forEach(((e,a)=>e.attr("y",d+a*o-t))),h=o*r.length}const l=i.node().getBBox();i.insert("rect",":first-child").attr("class","box").attr("x",n-g/2-(0,s.c)().state.padding/2).attr("y",d-h/2-(0,s.c)().state.padding/2-3.5).attr("width",g+(0,s.c)().state.padding).attr("height",h+(0,s.c)().state.padding),s.l.info(l)}x++}(e,w.edge(t),w.edge(t).relation))})),M=v.getBBox();const S={id:a||"root",label:a||"root",width:0,height:0};return S.width=M.width+2*u.padding,S.height=M.height+2*u.padding,s.l.debug("Doc rendered",S,w),S},w={setConf:function(){},draw:function(t,e,a,i){u=(0,s.c)().state;const d=(0,s.c)().securityLevel;let r;"sandbox"===d&&(r=(0,n.Ltv)("#i"+e));const o="sandbox"===d?(0,n.Ltv)(r.nodes()[0].contentDocument.body):(0,n.Ltv)("body"),c="sandbox"===d?r.nodes()[0].contentDocument:document;s.l.debug("Rendering diagram "+t);const g=o.select(`[id='${e}']`);g.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z");const p=i.db.getRootDoc();y(p,g,void 0,!1,o,c,i);const h=u.padding,l=g.node().getBBox(),x=l.width+2*h,f=l.height+2*h,w=1.75*x;(0,s.i)(g,f,w,u.useMaxWidth),g.attr("viewBox",`${l.x-u.padding} ${l.y-u.padding} `+x+" "+f)}},b={parser:i.p,db:i.d,renderer:w,styles:i.s,init:t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute,i.d.clear()}}}}]); \ No newline at end of file diff --git a/assets/js/95800b3e.941f0ed8.js b/assets/js/95800b3e.941f0ed8.js new file mode 100644 index 0000000000..2e09ea58a2 --- /dev/null +++ b/assets/js/95800b3e.941f0ed8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[75515],{12675:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"iaas/guides/concept-guide/layers","title":"Layers in a cluster","description":"Compute Plane","source":"@site/docs/02-iaas/guides/concept-guide/layers.md","sourceDirName":"02-iaas/guides/concept-guide","slug":"/iaas/guides/concept-guide/layers","permalink":"/docs/iaas/guides/concept-guide/layers","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/layers.md","tags":[],"version":"current","sidebarPosition":20,"frontMatter":{"sidebar_label":"Layers in a cluster","sidebar_position":20},"sidebar":"docs","previous":{"title":"Teleport","permalink":"/docs/iaas/guides/concept-guide/components/teleport"},"next":{"title":"Nodes in a cluster","permalink":"/docs/iaas/guides/concept-guide/nodes"}}');var i=a(74848),s=a(28453);const o={sidebar_label:"Layers in a cluster",sidebar_position:20},l="Layers in a cluster",r={},c=[{value:"Compute Plane",id:"compute-plane",level:2},{value:"Control Plane",id:"control-plane",level:2},{value:"Data Plane",id:"data-plane",level:2},{value:"Management Plane",id:"management-plane",level:2},{value:"Monitoring Plane",id:"monitoring-plane",level:2},{value:"Network Plane",id:"network-plane",level:2}];function d(e){const n={h1:"h1",h2:"h2",header:"header",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"layers-in-a-cluster",children:"Layers in a cluster"})}),"\n",(0,i.jsx)(n.h2,{id:"compute-plane",children:"Compute Plane"}),"\n",(0,i.jsx)(n.h2,{id:"control-plane",children:"Control Plane"}),"\n",(0,i.jsx)(n.h2,{id:"data-plane",children:"Data Plane"}),"\n",(0,i.jsx)(n.h2,{id:"management-plane",children:"Management Plane"}),"\n",(0,i.jsx)(n.h2,{id:"monitoring-plane",children:"Monitoring Plane"}),"\n",(0,i.jsx)(n.h2,{id:"network-plane",children:"Network Plane"})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>o,x:()=>l});var t=a(96540);const i={},s=t.createContext(i);function o(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/964e3c50.7dea5c6a.js b/assets/js/964e3c50.7dea5c6a.js new file mode 100644 index 0000000000..f2b36f61a1 --- /dev/null +++ b/assets/js/964e3c50.7dea5c6a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[34870],{3693:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>n,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow","title":"Upgrade flow","description":"This flow assumes that you have an existing cluster that references a certain ClusterClass called docker-ferrol-1-27-v1.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/topics","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow.md","tags":[],"version":"current","frontMatter":{}}');var r=s(74848),c=s(28453);const n={},a="Upgrade flow",i={},l=[];function d(e){const t={code:"code",h1:"h1",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"upgrade-flow",children:"Upgrade flow"})}),"\n",(0,r.jsxs)(t.p,{children:["This flow assumes that you have an existing cluster that references a certain ",(0,r.jsx)(t.code,{children:"ClusterClass"})," called ",(0,r.jsx)(t.code,{children:"docker-ferrol-1-27-v1"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:['There are two forms of updates: "normal" cluster stack updates, where you would update the above ',(0,r.jsx)(t.code,{children:"ClusterClass"})," to ",(0,r.jsx)(t.code,{children:"docker-ferrol-1-27-v2"}),", and updates of the Kubernetes minor version, e.g. ",(0,r.jsx)(t.code,{children:"docker-ferrol-1-28-v1"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["In both cases, you need to make sure that you have the respective ",(0,r.jsx)(t.code,{children:"ClusterClass"})," available. This works a bit different in the two cases, as you will need a new ",(0,r.jsx)(t.code,{children:"ClusterStack"})," object in the latter case that works with Kubernetes minor version 1.28. This is one of the properties of a ",(0,r.jsx)(t.code,{children:"ClusterStack"})," that you specify in the spec."]}),"\n",(0,r.jsxs)(t.p,{children:["After you made sure that you have the ",(0,r.jsx)(t.code,{children:"ClusterClass"})," ready to which you want to upgrade, you can edit your ",(0,r.jsx)(t.code,{children:"Cluster"})," object according to the following pattern:"]}),"\n",(0,r.jsxs)(t.p,{children:["Update ",(0,r.jsx)(t.code,{children:"spec.topology.class"})," to the name of the new ",(0,r.jsx)(t.code,{children:"ClusterClass"})," and change ",(0,r.jsx)(t.code,{children:"spec.topology.version"}),' to the respective Kubernetes version. This can be, for example, "1.28.1". You have to find out the right Kubernetes version for the respective cluster stack.']}),"\n",(0,r.jsxs)(t.p,{children:["You can either do this by checking the status of the ",(0,r.jsx)(t.code,{children:"ClusterStack"})," object, or by fetching the ",(0,r.jsx)(t.code,{children:"ClusterStackRelease"})," objects. You will find a ",(0,r.jsx)(t.code,{children:"ClusterStackRelease"})," object that has the same name as your desired ",(0,r.jsx)(t.code,{children:"ClusterClass"}),". This object has a property ",(0,r.jsx)(t.code,{children:"status.kubernetesVersion"})," that shows you the version that you need to specify."]}),"\n",(0,r.jsx)(t.p,{children:"Another option is to check the documentation of the cluster stack to find information about the respective releases."}),"\n",(0,r.jsxs)(t.p,{children:["Please note that ",(0,r.jsx)(t.code,{children:"spec.topology.version"})," does not have to be specified if a mutating webhook fills the property automatically for you. Check out the latest release notes of the operator to verify whether that is implemented already."]})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>n,x:()=>a});var o=s(96540);const r={},c=o.createContext(r);function n(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:n(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/96f8fd49.9a2a8354.js b/assets/js/96f8fd49.9a2a8354.js new file mode 100644 index 0000000000..da1e708089 --- /dev/null +++ b/assets/js/96f8fd49.9a2a8354.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[10667],{31872:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>r,contentTitle:()=>i,default:()=>p,frontMatter:()=>l,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"iaas/guides/operations-guide/manager/log","title":"Logging","description":"Ansible","source":"@site/docs/02-iaas/guides/operations-guide/manager/log.md","sourceDirName":"02-iaas/guides/operations-guide/manager","slug":"/iaas/guides/operations-guide/manager/log","permalink":"/docs/iaas/guides/operations-guide/manager/log","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/manager/log.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Logging"},"sidebar":"docs","previous":{"title":"Get","permalink":"/docs/iaas/guides/operations-guide/manager/get"},"next":{"title":"Task","permalink":"/docs/iaas/guides/operations-guide/manager/task"}}');var t=o(74848),a=o(28453);const l={sidebar_label:"Logging"},i="Logging",r={},c=[{value:"Ansible",id:"ansible",level:2},{value:"Files",id:"files",level:3},{value:"ARA - ARA Records Ansible",id:"ara---ara-records-ansible",level:3},{value:"Sample usage",id:"sample-usage",level:4},{value:"Container",id:"container",level:2},{value:"OpenSearch",id:"opensearch",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"logging",children:"Logging"})}),"\n",(0,t.jsx)(n.h2,{id:"ansible",children:"Ansible"}),"\n",(0,t.jsx)(n.h3,{id:"files",children:"Files"}),"\n",(0,t.jsx)(n.p,{children:"Each Ansible service has its own local Ansible log file. These log files are not persistent. The ARA service is\nused for the persistence of Ansible logs. The log files can be used to view currently running Ansible Plays,\nfor example if they are running as a background task."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ docker exec -it osism-ansible tail -f /ansible/logs/ansible.log\n$ docker exec -it ceph-ansible tail -f /ansible/logs/ansible.log\n$ docker exec -it kolla-ansible tail -f /ansible/logs/ansible.log\n"})}),"\n",(0,t.jsx)(n.h3,{id:"ara---ara-records-ansible",children:"ARA - ARA Records Ansible"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ osism log ansible\n(ara) help\n\nDocumented commands (use 'help -v' for verbose/'help <topic>' for details):\n===========================================================================\nalias exit history quit run_script shell\nedit help macro run_pyscript set shortcuts\n\nApplication commands (type help <topic>):\n=========================================\ncomplete host metrics playbook delete record delete result show\nexpire host show playbook list record list task delete\nhelp play delete playbook metrics record show task list\nhost delete play list playbook prune result delete task metrics\nhost list play show playbook show result list task show\n"})}),"\n",(0,t.jsx)(n.h4,{id:"sample-usage",children:"Sample usage"}),"\n",(0,t.jsx)(n.p,{children:"As an example, the role common is run. Irrelevant parts of outputs have been removed."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ osism apply common\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ osism log ansible\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"(ara) play list\n+----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+\n| id | status | name | playbook | tasks | results | started | duration |\n+----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+\n| 69 | completed | Apply role common | 49 | 21 | 68 | 2023-09-30T10:14:01.731212Z | 00:00:38.238032 |\n+----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"(ara) play show 69\n+----------+------------------------------------------+\n| Field | Value |\n+----------+------------------------------------------+\n| id | 69 |\n| report | http://ara-server:8000/playbooks/49.html |\n| status | completed |\n| name | Apply role common |\n| playbook | (49) /ansible/kolla-common.yml |\n| started | 2023-09-30T10:14:01.731212Z |\n| ended | 2023-09-30T10:14:39.969244Z |\n| duration | 00:00:38.238032 |\n| items | {'tasks': 21, 'results': 68} |\n+----------+------------------------------------------+\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"(ara) task list\n+-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+\n| id | status | results | action | name | playbook | started | duration |\n+-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+\n| 910 | completed | 0 | meta | common : Flush handlers | 49 | 2023-09-30T10:14:37.126872Z | 00:00:02.552006 |\n| 909 | completed | 4 | file | common : Link kolla_logs volume to /var/log/kolla | 49 | 2023-09-30T10:14:35.502754Z | 00:00:01.039468 |\n| 908 | completed | 4 | kolla_docker | common : Creating log volume | 49 | 2023-09-30T10:14:34.134312Z | 00:00:01.076976 |\n| 907 | completed | 4 | kolla_docker | common : Check common containers | 49 | 2023-09-30T10:14:31.411916Z | 00:00:02.146165 |\n| 906 | completed | 4 | template | common : Copy rabbitmq erl_inetrc to kolla toolbox | 49 | 2023-09-30T10:14:29.500998Z | 00:00:01.327607 |\n| 905 | completed | 4 | template | common : Copy rabbitmq-env.conf to kolla toolbox | 49 | 2023-09-30T10:14:27.979869Z | 00:00:01.231630 |\n| 904 | completed | 4 | file | common : Ensuring config directories have correct owner and permission | 49 | 2023-09-30T10:14:26.422535Z | 00:00:01.263370 |\n| 903 | completed | 4 | template | common : Ensure RabbitMQ Erlang cookie exists | 49 | 2023-09-30T10:14:24.880329Z | 00:00:01.255475 |\n| 902 | completed | 4 | template | common : Copying over cron logrotate config file | 49 | 2023-09-30T10:14:23.199518Z | 00:00:01.392765 |\n| 901 | completed | 4 | template | common : Copying over td-agent.conf | 49 | 2023-09-30T10:14:21.085351Z | 00:00:01.826039 |\n| 900 | completed | 1 | find | common : Find custom fluentd output config files | 49 | 2023-09-30T10:14:19.859670Z | 00:00:00.939663 |\n| 899 | completed | 1 | find | common : Find custom fluentd format config files | 49 | 2023-09-30T10:14:18.711171Z | 00:00:00.858586 |\n| 898 | completed | 1 | find | common : Find custom fluentd filter config files | 49 | 2023-09-30T10:14:17.542234Z | 00:00:00.877270 |\n| 897 | completed | 1 | find | common : Find custom fluentd input config files | 49 | 2023-09-30T10:14:15.911699Z | 00:00:01.315217 |\n| 896 | completed | 4 | template | common : Copying over config.json files for services | 49 | 2023-09-30T10:14:13.588195Z | 00:00:02.031647 |\n| 895 | completed | 4 | copy | service-cert-copy : common | Copying over backend internal TLS key | 49 | 2023-09-30T10:14:12.216984Z | 00:00:01.074853 |\n| 894 | completed | 4 | copy | service-cert-copy : common | Copying over backend internal TLS certificate | 49 | 2023-09-30T10:14:10.895833Z | 00:00:01.022530 |\n| 893 | completed | 4 | copy | service-cert-copy : common | Copying over extra CA certificates | 49 | 2023-09-30T10:14:08.551850Z | 00:00:02.040932 |\n| 892 | completed | 4 | include_tasks | common : include_tasks | 49 | 2023-09-30T10:14:07.019883Z | 00:00:00.950605 |\n| 891 | completed | 4 | file | common : Ensuring config directories exist | 49 | 2023-09-30T10:14:04.801633Z | 00:00:01.926842 |\n| 890 | completed | 4 | include_tasks | common : include_tasks | 49 | 2023-09-30T10:14:03.054547Z | 00:00:01.166032 |\n+-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"(ara) task show 910\n+----------+------------------------------------------+\n| Field | Value |\n+----------+------------------------------------------+\n| id | 910 |\n| uuid | 0242ac1f-6510-3867-9eea-00000000004f |\n| report | http://ara-server:8000/playbooks/49.html |\n| name | common : Flush handlers |\n| action | meta |\n| status | completed |\n| path | /ansible/roles/common/tasks/deploy.yml |\n| lineno | 8 |\n| started | 2023-09-30T10:14:37.126872Z |\n| ended | 2023-09-30T10:14:39.678878Z |\n| duration | 00:00:02.552006 |\n| tags | ['common'] |\n| handler | False |\n+----------+------------------------------------------+\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"(ara) playbook list\n+----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+\n| id | status | controller | user | ansible_version | path | tasks | results | hosts | started | duration |\n+----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+\n| 49 | completed | kolla-ansible.manager_default | dragon | 2.14.10 | /ansible/kolla-common.yml | 21 | 68 | 5 | 2023-09-30T10:14:01.410334Z | 00:00:39.135309 |\n+----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"(ara) playbook metrics\n+---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+\n| aggregate | count | duration_total | duration_avg | tasks | results | hosts | completed | failed | running |\n+---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+\n| /ansible/kolla-common.yml | 2 | 0:02:53.934432 | 0:01:26.967216 | 46 | 152 | 10 | 2 | 0 | 0 |\n+---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"(ara) host list\n+-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+\n| id | name | playbook | changed | failed | ok | skipped | unreachable | updated |\n+-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+\n| 164 | testbed-node-2.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.543599Z |\n| 161 | testbed-manager.testbed.osism.xyz | 49 | 0 | 0 | 18 | 2 | 0 | 2023-09-30T10:14:40.283581Z |\n| 163 | testbed-node-1.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.280601Z |\n| 162 | testbed-node-0.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.279181Z |\n| 165 | kolla-ansible.manager_default | 49 | 0 | 0 | 0 | 0 | 0 | 2023-09-30T10:14:16.932135Z |\n+-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"(ara) host show 164\n+-------------+------------------------------------------+\n| Field | Value |\n+-------------+------------------------------------------+\n| id | 164 |\n| report | http://ara-server:8000/playbooks/49.html |\n| name | testbed-node-2.testbed.osism.xyz |\n| changed | 0 |\n| failed | 0 |\n| ok | 14 |\n| skipped | 2 |\n| unreachable | 0 |\n| updated | 2023-09-30T10:14:40.543599Z |\n+-------------+------------------------------------------+\n"})}),"\n",(0,t.jsx)(n.h2,{id:"container",children:"Container"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ osism log container testbed-node-0 horizon\n[...]\n++++ APACHE_LOCK_DIR=/var/lock/apache2\n++++ export APACHE_LOG_DIR=/var/log/apache2\n++++ APACHE_LOG_DIR=/var/log/apache2\n++++ export LANG=C\n++++ LANG=C\n++++ export LANG\n+++ install -d /var/run/apache2/\n+++ rm -rf '/var/run/apache2/*'\n+++ [[ ubuntu =~ centos|rocky ]]\n+ echo 'Running command: '\\''/usr/sbin/apache2 -DFOREGROUND'\\'''\n+ exec /usr/sbin/apache2 -DFOREGROUND\nAH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.16.10. Set the 'ServerName' directive globally to suppress this message\n"})}),"\n",(0,t.jsx)(n.h2,{id:"opensearch",children:"OpenSearch"}),"\n",(0,t.jsxs)(n.p,{children:["OpenSearch can be queried with ",(0,t.jsx)(n.a,{href:"https://opensearch.org/docs/latest/search-plugins/sql/sql/index/",children:"SQL"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ osism log opensearch\n>>> SELECT * FROM flog-2023.10.31 LIMIT 1;\nOct 31 10:45:36 testbed-node-0 docker[847573]: cluster 2023-10-31T10:45:35.498718+0000 mgr.testbed-node-0 (mgr.5184) 24194 : cluster [DBG] pgmap v24196: 321 pgs: 321 active+clean; 577 KiB data, 270 MiB used, 60 GiB / 60 GiB avail\n\n>>> SELECT * FROM flog-2023.10.31 LIMIT 5;\nOct 31 11:19:57 testbed-node-2 docker[880827]: 2023-10-31T11:19:57.650+0000 7fa7e7c88700 0 [dashboard INFO root] Redirecting to active 'http://192.168.16.10:7000/'\nOct 31 11:19:57 testbed-node-2 docker[880827]: 2023-10-31T11:19:57.650+0000 7fa7e7c88700 0 [dashboard INFO request] [::ffff:192.168.16.11:56210] [OPTIONS] [302] [0.001s] [105.0B] [8a69cc7a-23db-410b-b744-cc5689cb4f4c] /\nOct 31 11:19:58 testbed-node-2 docker[844686]: cluster 2023-10-31T11:19:56.329684+0000 mgr.testbed-node-0 (mgr.5184) 25224 : cluster [DBG] pgmap v25226: 321 pgs: 321 active+clean; 577 KiB data, 270 MiB used, 60 GiB / 60 GiB avail\nOct 31 11:19:58 testbed-node-2 docker[844686]: debug 2023-10-31T11:19:58.566+0000 7fdbc9728700 1 mon.testbed-node-2@2(peon).osd e74 _set_new_cache_sizes cache_size:1020054731 inc_alloc: 348127232 full_alloc: 348127232 kv_alloc: 322961408\nOct 31 11:19:58 testbed-node-2 docker[880827]: 2023-10-31T11:19:58.710+0000 7fa7eb48f700 0 [dashboard INFO root] Redirecting to active 'http://192.168.16.10:7000/'\n\n>>> SELECT * FROM flog-2023.10.31 WHERE Hostname = 'testbed-node-0' LIMIT 5\nPATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29\nREQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27\nSCRIPT_NAME: `` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:28\n192.168.16.10 - - [31/Oct/2023 10:57:33] \"GET / HTTP/1.1\" 300 1761 0.001253\n(1039) accepted ('192.168.16.10', 58732) server /var/lib/kolla/venv/lib/python3.10/site-packages/eventlet/wsgi.py:1004\n\n>>> SELECT * FROM flog-2023.10.31 WHERE Hostname = 'testbed-node-0' AND programname = 'keystone' LIMIT 5\nPATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29\nREQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27\nSCRIPT_NAME: `` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:28\nPATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29\nREQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27\n"})})]})}function p(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>l,x:()=>i});var s=o(96540);const t={},a=s.createContext(t);function l(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9782cb54.f1211dbe.js b/assets/js/9782cb54.f1211dbe.js new file mode 100644 index 0000000000..e7173fb4cf --- /dev/null +++ b/assets/js/9782cb54.f1211dbe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9285],{33685:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"scs-0124-v1-security-of-iaas-service-software","title":"Standard for the security of IaaS service software","description":"Introduction","source":"@site/standards/scs-0124-v1-security-of-iaas-service-software.md","sourceDirName":".","slug":"/scs-0124-v1-security-of-iaas-service-software","permalink":"/standards/scs-0124-v1-security-of-iaas-service-software","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Standard for the security of IaaS service software","type":"Standard","status":"Draft","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0124: Standard for the security of IaaS service software","permalink":"/standards/iaas/scs-0124"},"next":{"title":"W1","permalink":"/standards/scs-0124-w1-security-of-iaas-service-software"}}');var n=s(74848),i=s(28453);const r={title:"Standard for the security of IaaS service software",type:"Standard",status:"Draft",track:"IaaS"},o=void 0,d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Only Allow the current versions of Software",id:"only-allow-the-current-versions-of-software",level:4},{value:"Allow only maintained versions of Software",id:"allow-only-maintained-versions-of-software",level:4},{value:"Standards implicitly define the minimum versions of Software",id:"standards-implicitly-define-the-minimum-versions-of-software",level:4},{value:"Advise CSPs to integrate software updates",id:"advise-csps-to-integrate-software-updates",level:4},{value:"Dependencies of the IaaS Layer Software",id:"dependencies-of-the-iaas-layer-software",level:4},{value:"What timeframe is needed to fix the issue?",id:"what-timeframe-is-needed-to-fix-the-issue",level:4},{value:"Standard for a minimum IaaS Layer Software version",id:"standard-for-a-minimum-iaas-layer-software-version",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",section:"section",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsx)(t.p,{children:"Software security relies on bug patches and security updates being available for specific versions of the software.\nThe services, which build the IaaS Layer should be updated on a regular basis based on updates provided by their respective authors or distributors.\nBut older releases or versions of the software of these services may not receive updates anymore.\nUnpatched versions should not be used in deployments as they are a security risk, so this standard will define how CSPs should deal with software versions and security updates."}),"\n",(0,n.jsx)(t.h2,{id:"terminology",children:"Terminology"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Term"}),(0,n.jsx)(t.th,{children:"Explanation"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"CSP"}),(0,n.jsx)(t.td,{children:"Cloud Service Provider, provider managing the OpenStack infrastructure."})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"SLURP"}),(0,n.jsx)(t.td,{children:"Skip Level Upgrade Release Process - A Process that allows upgrades between two releases, while skipping the one in between them."})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"OSSN"}),(0,n.jsxs)(t.td,{children:[(0,n.jsx)(t.a,{href:"https://wiki.openstack.org/wiki/Security_Notes",children:"OpenStack Security Note"})," - security issues from 3rd parties or due to misconfigurations."]})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"OSSA"}),(0,n.jsxs)(t.td,{children:[(0,n.jsx)(t.a,{href:"https://security.openstack.org/ossalist.html",children:"OpenStack Security Advisories"})," - security issues and advices for OpenStack."]})]})]})]}),"\n",(0,n.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,n.jsx)(t.p,{children:"On the IaaS Layer the software, that needs to be considered in the scope of this standard, is mainly the APIs of IaaS Services.\nAlso there might be shared libraries and other dependencies, that could be considered part of the IaaS Layer.\nIn software projects like e.g. OpenStack that provide the main services and all APIs, the software will be modified and receive bug fixes continuously and will receive releases of new versions on a regular basis.\nOlder releases will at some point not receive updates anymore, because maintaining more and more releases simultaneously requires too much manpower.\nThus older versions will also eventually not receive security updates anymore.\nUsing versions which do not receive updates anymore threatens the baseline security of deployments and should be avoided under all circumstances."}),"\n",(0,n.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,n.jsx)(t.p,{children:"It would be possible to define a minimum version of IaaS Layer software to avoid security risks.\nIn the following paragraphs several options of defining a minimum version or dealing with security patches otherwise are discussed."}),"\n",(0,n.jsx)(t.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,n.jsx)(t.h4,{id:"only-allow-the-current-versions-of-software",children:"Only Allow the current versions of Software"}),"\n",(0,n.jsx)(t.p,{children:"Considering that OpenStack as one provider of IaaS Layer Software has two releases per year, with one SLURP release per year, this option would require CSPs to update their deployment once or twice a year.\nUpdating a whole deployment is a lot of work and requires also good life-cycle management.\nFollowing only the SLURP releases would reduce this work to once per year."}),"\n",(0,n.jsx)(t.p,{children:"While following new releases closely already provides a deployment with recent bug fixes and new features, it also makes developing standards easier.\nDifferences between releases will accumulate eventually and may render older releases non-compliant to the SCS standards at some point."}),"\n",(0,n.jsxs)(t.p,{children:["On the other hand on the IaaS Level there aren't many breaking changes introduced by releases and also most standards will also work with older releases.\nSecurity updates and bug fixes are also provided by OpenStack for a few older releases with the state ",(0,n.jsx)(t.code,{children:"maintained"})," according to the OpenStack releases overview",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),".\nAdditionally the ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/release-notes/blob/main/Release7.md",children:"SCS reference implementation"})," is integrating OpenStack releases after half a year - so about the time when a new release is published by OpenStack.\nConsidering a CSP that wants to use only SLURP releases and waits for the reference implementation to adopt them, will already lag over a year (i.e. 2 OpenStack releases) behind the latest release, this cannot be considered as using the current version of IaaS Layer Software.\nThus this option can be discarded."]}),"\n",(0,n.jsx)(t.h4,{id:"allow-only-maintained-versions-of-software",children:"Allow only maintained versions of Software"}),"\n",(0,n.jsxs)(t.p,{children:["While following closely to the newest releases could be advised, there are several downsides to requiring this workflow, even if it would be only for SLURP releases.\nFollowing the SCS reference implementation for example would also lead into being a little bit behind the newest OpenStack release.\nBut this is not as bad as it may seem to be, because security related fixes and bug fixes are backported to older but still ",(0,n.jsx)(t.code,{children:"maintained"})," releases.\nAll releases that are still maintained can be looked up at the releases page from OpenStack",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-2",id:"user-content-fnref-2-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"."]}),"\n",(0,n.jsx)(t.p,{children:"Allowing maintained versions would give CSPs a little bit more time to update and test their environments, while still receiving relevant security updates and bug fixes.\nAlso CSPs that want to become SCS-compliant will not have to take on the burden to upgrade their deployments to very recent releases immediately, but can instead test with an existing release before an upgrade and identify where they need to put in additional work to become SCS-compliant."}),"\n",(0,n.jsx)(t.p,{children:"One problem is, that there might be new features implemented in the newest versions of the software, which are desired by other SCS standards to be SCS-compliant.\nIn that case allowing all maintained versions would lead to a two-year timespan customers would need to wait for before such a feature becomes available in all SCS-compliant deployments.\nIn case of security relevant features this is not advisable."}),"\n",(0,n.jsx)(t.h4,{id:"standards-implicitly-define-the-minimum-versions-of-software",children:"Standards implicitly define the minimum versions of Software"}),"\n",(0,n.jsx)(t.p,{children:"Instead of requiring a defined minimum software version centrally, it could be derived from the individual standards.\nBecause: Whenever there is a new wanted behavior a standard should be created and a resonable timeframe given to CSPs to adopt a software version that can fulfill the new standard.\nThrough the combination of all standards that are in place, the minimum version for the IaaS service software is implicitly given."}),"\n",(0,n.jsx)(t.p,{children:"This would avoid to have conflicting versions of software in terms of feature parity, while also allowing older software.\nUsing this approach requires an additional advise to CSPs to update or implement patches for security issues."}),"\n",(0,n.jsx)(t.h4,{id:"advise-csps-to-integrate-software-updates",children:"Advise CSPs to integrate software updates"}),"\n",(0,n.jsx)(t.p,{children:"As long as maintained versions of software are used, updates with security patches are available and only need to be integrated.\nThis can and should be done in a reasonable short timeframe."}),"\n",(0,n.jsx)(t.p,{children:"But CSPs may even use releases of IaaS software, that are either not maintained anymore by an open source community or may be even closed source implementations of the mandatory IaaS APIs.\nAllowing older versions or closed source software would only be acceptable, when CSPs assure (e.g. in documentation), that they themself will patch the software within their deployments.\nSecurity bug fixes must be implemented and proof of the fix then provided.\nOnly under these circumstances deployments with older or alternative IaaS Layer software may be handled as compliant."}),"\n",(0,n.jsx)(t.p,{children:"This option could be taken for granted, but to actually advise using it may encourage CSPs to take a closer look on their life-cycle management and security risk handling.\nAnd CSPs using OpenStack could even be encouraged to upgrade their deployments."}),"\n",(0,n.jsx)(t.h4,{id:"dependencies-of-the-iaas-layer-software",children:"Dependencies of the IaaS Layer Software"}),"\n",(0,n.jsx)(t.p,{children:"While the IaaS service software like OpenStack itself is monitored and security issues announced in OSSNs and OSSAs, these services have lots of dependecies, that are not monitored by the same entity.\nWhen dependencies have security issues, there might be no OSSN or OSSA, so CSPs also need to watch CVEs concerning these dependencies themselves.\nThose dependencies must also be updated in a reasonable timeframe, when a security issue is disclosed."}),"\n",(0,n.jsx)(t.h4,{id:"what-timeframe-is-needed-to-fix-the-issue",children:"What timeframe is needed to fix the issue?"}),"\n",(0,n.jsx)(t.p,{children:"CSPs should be encouraged to fix security issues as fast as possible.\nSome security issues are very easy to exploit so as soon as the vulnerability is disclosed attacks on deployments will start.\nOther vulnerabilities may need much knowledge and more time to be exploited.\nAlso the impact of different vulnerabilities will differ."}),"\n",(0,n.jsxs)(t.p,{children:["So it can be concluded that some security issues need to be fixed immediately while for others it is okay to take some time.\nThe BSI already has some guidance",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," on how fast CSPs should respond.\nFrom the moment a vulnerability is disclosed these are the advised reaction times ranked by the severity of the vulnerability:"]}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"Critical (CVSS = 9.0 \u2013 10.0): 3 hours"}),"\n",(0,n.jsx)(t.li,{children:"High (CVSS = 7.0 \u2013 8.9): 3 days"}),"\n",(0,n.jsx)(t.li,{children:"Mid (CVSS = 4.0 \u2013 6.9): 1 month"}),"\n",(0,n.jsx)(t.li,{children:"Low (CVSS = 0.1 \u2013 3.9): 3 months"}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:'This standard will follow this guidance and refer to these timeframes as "reasonable timeframes".'}),"\n",(0,n.jsx)(t.h2,{id:"standard-for-a-minimum-iaas-layer-software-version",children:"Standard for a minimum IaaS Layer Software version"}),"\n",(0,n.jsxs)(t.p,{children:["If a deployment is affected by a security issue and a maintained",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-2",id:"user-content-fnref-2-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})," version of OpenStack is used as implementation for IaaS Layer software, security patches noted in OSSNs and OSSAs MUST be integrated within a reasonable timeframe according to the severity of the security issue",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),".\nOtherwise the CSP MUST implement security bug fixes themself within a reasonable timeframe, when the deplyoment is affected by a security issue according to the severity of the security issue",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),"."]}),"\n",(0,n.jsx)(t.p,{children:"In both cases a notice of the update MUST be send to the OSBA, so that the compliance will not be revoked."}),"\n",(0,n.jsxs)(t.p,{children:["If a deployment uses a dependency of the IaaS service software which is affected by a security issue, this software also MUST be updated with security patches within a reasonable timeframe",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),"."]}),"\n",(0,n.jsx)(t.p,{children:"An open SBOM list MAY be used to propagate the current version of the software and may be used as proof of updates."}),"\n",(0,n.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,n.jsx)(t.p,{children:"In case of provided SBOMs the version numbers of the software could be checked.\nBut this is not a requirement, so there cannot be such a test.\nTests on the integration of security patches itself are difficult.\nAnd even if tests for certain security issues are possible, then those might be interpreted as an attack.\nThis is the reason there will be no conformance test."}),"\n",(0,n.jsx)(t.p,{children:"Rather the standard requires that CSPs provide notice of the fixed vulnerabilites themselves."}),"\n","\n",(0,n.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,n.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{id:"user-content-fn-2",children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://releases.openstack.org",children:"OpenStack versions and their current status"})," ",(0,n.jsx)(t.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-2-2","data-footnote-backref":"","aria-label":"Back to reference 1-2",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"2"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-2-3","data-footnote-backref":"","aria-label":"Back to reference 1-3",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"3"})]})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/CloudComputing/ComplianceControlsCatalogue/2020/C5_2020.pdf?__blob=publicationFile&v=3",children:"C5 criteria catalog with timeframes for responses on page 70."})," ",(0,n.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-1-2","data-footnote-backref":"","aria-label":"Back to reference 2-2",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"2"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-1-3","data-footnote-backref":"","aria-label":"Back to reference 2-3",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"3"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-1-4","data-footnote-backref":"","aria-label":"Back to reference 2-4",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"4"})]})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>o});var a=s(96540);const n={},i=a.createContext(n);function r(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/97b1504a.e20afa14.js b/assets/js/97b1504a.e20afa14.js new file mode 100644 index 0000000000..9d49647ab1 --- /dev/null +++ b/assets/js/97b1504a.e20afa14.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[94346],{55139:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"iaas/scs-0104","title":"scs-0104: SCS Standard Images","description":"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,","source":"@site/standards/iaas/scs-0104.md","sourceDirName":"iaas","slug":"/iaas/scs-0104","permalink":"/standards/iaas/scs-0104","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0103-v1-standard-flavors"},"next":{"title":"V1","permalink":"/standards/scs-0104-v1-standard-images"}}');var a=t(74848),d=t(28453);const r={},i="scs-0104: SCS Standard Images",c={},l=[{value:"Supplement: Implementation Notes",id:"supplement-implementation-notes",level:2}];function o(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(s.header,{children:(0,a.jsx)(s.h1,{id:"scs-0104-scs-standard-images",children:"scs-0104: SCS Standard Images"})}),"\n",(0,a.jsx)(s.p,{children:"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,\nspecifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined\ndeployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard's\nmachine-readable document facilitates automated processing for compliance and integration purposes, promoting\nconsistency and reliability in cloud environments."}),"\n",(0,a.jsxs)(s.table,{children:[(0,a.jsx)(s.thead,{children:(0,a.jsxs)(s.tr,{children:[(0,a.jsx)(s.th,{children:"Version"}),(0,a.jsx)(s.th,{children:"Type"}),(0,a.jsx)(s.th,{children:"State"}),(0,a.jsx)(s.th,{children:"stabilized"}),(0,a.jsx)(s.th,{children:"deprecated"})]})}),(0,a.jsx)(s.tbody,{children:(0,a.jsxs)(s.tr,{children:[(0,a.jsx)(s.td,{children:(0,a.jsx)(s.a,{href:"/standards/scs-0104-v1-standard-images",children:"scs-0104-v1"})}),(0,a.jsx)(s.td,{children:"Procedural"}),(0,a.jsx)(s.td,{children:"Stable"}),(0,a.jsx)(s.td,{children:"2024-02-21"}),(0,a.jsx)(s.td,{children:"-"})]})})]}),"\n",(0,a.jsx)(s.h2,{id:"supplement-implementation-notes",children:"Supplement: Implementation Notes"}),"\n",(0,a.jsxs)(s.table,{children:[(0,a.jsx)(s.thead,{children:(0,a.jsxs)(s.tr,{children:[(0,a.jsx)(s.th,{children:"Version"}),(0,a.jsx)(s.th,{children:"State"}),(0,a.jsx)(s.th,{children:"stabilized"}),(0,a.jsx)(s.th,{children:"deprecated"})]})}),(0,a.jsx)(s.tbody,{children:(0,a.jsxs)(s.tr,{children:[(0,a.jsx)(s.td,{children:(0,a.jsx)(s.a,{href:"/standards/scs-0104-w1-standard-images-implementation",children:"w1"})}),(0,a.jsx)(s.td,{children:"Draft"}),(0,a.jsx)(s.td,{children:"-"}),(0,a.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,d.R)(),...e.components};return s?(0,a.jsx)(s,{...e,children:(0,a.jsx)(o,{...e})}):o(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>i});var n=t(96540);const a={},d=n.createContext(a);function r(e){const s=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),n.createElement(d.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/97ef9758.3e3e3ab4.js b/assets/js/97ef9758.3e3e3ab4.js new file mode 100644 index 0000000000..4f41c1660b --- /dev/null +++ b/assets/js/97ef9758.3e3e3ab4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[26529],{73338:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"collaboration/team-iaas","title":"Team Iaas","description":"We build the reference implementation of the IaaS parts of SCS that informs and adheres to the SCS IaaS standards.","source":"@site/community/collaboration/team-iaas.md","sourceDirName":"collaboration","slug":"/collaboration/team-iaas","permalink":"/community/collaboration/team-iaas","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Collaboration","permalink":"/community/collaboration/"},"next":{"title":"Team IAM","permalink":"/community/collaboration/team-iam"}}');var o=a(74848),r=a(28453);const s={},i="Team Iaas",c={},l=[];function m(e){const t={h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"team-iaas",children:"Team Iaas"})}),"\n",(0,o.jsx)(t.p,{children:"We build the reference implementation of the IaaS parts of SCS that informs and adheres to the SCS IaaS standards."})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(m,{...e})}):m(e)}},28453:(e,t,a)=>{a.d(t,{R:()=>s,x:()=>i});var n=a(96540);const o={},r=n.createContext(o);function s(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9890ac63.1a13b384.js b/assets/js/9890ac63.1a13b384.js new file mode 100644 index 0000000000..d5de0f29a6 --- /dev/null +++ b/assets/js/9890ac63.1a13b384.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[41298],{18564:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"global/scs-0004","title":"scs-0004: Regulations for achieving SCS-compatible certification","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/global/scs-0004.md","sourceDirName":"global","slug":"/global/scs-0004","permalink":"/standards/global/scs-0004","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml"},"next":{"title":"V1","permalink":"/standards/scs-0004-v1-achieving-certification"}}');var r=s(74848),i=s(28453);const c={},a="scs-0004: Regulations for achieving SCS-compatible certification",d={},o=[];function l(e){const t={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0004-regulations-for-achieving-scs-compatible-certification",children:"scs-0004: Regulations for achieving SCS-compatible certification"})}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0004-v1-achieving-certification",children:"scs-0004-v1"})}),(0,r.jsx)(t.td,{children:"Procedural"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>a});var n=s(96540);const r={},i=n.createContext(r);function c(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9975996a.a094cb45.js b/assets/js/9975996a.a094cb45.js new file mode 100644 index 0000000000..6fffb2c0af --- /dev/null +++ b/assets/js/9975996a.a094cb45.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[78532],{51019:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing","title":"releasing","description":"Release Process","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/develop","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing.md","tags":[],"version":"current","frontMatter":{}}');var o=s(74848),r=s(28453);const a={},c=void 0,i={},l=[{value:"Release Process",id:"release-process",level:2},{value:"Step 1: Create and Push a tag",id:"step-1-create-and-push-a-tag",level:3},{value:"Step 2: Release in GitHub",id:"step-2-release-in-github",level:3}];function h(e){const t={a:"a",blockquote:"blockquote",br:"br",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h2,{id:"release-process",children:"Release Process"}),"\n",(0,o.jsxs)(t.p,{children:["This document describes the release process of cluster-stack-operator.\nThe release process is done using GitHub actions. The release workflow triggers when a tag is pushed starting with ",(0,o.jsx)(t.code,{children:"v*"})]}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsxs)(t.p,{children:["[!NOTE]\nBefore the release, please make sure that you've already updated metadata.yaml at the root of the repo. So, if you're using v1.2.0 then you'll also need to update the ",(0,o.jsx)(t.code,{children:"releaseSeries"})," block in metadata.yaml. The tag used for releasing should be compatible with what we have defined in metadata.yaml"]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"Creating a new release of cluster-stack-operator covers the following steps:"}),"\n",(0,o.jsx)(t.h3,{id:"step-1-create-and-push-a-tag",children:"Step 1: Create and Push a tag"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsx)(t.li,{children:"Create an annotated tag"}),"\n"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"git switch main\ngit pull --rebase \n# check older releases for semver compatibility\nexport RELEASE_TAG=<the tag of the release to be cut> (e.g. v0.0.1)\ngit tag -a ${RELEASE_TAG} -m ${RELEASE_TAG}\n"})}),"\n",(0,o.jsxs)(t.ol,{start:"2",children:["\n",(0,o.jsx)(t.li,{children:"Push the tag to GitHub repository"}),"\n"]}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsxs)(t.p,{children:["[!NOTE]",(0,o.jsx)(t.br,{}),"\n",(0,o.jsx)(t.code,{children:"origin"})," should be the name of the remote pointing to ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator",children:"https://github.com/SovereignCloudStack/cluster-stack-operator"})," and you should have permission to push tags to the repository."]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"Once you confirm that origin is correct then push the tag by invoking the following command:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"git push origin ${RELEASE_TAG}\n"})}),"\n",(0,o.jsx)(t.p,{children:"This will automatically trigger a Github workflow to create a draft release in GitHub."}),"\n",(0,o.jsx)(t.h3,{id:"step-2-release-in-github",children:"Step 2: Release in GitHub"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsx)(t.li,{children:"Review the draft release manually and check if the image tags are correct in the released manifest."}),"\n",(0,o.jsx)(t.li,{children:"After this, if you're going to cut a pre-release version then please append this line to the top of the release notes."}),"\n"]}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsxs)(t.p,{children:["[!WARNING]\n","\ud83d\udea8"," This is a RELEASE CANDIDATE. If you find any bugs, please file an ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/issues/new",children:"issue"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.ol,{start:"3",children:["\n",(0,o.jsxs)(t.li,{children:["Before publishing the images make sure that images are already there in GitHub container registry. This can be checked in the ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/pkgs/container/cso",children:"packages section"})," of the organisation."]}),"\n",(0,o.jsx)(t.li,{children:"Publish the release."}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>c});var n=s(96540);const o={},r=n.createContext(o);function a(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9a7c0197.c49ff924.js b/assets/js/9a7c0197.c49ff924.js new file mode 100644 index 0000000000..bb133b466d --- /dev/null +++ b/assets/js/9a7c0197.c49ff924.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[93402],{36857:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"operations/iam/identity-federation-in-scs","title":"Identity Federation in SCS","description":"SovereignCloudStack wants to make it possible for operators to delegate","source":"@site/contributor-docs/operations/iam/identity-federation-in-scs.md","sourceDirName":"operations/iam","slug":"/operations/iam/identity-federation-in-scs","permalink":"/contributor-docs/operations/iam/identity-federation-in-scs","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Identity Federation in SCS","type":null,"status":"Draft","track":"Global"},"sidebar":"devDocs","previous":{"title":"Documentation for SCS Contributors","permalink":"/contributor-docs/"},"next":{"title":"OpenStack Federation via OpenID-Connect","permalink":"/contributor-docs/operations/iam/openstack-federation-via-oidc"}}');var i=n(74848),s=n(28453);const a={title:"Identity Federation in SCS",type:null,status:"Draft",track:"Global"},r=void 0,c={},d=[{value:"1. IaaS / OpenStack",id:"1-iaas--openstack",level:2},{value:"2. CaaS",id:"2-caas",level:2}];function l(e){const t={a:"a",h2:"h2",p:"p",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.p,{children:"SovereignCloudStack wants to make it possible for operators to delegate\nadministration of user identities to the organizational entities that the\nusers are part of. Usually that's customer organizations but it could also\nbe the operator itself. Federation protocols like OpenID Connect can be used\nto achieve that goal. To simplify connecting the different parts of SCS\nto customer owned IAM solutions, SCS deploys Keycloak as central Identity\nProvider (IdP) service."}),"\n",(0,i.jsxs)(t.p,{children:["Currently this is deployed automatically only in the ",(0,i.jsx)(t.a,{href:"https://docs.scs.community/docs/iaas/guides/deploy-guide/examples/testbed/",children:"osism/testbed"}),",\nwhich provides ",(0,i.jsx)(t.a,{href:"https://docs.scs.community/docs/iaas/guides/deploy-guide/examples/testbed#authentication-with-oidc",children:"its own documentation for authentication with OIDC"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"The following sections describe how this is done."}),"\n",(0,i.jsx)(t.h2,{id:"1-iaas--openstack",children:"1. IaaS / OpenStack"}),"\n",(0,i.jsxs)(t.p,{children:["To provide Infrastrucure as a Service SCS builds upon\nOpenStack. See section ",(0,i.jsx)(t.a,{href:"https://docs.scs.community/dev-docs/operations/iam/openstack-federation-via-oidc",children:"OpenStack Federation via OpenID-Connect"}),"\nfor more details on identity federation for OpenStack."]}),"\n",(0,i.jsx)(t.h2,{id:"2-caas",children:"2. CaaS"}),"\n",(0,i.jsxs)(t.p,{children:["To provide Container as a Service SCS builds upon\nKubernetes. There is\n",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/issues/issues/373",children:"work in progress"}),"\nto optionally connect Kubernetes to Keycloak and to\nmap authorization decisions based on claims via cluster role bindings."]})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var o=n(96540);const i={},s=o.createContext(i);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9b12e85c.7cfd4145.js b/assets/js/9b12e85c.7cfd4145.js new file mode 100644 index 0000000000..92a4401a93 --- /dev/null +++ b/assets/js/9b12e85c.7cfd4145.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[38040],{86728:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>p});const o=JSON.parse('{"id":"operating-scs/components/status-page-web/docs/quickstart","title":"Quickstart","description":"To quickly start hosting the status page frontend, refer to the Quickstart guide of the status-page-deployment repository.","source":"@site/docs/04-operating-scs/components/status-page-web/docs/quickstart.md","sourceDirName":"04-operating-scs/components/status-page-web/docs","slug":"/operating-scs/components/status-page-web/docs/quickstart","permalink":"/docs/operating-scs/components/status-page-web/docs/quickstart","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-web/docs/quickstart.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Requirements","permalink":"/docs/operating-scs/components/status-page-web/docs/requirements"},"next":{"title":"Configuration","permalink":"/docs/operating-scs/components/status-page-web/docs/configuration"}}');var n=s(74848),c=s(28453);const r={},a="Quickstart",i={},p=[];function u(t){const e={a:"a",h1:"h1",header:"header",p:"p",...(0,c.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,n.jsxs)(e.p,{children:["To quickly start hosting the status page frontend, refer to ",(0,n.jsx)(e.a,{href:"https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/quickstart",children:"the Quickstart guide"})," of the status-page-deployment repository."]}),"\n",(0,n.jsxs)(e.p,{children:["When intending to develop for the status page frontend, refer to the ",(0,n.jsx)(e.a,{href:"/docs/operating-scs/components/status-page-web/docs/contribute",children:"Contribute section"}),"."]})]})}function d(t={}){const{wrapper:e}={...(0,c.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(u,{...t})}):u(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>r,x:()=>a});var o=s(96540);const n={},c=o.createContext(n);function r(t){const e=o.useContext(c);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(n):t.components||n:r(t.components),o.createElement(c.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/9b5d9131.8e559210.js b/assets/js/9b5d9131.8e559210.js new file mode 100644 index 0000000000..e62eff60a2 --- /dev/null +++ b/assets/js/9b5d9131.8e559210.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[61427],{52319:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>o,contentTitle:()=>r,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"operating-scs/components/central-api/poc-setup","title":"Central API MVP","description":"Right now, this repository implements issue 374.","source":"@site/docs/04-operating-scs/components/central-api/poc-setup.md","sourceDirName":"04-operating-scs/components/central-api","slug":"/operating-scs/components/central-api/poc-setup","permalink":"/docs/operating-scs/components/central-api/poc-setup","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/central-api/poc-setup.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/operating-scs/components/central-api/overview"},"next":{"title":"Automated Pentesting","permalink":"/docs/category/automated-pentesting"}}');var s=t(74848),i=t(28453);const c={},r="Central API MVP",o={},l=[{value:"Quick Start",id:"quick-start",level:2}];function p(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...n.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.header,{children:(0,s.jsx)(e.h1,{id:"central-api-mvp",children:"Central API MVP"})}),"\n",(0,s.jsxs)(e.p,{children:["Right now, this repository implements ",(0,s.jsx)(e.a,{href:"https://github.com/SovereignCloudStack/issues/issues/374",children:"issue 374"}),".\nIt contains a script (",(0,s.jsx)(e.code,{children:"gen.py"}),") to mirror all crossplane openstack provider cluster-scoped resources to namespaced resources in an SCS API group."]}),"\n",(0,s.jsxs)(e.p,{children:["Also, these instructions are striving to implement ",(0,s.jsx)(e.a,{href:"https://docs.crossplane.io/knowledge-base/guides/multi-tenant/#namespaces-as-an-isolation-mechanism",children:"namespaces as isolation mechanism"})," to implement a multi-tenant system backed by a single Kubernetes cluster."]}),"\n",(0,s.jsxs)(e.p,{children:[(0,s.jsx)(e.a,{href:"https://github.com/crossplane-contrib/x-generation",children:"crossplane-contrib/x-generation"})," might be used as soon as ",(0,s.jsx)(e.a,{href:"https://github.com/crossplane-contrib/x-generation/issues/21",children:"the required feature for namespace mapping"})," is implemented."]}),"\n",(0,s.jsx)(e.h2,{id:"quick-start",children:"Quick Start"}),"\n",(0,s.jsxs)(e.ol,{children:["\n",(0,s.jsx)(e.li,{children:"Setup testing Kubernetes cluster"}),"\n",(0,s.jsx)(e.li,{children:"Install crossplane"}),"\n",(0,s.jsxs)(e.li,{children:["Select fitting configuration package (containing provider definitions, XRD's and composites) and install it","\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-bash",children:"export VERSION=...\nexport XPKG=... # openstack / kubernetes\ncrossplane xpkg install configuration registry.scs.community/central-api/$XPKG:$VERSION\n"})}),"\n"]}),"\n",(0,s.jsxs)(e.li,{children:["Setup provider config (wearing CSP hat)","\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-yaml",children:'apiVersion: v1\nkind: Namespace\nmetadata:\n name: tenant-name\n---\napiVersion: openstack.upbound.io/v1beta1\nkind: ProviderConfig\nmetadata:\n name: tenant-name\nspec:\n credentials:\n secretRef:\n namespace: crossplane-system\n name: tenant-name-clouds-yaml\n key: clouds.json\n source: Secret\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: tenant-name-clouds-yaml\n namespace: crossplane-system\nstringData:\n clouds.json: |\n {\n "auth_url": "https://api.gx-scs.sovereignit.cloud:5000",\n "application_credential_id": "...",\n "application_credential_secret": "...",\n "tenant_name": "tenant-name"\n }\n'})}),"\n"]}),"\n",(0,s.jsxs)(e.li,{children:["Setup RBAC for tenants (wearing CSP hat)","\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-yaml",children:"apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n name: tenant\nrules:\n- apiGroups:\n - api.scs.community\n resources:\n - '*'\n verbs:\n - '*'\n---\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: tenant\n namespace: tenant-name\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n name: scs-bind\n namespace: tenant-name\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: tenant\nsubjects:\n- kind: ServiceAccount\n name: tenant\n namespace: tenant-name\n"})}),"\n"]}),"\n",(0,s.jsxs)(e.li,{children:["Create resource (wearing tenant hat, ",(0,s.jsx)(e.code,{children:"kubectl --as system:serviceaccount:tenant-name:tenant -n tenant-name"}),")","\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-yaml",children:"apiVersion: api.scs.community/v1alpha1\nkind: KeypairV2\nmetadata:\n name: admin\n namespace: tenant-name\nspec:\n name: admin-keypair\n publicKey: |-\n ssh-rsa ...\n---\napiVersion: api.scs.community/v1alpha1\nkind: InstanceV2\nmetadata:\n name: testing-vm\n namespace: tenant-name\nspec:\n name: testing-vm\n keyPair: admin-keyPair\n imageName: 'Debian 12'\n flavorName: 'SCS-1V:1:20'\n"})}),"\n"]}),"\n",(0,s.jsx)(e.li,{children:"Observe creation of resources"}),"\n"]}),"\n",(0,s.jsxs)(e.p,{children:["Right now, it would be expected to hand out the ",(0,s.jsx)(e.code,{children:"ServiceAccount"})," token to the actual tenant; When AuthN is done via OIDC (or other means), the ",(0,s.jsx)(e.code,{children:"ServiceAccount"})," ",(0,s.jsx)(e.code,{children:"tenant-name/tenant"})," may be dropped and ",(0,s.jsx)(e.code,{children:"RoleBinding"})," ",(0,s.jsx)(e.code,{children:"tenant-name/scs-bind"})," may point to an actual user/group."]})]})}function d(n={}){const{wrapper:e}={...(0,i.R)(),...n.components};return e?(0,s.jsx)(e,{...n,children:(0,s.jsx)(p,{...n})}):p(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>c,x:()=>r});var a=t(96540);const s={},i=a.createContext(s);function c(n){const e=a.useContext(i);return a.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function r(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(s):n.components||s:c(n.components),a.createElement(i.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/9d1324c7.524219d1.js b/assets/js/9d1324c7.524219d1.js new file mode 100644 index 0000000000..57b51d5073 --- /dev/null +++ b/assets/js/9d1324c7.524219d1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[16568],{66804:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>d,metadata:()=>i,toc:()=>a});const i=JSON.parse('{"id":"scs-0100-v1-flavor-naming","title":"SCS Flavor Naming Standard","description":"Introduction","source":"@site/standards/scs-0100-v1-flavor-naming.md","sourceDirName":".","slug":"/scs-0100-v1-flavor-naming","permalink":"/standards/scs-0100-v1-flavor-naming","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Flavor Naming Standard","version":"2022-09-08-002","authors":"Matthias Hamm, Kurt Garloff, Tim Beermann","type":"Standard","track":"IaaS","status":"Deprecated","state":"v1.1 (for R3)","stabilized_at":"2022-09-08T00:00:00.000Z","deprecated_at":"2023-10-31T00:00:00.000Z"},"sidebar":"standards","previous":{"title":"scs-0100: SCS Flavor Naming Standard","permalink":"/standards/iaas/scs-0100"},"next":{"title":"V2","permalink":"/standards/scs-0100-v2-flavor-naming"}}');var r=n(74848),t=n(28453);const d={title:"SCS Flavor Naming Standard",version:"2022-09-08-002",authors:"Matthias Hamm, Kurt Garloff, Tim Beermann",type:"Standard",track:"IaaS",status:"Deprecated",state:"v1.1 (for R3)",stabilized_at:new Date("2022-09-08T00:00:00.000Z"),deprecated_at:new Date("2023-10-31T00:00:00.000Z")},l=void 0,o={},a=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Proposal",id:"proposal",level:2},{value:"Type of information included",id:"type-of-information-included",level:3},{value:"Complete Proposal",id:"complete-proposal",level:3},{value:"Proposal Details",id:"proposal-details",level:2},{value:"[REQUIRED] CPU Suffixes",id:"required-cpu-suffixes",level:3},{value:"Baseline",id:"baseline",level:4},{value:"Higher oversubscription",id:"higher-oversubscription",level:4},{value:"Insufficient microcode",id:"insufficient-microcode",level:4},{value:"Examples",id:"examples",level:4},{value:"[REQUIRED] Memory",id:"required-memory",level:3},{value:"Baseline",id:"baseline-1",level:4},{value:"No ECC",id:"no-ecc",level:4},{value:"Enabled Oversubscription",id:"enabled-oversubscription",level:4},{value:"Examples",id:"examples-1",level:4},{value:"[OPTIONAL] Disk sizes and types",id:"optional-disk-sizes-and-types",level:3},{value:"Baseline",id:"baseline-2",level:4},{value:"Multi-provisioned Disk",id:"multi-provisioned-disk",level:4},{value:"Examples",id:"examples-2",level:4},{value:"[OPTIONAL] Hypervisor",id:"optional-hypervisor",level:3},{value:"Examples",id:"examples-3",level:4},{value:"[OPTIONAL] Hardware virtualization / Nested virtualization",id:"optional-hardware-virtualization--nested-virtualization",level:3},{value:"Examples",id:"examples-4",level:4},{value:"[OPTIONAL] CPU Architecture Details",id:"optional-cpu-architecture-details",level:3},{value:"Generation and Vendor",id:"generation-and-vendor",level:4},{value:"Frequency Suffixes",id:"frequency-suffixes",level:4},{value:"Examples",id:"examples-5",level:4},{value:"[OPTIONAL] Extra features",id:"optional-extra-features",level:3},{value:"Proposal Examples",id:"proposal-examples",level:2},{value:"Standard SCS flavors",id:"standard-scs-flavors",level:2},{value:"Naming policies",id:"naming-policies",level:2},{value:"Rationale",id:"rationale",level:3},{value:"Validation",id:"validation",level:2},{value:"Beyond SCS: Gaia-X",id:"beyond-scs-gaia-x",level:2}];function c(e){const s={a:"a",code:"code",del:"del",div:"div",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsx)(s.p,{children:"This is the standard v1.0 for SCS Release 0.\nNote that we intend to only extend it (so it's always backwards compatible),\nbut try to avoid changing in incompatible ways."}),"\n",(0,r.jsx)(s.h2,{id:"motivation",children:"Motivation"}),"\n",(0,r.jsx)(s.p,{children:"In OpenStack environments there is a need to define different flavors for instances.\nThe flavors are pre-defined by the operator, the customer can not change these.\nOpenStack providers thus typically offer a large selection of flavors."}),"\n",(0,r.jsxs)(s.p,{children:["While flavors can be discovered (",(0,r.jsx)(s.code,{children:"openstack flavor list"}),"), it is helpful for users (DevOps teams),\nto have"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere."}),"\n",(0,r.jsx)(s.li,{children:"Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"While not all details will be encoded in the name, the key features should be obvious:\nNumber of vCPUs, RAM, Root Disk.\nExtra features are important as well: There will be flavors with GPU support, fast disks for databases,\nmemory-heavy applications, and other useful aspects of an instance."}),"\n",(0,r.jsx)(s.p,{children:"It may also be important to make the CPU generation clearly recognisable, as this is always a topic in\ndiscussions with customers."}),"\n",(0,r.jsx)(s.h2,{id:"proposal",children:"Proposal"}),"\n",(0,r.jsx)(s.h3,{id:"type-of-information-included",children:"Type of information included"}),"\n",(0,r.jsx)(s.p,{children:"We believe the following characteristics are important in a flavour description:"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{style:{textAlign:"left"},children:"Type"}),(0,r.jsx)(s.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{style:{textAlign:"left"},children:"Generation"}),(0,r.jsx)(s.td,{style:{textAlign:"left"},children:"CPU Generation"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{style:{textAlign:"left"},children:"Number of CPU"}),(0,r.jsx)(s.td,{style:{textAlign:"left"},children:"Number of vCPUs - suffixed by L,V,T,C (see below)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{style:{textAlign:"left"},children:"Amount of RAM"}),(0,r.jsx)(s.td,{style:{textAlign:"left"},children:"Amount of memory available for the VM"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{style:{textAlign:"left"},children:"Performance Class"}),(0,r.jsx)(s.td,{style:{textAlign:"left"},children:"Ability to label high-performance CPUs, disks, network"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{style:{textAlign:"left"},children:"CPU Type"}),(0,r.jsx)(s.td,{style:{textAlign:"left"},children:"X86-intel, X86-amd, ARM, RISC-V, Generic"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{style:{textAlign:"left"},children:'"bms"'}),(0,r.jsx)(s.td,{style:{textAlign:"left"},children:"Bare Metal System (no virtualization/hypervisor)"})]})]})]}),"\n",(0,r.jsx)(s.h3,{id:"complete-proposal",children:"Complete Proposal"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Prefix"}),(0,r.jsx)(s.th,{children:"CPU"}),(0,r.jsx)(s.th,{children:"Suffix"}),(0,r.jsx)(s.th,{children:"RAM[GiB]"}),(0,r.jsx)(s.th,{children:"optional: Disk[GB]"}),(0,r.jsx)(s.th,{children:"optional: Disk type"}),(0,r.jsx)(s.th,{children:"optional: extra features"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"SCS-"})}),(0,r.jsx)(s.td,{children:"N"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"L/V/T/C[i]"})}),(0,r.jsxs)(s.td,{children:[":N",(0,r.jsx)(s.code,{children:"[u][o]"})]}),(0,r.jsxs)(s.td,{children:[(0,r.jsx)(s.code,{children:"[:["}),"M",(0,r.jsx)(s.code,{children:"x]"}),"N",(0,r.jsx)(s.code,{children:"]"})]}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"[n/s/l/p]"})}),(0,r.jsxs)(s.td,{children:[(0,r.jsx)(s.code,{children:"[-"}),"hyp",(0,r.jsx)(s.code,{children:"][-hwv]-["}),"arch",(0,r.jsx)(s.code,{children:"["}),"N",(0,r.jsx)(s.code,{children:"][h][-[G/g]"}),"X",(0,r.jsx)(s.code,{children:"["}),"N",(0,r.jsx)(s.code,{children:"][:"}),"M",(0,r.jsx)(s.code,{children:"[h]]][-ib]"})]})]})})]}),"\n",(0,r.jsx)(s.p,{children:"(Note that N and M are placeholders for numbers here)."}),"\n",(0,r.jsx)(s.h2,{id:"proposal-details",children:"Proposal Details"}),"\n",(0,r.jsx)(s.h3,{id:"required-cpu-suffixes",children:"[REQUIRED] CPU Suffixes"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Suffix"}),(0,r.jsx)(s.th,{children:"Meaning"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"C"}),(0,r.jsx)(s.td,{children:"dedicated Core"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"T"}),(0,r.jsx)(s.td,{children:"dedicated Thread (SMT)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"V"}),(0,r.jsx)(s.td,{children:"vCPU (oversubscribed)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"L"}),(0,r.jsx)(s.td,{children:"vCPU (heavily oversubscribed)"})]})]})]}),"\n",(0,r.jsx)(s.h4,{id:"baseline",children:"Baseline"}),"\n",(0,r.jsxs)(s.p,{children:["Note that vCPU oversubscription for a ",(0,r.jsx)(s.code,{children:"V"})," vCPU should be implemented such, that we\ncan guarantee ",(0,r.jsx)(s.code,{children:"at least 20% of a core in >99% of the time"}),"; this can be achieved by\nlimiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled)\nor by more advanced workload management logic. Otherwise ",(0,r.jsx)(s.code,{children:"L"})," (low performance) must be\nused. The >99% is measured over a month (1% is 7.2h/month)."]}),"\n",(0,r.jsxs)(s.p,{children:["Note that CPUs must use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.).\nWe expect that microcode gets updated within less than a month of a new release; for CVSS scores above 8,\nwe expect less than a week.\nThe provider must enable at least all mitigations that are enabled by default in the Linux kernel. CPUs that\nare susceptible to L1TF (intel x86 pre Cascade Lake) must switch off hyperthreading OR (in the future)\nuse core scheduling implementations that are deemed to be secure by the SCS security team, or declare themselves\nas insecure with the ",(0,r.jsx)(s.code,{children:"i"})," suffix (see below)."]}),"\n",(0,r.jsx)(s.h4,{id:"higher-oversubscription",children:"Higher oversubscription"}),"\n",(0,r.jsxs)(s.p,{children:["Must be indicated with a ",(0,r.jsx)(s.code,{children:"L"})," vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and\nthe lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month)."]}),"\n",(0,r.jsx)(s.h4,{id:"insufficient-microcode",children:"Insufficient microcode"}),"\n",(0,r.jsxs)(s.p,{children:["Not using these mitigations must be indicated by an additional ",(0,r.jsx)(s.code,{children:"i suffix"})," for insecure\n(weak protection against CPU vulnerabilities through insufficient microcode, lack of disabled hyperthreading\non L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor)."]}),"\n",(0,r.jsx)(s.h4,{id:"examples",children:"Examples"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["SCS-",(0,r.jsx)(s.strong,{children:"2C"}),":4:10n"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-",(0,r.jsx)(s.strong,{children:"2T"}),":4:10n"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-",(0,r.jsx)(s.strong,{children:"2V"}),":4:10n"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-",(0,r.jsx)(s.strong,{children:"2L"}),":4:10n"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-",(0,r.jsx)(s.strong,{children:"2Li"}),":4:10n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsxs)(s.del,{children:["SCS-",(0,r.jsx)(s.strong,{children:"2"}),":**4:10n"]})," - CPU suffix missing"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsxs)(s.del,{children:["SCS-",(0,r.jsx)(s.strong,{children:"2iT"}),":4:10n"]})," - This order is forbidden"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"required-memory",children:"[REQUIRED] Memory"}),"\n",(0,r.jsx)(s.h4,{id:"baseline-1",children:"Baseline"}),"\n",(0,r.jsx)(s.p,{children:"We expect cloud providers to use ECC memory.\nMemory oversubscription is not recommended.\nIt is allowed to specify half GiBs (e.g. 3.5), though this is discouraged for larger memory sizes (>= 10GiB)."}),"\n",(0,r.jsx)(s.h4,{id:"no-ecc",children:"No ECC"}),"\n",(0,r.jsxs)(s.p,{children:["If no ECC is used, the ",(0,r.jsx)(s.code,{children:"u suffix"})," must indicate this."]}),"\n",(0,r.jsx)(s.h4,{id:"enabled-oversubscription",children:"Enabled Oversubscription"}),"\n",(0,r.jsxs)(s.p,{children:["You have to expose this with the ",(0,r.jsx)(s.code,{children:"o sufffix"}),"."]}),"\n",(0,r.jsx)(s.h4,{id:"examples-1",children:"Examples"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["SCS-2C:",(0,r.jsx)(s.strong,{children:"4"}),":10n"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:",(0,r.jsx)(s.strong,{children:"3.5"}),":10n"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:",(0,r.jsx)(s.strong,{children:"4u"}),":10n"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:",(0,r.jsx)(s.strong,{children:"4o"}),":10n"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:",(0,r.jsx)(s.strong,{children:"4uo"}),":10n"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsxs)(s.del,{children:["SCS-2C:",(0,r.jsx)(s.strong,{children:"4ou"}),":10n"]})," - This order is forbidden"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"optional-disk-sizes-and-types",children:"[OPTIONAL] Disk sizes and types"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Disk type"}),(0,r.jsx)(s.th,{children:"Meaning"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"n"}),(0,r.jsx)(s.td,{children:"Network shared storage (ceph/cinder)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"h"}),(0,r.jsx)(s.td,{children:"Local disk (HDD: SATA/SAS class)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"s"}),(0,r.jsx)(s.td,{children:"Local SSD disk"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"p"}),(0,r.jsx)(s.td,{children:"Local high-perf NVMe"})]})]})]}),"\n",(0,r.jsx)(s.h4,{id:"baseline-2",children:"Baseline"}),"\n",(0,r.jsx)(s.p,{children:"Note that disk type might be omitted \u2014 the user then can not take any assumptions\non what storage is provided for the root disk (that the image gets provisioned to)."}),"\n",(0,r.jsxs)(s.p,{children:["It does make sense for ",(0,r.jsx)(s.code,{children:"n"})," to be requested explicitly to allow for smooth live migration.\n",(0,r.jsx)(s.code,{children:"h"})," typically provides latency advantages vs ",(0,r.jsx)(s.code,{children:"n"})," (but not necessarily bandwidth and\nalso is more likely to fail), ",(0,r.jsx)(s.code,{children:"s"})," and ",(0,r.jsx)(s.code,{children:"p"})," are for applications that need low\nlatency (high IOPS) and bandwidth disk I/O. ",(0,r.jsx)(s.code,{children:"n"})," storage is expected to survive\nsingle-disk and single-node failure."]}),"\n",(0,r.jsxs)(s.p,{children:["If the disk size is left out, the cloud is expected to allocate a disk (network or local)\nthat is large enough to fit the root file system (",(0,r.jsx)(s.code,{children:"min_disk"})," in image). This automatic\nallocation is indicated with ",(0,r.jsx)(s.code,{children:":"})," without a disk size.\nIf the ",(0,r.jsx)(s.code,{children:":"})," is left out completely, the user must create a boot volume manually and\ntell the instance to boot from it or use the\n",(0,r.jsx)(s.a,{href:"https://docs.openstack.org/api-ref/compute/?expanded=create-server-detail#create-server",children:"block_device_mapping_v2"}),"\nmechanism explicitly to create the boot volume from an image."]}),"\n",(0,r.jsx)(s.h4,{id:"multi-provisioned-disk",children:"Multi-provisioned Disk"}),"\n",(0,r.jsxs)(s.p,{children:["The disk size can be prefixed with ",(0,r.jsx)(s.code,{children:"Mx prefix"}),", where M is an integer specifying that the disk\nis provisioned M times."]}),"\n",(0,r.jsx)(s.h4,{id:"examples-2",children:"Examples"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:",(0,r.jsx)(s.strong,{children:"10n"})]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:",(0,r.jsx)(s.strong,{children:"10s"})]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:",(0,r.jsx)(s.strong,{children:"10s"}),"-bms-z3"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:",(0,r.jsx)(s.strong,{children:"3x10s"})," - Cloud creates three 10GB SSDs"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:",(0,r.jsx)(s.strong,{children:"3x10s"}),"-bms-z3"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:",(0,r.jsx)(s.strong,{children:"10"})," - Cloud decides disk type"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:",(0,r.jsx)(s.strong,{children:"10"}),"-bms-z3"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:",(0,r.jsx)(s.strong,{children:"n"})," - Cloud decides disk size (min_disk from image or larger)"]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:",(0,r.jsx)(s.strong,{children:"n"}),"-bms-3"]}),"\n",(0,r.jsx)(s.li,{children:"SCS-2C:4: - Cloud decides disk type and size"}),"\n",(0,r.jsx)(s.li,{children:"SCS-2C:4:-bms-z3"}),"\n",(0,r.jsx)(s.li,{children:"SCS-2C:4:-bms-z3h-GNa:64-ib"}),"\n",(0,r.jsx)(s.li,{children:"SCS-2C:4:-ib"}),"\n",(0,r.jsx)(s.li,{children:"SCS-2C:4 - You need to specify a boot volume yourself (boot from volume, or use block_device_mapping_v2)"}),"\n",(0,r.jsx)(s.li,{children:"SCS-2C:4-bms-z3"}),"\n",(0,r.jsx)(s.li,{children:"SCS-2C:4:3x - Cloud decides disk type and size and creates three of them (FIXME: Is this useful?)"}),"\n",(0,r.jsx)(s.li,{children:"SCS-2C:4:3xs - Cloud decides size and creates three local SSD volumes (FIXME: useful?)"}),"\n",(0,r.jsx)(s.li,{children:"SCS-2C:4:3x10 - Cloud decides type and creates three 10GB volumes"}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsxs)(s.del,{children:["SCS-2C:4:",(0,r.jsx)(s.strong,{children:"1.5n"})]})," - You must not specify disk sizes which are not in full GiBs"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"optional-hypervisor",children:"[OPTIONAL] Hypervisor"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"default Hypervisor"})," is assumed to be ",(0,r.jsx)(s.code,{children:"KVM"}),". Clouds, that offer different hypervisors\nor Bare Metal Systems should indicate the Hypervisor according to the following table:"]}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"hyp"}),(0,r.jsx)(s.th,{children:"Meaning"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"kvm"}),(0,r.jsx)(s.td,{children:"KVM"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"xen"}),(0,r.jsx)(s.td,{children:"Xen"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"vmw"}),(0,r.jsx)(s.td,{children:"VMware"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"hyv"}),(0,r.jsx)(s.td,{children:"Hyper-V"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"bms"}),(0,r.jsx)(s.td,{children:"Bare Metal System"})]})]})]}),"\n",(0,r.jsx)(s.h4,{id:"examples-3",children:"Examples"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"SCS-2C:4:10n"}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10n-",(0,r.jsx)(s.strong,{children:"bms"})]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10n-",(0,r.jsx)(s.strong,{children:"bms"}),"-z3h"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"optional-hardware-virtualization--nested-virtualization",children:"[OPTIONAL] Hardware virtualization / Nested virtualization"}),"\n",(0,r.jsxs)(s.p,{children:["If the instances that are created with this flavor support hardware-accelerated\nvirtualization, this can be reflected with the ",(0,r.jsx)(s.code,{children:"-hwv"})," flag (after the optional\nHypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel)\nor svm (AMD) is available. This will be the case on Bare Metal flavors on almost\nall non-ancient x86 CPUs or if your virtualization hypervisor is configured to\nsupport nested virtualization.\nFlavors without the ",(0,r.jsx)(s.code,{children:"-hwv"})," flag may or may not support hardware virtualization (as we\nrecommend enabling nesting, but don't require flavor names to reflect all\ncapabilities. Flavors may overdeliver ...)"]}),"\n",(0,r.jsx)(s.h4,{id:"examples-4",children:"Examples"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"SCS-2C:4:10 - may or may not support HW virtualization in VMs"}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10-kvm-",(0,r.jsx)(s.strong,{children:"hwv"})]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10-",(0,r.jsx)(s.strong,{children:"hwv"})," - not recommended, but allowed"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsxs)(s.del,{children:["SCS-2C:4:10-",(0,r.jsx)(s.strong,{children:"hwv"}),"-xen"]})," - illegal, wrong ordering"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"optional-cpu-architecture-details",children:"[OPTIONAL] CPU Architecture Details"}),"\n",(0,r.jsx)(s.p,{children:"Arch details provide more details on the specific CPU:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Vendor"}),"\n",(0,r.jsx)(s.li,{children:"Generation"}),"\n",(0,r.jsx)(s.li,{children:"Frequency"}),"\n"]}),"\n",(0,r.jsx)(s.h4,{id:"generation-and-vendor",children:"Generation and Vendor"}),"\n",(0,r.jsxs)(s.p,{children:["The generations are vendor specific and can be left out.\nNot specifying arch means that we have a generic CPU (",(0,r.jsx)(s.strong,{children:"x86-64"}),")."]}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Generation"}),(0,r.jsx)(s.th,{children:"i (Intel x86-64)"}),(0,r.jsx)(s.th,{children:"z (AMD x86-64)"}),(0,r.jsx)(s.th,{children:"\xa0a (AArch64)"}),(0,r.jsx)(s.th,{children:"r (RISC-V)"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"pre Skylake"}),(0,r.jsx)(s.td,{children:"pre Zen"}),(0,r.jsx)(s.td,{children:"pre Cortex A76"}),(0,r.jsx)(s.td,{children:"TBD"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{children:"Skylake"}),(0,r.jsx)(s.td,{children:"Zen-1 (Naples)"}),(0,r.jsx)(s.td,{children:"A76/NeoN1 class"}),(0,r.jsx)(s.td,{children:"TBD"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"2"}),(0,r.jsx)(s.td,{children:"Cascade Lake"}),(0,r.jsx)(s.td,{children:"Zen-2 (Rome)"}),(0,r.jsx)(s.td,{children:"A78/x1/NeoV1 class"}),(0,r.jsx)(s.td,{children:"TBD"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"3"}),(0,r.jsx)(s.td,{children:"Ice Lake"}),(0,r.jsx)(s.td,{children:"Zen-3 (Milan)"}),(0,r.jsx)(s.td,{children:"A71x/NeoN2 (ARMv9)"}),(0,r.jsx)(s.td,{children:"TBD"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"4"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"Zen-4 (Genoa)"}),(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:"TBD"})]})]})]}),"\n",(0,r.jsxs)(s.p,{children:["It is recommended to leave out the ",(0,r.jsx)(s.code,{children:"0"}),' when specifying the old generation; this will\nhelp the parser tool, which assumes 0 for an unspecified value and does leave it\nout when generating the name for comparison. In other words: 0 has a meaning of\n"rather old or unspecified".']}),"\n",(0,r.jsx)(s.h4,{id:"frequency-suffixes",children:"Frequency Suffixes"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Suffix"}),(0,r.jsx)(s.th,{children:"Meaning"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"h"}),(0,r.jsx)(s.td,{children:">2.75GHz all-core"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"hh"}),(0,r.jsx)(s.td,{children:">3.25GHz all-core"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"hhh"}),(0,r.jsx)(s.td,{children:">3.75GHz all-core"})]})]})]}),"\n",(0,r.jsx)(s.h4,{id:"examples-5",children:"Examples"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"SCS-2C:4:10n"}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10n-",(0,r.jsx)(s.strong,{children:"z"})]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10n-",(0,r.jsx)(s.strong,{children:"z3"})]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10n-",(0,r.jsx)(s.strong,{children:"z3h"})]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10n-",(0,r.jsx)(s.strong,{children:"z3hh"})]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10n-bms-",(0,r.jsx)(s.strong,{children:"z"})]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10n-bms-",(0,r.jsx)(s.strong,{children:"z3"})]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10n-bms-",(0,r.jsx)(s.strong,{children:"z3"})]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10n-bms-",(0,r.jsx)(s.strong,{children:"z3h"})]}),"\n",(0,r.jsxs)(s.li,{children:["SCS-2C:4:10n-bms-",(0,r.jsx)(s.strong,{children:"z3hh"})]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"optional-extra-features",children:"[OPTIONAL] Extra features"}),"\n",(0,r.jsxs)(s.p,{children:["Note that these are optional \u2014 it is recommended for providers to encode this information\ninto the flavor name, so there is a systematic way of differentiating flavors.\nProviders could leave it out however, leaving it to ",(0,r.jsx)(s.code,{children:"extra_specs"})," to make these flavor\ncapabilities discoverable. Nothing prevents providers from registering the same flavor\nunder a secondary (or tertiary) name."]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"-GX[N][:M[h]]"})," indicates a Pass-Through GPU from vendor X of gen N with M compute units / SMs / EUs exposed.\n",(0,r.jsx)(s.code,{children:"-gX[N][:M[h]]"})," indicates a vGPU from vendor X of gen N with M compute units / SMs / EUs assigned."]}),"\n",(0,r.jsx)(s.p,{children:"Note that the vendor letter is mandatory, generation and compute units are optional."}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"GPU"}),(0,r.jsx)(s.th,{children:"Vendor"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"N"}),(0,r.jsx)(s.td,{children:"nVidia"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"A"}),(0,r.jsx)(s.td,{children:"AMD"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"I"}),(0,r.jsx)(s.td,{children:"Intel"})]})]})]}),"\n",(0,r.jsx)(s.p,{children:"Generations could be nVidia (f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, ...),\nAMD (GCN-x=0.x, RDNA1=1, RDNA2=2), intel (Gen9=0.9, Xe(12.1)=1, ...), ...\n(Note: This may need further work to properly reflect what's out there.)"}),"\n",(0,r.jsxs)(s.p,{children:["The optional ",(0,r.jsx)(s.code,{children:"h"})," suffix to the comput unit count indicates high-performance (e.g. high freq or special\nhigh bandwidth gfx memory such as HBM);\n",(0,r.jsx)(s.code,{children:"h"})," can be duplicated for even higher performance."]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"-ib"})," indicates Infiniband networking."]}),"\n",(0,r.jsx)(s.p,{children:"More extensions will be forthcoming."}),"\n",(0,r.jsx)(s.p,{children:"Extensions need to be specified in the above-mentioned order."}),"\n",(0,r.jsx)(s.h2,{id:"proposal-examples",children:"Proposal Examples"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Example"}),(0,r.jsx)(s.th,{children:"Decoding"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-2C:4:10n"}),(0,r.jsx)(s.td,{children:"2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-8Ti:32:50p-i1"}),(0,r.jsx)(s.td,{children:"8 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-1L:1u:5"}),(0,r.jsx)(s.td,{children:"1 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific)"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-16T:64:200s-GNa:64-ib"}),(0,r.jsx)(s.td,{children:"16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 64 Passthrough nVidia Ampere SMs"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-4C:16:2x200p-a1"}),(0,r.jsx)(s.td,{children:"4 dedicated Arm64 cores (A78 class), 16GiB RAM, 2x200GB local NVMe drives"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"SCS-1V:0.5"}),(0,r.jsx)(s.td,{children:"1 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)"})]})]})]}),"\n",(0,r.jsx)(s.h2,{id:"standard-scs-flavors",children:"Standard SCS flavors"}),"\n",(0,r.jsx)(s.p,{children:"These are flavors expected to exist on standard SCS clouds (x86-64)."}),"\n",(0,r.jsxs)(s.p,{children:["We expect disk sizes to be 5, 10, 20, 50, 100, 200, 500, 1000GB, 2000GB.\nWe expect a typical CPU",(0,r.jsx)(s.div,{children:"GiB"})," ratio of 1:4."]}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsxs)(s.th,{children:["vCPU",":RAM"," ratio"]}),(0,r.jsx)(s.th,{children:"Mandatory Flavors"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1:4"}),(0,r.jsx)(s.td,{children:"SCS-1V:4, SCS-1V:4:10"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"2:8"}),(0,r.jsx)(s.td,{children:"SCS-2V:8, SCS-2V:8:20"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"4:16"}),(0,r.jsx)(s.td,{children:"SCS-4V:16, SCS-4V:16:50"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"8:32"}),(0,r.jsx)(s.td,{children:"SCS-8V:32, SCS-8V:32:100"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1:2"}),(0,r.jsx)(s.td,{children:"SCS-1V:2, SCS-1V:2:5"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"2:4"}),(0,r.jsx)(s.td,{children:"SCS-2V:4, SCS-2V:4:10"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"4:8"}),(0,r.jsx)(s.td,{children:"SCS-4V:8, SCS-4V:8:20"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"8:16"}),(0,r.jsx)(s.td,{children:"SCS-8V:16, SCS-8V:16:50"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"16:32"}),(0,r.jsx)(s.td,{children:"SCS-16V:32, SCS-16V:32:100"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1:8"}),(0,r.jsx)(s.td,{children:"SCS-1V:8, SCS-1V:8:20"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"2:16"}),(0,r.jsx)(s.td,{children:"SCS-2V:16, SCS-2V:16:50"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"4:32"}),(0,r.jsx)(s.td,{children:"SCS-4V:32, SCS-4V:32:100"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1:1"}),(0,r.jsx)(s.td,{children:"SCS-1L:1, SCS-1L:1:5"})]})]})]}),"\n",(0,r.jsxs)(s.p,{children:["Note that all vCPUs are oversubscribed \u2014 the smallest ",(0,r.jsx)(s.code,{children:"1L:1"})," flavor allows\nfor heavy oversubscription (note the ",(0,r.jsx)(s.code,{children:"L"}),"), and thus can be offered very\ncheaply \u2014 imagine jump hosts ...\nDisks types are not specified (and expected to be n or h typically)."]}),"\n",(0,r.jsx)(s.p,{children:"The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM\ncompute hosts) to offer all flavors."}),"\n",(0,r.jsxs)(s.p,{children:["Note: Compared to previous drafts, we have heavily reduced the variations\non disk sizes \u2014 this reflects that for the standard networked cinder\ndisks, you can pass block",(0,r.jsx)(s.em,{children:"device_mapping_v2 on server (VM) creation to\nallocate a boot disk of any size you desire. We have scaled the few\nmandatory disk sizes with the amount of RAM. For each flavor there is\nalso one _without"})," a pre-attached disk \u2014 these are meant to be used\nto boot from a volume (either created beforehand or allocated on-the-fly\nwith block_device_mapping_v2, e.g.\n",(0,r.jsx)(s.code,{children:"openstack server create --flavor SCS-1V:2 --block-device-mapping sda=IMGUUID:image:12:true"}),"\nto create a bootable 12G cinder volume from image ",(0,r.jsx)(s.code,{children:"IMGUUID"})," that gets tied to the VM\ninstance lifecycle.)"]}),"\n",(0,r.jsx)(s.h2,{id:"naming-policies",children:"Naming policies"}),"\n",(0,r.jsx)(s.p,{children:"To be certified as an SCS compliant x86-64 IaaS platform, you must offer all standard SCS flavors\naccording to the previous section. (We may define a mechanism that allows exceptions to be\ngranted in a way that makes this very transparent and visible to clients.)"}),"\n",(0,r.jsx)(s.p,{children:"You are allowed to understate your performance; you may implement a SCS-1Vl:1:5 flavor with\na flavor that actually implements SCS-1T:1:5n (i.e. you dedicate a secured hyperthread instead\nof high oversubscription) or even SCS-1D:1.5:8s (1 dedicated core, 50% more RAM and a 8GiB SSD)."}),"\n",(0,r.jsx)(s.p,{children:"We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V:32:100).\nLarger providers that offer more details are expected to still also offer the short variants\nfor usability and easier portability, even beyond the mandated flavors."}),"\n",(0,r.jsxs)(s.p,{children:["You must be very careful to expose low vCPU guarantees (",(0,r.jsx)(s.code,{children:"L"})," instead ov ",(0,r.jsx)(s.code,{children:"V"}),"), insecure\nhyperthreading/microcode ",(0,r.jsx)(s.code,{children:"i"}),", non-ECC-RAM ",(0,r.jsx)(s.code,{children:"u"}),", memory oversubscription ",(0,r.jsx)(s.code,{children:"o"}),". Note that omitting these qualifiers is\noverstating your security, reliability or performance properties and may be reason for\nclients to feel betrayed or claim damages. It might, in extreme cases, also cause SCS to withdraw certification\nalong with public statements."]}),"\n",(0,r.jsxs)(s.p,{children:["You may offer additional ",(0,r.jsx)(s.code,{children:"SCS-"})," flavors, following the naming scheme outlined here."]}),"\n",(0,r.jsx)(s.p,{children:"You may offer additional flavors, not following above scheme."}),"\n",(0,r.jsxs)(s.p,{children:["You must not offer flavors with the ",(0,r.jsx)(s.code,{children:"SCS-"})," prefix which do not follow this naming scheme.\nYou must not extend the SCS naming scheme with your own suffices; you are encouraged however\nto suggest extensions that we can discuss and add to the official scheme."]}),"\n",(0,r.jsx)(s.p,{children:"Note that all letters are case-sensitive.\nIn case you wonder: Feature indicators are capitalized, modifiers are lower case.\n(An exception is the uppercase -G for a passthrough GPU vs. lowercase -g for vGPU.)"}),"\n",(0,r.jsx)(s.h3,{id:"rationale",children:"Rationale"}),"\n",(0,r.jsx)(s.p,{children:"Note that we expect most clouds to prefer short flavor names,\nnot indicating CPU details or hypervisor types. See above list\nof standard flavors to get a feeling."}),"\n",(0,r.jsxs)(s.p,{children:["However, more successful providers will often need to differentiate their\nofferings in response to customer demand and allow customers to request\nflavors with specific detailed properties. The goal of this proposal is to avoid\nproviders to invent their own names and then refer customers to ",(0,r.jsx)(s.code,{children:"extra_specs"}),"\nor worse a non-machine-readable service description to find out the details."]}),"\n",(0,r.jsxs)(s.p,{children:["So a cloud provider might well evolve from offering ",(0,r.jsx)(s.code,{children:"SCS-8T:16:50"})," to offering\n",(0,r.jsx)(s.code,{children:"SCS-8T:16:50n"}),", ",(0,r.jsx)(s.code,{children:"SCS-8T:16:50n-i2"})," and ",(0,r.jsx)(s.code,{children:"SCS-8T:16:50n-a2"})," to specify that he\nis using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome.\nWe would expect the cloud provider to still offer the generic flavor\n",(0,r.jsx)(s.code,{children:"SCS-8C:16:50"})," and allow the scheduler (placement service) to pick both more\nspecific types (or just one if e.g. capacity management considerations suggest\nso). We would expect providers in such cases to ensure that the price of a requested\nflavor does not depend on the scheduler decisions."]}),"\n",(0,r.jsxs)(s.p,{children:["We are looking into the ",(0,r.jsx)(s.a,{href:"https://docs.openstack.org/image-guide/introduction.html#metadata-definition-metadefs-service",children:"metadefs"}),"\nmechanism and ",(0,r.jsx)(s.a,{href:"https://docs.openstack.org/api-guide/compute/extra_specs_and_properties.html",children:"extra_specs"}),"\nto allow customers to ask for specific flavor properties without the need to\nencode all these flavor details into the flavor name, so the optional pieces\nmay not be needed much. However, there must be a way to request flavor\nproperties without encoding the need into an image \u2014 this indirection is\nconsidered broken by the SCS team."]}),"\n",(0,r.jsx)(s.h2,{id:"validation",children:"Validation"}),"\n",(0,r.jsxs)(s.p,{children:["There is a script in ",(0,r.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/flavor-naming/flavor-name-check.py",children:"flavor_name_check.py"}),"\nwhich can be used to decode, validate and construct flavor names.\nThis script must stay in sync with the specification text."]}),"\n",(0,r.jsxs)(s.p,{children:["Ensure you have your OpenStack tooling (",(0,r.jsx)(s.code,{children:"python3-openstackclient"}),", ",(0,r.jsx)(s.code,{children:"OS_CLOUD"}),") setup and call\n",(0,r.jsx)(s.code,{children:"tools/flavor-name-check.py -c $(openstack flavor list -f value -c Name)"})," to get a report\non the flavor list compliance of the cloud environment."]}),"\n",(0,r.jsx)(s.h2,{id:"beyond-scs-gaia-x",children:"Beyond SCS: Gaia-X"}),"\n",(0,r.jsxs)(s.p,{children:['Some providers might offer VM services ("IaaS") without trying to adhere to SCS standards,\nyet still finding the flavor naming standards useful. The Gaia-X Technical Committee\'s\nProvider Working Group (WG) would seem like a logical place for such discussions then.\nIf so, we could\nreplace the ',(0,r.jsx)(s.code,{children:"SCS-"})," prefix with a GX- prefix and transfer the naming scheme governance from\nthe SCS project to the Gaia-X Provider WG (where we participate). SCS certification would\nthen reference the Gaia-X flavor naming standard as a requirement."]})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>d,x:()=>l});var i=n(96540);const r={},t=i.createContext(r);function d(e){const s=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),i.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9d49bc50.7940b5df.js b/assets/js/9d49bc50.7940b5df.js new file mode 100644 index 0000000000..d2f13f9462 --- /dev/null +++ b/assets/js/9d49bc50.7940b5df.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[75875],{78705:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>c,frontMatter:()=>r,metadata:()=>i,toc:()=>u});const i=JSON.parse('{"id":"iaas/guides/other-guides/developer-guide/zuul","title":"Zuul CI","description":"We use Zuul CI as a CI service for OSISM. The service is not required for","source":"@site/docs/02-iaas/guides/other-guides/developer-guide/zuul.md","sourceDirName":"02-iaas/guides/other-guides/developer-guide","slug":"/iaas/guides/other-guides/developer-guide/zuul","permalink":"/docs/iaas/guides/other-guides/developer-guide/zuul","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/developer-guide/zuul.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Zuul CI"},"sidebar":"docs","previous":{"title":"Style Guide","permalink":"/docs/iaas/guides/other-guides/developer-guide/style-guide"},"next":{"title":"Testbed Guide","permalink":"/docs/iaas/guides/other-guides/testbed"}}');var s=o(74848),t=o(28453);const r={sidebar_label:"Zuul CI"},l="Zuul CI",a={},u=[{value:"The <code>zuul</code> label",id:"the-zuul-label",level:2},{value:"Installation",id:"installation",level:2},{value:"Server preparation",id:"server-preparation",level:3},{value:"Define secrets",id:"define-secrets",level:3},{value:"Github App setup",id:"github-app-setup",level:3},{value:"Example Playbook",id:"example-playbook",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Your git repos are not displayed?",id:"your-git-repos-are-not-displayed",level:3},{value:"Your git repos are using the wrong branch?",id:"your-git-repos-are-using-the-wrong-branch",level:3},{value:"Your logs are not displayed in the web-UI?",id:"your-logs-are-not-displayed-in-the-web-ui",level:3},{value:"Hanging jobs in a pipeline?",id:"hanging-jobs-in-a-pipeline",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"zuul-ci",children:"Zuul CI"})}),"\n",(0,s.jsxs)(n.admonition,{type:"note",children:[(0,s.jsx)(n.p,{children:"We use Zuul CI as a CI service for OSISM. The service is not required for\nthe use of OSISM itself. However, as we deploy and provide Zuul CI ourselves,\nthe documentation for this is also included in the OSISM Developer Guide."}),(0,s.jsxs)(n.p,{children:["Our Zuul CI instance is available at\n",(0,s.jsx)(n.a,{href:"https://zuul.services.betacloud.xyz/t/osism/status",children:"zuul.services.betacloud.xyz"}),"."]})]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"osism.services.zuul"})," is the Ansible role to set up Zuul CI as a single-node\ninstallation with Docker Compose."]}),"\n",(0,s.jsxs)(n.h2,{id:"the-zuul-label",children:["The ",(0,s.jsx)(n.code,{children:"zuul"})," label"]}),"\n",(0,s.jsxs)(n.p,{children:["On CI jobs that consume a lot of resources and have long runtimes we use a label\n",(0,s.jsx)(n.code,{children:"zuul"})," to run these jobs."]}),"\n",(0,s.jsxs)(n.p,{children:["These CI jobs run in the ",(0,s.jsx)(n.a,{href:"https://zuul.services.betacloud.xyz/t/osism/buildsets?pipeline=label",children:"label pipeline"}),"\nand are only started once after the label has been assigned. If changes are made\nto a PR, the label must first be removed and then reassigned for a new run of the\nCI jobs."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"zuul"})," label is usable in the following repositories:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/osism/container-images-kolla",children:"osism/container-images-kolla"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/osism/testbed",children:"osism/testbed"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,s.jsx)(n.h3,{id:"server-preparation",children:"Server preparation"}),"\n",(0,s.jsx)(n.p,{children:"Set up a server (VM) with Ubuntu Server 22.04 LTS and make\nsure that these packages are installed:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"docker.io"}),"\n",(0,s.jsx)(n.li,{children:"docker-compose"}),"\n",(0,s.jsx)(n.li,{children:"python3-docker"}),"\n",(0,s.jsx)(n.li,{children:"python3-openstackclient"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Also configure your deploy user to be in the docker group and set up the\naccount for the zuul user. TCP-Ports 80 and 443 should be accessible\nfrom the internet, port 22 for management via SSH will also often be\nuseful, but not required."}),"\n",(0,s.jsx)(n.p,{children:"If you have an OpenStack tenant where you want to deploy the Zuul\nserver, you can download and adapt this example\nplaybook:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'---\n- name: Setup zuul server\n hosts: localhost\n vars:\n cloud: mycloud\n flavor: myflavor\n image: Ubuntu 22.04\n keypair: mykeypair\n network: myprivatenet\n project: myproject\n zuul_domain: mydomain.xyz.\n zuul_fqdn: "zuul01.services.{{ zuul_domain }}"\n zuul_host: zuul01\n\n tasks:\n - name: Create security group\n openstack.cloud.security_group:\n cloud: "{{ cloud }}"\n name: "{{ project }}-zuul"\n description: "Default security group for {{ project }}-zuul"\n\n - name: Create security group rule (icmp)\n openstack.cloud.security_group_rule:\n cloud: "{{ cloud }}"\n security_group: "{{ project }}-zuul"\n protocol: icmp\n remote_ip_prefix: 0.0.0.0/0\n\n - name: Create security group rules (tcp)\n openstack.cloud.security_group_rule:\n cloud: "{{ cloud }}"\n security_group: "{{ project }}-zuul"\n protocol: tcp\n remote_ip_prefix: 0.0.0.0/0\n port_range_min: "{{ item }}"\n port_range_max: "{{ item }}"\n loop:\n - 22\n - 80\n - 443\n\n - name: Create zuul server\n openstack.cloud.server:\n cloud: "{{ cloud }}"\n flavor: "{{ flavor }}"\n image: "{{ image }}"\n key_name: "{{ keypair }}"\n name: "{{ zuul_host }}"\n network: "{{ network }}"\n security_groups:\n - default\n - "{{ project }}-zuul"\n meta:\n hostname: "{{ zuul_host }}"\n register: zuul_server\n\n - name: Add host\n ansible.builtin.add_host:\n name: "{{ zuul_server.openstack.accessIPv4 }}"\n groups: zuul\n ansible_user: ubuntu\n\n- name: Initialize zuul server\n hosts: zuul\n gather_facts: false\n vars:\n zuul_user: zuul\n\n tasks:\n - name: Wait for system to become reachable\n ansible.builtin.wait_for_connection:\n\n - name: Update all packages\n ansible.builtin.apt:\n update_cache: true\n name: \'*\'\n state: latest\n become: true\n\n - name: Install required packages\n ansible.builtin.apt:\n name:\n - docker.io\n - docker-compose\n - python3-docker\n - python3-openstackclient\n become: true\n\n - name: Add user to docker group\n ansible.builtin.user:\n name: "{{ ansible_ssh_user }}"\n groups: docker\n append: true\n become: true\n\n - name: Add group\n ansible.builtin.group:\n name: "{{ zuul_user }}"\n become: true\n\n - name: Add user\n ansible.builtin.user:\n name: "{{ zuul_user }}"\n uid: 10001\n shell: /bin/bash\n group: "{{ zuul_user }}"\n groups: sudo\n append: true\n home: "/home/{{ zuul_user }}"\n become: true\n'})}),"\n",(0,s.jsx)(n.h3,{id:"define-secrets",children:"Define secrets"}),"\n",(0,s.jsxs)(n.p,{children:["There need to be some secrets handed to the deployment, the suggested\nmethod is to have a dedicated file that contains them, which will be\nincluded in the example playbook below via a ",(0,s.jsx)(n.code,{children:"vars_files"})," statement.\nThis allows you to easily protect all your secrets by applying\n",(0,s.jsx)(n.code,{children:"ansible-vault encrypt"})," to that file. The contents of this file should\nlook like:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"---\nzuul_auth_secret: secret used for zuul web auth\nwebhook_token: token defined for github webhooks\ndb_user_pass: DB password for the zuul user\ndb_root_pass: DB root password\n"})}),"\n",(0,s.jsxs)(n.p,{children:["In addition you need to prepare some further data that needs to be\nplaced into a ",(0,s.jsx)(n.code,{children:"files"})," directory in order to be consumed by the zuul\nrole. These are:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.code,{children:"clouds.yaml"})," file for nodepool. This will be used by\n",(0,s.jsx)(n.code,{children:"nodepool-builder"})," to upload the newly created images and by\n",(0,s.jsx)(n.code,{children:"nodepool-launcher"})," to start instances running these images, these\nwill then be handed over to Zuul as CI nodes."]}),"\n",(0,s.jsxs)(n.li,{children:["An SSH private key in the file ",(0,s.jsx)(n.code,{children:"nodepool"})," and the matching public\nkey in ",(0,s.jsx)(n.code,{children:"nodepool.pub"}),". These will be used by nodepool and zuul to\naccess the CI nodes via SSH."]}),"\n",(0,s.jsxs)(n.li,{children:["An SSL private key and certificate pasted together in a file\nnamed ",(0,s.jsx)(n.code,{children:"server.crt"}),". This file will be used in the https setup by\nthe webserver. The certificate should cover both ",(0,s.jsx)(n.code,{children:"zuul_webserver_fqdn"}),"\nand ",(0,s.jsx)(n.code,{children:"zuul_logserver_fqdn"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"github-app-setup",children:"Github App setup"}),"\n",(0,s.jsxs)(n.p,{children:["In order for zuul to be able to interact with repositories hosted on\ngithub, you need to set up a github application. Follow the instructions\nat ",(0,s.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/drivers/github.html#application",children:"https://zuul-ci.org/docs/zuul/latest/drivers/github.html#application"}),"\nto do this. The webhook token to use is the one defined in the\npervious section. Use ",(0,s.jsx)(n.code,{children:"github"})," in place of ",(0,s.jsx)(n.code,{children:"<connection-name>"})," for the\nWebhook URL in the app configuration. After the app has been created,\nplace the PEM files that you downloaded into a\ndirectory named ",(0,s.jsx)(n.code,{children:"pem-files"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ mkdir -p pem-files\n$ cp ~/Downloads/my-org-zuul.*.private-key.pem pem-files/my-org-zuul.pem\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Now add the information about your github app to ",(0,s.jsx)(n.code,{children:"vars.yml"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"github_app_id: 000000\ngithub_pem_name: my-org-zuul\n"})}),"\n",(0,s.jsx)(n.h3,{id:"example-playbook",children:"Example Playbook"}),"\n",(0,s.jsxs)(n.p,{children:["Save this file as ",(0,s.jsx)(n.code,{children:"main.yaml"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'---\n- name: Set up zuul\n hosts: zuul.example.com\n vars_files:\n - vars.yml\n pre_tasks:\n - name: Create /etc/openstack/\n ansible.builtin.file:\n state: directory\n path: /etc/openstack\n owner: root\n group: root\n mode: 0755\n become: true\n\n - name: Deploy clouds.yaml file\n ansible.builtin.copy:\n src: clouds.yaml\n dest: /etc/openstack/clouds.yaml\n owner: root\n group: zuul\n mode: \'0640\'\n become: true\n\n - name: Create keypair in the cloud\n openstack.cloud.keypair:\n cloud: osism-ci\n name: osism-zuul\n public_key: "{{ lookup(\'file\', \'nodepool.pub\') }}"\n become: true\n\n roles:\n - name: Execute zuul role\n role: zuul\n vars:\n zuul_connections:\n github:\n driver: github\n webhook_token: "{{ webhook_token }}"\n app_id: "{{ github_app_id }}"\n app_key: "/etc/zuul/pem-files/{{ github_pem_name }}.pem"\n opendevorg:\n name: opendev\n driver: git\n baseurl: https://opendev.org\n zuul_tenants:\n - tenant:\n name: my-tenant-name\n source:\n opendevorg:\n untrusted-projects:\n - zuul/zuul-jobs:\n include:\n - job\n github:\n config-projects:\n - my-org/zuul_demo_config:\n load-branch: main\n untrusted-projects:\n - my-org/zuul_demo_repo\n become: true\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Create an ",(0,s.jsx)(n.code,{children:"inventory"})," file containing the login information for your zuul\nserver, it might look like:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"zuul.example.com ansible_host=192.0.2.2 ansible_user=ubuntu\n"})}),"\n",(0,s.jsx)(n.p,{children:"Then you can deploy your zuul server by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ansible-playbook -i inventory main.yaml\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This will deploy a simple zuul setup with sample example repos being\nreferenced. You can fork the example repos from the\n",(0,s.jsx)(n.a,{href:"https://github.com/osism",children:"https://github.com/osism"})," tenant or just use them as a guide for how\nto build your own."]}),"\n",(0,s.jsx)(n.p,{children:"For further information about how to tune this setup for\nyou specific environment, have a look at the sections covering\nnodepool and tenant configuration."}),"\n",(0,s.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,s.jsx)(n.h3,{id:"your-git-repos-are-not-displayed",children:"Your git repos are not displayed?"}),"\n",(0,s.jsxs)(n.p,{children:["Have you thought of naming your repos with the prefix of your organization? ",(0,s.jsx)(n.code,{children:"release"})," should be ",(0,s.jsx)(n.code,{children:"osism/release"})," for example."]}),"\n",(0,s.jsx)(n.h3,{id:"your-git-repos-are-using-the-wrong-branch",children:"Your git repos are using the wrong branch?"}),"\n",(0,s.jsxs)(n.p,{children:["For ",(0,s.jsx)(n.code,{children:"config-projects"})," you set this value in the tenant-configuration with the ",(0,s.jsx)(n.code,{children:"load-branch"})," stanza.\nFor ",(0,s.jsx)(n.code,{children:"untrusted-projects"})," you set this value in the config-projects ",(0,s.jsx)(n.code,{children:"project"})," sections AND in EVERY ",(0,s.jsx)(n.code,{children:"untrusted-project"}),".\nEach ",(0,s.jsx)(n.code,{children:"project"})," section needs to have the ",(0,s.jsx)(n.code,{children:"default-branch"})," stanza."]}),"\n",(0,s.jsx)(n.h3,{id:"your-logs-are-not-displayed-in-the-web-ui",children:"Your logs are not displayed in the web-UI?"}),"\n",(0,s.jsx)(n.p,{children:"Check, if the IP of the logfile server is really correct. In combination with GitHub there is a\nbug which keeps the GitHub App posting to the old IP even if the webhook IP was changed. Current\nworkaround: Delete the old GitHub App and create a new one."}),"\n",(0,s.jsx)(n.h3,{id:"hanging-jobs-in-a-pipeline",children:"Hanging jobs in a pipeline?"}),"\n",(0,s.jsx)(n.p,{children:"Sometimes jobs get stuck in a pipeline and are never scheduled. They must then be removed manually\nso that they do not block other jobs."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Hanging jobs in a pipeline",src:o(85723).A+"",width:"774",height:"588"})}),"\n",(0,s.jsxs)(n.p,{children:["First create a local ",(0,s.jsx)(n.code,{children:".zuul.conf"})," configuration file in your home directory."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",metastring:'title="$HOME/.zuul.conf"'})}),"\n",(0,s.jsxs)(n.p,{children:["[osism]\nurl=",(0,s.jsx)(n.a,{href:"https://zuul.services.betacloud.xyz/",children:"https://zuul.services.betacloud.xyz/"}),"\nauth_token=TOKEN\ntenant=osism"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"\nThe required auth token can be generated on the Zuul control node with the `zuul-admin` client.\n\n"})}),"\n",(0,s.jsx)(n.p,{children:"docker exec -it zuul_scheduler zuul-admin create-auth-token --user USER --tenant osism --expires-in 3600 --auth-config zuul_operator"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"\nWith the [zuul-client](https://zuul-ci.org/docs/zuul-client/index.html) it is possible to\nremove the two hanging jobs from the screenshot.\n\n"})}),"\n",(0,s.jsx)(n.p,{children:"zuul-client --use-config osism dequeue --pipeline periodic-daily --project osism/k8s-capi-images --ref refs/heads/main\nzuul-client --use-config osism dequeue --pipeline periodic-daily --project osism/cfg-generics --ref refs/heads/main"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"\n## Important daily CI jobs\n\n* [osism/container-image-ceph-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-ceph-ansible&pipeline=periodic-daily&skip=0)\n* [osism/container-image-kolla-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-kolla-ansible&pipeline=periodic-daily&skip=0)\n* [osism/container-image-osism-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-osism-ansible&pipeline=periodic-daily&skip=0)\n* [osism/container-images-kolla](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-images-kolla&pipeline=periodic-midnight&skip=0)\n* [osism/testbed](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Ftestbed&pipeline=periodic-daily&skip=0)\n"})})]})}function c(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},85723:(e,n,o)=>{o.d(n,{A:()=>i});const i=o.p+"assets/images/zuul-hanging-jobs-in-a-pipeline-047d29fda9946dd80cebb88778249bce.png"},28453:(e,n,o)=>{o.d(n,{R:()=>r,x:()=>l});var i=o(96540);const s={},t=i.createContext(s);function r(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9e156860.6bfbfbb9.js b/assets/js/9e156860.6bfbfbb9.js new file mode 100644 index 0000000000..c9fcaaca42 --- /dev/null +++ b/assets/js/9e156860.6bfbfbb9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[63811],{78356:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"scs-0219-v1-kaas-networking","title":"KaaS Networking Standard","description":"Introduction","source":"@site/standards/scs-0219-v1-kaas-networking.md","sourceDirName":".","slug":"/scs-0219-v1-kaas-networking","permalink":"/standards/scs-0219-v1-kaas-networking","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"KaaS Networking Standard","type":"Standard","status":"Stable","stabilized_at":"2024-11-21T00:00:00.000Z","track":"KaaS"},"sidebar":"standards","previous":{"title":"scs-0219: KaaS Networking Standard","permalink":"/standards/kaas/scs-0219"},"next":{"title":"W1","permalink":"/standards/scs-0219-w1-kaas-networking"}}');var s=t(74848),r=t(28453);const o={title:"KaaS Networking Standard",type:"Standard",status:"Stable",stabilized_at:new Date("2024-11-21T00:00:00.000Z"),track:"KaaS"},a=void 0,c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"NetworkPolicy API",id:"networkpolicy-api",level:4},{value:"Default Network Policies in Namespaces",id:"default-network-policies-in-namespaces",level:4},{value:"AdminNetworkPolicy API",id:"adminnetworkpolicy-api",level:4},{value:"Ingress API",id:"ingress-api",level:4},{value:"Decision",id:"decision",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function d(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"Kubernetes defines a networking model that needs to be implemented by a separate CNI plugin.\nBeyond basic connectivity within the cluster, however, there are many networking features that are specified but optional.\nSome of these optional features provide vital functionality, such as the NetworkPolicy API and the Ingress API."}),"\n",(0,s.jsx)(n.p,{children:"This standard specifies a minimal set of networking features that users can expect in clusters created by an SCS-compliant KaaS provider."}),"\n",(0,s.jsx)(n.h2,{id:"terminology",children:"Terminology"}),"\n",(0,s.jsx)(n.p,{children:"The following terms are used throughout this document:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Term"}),(0,s.jsx)(n.th,{children:"Meaning"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"KaaS, managed Kubernetes"}),(0,s.jsx)(n.td,{children:"Kubernetes as a Service, automated on-demand deployment of Kubernetes clusters."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"CSP"}),(0,s.jsx)(n.td,{children:"Cloud Service Provider, the provider of the KaaS infrastructure."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"CNI"}),(0,s.jsx)(n.td,{children:"Container Network Interface, a standardized networking interface for container runtimes."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"CNI plugin, networking plugin"}),(0,s.jsx)(n.td,{children:"Kubernetes bindings for a CNI implementation, translates Kubernetes API concepts into more basic container networking concepts."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"network policy"}),(0,s.jsx)(n.td,{children:"A set of rules to restrict network traffic in a Kubernetes cluster."})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(n.p,{children:"KaaS providers will typically support aditional networking functionality beyond basic Kubernetes networking.\nThe specific range of features depends on the used CNI plugin, but may also be extended by additional operators.\nUsers may expect certain optional functionality, so we should define a baseline feature set that has to be available in an SCS-compliant KaaS cluster."}),"\n",(0,s.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsxs)(n.p,{children:["The Kubernetes API can be extended arbitrarily.\nMany CNI plugins will define custom resources to enable functionality that is not covered in the official ",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/",children:"API specification"}),".\nSometimes they will even reuse names from different API groups, such as ",(0,s.jsx)(n.code,{children:"NetworkPolicy"}),", which exists in the basic ",(0,s.jsx)(n.code,{children:"networking.k8s.io/v1"})," API, but also in ",(0,s.jsx)(n.code,{children:"projectcalico.org/v3"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"To avoid any ambiguity, we should therefore be explicit about the API groups and versions of resources.\nWe should also avoid mandating third-party API extensions, to avoid dependencies on specific third-party software and keep the standard as generic as possible."}),"\n",(0,s.jsx)(n.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,s.jsx)(n.h4,{id:"networkpolicy-api",children:"NetworkPolicy API"}),"\n",(0,s.jsx)(n.p,{children:"Kubernetes network policies are used to restrict network traffic between pods in a cluster, but also between pods and external network resources.\nThe policy rules can filter based on port and address ranges, but also on Kubernetes-specific target attributes such as namespaces and labels.\nThey must be implemented by the CNI plugin, and though they are widely supported, they are still technically optional, and there are some lightweight networking plugins, such as Flannel, that are not enforcing them."}),"\n",(0,s.jsx)(n.p,{children:"Nonetheless, network policies are widely used and most users will expect them in a managed Kubernetes cluster.\nThe wide, but varying support among CNI plugins makes them a good target for SCS standardization."}),"\n",(0,s.jsx)(n.h4,{id:"default-network-policies-in-namespaces",children:"Default Network Policies in Namespaces"}),"\n",(0,s.jsx)(n.p,{children:"Basic network policies are namespaced resources, and can only filter traffic to and from pods in their own namespace.\nIn a newly created namespace without policies the default behavior will apply, which is to not restrict traffic at all."}),"\n",(0,s.jsx)(n.p,{children:"It can be desirable to automatically create default network policies in new namespaces, using a policy operator such as Kyverno.\nA CSP could provide such an operator and offer a number of default policies, like blocking connections to other namespaces by default, or blocking access to the OpenStack metadata service."}),"\n",(0,s.jsx)(n.p,{children:"Any user with permissions to manage their own network policies in a namespace will of course be able to remove or modify any default network policies in that namespace.\nCSP-provided network policies should thus only be viewed as a safety default, and should only be deployed if they are actually beneficial to users."}),"\n",(0,s.jsx)(n.h4,{id:"adminnetworkpolicy-api",children:"AdminNetworkPolicy API"}),"\n",(0,s.jsxs)(n.p,{children:["An alternative to automatically created default network policies are API extensions that allow cluster-wide networking rules.\nSome CNI plugins have implemented such extensions, e.g. Calico's ",(0,s.jsx)(n.code,{children:"GlobalNetworkPolicy"})," and Cilium's ",(0,s.jsx)(n.code,{children:"CiliumClusterwideNetworkPolicy"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The Kubernetes Network Special Interest Group is currently working on an ",(0,s.jsx)(n.a,{href:"https://network-policy-api.sigs.k8s.io/api-overview/",children:"official API extension"})," to cover this functionality.\nThis API extension introduces the new ",(0,s.jsx)(n.code,{children:"AdminNetworkPolicy"})," and ",(0,s.jsx)(n.code,{children:"BaselineAdminNetworkPolicy"})," resources, which represent cluster-wide network policies with respectively higher or lower precedence than namespaced network policies."]}),"\n",(0,s.jsx)(n.p,{children:"This API is also a good candidate for standardization because it consolidates a number of vendor-specific workarounds to limitations of the NetworkPolicy API.\nIt has not been stabilized yet, so currently we can at most recommend CNI plugins where there is ongoing work to support these features."}),"\n",(0,s.jsx)(n.h4,{id:"ingress-api",children:"Ingress API"}),"\n",(0,s.jsxs)(n.p,{children:["The Ingress API allows the external exposure of HTTP/HTTPS-based services running in the cluster.\nUnlike the L3/L4-based LoadBalancer Service type, Ingress provides L7 load balancing, HTTP routing, and TLS termination for services.\nThis functionality can be provided within the cluster by a pod-based ingress controller such as ",(0,s.jsx)(n.code,{children:"ingress-nginx"}),", that exposes Ingress resources as Services."]}),"\n",(0,s.jsx)(n.p,{children:"However, there are also Ingress controllers that integrate with underlying infrastructure and may help to reduce overhead.\nExamples for this are the Cilium CNI plugin, which comes with built-in Ingress support, and the Octavia Ingress controller, which may be a good choice if OpenStack Octavia is already used to provide L3/L4 load balancing."}),"\n",(0,s.jsxs)(n.p,{children:["The CSPs that manage the underlying infrastructure can of course make the best choice for such an integrated Ingress controller, so they should be encouraged to do so.\nEven with a CSP-provided default Ingress controller present, users will be able to use alternative Ingress controllers by creating a new ",(0,s.jsx)(n.code,{children:"IngressClass"}),", which can then be referenced in Ingress resources."]}),"\n",(0,s.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsxs)(n.p,{children:["CSPs MUST provide a network plugin that fully supports ",(0,s.jsx)(n.code,{children:"NetworkPolicy"})," resources in the API version ",(0,s.jsx)(n.code,{children:"networking.k8s.io/v1"}),".\nCSPs SHOULD provide a network plugin that supports or is working on support for the ",(0,s.jsx)(n.code,{children:"AdminNetworkPolicy"})," and ",(0,s.jsx)(n.code,{children:"BaselineAdminNetworkPolicy"})," resources of the ",(0,s.jsx)(n.code,{children:"policy.networking.k8s.io"})," API group, in their latest version, up to ",(0,s.jsx)(n.code,{children:"v1"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["CSPs SHOULD offer the option for a managed, ",(0,s.jsx)(n.code,{children:"networking.k8s.io/v1"}),"-compliant Ingress controller and a default ",(0,s.jsx)(n.code,{children:"IngressClass"})," resource for this controller."]}),"\n",(0,s.jsxs)(n.p,{children:["CSPs MAY add default networking restrictions, using either ",(0,s.jsx)(n.code,{children:"networking.k8s.io/v1"}),"-compliant ",(0,s.jsx)(n.code,{children:"NetworkPolicy"})," resources with a policy operator, or alternatively any cluster-wide network policy extensions provided by the CNI plugin."]}),"\n",(0,s.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsx)(n.p,{children:"Required support for network policies will be tested using the upstream e2e tests via Sonobuoy."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var i=t(96540);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9e4087bc.adb8dec7.js b/assets/js/9e4087bc.adb8dec7.js new file mode 100644 index 0000000000..3589d8ae0e --- /dev/null +++ b/assets/js/9e4087bc.adb8dec7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[52711],{89331:(e,r,t)=>{t.r(r),t.d(r,{default:()=>m});t(96540);var a=t(28774),n=t(21312),s=t(61213),i=t(36266),c=t(59504),l=t(51107),o=t(74848);function d(e){let{year:r,posts:t}=e;const n=(0,i.i)({day:"numeric",month:"long",timeZone:"UTC"});return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(l.A,{as:"h3",id:r,children:r}),(0,o.jsx)("ul",{children:t.map((e=>{return(0,o.jsx)("li",{children:(0,o.jsxs)(a.A,{to:e.metadata.permalink,children:[(r=e.metadata.date,n.format(new Date(r)))," - ",e.metadata.title]})},e.metadata.date);var r}))})]})}function h(e){let{years:r}=e;return(0,o.jsx)("section",{className:"margin-vert--lg",children:(0,o.jsx)("div",{className:"container",children:(0,o.jsx)("div",{className:"row",children:r.map(((e,r)=>(0,o.jsx)("div",{className:"col col--4 margin-vert--lg",children:(0,o.jsx)(d,{...e})},r)))})})})}function m(e){let{archive:r}=e;const t=(0,n.T)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),a=(0,n.T)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),i=function(e){const r=e.reduce(((e,r)=>{const t=r.metadata.date.split("-")[0],a=e.get(t)??[];return e.set(t,[r,...a])}),new Map);return Array.from(r,(e=>{let[r,t]=e;return{year:r,posts:t}}))}(r.blogPosts);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.be,{title:t,description:a}),(0,o.jsxs)(c.A,{children:[(0,o.jsx)("header",{className:"hero hero--primary",children:(0,o.jsxs)("div",{className:"container",children:[(0,o.jsx)(l.A,{as:"h1",className:"hero__title",children:t}),(0,o.jsx)("p",{className:"hero__subtitle",children:a})]})}),(0,o.jsx)("main",{children:i.length>0&&(0,o.jsx)(h,{years:i})})]})]})}},36266:(e,r,t)=>{t.d(r,{i:()=>n});var a=t(44586);function n(e){void 0===e&&(e={});const{i18n:{currentLocale:r}}=(0,a.A)(),t=function(){const{i18n:{currentLocale:e,localeConfigs:r}}=(0,a.A)();return r[e].calendar}();return new Intl.DateTimeFormat(r,{calendar:t,...e})}}}]); \ No newline at end of file diff --git a/assets/js/9f356e5b.ee373634.js b/assets/js/9f356e5b.ee373634.js new file mode 100644 index 0000000000..62d9cd36ff --- /dev/null +++ b/assets/js/9f356e5b.ee373634.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[91844],{24573:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>n,toc:()=>u});const n=JSON.parse('{"id":"iaas/overview/architecture","title":"Architecture","description":"TODO","source":"@site/docs/02-iaas/overview/architecture.md","sourceDirName":"02-iaas/overview","slug":"/iaas/overview/architecture","permalink":"/docs/iaas/overview/architecture","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/overview/architecture.md","tags":[],"version":"current","frontMatter":{}}');var c=r(74848),o=r(28453);const s={},i="Architecture",a={},u=[];function d(e){const t={h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(t.header,{children:(0,c.jsx)(t.h1,{id:"architecture",children:"Architecture"})}),"\n",(0,c.jsx)(t.p,{children:"TODO"})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>s,x:()=>i});var n=r(96540);const c={},o=n.createContext(c);function s(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9f357fc0.0bb06e82.js b/assets/js/9f357fc0.0bb06e82.js new file mode 100644 index 0000000000..d819c74d58 --- /dev/null +++ b/assets/js/9f357fc0.0bb06e82.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[83292],{99590:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","title":"Getting Started","description":"Quickstart","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/topics","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview"},"next":{"title":"Troubleshooting","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot"}}');var n=s(74848),c=s(28453);const a={},o="Getting Started",i={},l=[{value:"Quickstart",id:"quickstart",level:2},{value:"Installation",id:"installation",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Cluster API",id:"cluster-api",level:4},{value:"Configure Release Source",id:"configure-release-source",level:3},{value:"Using GitHub Releases",id:"using-github-releases",level:4},{value:"Using OCI Registry",id:"using-oci-registry",level:4},{value:"Install Cluster Stack Operator",id:"install-cluster-stack-operator",level:3},{value:"Install by manifest",id:"install-by-manifest",level:4},{value:"Enable OCI registry as source",id:"enable-oci-registry-as-source",level:5},{value:"Install with Helm (experimental)",id:"install-with-helm-experimental",level:4}];function u(e){const t={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",p:"p",pre:"pre",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"getting-started",children:"Getting Started"})}),"\n",(0,n.jsx)(t.h2,{id:"quickstart",children:"Quickstart"}),"\n",(0,n.jsxs)(t.p,{children:["Currently, there is a ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks-demo",children:"demo"})," that can be used to see how the Cluster Stack approach can work. It uses the Docker Provider Integration for Cluster API."]}),"\n",(0,n.jsx)(t.h2,{id:"installation",children:"Installation"}),"\n",(0,n.jsx)(t.h3,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"- clusterctl\n- envsubst\n- kubectl\n- Helm (optional)\n"})}),"\n",(0,n.jsx)(t.h4,{id:"cluster-api",children:"Cluster API"}),"\n",(0,n.jsxs)(t.p,{children:["We assume access to a Kubernetes cluster. To start\n",(0,n.jsx)(t.a,{href:"https://kind.sigs.k8s.io/",children:"kind"})," can be used for that.\nThis Kubernetes cluster must act as Cluster API management cluster.\nIf not already done, to make your Kubernetes cluster a management cluster by\ninstalling the Cluster API objects, you can do"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"clusterctl init\n"})}),"\n",(0,n.jsx)(t.h3,{id:"configure-release-source",children:"Configure Release Source"}),"\n",(0,n.jsx)(t.p,{children:"The Cluster Stack Operator downloads Cluster Stack releases either from GitHub\nReleases or from an OCI registry.\nDepending on which method is preferred, environment variables must be set to\ngive the Cluster Stack Operator access to the specific source."}),"\n",(0,n.jsx)(t.h4,{id:"using-github-releases",children:"Using GitHub Releases"}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsxs)(t.p,{children:["Be aware that GitHub enforces limitations on the number of API requests per\nunit of time. To overcome this, it is recommended to configure a ",(0,n.jsx)(t.a,{href:"https://github.com/settings/personal-access-tokens/new",children:"personal\naccess token"})," for\nauthenticated calls. This will significantly increase the rate limit for GitHub\nAPI requests. Fine grained PAT with ",(0,n.jsx)(t.code,{children:"Public Repositories (read-only)"})," is\nenough."]}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["Following variables tells the Cluster Stack Operator to look for releases in\n",(0,n.jsx)(t.code,{children:"https://github.com/SovereignCloudStack/cluster-stacks"})]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"export GIT_PROVIDER_B64=Z2l0aHVi # github\nexport GIT_ORG_NAME_B64=U292ZXJlaWduQ2xvdWRTdGFjaw== # SovereignCloudStack\nexport GIT_REPOSITORY_NAME_B64=Y2x1c3Rlci1zdGFja3M= # cluster-stacks\nexport GIT_ACCESS_TOKEN_B64=$(echo -n '<my-personal-access-token>' | base64 -w0)\n"})}),"\n",(0,n.jsx)(t.h4,{id:"using-oci-registry",children:"Using OCI Registry"}),"\n",(0,n.jsxs)(t.p,{children:["Following variables tells the Cluster Stack Operator to look for releases in\n",(0,n.jsx)(t.code,{children:"https://registry.scs.community/kaas/cluster-stacks"})]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"export OCI_REGISTRY_B64=cmVnaXN0cnkuc2NzLmNvbW11bml0eQ== # registry.scs.community\nexport OCI_REPOSITORY_B64=cmVnaXN0cnkuc2NzLmNvbW11bml0eS9rYWFzL2NsdXN0ZXItc3RhY2tzCg== # registry.scs.community/kaas/cluster-stacks\n"})}),"\n",(0,n.jsxs)(t.p,{children:["If the registry is not public the Cluster Stack Operator please also provide\n",(0,n.jsx)(t.code,{children:"OCI_USERNAME_B64"})," and ",(0,n.jsx)(t.code,{children:"OCI_PASSWORD_B64"})," or\n",(0,n.jsx)(t.code,{children:"OCI_ACCESS_TOKEN_B64"})]}),"\n",(0,n.jsx)(t.h3,{id:"install-cluster-stack-operator",children:"Install Cluster Stack Operator"}),"\n",(0,n.jsx)(t.h4,{id:"install-by-manifest",children:"Install by manifest"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"# Get the latest CSO release version and apply CSO manifests\ncurl -sSL https://github.com/SovereignCloudStack/cluster-stack-operator/releases/latest/download/cso-infrastructure-components.yaml | envsubst | kubectl apply -f -\n"})}),"\n",(0,n.jsx)(t.h5,{id:"enable-oci-registry-as-source",children:"Enable OCI registry as source"}),"\n",(0,n.jsx)(t.p,{children:"Since GitHub is set as default source for the Cluster Stack releases, this can be changed with a patch:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'kubectl patch deployment -n cso-system cso-controller-manager --type=\'json\' -p=\'[{"op": "replace", "path": "/spec/template/spec/containers/0/command", "value": ["/manager", "-source", "oci"]}]\'\n'})}),"\n",(0,n.jsx)(t.h4,{id:"install-with-helm-experimental",children:"Install with Helm (experimental)"}),"\n",(0,n.jsx)(t.p,{children:"There are simple Helm charts available which were created especially to make the switch between the sources easier."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"helm upgrade -i cso -n cso-system \\\n --create-namespace oci://registry.scs.community/cluster-stacks/cso \\\n --set controllerManager.manager.source=oci \\\n --set clusterStackVariables.ociRepository=registry.scs.community/kaas/cluster-stacks\n"})})]})}function d(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>o});var r=s(96540);const n={},c=r.createContext(n);function a(e){const t=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),r.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a022b847.57572d71.js b/assets/js/a022b847.57572d71.js new file mode 100644 index 0000000000..9987900d67 --- /dev/null +++ b/assets/js/a022b847.57572d71.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[57013],{77946:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stacks/overview","title":"Overview","description":"Cluster Stacks","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stacks/overview.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stacks","slug":"/container/components/cluster-stacks/components/cluster-stacks/overview","permalink":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stacks/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster Stacks","permalink":"/docs/category/cluster-stacks"},"next":{"title":"Overview","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview"}}');var r=s(74848),i=s(28453);const a={},o="Overview",c={},l=[{value:"Cluster Stacks",id:"cluster-stacks",level:2},{value:"\ud83d\udd27 Usage",id:"-usage",level:2},{value:"Layers of a Cluster Stack",id:"layers-of-a-cluster-stack",level:2},{value:"\ud83d\udcda Cluster Class",id:"-cluster-class",level:3},{value:"\ud83c\udf81 Cluster Addons",id:"-cluster-addons",level:3},{value:"\ud83c\udf9e\ufe0f Node Images",id:"\ufe0f-node-images",level:3},{value:"\ud83c\udf10 IaaS Provider, Kubernetes Service Provider, and Cluster API",id:"-iaas-provider-kubernetes-service-provider-and-cluster-api",level:2},{value:"\ud83d\udccc Defining and Adding Providers",id:"-defining-and-adding-providers",level:2},{value:"\ud83d\udcc1 Repository Structure",id:"-repository-structure",level:3},{value:"\ud83d\udcd1 Versioning",id:"-versioning",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(t.h2,{id:"cluster-stacks",children:"Cluster Stacks"}),"\n",(0,r.jsx)(t.p,{children:"Cluster Stacks is a comprehensive framework and reference implementations for defining and managing Kubernetes clusters via the Cluster API. It is designed to cater to multiple providers and supports a broad range of Kubernetes versions, offering a standardized approach to managing and configuring Kubernetes clusters."}),"\n",(0,r.jsx)(t.p,{children:"It encapsulates multiple layers, including node configuration, Cluster API setup, and application-level configurations, such as the Container Network Interface (CNI). By packaging these interdependent configurations, the cluster stack allows for efficient management and deployment of Kubernetes clusters, offering standardized, resilient, and self-managed Kubernetes environments."}),"\n",(0,r.jsx)(t.h2,{id:"-usage",children:"\ud83d\udd27 Usage"}),"\n",(0,r.jsxs)(t.p,{children:["Follow our ",(0,r.jsx)(t.a,{href:"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart",children:"quickstart guide"})," for an introduction on how to deploy cluster stacks on openstack."]}),"\n",(0,r.jsx)(t.h2,{id:"layers-of-a-cluster-stack",children:"Layers of a Cluster Stack"}),"\n",(0,r.jsxs)(t.p,{children:["In essence, a cluster stack is an amalgamation of various components each of which serves a crucial role in setting up, maintaining, and operating a Kubernetes cluster. In the context of our framework, we categorize these components into three core layers: ",(0,r.jsx)(t.code,{children:"cluster-class"}),", ",(0,r.jsx)(t.code,{children:"cluster-addons"}),", and ",(0,r.jsx)(t.code,{children:"node-images"}),". Let's delve deeper into understanding each of these layers:"]}),"\n",(0,r.jsx)(t.h3,{id:"-cluster-class",children:"\ud83d\udcda Cluster Class"}),"\n",(0,r.jsx)(t.p,{children:"The Cluster Class serves as a blueprint for creating and configuring Kubernetes clusters consistently. It encapsulates various aspects of a cluster, including:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"The infrastructure provider details"}),"\n",(0,r.jsx)(t.li,{children:"Networking configurations"}),"\n",(0,r.jsx)(t.li,{children:"Cluster-class templating"}),"\n",(0,r.jsx)(t.li,{children:"Other cluster-specific settings"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Essentially, it defines the desired configuration and properties of a Kubernetes cluster. It leverages the ",(0,r.jsx)(t.a,{href:"https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/",children:"ClusterClass"})," feature of Cluster API, which provides a declarative, Kubernetes-style API for cluster creation, configuration, and management. Any change in this layer or in the node-image or cluster-addon layers triggers a version bump in the cluster class, hence the cluster stack."]}),"\n",(0,r.jsx)(t.h3,{id:"-cluster-addons",children:"\ud83c\udf81 Cluster Addons"}),"\n",(0,r.jsx)(t.p,{children:"Cluster Addons are core components or services required for the Kubernetes cluster to function correctly and efficiently. These are not user-facing applications but rather foundational services critical to the operation and management of a Kubernetes cluster. They're usually installed and configured after the cluster infrastructure has been provisioned and before the cluster is ready to serve workloads."}),"\n",(0,r.jsx)(t.p,{children:"Cluster addons encompass a variety of functionalities, including but not limited to:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Container Network Interfaces (CNI): These are plugins that facilitate container networking. A CNI is integral to setting up network connectivity and ensuring communication between pods in a Kubernetes cluster."}),"\n",(0,r.jsx)(t.li,{children:"Cloud Controller Manager (CCM): The CCM is a Kubernetes control plane component that embeds the cloud-specific control logic. Its role is to manage the communication with the underlying cloud services."}),"\n",(0,r.jsx)(t.li,{children:"Konnectivity service: This is a network proxy that enables connectivity from the control plane to nodes and vice versa. It is a critical component that supports Kubernetes API server connectivity."}),"\n",(0,r.jsx)(t.li,{children:"Metrics Server: A cluster-wide aggregator of resource usage data, Metrics Server collects CPU, memory, and other metrics from nodes and pods, enabling features like Horizontal Pod Autoscaling."}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"It's important to note that cluster addons are not user-provided applications or services that can be installed multiple times, such as ingress controllers, application-level monitoring tools, or user-facing APIs. Those are left to the discretion and responsibility of the users, who install and manage them according to their specific needs and preferences."}),"\n",(0,r.jsx)(t.p,{children:"Each addon version is independent and can be updated separately. However, a change in this layer also necessitates a version bump in the cluster class and the cluster stack, which is reflected in the metadata.yaml."}),"\n",(0,r.jsx)(t.h3,{id:"\ufe0f-node-images",children:"\ud83c\udf9e\ufe0f Node Images"}),"\n",(0,r.jsx)(t.p,{children:"Node images provide the foundation for the operating system environment on each node of a Kubernetes cluster. They are typically a minimal operating system distribution, like a lightweight Linux distro, which may also include container runtime components such as Docker or containerd."}),"\n",(0,r.jsx)(t.p,{children:"Node images are responsible for providing the necessary environment and dependencies to support Kubernetes components and workloads. This includes components like kubelet, kube-proxy, and other necessary system utilities and libraries."}),"\n",(0,r.jsx)(t.p,{children:"The version of a node image can be different from that of the cluster stack or the cluster class. However, an update to a node image will trigger a version bump in the cluster class and hence the cluster stack."}),"\n",(0,r.jsx)(t.p,{children:"In the cluster-stacks repository's directory structure, the build instructions for Node Images are always placed within the respective directory. The instructions outline the steps and configurations required to create the Node Image automatically. The specific method for releasing the Node Image may vary based on the provider's capabilities and requirements."}),"\n",(0,r.jsx)(t.p,{children:"During the development phase, the build instructions serve as a reference within the repository itself. These instructions may utilize tools like Packer or other image-building techniques. This allows for flexibility and customization, enabling users to define their Node Images according to specific needs and requirements."}),"\n",(0,r.jsx)(t.p,{children:"However, when it comes to the release of the cluster stack, the Node Image can be provided in different ways depending on the capabilities of the provider or the desired deployment method. Here are a few examples:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"URL on a remote endpoint"}),": In some cases, ",(0,r.jsx)(t.code,{children:"providers"})," may support deploying a Node Image directly from a URL. In this scenario, the Node Image referenced in the ",(0,r.jsx)(t.code,{children:"cluster stack"}),", specifically in the ",(0,r.jsx)(t.code,{children:"cluster class"}),", would be provided as a URL pointing to a pre-built image accessible remotely."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Artifact"}),": If the provider supports artifacts, the Node Image can be released as an artifact, such as a qcow2 file. The artifact would be uploaded to the provider, and the ",(0,r.jsx)(t.code,{children:"cluster stack"})," references the artifact for node provisioning."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Build Instructions"}),": In cases where the provider doesn't support direct URL deployment or artifact-based provisioning, the build instructions defined within the repository become critical. The build instructions serve as a comprehensive guide to build the Node Image, specifying all the necessary steps and configurations."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"Regardless of the release method, the cluster stack, specifically the cluster class, references the appropriate Node Image to be used for node provisioning."}),"\n",(0,r.jsx)(t.p,{children:"By allowing flexibility in the release and deployment methods of Node Images, the cluster stack framework caters to various provider capabilities and user requirements. This adaptability ensures the cluster stack can be deployed in diverse environments while maintaining a consistent and manageable approach to managing Kubernetes clusters."}),"\n",(0,r.jsx)(t.h2,{id:"-iaas-provider-kubernetes-service-provider-and-cluster-api",children:"\ud83c\udf10 IaaS Provider, Kubernetes Service Provider, and Cluster API"}),"\n",(0,r.jsxs)(t.p,{children:["In the context of the ",(0,r.jsx)(t.code,{children:"cluster-stacks"}),", we distinguish between two types of providers:"]}),"\n",(0,r.jsxs)(t.p,{children:["An ",(0,r.jsx)(t.strong,{children:"IaaS Provider"}),", in general, offers Infrastructure as a Service - providing the fundamental compute, storage, and network resources on which workloads can be run. In the context of cluster-stacks, an IaaS Provider specifically refers to an entity that owns an API for their infrastructure. If an organization uses a common infrastructure API, such as OpenStack, they are not considered an IaaS Provider in this context. However, if the organization owns the API for its infrastructure, it becomes an IaaS Provider for the purposes of cluster-stacks."]}),"\n",(0,r.jsxs)(t.p,{children:["A ",(0,r.jsx)(t.strong,{children:"Kubernetes Service Provider"}),", on the other hand, is an entity that implements a cluster stack. They do so on top of the IaaS Providers, potentially spanning across multiple IaaS Providers. They use the IaaS Provider's infrastructure services and integrate them into their cluster stack implementations."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.strong,{children:"Cluster API (CAPI)"})," is a Kubernetes project aimed at simplifying the process of managing Kubernetes clusters. It offers a declarative API that automates the creation, configuration, and management of clusters, providing a standardized way to interact with Kubernetes. The cluster stack approach leverages CAPI to deliver self-managed Kubernetes clusters."]}),"\n",(0,r.jsx)(t.h2,{id:"-defining-and-adding-providers",children:"\ud83d\udccc Defining and Adding Providers"}),"\n",(0,r.jsx)(t.p,{children:"The structure of this repository is specifically designed to handle multiple providers, multiple cluster stacks per provider, and multiple Kubernetes versions per cluster stack. This organized structure allows us to effectively manage, develop, and maintain multiple cluster stacks across various Kubernetes versions and providers, all in a single repository."}),"\n",(0,r.jsx)(t.h3,{id:"-repository-structure",children:"\ud83d\udcc1 Repository Structure"}),"\n",(0,r.jsx)(t.p,{children:"The repository maintains a specific structure:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Each IaaS Provider has a directory under providers."}),"\n",(0,r.jsx)(t.li,{children:"Each IaaS Provider can have multiple cluster stack implementations."}),"\n",(0,r.jsx)(t.li,{children:"Each cluster stack supports multiple Kubernetes major and minor versions."}),"\n"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"providers/\n\u2514\u2500\u2500 <provider_name>/\n \u2514\u2500\u2500 <cluster_stack_name>/\n \u2514\u2500\u2500 <k8s_major_minor_version>/\n"})}),"\n",(0,r.jsx)(t.p,{children:"The directory structure for adding a new provider would look something like this:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"providers/<provider_name>/<cluster_stack_name>/<k8s_major_minor_version>\n# example\nproviders/openstack/scs/1-28\n"})}),"\n",(0,r.jsx)(t.p,{children:"This granular, hierarchical structure allows us to manage different versions of Kubernetes and their associated cluster stacks across different providers."}),"\n",(0,r.jsx)(t.p,{children:"We decided to support multiple Kubernetes major and minor versions to provide the flexibility to accommodate different implementation requirements of the provider. However, we deliberately chose not to support Kubernetes patch versions directly. The reason is the high frequency of patch versions release (often weekly), which would complicate maintenance efforts significantly."}),"\n",(0,r.jsx)(t.p,{children:"Instead, we represent Kubernetes patch version updates through changes in our cluster stack version. For instance, if a patch version of Kubernetes necessitates a change in the node-image or the cluster-class configuration, this would trigger a version bump in the corresponding cluster stack, hence the cluster class, as reflected in the metadata.yaml."}),"\n",(0,r.jsx)(t.p,{children:"In this way, our versioning system, our directory structure, and our approach to Kubernetes versioning are all interlinked, providing us a comprehensive, manageable, and resilient framework for maintaining various Kubernetes distributions or cluster stacks across multiple providers and versions."}),"\n",(0,r.jsx)(t.h2,{id:"-versioning",children:"\ud83d\udcd1 Versioning"}),"\n",(0,r.jsxs)(t.p,{children:["Note: This section is subject to change, as our new tool ",(0,r.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/csctl",children:"csctl"})," will incorporate future versioning capabilities."]}),"\n",(0,r.jsx)(t.p,{children:"A fundamental aspect of the cluster stack approach is the encapsulation of versioning within a cluster stack distribution. Each of the components can be updated independently, leading to a flexible and maintainable system."}),"\n",(0,r.jsx)(t.p,{children:"However, the critical point to understand here is the relationship between these component versions and the cluster stack version. Whenever there's a change or an update to either the cluster addon or the node image, the version of the cluster stack must be bumped. And due to the connection between the cluster class and the cluster stack, the cluster class version must be updated to match the new cluster stack version."}),"\n",(0,r.jsx)(t.p,{children:'The cluster stack version doesn\'t simply mirror the versions of its components, but rather, it reflects the "version of change". In essence, the cluster stack version is a reflection of the state of the entire stack as a whole at a particular point in time. Any change in the components warrants a new state, and therefore a new version of the cluster stack.'}),"\n",(0,r.jsx)(t.p,{children:"So, an update to the cluster addon component will bump the version of the cluster stack, irrespective of the existing version of the node image. The same applies vice versa. When such an update occurs, the version of the cluster class is also incremented to align with the new cluster stack version, maintaining the unity of the cluster stack framework."}),"\n",(0,r.jsx)(t.p,{children:"This versioning approach ensures a clear and precise track of changes, promoting efficient management, and isolated testing. It offers enhanced resilience for the Kubernetes distribution or the cluster stack, ensuring safe and secure upgrades even in rapid update cycles. It's an efficient method of maintaining stability in the rapidly changing environment of a Kubernetes stack."}),"\n",(0,r.jsx)(t.p,{children:"The versioning of the cluster stack is primarily managed through a file named metadata.yaml, located at the root directory of each cluster stack. This file serves as the source of truth for the versioning information of the cluster stack, cluster class, node images, and cluster addons."}),"\n",(0,r.jsx)(t.p,{children:"Here is an example of how metadata.yaml could look like:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"apiVersion: metadata.clusterstack.x-k8s.io/v1alpha1\nversions:\n clusterStack: v3\n kubernetes: v1.27.3\n components:\n clusterAddon: v2\n nodeImage: v1\n"})}),"\n",(0,r.jsx)(t.p,{children:"In this example, the cluster stack (and thus the cluster class) is on version 3, while the cluster addon is on version 2 and node image is on version 1."}),"\n",(0,r.jsx)(t.p,{children:"When there's a change or update in the node images or cluster addons, we would bump the version of the cluster stack and cluster class, while leaving the unaffected component's version intact. So if the node image was updated, the metadata.yaml might then look like this:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"apiVersion: metadata.clusterstack.x-k8s.io/v1alpha1\nversions:\n clusterStack: v4\n kubernetes: v1.27.3\n components:\n clusterAddon: v2\n nodeImage: v2\n"})}),"\n",(0,r.jsx)(t.p,{children:"Here, the cluster stack and cluster class versions were updated to v4, the node image version was bumped to v2 due to the changes, while the cluster addon remained on v2 as it was not affected by the update."}),"\n",(0,r.jsx)(t.p,{children:"This versioning approach allows us to keep track of changes across different components, manage these components effectively, and conduct isolated testing. This ensures that our Kubernetes distribution or cluster stack remains resilient, and we can perform safe and secure upgrades even in the face of rapid update cycles. The metadata.yaml plays a critical role in maintaining this structure and providing an accurate representation of the state of the whole stack at any given time."})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>o});var n=s(96540);const r={},i=n.createContext(r);function a(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a0b1bbd7.edd55850.js b/assets/js/a0b1bbd7.edd55850.js new file mode 100644 index 0000000000..bad7c42277 --- /dev/null +++ b/assets/js/a0b1bbd7.edd55850.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7984],{29817:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"releases/Release5","title":"Release Notes for SCS Release 5","description":"(Release Date: 2023-09-20)","source":"@site/docs/06-releases/Release5.md","sourceDirName":"06-releases","slug":"/releases/Release5","permalink":"/docs/releases/Release5","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release5.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Release Notes for SCS Release 4","permalink":"/docs/releases/Release4"},"next":{"title":"Release Notes for SCS Release 6","permalink":"/docs/releases/Release6"}}');var i=n(74848),r=n(28453);const a={},o="Release Notes for SCS Release 5",l={},d=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"IaaS",id:"iaas",level:3},{value:"Container Management",id:"container-management",level:3},{value:"Preview: Cluster-Stacks",id:"preview-cluster-stacks",level:3},{value:"Operations and IAM related",id:"operations-and-iam-related",level:3},{value:"SCS Developer focused improvements (Cloud-in-a-Box, testbed and k8s cluster management)",id:"scs-developer-focused-improvements-cloud-in-a-box-testbed-and-k8s-cluster-management",level:3},{value:"Project Infrastructure",id:"project-infrastructure",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Deprecations via OSISM",id:"deprecations-via-osism",level:3},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Resolved Issues",id:"resolved-issues",level:2},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R5",id:"list-of-known-issues--restrictions-in-r5",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Thanks",id:"thanks",level:2}];function c(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"release-notes-for-scs-release-5",children:"Release Notes for SCS Release 5"})}),"\n",(0,i.jsx)(s.p,{children:"(Release Date: 2023-09-20)"}),"\n",(0,i.jsx)(s.h2,{id:"scope",children:"Scope"}),"\n",(0,i.jsx)(s.p,{children:"Just as our previous release, Release 5 has been developed alongside a set of associated outcomes.\nThese outcomes are comprised of:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"SCS is standardized"}),"\n",(0,i.jsx)(s.li,{children:"SCS is understandable"}),"\n",(0,i.jsx)(s.li,{children:"SCS is transparent"}),"\n",(0,i.jsx)(s.li,{children:"SCS is continuously built and tested"}),"\n",(0,i.jsx)(s.li,{children:"SCS is opinionated"}),"\n",(0,i.jsx)(s.li,{children:"SCS enables"}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,i.jsx)(s.h3,{id:"iaas",children:"IaaS"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["The IaaS reference implementation is based on ",(0,i.jsx)(s.a,{href:"https://release.osism.tech/notes/6.0.0.html",children:"OSISM 6.0.0"}),"."]}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://releases.openstack.org/antelope/highlights.html",children:"OpenStack 2023.1 (Antelope)"})}),"\n",(0,i.jsxs)(s.li,{children:["Default Ceph version is now ",(0,i.jsx)(s.a,{href:"https://docs.ceph.com/en/reef/releases/quincy/#v17-2-5-quincy",children:"Ceph Quincy"}),"."]}),"\n",(0,i.jsx)(s.li,{children:"OVN and OVS have been updated to their latest versions (OVN: 23.06.1, OVS: 3.2.0)."}),"\n",(0,i.jsx)(s.li,{children:"IPv6 east-west and north-south support is present and documented upstream."}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://github.com/osism/cloud-in-a-box",children:"Cloud-in-a-Box"})," now comes with Swift enabled as well as the option\nfor secondary NIC for external connectivity."]}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"container-management",children:"Container Management"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["The Kubernetes Cluster Management solution is ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R5.md",children:"available as version 6.0.0"})]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://github.com/kubernetes/kubernetes",children:"Kubernetes"})," v1.24 .. ",(0,i.jsx)(s.a,{href:"https://github.com/kubernetes/kubernetes/releases/tag/v1.27.6",children:"1.27"})," are officially supported. ",(0,i.jsx)(s.a,{href:"https://github.com/kubernetes/kubernetes/releases/tag/v1.28.2",children:"v1.28"})," also works (technical preview until officially supported by capo) as do older versions (with downgrading nginx-ingress), matching OCCM and CSI versions."]}),"\n",(0,i.jsx)(s.li,{children:"Cluster-API (capi) v1.5.1, Cluster-API provider for Openstack (capo) v0.7.3"}),"\n",(0,i.jsx)(s.li,{children:"The node images now use Ubuntu 22.04, the management host can use Ubuntu 22.04 or Debian 12."}),"\n",(0,i.jsx)(s.li,{children:"Cilium v1.14.1, default now, though Calico (3.26.x) is still supported."}),"\n",(0,i.jsx)(s.li,{children:"Cilium also brings the upcoming gateway API (opt-in) as technical preview."}),"\n",(0,i.jsx)(s.li,{children:"The Harbor container registry can now be rolled out with each cluster."}),"\n",(0,i.jsx)(s.li,{children:"The clusters can use a registry as cache to upstream dockerhub or gcr registries."}),"\n",(0,i.jsx)(s.li,{children:"The cluster management now works also on OpenStack clouds with a custom CA."}),"\n",(0,i.jsx)(s.li,{children:"Storage snapshots are supported now (fix was also backported to maintained branches)."}),"\n",(0,i.jsx)(s.li,{children:"Diskless flavors are supported everywhere (cluster-management, health-monitor)."}),"\n",(0,i.jsx)(s.li,{children:"etcd defragmentation and backup."}),"\n",(0,i.jsx)(s.li,{children:"Controls for pod and service IP ranges."}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"preview-cluster-stacks",children:"Preview: Cluster-Stacks"}),"\n",(0,i.jsxs)(s.p,{children:["The old scripts that are used to create, change and delete Kubernetes clusters with\nCluster API will be replaced by a proper Operator in the next release. A description can be found at the\n",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks",children:"cluster-stacks"}),"\nand ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator",children:"cluster-stack-operator"}),"\nrepositories. The technical preview can be tried with the ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks-demo",children:"cluster-stacks-demo"}),".\nThis solution will fit more nicely into the CNCF landscape and\nalso allow for easier support of IaaS solutions that do not comply to our SCS\nIaaS standards."]}),"\n",(0,i.jsx)(s.h3,{id:"operations-and-iam-related",children:"Operations and IAM related"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"A number of improvements when using identity federation via OIDC has been added, including\naddressing openstack CLI usage with PKCE Device Authz Grant, logout, and the usage of a\nproxy realm in keycloak. Improvements have been contributed to upstream keystone."}),"\n",(0,i.jsxs)(s.li,{children:["With the ",(0,i.jsx)(s.code,{children:"openstack-resource-manager"})," a new day 2 operations tool has been added.\nFurthermore an osism role for tuned to optimize system profiles is now present."]}),"\n",(0,i.jsxs)(s.li,{children:["The ",(0,i.jsx)(s.a,{href:"https://github.com/osism/openstack-flavor-manager",children:"openstack-flavor-manager"})," is now able to create all standard, mandatory SCS flavors for you."]}),"\n",(0,i.jsx)(s.li,{children:"Scaphandre Prometheus Exporter has been added to export power consumption metrics more easily."}),"\n",(0,i.jsx)(s.li,{children:"To optimize system profiles an osism role for tuned is now present."}),"\n",(0,i.jsx)(s.li,{children:"Full support for air-gapped installation and operation of environments."}),"\n",(0,i.jsx)(s.li,{children:"A migration script and guide for moving from R4 to R5 clusters is available."}),"\n",(0,i.jsx)(s.li,{children:"Metering has been improved and a reference billing API implementation is available as technical preview."}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"scs-developer-focused-improvements-cloud-in-a-box-testbed-and-k8s-cluster-management",children:"SCS Developer focused improvements (Cloud-in-a-Box, testbed and k8s cluster management)"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Documentation on testbed and Cloud-in-a-Box have been reworked."}),"\n",(0,i.jsx)(s.li,{children:"Reflecting CiaB's usage as edge cloud appliance, it now receives more automated testing."}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"project-infrastructure",children:"Project Infrastructure"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"zuul.scs.community now complements OSISM's existing zuul infrastructure and is used also\nby the container layer to execute the CNCF e2e tests."}),"\n",(0,i.jsx)(s.li,{children:"registry.scs.community has been migrated to a new IaaS location (documented in a blog\narticle) and is kept up-to-date now."}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["For the IaaS reference implementation, please refer to the ",(0,i.jsx)(s.a,{href:"https://release.osism.tech/notes/6.0.0.html#upgrade-notes",children:"OSISM 6.0.0 Upgrade Notes"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"removals",children:"Removals"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["Please check the removals for OSISM in the ",(0,i.jsx)(s.a,{href:"https://release.osism.tech/notes/6.0.0.html#removals",children:"upstream removal notices"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["The services ",(0,i.jsx)(s.code,{children:"minio.services.osism.tech"})," and ",(0,i.jsx)(s.code,{children:"harbor.services.osism.tech"})," are deprecated and will be turned of on October 20th, 2023."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,i.jsx)(s.h3,{id:"deprecations-via-osism",children:"Deprecations via OSISM"}),"\n",(0,i.jsxs)(s.p,{children:["For these please also refer to the ",(0,i.jsx)(s.a,{href:"https://release.osism.tech/notes/6.0.0.html#deprecations",children:"upstream deprecation notices"}),"."]}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["It is again noted that the old scripts of the form ",(0,i.jsx)(s.code,{children:"osism-"})," will be removed in the future.\nA note has been added to the scripts showing this when they are executed."]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"The following services are deprecated and will be removed with R6 (OSISM 6.1.0):"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Patchman"}),"\n",(0,i.jsx)(s.li,{children:"Adminer"}),"\n",(0,i.jsx)(s.li,{children:"Patchman Client"}),"\n",(0,i.jsx)(s.li,{children:"Virtualbmc"}),"\n",(0,i.jsx)(s.li,{children:"Bird"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,i.jsx)(s.p,{children:"Throughout the Release 5 development cycle, the SCS project issued two security advisories for upstream components:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["In April 2023 an advisory in Open vSwitch (OvS) (",(0,i.jsx)(s.a,{href:"https://cve.report/CVE-2023-1668",children:"CVE-2023-1668"})," was issued.\nOur ",(0,i.jsx)(s.a,{href:"https://scs.community/security/2023/04/21/cve-2023-1668/",children:"advisory"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["In May 2023 an advisory affecting the OpenStack component Cinder (",(0,i.jsx)(s.a,{href:"https://cve.report/CVE-2023-2088",children:"CVE-2023-2088"}),") was issued.\nOur ",(0,i.jsx)(s.a,{href:"https://scs.community/security/2023/05/10/cve-2023-2088/",children:"advisory"}),"."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"resolved-issues",children:"Resolved Issues"}),"\n",(0,i.jsx)(s.p,{children:"Numerous minor issue have been resolved. The most important steps on the IaaS side probably being the move to ceph Quincy\nto avoid running out of upstream support. On the container side, the fix of storage snapshots is probably most significant."}),"\n",(0,i.jsxs)(s.p,{children:["For details, we again refer to the ",(0,i.jsx)(s.a,{href:"https://release.osism.tech/notes/6.0.0.html",children:"OSISM"})," and\n",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R5.md",children:"k8s-cluster-api-provider"})," release notes."]}),"\n",(0,i.jsx)(s.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,i.jsxs)(s.p,{children:["A new certification set is expected in December. It will ensure we\nrun all automated tests also for all new standards, such as\n",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0100-v3-flavor-naming.md",children:"v3 flavor naming"}),",\nand the (previously included) ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0103-v1-standard-flavors.md",children:"v1 standard flavors"})," -- which includes the ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0110-v1-ssd-flavors.md$a",children:"new SSD flavors"}),", the ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0101-v1-entropy.md",children:"v1 entropy standard"}),". We have also split image naming and standard image recommendations into ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0104-v1-standard-images.md",children:"v1 standards images"}),"."]}),"\n",(0,i.jsxs)(s.p,{children:["Requirements for ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0210-v1-k8s-new-version-policy.md",children:"k8s version recency"}),", ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0211-v1-kaas-default-storage-class.md",children:"default storage class"})," as well as requirements to the ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0212-v1-requirements-for-container-registry.md",children:"container registry"})," have been captured."]}),"\n",(0,i.jsx)(s.p,{children:"The IAM area has seen ADRs on the chosen architecture."}),"\n",(0,i.jsx)(s.p,{children:"The (design) decisions on the metering work as well as on the status page project have also been\ncaptured."}),"\n",(0,i.jsxs)(s.p,{children:["The standards and the standards compliance of our operators' clouds can be seen in the\n",(0,i.jsx)(s.a,{href:"https://docs.scs.community/standards",children:"standards section of our doc pages"})," while the raw content is developed\nand discussed in the respective ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards",children:"github standards repository"}),"."]}),"\n",(0,i.jsx)(s.p,{children:"The SCS reference implementation follows all approved SCS standards."}),"\n",(0,i.jsx)(s.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,i.jsxs)(s.p,{children:["Relevant repositories have been tagged with ",(0,i.jsx)(s.code,{children:"v6.0.0"})," tag.\nFor some repositories ",(0,i.jsx)(s.code,{children:"maintained/v6.x"})," and ",(0,i.jsx)(s.code,{children:"maintained/v6.0.x"})," branches have been created."]}),"\n",(0,i.jsx)(s.h2,{id:"list-of-known-issues--restrictions-in-r5",children:"List of known issues & restrictions in R5"}),"\n",(0,i.jsx)(s.p,{children:"Nothing that we are aware of at this point."}),"\n",(0,i.jsx)(s.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(s.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,i.jsx)(s.a,{href:"https://scs.community/contribute/",children:"How to contribute page"}),"."]}),"\n",(0,i.jsx)(s.h2,{id:"thanks",children:"Thanks"}),"\n",(0,i.jsx)(s.p,{children:"Our wonderful community of integrators, operators, contractors and volunteers\nmade R5 possible. The project management team is employed by the OSB Alliance\nand we as well as the contractors are paid thanks to funding from the German\nMinistry for economic affairs and climate action. We build on top of a lot of\nexisting open source code from the CNCF, the OIF and various others and we\ntry to contribute back as much as we can."})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var t=n(96540);const i={},r=t.createContext(i);function a(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a12f05ab.9ccbfb1c.js b/assets/js/a12f05ab.9ccbfb1c.js new file mode 100644 index 0000000000..510e16cfbe --- /dev/null +++ b/assets/js/a12f05ab.9ccbfb1c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3453],{31353:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>c,default:()=>p,frontMatter:()=>o,metadata:()=>d,toc:()=>l});const d=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/cinder","title":"Cinder","description":"Remove service","source":"@site/docs/02-iaas/guides/operations-guide/openstack/cinder.md","sourceDirName":"02-iaas/guides/operations-guide/openstack","slug":"/iaas/guides/operations-guide/openstack/cinder","permalink":"/docs/iaas/guides/operations-guide/openstack/cinder","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/cinder.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Cinder"},"sidebar":"docs","previous":{"title":"OpenStack Health Monitor","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor"},"next":{"title":"Keystone","permalink":"/docs/iaas/guides/operations-guide/openstack/keystone"}}');var i=s(74848),r=s(28453);const o={sidebar_label:"Cinder"},c="Cinder",t={},l=[{value:"Remove service",id:"remove-service",level:2},{value:"Sync quota",id:"sync-quota",level:2},{value:"Quality of Service (QoS)",id:"quality-of-service-qos",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"cinder",children:"Cinder"})}),"\n",(0,i.jsx)(n.h2,{id:"remove-service",children:"Remove service"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack --os-cloud admin volume service list\n+------------------+-----------------------------------+----------+---------+-------+----------------------------+\n| Binary | Host | Zone | Status | State | Updated At |\n+------------------+-----------------------------------+----------+---------+-------+----------------------------+\n| cinder-scheduler | testbed-node-0 | internal | enabled | up | 2023-10-01T08:53:14.000000 |\n| cinder-scheduler | testbed-node-1 | internal | enabled | up | 2023-10-01T08:53:15.000000 |\n| cinder-scheduler | testbed-node-2 | internal | enabled | up | 2023-10-01T08:53:15.000000 |\n| cinder-volume | testbed-node-0@rbd-1 | nova | enabled | down | 2023-09-30T18:50:05.000000 |\n| cinder-volume | testbed-node-2@rbd-1 | nova | enabled | down | 2023-09-30T18:50:05.000000 |\n| cinder-volume | testbed-node-1@rbd-1 | nova | enabled | down | 2023-09-30T18:50:08.000000 |\n+------------------+-----------------------------------+----------+---------+-------+----------------------------+\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-0@rbd-1\nService cinder-volume on host testbed-node-0@rbd-1 removed.\n$ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-1@rbd-1\nService cinder-volume on host testbed-node-1@rbd-1 removed.\n$ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-2@rbd-1\nService cinder-volume on host testbed-node-2@rbd-1 removed.\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack --os-cloud admin volume service list\n+------------------+-----------------------------------+----------+---------+-------+----------------------------+\n| Binary | Host | Zone | Status | State | Updated At |\n+------------------+-----------------------------------+----------+---------+-------+----------------------------+\n| cinder-scheduler | testbed-node-0 | internal | enabled | up | 2023-10-01T08:56:24.000000 |\n| cinder-scheduler | testbed-node-1 | internal | enabled | up | 2023-10-01T08:56:25.000000 |\n| cinder-scheduler | testbed-node-2 | internal | enabled | up | 2023-10-01T08:56:25.000000 |\n+------------------+-----------------------------------+----------+---------+-------+----------------------------+\n"})}),"\n",(0,i.jsx)(n.h2,{id:"sync-quota",children:"Sync quota"}),"\n",(0,i.jsxs)(n.p,{children:["It can happen that more block storage usage is stored in the database for a project than\nis actually used. This can be corrected using ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/cinder/latest/cli/cinder-manage.html",children:"cinder-manage"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"For all projects:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ docker exec -it cinder_api cinder-manage quota sync\n"})}),"\n",(0,i.jsx)(n.p,{children:"Only for a specific project:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ docker exec -it cinder_api cinder-manage quota sync --project-id PROJECT_ID\n"})}),"\n",(0,i.jsx)(n.h2,{id:"quality-of-service-qos",children:"Quality of Service (QoS)"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/cinder/latest/admin/basic-volume-qos.html",children:"https://docs.openstack.org/cinder/latest/admin/basic-volume-qos.html"})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"default"})," volume QoS policy that allows 1000 read IOPS and 1000 write IOPS."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack --os-cloud admin volume qos create \\\n --consumer both \\\n --property read_iops_sec=1000 \\\n --property write_iops_sec=1000 \\\n default\n+------------+---------------------------------------------+\n| Field | Value |\n+------------+---------------------------------------------+\n| consumer | both |\n| id | 48920d26-e85f-4920-8ed4-ff8d322c77b9 |\n| name | testing |\n| properties | read_iops_sec='1000', write_iops_sec='1000' |\n+------------+---------------------------------------------+\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack --os-cloud admin volume qos list\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n| ID | Name | Consumer | Associations | Properties |\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n| 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | | read_iops_sec='1000', write_iops_sec='1000' |\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Assign the ",(0,i.jsx)(n.code,{children:"default"})," volume QoS policy to the ",(0,i.jsx)(n.code,{children:"__DEFAULT"})," volume type."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack --os-cloud admin volume qos associate default __DEFAULT__\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack --os-cloud admin volume qos list\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n| ID | Name | Consumer | Associations | Properties |\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n| 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | __DEFAULT__ | read_iops_sec='1000', write_iops_sec='1000' |\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Change the read IOPS from 1000 to 2000 and the write IOPS from 1000 to 2000 of the ",(0,i.jsx)(n.code,{children:"default"})," volume QoS policy."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack --os-cloud admin volume qos set \\\n --property read_iops_sec=2000 \\\n --property write_iops_sec=2000 \\\n default\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack --os-cloud admin volume qos list\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n| ID | Name | Consumer | Associations | Properties |\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n| 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | __DEFAULT__ | read_iops_sec='2000', write_iops_sec='2000' |\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n"})}),"\n",(0,i.jsx)(n.p,{children:"The following properties are available."}),"\n",(0,i.jsx)(n.p,{children:"For Fixed IOPS per volume:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"read_iops_sec"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"write_iops_sec"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"total_iops_sec"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"For Burst IOPS per volume:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"read_iops_sec_max"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"write_iops_sec_max"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"total_iops_sec_max"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"For Fixed bandwidth per volume:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"read_bytes_sec"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"write_bytes_sec"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"total_bytes_sec"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"For Burst bandwidth per volume:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"read_bytes_sec_max"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"write_bytes_sec_max"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"total_bytes_sec_max"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"For burst bucket size:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"size_iops_sec"})}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var d=s(96540);const i={},r=d.createContext(i);function o(e){const n=d.useContext(r);return d.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),d.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a15c4cb6.d48da5a3.js b/assets/js/a15c4cb6.d48da5a3.js new file mode 100644 index 0000000000..998522dfde --- /dev/null +++ b/assets/js/a15c4cb6.d48da5a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[11290],{72378:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"scs-0412-v1-metering-json","title":"Exposition of IaaS metering data as JSON","description":"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format\\nwithin the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with\\ntheir existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format\\nprovided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation\\nlayers and implementation components.\\n","source":"@site/standards/scs-0412-v1-metering-json.md","sourceDirName":".","slug":"/scs-0412-v1-metering-json","permalink":"/standards/scs-0412-v1-metering-json","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Exposition of IaaS metering data as JSON","type":"Standard","status":"Draft","track":"Ops","description":"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format\\nwithin the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with\\ntheir existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format\\nprovided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation\\nlayers and implementation components.\\n"},"sidebar":"standards","previous":{"title":"scs-0412: Exposition of IaaS metering data as JSON","permalink":"/standards/ops/scs-0412"}}');var o=t(74848),a=t(28453);const s={title:"Exposition of IaaS metering data as JSON",type:"Standard",status:"Draft",track:"Ops",description:"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format\nwithin the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with\ntheir existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format\nprovided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation\nlayers and implementation components.\n"},r=void 0,d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Use Ceilometer HTTP hook format",id:"use-ceilometer-http-hook-format",level:4},{value:"Use another format",id:"use-another-format",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const n={em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,o.jsx)(n.p,{children:"The Sovereign Cloud Stack project intends to standardise an infrastructure-as-a-service (IaaS) layer.\nIn order to economically sustainably run a cloud,\nit is generally useful to know which user or tenant consumes which amount of resources in which time frame."}),"\n",(0,o.jsx)(n.p,{children:"Similarly to how the SCS provides an interface for connecting monitoring services to detect outages,\nthis standard aims for providing an interface for connecting systems which aggregate customer resource usage."}),"\n",(0,o.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,o.jsx)(n.p,{children:"In general,\nusers of the SCS (i.e. cloud operators) may already have different systems in place\nfor tracking customer relationships\nas well as billing."}),"\n",(0,o.jsx)(n.p,{children:"Those systems are unlikely to have a uniform interface across all possible implementations.\nLikewise, those systems are unlikely to have a way to interface with OpenStack,\nthe reference IaaS layer in SCS."}),"\n",(0,o.jsx)(n.p,{children:"In order to provide SCS operators with a way to integrate the SCS IaaS layer with their billing,\nthis document shall provide a standard format,\nupon which shim conversion layers (to whichever billing system is in place)\ncan be built."}),"\n",(0,o.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,o.jsx)(n.p,{children:"In order to define a standard,\nthe various options for formats need to be considered.\nHowever, all formats also come with different implementation costs."}),"\n",(0,o.jsx)(n.p,{children:"These aspects are weighed in this section."}),"\n",(0,o.jsx)(n.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,o.jsx)(n.h4,{id:"use-ceilometer-http-hook-format",children:"Use Ceilometer HTTP hook format"}),"\n",(0,o.jsx)(n.p,{children:"The OpenStack Ceilometer project,\nwhich serves as a hub for all things telemetry and metering,\nprovides an HTTP-based hook to extract metering data.\nThis hook receives JSON-formatted data."}),"\n",(0,o.jsx)(n.p,{children:"Using this data has the advantage\nthat we do not need to implement another component to translate the format\nwhich may in turn be a point of failure."}),"\n",(0,o.jsx)(n.h4,{id:"use-another-format",children:"Use another format"}),"\n",(0,o.jsx)(n.p,{children:"In this option,\na format for metering data is researched and reused, or defined and specified by the SCS project."}),"\n",(0,o.jsx)(n.p,{children:"This option was not explored deeply, for the reasons explained in the decision."}),"\n",(0,o.jsx)(n.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,o.jsx)(n.p,{children:"None."}),"\n",(0,o.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,o.jsx)(n.p,{children:"We chose the Ceilometer HTTP hook format, described below, for the following reasons:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Ceilometer is a component which needs to be there anyway for successful metering of OpenStack. Re-using the format makes sense."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Using any other format requires a translation layer. However, users will likely need their own translation layer ",(0,o.jsx)(n.em,{children:"anyway"}),", to integrate the metering with their own infrastructure. Hence, it makes more sense to expose the data from Ceilometer directly."]}),"\n",(0,o.jsx)(n.p,{children:"A notable downside of this approach is that a change in Ceilometers format will inevitably cause issues in all downstream consumers."}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"SCS-0410-v1"}),"\n",(0,o.jsx)(n.li,{children:"SCS-0411-v1"}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,o.jsx)(n.p,{children:"None."})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>r});var i=t(96540);const o={},a=i.createContext(o);function s(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a2317717.6cbf1afd.js b/assets/js/a2317717.6cbf1afd.js new file mode 100644 index 0000000000..0faf7d785b --- /dev/null +++ b/assets/js/a2317717.6cbf1afd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[43400],{72885:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>t,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"iaas/guides/configuration-guide/services/chrony","title":"Chrony","description":"With the osism.services.chrony role, it is possible to manage the used NTP servers on a node.","source":"@site/docs/02-iaas/guides/configuration-guide/services/chrony.md","sourceDirName":"02-iaas/guides/configuration-guide/services","slug":"/iaas/guides/configuration-guide/services/chrony","permalink":"/docs/iaas/guides/configuration-guide/services/chrony","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/services/chrony.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Chrony"},"sidebar":"docs","previous":{"title":"Services","permalink":"/docs/iaas/guides/configuration-guide/services/"},"next":{"title":"Docker","permalink":"/docs/iaas/guides/configuration-guide/services/docker"}}');var o=i(74848),r=i(28453);const t={sidebar_label:"Chrony"},c="Chrony",a={},d=[];function u(e){const s={code:"code",h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"chrony",children:"Chrony"})}),"\n",(0,o.jsxs)(s.p,{children:["With the ",(0,o.jsx)(s.code,{children:"osism.services.chrony"})," role, it is possible to manage the used NTP servers on a node.\nIt is also possible to configure the Chrony service for use inside the cluster."]})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},28453:(e,s,i)=>{i.d(s,{R:()=>t,x:()=>c});var n=i(96540);const o={},r=n.createContext(o);function t(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a24f5044.a36944eb.js b/assets/js/a24f5044.a36944eb.js new file mode 100644 index 0000000000..9b43db78ff --- /dev/null +++ b/assets/js/a24f5044.a36944eb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9755],{86462:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>p,frontMatter:()=>d,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"scs-XXXX-vN-standard-template","title":"_Descriptive title_","description":"\x3c!---","source":"@site/standards/scs-XXXX-vN-standard-template.md","sourceDirName":".","slug":"/scs-XXXX-vN-standard-template","permalink":"/standards/scs-XXXX-vN-standard-template","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"_Descriptive title_","type":"Standard","status":"Draft","track":"Global"}}');var s=t(74848),o=t(28453);const d={title:"_Descriptive title_",type:"Standard",status:"Draft",track:"Global"},r=void 0,a={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"<em>Option 1</em>",id:"option-1",level:4},{value:"<em>Option 2</em>",id:"option-2",level:4},{value:"Open questions",id:"open-questions",level:3},{value:"Standard",id:"standard",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const n={em:"em",h2:"h2",h3:"h3",h4:"h4",p:"p",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"Introduction"}),"\n",(0,s.jsx)(n.h2,{id:"terminology",children:"Terminology"}),"\n",(0,s.jsx)(n.p,{children:"Example (abbr. Ex)\nThis is the description for an example terminology."}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(n.p,{children:"Motivation"}),"\n",(0,s.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsx)(n.p,{children:"OPTIONAL"}),"\n",(0,s.jsx)(n.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,s.jsx)(n.h4,{id:"option-1",children:(0,s.jsx)(n.em,{children:"Option 1"})}),"\n",(0,s.jsx)(n.p,{children:"Option 1 description"}),"\n",(0,s.jsx)(n.h4,{id:"option-2",children:(0,s.jsx)(n.em,{children:"Option 2"})}),"\n",(0,s.jsx)(n.p,{children:"Option 2 description"}),"\n",(0,s.jsx)(n.h3,{id:"open-questions",children:"Open questions"}),"\n",(0,s.jsx)(n.p,{children:"RECOMMENDED"}),"\n",(0,s.jsx)(n.h2,{id:"standard",children:"Standard"}),"\n",(0,s.jsx)(n.p,{children:"What is the essence of this standard? Adjust heading accordingly."}),"\n",(0,s.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsx)(n.p,{children:"Related Documents, OPTIONAL"}),"\n",(0,s.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsx)(n.p,{children:"Conformance Tests, OPTIONAL"})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>r});var i=t(96540);const s={},o=i.createContext(s);function d(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a35d3433.082ebf56.js b/assets/js/a35d3433.082ebf56.js new file mode 100644 index 0000000000..b138f7f0ac --- /dev/null +++ b/assets/js/a35d3433.082ebf56.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[80123],{90869:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"scs-0212-v1-requirements-for-container-registries","title":"Requirements for container registries","description":"Introduction","source":"@site/standards/scs-0212-v1-requirements-for-container-registries.md","sourceDirName":".","slug":"/scs-0212-v1-requirements-for-container-registries","permalink":"/standards/scs-0212-v1-requirements-for-container-registries","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Requirements for container registries","type":"Standard","status":"Draft","track":"KaaS"},"sidebar":"standards","previous":{"title":"scs-0212: Requirements for container registries","permalink":"/standards/kaas/scs-0212"},"next":{"title":"scs-0213: Kubernetes Nodes Anti Affinity","permalink":"/standards/kaas/scs-0213"}}');var t=i(74848),r=i(28453);const a={title:"Requirements for container registries",type:"Standard",status:"Draft",track:"KaaS"},o=void 0,l={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design considerations",id:"design-considerations",level:2},{value:"OSS health check",id:"oss-health-check",level:3},{value:"Required and desirable features check",id:"required-and-desirable-features-check",level:3},{value:"Required features",id:"required-features",level:4},{value:"Desirable features",id:"desirable-features",level:4},{value:"Standard",id:"standard",level:2},{value:"Related Documents",id:"related-documents",level:2}];function d(e){const n={a:"a",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsx)(n.p,{children:"A container registry is an infrastructure service to enable storing and accessing container\nimages. Images can be pushed to the registry by e.g. Continuous integration pipelines and\nbe pulled from by runtime environments like Kubernetes clusters."}),"\n",(0,t.jsx)(n.p,{children:"Container registries come in various forms, e.g. publicly accessible ones like Docker Hub or\nself-hosted and cloud-hosted services. The latter examples may apply various access control\nmechanisms to restrict access. Both solutions offer a wide range of features that may or may not\nattract potential users and CSPs."}),"\n",(0,t.jsx)(n.h2,{id:"terminology",children:"Terminology"}),"\n",(0,t.jsx)(n.p,{children:"Cloud Service Provider (abbr. CSP)\nEntity that provides scalable computing resources"}),"\n",(0,t.jsx)(n.p,{children:"Identity Provider (abbr. IdP)\nSystem that creates, maintains, and manages identity information"}),"\n",(0,t.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,t.jsx)(n.p,{children:'This standard is motivated by different use cases identified through the topics in the SCS project.\nOne use case would be the offering of private registries for customers by CSPs, which means that a CSP could\noffer private container registries either as a service or as a provided "recipe" to deploy a private registry\nutilizing the CSPs infrastructure.\nAnother use case would be the selection of a registry for the SCS reference implementation.'}),"\n",(0,t.jsx)(n.p,{children:"The idea and purpose of this document is to specify what requirements a specific technical container\nregistry implementation (i.e. software solution) needs to fulfill for an SCS-compliant registry."}),"\n",(0,t.jsx)(n.h2,{id:"design-considerations",children:"Design considerations"}),"\n",(0,t.jsx)(n.p,{children:"There are numerous features that should be evaluated for a container registry solution.\nIt is important to assess the registries based on the requirements of the OSS health checks and\ndesired features defined by the SCS. The following two subsections show these requirements."}),"\n",(0,t.jsx)(n.h3,{id:"oss-health-check",children:"OSS health check"}),"\n",(0,t.jsxs)(n.p,{children:["It is important to evaluate the health of a project before even evaluating the project for its feature set.\nA project should therefore fulfill all OSS health checks be defined by the\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Drafts/OSS-Health.md",children:"OSS-Health"})," document.\nThis document evaluates the health of the open-source projects that were selected from\nthe currently available solutions. The container registry software must fulfill all OSS\nhealth checks defined below:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Four Opens (code is fully open source, community is open and diverse, development process is open, design process is open)"}),"\n",(0,t.jsx)(n.li,{children:"Maturity"}),"\n",(0,t.jsx)(n.li,{children:"Security"}),"\n",(0,t.jsx)(n.li,{children:"Activity"}),"\n",(0,t.jsx)(n.li,{children:"Lock-in risk assessment"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"required-and-desirable-features-check",children:"Required and desirable features check"}),"\n",(0,t.jsx)(n.p,{children:"A container registry provides a specific feature set, which can be mapped out against the requirements\ndescribed in this section. The registry should generally be robust (e.g. operate under heavy load) and\nsecure in order to be acceptable for the SCS standard. Therefore, a required and optional feature set\nwere defined, to which a container registry must abide and be evaluated against."}),"\n",(0,t.jsx)(n.h4,{id:"required-features",children:"Required features"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Audit Logs","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"ability to record use in auditable logs so that activity can be traced to a single user"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Authentication of system identities","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"support for authenticating system identities like Kubernetes clusters"}),"\n",(0,t.jsx)(n.li,{children:"possibly support for dynamic identity tokens from some IdP"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Authentication of users","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"support for multiple authentication systems (IdM integration)"}),"\n",(0,t.jsx)(n.li,{children:"user and user account management"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Authorization","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"role-based access control to ensure strict access controls"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Automation","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"integration with CI/CD tools e.g. via webhooks"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Vulnerability scanning","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"reveal security vulnerabilities in container images"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Content Trust and Validation","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"verify image authenticity before running"}),"\n",(0,t.jsx)(n.li,{children:"image signing"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Multi-tenancy","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"container registry is able to serve multiple tenants (projects, teams, namespaces)"}),"\n",(0,t.jsxs)(n.li,{children:["implementation on the storage level, see e.g. ",(0,t.jsx)(n.a,{href:"https://github.com/sapcc/keppel#overview",children:"Keppel"}),", which uses\nmulti-tenant-aware storage drivers"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Backup and restore","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"possible strategies for disaster recovery and data migration scenarios"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Monitoring","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"observability is a key feature for operating a service in production so the container registry should expose key metrics"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["HA mode","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"enable the possibility of system uptime, even if a failure of some sort could occur"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Registry replication","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"replication allows users to replicate container images between registries of the same instances and between registries of different instances as well"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Proxy cache (pull-through cache)","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Proxy cache enables the use of a container registry to proxy and cache images from a target public or private registry"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Quota management","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"ability to control resource use of components or the whole registry"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Garbage collection","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"removing blobs from the filesystem when they are no longer referenced by a manifest"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Retention policy","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"reduce the number of image tags, many of which might not be required after a given time or once a subsequent image tag has superseded them"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"desirable-features",children:"Desirable features"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Additionally supported artifacts","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Additional artifacts that the registry is able to store in addition to OCI artifacts, e.g. Java, Node.js, or Python packages"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Integration possibilities","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Ability to cooperate with another software solution in order to improve own feature set (e.g. integration of P2P solution for improving container image distribution (download speed and stability, high scalability, ...))"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Deployment capabilities","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'ways to deploy a container registry (only "official" ways are mentioned)'}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:['Administration capabilities "as a code"',"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'ability to manage container registry via "as a code" solutions, e.g. Ansible role'}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"standard",children:"Standard"}),"\n",(0,t.jsx)(n.p,{children:"It is very unlikely, that every Container registry can fulfill every requirement defined by this document, and probably\nnot all deployments require every feature listed here. The required feature set should therefore be carefully considered\nby the provider of the registry. We nevertheless RECOMMEND using most of the feature set provided in this document."}),"\n",(0,t.jsx)(n.p,{children:"If the features mentioned above are all considered, a possible registry solution SHOULD fulfill the majority of\nthe required features. But this is again dependent on the specific use case and the surrounding architecture."}),"\n",(0,t.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Drafts/OSS-Health.md",children:"OSS-Health"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>o});var s=i(96540);const t={},r=s.createContext(t);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a3dd9468.afb100f4.js b/assets/js/a3dd9468.afb100f4.js new file mode 100644 index 0000000000..dcd4fade8c --- /dev/null +++ b/assets/js/a3dd9468.afb100f4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[26018],{97601:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>r,toc:()=>o});const r=JSON.parse('{"id":"iaas/scs-0113","title":"scs-0113: Security Groups Decision Record","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0113.md","sourceDirName":"iaas","slug":"/iaas/scs-0113","permalink":"/standards/iaas/scs-0113","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0112-v1-sonic"},"next":{"title":"V1","permalink":"/standards/scs-0113-v1-security-groups-decision-record"}}');var n=t(74848),c=t(28453);const d={},i="scs-0113: Security Groups Decision Record",a={},o=[];function l(e){const s={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"scs-0113-security-groups-decision-record",children:"scs-0113: Security Groups Decision Record"})}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Version"}),(0,n.jsx)(s.th,{children:"Type"}),(0,n.jsx)(s.th,{children:"State"}),(0,n.jsx)(s.th,{children:"stabilized"}),(0,n.jsx)(s.th,{children:"deprecated"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0113-v1-security-groups-decision-record",children:"scs-0113-v1"})}),(0,n.jsx)(s.td,{children:"Decision Record"}),(0,n.jsx)(s.td,{children:"Draft"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>d,x:()=>i});var r=t(96540);const n={},c=r.createContext(n);function d(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:d(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a3e11933.e7101d2e.js b/assets/js/a3e11933.e7101d2e.js new file mode 100644 index 0000000000..ed721f2657 --- /dev/null +++ b/assets/js/a3e11933.e7101d2e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[69657],{739:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"releases/Release1","title":"Release Notes for SCS Release 1","description":"(Release Date: 2021-09-29)","source":"@site/docs/06-releases/Release1.md","sourceDirName":"06-releases","slug":"/releases/Release1","permalink":"/docs/releases/Release1","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release1.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Release Notes for SCS Release 0","permalink":"/docs/releases/Release0"},"next":{"title":"Release Notes for SCS Release 2","permalink":"/docs/releases/Release2"}}');var o=s(74848),i=s(28453);const a={},r="Release Notes for SCS Release 1",l={},d=[{value:"Scope",id:"scope",level:2},{value:"CI framework",id:"ci-framework",level:2},{value:"Zuul-CI",id:"zuul-ci",level:3},{value:"Metrics collection and dashboards",id:"metrics-collection-and-dashboards",level:2},{value:"Prometheus exporters and Grafana dashboards",id:"prometheus-exporters-and-grafana-dashboards",level:3},{value:"openstack-health-monitor",id:"openstack-health-monitor",level:3},{value:"Logging",id:"logging",level:2},{value:"Central logging",id:"central-logging",level:3},{value:"Federation",id:"federation",level:2},{value:"OIDC support via keycloak",id:"oidc-support-via-keycloak",level:3},{value:"non-TLS restrictions (testbed)",id:"non-tls-restrictions-testbed",level:3},{value:"Known Issue with OIDC Logout",id:"known-issue-with-oidc-logout",level:3},{value:"Bare Metal Service",id:"bare-metal-service",level:2},{value:"Container Layer",id:"container-layer",level:2},{value:"Overview and Goals for R1",id:"overview-and-goals-for-r1",level:3},{value:"Beyond CAPI",id:"beyond-capi",level:3},{value:"Standardization",id:"standardization",level:2},{value:"SBOM and Links",id:"sbom-and-links",level:2},{value:"Release tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R1",id:"list-of-known-issues--restrictions-in-r1",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"release-notes-for-scs-release-1",children:"Release Notes for SCS Release 1"})}),"\n",(0,o.jsx)(n.p,{children:"(Release Date: 2021-09-29)"}),"\n",(0,o.jsx)(n.h2,{id:"scope",children:"Scope"}),"\n",(0,o.jsx)(n.p,{children:"Main goals for Release 1 (R1) was the strengthening of our CI test coverage and\nintegration, the operational tooling (metrics collection, dashboards, logging),\nlatest versions of upstream software (OpenStack Wallaby, Kubernetes-1.21.5),\nsupport for Bare Metal service, progress on user federation for clouds, and\nprogress on the integration of the container layer with k8s Cluster API (now in\nversion 0.4.x)."}),"\n",(0,o.jsx)(n.h2,{id:"ci-framework",children:"CI framework"}),"\n",(0,o.jsx)(n.h3,{id:"zuul-ci",children:"Zuul-CI"}),"\n",(0,o.jsxs)(n.p,{children:["For our internal development workflows we are planning to switch from GitHub\nActions to Zuul-CI (mostly). The infrastructure itself is already available,\nyet most of the repositories in the SovereignCloudStack organisation have not\nswitched over. Reasons for switching include cross-dependencies, scalability\nand costs. Reasons for using Zuul-CI include the close connection to the\nOpenStack project and the enormous flexibility in comparison to other similar\ntools. On top of that you have also gating instead of only CI. A quick example\nfor a Zuul-CI operated repository can be found here:\n",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-sandbox",children:"https://github.com/SovereignCloudStack/zuul-sandbox"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"metrics-collection-and-dashboards",children:"Metrics collection and dashboards"}),"\n",(0,o.jsx)(n.h3,{id:"prometheus-exporters-and-grafana-dashboards",children:"Prometheus exporters and Grafana dashboards"}),"\n",(0,o.jsxs)(n.p,{children:["We provide generic configuration examples and blueprints for prometheus rules\nand grafana dashboards. The examples need to be understood and adapted to the\nparticular needs of your environment. You can find the examples at\n",(0,o.jsx)(n.a,{href:"https://github.com/osism/kolla-operations",children:"https://github.com/osism/kolla-operations"}),"]."]}),"\n",(0,o.jsx)(n.p,{children:"With R2 we plan to implement a basic set of these alerts and dashboards in the\ntestbed deployment in order to make them even easier consumable for new users.\nFeel free to give feedback on the examples and contribute your own generic\nexamples."}),"\n",(0,o.jsx)(n.p,{children:"We're working on bringing a basic set of prometheus exporters to the\nOpenStack-kolla upstream community."}),"\n",(0,o.jsxs)(n.p,{children:["As part of our effort to add more monitoring tooling, we're integrating further\nprometheus exporters such as\n",(0,o.jsx)(n.a,{href:"https://review.opendev.org/c/openstack/kolla-ansible/+/643568",children:"libvirt"})," and\n",(0,o.jsx)(n.a,{href:"https://review.opendev.org/c/openstack/kolla/+/762986",children:"ovn"}),". Integration is\ntargeted for R2."]}),"\n",(0,o.jsxs)(n.p,{children:["More detailed information on monitoring topics will be continously provided in\nthe ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/monitoring.md",children:"corresponding design document"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"openstack-health-monitor",children:"openstack-health-monitor"}),"\n",(0,o.jsx)(n.p,{children:"We have made some progress with openstack-health-monitor since R0, but we have\nnot yet created ready-to-be-used influx data collection and the grafana\ndashboard. While the black box monitoring is perceived as very useful, the\nscript certainly has reached a complexity that is not handled well with bash\nscripting and makes it a difficult to maintain and even to use tool, so the\nusefulness of shipping it with SCS to make it available for Ops teams to\nmonitor has been questioned. Instead an expectation has been expressed that the\nSCS uses this to monitor all SCS partner clouds and provides some transparency\nthis way to the public -- and detailed statistics via e.g. a prometheus\nexporter to the respective cloud provider. This is currently under consideration."}),"\n",(0,o.jsx)(n.h2,{id:"logging",children:"Logging"}),"\n",(0,o.jsx)(n.h3,{id:"central-logging",children:"Central logging"}),"\n",(0,o.jsx)(n.p,{children:"OSISM now enables kolla-ansible centralized logging by default. The default\nrules need to be further refined to suit your needs. We plan to implement a\nmore generic set of rules for R2."}),"\n",(0,o.jsx)(n.h2,{id:"federation",children:"Federation"}),"\n",(0,o.jsx)(n.h3,{id:"oidc-support-via-keycloak",children:"OIDC support via keycloak"}),"\n",(0,o.jsxs)(n.p,{children:["Logging in to Horizon by authenticating with OIDC via Keycloak is now possible.\nFor details see the ",(0,o.jsx)(n.a,{href:"https://github.com/osism/testbed/blob/8430afdd36307acc1bf5ebd930ecbd3dd4b1dd22/docs/source/usage.rst#authentication-with-openid-connect",children:"testbed documentation"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"non-tls-restrictions-testbed",children:"non-TLS restrictions (testbed)"}),"\n",(0,o.jsxs)(n.p,{children:["Only TLS secured deployments get full support.\nWithout TLS, certain browsers won't be able to log in.\nFor deatils see the ",(0,o.jsx)(n.a,{href:"https://github.com/osism/testbed/blob/8430afdd36307acc1bf5ebd930ecbd3dd4b1dd22/docs/source/usage.rst#ssl-tls-connection-to-keycloak-openid-connect-provider",children:"testbed documentation"})]}),"\n",(0,o.jsx)(n.h3,{id:"known-issue-with-oidc-logout",children:"Known Issue with OIDC Logout"}),"\n",(0,o.jsxs)(n.p,{children:["Clicking ",(0,o.jsx)(n.code,{children:"Sign Out"})," on the Horizon dashboard doesn't perform\na proper OIDC logout. This is documented in ",(0,o.jsx)(n.a,{href:"https://github.com/osism/testbed/blob/8430afdd36307acc1bf5ebd930ecbd3dd4b1dd22/docs/source/usage.rst#openstack-web-dashboard-horizon-logout",children:"osism testbed"}),",\nwith some Keycloak settings that can be relevant for alleviating the issue,\nbut in Release 1 there is no solution for this yet."]}),"\n",(0,o.jsx)(n.h2,{id:"bare-metal-service",children:"Bare Metal Service"}),"\n",(0,o.jsx)(n.p,{children:"The ironic Bare Metal service can be deployed with the SCS (OSISM)\ninstallation. For it to get full test coverage, a virtual BMC\nsolution has been created, so bare metal can be validated in our testbed\nsetup just as nicely as the other components. While most pieces\nare ready, the final integration steps are still work-in-progress\nand will happen after R1."}),"\n",(0,o.jsx)(n.h2,{id:"container-layer",children:"Container Layer"}),"\n",(0,o.jsx)(n.h3,{id:"overview-and-goals-for-r1",children:"Overview and Goals for R1"}),"\n",(0,o.jsxs)(n.p,{children:["The container layer on SCS is implemented as a Self-Service,\nleveraging the ",(0,o.jsx)(n.a,{href:"https://cluster-api.sigs.k8s.io/",children:"Kubernetes cluster API"}),"\ntechnology. This was provided as a technical preview from the\n",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"SCS k8s-cluster-api-provider"}),"\nrepository for R0 back in July."]}),"\n",(0,o.jsx)(n.p,{children:"The focus for R1 was to make it ready for production, so DevOps teams can\nuse this to create and manage their k8s clusters in self-service for\ndevelopment, testing, deployment and production."}),"\n",(0,o.jsx)(n.p,{children:"To achieve this, a lot of work has been invested, updating the\ncluster API to 0.4 along the way, fixing snapshot classes, enabling\noptional metrics and ingress services, using application credentials\nand much improved management scripts. The sonobuoy test automation has\nbeen included and successfully used to validate the created clusters.\nReal-world testing has happened though the Gaia-X Hackathon #1, where\nclusters were provided on the fly for the various work streams."}),"\n",(0,o.jsxs)(n.p,{children:["The detailed list of changes for R1 is covered in the\n",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/master/Release-Notes-R1.md",children:"k8s capi provider Release Notes"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"Still in technical preview, but very promising are the helm charts\nbased k8s cluster management templates also documented there."}),"\n",(0,o.jsx)(n.h3,{id:"beyond-capi",children:"Beyond CAPI"}),"\n",(0,o.jsxs)(n.p,{children:["Some of our partners are using ",(0,o.jsx)(n.a,{href:"https://gardener.cloud",children:"Gardener"})," as a layer to manage\nlarge fleets of (optionally cross-cloud) k8s clusters. While there is a bit of\noverlap in functionality, they do happily coexist and our partner is actually\nusing k8s capi to bootstrap clusters on SCS clouds for Gardener management."]}),"\n",(0,o.jsx)(n.h2,{id:"standardization",children:"Standardization"}),"\n",(0,o.jsx)(n.p,{children:"As of this writing, the list of SCS defined standards still comprises\ntwo standards:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/flavor-naming.md",children:"SCS Flavor naming and standard flavors standard"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Image-Properties-Spec.md",children:"SCS Image naming and metadata standard"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"As before, we continue to rely on OpenStack and CNCF defined standards\nin addition to this -- the k8s clusters need to pass the conformance\ntests with sonobuoy and the OpenStack environment the OpenStack powered\nguidelines (with refstack)."}),"\n",(0,o.jsx)(n.p,{children:"There is a discussion on a glossary, detailing what we expect from regions,\navailability zones etc. Some major parts of it still need to be agreed\nbefore a useful doc can be published -- this will happen in due time and\nis expected before R2."}),"\n",(0,o.jsx)(n.h2,{id:"sbom-and-links",children:"SBOM and Links"}),"\n",(0,o.jsx)(n.p,{children:"We stand on the shoulders of giants:\nWithout all the great work from many open source communities, we would\nnot get anywhere."}),"\n",(0,o.jsx)(n.p,{children:"We are working on automation to create a complete list for all the software\nthat is used and deployed with SCS, so we have a complete Software Bill\nof Materials (SBoM). The reason this is non-trivial is that we are not\naggregating it all ourselves, but rely on pre-integrated pieces, such\nas Linux distributions, OpenStack, CNCF projects etc. The good news is\nthat these projects are diligent in their work, making sure we don't need\nto be too worried about security risks or legal risks introduced this way.\nNevertheless, the goal of creating a complete graph remains."}),"\n",(0,o.jsx)(n.p,{children:"We have started to put SPDX license identifiers into the SCS produced\ncode, so we make it easier for downstream consumers of our software to\nautomate the license compliance checks when assembling an SBoM."}),"\n",(0,o.jsx)(n.p,{children:"For R1, some of the major projects we build on have had releases that we\nincorporated and whose release notes we want to link here for convenience:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://github.com/kubernetes/kubernetes/releases",children:"Kubernetes v1.21.x"})}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api/releases",children:"Kubernetes Cluster API v0.4"}),"\nand ",(0,o.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api-provider-openstack/releases",children:"k8s cluster-api-provider openstack v0.4"})]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"https://releases.openstack.org/wallaby/",children:"OpenStack Wallaby"})," ",(0,o.jsx)(n.a,{href:"https://releases.openstack.org/wallaby/highlights.html",children:"Release Highlights"})]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"release-tagging",children:"Release tagging"}),"\n",(0,o.jsxs)(n.p,{children:["See ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Release-Numbering-Scheme.md",children:"Release Numbering scheme"})," -- unchanged from R0.\nWe have added the tag ",(0,o.jsx)(n.code,{children:"v2.0.0"})," to the relevant repositories to designate the ",(0,o.jsx)(n.code,{children:"SCS_RELEASE_R1"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"list-of-known-issues--restrictions-in-r1",children:"List of known issues & restrictions in R1"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"#Known-Issue-with-OIDC-Logout",children:"OIDC Logout doesn't work properly"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["OIDC Login is meant to be used with TLS, on\n",(0,o.jsx)(n.a,{href:"#non-TLS-restrictions-testbed",children:"non-TLS setups it only works with restrictions"}),"."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var t=s(96540);const o={},i=t.createContext(o);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a4833b52.a4bcc5e1.js b/assets/js/a4833b52.a4bcc5e1.js new file mode 100644 index 0000000000..ab28eaa2a7 --- /dev/null +++ b/assets/js/a4833b52.a4bcc5e1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[57753],{57344:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>d,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"scs-0104-v1-standard-images","title":"SCS Standard Images","description":"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,\\nspecifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined\\ndeployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard\'s\\nmachine-readable document facilitates automated processing for compliance and integration purposes, promoting\\nconsistency and reliability in cloud environments.\\n","source":"@site/standards/scs-0104-v1-standard-images.md","sourceDirName":".","slug":"/scs-0104-v1-standard-images","permalink":"/standards/scs-0104-v1-standard-images","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Standard Images","type":"Procedural","status":"Stable","stabilized_at":"2024-02-21T00:00:00.000Z","track":"IaaS","description":"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,\\nspecifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined\\ndeployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard\'s\\nmachine-readable document facilitates automated processing for compliance and integration purposes, promoting\\nconsistency and reliability in cloud environments.\\n"},"sidebar":"standards","previous":{"title":"scs-0104: SCS Standard Images","permalink":"/standards/iaas/scs-0104"},"next":{"title":"W1","permalink":"/standards/scs-0104-w1-standard-images-implementation"}}');var a=i(74848),t=i(28453);const o={title:"SCS Standard Images",type:"Procedural",status:"Stable",stabilized_at:new Date("2024-02-21T00:00:00.000Z"),track:"IaaS",description:"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,\nspecifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined\ndeployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard's\nmachine-readable document facilitates automated processing for compliance and integration purposes, promoting\nconsistency and reliability in cloud environments.\n"},d=void 0,r={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Uploading custom images",id:"uploading-custom-images",level:2},{value:"Standard images YAML",id:"standard-images-yaml",level:2},{value:"Image specification, single image",id:"image-specification-single-image",level:3},{value:"Image specification, class of images",id:"image-specification-class-of-images",level:3},{value:"Full example",id:"full-example",level:2},{value:"Lifecycle considerations",id:"lifecycle-considerations",level:2},{value:"YAML lifecycle",id:"yaml-lifecycle",level:3},{value:"Image lifecycle",id:"image-lifecycle",level:3},{value:"Conformance Tests",id:"conformance-tests",level:2},{value:"Operational tooling",id:"operational-tooling",level:2}];function c(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.a,{href:"https://scs.community",children:"Sovereign Cloud Stack (SCS)"})," provides standards for a range of cloud infrastructure types.\nIt strives for interoperable and sovereign cloud offerings which can be deployed and used by a wide range of organizations and individuals."]}),"\n",(0,a.jsx)(n.p,{children:"To this end, SCS unifies the naming and sourcing of virtual machine images, and for certain images their presence is mandated or recommended."}),"\n",(0,a.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,a.jsxs)(n.p,{children:["Following the example of the ",(0,a.jsx)(n.a,{href:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",children:"SCS standards YAML"}),",\nthis standard establishes, by means of a YAML file, a mechanism with the following main objectives:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"to maintain a list of mandatory, recommended, and optional images, which also fixes the source location,"}),"\n",(0,a.jsx)(n.li,{children:"to provide a machine-readable document for further processing (e.g. for a compliance tool suite or continuous integration)."}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"uploading-custom-images",children:"Uploading custom images"}),"\n",(0,a.jsx)(n.p,{children:"Image upload via Glance MUST be allowed based on a fair-use policy."}),"\n",(0,a.jsx)(n.h2,{id:"standard-images-yaml",children:"Standard images YAML"}),"\n",(0,a.jsxs)(n.p,{children:["The YAML file MUST contain the key ",(0,a.jsx)(n.code,{children:"images"}),", whose value is a list of objects. Each object has one of two forms, as described below."]}),"\n",(0,a.jsx)(n.h3,{id:"image-specification-single-image",children:"Image specification, single image"}),"\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Key"}),(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Description"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"name"})}),(0,a.jsx)(n.td,{children:"String"}),(0,a.jsx)(n.td,{children:"Name of the image"}),(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:'"Debian 12"'})})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"status"})}),(0,a.jsxs)(n.td,{children:["String (",(0,a.jsx)(n.em,{children:"optional"}),")"]}),(0,a.jsxs)(n.td,{children:[(0,a.jsx)(n.code,{children:"optional"})," (default), ",(0,a.jsx)(n.code,{children:"mandatory"})," or ",(0,a.jsx)(n.code,{children:"recommended"})]}),(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:'"recommended"'})})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"source"})}),(0,a.jsx)(n.td,{children:"String"}),(0,a.jsx)(n.td,{children:"Prefix of the source URL"}),(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:'"https://cloud.debian.org/images/cloud/bookworm/"'})})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{}),(0,a.jsx)(n.td,{children:"OR: List of strings"}),(0,a.jsx)(n.td,{children:"multiple possible prefixes"}),(0,a.jsx)(n.td,{children:"(see full example below)"})]})]})]}),"\n",(0,a.jsx)(n.p,{children:"The meaning of this specification is as follows."}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["If the status is ",(0,a.jsx)(n.code,{children:"mandatory"}),", then an image with the name given via ",(0,a.jsx)(n.code,{children:"name"})," MUST be present."]}),"\n",(0,a.jsxs)(n.li,{children:["If the status is ",(0,a.jsx)(n.code,{children:"recommended"}),", then an image with the name given via ",(0,a.jsx)(n.code,{children:"name"})," SHOULD be present."]}),"\n",(0,a.jsxs)(n.li,{children:["Regardless of the status:\nif an image with the name given is present, then its ",(0,a.jsx)(n.code,{children:"image_source"})," property\n(as described in the ",(0,a.jsx)(n.a,{href:"/standards/scs-0102-v1-image-metadata",children:"Image Metadata standard"}),")\nMUST start with one of the prefixes given via ",(0,a.jsx)(n.code,{children:"source"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"image-specification-class-of-images",children:"Image specification, class of images"}),"\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Key"}),(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Description"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"name"})}),(0,a.jsx)(n.td,{children:"String"}),(0,a.jsx)(n.td,{children:"Name of the class of images"}),(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:'"ubuntu-2204-kube"'})})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"name_scheme"})}),(0,a.jsx)(n.td,{children:"String (regex)"}),(0,a.jsx)(n.td,{children:"Regular expression for the image name"}),(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:'"ubuntu-2204-kube-v[0-9].[0-9]+(.[0-9]+)?"'})})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"status"})}),(0,a.jsxs)(n.td,{children:["String (",(0,a.jsx)(n.em,{children:"optional"}),")"]}),(0,a.jsxs)(n.td,{children:[(0,a.jsx)(n.code,{children:"optional"})," (default), ",(0,a.jsx)(n.code,{children:"mandatory"})," or ",(0,a.jsx)(n.code,{children:"recommended"})]}),(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:'"recommended"'})})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"source"})}),(0,a.jsx)(n.td,{children:"String"}),(0,a.jsx)(n.td,{children:"Prefix of the source URL"}),(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:'"https://swift.services.a.regiocloud.tech"'})})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{}),(0,a.jsx)(n.td,{children:"OR: List of strings"}),(0,a.jsx)(n.td,{children:"multiple possible prefixes"}),(0,a.jsx)(n.td,{children:"(see full example below)"})]})]})]}),"\n",(0,a.jsx)(n.p,{children:"The meaning of this specification is as follows:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["If the status is ",(0,a.jsx)(n.code,{children:"mandatory"}),", then at least one image MUST be present whose name\nmatches the regular expression given via ",(0,a.jsx)(n.code,{children:"name_scheme"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:["If the status is ",(0,a.jsx)(n.code,{children:"recommended"}),", then at least one image SHOULD be present whose name\nmatches the regular expression given via ",(0,a.jsx)(n.code,{children:"name_scheme"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:["Regardless of the status:\nfor any image whose name matches the regular expression given via ",(0,a.jsx)(n.code,{children:"name_scheme"}),",\nits ",(0,a.jsx)(n.code,{children:"image_source"})," property MUST start with one of the prefixes given via ",(0,a.jsx)(n.code,{children:"source"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"full-example",children:"Full example"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'images:\n- name: "Ubuntu 22.04"\n source:\n - https://cloud-images.ubuntu.com/releases/jammy/\n - https://cloud-images.ubuntu.com/jammy/\n status: mandatory\n- name: "ubuntu-capi-image"\n name_scheme: "ubuntu-capi-image v[0-9]\\\\.[0-9]+(\\\\.[0-9]+)?"\n source: https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-k8s-capi-images/ubuntu-2204-kube\n status: recommended\n- name: "Ubuntu 20.04"\n source:\n - https://cloud-images.ubuntu.com/releases/focal/\n - https://cloud-images.ubuntu.com/focal/\n- name: "Debian 12"\n source:\n - https://cloud.debian.org/images/cloud/bookworm/\n - https://cdimage.debian.org/cdimage/cloud/bookworm/\n- name: "Debian 11"\n source:\n - https://cloud.debian.org/images/cloud/bullseye/\n - https://cdimage.debian.org/cdimage/cloud/bullseye/\n'})}),"\n",(0,a.jsx)(n.p,{children:"This example provides allowable source prefixes for two Debian versions, two Ubuntu\nversions, and for any version of the Kubernetes cloud API provider. Only the latter is\nrecommended, while only Ubuntu 22.04 is mandatory."}),"\n",(0,a.jsx)(n.h2,{id:"lifecycle-considerations",children:"Lifecycle considerations"}),"\n",(0,a.jsx)(n.h3,{id:"yaml-lifecycle",children:"YAML lifecycle"}),"\n",(0,a.jsxs)(n.p,{children:["The YAML file is generally located under\n",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/",children:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"Any change that could render existing installations non-conformant (i.e., when new\nspecifications are added, when the name scheme of a specification is changed to\nmatch more names than before, when the status of an existing specification changes to\nmandatory, or when some source prefix is removed) requires a new YAML file to be created.\nAs a consequence, any currently valid certificates stay valid; the change can only take\neffect in a new version of the certificate in question, if so desired."}),"\n",(0,a.jsx)(n.h3,{id:"image-lifecycle",children:"Image lifecycle"}),"\n",(0,a.jsx)(n.p,{children:"It is important to note that this standard does not prohibit any images, and neither\ndoes it preclude the operator from providing any and all optional images."}),"\n",(0,a.jsx)(n.p,{children:"It is possible that a specification is mandatory in one version and non-mandatory in the\nnext version. This standard makes no statement as to what is supposed to happen to the\ncorresponding images in a live cloud environment. It is recommended to keep the\nonce-mandatory images in the live environment. As for new environments, it is up to the\noperator whether to provide any or all of these images, as stated above."}),"\n",(0,a.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,a.jsxs)(n.p,{children:["The script ",(0,a.jsx)(n.code,{children:"images-openstack.py"})," will read the lists of mandatory and recommended images\nfrom a yaml file provided as command-line argument, connect to an OpenStack installation,\nand check whether the images are present. Missing images will be reported on various\nlogging channels: error for mandatory, info for recommended images. Additionally, images\nwhose ",(0,a.jsx)(n.code,{children:"image_source"})," does not conform with the specifications will be reported on the\nerror channel. The return code will be non-zero if the test could not be performed or\nif any errors have been reported."]}),"\n",(0,a.jsx)(n.h2,{id:"operational-tooling",children:"Operational tooling"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.a,{href:"https://github.com/osism/openstack-image-manager",children:"openstack-image-manager"})," is able to\ncreate all standard, mandatory SCS images for you given image definitions from a YAML file."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>d});var s=i(96540);const a={},t=s.createContext(a);function o(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a51f78bf.575e352a.js b/assets/js/a51f78bf.575e352a.js new file mode 100644 index 0000000000..7be0637fff --- /dev/null +++ b/assets/js/a51f78bf.575e352a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[30825],{91439:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>l,default:()=>m,frontMatter:()=>c,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"iaas/guides/configuration-guide/commons/timezone","title":"Timezone","description":"With the osism.commons.timezone role, it is possible to manage the used timezone on a node.","source":"@site/docs/02-iaas/guides/configuration-guide/commons/timezone.md","sourceDirName":"02-iaas/guides/configuration-guide/commons","slug":"/iaas/guides/configuration-guide/commons/timezone","permalink":"/docs/iaas/guides/configuration-guide/commons/timezone","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/timezone.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Timezone"},"sidebar":"docs","previous":{"title":"Sysctl","permalink":"/docs/iaas/guides/configuration-guide/commons/sysctl"},"next":{"title":"User","permalink":"/docs/iaas/guides/configuration-guide/commons/user"}}');var o=n(74848),s=n(28453);const c={sidebar_label:"Timezone"},l="Timezone",r={},d=[];function a(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"timezone",children:"Timezone"})}),"\n",(0,o.jsxs)(t.p,{children:["With the ",(0,o.jsx)(t.code,{children:"osism.commons.timezone"})," role, it is possible to manage the used timezone on a node."]}),"\n",(0,o.jsxs)(t.p,{children:["This role is just a wrapper for the ",(0,o.jsx)(t.a,{href:"https://docs.ansible.com/ansible/latest/collections/community/general/timezone_module.html",children:"community.general.timezone"}),"\nmodule. The role also installs the ",(0,o.jsx)(t.code,{children:"tzdata"})," package."]}),"\n",(0,o.jsxs)(t.table,{children:[(0,o.jsx)(t.thead,{children:(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.th,{style:{textAlign:"left"},children:"Parameter"}),(0,o.jsx)(t.th,{style:{textAlign:"left"},children:"Default"}),(0,o.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,o.jsxs)(t.tbody,{children:[(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{style:{textAlign:"left"},children:(0,o.jsx)(t.code,{children:"timezone_hwclock"})}),(0,o.jsx)(t.td,{style:{textAlign:"left"},children:(0,o.jsx)(t.code,{children:"UTC"})}),(0,o.jsx)(t.td,{style:{textAlign:"left"},children:"Whether the hardware clock is in UTC or in local timezone."})]}),(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{style:{textAlign:"left"},children:(0,o.jsx)(t.code,{children:"timezone_name"})}),(0,o.jsx)(t.td,{style:{textAlign:"left"},children:(0,o.jsx)(t.code,{children:"UTC"})}),(0,o.jsx)(t.td,{style:{textAlign:"left"},children:"Name of the timezone for the system clock."})]})]})]})]})}function m(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>l});var i=n(96540);const o={},s=i.createContext(o);function c(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a52c62d4.455d8dd1.js b/assets/js/a52c62d4.455d8dd1.js new file mode 100644 index 0000000000..b189f04c93 --- /dev/null +++ b/assets/js/a52c62d4.455d8dd1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[45568],{56890:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>r,metadata:()=>a,toc:()=>d});const a=JSON.parse('{"id":"collaboration/sig-standardization","title":"SIG Standardization","description":"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.","source":"@site/community/collaboration/sig-standardization.md","sourceDirName":"collaboration","slug":"/collaboration/sig-standardization","permalink":"/community/collaboration/sig-standardization","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"SIG Monitoring","permalink":"/community/collaboration/sig-monitoring"},"next":{"title":"Tools","permalink":"/community/category/tools"}}');var o=n(74848),i=n(28453);const r={},s="SIG Standardization",c={},d=[];function l(e){const t={h1:"h1",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"sig-standardization",children:"SIG Standardization"})}),"\n",(0,o.jsx)(t.p,{children:"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."}),"\n",(0,o.jsx)(t.p,{children:"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."})]})}function p(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>s});var a=n(96540);const o={},i=a.createContext(o);function r(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a52f8495.7eb9c8a1.js b/assets/js/a52f8495.7eb9c8a1.js new file mode 100644 index 0000000000..c083c0e8c0 --- /dev/null +++ b/assets/js/a52f8495.7eb9c8a1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[19691],{90672:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>d,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"ops/scs-0400","title":"scs-0400: Status Page create decision","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/ops/scs-0400.md","sourceDirName":"ops","slug":"/ops/scs-0400","permalink":"/standards/ops/scs-0400","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"Ops Standards","permalink":"/standards/ops/"},"next":{"title":"V1","permalink":"/standards/scs-0400-v1-status-page-create-decision"}}');var r=s(74848),c=s(28453);const a={},d="scs-0400: Status Page create decision",i={},o=[];function l(e){const t={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0400-status-page-create-decision",children:"scs-0400: Status Page create decision"})}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0400-v1-status-page-create-decision",children:"scs-0400-v1"})}),(0,r.jsx)(t.td,{children:"Decision Record"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>d});var n=s(96540);const r={},c=n.createContext(r);function a(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a63812ab.46f4a502.js b/assets/js/a63812ab.46f4a502.js new file mode 100644 index 0000000000..42fb88813a --- /dev/null +++ b/assets/js/a63812ab.46f4a502.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[96147],{16190:(t,o,e)=>{e.r(o),e.d(o,{assets:()=>s,contentTitle:()=>c,default:()=>m,frontMatter:()=>r,metadata:()=>n,toc:()=>u});const n=JSON.parse('{"id":"collaboration/sig-documentation","title":"SIG Documentation","description":"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.","source":"@site/community/collaboration/sig-documentation.md","sourceDirName":"collaboration","slug":"/collaboration/sig-documentation","permalink":"/community/collaboration/sig-documentation","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SIG Documentation","operator":"Max Wolfs","time":"bi-weekly mondays 11-12 CET"},"sidebar":"community","previous":{"title":"SIG Community","permalink":"/community/collaboration/sig-community"},"next":{"title":"SIG Monitoring","permalink":"/community/collaboration/sig-monitoring"}}');var i=e(74848),a=e(28453);const r={title:"SIG Documentation",operator:"Max Wolfs",time:"bi-weekly mondays 11-12 CET"},c=void 0,s={},u=[];function l(t){const o={p:"p",...(0,a.R)(),...t.components};return(0,i.jsx)(o.p,{children:"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."})}function m(t={}){const{wrapper:o}={...(0,a.R)(),...t.components};return o?(0,i.jsx)(o,{...t,children:(0,i.jsx)(l,{...t})}):l(t)}},28453:(t,o,e)=>{e.d(o,{R:()=>r,x:()=>c});var n=e(96540);const i={},a=n.createContext(i);function r(t){const o=n.useContext(a);return n.useMemo((function(){return"function"==typeof t?t(o):{...o,...t}}),[o,t])}function c(t){let o;return o=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:r(t.components),n.createElement(a.Provider,{value:o},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/a64829d3.2b4d713a.js b/assets/js/a64829d3.2b4d713a.js new file mode 100644 index 0000000000..2597d43038 --- /dev/null +++ b/assets/js/a64829d3.2b4d713a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[88142],{5874:(e,c,n)=>{n.r(c),n.d(c,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>l,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","title":"Developing and Testing csctl","description":"Clone the Repo","source":"@site/docs/03-container/components/cluster-stacks/components/csctl/developing-and-testing-csctl.md","sourceDirName":"03-container/components/cluster-stacks/components/csctl","slug":"/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","permalink":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/csctl/developing-and-testing-csctl.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Getting started","permalink":"/docs/container/components/cluster-stacks/components/csctl/getting_started"},"next":{"title":"Quickstart","permalink":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart"}}');var s=n(74848),o=n(28453);const l={},r="Developing and Testing csctl",i={},a=[{value:"Clone the Repo",id:"clone-the-repo",level:2},{value:"Makefile",id:"makefile",level:2},{value:"make build",id:"make-build",level:2},{value:"csctl --help",id:"csctl---help",level:2},{value:"go run main.go ...",id:"go-run-maingo-",level:2},{value:"Create Docker Cluster Stack",id:"create-docker-cluster-stack",level:2}];function d(e){const c={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(c.header,{children:(0,s.jsx)(c.h1,{id:"developing-and-testing-csctl",children:"Developing and Testing csctl"})}),"\n",(0,s.jsx)(c.h2,{id:"clone-the-repo",children:"Clone the Repo"}),"\n",(0,s.jsxs)(c.p,{children:["Go to ",(0,s.jsx)(c.a,{href:"https://github.com/SovereignCloudStack/csctl/",children:"csctl at Github"})," and clone the repository to your local device:"]}),"\n",(0,s.jsx)(c.pre,{children:(0,s.jsx)(c.code,{className:"language-shell",children:"git clone git@github.com:SovereignCloudStack/csctl.git\n"})}),"\n",(0,s.jsx)(c.pre,{children:(0,s.jsx)(c.code,{className:"language-shell",children:"cd csctl\n"})}),"\n",(0,s.jsx)(c.h2,{id:"makefile",children:"Makefile"}),"\n",(0,s.jsxs)(c.p,{children:["We use a ",(0,s.jsx)(c.code,{children:"Makefile"})," to building the binary."]}),"\n",(0,s.jsxs)(c.p,{children:["You can see the available build targets with ",(0,s.jsx)(c.code,{children:"make help"}),"."]}),"\n",(0,s.jsx)(c.h2,{id:"make-build",children:"make build"}),"\n",(0,s.jsxs)(c.p,{children:["With ",(0,s.jsx)(c.code,{children:"make build"})," you create the executable."]}),"\n",(0,s.jsx)(c.h2,{id:"csctl---help",children:"csctl --help"}),"\n",(0,s.jsxs)(c.p,{children:["With ",(0,s.jsx)(c.code,{children:"./csctl --help"})," you can see the available sub-commands."]}),"\n",(0,s.jsxs)(c.p,{children:["BTW: Be sure to use ",(0,s.jsx)(c.code,{children:"./"}),", so that you don't accidentally use a different ",(0,s.jsx)(c.code,{children:"csctl"})," from your ",(0,s.jsx)(c.code,{children:"$PATH"}),"."]}),"\n",(0,s.jsxs)(c.p,{children:["Up to now only ",(0,s.jsx)(c.code,{children:"create"})," is a feasible sub-command."]}),"\n",(0,s.jsx)(c.h2,{id:"go-run-maingo-",children:"go run main.go ..."}),"\n",(0,s.jsxs)(c.p,{children:["If you modify the source of ",(0,s.jsx)(c.code,{children:"csctl"}),", you can skip the build step by using ",(0,s.jsx)(c.code,{children:"go run"}),":"]}),"\n",(0,s.jsx)(c.pre,{children:(0,s.jsx)(c.code,{className:"language-shell",children:"go run main.go create --help\n"})}),"\n",(0,s.jsx)(c.h2,{id:"create-docker-cluster-stack",children:"Create Docker Cluster Stack"}),"\n",(0,s.jsxs)(c.p,{children:["In the ",(0,s.jsx)(c.code,{children:"tests"})," directory is a cluster stack for the docker provider."]}),"\n",(0,s.jsx)(c.p,{children:"You can create the cluster stack like this:"}),"\n",(0,s.jsx)(c.pre,{children:(0,s.jsx)(c.code,{className:"language-shell",children:"\u276f go run main.go create tests/cluster-stacks/docker/ferrol -m hash \nCreated releases/docker-ferrol-1-27-v0-sha-7ff9188\n"})})]})}function h(e={}){const{wrapper:c}={...(0,o.R)(),...e.components};return c?(0,s.jsx)(c,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,c,n)=>{n.d(c,{R:()=>l,x:()=>r});var t=n(96540);const s={},o=t.createContext(s);function l(e){const c=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(c):{...c,...e}}),[c,e])}function r(e){let c;return c=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),t.createElement(o.Provider,{value:c},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a6a72687.9bf1523d.js b/assets/js/a6a72687.9bf1523d.js new file mode 100644 index 0000000000..470d2a8735 --- /dev/null +++ b/assets/js/a6a72687.9bf1523d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[87701],{49559:t=>{t.exports=JSON.parse('{"tag":{"label":"howto","permalink":"/blog/tags/howto","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/howto","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/a6aa9e1f.b0b42d8e.js b/assets/js/a6aa9e1f.b0b42d8e.js new file mode 100644 index 0000000000..a815f6c8ef --- /dev/null +++ b/assets/js/a6aa9e1f.b0b42d8e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[37643],{35124:(e,t,a)=>{a.r(t),a.d(t,{default:()=>j});a(96540);var s=a(18215),n=a(44586),r=a(61213),i=a(17559),l=a(28027),o=a(47713),c=a(41463),d=a(33892),m=a(5260),g=a(44096),u=a(74848);function h(e){const t=(0,g.kJ)(e);return(0,u.jsx)(m.A,{children:(0,u.jsx)("script",{type:"application/ld+json",children:JSON.stringify(t)})})}function p(e){const{metadata:t}=e,{siteConfig:{title:a}}=(0,n.A)(),{blogDescription:s,blogTitle:i,permalink:l}=t,o="/"===l?a:i;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(r.be,{title:o,description:s}),(0,u.jsx)(c.A,{tag:"blog_posts_list"})]})}function x(e){const{metadata:t,items:a,sidebar:s}=e;return(0,u.jsxs)(l.A,{sidebar:s,children:[(0,u.jsx)(d.A,{items:a}),(0,u.jsx)(o.A,{metadata:t})]})}function j(e){return(0,u.jsxs)(r.e3,{className:(0,s.A)(i.G.wrapper.blogPages,i.G.page.blogListPage),children:[(0,u.jsx)(p,{...e}),(0,u.jsx)(h,{...e}),(0,u.jsx)(x,{...e})]})}},47713:(e,t,a)=>{a.d(t,{A:()=>i});a(96540);var s=a(21312),n=a(39022),r=a(74848);function i(e){const{metadata:t}=e,{previousPage:a,nextPage:i}=t;return(0,r.jsxs)("nav",{className:"pagination-nav","aria-label":(0,s.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[a&&(0,r.jsx)(n.A,{permalink:a,title:(0,r.jsx)(s.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),i&&(0,r.jsx)(n.A,{permalink:i,title:(0,r.jsx)(s.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}},82907:(e,t,a)=>{a.d(t,{A:()=>O});a(96540);var s=a(18215),n=a(44096),r=a(74848);function i(e){let{children:t,className:a}=e;return(0,r.jsx)("article",{className:a,children:t})}var l=a(28774);const o={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:a,isBlogPostPage:i}=(0,n.e7)(),{permalink:c,title:d}=a,m=i?"h1":"h2";return(0,r.jsx)(m,{className:(0,s.A)(o.title,t),children:i?d:(0,r.jsx)(l.A,{to:c,children:d})})}var d=a(21312),m=a(53465),g=a(36266);const u={container:"container_mt6G"};function h(e){let{readingTime:t}=e;const a=function(){const{selectMessage:e}=(0,m.W)();return t=>{const a=Math.ceil(t);return e(a,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return(0,r.jsx)(r.Fragment,{children:a(t)})}function p(e){let{date:t,formattedDate:a}=e;return(0,r.jsx)("time",{dateTime:t,children:a})}function x(){return(0,r.jsx)(r.Fragment,{children:" \xb7 "})}function j(e){let{className:t}=e;const{metadata:a}=(0,n.e7)(),{date:i,readingTime:l}=a,o=(0,g.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,r.jsxs)("div",{className:(0,s.A)(u.container,"margin-vert--md",t),children:[(0,r.jsx)(p,{date:i,formattedDate:(c=i,o.format(new Date(c)))}),void 0!==l&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(x,{}),(0,r.jsx)(h,{readingTime:l})]})]});var c}var A=a(56913);const b={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function f(e){let{className:t}=e;const{metadata:{authors:a},assets:i}=(0,n.e7)();if(0===a.length)return null;const l=a.every((e=>{let{name:t}=e;return!t})),o=1===a.length;return(0,r.jsx)("div",{className:(0,s.A)("margin-top--md margin-bottom--sm",l?b.imageOnlyAuthorRow:"row",t),children:a.map(((e,t)=>(0,r.jsx)("div",{className:(0,s.A)(!l&&(o?"col col--12":"col col--6"),l?b.imageOnlyAuthorCol:b.authorCol),children:(0,r.jsx)(A.A,{author:{...e,imageURL:i.authorsImageUrls[t]??e.imageURL}})},t)))})}function v(){return(0,r.jsxs)("header",{children:[(0,r.jsx)(c,{}),(0,r.jsx)(j,{}),(0,r.jsx)(f,{})]})}var N=a(70440),T=a(11544);function w(e){let{children:t,className:a}=e;const{isBlogPostPage:i}=(0,n.e7)();return(0,r.jsx)("div",{id:i?N.LU:void 0,className:(0,s.A)("markdown",a),children:(0,r.jsx)(T.A,{children:t})})}var y=a(17559),k=a(4336),P=a(62053);function U(){return(0,r.jsx)("b",{children:(0,r.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function R(e){const{blogPostTitle:t,...a}=e;return(0,r.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...a,children:(0,r.jsx)(U,{})})}function C(){const{metadata:e,isBlogPostPage:t}=(0,n.e7)(),{tags:a,title:i,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,m=!t&&o,g=a.length>0;if(!(g||m||l))return null;if(t){const e=!!(l||d||c);return(0,r.jsxs)("footer",{className:"docusaurus-mt-lg",children:[g&&(0,r.jsx)("div",{className:(0,s.A)("row","margin-top--sm",y.G.blog.blogFooterEditMetaRow),children:(0,r.jsx)("div",{className:"col",children:(0,r.jsx)(P.A,{tags:a})})}),e&&(0,r.jsx)(k.A,{className:(0,s.A)("margin-top--sm",y.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,r.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[g&&(0,r.jsx)("div",{className:(0,s.A)("col",{"col--9":m}),children:(0,r.jsx)(P.A,{tags:a})}),m&&(0,r.jsx)("div",{className:(0,s.A)("col text--right",{"col--3":g}),children:(0,r.jsx)(R,{blogPostTitle:i,to:e.permalink})})]})}function O(e){let{children:t,className:a}=e;const l=function(){const{isBlogPostPage:e}=(0,n.e7)();return e?void 0:"margin-bottom--xl"}();return(0,r.jsxs)(i,{className:(0,s.A)(l,a),children:[(0,r.jsx)(v,{}),(0,r.jsx)(w,{children:t}),(0,r.jsx)(C,{})]})}},33892:(e,t,a)=>{a.d(t,{A:()=>i});a(96540);var s=a(44096),n=a(82907),r=a(74848);function i(e){let{items:t,component:a=n.A}=e;return(0,r.jsx)(r.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,r.jsx)(s.in,{content:t,children:(0,r.jsx)(a,{children:(0,r.jsx)(t,{})})},t.metadata.permalink)}))})}}}]); \ No newline at end of file diff --git a/assets/js/a708848c.bb930b4d.js b/assets/js/a708848c.bb930b4d.js new file mode 100644 index 0000000000..935428ffd0 --- /dev/null +++ b/assets/js/a708848c.bb930b4d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[27980],{54034:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>m,frontMatter:()=>s,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"iaas/components/project-manager","title":"Project Manager","description":"Overview","source":"@site/docs/02-iaas/components/project-manager.md","sourceDirName":"02-iaas/components","slug":"/iaas/components/project-manager","permalink":"/docs/iaas/components/project-manager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/project-manager.md","tags":[],"version":"current","sidebarPosition":53,"frontMatter":{"sidebar_label":"Project Manager","sidebar_position":53}}');var i=a(74848),t=a(28453);const s={sidebar_label:"Project Manager",sidebar_position:53},r="Project Manager",c={},d=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Defaults",id:"defaults",level:2},{value:"create.py",id:"createpy",level:3},{value:"manage.py",id:"managepy",level:3},{value:"Usage",id:"usage",level:2},{value:"create.py",id:"createpy-1",level:3},{value:"Create a Domain and inital project",id:"create-a-domain-and-inital-project",level:4},{value:"Create a User for a project",id:"create-a-user-for-a-project",level:4},{value:"Create additional project with unlimited quota",id:"create-additional-project-with-unlimited-quota",level:4},{value:"Set quotas for a project",id:"set-quotas-for-a-project",level:4},{value:"Special project: images",id:"special-project-images",level:4},{value:"Special project: service",id:"special-project-service",level:4},{value:"manage.py",id:"managepy-1",level:3},{value:"Manage a specific domain only",id:"manage-a-specific-domain-only",level:4},{value:"Config files",id:"config-files",level:2},{value:"Quota Templates",id:"quota-templates",level:2},{value:"Setup Endpoints",id:"setup-endpoints",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",p:"p",pre:"pre",strong:"strong",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"project-manager",children:"Project Manager"})}),"\n",(0,i.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(n.p,{children:"The OpenStack Project Manager manages the creation of Openstack Domains, Projects and Users."}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsx)(n.p,{children:"Prepare to use the Openstack Project Manager."}),"\n",(0,i.jsx)(n.p,{children:"During installation, ldap libraries are required under Linux; you should install libldap2-dev and libsasl2-dev beforehand."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"git clone https://github.com/osism/openstack-project-manager\ncd openstack-project-manager\npipenv install\npipenv shell\n"})}),"\n",(0,i.jsx)(n.h2,{id:"defaults",children:"Defaults"}),"\n",(0,i.jsx)(n.h3,{id:"createpy",children:"create.py"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"create.py"})," command and his default options while executing the command."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:" --admin-domain default\n --assign-admin-user true\n --cloud admin\n --create-admin-user true\n --create-domain false\n --create-user false\n --domain-name-prefix true\n --has-service-network false\n --has-public-network true\n --has-shared-images true\n --internal-id unset\n --random false\n --managed-network-resources false\n --name sandbox\n --owner unset\n --password unset\n --password-length 16\n --public-network public\n --quota-class basic\n --service-network-cidr unset\n --quota-multiplier 1\n --quota-multiplier-compute unset\n --quota-multiplier-network unset\n --quota-multiplier-storage unset\n --quota-router 1\n"})}),"\n",(0,i.jsx)(n.h3,{id:"managepy",children:"manage.py"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"manage.py"})," has also some defaults while executing and will touch all projects in your Openstack Cluster, if not --domain is used."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:" --admin-domain default\n --assign-admin-user false\n --classes etc/classes.yml\n --domain unset\n --dry-run false\n --endpoints etc/endpoints.yml\n --manage-endpoints false\n --manage-homeprojects false\n --name unset\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Default Openstack Roles to users are set to ",(0,i.jsx)(n.code,{children:"member"})," and ",(0,i.jsx)(n.code,{children:"load-balancer_member"})," at this time, the behavior can only be changed in the code."]}),"\n",(0,i.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsxs)(n.p,{children:["There must be a ",(0,i.jsx)(n.code,{children:"clouds.yml"})," and a ",(0,i.jsx)(n.code,{children:"secure.yml"})," file in the directory where the OpenStack Project Manager will be executed, examples are provided within the git repository."]}),"\n",(0,i.jsx)(n.p,{children:"The cloud profile to be used can be specified via the optional --cloud parameter. By default the cloud profile with the name admin is used. It has to be and admin account, to create and modify domains, projects, users and quotas."}),"\n",(0,i.jsxs)(n.p,{children:["The Openstack Project Manager essentially consists of two parts, the ",(0,i.jsx)(n.code,{children:"create.py"})," and the ",(0,i.jsx)(n.code,{children:"manage.py"}),", there are more scripts for handling users using ldap which needs more configuration setup."]}),"\n",(0,i.jsx)(n.h3,{id:"createpy-1",children:"create.py"}),"\n",(0,i.jsx)(n.p,{children:"This command is used to create and modify domains, projects, users and quotas. As default the domain is used as prefix for all projects and users created for easy alloction in Openstack."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"create.py can't delete once created objects, this must be done using Openstack commands to remove a project or domain."})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"python src/create.py -h\nusage: create [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--create-admin-user] [--create-domain] [--create-user]\n [--domain DOMAIN] [--domain-name-prefix] [--has-public-network] [--has-service-network] [--has-shared-images] [--internal-id INTERNAL_ID] [--managed-network-resources] [--name NAME]\n [--noassign-admin-user] [--nocreate-admin-user] [--nocreate-domain] [--nocreate-user] [--nodomain-name-prefix] [--nohas-public-network] [--nohas-service-network]\n [--nohas-shared-images] [--nomanaged-network-resources] [--norandom] [--owner OWNER] [--password PASSWORD] [--password-length PASSWORD_LENGTH] [--public-network PUBLIC_NETWORK]\n [--quota-class QUOTA_CLASS] [--quota-multiplier QUOTA_MULTIPLIER] [--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE] [--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK]\n [--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE] [--quota-router QUOTA_ROUTER] [--random] [--service-network-cidr SERVICE_NETWORK_CIDR]\n\noptions:\n -h, --help show this help message and exit\n --admin-domain ADMIN_DOMAIN\n Admin domain\n --assign-admin-user Assign admin user\n --cloud CLOUD Managed cloud\n --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set\n is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the\n command-line.\n --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the\n command-line.\n --create-admin-user Create admin user\n --create-domain Create domain only\n --create-user Create user\n --domain DOMAIN Domain\n --domain-name-prefix Add domain name as prefix to the project name\n --has-public-network Has public network infrastructure\n --has-service-network\n Has service network infrastructure\n --has-shared-images Has shared images\n --internal-id INTERNAL_ID\n Internal ID\n --managed-network-resources\n Manage the network resources\n --name NAME Projectname\n --noassign-admin-user\n The inverse of --assign-admin-user\n --nocreate-admin-user\n The inverse of --create-admin-user\n --nocreate-domain The inverse of --create-domain\n --nocreate-user The inverse of --create-user\n --nodomain-name-prefix\n The inverse of --domain-name-prefix\n --nohas-public-network\n The inverse of --has-public-network\n --nohas-service-network\n The inverse of --has-service-network\n --nohas-shared-images\n The inverse of --has-shared-images\n --nomanaged-network-resources\n The inverse of --managed-network-resources\n --norandom The inverse of --random\n --owner OWNER Owner of the project\n --password PASSWORD Password\n --password-length PASSWORD_LENGTH\n Password length\n --public-network PUBLIC_NETWORK\n Public network\n --quota-class QUOTA_CLASS\n Quota class\n --quota-multiplier QUOTA_MULTIPLIER\n Quota multiplier\n --quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE\n Quota multiplier compute\n --quota-multiplier-network QUOTA_MULTIPLIER_NETWORK\n Quota multiplier network\n --quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE\n Quota multiplier storage\n --quota-router QUOTA_ROUTER\n Quota router\n --random Generate random names\n --service-network-cidr SERVICE_NETWORK_CIDR\n Service network CIDR\n"})}),"\n",(0,i.jsx)(n.h4,{id:"create-a-domain-and-inital-project",children:"Create a Domain and inital project"}),"\n",(0,i.jsxs)(n.p,{children:["When executing the ",(0,i.jsx)(n.code,{children:"create.py"})," command, the first time with ",(0,i.jsx)(n.code,{children:"--domain"}),", it will create a new domain, an admin account and the first project ",(0,i.jsx)(n.code,{children:"webshop"}),". The admin account will be created in the default Domain of Openstack and can be used for the Service Provider to manager the complete domain."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name webshop\n+----------------+----------------------+----------------------------------+\n| name | value | id |\n|----------------+----------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-webshop | 645538bf67664cfeaed32476d58f95fb |\n| admin | democompany-admin | cc8d6bf7b61d4199ba5a4230c4ec6d62 |\n| admin_password | qawsEdfg2d45Fsxc | |\n+----------------+----------------------+----------------------------------+\n"})}),"\n",(0,i.jsx)(n.h4,{id:"create-a-user-for-a-project",children:"Create a User for a project"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name webshopuser --create-user \n+----------+-------------------------+----------------------------------+\n| name | value | id |\n|----------+-------------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-webshop | 5752b6701026478f9cac122fc54eb9cb |\n| user | democompany-webshopuser | ce213655559d47d7800501124fed4d02 |\n| password | vEvM9vgRESdffWE2 | |\n+----------+-------------------------+----------------------------------+\n"})}),"\n",(0,i.jsx)(n.h4,{id:"create-additional-project-with-unlimited-quota",children:"Create additional project with unlimited quota"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name styles --quota-class unlimited\n+----------+--------------------+----------------------------------+\n| name | value | id |\n|----------+--------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-styles | 666097e396fd4f9392d6aa55c76d8267 |\n+----------+--------------------+----------------------------------+\n"})}),"\n",(0,i.jsx)(n.h4,{id:"set-quotas-for-a-project",children:"Set quotas for a project"}),"\n",(0,i.jsxs)(n.p,{children:["All quota information must be set as a property to the Openstack project within your Openstack Cluster, if no property is set, the ",(0,i.jsx)(n.code,{children:"basic"})," quotaclass of ",(0,i.jsx)(n.code,{children:"etc/classes.yml"})," will be applied.\nIt is possible to set a quota multiplier for any project."]}),"\n",(0,i.jsx)(n.p,{children:"The following command you set a multiplier of 256 of the basic quota:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack project set --property quotamultiplier=256 democompany-webshop\n"})}),"\n",(0,i.jsx)(n.p,{children:"Adjusting gigabyte quota for storage with a multiplier of 20 of the basic quota for a project:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack project set --property quotamultiplier_storage=20 democompany-webshop\n"})}),"\n",(0,i.jsx)(n.p,{children:"This will override the general quotamultiplier only for storage."}),"\n",(0,i.jsxs)(n.p,{children:["Other possible multiplier which can be set individually are: ",(0,i.jsx)(n.code,{children:"quotamultiplier_compute"}),", ",(0,i.jsx)(n.code,{children:"quotamultiplier_network"}),", ",(0,i.jsx)(n.code,{children:"quota_router"})]}),"\n",(0,i.jsxs)(n.p,{children:["To change the quotaclass to unlimited from the ",(0,i.jsx)(n.code,{children:"etc/classes.yaml"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ openstack project set --property quotaclass=unlimited democompany-webshop\n"})}),"\n",(0,i.jsx)(n.h4,{id:"special-project-images",children:"Special project: images"}),"\n",(0,i.jsxs)(n.p,{children:["With this special Project you can share all images uploaded into this project to all other project in your domain which has set the property ",(0,i.jsx)(n.code,{children:"has-shared-images"}),", which is by default set.\nAlsoi only the domain-admin user has access to this project, other domain users won't see this, they will find the uploaded images in their projects.\nIf you want your grant other domain users also access to upload some images, you need to give them access to the images Project in Openstack."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name images\n+---------+---------------------+----------------------------------+\n| name | value | id |\n|---------+---------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-images | 6d57f39aacbe485d87733865b1e79d03 |\n+---------+---------------------+----------------------------------+\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Additionally you need to add the domain and domain-admin user to the ",(0,i.jsx)(n.code,{children:"clouds.yaml"}),", it is always named ",(0,i.jsx)(n.code,{children:"opm-domainname-admin:"})," so the manage.py can setup permissions to the projects later on and users are able to find the images."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:" opm-democompany-admin:\n auth:\n auth_url: https://keystone.my.cloud:5000/v3\n username: democompany-admin\n password: yourpassword\n user_domain_name: Default\n project_domain_name: democompany \n identity_api_version: 3\n"})}),"\n",(0,i.jsx)(n.h4,{id:"special-project-service",children:"Special project: service"}),"\n",(0,i.jsx)(n.p,{children:"With this special project you can share installed services, like a harbor, to all other projects in your domain. Per default, only the domain admin has access to this project."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name service\n+---------+---------------------+----------------------------------+\n| name | value | id |\n|---------+---------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-service | a5558f7338f94adea5f41858636256b5 |\n+---------+---------------------+----------------------------------+\n"})}),"\n",(0,i.jsx)(n.h3,{id:"managepy-1",children:"manage.py"}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["This command applies quotas, networks and routers to ",(0,i.jsx)(n.strong,{children:"all"})," projects in the Openstack Cluster, not only to those have been configured previously with the ",(0,i.jsx)(n.code,{children:"create.py"})," or ",(0,i.jsx)(n.code,{children:"openstack project set --property"})," commands."]})}),"\n",(0,i.jsx)(n.p,{children:"Best is to run this command by cron, every hour to apply all pending changes, it is also possible to run this at the command line to apply changes immediately."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"python3 src/manage.py -h\nusage: manage [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--classes CLASSES] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--domain DOMAIN] [--dry-run]\n [--endpoints ENDPOINTS] [--manage-endpoints] [--manage-homeprojects] [--name NAME] [--noassign-admin-user] [--nodry-run] [--nomanage-endpoints] [--nomanage-homeprojects]\n\noptions:\n -h, --help show this help message and exit\n --admin-domain ADMIN_DOMAIN\n Admin domain\n --assign-admin-user Assign admin user\n --classes CLASSES Path to the classes.yml file\n --cloud CLOUD Cloud name in clouds.yaml\n --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set\n is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the\n command-line.\n --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the\n command-line.\n --domain DOMAIN Domain to be managed\n --dry-run Do not really do anything\n --endpoints ENDPOINTS\n Path to the endpoints.yml file\n --manage-endpoints Manage endpoints\n --manage-homeprojects\n Manage home projects\n --name NAME Project to be managed\n --noassign-admin-user\n The inverse of --assign-admin-user\n --nodry-run The inverse of --dry-run\n --nomanage-endpoints The inverse of --manage-endpoints\n --nomanage-homeprojects\n The inverse of --manage-homeprojects\n"})}),"\n",(0,i.jsx)(n.h4,{id:"manage-a-specific-domain-only",children:"Manage a specific domain only"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python3 src/manage.py --domain democompany\n\n2024-04-19 14:24:02.873 | INFO | democompany - domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03\n2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03, domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:04.953 | INFO | democompany-images - quotaclass {'compute': {'cores': 0, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 0, 'key_pairs': 0, 'metadata_items': 128, 'ram': 0, 'server_group_members': 0, 'server_groups': 0}, 'network': {'floatingip': 0, 'network': 0, 'port': 0, 'rbac_policy': 0, 'router': 0, 'security_group': 0, 'security_group_rule': 0, 'subnet': 0, 'subnetpool': 0}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 1000, 'per_volume_gigabytes': 25, 'snapshots': 0, 'volumes': 100}, 'parent': 'default'}\n2024-04-19 14:24:04.953 | INFO | democompany-images - check network quota\n2024-04-19 14:24:05.048 | INFO | democompany-images - check compute quota\n2024-04-19 14:24:05.175 | INFO | democompany-images - check volume quota\n2024-04-19 14:24:05.286 | INFO | democompany-images - check if external rbac policy must be deleted (public)\n2024-04-19 14:24:05.349 | INFO | democompany-images - check if service rbac policy must be deleted (democompany-service)\n2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5\n2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5, domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:06.131 | INFO | democompany-service - quotaclass {'compute': {'cores': 256, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 256, 'key_pairs': 256, 'metadata_items': 128, 'ram': 262144, 'server_group_members': 256, 'server_groups': 256}, 'network': {'floatingip': 256, 'network': 256, 'port': 256, 'rbac_policy': 1024, 'router': 256, 'security_group': 256, 'security_group_rule': 1024, 'subnet': 256, 'subnetpool': 256}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 0, 'per_volume_gigabytes': 0, 'snapshots': 0, 'volumes': 0}, 'parent': 'default'}\n2024-04-19 14:24:06.131 | INFO | democompany-service - check network quota\n2024-04-19 14:24:06.212 | INFO | democompany-service - check compute quota\n2024-04-19 14:24:06.330 | INFO | democompany-service - check volume quota\n2024-04-19 14:24:06.467 | INFO | democompany-service - check if external rbac policy must be created (public)\n2024-04-19 14:24:06.589 | INFO | democompany-service - check if service rbac policy must be deleted (democompany-service)\n2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb\n2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb, domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:06.915 | INFO | democompany-webshop - quotaclass {'compute': {'cores': 4, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': -1, 'key_pairs': 4, 'metadata_items': 128, 'ram': 8192, 'server_group_members': 4, 'server_groups': 4}, 'network': {'floatingip': 4, 'network': 1, 'port': 20, 'rbac_policy': 10, 'router': 0, 'security_group': 5, 'security_group_rule': 20, 'subnet': 2, 'subnetpool': 1}, 'volume': {'backup_gigabytes': 40, 'backups': 8, 'gigabytes': 20, 'per_volume_gigabytes': 200, 'snapshots': 4, 'volumes': 4}, 'parent': 'default'}\n2024-04-19 14:24:06.915 | INFO | democompany-webshop - check network quota\n2024-04-19 14:24:06.993 | INFO | democompany-webshop - check compute quota\n2024-04-19 14:24:07.114 | INFO | democompany-webshop - check volume quota\n2024-04-19 14:24:07.254 | INFO | democompany-webshop - check if external rbac policy must be created (public)\n2024-04-19 14:24:07.334 | INFO | democompany-webshop - check if service rbac policy must be deleted (democompany-service)\n"})}),"\n",(0,i.jsx)(n.h2,{id:"config-files",children:"Config files"}),"\n",(0,i.jsxs)(n.p,{children:["The config files which can be used for ",(0,i.jsx)(n.code,{children:"create.py"})," and ",(0,i.jsx)(n.code,{children:"manage.py"})," are using the ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/oslo.config/latest/configuration/quickstart.html",children:"oslo.config format"}),", you can set the command line options as ",(0,i.jsx)(n.code,{children:"key = value pair"})," and create your own config files matching your setup."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="democompany.conf"',children:"[DEFAULT]\ncloud = admin\ndomain = democompany\n"})}),"\n",(0,i.jsx)(n.h2,{id:"quota-templates",children:"Quota Templates"}),"\n",(0,i.jsxs)(n.p,{children:["Edit the ",(0,i.jsx)(n.code,{children:"etc/classes.yml"})," file if you want to change or add new quota templates"]}),"\n",(0,i.jsx)(n.h2,{id:"setup-endpoints",children:"Setup Endpoints"}),"\n",(0,i.jsxs)(n.p,{children:["Edit the ",(0,i.jsx)(n.code,{children:"etc/endpoints.yml"})," file to fit your available endpoints"]})]})}function m(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>r});var o=a(96540);const i={},t=o.createContext(i);function s(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a70dabb3.97147162.js b/assets/js/a70dabb3.97147162.js new file mode 100644 index 0000000000..86852b7b67 --- /dev/null +++ b/assets/js/a70dabb3.97147162.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[45075],{78806:(s,t,e)=>{e.r(t),e.d(t,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>i});const n=JSON.parse('{"id":"global/scs-0002","title":"scs-0002: Standards, Docs and Organisation","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/global/scs-0002.md","sourceDirName":"global","slug":"/global/scs-0002","permalink":"/standards/global/scs-0002","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0001-v1-sovereign-cloud-standards"},"next":{"title":"V1","permalink":"/standards/scs-0002-v1-standards-docs-org"}}');var d=e(74848),r=e(28453);const a={},c="scs-0002: Standards, Docs and Organisation",o={},i=[];function l(s){const t={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...s.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(t.header,{children:(0,d.jsx)(t.h1,{id:"scs-0002-standards-docs-and-organisation",children:"scs-0002: Standards, Docs and Organisation"})}),"\n",(0,d.jsxs)(t.table,{children:[(0,d.jsx)(t.thead,{children:(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.th,{children:"Version"}),(0,d.jsx)(t.th,{children:"Type"}),(0,d.jsx)(t.th,{children:"State"}),(0,d.jsx)(t.th,{children:"stabilized"}),(0,d.jsx)(t.th,{children:"deprecated"})]})}),(0,d.jsxs)(t.tbody,{children:[(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"/standards/scs-0002-v1-standards-docs-org",children:"scs-0002-v1"})}),(0,d.jsx)(t.td,{children:"Procedural"}),(0,d.jsx)(t.td,{children:"Stable"}),(0,d.jsx)(t.td,{children:"2023-02-06"}),(0,d.jsx)(t.td,{children:"-"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"/standards/scs-0002-v2-standards-docs-org",children:"scs-0002-v2"})}),(0,d.jsx)(t.td,{children:"Procedural"}),(0,d.jsx)(t.td,{children:"Draft"}),(0,d.jsx)(t.td,{children:"-"}),(0,d.jsx)(t.td,{children:"-"})]})]})]})]})}function h(s={}){const{wrapper:t}={...(0,r.R)(),...s.components};return t?(0,d.jsx)(t,{...s,children:(0,d.jsx)(l,{...s})}):l(s)}},28453:(s,t,e)=>{e.d(t,{R:()=>a,x:()=>c});var n=e(96540);const d={},r=n.createContext(d);function a(s){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof s?s(t):{...t,...s}}),[t,s])}function c(s){let t;return t=s.disableParentContext?"function"==typeof s.components?s.components(d):s.components||d:a(s.components),n.createElement(r.Provider,{value:t},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/a7456010.d921c339.js b/assets/js/a7456010.d921c339.js new file mode 100644 index 0000000000..dbbb94c997 --- /dev/null +++ b/assets/js/a7456010.d921c339.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[61235],{88552:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-pages","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/a7769c8a.7076b235.js b/assets/js/a7769c8a.7076b235.js new file mode 100644 index 0000000000..d8dd2eae16 --- /dev/null +++ b/assets/js/a7769c8a.7076b235.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[84093],{12411:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"releases/Release7","title":"Release Notes for SCS Release 7","description":"Release 7 has been published on September 11, 2024.","source":"@site/docs/06-releases/Release7.md","sourceDirName":"06-releases","slug":"/releases/Release7","permalink":"/docs/releases/Release7","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release7.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Release Notes for SCS Release 6","permalink":"/docs/releases/Release6"},"next":{"title":"FAQ","permalink":"/docs/faq/"}}');var a=n(74848),i=n(28453);const o={},r="Release Notes for SCS Release 7",l={},c=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"IaaS",id:"iaas",level:3},{value:"KaaS",id:"kaas",level:3},{value:"Cluster Stack <code>SCS</code>",id:"cluster-stack-scs",level:4},{value:"Host Cluster Stack release assets on an OCI registry",id:"host-cluster-stack-release-assets-on-an-oci-registry",level:4},{value:"Build node images with csctl for use in openstack",id:"build-node-images-with-csctl-for-use-in-openstack",level:4},{value:"New Features (Highlights)",id:"new-features-highlights",level:2},{value:"Operator focused improvements",id:"operator-focused-improvements",level:3},{value:"IaaS",id:"iaas-1",level:3},{value:"SCS Developer focused improvements (testbed and k8s cluster management)",id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",level:3},{value:"Tech Preview: Central API",id:"tech-preview-central-api",level:3},{value:"Tech Preview: Automated pentesting for IaaS and KaaS",id:"tech-preview-automated-pentesting-for-iaas-and-kaas",level:3},{value:"Tech Preview: SCS Health Monitor",id:"tech-preview-scs-health-monitor",level:3},{value:"Status Page: 1.0 Full Release",id:"status-page-10-full-release",level:3},{value:"KaaS",id:"kaas-1",level:3},{value:"Multi-Stage-Addons support in Cluster Stack Operator",id:"multi-stage-addons-support-in-cluster-stack-operator",level:4},{value:"Tech Preview: Cluster Gen - GUI for generating Cluster objects",id:"tech-preview-cluster-gen---gui-for-generating-cluster-objects",level:4},{value:"Tech Preview: Kamaji",id:"tech-preview-kamaji",level:4},{value:"Openstack csp helper",id:"openstack-csp-helper",level:4},{value:"IAM",id:"iam",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R7",id:"list-of-known-issues--restrictions-in-r7",level:2},{value:"IAM",id:"iam-1",level:3},{value:"KaaS",id:"kaas-2",level:3},{value:"OVN Loadbalancers",id:"ovn-loadbalancers",level:3},{value:"Contributing",id:"contributing",level:2},{value:"On to R8 ...",id:"on-to-r8-",level:2},{value:"Thanks",id:"thanks",level:2}];function h(e){const s={a:"a",br:"br",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(s.header,{children:(0,a.jsx)(s.h1,{id:"release-notes-for-scs-release-7",children:"Release Notes for SCS Release 7"})}),"\n",(0,a.jsx)(s.p,{children:"Release 7 has been published on September 11, 2024."}),"\n",(0,a.jsx)(s.h2,{id:"scope",children:"Scope"}),"\n",(0,a.jsxs)(s.p,{children:["We had stated the goals of previous releases in terms of desired outcomes. For R7, we built on top of\n",(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/releases/Release6#scope",children:"R6"})," and continued in the same direction."]}),"\n",(0,a.jsxs)(s.p,{children:["With R7 being the last release during the original funded SCS project, we put a lot of focus on finalizing\nthe work on many of the components. Major progress was achieved for example in the area of observability\n(status page, new health monitor) and of course again in the cluster stacks, our Kubernetes as a Service\nframework. Finalizing also means a lot of non-feature work, such as ensuring that tests exist and pass,\ndocumentation, guides and blog articles are written and upstream contributions are done. An extra\nfocus was put on integrating the components well with each other and documenting the performance of a\ncomplete SCS deployment better. One result of this is the\n",(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/turnkey-solution/overview",children:"turnkey solution overview table"}),",\nanother one the Technical Preview for our\n",(0,a.jsx)(s.a,{href:"https://scs.community/tech/2024/08/13/central-api-tech-preview-release/",children:"Central API"})," where we\ndemonstrate our vision of one API for all of the SCS stack in a usable form."]}),"\n",(0,a.jsx)(s.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,a.jsx)(s.h3,{id:"iaas",children:"IaaS"}),"\n",(0,a.jsxs)(s.p,{children:["The IaaS reference implementation is based on ",(0,a.jsx)(s.a,{href:"https://osism.tech/docs/release-notes/osism-8",children:"OSISM 8.0.0"}),"\nand delivers the following components:"]}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.a,{href:"https://releases.openstack.org/caracal/highlights.html",children:"OpenStack 2024.1 (Caracal)"})}),"\n",(0,a.jsxs)(s.li,{children:["Default Ceph version is ",(0,a.jsx)(s.a,{href:"https://docs.ceph.com/en/latest/releases/quincy/#v17-2-7-quincy",children:"Ceph Quincy"}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsxs)(s.li,{children:[(0,a.jsx)(s.a,{href:"https://docs.ceph.com/en/latest/releases/reef/#v18-2-4-reef",children:"Ceph Reef"})," is available as an option"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(s.li,{children:"Support for deployments on Ubuntu 22.04, Ubuntu 24.04, CentOS 9 and Debian 12"}),"\n"]}),"\n",(0,a.jsx)(s.p,{children:"Throughout the R7 development cycle numerous, eight in total, minor releases of OSISM have been released.\nOne of the core ideas of SCS is to move towards a very incremental approach so that keeping infrastructure\nup to date is made easy - as such many of the features and improvements that are now part of the Release 7\nhave been shipped as part of one of the minor releases working towards Release 7."}),"\n",(0,a.jsx)(s.h3,{id:"kaas",children:"KaaS"}),"\n",(0,a.jsxs)(s.h4,{id:"cluster-stack-scs",children:["Cluster Stack ",(0,a.jsx)(s.code,{children:"SCS"})]}),"\n",(0,a.jsxs)(s.p,{children:["SCS KaaS v2, better known as SCS Cluster Stacks are the new reference implementation for managing SCS compliant Kubernetes on SCS compliant infrastructure.\nWhile we recommend to build Cluster Stacks for own purposes, the SCS projects provides preassembled Cluster Stacks to try out on OpenStack. These are simply called ",(0,a.jsx)(s.code,{children:"SCS"})," and come with a number of configuration options, which can be found in the ",(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration",children:"SCS Docs"}),"."]}),"\n",(0,a.jsx)(s.h4,{id:"host-cluster-stack-release-assets-on-an-oci-registry",children:"Host Cluster Stack release assets on an OCI registry"}),"\n",(0,a.jsxs)(s.p,{children:["With the first versions of SCS Cluster Stacks the only way to host the release assets was GitHub Releases. This made cross-team testing harder and lead to an unusual amount of releases on specific GitHub repositories.",(0,a.jsx)(s.br,{}),"\n","With SCS R7 it will be possible to put publish the Cluster Stack release assets on an OCI registry."]}),"\n",(0,a.jsx)(s.h4,{id:"build-node-images-with-csctl-for-use-in-openstack",children:"Build node images with csctl for use in openstack"}),"\n",(0,a.jsxs)(s.p,{children:["The ",(0,a.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/csctl-plugin-openstack",children:"csctl-plugin-openstack"})," can now be used to build node images and upload them directly to Swift Object Store."]}),"\n",(0,a.jsx)(s.h2,{id:"new-features-highlights",children:"New Features (Highlights)"}),"\n",(0,a.jsx)(s.h3,{id:"operator-focused-improvements",children:"Operator focused improvements"}),"\n",(0,a.jsx)(s.h3,{id:"iaas-1",children:"IaaS"}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsx)(s.li,{children:"The Prometheus node-exporter is now deployed on all nodes by default."}),"\n",(0,a.jsx)(s.li,{children:"cAdvisor is now deployed on all nodes by default."}),"\n",(0,a.jsxs)(s.li,{children:["It is now possible to manage custom images with ",(0,a.jsx)(s.code,{children:"osism manage images"}),"."]}),"\n",(0,a.jsxs)(s.li,{children:["It is now possible to manage custom flavors with ",(0,a.jsx)(s.code,{children:"osism manage flavors"}),"."]}),"\n",(0,a.jsxs)(s.li,{children:["Various commands for disabling nodes, such as ",(0,a.jsx)(s.code,{children:"osism apply disable-compute-node"})," have been added."]}),"\n",(0,a.jsx)(s.li,{children:"With the osism manage image octavia command it is possible to rotate the Octavia Amphora image, which is rebuilt daily."}),"\n",(0,a.jsx)(s.li,{children:"With the osism manage image clusterapi command it is possible to import all currently stable Cluster API images"}),"\n"]}),"\n",(0,a.jsx)(s.h3,{id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",children:"SCS Developer focused improvements (testbed and k8s cluster management)"}),"\n",(0,a.jsx)(s.h3,{id:"tech-preview-central-api",children:"Tech Preview: Central API"}),"\n",(0,a.jsx)(s.p,{children:"The idea of a central API for all API services in SCS was further evaluated, conceptualized and a PoC implemented. This implementation is now available as a Tech Preview for CSPs to deploy it at their own site."}),"\n",(0,a.jsx)(s.p,{children:"Deploying the Central API is done into a dedicated Kubernetes cluster, which will then host the Crossplane operator for connections to backend systems."}),"\n",(0,a.jsxs)(s.p,{children:["End-customers will then be able to create Kubernetes resources in the ",(0,a.jsx)(s.code,{children:"api.scs.community"})," group, for example a ",(0,a.jsx)(s.code,{children:"Cluster"})," resource to create a new Kubernetes workload cluster."]}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsxs)(s.li,{children:["Repository: ",(0,a.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/central-api/",children:"https://github.com/SovereignCloudStack/central-api/"})]}),"\n",(0,a.jsxs)(s.li,{children:["Documentation of PoC: ",(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/central-api/poc-setup",children:"https://docs.scs.community/docs/operating-scs/components/central-api/poc-setup"})]}),"\n"]}),"\n",(0,a.jsx)(s.h3,{id:"tech-preview-automated-pentesting-for-iaas-and-kaas",children:"Tech Preview: Automated pentesting for IaaS and KaaS"}),"\n",(0,a.jsx)(s.p,{children:"The security team has worked on a methodology for automated security scans that are specifically put together for SCS. This covers both the infrastructure-as-a-service layer and the Kubernetes container layer."}),"\n",(0,a.jsx)(s.p,{children:"For IaaS, a pipeline of tools is executed, with each tool covering different aspects of security weaknesses and the anticipated attack surface of the layer."}),"\n",(0,a.jsx)(s.p,{children:"For KaaS, the focus currently lies on the Trivy scanner, which can be deployed both as an ad-hoc scan and as a continuously running Operator in Kubernetes. This also includes a custom-made exporter for reports."}),"\n",(0,a.jsx)(s.p,{children:"Since both layers produce vulnerability reports, which CSPs might want to delegate to their security teams, the deployment of DefectDojo is part of the Tech Preview."}),"\n",(0,a.jsx)(s.p,{children:"For non-vulnerability reports, an export to S3/Swift was implemented and can be adjusted according to the CSP's needs."}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsxs)(s.li,{children:["Documentation for IaaS pentesting: ",(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/automated-pentesting-iaas/overview/",children:"https://docs.scs.community/docs/operating-scs/components/automated-pentesting-iaas/overview/"})]}),"\n",(0,a.jsxs)(s.li,{children:["Documentation for KaaS pentesting: ",(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/automated-pentesting-kaas/overview/",children:"https://docs.scs.community/docs/operating-scs/components/automated-pentesting-kaas/overview/"})]}),"\n"]}),"\n",(0,a.jsx)(s.h3,{id:"tech-preview-scs-health-monitor",children:"Tech Preview: SCS Health Monitor"}),"\n",(0,a.jsx)(s.p,{children:"As announced in the Release Notes for R6, a new health monitor was in the works during the last months. With R7 we are now at the state of releasing the first Tech Preview of the new SCS Health Monitor. It not only covers the infrastructure-as-a-service layer, but also has workflows for Kubernetes tests."}),"\n",(0,a.jsxs)(s.p,{children:["While the SCSHM took many IaaS-related inspirations from the OSHM, the developer team for the new SCSHM has built an entirely new foundation for behavior-driven testing in SCS. The implementation is based on the Python ",(0,a.jsx)(s.code,{children:"behave"})," framework, using the Gherkin language for test definitions. Using Python allows the tool to then use Python-native API clients for OpenStack and Kubernetes, with room for extension for many other tools in SCS as well."]}),"\n",(0,a.jsx)(s.p,{children:"During the test run, metrics and results are collected and exported via a Prometheus Push Gateway into a Grafana-based dashboard."}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsxs)(s.li,{children:["Documentation: ",(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/category/scs-health-monitor",children:"https://docs.scs.community/docs/category/scs-health-monitor"})]}),"\n",(0,a.jsxs)(s.li,{children:["Repository: ",(0,a.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor",children:"https://github.com/SovereignCloudStack/scs-health-monitor"})]}),"\n"]}),"\n",(0,a.jsx)(s.h3,{id:"status-page-10-full-release",children:"Status Page: 1.0 Full Release"}),"\n",(0,a.jsxs)(s.p,{children:["The Status Page, ",(0,a.jsx)(s.a,{href:"https://scs.community/de/tech/2024/04/30/status-page-tech-preview-release/",children:"formerly available as a tech preview"}),", has now been feature-complete for its first full release as version 1.0."]}),"\n",(0,a.jsx)(s.p,{children:"The status page is the web frontend to our status API server, a record keeper of any incidents that may limit or break parts of your SCS infrastructure. While the tech preview version was limited to displaying this data, this full release contains not just improvements to the code working in the background, but also two new features:"}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsxs)(s.li,{children:["The new ",(0,a.jsx)(s.em,{children:"Maintenance Events"})," are a type of incident that are set in the future and allow you to announce planned times of limited or non-existent service well in advance, right on the status page."]}),"\n",(0,a.jsxs)(s.li,{children:["The ",(0,a.jsx)(s.em,{children:"Management Page"})," provides a convenient interface to create and update incidents and maintenance events using a web UI, secured behind an authorization system using OpenID."]}),"\n"]}),"\n",(0,a.jsxs)(s.p,{children:["The ",(0,a.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/status-page-deployment",children:"status-page-deployment repository"})," and ",(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/overview",children:"its documentation"})," contain full example and development setups. Check the ",(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/quickstart",children:"Quickstart Guide"})," to see what you need to run your own API server with status page or visit the SCS project's ",(0,a.jsx)(s.a,{href:"https://status.k8s.scs.community/",children:"publicly hosted installation"})," to get an impression."]}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsxs)(s.li,{children:[(0,a.jsx)(s.code,{children:"status-page-openapi"})," (concepts)","\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi",children:"Repository"})}),"\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/category/concepts",children:"Documentation"})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(s.li,{children:[(0,a.jsx)(s.code,{children:"status-page-api"})," (API server reference implementation)","\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/status-page-api",children:"Repository"})}),"\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/category/api",children:"Documentation"})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(s.li,{children:[(0,a.jsx)(s.code,{children:"status-page-deployment"})," (examples and templates, including a development setup based on kind)","\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/status-page-deployment",children:"Repository"})}),"\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/overview",children:"Documentation"})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(s.li,{children:[(0,a.jsx)(s.code,{children:"status-page-web"})," (frontend code and development instructions)","\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/status-page-web",children:"Repository"})}),"\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.a,{href:"https://docs.scs.community/docs/category/web",children:"Documentation"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(s.p,{children:["Also see the ",(0,a.jsx)(s.a,{href:"https://scs.community/de/tech/2024/04/30/status-page-tech-preview-release/",children:"Tech preview announcement post"}),"."]}),"\n",(0,a.jsx)(s.h3,{id:"kaas-1",children:"KaaS"}),"\n",(0,a.jsx)(s.h4,{id:"multi-stage-addons-support-in-cluster-stack-operator",children:"Multi-Stage-Addons support in Cluster Stack Operator"}),"\n",(0,a.jsx)(s.p,{children:"The Multi-Stage-Addons mark a key feature of the Cluster Stacks approach. It enables the Cluster Stack Operator to upgrade clusters in predefined ways using Cluster API Lifecycle Hooks. Cluster upgrades can be painful, if e.g. new Kubernetes versions won't support the current used CNI. With the Multi-Stage-Addons the order of upgrades can be defined in a specific order which ensures the compatibility of components."}),"\n",(0,a.jsx)(s.h4,{id:"tech-preview-cluster-gen---gui-for-generating-cluster-objects",children:"Tech Preview: Cluster Gen - GUI for generating Cluster objects"}),"\n",(0,a.jsxs)(s.p,{children:["As a user of a ClusterAPI based managed Kubernetes the interface is the ",(0,a.jsx)(s.code,{children:"Cluster"})," object. To define this can be complicated and depends on the used ClusterClass. With ",(0,a.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-gen/",children:"Cluster-Gen"})," the possible options will be pulled from an existing ClusterClass to provide a form which can be used to create the ",(0,a.jsx)(s.code,{children:"Cluster"})," object to apply it to the management cluster, which results in the usable workload cluster."]}),"\n",(0,a.jsx)(s.h4,{id:"tech-preview-kamaji",children:"Tech Preview: Kamaji"}),"\n",(0,a.jsx)(s.p,{children:"Kamaji is a Control Plane manager which makes it possible to host Control Planes on pods instead on dedicated VMs. This makes them highly scalable and safes a lot of resources. We now provide Cluster Stacks using Kamaji as Control Plane provider, which can be especially interesting for smaller CSPs."}),"\n",(0,a.jsx)(s.h4,{id:"openstack-csp-helper",children:"Openstack csp helper"}),"\n",(0,a.jsxs)(s.p,{children:["The ",(0,a.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/openstack-csp-helper",children:"openstack-csp-helper"})," is a simple Helm Chart to build and deploy the needed secrets used in the management cluster (to create the machines) and in the workload cluster (to get persistent volumes and loadbalancers) from a usual ",(0,a.jsx)(s.code,{children:"clouds.yaml"})," file."]}),"\n",(0,a.jsx)(s.h3,{id:"iam",children:"IAM"}),"\n",(0,a.jsx)(s.p,{children:"The keycloak container has been updated and the build process has seen further automation.\nThe container is now deployed into the internal infrastructure k3s, using the modern\nKubernetes-based interfaces that OSISM has provided to allow providers to plug-in\nadditional components at the management layer."}),"\n",(0,a.jsx)(s.p,{children:"The work that SCS has done on a clean role model including the domain manager role\nneeded for self-service user and role management has successfully been discussed\nupstream and contributed there. This means that the SCS downstream implementation\ncan be dropped and replaced by the upstream one in the next release R8."}),"\n",(0,a.jsx)(s.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsxs)(s.li,{children:["For the IaaS reference implementation, please refer to the ",(0,a.jsx)(s.a,{href:"https://osism.tech/docs/release-notes/osism-8#800-20240911",children:"OSISM 8.0.0 Upgrade Notes"}),"."]}),"\n"]}),"\n",(0,a.jsx)(s.h2,{id:"removals",children:"Removals"}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsxs)(s.li,{children:["The following roles have been removed from OSISM, most of them do not affect the SCS operators in any real matter:","\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.code,{children:"osism.services.bird"})}),"\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.code,{children:"osism.commons.kompose"})}),"\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.code,{children:"osism.services.openldap"})}),"\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.code,{children:"osism.services.openstack_health_monitor"})}),"\n",(0,a.jsx)(s.li,{children:(0,a.jsx)(s.code,{children:"osism.validations.refstack"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(s.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsx)(s.li,{children:"KaaS v1 (k8s-cluster-api-provider)"}),"\n"]}),"\n",(0,a.jsx)(s.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,a.jsx)(s.p,{children:"During the R7 development cycle a few security issues were reported and we issued security\nadvisories and addressed them via maintenance updates for R6 (and some also R5). All of these\nissues are also fixed in the upcoming R7 release. These include:"}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsxs)(s.li,{children:["A ",(0,a.jsx)(s.a,{href:"https://scs.community/security/2024/07/02/cve-2024-32498/",children:"Security Advisory on arbitrary file access through QCOW2 external data file (CVE-2024-32498)"})]}),"\n",(0,a.jsxs)(s.li,{children:["A ",(0,a.jsx)(s.a,{href:"https://scs.community/security/2024/07/23/cve-2024-40767/",children:"Security Advisory on incomplete QCOW2 and VMDK image handling protections (CVE-2024-40767)"})]}),"\n",(0,a.jsxs)(s.li,{children:["A ",(0,a.jsx)(s.a,{href:"https://scs.community/security/2024/09/07/cve-2024-44082/",children:"Security Advisory on Image Processing in Ironic"})]}),"\n"]}),"\n",(0,a.jsx)(s.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,a.jsx)(s.p,{children:"This release brings quality-of-life improvements such as:"}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsxs)(s.li,{children:["improved documentation of the certification scopes: they now include formal parameters,\nsuch as the image spec file for the standard on standard images (",(0,a.jsx)(s.a,{href:"https://docs.scs.community/standards/scs-compatible-iaas/",children:"SCS-compatible IaaS\nv4"}),"),"]}),"\n",(0,a.jsxs)(s.li,{children:["removal of unnecessary strictness from the standard\n",(0,a.jsx)(s.a,{href:"https://docs.scs.community/standards/scs-0103-v1-standard-flavors/",children:"scs-0103-v1"}),"\non standard flavors, enabling operators to provide more meaningful information via ",(0,a.jsx)(s.code,{children:"extra_specs"}),","]}),"\n",(0,a.jsx)(s.li,{children:"improved output and documentation of the main check script,"}),"\n",(0,a.jsx)(s.li,{children:"and bug fixes on the test scripts."}),"\n"]}),"\n",(0,a.jsxs)(s.p,{children:["We are quite pleased that it could be shown in May that compliance with the certificate scope\nSCS-compatible IaaS v4 can be achieved with an alternative implementation (other than our reference\nimplementation), namely Yaook,\n",(0,a.jsx)(s.a,{href:"https://scs.community/de/2024/05/13/cost-of-making-an-openstack-cluster-scs-compliant/",children:"with reasonable effort"}),"."]}),"\n",(0,a.jsx)(s.p,{children:"Finally, we are also happy that we could welcome new partners to our table of SCS clouds, namely AOV,\nSysEleven, and, with proof-of-concept environments, the companies KDO Service GmbH and Cloud&Heat\nTechnologies GmbH."}),"\n",(0,a.jsx)(s.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,a.jsx)(s.p,{children:"OSISM uses the tag 8.0.0 for SCS R7 and some of the related repositories in the SCS project\nuse a similar tag. Some repositories use maintained (stable) branches where the amount of changes\nis limited to mainly bug and security fixes to make life easier for our operators that need to\nstay on top of our security fixes without incurring too much change. Please note that by default,\nwe will stop maintaining the old R6 branches after October. Also note that we have been\nable to establish a larger number of smaller changes during the R6 lifecycle to facilitate\nthe increasing insight that 4 (well-tested) small changes are less risky that one step with\n3x the amount of changes. We will continue to work with our operators to ensure there is a\ngood balance between effort (4 small changes is more operational effort!) and risk."}),"\n",(0,a.jsx)(s.h2,{id:"list-of-known-issues--restrictions-in-r7",children:"List of known issues & restrictions in R7"}),"\n",(0,a.jsx)(s.h3,{id:"iam-1",children:"IAM"}),"\n",(0,a.jsxs)(s.p,{children:["The most underestimated topic for SCS as probably the creation of a self-service federated\nIdentity- and Access Management. While we were able to connect an external Identity Provider\nvia OpenID Connect and fix the issues with API access before, we still have not achieved\nthe full vision with customers being able to configuring everything via self-service.\nOur work on the domain-manager role (persona) in OpenStack has been contributed upstream, so\nwe have an aligned view on this finally. Unfortunately, we will only get the results of\nthis into the next release (R8) when we use OpenStack 2024.2 (Dalamatian). Discussing with\nour operators, we also learned about new requirements where ",(0,a.jsx)(s.em,{children:"some"})," user identities need to\nwork across several tenants and thus escape our simple view of users always belonging to\na tenant. This topic will keep us busy for the next few releases."]}),"\n",(0,a.jsx)(s.h3,{id:"kaas-2",children:"KaaS"}),"\n",(0,a.jsx)(s.p,{children:"As already in R6, we do not yet have the handling of restrictive security\ngroups implemented nor the ability to avoid OpenStack scheduling more than one\ncontrol plane node on the same host (hypervisor).\nThose features are in review upstream."}),"\n",(0,a.jsx)(s.h3,{id:"ovn-loadbalancers",children:"OVN Loadbalancers"}),"\n",(0,a.jsxs)(s.p,{children:["The octavia ovn load balancer provider has a file descriptor leak which can lead\nto a dysfunctional octavia-api service. The ",(0,a.jsx)(s.a,{href:"https://github.com/osism/issues/issues/959",children:"bug"}),"\nis still in analysis; for now,\nrestarting the octavia-api service before the exhaustion is the workaround."]}),"\n",(0,a.jsx)(s.h2,{id:"contributing",children:"Contributing"}),"\n",(0,a.jsxs)(s.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,a.jsx)(s.a,{href:"https://scs.community/contribute/",children:"How to contribute page"}),"."]}),"\n",(0,a.jsx)(s.h2,{id:"on-to-r8-",children:"On to R8 ..."}),"\n",(0,a.jsx)(s.p,{children:"We expect the continuation of our half-yearly cycle and thus an R8 in March. A lot of the work on the\nSCS components was done via tenders paid for and managed by the OSBA (with the funding from the german\ngovernment / BMWK). The inclusion and exclusion of software components in future releases will depend\nmore on the willingness of the component maintainers than on the setup of the SCS work packages; we\nanticipate more projects to seek alignment with SCS while existing projects can more easily work\nwith loser coupling. We will make this transparent to the community in order to ensure that we\nmaintain predictability for operators that rely on our technology."}),"\n",(0,a.jsx)(s.h2,{id:"thanks",children:"Thanks"}),"\n",(0,a.jsx)(s.p,{children:"Even more contribution from upstream communities and partners in the SCS ecosystem, too many\nto mention here. Technology can only be improved to a certain degree in the hands of capable\ndevelopment teams; the real push comes through usage and very well-working feedback loops\nfrom operators and users back into engineering. Not everyone realizes it, but Open Source\nallows for extremely direct feedback, as users have the full bandwidth of option from just\nchanneling a requirement or idea into the development via a full bug analysis up to code\ncontributions. So let us use the opportunity for calling out to our operators and users.\nWe have been working on growing the SCS adoption further and are looking forward to\nfurther announcements during the next weeks."})]})}function d(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,a.jsx)(s,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>r});var t=n(96540);const a={},i=t.createContext(a);function o(e){const s=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function r(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a7bd4aaa.8c94a49f.js b/assets/js/a7bd4aaa.8c94a49f.js new file mode 100644 index 0000000000..3c87abf943 --- /dev/null +++ b/assets/js/a7bd4aaa.8c94a49f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[67098],{74532:(n,e,s)=>{s.r(e),s.d(e,{default:()=>d});s(96540);var r=s(61213),o=s(82565),t=s(23025),c=s(22831),i=s(41463),u=s(74848);function a(n){const{version:e}=n;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(i.A,{version:e.version,tag:(0,o.k)(e.pluginId,e.version)}),(0,u.jsx)(r.be,{children:e.noIndex&&(0,u.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})]})}function l(n){const{version:e,route:s}=n;return(0,u.jsx)(r.e3,{className:e.className,children:(0,u.jsx)(t.n,{version:e,children:(0,c.v)(s.routes)})})}function d(n){return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(a,{...n}),(0,u.jsx)(l,{...n})]})}}}]); \ No newline at end of file diff --git a/assets/js/a8f67d60.246a5b3b.js b/assets/js/a8f67d60.246a5b3b.js new file mode 100644 index 0000000000..1565dc026a --- /dev/null +++ b/assets/js/a8f67d60.246a5b3b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[18463],{31254:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>r,default:()=>h,frontMatter:()=>d,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"contribute/adding-docs-guide","title":"Adding Docs Guide","description":"In this Guide you will learn how to integrate your documentation to the SCS documentation, which you will find on docs.scs.community.","source":"@site/community/contribute/adding-docs-guide.md","sourceDirName":"contribute","slug":"/contribute/adding-docs-guide","permalink":"/community/contribute/adding-docs-guide","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Contribute to Docs","permalink":"/community/category/contribute-to-docs"},"next":{"title":"Documentation Files Structure","permalink":"/community/contribute/doc-files-structure-guide"}}');var o=t(74848),c=t(28453);const d={},r="Adding Docs Guide",s={},l=[{value:"Step 1 \u2013 Documentation type",id:"step-1--documentation-type",level:2},{value:"1. Technical Documentation",id:"1-technical-documentation",level:2},{value:"Step 1 \u2013 Checklist",id:"step-1--checklist",level:3},{value:"Step 2 \u2013 Adding your repo to the docs.json",id:"step-2--adding-your-repo-to-the-docsjson",level:3},{value:"2. Operational documentation",id:"2-operational-documentation",level:2},{value:"3. Community documentation",id:"3-community-documentation",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,c.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"adding-docs-guide",children:"Adding Docs Guide"})}),"\n",(0,o.jsxs)(n.p,{children:["In this Guide you will learn how to integrate your documentation to the SCS documentation, which you will find on ",(0,o.jsx)(n.a,{href:"https://docs.scs.community",children:"docs.scs.community"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"step-1--documentation-type",children:"Step 1 \u2013 Documentation type"}),"\n",(0,o.jsx)(n.p,{children:"Determine the type of your documentation and click to continue."}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"#1-technical-documentation",children:"Technical documentation"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"#2-operational-documentation",children:"Operational documentation"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"#3-community-documentation",children:"Community documentation"})}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["If unsure don't hestitate to ask us at ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/communication/matrix.md",children:"Matrix"})]}),"\n",(0,o.jsx)(n.h2,{id:"1-technical-documentation",children:"1. Technical Documentation"}),"\n",(0,o.jsx)(n.h3,{id:"step-1--checklist",children:"Step 1 \u2013 Checklist"}),"\n",(0,o.jsx)(n.p,{children:"Your repository containing the documentation has to..."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"be a public repository"}),"\n",(0,o.jsxs)(n.li,{children:["contain a directory named ",(0,o.jsx)(n.code,{children:"/doc"})," or ",(0,o.jsx)(n.code,{children:"/docs"})," within root, containing the documentation files"]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"The documentation files have to be in markdown format and..."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["comply ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/license-considerations.md",children:"SCS licensing guidelines"})]}),"\n",(0,o.jsxs)(n.li,{children:["match our","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/contribute/doc-files-structure-guide.md",children:"markdown file structure guideline"})}),"\n",(0,o.jsx)(n.li,{children:"linting Rules"}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/contribute/styleguide.md",children:"styleguide"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"step-2--adding-your-repo-to-the-docsjson",children:"Step 2 \u2013 Adding your repo to the docs.json"}),"\n",(0,o.jsxs)(n.p,{children:["File a Pull Request within the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs",children:"docs"})," repository and add your repo to the docs.package.json:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'[\n {\n "repo": "demo-organisation/demo-repository",\n "source": "doc/*.md",\n "target": "docs",\n "label": "demo-repository-label"\n }\n]\n'})}),"\n",(0,o.jsxs)(n.table,{children:[(0,o.jsx)(n.thead,{children:(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.th,{children:"key"}),(0,o.jsx)(n.th,{children:"description"})]})}),(0,o.jsxs)(n.tbody,{children:[(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:"repo"}),(0,o.jsx)(n.td,{children:"reference to github organisation and repository"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:"source"}),(0,o.jsx)(n.td,{children:"path to content to copy: Either glob matching individual markdown files OR the path of a single directory"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:"target"}),(0,o.jsx)(n.td,{children:"directory where the files should be copied to within the docs-page repo"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:"label"}),(0,o.jsx)(n.td,{children:"label for directory. only mandatory if source file is set to copy only *.md files and not the complete directory"})]})]})]}),"\n",(0,o.jsxs)(n.p,{children:["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 ",(0,o.jsx)(n.a,{href:"https://docs.scs.community",children:"documentation"})," page \u2013 now with your content."]}),"\n",(0,o.jsxs)(n.p,{children:["An explanation on how the sync & distill workflow and a guide on how to test it in a local development environment you will find ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/contribute/docs-workflow-explanation.md",children:"here"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"2-operational-documentation",children:"2. Operational documentation"}),"\n",(0,o.jsx)(n.p,{children:"Your doc files contain operational knowledge. Which layer in the stack do they belong to?"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsx)(n.li,{children:"iaas"}),"\n",(0,o.jsx)(n.li,{children:"iam"}),"\n",(0,o.jsx)(n.li,{children:"kaas"}),"\n",(0,o.jsx)(n.li,{children:"operations"}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["File a Pull Request within the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs",children:"docs"})," repository and add your markdown files to the fitting directory."]}),"\n",(0,o.jsx)(n.h2,{id:"3-community-documentation",children:"3. Community documentation"}),"\n",(0,o.jsxs)(n.p,{children:["Your doc files contain knowledge regarding our community? Choose the right directory. If unsure don't hestitate to ask us at ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/communication/matrix.md",children:"Matrix"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["File a Pull Request within the ",(0,o.jsx)(n.code,{children:"docs"})," repository and add your markdown files to the fitting directory."]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>r});var i=t(96540);const o={},c=i.createContext(o);function d(e){const n=i.useContext(c);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:d(e.components),i.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a94703ab.68fdd05f.js b/assets/js/a94703ab.68fdd05f.js new file mode 100644 index 0000000000..9ab1c8f4da --- /dev/null +++ b/assets/js/a94703ab.68fdd05f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[79048],{11377:(e,t,n)=>{n.r(t),n.d(t,{default:()=>be});var a=n(96540),o=n(18215),i=n(61213),s=n(17559),l=n(26972),r=n(60609),c=n(21312),d=n(23104),u=n(75062);const m={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var b=n(74848);function h(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,o]=(0,a.useState)(!1),i=(0,a.useRef)(!1),{startScroll:s,cancelScroll:l}=(0,d.gk)();return(0,d.Mq)(((e,n)=>{let{scrollY:a}=e;const s=n?.scrollY;s&&(i.current?i.current=!1:a>=s?(l(),o(!1)):a<t?o(!1):a+window.innerHeight<document.documentElement.scrollHeight&&o(!0))})),(0,u.$)((e=>{e.location.hash&&(i.current=!0,o(!1))})),{shown:n,scrollToTop:()=>s(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,c.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,o.A)("clean-btn",s.G.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(53109),x=n(56347),f=n(24581),j=n(6342),v=n(23465);function _(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const A={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function g(e){let{onClick:t}=e;return(0,b.jsx)("button",{type:"button",title:(0,c.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,o.A)("button button--secondary button--outline",A.collapseSidebarButton),onClick:t,children:(0,b.jsx)(_,{className:A.collapseSidebarButtonIcon})})}var k=n(65041),C=n(89532);const S=Symbol("EmptyContext"),T=a.createContext(S);function N(e){let{children:t}=e;const[n,o]=(0,a.useState)(null),i=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:o})),[n]);return(0,b.jsx)(T.Provider,{value:i,children:t})}var I=n(41422),B=n(99169),y=n(28774),w=n(92303);function L(e){let{collapsed:t,categoryLabel:n,onClick:a}=e;return(0,b.jsx)("button",{"aria-label":t?(0,c.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:n}):(0,c.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:n}),"aria-expanded":!t,type:"button",className:"clean-btn menu__caret",onClick:a})}function E(e){let{item:t,onItemClick:n,activePath:i,level:r,index:c,...d}=e;const{items:u,label:m,collapsible:h,className:p,href:x}=t,{docs:{sidebar:{autoCollapseCategories:f}}}=(0,j.p)(),v=function(e){const t=(0,w.A)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.Nr)(e):void 0),[e,t])}(t),_=(0,l.w8)(t,i),A=(0,B.ys)(x,i),{collapsed:g,setCollapsed:k}=(0,I.u)({initialState:()=>!!h&&(!_&&t.collapsed)}),{expandedItem:N,setExpandedItem:E}=function(){const e=(0,a.useContext)(T);if(e===S)throw new C.dV("DocSidebarItemsExpandedStateProvider");return e}(),M=function(e){void 0===e&&(e=!g),E(e?null:c),k(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:o}=e;const i=(0,C.ZC)(t);(0,a.useEffect)((()=>{t&&!i&&n&&o(!1)}),[t,i,n,o])}({isActive:_,collapsed:g,updateCollapsed:M}),(0,a.useEffect)((()=>{h&&null!=N&&N!==c&&f&&k(!0)}),[h,N,c,k,f]),(0,b.jsxs)("li",{className:(0,o.A)(s.G.docs.docSidebarItemCategory,s.G.docs.docSidebarItemCategoryLevel(r),"menu__list-item",{"menu__list-item--collapsed":g},p),children:[(0,b.jsxs)("div",{className:(0,o.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":A}),children:[(0,b.jsx)(y.A,{className:(0,o.A)("menu__link",{"menu__link--sublist":h,"menu__link--sublist-caret":!x&&h,"menu__link--active":_}),onClick:h?e=>{n?.(t),x?M(!1):(e.preventDefault(),M())}:()=>{n?.(t)},"aria-current":A?"page":void 0,role:h&&!x?"button":void 0,"aria-expanded":h&&!x?!g:void 0,href:h?v??"#":v,...d,children:m}),x&&h&&(0,b.jsx)(L,{collapsed:g,categoryLabel:m,onClick:e=>{e.preventDefault(),M()}})]}),(0,b.jsx)(I.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:g,children:(0,b.jsx)(U,{items:u,tabIndex:g?-1:0,onItemClick:n,activePath:i,level:r+1})})]})}var M=n(16654),H=n(43186);const G={menuExternalLink:"menuExternalLink_NmtK"};function W(e){let{item:t,onItemClick:n,activePath:a,level:i,index:r,...c}=e;const{href:d,label:u,className:m,autoAddBaseUrl:h}=t,p=(0,l.w8)(t,a),x=(0,M.A)(d);return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(i),"menu__list-item",m),children:(0,b.jsxs)(y.A,{className:(0,o.A)("menu__link",!x&&G.menuExternalLink,{"menu__link--active":p}),autoAddBaseUrl:h,"aria-current":p?"page":void 0,to:d,...x&&{onClick:n?()=>n(t):void 0},...c,children:[u,!x&&(0,b.jsx)(H.A,{})]})},u)}const P={menuHtmlItem:"menuHtmlItem_M9Kj"};function R(e){let{item:t,level:n,index:a}=e;const{value:i,defaultStyle:l,className:r}=t;return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(n),l&&[P.menuHtmlItem,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:i}},a)}function D(e){let{item:t,...n}=e;switch(t.type){case"category":return(0,b.jsx)(E,{item:t,...n});case"html":return(0,b.jsx)(R,{item:t,...n});default:return(0,b.jsx)(W,{item:t,...n})}}function F(e){let{items:t,...n}=e;const a=(0,l.Y)(t,n.activePath);return(0,b.jsx)(N,{children:a.map(((e,t)=>(0,b.jsx)(D,{item:e,index:t,...n},t)))})}const U=(0,a.memo)(F),V={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function Y(e){let{path:t,sidebar:n,className:i}=e;const l=function(){const{isActive:e}=(0,k.M)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,c.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,o.A)("menu thin-scrollbar",V.menu,l&&V.menuWithAnnouncementBar,i),children:(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:n,activePath:t,level:1})})})}const K="sidebar_njMd",z="sidebarWithHideableNavbar_wUlq",q="sidebarHidden_VK0M",O="sidebarLogo_isFc";function J(e){let{path:t,sidebar:n,onCollapse:a,isHidden:i}=e;const{navbar:{hideOnScroll:s},docs:{sidebar:{hideable:l}}}=(0,j.p)();return(0,b.jsxs)("div",{className:(0,o.A)(K,s&&z,i&&q),children:[s&&(0,b.jsx)(v.A,{tabIndex:-1,className:O}),(0,b.jsx)(Y,{path:t,sidebar:n}),l&&(0,b.jsx)(g,{onClick:a})]})}const Q=a.memo(J);var X=n(75600),Z=n(22069);const $=e=>{let{sidebar:t,path:n}=e;const a=(0,Z.M)();return(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&a.toggle(),"link"===e.type&&a.toggle()},level:1})})};function ee(e){return(0,b.jsx)(X.GX,{component:$,props:e})}const te=a.memo(ee);function ne(e){const t=(0,f.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(Q,{...e}),a&&(0,b.jsx)(te,{...e})]})}const ae={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function oe(e){let{toggleSidebar:t}=e;return(0,b.jsx)("div",{className:ae.expandButton,title:(0,c.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t,children:(0,b.jsx)(_,{className:ae.expandButtonIcon})})}const ie={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function se(e){let{children:t}=e;const n=(0,r.t)();return(0,b.jsx)(a.Fragment,{children:t},n?.name??"noSidebar")}function le(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:i}=e;const{pathname:l}=(0,x.zy)(),[r,c]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.O)()&&c(!0),i((e=>!e))}),[i,r]);return(0,b.jsx)("aside",{className:(0,o.A)(s.G.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&c(!0)},children:(0,b.jsx)(se,{children:(0,b.jsxs)("div",{className:(0,o.A)(ie.sidebarViewport,r&&ie.sidebarViewportHidden),children:[(0,b.jsx)(ne,{sidebar:t,path:l,onCollapse:d,isHidden:r}),r&&(0,b.jsx)(oe,{toggleSidebar:d})]})})})}const re={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ce(e){let{hiddenSidebarContainer:t,children:n}=e;const a=(0,r.t)();return(0,b.jsx)("main",{className:(0,o.A)(re.docMainContainer,(t||!a)&&re.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,o.A)("container padding-top--md padding-bottom--lg",re.docItemWrapper,t&&re.docItemWrapperEnhanced),children:n})})}const de={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function ue(e){let{children:t}=e;const n=(0,r.t)(),[o,i]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:de.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:de.docRoot,children:[n&&(0,b.jsx)(le,{sidebar:n.items,hiddenSidebarContainer:o,setHiddenSidebarContainer:i}),(0,b.jsx)(ce,{hiddenSidebarContainer:o,children:t})]})]})}var me=n(23363);function be(e){const t=(0,l.B5)(e);if(!t)return(0,b.jsx)(me.A,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,b.jsx)(i.e3,{className:(0,o.A)(s.G.page.docsDocPage),children:(0,b.jsx)(r.V,{name:a,items:c,children:(0,b.jsx)(ue,{children:n})})})}},23363:(e,t,n)=>{n.d(t,{A:()=>l});n(96540);var a=n(18215),o=n(21312),i=n(51107),s=n(74848);function l(e){let{className:t}=e;return(0,s.jsx)("main",{className:(0,a.A)("container margin-vert--xl",t),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(i.A,{as:"h1",className:"hero__title",children:(0,s.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/assets/js/a94c36cd.b00c2914.js b/assets/js/a94c36cd.b00c2914.js new file mode 100644 index 0000000000..c09a7a4842 --- /dev/null +++ b/assets/js/a94c36cd.b00c2914.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[51548],{59711:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>u});const n=JSON.parse('{"id":"container/overview/architecture","title":"Architecture","description":"TODO","source":"@site/docs/03-container/overview/architecture.md","sourceDirName":"03-container/overview","slug":"/container/overview/architecture","permalink":"/docs/container/overview/architecture","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/overview/architecture.md","tags":[],"version":"current","frontMatter":{}}');var c=r(74848),o=r(28453);const i={},s="Architecture",a={},u=[];function d(e){const t={h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(t.header,{children:(0,c.jsx)(t.h1,{id:"architecture",children:"Architecture"})}),"\n",(0,c.jsx)(t.p,{children:"TODO"})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>s});var n=r(96540);const c={},o=n.createContext(c);function i(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a9f40339.50671081.js b/assets/js/a9f40339.50671081.js new file mode 100644 index 0000000000..1f85ca3824 --- /dev/null +++ b/assets/js/a9f40339.50671081.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[86164],{20332:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>c,toc:()=>l});const c=JSON.parse('{"id":"operating-scs/lifecycle-management/index","title":"Overview","description":"TODO","source":"@site/docs/04-operating-scs/05-lifecycle-management/index.md","sourceDirName":"04-operating-scs/05-lifecycle-management","slug":"/operating-scs/lifecycle-management/","permalink":"/docs/operating-scs/lifecycle-management/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/05-lifecycle-management/index.md","tags":[],"version":"current","frontMatter":{}}');var s=t(74848),r=t(28453);const o={},i="Overview",a={},l=[];function d(e){const n={h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,s.jsx)(n.p,{children:"TODO"})]})}function m(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>i});var c=t(96540);const s={},r=c.createContext(s);function o(e){const n=c.useContext(r);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),c.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aaebd759.badbff06.js b/assets/js/aaebd759.badbff06.js new file mode 100644 index 0000000000..7a870e6ed5 --- /dev/null +++ b/assets/js/aaebd759.badbff06.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[77609],{36886:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Cluster Stacks","slug":"/category/cluster-stacks","permalink":"/docs/category/cluster-stacks","sidebar":"docs","navigation":{"previous":{"title":"Components","permalink":"/docs/category/components-1"},"next":{"title":"Overview","permalink":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/ab2759ca.6af1358f.js b/assets/js/ab2759ca.6af1358f.js new file mode 100644 index 0000000000..d2418f2107 --- /dev/null +++ b/assets/js/ab2759ca.6af1358f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[76153],{82553:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"scs-0005-v1-project-governance","title":"Governance of the SCS community","description":"SCS-0005 outlines the structure and governance of the SCS community by the SCS Project Board and how this is elected.\\n","source":"@site/standards/scs-0005-v1-project-governance.md","sourceDirName":".","slug":"/scs-0005-v1-project-governance","permalink":"/standards/scs-0005-v1-project-governance","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Governance of the SCS community","type":"Procedural","status":"Draft","track":"Global","description":"SCS-0005 outlines the structure and governance of the SCS community by the SCS Project Board and how this is elected.\\n"},"sidebar":"standards","previous":{"title":"scs-0005: Governance of the SCS community","permalink":"/standards/global/scs-0005"},"next":{"title":"IaaS Standards","permalink":"/standards/iaas/"}}');var o=t(74848),r=t(28453);const s={title:"Governance of the SCS community",type:"Procedural",status:"Draft",track:"Global",description:"SCS-0005 outlines the structure and governance of the SCS community by the SCS Project Board and how this is elected.\n"},a=void 0,l={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Role of the <em>SCS Project Board</em>",id:"role-of-the-scs-project-board",level:2},{value:"Definitions",id:"definitions",level:3},{value:"<em>SCS Project</em>",id:"scs-project",level:4},{value:"<em>SCS Community</em>",id:"scs-community",level:4},{value:"<em>SCS GitHub Organization</em>",id:"scs-github-organization",level:4},{value:"Roles in the <em>SCS GitHub Organization</em>",id:"roles-in-the-scs-github-organization",level:3},{value:"Members",id:"members",level:4},{value:"Owners",id:"owners",level:4},{value:"Joining the SCS GitHub Organization",id:"joining-the-scs-github-organization",level:2},{value:"Election of the <em>SCS Project Board</em>",id:"election-of-the-scs-project-board",level:2},{value:"Term",id:"term",level:3},{value:"Seats on the board",id:"seats-on-the-board",level:3},{value:"Nominations",id:"nominations",level:3},{value:"Eligible for voting",id:"eligible-for-voting",level:3},{value:"Electoral management",id:"electoral-management",level:3},{value:"Voting period",id:"voting-period",level:3},{value:"Announcement",id:"announcement",level:3},{value:"Mechanisms",id:"mechanisms",level:3},{value:"Roles in the <em>SCS Project Board</em>",id:"roles-in-the-scs-project-board",level:2}];function d(e){const n={a:"a",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.a,{href:"https://scs.community",children:"Sovereign Cloud Stack (SCS)"})," provides standards\nfor a range of cloud infrastructure types as well as a modular open-source\nreference implementation.\nThe project is governed by the ",(0,o.jsx)(n.em,{children:"SCS Project Board"}),"."]}),"\n",(0,o.jsxs)(n.h2,{id:"role-of-the-scs-project-board",children:["Role of the ",(0,o.jsx)(n.em,{children:"SCS Project Board"})]}),"\n",(0,o.jsxs)(n.p,{children:["The role of the ",(0,o.jsx)(n.em,{children:"SCS Project Board"})," is the overall governance of the SCS Community and Project.\nThis happens together with the ",(0,o.jsx)(n.em,{children:"Forum SCS-Standards"})," of the Open Source Business Alliance. To further\nunderline this alignment, the ",(0,o.jsx)(n.em,{children:"Forum SCS-Standards"})," is part of the ",(0,o.jsx)(n.em,{children:"SCS Project Board"}),".\nThe ",(0,o.jsx)(n.em,{children:"SCS Project Board"})," itself is elected by the ",(0,o.jsx)(n.em,{children:"SCS Community"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"definitions",children:"Definitions"}),"\n",(0,o.jsx)(n.h4,{id:"scs-project",children:(0,o.jsx)(n.em,{children:"SCS Project"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.em,{children:"SCS Project"}),' is the Open-Source project that consists of the software, documentation, documents, blog posts as well as the people ("',(0,o.jsx)(n.em,{children:"SCS Community"}),'") working on this.']}),"\n",(0,o.jsx)(n.h4,{id:"scs-community",children:(0,o.jsx)(n.em,{children:"SCS Community"})}),"\n",(0,o.jsxs)(n.p,{children:["The collective of people, companies, and organizations promoting the idea of the ",(0,o.jsx)(n.em,{children:"SCS Project"})," as well as the people working on the various aspects."]}),"\n",(0,o.jsx)(n.h4,{id:"scs-github-organization",children:(0,o.jsx)(n.em,{children:"SCS GitHub Organization"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.em,{children:"SCS GitHub Organization"})," is this: ",(0,o.jsx)(n.a,{href:"https://github.com/sovereigncloudstack",children:"https://github.com/sovereigncloudstack"})]}),"\n",(0,o.jsxs)(n.h3,{id:"roles-in-the-scs-github-organization",children:["Roles in the ",(0,o.jsx)(n.em,{children:"SCS GitHub Organization"})]}),"\n",(0,o.jsx)(n.h4,{id:"members",children:"Members"}),"\n",(0,o.jsxs)(n.p,{children:["Joining the SCS GitHub Organization as a contributor results in being assigned the ",(0,o.jsx)(n.strong,{children:"member role"})," in the organization. Members are contributors or collaborators who:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Actively contribute to projects within the organization."}),"\n",(0,o.jsx)(n.li,{children:"Have repository-specific access based on their contributions."}),"\n",(0,o.jsxs)(n.li,{children:["Are eligible to vote in elections and nominate candidates for the ",(0,o.jsx)(n.em,{children:"SCS Project Board"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Must adhere to the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/.github/blob/main/CODE_OF_CONDUCT.md",children:"Code of Conduct"}),"."]}),"\n"]}),"\n",(0,o.jsx)(n.h4,{id:"owners",children:"Owners"}),"\n",(0,o.jsxs)(n.p,{children:["Members of the ",(0,o.jsx)(n.em,{children:"SCS Project Board"})," are also designated as ",(0,o.jsx)(n.strong,{children:"owners"})," of the SCS GitHub organization. Owners have administrative privileges, including:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Managing organization-level settings."}),"\n",(0,o.jsx)(n.li,{children:"Onboarding new members."}),"\n",(0,o.jsx)(n.li,{children:"Enforcing compliance with governance and community standards."}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"This alignment ensures that governance roles in the SCS Project Board directly translate into operational responsibilities within the GitHub organization."}),"\n",(0,o.jsx)(n.h2,{id:"joining-the-scs-github-organization",children:"Joining the SCS GitHub Organization"}),"\n",(0,o.jsx)(n.p,{children:"Since being part of the GitHub organization comes with a set of responsibilities, joining the SCS GitHub Organization can be done by:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["being invited by the ",(0,o.jsx)(n.em,{children:"SCS Project Board"})]}),"\n",(0,o.jsxs)(n.li,{children:["submitting a request to be onboarded as a member to the ",(0,o.jsx)(n.em,{children:"SCS Project Board"})]}),"\n",(0,o.jsx)(n.li,{children:"have existing members of the GitHub organization nominate you"}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"One of these items is sufficient."}),"\n",(0,o.jsxs)(n.p,{children:["Actively contributing to one or several of the projects under the governance of the SCS project board should typically result in a membership. Please be aware of our ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/.github/blob/main/CODE_OF_CONDUCT.md",children:"Code of Conduct"}),"."]}),"\n",(0,o.jsxs)(n.h2,{id:"election-of-the-scs-project-board",children:["Election of the ",(0,o.jsx)(n.em,{children:"SCS Project Board"})]}),"\n",(0,o.jsx)(n.h3,{id:"term",children:"Term"}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.em,{children:"SCS Project Board"})," is elected for the term of one year. Elections are done\nwithin the last six weeks of the calendar year."]}),"\n",(0,o.jsx)(n.h3,{id:"seats-on-the-board",children:"Seats on the board"}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.em,{children:"SCS Project Board"})," contains five seats. One of these seats is filled by\nthe delegate of the ",(0,o.jsx)(n.em,{children:"Forum SCS-Standards"}),". The other four seats are voted upon."]}),"\n",(0,o.jsx)(n.h3,{id:"nominations",children:"Nominations"}),"\n",(0,o.jsxs)(n.p,{children:['Every person who is part of the Sovereign Cloud Stack GitHub organization can be\nnominated for the board. Likewise, one can nominate oneself.\nThe nomination is done by adding the person with the required data to the file corresponding to the term in the "Community-Governance" folder in the ',(0,o.jsx)(n.a,{href:"https://github.com/sovereignCloudStack/standards/",children:"Standards"})," repository. Obviously, the person, that is to be nominated, should be asked before being added to the file."]}),"\n",(0,o.jsx)(n.h3,{id:"eligible-for-voting",children:"Eligible for voting"}),"\n",(0,o.jsx)(n.p,{children:'Every person who is a member of the GitHub organization "Sovereign Cloud Stack" is eligible for voting. In order to be able to vote an onboarding onto the Identity Management of the SCS community needs to happen.'}),"\n",(0,o.jsx)(n.h3,{id:"electoral-management",children:"Electoral management"}),"\n",(0,o.jsxs)(n.p,{children:["The voting process is governed by the ",(0,o.jsx)(n.em,{children:"Forum SCS-Standards"}),".\nVoting is done using the ",(0,o.jsx)(n.a,{href:"https://civs.cs.cornell.edu",children:"Condorcet Internet Voting Service"}),". This is the same system as is ",(0,o.jsx)(n.a,{href:"https://wiki.openstack.org/wiki/Election_Officiating_Guidelines#Running_the_election_itself",children:"being used by the OpenInfra foundation"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"voting-period",children:"Voting period"}),"\n",(0,o.jsx)(n.p,{children:"The voting will be open for a week."}),"\n",(0,o.jsx)(n.h3,{id:"announcement",children:"Announcement"}),"\n",(0,o.jsxs)(n.p,{children:["The voting will be announced on the SCS-Members Mailinglist as well as on the ",(0,o.jsx)(n.a,{href:"https://matrix.to/#/#scs-general:matrix.org",children:"General & Announcements"}),". Enlisted voters will receive e-mails to the email address used in the SCS community's Identity Management system."]}),"\n",(0,o.jsx)(n.h3,{id:"mechanisms",children:"Mechanisms"}),"\n",(0,o.jsxs)(n.p,{children:["Each eligible voter is asked to rank the candidates according to their priorities.\nThe four favorite choices among all voters will be elected into the ",(0,o.jsx)(n.em,{children:"SCS Project Board"}),"."]}),"\n",(0,o.jsxs)(n.h2,{id:"roles-in-the-scs-project-board",children:["Roles in the ",(0,o.jsx)(n.em,{children:"SCS Project Board"})]}),"\n",(0,o.jsx)(n.p,{children:"Among the elected Project Board a spokesperson is nominated. The spokesperson is\nelected by a simple majority vote among the members of the project board. The\nspokesperson is elected for the whole term."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>a});var i=t(96540);const o={},r=i.createContext(o);function s(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aba21aa0.5d49a645.js b/assets/js/aba21aa0.5d49a645.js new file mode 100644 index 0000000000..57d0ed0f15 --- /dev/null +++ b/assets/js/aba21aa0.5d49a645.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[35742],{27093:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/abb47370.912c6252.js b/assets/js/abb47370.912c6252.js new file mode 100644 index 0000000000..284d6079f5 --- /dev/null +++ b/assets/js/abb47370.912c6252.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[85075],{38554:(e,n,t)=>{t.r(n),t.d(n,{TableCellStyleApplier:()=>l,assets:()=>o,contentTitle:()=>c,default:()=>m,frontMatter:()=>a,metadata:()=>s,toc:()=>h});const s=JSON.parse('{"id":"iam/index","title":"IAM Standards","description":"This track revolves around Identity and Access Management (IAM) standards, providing guidelines for ensuring secure and efficient user authentication, authorization, and administration. It addresses issues related to user identity, permissions, roles, and policies, aiming to safeguard and streamline access to cloud resources and services.","source":"@site/standards/iam/index.md","sourceDirName":"iam","slug":"/iam/","permalink":"/standards/iam/","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0219-w1-kaas-networking"},"next":{"title":"scs-0300: Requirements for SSO identity federation","permalink":"/standards/iam/scs-0300"}}');var r=t(74848),i=t(28453),d=t(96540);const a={},c="IAM Standards",o={},l=()=>{const e={3:"#FBFDE2",4:"#E2EAFD",5:"#FDE2E2"},n={2:"#FBFDE2",3:"#E2EAFD",4:"#FDE2E2"};return(0,d.useEffect)((()=>{const t=(e,n)=>{const t=document.querySelector("#"+e);if(t){const e=t.nextElementSibling;e&&"table"===e.tagName.toLowerCase()&&e.querySelectorAll("tbody tr").forEach((e=>{e.querySelectorAll("td").forEach(((e,t)=>{n[t]&&"-"!==e.textContent.trim()&&(e.style.backgroundColor=n[t])}))}))}};t("color-table-cells-overview",e),t("color-table-cells-track-overview",n)}),[]),null},h=[];function u(e){const n={a:"a",h1:"h1",header:"header",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"iam-standards",children:"IAM Standards"})}),"\n",(0,r.jsx)(n.p,{children:"This track revolves around Identity and Access Management (IAM) standards, providing guidelines for ensuring secure and efficient user authentication, authorization, and administration. It addresses issues related to user identity, permissions, roles, and policies, aiming to safeguard and streamline access to cloud resources and services."}),"\n",(0,r.jsx)("p",{children:"*Legend to the column headings and entries:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Document states: Draft, Effective, Deprecated (and no longer effective)"}),"\n",(0,r.jsx)(n.li,{children:"Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future"}),"\n",(0,r.jsx)(n.li,{children:"Entries in the effective column marked with a \u2020 will turn deprecated in the near future"}),"\n"]}),"\n","\n","\n",(0,r.jsx)(l,{}),"\n",(0,r.jsx)("div",{id:"color-table-cells-track-overview"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Standard"}),(0,r.jsx)(n.th,{children:"Description"}),(0,r.jsx)(n.th,{children:"Draft"}),(0,r.jsx)(n.th,{children:"Effective"}),(0,r.jsx)(n.th,{children:"Deprecated*"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/standards/iam/scs-0300",children:"scs-0300"})}),(0,r.jsx)(n.td,{children:"Requirements for SSO identity federation"}),(0,r.jsx)(n.td,{children:"-"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/standards/scs-0300-v1-requirements-for-sso-identity-federation",children:"v1"})}),(0,r.jsx)(n.td,{children:"-"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/standards/iam/scs-0301",children:"scs-0301"})}),(0,r.jsx)(n.td,{children:"Naming for domains/groups/roles/project when onboarding new customers"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/standards/scs-0301-v1-naming-conventions",children:"v1"})}),(0,r.jsx)(n.td,{children:"-"}),(0,r.jsx)(n.td,{children:"-"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/standards/iam/scs-0302",children:"scs-0302"})}),(0,r.jsx)(n.td,{children:"Domain Manager configuration for Keystone"}),(0,r.jsx)(n.td,{children:"-"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/standards/scs-0302-v1-domain-manager-role",children:"v1"})}),(0,r.jsx)(n.td,{children:"-"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{}),(0,r.jsx)(n.td,{children:"Supplement: Domain Manager implementation notes"}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/standards/scs-0302-w1-domain-manager-implementation-notes",children:"w1"})}),(0,r.jsx)(n.td,{children:"-"}),(0,r.jsx)(n.td,{children:"-"})]})]})]})]})}function m(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>a});var s=t(96540);const r={},i=s.createContext(r);function d(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/abd5b058.ddc4f600.js b/assets/js/abd5b058.ddc4f600.js new file mode 100644 index 0000000000..df1a04ab7b --- /dev/null +++ b/assets/js/abd5b058.ddc4f600.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[66846],{15176:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>o,frontMatter:()=>d,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"iaas/scs-0121","title":"scs-0121: SCS Availability Zones","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0121.md","sourceDirName":"iaas","slug":"/iaas/scs-0121","permalink":"/standards/iaas/scs-0121","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0120-v1-capi-images"},"next":{"title":"V1","permalink":"/standards/scs-0121-v1-Availability-Zones-Standard"}}');var a=s(74848),i=s(28453);const d={},r="scs-0121: SCS Availability Zones",l={},c=[{value:"Supplement: Implementation and Testing Notes",id:"supplement-implementation-and-testing-notes",level:2}];function h(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"scs-0121-scs-availability-zones",children:"scs-0121: SCS Availability Zones"})}),"\n",(0,a.jsxs)(t.table,{children:[(0,a.jsx)(t.thead,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.th,{children:"Version"}),(0,a.jsx)(t.th,{children:"Type"}),(0,a.jsx)(t.th,{children:"State"}),(0,a.jsx)(t.th,{children:"stabilized"}),(0,a.jsx)(t.th,{children:"deprecated"})]})}),(0,a.jsx)(t.tbody,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.td,{children:(0,a.jsx)(t.a,{href:"/standards/scs-0121-v1-Availability-Zones-Standard",children:"scs-0121-v1"})}),(0,a.jsx)(t.td,{children:"Standard"}),(0,a.jsx)(t.td,{children:"Stable"}),(0,a.jsx)(t.td,{children:"2024-11-13"}),(0,a.jsx)(t.td,{children:"-"})]})})]}),"\n",(0,a.jsx)(t.h2,{id:"supplement-implementation-and-testing-notes",children:"Supplement: Implementation and Testing Notes"}),"\n",(0,a.jsxs)(t.table,{children:[(0,a.jsx)(t.thead,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.th,{children:"Version"}),(0,a.jsx)(t.th,{children:"State"}),(0,a.jsx)(t.th,{children:"stabilized"}),(0,a.jsx)(t.th,{children:"deprecated"})]})}),(0,a.jsx)(t.tbody,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.td,{children:(0,a.jsx)(t.a,{href:"/standards/scs-0121-w1-Availability-Zones-Standard",children:"w1"})}),(0,a.jsx)(t.td,{children:"Draft"}),(0,a.jsx)(t.td,{children:"-"}),(0,a.jsx)(t.td,{children:"-"})]})})]})]})}function o(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>r});var n=s(96540);const a={},i=n.createContext(a);function d(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/abd7a988.ce89e052.js b/assets/js/abd7a988.ce89e052.js new file mode 100644 index 0000000000..a88f2bd9e4 --- /dev/null +++ b/assets/js/abd7a988.ce89e052.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[42747],{68537:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"container/components/container-registry/docs/ha-deployment","title":"HA deployment","description":"Prerequisites","source":"@site/docs/03-container/components/container-registry/docs/ha-deployment.md","sourceDirName":"03-container/components/container-registry/docs","slug":"/container/components/container-registry/docs/ha-deployment","permalink":"/docs/container/components/container-registry/docs/ha-deployment","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/ha-deployment.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Persistence","permalink":"/docs/container/components/container-registry/docs/persistence"},"next":{"title":"Operating SCS","permalink":"/docs/category/operating-scs"}}');var t=s(74848),i=s(28453);const l={},o="HA deployment",a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install and wait for operators",id:"install-and-wait-for-operators",level:2},{value:"Create redis and postgres clusters",id:"create-redis-and-postgres-clusters",level:2},{value:"Install Harbor",id:"install-harbor",level:2},{value:"All in one installation using FluxCD Kustomization and GitRepository reconciliation",id:"all-in-one-installation-using-fluxcd-kustomization-and-gitrepository-reconciliation",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"ha-deployment",children:"HA deployment"})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Kubernetes cluster v1.20+","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Use existing cluster","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"export KUBECONFIG=/path/to/kubeconfig\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Alternatively, spawn some dev cluster, e.g. using ",(0,t.jsx)(n.a,{href:"https://kind.sigs.k8s.io/docs/user/quick-start/",children:"KinD"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kind create cluster\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Flux CLI","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Installation documentation: ",(0,t.jsx)(n.a,{href:"https://fluxcd.io/flux/installation/#install-the-flux-cli",children:"https://fluxcd.io/flux/installation/#install-the-flux-cli"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s https://fluxcd.io/install.sh | sudo FLUX_VERSION=2.2.3 bash\nflux install\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"install-and-wait-for-operators",children:"Install and wait for operators"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ kubectl apply -k operators/\n$ flux get helmrelease -n default\nNAME REVISION SUSPENDED READY MESSAGE\ncert-manager v1.11.0 False True Release reconciliation succeeded\ningress-nginx 4.5.2 False True Release reconciliation succeeded\npostgres-operator 1.9.0 False True Release reconciliation succeeded\nredis-operator 3.2.7 False True Release reconciliation succeeded\n"})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Note: Install separate operators by e.g.:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"kubectl apply -k operators/redis/\nkubectl apply -k operators/postgres/\n"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"create-redis-and-postgres-clusters",children:"Create redis and postgres clusters"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"envs/public-ha/redis/redis-secret.bash # pwgen needs to be installed\nkubectl apply -k envs/public-ha/redis/\nkubectl apply -k envs/public-ha/postgres/\n"})}),"\n",(0,t.jsx)(n.h2,{id:"install-harbor",children:"Install Harbor"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Replace the ",(0,t.jsx)(n.code,{children:"example.com"})," URL in the ",(0,t.jsx)(n.code,{children:"harbor-config.yaml"})," file with the desired one."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Take ",(0,t.jsx)(n.em,{children:"ingress-nginx-controller"})," LoadBalancer IP address and create DNS record for Harbor."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"kubectl get svc -n ingress-nginx\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\ningress-nginx-controller LoadBalancer 100.92.14.168 81.163.194.219 80:30799/TCP,443:32482/TCP 2m51s\ningress-nginx-controller-admission ClusterIP 100.88.40.231 <none> 443/TCP 2m51s\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Generate secrets and install Harbor:"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["It is recommended to replace ",(0,t.jsx)(n.code,{children:"admin@example.com"})," email address in ",(0,t.jsx)(n.code,{children:"issuer.yaml"})," with your own.\nLet's Encrypt will use this to contact you about expiring certificates, and issues related to your account."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"base/harbor-secrets.bash # pwgen and htpasswd need to be installed\nenvs/public-ha/swift-secret.bash <username> <password>\nkubectl apply -k envs/public-ha/\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"all-in-one-installation-using-fluxcd-kustomization-and-gitrepository-reconciliation",children:"All in one installation using FluxCD Kustomization and GitRepository reconciliation"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"envs/public-ha/redis/redis-secret.bash\nbase/harbor-secrets.bash\nenvs/public-ha/swift-secret.bash <username> <password>\n# --branch/tag can be specified, default to master\nflux create source git k8s-harbor --url=https://github.com/SovereignCloudStack/k8s-harbor --interval=5m\nkubectl apply -f envs/public-ha/public-ha.yaml\n"})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>o});var r=s(96540);const t={},i=r.createContext(t);function l(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/abecca15.c6b48db0.js b/assets/js/abecca15.c6b48db0.js new file mode 100644 index 0000000000..c03bfaef72 --- /dev/null +++ b/assets/js/abecca15.c6b48db0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[67560],{91877:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>l,contentTitle:()=>d,default:()=>g,frontMatter:()=>t,metadata:()=>s,toc:()=>a});const s=JSON.parse('{"id":"iaas/guides/deploy-guide/services/logging-monitoring","title":"Logging & Monitoring","description":"Common issues with deploying logging & monitoring services provided by Kolla","source":"@site/docs/02-iaas/guides/deploy-guide/services/logging-monitoring.md","sourceDirName":"02-iaas/guides/deploy-guide/services","slug":"/iaas/guides/deploy-guide/services/logging-monitoring","permalink":"/docs/iaas/guides/deploy-guide/services/logging-monitoring","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/logging-monitoring.md","tags":[],"version":"current","sidebarPosition":40,"frontMatter":{"sidebar_label":"Logging & Monitoring","sidebar_position":40},"sidebar":"docs","previous":{"title":"Network","permalink":"/docs/iaas/guides/deploy-guide/services/network"},"next":{"title":"Ceph","permalink":"/docs/iaas/guides/deploy-guide/services/ceph"}}');var o=n(74848),r=n(28453);const t={sidebar_label:"Logging & Monitoring",sidebar_position:40},d="Logging & Monitoring",l={},a=[];function c(e){const i={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(i.header,{children:(0,o.jsx)(i.h1,{id:"logging--monitoring",children:"Logging & Monitoring"})}),"\n",(0,o.jsxs)(i.p,{children:["Common issues with deploying logging & monitoring services provided by Kolla\nare documented in the ",(0,o.jsx)(i.a,{href:"/docs/iaas/guides/troubleshooting-guide/openstack",children:"OpenStack Troubleshooting Guide"}),"."]}),"\n",(0,o.jsxs)(i.ol,{children:["\n",(0,o.jsxs)(i.li,{children:["\n",(0,o.jsx)(i.p,{children:"OpenSearch"}),"\n",(0,o.jsxs)(i.p,{children:["OpenSearch dashboards is also deployed with the ",(0,o.jsx)(i.code,{children:"opensearch"})," role."]}),"\n",(0,o.jsx)(i.pre,{children:(0,o.jsx)(i.code,{children:"osism apply -a pull opensearch\nosism apply opensearch\n"})}),"\n"]}),"\n",(0,o.jsxs)(i.li,{children:["\n",(0,o.jsx)(i.p,{children:"Prometheus"}),"\n",(0,o.jsx)(i.pre,{children:(0,o.jsx)(i.code,{children:"osism apply -a pull prometheus\nosism apply prometheus\n"})}),"\n"]}),"\n",(0,o.jsxs)(i.li,{children:["\n",(0,o.jsx)(i.p,{children:"Grafana"}),"\n",(0,o.jsx)(i.pre,{children:(0,o.jsx)(i.code,{children:"osism apply -a pull grafana\nosism apply grafana\n"})}),"\n"]}),"\n"]})]})}function g(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,o.jsx)(i,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>t,x:()=>d});var s=n(96540);const o={},r=s.createContext(o);function t(e){const i=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function d(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),s.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/abfb0638.d59c1857.js b/assets/js/abfb0638.d59c1857.js new file mode 100644 index 0000000000..88d7b5e9b4 --- /dev/null +++ b/assets/js/abfb0638.d59c1857.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[76793],{55530:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"iaas/guides/operations-guide/manager/apply","title":"Apply","description":"With the apply command it is possible to run Ansible plays. These are executed as","source":"@site/docs/02-iaas/guides/operations-guide/manager/apply.md","sourceDirName":"02-iaas/guides/operations-guide/manager","slug":"/iaas/guides/operations-guide/manager/apply","permalink":"/docs/iaas/guides/operations-guide/manager/apply","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/manager/apply.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Apply"},"sidebar":"docs","previous":{"title":"Manager","permalink":"/docs/iaas/guides/operations-guide/manager/"},"next":{"title":"Console","permalink":"/docs/iaas/guides/operations-guide/manager/console"}}');var s=i(74848),t=i(28453);const o={sidebar_label:"Apply"},l="Apply",r={},c=[{value:"List all plays",id:"list-all-plays",level:2},{value:"Apply a play",id:"apply-a-play",level:2},{value:"Use of custom plays",id:"use-of-custom-plays",level:2},{value:"Example play with roles: Manage the infrastructure of the SCS testing environment",id:"example-play-with-roles-manage-the-infrastructure-of-the-scs-testing-environment",level:3},{value:"Example play: Wiping partitions",id:"example-play-wiping-partitions",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"apply",children:"Apply"})}),"\n",(0,s.jsxs)(n.p,{children:["With the ",(0,s.jsx)(n.code,{children:"apply"})," command it is possible to run Ansible plays. These are executed as\nbackground activity via a queuing system so that, for example, the loss of an SSH connection\ndoes not result in the execution being aborted. In this case, the logs can also be analyzed\n",(0,s.jsx)(n.a,{href:"./log",children:"retrospectively"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"list-all-plays",children:"List all plays"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"osism apply"})," command can be used to list all integrated playbooks and their associated\nenvironments. Custom plays that have been added in the configuration repository are not visible\nin this list."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ osism apply\n2023-09-30 10:09:25 | INFO | No role given for execution. The roles listed in the table can be used.\n+------------------------------------------------------------------+----------------+\n| Role | Environment |\n|------------------------------------------------------------------+----------------|\n| aodh | kolla |\n| barbican | kolla |\n| bifrost | kolla |\n| bifrost-keypair | kolla |\n| ceilometer | kolla |\n| certificates | generic |\n| cinder | kolla |\n| cloudkitty | kolla |\n| collectd | kolla |\n| common | kolla |\n| designate | kolla |\n| elasticsearch | kolla |\n| etcd | kolla |\n| glance | kolla |\n| gnocchi | kolla |\n| grafana | kolla |\n| heat | kolla |\n| horizon | kolla |\n| ironic | kolla |\n| iscsi | kolla |\n...\n"})}),"\n",(0,s.jsx)(n.h2,{id:"apply-a-play",children:"Apply a play"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ osism apply operator -l node01\n2024-06-14 09:33:10 | INFO | Task f94a2e6f-d199-421c-b7b7-743db4661305 (operator) was prepared for execution.\n2024-06-14 09:33:10 | INFO | It takes a moment until task f94a2e6f-d199-421c-b7b7-743db4661305 (operator) has been started and output is visible here.\n\nPLAY [Make ssh pipelining working] *********************************************\n\nTASK [Do not require tty for all users] ****************************************\nok: [node01]\n...\nPLAY RECAP *********************************************************************\n2024-06-14 09:34:14 | INFO | Play has been completed. There may now be a delay until all logs have been written.\n2024-06-14 09:34:14 | INFO | Please wait and do not abort execution.\nnode01 : ok=11 changed=0 unreachable=0 failed=0 skipped=5 rescued=0 ignored=0\n"})}),"\n",(0,s.jsx)(n.h2,{id:"use-of-custom-plays",children:"Use of custom plays"}),"\n",(0,s.jsx)(n.p,{children:"Custom plays can be used in all environments of the configuration repository to add\nlogic which should also be part of the configuration repository."}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsx)(n.p,{children:"It seems to us to be a good idea to minimize the amount of such special solutions, as extensive in-house\nsolutions can potentially result in unexpected interactions or additional testing-, integration and maintenance\nwork."}),(0,s.jsx)(n.p,{children:"We would also like to make a clear recommendation that, if possible, missing functions should be resolved by\ncontributing to OSISM."})]}),"\n",(0,s.jsx)(n.p,{children:"Some facts about custom plays:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Plays must be stored under the following naming scheme so that they can be executed with the OSISM command.\n",(0,s.jsx)(n.code,{children:"environments/<environment>/playbook-<the name of the play>.yml"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Without specifying a particular environment the ",(0,s.jsx)(n.code,{children:"custom"})," environment is used."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"# executes: environments/custom/playbook-setup-serial-device.yml\nosism apply setup-serial-device\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Specifying a play of a environment:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"# executes environments/deph/playbook-wipe-parititons.yml\nosism apply -e ceph wipe-parititons\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Custom roles that are used for a specific environment must be stored under the following path so that\nthey can be found by plays."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"environments/<environment>/roles/<role>/"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"example-play-with-roles-manage-the-infrastructure-of-the-scs-testing-environment",children:"Example play with roles: Manage the infrastructure of the SCS testing environment"}),"\n",(0,s.jsx)(n.p,{children:"The SCS hardware landscape testing environment provides a selection of custom roles which are used\nto manage some infrastructural aspects of this testing environment."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Instructions ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/hardware-landscape/blob/main/documentation/System_Deployment.md",children:"how to use"})," the custom code"]}),"\n",(0,s.jsxs)(n.li,{children:["The custom ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/hardware-landscape/tree/main/environments/custom",children:"plays and roles"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"example-play-wiping-partitions",children:"Example play: Wiping partitions"}),"\n",(0,s.jsx)(n.p,{children:"For example, this is a play to prepare all devices to be used for Ceph on a Ceph\nresource node."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["It is saved in the configuration repository in the file ",(0,s.jsx)(n.code,{children:"environments/ceph/playbook-wipe-partitions.yml"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["It is run with ",(0,s.jsx)(n.code,{children:"osism apply -e ceph wipe-parititons"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"Just to be on the safe side: The following example can be useful, but it can also cause a lot of damage. Be warned!"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/playbook-wipe-partitions.yml',children:'---\n- name: Wipe partitions\n hosts: ceph-resource\n gather_facts: false\n\n tasks:\n - name: Find all logical devices with prefix ceph\n ansible.builtin.find:\n paths: /dev/mapper\n recurse: false\n file_type: link\n patterns: "ceph*"\n register: result\n\n - name: Remove all ceph related logical devices\n become: true\n ansible.builtin.command: "dmsetup remove {{ item.path }}"\n loop: "{{ result.files }}"\n changed_when: true\n\n - name: Wipe partitions with wipefs\n become: true\n ansible.builtin.command: "wipefs --all {{ item }}"\n changed_when: true\n loop: "{{ ansible_local.testbed_ceph_devices_all }}"\n\n - name: Overwrite first 32M with zeros\n become: true\n ansible.builtin.command: "dd if=/dev/zero of={{ item }} bs=1M count=32 oflag=direct,dsync"\n changed_when: true\n loop: "{{ ansible_local.testbed_ceph_devices_all }}"\n'})})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>l});var a=i(96540);const s={},t=a.createContext(s);function o(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ac087500.941ecada.js b/assets/js/ac087500.941ecada.js new file mode 100644 index 0000000000..3941aad062 --- /dev/null +++ b/assets/js/ac087500.941ecada.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[38411],{87886:(e,o,i)=>{i.r(o),i.d(o,{assets:()=>d,contentTitle:()=>u,default:()=>l,frontMatter:()=>r,metadata:()=>s,toc:()=>a});const s=JSON.parse('{"id":"iaas/guides/troubleshooting-guide/index","title":"Troubleshooting Guide","description":"\ud83d\udca1 The Troubleshooting Guide describe how to solve issues.","source":"@site/docs/02-iaas/guides/troubleshooting-guide/index.md","sourceDirName":"02-iaas/guides/troubleshooting-guide","slug":"/iaas/guides/troubleshooting-guide/","permalink":"/docs/iaas/guides/troubleshooting-guide/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/troubleshooting-guide/index.md","tags":[],"version":"current","sidebarPosition":40,"frontMatter":{"sidebar_label":"Troubleshooting Guide","sidebar_position":40},"sidebar":"docs","previous":{"title":"Rookify (technical preview)","permalink":"/docs/iaas/guides/operations-guide/rookify"},"next":{"title":"Manager","permalink":"/docs/iaas/guides/troubleshooting-guide/manager"}}');var t=i(74848),n=i(28453);const r={sidebar_label:"Troubleshooting Guide",sidebar_position:40},u="Troubleshooting Guide",d={},a=[];function c(e){const o={h1:"h1",header:"header",p:"p",...(0,n.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.header,{children:(0,t.jsx)(o.h1,{id:"troubleshooting-guide",children:"Troubleshooting Guide"})}),"\n",(0,t.jsx)(o.p,{children:"\ud83d\udca1 The Troubleshooting Guide describe how to solve issues."})]})}function l(e={}){const{wrapper:o}={...(0,n.R)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,o,i)=>{i.d(o,{R:()=>r,x:()=>u});var s=i(96540);const t={},n=s.createContext(t);function r(e){const o=s.useContext(n);return s.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function u(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),s.createElement(n.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aca4bcb1.15d839cf.js b/assets/js/aca4bcb1.15d839cf.js new file mode 100644 index 0000000000..f538be5356 --- /dev/null +++ b/assets/js/aca4bcb1.15d839cf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[93750],{62662:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/terminology","title":"Terminology","description":"The Cluster Stacks are a framework and provide tools how to use them. The terminology is not perfect and if you have an idea how to improve it, please reach out. Right now there are the following terms:","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/terminology.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/terminology","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/terminology.md","tags":[],"version":"current","frontMatter":{}}');var r=o(74848),n=o(28453);const a={},i="Terminology",c={},l=[{value:"Cluster Stack framework",id:"cluster-stack-framework",level:2},{value:"A definition of a cluster stack",id:"a-definition-of-a-cluster-stack",level:2},{value:"An implementation of a cluster Stack",id:"an-implementation-of-a-cluster-stack",level:2},{value:"Cluster Stack Operator",id:"cluster-stack-operator",level:2},{value:"Cluster Stack Provider Integration",id:"cluster-stack-provider-integration",level:2},{value:"ClusterStack as custom resource definition",id:"clusterstack-as-custom-resource-definition",level:2}];function u(e){const t={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"terminology",children:"Terminology"})}),"\n",(0,r.jsx)(t.p,{children:"The Cluster Stacks are a framework and provide tools how to use them. The terminology is not perfect and if you have an idea how to improve it, please reach out. Right now there are the following terms:"}),"\n",(0,r.jsx)(t.h2,{id:"cluster-stack-framework",children:"Cluster Stack framework"}),"\n",(0,r.jsx)(t.p,{children:"The framework of cluster stacks refers to the fact that cluster stacks of any shape can be created for any provider that supports Cluster API. The framework has no opinion about how the Cluster Stacks have to look like, which configuration of node images and Kubernetes you use and which cluster addons you include."}),"\n",(0,r.jsx)(t.p,{children:"As long as a cluster stack is implemented and released in a correct way, the cluster-stack-operator will be able to use it, fully independent of the detailed architectural decisions that were taken with regards to how the clusters that come out of this cluster stack should look like."}),"\n",(0,r.jsx)(t.p,{children:'This flexibility is meant by the term "framework".'}),"\n",(0,r.jsx)(t.h2,{id:"a-definition-of-a-cluster-stack",children:"A definition of a cluster stack"}),"\n",(0,r.jsx)(t.p,{children:'A definition of a cluster stack is a document describing, independent of any provider, how a cluster stack xyz should look like. On a very high level, this could be something like "we want to use Ubuntu node images, basic Kubeadm and Cilium as CNI".'}),"\n",(0,r.jsx)(t.p,{children:"There is no template for such a definition and no pre-defined structure how such a definition should look like."}),"\n",(0,r.jsx)(t.p,{children:"A definition of a cluster stack xyz can be used as a base to implement this cluster stack xyz for providers a and b."}),"\n",(0,r.jsx)(t.h2,{id:"an-implementation-of-a-cluster-stack",children:"An implementation of a cluster Stack"}),"\n",(0,r.jsx)(t.p,{children:"A cluster stack can be implemented for a certain provider. The collection of configuration code, Helm charts, etc. is what we call an implementation of a cluster stack. The release assets that have to be generated from that is what people actually use, usually with the Cluster Stack Operator."}),"\n",(0,r.jsx)(t.h2,{id:"cluster-stack-operator",children:"Cluster Stack Operator"}),"\n",(0,r.jsx)(t.p,{children:"A Kubernetes operator that works with the release assets and applies resources in management and each workload cluster. It works together with Provider Integrations, if they are needed."}),"\n",(0,r.jsx)(t.h2,{id:"cluster-stack-provider-integration",children:"Cluster Stack Provider Integration"}),"\n",(0,r.jsx)(t.p,{children:"Provider integrations are needed if a user has to do manual steps on a provider to use custom node images for the nodes in a cluster. If no such steps are required, then the provider integration is not needed."}),"\n",(0,r.jsx)(t.h2,{id:"clusterstack-as-custom-resource-definition",children:"ClusterStack as custom resource definition"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"ClusterStack"})," is a CRD that the user interacts with directly. It shows in its status the state of the respective versions of this cluster stack that the user wants to have."]})]})}function d(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,o)=>{o.d(t,{R:()=>a,x:()=>i});var s=o(96540);const r={},n=s.createContext(r);function a(e){const t=s.useContext(n);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/acecf23e.7516ff6f.js b/assets/js/acecf23e.7516ff6f.js new file mode 100644 index 0000000000..84c11ebe72 --- /dev/null +++ b/assets/js/acecf23e.7516ff6f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[81903],{1912:s=>{s.exports=JSON.parse('{"blogBasePath":"/blog","blogTitle":"Blog","authorsListPath":"/blog/authors"}')}}]); \ No newline at end of file diff --git a/assets/js/ad1cb202.ee6712e8.js b/assets/js/ad1cb202.ee6712e8.js new file mode 100644 index 0000000000..9c0eca2b50 --- /dev/null +++ b/assets/js/ad1cb202.ee6712e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[93086],{13805:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"iaas/guides/concept-guide/components/gardener","title":"Gardener","description":"Kubernetes as a Service (KaaS) simplifies the deployment, management, and scaling of","source":"@site/docs/02-iaas/guides/concept-guide/components/gardener.md","sourceDirName":"02-iaas/guides/concept-guide/components","slug":"/iaas/guides/concept-guide/components/gardener","permalink":"/docs/iaas/guides/concept-guide/components/gardener","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/gardener.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster API","permalink":"/docs/iaas/guides/concept-guide/components/clusterapi"},"next":{"title":"Ironic","permalink":"/docs/iaas/guides/concept-guide/components/ironic"}}');var r=s(74848),a=s(28453);const i={},o="Gardener",c={},l=[{value:"Lifecycle Management of Gardener in OSISM",id:"lifecycle-management-of-gardener-in-osism",level:2}];function d(e){const n={h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"gardener",children:"Gardener"})}),"\n",(0,r.jsx)(n.p,{children:"Kubernetes as a Service (KaaS) simplifies the deployment, management, and scaling of\nKubernetes clusters by abstracting the underlying infrastructure. Gardener by SAP is\nan advanced KaaS solution that leverages a Kubernetes-native approach to manage\nKubernetes clusters at scale. Gardener is designed to provide consistent and efficient\ncluster management across various cloud environments and on-premises data centers."}),"\n",(0,r.jsx)(n.p,{children:"Key benefits of Gardener include:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Kubernetes-Native Design: Gardener operates by treating Kubernetes clusters as first-class\ncitizens. It uses Kubernetes itself to orchestrate the deployment and management of other\nKubernetes clusters, ensuring that all operations are consistent and follow Kubernetes best\npractices."}),"\n",(0,r.jsxs)(n.li,{children:["Shoot, Seed, and Garden Clusters:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Shoot Clusters: These are the user clusters managed by Gardener, running the workloads."}),"\n",(0,r.jsx)(n.li,{children:"Seed Clusters: These clusters host the control planes of shoot clusters and are managed by\nthe Gardener infrastructure."}),"\n",(0,r.jsx)(n.li,{children:"Garden Cluster: This is the central cluster where the Gardener components run and from which\nall other clusters (seed and shoot) are managed."}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.li,{children:"Multi-Cloud and Hybrid Cloud Support: Gardener supports deployment across various cloud providers,\nincluding AWS, Azure, Google Cloud, and OpenStack, as well as on-premises environments.\nThis multi-cloud capability allows for a consistent Kubernetes experience regardless of the\nunderlying infrastructure."}),"\n",(0,r.jsx)(n.li,{children:"Automated Cluster Management: Gardener automates the lifecycle management of Kubernetes clusters,\nincluding provisioning, scaling, upgrading, and healing. This automation reduces operational\noverhead and ensures clusters are always running optimally."}),"\n",(0,r.jsx)(n.li,{children:"High Availability and Resilience: Gardener ensures high availability by distributing control\nplanes across multiple seed clusters and leveraging cloud provider features to enhance resilience.\nThis design minimizes downtime and enhances the reliability of managed clusters."}),"\n",(0,r.jsx)(n.li,{children:"Extensibility and Customization: Gardener\u2019s architecture allows for customization and extensibility\nthrough extensions and webhooks. This flexibility enables organizations to tailor the solution to\nmeet specific requirements and integrate with existing tools and processes."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"By using Gardener by SAP for Kubernetes as a Service, organisations can achieve a scalable,\nautomated and consistent approach to managing Kubernetes clusters across multiple environments.\nThis allows them to focus on delivering business value through their applications, rather\nthan dealing with the complexities of cluster management."}),"\n",(0,r.jsx)(n.h2,{id:"lifecycle-management-of-gardener-in-osism",children:"Lifecycle Management of Gardener in OSISM"})]})}function u(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>o});var t=s(96540);const r={},a=t.createContext(r);function i(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad39e84b.931af984.js b/assets/js/ad39e84b.931af984.js new file mode 100644 index 0000000000..15dd2339a5 --- /dev/null +++ b/assets/js/ad39e84b.931af984.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[44657],{21556:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"scs-0102-v1-image-metadata","title":"SCS Image Metadata","description":"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating\\nsystem images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements,\\nimage handling protocols including updating and origin, and licensing/support details. These guidelines ensure\\nthat users can understand, access, and utilize OS images effectively, with clear information on features, updates,\\nand licensing provided through well-defined metadata properties.\\n","source":"@site/standards/scs-0102-v1-image-metadata.md","sourceDirName":".","slug":"/scs-0102-v1-image-metadata","permalink":"/standards/scs-0102-v1-image-metadata","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Image Metadata","type":"Standard","stabilized_at":"2022-10-31T00:00:00.000Z","status":"Stable","track":"IaaS","replaces":"Image-Metadata-Spec.md","description":"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating\\nsystem images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements,\\nimage handling protocols including updating and origin, and licensing/support details. These guidelines ensure\\nthat users can understand, access, and utilize OS images effectively, with clear information on features, updates,\\nand licensing provided through well-defined metadata properties.\\n"},"sidebar":"standards","previous":{"title":"scs-0102: SCS Image Metadata","permalink":"/standards/iaas/scs-0102"},"next":{"title":"W1","permalink":"/standards/scs-0102-w1-image-metadata-implementation-testing"}}');var s=n(74848),a=n(28453);const d={title:"SCS Image Metadata",type:"Standard",stabilized_at:new Date("2022-10-31T00:00:00.000Z"),status:"Stable",track:"IaaS",replaces:"Image-Metadata-Spec.md",description:"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating\nsystem images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements,\nimage handling protocols including updating and origin, and licensing/support details. These guidelines ensure\nthat users can understand, access, and utilize OS images effectively, with clear information on features, updates,\nand licensing provided through well-defined metadata properties.\n"},r=void 0,o={},c=[{value:"Motivation",id:"motivation",level:2},{value:"Overview",id:"overview",level:2},{value:"Naming",id:"naming",level:2},{value:"Technical requirements and features",id:"technical-requirements-and-features",level:2},{value:"Image handling",id:"image-handling",level:2},{value:"Image updating",id:"image-updating",level:3},{value:"Example",id:"example",level:4},{value:"Image Origin",id:"image-origin",level:3},{value:"Image build info",id:"image-build-info",level:3},{value:"Licensing / Maintenance subscription / Support",id:"licensing--maintenance-subscription--support",level:3},{value:"Conformance Tests",id:"conformance-tests",level:3}];function l(e){const i={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(i.p,{children:"Many clouds offer standard Operating System images for their users' convenience.\nTo make them really useful, they should contain metadata (properties) to allow\nusers to understand what they can expect using these images."}),"\n",(0,s.jsx)(i.p,{children:"The specification is targeting images that are managed by the service provider,\nprovided for public consumption. The spec or parts of it however might turn out\nto be useful whenever someone manages images for somebody else's consumption."}),"\n",(0,s.jsx)(i.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsx)(i.p,{children:"We categorize the image properties into a few buckets"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Technical requirements and features"}),"\n",(0,s.jsx)(i.li,{children:"Image handling aspects"}),"\n",(0,s.jsx)(i.li,{children:"Licensing/Maintenance/Support aspects"}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"naming",children:"Naming"}),"\n",(0,s.jsx)(i.p,{children:'We suggest plain OS images to be named "Distribution Version",\ne.g. "openSUSE Leap 15.3" or "Ubuntu 20.04" or "CentOS 8", "Windows Server 2012R2".\nWe do not normally recommend to add more detailed patch levels into the name.'}),"\n",(0,s.jsx)(i.p,{children:'Special variants that include specific non-standard features should be named\n"Distribution Version Feature1 Feature2".'}),"\n",(0,s.jsx)(i.p,{children:"There are several policies possible to provide updated images to include the latest\nbug- and security fixes. This is outlined in update policy description below."}),"\n",(0,s.jsx)(i.h2,{id:"technical-requirements-and-features",children:"Technical requirements and features"}),"\n",(0,s.jsx)(i.p,{children:"This is dependent on whether we deal with VM images or container images."}),"\n",(0,s.jsxs)(i.p,{children:["For VM images (OpenStack), we recommend to use the properties as described\nin the ",(0,s.jsx)(i.a,{href:"https://docs.openstack.org/glance/latest//admin/useful-image-properties",children:"OpenStack Image documentation"}),"."]}),"\n",(0,s.jsx)(i.p,{children:"The following properties are considered mandatory:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"architecture"}),", ",(0,s.jsx)(i.code,{children:"hypervisor_type"})]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"min_disk"})," (in GiB), ",(0,s.jsx)(i.code,{children:"min_ram"})," (in MiB)"]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"os_version"}),", ",(0,s.jsx)(i.code,{children:"os_distro"})]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"hw_rng_model"}),", ",(0,s.jsx)(i.code,{children:"hw_disk_bus"})," (",(0,s.jsx)(i.code,{children:"scsi"})," recommended, and then setting ",(0,s.jsx)(i.code,{children:"hw_scsi_model"})," is also recommended)"]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.strong,{children:"Note"}),": Disk sizes tend to be measured in GB = 10^9 and not GiB = 2^30 in the disk industry, but OpenStack uses GiB."]}),"\n",(0,s.jsx)(i.p,{children:"The following properties are recommended (if the features are supported):"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"os_secure_boot"}),", ",(0,s.jsx)(i.code,{children:"hw_firmware_type"})]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"hw_watchdog_action"}),", ",(0,s.jsx)(i.code,{children:"hw_mem_encryption"}),", ",(0,s.jsx)(i.code,{children:"hw_pmu"}),", ",(0,s.jsx)(i.code,{children:"hw_video_ram"}),", ",(0,s.jsx)(i.code,{children:"hw_vif_multiqueue_enabled"})]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["The ",(0,s.jsx)(i.code,{children:"trait:XXX=required"})," property can be used to indicate that certain virtual hardware\nfeatures ",(0,s.jsx)(i.code,{children:"XXX"})," are required."]}),"\n",(0,s.jsx)(i.h2,{id:"image-handling",children:"Image handling"}),"\n",(0,s.jsx)(i.h3,{id:"image-updating",children:"Image updating"}),"\n",(0,s.jsxs)(i.p,{children:["It is recommended that provider managed images are regularly updated.\nThis means that users referencing an image ",(0,s.jsx)(i.em,{children:"by name"})," will always get the latest image for the\noperating system indicated by that name (which includes a version number, but not the patch\nlevel)."]}),"\n",(0,s.jsxs)(i.p,{children:["Technically, the thus updated image is a new image and will thus carry a new UUID.\nIt is recommended that the old image gets renamed (e.g. build date or patch level attached)\nand hidden (",(0,s.jsx)(i.code,{children:"os_hidden=True"}),"), but remains accessible via its (unchanged) UUID for some\ntime."]}),"\n",(0,s.jsxs)(i.p,{children:["The update handling by the provider is described via the properties ",(0,s.jsx)(i.code,{children:"replace_frequency"}),",\n",(0,s.jsx)(i.code,{children:"uuid_validity"}),", ",(0,s.jsx)(i.code,{children:"provided_until"}),", and ",(0,s.jsx)(i.code,{children:"hotfix_hours"}),"."]}),"\n",(0,s.jsxs)(i.p,{children:["The ",(0,s.jsx)(i.code,{children:"replace_frequency"}),", ",(0,s.jsx)(i.code,{children:"provided_until"}),", and ",(0,s.jsx)(i.code,{children:"hotfix_hours"})," fields reference to the image\nas referenced by its name."]}),"\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:(0,s.jsx)(i.code,{children:"replace_frequency"})}),(0,s.jsx)(i.th,{children:"meaning"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"yearly"})}),(0,s.jsxs)(i.td,{children:["the image will get replaced ",(0,s.jsx)(i.em,{children:"at least"})," once per year"]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"quarterly"})}),(0,s.jsxs)(i.td,{children:["the image will get replaced ",(0,s.jsx)(i.em,{children:"at least"})," once per quarter"]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"monthly"})}),(0,s.jsxs)(i.td,{children:["the image will get replaced ",(0,s.jsx)(i.em,{children:"at least"})," once per month"]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"weekly"})}),(0,s.jsxs)(i.td,{children:["the image will get replaced ",(0,s.jsx)(i.em,{children:"at least"})," once per week"]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"daily"})}),(0,s.jsxs)(i.td,{children:["the image will get replaced ",(0,s.jsx)(i.em,{children:"at least"})," once per day"]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"critical_bug"})}),(0,s.jsx)(i.td,{children:"the image will get replaced for critical issues only"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"never"})}),(0,s.jsxs)(i.td,{children:["the image referenced by name will never change (until the date ",(0,s.jsx)(i.code,{children:"provided_until"}),")"]})]})]})]}),"\n",(0,s.jsxs)(i.p,{children:["Note the ",(0,s.jsx)(i.em,{children:"at least"})," wording: Providers can replace images more often.\nThe frequency is starting from the first release; so an image published on 2021-04-14 with an\nupdate frequency of ",(0,s.jsx)(i.code,{children:"monthly"}),", should be replaced no later than 2021-05-14. Due to weekends\netc., up to 3 days later is not considered a violation of this policy. So a valid sequence\nfrom an image with ",(0,s.jsx)(i.code,{children:"monthly"})," update frequency might be 2021-04-14, 2021-05-14, 2021-06-15,\n2021-07-14, 2021-07-27 (hotfix), 2021-08-13 ..."]}),"\n",(0,s.jsx)(i.p,{children:"Promises to update the registered public images typically depend on upstream image providers\n(Linux distributors, OS vendors) keeping their promises to build and provide updated images.\nFailures from upstream are not a reason to claim the cloud provider to be in violation of his\npromises. However, if the provider observes massive upstream failures (which can e.g. cause\nincreased security risks), we advise the provider to inform the users."}),"\n",(0,s.jsx)(i.p,{children:"We recommend updating images at least monthly."}),"\n",(0,s.jsxs)(i.p,{children:["The ",(0,s.jsx)(i.code,{children:"hotfix_hours"})," field indicates how providers deal with critical security issues\nthat affect the images; it is an optional field that contains a numerical value, indicating\nhow quickly (in hours) a new image is provided ",(0,s.jsx)(i.em,{children:"after the latter of the points in time that\nthe issue becomes public and a tested fix is available as maintenance update from the upstream\ndistribution"}),". A value of 0 indicates a best-effort approach without firm SLAs; the field not\nbeing present indicates no commitment. A value of 48 would indicate that the provider\ncommits to a new image within 48hrs. A critical issue is defined as a security vulnerability\nwith a CVSS score of 9.0 or higher that affects software that is included in the image."]}),"\n",(0,s.jsxs)(i.p,{children:["The ",(0,s.jsx)(i.code,{children:"provided_until"})," field is supposed to contain a date in ",(0,s.jsx)(i.code,{children:"YYYY-MM-DD"})," format that\nindicates until when an image under this name will be provided and (according to the\n",(0,s.jsx)(i.code,{children:"replace_frequency"}),") updated at least. (Providers are free to provide updates for\nlonger or leave the non-updated image visible for longer.)\nIf this field is set to ",(0,s.jsx)(i.code,{children:"none"}),", no promises are made, if it is set to ",(0,s.jsx)(i.code,{children:"notice"}),", updates\nwill be provided until a deprecation notice is published. (The values are the same as\nfor below ",(0,s.jsx)(i.code,{children:"uuid_validity"}),", except that ",(0,s.jsx)(i.code,{children:"forever"})," and ",(0,s.jsx)(i.code,{children:"last-N"})," don't make any sense.)"]}),"\n",(0,s.jsxs)(i.p,{children:["The ",(0,s.jsx)(i.code,{children:"uuid_validity"})," field indicates how long the public image will be referencable\nby its UUID."]}),"\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:(0,s.jsx)(i.code,{children:"uuid_validity"})}),(0,s.jsx)(i.th,{children:"meaning"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"none"})}),(0,s.jsx)(i.td,{children:"UUID will only be valid as long as the content does not change"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"last-N"})}),(0,s.jsx)(i.td,{children:"The last N images for newer replacement will remain accessible via UUID"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"YYYY-MM-DD"})}),(0,s.jsx)(i.td,{children:"UUID will be valid until at least the date YYYY-MM-DD"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"notice"})}),(0,s.jsx)(i.td,{children:"UUID will remain valid until a deprecation notice will be published"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"forever"})}),(0,s.jsx)(i.td,{children:"UUID will remain valid for as long as the cloud operates"})]})]})]}),"\n",(0,s.jsxs)(i.p,{children:["Note that the old images must be hidden from the image catalogue or renamed (or both)\nto avoid failing referencing by name. Note that ",(0,s.jsx)(i.code,{children:"last-N"})," may be limited by the ",(0,s.jsx)(i.code,{children:"provided_until"}),"\ndate. We recommend providers that keep old images according to the advertized ",(0,s.jsx)(i.code,{children:"uuid_validity"}),"\nto hide older images (setting the ",(0,s.jsx)(i.code,{children:"os_hidden"})," property to ",(0,s.jsx)(i.code,{children:"True"}),'). If the outdated images must\nremain visible, the recommendation is to rename the images by attaching a datestamp in the\nformat " ',(0,s.jsx)(i.code,{children:"YYYYMMDD"}),'" to the name where the date must reflect the ',(0,s.jsx)(i.code,{children:"build_date"})," of the image."]}),"\n",(0,s.jsxs)(i.p,{children:["The three properties ",(0,s.jsx)(i.code,{children:"uuid_validity"}),", ",(0,s.jsx)(i.code,{children:"provided_until"})," and ",(0,s.jsx)(i.code,{children:"replace_frequency"})," are mandatory;\nthe field ",(0,s.jsx)(i.code,{children:"hotfix_hours"})," is optional."]}),"\n",(0,s.jsx)(i.p,{children:"All dates are in UTC."}),"\n",(0,s.jsx)(i.h4,{id:"example",children:"Example"}),"\n",(0,s.jsxs)(i.p,{children:["Providing an image with name ",(0,s.jsx)(i.code,{children:"OPSYS MAJ.MIN"})," with\n",(0,s.jsx)(i.code,{children:"replace_frequency=monthly"}),", ",(0,s.jsx)(i.code,{children:"provided_until=2022-09-30"}),", ",(0,s.jsx)(i.code,{children:"uuid_validity=2022-12-31"}),",\n",(0,s.jsx)(i.code,{children:"hotfix_hours=0"}),"\nmeans that we will have a new image with this name at least once per month (starting from\nthe initial release) until the end of September 2022. Old images will be hidden and/or\nrenamed, but remain accessible via their UUID until at least the end of 2022 (in Universal Time).\nThe provider makes an effort to replace images upon critical security issues out of order."]}),"\n",(0,s.jsx)(i.h3,{id:"image-origin",children:"Image Origin"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:["Mandatory: ",(0,s.jsx)(i.code,{children:"image_source"}),' needs to be a URL to point to a place from which the image can be downloaded.\n(Note: This may be set to the string "private" to indicate that the image can not be freely\ndownloaded.)']}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:["Mandatory: ",(0,s.jsx)(i.code,{children:"image_description"})," needs to be a URL (or text) with release notes and other human-readable\ndata about the image."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:["Recommended ",(0,s.jsx)(i.em,{children:"tag"}),": ",(0,s.jsx)(i.code,{children:"managed_by_VENDOR"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["Note that for most images that come straight from an upstream source, ",(0,s.jsx)(i.code,{children:"image_description"})," should point\nto an upstream web page where these images are described. If download links are available as well\non that page, ",(0,s.jsx)(i.code,{children:"image_source"})," can point to the same page, otherwise a more direct link to the image\nshould be used, e.g. directly linking the ",(0,s.jsx)(i.code,{children:".qcow2"})," or ",(0,s.jsx)(i.code,{children:".img"})," file.\nIf providers have their own image building machinery or do some post-processing on top of\nupstream images, they should point to the place where they document and offer these images."]}),"\n",(0,s.jsx)(i.h3,{id:"image-build-info",children:"Image build info"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:["Mandatory: ",(0,s.jsx)(i.code,{children:"image_build_date"})," needs to be ",(0,s.jsx)(i.code,{children:"YYYY-MM-DD"})," or ",(0,s.jsx)(i.code,{children:"YYYY-MM-DD hh:mm[:ss]"})," (time in UTC,\n24hrs clock).\nAll publicly released and generally recommended patches before this date must be included in the\nimage build. If the cutoff date is earlier, this cutoff date needs to be set instead, even\nif the actual build happens significantly after the cutoff date. If not all patches can be\nincluded for a good reason, then the ",(0,s.jsx)(i.code,{children:"patchlevel"})," field (see below) must be used to describe\nthe patch status."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:["Mandatory: ",(0,s.jsx)(i.code,{children:"image_original_user"})," is the default login user for the operating system which can connect\nto the image via the injected SSH key or provided password. (This can be set to ",(0,s.jsx)(i.code,{children:"none"})," if no default\nusername exists for the operating system.)"]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:["Optional: ",(0,s.jsx)(i.code,{children:"patchlevel"})," can be set to an operating specific patch level that describes the\npatch status \u2014 typically we would expect the ",(0,s.jsx)(i.code,{children:"image_build_date"})," to be sufficient."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:["Recommended: ",(0,s.jsx)(i.code,{children:"os_hash_algo"})," and ",(0,s.jsx)(i.code,{children:"os_hash_value"}),": The sha256 or sha512 hash\nfor the image file. (This references the image file in the format it is stored in, we\nrecommend raw over qcow2 for systems that use ceph.) Note that these values are\ntypically generated automatically upon image registration."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:["Recommended ",(0,s.jsx)(i.em,{children:"tag"}),": ",(0,s.jsx)(i.code,{children:"os:OPERATINGSYSTEM"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"licensing--maintenance-subscription--support",children:"Licensing / Maintenance subscription / Support"}),"\n",(0,s.jsxs)(i.p,{children:["Some images require a license; in many cases the cloud providers include the license cost\nby a per-use (e.g. hourly) fee. However, it is also possible sometimes that customers\nuse their own license agreements with the OS vendor with a bring-your-own-license (BYOL)\nprogram. These properties may be attached to the image. Note that free Linux images\nmight not use any of these properties, except maybe ",(0,s.jsx)(i.code,{children:"maintained_until"}),". Note that\nWindows images would typically require ",(0,s.jsx)(i.code,{children:"license_included"}),", ",(0,s.jsx)(i.code,{children:"subscription_included"}),".\nA boolean property that is not present is considered to be ",(0,s.jsx)(i.code,{children:"false"}),"."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["Optional: ",(0,s.jsx)(i.code,{children:"license_included"})," (boolean) indicates whether the flavor fee\nincludes the licenses required to use this image. This field is mandatory for\nimages that contain software that requires commercial licenses."]}),"\n",(0,s.jsxs)(i.li,{children:["Optional: ",(0,s.jsx)(i.code,{children:"license_required"})," (boolean) indicates whether a customer must bring\nits own license to be license compliant. This can not be true at the same time as the\nprevious setting. This field is mandatory IF customers need to bring their own\nlicense to use the image."]}),"\n",(0,s.jsxs)(i.li,{children:["Optional: ",(0,s.jsx)(i.code,{children:"subscription_included"})," (boolean) indicates that the image contains already\na maintenance subscription which typically gives access to bug fixes, security\nfixes and (minor) function updates. If a subscription is included, the CSP should\nhave prepared the image to also receive the provided maintenance updates from the\nvendor (optionally via a mirror)."]}),"\n",(0,s.jsxs)(i.li,{children:["Optional: ",(0,s.jsx)(i.code,{children:"subscription_required"})," (boolean) indicates that the customer requires\na maintenance subscription from the OS vendor in order to receive fixes\n(which is often also a prerequisite to be eligible for support)."]}),"\n",(0,s.jsxs)(i.li,{children:["Optional: ",(0,s.jsx)(i.code,{children:"maintained_until: YYYY-MM-DD"})," promises maintenance from the OS vendor\nuntil at least this date (in UTC)."]}),"\n",(0,s.jsxs)(i.li,{children:["Optional: ",(0,s.jsx)(i.code,{children:"l1_support_contact"})," contains a URI that provides customer support\ncontact for issues with this image. Note that this field must only be set if the\nservice provider does provide support for this image included in the image/flavor\npricing (but it might be provided by a contracted 3rd party, e.g. the OS vendor)."]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsxs)(i.p,{children:["The script ",(0,s.jsx)(i.code,{children:"image-md-check.py"})," retrieves the\nimage list from a configured cloud and checks each image for the\ncompleteness and consistency of mandatory properties."]})]})}function h(e={}){const{wrapper:i}={...(0,a.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>d,x:()=>r});var t=n(96540);const s={},a=t.createContext(s);function d(e){const i=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),t.createElement(a.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad59ba68.acc0ad04.js b/assets/js/ad59ba68.acc0ad04.js new file mode 100644 index 0000000000..d339e24d4e --- /dev/null +++ b/assets/js/ad59ba68.acc0ad04.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[47191],{50896:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"scs-0117-v1-volume-backup-service","title":"Volume Backup Functionality","description":"Introduction","source":"@site/standards/scs-0117-v1-volume-backup-service.md","sourceDirName":".","slug":"/scs-0117-v1-volume-backup-service","permalink":"/standards/scs-0117-v1-volume-backup-service","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Volume Backup Functionality","type":"Standard","status":"Stable","stabilized_at":"2024-11-13T00:00:00.000Z","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0117: Volume Backup Functionality","permalink":"/standards/iaas/scs-0117"},"next":{"title":"scs-0118: SCS Taxonomy of Failsafe Levels","permalink":"/standards/iaas/scs-0118"}}');var s=t(74848),r=t(28453);const i={title:"Volume Backup Functionality",type:"Standard",status:"Stable",stabilized_at:new Date("2024-11-13T00:00:00.000Z"),track:"IaaS"},o=void 0,c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Only recommend volume backup feature, use images as alternative",id:"only-recommend-volume-backup-feature-use-images-as-alternative",level:4},{value:"Focus on feature availability, make feature mandatory",id:"focus-on-feature-availability-make-feature-mandatory",level:4},{value:"Focus on backup reliability, make separate backend mandatory",id:"focus-on-backup-reliability-make-separate-backend-mandatory",level:4},{value:"Standard",id:"standard",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function d(e){const a={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(a.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(a.p,{children:"OpenStack offers a variety of resources where users are able to transfer and store data in the infrastructure.\nA prime example of these resources are volumes which are attached to virtual machines as virtual block storage devices.\nAs such they carry potentially large amounts of user data which is constantly changing at runtime.\nIt is important for users to have the ability to create backups of this data in a reliable and effifcient manner."}),"\n",(0,s.jsx)(a.h2,{id:"terminology",children:"Terminology"}),"\n",(0,s.jsxs)(a.table,{children:[(0,s.jsx)(a.thead,{children:(0,s.jsxs)(a.tr,{children:[(0,s.jsx)(a.th,{children:"Term"}),(0,s.jsx)(a.th,{children:"Meaning"})]})}),(0,s.jsxs)(a.tbody,{children:[(0,s.jsxs)(a.tr,{children:[(0,s.jsx)(a.td,{children:"CSP"}),(0,s.jsx)(a.td,{children:"Cloud Service Provider, provider managing the OpenStack infrastructure"})]}),(0,s.jsxs)(a.tr,{children:[(0,s.jsx)(a.td,{children:"IaaS"}),(0,s.jsx)(a.td,{children:"Abbreviation for Infrastructure as a Service"})]}),(0,s.jsxs)(a.tr,{children:[(0,s.jsx)(a.td,{children:"Image"}),(0,s.jsx)(a.td,{children:"IaaS resource representing a snapshot of a block storage disk, can be used to create Volumes"})]}),(0,s.jsxs)(a.tr,{children:[(0,s.jsx)(a.td,{children:"Volume"}),(0,s.jsx)(a.td,{children:"IaaS resource representing a virtual block storage device that can be attached as a disk to virtual machines"})]})]})]}),"\n",(0,s.jsx)(a.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsxs)(a.p,{children:["The ",(0,s.jsx)(a.a,{href:"https://docs.openstack.org/cinder/latest/admin/volume-backups.html",children:"volume backup functionality of the Block Storage API"})," is a feature that is not available in all clouds per default, e.g., in OpenStack.\nThe feature requires a backend to be prepared and configured correctly before it can be used.\nIn the Block Storage service, the backup storage backend is usually configured separately from the storage backend of the general volume service and may not be mandatory.\nThus, an arbitrary cloud may or may not offer the backup feature in the Block Storage API."]}),"\n",(0,s.jsx)(a.p,{children:"This standard aims to make this functionality the default in SCS clouds so that customers can expect the feature to be usable."}),"\n",(0,s.jsx)(a.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsx)(a.p,{children:"The standard should make sure that the feature is available and usable but should not limit the exact implementation (e.g. choice of backend driver) any further than necessary."}),"\n",(0,s.jsx)(a.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,s.jsx)(a.h4,{id:"only-recommend-volume-backup-feature-use-images-as-alternative",children:"Only recommend volume backup feature, use images as alternative"}),"\n",(0,s.jsx)(a.p,{children:"As an alternative to the volume backup feature of the Block Storage API, images can also be created based on volumes and act as a backup under certain circumstances.\nAs an option, this standard could keep the actual integration of the volume backup feature optional and guide users how to use images as backup targets instead in case the feature is unavailable."}),"\n",(0,s.jsx)(a.p,{children:"However, it is not guaranteed that the image backend storage is separate from the volume storage.\nFor instance, both could be using the same Ceph cluster.\nIn such case, the images would not count as genuine backups."}),"\n",(0,s.jsx)(a.p,{children:"Although users are able to download images and transfer them to a different storage location, this approach might also prove unfeasible depending on the image size and the existence (or lack) of appropriate target storage on the user side."}),"\n",(0,s.jsx)(a.p,{children:"Furthermore, incremental backups are not possible when creating images from volumes either.\nThis results in time-consuming backup operations of fully copying a volume everytime a backup is created."}),"\n",(0,s.jsx)(a.h4,{id:"focus-on-feature-availability-make-feature-mandatory",children:"Focus on feature availability, make feature mandatory"}),"\n",(0,s.jsx)(a.p,{children:"This option is pretty straightforward.\nIt would make the volume backup feature mandatory for SCS clouds.\nThis way users can expect the feature to be available and usable."}),"\n",(0,s.jsx)(a.p,{children:"With this, users can leverage functionalities like incremental backups and benefit from optimized performance of the backup process due to the tight integration with the volume service."}),"\n",(0,s.jsx)(a.p,{children:"However, it does not seem feasible to also mandate having a separate storage backend for volume backups at the same time due to potential infrastructure limitations at CSP-side making it hard or even impossible to offer.\nAs such, the actual benefit of backups in terms of reliability and security aspects would be questionable if a separate storage backend is not mandated and therefore not guaranteed."}),"\n",(0,s.jsx)(a.p,{children:"This approach would focus on feature availability rather than backup reliability."}),"\n",(0,s.jsx)(a.h4,{id:"focus-on-backup-reliability-make-separate-backend-mandatory",children:"Focus on backup reliability, make separate backend mandatory"}),"\n",(0,s.jsx)(a.p,{children:"As an alternative, the volume backup feature availability could be made optional but in case a CSP chooses to offer it, the standard would mandate a separate storage backend to be used for volume backups.\nThis way, failures of the volume storage backend would not directly impact the availability and safety of volume backups, making them actually live up to their name."}),"\n",(0,s.jsx)(a.p,{children:"In contrast to the above, this approach would focus on backup reliability rather than feature availability."}),"\n",(0,s.jsx)(a.h2,{id:"standard",children:"Standard"}),"\n",(0,s.jsx)(a.p,{children:"This standard decides to go with the second option and makes the volume backup feature mandatory in the following way:"}),"\n",(0,s.jsxs)(a.p,{children:["In an SCS cloud, the volume backup functionality MUST be configured properly and its API as defined per ",(0,s.jsx)(a.code,{children:"/v3/{project_id}/backups"})," MUST be offered to customers.\nIf using Cinder, a suitable ",(0,s.jsx)(a.a,{href:"https://docs.openstack.org/cinder/latest/configuration/block-storage/backup-drivers.html",children:"backup driver"})," MUST be set up."]}),"\n",(0,s.jsx)(a.p,{children:"The volume backup target storage SHOULD be a separate storage system from the one used for volumes themselves."}),"\n",(0,s.jsx)(a.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsxs)(a.ul,{children:["\n",(0,s.jsx)(a.li,{children:(0,s.jsx)(a.a,{href:"https://docs.openstack.org/api-ref/block-storage/v3/index.html#backups-backups",children:"OpenStack Block Storage v3 Backup API reference"})}),"\n",(0,s.jsx)(a.li,{children:(0,s.jsx)(a.a,{href:"https://docs.openstack.org/cinder/latest/configuration/block-storage/backup-drivers.html",children:"OpenStack Volume Backup Drivers"})}),"\n"]}),"\n",(0,s.jsx)(a.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsxs)(a.p,{children:["Conformance tests include using the ",(0,s.jsx)(a.code,{children:"/v3/{project_id}/backups"})," Block Storage API endpoint to create a volume and a backup of it as a non-admin user and subsequently restore the backup on a new volume while verifying the success of each operation.\nThese tests verify the mandatory part of the standard: providing the Volume Backup API."]}),"\n",(0,s.jsxs)(a.p,{children:["There is a test suite in ",(0,s.jsx)(a.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/volume-backup/volume-backup-tester.py",children:(0,s.jsx)(a.code,{children:"volume-backup-tester.py"})}),".\nThe test suite connects to the OpenStack API and executes basic operations using the volume backup API to verify that the functionality requested by the standard is available.\nPlease consult the associated ",(0,s.jsx)(a.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/volume-backup/README.md",children:"README.md"})," for detailed setup and testing instructions."]}),"\n",(0,s.jsx)(a.p,{children:"Note that these tests don't verify the optional part of the standard: providing a separate storage backend for Cinder volume backups.\nThis cannot be checked from outside of the infrastructure as it is an architectural property of the infrastructure itself and transparent to customers."})]})}function u(e={}){const{wrapper:a}={...(0,r.R)(),...e.components};return a?(0,s.jsx)(a,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,a,t)=>{t.d(a,{R:()=>i,x:()=>o});var n=t(96540);const s={},r=n.createContext(s);function i(e){const a=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function o(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),n.createElement(r.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ae009198.054ba784.js b/assets/js/ae009198.054ba784.js new file mode 100644 index 0000000000..5c8864b4d5 --- /dev/null +++ b/assets/js/ae009198.054ba784.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[50676],{39104:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>p,frontMatter:()=>l,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"operating-scs/components/status-page-deployment/docs/k3s","title":"k3s - A simple deployment on a single host","description":"From a new machine to a working status page in ~15 minutes.","source":"@site/docs/04-operating-scs/components/status-page-deployment/docs/k3s.md","sourceDirName":"04-operating-scs/components/status-page-deployment/docs","slug":"/operating-scs/components/status-page-deployment/docs/k3s","permalink":"/docs/operating-scs/components/status-page-deployment/docs/k3s","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-deployment/docs/k3s.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"kind - Local development environment","permalink":"/docs/operating-scs/components/status-page-deployment/docs/kind"},"next":{"title":"SCS Public","permalink":"/docs/operating-scs/components/status-page-deployment/docs/scs-public"}}');var o=s(74848),i=s(28453);const l={},r="k3s - A simple deployment on a single host",a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"k3s setup",id:"k3s-setup",level:2},{value:"Firewall settings",id:"firewall-settings",level:3},{value:"<code>ufw</code> example",id:"ufw-example",level:4},{value:"Install",id:"install",level:3},{value:"Deployment",id:"deployment",level:2},{value:"Kube config",id:"kube-config",level:3},{value:"Deploy cert manager",id:"deploy-cert-manager",level:3},{value:"Configure and deploy status page",id:"configure-and-deploy-status-page",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"k3s---a-simple-deployment-on-a-single-host",children:"k3s - A simple deployment on a single host"})}),"\n",(0,o.jsx)(n.p,{children:"From a new machine to a working status page in ~15 minutes."}),"\n",(0,o.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsx)(n.p,{children:"A VM or bare metal host with a public IP. Optional: A domain pointing to the public IP."}),"\n",(0,o.jsx)(n.h2,{id:"k3s-setup",children:"k3s setup"}),"\n",(0,o.jsx)(n.p,{children:"Setting up k3s to run k8s workloads on the machine."}),"\n",(0,o.jsx)(n.h3,{id:"firewall-settings",children:"Firewall settings"}),"\n",(0,o.jsx)(n.p,{children:"Allow communication to and from the cluster."}),"\n",(0,o.jsx)(n.p,{children:"Incoming:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"6443 Kubernetes API server"}),"\n",(0,o.jsx)(n.li,{children:"80 HTTP ingress"}),"\n",(0,o.jsx)(n.li,{children:"443 HTTPS ingress"}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"Internal:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"10.42.0.0/16 - Pod communication"}),"\n",(0,o.jsx)(n.li,{children:"10.43.0.0/16 - Service communication"}),"\n"]}),"\n",(0,o.jsxs)(n.h4,{id:"ufw-example",children:[(0,o.jsx)(n.code,{children:"ufw"})," example"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"ufw allow 6443/tcp # api server\nufw allow from 10.42.0.0/16 to any # pods\nufw allow from 10.43.0.0/16 to any # services\n\nufw allow 80/tcp # http\nufw allow 443/tcp # https\n"})}),"\n",(0,o.jsx)(n.h3,{id:"install",children:"Install"}),"\n",(0,o.jsxs)(n.p,{children:["Configure and install k3s directly via install script. See the ",(0,o.jsx)(n.a,{href:"https://docs.k3s.io/cli/server",children:"k3s server config"}),"."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl -sfL https://get.k3s.io | sh -s - server \\\n--tls-san <your-ip> \\\n--tls-san <your-domain>\n"})}),"\n",(0,o.jsx)(n.p,{children:"Setting the SANs enables the k3s server to be available via your domain and server ip."}),"\n",(0,o.jsx)(n.h2,{id:"deployment",children:"Deployment"}),"\n",(0,o.jsx)(n.p,{children:"Deploy services to the cluster, to get the status page running."}),"\n",(0,o.jsxs)(n.p,{children:["If you don't have access to a domain name, consider using ",(0,o.jsx)(n.a,{href:"https://nip.io/",children:"nip.io"})," to use as (sub)domains for Dex, Oathkeeper (API server) and the web frontend."]}),"\n",(0,o.jsx)(n.h3,{id:"kube-config",children:"Kube config"}),"\n",(0,o.jsxs)(n.p,{children:["The newly generated kube config for the cluster is located at ",(0,o.jsx)(n.code,{children:"/etc/rancher/k3s/k3s.yaml"}),". Copy to your machine to configure access to the cluster."]}),"\n",(0,o.jsxs)(n.p,{children:["Change the URI at ",(0,o.jsx)(n.code,{children:".clusters[0].cluster.server"})," to the URI you added to the SAN config."]}),"\n",(0,o.jsx)(n.h3,{id:"deploy-cert-manager",children:"Deploy cert manager"}),"\n",(0,o.jsxs)(n.p,{children:["Deploy ",(0,o.jsx)(n.a,{href:"https://cert-manager.io/docs/installation/kubectl/",children:"cert-manager"})," on the cluster to automatically receive LetsEncrypt certificates."]}),"\n",(0,o.jsxs)(n.p,{children:["See ",(0,o.jsx)(n.code,{children:"issuer.yaml"})," for settings."]}),"\n",(0,o.jsx)(n.h3,{id:"configure-and-deploy-status-page",children:"Configure and deploy status page"}),"\n",(0,o.jsxs)(n.p,{children:["For in depth configuration see ",(0,o.jsx)(n.a,{href:"/docs/operating-scs/components/status-page-deployment/docs/configuration",children:(0,o.jsx)(n.code,{children:"configuration.md"})}),"."]}),"\n",(0,o.jsx)(n.p,{children:"Assemble and deploy the k3s deployment."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"kubectl kustomize kubernetes/environments/k3s/ > k3s_out.yaml\nkubectl apply -f k3s_out.yaml\n# or\nkubectl apply -k kubernetes/environments/k3s/\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The deployment creates a namespace called ",(0,o.jsx)(n.code,{children:"status-page"})," where all services, ingress, etc. gets deployed."]})]})}function p(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>r});var t=s(96540);const o={},i=t.createContext(o);function l(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:l(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aed2f698.6961a962.js b/assets/js/aed2f698.6961a962.js new file mode 100644 index 0000000000..83ddd8b71b --- /dev/null +++ b/assets/js/aed2f698.6961a962.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[85612],{27448:(e,r,s)=>{s.r(r),s.d(r,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>t,toc:()=>u});const t=JSON.parse('{"id":"iaas/guides/user-guide/openstack/security-groups","title":"How to configure and use security groups","description":"Security groups in OpenStack are part of the network security mechanisms provided for the users.","source":"@site/docs/02-iaas/guides/user-guide/openstack/security-groups.md","sourceDirName":"02-iaas/guides/user-guide/openstack","slug":"/iaas/guides/user-guide/openstack/security-groups","permalink":"/docs/iaas/guides/user-guide/openstack/security-groups","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/openstack/security-groups.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Security groups"},"sidebar":"docs","previous":{"title":"Client","permalink":"/docs/iaas/guides/user-guide/openstack/openstackclient"},"next":{"title":"User Data Backups","permalink":"/docs/iaas/guides/user-guide/openstack/user-data-backups"}}');var i=s(74848),n=s(28453);const o={sidebar_label:"Security groups"},a="How to configure and use security groups",c={},u=[{value:"Identify the requirements of your setup",id:"identify-the-requirements-of-your-setup",level:2},{value:"Further security considerations",id:"further-security-considerations",level:3},{value:"How to create security groups",id:"how-to-create-security-groups",level:2},{value:"Default security group",id:"default-security-group",level:3},{value:"Recommended security groups",id:"recommended-security-groups",level:3},{value:"How to use security groups",id:"how-to-use-security-groups",level:2}];function l(e){const r={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,n.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(r.header,{children:(0,i.jsx)(r.h1,{id:"how-to-configure-and-use-security-groups",children:"How to configure and use security groups"})}),"\n",(0,i.jsx)(r.p,{children:"Security groups in OpenStack are part of the network security mechanisms provided for the users.\nThey resemble sets of simple firewall rules allowing specific network traffic at a Port of a VM that connects it to a network.\nThe rules allow specific network port numbers and protocols while also differentiating between ingress and egress directions.\nUsually security groups are assigned to the Port(s) when a virtual machine is created, but assignments can also be changed at runtime later on.\nMultiple security groups can be assigned to a VM or Port simultaneously and in such case they will be combined as the union of all their rules."}),"\n",(0,i.jsx)(r.admonition,{type:"caution",children:(0,i.jsxs)(r.p,{children:["Security groups are mutable resources.\nTheir rules can be adjusted at any time after creation.\n",(0,i.jsx)(r.strong,{children:"Changing the rules of a security group will immediately apply the changes to all Ports or VMs it is assigned to."}),"\nIt is advisable to always review resources which use a security group before making changes to it."]})}),"\n",(0,i.jsx)(r.h2,{id:"identify-the-requirements-of-your-setup",children:"Identify the requirements of your setup"}),"\n",(0,i.jsx)(r.p,{children:"Every virtual machine that is created may need different firewall rules.\nThese requirements can also change over time.\nAdding or removing security groups will allow users to adapt the firewall rules specifically to their virtual machines."}),"\n",(0,i.jsx)(r.p,{children:"To harden the firewall settings for your virtual machine you may follow these steps:"}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsx)(r.li,{children:"Before creating a virtual machine its purpose is usually already known. Use this information to identify all incoming and outgoing traffic rules that will be needed based on the communication patterns of the services it is meant to deploy. This includes communication protocols, port numbers, communication directions and optionally target/source address ranges."}),"\n",(0,i.jsx)(r.li,{children:"Look through already existing security groups and their rules. If a security group allows more traffic than needed it SHOULD NOT be used. If a security group contains only a subset of the required rules it MAY be used in combination with other security groups that contain rules which fulfill the remaining required traffic rules from point 1."}),"\n",(0,i.jsx)(r.li,{children:"If you were not successful in finding an appropriate combination of existing security groups or you need additional specific rules to cover all requirements, you MAY create one or more new Security Groups in which you can add the required rules."}),"\n",(0,i.jsx)(r.li,{children:"After ensuring the existence of one or more security groups that fulfill your requirements, you can create the VM with those security groups already specified in the creation command."}),"\n"]}),"\n",(0,i.jsx)(r.h3,{id:"further-security-considerations",children:"Further security considerations"}),"\n",(0,i.jsx)(r.p,{children:"When implementing network security requirements, firewall rules alone are not always sufficient and might need to be augmented with additional configuration or time-based constraints. Notable examples are:"}),"\n",(0,i.jsxs)(r.p,{children:[(0,i.jsx)(r.strong,{children:"SSH"}),"\nSSH is needed on many virtual machines to operate their guest operating system.\nIn a security group the port 22 can be opened for the TCP protocol to allow incoming SSH connections.\nBut that only should be done while also restricting the SSH configuration to public key authentication only (the recommended way) or having a strong username and password policy already applied to the operating system of the virtual machine.\nOtherwise default usernames and passwords which are often preconfigured in system images may be exploited through the exposed SSH port which enables attackers to compromise the virtual machine."]}),"\n",(0,i.jsxs)(r.p,{children:[(0,i.jsx)(r.strong,{children:"ICMP"}),"\nIt might be useful to be able to ping a virtual machine or use other ICMP requests.\nBut for some virtual machine configurations this is either not necessary at all or only temporarily needed.\nOne benefit of security groups among other things is the ability to be easily added to and removed from existing virtual machines.\nSo a dedicated security group allowing ICMP could be added temporarily to a virtual machine for debugging purposes and removed from it afterwards."]}),"\n",(0,i.jsx)(r.h2,{id:"how-to-create-security-groups",children:"How to create security groups"}),"\n",(0,i.jsx)(r.p,{children:"Security groups are managed within a project.\nSo every project will have a different set of security groups.\nThey can be added dynamically to each virtual machine, during their creation or afterwards.\nAdditionally, they may also be removed from VMs at any point."}),"\n",(0,i.jsx)(r.p,{children:"Every project has its own default security group, which rules can be edited.\nAdditionally other security groups can be added until the project's quota is exhausted.\nTo add a security group, use the following command:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group create $SECURITY_GROUP\n"})}),"\n",(0,i.jsx)(r.p,{children:"Within every security group rules can be added up unto a defined maximum of rules, that usually is about 100.\nRules can be added to security groups with the following command:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group rule create [...] $SECURITY_GROUP\n"})}),"\n",(0,i.jsx)(r.p,{children:"To delete rules from a security group, the rule id has to be used.\nIt is listed in the details of the rules section of the security group."}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group rule delete $RULE_ID\n"})}),"\n",(0,i.jsx)(r.h3,{id:"default-security-group",children:"Default security group"}),"\n",(0,i.jsx)(r.p,{children:"Unless specified otherwise, the default security group is assigned to all VMs or Ports at creation.\nTo use any other than the default security group at creation it is necessary to specify the desired security group(s) during the creation process."}),"\n",(0,i.jsx)(r.p,{children:"To review which rules are defined in a security group, the following command can be used:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group show default\n"})}),"\n",(0,i.jsx)(r.h3,{id:"recommended-security-groups",children:"Recommended security groups"}),"\n",(0,i.jsx)(r.p,{children:"While projects can use very different aspects in security group rules and thus the security groups will always differ between projects, there are some security groups that are widely used.\nThrough the nature of security groups being seen as a set of rules that can be combined, having some basic security groups that allow basic protocols is a commonly used setup.\nThis section will demonstrate how to create some security groups for commonly used protocols and ports."}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsx)(r.li,{children:"A security groups, that allows incoming SSH traffic:"}),"\n"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group create ssh\nopenstack security group rule create --ingress --protocol tcp --dst-port 22 ssh\n"})}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsx)(r.li,{children:"A security group, that allows incoming HTTP requests:"}),"\n"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group create http\nopenstack security group rule create --ingress --protocol tcp --dst-port 80 http\n"})}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsx)(r.li,{children:"A security group, that allows incoming HTTPS requests:"}),"\n"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group create https\nopenstack security group rule create --ingress --protocol tcp --dst-port 443 https\n"})}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsx)(r.li,{children:"A security group, that allows incoming ICMP requests:"}),"\n"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack security group create icmp\nopenstack security group rule create --protocol icmp icmp\n"})}),"\n",(0,i.jsx)(r.h2,{id:"how-to-use-security-groups",children:"How to use security groups"}),"\n",(0,i.jsx)(r.admonition,{type:"info",children:(0,i.jsx)(r.p,{children:"Security groups can be assigned to multiple resources simultaneously (such as VMs or Ports).\nThis means that security groups are reusable and don't need to be recreated for each applicable resource individually."})}),"\n",(0,i.jsxs)(r.p,{children:["Usually, initial security groups are added at the time of the creation of a VM.\nDuring creation, multiple security groups can also be added at the same time by repeating the ",(0,i.jsx)(r.code,{children:"--security-group"})," argument:"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack server create [...] --security-group $SECURITY_GROUP_1 --security-group $SECURITY_GROUP_2 $SERVER_NAME\n"})}),"\n",(0,i.jsx)(r.p,{children:"To add a security group to an existing VM, the following command can be used:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack server add security group $SERVER_NAME $SECURITY_GROUP\n"})}),"\n",(0,i.jsx)(r.p,{children:"To remove a security group from a VM, the following command can be used:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"openstack server remove security group $SERVER_NAME $SECURITY_GROUP\n"})}),"\n",(0,i.jsx)(r.p,{children:(0,i.jsxs)(r.em,{children:["The source of this document can be found in the ",(0,i.jsx)(r.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/docs/main/docs/02-iaas/guides/user-guide/security-groups/security-groups.md",children:"SovereignCloudStack/docs"})," repository."]})}),"\n",(0,i.jsx)(r.p,{children:(0,i.jsx)(r.em,{children:"Author: SCS Community, License: CC by Attribution 4.0 International"})})]})}function d(e={}){const{wrapper:r}={...(0,n.R)(),...e.components};return r?(0,i.jsx)(r,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,r,s)=>{s.d(r,{R:()=>o,x:()=>a});var t=s(96540);const i={},n=t.createContext(i);function o(e){const r=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(n.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b08c16de.389bc875.js b/assets/js/b08c16de.389bc875.js new file mode 100644 index 0000000000..48dadb5a19 --- /dev/null +++ b/assets/js/b08c16de.389bc875.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[89390],{41365:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"contribute/styleguides/ansible_styleguide","title":"Ansible Style Guide","description":"We use nearly all default rules of ansible lint. A listing of all these rules can be found in the Ansible Lint documentation:","source":"@site/community/contribute/styleguides/ansible_styleguide.md","sourceDirName":"contribute/styleguides","slug":"/contribute/styleguides/ansible_styleguide","permalink":"/community/contribute/styleguides/ansible_styleguide","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{}}');var i=s(74848),l=s(28453);const o={},a="Ansible Style Guide",r={},d=[{value:"Task naming",id:"task-naming",level:2},{value:"Key Order",id:"key-order",level:2},{value:"Positioning and use of the become directive",id:"positioning-and-use-of-the-become-directive",level:3},{value:"Position of the when condition",id:"position-of-the-when-condition",level:3},{value:"Usage of collections",id:"usage-of-collections",level:2},{value:"Usage of roles from other collections",id:"usage-of-roles-from-other-collections",level:2},{value:"Parameters that offer lists",id:"parameters-that-offer-lists",level:2},{value:"Usage of changed_when",id:"usage-of-changed_when",level:2},{value:"Disable linting rules",id:"disable-linting-rules",level:2}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,l.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"ansible-style-guide",children:"Ansible Style Guide"})}),"\n",(0,i.jsxs)(n.p,{children:["We use nearly all default rules of ansible lint. A listing of all these rules can be found in the Ansible Lint documentation:\n",(0,i.jsx)(n.a,{href:"https://ansible.readthedocs.io/projects/lint/rules/",children:"https://ansible.readthedocs.io/projects/lint/rules/"}),".\nPlease always use the ansible linting to check if the code complies with the default linting rules.\nHowever, since in most cases we always use the latest version of packages and Ansible lint does not provide this, we decided to\ndisable the package_latest rule."]}),"\n",(0,i.jsx)(n.h2,{id:"task-naming",children:"Task naming"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Tasks must always have names. The only exception allowed is for forked playbooks."}),"\n",(0,i.jsx)(n.li,{children:"A name never starts with a small letter"}),"\n",(0,i.jsx)(n.li,{children:"Names are written in present tense"}),"\n",(0,i.jsx)(n.li,{children:"No punctuation is used in names"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"key-order",children:"Key Order"}),"\n",(0,i.jsxs)(n.p,{children:["To check the key order we use our own rule. This can be found ",(0,i.jsx)(n.a,{href:"https://github.com/osism/zuul-jobs/tree/main/roles/ansible-lint/files",children:"here"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"positioning-and-use-of-the-become-directive",children:"Positioning and use of the become directive"}),"\n",(0,i.jsx)(n.p,{children:"The become directive is only set when needed and is always set explicitly for each task that needs it."}),"\n",(0,i.jsx)(n.p,{children:"Blocks, roles or playbooks are never executed in a privileged mode."}),"\n",(0,i.jsxs)(n.p,{children:["We always insert the become directive between the name of a task and the task itself. This also applies to related directives\nlike ",(0,i.jsx)(n.em,{children:"become_user"})," or ",(0,i.jsx)(n.em,{children:"become_flags"}),". This is for better visibility if a task is privileged or not."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'- name: Copy hddtemp configuration file\n become: true\n ansible.builtin.copy:\n src: "{{ ansible_os_family }}/hddtemp"\n dest: "{{ hddtemp_conf_file }}"\n owner: root\n group: root\n mode: 0644\n notify: Restart hddtemp service\n'})}),"\n",(0,i.jsx)(n.h3,{id:"position-of-the-when-condition",children:"Position of the when condition"}),"\n",(0,i.jsx)(n.p,{children:"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\neasier to understand for others. Ansible lint provides the when condition under the task name for blocks. To keep the code clear\nwe decided against it. Please disable this with a noqa if necessary. For example:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'- name: "Archive existing {{ resolvconf_file }} file"\n become: true\n ansible.posix.synchronize:\n src: "/etc/resolv.conf"\n dest: "/etc/resolv.conf.{{ ansible_date_time.date }}"\n archive: true\n delegate_to: "{{ inventory_hostname }}"\n when: stat_resolvconf_file.stat.islnk is defined and not stat_resolvconf_file.stat.islnk\n'})}),"\n",(0,i.jsx)(n.h2,{id:"usage-of-collections",children:"Usage of collections"}),"\n",(0,i.jsx)(n.p,{children:"Collections are always defined as in the following example."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"netbox.netbox"})," is here the collection that is used."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"- name: Configure netbox manufacturers\n netbox.netbox.netbox_manufacturer:\n netbox_url: '{{ netbox_url }}'\n netbox_token: '{{ netbox_token }}'\n data:\n name: '{{ item.value.name }}'\n slug: '{{ item.value.slug }}'\n description: \"{{ item.value.description | default('') }}\"\n state: present\n with_dict: '{{ netbox_data_manufacturers }}'\n"})}),"\n",(0,i.jsx)(n.p,{children:"Please don\xb4t declare it in this way!:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'collections:\n - netbox.netbox\n\n tasks:\n - name: Manage Discworld site\n netbox_site:\n netbox_url: "{{ netbox_url }}"\n netbox_token: "{{ netbox_token }}"\n validate_certs: false\n data:\n name: Discworld\n slug: discworld\n state: present\n'})}),"\n",(0,i.jsx)(n.p,{children:"If you have to use collections please define them in a requirements.yml."}),"\n",(0,i.jsx)(n.p,{children:"Example yaml:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"roles:\n - name: geerlingguy.certbot\n version: master\n type: git\n src: git+https://github.com/geerlingguy/ansible-role-certbot.git\n---\ncollections:\n - name: ansible.netcommon\n source: https://galaxy.ansible.com\n\n - name: https://github.com/ansible-collections/ansible.posix.git\n type: git\n version: main\n"})}),"\n",(0,i.jsx)(n.h2,{id:"usage-of-roles-from-other-collections",children:"Usage of roles from other collections"}),"\n",(0,i.jsx)(n.p,{children:"If you want to reuse roles please do it in the following way:"}),"\n",(0,i.jsx)(n.p,{children:"First you have to declare the role or collection in the requirements.yml like shown in the example before."}),"\n",(0,i.jsx)(n.p,{children:"Than you can use it in playbooks like this"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"roles:\n - role: osism.services.auditd\n"})}),"\n",(0,i.jsx)(n.h2,{id:"parameters-that-offer-lists",children:"Parameters that offer lists"}),"\n",(0,i.jsx)(n.p,{children:"Parameters that provide a list are always defined as in the following example."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"docker_hosts_defaults"})," sets the defaults in the role. Overriding is only possible with the ",(0,i.jsx)(n.strong,{children:"ansible-defaults"})," repository."]}),"\n",(0,i.jsx)(n.p,{children:"In the configuration repository, docker_hosts_extra is then used to add additional items to the list."}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"docker_hosts"})," itself is never modified from the outside."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"docker_hosts_defaults:\n - 'unix:///var/run/docker.sock'\ndocker_hosts_extra: []\ndocker_hosts: '{{ docker_hosts_defaults + docker_hosts_extra }}'\n"})}),"\n",(0,i.jsx)(n.h2,{id:"usage-of-changed_when",children:"Usage of changed_when"}),"\n",(0,i.jsx)(n.p,{children:"Please think twice before turning off changed_when. It's a fairly simple yet safety-relevant linting rule and is quite easy to\nimplement."}),"\n",(0,i.jsx)(n.h2,{id:"disable-linting-rules",children:"Disable linting rules"}),"\n",(0,i.jsxs)(n.p,{children:["In principle, it is only allowed to disable rules if there is really no other possibility.\nPlease do not disable rules in general but only in individual cases via Noqa. Please use in this case the full rulename and not\nthe numbers, because them are depricated. If it makes sense to ignore a rule, please open up an issue in the\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/issues",children:"https://github.com/osism/issues"})," repository with a label discussion."]})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const i={},l=t.createContext(i);function o(e){const n=t.useContext(l);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b0ccdb87.ef8f6cd2.js b/assets/js/b0ccdb87.ef8f6cd2.js new file mode 100644 index 0000000000..585f6e6a2f --- /dev/null +++ b/assets/js/b0ccdb87.ef8f6cd2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6646],{4030:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"operating-scs/components/central-api/overview","title":"Overview","description":"Premise","source":"@site/docs/04-operating-scs/components/central-api/overview.md","sourceDirName":"04-operating-scs/components/central-api","slug":"/operating-scs/components/central-api/overview","permalink":"/docs/operating-scs/components/central-api/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/central-api/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Central API","permalink":"/docs/category/central-api"},"next":{"title":"Central API MVP","permalink":"/docs/operating-scs/components/central-api/poc-setup"}}');var r=t(74848),i=t(28453);const o={},a="Overview",c={},l=[{value:"Premise",id:"premise",level:2},{value:"Challenge",id:"challenge",level:2},{value:"The chosen approach to pursue",id:"the-chosen-approach-to-pursue",level:2},{value:"Kubernetes API",id:"kubernetes-api",level:3},{value:"Crossplane tooling",id:"crossplane-tooling",level:3},{value:"Cluster stacks / Cluster API",id:"cluster-stacks--cluster-api",level:3},{value:"Implementation",id:"implementation",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",ol:"ol",p:"p",section:"section",strong:"strong",sup:"sup",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(n.h2,{id:"premise",children:"Premise"}),"\n",(0,r.jsx)(n.p,{children:"By embracing existing open source solutions and bundling them, SCS provides a viable\nalternative to widely adopted proprietary cloud offerings, including\nInfrastructure-as-a-Service offerings, Kubernetes-as-a-Service offerings and other\nX-as-a-Service offerings."}),"\n",(0,r.jsx)(n.p,{children:"The choice to embrace existing technology has huge advantages over starting from\nscratch.\nBy not reinventing wheels, a lot of effort is saved and existing communities are\nstrengthened. The adoption of existing open standards is supported, reducing\nmarket fragmentation and increasing interoperability."}),"\n",(0,r.jsx)(n.h2,{id:"challenge",children:"Challenge"}),"\n",(0,r.jsx)(n.p,{children:"The challenge: Using popular open source components at cloud service providers\ndoes not result in a consistent experience for their users, yet."}),"\n",(0,r.jsxs)(n.p,{children:["Each part of the stack is consistent within its own scope: E.g. The\n",(0,r.jsx)(n.a,{href:"https://docs.openstack.org/api-ref/network/v2/",children:"OpenStack Networking API"})," is sort of\nconsistent with the\n",(0,r.jsx)(n.a,{href:"https://docs.openstack.org/api-ref/load-balancer/v2/",children:"OpenStack Load Balancer API"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"The OpenStack API's share API idioms like the used AuthN/AuthZ\n(Authentication/Authorization) mechanisms. But these are not applicable beyond\nOpenStack services."}),"\n",(0,r.jsxs)(n.p,{children:["Entering general IAM (Identity and Access Management), Keycloak has its own set of\nAPI endpoints and authentication flows.\nEntering Kubernetes, CAPI (",(0,r.jsx)(n.a,{href:"https://cluster-api.sigs.k8s.io/",children:"Kubernetes Cluster API"}),")\nuses the Kubernetes API with its own authentication configuration, RBAC (Role Based\nAccess Control) and opinionated resource management idioms."]}),"\n",(0,r.jsx)(n.p,{children:"So, without a central API harmonizing at least the semantics of AuthN/AuthZ and\nresource management, users are left with a bunch of semantically incompatible API's.\nIf resources in different API's are somehow interconnected, the users have to take\ncare of bridging these differences themselves."}),"\n",(0,r.jsx)(n.p,{children:"Providing a consistent API across many different offerings with sort of consistent\nAPI idioms is something that primarily the big proprietary cloud providers manage to\ndo. And while that serves users well in that regard, it also serves as an effective\nvendor lock-in feature."}),"\n",(0,r.jsx)(n.h2,{id:"the-chosen-approach-to-pursue",children:"The chosen approach to pursue"}),"\n",(0,r.jsx)(n.mermaid,{value:'flowchart TB\n subgraph "With central API (simplified)"\n User2{"User"}\n subgraph "provider responsibility"\n CentralAPI["Central API"]\n OpenStack2["OpenStack API"]\n Keycloak2["Keycloak API"]\n CAPI2["Cluster API"]\n end\n\n User2\n -- uses --\x3e K8sTooling2["kubectl/\\nargocd/flux/..."]\n K8sTooling2 -- calls --\x3e CentralAPI\n CentralAPI -- calls --\x3e OpenStack2\n CentralAPI -- calls --\x3e Keycloak2\n CentralAPI -- calls --\x3e CAPI2\n end\n subgraph "Without central API (simplified)"\n User1{"User"}\n subgraph "provider responsibility"\n OpenStack1["OpenStack API"]\n Keycloak1["Keycloak API"]\n end\n CAPI1["Cluster API"]\n\n User1\n -- uses --\x3e OpenStackCLI1["OpenStackCLI/OpenStackUI/\\nTerraform/Ansible/..."]\n -- calls --\x3e OpenStack1\n User1\n -- uses --\x3e KeycloakCLI1["KeycloakCLI/KeycloakUI/\\nTerraform/Ansible/..."]\n -- calls --\x3e Keycloak1\n User1\n -- uses --\x3e K8sTooling1["kubectl/\\nargocd/flux/..."]\n -- calls --\x3e CAPI1\n end'}),"\n",(0,r.jsxs)(n.p,{children:["Goal: ",(0,r.jsx)(n.strong,{children:'Provide a "semantically" consistent API modelling most cloud resources\nthat are in scope for SCS'}),"."]}),"\n",(0,r.jsx)(n.p,{children:"In other words: Bring each cloud resource type - as it is - into the central API."}),"\n",(0,r.jsxs)(n.p,{children:["An ",(0,r.jsx)(n.code,{children:"OpenStack Compute Instance"})," continues to be as-is with all of its usual\nproperties and implementation details.\nA ",(0,r.jsx)(n.code,{children:"Keycloak Realm"})," continues to be as-is with all of its usual properties\nand implementation details."]}),"\n",(0,r.jsxs)(n.p,{children:["That is not to say that abstractions are absolutely not planned as further steps.\nThere were discussions happening about that already: Regarding IAM management ",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"\nand Kubernetes management ",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["However, the ",(0,r.jsx)(n.strong,{children:"main"})," benefit is that all offered API objects can be managed\nusing the same API idioms (AuthN/AuthZ/REST) with the same client tooling ",(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-3",id:"user-content-fnref-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"kubernetes-api",children:"Kubernetes API"}),"\n",(0,r.jsx)(n.p,{children:'Instead of creating SCS-specific API idioms and building the implementation\nfrom scratch, the Kubernetes API will be "reused". Essentially, the Kubernetes\nAPI is just an opinionated REST API which has opinions on how a resource\nis defined, how it looks like, how it is reconciled/handled, how AuthN/AuthZ\ncan be implemented. The Kubernetes ecosystem provides much tooling for working\nwith such (custom) resource definitions: For creating the definitions\nthemselves, building controllers, making them discoverable and deployable.'}),"\n",(0,r.jsx)(n.p,{children:"As such, Kubernetes is a great choice for building any sort of resource\nmanagement API - with some caveats regarding its deployment and the legacy\nof starting off as container orchestration tooling."}),"\n",(0,r.jsx)(n.h3,{id:"crossplane-tooling",children:"Crossplane tooling"}),"\n",(0,r.jsxs)(n.p,{children:['Crossplane even extends the Kubernetes API with\n"',(0,r.jsx)(n.a,{href:"https://docs.crossplane.io/v1.14/concepts/compositions/",children:"Compositions"}),'" and\n"',(0,r.jsx)(n.a,{href:"https://docs.crossplane.io/v1.14/concepts/composite-resource-definitions/",children:"Composite Resource Definitions"}),'"\n(XRD) to make Kubernetes the base for platform engineering within organizations.']}),"\n",(0,r.jsx)(n.p,{children:'Secondly, it provides an API machinery to bring any cloud resource into Kubernetes\nusing backend-specific "providers" (roughly comparable with Terraform providers).\nAs such, Crossplane with its provider ecosystem actually already did most of\nthe heavy lifting for providing e.g. OpenStack or Keycloak resources inside of Kubernetes.'}),"\n",(0,r.jsxs)(n.p,{children:["On top, the platform engineering concepts in Crossplane make building multi-tenancy\nsystems pretty straight-forward, even for\n",(0,r.jsx)(n.a,{href:"https://docs.crossplane.io/knowledge-base/guides/multi-tenant/#single-cluster-multi-tenancy",children:"single clusters"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Alright. Crossplane takes care of exposing OpenStack resources and does some\nfancy stuff regarding multi-tenancy. What about providing actual Kubernetes\n",(0,r.jsx)(n.strong,{children:"workload"})," clusters?"]}),"\n",(0,r.jsx)(n.h3,{id:"cluster-stacks--cluster-api",children:"Cluster stacks / Cluster API"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks",children:"Cluster stacks"})," do\n",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/blob/adb648ceaebddca04a015fbea0319110ca99a5cc/docs/architecture/user-flow.md#recap---how-do-cluster-api-and-cluster-stacks-work-together",children:"not replace the use of Cluster API"}),".\nInstead, they are complementing Cluster API by providing ",(0,r.jsx)(n.code,{children:"ClusterClasses"}),", node\nimages (if required) and workload cluster addons."]}),"\n",(0,r.jsx)(n.p,{children:"It is still to be determined how to bring multi-tenancy concepts from Crossplane\ninto ClusterStacks/CAPI, if even required."}),"\n",(0,r.jsxs)(n.p,{children:["Should the provider be responsible for creating ",(0,r.jsx)(n.code,{children:"ClusterClasses"}),"?\nIf yes, enforcing some parameters inside via a ",(0,r.jsx)(n.code,{children:"ClusterClass"})," may be enough\nto provide multi-tenancy, already. That is to be determined, though."]}),"\n",(0,r.jsx)(n.h2,{id:"implementation",children:"Implementation"}),"\n",(0,r.jsxs)(n.p,{children:["Disregarding any potential further abstractions, most work in automation for\nthe providers will be about installing the central API and securely distributing\ncredentials for backing services like OpenStack or Keycloak.\nFor that, there is no production implementation yet. See\n",(0,r.jsx)(n.a,{href:"/docs/operating-scs/components/central-api/poc-setup",children:"the POC for inspiration"})," for now. It includes access to an OpenStack API\nthrough Kubernetes/Crossplane."]}),"\n","\n",(0,r.jsxs)(n.section,{"data-footnotes":!0,className:"footnotes",children:[(0,r.jsx)(n.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{id:"user-content-fn-1",children:["\n",(0,r.jsxs)(n.p,{children:['There were discussions to build a generic SCS API to support\nSCS installations powered by Zitadel. Approaching the issue a little\nbit like the "Abstract all the things!" consideration above, but focusing\non two basic use cases (Firstly, setting up an identity federation to some\nexisting identity provider; Secondly, managing users without remote identity\nprovider). While not in scope for the first steps, this probably could be\nelegantly implemented as one generic Crossplane "Composite Resource Definition"\nbacked by a Crossplane "Composition" defining either Keycloak objects OR\nZitadel objects (given that Zitadel gets a Crossplane provider or a similar\nKubernetes controller before). ',(0,r.jsx)(n.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-2",children:["\n",(0,r.jsxs)(n.p,{children:['In order to cover providers that use Gardnener, a generic Crossplane\n"Composite Resource Definition" like in ',(0,r.jsx)(n.sup,{children:(0,r.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),' may be created. Alternatively,\nGardnener CRD\'s could maybe just be mirrored in their Central API instance,\nstill creating an interoperability benefit through "semantic" compatibility. ',(0,r.jsx)(n.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{id:"user-content-fn-3",children:["\n",(0,r.jsxs)(n.p,{children:["Which is also not to say that it will be suggested to providers to disable\ntheir public OpenStack/Keycloak/... API's, preventing use of native\nOpenStack/Keycloak/... tooling and breaking existing solutions.\nExtensively using these API's together with the central API may compromise\nthe benefits of its uniform AuthZ, though. ",(0,r.jsx)(n.a,{href:"#user-content-fnref-3","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const r={},i=s.createContext(r);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b0f0cb2b.efce416d.js b/assets/js/b0f0cb2b.efce416d.js new file mode 100644 index 0000000000..bab7911d11 --- /dev/null +++ b/assets/js/b0f0cb2b.efce416d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[86376],{95923:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"iaas/scs-0118","title":"scs-0118: SCS Taxonomy of Failsafe Levels","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0118.md","sourceDirName":"iaas","slug":"/iaas/scs-0118","permalink":"/standards/iaas/scs-0118","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0117-v1-volume-backup-service"},"next":{"title":"V1","permalink":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels"}}');var n=t(74848),r=t(28453);const d={},i="scs-0118: SCS Taxonomy of Failsafe Levels",c={},l=[{value:"Supplement: Examples of Failure Cases and their impact on IaaS and KaaS resources",id:"supplement-examples-of-failure-cases-and-their-impact-on-iaas-and-kaas-resources",level:2}];function o(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"scs-0118-scs-taxonomy-of-failsafe-levels",children:"scs-0118: SCS Taxonomy of Failsafe Levels"})}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Version"}),(0,n.jsx)(s.th,{children:"Type"}),(0,n.jsx)(s.th,{children:"State"}),(0,n.jsx)(s.th,{children:"stabilized"}),(0,n.jsx)(s.th,{children:"deprecated"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0118-v1-taxonomy-of-failsafe-levels",children:"scs-0118-v1"})}),(0,n.jsx)(s.td,{children:"Decision Record"}),(0,n.jsx)(s.td,{children:"Draft"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]})})]}),"\n",(0,n.jsx)(s.h2,{id:"supplement-examples-of-failure-cases-and-their-impact-on-iaas-and-kaas-resources",children:"Supplement: Examples of Failure Cases and their impact on IaaS and KaaS resources"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Version"}),(0,n.jsx)(s.th,{children:"State"}),(0,n.jsx)(s.th,{children:"stabilized"}),(0,n.jsx)(s.th,{children:"deprecated"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0118-w1-example-impacts-of-failure-scenarios",children:"w1"})}),(0,n.jsx)(s.td,{children:"Draft"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(o,{...e})}):o(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>d,x:()=>i});var a=t(96540);const n={},r=a.createContext(n);function d(e){const s=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:d(e.components),a.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b191927f.704e1471.js b/assets/js/b191927f.704e1471.js new file mode 100644 index 0000000000..73cb09be56 --- /dev/null +++ b/assets/js/b191927f.704e1471.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[86452],{121:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>a});const l=JSON.parse('{"id":"scs-compatible-iaas","title":"SCS-compatible IaaS","description":"| Scope versions -> | v3 | v4 | v5.1 |","source":"@site/standards/scs-compatible-iaas.md","sourceDirName":".","slug":"/scs-compatible-iaas","permalink":"/standards/scs-compatible-iaas","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"Scopes and versions","permalink":"/standards/certification/scopes-versions"},"next":{"title":"SCS-compatible KaaS","permalink":"/standards/scs-compatible-kaas"}}');var n=s(74848),d=s(28453);const i={},r="SCS-compatible IaaS",c={},a=[];function x(t){const e={a:"a",h1:"h1",header:"header",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"scs-compatible-iaas",children:"SCS-compatible IaaS"})}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"Scope versions ->"}),(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"v3"}),(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"v4"}),(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"v5.1"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"State"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"Deprecated"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"Effective"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"Effective"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"Stabilized at"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"2024-02-28"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"2024-02-28"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"2024-12-19"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.strong,{children:"Modules"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://opendev.org/openinfra/interop/src/branch/master/guidelines/2022.11.json",children:"OpenStack Powered Compute v2022.11"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0100-v3-flavor-naming",children:"scs-0100-v3.1: Flavor naming v3.1"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0101-v1-entropy",children:"scs-0101-v1: Entropy v1"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0102-v1-image-metadata",children:"scs-0102-v1: Image metadata v1"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0103-v1-standard-flavors",children:"scs-0103-v1: Standard flavors"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0104-v1-standard-images",children:"scs-0104-v1: Standard images"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsxs)(e.td,{style:{textAlign:"left"},children:["X (",(0,n.jsx)(e.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/iaas/scs-0104-v1-images.yaml",children:"image_spec"}),")"]}),(0,n.jsxs)(e.td,{style:{textAlign:"left"},children:["X (",(0,n.jsx)(e.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/iaas/scs-0104-v1-images-v5.yaml",children:"image_spec"}),")"]})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0114-v1-volume-type-standard",children:"scs-0114-v1: Volume Types"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0115-v1-default-rules-for-security-groups",children:"scs-0115-v1: Default rules for security groups"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0116-v1-key-manager-standard",children:"scs-0116-v1: Key manager"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0117-v1-volume-backup-service",children:"scs-0117-v1: Volume backup"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0121-v1-Availability-Zones-Standard",children:"scs-0121-v1: Availability Zones"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0123-v1-mandatory-and-supported-IaaS-services",children:"scs-0123-v1: Mandatory and Supported IaaS Services"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0302-v1-domain-manager-role",children:"scs-0302-v1: Domain Manager Role"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]})]})]})]})}function h(t={}){const{wrapper:e}={...(0,d.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(x,{...t})}):x(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>i,x:()=>r});var l=s(96540);const n={},d=l.createContext(n);function i(t){const e=l.useContext(d);return l.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function r(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(n):t.components||n:i(t.components),l.createElement(d.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/b1bfccfc.76e67101.js b/assets/js/b1bfccfc.76e67101.js new file mode 100644 index 0000000000..708762c2c5 --- /dev/null +++ b/assets/js/b1bfccfc.76e67101.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[11159],{73750:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"iaas/guides/deploy-guide/rookify","title":"Deploy Rookify: Migrate to Rook from Ceph-Ansible (Technical Preview)","description":"Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime.","source":"@site/docs/02-iaas/guides/deploy-guide/rookify.md","sourceDirName":"02-iaas/guides/deploy-guide","slug":"/iaas/guides/deploy-guide/rookify","permalink":"/docs/iaas/guides/deploy-guide/rookify","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/rookify.md","tags":[],"version":"current","sidebarPosition":51,"frontMatter":{"sidebar_label":"Rookify (technical preview)","sidebar_position":51},"sidebar":"docs","previous":{"title":"Bootstrap","permalink":"/docs/iaas/guides/deploy-guide/bootstrap"},"next":{"title":"Services","permalink":"/docs/iaas/guides/deploy-guide/services/"}}');var t=r(74848),i=r(28453);r(11470),r(19365);const s={sidebar_label:"Rookify (technical preview)",sidebar_position:51},a="Deploy Rookify: Migrate to Rook from Ceph-Ansible (Technical Preview)",l={},c=[{value:"Prerequisites & Requirements",id:"prerequisites--requirements",level:2},{value:"Manual Installation",id:"manual-installation",level:2},{value:"Download or Clone the Repository",id:"download-or-clone-the-repository",level:3},{value:"Install and Run Locally (without Docker)",id:"install-and-run-locally-without-docker",level:3},{value:"Install and Run from within a Container",id:"install-and-run-from-within-a-container",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"deploy-rookify-migrate-to-rook-from-ceph-ansible-technical-preview",children:"Deploy Rookify: Migrate to Rook from Ceph-Ansible (Technical Preview)"})}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsxs)(n.p,{children:["Rookify is developed to migrate from Ceph-Ansible to Rook ",(0,t.jsx)(n.em,{children:"in place"})," and ",(0,t.jsx)(n.em,{children:"without downtime"}),".\nNevertheless, it is ",(0,t.jsx)(n.strong,{children:"strongly advised"})," to test Rookify in a controlled environment first, such as the ",(0,t.jsx)(n.a,{href:"https://github.com/osism/testbed",children:"OSISM testbed"}),". Additionally ensure that precautionary backups are made and all other necessary safety measures are in place."]})}),"\n",(0,t.jsx)(n.p,{children:'It is currently recommended to install Rookify on your local machine and connect through VPNs to the target system (the one where Ceph-Ansible needs to be "rookified" \ud83d\ude09).'}),"\n",(0,t.jsxs)(n.p,{children:["Rookify operates ",(0,t.jsx)(n.code,{children:"in place"}),", meaning no parallel nodes are required. As noted earlier, Rookify is developed to migrate from Ceph-Ansible to Rook ",(0,t.jsx)(n.em,{children:"in place"})," and ",(0,t.jsx)(n.em,{children:"without downtime"}),", but given the complexity of infrastructure, precautionary backups and safety measures are highly recommended."]}),"\n",(0,t.jsxs)(n.p,{children:["For a condensed summary of the information covered here, refer to the ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/rookify",children:"Rookify GitHub repository"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites--requirements",children:"Prerequisites & Requirements"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"A functioning Ceph cluster deployed using traditional methods."}),"\n",(0,t.jsx)(n.li,{children:"Access to a Kubernetes cluster with sufficient resources to host the migrated Ceph cluster."}),"\n",(0,t.jsx)(n.li,{children:"Kubernetes nodes must be deployed on at least the OSD nodes."}),"\n",(0,t.jsx)(n.li,{children:"Monitor and OSD daemons should stay in place. Former to ensure that the Ceph endpoints do not change during migration, the later ones to have access to the underlying hardware."}),"\n",(0,t.jsx)(n.li,{children:"Rook operator version 1.13 or higher installed on the Kubernetes cluster."}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"radoslib"})," version 2.0.0 installed."]}),"\n",(0,t.jsxs)(n.li,{children:["For a ",(0,t.jsx)(n.em,{children:"dockerized setup"}),", ",(0,t.jsx)(n.code,{children:"docker"})," and ",(0,t.jsx)(n.code,{children:"docker compose"})," are required."]}),"\n",(0,t.jsxs)(n.li,{children:["In order to use the Makefile, ",(0,t.jsx)(n.code,{children:"GNU make"})," is required."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"manual-installation",children:"Manual Installation"}),"\n",(0,t.jsx)(n.h3,{id:"download-or-clone-the-repository",children:"Download or Clone the Repository"}),"\n",(0,t.jsxs)(n.p,{children:["Clone or download Rookify from the ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/rookify",children:"repository"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"install-and-run-locally-without-docker",children:"Install and Run Locally (without Docker)"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Navigate to the tool directory:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd rookify\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["To install Rookify locally, Python's ",(0,t.jsx)(n.code,{children:"virtualenv"})," will be used (Note: This will install ",(0,t.jsx)(n.code,{children:"pre-commit"})," in your local user user context):"]}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["Checkout the included options in the ",(0,t.jsx)(n.code,{children:"Makefile"})," by typing ",(0,t.jsx)(n.code,{children:"make"}),"."]})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"make setup\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This command also verifies if the required Python library ",(0,t.jsx)(n.code,{children:"radoslib"})," is installed. Ensure it is available on your Linux distribution."]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["Before running Rookify, check all available options by using ",(0,t.jsx)(n.code,{children:"rookify --help"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:["To run Rookify you can either run it directly from within Python's ",(0,t.jsx)(n.code,{children:"virtualenv"})," or with help of the Makefile:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# directly\n./.venv/bin/rookify --help\n# using make\nmake run-local-rookify\n"})}),"\n",(0,t.jsx)(n.h3,{id:"install-and-run-from-within-a-container",children:"Install and Run from within a Container"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Navigate to the tool directory:"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["To install Rookify in a container, you can use either Podman or Docker (Note: In both cases, Python\u2019s ",(0,t.jsx)(n.code,{children:"radoslib"})," library must be installed locally):"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"make check-radoslib\nmake up\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This command uses ",(0,t.jsx)(n.code,{children:"docker compose"}),", so ensure it is installed as well."]}),"\n",(0,t.jsxs)(n.p,{children:["To run Rookify, you can either enter the container and run it from there or use ",(0,t.jsx)(n.code,{children:"make run-rookify"}),"."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Before running rookify, it's useful to check all options by using ",(0,t.jsx)(n.code,{children:"rookify --help"}),"."]})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},19365:(e,n,r)=>{r.d(n,{A:()=>s});r(96540);var o=r(18215);const t={tabItem:"tabItem_Ymn6"};var i=r(74848);function s(e){let{children:n,hidden:r,className:s}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,o.A)(t.tabItem,s),hidden:r,children:n})}},11470:(e,n,r)=>{r.d(n,{A:()=>j});var o=r(96540),t=r(18215),i=r(23104),s=r(56347),a=r(205),l=r(57485),c=r(31682),d=r(70679);function u(e){return o.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,o.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:n,children:r}=e;return(0,o.useMemo)((()=>{const e=n??function(e){return u(e).map((e=>{let{props:{value:n,label:r,attributes:o,default:t}}=e;return{value:n,label:r,attributes:o,default:t}}))}(r);return function(e){const n=(0,c.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,r])}function p(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:r}=e;const t=(0,s.W6)(),i=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,l.aZ)(i),(0,o.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(t.location.search);n.set(i,e),t.replace({...t.location,search:n.toString()})}),[i,t])]}function f(e){const{defaultValue:n,queryString:r=!1,groupId:t}=e,i=h(e),[s,l]=(0,o.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!p({value:n,tabValues:r}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const o=r.find((e=>e.default))??r[0];if(!o)throw new Error("Unexpected error: 0 tabValues");return o.value}({defaultValue:n,tabValues:i}))),[c,u]=m({queryString:r,groupId:t}),[f,y]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,i]=(0,d.Dv)(r);return[t,(0,o.useCallback)((e=>{r&&i.set(e)}),[r,i])]}({groupId:t}),b=(()=>{const e=c??f;return p({value:e,tabValues:i})?e:null})();(0,a.A)((()=>{b&&l(b)}),[b]);return{selectedValue:s,selectValue:(0,o.useCallback)((e=>{if(!p({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),y(e)}),[u,y,i]),tabValues:i}}var y=r(92303);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=r(74848);function g(e){let{className:n,block:r,selectedValue:o,selectValue:s,tabValues:a}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,i.a_)(),d=e=>{const n=e.currentTarget,r=l.indexOf(n),t=a[r].value;t!==o&&(c(n),s(t))},u=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;n=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;n=l[r]??l[l.length-1];break}}n?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":r},n),children:a.map((e=>{let{value:n,label:r,attributes:i}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:o===n?0:-1,"aria-selected":o===n,ref:e=>l.push(e),onKeyDown:u,onClick:d,...i,className:(0,t.A)("tabs__item",b.tabItem,i?.className,{"tabs__item--active":o===n}),children:r??n},n)}))})}function v(e){let{lazy:n,children:r,selectedValue:i}=e;const s=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=s.find((e=>e.props.value===i));return e?(0,o.cloneElement)(e,{className:(0,t.A)("margin-top--md",e.props.className)}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:s.map(((e,n)=>(0,o.cloneElement)(e,{key:n,hidden:e.props.value!==i})))})}function k(e){const n=f(e);return(0,x.jsxs)("div",{className:(0,t.A)("tabs-container",b.tabList),children:[(0,x.jsx)(g,{...n,...e}),(0,x.jsx)(v,{...n,...e})]})}function j(e){const n=(0,y.A)();return(0,x.jsx)(k,{...e,children:u(e.children)},String(n))}},28453:(e,n,r)=>{r.d(n,{R:()=>s,x:()=>a});var o=r(96540);const t={},i=o.createContext(t);function s(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b1eed1ab.95975c42.js b/assets/js/b1eed1ab.95975c42.js new file mode 100644 index 0000000000..8ff19a0a66 --- /dev/null +++ b/assets/js/b1eed1ab.95975c42.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[37362],{48377:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"kaas/scs-0214","title":"scs-0214: Kubernetes Node Distribution and Availability","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/kaas/scs-0214.md","sourceDirName":"kaas","slug":"/kaas/scs-0214","permalink":"/standards/kaas/scs-0214","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0213-v1-k8s-nodes-anti-affinity"},"next":{"title":"V1","permalink":"/standards/scs-0214-v1-k8s-node-distribution"}}');var d=s(74848),i=s(28453);const r={},a="scs-0214: Kubernetes Node Distribution and Availability",c={},l=[{value:"Supplement: Implementation and Testing Notes",id:"supplement-implementation-and-testing-notes",level:2}];function o(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(t.header,{children:(0,d.jsx)(t.h1,{id:"scs-0214-kubernetes-node-distribution-and-availability",children:"scs-0214: Kubernetes Node Distribution and Availability"})}),"\n",(0,d.jsxs)(t.table,{children:[(0,d.jsx)(t.thead,{children:(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.th,{children:"Version"}),(0,d.jsx)(t.th,{children:"Type"}),(0,d.jsx)(t.th,{children:"State"}),(0,d.jsx)(t.th,{children:"stabilized"}),(0,d.jsx)(t.th,{children:"deprecated"})]})}),(0,d.jsxs)(t.tbody,{children:[(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"/standards/scs-0214-v1-k8s-node-distribution",children:"scs-0214-v1"})}),(0,d.jsx)(t.td,{children:"Standard"}),(0,d.jsx)(t.td,{children:"Stable"}),(0,d.jsx)(t.td,{children:"2024-02-08"}),(0,d.jsx)(t.td,{children:"-"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"/standards/scs-0214-v2-k8s-node-distribution",children:"scs-0214-v2"})}),(0,d.jsx)(t.td,{children:"Standard"}),(0,d.jsx)(t.td,{children:"Stable"}),(0,d.jsx)(t.td,{children:"2024-11-21"}),(0,d.jsx)(t.td,{children:"-"})]})]})]}),"\n",(0,d.jsx)(t.h2,{id:"supplement-implementation-and-testing-notes",children:"Supplement: Implementation and Testing Notes"}),"\n",(0,d.jsxs)(t.table,{children:[(0,d.jsx)(t.thead,{children:(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.th,{children:"Version"}),(0,d.jsx)(t.th,{children:"State"}),(0,d.jsx)(t.th,{children:"stabilized"}),(0,d.jsx)(t.th,{children:"deprecated"})]})}),(0,d.jsx)(t.tbody,{children:(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{children:(0,d.jsx)(t.a,{href:"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing",children:"w1"})}),(0,d.jsx)(t.td,{children:"Draft"}),(0,d.jsx)(t.td,{children:"-"}),(0,d.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,d.jsx)(t,{...e,children:(0,d.jsx)(o,{...e})}):o(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>a});var n=s(96540);const d={},i=n.createContext(d);function r(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:r(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b1fd1705.dfffdf58.js b/assets/js/b1fd1705.dfffdf58.js new file mode 100644 index 0000000000..3d0ecb10df --- /dev/null +++ b/assets/js/b1fd1705.dfffdf58.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[78215],{76165:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"operating-scs/guides/openstack-health-monitor/Debian12-Install","title":"Guide: Setting up openstack-health-monitor on Debian 12","description":"Kurt Garloff, 2024-02-20","source":"@site/docs/04-operating-scs/01-guides/openstack-health-monitor/Debian12-Install.md","sourceDirName":"04-operating-scs/01-guides/openstack-health-monitor","slug":"/operating-scs/guides/openstack-health-monitor/Debian12-Install","permalink":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/01-guides/openstack-health-monitor/Debian12-Install.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Guides","permalink":"/docs/category/guides-1"},"next":{"title":"Metering","permalink":"/docs/category/metering"}}');var s=t(74848),a=t(28453);const i={},r="Guide: Setting up openstack-health-monitor on Debian 12",d={},l=[{value:"Intro",id:"intro",level:2},{value:"Setting up the driver VM",id:"setting-up-the-driver-vm",level:2},{value:"Internal vs external monitoring",id:"internal-vs-external-monitoring",level:3},{value:"Unprivileged operation",id:"unprivileged-operation",level:3},{value:"Driver VM via openstack CLI",id:"driver-vm-via-openstack-cli",level:3},{value:"Configuring openstack CLI on the driver VM",id:"configuring-openstack-cli-on-the-driver-vm",level:3},{value:"Custom CA",id:"custom-ca",level:3},{value:"Your first <code>api_monitor.sh</code> iteration",id:"your-first-api_monitorsh-iteration",level:2},{value:"Resource impact and charging",id:"resource-impact-and-charging",level:3},{value:"Automating startup and cleanup",id:"automating-startup-and-cleanup",level:2},{value:"Changing parameters and restarting",id:"changing-parameters-and-restarting",level:3},{value:"Multiple instances",id:"multiple-instances",level:3},{value:"Alarming and Logs",id:"alarming-and-logs",level:2},{value:"eMail",id:"email",level:3},{value:"Log files",id:"log-files",level:3},{value:"Data collection and dashboard",id:"data-collection-and-dashboard",level:2},{value:"Telegraf",id:"telegraf",level:3},{value:"InfluxDB",id:"influxdb",level:3},{value:"Add <code>-S CLOUDNAME</code> to your <code>run_CLOUDNAME.sh</code> script",id:"add--s-cloudname-to-your-run_cloudnamesh-script",level:3},{value:"Caddy (Reverse Proxy)",id:"caddy-reverse-proxy",level:3},{value:"Install Caddy",id:"install-caddy",level:4},{value:"Allow HTTP traffic for oshm-driver",id:"allow-http-traffic-for-oshm-driver",level:4},{value:"Configure Caddy",id:"configure-caddy",level:4},{value:"Grafana",id:"grafana",level:3},{value:"Install Grafana",id:"install-grafana",level:4},{value:"Basic config",id:"basic-config",level:4},{value:"Enable influx database in grafana",id:"enable-influx-database-in-grafana",level:4},{value:"Importing the dashboard",id:"importing-the-dashboard",level:4},{value:"No data displayed?",id:"no-data-displayed",level:4},{value:"Dashboard features",id:"dashboard-features",level:4},{value:"GitHub OIDC Integration",id:"github-oidc-integration",level:4},{value:"Maintenance",id:"maintenance",level:2},{value:"Unattended upgrades",id:"unattended-upgrades",level:3},{value:"sshd setup",id:"sshd-setup",level:3},{value:"Updating openstack-health-monitor",id:"updating-openstack-health-monitor",level:3},{value:"Backup",id:"backup",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Debugging issues",id:"debugging-issues",level:3},{value:"Analyzing failures",id:"analyzing-failures",level:3},{value:"Cleaning things up",id:"cleaning-things-up",level:3}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"guide-setting-up-openstack-health-monitor-on-debian-12",children:"Guide: Setting up openstack-health-monitor on Debian 12"})}),"\n",(0,s.jsx)(n.p,{children:"Kurt Garloff, 2024-02-20"}),"\n",(0,s.jsx)(n.h2,{id:"intro",children:"Intro"}),"\n",(0,s.jsxs)(n.p,{children:["The development of ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/",children:"openstack-health-monitor"})," was done on ",(0,s.jsx)(n.a,{href:"https://kfg.images.obs-website.eu-de.otc.t-systems.com/",children:"openSUSE 15.x images"}),", just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution."]}),"\n",(0,s.jsx)(n.p,{children:"Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here."}),"\n",(0,s.jsxs)(n.p,{children:["Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor",children:"successor project"})," for the increasingly hard to maintain shell code, this may not be worth the trouble."]}),"\n",(0,s.jsxs)(n.p,{children:["openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested.\nThe scenario is described in a bit more detail in the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"repository's README.md"})," file."]}),"\n",(0,s.jsxs)(n.p,{children:["The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/docs/category/monitoring",children:"monitoring section"})," of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up."]}),"\n",(0,s.jsx)(n.h2,{id:"setting-up-the-driver-vm",children:"Setting up the driver VM"}),"\n",(0,s.jsxs)(n.p,{children:["So we start a ",(0,s.jsx)(n.code,{children:"Debian 12"})," image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard;\nthe instructions use flavor names and image names from the SCS standards.\nFor many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack)."]}),"\n",(0,s.jsx)(n.h3,{id:"internal-vs-external-monitoring",children:"Internal vs external monitoring"}),"\n",(0,s.jsx)(n.p,{children:"There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor."}),"\n",(0,s.jsx)(n.p,{children:"The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems."}),"\n",(0,s.jsx)(n.h3,{id:"unprivileged-operation",children:"Unprivileged operation"}),"\n",(0,s.jsx)(n.p,{children:"Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own."}),"\n",(0,s.jsxs)(n.p,{children:["If ",(0,s.jsx)(n.code,{children:"openstack availability zone list --compute"})," fails for you without admin rights, please fix your openstack client, e.g. by applying the ",(0,s.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/openstack-health-monitor/main/docs/openstackclient-az-list-fallback-f3207bd.diff",children:"patch"})," I mentioned in ",(0,s.jsx)(n.a,{href:"https://storyboard.openstack.org/#!/story/2010989",children:"this issue"}),". (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Health-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)"]}),"\n",(0,s.jsx)(n.h3,{id:"driver-vm-via-openstack-cli",children:"Driver VM via openstack CLI"}),"\n",(0,s.jsxs)(n.p,{children:["The author prefers to setup the VM via ",(0,s.jsx)(n.code,{children:"openstack"})," CLI tooling. He has working entries for all clouds he uses in his ",(0,s.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})," and ",(0,s.jsx)(n.code,{children:"secure.yaml"})," and has exported the ",(0,s.jsx)(n.code,{children:"OS_CLOUD"})," environment variable to point to the cloud he is working on to set up the driver VM. The author uses the ",(0,s.jsx)(n.code,{children:"bash"})," shell. All of this of course could be scripted."]}),"\n",(0,s.jsx)(n.p,{children:"So here we go"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Create the network setup for a VM in a network ",(0,s.jsx)(n.code,{children:"oshm-network"})," with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network."]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"PUBLIC=$(openstack network list --external -f value -c Name)\nopenstack router create oshm-router\nopenstack router set --external-gateway $PUBLIC oshm-driver-router\nopenstack network create oshm-network\nopenstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet\nopenstack router add subnet oshm-router oshm-subnet\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsx)(n.li,{children:"Create a security group that allows ssh and ping access"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack security group create sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsx)(n.li,{children:"Being at it, we also create the security group for grafana"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack security group create grafana\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"To connect to the VM via ssh later, we create an SSH keypair"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key\nchmod og-r ~/.ssh/oshm-key.pem \n"})}),"\n",(0,s.jsxs)(n.p,{children:["Rather than creating a new key (and storing and protecting the private key), we could have passed ",(0,s.jsx)(n.code,{children:"--public-key"})," and used an existing keypair."]}),"\n",(0,s.jsxs)(n.ol,{start:"5",children:["\n",(0,s.jsx)(n.li,{children:"Look up Debian 12 image UUID."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"IMGUUID=$(openstack image list --name \"Debian 12\" -f value -c ID | tr -d '\\r')\necho $IMGUUID\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Sidenote: The ",(0,s.jsx)(n.code,{children:"tr"})," command is there to handle broken tooling that embeds a trailing ",(0,s.jsx)(n.code,{children:"\\r"})," in the output."]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsx)(n.li,{children:"Boot the driver VM"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing ",(0,s.jsx)(n.code,{children:"--block-device"}),". See ",(0,s.jsx)(n.a,{href:"https://scs.community/2023/08/21/diskless-flavors/",children:"diskless flavor blog article"}),". For flavors with local root disks, you could have used the ",(0,s.jsx)(n.code,{children:"--image $IMGUUID"})," parameter instead."]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:["Wait for it to boot (optional)\nYou can look at the boot log with ",(0,s.jsx)(n.code,{children:"openstack console log show oshm-driver"})," or connect to it via VNC at the URL given by ",(0,s.jsx)(n.code,{children:"openstack console url show oshm-driver"}),". You can of course also query openstack on the status ",(0,s.jsx)(n.code,{children:"openstack server list"})," or ",(0,s.jsx)(n.code,{children:"openstack server show oshm-driver"}),". You can also just create a simple loop:"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'declare -i ctr=0 RC=0\nwhile [ $ctr -le 120 ]; do\n STATUS="$(openstack server list --name oshm-driver -f value -c Status)"\n if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi \n if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi\n if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi\n sleep 2\n let ctr+=1\ndone\n# return $RC\nif [ $RC != 0 ]; then false; fi\n'})}),"\n",(0,s.jsxs)(n.ol,{start:"8",children:["\n",(0,s.jsx)(n.li,{children:"Attach a floating IP so it's reachable from the outside."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks | sed "s@^[^:]*:[^\']*\'\\([0-9\\.]*\\)\'.*\\$@\\1@")\nFIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)\necho $FIXEDIP $FIXEDPORT\nopenstack floating ip create --port $FIXEDPORT $PUBLIC\nFLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")\necho "Floating IP: $FLOATINGIP"\n'})}),"\n",(0,s.jsx)(n.p,{children:"Remember this floating IP address."}),"\n",(0,s.jsxs)(n.ol,{start:"9",children:["\n",(0,s.jsx)(n.li,{children:"Connect to it via ssh"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP\n"})}),"\n",(0,s.jsx)(n.p,{children:"On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"All the following commands are performed on the newly started driver VM."})}),"\n",(0,s.jsx)(n.h3,{id:"configuring-openstack-cli-on-the-driver-vm",children:"Configuring openstack CLI on the driver VM"}),"\n",(0,s.jsx)(n.p,{children:"We need to install the openstack client utilities."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"sudo apt-get update\nsudo apt-get install python3-openstackclient\nsudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Configure your cloud access in ",(0,s.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n interface: public\n identity-api-version: 3\n #region_name: REGION\n auth:\n auth_url: KEYSTONE_ENDPOINT\n project_id: PROJECT_UUID\n #alternatively project_name and project_domain_name\n user_domain_name: default\n # change to your real domain\n"})}),"\n",(0,s.jsxs)(n.p,{children:["and ",(0,s.jsx)(n.code,{children:"secure.yaml"})," (in the same directory)"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n auth:\n username: USERNAME\n password: PASSWORD\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"CLOUDNAME"})," can be freely chosen. This is the value passed to the openstack CLI with ",(0,s.jsx)(n.code,{children:"--os-cloud"})," or exported to your environment in ",(0,s.jsx)(n.code,{children:"OS_CLOUD"}),". The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample ",(0,s.jsx)(n.code,{children:"clouds.yaml"})," file that works (but lacks the password)."]}),"\n",(0,s.jsxs)(n.p,{children:["Protect your ",(0,s.jsx)(n.code,{children:"secure.yaml"})," from being read by others: ",(0,s.jsx)(n.code,{children:"chmod 0600 ~/.config/openstack/secure.yaml"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["If you are using application credentials instead of username, password to authenticate, you don't need to specify ",(0,s.jsx)(n.code,{children:"project_id"})," nor project's nor user's domain names in ",(0,s.jsx)(n.code,{children:"clouds.yaml"}),". Just (in ",(0,s.jsx)(n.code,{children:"secure.yaml"}),"):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'clouds:\n CLOUDNAME:\n auth_type: v3applicationcredential\n auth:\n application_credential_id: APPCRED_ID\n application_credential_secret: "APPCRED_SECRET"\n'})}),"\n",(0,s.jsx)(n.p,{children:"Configure this to be your default cloud:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"export OS_CLOUD=CLOUDNAME\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You might consider adding this to your ",(0,s.jsx)(n.code,{children:"~/.bashrc"})," for convenience. Being at it, you might want to add ",(0,s.jsx)(n.code,{children:"export CLIFF_FIT_WIDTH=1"})," there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste)."]}),"\n",(0,s.jsx)(n.p,{children:"Verify that your openstack CLI works:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack catalog list\nopenstack server list\n"})}),"\n",(0,s.jsx)(n.p,{children:"You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases."}),"\n",(0,s.jsx)(n.h3,{id:"custom-ca",children:"Custom CA"}),"\n",(0,s.jsxs)(n.p,{children:["If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in ",(0,s.jsx)(n.code,{children:"/etc/ssl/certs/ca-certificates.crt"}),". You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the ",(0,s.jsx)(n.code,{children:"debian"})," user."]}),"\n",(0,s.jsxs)(n.p,{children:["Add it to your ",(0,s.jsx)(n.code,{children:"clouds.yaml"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n cacert: /PATH/TO/CACERT.CRT\n [...]\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If you want to allow ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"export OS_CACERT=/PATH/TO/CACERT.CRT\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Consider adding this to your ",(0,s.jsx)(n.code,{children:"~/.bashrc"})," as well."]}),"\n",(0,s.jsxs)(n.h2,{id:"your-first-api_monitorsh-iteration",children:["Your first ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," iteration"]}),"\n",(0,s.jsx)(n.p,{children:"Checkout openstack-health-monitor:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install git bc jq netcat-traditional tmux zstd\ngit clone https://github.com/SovereignCloudStack/openstack-health-monitor\ncd openstack-health-monitor\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You may want to start a ",(0,s.jsx)(n.code,{children:"tmux"})," (or ",(0,s.jsx)(n.code,{children:"screen"}),") session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect."]}),"\n",(0,s.jsxs)(n.p,{children:["The script ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"})," file."]}),"\n",(0,s.jsxs)(n.p,{children:["It is good practice to use ",(0,s.jsx)(n.code,{children:"tmux"}),". This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to ",(0,s.jsx)(n.code,{children:"screen"})," over ",(0,s.jsx)(n.code,{children:"tmux"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'export IMG="Debian 12"\nexport JHIMG="Debian 12"\n./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Leave out the ",(0,s.jsx)(n.code,{children:"-LL"})," if you don't have a working loadbalancer service or replace ",(0,s.jsx)(n.code,{children:"-LL"})," with ",(0,s.jsx)(n.code,{children:"-LO"})," if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources)."]}),"\n",(0,s.jsxs)(n.p,{children:["Feel free to study the meaning of all the command line parameters by looking at the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"}),". (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)"]}),"\n",(0,s.jsxs)(n.p,{children:["This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs ",(0,s.jsx)(n.code,{children:"DOWN"}),", ",(0,s.jsx)(n.code,{children:"BUILD"}),", ",(0,s.jsx)(n.code,{children:"creating"})," are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual ",(0,s.jsx)(n.code,{children:"openstack RESOURCE list"})," and ",(0,s.jsx)(n.code,{children:"openstack RESOURCE show NAME"})," and ",(0,s.jsx)(n.code,{children:"RESOURCE"})," being something like ",(0,s.jsx)(n.code,{children:"router"}),", ",(0,s.jsx)(n.code,{children:"network"}),", ",(0,s.jsx)(n.code,{children:"subnet"}),", ",(0,s.jsx)(n.code,{children:"port"}),", ",(0,s.jsx)(n.code,{children:"volume"}),", ",(0,s.jsx)(n.code,{children:"server"}),", ",(0,s.jsx)(n.code,{children:"floating ip"}),", ",(0,s.jsx)(n.code,{children:"loadbalancer"}),", ",(0,s.jsx)(n.code,{children:"loadbalancer pool"}),", ",(0,s.jsx)(n.code,{children:"loadbalancer listener"}),", ",(0,s.jsx)(n.code,{children:"security group"}),", ",(0,s.jsx)(n.code,{children:"keypair"}),", ",(0,s.jsx)(n.code,{children:"image"}),", ...)"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," uses and ",(0,s.jsx)(n.code,{children:"APIMonitor_TIMESTAMP"})," prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong.\n",(0,s.jsx)(n.code,{children:"TIMESTAMP"})," is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time)."]}),"\n",(0,s.jsxs)(n.p,{children:["This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least ",(0,s.jsx)(n.code,{children:"-N 2"})," to test the ability of the router to route traffic between networks. So expect ",(0,s.jsx)(n.code,{children:"-n 6"})," to become ",(0,s.jsx)(n.code,{children:"-N 2 -n 6"})," for a very small single-AZ cloud or ",(0,s.jsx)(n.code,{children:"-n 12"})," for a large 3 AZ cloud region. So, re-run the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," with the target sizing."]}),"\n",(0,s.jsx)(n.h3,{id:"resource-impact-and-charging",children:"Resource impact and charging"}),"\n",(0,s.jsxs)(n.p,{children:["Note that ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," uses small flavors (",(0,s.jsx)(n.code,{children:"SCS-1V-2"})," for the N jump hosts and ",(0,s.jsx)(n.code,{children:"SCS-1L-1"})," for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors."]}),"\n",(0,s.jsxs)(n.p,{children:["If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," in a loop (which you will) with say 10 VMs (e.g. ",(0,s.jsx)(n.code,{children:"-N 2 -n 8"}),") in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference."]}),"\n",(0,s.jsxs)(n.p,{children:["Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of ",(0,s.jsx)(n.code,{children:"openstack volume list"}),", ",(0,s.jsx)(n.code,{children:"openstack volume show BROKEN_VOLUME"}),", ",(0,s.jsx)(n.code,{children:"openstack loadbalancer list"}),", ",(0,s.jsx)(n.code,{children:"openstack loadbalancer show BROKEN_LB"}),".)"]}),"\n",(0,s.jsxs)(n.p,{children:["Using ",(0,s.jsx)(n.code,{children:"-w -1"})," makes ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," wait for interactive input whenever an error occurs; this can be convenient for debugging."]}),"\n",(0,s.jsx)(n.p,{children:"Once you have single iterations working nicely, we can proceed."}),"\n",(0,s.jsx)(n.h2,{id:"automating-startup-and-cleanup",children:"Automating startup and cleanup"}),"\n",(0,s.jsxs)(n.p,{children:["Typically, we run ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'#!/bin/bash\n# run_CLOUDNAME.sh\n# Do some global settings\nexport IMG="Debian 12"\nexport JHIMG="Debian 12"\n#export OS_CACERT=/home/debian/ca-certificates.pem\n# Additional settings to override flavors or to\n# configure email addresses for sending alarms can be set here\n\n# Does openstack CLI work?\nopenstack server list >/dev/null || exit 1\n# Upload log files to this swift container (which you need to create)\n#export SWIFTCONTAINER=OS-HM-Logfiles\n\n# CLEANUP\necho "Finding resources from previous runs to clean up ..."\n# Find Floating IPs\nFIPLIST=""\nFIPS=$(openstack floating ip list -f value -c ID)\nfor fip in $FIPS; do\n FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")\n if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_\n"; fi\ndone\nFIPLIST=$(echo "$FIPLIST" | grep -v \'^$\' | sort -u)\n# Cleanup previous interrupted runs\nSERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nKEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nVOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nNETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nLOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nSECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)\necho CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS\nfor ENV in $FIPLIST; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV\n echo "******************************"\ndone\nTOCLEAN=$(echo "$SERVERS\n$KEYPAIR\n$VOLUMES\n$NETWORK\n$LOADBAL\n$ROUTERS\n$SECGRPS\n" | grep -v \'^$\' | sort -u)\nfor ENV in $TOCLEAN; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV\n echo "******************************"\ndone\n\n# Now run the monitor\n#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"\nexec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Compared to the previous run, we have explicitly set two networks here ",(0,s.jsx)(n.code,{children:"-N 2"})," and rely on the iterations being passed in as command line arguments. Add parameter ",(0,s.jsx)(n.code,{children:"-t"})," if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (",(0,s.jsx)(n.code,{children:"-LO"}),") in this example rather than the amphora based one (",(0,s.jsx)(n.code,{children:"-LL"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["You may use one of the existing ",(0,s.jsx)(n.code,{children:"run_XXXX.sh"})," scripts as example. Beware: eMail alerting with ",(0,s.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESS"})," and ",(0,s.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESS"})," (and limiting with ",(0,s.jsx)(n.code,{children:"-a"})," and ",(0,s.jsx)(n.code,{children:"-R"})," ) and reporting data to telegraf (option ",(0,s.jsx)(n.code,{children:"-S"}),") may be present in the samples. Make this script executable (",(0,s.jsx)(n.code,{children:"chmod +x run_CLOUDNAME.sh"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["We wrap a loop around this in ",(0,s.jsx)(n.code,{children:"run_in_loop.sh"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'#!/bin/bash\n# run_in_loop.sh\nrm stop-os-hm 2>/dev/null\nwhile true; do\n ./run_CLOUDNAME.sh -i 200\n if test -e stop-os-hm; then break; fi\n echo -n "Hit ^C to abort ..."\n sleep 15; echo\ndone\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Also make this executable (",(0,s.jsx)(n.code,{children:"chmod +x run_in_loop.sh"}),").\nTo run this automatically in a tmux window whenever the system starts, we follow the steps in the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/startup/README.md",children:"startup README.md"})]}),"\n",(0,s.jsxs)(n.p,{children:["Change ",(0,s.jsx)(n.code,{children:"OS_CLOUD"})," in ",(0,s.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"}),". (If you need to set ",(0,s.jsx)(n.code,{children:"OS_CACERT"}),", also add it in this file and pass it into the windows.)"]}),"\n",(0,s.jsx)(n.p,{children:"Activate everything:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"mkdir -p ~/.config/systemd/user/\ncp -p startup/apimon.service ~/.config/systemd/user/\nsystemctl --user enable apimon\nsystemctl --user start apimon\nsudo loginctl enable-linger debian\ntmux attach -t oshealthmon\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This assumes that you are using the user ",(0,s.jsx)(n.code,{children:"debian"})," for this monitoring and have checked out the repository at ",(0,s.jsx)(n.code,{children:"~/openstack-health-monitor/"}),". Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)"]}),"\n",(0,s.jsx)(n.h3,{id:"changing-parameters-and-restarting",children:"Changing parameters and restarting"}),"\n",(0,s.jsxs)(n.p,{children:["If you want to change the parameters passed to ",(0,s.jsx)(n.code,{children:"api_monitor.sh"}),", you best do this by editing ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),", potentially after testing it with one iteration before."]}),"\n",(0,s.jsxs)(n.p,{children:["To make the change effective, you can wait until the current 200 iterations are completed and the ",(0,s.jsx)(n.code,{children:"run_in_loop.sh"})," calls ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," again. You can also hit ",(0,s.jsx)(n.code,{children:"^C"})," in the tmux window that has",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ",(0,s.jsx)(n.code,{children:"^C"})," during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ",(0,s.jsx)(n.code,{children:"^C"})," twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ",(0,s.jsx)(n.code,{children:"./run_in_loop.sh"})," again."]}),"\n",(0,s.jsxs)(n.p,{children:["You can also issue the ",(0,s.jsx)(n.code,{children:"systemctl --user stop apimon"})," command; it will basically do the same thing: Send ",(0,s.jsx)(n.code,{children:"^C"})," and then wait for everything to be completed and tear down the tmux session.\nAfter waiting for that to complete, you can start it again with ",(0,s.jsx)(n.code,{children:"systemctl --user start apimon"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"multiple-instances",children:"Multiple instances"}),"\n",(0,s.jsxs)(n.p,{children:["You can run multiple instances of ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," on the same driver VM. In this case, you should rename ",(0,s.jsx)(n.code,{children:"run_in_loop.sh"})," to e.g. ",(0,s.jsx)(n.code,{children:"run_in_loop_CLOUDNAME1.sh"})," and call ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME1.sh"})," from there. Don't forget to adjust ",(0,s.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"})," and ",(0,s.jsx)(n.code,{children:"startup/kill-apimon-in-tmux.sh"})," to start more windows."]}),"\n",(0,s.jsxs)(n.p,{children:["It is not recommended to run multiple instances against the same OpenStack project however. While the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations."]}),"\n",(0,s.jsx)(n.h2,{id:"alarming-and-logs",children:"Alarming and Logs"}),"\n",(0,s.jsx)(n.h3,{id:"email",children:"eMail"}),"\n",(0,s.jsxs)(n.p,{children:["If wanted, the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the ",(0,s.jsx)(n.code,{children:"-a N"})," and ",(0,s.jsx)(n.code,{children:"-R"})," options. In order to enable sending emails from the driver VM, it needs to have ",(0,s.jsx)(n.code,{children:"postfix"})," (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly."]}),"\n",(0,s.jsxs)(n.p,{children:["Once you have configured ",(0,s.jsx)(n.code,{children:"postfix"}),", you can enable eMail notifications using the option ",(0,s.jsx)(n.code,{children:"-e"}),". Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ",(0,s.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESSES"})," and ",(0,s.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESSES"})," environment variables to ",(0,s.jsx)(n.code,{children:"api_monitor.sh"}),", e.g. by setting it in the ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"log-files",children:"Log files"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"api_monitor.sh"})," writes a log file with the name ",(0,s.jsx)(n.code,{children:"APIMonitor_TIMESTAMP.log"}),". It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (",(0,s.jsx)(n.code,{children:"TIMESTAMP"})," is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)"]}),"\n",(0,s.jsxs)(n.p,{children:["Note that ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties."]}),"\n",(0,s.jsxs)(n.p,{children:["The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable ",(0,s.jsx)(n.code,{children:"SWIFTCONTAINER"})," has been set (in ",(0,s.jsx)(n.code,{children:"run_COULDNAME.sh"}),") when starting ",(0,s.jsx)(n.code,{children:"api_monitor.sh"}),". the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: ",(0,s.jsx)(n.code,{children:"export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER"})]}),"\n",(0,s.jsxs)(n.p,{children:["After the 200 iterations, a ",(0,s.jsx)(n.code,{children:".psv"})," file (pipe-separated values) is created ",(0,s.jsx)(n.code,{children:"Stats.STARTTIME-ENDTIME.psv"})," (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured)."]}),"\n",(0,s.jsx)(n.h2,{id:"data-collection-and-dashboard",children:"Data collection and dashboard"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md",children:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md"})]}),"\n",(0,s.jsx)(n.h3,{id:"telegraf",children:"Telegraf"}),"\n",(0,s.jsx)(n.p,{children:"To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key\necho "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list\nsudo apt update\nsudo apt -y install telegraf\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the config file ",(0,s.jsx)(n.code,{children:"/etc/telegraf/telegraf.conf"}),", we enable"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:'[[inputs.influxdb_listener]]\n service_address = ":8186"\n\n[[outputs.influxdb]]\n urls = ["http://127.0.0.1:8086"]\n'})}),"\n",(0,s.jsxs)(n.p,{children:["and restart the service (",(0,s.jsx)(n.code,{children:"sudo systemctl restart telegraf"}),").\nEnable it on system startup: ",(0,s.jsx)(n.code,{children:"sudo systemctl enable telegraf"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"influxdb",children:"InfluxDB"}),"\n",(0,s.jsx)(n.p,{children:"We proceed to influxdb:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo apt-get install influxdb\n"})}),"\n",(0,s.jsxs)(n.p,{children:["In the configuration file ",(0,s.jsx)(n.code,{children:"/etc/influxdb/influxdb.conf"}),", ensure that the http interface on port 8086 is enabled."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:'[http]\n enabled = true\n bind-address = ":8086"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Restart influxdb as needed with ",(0,s.jsx)(n.code,{children:"sudo systemctl restart influxdb"}),".\nAlso enable it on system startup: ",(0,s.jsx)(n.code,{children:"sudo systemctl enable influxdb"}),"."]}),"\n",(0,s.jsxs)(n.h3,{id:"add--s-cloudname-to-your-run_cloudnamesh-script",children:["Add ",(0,s.jsx)(n.code,{children:"-S CLOUDNAME"})," to your ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script"]}),"\n",(0,s.jsxs)(n.p,{children:["You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter ",(0,s.jsx)(n.code,{children:"-S CLOUDNAME"})," to the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," call in ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),". Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete)."]}),"\n",(0,s.jsx)(n.h3,{id:"caddy-reverse-proxy",children:"Caddy (Reverse Proxy)"}),"\n",(0,s.jsxs)(n.p,{children:["We're going to deploy Grafana behind ",(0,s.jsx)(n.a,{href:"https://caddyserver.com/docs/",children:"Caddy"})," as a reverse proxy.\nCaddy is very easy to configure, comes with sensible defaults and can automatically provision TLS\ncertificates using Let's Encrypt."]}),"\n",(0,s.jsx)(n.h4,{id:"install-caddy",children:"Install Caddy"}),"\n",(0,s.jsxs)(n.p,{children:["We follow ",(0,s.jsx)(n.a,{href:"https://caddyserver.com/docs/install#debian-ubuntu-raspbian",children:"https://caddyserver.com/docs/install#debian-ubuntu-raspbian"})," to setup the stable APT repository:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl\ncurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg\ncurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list\n"})}),"\n",(0,s.jsx)(n.p,{children:"And install Caddy:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo apt update\nsudo apt install caddy\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Ensure it's started and starts at boot with ",(0,s.jsx)(n.code,{children:"sudo systemctl enable --now caddy"}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"allow-http-traffic-for-oshm-driver",children:"Allow HTTP traffic for oshm-driver"}),"\n",(0,s.jsxs)(n.p,{children:["Caddy needs TCP port ",(0,s.jsx)(n.code,{children:"80"})," opened to be able to process the Let's Encrypt HTTP challenge, so let's\nconfigure an appropriate security group for ",(0,s.jsx)(n.code,{children:"oshm-driver"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"openstack security group create http\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 80 http\nopenstack server add security group oshm-driver http\n"})}),"\n",(0,s.jsx)(n.h4,{id:"configure-caddy",children:"Configure Caddy"}),"\n",(0,s.jsxs)(n.p,{children:["Create a file ",(0,s.jsx)(n.code,{children:"/etc/caddy/Caddyfile"})," with the following contents:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"https://health.YOURCLOUD.osba.sovereignit.cloud:3000 {\n\treverse_proxy localhost:3003\n}\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Replace ",(0,s.jsx)(n.code,{children:"health.YOURCLOUD.osba.sovereignit.cloud"})," with your actual domain.\nYou can use a hostname of your liking, but Caddy will create TLS certificates for this host using\nthe HTTP challenge.\nThe ",(0,s.jsx)(n.code,{children:"sovereignit.cloud"})," domain is controlled by the SCS project team and has been used for a number\nof health mon instances."]}),"\n",(0,s.jsxs)(n.p,{children:["Reload Caddy with ",(0,s.jsx)(n.code,{children:"sudo systemctl reload caddy"}),". That's it."]}),"\n",(0,s.jsxs)(n.p,{children:["You should now be able to access ",(0,s.jsx)(n.code,{children:"https://health.YOURCLOUD.sovereignit.cloud:3000"})," and see a proxy error\npage because the Grafana service is not yet running (this is our next step).\nThe very first request will be a bit slower, because Caddy interacts with Let's Encrypt API to create\nthe TLS certificate behind the scenes."]}),"\n",(0,s.jsxs)(n.p,{children:["Caddy logs can be accessed with ",(0,s.jsx)(n.code,{children:"sudo journalctl -u caddy"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"grafana",children:"Grafana"}),"\n",(0,s.jsx)(n.h4,{id:"install-grafana",children:"Install Grafana"}),"\n",(0,s.jsxs)(n.p,{children:["We follow ",(0,s.jsx)(n.a,{href:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/",children:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/"})," and setup the stable APT repository:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'mkdir -p /etc/apt/keyrings\nwget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null\necho "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list\n'})}),"\n",(0,s.jsx)(n.p,{children:"And install it:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo apt update\nsudo apt -y install grafana\n"})}),"\n",(0,s.jsx)(n.h4,{id:"basic-config",children:"Basic config"}),"\n",(0,s.jsxs)(n.p,{children:["The config file ",(0,s.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," needs some adjustments."]}),"\n",(0,s.jsx)(n.p,{children:"We're going to deploy Grafana behind a reverse proxy (Caddy) and configure it as such."}),"\n",(0,s.jsxs)(n.p,{children:["Therefore, in the ",(0,s.jsx)(n.code,{children:"[server]"})," section:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[server]\nprotocol = http\nhttp_addr = 127.0.0.1\nhttp_port = 3003\ndomain = health.YOURCLOUD.sovereignit.cloud\nroot_url = https://%(domain)s:3000/\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Please replace ",(0,s.jsx)(n.code,{children:"health.YOURCLOUD.sovereignit.cloud"})," with your actual domain."]}),"\n",(0,s.jsxs)(n.p,{children:["Next, in the ",(0,s.jsx)(n.code,{children:"[security]"})," section, set:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[security]\nadmin_user = admin\nadmin_password = SOME_SECRET_PASS\nsecret_key = SOME_SECRET_KEY\ndata_source_proxy_whitelist = localhost:8088 localhost:8086\ncookie_secure = true\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Please replace ",(0,s.jsx)(n.code,{children:"SOME_SECRET_PASS"})," and ",(0,s.jsx)(n.code,{children:"SOME_SECRET_KEY"})," with secure passwords (for example, you can use ",(0,s.jsx)(n.code,{children:"pwgen -s 20"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["Finally, in the ",(0,s.jsx)(n.code,{children:"[users]"})," section, set:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[users]\nallow_sign_up = false\nallow_org_create = false\n"})}),"\n",(0,s.jsx)(n.p,{children:"The configuration file contains secrets and should be protected such that only root and group grafana\ncan read it:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"sudo chown root:grafana /etc/grafana/grafana.ini\nsudo chmod 0640 /etc/grafana/grafana.ini\n"})}),"\n",(0,s.jsxs)(n.p,{children:["We do the OIDC connection in the section ",(0,s.jsx)(n.code,{children:"[auth.github]"})," ",(0,s.jsx)(n.a,{href:"#github-oidc-integration",children:"later"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["We can now restart the service: ",(0,s.jsx)(n.code,{children:"sudo systemctl restart grafana-server"}),".\nBeing at it, also enable it on system startup: ",(0,s.jsx)(n.code,{children:"sudo systemctl enable grafana-server"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You should now be able to access your dashboard on ",(0,s.jsx)(n.code,{children:"https://health.YOURCLOUD.sovereignit.cloud:3000"})," and log in\nvia the configured username ",(0,s.jsx)(n.code,{children:"admin"})," and your ",(0,s.jsx)(n.code,{children:"SOME_SECRET_PASS"})," password."]}),"\n",(0,s.jsx)(n.h4,{id:"enable-influx-database-in-grafana",children:"Enable influx database in grafana"}),"\n",(0,s.jsxs)(n.p,{children:["In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to ",(0,s.jsx)(n.code,{children:"http://localhost:8086"})," (despite this being the suggestion). Set the database name to ",(0,s.jsx)(n.code,{children:"telegraf"}),". Save&test should succeed."]}),"\n",(0,s.jsx)(n.h4,{id:"importing-the-dashboard",children:"Importing the dashboard"}),"\n",(0,s.jsxs)(n.p,{children:["Go to Home, Dashboards, New, Import.\nUpload the dashboard ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard.json",children:".json file"})," from the repository, user the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard-10.json",children:"Grafana-10 variant"})," if you use Grafana 10 or newer."]}),"\n",(0,s.jsx)(n.p,{children:"In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.)\nSave."}),"\n",(0,s.jsx)(n.p,{children:"Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable)."}),"\n",(0,s.jsx)(n.h4,{id:"no-data-displayed",children:"No data displayed?"}),"\n",(0,s.jsx)(n.p,{children:'Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.'}),"\n",(0,s.jsx)(n.p,{children:"One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved."}),"\n",(0,s.jsx)(n.h4,{id:"dashboard-features",children:"Dashboard features"}),"\n",(0,s.jsx)(n.p,{children:"Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended."}),"\n",(0,s.jsx)(n.p,{children:"The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously."}),"\n",(0,s.jsx)(n.p,{children:"You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term."}),"\n",(0,s.jsx)(n.h4,{id:"github-oidc-integration",children:"GitHub OIDC Integration"}),"\n",(0,s.jsx)(n.p,{children:"The SCS providers do allow all GitHub users that belong to the SovereignCloudStack organization to get Viewer\naccess to the dashboards.\nThis allows to exchange experience and to get a feeling for the achievable stability.\n(Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)"}),"\n",(0,s.jsxs)(n.p,{children:["OIDC integration is achieved by adjusting the ",(0,s.jsx)(n.code,{children:"[auth.github]"})," section in ",(0,s.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," as follows:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:'[auth.github]\nenabled = true\nclient_id = YOUR_CLIENT_ID\nclient_secret = YOUR_CLIENT_SECRET\nallowed_organizations = ["SovereignCloudStack"]\nrole_attribute_path = "\'Viewer\'"\nallow_assign_grafana_admin = false\nskip_org_role_sync = true\n'})}),"\n",(0,s.jsxs)(n.p,{children:["This config maps all users to the ",(0,s.jsx)(n.code,{children:"Viewer"})," role regardless of their role in the GitHub Org.\nPlease replace ",(0,s.jsx)(n.code,{children:"YOUR_CLIENT_ID"})," and ",(0,s.jsx)(n.code,{children:"YOUR_CLIENT_SECRET"})," with the OAuth2 credentials that the SCS Org GitHub admins\nprovided to you.\nFinally, don't forgot to restart Grafana with ",(0,s.jsx)(n.code,{children:"sudo systemctl restart grafana-server"})," after adjusting the config."]}),"\n",(0,s.jsxs)(n.p,{children:["More information can be found in the ",(0,s.jsx)(n.a,{href:"https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/github/",children:"Grafana documentation for GitHub OAuth2"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"maintenance",children:"Maintenance"}),"\n",(0,s.jsx)(n.p,{children:"The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained."}),"\n",(0,s.jsx)(n.h3,{id:"unattended-upgrades",children:"Unattended upgrades"}),"\n",(0,s.jsxs)(n.p,{children:["It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See ",(0,s.jsx)(n.a,{href:"https://wiki.debian.org/UnattendedUpgrades",children:"https://wiki.debian.org/UnattendedUpgrades"}),". If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and Caddy/Grafana (port 3000)."]}),"\n",(0,s.jsxs)(n.p,{children:["If you use ",(0,s.jsx)(n.code,{children:"unattended-upgrades"}),", you should review your settings in ",(0,s.jsx)(n.code,{children:"/etc/apt/apt.conf.d/50unattended-upgrades"}),",\nespecially ",(0,s.jsx)(n.code,{children:"Unattended-Upgrade::Origins-Pattern"}),". It controls which packages are upgraded. If you want Caddy to be\npart of the automated updates, add an entry like the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'Unattended-Upgrade::Origins-Pattern {\n // ...\n "origin=cloudsmith/caddy/stable";\n};\n'})}),"\n",(0,s.jsxs)(n.p,{children:["(This corresponds to ",(0,s.jsx)(n.code,{children:"o=cloudsmith/caddy/stable"})," in the output of ",(0,s.jsx)(n.code,{children:"apt-cache policy"}),")."]}),"\n",(0,s.jsx)(n.h3,{id:"sshd-setup",children:"sshd setup"}),"\n",(0,s.jsxs)(n.p,{children:["If you already use SSH keys to sign in to the driver VM, consider setting the following in your ",(0,s.jsx)(n.code,{children:"/etc/ssh/sshd_config"}),"\nif not already set:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"PasswordAuthentication no\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Debian's ",(0,s.jsx)(n.code,{children:"openssh-server"}),", by default, is also very open about its version, so you might consider disabling this via:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"DebianBanner no\n"})}),"\n",(0,s.jsx)(n.h3,{id:"updating-openstack-health-monitor",children:"Updating openstack-health-monitor"}),"\n",(0,s.jsxs)(n.p,{children:["You can just do a ",(0,s.jsx)(n.code,{children:"git update"})," in the ",(0,s.jsx)(n.code,{children:"openstack-health-monitor"})," directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ",(0,s.jsx)(n.code,{children:"^C"}),", see above in the restart section."]}),"\n",(0,s.jsx)(n.h3,{id:"backup",children:"Backup"}),"\n",(0,s.jsxs)(n.p,{children:["The system holds two things that you might consider valuable for long-term storage:\n(1) The log files. These are compressed and uploaded to object storage if you enable the ",(0,s.jsx)(n.code,{children:"SWIFTCONTAINER"})," setting, which probably means that these do not need any additional backing up then.\n(2) The influx time series data. Back up the data in ",(0,s.jsx)(n.code,{children:"/var/lib/influxdb"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, ",(0,s.jsx)(n.code,{children:"clouds.yaml"}),", etc. Be careful not to expose sensitive data by granting too generous access to your backed up files."]}),"\n",(0,s.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,s.jsx)(n.h3,{id:"debugging-issues",children:"Debugging issues"}),"\n",(0,s.jsx)(n.p,{children:"In case there is trouble with your cloud, the normal course of action to analyze is as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Look at the dashboard (see above)"}),"\n",(0,s.jsxs)(n.li,{children:["Connect to the driver VM and attach to the tmux session and look at the console output of ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})]}),"\n",(0,s.jsx)(n.li,{children:"Analyze the logfile (locally on the driver VM or grab it from the object storage)"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"analyzing-failures",children:"Analyzing failures"}),"\n",(0,s.jsxs)(n.p,{children:["When VM instances are created successfully, but then end up in ",(0,s.jsx)(n.code,{children:"ERROR"})," state, the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," does an explicit ",(0,s.jsx)(n.code,{children:"openstack server show"}),", so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files."]}),"\n",(0,s.jsxs)(n.p,{children:["Sometimes the VMs end up being ",(0,s.jsx)(n.code,{children:"ACTIVE"})," as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail."]}),"\n",(0,s.jsxs)(n.p,{children:["To gather more details, you can look at the console output ",(0,s.jsx)(n.code,{children:"openstack console log show VM"})," (where ",(0,s.jsx)(n.code,{children:"VM"})," is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ",(0,s.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_JH.pem debian@FIP"}),", whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ",(0,s.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP"}),". Replace ",(0,s.jsx)(n.code,{children:"XXXXX"})," with the number in your current APIMonitor prefix, ",(0,s.jsx)(n.code,{children:"FIP"})," with the floating IP address of the responsible JumpHost and ",(0,s.jsx)(n.code,{children:"debian"})," with the user name used by the images you boot. Use ",(0,s.jsx)(n.code,{children:"223"})," to connect to the second VM in the network, ",(0,s.jsx)(n.code,{children:"224"})," the third etc."]}),"\n",(0,s.jsxs)(n.p,{children:["When logged in, look at ",(0,s.jsx)(n.code,{children:"/var/log/cloud-init-output.log"})," and ",(0,s.jsx)(n.code,{children:"/var/log/cloud-init.log"}),". You can find the metadata in ",(0,s.jsx)(n.code,{children:"/var/lib/cloud/instance/"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You will not have much time to look around -- the still running ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," script does continue and clean things up again. So you might want to suspend it with ",(0,s.jsx)(n.code,{children:"^Z"})," (and continue it later with ",(0,s.jsx)(n.code,{children:"fg"}),"). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the ",(0,s.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script as it would do cleanup against the running instance, but rather copy the ",(0,s.jsx)(n.code,{children:"api_monitor.sh"})," command line from the bottom (without the ",(0,s.jsx)(n.code,{children:"exec"}),"), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach ",(0,s.jsx)(n.code,{children:"-w -1"})," to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work."]}),"\n",(0,s.jsx)(n.h3,{id:"cleaning-things-up",children:"Cleaning things up"}),"\n",(0,s.jsx)(n.p,{children:"If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard)."}),"\n",(0,s.jsx)(n.p,{children:"There are a few things that may need support from a cloud admin:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Volumes may end up permanently in a ",(0,s.jsx)(n.code,{children:"deleting"})," or ",(0,s.jsx)(n.code,{children:"reserved"})," state or may be ",(0,s.jsx)(n.code,{children:"in-use"}),", attached to a VM that has long gone. The admin needs to set the state to ",(0,s.jsx)(n.code,{children:"error"})," and then delete them."]}),"\n",(0,s.jsxs)(n.li,{children:["Loadbalancers may end up in a ",(0,s.jsx)(n.code,{children:"PENDING_XXX"})," state (",(0,s.jsx)(n.code,{children:"XXX"})," being ",(0,s.jsx)(n.code,{children:"CREATE"}),", ",(0,s.jsx)(n.code,{children:"UPDATE"})," or ",(0,s.jsx)(n.code,{children:"DELETE"}),") without ever changing. This also needs the cloud admin to set the status to ",(0,s.jsx)(n.code,{children:"ERROR"}),", so it can be cleaned up. amphorae are more prone to this than ovn LBs."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted."})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var o=t(96540);const s={},a=o.createContext(s);function i(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b262b314.6d6c1d38.js b/assets/js/b262b314.6d6c1d38.js new file mode 100644 index 0000000000..00e84b33fe --- /dev/null +++ b/assets/js/b262b314.6d6c1d38.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[53681],{66720:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"scs-0216-v1-requirements-for-testing-cluster-stacks","title":"Requirements for testing cluster-stacks","description":"Introduction","source":"@site/standards/scs-0216-v1-requirements-for-testing-cluster-stacks.md","sourceDirName":".","slug":"/scs-0216-v1-requirements-for-testing-cluster-stacks","permalink":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Requirements for testing cluster-stacks","type":"Decision Record","status":"Draft","track":"KaaS"},"sidebar":"standards","previous":{"title":"scs-0216: Requirements for testing cluster-stacks","permalink":"/standards/kaas/scs-0216"},"next":{"title":"scs-0217: Kubernetes cluster hardening","permalink":"/standards/kaas/scs-0217"}}');var s=i(74848),o=i(28453);const r={title:"Requirements for testing cluster-stacks",type:"Decision Record",status:"Draft",track:"KaaS"},a=void 0,l={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Required Features",id:"required-features",level:2},{value:"Pros and Cons of Different Approaches",id:"pros-and-cons-of-different-approaches",level:2},{value:"IaaS Provider (OpenStack, Hetzner, AWS)",id:"iaas-provider-openstack-hetzner-aws",level:3},{value:"Pros",id:"pros",level:4},{value:"Cons",id:"cons",level:4},{value:"Local Environment (Docker, KubeVirt)",id:"local-environment-docker-kubevirt",level:3},{value:"Pros",id:"pros-1",level:4},{value:"Cons",id:"cons-1",level:4},{value:"Beyond Docker: Virtual Machine based Approach",id:"beyond-docker-virtual-machine-based-approach",level:2},{value:"Virtual Machine Based Approach",id:"virtual-machine-based-approach",level:3},{value:"Pros",id:"pros-2",level:4},{value:"Cons",id:"cons-2",level:4},{value:"Proposed Path Forward",id:"proposed-path-forward",level:2},{value:"Conclusion",id:"conclusion",level:2}];function d(e){const n={h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"In this proposal, we discuss the necessity and design considerations of a lightweight solution for testing cluster-stacks. The purpose is to address the challenges associated with testing on an Infrastructure as a Service (IaaS) provider and the limitations of using Docker as the primary containerization tool for testing. This proposal will elaborate on why we need to test in a local environment, specifically a laptop, and the benefits and drawbacks associated with it. We aim to make an informed decision for testing cluster stacks to cater to both the organizational and technical perspectives of our stakeholders."}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(n.p,{children:"From an organization's point of view, it is crucial to lower the entry barrier for testing. This action will make it possible for anyone, including external contributors, to easily participate in the testing process without needing an account with the IaaS provider. It is also necessary to overcome the hurdles associated with maintaining a balance in the provider account and managing sponsorships to fund the testing."}),"\n",(0,s.jsx)(n.p,{children:"From a technical standpoint, there are multiple reasons to favor a local environment for testing. Among them is the ability to test without internet, finish tests in a shorter timeframe, and incur no cost. The provider independence of Cluster Stacks makes it nonsensical to test with a specific provider due to the varied behaviors of different providers. There are also challenges in monitoring and debugging tests run on IaaS providers and dealing with their downtime and limitations on concurrent testing."}),"\n",(0,s.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Lightweight Solution"}),"\nThe testing solution should be lightweight and easy to use in a local environment, such as a laptop. This lightweight solution should minimize dependencies and resource usage while maximizing speed and efficiency of the tests. It should be capable of handling the cluster-stack testing requirements without necessitating a bulky or resource-intensive setup."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Independence from Specific Providers"}),"\nThe solution should be generalized and not bound to any specific provider. This consideration ensures that the solution can be applied to any provider, guaranteeing its versatility and broad applicability."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Offline Testing"}),"\nThe testing solution should support testing without internet connection, which will enable more robust and flexible testing scenarios. It should be possible to run the tests even in cases of limited or disrupted internet access."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Fast Execution Time"}),"\nThe tests should execute within a reasonably short amount of time. The solution must be optimized to ensure quick testing cycles, which can help increase productivity and shorten development cycles."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"No-Cost Solution"}),"\nThe solution should not impose any additional costs on the organization or individual testers. This characteristic is crucial to enable widespread adoption of the testing process and to lower the entry barrier for contributors."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Easy Monitoring and Debugging"}),"\nThe solution should provide easy monitoring and debugging capabilities. It should allow developers to quickly identify, diagnose, and fix issues that arise during testing, without requiring access to any external logs or monitoring tools."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Concurrent Testing"}),"\nThe solution should support the ability to run concurrent tests without causing any disruption or downtime. This ability can improve the efficiency and speed of the testing process."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"required-features",children:"Required Features"}),"\n",(0,s.jsx)(n.p,{children:"The proposed solution should meet the following feature requirements:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Local Environment: The solution should support a local testing environment that allows developers to test cluster stacks on their local machines, reducing dependencies on external providers."}),"\n",(0,s.jsx)(n.li,{children:"Compatibility: The solution should be compatible with various operating systems and platforms, ensuring its usability across diverse environments."}),"\n",(0,s.jsx)(n.li,{children:"Performance: The solution should offer high-performance testing capabilities, allowing fast execution of tests."}),"\n",(0,s.jsx)(n.li,{children:"Offline Support: The solution should allow testing in offline mode, ensuring tests can be performed even without an internet connection."}),"\n",(0,s.jsx)(n.li,{children:"Concurrency: The solution should support running multiple tests concurrently without causing disruptions or conflicts."}),"\n",(0,s.jsx)(n.li,{children:"Monitoring & Debugging: The solution should provide easy-to-use tools for monitoring test progress and debugging issues."}),"\n",(0,s.jsx)(n.li,{children:"Cost-effectiveness: The solution should not require any financial investment from the testers or the organization, promoting broad accessibility and usage."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"pros-and-cons-of-different-approaches",children:"Pros and Cons of Different Approaches"}),"\n",(0,s.jsx)(n.p,{children:"Two potential approaches for testing cluster stacks are the use of an IaaS provider and the use of a local environment. Here we discuss the pros and cons of these two approaches."}),"\n",(0,s.jsx)(n.h3,{id:"iaas-provider-openstack-hetzner-aws",children:"IaaS Provider (OpenStack, Hetzner, AWS)"}),"\n",(0,s.jsx)(n.h4,{id:"pros",children:"Pros"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Comprehensive testing environment with advanced capabilities."}),"\n",(0,s.jsx)(n.li,{children:"Possibility to mimic real-world production environments closely."}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"cons",children:"Cons"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Requires signing up and account management, which can be a barrier for some testers."}),"\n",(0,s.jsx)(n.li,{children:"Requires maintaining a balance in the provider account, which can pose financial burdens."}),"\n",(0,s.jsx)(n.li,{children:"Internet dependency for testing."}),"\n",(0,s.jsx)(n.li,{children:"Potential for prolonged testing time due to various dependencies."}),"\n",(0,s.jsx)(n.li,{children:"Challenges with monitoring and debugging."}),"\n",(0,s.jsx)(n.li,{children:"Potential downtime and difficulty in running concurrent tests."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"local-environment-docker-kubevirt",children:"Local Environment (Docker, KubeVirt)"}),"\n",(0,s.jsx)(n.h4,{id:"pros-1",children:"Pros"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Faster test execution with no downtime."}),"\n",(0,s.jsx)(n.li,{children:"Ability to test without internet."}),"\n",(0,s.jsx)(n.li,{children:"Independent of any provider knowledge."}),"\n",(0,s.jsx)(n.li,{children:"Cost-free testing."}),"\n",(0,s.jsx)(n.li,{children:"Easier integration into CI/CD."}),"\n",(0,s.jsx)(n.li,{children:"Simplified monitoring and debugging."}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"cons-1",children:"Cons"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Limited systemd support and containerd support for kubeadm in Docker."}),"\n",(0,s.jsx)(n.li,{children:"Inability to mimic the exact real-world production environments."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"beyond-docker-virtual-machine-based-approach",children:"Beyond Docker: Virtual Machine based Approach"}),"\n",(0,s.jsx)(n.p,{children:"While Docker provides significant benefits for local environment testing, it's important to recognize its limitations. Docker containers, by design, are lightweight and don't contain a full operating system which can lead to challenges when trying to mimic real-world production environments. Also, Docker containers lack some necessary features like systemd which is used in many production environments for initializing and managing services."}),"\n",(0,s.jsx)(n.p,{children:"One major aspect that Docker lacks is the ability to mimic real-world production environments effectively. This is primarily due to its nature as a containerization tool, operating within the host OS, and sharing resources among its containers. This might create disparities in behavior when comparing to deployments on real, isolated systems, which could be problematic in some scenarios."}),"\n",(0,s.jsx)(n.p,{children:"Furthermore, Docker utilizes a Union File System for its images, leading to the creation of layers. This approach can lead to some complexities when dealing with node-images which comprise a significant chunk of our layers. Handling such situations might require workarounds that could add additional complexity and potential points of failure. This creates a blind spot, as real providers won't require these workarounds, which might lead to disparities in results when comparing testing in local and actual production environments."}),"\n",(0,s.jsx)(n.p,{children:"Therefore, to achieve a more accurate representation of real-world environments, we propose a solution that utilizes a virtual machine based approach for local testing. This approach could leverage tools like KubeVirt, Vagrant, or VirtualBox to create and manage virtual machines on the local environment. This strategy would provide a more robust and realistic environment for testing, as it can better emulate the behavior of a full-fledged operating system and thereby more closely mimic a real-world production environment."}),"\n",(0,s.jsx)(n.h3,{id:"virtual-machine-based-approach",children:"Virtual Machine Based Approach"}),"\n",(0,s.jsx)(n.h4,{id:"pros-2",children:"Pros"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Provides a more accurate representation of real-world production environments."}),"\n",(0,s.jsx)(n.li,{children:"Allows for full operating system emulation, including features like systemd."}),"\n",(0,s.jsx)(n.li,{children:"Can create isolated environments, thereby mimicking actual deployments better than containers."}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"cons-2",children:"Cons"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Potentially more resource-intensive than container-based solutions."}),"\n",(0,s.jsx)(n.li,{children:"Increased complexity due to the need for managing full virtual machines rather than lightweight containers."}),"\n",(0,s.jsx)(n.li,{children:"Initial setup might be more complicated compared to a Docker-based solution."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"proposed-path-forward",children:"Proposed Path Forward"}),"\n",(0,s.jsx)(n.p,{children:"Given the limitations of Docker and the potential advantages of a virtual machine based approach, we propose to investigate further into this strategy. The exact tool or set of tools used can be determined based on a thorough evaluation of the available options."}),"\n",(0,s.jsx)(n.p,{children:"Although there might be some initial complexity and potentially higher resource usage compared to Docker, we believe that the benefits of more accurate testing and better emulation of real-world environments outweigh these potential disadvantages."}),"\n",(0,s.jsx)(n.p,{children:"The proposed solution should meet all the requirements mentioned in the previous sections of the proposal, in addition to providing the benefits of a virtual machine based approach. By doing so, we aim to establish a robust, reliable, and realistic testing environment for cluster stacks that mimics real-world production environments as closely as possible."}),"\n",(0,s.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,s.jsx)(n.p,{children:"After thoroughly examining the organizational needs, technical requirements, and potential testing approaches, it is evident that testing cluster stacks in a local environment provides significant advantages over using an Infrastructure as a Service (IaaS) provider. A local environment minimizes financial constraints, reduces testing time, offers offline capabilities, and enables greater tester participation without the need for specialized IaaS knowledge."}),"\n",(0,s.jsx)(n.p,{children:"While Docker stands out for its broad adoption, cost-effectiveness, and impressive containerization benefits, it also presents some limitations that cannot be overlooked. The lack of full operating system emulation and certain system features like systemd pose challenges to mimic real-world production environments accurately."}),"\n",(0,s.jsx)(n.p,{children:"Given Docker's limitations and the need to reproduce realistic testing scenarios, we propose moving beyond Docker to a virtual machine-based approach. Even though this approach may introduce initial complexity and potentially higher resource usage, it promises a more accurate representation of real-world environments, thereby ensuring more reliable and robust test results."}),"\n",(0,s.jsx)(n.p,{children:"Tools such as KubeVirt, Vagrant, or VirtualBox could potentially fulfill our requirements, offering benefits such as full operating system emulation and isolated environments. However, an in-depth evaluation of these and possibly other tools is necessary to determine the best path forward."}),"\n",(0,s.jsx)(n.p,{children:"In conclusion, our goal is to design a robust, reliable, and realistic testing environment for cluster stacks that closely mimics real-world production environments, aligns with our organizational and technical perspectives, and ensures a low entry barrier for all testers. Embracing a virtual machine-based approach for local environment testing represents a promising strategy to achieve this objective, paving the way for more efficient and reliable cluster stack testing."})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>a});var t=i(96540);const s={},o=t.createContext(s);function r(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b30e8b21.dde25c3d.js b/assets/js/b30e8b21.dde25c3d.js new file mode 100644 index 0000000000..9b5727decf --- /dev/null +++ b/assets/js/b30e8b21.dde25c3d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[96578],{76807:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"scs-0217-v1-cluster-hardening","title":"Kubernetes cluster hardening","description":"Introduction","source":"@site/standards/scs-0217-v1-cluster-hardening.md","sourceDirName":".","slug":"/scs-0217-v1-cluster-hardening","permalink":"/standards/scs-0217-v1-cluster-hardening","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Kubernetes cluster hardening","type":"Standard","status":"Draft","track":"KaaS"},"sidebar":"standards","previous":{"title":"scs-0217: Kubernetes cluster hardening","permalink":"/standards/kaas/scs-0217"},"next":{"title":"scs-0218: Container registry for SCS standard implementation","permalink":"/standards/kaas/scs-0218"}}');var i=n(74848),r=n(28453);const o={title:"Kubernetes cluster hardening",type:"Standard",status:"Draft",track:"KaaS"},a=void 0,c={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Hardening Kubernetes",id:"hardening-kubernetes",level:2},{value:"Regular updates",id:"regular-updates",level:3},{value:"Securing etcd",id:"securing-etcd",level:3},{value:"Strong authentication",id:"strong-authentication",level:4},{value:"Multiple etcd instances",id:"multiple-etcd-instances",level:4},{value:"etcd isolation",id:"etcd-isolation",level:4},{value:"ACL restrictions",id:"acl-restrictions",level:4},{value:"TLS communication",id:"tls-communication",level:4},{value:"Securing endpoints",id:"securing-endpoints",level:3},{value:"Control plane nodes",id:"control-plane-nodes",level:4},{value:"Worker nodes",id:"worker-nodes",level:4},{value:"API security, authentication and authorization",id:"api-security-authentication-and-authorization",level:3},{value:"Authentication",id:"authentication",level:4},{value:"Authorization",id:"authorization",level:4},{value:"Admission Controllers",id:"admission-controllers",level:4},{value:"Kubelet access control",id:"kubelet-access-control",level:3},{value:"Pod security policies",id:"pod-security-policies",level:3},{value:"Further measurements",id:"further-measurements",level:3},{value:"Standard",id:"standard",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2},{value:"Related Documents",id:"related-documents",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"Due to the regular changes and updates, there are always new security features to deploy and use in Kubernetes.\nNevertheless, a provider (or even a customer) needs to take action in order to achieve a\nbaseline-secure cluster due to the myriad of configurations possible. This is especially\nthe case since Kubernetes ships with insecure features and configurations out of the box,\nwhich will need to be mitigated by an administrator with the proper knowledge.\nSecure Kubernetes clusters are desirable regardless of the possible threat model,\nsince higher security doesn't necessarily mean higher complexity in this case."}),"\n",(0,i.jsx)(t.h2,{id:"terminology",children:"Terminology"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Term"}),(0,i.jsx)(t.th,{children:"Meaning"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"TLS"}),(0,i.jsx)(t.td,{children:"Transport Layer Security"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"CA"}),(0,i.jsx)(t.td,{children:"Certificate Authority"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"JWT"}),(0,i.jsx)(t.td,{children:"JSON Web Token"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"ABAC"}),(0,i.jsx)(t.td,{children:"Attribute-based access control"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"RBAC"}),(0,i.jsx)(t.td,{children:"Role-based access control"})]})]})]}),"\n",(0,i.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:"Kubernetes clusters are highly configurable, which also gives rise to different security\nproblems, if the configuration isn't done properly.\nThese security risks can potentially be exposed in many different parts of a cluster, e.g.\ndifferent APIs, authorization and authentication procedures or even Pod privilege mechanisms.\nIn order to mitigate these problems, different steps and hardening mechanisms could be used\nto increase the security of a Kubernetes setup.\nDue to the focus of the SCS KaaS standards on the providers, best practices for security\nthat are more focused on user environments aren't described here, e.g., the possibility for\nnetwork traffic control between pods. This could theoretically be set up by a provider,\nbut isn't very practical for the user, since he would probably need to request changes\nregularly in this case."}),"\n",(0,i.jsx)(t.h2,{id:"hardening-kubernetes",children:"Hardening Kubernetes"}),"\n",(0,i.jsx)(t.p,{children:"This section is non-authoritative and only describes concepts and design considerations."}),"\n",(0,i.jsx)(t.h3,{id:"regular-updates",children:"Regular updates"}),"\n",(0,i.jsxs)(t.p,{children:["Due to the risk associated with running older versions of software, e.g. known security vulnerabilities,\nbugs or missing features as well as the difficulty of tracking or identifying attack vectors,\nit is advised to first and foremost keep the version of the Kubernetes components up-to-date.\nIt should be especially important to keep on track with the patch-level ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/releases/",children:"versions of Kubernetes"}),",\nsince they include bugfixes and security patches, which are also backported to the previous\nthree minor-level versions, depending on their severity and the feasibility. It is also recommended\nto refer to the version skew policy for more details about ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/releases/version-skew-policy/",children:"component versions"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"securing-etcd",children:"Securing etcd"}),"\n",(0,i.jsx)(t.p,{children:"The etcd database is the storage for Kubernetes, containing information about cluster workloads, states and secrets.\nGaining access to this critical infrastructure part would enable a bad actor to read the aforementioned information;\nwrite access would be equivalent to administrative access on the Kubernetes cluster and information could be manipulated\nwhile ignoring any restrictions or validations put in place by other Kubernetes components."}),"\n",(0,i.jsx)(t.p,{children:"Securing etcd can be done through different or a combination of\nmany mechanisms, including strong security credentials for the etcd server, the isolation of the etcd servers behind a firewall, separate etcd\ninstances for components beside the API-server, ACL restrictions for read-write-access to subsets of the keyspace and\na separate CA for etcd communication, which limits the trusted partners of the etcd database to clients with a certificate from this CA.\nThese strategies will be explained a bit more in-depth in the following subsections."}),"\n",(0,i.jsx)(t.h4,{id:"strong-authentication",children:"Strong authentication"}),"\n",(0,i.jsxs)(t.p,{children:["If an etcd instance wasn't secured correctly, it could be possible that a bad actor would try to authenticate against\nthe database.\nIt is therefore advised to use strong security credentials (see e.g. ",(0,i.jsx)(t.a,{href:"https://pages.nist.gov/800-63-3/sp800-63b.html",children:"the strong credentials requirements by NIST"}),") for\nall user accounts on the etcd server as well as the machines running this critical component.\nThis is obviously a fact for all possibly accessible components, but especially true for etcd, since it contains\nthe complete cluster state."]}),"\n",(0,i.jsx)(t.h4,{id:"multiple-etcd-instances",children:"Multiple etcd instances"}),"\n",(0,i.jsxs)(t.p,{children:["etcd is a critical component that needs to be protected from\nbad actors as well as outages. Kubernetes recommends a ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/#multi-node-etcd-cluster",children:"five-member cluster"})," for durability and high-availability as well as regular back-ups of the data.\nFor more information on high-availability, look into the ",(0,i.jsx)(t.a,{href:"/standards/scs-0214-v1-k8s-node-distribution",children:"Kubernetes Node Distribution and Availability Standard"}),".\nIt would also be possible to use these etcd instances in order to select specific instances\nthat aren't the current etcd leader for interaction with different components (e.g. Calico), since access to the primary etcd instance could be considered dangerous, because the full keyspace could be viewed without further restrictions (see ",(0,i.jsx)(t.a,{href:"https://cheatsheetseries.owasp.org/cheatsheets/Kubernetes_Security_Cheat_Sheet.html#limiting-access-to-the-primary-etcd-instance",children:"here"})," or ",(0,i.jsx)(t.a,{href:"https://docs.tigera.io/calico/latest/reference/etcd-rbac/kubernetes-advanced",children:"here"}),").\nThis approach should still be paired with ",(0,i.jsx)(t.a,{href:"#acl-restrictions",children:"etcd ACL"})," to better restrict access."]}),"\n",(0,i.jsx)(t.h4,{id:"etcd-isolation",children:"etcd isolation"}),"\n",(0,i.jsx)(t.p,{children:"The etcd database should at best be isolated from the rest of a Kubernetes cluster.\nAccess should only be granted to components that need it, which is in most cases mainly (or only)\nthe API server. Best practice would be to host etcd on machines separate from the Kubernetes cluster\nand block access from machines or networks that don't need access with specific firewall rules.\nIn most cases, only the API server machines should need access to etcd on ports 2379-2380."}),"\n",(0,i.jsx)(t.h4,{id:"acl-restrictions",children:"ACL restrictions"}),"\n",(0,i.jsxs)(t.p,{children:["etcd implements access control lists (ACL) and authentication since version 2.1 ",(0,i.jsx)(t.a,{href:"https://etcd.io/docs/v3.3/op-guide/authentication/",children:"1"}),".\netcd provides users and roles; users gain permissions through roles. When authentication is enabled,\neach request to etcd requires authentication and the transaction is only allowed, if the user has the correct access rights.\netcd can also be launched with ",(0,i.jsx)(t.code,{children:"--client-cert-auth=true"}),", which enables authentication via\nthe Common Name (CN) field of a client TLS certificate without a password.\nThis option enables Kubernetes components to authenticate as a user without providing a password,\nwhich is neither possible for Kubernetes components nor planned in future releases.\nThis method is recommended in order to implement ACL for different Kubernetes components and\nnot give the Kubernetes API full root access to the etcd instance; instead, a separate user can be created."]}),"\n",(0,i.jsx)(t.h4,{id:"tls-communication",children:"TLS communication"}),"\n",(0,i.jsxs)(t.p,{children:["etcd should use TLS for peer- and cluster-communication, so that traffic between different peered etcd instances as well\nas the communication with the Kubernetes cluster can be secured.\netcd provides options for all these scenarios, including ",(0,i.jsx)(t.code,{children:"--peer-key-file=peer.key"})," and ",(0,i.jsx)(t.code,{children:"--peer-cert-file=peer.cert"}),"\nfor securing peer communication and the flags ",(0,i.jsx)(t.code,{children:"--key-file=k8sclient.key"})," and ",(0,i.jsx)(t.code,{children:"--cert-file=k8sclient.cert"})," for securing\nclient communication (and therefore cluster communication).\nAdditionally, HTTPS should be used as the URL schema.\nIt is also possible to use a separate CA for the etcd in order to separate and better control access through client\ncertificates, since etcd by default trusts all the certificates issued by the root CA ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/blog/2021/10/05/nsa-cisa-kubernetes-hardening-guidance/",children:"2"}),".\nMore information about authentication via TLS is provided in the chapter ",(0,i.jsx)(t.a,{href:"#acl-restrictions",children:"ACL restrictions"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"securing-endpoints",children:"Securing endpoints"}),"\n",(0,i.jsx)(t.p,{children:"Kubernetes provides a well-defined set of ports in its default configuration. These ports are\nused for inter-component communication as well as external access. Due to the distribution of information\nabout Kubernetes clusters, it is easy for a bad actor to identify a clusters\nports and try to attack them. In order to minimize the attack vector, internal ports (and therefore components)\nshould not be accessible from external networks, except if there are requirements to enable this behavior."}),"\n",(0,i.jsx)(t.p,{children:"A good way to restrict access would be a combination of firewalls with port\nblocking and the integration of network separation.\nHow this is done is highly dependent on the specific setup of the provider.\nAn additional document could be provided in the future to give basic\nguidelines for this task."}),"\n",(0,i.jsx)(t.p,{children:"A list of the default ports used in Kubernetes as well as the components accessing them can be found below:"}),"\n",(0,i.jsx)(t.h4,{id:"control-plane-nodes",children:"Control plane nodes"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Ports"}),(0,i.jsx)(t.th,{children:"Protocol"}),(0,i.jsx)(t.th,{children:"Purpose"}),(0,i.jsx)(t.th,{children:"Used by"}),(0,i.jsx)(t.th,{children:"Access type"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"6443"}),(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"API server"}),(0,i.jsx)(t.td,{children:"All"}),(0,i.jsx)(t.td,{children:"External, internal"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"2379-2380"}),(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"etcd server"}),(0,i.jsx)(t.td,{children:"kube-apiserver, etcd"}),(0,i.jsx)(t.td,{children:"Internal"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10250"}),(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"Kubelet API"}),(0,i.jsx)(t.td,{children:"Self, Control plane"}),(0,i.jsx)(t.td,{children:"Internal"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10255"}),(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"Read-only Kubelet API"}),(0,i.jsx)(t.td,{children:"External applications"}),(0,i.jsx)(t.td,{children:"External, Internal"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10257"}),(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"kube-controller-manager"}),(0,i.jsx)(t.td,{children:"Self"}),(0,i.jsx)(t.td,{children:"Internal"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10259"}),(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"kube-scheduler"}),(0,i.jsx)(t.td,{children:"Self"}),(0,i.jsx)(t.td,{children:"Internal"})]})]})]}),"\n",(0,i.jsxs)(t.p,{children:["Hint: ",(0,i.jsx)(t.code,{children:"Self"})," in the ",(0,i.jsx)(t.code,{children:"Used by"})," context means, that a resource will access its own port for requests."]}),"\n",(0,i.jsx)(t.h4,{id:"worker-nodes",children:"Worker nodes"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Ports"}),(0,i.jsx)(t.th,{children:"Protocol"}),(0,i.jsx)(t.th,{children:"Purpose"}),(0,i.jsx)(t.th,{children:"Used by"}),(0,i.jsx)(t.th,{children:"Access type"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10250"}),(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"Kubelet API"}),(0,i.jsx)(t.td,{children:"Self, Control plane"}),(0,i.jsx)(t.td,{children:"Internal"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"10255"}),(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"Read-only Kubelet API"}),(0,i.jsx)(t.td,{children:"External applications"}),(0,i.jsx)(t.td,{children:"External, internal"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"30000-32767"}),(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"NodePort Services"}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{children:"External"})]})]})]}),"\n",(0,i.jsx)(t.h3,{id:"api-security-authentication-and-authorization",children:"API security, authentication and authorization"}),"\n",(0,i.jsx)(t.p,{children:"In order to secure Kubernetes against bad actors, limiting and securing access to API requests\nis recommended, since requests to those are able to control the entire Kubernetes cluster.\nAccess control is applied to both human users and Kubernetes service accounts, which goes through\nseveral stages after a request reaches the API."}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["The Kubernetes API server listens on port 6443 on the first non-localhost network interface by default,\nprotected by TLS ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/security/controlling-access/",children:"3"}),". The TLS certificate can either be signed with a private CA or based on a public key\ninfrastructure with a widely recognized CA behind it."]}),"\n",(0,i.jsx)(t.li,{children:"The authentication step checks the request for correct authentication based on different possible\nauthentication modules like password, plain tokens or JWT. Only one of these methods needs to succeed\nin order to allow a request to pass to the next stage."}),"\n",(0,i.jsx)(t.li,{children:"The authorization step authorizes a request, if a user is allowed to carry out a specific operation.\nThe request must contain the username of the requester, the requested action and the affected object.\nKubernetes supports different authorization modules like ABAC, RBAC or Webhooks. Only one of these\nmodules need to approve the request in order for it to be authorized."}),"\n",(0,i.jsx)(t.li,{children:"The last step are Admission control modules, which can modify or reject requests after accessing\nthe objects contents."}),"\n"]}),"\n",(0,i.jsx)(t.h4,{id:"authentication",children:"Authentication"}),"\n",(0,i.jsxs)(t.p,{children:["Kubernetes provides different internal authentication mechanisms, that can be used depending\non the requirements of the cluster provider and user. Multiple authentication systems can\nbe enabled and the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/authentication/",children:"Kubernetes documentation"})," recommends at least using two methods,\nincluding Service Account Tokens and another method. Methods directly provided by Kubernetes include\nthe following (a more complete or up-to-date list may be found in the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/authentication/",children:"Kubernetes authentication docs"}),"):"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.em,{children:"Static Token Files"})}),"\n",(0,i.jsxs)(t.p,{children:["This method reads bearer tokens from requests and checks them against a CSV file provided to Kubernetes containing\nthree columns named ",(0,i.jsx)(t.code,{children:"token"}),", ",(0,i.jsx)(t.code,{children:"username"})," and ",(0,i.jsx)(t.code,{children:"uid"}),". These tokens last indefinitely and the list can't be changed\nwithout a restart of the API server. This makes this option unsuitable for production clusters."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.em,{children:"Service Account Tokens"})}),"\n",(0,i.jsxs)(t.p,{children:["A service account is an authenticator that uses signed bearer tokens for request verification.\nService accounts can be given to the API server with a file containing PEM-encoded X509 RSA or\nECDSA private or public keys that verify the Service Account Tokens.\nService Accounts are normally created automatically by the API server and associated with the\npods through the ",(0,i.jsx)(t.code,{children:"ServiceAccount"})," admission controller. Tokens are signed JSON Web Tokens,\nthat can be used as a Bearer Token or mounted into the pods for API server access.\nSince Service Account Tokens are mainly used to allow workloads accessing the API server,\nthey're not really intended to authenticate users in production clusters."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.em,{children:"X509 client certificates"})}),"\n",(0,i.jsxs)(t.p,{children:["Client certificate authentication can be enabled by providing a ",(0,i.jsx)(t.code,{children:"Certificate Authority"}),"\nfile to the API server via the ",(0,i.jsx)(t.code,{children:"--client-ca-file="})," option. The file contains one\nor more CAs that a presented client certificate is validated against.\nIn this case the common subject name is used as the username for the request;\nadditionally, a group membership can be indicated with the certificates organization field.\nThese certificates are unsuitable for production use, because Kubernetes does not\nsupport certificate revocation. This means user credentials can't be modified or\nrevoked without rotating the root CA and re-issuing all cluster certificates."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"As outlined, most internal authentication mechanisms of Kubernetes aren't really\nusable in productive environments at the current time. Instead, external authentication\nshould be used in order to provide production-ready workflows.\nThe Kubernetes documentation lists a few examples for external authenticators, e.g."}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens",children:"OpenIDConnect"})}),"\n",(0,i.jsxs)(t.li,{children:["Bearer Tokens with ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication",children:"Webhook Token Authentication"})]}),"\n",(0,i.jsxs)(t.li,{children:["Request Header Authentication with an ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/authentication/#authenticating-proxy",children:"Authenticating Proxy"})]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"All of these examples are useful to set up for an organization or can be used with\nan already in-place solution. More information can be found in their respective\npart of the Kubernetes documentation.\nMost of these are good solutions for productive setups, since they enable easy\nuser management, access revocation and things like short-lived access tokens.\nWhat will be used by your organization depends on the present setup and the use case."}),"\n",(0,i.jsx)(t.h4,{id:"authorization",children:"Authorization"}),"\n",(0,i.jsx)(t.p,{children:"Authorization is done after the authentication step in order to check the rights\nof a user within the system. Kubernetes authorizes API requests with the API server,\nwhich evaluates requests against all policies in place and then allows or denies these requests.\nBy default, a request would be denied."}),"\n",(0,i.jsx)(t.p,{children:"Kubernetes provides several authentication modes to authorize a request:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.em,{children:"Node"})}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/node/",children:"Node authorization mode"})," grants permission to a Kubelet\nbased on the scheduled pods running on them. It allows a Kubelet to perform specific\nAPI operations. The goal is to have a minimal set of permissions to ensure\nthe Kubelet can operate correctly.\nEach Kubelet identifies with credentials belonging to the ",(0,i.jsx)(t.code,{children:"system:nodes"})," group and\na username ",(0,i.jsx)(t.code,{children:"system:nodes:<node>"})," against this authorizer."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.em,{children:"ABAC (Attribute-based access control)"})}),"\n",(0,i.jsxs)(t.p,{children:["ABAC grants access rights based on policies dependent on attributes like\nuser attributes, resource attributes or environment attributes.\nAn example would be the ",(0,i.jsx)(t.code,{children:"resource"})," attribute, which could limit access for a user\nto only ",(0,i.jsx)(t.code,{children:"Pod"})," resources."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.em,{children:"RBAC (Role-based access control)"})}),"\n",(0,i.jsxs)(t.p,{children:["RBAC is a method of regulating access to the resources based on the roles of\nindividual users. A user therefore must have the ability to perform a specific set\nof tasks with a set of resources based on his role.\nKubernetes implements ",(0,i.jsx)(t.code,{children:"Role"}),"s to accomplish this and binds these with ",(0,i.jsx)(t.code,{children:"Role Binding"}),"s\nto a user in order to specify his permission set."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.em,{children:"Webhook"})}),"\n",(0,i.jsx)(t.p,{children:"Webhook authorization uses an HTTP callback to check the authorization of a user\nagainst a URL provided for this mode. This externalises the authorization part\noutside of Kubernetes."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Most organizations and deployments work with RBAC, most often due to organizational or\ncustomer-owner-relationship-like structures in place.\nNonetheless, neither ABAC, RBAC nor Webhook authorization can be recommended over the\nother, since this all depends on the use case and required structure of a deployment.\nUsing at least one of these modes is recommended."}),"\n",(0,i.jsx)(t.p,{children:"It is also recommended to enable the Node authorizer in order to limit Kubelet\npermissions to a minimum operational state."}),"\n",(0,i.jsx)(t.h4,{id:"admission-controllers",children:"Admission Controllers"}),"\n",(0,i.jsxs)(t.p,{children:["Admission controllers intercept requests to the Kubernetes API after the\nauthentication and authorization step, which validate and/or mutate the request.\nThis step is limited to ",(0,i.jsx)(t.code,{children:"create"}),", ",(0,i.jsx)(t.code,{children:"modify"})," and ",(0,i.jsx)(t.code,{children:"delete"})," objects as well as custom\nverbs, but other requests are not blocked.\nKubernetes provides multiple admission controllers, some of which are enabled by default."]}),"\n",(0,i.jsxs)(t.p,{children:["One recommended admission controller is the ",(0,i.jsxs)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction",children:[(0,i.jsx)(t.code,{children:"NodeRestriction"})," controller"]}),",\nwhich limits the ",(0,i.jsx)(t.code,{children:"Node"})," and ",(0,i.jsx)(t.code,{children:"Pod"})," objects a Kubelet is allowed to modify to their own ",(0,i.jsx)(t.code,{children:"Node"})," or\nobjects that are bound to them. It also disallows updating or removing taints and prevents changing\nor adding labels with a ",(0,i.jsx)(t.code,{children:"node-restriction.kubernetes.io/"})," prefix.\nBe aware that Kubelets will only be limited by this admission controller, if the user credentials\nin the ",(0,i.jsx)(t.code,{children:"system:nodes"})," group begin with a ",(0,i.jsx)(t.code,{children:"system:node:<nodeName>"})," username. Administrators must therefore\nconfigure their Kubelets correctly, if the ",(0,i.jsx)(t.code,{children:"NodeRestriction"})," controller should be fully functional."]}),"\n",(0,i.jsx)(t.h3,{id:"kubelet-access-control",children:"Kubelet access control"}),"\n",(0,i.jsxs)(t.p,{children:["The Kubelet is the node agent that runs on each node. It registers with the API\nserver and ensures, that pods handed over to it are running and healthy according\nto the specification provided to it. The HTTPS endpoint of a Kubelet exposes APIs\nwith varying access to sensitive data and also enables various levels\nof performant operations enabling manipulation of node data and containers.\nThere is also a read-only HTTP endpoint that was used for monitoring a Kubelet and\nits information. This port was also used by applications like ",(0,i.jsx)(t.code,{children:"kubeadm"})," to check\nthe health status of the Kubelet.\nThis port is still available, but it is planned to be ",(0,i.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/issues/12968",children:"removed"}),"\nin a future version. At the moment, the port is disabled by default since ",(0,i.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/pull/59666",children:"Kubernetes 1.10"}),"\nand shortly later also in ",(0,i.jsx)(t.a,{href:"https://github.com/kubernetes/kubeadm/issues/732",children:(0,i.jsx)(t.code,{children:"kubeadm"})}),".\nDifferent sources recommend disabling this port ",(0,i.jsx)(t.a,{href:"https://www.stigviewer.com/stig/kubernetes/2021-04-14/finding/V-242387",children:"4"})," ",(0,i.jsx)(t.a,{href:"https://docs.datadoghq.com/security/default_rules/cis-kubernetes-1.5.1-4.2.4/",children:"5"})," due to possible\nsecurity risks, but since this standard recommends restricting accessibility of internal ports,\nthis port wouldn't be accessible from external networks.\nIt is nevertheless recommended to keep this port disabled, since Kubernetes also acknowledged\nits risks and plans to remove it."]}),"\n",(0,i.jsxs)(t.p,{children:["By default, the API server does not verify the Kubelets serving certificate and\nrequests to the HTTPS endpoint that are not rejected by other authentication\nmethods are treated as anonymous requests with the combination of name ",(0,i.jsx)(t.code,{children:"system:anonymous"}),"\nand group ",(0,i.jsx)(t.code,{children:"system:unauthenticated"}),".\nThis can be disabled by starting the Kubelet with the flag ",(0,i.jsx)(t.code,{children:"--anonymous-auth=false"}),",\nwhich return ",(0,i.jsx)(t.code,{children:"401 Unauthorized"})," for unauthenticated requests.\nIt is also possible to enable internal authentication methods for the Kubelet.\nPossibilities include X509 client certificates as well as API bearer tokens to\nauthenticate against the Kubelet; details for these methods can be found in the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/#kubelet-authorization",children:"Kubernetes docs"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["After a request is authenticated, the authorization for it is checked, with the default\nbeing ",(0,i.jsx)(t.code,{children:"AlwaysAllow"}),". Requests should at best be authorized depending on their source,\nso differentiation of access makes sense for the Kubelet; not all users should have\nthe same access rights. How access can be configured and delegated to the Kubernetes\nAPI server can be found in the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/#kubelet-authorization",children:"Kubernetes docs"}),". The process works like the API request\nauthorization approach with verbs and resources being used as identifiers in roles and role bindings."]}),"\n",(0,i.jsx)(t.h3,{id:"pod-security-policies",children:"Pod security policies"}),"\n",(0,i.jsx)(t.p,{children:'Pod security plays a big part in securing a Kubernetes cluster, since bad actors could use pods to gain\nprivileged access to the systems underneath. The security risk here is mainly influenced by the capabilities\nand privileges given to a container. It is therefore recommended to apply the principal of "least privilege",\nwhich should limit the security risk to a minimum.'}),"\n",(0,i.jsxs)(t.p,{children:["Kubernetes defines the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/security/pod-security-standards/",children:(0,i.jsx)(t.em,{children:"Pod security standards"})}),"\nin the form of three policies that try to cover the range of the security spectrum.\nThese policies can be found in the following list and define a list of restricted fields that can only be\nchanged to a set of allowed values. An up-to-date list of these values can be found ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/security/pod-security-standards/",children:"here"}),"."]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.em,{children:"Privileged"})}),"\n",(0,i.jsx)(t.p,{children:"Unrestricted policy, providing the widest possible level of permissions.\nThis policy allows for known privilege escalations."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.em,{children:"Baseline"})}),"\n",(0,i.jsx)(t.p,{children:"Minimally restrictive policy which prevents known privilege escalations.\nAllows the default (minimally specified) Pod configuration."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.em,{children:"Restricted"})}),"\n",(0,i.jsx)(t.p,{children:"Heavily restricted policy, following current Pod hardening best practices."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["Kubernetes also offers the ",(0,i.jsx)(t.em,{children:"Pod security"})," admission controller, which enforces\nthe ",(0,i.jsx)(t.em,{children:"Pod security standards"})," on a namespace level during pod creation.\nThe admission controller defines the standard to be used with the three levels\n",(0,i.jsx)(t.code,{children:"privileged"}),", ",(0,i.jsx)(t.code,{children:"baseline"})," and ",(0,i.jsx)(t.code,{children:"restricted"}),". Each namespace can be configured to enforce\na different control mode, which defines what action the control plane takes\nafter a violation of the selected ",(0,i.jsx)(t.em,{children:"Pod security"})," is detected."]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.code,{children:"enforce"})}),"\n",(0,i.jsx)(t.p,{children:"Policy violations will cause the pod to be rejected."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.code,{children:"audit"})}),"\n",(0,i.jsx)(t.p,{children:"Policy violations will trigger the addition of an audit annotation to the event\nrecorded in the audit log, but are otherwise allowed."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.code,{children:"warn"})}),"\n",(0,i.jsx)(t.p,{children:"Policy violations will trigger a user-facing warning, but are otherwise allowed."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["Be aware, that ",(0,i.jsx)(t.code,{children:"enforce"})," is not applied to workload resources, only to the pods created from their template."]}),"\n",(0,i.jsx)(t.h3,{id:"further-measurements",children:"Further measurements"}),"\n",(0,i.jsxs)(t.p,{children:["While researching this topic, further measurements were considered such as container image verification,\ndistroless images, usage of ",(0,i.jsx)(t.code,{children:"ImagePolicyWebhook"}),", network policy enforcement,\ncontainer sandboxing and prevention of kernel module loading.\nMost of these were taken out of the document during writing due to either being the responsibility\nof the clusters' user (and therefore not possible to implement for the provider), being more relevant\nfor high security clusters or changing the expected cluster environment too much, so that normally\nexpected operations could potentially not work in such a modified cluster.\nThese measurements will possibly be introduced in a future document about higher security clusters."]}),"\n",(0,i.jsx)(t.h2,{id:"standard",children:"Standard"}),"\n",(0,i.jsx)(t.p,{children:"This standard provides the baseline security requirements for a cluster in the SCS context."}),"\n",(0,i.jsxs)(t.p,{children:["Kubernetes clusters MUST be updated regularly in order to receive bugfixes and security patches.\nFor more information refer to the ",(0,i.jsx)(t.a,{href:"/standards/scs-0210-v2-k8s-version-policy",children:"SCS K8s Version Policy"}),",\nwhich outlines the version update policies of the SCS."]}),"\n",(0,i.jsx)(t.p,{children:"Hardening etcd is important due to it being a critical component inside a Kubernetes cluster.\netcd SHOULD be isolated from the Kubernetes cluster by being hosted on separate (virtual) machines.\nIf this is the case, access to these instances MUST be configured, so that only the API server and\nnecessary cluster components requiring access can access etcd.\nCommunication with etcd MUST be secured with TLS for both peer- and cluster-communication.\nIt is RECOMMENDED to use a CA separate from the one used for the Kubernetes cluster for etcd in\norder to better control and issue certificates for clients allowed to access etcd.\nACL MUST be enabled for etcd, which allows better control of the access rights to specific key sets\nfor specific users. Authentication MUST be done via the Common Name (CN) field of the TLS client\ncertificates (since normal username-password-authentication isn't implemented for Kubernetes)."}),"\n",(0,i.jsx)(t.p,{children:"Kubernetes' endpoints MUST be secured in order to provide a small attack surface for bad actors.\nIt MUST NOT be possible to access Kubernetes ports from outside the internal network hosting the\nKubernetes cluster except for the ports of the API server (default 6443) and the NodePort Services\n(default 30000-32767). The read-only Kubelet API port (default 10255), which is mostly used for monitoring,\nSHOULD be disabled altogether if it isn't in use, mainly because the port is HTTP-only\nand can deliver sensitive information to the outside.\nEndpoints MUST be secured via HTTPS."}),"\n",(0,i.jsxs)(t.p,{children:["Securing Kubernetes via authentication and authorization is another important topic here.\nAuthentication is possible through multiple mechanisms, including Kubernetes-provided systems as well as external\nauthentication processes.\nA cluster MUST implement at least two methods for authentication. One of these MUST be ",(0,i.jsx)(t.em,{children:"Service Account Tokens"}),", in order\nto provide full functionality to Pods. A second authentication mechanisms can be chosen depending on the requirements\nof the provider and/or customer."]}),"\n",(0,i.jsxs)(t.p,{children:["Authorization also can be provided through multiple mechanisms.\nA cluster MUST activate at least two authorization methods, one of which MUST be ",(0,i.jsx)(t.em,{children:"Node authorization"})," and another one\nconsisting of either ABAC, RBAC or Webhook authorization depending on the required use case.\nWe RECOMMEND RBAC due to it fitting most use cases and being very well documented, but your setup might require another solution."]}),"\n",(0,i.jsxs)(t.p,{children:["In order to harden Kubelet access control, a Kubelet SHOULD only be accessible internally via HTTPS. This is already the\ncase for the Kubelet API, except for the read-only port, which is only available as HTTP. As mentioned earlier, this port\nshould be disabled.\nKubelets MUST disable anonymous request authentication to disallow non-rejected requests to go through as anonymous requests.\nOPTIONALLY, X509 client certificate authentication or API bearer token authentication can be enabled.\nRequest authorization for the Kubelet MUST be delegated to the API server via ",(0,i.jsx)(t.code,{children:"Webhook"})," authorization as it is recommended\nby the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/#kubelet-authorization",children:"Kubernetes documentation"}),".\nAdditionally, the ",(0,i.jsx)(t.code,{children:"NodeRestriction"})," admission controller MUST be activated in order to limit interactions between\ndifferent Kubelets by disallowing modification of ",(0,i.jsx)(t.code,{children:"Pod"})," objects, if they're not bound to the Kubelet requesting the modification."]}),"\n",(0,i.jsxs)(t.p,{children:["At last, ",(0,i.jsx)(t.em,{children:"Pod security standards"})," in the form of policies MUST be activated for the cluster. The SCS REQUIRES at least\nthe ",(0,i.jsx)(t.em,{children:"Baseline"})," policy with the ",(0,i.jsx)(t.em,{children:"Restricted"})," policy CAN also be used.\nThe ",(0,i.jsx)(t.em,{children:"Pod security"})," admission controller MUST also be activated in order to enforce these policies on a namespace level.\nWe RECOMMEND the ",(0,i.jsx)(t.code,{children:"enforce"})," level to be used for this admission controller setup."]}),"\n",(0,i.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,i.jsx)(t.p,{children:"Conformance Tests will be written within another issue."}),"\n",(0,i.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cheatsheetseries.owasp.org/cheatsheets/Kubernetes_Security_Cheat_Sheet.html",children:"OWASP Kubernetes Security Sheet"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/security/",children:"Kubernetes security concepts"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/securing-a-cluster/",children:"Securing a cluster"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/security/controlling-access/",children:"Controlling access"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/security/pod-security-standards/",children:"Pod security standards"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/blog/2021/10/05/nsa-cisa-kubernetes-hardening-guidance/",children:"NSA CISA Kubernetes hardening"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/",children:"Configure etcd"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-trust",children:"Google Kubernetes cluster trust"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const i={},r=s.createContext(i);function o(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b361e208.6471b5b4.js b/assets/js/b361e208.6471b5b4.js new file mode 100644 index 0000000000..984bfcfb66 --- /dev/null +++ b/assets/js/b361e208.6471b5b4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[67548],{47631:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"operating-scs/components/automated-pentesting-kaas/tools","title":"Tools Description","description":"The following tools make up the automated scanning pipeline and report sending.","source":"@site/docs/04-operating-scs/components/automated-pentesting-kaas/tools.md","sourceDirName":"04-operating-scs/components/automated-pentesting-kaas","slug":"/operating-scs/components/automated-pentesting-kaas/tools","permalink":"/docs/operating-scs/components/automated-pentesting-kaas/tools","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/automated-pentesting-kaas/tools.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Quickstart Guide","permalink":"/docs/operating-scs/components/automated-pentesting-kaas/quickstart"},"next":{"title":"Guides","permalink":"/docs/category/guides-1"}}');var s=i(74848),r=i(28453);const o={},a="Tools Description",l={},c=[{value:"Trivy Container",id:"trivy-container",level:2},{value:"Trivy Operator",id:"trivy-operator",level:2},{value:"Trivy Reporter",id:"trivy-reporter",level:2},{value:"Kubernetes CronJob",id:"kubernetes-cronjob",level:2},{value:"Defect Dojo",id:"defect-dojo",level:2}];function d(e){const n={h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"tools-description",children:"Tools Description"})}),"\n",(0,s.jsx)(n.p,{children:"The following tools make up the automated scanning pipeline and report sending."}),"\n",(0,s.jsx)(n.h2,{id:"trivy-container",children:"Trivy Container"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Functionality"}),": Trivy is a open source scanner for docker and kubernetes, is commonly used to find vulnerabilities even in infrastructure side."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Multiple Output Formats: Supports text, JSON, CyclonDX and XML formats for integration with other tools."}),"\n",(0,s.jsx)(n.li,{children:"Flexible Target Specification: Capable of scanning individual namespaces, whole cluster and specific resource."}),"\n",(0,s.jsx)(n.li,{children:"Broad Vulnerability Coverage: Capable of scanning a variety of security weaknesses and exposures."}),"\n",(0,s.jsx)(n.li,{children:"Automation-Friendly: Easily integrates into automated workflows and pipelines."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Updates"}),": Twice per day updated DB for keep all vulnerability in scope."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"trivy-operator",children:"Trivy Operator"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Functionality"}),": Same as above but the big different is it is inside kubernete and is triggered automatically when is a new change in any kubernetes component or application."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Fast Scanning: Run diffrents scanners at the same time making parallelism."}),"\n",(0,s.jsx)(n.li,{children:"Automation-Friendly: Is triggered automatically when a new resourse is deployed."}),"\n",(0,s.jsx)(n.li,{children:"Broad Vulnerability Coverage: Capable of scanning a variety of security weaknesses and exposures."}),"\n",(0,s.jsx)(n.li,{children:"Detailed Reporting: Generates comprehensive reports for vulnerabilities or compliance and remediation planning."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Updates"}),": Continuously updated with enhancements for speed, accuracy, and additional features."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"trivy-reporter",children:"Trivy Reporter"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Functionality"}),": This operator is used to send report to Defect Dojo automatically once is genereted by Trivy Operator."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Integration-Ready: Designed to fit with trivy operator."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Updates"}),": Community and developers regularly update tool features."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"kubernetes-cronjob",children:"Kubernetes CronJob"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Functionality"}),": This is a specfic developed component to send whole reports to S3 bucket to maintain all information saved in one place."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Automation-Friendly: Is triggered automatically depending when we want to sent the reports."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Updates"}),": Maintained with regular updates to the vulnerability feed and software enhancements."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"defect-dojo",children:"Defect Dojo"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Functionality"}),": Defect Dojo is a security program and vulnerability management tool. It centralizes and streamlines the management of security programs, allowing for efficient tracking, measurement, and reporting of vulnerabilities."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Vulnerability Management: Enables tracking and management of vulnerabilities discovered across different tools and tests."}),"\n",(0,s.jsx)(n.li,{children:"Reporting and Metrics: Offers comprehensive reporting features for understanding security postures and metrics."}),"\n",(0,s.jsx)(n.li,{children:"Integration with CI/CD: Seamlessly integrates with CI/CD pipelines for automated importing of scan results."}),"\n",(0,s.jsx)(n.li,{children:"Customization and Flexibility: Allows customizations to fit various workflow requirements and integrates with other tools via APIs."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Updates"}),": Regularly updated with enhancements for functionality, usability, and security."]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>a});var t=i(96540);const s={},r=t.createContext(s);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b36e6e7c.3c11eda7.js b/assets/js/b36e6e7c.3c11eda7.js new file mode 100644 index 0000000000..209e136c00 --- /dev/null +++ b/assets/js/b36e6e7c.3c11eda7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[25152],{67126:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>i});const n=JSON.parse('{"id":"iaas/scs-0122","title":"scs-0122: _End-to-End Encryption between Customer Workloads_","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0122.md","sourceDirName":"iaas","slug":"/iaas/scs-0122","permalink":"/standards/iaas/scs-0122","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0121-w1-Availability-Zones-Standard"},"next":{"title":"V1","permalink":"/standards/scs-0122-v1-node-to-node-encryption"}}');var r=s(74848),d=s(28453);const o={},a="scs-0122: End-to-End Encryption between Customer Workloads",c={},i=[];function l(e){const t={a:"a",em:"em",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsxs)(t.h1,{id:"scs-0122-end-to-end-encryption-between-customer-workloads",children:["scs-0122: ",(0,r.jsx)(t.em,{children:"End-to-End Encryption between Customer Workloads"})]})}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0122-v1-node-to-node-encryption",children:"scs-0122-v1"})}),(0,r.jsx)(t.td,{children:"Decision Record"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,d.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>a});var n=s(96540);const r={},d=n.createContext(r);function o(e){const t=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(d.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b3e290f1.50a67625.js b/assets/js/b3e290f1.50a67625.js new file mode 100644 index 0000000000..4075fc1e67 --- /dev/null +++ b/assets/js/b3e290f1.50a67625.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[89031],{87390:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>l,metadata:()=>n,toc:()=>i});const n=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","title":"using-local-clusterstacks","description":"This is a quickstart guide on using the local clusterstacks.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/topics","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks.md","tags":[],"version":"current","frontMatter":{}}');var r=t(74848),o=t(28453);const l={},c=void 0,a={},i=[{value:"Introduction",id:"introduction",level:3},{value:"using right flags",id:"using-right-flags",level:3},{value:"getting release assets",id:"getting-release-assets",level:3},{value:"getting release assets: From Github",id:"getting-release-assets-from-github",level:4},{value:"getting release assets: From csmctl",id:"getting-release-assets-from-csmctl",level:4},{value:"using local mode (toggling local mode)",id:"using-local-mode-toggling-local-mode",level:3},{value:"Troubleshooting",id:"troubleshooting",level:3}];function d(e){const s={a:"a",code:"code",em:"em",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.p,{children:"This is a quickstart guide on using the local clusterstacks."}),"\n",(0,r.jsx)(s.p,{children:"Requirements:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"docker"}),"\n",(0,r.jsx)(s.li,{children:"kind"}),"\n",(0,r.jsx)(s.li,{children:"make"}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsxs)(s.p,{children:["Our controller interacts with cluster-stacks and they are stored inside GitHub releases when used in production. While this is the ideal combination to run our controller it's not a great experience when we want to develop or test new cluster-stacks.\nTo avoid this problem, we introduced ",(0,r.jsx)(s.code,{children:"local_mode"})," and in this mode we start our controller by passing some flags and instead of using remote cluster-stacks, we put them inside a directory locally.\nThis way developers working on developing new cluster-stacks get a more better experience developing cluster-stacks and iterating fast on the same."]}),"\n",(0,r.jsx)(s.h3,{id:"using-right-flags",children:"using right flags"}),"\n",(0,r.jsx)(s.p,{children:"Cluster stacks in local_mode do not fetch release assets directly from GitHub and to work with that we first need to download that and use the correct flags when we start the container.\nThe flags we are using in this repo is following:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:" args:\n - --leader-elect=true\n - --release-dir=/tmp\n - --local=true\n"})}),"\n",(0,r.jsxs)(s.p,{children:["What this means is that, the controller will look for release assets under /tmp directory inside the contanier. If the controller doesn't find release asset under ",(0,r.jsx)(s.code,{children:"/tmp"})," directory then you can get an error in the status of ",(0,r.jsx)(s.code,{children:"clusterstackrelease"})," object."]}),"\n",(0,r.jsx)(s.h3,{id:"getting-release-assets",children:"getting release assets"}),"\n",(0,r.jsx)(s.p,{children:"There are several ways to get release assets. Two common ways:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"From a Github release"}),"\n",(0,r.jsxs)(s.li,{children:["From a directory created by ",(0,r.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/csmctl",children:"csmctl"})]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Overall it does not matter who you received the directory."}),"\n",(0,r.jsxs)(s.p,{children:["Tilt expects the release assets under ",(0,r.jsx)(s.code,{children:".release"})," directory of the repository."]}),"\n",(0,r.jsx)(s.h4,{id:"getting-release-assets-from-github",children:"getting release assets: From Github"}),"\n",(0,r.jsx)(s.p,{children:"To download a release asset from Github use the following commands."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"mkdir -p .release/docker-ferrol-1-27-v2\ncd .release/docker-ferrol-1-27-v2\ngh release download -R sovereigncloudstack/cluster-stacks docker-ferrol-1-27-v2\n"})}),"\n",(0,r.jsxs)(s.p,{children:["You can also fetch the release asset manually. Using ",(0,r.jsx)(s.code,{children:"gh"})," makes it a little bit easier to download all the release asset just by invoking one command."]}),"\n",(0,r.jsxs)(s.p,{children:["Your local ",(0,r.jsx)(s.code,{children:".release"})," directory should have the following structure."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"$ tree .release/\n.release/\n\u2514\u2500\u2500 docker-ferrol-1-27-v2\n \u251c\u2500\u2500 cluster-addon-values.yaml\n \u251c\u2500\u2500 docker-ferrol-1-27-cluster-addon-v2.tgz\n \u251c\u2500\u2500 docker-ferrol-1-27-cluster-class-v2.tgz\n \u251c\u2500\u2500 metadata.yaml\n \u251c\u2500\u2500 node-images.yaml\n \u2514\u2500\u2500 topology-docker.yaml\n\n2 directories, 6 files\n"})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.em,{children:"NOTE: This directory structure is very important and you should have the same in order for the controller to work and sync."})}),"\n",(0,r.jsx)(s.h4,{id:"getting-release-assets-from-csmctl",children:"getting release assets: From csmctl"}),"\n",(0,r.jsxs)(s.p,{children:["If you use ",(0,r.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/csmctl",children:"csmctl"}),", then it creates the required directory under ",(0,r.jsx)(s.code,{children:"release"}),"."]}),"\n",(0,r.jsx)(s.p,{children:"Example:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"\u276f csmctl create tests/cluster-stacks/docker/ferrol -m hash\nCreated releases/docker-ferrol-1-27-v0-sha-7ff9188\n"})}),"\n",(0,r.jsx)(s.p,{children:"Copy this directory to .release:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"cp -a releases/docker-ferrol-1-27-v0-sha-7ff9188 ../cluster-stack-operator/.release\n"})}),"\n",(0,r.jsx)(s.h3,{id:"using-local-mode-toggling-local-mode",children:"using local mode (toggling local mode)"}),"\n",(0,r.jsx)(s.p,{children:"From a user perspective who is using tilt to develop and test local cluster-stacks, we just have to make one change in Tiltfile and restart the complete setup all over again."}),"\n",(0,r.jsxs)(s.p,{children:["For making changes in tilt environment, we use ",(0,r.jsx)(s.code,{children:"tilt-settings.yaml"})," file. If you don't have it then please copy it from ",(0,r.jsx)(s.code,{children:"tilt-settings.yaml.example"})," which is at the root of the repo using the following command."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"cp tilt-settings.yaml.example tilt-settings.yaml\n"})}),"\n",(0,r.jsxs)(s.p,{children:["Now, since you have your ",(0,r.jsx)(s.code,{children:"tilt-settings.yaml"})," ready, you have to edit ",(0,r.jsx)(s.code,{children:"local_mode"})," and make it to ",(0,r.jsx)(s.code,{children:"true"}),"\nYour ",(0,r.jsx)(s.code,{children:"tilt-settings.yaml"})," file should look following:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"allowed_contexts:\n - kind-cso\nlocal_mode: false\n# truncated\n"})}),"\n",(0,r.jsxs)(s.p,{children:["Once you're toggled ",(0,r.jsx)(s.code,{children:"local_mode"})," to ",(0,r.jsx)(s.code,{children:"true"}),", you're ready to start your tilt setup. Use the following command to start it."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"make tilt-up\n"})}),"\n",(0,r.jsxs)(s.p,{children:["Once the setup is ready and you've the cluster-stack-operator pod running, you can exec into the container and check the ",(0,r.jsx)(s.code,{children:"/tmp"})," directory for the presence of cluster-stacks."]}),"\n",(0,r.jsx)(s.h3,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"$ kubectl -n cso-system exec -it cso-controller-manager-5bdc445647-j4p9p -- sh\n/ # tree /tmp/\n/tmp/\n\u2514\u2500\u2500 cluster-stacks\n \u2514\u2500\u2500 docker-ferrol-1-27-v2\n \u251c\u2500\u2500 cluster-addon-values.yaml\n \u251c\u2500\u2500 docker-ferrol-1-27-cluster-addon-v2.tgz\n \u251c\u2500\u2500 docker-ferrol-1-27-cluster-class-v2.tgz\n \u251c\u2500\u2500 metadata.yaml\n \u251c\u2500\u2500 node-images.yaml\n \u2514\u2500\u2500 topology-docker.yaml\n\n2 directories, 6 files\n"})}),"\n",(0,r.jsxs)(s.p,{children:["You can now click on ",(0,r.jsx)(s.code,{children:"+"})," button on the right hand side of tilt UI to create a workload cluster. Once the cluster is created you can check the status of the components via the following commands."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:" $ kubectl get clusterstack -A\nNAMESPACE NAME PROVIDER CLUSTERSTACK K8S CHANNEL AUTOSUBSCRIBE USABLE LATEST AGE REASON MESSAGE\ncluster clusterstack docker ferrol 1.27 stable false v2 docker-ferrol-1-27-v2 | v1.27.3 5m16s\n\n $ kubectl get clusterstackreleases.clusterstack.x-k8s.io -A\nNAMESPACE NAME K8S VERSION READY AGE REASON MESSAGE\ncluster docker-ferrol-1-27-v2 v1.27.3 true 5m16s\n\n $ kubectl get clusters -A\nNAMESPACE NAME CLUSTERCLASS PHASE AGE VERSION\ncluster test-dfkhje docker-ferrol-1-27-v2 Provisioned 2m46s v1.27.3\n"})})]})}function h(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>l,x:()=>c});var n=t(96540);const r={},o=n.createContext(r);function l(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b4038536.fce62e81.js b/assets/js/b4038536.fce62e81.js new file mode 100644 index 0000000000..0eb27e352f --- /dev/null +++ b/assets/js/b4038536.fce62e81.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[36084],{6935:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>i});const o=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot","title":"Troubleshooting","description":"Check the latest events:","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/topics","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Getting Started","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart"},"next":{"title":"Contributing","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/"}}');var n=s(74848),c=s(28453);const r={},l="Troubleshooting",a={},i=[];function u(e){const t={code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"troubleshooting",children:"Troubleshooting"})}),"\n",(0,n.jsx)(t.p,{children:"Check the latest events:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"kubectl get events -A --sort-by=.lastTimestamp\n"})}),"\n",(0,n.jsx)(t.p,{children:"Check the conditions:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"go run github.com/guettli/check-conditions@latest all\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Check with ",(0,n.jsx)(t.code,{children:"clusterctl"}),":"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"clusterctl describe cluster -n cluster my-cluster\n"})}),"\n",(0,n.jsx)(t.p,{children:"Check the logs. List all logs from all deployments. Show the logs of the last ten minutes:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:'kubectl get deployment -A --no-headers | while read -r ns d _; do echo; echo "====== $ns $d"; kubectl logs --since=10m -n $ns deployment/$d; done\n'})})]})}function d(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>l});var o=s(96540);const n={},c=o.createContext(n);function r(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b43d8ee7.1a648d6b.js b/assets/js/b43d8ee7.1a648d6b.js new file mode 100644 index 0000000000..d2d2644f0e --- /dev/null +++ b/assets/js/b43d8ee7.1a648d6b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8373],{22738:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>l,frontMatter:()=>r,metadata:()=>n,toc:()=>u});const n=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow","title":"Node image flow","description":"The node image flow depends on each provider. There are various ways in which providers allow the use of custom images. We have documented the options in the cluster stacks repo.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/architecture","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow.md","tags":[],"version":"current","frontMatter":{}}');var s=o(74848),c=o(28453);const r={},a="Node image flow",i={},u=[];function d(e){const t={a:"a",h1:"h1",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"node-image-flow",children:"Node image flow"})}),"\n",(0,s.jsxs)(t.p,{children:["The node image flow depends on each provider. There are various ways in which providers allow the use of custom images. We have documented the options in the ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks#film_strip-node-images",children:"cluster stacks repo"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,o)=>{o.d(t,{R:()=>r,x:()=>a});var n=o(96540);const s={},c=n.createContext(s);function r(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b4dfe8b3.2e391262.js b/assets/js/b4dfe8b3.2e391262.js new file mode 100644 index 0000000000..001473d472 --- /dev/null +++ b/assets/js/b4dfe8b3.2e391262.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[59417],{36531:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Deployment Examples","slug":"/category/deployment-examples","permalink":"/docs/category/deployment-examples","sidebar":"docs","navigation":{"previous":{"title":"Flavor Manager","permalink":"/docs/iaas/components/flavor-manager"},"next":{"title":"artcodix","permalink":"/docs/iaas/deployment-examples/artcodix/"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/b501f8e8.4820dcbe.js b/assets/js/b501f8e8.4820dcbe.js new file mode 100644 index 0000000000..a6c87b168e --- /dev/null +++ b/assets/js/b501f8e8.4820dcbe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[51528],{39976:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"collaboration/team-container","title":"Team Container","description":"The Team Container deals with all topics around Containers and Kubernetes.","source":"@site/community/collaboration/team-container.md","sourceDirName":"collaboration","slug":"/collaboration/team-container","permalink":"/community/collaboration/team-container","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Team IAM","permalink":"/community/collaboration/team-iam"},"next":{"title":"Team Ops","permalink":"/community/collaboration/team-ops"}}');var a=t(74848),r=t(28453);const i={},s="Team Container",c={},l=[];function m(e){const n={h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"team-container",children:"Team Container"})}),"\n",(0,a.jsx)(n.p,{children:"The Team Container deals with all topics around Containers and Kubernetes."}),"\n",(0,a.jsx)(n.p,{children:"at the moment: Kubernetes Deployments via ClusterAPI\nin the future deployments via ClusterStacks\nKaaS Standard"})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(m,{...e})}):m(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>s});var o=t(96540);const a={},r=o.createContext(a);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b5a6d29b.a2e40d9d.js b/assets/js/b5a6d29b.a2e40d9d.js new file mode 100644 index 0000000000..56bb6d1777 --- /dev/null +++ b/assets/js/b5a6d29b.a2e40d9d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[68226],{14307:(e,a,n)=>{n.r(a),n.d(a,{assets:()=>t,contentTitle:()=>s,default:()=>u,frontMatter:()=>d,metadata:()=>r,toc:()=>i});const r=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/tools/resource-manager","title":"Resource Manager","description":"Preparations","source":"@site/docs/02-iaas/guides/operations-guide/openstack/tools/resource-manager.md","sourceDirName":"02-iaas/guides/operations-guide/openstack/tools","slug":"/iaas/guides/operations-guide/openstack/tools/resource-manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/resource-manager.md","tags":[],"version":"current","sidebarPosition":52,"frontMatter":{"sidebar_label":"Resource Manager","sidebar_position":52},"sidebar":"docs","previous":{"title":"Flavor Manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager"},"next":{"title":"Project Manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager"}}');var c=n(74848),o=n(28453);const d={sidebar_label:"Resource Manager",sidebar_position:52},s="Resource Manager",t={},i=[{value:"Preparations",id:"preparations",level:2},{value:"Nova",id:"nova",level:2},{value:"Live migration",id:"live-migration",level:3},{value:"Evacuation",id:"evacuation",level:3},{value:"Octavia",id:"octavia",level:2},{value:"Amphora rotation",id:"amphora-rotation",level:3},{value:"Cinder",id:"cinder",level:2},{value:"Orphans",id:"orphans",level:2}];function l(e){const a={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(a.header,{children:(0,c.jsx)(a.h1,{id:"resource-manager",children:"Resource Manager"})}),"\n",(0,c.jsx)(a.h2,{id:"preparations",children:"Preparations"}),"\n",(0,c.jsx)(a.p,{children:"Prepare use of the OpenStack Resource Manager."}),"\n",(0,c.jsx)(a.pre,{children:(0,c.jsx)(a.code,{className:"language-bash",children:"git clone https://github.com/osism/openstack-resource-manager\ncd openstack-resource-manager\npipenv install\npipenv shell\n"})}),"\n",(0,c.jsxs)(a.p,{children:["Prepare cloud profile ",(0,c.jsx)(a.code,{children:"admin"})," in ",(0,c.jsx)(a.code,{children:"clouds.yml"})," and ",(0,c.jsx)(a.code,{children:"secure.yml"})," (use ",(0,c.jsx)(a.code,{children:"clouds.yml.sample"})," and ",(0,c.jsx)(a.code,{children:"secure.yml.sample"}),"\nin the ",(0,c.jsx)(a.a,{href:"https://github.com/osism/openstack-resource-manager",children:"openstack-resource-manager"})," repository as sample files)."]}),"\n",(0,c.jsx)(a.h2,{id:"nova",children:"Nova"}),"\n",(0,c.jsx)(a.h3,{id:"live-migration",children:"Live migration"}),"\n",(0,c.jsxs)(a.p,{children:["Live migrate all instances from compute node ",(0,c.jsx)(a.code,{children:"SOURCE"})," to compute node ",(0,c.jsx)(a.code,{children:"TARGET"}),"."]}),"\n",(0,c.jsx)(a.pre,{children:(0,c.jsx)(a.code,{className:"language-bash",children:"python3 src/host-action.py --yes --disable --action live-migrate --host SOURCE --input TARGET\n"})}),"\n",(0,c.jsx)(a.h3,{id:"evacuation",children:"Evacuation"}),"\n",(0,c.jsxs)(a.p,{children:["Evacuate all instances from compute node ",(0,c.jsx)(a.code,{children:"SOURCE"})," to compute node ",(0,c.jsx)(a.code,{children:"TARGET"}),"."]}),"\n",(0,c.jsx)(a.pre,{children:(0,c.jsx)(a.code,{className:"language-bash",children:"python3 src/host-action.py --yes --action evacutate --host SOURCE --input TARGET\n"})}),"\n",(0,c.jsx)(a.h2,{id:"octavia",children:"Octavia"}),"\n",(0,c.jsx)(a.h3,{id:"amphora-rotation",children:"Amphora rotation"}),"\n",(0,c.jsx)(a.p,{children:"Rotation of amphorae older than 30 days."}),"\n",(0,c.jsx)(a.pre,{children:(0,c.jsx)(a.code,{className:"language-bash",children:"$ python3 src/amphora.py --rotate\n2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa is older than 30 days\n2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa of loadbalancer 9008d3d7-f593-4bc3-941c-a740c178148d is rotated by a loadbalancer failover\n"})}),"\n",(0,c.jsx)(a.h2,{id:"cinder",children:"Cinder"}),"\n",(0,c.jsx)(a.pre,{children:(0,c.jsx)(a.code,{className:"language-bash",children:"$ python3 src/volume.py\n2023-12-11 23:09:44 | INFO | Volume ad848454-ba1f-4c28-b9a8-edada17948b0 hangs in CREATING status for more than 2 hours\nDelete volume ad848454-ba1f-4c28-b9a8-edada17948b0 [yes/no]:\n"})}),"\n",(0,c.jsx)(a.h2,{id:"orphans",children:"Orphans"}),"\n",(0,c.jsx)(a.pre,{children:(0,c.jsx)(a.code,{className:"language-bash",children:"$ python3 src/orphan.py\n2023-12-11 23:11:16 | INFO | Checking nova / server\n2023-12-11 23:11:21 | INFO | Checking neutron / port\n2023-12-11 23:11:23 | INFO | Checking neutron / router\n2023-12-11 23:11:23 | INFO | Checking neutron / network\n2023-12-11 23:11:24 | INFO | Checking neutron / subnet\n2023-12-11 23:11:24 | INFO | Checking neutron / floatingip\n2023-12-11 23:11:24 | INFO | Checking neutron / rbacpolicy\n2023-12-11 23:11:24 | INFO | Checking neutron / securitygroup\n2023-12-11 23:11:26 | INFO | Checking neutron / securitygrouprule\n2023-12-11 23:11:27 | INFO | Checking glance / image\n2023-12-11 23:11:30 | INFO | Checking glance / imagemember\n[...]\n+---------------+-------------------+--------------------------------------+----------------------------------+\n| servicename | resourcename | resource_id | project_id |\n|---------------+-------------------+--------------------------------------+----------------------------------|\n| neutron | port | 561f8f76-18b0-470a-92cd-4336346b4b18 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | port | 6d1986e4-1e6d-4d4a-961d-97d372945bb1 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | port | 74f9bddc-9bfa-4d06-a147-ca87127e501e | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | port | f630a66b-7725-4a68-868b-caebbaf1c003 | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | router | c0c4e4aa-53ee-4fd1-8f53-84d52cf6c60b | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | router | c8f9a13b-adcd-4a8e-942b-338bcf4dde7c | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | network | 62d6ad2a-0cda-4d45-9325-963b8eb67000 | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | network | 63b8fea6-7d7b-40c3-9c31-bee4404a92d6 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | subnet | 0cd16262-330a-44ad-9160-daef84aded2d | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | subnet | 690dee14-ac12-464d-a911-a873c27ec818 | d33b0d15fd474131a335207216297a2a |\n| neutron | subnet | 854e7c55-62e2-4679-9b18-805460b998ce | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | rbacpolicy | 00d7c2a2-6674-4f40-9f95-176a7858fcca | c8e4393b6d064a26a31014f82939172f |\n| neutron | rbacpolicy | 0608c701-5b81-4712-989b-ba03cdcc255d | c8e4393b6d064a26a31014f82939172f |\n[...]\n| neutron | securitygrouprule | fd3c553f-168e-4c24-ab40-09aa934bab86 | 3a96207b719643ae9ea9a81d95116e9e |\n| neutron | securitygrouprule | fdf337be-971c-4d5d-88ca-d90cdb468e88 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | securitygrouprule | ff8162fe-f053-49c9-8659-078061ce3e23 | d0b0add9ede0452791f71cb900e35242 |\n| glance | imagemember | c7f2cb0c25d34c5d886ecaf483e5fda6 | c7f2cb0c25d34c5d886ecaf483e5fda6 |\n| glance | imagemember | d4d0a161f9024fc8b517b0375eb97c89 | d4d0a161f9024fc8b517b0375eb97c89 |\n| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |\n| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |\n| glance | imagemember | d33b0d15fd474131a335207216297a2a | d33b0d15fd474131a335207216297a2a |\n| cinder | volume | e7c4b05c-b76a-40cc-8381-03262e57eb94 | 9b5f7f8ed70d410c81e3f45bf4e36498 |\n+---------------+-------------------+--------------------------------------+----------------------------------+\n"})})]})}function u(e={}){const{wrapper:a}={...(0,o.R)(),...e.components};return a?(0,c.jsx)(a,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},28453:(e,a,n)=>{n.d(a,{R:()=>d,x:()=>s});var r=n(96540);const c={},o=r.createContext(c);function d(e){const a=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function s(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:d(e.components),r.createElement(o.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b5f86da1.e7c50e28.js b/assets/js/b5f86da1.e7c50e28.js new file mode 100644 index 0000000000..eb7fbf03f3 --- /dev/null +++ b/assets/js/b5f86da1.e7c50e28.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[67214],{65923:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Configuration","slug":"/category/configuration","permalink":"/docs/category/configuration","sidebar":"docs","navigation":{"previous":{"title":"Quickstart","permalink":"/docs/operating-scs/components/status-page-deployment/docs/quickstart"},"next":{"title":"Configure status page","permalink":"/docs/operating-scs/components/status-page-deployment/docs/configuration"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/b65fe363.d5a40099.js b/assets/js/b65fe363.d5a40099.js new file mode 100644 index 0000000000..191c07e27b --- /dev/null +++ b/assets/js/b65fe363.d5a40099.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[33475],{66346:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>r,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/ironic","title":"Ironic","description":"* Ironic admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/ironic.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/ironic","permalink":"/docs/iaas/guides/configuration-guide/openstack/ironic","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/ironic.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Ironic"},"sidebar":"docs","previous":{"title":"Horizon","permalink":"/docs/iaas/guides/configuration-guide/openstack/horizon"},"next":{"title":"Keystone","permalink":"/docs/iaas/guides/configuration-guide/openstack/keystone"}}');var t=i(74848),s=i(28453);const r={sidebar_label:"Ironic"},c="Ironic",a={},d=[];function u(e){const n={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"ironic",children:"Ironic"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/ironic/latest/admin/index.html",children:"Ironic admin guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/ironic/latest/configuration/index.html",children:"Ironic configuration reference"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>c});var o=i(96540);const t={},s=o.createContext(t);function r(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b6ce023b.22d2187b.js b/assets/js/b6ce023b.22d2187b.js new file mode 100644 index 0000000000..9de6a3b004 --- /dev/null +++ b/assets/js/b6ce023b.22d2187b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[59346],{33551:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>a});const o=JSON.parse('{"id":"operating-scs/components/status-page-openapi/docs/levels_of_consensus","title":"\\"Levels of consensus\\"","description":"When implementing any system to be used by a group of potential users, there will be varying use cases and opinions about API\'s, programming languages, persistence models, authentication, authorization, deployment options and so on.","source":"@site/docs/04-operating-scs/components/status-page-openapi/docs/levels_of_consensus.md","sourceDirName":"04-operating-scs/components/status-page-openapi/docs","slug":"/operating-scs/components/status-page-openapi/docs/levels_of_consensus","permalink":"/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-openapi/docs/levels_of_consensus.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Components","permalink":"/docs/operating-scs/components/status-page-openapi/docs/components"},"next":{"title":"Component Overview","permalink":"/docs/operating-scs/components/status-page-openapi/docs/component_overview"}}');var t=s(74848),i=s(28453);const l={},c='"Levels of consensus"',r={},a=[];function p(e){const n={h1:"h1",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"levels-of-consensus",children:'"Levels of consensus"'})}),"\n",(0,t.jsx)(n.p,{children:"When implementing any system to be used by a group of potential users, there will be varying use cases and opinions about API's, programming languages, persistence models, authentication, authorization, deployment options and so on.\nHence, building a complete one-fits-all solution is difficult, but (while offering a pretty un-opinionated reference implementation) even finding consensus on a few basic concepts may make adaptation and integration of different solutions possible."}),"\n",(0,t.jsx)(n.p,{children:'The "levels" of consensus could be split into:'}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Consensus on..."})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Resource Definition"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'"What is an incident?"'}),"\n",(0,t.jsx)(n.li,{children:"Core REST API Spec"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"General Architecture"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'"Monolithic Web App or multiple components?"'}),"\n",(0,t.jsx)(n.li,{children:'"Use static password file or rely on OIDC provider?"'}),"\n",(0,t.jsxs)(n.li,{children:["(If any:) Interfaces between components:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"AuthN mechanisms"}),"\n",(0,t.jsx)(n.li,{children:"AuthZ decisions"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Implementation of core component(s)"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'"Use reference implementation components?"'}),"\n",(0,t.jsx)(n.li,{children:'"Go vs. JavaScript?"'}),"\n",(0,t.jsx)(n.li,{children:'"Postgres vs. MySQL?"'}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Choice of all used components"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'"Policy: Istio vs. traefik?"'}),"\n",(0,t.jsx)(n.li,{children:'"Deployment: Helm vs. ansible?"'}),"\n",(0,t.jsx)(n.li,{children:'"dex vs. keycloak vs. zitadel?"'}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Every user of the Status Page (API) should be able to either make full use of the full reference implementation, building little to none on their own; Or just pick core concepts/API's/automation and build partial compatibility."}),"\n",(0,t.jsx)(n.p,{children:'E.g. while the value on agreeing on every aspect would bring the most value, this most likely is not likely to happen, but adopting only the "Resource Definition", should ideally bring value already.'})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>c});var o=s(96540);const t={},i=o.createContext(t);function l(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b6fc97b5.89dbb78c.js b/assets/js/b6fc97b5.89dbb78c.js new file mode 100644 index 0000000000..95f17098e2 --- /dev/null +++ b/assets/js/b6fc97b5.89dbb78c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[75717],{56676:t=>{t.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Tools","slug":"/category/tools","permalink":"/community/category/tools","sidebar":"community","navigation":{"previous":{"title":"SIG Standardization","permalink":"/community/collaboration/sig-standardization"},"next":{"title":"Jitsi","permalink":"/community/tools/jitsi"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/b74e5806.aaabaa3e.js b/assets/js/b74e5806.aaabaa3e.js new file mode 100644 index 0000000000..b66b581086 --- /dev/null +++ b/assets/js/b74e5806.aaabaa3e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[24730],{98768:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"iam/scs-0301","title":"scs-0301: Naming for domains/groups/roles/project when onboarding new customers","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iam/scs-0301.md","sourceDirName":"iam","slug":"/iam/scs-0301","permalink":"/standards/iam/scs-0301","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0300-v1-requirements-for-sso-identity-federation"},"next":{"title":"V1","permalink":"/standards/scs-0301-v1-naming-conventions"}}');var r=n(74848),o=n(28453);const d={},i="scs-0301: Naming for domains/groups/roles/project when onboarding new customers",a={},c=[];function l(e){const s={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"scs-0301-naming-for-domainsgroupsrolesproject-when-onboarding-new-customers",children:"scs-0301: Naming for domains/groups/roles/project when onboarding new customers"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0301-v1-naming-conventions",children:"scs-0301-v1"})}),(0,r.jsx)(s.td,{children:"Decision Record"}),(0,r.jsx)(s.td,{children:"Draft"}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>d,x:()=>i});var t=n(96540);const r={},o=t.createContext(r);function d(e){const s=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),t.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b77ceb62.e56cf4a5.js b/assets/js/b77ceb62.e56cf4a5.js new file mode 100644 index 0000000000..1aa07d4544 --- /dev/null +++ b/assets/js/b77ceb62.e56cf4a5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9689],{99502:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/ceilometer","title":"Ceilometer","description":"* Ceilometer admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/ceilometer.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/ceilometer","permalink":"/docs/iaas/guides/configuration-guide/openstack/ceilometer","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/ceilometer.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Ceilometer"},"sidebar":"docs","previous":{"title":"Barbican","permalink":"/docs/iaas/guides/configuration-guide/openstack/barbican"},"next":{"title":"Cinder","permalink":"/docs/iaas/guides/configuration-guide/openstack/cinder"}}');var o=i(74848),r=i(28453);const s={sidebar_label:"Ceilometer"},a="Ceilometer",c={},d=[];function l(e){const t={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"ceilometer",children:"Ceilometer"})}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://docs.openstack.org/ceilometer/latest/admin/index.html",children:"Ceilometer admin guide"})}),"\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://docs.openstack.org/ceilometer/latest/configuration/index.html",children:"Ceilometer configuration reference"})}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>a});var n=i(96540);const o={},r=n.createContext(o);function s(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b7cec31e.225821b8.js b/assets/js/b7cec31e.225821b8.js new file mode 100644 index 0000000000..47a97f9af5 --- /dev/null +++ b/assets/js/b7cec31e.225821b8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[57938],{8660:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>l,frontMatter:()=>r,metadata:()=>o,toc:()=>m});const o=JSON.parse('{"id":"collaboration/sig-community","title":"SIG Community","description":"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!","source":"@site/community/collaboration/sig-community.md","sourceDirName":"collaboration","slug":"/collaboration/sig-community","permalink":"/community/collaboration/sig-community","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"SIG Central API","permalink":"/community/collaboration/sig-central-api"},"next":{"title":"SIG Documentation","permalink":"/community/collaboration/sig-documentation"}}');var i=n(74848),a=n(28453);const r={},c="SIG Community",s={},m=[];function u(e){const t={h1:"h1",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"sig-community",children:"SIG Community"})}),"\n",(0,i.jsx)(t.p,{children:"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!"})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>c});var o=n(96540);const i={},a=o.createContext(i);function r(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b8c7b97f.0111641c.js b/assets/js/b8c7b97f.0111641c.js new file mode 100644 index 0000000000..742f082c3b --- /dev/null +++ b/assets/js/b8c7b97f.0111641c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[76443],{84212:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"iam/index","title":"Introduction on Identity Management and Federation in SCS","description":"Sovereign Cloud Stack wants to make it possible for operators to delegate","source":"@site/docs/05-iam/index.md","sourceDirName":"05-iam","slug":"/iam/","permalink":"/docs/iam/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/05-iam/index.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Metering Configuration","permalink":"/docs/operating-scs/metering/meter_configuration"},"next":{"title":"Guides","permalink":"/docs/category/guides-2"}}');var o=t(74848),s=t(28453);const a={},r="Introduction on Identity Management and Federation in SCS",l={},d=[{value:"Deployment",id:"deployment",level:2},{value:"Accessing Keycloak",id:"accessing-keycloak",level:2},{value:"Identity Mapping",id:"identity-mapping",level:2},{value:"SCS to SCS federation",id:"scs-to-scs-federation",level:2},{value:"Prerequisites and Requirements",id:"prerequisites-and-requirements",level:3},{value:"Features",id:"features",level:3},{value:"Limitations",id:"limitations",level:3},{value:"Current state and future Outlook",id:"current-state-and-future-outlook",level:3}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"introduction-on-identity-management-and-federation-in-scs",children:"Introduction on Identity Management and Federation in SCS"})}),"\n",(0,o.jsx)(n.p,{children:"Sovereign Cloud Stack wants to make it possible for operators to delegate\nadministration of user identities to the organizational entities that the\nusers are part of. Usually that's customer organizations but it could also\nbe the operator itself. Federation protocols like OpenID Connect can be used\nto achieve that goal. To simplify connecting the different parts of SCS\nto customer owned IAM solutions, the SCS reference implementation offers\nKeycloak as central Identity Provider (IdP) service."}),"\n",(0,o.jsx)(n.h2,{id:"deployment",children:"Deployment"}),"\n",(0,o.jsx)(n.p,{children:"Keycloak can be deployed by running"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply keycloak\n"})}),"\n",(0,o.jsx)(n.p,{children:"The required Keycloak client configuration that allows Keystone to obtain\nOIDC token from Keycloak needs to be deployed by running"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply keycloak-oidc-client-config\n"})}),"\n",(0,o.jsxs)(n.p,{children:["After these steps Keystone should be able to obtain token using the\nDevice Authorization Grant with PKCE, which is configured by default in the\n",(0,o.jsx)(n.code,{children:"wsgi-keystone.conf"})," deployed in SCS."]}),"\n",(0,o.jsx)(n.h2,{id:"accessing-keycloak",children:"Accessing Keycloak"}),"\n",(0,o.jsxs)(n.p,{children:["Currently deployed on the manager node, by default under ",(0,o.jsx)(n.code,{children:"https://keycloak.<yourdomain>"}),".\nDetails TODO."]}),"\n",(0,o.jsx)(n.h2,{id:"identity-mapping",children:"Identity Mapping"}),"\n",(0,o.jsxs)(n.p,{children:["The idea is that customer can create groups with specific names in their own IAM.\nThese shall be mapped to a claim ",(0,o.jsx)(n.code,{children:"groups"})," to be included in the OIDC token.\nVia the Keystone ",(0,o.jsx)(n.a,{href:"https://docs.openstack.org/keystone/latest/admin/federation/mapping_combinations.html",children:"mapping"}),"\nthey shall be mapped to roles on OpenStack projects.\n",(0,o.jsx)(n.a,{href:"https://docs.scs.community/contributor-docs/operations/iam/identity-federation-in-scs",children:"The corresponding section for Developers"})," may be interesting for more technical details.\nPlease be aware that currently there are still some technical challenges to be solved\nwithin the OpenStack Keystone mapping engine and the mapping rules to make this work\nseamlessly."]}),"\n",(0,o.jsx)(n.h2,{id:"scs-to-scs-federation",children:"SCS to SCS federation"}),"\n",(0,o.jsxs)(n.p,{children:["Federation between separate deployments of SCS is possible via the IdP by\nmeans of OpenID Connect.\nThe section on ",(0,o.jsx)(n.a,{href:"https://docs.scs.community/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations",children:"inter SCS federation setup"})," explains the required steps in some detail."]}),"\n",(0,o.jsx)(n.h3,{id:"prerequisites-and-requirements",children:"Prerequisites and Requirements"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Knowledge: Familiarity with Keycloak, OIDC federation, and basic SSL and web security principles is pivotal."}),"\n",(0,o.jsx)(n.li,{children:"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."}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"features",children:"Features"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Horizon Web SSO"}),"\n",(0,o.jsx)(n.li,{children:"OpenStack CLI use via the Device Authorization Grant"}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"limitations",children:"Limitations"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Keystone currently still has limitations in its mapping engine, which are addressed by the SCS development team as we\nsee possibilities and alignement with upstream OpenDev development plans. Automatically creating ",(0,o.jsx)(n.code,{children:"ephemeral"})," users in\ntheir specific OpenStack domains, as specified in their OIDC token is one example, currently beeing worked on. Please\ncheck carefully if the technical results meet the security demands of your specific environment."]}),"\n",(0,o.jsxs)(n.li,{children:["Keystone currently has another limitation which is being addressed by the SCS development team aligned\nwith upstream OpenDev development plans: The roles for federated users are stored on the database for the ",(0,o.jsx)(n.code,{children:"ephemeral"})," users\ncreated during a federated login. This limits the ability to modify users roles from the identity source directly, as roles of\nthe ",(0,o.jsx)(n.code,{children:"epehemeral"})," users do not get cleaned up or updated based on changes in the claims contained in the OpenID-Connect token."]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"current-state-and-future-outlook",children:"Current state and future Outlook"}),"\n",(0,o.jsx)(n.p,{children:"Currently SCS exemplifies deploying Keycloak on the management plane. This shall be moved to a Kubernetes based\nmanagement plane to improve scalability and architecture."}),"\n",(0,o.jsx)(n.p,{children:"In the near future, the Container layer shall be able to make use of the IdP to allow federated users to access Kubernetes.\nIn the mid term, workloads on Kubernetes shall be able to make use of OAuth tokens to access resources on the IaaS layer."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var i=t(96540);const o={},s=i.createContext(o);function a(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b8fd74b5.d750270a.js b/assets/js/b8fd74b5.d750270a.js new file mode 100644 index 0000000000..00863ad1a0 --- /dev/null +++ b/assets/js/b8fd74b5.d750270a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[93153],{92406:(n,e,a)=>{a.r(e),a.d(e,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"iaas/components/sandbox-manager","title":"Sandbox Manager","description":"","source":"@site/docs/02-iaas/components/sandbox-manager.md","sourceDirName":"02-iaas/components","slug":"/iaas/components/sandbox-manager","permalink":"/docs/iaas/components/sandbox-manager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/sandbox-manager.md","tags":[],"version":"current","sidebarPosition":54,"frontMatter":{"sidebar_label":"Sandbox Manager","sidebar_position":54}}');var t=a(74848),s=a(28453);const r={sidebar_label:"Sandbox Manager",sidebar_position:54},c="Sandbox Manager",i={},d=[];function m(n){const e={h1:"h1",header:"header",...(0,s.R)(),...n.components};return(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"sandbox-manager",children:"Sandbox Manager"})})}function u(n={}){const{wrapper:e}={...(0,s.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(m,{...n})}):m(n)}},28453:(n,e,a)=>{a.d(e,{R:()=>r,x:()=>c});var o=a(96540);const t={},s=o.createContext(t);function r(n){const e=o.useContext(s);return o.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(t):n.components||t:r(n.components),o.createElement(s.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/bba00861.4c43338c.js b/assets/js/bba00861.4c43338c.js new file mode 100644 index 0000000000..7ba3782c9f --- /dev/null +++ b/assets/js/bba00861.4c43338c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[28439],{11885:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Pentesting KaaS","slug":"/category/pentesting-kaas","permalink":"/docs/category/pentesting-kaas","sidebar":"docs","navigation":{"previous":{"title":"Using Automated Pentesting Reports for CSPs, Operators, and Users","permalink":"/docs/operating-scs/components/automated-pentesting-iaas/reports"},"next":{"title":"Overview","permalink":"/docs/operating-scs/components/automated-pentesting-kaas/overview"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/bccb1b42.d92c74a9.js b/assets/js/bccb1b42.d92c74a9.js new file mode 100644 index 0000000000..6a0290be66 --- /dev/null +++ b/assets/js/bccb1b42.d92c74a9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[56986],{68002:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"container/components/container-registry/docs/migration","title":"Migration","description":"harbormigration.png","source":"@site/docs/03-container/components/container-registry/docs/migration.md","sourceDirName":"03-container/components/container-registry/docs","slug":"/container/components/container-registry/docs/migration","permalink":"/docs/container/components/container-registry/docs/migration","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/migration.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Backup and restore","permalink":"/docs/container/components/container-registry/docs/backup_and_restore"},"next":{"title":"Persistence","permalink":"/docs/container/components/container-registry/docs/persistence"}}');var s=r(74848),o=r(28453);const i={},a="Migration",c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Kubernetes clusters",id:"kubernetes-clusters",level:3},{value:"S3 bucket and EC2 credentials",id:"s3-bucket-and-ec2-credentials",level:3},{value:"Velero client",id:"velero-client",level:3},{value:"Velero server",id:"velero-server",level:3},{value:"Migration",id:"migration-1",level:2}];function d(e){const n={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"migration",children:"Migration"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"harbor_migration.png",src:r(26763).A+"",width:"721",height:"243"})}),"\n",(0,s.jsxs)(n.p,{children:["This page aims at providing a step-by-step guide for lift and shift migration of ",(0,s.jsx)(n.a,{href:"https://goharbor.io/",children:"Harbor"}),"\ncontainer registry, which operates in the Kubernetes environment and is deployed with Helm.\nThis migration scenario uses ",(0,s.jsx)(n.a,{href:"https://velero.io/",children:"Velero"})," tool which\nenables moving your Harbor instance as-is from one Kubernetes environment to another\nKubernetes environment. The motivation behind this could be e.g. migration\nfrom one cloud provider to another, an outdated Kubernetes environment of your Harbor\ninstance or avoiding the Harbor in-place upgrade."]}),"\n",(0,s.jsxs)(n.p,{children:["Note that the official Harbor's documentation contains an \"",(0,s.jsx)(n.a,{href:"https://goharbor.io/docs/main/administration/upgrade/",children:"Upgrade Harbor and Migrate Data"}),'" page\nthat instructs users on how to upgrade and migrate Harbor data from one instance to\nanother. This tutorial supports only deployments that have been installed by ',(0,s.jsx)(n.a,{href:"https://goharbor.io/docs/main/install-config/download-installer/",children:"Harbor installer"})," script.\nHence, Harbor instances running in docker containers and spawned by docker-compose."]}),"\n",(0,s.jsxs)(n.p,{children:["Note that this guide is not limited to Harbor deployments that utilize SCS environments.\nVisit the ",(0,s.jsx)(n.a,{href:"#prerequisites",children:"prerequisites"})," section to see what is required for a successful\nmigration. These prerequisites come out of the box when the SCS infrastructure and KaaS\nare used for Harbor deployment, hence it is convenient to use them."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["As this scenario uses a backup and restore procedure for the migration process, this section\nrefers to the prerequisites section in ",(0,s.jsx)(n.a,{href:"/docs/container/components/container-registry/docs/backup_and_restore#prerequisites",children:"Harbor - backup and restore"}),"\ndocs page."]}),"\n",(0,s.jsx)(n.h3,{id:"kubernetes-clusters",children:"Kubernetes clusters"}),"\n",(0,s.jsx)(n.p,{children:"This migration scenario expects that you want to migrate your Harbor instance\nbetween different Kubernetes clusters that could live in different environments (e.g.\nOpenStack projects) or even in different cloud providers. Let's call them Cluster_A and\nCluster_B. Cluster_A represents the Kubernetes cluster where your Harbor currently operates and\nCluster_B represents the target Kubernetes cluster to which you want to migrate your Harbor."}),"\n",(0,s.jsxs)(n.p,{children:["As Cluster_A and Cluster_B do not have to share the same infrastructure it is convenient to\nuse a full Harbor data backup (not a snapshot) using ",(0,s.jsx)(n.a,{href:"https://restic.net/",children:"Restic"}),"\nintegration in Velero. In this case, Cluster_A and Cluster_B should have\nKubernetes version ",(0,s.jsx)(n.strong,{children:"1.16"})," or greater.\nFor further details about Restic-Velero integration refer to the",(0,s.jsx)(n.br,{}),"\n","related ",(0,s.jsx)(n.a,{href:"https://velero.io/docs/main/file-system-backup/",children:"Velero docs"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Kubernetes versions of Cluster_A and Cluster_B may differ. In this case, it is\nnot unusual to see the Kubernetes API group versions differing between clusters. This\nincompatibility may cause issues during the migration of your Harbor instance. By default,\nVelero only backs up resources that use the preferred version of the Kubernetes API.\nHowever, Velero also includes a feature, ",(0,s.jsx)(n.a,{href:"https://velero.io/docs/main/enable-api-group-versions-feature/",children:"Enable API Group Versions"}),",\nthat overcomes this limitation and backup all Kubernetes API group versions that are\nsupported on the source Cluster_A. Then, if this feature is also enabled on the Cluster_B,\nVelero will make the best choice of Kubernetes API version which is defined in the group\nname of both source Cluster_A and target Cluster_B based on API group version priority order,\nread ",(0,s.jsx)(n.a,{href:"https://velero.io/docs/main/enable-api-group-versions-feature/",children:"docs"})," for further details.\nIf the above is the case consider installing Velero on both clusters\nwith a feature flag ",(0,s.jsx)(n.code,{children:"--features=EnableAPIGroupVersions"}),". Note that this feature is still in beta."]}),"\n",(0,s.jsx)(n.h3,{id:"s3-bucket-and-ec2-credentials",children:"S3 bucket and EC2 credentials"}),"\n",(0,s.jsxs)(n.p,{children:["This guide assumes that the public cloud's object store with S3-compatible API is available as\nthe storage backend for Velero. Refer to the ",(0,s.jsx)(n.a,{href:"/docs/container/components/container-registry/docs/backup_and_restore#s3-bucket-and-ec2-credentials",children:"S3 bucket and EC2 credentials"}),"\nsection in the backup and restore docs and create a bucket that will be later used for\nthe migration."]}),"\n",(0,s.jsx)(n.h3,{id:"velero-client",children:"Velero client"}),"\n",(0,s.jsxs)(n.p,{children:["Install the Velero client on your local environment, refer to ",(0,s.jsx)(n.a,{href:"/docs/container/components/container-registry/docs/backup_and_restore#velero-client",children:"Velero client"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"velero-server",children:"Velero server"}),"\n",(0,s.jsxs)(n.p,{children:["Install Velero server components along with the appropriate plugins, into the both\n(Cluster_A and Cluster_B) clusters. Keep in mind that we will use Restic uploader in\nVelero, hence follows interactions on how to do that in the related docs section ",(0,s.jsx)(n.a,{href:"/docs/container/components/container-registry/docs/backup_and_restore#velero-server",children:"Velero server"}),".\nDo not forget to add ",(0,s.jsx)(n.code,{children:"--kubeconfig"})," argument to install Velero server components\nto the Cluster_A and then to the Cluster_B. The rest of arguments should be the same:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'velero install \\\n --kubeconfig <path to the kubeconfig file of Cluster_[A,B]> \\ \n --provider aws \\\n --plugins velero/velero-plugin-for-aws:v1.6.1 \\\n --bucket velero-backup \\\n --secret-file ~/.aws/credentials \\\n --use-volume-snapshots=false \\\n --uploader-type=restic \\\n --use-node-agent \\\n --backup-location-config region=RegionOne,s3ForcePathStyle="true",s3Url=https://api.gx-scs.sovereignit.cloud:8080\n'})}),"\n",(0,s.jsxs)(n.p,{children:["It is a good practice to configure the backup location in the Cluster_B as read-only.\nThis will make sure that the backup created from Cluster_A is not deleted from the object\nstore by mistake during the restore to Cluster_B. To do this you can just edit the ",(0,s.jsx)(n.code,{children:"default"}),"\nBackupStorageLocation resource in Cluster_B."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ kubectl -n velero --kubeconfig <path of Cluster_B kubeconfig> edit backupstoragelocations default\n# Set the `accessMode` to `ReadOnly`\n# spec:\n# accessMode: ReadOnly\n"})}),"\n",(0,s.jsx)(n.h2,{id:"migration-1",children:"Migration"}),"\n",(0,s.jsxs)(n.p,{children:["Before we start to migrate Harbor instance from one environment to another go through the\n",(0,s.jsx)(n.a,{href:"/docs/container/components/container-registry/docs/backup_and_restore#backup-and-restore",children:"Backup and restore"})," section and read\nvarious limitations of the backup/restore process to be aware of the potential impact on\nyour Harbor instance."]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Backup Harbor instance in Cluster_A","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsxs)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#set-harbor-to-readonly",children:["Set Harbor to the ",(0,s.jsx)(n.code,{children:"ReadOnly"})," mode"]})}),"\n",(0,s.jsxs)(n.li,{children:["Exclude the volume of Redis in backup in Cluster_A","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# replace the namespace and pod name with yours\nkubectl -n default --kubeconfig <path of Cluster_A kubeconfig> annotate pod/harbor-harbor-redis-0 backup.velero.io/backup-volumes-excludes=data\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Back up Harbor in Cluster_A","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"velero backup create harbor-backup --kubeconfig <path of Cluster_A kubeconfig> --include-namespaces default --default-volumes-to-fs-backup --wait\n"})}),"\n","This creates a full backup of all resources in the given namespace including their\npersistent storages (besides Redis PV)."]}),"\n",(0,s.jsxs)(n.li,{children:["Optionally: ",(0,s.jsxs)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#unset-readonly",children:["Unset Harbor from the ",(0,s.jsx)(n.code,{children:"ReadOnly"})," mode"]}),".\nKeep in mind that the ",(0,s.jsx)(n.code,{children:"ReadOnly"})," mode protects your Harbor instance from deleting\nrepository, artifact, tag, and pushing images. This ensures that the Harbor instance\nin Cluster_A will be in sync with the Harbor instance in Cluster_B after you restored\nHarbor instance from the backup in Cluster_B. Therefore, it is recommended to ",(0,s.jsx)(n.strong,{children:"not"}),"\nunset Harbor from the ",(0,s.jsx)(n.code,{children:"ReadOnly"})," mode in Cluster_A."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Restore Harbor instance in Cluster_B","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Restore from the Backup","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# replace the backup and restore names with yours\nvelero restore create harbor-restore --from-backup harbor-backup --kubeconfig <path of Cluster_B kubeconfig> --wait \n"})}),"\n","Velero backed up the whole namespace where the Harbor instance lives in Cluster_A,\ntherefore the restored namespace in Cluster_B may contain resources (e.g. service,\ningress, TLS certificates) that expose Harbor instance in the same way as in\nCluster_A. It is a good practice to test this Cluster_B instance before you allow\nusers to use it."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsxs)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#unset-readonly",children:["Unset Harbor from the ",(0,s.jsx)(n.code,{children:"ReadOnly"})," mode"]}),".\nAs we set Harbor in Cluster_A to ReadOnly when doing the backup, the instance is\nstill in ReadOnly mode after restoring. Unset Harbor from the ReadOnly mode after\nyou check its functionality."]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},26763:(e,n,r)=>{r.d(n,{A:()=>t});const t=r.p+"assets/images/harbor_migration-15d83bf7e5b37c0bdcb698280dde0684.png"},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>a});var t=r(96540);const s={},o=t.createContext(s);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bceb927f.22ef34a7.js b/assets/js/bceb927f.22ef34a7.js new file mode 100644 index 0000000000..ef3c05bbf9 --- /dev/null +++ b/assets/js/bceb927f.22ef34a7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[78081],{12162:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>s,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/neutron","title":"Neutron","description":"* Neutron admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/neutron.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/neutron","permalink":"/docs/iaas/guides/configuration-guide/openstack/neutron","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/neutron.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Neutron"},"sidebar":"docs","previous":{"title":"Manila","permalink":"/docs/iaas/guides/configuration-guide/openstack/manila"},"next":{"title":"Nova","permalink":"/docs/iaas/guides/configuration-guide/openstack/nova"}}');var o=t(74848),r=t(28453);const s={sidebar_label:"Neutron"},a="Neutron",c={},d=[{value:"MTU Considerations",id:"mtu-considerations",level:2}];function u(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...n.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(e.header,{children:(0,o.jsx)(e.h1,{id:"neutron",children:"Neutron"})}),"\n",(0,o.jsxs)(e.ul,{children:["\n",(0,o.jsx)(e.li,{children:(0,o.jsx)(e.a,{href:"https://docs.openstack.org/neutron/latest/admin/index.html",children:"Neutron admin guide"})}),"\n",(0,o.jsx)(e.li,{children:(0,o.jsx)(e.a,{href:"https://docs.openstack.org/neutron/latest/configuration/index.html",children:"Neutron configuration guide"})}),"\n",(0,o.jsx)(e.li,{children:(0,o.jsx)(e.a,{href:"https://docs.openstack.org/neutron/latest/configuration/config.html",children:"Neutron configuration reference"})}),"\n"]}),"\n",(0,o.jsx)(e.p,{children:"Neutron-Dynamic-Routing:"}),"\n",(0,o.jsxs)(e.ul,{children:["\n",(0,o.jsx)(e.li,{children:(0,o.jsx)(e.a,{href:"https://docs.openstack.org/neutron-dynamic-routing/latest/admin/index.html",children:"Neutron-Dynamic-Routing admin guide"})}),"\n",(0,o.jsx)(e.li,{children:(0,o.jsx)(e.a,{href:"https://docs.openstack.org/neutron-dynamic-routing/latest/configuration/index.html",children:"Neutron-Dynamic-Routing configuration guide"})}),"\n",(0,o.jsx)(e.li,{children:(0,o.jsx)(e.a,{href:"https://docs.openstack.org/neutron-dynamic-routing/latest/configuration/bgp_dragent.html",children:"Neutron-Dynamic-Routing configuration reference"})}),"\n"]}),"\n",(0,o.jsx)(e.p,{children:"Neutron-VPNaaS:"}),"\n",(0,o.jsxs)(e.ul,{children:["\n",(0,o.jsx)(e.li,{children:(0,o.jsx)(e.a,{href:"https://docs.openstack.org/neutron-vpnaas/latest/admin/index.html",children:"Neutron-VPNaaS admin guide"})}),"\n",(0,o.jsx)(e.li,{children:(0,o.jsx)(e.a,{href:"https://docs.openstack.org/neutron-vpnaas/latest/configuration/index.html",children:"Neutron-VPNaaS configuration guide"})}),"\n"]}),"\n",(0,o.jsx)(e.h2,{id:"mtu-considerations",children:"MTU Considerations"}),"\n",(0,o.jsx)(e.p,{children:"Neutron uses the MTU of the underlying physical network to calculate the MTU for virtual network\ncomponents including instance network interfaces. By default, it assumes a standard 1500-byte MTU\nfor the underlying physical network."}),"\n",(0,o.jsx)(e.p,{children:"Neutron only references the underlying physical network MTU. Changing the underlying physical network\ndevice MTU requires configuration of physical network devices such as switches and routers."}),"\n",(0,o.jsxs)(e.p,{children:["The configuration is described in the ",(0,o.jsx)(e.a,{href:"https://docs.openstack.org/neutron/latest/admin/config-mtu.html",children:"Neutron admin guide"}),".\nThe configuration files are placed under ",(0,o.jsx)(e.code,{children:"environments/kolla/files/overlays/neutron/ml2_conf.ini"}),"\nand ",(0,o.jsx)(e.code,{children:"environments/kolla/files/overlays/neutron.conf"}),"."]})]})}function l(n={}){const{wrapper:e}={...(0,r.R)(),...n.components};return e?(0,o.jsx)(e,{...n,children:(0,o.jsx)(u,{...n})}):u(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>s,x:()=>a});var i=t(96540);const o={},r=i.createContext(o);function s(n){const e=i.useContext(r);return i.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function a(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(o):n.components||o:s(n.components),i.createElement(r.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/bd319452.ead4aaf5.js b/assets/js/bd319452.ead4aaf5.js new file mode 100644 index 0000000000..0513f4fa0e --- /dev/null +++ b/assets/js/bd319452.ead4aaf5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[66971],{975:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>r,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>d,toc:()=>c});const d=JSON.parse('{"id":"iaas/guides/deploy-guide/examples/testbed","title":"Testbed","description":"This section has moved. You can now find the content in the","source":"@site/docs/02-iaas/guides/deploy-guide/examples/testbed.md","sourceDirName":"02-iaas/guides/deploy-guide/examples","slug":"/iaas/guides/deploy-guide/examples/testbed","permalink":"/docs/iaas/guides/deploy-guide/examples/testbed","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/examples/testbed.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Testbed"},"sidebar":"docs","previous":{"title":"Cloud in a Box","permalink":"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box"},"next":{"title":"Upgrade Guide","permalink":"/docs/iaas/guides/upgrade-guide/"}}');var n=t(74848),i=t(28453);const o={sidebar_label:"Testbed"},a="Testbed",r={},c=[];function u(e){const s={a:"a",h1:"h1",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"testbed",children:"Testbed"})}),"\n",(0,n.jsxs)(s.p,{children:["This section has moved. You can now find the content in the\n",(0,n.jsx)(s.a,{href:"/docs/iaas/guides/other-guides/",children:"Other Guides"})," as\n",(0,n.jsx)(s.a,{href:"../../other-guides/testbed/",children:"Testbed Guide"}),"."]})]})}function l(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>o,x:()=>a});var d=t(96540);const n={},i=d.createContext(n);function o(e){const s=d.useContext(i);return d.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),d.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bd8a0ffe.88762ccc.js b/assets/js/bd8a0ffe.88762ccc.js new file mode 100644 index 0000000000..1410e2139b --- /dev/null +++ b/assets/js/bd8a0ffe.88762ccc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[24497],{43355:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"scs-0101-w1-entropy-implementation-testing","title":"SCS Entropy: Implementation and Testing Notes","description":"Implementation notes","source":"@site/standards/scs-0101-w1-entropy-implementation-testing.md","sourceDirName":".","slug":"/scs-0101-w1-entropy-implementation-testing","permalink":"/standards/scs-0101-w1-entropy-implementation-testing","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Entropy: Implementation and Testing Notes","type":"Supplement","track":"IaaS","status":"Draft","supplements":["scs-0101-v1-entropy.md"]},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0101-v1-entropy"},"next":{"title":"scs-0102: SCS Image Metadata","permalink":"/standards/iaas/scs-0102"}}');var r=t(74848),i=t(28453);const a={title:"SCS Entropy: Implementation and Testing Notes",type:"Supplement",track:"IaaS",status:"Draft",supplements:["scs-0101-v1-entropy.md"]},o=void 0,l={},c=[{value:"Implementation notes",id:"implementation-notes",level:2},{value:"Automated tests",id:"automated-tests",level:2},{value:"Images sample",id:"images-sample",level:3},{value:"Errors",id:"errors",level:3},{value:"Warnings",id:"warnings",level:3},{value:"Implementation",id:"implementation",level:3},{value:"Manual tests",id:"manual-tests",level:2}];function d(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"implementation-notes",children:"Implementation notes"}),"\n",(0,r.jsx)(n.p,{children:"With reasonably recent hardware\u2014x86 CPU with RDRAND/RDSEED (Intel from 2012,\nAMD from 2015) or ARM CPU with FEAT_RNG or FEAT_RNG_TRAP\u2014and recent VM image\u2014Linux\nkernel 5.18 or higher\u2014, there is (almost) nothing to be done."}),"\n",(0,r.jsx)(n.p,{children:"Only the flavor and image attributes required by the standard have to be set:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["flavor extra_spec: ",(0,r.jsx)(n.code,{children:"hw_rng:allowed=True"})," ,"]}),"\n",(0,r.jsxs)(n.li,{children:["image property: ",(0,r.jsx)(n.code,{children:"hw_rng_model: virtio"})," ."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"automated-tests",children:"Automated tests"}),"\n",(0,r.jsx)(n.h3,{id:"images-sample",children:"Images sample"}),"\n",(0,r.jsx)(n.p,{children:"Some checks need to be performed on a live instance. For these checks, it is\nnecessary to choose a sample of VM images to test on."}),"\n",(0,r.jsx)(n.p,{children:"For the time being, the sample MUST contain at least one public image reported\nby OpenStack. This may be extended in the future."}),"\n",(0,r.jsx)(n.h3,{id:"errors",children:"Errors"}),"\n",(0,r.jsx)(n.p,{children:"For every image in the chosen sample, the following items MUST be detected and\nreported as an error:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["the service ",(0,r.jsx)(n.code,{children:"rngd"})," is not running,"]}),"\n",(0,r.jsxs)(n.li,{children:["the special file ",(0,r.jsx)(n.code,{children:"/proc/sys/kernel/random/entropy_avail"})," does not contain\nthe value 256 (pinned since kernel 5.18),"]}),"\n",(0,r.jsxs)(n.li,{children:["the number of FIPS 140-2 failures exceeds 3 out of 1000 blocks\ntested, as determined by ",(0,r.jsx)(n.code,{children:"cat /dev/random | rngtest -c 1000"})," ."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Note: The latter two items act as surrogates for the following item, which\ncannot be detected directly:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"CPU instructions for accessing entropy are not available to the VMs."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"warnings",children:"Warnings"}),"\n",(0,r.jsx)(n.p,{children:"The following items MUST be detected and reported as a warning:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["any flavor missing the attribute ",(0,r.jsx)(n.code,{children:"hw_rng:allowed=True"}),","]}),"\n",(0,r.jsxs)(n.li,{children:["any image missing the attribute ",(0,r.jsx)(n.code,{children:"hw_rng_model: virtio"}),","]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Note that the requirement regarding the kernel patch level will not be\nchecked, because of two reasons: (a) we already check the file ",(0,r.jsx)(n.code,{children:"entropy_avail"}),"\n(see subsection on Errors), and (b) users can always choose a recent image,\nas ensured by the image metadata standard."]}),"\n",(0,r.jsx)(n.h3,{id:"implementation",children:"Implementation"}),"\n",(0,r.jsxs)(n.p,{children:["The script ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/entropy/entropy-check.py",children:(0,r.jsx)(n.code,{children:"entropy-check.py"})}),"\nconnects to OpenStack and performs the checks described in this section."]}),"\n",(0,r.jsx)(n.h2,{id:"manual-tests",children:"Manual tests"}),"\n",(0,r.jsx)(n.p,{children:"None."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var s=t(96540);const r={},i=s.createContext(r);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bd8a97c5.eafa0cca.js b/assets/js/bd8a97c5.eafa0cca.js new file mode 100644 index 0000000000..941fe78938 --- /dev/null +++ b/assets/js/bd8a97c5.eafa0cca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[43536],{85819:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"iaas/guides/configuration-guide/proxy","title":"Proxy","description":"In the following examples, it is assumed that the Squid proxy integrated by OSISM","source":"@site/docs/02-iaas/guides/configuration-guide/proxy.md","sourceDirName":"02-iaas/guides/configuration-guide","slug":"/iaas/guides/configuration-guide/proxy","permalink":"/docs/iaas/guides/configuration-guide/proxy","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/proxy.md","tags":[],"version":"current","sidebarPosition":15,"frontMatter":{"sidebar_label":"Proxy","sidebar_position":15},"sidebar":"docs","previous":{"title":"Network","permalink":"/docs/iaas/guides/configuration-guide/network"},"next":{"title":"Loadbalancer","permalink":"/docs/iaas/guides/configuration-guide/loadbalancer"}}');var o=t(74848),a=t(28453);const r={sidebar_label:"Proxy",sidebar_position:15},i="Proxy",l={},c=[{value:"Deployment of a Squid Proxy Server",id:"deployment-of-a-squid-proxy-server",level:2},{value:"Configurations",id:"configurations",level:2},{value:"Docker",id:"docker",level:3},{value:"APT",id:"apt",level:3},{value:"OpenStack",id:"openstack",level:3},{value:"Kubernetes / K3s",id:"kubernetes--k3s",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"proxy",children:"Proxy"})}),"\n",(0,o.jsxs)(n.p,{children:["In the following examples, it is assumed that the Squid proxy integrated by OSISM\nis used on the first manager node. Any other proxy accessible from the nodes can\nalso be used here. ",(0,o.jsx)(n.code,{children:"http://{{ groups['manager'][0] }}:3128"})," which is used here as an\nexample is then replaced accordingly with the address of the proxy."]}),"\n",(0,o.jsx)(n.h2,{id:"deployment-of-a-squid-proxy-server",children:"Deployment of a Squid Proxy Server"}),"\n",(0,o.jsx)(n.p,{children:"The Squid service can be deployed on the first manager. This is useful if no proxy\ncan be used in the environment. The first manager node is then used by all other nodes\nas a pass-through node. Please note that this is not a caching proxy or even an air gap.\nThis is also possible with OSISM, but not with the help of the Squid service."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply squid\n"})}),"\n",(0,o.jsx)(n.h2,{id:"configurations",children:"Configurations"}),"\n",(0,o.jsx)(n.p,{children:"It is advisable to exclude hosts that are locally accessible from using the HTTP proxy\nif they use HTTP(S) communication, as otherwise communication will take place unnecessarily via the\nproxy. In some cases the proxy does not have access to the internal networks (this depends on its location),\nbut this can also lead to higher latencies or to inferred availability problems\nif the proxy is temporarily unavailable."}),"\n",(0,o.jsxs)(n.admonition,{type:"warning",children:[(0,o.jsxs)(n.p,{children:["As ",(0,o.jsx)(n.a,{href:"https://about.gitlab.com/blog/2021/01/27/we-need-to-talk-no-proxy/#no_proxy",children:"Gitlab has described in 2021"}),", there are subtle differences depending on the technology, implementation and age as to whether environment variables should be lowercase or uppercase, or what types of exclusions are possible."]}),(0,o.jsx)(n.p,{children:"Furthermore, the documentation of certain implementations is not very clear in its statements."}),(0,o.jsxs)(n.p,{children:["It usually makes sense to exclude all ",(0,o.jsx)(n.a,{href:"https://www.rfc-editor.org/rfc/rfc1918",children:"private ipv4 networks"})," when the involved technology supports this\nbecause these private networks or network areas are typicall relatively rarely accessed via a proxy anyway but there is a high potential that a network\nwhich is required to be reached directly is overlooked."]})]}),"\n",(0,o.jsx)(n.p,{children:"We therefore try to choose the clearest examples possible."}),"\n",(0,o.jsxs)(n.p,{children:["The example domain ",(0,o.jsx)(n.code,{children:"landscape.example.com"})," is used for hosts of the following names:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.code,{children:"api.zone1.landscape.example.com"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.code,{children:"api-internal.zone1.landscape.example.com"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.code,{children:"manager.landscape.example.com"})}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"docker",children:"Docker"}),"\n",(0,o.jsx)(n.p,{children:"This allows Docker images to be pulled via a proxy."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:'##########################################################\n# proxy\n\ndocker_configure_proxy: true\ndocker_proxy_http: "http://{{ groups[\'manager\'][0] }}:3128"\ndocker_proxy_https: "{{ docker_proxy_http }}"\n\n# Due to the fact, that Golang supports CIDR blocks its a good idea to exclude local networks,\n# there might be cases where CIDR excludes are ignored when calling non-golang binaries.\ndocker_proxy_no_proxy_extra:\n - landscape.example.com\n - "10.0.0.0/8"\n - "172.16.0.0/12"\n - "192.168.0.0/16"\n'})}),"\n",(0,o.jsx)(n.h3,{id:"apt",children:"APT"}),"\n",(0,o.jsx)(n.p,{children:"This allows APT packages to be downloaded via a proxy."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"##########################################################\n# proxy\n\nproxy_proxies:\n http: \"http://{{ groups['manager'][0] }}:3128\"\n https: \"http://{{ groups['manager'][0] }}:3128\"\n\n# Due to the fact, that APT and libcurl does not support CIDR blocks, we cannot use global excludes\n# using CIDR expressions\nproxy_no_proxy_extra:\n - landscape.example.com\n"})}),"\n",(0,o.jsx)(n.h3,{id:"openstack",children:"OpenStack"}),"\n",(0,o.jsx)(n.p,{children:"Proxy settings for containers such as Magnum that need internet access."}),"\n",(0,o.jsxs)(n.p,{children:["Exclude all internal adresses, ",(0,o.jsx)(n.em,{children:"especially"})," the internal api endpoint."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'##########################################################\n# proxy\n\ncontainer_http_proxy: "http://{{ groups[\'manager\'][0] }}:3128"\ncontainer_https_proxy: "http://{{ groups[\'manager\'][0] }}:3128"\n\n# Due to the fact, that openstacks relies on python, we cannot trust that global CIDR\n# excludes are working in general but it they don\'t harm\ncontainer_no_proxy: "localhost,127.0.0.1,landscape.example.com,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"\n'})}),"\n",(0,o.jsx)(n.h3,{id:"kubernetes--k3s",children:"Kubernetes / K3s"}),"\n",(0,o.jsxs)(n.p,{children:["Settings for the OSISM Kubernetes cluster, which is operated independently of Openstack.\nThese settings affect all http and https requests of the K3s installation as they are passed as environment variables via the systemd unit.\nFor this reason, ",(0,o.jsx)(n.code,{children:"NO_PROXY"})," must be configured so that the network between the K8S nodes is explicitly excluded."]}),"\n",(0,o.jsx)(n.p,{children:"An example:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:'##########################################################\n# proxy\n\nproxy_env:\n HTTP_PROXY: "http://{{ groups[\'manager\'][0] }}:3128"\n HTTPS_PROXY: "http://{{ groups[\'manager\'][0] }}:3128"\n # Due to the fact, that k8s is based on Golang supports CIDR blocks its a good idea to exclude local networks,\n # there might be really rare cases where CIDR excludes are ignored when calling non-golang binaries.\n NO_PROXY: "localhost,127.0.0.1,landscape.example.com,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"\n'})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var s=t(96540);const o={},a=s.createContext(o);function r(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bdaaff35.ab3b1d93.js b/assets/js/bdaaff35.ab3b1d93.js new file mode 100644 index 0000000000..edae6a26cb --- /dev/null +++ b/assets/js/bdaaff35.ab3b1d93.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[49063],{75305:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"iaas/guides/user-guide/openstack/index","title":"OpenStack","description":"","source":"@site/docs/02-iaas/guides/user-guide/openstack/index.md","sourceDirName":"02-iaas/guides/user-guide/openstack","slug":"/iaas/guides/user-guide/openstack/","permalink":"/docs/iaas/guides/user-guide/openstack/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/openstack/index.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"OpenStack"},"sidebar":"docs","previous":{"title":"Migrate from VMware ESXi to OpenStack","permalink":"/docs/iaas/guides/user-guide/migration-vmware-esxi"},"next":{"title":"Install instance from ISO image","permalink":"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso"}}');var a=s(74848),i=s(28453);const o={sidebar_label:"OpenStack"},r="OpenStack",c={},d=[];function u(e){const t={h1:"h1",header:"header",...(0,i.R)(),...e.components};return(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"openstack",children:"OpenStack"})})}function p(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>r});var n=s(96540);const a={},i=n.createContext(a);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/be01f2a0.04e74b46.js b/assets/js/be01f2a0.04e74b46.js new file mode 100644 index 0000000000..daffeb68bc --- /dev/null +++ b/assets/js/be01f2a0.04e74b46.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[89954],{23739:(e,a,n)=>{n.r(a),n.d(a,{assets:()=>s,contentTitle:()=>t,default:()=>l,frontMatter:()=>o,metadata:()=>r,toc:()=>m});const r=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/keystone","title":"Keystone","description":"* Keystone admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/keystone.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/keystone","permalink":"/docs/iaas/guides/configuration-guide/openstack/keystone","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/keystone.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Keystone"},"sidebar":"docs","previous":{"title":"Ironic","permalink":"/docs/iaas/guides/configuration-guide/openstack/ironic"},"next":{"title":"Magnum","permalink":"/docs/iaas/guides/configuration-guide/openstack/magnum"}}');var i=n(74848),d=n(28453);const o={sidebar_label:"Keystone"},t="Keystone",s={},m=[{value:"Domain manager policy",id:"domain-manager-policy",level:2},{value:"OIDC Federation",id:"oidc-federation",level:2}];function _(e){const a={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(a.header,{children:(0,i.jsx)(a.h1,{id:"keystone",children:"Keystone"})}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:(0,i.jsx)(a.a,{href:"https://docs.openstack.org/keystone/latest/admin/index.html",children:"Keystone admin guide"})}),"\n",(0,i.jsx)(a.li,{children:(0,i.jsx)(a.a,{href:"https://docs.openstack.org/keystone/latest/configuration/index.html",children:"Keystone configuration reference"})}),"\n"]}),"\n",(0,i.jsx)(a.h2,{id:"domain-manager-policy",children:"Domain manager policy"}),"\n",(0,i.jsx)(a.p,{children:(0,i.jsx)(a.strong,{children:"This policy is currently still in draft status. Its use in production is currently not recommended."})}),"\n",(0,i.jsxs)(a.table,{children:[(0,i.jsx)(a.thead,{children:(0,i.jsxs)(a.tr,{children:[(0,i.jsx)(a.th,{style:{textAlign:"left"},children:"SCS Standard Track"}),(0,i.jsx)(a.th,{style:{textAlign:"left"},children:"SCS Standard"}),(0,i.jsx)(a.th,{style:{textAlign:"left"},children:"SCS Documentation"})]})}),(0,i.jsx)(a.tbody,{children:(0,i.jsxs)(a.tr,{children:[(0,i.jsx)(a.td,{style:{textAlign:"left"},children:(0,i.jsx)(a.a,{href:"https://docs.scs.community/standards/iam/",children:"IAM"})}),(0,i.jsx)(a.td,{style:{textAlign:"left"},children:(0,i.jsx)(a.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0302-v1-domain-manager-role.md",children:"scs-0302"})}),(0,i.jsx)(a.td,{style:{textAlign:"left"},children:(0,i.jsx)(a.a,{href:"https://docs.scs.community/standards/scs-0302-v1-domain-manager-role/",children:"Domain Manager configuration for Keystone"})})]})})]}),"\n",(0,i.jsxs)(a.p,{children:["To configure and use the domain manager role from the SCS project, the\n",(0,i.jsx)(a.code,{children:"environments/kolla/files/overlays/keystone/policy.yaml"})," file is created\nin the configuration repository. The deployment and upgrade of the Keystone\nservice itself is then done as usual."]}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{className:"language-yaml",metastring:'title="environments/kolla/files/overlays/keystone/policy.yaml"',children:'---\n# SCS Domain Manager policy configuration\n\n# Section A: OpenStack base definitons\n# The entries beginning with "base_<rule>" should be exact copies of the\n# default "identity:<rule>" definitions for the target OpenStack release.\n# They will be extended upon for the domain manager role below this section.\n"base_get_domain": "(role:reader and system_scope:all) or token.domain.id:%(target.domain.id)s or token.project.domain.id:%(target.domain.id)s"\n"base_list_domains": "(role:reader and system_scope:all)"\n"base_list_roles": "(role:reader and system_scope:all)"\n"base_get_role": "(role:reader and system_scope:all)"\n"base_list_users": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"\n"base_get_user": "(role:reader and system_scope:all) or (role:reader and token.domain.id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"\n"base_create_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"\n"base_update_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"\n"base_delete_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"\n"base_list_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"\n"base_get_project": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.project.domain_id)s) or project_id:%(target.project.id)s"\n"base_create_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"\n"base_update_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"\n"base_delete_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"\n"base_list_user_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"\n"base_check_grant": "(role:reader and system_scope:all) or ((role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"\n"base_list_grants": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)"\n"base_create_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"\n"base_revoke_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"\n"base_list_role_assignments": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"\n"base_list_groups": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"\n"base_get_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"\n"base_create_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"\n"base_update_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"\n"base_delete_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"\n"base_list_groups_for_user": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(user_id)s"\n"base_list_users_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"\n"base_remove_user_from_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"\n"base_check_user_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"\n"base_add_user_to_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"\n\n# Section B: Domain Manager Extensions\n\n# classify domain managers with a special role\n"is_domain_manager": "role:manager"\n\n# specify a rule that whitelists roles which domain admins are permitted\n# to assign and revoke within their domain\n"is_domain_managed_role": "\'member\':%(target.role.name)s or \'load-balancer_member\':%(target.role.name)s or \'creator\':%(target.role.name)s"\n\n# allow domain admins to retrieve their own domain (does not need changes)\n"identity:get_domain": "rule:base_get_domain or rule:admin_required"\n\n# list_domains is needed for GET /v3/domains?name=... requests\n# this is mandatory for things like\n# `create user --domain $DOMAIN_NAME $USER_NAME` to correctly discover\n# domains by name\n"identity:list_domains": "rule:is_domain_manager or rule:base_list_domains or rule:admin_required"\n\n# list_roles is needed for GET /v3/roles?name=... requests\n# this is mandatory for things like `role add ... $ROLE_NAME`` to correctly\n# discover roles by name\n"identity:list_roles": "rule:is_domain_manager or rule:base_list_roles or rule:admin_required"\n\n# get_role is needed for GET /v3/roles/{role_id} requests\n# this is mandatory for the OpenStack SDK to properly process role assignments\n# which are issued by role id instead of name\n"identity:get_role": "(rule:is_domain_manager and rule:is_domain_managed_role) or rule:base_get_role or rule:admin_required"\n\n# allow domain admins to manage users within their domain\n"identity:list_users": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_users or rule:admin_required"\n"identity:get_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_get_user or rule:admin_required"\n"identity:create_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_create_user or rule:admin_required"\n"identity:update_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_update_user or rule:admin_required"\n"identity:delete_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_delete_user or rule:admin_required"\n\n# allow domain admins to manage projects within their domain\n"identity:list_projects": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_projects or rule:admin_required"\n"identity:get_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_get_project or rule:admin_required"\n"identity:create_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_create_project or rule:admin_required"\n"identity:update_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_update_project or rule:admin_required"\n"identity:delete_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_delete_project or rule:admin_required"\n"identity:list_user_projects": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_user_projects or rule:admin_required"\n\n# allow domain managers to manage role assignments within their domain\n# (restricted to specific roles by the \'is_domain_managed_role\' rule)\n#\n# project-level role assignment to user within domain\n"is_domain_user_project_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s"\n# project-level role assignment to group within domain\n"is_domain_group_project_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.project.domain_id)s"\n# domain-level role assignment to group\n"is_domain_level_group_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.domain.id)s"\n# domain-level role assignment to user\n"is_domain_level_user_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.domain.id)s"\n"domain_manager_grant": "rule:is_domain_manager and (rule:is_domain_user_project_grant or rule:is_domain_group_project_grant or rule:is_domain_level_group_grant or rule:is_domain_level_user_grant)"\n"identity:check_grant": "rule:domain_manager_grant or rule:base_check_grant or rule:admin_required"\n"identity:list_grants": "rule:domain_manager_grant or rule:base_list_grants or rule:admin_required"\n"identity:create_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_create_grant or rule:admin_required"\n"identity:revoke_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_revoke_grant or rule:admin_required"\n"identity:list_role_assignments": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_role_assignments or rule:admin_required"\n\n\n# allow domain managers to manage groups within their domain\n"identity:list_groups": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_list_groups or rule:admin_required"\n"identity:get_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_get_group or rule:admin_required"\n"identity:create_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_create_group or rule:admin_required"\n"identity:update_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_update_group or rule:admin_required"\n"identity:delete_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_delete_group or rule:admin_required"\n"identity:list_groups_for_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_groups_for_user or rule:admin_required"\n"identity:list_users_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_list_users_in_group or rule:admin_required"\n"identity:remove_user_from_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_remove_user_from_group or rule:admin_required"\n"identity:check_user_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_check_user_in_group or rule:admin_required"\n"identity:add_user_to_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_add_user_to_group or rule:admin_required"\n'})}),"\n",(0,i.jsxs)(a.p,{children:["The role ",(0,i.jsx)(a.code,{children:"manager"})," is created using the OpenStack CLI. Alternatively, the role can\nbe added using Ansible or other tools."]}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{children:'$ openstack --os-cloud admin \\\n role create \\\n --or-show \\\n --description "Domain Manager Role" \\\n manager\n+-------------+----------------------------------+\n| Field | Value |\n+-------------+----------------------------------+\n| description | Domain Manager Role |\n| domain_id | None |\n| id | 9b7140bfe628468ab9b86b365f9ac4c2 |\n| name | manager |\n| options | {} |\n+-------------+----------------------------------+\n'})}),"\n",(0,i.jsx)(a.p,{children:"A user can then be made a domain manager for a particular domain by assigning this role."}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{children:"$ openstack --os-cloud admin \\\n role add \\\n --user test \\\n --domain test \\\n manager\n"})}),"\n",(0,i.jsx)(a.h2,{id:"oidc-federation",children:"OIDC Federation"})]})}function l(e={}){const{wrapper:a}={...(0,d.R)(),...e.components};return a?(0,i.jsx)(a,{...e,children:(0,i.jsx)(_,{...e})}):_(e)}},28453:(e,a,n)=>{n.d(a,{R:()=>o,x:()=>t});var r=n(96540);const i={},d=r.createContext(i);function o(e){const a=r.useContext(d);return r.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function t(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(d.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/befb6565.9a5015b1.js b/assets/js/befb6565.9a5015b1.js new file mode 100644 index 0000000000..ffbf7bd3ee --- /dev/null +++ b/assets/js/befb6565.9a5015b1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[47020],{70295:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>d});const a=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/heat","title":"Heat","description":"* Heat admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/heat.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/heat","permalink":"/docs/iaas/guides/configuration-guide/openstack/heat","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/heat.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Heat"},"sidebar":"docs","previous":{"title":"Glance","permalink":"/docs/iaas/guides/configuration-guide/openstack/glance"},"next":{"title":"Horizon","permalink":"/docs/iaas/guides/configuration-guide/openstack/horizon"}}');var i=n(74848),s=n(28453);const o={sidebar_label:"Heat"},c="Heat",r={},d=[];function u(e){const t={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"heat",children:"Heat"})}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://docs.openstack.org/heat/latest/admin/index.html",children:"Heat admin guide"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://docs.openstack.org/heat/latest/configuration/index.html",children:"Heat configuration reference"})}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>c});var a=n(96540);const i={},s=a.createContext(i);function o(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c059aa33.292aac2a.js b/assets/js/c059aa33.292aac2a.js new file mode 100644 index 0000000000..8b28c32275 --- /dev/null +++ b/assets/js/c059aa33.292aac2a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[44716],{48472:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"iaas/deployment-examples/artcodix/index","title":"artcodix","description":"Preface","source":"@site/docs/02-iaas/deployment-examples/artcodix/index.mdx","sourceDirName":"02-iaas/deployment-examples/artcodix","slug":"/iaas/deployment-examples/artcodix/","permalink":"/docs/iaas/deployment-examples/artcodix/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/deployment-examples/artcodix/index.mdx","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Deployment Examples","permalink":"/docs/category/deployment-examples"},"next":{"title":"Container Layer Introduction","permalink":"/docs/container/"}}');var r=o(74848),s=o(28453);const i={},a="artcodix",l={},d=[{value:"Preface",id:"preface",level:2},{value:"Node type definitions",id:"node-type-definitions",level:2},{value:"Control Node",id:"control-node",level:3},{value:"Compute Node (HCI/no HCI)",id:"compute-node-hcino-hci",level:3},{value:"Not Hyperconverged Infrastructure (no HCI)",id:"not-hyperconverged-infrastructure-no-hci",level:4},{value:"Hyperconverged Infrastructure (HCI)",id:"hyperconverged-infrastructure-hci",level:4},{value:"No HCI / vs HCI",id:"no-hci--vs-hci",level:4},{value:"Storage Node",id:"storage-node",level:3},{value:"Network Node",id:"network-node",level:3},{value:"Nodes in this deployment example",id:"nodes-in-this-deployment-example",level:2},{value:"Use cases and validation",id:"use-cases-and-validation",level:3},{value:"Control Node",id:"control-node-1",level:3},{value:"General requirements",id:"general-requirements",level:4},{value:"Hardware recommendation",id:"hardware-recommendation",level:4},{value:"Compute Node (HCI)",id:"compute-node-hci",level:3},{value:"Hardware recommendation",id:"hardware-recommendation-1",level:4},{value:"Network",id:"network",level:2},{value:"Scenario A: Not recommended for production",id:"scenario-a-not-recommended-for-production",level:3},{value:"Scenario B: Minimum recommended setup for small production environments",id:"scenario-b-minimum-recommended-setup-for-small-production-environments",level:3},{value:"Network adapters",id:"network-adapters",level:3},{value:"How to continue",id:"how-to-continue",level:2}];function c(e){const n={a:"a",blockquote:"blockquote",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"artcodix",children:"artcodix"})}),"\n",(0,r.jsx)(n.h2,{id:"preface",children:"Preface"}),"\n",(0,r.jsx)(n.p,{children:"This document describes a possible environment setup for a pre-production or minimal production setup.\nIn general hardware requirements can vary largely from environment to environment and this guide is not\na hardware sizing guide nor the best placement solution of services for every setup. This guide intends to\nprovide a starting point for a hardware based deployment of the SCS-IaaS reference implementation based on OSISM."}),"\n",(0,r.jsx)(n.h2,{id:"node-type-definitions",children:"Node type definitions"}),"\n",(0,r.jsx)(n.h3,{id:"control-node",children:"Control Node"}),"\n",(0,r.jsxs)(n.p,{children:["A control node runs all or most of the openstack services, that are responsible for API-services and the corresponding\nruntimes. These nodes are necessary for any user to interact with the cloud and to keep the cloud in a managed state.\nHowever these nodes are usualy ",(0,r.jsx)(n.strong,{children:"not"})," running user virtual machines.\nHence it is advisable to have the control nodes replicated. To have a RAFT-quorum three nodes are a good starting point."]}),"\n",(0,r.jsx)(n.h3,{id:"compute-node-hcino-hci",children:"Compute Node (HCI/no HCI)"}),"\n",(0,r.jsx)(n.h4,{id:"not-hyperconverged-infrastructure-no-hci",children:"Not Hyperconverged Infrastructure (no HCI)"}),"\n",(0,r.jsx)(n.p,{children:"Non HCI compute nodes are exclusively running user virtual machines. They are running no API-services, no storage daemons\nand no network routers, except for the necessary network infrastructure to connect virtual machines."}),"\n",(0,r.jsx)(n.h4,{id:"hyperconverged-infrastructure-hci",children:"Hyperconverged Infrastructure (HCI)"}),"\n",(0,r.jsx)(n.p,{children:"HCI nodes generally run at least user virtual machines and storage daemons. It is possible to place networking services\nhere as well but that is not considered good practice."}),"\n",(0,r.jsx)(n.h4,{id:"no-hci--vs-hci",children:"No HCI / vs HCI"}),"\n",(0,r.jsx)(n.p,{children:"Whether to use HCI nodes or not is in general not an easy question. For a getting started (pre production/smalles possible production)\nenvironment however, it is the most cost efficent option. Therefore we will continue with HCI nodes (compute + storage)."}),"\n",(0,r.jsx)(n.h3,{id:"storage-node",children:"Storage Node"}),"\n",(0,r.jsx)(n.p,{children:"A dedicated storage node runs only storage daemons. This can be necessary in larger deployments to protect the storage daemons from\nressource starvation through user workloads."}),"\n",(0,r.jsx)(n.p,{children:"Not used in this setup."}),"\n",(0,r.jsx)(n.h3,{id:"network-node",children:"Network Node"}),"\n",(0,r.jsx)(n.p,{children:"A dedicated network node runs the routing infrastructure for user virtual machines that connects these machines with provider / external\nnetworks. In larger deployments these can be useful to enhance scaling and improve network performance."}),"\n",(0,r.jsx)(n.p,{children:"Not used in this setup."}),"\n",(0,r.jsx)(n.h2,{id:"nodes-in-this-deployment-example",children:"Nodes in this deployment example"}),"\n",(0,r.jsx)(n.p,{children:"As mentioned before we are running three dedicated control nodes. To be able to fully test an openstack environment it is\nrecommended to run three compute nodes (HCI) as well. Technically you can get a setup running with just one compute node.\nSee the following chapter (Use cases and validation) for more information."}),"\n",(0,r.jsx)(n.h3,{id:"use-cases-and-validation",children:"Use cases and validation"}),"\n",(0,r.jsx)(n.p,{children:"The setup described allows for the following use cases / test cases:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Highly available control plane","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Control plane failure toleration test (Database, RabbitMQ, Ceph Mons, Routers)"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Highly available user virtual clusters (e.g. Kubernetes clusters)","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Compute host failure simulation"}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.li,{children:"Host aggregates / compute node grouping"}),"\n",(0,r.jsxs)(n.li,{children:["Host based storage replication (instead of OSD based)","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Fully replicated storage / storage high availability test"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"control-node-1",children:"Control Node"}),"\n",(0,r.jsx)(n.h4,{id:"general-requirements",children:"General requirements"}),"\n",(0,r.jsx)(n.p,{children:"The control nodes do not run any user workloads. This means they are usually not sized as big as the compute nodes.\nRelevant metrics for control nodes are:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Fast and big enough discs. At least SATA-SSDs are recommended, NVMe will greatly improve the overall responsiveness."}),"\n",(0,r.jsx)(n.li,{children:"A rather large amount of memory to house all the caches for databases and queues."}),"\n",(0,r.jsx)(n.li,{children:"CPU performance should be average. A good compromise between amount of cores and speed should be used. However this is\nthe least important requirement on the list."}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"hardware-recommendation",children:"Hardware recommendation"}),"\n",(0,r.jsx)(n.p,{children:"The following server specs are just a starting point and can greatly vary between environments."}),"\n",(0,r.jsx)(n.p,{children:"Example:\n3x Dell R630/R640/R650 1HE Server"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Dual 8 Core 3,00 GHz Intel/AMD"}),"\n",(0,r.jsx)(n.li,{children:"128 GB RAM"}),"\n",(0,r.jsx)(n.li,{children:"2x 3,84 TB NVMe in (Software-) RAID 1"}),"\n",(0,r.jsx)(n.li,{children:"2x 10/25/40 GBit 2 Port SFP+/QSFP Network Cards"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"compute-node-hci",children:"Compute Node (HCI)"}),"\n",(0,r.jsxs)(n.p,{children:["The compute nodes in this scenario run all the user virtual workloads ",(0,r.jsx)(n.strong,{children:"and"})," the storage infrastructure. To make sure\nwe don't starve these nodes, they should be of decent size."]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:"This setup takes local storage tests into consideration. The SCS-standards require certain flavors with very fast disc speed\nto house customer kubernetes control planes (etcd). These speeds are usually not achievable with shared storage. If you don't\nintend to test this scenario, you can skip the NVMe discs."}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"hardware-recommendation-1",children:"Hardware recommendation"}),"\n",(0,r.jsx)(n.p,{children:"The following server specs are just a starting point and can greatly vary between environments. The sizing of the nodes needs to fit\nthe expected workloads (customer VMs)."}),"\n",(0,r.jsx)(n.p,{children:"Example:\n3x Dell R730(xd)/R740(xd)/R750(xd)\nor\n3x Supermicro"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Dual 16 Core 2,8 GHz Intel/AMD"}),"\n",(0,r.jsx)(n.li,{children:"512 GB RAM"}),"\n",(0,r.jsx)(n.li,{children:"2x 3,84 TB NVMe in (Software-) RAID 1 if you want to have local storage available (optional)"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"For hyperconverged ceph osds:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"4x 10 TB HDD -> This leads to ~30 TB of available HDD storage (optional)"}),"\n",(0,r.jsx)(n.li,{children:"4x 7,68 TB SSD -> This leads to ~25 TB of available SSD storage (optional)"}),"\n",(0,r.jsx)(n.li,{children:"2x 10/25/40 GBit 2 Port SFP+/QSFP Network Cards"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"network",children:"Network"}),"\n",(0,r.jsx)(n.p,{children:"The network infrastructure can vary a lot from setup to setup. This guide does not intend to define the best networking solution\nfor every cluster but rather give two possible scenarios."}),"\n",(0,r.jsx)(n.h3,{id:"scenario-a-not-recommended-for-production",children:"Scenario A: Not recommended for production"}),"\n",(0,r.jsx)(n.p,{children:"The smallest possible setup is just a single switch connected to all the nodes physically on one interface. The switch has to be\nVLAN enabled. Openstack recommends multiple isolated networks but the following are at least recommended to be split:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Out of Band network"}),"\n",(0,r.jsx)(n.li,{children:"Management networks"}),"\n",(0,r.jsx)(n.li,{children:"Storage backend network"}),"\n",(0,r.jsx)(n.li,{children:"Public / External network for virutal machines\nIf there is only one switch, these networks should all be defined as seperate VLANs. One of the networks can run in untagged default\nVLAN 1."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"scenario-b-minimum-recommended-setup-for-small-production-environments",children:"Scenario B: Minimum recommended setup for small production environments"}),"\n",(0,r.jsx)(n.p,{children:"The recommended setup uses two stacked switches connected in a LAG and at least three different physical network ports on each node."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Physical Network 1: VLANs for Public / External network for virutal machines, Management networks"}),"\n",(0,r.jsx)(n.li,{children:"Physical Network 2: Storage backend network"}),"\n",(0,r.jsx)(n.li,{children:"Physical Network 3: Out of Band network"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"network-adapters",children:"Network adapters"}),"\n",(0,r.jsx)(n.p,{children:"The out of band network does usually not need a lot of bandwith. Most modern servers come with 1Gbit/s adapters which are sufficient.\nFor small test clusters, it might also be sufficient to use 1Gbit/s networks for the other two physical networks.\nFor a minimum production cluster it is recommended to use the following:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Out of Band Network: 1Gbit/s"}),"\n",(0,r.jsx)(n.li,{children:"VLANs for Public / External network for virutal machines, Management networks: 10 / 25 Gbit/s"}),"\n",(0,r.jsx)(n.li,{children:"Storage backend network: 10 / 25 / 40 Gbit/s"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Whether you need a higher throughput for your storage backend services depends on your expected storage load. The faster the network\nthe faster storage data can be replicated between nodes. This usually leads to improved performance and better/faster fault tolerance."}),"\n",(0,r.jsx)(n.h2,{id:"how-to-continue",children:"How to continue"}),"\n",(0,r.jsxs)(n.p,{children:["After implementing the recommended deployment example hardware, you can continue with the ",(0,r.jsx)(n.a,{href:"https://docs.scs.community/docs/iaas/guides/deploy-guide/",children:"deployment guide"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>a});var t=o(96540);const r={},s=t.createContext(r);function i(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c06491c2.ca853aa9.js b/assets/js/c06491c2.ca853aa9.js new file mode 100644 index 0000000000..7fd91a068e --- /dev/null +++ b/assets/js/c06491c2.ca853aa9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[70337],{66276:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"application-examples/opendesk-on-scs/overview","title":"Overview","description":"This guide takes you through the steps to deploy openDesk on a Sovereign Cloud Stack Kubernetes cluster.","source":"@site/user-docs/application-examples/opendesk-on-scs/overview.md","sourceDirName":"application-examples/opendesk-on-scs","slug":"/application-examples/opendesk-on-scs/overview","permalink":"/user-docs/application-examples/opendesk-on-scs/overview","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"userDocs","previous":{"title":"OpenDesk on SCS","permalink":"/user-docs/category/opendesk-on-scs"},"next":{"title":"Quickstart","permalink":"/user-docs/application-examples/opendesk-on-scs/quickstart"}}');var s=t(74848),i=t(28453);const a={},r="Overview",c={},l=[];function d(e){const n={a:"a",em:"em",h1:"h1",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,s.jsxs)(n.p,{children:["This guide takes you through the steps to deploy ",(0,s.jsx)(n.a,{href:"https://gitlab.opencode.de/bmi/opendesk",children:"openDesk"})," on a Sovereign Cloud Stack Kubernetes cluster.\nopenDesk is a Kubernetes based, open-source and cloud-native digital workplace suite provided by the ",(0,s.jsx)(n.em,{children:"Zentrum f\xfcr Digitale Souver\xe4nit\xe4t der \xd6ffentlichen Verwaltung (ZenDiS) GmbH"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["It bundles ",(0,s.jsx)(n.a,{href:"https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk/-/blob/main/docs/getting-started.md#apps",children:"a number of modular software components"})," for collaboration in organizations, such as an identity and access management system with a web based portal (Univention Nubus), a groupware (OX App Suite), tools for knowledge and project management (XWiki, OpenProject), file sharing (Nextcloud), video conferencing (Jitsi), chat (Element), and weboffice tools for online editing (Collabora, Cryptpad)."]}),"\n",(0,s.jsx)(n.p,{children:"An increasing number of public administrations migrate their work environments to free/libre and/or open source-based solutions. These environments are nowadays built on the container orchestration software Kubernetes. Public administrations strive to be as independent as possible from a few large global companies. Therefore, it is important for them to also have a choice of implementations of the underlying stack for their deployments. The same criteria of openness, standardization and interoperability that apply to the actual tools delivered by openDesk can be applied to the underlying cluster infastructure when running on a Sovereign Cloud Stack cluster."}),"\n",(0,s.jsxs)(n.p,{children:["This howto describes the steps to deploy an openDesk environment from a local machine to a Kubernetes cluster in the simplest possible way. It is meant to support Kubernetes beginners in getting started with a deployment in SCS. The goal is to get a single node openDesk installation with a portal and a configurable number of modules that are accessible via a web browser. openDesk also provides information about ",(0,s.jsx)(n.a,{href:"https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk/-/blob/main/docs/ci.md",children:"deployment via Gitlab CI"})," which is not covered here."]}),"\n",(0,s.jsxs)(n.p,{children:["Please refer to the ",(0,s.jsx)(n.a,{href:"https://gitlab.opencode.de/bmi/opendesk/documentation",children:"openDesk documentation"})," for further details."]})]})}function p(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var o=t(96540);const s={},i=o.createContext(s);function a(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c0cd111c.3c50b3be.js b/assets/js/c0cd111c.3c50b3be.js new file mode 100644 index 0000000000..2bc5782f18 --- /dev/null +++ b/assets/js/c0cd111c.3c50b3be.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[88477],{99134:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>l,frontMatter:()=>a,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"iaas/overview/storage","title":"Storage","description":"TODO","source":"@site/docs/02-iaas/overview/storage.md","sourceDirName":"02-iaas/overview","slug":"/iaas/overview/storage","permalink":"/docs/iaas/overview/storage","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/overview/storage.md","tags":[],"version":"current","frontMatter":{}}');var r=o(74848),s=o(28453);const a={},c="Storage",i={},d=[];function u(e){const t={h1:"h1",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"storage",children:"Storage"})}),"\n",(0,r.jsx)(t.p,{children:"TODO"})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,o)=>{o.d(t,{R:()=>a,x:()=>c});var n=o(96540);const r={},s=n.createContext(r);function a(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c0e025b3.a2028aa3.js b/assets/js/c0e025b3.a2028aa3.js new file mode 100644 index 0000000000..fc09eebde7 --- /dev/null +++ b/assets/js/c0e025b3.a2028aa3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[52179],{94399:(e,t,l)=>{l.r(t),l.d(t,{assets:()=>c,contentTitle:()=>d,default:()=>x,frontMatter:()=>r,metadata:()=>i,toc:()=>o});const i=JSON.parse('{"id":"iaas/guides/configuration-guide/services/tuned","title":"Tuned","description":"The roller can be applied with osism apply tuned. The role is applied to all","source":"@site/docs/02-iaas/guides/configuration-guide/services/tuned.md","sourceDirName":"02-iaas/guides/configuration-guide/services","slug":"/iaas/guides/configuration-guide/services/tuned","permalink":"/docs/iaas/guides/configuration-guide/services/tuned","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/services/tuned.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Tuned"},"sidebar":"docs","previous":{"title":"Docker","permalink":"/docs/iaas/guides/configuration-guide/services/docker"},"next":{"title":"Validations","permalink":"/docs/iaas/guides/configuration-guide/validations/"}}');var s=l(74848),n=l(28453);const r={sidebar_label:"Tuned"},d="Tuned",c={},o=[];function a(e){const t={code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"tuned",children:"Tuned"})}),"\n",(0,s.jsxs)(t.p,{children:["The roller can be applied with ",(0,s.jsx)(t.code,{children:"osism apply tuned"}),". The role is applied to all\ncompute nodes by default. This can be changed via the ",(0,s.jsx)(t.code,{children:"hosts_tuned"})," parameter."]}),"\n",(0,s.jsxs)(t.p,{children:["The profile to be used can be set via ",(0,s.jsx)(t.code,{children:"tuned_profile"}),". By default, ",(0,s.jsx)(t.code,{children:"virtual-host"}),"\nis used."]}),"\n",(0,s.jsx)(t.p,{children:"The following profiles are available:"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Profile"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"accelerator-performance"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Throughput performance based tuning with disabled higher latency STOP states"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"atomic-guest"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize virtual guests based on the Atomic variant"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"atomic-host"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize bare metal systems running the Atomic variant"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"balanced"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"General non-specialized tuned profile"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"cpu-partitioning"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for CPU partitioning"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"default"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Legacy default tuned profile"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"desktop"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for the desktop use-case"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"desktop-powersave"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optmize for the desktop use-case with power saving"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"enterprise-storage"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Legacy profile for RHEL6, for RHEL7, please use throughput-performance profile"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"hpc-compute"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for HPC compute workloads"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"intel-sst"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Configure for Intel Speed Select Base Frequency"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"laptop-ac-powersave"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for laptop with power savings"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"laptop-battery-powersave"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize laptop profile with more aggressive power saving"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"latency-performance"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for deterministic performance at the cost of increased power consumption"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"mssql"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for MS SQL Server"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"network-latency"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for deterministic performance at the cost of increased power consumption, focused on low latency network performance"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"network-throughput"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for streaming network throughput, generally only necessary on older CPUs or 40G+ networks"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"optimize-serial-console"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for serial console use."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"oracle"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for Oracle RDBMS"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"postgresql"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for PostgreSQL server"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"powersave"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for low power consumption"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"realtime"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for realtime workloads"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"sap-hana"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for SAP HANA"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"sap-netweaver"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for SAP NetWeaver"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"server-powersave"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for server power savings"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"spectrumscale-ece"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimized for Spectrum Scale Erasure Code Edition Servers"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"spindown-disk"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for power saving by spinning-down rotational disks"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"throughput-performance"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Broadly applicable tuning that provides excellent performance across a variety of common server workloads"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"virtual-guest"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for running inside a virtual guest"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"virtual-host"}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for running KVM guests"})]})]})]})]})}function x(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,t,l)=>{l.d(t,{R:()=>r,x:()=>d});var i=l(96540);const s={},n=i.createContext(s);function r(e){const t=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c1172cc8.3d7136b0.js b/assets/js/c1172cc8.3d7136b0.js new file mode 100644 index 0000000000..f4cc7b901a --- /dev/null +++ b/assets/js/c1172cc8.3d7136b0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[73739],{36758:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>m,default:()=>c,frontMatter:()=>o,metadata:()=>s,toc:()=>r});const s=JSON.parse('{"id":"scs-0102-w1-image-metadata-implementation-testing","title":"SCS Image Metadata: Implementation and Testing Notes","description":"Implementation notes","source":"@site/standards/scs-0102-w1-image-metadata-implementation-testing.md","sourceDirName":".","slug":"/scs-0102-w1-image-metadata-implementation-testing","permalink":"/standards/scs-0102-w1-image-metadata-implementation-testing","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Image Metadata: Implementation and Testing Notes","type":"Supplement","track":"IaaS","status":"Draft","supplements":["scs-0102-v1-image-metadata.md"]},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0102-v1-image-metadata"},"next":{"title":"scs-0103: SCS Standard Flavors and Properties","permalink":"/standards/iaas/scs-0103"}}');var n=a(74848),i=a(28453);const o={title:"SCS Image Metadata: Implementation and Testing Notes",type:"Supplement",track:"IaaS",status:"Draft",supplements:["scs-0102-v1-image-metadata.md"]},m=void 0,l={},r=[{value:"Implementation notes",id:"implementation-notes",level:2},{value:"Automated tests",id:"automated-tests",level:2},{value:"Images sample",id:"images-sample",level:3},{value:"Implementation",id:"implementation",level:3},{value:"Manual tests",id:"manual-tests",level:2}];function d(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"implementation-notes",children:"Implementation notes"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.a,{href:"https://github.com/osism/openstack-image-manager",children:"OpenStack Image Manager from OSISM"}),'\nwill create a set of images from a "spec file" provided by the user, which can also set the required properties\nfor these images.']}),"\n",(0,n.jsx)(t.h2,{id:"automated-tests",children:"Automated tests"}),"\n",(0,n.jsx)(t.h3,{id:"images-sample",children:"Images sample"}),"\n",(0,n.jsx)(t.p,{children:"Some checks need to be performed on a live instance. All publicly available images on this instance\nwill be checked for either only the mandatory properties or possibly also the recommended ones.\nAdditionally, a user can also decide to test their private images, although this isn't a necessity."}),"\n",(0,n.jsx)(t.h3,{id:"implementation",children:"Implementation"}),"\n",(0,n.jsxs)(t.p,{children:["The script ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/image-metadata/image-md-check.py",children:(0,n.jsx)(t.code,{children:"image-md-check.py"})}),"\nconnects to OpenStack and performs the checks described in this section."]}),"\n",(0,n.jsx)(t.h2,{id:"manual-tests",children:"Manual tests"}),"\n",(0,n.jsx)(t.p,{children:"None."})]})}function c(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,a)=>{a.d(t,{R:()=>o,x:()=>m});var s=a(96540);const n={},i=s.createContext(n);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function m(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c12abb16.f1b7276e.js b/assets/js/c12abb16.f1b7276e.js new file mode 100644 index 0000000000..a176791bb0 --- /dev/null +++ b/assets/js/c12abb16.f1b7276e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[80281],{86672:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>d,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"operating-scs/components/status-page-web/docs/configuration","title":"Configuration","description":"The SPA expects a configuration file called config.json to be present in the src/assets folder. The very same folder also contains a template for this configuration file, called config.tmpl.json. The resulting configuration, in the static build of the SPA, will be located at dist/scs-statuspage/browser/assets.","source":"@site/docs/04-operating-scs/components/status-page-web/docs/configuration.md","sourceDirName":"04-operating-scs/components/status-page-web/docs","slug":"/operating-scs/components/status-page-web/docs/configuration","permalink":"/docs/operating-scs/components/status-page-web/docs/configuration","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-web/docs/configuration.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Quickstart","permalink":"/docs/operating-scs/components/status-page-web/docs/quickstart"},"next":{"title":"Contribute","permalink":"/docs/operating-scs/components/status-page-web/docs/contribute"}}');var i=t(74848),r=t(28453);const d={},o="Configuration",c={},l=[{value:"Configuration File",id:"configuration-file",level:2},{value:"Field Types",id:"field-types",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"configuration",children:"Configuration"})}),"\n",(0,i.jsxs)(n.p,{children:["The SPA expects a configuration file called ",(0,i.jsx)(n.code,{children:"config.json"})," to be present in the ",(0,i.jsx)(n.code,{children:"src/assets"})," folder. The very same folder also contains a template for this configuration file, called ",(0,i.jsx)(n.code,{children:"config.tmpl.json"}),". The resulting configuration, in the static build of the SPA, will be located at ",(0,i.jsx)(n.code,{children:"dist/scs-statuspage/browser/assets"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"configuration-file",children:"Configuration File"}),"\n",(0,i.jsx)(n.p,{children:"The following table explains all settings available in the configuration file. Explanations for non-basic field types can be found below the table."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Configuration Key"}),(0,i.jsx)(n.th,{children:"Description"}),(0,i.jsx)(n.th,{children:"Type"}),(0,i.jsx)(n.th,{children:"Default"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"apiServerUrl"}),(0,i.jsx)(n.td,{children:"The URL of the API server supplying data."}),(0,i.jsx)(n.td,{children:"String"}),(0,i.jsx)(n.td,{children:"empty"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"redirectUrl"}),(0,i.jsx)(n.td,{children:"URL you are being redirected to after Dex."}),(0,i.jsx)(n.td,{children:"String"}),(0,i.jsx)(n.td,{children:"empty"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"dexUrl"}),(0,i.jsx)(n.td,{children:"The URL of your Dex server."}),(0,i.jsx)(n.td,{children:"String"}),(0,i.jsx)(n.td,{children:"empty"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"dexId"}),(0,i.jsx)(n.td,{children:"ID your application uses for Dex."}),(0,i.jsx)(n.td,{children:"String"}),(0,i.jsx)(n.td,{children:"empty"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"noOfDays"}),(0,i.jsx)(n.td,{children:"Number of days to display incidents for."}),(0,i.jsx)(n.td,{children:"Number"}),(0,i.jsx)(n.td,{children:"90"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"dateFormat"}),(0,i.jsx)(n.td,{children:"The format to use for dates displayed."}),(0,i.jsx)(n.td,{children:"Format"}),(0,i.jsxs)(n.td,{children:['"YYYY-MM-DD HH:mm',":ss",' z"']})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"longDateFormat"}),(0,i.jsx)(n.td,{children:"Long format for dates, including day names."}),(0,i.jsx)(n.td,{children:"Format"}),(0,i.jsxs)(n.td,{children:['"dddd, Do MMMM YYYY, HH:mm',":ss",' z"']})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"severities"}),(0,i.jsx)(n.td,{children:"Maps severities to colors to use."}),(0,i.jsx)(n.td,{children:"Object"}),(0,i.jsx)(n.td,{children:"see below"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"unknownColor"}),(0,i.jsx)(n.td,{children:"Color to use for unknown severity values."}),(0,i.jsx)(n.td,{children:"Color"}),(0,i.jsx)(n.td,{children:'"lightsteelblue"'})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"aboutText"}),(0,i.jsx)(n.td,{children:'Short text that appears in the "About" section.'}),(0,i.jsx)(n.td,{children:"String"}),(0,i.jsx)(n.td,{children:"empty"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"maintenancePreviewDays"}),(0,i.jsx)(n.td,{children:"Number of days in the future to check for maintenance events."}),(0,i.jsx)(n.td,{children:"number"}),(0,i.jsx)(n.td,{children:"30"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"hideManagementPage"}),(0,i.jsx)(n.td,{children:"Makes the old management page inaccessible."}),(0,i.jsx)(n.td,{children:"Boolean"}),(0,i.jsx)(n.td,{children:"true"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"dayDefaultSeverity"}),(0,i.jsx)(n.td,{children:"Severity value used for days where no incidents occured"}),(0,i.jsx)(n.td,{children:"Number"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"severities"})," map contains one entry for each severity level specified in the API server. The default configuration included in the template file looks like this:"]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"}),": The ",(0,i.jsx)(n.code,{children:"noOfDays"})," field is not recommended to be edited. Unexpected results may occur."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json5",children:'"severities": {\n // Maintenance is a special case and uses only the severity value 0\n "maintenance": {\n "start": 0,\n "end": 0,\n "color": "#50c3a5",\n "colorblind": "#e1be6a"\n },\n "operational": {\n // Start value is explicit\n "start": 1,\n // End value\n "end": 33,\n // Normal mode color\n // Colors can be specified as in CSS\n "color": "#50c3a5",\n // Color to use for colorblind mode\n "colorblind": "#8ce05d"\n },\n "limited": {\n "start": 34,\n "end": 66,\n "color": "#f5c451",\n "colorblind": "#5d3a9b"\n },\n "broken": {\n "start": 67,\n "end": 100,\n "color": "#ee6a5f",\n "colorblind": "#d62c13"\n }\n}\n'})}),"\n",(0,i.jsx)(n.h2,{id:"field-types",children:"Field Types"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Format:"})," A format string using the ",(0,i.jsx)(n.a,{href:"https://day.js.org/docs/en/display/format",children:"format specifiers"})," provided by ",(0,i.jsx)(n.a,{href:"https://day.js.org/",children:"Day.js"}),", including the ones provided by the ",(0,i.jsx)(n.code,{children:"AdvancedFormat"})," plugin."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Color:"})," A string containing a color value, specified using CSS notation. Allows for color names, hex values using a leading ",(0,i.jsx)(n.code,{children:"#"})," or the ",(0,i.jsx)(n.code,{children:"rgb(...)"})," syntax."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>o});var s=t(96540);const i={},r=s.createContext(i);function d(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c15d9823.6a506149.js b/assets/js/c15d9823.6a506149.js new file mode 100644 index 0000000000..3491ae955d --- /dev/null +++ b/assets/js/c15d9823.6a506149.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[18146],{29328:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/c2f44c5f.5d661d61.js b/assets/js/c2f44c5f.5d661d61.js new file mode 100644 index 0000000000..23aaf04775 --- /dev/null +++ b/assets/js/c2f44c5f.5d661d61.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[660],{6515:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"iaas/guides/troubleshooting-guide/openstack","title":"OpenStack","description":"Database creation fails","source":"@site/docs/02-iaas/guides/troubleshooting-guide/openstack.md","sourceDirName":"02-iaas/guides/troubleshooting-guide","slug":"/iaas/guides/troubleshooting-guide/openstack","permalink":"/docs/iaas/guides/troubleshooting-guide/openstack","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/troubleshooting-guide/openstack.md","tags":[],"version":"current","sidebarPosition":40,"frontMatter":{"sidebar_label":"OpenStack","sidebar_position":40},"sidebar":"docs","previous":{"title":"Manager","permalink":"/docs/iaas/guides/troubleshooting-guide/manager"},"next":{"title":"Rookify (technical preview)","permalink":"/docs/iaas/guides/troubleshooting-guide/rookify"}}');var r=t(74848),o=t(28453);const s={sidebar_label:"OpenStack",sidebar_position:40},a="OpenStack",c={},l=[{value:"Database creation fails",id:"database-creation-fails",level:2},{value:"Ceph connections not working",id:"ceph-connections-not-working",level:2},{value:"Cinder volume create failure",id:"cinder-volume-create-failure",level:2}];function d(e){const n={code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"openstack",children:"OpenStack"})}),"\n",(0,r.jsx)(n.h2,{id:"database-creation-fails",children:"Database creation fails"}),"\n",(0,r.jsx)(n.p,{children:"Problem:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"TASK [keystone : Creating keystone database] ***********************************\nfatal: [testbed-node-0]: FAILED! => changed=false\n action: mysql_db\n msg: 'unable to find /var/lib/ansible/.my.cnf. Exception message: (2003, \"Can''t connect to MySQL server on ''api-int.local'' ([Errno 111] Connection refused)\")'\n"})}),"\n",(0,r.jsx)(n.p,{children:"Solution:"}),"\n",(0,r.jsxs)(n.p,{children:["Restart the ",(0,r.jsx)(n.code,{children:"kolla_toolbox"})," container. in this case on the node ",(0,r.jsx)(n.code,{children:"testbed-node-0"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ osism console testbed-node-0/\ntestbed-node-0>>> restart kolla_toolbox\nkolla_toolbox\ntestbed-node-0>>>\n"})}),"\n",(0,r.jsx)(n.h2,{id:"ceph-connections-not-working",children:"Ceph connections not working"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Problem: ",(0,r.jsx)(n.code,{children:"auth: error parsing file"})," or ",(0,r.jsx)(n.code,{children:"auth: failed to load"})]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ docker exec -ti nova_compute ceph -k /etc/ceph/ceph.client.nova.keyring -n client.nova -s\n2024-06-28T06:43:05.660+0000 7d5df526b640 -1 auth: error parsing file /etc/ceph/ceph.client.nova.keyring: cannot parse buffer: Malformed input\n2024-06-28T06:43:05.660+0000 7d5df526b640 -1 auth: failed to load /etc/ceph/ceph.client.nova.keyring: (5) Input/output error\n2024-06-28T06:43:05.664+0000 7d5df526b640 -1 auth: error parsing file /etc/ceph/ceph.client.nova.keyring: cannot parse buffer: Malformed input\n2024-06-28T06:43:05.664+0000 7d5df526b640 -1 auth: failed to load /etc/ceph/ceph.client.nova.keyring: (5) Input/output error\n2024-06-28T06:43:05.664+0000 7d5df526b640 -1 auth: error parsing file /etc/ceph/ceph.client.nova.keyring: cannot parse buffer: Malformed input\n2024-06-28T06:43:05.664+0000 7d5df526b640 -1 auth: failed to load /etc/ceph/ceph.client.nova.keyring: (5) Input/output error\n2024-06-28T06:43:05.664+0000 7d5df526b640 -1 auth: error parsing file /etc/ceph/ceph.client.nova.keyring: cannot parse buffer: Malformed input\n2024-06-28T06:43:05.664+0000 7d5df526b640 -1 auth: failed to load /etc/ceph/ceph.client.nova.keyring: (5) Input/output error\n2024-06-28T06:43:05.664+0000 7d5df526b640 -1 monclient: keyring not found\n[errno 5] RADOS I/O error (error connecting to the cluster)\n"})}),"\n",(0,r.jsx)(n.p,{children:"Solution:"}),"\n",(0,r.jsx)(n.p,{children:"Check your Ceph keyfiles. Probably a missing newline at the EOF."}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"cinder-volume-create-failure",children:"Cinder volume create failure"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Problem: Volume creation is stuck after creation of the database object with no host assigned."}),"\n",(0,r.jsx)(n.p,{children:"Solution:"}),"\n",(0,r.jsx)(n.p,{children:"Database objects are created by the API service for valid request while the host is assigned by the scheduler."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Check the scheduler logs for errors"}),"\n",(0,r.jsxs)(n.li,{children:["If there is nothing wrong with the scheduler itself, check the communication between the services via oslo.messaging\nUsually this is done via rabbitmq:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Check cluster status on every node for status, alarms and network partitions","\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"docker exec rabbitmq rabbitmqctl cluster_status\n"})}),"\n"]}),"\n",(0,r.jsx)(n.li,{children:"Check rabbitmq logs for errors"}),"\n",(0,r.jsxs)(n.li,{children:["Check rabbitmq queues for errors or accumulated messages","\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"docker exec rabbitmq rabbitmqctl list_queues name type state consumers messages | grep -E '^cinder'\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["If everything seems fine check network connectivity to rule out network issues","\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"osism validate kolla-connectivity\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["If networking is fine then as a last resort a reset of rabbitmq may be considered\nBeware that this will destroy rabbitmq state which may result in inconsitent resource states","\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"osism apply rabbitmq-reset-state\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>a});var i=t(96540);const r={},o=i.createContext(r);function s(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c3529e0a.fd20a084.js b/assets/js/c3529e0a.fd20a084.js new file mode 100644 index 0000000000..41e2e56500 --- /dev/null +++ b/assets/js/c3529e0a.fd20a084.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[76871],{31239:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>h,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","title":"Using Sonobuoy for KaaS conformance tests","description":"Motivation","source":"@site/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests.md","sourceDirName":".","slug":"/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","permalink":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Using Sonobuoy for KaaS conformance tests","type":"Decision Record","status":"Draft","track":"KaaS"},"sidebar":"standards","previous":{"title":"scs-0200: Using Sonobuoy for KaaS conformance tests","permalink":"/standards/kaas/scs-0200"},"next":{"title":"scs-0210: SCS K8S Version Policy","permalink":"/standards/kaas/scs-0210"}}');var o=s(74848),r=s(28453);const i={title:"Using Sonobuoy for KaaS conformance tests",type:"Decision Record",status:"Draft",track:"KaaS"},a=void 0,h={},c=[{value:"Motivation",id:"motivation",level:2},{value:"Short Sonobuoy Introduction",id:"short-sonobuoy-introduction",level:3},{value:"Design Considerations",id:"design-considerations",level:2},{value:"<em>Option 1</em> Golang based approach 1: Pick a framework from the Sonobuoy plugin examples",id:"option-1-golang-based-approach-1-pick-a-framework-from-the-sonobuoy-plugin-examples",level:3},{value:"<em>Option 2</em> Golang based approach 2: Reuse the Kubernetes own e2e test infrastructure and framework",id:"option-2-golang-based-approach-2-reuse-the-kubernetes-own-e2e-test-infrastructure-and-framework",level:3},{value:"<em>Option 3</em> Write Python scripts for tests",id:"option-3-write-python-scripts-for-tests",level:3},{value:"Approaches to providing a Sonobuoy plugin image",id:"approaches-to-providing-a-sonobuoy-plugin-image",level:2},{value:"<em>Option 1</em> Public container registry",id:"option-1-public-container-registry",level:3},{value:"<em>Option 2</em> Local image upload",id:"option-2-local-image-upload",level:3},{value:"Decision",id:"decision",level:2}];function l(e){const t={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,o.jsxs)(t.p,{children:["With the ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"k8s-cluster-api-provider"}),", the SCS provides a tool to generate\nand manage k8s clusters on top of its IaaS infrastructure. As part of\nthe application, ",(0,o.jsx)(t.a,{href:"https://sonobuoy.io/",children:"Sonobuoy"})," is used as a test suite to execute the\nofficial ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes e2e tests"}),".\nWe expect that current and future tests derived from SCS standards\nwill benefit from (or even require) the testing mechanisms that Sonobuoy provides."]}),"\n",(0,o.jsxs)(t.p,{children:["Apart from running the Kubernetes e2e tests, Sonobuoy also allows users to write\ntheir own tests and apply them as a self-managed ",(0,o.jsx)(t.a,{href:"https://sonobuoy.io/docs/main/plugins/",children:"plugin"}),".\nAll tests not provided by the ",(0,o.jsx)(t.a,{href:"https://sonobuoy.io/docs/main/e2eplugin/",children:"e2e test plugin"})," could therefore\nbe written by the respective SCS teams responsible for the standards or tests and\nthen be made executable with Sonobuoy. Hence, Sonobuoy could provide both a pre-done\ntest suite and a framework to write additional conformance tests required for SCS."]}),"\n",(0,o.jsx)(t.h3,{id:"short-sonobuoy-introduction",children:"Short Sonobuoy Introduction"}),"\n",(0,o.jsxs)(t.p,{children:["The main objective of ",(0,o.jsx)(t.a,{href:"https://sonobuoy.io/docs/main/plugins/",children:"Sonobuoy plugins"}),' is to present test\nresults in a consolidated way. To do this, Sonobuoy integrates the test into a pod,\nwhich is then applied to the K8s cluster under test. A Sonobuoy worker supervises\nthis pod and forwards all test results to the aggregator module. It does this by\nwaiting for a specific "Done" file to be created. Once this file is recognized,\nthe worker forwards the results to the aggregator, using a predefined location\nfor the results file within a folder, as seen in following image:\n',(0,o.jsx)(t.img,{src:"https://sonobuoy.io/img/plugin-contract.png",alt:"image search api"})]}),"\n",(0,o.jsx)(t.p,{children:"In order to use the existing conformance tests as a Sonobuoy plugin, a wrapper\naround the individual test scripts would be required. This wrapper would need to\nhave the following effects:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"gathers all test results and provides them in the results file"}),"\n",(0,o.jsx)(t.li,{children:'run tests in sequence and signal the worker when it\'s finished by generating a "Done" file'}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"Apart from providing the test results, a plugin container must also forward the\nstatus of each test by setting a status flag in the results file.\nAdditionally, the tests would need to be able to run inside a pod in the K8s cluster under test."}),"\n",(0,o.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,o.jsx)(t.p,{children:"There are different approaches to create a Sonobuoy plugin, which are discussed\nbelow in order to find a best practice for the SCS project. The documented approaches\nshow one example each in order to give a better representation to the reader."}),"\n",(0,o.jsxs)(t.p,{children:["Sonobuoy provides plugin examples in the ",(0,o.jsx)(t.a,{href:"https://github.com/vmware-tanzu/sonobuoy-plugins",children:"plugins repository"}),",\nwhich are referenced throughout this section."]}),"\n",(0,o.jsxs)(t.h3,{id:"option-1-golang-based-approach-1-pick-a-framework-from-the-sonobuoy-plugin-examples",children:[(0,o.jsx)(t.em,{children:"Option 1"})," Golang based approach 1: Pick a framework from the Sonobuoy plugin examples"]}),"\n",(0,o.jsxs)(t.p,{children:["The seemingly most interesting plugin is the ",(0,o.jsx)(t.a,{href:"https://github.com/vmware-tanzu/sonobuoy-plugins/tree/main/examples/e2e-skeleton",children:"e2e-skeleton"}),", which uses\nthe ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework",children:"kubernetes-sigs/e2e-framework"}),". The ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework",children:"kubernetes-sigs/e2e-framework"}),"\nis a stand-alone project that is separate from the official ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes e2e tests"}),'.\nThe framework provides proper documentation as well as helper functions that abstract\nclient functionalities, similar to those found in "kubernetes/kubernetes/test/e2e/framework" repository.']}),"\n",(0,o.jsxs)(t.p,{children:["As mentioned in the ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework/blob/main/docs/design/README.md#motivations",children:"motivation"})," of the ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework",children:"e2e-framework"}),",\nthe project was created to circumvent the disadvantages of ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes' own e2e-tests"}),",\nwhich are described in more detail in the ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework/blob/main/docs/design/README.md#goals",children:"goals"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"PROS:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["arguments in favor of this framework can also be found under the ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework/blob/main/docs/design/README.md#goals",children:"goals description"})," of the documentation"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework",children:"e2e-framework"})," is a well-defined framework, that allows the handling of resource creation and deletion"]}),"\n",(0,o.jsx)(t.li,{children:'official framework provided by "Kubernetes-sigs"'}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"CONS:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["arguments not in favor of this framework can be derived from the ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework/blob/main/docs/design/README.md#non-goals",children:"Non-Goals"})," description of the documentation:","\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:'"no responsibility for bootstrapping or the execution of the tests themselves" can be ignored, as this is partly taken over by Sonobuoy'}),"\n",(0,o.jsx)(t.li,{children:'"no mock or fake cluster components" can be ignored, since the e2e tests of SCS should be used to test real clusters and their functionality'}),"\n",(0,o.jsx)(t.li,{children:"for this test procedure, the Sonobuoy e2e plugin should be run in addition to the SCS KaaS conformance tests"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsxs)(t.p,{children:["proof of concept: ",(0,o.jsx)(t.code,{children:"../Tests/kaas/kaas-sonobuoy-go-example-e2e-framework/"})]}),"\n"]}),"\n",(0,o.jsxs)(t.h3,{id:"option-2-golang-based-approach-2-reuse-the-kubernetes-own-e2e-test-infrastructure-and-framework",children:[(0,o.jsx)(t.em,{children:"Option 2"})," Golang based approach 2: Reuse the Kubernetes own e2e test infrastructure and framework"]}),"\n",(0,o.jsx)(t.p,{children:"The existing Sonobuoy e2e plugin already provides a vast number of tests that could\nbe adapted or reused for the SCS project."}),"\n",(0,o.jsxs)(t.p,{children:["If these e2e tests are to be reused in a customized structure, a framework like ",(0,o.jsx)(t.a,{href:"https://onsi.github.io/ginkgo/",children:"ginkgo"}),"\nmust be used as it is used by the Kubernetes e2e test infrastructure.\nThis could use the implementation of the build process responsible for the Docker\nimage containing the e2e tests. The setup could be copied from ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/conformance/image",children:"kubernetes/test/conformance/image"}),"\nand adapted to the projects requirements. The mentioned build process must use the\nfiles of the following directories from the Kubernetes repository:"]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/cluster",children:"kubernetes/cluster"})}),"\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"kubernetes/test/e2e/framework"})}),"\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/conformance/image/go-runner",children:"kubernetes/test/conformance/image/go-runner"})}),"\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/hack/conformance",children:"kubernetes/hack/conformance"})}),"\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/hack/make-rules",children:"kubernetes/hack/make-rules"})}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"PROS:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes' own e2e tests"})," already provide a vast amount of examples, which could be reused to develop specific SCS tests"]}),"\n",(0,o.jsxs)(t.li,{children:["compared to ",(0,o.jsx)(t.em,{children:"option 1"}),", the ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework/blob/main/docs/design/README.md#non-goals",children:"non-goals"})," of the ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework",children:"e2e-framework"})," can be seen as the advantages of using ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes' own e2e-tests"}),"."]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"CONS:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"not easy to implement, as we would have to copy part of the Kubernetes repository and track the changes from the upstream"}),"\n",(0,o.jsxs)(t.li,{children:["according to ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/cluster#readme",children:"README.md"}),", part of it seems to be outdated and might change with a future version","\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["compared to ",(0,o.jsx)(t.em,{children:"option 1"}),", the ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework/blob/main/docs/design/README.md#goals",children:"goals"})," of the ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework",children:"e2e-framework"})," can be seen as the disadvantages of using ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes' own e2e-tests"}),"."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsxs)(t.p,{children:["TODO: provide proof of concept: ",(0,o.jsx)(t.em,{children:"kaas-sonobuoy-go-example-k8s-e2e"})]}),"\n"]}),"\n",(0,o.jsxs)(t.h3,{id:"option-3-write-python-scripts-for-tests",children:[(0,o.jsx)(t.em,{children:"Option 3"})," Write Python scripts for tests"]}),"\n",(0,o.jsx)(t.p,{children:"Sonobuoy makes it possible to write tests in Python and execute them like other\ntests in a pod on the K8s cluster. It would therefore be possible to keep on writing\nconformance tests in Python."}),"\n",(0,o.jsx)(t.p,{children:'This option would require a wrapper in order to make the tests scripts executable\nas Sonobuoy plugins. This wrapper, as mentioned earlier, would need to capture\nthe collection of test results as well as the generation of the "Done" file after\nthe test execution is finished. This could be managed by executing each test script\nin a sequential order.'}),"\n",(0,o.jsx)(t.p,{children:"The wrapper as well as the python tests and test framework could then be stored\nin a container image and uploaded to a registry in order to be usable by Sonobuoy\nwithin the k8s-cluster-api-provider."}),"\n",(0,o.jsx)(t.p,{children:"This approach also leaves the decision open as to which test framework should be\nused for Python, which should be decided in a secondary Decision Record."}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsxs)(t.p,{children:["proof of work: ",(0,o.jsx)(t.code,{children:"../Tests/kaas/k8s-default-storage-class"})]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"PROS:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["continue using the already available Python tests","\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"only a small number of tests is implemented thus far"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"CONS:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:'no "native" support in Sonobuoy, a wrapper is needed'}),"\n",(0,o.jsx)(t.li,{children:"decision for a framework is still not done"}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"approaches-to-providing-a-sonobuoy-plugin-image",children:"Approaches to providing a Sonobuoy plugin image"}),"\n",(0,o.jsxs)(t.p,{children:["The following section showcases both ways to provide a Sonobuoy plugin image.\n",(0,o.jsx)(t.em,{children:"Option 1"})," would most likely be used, if an image is published to be used by an end user.\n",(0,o.jsx)(t.em,{children:"Option 2"})," is the expected way for local development and testing."]}),"\n",(0,o.jsxs)(t.h3,{id:"option-1-public-container-registry",children:[(0,o.jsx)(t.em,{children:"Option 1"})," Public container registry"]}),"\n",(0,o.jsx)(t.p,{children:"The image can be made available via a public container registry, which would require\na regular job (e.g. CI/CD) to build and publish the image."}),"\n",(0,o.jsxs)(t.h3,{id:"option-2-local-image-upload",children:[(0,o.jsx)(t.em,{children:"Option 2"})," Local image upload"]}),"\n",(0,o.jsx)(t.p,{children:'Create the image locally on the "clusterctl admin control node" and then upload\nit manually to the Kubernetes cluster under test.'}),"\n",(0,o.jsx)(t.p,{children:'Both approaches are useful in different ways. While the usage of a container registry\nallows easy distribution of tests and guarantees new images through the usage of a\nCI/CD job, it also makes it harder to test changes quickly, since a wait time could be\nnecessary to let the CI/CD job run through and access the image. This can be solved\nby using the "Local image upload" or a combination of both approaches.'}),"\n",(0,o.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,o.jsx)(t.p,{children:"The KaaS conformance test MUST be provided as a test suite holding the\ntest cases for the Kubernetes clusters to be checked.\nFurthermore, the test cases themselves MUST be wrapped by a test framework to:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"handle the creation and deletion of resources"}),"\n",(0,o.jsx)(t.li,{children:"collect and present results"}),"\n",(0,o.jsx)(t.li,{children:"consolidate redundant code across test cases"}),"\n",(0,o.jsx)(t.li,{children:"support the creation of test cases through predefined structures"}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["As with the ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"k8s-cluster-api-provider"})," the SCS provides a tooling to generate\nits KaaS infrastructure. Part of the ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"k8s-cluster-api-provider"})," is the usage\nof Sonobuoy as a test suite to execute the ",(0,o.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes own e2e tests"}),".\nInvestigating those e2e test lead to the conclusion that they are not always reusable.\nThe main purpose of Kubernetes own e2e tests is to test the functionality of\nthe Kubernetes code itself and not the resources and setup of a specific KaaS infrastructure\nas it is the aim of the SCS KaaS conformance test."]}),"\n",(0,o.jsx)(t.p,{children:"However, considering that the SCS has an ongoing process of defining standards and\nimplementing test cases to check their compliance, that means in some cases future standards\nmight already be covered by the e2e test inside the Kubernetes repository.\nHence, before writing tests, a developer SHOULD check the Kubernetes e2e tests for\nexisting test cases that might cover conformance of a standard currently being worked on."}),"\n",(0,o.jsx)(t.p,{children:"As described above, Sonobuoy offers the possibility to generate custom plugins\nthat provide self-created test cases. Therefore, future conformance tests MUST\nbe executable by Sonobuoy by wrapping them in a Sonobuoy plugin.\nMoreover, three options for the implementation of the SCS KaaS compliance test\ncases are described above so that it can be decided within this decision record which\noptions should be used."}),"\n",(0,o.jsxs)(t.p,{children:['As a first decision, "',(0,o.jsx)(t.em,{children:"Option 2"})," Go Approach 2: Reuse Kubernetes' own e2e test infrastructure and framework\"\nis the least viable, as it would mean copying almost all the files used from\nthe Kubernetes e2e tests. This framework is closely linked to the development of\nthe Kubernetes code. Therefore, changes to its structure mainly are in line with its usage\nin the Kubernetes repository itself and is most likely not relevant for other parties.\nChanges in the framework cloud have a greater impact on our side as they are\npredictable. The development effort gained by reusing these examples could be\noutweighed by the investment necessary to adapt tests to the corresponding framework changes."]}),"\n",(0,o.jsxs)(t.p,{children:['This leaves "',(0,o.jsx)(t.em,{children:"Option 1"}),' Go approach 1: Pick framework from the Sonobuoy plugin examples"\nand "',(0,o.jsx)(t.em,{children:"Option 3"})," Write Python scripts for tests\" as methods for implementing test cases.\nIt is possible to use both approaches in parallel, which would enable usage of both Python\nand Go code. This could possibly generate two Sonobuoy plugins, but this isn't a necessity."]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>a});var n=s(96540);const o={},r=n.createContext(o);function i(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c49f9378.4b59087c.js b/assets/js/c49f9378.4b59087c.js new file mode 100644 index 0000000000..031b21c5b4 --- /dev/null +++ b/assets/js/c49f9378.4b59087c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[20126],{71575:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>f,frontMatter:()=>o,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"iaas/components/simple-stress","title":"Simple Stress","description":"Overview","source":"@site/docs/02-iaas/components/simple-stress.md","sourceDirName":"02-iaas/components","slug":"/iaas/components/simple-stress","permalink":"/docs/iaas/components/simple-stress","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/simple-stress.md","tags":[],"version":"current","sidebarPosition":55,"frontMatter":{"sidebar_label":"Simple Stress","sidebar_position":55}}');var t=s(74848),r=s(28453);const o={sidebar_label:"Simple Stress",sidebar_position:55},a="Simple Stress",l={},d=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Defaults",id:"defaults",level:2},{value:"Usage",id:"usage",level:2},{value:"Config files",id:"config-files",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"simple-stress",children:"Simple Stress"})}),"\n",(0,t.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,t.jsx)(n.p,{children:"The OpenStack Simple Stress is a small stress test for your Openstack Cluster. You can use it for burnin tests or if you want to monitor your cluster perfomance.\nIt is able to start a predefined amount of Servers in specific networks in parallel and serial and removes them afterwards, so you can test your environment to the limits."}),"\n",(0,t.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,t.jsx)(n.p,{children:"Prepare to use the Openstack Simple Stress."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"git clone https://github.com/osism/openstack-simple-stress\ncd openstack-simple-stress\npipenv install\npipenv shell\n"})}),"\n",(0,t.jsx)(n.h2,{id:"defaults",children:"Defaults"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"main.py"})," command and the default options while executing the command."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:" --cleanup true\n --cloud simple-stress\n --compute-zone nova\n --debug false\n --delete true\n --flavor SCS-2V-8\n --floating false\n --image Ubuntu 22.04\n --interval 10 (seconds)\n --keypair unset\n --network simple-stress\n --network-zone nova\n --number 1\n --parallel 1\n --prefix simple-stress\n --storage-zone simple-stress\n --timeout 600 (seconds)\n --volume false\n --volume-number 1\n --volume-size 1 (gigabyte)\n --wait true\n"})}),"\n",(0,t.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsxs)(n.p,{children:["There must be a ",(0,t.jsx)(n.code,{children:"clouds.yml"})," and a ",(0,t.jsx)(n.code,{children:"secure.yml"})," file in the directory where the OpenStack Simple Stress will be executed, examples are provided within the git repository."]}),"\n",(0,t.jsxs)(n.p,{children:["The cloud profile to be used can be specified via the optional ",(0,t.jsx)(n.code,{children:"--cloud"})," parameter. By default, the cloud profile with the name ",(0,t.jsx)(n.code,{children:"simple-stress"})," is used."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ python src/main.py -h\nusage: main [-h] [--cleanup] [--cloud CLOUD] [--compute-zone COMPUTE_ZONE] [--config-dir DIR]\n [--config-file PATH] [--debug] [--delete] [--flavor FLAVOR] [--floating] [--image IMAGE]\n [--interval INTERVAL] [--keypair KEYPAIR] [--network NETWORK] [--network-zone NETWORK_ZONE]\n [--nocleanup] [--nodebug] [--nodelete] [--nofloating] [--novolume] [--nowait]\n [--number NUMBER] [--parallel PARALLEL] [--prefix PREFIX] [--storage-zone STORAGE_ZONE]\n [--timeout TIMEOUT] [--volume] [--volume-number VOLUME_NUMBER] [--volume-size VOLUME_SIZE]\n [--wait]\n\noptions:\n -h, --help show this help message and exit\n --cleanup\n --cloud CLOUD Cloud name\n --compute-zone COMPUTE_ZONE\n Compute availability zone to use\n --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted,\n so as to provide a predictable parse order if individual options are over-\n ridden. The set is parsed after the file(s) specified via previous --config-\n file, arguments hence over-ridden options in the directory take precedence. This\n option must be set from the command-line.\n --config-file PATH Path to a config file to use. Multiple config files can be specified, with\n values in later files taking precedence. Defaults to None. This option must be\n set from the command-line.\n --debug\n --delete\n --flavor FLAVOR\n --floating\n --image IMAGE\n --interval INTERVAL\n --keypair KEYPAIR\n --network NETWORK\n --network-zone NETWORK_ZONE\n Network availability zone to use\n --nocleanup The inverse of --cleanup\n --nodebug The inverse of --debug\n --nodelete The inverse of --delete\n --nofloating The inverse of --floating\n --novolume The inverse of --volume\n --nowait The inverse of --wait\n --number NUMBER\n --parallel PARALLEL\n --prefix PREFIX\n --storage-zone STORAGE_ZONE\n Storage availability zone to use\n --timeout TIMEOUT\n --volume\n --volume-number VOLUME_NUMBER\n --volume-size VOLUME_SIZE\n --wait\n"})}),"\n",(0,t.jsx)(n.p,{children:"Running a small and simple test on your Openstack environment, using Ubuntu_22.04 image with the flavor of 2VCPUs and 8Gigabytes of RAM, starting 6 servers, 2 parallel each with a volume size of 20Gigabytes."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ python src/main.py --network test-net --flavor SCS-2V-8 --image Ubuntu_22.04 --number 6 --parallel 2 --volume-size 20\n2024-04-23 11:47:16 | INFO | Checking flavor SCS-2V-8\n2024-04-23 11:47:17 | INFO | flavor.id = 926f952f-0714-4c55-92c2-7514191fecce\n2024-04-23 11:47:17 | INFO | Checking image Ubuntu_22.04\n2024-04-23 11:47:17 | INFO | image.id = 667649d6-e828-403b-8871-15dde7b9ce85\n2024-04-23 11:47:17 | INFO | Checking network test-net\n2024-04-23 11:47:18 | INFO | network.id = 9688192e-11dd-4618-a18c-99d3267f630a\n2024-04-23 11:47:18 | INFO | Creating server simple-stress-0\n2024-04-23 11:47:18 | INFO | Creating server simple-stress-1\n2024-04-23 11:47:18 | INFO | Waiting for server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:18 | INFO | Waiting for server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:28 | INFO | Waiting for boot / test results of 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:29 | INFO | Waiting for boot / test results of e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:39 | INFO | Deleting server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:39 | INFO | Waiting for deletion of server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:39 | INFO | Deleting server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:40 | INFO | Waiting for deletion of server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:49 | INFO | Creating server simple-stress-2\n2024-04-23 11:47:50 | INFO | Creating server simple-stress-3\n2024-04-23 11:47:50 | INFO | Waiting for server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:47:51 | INFO | Waiting for server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:00 | INFO | Waiting for boot / test results of 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:48:01 | INFO | Waiting for boot / test results of a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:11 | INFO | Deleting server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:12 | INFO | Waiting for deletion of server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:12 | INFO | Deleting server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:48:12 | INFO | Waiting for deletion of server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:48:22 | INFO | Creating server simple-stress-4\n2024-04-23 11:48:22 | INFO | Waiting for server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:22 | INFO | Creating server simple-stress-5\n2024-04-23 11:48:23 | INFO | Waiting for server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:48:55 | INFO | Deleting server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:55 | INFO | Deleting server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:48:55 | INFO | Waiting for deletion of server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:55 | INFO | Waiting for deletion of server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:49:05 | INFO | Server 049bf974-b0fd-467f-aabd-3593b2a409a4 finished\n2024-04-23 11:49:05 | INFO | Server e485697f-feae-458c-952d-000072374c3f finished\n2024-04-23 11:49:05 | INFO | Server a098cc12-94ff-4036-bf42-4fc08287809f finished\n2024-04-23 11:49:05 | INFO | Server 26595dd3-09d4-4758-8d1f-58a40b681d11 finished\n2024-04-23 11:49:05 | INFO | Server 05b9f996-5a06-4359-b495-3463cc7b81e0 finished\n2024-04-23 11:49:05 | INFO | Server 8d372de6-ca07-4afb-9e80-1589fd5242e8 finished\n2024-04-23 11:49:05 | INFO | Runtime: 107.4460s\n"})}),"\n",(0,t.jsx)(n.p,{children:"Using a config directory with configfiles to run the test."}),"\n",(0,t.jsxs)(n.p,{children:["Path to a config directory to pull ",(0,t.jsx)(n.code,{children:"*.conf"})," files from. This file set is sorted,\nso as to provide a predictable parse order if individual options are over-ridden.\nThe set is parsed after the file(s) specified via previous --config file,\narguments hence over-ridden options in the directory take precedence. This\noption must be set from the command-line."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"python src/main.py --config-dir /path/to/config-dir\n"})}),"\n",(0,t.jsx)(n.h2,{id:"config-files",children:"Config files"}),"\n",(0,t.jsxs)(n.p,{children:["The config files which can be used for ",(0,t.jsx)(n.code,{children:"main.py"})," are using the ",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/oslo.config/latest/configuration/quickstart.html",children:"oslo.config format"}),", you can set the command line options as ",(0,t.jsx)(n.code,{children:"key = value pair"})," and create your own config files matching your setup."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="mytest.conf"',children:"[DEFAULT]\ncloud = simple-stress\nnetwork = test-net\nnumber = 6\nparallel = 2\nflavor = SCS-2V-8\nimage = Ubuntu_22.04\nvolume-size = 20\n"})})]})}function f(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c5479f59.3cd2d794.js b/assets/js/c5479f59.3cd2d794.js new file mode 100644 index 0000000000..73117dbf5b --- /dev/null +++ b/assets/js/c5479f59.3cd2d794.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[72283],{80016:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"container/components/container-registry/docs/rate_limit","title":"Rate limit","description":"This page describes how the rate limiting can be set up for the Harbor container registry.","source":"@site/docs/03-container/components/container-registry/docs/rate_limit.md","sourceDirName":"03-container/components/container-registry/docs","slug":"/container/components/container-registry/docs/rate_limit","permalink":"/docs/container/components/container-registry/docs/rate_limit","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/rate_limit.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"SCS deployment","permalink":"/docs/container/components/container-registry/docs/scs-deployment"},"next":{"title":"Upgrade","permalink":"/docs/container/components/container-registry/docs/upgrade"}}');var r=t(74848),s=t(28453);const o={},a="Rate limit",c={},l=[];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",header:"header",p:"p",pre:"pre",strong:"strong",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"rate-limit",children:"Rate limit"})}),"\n",(0,r.jsx)(n.p,{children:"This page describes how the rate limiting can be set up for the Harbor container registry."}),"\n",(0,r.jsxs)(n.p,{children:["Harbor itself doesn't support rate limit protection yet, see open ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor/issues/3419",children:"issue"}),".\nTherefore, we can take advantage of the ingress controller in front of the Harbor. In our case Nginx."]}),"\n",(0,r.jsxs)(n.p,{children:["In the ingress-nginx controller, the rate-limiting options can be specified via ",(0,r.jsx)(n.a,{href:"https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#rate-limiting",children:"annotations"}),".\nE.g. ",(0,r.jsx)(n.code,{children:'nginx.ingress.kubernetes.io/limit-rps: "1"'})," means that ingress will allow only 1 request from a given IP per second.\nClient IP is set based on the use of ",(0,r.jsx)(n.code,{children:"PROXY protocol"})," or from the ",(0,r.jsx)(n.code,{children:"X-Forwarded-For"})," header value.\nIn the SCS reference implementation, proxy protocol for ingress nginx is ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R4.md#enabling-the-proxy-protocol-for-nginx-ingress-and-preliminary-support-for-ovn-lb-325",children:"enabled by default"}),".\nThis rate-limit annotation is ideal for ",(0,r.jsx)(n.em,{children:"DDoS attacks"})," mitigation. When clients exceed this limit\n",(0,r.jsx)(n.strong,{children:"503"})," status code is returned. This status code can be changed via nginx ingress controller configmap:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'$ kubectl edit cm -n ingress-nginx ingress-nginx-controller\n# data:\n# limit-req-status-code: "429"\n'})}),"\n",(0,r.jsxs)(n.p,{children:["There are other useful annotations, such as limit concurrent connections, number of kilobytes per second or limit burst requests.\nE.g. bursts can be configured via ",(0,r.jsx)(n.code,{children:"nginx.ingress.kubernetes.io/limit-burst-multiplier"}),", which is by default ",(0,r.jsx)(n.em,{children:"5"}),".\nIt means that ",(0,r.jsx)(n.a,{href:"http://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req",children:"burst"}),"\nwill be set in this case to ",(0,r.jsx)(n.code,{children:"limit-rps * limit-burst-multiplier = 1 * 5 = 5"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["More information about nginx rate-limiting and real-world examples can be seen in this nginx ",(0,r.jsx)(n.a,{href:"https://www.nginx.com/blog/rate-limiting-nginx/",children:"blog"}),".\nAlso, there is a second option for how the rate limiting can be configured called ",(0,r.jsx)(n.a,{href:"https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#global-rate-limiting",children:"global rate limiting"}),".\nDetailed research and comparison are done in this ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-harbor/issues/38#issuecomment-1570181044",children:"issue"}),".\nFurthermore, see this ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-harbor/pull/42",children:"PR"}),",\nwhich adds a rate limit for the public(registry.scs.community) environment."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var i=t(96540);const r={},s=i.createContext(r);function o(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c5533f5e.4312e23c.js b/assets/js/c5533f5e.4312e23c.js new file mode 100644 index 0000000000..c0d7dc70d6 --- /dev/null +++ b/assets/js/c5533f5e.4312e23c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[69346],{97819:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"scs-0210-v1-k8s-new-version-policy","title":"SCS K8S Version Policy for new Kubernetes versions","description":"The SCS-0210 standard outlines the expected pace at which providers should adopt new Kubernetes versions, aiming\\nfor alignment with the rapid development cycle of Kubernetes. Providers must offer the latest minor version within\\nfour months of its release and the newest patch version within a week, ensuring users have timely access to security\\nupdates, bug fixes, and features. The standard emphasizes the need for expedited updates for critical CVEs and\\nexpects providers to thoroughly test new versions before deployment.\\n","source":"@site/standards/scs-0210-v1-k8s-new-version-policy.md","sourceDirName":".","slug":"/scs-0210-v1-k8s-new-version-policy","permalink":"/standards/scs-0210-v1-k8s-new-version-policy","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS K8S Version Policy for new Kubernetes versions","type":"Standard","stabilized_at":"2023-02-07T00:00:00.000Z","deprecated_at":"2024-02-08T00:00:00.000Z","status":"Deprecated","track":"KaaS","description":"The SCS-0210 standard outlines the expected pace at which providers should adopt new Kubernetes versions, aiming\\nfor alignment with the rapid development cycle of Kubernetes. Providers must offer the latest minor version within\\nfour months of its release and the newest patch version within a week, ensuring users have timely access to security\\nupdates, bug fixes, and features. The standard emphasizes the need for expedited updates for critical CVEs and\\nexpects providers to thoroughly test new versions before deployment.\\n"},"sidebar":"standards","previous":{"title":"scs-0210: SCS K8S Version Policy","permalink":"/standards/kaas/scs-0210"},"next":{"title":"V2","permalink":"/standards/scs-0210-v2-k8s-version-policy"}}');var r=s(74848),i=s(28453);const a={title:"SCS K8S Version Policy for new Kubernetes versions",type:"Standard",stabilized_at:new Date("2023-02-07T00:00:00.000Z"),deprecated_at:new Date("2024-02-08T00:00:00.000Z"),status:"Deprecated",track:"KaaS",description:"The SCS-0210 standard outlines the expected pace at which providers should adopt new Kubernetes versions, aiming\nfor alignment with the rapid development cycle of Kubernetes. Providers must offer the latest minor version within\nfour months of its release and the newest patch version within a week, ensuring users have timely access to security\nupdates, bug fixes, and features. The standard emphasizes the need for expedited updates for critical CVEs and\nexpects providers to thoroughly test new versions before deployment.\n"},o=void 0,d={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function l(e){const t={a:"a",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsx)(t.p,{children:"Here we will describe how fast providers need to keep up with the upstream Kubernetes version."}),"\n",(0,r.jsx)(t.p,{children:"To create an informed decision we summarize here the Kubernetes rules regarding versioning at the time of writing (2023-01-16):"}),"\n",(0,r.jsxs)(t.p,{children:["Kubernetes usually provides about ",(0,r.jsx)(t.strong,{children:"3 minor"})," releases per year (see ",(0,r.jsx)(t.a,{href:"https://kubernetes.io/releases/release/#the-release-cycle",children:"Kubernetes Release Cycle"}),")."]}),"\n",(0,r.jsxs)(t.p,{children:["Patch release cadence is typically monthly. However, the first patches after the first minor release usually arrive 1-2 weeks after the first minor release\n(see ",(0,r.jsx)(t.a,{href:"https://kubernetes.io/releases/patch-releases/#cadence",children:"Patch Release Cadence"}),")."]}),"\n",(0,r.jsxs)(t.p,{children:["As stated in ",(0,r.jsx)(t.a,{href:"https://kubernetes.io/releases/patch-releases/#support-period",children:"Kubernetes Support Period"}),", in general the latest 3 minor versions are maintained by the Kubernetes project.\nEvery release will be maintained for about 14 months.\nThe first 12 months are the standard support period.\nThe remaining 2 months are only for:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"CVEs (under the advisement of the Security Response Committee)"}),"\n",(0,r.jsx)(t.li,{children:"dependency issues (including base image updates)"}),"\n",(0,r.jsx)(t.li,{children:"critical core component issues"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,r.jsx)(t.p,{children:"Kubernetes is a fast-paced project.\nWe want to achieve that providers keep up to date with upstream and do not fall behind Kubernetes releases.\nThis ensures that users are able to upgrade their clusters to address security issues, bug fixes and new features when using SCS compliant clusters in regard to Kubernetes.\nHowever, providers should have reasonable time to implement the new Kubernetes versions and test them."}),"\n",(0,r.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Must provide latest minor version no later than 4 months after release"}),"\n",(0,r.jsx)(t.li,{children:"Must provide latest patch version no later than a week after release"}),"\n",(0,r.jsx)(t.li,{children:"Should be faster for critical CVEs (CVSS >= 8)"}),"\n",(0,r.jsx)(t.li,{children:"Should be tested"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,r.jsxs)(t.p,{children:["All important documents regarding versioning, releases, etc. for the official Kubernetes project can be found on the ",(0,r.jsx)(t.a,{href:"https://kubernetes.io/releases/",children:"Kubernetes Releases page"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,r.jsx)(t.p,{children:"The conformance test is written in the 'k8s-version-recency-check.py' script. The script requires the path to a valid\nkubeconfig file, which should describe the k8s cluster under test. This can either be done by creating a config from\nthe also provided 'config.yaml.template' or by calling the test script with its cli arguments."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>o});var n=s(96540);const r={},i=n.createContext(r);function a(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c6e1beb6.237bf4df.js b/assets/js/c6e1beb6.237bf4df.js new file mode 100644 index 0000000000..c6c7e9cbe3 --- /dev/null +++ b/assets/js/c6e1beb6.237bf4df.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[67085],{31320:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"operating-scs/components/monitoring/docs/alertmanager","title":"Alertmanager notifications in Matrix chat","description":"This page contains instructions on how to enable the Alertmanager to Matrix chat notifications in the Observer solution.","source":"@site/docs/04-operating-scs/components/monitoring/docs/alertmanager.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/alertmanager","permalink":"/docs/operating-scs/components/monitoring/docs/alertmanager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/alertmanager.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Zuul monitoring","permalink":"/docs/operating-scs/components/monitoring/docs/zuul"},"next":{"title":"OAUTH","permalink":"/docs/operating-scs/components/monitoring/docs/oauth"}}');var r=n(74848),a=n(28453);const i={},s="Alertmanager notifications in Matrix chat",c={},l=[];function m(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"alertmanager-notifications-in-matrix-chat",children:"Alertmanager notifications in Matrix chat"})}),"\n",(0,r.jsx)(t.p,{children:"This page contains instructions on how to enable the Alertmanager to Matrix chat notifications in the Observer solution."}),"\n",(0,r.jsxs)(t.p,{children:["Project ",(0,r.jsx)(t.a,{href:"https://github.com/metio/matrix-alertmanager-receiver",children:"https://github.com/metio/matrix-alertmanager-receiver"})," is used for forwarding alerts to a Matrix room."]}),"\n",(0,r.jsxs)(t.p,{children:["To use it, fill your matrix credentials in ",(0,r.jsx)(t.code,{children:"matrix-alertmanager/matrix-alertmanager-receiver.yaml"})," ConfigMap and deploy it:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"kubectl apply -f matrix-alertmanager/matrix-alertmanager-receiver.yaml\n"})}),"\n",(0,r.jsxs)(t.p,{children:["You can modify other settings according to the mentioned project ",(0,r.jsx)(t.a,{href:"https://github.com/metio/matrix-alertmanager-receiver",children:"docs"}),"\nin the ConfigMap."]}),"\n",(0,r.jsxs)(t.p,{children:["You have to also uncomment a related section in ",(0,r.jsx)(t.code,{children:"values-observer.yaml"})," alertmanager section.\nThe sections related to Alertmanager notifications in the ",(0,r.jsx)(t.code,{children:"values-observer-scs.yaml"})," values file are already uncommented."]})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(m,{...e})}):m(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var o=n(96540);const r={},a=o.createContext(r);function i(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c75320ff.146dbcd8.js b/assets/js/c75320ff.146dbcd8.js new file mode 100644 index 0000000000..d2885f7da9 --- /dev/null +++ b/assets/js/c75320ff.146dbcd8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[11407],{61401:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>l,frontMatter:()=>a,metadata:()=>s,toc:()=>g});const s=JSON.parse('{"id":"iaas/guides/upgrade-guide/logging-monitoring","title":"Logging & Monitoring","description":"1. OpenSearch","source":"@site/docs/02-iaas/guides/upgrade-guide/logging-monitoring.md","sourceDirName":"02-iaas/guides/upgrade-guide","slug":"/iaas/guides/upgrade-guide/logging-monitoring","permalink":"/docs/iaas/guides/upgrade-guide/logging-monitoring","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/logging-monitoring.md","tags":[],"version":"current","sidebarPosition":40,"frontMatter":{"sidebar_label":"Logging & Monitoring","sidebar_position":40},"sidebar":"docs","previous":{"title":"Infrastructure","permalink":"/docs/iaas/guides/upgrade-guide/infrastructure"},"next":{"title":"OpenStack","permalink":"/docs/iaas/guides/upgrade-guide/openstack"}}');var r=i(74848),o=i(28453);const a={sidebar_label:"Logging & Monitoring",sidebar_position:40},t="Logging & Monitoring",d={},g=[];function c(e){const n={code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"logging--monitoring",children:"Logging & Monitoring"})}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"OpenSearch"}),"\n",(0,r.jsxs)(n.p,{children:["OpenSearch dashboards is also upgraded with the ",(0,r.jsx)(n.code,{children:"opensearch"})," role."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"osism apply -a pull opensearch\nosism apply -a upgrade opensearch\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Prometheus"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"osism apply -a pull prometheus\nosism apply prometheus\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Grafana"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"osism apply -a pull grafana\nosism apply -a upgrade grafana\n"})}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>t});var s=i(96540);const r={},o=s.createContext(r);function a(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c7e8a920.2290b9a0.js b/assets/js/c7e8a920.2290b9a0.js new file mode 100644 index 0000000000..0c16b9ae8f --- /dev/null +++ b/assets/js/c7e8a920.2290b9a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[81542],{93467:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"scs-0004-v1-achieving-certification","title":"Regulations for achieving SCS-compatible certification","description":"Introduction","source":"@site/standards/scs-0004-v1-achieving-certification.md","sourceDirName":".","slug":"/scs-0004-v1-achieving-certification","permalink":"/standards/scs-0004-v1-achieving-certification","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Regulations for achieving SCS-compatible certification","type":"Procedural","status":"Draft","track":"Global"},"sidebar":"standards","previous":{"title":"scs-0004: Regulations for achieving SCS-compatible certification","permalink":"/standards/global/scs-0004"},"next":{"title":"scs-0005: Governance of the SCS community","permalink":"/standards/global/scs-0005"}}');var a=i(74848),s=i(28453);const o={title:"Regulations for achieving SCS-compatible certification",type:"Procedural",status:"Draft",track:"Global"},r=void 0,c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Regulations",id:"regulations",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Open Questions",id:"open-questions",level:2},{value:"Related Documents",id:"related-documents",level:2}];function d(e){const t={a:"a",em:"em",h2:"h2",li:"li",ol:"ol",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,a.jsxs)(t.p,{children:["The Sovereign Cloud Stack (SCS) issues certificates with various scopes, among them ",(0,a.jsx)(t.em,{children:"SCS-compatible IaaS"})," (infrastructure as a service) and ",(0,a.jsx)(t.em,{children:"SCS-compatible KaaS"})," (Kubernetes as a service)."]}),"\n",(0,a.jsx)(t.p,{children:"This document details how a cloud service provider (henceforth also called operator) can attain such a certificate for one of their clouds."}),"\n",(0,a.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,a.jsx)(t.p,{children:"As operator, I want to obtain a certificate with the scope SCS-compatible IaaS or SCS-compatible KaaS."}),"\n",(0,a.jsx)(t.h2,{id:"regulations",children:"Regulations"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Each certificate issued pertains to a given cloud, a given scope, and a given version of that scope with a fixed expiry date. The certificate is only valid for that cloud and for the time frame that ends on that expiry date."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:["The operator MUST include the official ",(0,a.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Tests",children:"SCS compliance test suite"})," (which does not require admin privileges) in their continuous test infrastructure (e.g., Zuul). The tests MUST be run at given intervals, depending on their resource-usage classification:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"light"}),": at least nightly,"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"medium"}),": at least weekly,"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.em,{children:"heavy"}),": at least monthly."]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"For public clouds, it is recommended to offer the SCS project access to the infrastructure so the test suite runs can be triggered continuously by the SCS team."}),"\n",(0,a.jsx)(t.p,{children:"Alternatively, and for non-public clouds, the results (log files) MUST be submitted to SCS (by a mechanism of SCS' choice) at least weekly, and they need to be reproduced again on request by SCS."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"If the desired certificate requires manual checks, then the operator MUST offer the SCS project suitable access. Manual checks MUST be repeated once every quarter."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsxs)(t.p,{children:["Details on the standards achieved, as well as the current state and the history of all test and check results of the past 18 months will be displayed on a public webpage (henceforth, ",(0,a.jsx)(t.em,{children:"certificate status page"}),") owned by SCS."]}),"\n",(0,a.jsx)(t.p,{children:"The page will be kept online for the duration of the certificate's validity, plus at least 3 months; afterwards, it can be taken offline, either upon request or in the course of maintenance cleanup. However, the page's content won't be deleted until 12 months after the certificate's expiration, for the page will be reanimated and reused if, within this timeframe, a new certificate is issued for the same scope and the same cloud."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The SCS certification assessment body (initially the SCS project in the OSB Alliance e.V., possibly further entities empowered to do so by the SCS trademark owner, currently the OSB Alliance e.V.) WILL review the certification application and either grant the certification, reject it or ask for further measures or information."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:'Once the certificate is granted by the SCS certification assessment body, the operator SHOULD use the corresponding logo and publicly state the certified "SCS compatibility" on the respective layer for the time of the validity of the certification. In case of a public cloud, this public display is even REQUIRED. In any case, the logo MUST be accompanied by a hyperlink (a QR code for printed assets) to the respective certificate status page.'}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"If the certificate is to be revoked for any reason, it will be included in a publicly available Certificate Revocation List (CRL). This fact will also be reflected in the certificate status page."}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"If any of the automated tests or manual checks fail after the certificate has been issued, the certificate is not immediately revoked. Rather, the automated tests MUST pass 99.x % of the runs, and the operator SHALL be notified at the second failed attempt in a row at the latest. In case a manual check fails, it has to be repeated at a date to be negotiated with SCS. It MAY NOT fail more than two times in a row."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,a.jsx)(t.h2,{id:"open-questions",children:"Open Questions"}),"\n",(0,a.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,a.jsxs)(t.p,{children:["As of now, this document pertains to the certificate scopes on the certification level ",(0,a.jsx)(t.em,{children:"SCS-compatible"})," only. It will be extended to cover the remaining levels as they become relevant, either directly or by way of referring to additional documents."]}),"\n",(0,a.jsxs)(t.p,{children:["For details on our mechanisms for developing, denoting, and versioning the certificate scopes, we refer to the document ",(0,a.jsx)(t.a,{href:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",children:"scs-0003-v1"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>o,x:()=>r});var n=i(96540);const a={},s=n.createContext(a);function o(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c8d5479b.1facc27a.js b/assets/js/c8d5479b.1facc27a.js new file mode 100644 index 0000000000..065c4634e2 --- /dev/null +++ b/assets/js/c8d5479b.1facc27a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[19289],{70027:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"iam/scs-0302","title":"scs-0302: Domain Manager configuration for Keystone","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iam/scs-0302.md","sourceDirName":"iam","slug":"/iam/scs-0302","permalink":"/standards/iam/scs-0302","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0301-v1-naming-conventions"},"next":{"title":"V1","permalink":"/standards/scs-0302-v1-domain-manager-role"}}');var r=t(74848),a=t(28453);const i={},d="scs-0302: Domain Manager configuration for Keystone",o={},c=[{value:"Supplement: Domain Manager implementation notes",id:"supplement-domain-manager-implementation-notes",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"scs-0302-domain-manager-configuration-for-keystone",children:"scs-0302: Domain Manager configuration for Keystone"})}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Version"}),(0,r.jsx)(n.th,{children:"Type"}),(0,r.jsx)(n.th,{children:"State"}),(0,r.jsx)(n.th,{children:"stabilized"}),(0,r.jsx)(n.th,{children:"deprecated"})]})}),(0,r.jsx)(n.tbody,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/standards/scs-0302-v1-domain-manager-role",children:"scs-0302-v1"})}),(0,r.jsx)(n.td,{children:"Standard"}),(0,r.jsx)(n.td,{children:"Stable"}),(0,r.jsx)(n.td,{children:"2024-11-13"}),(0,r.jsx)(n.td,{children:"-"})]})})]}),"\n",(0,r.jsx)(n.h2,{id:"supplement-domain-manager-implementation-notes",children:"Supplement: Domain Manager implementation notes"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Version"}),(0,r.jsx)(n.th,{children:"State"}),(0,r.jsx)(n.th,{children:"stabilized"}),(0,r.jsx)(n.th,{children:"deprecated"})]})}),(0,r.jsx)(n.tbody,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/standards/scs-0302-w1-domain-manager-implementation-notes",children:"w1"})}),(0,r.jsx)(n.td,{children:"Draft"}),(0,r.jsx)(n.td,{children:"-"}),(0,r.jsx)(n.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>d});var s=t(96540);const r={},a=s.createContext(r);function i(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9581477.5bb98b23.js b/assets/js/c9581477.5bb98b23.js new file mode 100644 index 0000000000..4038e0d00c --- /dev/null +++ b/assets/js/c9581477.5bb98b23.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[86293],{23242:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/nova","title":"Nova","description":"* Nova admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/nova.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/nova","permalink":"/docs/iaas/guides/configuration-guide/openstack/nova","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/nova.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Nova"},"sidebar":"docs","previous":{"title":"Neutron","permalink":"/docs/iaas/guides/configuration-guide/openstack/neutron"},"next":{"title":"Octavia","permalink":"/docs/iaas/guides/configuration-guide/openstack/octavia"}}');var t=o(74848),i=o(28453);const a={sidebar_label:"Nova"},r="Nova",d={},c=[{value:"Nested virtualisation",id:"nested-virtualisation",level:2},{value:"AMD",id:"amd",level:3},{value:"Intel",id:"intel",level:3},{value:"Reserve compute node resources",id:"reserve-compute-node-resources",level:2},{value:"Host memory",id:"host-memory",level:3},{value:"Host CPUs",id:"host-cpus",level:3},{value:"Dedicated cores for instances",id:"dedicated-cores-for-instances",level:2},{value:"Add NUMA topology filter to nova scheduler",id:"add-numa-topology-filter-to-nova-scheduler",level:3},{value:"Specify CPU cores to be used as dedicated cores",id:"specify-cpu-cores-to-be-used-as-dedicated-cores",level:3},{value:"Create flavors or images backed by dedicated cores",id:"create-flavors-or-images-backed-by-dedicated-cores",level:3},{value:"Mixing dedicated and shared cores on a compute node",id:"mixing-dedicated-and-shared-cores-on-a-compute-node",level:3},{value:"Mixing dedicated and shared cores in a nova instance",id:"mixing-dedicated-and-shared-cores-in-a-nova-instance",level:3},{value:"Creating images with special CPU requirements",id:"creating-images-with-special-cpu-requirements",level:3},{value:"Back instance memory by hugepages",id:"back-instance-memory-by-hugepages",level:2},{value:"Local SSD storage",id:"local-ssd-storage",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"nova",children:"Nova"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/admin/index.html",children:"Nova admin guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/index.html",children:"Nova configuration guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/config.html",children:"Nova configuration reference"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"nested-virtualisation",children:"Nested virtualisation"}),"\n",(0,t.jsx)(n.h3,{id:"amd",children:"AMD"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'echo "options kvm-amd nested=y" | sudo tee /etc/modprobe.d/kvm-nested-virtualization.conf\nsudo modprobe -r kvm_amd\nsudo modprobe kvm_amd\ncat /sys/module/kvm_amd/parameters/nested\nY\ndocker restart nova_libvirt\n'})}),"\n",(0,t.jsx)(n.h3,{id:"intel",children:"Intel"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'echo "options kvm-intel nested=y" | sudo tee /etc/modprobe.d/kvm-nested-virtualization.conf\nsudo modprobe -r kvm_intel\nsudo modprobe kvm_intel\ncat /sys/module/kvm_intel/parameters/nested\nY\ndocker restart nova_libvirt\n'})}),"\n",(0,t.jsx)(n.h2,{id:"reserve-compute-node-resources",children:"Reserve compute node resources"}),"\n",(0,t.jsx)(n.p,{children:"How many resources you want to reserve on a compute node depends very much on which additional\nservices are running on the compute node."}),"\n",(0,t.jsx)(n.h3,{id:"host-memory",children:"Host memory"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.reserved_host_memory_mb",children:"https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.reserved_host_memory_mb"})}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="environments/kolla/files/overlays/nova/nova-compute.conf"',children:"[DEFAULT]\nreserved_host_memory_mb = 32768\n"})}),"\n",(0,t.jsx)(n.h3,{id:"host-cpus",children:"Host CPUs"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.reserved_host_cpus",children:"https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.reserved_host_cpus"})}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="environments/kolla/files/overlays/nova/nova-compute.conf"',children:"[DEFAULT]\nreserved_host_cpus = 4\n"})}),"\n",(0,t.jsx)(n.h2,{id:"dedicated-cores-for-instances",children:"Dedicated cores for instances"}),"\n",(0,t.jsxs)(n.p,{children:["This section will describe how to use dedicated cores for nova instances. There are a few configuration options involved, so please refer to ",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/admin/cpu-topologies.html",children:"the upstream documentation"})," for a full overview of possible combinations and results."]}),"\n",(0,t.jsx)(n.h3,{id:"add-numa-topology-filter-to-nova-scheduler",children:"Add NUMA topology filter to nova scheduler"}),"\n",(0,t.jsxs)(n.p,{children:["Add the ",(0,t.jsx)(n.code,{children:"NUMATopologyFilter"})," to the list of enabled nova filters.\nThe filter makes the nova scheduler ",(0,t.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Non-uniform_memory_access",children:"NUMA"})," aware, so that the instance will have pinned cores from the same NUMA node.\nGet the list of currently enabled filters or use the list of ",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/config.html#filter_scheduler.enabled_filters",children:"default filters"})," and add the ",(0,t.jsx)(n.code,{children:"NUMATopologyFilter"})," in the nova-scheduler config, e.g.:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="environments/kolla/files/overlays/nova/nova-scheduler.conf"',children:"[filter_scheduler]\nenabled_filters = ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter,NUMATopologyFilter\n"})}),"\n",(0,t.jsx)(n.p,{children:"Apply the configuration using the osism CLI on the manager"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply nova\n"})}),"\n",(0,t.jsx)(n.h3,{id:"specify-cpu-cores-to-be-used-as-dedicated-cores",children:"Specify CPU cores to be used as dedicated cores"}),"\n",(0,t.jsxs)(n.p,{children:["The nova compute service needs to be aware of which CPU threads should be used as dedicated cores on each hypervisor. The config option ",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/config.html#compute.cpu_dedicated_set",children:"cpu_dedicated_set"})," is used to do that. It takes a comma-separated list of CPU threads, ranges or threads to exclude.\nBefore deciding on the set of dedicated cores assess the number of services and their required CPU load to exclude the required number of threads from the list.\nThe following example will leave thread 0 and 1 for the compute node and use ansible facts to extend the range to the other available threads:"]}),"\n",(0,t.jsxs)(n.p,{children:["Warning: Do ",(0,t.jsx)(n.strong,{children:"not"})," use ",(0,t.jsx)(n.code,{children:"ansible_processor_*"})," facts if you intend to use ",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/config.html#libvirt.cpu_power_management_strategy",children:"cpu_power_management_strategy=cpu_state"})," as offline cores will not be shown and subsequent applies will result in a wrong range"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="environments/kolla/files/overlays/nova/nova-compute.conf"',children:"[compute]\ncpu_dedicated_set=2-{{ ansible_facts['processor_nproc'] - 1 }}\n"})}),"\n",(0,t.jsx)(n.p,{children:"You may use node specific configuration to override the dedicated set for specific compute nodes, e.g.:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="environments/kolla/files/overlays/nova/$INVENTORY_HOSTNAME/nova-compute.conf"',children:"[compute]\ncpu_dedicated_set=4-12,^8,15\n"})}),"\n",(0,t.jsx)(n.p,{children:"Apply the configuration using the osism CLI on the manager"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply nova\n"})}),"\n",(0,t.jsx)(n.h3,{id:"create-flavors-or-images-backed-by-dedicated-cores",children:"Create flavors or images backed by dedicated cores"}),"\n",(0,t.jsxs)(n.p,{children:["To make the configured dedicated cores available to users, create flavors with property ",(0,t.jsx)(n.code,{children:"hw:cpu_policy=dedicated"}),", so that the given ",(0,t.jsx)(n.code,{children:"vcpus"})," will be pinned to the threads in the dedicated set specified on the compute node, e.g.:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"openstack flavor create --ram 4096 --disk 10 --vcpus 2 --property hw:cpu_policy=dedicated $FLAVOR_NAME \n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that this configuration will pin the qemu emulator threads to the instances CPUs. This will be fine for most workloads, but might not be sufficient for real-time or latency sensitive workloads like loadbalancers. If you get reports of ",(0,t.jsx)(n.a,{href:"https://docs.kernel.org/filesystems/proc.html#miscellaneous-kernel-statistics-in-proc-stat",children:"CPU steal"})," on an instance with dedicated cores or know that you need this, you may pin the emulator threads to another dedicated core by setting the property ",(0,t.jsx)(n.code,{children:"hw:emulator_threads_policy=isolate"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"openstack flavor set --property hw:emulator_threads_policy=isolate $FLAVOR_NAME \n"})}),"\n",(0,t.jsx)(n.h3,{id:"mixing-dedicated-and-shared-cores-on-a-compute-node",children:"Mixing dedicated and shared cores on a compute node"}),"\n",(0,t.jsxs)(n.p,{children:["You may also mix dedicated and shared cores on a single compute node by adding cores to the ",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/config.html#compute.cpu_shared_set",children:"shared CPU set"}),", e.g."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="environments/kolla/files/overlays/nova/nova-compute.conf"',children:"[compute]\ncpu_shared_set=4-12,^8,15\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This will allow nova to schedule instances with floating cores on this set of CPU cores.\nWhen a shared CPU set is specified setting the property ",(0,t.jsx)(n.code,{children:"hw:emulator_threads_policy=share"})," will pin the emulator threads to this set of cores."]}),"\n",(0,t.jsx)(n.h3,{id:"mixing-dedicated-and-shared-cores-in-a-nova-instance",children:"Mixing dedicated and shared cores in a nova instance"}),"\n",(0,t.jsxs)(n.p,{children:["It is possible to create instances with a mixed set of dedicated and shared CPU cores. Set the property ",(0,t.jsx)(n.code,{children:"hw:cpu_policy=mixed"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"openstack flavor set --property hw:cpu_policy=mixed $MIXED_FLAVOR_NAME \n"})}),"\n",(0,t.jsxs)(n.p,{children:["and specify a mask for the instance cores which are to be pinned with property ",(0,t.jsxs)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/extra-specs.html#hw:cpu_dedicated_mask",children:["hw",":cpu_dedicated_mask"]}),". E.g.:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"openstack flavor set --property hw:cpu_dedicated_mask=0-1 $MIXED_FLAVOR_NAME \n"})}),"\n",(0,t.jsx)(n.p,{children:"to pin instance cores 0 and 1."}),"\n",(0,t.jsx)(n.h3,{id:"creating-images-with-special-cpu-requirements",children:"Creating images with special CPU requirements"}),"\n",(0,t.jsx)(n.p,{children:"All properties used in this section may also be set on images to indicate that instances should use the specified mixed or dedicated cores or isolated emulator threads. Note however that properties set on flavors take precedence."}),"\n",(0,t.jsx)(n.h2,{id:"back-instance-memory-by-hugepages",children:"Back instance memory by hugepages"}),"\n",(0,t.jsxs)(n.p,{children:["Qemu/KVM can make use of hugepages, which reduces the required number of TLB entries for the instances memory. Thus it will reduce the number TLB misses, which will result in faster memory access inside the instance.\nAs with ",(0,t.jsx)(n.a,{href:"#dedicated-cores-for-instances",children:"dedicated cores"})," usage will enable NUMA topologies and require the ",(0,t.jsx)(n.a,{href:"#add-numa-topology-filter-to-nova-scheduler",children:"NUMA topology filter to be added to the nova-scheduler's enabled filters"}),".\nSince allocating hugepages requires contiguous regions of memory it is advisable to do so at boot time, by ",(0,t.jsx)(n.a,{href:"https://docs.kernel.org/admin-guide/mm/hugetlbpage.html",children:"specifying the required size and number of hugepages on the kernel cmdline"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["If you have configured dedicated cores, make sure to configure a matching hugepage reservation by NUMA node.\nE.g. assuming a compute node with two NUMA nodes of 32GB where some cores and 8GB of 4k memory pages on the first NUMA node are reserved for the hypervisor services, while the rest should be used as hugepage-backed instance memory, the following cmdline could be used: ",(0,t.jsx)(n.code,{children:"default_hugepagesz=1G transparent_hugepage=never hugepagesz=1G hugepages=0:24,1:32"}),"\nThis would set a default hugepage size of 1GB, turn off ",(0,t.jsx)(n.a,{href:"https://docs.kernel.org/admin-guide/mm/transhuge.html",children:"transparent hugepages"}),", and reserve 24 1GB hugepages on NUMA node 0 and 32 1GB hugepages on NUMA node 1.\nTo set this via osism for a group of hosts defined in the inventory create or add to the file with the following content:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/group_vars/INVENTORY_GROUP_NAME.yml"',children:"---\ngrub__configuration:\n - name: cmdline_linux\n value:\n - default_hugepagesz=1G\n - transparent_hugepage=never\n - hugepagesz=1G\n - hugepages=0:24,1:32\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Of course the same configuration may also be set by host using ",(0,t.jsx)(n.code,{children:"host_vars"})," in ",(0,t.jsx)(n.code,{children:"inventory/host_vars/INVENTORY_HOST_NAME.yml"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Sync the variables with the inventory by running"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism sync inventory\n"})}),"\n",(0,t.jsx)(n.p,{children:"and apply the configuration with"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply grub\n"})}),"\n",(0,t.jsxs)(n.p,{children:["After rebooting the nodes the hugepages will be allocated. You may check this by, e.g. looking at the corresponding values in ",(0,t.jsx)(n.code,{children:"/proc/meminfo"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"grep Huge /proc/meminfo\nAnonHugePages: 0 kB\nShmemHugePages: 0 kB\nFileHugePages: 0 kB\nHugePages_Total: 24\nHugePages_Free: 24\nHugePages_Rsvd: 0\nHugePages_Surp: 0\nHugepagesize: 1048576 kB\nHugetlb: 25165824 kB\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you require hugepages for services on the compute node, make sure to configure nova to reserve them for the host by setting ",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.reserved_huge_pages",children:"DEFAULT.reserved_huge_pages"})," accordingly."]}),"\n",(0,t.jsxs)(n.p,{children:["To back an instance's memory by hugepages add the property ",(0,t.jsx)(n.code,{children:"hw:mem_page_size=large"})," to a flavor and create the instance from it, e.g.:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"openstack flavor set --property hw:mem_page_size=large $FLAVOR_NAME\n"})}),"\n",(0,t.jsx)(n.h2,{id:"local-ssd-storage",children:"Local SSD storage"}),"\n",(0,t.jsxs)(n.p,{children:["In this example, a local SSD is provided for use on compute node ",(0,t.jsx)(n.code,{children:"testbed-node-0"}),".\nBy default, Nova accesses the local storage on a file basis."]}),"\n",(0,t.jsxs)(n.p,{children:["It is also possible to work with logical volumes instead. However, this is not\nrecommended or supported by OSISM. More details in the\n",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/admin/configuration/index.html",children:"Nova Configuration Guide"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["On the compute node, the local SSD to be used is formatted with a file system of\nyour choice and mounted to ",(0,t.jsx)(n.code,{children:"/var/lib/nova"}),". When using more than one local SSD, a\nsoftware RAID 1 should be used It is recommended to automate the creation of the\nfile system and the creation of the mount point with a custom playbook."]}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.code,{children:"nova.conf"})," configuration file is created as an overlay file for the compute node\n",(0,t.jsx)(n.code,{children:"testbed-node-0"}),". The name of the directory must match the name of the host in the\ninventory. If the compute node has a file with the name ",(0,t.jsx)(n.code,{children:"testbed-node-0.yml"})," in the\n",(0,t.jsx)(n.code,{children:"host_vars"})," directory in the inventory, then the name of the directory\nin the overlays is ",(0,t.jsx)(n.code,{children:"testbed-node-0"})," accordingly. If the file name there were\n",(0,t.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz.yml"})," then the name of the directory would be\n",(0,t.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="environments/kolla/files/overlays/nova/testbed-node-0/nova.conf"',children:"[libvirt]\nimages_type = raw\n\n[glance]\nenable_rbd_download = true\n"})}),"\n",(0,t.jsxs)(n.p,{children:["As Ceph is still used as the storage backend for Glance and Cinder, the image type is\nset to ",(0,t.jsx)(n.code,{children:"raw"}),". To allow to download and cache images from Ceph via rbd rather than the\nGlance API via http ",(0,t.jsx)(n.code,{children:"enable_rbd_download"})," is set to ",(0,t.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Parameters must also be added in the inventory. This differs depending on the OSISM\nversion used."}),"\n",(0,t.jsx)(n.p,{children:"Up to OSISM 6 it looks like this:"}),"\n",(0,t.jsxs)(n.p,{children:["In the inventory, the parameter ",(0,t.jsx)(n.code,{children:"nova_instance_datadir_volume"}),"\nis added in the section for the ",(0,t.jsx)(n.code,{children:"kolla"})," environment."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/testbed-node-0.yml"',children:"##########################################################\n# kolla\n\nnova_instance_datadir_volume: /var/lib/nova\n"})}),"\n",(0,t.jsx)(n.p,{children:"Starting with OSISM 7, it looks like this:"}),"\n",(0,t.jsxs)(n.p,{children:["In the inventory, the parameters ",(0,t.jsx)(n.code,{children:"nova_instance_datadir_volume"})," and ",(0,t.jsx)(n.code,{children:"nova_backend"}),",\nare added in the section for the ",(0,t.jsx)(n.code,{children:"kolla"})," environment."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/testbed-node-0.yml"',children:"##########################################################\n# kolla\n\nnova_instance_datadir_volume: /var/lib/nova\nnova_backend: default\n"})}),"\n",(0,t.jsx)(n.p,{children:"It is currently not possible to completely deactivate the Ceph integration with Nova.\nSo if you have all compute nodes with local storage, you still have to do the Ceph\nintegration for Nova itself and convert each compute node specifically to local storage.\nIf this is not done, errors will occur when deploying Nova."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>a,x:()=>r});var s=o(96540);const t={},i=s.createContext(t);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9b16325.c24a123d.js b/assets/js/c9b16325.c24a123d.js new file mode 100644 index 0000000000..b88f8aff2c --- /dev/null +++ b/assets/js/c9b16325.c24a123d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[82798],{16348:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>a,frontMatter:()=>s,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"development/index","title":"Developer documentation","description":"Welcome to the developer section of the contributor docs. Here you will find","source":"@site/contributor-docs/development/index.md","sourceDirName":"development","slug":"/development/","permalink":"/contributor-docs/development/","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"devDocs","next":{"title":"SCS RFC2119 Keyword Test Guide","permalink":"/contributor-docs/development/tests/rfc2119-keyword-test-guide"}}');var r=o(74848),c=o(28453);const s={},i="Developer documentation",d={},l=[];function u(e){const t={h1:"h1",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"developer-documentation",children:"Developer documentation"})}),"\n",(0,r.jsx)(t.p,{children:"Welcome to the developer section of the contributor docs. Here you will find\nguidelines for the implementation of tooling such as the SCS conformance tests."})]})}function a(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,o)=>{o.d(t,{R:()=>s,x:()=>i});var n=o(96540);const r={},c=n.createContext(r);function s(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ca219831.13d44dfe.js b/assets/js/ca219831.13d44dfe.js new file mode 100644 index 0000000000..7cba5e6426 --- /dev/null +++ b/assets/js/ca219831.13d44dfe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[46471],{71535:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"application-examples/opendesk-on-scs/getting_started","title":"Getting started: Deployment from a local machine","description":"Please note the general Getting Started documentation by openDesk.","source":"@site/user-docs/application-examples/opendesk-on-scs/getting_started.md","sourceDirName":"application-examples/opendesk-on-scs","slug":"/application-examples/opendesk-on-scs/getting_started","permalink":"/user-docs/application-examples/opendesk-on-scs/getting_started","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"userDocs","previous":{"title":"Requirements","permalink":"/user-docs/application-examples/opendesk-on-scs/requirements"},"next":{"title":"Configuration","permalink":"/user-docs/application-examples/opendesk-on-scs/configuration"}}');var r=s(74848),o=s(28453);const a={},i="Getting started: Deployment from a local machine",l={},d=[{value:"Clone the openDesk repository",id:"clone-the-opendesk-repository",level:2},{value:"Add settings for your environment",id:"add-settings-for-your-environment",level:2},{value:"Choose your components",id:"choose-your-components",level:2},{value:"Basic configuration",id:"basic-configuration",level:2},{value:"Namespace",id:"namespace",level:2},{value:"Deploy an ingress resource inside the namespace",id:"deploy-an-ingress-resource-inside-the-namespace",level:2},{value:"Deployment",id:"deployment",level:2},{value:"First login",id:"first-login",level:2},{value:"Deploy the desired apps",id:"deploy-the-desired-apps",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"getting-started-deployment-from-a-local-machine",children:"Getting started: Deployment from a local machine"})}),"\n",(0,r.jsxs)(n.p,{children:["Please note the general ",(0,r.jsx)(n.a,{href:"https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk/-/blob/main/docs/getting-started.md",children:"Getting Started documentation"})," by openDesk."]}),"\n",(0,r.jsx)(n.h2,{id:"clone-the-opendesk-repository",children:"Clone the openDesk repository"}),"\n",(0,r.jsxs)(n.p,{children:["Clone the ",(0,r.jsx)(n.a,{href:"https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk",children:"openDesk repository"})," to your local computer:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"git clone https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk\ncd opendesk\n"})}),"\n",(0,r.jsx)(n.h2,{id:"add-settings-for-your-environment",children:"Add settings for your environment"}),"\n",(0,r.jsx)(n.p,{children:"Create your own directory for one or more environments:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"mkdir -p helmfile/environments/example-env/dev/\n"})}),"\n",(0,r.jsxs)(n.p,{children:["In the folder you created, add one or more files with the configuration for your environment, e.g. ",(0,r.jsx)(n.code,{children:"values.yaml.gotmpl"})," (see the ",(0,r.jsx)(n.a,{href:"getting_started",children:"Getting Started"})," chapter for an example)."]}),"\n",(0,r.jsxs)(n.p,{children:["Reference the environment you want to deploy in ",(0,r.jsx)(n.code,{children:"helmfile.yaml"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'cat helmfile.yaml <<__EOF__\nexample-env:\n values:\n - "helmfile/environments/example-env/dev/*.yaml.gotmpl"\n__EOF__\n'})}),"\n",(0,r.jsx)(n.h2,{id:"choose-your-components",children:"Choose your components"}),"\n",(0,r.jsxs)(n.p,{children:["Decide which ",(0,r.jsx)(n.a,{href:"https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk/-/blob/main/docs/components.md",children:"components"})," you want to deploy. If you start with some apps only, you can enable the rest of them later.\nIn the example configuration below all apps are enabled for the initial rollout."]}),"\n",(0,r.jsx)(n.h2,{id:"basic-configuration",children:"Basic configuration"}),"\n",(0,r.jsxs)(n.p,{children:["You can use the following example settings as a starting point for your ",(0,r.jsx)(n.code,{children:"helmfile/environments/example-env/dev/values.yaml.gotmpl"})," file. Please see the ",(0,r.jsx)(n.a,{href:"/user-docs/application-examples/opendesk-on-scs/configuration",children:"configuration"})," chapter for more details."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'{{/*\nSPDX-FileCopyrightText: 2024 Zentrum f\xfcr Digitale Souver\xe4nit\xe4t der \xd6ffentlichen Verwaltung (ZenDiS) GmbH\nSPDX-FileCopyrightText: 2023 Bundesministerium des Innern und f\xfcr Heimat, PG ZenDiS "Projektgruppe f\xfcr Aufbau ZenDiS"\nSPDX-License-Identifier: Apache-2.0\n*/}}\n\n---\ngrafana:\n dashboards:\n annotations:\n "grafana-dashboard-folder": "openDesk: {{ env "NAMESPACE" | default "Main" }}"\n enabled: true\n\nfunctional:\n authentication:\n twoFactor:\n # Define a list of groups to enable 2FA for.\n # Note: Removing a group from the list will not disable 2FA for the removed group.\n groups: []\n\ncertificate:\n issuerRef:\n name: "letsencrypt-prod"\n wildcard: true\n\ningress:\n ingressClassName: "nginx"\n\npersistence:\n storageClassNames:\n RWX: "csi-cinder-sc-delete"\n RWO: "csi-cinder-sc-delete"\n\nsmtp:\n host: "host.example-relay.org"\n username: "some-account"\n port: 587\n\nturn:\n server:\n host: "turn.example.org"\n port: "3478"\n tls:\n host: "turn.example.org"\n port: "5349"\n\ncluster:\n service:\n type: "ClusterIP"\n api:\n domain: "api.example.org"\n port: 6443\n networking:\n ingressGatewayIP: "YOUR-PUBLIC-IP"\n\nprometheus:\n serviceMonitors:\n enabled: true\n podMonitors:\n enabled: true\n prometheusRules:\n enabled: true\n\nsecurity:\n clusterPostfix:\n namespace: "swp-cross-instance-mail"\n\ndebug:\n enabled: true\n\ndatabases:\n oxAppsuite:\n host: "mariadb"\n # DB name has to set or else "configdb" will used while "openxchange" is created.\n name: "openxchange"\n username: "root"\n\ncollabora:\n enabled: true\n\ncryptpad:\n enabled: true\n\nelement:\n enabled: true\n\nintercom:\n enabled: true\n\njitsi:\n enabled: true\n\nnextcloud:\n enabled: true\n\nopenproject:\n enabled: true\n\noxAppsuite:\n enabled: true\n\noxConnector:\n enabled: true\n\nxwiki:\n enabled: true\n\n...\n\n'})}),"\n",(0,r.jsx)(n.h2,{id:"namespace",children:"Namespace"}),"\n",(0,r.jsx)(n.p,{children:"Create a namespace in your SCS cluster:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl create namespace your-namespace\n"})}),"\n",(0,r.jsx)(n.h2,{id:"deploy-an-ingress-resource-inside-the-namespace",children:"Deploy an ingress resource inside the namespace"}),"\n",(0,r.jsx)(n.p,{children:"Create an ingress resource:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'cat >ingress-resource.yaml <<EOF\n---\napiVersion: "networking.k8s.io/v1"\nkind: "Ingress"\nmetadata:\n name: "example.org"\n annotations:\n cert-manager.io/cluster-issuer: "letsencrypt-prod"\nspec:\n ingressClassName: "nginx"\n tls:\n - hosts:\n - "example.org"\n - "*.example.org"\n secretName: "opendesk-certificates-tls"\n rules:\n - host: "*.example.org"\n http:\n paths:\n - pathType: "Prefix"\n path: "/"\n backend:\n service:\n name: "ums-portal-frontend"\n port:\n number: 443\nEOF\n'})}),"\n",(0,r.jsx)(n.p,{children:"Deploy the ingress resource inside your namespace:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f ingress-resource.yaml -n your-namespace\n"})}),"\n",(0,r.jsx)(n.h2,{id:"deployment",children:"Deployment"}),"\n",(0,r.jsx)(n.p,{children:"Trigger the deployment:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'OPENDESK_SMTPRELAY_PASSWORD="************" OPENDESK_MASTER_PASSWORD="************" DOMAIN="example.org" helmfile apply -e example-env -n your-namespace\n\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Note that the ",(0,r.jsx)(n.a,{href:"helper/deploy-openDesk",children:"wrapper script"})," supports you in running some of the above tasks."]}),"\n",(0,r.jsx)(n.h2,{id:"first-login",children:"First login"}),"\n",(0,r.jsx)(n.p,{children:"Two accounts, an admin and a user account, are automatically created for you."}),"\n",(0,r.jsxs)(n.p,{children:["The default admin user is called ",(0,r.jsx)(n.code,{children:"default.admin"}),", you can retrieve its password by running:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl -n your-namespace get secret ums-nubus-credentials -o json | jq -r '.data.admin_password' | base64 -d\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The default user is called ",(0,r.jsx)(n.code,{children:"default.user"}),", you can retrieve its password by running:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl -n your-namespace get secret ums-nubus-credentials -o json | jq -r '.data.user_password' | base64 -d\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Open the portal in your browser, e.g. ",(0,r.jsx)(n.code,{children:"https://portal.example.org"})," and log in."]}),"\n",(0,r.jsx)(n.h2,{id:"deploy-the-desired-apps",children:"Deploy the desired apps"}),"\n",(0,r.jsxs)(n.p,{children:["To add an app later you don't have to run ",(0,r.jsx)(n.code,{children:"helmfile"})," in the top-level directory. You can ",(0,r.jsx)(n.code,{children:"cd"})," into the app's directory underneath ",(0,r.jsx)(n.code,{children:"helmfile/apps"})," an execute ",(0,r.jsx)(n.code,{children:"helmfile"})," in there. The advantage is that this is faster."]})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>i});var t=s(96540);const r={},o=t.createContext(r);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/caeeb51c.657fcbd3.js b/assets/js/caeeb51c.657fcbd3.js new file mode 100644 index 0000000000..ad72230127 --- /dev/null +++ b/assets/js/caeeb51c.657fcbd3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[25162],{57887:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"iaas/guides/concept-guide/index","title":"Concept Guide","description":"Highlevel Overview","source":"@site/docs/02-iaas/guides/concept-guide/index.md","sourceDirName":"02-iaas/guides/concept-guide","slug":"/iaas/guides/concept-guide/","permalink":"/docs/iaas/guides/concept-guide/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/index.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Concept Guide","sidebar_position":10},"sidebar":"docs","previous":{"title":"IaaS Layer","permalink":"/docs/category/iaas-layer"},"next":{"title":"Components","permalink":"/docs/iaas/guides/concept-guide/components/"}}');var s=r(74848),a=r(28453);const t={sidebar_label:"Concept Guide",sidebar_position:10},l="Concept Guide",c={},d=[{value:"Highlevel Overview",id:"highlevel-overview",level:2},{value:"Components in a cluster",id:"components-in-a-cluster",level:2},{value:"Requirements",id:"requirements",level:2},{value:"Layers in a cluster",id:"layers-in-a-cluster",level:2},{value:"Cluster design",id:"cluster-design",level:2},{value:"Use cases",id:"use-cases",level:2},{value:"Hardware Bill of Materials",id:"hardware-bill-of-materials",level:2}];function o(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"concept-guide",children:"Concept Guide"})}),"\n",(0,s.jsx)(n.h2,{id:"highlevel-overview",children:"Highlevel Overview"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"OSISM overview",src:r(70750).A+"",width:"572",height:"543"})}),"\n",(0,s.jsx)(n.h2,{id:"components-in-a-cluster",children:"Components in a cluster"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./components/openstack",children:"Infrastructure as a Service (IaaS) with OpenStack"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./components/ceph",children:"Software Defined Storage (SDS) with Ceph"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./components/ironic",children:"Bare Metal as a Service (BMaaS) with Ironic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./components/sonic",children:"Software Defined Networking (SDN) with SONiC & OVN"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./components/k3s",children:"Kubernetes (K8s) with K3S"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./components/gardener",children:"Kubernetes as a Service (KaaS) with Gardener"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./components/clusterapi",children:"Kubernetes as a Service (KaaS) with Cluster API"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./components/keycloak",children:"Identity & Access Management with Keycloak"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./components/teleport",children:"Privileged Access Management (PAM) to all infrastructure with Teleport"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./components/prometheus",children:"Logging, Monitoring & Telemetry with Prometheus & Grafana"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./components/netdata",children:"Realtime insights with Netdata"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,s.jsx)(n.h2,{id:"layers-in-a-cluster",children:"Layers in a cluster"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./layers#compute-plane",children:"Compute Plane"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./layers#control-plane",children:"Control Plane"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./layers#data-plane",children:"Data Plane"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./layers#management-plane",children:"Management Plane"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./layers#monitoring-plane",children:"Monitoring Plane"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./layers#network-plane",children:"Network Plane"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"cluster-design",children:"Cluster design"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./design#compute-architecture",children:"Compute architecture"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./design#storage-architecture",children:"Storage architecture"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./design#network-architecture",children:"Network architecture"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./design#identity-architecture",children:"Identity architecture"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./design#control-plane-architecture",children:"Control plane architecture"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./use-cases#hyper-converged-infrastructure-hci",children:"Hyper-converged infrastructure (HCI)"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"hardware-bill-of-materials",children:"Hardware Bill of Materials"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./hardware-bom#control-nodes",children:"Control nodes"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./hardware-bom#compute-nodes",children:"Compute nodes"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./hardware-bom#storage-nodes",children:"Storage nodes"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./hardware-bom#network-nodes",children:"Network nodes"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./hardware-bom#manager-nodes",children:"Manager nodes"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./hardware-bom#switches",children:"Switches"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./hardware-bom#network-interface-cards",children:"Network interface cards"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(o,{...e})}):o(e)}},70750:(e,n,r)=>{r.d(n,{A:()=>i});const i=r.p+"assets/images/overview.drawio-f6a92d48381c9de5fcbbd5205e022b0a.png"},28453:(e,n,r)=>{r.d(n,{R:()=>t,x:()=>l});var i=r(96540);const s={},a=i.createContext(s);function t(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cb18db4b.25b31e2e.js b/assets/js/cb18db4b.25b31e2e.js new file mode 100644 index 0000000000..8ad29a591e --- /dev/null +++ b/assets/js/cb18db4b.25b31e2e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[69859],{30359:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"operating-scs/components/automated-pentesting-iaas/tools","title":"Tools Description","description":"The following tools make up the automated pentesting pipeline.","source":"@site/docs/04-operating-scs/components/automated-pentesting-iaas/tools.md","sourceDirName":"04-operating-scs/components/automated-pentesting-iaas","slug":"/operating-scs/components/automated-pentesting-iaas/tools","permalink":"/docs/operating-scs/components/automated-pentesting-iaas/tools","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/automated-pentesting-iaas/tools.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Quickstart","permalink":"/docs/operating-scs/components/automated-pentesting-iaas/quickstart"},"next":{"title":"Using Automated Pentesting Reports for CSPs, Operators, and Users","permalink":"/docs/operating-scs/components/automated-pentesting-iaas/reports"}}');var t=i(74848),a=i(28453);const r={},o="Tools Description",l={},d=[{value:"Naabu",id:"naabu",level:2},{value:"HTTPx",id:"httpx",level:2},{value:"Nuclei",id:"nuclei",level:2},{value:"Greenbone Community Edition (OpenVAS)",id:"greenbone-community-edition-openvas",level:2},{value:"ZAP Proxy",id:"zap-proxy",level:2},{value:"Defect Dojo",id:"defect-dojo",level:2}];function c(e){const n={h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"tools-description",children:"Tools Description"})}),"\n",(0,t.jsx)(n.p,{children:"The following tools make up the automated pentesting pipeline."}),"\n",(0,t.jsx)(n.h2,{id:"naabu",children:"Naabu"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Functionality"}),": Naabu is a port scanning tool used for identifying open ports on a target host or IP range, crucial for initial reconnaissance in penetration testing."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Fast Scanning: Utilizes a high-speed, asynchronous approach for efficient port scanning."}),"\n",(0,t.jsx)(n.li,{children:"Multiple Output Formats: Supports text, JSON, and XML formats for integration with other tools."}),"\n",(0,t.jsx)(n.li,{children:"Flexible Target Specification: Capable of scanning individual hosts, IP ranges, or CIDR notations."}),"\n",(0,t.jsx)(n.li,{children:"Custom Port Ranges: Allows scanning specific port ranges or using standard lists of common ports."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Updates"}),": Regularly updated for performance improvements and new features."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"httpx",children:"HTTPx"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Functionality"}),": HTTPx is a powerful HTTP toolkit for web server fingerprinting, crucial for identifying web technologies and analyzing responses from web servers."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"High-Speed HTTP Detection: Efficient in analyzing HTTP servers and responses."}),"\n",(0,t.jsx)(n.li,{children:"Status Code Retrieval: Collects HTTP status codes to identify live hosts and valid endpoints."}),"\n",(0,t.jsx)(n.li,{children:"Custom Headers and Methods: Supports advanced HTTP requests for detailed analysis."}),"\n",(0,t.jsx)(n.li,{children:"Automation-Friendly: Easily integrates into automated workflows and pipelines."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Updates"}),": Continuously updated with enhancements for speed, accuracy, and additional features."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"nuclei",children:"Nuclei"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Functionality"}),": Nuclei is a template-based vulnerability scanner, essential for detecting known vulnerabilities using predefined and community-driven templates."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Extensive Template Library: Wide range of continuously updated templates for various vulnerabilities."}),"\n",(0,t.jsx)(n.li,{children:"Custom Template Creation: Allows creation of tailored templates for specific environment needs."}),"\n",(0,t.jsx)(n.li,{children:"Broad Vulnerability Coverage: Capable of scanning a variety of security weaknesses and exposures."}),"\n",(0,t.jsx)(n.li,{children:"Integration-Ready: Designed to fit seamlessly into CI/CD pipelines."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Updates"}),": Community and developers regularly update templates and tool features."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"greenbone-community-edition-openvas",children:"Greenbone Community Edition (OpenVAS)"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Functionality"}),": Greenbone CE, known as OpenVAS, is a full-featured vulnerability scanner for comprehensive assessments of networks, hosts, and applications."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Wide Range of Tests: Offers a broad spectrum of network and application vulnerability tests."}),"\n",(0,t.jsx)(n.li,{children:"Regular Feed Updates: The vulnerability feed is frequently updated for new threats."}),"\n",(0,t.jsx)(n.li,{children:"Scan Customization: Supports various scan configurations and scheduling."}),"\n",(0,t.jsx)(n.li,{children:"Detailed Reporting: Generates comprehensive reports for compliance and remediation planning."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Updates"}),": Maintained with regular updates to the vulnerability feed and software enhancements."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"zap-proxy",children:"ZAP Proxy"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Functionality"}),": ZAP Proxy is an intercepting proxy for dynamic application security testing (DAST), vital for identifying vulnerabilities in web applications."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Passive and Active Scanning: Provides both passive scanning (traffic analysis) and active scanning (direct testing)."}),"\n",(0,t.jsx)(n.li,{children:"Comprehensive Web App Mapping: Includes tools like Spider and AJAX Spider for thorough application mapping."}),"\n",(0,t.jsx)(n.li,{children:"Supports Various Authentication Types: Handles different web application authentication mechanisms."}),"\n",(0,t.jsx)(n.li,{children:"Extensibility: Offers a range of plugins and extensions for additional functionalities."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Updates"}),": Regularly updated with new features and security tests."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"defect-dojo",children:"Defect Dojo"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Functionality"}),": Defect Dojo is a security program and vulnerability management tool. It centralizes and streamlines the management of security programs, allowing for efficient tracking, measurement, and reporting of vulnerabilities."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Vulnerability Management: Enables tracking and management of vulnerabilities discovered across different tools and tests."}),"\n",(0,t.jsx)(n.li,{children:"Reporting and Metrics: Offers comprehensive reporting features for understanding security postures and metrics."}),"\n",(0,t.jsx)(n.li,{children:"Integration with CI/CD: Seamlessly integrates with CI/CD pipelines for automated importing of scan results."}),"\n",(0,t.jsx)(n.li,{children:"Customization and Flexibility: Allows customizations to fit various workflow requirements and integrates with other tools via APIs."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Updates"}),": Regularly updated with enhancements for functionality, usability, and security."]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>o});var s=i(96540);const t={},a=s.createContext(t);function r(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cbf20d25.f9a8d060.js b/assets/js/cbf20d25.f9a8d060.js new file mode 100644 index 0000000000..8314d9b281 --- /dev/null +++ b/assets/js/cbf20d25.f9a8d060.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[35575],{77123:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"development/tests/test-implementation-guide","title":"SCS Conformance Test Implementation Guide","description":"SovereignCloudStack (SCS) uses conformance tests to certify","source":"@site/contributor-docs/development/tests/test-implementation-guide.md","sourceDirName":"development/tests","slug":"/development/tests/test-implementation-guide","permalink":"/contributor-docs/development/tests/test-implementation-guide","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Conformance Test Implementation Guide","type":null,"status":"Draft","track":"Global"},"sidebar":"devDocs","previous":{"title":"SCS RFC2119 Keyword Test Guide","permalink":"/contributor-docs/development/tests/rfc2119-keyword-test-guide"},"next":{"title":"Documentation for SCS Contributors","permalink":"/contributor-docs/"}}');var i=n(74848),o=n(28453);const r={title:"SCS Conformance Test Implementation Guide",type:null,status:"Draft",track:"Global"},a=void 0,c={},l=[{value:"1. Mapping of RFC2119 Keywords",id:"1-mapping-of-rfc2119-keywords",level:2},{value:"2. Unit and Regression Tests",id:"2-unit-and-regression-tests",level:2},{value:"Naming Conventions",id:"naming-conventions",level:3},{value:"Write Testable Conformance Tests",id:"write-testable-conformance-tests",level:3},{value:"Pytest Test Example",id:"pytest-test-example",level:3},{value:"3. Conformance Tests Shouldn't Require Admin Privileges",id:"3-conformance-tests-shouldnt-require-admin-privileges",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.p,{children:["SovereignCloudStack (SCS) uses ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Tests",children:"conformance tests"})," to certify\ncompliance of a given cloud offering with respect to a given ",(0,i.jsx)(t.a,{href:"https://docs.scs.community/standards/certification/scopes-versions",children:"certificate\nscope"})," such as ",(0,i.jsx)(t.em,{children:"SCS Compatible IaaS v4"}),".\nOur aim is that these tests are reliable, consistent and comprehensible for\nthe users.\nThis document is a guideline for conformance test authors and summarizes the\ncurrent best practices to achieve this goal."]}),"\n",(0,i.jsx)(t.h2,{id:"1-mapping-of-rfc2119-keywords",children:"1. Mapping of RFC2119 Keywords"}),"\n",(0,i.jsxs)(t.p,{children:["Test authors working on new and existing conformance tests for an SCS standard\nmust implement the keywords such as MUST and SHOULD according to the ",(0,i.jsx)(t.a,{href:"https://docs.scs.community/contributor-docs/operations/tests/rfc2119-keyword-test-guide",children:"SCS\nRFC2119 Keyword Test Guide"}),"."]}),"\n",(0,i.jsx)(t.h2,{id:"2-unit-and-regression-tests",children:"2. Unit and Regression Tests"}),"\n",(0,i.jsxs)(t.p,{children:["Test authors are ",(0,i.jsx)(t.em,{children:"strongly"})," encouraged to include unit and regression tests for\nthe conformance test's logic.\nConformance tests will inevitably contain some non-trivial algorithms, be it for\nparsing flavor names or evaluating CVE vulnerability reports.\nTesting them automatically and regularly against valid and invalid inputs helps\ntest authors to find programming mistakes early on.\nAs a bonus, a well written unit test also makes it easier for reviewers to cross\ncheck a given pull request with new, enhanced or refactored conformance tests."]}),"\n",(0,i.jsxs)(t.p,{children:["In general, unit and regression tests for the conformance tests are located in\nthe same location as the conformance tests, that is, the ",(0,i.jsx)(t.code,{children:"Tests/"})," directory of\nthe ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/",children:"SCS standards repository"}),".\nSetup and development of the unit tests is described in the ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/README.md",children:"SCS conformance\ntests README"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"naming-conventions",children:"Naming Conventions"}),"\n",(0,i.jsxs)(t.p,{children:["Any module that ends in ",(0,i.jsx)(t.code,{children:"_test"})," will be picked up as a unit test module by\npytest in our CI pipeline (in other words, all files matched by the pattern\n",(0,i.jsx)(t.code,{children:"Tests/**/*_test.py"}),").\nPytest will execute any function prefixed with ",(0,i.jsx)(t.code,{children:"test_"})," as a test function, or,\nalternatively, tests based on the ",(0,i.jsx)(t.code,{children:"unittest"})," module from the Python standard\nlibrary."]}),"\n",(0,i.jsx)(t.p,{children:"Follow these naming rules:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The name of a unit test module is constructed from the module to be unit\ntested and the ",(0,i.jsx)(t.code,{children:"_test"})," suffix. For example, unit tests for ",(0,i.jsx)(t.code,{children:"flavor_names.py"}),"\nshould reside in ",(0,i.jsx)(t.code,{children:"flavor_names_test.py"}),"."]}),"\n",(0,i.jsxs)(t.li,{children:["The name of a Python module in general should be a valid ",(0,i.jsx)(t.a,{href:"https://docs.python.org/3/reference/lexical_analysis.html#identifiers",children:"Python\nidentifier"}),", to allow imports via the ",(0,i.jsx)(t.code,{children:"import"})," statement.\nFor example, use ",(0,i.jsx)(t.code,{children:"flavor_names.py"})," instead of ",(0,i.jsx)(t.code,{children:"flavor-names.py"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"write-testable-conformance-tests",children:"Write Testable Conformance Tests"}),"\n",(0,i.jsx)(t.p,{children:"Software design fills complete book shelves and this section can only cover some\nbasic best practices.\nAs a general rule of thumb, the earlier you begin writing unit tests, the better\n\u2013 it will force you to write modules that are easy to test."}),"\n",(0,i.jsxs)(t.p,{children:["Divide conformance tests scripts into smaller, loosely coupled units, i.e.,\nfunctions that serve one purpose each.\nUse the ",(0,i.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Dependency_injection",children:(0,i.jsx)(t.em,{children:"dependency injection"})})," technique, i.e., pass externally\nretrieved data as function arguments instead of hardcoding the calls to the\nretrieval functions inside a function.\nAvoid logging calls deep down in the call hierarchy and use explicit return\nvalues or raise exceptions, instead.\nHere is an abstract example of a conformance test which does exactly that:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-python",children:'# property_compliance.py\n\ndef retrieve(location):\n """Retrieve raw data via network."""\n ...\n\ndef parse(data):\n """Parse raw data and return a dict."""\n ...\n\ndef handle(...):\n """Evaluate parsed data."""\n ...\n\ndef main(args):\n ...\n data = retrieve(location)\n parsed = parse(data)\n result = handle(parsed)\n ...\n if result.some_prop != expected_value:\n logging.warn("some_prop is not as expected: %s (vs. %s)", result.some_prop, expected_value)\n ...\n return result.success\n\nif __name__ == "__main__":\n # using sys.exit(\u2026) only here makes it possible to unit test main(\u2026)\n sys.exit(main(sys.argv))\n'})}),"\n",(0,i.jsx)(t.p,{children:"Adhering to this style makes it easier to test an algorithm in isolation,\nwithout actually making a call to some external service."}),"\n",(0,i.jsx)(t.h3,{id:"pytest-test-example",children:"Pytest Test Example"}),"\n",(0,i.jsxs)(t.p,{children:["Assuming we want to unit test some members of the module ",(0,i.jsx)(t.code,{children:"property_compliance"}),"\nfrom the previous section, we would create a file ",(0,i.jsx)(t.code,{children:"property_compliance_test.py"}),"\nwith the following content as a starting point:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-python",children:'"""Unit tests for property_compliance.\n\n(c) Your Name <your.name@example.com>, 4/2024\nSPDX-License-Identifier: CC-BY-SA-4.0\n"""\n\nimport pytest\n\nfrom property_compliance import parse\n\n\ndef test_success():\n assert parse("some valid input") == "expected output"\n\n\ndef test_failure():\n with pytest.raises(ValueError):\n parse("invalid input")\n'})}),"\n",(0,i.jsx)(t.h2,{id:"3-conformance-tests-shouldnt-require-admin-privileges",children:"3. Conformance Tests Shouldn't Require Admin Privileges"}),"\n",(0,i.jsxs)(t.p,{children:["Conformance tests are expected to be executable without admin privileges (see \xa72 of\n",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0004-v1-achieving-certification.md",children:"Regulations for achieving SCS-compatible certification"}),").\nIn particular, this means:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The cloud credentials (e.g., kubeconfig and OpenStack ",(0,i.jsx)(t.code,{children:"clouds.yaml"}),") passed to\nthe scripts are non-admin credentials."]}),"\n",(0,i.jsx)(t.li,{children:"Conformance tests scripts should not require root privileges, except for the\ninstallation of operating system prerequisites (e.g., a Python interpreter)."}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var s=n(96540);const i={},o=s.createContext(i);function r(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ccc49370.7d02ad21.js b/assets/js/ccc49370.7d02ad21.js new file mode 100644 index 0000000000..c91a93c7fe --- /dev/null +++ b/assets/js/ccc49370.7d02ad21.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[83249],{82907:(e,t,n)=>{n.d(t,{A:()=>O});n(96540);var a=n(18215),s=n(44096),r=n(74848);function i(e){let{children:t,className:n}=e;return(0,r.jsx)("article",{className:n,children:t})}var l=n(28774);const o={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:n,isBlogPostPage:i}=(0,s.e7)(),{permalink:c,title:d}=n,m=i?"h1":"h2";return(0,r.jsx)(m,{className:(0,a.A)(o.title,t),children:i?d:(0,r.jsx)(l.A,{to:c,children:d})})}var d=n(21312),m=n(53465),u=n(36266);const h={container:"container_mt6G"};function g(e){let{readingTime:t}=e;const n=function(){const{selectMessage:e}=(0,m.W)();return t=>{const n=Math.ceil(t);return e(n,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:n}))}}();return(0,r.jsx)(r.Fragment,{children:n(t)})}function f(e){let{date:t,formattedDate:n}=e;return(0,r.jsx)("time",{dateTime:t,children:n})}function x(){return(0,r.jsx)(r.Fragment,{children:" \xb7 "})}function p(e){let{className:t}=e;const{metadata:n}=(0,s.e7)(),{date:i,readingTime:l}=n,o=(0,u.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,r.jsxs)("div",{className:(0,a.A)(h.container,"margin-vert--md",t),children:[(0,r.jsx)(f,{date:i,formattedDate:(c=i,o.format(new Date(c)))}),void 0!==l&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(x,{}),(0,r.jsx)(g,{readingTime:l})]})]});var c}var v=n(56913);const j={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function b(e){let{className:t}=e;const{metadata:{authors:n},assets:i}=(0,s.e7)();if(0===n.length)return null;const l=n.every((e=>{let{name:t}=e;return!t})),o=1===n.length;return(0,r.jsx)("div",{className:(0,a.A)("margin-top--md margin-bottom--sm",l?j.imageOnlyAuthorRow:"row",t),children:n.map(((e,t)=>(0,r.jsx)("div",{className:(0,a.A)(!l&&(o?"col col--12":"col col--6"),l?j.imageOnlyAuthorCol:j.authorCol),children:(0,r.jsx)(v.A,{author:{...e,imageURL:i.authorsImageUrls[t]??e.imageURL}})},t)))})}function A(){return(0,r.jsxs)("header",{children:[(0,r.jsx)(c,{}),(0,r.jsx)(p,{}),(0,r.jsx)(b,{})]})}var N=n(70440),L=n(11544);function y(e){let{children:t,className:n}=e;const{isBlogPostPage:i}=(0,s.e7)();return(0,r.jsx)("div",{id:i?N.LU:void 0,className:(0,a.A)("markdown",n),children:(0,r.jsx)(L.A,{children:t})})}var C=n(17559),T=n(4336),_=n(62053);function H(){return(0,r.jsx)("b",{children:(0,r.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function k(e){const{blogPostTitle:t,...n}=e;return(0,r.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...n,children:(0,r.jsx)(H,{})})}function w(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:n,title:i,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,m=!t&&o,u=n.length>0;if(!(u||m||l))return null;if(t){const e=!!(l||d||c);return(0,r.jsxs)("footer",{className:"docusaurus-mt-lg",children:[u&&(0,r.jsx)("div",{className:(0,a.A)("row","margin-top--sm",C.G.blog.blogFooterEditMetaRow),children:(0,r.jsx)("div",{className:"col",children:(0,r.jsx)(_.A,{tags:n})})}),e&&(0,r.jsx)(T.A,{className:(0,a.A)("margin-top--sm",C.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,r.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[u&&(0,r.jsx)("div",{className:(0,a.A)("col",{"col--9":m}),children:(0,r.jsx)(_.A,{tags:n})}),m&&(0,r.jsx)("div",{className:(0,a.A)("col text--right",{"col--3":u}),children:(0,r.jsx)(k,{blogPostTitle:i,to:e.permalink})})]})}function O(e){let{children:t,className:n}=e;const l=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,r.jsxs)(i,{className:(0,a.A)(l,n),children:[(0,r.jsx)(A,{}),(0,r.jsx)(y,{children:t}),(0,r.jsx)(w,{})]})}},73858:(e,t,n)=>{n.r(t),n.d(t,{default:()=>j});n(96540);var a=n(18215),s=n(61213),r=n(17559),i=n(44096),l=n(28027),o=n(82907),c=n(21312),d=n(39022),m=n(74848);function u(e){const{nextItem:t,prevItem:n}=e;return(0,m.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,c.T)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"}),children:[n&&(0,m.jsx)(d.A,{...n,subLabel:(0,m.jsx)(c.A,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post",children:"Newer post"})}),t&&(0,m.jsx)(d.A,{...t,subLabel:(0,m.jsx)(c.A,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post",children:"Older post"}),isNext:!0})]})}function h(){const{assets:e,metadata:t}=(0,i.e7)(),{title:n,description:a,date:r,tags:l,authors:o,frontMatter:c}=t,{keywords:d}=c,u=e.image??c.image;return(0,m.jsxs)(s.be,{title:c.title_meta??n,description:a,keywords:d,image:u,children:[(0,m.jsx)("meta",{property:"og:type",content:"article"}),(0,m.jsx)("meta",{property:"article:published_time",content:r}),o.some((e=>e.url))&&(0,m.jsx)("meta",{property:"article:author",content:o.map((e=>e.url)).filter(Boolean).join(",")}),l.length>0&&(0,m.jsx)("meta",{property:"article:tag",content:l.map((e=>e.label)).join(",")})]})}var g=n(5260);function f(){const e=(0,i.J_)();return(0,m.jsx)(g.A,{children:(0,m.jsx)("script",{type:"application/ld+json",children:JSON.stringify(e)})})}var x=n(67763),p=n(41689);function v(e){let{sidebar:t,children:n}=e;const{metadata:a,toc:s}=(0,i.e7)(),{nextItem:r,prevItem:c,frontMatter:d}=a,{hide_table_of_contents:h,toc_min_heading_level:g,toc_max_heading_level:f}=d;return(0,m.jsxs)(l.A,{sidebar:t,toc:!h&&s.length>0?(0,m.jsx)(x.A,{toc:s,minHeadingLevel:g,maxHeadingLevel:f}):void 0,children:[(0,m.jsx)(p.A,{metadata:a}),(0,m.jsx)(o.A,{children:n}),(r||c)&&(0,m.jsx)(u,{nextItem:r,prevItem:c})]})}function j(e){const t=e.content;return(0,m.jsx)(i.in,{content:e.content,isBlogPostPage:!0,children:(0,m.jsxs)(s.e3,{className:(0,a.A)(r.G.wrapper.blogPages,r.G.page.blogPostPage),children:[(0,m.jsx)(h,{}),(0,m.jsx)(f,{}),(0,m.jsx)(v,{sidebar:e.sidebar,children:(0,m.jsx)(t,{})})]})})}},32234:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var a=n(18215),s=n(44084),r=n(17559),i=n(27293),l=n(74848);function o(e){let{className:t}=e;return(0,l.jsx)(i.A,{type:"caution",title:(0,l.jsx)(s.Rc,{}),className:(0,a.A)(t,r.G.common.unlistedBanner),children:(0,l.jsx)(s.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.AE,{}),(0,l.jsx)(o,{...e})]})}},41689:(e,t,n)=>{n.d(t,{A:()=>d});n(96540);var a=n(18215),s=n(44084),r=n(17559),i=n(27293),l=n(74848);function o(e){let{className:t}=e;return(0,l.jsx)(i.A,{type:"caution",title:(0,l.jsx)(s.Yh,{}),className:(0,a.A)(t,r.G.common.draftBanner),children:(0,l.jsx)(s.TT,{})})}var c=n(32234);function d(e){let{metadata:t}=e;const{unlisted:n,frontMatter:a}=t;return(0,l.jsxs)(l.Fragment,{children:[(n||a.unlisted)&&(0,l.jsx)(c.A,{}),a.draft&&(0,l.jsx)(o,{})]})}},67763:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var a=n(18215),s=n(65195);const r={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var i=n(74848);const l="table-of-contents__link toc-highlight",o="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,i.jsx)("div",{className:(0,a.A)(r.tableOfContents,"thin-scrollbar",t),children:(0,i.jsx)(s.A,{...n,linkClassName:l,linkActiveClassName:o})})}},65195:(e,t,n)=>{n.d(t,{A:()=>f});var a=n(96540),s=n(6342);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...s}=e;n>=0?t[n].children.push(s):a.push(s)})),a}function i(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=i({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function l(e){const t=e.getBoundingClientRect();return t.top===t.bottom?l(e.parentNode):t}function o(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>l(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(l(a))?a:e[e.indexOf(a)-1]??null}return e[e.length-1]??null}function c(){const e=(0,a.useRef)(0),{navbar:{hideOnScroll:t}}=(0,s.p)();return(0,a.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,a.useRef)(void 0),n=c();(0,a.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:s,minHeadingLevel:r,maxHeadingLevel:i}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),l=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let s=t;s<=n;s+=1)a.push(`h${s}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:r,maxHeadingLevel:i}),c=o(l,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(s),e.classList.add(s),t.current=e):e.classList.remove(s)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}var m=n(28774),u=n(74848);function h(e){let{toc:t,className:n,linkClassName:a,isChild:s}=e;return t.length?(0,u.jsx)("ul",{className:s?void 0:n,children:t.map((e=>(0,u.jsxs)("li",{children:[(0,u.jsx)(m.A,{to:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,u.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:a})]},e.id)))}):null}const g=a.memo(h);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:l="table-of-contents__link",linkActiveClassName:o,minHeadingLevel:c,maxHeadingLevel:m,...h}=e;const f=(0,s.p)(),x=c??f.tableOfContents.minHeadingLevel,p=m??f.tableOfContents.maxHeadingLevel,v=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return(0,a.useMemo)((()=>i({toc:r(t),minHeadingLevel:n,maxHeadingLevel:s})),[t,n,s])}({toc:t,minHeadingLevel:x,maxHeadingLevel:p});return d((0,a.useMemo)((()=>{if(l&&o)return{linkClassName:l,linkActiveClassName:o,minHeadingLevel:x,maxHeadingLevel:p}}),[l,o,x,p])),(0,u.jsx)(g,{toc:v,className:n,linkClassName:l,...h})}},44084:(e,t,n)=>{n.d(t,{AE:()=>o,Rc:()=>i,TT:()=>d,Uh:()=>l,Yh:()=>c});n(96540);var a=n(21312),s=n(5260),r=n(74848);function i(){return(0,r.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,r.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function o(){return(0,r.jsx)(s.A,{children:(0,r.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,r.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,r.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}}}]); \ No newline at end of file diff --git a/assets/js/cd0ad4f0.89dc2191.js b/assets/js/cd0ad4f0.89dc2191.js new file mode 100644 index 0000000000..0c2186ec01 --- /dev/null +++ b/assets/js/cd0ad4f0.89dc2191.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[64625],{54287:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>a,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"getting-started/containerization","title":"Containerization","description":"TODO","source":"@site/docs/01-getting-started/containerization.md","sourceDirName":"01-getting-started","slug":"/getting-started/containerization","permalink":"/docs/getting-started/containerization","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/01-getting-started/containerization.md","tags":[],"version":"current","frontMatter":{"sidebar":3}}');var i=n(74848),r=n(28453);const a={sidebar:3},s="Containerization",c={},d=[];function u(t){const e={h1:"h1",header:"header",p:"p",...(0,r.R)(),...t.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.header,{children:(0,i.jsx)(e.h1,{id:"containerization",children:"Containerization"})}),"\n",(0,i.jsx)(e.p,{children:"TODO"})]})}function l(t={}){const{wrapper:e}={...(0,r.R)(),...t.components};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(u,{...t})}):u(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>a,x:()=>s});var o=n(96540);const i={},r=o.createContext(i);function a(t){const e=o.useContext(r);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:a(t.components),o.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/cd4fb20e.47779d1c.js b/assets/js/cd4fb20e.47779d1c.js new file mode 100644 index 0000000000..787ec3eb62 --- /dev/null +++ b/assets/js/cd4fb20e.47779d1c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[96165],{48115:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>d,metadata:()=>i,toc:()=>a});const i=JSON.parse('{"id":"scs-0100-v2-flavor-naming","title":"SCS Flavor Naming Standard","description":"Introduction","source":"@site/standards/scs-0100-v2-flavor-naming.md","sourceDirName":".","slug":"/scs-0100-v2-flavor-naming","permalink":"/standards/scs-0100-v2-flavor-naming","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Flavor Naming Standard","type":"Standard","status":"Deprecated","track":"IaaS","replaces":"scs-0100-v1-flavor-naming.md","stabilized_at":"2023-02-21T00:00:00.000Z","deprecated_at":"2023-11-30T00:00:00.000Z"},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0100-v1-flavor-naming"},"next":{"title":"V3","permalink":"/standards/scs-0100-v3-flavor-naming"}}');var t=s(74848),r=s(28453);const d={title:"SCS Flavor Naming Standard",type:"Standard",status:"Deprecated",track:"IaaS",replaces:"scs-0100-v1-flavor-naming.md",stabilized_at:new Date("2023-02-21T00:00:00.000Z"),deprecated_at:new Date("2023-11-30T00:00:00.000Z")},l=void 0,o={},a=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Type of information included",id:"type-of-information-included",level:3},{value:"Complete Proposal for systematic flavor naming",id:"complete-proposal-for-systematic-flavor-naming",level:2},{value:"Proposal Details",id:"proposal-details",level:2},{value:"[REQUIRED] CPU Suffixes",id:"required-cpu-suffixes",level:3},{value:"Baseline",id:"baseline",level:4},{value:"Higher oversubscription",id:"higher-oversubscription",level:4},{value:"Insufficient microcode",id:"insufficient-microcode",level:4},{value:"Examples",id:"examples",level:4},{value:"[REQUIRED] Memory",id:"required-memory",level:3},{value:"Baseline",id:"baseline-1",level:4},{value:"No ECC",id:"no-ecc",level:4},{value:"Enabled Oversubscription",id:"enabled-oversubscription",level:4},{value:"Examples",id:"examples-1",level:4},{value:"[OPTIONAL] Disk sizes and types",id:"optional-disk-sizes-and-types",level:3},{value:"Baseline",id:"baseline-2",level:4},{value:"Multi-provisioned Disk",id:"multi-provisioned-disk",level:4},{value:"Examples",id:"examples-2",level:4},{value:"Standard SCS flavors",id:"standard-scs-flavors",level:2},{value:"Naming policy compliance",id:"naming-policy-compliance",level:2},{value:"Validation",id:"validation",level:2},{value:"Operational tooling",id:"operational-tooling",level:2},{value:"Extensions",id:"extensions",level:2},{value:"[OPTIONAL] Hypervisor",id:"optional-hypervisor",level:3},{value:"Examples",id:"examples-3",level:4},{value:"[OPTIONAL] Hardware virtualization / Nested virtualization",id:"optional-hardware-virtualization--nested-virtualization",level:3},{value:"Examples",id:"examples-4",level:4},{value:"[OPTIONAL] CPU Architecture Details",id:"optional-cpu-architecture-details",level:3},{value:"Generation and Vendor",id:"generation-and-vendor",level:4},{value:"Frequency Suffixes",id:"frequency-suffixes",level:4},{value:"Examples",id:"examples-5",level:4},{value:"[OPTIONAL] GPU support",id:"optional-gpu-support",level:3},{value:"[OPTIONAL] Infiniband",id:"optional-infiniband",level:3},{value:"Naming options advice",id:"naming-options-advice",level:3},{value:"Proposal Examples",id:"proposal-examples",level:2},{value:"Previous standard versions",id:"previous-standard-versions",level:2},{value:"Beyond SCS",id:"beyond-scs",level:2}];function c(e){const n={a:"a",code:"code",del:"del",div:"div",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsx)(n.p,{children:"This is the standard v2.1 for SCS Release 4.\nNote that we intend to only extend it (so it's always backwards compatible),\nbut try to avoid changing in incompatible ways.\n(See at the end for the v1 to v2 transition where we have not met that\ngoal, but at least managed to have a 1:1 relationship between v1 and v2 names.)"}),"\n",(0,t.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,t.jsx)(n.p,{children:"In OpenStack environments there is a need to define different flavors for instances.\nThe flavors are pre-defined by the operator, the customer can not change these.\nOpenStack providers thus typically offer a large selection of flavors."}),"\n",(0,t.jsxs)(n.p,{children:["While flavors can be discovered (",(0,t.jsx)(n.code,{children:"openstack flavor list"}),"), it is helpful for users (DevOps teams),\nto have"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere."}),"\n",(0,t.jsx)(n.li,{children:"Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"While not all details will be encoded in the name, the key features should be obvious:\nNumber of vCPUs, RAM, Root Disk.\nExtra features are important as well: There will be flavors with GPU support, fast disks for databases,\nmemory-heavy applications, and other useful aspects of an instance."}),"\n",(0,t.jsx)(n.p,{children:"It may also be important to make the CPU generation clearly recognizable, as this is always a topic in\ndiscussions with customers."}),"\n",(0,t.jsx)(n.p,{children:"Note that not all relevant properties of flavors can be discovered; creating a specification\nto address this is a separate but related effort to the name standardization.\nCommonly used infrastructure-as-code tools do not provide a way to use discoverability\nfeatures to express something like \"I want a flavor with 2 vCPUs, 8GiB of RAM, a local\n20GB SSD disk and Infiniband support, but I don't care whether it's AMD or intel\" in a\nreasonable manner. Using flavor names to express this will thus continue to be useful,\nand we don't expect the need for standardization of flavor names to go away until\nthe commonly used IaC tools work on a higher abstraction layer than they currently do."}),"\n",(0,t.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,t.jsx)(n.h3,{id:"type-of-information-included",children:"Type of information included"}),"\n",(0,t.jsx)(n.p,{children:"From discussions of our operators with their customers we learned that\nthe following characteristics are important in a flavor description:"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{style:{textAlign:"left"},children:"Type"}),(0,t.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"Generation"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"CPU Generation"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"Number of CPU"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"Number of vCPUs - suffixed by L,V,T,C (see below)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"Amount of RAM"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"Amount of memory available for the VM"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"Performance Class"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"Ability to label high-performance CPUs, disks, network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"CPU Type"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"X86-intel, X86-amd, ARM, RISC-V, Generic"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:'"bms"'}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"Bare Metal System (no virtualization/hypervisor)"})]})]})]}),"\n",(0,t.jsx)(n.p,{children:"This list is likely not comprehensive and will grow over time."}),"\n",(0,t.jsxs)(n.p,{children:["Rather than using random names ",(0,t.jsx)(n.code,{children:"s5a.medium"})," and assigning a discrete set of properties\nto them, we wanted to come up with a scheme that allows to systematically derive\nnames from properties and vice versa. The scheme allows for short names (by not\nencoding all details) as well as very detailed longer names."]}),"\n",(0,t.jsx)(n.h2,{id:"complete-proposal-for-systematic-flavor-naming",children:"Complete Proposal for systematic flavor naming"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Prefix"}),(0,t.jsx)(n.th,{children:"CPUs & Suffix"}),(0,t.jsx)(n.th,{children:"RAM[GiB]"}),(0,t.jsx)(n.th,{children:"optional: Disk[GB]&type"}),(0,t.jsx)(n.th,{children:"opt: extensions"})]})}),(0,t.jsx)(n.tbody,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"SCS-"})}),(0,t.jsxs)(n.td,{children:["N",(0,t.jsx)(n.code,{children:"L/V/T/C"}),"[",(0,t.jsx)(n.code,{children:"i"}),"]"]}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"-"}),"N[",(0,t.jsx)(n.code,{children:"u"}),"][",(0,t.jsx)(n.code,{children:"o"}),"]"]}),(0,t.jsxs)(n.td,{children:["[",(0,t.jsx)(n.code,{children:"-"}),"[M",(0,t.jsx)(n.code,{children:"x"}),"]N[",(0,t.jsx)(n.code,{children:"n/s/l/p"}),"]]"]}),(0,t.jsxs)(n.td,{children:["[",(0,t.jsx)(n.code,{children:"_"}),"EXT]"]})]})})]}),"\n",(0,t.jsxs)(n.p,{children:["Note that ",(0,t.jsx)(n.code,{children:"N"})," and ",(0,t.jsx)(n.code,{children:"M"})," are placeholders for numbers here.\nThe optional fields are denoted in brackets (and have ",(0,t.jsx)(n.code,{children:"opt:"})," in the header).\nSee below for extensions."]}),"\n",(0,t.jsx)(n.p,{children:"Note that all letters are case-sensitive."}),"\n",(0,t.jsxs)(n.p,{children:["Typical flavor names look like ",(0,t.jsx)(n.code,{children:"SCS-4V-16-50"})," for a flavor with 4vCPUs (with limited\noversubscription), 16GiB RAM and a 50GB disk (of unspecified type)."]}),"\n",(0,t.jsx)(n.h2,{id:"proposal-details",children:"Proposal Details"}),"\n",(0,t.jsx)(n.h3,{id:"required-cpu-suffixes",children:"[REQUIRED] CPU Suffixes"}),"\n",(0,t.jsx)(n.p,{children:"Next to the number of vCPUs, these vCPUs need to be characterized ti describe their nature."}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Suffix"}),(0,t.jsx)(n.th,{children:"Meaning"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"C"}),(0,t.jsx)(n.td,{children:"dedicated Core"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"T"}),(0,t.jsx)(n.td,{children:"dedicated Thread (SMT)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"V"}),(0,t.jsx)(n.td,{children:"vCPU (oversubscribed)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"L"}),(0,t.jsx)(n.td,{children:"vCPU (heavily oversubscribed)"})]})]})]}),"\n",(0,t.jsx)(n.h4,{id:"baseline",children:"Baseline"}),"\n",(0,t.jsxs)(n.p,{children:["Note that vCPU oversubscription for a ",(0,t.jsx)(n.code,{children:"V"})," vCPU should be implemented such, that we\ncan guarantee ",(0,t.jsx)(n.em,{children:"at least 20% of a core in >99% of the time"}),"; this can be achieved by\nlimiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled)\nor by more advanced workload management logic. Otherwise ",(0,t.jsx)(n.code,{children:"L"})," (low performance) instead\nof ",(0,t.jsx)(n.code,{children:"V"})," must be used. The >99% is measured over a month (1% is 7.2h/month)."]}),"\n",(0,t.jsx)(n.p,{children:"Note that CPUs should use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.).\nMicrocode must be updated within less than a month of a new release; for CVSS scores above 8,\nproviders should do it in less than a week.\nThe provider should enable at least all mitigations that are enabled by default in the Linux kernel and the\nKVM hypervisor. CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) should switch off hyperthreading\nOR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team."}),"\n",(0,t.jsxs)(n.p,{children:["If microcode updates needed for mitigation are lacking for longer than a month, default kernel/hypervisor\nmitigations are disabled or hyperthreading is enabled despite the CPU being susceptible to L1TF, the\nflavors must declare themselves insecure with the ",(0,t.jsx)(n.code,{children:"i"})," suffix (see below)."]}),"\n",(0,t.jsx)(n.h4,{id:"higher-oversubscription",children:"Higher oversubscription"}),"\n",(0,t.jsxs)(n.p,{children:["Must be indicated with a ",(0,t.jsx)(n.code,{children:"L"})," vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and\nthe lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month)."]}),"\n",(0,t.jsx)(n.h4,{id:"insufficient-microcode",children:"Insufficient microcode"}),"\n",(0,t.jsxs)(n.p,{children:["Not using these mitigations must be indicated by an additional ",(0,t.jsx)(n.code,{children:"i"})," suffix for insecure\n(weak protection against CPU vulnerabilities through insufficient microcode, lack of disabled hyperthreading\non L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor)."]}),"\n",(0,t.jsx)(n.h4,{id:"examples",children:"Examples"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["SCS-",(0,t.jsx)(n.strong,{children:"2C"}),"-4-10n"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-",(0,t.jsx)(n.strong,{children:"2T"}),"-4-10n"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-",(0,t.jsx)(n.strong,{children:"2V"}),"-4-10n"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-",(0,t.jsx)(n.strong,{children:"2L"}),"-4-10n"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-",(0,t.jsx)(n.strong,{children:"2Li"}),"-4-10n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsxs)(n.del,{children:["SCS-",(0,t.jsx)(n.strong,{children:"2"}),"-**4-10n"]})," - CPU suffix missing"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsxs)(n.del,{children:["SCS-",(0,t.jsx)(n.strong,{children:"2iT"}),"-4-10n"]})," - This order is forbidden"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"required-memory",children:"[REQUIRED] Memory"}),"\n",(0,t.jsx)(n.h4,{id:"baseline-1",children:"Baseline"}),"\n",(0,t.jsx)(n.p,{children:"Cloud providers should use ECC memory.\nMemory oversubscription should not be used.\nIt is allowed to specify half GiBs (e.g. 3.5), though this should not be done for larger memory sizes (>= 10GiB)."}),"\n",(0,t.jsx)(n.h4,{id:"no-ecc",children:"No ECC"}),"\n",(0,t.jsxs)(n.p,{children:["If no ECC is used, the ",(0,t.jsx)(n.code,{children:"u"})," suffix must indicate this."]}),"\n",(0,t.jsx)(n.h4,{id:"enabled-oversubscription",children:"Enabled Oversubscription"}),"\n",(0,t.jsxs)(n.p,{children:["If memory is oversubscribed, you must expose this with the ",(0,t.jsx)(n.code,{children:"o"})," suffix."]}),"\n",(0,t.jsx)(n.h4,{id:"examples-1",children:"Examples"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["SCS-2C-",(0,t.jsx)(n.strong,{children:"4"}),"-10n"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-",(0,t.jsx)(n.strong,{children:"3.5"}),"-10n"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-",(0,t.jsx)(n.strong,{children:"4u"}),"-10n"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-",(0,t.jsx)(n.strong,{children:"4o"}),"-10n"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-",(0,t.jsx)(n.strong,{children:"4uo"}),"-10n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsxs)(n.del,{children:["SCS-2C-",(0,t.jsx)(n.strong,{children:"4ou"}),"-10n"]})," - This order is forbidden"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"optional-disk-sizes-and-types",children:"[OPTIONAL] Disk sizes and types"}),"\n",(0,t.jsx)(n.p,{children:"Disk sizes (in GB) should use sizes 5, 10, 20, 50, 100, 200, 500, 1000."}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Disk type"}),(0,t.jsx)(n.th,{children:"Meaning"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"n"}),(0,t.jsx)(n.td,{children:"Network shared storage (ceph/cinder)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"h"}),(0,t.jsx)(n.td,{children:"Local disk (HDD: SATA/SAS class)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"s"}),(0,t.jsx)(n.td,{children:"Local SSD disk"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"p"}),(0,t.jsx)(n.td,{children:"Local high-perf NVMe"})]})]})]}),"\n",(0,t.jsx)(n.h4,{id:"baseline-2",children:"Baseline"}),"\n",(0,t.jsx)(n.p,{children:"Note that disk type might be omitted \u2014 the user then can not take any assumptions\non what storage is provided for the root disk (that the image gets provisioned to)."}),"\n",(0,t.jsxs)(n.p,{children:["It does make sense for ",(0,t.jsx)(n.code,{children:"n"})," to be requested explicitly to allow for smooth live migration.\n",(0,t.jsx)(n.code,{children:"h"})," typically provides latency advantages vs ",(0,t.jsx)(n.code,{children:"n"})," (but not necessarily bandwidth and\nalso is more likely to fail), ",(0,t.jsx)(n.code,{children:"s"})," and ",(0,t.jsx)(n.code,{children:"p"})," are for applications that need low\nlatency (high IOPS) and bandwidth disk I/O. ",(0,t.jsx)(n.code,{children:"n"})," storage is expected to survive\nsingle-disk and single-node failure."]}),"\n",(0,t.jsxs)(n.p,{children:["If the disk size is left out, the cloud is expected to allocate a disk (network or local)\nthat is large enough to fit the root file system (",(0,t.jsx)(n.code,{children:"min_disk"})," in image). This automatic\nallocation is indicated with ",(0,t.jsx)(n.code,{children:"-"})," without a disk size.\nIf the ",(0,t.jsx)(n.code,{children:"-"})," is left out completely, the user must create a boot volume manually and\ntell the instance to boot from it or use the\n",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/api-ref/compute/?expanded=create-server-detail#create-server",children:(0,t.jsx)(n.code,{children:"block_device_mapping_v2"})}),"\nmechanism explicitly to create the boot volume from an image."]}),"\n",(0,t.jsx)(n.h4,{id:"multi-provisioned-disk",children:"Multi-provisioned Disk"}),"\n",(0,t.jsxs)(n.p,{children:["The disk size can be prefixed with ",(0,t.jsx)(n.code,{children:"Mx prefix"}),", where M is an integer specifying that the disk\nis provisioned M times. Multiple disks provided this way should be independent storage media,\nso users can expect some level of parallelism and independence."]}),"\n",(0,t.jsx)(n.h4,{id:"examples-2",children:"Examples"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-",(0,t.jsx)(n.strong,{children:"10n"})]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-",(0,t.jsx)(n.strong,{children:"10s"})]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-",(0,t.jsx)(n.strong,{children:"10s"}),"_bms_z3"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-",(0,t.jsx)(n.strong,{children:"3x10s"})," - Cloud creates three 10GB SSDs"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-",(0,t.jsx)(n.strong,{children:"3x10s"}),"_bms_z3"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-",(0,t.jsx)(n.strong,{children:"10"})," - Cloud decides disk type"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-",(0,t.jsx)(n.strong,{children:"10"}),"_bms_z3"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-",(0,t.jsx)(n.strong,{children:"n"})," - Cloud decides disk size (min_disk from image or larger)"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-",(0,t.jsx)(n.strong,{children:"n"}),"_bms_3"]}),"\n",(0,t.jsx)(n.li,{children:"SCS-2C-4- - Cloud decides disk type and size"}),"\n",(0,t.jsx)(n.li,{children:"SCS-2C-4-_bms_z3"}),"\n",(0,t.jsx)(n.li,{children:"SCS-2C-4-_bms_z3h_GNa-64_ib"}),"\n",(0,t.jsx)(n.li,{children:"SCS-2C-4-_ib"}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4 - You need to specify a boot volume yourself (boot from volume, or use ",(0,t.jsx)(n.code,{children:"block_device_mapping_v2"}),")"]}),"\n",(0,t.jsx)(n.li,{children:"SCS-2C-4_bms_z3"}),"\n",(0,t.jsx)(n.li,{children:"SCS-2C-4-3x- - Cloud decides disk type and size and creates three of them (FIXME: Is this useful?)"}),"\n",(0,t.jsx)(n.li,{children:"SCS-2C-4-3xs - Cloud decides size and creates three local SSD volumes (FIXME: useful?)"}),"\n",(0,t.jsx)(n.li,{children:"SCS-2C-4-3x10 - Cloud decides type and creates three 10GB volumes"}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsxs)(n.del,{children:["SCS-2C-4-",(0,t.jsx)(n.strong,{children:"1.5n"})]})," - You must not specify disk sizes which are not in full GiBs"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"standard-scs-flavors",children:"Standard SCS flavors"}),"\n",(0,t.jsx)(n.p,{children:"These are flavors that must exist on standard SCS clouds (x86-64)."}),"\n",(0,t.jsxs)(n.p,{children:["We expect disk sizes to be 5, 10, 20, 50, 100, 200, 500, 1000GB, 2000GB.\nWe expect a typical CPU",(0,t.jsx)(n.div,{children:"GiB"})," ratio of 1:4."]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.th,{children:["vCPU",":RAM"," ratio"]}),(0,t.jsx)(n.th,{children:"Mandatory Flavors"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"1:4"}),(0,t.jsx)(n.td,{children:"SCS-1V-4, SCS-1V-4-10"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"2:8"}),(0,t.jsx)(n.td,{children:"SCS-2V-8, SCS-2V-8-20"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"4:16"}),(0,t.jsx)(n.td,{children:"SCS-4V-16, SCS-4V-16-50"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"8:32"}),(0,t.jsx)(n.td,{children:"SCS-8V-32, SCS-8V-32-100"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"1:2"}),(0,t.jsx)(n.td,{children:"SCS-1V-2, SCS-1V-2-5"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"2:4"}),(0,t.jsx)(n.td,{children:"SCS-2V-4, SCS-2V-4-10"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"4:8"}),(0,t.jsx)(n.td,{children:"SCS-4V-8, SCS-4V-8-20"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"8:16"}),(0,t.jsx)(n.td,{children:"SCS-8V-16, SCS-8V-16-50"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"16:32"}),(0,t.jsx)(n.td,{children:"SCS-16V-32, SCS-16V-32-100"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"1:8"}),(0,t.jsx)(n.td,{children:"SCS-1V-8, SCS-1V-8-20"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"2:16"}),(0,t.jsx)(n.td,{children:"SCS-2V-16, SCS-2V-16-50"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"4:32"}),(0,t.jsx)(n.td,{children:"SCS-4V-32, SCS-4V-32-100"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"1:1"}),(0,t.jsx)(n.td,{children:"SCS-1L-1, SCS-1L-1-5"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Note that all vCPUs of SCS standard flavors are oversubscribed \u2014 the smallest ",(0,t.jsx)(n.code,{children:"1L-1"}),"\nflavor allows for heavy oversubscription (note the ",(0,t.jsx)(n.code,{children:"L"}),"), and thus can be offered very\ncheaply \u2014 imagine jump hosts ...\nDisks types are not specified (and expected to be n or h typically)."]}),"\n",(0,t.jsx)(n.p,{children:"The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM\ncompute hosts) to offer all flavors."}),"\n",(0,t.jsxs)(n.p,{children:["Note: Compared to previous drafts, we have heavily reduced the variations\non disk sizes \u2014 this reflects that for the standard networked cinder\ndisks, you can pass ",(0,t.jsx)(n.code,{children:"block_device_mapping_v2"})," on server (VM) creation to\nallocate a boot disk of any size you desire. We have scaled the few\nmandatory disk sizes with the amount of RAM. For each flavor there is\nalso one ",(0,t.jsx)(n.em,{children:"without"})," a pre-attached disk \u2014 these are meant to be used\nto boot from a volume (either created beforehand or allocated on-the-fly\nwith ",(0,t.jsx)(n.code,{children:"block_device_mapping_v2"}),", e.g.\n",(0,t.jsx)(n.code,{children:"openstack server create --flavor SCS-1V:2 --block-device-mapping sda=IMGUUID:image:12:true"}),"\nto create a bootable 12G cinder volume from image ",(0,t.jsx)(n.code,{children:"IMGUUID"})," that gets tied to the VM\ninstance life cycle.)"]}),"\n",(0,t.jsx)(n.h2,{id:"naming-policy-compliance",children:"Naming policy compliance"}),"\n",(0,t.jsx)(n.p,{children:"To be certified as an SCS compliant x86-64 IaaS platform, you must offer all standard SCS flavors\naccording to the previous section. (We may define a mechanism that allows exceptions to be\ngranted in a way that makes this very transparent and visible to clients.)"}),"\n",(0,t.jsx)(n.p,{children:"You are allowed to understate your performance; you may implement a SCS-1V-1-5 flavor with\na flavor that actually implements SCS-1T-1-5n (i.e. you dedicate a dedicated hyperthread instead\nof higher oversubscription) or even SCS-1D-1.5-8s (1 dedicated core, 50% more RAM and a 8GiB SSD)."}),"\n",(0,t.jsxs)(n.p,{children:["Flavor names indicating certain capabilities must ",(0,t.jsx)(n.em,{children:"at least"})," provide these, otherwise they\nare in violation of the SCS specification and prevent SCS compliance."]}),"\n",(0,t.jsx)(n.p,{children:"We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V-32-100).\nLarger providers that offer more details (using the extension below) are expected to still also\noffer the short variants for usability and easier portability, even beyond the mandated flavors."}),"\n",(0,t.jsxs)(n.p,{children:["You must be very careful to expose low vCPU guarantees (",(0,t.jsx)(n.code,{children:"L"})," instead of ",(0,t.jsx)(n.code,{children:"V"}),"), insecure\nhyperthreading/microcode ",(0,t.jsx)(n.code,{children:"i"}),", non-ECC-RAM ",(0,t.jsx)(n.code,{children:"u"}),", memory oversubscription ",(0,t.jsx)(n.code,{children:"o"}),". Note that omitting these qualifiers is\noverstating your security, reliability or performance properties and may be reason for\nclients to feel betrayed or claim damages. This would prevent SCS compliance and certification;\nin extreme cases, the SCS project might be forced to work with public statements."]}),"\n",(0,t.jsxs)(n.p,{children:["You may offer additional ",(0,t.jsx)(n.code,{children:"SCS-"})," flavors, following the naming scheme and rules outlined here."]}),"\n",(0,t.jsxs)(n.p,{children:["You may offer additional flavors, not following above scheme and not starting with ",(0,t.jsx)(n.code,{children:"SCS-"})]}),"\n",(0,t.jsxs)(n.p,{children:["You must not offer flavors with the ",(0,t.jsx)(n.code,{children:"SCS-"})," prefix which do not follow this naming scheme.\nYou must not extend the SCS naming scheme with your own suffices; you are encouraged however\nto suggest extensions that we can discuss and add to the official scheme."]}),"\n",(0,t.jsx)(n.h2,{id:"validation",children:"Validation"}),"\n",(0,t.jsxs)(n.p,{children:["There is a script in ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/flavor-naming/flavor-name-check.py",children:(0,t.jsx)(n.code,{children:"flavor_name_check.py"})}),"\nwhich can be used to decode, validate and construct flavor names.\nThis script must stay in sync with the specification text."]}),"\n",(0,t.jsxs)(n.p,{children:["Ensure you have your OpenStack tooling (",(0,t.jsx)(n.code,{children:"python3-openstackclient"}),", ",(0,t.jsx)(n.code,{children:"OS_CLOUD"}),") setup and call\n",(0,t.jsx)(n.code,{children:"tools/flavor-name-check.py -c $(openstack flavor list -f value -c Name)"})," to get a report\non the flavor list compliance of the cloud environment."]}),"\n",(0,t.jsxs)(n.p,{children:["The script ",(0,t.jsx)(n.code,{children:"flavor-names-openstack.py"})," talks to the OpenStack API of the\ncloud specified by the ",(0,t.jsx)(n.code,{children:"OS_CLOUD"})," environment and queries properties and checks\nthe names for standards compliance and completeness w.r.t. the mandatory\nflavor list. It goes beyond the above example in checking that the discoverable\nfeatures of flavors (vCPUs, RAM, Disk) match what the flavor names claim."]}),"\n",(0,t.jsx)(n.h2,{id:"operational-tooling",children:"Operational tooling"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/osism/openstack-flavor-manager",children:"openstack-flavor-manager"})," is able to\ncreate all standard, mandatory SCS flavors for you."]}),"\n",(0,t.jsx)(n.h2,{id:"extensions",children:"Extensions"}),"\n",(0,t.jsx)(n.p,{children:"Extensions provide a possibility for providers that offer a very differentiated set\nof flavors to indicate hypervisors, support for hardware/nested virtualization,\nCPU types and generations, high-frequency models, GPU support and GPU types as\nwell as Infiniband support. (More extensions may be appended in the future.)"}),"\n",(0,t.jsx)(n.p,{children:"Using the systematic naming approach ensures that two providers that offer flavors\nwith the same specific features will use the same name for them, thus simplifying\nlife for their customers when consuming these flavors."}),"\n",(0,t.jsxs)(n.p,{children:["Note that there is no need to indicate all details and extra features this way.\nFlavors may always perform better or have more features than indicated in a name.\nUnderperformance (CPU suffices ",(0,t.jsx)(n.code,{children:"L"})," or ",(0,t.jsx)(n.code,{children:"i"})," or memory suffices ",(0,t.jsx)(n.code,{children:"o"})," and ",(0,t.jsx)(n.code,{children:"u"}),") on the other\nhand MUST be indicated in the name; this happens rarely in practice."]}),"\n",(0,t.jsx)(n.p,{children:"For smaller providers, the ability to e.g. differentiate between an AMD Milan and an intel\nIceLake and exposed the slightly different feature set to customers and have slightly\ndifferent price points is often not worth the extra effort. This is because having\nthis extra differentiation causes fragmentation of the machines (host aggregates)\nthat can offer these flavors, thus resulting in a lower utilization (as the capacity\nmanagement will need to have a certain amount of headroom per machine pool to avoid\nrunning out of capacity)."}),"\n",(0,t.jsx)(n.p,{children:"Note that it possible for providers to register both the generic short names and the\nlonger, more detailed names and allow them to use the same set of machines (host aggregates).\nNote that machines (hypervisors) can be part of more than one host aggregate."}),"\n",(0,t.jsx)(n.p,{children:"The extensions have the format:"}),"\n",(0,t.jsxs)(n.p,{children:["[",(0,t.jsx)(n.code,{children:"_"}),"hyp][",(0,t.jsx)(n.code,{children:"_hwv"}),"][",(0,t.jsx)(n.code,{children:"_"}),"[arch[N][",(0,t.jsx)(n.code,{children:"h"}),"][",(0,t.jsx)(n.code,{children:"_"}),"[",(0,t.jsx)(n.code,{children:"G/g"}),"]X[N][",(0,t.jsx)(n.code,{children:"-"}),"M[",(0,t.jsx)(n.code,{children:"h"}),"]]][",(0,t.jsx)(n.code,{children:"_ib"}),"]"]}),"\n",(0,t.jsx)(n.p,{children:"Remember that letters are case-sensitive.\nIn case you wonder: Feature indicators are capitalized, modifiers are lower case.\n(An exception is the uppercase -G for a pass-through GPU vs. lowercase -g for vGPU.)"}),"\n",(0,t.jsx)(n.h3,{id:"optional-hypervisor",children:"[OPTIONAL] Hypervisor"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.em,{children:"default Hypervisor"})," is assumed to be ",(0,t.jsx)(n.code,{children:"KVM"}),". Clouds, that offer different hypervisors\nor Bare Metal Systems should indicate the Hypervisor according to the following table:"]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"hyp"}),(0,t.jsx)(n.th,{children:"Meaning"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"kvm"}),(0,t.jsx)(n.td,{children:"KVM"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"xen"}),(0,t.jsx)(n.td,{children:"Xen"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"vmw"}),(0,t.jsx)(n.td,{children:"VMware"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"hyv"}),(0,t.jsx)(n.td,{children:"Hyper-V"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"bms"}),(0,t.jsx)(n.td,{children:"Bare Metal System"})]})]})]}),"\n",(0,t.jsx)(n.h4,{id:"examples-3",children:"Examples"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"SCS-2C-4-10n"}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,t.jsx)(n.strong,{children:"bms"})]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,t.jsx)(n.strong,{children:"bms"}),"_z3h"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"optional-hardware-virtualization--nested-virtualization",children:"[OPTIONAL] Hardware virtualization / Nested virtualization"}),"\n",(0,t.jsxs)(n.p,{children:["If the instances that are created with this flavor support hardware-accelerated\nvirtualization, this can be reflected with the ",(0,t.jsx)(n.code,{children:"_hwv"})," flag (after the optional\nHypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel)\nor svm (AMD) is available. This will be the case on Bare Metal flavors on almost\nall non-ancient x86 CPUs or if your virtualization hypervisor is configured to\nsupport nested virtualization.\nFlavors without the ",(0,t.jsx)(n.code,{children:"_hwv"})," flag may or may not support hardware virtualization (as we\nrecommend enabling nesting, but don't require flavor names to reflect all\ncapabilities. Flavors may over-deliver ...)"]}),"\n",(0,t.jsx)(n.h4,{id:"examples-4",children:"Examples"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"SCS-2C-4-10 - may or may not support HW virtualization in VMs"}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10_kvm_",(0,t.jsx)(n.strong,{children:"hwv"})," - kvm with enabled nested virtualization"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10_",(0,t.jsx)(n.strong,{children:"hwv"})," - not recommended, but allowed"]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10_bms_",(0,t.jsx)(n.strong,{children:"hwv"})," - better: bare metal with HW virt support (VMX on intel, SVM on AMD, ...)"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsxs)(n.del,{children:["SCS-2C-4-10_",(0,t.jsx)(n.strong,{children:"hwv"}),"_xen"]})," - illegal, wrong ordering"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"optional-cpu-architecture-details",children:"[OPTIONAL] CPU Architecture Details"}),"\n",(0,t.jsx)(n.p,{children:"Arch details provide more details on the specific CPU:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Vendor"}),"\n",(0,t.jsx)(n.li,{children:"Generation"}),"\n",(0,t.jsx)(n.li,{children:"Frequency"}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"generation-and-vendor",children:"Generation and Vendor"}),"\n",(0,t.jsxs)(n.p,{children:["The generations are vendor specific and can be left out.\nNot specifying arch means that we have a generic CPU (",(0,t.jsx)(n.strong,{children:"x86-64"}),").\nThe letters ",(0,t.jsx)(n.code,{children:"i"}),", ",(0,t.jsx)(n.code,{children:"z"}),", ",(0,t.jsx)(n.code,{children:"a"})," and ",(0,t.jsx)(n.code,{children:"r"})," specify the vendors Intel,\nAMD (",(0,t.jsx)(n.code,{children:"z"})," like in Zen), ARM v8+, RISC-V."]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Generation"}),(0,t.jsx)(n.th,{children:"i (Intel x86-64)"}),(0,t.jsx)(n.th,{children:"z (AMD x86-64)"}),(0,t.jsx)(n.th,{children:"\xa0a (AArch64)"}),(0,t.jsx)(n.th,{children:"r (RISC-V)"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"0"}),(0,t.jsx)(n.td,{children:"pre Skylake"}),(0,t.jsx)(n.td,{children:"pre Zen"}),(0,t.jsx)(n.td,{children:"pre Cortex A76"}),(0,t.jsx)(n.td,{children:"TBD"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"Skylake"}),(0,t.jsx)(n.td,{children:"Zen-1 (Naples)"}),(0,t.jsx)(n.td,{children:"A76/NeoN1 class"}),(0,t.jsx)(n.td,{children:"TBD"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"2"}),(0,t.jsx)(n.td,{children:"Cascade Lake"}),(0,t.jsx)(n.td,{children:"Zen-2 (Rome)"}),(0,t.jsx)(n.td,{children:"A78/x1/NeoV1 class"}),(0,t.jsx)(n.td,{children:"TBD"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"3"}),(0,t.jsx)(n.td,{children:"Ice Lake"}),(0,t.jsx)(n.td,{children:"Zen-3 (Milan)"}),(0,t.jsx)(n.td,{children:"A71x/NeoN2 (ARMv9)"}),(0,t.jsx)(n.td,{children:"TBD"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"4"}),(0,t.jsx)(n.td,{children:"Sapphire Rapids"}),(0,t.jsx)(n.td,{children:"Zen-4 (Genoa)"}),(0,t.jsx)(n.td,{}),(0,t.jsx)(n.td,{children:"TBD"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["It is recommended to leave out the ",(0,t.jsx)(n.code,{children:"0"}),' when specifying the old generation; this will\nhelp the parser tool, which assumes 0 for an unspecified value and does leave it\nout when generating the name for comparison. In other words: 0 has a meaning of\n"rather old or unspecified".']}),"\n",(0,t.jsx)(n.h4,{id:"frequency-suffixes",children:"Frequency Suffixes"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Suffix"}),(0,t.jsx)(n.th,{children:"Meaning"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"h"}),(0,t.jsx)(n.td,{children:">2.75GHz all-core"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"hh"}),(0,t.jsx)(n.td,{children:">3.25GHz all-core"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"hhh"}),(0,t.jsx)(n.td,{children:">3.75GHz all-core"})]})]})]}),"\n",(0,t.jsx)(n.h4,{id:"examples-5",children:"Examples"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"SCS-2C-4-10n"}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,t.jsx)(n.strong,{children:"z"})]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,t.jsx)(n.strong,{children:"z3"})]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,t.jsx)(n.strong,{children:"z3h"})]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,t.jsx)(n.strong,{children:"z3hh"})]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,t.jsx)(n.strong,{children:"z"})]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,t.jsx)(n.strong,{children:"z3"})]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,t.jsx)(n.strong,{children:"z3"})]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,t.jsx)(n.strong,{children:"z3h"})]}),"\n",(0,t.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,t.jsx)(n.strong,{children:"z3hh"})," - Bare Metal, Intel Ice Lake with > 3.25GHz all core freq"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"optional-gpu-support",children:"[OPTIONAL] GPU support"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"_G"}),"X[N][",(0,t.jsx)(n.code,{children:"-"}),"M[",(0,t.jsx)(n.code,{children:"h"}),"]] indicates a Pass-Through GPU from vendor X of gen N with M compute units / SMs / EUs exposed.\n",(0,t.jsx)(n.code,{children:"_g"}),"X[N][",(0,t.jsx)(n.code,{children:"-"}),"M[",(0,t.jsx)(n.code,{children:"h"}),"]] indicates a vGPU from vendor X of gen N with M compute units / SMs / EUs assigned."]}),"\n",(0,t.jsx)(n.p,{children:"Note that the vendor letter X is mandatory, generation and compute units are optional."}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"GPU"}),(0,t.jsx)(n.th,{children:"Vendor"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"N"}),(0,t.jsx)(n.td,{children:"nVidia"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"A"}),(0,t.jsx)(n.td,{children:"AMD"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"I"}),(0,t.jsx)(n.td,{children:"Intel"})]})]})]}),"\n",(0,t.jsx)(n.p,{children:"For nVidia, the generation N can be f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, l=Ada Lovelace, ...,\nfor AMD GCN-x=0.x, RDNA1=1, RDNA2=2, RDNA3=3, for intel Gen9=0.9, Xe(12.1)=1, ...\n(Note: This may need further work to properly reflect what's out there.)"}),"\n",(0,t.jsxs)(n.p,{children:["The optional ",(0,t.jsx)(n.code,{children:"h"})," suffix to the compute unit count indicates high-performance (e.g. high freq or special\nhigh bandwidth gfx memory such as HBM);\n",(0,t.jsx)(n.code,{children:"h"})," can be duplicated for even higher performance."]}),"\n",(0,t.jsx)(n.h3,{id:"optional-infiniband",children:"[OPTIONAL] Infiniband"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"_ib"})," indicates Infiniband networking."]}),"\n",(0,t.jsx)(n.p,{children:"More extensions may be forthcoming and appended in a later revision of this spec."}),"\n",(0,t.jsx)(n.p,{children:"Extensions need to be specified in the above-mentioned order."}),"\n",(0,t.jsx)(n.h3,{id:"naming-options-advice",children:"Naming options advice"}),"\n",(0,t.jsx)(n.p,{children:"Note that we expect most clouds to prefer short flavor names,\nnot indicating CPU details or hypervisor types. See above list\nof standard flavors to get a feeling."}),"\n",(0,t.jsxs)(n.p,{children:["However, more successful providers will often need to differentiate their\nofferings in response to customer demand and allow customers to request\nflavors with specific detailed properties. The goal of this proposal is to avoid\nproviders to invent their own names and then refer customers to (currently\nincompletely standardized) ",(0,t.jsx)(n.code,{children:"extra_specs"}),"\nor worse a non-machine-readable service descriptions to find out the details."]}),"\n",(0,t.jsxs)(n.p,{children:["So a cloud provider might well evolve from offering ",(0,t.jsx)(n.code,{children:"SCS-8T-16-50"})," to offering\n",(0,t.jsx)(n.code,{children:"SCS-8T-16-50n"}),", ",(0,t.jsx)(n.code,{children:"SCS-8T-16-50n_i2"})," and ",(0,t.jsx)(n.code,{children:"SCS-8T-16-50n_a2"})," to specify that he\nis using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome.\nWe would expect the cloud provider to still offer the generic flavor\n",(0,t.jsx)(n.code,{children:"SCS-8T-16-50"})," and allow the scheduler (placement service) to pick both more\nspecific types (or just one if e.g. capacity management considerations suggest\nso). Providers should in such cases make sure that the price does not depend\non scheduler decisions."]}),"\n",(0,t.jsxs)(n.p,{children:["We are looking into the ",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/image-guide/introduction.html#metadata-definition-metadefs-service",children:"metadefs"}),"\nmechanism and ",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/api-guide/compute/extra_specs_and_properties.html",children:"extra_specs"}),"\nto allow customers to ask for specific flavor properties without the need to\nencode all these flavor details into the flavor name, so the optional pieces\nmay not be needed much. However, there must be a way to request flavor\nproperties without encoding the need into an image \u2014 the indirection via\nan image is considered broken by the SCS team."]}),"\n",(0,t.jsx)(n.h2,{id:"proposal-examples",children:"Proposal Examples"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Example"}),(0,t.jsx)(n.th,{children:"Decoding"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SCS-2C-4-10n"}),(0,t.jsx)(n.td,{children:"2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SCS-8Ti-32-50p_i1"}),(0,t.jsx)(n.td,{children:"8 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SCS-1L-1u-5"}),(0,t.jsx)(n.td,{children:"1 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SCS-16T-64-200s_GNa-64_ib"}),(0,t.jsx)(n.td,{children:"16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 64 Passthrough nVidia Ampere SMs"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SCS-4C-16-2x200p_a1"}),(0,t.jsx)(n.td,{children:"4 dedicated Arm64 cores (A76 class), 16GiB RAM, 2x200GB local NVMe drives"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SCS-1V-0.5"}),(0,t.jsx)(n.td,{children:"1 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"previous-standard-versions",children:"Previous standard versions"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/standards/scs-0100-v1-flavor-naming",children:"Version 1 of the standard"}),"\nused a slightly different naming syntax while the logic was exactly the same.\nWhat is a ",(0,t.jsx)(n.code,{children:"-"})," in v2 used to be a ",(0,t.jsx)(n.code,{children:":"}),"; ",(0,t.jsx)(n.code,{children:"_"})," used to be ",(0,t.jsx)(n.code,{children:"-"}),". The reason for\nthe change was certain Kubernetes tools using the flavor names as labels.\nLabels however are subject to stricter naming rules and in particular don't\nallow for a ",(0,t.jsx)(n.code,{children:":"}),". See ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/issues/190",children:"PR #190"}),"\nfor a discussion."]}),"\n",(0,t.jsx)(n.p,{children:"Version 1 flavor names can be translated to v2 using the following transformation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"NAMEV2=$(echo \"$NAMEV1\" | sed -e 's/\\-/_/g' -e 's/:/-/g' -e 's/^SCS_/SCS-/')\n"})}),"\n",(0,t.jsx)(n.p,{children:"and the way back can be done with"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"NAMEV1=$(echo \"$NAMEV2\" | sed -e 's/\\-/:/g' -e 's/_/-/g' -e 's/^SCS:/SCS-/')\n"})}),"\n",(0,t.jsx)(n.p,{children:"Considerations for how providers can ensure a smooth transition for their customers\nfrom v1 to v2 are written in a separate document."}),"\n",(0,t.jsxs)(n.p,{children:["For the time being, the validation tools still accept the old names with a warning\n(despite the unchanged ",(0,t.jsx)(n.code,{children:"SCS-"})," prefix) unless you pass option ",(0,t.jsx)(n.code,{children:"-2"})," to them. They will\nhowever not count v1 flavors towards fulfilling the needs against the corresponding\nv2 mandatory flavor list unless you pass the option ",(0,t.jsx)(n.code,{children:"-1"}),".\nIn other words: An IaaS infrastructure with the 26\nv1 mandatory flavors will produce 26 warnings (for using old flavors) and 26\nerrors (for missing the 26 mandatory v2 flavors) unless you pass ",(0,t.jsx)(n.code,{children:"-1"})," in which\ncase no errors and no warnings will be produced. Registering the 26 mandatory\nv2 flavor names in addition will result in passing the test with only 26\nwarnings \u2014 unless you specify ",(0,t.jsx)(n.code,{children:"-2"}),". If you do and want to pass you'll need\nto remove the old v1 names or rename them to no longer start with ",(0,t.jsx)(n.code,{children:"SCS-"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"beyond-scs",children:"Beyond SCS"}),"\n",(0,t.jsx)(n.p,{children:"The Gaia-X provider working group which could have created a superseding standard\ndoes no longer exist."}),"\n",(0,t.jsx)(n.p,{children:"However, we have been reaching out to the OpenStack Public Cloud SIG and the ALASCA\nmembers to seek further alignment."}),"\n",(0,t.jsx)(n.p,{children:"Getting upstream OpenStack support for flavor aliases would provide more flexibility\nand ease migrations between providers, also providers that don't offer the SCS-\nflavors."}),"\n",(0,t.jsxs)(n.p,{children:["We also would like to see upstream ",(0,t.jsx)(n.code,{children:"extra_specs"})," standardizing the discoverability of some\nproperties exposed via the SCS names and work on IaC tooling (terraform ...)\nto make use of these when selecting a flavor."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>l});var i=s(96540);const t={},r=i.createContext(t);function d(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cd87bcd5.3055b308.js b/assets/js/cd87bcd5.3055b308.js new file mode 100644 index 0000000000..1b6007dfd2 --- /dev/null +++ b/assets/js/cd87bcd5.3055b308.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[95113],{43063:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"operating-scs/components/status-page-api/docs/quickstart","title":"Quickstart","description":"See requirements","source":"@site/docs/04-operating-scs/components/status-page-api/docs/quickstart.md","sourceDirName":"04-operating-scs/components/status-page-api/docs","slug":"/operating-scs/components/status-page-api/docs/quickstart","permalink":"/docs/operating-scs/components/status-page-api/docs/quickstart","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-api/docs/quickstart.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Requirements","permalink":"/docs/operating-scs/components/status-page-api/docs/requirements"},"next":{"title":"Configuration","permalink":"/docs/operating-scs/components/status-page-api/docs/configuration"}}');var a=t(74848),r=t(28453);const o={},c="Quickstart",i={},d=[{value:"Run as container",id:"run-as-container",level:2},{value:"Compile and run the binary",id:"compile-and-run-the-binary",level:2},{value:"Running tests",id:"running-tests",level:2}];function p(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(s.header,{children:(0,a.jsx)(s.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,a.jsxs)(s.p,{children:["See ",(0,a.jsx)(s.a,{href:"/docs/operating-scs/components/status-page-api/docs/requirements",children:"requirements"})]}),"\n",(0,a.jsx)(s.h2,{id:"run-as-container",children:"Run as container"}),"\n",(0,a.jsx)(s.p,{children:"The quickest way to start working with the API server, is to run the container directly."}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{className:"language-bash",children:'docker run --rm --network host -e STATUS_PAGE_DATABASE_CONNECTION_STRING="host=localhost user=postgres dbname=postgres port=5432 password=debug sslmode=disable" -e STATUS_PAGE_VERBOSE=3 registry.scs.community/status-page/status-page-api:latest\n'})}),"\n",(0,a.jsx)(s.h2,{id:"compile-and-run-the-binary",children:"Compile and run the binary"}),"\n",(0,a.jsx)(s.p,{children:"Compiling the binary and running it is equally easy."}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{className:"language-bash",children:'go build -o /bin/status-page-api cmd/status-page-api/main.go\n\nSTATUS_PAGE_DATABASE_CONNECTION_STRING="host=localhost user=postgres dbname=postgres port=5432 password=debug sslmode=disable" STATUS_PAGE_VERBOSE=3 ./bin/status-page-api\n'})}),"\n",(0,a.jsx)(s.h2,{id:"running-tests",children:"Running tests"}),"\n",(0,a.jsxs)(s.p,{children:["The status page API server tests it's API handler and database code with a plethora of tests. These tests can be run with ",(0,a.jsx)(s.code,{children:"go"}),"."]}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{className:"language-bash",children:"go test ./...\n"})}),"\n",(0,a.jsx)(s.p,{children:"Furthermore test can be run to create a coverage profile."}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{className:"language-bash",children:"go test -coverprofile coverage.out ./...\n"})}),"\n",(0,a.jsx)(s.p,{children:"This cover profile can be used to analyze code coverage"}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{className:"language-bash",children:"# per function coverage\ngo tool cover -func coverage.out\n# HTML representation of tested code\ngo tool cover -html coverage.out\n"})})]})}function u(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,a.jsx)(s,{...e,children:(0,a.jsx)(p,{...e})}):p(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>o,x:()=>c});var n=t(96540);const a={},r=n.createContext(a);function o(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cda5fe29.29570c45.js b/assets/js/cda5fe29.29570c45.js new file mode 100644 index 0000000000..261546b79e --- /dev/null +++ b/assets/js/cda5fe29.29570c45.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[62840],{7706:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>d,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"iaas/guides/deploy-guide/services/kubernetes","title":"Kubernetes","description":"As of OSISM 7, it is possible to create a Kubernetes cluster on all nodes.","source":"@site/docs/02-iaas/guides/deploy-guide/services/kubernetes.md","sourceDirName":"02-iaas/guides/deploy-guide/services","slug":"/iaas/guides/deploy-guide/services/kubernetes","permalink":"/docs/iaas/guides/deploy-guide/services/kubernetes","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/kubernetes.md","tags":[],"version":"current","sidebarPosition":12,"frontMatter":{"sidebar_label":"Kubernetes","sidebar_position":12},"sidebar":"docs","previous":{"title":"Infrastructure","permalink":"/docs/iaas/guides/deploy-guide/services/infrastructure"},"next":{"title":"Network","permalink":"/docs/iaas/guides/deploy-guide/services/network"}}');var t=n(74848),r=n(28453);const o={sidebar_label:"Kubernetes",sidebar_position:12},d="Kubernetes",l={},c=[{value:"Cluster API",id:"cluster-api",level:2}];function a(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"kubernetes",children:"Kubernetes"})}),"\n",(0,t.jsx)(s.admonition,{type:"info",children:(0,t.jsx)(s.p,{children:"As of OSISM 7, it is possible to create a Kubernetes cluster on all nodes.\nAt the moment, this is still optional. In the future, it will be necessary\nto deploy this Kubernetes cluster."})}),"\n",(0,t.jsxs)(s.ol,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["Deploy the ",(0,t.jsx)(s.a,{href:"https://k3s.io",children:"K3s"})," cluster."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"osism apply kubernetes\n"})}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["Deploy the ",(0,t.jsx)(s.a,{href:"https://github.com/kubernetes/dashboard",children:"Kubernetes dashboard"}),":"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"osism apply kubernetes-dashboard\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"cluster-api",children:"Cluster API"}),"\n",(0,t.jsxs)(s.ol,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["Deploy the ",(0,t.jsx)(s.a,{href:"https://cluster-api.sigs.k8s.io",children:"Cluster API"})," management cluster on the K3s cluster:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"osism apply clusterapi\n"})}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["Add the ",(0,t.jsx)(s.code,{children:"kubeconfig"})," file to the configuration repository (required later by OpenStack\nMagnum Service):"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"osism apply copy-kubeconfig\n"})}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>d});var i=n(96540);const t={},r=i.createContext(t);function o(e){const s=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cdb233b1.e9079335.js b/assets/js/cdb233b1.e9079335.js new file mode 100644 index 0000000000..bfd2c210cb --- /dev/null +++ b/assets/js/cdb233b1.e9079335.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[71755],{77296:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Application Examples","slug":"/category/application-examples","permalink":"/user-docs/category/application-examples","sidebar":"userDocs","navigation":{"previous":{"title":"Introduction","permalink":"/user-docs/"},"next":{"title":"OpenDesk on SCS","permalink":"/user-docs/category/opendesk-on-scs"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/cdce7391.0c8f9884.js b/assets/js/cdce7391.0c8f9884.js new file mode 100644 index 0000000000..28e8e809b4 --- /dev/null +++ b/assets/js/cdce7391.0c8f9884.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[45350],{73488:e=>{e.exports=JSON.parse('{"version":{"pluginId":"user-docs","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"userDocs":[{"type":"link","label":"Introduction","href":"/user-docs/","docId":"index","unlisted":false},{"type":"category","label":"Application Examples","items":[{"type":"category","label":"OpenDesk on SCS","items":[{"type":"link","label":"Overview","href":"/user-docs/application-examples/opendesk-on-scs/overview","docId":"application-examples/opendesk-on-scs/overview","unlisted":false},{"type":"link","label":"Quickstart","href":"/user-docs/application-examples/opendesk-on-scs/quickstart","docId":"application-examples/opendesk-on-scs/quickstart","unlisted":false},{"type":"link","label":"Requirements","href":"/user-docs/application-examples/opendesk-on-scs/requirements","docId":"application-examples/opendesk-on-scs/requirements","unlisted":false},{"type":"link","label":"Getting started: Deployment from a local machine","href":"/user-docs/application-examples/opendesk-on-scs/getting_started","docId":"application-examples/opendesk-on-scs/getting_started","unlisted":false},{"type":"link","label":"Configuration","href":"/user-docs/application-examples/opendesk-on-scs/configuration","docId":"application-examples/opendesk-on-scs/configuration","unlisted":false},{"type":"link","label":"User import","href":"/user-docs/application-examples/opendesk-on-scs/user-import","docId":"application-examples/opendesk-on-scs/user-import","unlisted":false},{"type":"link","label":"Contribute","href":"/user-docs/application-examples/opendesk-on-scs/contribute","docId":"application-examples/opendesk-on-scs/contribute","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/user-docs/category/opendesk-on-scs"}],"collapsed":true,"collapsible":true,"href":"/user-docs/category/application-examples"}]},"docs":{"application-examples/opendesk-on-scs/configuration":{"id":"application-examples/opendesk-on-scs/configuration","title":"Configuration","description":"openDesk has many configuration options. You can view them and their default values in your copy of openDesk:","sidebar":"userDocs"},"application-examples/opendesk-on-scs/contribute":{"id":"application-examples/opendesk-on-scs/contribute","title":"Contribute","description":"Contributions to this documentation are welcome and can be submitted to this repository.","sidebar":"userDocs"},"application-examples/opendesk-on-scs/getting_started":{"id":"application-examples/opendesk-on-scs/getting_started","title":"Getting started: Deployment from a local machine","description":"Please note the general Getting Started documentation by openDesk.","sidebar":"userDocs"},"application-examples/opendesk-on-scs/overview":{"id":"application-examples/opendesk-on-scs/overview","title":"Overview","description":"This guide takes you through the steps to deploy openDesk on a Sovereign Cloud Stack Kubernetes cluster.","sidebar":"userDocs"},"application-examples/opendesk-on-scs/quickstart":{"id":"application-examples/opendesk-on-scs/quickstart","title":"Quickstart","description":"To get started quickly, you can use the wrapper script that does parts of the work described in Getting started. Please see that page for details nevertheless. # noqa: [relative-link-path]","sidebar":"userDocs"},"application-examples/opendesk-on-scs/requirements":{"id":"application-examples/opendesk-on-scs/requirements","title":"Requirements","description":"You can find the general requirements in the openDesk documentation. Please study them before beginning. This howto only touches on requirements concerning the rollout on an SCS cluster.","sidebar":"userDocs"},"application-examples/opendesk-on-scs/user-import":{"id":"application-examples/opendesk-on-scs/user-import","title":"User import","description":"Once you have a complete deployment, you can add additional accounts via the administration interface.","sidebar":"userDocs"},"index":{"id":"index","title":"Introduction","description":"Welcome to the User Documentation of the Sovereign Cloud Stack (SCS)","sidebar":"userDocs"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/ce756c16.f16871e2.js b/assets/js/ce756c16.f16871e2.js new file mode 100644 index 0000000000..0d1e0963a8 --- /dev/null +++ b/assets/js/ce756c16.f16871e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[19807],{24268:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"license-considerations","title":"License considerations for SCS","description":"As Sovereign Cloud Stack (SCS), our mission is to provide Operators","source":"@site/community/license-considerations.md","sourceDirName":".","slug":"/license-considerations","permalink":"/community/license-considerations","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Mission Statement","permalink":"/community/mission-statement"},"next":{"title":"Collaboration","permalink":"/community/collaboration/"}}');var s=t(74848),o=t(28453);const r={},a="License considerations for SCS",c={},l=[{value:"Reciprocity",id:"reciprocity",level:2},{value:"Controversy",id:"controversy",level:2},{value:"Affero",id:"affero",level:2},{value:"Derived works and Strong vs. Weak Copyleft",id:"derived-works-and-strong-vs-weak-copyleft",level:2},{value:"Patents",id:"patents",level:2},{value:"Copyright Assignments and Contributor License Agreements",id:"copyright-assignments-and-contributor-license-agreements",level:2},{value:"License in = License out",id:"license-in--license-out",level:2},{value:"Further reading",id:"further-reading",level:2}];function h(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"license-considerations-for-scs",children:"License considerations for SCS"})}),"\n",(0,s.jsxs)(n.p,{children:["As Sovereign Cloud Stack (",(0,s.jsx)(n.a,{href:"https://scs.community/",children:"SCS"}),"), our mission is to provide Operators\n(be it Cloud Service Providers or just internal IT departments) with a well working software\nstack, that avoids exposing them to legal risks or additional restrictions that limits the\nusefulness. Free software licenses have this intention but differ in how they achieve it and in\nwhat kind of protections they provide. In the first approximation, all ",(0,s.jsx)(n.a,{href:"https://opensource.org/licenses",children:"OSI"}),"-approved\nopen source licenses can be considered as valid options. As a matter of fact,\nwe do consider projects under such licenses as valid modules for SCS \u2014 where we\nuse such projects and adjust or extend them, we would provide our contributions\nunder the license terms of the respective project, so we can achieve our goal to feed back code\nupstream to the respective project, contribute to it and avoid fragmentation."]}),"\n",(0,s.jsx)(n.p,{children:"Where we do create independent code, we do have additional preferences, though."}),"\n",(0,s.jsxs)(n.p,{children:["For our own code, we do prefer the ",(0,s.jsx)(n.a,{href:"https://www.gnu.org/licenses/agpl-3.0.html",children:"Affero General Public License version 3"}),"\n(AGPLv3) as license. Likewise, for documentation, we prefer ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/CC-BY-SA",children:"CC-BY-SA"}),".\nWhere we create standard libraries to interface with our software, we would\nconsider the ",(0,s.jsx)(n.a,{href:"https://www.gnu.de/documents/lgpl-3.0.en.html",children:"LGPLv3"})," for these,\nas we don't want interaction with our platform to be seen as requiring licensing\ncode."]}),"\n",(0,s.jsx)(n.h2,{id:"reciprocity",children:"Reciprocity"}),"\n",(0,s.jsxs)(n.p,{children:["The GPL family of licenses are reciprocal licenses \u2014 sometimes called ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Copyleft",children:"copyleft"}),"\nlicenses \u2014 the recipient of the licensed code can make all sorts of modifications,\nbut if she uses the code to release software (GPL) or provide a networked service\n(AGPL) to others, then she must grant the same rights to the recipients \u2014 this\nincludes making the modifications available under the same terms as the received software.\nMicrosoft has infamously ",(0,s.jsx)(n.a,{href:"https://web.archive.org/web/20010615205548/http://suntimes.com/output/tech/cst-fin-micro01.html",children:"attacked"}),'\ncopyleft licenses (and specifically the GPL) as cancerous "viral" license.']}),"\n",(0,s.jsx)(n.p,{children:"Reciprocity has many advantages:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Code that has been created as free software will stay free. While GPL code can be\ncombined in a larger software collection with proprietary software, the code itself\nincluding its enhancements etc. (technically: all derived works, see below) will\nremain free."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:['The obligation to make the changes available avoids fragmentation. As changed and\n"improved" versions need to be made available, it is much easier to review and feed\nthose changes back and create a unified upstream codebase that reflects the needs of\nthe complete user base by including the needed changes. This was observed and\n',(0,s.jsx)(n.a,{href:"https://lwn.net/Articles/660428/",children:"reported"})," by Martin Fink (HP's former CTO)."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The hugely successful ",(0,s.jsx)(n.a,{href:"https://kernel.org/",children:"Linux kernel"})," project uses the GNU GPL;\nmany of the more traditional key projects in the open source world use copyleft licenses such as\nthe AGPL, GNU GPL, GNU LGPL, MPL or the ",(0,s.jsx)(n.a,{href:"https://opensource.org/licenses/OSL-3.0",children:"OSL"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"controversy",children:"Controversy"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Not fulfilling the license terms of a software license typically leads to the ability for the\nlicense owner to revoke the license \u2014 as it is relatively easy to not fulfill all obligations\nof the GPL out of sheer negligence, the revocation without prior warning seems\ndisproportionate \u2014 this is sometimes called the GPL death penalty. The open source community\nthough has a strong interest in bringing every licensee into compliance by giving violators a\nfair chance to correct their behavior. SCS explicitly supports the ",(0,s.jsx)(n.a,{href:"https://gplcc.github.io/gplcc/",children:"GPL Cooperation Commitment"}),"\nand the respective ",(0,s.jsx)(n.a,{href:"https://www.kernel.org/doc/html/v4.15/process/kernel-enforcement-statement.html",children:"document"}),"\nfrom the Linux kernel developers and pledges to give violators a warning and a chance to correct action\nby allowing for a cure period. This is a bit of a legacy issue \u2014 it is relevant to (L)GPLv2\ncode only \u2014 v3 of L/A/GPL does already contain language that has cure provisions, so it's\nclear by the licensing terms."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Many companies seem to be worried that they will inadvertently violate the GPL by negligence.\nAnd it is true that a company needs a tighter control of the usage of inbound source code\nwhich comes with a reciprocal license than the permissive BSD 3-clause or Apache Software (v2)\nlicenses. This advantage however quickly turns into a disadvantage as soon as the company does\nsignificant outbound open source contributions under a permissive license \u2014 they rarely want\nto give their competitors an opportunity to consume their contributions and then add\nproprietary changes to gain an advantage. In general, companies are well advised to have a\ndetailed understanding of all code that is being used and contributed and their respective\nlicense terms \u2014 for proprietary and open source code and for reciprocal and for permissive\nlicenses. Some companies have successfully installed license review boards or\n",(0,s.jsx)(n.a,{href:"https://www.linuxfoundation.org/resources/open-source-guides/using-open-source-code/",children:"open source review boards"}),"\nto create oversight, recommendations and policies to ease the governance."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Despite this, many of the recent open source projects, especially in the cloud world\nhave adopted permissive licenses, such as X11, BSD 3-clause, MIT and especially the popular\n",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Apache_License",children:"Apache software license"})," (ASL2), as it\nappears to allow for faster adoption by companies that may not have mature open source\npolicies in place or that simply have overly careful lawyers which may be influenced\nby the scare tactics some bad companies have built on top of copyleft licenses."]}),"\n",(0,s.jsx)(n.h2,{id:"affero",children:"Affero"}),"\n",(0,s.jsxs)(n.p,{children:["The reciprocity of the GNU GPL does not apply on the ",(0,s.jsx)(n.em,{children:"creation"})," of a derived work. A company\ncan consume GPL'ed code and change it to their own liking without ever making any the\nchanges available if only used in-house. The terms however do apply as soon as the derived\nwork is ",(0,s.jsx)(n.em,{children:"released"}),", i.e. the software is passed on to a third party."]}),"\n",(0,s.jsxs)(n.p,{children:["In modern times, software is often used to provide a ",(0,s.jsx)(n.em,{children:"networked service"})," (think SaaS) to third\nparties. Unlike the standard GPL, the Affero GPL (AGPL) does consider the act of making it\navailable in such a way as similar to releasing the software and does require that applied\nchanges to the software are being made available in this case."]}),"\n",(0,s.jsx)(n.p,{children:"The AGPL thus closes a shortcoming in the traditional non-Affero GPL for a world that\nincreasingly moves towards networked services."}),"\n",(0,s.jsxs)(n.p,{children:["The very successful ",(0,s.jsx)(n.a,{href:"https://nextcloud.com/",children:"Nextcloud"})," project uses the AGPLv3."]}),"\n",(0,s.jsx)(n.h2,{id:"derived-works-and-strong-vs-weak-copyleft",children:"Derived works and Strong vs. Weak Copyleft"}),"\n",(0,s.jsx)(n.p,{children:"What exactly constitutes derived work needs to be defined \u2014 it's one of the questions where\ncopyright law can get subtle. From a practical view, consuming (non-trivial) source code and\nbinary linking is typically considered creating derived works. Whereas interacting via a network\nAPI or starting another process is typically considered a copyright boundary. To avoid any\nunclarity, the Linux kernel community has explicitly called out using Linux system calls (which\nincludes using the interface definitions) is a copyright boundary and can thus be done by\napplications without any license implications."}),"\n",(0,s.jsx)(n.p,{children:"Considering linked code to be derived works (as is the case in the GPL and AGPL) and thus\nrequiring it under the same (or a compatible) copyleft license is considered a Strong Copyleft\nlicense."}),"\n",(0,s.jsxs)(n.p,{children:["Libraries are often providing implementations for standard services and helpers; it may not be\nreasonable to consider applications that want to use a library as derived works from that\nlibrary and requiring the application to thus be licensed under a (compatible) copyleft license.\nFor these libraries, a Weak Copyleft license (such as the ",(0,s.jsx)(n.a,{href:"https://www.gnu.org/licenses/lgpl-3.0.en.html",children:"LGPL"}),"\nor the ",(0,s.jsx)(n.a,{href:"https://www.eclipse.org/legal/epl-2.0/",children:"EPL"})," can be used. This would still require changes to\nthe library ",(0,s.jsx)(n.em,{children:"itself"})," to me made available under the copyleft license but would make binary\nlinking (including the use of interface definitions) a copyright barrier and thus allow for\nnon-copylefted code to be linked against a weakly copylefted library. This license is used by\nmany of the standard and system libraries in the Linux world and is often a good choice for\nlibraries of standardized services."]}),"\n",(0,s.jsx)(n.h2,{id:"patents",children:"Patents"}),"\n",(0,s.jsxs)(n.p,{children:["Free software licenses are intended to give users broad rights \u2014 the GNU GPL talks about the\n",(0,s.jsx)(n.a,{href:"https://fsfe.org/freesoftware/",children:"four freedoms"})," to use software for any purpose, to study and\nadjust the software (this needs source code access), to redistribute the software and to improve\nit and to make these improvements available."]}),"\n",(0,s.jsxs)(n.p,{children:["Software patents can significantly subvert the intended rights \u2014 the open source community in\ngeneral dislikes software patents for this and many other reasons that are discussed\n",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Software_patents_and_free_software",children:"elsewhere"})," .\nIn some countries, there are rules that prevent pure software from being patented, though ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Software_patents_under_the_European_Patent_Convention",children:"not\nall patent offices are fully following these rules"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"As software patents are existing and a serious danger to the open source goals, there are a few\nattempts to improve the situation. The Apache Software License (a permissive license), requires\ncode contributors to grant a patent license to all downstream recipients of the code\nto use the contributed code by itself or in combination with the project that it was contributed\nto and makes a possible patent holder lose its license rights should he nevertheless try to\nassert a patent against the thus licensed use. The (A)GPLv3 has a similar clause."}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://www.openinventionnetwork.com/",children:"Open Invention Network"})," (OIN) has a meanwhile\nhuge patent pool that is cross-licensed between all participants and which can freely be used\nin a large list of covered open source software by everyone, except for those that raise patent\nviolation claims against any of the covered open source projects. This basically restricts\nthose patents to be only used defensively in the context of the covered open source projects."]}),"\n",(0,s.jsx)(n.p,{children:"Should SCS be in a position to make inventions that should be protected by a software patent,\nit pledges to contribute these to the OIN pool."}),"\n",(0,s.jsx)(n.h2,{id:"copyright-assignments-and-contributor-license-agreements",children:"Copyright Assignments and Contributor License Agreements"}),"\n",(0,s.jsx)(n.p,{children:"Very few Open Source projects require copyright assignment; the GNU projects are the\nonly commonly used ones that the author is aware of. This results in fully centralized\ncopyright ownership. This puts the FSF into a very\nstrong position \u2014 a position to enforce copyright, to change licenses etc. This requires\na lot of trust towards the copyright assigneed."}),"\n",(0,s.jsx)(n.p,{children:"Most open source projects prefer distributed copyright \u2014 the authors (or their\nemployers) retain the copyright to their works. They grant a license for the open\nsource project to use and integrate and redistribute the work \u2014 typically the\nlicense grant is extended to the public. In a sufficiently distributed copyright model,\nit is very hard to change a license, as all copyright holders would need to agree.\nThis can both be considered advantageous and disadvantageous."}),"\n",(0,s.jsxs)(n.p,{children:["Many software projects use ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Contributor_License_Agreement",children:"Contributor License Agreements"}),"\n(CLAs), documenting that contributed code grants certain rights to the project\nowner (a foundation or sometimes a company). This ensures that the project owner\nhas all needed rights to use, protect, redistribute ... the code. If the CLA contains\n",(0,s.jsx)(n.em,{children:"copyright assignment"}),", it also allows the project to change the license or to\ncreate derived works under a different license."]}),"\n",(0,s.jsx)(n.p,{children:"While this is advantageous for the project owner, it is not necessarily advantageous for the\ncode contributor."}),"\n",(0,s.jsx)(n.p,{children:"Copyright enforcement does not require all copyrights to be held by a legal entity. Any holder\nof significant copyrights can actually enforce it against violators."}),"\n",(0,s.jsxs)(n.p,{children:["The Linux kernel and an increasing number of projects do not work with copyright assignments\nnor CLAs, but with ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Developer_Certificate_of_Origin",children:"Developer Certificates of Origin"}),"\n(DCO \u2014 the signed-off lines of kernel commits). This is deemed sufficient to document the origin and the authorization to\ncontribute code."]}),"\n",(0,s.jsx)(n.p,{children:"The SCS project will not change the license. There however might be cases, where potential users\ncan not consume AGPL'ed or LGPL'ed code (due to corporate policies, e.g. based on bad experience,\nimmature license governance practices or lawyers that panic). Our goal would be to ensure that our\nlicensing terms and all other pledges provide the assurance needed that users do not need to be\nafraid of the AGPL. The cure provisions from v3 of the GPL license family actually also help to\navoid unnecessary fear. However, unfortunately, some \"open source\" companies in the past have\nabused copyleft with a scare and sell a proprietary license tactics to make money, which has\nhurt copyleft acceptance significantly. We might thus not be successful and need to somehow\naccept not serving all users or come up with a relicensing scheme that can not corrupt\nourselves. We are following the copyleft-next discussion to work out how we can best achieve\nthis, but have not yet found the silver bullet. This might have an influence how we do DCOs,\nmaybe under a permissive license, or maybe need to use CLAs."}),"\n",(0,s.jsx)(n.h2,{id:"license-in--license-out",children:"License in = License out"}),"\n",(0,s.jsx)(n.p,{children:"It is best practice that open source projects grant their downstream users the same\nlicense rights as they received contributions under. Or worded the opposite direction:\nIt is best practice to require no more rights to be granted from upstream contributors\n(in the CLA or DCO) than the projects grants to downstream consumers of the project.\nSCS follows this best practice."}),"\n",(0,s.jsx)(n.h2,{id:"further-reading",children:"Further reading"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Comparison_of_free_and_open-source_software_licences",children:"https://en.wikipedia.org/wiki/Comparison_of_free_and_open-source_software_licences"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Software_patents_and_free_software",children:"https://en.wikipedia.org/wiki/Software_patents_and_free_software"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://joinup.ec.europa.eu/collection/eupl/matrix-eupl-compatible-open-source-licences",children:"https://joinup.ec.europa.eu/collection/eupl/matrix-eupl-compatible-open-source-licences"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://lwn.net/Articles/592503/",children:"https://lwn.net/Articles/592503/"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://sfconservancy.org/blog/2020/jan/06/copyleft-equality/",children:"https://sfconservancy.org/blog/2020/jan/06/copyleft-equality/"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://developercertificate.org",children:"https://developercertificate.org"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/",children:"https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/"})}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cf99a16e.9342a7aa.js b/assets/js/cf99a16e.9342a7aa.js new file mode 100644 index 0000000000..35664523b4 --- /dev/null +++ b/assets/js/cf99a16e.9342a7aa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[34855],{72775:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>f,frontMatter:()=>o,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/tools/simple-stress","title":"Simple Stress","description":"Overview","source":"@site/docs/02-iaas/guides/operations-guide/openstack/tools/simple-stress.md","sourceDirName":"02-iaas/guides/operations-guide/openstack/tools","slug":"/iaas/guides/operations-guide/openstack/tools/simple-stress","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/simple-stress.md","tags":[],"version":"current","sidebarPosition":55,"frontMatter":{"sidebar_label":"Simple Stress","sidebar_position":55},"sidebar":"docs","previous":{"title":"Sandbox Manager","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager"},"next":{"title":"OpenStack Health Monitor","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor"}}');var t=n(74848),r=n(28453);const o={sidebar_label:"Simple Stress",sidebar_position:55},a="Simple Stress",l={},d=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Defaults",id:"defaults",level:2},{value:"Usage",id:"usage",level:2},{value:"Config files",id:"config-files",level:2}];function c(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"simple-stress",children:"Simple Stress"})}),"\n",(0,t.jsx)(s.h2,{id:"overview",children:"Overview"}),"\n",(0,t.jsx)(s.p,{children:"The OpenStack Simple Stress is a small stress test for your Openstack Cluster. You can use it for burnin tests or if you want to monitor your cluster perfomance.\nIt is able to start a predefined amount of Servers in specific networks in parallel and serial and removes them afterwards, so you can test your environment to the limits."}),"\n",(0,t.jsx)(s.h2,{id:"installation",children:"Installation"}),"\n",(0,t.jsx)(s.p,{children:"Prepare to use the Openstack Simple Stress."}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"git clone https://github.com/osism/openstack-simple-stress\ncd openstack-simple-stress\npipenv install\npipenv shell\n"})}),"\n",(0,t.jsx)(s.h2,{id:"defaults",children:"Defaults"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.code,{children:"main.py"})," command and the default options while executing the command."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:" --cleanup true\n --cloud simple-stress\n --compute-zone nova\n --debug false\n --delete true\n --flavor SCS-2V-8\n --floating false\n --image Ubuntu 22.04\n --interval 10 (seconds)\n --keypair unset\n --network simple-stress\n --network-zone nova\n --number 1\n --parallel 1\n --prefix simple-stress\n --storage-zone simple-stress\n --timeout 600 (seconds)\n --volume false\n --volume-number 1\n --volume-size 1 (gigabyte)\n --wait true\n"})}),"\n",(0,t.jsx)(s.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsxs)(s.p,{children:["There must be a ",(0,t.jsx)(s.code,{children:"clouds.yml"})," and a ",(0,t.jsx)(s.code,{children:"secure.yml"})," file in the directory where the OpenStack Simple Stress will be executed, examples are provided within the git repository."]}),"\n",(0,t.jsxs)(s.p,{children:["The cloud profile to be used can be specified via the optional ",(0,t.jsx)(s.code,{children:"--cloud"})," parameter. By default, the cloud profile with the name ",(0,t.jsx)(s.code,{children:"simple-stress"})," is used."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"$ python src/main.py -h\nusage: main [-h] [--cleanup] [--cloud CLOUD] [--compute-zone COMPUTE_ZONE] [--config-dir DIR]\n [--config-file PATH] [--debug] [--delete] [--flavor FLAVOR] [--floating] [--image IMAGE]\n [--interval INTERVAL] [--keypair KEYPAIR] [--network NETWORK] [--network-zone NETWORK_ZONE]\n [--nocleanup] [--nodebug] [--nodelete] [--nofloating] [--novolume] [--nowait]\n [--number NUMBER] [--parallel PARALLEL] [--prefix PREFIX] [--storage-zone STORAGE_ZONE]\n [--timeout TIMEOUT] [--volume] [--volume-number VOLUME_NUMBER] [--volume-size VOLUME_SIZE]\n [--wait]\n\noptions:\n -h, --help show this help message and exit\n --cleanup\n --cloud CLOUD Cloud name\n --compute-zone COMPUTE_ZONE\n Compute availability zone to use\n --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted,\n so as to provide a predictable parse order if individual options are over-\n ridden. The set is parsed after the file(s) specified via previous --config-\n file, arguments hence over-ridden options in the directory take precedence. This\n option must be set from the command-line.\n --config-file PATH Path to a config file to use. Multiple config files can be specified, with\n values in later files taking precedence. Defaults to None. This option must be\n set from the command-line.\n --debug\n --delete\n --flavor FLAVOR\n --floating\n --image IMAGE\n --interval INTERVAL\n --keypair KEYPAIR\n --network NETWORK\n --network-zone NETWORK_ZONE\n Network availability zone to use\n --nocleanup The inverse of --cleanup\n --nodebug The inverse of --debug\n --nodelete The inverse of --delete\n --nofloating The inverse of --floating\n --novolume The inverse of --volume\n --nowait The inverse of --wait\n --number NUMBER\n --parallel PARALLEL\n --prefix PREFIX\n --storage-zone STORAGE_ZONE\n Storage availability zone to use\n --timeout TIMEOUT\n --volume\n --volume-number VOLUME_NUMBER\n --volume-size VOLUME_SIZE\n --wait\n"})}),"\n",(0,t.jsx)(s.p,{children:"Running a small and simple test on your Openstack environment, using Ubuntu_22.04 image with the flavor of 2VCPUs and 8Gigabytes of RAM, starting 6 servers, 2 parallel each with a volume size of 20Gigabytes."}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"$ python src/main.py --network test-net --flavor SCS-2V-8 --image Ubuntu_22.04 --number 6 --parallel 2 --volume-size 20\n2024-04-23 11:47:16 | INFO | Checking flavor SCS-2V-8\n2024-04-23 11:47:17 | INFO | flavor.id = 926f952f-0714-4c55-92c2-7514191fecce\n2024-04-23 11:47:17 | INFO | Checking image Ubuntu_22.04\n2024-04-23 11:47:17 | INFO | image.id = 667649d6-e828-403b-8871-15dde7b9ce85\n2024-04-23 11:47:17 | INFO | Checking network test-net\n2024-04-23 11:47:18 | INFO | network.id = 9688192e-11dd-4618-a18c-99d3267f630a\n2024-04-23 11:47:18 | INFO | Creating server simple-stress-0\n2024-04-23 11:47:18 | INFO | Creating server simple-stress-1\n2024-04-23 11:47:18 | INFO | Waiting for server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:18 | INFO | Waiting for server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:28 | INFO | Waiting for boot / test results of 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:29 | INFO | Waiting for boot / test results of e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:39 | INFO | Deleting server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:39 | INFO | Waiting for deletion of server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:39 | INFO | Deleting server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:40 | INFO | Waiting for deletion of server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:49 | INFO | Creating server simple-stress-2\n2024-04-23 11:47:50 | INFO | Creating server simple-stress-3\n2024-04-23 11:47:50 | INFO | Waiting for server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:47:51 | INFO | Waiting for server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:00 | INFO | Waiting for boot / test results of 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:48:01 | INFO | Waiting for boot / test results of a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:11 | INFO | Deleting server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:12 | INFO | Waiting for deletion of server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:12 | INFO | Deleting server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:48:12 | INFO | Waiting for deletion of server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:48:22 | INFO | Creating server simple-stress-4\n2024-04-23 11:48:22 | INFO | Waiting for server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:22 | INFO | Creating server simple-stress-5\n2024-04-23 11:48:23 | INFO | Waiting for server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:48:55 | INFO | Deleting server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:55 | INFO | Deleting server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:48:55 | INFO | Waiting for deletion of server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:55 | INFO | Waiting for deletion of server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:49:05 | INFO | Server 049bf974-b0fd-467f-aabd-3593b2a409a4 finished\n2024-04-23 11:49:05 | INFO | Server e485697f-feae-458c-952d-000072374c3f finished\n2024-04-23 11:49:05 | INFO | Server a098cc12-94ff-4036-bf42-4fc08287809f finished\n2024-04-23 11:49:05 | INFO | Server 26595dd3-09d4-4758-8d1f-58a40b681d11 finished\n2024-04-23 11:49:05 | INFO | Server 05b9f996-5a06-4359-b495-3463cc7b81e0 finished\n2024-04-23 11:49:05 | INFO | Server 8d372de6-ca07-4afb-9e80-1589fd5242e8 finished\n2024-04-23 11:49:05 | INFO | Runtime: 107.4460s\n"})}),"\n",(0,t.jsx)(s.p,{children:"Using a config directory with configfiles to run the test."}),"\n",(0,t.jsxs)(s.p,{children:["Path to a config directory to pull ",(0,t.jsx)(s.code,{children:"*.conf"})," files from. This file set is sorted,\nso as to provide a predictable parse order if individual options are over-ridden.\nThe set is parsed after the file(s) specified via previous --config file,\narguments hence over-ridden options in the directory take precedence. This\noption must be set from the command-line."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"python src/main.py --config-dir /path/to/config-dir\n"})}),"\n",(0,t.jsx)(s.h2,{id:"config-files",children:"Config files"}),"\n",(0,t.jsxs)(s.p,{children:["The config files which can be used for ",(0,t.jsx)(s.code,{children:"main.py"})," are using the ",(0,t.jsx)(s.a,{href:"https://docs.openstack.org/oslo.config/latest/configuration/quickstart.html",children:"oslo.config format"}),", you can set the command line options as ",(0,t.jsx)(s.code,{children:"key = value pair"})," and create your own config files matching your setup."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-yaml",metastring:'title="mytest.conf"',children:"[DEFAULT]\ncloud = simple-stress\nnetwork = test-net\nnumber = 6\nparallel = 2\nflavor = SCS-2V-8\nimage = Ubuntu_22.04\nvolume-size = 20\n"})})]})}function f(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var i=n(96540);const t={},r=i.createContext(t);function o(e){const s=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cffc493c.4c29b257.js b/assets/js/cffc493c.4c29b257.js new file mode 100644 index 0000000000..f53d6b8248 --- /dev/null +++ b/assets/js/cffc493c.4c29b257.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[40714],{70984:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"contribute/docs-workflow-explanation","title":"Documentation workflow explanation","description":"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.","source":"@site/community/contribute/docs-workflow-explanation.md","sourceDirName":"contribute","slug":"/contribute/docs-workflow-explanation","permalink":"/community/contribute/docs-workflow-explanation","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Documentation Files Structure","permalink":"/community/contribute/doc-files-structure-guide"},"next":{"title":"Linting Guide","permalink":"/community/contribute/linting-guide"}}');var r=n(74848),i=n(28453);const s={},c="Documentation workflow explanation",a={},d=[{value:"Information Architecture",id:"information-architecture",level:2}];function l(e){const o={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(o.header,{children:(0,r.jsx)(o.h1,{id:"documentation-workflow-explanation",children:"Documentation workflow explanation"})}),"\n",(0,r.jsx)(o.p,{children:"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."}),"\n",(0,r.jsx)(o.h2,{id:"information-architecture",children:"Information Architecture"}),"\n",(0,r.jsxs)(o.ul,{children:["\n",(0,r.jsxs)(o.li,{children:["\n",(0,r.jsxs)(o.p,{children:["All general docs are located within the ",(0,r.jsx)(o.a,{href:"https://github.com/SovereignCloudStack/docs",children:"SovereignCloudStack/docs"})," repository."]}),"\n"]}),"\n",(0,r.jsxs)(o.li,{children:["\n",(0,r.jsx)(o.p,{children:"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."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(o.p,{children:["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 ",(0,r.jsx)(o.a,{href:"https://docs.scs.community",children:"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."]}),"\n",(0,r.jsxs)(o.p,{children:["The script is called ",(0,r.jsx)(o.code,{children:"getDocs"}),". It is a postinstall script and is executed after ",(0,r.jsx)(o.code,{children:"npm install"}),". This has the advantage to have the docs \u2013 coming from the cloud \u2013 in your local docusaurus development environment as well as in the build process."]}),"\n",(0,r.jsxs)(o.p,{children:["You'll find the script in the root directory of the ",(0,r.jsx)(o.a,{href:"https://github.com/SovereignCloudStack/docs-page",children:"SovereignCloudStack/docs-page"})," repository:"]}),"\n",(0,r.jsx)(o.pre,{children:(0,r.jsx)(o.code,{className:"language-js",metastring:'title="getDocs.js"',children:"const fs = require('fs')\nconst { execSync } = require('child_process')\n\n// Read the contents of the \"docs.package.json\" file and remove all whitespace\nconst reposJson = fs\n .readFileSync('./docs.package.json', 'utf8')\n .replace(/\\s/g, '')\n\n// Parse the JSON and create an array of repositories\nconst repos = JSON.parse(reposJson)\nconst ghUrl = 'https://github.com/'\n\n// Clone each repository, remove git folders and README files, and copy the docs to the target directory\nrepos.forEach((repo) => {\n const repoDir = `repo_to_be_edited/${repo.label}`\n\n // Clone the repository\n const cloneCommand = `git clone ${ghUrl + repo.repo} ${repoDir}`\n execSync(cloneCommand)\n\n // Remove git folders\n const removeGitCommand = `rm -rf ${repoDir}/.git`\n execSync(removeGitCommand)\n\n // Remove README files\n const removeReadmeCommand = `find ${repoDir} -name \"README.md\" | xargs rm -f`\n execSync(removeReadmeCommand)\n\n // Create the docusaurus subdirectory\n const subDirPath = `${repo.target}/${repo.label}`\n fs.mkdirSync(subDirPath, { recursive: true })\n\n // Copy docs content from A to B\n const copyDocsCommand = `cp -r ${repoDir}/${repo.source} ${subDirPath}`\n execSync(copyDocsCommand)\n\n // Remove the cloned repository\n const removeRepoCommand = 'rm -rf repo_to_be_edited'\n execSync(removeRepoCommand)\n})\n"})})]})}function h(e={}){const{wrapper:o}={...(0,i.R)(),...e.components};return o?(0,r.jsx)(o,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,o,n)=>{n.d(o,{R:()=>s,x:()=>c});var t=n(96540);const r={},i=t.createContext(r);function s(e){const o=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function c(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),t.createElement(i.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d0ee365b.2f7697ee.js b/assets/js/d0ee365b.2f7697ee.js new file mode 100644 index 0000000000..3392cd6833 --- /dev/null +++ b/assets/js/d0ee365b.2f7697ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[26223],{40208:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>a});const i=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/index","title":"OpenStack","description":"Image tags","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/index.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/","permalink":"/docs/iaas/guides/configuration-guide/openstack/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/index.md","tags":[],"version":"current","sidebarPosition":30,"frontMatter":{"sidebar_label":"OpenStack","sidebar_position":30},"sidebar":"docs","previous":{"title":"Ceph","permalink":"/docs/iaas/guides/configuration-guide/ceph"},"next":{"title":"Aodh","permalink":"/docs/iaas/guides/configuration-guide/openstack/aodh"}}');var l=t(74848),s=t(28453);const r={sidebar_label:"OpenStack",sidebar_position:30},o="OpenStack",c={},a=[{value:"Image tags",id:"image-tags",level:2},{value:"Endpoints",id:"endpoints",level:2},{value:"Public endpoints",id:"public-endpoints",level:3},{value:"Example for the use of name-based endpoints",id:"example-for-the-use-of-name-based-endpoints",level:3},{value:"Network interfaces",id:"network-interfaces",level:2},{value:"Customization of the service configurations",id:"customization-of-the-service-configurations",level:2},{value:"How does the configuration get into services?",id:"how-does-the-configuration-get-into-services",level:2},{value:"Number of service workers",id:"number-of-service-workers",level:2},{value:"Back-end TLS configuration",id:"back-end-tls-configuration",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"openstack",children:"OpenStack"})}),"\n",(0,l.jsx)(n.h2,{id:"image-tags",children:"Image tags"}),"\n",(0,l.jsxs)(n.p,{children:["Sometimes it is necessary to specify the image tag to be used for a specific service or a specific image of a service.\nAll available images and tags are listed in the ",(0,l.jsx)(n.a,{href:"https://github.com/osism/defaults/blob/main/all/002-images-kolla.yml",children:"002-images-kolla.yml"}),"\nfile."]}),"\n",(0,l.jsxs)(n.p,{children:["The image tags can be set in the ",(0,l.jsx)(n.code,{children:"environments/kolla/images.yml"})," file."]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Use a specific tag for all images of a service:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/images.yml"',children:'barbican_tag: "2023.1"\n'})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"Use a specific tag for a specific image of a service:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/images.yml"',children:'barbican_worker_tag: "2023.1"\n'})}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"endpoints",children:"Endpoints"}),"\n",(0,l.jsx)(n.h3,{id:"public-endpoints",children:"Public endpoints"}),"\n",(0,l.jsxs)(n.p,{children:["The public endpoints used for the individual OpenStack services can be configured via the ",(0,l.jsx)(n.code,{children:"public_endpoint"})," parameters.\nThese are defined as follows."]}),"\n",(0,l.jsxs)(n.table,{children:[(0,l.jsx)(n.thead,{children:(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,l.jsx)(n.th,{style:{textAlign:"left"},children:"Default value"})]})}),(0,l.jsxs)(n.tbody,{children:[(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"aodh_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"aodh_external_fqdn | kolla_url(public_protocol, aodh_api_public_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"blazar_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"blazar_external_fqdn | kolla_url(public_protocol, blazar_api_public_port, '/v1')"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"ceph_rgw_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"ceph_rgw_external_fqdn | kolla_url(public_protocol, ceph_rgw_public_port, ceph_rgw_endpoint_path)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"cinder_v3_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ cinder_public_base_endpoint }}/v3/%(tenant_id)s"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"cloudkitty_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"cloudkitty_external_fqdn | kolla_url(public_protocol, cloudkitty_api_public_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"cyborg_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"cyborg_external_fqdn | kolla_url(public_protocol, cyborg_api_port, '/v2')"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"gnocchi_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"gnocchi_external_fqdn | kolla_url(public_protocol, gnocchi_api_public_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"heat_cfn_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ heat_cfn_public_base_endpoint }}/v1"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"heat_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"heat_external_fqdn | kolla_url(public_protocol, heat_api_public_port, '/v1/%(tenant_id)s')"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"ironic_inspector_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"ironic_inspector_external_fqdn | kolla_url(public_protocol, ironic_inspector_public_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"magnum_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"magnum_external_fqdn | kolla_url(public_protocol, magnum_api_public_port, '/v1')"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"manila_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ manila_public_base_endpoint }}/v1/%(tenant_id)s"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"manila_v2_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ manila_public_base_endpoint }}/v2"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"masakari_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"masakari_external_fqdn | kolla_url(public_protocol, masakari_api_public_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"mistral_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"mistral_external_fqdn | kolla_url(public_protocol, mistral_api_public_port, '/v2')"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"nova_legacy_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ nova_public_base_endpoint }}/v2/%(tenant_id)s"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"nova_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ nova_public_base_endpoint }}/v2.1"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"placement_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"placement_external_fqdn | kolla_url(public_protocol, placement_api_public_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"tacker_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"tacker_external_fqdn | kolla_url(public_protocol, tacker_server_public_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"trove_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"trove_external_fqdn | kolla_url(public_protocol, trove_api_public_port, '/v1.0/%(tenant_id)s')"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"venus_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"venus_external_fqdn | kolla_url(public_protocol, venus_api_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"watcher_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"watcher_external_fqdn | kolla_url(public_protocol, watcher_api_public_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"zun_public_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"zun_external_fqdn | kolla_url(public_protocol, zun_api_public_port, '/v1/')"})})]})]})]}),"\n",(0,l.jsxs)(n.p,{children:["Some of the previous default values refer to a ",(0,l.jsx)(n.code,{children:"public_base_endpoint parameter"}),". These are defined as follows."]}),"\n",(0,l.jsxs)(n.table,{children:[(0,l.jsx)(n.thead,{children:(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,l.jsx)(n.th,{style:{textAlign:"left"},children:"Default value"})]})}),(0,l.jsxs)(n.tbody,{children:[(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"cinder_public_base_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"cinder_external_fqdn | kolla_url(public_protocol, cinder_api_public_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"heat_cfn_public_base_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"heat_cfn_external_fqdn | kolla_url(public_protocol, heat_api_cfn_public_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"manila_public_base_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"manila_external_fqdn | kolla_url(public_protocol, manila_api_public_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"nova_public_base_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"nova_external_fqdn | kolla_url(public_protocol, nova_api_public_port)"})})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"skyline_apiserver_public_base_endpoint"}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"skyline_apiserver_external_fqdn | kolla_url(public_protocol, skyline_apiserver_public_port)"})})]})]})]}),"\n",(0,l.jsx)(n.h3,{id:"example-for-the-use-of-name-based-endpoints",children:"Example for the use of name-based endpoints"}),"\n",(0,l.jsxs)(n.p,{children:["DNS records pointing to the ",(0,l.jsx)(n.code,{children:"kolla_external_vip_address"})," are created in advance."]}),"\n",(0,l.jsxs)(n.p,{children:["Additional configuration parameters to overwrite the public endpoints\nare added in the ",(0,l.jsx)(n.code,{children:"environments/kolla/configuration.yml"})," file. If certain services\nare not used, they are removed. If other services are used, these are added (see the\ntable above)."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:"barbican_public_endpoint: https://barbican.services.a.regiocloud.tech\ncinder_public_base_endpoint: https://cinder.services.a.regiocloud.tech\ndesignate_public_endpoint: https://designate.services.a.regiocloud.tech\nglance_public_endpoint: https://glance.services.a.regiocloud.tech\nironic_public_endpoint: https://ironic.services.a.regiocloud.tech\nkeystone_public_url: https://keystone.services.a.regiocloud.tech\nmanila_public_endpoint: https://manila.services.a.regiocloud.tech\nneutron_public_endpoint: https://neutron.services.a.regiocloud.tech\nnova_public_base_endpoint: https://nova.services.a.regiocloud.tech\noctavia_public_endpoint: https://octavia.services.a.regiocloud.tech\nplacement_public_endpoint: https://placement.services.a.regiocloud.tech\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Since we bind the ",(0,l.jsx)(n.code,{children:"name_based_external_front"})," frontend to the same ports as the\n",(0,l.jsx)(n.code,{children:"horizon_external_front"}),", the external Horizon frontend must be disabled. This is\nonly possible as of OSISM 7.0.6."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:"haproxy_enable_horizon_external: false\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Additional HAProxy configuration in ",(0,l.jsx)(n.code,{children:"haproxy/services.d/haproxy.cfg"})," is required to map\nthe DNS records to the correct backends. Here too, unused services are removed or\nadditional services are added."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-none",metastring:'title="environments/kolla/files/overlays/haproxy/services.d/haproxy.cfg"',children:"frontend name_based_external_front\n mode http\n http-request del-header X-Forwarded-Proto\n option httplog\n option forwardfor\n http-request set-header X-Forwarded-Proto https if { ssl_fc }\n bind {{ kolla_external_vip_address }}:80\n bind {{ kolla_external_vip_address }}:443 ssl crt /etc/haproxy/certificates/haproxy.pem\n default_backend horizon_back\n\n acl ACL_keystone.services.a.regiocloud.tech hdr(host) -i keystone.services.a.regiocloud.tech\n use_backend keystone_external_back if ACL_keystone.services.a.regiocloud.tech\n\n acl ACL_glance.services.a.regiocloud.tech hdr(host) -i glance.services.a.regiocloud.tech\n use_backend glance_api_external_back if ACL_glance.services.a.regiocloud.tech\n\n acl ACL_neutron.services.a.regiocloud.tech hdr(host) -i neutron.services.a.regiocloud.tech\n use_backend neutron_server_external_back if ACL_neutron.services.a.regiocloud.tech\n\n acl ACL_placement.services.a.regiocloud.tech hdr(host) -i placement.services.a.regiocloud.tech\n use_backend placement_api_external_back if ACL_placement.services.a.regiocloud.tech\n\n acl ACL_nova.services.a.regiocloud.tech hdr(host) -i nova.services.a.regiocloud.tech\n use_backend nova_api_external_back if ACL_nova.services.a.regiocloud.tech\n\n acl ACL_console.services.a.regiocloud.tech hdr(host) -i console.services.a.regiocloud.tech\n use_backend nova_novncproxy_external_back if ACL_console.services.a.regiocloud.tech\n\n acl ACL_designate.services.a.regiocloud.tech hdr(host) -i designate.services.a.regiocloud.tech\n use_backend designate_api_external_back if ACL_designate.services.a.regiocloud.tech\n\n acl ACL_cinder.services.a.regiocloud.tech hdr(host) -i cinder.services.a.regiocloud.tech\n use_backend cinder_api_external_back if ACL_cinder.services.a.regiocloud.tech\n\n acl ACL_octavia.services.a.regiocloud.tech hdr(host) -i octavia.services.a.regiocloud.tech\n use_backend octavia_api_external_back if ACL_octavia.services.a.regiocloud.tech\n\n acl ACL_swift.services.a.regiocloud.tech hdr(host) -i swift.services.a.regiocloud.tech\n use_backend swift_api_external_back if ACL_swift.services.a.regiocloud.tech\n\n acl ACL_ironic.services.a.regiocloud.tech hdr(host) -i ironic.services.a.regiocloud.tech\n use_backend ironic_api_external_back if ACL_ironic.services.a.regiocloud.tech\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Additional Nova configuration in ",(0,l.jsx)(n.code,{children:"nova.conf"})," is required to use the URL for the NoVNC service."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ini",metastring:'title="environments/kolla/files/overlays/nova.conf"',children:"[vnc]\nnovncproxy_base_url = https://console.services.a.regiocloud.tech/vnc_lite.html\n"})}),"\n",(0,l.jsx)(n.h2,{id:"network-interfaces",children:"Network interfaces"}),"\n",(0,l.jsxs)(n.table,{children:[(0,l.jsx)(n.thead,{children:(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,l.jsx)(n.th,{style:{textAlign:"left"},children:"Default"}),(0,l.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,l.jsxs)(n.tbody,{children:[(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"network_interface"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"eth0"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"neutron_external_interface"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ network_interface }}"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"kolla_external_vip_interface"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ network_interface }}"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"api_interface"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ network_interface }}"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"migration_interface"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ api_interface }}"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"tunnel_interface"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ network_interface }}"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"octavia_network_interface"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ 'o-hm0' if octavia_network_type == 'tenant' else api_interface }}"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"dns_interface"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ network_interface }}"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"dpdk_tunnel_interface"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ neutron_external_interface }}"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"ironic_http_interface"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ api_interface }}"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(n.tr,{children:[(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"ironic_tftp_interface"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"},children:(0,l.jsx)(n.code,{children:"{{ api_interface }}"})}),(0,l.jsx)(n.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,l.jsx)(n.h2,{id:"customization-of-the-service-configurations",children:"Customization of the service configurations"}),"\n",(0,l.jsx)(n.admonition,{type:"info",children:(0,l.jsxs)(n.p,{children:["The following content is based on the ",(0,l.jsx)(n.a,{href:"https://docs.openstack.org/kolla-ansible/latest/admin/advanced-configuration.html#openstack-service-configuration-in-kolla",children:"kolla-ansible uptream documentation"}),"."]})}),"\n",(0,l.jsxs)(n.p,{children:["OSISM will generally look for files in ",(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/CONFIGFILE"}),",\n",(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/SERVICENAME/CONFIGFILE"})," or ",(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/SERVICENAME/HOSTNAME/CONFIGFILE"}),"\nin the configuration repository. These locations sometimes vary and you should check the config task in the appropriate\nAnsible role for a full list of supported locations. For example, in the case of ",(0,l.jsx)(n.code,{children:"nova.conf"})," the following locations are\nsupported, assuming that you have services using ",(0,l.jsx)(n.code,{children:"nova.conf"})," running on hosts called ctl1, ctl2 and ctl3:"]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/nova.conf"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/nova/ctl1/nova.conf"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/nova/ctl2/nova.conf"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/nova/ctl3/nova.conf"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/nova/nova-scheduler.conf"})}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:"Using this mechanism, overrides can be configured per-project (Nova), per-project-service (Nova scheduler service) or\nper-project-service-on-specified-host (Nova servies on ctl1)."}),"\n",(0,l.jsxs)(n.p,{children:["Overriding an option is as simple as setting the option under the relevant section. For example, to set\noverride ",(0,l.jsx)(n.code,{children:"scheduler_max_attempts"})," in the Nova scheduler service, the operator could create\n",(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/nova/nova-scheduler.conf"})," in the configuration repository with this content:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ini",children:"[DEFAULT]\nscheduler_max_attempts = 100\n"})}),"\n",(0,l.jsxs)(n.p,{children:["If the operator wants to configure the initial disk, cpu and ram allocation ratio on compute node ",(0,l.jsx)(n.code,{children:"com1"}),",\nthe operator needs to create the file ",(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/nova/com1/nova.conf"})," with this\ncontent:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ini",children:"[DEFAULT]\ninitial_cpu_allocation_ratio = 3.0\ninitial_ram_allocation_ratio = 1.0\ninitial_disk_allocation_ratio = 1.0\n"})}),"\n",(0,l.jsxs)(n.p,{children:["Note that the numbers shown here with an ",(0,l.jsx)(n.code,{children:"initial_cpu_allocation_ratio"})," of 3.0 do match the requirements\nof the SCS-nV-* (moderate oversubscription) flavors. If you do not use SMT/hyperthreading, SCS would allow\n5.0 here (for the V flavors)."]}),"\n",(0,l.jsxs)(n.p,{children:["This method of merging configuration sections is supported for all services using ",(0,l.jsx)(n.a,{href:"https://docs.openstack.org/oslo.config/latest/",children:"oslo.config"}),",\nwhich includes the vast majority of OpenStack services, and in some cases for services using YAML configuration.\nSince the INI format is an informal standard, not all INI files can be merged in this way. In these cases OSISM supports\noverriding the entire config file."]}),"\n",(0,l.jsxs)(n.p,{children:["Additional flexibility can be introduced by using Jinja conditionals in the config files. For example, you may create\nNova cells which are homogeneous with respect to the hypervisor model. In each cell, you may wish to configure the\nhypervisors differently, for example the following override shows one way of setting the ",(0,l.jsx)(n.code,{children:"bandwidth_poll_interval"}),"\nvariable as a function of the cell:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ini",children:"[DEFAULT]\n{% if 'cell0001' in group_names %}\nbandwidth_poll_interval = 100\n{% elif 'cell0002' in group_names %}\nbandwidth_poll_interval = -1\n{% else %}\nbandwidth_poll_interval = 300\n{% endif %}\n"})}),"\n",(0,l.jsxs)(n.p,{children:["An alternative to Jinja conditionals would be to define a variable for the ",(0,l.jsx)(n.code,{children:"bandwidth_poll_interval"})," and set\nit in according to your requirements in the inventory group or host vars:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ini",children:"[DEFAULT]\nbandwidth_poll_interval = {{ bandwidth_poll_interval }}\n"})}),"\n",(0,l.jsxs)(n.p,{children:["OSISM allows the operator to override configuration globally for all services. It will look for a file\ncalled ",(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/global.conf"})," in the configuration repository."]}),"\n",(0,l.jsxs)(n.p,{children:["For example to modify database pool size connection for all services, the operator needs to create\n",(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/global.conf"})," in the configuration repository with this content:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ini",children:"[database]\nmax_pool_size = 100\n"})}),"\n",(0,l.jsx)(n.h2,{id:"how-does-the-configuration-get-into-services",children:"How does the configuration get into services?"}),"\n",(0,l.jsx)(n.p,{children:"It is explained with example of OpenSearch Service how the configuration for OpenSearch\nis created and gets into the container."}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["The task ",(0,l.jsx)(n.a,{href:"https://github.com/openstack/kolla-ansible/blob/master/ansible/roles/opensearch/tasks/config.yml",children:"Copying over opensearch service config file"}),"\nmerges the individual sources of the files."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="Copying over opensearch service config file task"',children:'- name: Copying over opensearch service config file\n merge_yaml:\n sources:\n # highlight-start\n - "{{ role_path }}/templates/opensearch.yml.j2"\n - "{{ node_custom_config }}/opensearch.yml"\n - "{{ node_custom_config }}/opensearch/opensearch.yml"\n - "{{ node_custom_config }}/opensearch/{{ inventory_hostname }}/opensearch.yml"\n # highlight-end\n dest: "{{ node_config_directory }}/opensearch/opensearch.yml"\n mode: "0660"\n become: true\n when:\n - inventory_hostname in groups[\'opensearch\']\n - opensearch_services[\'opensearch\'].enabled | bool\n notify:\n - Restart opensearch container\n'})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["As a basis a template ",(0,l.jsx)(n.a,{href:"https://github.com/openstack/kolla-ansible/blob/master/ansible/roles/opensearch/templates/opensearch.yml.j2",children:"opensearch.yml.j2"}),"\nis used which is part of the OpenSearch service role."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="opensearch.yml.j2 template"',children:"{% set num_nodes = groups['opensearch'] | length %}\n{% set recover_after_nodes = (num_nodes * 2 / 3) | round(0, 'floor') | int if num_nodes > 1 else 1 %}\nplugins.security.disabled: \"true\"\n\nnode.name: \"{{ 'api' | kolla_address | put_address_in_context('url') }}\"\nnetwork.host: \"{{ 'api' | kolla_address | put_address_in_context('url') }}\"\n\ncluster.name: \"{{ opensearch_cluster_name }}\"\ncluster.initial_master_nodes: [{% for host in groups['opensearch'] %}\"{{ 'api' | kolla_address(host) }}\"{% if not loop.last %},{% endif %}{% endfor %}]\nnode.master: true\nnode.data: true\ndiscovery.seed_hosts: [{% for host in groups['opensearch'] %}\"{{ 'api' | kolla_address(host) | put_address_in_context('url') }}\"{% if not loop.last %},{% endif %}{% endfor %}]\n\nhttp.port: {{ opensearch_port }}\ngateway.expected_nodes: {{ num_nodes }}\ngateway.recover_after_time: \"5m\"\ngateway.recover_after_nodes: {{ recover_after_nodes }}\npath.data: \"/var/lib/opensearch/data\"\npath.logs: \"/var/log/kolla/opensearch\"\nindices.fielddata.cache.size: 40%\naction.auto_create_index: \"true\"\n"})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsx)(n.p,{children:"For OpenSearch, overlay files can additionally be stored in 3 places in the configuration repository."}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/opensearch.yml"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/opensearch/opensearch.yml"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/opensearch/{{ inventory_hostname }}/opensearch.yml"})}),"\n"]}),"\n",(0,l.jsxs)(n.p,{children:["When merging files, the last file found has the most weight. If there is a parameter ",(0,l.jsx)(n.code,{children:"node.master: true"}),"\nin the service role template ",(0,l.jsx)(n.code,{children:"opensearch.yml.j2"})," of the OpenSearch service and you set e.g.\n",(0,l.jsx)(n.code,{children:"node.master: false"})," in ",(0,l.jsx)(n.code,{children:"environments/kolla/files/overlays/opensearch.yml"})," then accordingly in the finished ",(0,l.jsx)(n.code,{children:"opensearch.yml"}),"\n",(0,l.jsx)(n.code,{children:"node.master: false"})," is used."]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["After the merge the task ",(0,l.jsx)(n.code,{children:"Copying over opensearch service config file"})," copies the content into the\nconfiguration directory ",(0,l.jsx)(n.code,{children:"/etc/kolla/opensearch"})," of the service."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="/etc/kolla/opensearch/opensearch.yml"',children:"action.auto_create_index: 'true'\ncluster.initial_master_nodes:\n- 192.168.16.10\ncluster.name: kolla_logging\ndiscovery.seed_hosts:\n- 192.168.16.10\ngateway.expected_nodes: 1\ngateway.recover_after_nodes: 1\ngateway.recover_after_time: 5m\nhttp.port: 9200\nindices.fielddata.cache.size: 40%\nnetwork.host: 192.168.16.10\nnode.data: true\nnode.master: true\nnode.name: 192.168.16.10\npath.data: /var/lib/opensearch/data\npath.logs: /var/log/kolla/opensearch\nplugins.security.disabled: 'true'\n"})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["The configuration directory ",(0,l.jsx)(n.code,{children:"/etc/kolla/opensearch"})," is mounted in each container of the OpenSearch service\nto ",(0,l.jsx)(n.code,{children:"/var/lib/kolla/config_files"}),"."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",metastring:'title="Output of docker inspect opensearch"',children:'"Mounts": [\n {\n "Type": "bind",\n // highlight-start\n "Source": "/etc/kolla/opensearch",\n "Destination": "/var/lib/kolla/config_files",\n // highlight-end\n "Mode": "rw",\n "RW": true,\n "Propagation": "rprivate"\n },\n'})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["Entrypoint of a service is always ",(0,l.jsx)(n.a,{href:"https://github.com/openstack/kolla/blob/master/docker/base/start.sh",children:"kolla_start"}),".\nThis script calls a script ",(0,l.jsx)(n.a,{href:"https://github.com/openstack/kolla/blob/master/docker/base/set_configs.py",children:"set_configs.py"}),".\nThis script takes care of copying files from ",(0,l.jsx)(n.code,{children:"/var/lib/kolla/config_files"})," to the right place inside the container.\nFor this purpose, the container has a\n",(0,l.jsx)(n.a,{href:"https://github.com/openstack/kolla-ansible/blob/master/ansible/roles/opensearch/templates/opensearch.json.j2",children:"config.json"}),"\nin which the individual actions are configured."]}),"\n",(0,l.jsxs)(n.p,{children:["The file ",(0,l.jsx)(n.code,{children:"/var/lib/kolla/config_files/opensearch.yml"})," is copied to ",(0,l.jsx)(n.code,{children:"/etc/opensearch/opensearch.yml"}),"."]}),"\n",(0,l.jsxs)(n.p,{children:["The permissions of ",(0,l.jsx)(n.code,{children:"/var/lib/opensearch"})," and ",(0,l.jsx)(n.code,{children:"/var/log/kolla/opensearch"})," are set accordingly."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",metastring:'title="/etc/kolla/opensearch/config.json"',children:'{\n "command": "/usr/share/opensearch/bin/opensearch",\n "config_files": [\n {\n // highlight-start\n "source": "/var/lib/kolla/config_files/opensearch.yml",\n "dest": "/etc/opensearch/opensearch.yml",\n "owner": "opensearch",\n "perm": "0600"\n // highlight-end\n }\n ],\n "permissions": [\n {\n // highlight-start\n "path": "/var/lib/opensearch",\n "owner": "opensearch:opensearch",\n "recurse": true\n // highlight-end\n },\n {\n // highlight-start\n "path": "/var/log/kolla/opensearch",\n "owner": "opensearch:opensearch",\n "recurse": true\n // highlight-end\n }\n ]\n}\n'})}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["\n",(0,l.jsxs)(n.p,{children:["In the ",(0,l.jsx)(n.code,{children:"config.json"})," of the service is also defined the command which will be executed after finishing the preparations.\nIn the case of OpenSearch this is ",(0,l.jsx)(n.code,{children:"/usr/share/opensearch/bin/opensearch"}),"."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-json",metastring:'title="/etc/kolla/opensearch/config.json"',children:'{\n // highlight-start\n "command": "/usr/share/opensearch/bin/opensearch",\n // highlight-end\n "config_files": [\n {\n "source": "/var/lib/kolla/config_files/opensearch.yml",\n "dest": "/etc/opensearch/opensearch.yml",\n "owner": "opensearch",\n "perm": "0600"\n }\n ],\n "permissions": [\n {\n "path": "/var/lib/opensearch",\n "owner": "opensearch:opensearch",\n "recurse": true\n },\n {\n "path": "/var/log/kolla/opensearch",\n "owner": "opensearch:opensearch",\n "recurse": true\n }\n ]\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"number-of-service-workers",children:"Number of service workers"}),"\n",(0,l.jsx)(n.p,{children:"The number of workers used for the individual services can generally be configured using two parameters."}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:'openstack_service_workers: "{{ [ansible_facts.processor_vcpus, 5] | min }}"\nopenstack_service_rpc_workers: "{{ [ansible_facts.processor_vcpus, 3] | min }}\u201c\n'})}),"\n",(0,l.jsxs)(n.p,{children:["The default for ",(0,l.jsx)(n.code,{children:"openstack_service_workers"})," is set to ",(0,l.jsx)(n.code,{children:"5"})," when using the cookiecutter for the initial creation\nof the configuration."]}),"\n",(0,l.jsxs)(n.p,{children:["This value can be overwritten for individual services. The default for all parameters in the following table is\n",(0,l.jsx)(n.code,{children:"{{ openstack_service_workers }}"}),". The parameter ",(0,l.jsx)(n.code,{children:"aodh_api_workers"})," can then be used to explicitly set the\nnumber of workers for the AODH API, for example. A reconfigure must be made for the particular services in the\ncase of a change. ",(0,l.jsx)(n.code,{children:"osism apply -a reconfigure aodh"})," in this example."]}),"\n",(0,l.jsxs)(n.p,{children:["These parameters are all set in ",(0,l.jsx)(n.code,{children:"environments/kolla/configuration.yml"}),"."]}),"\n",(0,l.jsxs)(n.table,{children:[(0,l.jsx)(n.thead,{children:(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"})})}),(0,l.jsxs)(n.tbody,{children:[(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"aodh_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"barbican_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"cinder_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"designate_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"designate_worker_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"designate_producer_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"designate_central_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"designate_sink_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"designate_mdns_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"glance_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"gnocchi_metricd_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"gnocchi_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"heat_api_cfn_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"heat_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"heat_engine_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"horizon_wsgi_processes"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"ironic_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"keystone_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"proxysql_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"magnum_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"magnum_conductor_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"manila_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"neutron_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"neutron_metadata_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"nova_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"nova_superconductor_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"nova_metadata_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"nova_scheduler_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"nova_cell_conductor_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"octavia_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"octavia_healthmanager_health_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"octavia_healthmanager_stats_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"placement_api_workers"})}),(0,l.jsx)(n.tr,{children:(0,l.jsx)(n.td,{style:{textAlign:"left"},children:"skyline_gunicorn_workers"})})]})]}),"\n",(0,l.jsx)(n.h2,{id:"back-end-tls-configuration",children:"Back-end TLS configuration"})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var i=t(96540);const l={},s=i.createContext(l);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d14d7097.b01d73d7.js b/assets/js/d14d7097.b01d73d7.js new file mode 100644 index 0000000000..a0d54375fc --- /dev/null +++ b/assets/js/d14d7097.b01d73d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[37919],{64148:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>a,metadata:()=>o,toc:()=>u});const o=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/neutron","title":"Neutron","description":"Quality of Service (QoS)","source":"@site/docs/02-iaas/guides/operations-guide/openstack/neutron.md","sourceDirName":"02-iaas/guides/operations-guide/openstack","slug":"/iaas/guides/operations-guide/openstack/neutron","permalink":"/docs/iaas/guides/operations-guide/openstack/neutron","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/neutron.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Neutron"},"sidebar":"docs","previous":{"title":"Keystone","permalink":"/docs/iaas/guides/operations-guide/openstack/keystone"},"next":{"title":"Nova","permalink":"/docs/iaas/guides/operations-guide/openstack/nova"}}');var s=n(74848),i=n(28453);const a={sidebar_label:"Neutron"},r="Neutron",c={},u=[{value:"Quality of Service (QoS)",id:"quality-of-service-qos",level:2}];function d(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"neutron",children:"Neutron"})}),"\n",(0,s.jsx)(t.h2,{id:"quality-of-service-qos",children:"Quality of Service (QoS)"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://docs.openstack.org/neutron/latest/admin/config-qos.html",children:"https://docs.openstack.org/neutron/latest/admin/config-qos.html"})}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var o=n(96540);const s={},i=o.createContext(s);function a(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d1aa920e.94404ca3.js b/assets/js/d1aa920e.94404ca3.js new file mode 100644 index 0000000000..f066f9c630 --- /dev/null +++ b/assets/js/d1aa920e.94404ca3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[53920],{42265:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/index","title":"OpenStack","description":"Create an external network","source":"@site/docs/02-iaas/guides/operations-guide/openstack/index.md","sourceDirName":"02-iaas/guides/operations-guide/openstack","slug":"/iaas/guides/operations-guide/openstack/","permalink":"/docs/iaas/guides/operations-guide/openstack/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/index.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"OpenStack"},"sidebar":"docs","previous":{"title":"Network","permalink":"/docs/iaas/guides/operations-guide/network"},"next":{"title":"Tools","permalink":"/docs/iaas/guides/operations-guide/openstack/tools/"}}');var o=s(74848),i=s(28453);const r={sidebar_label:"OpenStack"},l="OpenStack",c={},d=[{value:"Create an external network",id:"create-an-external-network",level:2},{value:"Reboot a compute node",id:"reboot-a-compute-node",level:2},{value:"Add a new compute node",id:"add-a-new-compute-node",level:2},{value:"Remove a compute node",id:"remove-a-compute-node",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"openstack",children:"OpenStack"})}),"\n",(0,o.jsx)(n.h2,{id:"create-an-external-network",children:"Create an external network"}),"\n",(0,o.jsxs)(n.p,{children:["The play ",(0,o.jsx)(n.code,{children:"network-external"})," is available and usable as of OSISM 7.0.6."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply network-external\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Available parameters for the OpenStack Environment (",(0,o.jsx)(n.code,{children:"environments/openstack/configuration.yml"}),")."]}),"\n",(0,o.jsxs)(n.table,{children:[(0,o.jsx)(n.thead,{children:(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,o.jsx)(n.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,o.jsxs)(n.tbody,{children:[(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_allocation_pool_end"}),(0,o.jsx)(n.td,{style:{textAlign:"left"},children:'"192.168.112.200"'})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_allocation_pool_start"}),(0,o.jsx)(n.td,{style:{textAlign:"left"},children:'"192.168.112.100"'})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_cidr"}),(0,o.jsx)(n.td,{style:{textAlign:"left"},children:'"192.168.112.0/20"'})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_cloud"}),(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"admin"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_gateway_ip"}),(0,o.jsx)(n.td,{style:{textAlign:"left"},children:'"192.168.112.5"'})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_name"}),(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"public"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_provider_network_type"}),(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"flat"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_provider_physical_network"}),(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"physnet1"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_state"}),(0,o.jsx)(n.td,{style:{textAlign:"left"},children:"present"})]})]})]}),"\n",(0,o.jsx)(n.h2,{id:"reboot-a-compute-node",children:"Reboot a compute node"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Live migrate all instances running on the compute node\nwith the help of the ",(0,o.jsx)(n.a,{href:"./tools/resource-manager#live-migration",children:"OpenStack Resource Manager"})]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Ensure that no more instances are running on the compute node"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ps ax | grep qemu\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Reboot the compute node"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply reboot -l NODE -e ireallymeanit=yes\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Wait for the compute node to reboot"}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Re-enable the compute service"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'openstack --os-cloud admin compute service set --enable --disable-reason "" NODE nova-compute\n'})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Check compute service"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack --os-cloud admin compute service list --host NODE --service nova-compute\n"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"add-a-new-compute-node",children:"Add a new compute node"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Add the operater user"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply operator -u osism -l NODE\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Run the bootstrap"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply bootstrap -l NODE\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"When a routed network fabric is used deploy the FRR service (optional)"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply frr -l NODE\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Deploy logging service and Prometheus exporters"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply common -l NODE\nosism apply prometheus -l NODE\nosism apply scaphandre -l NODE\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Deploy network services"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply openvswitch -l NODE\nosism apply ovn -l NODE\nosism apply neutron -l NODE\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If you do not use the OVN SDN skip ",(0,o.jsx)(n.code,{children:"osism apply ovn -l NODE"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Deploy compute services"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply nova -l NODE\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Deploy telemetry services (optional)"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply ceilometer -l NODE\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Deploy Netdata service (optional)"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply netdata -l NODE\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Add compute node to Prometheus monitoring"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply prometheus -l monitoring\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Refresh the ",(0,o.jsx)(n.code,{children:"/etc/hosts"})," file"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply hosts\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Refresh the SSH client configuration file"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply sshconfig\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Add compute node to the known hosts file"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply known-hosts\n"})}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Containers that run on a compute node. Versions may differ. There is no ",(0,o.jsx)(n.code,{children:"ceilometer_compute"})," container\nif you have not deployed the optional OpenStack telemetry service."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'$ docker ps\nCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n559e5176695c quay.io/osism/nova-compute:27.1.1.20230919 "dumb-init --single-\u2026" 5 minutes ago Up 5 minutes (healthy) nova_compute\n31248d71ab7d quay.io/osism/nova-libvirt:8.0.0.20230919 "dumb-init --single-\u2026" 6 minutes ago Up 6 minutes (healthy) nova_libvirt\n9292030d706c quay.io/osism/nova-ssh:27.1.1.20230919 "dumb-init --single-\u2026" 6 minutes ago Up 6 minutes (healthy) nova_ssh\nfda4b6fb30c8 quay.io/osism/neutron-metadata-agent:22.0.3.20230919 "dumb-init --single-\u2026" 2 hours ago Up 2 hours (healthy) neutron_ovn_metadata_agent\n0e3ec450b668 quay.io/osism/ceilometer-compute:20.0.1.20230919 "dumb-init --single-\u2026" 6 hours ago Up 6 hours (healthy) ceilometer_compute\n25ff9702e0e5 quay.io/osism/prometheus-libvirt-exporter:6.0.0.20230919 "dumb-init --single-\u2026" 6 hours ago Up 6 hours prometheus_libvirt_exporter\n1bff2e29923b quay.io/osism/prometheus-cadvisor:0.45.0.20230919 "dumb-init --single-\u2026" 6 hours ago Up 6 hours prometheus_cadvisor\n602832daf237 quay.io/osism/prometheus-node-exporter:1.4.0.20230919 "dumb-init --single-\u2026" 6 hours ago Up 6 hours prometheus_node_exporter\nd4de2f32cdf8 quay.io/osism/ovn-controller:23.6.1.20230919 "dumb-init --single-\u2026" 6 hours ago Up 6 hours ovn_controller\n3bf43ae5a94f quay.io/osism/openvswitch-vswitchd:3.1.2.20230919 "dumb-init --single-\u2026" 7 hours ago Up 7 hours (healthy) openvswitch_vswitchd\nebc048b02ab2 quay.io/osism/openvswitch-db-server:3.1.2.20230919 "dumb-init --single-\u2026" 7 hours ago Up 7 hours (healthy) openvswitch_db\n4f33dfa66c14 hubblo/scaphandre:0.5.0 "scaphandre promethe\u2026" 7 hours ago Up 7 hours 10.10.129.64:9155->8080/tcp scaphandre\n9b1f6342dc60 quay.io/osism/cron:3.0.20230919 "dumb-init --single-\u2026" 7 hours ago Up 7 hours cron\n718aecaddde1 quay.io/osism/kolla-toolbox:16.1.1.20230919 "dumb-init --single-\u2026" 7 hours ago Up 7 hours kolla_toolbox\nf6f9422c1853 quay.io/osism/fluentd:4.5.1.20230919 "dumb-init --single-\u2026" 7 hours ago Up 7 hours fluentd\n'})}),"\n",(0,o.jsx)(n.h2,{id:"remove-a-compute-node",children:"Remove a compute node"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["In the configuration repository remove the compute node everywhere. Then update the configuration\nrepository on the manager with ",(0,o.jsx)(n.code,{children:"osism apply configuration"})]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Live migrate all instances running on the compute node\nwith the help of the ",(0,o.jsx)(n.a,{href:"./tools/resource-manager#live-migration",children:"OpenStack Resource Manager"})]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Evacuate all instances on the compute node\nwith the help of the ",(0,o.jsx)(n.a,{href:"./tools/resource-manager#evacutation",children:"OpenStack Resource Manager"})]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Ensure that no more instances are running on the compute node"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ps ax | grep qemu\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Stop all OpenStack compute services on the compute node"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"systemctl stop kolla-nova_ssh-container.service\nsystemctl stop kolla-nova_libvirt-container.service\nsystemctl stop kolla-nova_compute-container.service\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Delete the compute service"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ openstack --os-cloud admin compute service list --host NODE\n+--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+\n| ID | Binary | Host | Zone | Status | State | Updated At |\n+--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+\n| 90345eb5-cf2f-47ef-becc-758ee36fb132 | nova-compute | NODE | nova | enabled | down | 2023-12-21T11:53:00.000000 |\n+--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ openstack --os-cloud admin compute service delete 90345eb5-cf2f-47ef-becc-758ee36fb132\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Stop all OpenStack network services on the compute node"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"systemctl stop kolla-neutron_ovn_metadata_agent-container.service\nsystemctl stop kolla-ovn_controller-container.service\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Delete the network services"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ openstack --os-cloud admin network agent list --host NODE\n+--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+\n| ID | Agent Type | Host | Availability Zone | Alive | State | Binary |\n+--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+\n| 0a5708ea-ba8b-5fde-8187-c6b24d3cf5ed | OVN Metadata agent | NODE | | :-) | UP | neutron-ovn-metadata-agent |\n| NODE | OVN Controller agent | NODE | | :-) | UP | ovn-controller |\n+--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+\n\n$ openstack --os-cloud admin network agent delete 0a5708ea-ba8b-5fde-8187-c6b24d3cf5ed\n$ openstack --os-cloud admin network agent delete NODE\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Refresh the facts"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply facts\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Refresh the ",(0,o.jsx)(n.code,{children:"/etc/hosts"})," file"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply hosts\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Refresh the SSH client configuration file"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply sshconfig\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Remove compute node from Prometheus monitoring"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply prometheus -l monitoring\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Remove compute node from the known hosts file"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply known-hosts\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d1c3b532.739f0858.js b/assets/js/d1c3b532.739f0858.js new file mode 100644 index 0000000000..63eb78f579 --- /dev/null +++ b/assets/js/d1c3b532.739f0858.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[68992],{93384:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"iaas/guides/operations-guide/infrastructure","title":"Infrastructure","description":"Loadbalancer","source":"@site/docs/02-iaas/guides/operations-guide/infrastructure.md","sourceDirName":"02-iaas/guides/operations-guide","slug":"/iaas/guides/operations-guide/infrastructure","permalink":"/docs/iaas/guides/operations-guide/infrastructure","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/infrastructure.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Infrastructure"},"sidebar":"docs","previous":{"title":"Ceph","permalink":"/docs/iaas/guides/operations-guide/ceph"},"next":{"title":"Network","permalink":"/docs/iaas/guides/operations-guide/network"}}');var s=a(74848),l=a(28453);const o={sidebar_label:"Infrastructure"},i="Infrastructure",c={},d=[{value:"Loadbalancer",id:"loadbalancer",level:2},{value:"MariaDB",id:"mariadb",level:2},{value:"Backup",id:"backup",level:3},{value:"Restore",id:"restore",level:3},{value:"Recovery",id:"recovery",level:3},{value:"Create database & user",id:"create-database--user",level:3},{value:"Open Search",id:"open-search",level:2},{value:"Get all indices",id:"get-all-indices",level:3},{value:"Delete an index",id:"delete-an-index",level:3}];function t(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"infrastructure",children:"Infrastructure"})}),"\n",(0,s.jsx)(n.h2,{id:"loadbalancer",children:"Loadbalancer"}),"\n",(0,s.jsxs)(n.p,{children:["For the ",(0,s.jsx)(n.code,{children:"manage-loadbalancer"})," play to work, the internal control socket\nof the HAProxy service must be set to admin level. As of OSISM 7.0.6 this\nis the default. Before this, the parameter ",(0,s.jsx)(n.code,{children:"haproxy_socket_level_admin"})," must\nbe added to the configuration repository and then a reconfigure\n(",(0,s.jsx)(n.code,{children:"osism apply -a reconfigure loadbalancer"}),") must be done for the loadbalancer\nservice."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'haproxy_socket_level_admin: "yes"\n'})}),"\n",(0,s.jsx)(n.p,{children:"You can check in the HAProxy configuration whether the control socket is\nconfigured correctly."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",metastring:'title="/etc/kolla/haproxy/haproxy.cfg"',children:"global\n [...]\n stats socket /var/lib/kolla/haproxy/haproxy.sock group kolla mode 660 level admin\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Disable the host ",(0,s.jsx)(n.code,{children:"testbed-node-0"})," in all backends of the service ",(0,s.jsx)(n.code,{children:"keystone "})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply manage-loadbalancer \\\n -e manage_loadbalancer_action=disable \\\n -e manage_loadbalancer_service=keystone \\\n -e manage_loadbalancer_host=testbed-node-0\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Enable the host ",(0,s.jsx)(n.code,{children:"testbed-node-0"})," in all backends of the service ",(0,s.jsx)(n.code,{children:"keystone "})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply manage-loadbalancer \\\n -e manage_loadbalancer_action=enable \\\n -e manage_loadbalancer_service=keystone \\\n -e manage_loadbalancer_host=testbed-node-0\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Disable the host ",(0,s.jsx)(n.code,{children:"testbed-node-0"})," in all backends"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply manage-loadbalancer \\\n -e manage_loadbalancer_action=disable \\\n -e manage_loadbalancer_service=all \\\n -e manage_loadbalancer_host=testbed-node-0\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Enable the host ",(0,s.jsx)(n.code,{children:"testbed-node-0"})," in all backends"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply manage-loadbalancer \\\n -e manage_loadbalancer_action=enable \\\n -e manage_loadbalancer_service=all \\\n -e manage_loadbalancer_host=testbed-node-0\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"mariadb",children:"MariaDB"}),"\n",(0,s.jsx)(n.h3,{id:"backup",children:"Backup"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://mariadb.com/kb/en/mariabackup-overview/",children:"Mariabackup"})," is used to create backups\nof MariaDB. For more details about backups, you can use the offical\n",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/kolla-ansible/latest/admin/mariadb-backup-and-restore.html",children:"kolla-ansible"})," documentation."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Create a full backup"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply mariadb_backup\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Create a incremental backup (supported as of OSISM 7.0.6)"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply mariadb_backup -e mariadb_backup_type=incremental\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Accessing created backups"}),"\n",(0,s.jsxs)(n.p,{children:["There is a Docker volume ",(0,s.jsx)(n.code,{children:"mariadb_backup"})," on the 1st control node. The backups\nare stored in this volume.\n(see also /var/lib/docker/volumes/mariadb_backup/)"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ docker run --rm -v mariadb_backup:/backup -it ubuntu:22.04 bash -c 'ls -la /backup'\ntotal 9728\ndrwxr-xr-x 2 42434 42434 4096 Jun 3 18:46 .\ndrwxr-xr-x 1 root root 4096 Jun 3 18:47 ..\n-rw-r--r-- 1 42434 42434 4530618 Jun 3 18:46 incremental-18-mysqlbackup-03-06-2024-1717440409.qp.xbc.xbs.gz\n-rw-r--r-- 1 42434 42434 11 Jun 3 18:45 last_full_date\n-rw-r--r-- 1 42434 42434 5411763 Jun 3 18:45 mysqlbackup-03-06-2024-1717440342.qp.xbc.xbs.gz\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Currently there is no offical scheduling and houskeeping (disk space) for mariadb backups.\nYou can create a simple cronjob on the manager or use your enterprise backup software."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"cat /etc/cron.d/mariadb_backup <<'EOF'\n0 7 * * * dragon osism apply mariadb_backup |logger -t mariadb_backup\nEOF\n"})}),"\n",(0,s.jsx)(n.h3,{id:"restore",children:"Restore"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Stop all MariaDb Instances"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply -s stop maria\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Follow the ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/kolla-ansible/latest/admin/mariadb-backup-and-restore.html#restoring-backups",children:"restore procedure described in the kolla-ansible manual"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Execute the recovery procedure with the node name where you executed the recovery"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply mariadb_recovery -e mariadb_recover_inventory_name=THE_NAME_OF_THE_RESTORE_NODE\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"recovery",children:"Recovery"}),"\n",(0,s.jsx)(n.p,{children:"If you stopped your mariadb galera cluster completly, you can use the following procedure\nto start a recovery."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply mariadb_recovery\n"})}),"\n",(0,s.jsx)(n.h3,{id:"create-database--user",children:"Create database & user"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Create a custom play ",(0,s.jsx)(n.code,{children:"playbook-database-sample.yml"})," in ",(0,s.jsx)(n.code,{children:"environments/kolla"})," in\nthe configuration repository."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'---\n- name: Manage sample database\n hosts: control\n\n vars:\n database_sample_username: sample\n database_sample_name: sample\n\n tasks:\n - name: Create sample database\n become: true\n kolla_toolbox:\n container_engine: "{{ kolla_container_engine }}"\n module_name: mysql_db\n module_args:\n login_host: "{{ database_address }}"\n login_port: "{{ database_port }}"\n login_user: "root"\n login_password: "{{ database_password }}"\n name: "{{ database_sample_name }}"\n run_once: true\n\n - name: Create sample user\n become: true\n kolla_toolbox:\n container_engine: "{{ kolla_container_engine }}"\n module_name: mysql_user\n module_args:\n login_host: "{{ api_interface_address }}"\n login_port: "{{ mariadb_port }}"\n login_user: "root"\n login_password: "{{ database_password }}"\n name: "{{ database_sample_username }}"\n password: "{{ database_sample_password }}"\n host: "%"\n priv: "{{ database_sample_name }}.*:ALL"\n append_privs: True\n run_once: true\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Add secret ",(0,s.jsx)(n.code,{children:"database_sample_password"})," in ",(0,s.jsx)(n.code,{children:"environments/kolla/secrets.yml"})," in the\nconfiguration repository."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Commit the custom play and the secret. Sync the configuration on the manager\nnode with ",(0,s.jsx)(n.code,{children:"osism apply configuration"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run ",(0,s.jsx)(n.code,{children:"osism apply xxx"})," on the manager node."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"open-search",children:"Open Search"}),"\n",(0,s.jsx)(n.h3,{id:"get-all-indices",children:"Get all indices"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ curl https://api-int.testbed.osism.xyz:9200/_cat/indices?v\nhealth status index uuid pri rep docs.count docs.deleted store.size pri.store.size\ngreen open flog-2024.04.17 1rCP3NpUQSS5wmulCn6Y5g 1 1 1657832 0 1gb 654.4mb\ngreen open .opensearch-observability UnS2gFb-QhC8oIefL3C52Q 1 2 0 0 624b 208b\ngreen open .plugins-ml-config hMdzW6ooRMGZ_0OGcdNSgA 1 1 1 0 7.8kb 3.9kb\ngreen open .opendistro-job-scheduler-lock fa_Io8bJQ8qfGII4DypxFg 1 1 1 3 51.1kb 35.1kb\ngreen open .kibana_1 v-aJ6ioSQsOwHQn_NNbeOg 1 1 0 0 416b 208b\n"})}),"\n",(0,s.jsx)(n.h3,{id:"delete-an-index",children:"Delete an index"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'$ curl -X DELETE https://api-int.testbed.osism.xyz:9200/flog-2024.04.17\n{"acknowledged":true}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(t,{...e})}):t(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>o,x:()=>i});var r=a(96540);const s={},l=r.createContext(s);function o(e){const n=r.useContext(l);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d2436a2b.5bb66ee4.js b/assets/js/d2436a2b.5bb66ee4.js new file mode 100644 index 0000000000..978492ecac --- /dev/null +++ b/assets/js/d2436a2b.5bb66ee4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[60837],{19112:e=>{e.exports=JSON.parse('{"version":{"pluginId":"community","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"community":[{"type":"link","label":"Overview","href":"/community/","docId":"index","unlisted":false},{"type":"link","label":"Mission Statement","href":"/community/mission-statement","docId":"mission-statement","unlisted":false},{"type":"link","label":"License considerations for SCS","href":"/community/license-considerations","docId":"license-considerations","unlisted":false},{"type":"category","label":"Collaboration","items":[{"type":"link","label":"Team Iaas","href":"/community/collaboration/team-iaas","docId":"collaboration/team-iaas","unlisted":false},{"type":"link","label":"Team IAM","href":"/community/collaboration/team-iam","docId":"collaboration/team-iam","unlisted":false},{"type":"link","label":"Team Container","href":"/community/collaboration/team-container","docId":"collaboration/team-container","unlisted":false},{"type":"link","label":"Team Ops","href":"/community/collaboration/team-ops","docId":"collaboration/team-ops","unlisted":false},{"type":"link","label":"SIG Central API","href":"/community/collaboration/sig-central-api","docId":"collaboration/sig-central-api","unlisted":false},{"type":"link","label":"SIG Community","href":"/community/collaboration/sig-community","docId":"collaboration/sig-community","unlisted":false},{"type":"link","label":"SIG Documentation","href":"/community/collaboration/sig-documentation","docId":"collaboration/sig-documentation","unlisted":false},{"type":"link","label":"SIG Monitoring","href":"/community/collaboration/sig-monitoring","docId":"collaboration/sig-monitoring","unlisted":false},{"type":"link","label":"SIG Standardization","href":"/community/collaboration/sig-standardization","docId":"collaboration/sig-standardization","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/community/collaboration/"},{"type":"category","label":"Tools","items":[{"type":"link","label":"Jitsi","href":"/community/tools/jitsi","docId":"tools/jitsi","unlisted":false},{"type":"link","label":"Matrix","href":"/community/tools/matrix","docId":"tools/matrix","unlisted":false},{"type":"link","label":"Mailing Lists","href":"/community/tools/mailinglists","docId":"tools/mailinglists","unlisted":false},{"type":"link","label":"Nextcloud","href":"/community/tools/nextcloud","docId":"tools/nextcloud","unlisted":false},{"type":"link","label":"Zuul","href":"/community/tools/zuul","docId":"tools/zuul","unlisted":false},{"type":"category","label":"GitHub","items":[{"type":"link","label":"Branch Protection Rules","href":"/community/tools/github/branchprotection","docId":"tools/github/branchprotection","unlisted":false},{"type":"link","label":"Developer Certificate of Origin + Licenses","href":"/community/tools/github/dco-and-licenses","docId":"tools/github/dco-and-licenses","unlisted":false},{"type":"link","label":"Tips and Tricks","href":"/community/tools/github/tips-and-tricks","docId":"tools/github/tips-and-tricks","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Cloud Resources","items":[{"type":"link","label":"Test and development cloud resources","href":"/community/cloud-resources/","docId":"cloud-resources/cloud-resources","unlisted":false},{"type":"link","label":"Getting Started with OpenStack","href":"/community/cloud-resources/getting-started-openstack","docId":"cloud-resources/getting-started-openstack","unlisted":false},{"type":"link","label":"Getting Started Gaia-X Demonstrator @ plusserver","href":"/community/cloud-resources/plusserver-gx-scs","docId":"cloud-resources/plusserver-gx-scs","unlisted":false},{"type":"link","label":"Getting Started with Wavestack","href":"/community/cloud-resources/wavestack","docId":"cloud-resources/wavestack","unlisted":false}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true,"href":"/community/category/tools"},{"type":"category","label":"Contribute to Docs","items":[{"type":"link","label":"Adding Docs Guide","href":"/community/contribute/adding-docs-guide","docId":"contribute/adding-docs-guide","unlisted":false},{"type":"link","label":"Documentation Files Structure","href":"/community/contribute/doc-files-structure-guide","docId":"contribute/doc-files-structure-guide","unlisted":false},{"type":"link","label":"Documentation workflow explanation","href":"/community/contribute/docs-workflow-explanation","docId":"contribute/docs-workflow-explanation","unlisted":false},{"type":"link","label":"Linting Guide","href":"/community/contribute/linting-guide","docId":"contribute/linting-guide","unlisted":false},{"type":"link","label":"Installation","href":"/community/contribute/local-docusaurus-development-guide","docId":"contribute/local-docusaurus-development-guide","unlisted":false},{"type":"link","label":"Styleguide","href":"/community/contribute/styleguide","docId":"contribute/styleguide","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/community/category/contribute-to-docs"}]},"docs":{"central-services/plusserver-gx-scs":{"id":"central-services/plusserver-gx-scs","title":"Central services","description":"This document gives an overview of what SCS central services are deployed and who is responsible for them in plusserver gx-scs infrastructure."},"cloud-resources/cloud-resources":{"id":"cloud-resources/cloud-resources","title":"Test and development cloud resources","description":"This document gives an overview of the test and development cloud resources currently provided by our partners.","sidebar":"community"},"cloud-resources/getting-started-openstack":{"id":"cloud-resources/getting-started-openstack","title":"Getting Started with OpenStack","description":"Getting Started with OpenStack CLI","sidebar":"community"},"cloud-resources/plusserver-gx-scs":{"id":"cloud-resources/plusserver-gx-scs","title":"Getting Started Gaia-X Demonstrator @ plusserver","description":"Getting Started for the Gaia-X Demonstrator @ plusserver","sidebar":"community"},"cloud-resources/wavestack":{"id":"cloud-resources/wavestack","title":"Getting Started with Wavestack","description":"Getting Started with Wavestack","sidebar":"community"},"collaboration/index":{"id":"collaboration/index","title":"Collaboration","description":"We\u2019re an open community","sidebar":"community"},"collaboration/sig-central-api":{"id":"collaboration/sig-central-api","title":"SIG Central API","description":"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.","sidebar":"community"},"collaboration/sig-community":{"id":"collaboration/sig-community","title":"SIG Community","description":"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!","sidebar":"community"},"collaboration/sig-documentation":{"id":"collaboration/sig-documentation","title":"SIG Documentation","description":"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.","sidebar":"community"},"collaboration/sig-monitoring":{"id":"collaboration/sig-monitoring","title":"SIG Monitoring","description":"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.","sidebar":"community"},"collaboration/sig-standardization":{"id":"collaboration/sig-standardization","title":"SIG Standardization","description":"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.","sidebar":"community"},"collaboration/team-container":{"id":"collaboration/team-container","title":"Team Container","description":"The Team Container deals with all topics around Containers and Kubernetes.","sidebar":"community"},"collaboration/team-iaas":{"id":"collaboration/team-iaas","title":"Team Iaas","description":"We build the reference implementation of the IaaS parts of SCS that informs and adheres to the SCS IaaS standards.","sidebar":"community"},"collaboration/team-iam":{"id":"collaboration/team-iam","title":"Team IAM","description":"The Team IAM deals with topics around Identity and Access Management.","sidebar":"community"},"collaboration/team-ops":{"id":"collaboration/team-ops","title":"Team Ops","description":"We build tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.","sidebar":"community"},"contribute/adding-docs-guide":{"id":"contribute/adding-docs-guide","title":"Adding Docs Guide","description":"In this Guide you will learn how to integrate your documentation to the SCS documentation, which you will find on docs.scs.community.","sidebar":"community"},"contribute/doc-files-structure-guide":{"id":"contribute/doc-files-structure-guide","title":"Documentation Files Structure","description":"Structure Best Practice","sidebar":"community"},"contribute/docs-workflow-explanation":{"id":"contribute/docs-workflow-explanation","title":"Documentation workflow explanation","description":"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.","sidebar":"community"},"contribute/linting-guide":{"id":"contribute/linting-guide","title":"Linting Guide","description":"In order to have a clean content repository regarding all markdown files we enforce linting on:","sidebar":"community"},"contribute/local-docusaurus-development-guide":{"id":"contribute/local-docusaurus-development-guide","title":"Installation","description":"This Guide shows you how to setup docusaurus on your local machine to run this docs in your local development enviroment.","sidebar":"community"},"contribute/styleguide":{"id":"contribute/styleguide","title":"Styleguide","description":"Admonitions","sidebar":"community"},"contribute/styleguides/ansible_styleguide":{"id":"contribute/styleguides/ansible_styleguide","title":"Ansible Style Guide","description":"We use nearly all default rules of ansible lint. A listing of all these rules can be found in the Ansible Lint documentation:"},"hackathons/checklist":{"id":"hackathons/checklist","title":"Hackathon planning checklist","description":"This checklist is designed to simplify the planning of hackathons and meetups. All items are suggestions and optionally adaptable"},"index":{"id":"index","title":"Overview","description":"Welcome to our SCS Community","sidebar":"community"},"license-considerations":{"id":"license-considerations","title":"License considerations for SCS","description":"As Sovereign Cloud Stack (SCS), our mission is to provide Operators","sidebar":"community"},"mission-statement":{"id":"mission-statement","title":"Mission Statement","description":"Sovereign Cloud Stack (SCS) offers more than just a software stack \u2014 it\'s the embodiment of a collaborative open-source spirit, united by the aim of achieving digital sovereignty. At the heart of this initiative is a foundational pillar: the community.","sidebar":"community"},"tools/github/branchprotection":{"id":"tools/github/branchprotection","title":"Branch Protection Rules","description":"To protect our source code from unwanted changes, we enforce the following branch protection rules for all repositories within our GitHub organization:","sidebar":"community"},"tools/github/dco-and-licenses":{"id":"tools/github/dco-and-licenses","title":"Developer Certificate of Origin + Licenses","description":"The Developer Certificate of Origin (DCO) is a lightweight way for contributors","sidebar":"community"},"tools/github/tips-and-tricks":{"id":"tools/github/tips-and-tricks","title":"Tips and Tricks","description":"Octo Reminder - your friendly assistant","sidebar":"community"},"tools/jitsi":{"id":"tools/jitsi","title":"Jitsi","description":"We use a self-hosted Jitsi Meet instance for video conferencing.","sidebar":"community"},"tools/mailinglists":{"id":"tools/mailinglists","title":"Mailing Lists","description":"We have an announcements mailing list there announce@lists.scs.community and you","sidebar":"community"},"tools/matrix":{"id":"tools/matrix","title":"Matrix","description":"We have created an open community space on the Matrix federation. Feel free to join the several channels and start chatting with our community. A good starting point is entering the General & Announcements and the Tech channel.","sidebar":"community"},"tools/nextcloud":{"id":"tools/nextcloud","title":"Nextcloud","description":"We have a Nextcloud","sidebar":"community"},"tools/zuul":{"id":"tools/zuul","title":"Zuul","description":"Zuul CI/CD pipelines and project gating","sidebar":"community"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/d341f8b3.ff4aa669.js b/assets/js/d341f8b3.ff4aa669.js new file mode 100644 index 0000000000..4e6feb6c60 --- /dev/null +++ b/assets/js/d341f8b3.ff4aa669.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[24170],{21266:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>d,metadata:()=>n,toc:()=>a});const n=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","title":"Configuration","description":"This page lists the custom configuration options available, including their default values and if they are optional. The following example shows how these variables can be used inside the cluster.yaml file under spec.topology.variables.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stacks/providers/openstack","slug":"/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","permalink":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Quickstart","permalink":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart"},"next":{"title":"Container Registry","permalink":"/docs/category/container-registry"}}');var t=r(74848),i=r(28453);const d={},l="Configuration",c={},a=[{value:"Example",id:"example",level:2},{value:"Available variables",id:"available-variables",level:2}];function o(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"configuration",children:"Configuration"})}),"\n",(0,t.jsxs)(s.p,{children:["This page lists the custom configuration options available, including their default values and if they are optional. The following example shows how these variables can be used inside the ",(0,t.jsx)(s.code,{children:"cluster.yaml"})," file under ",(0,t.jsx)(s.code,{children:"spec.topology.variables"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-yaml",children:'apiVersion: cluster.x-k8s.io/v1beta1\nkind: Cluster\nmetadata:\n name:\n namespace:\n labels:\n managed-secret: cloud-config\nspec:\n clusterNetwork:\n pods:\n cidrBlocks:\n - 192.168.0.0/16\n serviceDomain: cluster.local\n services:\n cidrBlocks:\n - 10.96.0.0/12\n topology:\n variables: // <-- variables from the table can be set here\n - name: controller_flavor\n value: "SCS-4V-8-20"\n - name: worker_flavor\n value: "SCS-4V-8-20"\n - name: external_id\n value: "ebfe5546-f09f-4f42-ab54-094e457d42ec"\n class: openstack-alpha-1-29-v2\n controlPlane:\n replicas: 2\n version: v1.29.3\n workers:\n machineDeployments:\n - class: openstack-alpha-1-29-v2\n failureDomain: nova\n name: openstack-alpha-1-29-v2\n replicas: 4\n'})}),"\n",(0,t.jsxs)(s.p,{children:["Variables from the table containing a ",(0,t.jsx)(s.code,{children:"."})," are to be used in an object with the part before the dot being the object name and the part behind the dot being the value names. The following example demonstrates this with ",(0,t.jsx)(s.code,{children:"oidc_config"}),"."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-yaml",children:'...\ntopology:\n variables:\n - name: oidc_config\n value:\n issuer_url: "https://dex.k8s.scs.community"\n client_id: "kubectl"\n...\n'})}),"\n",(0,t.jsx)(s.h2,{id:"available-variables",children:"Available variables"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Name"}),(0,t.jsx)(s.th,{children:"Type"}),(0,t.jsx)(s.th,{children:"Default"}),(0,t.jsx)(s.th,{children:"Example"}),(0,t.jsx)(s.th,{children:"Description"}),(0,t.jsx)(s.th,{children:"Required"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"external_id"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'""'}),(0,t.jsx)(s.td,{children:'"ebfe5546-f09f-4f42-ab54-094e457d42ec"'}),(0,t.jsx)(s.td,{children:"ExternalNetworkID is the ID of an external OpenStack Network. This is necessary to get public internet to the VMs."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"controller_flavor"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'"SCS-2V-4-20s"'}),(0,t.jsx)(s.td,{children:'"SCS-2V-4-20s"'}),(0,t.jsx)(s.td,{children:"OpenStack instance flavor for control-plane nodes."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"worker_flavor"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'"SCS-2V-4"'}),(0,t.jsx)(s.td,{children:'"SCS-2V-4"'}),(0,t.jsx)(s.td,{children:"OpenStack instance flavor for worker nodes."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"controller_root_disk"})}),(0,t.jsx)(s.td,{children:"integer"}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"25"}),(0,t.jsx)(s.td,{children:"Root disk size in GiB for control-plane nodes. OpenStack volume will be created and used instead of an ephemeral disk defined in flavor. Should only be used for the diskless flavors."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"worker_root_disk"})}),(0,t.jsx)(s.td,{children:"integer"}),(0,t.jsx)(s.td,{children:"25"}),(0,t.jsx)(s.td,{children:"25"}),(0,t.jsx)(s.td,{children:"Root disk size in GiB for worker nodes. OpenStack volume will be created and used instead of an ephemeral disk defined in flavor. Should be used for the diskless flavors."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"yawol_flavor_id"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'""'}),(0,t.jsx)(s.td,{children:'"0a79590e-10d7-4c2c-8f69-ca0a2c6208d2"'}),(0,t.jsx)(s.td,{children:"ID of the existing flavor used as a default yawol flavor."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"yawol_image_id"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'""'}),(0,t.jsx)(s.td,{children:'"f0b2ef46-f0ff-43d2-9c08-f58a5a6e9060"'}),(0,t.jsx)(s.td,{children:"ID of the existing imaged used as a default yawol image."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"kube_vip_network_id"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'""'}),(0,t.jsx)(s.td,{children:'"40a51f6c-9e4b-4b24-9187-49851a410c97"'}),(0,t.jsx)(s.td,{children:"ID of the existing network. The network should have one subnet with one port reserved as virtual IP."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"kube_vip_apiserver_virtual_ip"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'""'}),(0,t.jsx)(s.td,{children:'"10.0.0.197"'}),(0,t.jsx)(s.td,{children:"Virtual IP address reserved in kube_vip_network_id."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"kube_vip_apiserver_public_ip"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'""'}),(0,t.jsx)(s.td,{children:'""'}),(0,t.jsx)(s.td,{children:"Public IP address associated with kube_vip_apiserver_virtual_ip. It is needed only when the management cluster is on a different network as a workload cluster."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"openstack_security_groups"})}),(0,t.jsx)(s.td,{children:"array"}),(0,t.jsx)(s.td,{children:"[]"}),(0,t.jsx)(s.td,{children:"['security-group-1']"}),(0,t.jsx)(s.td,{children:"The names of the security groups to assign to the instance"}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"cloud_name"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'"openstack"'}),(0,t.jsx)(s.td,{children:'"openstack"'}),(0,t.jsx)(s.td,{children:"The name of the cloud to use from the clouds secret"}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"secret_name"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'"openstack"'}),(0,t.jsx)(s.td,{children:'"openstack"'}),(0,t.jsx)(s.td,{children:"The name of the clouds secret"}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"controller_server_group_id"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'""'}),(0,t.jsx)(s.td,{children:'"3adf4e92-bb33-4e44-8ad3-afda9dfe8ec3"'}),(0,t.jsx)(s.td,{children:"The server group to assign the control plane nodes to."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"worker_server_group_id"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'""'}),(0,t.jsx)(s.td,{children:'"869fe071-1e56-46a9-9166-47c9f228e297"'}),(0,t.jsx)(s.td,{children:"The server group to assign the worker nodes to."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"ssh_key"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'""'}),(0,t.jsx)(s.td,{children:'"capi-keypair"'}),(0,t.jsx)(s.td,{children:"The ssh key to inject in the nodes."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"apiserver_loadbalancer"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'"octavia-amphora"'}),(0,t.jsx)(s.td,{children:'"none, octavia-amphora, octavia-ovn, kube-vip"'}),(0,t.jsxs)(s.td,{children:['"In this cluster-stack we have two kind of loadbalancers. Each of them has its own configuration variable. This setting here is to configure the loadbalancer that is placed in front of the apiserver.',(0,t.jsx)("br",{}),"To configure the loadbalancer for the workloads, see variable workload_loadbalancer.",(0,t.jsx)("br",{}),"You can choose from 4 options:",(0,t.jsx)("br",{}),(0,t.jsx)("br",{}),"none:",(0,t.jsx)("br",{})," No loadbalancer solution will be deployed",(0,t.jsx)("br",{}),(0,t.jsx)("br",{}),"octavia-amphora:",(0,t.jsx)("br",{})," (default) Uses openstack's loadbalancer service (provider",":amphora",")",(0,t.jsx)("br",{}),(0,t.jsx)("br",{}),"octavia-ovn:",(0,t.jsx)("br",{})," Uses openstack's loadbalancer service (provider",":ovn",")",(0,t.jsx)("br",{}),(0,t.jsx)("br",{}),"kube-vip:",(0,t.jsx)("br",{})," Uses kube-vip as loadbalancer.",(0,t.jsx)("br",{})," You have to provide the following additional variables: ",(0,t.jsx)("br",{})," kube_vip_network_id",(0,t.jsx)("br",{})," kube_vip_apiserver_virtual_ip",(0,t.jsx)("br",{})," kube_vip_apiserver_public_ip ",(0,t.jsx)("br",{})," ",(0,t.jsx)("br",{})," Requires Kubernetes version < 1.29",(0,t.jsx)("br",{})," Also the settings node_cidr and dns_nameservers will no longer have an effect.",(0,t.jsx)("br",{})]}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"workload_loadbalancer"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'"octavia-amphora"'}),(0,t.jsx)(s.td,{children:'"none, octavia-amphora, octavia-ovn, yawol"'}),(0,t.jsxs)(s.td,{children:['"This setting here is to configure the loadbalancer solution for your services inside your cluster.',(0,t.jsx)("br",{}),"If you want to configure the loadbalancer in front of your apiserver, see variable apiserver_loadbalancer instead.",(0,t.jsx)("br",{}),"You can choose from 4 options:",(0,t.jsx)("br",{}),(0,t.jsx)("br",{}),"none:",(0,t.jsx)("br",{})," No loadbalancer solution will be deployed",(0,t.jsx)("br",{}),(0,t.jsx)("br",{}),"octavia-amphora:",(0,t.jsx)("br",{})," (default) Uses openstack's loadbalancer service (provider",":amphora",")",(0,t.jsx)("br",{}),(0,t.jsx)("br",{}),"octavia-ovn:",(0,t.jsx)("br",{})," Uses openstack's loadbalancer service (provider",":ovn",")",(0,t.jsx)("br",{}),(0,t.jsx)("br",{}),"yawol:",(0,t.jsx)("br",{})," Uses yawol as loadbalancer.",(0,t.jsx)("br",{})," You have to provide the following additional variables: ",(0,t.jsx)("br",{})," yawol_flavor_id",(0,t.jsx)("br",{})," yawol_image_id",(0,t.jsx)("br",{})," ",(0,t.jsx)("br",{}),' Also note this setting does not work with application credentials (only username/password)"',(0,t.jsx)("br",{})]}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"dns_nameservers"})}),(0,t.jsx)(s.td,{children:"array"}),(0,t.jsx)(s.td,{children:"['5.1.66.255', '185.150.99.255']"}),(0,t.jsx)(s.td,{children:"['5.1.66.255', '185.150.99.255']"}),(0,t.jsxs)(s.td,{children:['"DNSNameservers is the list of nameservers for the OpenStack Subnet being created. Set this value when you need to create a new network/subnet while the access through DNS is required.',(0,t.jsx)("br",{}),"This setting has no effect when apiserver_loadbalancer is set to kube-vip.",(0,t.jsx)("br",{}),'However you can set the dns server when creating the subnet for kube-vip."',(0,t.jsx)("br",{})]}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"node_cidr"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:'"10.8.0.0/20"'}),(0,t.jsx)(s.td,{children:'"10.8.0.0/20"'}),(0,t.jsxs)(s.td,{children:['"NodeCIDR is the OpenStack Subnet to be created. Cluster actuator will create a network, a subnet with NodeCIDR, and a router connected to this subnet. If you leave this empty, no network will be created.',(0,t.jsx)("br",{}),"This setting has no effect when apiserver_loadbalancer is set to kube-vip.",(0,t.jsx)("br",{}),'However you can set the node_cidr when creating the subnet for kube-vip."',(0,t.jsx)("br",{})]}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"certSANs"})}),(0,t.jsx)(s.td,{children:"array"}),(0,t.jsx)(s.td,{children:"[]"}),(0,t.jsx)(s.td,{children:"['mydomain.example']"}),(0,t.jsx)(s.td,{children:"CertSANs sets extra Subject Alternative Names for the API Server signing cert."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"oidc_config.client_id"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"kubectl"}),(0,t.jsx)(s.td,{children:"A client id that all tokens must be issued for."}),(0,t.jsx)(s.td,{})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"oidc_config.issuer_url"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.a,{href:"https://dex.k8s.scs.community",children:"https://dex.k8s.scs.community"})}),(0,t.jsx)(s.td,{children:"URL of the provider that allows the API server to dis cover public signing keys. Only URLs that use the https:// scheme are acc epted. This is typically the provider's discovery URL, changed to have an emp ty path"}),(0,t.jsx)(s.td,{})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"oidc_config.username_claim"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:"preferred_username"}),(0,t.jsx)(s.td,{children:"preferred_username"}),(0,t.jsx)(s.td,{children:"JWT claim to use as the user name. By default sub, whi ch is expected to be a unique identifier of the end user. Admins can choose oth er claims, such as email or name, depending on their provider. However, cla ims other than email will be prefixed with the issuer URL to prevent naming cla shes with other plugins."}),(0,t.jsx)(s.td,{})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"oidc_config.groups_claim"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:"groups"}),(0,t.jsx)(s.td,{children:"groups"}),(0,t.jsx)(s.td,{children:"JWT claim to use as the user's group. If the claim is present it must be an array of strings."}),(0,t.jsx)(s.td,{})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"oidc_config.username_prefix"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:"oidc:"}),(0,t.jsx)(s.td,{children:"oidc:"}),(0,t.jsxs)(s.td,{children:["Prefix prepended to username claims to prevent cla shes with existing names (such as system: users). For example, the value oid c: will create usernames like oidc",":jane",".doe. If this flag isn't provided and --o idc-username-claim is a value other than email the prefix defaults to ( Iss uer URL )# where ( Issuer URL ) is the value of --oidc-issuer-url. The value - c an be used to disable all prefixing."]}),(0,t.jsx)(s.td,{})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"oidc_config.groups_prefix"})}),(0,t.jsx)(s.td,{children:"string"}),(0,t.jsx)(s.td,{children:"oidc:"}),(0,t.jsx)(s.td,{children:"oidc:"}),(0,t.jsxs)(s.td,{children:["Prefix prepended to group claims to prevent clashes wit h existing names (such as system: groups). For example, the value oidc: will cre ate group names like oidc",":engineering"," and oidc",":infra","."]}),(0,t.jsx)(s.td,{})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"network_mtu"})}),(0,t.jsx)(s.td,{children:"integer"}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"1500"}),(0,t.jsx)(s.td,{children:"NetworkMTU sets the maximum transmission unit (MTU) value to address fragmentation for the private network ID."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"controlPlaneAvailabilityZones"})}),(0,t.jsx)(s.td,{children:"array"}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"['nova']"}),(0,t.jsx)(s.td,{children:"ControlPlaneAvailabilityZones is the set of availability zones which control plane machines may be deployed to."}),(0,t.jsx)(s.td,{children:"False"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"controlPlaneOmitAvailabilityZone"})}),(0,t.jsx)(s.td,{children:"boolean"}),(0,t.jsx)(s.td,{}),(0,t.jsx)(s.td,{children:"True"}),(0,t.jsx)(s.td,{children:"ControlPlaneOmitAvailabilityZone causes availability zone to be omitted when creating control plane nodes, allowing the Nova scheduler to make a decision on which availability zone to use based on other scheduling constraints."}),(0,t.jsx)(s.td,{children:"False"})]})]})]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>d,x:()=>l});var n=r(96540);const t={},i=n.createContext(t);function d(e){const s=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),n.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d35a3623.1db1366c.js b/assets/js/d35a3623.1db1366c.js new file mode 100644 index 0000000000..2c8cf1a033 --- /dev/null +++ b/assets/js/d35a3623.1db1366c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8655],{19176:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"iaas/guides/troubleshooting-guide/rookify","title":"Rookify (Technical Preview)","description":"Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime.","source":"@site/docs/02-iaas/guides/troubleshooting-guide/rookify.md","sourceDirName":"02-iaas/guides/troubleshooting-guide","slug":"/iaas/guides/troubleshooting-guide/rookify","permalink":"/docs/iaas/guides/troubleshooting-guide/rookify","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/troubleshooting-guide/rookify.md","tags":[],"version":"current","sidebarPosition":40,"frontMatter":{"sidebar_label":"Rookify (technical preview)","sidebar_position":40},"sidebar":"docs","previous":{"title":"OpenStack","permalink":"/docs/iaas/guides/troubleshooting-guide/openstack"},"next":{"title":"Ceph","permalink":"/docs/iaas/guides/troubleshooting-guide/ceph"}}');var s=n(74848),t=n(28453);const r={sidebar_label:"Rookify (technical preview)",sidebar_position:40},d="Rookify (Technical Preview)",a={},c=[{value:"SSH Issues",id:"ssh-issues",level:2},{value:"Frozen State",id:"frozen-state",level:2}];function l(e){const o={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.header,{children:(0,s.jsx)(o.h1,{id:"rookify-technical-preview",children:"Rookify (Technical Preview)"})}),"\n",(0,s.jsx)(o.admonition,{type:"warning",children:(0,s.jsxs)(o.p,{children:["Rookify is developed to migrate from Ceph-Ansible to Rook ",(0,s.jsx)(o.em,{children:"in place"})," and ",(0,s.jsx)(o.em,{children:"without downtime"}),".\nNevertheless, it is ",(0,s.jsx)(o.strong,{children:"strongly advised"})," to test Rookify in a controlled environment first, such as the ",(0,s.jsx)(o.a,{href:"https://github.com/osism/testbed",children:"OSISM testbed"}),". Additionally ensure that precautionary backups are made and all other necessary safety measures are in place."]})}),"\n",(0,s.jsxs)(o.p,{children:["For a condensed summary of the information covered here, refer to the ",(0,s.jsx)(o.a,{href:"https://github.com/SovereignCloudStack/rookify",children:"Rookify GitHub repository"}),"."]}),"\n",(0,s.jsx)(o.h2,{id:"ssh-issues",children:"SSH Issues"}),"\n",(0,s.jsx)(o.p,{children:(0,s.jsx)(o.strong,{children:'"Failed to load private key"'})}),"\n",(0,s.jsxs)(o.ul,{children:["\n",(0,s.jsxs)(o.li,{children:["Ensure the ",(0,s.jsx)(o.code,{children:"id-rsa"}),' keys are "clean" and do not contain unexpected strings like "<<EOF".']}),"\n",(0,s.jsxs)(o.li,{children:["Clean the keys manually, or use the following command to reformat the keyfile: ",(0,s.jsx)(o.code,{children:'ssh-keygen -p -N "" -f ssh.key'}),"."]}),"\n"]}),"\n",(0,s.jsx)(o.p,{children:(0,s.jsx)(o.strong,{children:'"Too many authentications error"'})}),"\n",(0,s.jsxs)(o.ul,{children:["\n",(0,s.jsx)(o.li,{children:"This can occur if too many keys are loaded by the ssh-agent."}),"\n",(0,s.jsxs)(o.li,{children:["Disable the ssh-agent on your machine. You can do this manually or by allowing ",(0,s.jsx)(o.code,{children:"direnv"})," to use ",(0,s.jsx)(o.code,{children:".envrc"})," with the command ",(0,s.jsx)(o.code,{children:"direnv allow"}),". To install ",(0,s.jsx)(o.code,{children:"direnv"})," on your machine refer to ",(0,s.jsx)(o.a,{href:"https://direnv.net/docs/installation.html",children:"Direnv's documentation"})]}),"\n"]}),"\n",(0,s.jsx)(o.h2,{id:"frozen-state",children:"Frozen State"}),"\n",(0,s.jsxs)(o.ul,{children:["\n",(0,s.jsx)(o.li,{children:"If the Rookify process freezes, check your connections."}),"\n",(0,s.jsxs)(o.li,{children:["In the OSISM testbed, ensure the VPN connection is active. For help to setup the VPN connection for the Testbed refer to ",(0,s.jsx)(o.a,{href:"https://osism.tech/docs/guides/other-guides/testbed/#vpn-access",children:"OSISM's documentation for testbed setup"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:o}={...(0,t.R)(),...e.components};return o?(0,s.jsx)(o,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,o,n)=>{n.d(o,{R:()=>r,x:()=>d});var i=n(96540);const s={},t=i.createContext(s);function r(e){const o=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function d(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d5658917.a0a8db03.js b/assets/js/d5658917.a0a8db03.js new file mode 100644 index 0000000000..30a79bdd73 --- /dev/null +++ b/assets/js/d5658917.a0a8db03.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[53156],{15003:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>i});const n=JSON.parse('{"id":"container/components/cluster-stacks/components/csctl/how_to_use_csctl","title":"how_to_use_csctl","description":"Obsolete, content moved to overview.md and quickstart.md for use in docs.scs.community","source":"@site/docs/03-container/components/cluster-stacks/components/csctl/how_to_use_csctl.md","sourceDirName":"03-container/components/cluster-stacks/components/csctl","slug":"/container/components/cluster-stacks/components/csctl/how_to_use_csctl","permalink":"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/csctl/how_to_use_csctl.md","tags":[],"version":"current","frontMatter":{}}');var o=s(74848),c=s(28453);const r={},a="Using csctl",l={},i=[{value:"What does csctl do?",id:"what-does-csctl-do",level:2},{value:"Different modes of csctl",id:"different-modes-of-csctl",level:2},{value:"Hash mode",id:"hash-mode",level:3},{value:"Stable mode",id:"stable-mode",level:3},{value:"Beta mode",id:"beta-mode",level:3},{value:"Custom mode",id:"custom-mode",level:3},{value:"Installing csctl",id:"installing-csctl",level:2},{value:"Creating Cluster Stacks",id:"creating-cluster-stacks",level:2}];function d(e){const t={blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,c.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsx)(t.p,{children:"Obsolete, content moved to overview.md and quickstart.md for use in docs.scs.community"}),"\n"]}),"\n",(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"using-csctl",children:"Using csctl"})}),"\n",(0,o.jsx)(t.h2,{id:"what-does-csctl-do",children:"What does csctl do?"}),"\n",(0,o.jsx)(t.p,{children:"As a user, you can create clusters based on Cluster Stacks with the help of the Cluster Stack Operator. The operator needs certain files, e.g. to apply the required Helm charts, and to get the necessary information about the versions in the cluster stack."}),"\n",(0,o.jsx)(t.p,{children:"In order to not generate these files manually, this CLI tool takes a certain pre-defined directory structure, in which users can configure all necessary Helm charts and build scripts for node images, and generates the assets that the Cluster Stack Operator can process."}),"\n",(0,o.jsx)(t.p,{children:"Therefore, this tool can be used to configure Cluster Stacks and to test them with the Cluster Stack Operator. It can also be used to release stable releases of Cluster Stacks that can be published for a broader community."}),"\n",(0,o.jsx)(t.h2,{id:"different-modes-of-csctl",children:"Different modes of csctl"}),"\n",(0,o.jsx)(t.p,{children:"The csctl has multiple modes that can be used for different use cases."}),"\n",(0,o.jsx)(t.h3,{id:"hash-mode",children:"Hash mode"}),"\n",(0,o.jsxs)(t.p,{children:["This mode is the most used one, as it allows quick iterations and testing of a cluster stack. It takes the hash of the content of the cluster stack and generates a semver version on this. You can combine it with the ",(0,o.jsx)(t.code,{children:"custom"})," channel of Cluster Stack Operator and test your Cluster Stacks easily!"]}),"\n",(0,o.jsx)(t.h3,{id:"stable-mode",children:"Stable mode"}),"\n",(0,o.jsx)(t.p,{children:'This mode checks for existing releases of cluster stacks and versions your cluster stack accordingly. If you have an existing release of "v1", then it would use "v2" for the new one. It also checks whether the node images and cluster addons have changed or not and will only update the versions if something actually changed.'}),"\n",(0,o.jsx)(t.h3,{id:"beta-mode",children:"Beta mode"}),"\n",(0,o.jsx)(t.p,{children:'Similar to stable mode, but for a beta release channel. It versions according to "v0-beta.1", etc.'}),"\n",(0,o.jsx)(t.h3,{id:"custom-mode",children:"Custom mode"}),"\n",(0,o.jsx)(t.p,{children:"The custom mode can be used to define your own version. You can input any semver version and your cluster stack will be versioned accordingly."}),"\n",(0,o.jsx)(t.h2,{id:"installing-csctl",children:"Installing csctl"}),"\n",(0,o.jsx)(t.p,{children:"You can click on the respective release of csctl on GitHub and download the binary."}),"\n",(0,o.jsxs)(t.p,{children:["Assuming, you have downloaded the ",(0,o.jsx)(t.code,{children:"csctl_0.0.2_linux_amd64"})," binary in your Downloads directory, you will need the following commands to rename the binary and to give it executable permissions."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"$ sudo chmod u+x ~/Downloads/csctl_0.0.2_linux_amd64\n$ sudo mv ~/Downloads/csctl_0.0.2_linux_amd64 /usr/local/bin/csctl # or use any bin directory from your PATH\n"})}),"\n",(0,o.jsx)(t.p,{children:"Then you can check whether everything worked by printing the version of csctl."}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"$ csctl version\ncsctl version: 0.0.2\ncommit: f252304eb013014b35f8a91abf1f61aff2062601\n"})}),"\n",(0,o.jsx)(t.p,{children:"If you don't see a version there, then something has gone wrong. Re-check above steps and open an issue if it still does not work!"}),"\n",(0,o.jsxs)(t.p,{children:["If you're using ",(0,o.jsx)(t.code,{children:"gh"})," CLI then you can also use the following to download it."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"$ gh release download -p csctl_0.0.2_linux_amd64 -R SovereignCloudStack/csctl\n"})}),"\n",(0,o.jsx)(t.h2,{id:"creating-cluster-stacks",children:"Creating Cluster Stacks"}),"\n",(0,o.jsxs)(t.p,{children:["The most important subcommand is ",(0,o.jsx)(t.code,{children:"create"}),". This command takes a path to the directory where you configured your Cluster Stack and generates the necessary files in the output directory via the ",(0,o.jsx)(t.code,{children:"--output"})," flag:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"$ csctl create <path-to-cluster-stack-configuration-directory> --output <path-to-output-directory>\n"})}),"\n",(0,o.jsxs)(t.p,{children:["You can specify your node image registry with the flag ",(0,o.jsx)(t.code,{children:"--node-image-registry"}),". The plugin of your provider will update the node images in the respective container registry."]}),"\n",(0,o.jsxs)(t.p,{children:["You can use the ",(0,o.jsx)(t.code,{children:"--mode"})," flag to specify the mode you want to use."]}),"\n",(0,o.jsx)(t.p,{children:"For example:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"$ csctl create <path-to-cluster-stack-directory> --output <path-to-output-directory> --mode hash --node-image-registry <url-of-registry>\n"})}),"\n",(0,o.jsx)(t.p,{children:"You have to be authenticated to your cloud provider and container registry to which you want to upload the node images."})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>a});var n=s(96540);const o={},c=n.createContext(o);function r(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d5947e44.777965a9.js b/assets/js/d5947e44.777965a9.js new file mode 100644 index 0000000000..d09503e500 --- /dev/null +++ b/assets/js/d5947e44.777965a9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[47861],{3252:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"iaas/guides/operations-guide/network","title":"Network","description":"OpenStack, OVN, and Open vSwitch all really like UUIDs.","source":"@site/docs/02-iaas/guides/operations-guide/network.md","sourceDirName":"02-iaas/guides/operations-guide","slug":"/iaas/guides/operations-guide/network","permalink":"/docs/iaas/guides/operations-guide/network","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/network.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Network"},"sidebar":"docs","previous":{"title":"Infrastructure","permalink":"/docs/iaas/guides/operations-guide/infrastructure"},"next":{"title":"OpenStack","permalink":"/docs/iaas/guides/operations-guide/openstack/"}}');var o=t(74848),r=t(28453);const a={sidebar_label:"Network"},i="Network",d={},c=[{value:"Open vSwitch (OVS)",id:"open-vswitch-ovs",level:2},{value:"Open Virtual Network (OVN)",id:"open-virtual-network-ovn",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"network",children:"Network"})}),"\n",(0,o.jsx)(n.p,{children:"OpenStack, OVN, and Open vSwitch all really like UUIDs."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ openstack --os-cloud admin image list -f yaml\n- ID: d64f0b9d-0ea1-40b0-b879-b98e46fc7bcf\n Name: Cirros 0.6.0\n Status: active\n- ID: ee842bc5-dd29-4de5-a5db-1c9be759fe85\n Name: Cirros 0.6.1\n Status: active\n- ID: cd28d95c-bd12-4e1e-8155-b9bf5ecbcb2f\n Name: Cirros 0.6.2\n Status: active\n"})}),"\n",(0,o.jsx)(n.p,{children:"These UUIDs are great for uniqueness, but 36-character strings are terrible\nfor readability. Statistically, just the first few characters are enough for\nuniqueness in small environments, so let\u2019s define a helper to make things more\nreadable:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"abbrev() { a='[0-9a-fA-F]' b=$a$a c=$b$b; sed \"s/$b-$c-$c-$c-$c$c$c//g\"; }\n"})}),"\n",(0,o.jsx)(n.p,{children:"You can use this as a filter to abbreviate UUIDs. For example, use it to abbreviate\nthe above image list:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ openstack --os-cloud admin image list -f yaml | abbrev\n- ID: d64f0b\n Name: Cirros 0.6.0\n Status: active\n- ID: ee842b\n Name: Cirros 0.6.1\n Status: active\n- ID: cd28d9\n Name: Cirros 0.6.2\n Status: active\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Source: ",(0,o.jsx)(n.a,{href:"https://docs.ovn.org/en/stable/tutorials/ovn-openstack.html#shortening-uuids",children:"https://docs.ovn.org/en/stable/tutorials/ovn-openstack.html#shortening-uuids"})]}),"\n",(0,o.jsx)(n.h2,{id:"open-vswitch-ovs",children:"Open vSwitch (OVS)"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://gist.github.com/djoreilly/c5ea44663c133b246dd9d42b921f7646",children:"https://gist.github.com/djoreilly/c5ea44663c133b246dd9d42b921f7646"})}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Open vSwitch on a network node with external network ",(0,o.jsx)(n.code,{children:"vxlan0"})," and integration\nwith the Octavia service via ",(0,o.jsx)(n.code,{children:"ohm0"}),"."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'$ docker exec -it openvswitch_vswitchd ovs-vsctl show\n2e6227aa-33f1-4762-8831-ab678ce7272d\n Bridge br-int\n fail_mode: secure\n datapath_type: system\n Port ovn-testbe-0\n Interface ovn-testbe-0\n type: geneve\n options: {csum="true", key=flow, remote_ip="192.168.16.12"}\n Port br-int\n Interface br-int\n type: internal\n Port ovn-testbe-1\n Interface ovn-testbe-1\n type: geneve\n options: {csum="true", key=flow, remote_ip="192.168.16.11"}\n Port tap8fe7d09b-90\n Interface tap8fe7d09b-90\n Port ohm0\n Interface ohm0\n type: internal\n Bridge br-ex\n Port vxlan0\n Interface vxlan0\n Port br-ex\n Interface br-ex\n type: internal\n'})}),"\n",(0,o.jsx)(n.h2,{id:"open-virtual-network-ovn",children:"Open Virtual Network (OVN)"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.ovn.org/en/stable/tutorials/ovn-openstack.html",children:"https://docs.ovn.org/en/stable/tutorials/ovn-openstack.html"})}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Get OVN NB and OVN SB connection information from the ",(0,o.jsx)(n.code,{children:"/etc/kolla/neutron-server/ml2_conf.ini"}),"\nfile."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'ovn_nb_connection=$(sudo grep -P -o -e "(?<=^ovn_nb_connection = ).*" "/etc/kolla/neutron-server/ml2_conf.ini")\novn_sb_connection=$(sudo grep -P -o -e "(?<=^ovn_sb_connection = ).*" "/etc/kolla/neutron-server/ml2_conf.ini")\n'})}),"\n",(0,o.jsxs)(n.p,{children:["The following examples are from a fresh ",(0,o.jsx)(n.a,{href:"https://github.com/osism/testbed",children:"osism/testbed"}),"\ndeployment with no payload running yet."]}),"\n",(0,o.jsx)(n.p,{children:"OVN NB DB entries:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'$ docker exec ovn_northd ovn-nbctl --db "$ovn_nb_connection" show | abbrev\nswitch b5139b (neutron-8fe7d0) (aka lb-mgmt-net)\n port 45a49e\n type: localport\n addresses: ["fa:16:3e:fa:99:ea 10.1.0.2"]\n port 4d39a5 (aka octavia-listen-port-testbed-node-2)\n addresses: ["fa:16:3e:dc:11:e4 10.1.0.45"]\n port 8df1b7 (aka octavia-listen-port-testbed-node-0)\n addresses: ["fa:16:3e:4d:63:a9 10.1.0.43"]\n port ddb6aa (aka octavia-listen-port-testbed-node-1)\n addresses: ["fa:16:3e:67:f3:3d 10.1.0.40"]\n'})}),"\n",(0,o.jsx)(n.p,{children:"OVN SB DB entries:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'$ docker exec ovn_northd ovn-sbctl --db "$ovn_sb_connection" show | abbrev\nChassis testbed-node-0\n hostname: testbed-node-0\n Encap geneve\n ip: "192.168.16.10"\n options: {csum="true"}\n Port_Binding "8df1b7"\nChassis testbed-node-2\n hostname: testbed-node-2\n Encap geneve\n ip: "192.168.16.12"\n options: {csum="true"}\n Port_Binding "4d39a5"\nChassis testbed-node-1\n hostname: testbed-node-1\n Encap geneve\n ip: "192.168.16.11"\n options: {csum="true"}\n Port_Binding "ddb6aa\n'})}),"\n",(0,o.jsx)(n.p,{children:"OVN NB status:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ docker exec ovn_nb_db ovs-appctl -t /var/run/ovn/ovnnb_db.ctl cluster/status OVN_Northbound | abbrev\n6d15\nName: OVN_Northbound\nCluster ID: f5eb (f5ebd8)\nServer ID: 6d15 (6d159e)\nAddress: tcp:192.168.16.10:6643\nStatus: cluster member\nRole: follower\nTerm: 5\nLeader: 87d6\nVote: 87d6\n\nLast Election started 41049332 ms ago, reason: timeout\nElection timer: 1000\nLog: [2, 54]\nEntries not yet committed: 0\nEntries not yet applied: 0\nConnections: ->21d7 ->87d6 <-87d6 <-21d7\nDisconnections: 6\nServers:\n 6d15 (6d15 at tcp:192.168.16.10:6643) (self)\n 87d6 (87d6 at tcp:192.168.16.11:6643) last msg 266 ms ago\n 21d7 (21d7 at tcp:192.168.16.12:6643) last msg 41048563 ms ago\n"})}),"\n",(0,o.jsx)(n.p,{children:"OVN SB status:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ docker exec ovn_sb_db ovs-appctl -t /var/run/ovn/ovnsb_db.ctl cluster/status OVN_Southbound | abbrev\nbe29\nName: OVN_Southbound\nCluster ID: bd0c (bd0c26)\nServer ID: be29 (be2932)\nAddress: tcp:192.168.16.10:6644\nStatus: cluster member\nRole: follower\nTerm: 6\nLeader: dfdf\nVote: unknown\n\nLast Election started 41063820 ms ago, reason: timeout\nElection timer: 1000\nLog: [2, 62]\nEntries not yet committed: 0\nEntries not yet applied: 0\nConnections: ->dfdf ->085c <-dfdf <-085c\nDisconnections: 7\nServers:\n be29 (be29 at tcp:192.168.16.10:6644) (self)\n dfdf (dfdf at tcp:192.168.16.11:6644) last msg 146 ms ago\n 085c (085c at tcp:192.168.16.12:6644) last msg 41063293 ms ago\n"})})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var s=t(96540);const o={},r=s.createContext(o);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d59f7d52.cb222074.js b/assets/js/d59f7d52.cb222074.js new file mode 100644 index 0000000000..c85eefd0c9 --- /dev/null +++ b/assets/js/d59f7d52.cb222074.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[55139],{24907:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"scs-0301-v1-naming-conventions","title":"Naming for domains/groups/roles/project when onboarding new customers","description":"\x3c!---","source":"@site/standards/scs-0301-v1-naming-conventions.md","sourceDirName":".","slug":"/scs-0301-v1-naming-conventions","permalink":"/standards/scs-0301-v1-naming-conventions","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Naming for domains/groups/roles/project when onboarding new customers","type":"Decision Record","status":"Draft","track":"IAM"},"sidebar":"standards","previous":{"title":"scs-0301: Naming for domains/groups/roles/project when onboarding new customers","permalink":"/standards/iam/scs-0301"},"next":{"title":"scs-0302: Domain Manager configuration for Keystone","permalink":"/standards/iam/scs-0302"}}');var s=o(74848),r=o(28453);const i={title:"Naming for domains/groups/roles/project when onboarding new customers",type:"Decision Record",status:"Draft",track:"IAM"},a=void 0,c={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"PS approach to naming",id:"ps-approach-to-naming",level:4},{value:"<em>Option 2</em>",id:"option-2",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function l(e){const n={code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"When CSPs try to enroll a new customer they encounter themselves in\na situation where they have to choose names for the openstack domain,\nproject and user."}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(n.p,{children:"Create a naming convention to use during the provisioning of the users and\ngroups through an openstack domain."}),"\n",(0,s.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsx)(n.p,{children:"OPTIONAL"}),"\n",(0,s.jsx)(n.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,s.jsx)(n.h4,{id:"ps-approach-to-naming",children:"PS approach to naming"}),"\n",(0,s.jsx)(n.p,{children:"For naming the customers the suggestion from PS is the following:"}),"\n",(0,s.jsx)(n.p,{children:"A prefix will be used to differentiate domain, project and user in\nthe openstack environment. The project name is also added as a suffix."}),"\n",(0,s.jsx)(n.p,{children:"So the onboarding tool will create the following structure for a new\ncustomer onboarded in the system."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-commandline",children:"domain: d<customer_id>\nproject: p<customer_id>-<project_name>\nuser: u<customer_id>-<user_name>\n"})}),"\n",(0,s.jsx)(n.p,{children:'For the customer also a domain admin group and a project admin group are\ncreated. Please note that, at the time of writing, PCO is not making any\nuse of OpenStack domains to isolate customers. So, for the scope of this\ndocument, the term "domain admin" is used in a conceptual way rather than\nreferring to the specific OpenStack implementation. For the scope of this\ndocument "domain admins" can do things like creating projects, creating\nusers and granting users access to some projects (within the domain of\ncourse). "Users" can create and view resources within the projects that\nthey have been granted access to by the "domain admin".\nThese groups use the prefix "gd" for domain group and "gp" for group project\nand are build like the following:'}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-commandline",children:"domain admin group: gd<customer_id>-member\nproject admin group: gp<customer_id>-<project_name>-member\n"})}),"\n",(0,s.jsx)(n.p,{children:"For the creation of a domain a new domain admin group is created."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-commandline",children:"openstack domain create d000001\nopenstack group create gd000001-member\n"})}),"\n",(0,s.jsx)(n.p,{children:"When a project is created a new admin group for that project is created."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-commandline",children:"openstack project create p000001-scs_dev_project\nopenstack group create p000001-scs_dev_project-member\n"})}),"\n",(0,s.jsx)(n.p,{children:"After the creation of a project it is necessary to assign roles to the\nnew groups."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-commandline",children:"openstack role add --group gd000001-member --project p000001-scs_dev_project $role\nopenstack role add --group gp000001-scs_dev_project-member --project p000001-scs_dev_project $role\n"})}),"\n",(0,s.jsx)(n.p,{children:'For the creation of regular non admin users, the accounts will be added\nto the "domain admin" group to give them access to all projects within\nthe domain.'}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-commandline",children:"openstack user created u000001-user1\nopenstack group add user gd000001-member u000001-user1\n"})}),"\n",(0,s.jsx)(n.p,{children:'In the case of machine accounts, they are only added to the specific\n"project admin" groups.'}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-commandline",children:"openstack user created u000001-svc_user_project\nopenstack group add user gp000001-scs_dev_project-member u000001-svc_user_project\n"})}),"\n",(0,s.jsx)(n.p,{children:"In case of using federation, there are suggestions to the namings within Keycloak."}),"\n",(0,s.jsx)(n.p,{children:'The realms in Keycloak for each customer would be the same as the customer. e.g. The Keycloak realm for "Customer A"\nwill be called "Customer A".'}),"\n",(0,s.jsx)(n.p,{children:"There should be an OIDC client in each customer realm to allow the federation to the Proxy realm. Currently called OSISM\non the testbed."}),"\n",(0,s.jsxs)(n.p,{children:['On the proxy realm, it\'s needed to add this new customer realm as an identity provider. During the creation of the identity\nprovider for "Customer A", the field "Alias" should be set to ',(0,s.jsx)(n.code,{children:"<customer-id>"}),'. This will make that the users federated from\nrealm "Customer A" to the proxy realm to be prefixed to avoid naming collisions, e.g. ',(0,s.jsx)(n.code,{children:"d${ALIAS}-${CLAIM.preferred_username}"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Also, on the identity federation there should be configured to store the ",(0,s.jsx)(n.code,{children:"<customer-id>"})," from that realm into the users. So it\ncan be sent to Keystone mapping to use it as ",(0,s.jsx)(n.code,{children:"gd<customer-id>-member"})," and ",(0,s.jsx)(n.code,{children:"gp<customer-id>-<project_name>-member"}),". There is\nalso the necessity of a mapper to send the ",(0,s.jsx)(n.code,{children:"openstack-default-project"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Add the additional mappings for roles and groups as necessary to get the attributes from the customer realm into the OIDC\nuserinfo that is put into the OIDC to the proxy realm and from there to Keystone."}),"\n",(0,s.jsx)(n.h4,{id:"option-2",children:(0,s.jsx)(n.em,{children:"Option 2"})}),"\n",(0,s.jsx)(n.p,{children:"Option 2 description"}),"\n",(0,s.jsx)(n.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,s.jsx)(n.p,{children:"RECOMMENDED"}),"\n",(0,s.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsx)(n.p,{children:"Decision"}),"\n",(0,s.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsx)(n.p,{children:"Related Documents, OPTIONAL"}),"\n",(0,s.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsx)(n.p,{children:"Conformance Tests, OPTIONAL"})]})}function m(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>a});var t=o(96540);const s={},r=t.createContext(s);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d71eca41.63dcb63b.js b/assets/js/d71eca41.63dcb63b.js new file mode 100644 index 0000000000..39bcbe41e6 --- /dev/null +++ b/assets/js/d71eca41.63dcb63b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[70467],{33978:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"iaas/guides/concept-guide/components/index","title":"Components","description":"* Infrastructure as a Service (IaaS) with OpenStack","source":"@site/docs/02-iaas/guides/concept-guide/components/index.md","sourceDirName":"02-iaas/guides/concept-guide/components","slug":"/iaas/guides/concept-guide/components/","permalink":"/docs/iaas/guides/concept-guide/components/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/index.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Components","sidebar_position":10},"sidebar":"docs","previous":{"title":"Concept Guide","permalink":"/docs/iaas/guides/concept-guide/"},"next":{"title":"Ceph","permalink":"/docs/iaas/guides/concept-guide/components/ceph"}}');var s=i(74848),r=i(28453);const a={sidebar_label:"Components",sidebar_position:10},c="Components",o={},d=[];function l(e){const n={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"components",children:"Components"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./openstack",children:"Infrastructure as a Service (IaaS) with OpenStack"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./ceph",children:"Software Defined Storage (SDS) with Ceph"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./ironic",children:"Bare Metal as a Service (BMaaS) with Ironic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./sonic",children:"Software Defined Networking (SDN) with SONiC & OVN"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./k3s",children:"Kubernetes (K8s) with K3S"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./gardener",children:"Kubernetes as a Service (KaaS) with Gardener"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./clusterapi",children:"Kubernetes as a Service (KaaS) with Cluster API"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./keycloak",children:"Identity & Access Management with Keycloak"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./teleport",children:"Privileged Access Management (PAM) to all infrastructure with Teleport"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./prometheus",children:"Logging, Monitoring & Telemetry with Prometheus & Grafana"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"./netdata",children:"Realtime insights with Netdata"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>c});var t=i(96540);const s={},r=t.createContext(s);function a(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d83cc1de.b0074640.js b/assets/js/d83cc1de.b0074640.js new file mode 100644 index 0000000000..fafb271f37 --- /dev/null +++ b/assets/js/d83cc1de.b0074640.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1396],{25641:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>n,metadata:()=>r,toc:()=>u});const r=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow","title":"Management Cluster flow","description":"In a Cluster API management cluster, the Cluster API operators run. In our management cluster, there are also the Cluster Stack operators.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/architecture","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow.md","tags":[],"version":"current","frontMatter":{}}');var c=s(74848),o=s(28453);const n={},a="Management Cluster flow",l={},u=[];function i(e){const t={code:"code",h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(t.header,{children:(0,c.jsx)(t.h1,{id:"management-cluster-flow",children:"Management Cluster flow"})}),"\n",(0,c.jsx)(t.p,{children:"In a Cluster API management cluster, the Cluster API operators run. In our management cluster, there are also the Cluster Stack operators."}),"\n",(0,c.jsxs)(t.p,{children:["The user controls workload clusters via custom resources. As the Cluster Stack approach uses ",(0,c.jsx)(t.code,{children:"ClusterClasses"}),", the user has to create only a ",(0,c.jsx)(t.code,{children:"Cluster"})," object and refer to a ",(0,c.jsx)(t.code,{children:"ClusterClass"}),"."]}),"\n",(0,c.jsxs)(t.p,{children:["However, in order for this to work, the ",(0,c.jsx)(t.code,{children:"ClusterClass"})," has to be applied as well as all other Cluster API objects that are referenced by the ",(0,c.jsx)(t.code,{children:"ClusterClass"}),", such as ",(0,c.jsx)(t.code,{children:"MachineTemplates"}),", etc."]}),"\n",(0,c.jsxs)(t.p,{children:["These Cluster API objects are packaged in a Helm Chart that is part of every cluster stack. The clusterstackrelease-controller is responsible for applying this Helm chart, which is done by first calling ",(0,c.jsx)(t.code,{children:"helm template"}),' and then the "apply" method of the Kubernetes go-client.']}),"\n",(0,c.jsxs)(t.p,{children:["The main resource is always the ",(0,c.jsx)(t.code,{children:"ClusterClass"})," that follows a very specific naming pattern and is called in the exact same way as the ",(0,c.jsx)(t.code,{children:"ClusterStackRelease"})," object that manages it. For example, ",(0,c.jsx)(t.code,{children:"docker-ferrol-1-27-v1"}),", which refers to all defining properties of a specific release of a cluster stack for a certain provider."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(i,{...e})}):i(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>n,x:()=>a});var r=s(96540);const c={},o=r.createContext(c);function n(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:n(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d902a273.09b18c45.js b/assets/js/d902a273.09b18c45.js new file mode 100644 index 0000000000..2c8f51633a --- /dev/null +++ b/assets/js/d902a273.09b18c45.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[57695],{87380:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>d,contentTitle:()=>i,default:()=>l,frontMatter:()=>r,metadata:()=>n,toc:()=>p});const n=JSON.parse('{"id":"operating-scs/components/status-page-deployment/docs/scs-public","title":"SCS Public","description":"Data present in kubernetes/environments/scs-public is the deployment specified for the provided SCS Cluster, which is already fully setup to run k8s workloads.","source":"@site/docs/04-operating-scs/components/status-page-deployment/docs/scs-public.md","sourceDirName":"04-operating-scs/components/status-page-deployment/docs","slug":"/operating-scs/components/status-page-deployment/docs/scs-public","permalink":"/docs/operating-scs/components/status-page-deployment/docs/scs-public","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-deployment/docs/scs-public.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"k3s - A simple deployment on a single host","permalink":"/docs/operating-scs/components/status-page-deployment/docs/k3s"},"next":{"title":"Usage","permalink":"/docs/operating-scs/components/status-page-deployment/docs/usage"}}');var o=t(74848),c=t(28453);const r={},i="SCS Public",d={},p=[];function a(e){const s={a:"a",code:"code",h1:"h1",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"scs-public",children:"SCS Public"})}),"\n",(0,o.jsxs)(s.p,{children:["Data present in ",(0,o.jsx)(s.code,{children:"kubernetes/environments/scs-public"})," is the deployment specified for the provided SCS Cluster, which is already fully setup to run k8s workloads."]}),"\n",(0,o.jsxs)(s.p,{children:["Configure the provided ",(0,o.jsx)(s.code,{children:".env"}),"s. For secrets, the provided examples drop the ",(0,o.jsx)(s.code,{children:"-example"})," part of their file names to be used as ",(0,o.jsx)(s.code,{children:".env"})," for that secret."]}),"\n",(0,o.jsxs)(s.p,{children:["For in depth configuration see ",(0,o.jsx)(s.a,{href:"/docs/operating-scs/components/status-page-deployment/docs/configuration",children:(0,o.jsx)(s.code,{children:"configuration"})}),"."]}),"\n",(0,o.jsxs)(s.p,{children:["Deploy ",(0,o.jsx)(s.code,{children:"kubernetes/environments/scs-public/kustomization.yaml"})," to your desired cluster."]})]})}function l(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>i});var n=t(96540);const o={},c=n.createContext(o);function r(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d98f39e0.16de317a.js b/assets/js/d98f39e0.16de317a.js new file mode 100644 index 0000000000..343e7929e5 --- /dev/null +++ b/assets/js/d98f39e0.16de317a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[18659],{80873:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>n,toc:()=>p});const n=JSON.parse('{"id":"operating-scs/components/status-page-api/docs/overview","title":"Overview","description":"The status-page-api repository strives to provide a reference implementation of the concepts being outlined by status-page-openapi.","source":"@site/docs/04-operating-scs/components/status-page-api/docs/overview.md","sourceDirName":"04-operating-scs/components/status-page-api/docs","slug":"/operating-scs/components/status-page-api/docs/overview","permalink":"/docs/operating-scs/components/status-page-api/docs/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-api/docs/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"API","permalink":"/docs/category/api"},"next":{"title":"Requirements","permalink":"/docs/operating-scs/components/status-page-api/docs/requirements"}}');var o=s(74848),r=s(28453);const i={},a="Overview",c={},p=[];function d(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,o.jsxs)(t.p,{children:["The ",(0,o.jsx)(t.code,{children:"status-page-api"})," repository strives to provide a reference implementation of the concepts being outlined by ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi",children:(0,o.jsx)(t.code,{children:"status-page-openapi"})}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["For the implementation ",(0,o.jsx)(t.a,{href:"https://go.dev/",children:(0,o.jsx)(t.code,{children:"go"})})," was used, as rational see the ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0401-v1-status-page-reference-implementation-decision.md#programming-language",children:"decision record"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["Code under the ",(0,o.jsx)(t.code,{children:"pkg/"})," directory, is considered as public reference or even library code to implement your own API server, while code in ",(0,o.jsx)(t.code,{children:"internal/"})," is implementation specific to this application, but can serve as reference, too."]})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>a});var n=s(96540);const o={},r=n.createContext(o);function i(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/da1a5473.00cab2c3.js b/assets/js/da1a5473.00cab2c3.js new file mode 100644 index 0000000000..cd0d8eb023 --- /dev/null +++ b/assets/js/da1a5473.00cab2c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[77125],{18599:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>h,contentTitle:()=>c,default:()=>d,frontMatter:()=>t,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"iaas/guides/other-guides/developer-guide/scripts","title":"Scripts","description":"Scripts are included in container images to simplify development work and to enable","source":"@site/docs/02-iaas/guides/other-guides/developer-guide/scripts.md","sourceDirName":"02-iaas/guides/other-guides/developer-guide","slug":"/iaas/guides/other-guides/developer-guide/scripts","permalink":"/docs/iaas/guides/other-guides/developer-guide/scripts","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/developer-guide/scripts.md","tags":[],"version":"current","sidebarPosition":20,"frontMatter":{"sidebar_label":"Scripts","sidebar_position":20},"sidebar":"docs","previous":{"title":"Releases","permalink":"/docs/iaas/guides/other-guides/developer-guide/releases"},"next":{"title":"Style Guide","permalink":"/docs/iaas/guides/other-guides/developer-guide/style-guide"}}');var o=i(74848),r=i(28453);const t={sidebar_label:"Scripts",sidebar_position:20},c="Scripts",h={},l=[];function a(e){const s={a:"a",code:"code",h1:"h1",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"scripts",children:"Scripts"})}),"\n",(0,o.jsx)(s.p,{children:"Scripts are included in container images to simplify development work and to enable\ntesting and hotfixes in running environments. What scripts are available and how to\nuse them is described in this chapter."}),"\n",(0,o.jsxs)(s.p,{children:["The ",(0,o.jsx)(s.code,{children:"change.sh"})," script may be used to update repositories to development branches. Different\ntargets may be passed as a first parameter and existing branch names as a second. The availability\nof targets depends on the container it is run in."]}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["For the ",(0,o.jsx)(s.code,{children:"osismclient"})," container"]}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh osism <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/python-osism",children:"osism/python-osism"})," repository"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["For the ",(0,o.jsx)(s.code,{children:"inventory-reonciler"})," container"]}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh osism <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/python-osism",children:"osism/python-osism"})," repository"]}),"\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh generics <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/cfg-generics",children:"osism/cfg-generics"})," repository"]}),"\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh defaults <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/defaults",children:"osism/defaults"})," repository"]}),"\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh release <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/release",children:"osism/release"})," repository"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["For the ",(0,o.jsx)(s.code,{children:"osism-ansible"})," container"]}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh osism <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/python-osism",children:"osism/python-osism"})," repository"]}),"\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh playbooks <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/ansible-playbooks",children:"osism/ansible-playbooks"})," repository"]}),"\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh [services|commons|validations] <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/ansible-collection-services",children:"osism/ansible-collection-services"}),", ",(0,o.jsx)(s.a,{href:"https://github.com/osism/ansible-collection-commons",children:"osism/ansible-collection-commons"}),", and ",(0,o.jsx)(s.a,{href:"https://github.com/osism/ansible-collection-validations",children:"osism/ansible-collection-validations"})," repositories"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["For the ",(0,o.jsx)(s.code,{children:"ceph-ansible"})," container"]}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh osism <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/python-osism",children:"osism/python-osism"})," repository"]}),"\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh operations <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/kolla-operations",children:"osism/kolla-operations"})," repository"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["For the ",(0,o.jsx)(s.code,{children:"kolla-ansible"})," container"]}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh osism <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/python-osism",children:"osism/python-osism"})," repository"]}),"\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh operations <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/kolla-operations",children:"osism/kolla-operations"})," repository"]}),"\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.code,{children:"/change.sh kolla-ansible <git branch>"})," for the ",(0,o.jsx)(s.a,{href:"https://opendev.org/openstack/kolla-ansible",children:"openstack/kolla-ansible"})," repository"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(s.p,{children:["In this example, the ",(0,o.jsx)(s.code,{children:"main"})," branch of ",(0,o.jsx)(s.a,{href:"https://github.com/osism/ansible-collection-services",children:"osism/ansible-collection-services"}),"\nis used in the ",(0,o.jsx)(s.code,{children:"osism-ansible"})," container."]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"docker exec -u root -it osism-ansible /change.sh services main\n"})}),"\n",(0,o.jsx)(s.p,{children:"The respective container should always be restarted after a change."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"docker restart osism-ansible\n"})}),"\n",(0,o.jsx)(s.p,{children:"If something has been changed in the defaults and is to be tested, this must be\nchanged in the inventory reconciler service. Regardless of which of the Ansible services\nthe customised defaults are intended for."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"docker exec -u root -it manager-inventory_reconciler-1 /change.sh defaults main\ndocker restart manager-inventory_reconciler-1\n"})})]})}function d(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},28453:(e,s,i)=>{i.d(s,{R:()=>t,x:()=>c});var n=i(96540);const o={},r=n.createContext(o);function t(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/db103552.585bfc17.js b/assets/js/db103552.585bfc17.js new file mode 100644 index 0000000000..0421e9bca6 --- /dev/null +++ b/assets/js/db103552.585bfc17.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[90495],{36866:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Concepts","slug":"/category/concepts","permalink":"/docs/category/concepts","sidebar":"docs","navigation":{"previous":{"title":"Status Page","permalink":"/docs/category/status-page"},"next":{"title":"Overview","permalink":"/docs/operating-scs/components/status-page-openapi/docs/overview"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/db47e023.024cc770.js b/assets/js/db47e023.024cc770.js new file mode 100644 index 0000000000..ea40654d0e --- /dev/null +++ b/assets/js/db47e023.024cc770.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[83160],{59497:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"operating-scs/components/automated-pentesting-iaas/quickstart","title":"Quickstart","description":"This page covers the process of setting up an IaaS layer automated pentesting pipeline.","source":"@site/docs/04-operating-scs/components/automated-pentesting-iaas/quickstart.md","sourceDirName":"04-operating-scs/components/automated-pentesting-iaas","slug":"/operating-scs/components/automated-pentesting-iaas/quickstart","permalink":"/docs/operating-scs/components/automated-pentesting-iaas/quickstart","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/automated-pentesting-iaas/quickstart.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/operating-scs/components/automated-pentesting-iaas/overview"},"next":{"title":"Tools Description","permalink":"/docs/operating-scs/components/automated-pentesting-iaas/tools"}}');var t=i(74848),o=i(28453);const r={},a="Quickstart",l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Configuration",id:"configuration",level:2},{value:"DefectDojo",id:"defectdojo",level:3},{value:"Zuul",id:"zuul",level:3},{value:"Aditional notes",id:"aditional-notes",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,t.jsx)(n.p,{children:"This page covers the process of setting up an IaaS layer automated pentesting pipeline."}),"\n",(0,t.jsx)(n.p,{children:"The provided configuration options result in a simple and working deployment that allows to scan a set of defined targets. However, it is possible to adapt each tool behaviour adding additional capabilities, which are defined in their specific documentation."}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["DefectDojo instance available. See ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/defectdojo",children:"defectdojo repo"})," for deployment instructions."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Zuul instance available and configured with daily and weekly timed pipelines. See ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul",children:"zuul repo"}),", ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-scs-jobs",children:"zuul-scs-jobs repo"})," and ",(0,t.jsx)(n.a,{href:"https://docs.scs.community/community/tools/zuul/",children:"zuul community docs"})," for deployment instructions and examples."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,t.jsx)(n.h3,{id:"defectdojo",children:"DefectDojo"}),"\n",(0,t.jsx)(n.p,{children:"After installing DefectDojo, a few key configurations are necessary to start using the platform effectively, ensuring that a streamlined process for managing security assessments, tracking vulnerabilities, and integrating with existing tools and processes is set up based on SCS Standards."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Products"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'Definition: In DefectDojo, a "Product" represents an application, system, or any entity that is being tested or tracked for vulnerabilities.'}),"\n",(0,t.jsxs)(n.li,{children:["Configuration:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'Navigate to the "Products" section and click "Add Product."'}),"\n",(0,t.jsx)(n.li,{children:"Fill in the necessary details such as the product name, description, and criticality."}),"\n",(0,t.jsx)(n.li,{children:"Assign product type, enable/disable tracking of findings, and set the product's authorization configuration."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Engagements"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'Definition: An "Engagement" refers to a specific instance of testing or assessment activity against a product. This could be a penetration test, vulnerability assessment, or any other security-related activity.'}),"\n",(0,t.jsxs)(n.li,{children:["Configuration:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'In the "Engagements" section, click "Add Engagement."'}),"\n",(0,t.jsx)(n.li,{children:"Choose the product you want to engage with, define the type of engagement (e.g., pen test, code review), and set the time frame."}),"\n",(0,t.jsxs)(n.li,{children:["Once created, note the engagement id that has been generated, as it will be needed for pipeline configuration (just pick the id number from the URL, in the form of ",(0,t.jsx)(n.code,{children:"https://<instance_url>/engagement/<engagement_id>"}),")"]}),"\n",(0,t.jsx)(n.li,{children:"Optionally, link the engagement to an external test plan, define test lead, and add team members."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Recommended setup"}),": Add at least the following engagements.","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.em,{children:"Daily Automated Scan"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.em,{children:"Weekly Automated Scan"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Importing Findings from Tools"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Definition: DefectDojo can import findings from various security tools, allowing centralized tracking and management."}),"\n",(0,t.jsxs)(n.li,{children:["Configuration:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Tasks on the automated pipelines leverage DefectDojo API to automate imports by sending scan results directly to the system using specific endpoints for supported tools."}),"\n",(0,t.jsx)(n.li,{children:"The import POST request to the api needs to be authenticated. Several methods are availiable, but taking into accounts security measures, the use of tokens/keys are encouraged."}),"\n",(0,t.jsxs)(n.li,{children:['To get a working API key, under user menu head to "',(0,t.jsx)(n.em,{children:"API v2 Key"}),'" or directly access the endpoint ',(0,t.jsx)(n.code,{children:"https://<instance_url>/api/key-v2"}),". If it is needed, generate a new one."]}),"\n",(0,t.jsx)(n.li,{children:'Alternatively, it is possible to use the "Import Scan Results" option within an engagement to manually import results from tools like OWASP ZAP, Burp Suite, Nessus, etc.'}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"User and Role Management"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Configuration:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"It is possible to directly set up users and assign roles (Admin, Staff, Developer, etc.) based on the level of access required. Using Keycloak based login is encouraged."}),"\n",(0,t.jsx)(n.li,{children:"Manage permissions and ensure users have the correct access to products, engagements, and reports."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Notifications and Reports"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Configuration:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Set up notifications to alert users about new findings, engagement updates, or product changes."}),"\n",(0,t.jsx)(n.li,{children:"Generate reports to summarize findings, trends, and metrics for stakeholders."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"zuul",children:"Zuul"}),"\n",(0,t.jsxs)(n.p,{children:["Based on how the jobs and tasks are defined across the automated scan pipelines, it is neccesary to define some variables and secrets at Zuul level in the ",(0,t.jsx)(n.code,{children:".zuul.d/"})," folder of the repo."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"config.yaml"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"This file contains project specific zuul configuration related to jobs."}),"\n",(0,t.jsx)(n.li,{children:"During checks, the pipeline is run with a mock test configuration in order to debug canges and determine if it works as expected."}),"\n",(0,t.jsxs)(n.li,{children:["Configuration:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"scan_targets"})," variable, under ",(0,t.jsx)(n.code,{children:"scs-security-scan-base"})," job, controls what will be scanned. ",(0,t.jsx)(n.em,{children:(0,t.jsx)(n.strong,{children:"Only use IPv4 addresses and/or full domain names"})})," (Otherwise pipeline will fail)."]}),"\n",(0,t.jsxs)(n.li,{children:["It is mandatory to set ",(0,t.jsx)(n.code,{children:"timeout"})," values based on the targets being defined for scanning, especially for the ",(0,t.jsx)(n.code,{children:"scs-greenbone-security-scan-base"})," job, as greenbone ecosystem deployment and full scanning takes a very long time, which could cause workers to finish earlier than expected."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"secrets.yaml"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["This file contains encrypted variables which may contain sensitive data:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"dojo_api_key"}),": API Token generated during DefecDojo configuration."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"dojo_url"}),": DefecDojo endpoint for importing scans in the form of ",(0,t.jsx)(n.code,{children:"https://<instance_url>/api/v2/import-scan/"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"daily_scan_engagement_id"}),": Engagement id for daily scans generated during DefecDojo configuration."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"weekly_scan_engagement_id"}),": Engagement id for weekly scans generated during DefecDojo configuration."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["In order to generate secrets it is recommended to use zuul-cli tool. As an example: ",(0,t.jsx)(n.code,{children:'echo -n "secret" | zuul-client --zuul-url https://zuul.sovereignit.cloud encrypt --tenant scs --project SovereignCloudStack/security-infra-scan-pipeline --field-name <variable_name>'})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"aditional-notes",children:"Aditional notes"}),"\n",(0,t.jsx)(n.p,{children:"With this configuration pipeline should work with its default configuration, uploading each scan results to DefctDojo for further analysis and tracking of the vulnerabilities found."}),"\n",(0,t.jsx)(n.p,{children:"However, depending on user needs, it is possible to leverage included tools functionalities modifying the command being launched in their respective playbook. Options include, but not limited to, ports being scanned, requests rate-limit, threads spawned, templates/rules being used or response codes filtering, among others."}),"\n",(0,t.jsx)(n.p,{children:"This provides a complete and very customizable toolkit to perform vulnerability assessments across a wide range of targers."}),"\n",(0,t.jsx)(n.p,{children:"For further details refer to each tool official documentation."})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>a});var s=i(96540);const t={},o=s.createContext(t);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dbde4c02.c1ec7a9b.js b/assets/js/dbde4c02.c1ec7a9b.js new file mode 100644 index 0000000000..90b38b0400 --- /dev/null +++ b/assets/js/dbde4c02.c1ec7a9b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[70445],{84858:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>d,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"iaas/guides/upgrade-guide/infrastructure","title":"Infrastructure","description":"1. Kubernetes","source":"@site/docs/02-iaas/guides/upgrade-guide/infrastructure.md","sourceDirName":"02-iaas/guides/upgrade-guide","slug":"/iaas/guides/upgrade-guide/infrastructure","permalink":"/docs/iaas/guides/upgrade-guide/infrastructure","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/infrastructure.md","tags":[],"version":"current","sidebarPosition":30,"frontMatter":{"sidebar_label":"Infrastructure","sidebar_position":30},"sidebar":"docs","previous":{"title":"Docker","permalink":"/docs/iaas/guides/upgrade-guide/docker"},"next":{"title":"Logging & Monitoring","permalink":"/docs/iaas/guides/upgrade-guide/logging-monitoring"}}');var i=s(74848),a=s(28453);const d={sidebar_label:"Infrastructure",sidebar_position:30},o="Infrastructure",c={},l=[];function t(e){const n={code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"infrastructure",children:"Infrastructure"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Kubernetes"}),"\n",(0,i.jsxs)(n.p,{children:["This is only necessary if the internal Kubernetes cluster has also been deployed.\nThis can be checked by executing ",(0,i.jsx)(n.code,{children:"kubectl get nodes"})," on the manager node."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply k3s-upgrade\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Cron, Fluentd & Kolla Toolbox"}),"\n",(0,i.jsxs)(n.p,{children:["The common role of Kolla is used to manage the services ",(0,i.jsx)(n.code,{children:"cron"}),", ",(0,i.jsx)(n.code,{children:"fluentd"}),"\nand ",(0,i.jsx)(n.code,{children:"kolla-toolbox"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["It is important to do this upgrade before any other upgrades in the Kolla\nenvironment, as parts of the other upgrades depend on the ",(0,i.jsx)(n.code,{children:"kolla-toolbox"}),"\nservice."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull common\nosism apply -a upgrade common\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Loadbalancer"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull loadbalancer\nosism apply -a upgrade loadbalancer\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Redis"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull redis\nosism apply -a upgrade redis\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Memcached"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull memcached\nosism apply -a upgrade memcached\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"RabbitMQ"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull rabbitmq\nosism apply -a upgrade rabbitmq\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"MariaDB"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull mariadb\nosism apply -a upgrade mariadb\n"})}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(t,{...e})}):t(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>o});var r=s(96540);const i={},a=r.createContext(i);function d(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dc09f893.d46295ee.js b/assets/js/dc09f893.d46295ee.js new file mode 100644 index 0000000000..e72cceafc4 --- /dev/null +++ b/assets/js/dc09f893.d46295ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[13527],{31579:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>a,contentTitle:()=>o,default:()=>l,frontMatter:()=>d,metadata:()=>t,toc:()=>u});const t=JSON.parse('{"id":"iaas/guides/user-guide/index","title":"User Guide","description":"","source":"@site/docs/02-iaas/guides/user-guide/index.md","sourceDirName":"02-iaas/guides/user-guide","slug":"/iaas/guides/user-guide/","permalink":"/docs/iaas/guides/user-guide/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/index.md","tags":[],"version":"current","sidebarPosition":50,"frontMatter":{"sidebar_label":"User Guide","sidebar_position":50},"sidebar":"docs","previous":{"title":"Guides","permalink":"/docs/iaas/guides/"},"next":{"title":"Migrate from VMware ESXi to OpenStack","permalink":"/docs/iaas/guides/user-guide/migration-vmware-esxi"}}');var r=i(74848),n=i(28453);const d={sidebar_label:"User Guide",sidebar_position:50},o="User Guide",a={},u=[];function c(e){const s={h1:"h1",header:"header",...(0,n.R)(),...e.components};return(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"user-guide",children:"User Guide"})})}function l(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,s,i)=>{i.d(s,{R:()=>d,x:()=>o});var t=i(96540);const r={},n=t.createContext(r);function d(e){const s=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),t.createElement(n.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dc218a96.6ba7c083.js b/assets/js/dc218a96.6ba7c083.js new file mode 100644 index 0000000000..d9cf357584 --- /dev/null +++ b/assets/js/dc218a96.6ba7c083.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[63935],{92497:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>c,metadata:()=>n,toc:()=>p});const n=JSON.parse('{"id":"operating-scs/components/status-page-api/docs/contribute","title":"Contribute","description":"Contributions are welcome at SovereignCloudStack/status-page-api.","source":"@site/docs/04-operating-scs/components/status-page-api/docs/contribute.md","sourceDirName":"04-operating-scs/components/status-page-api/docs","slug":"/operating-scs/components/status-page-api/docs/contribute","permalink":"/docs/operating-scs/components/status-page-api/docs/contribute","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-api/docs/contribute.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Example requests","permalink":"/docs/operating-scs/components/status-page-api/docs/example-requests"},"next":{"title":"Deployment","permalink":"/docs/category/deployment"}}');var o=s(74848),a=s(28453);const c={},r="Contribute",i={},p=[];function u(t){const e={a:"a",h1:"h1",header:"header",p:"p",...(0,a.R)(),...t.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(e.header,{children:(0,o.jsx)(e.h1,{id:"contribute",children:"Contribute"})}),"\n",(0,o.jsxs)(e.p,{children:["Contributions are welcome at ",(0,o.jsx)(e.a,{href:"https://github.com/SovereignCloudStack/status-page-api",children:"SovereignCloudStack/status-page-api"}),"."]})]})}function d(t={}){const{wrapper:e}={...(0,a.R)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>c,x:()=>r});var n=s(96540);const o={},a=n.createContext(o);function c(t){const e=n.useContext(a);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function r(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(o):t.components||o:c(t.components),n.createElement(a.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/dc8e8e39.7b411376.js b/assets/js/dc8e8e39.7b411376.js new file mode 100644 index 0000000000..b96c0d2e49 --- /dev/null +++ b/assets/js/dc8e8e39.7b411376.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[10488],{95102:t=>{t.exports=JSON.parse('{"tag":{"label":"community","permalink":"/blog/tags/community","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/community","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/dcae780a.12089a91.js b/assets/js/dcae780a.12089a91.js new file mode 100644 index 0000000000..784624f4fc --- /dev/null +++ b/assets/js/dcae780a.12089a91.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[62350],{76318:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>d,metadata:()=>s,toc:()=>i});const s=JSON.parse('{"id":"scs-0118-w1-example-impacts-of-failure-scenarios","title":"SCS Taxonomy of Failsafe Levels: Examples of Failure Cases and their impact on IaaS and KaaS resources","description":"Examples of the impact from certain failure scenarios on Cloud Resources","source":"@site/standards/scs-0118-w1-example-impacts-of-failure-scenarios.md","sourceDirName":".","slug":"/scs-0118-w1-example-impacts-of-failure-scenarios","permalink":"/standards/scs-0118-w1-example-impacts-of-failure-scenarios","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Taxonomy of Failsafe Levels: Examples of Failure Cases and their impact on IaaS and KaaS resources","type":"Supplement","track":"IaaS","status":"Draft","supplements":["scs-0118-v1-taxonomy-of-failsafe-levels.md"]},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels"},"next":{"title":"scs-0119: Replacement of the deprecated ceph-ansible tool","permalink":"/standards/iaas/scs-0119"}}');var n=r(74848),a=r(28453);const d={title:"SCS Taxonomy of Failsafe Levels: Examples of Failure Cases and their impact on IaaS and KaaS resources",type:"Supplement",track:"IaaS",status:"Draft",supplements:["scs-0118-v1-taxonomy-of-failsafe-levels.md"]},o=void 0,c={},i=[{value:"Examples of the impact from certain failure scenarios on Cloud Resources",id:"examples-of-the-impact-from-certain-failure-scenarios-on-cloud-resources",level:2},{value:"Impact on IaaS Resources (IaaS Layer)",id:"impact-on-iaas-resources-iaas-layer",level:3},{value:"Impact on Kubernetes Resources (KaaS layer)",id:"impact-on-kubernetes-resources-kaas-layer",level:3}];function l(e){const t={a:"a",admonition:"admonition",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",section:"section",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"examples-of-the-impact-from-certain-failure-scenarios-on-cloud-resources",children:"Examples of the impact from certain failure scenarios on Cloud Resources"}),"\n",(0,n.jsx)(t.p,{children:"Failure cases in Cloud deployments can be hardware related, environmental, due to software errors or human interference.\nThe following table summerizes different failure scenarios, that can occur:"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Failure Scenario"}),(0,n.jsx)(t.th,{children:"Probability"}),(0,n.jsx)(t.th,{children:"Consequences"}),(0,n.jsx)(t.th,{children:"Failsafe Level Coverage"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Disk Failure"}),(0,n.jsx)(t.td,{children:"High"}),(0,n.jsx)(t.td,{children:"Permanent data loss in this disk. Impact depends on type of lost data (data base, user data)"}),(0,n.jsx)(t.td,{children:"L1"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Host Failure (without disks)"}),(0,n.jsx)(t.td,{children:"Medium to High"}),(0,n.jsx)(t.td,{children:"Permanent loss of functionality and connectivity of host (impact depends on type of host)"}),(0,n.jsx)(t.td,{children:"L1"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Host Failure"}),(0,n.jsx)(t.td,{children:"Medium to High"}),(0,n.jsx)(t.td,{children:"Data loss in RAM and temporary loss of functionality and connectivity of host (impact depends on type of host)"}),(0,n.jsx)(t.td,{children:"L1"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Rack Outage"}),(0,n.jsx)(t.td,{children:"Medium"}),(0,n.jsx)(t.td,{children:"Outage of all nodes in rack"}),(0,n.jsx)(t.td,{children:"L2"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Network router/switch outage"}),(0,n.jsx)(t.td,{children:"Medium"}),(0,n.jsx)(t.td,{children:"Temporary loss of service, loss of connectivity, network partitioning"}),(0,n.jsx)(t.td,{children:"L2"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Loss of network uplink"}),(0,n.jsx)(t.td,{children:"Medium"}),(0,n.jsx)(t.td,{children:"Temporary loss of service, loss of connectivity"}),(0,n.jsx)(t.td,{children:"L3"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Power Outage (Data Center supply)"}),(0,n.jsx)(t.td,{children:"Medium"}),(0,n.jsx)(t.td,{children:"Temporary outage of all nodes in all racks"}),(0,n.jsx)(t.td,{children:"L3"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Fire"}),(0,n.jsx)(t.td,{children:"Medium"}),(0,n.jsx)(t.td,{children:"permanent Disk and Host loss in the affected zone"}),(0,n.jsx)(t.td,{children:"L3"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Flood"}),(0,n.jsx)(t.td,{children:"Low"}),(0,n.jsx)(t.td,{children:"permanent Disk and Host loss in the affected region"}),(0,n.jsx)(t.td,{children:"L4"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Earthquake"}),(0,n.jsx)(t.td,{children:"Very Low"}),(0,n.jsx)(t.td,{children:"permanent Disk and Host loss in the affected region"}),(0,n.jsx)(t.td,{children:"L4"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Storm/Tornado"}),(0,n.jsx)(t.td,{children:"Low"}),(0,n.jsx)(t.td,{children:"permanent Disk and Host loss in the affected region"}),(0,n.jsx)(t.td,{children:"L4"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Software bug (major)"}),(0,n.jsx)(t.td,{children:"Low"}),(0,n.jsx)(t.td,{children:"permanent loss or compromise of data that trigger the bug up to data on the whole physical machine"}),(0,n.jsx)(t.td,{children:"L3"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Software bug (minor)"}),(0,n.jsx)(t.td,{children:"High"}),(0,n.jsx)(t.td,{children:"temporary or partial loss or compromise of data"}),(0,n.jsx)(t.td,{children:"L1"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Minor operating error"}),(0,n.jsx)(t.td,{children:"High"}),(0,n.jsx)(t.td,{children:"Temporary outage"}),(0,n.jsx)(t.td,{children:"L1"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Major operating error"}),(0,n.jsx)(t.td,{children:"Low"}),(0,n.jsx)(t.td,{children:"Permanent loss of data"}),(0,n.jsx)(t.td,{children:"L3"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Cyber attack (minor)"}),(0,n.jsx)(t.td,{children:"High"}),(0,n.jsx)(t.td,{children:"permanent loss or compromise of data on affected Disk and Host"}),(0,n.jsx)(t.td,{children:"L1"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Cyber attack (major)"}),(0,n.jsx)(t.td,{children:"Medium"}),(0,n.jsx)(t.td,{children:"permanent loss or compromise of data on affected Disk and Host"}),(0,n.jsx)(t.td,{children:"L3"})]})]})]}),"\n",(0,n.jsxs)(t.p,{children:["Those failure scenarios can result in either only temporary (T) or permanent (P) loss of IaaS / KaaS resources or data.\nAdditionally, there are a lot of resources in IaaS alone that are more or less affected by these failure scenarios.\nThe following tables shows the impact ",(0,n.jsx)(t.strong,{children:"when no redundancy or failure safety measure is in place"}),", i.e., when\n",(0,n.jsx)(t.strong,{children:"not even failsafe level 1 is fulfilled"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"impact-on-iaas-resources-iaas-layer",children:"Impact on IaaS Resources (IaaS Layer)"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Resource"}),(0,n.jsx)(t.th,{children:"Disk Loss"}),(0,n.jsx)(t.th,{children:"Node Loss"}),(0,n.jsx)(t.th,{children:"Rack Loss"}),(0,n.jsx)(t.th,{children:"Power Loss"}),(0,n.jsx)(t.th,{children:"Natural Catastrophy"}),(0,n.jsx)(t.th,{children:"Cyber Threat"}),(0,n.jsx)(t.th,{children:"Software Bug"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Image"}),(0,n.jsxs)(t.td,{children:["P",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]}),(0,n.jsxs)(t.td,{children:["T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-3",id:"user-content-fnref-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"T"}),(0,n.jsxs)(t.td,{children:["P (T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-4",id:"user-content-fnref-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),")"]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"P"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Volume"}),(0,n.jsxs)(t.td,{children:["P",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]}),(0,n.jsxs)(t.td,{children:["T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-3",id:"user-content-fnref-3-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"T"}),(0,n.jsxs)(t.td,{children:["P (T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-4",id:"user-content-fnref-4-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),")"]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"P"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"User Data on RAM /CPU"}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{children:"P"}),(0,n.jsx)(t.td,{children:"P"}),(0,n.jsx)(t.td,{children:"P"}),(0,n.jsx)(t.td,{children:"P"}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"P"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"volume-based VM"}),(0,n.jsxs)(t.td,{children:["P",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]}),(0,n.jsxs)(t.td,{children:["T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-3",id:"user-content-fnref-3-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"T"}),(0,n.jsxs)(t.td,{children:["P (T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-4",id:"user-content-fnref-4-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),")"]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"P"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"ephemeral-based VM"}),(0,n.jsxs)(t.td,{children:["P",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]}),(0,n.jsx)(t.td,{children:"P"}),(0,n.jsx)(t.td,{children:"P"}),(0,n.jsx)(t.td,{children:"T"}),(0,n.jsxs)(t.td,{children:["P (T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-4",id:"user-content-fnref-4-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),")"]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"P"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Ironic-based VM"}),(0,n.jsxs)(t.td,{children:["P",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"4"})})]}),(0,n.jsx)(t.td,{children:"P"}),(0,n.jsx)(t.td,{children:"P"}),(0,n.jsx)(t.td,{children:"T"}),(0,n.jsxs)(t.td,{children:["P (T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-4",id:"user-content-fnref-4-5","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),")"]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"P"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Secret"}),(0,n.jsxs)(t.td,{children:["P",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-5","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]}),(0,n.jsxs)(t.td,{children:["T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-3",id:"user-content-fnref-3-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"T"}),(0,n.jsxs)(t.td,{children:["P (T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-4",id:"user-content-fnref-4-6","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),")"]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"P"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"network configuration (DB objects)"}),(0,n.jsxs)(t.td,{children:["P",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-6","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]}),(0,n.jsxs)(t.td,{children:["T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-3",id:"user-content-fnref-3-5","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"T"}),(0,n.jsxs)(t.td,{children:["P (T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-4",id:"user-content-fnref-4-7","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),")"]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"P"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"network connectivity (materialization)"}),(0,n.jsx)(t.td,{}),(0,n.jsxs)(t.td,{children:["T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-3",id:"user-content-fnref-3-6","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"T"}),(0,n.jsxs)(t.td,{children:["P (T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-4",id:"user-content-fnref-4-8","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),")"]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"T"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"floating IP"}),(0,n.jsxs)(t.td,{children:["P",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-7","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})]}),(0,n.jsxs)(t.td,{children:["T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-3",id:"user-content-fnref-3-7","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"T"}),(0,n.jsxs)(t.td,{children:["P (T",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-4",id:"user-content-fnref-4-9","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),")"]}),(0,n.jsx)(t.td,{children:"T/P"}),(0,n.jsx)(t.td,{children:"T"})]})]})]}),"\n",(0,n.jsx)(t.p,{children:"For some cases, this only results in temporary unavailability and cloud infrastructures usually have certain mechanisms in place to avoid data loss, like redundancy in storage backends and databases.\nSo some of these outages are easier to mitigate than others."}),"\n",(0,n.jsx)(t.h3,{id:"impact-on-kubernetes-resources-kaas-layer",children:"Impact on Kubernetes Resources (KaaS layer)"}),"\n",(0,n.jsx)(t.admonition,{type:"note",children:(0,n.jsx)(t.p,{children:"In case the KaaS layer runs on top of IaaS layer, the impacts described in the above table apply for the KaaS layer as well."})}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Resource"}),(0,n.jsx)(t.th,{children:"Disk Loss"}),(0,n.jsx)(t.th,{children:"Node Loss"}),(0,n.jsx)(t.th,{children:"Rack Loss"}),(0,n.jsx)(t.th,{children:"Power Loss"}),(0,n.jsx)(t.th,{children:"Natural Catastrophy"}),(0,n.jsx)(t.th,{children:"Cyber Threat"}),(0,n.jsx)(t.th,{children:"Software Bug"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Node"}),(0,n.jsx)(t.td,{children:"P"}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{children:"T/P"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Kubelet"}),(0,n.jsx)(t.td,{children:"T"}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{children:"T/P"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Pod"}),(0,n.jsx)(t.td,{children:"T"}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{children:"T/P"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"PVC"}),(0,n.jsx)(t.td,{children:"P"}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{children:"P"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"API Server"}),(0,n.jsx)(t.td,{children:"T"}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{children:"T/P"})]})]})]}),"\n","\n",(0,n.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,n.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,n.jsxs)(t.p,{children:["If the resource is located on that specific disk. ",(0,n.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-1-2","data-footnote-backref":"","aria-label":"Back to reference 1-2",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"2"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-1-3","data-footnote-backref":"","aria-label":"Back to reference 1-3",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"3"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-1-4","data-footnote-backref":"","aria-label":"Back to reference 1-4",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"4"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-1-5","data-footnote-backref":"","aria-label":"Back to reference 1-5",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"5"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-1-6","data-footnote-backref":"","aria-label":"Back to reference 1-6",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"6"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-1-7","data-footnote-backref":"","aria-label":"Back to reference 1-7",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"7"})]})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{id:"user-content-fn-3",children:["\n",(0,n.jsxs)(t.p,{children:["If the resource is located on that specific node. ",(0,n.jsx)(t.a,{href:"#user-content-fnref-3","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-3-2","data-footnote-backref":"","aria-label":"Back to reference 2-2",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"2"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-3-3","data-footnote-backref":"","aria-label":"Back to reference 2-3",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"3"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-3-4","data-footnote-backref":"","aria-label":"Back to reference 2-4",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"4"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-3-5","data-footnote-backref":"","aria-label":"Back to reference 2-5",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"5"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-3-6","data-footnote-backref":"","aria-label":"Back to reference 2-6",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"6"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-3-7","data-footnote-backref":"","aria-label":"Back to reference 2-7",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"7"})]})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{id:"user-content-fn-4",children:["\n",(0,n.jsxs)(t.p,{children:["In case of disks, nodes or racks are not destroyed, some data could be safed. E.g. when a fire just destroyes the power line. ",(0,n.jsx)(t.a,{href:"#user-content-fnref-4","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-4-2","data-footnote-backref":"","aria-label":"Back to reference 3-2",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"2"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-4-3","data-footnote-backref":"","aria-label":"Back to reference 3-3",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"3"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-4-4","data-footnote-backref":"","aria-label":"Back to reference 3-4",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"4"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-4-5","data-footnote-backref":"","aria-label":"Back to reference 3-5",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"5"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-4-6","data-footnote-backref":"","aria-label":"Back to reference 3-6",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"6"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-4-7","data-footnote-backref":"","aria-label":"Back to reference 3-7",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"7"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-4-8","data-footnote-backref":"","aria-label":"Back to reference 3-8",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"8"})]})," ",(0,n.jsxs)(t.a,{href:"#user-content-fnref-4-9","data-footnote-backref":"","aria-label":"Back to reference 3-9",className:"data-footnote-backref",children:["\u21a9",(0,n.jsx)(t.sup,{children:"9"})]})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{id:"user-content-fn-2",children:["\n",(0,n.jsxs)(t.p,{children:["Everything located on that specific disk. If more than one disk is used, some data could be recovered. ",(0,n.jsx)(t.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 4",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function f(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>d,x:()=>o});var s=r(96540);const n={},a=s.createContext(n);function d(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:d(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dcbc8e94.87f03815.js b/assets/js/dcbc8e94.87f03815.js new file mode 100644 index 0000000000..5bc130daeb --- /dev/null +++ b/assets/js/dcbc8e94.87f03815.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[59495],{25367:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>l,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"iaas/guides/configuration-guide/loadbalancer","title":"Loadbalancer","description":"The settings of the following section rely on the mechanisms of Kolla-Ansible,","source":"@site/docs/02-iaas/guides/configuration-guide/loadbalancer.md","sourceDirName":"02-iaas/guides/configuration-guide","slug":"/iaas/guides/configuration-guide/loadbalancer","permalink":"/docs/iaas/guides/configuration-guide/loadbalancer","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/loadbalancer.md","tags":[],"version":"current","sidebarPosition":20,"frontMatter":{"sidebar_label":"Loadbalancer","sidebar_position":20},"sidebar":"docs","previous":{"title":"Proxy","permalink":"/docs/iaas/guides/configuration-guide/proxy"},"next":{"title":"Ceph","permalink":"/docs/iaas/guides/configuration-guide/ceph"}}');var a=i(74848),s=i(28453);const l={sidebar_label:"Loadbalancer",sidebar_position:20},r="Loadbalancer",o={},c=[{value:"IP addresses & FQDNs",id:"ip-addresses--fqdns",level:2},{value:"TLS certificates",id:"tls-certificates",level:2},{value:"General procedure",id:"general-procedure",level:2},{value:"Self-signed certificates",id:"self-signed-certificates",level:3},{value:"Generating TLS certificates with Let\u2019s Encrypt",id:"generating-tls-certificates-with-lets-encrypt",level:3},{value:"Second Loadbalancer",id:"second-loadbalancer",level:2},{value:"ProxySQL",id:"proxysql",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"loadbalancer",children:"Loadbalancer"})}),"\n",(0,a.jsxs)(n.p,{children:["The settings of the following section rely on the mechanisms of Kolla-Ansible,\ntherefore it's a good idea to consult the ",(0,a.jsx)(n.a,{href:"https://docs.openstack.org/kolla-ansible/latest/admin/tls.html",children:"upstream documentation"}),"\nfor finding out details which are not covered by this documentation."]}),"\n",(0,a.jsx)(n.h2,{id:"ip-addresses--fqdns",children:"IP addresses & FQDNs"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:"kolla_internal_vip_address: 192.168.16.9\nkolla_external_vip_address: 192.168.16.254\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:"kolla_internal_fqdn: api-int.testbed.osism.xyz\nkolla_external_fqdn: api.testbed.osism.xyz\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"hosts_additional_entries:\n api-int.testbed.osism.xyz: 192.168.16.9\n api.testbed.osism.xyz: 192.168.16.254\n"})}),"\n",(0,a.jsx)(n.h2,{id:"tls-certificates",children:"TLS certificates"}),"\n",(0,a.jsx)(n.admonition,{type:"warning",children:(0,a.jsx)(n.p,{children:"To avoid unnecessary additional work and debugging, it is recommended that you configure TLS with the intended target\nconfiguration of the specific environment before executing the initial rollout procedures."})}),"\n",(0,a.jsx)(n.p,{children:"Changes to the configuration of TLS (i.e. enable or disable) or fully qualified domain names (FQDNs) will\nresult in new URLs (with and without the https prefix).\nThese addresses are often stored in the Openstack database on initial deployment and cannot\nbe updated by simply modifying the configuration repository and performing an additional rollout."}),"\n",(0,a.jsx)(n.p,{children:"In the case of self-signed certificates, the CA certificate must be distributed to all participating\nhttps clients in the correct dependency order and in a manner appropriate to the associated Openstack service."}),"\n",(0,a.jsx)(n.p,{children:"As a result, at a minimum, the involved Ansible Plays must be run in the appropriate order, and not all Ansible Plays\nare designed to to handle all possible configuration transitions on their own."}),"\n",(0,a.jsx)(n.h2,{id:"general-procedure",children:"General procedure"}),"\n",(0,a.jsx)(n.p,{children:"To enable TLS encryption the following steps are needed."}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"Activate tls encryption for both endpoints"}),"\n"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"To enable external TLS encryption:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'kolla_enable_tls_external: "yes"\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"To enable internal TLS encryption:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'kolla_enable_tls_internal: "yes"\n'})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.ol,{start:"2",children:["\n",(0,a.jsx)(n.li,{children:"Add the combined server certificate and private key to the following locations in the configuration repository:"}),"\n"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["private key & certificates for ",(0,a.jsx)(n.code,{children:"kolla_external_fqdn"}),": ",(0,a.jsx)(n.code,{children:"environments/kolla/certificates/haproxy.pem"})]}),"\n",(0,a.jsxs)(n.li,{children:["private key & certificates for ",(0,a.jsx)(n.code,{children:"kolla_internal_fqdn"}),": ",(0,a.jsx)(n.code,{children:"environments/kolla/certificates/haproxy-internal.pem"})]}),"\n"]}),"\n",(0,a.jsxs)(n.ol,{start:"3",children:["\n",(0,a.jsxs)(n.li,{children:["Encrypt the certificates using ansible vault:","\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"make ansible_vault_edit FILE=environments/kolla/certificates/haproxy.pem\nmake ansible_vault_edit FILE=environments/kolla/certificates/haproxy-internal.pem\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["Add the changes to the Git repository","\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:'git add environments/kolla/certificates/haproxy.pem \\\n environments/kolla/certificates/haproxy-internal.pem \\\n environments/kolla/configuration.yml\n\ngit commit -m "Add new certificates" environments/kolla/certificates/haproxy.pem \\\n environments/kolla/certificates/haproxy-internal.pem \\\n environments/kolla/configuration.yml\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["Rollout changes","\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply loadbalancer\n"})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"self-signed-certificates",children:"Self-signed certificates"}),"\n",(0,a.jsx)(n.p,{children:"OSISM supports the usage of self-signed certificates with a custom CA i.e if you\nare running a test installation or for interim purposes."}),"\n",(0,a.jsx)(n.p,{children:"Two certificate files are required to use TLS securely with authentication,\nwhich will be provided by your custom Certificate Authority:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"the server certificate with private key"}),"\n",(0,a.jsx)(n.li,{children:"the CA certificate with any intermediate certificates"}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The following procedure describes the preparation tasks for the CA, which is later followed\nby the ",(0,a.jsx)(n.a,{href:"#general-procedure",children:"general procedure"})," described above."]}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Import custom CA"}),"\n",(0,a.jsxs)(n.p,{children:["Any custom CA can be added via the ",(0,a.jsx)(n.code,{children:"certificates_ca"})," parameter.\nThis is already done in the bootstrap of the nodes."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"certificates_ca:\n - name: custom.crt\n certificate: |\n -----BEGIN CERTIFICATE-----\n [...]\n -----END CERTIFICATE-----\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Manager service"}),"\n",(0,a.jsxs)(n.p,{children:["The local environment variable ",(0,a.jsx)(n.code,{children:"REQUESTS_CA_BUNDLE"})," must be set explicitly so that\nthe manager service knows the custom CA in all necessary places."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/configuration.yml"',children:"manager_environment_extra:\n REQUESTS_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Use in OpenStack"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Add the custom CA to the configuration repository in the directory ",(0,a.jsx)(n.code,{children:"environments/kolla/certificates/ca"})," with the same\nname like in step 1"]}),"\n",(0,a.jsxs)(n.li,{children:["Configure the custom CA to be copied to the OpenStack containers","\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/configuration.yml"',children:'kolla_copy_ca_into_containers: "yes"\nopenstack_cacert: /etc/ssl/certs/ca-certificates.crt\n'})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Import the ca certificate to all nodes so that the custom CA is known everywhere and the self-signed certificates are accepted as valid."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply certificates\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Execute all steps in the ",(0,a.jsx)(n.a,{href:"#general-procedure",children:"general procedure"})," above"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"generating-tls-certificates-with-lets-encrypt",children:"Generating TLS certificates with Let\u2019s Encrypt"}),"\n",(0,a.jsx)(n.p,{children:"Using Let's encrypt certificates is a good alternative to traditional certificate authorities and\ngreatly simplifies the administration of TLS certificates."}),"\n",(0,a.jsxs)(n.p,{children:["For a working Let's Encrypt configuration, the API endpoints (configured by ",(0,a.jsx)(n.code,{children:"kolla_internal_fqdn"})," and ",(0,a.jsx)(n.code,{children:"kolla_external_fqdn"}),")\nmust be accessible from the internet."]}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Activate Let's Encrypt tls encryption for both endpoints"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'enable_letsencrypt: "yes"\nletsencrypt_email: "<The email used for registration and recovery contact>"\nkolla_enable_tls_external: "yes"\nkolla_enable_tls_internal: "yes"\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Rollout changes"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply loadbalancer\n"})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["For more details about this topic, we recommend the ",(0,a.jsx)(n.a,{href:"https://docs.openstack.org/kolla-ansible/latest/admin/tls.html#generating-tls-certificates-with-let-s-encrypt",children:"offical kolla-ansible documentation"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"second-loadbalancer",children:"Second Loadbalancer"}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsx)(n.p,{children:"This feature is available from OSISM 7.0.5."})}),"\n",(0,a.jsxs)(n.p,{children:["With OSISM, it is possible to manage any number of independent loadbalancers via a single OSISM\nmanager service using sub-environments. A sub environment is basically nothing more than another directory\nbelow the ",(0,a.jsx)(n.code,{children:"environments"})," directory of the configuration repository with a special name."]}),"\n",(0,a.jsxs)(n.p,{children:["A sub-environment for an additional loadbalancer always has the name ",(0,a.jsx)(n.code,{children:"kolla.NAME"})," as the loadbalancer\nis provided as part of Kolla. The ",(0,a.jsx)(n.code,{children:"kolla.NAME"})," directory in the configuration repository then contains\nthe ",(0,a.jsx)(n.code,{children:"configuration.yml"}),", ",(0,a.jsx)(n.code,{children:"images.yml"})," and ",(0,a.jsx)(n.code,{children:"secrets.yml"})," files as usual."]}),"\n",(0,a.jsx)(n.p,{children:"The following directories and files are also required in a sub-environment for a loadbalancer."}),"\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{style:{textAlign:"left"},children:"File"}),(0,a.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{style:{textAlign:"left"},children:(0,a.jsx)(n.code,{children:"certificates/ca/custom.crt"})}),(0,a.jsx)(n.td,{style:{textAlign:"left"},children:"The file is optional. If a custom CA is used, it must be added here."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{style:{textAlign:"left"},children:(0,a.jsx)(n.code,{children:"certificates/haproxy-internal.pem"})}),(0,a.jsx)(n.td,{style:{textAlign:"left"},children:"SSL certificate to be used."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{style:{textAlign:"left"},children:(0,a.jsx)(n.code,{children:"files/overlays/haproxy/services.d/haproxy.cfg"})}),(0,a.jsx)(n.td,{style:{textAlign:"left"},children:"HAProxy configuration to be used on the loadbalancer."})]})]})]}),"\n",(0,a.jsxs)(n.p,{children:["In this example, a sub-environment ",(0,a.jsx)(n.code,{children:"kolla.external"})," is created, which is used for an outward facing\nloadbalancer that only offers certain API services."]}),"\n",(0,a.jsxs)(n.p,{children:["In comparison to the normal ",(0,a.jsx)(n.code,{children:"kolla"})," environment, the groups to be used must be overwritten for a\nKolla sub-environment. In this case, one group is defined: ",(0,a.jsx)(n.code,{children:"kolla.external.loadbalancer"}),". It is\nrecommended to base the name of the groups on the name of the sub-environments."]}),"\n",(0,a.jsxs)(n.p,{children:["The group ",(0,a.jsx)(n.code,{children:"kolla.external.loadbalancer"})," is added to the global inventory in the ",(0,a.jsx)(n.code,{children:"10-custom"})," file.\nIn this example, ",(0,a.jsx)(n.code,{children:"testbed-node-2.testbed.osism.xyz"})," is used for the second loadbalancer."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/10-custom"',children:"[kolla.external.loadbalancer]\ntestbed-node-2.testbed.osism.xyz\n"})}),"\n",(0,a.jsxs)(n.p,{children:["It is also important to ensure that the nodes used for the second loadbalancer are not included in\nthe ",(0,a.jsx)(n.code,{children:"loadbalancer"})," group. This can be checked with ",(0,a.jsx)(n.code,{children:"osism get hosts -l loadbalancer"}),". If the nodes of\nthe second loadbalancer are also listed there, the ",(0,a.jsx)(n.code,{children:"loadbalancer"})," group in the ",(0,a.jsx)(n.code,{children:"99-overwrite"})," file of\nthe global inventory must be overwritten. In this example, the ",(0,a.jsx)(n.code,{children:"loadbalaner"})," group is overwritten so\nthat only ",(0,a.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz"})," and ",(0,a.jsx)(n.code,{children:"testbed-node-1.testbed.osism.xyz"})," are left in the\n",(0,a.jsx)(n.code,{children:"loadbalancer"})," group."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/99-overwrite"',children:"[loadbalancer]\ntestbed-node-0.testbed.osism.xyz\ntestbed-node-1.testbed.osism.xyz\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Furthermore, in a Kolla sub-environment that is only used for a loadbalancer, only a few additional\nparameters are required in the ",(0,a.jsx)(n.code,{children:"configuration.yml"})," file."]}),"\n",(0,a.jsxs)(n.p,{children:["Don't get confused, only the ",(0,a.jsx)(n.code,{children:"kolla_*internal*"})," parameters and the ",(0,a.jsx)(n.code,{children:"haproxy-internal.pem"})," file are used\nhere in the example. This is because we only want to configure one virtual IP address on the external\nloadbalancer and the loadbalancer managed by Kolla has the internal IP address by default. It is therefore\nnot possible with Kolla to use only the ",(0,a.jsx)(n.code,{children:"kolla_*external*"})," parameters as an additional virtual IP address\nwith default values would then be configured by default."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla.external/configuration.yml"',children:'---\n##########################################################\n# hosts\n\nhosts_kolla_all: kolla.external.loadbalancer\nhosts_kolla_loadbalancer: kolla.external.loadbalancer\n\n##########################################################\n# docker\n\ndocker_namespace: osism\n\n##########################################################\n# loadbalancer\n\nkolla_internal_vip_address: 192.168.24.200\nkolla_internal_fqdn: api.testbed.osism.com\nkolla_enable_tls_internal: "yes"\n\n# Required if a custom CA is used.\nkolla_copy_ca_into_containers: "yes"\n'})}),"\n",(0,a.jsx)(n.p,{children:"At the moment it is only possible to deploy the loadbalancer itself with its own configuration. It is currently\nnot possible to use the integrated service configurations of Kolla itself (Nova, Cinder, ..) on an additional\nloadbalancer. This will be possible in the future."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply --sub external loadbalancer-without-service-config\n"})}),"\n",(0,a.jsx)(n.h2,{id:"proxysql",children:"ProxySQL"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'enable_proxysql: "yes"\n'})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>l,x:()=>r});var t=i(96540);const a={},s=t.createContext(a);function l(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:l(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dcf2f717.7fe3db53.js b/assets/js/dcf2f717.7fe3db53.js new file mode 100644 index 0000000000..97a91f5fca --- /dev/null +++ b/assets/js/dcf2f717.7fe3db53.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[78981],{35352:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>l,frontMatter:()=>i,metadata:()=>o,toc:()=>u});const o=JSON.parse('{"id":"container/guides/guide1","title":"Guide 1","description":"TODO","source":"@site/docs/03-container/guides/guide1.md","sourceDirName":"03-container/guides","slug":"/container/guides/guide1","permalink":"/docs/container/guides/guide1","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/guides/guide1.md","tags":[],"version":"current","frontMatter":{}}');var r=t(74848),s=t(28453);const i={},c="Guide 1",d={},u=[];function a(e){const n={h1:"h1",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"guide-1",children:"Guide 1"})}),"\n",(0,r.jsx)(n.p,{children:"TODO"})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>c});var o=t(96540);const r={},s=o.createContext(r);function i(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dd4ba739.4776bdf3.js b/assets/js/dd4ba739.4776bdf3.js new file mode 100644 index 0000000000..8397aba92e --- /dev/null +++ b/assets/js/dd4ba739.4776bdf3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[27425],{31097:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"scs-0116-w1-key-manager-implementation-testing","title":"SCS Key Manager Standard: Implementation and Testing Notes","description":"Implementation","source":"@site/standards/scs-0116-w1-key-manager-implementation-testing.md","sourceDirName":".","slug":"/scs-0116-w1-key-manager-implementation-testing","permalink":"/standards/scs-0116-w1-key-manager-implementation-testing","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Key Manager Standard: Implementation and Testing Notes","type":"Supplement","track":"IaaS","status":"Draft","supplements":["scs-0116-v1-key-manager-standard.md"]},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0116-v1-key-manager-standard"},"next":{"title":"scs-0117: Volume Backup Functionality","permalink":"/standards/iaas/scs-0117"}}');var s=n(74848),i=n(28453);const r={title:"SCS Key Manager Standard: Implementation and Testing Notes",type:"Supplement",track:"IaaS",status:"Draft",supplements:["scs-0116-v1-key-manager-standard.md"]},o=void 0,c={},l=[{value:"Implementation",id:"implementation",level:2},{value:"Policies",id:"policies",level:3},{value:"Automated Tests",id:"automated-tests",level:2},{value:"Implementation",id:"implementation-1",level:3},{value:"Manual Tests",id:"manual-tests",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",section:"section",sup:"sup",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"implementation",children:"Implementation"}),"\n",(0,s.jsxs)(t.p,{children:["A Key Manager service can have different backends.\nFor Barbican these are called Plugins.\nThe standard plugin is ",(0,s.jsx)(t.code,{children:"simple_crypto"}),", which has the Master-KEK written in the Barbican config file.\nIn that case the Master-KEK needs additional protection.\nWhen the ",(0,s.jsx)(t.code,{children:"simple_crypto"})," plugin is used, securing the Master-KEK can be achieved through protection of the Barbican config e.g. through running Barbican in an enclave."]}),"\n",(0,s.jsx)(t.p,{children:"Another option to secure the Master-KEK would be using an HSM with a corresponding plugin in Barbican.\nIn that case the Master-KEK will be stored inside the HSM and encryption and decryption of the Project-KEKs will also happen in the HSM.\nThere are also software HSMs available, that should be tested for their integration into the Barbican workflow."}),"\n",(0,s.jsxs)(t.p,{children:["Other Plugins in Barbican are the KMIP plugin and Vault",(0,s.jsx)(t.sup,{children:(0,s.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),".\nThey are storing the keys differently and CSPs need to make sure, that the access to the keys is configured securely."]}),"\n",(0,s.jsx)(t.admonition,{type:"tip",children:(0,s.jsx)(t.p,{children:"Barbican supports deploying out-of-tree drivers what enables operators to satisfy their specific needs."})}),"\n",(0,s.jsx)(t.h3,{id:"policies",children:"Policies"}),"\n",(0,s.jsxs)(t.p,{children:["When a Key Manager is used, but it uses the old policies and does not enforce the new secure RBAC work, the roles between Barbican and the other IaaS services differ.\nThis can be done with a small change in the policy.yaml file. The ",(0,s.jsx)(t.code,{children:"creator"})," has to be defined like this:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:'"creator": "role:member"\n'})}),"\n",(0,s.jsx)(t.h2,{id:"automated-tests",children:"Automated Tests"}),"\n",(0,s.jsx)(t.p,{children:"The check for the presence of a Key Manager is done with a test script, that checks the presence of a Key Manager service in the catalog endpoint of Openstack.\nThis check can eventually be moved to the checks for the mandatory an supported service/API list, in case of a promotion of the Key Manager to the mandatory list."}),"\n",(0,s.jsx)(t.h3,{id:"implementation-1",children:"Implementation"}),"\n",(0,s.jsxs)(t.p,{children:["The script ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/key-manager/check-for-key-manager.py",children:(0,s.jsx)(t.code,{children:"check-for-key-manager.py"})}),"\nconnects to OpenStack and performs the checks described in this section."]}),"\n",(0,s.jsx)(t.h2,{id:"manual-tests",children:"Manual Tests"}),"\n",(0,s.jsx)(t.p,{children:"It is not possible to check a deployment for a correctly protected Master KEK automatically from the outside.\nEven audits would need to check the complete host for plain-text keys.\nCSPs are responsible for ensuring the protection of the Master KEK and they have to make at least their architecture for that protection auditable."}),"\n","\n",(0,s.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,s.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://docs.openstack.org/barbican/latest/install/barbican-backend.html",children:"Barbican Plugins"})," ",(0,s.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var a=n(96540);const s={},i=a.createContext(s);function r(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dd5128a0.7c8eac03.js b/assets/js/dd5128a0.7c8eac03.js new file mode 100644 index 0000000000..6569015103 --- /dev/null +++ b/assets/js/dd5128a0.7c8eac03.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[37568],{59670:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"iaas/guides/configuration-guide/rookify","title":"Configure Rookify: Migrate from Ceph-Ansible to Rook (Technical Preview)","description":"Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime.","source":"@site/docs/02-iaas/guides/configuration-guide/rookify.md","sourceDirName":"02-iaas/guides/configuration-guide","slug":"/iaas/guides/configuration-guide/rookify","permalink":"/docs/iaas/guides/configuration-guide/rookify","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/rookify.md","tags":[],"version":"current","sidebarPosition":31,"frontMatter":{"sidebar_label":"Rookify (technical preview)","sidebar_position":31},"sidebar":"docs","previous":{"title":"Ceph via Rook (technical preview)","permalink":"/docs/iaas/guides/configuration-guide/rook"},"next":{"title":"Commons","permalink":"/docs/iaas/guides/configuration-guide/commons/"}}');var s=n(74848),r=n(28453);const t={sidebar_label:"Rookify (technical preview)",sidebar_position:31},a="Configure Rookify: Migrate from Ceph-Ansible to Rook (Technical Preview)",l={},c=[{value:"Config.yaml",id:"configyaml",level:2},{value:"Parameters",id:"parameters",level:3},{value:"General",id:"general",level:4},{value:"Logging",id:"logging",level:4},{value:"Ceph",id:"ceph",level:4},{value:"SSH",id:"ssh",level:4},{value:"Kubernetes",id:"kubernetes",level:4},{value:"Migration_modules",id:"migration_modules",level:4}];function d(e){const o={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.header,{children:(0,s.jsx)(o.h1,{id:"configure-rookify-migrate-from-ceph-ansible-to-rook-technical-preview",children:"Configure Rookify: Migrate from Ceph-Ansible to Rook (Technical Preview)"})}),"\n",(0,s.jsx)(o.admonition,{type:"warning",children:(0,s.jsxs)(o.p,{children:["Rookify is developed to migrate from Ceph-Ansible to Rook ",(0,s.jsx)(o.em,{children:"in place"})," and ",(0,s.jsx)(o.em,{children:"without downtime"}),".\nNevertheless, it is ",(0,s.jsx)(o.strong,{children:"strongly advised"})," to test Rookify in a controlled environment first, such as the ",(0,s.jsx)(o.a,{href:"https://github.com/osism/testbed",children:"OSISM testbed"}),". Additionally ensure that precautionary backups are made and all other necessary safety measures are in place."]})}),"\n",(0,s.jsxs)(o.p,{children:["For a condensed summary of the information covered here, refer to the ",(0,s.jsx)(o.a,{href:"https://github.com/SovereignCloudStack/rookify",children:"Rookify GitHub repository"}),"."]}),"\n",(0,s.jsx)(o.h2,{id:"configyaml",children:"Config.yaml"}),"\n",(0,s.jsxs)(o.p,{children:["The primary configuration file for Rookify is ",(0,s.jsx)(o.code,{children:"config.yaml"}),". The repository includes an example file for general use, as well as one specifically tailored for OSISM based setups:"]}),"\n",(0,s.jsxs)(o.ul,{children:["\n",(0,s.jsx)(o.li,{children:(0,s.jsx)(o.a,{href:"https://github.com/SovereignCloudStack/rookify/blob/main/config.example.yaml",children:"config.example.yaml"})}),"\n",(0,s.jsx)(o.li,{children:(0,s.jsx)(o.a,{href:"https://github.com/SovereignCloudStack/rookify/blob/main/config.example.osism.yaml",children:"config.example.osism.yaml"})}),"\n"]}),"\n",(0,s.jsx)(o.h3,{id:"parameters",children:"Parameters"}),"\n",(0,s.jsx)(o.h4,{id:"general",children:"General"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="config.example.yaml"',children:"general:\n machine_pickle_file: data.pickle\n"})}),"\n",(0,s.jsxs)(o.p,{children:["The ",(0,s.jsx)(o.code,{children:"general"})," section allows for the optional definition of a pickle file, which saves the state of the migration as serialized objects on disk. The pickle file can be named as desired."]}),"\n",(0,s.jsx)(o.h4,{id:"logging",children:"Logging"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="config.example.yaml"',children:'logging:\n level: INFO # level at which logging should start\n format:\n time: "%Y-%m-%d %H:%M.%S" # other example: "iso"\n renderer: console # or: json\n'})}),"\n",(0,s.jsxs)(o.p,{children:["The ",(0,s.jsx)(o.code,{children:"logging"})," section allows for specification of ",(0,s.jsx)(o.code,{children:"structlog"}),". The ",(0,s.jsx)(o.code,{children:"level"})," parameter can be set to any Python ",(0,s.jsx)(o.a,{href:"https://docs.python.org/3/library/logging.html#logging-levels",children:"log-levels"}),", such as ",(0,s.jsx)(o.code,{children:"NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAl"}),", but using ",(0,s.jsx)(o.code,{children:"INFO"})," is recommended."]}),"\n",(0,s.jsx)(o.h4,{id:"ceph",children:"Ceph"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="config.example.yaml"',children:"\nceph:\n config: ./.ceph/ceph.conf\n keyring: ./.ceph/ceph.client.admin.keyring\n"})}),"\n",(0,s.jsxs)(o.p,{children:["The ceph section specifies the paths for the ",(0,s.jsx)(o.code,{children:"ceph.conf"})," and ",(0,s.jsx)(o.code,{children:"ceph.client.admin.keyring"})," files on the target system (the system where Ceph-Ansible needs to be migrated to Rook)."]}),"\n",(0,s.jsx)(o.h4,{id:"ssh",children:"SSH"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="config.example.yaml"',children:"# specify the correct path to the private key\nssh:\n private_key: /home/USER/.ssh/cloud.private\n hosts:\n testbed-node-0:\n address: 192.168.16.10\n user: dragon\n testbed-node-1:\n address: 192.168.16.11\n user: dragon\n testbed-node-2:\n address: 192.168.16.12\n user: dragon\n"})}),"\n",(0,s.jsxs)(o.p,{children:["The ",(0,s.jsx)(o.code,{children:"ssh"})," section specifies the ",(0,s.jsx)(o.code,{children:"private_key"})," and ",(0,s.jsx)(o.code,{children:"hosts"}),". The ",(0,s.jsx)(o.code,{children:"hosts"})," section includes hostnames or aliases (e.g. ",(0,s.jsx)(o.code,{children:"testbed-node-0"}),"), their IP addresses (e.g., for VPN connections, IPs starting with ",(0,s.jsx)(o.code,{children:"192.186..."}),"), and the user for login. If you are using the OSISM testbed, ensure the private key does not contain any extra strings like ",(0,s.jsx)(o.code,{children:"EOF"}),". The keys must be 'clean' to avoid connection errors."]}),"\n",(0,s.jsx)(o.h4,{id:"kubernetes",children:"Kubernetes"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="config.example.yaml"',children:"\nkubernetes:\n config: ./k8s/config\n"})}),"\n",(0,s.jsxs)(o.p,{children:["The ",(0,s.jsx)(o.code,{children:"kubernetes"})," section specifies the Kubernetes configuration (e.g. if you use ",(0,s.jsx)(o.code,{children:"kubectl"}),", this is usually located in ",(0,s.jsx)(o.code,{children:"~/.kube/config"}),") for Rookify's Kubernetes library. Rookify needs to connect to the Kubernetes cluster on the target systems to use Rook."]}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="config.example.yaml"',children:"rook:\n cluster:\n name: osism-ceph\n namespace: rook-ceph\n ceph:\n image: quay.io/ceph/ceph:v18.2.1\n"})}),"\n",(0,s.jsxs)(o.p,{children:["The ",(0,s.jsx)(o.code,{children:"rook"})," sections requires information about the Rook installation on the target system. For the ",(0,s.jsx)(o.code,{children:"cluster"}),", Rookify needs the cluster name and namespace. Additionally, Rookify requires the Ceph version being used, i.e., the image version of the Ceph container."]}),"\n",(0,s.jsx)(o.admonition,{type:"note",children:(0,s.jsx)(o.p,{children:"Rookify does not install Rook for you. You need to provide a running Rook installation, i.e. a Rook Operator, on your target system."})}),"\n",(0,s.jsx)(o.p,{children:"For OSISM-specific migrations, Rookify needs additional information, such as the respective labels for the Rook resources:"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="config.example.osism.yaml"',children:"rook:\n cluster:\n name: osism-ceph\n namespace: rook-ceph\n mds_placement_label: node-role.osism.tech/rook-mds\n mgr_placement_label: node-role.osism.tech/rook-mgr\n mon_placement_label: node-role.osism.tech/rook-mon\n osd_placement_label: node-role.osism.tech/rook-osd\n rgw_placement_label: node-role.osism.tech/rook-rgw\n ceph:\n image: quay.io/ceph/ceph:v18.2.1\n"})}),"\n",(0,s.jsx)(o.h4,{id:"migration_modules",children:"Migration_modules"}),"\n",(0,s.jsx)(o.pre,{children:(0,s.jsx)(o.code,{className:"language-yaml",metastring:'title="config.example.yaml"',children:"migration_modules:\n- analyze_ceph\n- create_rook_cluster\n- migrate_mons\n- migrate_osds\n- migrate_osd_pools\n- migrate_mds\n- migrate_mds_pools\n- migrate_mgrs\n- migrate_rgws\n- migrate_rgw_pools\n"})}),"\n",(0,s.jsxs)(o.p,{children:["Rookify uses a modular structure, allowing you to migrate various parts of Ceph-Ansible to Rook. The ",(0,s.jsx)(o.code,{children:"migration_modules"})," section specifies which modules need to be executed for the migration. Rookify contains more modules \u2014 check the ",(0,s.jsx)(o.a,{href:"https://github.com/SovereignCloudStack/rookify/tree/main/src/rookify/modules",children:(0,s.jsx)(o.code,{children:"src/rookify/module"})})," directory to see the currently implemented modules."]}),"\n",(0,s.jsx)(o.admonition,{type:"note",children:(0,s.jsxs)(o.p,{children:["Many modules depend on each other. For example, the ",(0,s.jsx)(o.code,{children:"analyze_ceph"})," module will automatically run with all other modules, so\nthere is no need to specify it. It\u2019s included here for clarity."]})})]})}function h(e={}){const{wrapper:o}={...(0,r.R)(),...e.components};return o?(0,s.jsx)(o,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,o,n)=>{n.d(o,{R:()=>t,x:()=>a});var i=n(96540);const s={},r=i.createContext(s);function t(e){const o=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function a(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),i.createElement(r.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dd9a4eb2.c92386f4.js b/assets/js/dd9a4eb2.c92386f4.js new file mode 100644 index 0000000000..b268d07599 --- /dev/null +++ b/assets/js/dd9a4eb2.c92386f4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[19512],{41346:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Guides","slug":"/category/guides-1","permalink":"/docs/category/guides-1","sidebar":"docs","navigation":{"previous":{"title":"Tools Description","permalink":"/docs/operating-scs/components/automated-pentesting-kaas/tools"},"next":{"title":"Guide: Setting up openstack-health-monitor on Debian 12","permalink":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/de6833f9.60fa945f.js b/assets/js/de6833f9.60fa945f.js new file mode 100644 index 0000000000..1c24e14de0 --- /dev/null +++ b/assets/js/de6833f9.60fa945f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[42309],{98423:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>a,contentTitle:()=>r,default:()=>l,frontMatter:()=>c,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"iaas/guides/configuration-guide/commons/resolvconf","title":"Resolvconf","description":"With the osism.commons.resolvconf role, it is possible to manage the used DNS servers on a node.","source":"@site/docs/02-iaas/guides/configuration-guide/commons/resolvconf.md","sourceDirName":"02-iaas/guides/configuration-guide/commons","slug":"/iaas/guides/configuration-guide/commons/resolvconf","permalink":"/docs/iaas/guides/configuration-guide/commons/resolvconf","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/resolvconf.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Resolvconf"},"sidebar":"docs","previous":{"title":"Packages","permalink":"/docs/iaas/guides/configuration-guide/commons/packages"},"next":{"title":"Services","permalink":"/docs/iaas/guides/configuration-guide/commons/services"}}');var i=s(74848),t=s(28453);const c={sidebar_label:"Resolvconf"},r="Resolvconf",a={},d=[];function u(e){const o={code:"code",h1:"h1",header:"header",p:"p",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(o.header,{children:(0,i.jsx)(o.h1,{id:"resolvconf",children:"Resolvconf"})}),"\n",(0,i.jsxs)(o.p,{children:["With the ",(0,i.jsx)(o.code,{children:"osism.commons.resolvconf"})," role, it is possible to manage the used DNS servers on a node."]})]})}function l(e={}){const{wrapper:o}={...(0,t.R)(),...e.components};return o?(0,i.jsx)(o,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,o,s)=>{s.d(o,{R:()=>c,x:()=>r});var n=s(96540);const i={},t=n.createContext(i);function c(e){const o=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function r(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),n.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/df35cf96.26d44ffc.js b/assets/js/df35cf96.26d44ffc.js new file mode 100644 index 0000000000..ff5c7a6ee5 --- /dev/null +++ b/assets/js/df35cf96.26d44ffc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[36831],{51629:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"iaas/guides/configuration-guide/commons/services","title":"Services","description":"With the osism.commons.services role, it is possible to manage services on a node","source":"@site/docs/02-iaas/guides/configuration-guide/commons/services.md","sourceDirName":"02-iaas/guides/configuration-guide/commons","slug":"/iaas/guides/configuration-guide/commons/services","permalink":"/docs/iaas/guides/configuration-guide/commons/services","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/services.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Services"},"sidebar":"docs","previous":{"title":"Resolvconf","permalink":"/docs/iaas/guides/configuration-guide/commons/resolvconf"},"next":{"title":"SSH Config","permalink":"/docs/iaas/guides/configuration-guide/commons/sshconfig"}}');var r=i(74848),t=i(28453);const o={sidebar_label:"Services"},c="Services",a={},d=[{value:"Start and enable required services",id:"start-and-enable-required-services",level:2},{value:"Note on services that should be deactivated",id:"note-on-services-that-should-be-deactivated",level:2}];function l(e){const s={admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"services",children:"Services"})}),"\n",(0,r.jsxs)(s.p,{children:["With the ",(0,r.jsx)(s.code,{children:"osism.commons.services"})," role, it is possible to manage services on a node\nin a general form. This allows you to either activate any services or indicate that\nspecific services are running and should be deactivated."]}),"\n",(0,r.jsx)(s.h2,{id:"start-and-enable-required-services",children:"Start and enable required services"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:'services_required_default:\n - cron\nservices_required_extra: []\nservices_required: "{{ services_required_default + services_required_extra }}"\n'})}),"\n",(0,r.jsx)(s.admonition,{type:"note",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"services_required"})," should not be overwritten. Use ",(0,r.jsx)(s.code,{children:"services_required_extra"})," to add extra services."]})}),"\n",(0,r.jsx)(s.h2,{id:"note-on-services-that-should-be-deactivated",children:"Note on services that should be deactivated"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:'services_warning_default:\n - nscd\nservices_warning_extra: []\nservices_warning: "{{ services_warning_default + services_warning_extra }}"\n'})}),"\n",(0,r.jsx)(s.admonition,{type:"note",children:(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"services_warning"})," should not be overwritten. Use ",(0,r.jsx)(s.code,{children:"services_warning_extra"})," to add extra services."]})})]})}function u(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,s,i)=>{i.d(s,{R:()=>o,x:()=>c});var n=i(96540);const r={},t=n.createContext(r);function o(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dfce392e.dc8ba0a6.js b/assets/js/dfce392e.dc8ba0a6.js new file mode 100644 index 0000000000..87f8fc8311 --- /dev/null +++ b/assets/js/dfce392e.dc8ba0a6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[84398],{93851:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"scs-0401-v1-status-page-reference-implementation-decision","title":"Status page reference implementation decision","description":"Introduction","source":"@site/standards/scs-0401-v1-status-page-reference-implementation-decision.md","sourceDirName":".","slug":"/scs-0401-v1-status-page-reference-implementation-decision","permalink":"/standards/scs-0401-v1-status-page-reference-implementation-decision","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Status page reference implementation decision","type":"Decision Record","status":"Draft","track":"Ops"},"sidebar":"standards","previous":{"title":"scs-0401: Status page reference implementation decision","permalink":"/standards/ops/scs-0401"},"next":{"title":"scs-0402: Status page OpenAPI decision","permalink":"/standards/ops/scs-0402"}}');var a=n(74848),i=n(28453);const o={title:"Status page reference implementation decision",type:"Decision Record",status:"Draft",track:"Ops"},r=void 0,c={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Decision",id:"decision",level:2},{value:"Programming Language",id:"programming-language",level:3},{value:"Database",id:"database",level:3}];function l(e){const t={a:"a",h2:"h2",h3:"h3",p:"p",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,a.jsxs)(t.p,{children:["For the reference implementation of the status page API defined by the ",(0,a.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi",children:"OpenAPI spec"})," some decision should be made to which technology to be used and why."]}),"\n",(0,a.jsx)(t.p,{children:"A reference implementation should be of use to most of the intended group, but is not necessarily applicable for every use case."}),"\n",(0,a.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,a.jsx)(t.p,{children:"For a reference implementation to be of any use, some common and widely used technologies should be used, so it's useful to most of the intended user group."}),"\n",(0,a.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,a.jsx)(t.h3,{id:"programming-language",children:"Programming Language"}),"\n",(0,a.jsxs)(t.p,{children:["The status page application consists of an api server as well as a frontend. For implementing the ",(0,a.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-api",children:"api server"}),", which is generated from the ",(0,a.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi",children:"OpenAPI spec"}),", ",(0,a.jsx)(t.a,{href:"https://go.dev/",children:"Go"})," was chosen, because of maturity and widespread usage as industry standard. Go, in particular, is a modern programming language and is commonly used in network and cloud computing environments."]}),"\n",(0,a.jsx)(t.h3,{id:"database",children:"Database"}),"\n",(0,a.jsxs)(t.p,{children:["As database, ",(0,a.jsx)(t.a,{href:"https://www.postgresql.org/",children:"PostgreSQL"})," was chosen, since it is a mature, well-known database. PostgreSQL can be run in various environments from small setups to scaled setups.\nFurthermore, PostgreSQL is a very healthy project with an active community and a solid license. It easily passed the ",(0,a.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Drafts/OSS-Health.md",children:"SCS OSS health check"}),"."]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var s=n(96540);const a={},i=s.createContext(a);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e0719818.791bd268.js b/assets/js/e0719818.791bd268.js new file mode 100644 index 0000000000..138000c83f --- /dev/null +++ b/assets/js/e0719818.791bd268.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[15220],{68669:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"community"}')}}]); \ No newline at end of file diff --git a/assets/js/e0c197a4.04fb4e06.js b/assets/js/e0c197a4.04fb4e06.js new file mode 100644 index 0000000000..d96230acd9 --- /dev/null +++ b/assets/js/e0c197a4.04fb4e06.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[17051],{72799:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"iaas/guides/concept-guide/components/ironic","title":"Ironic","description":"OpenStack Ironic is a project that provides Baremetal as a Service (BMaaS), enabling the","source":"@site/docs/02-iaas/guides/concept-guide/components/ironic.md","sourceDirName":"02-iaas/guides/concept-guide/components","slug":"/iaas/guides/concept-guide/components/ironic","permalink":"/docs/iaas/guides/concept-guide/components/ironic","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/ironic.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Gardener","permalink":"/docs/iaas/guides/concept-guide/components/gardener"},"next":{"title":"K3S","permalink":"/docs/iaas/guides/concept-guide/components/k3s"}}');var t=i(74848),r=i(28453);const o={},s="Ironic",c={},l=[{value:"Lifecycle Management of Ironic in OSISM",id:"lifecycle-management-of-ironic-in-osism",level:2}];function d(e){const n={h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"ironic",children:"Ironic"})}),"\n",(0,t.jsx)(n.p,{children:"OpenStack Ironic is a project that provides Baremetal as a Service (BMaaS), enabling the\nprovisioning and management of physical machines in a cloud-like manner. Unlike traditional\nvirtualization, where virtual machines run on top of a hypervisor, BMaaS allows users to\ndirectly manage and utilize physical hardware, offering the full performance and isolation\nof dedicated servers."}),"\n",(0,t.jsx)(n.p,{children:"Key benefits of OpenStack Ironic:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Hardware Provisioning: Ironic automates the provisioning of physical servers, including\nthe deployment of operating systems and configuration of hardware settings. This automation\nstreamlines the setup process, reducing the time and effort required to bring new servers\nonline."}),"\n",(0,t.jsx)(n.li,{children:"Integration with OpenStack: Ironic integrates seamlessly with other OpenStack services,\nsuch as Nova for compute management, Neutron for networking, and Glance for image services.\nThis integration allows users to manage both virtual and baremetal resources through a\nunified OpenStack dashboard."}),"\n",(0,t.jsx)(n.li,{children:"Support for Multiple Hardware Drivers: Ironic supports a wide range of hardware through\nvarious drivers, including IPMI, Redfish, and vendor-specific drivers. This flexibility\nensures compatibility with a diverse set of hardware platforms and management interfaces."}),"\n",(0,t.jsx)(n.li,{children:"Resource Management and Scheduling: Ironic leverages OpenStack\u2019s scheduling capabilities\nto manage the allocation of physical servers, ensuring optimal utilization of hardware\nresources. Users can request specific hardware configurations and Ironic will match these\nrequests with available resources."}),"\n",(0,t.jsx)(n.li,{children:"Provisioning States: Ironic manages the lifecycle of baremetal nodes through various\nprovisioning states, such as enroll, available, active, and maintenance. This state\nmanagement ensures that hardware is correctly tracked and managed throughout its lifecycle."}),"\n",(0,t.jsx)(n.li,{children:"Network Integration: Ironic integrates with Neutron to provide networking services for\nbaremetal nodes, including support for VLANs, flat networks, and more complex networking\nsetups. This integration ensures that baremetal nodes can be seamlessly integrated into\nexisting network topologies."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"By utilizing OpenStack Ironic, organizations can leverage the benefits of BMaaS,\nproviding users with the performance and control of physical hardware while maintaining\nthe flexibility and scalability of cloud infrastructure. This approach is particularly\nbeneficial for workloads that require high performance, low latency, or specific hardware\nconfigurations that are not achievable with virtual machines."}),"\n",(0,t.jsx)(n.h2,{id:"lifecycle-management-of-ironic-in-osism",children:"Lifecycle Management of Ironic in OSISM"})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>s});var a=i(96540);const t={},r=a.createContext(t);function o(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e10bed52.df61e061.js b/assets/js/e10bed52.df61e061.js new file mode 100644 index 0000000000..42bd7d87bb --- /dev/null +++ b/assets/js/e10bed52.df61e061.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2925],{36667:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>p,frontMatter:()=>r,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"operating-scs/components/status-page-deployment/docs/configuration","title":"Configure status page","description":"A minimal configuration of the status page deployment.","source":"@site/docs/04-operating-scs/components/status-page-deployment/docs/configuration.md","sourceDirName":"04-operating-scs/components/status-page-deployment/docs","slug":"/operating-scs/components/status-page-deployment/docs/configuration","permalink":"/docs/operating-scs/components/status-page-deployment/docs/configuration","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-deployment/docs/configuration.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Configuration","permalink":"/docs/category/configuration"},"next":{"title":"kind - Local development environment","permalink":"/docs/operating-scs/components/status-page-deployment/docs/kind"}}');var o=t(74848),i=t(28453);const r={},d="Configure status page",a={},c=[{value:"API server",id:"api-server",level:2},{value:"Database",id:"database",level:2},{value:"Dex",id:"dex",level:2},{value:"Oathkeeper",id:"oathkeeper",level:2},{value:"Web frontend",id:"web-frontend",level:2},{value:"Ingress",id:"ingress",level:2},{value:"Issuer",id:"issuer",level:2}];function l(e){const n={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"configure-status-page",children:"Configure status page"})}),"\n",(0,o.jsx)(n.p,{children:"A minimal configuration of the status page deployment."}),"\n",(0,o.jsx)(n.h2,{id:"api-server",children:"API server"}),"\n",(0,o.jsxs)(n.p,{children:["Configure the allowed origins via ",(0,o.jsx)(n.code,{children:"api/api.env"})," to include the domain from the web frontend. CORS origins need to include the protocol, too. Example: ",(0,o.jsx)(n.code,{children:"https://frontend.<your-domain>"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"database",children:"Database"}),"\n",(0,o.jsxs)(n.p,{children:["Set a password for the database at ",(0,o.jsx)(n.code,{children:"database/db-secrets.env"})," and configure the connection string in ",(0,o.jsx)(n.code,{children:"api/api-secrets.env"})]}),"\n",(0,o.jsx)(n.h2,{id:"dex",children:"Dex"}),"\n",(0,o.jsxs)(n.p,{children:["Dex needs a GitHub Applications Client Secret in ",(0,o.jsx)(n.code,{children:"dex/dex-secrets.env"}),", please refer to ",(0,o.jsx)(n.code,{children:"dex/dex-secrets-example.env"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Set the ",(0,o.jsx)(n.code,{children:"issuer"})," and ",(0,o.jsx)(n.code,{children:"redirectURI"})," at ",(0,o.jsx)(n.code,{children:"dex/config.yaml"})," to your domain. Keep in mind, that dex needs it's own domain or subdomain."]}),"\n",(0,o.jsxs)(n.p,{children:["Other Dex related configuration is located in ",(0,o.jsx)(n.code,{children:"dex/dex.env"}),", ",(0,o.jsx)(n.code,{children:"web/web-secrets.env"})," and ",(0,o.jsx)(n.code,{children:"web/web.env"})," to fill the configuration template ",(0,o.jsx)(n.code,{children:"dex/config.yaml"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"oathkeeper",children:"Oathkeeper"}),"\n",(0,o.jsxs)(n.p,{children:["Set your domain in ",(0,o.jsx)(n.code,{children:"oathkeeper/config.yaml"})," at ",(0,o.jsx)(n.code,{children:"authenticators.jwt.config.jwks_urls"})," and ",(0,o.jsx)(n.code,{children:"authenticators.jwt.config.trusted_issuers"})," to point towards Dex."]}),"\n",(0,o.jsx)(n.h2,{id:"web-frontend",children:"Web frontend"}),"\n",(0,o.jsxs)(n.p,{children:["In ",(0,o.jsx)(n.code,{children:"web/web.env"})," configure the OIDC authentication callback and the API url. The API URL must be pointing to the external domain, not the K8s service name."]}),"\n",(0,o.jsx)(n.h2,{id:"ingress",children:"Ingress"}),"\n",(0,o.jsxs)(n.p,{children:["In ",(0,o.jsx)(n.code,{children:"ingress.yaml"})," set your domains for Dex, Oathkeeper and the web frontend respectively. Oathkeeper acts as the auth proxy for the API server. Exposing the API server directly, opens up the possibility of unsupervised write actions."]}),"\n",(0,o.jsx)(n.h2,{id:"issuer",children:"Issuer"}),"\n",(0,o.jsxs)(n.p,{children:["Set the e-mail address in ",(0,o.jsx)(n.code,{children:"issuer.yaml"})," to your desired e-mail address."]})]})}function p(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>d});var s=t(96540);const o={},i=s.createContext(o);function r(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e1e9b906.d09031b2.js b/assets/js/e1e9b906.d09031b2.js new file mode 100644 index 0000000000..8f043ca775 --- /dev/null +++ b/assets/js/e1e9b906.d09031b2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6934],{63158:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>u,frontMatter:()=>c,metadata:()=>o,toc:()=>i});const o=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/develop/develop","title":"Contributing","description":"Develop Cluster Stack Operator","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/develop/develop.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/develop","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/develop/","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/develop/develop.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Troubleshooting","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot"},"next":{"title":"Overview","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview"}}');var n=s(74848),r=s(28453);const c={},l="Contributing",a={},i=[{value:"Develop Cluster Stack Operator",id:"develop-cluster-stack-operator",level:2},{value:"Setting Tilt up",id:"setting-tilt-up",level:2},{value:"Developing with Tilt",id:"developing-with-tilt",level:2}];function d(e){const t={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"contributing",children:"Contributing"})}),"\n",(0,n.jsx)(t.h2,{id:"develop-cluster-stack-operator",children:"Develop Cluster Stack Operator"}),"\n",(0,n.jsx)(t.p,{children:"Developing our operator is quite easy. First, you need to install some base requirements: Docker and Go. Second, you need to configure your environment variables. Then you can start developing with the local Kind cluster and the Tilt UI to create a workload cluster that is already pre-configured."}),"\n",(0,n.jsx)(t.h2,{id:"setting-tilt-up",children:"Setting Tilt up"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"Install Docker and Go. We expect you to run on a Linux OS."}),"\n",(0,n.jsxs)(t.li,{children:["Create an ",(0,n.jsx)(t.code,{children:".envrc"})," file and specify the values you need. See the .envrc.sample for details."]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"developing-with-tilt",children:"Developing with Tilt"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Tilt",src:s(26737).A+"",width:"2550",height:"1327"})}),"\n",(0,n.jsx)(t.p,{children:"Operator development requires a lot of iteration, and the \u201cbuild, tag, push, update deployment\u201d workflow can be very tedious. Tilt makes this process much simpler by watching for updates and automatically building and deploying them. To build a kind cluster and to start Tilt, run:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"make tilt-up\n"})}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsxs)(t.p,{children:["To access the Tilt UI please go to: ",(0,n.jsx)(t.code,{children:"http://localhost:10351"})]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"You should make sure that everything in the UI looks green. If not, e.g. if the clusterstack has not been synced, you can trigger the Tilt workflow again. In case of the clusterstack button this might be necessary, as it cannot be applied right after startup of the cluster and fails. Tilt unfortunately does not include a waiting period."}),"\n",(0,n.jsx)(t.p,{children:"If everything is green, then you can already check for your clusterstack that has been deployed. You can use a tool like k9s to have a look at the management cluster and its custom resources."}),"\n",(0,n.jsx)(t.p,{children:"Example:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"\u276f kubectl get clusterstacks -A\nNAMESPACE NAME PROVIDER CLUSTERSTACK K8S CHANNEL AUTOSUBSCRIBE USABLE LATEST AGE REASON MESSAGE\ncluster clusterstack docker ferrol 1.27 stable false v2 docker-ferrol-1-27-v2 | v1.27.3 4m52s\n"})}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"\u276f kubectl get clusterstackreleases.clusterstack.x-k8s.io -A\nNAMESPACE NAME K8S VERSION READY AGE REASON MESSAGE\ncluster docker-ferrol-1-27-v2 v1.27.3 true 7m51s\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The above cluster stack was downloaded from ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks/releases",children:"SovereignCloudStack/cluster-stacks"})]}),"\n",(0,n.jsxs)(t.p,{children:['In case your clusterstack shows that it is ready, you can deploy a workload cluster. This could be done through the Tilt UI, by pressing the button in the top right corner "Create Workload Cluster". This triggers the ',(0,n.jsx)(t.code,{children:"make create-workload-cluster-docker"}),", which uses the environment variables and the cluster-template."]}),"\n",(0,n.jsx)(t.p,{children:"In case you want to change some code, you can do so and see that Tilt triggers on save. It will update the container of the operator automatically."}),"\n",(0,n.jsxs)(t.p,{children:["If you want to change something in your ClusterStack or Cluster custom resources, you can have a look at ",(0,n.jsx)(t.code,{children:".cluster.yaml"})," and ",(0,n.jsx)(t.code,{children:".clusterstack.yaml"}),", which Tilt uses."]}),"\n",(0,n.jsx)(t.p,{children:'To tear down the workload cluster press the "Delete Workload Cluster" button. After a few minutes the resources should be deleted.'}),"\n",(0,n.jsx)(t.p,{children:"To tear down the kind cluster, use:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"$ make delete-bootstrap-cluster\n"})}),"\n",(0,n.jsxs)(t.p,{children:["If you have any trouble finding the right command, then you can use ",(0,n.jsx)(t.code,{children:"make help"})," to get a list of all available make targets."]})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},26737:(e,t,s)=>{s.d(t,{A:()=>o});const o=s.p+"assets/images/tilt-5733a9f1bf4409991abcf6d96d8a13bd.png"},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>l});var o=s(96540);const n={},r=o.createContext(n);function c(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e20b631f.8f51fa59.js b/assets/js/e20b631f.8f51fa59.js new file mode 100644 index 0000000000..9619aca055 --- /dev/null +++ b/assets/js/e20b631f.8f51fa59.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[80272],{27720:(n,e,a)=>{a.r(e),a.d(e,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/manila","title":"Manila","description":"* Manila admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/manila.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/manila","permalink":"/docs/iaas/guides/configuration-guide/openstack/manila","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/manila.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Manila"},"sidebar":"docs","previous":{"title":"Magnum","permalink":"/docs/iaas/guides/configuration-guide/openstack/magnum"},"next":{"title":"Neutron","permalink":"/docs/iaas/guides/configuration-guide/openstack/neutron"}}');var t=a(74848),s=a(28453);const o={sidebar_label:"Manila"},r="Manila",c={},l=[];function d(n){const e={a:"a",h1:"h1",header:"header",li:"li",ul:"ul",...(0,s.R)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"manila",children:"Manila"})}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:"https://docs.openstack.org/manila/latest/admin/index.html",children:"Manila admin guide"})}),"\n",(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:"https://docs.openstack.org/manila/latest/configuration/index.html",children:"Manila configuration guide"})}),"\n",(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:"https://docs.openstack.org/manila/latest/configuration/shared-file-systems/samples/manila.conf.html",children:"Manila configuration reference"})}),"\n"]})]})}function u(n={}){const{wrapper:e}={...(0,s.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(d,{...n})}):d(n)}},28453:(n,e,a)=>{a.d(e,{R:()=>o,x:()=>r});var i=a(96540);const t={},s=i.createContext(t);function o(n){const e=i.useContext(s);return i.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function r(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(t):n.components||t:o(n.components),i.createElement(s.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/e24c1f8d.f1046400.js b/assets/js/e24c1f8d.f1046400.js new file mode 100644 index 0000000000..df3bc0e4f9 --- /dev/null +++ b/assets/js/e24c1f8d.f1046400.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[84480],{87392:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>d,contentTitle:()=>c,default:()=>x,frontMatter:()=>r,metadata:()=>l,toc:()=>o});const l=JSON.parse('{"id":"iaas/guides/configuration-guide/commons/sysctl","title":"Sysctl","description":"With the osism.commons.sysctl role, it is possible to manage the attributes of the kernel","source":"@site/docs/02-iaas/guides/configuration-guide/commons/sysctl.md","sourceDirName":"02-iaas/guides/configuration-guide/commons","slug":"/iaas/guides/configuration-guide/commons/sysctl","permalink":"/docs/iaas/guides/configuration-guide/commons/sysctl","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/sysctl.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Sysctl"},"sidebar":"docs","previous":{"title":"SSH Config","permalink":"/docs/iaas/guides/configuration-guide/commons/sshconfig"},"next":{"title":"Timezone","permalink":"/docs/iaas/guides/configuration-guide/commons/timezone"}}');var n=s(74848),i=s(28453);const r={sidebar_label:"Sysctl"},c="Sysctl",d={},o=[];function a(t){const e={a:"a",code:"code",h1:"h1",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"sysctl",children:"Sysctl"})}),"\n",(0,n.jsxs)(e.p,{children:["With the ",(0,n.jsx)(e.code,{children:"osism.commons.sysctl"})," role, it is possible to manage the attributes of the kernel\nvia ",(0,n.jsx)(e.a,{href:"https://en.wikipedia.org/wiki/Sysctl",children:"sysctl"})," on a node."]}),"\n",(0,n.jsxs)(e.p,{children:["The following defaults are set via the parameter ",(0,n.jsx)(e.code,{children:"sysctl_defaults"}),"."]}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"Group"}),(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"Attribute"}),(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"elasticsearch"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"vm.max_map_count"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"262144"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_keepalive_time"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"6"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_keepalive_intvl"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"3"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_keepalive_probes"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"3"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"net.core.wmem_max"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"16777216"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"net.core.rmem_max"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"16777216"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_fin_timeout"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"20"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_tw_reuse"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"1"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"net.core.somaxconn"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"4096"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_syncookies"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"0"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_max_syn_backlog"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"8192"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"generic"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"vm.swappiness"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"1"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"compute"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"net.netfilter.nf_conntrack_max"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"1048576"})]})]})]}),"\n",(0,n.jsxs)(e.p,{children:["The ",(0,n.jsx)(e.code,{children:"sysctl_extra"})," parameter can be used to set your own parameters or overwrite existing\nparameters in the defaults."]}),"\n",(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:"language-yaml",metastring:'title="Set attribute fs.inotify.max_user_instances to 256 for all nodes in group generic"',children:"sysctl_extra:\n generic:\n - name: fs.inotify.max_user_instances\n value: 256\n"})})]})}function x(t={}){const{wrapper:e}={...(0,i.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(a,{...t})}):a(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>r,x:()=>c});var l=s(96540);const n={},i=l.createContext(n);function r(t){const e=l.useContext(i);return l.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(n):t.components||n:r(t.components),l.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/e2bda29d.8b3be122.js b/assets/js/e2bda29d.8b3be122.js new file mode 100644 index 0000000000..6135032ca1 --- /dev/null +++ b/assets/js/e2bda29d.8b3be122.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[96162],{51302:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"iaas/guides/user-guide/openstack/install-instance-from-iso","title":"Install instance from ISO image","description":"While in general it is considered best practice to create instances from existing or specially crafted images, sometimes it is necessary to install an instance using a traditional installer packaged in an ISO image.","source":"@site/docs/02-iaas/guides/user-guide/openstack/install-instance-from-iso.md","sourceDirName":"02-iaas/guides/user-guide/openstack","slug":"/iaas/guides/user-guide/openstack/install-instance-from-iso","permalink":"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/openstack/install-instance-from-iso.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Install instance from ISO image"},"sidebar":"docs","previous":{"title":"OpenStack","permalink":"/docs/iaas/guides/user-guide/openstack/"},"next":{"title":"Client","permalink":"/docs/iaas/guides/user-guide/openstack/openstackclient"}}');var i=t(74848),a=t(28453);const o={sidebar_label:"Install instance from ISO image"},r="Install instance from ISO image",c={},l=[{value:"Upload the ISO image",id:"upload-the-iso-image",level:2},{value:"Creating the instance",id:"creating-the-instance",level:2},{value:"Using nova local storage",id:"using-nova-local-storage",level:3},{value:"Using boot from volume",id:"using-boot-from-volume",level:3},{value:"Install the created instance from the uploaded ISO",id:"install-the-created-instance-from-the-uploaded-iso",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"install-instance-from-iso-image",children:"Install instance from ISO image"})}),"\n",(0,i.jsxs)(n.p,{children:["While in general it is considered best practice to create instances from existing or specially crafted images, sometimes it is necessary to install an instance using a traditional installer packaged in an ISO image.\nOne way to do this in OpenStack is to leverage the ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/user/rescue.html",children:"instance rescue mechanism"}),", which allows to boot an instance from another image while providing access to the instances storage."]}),"\n",(0,i.jsx)(n.h2,{id:"upload-the-iso-image",children:"Upload the ISO image"}),"\n",(0,i.jsx)(n.p,{children:"If the required ISO image is not available in the image store yet upload it first:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'PATH_TO_ISO_IMAGE=""\nIMAGE_NAME=""\nopenstack image create \\\n --disk-format iso \\\n --file $PATH_TO_ISO_IMAGE \\\n --property hw_rescue_device=disk \\\n --property hw_rescue_bus=virtio \\\n $IMAGE_NAME\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"hw_rescue_device"})," and ",(0,i.jsx)(n.code,{children:"hw_rescue_bus"})," properties may be omitted if you do not intent to create an instance from a boot volume."]}),"\n",(0,i.jsx)(n.h2,{id:"creating-the-instance",children:"Creating the instance"}),"\n",(0,i.jsx)(n.h3,{id:"using-nova-local-storage",children:"Using nova local storage"}),"\n",(0,i.jsx)(n.p,{children:"Create an instance with a blank local boot device, e.g.:"}),"\n",(0,i.jsxs)(n.p,{children:["Until ",(0,i.jsx)(n.a,{href:"https://bugs.launchpad.net/nova/+bug/2090926",children:"this bug"})," is fixed, one cannot create an instance with a blank local boot device. As a workaround create an unbootable dummy image first, e.g.:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'DUMMY_IMAGE_NAME="dummy"\ndd if=/dev/zero of="$DUMMY_IMAGE_NAME" bs=1k count=1\nopenstack image create \\\n --file "$DUMMY_IMAGE_NAME" \\\n "$DUMMY_IMAGE_NAME"\nrm "$DUMMY_IMAGE_NAME"\n'})}),"\n",(0,i.jsx)(n.p,{children:"Create the instance:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'INSTANCE_NAME=""\nFLAVOR=""\nopenstack server create \\\n --flavor "$FLAVOR" \\\n --image "$DUMMY_IMAGE_NAME" \\\n --no-network \\\n "$INSTANCE_NAME"\n'})}),"\n",(0,i.jsx)(n.p,{children:"Once the bug is fixed the instance may be created directly:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'INSTANCE_NAME=""\nFLAVOR=""\nopenstack server create \\\n --flavor "$FLAVOR" \\\n --block-device "source_type=blank,destination_type=local,guest_format=raw,boot_index=0" \\\n --no-network \\\n "$INSTANCE_NAME"\n'})}),"\n",(0,i.jsx)(n.h3,{id:"using-boot-from-volume",children:"Using boot from volume"}),"\n",(0,i.jsx)(n.p,{children:"Create an instance with a blank boot volume"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'INSTANCE_NAME=""\nFLAVOR=""\nBOOT_VOLUME_SIZE=""\nopenstack server create \\\n --flavor "$FLAVOR" \\\n --block-device "source_type=blank,destination_type=volume,volume_size=$BOOT_VOLUME_SIZE,boot_index=0" \\\n --no-network \\\n "$INSTANCE_NAME"\n'})}),"\n",(0,i.jsx)(n.p,{children:"Set the created volume to bootable"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"openstack volume set --bootable $(openstack server show $INSTANCE_NAME -f json -c attached_volumes | jq -r '.attached_volumes | first | .id')\n"})}),"\n",(0,i.jsx)(n.h2,{id:"install-the-created-instance-from-the-uploaded-iso",children:"Install the created instance from the uploaded ISO"}),"\n",(0,i.jsx)(n.p,{children:"Use the rescue mechanism to boot the ISO, e.g.:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"openstack server rescue \\\n --image $IMAGE_NAME \\\n $INSTANCE_NAME\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Wait for the instance to be rescued. This will take a moment, as a soft reboot is tried before issueing a hard reboot.\nWatch the instance ",(0,i.jsx)(n.code,{children:"task_state"})," and ",(0,i.jsx)(n.code,{children:"status"})," to see the latter change from ",(0,i.jsx)(n.code,{children:"ACTIVE"})," to ",(0,i.jsx)(n.code,{children:"RESCUE"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"watch openstack server show $INSTANCE_NAME -f value -c status -c task_state\n"})}),"\n",(0,i.jsx)(n.p,{children:"Start the installation procedure, e.g. by opening the instance's console"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"openstack console url show $INSTANCE_NAME\n"})}),"\n",(0,i.jsx)(n.p,{children:"The instances storage device should be available as a destination for the installation.\nRebooting the instance in this state will lead to the rescue image being booted again.\nTo boot the instance from its freshly provisioned boot device unrescue the instance:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"openstack server unrescue $INSTANCE_NAME\n"})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e2dcdabe.13cfa021.js b/assets/js/e2dcdabe.13cfa021.js new file mode 100644 index 0000000000..15e74169c6 --- /dev/null +++ b/assets/js/e2dcdabe.13cfa021.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[91099],{40093:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>c,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"scs-XXXX-vN-decision-record-template","title":"_Descriptive title_","description":"\x3c!---","source":"@site/standards/scs-XXXX-vN-decision-record-template.md","sourceDirName":".","slug":"/scs-XXXX-vN-decision-record-template","permalink":"/standards/scs-XXXX-vN-decision-record-template","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"_Descriptive title_","type":"Decision Record","status":"Draft","track":"Global"}}');var i=n(74848),o=n(28453);const c={title:"_Descriptive title_",type:"Decision Record",status:"Draft",track:"Global"},r=void 0,a={},d=[{value:"Abstract",id:"abstract",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Context",id:"context",level:2},{value:"Decision",id:"decision",level:2},{value:"Consequences",id:"consequences",level:2},{value:"Related Documents",id:"related-documents",level:2}];function l(e){const t={h2:"h2",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"abstract",children:"Abstract"}),"\n",(0,i.jsx)(t.p,{children:"Very short introduction about the topic of this document."}),"\n",(0,i.jsx)(t.h2,{id:"terminology",children:"Terminology"}),"\n",(0,i.jsx)(t.p,{children:"Example (abbr. Ex)\nThis is the description for an example terminology."}),"\n",(0,i.jsx)(t.h2,{id:"context",children:"Context"}),"\n",(0,i.jsx)(t.p,{children:"What is the issue that we're seeing that is motivating this decision or change?"}),"\n",(0,i.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(t.p,{children:"What is the decision that we're proposing and/or doing?\nShould also include reasoning for this decision"}),"\n",(0,i.jsx)(t.h2,{id:"consequences",children:"Consequences"}),"\n",(0,i.jsx)(t.p,{children:"What becomes easier or more difficult to do because of this change?"}),"\n",(0,i.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,i.jsx)(t.p,{children:"Related Documents, OPTIONAL"})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>r});var s=n(96540);const i={},o=s.createContext(i);function c(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e34f30ed.9713edfa.js b/assets/js/e34f30ed.9713edfa.js new file mode 100644 index 0000000000..62206abb09 --- /dev/null +++ b/assets/js/e34f30ed.9713edfa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[96211],{31412:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"operating-scs/components/monitoring/docs/iaas","title":"IaaS monitoring (experimental)","description":"This component is marked as experimental, and it is not part of the reference SCS installation available","source":"@site/docs/04-operating-scs/components/monitoring/docs/iaas.md","sourceDirName":"04-operating-scs/components/monitoring/docs","slug":"/operating-scs/components/monitoring/docs/iaas","permalink":"/docs/operating-scs/components/monitoring/docs/iaas","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/iaas.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Infrastructure service endpoints","permalink":"/docs/operating-scs/components/monitoring/docs/infrastructure_services"},"next":{"title":"KaaS monitoring (experimental)","permalink":"/docs/operating-scs/components/monitoring/docs/kaas"}}');var o=n(74848),r=n(28453);const a={},i="IaaS monitoring (experimental)",l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Local environment use case - KinD/K3s cluster deployed locally",id:"local-environment-use-case---kindk3s-cluster-deployed-locally",level:3},{value:"KinD",id:"kind",level:4},{value:"K3s",id:"k3s",level:4},{value:"OSISM use case - K3s cluster in OSISM deployment",id:"osism-use-case---k3s-cluster-in-osism-deployment",level:3},{value:"Deploy IaaS monitoring components",id:"deploy-iaas-monitoring-components",level:2},{value:"OpenStack",id:"openstack",level:3},{value:"Prometheus metrics and alerts",id:"prometheus-metrics-and-alerts",level:4},{value:"Grafana dashboards",id:"grafana-dashboards",level:4},{value:"Update the SCS monitoring deployment",id:"update-the-scs-monitoring-deployment",level:4},{value:"Access the OpenStack dashboard",id:"access-the-openstack-dashboard",level:4},{value:"Ceph",id:"ceph",level:3},{value:"Prometheus metrics and alerts",id:"prometheus-metrics-and-alerts-1",level:4},{value:"Grafana dashboards",id:"grafana-dashboards-1",level:4},{value:"Update the SCS monitoring deployment",id:"update-the-scs-monitoring-deployment-1",level:4}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"iaas-monitoring-experimental",children:"IaaS monitoring (experimental)"})}),"\n",(0,o.jsxs)(s.p,{children:["This component is marked as experimental, and it is not part of the reference SCS installation available\nat ",(0,o.jsx)(s.a,{href:"https://monitoring.scs.community",children:"https://monitoring.scs.community"}),"."]}),"\n",(0,o.jsx)(s.p,{children:"IaaS monitoring currently integrates and is able to observe the following targets:"}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsx)(s.li,{children:(0,o.jsx)(s.a,{href:"#openstack",children:"OpenStack"})}),"\n",(0,o.jsx)(s.li,{children:(0,o.jsx)(s.a,{href:"#ceph",children:"Ceph"})}),"\n"]}),"\n",(0,o.jsx)(s.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsx)(s.p,{children:"To test the Monitoring of the IaaS layer we expect running Kubernetes cluster that already contains\nSCS monitoring platform."}),"\n",(0,o.jsx)(s.h3,{id:"local-environment-use-case---kindk3s-cluster-deployed-locally",children:"Local environment use case - KinD/K3s cluster deployed locally"}),"\n",(0,o.jsx)(s.h4,{id:"kind",children:"KinD"}),"\n",(0,o.jsxs)(s.p,{children:["Install the SCS monitoring solution into the KinD Kubernetes cluster following the instructions provided in\nthe ",(0,o.jsx)(s.a,{href:"/docs/operating-scs/components/monitoring/docs/quickstart",children:"quickstart guide"}),"."]}),"\n",(0,o.jsx)(s.h4,{id:"k3s",children:"K3s"}),"\n",(0,o.jsxs)(s.p,{children:["Install the SCS monitoring solution into the K3s Kubernetes cluster following the instructions provided in\nthe ",(0,o.jsx)(s.a,{href:"/docs/operating-scs/components/monitoring/docs/k3s",children:"k3s guide"}),"."]}),"\n",(0,o.jsx)(s.h3,{id:"osism-use-case---k3s-cluster-in-osism-deployment",children:"OSISM use case - K3s cluster in OSISM deployment"}),"\n",(0,o.jsxs)(s.p,{children:[(0,o.jsx)(s.a,{href:"https://osism.tech/docs/guides/deploy-guide/services/kubernetes",children:"OSISM"})," utilizes the k3s distribution of Kubernetes\nas a management cluster for the OSISM IaaS platform. This management cluster is then used as a host for\nthe SCS monitoring solution. Subsequently, the management cluster becomes an Observer cluster as it hosts\nthe SCS monitoring solution.\nFrom that point, the Observer cluster observes itself (i.e., k3s cluster control plane components and nodes) and is used\nfor observing the IaaS layer around the k3s cluster."]}),"\n",(0,o.jsxs)(s.p,{children:["In the case of the existing ",(0,o.jsx)(s.a,{href:"https://osism.tech/docs/release-notes/osism-7#703",children:"OSISM IaaS deployment >= 7.0.3"})," on\nbaremetal, ",(0,o.jsx)(s.a,{href:"https://osism.tech/docs/guides/other-guides/testbed",children:"testbed"})," or ",(0,o.jsx)(s.a,{href:"https://osism.tech/docs/guides/other-guides/cloud-in-a-box",children:"cloud in the box"}),"\nwe expect a management k3s Kubernetes cluster with the deployed SCS monitoring platform.\nIf your OSISM installation does not meet the above requirements, apply the following plays:"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"osism apply kubernetes\nosism apply kubernetes-monitoring\n"})}),"\n",(0,o.jsx)(s.h2,{id:"deploy-iaas-monitoring-components",children:"Deploy IaaS monitoring components"}),"\n",(0,o.jsx)(s.h3,{id:"openstack",children:"OpenStack"}),"\n",(0,o.jsx)(s.h4,{id:"prometheus-metrics-and-alerts",children:"Prometheus metrics and alerts"}),"\n",(0,o.jsxs)(s.p,{children:["The ",(0,o.jsx)(s.a,{href:"https://github.com/openstack-exporter",children:"OpenStack exporter for Prometheus"})," could be deployed using the SCS ",(0,o.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/openstack-exporter-helm-charts",children:"openstack-exporter-helm-chart"}),".\nThis exporter contains a bunch of ",(0,o.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/openstack-exporter-helm-charts/blob/master/charts/prometheus-openstack-exporter/templates/prometheusrule.yaml",children:"Prometheus alerts and rules"}),"\nthat are deployed together with the exporter.\nVisit the ",(0,o.jsx)(s.code,{children:"iaas/openstack-exporter-values.yaml"})," file to validate the Helm configuration options.\nEnsure valid OpenStack API credentials are set under the ",(0,o.jsx)(s.code,{children:"clouds_yaml_config"})," section. This ",(0,o.jsx)(s.strong,{children:"MUST"})," be overridden!"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:'helm upgrade --install prometheus-openstack-exporter oci://registry.scs.community/openstack-exporter/prometheus-openstack-exporter \\\n --version 0.4.5 \\\n -f iaas/openstack-exporter-values.yaml # --set "endpoint_type=public" --set "serviceMonitor.scrapeTimeout=1m"\n'})}),"\n",(0,o.jsxs)(s.p,{children:["Tip: If you want to test the exporter basic functionality with ",(0,o.jsx)(s.strong,{children:"public"})," OpenStack API, configure ",(0,o.jsx)(s.code,{children:"endpoint_type"}),"\nto ",(0,o.jsx)(s.code,{children:"public"})," (",(0,o.jsx)(s.code,{children:'--set "endpoint_type=public"'}),"). Note that configuring ",(0,o.jsx)(s.code,{children:"endpoint_type"})," as ",(0,o.jsx)(s.code,{children:"public"})," will result in\nincomplete functionality for the Grafana dashboard."]}),"\n",(0,o.jsxs)(s.p,{children:["Tip: Requesting and collecting metrics from the OpenStack API can be time-consuming, especially if the API is not\nperforming well. In such cases, you may observe timeouts on the Prometheus server when it tries to fetch OpenStack\nmetrics. To mitigate this, consider increasing the scrape interval to e.g. 1 minute (",(0,o.jsx)(s.code,{children:'--set "serviceMonitor.scrapeTimeout=1m"'}),")."]}),"\n",(0,o.jsx)(s.h4,{id:"grafana-dashboards",children:"Grafana dashboards"}),"\n",(0,o.jsxs)(s.p,{children:["The Grafana dashboard designed to visualize metrics collected from an OpenStack cloud through the OpenStack exporter\nis publicly available at ",(0,o.jsx)(s.a,{href:"https://grafana.com/grafana/dashboards/21085",children:"https://grafana.com/grafana/dashboards/21085"}),". Its source code is located in the\n",(0,o.jsx)(s.code,{children:"iaas/dashboards"})," directory. Feel free to import it to the Grafana via its source or ID.\nFor automatic integration into the SCS monitoring solution proceed to the next step."]}),"\n",(0,o.jsx)(s.h4,{id:"update-the-scs-monitoring-deployment",children:"Update the SCS monitoring deployment"}),"\n",(0,o.jsx)(s.p,{children:"This step deploys the Grafana dashboards and instructs the monitoring stack to add the OpenStack exporter target into the Prometheus configuration:"}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack --reset-then-reuse-values -f iaas/values-observer-iaas.yaml\n"})}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["Note: The ",(0,o.jsx)(s.code,{children:"--reset-then-reuse-values"})," option requires Helm v3.14.0 or later. Alternatively, you can use the original values\nby applying ",(0,o.jsx)(s.code,{children:"-f values-observer.yaml"}),", see full command: ",(0,o.jsx)(s.code,{children:"helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml -f iaas/values-observer-iaas.yaml"})]}),"\n"]}),"\n",(0,o.jsx)(s.h4,{id:"access-the-openstack-dashboard",children:"Access the OpenStack dashboard"}),"\n",(0,o.jsx)(s.p,{children:"At this point, you should have the ability to access the Grafana UI, and OpenStack dashboard."}),"\n",(0,o.jsx)(s.p,{children:"Log in to the Grafana UI and find the OpenStack dashboard in IaaS directory:"}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"http://localhost:30000\n"})}),"\n",(0,o.jsx)(s.p,{children:"or directly access the OpenStack dashboard:"}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"http://localhost:30000/d/openstack-overview\n"})}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["Use the following credentials:","\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["username: ",(0,o.jsx)(s.code,{children:"admin"})]}),"\n",(0,o.jsxs)(s.li,{children:["password: ",(0,o.jsx)(s.code,{children:"pass"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(s.h3,{id:"ceph",children:"Ceph"}),"\n",(0,o.jsxs)(s.p,{children:["The SCS IaaS reference implementation (OSISM) currently supports ",(0,o.jsx)(s.a,{href:"https://github.com/ceph/ceph-ansible",children:"ceph-ansible"}),"\nmethod for deploying Ceph. Support for the ",(0,o.jsx)(s.a,{href:"https://github.com/rook/rook",children:"rook operator"})," deployment method will be available ",(0,o.jsx)(s.a,{href:"https://github.com/osism/issues/issues/881",children:"soon"}),"."]}),"\n",(0,o.jsx)(s.p,{children:"This guide covers Ceph cluster monitoring for both deployment methods. While both expose the same metrics via the same\nendpoint, there are some differences in Prometheus configuration and alerts."}),"\n",(0,o.jsx)(s.h4,{id:"prometheus-metrics-and-alerts-1",children:"Prometheus metrics and alerts"}),"\n",(0,o.jsx)(s.p,{children:"Ceph contains 2 build-in sources of metrics a.k.a. exporters.\nThe Ceph exporter (introduced in Reef release of Ceph) is the main source of Ceph performance metrics. It runs as a\ndedicated daemon. This daemon runs on every Ceph cluster host and exposes a metrics end point where all the performance\ncounters exposed by all the Ceph daemons running in the host are published in the form of Prometheus metrics."}),"\n",(0,o.jsx)(s.p,{children:"The second source of metrics is the Prometheus manager module. It exposes metrics related to the whole cluster,\nbasically metrics that are not produced by individual Ceph daemons."}),"\n",(0,o.jsxs)(s.p,{children:["Read the related Ceph ",(0,o.jsx)(s.a,{href:"https://docs.ceph.com/en/reef/monitoring/#ceph-metrics",children:"docs"}),".\nSince these exporters are integrated with Ceph, deploying a third-party Ceph exporter is unnecessary."]}),"\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.strong,{children:"Prometheus alerts"})}),"\n",(0,o.jsxs)(s.p,{children:["Both Ceph deployment strategies use the ceph-mixins project as a source of alerts. The ceph-ansible and rook projects\neach maintain a rendered version of these alerts, but the rook repository contains some differences, primarily because\nrook does not use the cephadm tool as a backend.\nTherefore, find and apply one of the following commands to create a custom observer rules values file for either the\nceph-ansible or ceph-rook deployment (",(0,o.jsx)(s.a,{href:"https://github.com/mikefarah/yq/#install",children:"yq"})," tool required):"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:'# ceph-ansible\ncurl -s https://raw.githubusercontent.com/ceph/ceph/main/monitoring/ceph-mixin/prometheus_alerts.yml | \\\n yq \'{"kube-prometheus-stack": {"additionalPrometheusRulesMap": {"ceph-ansible-rules": (. + {"additionalLabels": {"prometheus_rule": "1"}})}}}\' > iaas/values-observer-ceph-rules.yaml\n\n# rook\ncurl -s https://raw.githubusercontent.com/rook/rook/master/deploy/charts/rook-ceph-cluster/prometheus/localrules.yaml | \\\n yq \'{"kube-prometheus-stack": {"additionalPrometheusRulesMap": {"ceph-rook-rules": (. + {"additionalLabels": {"prometheus_rule": "1"}})}}}\' > iaas/values-observer-ceph-rules.yaml\n'})}),"\n",(0,o.jsx)(s.h4,{id:"grafana-dashboards-1",children:"Grafana dashboards"}),"\n",(0,o.jsx)(s.p,{children:"We've tested and could recommend 2 sources of Grafana dashboards that are suitable for both Ceph deployment strategies (ansible and rook):"}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsx)(s.li,{children:(0,o.jsx)(s.a,{href:"https://rook.io/docs/rook/latest-release/Storage-Configuration/Monitoring/ceph-monitoring/?h=gra#grafana-dashboards",children:"dashboards linked in rook docs"})}),"\n",(0,o.jsxs)(s.li,{children:[(0,o.jsx)(s.a,{href:"https://github.com/ceph/ceph-mixins/tree/master/dashboards",children:"ceph-mixins dashboards"}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["Built version of ceph-mixins dashboards could be found e.g. ",(0,o.jsx)(s.a,{href:"https://github.com/ceph/ceph/tree/main/monitoring/ceph-mixin/dashboards_out",children:"here"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(s.p,{children:["We consider the dashboards created within the Rook project as a solid starting point for Ceph metrics visualization.\nIf you want to see more detailed dashboards, uncomment and use the ceph-mixin dashboards in the ",(0,o.jsx)(s.code,{children:"values-observer-ceph-rook.yaml"}),"\nor ",(0,o.jsx)(s.code,{children:"values-observer-ceph-ansible.yaml"})," file. You can use both."]}),"\n",(0,o.jsx)(s.h4,{id:"update-the-scs-monitoring-deployment-1",children:"Update the SCS monitoring deployment"}),"\n",(0,o.jsxs)(s.p,{children:["This step deploys Grafana dashboards, Prometheus rules and instruct monitoring stack to add the Ceph exporter targets into the Prometheus configuration.\nEnsure that you add the monitoring targets' IPs and ports to ",(0,o.jsx)(s.code,{children:"values-observer-ceph-ansible.yaml"})," for Ceph-ansible deployment."]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack --reset-then-reuse-values \\\n -f iaas/values-observer-ceph-rules.yaml \\\n -f iaas/values-observer-ceph-[rook|ansible].yaml # use values file for either the ceph-ansible or ceph-rook deployment\n"})}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["Note: The ",(0,o.jsx)(s.code,{children:"--reset-then-reuse-values"})," option requires Helm v3.14.0 or later. Alternatively, you can use the original values\nby applying ",(0,o.jsx)(s.code,{children:"-f values-observer.yaml"}),", see full command: ",(0,o.jsx)(s.code,{children:"helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml -f iaas/values-observer-ceph-rules.yaml -f iaas/values-observer-ceph-[rook|ansible].yaml"})]}),"\n"]})]})}function d(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>i});var t=n(96540);const o={},r=t.createContext(o);function a(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e4409f64.190e6014.js b/assets/js/e4409f64.190e6014.js new file mode 100644 index 0000000000..346a2d743d --- /dev/null +++ b/assets/js/e4409f64.190e6014.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[33559],{73330:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"iaas/guides/user-guide/migration-vmware-esxi","title":"Migrate from VMware ESXi to OpenStack","description":"This guide is an example of how to perform a manual migration from a VMware ESXi host to OpenStack.","source":"@site/docs/02-iaas/guides/user-guide/migration-vmware-esxi.md","sourceDirName":"02-iaas/guides/user-guide","slug":"/iaas/guides/user-guide/migration-vmware-esxi","permalink":"/docs/iaas/guides/user-guide/migration-vmware-esxi","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/migration-vmware-esxi.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Migrate from VMware ESXi to OpenStack"},"sidebar":"docs","previous":{"title":"User Guide","permalink":"/docs/iaas/guides/user-guide/"},"next":{"title":"OpenStack","permalink":"/docs/iaas/guides/user-guide/openstack/"}}');var s=t(74848),i=t(28453);const a={sidebar_label:"Migrate from VMware ESXi to OpenStack"},r="Migrate from VMware ESXi to OpenStack",c={},d=[{value:"Scenario",id:"scenario",level:2},{value:"Requirements",id:"requirements",level:2},{value:"Prechecks",id:"prechecks",level:2},{value:"Migration",id:"migration",level:2},{value:"How to copy vmdk images",id:"how-to-copy-vmdk-images",level:3},{value:"How to convert vmdk to raw",id:"how-to-convert-vmdk-to-raw",level:3},{value:"Edit the raw Images (optional)",id:"edit-the-raw-images-optional",level:3},{value:"How to import Images",id:"how-to-import-images",level:3},{value:"How to create your server",id:"how-to-create-your-server",level:3},{value:"Show your new server",id:"show-your-new-server",level:3},{value:"How to access the VNC console",id:"how-to-access-the-vnc-console",level:3},{value:"Last words",id:"last-words",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"migrate-from-vmware-esxi-to-openstack",children:"Migrate from VMware ESXi to OpenStack"})}),"\n",(0,s.jsx)(n.p,{children:"This guide is an example of how to perform a manual migration from a VMware ESXi host to OpenStack.\nMigration to OpenStack always depends very much on the use case. It is not possible to document an\napproach or to write a tool that works for all use cases. This guide shows one possible way. There are many ways to\nperform a migration. A migration must always be carefully prepared and tested in advance."}),"\n",(0,s.jsxs)(n.p,{children:["At this point, we would also like to point out the open source project\n",(0,s.jsx)(n.a,{href:"https://github.com/cloudbase/coriolis",children:"cloudbase/coriolis"})," from Cloudbase. There are also commercial\nproviders that perform migration from VMware ESXi to OpenStack. One of the offerings is\n",(0,s.jsx)(n.a,{href:"https://hystax.com/cloud-migration/",children:"Hystax Acura Live Cloud Migration"}),".\n",(0,s.jsx)(n.a,{href:"https://github.com/vexxhost/migratekit",children:"Migratekit"})," from Vexxhost is another option for migrating VMWare to OpenStack."]}),"\n",(0,s.jsxs)(n.p,{children:["A good overview and comparison of VMWare resources and their OpenStack counterparts is available ",(0,s.jsx)(n.a,{href:"https://www.openstack.org/vmware-migration-to-openstack",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"scenario",children:"Scenario"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Source: ESXi 7.0 host"}),"\n",(0,s.jsx)(n.li,{children:"Destination: OpenStack"}),"\n",(0,s.jsxs)(n.li,{children:["a security group (",(0,s.jsx)(n.code,{children:"web_ssh"}),") is already available at the destination"]}),"\n",(0,s.jsx)(n.li,{children:"a Linux converter host is installed and ready, we also have root access to it"}),"\n",(0,s.jsxs)(n.li,{children:["an IPv4 address (",(0,s.jsx)(n.code,{children:"10.50.40.230"}),") will be given manually out of a preconfigured network"]}),"\n",(0,s.jsx)(n.li,{children:"we migrate one host with a kernel newer then 2.6.25 with two scsi harddrives attached and one networkcard"}),"\n",(0,s.jsx)(n.li,{children:"destination openstack using Libvirt/KVM as virtualisation"}),"\n",(0,s.jsx)(n.li,{children:"the converter host has access to ESXi and the OpenStack environment over IP network"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"VMware credentials"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"SSH enabled on ESXi host"}),"\n",(0,s.jsx)(n.li,{children:"access to the webinterface of the ESXi host"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"OpenStack credentials"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Linux packages installed on the coverter, in this case it is an Ubuntu 22.04"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"apt-get install qemu-utils python3-openstackclient\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"twice the space of the largest vmdk disc image on the converter or nfs access to the image files with enough storage"}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"prechecks",children:"Prechecks"}),"\n",(0,s.jsxs)(n.p,{children:["Check the ",(0,s.jsx)(n.code,{children:"/etc/fstab"})," file of your VMware ESXi host you want to move. See how all the discs or paritions are mounted.\nIf they are all mounted by LVM or UUID you do not need to change anything."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-txt",metastring:'title="cat /etc/fstab"',children:"/dev/mapper/vg00-lvroot / ext4 errors=remount-ro 0 1\n/dev/mapper/vg00-lvboot /boot ext2 defaults 0 2\n/dev/mapper/vg00-lvhome /home ext4 defaults 0 2\n/dev/mapper/vg00-lvvar /var ext4 defaults 0 2\n/dev/mapper/vg00-lvswap none swap sw 0 0\n/dev/mapper/vgdata-lvsrv /srv ext4 defaults 0 2\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If they are mounted like ",(0,s.jsx)(n.code,{children:"/dev/sda"})," it is better to change the ",(0,s.jsx)(n.code,{children:"/etc/fstab"})," to UUID mounting using ",(0,s.jsx)(n.code,{children:"blkid"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Replace these entries with ",(0,s.jsx)(n.code,{children:"UUID=filesystems_uuid"})," and add the rest of the line same as with the devicenames."]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-txt",metastring:'title="example devicename fstab"',children:"/dev/sda1 /boot ext2 defaults 0 2\n/dev/sda2 / ext4 errors=remount-ro 0 1\n"})}),"\n",(0,s.jsx)(n.p,{children:"Change it to something like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-txt",metastring:'title="example uuid fstab"',children:"UUID=574c96bf-f2cb-49b8-9196-232a24047f94 /boot ext2 defaults 0 2\nUUID=93cc3b34-36c3-422e-b7a6-c80439e8f431 / ext4 errors=remount-ro 0 1\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsxs)(n.p,{children:["When creating a new server, OpenStack uses ",(0,s.jsx)(n.code,{children:"/dev/vd*"})," or ",(0,s.jsx)(n.code,{children:"/dev/sd*"})," as devices for volumes.\nUsing UUID/LVM mounts will ensure that the kernel will find your devices while booting.\nUsing old device names may lead to the boot sequence to get stuck, due to missing devices."]})}),"\n",(0,s.jsx)(n.p,{children:"Also check your NIC interface configuration as the devicenames can change to a new devicename."}),"\n",(0,s.jsx)(n.p,{children:"This depends on the udev or systemd setup of your specific system."}),"\n",(0,s.jsx)(n.p,{children:"It needs to be changed to either DCHP if you want to use floating IPs or static IP of the new network."}),"\n",(0,s.jsx)(n.h2,{id:"migration",children:"Migration"}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"Shutdown the host in VMware as the movement is only possible while the host is offline.\nOtherwise you will get corrupted disc files."})}),"\n",(0,s.jsxs)(n.p,{children:["You can use either the webinterface or SSH to identify and copy the ",(0,s.jsx)(n.code,{children:"*.vmdk"})," files of your VMware ESXi host."]}),"\n",(0,s.jsx)(n.p,{children:"While using the web interface you need to locate the datastore and the directoy where the disc files are\nlocated and start downloading all vmdk files. You will always get files files for a disc, a smaller and a\nlarger one, both are required."}),"\n",(0,s.jsxs)(n.p,{children:["When using SSh, please also copy both vmdk files for the disc to the converter host. Start looking up your\nfiles under ",(0,s.jsx)(n.code,{children:"/vmfs/volumes/"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"how-to-copy-vmdk-images",children:"How to copy vmdk images"}),"\n",(0,s.jsx)(n.p,{children:"Example SSH copy and path of all vmdk files to the converter host using the scp command for our testing-host:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"scp user@vmhost:/vmfs/volumes/datastore1/testing-host/*.vmdk .\n"})}),"\n",(0,s.jsx)(n.p,{children:"After copying is finished, we find several vmdk files in our directory.\nWe copied two disc images:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"testing-host-disc0-flat.vmdk testing-host-disc1.vmdk\ntesting-host-disc0.vmdk testing-host-disc1-flat.vmdk\n"})}),"\n",(0,s.jsx)(n.h3,{id:"how-to-convert-vmdk-to-raw",children:"How to convert vmdk to raw"}),"\n",(0,s.jsxs)(n.admonition,{type:"note",children:[(0,s.jsx)(n.p,{children:"Now convert those vmdk files into raw images with the following flags:"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"-p show progress (optional)\n-f Input Format\n-O Output Format\n"})}),(0,s.jsx)(n.p,{children:"Raw files are required to import images into OpenStack."})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"qemu-img convert -p -f vmdk -O raw testing-host-disc0.vmdk testing-host-disc0.raw\n"})}),"\n",(0,s.jsx)(n.p,{children:"Repeat this step for each disc image you need to convert."}),"\n",(0,s.jsx)(n.h3,{id:"edit-the-raw-images-optional",children:"Edit the raw Images (optional)"}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"This step is completely optional and you should have some Linux knowledge to do this."})}),"\n",(0,s.jsx)(n.p,{children:"After converting the images of a Linux host, you now have the possibilty to edit some settings offline before importing the images into OpenStack."}),"\n",(0,s.jsx)(n.p,{children:"By mounting the raw image files you can edit the configuration files to, e.g.:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"disable mountpoints at the fstab, like nfs server"}),"\n",(0,s.jsx)(n.li,{children:"change the ip config of the networkcard to dhcp or fixed ip"}),"\n",(0,s.jsx)(n.li,{children:"adjust resolv.conf"}),"\n",(0,s.jsx)(n.li,{children:"adjust routing"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"On Ubuntu you can use losetup to mount the raw image as a loopdevice to mount it somewhere you have access to."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-txt",metastring:"example of mounting and raw image",children:"losetup -f -P testing-host-disc0.raw\nlosetup -l\n\nmount /dev/loop0p1 /mnt/test/\nor\nlvscan and mount the lvm volume\n"})}),"\n",(0,s.jsx)(n.h3,{id:"how-to-import-images",children:"How to import Images"}),"\n",(0,s.jsxs)(n.p,{children:["First of all you need your OpenStack credentials, having them in an ",(0,s.jsx)(n.code,{children:"my-project-openrc.sh"})," file and source them to your shell."]}),"\n",(0,s.jsx)(n.p,{children:"The openstack cli client is now able to connect to the cloud environment and do all the following steps."}),"\n",(0,s.jsx)(n.p,{children:"To get your credentials please check with your OpenStack provider."}),"\n",(0,s.jsxs)(n.p,{children:["If you want to preserve the ",(0,s.jsx)(n.code,{children:"/dev/sd*"})," device names of the mountpoints, you must inject the new image and add some properties while uploading it into the OpenStack environment or add them later on to the images with Horzion web interface or openstack cli client."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack image create --progress --property hw_disk_bus=scsi --property hw_scsi_model=virtio-scsi --property hw_watchdog_action=reset --disk-format raw --private --file testing-host-disc0.raw testing-host-image-disc0\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack image list\n+--------------------------------------+------------------------------+--------+\n| ID | Name | Status |\n+--------------------------------------+------------------------------+--------+\n| 2a12b545-5d09-4ca1-9a76-b57f8d2489be | testing-host-disc0 | active |\n| b34744f7-6ef6-4282-a001-08a06812e381 | testing-host-disc1 | active |\n+--------------------------------------+------------------------------+--------+\n"})}),"\n",(0,s.jsx)(n.h3,{id:"how-to-create-your-server",children:"How to create your server"}),"\n",(0,s.jsx)(n.p,{children:"The previously imported images need to be copied to a volume so the server is also able to evict to other hosts in the cluster,\nso lets create and start our server in OpenStack."}),"\n",(0,s.jsxs)(n.p,{children:["Select one flavor for the host, in this case ",(0,s.jsx)(n.code,{children:"SCS-8V-16"}),", which means 8 Virtual CPUs and 16GB of RAM, get a list of all your available flavors by executing\n",(0,s.jsx)(n.code,{children:"openstack flavor list"})," and select the best matching one."]}),"\n",(0,s.jsx)(n.p,{children:"As the images are 20GB, you tell openstack that you need a boot volume with a size of 20 and a block-device for the additional device also with a size of 20GB."}),"\n",(0,s.jsx)(n.p,{children:"In this guide there is already a security group which fits our needs, if not, create one or you will not be able to communicate with your new host."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack security group list\n+--------------------------------------+-----------------+------------------------------+----------------------------------+------+\n| ID | Name | Description | Project | Tags |\n+--------------------------------------+-----------------+------------------------------+----------------------------------+------+\n| 4fd1d060-bf1d-4f5a-8e80-fde975d41f5f | default | Default security group | c9aa53cc3c654692b14a8f81a88cfa2f | [] |\n| 73967e73-e8d5-4318-b621-a06e7496fec3 | web_ssh | Webserver security group | c9aa53cc3c654692b14a8f81a88cfa2f | [] |\n+--------------------------------------+-----------------+------------------------------+----------------------------------+------+\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"web_ssh"})," group will be attached to the server."]}),"\n",(0,s.jsx)(n.p,{children:"Now you need to tell which network you want to deploy your host on, optionally including a fixed IPv4 address."}),"\n",(0,s.jsxs)(n.p,{children:["You can repeat the ",(0,s.jsx)(n.code,{children:"--nic"})," for additional nics in your server, in this guide it's the my_corp_net."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack network list\n+--------------------------------------+-------------------+--------------------------------------+\n| ID | Name | Subnets |\n+--------------------------------------+-------------------+--------------------------------------+\n| 9688192e-11dd-4618-a18c-99d3267f630a | my_corp_net | 0d502fdb-be73-457a-8678-79eb6088a9a1 |\n| 98842b77-c070-4532-a2a9-99d588c4e947 | internet | 2dfc3916-972f-44d1-afdb-6f89488ef3a4 |\n| c846238a-b00a-4c73-87e3-3614d94f46fd | my_other_corp_net | b8210b4e-5d91-425a-b05c-ca5d4bf8329a |\n+--------------------------------------+-------------------+--------------------------------------+\n"})}),"\n",(0,s.jsx)(n.p,{children:"As last parameter, you give the server name of your migrated system."}),"\n",(0,s.jsx)(n.p,{children:"As we are starting an already configured system we do not need to inject SSH keys or passwords as they should already be present on the host."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack server create --flavor SCS-8V-16 \\\n --image 2a12b545-5d09-4ca1-9a76-b57f8d2489be --boot-from-volume 20 \\\n --security-group 73967e73-e8d5-4318-b621-a06e7496fec3 \\\n --nic net-id=9688192e-11dd-4618-a18c-99d3267f630a,v4-fixed-ip=10.50.40.230 \\\n --block-device uuid=b34744f7-6ef6-4282-a001-08a06812e381,source_type=image,destination_type=volume,volume_size=20 \\\n --os-compute-api-version 2.90 testing-host\n"})}),"\n",(0,s.jsx)(n.h3,{id:"show-your-new-server",children:"Show your new server"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack server list\n+--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+\n| ID | Name | Status | Networks | Image | Flavor |\n+--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+\n| 71a8b930-4212-434a-8891-afdeeb1802dc | testing-host | ACTIVE | my_network=10.50.40.230 | N/A (booted from volume) | SCS-8V-16 |\n+--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+\n"})}),"\n",(0,s.jsx)(n.p,{children:"To see the attached volumes and their mountpoints:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack server volume list 71a8b930-4212-434a-8891-afdeeb1802dc\n+----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+\n| Device | Server ID | Volume ID | Tag | Delete On Termination? | Attachment ID | BlockDeviceMapping UUID |\n+----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+\n| /dev/sda | 71a8b930-4212-434a-8891-afdeeb1802dc | 71902b03-48ea-483c-a6a3-6c47b9d8537b | None | False | 3cd241ff-5296-4bb1-9ba0-d743cb8c8f31 | 2d08e835-156f-4f71-8c95-7ff828230b8e |\n| /dev/sdb | 71a8b930-4212-434a-8891-afdeeb1802dc | 15a835a3-5149-49a8-8e2b-a81ef8097c35 | None | False | 9deeb06b-718b-49d4-84a4-87dabc34ba56 | 04483f95-0333-4b37-92e6-db604e4ddc7c |\n+----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+\n"})}),"\n",(0,s.jsx)(n.h3,{id:"how-to-access-the-vnc-console",children:"How to access the VNC console"}),"\n",(0,s.jsx)(n.p,{children:"To get the VNC URL for console login use:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"openstack console url show 71a8b930-4212-434a-8891-afdeeb1802dc\n+----------+-------------------------------------------------------------------------------------------+\n| Field | Value |\n+----------+-------------------------------------------------------------------------------------------+\n| protocol | vnc |\n| type | novnc |\n| url | https://vnc.your.cloud/vnc_lite.html?path=%3Ftoken%3Db9b6920d-e533-4728-8132-a5a0adfc24e5 |\n+----------+-------------------------------------------------------------------------------------------+\n"})}),"\n",(0,s.jsx)(n.p,{children:"This will print out the VNC URL for the videoconsole connection to your host."}),"\n",(0,s.jsx)(n.p,{children:"Now the server will boot and be available."}),"\n",(0,s.jsx)(n.p,{children:"Maybe you need to tweak the network setup if it is still not accessible.\nTo do this, you could use the VNC console of the OpenStack host:"}),"\n",(0,s.jsx)(n.p,{children:"Login and then setup the network card if you have not already done that before host had been shutdown."}),"\n",(0,s.jsx)(n.p,{children:"You now can remove the imported images, as they are no longer required - except you want to generate\nanother host with the same images."}),"\n",(0,s.jsx)(n.h2,{id:"last-words",children:"Last words"}),"\n",(0,s.jsx)(n.p,{children:"In this little guide, we only can give a sneak peak of what you need to do with a simple VMware ESXi host.\nMore complex setups needs consulting, planning and testing as there a several scenarios out there which\ncannot be handled like this.\nEspecially if you have terrabytes of data to move or graphics- or AIcards in you VMware ESXi hosts."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var o=t(96540);const s={},i=o.createContext(s);function a(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e44168e5.c714f7d5.js b/assets/js/e44168e5.c714f7d5.js new file mode 100644 index 0000000000..42ffdbad40 --- /dev/null +++ b/assets/js/e44168e5.c714f7d5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[31909],{49901:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>a,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"getting-started/virtualization","title":"Virtualization","description":"TODO","source":"@site/docs/01-getting-started/virtualization.md","sourceDirName":"01-getting-started","slug":"/getting-started/virtualization","permalink":"/docs/getting-started/virtualization","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/01-getting-started/virtualization.md","tags":[],"version":"current","frontMatter":{"sidebar":2}}');var r=n(74848),o=n(28453);const a={sidebar:2},s="Virtualization",c={},d=[];function u(t){const e={h1:"h1",header:"header",p:"p",...(0,o.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"virtualization",children:"Virtualization"})}),"\n",(0,r.jsx)(e.p,{children:"TODO"})]})}function l(t={}){const{wrapper:e}={...(0,o.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(u,{...t})}):u(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>a,x:()=>s});var i=n(96540);const r={},o=i.createContext(r);function a(t){const e=i.useContext(o);return i.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:a(t.components),i.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/e48c83c9.0f77ba54.js b/assets/js/e48c83c9.0f77ba54.js new file mode 100644 index 0000000000..36d1e766e2 --- /dev/null +++ b/assets/js/e48c83c9.0f77ba54.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[54252],{5492:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>c,frontMatter:()=>l,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","title":"Running on a virtual machine","description":"KVM","source":"@site/docs/02-iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine.md","sourceDirName":"02-iaas/guides/other-guides/cloud-in-a-box","slug":"/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","permalink":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Cloud in a Box Guide","permalink":"/docs/iaas/guides/other-guides/cloud-in-a-box/"},"next":{"title":"Contributor Guide","permalink":"/docs/iaas/guides/other-guides/contributor-guide"}}');var t=i(74848),a=i(28453);const l={},r="Running on a virtual machine",o={},d=[{value:"KVM",id:"kvm",level:2},{value:"Nested virtualization",id:"nested-virtualization",level:3},{value:"Disk space saving",id:"disk-space-saving",level:3},{value:"QEMU guest agent",id:"qemu-guest-agent",level:3},{value:"VMware vSphere/ESXi",id:"vmware-vsphereesxi",level:2},{value:"Guest OS:",id:"guest-os",level:3},{value:"Hardware:",id:"hardware",level:3},{value:"VirtualBox",id:"virtualbox",level:2},{value:"General:",id:"general",level:3},{value:"System:",id:"system",level:3},{value:"Storage:",id:"storage",level:3}];function u(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"running-on-a-virtual-machine",children:"Running on a virtual machine"})}),"\n",(0,t.jsx)(n.h2,{id:"kvm",children:"KVM"}),"\n",(0,t.jsx)(n.h3,{id:"nested-virtualization",children:"Nested virtualization"}),"\n",(0,t.jsx)(n.p,{children:"You likely want to run virtual machines on top of your Cloud in a Box.\nThe host machine has to support and enabled nested virtualization."}),"\n",(0,t.jsxs)(n.p,{children:["To enable nested virtualization the CPU configuration of the VM has to be ",(0,t.jsx)(n.code,{children:"host-passthrough"})," or ",(0,t.jsx)(n.code,{children:"host-model"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.fedoraproject.org/en-US/quick-docs/using-nested-virtualization-in-kvm/",children:"Enabling nested virtualization in Fedora"})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The linked guide can be used in other distributions as well."}),"\n",(0,t.jsx)(n.h3,{id:"disk-space-saving",children:"Disk space saving"}),"\n",(0,t.jsxs)(n.p,{children:["When using Cloud in a Box in a VM, you can utilize the qcow2 disk image or similar technology to save space.\nIn that case, the base installation requires just around 70 GB instead of a full 1 TB.\n(",(0,t.jsx)(n.em,{children:"The drive still needs to be made with a capacity of at least 1TB; however, the actual disk space usage is lower."}),")"]}),"\n",(0,t.jsxs)(n.p,{children:['Also in case you want to experiment a bit more and "hack around" using the manual installation\nyou can make disk snapshots when turned off after the Ubuntu installs, ',(0,t.jsx)(n.code,{children:"bootstrap.sh"})," and ",(0,t.jsx)(n.code,{children:"deploy.sh"})," to speed up your\nprogress."]}),"\n",(0,t.jsx)(n.p,{children:"If you use qemu, you can use following command to do snapshots."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'sudo virsh snapshot-create-as --domain cib bootstrap "run of bootstrap.sh" --disk-only --diskspec sda,snapshot=external,file=/var/lib/libvirt/images/ub2022_cib_boostrap.qcow2 --atomic\n'})}),"\n",(0,t.jsx)(n.h3,{id:"qemu-guest-agent",children:"QEMU guest agent"}),"\n",(0,t.jsx)(n.p,{children:"When running inside QEMU, it may be worth it to install the QEMU guest agent."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt -y install qemu-guest-agent\nsudo systemctl enable qemu-guest-agent\nsudo systemctl start qemu-guest-agent\n"})}),"\n",(0,t.jsx)(n.h2,{id:"vmware-vsphereesxi",children:"VMware vSphere/ESXi"}),"\n",(0,t.jsx)(n.p,{children:"When running Cloud in a Box on a VMware vSphere/ESXi virtual machine, you can use the below specs to configure the virtual machine:"}),"\n",(0,t.jsx)(n.h3,{id:"guest-os",children:"Guest OS:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Compatibility set to current running vSphere/ESXi version"}),"\n",(0,t.jsx)(n.li,{children:'Guest OS family set to "Linux"'}),"\n",(0,t.jsx)(n.li,{children:'Guest OS version set to "Ubuntu Linux (64-bit)"'}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"hardware",children:"Hardware:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"32GB RAM"}),"\n",(0,t.jsx)(n.li,{children:"8 vCores"}),"\n",(0,t.jsx)(n.li,{children:"SCSI Controller 0 set to LSI Logic Parallel"}),"\n",(0,t.jsx)(n.li,{children:"SCSI Disk with 500GB"}),"\n",(0,t.jsx)(n.li,{children:"CDROM/DVD drive mounted with ubuntu-autoinstall-cloud-in-a-box-1.iso image"}),"\n",(0,t.jsx)(n.li,{children:'Firmware set to "EFI" (VM Options > Boot Options > Firmware > choose EFI)'}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"This configuration has been successfully tested with VMware ESXi 7.0 U1."}),"\n",(0,t.jsx)(n.h2,{id:"virtualbox",children:"VirtualBox"}),"\n",(0,t.jsx)(n.p,{children:"When running Cloud in a Box on a VirtualBox, you can use the the blow specs for configure the virtual machine:"}),"\n",(0,t.jsx)(n.h3,{id:"general",children:"General:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Type Linux"}),"\n",(0,t.jsx)(n.li,{children:"Version Ubuntu (64-bit)"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"system",children:"System:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"32GB RAM"}),"\n",(0,t.jsx)(n.li,{children:"8 Processors"}),"\n",(0,t.jsx)(n.li,{children:"Enable PAE/NX"}),"\n",(0,t.jsx)(n.li,{children:"Enable Nested VT-x/AMD-v"}),"\n",(0,t.jsx)(n.li,{children:"Extended Feature: Enable EFI (special OSes only)"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"storage",children:"Storage:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Controller: SATA"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Type AHCI"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Use Host I/O Cache"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Disc Size 600 GB"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Controller: IDE"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Optical Drive: IDE Secondary Device"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Live CD/DVD"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Insert the ubuntu-autoinstall-cloud-in-a-box-1.iso image"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Boot Order: Set Optical as first boot device"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"This configuration has been successfully tested with VirtualBox 6.1.50 using an Ubuntu 22.04 Host with HWE Kernel 6.5.0\nThe more CPU, RAM and Disc the better, as this is the bare minimum for a basic installation."})]})}function c(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>l,x:()=>r});var s=i(96540);const t={},a=s.createContext(t);function l(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e4a5809a.42e8872f.js b/assets/js/e4a5809a.42e8872f.js new file mode 100644 index 0000000000..ed0ec9e8f1 --- /dev/null +++ b/assets/js/e4a5809a.42e8872f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[12196],{92515:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"iaas/guides/operations-guide/rook","title":"Ceph via Rook (technical preview)","description":"This is a technical preview and not recommended for production use yet. This whole","source":"@site/docs/02-iaas/guides/operations-guide/rook.md","sourceDirName":"02-iaas/guides/operations-guide","slug":"/iaas/guides/operations-guide/rook","permalink":"/docs/iaas/guides/operations-guide/rook","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/rook.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Ceph via Rook (technical preview)"},"sidebar":"docs","previous":{"title":"Octavia","permalink":"/docs/iaas/guides/operations-guide/openstack/octavia"},"next":{"title":"Rookify (technical preview)","permalink":"/docs/iaas/guides/operations-guide/rookify"}}');var r=o(74848),i=o(28453);const a={sidebar_label:"Ceph via Rook (technical preview)"},t="Ceph via Rook (technical preview)",l={},d=[{value:"Where to find docs",id:"where-to-find-docs",level:2},{value:"Advice on Ceph releases",id:"advice-on-ceph-releases",level:2},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Monitoring",id:"monitoring",level:2},{value:"Dashboard",id:"dashboard",level:3},{value:"Updating",id:"updating",level:2},{value:"Rook Upgrades",id:"rook-upgrades",level:3},{value:"Ceph Upgrades",id:"ceph-upgrades",level:3},{value:"General maintenance",id:"general-maintenance",level:2},{value:"60 seconds cluster overview",id:"60-seconds-cluster-overview",level:3},{value:"Mute/Unmute a health warning",id:"muteunmute-a-health-warning",level:3},{value:"Disable/Enable (deep-)scrubbing",id:"disableenable-deep-scrubbing",level:3},{value:"Reboot a single node",id:"reboot-a-single-node",level:3},{value:"Gathering information about block devices",id:"gathering-information-about-block-devices",level:2},{value:"Enumerate typical storage devices and LVM",id:"enumerate-typical-storage-devices-and-lvm",level:3},{value:"SMART data for SATA/SAS and NVME devices",id:"smart-data-for-satasas-and-nvme-devices",level:3},{value:"Check format of a NVME device",id:"check-format-of-a-nvme-device",level:3},{value:"Format a NVME device to a different LBA format using nvme-cli",id:"format-a-nvme-device-to-a-different-lba-format-using-nvme-cli",level:3},{value:"Secure Erase a NVME drive using nvme-cli",id:"secure-erase-a-nvme-drive-using-nvme-cli",level:3},{value:"Secure Erase a SATA/SAS drive using hdparm",id:"secure-erase-a-satasas-drive-using-hdparm",level:3},{value:"OSD maintenance tasks",id:"osd-maintenance-tasks",level:2},{value:"Disable backfills/recovery completely",id:"disable-backfillsrecovery-completely",level:3},{value:"Rebalance OSDs",id:"rebalance-osds",level:3},{value:"Placement Group maintenance",id:"placement-group-maintenance",level:2},{value:"Dump placement groups",id:"dump-placement-groups",level:3},{value:"Query a PG about its status",id:"query-a-pg-about-its-status",level:3},{value:"Start (deep-)scrubbing of a placement group",id:"start-deep-scrubbing-of-a-placement-group",level:3},{value:"HEALTH_WARN - Large omap objects found...",id:"health_warn---large-omap-objects-found",level:3},{value:"Instruct a PG to repair in case of scrub errors (inconsistent PG)",id:"instruct-a-pg-to-repair-in-case-of-scrub-errors-inconsistent-pg",level:3},{value:"RADOS Pool maintenance",id:"rados-pool-maintenance",level:2},{value:"Get pools and their configuration",id:"get-pools-and-their-configuration",level:3},{value:"Dump all CRUSH rules",id:"dump-all-crush-rules",level:3},{value:"Get autoscaler status",id:"get-autoscaler-status",level:3},{value:"Create a replicated pool",id:"create-a-replicated-pool",level:3},{value:"Enabling an application on a pool",id:"enabling-an-application-on-a-pool",level:3},{value:"Delete a pool",id:"delete-a-pool",level:3},{value:"Set number of PGs for a pool",id:"set-number-of-pgs-for-a-pool",level:3},{value:"Create CRUSH rules for different storage classes",id:"create-crush-rules-for-different-storage-classes",level:3},{value:"Change CRUSH rule for a pool ("move pool")",id:"change-crush-rule-for-a-pool-move-pool",level:3},{value:"Advanced topics",id:"advanced-topics",level:2},{value:"Performance benchmark",id:"performance-benchmark",level:2},{value:"Where and how to get further help",id:"where-and-how-to-get-further-help",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"ceph-via-rook-technical-preview",children:"Ceph via Rook (technical preview)"})}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"This is a technical preview and not recommended for production use yet. This whole\ndocument has to be reworkded with more rook like handling. Do not take it for\ngranted yet."})}),"\n",(0,r.jsx)(n.h2,{id:"where-to-find-docs",children:"Where to find docs"}),"\n",(0,r.jsxs)(n.p,{children:["The official Rook documentation starts here ",(0,r.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Getting-Started/intro/",children:"https://rook.io/docs/rook/latest-release/Getting-Started/intro/"})]}),"\n",(0,r.jsx)(n.p,{children:"Some sections to point out are:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Troubleshooting/common-issues/",children:"Rook Common Issues Documentation"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Troubleshooting/ceph-common-issues/",children:"Rook Ceph Common Issues Documentation"})}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The official Ceph documentation is located on ",(0,r.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/",children:"https://docs.ceph.com/en/latest/rados/operations/"})]}),"\n",(0,r.jsxs)(n.p,{children:["It is ",(0,r.jsx)(n.strong,{children:"strongly advised"})," to use the documentation for the version being used."]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Quincy - ",(0,r.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/rados/operations/",children:"https://docs.ceph.com/en/quincy/rados/operations/"})]}),"\n",(0,r.jsxs)(n.li,{children:["Reef - ",(0,r.jsx)(n.a,{href:"https://docs.ceph.com/en/reef/rados/operations/",children:"https://docs.ceph.com/en/reef/rados/operations/"})]}),"\n"]}),"\n",(0,r.jsxs)(n.admonition,{type:"note",children:[(0,r.jsxs)(n.p,{children:["Do not take information in the documentation at face value.\nEspecially when it comes to advanced/rarely used/very new features it is ",(0,r.jsx)(n.strong,{children:"strongly advised"}),"\nto test any claims made in the documentation about any particular feature."]}),(0,r.jsx)(n.p,{children:"Never assume that things will work as written without actually testing it on a test setup\nas close to your real workload scenario as possible."})]}),"\n",(0,r.jsx)(n.h2,{id:"advice-on-ceph-releases",children:"Advice on Ceph releases"}),"\n",(0,r.jsxs)(n.p,{children:["The current Ceph releases and their support status can be found on ",(0,r.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/releases/",children:"https://docs.ceph.com/en/latest/releases/"})]}),"\n",(0,r.jsxs)(n.p,{children:["When a new Ceph stable version is released you are ",(0,r.jsx)(n.strong,{children:"strongly advised"}),"\nto not roll it out on any production cluster whatsoever.\nEven though its listed as \"stable\" it doesn't mean that this is actually true.\nEspecially avoid using .0 releases on anything remotely production\nunless you really, really now what you're doing and can live with a possible catastrophic failure."]}),"\n",(0,r.jsxs)(n.p,{children:["Be ",(0,r.jsx)(n.strong,{children:"very"})," conservative about what version you run on production systems."]}),"\n",(0,r.jsx)(n.p,{children:"Shiny new features aren't worth the risk of total or partial data loss/corruption."}),"\n",(0,r.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,r.jsxs)(n.p,{children:["Please have a look at the ",(0,r.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Troubleshooting/ceph-toolbox/",children:"Rook Troubleshooting documentation"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The Rook toolbox is available via the ",(0,r.jsx)(n.code,{children:"ceph"})," command on the manager node, after you deployed the wrapper via ",(0,r.jsx)(n.code,{children:"osism apply cephclient"}),". You have to make sure the correct ",(0,r.jsx)(n.a,{href:"/docs/iaas/guides/configuration-guide/rook#client",children:"Configuration Options for the Rook Ceph Client Wrapper"})," are net."]}),"\n",(0,r.jsx)(n.h2,{id:"monitoring",children:"Monitoring"}),"\n",(0,r.jsx)(n.h3,{id:"dashboard",children:"Dashboard"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://rook.io/docs/rook/latest/Storage-Configuration/Monitoring/ceph-dashboard/",children:"https://rook.io/docs/rook/latest/Storage-Configuration/Monitoring/ceph-dashboard/"})}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The password is stored in the secret ",(0,r.jsx)(n.code,{children:"rook-ceph-dashboard-password"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath=\"{['data']['password']}\" | base64 --decode && echo\n"})}),"\n",(0,r.jsx)(n.h2,{id:"updating",children:"Updating"}),"\n",(0,r.jsx)(n.h3,{id:"rook-upgrades",children:"Rook Upgrades"}),"\n",(0,r.jsxs)(n.p,{children:["Please have a look at the ",(0,r.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Upgrade/rook-upgrade/",children:"Rook Upgrades documentation"}),". Take note of update instructions specific to your version."]}),"\n",(0,r.jsxs)(n.p,{children:["Usually you can simply update by bumping the ",(0,r.jsx)(n.code,{children:"rook_operator_image_tag"})," ansible variable and applying ",(0,r.jsx)(n.code,{children:"osism apply rook-operator"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"ceph-upgrades",children:"Ceph Upgrades"}),"\n",(0,r.jsxs)(n.p,{children:["Please have a look at the ",(0,r.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Upgrade/ceph-upgrade/",children:"Rook Ceph Upgrades documentation"}),". Take note of update instructions specific to your version."]}),"\n",(0,r.jsxs)(n.p,{children:["Usually you can simply update by bumping the ",(0,r.jsx)(n.code,{children:"rook_ceph_image_tag"})," ansible variable and applying ",(0,r.jsx)(n.code,{children:"osism apply rook"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"general-maintenance",children:"General maintenance"}),"\n",(0,r.jsx)(n.h3,{id:"60-seconds-cluster-overview",children:"60 seconds cluster overview"}),"\n",(0,r.jsx)(n.p,{children:"The following commands can be used to quickly check the status of Ceph:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Print overall cluster status"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph -s\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Print detailed health information"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph health detail\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Display current OSD tree"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph osd tree\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Cluster storage usage by pool and storage class"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph df\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"List pools with detailed configuration"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph osd pool ls detail\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Get usage stats for OSDs"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph osd df {plain|tree} {class e.g. hdd|ssd}\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Watch Ceph health messages sequentially"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph -w\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"List daemon versions running in the cluster"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph versions\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Also you can run the following on each node running ceph-daemons,\nto provide further debug information about the environment:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# lscpu\n# cat /proc/cpuinfo # if lscpu isn't available\n# free -g\n# ip l\n# ethtool <device> # for each network adapter\n"})}),"\n",(0,r.jsx)(n.h3,{id:"muteunmute-a-health-warning",children:"Mute/Unmute a health warning"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph health mute <what> <duration>\n$ ceph health unmute <what>\n"})}),"\n",(0,r.jsx)(n.h3,{id:"disableenable-deep-scrubbing",children:"Disable/Enable (deep-)scrubbing"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph osd set noscrub\n$ ceph osd set nodeep-scrub\n$ ceph osd unset noscrub\n$ ceph osd unset nodeep-scrub\n"})}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"Use this sparingly only in emergency situations.\nSetting these flags will cause a HEALTH_WARN status,\nincrease risk of data corruption and also the risk of generating\na HEALTH_WARN due to PGs not being (deep-)scrubbed in time."})}),"\n",(0,r.jsx)(n.h3,{id:"reboot-a-single-node",children:"Reboot a single node"}),"\n",(0,r.jsxs)(n.p,{children:["The traditional way of doing this is by setting the ",(0,r.jsx)(n.code,{children:"noout"})," flag,\ndo the appropriate maintenance work and after the node is back online\nunset the flag like so:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph osd set noout\n"})}),"\n",(0,r.jsx)(n.p,{children:"After maintenance is done and host is back up:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph osd unset noout\n"})}),"\n",(0,r.jsx)(n.p,{children:"On versions Luminous or above you can set the flag individually for single\nOSDs or entire CRUSH buckets, which can be a safer option in case of prolonged\nmaintenance periods."}),"\n",(0,r.jsx)(n.p,{children:"Add noout for a OSD:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph osd add-noout osd.<ID>\n"})}),"\n",(0,r.jsx)(n.p,{children:"Remove noout for a OSD:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph osd rm-noout osd.<ID>\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Add noout for CRUSH bucket (e.g. host name as seen in ",(0,r.jsx)(n.code,{children:"ceph osd tree"}),"):"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph osd set-group noout <crush-bucket-name>\n"})}),"\n",(0,r.jsx)(n.p,{children:"Remove noout for CRUSH bucket:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ceph osd unset-group noout <crush-bucket-name>\n"})}),"\n",(0,r.jsx)(n.h2,{id:"gathering-information-about-block-devices",children:"Gathering information about block devices"}),"\n",(0,r.jsx)(n.h3,{id:"enumerate-typical-storage-devices-and-lvm",children:"Enumerate typical storage devices and LVM"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# lsblk\n# lsblk -S\n# lsscsi\n# nvme list\n# pvs\n# vgs\n# lvs\n"})}),"\n",(0,r.jsx)(n.h3,{id:"smart-data-for-satasas-and-nvme-devices",children:"SMART data for SATA/SAS and NVME devices"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# smartctl -a /dev/sdX\n# nvme smart-log /dev/nvmeXnY\n"})}),"\n",(0,r.jsx)(n.h3,{id:"check-format-of-a-nvme-device",children:"Check format of a NVME device"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# nvme id-ns -H /dev/nvmeXnY\n"})}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsx)(n.p,{children:'Check the last lines named "LBA Format".\nIt will show which formats are supported,\nwhich format is in use and which format offers the best performance\naccording to the vendor.'})}),"\n",(0,r.jsx)(n.h3,{id:"format-a-nvme-device-to-a-different-lba-format-using-nvme-cli",children:"Format a NVME device to a different LBA format using nvme-cli"}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"This will destroy all data on the device!"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# nvme format --lbaf=<id> /dev/nvmeXnY\n"})}),"\n",(0,r.jsx)(n.h3,{id:"secure-erase-a-nvme-drive-using-nvme-cli",children:"Secure Erase a NVME drive using nvme-cli"}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"This will destroy all data on the device!"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# nvme format -s2 /dev/nvmeXnY\n# blkdiscard /dev/nvmeXnY\n# nvme format -s1 /dev/nvmeXnY\n"})}),"\n",(0,r.jsx)(n.h3,{id:"secure-erase-a-satasas-drive-using-hdparm",children:"Secure Erase a SATA/SAS drive using hdparm"}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"This will destroy all data on the device!"})}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Gather device info:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# hdparm -I /dev/sdX\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Check that the output says ",(0,r.jsx)(n.strong,{children:'"not frozen"'})," and ",(0,r.jsx)(n.strong,{children:'"not locked"'}),",\nalso it should list support for enhanced erase and list time estimates\nfor ",(0,r.jsx)(n.strong,{children:"SECURITY ERASE UNIT"})," and/or ",(0,r.jsx)(n.strong,{children:"ENHANCED SECURITY ERASE UNIT"})]}),"\n",(0,r.jsxs)(n.ol,{start:"2",children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Set a master password for the disk (required, will be automatically removed after wipe)"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# hdparm --user-master wipeit --security-set-pass wipeit /dev/sdX\n# hdparm -I /dev/sdX\n"})}),"\n",(0,r.jsxs)(n.p,{children:['Check that "Security level" is now ',(0,r.jsx)(n.strong,{children:'"high"'})," and master password is now\n",(0,r.jsx)(n.strong,{children:'"enabled"'})," instead of ",(0,r.jsx)(n.strong,{children:'"not enabled"'})," before"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Wipe the device"}),"\n",(0,r.jsx)(n.p,{children:"If device supports enhanced security erase (better), use the following:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# hdparm --user-master wipeit --security-erase-enhanced wipeit /dev/sdX\n"})}),"\n",(0,r.jsx)(n.p,{children:"If not, use standard security erase:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# hdparm --user-master wipeit --security-erase wipeit /dev/sdX\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:['On some systems the system firmware might "freeze" the device,\nwhich makes it impossible to issue a secure erase or reformat the device.\nIn that case it might be necessary to either "unfreeze" the drive or\nto install the drive in another system where it can be unfrozen.\nAlso make sure that the device is ',(0,r.jsx)(n.em,{children:"actually"})," wiped. Its recommended to\nat least perform a blanking pass on HDDs with a tool like nwipe."]})}),"\n",(0,r.jsx)(n.h2,{id:"osd-maintenance-tasks",children:"OSD maintenance tasks"}),"\n",(0,r.jsxs)(n.p,{children:["Please have a look at the ",(0,r.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/Storage-Configuration/Advanced/ceph-osd-mgmt/.",children:"Rook Ceph OSD Management documentation"})]}),"\n",(0,r.jsx)(n.h3,{id:"disable-backfillsrecovery-completely",children:"Disable backfills/recovery completely"}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"Use only in emergency situations!"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph osd set nobackfill\n$ ceph osd set norecovery\n$ ceph osd set norebalance\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Unset the flags with ",(0,r.jsx)(n.code,{children:"ceph osd unset <flag>"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"rebalance-osds",children:"Rebalance OSDs"}),"\n",(0,r.jsx)(n.h2,{id:"placement-group-maintenance",children:"Placement Group maintenance"}),"\n",(0,r.jsx)(n.h3,{id:"dump-placement-groups",children:"Dump placement groups"}),"\n",(0,r.jsx)(n.p,{children:"Usually only useful when parsing it, so here are two ways to get the data:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph pg dump\n$ ceph pg dump --format=json-pretty\n"})}),"\n",(0,r.jsx)(n.h3,{id:"query-a-pg-about-its-status",children:"Query a PG about its status"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph pg <pgid> query\n"})}),"\n",(0,r.jsx)(n.h3,{id:"start-deep-scrubbing-of-a-placement-group",children:"Start (deep-)scrubbing of a placement group"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph pg scrub <pgid>\n$ ceph pg deep-scrub <pgid>\n"})}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsx)(n.p,{children:"Instructing a PG to (deep-)scrub does not mean that it will do so immediately,\nit can take some time for the scrub to start."})}),"\n",(0,r.jsx)(n.h3,{id:"health_warn---large-omap-objects-found",children:"HEALTH_WARN - Large omap objects found..."}),"\n",(0,r.jsx)(n.p,{children:"Finding PGs which have large OMAP objects:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# ceph pg dump --format=json | jq '.pg_map.pg_stats[] |\nselect(.stat_sum.num_large_omap_objects != 0) |\n(.pgid, .stat_sum.num_large_omap_objects, .up, .acting)'\n"})}),"\n",(0,r.jsxs)(n.p,{children:["(Remove the line breaks between the single quotes or ",(0,r.jsx)(n.code,{children:"jq"})," might act weird!)"]}),"\n",(0,r.jsxs)(n.p,{children:["This will dump all PG IDs with large OMAP objects and their up/acting OSDs.\nYou then can grep the logs of these OSDs for ",(0,r.jsx)(n.strong,{children:'"Large omap object"'}),"\nto find the actual objects causing the health warning."]}),"\n",(0,r.jsx)(n.p,{children:"Also the PG ID before the dot is equal to the pool ID it belongs to."}),"\n",(0,r.jsx)(n.p,{children:"In case the logs have been rotated, instruct those OSDs to do a deep-scrub\nand watch the logs for the message to appear."}),"\n",(0,r.jsx)(n.p,{children:"From there you can investigate the issue further,\nmostly it'll be due to the index of a RGW bucket getting too big due to too many objects,\nthus resharding that bucket's index will be necessary."}),"\n",(0,r.jsx)(n.h3,{id:"instruct-a-pg-to-repair-in-case-of-scrub-errors-inconsistent-pg",children:"Instruct a PG to repair in case of scrub errors (inconsistent PG)"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph pg repair <pgid>\n"})}),"\n",(0,r.jsxs)(n.admonition,{type:"note",children:[(0,r.jsxs)(n.p,{children:["Recovery might not start immediately and might take some time.\nYou can query the status of the recovery through ",(0,r.jsx)(n.code,{children:"ceph pg <pgid> query"}),".\nBe sure to read the Ceph manual about this topic ",(0,r.jsx)(n.em,{children:"thoroughly"}),":"]}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshooting-pg/",children:"https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshooting-pg/"})})]}),"\n",(0,r.jsx)(n.h2,{id:"rados-pool-maintenance",children:"RADOS Pool maintenance"}),"\n",(0,r.jsxs)(n.admonition,{type:"note",children:[(0,r.jsx)(n.p,{children:"Read the RADOS pool operations documentation in detail before playing around with pools.\nEspecially when considering making changes to the CRUSH map.\nWrong decisions there can lead to data loss or other catastrophic failures."}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/pools/",children:"https://docs.ceph.com/en/latest/rados/operations/pools/"})})]}),"\n",(0,r.jsx)(n.h3,{id:"get-pools-and-their-configuration",children:"Get pools and their configuration"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph osd pool ls detail\n"})}),"\n",(0,r.jsx)(n.h3,{id:"dump-all-crush-rules",children:"Dump all CRUSH rules"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph osd crush rule dump\n"})}),"\n",(0,r.jsx)(n.h3,{id:"get-autoscaler-status",children:"Get autoscaler status"}),"\n",(0,r.jsx)(n.p,{children:"Autoscaler is enabled by default in a Rook Ceph cluster."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph osd pool autoscale-status\n"})}),"\n",(0,r.jsx)(n.h3,{id:"create-a-replicated-pool",children:"Create a replicated pool"}),"\n",(0,r.jsxs)(n.p,{children:["This should be done by updating your ",(0,r.jsx)(n.code,{children:"values.yml"})," file via the variables in ",(0,r.jsx)(n.a,{href:"/docs/iaas/guides/configuration-guide/rook#extra-pool--cephblockpool-crd",children:"Rook Extra pools - CephBlockPoolC CRD"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"It also can be done by hand but Rook will not know about the pool in this case."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph osd pool create <pool_name> <pg_num> <pgp_num> replicated [<crush_rule_name>]\n"})}),"\n",(0,r.jsx)(n.h3,{id:"enabling-an-application-on-a-pool",children:"Enabling an application on a pool"}),"\n",(0,r.jsx)(n.p,{children:"Required, otherwise a health warning will be raised after some time."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph osd pool application enable <pool_name> <application_name> # Syntax\n$ ceph osd pool application enable cinder rbd # Example\n"})}),"\n",(0,r.jsx)(n.p,{children:"Typical application names are: rbd, rgw, cephfs"}),"\n",(0,r.jsx)(n.h3,{id:"delete-a-pool",children:"Delete a pool"}),"\n",(0,r.jsxs)(n.p,{children:["This should be done by updating your ",(0,r.jsx)(n.code,{children:"values.yml"})," file via the variables in ",(0,r.jsx)(n.a,{href:"/docs/iaas/guides/configuration-guide/rook#extra-pool--cephblockpool-crd",children:"Rook Extra pools - CephBlockPoolC CRD"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"It also can be done by hand but Rook will not know about the pool in this case."}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"This will delete all data in that pool. There is no undo/undelete."})}),"\n",(0,r.jsx)(n.h3,{id:"set-number-of-pgs-for-a-pool",children:"Set number of PGs for a pool"}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsx)(n.p,{children:"PG autoscaling is enabled by default in Rook managed Ceph Clusters."})}),"\n",(0,r.jsx)(n.p,{children:"If no autoscaling of PGs is used, it is very important to adapt the PGs per pool to the\nreal world when operating a Ceph cluster. If, for example, OSDs are exchanged, added, new\nnodes are added, etc., the number of PGs must also be taken into account."}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/pgcalc/",children:"PG Calc Tool"})," can be used\nto calculate a reasonable number of PGs per pool depending on all ODSs and pools."]}),"\n",(0,r.jsxs)(n.p,{children:["Further information on placement groups can be found in the\n",(0,r.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/placement-groups/",children:"Ceph documentation"}),".\nYou should definitely read ",(0,r.jsx)(n.em,{children:"FACTORS RELEVANT TO SPECIFYING PG_NUM"})," and ",(0,r.jsx)(n.em,{children:"CHOOSING THE NUMBER OF PGS"}),"\nthere."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph osd pool set <poolname> pg_num <num_pgs>\n"})}),"\n",(0,r.jsxs)(n.admonition,{type:"note",children:[(0,r.jsx)(n.p,{children:"Num PGs must be a power of two! Be careful about changing number of PGs.\nChanging pg_num to a new value will gradually increase pgp_num on newer versions of Ceph."}),(0,r.jsx)(n.p,{children:"In older versions one also has to set pgp_num manually, either in increments or in one big leap."})]}),"\n",(0,r.jsx)(n.h3,{id:"create-crush-rules-for-different-storage-classes",children:"Create CRUSH rules for different storage classes"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph osd crush rule create-replicated replicated_hdd default host hdd\n$ ceph osd crush rule create-replicated replicated_ssd default host ssd\n$ ceph osd crush rule create-replicated replicated_nvme default host nvme\n"})}),"\n",(0,r.jsx)(n.h3,{id:"change-crush-rule-for-a-pool-move-pool",children:'Change CRUSH rule for a pool ("move pool")'}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ ceph osd pool set <poolname> crush_rule <rule_name>\n"})}),"\n",(0,r.jsx)(n.p,{children:"This can be used to move a pool from e.g. HDD to SSD or NVME class\nor anything else that the new CRUSH rule specifies."}),"\n",(0,r.jsx)(n.h2,{id:"advanced-topics",children:"Advanced topics"}),"\n",(0,r.jsx)(n.h2,{id:"performance-benchmark",children:"Performance benchmark"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# apt-get install -y fio\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:'#!/usr/bin/env bash\n\nBENCH_DEVICE="$2"\nDATE=$(date +%s)\nIOENGINE="libaio"\nLOGPATH="$1"\nSIZE=1G\n\nmkdir -p $LOGPATH\n\nfor RW in "write" "randwrite" "read" "randread"\ndo\n for BS in "4K" "64K" "1M" "4M" "16M" "64M"\n do\n (\n echo "==== $RW - $BS - DIRECT ===="\n echo 3 > /proc/sys/vm/drop_caches\n fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json\n sync\n echo 3 > /proc/sys/vm/drop_caches\n echo "==== $RW - $BS - DIRECT IODEPTH 32 ===="\n fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --iodepth=32 --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-iod32-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json\n sync\n ) | tee $LOGPATH/$RW.$BS-$(basename $BENCH_DEVICE).$DATE.log\n echo\n done\ndone\n'})}),"\n",(0,r.jsx)(n.h2,{id:"where-and-how-to-get-further-help",children:"Where and how to get further help"}),"\n",(0,r.jsxs)(n.p,{children:["Join the ",(0,r.jsx)(n.strong,{children:"#ceph"})," IRC channel on ",(0,r.jsx)(n.strong,{children:"irc.oftc.net"}),', state the problem with as many details as possible\nincluding information about what steps have already been taken to solve the problem\nalso provide information from the command output from the "60 seconds cluster overview" above\nthrough a pastebin or a similar service. In order for people to be able\nto help, details and some patience are important.']})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>a,x:()=>t});var s=o(96540);const r={},i=s.createContext(r);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e6263de7.9d9463ef.js b/assets/js/e6263de7.9d9463ef.js new file mode 100644 index 0000000000..e74302058a --- /dev/null +++ b/assets/js/e6263de7.9d9463ef.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[72111],{99966:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"iaas/guides/deploy-guide/services/rook","title":"Ceph via Rook (technical preview)","description":"This is a technical preview and not recommended for production use yet.","source":"@site/docs/02-iaas/guides/deploy-guide/services/rook.md","sourceDirName":"02-iaas/guides/deploy-guide/services","slug":"/iaas/guides/deploy-guide/services/rook","permalink":"/docs/iaas/guides/deploy-guide/services/rook","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/rook.md","tags":[],"version":"current","sidebarPosition":51,"frontMatter":{"sidebar_label":"Ceph via Rook (technical preview)","sidebar_position":51},"sidebar":"docs","previous":{"title":"Ceph","permalink":"/docs/iaas/guides/deploy-guide/services/ceph"},"next":{"title":"Migrate Ceph-Ansible via Rookify (technical preview)","permalink":"/docs/iaas/guides/deploy-guide/services/rookify"}}');var t=r(74848),s=r(28453);r(11470),r(19365);const i={sidebar_label:"Ceph via Rook (technical preview)",sidebar_position:51},a="Ceph via Rook (technical preview)",l={},c=[{value:"RGW service",id:"rgw-service",level:2},{value:"Change node labels",id:"change-node-labels",level:2},{value:"Cleanup",id:"cleanup",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"ceph-via-rook-technical-preview",children:"Ceph via Rook (technical preview)"})}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsx)(n.p,{children:"This is a technical preview and not recommended for production use yet."})}),"\n",(0,t.jsxs)(n.p,{children:["In OSISM it is also possible to integrate and use existing Ceph clusters. It\nis not necessary to deploy Ceph with OSISM. If Ceph is deployed with OSISM, it\nshould be noted that OSISM does not claim to provide all possible features of Ceph.\nCeph provided with OSISM is intended to provide the storage for Glance, Nova, Cinder\nand Manila. In a specific way that has been implemented by OSISM for years. It\nshould be checked in advance whether the way in OSISM the Ceph deployment and the\nprovided features are sufficient. If this is not the case, it is recommended to\ndeploy Ceph in a different way directly and independently of OSISM. For possible\nopen source projects, please refer to\n",(0,t.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/cephadm/index.html",children:"cephadm"})," and\n",(0,t.jsx)(n.a,{href:"https://rook.io",children:"Rook"}),"."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Deploy services."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["When using rook, all services are deployed via a single helm chart and at the same time. This could be altered by passing custom CRDs. See ",(0,t.jsx)(n.a,{href:"../../configuration-guide/rook",children:"Rook Configuration Guide"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install ",(0,t.jsx)(n.a,{href:"/docs/iaas/guides/deploy-guide/services/kubernetes",children:"Kubernetes Cluster"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Deploy ",(0,t.jsx)(n.a,{href:"https://rook.io/docs/rook/latest/Helm-Charts/operator-chart/",children:"Rook Operator Helm Chart"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply rook-operator\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy complete Rook Ceph Cluster"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply rook\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Copy ceph keyrings to kolla directories (if deploying OpenStack)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply rook-fetch-keys\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Get ceph keyrings. This places the necessary keys in ",(0,t.jsx)(n.code,{children:"/opt/configuration"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply rook-fetch-keys\n"})}),"\n",(0,t.jsx)(n.p,{children:"After run, these keys must be permanently added to the configuration repository\nvia Git."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"environments/infrastructure/files/ceph/ceph.client.admin.keyring\nenvironments/kolla/files/overlays/gnocchi/ceph.client.gnocchi.keyring\nenvironments/kolla/files/overlays/nova/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/nova/ceph.client.nova.keyring\nenvironments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder-backup.keyring\nenvironments/kolla/files/overlays/cinder/cinder-volume/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/manila/ceph.client.manila.keyring\nenvironments/kolla/files/overlays/glance/ceph.client.glance.keyring\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can also overwrite the ",(0,t.jsx)(n.code,{children:"rook_cephclients"})," parameter to skip\nthese keys."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_cephclients: {}\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"A Ceph client (a wrapper on the manager for entering the rook toolbox) can be deployed."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply cephclient\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You have to make sure the correct ",(0,t.jsx)(n.a,{href:"/docs/iaas/guides/configuration-guide/rook#client",children:"Configuration Options for the Rook Ceph Client Wrapper"})," are net."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["After getting the Ceph Keyrings, the ",(0,t.jsx)(n.a,{href:"/docs/iaas/guides/deploy-guide/services/openstack",children:"OpenStack Deployment"})," can optionally be done."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"rgw-service",children:"RGW service"}),"\n",(0,t.jsxs)(n.p,{children:["Deployment of the Ceph RGW Service is enabled by default in rook. This is done by creating a default ",(0,t.jsx)(n.a,{href:"https://rook.io/docs/rook/latest-release/CRDs/Object-Storage/ceph-object-store-crd/",children:"CephObjectStore CRD"}),". How the Ceph RGW service can be deployed and integrated into OpenStack is described here."]}),"\n",(0,t.jsxs)(n.p,{children:["In the ",(0,t.jsx)(n.code,{children:"environments/rook/configuration.yml"})," file you have to adapt accordingly to your environment at least like shown below:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:'rook_cephconfig:\n client.rgw.rgw.a:\n rgw_keystone_verify_ssl: "false"\n rgw_verify_ssl: "false"\n## keystone\nrook_cephobjectstore_keystone_acceptedRoles:\n - admin\n - member\nrook_cephobjectstore_keystone_implicitTenants: "true"\nrook_cephobjectstore_keystone_url: "https://api-int.testbed.osism.xyz:5000"\nrook_cephobjectstore_swift_urlPrefix: "swift"\n## keystone user\nrook_cephobjectstore_keystone_auth_type: "password"\nrook_cephobjectstore_keystone_project_domain_name: "Default"\nrook_cephobjectstore_keystone_project_name: "service"\nrook_cephobjectstore_keystone_user_domain_name: "Default"\nrook_cephobjectstore_keystone_username: "ceph_rgw"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["As well as in the ",(0,t.jsx)(n.code,{children:"environments/rook/secrets.yml"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/rook/secrets.yml"',children:"rook_cephobjectstore_keystone_passwor: supersecretpassword\n"})}),"\n",(0,t.jsx)(n.h2,{id:"change-node-labels",children:"Change node labels"}),"\n",(0,t.jsx)(n.p,{children:"In case you decided to move workloads to different nodes and changed the inventory groups e.g. like this:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"[rook-mds:children]\nceph-control\n\n[rook-mgr:children]\nceph-control\n\n[rook-mon:children]\nceph-control\n\n[rook-osd:children]\nceph-resource\n\n[rook-rgw:children]\nceph-control\n"})}),"\n",(0,t.jsx)(n.p,{children:"You can apply the changes running:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"osism apply rook-change-labels\n"})}),"\n",(0,t.jsx)(n.p,{children:"This will remove all labels and apply the changed inventory groups as labels. After those steps are done it will trigger the rescheduling of the components so they get deployed on the adjusted nodes."}),"\n",(0,t.jsx)(n.h2,{id:"cleanup",children:"Cleanup"}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsx)(n.p,{children:"This will permanently delete all your data in the Ceph Cluster. Be sure you know what you are doing before proceeding."})}),"\n",(0,t.jsxs)(n.p,{children:["If you want to cleanup/delete the whole cluster, you can do that by enabling ",(0,t.jsx)(n.code,{children:"rook_cleanup"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/rook/configuration.yml"',children:"rook_cleanup: true\n"})}),"\n",(0,t.jsxs)(n.p,{children:["And running the ",(0,t.jsx)(n.code,{children:"rook-cleanup"})," role."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply rook-cleanup\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},19365:(e,n,r)=>{r.d(n,{A:()=>i});r(96540);var o=r(18215);const t={tabItem:"tabItem_Ymn6"};var s=r(74848);function i(e){let{children:n,hidden:r,className:i}=e;return(0,s.jsx)("div",{role:"tabpanel",className:(0,o.A)(t.tabItem,i),hidden:r,children:n})}},11470:(e,n,r)=>{r.d(n,{A:()=>x});var o=r(96540),t=r(18215),s=r(23104),i=r(56347),a=r(205),l=r(57485),c=r(31682),d=r(70679);function h(e){return o.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,o.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:r}=e;return(0,o.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:r,attributes:o,default:t}}=e;return{value:n,label:r,attributes:o,default:t}}))}(r);return function(e){const n=(0,c.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,r])}function p(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:r}=e;const t=(0,i.W6)(),s=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,l.aZ)(s),(0,o.useCallback)((e=>{if(!s)return;const n=new URLSearchParams(t.location.search);n.set(s,e),t.replace({...t.location,search:n.toString()})}),[s,t])]}function f(e){const{defaultValue:n,queryString:r=!1,groupId:t}=e,s=u(e),[i,l]=(0,o.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!p({value:n,tabValues:r}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const o=r.find((e=>e.default))??r[0];if(!o)throw new Error("Unexpected error: 0 tabValues");return o.value}({defaultValue:n,tabValues:s}))),[c,h]=m({queryString:r,groupId:t}),[f,g]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,s]=(0,d.Dv)(r);return[t,(0,o.useCallback)((e=>{r&&s.set(e)}),[r,s])]}({groupId:t}),y=(()=>{const e=c??f;return p({value:e,tabValues:s})?e:null})();(0,a.A)((()=>{y&&l(y)}),[y]);return{selectedValue:i,selectValue:(0,o.useCallback)((e=>{if(!p({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);l(e),h(e),g(e)}),[h,g,s]),tabValues:s}}var g=r(92303);const y={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var v=r(74848);function k(e){let{className:n,block:r,selectedValue:o,selectValue:i,tabValues:a}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.a_)(),d=e=>{const n=e.currentTarget,r=l.indexOf(n),t=a[r].value;t!==o&&(c(n),i(t))},h=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;n=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;n=l[r]??l[l.length-1];break}}n?.focus()};return(0,v.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":r},n),children:a.map((e=>{let{value:n,label:r,attributes:s}=e;return(0,v.jsx)("li",{role:"tab",tabIndex:o===n?0:-1,"aria-selected":o===n,ref:e=>l.push(e),onKeyDown:h,onClick:d,...s,className:(0,t.A)("tabs__item",y.tabItem,s?.className,{"tabs__item--active":o===n}),children:r??n},n)}))})}function b(e){let{lazy:n,children:r,selectedValue:s}=e;const i=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===s));return e?(0,o.cloneElement)(e,{className:(0,t.A)("margin-top--md",e.props.className)}):null}return(0,v.jsx)("div",{className:"margin-top--md",children:i.map(((e,n)=>(0,o.cloneElement)(e,{key:n,hidden:e.props.value!==s})))})}function j(e){const n=f(e);return(0,v.jsxs)("div",{className:(0,t.A)("tabs-container",y.tabList),children:[(0,v.jsx)(k,{...n,...e}),(0,v.jsx)(b,{...n,...e})]})}function x(e){const n=(0,g.A)();return(0,v.jsx)(j,{...e,children:h(e.children)},String(n))}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>a});var o=r(96540);const t={},s=o.createContext(t);function i(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e747ec83.cdaefe9a.js b/assets/js/e747ec83.cdaefe9a.js new file mode 100644 index 0000000000..e0ad663582 --- /dev/null +++ b/assets/js/e747ec83.cdaefe9a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[39432],{93583:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"glossary","title":"Glossary","description":"This file serves as the central glossary within SCS. It is intended to clearly","source":"@site/docs/glossary.md","sourceDirName":".","slug":"/glossary","permalink":"/docs/glossary","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/glossary.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"FAQ","permalink":"/docs/faq/"}}');var a=t(74848),i=t(28453);const s={},r="Glossary",l={},c=[{value:"Definition of a Region",id:"definition-of-a-region",level:2},{value:"Definition of a Availability Zone",id:"definition-of-a-availability-zone",level:2},{value:"Definition of Host Aggregates",id:"definition-of-host-aggregates",level:2},{value:"Definition of a Cell",id:"definition-of-a-cell",level:2},{value:"Definition of a Control Plane",id:"definition-of-a-control-plane",level:2},{value:"Definition of Control Node",id:"definition-of-control-node",level:2},{value:"Definition of Compute Node",id:"definition-of-compute-node",level:2},{value:"Definition of Manager Node",id:"definition-of-manager-node",level:2},{value:"Definition of provider network",id:"definition-of-provider-network",level:2},{value:"Definition of API",id:"definition-of-api",level:2},{value:"Horizon",id:"horizon",level:2},{value:"Message Queue",id:"message-queue",level:2},{value:"Keystone",id:"keystone",level:2},{value:"Glance",id:"glance",level:2},{value:"OSISM",id:"osism",level:2},{value:"Ceph",id:"ceph",level:2},{value:"Nova",id:"nova",level:2},{value:"Neutron",id:"neutron",level:2},{value:"Cinder",id:"cinder",level:2},{value:"Swift",id:"swift",level:2},{value:"Ceph OSD",id:"ceph-osd",level:2},{value:"Personas",id:"personas",level:2}];function d(e){const n={h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"glossary",children:"Glossary"})}),"\n",(0,a.jsx)(n.p,{children:"This file serves as the central glossary within SCS. It is intended to clearly\ndefine terms used within SCS where there may be differing understandings. The\nglossary is not intended to evaluate or standardize specific terms."}),"\n",(0,a.jsx)(n.h2,{id:"definition-of-a-region",children:"Definition of a Region"}),"\n",(0,a.jsx)(n.p,{children:"An OpenStack/SCS region consists of at least one or more Availability Zones that share a Control Plane with their services. As a result, they share one API. Also a Control Plane can share one CEPH cluster over different fire departments or each Availbility Zone can have its own CEPH cluster. Within the region, any Layer 2 networks are available to the user. Availbility Zones which build a region are connected by redundant low-latency (< 2ms ) high-bandwidth (10s of Gbps) connections."}),"\n",(0,a.jsx)(n.p,{children:"Regions can be federated when the SCS code is ready."}),"\n",(0,a.jsx)(n.h2,{id:"definition-of-a-availability-zone",children:"Definition of a Availability Zone"}),"\n",(0,a.jsx)(n.p,{children:"An Availability Zone is a (physical) group of multiple compute nodes, controlled by the region's control plane that provides the API and interface."}),"\n",(0,a.jsx)(n.p,{children:"An Availability Zone allows OpenStack compute hosts to be divided into logical groups and provides a form of physical isolation and redundancy from other Availability Zones, for example by using a separate power supply or network devices."}),"\n",(0,a.jsx)(n.p,{children:"When users provision resources, they can specify in which Availability Zone their instances should be created. In this way, customers can ensure that their application resources are distributed across different failure domains to achieve high availability in the event of a hardware failure."}),"\n",(0,a.jsx)(n.h2,{id:"definition-of-host-aggregates",children:"Definition of Host Aggregates"}),"\n",(0,a.jsx)(n.p,{children:"Host aggregates are a mechanism for partitioning compute nodes which is not explicitly visible to users in an OpenStack/SCS cloud. Host aggregates are based on arbitrary characteristics such as server type, processor type, GPU, disk speed, etc.\nAdministrators assign flavors to host aggregates by specifying metadata on the host aggregate and customizing the extra specifications of the flavor. It is then up to the Nova scheduler to determine the best match for the user request. Compute nodes can also be in more than one host aggregate."}),"\n",(0,a.jsx)(n.p,{children:"Optionally, one can designate a host aggregate as an Availability Zone, e.g. for simplification reasons of the user selection of an availbility zone.\nAvailability Zones differ from Host Aggregates in that they are shown to the user as a Nova boot option, so Compute VMs can be started on them.\nCompute Nodes, however, can only be in a single Availability Zone. We can configure a default Availability Zone where instances will be scheduled if the user does not specify an Availability Zone."}),"\n",(0,a.jsx)(n.p,{children:"Info: A prerequisite for creating an Availability Zone is a host aggregate."}),"\n",(0,a.jsx)(n.h2,{id:"definition-of-a-cell",children:"Definition of a Cell"}),"\n",(0,a.jsx)(n.p,{children:"The Cells paradigm simplifies the handling of large Openstack deployments."}),"\n",(0,a.jsx)(n.p,{children:"Cells is an OpenStack Nova feature that improves scalability for Nova in OpenStack Platform. Each Cell has a separate database and message queue, which increases performance when scaling. One can provision additional Cells to handle large deployments, and compared to Regions, this allows access to a large number of compute nodes through a single API."}),"\n",(0,a.jsx)(n.p,{children:"Each Cell has its own Cell controllers running the database server and RabbitMQ along with the Nova Conductor services."}),"\n",(0,a.jsx)(n.p,{children:'Nova Conductor services, called "Super Conductor", continue to run on the main controller nodes.'}),"\n",(0,a.jsx)(n.p,{children:"The services in the Cell Controllers can still call placement APIs, but cannot access other API layer services via RPC, nor can they access global API databases on the control nodes."}),"\n",(0,a.jsx)(n.h2,{id:"definition-of-a-control-plane",children:"Definition of a Control Plane"}),"\n",(0,a.jsx)(n.p,{children:"In Openstack/SCS, a Control Plane consists of at least 5 hardware nodes, which together serve several Availability Zones and thus provide a common usable API for a region. The Control Plane also shares the network (Neutron), the Scheduler and the CEPH services."}),"\n",(0,a.jsx)(n.p,{children:"It includes the Controller Nodes (Galera Cluster, RabbitMQ) and the Manager Nodes, Maas,..."}),"\n",(0,a.jsx)(n.h2,{id:"definition-of-control-node",children:"Definition of Control Node"}),"\n",(0,a.jsx)(n.p,{children:"The Control Node runs the Identity Service, Image Service , management processes for compute nodes, management processes for networking, various networking agents, and the Dashboard. It also includes supporting services such as an SQL database, a message queue, and NTP."}),"\n",(0,a.jsx)(n.p,{children:"Optionally, the Controller Node runs parts of the Block Storage, Object Storage, Orchestration and Telemetry services."}),"\n",(0,a.jsx)(n.p,{children:"The Controller Node requires at least two network interfaces."}),"\n",(0,a.jsx)(n.h2,{id:"definition-of-compute-node",children:"Definition of Compute Node"}),"\n",(0,a.jsx)(n.p,{children:"A compute host runs the hypervisor part of compute that runs instances. By default, compute uses the KVM hypervisor. The compute host also runs a networking service agent that connects instances to virtual networks and provides firewall services to the instances through security groups."}),"\n",(0,a.jsx)(n.p,{children:"If you offer hyper-converged infrastructure, a compute host also serves the Ceph. This makes the storage dynamically scalable (horizontally and vertically). For the Ceph services, 1 CPU core and 4 GB of RAM are reserved per OSD to ensure appropriate performance."}),"\n",(0,a.jsx)(n.h2,{id:"definition-of-manager-node",children:"Definition of Manager Node"}),"\n",(0,a.jsx)(n.p,{children:"From here, the OSISM Ansible playbooks are applied to the environment. Furthermore, the following services often run here non-redundantly: Prometheus server,...."}),"\n",(0,a.jsx)(n.h2,{id:"definition-of-provider-network",children:"Definition of provider network"}),"\n",(0,a.jsx)(n.p,{children:'The provider network is the network that is "in front", i.e. at the output points of the openstack/SCS. This is usually a public network, but can also be a private network in individual cases. IPs from the provider network can be assigned to instances within the SCS. The same applies to load balancers, of course.'}),"\n",(0,a.jsx)(n.h2,{id:"definition-of-api",children:"Definition of API"}),"\n",(0,a.jsx)(n.p,{children:"The Rest API provides the core of openstack/SCS and can be addressed for a whole region. It accepts and responds to end-user API calls. The service supports the OpenStack Compute API, the Amazon EC2 API, and a special Admin API for privileged users to perform administrative actions. Policies are enforced and most orchestration actions can be started, such as launching an instance."}),"\n",(0,a.jsx)(n.h2,{id:"horizon",children:"Horizon"}),"\n",(0,a.jsx)(n.p,{children:"Horizon is openstack's preferred GUI for the end user, but also for the administrator for a quick overview. It runs on the controller node. Other GUIs are possible, also GUIs which replace the horizon interface"}),"\n",(0,a.jsx)(n.h2,{id:"message-queue",children:"Message Queue"}),"\n",(0,a.jsx)(n.p,{children:"Most OpenStack services communicate with each other through the message queue. For example, Compute communicates with Block Storage services and Network services via the message queue. RabbitMQ, Qpid, and Zeromq are popular choices for a message queue service. When the message queue fails or becomes inaccessible, the cluster generally comes to a halt and ends up in a read-only state where the information is stuck at the point where the last message was sent. Therefore, this is clustered. RabbitMQ has shown itself to be the most widespread and best supported variant in the OpenStack context, Qpid occurs occasionally, ZeroMQ lacks HA functionality to date"}),"\n",(0,a.jsx)(n.h2,{id:"keystone",children:"Keystone"}),"\n",(0,a.jsx)(n.p,{children:'( The OpenStack Identity module called Keystone is used as an authentication and rights system between the OpenStack components. Keystone divides access to projects in the cloud into so-called "tenants". A tenant is a tenant of the cloud and has at least one assigned user. It is possible to create multiple users per tenant with different rights. Keystone uses a token system for authorization and also supports the connection to other authentication options such as LDAP. (wikipedia) )'}),"\n",(0,a.jsx)(n.h2,{id:"glance",children:"Glance"}),"\n",(0,a.jsx)(n.p,{children:"The OpenStack Image Service, also called Glance, is a service that provides virtual machine images to OpenStack users. These images are used by Nova as a template to compile virtual machine instances. Both local hard disks and object storage solutions such as Swift or Ceph can be used as storage backends."}),"\n",(0,a.jsx)(n.p,{children:"In addition to the images, Glance can also store metadata such as the operating system used or the kernel version. Access to both this metadata and the images themselves is via a REST API. Glance supports a number of formats such as VHD, VMDK and qcow2."}),"\n",(0,a.jsx)(n.h2,{id:"osism",children:"OSISM"}),"\n",(0,a.jsx)(n.p,{children:"The Open Source Infrastructure & Service Manager is a powerful deployment framework for OpenStack and Ceph as well as required services such as a RabbitMQ broker or a MariaDB Galera cluster."}),"\n",(0,a.jsx)(n.h2,{id:"ceph",children:"Ceph"}),"\n",(0,a.jsx)(n.p,{children:"Ceph is an open source distributed storage solution. The core component is RADOS (Reliable Autonomic Distributed Object Store), an object store that can be distributed redundantly over any number of servers. Ceph offers the user three types of storage: An object store compatible with the Swift and S3 API (RADOS Gateway), virtual block devices (RADOS Block Devices) and CephFS, a distributed file system."}),"\n",(0,a.jsx)(n.h2,{id:"nova",children:"Nova"}),"\n",(0,a.jsx)(n.p,{children:"Nova is virtually a synonym for Compute. It is the part of the stack that can manage groups of virtual machines."}),"\n",(0,a.jsx)(n.p,{children:"The virtualized systems can be distributed over any number of so-called compute nodes. Hypervisors supported include KVM, Xen Hyper-V and ESXI. In the community, KVM is considered to be set and best supported (we use KVM), which is controlled via libvirt. ESXI and Hyper-V can be used, sometimes with limited functionality."}),"\n",(0,a.jsx)(n.h2,{id:"neutron",children:"Neutron"}),"\n",(0,a.jsx)(n.p,{children:'The OpenStack Networking module Neutron provides the networking service for OpenStack. Neutron can be used to manage networks, subnets, and IP addresses/floating IPs. A floating IP in OpenStack refers to an official IP that serves as an interface from the internal to the public network. In addition to a load balancer, HA proxy and health monitor, Neutron also supports techniques such as VLAN and VPN. To secure the networks, Neutron uses a firewall that allows versatile port rules, e.g. on a security group basis. For trademark reasons, the OpenStack networking module had to be renamed "Neutron". The previous name was "Quantum".'}),"\n",(0,a.jsx)(n.p,{children:"For the management of the data link layer, Neutron offers the possibility to use various already existing networking software such as Open vSwitch or the bridge functionality of the Linux kernel by means of plugins."}),"\n",(0,a.jsx)(n.p,{children:'In the OpenStack releases since Ussuri, the "OpenVirtualNetwork"(OVN) has established itself, it replaces many of the Neutron components, e.g. L3 and DHCP agent, so that Neutron only has to talk directly to OVN.'}),"\n",(0,a.jsx)(n.h2,{id:"cinder",children:"Cinder"}),"\n",(0,a.jsx)(n.p,{children:"OpenStack Block Storage or Cinder provides virtual block storage in the form of virtualized storage media (hard disks, CDs, etc.). The block storage can be attached to virtual machines. An API interface allows Cinder to connect to Swift so that block storage media can communicate with object storage. Meanwhile, many other storage backends are also fully or partially supported. There is also the option of defining multiple backends and creating a volume type for each backend, so that when a new volume is created, it can be selected on which storage backend the volume is created."}),"\n",(0,a.jsx)(n.h2,{id:"swift",children:"Swift"}),"\n",(0,a.jsx)(n.p,{children:"Swift is the so-called object storage that can be used by Nova. This is responsible for redundant data storage. Swift can also be used as a backend for Cinder or Glance. Objects are stored in so-called containers, which are primarily used to group objects and store metadata and in turn belong to individual accounts. Objects and containers are accessed via a REST API."}),"\n",(0,a.jsx)(n.h2,{id:"ceph-osd",children:"Ceph OSD"}),"\n",(0,a.jsx)(n.p,{children:"A Ceph OSD (Object Storage Daemon) logically represents a storage device in a Ceph cluster, which can logically be a hard disk, which is the ideal case. In other cases it can also be a raid, which however leads to considerable performance limitations due to caching or other raid optimization."}),"\n",(0,a.jsx)(n.h2,{id:"personas",children:"Personas"}),"\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Persona"}),(0,a.jsx)(n.th,{children:"Description"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"SCS Operator"}),(0,a.jsx)(n.td,{children:"The SCS Operator is the one who owns and operates a standardized cloud environment."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"SCS Operations Team"}),(0,a.jsx)(n.td,{children:"The team at the SCS Operator which actually runs the cloud environment."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"SCS Consumer"}),(0,a.jsx)(n.td,{children:"The SCS Consumer consumes a standardized SCS environment and operates and orchestrates applications on top of it. The SCS Consumer is typically a customer or user of the SCS Operator."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"SCS Integrator"}),(0,a.jsx)(n.td,{children:"The SCS Integrator assists in or is building up a standardized cloud environment. The SCS Integrator can be 2nd or 3rd level support for the SCS Operator."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"SCS Project"}),(0,a.jsx)(n.td,{children:"The SCS Project oversees the overall activities around the Sovereign Cloud Stack."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"SCS Developer"}),(0,a.jsx)(n.td,{children:"The SCS Developer actively contributes to technical elements of the Sovereign Cloud Stack."})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>r});var o=t(96540);const a={},i=o.createContext(a);function s(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e83ec39f.bb775013.js b/assets/js/e83ec39f.bb775013.js new file mode 100644 index 0000000000..e4bcb17cd0 --- /dev/null +++ b/assets/js/e83ec39f.bb775013.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[72439],{64832:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>d,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"iaas/guides/other-guides/developer-guide/style-guide","title":"Style Guide","description":"Ansible","source":"@site/docs/02-iaas/guides/other-guides/developer-guide/style-guide.md","sourceDirName":"02-iaas/guides/other-guides/developer-guide","slug":"/iaas/guides/other-guides/developer-guide/style-guide","permalink":"/docs/iaas/guides/other-guides/developer-guide/style-guide","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/developer-guide/style-guide.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Style Guide"},"sidebar":"docs","previous":{"title":"Scripts","permalink":"/docs/iaas/guides/other-guides/developer-guide/scripts"},"next":{"title":"Zuul CI","permalink":"/docs/iaas/guides/other-guides/developer-guide/zuul"}}');var l=s(74848),n=s(28453);const o={sidebar_label:"Style Guide"},r="Style Guide",d={},c=[{value:"Ansible",id:"ansible",level:2},{value:"Task names",id:"task-names",level:3},{value:"<code>become</code> directive",id:"become-directive",level:3},{value:"<code>when</code> directive",id:"when-directive",level:3},{value:"Lists as defaults",id:"lists-as-defaults",level:3},{value:"Containerfiles",id:"containerfiles",level:2},{value:"Commit messages",id:"commit-messages",level:2},{value:"Python",id:"python",level:2},{value:"Installation",id:"installation",level:3},{value:"Formatting a Single File",id:"formatting-a-single-file",level:3},{value:"Formatting Multiple Files and/or directories",id:"formatting-multiple-files-andor-directories",level:3},{value:"Formatting an Entire Project",id:"formatting-an-entire-project",level:3},{value:"Check Mode (Dry Run)",id:"check-mode-dry-run",level:3},{value:"Excluding Files or Directories",id:"excluding-files-or-directories",level:3},{value:"Integration with Code Editors",id:"integration-with-code-editors",level:3},{value:"Example of failed python-black Zuul job",id:"example-of-failed-python-black-zuul-job",level:3}];function a(e){const i={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,n.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(i.header,{children:(0,l.jsx)(i.h1,{id:"style-guide",children:"Style Guide"})}),"\n",(0,l.jsx)(i.h2,{id:"ansible",children:"Ansible"}),"\n",(0,l.jsxs)(i.p,{children:["We implement all the default rules of Ansible Lint. All default rules can be found in the\n",(0,l.jsx)(i.a,{href:"https://ansible.readthedocs.io/projects/lint/rules/",children:"Ansible Lint documentation"}),"."]}),"\n",(0,l.jsx)(i.h3,{id:"task-names",children:"Task names"}),"\n",(0,l.jsxs)(i.ul,{children:["\n",(0,l.jsx)(i.li,{children:"Tasks must always have names. The only exception allowed is for forked playbooks."}),"\n",(0,l.jsx)(i.li,{children:"A name never starts with a small letter"}),"\n",(0,l.jsx)(i.li,{children:"Names are written in present tense"}),"\n",(0,l.jsx)(i.li,{children:"No punctuation is used in names"}),"\n"]}),"\n",(0,l.jsxs)(i.h3,{id:"become-directive",children:[(0,l.jsx)(i.code,{children:"become"})," directive"]}),"\n",(0,l.jsxs)(i.p,{children:["The ",(0,l.jsx)(i.code,{children:"become"})," directive is only set when needed and is always set explicitly for each task that needs it."]}),"\n",(0,l.jsx)(i.p,{children:"Blocks, roles, or playbooks are never executed in a privileged mode."}),"\n",(0,l.jsxs)(i.p,{children:["We always insert the ",(0,l.jsx)(i.code,{children:"become"})," directive between the name of a task and the task itself. This also applies\nto related directives like ",(0,l.jsx)(i.code,{children:"become_user"})," or ",(0,l.jsx)(i.code,{children:"become_flags"}),". This is for better visibility if a task is\nprivileged or not."]}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-yaml",children:'- name: Copy hddtemp configuration file\n become: true\n ansible.builtin.copy:\n src: "{{ ansible_os_family }}/hddtemp"\n dest: "{{ hddtemp_conf_file }}"\n owner: root\n group: root\n mode: 0644\n notify: Restart hddtemp service\n'})}),"\n",(0,l.jsxs)(i.h3,{id:"when-directive",children:[(0,l.jsx)(i.code,{children:"when"})," directive"]}),"\n",(0,l.jsxs)(i.p,{children:["If you need to use the ",(0,l.jsx)(i.code,{children:"when"})," directive add this at the end-section from the task where it is needed. This\nmakes the code easier to understand for others."]}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-yaml",children:'- name: "Archive existing {{ resolvconf_file }} file"\n become: true\n ansible.posix.synchronize:\n src: "/etc/resolv.conf"\n dest: "/etc/resolv.conf.{{ ansible_date_time.date }}"\n archive: true\n delegate_to: "{{ inventory_hostname }}"\n when: stat_resolvconf_file.stat.islnk is defined and not stat_resolvconf_file.stat.islnk\n'})}),"\n",(0,l.jsx)(i.h3,{id:"lists-as-defaults",children:"Lists as defaults"}),"\n",(0,l.jsx)(i.p,{children:"Defaults that provide a list are always defined as in the following example."}),"\n",(0,l.jsxs)(i.p,{children:[(0,l.jsx)(i.code,{children:"docker_hosts_defaults"})," sets the defaults in the role. Overriding is only possible with the ",(0,l.jsx)(i.code,{children:"defaults"})," repository."]}),"\n",(0,l.jsxs)(i.p,{children:["In the configuration repository, ",(0,l.jsx)(i.code,{children:"docker_hosts_extra"})," is then used to add additional items to the list."]}),"\n",(0,l.jsxs)(i.p,{children:[(0,l.jsx)(i.code,{children:"docker_hosts"})," itself is never modified from the outside."]}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{className:"language-yaml",children:'docker_hosts_defaults:\n - "unix:///var/run/docker.sock"\ndocker_hosts_extra: []\ndocker_hosts: "{{ docker_hosts_defaults + docker_hosts_extra }}"\n'})}),"\n",(0,l.jsx)(i.h2,{id:"containerfiles",children:"Containerfiles"}),"\n",(0,l.jsx)(i.h2,{id:"commit-messages",children:"Commit messages"}),"\n",(0,l.jsx)(i.h2,{id:"python",children:"Python"}),"\n",(0,l.jsxs)(i.p,{children:[(0,l.jsx)(i.a,{href:"https://github.com/psf/black",children:"Black"})," is a popular Python code formatter that automatically\nformats your code to adhere to a consistent style. We use it to automatically format the\nsyntax of Python. A job is running in the CI that checks, if Black has been applied. Therefore,\nformat the files with Black accordingly in advance."]}),"\n",(0,l.jsx)(i.h3,{id:"installation",children:"Installation"}),"\n",(0,l.jsx)(i.p,{children:(0,l.jsx)(i.code,{children:"pip install black"})}),"\n",(0,l.jsx)(i.h3,{id:"formatting-a-single-file",children:"Formatting a Single File"}),"\n",(0,l.jsx)(i.p,{children:(0,l.jsx)(i.code,{children:"black myfile.py"})}),"\n",(0,l.jsx)(i.h3,{id:"formatting-multiple-files-andor-directories",children:"Formatting Multiple Files and/or directories"}),"\n",(0,l.jsx)(i.p,{children:(0,l.jsx)(i.code,{children:"black file1.py file2.py dir/"})}),"\n",(0,l.jsx)(i.h3,{id:"formatting-an-entire-project",children:"Formatting an Entire Project"}),"\n",(0,l.jsx)(i.p,{children:"This command will format all Python files in the current directory and its subdirectories:"}),"\n",(0,l.jsx)(i.p,{children:(0,l.jsx)(i.code,{children:"black ."})}),"\n",(0,l.jsx)(i.h3,{id:"check-mode-dry-run",children:"Check Mode (Dry Run)"}),"\n",(0,l.jsxs)(i.p,{children:["Running Black with the ",(0,l.jsx)(i.code,{children:"--check"})," option performs a dry run and reports files that would be\nchanged without actually modifying them:"]}),"\n",(0,l.jsx)(i.p,{children:(0,l.jsx)(i.code,{children:"black --check myfile.py"})}),"\n",(0,l.jsx)(i.h3,{id:"excluding-files-or-directories",children:"Excluding Files or Directories"}),"\n",(0,l.jsxs)(i.p,{children:["You can exclude files or directories from formatting using the ",(0,l.jsx)(i.code,{children:"--exclude"})," option:"]}),"\n",(0,l.jsx)(i.p,{children:(0,l.jsx)(i.code,{children:"black --exclude=dir_to_exclude/ ."})}),"\n",(0,l.jsx)(i.h3,{id:"integration-with-code-editors",children:"Integration with Code Editors"}),"\n",(0,l.jsx)(i.p,{children:"Many code editors have extensions or plugins that can automatically run Black on your code.\nFor example, if you're using VSCode or PyCharm, you can easily integrate it into your IDE."}),"\n",(0,l.jsx)(i.h3,{id:"example-of-failed-python-black-zuul-job",children:"Example of failed python-black Zuul job"}),"\n",(0,l.jsx)(i.p,{children:"job-output.txt:"}),"\n",(0,l.jsx)(i.pre,{children:(0,l.jsx)(i.code,{children:'[\u2026]\n2023-11-16 14:38:14.149756 | TASK [python-black : Install pip module black]\n2023-11-16 14:38:18.717886 | ubuntu-jammy | changed\n2023-11-16 14:38:18.723062 |\n2023-11-16 14:38:18.723137 | TASK [python-black : Format code with Black if there is nothing to exclude]\n2023-11-16 14:38:19.138060 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/adminer.py\n2023-11-16 14:38:19.151965 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/bird.py\n2023-11-16 14:38:19.163608 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/auditd.py\n2023-11-16 14:38:19.187772 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cephclient/package.py\n2023-11-16 14:38:19.192695 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cephclient/container.py\n2023-11-16 14:38:19.219694 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cgit.py\n2023-11-16 14:38:19.230577 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/dnsdist.py\n2023-11-16 14:38:19.275681 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/hddtemp/redhat.py\n2023-11-16 14:38:19.300350 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/homer.py\n2023-11-16 14:38:19.310641 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/lldpd.py\n2023-11-16 14:38:19.318096 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/docker.py\n2023-11-16 14:38:19.329099 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/osquery.py\n2023-11-16 14:38:19.344766 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/rsyslog.py\n2023-11-16 14:38:19.358190 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/smartd.py\n2023-11-16 14:38:19.363578 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/tuned.py\n2023-11-16 14:38:19.389205 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/util/util.py\n2023-11-16 14:38:19.406360 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_container_facts.py\n2023-11-16 14:38:19.415046 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/filter/address.py\n2023-11-16 14:38:19.473508 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_toolbox.py\n2023-11-16 14:38:19.908963 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_docker.py\n2023-11-16 14:38:19.914395 | ubuntu-jammy |\n2023-11-16 14:38:19.914412 | ubuntu-jammy | Oh no! \xf0\u0178\u2019\xa5 \xf0\u0178\u2019\u201d \xf0\u0178\u2019\xa5\n2023-11-16 14:38:19.914419 | ubuntu-jammy | 20 files would be reformatted, 18 files would be left unchanged.\n2023-11-16 14:38:20.249358 | ubuntu-jammy | ERROR\n2023-11-16 14:38:20.249501 | ubuntu-jammy | {\n2023-11-16 14:38:20.249533 | ubuntu-jammy | "delta": "0:00:01.053565",\n2023-11-16 14:38:20.249553 | ubuntu-jammy | "end": "2023-11-16 14:38:19.932073",\n2023-11-16 14:38:20.249571 | ubuntu-jammy | "msg": "non-zero return code",\n2023-11-16 14:38:20.249587 | ubuntu-jammy | "rc": 1,\n2023-11-16 14:38:20.249603 | ubuntu-jammy | "start": "2023-11-16 14:38:18.878508"\n2023-11-16 14:38:20.249618 | ubuntu-jammy | }\n[\u2026]\n'})})]})}function u(e={}){const{wrapper:i}={...(0,n.R)(),...e.components};return i?(0,l.jsx)(i,{...e,children:(0,l.jsx)(a,{...e})}):a(e)}},28453:(e,i,s)=>{s.d(i,{R:()=>o,x:()=>r});var t=s(96540);const l={},n=t.createContext(l);function o(e){const i=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:o(e.components),t.createElement(n.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e84ae951.6420a661.js b/assets/js/e84ae951.6420a661.js new file mode 100644 index 0000000000..42c356798d --- /dev/null +++ b/assets/js/e84ae951.6420a661.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[10329],{5913:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"scs-0116-v1-key-manager-standard","title":"SCS Key Manager Standard","description":"Introduction","source":"@site/standards/scs-0116-v1-key-manager-standard.md","sourceDirName":".","slug":"/scs-0116-v1-key-manager-standard","permalink":"/standards/scs-0116-v1-key-manager-standard","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS Key Manager Standard","type":"Standard","status":"Stable","stabilized_at":"2024-11-13T00:00:00.000Z","track":"IaaS"},"sidebar":"standards","previous":{"title":"scs-0116: SCS Key Manager Standard","permalink":"/standards/iaas/scs-0116"},"next":{"title":"W1","permalink":"/standards/scs-0116-w1-key-manager-implementation-testing"}}');var s=t(74848),r=t(28453);const i={title:"SCS Key Manager Standard",type:"Standard",status:"Stable",stabilized_at:new Date("2024-11-13T00:00:00.000Z"),track:"IaaS"},o=void 0,d={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Recommend or even mandate specific Key Manager plugins",id:"recommend-or-even-mandate-specific-key-manager-plugins",level:4},{value:"Recommendation regarding the handling of the Master KEK",id:"recommendation-regarding-the-handling-of-the-master-kek",level:4},{value:"Standardization of the Key Manager Policy",id:"standardization-of-the-key-manager-policy",level:4},{value:"Key Manager Standard",id:"key-manager-standard",level:2},{value:"Key Manager Policies",id:"key-manager-policies",level:3},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function l(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",section:"section",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"To encrypt user data like volumes or in the future also Images and ephemeral storage for VMs, the key has to be present in the infrastructure.\nA Key Manager service within the infrastructure can be utilized to store keys.\nConsequently providing keys for every encryption or decryption is possible without including the user.\nAlso authorization policies can be applied on every request to the Key Manager service.\nOpenStack offers a Key Manager implementation that is named Barbican, which provides these features.\nThis standard aims to provide a base level of security for Cloud Service Providers that integrate a Key Manager into their deployments."}),"\n",(0,s.jsx)(n.h2,{id:"terminology",children:"Terminology"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Term"}),(0,s.jsx)(n.th,{children:"Meaning"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"API"}),(0,s.jsx)(n.td,{children:"Application Programming Interface, often referring to the REST API interfaces provided by OpenStack and related services"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Barbican"}),(0,s.jsx)(n.td,{children:"The Key Manager implementation in OpenStack"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"CSP"}),(0,s.jsx)(n.td,{children:"Cloud Service Provider, provider managing the OpenStack infrastructure"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"IaaS"}),(0,s.jsx)(n.td,{children:"Infrastructure-as-a-Service"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"HSM"}),(0,s.jsx)(n.td,{children:"Hardware Security Module"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"KEK"}),(0,s.jsx)(n.td,{children:"Key Encryption Key"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"RBAC"}),(0,s.jsx)(n.td,{children:"Role Based Access Control"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(n.p,{children:"User data encryption requires an encryption key to be known during encryption and decryption processes.\nKey Managers like Barbican provide this functionality on the IaaS-Level.\nNot every IaaS deployment currently offers user data encryption as part of their standard offering.\nThis standard should encourage CSPs to integrate a Key Manager and thus increase the amount of Clouds with offerings of data encryption.\nIt is also important to take a closer look into the Key Manager and analyze how such a service can be configured securely."}),"\n",(0,s.jsx)(n.p,{children:"A Key Manager service manages keys in a secure manner, but this can be achieved differently and is not primarily in scope of this standard.\nThe OpenStack Key Manager Barbican stores keys encrypted with a project specific KEK in the database.\nThe KEKs are also stored encrypted in the same database.\nThe Master-KEK, used to encrypt the project specific KEKs is not stored in the database and is stored differently depending on the backend storage plugin used.\nThis standard also abstracts the used plugins and wants to ensure that the Master-KEK is protected, too."}),"\n",(0,s.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsx)(n.p,{children:"While discussing what this standard should aim for it was discovered that some CSPs don't use Barbican or another Key Manager at all and do not provide the feature to encrypt user data to their customers.\nThis should change, but the exact change comes with financial burden, when choosing a plugin in Barbican to store the Master-KEK or choosing to integrate another Key Manager service instead.\nTo minimize the burden and enable more CSPs to step up and provide encryption, this standard will only make recommendations about plugins from Barbican."}),"\n",(0,s.jsx)(n.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,s.jsx)(n.h4,{id:"recommend-or-even-mandate-specific-key-manager-plugins",children:"Recommend or even mandate specific Key Manager plugins"}),"\n",(0,s.jsx)(n.p,{children:"It was considered to only recommend a certain set of plugins or backends for the Key Manager, but this may be very prone to change if e.g. Barbican adds a new plugin.\nAs the SCS only wants to mandate the API that can be abstracted through the Castellan library in OpenStack, integrating any other Key Manager implementation is not uncommon, so this standard needs to consider other possible Key Managers as well.\nDue to these reasons this option was disregarded."}),"\n",(0,s.jsx)(n.h4,{id:"recommendation-regarding-the-handling-of-the-master-kek",children:"Recommendation regarding the handling of the Master KEK"}),"\n",(0,s.jsx)(n.p,{children:"Looking into the available Barbican plugins and possible attack vectors one design decision in the plugins is very important: where and how to store the Master-KEK.\nBecause the Plugins might use different technologies there are many locations for the Master KEK possible.\nMost of the Plugins increase the security level by not storing the Master-KEK in plain text on the physical machine Barbican is running on.\nThis mechanism as a whole, is something that CSPs should aim to do."}),"\n",(0,s.jsx)(n.h4,{id:"standardization-of-the-key-manager-policy",children:"Standardization of the Key Manager Policy"}),"\n",(0,s.jsxs)(n.p,{children:["Because this standards recommends or even eventually mandates the presence of a Key Manager, the situation about the policy of the Key Manager needs to be discussed.\nThe policy of an IaaS service should use the same roles as the other IaaS services.\nUnfortunately this does not apply to the Key Manager implementation Barbican.\nIt has the roles ",(0,s.jsx)(n.code,{children:"reader"}),", ",(0,s.jsx)(n.code,{children:"audit"})," and ",(0,s.jsx)(n.code,{children:"creator"}),", which are not present in the Keystone role concept.\nThe roles a customer usually gets through the Identity API is ",(0,s.jsx)(n.code,{children:"member"}),".\nLeaving it this way will prevent users from creating and using secrets even when a Key Manager is integrated."]}),"\n",(0,s.jsxs)(n.p,{children:["To unify the roles among all IaaS services, there is currently work done in the OpenStack Community.\nThis initiative is called secure RBAC",(0,s.jsx)(n.sup,{children:(0,s.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),".\nAlso the SCS is discussing a standard concerning the roles",(0,s.jsx)(n.sup,{children:(0,s.jsx)(n.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),".\nWhen this is done, there is no further work needed.\nBut as of the 2024.1 release, this is still under development."]}),"\n",(0,s.jsxs)(n.p,{children:["In conclusion this standard should mandate everyone who uses a Key Manager that does not include the secure RBAC, to adjust the policies to have a mapping between the internal ",(0,s.jsx)(n.code,{children:"creator"})," and the identity-based ",(0,s.jsx)(n.code,{children:"member"})," role.\nThis will result in a ",(0,s.jsx)(n.code,{children:"member"})," being allowed to do everything a ",(0,s.jsx)(n.code,{children:"creator"})," can do."]}),"\n",(0,s.jsx)(n.h2,{id:"key-manager-standard",children:"Key Manager Standard"}),"\n",(0,s.jsx)(n.p,{children:"To increase security and allow user data encryption, CSPs SHOULD implement the Key Manager API (e.g. implemented by Barbican).\nThe Keys managed by this Key Manager MUST be stored encrypted and the Master-KEK of the Key Manager MUST be stored in another place than the Keys."}),"\n",(0,s.jsx)(n.p,{children:"If possible CSPs SHOULD NOT store the Master-KEK in plain-text on the physical host the Key Manager is running on."}),"\n",(0,s.jsx)(n.h3,{id:"key-manager-policies",children:"Key Manager Policies"}),"\n",(0,s.jsxs)(n.p,{children:["If a Key Manager without secure RBAC enabled is used, the policies MUST be adjusted to let the ",(0,s.jsx)(n.code,{children:"member"})," role of the Identity service be equivalent to the Key Manager internal ",(0,s.jsx)(n.code,{children:"creator"})," role."]}),"\n",(0,s.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/de/security-guide/secrets-management/barbican.html",children:"Barbican Plugins"})}),"\n",(0,s.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsx)(n.p,{children:"Conformance must be tested in two steps."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"The check whether a Key Manager is present can be done in a similar way as in the mandatory OpenStack service APIs standard and the test should be merged into the mandatory service test as soon as a Key Manager is required in scs-conformant infrastructures."}),"\n",(0,s.jsx)(n.li,{children:"The check, that there is no Master-KEK present on the Key Manager Node, has to be done by the CSP themself."}),"\n"]}),"\n","\n",(0,s.jsxs)(n.section,{"data-footnotes":!0,className:"footnotes",children:[(0,s.jsx)(n.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{id:"user-content-fn-1",children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://etherpad.opendev.org/p/rbac-goal-tracking",children:"Secure RBAC work in OpenStack"})," ",(0,s.jsx)(n.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{id:"user-content-fn-2",children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/issues/issues/396",children:"Issue for a role standard in SCS"})," ",(0,s.jsx)(n.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>o});var a=t(96540);const s={},r=a.createContext(s);function i(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ea470413.59e25e2e.js b/assets/js/ea470413.59e25e2e.js new file mode 100644 index 0000000000..95e710815e --- /dev/null +++ b/assets/js/ea470413.59e25e2e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[38730],{72067:(t,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>e,toc:()=>l});const e=JSON.parse('{"id":"collaboration/sig-monitoring","title":"SIG Monitoring","description":"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.","source":"@site/community/collaboration/sig-monitoring.md","sourceDirName":"collaboration","slug":"/collaboration/sig-monitoring","permalink":"/community/collaboration/sig-monitoring","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"SIG Documentation","permalink":"/community/collaboration/sig-documentation"},"next":{"title":"SIG Standardization","permalink":"/community/collaboration/sig-standardization"}}');var i=o(74848),r=o(28453);const s={},a="SIG Monitoring",c={},l=[];function d(t){const n={h1:"h1",header:"header",p:"p",...(0,r.R)(),...t.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"sig-monitoring",children:"SIG Monitoring"})}),"\n",(0,i.jsx)(n.p,{children:"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."})]})}function u(t={}){const{wrapper:n}={...(0,r.R)(),...t.components};return n?(0,i.jsx)(n,{...t,children:(0,i.jsx)(d,{...t})}):d(t)}},28453:(t,n,o)=>{o.d(n,{R:()=>s,x:()=>a});var e=o(96540);const i={},r=e.createContext(i);function s(t){const n=e.useContext(r);return e.useMemo((function(){return"function"==typeof t?t(n):{...n,...t}}),[n,t])}function a(t){let n;return n=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:s(t.components),e.createElement(r.Provider,{value:n},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/ea6d9109.a6de4ddb.js b/assets/js/ea6d9109.a6de4ddb.js new file mode 100644 index 0000000000..41641f8535 --- /dev/null +++ b/assets/js/ea6d9109.a6de4ddb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5912],{4355:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Web","slug":"/category/web","permalink":"/docs/category/web","sidebar":"docs","navigation":{"previous":{"title":"FAQ","permalink":"/docs/operating-scs/components/status-page-deployment/docs/faq"},"next":{"title":"Overview","permalink":"/docs/operating-scs/components/status-page-web/docs/overview"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/eaf69a59.2b56db9e.js b/assets/js/eaf69a59.2b56db9e.js new file mode 100644 index 0000000000..646a09f137 --- /dev/null +++ b/assets/js/eaf69a59.2b56db9e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[57633],{52705:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","title":"Troubleshooting","description":"This guide explains general info on how to debug issues if a cluster creation fails.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs","slug":"/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting.md","tags":[],"version":"current","frontMatter":{}}');var s=n(74848),c=n(28453);const r={},i="Troubleshooting",a={},l=[{value:"providerClient authentication err",id:"providerclient-authentication-err",level:2}];function u(e){const t={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,c.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"troubleshooting",children:"Troubleshooting"})}),"\n",(0,s.jsx)(t.p,{children:"This guide explains general info on how to debug issues if a cluster creation fails."}),"\n",(0,s.jsx)(t.h2,{id:"providerclient-authentication-err",children:"providerClient authentication err"}),"\n",(0,s.jsx)(t.p,{children:"If you are using https, and when you encounter issues like:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:'kubectl logs -n cspo-system -l control-plane=controller-manager\n...\n[manager] 2024-04-15T15:20:07Z\tDEBUG\tevents\tPost "https://10.0.3.15/identity/v3/auth/tokens": tls: failed to verify certificate: x509: certificate signed by unknown authority\t{"type": "Warning", "object": {"kind":"OpenStackNodeImageRelease","namespace":"cluster","name":"openstack-ferrol-1-27-ubuntu-capi-image-v1.27.8-v2","uid":"93d2c1c8-5a19-45f8-9f93-8e8bd5227ebf","apiVersion":"infrastructure.clusterstack.x-k8s.io/v1alpha1","resourceVersion":"3773"}, "reason": "OpenStackProviderClientNotSet"}\n...\n'})}),"\n",(0,s.jsx)(t.p,{children:"you must specify the CA certificate in your secret, which contains the access data to the OpenStack instance, then secret should look similar to this example:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'apiVersion: v1\ndata:\n cacert: <PEM_ENCODED_CA_CERT>\n clouds.yaml: <ENCODED_CLOUDS_YAML>\nkind: Secret\nmetadata:\n labels:\n clusterctl.cluster.x-k8s.io/move: "true"\n name: "openstack"\n namespace: cluster\n'})})]})}function d(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>i});var o=n(96540);const s={},c=o.createContext(s);function r(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eb99bfed.fbf47341.js b/assets/js/eb99bfed.fbf47341.js new file mode 100644 index 0000000000..8c3a31ea6f --- /dev/null +++ b/assets/js/eb99bfed.fbf47341.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6063],{67420:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"iaas/guides/troubleshooting-guide/manager","title":"Manager","description":"Reset","source":"@site/docs/02-iaas/guides/troubleshooting-guide/manager.md","sourceDirName":"02-iaas/guides/troubleshooting-guide","slug":"/iaas/guides/troubleshooting-guide/manager","permalink":"/docs/iaas/guides/troubleshooting-guide/manager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/troubleshooting-guide/manager.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Manager","sidebar_position":10},"sidebar":"docs","previous":{"title":"Troubleshooting Guide","permalink":"/docs/iaas/guides/troubleshooting-guide/"},"next":{"title":"OpenStack","permalink":"/docs/iaas/guides/troubleshooting-guide/openstack"}}');var a=s(74848),i=s(28453);const o={sidebar_label:"Manager",sidebar_position:10},r="Manager",c={},l=[{value:"Reset",id:"reset",level:2}];function u(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"manager",children:"Manager"})}),"\n",(0,a.jsx)(n.h2,{id:"reset",children:"Reset"}),"\n",(0,a.jsx)(n.p,{children:"Sometimes it is necessary to reset the entire manager service."}),"\n",(0,a.jsx)(n.admonition,{type:"warning",children:(0,a.jsx)(n.p,{children:"This is a disruptive action. Data is lost in the process. For example, the database\nof the ARA service."})}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Stop the manager service"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"sudo systemctl stop docker-compose@manager.service\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Files on the ",(0,a.jsx)(n.code,{children:"/share"})," volume are backed up in advance and restored after\nthe manager service is started."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"docker run --rm \\\n --mount source=manager_share,target=/share \\\n --volume $(pwd):/backup \\\n busybox \\\n tar -czvf /backup/manager-share-$(date +%Y%m%d).tar.gz /share\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Delete the manager service. ",(0,a.jsx)(n.strong,{children:"This is a disruptive action."})]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"docker compose --project-directory /opt/manager down -v\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Start the manager service"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"sudo systemctl start docker-compose@manager.service\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Restore the files on the ",(0,a.jsx)(n.code,{children:"/share"})," volume."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"docker run --rm \\\n --mount source=manager_share,target=/share \\\n --volume $(pwd):/backup \\\n busybox \\\n tar -xzvf /backup/manager-share-$(date +%Y%m%d).tar.gz -C /\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Check that manager service is healthy"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"docker compose --project-directory /opt/manager ps\n"})}),"\n",(0,a.jsx)(n.p,{children:"Depending on what the manager service looks like, this output may vary."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:'NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS\nceph-ansible quay.io/osism/ceph-ansible:quincy "/entrypoint.sh osis\u2026" ceph-ansible About a minute ago Up About a minute (healthy)\nkolla-ansible quay.io/osism/kolla-ansible:2023.2 "/entrypoint.sh osis\u2026" kolla-ansible About a minute ago Up About a minute (healthy)\nmanager-api-1 quay.io/osism/osism:latest "osism service api" api About a minute ago Up About a minute (healthy) 192.168.16.5:8000->8000/tcp\nmanager-ara-server-1 quay.io/osism/ara-server:latest "sh -c \'/wait && /ru\u2026" ara-server About a minute ago Up About a minute (healthy) 8000/tcp\nmanager-beat-1 quay.io/osism/osism:latest "osism service beat" beat About a minute ago Up About a minute (healthy)\nmanager-conductor-1 quay.io/osism/osism:latest "osism worker conduc\u2026" conductor About a minute ago Up About a minute (healthy)\nmanager-flower-1 quay.io/osism/osism:latest "osism service flower" flower About a minute ago Up About a minute (healthy)\nmanager-inventory_reconciler-1 quay.io/osism/inventory-reconciler:latest "/sbin/tini -- /entr\u2026" inventory_reconciler About a minute ago Up About a minute (healthy)\nmanager-listener-1 quay.io/osism/osism:latest "osism service liste\u2026" listener About a minute ago Up About a minute (healthy)\nmanager-mariadb-1 index.docker.io/library/mariadb:11.3.2 "docker-entrypoint.s\u2026" mariadb About a minute ago Up About a minute (healthy) 3306/tcp\nmanager-netbox-1 quay.io/osism/osism-netbox:latest "osism worker netbox" netbox About a minute ago Up About a minute (healthy)\nmanager-openstack-1 quay.io/osism/osism:latest "osism worker openst\u2026" openstack About a minute ago Up About a minute (healthy)\nmanager-redis-1 index.docker.io/library/redis:7.2.4-alpine "docker-entrypoint.s\u2026" redis About a minute ago Up About a minute (healthy) 6379/tcp\nmanager-watchdog-1 quay.io/osism/osism:latest "osism service watch\u2026" watchdog About a minute ago Up About a minute (healthy)\nosism-ansible quay.io/osism/osism-ansible:latest "/entrypoint.sh osis\u2026" osism-ansible About a minute ago Up About a minute (healthy)\nosismclient quay.io/osism/osism:latest "sleep infinity" osismclient About a minute ago Up About a minute\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"When the manager service is healthy, the inventory and the fact cache\nmust be rebuilt."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism reconciler sync\nosism apply facts\n"})}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var t=s(96540);const a={},i=t.createContext(a);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ecbad217.01bde511.js b/assets/js/ecbad217.01bde511.js new file mode 100644 index 0000000000..b16f97d0b3 --- /dev/null +++ b/assets/js/ecbad217.01bde511.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[96454],{52988:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>p,frontMatter:()=>l,metadata:()=>s,toc:()=>u});const s=JSON.parse('{"id":"iaas/guides/upgrade-guide/manager","title":"Manager","description":"Always read the release notes first to learn what has changed and what","source":"@site/docs/02-iaas/guides/upgrade-guide/manager.mdx","sourceDirName":"02-iaas/guides/upgrade-guide","slug":"/iaas/guides/upgrade-guide/manager","permalink":"/docs/iaas/guides/upgrade-guide/manager","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/manager.mdx","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"sidebar_label":"Manager","sidebar_position":10},"sidebar":"docs","previous":{"title":"Upgrade Guide","permalink":"/docs/iaas/guides/upgrade-guide/"},"next":{"title":"Network","permalink":"/docs/iaas/guides/upgrade-guide/network"}}');var t=r(74848),a=r(28453),i=r(11470),o=r(19365);const l={sidebar_label:"Manager",sidebar_position:10},c="Manager",d={},u=[];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"manager",children:"Manager"})}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsxs)(n.p,{children:["Always read the ",(0,t.jsx)(n.a,{href:"https://osism.tech/docs/release-notes/",children:"release notes"})," first to learn what has changed and what\nadjustments are necessary. Read the release notes even if you are only updating from e.g. 7.0.2 to 7.0.5."]})}),"\n",(0,t.jsx)(n.p,{children:"The update of a manager service with a stable release of OSISM is described here.\nIn the example, OSISM release 7.0.5 is used."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Change the OSISM release in the configuration repository."}),"\n",(0,t.jsx)(n.p,{children:"1.1. Set the new OSISM version in the configuration repository."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'MANAGER_VERSION=7.0.5\nsed -i -e "s/manager_version: .*/manager_version: ${MANAGER_VERSION}/g" environments/manager/configuration.yml\n'})}),"\n",(0,t.jsxs)(n.p,{children:["1.2. If ",(0,t.jsx)(n.code,{children:"openstack_version"})," or ",(0,t.jsx)(n.code,{children:"ceph_version"})," are set in ",(0,t.jsx)(n.code,{children:"environments/manager/configuration.yml"}),"\n(or anywhere else), they must be removed. If these are set, the stable release is not used for\nthese components."]}),"\n",(0,t.jsx)(n.p,{children:"1.3. Sync the image versions and files in the configuration repository."}),"\n",(0,t.jsxs)(i.A,{children:[(0,t.jsx)(o.A,{value:"osism-7",label:"OSISM >= 7.0.0",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"make sync\n"})})}),(0,t.jsxs)(o.A,{value:"osism-6",label:"OSISM < 7.0.0",children:[(0,t.jsxs)(n.p,{children:["If Gilt is not installed via the ",(0,t.jsx)(n.code,{children:"requirements.txt"})," of the manager environment it is\nimportant to use a version smaller v2. The v2 of Gilt is not yet usable."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"gilt overlay # you have to do this 2x, this is not a copy & paste error\ngilt overlay\n"})}),(0,t.jsxs)(n.p,{children:["Optionally, this is normally not necessary, it is possible to reference a specific tag of the\n",(0,t.jsx)(n.a,{href:"https://github.com/osism/cfg-generics",children:"osism/cfg-generics"})," repository. To do this, first\ncheck which version of osism/cfg-generics is used in a particular release. The version is\ndefined in ",(0,t.jsx)(n.code,{children:"generics_version"})," in the ",(0,t.jsx)(n.code,{children:"base.yml"})," file in the ",(0,t.jsx)(n.code,{children:"osism/release"})," repository. For OSISM 6.0.0,\nfor example, this is version ",(0,t.jsx)(n.a,{href:"https://github.com/osism/release/blob/main/6.0.0/base.yml#L6",children:"v0.20230919.0"}),".\nThis version is then added to the file ",(0,t.jsx)(n.code,{children:"gilt.yml"})," in the configuration repository instead of\n",(0,t.jsx)(n.code,{children:"main"})," at ",(0,t.jsx)(n.code,{children:"version"}),". This change must be made again after each execution of ",(0,t.jsx)(n.code,{children:"gilt overlay"})," as\nit is overwritten by the call of ",(0,t.jsx)(n.code,{children:"gilt overlay"}),". This cannot be realized differently in the\ncurrent implementation of ",(0,t.jsx)(n.a,{href:"https://github.com/retr0h/gilt",children:"Gilt"}),"."]})]})]}),"\n",(0,t.jsx)(n.p,{children:"1.4. Commit and push all changes in the configuration repository. Since everyone here has their own\nworkflows for changes to the configuration repository, only a generic example for Git."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'git commit -a -s -m "manager: use OSISM version 7.0.5"\ngit push\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Update the configuration repository on the manager node."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply configuration\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Update the manager service on the manager node."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism update manager\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["If Ansible Vault was used to encrypt ",(0,t.jsx)(n.code,{children:"environments/manager/secrets.yml"}),", the parameter\n",(0,t.jsx)(n.code,{children:"--ask-vault-pass"})," is also appended. From OSISM >= 8.0.0 this is no longer necessary."]}),"\n",(0,t.jsxs)(n.li,{children:["If ",(0,t.jsx)(n.code,{children:"osism update manager"})," does not work yet, use ",(0,t.jsx)(n.code,{children:"osism-update-manager"})," instead."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Refresh the facts cache."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply facts\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["If Traefik is used on the manager node (",(0,t.jsx)(n.code,{children:"traefik_enable: true"})," in ",(0,t.jsx)(n.code,{children:"environments/infrastructure/configuration.yml"}),")\nthen Traefik should also be upgraded."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply traefik\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Finally, the Ansible vault password must be made known again."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism set vault password\n"})}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},19365:(e,n,r)=>{r.d(n,{A:()=>i});r(96540);var s=r(18215);const t={tabItem:"tabItem_Ymn6"};var a=r(74848);function i(e){let{children:n,hidden:r,className:i}=e;return(0,a.jsx)("div",{role:"tabpanel",className:(0,s.A)(t.tabItem,i),hidden:r,children:n})}},11470:(e,n,r)=>{r.d(n,{A:()=>w});var s=r(96540),t=r(18215),a=r(23104),i=r(56347),o=r(205),l=r(57485),c=r(31682),d=r(70679);function u(e){return s.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:n,children:r}=e;return(0,s.useMemo)((()=>{const e=n??function(e){return u(e).map((e=>{let{props:{value:n,label:r,attributes:s,default:t}}=e;return{value:n,label:r,attributes:s,default:t}}))}(r);return function(e){const n=(0,c.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,r])}function p(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:r}=e;const t=(0,i.W6)(),a=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,l.aZ)(a),(0,s.useCallback)((e=>{if(!a)return;const n=new URLSearchParams(t.location.search);n.set(a,e),t.replace({...t.location,search:n.toString()})}),[a,t])]}function f(e){const{defaultValue:n,queryString:r=!1,groupId:t}=e,a=h(e),[i,l]=(0,s.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!p({value:n,tabValues:r}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const s=r.find((e=>e.default))??r[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:a}))),[c,u]=m({queryString:r,groupId:t}),[f,g]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,a]=(0,d.Dv)(r);return[t,(0,s.useCallback)((e=>{r&&a.set(e)}),[r,a])]}({groupId:t}),x=(()=>{const e=c??f;return p({value:e,tabValues:a})?e:null})();(0,o.A)((()=>{x&&l(x)}),[x]);return{selectedValue:i,selectValue:(0,s.useCallback)((e=>{if(!p({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),g(e)}),[u,g,a]),tabValues:a}}var g=r(92303);const x={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=r(74848);function v(e){let{className:n,block:r,selectedValue:s,selectValue:i,tabValues:o}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,a.a_)(),d=e=>{const n=e.currentTarget,r=l.indexOf(n),t=o[r].value;t!==s&&(c(n),i(t))},u=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;n=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;n=l[r]??l[l.length-1];break}}n?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":r},n),children:o.map((e=>{let{value:n,label:r,attributes:a}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,ref:e=>l.push(e),onKeyDown:u,onClick:d,...a,className:(0,t.A)("tabs__item",x.tabItem,a?.className,{"tabs__item--active":s===n}),children:r??n},n)}))})}function j(e){let{lazy:n,children:r,selectedValue:a}=e;const i=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===a));return e?(0,s.cloneElement)(e,{className:(0,t.A)("margin-top--md",e.props.className)}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:i.map(((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==a})))})}function y(e){const n=f(e);return(0,b.jsxs)("div",{className:(0,t.A)("tabs-container",x.tabList),children:[(0,b.jsx)(v,{...n,...e}),(0,b.jsx)(j,{...n,...e})]})}function w(e){const n=(0,g.A)();return(0,b.jsx)(y,{...e,children:u(e.children)},String(n))}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>o});var s=r(96540);const t={},a=s.createContext(t);function i(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/edaafa5c.9d47e0a3.js b/assets/js/edaafa5c.9d47e0a3.js new file mode 100644 index 0000000000..116e8949a6 --- /dev/null +++ b/assets/js/edaafa5c.9d47e0a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[65981],{75394:(s,e,t)=>{t.r(e),t.d(e,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"operating-scs/components/status-page-api/docs/configuration","title":"Configuration","description":"Configuration can be done by environment variables or flags to the binary.","source":"@site/docs/04-operating-scs/components/status-page-api/docs/configuration.md","sourceDirName":"04-operating-scs/components/status-page-api/docs","slug":"/operating-scs/components/status-page-api/docs/configuration","permalink":"/docs/operating-scs/components/status-page-api/docs/configuration","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-api/docs/configuration.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Quickstart","permalink":"/docs/operating-scs/components/status-page-api/docs/quickstart"},"next":{"title":"Requests","permalink":"/docs/operating-scs/components/status-page-api/docs/requests"}}');var r=t(74848),d=t(28453);const i={},c="Configuration",o={},l=[];function a(s){const e={code:"code",h1:"h1",header:"header",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...s.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"configuration",children:"Configuration"})}),"\n",(0,r.jsx)(e.p,{children:"Configuration can be done by environment variables or flags to the binary."}),"\n",(0,r.jsxs)(e.p,{children:["Code to the configuration can be found at ",(0,r.jsx)(e.code,{children:"internal/app/config/config.go"}),"."]}),"\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Environment key"}),(0,r.jsx)(e.th,{children:"Flag"}),(0,r.jsx)(e.th,{children:"Description"}),(0,r.jsx)(e.th,{children:"Type"}),(0,r.jsx)(e.th,{children:"Default"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.strong,{children:"General settings"})}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:"STATUS_PAGE_PROVISIONING_FILE"}),(0,r.jsx)(e.td,{children:"--provisioning-file"}),(0,r.jsx)(e.td,{children:"YAML file containing the initial values"}),(0,r.jsx)(e.td,{children:"Path"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.code,{children:"./provisioning.yaml"})})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:"STATUS_PAGE_SHUTDOWN_TIMEOUT"}),(0,r.jsx)(e.td,{children:"--shutdown-timeout"}),(0,r.jsx)(e.td,{children:"Timeout to gracefully stop the server"}),(0,r.jsx)(e.td,{children:"Duration"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.code,{children:"10s"})})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:"STATUS_PAGE_VERBOSE"}),(0,r.jsx)(e.td,{children:"-v / --verbose"}),(0,r.jsx)(e.td,{children:"Increase log level"}),(0,r.jsx)(e.td,{children:"Counter"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.code,{children:"0"})})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.strong,{children:"Server settings"})}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:"STATUS_PAGE_SERVER_ADDRESS"}),(0,r.jsx)(e.td,{children:"--server-address"}),(0,r.jsx)(e.td,{children:"API server listen address"}),(0,r.jsx)(e.td,{children:"String"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.code,{children:":3000"})})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.strong,{children:"\u21b3 Swagger settings"})}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:"STATUS_PAGE_SERVER_SWAGGER_UI_ENABLED"}),(0,r.jsx)(e.td,{children:"--server-swagger-ui-enabled"}),(0,r.jsxs)(e.td,{children:["Enable the swagger UI at ",(0,r.jsx)(e.code,{children:"/swagger"})]}),(0,r.jsx)(e.td,{children:"Boolean"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.code,{children:"false"})})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.strong,{children:"\u21b3 CORS settings"})}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:"STATUS_PAGE_SERVER_CORS_ENABLED"}),(0,r.jsx)(e.td,{children:"--server-cors-enabled"}),(0,r.jsx)(e.td,{children:"Server handles CORS."}),(0,r.jsx)(e.td,{children:"Boolean"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.code,{children:"true"})})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:"STATUS_PAGE_SERVER_CORS_ALLOWED_ORIGINS"}),(0,r.jsx)(e.td,{children:"--server-cors-allowed-origins"}),(0,r.jsx)(e.td,{children:"List of allowed CORS origins"}),(0,r.jsx)(e.td,{children:"String Array"}),(0,r.jsxs)(e.td,{children:[(0,r.jsx)(e.code,{children:"http://127.0.0.1"}),", ",(0,r.jsx)(e.code,{children:"http://localhost"})]})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.strong,{children:"Database settings"})}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:"STATUS_PAGE_DATABASE_CONNECTION_STRING"}),(0,r.jsx)(e.td,{children:"--database-connection-string"}),(0,r.jsx)(e.td,{children:"PostgreSQL connection string"}),(0,r.jsx)(e.td,{children:"String"}),(0,r.jsx)(e.td,{})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.strong,{children:"Metrics settings"})}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:"STATUS_PAGE_METRICS_ADDRESS"}),(0,r.jsx)(e.td,{children:"--metrics-address"}),(0,r.jsx)(e.td,{children:"Enable and set metrics server listen address"}),(0,r.jsx)(e.td,{children:"String"}),(0,r.jsx)(e.td,{})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:"STATUS_PAGE_METRICS_NAMESPACE"}),(0,r.jsx)(e.td,{children:"--metrics-namespace"}),(0,r.jsx)(e.td,{children:"Metrics namespace"}),(0,r.jsx)(e.td,{children:"String"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.code,{children:"status_page"})})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:"STATUS_PAGE_METRICS_SUBSYSTEM"}),(0,r.jsx)(e.td,{children:"--metrics-subsystem"}),(0,r.jsx)(e.td,{children:"Metrics subsystem name"}),(0,r.jsx)(e.td,{children:"String"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.code,{children:"api"})})]})]})]})]})}function h(s={}){const{wrapper:e}={...(0,d.R)(),...s.components};return e?(0,r.jsx)(e,{...s,children:(0,r.jsx)(a,{...s})}):a(s)}},28453:(s,e,t)=>{t.d(e,{R:()=>i,x:()=>c});var n=t(96540);const r={},d=n.createContext(r);function i(s){const e=n.useContext(d);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function c(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(r):s.components||r:i(s.components),n.createElement(d.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/edc931f8.1cdfc14a.js b/assets/js/edc931f8.1cdfc14a.js new file mode 100644 index 0000000000..08c0cba992 --- /dev/null +++ b/assets/js/edc931f8.1cdfc14a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[12526],{15983:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>s,metadata:()=>o,toc:()=>m});const o=JSON.parse('{"id":"index","title":"Overview","description":"Welcome to our SCS Community","source":"@site/community/index.md","sourceDirName":".","slug":"/","permalink":"/community/","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"sidebar_position":1,"title":"Overview"},"sidebar":"community","next":{"title":"Mission Statement","permalink":"/community/mission-statement"}}');var i=n(74848),r=n(28453);const s={sidebar_position:1,title:"Overview"},a=void 0,c={},m=[{value:"Welcome to our SCS Community",id:"welcome-to-our-scs-community",level:2}];function u(e){const t={a:"a",h2:"h2",p:"p",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"welcome-to-our-scs-community",children:"Welcome to our SCS Community"}),"\n",(0,i.jsx)(t.p,{children:"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."}),"\n",(0,i.jsxs)(t.p,{children:["We have created an open community space on the ",(0,i.jsx)(t.a,{href:"https://matrix.to/#/#scs-community:matrix.org",children:"Matrix network"}),". Feel free to join the several channels and start interacting with the community. A good starting point is entering the ",(0,i.jsx)(t.a,{href:"https://matrix.to/#/#scs-general:matrix.org",children:"General & Announcements"})," and the ",(0,i.jsx)(t.a,{href:"https://matrix.to/#/#scs-tech:matrix.org",children:"Tech channel"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["Check out our ",(0,i.jsx)(t.a,{href:"/community/collaboration",children:"Community Calendar"})," to know when our several Teams and SIGs meet."]})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>a});var o=n(96540);const i={},r=o.createContext(i);function s(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eea6a18c.1c0a20ad.js b/assets/js/eea6a18c.1c0a20ad.js new file mode 100644 index 0000000000..0580c360ae --- /dev/null +++ b/assets/js/eea6a18c.1c0a20ad.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[79245],{85629:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>o,frontMatter:()=>r,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"scs-0400-v1-status-page-create-decision","title":"Status Page create decision","description":"Introduction","source":"@site/standards/scs-0400-v1-status-page-create-decision.md","sourceDirName":".","slug":"/scs-0400-v1-status-page-create-decision","permalink":"/standards/scs-0400-v1-status-page-create-decision","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Status Page create decision","type":"Decision Record","status":"Draft","track":"Ops","enhances":"status-page-comparison.md"},"sidebar":"standards","previous":{"title":"scs-0400: Status Page create decision","permalink":"/standards/ops/scs-0400"},"next":{"title":"scs-0401: Status page reference implementation decision","permalink":"/standards/ops/scs-0401"}}');var i=s(74848),d=s(28453);const r={title:"Status Page create decision",type:"Decision Record",status:"Draft",track:"Ops",enhances:"status-page-comparison.md"},l=void 0,a={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Existing Applications",id:"existing-applications",level:2},{value:"Decision",id:"decision",level:2},{value:"Status Page Requirements",id:"status-page-requirements",level:2},{value:"Comparison matrix",id:"comparison-matrix",level:3}];function h(e){const t={a:"a",h2:"h2",h3:"h3",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsxs)(t.p,{children:['Creating and maintaining IT infrastructure is a complex task.\nAny kind of consumer (e.g. operators, customers) can\nbe supported by presenting the status of all possible parts of the\nserving infrastructure. Whether a service is not reachable or\nthe used hardware is having an outage we want the consumers to be easily informed\nby using a "Status Page" application. The need for a "Status Page"\ncame up early in the SCS project and the requirements a "Status Page" application\nhas to fulfill were defined and written down on 2022-06-02 as the\n',(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/issues/issues/123",children:"MVP-0 epic"}),'.\nThe upcoming research on existing solutions came to the conclusion that we want to\ncreate a new "Status Page" application.']}),"\n",(0,i.jsx)(t.h2,{id:"existing-applications",children:"Existing Applications"}),"\n",(0,i.jsx)(t.p,{children:'Since we want to use as much as possible from existing projects and contribute to\nupstream projects to support the community with our efforts, it was a hard\ndecision to create a new "Status Page" application.'}),"\n",(0,i.jsxs)(t.p,{children:["Before the decision was made some existing and known applications were tested\nand analyzed if they would fit to our use case. An overview of this\ncomparison can be found ",(0,i.jsx)(t.a,{href:"#comparison-matrix",children:"below in this document"}),"\nWhile this is not a complete list of all existing applications it did\ncapture the most promising ones from the ",(0,i.jsx)(t.a,{href:"https://github.com/ivbeg/awesome-status-pages",children:"awesome-status-page list"}),"\nin order to have base to decide upon."]}),"\n",(0,i.jsx)(t.p,{children:"Work on an existing project only makes sense if the project is healthy OR can be\nbrought into a healthy state. If upstream does not accept patches a fork is needed.\nThe fork however only makes sense if the underlying technology is worth to be maintained.\nThe possible candidates did not fulfill these conditions - in the cases where\ncontribution seemed possible the candidates looked abandoned and long existing CVEs weren't\nworked on."}),"\n",(0,i.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(t.p,{children:"Based on the results the decision was made, that the effort is likely to be the same if\nwe pick up an existing project and try to get it in shape for our use case. It was not\n100% clear if this would even be possible or if we still would have to maintain our\nown additional patches."}),"\n",(0,i.jsx)(t.p,{children:"So there will be a reference implementation that will match the requirements we have.\nIn addition, there will be an architecture design documentation. So if the reference\nimplementation may not fit to you, it will be possible to create your own application."}),"\n",(0,i.jsx)(t.h2,{id:"status-page-requirements",children:"Status Page Requirements"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"The status page application should be simplistic in software design and should not depend on a large\nvariety of services"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["simplistic, yet existing user management for write access (oauth? OIDC?)","\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Simple RBAC (role based access control) is nice to have"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["support that components are only visible to a subset of users","\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"implies that there is a role that is read-only"}),"\n",(0,i.jsx)(t.li,{children:"On-Prem use case might be handled by having an authenticating reverse proxy in front"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"The status page application should allow for simple and easy theming"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Page = (Possibly simple) Web-UI"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"As a CSP, I want to have a status page that allows to"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"define locations and similar grouping (AZs, ...)"}),"\n",(0,i.jsx)(t.li,{children:"define components globally or per location\n_to ease maintenance I want to define per component where it belongs so that I only have\nto define a component once, but have it visible in several locations\n_ status per component should be allowed to be toggleable per location or overall * a component should allow for several statuses, that are defined by me"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Status, Status Items should be easy to extract"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"REST(less)-API to interact with\n_API should be versioned\n_ this allows for embedding status information in other applications, such as cloud\ndashboards\n_this also allows for submitting items from other tooling\n_ incoming webhooks (https POST) should be supported (e.g. for air-gapped setups) \u2013\ni.e. submitting a health beacon every x seconds\n_web-UI wanted for posting updates as well\n_ Token based Auth"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Configuration should be manageable with YAML files (imho this annoys me using Uptime Kuma)"}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"As a consumer of the status page, I'd like to subscribe to events on the status page via e-mail"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"for everything"}),"\n",(0,i.jsx)(t.li,{children:"for specific components"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"As a consumer of the status page, I'd like to subscribe to an RSS or atom feed"}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Allow for the ability to trigger webhooks upon certain events (to submit info to other systems via\nwebhooks, e.g. chat/messenger)"}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"As a CSP Operator, I want to be able to flag a component with a new status quick and easy"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"to minimize the probability of making errors, updating the status of a component should not be\nhard brainwork"}),"\n",(0,i.jsx)(t.li,{children:"updates can be both machine generated status changes (triggered e.g. by health monitoring)\nand updates from human operators"}),"\n",(0,i.jsx)(t.li,{children:"updating a status should allow the CSP Operator to do that in a fashion that either pushes\ninfos to the subscribers or just updates the status on the status page"}),"\n",(0,i.jsx)(t.li,{children:"updating the status can either be toggling the status of the component or can be\naccompanied by additional textual information."}),"\n",(0,i.jsx)(t.li,{children:"When updating a status with textual information the status page application should make it\neasy for me as the CSP Operator to do in a way, that if different people submit infos over time,\nthey are presented in a similar way (e.g. the status page application should guide so that the\nresulting infos are presented in an identical way). Example: when updating infos of an incident\nover time the timeline should automatically be sorted by the status page application so that it\ndoes not depend on the Operator whether the newest info is on top or at the bottom. This is\ntypical thing that varies if several people update items"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Allow for templates for certain types of incidents"}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"User-specific monitoring (how are MY instances, load-balancers, ... doing?) is OUT OF SCOPE for\nthe status page."}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"But having it would be useful and if we have something like this, link it from the status page\n(and a link to horizon might be the default)"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Sidenote: External hosting is desired to avoid status page going down with infra"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"With those requirements in mind the projects that initially were found, were evaluated."}),"\n",(0,i.jsx)(t.h3,{id:"comparison-matrix",children:"Comparison matrix"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{}),(0,i.jsx)(t.th,{children:"CachetHQ"}),(0,i.jsx)(t.th,{children:"ClearStatus"}),(0,i.jsx)(t.th,{children:"ciao"}),(0,i.jsx)(t.th,{children:"cState"}),(0,i.jsx)(t.th,{children:"Gatus"}),(0,i.jsx)(t.th,{children:"Issue Status"}),(0,i.jsx)(t.th,{children:"statusfy"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"CSP VIEW"}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"small dependency tree"}),(0,i.jsx)(t.td,{children:"\u274c Composer"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c ruby gems"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2047 helm chart"}),(0,i.jsx)(t.td,{children:"\u274c npm/github/zapier"}),(0,i.jsx)(t.td,{children:"\u274c npm dependencies very huge"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"easy themable"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"grouping (by location...)"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2047"}),(0,i.jsx)(t.td,{children:"\u2705"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"components definition ..."}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"... local or global"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2047"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"... easy flagging with new status"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2047"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"... push notification on update"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2047"}),(0,i.jsx)(t.td,{children:"\u2705"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"... updates with additional information"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2047"}),(0,i.jsx)(t.td,{children:"\u2047"}),(0,i.jsx)(t.td,{children:"\u2047"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"API Support ..."}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c read only"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705 GitHub API"}),(0,i.jsx)(t.td,{children:"\u274c"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"... versioned"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2047"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"... web ui for posting updates"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"... token based auth"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705 Auth managed by git provider"}),(0,i.jsx)(t.td,{children:"\u274c only basic auth"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c BUT OIDC!"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"manageable configuration"}),(0,i.jsx)(t.td,{children:"\u274c config depends on web server and initial install relies on env variables"}),(0,i.jsx)(t.td,{children:"\u274c based on hugo CMS"}),(0,i.jsx)(t.td,{children:"\u274c config by env variables"}),(0,i.jsx)(t.td,{children:"\u274c based on hugo CMS"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c no real config needed"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"templating support"}),(0,i.jsx)(t.td,{children:"\u2705 twig"}),(0,i.jsx)(t.td,{children:"\u274c Hugo itself uses GO template libraries"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"CUSTOMER VIEW"}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{}),(0,i.jsx)(t.td,{})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"subscription support ..."}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c only by git provider"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"... send by eMail"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"watchdog for status page support"}),(0,i.jsx)(t.td,{children:"\u2047"}),(0,i.jsx)(t.td,{children:"\u2047"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2047"}),(0,i.jsx)(t.td,{children:"\u274c"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"trigger webhook support"}),(0,i.jsx)(t.td,{children:"\u274c needs cachet-monitor"}),(0,i.jsx)(t.td,{children:"\u2047"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2047"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2047"}),(0,i.jsx)(t.td,{children:"\u274c"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"additional infos"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"basically a theme for hugo cms, depends on netlify cms"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"basically a theme for hugo cms, depends on netlify cms"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"It's highly optimized for github pages"}),(0,i.jsx)(t.td,{children:"SPA created with netlify"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"hidden components"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"user management"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705 by OIDC"}),(0,i.jsx)(t.td,{children:"\u2047 through github?"}),(0,i.jsx)(t.td,{children:"\u274c"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"different output format on notification"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"external hosting"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c looks like you are limited to github"}),(0,i.jsx)(t.td,{children:"\u2705"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"project healthy"}),(0,i.jsx)(t.td,{children:"\u274c last commit 17 months"}),(0,i.jsx)(t.td,{children:"\u274c last commit 3 years"}),(0,i.jsx)(t.td,{children:"\u274c last commit 5 months"}),(0,i.jsx)(t.td,{children:"\u2705 last commit 2 months"}),(0,i.jsx)(t.td,{children:"\u2705 recent activities"}),(0,i.jsx)(t.td,{children:"\u2705 recent activities"}),(0,i.jsx)(t.td,{children:"\u274c archived and abandoned by the owner"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"documentation"}),(0,i.jsx)(t.td,{children:"\u2705 API \u274c User Documentation"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2047u"}),(0,i.jsx)(t.td,{children:"\u274c not reachable anymore"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"git based"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u274c"}),(0,i.jsx)(t.td,{children:"\u2705"}),(0,i.jsx)(t.td,{children:"\u2047 a netlify based installation is able to communicate with github"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"project page"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"https://cachethq.io/",children:"project page"})}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"https://github.com/weeblrpress/clearstatus",children:"project page"})}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"https://www.brotandgames.com/ciao/",children:"project page"})}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"https://cstate.netlify.app/",children:"project page"})}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"https://gatus.io/",children:"project page"})}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"https://github.com/tadhglewis/issue-status",children:"project page"})}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"https://marquez.co/statusfy",children:"project page"})})]})]})]})]})}function o(e={}){const{wrapper:t}={...(0,d.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>l});var n=s(96540);const i={},d=n.createContext(i);function r(e){const t=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),n.createElement(d.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef682180.fc22b3a9.js b/assets/js/ef682180.fc22b3a9.js new file mode 100644 index 0000000000..875b4c6a7b --- /dev/null +++ b/assets/js/ef682180.fc22b3a9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[67731],{21763:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>o,contentTitle:()=>c,default:()=>u,frontMatter:()=>d,metadata:()=>n,toc:()=>i});const n=JSON.parse('{"id":"kaas/scs-0215","title":"scs-0215: Robustness features for Kubernetes clusters","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/kaas/scs-0215.md","sourceDirName":"kaas","slug":"/kaas/scs-0215","permalink":"/standards/kaas/scs-0215","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing"},"next":{"title":"V1","permalink":"/standards/scs-0215-v1-robustness-features"}}');var r=t(74848),a=t(28453);const d={},c="scs-0215: Robustness features for Kubernetes clusters",o={},i=[];function l(e){const s={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"scs-0215-robustness-features-for-kubernetes-clusters",children:"scs-0215: Robustness features for Kubernetes clusters"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0215-v1-robustness-features",children:"scs-0215-v1"})}),(0,r.jsx)(s.td,{children:"Standard"}),(0,r.jsx)(s.td,{children:"Draft"}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]})})]})]})}function u(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>d,x:()=>c});var n=t(96540);const r={},a=n.createContext(r);function d(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef8b811a.44f93fed.js b/assets/js/ef8b811a.44f93fed.js new file mode 100644 index 0000000000..0c22f49dec --- /dev/null +++ b/assets/js/ef8b811a.44f93fed.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[38947],{56600:t=>{t.exports=JSON.parse('{"authors":[{"name":"Max Wolfs","title":"Knowledge Management Engineer @ SCS","url":"https://github.com/maxwolfs","imageURL":"https://github.com/maxwolfs.png","key":"maxwolfs","page":null,"count":0},{"name":"Eduard Itrich","title":"Community Manager @ SCS","url":"https://github.com/itrich","imageURL":"https://github.com/itrich.png","key":"itrich","page":null,"count":1},{"name":"Kurt Garloff","title":"CEO @ SCS","url":"https://github.com/garloff","imageURL":"https://github.com/garloff.png","key":"garloff","page":null,"count":0},{"name":"Felix Kronlage-Dammers","title":"Product Owner @ SCS","url":"https://github.com/fkr","imageURL":"https://github.com/fkr.png","key":"fkr","page":null,"count":0}]}')}}]); \ No newline at end of file diff --git a/assets/js/ef9d238d.64dfafa5.js b/assets/js/ef9d238d.64dfafa5.js new file mode 100644 index 0000000000..2785ca8c1e --- /dev/null +++ b/assets/js/ef9d238d.64dfafa5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[39864],{86769:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>u,default:()=>p,frontMatter:()=>o,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"contribute/local-docusaurus-development-guide","title":"Installation","description":"This Guide shows you how to setup docusaurus on your local machine to run this docs in your local development enviroment.","source":"@site/community/contribute/local-docusaurus-development-guide.mdx","sourceDirName":"contribute","slug":"/contribute/local-docusaurus-development-guide","permalink":"/community/contribute/local-docusaurus-development-guide","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"community","previous":{"title":"Linting Guide","permalink":"/community/contribute/linting-guide"},"next":{"title":"Styleguide","permalink":"/community/contribute/styleguide"}}');var s=t(74848),l=t(28453),a=t(11470),i=t(19365);const o={},u="Installation",c={},d=[{value:"Requirements",id:"requirements",level:2},{value:"Installation Guide",id:"installation-guide",level:2},{value:"Step 1 \u2013 Installing Node.js via nvm",id:"step-1--installing-nodejs-via-nvm",level:3},{value:"Step 2 \u2013\xa0Cloning the repository",id:"step-2-cloning-the-repository",level:3},{value:"Step 3 \u2013 Installing dependencies",id:"step-3--installing-dependencies",level:3},{value:"Step 4 \u2013 Starting the development server",id:"step-4--starting-the-development-server",level:3}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"installation",children:"Installation"})}),"\n",(0,s.jsx)(n.p,{children:"This Guide shows you how to setup docusaurus on your local machine to run this docs in your local development enviroment."}),"\n",(0,s.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"git"}),"\n",(0,s.jsx)(n.li,{children:"Node.js v16"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"installation-guide",children:"Installation Guide"}),"\n",(0,s.jsx)(n.h3,{id:"step-1--installing-nodejs-via-nvm",children:"Step 1 \u2013 Installing Node.js via nvm"}),"\n",(0,s.jsx)(n.p,{children:"It is recommended to install Node.js via nvm \u2013 a node version manager \u2013 to have the possibility to switch between different node.js versions."}),"\n",(0,s.jsxs)(a.A,{groupId:"operating-systems",children:[(0,s.jsxs)(i.A,{value:"mac",label:"macOS",children:[(0,s.jsx)(n.p,{children:"You must have macOS desktop access with administrator privileges."}),(0,s.jsxs)(n.p,{children:["Login to the macOS desktop system and ",(0,s.jsx)(n.a,{href:"https://brew.sh/",children:"install Homebrew"})," on your system (if not already installed)."]}),(0,s.jsx)(n.p,{children:"Install nvm via homebrew:"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"brew install nvm\n"})})]}),(0,s.jsx)(i.A,{value:"linux",label:"Linux",children:(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"https://github.com/nvm-sh/nvm#installing-and-updating",children:"this"})," installation guide on GitHub by nvm-sh for installing nvm."]})}),(0,s.jsx)(i.A,{value:"win",label:"Windows",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/coreybutler/nvm-windows",children:"NVM for Windows"}),"\nruns 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 ",(0,s.jsx)(n.a,{href:"https://github.com/coreybutler/nvm-windows/releases",children:"release page"}),"."]})})]}),"\n",(0,s.jsx)(n.p,{children:"Once installed you can check the available versions with"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"nvm list\n"})}),"\n",(0,s.jsx)(n.p,{children:"If you have no other projects, where you need a different version, it is recommended to install the latest stable LTS version of node."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",children:"nvm install lts\n"})}),"\n",(0,s.jsx)(n.p,{children:"nvm has now installed the latest node.js version with its package manager npm. Check if the installation has been successfull by checking it:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",children:"node --version\n"})}),"\n",(0,s.jsx)(n.h3,{id:"step-2-cloning-the-repository",children:"Step 2 \u2013\xa0Cloning the repository"}),"\n",(0,s.jsxs)(n.p,{children:["Clone the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs",children:"docs"})," repository via your favourite method:"]}),"\n",(0,s.jsxs)(a.A,{groupId:"cloning-",children:[(0,s.jsx)(i.A,{value:"https",label:"HTTPS",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",metastring:'title="HTTPS"',children:"git clone https://github.com/SovereignCloudStack/docs.git\n"})})}),(0,s.jsx)(i.A,{value:"ssh",label:"SSH",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",metastring:'title="SSH"',children:"git clone git@github.com:SovereignCloudStack/docs.git\n"})})})]}),"\n",(0,s.jsx)(n.h3,{id:"step-3--installing-dependencies",children:"Step 3 \u2013 Installing dependencies"}),"\n",(0,s.jsxs)(n.p,{children:["Change your working directory within your terminal to the root of the cloned repository ",(0,s.jsx)(n.code,{children:"/docs"})," and install all dependencies:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",children:"npm install\n"})}),"\n",(0,s.jsx)(n.h3,{id:"step-4--starting-the-development-server",children:"Step 4 \u2013 Starting the development server"}),"\n",(0,s.jsx)(n.p,{children:"You can now run the local development server from your terminal:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",children:"npm start\n"})}),"\n",(0,s.jsx)(n.p,{children:"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."})]})}function p(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},19365:(e,n,t)=>{t.d(n,{A:()=>a});t(96540);var r=t(18215);const s={tabItem:"tabItem_Ymn6"};var l=t(74848);function a(e){let{children:n,hidden:t,className:a}=e;return(0,l.jsx)("div",{role:"tabpanel",className:(0,r.A)(s.tabItem,a),hidden:t,children:n})}},11470:(e,n,t)=>{t.d(n,{A:()=>w});var r=t(96540),s=t(18215),l=t(23104),a=t(56347),i=t(205),o=t(57485),u=t(31682),c=t(70679);function d(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??function(e){return d(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:s}}=e;return{value:n,label:t,attributes:r,default:s}}))}(t);return function(e){const n=(0,u.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function p(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:t}=e;const s=(0,a.W6)(),l=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,o.aZ)(l),(0,r.useCallback)((e=>{if(!l)return;const n=new URLSearchParams(s.location.search);n.set(l,e),s.replace({...s.location,search:n.toString()})}),[l,s])]}function v(e){const{defaultValue:n,queryString:t=!1,groupId:s}=e,l=h(e),[a,o]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!p({value:n,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:l}))),[u,d]=m({queryString:t,groupId:s}),[v,g]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[s,l]=(0,c.Dv)(t);return[s,(0,r.useCallback)((e=>{t&&l.set(e)}),[t,l])]}({groupId:s}),b=(()=>{const e=u??v;return p({value:e,tabValues:l})?e:null})();(0,i.A)((()=>{b&&o(b)}),[b]);return{selectedValue:a,selectValue:(0,r.useCallback)((e=>{if(!p({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);o(e),d(e),g(e)}),[d,g,l]),tabValues:l}}var g=t(92303);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var f=t(74848);function x(e){let{className:n,block:t,selectedValue:r,selectValue:a,tabValues:i}=e;const o=[],{blockElementScrollPositionUntilNextRender:u}=(0,l.a_)(),c=e=>{const n=e.currentTarget,t=o.indexOf(n),s=i[t].value;s!==r&&(u(n),a(s))},d=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const t=o.indexOf(e.currentTarget)+1;n=o[t]??o[0];break}case"ArrowLeft":{const t=o.indexOf(e.currentTarget)-1;n=o[t]??o[o.length-1];break}}n?.focus()};return(0,f.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.A)("tabs",{"tabs--block":t},n),children:i.map((e=>{let{value:n,label:t,attributes:l}=e;return(0,f.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>o.push(e),onKeyDown:d,onClick:c,...l,className:(0,s.A)("tabs__item",b.tabItem,l?.className,{"tabs__item--active":r===n}),children:t??n},n)}))})}function j(e){let{lazy:n,children:t,selectedValue:l}=e;const a=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=a.find((e=>e.props.value===l));return e?(0,r.cloneElement)(e,{className:(0,s.A)("margin-top--md",e.props.className)}):null}return(0,f.jsx)("div",{className:"margin-top--md",children:a.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==l})))})}function y(e){const n=v(e);return(0,f.jsxs)("div",{className:(0,s.A)("tabs-container",b.tabList),children:[(0,f.jsx)(x,{...n,...e}),(0,f.jsx)(j,{...n,...e})]})}function w(e){const n=(0,g.A)();return(0,f.jsx)(y,{...e,children:d(e.children)},String(n))}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var r=t(96540);const s={},l=r.createContext(s);function a(e){const n=r.useContext(l);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/efbcd183.c107b2c9.js b/assets/js/efbcd183.c107b2c9.js new file mode 100644 index 0000000000..ece4d737a1 --- /dev/null +++ b/assets/js/efbcd183.c107b2c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[29093],{80436:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"scs-compatible-kaas","title":"SCS-compatible KaaS","description":"| Scope versions -> | v1 |","source":"@site/standards/scs-compatible-kaas.md","sourceDirName":".","slug":"/scs-compatible-kaas","permalink":"/standards/scs-compatible-kaas","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"SCS-compatible IaaS","permalink":"/standards/scs-compatible-iaas"},"next":{"title":"Compliance Check Pipeline","permalink":"/standards/certification/pipeline"}}');var l=s(74848),i=s(28453);const r={},c="SCS-compatible KaaS",a={},d=[];function o(t){const e={a:"a",h1:"h1",header:"header",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...t.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(e.header,{children:(0,l.jsx)(e.h1,{id:"scs-compatible-kaas",children:"SCS-compatible KaaS"})}),"\n",(0,l.jsxs)(e.table,{children:[(0,l.jsx)(e.thead,{children:(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.th,{style:{textAlign:"left"},children:"Scope versions ->"}),(0,l.jsx)(e.th,{style:{textAlign:"left"},children:"v1"})]})}),(0,l.jsxs)(e.tbody,{children:[(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"State"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"Effective"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"Stabilized at"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"2024-11-26"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:(0,l.jsx)(e.strong,{children:"Modules"})}),(0,l.jsx)(e.td,{style:{textAlign:"left"}})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:(0,l.jsx)(e.a,{href:"https://github.com/cncf/k8s-conformance/tree/master",children:"CNCF Kubernetes conformance"})}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:(0,l.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0210-v2-k8s-version-policy",children:"scs-0210-v2: Kubernetes version policy"})}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:(0,l.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0214-v2-k8s-node-distribution",children:"scs-0214-v2: Kubernetes node distribution and availability"})}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:(0,l.jsx)(e.a,{href:"https://docs.scs.community/standards/scs-0219-v1-kaas-networking",children:"scs-0219-v1: KaaS networking"})}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"X"})]})]})]})]})}function h(t={}){const{wrapper:e}={...(0,i.R)(),...t.components};return e?(0,l.jsx)(e,{...t,children:(0,l.jsx)(o,{...t})}):o(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>r,x:()=>c});var n=s(96540);const l={},i=n.createContext(l);function r(t){const e=n.useContext(i);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(l):t.components||l:r(t.components),n.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/f0e20cb6.263154cd.js b/assets/js/f0e20cb6.263154cd.js new file mode 100644 index 0000000000..9ce45c408a --- /dev/null +++ b/assets/js/f0e20cb6.263154cd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[41479],{33893:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>u,contentTitle:()=>a,default:()=>g,frontMatter:()=>r,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"iaas/guides/configuration-guide/index","title":"Configuration Guide","description":"","source":"@site/docs/02-iaas/guides/configuration-guide/index.md","sourceDirName":"02-iaas/guides/configuration-guide","slug":"/iaas/guides/configuration-guide/","permalink":"/docs/iaas/guides/configuration-guide/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/index.md","tags":[],"version":"current","sidebarPosition":30,"frontMatter":{"sidebar_label":"Configuration Guide","sidebar_position":30},"sidebar":"docs","previous":{"title":"OpenStack","permalink":"/docs/iaas/guides/upgrade-guide/openstack"},"next":{"title":"Configuration repository","permalink":"/docs/iaas/guides/configuration-guide/configuration-repository"}}');var t=n(74848),s=n(28453);const r={sidebar_label:"Configuration Guide",sidebar_position:30},a="Configuration Guide",u={},d=[];function c(e){const i={h1:"h1",header:"header",...(0,s.R)(),...e.components};return(0,t.jsx)(i.header,{children:(0,t.jsx)(i.h1,{id:"configuration-guide",children:"Configuration Guide"})})}function g(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>r,x:()=>a});var o=n(96540);const t={},s=o.createContext(t);function r(e){const i=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),o.createElement(s.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f14428ad.606a7d10.js b/assets/js/f14428ad.606a7d10.js new file mode 100644 index 0000000000..16ee233741 --- /dev/null +++ b/assets/js/f14428ad.606a7d10.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[83709],{70484:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>p});const o=JSON.parse('{"id":"application-examples/opendesk-on-scs/contribute","title":"Contribute","description":"Contributions to this documentation are welcome and can be submitted to this repository.","source":"@site/user-docs/application-examples/opendesk-on-scs/contribute.md","sourceDirName":"application-examples/opendesk-on-scs","slug":"/application-examples/opendesk-on-scs/contribute","permalink":"/user-docs/application-examples/opendesk-on-scs/contribute","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"userDocs","previous":{"title":"User import","permalink":"/user-docs/application-examples/opendesk-on-scs/user-import"}}');var s=n(74848),r=n(28453);const i={},c="Contribute",a={},p=[];function u(e){const t={a:"a",h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"contribute",children:"Contribute"})}),"\n",(0,s.jsxs)(t.p,{children:["Contributions to this documentation are welcome and can be submitted to ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/opendesk-on-scs",children:"this repository"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var o=n(96540);const s={},r=o.createContext(s);function i(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f1715aef.857f8540.js b/assets/js/f1715aef.857f8540.js new file mode 100644 index 0000000000..8ed489a146 --- /dev/null +++ b/assets/js/f1715aef.857f8540.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[36647],{29221:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"iaas/scs-0100","title":"scs-0100: SCS Flavor Naming Standard","description":"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack","source":"@site/standards/iaas/scs-0100.md","sourceDirName":"iaas","slug":"/iaas/scs-0100","permalink":"/standards/iaas/scs-0100","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"IaaS Standards","permalink":"/standards/iaas/"},"next":{"title":"V1","permalink":"/standards/scs-0100-v1-flavor-naming"}}');var a=s(74848),r=s(28453);const d={},i="scs-0100: SCS Flavor Naming Standard",c={},l=[{value:"Supplement: Implementation and Testing Notes",id:"supplement-implementation-and-testing-notes",level:2}];function o(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"scs-0100-scs-flavor-naming-standard",children:"scs-0100: SCS Flavor Naming Standard"})}),"\n",(0,a.jsx)(n.p,{children:"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack\nenvironments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM,\nand Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for\nusability and portability across all SCS flavors."}),"\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Version"}),(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"State"}),(0,a.jsx)(n.th,{children:"stabilized"}),(0,a.jsx)(n.th,{children:"deprecated"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/standards/scs-0100-v1-flavor-naming",children:"scs-0100-v1"})}),(0,a.jsx)(n.td,{children:"Standard"}),(0,a.jsx)(n.td,{children:"Deprecated"}),(0,a.jsx)(n.td,{children:"2022-09-08"}),(0,a.jsx)(n.td,{children:"2023-10-31"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/standards/scs-0100-v2-flavor-naming",children:"scs-0100-v2"})}),(0,a.jsx)(n.td,{children:"Standard"}),(0,a.jsx)(n.td,{children:"Deprecated"}),(0,a.jsx)(n.td,{children:"2023-02-21"}),(0,a.jsx)(n.td,{children:"2023-11-30"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"scs-0100-v3"})}),(0,a.jsx)(n.td,{children:"Standard"}),(0,a.jsx)(n.td,{children:"Stable"}),(0,a.jsx)(n.td,{children:"2023-06-14"}),(0,a.jsx)(n.td,{children:"-"})]})]})]}),"\n",(0,a.jsx)(n.h2,{id:"supplement-implementation-and-testing-notes",children:"Supplement: Implementation and Testing Notes"}),"\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Version"}),(0,a.jsx)(n.th,{children:"State"}),(0,a.jsx)(n.th,{children:"stabilized"}),(0,a.jsx)(n.th,{children:"deprecated"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/standards/scs-0100-w1-flavor-naming-implementation-testing",children:"w1"})}),(0,a.jsx)(n.td,{children:"Draft"}),(0,a.jsx)(n.td,{children:"-"}),(0,a.jsx)(n.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(o,{...e})}):o(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>i});var t=s(96540);const a={},r=t.createContext(a);function d(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f17f9c44.9f524a69.js b/assets/js/f17f9c44.9f524a69.js new file mode 100644 index 0000000000..6a1c4051e1 --- /dev/null +++ b/assets/js/f17f9c44.9f524a69.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4979],{56778:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>n,toc:()=>i});const n=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","title":"Controllers","description":"OpenStackClusterStackRelease controller","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs","slug":"/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Quickstart","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart"},"next":{"title":"Developer Guide","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop"}}');var c=s(74848),o=s(28453);const r={},l="Controllers",a={},i=[{value:"OpenStackClusterStackRelease controller",id:"openstackclusterstackrelease-controller",level:2},{value:"OpenStackNodeImageRelease controller",id:"openstacknodeimagerelease-controller",level:2}];function d(e){const t={code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(t.header,{children:(0,c.jsx)(t.h1,{id:"controllers",children:"Controllers"})}),"\n",(0,c.jsx)(t.h2,{id:"openstackclusterstackrelease-controller",children:"OpenStackClusterStackRelease controller"}),"\n",(0,c.jsx)(t.p,{children:"The OpenStackClusterStackRelease controller\u2019s main responsibilities are:"}),"\n",(0,c.jsxs)(t.ul,{children:["\n",(0,c.jsx)(t.li,{children:"Download release assets into the CSPO container"}),"\n",(0,c.jsxs)(t.li,{children:["Create OpenStackNodeImageRelease resources based on the required NodeImages defined in the downloaded release asset ",(0,c.jsx)(t.code,{children:"node-images.yaml"})]}),"\n",(0,c.jsx)(t.li,{children:"Set an OwnerReference on the existing OpenStackNodeImageRelease resources that could be utilized by the ClusterStack release (multiple versions of one ClusterStack could share an image)"}),"\n",(0,c.jsxs)(t.li,{children:["Update the OpenStackClusterStackRelease status to ",(0,c.jsx)(t.code,{children:"ready"})," once all related OpenStackNodeImageReleases are also ",(0,c.jsx)(t.code,{children:"ready"})]}),"\n"]}),"\n",(0,c.jsx)(t.p,{children:(0,c.jsx)(t.img,{alt:"OSCSR controller",src:s(61779).A+"",title:"OSCSR controller",width:"820",height:"1572"})}),"\n",(0,c.jsx)(t.h2,{id:"openstacknodeimagerelease-controller",children:"OpenStackNodeImageRelease controller"}),"\n",(0,c.jsx)(t.p,{children:"The OpenStackNodeImageRelease controller\u2019s main responsibilities are:"}),"\n",(0,c.jsxs)(t.ul,{children:["\n",(0,c.jsxs)(t.li,{children:["Load the OpenStack Cloud configuration from the Secret referenced in ",(0,c.jsx)(t.code,{children:"spec.IdentityRef"})]}),"\n",(0,c.jsxs)(t.li,{children:["Create an Image as defined by ",(0,c.jsx)(t.code,{children:"spec.Image"})," if it does not already exist in the specified OpenStack project"]}),"\n",(0,c.jsx)(t.li,{children:"Instruct the OpenStack Glance service to import an Image from the provided URL"}),"\n",(0,c.jsxs)(t.li,{children:["Set the OpenStackNodeImageRelease status to ",(0,c.jsx)(t.code,{children:"ready"})," once the image achieves an Active status"]}),"\n"]}),"\n",(0,c.jsx)(t.p,{children:(0,c.jsx)(t.img,{alt:"OSNIR controller",src:s(57678).A+"",title:"OSNIR controller",width:"1283",height:"1450"})})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},61779:(e,t,s)=>{s.d(t,{A:()=>n});const n=s.p+"assets/images/openstackclusterstackrelease-controller-7116cf20417bba3296181501c313ed65.png"},57678:(e,t,s)=>{s.d(t,{A:()=>n});const n=s.p+"assets/images/openstacknodeimagerelease-controller-0b39df07c1e9d7a4e028f0795dd056d8.png"},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>l});var n=s(96540);const c={},o=n.createContext(c);function r(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f2a59390.c536ca08.js b/assets/js/f2a59390.c536ca08.js new file mode 100644 index 0000000000..02a8ab4df4 --- /dev/null +++ b/assets/js/f2a59390.c536ca08.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[92078],{82697:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>o,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"iaas/guides/deploy-guide/services/openstack","title":"OpenStack","description":"Common issues with deploying OpenStack services are documented in the","source":"@site/docs/02-iaas/guides/deploy-guide/services/openstack.md","sourceDirName":"02-iaas/guides/deploy-guide/services","slug":"/iaas/guides/deploy-guide/services/openstack","permalink":"/docs/iaas/guides/deploy-guide/services/openstack","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/openstack.md","tags":[],"version":"current","sidebarPosition":60,"frontMatter":{"sidebar_label":"OpenStack","sidebar_position":60},"sidebar":"docs","previous":{"title":"Migrate Ceph-Ansible via Rookify (technical preview)","permalink":"/docs/iaas/guides/deploy-guide/services/rookify"},"next":{"title":"Examples","permalink":"/docs/iaas/guides/deploy-guide/examples/"}}');var a=s(74848),c=s(28453);const r={sidebar_label:"OpenStack",sidebar_position:60},o="OpenStack",t={},l=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"openstack",children:"OpenStack"})}),"\n",(0,a.jsxs)(n.p,{children:["Common issues with deploying OpenStack services are documented in the\n",(0,a.jsx)(n.a,{href:"/docs/iaas/guides/troubleshooting-guide/openstack",children:"OpenStack Troubleshooting Guide"}),"."]}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsxs)(n.p,{children:["An OpenStack deployment contains a number of components providing APIs to access infrastructure resources.\nThe ",(0,a.jsx)(n.a,{href:"https://www.openstack.org/software/project-navigator/openstack-components#openstack-services",children:"OpenStack Components"}),"\npage lists the various services that can be deployed to provide such resources to cloud end users.\nUnfortunately, not all of the OpenStack projects listed there are still active.\nNot all of the services listed there are supported by OSISM."]})}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"OpenStack client"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply openstackclient\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Keystone"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull keystone\nosism apply keystone\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Glance"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull glance\nosism apply glance\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Designate"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull designate\nosism apply designate\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Placement"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull placement\nosism apply placement\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Cinder"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull cinder\nosism apply cinder\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Neutron"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull neutron\nosism apply neutron\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Nova"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull nova\nosism apply nova\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Octavia"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply octavia-certificates\nosism apply copy-octavia-certificates\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull octavia\nosism apply octavia\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Optional: Manage amphora image"}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"This step is only necessary if the Amphora Driver is used. If OVN is used as the driver,\nthis step is not necessary."}),"\n",(0,a.jsxs)(n.p,{children:["We provide regularly updated images for Octavia in\n",(0,a.jsx)(n.a,{href:"https://github.com/osism/openstack-octavia-amphora-image",children:"osism/openstack-octavia/amphora-image"}),"."]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Configure API Endpoint"}),"\n",(0,a.jsxs)(n.p,{children:["For the command to be usable, a cloud profile for octavia must currently be added in the\nclouds.yml file of the OpenStack environment. The ",(0,a.jsx)(n.code,{children:"auth_url"})," is changed accordingly."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/openstack/clouds.yml"',children:"clouds:\n [...]\n octavia:\n auth:\n username: octavia\n project_name: service\n auth_url: https://api.testbed.osism.xyz:5000/v3\n project_domain_name: default\n user_domain_name: default\n cacert: /etc/ssl/certs/ca-certificates.crt\n identity_api_version: 3\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Configure the secret"}),"\n",(0,a.jsxs)(n.p,{children:["The secret is added to the secure.yml file. The password is set in the parameter\n",(0,a.jsx)(n.code,{children:"octavia_keystone_password"})," in the file ",(0,a.jsx)(n.code,{children:"environments/kolla/secrets.yml"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"Get the secret with"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"make ansible_vault_show FILE=environments/kolla/secrets.yml |grep octavia_keystone_password\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/openstack/secure.yml"',children:"---\nclouds:\n [...]\n octavia:\n auth:\n password: VALUE_OF_octavia_keystone_password\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Upload the correct and current image depending on the current Openstack release:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism manage image octavia\n"})}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.ol,{start:"11",children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Horizon"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply -a pull horizon\nosism apply horizon\n"})}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>o});var i=s(96540);const a={},c=i.createContext(a);function r(e){const n=i.useContext(c);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),i.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f385820d.e61458f8.js b/assets/js/f385820d.e61458f8.js new file mode 100644 index 0000000000..7e8301acc7 --- /dev/null +++ b/assets/js/f385820d.e61458f8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[27841],{84088:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>c,default:()=>m,frontMatter:()=>l,metadata:()=>a,toc:()=>d});const a=JSON.parse('{"id":"iaas/guides/configuration-guide/openstack/horizon","title":"Horizon","description":"* Horizon admin guide","source":"@site/docs/02-iaas/guides/configuration-guide/openstack/horizon.md","sourceDirName":"02-iaas/guides/configuration-guide/openstack","slug":"/iaas/guides/configuration-guide/openstack/horizon","permalink":"/docs/iaas/guides/configuration-guide/openstack/horizon","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/horizon.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Horizon"},"sidebar":"docs","previous":{"title":"Heat","permalink":"/docs/iaas/guides/configuration-guide/openstack/heat"},"next":{"title":"Ironic","permalink":"/docs/iaas/guides/configuration-guide/openstack/ironic"}}');var s=t(74848),o=t(28453),r=t(11470),i=t(19365);const l={sidebar_label:"Horizon"},c="Horizon",u={},d=[{value:"Problems uploading machine images larger than 1 GiB",id:"problems-uploading-machine-images-larger-than-1-gib",level:2},{value:"Make clouds.yml file downloadable as an alternative to the RC file",id:"make-cloudsyml-file-downloadable-as-an-alternative-to-the-rc-file",level:2},{value:"Custom themes",id:"custom-themes",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"horizon",children:"Horizon"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/horizon/latest/admin/index.html",children:"Horizon admin guide"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/horizon/latest/configuration/index.html",children:"Horizon configuration guide"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/horizon/latest/configuration/settings.html",children:"Horizon configuration reference"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"problems-uploading-machine-images-larger-than-1-gib",children:"Problems uploading machine images larger than 1 GiB"}),"\n",(0,s.jsxs)(n.p,{children:["By default, the ",(0,s.jsx)(n.code,{children:"LimitRequestBody"})," is set to ",(0,s.jsx)(n.code,{children:"1073741824"})," (1 GiB).\nThis is a security feature (",(0,s.jsx)(n.a,{href:"https://access.redhat.com/security/cve/CVE-2022-29404",children:"CVE-2022-29404"}),")\nand not a bug. Further details in the\n",(0,s.jsx)(n.a,{href:"https://access.redhat.com/articles/6975397",children:"A new default for the LimitRequestBody directive in httpd configuration"}),"\narticle in the RedHat knowledgebase."]}),"\n",(0,s.jsxs)(n.p,{children:["This limit can be increased via the parameter ",(0,s.jsx)(n.code,{children:"horizon_httpd_limitrequestbody"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:"horizon_httpd_limitrequestbody: 2147483648 # 2 GiB\n"})}),"\n",(0,s.jsx)(n.h2,{id:"make-cloudsyml-file-downloadable-as-an-alternative-to-the-rc-file",children:"Make clouds.yml file downloadable as an alternative to the RC file"}),"\n",(0,s.jsxs)(n.p,{children:["By default, only the ",(0,s.jsx)(n.code,{children:"openrc"})," file is offered for download in Horizon. It makes sense to also add the\n",(0,s.jsx)(n.code,{children:"clouds.yaml"})," as a download. To do this, the menu is customised. The change can be deployed with\n",(0,s.jsx)(n.code,{children:"osism apply -a reconfigure horizon"}),"."]}),"\n",(0,s.jsxs)(r.A,{children:[(0,s.jsx)(i.A,{value:"osism-8",label:"OSISM >= 8.0.0",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/files/overlays/horizon/_9999-custom-settings.py"',children:"SHOW_KEYSTONE_V2_RC = False\nUSER_MENU_LINKS = [\n {'name': _('OpenStack clouds.yml File'),\n 'icon_classes': ['fa-download', ],\n 'url': 'horizon:project:api_access:clouds.yaml',\n 'external': False,\n },\n {'name': _('OpenStack RC File v3'),\n 'icon_classes': ['fa-download', ],\n 'url': 'horizon:project:api_access:openrc',\n 'external': False,\n }\n]\n"})})}),(0,s.jsx)(i.A,{value:"osism-7",label:"OSISM < 8.0.0",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/files/overlays/horizon/custom_local_settings"',children:"SHOW_KEYSTONE_V2_RC = False\nUSER_MENU_LINKS = [\n {'name': _('OpenStack clouds.yml File'),\n 'icon_classes': ['fa-download', ],\n 'url': 'horizon:project:api_access:clouds.yaml',\n 'external': False,\n },\n {'name': _('OpenStack RC File v3'),\n 'icon_classes': ['fa-download', ],\n 'url': 'horizon:project:api_access:openrc',\n 'external': False,\n }\n]\n"})})})]}),"\n",(0,s.jsx)(n.h2,{id:"custom-themes",children:"Custom themes"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Place the files and directories of the custom theme in\n",(0,s.jsx)(n.code,{children:"environments/kolla/files/overlays/horizon/themes/custom_theme"}),".\nExamples of custom themes can be found in the ",(0,s.jsx)(n.a,{href:"https://github.com/osism/openstack-themes",children:"osism/openstack-themes"}),"\nrepository."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Add the custom theme to the ",(0,s.jsx)(n.code,{children:"horizon_custom_themes"})," dictionary.\nUse the name of the directory in ",(0,s.jsx)(n.code,{children:"environments/kolla/files/overlays/horizon/themes"})," as\nname."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:"horizon_custom_themes:\n - name: custom_theme\n label: CustomTheme\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["If the custom theme should be the default then add the ",(0,s.jsx)(n.code,{children:"DEFAULT_THEME"})," parameter."]}),"\n",(0,s.jsxs)(r.A,{children:[(0,s.jsx)(i.A,{value:"osism-8",label:"OSISM >= 8.0.0",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",metastring:'title="environments/kolla/files/overlays/horizon/_9999-custom-settings.py"',children:"DEFAULT_THEME = 'custom_theme'\n"})})}),(0,s.jsx)(i.A,{value:"osism-7",label:"OSISM < 8.0.0",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",metastring:'title="environments/kolla/files/overlays/horizon/custom_local_settings"',children:"DEFAULT_THEME = 'custom_theme'\n"})})})]}),"\n"]}),"\n"]})]})}function m(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},19365:(e,n,t)=>{t.d(n,{A:()=>r});t(96540);var a=t(18215);const s={tabItem:"tabItem_Ymn6"};var o=t(74848);function r(e){let{children:n,hidden:t,className:r}=e;return(0,o.jsx)("div",{role:"tabpanel",className:(0,a.A)(s.tabItem,r),hidden:t,children:n})}},11470:(e,n,t)=>{t.d(n,{A:()=>_});var a=t(96540),s=t(18215),o=t(23104),r=t(56347),i=t(205),l=t(57485),c=t(31682),u=t(70679);function d(e){return a.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:n,children:t}=e;return(0,a.useMemo)((()=>{const e=n??function(e){return d(e).map((e=>{let{props:{value:n,label:t,attributes:a,default:s}}=e;return{value:n,label:t,attributes:a,default:s}}))}(t);return function(e){const n=(0,c.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function m(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function p(e){let{queryString:n=!1,groupId:t}=e;const s=(0,r.W6)(),o=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,l.aZ)(o),(0,a.useCallback)((e=>{if(!o)return;const n=new URLSearchParams(s.location.search);n.set(o,e),s.replace({...s.location,search:n.toString()})}),[o,s])]}function f(e){const{defaultValue:n,queryString:t=!1,groupId:s}=e,o=h(e),[r,l]=(0,a.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!m({value:n,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const a=t.find((e=>e.default))??t[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:o}))),[c,d]=p({queryString:t,groupId:s}),[f,g]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[s,o]=(0,u.Dv)(t);return[s,(0,a.useCallback)((e=>{t&&o.set(e)}),[t,o])]}({groupId:s}),b=(()=>{const e=c??f;return m({value:e,tabValues:o})?e:null})();(0,i.A)((()=>{b&&l(b)}),[b]);return{selectedValue:r,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),g(e)}),[d,g,o]),tabValues:o}}var g=t(92303);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=t(74848);function v(e){let{className:n,block:t,selectedValue:a,selectValue:r,tabValues:i}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.a_)(),u=e=>{const n=e.currentTarget,t=l.indexOf(n),s=i[t].value;s!==a&&(c(n),r(s))},d=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const t=l.indexOf(e.currentTarget)+1;n=l[t]??l[0];break}case"ArrowLeft":{const t=l.indexOf(e.currentTarget)-1;n=l[t]??l[l.length-1];break}}n?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.A)("tabs",{"tabs--block":t},n),children:i.map((e=>{let{value:n,label:t,attributes:o}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:a===n?0:-1,"aria-selected":a===n,ref:e=>l.push(e),onKeyDown:d,onClick:u,...o,className:(0,s.A)("tabs__item",b.tabItem,o?.className,{"tabs__item--active":a===n}),children:t??n},n)}))})}function j(e){let{lazy:n,children:t,selectedValue:o}=e;const r=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=r.find((e=>e.props.value===o));return e?(0,a.cloneElement)(e,{className:(0,s.A)("margin-top--md",e.props.className)}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:r.map(((e,n)=>(0,a.cloneElement)(e,{key:n,hidden:e.props.value!==o})))})}function y(e){const n=f(e);return(0,x.jsxs)("div",{className:(0,s.A)("tabs-container",b.tabList),children:[(0,x.jsx)(v,{...n,...e}),(0,x.jsx)(j,{...n,...e})]})}function _(e){const n=(0,g.A)();return(0,x.jsx)(y,{...e,children:d(e.children)},String(n))}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var a=t(96540);const s={},o=a.createContext(s);function r(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f39ce5f1.bbfe99fa.js b/assets/js/f39ce5f1.bbfe99fa.js new file mode 100644 index 0000000000..3fedd6f57b --- /dev/null +++ b/assets/js/f39ce5f1.bbfe99fa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[99115],{7643:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"operating-scs/components/status-page-openapi/docs/overview","title":"Overview","description":"Service providers often times want to communicate the status of their systems transparently to their users.","source":"@site/docs/04-operating-scs/components/status-page-openapi/docs/overview.md","sourceDirName":"04-operating-scs/components/status-page-openapi/docs","slug":"/operating-scs/components/status-page-openapi/docs/overview","permalink":"/docs/operating-scs/components/status-page-openapi/docs/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-openapi/docs/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Concepts","permalink":"/docs/category/concepts"},"next":{"title":"Components","permalink":"/docs/operating-scs/components/status-page-openapi/docs/components"}}');var o=n(74848),i=n(28453);const a={},r="Overview",c={},l=[{value:"The SCS status page <strong>API</strong>",id:"the-scs-status-page-api",level:2},{value:"Reference implementation",id:"reference-implementation",level:3},{value:"The SCS status page <strong>frontend</strong>",id:"the-scs-status-page-frontend",level:2},{value:"Reference implementation",id:"reference-implementation-1",level:3}];function d(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",section:"section",strong:"strong",sup:"sup",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,o.jsx)(t.p,{children:'Service providers often times want to communicate the status of their systems transparently to their users.\nA commonly used pattern is to provide a "status page" web application, where the current system health as well as recent incidents are made available.'}),"\n",(0,o.jsx)(t.p,{children:"SCS strives to implement a status page that works well, while being interoperable with other systems."}),"\n",(0,o.jsx)(t.admonition,{type:"note",children:(0,o.jsxs)(t.p,{children:["How was the decision to implement a new status page application made? What were the requirements? See the ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/1fb174da1ee906f0da6a8bbefbd3d95884df5669/Standards/scs-0400-v1-status-page-create-decision.md",children:"decision record"}),"."]})}),"\n",(0,o.jsxs)(t.p,{children:['To be easily interoperable with other software, being "API-first" is a priority.\nAs such, the status page should not ',(0,o.jsx)(t.em,{children:"need to"})," be a typical monolithic web application (even though it could be), hence making it possible to split functionality into an API server and a frontend component."]}),"\n",(0,o.jsxs)(t.h2,{id:"the-scs-status-page-api",children:["The SCS status page ",(0,o.jsx)(t.strong,{children:"API"})]}),"\n",(0,o.jsxs)(t.p,{children:["The SCS status page ",(0,o.jsx)(t.strong,{children:"API"})," (as opposed to actual implementations) is supposed to be as un-opinionated as possible regarding deployment, user management, persistence and tech stack, to allow operators/developers (1) to make their own decisions regarding these topics and (2) to quickly implement the API with their own tech stack opinions, if the reference implementation does not fit theirs."]}),"\n",(0,o.jsxs)(t.p,{children:["In particular, the ",(0,o.jsx)(t.strong,{children:"API"})," has no opinion about:"]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["How authentication/authorization is done (apart from splitting Read-only from Read-write ",(0,o.jsx)(t.sup,{children:(0,o.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"; See below)"]}),"\n",(0,o.jsx)(t.li,{children:"Server implementation, used database, deployment automation, high availability"}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"However, as un-opinionated the API (in its first iteration) strives to be, it is...:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"a REST API (no GRPC/GraphQL/...)"}),"\n",(0,o.jsx)(t.li,{children:"defined using an OpenAPI file to make use of OpenAPI tooling"}),"\n",(0,o.jsxs)(t.li,{children:["split in two parts ",(0,o.jsx)(t.sup,{children:(0,o.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),":","\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsx)(t.li,{children:"Read-only anonymous access"}),"\n",(0,o.jsx)(t.li,{children:"Read-write authenticated access"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.h3,{id:"reference-implementation",children:"Reference implementation"}),"\n",(0,o.jsxs)(t.p,{children:["It is envisioned to have a well-maintained reference implementation of the status page API with some basic tech stack decisions made, to not ",(0,o.jsx)(t.em,{children:"require"})," anyone to implement the API themselves:"]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Programming Language: Go"}),"\n",(0,o.jsx)(t.li,{children:"Persistence: Postgres compatible database"}),"\n"]}),"\n",(0,o.jsxs)(t.h2,{id:"the-scs-status-page-frontend",children:["The SCS status page ",(0,o.jsx)(t.strong,{children:"frontend"})]}),"\n",(0,o.jsxs)(t.p,{children:["The SCS status page ",(0,o.jsx)(t.strong,{children:"frontend"})," is supposed to be an application which uses the status page API to get information. This could be an CLI tool as well as an web application."]}),"\n",(0,o.jsx)(t.h3,{id:"reference-implementation-1",children:"Reference implementation"}),"\n",(0,o.jsx)(t.p,{children:"It is envisioned to have a well-maintained reference implementation of an status page frontend with some basic tech stack decisions made:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Platform: Web (HTML/JS/...)"}),"\n",(0,o.jsx)(t.li,{children:"Framework: VueJS, Vuetify"}),"\n"]}),"\n","\n",(0,o.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,o.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,o.jsxs)(t.p,{children:["In the future ",(0,o.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})," ",(0,o.jsxs)(t.a,{href:"#user-content-fnref-1-2","data-footnote-backref":"","aria-label":"Back to reference 1-2",className:"data-footnote-backref",children:["\u21a9",(0,o.jsx)(t.sup,{children:"2"})]})]}),"\n"]}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var s=n(96540);const o={},i=s.createContext(o);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f40b2df0.8c50ef9e.js b/assets/js/f40b2df0.8c50ef9e.js new file mode 100644 index 0000000000..3af0857728 --- /dev/null +++ b/assets/js/f40b2df0.8c50ef9e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3639],{32253:(e,a,o)=>{o.r(a),o.d(a,{assets:()=>r,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"iaas/guides/operations-guide/openstack/octavia","title":"Octavia","description":"Cleanup of amphorae missing from the DB","source":"@site/docs/02-iaas/guides/operations-guide/openstack/octavia.md","sourceDirName":"02-iaas/guides/operations-guide/openstack","slug":"/iaas/guides/operations-guide/openstack/octavia","permalink":"/docs/iaas/guides/operations-guide/openstack/octavia","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/octavia.md","tags":[],"version":"current","frontMatter":{"sidebar_label":"Octavia"},"sidebar":"docs","previous":{"title":"Nova","permalink":"/docs/iaas/guides/operations-guide/openstack/nova"},"next":{"title":"Ceph via Rook (technical preview)","permalink":"/docs/iaas/guides/operations-guide/rook"}}');var s=o(74848),n=o(28453);const i={sidebar_label:"Octavia"},c="Octavia",r={},d=[{value:"Cleanup of amphorae missing from the DB",id:"cleanup-of-amphorae-missing-from-the-db",level:2},{value:"SSH access to amphorae",id:"ssh-access-to-amphorae",level:2}];function l(e){const a={code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,n.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(a.header,{children:(0,s.jsx)(a.h1,{id:"octavia",children:"Octavia"})}),"\n",(0,s.jsx)(a.h2,{id:"cleanup-of-amphorae-missing-from-the-db",children:"Cleanup of amphorae missing from the DB"}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{className:"language-none",metastring:'title="/var/log/kolla/octavia/octavia-health-manager.log"',children:"2023-10-25 16:43:52.547 22 WARNING octavia.amphorae.drivers.health.heartbeat_udp [-]\nThe amphora 2a33a889-4f9a-4340-84a5-e58a7a8af17e with IP 10.1.0.79 is missing from the\nDB, so it cannot be automatically deleted (the compute_id is unknown). An operator must\nmanually delete it from the compute service.\n"})}),"\n",(0,s.jsx)(a.h2,{id:"ssh-access-to-amphorae",children:"SSH access to amphorae"}),"\n",(0,s.jsxs)(a.ol,{children:["\n",(0,s.jsxs)(a.li,{children:["\n",(0,s.jsxs)(a.p,{children:["Get the local IP address (",(0,s.jsx)(a.code,{children:"lb_network_ip"}),") of the amphora you want to access via\n",(0,s.jsx)(a.code,{children:"openstack --os-cloud admin loadbalancer amphora list"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(a.li,{children:["\n",(0,s.jsx)(a.p,{children:"Connect to one of the nodes that you use for Octavia. Normally the control-\nor network nodes."}),"\n"]}),"\n",(0,s.jsxs)(a.li,{children:["\n",(0,s.jsxs)(a.p,{children:["You can now use SSH to access the amphora. The use of sudo is required here because\nyou cannot access ",(0,s.jsx)(a.code,{children:"/etc/kolla/octavia-worker/octavia_ssh_key"})," with the operator user\naccount. Replace ",(0,s.jsx)(a.code,{children:"lb_network_ip"})," with the local IP address of the amphora."]}),"\n",(0,s.jsx)(a.pre,{children:(0,s.jsx)(a.code,{children:"sudo ssh -i /etc/kolla/octavia-worker/octavia_ssh_key ubuntu@lb_network_ip\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:a}={...(0,n.R)(),...e.components};return a?(0,s.jsx)(a,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,a,o)=>{o.d(a,{R:()=>i,x:()=>c});var t=o(96540);const s={},n=t.createContext(s);function i(e){const a=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function c(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(n.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f4cdb2d9.b75924eb.js b/assets/js/f4cdb2d9.b75924eb.js new file mode 100644 index 0000000000..addc1eb118 --- /dev/null +++ b/assets/js/f4cdb2d9.b75924eb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[49745],{86568:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>o,toc:()=>a});const o=JSON.parse('{"id":"container/overview/knowledge","title":"Knowledge","description":"TODO","source":"@site/docs/03-container/overview/knowledge.md","sourceDirName":"03-container/overview","slug":"/container/overview/knowledge","permalink":"/docs/container/overview/knowledge","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/overview/knowledge.md","tags":[],"version":"current","frontMatter":{}}');var r=t(74848),c=t(28453);const s={},i="Knowledge",d={},a=[];function l(e){const n={h1:"h1",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"knowledge",children:"Knowledge"})}),"\n",(0,r.jsx)(n.p,{children:"TODO"})]})}function u(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>i});var o=t(96540);const r={},c=o.createContext(r);function s(e){const n=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),o.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f4daec3f.6aed5561.js b/assets/js/f4daec3f.6aed5561.js new file mode 100644 index 0000000000..8c48376a73 --- /dev/null +++ b/assets/js/f4daec3f.6aed5561.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[47475],{27860:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>d,default:()=>u,frontMatter:()=>c,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"iaas/scs-0117","title":"scs-0117: Volume Backup Functionality","description":"| Version | Type | State | stabilized | deprecated |","source":"@site/standards/iaas/scs-0117.md","sourceDirName":"iaas","slug":"/iaas/scs-0117","permalink":"/standards/iaas/scs-0117","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"W1","permalink":"/standards/scs-0116-w1-key-manager-implementation-testing"},"next":{"title":"V1","permalink":"/standards/scs-0117-v1-volume-backup-service"}}');var a=s(74848),r=s(28453);const c={},d="scs-0117: Volume Backup Functionality",i={},o=[];function l(e){const t={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"scs-0117-volume-backup-functionality",children:"scs-0117: Volume Backup Functionality"})}),"\n",(0,a.jsxs)(t.table,{children:[(0,a.jsx)(t.thead,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.th,{children:"Version"}),(0,a.jsx)(t.th,{children:"Type"}),(0,a.jsx)(t.th,{children:"State"}),(0,a.jsx)(t.th,{children:"stabilized"}),(0,a.jsx)(t.th,{children:"deprecated"})]})}),(0,a.jsx)(t.tbody,{children:(0,a.jsxs)(t.tr,{children:[(0,a.jsx)(t.td,{children:(0,a.jsx)(t.a,{href:"/standards/scs-0117-v1-volume-backup-service",children:"scs-0117-v1"})}),(0,a.jsx)(t.td,{children:"Standard"}),(0,a.jsx)(t.td,{children:"Stable"}),(0,a.jsx)(t.td,{children:"2024-11-13"}),(0,a.jsx)(t.td,{children:"-"})]})})]})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>d});var n=s(96540);const a={},r=n.createContext(a);function c(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f4f96b66.e938f80d.js b/assets/js/f4f96b66.e938f80d.js new file mode 100644 index 0000000000..2c9418d637 --- /dev/null +++ b/assets/js/f4f96b66.e938f80d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[34062],{92789:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});const a=JSON.parse('{"id":"turnkey-solution/hardware-landscape","title":"The SCS Hardware-Landscape","description":"An image of the SCS hardware landscape rack","source":"@site/docs/turnkey-solution/hardware-landscape.md","sourceDirName":"turnkey-solution","slug":"/turnkey-solution/hardware-landscape","permalink":"/docs/turnkey-solution/hardware-landscape","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/turnkey-solution/hardware-landscape.md","tags":[],"version":"current","sidebarPosition":99,"frontMatter":{"sidebar_label":"Hardware-Landscape","sidebar_position":99},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/turnkey-solution/overview"},"next":{"title":"Releases","permalink":"/docs/category/releases"}}');var i=t(74848),s=t(28453);const r={sidebar_label:"Hardware-Landscape",sidebar_position:99},o="The SCS Hardware-Landscape",l={},d=[{value:"General information",id:"general-information",level:2},{value:"Tasks and Objectives",id:"tasks-and-objectives",level:2},{value:"Installation details",id:"installation-details",level:2},{value:"Available documentation",id:"available-documentation",level:2},{value:"Specific installation and configuration details",id:"specific-installation-and-configuration-details",level:2}];function c(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"the-scs-hardware-landscape",children:"The SCS Hardware-Landscape"})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"An image of the SCS hardware landscape rack",src:t(23554).A+"",width:"1100",height:"1364"})}),"\n",(0,i.jsx)(n.h2,{id:"general-information",children:"General information"}),"\n",(0,i.jsx)(n.p,{children:"The general aim of this environment is to install and operate the SCS reference implementation on hardware.\nIn addition to the classic tasks in the area of quality assurance, the environment is also used to evaluate\nnew concepts in the underlay/overlay network area, as a test environment for hardware-related developments,\nas a demonstration environment for interested parties and as a publicly accessible blueprint for users.\nThe environment is designed for long-term use which a varying circle of users."}),"\n",(0,i.jsx)(n.p,{children:"The environment consists of 21 server and 12 switch components. The selection of hardware and the\nfunctions and properties used was designed so that the focus is on generally available or characteristic\nfunctions and dependency on manufacturer-specific functions is avoided. Instead of the x86 servers or SONiC\nswitches used here, the realised environment could also be realised with hardware from other manufacturers."}),"\n",(0,i.jsxs)(n.p,{children:["From 1 January 2025, the environment will be operated by ",(0,i.jsx)(n.a,{href:"https://scs.community/2024/10/23/osba-forum-scs-standards/",children:"forum SCS-Standards"}),"\nand the participating companies."]}),"\n",(0,i.jsx)(n.h2,{id:"tasks-and-objectives",children:"Tasks and Objectives"}),"\n",(0,i.jsx)(n.p,{children:"The tasks and objectives of the environments can be summarised as follows:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The division into several environments makes it possible to run a lab as well as to map a productive environment (near-live operation)."}),"\n",(0,i.jsx)(n.li,{children:"Operation of the compliance monitor (automated test for conformity with the SCS standards)"}),"\n",(0,i.jsx)(n.li,{children:"Implementation and validation of the developed standards in a reference environment"}),"\n",(0,i.jsx)(n.li,{children:"Analysis of problems in the interaction with the standards"}),"\n",(0,i.jsx)(n.li,{children:"Provision of proof-of-concept installations for interested parties who want to use, promote or further develop the project"}),"\n",(0,i.jsx)(n.li,{children:"The environment can be used by members of the SCS Standards forum and by contributors to the SCS community\nas a development and test environment for open-source development in connection with the further development\nof the SCS standards, SCS reference implementation and other relevant software components ('open-lab'/'near-live laboratory')."}),"\n",(0,i.jsx)(n.li,{children:"Continuous Integration Environment ('Zuul as a Service') - Operation of non-critical zuul worker instances"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"installation-details",children:"Installation details"}),"\n",(0,i.jsx)(n.p,{children:"The available hardware was divided into two distinct application areas:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["The ",(0,i.jsx)(n.strong,{children:"lab environment"})," consists exclusively of switch hardware used to evaluate, test and develop\nconcepts in the area of 'Software Defined Networking'. This means that various switch models can be\nused to test and implement development tasks in the area of the open ",(0,i.jsx)(n.a,{href:"https://sonicfoundation.dev/",children:"SONiC"})," NOS\n(a network operating system based on Debian Linux) or provisioning automation tasks in the SONiC environment with the\nopen-source system Netbox, a solution that is used primarily for IPAM and DCIM (IP Address Management, Data Center Infrastructure Management)."]}),"\n",(0,i.jsxs)(n.li,{children:["The ",(0,i.jsx)(n.strong,{children:"production environment"})," is an exemplary installation of the relevant or most reference implementations with regard to an\nSCS system. It follows a configuration or approach that is based on the needs and circumstances of a real and much larger environment.\nTo this end, characteristic infrastructure components were automatically installed on the manager nodes used for the installation."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The setup of the entire environment is designed in such a way that it can be reproducibly restored or reset.\nTherefore, the Ansible automation available via OSISM was used in many areas.\nAreas that could not be usefully automated using Ansible were implemented using a Python command-line tooling stored in the GIT repository."}),"\n",(0,i.jsx)(n.h2,{id:"available-documentation",children:"Available documentation"}),"\n",(0,i.jsxs)(n.p,{children:["The primary point of information and orientation is the ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/hardware-landscape?tab=readme-ov-file#references",children:(0,i.jsx)(n.em,{children:"readme file"})}),"\nwhich is stored at the top level of the ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/hardware-landscape",children:"configuration repository"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The relevant ",(0,i.jsx)(n.strong,{children:"References"})," section refers here to the individual documentation areas."]}),"\n",(0,i.jsx)(n.h2,{id:"specific-installation-and-configuration-details",children:"Specific installation and configuration details"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Processes for access management to the environment (2 VPN gateways, SSH logins, SSH profiles,..) have been implemented"}),"\n",(0,i.jsx)(n.li,{children:"The production and lab environments have been set up, automated and documented as described above"}),"\n",(0,i.jsxs)(n.li,{children:["The complete environment is managed in a ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/hardware-landscape",children:"GIT repository"}),",\nadjustments and further developments are managed via GIT merge requests"]}),"\n",(0,i.jsxs)(n.li,{children:["Almost all installation steps are ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/hardware-landscape/blob/main/documentation/System_Deployment.md",children:"documented and automated"}),"\nbased on a pure rack installation (The setup is extensively documented, in particular the few manual steps)","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["The entire customized setup of the nodes is ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/hardware-landscape/tree/main/environments/custom",children:"implemented by OSISM/Ansible"})]}),"\n",(0,i.jsx)(n.li,{children:"All secrets (e.g. passwords) of the environment are stored and versioned in the encrypted Ansible Vault in\nthe repository (when access is transferred, rekeying can be used to change the access or the rights to it)."}),"\n",(0,i.jsx)(n.li,{children:"A far-reaching or in-depth automation has been created that allows the environment to be re-set up or parts of it to\nbe re-set up with a reasonable amount of personnel."}),"\n",(0,i.jsx)(n.li,{children:"The setup of the basic environment was implemented appropriately with Ansible and using the OSISM environment (the reference implementation)"}),"\n",(0,i.jsx)(n.li,{children:"Python tooling was created that adds areas that are specific to the use case of the environment and provides functions that simplify the operation of the infrastructure"}),"\n",(0,i.jsxs)(n.li,{children:["Server systems","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Backup and restore of the hardware configuration"}),"\n",(0,i.jsx)(n.li,{children:"Templating of the BMC configuration"}),"\n",(0,i.jsx)(n.li,{children:"Automatic installation of the operating system base image via Redfish Virtual Media"}),"\n",(0,i.jsx)(n.li,{children:"Control of the server status via command line (to stop and start the system for test, maintenance and energy-saving purposes)"}),"\n",(0,i.jsx)(n.li,{children:"Generation of base profiles for the Ansible Inventory based on the hardware key data stored in the documentation"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Switches","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Backup and restore of the switch configuration"}),"\n",(0,i.jsx)(n.li,{children:"Generation of base profiles for the Ansible Inventory based on the hardware key data stored in the documentation"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Network setup","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The two management hosts act as redundant VPN gateways, ssh jumphosts, routers and uplink routers"}),"\n",(0,i.jsx)(n.li,{children:"The system is deployed with a layer 3 underlay concept"}),"\n",(0,i.jsx)(n.li,{children:'An "eBGP router on the host" is implemented for the node-interconnectivity\n(all nodes and all switches are running FRR instances)'}),"\n",(0,i.jsx)(n.li,{children:"All Ceph and Openstack nodes of the system do not have a direct upstream routing\n(access is configured and provided by HTTP-, NTP and DNS-proxies)"}),"\n",(0,i.jsx)(n.li,{children:"For security reasons, the system itself can only be accessed via VPN.\nThe provider network of the production environment is realized with a VXLAN which is terminated on the managers for routing\n('a virtual provider network'))."}),"\n",(0,i.jsxs)(n.li,{children:["The basic node installation was realised in such a way that specific ",(0,i.jsx)(n.a,{href:"https://github.com/osism/node-image",children:"node images"}),"\nare created for the respective rack, which make the operation or reconfiguration of network equipment for PXE bootstrap\nunnecessary. (Preliminary stage for rollout via OpenStack Ironic)"]}),"\n",(0,i.jsx)(n.li,{children:"The management of the hardware (BMC and switch management) is implemented with a VLAN"}),"\n",(0,i.jsx)(n.li,{children:"Routing, firewalling and NAT is managed by a NFTables Script which adds rules in a idempotent way to the existing rules\nof the manager nodes."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["The ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-workload-generator",children:"openstack workload generator"})," is used put test workloads\non the system","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Automated creation of OpenStack domains, projects, servers, networks, users, etc."}),"\n",(0,i.jsx)(n.li,{children:"Launching test workloads"}),"\n",(0,i.jsx)(n.li,{children:"Dismantling test workloads"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["An observability stack was built","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Prometheus for metrics"}),"\n",(0,i.jsx)(n.li,{children:"Opensearch for log aggregation"}),"\n",(0,i.jsx)(n.li,{children:"Central syslog server for the switches on the managers (recorded via the manager nodes in Opensearch)"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Specific documentation created for the project","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Details of the hardware installed in the environment"}),"\n",(0,i.jsx)(n.li,{children:"The physical structure of the environment was documented in detail (rack installation and cabling)"}),"\n",(0,i.jsx)(n.li,{children:"The technical and logical structure of the environment was documented in detail"}),"\n",(0,i.jsx)(n.li,{children:"A FAQ for handling the open-source network operating system SONiC was created with relevant topics for the test environment"}),"\n",(0,i.jsx)(n.li,{children:"As part of the development, the documentation and implementation of the OSISM reference implementation was significantly improved (essentially resulting from"}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},23554:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/combined_rack_visual-56539dc452d0bee6fd7c677d5117d814.jpg"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const i={},s=a.createContext(i);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f53abb4b.36a5d3a8.js b/assets/js/f53abb4b.36a5d3a8.js new file mode 100644 index 0000000000..5b37d5fd28 --- /dev/null +++ b/assets/js/f53abb4b.36a5d3a8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[43862],{83760:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"standards"}')}}]); \ No newline at end of file diff --git a/assets/js/f5b4e375.98fb71e1.js b/assets/js/f5b4e375.98fb71e1.js new file mode 100644 index 0000000000..70705a9414 --- /dev/null +++ b/assets/js/f5b4e375.98fb71e1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[60778],{60106:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"scs-0210-v2-k8s-version-policy","title":"SCS K8S Version Policy","description":"Introduction","source":"@site/standards/scs-0210-v2-k8s-version-policy.md","sourceDirName":".","slug":"/scs-0210-v2-k8s-version-policy","permalink":"/standards/scs-0210-v2-k8s-version-policy","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS K8S Version Policy","type":"Standard","stabilized_at":"2024-02-08T00:00:00.000Z","status":"Stable","track":"KaaS"},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0210-v1-k8s-new-version-policy"},"next":{"title":"W1","permalink":"/standards/scs-0210-w1-k8s-version-policy-implementation-testing"}}');var r=n(74848),i=n(28453);const o={title:"SCS K8S Version Policy",type:"Standard",stabilized_at:new Date("2024-02-08T00:00:00.000Z"),status:"Stable",track:"KaaS"},a=void 0,l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const s={a:"a",code:"code",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsx)(s.p,{children:"The Kubernetes project maintains multiple release versions including their patched versions.\nIn the project, the three most recent minor releases are actively maintained, with a fourth\nversion being in development. As soon as a new minor version is officially released,\nthe oldest version is dropped out of the support period.\nKubernetes supports its releases for around 14 months. 12 of these are the standard\nsupport period. The remaining 2 months are the end-of-life support period for things like:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"CVEs (under the advisement of the Security Response Committee)"}),"\n",(0,r.jsx)(s.li,{children:"dependency issues (including base image updates)"}),"\n",(0,r.jsx)(s.li,{children:"critical core component issues"}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"More information can be found under [Kubernetes Support Period]."}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/releases/release/#the-release-cycle",children:"Kubernetes release cycle"})," is set around 4 months, which\nusually results in about ",(0,r.jsx)(s.strong,{children:"3 minor"})," releases per year."]}),"\n",(0,r.jsxs)(s.p,{children:["Patches to these releases are provided monthly, except for the first patch,\nwhich is usually provided 1-2 weeks after the initial release (see ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/releases/patch-releases/#cadence",children:"Patch Release\nCadence"}),")."]}),"\n",(0,r.jsx)(s.h2,{id:"motivation",children:"Motivation"}),"\n",(0,r.jsx)(s.p,{children:"Kubernetes is a living, fast-paced project, which follows a pre-defined release cycle.\nThis enables forward planning with regard to releases and patches, but also implies a\nnecessity to upgrade to newer versions quickly, since these often include new features,\nimportant security updates or especially if a previous version falls out of the support\nperiod window."}),"\n",(0,r.jsx)(s.p,{children:"We want to achieve an up-to-date policy, meaning that providers should be mostly in\nsync with the upstream and don't fall behind the official Kubernetes releases.\nThis is achievable, since new versions are released periodical on a well communicated\nschedule, enabling providers and users to set up processes around it.\nBeing up-to-date ensures that security issues and bugs are addressed and new features\nare made available when using SCS compliant clusters."}),"\n",(0,r.jsx)(s.p,{children:"It is nevertheless important to at least support all Kubernetes versions that are still\ninside the support period, since users could depend on specific versions or may need\nlonger to upgrade their workloads to a newer version."}),"\n",(0,r.jsx)(s.p,{children:"The standard therefore should provide a version recency policy as well as a support\nwindow period."}),"\n",(0,r.jsx)(s.h2,{id:"decision",children:"Decision"}),"\n",(0,r.jsx)(s.p,{children:"In order to keep up-to-date with the latest Kubernetes features, bug fixes and security improvements,\nthe provided Kubernetes versions should be kept up-to-date with new upstream releases:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"The latest minor version MUST be provided no later than 4 months after release."}),"\n",(0,r.jsx)(s.li,{children:"The latest patch version MUST be provided no later than 2 weeks after release."}),"\n",(0,r.jsx)(s.li,{children:"This time period MUST be even shorter for patches that fix critical CVEs.\nIn this context, a critical CVE is a CVE with a CVSS base score >= 8 according\nto the CVSS version used in the original CVE record (e.g., CVSSv3.1).\nIt is RECOMMENDED to provide a new patch version in a 2-day time period after their release."}),"\n",(0,r.jsxs)(s.li,{children:["New versions MUST be tested before being rolled out on productive infrastructure;\nat least the ",(0,r.jsx)(s.a,{href:"https://github.com/cncf/k8s-conformance",children:"CNCF E2E tests"})," should be passed beforehand."]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["At the same time, providers must support Kubernetes versions at least as long as the\nofficial sources as described in ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/releases/patch-releases/#support-period",children:"Kubernetes Support Period"}),":"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["Kubernetes versions MUST be supported as long as the official sources support them\naccording to the ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/releases/patch-releases/#support-period",children:"Kubernetes Support Period"})," and their end-of-life\ndate according to the ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/releases/",children:"Kubernetes Releases page"}),"."]}),"\n",(0,r.jsx)(s.li,{children:"It is RECOMMENDED to not support versions after this period in order to not encourage\nusage of out-of-date versions."}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,r.jsxs)(s.p,{children:["All documents regarding versioning, releases, etc. for the official Kubernetes projects can\nbe found on the ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/releases/",children:"Kubernetes Releases page"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,r.jsxs)(s.p,{children:["The script ",(0,r.jsx)(s.code,{children:"k8s_version_policy.py"})," requires a kubeconfig file with connection details for\na set of existing Kubernetes clusters that should be checked, with each of these clusters\nrepresenting one of the currently supported upstream Kubernetes releases.\nIt will check the encountered cluster versions according to the rules of this standard.\nRule violations will be reported on various logging channels: ERROR for mandatory rules\nand INFO for recommended rules.\nThe script will exit with a non-zero status if a mandatory rule has been violated or if\nthe test could not be performed."]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var t=n(96540);const r={},i=t.createContext(r);function o(e){const s=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f5cc95ce.555c9990.js b/assets/js/f5cc95ce.555c9990.js new file mode 100644 index 0000000000..29cbc5ae08 --- /dev/null +++ b/assets/js/f5cc95ce.555c9990.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[62312],{78068:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>i,default:()=>u,frontMatter:()=>p,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"operating-scs/components/status-page-openapi/docs/components","title":"Components","description":"Illustrating multiple interchangeable logical \\"layers\\" of possible Status Page application stacks:","source":"@site/docs/04-operating-scs/components/status-page-openapi/docs/components.md","sourceDirName":"04-operating-scs/components/status-page-openapi/docs","slug":"/operating-scs/components/status-page-openapi/docs/components","permalink":"/docs/operating-scs/components/status-page-openapi/docs/components","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-openapi/docs/components.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/operating-scs/components/status-page-openapi/docs/overview"},"next":{"title":"\\"Levels of consensus\\"","permalink":"/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus"}}');var o=t(74848),a=t(28453);const p={},i="Components",r={},c=[];function l(e){const n={h1:"h1",header:"header",mermaid:"mermaid",p:"p",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"components",children:"Components"})}),"\n",(0,o.jsx)(n.p,{children:'Illustrating multiple interchangeable logical "layers" of possible Status Page application stacks:'}),"\n",(0,o.jsx)(n.mermaid,{value:' C4Container\n title SCS Status Page components\n UpdateLayoutConfig("100", "1")\n Boundary(b4, "Application layer") {\n Container(app1, "Flask App", "OAuth2 impl. etc.")\n Container(app2, "Vue App", "OAuth2 impl. etc.")\n Container(app3, "CLI Client", "CLI Client")\n }\n Boundary(b3, "Policy layer") {\n Container(policy1, "istio end-user auth", "")\n Container(policy2, "custom auth proxy", "")\n Container(policy3, "Caddy", "")\n }\n Boundary(b2, "API server layer") {\n Container(api1, "API Server (Go)", "")\n Container(api2, "API Server (Python)", "")\n Container(api3, "API Server (Go)", "")\n }\n Boundary(b1, "Database layer") {\n Container(db1, "postgres", "")\n Container(db2, "mysql", "")\n Container(db3, "github", "Github Projects API")\n }\n Rel(api1, db1, "Uses", "Postgres protocol")\n Rel(api2, db2, "Uses", "MySQL protocol")\n Rel(api3, db3, "Uses", "GraphQL API")\n Rel(policy1, api1, "Relays", "SCS Status Page API")\n Rel(policy2, api2, "Relays", "SCS Status Page API")\n Rel(policy3, api3, "Relays", "SCS Status Page API")\n Rel(app1, policy1, "Requests", "SCS Status Page API + Auth")\n Rel(app2, policy2, "Requests", "SCS Status Page API + Auth")\n Rel(app3, policy3, "Requests", "SCS Status Page API + Auth")'}),"\n",(0,o.jsx)(n.p,{children:"Note that not everything that is shown here, actually exists or was tested. It is just shown for illustration purposes."})]})}function u(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>p,x:()=>i});var s=t(96540);const o={},a=s.createContext(o);function p(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:p(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f600298c.6a37af8c.js b/assets/js/f600298c.6a37af8c.js new file mode 100644 index 0000000000..0aa7de63d1 --- /dev/null +++ b/assets/js/f600298c.6a37af8c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[80639],{49282:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"operating-scs/components/automated-pentesting-iaas/reports","title":"Using Automated Pentesting Reports for CSPs, Operators, and Users","description":"This section outlines how Infrastructure Operators (Cloud Service Providers - CSPs) and users can leverage automated pentesting reports focused on Infrastructure-as-a-Service (IaaS) and Container-as-a-Service (CaaS) environments.","source":"@site/docs/04-operating-scs/components/automated-pentesting-iaas/reports.md","sourceDirName":"04-operating-scs/components/automated-pentesting-iaas","slug":"/operating-scs/components/automated-pentesting-iaas/reports","permalink":"/docs/operating-scs/components/automated-pentesting-iaas/reports","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/automated-pentesting-iaas/reports.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Tools Description","permalink":"/docs/operating-scs/components/automated-pentesting-iaas/tools"},"next":{"title":"Pentesting KaaS","permalink":"/docs/category/pentesting-kaas"}}');var r=i(74848),t=i(28453);const o={},a="Using Automated Pentesting Reports for CSPs, Operators, and Users",l={},c=[{value:"Understanding the Pentesting Reports for IaaS and CaaS",id:"understanding-the-pentesting-reports-for-iaas-and-caas",level:2},{value:"Importance of Daily and Weekly Reports",id:"importance-of-daily-and-weekly-reports",level:3},{value:"Daily Reports",id:"daily-reports",level:4},{value:"Weekly Reports",id:"weekly-reports",level:4},{value:"Key Characteristics and Capabilities of Reports",id:"key-characteristics-and-capabilities-of-reports",level:3},{value:"Role and Responsibilities of Operators and Users",id:"role-and-responsibilities-of-operators-and-users",level:2},{value:"For Operators (high-level view):",id:"for-operators-high-level-view",level:3},{value:"For Operator's staff:",id:"for-operators-staff",level:3},{value:"For Users (DevOps):",id:"for-users-devops",level:3},{value:"Actions Based on Pentesting Reports",id:"actions-based-on-pentesting-reports",level:2},{value:"SOC Operations",id:"soc-operations",level:2},{value:"With a SOC",id:"with-a-soc",level:3},{value:"Without a SOC:",id:"without-a-soc",level:3},{value:"Future Policy Development",id:"future-policy-development",level:2},{value:"Conclusion",id:"conclusion",level:2}];function d(e){const n={h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"using-automated-pentesting-reports-for-csps-operators-and-users",children:"Using Automated Pentesting Reports for CSPs, Operators, and Users"})}),"\n",(0,r.jsx)(n.p,{children:"This section outlines how Infrastructure Operators (Cloud Service Providers - CSPs) and users can leverage automated pentesting reports focused on Infrastructure-as-a-Service (IaaS) and Container-as-a-Service (CaaS) environments.\nIt explains the importance of daily and weekly reports for identifying and mitigating vulnerabilities, configuration issues, and security gaps in cloud infrastructure. Additionally, this documentation describes actionable\nprocesses for vulnerability management, tailored for both environments, and provides insights for operations with and without a Security Operations Center (SOC)."}),"\n",(0,r.jsx)(n.h2,{id:"understanding-the-pentesting-reports-for-iaas-and-caas",children:"Understanding the Pentesting Reports for IaaS and CaaS"}),"\n",(0,r.jsx)(n.p,{children:"Pentesting reports for IaaS and CaaS layers focus on identifying security weaknesses in cloud infrastructure and containerized environments. These reports are generated by automated tools designed to scan for:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Open Ports"})," and ",(0,r.jsx)(n.strong,{children:"exposed services"})," in IaaS environments."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Container Security"}),": Assessing containerized environments for misconfigurations, unpatched vulnerabilities, and insecure networking settings."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Cloud Misconfigurations"}),": Ensuring proper IAM (Identity and Access Management) policies, storage bucket configurations, and other cloud resource settings."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Compliance Gaps"}),": Ensuring alignment with security policies and regulatory frameworks like CIS benchmarks and industry-specific standards."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"importance-of-daily-and-weekly-reports",children:"Importance of Daily and Weekly Reports"}),"\n",(0,r.jsx)(n.h4,{id:"daily-reports",children:"Daily Reports"}),"\n",(0,r.jsx)(n.p,{children:"Daily reports provide real-time insights into the current state of cloud infrastructure. They focus on:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Immediate Vulnerabilities"}),": New misconfigurations, exposed services or detected container security flaws."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Rapid Incident Response"}),": Helping CSPs and operators address critical issues quickly, reducing the window of exposure."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Change Monitoring"}),": Keeping track of changes in cloud and container environments that could introduce risks, particularly for systems with continuous updates."]}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"weekly-reports",children:"Weekly Reports"}),"\n",(0,r.jsx)(n.p,{children:"Weekly reports give a broader view of security health, highlighting trends and recurring issues. They are used to:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Strategize Long-term Remediation"}),": Address systemic problems like consistently misconfigured security groups or recurring container vulnerabilities."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Track Progress"}),": Monitor how quickly vulnerabilities are being resolved and track overall improvement in security posture."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Policy Compliance"}),": Provide a comprehensive overview for audits and compliance reporting, ensuring that security frameworks are being adhered to."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"key-characteristics-and-capabilities-of-reports",children:"Key Characteristics and Capabilities of Reports"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Actionable Insights"}),": Each report prioritizes vulnerabilities by severity, allowing teams to act efficiently and allocate resources accordingly."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Compliance Assurance"}),": Continuous monitoring and scanning ensure compliance with security standards such as GDPR, HIPAA, and CIS benchmarks."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Detailed Analysis"}),": Reports encompass vulnerabilities at different layers\u2014network, applications, and containers\u2014identifying open ports, unpatched software, and web app flaws."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"role-and-responsibilities-of-operators-and-users",children:"Role and Responsibilities of Operators and Users"}),"\n",(0,r.jsx)(n.h3,{id:"for-operators-high-level-view",children:"For Operators (high-level view):"}),"\n",(0,r.jsx)(n.p,{children:"Operators (CSPs) have a responsibility to ensure the security of the IaaS and CaaS layers they manage to protect their services and customer data. Key responsibilities include:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Daily Monitoring"}),": Use tools like Naabu and Httpx for open port discovery and service monitoring. Remediate any critical issues immediately, especially for public-facing services."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Configuration Audits"}),": Regularly assess cloud resource configurations using Nuclei and other compliance-focused tools to ensure adherence to security policies."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Container Vulnerability Management"}),": Ensure that containerized environments are properly isolated, updated, and hardened against known vulnerabilities."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"for-operators-staff",children:"For Operator's staff:"}),"\n",(0,r.jsx)(n.p,{children:"Operators are responsible for managing the security of cloud infrastructure, taking action based on the findings in the pentesting reports. Responsibilities include:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Triage and Response"}),": Review daily reports to prioritize high-risk vulnerabilities such as misconfigurations or container escape risks. Act immediately to close exposed ports or restrict access where needed."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Patch Management"}),": Use weekly reports to identify vulnerabilities that require patching or configuration changes, especially in CaaS environments where container images may have known flaws."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Long-term Fixes"}),": Address recurring issues by implementing security controls that reduce the likelihood of similar vulnerabilities appearing in the future."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"for-users-devops",children:"For Users (DevOps):"}),"\n",(0,r.jsx)(n.p,{children:"DevOps teams must integrate security into the development lifecycle for IaaS and CaaS environments:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Embed Tools in CI/CD"}),": Automated scanning tools should be part of the CI/CD pipeline to catch vulnerabilities before production deployment."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Infrastructure as Code"}),": Use pentesting insights to continuously improve cloud configuration templates, ensuring best practices are embedded in every deployment."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Monitor Application Security"}),": Continuously review reports to ensure that containerized applications are not introducing new vulnerabilities or compliance issues."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"actions-based-on-pentesting-reports",children:"Actions Based on Pentesting Reports"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Review Daily Reports"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Prioritize Critical Vulnerabilities: Focus first on critical issues such as open ports, misconfigurations, and unpatched containers. Use tools like Naabu for open ports and ZAP Proxy for application layer vulnerabilities."}),"\n",(0,r.jsx)(n.li,{children:"Validate Exposed Services: Ensure any services flagged as exposed are necessary. If not, restrict or close access."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Immediate Response"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Apply Patches: For vulnerabilities in container images or cloud configurations, apply patches immediately using automated pipelines where possible."}),"\n",(0,r.jsx)(n.li,{children:"Remediate Misconfigurations: Correct any misconfigurations flagged in identity, access management (IAM), or resource policies to prevent exploitation."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Automate Responses"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Use Predefined Rules: Set up automatic responses for common issues such as closing ports or restarting vulnerable services. Implement this via configuration management tools or CI/CD pipelines."}),"\n",(0,r.jsx)(n.li,{children:"Integration with Monitoring Tools: Integrate the pentesting results with monitoring tools for real-time alerting and response automation, reducing manual efforts."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Document Actions"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Track Resolutions: Use vulnerability management platforms like DefectDojo to track issues resolved throughout the day. Ensure all critical vulnerabilities are documented and tracked to completion."}),"\n",(0,r.jsx)(n.li,{children:"Generate Daily Reports for Management: Summarize critical vulnerabilities addressed and ongoing risks for reporting purposes."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Plan for Continuous Scans"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Rerun Scans After Fixes: Ensure new scans are initiated after significant patches or configuration changes to validate that vulnerabilities have been fully mitigated."}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Feedback Loop"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Refine Pipelines: Use insights from recurring vulnerabilities or issues to improve your IaaS and CaaS configuration templates and pentesting configurations."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"By following these steps daily, teams can ensure they stay on top of vulnerabilities, continuously improving their cloud infrastructure security posture."}),"\n",(0,r.jsx)(n.h2,{id:"soc-operations",children:"SOC Operations"}),"\n",(0,r.jsx)(n.p,{children:"A SOC (Security Operations Center) is crucial for larger organizations to centralize threat detection, vulnerability management, and incident response.\nIt allows for rapid response to vulnerabilities identified in pentesting reports, providing 24/7 monitoring and remediation capabilities.\nHowever it is also possible for smaller teams (without a dedicated SOC) to take advantage of these reports."}),"\n",(0,r.jsx)(n.h3,{id:"with-a-soc",children:"With a SOC"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Daily Triage and Monitoring"}),": SOC teams use pentesting reports to triage vulnerabilities, prioritizing critical risks such as exposed ports, misconfigurations, and unpatched containers."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Vulnerability Ticketing"}),": Use platforms like DefectDojo to assign vulnerabilities to appropriate teams, tracking their resolution."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Incident Response"}),": High-priority vulnerabilities are immediately addressed, with automated workflows in place to deploy fixes or isolate compromised services."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Documentation"}),": Weekly reports are used for documenting resolved vulnerabilities and tracking recurring issues, providing a basis for long-term improvements."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"without-a-soc",children:"Without a SOC:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Manual Review"}),": Without a SOC, designated IT or DevOps teams must manually review daily pentesting reports. High-risk vulnerabilities should be addressed immediately, while lower-risk issues can be prioritized based on business impact."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Automation"}),": Automate remediation processes where possible (e.g., automated patching of containers or closing of exposed ports) to reduce manual effort and response time."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Long-term Monitoring"}),": Use weekly reports to monitor recurring vulnerabilities and address the root causes, ensuring systemic issues are resolved over time."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"future-policy-development",children:"Future Policy Development"}),"\n",(0,r.jsx)(n.p,{children:"Pentesting reports not only drive immediate security actions but also form the backbone for long-term security policy development.\nThey provide a continuous stream of vulnerability data that can be used to craft policies around patch management, incident response, and compliance enforcement. This continuous cycle of vulnerability identification and remediation supports the development of:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Risk-Based Patch Management Policies"}),": Define timelines for addressing vulnerabilities based on their severity and potential impact on cloud services."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Security Audits and Compliance"}),": Use the reports as evidence of compliance with industry standards, like CIS benchmarks ir GPDR, allowing for continuous audits and ensuring regulatory alignment."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Incident Response Plans"}),": Establish guidelines for handling vulnerabilities identified in pentesting reports, ensuring quick and effective responses to critical risks."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,r.jsx)(n.p,{children:"Pentesting reports provide crucial insights that enable CSPs, operators, and users to maintain a proactive security posture.\nSOC teams, or in their absence, designated personnel, should use these reports to address vulnerabilities, manage risks, and improve infrastructure security.\nDaily and weekly reports guide both immediate and long-term actions, ensuring that vulnerabilities are addressed promptly and systemic issues are resolved through strategic security improvements."}),"\n",(0,r.jsx)(n.p,{children:"By using pentesting reports effectively, organizations can improve their vulnerability management processes, maintain compliance, and enhance their overall security strategy."})]})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>a});var s=i(96540);const r={},t=s.createContext(r);function o(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f68824be.2624aad4.js b/assets/js/f68824be.2624aad4.js new file mode 100644 index 0000000000..79d7c0b3c9 --- /dev/null +++ b/assets/js/f68824be.2624aad4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[36070],{92291:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"scs-0300-v1-requirements-for-sso-identity-federation","title":"Requirements for SSO identity federation","description":"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign\\nCloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed\\nexternally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard\\nfocuses on delegating authentication to external identity providers and mapping users to roles within SCS for\\nauthorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity\\nProvider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible.\\n","source":"@site/standards/scs-0300-v1-requirements-for-sso-identity-federation.md","sourceDirName":".","slug":"/scs-0300-v1-requirements-for-sso-identity-federation","permalink":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Requirements for SSO identity federation","type":"Decision Record","status":"Stable","stabilized_at":"2023-06-21T00:00:00.000Z","track":"IAM","description":"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign\\nCloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed\\nexternally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard\\nfocuses on delegating authentication to external identity providers and mapping users to roles within SCS for\\nauthorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity\\nProvider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible.\\n"},"sidebar":"standards","previous":{"title":"scs-0300: Requirements for SSO identity federation","permalink":"/standards/iam/scs-0300"},"next":{"title":"scs-0301: Naming for domains/groups/roles/project when onboarding new customers","permalink":"/standards/iam/scs-0301"}}');var s=n(74848),o=n(28453);const a={title:"Requirements for SSO identity federation",type:"Decision Record",status:"Stable",stabilized_at:new Date("2023-06-21T00:00:00.000Z"),track:"IAM",description:"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign\nCloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed\nexternally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard\nfocuses on delegating authentication to external identity providers and mapping users to roles within SCS for\nauthorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity\nProvider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible.\n"},r=void 0,d={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation for this document",id:"motivation-for-this-document",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Keycloak",id:"keycloak",level:4},{value:"Zitadel",id:"zitadel",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2},{value:"Conformance Tests, OPTIONAL",id:"conformance-tests-optional",level:2}];function l(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(t.p,{children:"Our assumption is that there are use cases, where CSPs would like to be able to\nlet customers access their SCS based services by identifying themselves with\ncredentials that are stored and managed external to the CSP's SCS installation."}),"\n",(0,s.jsx)(t.p,{children:"This is based on the observation that prospective customers of an SCS based CSP\nsometimes already come equipped with an IAM solution of their choice, either on\npremises or e.g. as an external 3rd party cloud service. To ease onboarding of\ncustomer employees (or e.g. customer contracted 3rd party admin staff) as SCS\nusers, it would be good to be able to consume these external identities in SCS."}),"\n",(0,s.jsx)(t.p,{children:"For customers this avoids the necessity to explicitly maintain an additional\ndedicated account in SCS and this also reduces what SCS needs to do with\nrespect to taking care of persisting user account information."}),"\n",(0,s.jsx)(t.p,{children:"To put it in other words, in SCS we would like to be able to delegate\nauthentication to external identity providers and map those users to roles in\nSCS that can be used for authorization decisions when users access SCS services."}),"\n",(0,s.jsx)(t.p,{children:'In addition to user identities there we also see the necessity to support the\nuse of "machine identities" (aka "workload identities" or "service accounts").\nThese will probably be SCS-local accounts and have for example the purpose\nto grant CaaS workload access to storage resources served by the infrastructure\nlayer. Exact architectural details for this are still in active discussion,\nbut it is anticipated that the IdP component should be very useful in\nfacilitating the integration.'}),"\n",(0,s.jsx)(t.h2,{id:"motivation-for-this-document",children:"Motivation for this document"}),"\n",(0,s.jsx)(t.p,{children:"SCS has multiple service layers, like IaaS and CaaS, both of which running their\nown technological stack with specific internal models of accounts and\nauthorization."}),"\n",(0,s.jsx)(t.p,{children:"One thing these services have in common, is that they are able\nto use SSO protocols like OAuth 2.0 or OpenID Connect (OIDC) on top of it to\ndelegate authentication. They are service providers (SAML terminology) and can\nbe relying on parties (OIDC terminology) of a protocol compliant identity provider\n(IdP)."}),"\n",(0,s.jsx)(t.p,{children:"So the idea is, to run an SSO IdP as part of SCS to provide a dedicated point\nof entry for identities, which the SCS service layers can use as a common\ninterface to consume external user identities."}),"\n",(0,s.jsx)(t.p,{children:"The purpose of this document is to specify what requirements a specific\ntechnical IdP implementation (i.e. software solution) needs to fulfill\nin the context of SCS."}),"\n",(0,s.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsx)(t.p,{children:"As a central service for identity handling, the IdP\nservice needs to be robust and reliable."}),"\n",(0,s.jsx)(t.p,{children:'Customers shall be able to access self-service, so that\nthey can make reasonable adjustments e.g. to role mapping.\nAt the time of writing this document it\'s still undecided\nif SCS has the requirement of a dedicated "self-service" service\nthat serves as a frontend to provision and re-configure\ncustomer specific data, abstracting e.g. from IdP specific\nuser interface particularities.'}),"\n",(0,s.jsx)(t.p,{children:'Keycloak is currently being deployed as part of the IaaS reference implementation.\nTechnically this IdP component shall be shifted from the management\nplane to be run on the basis of a "minimal" Kubernetes (e.g. K3S),\ne.g. to make use of the "self-healing" and scaling features achievable\nwith that.'}),"\n",(0,s.jsx)(t.p,{children:"So one of the considerations is if the solution will work well on a\nK8S environment. The instances will need to share configuration\n(probably via the shared backend database) as well as session state.\nMaybe one is better prepared for horizontal scaling than the other."}),"\n",(0,s.jsx)(t.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,s.jsx)(t.h4,{id:"keycloak",children:"Keycloak"}),"\n",(0,s.jsx)(t.p,{children:"Keycloak is a commonly used IdP solution implemented in Java.\nIt is developed as an open source community project.\nRed Hat uses it as upstream source for their Red Hat SSO product\nand is also listed as sponsor of the project.\nStarting with version 17 the default distribution is based on\nQuarkus instead of WildFly/JBoss."}),"\n",(0,s.jsxs)(t.p,{children:["The project maintains several means of community contributions\nas listed on the ",(0,s.jsx)(t.a,{href:"https://www.keycloak.org/community",children:"community section"}),"\nof the project website. It uses ",(0,s.jsx)(t.a,{href:"https://github.com/keycloak/keycloak/issues",children:"GitHub issues"}),"\nto track development."]}),"\n",(0,s.jsx)(t.p,{children:"It offers a REST API for administration and there's a separately maintained\n3rd party python module as well as ansible support for it. Both of these are\ndownstream of Keycloak itself and may thus not always be feature complete and\nsuffer latency with respect to getting adjusted to upstream changes."}),"\n",(0,s.jsx)(t.p,{children:'It offers support for commonly used SSO protocols and is "reasonably" fast\nin adopting to protocol standard changes and extensions. This has been\nobserved in the case of logout support (backend and frontend variants) in OIDC.'}),"\n",(0,s.jsx)(t.p,{children:'It offers a concept of "Identity Brokering", where Keycloak is not just IdP\nbut also "client" to other IdPs. This allows daisy-chaining of identity\nfederation. In this configuration it can work as a point of protocol\ntransition between different supported SSO protocols (SAML, OAuth 2.0, etc.).'}),"\n",(0,s.jsx)(t.p,{children:"Beyond this capability of using other IdPs as identity sources, it also supports\nusing classic LDAP based IAM services as backend (OpenLDAP and Active Directory,\ne.g.)."}),"\n",(0,s.jsx)(t.p,{children:'Keycloak\'s implementation makes some design decisions, that are specific\nto it and have consequences for clients of the service. E.g. Keycloak\nhas a concept of management "Realms", which have their own specific\nset of HTTP API entrypoints, both for administration and for IdP\nrequests.'}),"\n",(0,s.jsx)(t.p,{children:'Commonly Keycloak realms can be used to map them 1:1 to user domains,\nbut since Keycloak supports configuring multiple backend IdPs in a\nrealm to be used for "Identity Brokering", there is always the\npossibility to create a kind of "proxy" realm to provide a single\nstandard set of HTTP API endpoints for SSO clients (service providers)\nto avoid the need to frequently extend/reduce client service configuration\nwhenever a new IdP federation needs to be added to Keycloak to onboard\na new customer. This is relevant for services like OpenStack Keystone,\nwhich currently cannot be easily reconfigured for new SSO endpoints\nwithout restarting the service, making the service unavailable for\na short span of time and increasing risk connected with service restarts.'}),"\n",(0,s.jsx)(t.p,{children:'Since version 17, Keycloak claims that it\'s capability for\n"cloud native" deployments on Kubernetes has improved.'}),"\n",(0,s.jsxs)(t.p,{children:["Keycloak is offering a ",(0,s.jsx)(t.a,{href:"https://www.keycloak.org/documentation",children:"documented REST API"}),"\nfor all aspects of its administration interface."]}),"\n",(0,s.jsx)(t.p,{children:"For storage of Keycloak configuration and local user metadata\n(e.g. from which external IdP a user account originally came from)\nKeycloak supports several SQL backends through JDBC. Thus,\nit can be hooked up to a Postgres Database or to a\nMariaDB/Galera cluster e.g."}),"\n",(0,s.jsx)(t.p,{children:"As of April 11, 2023, Keycloak joined the CNCF as an incubating project."}),"\n",(0,s.jsx)(t.h4,{id:"zitadel",children:"Zitadel"}),"\n",(0,s.jsx)(t.p,{children:"Zitadel is a newer implementation of an SSO IdP.\nIt is implemented in Go and under active development and maintained by ZITADEL."}),"\n",(0,s.jsxs)(t.p,{children:["The project is open for community ",(0,s.jsx)(t.a,{href:"https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md",children:"contributions"}),"\nto all parts of the ecosystem.\nFeature requests and bugs being tracked on ",(0,s.jsx)(t.a,{href:"https://github.com/orgs/zitadel/projects/2/views/5",children:"GitHub"})," for development.\nCommunity questions can be asked in the ",(0,s.jsx)(t.a,{href:"https://zitadel.com/chat",children:"public chat"})," or via ",(0,s.jsx)(t.a,{href:"https://github.com/zitadel/zitadel/discussions",children:"GitHub Discussions"}),".\nZITADEL offers support for the commonly used authentication and authorization protocols such as OIDC, OAuth2, SAML2.\nIt is a compliant and certified OpenID Connect provider with support for various Grant Types for both human users and machine users.\nCompared to Keycloak SPIs, ZITADEL offers Actions to customize and integrate (eg, calling external APIs, Webhooks, customizing pre-built workflows, customizing tokens)\nActions are executed at runtime and can be maintained independently of platform.\nIdentity brokering (OIDC, SAML, JWT) can be configured system-wide or for each organization with templates.\nUsers will be created just in time for audit purposes and linked to the external identity provider.\nUsers can have multiple identity providers linked to their profile."]}),"\n",(0,s.jsx)(t.p,{children:"It came to attention of the SCS project because it offers a\nfresh take of an organization focussed data model, which has\nthe potential to simplify IdP federation to SCS customer domains\nin the following areas:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"For client services (single set of HTTP API endpoints)."}),"\n",(0,s.jsxs)(t.li,{children:["For SCS operators for provisioning customer ",(0,s.jsx)(t.a,{href:"https://zitadel.com/docs/concepts/structure/organizations",children:"organizations"}),"\nand robust configuration by using templated client, role and mapping\nconfiguration."]}),"\n",(0,s.jsx)(t.li,{children:"For SCS customers for a robust user experience for self servicing."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["The concept for ",(0,s.jsx)(t.a,{href:"https://zitadel.com/docs/concepts/structure/organizations",children:"Delegated Access Management"}),"\nreduces the management overhead compared to isolated realms.\nProjects (Applications + Roles) can be maintained by one organization and delegated to be used by other Organizations.\nManagers that receive granted Projects can assign users permissions to use the project."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://zitadel.com/docs/apis/introduction",children:"Zitadel is offering REST APIs"}),"\nfor multiple areas of use and configuration."]}),"\n",(0,s.jsxs)(t.p,{children:["It recently also added support for the ",(0,s.jsx)(t.a,{href:"https://github.com/zitadel/oidc/issues/141",children:"Device Authorization Grant"}),",\nwhich, at time of writing, is a feature that is relevant\nfor SCS to be able to use OpenStack CLI and APIs with federated\nidentities (",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/issues/issues/221",children:"Device Authorization Grant"}),")."]}),"\n",(0,s.jsxs)(t.p,{children:["Support for consumption of LDAP backends is available since ",(0,s.jsx)(t.a,{href:"https://github.com/zitadel/zitadel/releases/tag/v2.23.0",children:"Zitadel v2.23.0"}),"\n(see ",(0,s.jsx)(t.a,{href:"https://zitadel.com/docs/guides/integrate/identity-providers/ldap",children:"this guide"}),")."]}),"\n",(0,s.jsx)(t.p,{children:"ZITADEL supported backend databases are CockroachDB and PostgreSQL."}),"\n",(0,s.jsxs)(t.p,{children:["For ",(0,s.jsx)(t.a,{href:"https://zitadel.com/docs/self-hosting/manage/production",children:"production setups"})," it is recommended\nto use Kubernetes (or similar like Knative) and CockroachDB."]}),"\n",(0,s.jsx)(t.p,{children:'At time of writing a PoC "spike" is done to assess and verify the hopes\nconnected with Zitadel in the context of the SCS testbed.'}),"\n",(0,s.jsxs)(t.p,{children:["Currently, Zitadel is lacking the possibility to easily add custom claims.\nIt supports ",(0,s.jsx)(t.code,{children:"urn:zitadel:iam:user:metadata"}),", but that is more suitable\ntowards Kubernetes and cannot be parsed with the OpenStack mapping mechanism.\n",(0,s.jsx)(t.a,{href:"https://github.com/zitadel/zitadel/issues/3997",children:"There is work going on"})," which\nmay be suitable to resolve this issue.\nAn approach based on Zitadel actions is also currently evaluated.\nOpenStack currently makes use of custom claims to pass ",(0,s.jsx)(t.code,{children:"openstack-default-project"}),"\nfrom the IdP to OpenStack. Combined with federation to external customer managed IdPs\nthis should allow customers to manage settings like these in their own IAM."]}),"\n",(0,s.jsx)(t.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["How would we implement testbed deployment support for Zitadel?","\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["e.g. ",(0,s.jsx)(t.code,{children:"wsgi-keystone.conf"})," would need to look different. One template covering both options?"]}),"\n",(0,s.jsxs)(t.li,{children:["e.g. steps like ",(0,s.jsx)(t.code,{children:"openstack federation protocol create"})," would probably be different."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["Should we support both as options?","\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"What's the benefit?"}),"\n",(0,s.jsx)(t.li,{children:"How would we allow SCS operators to choose?"}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.li,{children:"Do we need some kind of SWOT analysis to come to a decision?"}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsx)(t.p,{children:"SCS wants to make use of an IdP as part of the reference implementation.\nTo move forward with topics of configuration and mapping of roles in a\nOAuth2 federation scenario as well as questions of token lifecycles etc. across\nthe federation stack it makes sense to focus on one IdP implementation at a\ngiven time. Both considered options seem to be potentially viable, but ultimately,\na decision should be made, even if there are no strict/strong reasons for\ndismissing either option in particular."}),"\n",(0,s.jsx)(t.p,{children:"The project's current choice is Keycloak for the following reasons:\nKeycloak currently supports the OAuth 2.0 grants that SCS wants to make\nuse of (e.g. Device Authorization Grant). It is the implementation for\nwhich integration is currently documented in OpenStack and implemented\nin kolla-ansible. SCS currently deploys Keycloak and the IAM team has\nmost hands-on experience with it, e.g. when it comes to collateral questions\nlike how to make TLS and signing certificates available to the IdP that shall\nbe used in federation to external domains."}),"\n",(0,s.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Drafts/IAM-federation",children:"https://github.com/SovereignCloudStack/standards/tree/main/Drafts/IAM-federation"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsx)(t.h2,{id:"conformance-tests-optional",children:"Conformance Tests, OPTIONAL"})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var i=n(96540);const s={},o=i.createContext(s);function a(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f699bead.9990054f.js b/assets/js/f699bead.9990054f.js new file mode 100644 index 0000000000..8e1bcd42f8 --- /dev/null +++ b/assets/js/f699bead.9990054f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1193],{60027:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>i});const n=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/concept","title":"Understanding the concept of Cluster Stacks","description":"The Cluster Stack framework was developed as one of the building blocks of an open-source Kubernetes-as-a-Service. The goal was to make it easier and more user-friendly to manage Kubernetes and Cluster API.","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/concept.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/concept","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/concept.md","tags":[],"version":"current","frontMatter":{}}');var o=s(74848),r=s(28453);const a={},c="Understanding the concept of Cluster Stacks",l={},i=[{value:"Cluster Stacks and Cluster API",id:"cluster-stacks-and-cluster-api",level:2},{value:"Why cluster stacks?",id:"why-cluster-stacks",level:2},{value:"What do cluster stacks NOT try to do?",id:"what-do-cluster-stacks-not-try-to-do",level:2},{value:"Integrating cluster stacks with other tools",id:"integrating-cluster-stacks-with-other-tools",level:2}];function u(e){const t={h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"understanding-the-concept-of-cluster-stacks",children:"Understanding the concept of Cluster Stacks"})}),"\n",(0,o.jsx)(t.p,{children:"The Cluster Stack framework was developed as one of the building blocks of an open-source Kubernetes-as-a-Service. The goal was to make it easier and more user-friendly to manage Kubernetes and Cluster API."}),"\n",(0,o.jsx)(t.h2,{id:"cluster-stacks-and-cluster-api",children:"Cluster Stacks and Cluster API"}),"\n",(0,o.jsx)(t.p,{children:"Do Cluster Stacks replace Cluster API? No! Do Cluster Stacks use Cluster API internally? No! The Cluster Stack framework accompanies Cluster API, but is on the same level of the hierarchy. The Cluster Stack approach does not wrap Cluster API into something else, but adds a few tools next to it. The Cluster Stacks are meant to take over some tasks that are relevant to the user, but for which Cluster API has no opinion."}),"\n",(0,o.jsx)(t.p,{children:"As a user of Cluster Stacks, you will see that you have an opinionated way of using Cluster API, for example by enforcing the use of ClusterClasses, but in the end, it is still vanilla Cluster API. However, instead of, for example, having to manage core cluster components, the so-called cluster addons, yourself, the cluster-stack-operator takes care of this."}),"\n",(0,o.jsx)(t.p,{children:"By installing the required CRDs as well as the cluster-stack-operator next to the Cluster API CRDs and operators into the Cluster API management cluster, you can start using the Cluster Stacks!"}),"\n",(0,o.jsx)(t.p,{children:"To sum up: everything you know about Cluster API still applies when using the Cluster Stack Framework!"}),"\n",(0,o.jsx)(t.h2,{id:"why-cluster-stacks",children:"Why cluster stacks?"}),"\n",(0,o.jsx)(t.p,{children:"Cluster stacks solve multiple issues users face when using Cluster API. Here a selection of them:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Cluster API assumes that node images are available. This might mean some manual work for the user, which is completely out of scope for Cluster API."}),"\n",(0,o.jsx)(t.li,{children:'Cluster API does not have a stable solution to manage core cluster components that every workload cluster needs (cloud controller manager, container network interface, etc.). There is some work around so-called "add-on providers", but this is a very recent development.'}),"\n",(0,o.jsx)(t.li,{children:"Upgrading clusters is challenging, as there might be incompatibilites between the various components (configurations, applications, etc.). Many users don't regularly upgrade clusters because of that."}),"\n",(0,o.jsx)(t.li,{children:"Cluster API has some downsides with regards to user experience, as there are many different objects that a user has to apply and manage."}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"The cluster stack approach tries to solve all of the above issues and tries to connect everything that users need in order to manage a fleet of Kubernetes clusters efficiently and easily."}),"\n",(0,o.jsx)(t.p,{children:"At the same time, it acknowledges the ease of Cluster API and uses it as its core component. Instead of re-inventing the wheel, Cluster API is extended with relevant and meaningful additions that improve the user experience."}),"\n",(0,o.jsx)(t.h2,{id:"what-do-cluster-stacks-not-try-to-do",children:"What do cluster stacks NOT try to do?"}),"\n",(0,o.jsx)(t.p,{children:"Cluster stacks concentrate on providing users with all necessary Cluster API objects in the management cluster, on providing node images (according to the demands of the respective provider), as well as core components of the workload clusters. The cluster stacks aim to provide a way of testing and versioning full templates of clusters."}),"\n",(0,o.jsx)(t.p,{children:"However, they also aim to fulfill their purpose in a similar way of Cluster API by concentrating on one very important part and do that very well."}),"\n",(0,o.jsx)(t.p,{children:"If there are any other use cases, e.g. installing applications automatically in workload clusters (an observability stack, GitOps tools, etc.), then this is a use case that is outside of the cluster stacks functionality."}),"\n",(0,o.jsx)(t.p,{children:"They are not intended to incorporate all features that users might want, but they can easily go hand-in-hand with other tools that enhance Cluster API."}),"\n",(0,o.jsx)(t.h2,{id:"integrating-cluster-stacks-with-other-tools",children:"Integrating cluster stacks with other tools"}),"\n",(0,o.jsx)(t.p,{children:"The Cluster API cosmos is large and there are many tools around that can prove useful. Cluster stacks should be compatible with most of the other tools that you might want to use or build, as long as they follow the same pattern of using the declaritive approach of having custom resources that are reconciled by operators."}),"\n",(0,o.jsx)(t.p,{children:"The cluster stacks can be used via custom resources and an operator reconciling them. Custom resources allow users to extend the Kubernetes API according to their needs."}),"\n",(0,o.jsx)(t.p,{children:"If you want to add your own functionality, you can also define your CRDs and write operators to reconcile them. If you think that your idea is very generic and might be interesting for the community in general, then reach out to the SCS team. Together, we will be able to improve the user experience even further!"})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>c});var n=s(96540);const o={},r=n.createContext(o);function a(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f6ed81c9.f623c022.js b/assets/js/f6ed81c9.f623c022.js new file mode 100644 index 0000000000..af50657157 --- /dev/null +++ b/assets/js/f6ed81c9.f623c022.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[19653],{85297:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Status Page","slug":"/category/status-page","permalink":"/docs/category/status-page","sidebar":"docs","navigation":{"previous":{"title":"Components","permalink":"/docs/category/components-2"},"next":{"title":"Concepts","permalink":"/docs/category/concepts"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/f81c1134.412030c3.js b/assets/js/f81c1134.412030c3.js new file mode 100644 index 0000000000..3ff7a78f9d --- /dev/null +++ b/assets/js/f81c1134.412030c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[48130],{77735:t=>{t.exports=JSON.parse('{"archive":{"blogPosts":[{"id":"first-blog-post","metadata":{"permalink":"/blog/first-blog-post","editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/blog/2022-10-28-first-blog-post.md","source":"@site/blog/2022-10-28-first-blog-post.md","title":"First Blog Post","description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet","date":"2022-10-28T00:00:00.000Z","tags":[{"inline":true,"label":"community","permalink":"/blog/tags/community"},{"inline":true,"label":"howto","permalink":"/blog/tags/howto"}],"readingTime":0.12,"hasTruncateMarker":false,"authors":[{"name":"Eduard Itrich","title":"Community Manager @ SCS","url":"https://github.com/itrich","imageURL":"https://github.com/itrich.png","key":"itrich","page":null}],"frontMatter":{"slug":"first-blog-post","title":"First Blog Post","authors":"itrich","tags":["community","howto"]},"unlisted":false},"content":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}]}}')}}]); \ No newline at end of file diff --git a/assets/js/f8869d03.94ccab66.js b/assets/js/f8869d03.94ccab66.js new file mode 100644 index 0000000000..580a7da810 --- /dev/null +++ b/assets/js/f8869d03.94ccab66.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[25595],{18829:(s,e,n)=>{n.r(e),n.d(e,{TableCellStyleApplier:()=>h,assets:()=>l,contentTitle:()=>c,default:()=>j,frontMatter:()=>i,metadata:()=>t,toc:()=>o});const t=JSON.parse('{"id":"kaas/index","title":"KaaS Standards","description":"Standards in this track are concerned with Kubernetes as a Service layer, outlining norms and best practices for deploying, managing, and operating Kubernetes clusters. These standards aim to ensure that the orchestration of containers is streamlined, secure, and compatible across various cloud environments and platforms.","source":"@site/standards/kaas/index.md","sourceDirName":"kaas","slug":"/kaas/","permalink":"/standards/kaas/","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"V1","permalink":"/standards/scs-0125-v1-secure-connections"},"next":{"title":"scs-0200: Using Sonobuoy for KaaS conformance tests","permalink":"/standards/kaas/scs-0200"}}');var r=n(74848),d=n(28453),a=n(96540);const i={},c="KaaS Standards",l={},h=()=>{const s={3:"#FBFDE2",4:"#E2EAFD",5:"#FDE2E2"},e={2:"#FBFDE2",3:"#E2EAFD",4:"#FDE2E2"};return(0,a.useEffect)((()=>{const n=(s,e)=>{const n=document.querySelector("#"+s);if(n){const s=n.nextElementSibling;s&&"table"===s.tagName.toLowerCase()&&s.querySelectorAll("tbody tr").forEach((s=>{s.querySelectorAll("td").forEach(((s,n)=>{e[n]&&"-"!==s.textContent.trim()&&(s.style.backgroundColor=e[n])}))}))}};n("color-table-cells-overview",s),n("color-table-cells-track-overview",e)}),[]),null},o=[];function x(s){const e={a:"a",h1:"h1",header:"header",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...s.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"kaas-standards",children:"KaaS Standards"})}),"\n",(0,r.jsx)(e.p,{children:"Standards in this track are concerned with Kubernetes as a Service layer, outlining norms and best practices for deploying, managing, and operating Kubernetes clusters. These standards aim to ensure that the orchestration of containers is streamlined, secure, and compatible across various cloud environments and platforms."}),"\n",(0,r.jsx)("p",{children:"*Legend to the column headings and entries:"}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsx)(e.li,{children:"Document states: Draft, Effective, Deprecated (and no longer effective)"}),"\n",(0,r.jsx)(e.li,{children:"Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future"}),"\n",(0,r.jsx)(e.li,{children:"Entries in the effective column marked with a \u2020 will turn deprecated in the near future"}),"\n"]}),"\n","\n","\n",(0,r.jsx)(h,{}),"\n",(0,r.jsx)("div",{id:"color-table-cells-track-overview"}),"\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Standard"}),(0,r.jsx)(e.th,{children:"Description"}),(0,r.jsx)(e.th,{children:"Draft"}),(0,r.jsx)(e.th,{children:"Effective"}),(0,r.jsx)(e.th,{children:"Deprecated*"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/kaas/scs-0200",children:"scs-0200"})}),(0,r.jsx)(e.td,{children:"Using Sonobuoy for KaaS conformance tests"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/kaas/scs-0210",children:"scs-0210"})}),(0,r.jsx)(e.td,{children:"SCS K8S Version Policy"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0210-v2-k8s-version-policy",children:"v2"})}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0210-v1-k8s-new-version-policy",children:"v1"})})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{children:"Supplement: Implementation and Testing Notes"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0210-w1-k8s-version-policy-implementation-testing",children:"w1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/kaas/scs-0211",children:"scs-0211"})}),(0,r.jsx)(e.td,{children:"SCS KaaS default storage class"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0211-v2-kaas-default-storage-class",children:"v2"})}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0211-v1-kaas-default-storage-class",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{children:"Supplement: Implementation and Testing Notes"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing",children:"w1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/kaas/scs-0212",children:"scs-0212"})}),(0,r.jsx)(e.td,{children:"Requirements for container registries"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0212-v1-requirements-for-container-registries",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/kaas/scs-0213",children:"scs-0213"})}),(0,r.jsx)(e.td,{children:"Kubernetes Nodes Anti Affinity"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0213-v1-k8s-nodes-anti-affinity",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/kaas/scs-0214",children:"scs-0214"})}),(0,r.jsx)(e.td,{children:"Kubernetes Node Distribution and Availability"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsxs)(e.td,{children:[(0,r.jsx)(e.a,{href:"/standards/scs-0214-v1-k8s-node-distribution",children:"v1"}),", ",(0,r.jsx)(e.a,{href:"/standards/scs-0214-v2-k8s-node-distribution",children:"v2"})]}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{children:"Supplement: Implementation and Testing Notes"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing",children:"w1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/kaas/scs-0215",children:"scs-0215"})}),(0,r.jsx)(e.td,{children:"Robustness features for Kubernetes clusters"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0215-v1-robustness-features",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/kaas/scs-0216",children:"scs-0216"})}),(0,r.jsx)(e.td,{children:"Requirements for testing cluster-stacks"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/kaas/scs-0217",children:"scs-0217"})}),(0,r.jsx)(e.td,{children:"Kubernetes cluster hardening"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0217-v1-cluster-hardening",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/kaas/scs-0218",children:"scs-0218"})}),(0,r.jsx)(e.td,{children:"Container registry for SCS standard implementation"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/kaas/scs-0219",children:"scs-0219"})}),(0,r.jsx)(e.td,{children:"KaaS Networking Standard"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0219-v1-kaas-networking",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{children:"Supplement: Implementation Notes"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0219-w1-kaas-networking",children:"w1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]})]})]})]})}function j(s={}){const{wrapper:e}={...(0,d.R)(),...s.components};return e?(0,r.jsx)(e,{...s,children:(0,r.jsx)(x,{...s})}):x(s)}},28453:(s,e,n)=>{n.d(e,{R:()=>a,x:()=>i});var t=n(96540);const r={},d=t.createContext(r);function a(s){const e=t.useContext(d);return t.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function i(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(r):s.components||r:a(s.components),t.createElement(d.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/f9ec068e.68698bfe.js b/assets/js/f9ec068e.68698bfe.js new file mode 100644 index 0000000000..f638010483 --- /dev/null +++ b/assets/js/f9ec068e.68698bfe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[751],{72759:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>c,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>i});const s=JSON.parse('{"id":"global/scs-0001","title":"scs-0001: Sovereign Cloud Standards","description":"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision","source":"@site/standards/global/scs-0001.md","sourceDirName":"global","slug":"/global/scs-0001","permalink":"/standards/global/scs-0001","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"Global Standards","permalink":"/standards/global/"},"next":{"title":"V1","permalink":"/standards/scs-0001-v1-sovereign-cloud-standards"}}');var r=n(74848),d=n(28453);const a={},c="scs-0001: Sovereign Cloud Standards",o={},i=[];function l(e){const t={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"scs-0001-sovereign-cloud-standards",children:"scs-0001: Sovereign Cloud Standards"})}),"\n",(0,r.jsx)(t.p,{children:"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision\nrecords within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in\nthe development and maintenance of interoperable and transparent cloud infrastructure standards."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0001-v1-sovereign-cloud-standards",children:"scs-0001-v1"})}),(0,r.jsx)(t.td,{children:"Procedural"}),(0,r.jsx)(t.td,{children:"Stable"}),(0,r.jsx)(t.td,{children:"2022-11-28"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function u(e={}){const{wrapper:t}={...(0,d.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>c});var s=n(96540);const r={},d=s.createContext(r);function a(e){const t=s.useContext(d);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(d.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f9fdfcc0.67bf78fc.js b/assets/js/f9fdfcc0.67bf78fc.js new file mode 100644 index 0000000000..4f089e7be7 --- /dev/null +++ b/assets/js/f9fdfcc0.67bf78fc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[35210],{39596:(t,e,o)=>{o.r(e),o.d(e,{assets:()=>i,contentTitle:()=>a,default:()=>l,frontMatter:()=>c,metadata:()=>n,toc:()=>p});const n=JSON.parse('{"id":"container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration","title":"provider-integration","description":"","source":"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration.md","sourceDirName":"03-container/components/cluster-stacks/components/cluster-stack-operator/develop","slug":"/container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration.md","tags":[],"version":"current","frontMatter":{}}');var r=o(74848),s=o(28453);const c={},a=void 0,i={},p=[];function u(t){return(0,r.jsx)(r.Fragment,{})}function l(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(u,{...t})}):u()}},28453:(t,e,o)=>{o.d(e,{R:()=>c,x:()=>a});var n=o(96540);const r={},s=n.createContext(r);function c(t){const e=n.useContext(s);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:c(t.components),n.createElement(s.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/fa7c4c29.ba18c231.js b/assets/js/fa7c4c29.ba18c231.js new file mode 100644 index 0000000000..cb9e6da62c --- /dev/null +++ b/assets/js/fa7c4c29.ba18c231.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[35122],{1869:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"iaas/guides/upgrade-guide/network","title":"Network","description":"1. Open vSwitch (OVS)","source":"@site/docs/02-iaas/guides/upgrade-guide/network.md","sourceDirName":"02-iaas/guides/upgrade-guide","slug":"/iaas/guides/upgrade-guide/network","permalink":"/docs/iaas/guides/upgrade-guide/network","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/network.md","tags":[],"version":"current","sidebarPosition":15,"frontMatter":{"sidebar_label":"Network","sidebar_position":15},"sidebar":"docs","previous":{"title":"Manager","permalink":"/docs/iaas/guides/upgrade-guide/manager"},"next":{"title":"Ceph","permalink":"/docs/iaas/guides/upgrade-guide/ceph"}}');var s=t(74848),i=t(28453);const o={sidebar_label:"Network",sidebar_position:15},a="Network",d={},c=[];function l(e){const n={code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"network",children:"Network"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Open vSwitch (OVS)"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply -a pull openvswitch\nosism apply -a upgrade openvswitch\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Open Virtual Network (OVN)"}),"\n",(0,s.jsxs)(n.p,{children:["In ",(0,s.jsx)(n.code,{children:"environments/kolla/configuration.yml"})," the parameter ",(0,s.jsx)(n.code,{children:"neutron_plugin_agent"})," is set to\n",(0,s.jsx)(n.code,{children:"ovn"}),". The parameter is set to ",(0,s.jsx)(n.code,{children:"ovn"})," by default in the Cookiecutter and is the OSISM default."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'# neutron\nneutron_plugin_agent: "ovn"\n'})}),"\n",(0,s.jsx)(n.p,{children:"Before the upgrade of OVN, the upgrade of Open vSwitch must already have been done."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply -a pull ovn\nosism apply -a upgrade ovn\n"})}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var r=t(96540);const s={},i=r.createContext(s);function o(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fbd7a1e9.e85339ad.js b/assets/js/fbd7a1e9.e85339ad.js new file mode 100644 index 0000000000..f58383efb9 --- /dev/null +++ b/assets/js/fbd7a1e9.e85339ad.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9416],{47711:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>n,toc:()=>u});const n=JSON.parse('{"id":"operating-scs/components/status-page-web/docs/requirements","title":"Requirements","description":"Compiling the status page frontend requires Angular 17+.","source":"@site/docs/04-operating-scs/components/status-page-web/docs/requirements.md","sourceDirName":"04-operating-scs/components/status-page-web/docs","slug":"/operating-scs/components/status-page-web/docs/requirements","permalink":"/docs/operating-scs/components/status-page-web/docs/requirements","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-web/docs/requirements.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/operating-scs/components/status-page-web/docs/overview"},"next":{"title":"Quickstart","permalink":"/docs/operating-scs/components/status-page-web/docs/quickstart"}}');var o=s(74848),r=s(28453);const c={},a="Requirements",i={},u=[];function p(e){const t={h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"requirements",children:"Requirements"})}),"\n",(0,o.jsx)(t.p,{children:"Compiling the status page frontend requires Angular 17+."})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>a});var n=s(96540);const o={},r=n.createContext(o);function c(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fc07b5ea.41f626b2.js b/assets/js/fc07b5ea.41f626b2.js new file mode 100644 index 0000000000..44c33bd6c5 --- /dev/null +++ b/assets/js/fc07b5ea.41f626b2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[33760],{13846:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>r});const s=JSON.parse('{"id":"certification/pipeline","title":"SCS Compliance Check Pipeline Manual","description":"The SCS compliance check suite runs automated tests, generates a signed report for the run, and feeds it to","source":"@site/standards/certification/pipeline.md","sourceDirName":"certification","slug":"/certification/pipeline","permalink":"/standards/certification/pipeline","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"standards","previous":{"title":"SCS-compatible KaaS","permalink":"/standards/scs-compatible-kaas"},"next":{"title":"Overview","permalink":"/standards/standards/overview"}}');var i=t(74848),o=t(28453);const a={},c="SCS Compliance Check Pipeline Manual",l={},r=[{value:"Common requirements for the compliance checks",id:"common-requirements-for-the-compliance-checks",level:2},{value:"for SCS-compatible IaaS",id:"for-scs-compatible-iaas",level:3},{value:"How to add a new test subject to the official pipeline",id:"how-to-add-a-new-test-subject-to-the-official-pipeline",level:2},{value:"for SCS-compatible IaaS",id:"for-scs-compatible-iaas-1",level:3},{value:"How to feed the compliance monitor yourself",id:"how-to-feed-the-compliance-monitor-yourself",level:2},{value:"for SCS-compatible IaaS",id:"for-scs-compatible-iaas-2",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"scs-compliance-check-pipeline-manual",children:"SCS Compliance Check Pipeline Manual"})}),"\n",(0,i.jsx)(n.p,{children:'The SCS compliance check suite runs automated tests, generates a signed report for the run, and feeds it to\nthe compliance monitor. Roughly speaking, this process has to be performed daily, for instance, using a\ncontinuous-integration "pipeline".'}),"\n",(0,i.jsx)(n.p,{children:"Providers of public clouds do not need to use their own pipelines; those clouds can be tested via the\nofficial SCS compliance check pipeline."}),"\n",(0,i.jsx)(n.p,{children:"Alternatively, if using this pipeline is not feasible (for instance, for private clouds) or not desired,\ncloud-service providers can run the tests and feed the compliance monitor themselves."}),"\n",(0,i.jsx)(n.p,{children:"The next subsection shows common requirements for each of these two cases. The two subsections after that\nare each dedicated to the specific cases."}),"\n",(0,i.jsx)(n.h2,{id:"common-requirements-for-the-compliance-checks",children:"Common requirements for the compliance checks"}),"\n",(0,i.jsx)(n.h3,{id:"for-scs-compatible-iaas",children:"for SCS-compatible IaaS"}),"\n",(0,i.jsxs)(n.p,{children:["You need an OpenStack project that allows for at least one server and one router, possibly more if it's going\nto be used for purposes other than compliance testing (such as the\n",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor",children:"OpenStack Health Monitor"})," or the\n",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor",children:"SCS Health Monitor"}),")."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Create an application credential. It must be possible to create resources such as servers, routers, etc."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Create a new branch in ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards",children:"the standards repository"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"git clone git@github.com:SovereignCloudStack/standards.git"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"cd standards"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"git checkout -b feat/add_my_cloud"})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"CAUTION"}),": If you are not a member of the SCS Github org, this won't work.\nAsk the SCS team (or other members) to add you. Alternatively, you may fork the repository on\nGithub first and then clone the fork."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add your subject to the results table. This is necessary so your subject shows up in the\n",(0,i.jsx)(n.a,{href:"https://compliance.sovereignit.cloud/page/table",children:"compliance monitor web-site"}),". Add the following lines\n(substituting all-caps parts except ",(0,i.jsx)(n.code,{children:"HM"}),"):"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-diff",children:" | [gx-scs](https://github.com/SovereignCloudStack/docs/blob/main/community/cloud-resources/plusserver-gx-scs.md) | Dev environment provided for SCS & GAIA-X context | plusserver GmbH |\n {#- #} [{{ results | pick('gx-scs', iaas) | summary }}]({{ detail_url('gx-scs', iaas) }}) {# -#}\n | [HM](https://health.gx-scs.sovereignit.cloud:3000/) |\n+| [SUBJECT_NAME](YOUR_URL) | DESCRIPTION | COMPANY_NAME |\n+{#- #} [{{ results | pick('SUBJECT_NAME', iaas) | summary }}]({{ detail_url('SUBJECT_NAME', iaas) }}) {# -#}\n+| [HM](HEALTH_MONITOR_URL) |\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Ideally, insert the lines at a position that keeps the part of the table below ",(0,i.jsx)(n.code,{children:"gx-scs"})," sorted."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Now you can proceed with the steps from one of the next subsections, depending on whether you want to\ncheck suite run by the SCS pipeline or not."}),"\n",(0,i.jsx)(n.h2,{id:"how-to-add-a-new-test-subject-to-the-official-pipeline",children:"How to add a new test subject to the official pipeline"}),"\n",(0,i.jsx)(n.h3,{id:"for-scs-compatible-iaas-1",children:"for SCS-compatible IaaS"}),"\n",(0,i.jsxs)(n.p,{children:["We are going to create a pull request that is very similar to real-life example that\n",(0,i.jsxs)(n.a,{href:"https://github.com/SovereignCloudStack/standards/pull/797",children:["adds the test subject ",(0,i.jsx)(n.code,{children:"scaleup-occ2"})]}),".\n(However, note that this example also adds an optional GitHub workflow, which we won't do here.)"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Modify ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/playbooks/clouds.yaml.j2",children:"playbooks/clouds.yaml.j2"}),".\nThis is necessary so that the tests can access your cloud.\nYou can use the following template (replace all-caps parts):"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:' SUBJECT_NAME:\n region_name: REGION\n interface: "public"\n identity_api_version: 3\n auth_type: "v3applicationcredential"\n auth:\n auth_url: AUTH_URL\n application_credential_id: "{{ clouds_conf.SUBJECT_NAME_ac_id }}"\n application_credential_secret: "{{ clouds_conf.SUBJECT_NAME_a_ac_secret }}"\n'})}),"\n",(0,i.jsx)(n.p,{children:"Note that you need to replace dashes (and other special characters) by underscores in the last two lines."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add your subject to ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/config.toml",children:"Tests/config.toml"}),".\nThis is necessary so that your cloud will be included in the nightly tests. Add a line like so:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-diff",children:' [presets.all]\n scopes = [\n "scs-compatible-iaas",\n ]\n subjects = [\n "gx-scs",\n+ "SUBJECT_NAME",\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Ideally, insert your subject so that the list (after ",(0,i.jsx)(n.code,{children:"gx-scs"}),") remains sorted."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add your subject to ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/compliance-monitor/bootstrap.yaml",children:"compliance-monitor/bootstrap.yaml"}),".\nThis is necessary to that the reports will be accepted as genuine. Add a section like so:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-diff",children:" - subject: artcodix\n delegates:\n - zuul_ci\n+ - subject: SUBJECT_NAME\n+ delegates:\n+ - zuul_ci\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Again, insert your subject so that the list (after ",(0,i.jsx)(n.code,{children:"gx-scs"}),") remains sorted."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Finally, add secrets to ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/.zuul.d/secure.yaml",children:".zuul.d/secure.yaml"}),".\nThis is necessary so the tests can access your cloud."]}),"\n",(0,i.jsx)(n.p,{children:"This step is the most involved, and you can always have us do it for you; in that case, please send us\nthe application credential id and secret via an encrypted channel, e.g. Matrix."}),"\n",(0,i.jsxs)(n.p,{children:["To proceed, you need ",(0,i.jsx)(n.code,{children:"zuul-client"})," installed:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"pipx install zuul-client\n"})}),"\n",(0,i.jsx)(n.p,{children:"Then you can execute:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"$ zuul-client --zuul-url https://zuul.sovereignit.cloud/ encrypt --tenant scs --project SovereignCloudStack/standards\n<PASTE application credential id HERE>\n<HIT ctrl-d>\n\n...\n - secret:\n name: <name>\n data:\n <fieldname>: !encrypted/pkcs1-oaep\n - ...\n\n$ zuul-client --zuul-url https://zuul.sovereignit.cloud/ encrypt --tenant scs --project SovereignCloudStack/standards\n<PASTE application credential secret HERE>\n<HIT ctrl-d>\n\n...\n - secret:\n name: <name>\n data:\n <fieldname>: !encrypted/pkcs1-oaep\n - ...\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Copy the parts of the respective outputs starting in the final line shown here (the one starting ",(0,i.jsx)(n.code,{children:"-"}),").\nInsert them like so:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-diff",children:"+ SUBJECT_NAME_ac_id: !encrypted/pkcs1-oaep\n+ - ENCRYPTED_ID\n+ SUBJECT_NAME_ac_secret: !encrypted/pkcs1-oaep\n+ - ENCRYPTED_SECRET\n"})}),"\n",(0,i.jsx)(n.p,{children:"Note that you have to use the same keys as in Step 1 (that is, with special characters replaced)."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Commit your changes and open a pull request:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:'git commit -asm "Add SUBJECT_NAME"\ngit push # the output of this command will show you the URL for creating the pull request\n'})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"how-to-feed-the-compliance-monitor-yourself",children:"How to feed the compliance monitor yourself"}),"\n",(0,i.jsx)(n.h3,{id:"for-scs-compatible-iaas-2",children:"for SCS-compatible IaaS"}),"\n",(0,i.jsx)(n.p,{children:"Note: you may have to adapt these instructions to your infrastructure. For instance, the secrets\nwe create here are stored locally. If you want to include the check suite into your own\ncontinuous-integration pipeline, you may want to use some dedicated credential store and mechanism for\ninjecting secrets."}),"\n",(0,i.jsxs)(n.p,{children:["You may want to take inspiration from our own Zuul setup by looking at\n",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/.zuul.d",children:".zuul.d"})," and\n",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/playbooks",children:"playbooks"}),".\nHowever, don't be overwhelmed by the complexities of Zuul; it's well possible to use other solutions,\nincluding a cronjob."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Install requirements."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"virtualenv .venv\n. .venv/bin/activate\npip install -r requirements.txt\npip install passlib argon2_cffi # these are only needed for Step 2\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Run our support script (substitute ",(0,i.jsx)(n.code,{children:"$SUBJECT_NAME"})," appropriately):"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"Tests/add_subject.py $SUBJECT_NAME\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Follow the instructions.\nAt the end, it will tell you to amend the file ",(0,i.jsx)(n.code,{children:"compliance-monitor/boostrap.py"}),". Do so."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Make sure you have ",(0,i.jsx)(n.code,{children:"$SUBJECT_NAME"})," in your ",(0,i.jsx)(n.code,{children:".config/openstack/clouds.yaml"})," like so:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:' SUBJECT_NAME:\n region_name: REGION\n interface: "public"\n identity_api_version: 3\n auth_type: "v3applicationcredential"\n auth:\n auth_url: AUTH_URL\n application_credential_id: "APPLICATION_CREDENTIAL_ID"\n application_credential_secret: "APPLICATION_CREDENTIAL_SECRET"\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Perform a test run of the check suite like so:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"python3 Tests/scs-test-runner.py --config Tests/config.toml run --scope scs-compatible-iaas --subject $SUBJECT_NAME\n"})}),"\n",(0,i.jsx)(n.p,{children:"If the report can't be submitted at the very end, this is to be expected, because the keyfile is not yet\nknown to the compliance monitor. To change this, we proceed to the next step."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Commit your changes and open a pull request:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:'git commit -asm "Add SUBJECT_NAME"\ngit push # the output of this command will show you the URL for creating the pull request\n'})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>c});var s=t(96540);const i={},o=s.createContext(i);function a(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fc3b013c.c19f5a8a.js b/assets/js/fc3b013c.c19f5a8a.js new file mode 100644 index 0000000000..f6c5ce0d04 --- /dev/null +++ b/assets/js/fc3b013c.c19f5a8a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[46774],{6446:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>a});const s=JSON.parse('{"id":"operating-scs/components/automated-pentesting-kaas/quickstart","title":"Quickstart Guide","description":"This document provides a quick guide to setting up and running the security scanning infrastructure using Trivy and other related tools.","source":"@site/docs/04-operating-scs/components/automated-pentesting-kaas/quickstart.md","sourceDirName":"04-operating-scs/components/automated-pentesting-kaas","slug":"/operating-scs/components/automated-pentesting-kaas/quickstart","permalink":"/docs/operating-scs/components/automated-pentesting-kaas/quickstart","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/automated-pentesting-kaas/quickstart.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/docs/operating-scs/components/automated-pentesting-kaas/overview"},"next":{"title":"Tools Description","permalink":"/docs/operating-scs/components/automated-pentesting-kaas/tools"}}');var t=r(74848),i=r(28453);const o={},l="Quickstart Guide",c={},a=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Project Structure",id:"project-structure",level:2},{value:"Main Files",id:"main-files",level:3},{value:"1. <code>cronjob/configmap.yaml</code>",id:"1-cronjobconfigmapyaml",level:4},{value:"2. <code>cronjob/trivy-cronjob.yaml</code>",id:"2-cronjobtrivy-cronjobyaml",level:4},{value:"3. <code>trivy-operator/trivy_results.json</code>",id:"3-trivy-operatortrivy_resultsjson",level:4},{value:"4. <code>trivy-operator/values.yaml</code>",id:"4-trivy-operatorvaluesyaml",level:4},{value:"5. <code>trivy-reporter/values.yaml</code>",id:"5-trivy-reportervaluesyaml",level:4},{value:"Deployment",id:"deployment",level:2}];function d(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"quickstart-guide",children:"Quickstart Guide"})}),"\n",(0,t.jsx)(n.p,{children:"This document provides a quick guide to setting up and running the security scanning infrastructure using Trivy and other related tools."}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"Before you begin, make sure you have the following prerequisites installed in your environment:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Kubernetes Cluster"}),"\n",(0,t.jsx)(n.li,{children:"Helm 3.x"}),"\n",(0,t.jsx)(n.li,{children:"Credential setup in HashiCorp Vault"}),"\n",(0,t.jsx)(n.li,{children:"Access to OpenStack (for storing results)"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"project-structure",children:"Project Structure"}),"\n",(0,t.jsx)(n.p,{children:"The project structure is organized as follows:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-plaintext",children:".\n\u251c\u2500\u2500 cronjob\n\u2502 \u251c\u2500\u2500 configmap.yaml\n\u2502 \u2514\u2500\u2500 trivy-cronjob.yaml\n\u251c\u2500\u2500 trivy-operator\n\u2502 \u2514\u2500\u2500 values.yaml\n\u2514\u2500\u2500 trivy-reporter\n \u2514\u2500\u2500 values.yaml\n"})}),"\n",(0,t.jsx)(n.h3,{id:"main-files",children:"Main Files"}),"\n",(0,t.jsxs)(n.h4,{id:"1-cronjobconfigmapyaml",children:["1. ",(0,t.jsx)(n.code,{children:"cronjob/configmap.yaml"})]}),"\n",(0,t.jsxs)(n.p,{children:["This file defines a ",(0,t.jsx)(n.code,{children:"ConfigMap"})," that is used to store configurations and scripts necessary for executing the ",(0,t.jsx)(n.code,{children:"CronJob"})," that performs security scans using Trivy."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Primary Use:"})," Store scripts and configurations that will be used by the ",(0,t.jsx)(n.code,{children:"CronJob"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Important:"})," Ensure that the scripts stored in this ",(0,t.jsx)(n.code,{children:"ConfigMap"})," are correctly formatted and configured to run in the Kubernetes environment."]}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"2-cronjobtrivy-cronjobyaml",children:["2. ",(0,t.jsx)(n.code,{children:"cronjob/trivy-cronjob.yaml"})]}),"\n",(0,t.jsxs)(n.p,{children:["This file defines a ",(0,t.jsx)(n.code,{children:"CronJob"})," in Kubernetes that is responsible for periodically running the security scan using Trivy."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Schedule:"})," The ",(0,t.jsx)(n.code,{children:"CronJob"})," is configured to run at specific intervals defined in the file."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Containers:"})," It uses several containers, including ",(0,t.jsx)(n.code,{children:"trivy-reports-getter"})," for fetching the reports and ",(0,t.jsx)(n.code,{children:"trivy-reports-uploader"})," for uploading the results to an external storage like OpenStack."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Configurations:"})," Ensure that all configurations, including volumes and ",(0,t.jsx)(n.code,{children:"initContainers"}),", are correctly set up before deploying this ",(0,t.jsx)(n.code,{children:"CronJob"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"3-trivy-operatortrivy_resultsjson",children:["3. ",(0,t.jsx)(n.code,{children:"trivy-operator/trivy_results.json"})]}),"\n",(0,t.jsx)(n.p,{children:"This file contains an example JSON output generated by Trivy after performing a security scan."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Usage:"})," Used as an example or reference to analyze the results of the scans."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Important:"})," This file can be used to conduct local tests on scripts that process Trivy's scan results."]}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"4-trivy-operatorvaluesyaml",children:["4. ",(0,t.jsx)(n.code,{children:"trivy-operator/values.yaml"})]}),"\n",(0,t.jsxs)(n.p,{children:["This file contains specific configurations for deploying the ",(0,t.jsx)(n.code,{children:"trivy-operator"})," using Helm."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Configuration:"})," Defines the values to customize the deployment of the Trivy operator in the Kubernetes cluster."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Note:"})," Ensure to customize this file according to your environment's needs before deploying."]}),"\n"]}),"\n",(0,t.jsxs)(n.h4,{id:"5-trivy-reportervaluesyaml",children:["5. ",(0,t.jsx)(n.code,{children:"trivy-reporter/values.yaml"})]}),"\n",(0,t.jsxs)(n.p,{children:["This file contains specific configurations for the ",(0,t.jsx)(n.code,{children:"trivy-reporter"})," tool."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Purpose:"})," Used to configure how reports should be generated and processed after Trivy performs a scan."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Configuration:"})," Customize this file according to the environment and the report you wish to generate."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"deployment",children:"Deployment"}),"\n",(0,t.jsx)(n.p,{children:"To deploy the security scanning infrastructure, follow the steps below:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Configure ConfigMaps and Secrets:"}),"\nEnsure all necessary ",(0,t.jsx)(n.code,{children:"ConfigMaps"})," and ",(0,t.jsx)(n.code,{children:"Secrets"})," are properly created in your Kubernetes cluster."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:" kubectl apply -f cronjob/configmap.yaml\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Deploy the CronJob:"}),"\nDeploy the ",(0,t.jsx)(n.code,{children:"CronJob"})," that will run the periodic scans."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:" kubectl apply -f cronjob/trivy-cronjob.yaml\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Deploy Trivy Operator:"}),"\nUse Helm to deploy the ",(0,t.jsx)(n.code,{children:"trivy-operator"})," in your cluster."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:" helm install trivy-operator trivy-operator/ -f trivy-operator/values.yaml\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Deploy Trivy Reporter:"}),"\nUse Helm to deploy the ",(0,t.jsx)(n.code,{children:"trivy-reporter"})," in your cluster."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:" helm repo add trivy-dojo-report-operator https://telekom-mms.github.io/trivy-dojo-report-operator/\n helm repo update\n helm install chart-name trivy-dojo-report-operator/trivy-dojo-report-operator --values trivy-reporter/values.yaml\n"})}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>l});var s=r(96540);const t={},i=s.createContext(t);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fc83dba0.9b03d070.js b/assets/js/fc83dba0.9b03d070.js new file mode 100644 index 0000000000..2d701d8e33 --- /dev/null +++ b/assets/js/fc83dba0.9b03d070.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7628],{2357:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"operating-scs/components/status-page-deployment/docs/kind","title":"kind - Local development environment","description":"kind is a tool to quickly setup a local development environment, to test and debug the deployment.","source":"@site/docs/04-operating-scs/components/status-page-deployment/docs/kind.md","sourceDirName":"04-operating-scs/components/status-page-deployment/docs","slug":"/operating-scs/components/status-page-deployment/docs/kind","permalink":"/docs/operating-scs/components/status-page-deployment/docs/kind","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page-deployment/docs/kind.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Configure status page","permalink":"/docs/operating-scs/components/status-page-deployment/docs/configuration"},"next":{"title":"k3s - A simple deployment on a single host","permalink":"/docs/operating-scs/components/status-page-deployment/docs/k3s"}}');var o=s(74848),i=s(28453);const r={},l="kind - Local development environment",d={},c=[{value:""Secrets"",id:"secrets",level:2},{value:"Per Installation Steps",id:"per-installation--steps",level:2},{value:"Setup",id:"setup",level:2},{value:"Deploy",id:"deploy",level:2},{value:"Port forward",id:"port-forward",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsxs)(n.h1,{id:"kind---local-development-environment",children:[(0,o.jsx)(n.code,{children:"kind"})," - Local development environment"]})}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"kind"})," is a tool to quickly setup a local development environment, to test and debug the deployment."]}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"NOTE"}),": ",(0,o.jsx)(n.code,{children:"kind"})," is not considered to be used as any kind of productive deployment."]}),"\n",(0,o.jsx)(n.h2,{id:"secrets",children:'"Secrets"'}),"\n",(0,o.jsxs)(n.p,{children:['All "secrets" shared in ',(0,o.jsx)(n.code,{children:"kubernetes/environments/kind"})," are example values to get a local environment up and running. These values should be substituted by real and secure secrets."]}),"\n",(0,o.jsx)(n.h2,{id:"per-installation--steps",children:"Per Installation Steps"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Install ",(0,o.jsx)(n.code,{children:"kind"})," from the ",(0,o.jsx)(n.a,{href:"https://kind.sigs.k8s.io/",children:"official website"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Clone the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/status-page-deployment",children:"status-page-deployment"})," repository","\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"git clone git@github.com:SovereignCloudStack/status-page-deployment.git\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["Create a ",(0,o.jsx)(n.a,{href:"https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app",children:"Github OAuth app"})," for testing, see example data:\n(Note: It is ",(0,o.jsx)(n.strong,{children:"not critical"})," to share the data listed here, as this is only a test application which is reachable from localhost)","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Name: SCS Gatekeeper Test DEV"}),"\n",(0,o.jsxs)(n.li,{children:["Homepage URL: ",(0,o.jsx)(n.a,{href:"https://scs.community/",children:"https://scs.community/"})]}),"\n",(0,o.jsxs)(n.li,{children:["Authorization callback URL: ",(0,o.jsx)(n.a,{href:"http://localhost:8080/",children:"http://localhost:8080/"})]}),"\n",(0,o.jsxs)(n.li,{children:["Client ID: ",(0,o.jsx)(n.code,{children:"<generated>"})]}),"\n",(0,o.jsxs)(n.li,{children:["Client Secret: ",(0,o.jsx)(n.code,{children:"<generated>"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"setup",children:"Setup"}),"\n",(0,o.jsxs)(n.p,{children:["Create a local ",(0,o.jsx)(n.code,{children:"kind"})," cluster with:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"make cluster\n"})}),"\n",(0,o.jsx)(n.h2,{id:"deploy",children:"Deploy"}),"\n",(0,o.jsxs)(n.p,{children:["All needed configurations and secrets, except Dex's GitHub app secrets, are set up in a ready to use kustomization: ",(0,o.jsx)(n.code,{children:"kubernetes/environments/kind/kustomization.yaml"}),", just assemble and deploy:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Create Github application"}),"\n",(0,o.jsxs)(n.li,{children:["Create and configure OAUTH config files","\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"cp kubernetes/environments/kind/dex/dex-secrets-example.env kubernetes/environments/kind/dex/secrets.env\nvim kubernetes/environments/kind/dex/dex.env # configure GITHUB_CLIENT_ID\nvim kubernetes/environments/kind/dex/secrets.env # configure GITHUB_CLIENT_SECRET\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["Deploy Application","\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"make deploy\n"})}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["For further configuration see ",(0,o.jsx)(n.a,{href:"/docs/operating-scs/components/status-page-deployment/docs/configuration",children:(0,o.jsx)(n.code,{children:"configuration.md"})}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"port-forward",children:"Port forward"}),"\n",(0,o.jsxs)(n.p,{children:["The local ",(0,o.jsx)(n.code,{children:"kind"})," deployment uses ",(0,o.jsx)(n.a,{href:"https://caddyserver.com/",children:"Caddy"})," as reverse proxy, instead of ",(0,o.jsx)(n.code,{children:"Ingress"})," and ",(0,o.jsx)(n.code,{children:"IngressController"}),"s, to the cluster services.\nPort forward to the reverse proxy to start using the deployment locally."]}),"\n",(0,o.jsx)(n.p,{children:"For example:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"make forward\n"})})]})}function p(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fd34a958.eb4a43e0.js b/assets/js/fd34a958.eb4a43e0.js new file mode 100644 index 0000000000..69f9623385 --- /dev/null +++ b/assets/js/fd34a958.eb4a43e0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[39049],{29751:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"scs-0402-v1-status-page-openapi-spec-decision","title":"Status page OpenAPI decision","description":"Introduction","source":"@site/standards/scs-0402-v1-status-page-openapi-spec-decision.md","sourceDirName":".","slug":"/scs-0402-v1-status-page-openapi-spec-decision","permalink":"/standards/scs-0402-v1-status-page-openapi-spec-decision","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Status page OpenAPI decision","type":"Decision Record","status":"Draft","track":"Ops"},"sidebar":"standards","previous":{"title":"scs-0402: Status page OpenAPI decision","permalink":"/standards/ops/scs-0402"},"next":{"title":"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer","permalink":"/standards/ops/scs-0403"}}');var s=i(74848),a=i(28453);const r={title:"Status page OpenAPI decision",type:"Decision Record",status:"Draft",track:"Ops"},o=void 0,d={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Requirements",id:"requirements",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Decision",id:"decision",level:2},{value:"Common definitions",id:"common-definitions",level:3},{value:"Id",id:"id",level:4},{value:"Incremental",id:"incremental",level:4},{value:"Generation and order",id:"generation-and-order",level:4},{value:"SeverityValue",id:"severityvalue",level:4},{value:"API objects",id:"api-objects",level:3},{value:"API object fields",id:"api-object-fields",level:3},{value:"Endpoint naming",id:"endpoint-naming",level:3},{value:"Incidents",id:"incidents",level:3},{value:"Phase list",id:"phase-list",level:3},{value:"Labels",id:"labels",level:3},{value:"Impact",id:"impact",level:3},{value:"Severity",id:"severity",level:3},{value:"Component impacts",id:"component-impacts",level:3},{value:"Maintenance",id:"maintenance",level:3},{value:"Return of <code>POST</code> requests",id:"return-of-post-requests",level:3},{value:"Return of <code>PATCH</code> requests",id:"return-of-patch-requests",level:3},{value:"<code>PATCH</code> vs <code>PUT</code> for updating resources",id:"patch-vs-put-for-updating-resources",level:3},{value:"Authentication and authorization",id:"authentication-and-authorization",level:3}];function l(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.p,{children:["While defining the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi",children:"OpenAPI spec"})," some considerations and decisions are made and should be documented."]}),"\n",(0,s.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,s.jsxs)(n.p,{children:['The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in ',(0,s.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2119",children:"RFC 2119"}),"."]}),"\n",(0,s.jsx)(n.p,{children:'In addition, "FORBIDDEN" is to be interpreted equivalent to "MUST NOT".'}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(n.p,{children:"The spec should be as minimal as possible, while being as understandable as possible, so some choices to the design of API objects, requests and responses are made."}),"\n",(0,s.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsx)(n.h3,{id:"common-definitions",children:"Common definitions"}),"\n",(0,s.jsx)(n.p,{children:"Some defined schemas are used as common types. These common definitions help to simplify the actual object definitions by providing meaningful names, and reduce duplication. A change of ID type for example only needs one change in the common definition, and not in any of the object definitions which include an ID."}),"\n",(0,s.jsx)(n.p,{children:"Special mentions:"}),"\n",(0,s.jsx)(n.h4,{id:"id",children:"Id"}),"\n",(0,s.jsx)(n.p,{children:"IDs are used for identification of resources, which can be retrieved by the API."}),"\n",(0,s.jsx)(n.p,{children:"UUIDs are used, to ensure uniqueness. Also, they can be visually recognized as identifier."}),"\n",(0,s.jsx)(n.h4,{id:"incremental",children:"Incremental"}),"\n",(0,s.jsxs)(n.p,{children:["An ",(0,s.jsx)(n.code,{children:"Incremental"})," is used in combination with other identifiers to identify a sub resource of any kind. ",(0,s.jsx)(n.code,{children:"Incremental"}),"s themselves are not globally unique, but unique for every sub resource of a unique resource."]}),"\n",(0,s.jsx)(n.h4,{id:"generation-and-order",children:"Generation and order"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Generation"})," and ",(0,s.jsx)(n.code,{children:"Order"})," are predefined objects which include a ",(0,s.jsx)(n.code,{children:"Incremental"})," typed field for the common usages of the ",(0,s.jsx)(n.code,{children:"Incremental"})," value."]}),"\n",(0,s.jsx)(n.h4,{id:"severityvalue",children:"SeverityValue"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"SeverityValue"})," is an unsigned integer ranging from 0 to 100 inclusively. It MUST be utilized by an ",(0,s.jsx)(n.code,{children:"Impact"})," when referenced by a requested ",(0,s.jsx)(n.code,{children:"Component"})," to gauge the severity of the impact on that component. It MUST be added to an ",(0,s.jsx)(n.code,{children:"Impact"})," when referenced by an ",(0,s.jsx)(n.code,{children:"Incident"}),", when its created. While being described as an unsigned integer, implementing this value MAY not require it to be an uint data type in any form, because its range even fits in a signed int8 (byte) data type. Each severity value SHOULD be unique, as multiple severities with the same value will be ambiguous."]}),"\n",(0,s.jsx)(n.h3,{id:"api-objects",children:"API objects"}),"\n",(0,s.jsx)(n.p,{children:"All objects which are used as payload, either as request or response, are defined by schemas. This centralizes the maintenance of field names and types, for both requests and responses."}),"\n",(0,s.jsx)(n.h3,{id:"api-object-fields",children:"API object fields"}),"\n",(0,s.jsx)(n.p,{children:"Most fields of objects are not required. This allows usage as request and response payloads."}),"\n",(0,s.jsxs)(n.p,{children:["Responses of payload objects, which contain an ID or an ",(0,s.jsx)(n.code,{children:"Incremental"})," typed field, MUST fill the ID or ",(0,s.jsx)(n.code,{children:"Incremental"})," field to fully identify the (sub) resource."]}),"\n",(0,s.jsxs)(n.p,{children:["Requests on a single resource MUST contain the ID in the path parameters. Request on sub resources MUST contain the ID and ",(0,s.jsx)(n.code,{children:"Incremental"})," typed value as path parameters. The payload SHOULD NOT contain the ID or ",(0,s.jsx)(n.code,{children:"Incremental"})," typed field.\nIf it contains these fields as payload, they SHALL NOT change them."]}),"\n",(0,s.jsxs)(n.p,{children:["Requests to updating operations SHOULD contain the minimum of the changed fields, but MAY contain the full object. ID and ",(0,s.jsx)(n.code,{children:"Incremental"})," typed fields MUST follow the same rules as stated above."]}),"\n",(0,s.jsx)(n.h3,{id:"endpoint-naming",children:"Endpoint naming"}),"\n",(0,s.jsx)(n.p,{children:"The endpoints are named in plural form, even when handling single objects, to keep uniform paths."}),"\n",(0,s.jsx)(n.h3,{id:"incidents",children:"Incidents"}),"\n",(0,s.jsx)(n.p,{children:"Incidents are the main information bearer at the status page. They hold most of the data that describes an incident:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"when it happened"}),"\n",(0,s.jsx)(n.li,{children:"when it completed or if it is still ongoing"}),"\n",(0,s.jsx)(n.li,{children:"which components it affected"}),"\n",(0,s.jsx)(n.li,{children:"the stages the incident progressed through"}),"\n",(0,s.jsx)(n.li,{children:"all updates related to the resolution of the incident"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["An incident is considered ",(0,s.jsx)(n.em,{children:"active"})," while no end time has been set. Incidents whose end time has been set are considered to be ",(0,s.jsx)(n.em,{children:"inactive"})," or ",(0,s.jsx)(n.em,{children:"resolved"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"phase-list",children:"Phase list"}),"\n",(0,s.jsx)(n.p,{children:"The list of phases that an incident can go through has a crucial order. So it MUST be handled as the given list."}),"\n",(0,s.jsx)(n.p,{children:"Delete or update operations are FORBIDDEN."}),"\n",(0,s.jsx)(n.p,{children:'To "change" a phase list, a new one must be created. The old one must be kept. For this mechanic the lists are structured in generations. All references to phases MUST include their generation to ensure correct references.'}),"\n",(0,s.jsxs)(n.p,{children:["To reference a single phase a ",(0,s.jsx)(n.code,{children:"PhaseReference"})," MUST include a generation and an order field. This MAY be used to reference a single generation too."]}),"\n",(0,s.jsx)(n.h3,{id:"labels",children:"Labels"}),"\n",(0,s.jsx)(n.p,{children:"Labels are identifying metadata to components. They do not represent a resource or sub resource of any kind. They are designed as non system critical pieces of information, mainly intended for human consumption."}),"\n",(0,s.jsx)(n.p,{children:"Labels are simple key/value pairs attached to components, categorizing them dynamically."}),"\n",(0,s.jsx)(n.h3,{id:"impact",children:"Impact"}),"\n",(0,s.jsx)(n.p,{children:"An impact defines the relation between an incident and a component. A component can be affected by multiple incidents and an incident can affect multiple components. Each of these impacts can have a different type depending on the incident and component, like for example connectivity or performance issues."}),"\n",(0,s.jsx)(n.p,{children:"To reflect this, each component and incident can have a list of impacts, stating the type of impact and a reference to the incident or component, it refers to."}),"\n",(0,s.jsxs)(n.p,{children:["Furthermore, a ",(0,s.jsx)(n.code,{children:"SeverityValue"})," MUST be supplied to the ",(0,s.jsx)(n.code,{children:"Impact"})," when referenced by a ",(0,s.jsx)(n.code,{children:"Component"}),", to gauge the impact's severity on that component."]}),"\n",(0,s.jsx)(n.h3,{id:"severity",children:"Severity"}),"\n",(0,s.jsxs)(n.p,{children:["A severity contains a name, that MUST be unique and will be used as identifier. The ",(0,s.jsx)(n.code,{children:"SeverityValue"})," marks the upper boundary of the severity."]}),"\n",(0,s.jsxs)(n.p,{children:["The severity's value range is calculated by taking the previous severity's (",(0,s.jsx)(n.code,{children:"SeverityA"}),") value and adding 1 to obtain the starting point and taking the current severity's (SeverityB) value as the end point. These limits are inclusive."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-acsii",children:"0, ... , SeverityA.value, SeverityA.value, + 1, ... , SeverityB.value - 1, SeverityB.value, SeverityB.value + 1, ... , 100\n |<------------range of severity values for SeverityB-------------\x3e|\n"})}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'[\n {\n "displayName": "operational",\n "value": 33\n },\n {\n "displayName": "limited",\n "value": 66\n },\n {\n "displayName": "broken",\n "value": 100\n }\n]\n'})}),"\n",(0,s.jsx)(n.p,{children:'A special severity of type "maintenance" is given the exact value of 0.'}),"\n",(0,s.jsx)(n.p,{children:"This means:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"maintenance at 0"}),"\n",(0,s.jsx)(n.li,{children:"operational from 1 to 33"}),"\n",(0,s.jsx)(n.li,{children:"limited from 34 to 66"}),"\n",(0,s.jsx)(n.li,{children:"broken from 67 to 100."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"A value of 100 is the maximum of the severity value."}),"\n",(0,s.jsxs)(n.p,{children:["A severity with the value of 100 MUST always be supplied. This is the highest severity for the system. If no severity with a value of 100 exists, e.g. the highest severity value is set at 90, an ",(0,s.jsx)(n.code,{children:"Impact"})," with a higher ",(0,s.jsx)(n.code,{children:"SeverityValue"})," WILL be considered to be an ",(0,s.jsx)(n.em,{children:"unknown"})," severity."]}),"\n",(0,s.jsx)(n.h3,{id:"component-impacts",children:"Component impacts"}),"\n",(0,s.jsx)(n.p,{children:"Components list their impacts, which they are affected by, as read only. Only an incident creates an impact on a component. Components MUST only list their currently active impacts."}),"\n",(0,s.jsxs)(n.p,{children:["An optional ",(0,s.jsx)(n.code,{children:"at"})," parameter can be supplied, to set a reference time to show all incidents, active at that time, even when they are inactive currently."]}),"\n",(0,s.jsx)(n.h3,{id:"maintenance",children:"Maintenance"}),"\n",(0,s.jsxs)(n.p,{children:["Any ",(0,s.jsx)(n.code,{children:"impact"})," that has the reserved ",(0,s.jsx)(n.code,{children:"SeverityValue"})," of 0 is a maintenance time slot. As such it MUST include a start and end time. However, both are allowed to be set in the future."]}),"\n",(0,s.jsxs)(n.h3,{id:"return-of-post-requests",children:["Return of ",(0,s.jsx)(n.code,{children:"POST"})," requests"]}),"\n",(0,s.jsxs)(n.p,{children:["Generally ",(0,s.jsx)(n.code,{children:"POST"})," requests create new resources. These endpoints do not return the new resource, but a unique identifier to the resource e.g. a UUID."]}),"\n",(0,s.jsx)(n.p,{children:"In most cases the new resource won't be used directly after creation. Most often list calls are used. If the new resource is used directly, it can be retrieved by the returned identifier."}),"\n",(0,s.jsxs)(n.p,{children:["Payloads to POST requests SHALL NOT include ID or ",(0,s.jsx)(n.code,{children:"Incremental"})," typed fields, it lies in the responsibility of the API server to assign IDs and ",(0,s.jsx)(n.code,{children:"Incremental"}),"s to objects."]}),"\n",(0,s.jsxs)(n.h3,{id:"return-of-patch-requests",children:["Return of ",(0,s.jsx)(n.code,{children:"PATCH"})," requests"]}),"\n",(0,s.jsxs)(n.p,{children:["Most commonly ",(0,s.jsx)(n.code,{children:"PATCH"})," requests are used to partially or fully change a resource. These requests do not respond with the changed resource, nor an identifier."]}),"\n",(0,s.jsx)(n.p,{children:"Both the old state as well as the new state are known on the client at that point in time and if they need to load the actual recent version from the server, the identifier is already known."}),"\n",(0,s.jsxs)(n.h3,{id:"patch-vs-put-for-updating-resources",children:[(0,s.jsx)(n.code,{children:"PATCH"})," vs ",(0,s.jsx)(n.code,{children:"PUT"})," for updating resources"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"PUT"})," requests is most commonly used to update full objects, whereas ",(0,s.jsx)(n.code,{children:"PATCH"})," is used for partial updates."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"PATCH"})," is used as the default method for updating resources because it does not require the full object for an update, but does not discourage the use of the complete object."]}),"\n",(0,s.jsx)(n.h3,{id:"authentication-and-authorization",children:"Authentication and authorization"}),"\n",(0,s.jsx)(n.p,{children:"The API spec does not include either authentication (AuthN) nor authorization (AuthZ) of any kind. The API server MUST be secured by a reverse/auth proxy."})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>o});var t=i(96540);const s={},a=t.createContext(s);function r(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fe5fac7c.9896d0a3.js b/assets/js/fe5fac7c.9896d0a3.js new file mode 100644 index 0000000000..fe351d2994 --- /dev/null +++ b/assets/js/fe5fac7c.9896d0a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[12479],{86916:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>m,frontMatter:()=>s,metadata:()=>r,toc:()=>i});const r=JSON.parse('{"id":"container/deployment-examples/a/hardware","title":"Hardware Requirements","description":"TODO","source":"@site/docs/03-container/deployment-examples/a/hardware.md","sourceDirName":"03-container/deployment-examples/a","slug":"/container/deployment-examples/a/hardware","permalink":"/docs/container/deployment-examples/a/hardware","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/deployment-examples/a/hardware.md","tags":[],"version":"current","frontMatter":{}}');var a=t(74848),o=t(28453);const s={},c="Hardware Requirements",d={},i=[];function l(e){const n={h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"hardware-requirements",children:"Hardware Requirements"})}),"\n",(0,a.jsx)(n.p,{children:"TODO"})]})}function m(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>c});var r=t(96540);const a={},o=r.createContext(a);function s(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ff45c01b.a2c19573.js b/assets/js/ff45c01b.a2c19573.js new file mode 100644 index 0000000000..e0d135e007 --- /dev/null +++ b/assets/js/ff45c01b.a2c19573.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[66290],{90857:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"development/tests/rfc2119-keyword-test-guide","title":"SCS RFC2119 Keyword Test Guide","description":"Introduction","source":"@site/contributor-docs/development/tests/rfc2119-keyword-test-guide.md","sourceDirName":"development/tests","slug":"/development/tests/rfc2119-keyword-test-guide","permalink":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"SCS RFC2119 Keyword Test Guide","type":null,"status":"Draft","track":"Global"},"sidebar":"devDocs","previous":{"title":"Developer documentation","permalink":"/contributor-docs/development/"},"next":{"title":"SCS Conformance Test Implementation Guide","permalink":"/contributor-docs/development/tests/test-implementation-guide"}}');var r=s(74848),i=s(28453);const o={title:"SCS RFC2119 Keyword Test Guide",type:null,status:"Draft",track:"Global"},a=void 0,l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"1. Understanding SCS Standards and RFC2119 Keywords",id:"1-understanding-scs-standards-and-rfc2119-keywords",level:2},{value:"2. Interpreting RFC2119 Keywords in the Context of SCS",id:"2-interpreting-rfc2119-keywords-in-the-context-of-scs",level:2},{value:"3. Channels for Output in Test Scripts",id:"3-channels-for-output-in-test-scripts",level:2},{value:"4. Compliance and Test Passing Criteria",id:"4-compliance-and-test-passing-criteria",level:2},{value:"Examples",id:"examples",level:2},{value:"5.1 Example: Standards Document using RFC2119 Keywords",id:"51-example-standards-document-using-rfc2119-keywords",level:3},{value:"Web Server Installation Standard",id:"web-server-installation-standard",level:3},{value:"Purpose",id:"purpose",level:4},{value:"Requirements",id:"requirements",level:4},{value:"Compliance",id:"compliance",level:4},{value:"5.2 Example: Test script using RFC2119 Keywords",id:"52-example-test-script-using-rfc2119-keywords",level:3}];function c(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsxs)(n.p,{children:["The development and validation of tests within the Sovereign Cloud Stack (SCS) is a critical endeavor aimed at ensuring that cloud technologies meet the highest standards of interoperability, security and sovereignty. This process is not only about aligning with the technical specifications and standards set by SCS but also about safeguarding the principles of open-source collaboration and the autonomy of cloud services. By thoroughly crafting tests that adhere to the stringent requirement levels as indicated by ",(0,r.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2119",children:"RFC2119 keywords"}),", we ensure that the infrastructure, services and their integrations within the SCS ecosystem are robust, secure and sovereign."]}),"\n",(0,r.jsx)(n.p,{children:"This detailed process is crucial for stakeholders seeking to develop or utilize sovereign cloud services that are reliable, compliant and capable of standing up to the demands of modern cloud computing. It serves as an indispensable guide for developers, operators and policymakers who are involved in the creation, deployment and governance of cloud services within SCS. By understanding and implementing the standards and tests defined by the SCS, professionals can contribute to a cloud infrastructure that is not only technologically advanced but also aligns with the core values of sovereignty and open-source ethics."}),"\n",(0,r.jsx)(n.p,{children:"Therefore, for individuals tasked with writing tests and defining standards within SCS, this document is particularly important. It serves as a base with guidelines on how to use and understand RFC2119 keywords in the context of SCS. Its insights are crucial for anyone from technical architects to regulatory bodies within the SCS ecosystem, underlining the foundational principles necessary for achieving a sovereign cloud environment."}),"\n",(0,r.jsx)(n.h2,{id:"1-understanding-scs-standards-and-rfc2119-keywords",children:"1. Understanding SCS Standards and RFC2119 Keywords"}),"\n",(0,r.jsx)(n.p,{children:"SCS standards use RFC2119 keywords like:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"MUST"})," (same as ",(0,r.jsx)(n.strong,{children:"REQUIRED"}),", ",(0,r.jsx)(n.strong,{children:"SHALL"}),"),"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"MUST NOT"})," (same as ",(0,r.jsx)(n.strong,{children:"SHALL NOT"}),"),"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"SHOULD"})," (same as ",(0,r.jsx)(n.strong,{children:"RECOMMENDED"}),"),"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"SHOULD NOT"})," (same as ",(0,r.jsx)(n.strong,{children:"NOT RECOMMENDED"}),"),"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"MAY"})," (same as ",(0,r.jsx)(n.strong,{children:"OPTIONAL"}),")"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"to define requirements for SCS-compatible IaaS and KaaS resources. These standards & tests are crucial for ensuring interoperability and sovereignty in cloud services, as they are built on open-source components such as Kubernetes and OpenStack."}),"\n",(0,r.jsxs)(n.p,{children:["To ensure readability and comprehensibility, only the main keywords ",(0,r.jsx)(n.strong,{children:"MUST"}),", ",(0,r.jsx)(n.strong,{children:"MUST NOT"}),", ",(0,r.jsx)(n.strong,{children:"SHOULD"}),", ",(0,r.jsx)(n.strong,{children:"SHOULD NOT"})," and ",(0,r.jsx)(n.strong,{children:"MAY"})," are referred to below."]}),"\n",(0,r.jsx)(n.h2,{id:"2-interpreting-rfc2119-keywords-in-the-context-of-scs",children:"2. Interpreting RFC2119 Keywords in the Context of SCS"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"MUST and MUST NOT"}),": These are binary and straightforward to test. Compliance or\nnon-compliance directly affects whether the standard is satisfied. For visualization, fulfilled\nrequirements could be marked in green, unfulfilled ones in red."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"SHOULD and SHOULD NOT"}),": These represent recommendations. While fulfilling these do\nnot directly affect standard compliance, it is advised for future-proofing against\npotential standard evolutions. Non-compliance could be visualized in yellow, possibly\nwith a valid reason for non-fulfillment."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"MAY"}),": This is more flexible and could be used to provide additional\ninformation or best practices. Their impact on compliance is not as direct as ",(0,r.jsx)(n.strong,{children:"MUST"})," or\n",(0,r.jsx)(n.strong,{children:"SHOULD"})," categories. These can be marked as blue."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"3-channels-for-output-in-test-scripts",children:"3. Channels for Output in Test Scripts"}),"\n",(0,r.jsx)(n.p,{children:"In test scripts, different channels are used to convey information of different importance to the user. These channels are based on the ubiquitous and de-facto standard logging levels of common logging libraries in scripting and programming languages, in particular Python: DEBUG, INFO, WARNING, ERROR and CRITICAL."}),"\n",(0,r.jsx)(n.p,{children:"Alignment of the RFC2119 keywords with specific channels in test scripts:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"MUST"})," and ",(0,r.jsx)(n.strong,{children:"MUST NOT"})," lead to the ERROR channel for failed tests"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"SHOULD"})," and ",(0,r.jsx)(n.strong,{children:"SHOULD NOT"})," lead to the WARNING channel, the test is still passed"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"MAY"})," leads to the INFO channel, the test is still passed"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"However, the CRITICAL level is not directly associated with any of the RFC2119 keywords; it is instead used to signify that a test was unable to complete or was interrupted due to various issues, such as runtime failures."}),"\n",(0,r.jsx)(n.h2,{id:"4-compliance-and-test-passing-criteria",children:"4. Compliance and Test Passing Criteria"}),"\n",(0,r.jsxs)(n.p,{children:["A test is considered to pass if and only if it doesn't produce any messages on the\nERROR nor the CRITICAL channel. The presence of warnings or informational items from\n",(0,r.jsx)(n.strong,{children:"SHOULD"})," and ",(0,r.jsx)(n.strong,{children:"MAY"})," categories do not directly impact the pass/fail status but is\nimportant for overall quality and compatibility with future standards."]}),"\n",(0,r.jsx)(n.p,{children:"That means a test can have one of three results:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"fail: if it has at least one message on ERROR"}),"\n",(0,r.jsx)(n.li,{children:"DNF (did not finish): if it has no message on ERROR, but at least one on CRITICAL"}),"\n",(0,r.jsx)(n.li,{children:"pass: otherwise"}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["In addition, a test ",(0,r.jsx)(n.strong,{children:"MUST"})," exit with a non-zero exit code (e.g., via ",(0,r.jsx)(n.code,{children:"sys.exit(\u2026)"}),") if there are any ERROR or CRITICAL messages, thus signaling a failure to meet a standard."]}),"\n",(0,r.jsxs)(n.p,{children:["In test scripts it is a ",(0,r.jsx)(n.strong,{children:"MUST"})," to redirect all channel outputs to standard error (",(0,r.jsx)(n.strong,{children:"stderr"}),"), which aligns with Python's default logging behavior. The format which ",(0,r.jsx)(n.strong,{children:"MUST"})," be used is ",(0,r.jsx)(n.strong,{children:"CHANNEL: MESSAGE"}),", where ",(0,r.jsx)(n.strong,{children:"CHANNEL"})," represents the log level (e.g., DEBUG, INFO, WARNING, ERROR, CRITICAL) and ",(0,r.jsx)(n.strong,{children:"MESSAGE"})," encapsulates the actual log message."]}),"\n",(0,r.jsx)(n.p,{children:"For instance, when logging an INFO regarding a Kubernetes cluster, the format on the command line should be like this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-md",children:"INFO: Checking cluster specified by context 'my-cluster' in /path/to/.kube/config.\n"})}),"\n",(0,r.jsx)(n.p,{children:"This example adheres to our proposed format by clearly indicating the severity level (INFO) followed by the specific message intended for the user or developer."}),"\n",(0,r.jsx)(n.h2,{id:"examples",children:"Examples"}),"\n",(0,r.jsx)(n.h3,{id:"51-example-standards-document-using-rfc2119-keywords",children:"5.1 Example: Standards Document using RFC2119 Keywords"}),"\n",(0,r.jsx)(n.p,{children:'The following example of a fictitious document for a "Web Server Installation Standard"\nis intended to illustrate the use of RFC2119 keywords in connection with the creation of\nSCS-compliant standard documents.'}),"\n",(0,r.jsx)(n.h3,{id:"web-server-installation-standard",children:"Web Server Installation Standard"}),"\n",(0,r.jsx)(n.h4,{id:"purpose",children:"Purpose"}),"\n",(0,r.jsx)(n.p,{children:"This document provides a concise set of requirements for installing a secure web server."}),"\n",(0,r.jsx)(n.h4,{id:"requirements",children:"Requirements"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Web Server Software: Apache HTTP Server 2.4.x or Nginx 1.18.x ",(0,r.jsx)(n.strong,{children:"MUST"})," be installed. No\nother web server software versions or types are permitted."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Operating System: The server ",(0,r.jsx)(n.strong,{children:"MUST"})," run on an OS that receives current security updates.\nUnsupported versions ",(0,r.jsx)(n.strong,{children:"MUST NOT"})," be used."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["TLS Configuration: TLS 1.2 or higher ",(0,r.jsx)(n.strong,{children:"MUST"})," be enabled for all connections. SSL and\nearlier TLS versions ",(0,r.jsx)(n.strong,{children:"MUST NOT"})," be used."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Security Patches: The web server and OS ",(0,r.jsx)(n.strong,{children:"MUST"})," be kept up-to-date with security patches.\nCritical patches ",(0,r.jsx)(n.strong,{children:"SHOULD"})," be applied within 48 hours of release."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Firewall Setup: The firewall ",(0,r.jsx)(n.strong,{children:"SHOULD"})," be configured to allow only necessary ports,\nsuch as 80 (HTTP) and 443 (HTTPS). All unnecessary ports ",(0,r.jsx)(n.strong,{children:"SHOULD NOT"})," be open."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Backup Plan: Regular backups of the web server data ",(0,r.jsx)(n.strong,{children:"MAY"})," be performed, and it is\nrecommended that backup integrity checks are conducted to ensure recoverability."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"compliance",children:"Compliance"}),"\n",(0,r.jsx)(n.p,{children:"Failure to comply with these requirements results in the web server being\nconsidered non-compliant with the organization's security policies."}),"\n",(0,r.jsx)(n.h3,{id:"52-example-test-script-using-rfc2119-keywords",children:"5.2 Example: Test script using RFC2119 Keywords"}),"\n",(0,r.jsx)(n.p,{children:'The following example of a fictitious code for a test of "process_requirements"\nis intended to illustrate the use of RFC2119 keywords in connection with the\ncreation of SCS-compliant standard tests.'}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'\nimport logging\nlogging.basicConfig(level=logging.DEBUG)\nlogger = logging.getLogger(__name__)\n\ndef process_requirements(var1, var2):\n try:\n # debug log for input variables\n logger.debug(f"Received input var1: {var1}, var2: {var2}")\n\n # example of an error case (equivalent to MUST and MUST NOT)\n if var1 < 0:\n logger.error("var1 must be positive")\n elif var1 > 100:\n logger.error("var1 must not exceed 100")\n\n # add debug log to confirm evaluation of var1\n logger.debug(f"var1 evaluated: {var1 > 0 and var1 < 100}")\n\n # example of a warning case (equivalent to SHOULD and SHOULD NOT)\n if var2 < 10:\n logger.warning("var2 should be at least 10 for optimal performance")\n elif var2 > 50:\n logger.warning("var2 should not exceed 50 for optimal performance")\n\n # add debug log to confirm evaluation of var2\n logger.debug(f"var2 evaluated: {var2 > 10 and var2 < 50}")\n\n # example of an informative case (equivalent to MAY)\n if var1 + var2 < 100:\n logger.info("Combination is within recommended range")\n else:\n logger.info("Combination exceeds the recommended range but may still proceed")\n\n # debug log before completing the process\n logger.debug(f"Final evaluation before completion: var1 + var2 = {var1 + var2}")\n\n # success log\n logger.debug("Process completed successfully")\n\n except ValueError as e:\n # debug log before raising a critical error\n logger.debug("Encountered a critical error about to log", exc_info=True)\n logger.critical(f"Process failed: {e}", exc_info=True)\n\n'})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Note"}),": The DEBUG channel is used for additional information for developers to better understand a process and does not apply to RFC2119 keywords."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ff7b9a4c.29b46cb9.js b/assets/js/ff7b9a4c.29b46cb9.js new file mode 100644 index 0000000000..c7431e6f9a --- /dev/null +++ b/assets/js/ff7b9a4c.29b46cb9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[45929],{87805:s=>{s.exports=JSON.parse('{"version":{"pluginId":"standards","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"standards":[{"type":"link","label":"Introduction","href":"/standards/","docId":"index","unlisted":false},{"type":"category","label":"Certification","items":[{"type":"category","label":"Scopes and Versions","items":[{"type":"link","label":"SCS-compatible IaaS","href":"/standards/scs-compatible-iaas","docId":"scs-compatible-iaas","unlisted":false},{"type":"link","label":"SCS-compatible KaaS","href":"/standards/scs-compatible-kaas","docId":"scs-compatible-kaas","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/certification/scopes-versions"},{"type":"link","label":"Compliance Check Pipeline","href":"/standards/certification/pipeline","docId":"certification/pipeline","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/certification/overview"},{"type":"category","label":"Standards","items":[{"type":"category","label":"Global","items":[{"type":"category","label":"scs-0001","items":[{"type":"link","label":"V1","href":"/standards/scs-0001-v1-sovereign-cloud-standards","docId":"scs-0001-v1-sovereign-cloud-standards","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/global/scs-0001"},{"type":"category","label":"scs-0002","items":[{"type":"link","label":"V1","href":"/standards/scs-0002-v1-standards-docs-org","docId":"scs-0002-v1-standards-docs-org","unlisted":false},{"type":"link","label":"V2","href":"/standards/scs-0002-v2-standards-docs-org","docId":"scs-0002-v2-standards-docs-org","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/global/scs-0002"},{"type":"category","label":"scs-0003","items":[{"type":"link","label":"V1","href":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","docId":"scs-0003-v1-sovereign-cloud-standards-yaml","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/global/scs-0003"},{"type":"category","label":"scs-0004","items":[{"type":"link","label":"V1","href":"/standards/scs-0004-v1-achieving-certification","docId":"scs-0004-v1-achieving-certification","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/global/scs-0004"},{"type":"category","label":"scs-0005","items":[{"type":"link","label":"V1","href":"/standards/scs-0005-v1-project-governance","docId":"scs-0005-v1-project-governance","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/global/scs-0005"}],"collapsed":true,"collapsible":true,"href":"/standards/global/"},{"type":"category","label":"IaaS","items":[{"type":"category","label":"scs-0100","items":[{"type":"link","label":"V1","href":"/standards/scs-0100-v1-flavor-naming","docId":"scs-0100-v1-flavor-naming","unlisted":false},{"type":"link","label":"V2","href":"/standards/scs-0100-v2-flavor-naming","docId":"scs-0100-v2-flavor-naming","unlisted":false},{"type":"link","label":"V3","href":"/standards/scs-0100-v3-flavor-naming","docId":"scs-0100-v3-flavor-naming","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0100-w1-flavor-naming-implementation-testing","docId":"scs-0100-w1-flavor-naming-implementation-testing","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0100"},{"type":"category","label":"scs-0101","items":[{"type":"link","label":"V1","href":"/standards/scs-0101-v1-entropy","docId":"scs-0101-v1-entropy","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0101-w1-entropy-implementation-testing","docId":"scs-0101-w1-entropy-implementation-testing","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0101"},{"type":"category","label":"scs-0102","items":[{"type":"link","label":"V1","href":"/standards/scs-0102-v1-image-metadata","docId":"scs-0102-v1-image-metadata","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0102-w1-image-metadata-implementation-testing","docId":"scs-0102-w1-image-metadata-implementation-testing","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0102"},{"type":"category","label":"scs-0103","items":[{"type":"link","label":"V1","href":"/standards/scs-0103-v1-standard-flavors","docId":"scs-0103-v1-standard-flavors","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0103"},{"type":"category","label":"scs-0104","items":[{"type":"link","label":"V1","href":"/standards/scs-0104-v1-standard-images","docId":"scs-0104-v1-standard-images","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0104-w1-standard-images-implementation","docId":"scs-0104-w1-standard-images-implementation","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0104"},{"type":"category","label":"scs-0110","items":[{"type":"link","label":"V1","href":"/standards/scs-0110-v1-ssd-flavors","docId":"scs-0110-v1-ssd-flavors","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0110"},{"type":"category","label":"scs-0111","items":[{"type":"link","label":"V1","href":"/standards/scs-0111-v1-volume-type-decisions","docId":"scs-0111-v1-volume-type-decisions","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0111"},{"type":"category","label":"scs-0112","items":[{"type":"link","label":"V1","href":"/standards/scs-0112-v1-sonic","docId":"scs-0112-v1-sonic","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0112"},{"type":"category","label":"scs-0113","items":[{"type":"link","label":"V1","href":"/standards/scs-0113-v1-security-groups-decision-record","docId":"scs-0113-v1-security-groups-decision-record","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0113"},{"type":"category","label":"scs-0114","items":[{"type":"link","label":"V1","href":"/standards/scs-0114-v1-volume-type-standard","docId":"scs-0114-v1-volume-type-standard","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0114"},{"type":"category","label":"scs-0115","items":[{"type":"link","label":"V1","href":"/standards/scs-0115-v1-default-rules-for-security-groups","docId":"scs-0115-v1-default-rules-for-security-groups","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0115"},{"type":"category","label":"scs-0116","items":[{"type":"link","label":"V1","href":"/standards/scs-0116-v1-key-manager-standard","docId":"scs-0116-v1-key-manager-standard","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0116-w1-key-manager-implementation-testing","docId":"scs-0116-w1-key-manager-implementation-testing","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0116"},{"type":"category","label":"scs-0117","items":[{"type":"link","label":"V1","href":"/standards/scs-0117-v1-volume-backup-service","docId":"scs-0117-v1-volume-backup-service","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0117"},{"type":"category","label":"scs-0118","items":[{"type":"link","label":"V1","href":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","docId":"scs-0118-v1-taxonomy-of-failsafe-levels","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0118-w1-example-impacts-of-failure-scenarios","docId":"scs-0118-w1-example-impacts-of-failure-scenarios","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0118"},{"type":"category","label":"scs-0119","items":[{"type":"link","label":"V1","href":"/standards/scs-0119-v1-rook-decision","docId":"scs-0119-v1-rook-decision","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0119"},{"type":"category","label":"scs-0120","items":[{"type":"link","label":"V1","href":"/standards/scs-0120-v1-capi-images","docId":"scs-0120-v1-capi-images","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0120"},{"type":"category","label":"scs-0121","items":[{"type":"link","label":"V1","href":"/standards/scs-0121-v1-Availability-Zones-Standard","docId":"scs-0121-v1-Availability-Zones-Standard","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0121-w1-Availability-Zones-Standard","docId":"scs-0121-w1-Availability-Zones-Standard","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0121"},{"type":"category","label":"scs-0122","items":[{"type":"link","label":"V1","href":"/standards/scs-0122-v1-node-to-node-encryption","docId":"scs-0122-v1-node-to-node-encryption","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0122"},{"type":"category","label":"scs-0123","items":[{"type":"link","label":"V1","href":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","docId":"scs-0123-v1-mandatory-and-supported-IaaS-services","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0123"},{"type":"category","label":"scs-0124","items":[{"type":"link","label":"V1","href":"/standards/scs-0124-v1-security-of-iaas-service-software","docId":"scs-0124-v1-security-of-iaas-service-software","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0124-w1-security-of-iaas-service-software","docId":"scs-0124-w1-security-of-iaas-service-software","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0124"},{"type":"category","label":"scs-0125","items":[{"type":"link","label":"V1","href":"/standards/scs-0125-v1-secure-connections","docId":"scs-0125-v1-secure-connections","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0125"}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/"},{"type":"category","label":"KaaS","items":[{"type":"category","label":"scs-0200","items":[{"type":"link","label":"V1","href":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","docId":"scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0200"},{"type":"category","label":"scs-0210","items":[{"type":"link","label":"V1","href":"/standards/scs-0210-v1-k8s-new-version-policy","docId":"scs-0210-v1-k8s-new-version-policy","unlisted":false},{"type":"link","label":"V2","href":"/standards/scs-0210-v2-k8s-version-policy","docId":"scs-0210-v2-k8s-version-policy","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0210-w1-k8s-version-policy-implementation-testing","docId":"scs-0210-w1-k8s-version-policy-implementation-testing","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0210"},{"type":"category","label":"scs-0211","items":[{"type":"link","label":"V1","href":"/standards/scs-0211-v1-kaas-default-storage-class","docId":"scs-0211-v1-kaas-default-storage-class","unlisted":false},{"type":"link","label":"V2","href":"/standards/scs-0211-v2-kaas-default-storage-class","docId":"scs-0211-v2-kaas-default-storage-class","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing","docId":"scs-0211-w1-kaas-default-storage-class-implementation-testing","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0211"},{"type":"category","label":"scs-0212","items":[{"type":"link","label":"V1","href":"/standards/scs-0212-v1-requirements-for-container-registries","docId":"scs-0212-v1-requirements-for-container-registries","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0212"},{"type":"category","label":"scs-0213","items":[{"type":"link","label":"V1","href":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","docId":"scs-0213-v1-k8s-nodes-anti-affinity","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0213"},{"type":"category","label":"scs-0214","items":[{"type":"link","label":"V1","href":"/standards/scs-0214-v1-k8s-node-distribution","docId":"scs-0214-v1-k8s-node-distribution","unlisted":false},{"type":"link","label":"V2","href":"/standards/scs-0214-v2-k8s-node-distribution","docId":"scs-0214-v2-k8s-node-distribution","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing","docId":"scs-0214-w1-k8s-node-distribution-implementation-testing","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0214"},{"type":"category","label":"scs-0215","items":[{"type":"link","label":"V1","href":"/standards/scs-0215-v1-robustness-features","docId":"scs-0215-v1-robustness-features","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0215"},{"type":"category","label":"scs-0216","items":[{"type":"link","label":"V1","href":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","docId":"scs-0216-v1-requirements-for-testing-cluster-stacks","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0216"},{"type":"category","label":"scs-0217","items":[{"type":"link","label":"V1","href":"/standards/scs-0217-v1-cluster-hardening","docId":"scs-0217-v1-cluster-hardening","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0217"},{"type":"category","label":"scs-0218","items":[{"type":"link","label":"V1","href":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","docId":"scs-0218-v1-container-registry-for-scs-standard-implementation","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0218"},{"type":"category","label":"scs-0219","items":[{"type":"link","label":"V1","href":"/standards/scs-0219-v1-kaas-networking","docId":"scs-0219-v1-kaas-networking","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0219-w1-kaas-networking","docId":"scs-0219-w1-kaas-networking","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0219"}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/"},{"type":"category","label":"IAM","items":[{"type":"category","label":"scs-0300","items":[{"type":"link","label":"V1","href":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","docId":"scs-0300-v1-requirements-for-sso-identity-federation","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iam/scs-0300"},{"type":"category","label":"scs-0301","items":[{"type":"link","label":"V1","href":"/standards/scs-0301-v1-naming-conventions","docId":"scs-0301-v1-naming-conventions","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iam/scs-0301"},{"type":"category","label":"scs-0302","items":[{"type":"link","label":"V1","href":"/standards/scs-0302-v1-domain-manager-role","docId":"scs-0302-v1-domain-manager-role","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0302-w1-domain-manager-implementation-notes","docId":"scs-0302-w1-domain-manager-implementation-notes","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iam/scs-0302"}],"collapsed":true,"collapsible":true,"href":"/standards/iam/"},{"type":"category","label":"Ops","items":[{"type":"category","label":"scs-0400","items":[{"type":"link","label":"V1","href":"/standards/scs-0400-v1-status-page-create-decision","docId":"scs-0400-v1-status-page-create-decision","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0400"},{"type":"category","label":"scs-0401","items":[{"type":"link","label":"V1","href":"/standards/scs-0401-v1-status-page-reference-implementation-decision","docId":"scs-0401-v1-status-page-reference-implementation-decision","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0401"},{"type":"category","label":"scs-0402","items":[{"type":"link","label":"V1","href":"/standards/scs-0402-v1-status-page-openapi-spec-decision","docId":"scs-0402-v1-status-page-openapi-spec-decision","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0402"},{"type":"category","label":"scs-0403","items":[{"type":"link","label":"V1","href":"/standards/scs-0403-v1-csp-kaas-observability-stack","docId":"scs-0403-v1-csp-kaas-observability-stack","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0403"},{"type":"category","label":"scs-0410","items":[{"type":"link","label":"V1","href":"/standards/scs-0410-v1-gnocchi-as-metering-database","docId":"scs-0410-v1-gnocchi-as-metering-database","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0410"},{"type":"category","label":"scs-0411","items":[{"type":"link","label":"V1","href":"/standards/scs-0411-v1-publishing_method_for_metering_data","docId":"scs-0411-v1-publishing_method_for_metering_data","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0411"},{"type":"category","label":"scs-0412","items":[{"type":"link","label":"V1","href":"/standards/scs-0412-v1-metering-json","docId":"scs-0412-v1-metering-json","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0412"}],"collapsed":true,"collapsible":true,"href":"/standards/ops/"}],"collapsed":true,"collapsible":true,"href":"/standards/standards/overview"}]},"docs":{"certification/overview":{"id":"certification/overview","title":"overview","description":"SCS certificates come with various scopes. See Scopes and Versions for details.","sidebar":"standards"},"certification/overview.template":{"id":"certification/overview.template","title":"overview.template","description":"SCS certificates come with various scopes. See Scopes and Versions for details."},"certification/pipeline":{"id":"certification/pipeline","title":"SCS Compliance Check Pipeline Manual","description":"The SCS compliance check suite runs automated tests, generates a signed report for the run, and feeds it to","sidebar":"standards"},"certification/scopes-versions":{"id":"certification/scopes-versions","title":"Scopes and versions","description":"SCS provides a certification framework consisting of six different kinds of certificates of varying scope.","sidebar":"standards"},"global/index":{"id":"global/index","title":"Global Standards","description":"This track encompasses the foundational standards that guide the overall structure, documentation, and general topics related to the Sovereign Cloud Stack. It serves as the core framework, ensuring consistency, clarity, and comprehensibility across all aspects of the cloud stack, fostering an environment where information is easily accessible and understood.","sidebar":"standards"},"global/scs-0001":{"id":"global/scs-0001","title":"scs-0001: Sovereign Cloud Standards","description":"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision","sidebar":"standards"},"global/scs-0002":{"id":"global/scs-0002","title":"scs-0002: Standards, Docs and Organisation","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"global/scs-0003":{"id":"global/scs-0003","title":"scs-0003: Sovereign Cloud Standards YAML","description":"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,","sidebar":"standards"},"global/scs-0004":{"id":"global/scs-0004","title":"scs-0004: Regulations for achieving SCS-compatible certification","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"global/scs-0005":{"id":"global/scs-0005","title":"scs-0005: Governance of the SCS community","description":"SCS-0005 outlines the structure and governance of the SCS community by the SCS Project Board and how this is elected.","sidebar":"standards"},"iaas/index":{"id":"iaas/index","title":"IaaS Standards","description":"The IaaS Layer Standards track focuses on the protocols, guidelines, and specifications that govern the infrastructure as a service layer. This encompasses standards for virtual machines, storage, networking, and other foundational resources, ensuring seamless, efficient, and secure operation, interoperability, and management of the underlying cloud infrastructure.","sidebar":"standards"},"iaas/scs-0100":{"id":"iaas/scs-0100","title":"scs-0100: SCS Flavor Naming Standard","description":"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack","sidebar":"standards"},"iaas/scs-0101":{"id":"iaas/scs-0101","title":"scs-0101: SCS Entropy","description":"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations","sidebar":"standards"},"iaas/scs-0102":{"id":"iaas/scs-0102","title":"scs-0102: SCS Image Metadata","description":"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating","sidebar":"standards"},"iaas/scs-0103":{"id":"iaas/scs-0103","title":"scs-0103: SCS Standard Flavors and Properties","description":"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack","sidebar":"standards"},"iaas/scs-0104":{"id":"iaas/scs-0104","title":"scs-0104: SCS Standard Images","description":"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,","sidebar":"standards"},"iaas/scs-0110":{"id":"iaas/scs-0110","title":"scs-0110: SSD Flavors","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0111":{"id":"iaas/scs-0111","title":"scs-0111: Decisions for the Volume Type Standard","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0112":{"id":"iaas/scs-0112","title":"scs-0112: SONiC Support in SCS","description":"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.","sidebar":"standards"},"iaas/scs-0113":{"id":"iaas/scs-0113","title":"scs-0113: Security Groups Decision Record","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0114":{"id":"iaas/scs-0114","title":"scs-0114: SCS Volume Types","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0115":{"id":"iaas/scs-0115","title":"scs-0115: Default Rules for Security Groups","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0116":{"id":"iaas/scs-0116","title":"scs-0116: SCS Key Manager Standard","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0117":{"id":"iaas/scs-0117","title":"scs-0117: Volume Backup Functionality","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0118":{"id":"iaas/scs-0118","title":"scs-0118: SCS Taxonomy of Failsafe Levels","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0119":{"id":"iaas/scs-0119","title":"scs-0119: Replacement of the deprecated ceph-ansible tool","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0120":{"id":"iaas/scs-0120","title":"scs-0120: Cluster-API images","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0121":{"id":"iaas/scs-0121","title":"scs-0121: SCS Availability Zones","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0122":{"id":"iaas/scs-0122","title":"scs-0122: _End-to-End Encryption between Customer Workloads_","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0123":{"id":"iaas/scs-0123","title":"scs-0123: Mandatory and Supported IaaS Services","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0124":{"id":"iaas/scs-0124","title":"scs-0124: Standard for the security of IaaS service software","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0125":{"id":"iaas/scs-0125","title":"scs-0125: Secure Connections","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iam/index":{"id":"iam/index","title":"IAM Standards","description":"This track revolves around Identity and Access Management (IAM) standards, providing guidelines for ensuring secure and efficient user authentication, authorization, and administration. It addresses issues related to user identity, permissions, roles, and policies, aiming to safeguard and streamline access to cloud resources and services.","sidebar":"standards"},"iam/scs-0300":{"id":"iam/scs-0300","title":"scs-0300: Requirements for SSO identity federation","description":"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign","sidebar":"standards"},"iam/scs-0301":{"id":"iam/scs-0301","title":"scs-0301: Naming for domains/groups/roles/project when onboarding new customers","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iam/scs-0302":{"id":"iam/scs-0302","title":"scs-0302: Domain Manager configuration for Keystone","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"index":{"id":"index","title":"Introduction","description":"The Sovereign Cloud Stack (SCS) is a community-driven project that curates a set of standards\u2014including both existing standards, such as the OpenInfra interoperability guides or the CNCF Kubernetes conformance, and newly created ones\u2014to enable and ensure compatibility, openness, and sovereignty of cloud services across a wide range of providers, particularly small and medium businesses.","sidebar":"standards"},"kaas/index":{"id":"kaas/index","title":"KaaS Standards","description":"Standards in this track are concerned with Kubernetes as a Service layer, outlining norms and best practices for deploying, managing, and operating Kubernetes clusters. These standards aim to ensure that the orchestration of containers is streamlined, secure, and compatible across various cloud environments and platforms.","sidebar":"standards"},"kaas/scs-0200":{"id":"kaas/scs-0200","title":"scs-0200: Using Sonobuoy for KaaS conformance tests","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0210":{"id":"kaas/scs-0210","title":"scs-0210: SCS K8S Version Policy","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0211":{"id":"kaas/scs-0211","title":"scs-0211: SCS KaaS default storage class","description":"The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).","sidebar":"standards"},"kaas/scs-0212":{"id":"kaas/scs-0212","title":"scs-0212: Requirements for container registries","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0213":{"id":"kaas/scs-0213","title":"scs-0213: Kubernetes Nodes Anti Affinity","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0214":{"id":"kaas/scs-0214","title":"scs-0214: Kubernetes Node Distribution and Availability","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0215":{"id":"kaas/scs-0215","title":"scs-0215: Robustness features for Kubernetes clusters","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0216":{"id":"kaas/scs-0216","title":"scs-0216: Requirements for testing cluster-stacks","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0217":{"id":"kaas/scs-0217","title":"scs-0217: Kubernetes cluster hardening","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0218":{"id":"kaas/scs-0218","title":"scs-0218: Container registry for SCS standard implementation","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0219":{"id":"kaas/scs-0219","title":"scs-0219: KaaS Networking Standard","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/index":{"id":"ops/index","title":"Ops Standards","description":"Operational Tooling Standards cover the protocols and guidelines associated with tools and utilities used for monitoring, management, and maintenance of the cloud environment. This includes standards for status pages, alerts, logs, and other operational tools, aiming to optimize the reliability, performance, and security of cloud services and resources.","sidebar":"standards"},"ops/scs-0400":{"id":"ops/scs-0400","title":"scs-0400: Status Page create decision","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/scs-0401":{"id":"ops/scs-0401","title":"scs-0401: Status page reference implementation decision","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/scs-0402":{"id":"ops/scs-0402","title":"scs-0402: Status page OpenAPI decision","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/scs-0403":{"id":"ops/scs-0403","title":"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/scs-0410":{"id":"ops/scs-0410","title":"scs-0410: Gnocchi as database for metering","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/scs-0411":{"id":"ops/scs-0411","title":"scs-0411: Push-based approach for providing usage data","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/scs-0412":{"id":"ops/scs-0412","title":"scs-0412: Exposition of IaaS metering data as JSON","description":"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format","sidebar":"standards"},"scs-0001-v1-sovereign-cloud-standards":{"id":"scs-0001-v1-sovereign-cloud-standards","title":"Sovereign Cloud Standards","description":"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision\\nrecords within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in\\nthe development and maintenance of interoperable and transparent cloud infrastructure standards.\\n","sidebar":"standards"},"scs-0002-v1-standards-docs-org":{"id":"scs-0002-v1-standards-docs-org","title":"Standards, Docs and Organisation","description":"Introduction","sidebar":"standards"},"scs-0002-v2-standards-docs-org":{"id":"scs-0002-v2-standards-docs-org","title":"SCS Documentation structure","description":"SCS-0002 outlines the standardized structure and maintenance processes for easily accessible and\\ncomprehensible content of the SCS project.\\n","sidebar":"standards"},"scs-0003-v1-sovereign-cloud-standards-yaml":{"id":"scs-0003-v1-sovereign-cloud-standards-yaml","title":"Sovereign Cloud Standards YAML","description":"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,\\ncategorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning\\nin a machine-readable YAML format for clarity, traceability, and tool integration.\\n","sidebar":"standards"},"scs-0004-v1-achieving-certification":{"id":"scs-0004-v1-achieving-certification","title":"Regulations for achieving SCS-compatible certification","description":"Introduction","sidebar":"standards"},"scs-0005-v1-project-governance":{"id":"scs-0005-v1-project-governance","title":"Governance of the SCS community","description":"SCS-0005 outlines the structure and governance of the SCS community by the SCS Project Board and how this is elected.\\n","sidebar":"standards"},"scs-0100-v1-flavor-naming":{"id":"scs-0100-v1-flavor-naming","title":"SCS Flavor Naming Standard","description":"Introduction","sidebar":"standards"},"scs-0100-v2-flavor-naming":{"id":"scs-0100-v2-flavor-naming","title":"SCS Flavor Naming Standard","description":"Introduction","sidebar":"standards"},"scs-0100-v3-flavor-naming":{"id":"scs-0100-v3-flavor-naming","title":"SCS Flavor Naming Standard","description":"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack\\nenvironments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM,\\nand Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for\\nusability and portability across all SCS flavors.\\n","sidebar":"standards"},"scs-0100-w1-flavor-naming-implementation-testing":{"id":"scs-0100-w1-flavor-naming-implementation-testing","title":"SCS Flavor Naming Standard: Implementation and Testing Notes","description":"Introduction","sidebar":"standards"},"scs-0101-v1-entropy":{"id":"scs-0101-v1-entropy","title":"SCS Entropy","description":"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations\\nsuch as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and\\nactivating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy\\naccessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into\\nvirtual instances and ensures the availability and quality of entropy in virtual environments, promoting system\\nsecurity and efficiency.\\n","sidebar":"standards"},"scs-0101-w1-entropy-implementation-testing":{"id":"scs-0101-w1-entropy-implementation-testing","title":"SCS Entropy: Implementation and Testing Notes","description":"Implementation notes","sidebar":"standards"},"scs-0102-v1-image-metadata":{"id":"scs-0102-v1-image-metadata","title":"SCS Image Metadata","description":"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating\\nsystem images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements,\\nimage handling protocols including updating and origin, and licensing/support details. These guidelines ensure\\nthat users can understand, access, and utilize OS images effectively, with clear information on features, updates,\\nand licensing provided through well-defined metadata properties.\\n","sidebar":"standards"},"scs-0102-w1-image-metadata-implementation-testing":{"id":"scs-0102-w1-image-metadata-implementation-testing","title":"SCS Image Metadata: Implementation and Testing Notes","description":"Implementation notes","sidebar":"standards"},"scs-0103-v1-standard-flavors":{"id":"scs-0103-v1-standard-flavors","title":"SCS Standard Flavors and Properties","description":"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack\\nenvironments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific\\nconfigurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs:name-vN, scs:cpu-type,\\nand scs:diskN-type to detail the flavor\'s specifications. This standard facilitates guaranteed availability and\\nconsistency of flavors, simplifying the deployment process for DevOps teams.\\n","sidebar":"standards"},"scs-0104-v1-standard-images":{"id":"scs-0104-v1-standard-images","title":"SCS Standard Images","description":"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,\\nspecifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined\\ndeployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard\'s\\nmachine-readable document facilitates automated processing for compliance and integration purposes, promoting\\nconsistency and reliability in cloud environments.\\n","sidebar":"standards"},"scs-0104-w1-standard-images-implementation":{"id":"scs-0104-w1-standard-images-implementation","title":"SCS Standard Images: Implementation Notes","description":"Introduction","sidebar":"standards"},"scs-0110-v1-ssd-flavors":{"id":"scs-0110-v1-ssd-flavors","title":"SSD Flavors","description":"Introduction","sidebar":"standards"},"scs-0111-v1-volume-type-decisions":{"id":"scs-0111-v1-volume-type-decisions","title":"Decisions for the Volume Type Standard","description":"Introduction","sidebar":"standards"},"scs-0112-v1-sonic":{"id":"scs-0112-v1-sonic","title":"SONiC Support in SCS","description":"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.\\n","sidebar":"standards"},"scs-0113-v1-security-groups-decision-record":{"id":"scs-0113-v1-security-groups-decision-record","title":"Security Groups Decision Record","description":"Introduction","sidebar":"standards"},"scs-0114-v1-volume-type-standard":{"id":"scs-0114-v1-volume-type-standard","title":"SCS Volume Types","description":"Introduction","sidebar":"standards"},"scs-0115-v1-default-rules-for-security-groups":{"id":"scs-0115-v1-default-rules-for-security-groups","title":"Default Rules for Security Groups","description":"Introduction","sidebar":"standards"},"scs-0116-v1-key-manager-standard":{"id":"scs-0116-v1-key-manager-standard","title":"SCS Key Manager Standard","description":"Introduction","sidebar":"standards"},"scs-0116-w1-key-manager-implementation-testing":{"id":"scs-0116-w1-key-manager-implementation-testing","title":"SCS Key Manager Standard: Implementation and Testing Notes","description":"Implementation","sidebar":"standards"},"scs-0117-v1-volume-backup-service":{"id":"scs-0117-v1-volume-backup-service","title":"Volume Backup Functionality","description":"Introduction","sidebar":"standards"},"scs-0118-v1-taxonomy-of-failsafe-levels":{"id":"scs-0118-v1-taxonomy-of-failsafe-levels","title":"SCS Taxonomy of Failsafe Levels","description":"Abstract","sidebar":"standards"},"scs-0118-w1-example-impacts-of-failure-scenarios":{"id":"scs-0118-w1-example-impacts-of-failure-scenarios","title":"SCS Taxonomy of Failsafe Levels: Examples of Failure Cases and their impact on IaaS and KaaS resources","description":"Examples of the impact from certain failure scenarios on Cloud Resources","sidebar":"standards"},"scs-0119-v1-rook-decision":{"id":"scs-0119-v1-rook-decision","title":"Replacement of the deprecated ceph-ansible tool","description":"Abstract","sidebar":"standards"},"scs-0120-v1-capi-images":{"id":"scs-0120-v1-capi-images","title":"Cluster-API images","description":"Abstract","sidebar":"standards"},"scs-0121-v1-Availability-Zones-Standard":{"id":"scs-0121-v1-Availability-Zones-Standard","title":"SCS Availability Zones","description":"Introduction","sidebar":"standards"},"scs-0121-w1-Availability-Zones-Standard":{"id":"scs-0121-w1-Availability-Zones-Standard","title":"SCS Availability Zones: Implementation and Testing Notes","description":"Automated Tests","sidebar":"standards"},"scs-0122-v1-node-to-node-encryption":{"id":"scs-0122-v1-node-to-node-encryption","title":"_End-to-End Encryption between Customer Workloads_","description":"Abstract","sidebar":"standards"},"scs-0123-v1-mandatory-and-supported-IaaS-services":{"id":"scs-0123-v1-mandatory-and-supported-IaaS-services","title":"Mandatory and Supported IaaS Services","description":"Introduction","sidebar":"standards"},"scs-0124-v1-security-of-iaas-service-software":{"id":"scs-0124-v1-security-of-iaas-service-software","title":"Standard for the security of IaaS service software","description":"Introduction","sidebar":"standards"},"scs-0124-w1-security-of-iaas-service-software":{"id":"scs-0124-w1-security-of-iaas-service-software","title":"SCS Standard for the security of IaaS service software: Implementation and Testing Notes","description":"Testing or Detecting security updates in software","sidebar":"standards"},"scs-0125-v1-secure-connections":{"id":"scs-0125-v1-secure-connections","title":"Secure Connections","description":"Introduction","sidebar":"standards"},"scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests":{"id":"scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","title":"Using Sonobuoy for KaaS conformance tests","description":"Motivation","sidebar":"standards"},"scs-0210-v1-k8s-new-version-policy":{"id":"scs-0210-v1-k8s-new-version-policy","title":"SCS K8S Version Policy for new Kubernetes versions","description":"The SCS-0210 standard outlines the expected pace at which providers should adopt new Kubernetes versions, aiming\\nfor alignment with the rapid development cycle of Kubernetes. Providers must offer the latest minor version within\\nfour months of its release and the newest patch version within a week, ensuring users have timely access to security\\nupdates, bug fixes, and features. The standard emphasizes the need for expedited updates for critical CVEs and\\nexpects providers to thoroughly test new versions before deployment.\\n","sidebar":"standards"},"scs-0210-v2-k8s-version-policy":{"id":"scs-0210-v2-k8s-version-policy","title":"SCS K8S Version Policy","description":"Introduction","sidebar":"standards"},"scs-0210-w1-k8s-version-policy-implementation-testing":{"id":"scs-0210-w1-k8s-version-policy-implementation-testing","title":"SCS K8S Version Policy: Implementation and Testing Notes","description":"Implementation notes","sidebar":"standards"},"scs-0211-v1-kaas-default-storage-class":{"id":"scs-0211-v1-kaas-default-storage-class","title":"SCS KaaS default storage class","description":"The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).\\nThe standard ensures that the default StorageClass, identified by the \\"storageclass.kubernetes.io/is-default-class\\"\\nannotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or\\nhost hardware failures.\\n","sidebar":"standards"},"scs-0211-v2-kaas-default-storage-class":{"id":"scs-0211-v2-kaas-default-storage-class","title":"SCS KaaS default storage class","description":"The SCS-0211 standard ensures that a default StorageClass with specific characteristics is available to KaaS users.\\n","sidebar":"standards"},"scs-0211-w1-kaas-default-storage-class-implementation-testing":{"id":"scs-0211-w1-kaas-default-storage-class-implementation-testing","title":"SCS KaaS default storage class: Implementation and Testing Notes","description":"Implementation notes","sidebar":"standards"},"scs-0212-v1-requirements-for-container-registries":{"id":"scs-0212-v1-requirements-for-container-registries","title":"Requirements for container registries","description":"Introduction","sidebar":"standards"},"scs-0213-v1-k8s-nodes-anti-affinity":{"id":"scs-0213-v1-k8s-nodes-anti-affinity","title":"Kubernetes Nodes Anti Affinity","description":"Introduction","sidebar":"standards"},"scs-0214-v1-k8s-node-distribution":{"id":"scs-0214-v1-k8s-node-distribution","title":"Kubernetes Node Distribution and Availability","description":"Introduction","sidebar":"standards"},"scs-0214-v2-k8s-node-distribution":{"id":"scs-0214-v2-k8s-node-distribution","title":"Kubernetes Node Distribution and Availability","description":"Introduction","sidebar":"standards"},"scs-0214-w1-k8s-node-distribution-implementation-testing":{"id":"scs-0214-w1-k8s-node-distribution-implementation-testing","title":"Kubernetes Node Distribution and Availability: Implementation and Testing Notes","description":"Implementation notes","sidebar":"standards"},"scs-0215-v1-robustness-features":{"id":"scs-0215-v1-robustness-features","title":"Robustness features for Kubernetes clusters","description":"Introduction","sidebar":"standards"},"scs-0216-v1-requirements-for-testing-cluster-stacks":{"id":"scs-0216-v1-requirements-for-testing-cluster-stacks","title":"Requirements for testing cluster-stacks","description":"Introduction","sidebar":"standards"},"scs-0217-v1-cluster-hardening":{"id":"scs-0217-v1-cluster-hardening","title":"Kubernetes cluster hardening","description":"Introduction","sidebar":"standards"},"scs-0218-v1-container-registry-for-scs-standard-implementation":{"id":"scs-0218-v1-container-registry-for-scs-standard-implementation","title":"Container registry for SCS standard implementation","description":"Introduction","sidebar":"standards"},"scs-0219-v1-kaas-networking":{"id":"scs-0219-v1-kaas-networking","title":"KaaS Networking Standard","description":"Introduction","sidebar":"standards"},"scs-0219-w1-kaas-networking":{"id":"scs-0219-w1-kaas-networking","title":"KaaS Networking Standard: Implementation Notes","description":"List of compliant CNI Plugins","sidebar":"standards"},"scs-0300-v1-requirements-for-sso-identity-federation":{"id":"scs-0300-v1-requirements-for-sso-identity-federation","title":"Requirements for SSO identity federation","description":"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign\\nCloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed\\nexternally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard\\nfocuses on delegating authentication to external identity providers and mapping users to roles within SCS for\\nauthorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity\\nProvider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible.\\n","sidebar":"standards"},"scs-0301-v1-naming-conventions":{"id":"scs-0301-v1-naming-conventions","title":"Naming for domains/groups/roles/project when onboarding new customers","description":"\x3c!---","sidebar":"standards"},"scs-0302-v1-domain-manager-role":{"id":"scs-0302-v1-domain-manager-role","title":"Domain Manager configuration for Keystone","description":"Introduction","sidebar":"standards"},"scs-0302-w1-domain-manager-implementation-notes":{"id":"scs-0302-w1-domain-manager-implementation-notes","title":"Domain Manager implementation notes","description":"Implementation notes","sidebar":"standards"},"scs-0400-v1-status-page-create-decision":{"id":"scs-0400-v1-status-page-create-decision","title":"Status Page create decision","description":"Introduction","sidebar":"standards"},"scs-0401-v1-status-page-reference-implementation-decision":{"id":"scs-0401-v1-status-page-reference-implementation-decision","title":"Status page reference implementation decision","description":"Introduction","sidebar":"standards"},"scs-0402-v1-status-page-openapi-spec-decision":{"id":"scs-0402-v1-status-page-openapi-spec-decision","title":"Status page OpenAPI decision","description":"Introduction","sidebar":"standards"},"scs-0403-v1-csp-kaas-observability-stack":{"id":"scs-0403-v1-csp-kaas-observability-stack","title":"Architecture for the Cloud Service provider Observability System for the KaaS Layer","description":"Introduction","sidebar":"standards"},"scs-0410-v1-gnocchi-as-metering-database":{"id":"scs-0410-v1-gnocchi-as-metering-database","title":"Gnocchi as database for metering","description":"for more info. --\x3e","sidebar":"standards"},"scs-0411-v1-publishing_method_for_metering_data":{"id":"scs-0411-v1-publishing_method_for_metering_data","title":"Push-based approach for providing usage data","description":"for more info. --\x3e","sidebar":"standards"},"scs-0412-v1-metering-json":{"id":"scs-0412-v1-metering-json","title":"Exposition of IaaS metering data as JSON","description":"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format\\nwithin the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with\\ntheir existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format\\nprovided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation\\nlayers and implementation components.\\n","sidebar":"standards"},"scs-compatible-iaas":{"id":"scs-compatible-iaas","title":"SCS-compatible IaaS","description":"| Scope versions -> | v3 | v4 | v5.1 |","sidebar":"standards"},"scs-compatible-kaas":{"id":"scs-compatible-kaas","title":"SCS-compatible KaaS","description":"| Scope versions -> | v1 |","sidebar":"standards"},"scs-XXXX-vN-decision-record-template":{"id":"scs-XXXX-vN-decision-record-template","title":"_Descriptive title_","description":"\x3c!---"},"scs-XXXX-vN-standard-template":{"id":"scs-XXXX-vN-standard-template","title":"_Descriptive title_","description":"\x3c!---"},"standards/overview":{"id":"standards/overview","title":"Overview","description":"Standards are the core deliverable of SCS. By standardizing the open source software components of a cloud computing stack, their versions, how they are to be configured, deployed and utilized, SCS guarantees the reproducibility of a certain behavior of this technology.","sidebar":"standards"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/ffa81568.dc6a50d4.js b/assets/js/ffa81568.dc6a50d4.js new file mode 100644 index 0000000000..cac74149d2 --- /dev/null +++ b/assets/js/ffa81568.dc6a50d4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[79728],{20189:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"operating-scs/components/automated-pentesting-iaas/overview","title":"Overview","description":"Introdution","source":"@site/docs/04-operating-scs/components/automated-pentesting-iaas/overview.md","sourceDirName":"04-operating-scs/components/automated-pentesting-iaas","slug":"/operating-scs/components/automated-pentesting-iaas/overview","permalink":"/docs/operating-scs/components/automated-pentesting-iaas/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/automated-pentesting-iaas/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Pentesting IaaS","permalink":"/docs/category/pentesting-iaas"},"next":{"title":"Quickstart","permalink":"/docs/operating-scs/components/automated-pentesting-iaas/quickstart"}}');var s=n(74848),r=n(28453);const o={},a="Overview",c={},l=[{value:"Introdution",id:"introdution",level:2},{value:"Cloud Security Concerns",id:"cloud-security-concerns",level:2},{value:"SCS automated pentesting",id:"scs-automated-pentesting",level:2},{value:"Quickstart Guide",id:"quickstart-guide",level:2},{value:"Tools",id:"tools",level:2},{value:"Source",id:"source",level:2}];function d(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,s.jsx)(t.h2,{id:"introdution",children:"Introdution"}),"\n",(0,s.jsx)(t.p,{children:"Modern cloud infrastructure security is a complex and critical aspect of maintaining robust and resilient cloud services. Moreover, as organizations increasingly rely on cloud environments for their operations, the security of these infrastructures becomes paramount."}),"\n",(0,s.jsx)(t.p,{children:"The SCS Software stack, and more specifically its Infrastructure-as-a-Service layer, is susceptible to various security threats, including but not limited to misconfigurations, vulnerabilities and external attacks. To address these concerns, continuous and automated security testing is essential."}),"\n",(0,s.jsx)(t.h2,{id:"cloud-security-concerns",children:"Cloud Security Concerns"}),"\n",(0,s.jsx)(t.p,{children:"Cloud infrastructure security involves protecting data, applications, and services from unauthorized access and threats. Key concerns include:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Data Breaches"}),": Unauthorized access to sensitive data."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Misconfigurations"}),": Incorrect settings that expose systems to vulnerabilities."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Compliance Violations"}),": Failure to meet regulatory and industry standards."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Advanced Persistent Threats (APTs)"}),": Prolonged and targeted cyber-attacks."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Insider Threats"}),": Malicious actions by authorized users."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"To mitigate these risks, security practices like Static Application Security Testing (SAST) and Dynamic Application Security Testing (DAST) are employed. However, if you look at it from an automation perspective, a basic distinction of tooling is needed to be considered:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:"SAST involves analyzing the source code, bytecode, or binary code of applications to identify vulnerabilities without executing them. It helps in detecting issues like SQL injection, XSS, and other code-related vulnerabilities early in the development lifecycle."}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:"DAST involves testing the application in its running state, as well as deployed infrastructure, to identify vulnerabilities that could be exploited in real-time. It focuses on the application's exposed interfaces and is crucial for detecting issues like authentication problems, server misconfigurations, and injection flaws."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"In this project we solely focus on DAST."}),"\n",(0,s.jsx)(t.h2,{id:"scs-automated-pentesting",children:"SCS automated pentesting"}),"\n",(0,s.jsx)(t.p,{children:"The automated pentesting pipeline is based on a proposed methodology for the Sovereign Cloud Stack community. It integrates state-of-the-art tools to conduct dynamic security testing and ensure continuous security assurance for SCS based cloud infrastructures."}),"\n",(0,s.jsx)(t.p,{children:"The pipeline has been developed from a DevSecOps perspective, which ensures that security is deeply embedded into the fabric of the cloud infrastructure. It aligns with the following principles:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Integrated Security Testing"}),": The pipeline integrates DAST tools directly into the workflow managed by SCS Zuul. This ensures that every target is automatically tested for security vulnerabilities."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Continuous Monitoring"}),": Scheduled daily and weekly scans maintain continuous oversight of the infrastructure\u2019s security posture, ensuring that any new vulnerabilities are quickly identified and addressed."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Automated Feedback Loop"}),": The results from security tests are automatically fed back to the a central vulnerabilities repository, enabling quick remediation and continuous improvement."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Cultural Shift"}),": By adopting a DevSecOps approach, the pipeline fosters a culture where security is a shared responsibility, encouraging all team members to prioritize and contribute to security efforts."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Following this approach, each each tool has it's own use case and they build up onto each other over two different pipelines: A fast daily scan and a comprehensive weekly scan."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Naabu"})," -> Identify open ports"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Httpx"})," -> Identify web services from previous result"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Nuclei"})," -> Scan web services based on community templates"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"ZAP Proxy"})," -> Scan web services based on OWASP rulesets"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Greenbone"})," Community Edition (OpenVAS) -> Full scan targets"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Defect Dojo"})," -> Vulnerabilities management"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"scs_automated_pentesting_workflow.png",src:n(30285).A+"",width:"1024",height:"768"})}),"\n",(0,s.jsx)(t.p,{children:"Color meaning:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Green: Daily triggered pipeline"}),"\n",(0,s.jsx)(t.li,{children:"Blue: Weekly triggered pipeline"}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"quickstart-guide",children:"Quickstart Guide"}),"\n",(0,s.jsxs)(t.p,{children:["See ",(0,s.jsx)(t.a,{href:"/docs/operating-scs/components/automated-pentesting-iaas/quickstart",children:"the quickstart page"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"tools",children:"Tools"}),"\n",(0,s.jsxs)(t.p,{children:["See ",(0,s.jsx)(t.a,{href:"/docs/operating-scs/components/automated-pentesting-iaas/tools",children:"the tools page"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"source",children:"Source"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/security-infra-scan-pipeline",children:"github.com/SovereignCloudStack/security-infra-scan-pipeline"}),"."]})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},30285:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/scs_automated_pentesting_workflow-14a9ffdbf77267915ddcc95b954c4f1a.png"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var i=n(96540);const s={},r=i.createContext(s);function o(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ffd7fd32.5a60c8df.js b/assets/js/ffd7fd32.5a60c8df.js new file mode 100644 index 0000000000..58f7d3d386 --- /dev/null +++ b/assets/js/ffd7fd32.5a60c8df.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[31525],{10367:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"contributor-docs"}')}}]); \ No newline at end of file diff --git a/assets/js/fff06078.afa5a33b.js b/assets/js/fff06078.afa5a33b.js new file mode 100644 index 0000000000..1a9c1c6cad --- /dev/null +++ b/assets/js/fff06078.afa5a33b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[92710],{18902:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>l,frontMatter:()=>i,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"iaas/guides/concept-guide/components/k3s","title":"K3S","description":"Lifecycle Management of K3S in OSISM","source":"@site/docs/02-iaas/guides/concept-guide/components/k3s.md","sourceDirName":"02-iaas/guides/concept-guide/components","slug":"/iaas/guides/concept-guide/components/k3s","permalink":"/docs/iaas/guides/concept-guide/components/k3s","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/k3s.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Ironic","permalink":"/docs/iaas/guides/concept-guide/components/ironic"},"next":{"title":"Keycloak","permalink":"/docs/iaas/guides/concept-guide/components/keycloak"}}');var o=t(74848),c=t(28453);const i={},a="K3S",r={},d=[{value:"Lifecycle Management of K3S in OSISM",id:"lifecycle-management-of-k3s-in-osism",level:2}];function u(e){const n={h1:"h1",h2:"h2",header:"header",...(0,c.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"k3s",children:"K3S"})}),"\n",(0,o.jsx)(n.h2,{id:"lifecycle-management-of-k3s-in-osism",children:"Lifecycle Management of K3S in OSISM"})]})}function l(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var s=t(96540);const o={},c=s.createContext(o);function i(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fff9aecb.45d0c1ff.js b/assets/js/fff9aecb.45d0c1ff.js new file mode 100644 index 0000000000..e81c0dab7b --- /dev/null +++ b/assets/js/fff9aecb.45d0c1ff.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[53649],{19196:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>o,contentTitle:()=>n,default:()=>p,frontMatter:()=>d,metadata:()=>t,toc:()=>u});const t=JSON.parse('{"id":"iaas/guides/upgrade-guide/index","title":"Upgrade Guide","description":"In the examples, the pull of images (if supported by a role) is always run first. While","source":"@site/docs/02-iaas/guides/upgrade-guide/index.md","sourceDirName":"02-iaas/guides/upgrade-guide","slug":"/iaas/guides/upgrade-guide/","permalink":"/docs/iaas/guides/upgrade-guide/","draft":false,"unlisted":false,"editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/index.md","tags":[],"version":"current","sidebarPosition":20,"frontMatter":{"sidebar_label":"Upgrade Guide","sidebar_position":20},"sidebar":"docs","previous":{"title":"Testbed","permalink":"/docs/iaas/guides/deploy-guide/examples/testbed"},"next":{"title":"Manager","permalink":"/docs/iaas/guides/upgrade-guide/manager"}}');var a=s(74848),r=s(28453);const d={sidebar_label:"Upgrade Guide",sidebar_position:20},n="Upgrade Guide",o={},u=[];function c(e){const i={h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.header,{children:(0,a.jsx)(i.h1,{id:"upgrade-guide",children:"Upgrade Guide"})}),"\n",(0,a.jsx)(i.p,{children:"In the examples, the pull of images (if supported by a role) is always run first. While\nthis is optional, it is recommended to speed up the execution of the upgrade action in\nthe second step. This significantly reduces the times required for the restart from a\nservice."})]})}function p(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,a.jsx)(i,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,i,s)=>{s.d(i,{R:()=>d,x:()=>n});var t=s(96540);const a={},r=t.createContext(a);function d(e){const i=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function n(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),t.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/main.f32cb623.js b/assets/js/main.f32cb623.js new file mode 100644 index 0000000000..3124e56bf1 --- /dev/null +++ b/assets/js/main.f32cb623.js @@ -0,0 +1,2 @@ +/*! For license information please see main.f32cb623.js.LICENSE.txt */ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[38792],{35947:(e,t,n)=>{"use strict";n.d(t,{A:()=>p});n(96540);var s=n(53259),o=n.n(s),a=n(84054);const r={"0047ab5d":[()=>n.e(15058).then(n.bind(n,9691)),"@site/docs/02-iaas/guides/configuration-guide/services/index.md",9691],"0050251a":[()=>n.e(11945).then(n.bind(n,92732)),"@site/contributor-docs/index.md",92732],"0058b4c6":[()=>n.e(90849).then(n.t.bind(n,86164,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-175.json",86164],"0121636f":[()=>n.e(95752).then(n.bind(n,53466)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/project-manager.md",53466],"012688b3":[()=>n.e(55251).then(n.bind(n,56636)),"@site/docs/02-iaas/guides/concept-guide/hardware-bom.md",56636],"013c29c1":[()=>n.e(90923).then(n.bind(n,41984)),"@site/docs/04-operating-scs/components/monitoring/docs/zuul.md",41984],"01a85c17":[()=>Promise.all([n.e(71869),n.e(8209)]).then(n.bind(n,69158)),"@theme/BlogTagsListPage",69158],"03412b54":[()=>n.e(9382).then(n.bind(n,86925)),"@site/community/tools/github/dco-and-licenses.md",86925],"03babb4a":[()=>n.e(62294).then(n.bind(n,11141)),"@site/community/tools/github/tips-and-tricks.md",11141],"03c8668f":[()=>n.e(74507).then(n.bind(n,12092)),"@site/standards/ops/scs-0412.md",12092],"04437fec":[()=>n.e(59075).then(n.bind(n,85646)),"@site/standards/scs-0114-v1-volume-type-standard.md",85646],"0476f709":[()=>n.e(20344).then(n.bind(n,41031)),"@site/standards/scs-0215-v1-robustness-features.md",41031],"04fe2bfd":[()=>n.e(12106).then(n.bind(n,9142)),"@site/blog/2022-10-28-first-blog-post.md?truncated=true",9142],"05370f9a":[()=>n.e(92864).then(n.bind(n,10090)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks.md",10090],"05e7973d":[()=>n.e(89823).then(n.bind(n,91610)),"@site/docs/02-iaas/guides/configuration-guide/commons/sshconfig.md",91610],"061d8128":[()=>n.e(21009).then(n.bind(n,14643)),"@site/standards/scs-0100-v3-flavor-naming.md",14643],"066abe51":[()=>n.e(71351).then(n.bind(n,45690)),"@site/docs/02-iaas/guides/concept-guide/components/sonic.md",45690],"070e71f0":[()=>n.e(67255).then(n.bind(n,49851)),"@site/docs/02-iaas/guides/upgrade-guide/ceph.md",49851],"07d3bac7":[()=>n.e(30458).then(n.bind(n,62845)),"@site/standards/scs-0211-v1-kaas-default-storage-class.md",62845],"093291a8":[()=>n.e(51276).then(n.bind(n,39220)),"@site/standards/ops/scs-0411.md",39220],"0935f628":[()=>n.e(31036).then(n.bind(n,27162)),"@site/docs/04-operating-scs/components/status-page-openapi/docs/component_overview.md",27162],"09539d9b":[()=>n.e(7344).then(n.bind(n,43938)),"@site/standards/scs-0302-w1-domain-manager-implementation-notes.md",43938],"096c51c8":[()=>n.e(92544).then(n.bind(n,20738)),"@site/community/contribute/linting-guide.md",20738],"09adb968":[()=>n.e(6148).then(n.bind(n,28412)),"@site/docs/04-operating-scs/03-incident-management/index.md",28412],"09ba26e2":[()=>n.e(99244).then(n.bind(n,35186)),"@site/docs/02-iaas/guides/deploy-guide/index.md",35186],"09cf625e":[()=>n.e(53767).then(n.bind(n,35458)),"@site/docs/04-operating-scs/overview.md",35458],"0a757274":[()=>n.e(48296).then(n.bind(n,38344)),"@site/docs/02-iaas/overview/knowledge.md",38344],"0bb6d954":[()=>n.e(77479).then(n.bind(n,54341)),"@site/docs/02-iaas/guides/concept-guide/components/netdata.md",54341],"0bcc5672":[()=>n.e(1085).then(n.bind(n,20254)),"@site/docs/03-container/deployment-examples/a/software.md",20254],"0c1b7bd3":[()=>n.e(20717).then(n.t.bind(n,30746,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-central-api-131.json",30746],"0c2cbcc3":[()=>n.e(23786).then(n.bind(n,3908)),"@site/docs/04-operating-scs/components/status-page-web/docs/contribute.md",3908],"0cb1d654":[()=>n.e(36182).then(n.bind(n,35720)),"@site/docs/04-operating-scs/components/monitoring/docs/overview.md",35720],"0d2860b1":[()=>n.e(67148).then(n.bind(n,59042)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/image-manager/update.md",59042],"0dfeccb2":[()=>n.e(94342).then(n.bind(n,63532)),"@site/standards/scs-0410-v1-gnocchi-as-metering-database.md",63532],"0e4c395f":[()=>n.e(33384).then(n.bind(n,11325)),"@site/docs/04-operating-scs/components/monitoring/docs/scs-deployment.md",11325],"0ea173ba":[()=>n.e(75341).then(n.bind(n,39651)),"@site/standards/certification/overview.md",39651],"0eef3953":[()=>n.e(78423).then(n.bind(n,94850)),"@site/standards/scs-0121-v1-Availability-Zones-Standard.md",94850],"0f0de498":[()=>n.e(75013).then(n.bind(n,30859)),"@site/docs/02-iaas/guides/configuration-guide/openstack/designate.md",30859],"0f1ad89c":[()=>n.e(46347).then(n.bind(n,9801)),"@site/docs/04-operating-scs/components/status-page-deployment/docs/requirements.md",9801],"0fd39870":[()=>n.e(42140).then(n.bind(n,86062)),"@site/docs/04-operating-scs/components/status-page-api/docs/requests.md",86062],"1109f10b":[()=>n.e(13605).then(n.bind(n,16538)),"@site/standards/scs-0110-v1-ssd-flavors.md",16538],"119c53e5":[()=>n.e(58407).then(n.bind(n,65572)),"@site/docs/02-iaas/guides/configuration-guide/commons/user.md",65572],"1276f6ab":[()=>n.e(44684).then(n.bind(n,29973)),"@site/standards/scs-0411-v1-publishing_method_for_metering_data.md",29973],"1300cb4e":[()=>n.e(86273).then(n.bind(n,67601)),"@site/standards/scs-0104-w1-standard-images-implementation.md",67601],"130ed5c1":[()=>n.e(19303).then(n.bind(n,89069)),"@site/standards/scs-0125-v1-secure-connections.md",89069],"137a0b1a":[()=>n.e(27379).then(n.bind(n,13669)),"@site/docs/04-operating-scs/components/scs-health-monitor/Testflow.md",13669],"138e0e15":[()=>n.e(64921).then(n.t.bind(n,41597,19)),"@generated/@easyops-cn/docusaurus-search-local/default/__plugin.json",41597],"14a658e6":[()=>n.e(55235).then(n.bind(n,2582)),"@site/user-docs/index.md",2582],"14eb3368":[()=>Promise.all([n.e(71869),n.e(46969)]).then(n.bind(n,34136)),"@theme/DocCategoryGeneratedIndexPage",34136],"15e4a743":[()=>n.e(85609).then(n.bind(n,45155)),"@site/docs/04-operating-scs/02-monitoring/index.md",45155],"16c50622":[()=>n.e(14712).then(n.bind(n,36703)),"@site/docs/02-iaas/guides/configuration-guide/validations/index.md",36703],"16ee6b7c":[()=>n.e(34826).then(n.t.bind(n,40227,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-guides-2-743.json",40227],"1722e234":[()=>n.e(71255).then(n.bind(n,16888)),"@site/community/cloud-resources/cloud-resources.md",16888],17896441:[()=>Promise.all([n.e(71869),n.e(43498),n.e(18401)]).then(n.bind(n,30833)),"@theme/DocItem",30833],"178df98e":[()=>n.e(98029).then(n.bind(n,93784)),"@site/standards/ops/index.md",93784],"184e5ead":[()=>n.e(60988).then(n.bind(n,58912)),"@site/standards/iaas/scs-0102.md",58912],"193dc870":[()=>n.e(98220).then(n.bind(n,59241)),"@site/docs/02-iaas/guides/concept-guide/components/teleport.md",59241],"1967361e":[()=>n.e(24485).then(n.bind(n,42964)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/sandbox-manager.md",42964],"19afbcc8":[()=>n.e(14840).then(n.bind(n,83164)),"@site/docs/01-getting-started/overview.md",83164],"19cb43cd":[()=>n.e(11572).then(n.bind(n,15030)),"@site/docs/03-container/components/container-registry/docs/upgrade.md",15030],"19e9bde5":[()=>n.e(64175).then(n.bind(n,30638)),"@site/docs/04-operating-scs/components/monitoring/docs/quickstart.md",30638],"19f6a518":[()=>n.e(33444).then(n.bind(n,91976)),"@site/community/mission-statement.md",91976],"1a4e3797":[()=>Promise.all([n.e(71869),n.e(62138)]).then(n.bind(n,41283)),"@theme/SearchPage",41283],"1bb8290c":[()=>n.e(53652).then(n.t.bind(n,42204,19)),"@generated/docusaurus-plugin-content-docs/community/p/community-category-contribute-to-docs-2c7.json",42204],"1bc22123":[()=>n.e(14111).then(n.bind(n,35212)),"@site/docs/06-releases/ReleaseX.md",35212],"1bc8ea4c":[()=>n.e(8514).then(n.bind(n,18421)),"@site/docs/02-iaas/guides/concept-guide/nodes.md",18421],"1c894279":[()=>n.e(81804).then(n.bind(n,31490)),"@site/standards/scs-0001-v1-sovereign-cloud-standards.md",31490],"1c94670e":[()=>n.e(82336).then(n.t.bind(n,31671,19)),"@generated/docusaurus-plugin-content-docs/user-docs/p/user-docs-category-opendesk-on-scs-eaa.json",31671],"1ca0f8e7":[()=>n.e(37810).then(n.bind(n,93817)),"@site/docs/03-container/components/container-registry/docs/scs-deployment.md",93817],"1df93b7f":[()=>Promise.all([n.e(71869),n.e(34583)]).then(n.bind(n,68198)),"@site/src/pages/index.tsx",68198],"1e818dbe":[()=>n.e(41335).then(n.bind(n,30920)),"@site/community/tools/nextcloud.md",30920],"1f34ee25":[()=>n.e(53894).then(n.bind(n,16030)),"@site/community/cloud-resources/wavestack.md",16030],"20da611c":[()=>n.e(17491).then(n.bind(n,80903)),"@site/docs/04-operating-scs/components/monitoring/docs/k3s.md",80903],22869887:[()=>n.e(62673).then(n.bind(n,9485)),"@site/standards/global/scs-0005.md",9485],"22aa5ce0":[()=>n.e(66910).then(n.bind(n,4814)),"@site/standards/ops/scs-0403.md",4814],"23c48947":[()=>n.e(3813).then(n.bind(n,7938)),"@site/standards/iaas/scs-0124.md",7938],"23d0e2bb":[()=>n.e(16323).then(n.bind(n,98808)),"@site/standards/iaas/scs-0114.md",98808],"23e62f09":[()=>n.e(68966).then(n.bind(n,17828)),"@site/standards/iam/scs-0300.md",17828],"25cf6706":[()=>n.e(97104).then(n.bind(n,46305)),"@site/docs/02-iaas/guides/configuration-guide/openstack/octavia.md",46305],"26bc5a46":[()=>n.e(32914).then(n.bind(n,65916)),"@site/docs/02-iaas/guides/upgrade-guide/docker.md",65916],"26c6a551":[()=>n.e(75804).then(n.bind(n,50145)),"@site/standards/certification/overview.template.md",50145],"26dd306b":[()=>n.e(52342).then(n.bind(n,6738)),"@site/docs/02-iaas/guides/other-guides/index.md",6738],"26ef8bfb":[()=>n.e(43848).then(n.t.bind(n,47388,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-deployment-c9b.json",47388],"27e03890":[()=>n.e(22339).then(n.bind(n,66083)),"@site/standards/scs-0219-w1-kaas-networking.md",66083],"27f24dfd":[()=>n.e(14132).then(n.bind(n,92947)),"@site/standards/scs-0214-v1-k8s-node-distribution.md",92947],"287cd167":[()=>n.e(13043).then(n.bind(n,64737)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart.md",64737],"2886628e":[()=>n.e(37778).then(n.bind(n,7338)),"@site/community/tools/github/branchprotection.md",7338],"28c03198":[()=>n.e(11935).then(n.bind(n,7281)),"@site/standards/scs-0124-w1-security-of-iaas-service-software.md",7281],"28d842ee":[()=>n.e(73405).then(n.bind(n,74511)),"@site/standards/scs-0112-v1-sonic.md",74511],"28f8b1f8":[()=>n.e(21698).then(n.t.bind(n,3415,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-turnkey-solution-e74.json",3415],"291e1144":[()=>n.e(54644).then(n.bind(n,99121)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow.md",99121],"29c2cfba":[()=>n.e(98547).then(n.bind(n,46796)),"@site/community/contribute/doc-files-structure-guide.md",46796],"2ab96e79":[()=>n.e(23844).then(n.bind(n,56793)),"@site/docs/02-iaas/guides/other-guides/cloud-in-a-box/index.md",56793],"2abb9c6f":[()=>n.e(76372).then(n.bind(n,44107)),"@site/docs/02-iaas/guides/concept-guide/components/prometheus.md",44107],"2c0d30da":[()=>n.e(16218).then(n.bind(n,71307)),"@site/user-docs/application-examples/opendesk-on-scs/requirements.md",71307],"2c36e6c1":[()=>n.e(43136).then(n.bind(n,50370)),"@site/docs/turnkey-solution/overview.md",50370],"2cc9d448":[()=>n.e(83574).then(n.bind(n,95199)),"@site/docs/06-releases/Release6.md",95199],"2ce1dccd":[()=>n.e(91026).then(n.bind(n,58840)),"@site/docs/02-iaas/components/image-manager/index.md",58840],"2d071e49":[()=>n.e(60953).then(n.bind(n,70160)),"@site/docs/04-operating-scs/components/monitoring/docs/kaas.md",70160],"2e505a53":[()=>n.e(79089).then(n.t.bind(n,53179,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-monitoring-4ac.json",53179],"2ee7a08a":[()=>n.e(5658).then(n.bind(n,86628)),"@site/docs/02-iaas/guides/concept-guide/components/clusterapi.md",86628],"2f1a0bb3":[()=>n.e(16594).then(n.t.bind(n,78706,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-metering-51f.json",78706],"310c7ee8":[()=>n.e(80295).then(n.bind(n,49322)),"@site/standards/scs-0210-w1-k8s-version-policy-implementation-testing.md",49322],"315ee77a":[()=>n.e(78353).then(n.bind(n,31642)),"@site/docs/04-operating-scs/components/scs-health-monitor/overview.md",31642],"3180fd0e":[()=>n.e(78340).then(n.bind(n,62465)),"@site/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing.md",62465],"31d44bea":[()=>n.e(40935).then(n.bind(n,69676)),"@site/docs/04-operating-scs/components/scs-health-monitor/SetupObservabilityStack.md",69676],"31e2019b":[()=>n.e(13974).then(n.bind(n,98247)),"@site/docs/03-container/components/cluster-stacks/components/csctl/quickstart.md",98247],"320ccb30":[()=>n.e(67677).then(n.bind(n,18418)),"@site/docs/04-operating-scs/components/monitoring/docs/oauth.md",18418],"32227eef":[()=>n.e(53429).then(n.bind(n,84091)),"@site/standards/scs-0003-v1-sovereign-cloud-standards-yaml.md",84091],"32dcd940":[()=>n.e(86).then(n.bind(n,66607)),"@site/docs/02-iaas/guides/configuration-guide/openstack/placement.md",66607],"343a1afc":[()=>n.e(28965).then(n.bind(n,38735)),"@site/docs/04-operating-scs/06-logging/index.md",38735],"34c3e4b2":[()=>n.e(40163).then(n.bind(n,76129)),"@site/standards/iaas/scs-0115.md",76129],"34fc7a35":[()=>n.e(97399).then(n.bind(n,28478)),"@site/docs/03-container/components/cluster-stacks/components/csctl/overview.md",28478],"35b359a4":[()=>Promise.all([n.e(71869),n.e(27683)]).then(n.bind(n,35798)),"@site/docs/02-iaas/guides/other-guides/testbed.mdx",35798],"35fbae7a":[()=>n.e(91617).then(n.bind(n,24361)),"@site/community/cloud-resources/plusserver-gx-scs.md",24361],"36994c47":[()=>n.e(89858).then(n.t.bind(n,45516,19)),"@generated/docusaurus-plugin-content-blog/default/__plugin.json",45516],"36c47bdd":[()=>n.e(9766).then(n.bind(n,41284)),"@site/community/collaboration/team-ops.md",41284],"36d4bf8b":[()=>n.e(26590).then(n.bind(n,1273)),"@site/standards/scs-0121-w1-Availability-Zones-Standard.md",1273],"36f749d2":[()=>n.e(14602).then(n.bind(n,22905)),"@site/docs/04-operating-scs/04-audits/index.md",22905],"37a5cb6b":[()=>n.e(91384).then(n.bind(n,51727)),"@site/standards/ops/scs-0402.md",51727],"38c9ef35":[()=>n.e(13131).then(n.bind(n,35042)),"@site/standards/global/index.md",35042],"3a1d878d":[()=>n.e(78031).then(n.bind(n,72731)),"@site/docs/02-iaas/guides/concept-guide/components/openstack.md",72731],"3a2db09e":[()=>n.e(18121).then(n.t.bind(n,68070,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-df9.json",68070],"3a36ab0d":[()=>n.e(46125).then(n.bind(n,13383)),"@site/standards/scs-0214-w1-k8s-node-distribution-implementation-testing.md",13383],"3abbf0e9":[()=>n.e(80231).then(n.bind(n,81252)),"@site/docs/02-iaas/guides/operations-guide/rookify.md",81252],"3ad2c61e":[()=>n.e(38384).then(n.bind(n,45449)),"@site/docs/02-iaas/guides/concept-guide/components/ceph.md",45449],"3d19221e":[()=>n.e(3714).then(n.bind(n,984)),"@site/docs/02-iaas/guides/configuration-guide/commons/index.md",984],"3d9e0922":[()=>n.e(62069).then(n.bind(n,86460)),"@site/standards/ops/scs-0410.md",86460],"3e493f26":[()=>n.e(96029).then(n.bind(n,33171)),"@site/docs/02-iaas/overview/network.md",33171],"3f3928dc":[()=>n.e(43213).then(n.bind(n,43868)),"@site/standards/iaas/index.md",43868],"3ff13a62":[()=>n.e(55743).then(n.bind(n,40044)),"@site/docs/03-container/index.md",40044],"406caaae":[()=>n.e(26918).then(n.bind(n,36715)),"@site/docs/04-operating-scs/components/status-page-web/docs/overview.md",36715],"40d9468c":[()=>n.e(90783).then(n.bind(n,85281)),"@site/docs/02-iaas/guides/other-guides/developer-guide/index.md",85281],"41ab9761":[()=>n.e(45676).then(n.bind(n,80572)),"@site/docs/04-operating-scs/07-metering/meter_configuration.md",80572],"41be304a":[()=>n.e(90205).then(n.bind(n,28792)),"@site/standards/iaas/scs-0123.md",28792],"41f0af85":[()=>n.e(26608).then(n.bind(n,27843)),"@site/docs/04-operating-scs/components/status-page-deployment/docs/contribute.md",27843],"420452be":[()=>n.e(1911).then(n.bind(n,85763)),"@site/community/tools/matrix.md",85763],"422fff4b":[()=>n.e(86227).then(n.bind(n,29003)),"@site/standards/kaas/scs-0210.md",29003],"437bedbc":[()=>n.e(19745).then(n.bind(n,3904)),"@site/docs/06-releases/Release4.md",3904],"43915cdf":[()=>n.e(86512).then(n.bind(n,26589)),"@site/docs/04-operating-scs/components/status-page-deployment/docs/usage.md",26589],"440f3548":[()=>n.e(99417).then(n.bind(n,86105)),"@site/user-docs/application-examples/opendesk-on-scs/quickstart.md",86105],"441bd449":[()=>n.e(49851).then(n.bind(n,46333)),"@site/docs/02-iaas/guides/troubleshooting-guide/ceph.md",46333],"4468ebd1":[()=>n.e(98805).then(n.bind(n,45378)),"@site/blog/2022-10-28-first-blog-post.md",45378],"452be0ad":[()=>n.e(5546).then(n.bind(n,9840)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview.md",9840],"45bfeaeb":[()=>n.e(34257).then(n.bind(n,31020)),"@site/community/tools/zuul.md",31020],"45f4377b":[()=>n.e(68965).then(n.bind(n,9089)),"@site/docs/02-iaas/guides/deploy-guide/seed.md",9089],"46a1aa97":[()=>n.e(94561).then(n.t.bind(n,13083,19)),"@generated/docusaurus-plugin-content-docs/contributor-docs/p/contributor-docs-5fe.json",13083],"473bdf69":[()=>n.e(25930).then(n.bind(n,30941)),"@site/docs/04-operating-scs/components/status-page-deployment/docs/monitoring.md",30941],"477ed06d":[()=>n.e(93502).then(n.bind(n,6701)),"@site/standards/iaas/scs-0101.md",6701],"4913574b":[()=>n.e(99084).then(n.bind(n,27795)),"@site/docs/04-operating-scs/components/status-page-deployment/docs/overview.md",27795],49993131:[()=>n.e(28460).then(n.bind(n,62197)),"@site/docs/02-iaas/guides/other-guides/developer-guide/releases.md",62197],"49bc3785":[()=>n.e(8592).then(n.bind(n,53998)),"@site/community/hackathons/checklist.md",53998],"4a61a7c1":[()=>n.e(43705).then(n.bind(n,49837)),"@site/standards/kaas/scs-0200.md",49837],"4aabd97d":[()=>n.e(60183).then(n.bind(n,65729)),"@site/standards/scs-0214-v2-k8s-node-distribution.md",65729],"4b015924":[()=>n.e(52076).then(n.bind(n,4937)),"@site/docs/02-iaas/guides/deploy-guide/services/network.md",4937],"4d571bd0":[()=>n.e(29226).then(n.bind(n,30822)),"@site/docs/02-iaas/guides/configuration-guide/openstack/aodh.md",30822],"4e607b99":[()=>n.e(42441).then(n.bind(n,30968)),"@site/community/tools/jitsi.md",30968],"4e6fa974":[()=>n.e(70557).then(n.bind(n,2145)),"@site/standards/scs-0302-v1-domain-manager-role.md",2145],"4edc808e":[()=>Promise.all([n.e(71869),n.e(90308)]).then(n.bind(n,16215)),"@site/docs/index.mdx",16215],"4f2b2ca4":[()=>n.e(87915).then(n.t.bind(n,48889,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-components-909.json",48889],"4f363fd8":[()=>n.e(14605).then(n.bind(n,82815)),"@site/docs/02-iaas/guides/configuration-guide/openstack/cinder.md",82815],"500c8deb":[()=>n.e(73634).then(n.bind(n,8969)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow.md",8969],"502adbf6":[()=>n.e(48561).then(n.bind(n,42288)),"@site/docs/02-iaas/guides/index.md",42288],"5199876b":[()=>n.e(23008).then(n.bind(n,83629)),"@site/docs/02-iaas/guides/operations-guide/manager/get.md",83629],"5201921d":[()=>n.e(95369).then(n.t.bind(n,25312,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-components-1-cd2.json",25312],"526893f8":[()=>n.e(82346).then(n.bind(n,1981)),"@site/docs/02-iaas/guides/user-guide/openstack/openstackclient.md",1981],"526992cf":[()=>n.e(81475).then(n.bind(n,56815)),"@site/standards/scs-0103-v1-standard-flavors.md",56815],"52ac6bcf":[()=>n.e(47813).then(n.bind(n,10979)),"@site/standards/kaas/scs-0213.md",10979],"531f0326":[()=>n.e(21249).then(n.bind(n,42559)),"@site/docs/04-operating-scs/components/status-page-deployment/docs/faq.md",42559],"53cbe722":[()=>n.e(67768).then(n.bind(n,60210)),"@site/docs/04-operating-scs/components/status-page-deployment/docs/admin-authentication.md",60210],"53f25e30":[()=>n.e(80332).then(n.bind(n,53478)),"@site/docs/04-operating-scs/components/monitoring/docs/infrastructure_services.md",53478],"54451aca":[()=>n.e(1591).then(n.bind(n,42287)),"@site/standards/kaas/scs-0219.md",42287],"5447d460":[()=>n.e(83881).then(n.bind(n,30960)),"@site/standards/certification/scopes-versions.md",30960],"5565c8ed":[()=>n.e(62016).then(n.bind(n,647)),"@site/docs/02-iaas/guides/deploy-guide/examples/cloud-in-a-box.md",647],"55e21dcd":[()=>n.e(31810).then(n.bind(n,59684)),"@site/docs/04-operating-scs/components/monitoring/docs/tracing.md",59684],"56dd32bb":[()=>n.e(12473).then(n.t.bind(n,21687,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-pentesting-iaas-9a2.json",21687],"57b63ae3":[()=>Promise.all([n.e(71869),n.e(9539)]).then(n.bind(n,57858)),"@site/docs/02-iaas/guides/configuration-guide/manager.mdx",57858],"582db9b7":[()=>n.e(18872).then(n.t.bind(n,29033,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-automated-pentesting-101.json",29033],"589280f5":[()=>n.e(53530).then(n.bind(n,55034)),"@site/docs/02-iaas/guides/deploy-guide/services/infrastructure.md",55034],"58af14fe":[()=>Promise.all([n.e(71869),n.e(43745)]).then(n.bind(n,36075)),"@site/docs/02-iaas/guides/deploy-guide/services/rookify.md",36075],59307471:[()=>n.e(42637).then(n.bind(n,35350)),"@site/standards/kaas/scs-0211.md",35350],"5abd544f":[()=>n.e(1822).then(n.bind(n,84856)),"@site/standards/ops/scs-0401.md",84856],"5af709c8":[()=>n.e(46008).then(n.bind(n,40264)),"@site/docs/03-container/components/cluster-stacks/components/csctl/getting_started.md",40264],"5b235e06":[()=>n.e(58523).then(n.bind(n,81586)),"@site/docs/02-iaas/guides/other-guides/contributor-guide.md",81586],"5b402526":[()=>n.e(51001).then(n.bind(n,94365)),"@site/standards/scs-0002-v1-standards-docs-org.md",94365],"5b909c46":[()=>n.e(36707).then(n.bind(n,21081)),"@site/community/tools/mailinglists.md",21081],"5bd7bc3b":[()=>n.e(70643).then(n.bind(n,5549)),"@site/docs/02-iaas/guides/operations-guide/index.md",5549],"5c201b0a":[()=>n.e(2621).then(n.bind(n,19169)),"@site/docs/06-releases/Release3.md",19169],"5c2c818b":[()=>n.e(57153).then(n.bind(n,98e3)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/image-manager/index.md",98e3],"5c8ebdd1":[()=>n.e(23953).then(n.bind(n,20563)),"@site/docs/04-operating-scs/components/automated-pentesting-kaas/overview.md",20563],"5cc619f0":[()=>Promise.all([n.e(71869),n.e(2049),n.e(49648)]).then(n.bind(n,87866)),"@site/community/collaboration/index.mdx",87866],"5d51a55a":[()=>n.e(5238).then(n.bind(n,8455)),"@site/user-docs/application-examples/opendesk-on-scs/configuration.md",8455],"5d54de92":[()=>n.e(67299).then(n.bind(n,43824)),"@site/docs/02-iaas/guides/operations-guide/ceph.md",43824],"5e95c892":[()=>n.e(9647).then(n.bind(n,7121)),"@theme/DocsRoot",7121],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,4784)),"@generated/docusaurus.config",4784],"5f46a90e":[()=>n.e(66947).then(n.t.bind(n,79421,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-container-registry-25f.json",79421],"6019e202":[()=>n.e(50640).then(n.bind(n,76060)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview.md",76060],"604a51e1":[()=>n.e(61976).then(n.bind(n,19186)),"@site/standards/scs-0119-v1-rook-decision.md",19186],"60fc342f":[()=>n.e(99525).then(n.bind(n,16664)),"@site/docs/02-iaas/guides/configuration-guide/commons/packages.md",16664],61171858:[()=>n.e(51400).then(n.bind(n,16999)),"@site/docs/02-iaas/guides/concept-guide/use-cases.md",16999],"621db11d":[()=>Promise.all([n.e(71869),n.e(3347),n.e(64212)]).then(n.bind(n,13250)),"@theme/Blog/Pages/BlogAuthorsListPage",13250],"62337dff":[()=>n.e(89376).then(n.bind(n,61278)),"@site/community/collaboration/team-iam.md",61278],"631b9b66":[()=>n.e(71682).then(n.bind(n,84512)),"@site/standards/scs-0211-v2-kaas-default-storage-class.md",84512],"63768f60":[()=>n.e(86397).then(n.bind(n,16380)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack.md",16380],"63c8fde6":[()=>n.e(4168).then(n.bind(n,83139)),"@site/standards/scs-0101-v1-entropy.md",83139],"640bb4cf":[()=>n.e(6358).then(n.bind(n,79381)),"@site/standards/scs-0100-w1-flavor-naming-implementation-testing.md",79381],"64f9507b":[()=>n.e(55790).then(n.bind(n,62676)),"@site/standards/iaas/scs-0110.md",62676],"65742e9f":[()=>n.e(45147).then(n.bind(n,99963)),"@site/docs/05-iam/SCS-example-setup-configuration-description.md",99963],"657efcba":[()=>n.e(61238).then(n.bind(n,5678)),"@site/docs/03-container/components/container-registry/docs/quickstart.md",5678],"65c1efe1":[()=>n.e(55663).then(n.bind(n,92489)),"@site/standards/kaas/scs-0212.md",92489],"670b12e1":[()=>n.e(63919).then(n.bind(n,51881)),"@site/docs/02-iaas/guides/operations-guide/manager/console.md",51881],67140352:[()=>n.e(93575).then(n.bind(n,997)),"@site/docs/05-iam/domain-manager-setup-and-usage.md",997],"6738f543":[()=>n.e(92671).then(n.bind(n,56129)),"@site/standards/standards/overview.mdx",56129],"67dad519":[()=>n.e(4980).then(n.bind(n,60486)),"@site/docs/02-iaas/guides/deploy-guide/provisioning.md",60486],"685813dc":[()=>n.e(11953).then(n.bind(n,10726)),"@site/docs/02-iaas/components/resource-manager.md",10726],"6875c492":[()=>Promise.all([n.e(71869),n.e(43498),n.e(3347),n.e(84813)]).then(n.bind(n,33069)),"@theme/BlogTagsPostsPage",33069],"699c0e5c":[()=>n.e(83725).then(n.bind(n,1551)),"@site/standards/scs-0111-v1-volume-type-decisions.md",1551],"6a0c14a5":[()=>n.e(8834).then(n.bind(n,13357)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/flavor-manager.md",13357],"6a49ee0a":[()=>n.e(85066).then(n.bind(n,77861)),"@site/docs/04-operating-scs/components/status-page-deployment/docs/quickstart.md",77861],"6ad9ab45":[()=>n.e(58561).then(n.bind(n,94252)),"@site/standards/iaas/scs-0103.md",94252],"6bcd11f8":[()=>n.e(68502).then(n.bind(n,55850)),"@site/docs/02-iaas/guides/concept-guide/components/keycloak.md",55850],"6c33bb99":[()=>n.e(44810).then(n.bind(n,77488)),"@site/docs/02-iaas/guides/configuration-guide/ceph.md",77488],"6c4198a1":[()=>n.e(87638).then(n.bind(n,49862)),"@site/docs/02-iaas/guides/deploy-guide/bootstrap.md",49862],"6cdabe05":[()=>n.e(9701).then(n.bind(n,14069)),"@site/standards/scs-0122-v1-node-to-node-encryption.md",14069],"6cdfddef":[()=>n.e(73281).then(n.bind(n,75478)),"@site/docs/04-operating-scs/components/monitoring/docs/status-page.md",75478],"6d32cafb":[()=>n.e(45978).then(n.bind(n,46910)),"@site/docs/02-iaas/guides/upgrade-guide/openstack.md",46910],"6d890b23":[()=>n.e(84331).then(n.bind(n,6986)),"@site/docs/02-iaas/guides/operations-guide/manager/task.md",6986],"6d8acf16":[()=>n.e(73374).then(n.bind(n,57607)),"@site/docs/04-operating-scs/components/monitoring/docs/tuning.md",57607],"6db2ece2":[()=>n.e(69356).then(n.bind(n,28191)),"@site/docs/02-iaas/guides/configuration-guide/inventory.md",28191],"6ddb698c":[()=>n.e(65679).then(n.bind(n,87248)),"@site/standards/kaas/scs-0217.md",87248],"6e45ed1a":[()=>n.e(94604).then(n.bind(n,9249)),"@site/docs/02-iaas/guides/configuration-guide/commons/certificates.md",9249],"6e84ad78":[()=>n.e(22270).then(n.bind(n,55572)),"@site/standards/iaas/scs-0120.md",55572],"6f1c571c":[()=>n.e(88071).then(n.bind(n,89111)),"@site/docs/02-iaas/guides/deploy-guide/examples/index.md",89111],"6f4a06ca":[()=>n.e(42372).then(n.bind(n,5957)),"@site/docs/02-iaas/guides/deploy-guide/manager.md",5957],"6fc3ae76":[()=>n.e(644).then(n.bind(n,93774)),"@site/standards/iaas/scs-0125.md",93774],"6fe5bbf3":[()=>n.e(18096).then(n.bind(n,18254)),"@site/docs/02-iaas/guides/configuration-guide/rook.md",18254],"7023f74c":[()=>n.e(94869).then(n.bind(n,62779)),"@site/docs/02-iaas/components/image-manager/update.md",62779],"70b53392":[()=>n.e(69110).then(n.bind(n,5879)),"@site/standards/scs-0403-v1-csp-kaas-observability-stack.md",5879],"71acf54e":[()=>n.e(20309).then(n.bind(n,2390)),"@site/docs/02-iaas/guides/concept-guide/design.md",2390],"7217b34c":[()=>n.e(46098).then(n.bind(n,11270)),"@site/docs/02-iaas/guides/configuration-guide/openstack/magnum.md",11270],"732919ef":[()=>n.e(32233).then(n.t.bind(n,3325,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-releases-66b.json",3325],"73512cb1":[()=>n.e(18897).then(n.bind(n,38004)),"@site/standards/scs-0218-v1-container-registry-for-scs-standard-implementation.md",38004],73956345:[()=>n.e(26083).then(n.bind(n,47771)),"@site/docs/02-iaas/overview/compute.md",47771],"742db51e":[()=>n.e(38781).then(n.bind(n,2950)),"@site/standards/kaas/scs-0218.md",2950],"748dce39":[()=>n.e(20082).then(n.bind(n,95437)),"@site/docs/02-iaas/guides/operations-guide/openstack/keystone.md",95437],"749c6f3f":[()=>n.e(48625).then(n.t.bind(n,75709,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-scs-health-monitor-311.json",75709],"755df717":[()=>n.e(25429).then(n.bind(n,41082)),"@site/docs/02-iaas/guides/configuration-guide/openstack/barbican.md",41082],"757d752e":[()=>n.e(6337).then(n.bind(n,29377)),"@site/docs/04-operating-scs/components/scs-health-monitor/Workflow.md",29377],"760c57f4":[()=>Promise.all([n.e(71869),n.e(14385)]).then(n.bind(n,65180)),"@site/docs/02-iaas/guides/deploy-guide/services/ceph.mdx",65180],"767805d3":[()=>n.e(18519).then(n.bind(n,61396)),"@site/docs/02-iaas/guides/configuration-guide/configuration-repository.md",61396],"777b847b":[()=>n.e(79001).then(n.bind(n,30406)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stacks/continuous-integration.md",30406],"779440a1":[()=>n.e(22672).then(n.bind(n,8618)),"@site/standards/iaas/scs-0112.md",8618],"7850b12c":[()=>n.e(30675).then(n.bind(n,64680)),"@site/docs/03-container/components/container-registry/docs/persistence.md",64680],"78bb765a":[()=>n.e(89295).then(n.bind(n,62285)),"@site/docs/04-operating-scs/components/status-page-api/docs/requirements.md",62285],"79a28527":[()=>n.e(61902).then(n.bind(n,63441)),"@site/user-docs/application-examples/opendesk-on-scs/user-import.md",63441],"7aa8d561":[()=>n.e(11362).then(n.bind(n,23920)),"@site/standards/scs-0115-v1-default-rules-for-security-groups.md",23920],"7ac7e960":[()=>n.e(61329).then(n.bind(n,22201)),"@site/standards/scs-0120-v1-capi-images.md",22201],"7ace79c4":[()=>n.e(974).then(n.bind(n,88642)),"@site/standards/iaas/scs-0111.md",88642],"7b449e09":[()=>n.e(45123).then(n.bind(n,95763)),"@site/standards/scs-0002-v2-standards-docs-org.md",95763],"7b787d81":[()=>n.e(52257).then(n.bind(n,35254)),"@site/docs/06-releases/Release0.md",35254],"7bd33c3d":[()=>n.e(40192).then(n.bind(n,84767)),"@site/community/cloud-resources/getting-started-openstack.md",84767],"7bed4829":[()=>n.e(24984).then(n.bind(n,16347)),"@site/docs/03-container/components/container-registry/docs/backup_and_restore.md",16347],"7cf96b3e":[()=>n.e(65770).then(n.bind(n,49136)),"@site/standards/scs-0113-v1-security-groups-decision-record.md",49136],"7d3935d1":[()=>n.e(2683).then(n.bind(n,1523)),"@site/docs/02-iaas/guides/user-guide/security-groups/security-groups.md",1523],"7e7cf0e4":[()=>n.e(74612).then(n.bind(n,79976)),"@site/standards/global/scs-0003.md",79976],"7eea03ab":[()=>n.e(56699).then(n.t.bind(n,2571,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-operating-scs-ba0.json",2571],"7f1a31c3":[()=>n.e(39464).then(n.bind(n,90300)),"@site/docs/06-releases/Release2.md",90300],"7f57b062":[()=>n.e(35894).then(n.bind(n,36528)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart.md",36528],"7fd33963":[()=>n.e(78526).then(n.bind(n,61954)),"@site/standards/kaas/scs-0216.md",61954],"7fedb4ba":[()=>n.e(42686).then(n.t.bind(n,47281,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-api-985.json",47281],"8092c627":[()=>n.e(4880).then(n.bind(n,52766)),"@site/docs/02-iaas/guides/user-guide/user-data-backups.md",52766],"814f3328":[()=>n.e(67472).then(n.t.bind(n,55513,19)),"~blog/default/blog-post-list-prop-default.json",55513],"81875c35":[()=>n.e(31669).then(n.bind(n,92725)),"@site/docs/04-operating-scs/components/status-page-api/docs/example-requests.md",92725],83100446:[()=>n.e(46334).then(n.bind(n,40106)),"@site/docs/03-container/deployment-examples/a/index.md",40106],"8493ac52":[()=>n.e(45054).then(n.bind(n,74829)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop.md",74829],"853df457":[()=>n.e(4365).then(n.bind(n,85683)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/index.md",85683],"85f4c940":[()=>n.e(34312).then(n.t.bind(n,83501,19)),"@generated/docusaurus-plugin-content-docs/user-docs/__plugin.json",83501],"8679ddc4":[()=>n.e(6960).then(n.bind(n,29598)),"@site/docs/02-iaas/guides/configuration-guide/services/docker.md",29598],"86bbda6f":[()=>n.e(10296).then(n.bind(n,87938)),"@site/standards/scs-0123-v1-mandatory-and-supported-IaaS-services.md",87938],"86ee3414":[()=>n.e(63365).then(n.bind(n,59380)),"@site/docs/02-iaas/components/index.md",59380],"87086dc6":[()=>n.e(54725).then(n.t.bind(n,31045,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-iaas-layer-2b6.json",31045],87293620:[()=>n.e(44850).then(n.bind(n,19592)),"@site/community/collaboration/sig-central-api.md",19592],"88684b71":[()=>n.e(22151).then(n.bind(n,50652)),"@site/docs/02-iaas/components/flavor-manager.md",50652],"88f37d1b":[()=>n.e(96734).then(n.bind(n,57517)),"@site/docs/05-iam/intra-SCS-federation-setup-description-for-osism-doc-operations.md",57517],"89176cae":[()=>n.e(45673).then(n.bind(n,92895)),"@site/docs/07-standards/index.md",92895],"89ad43f4":[()=>n.e(2884).then(n.bind(n,18648)),"@site/docs/02-iaas/guides/deploy-guide/services/index.md",18648],"8aade8b1":[()=>n.e(6305).then(n.bind(n,33154)),"@site/docs/02-iaas/guides/operations-guide/openstack/nova.md",33154],"8b8a137c":[()=>n.e(37074).then(n.bind(n,19027)),"@site/docs/02-iaas/guides/configuration-guide/network.md",19027],"8d25d5d4":[()=>n.e(64277).then(n.bind(n,49516)),"@site/contributor-docs/operations/iam/openstack-federation-via-oidc.md",49516],"8db05b07":[()=>n.e(63663).then(n.bind(n,60758)),"@site/docs/02-iaas/components/openstack-health-monitor.md",60758],"8e8909f7":[()=>n.e(19407).then(n.bind(n,17329)),"@site/docs/02-iaas/guides/configuration-guide/openstack/skyline.md",17329],"8ec565c1":[()=>n.e(46866).then(n.bind(n,23860)),"@site/standards/iaas/scs-0116.md",23860],"8ed6f0f1":[()=>n.e(71001).then(n.bind(n,25927)),"@site/docs/03-container/components/cluster-stacks/components/csctl/design.md",25927],"8fc094a7":[()=>n.e(46251).then(n.bind(n,75252)),"@site/docs/02-iaas/guides/operations-guide/manager/index.md",75252],"9099a3d2":[()=>n.e(96172).then(n.bind(n,77401)),"@site/community/central-services/plusserver-gx-scs.md",77401],"90c33bef":[()=>n.e(79692).then(n.bind(n,8602)),"@site/standards/scs-0118-v1-taxonomy-of-failsafe-levels.md",8602],"915e2cf4":[()=>n.e(89260).then(n.bind(n,16442)),"@site/docs/02-iaas/guides/user-guide/openstack/user-data-backups.md",16442],"926668e5":[()=>n.e(91770).then(n.bind(n,99747)),"@site/standards/iaas/scs-0119.md",99747],"9278f3d6":[()=>n.e(20904).then(n.bind(n,74436)),"@site/standards/scs-0213-v1-k8s-nodes-anti-affinity.md",74436],"929c4e1b":[()=>n.e(83802).then(n.bind(n,34787)),"@site/standards/index.md",34787],"931040e8":[()=>n.e(57743).then(n.bind(n,53800)),"@site/community/contribute/styleguide.md",53800],"946bf800":[()=>n.e(98842).then(n.t.bind(n,25851,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-components-2-cac.json",25851],"9490f32b":[()=>n.e(83874).then(n.bind(n,4943)),"@site/docs/02-iaas/guides/configuration-guide/openstack/glance.md",4943],"94b13e0d":[()=>n.e(96707).then(n.bind(n,76148)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/openstack-health-monitor.md",76148],"94f31572":[()=>n.e(69752).then(n.bind(n,59299)),"@site/docs/08-faq/index.mdx",59299],"950c7487":[()=>n.e(42456).then(n.bind(n,92599)),"@site/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide.md",92599],"95800b3e":[()=>n.e(75515).then(n.bind(n,12675)),"@site/docs/02-iaas/guides/concept-guide/layers.md",12675],"964e3c50":[()=>n.e(34870).then(n.bind(n,3693)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow.md",3693],"96f8fd49":[()=>n.e(10667).then(n.bind(n,31872)),"@site/docs/02-iaas/guides/operations-guide/manager/log.md",31872],"9782cb54":[()=>n.e(9285).then(n.bind(n,33685)),"@site/standards/scs-0124-v1-security-of-iaas-service-software.md",33685],"97b1504a":[()=>n.e(94346).then(n.bind(n,55139)),"@site/standards/iaas/scs-0104.md",55139],"97ef9758":[()=>n.e(26529).then(n.bind(n,73338)),"@site/community/collaboration/team-iaas.md",73338],"9890ac63":[()=>n.e(41298).then(n.bind(n,18564)),"@site/standards/global/scs-0004.md",18564],"9975996a":[()=>n.e(78532).then(n.bind(n,51019)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing.md",51019],"9a7c0197":[()=>n.e(93402).then(n.bind(n,36857)),"@site/contributor-docs/operations/iam/identity-federation-in-scs.md",36857],"9b12e85c":[()=>n.e(38040).then(n.bind(n,86728)),"@site/docs/04-operating-scs/components/status-page-web/docs/quickstart.md",86728],"9b5d9131":[()=>n.e(61427).then(n.bind(n,52319)),"@site/docs/04-operating-scs/components/central-api/poc-setup.md",52319],"9d1324c7":[()=>n.e(16568).then(n.bind(n,66804)),"@site/standards/scs-0100-v1-flavor-naming.md",66804],"9d49bc50":[()=>n.e(75875).then(n.bind(n,78705)),"@site/docs/02-iaas/guides/other-guides/developer-guide/zuul.md",78705],"9e156860":[()=>n.e(63811).then(n.bind(n,78356)),"@site/standards/scs-0219-v1-kaas-networking.md",78356],"9e4087bc":[()=>n.e(52711).then(n.bind(n,89331)),"@theme/BlogArchivePage",89331],"9f356e5b":[()=>n.e(91844).then(n.bind(n,24573)),"@site/docs/02-iaas/overview/architecture.md",24573],"9f357fc0":[()=>n.e(83292).then(n.bind(n,99590)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart.md",99590],a022b847:[()=>n.e(57013).then(n.bind(n,77946)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stacks/overview.md",77946],a0b1bbd7:[()=>n.e(7984).then(n.bind(n,29817)),"@site/docs/06-releases/Release5.md",29817],a12f05ab:[()=>n.e(3453).then(n.bind(n,31353)),"@site/docs/02-iaas/guides/operations-guide/openstack/cinder.md",31353],a15c4cb6:[()=>n.e(11290).then(n.bind(n,72378)),"@site/standards/scs-0412-v1-metering-json.md",72378],a2317717:[()=>n.e(43400).then(n.bind(n,72885)),"@site/docs/02-iaas/guides/configuration-guide/services/chrony.md",72885],a24f5044:[()=>n.e(9755).then(n.bind(n,86462)),"@site/standards/scs-XXXX-vN-standard-template.md",86462],a35d3433:[()=>n.e(80123).then(n.bind(n,90869)),"@site/standards/scs-0212-v1-requirements-for-container-registries.md",90869],a3dd9468:[()=>n.e(26018).then(n.bind(n,97601)),"@site/standards/iaas/scs-0113.md",97601],a3e11933:[()=>n.e(69657).then(n.bind(n,739)),"@site/docs/06-releases/Release1.md",739],a4833b52:[()=>n.e(57753).then(n.bind(n,57344)),"@site/standards/scs-0104-v1-standard-images.md",57344],a51f78bf:[()=>n.e(30825).then(n.bind(n,91439)),"@site/docs/02-iaas/guides/configuration-guide/commons/timezone.md",91439],a52c62d4:[()=>n.e(45568).then(n.bind(n,56890)),"@site/community/collaboration/sig-standardization.md",56890],a52f8495:[()=>n.e(19691).then(n.bind(n,90672)),"@site/standards/ops/scs-0400.md",90672],a63812ab:[()=>n.e(96147).then(n.bind(n,16190)),"@site/community/collaboration/sig-documentation.md",16190],a64829d3:[()=>n.e(88142).then(n.bind(n,5874)),"@site/docs/03-container/components/cluster-stacks/components/csctl/developing-and-testing-csctl.md",5874],a6a72687:[()=>n.e(87701).then(n.t.bind(n,49559,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-howto-2c5.json",49559],a6aa9e1f:[()=>Promise.all([n.e(71869),n.e(43498),n.e(3347),n.e(37643)]).then(n.bind(n,35124)),"@theme/BlogListPage",35124],a708848c:[()=>n.e(27980).then(n.bind(n,54034)),"@site/docs/02-iaas/components/project-manager.md",54034],a70dabb3:[()=>n.e(45075).then(n.bind(n,78806)),"@site/standards/global/scs-0002.md",78806],a7456010:[()=>n.e(61235).then(n.t.bind(n,88552,19)),"@generated/docusaurus-plugin-content-pages/default/__plugin.json",88552],a7769c8a:[()=>n.e(84093).then(n.bind(n,12411)),"@site/docs/06-releases/Release7.md",12411],a7bd4aaa:[()=>n.e(67098).then(n.bind(n,74532)),"@theme/DocVersionRoot",74532],a8f67d60:[()=>n.e(18463).then(n.bind(n,31254)),"@site/community/contribute/adding-docs-guide.md",31254],a94703ab:[()=>Promise.all([n.e(71869),n.e(79048)]).then(n.bind(n,11377)),"@theme/DocRoot",11377],a94c36cd:[()=>n.e(51548).then(n.bind(n,59711)),"@site/docs/03-container/overview/architecture.md",59711],a9f40339:[()=>n.e(86164).then(n.bind(n,20332)),"@site/docs/04-operating-scs/05-lifecycle-management/index.md",20332],aaebd759:[()=>n.e(77609).then(n.t.bind(n,36886,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-cluster-stacks-1fb.json",36886],ab2759ca:[()=>n.e(76153).then(n.bind(n,82553)),"@site/standards/scs-0005-v1-project-governance.md",82553],aba21aa0:[()=>n.e(35742).then(n.t.bind(n,27093,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",27093],abb47370:[()=>n.e(85075).then(n.bind(n,38554)),"@site/standards/iam/index.md",38554],abd5b058:[()=>n.e(66846).then(n.bind(n,15176)),"@site/standards/iaas/scs-0121.md",15176],abd7a988:[()=>n.e(42747).then(n.bind(n,68537)),"@site/docs/03-container/components/container-registry/docs/ha-deployment.md",68537],abecca15:[()=>n.e(67560).then(n.bind(n,91877)),"@site/docs/02-iaas/guides/deploy-guide/services/logging-monitoring.md",91877],abfb0638:[()=>n.e(76793).then(n.bind(n,55530)),"@site/docs/02-iaas/guides/operations-guide/manager/apply.md",55530],ac087500:[()=>n.e(38411).then(n.bind(n,87886)),"@site/docs/02-iaas/guides/troubleshooting-guide/index.md",87886],aca4bcb1:[()=>n.e(93750).then(n.bind(n,62662)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/terminology.md",62662],acecf23e:[()=>n.e(81903).then(n.t.bind(n,1912,19)),"~blog/default/blogMetadata-default.json",1912],ad1cb202:[()=>n.e(93086).then(n.bind(n,13805)),"@site/docs/02-iaas/guides/concept-guide/components/gardener.md",13805],ad39e84b:[()=>n.e(44657).then(n.bind(n,21556)),"@site/standards/scs-0102-v1-image-metadata.md",21556],ad59ba68:[()=>n.e(47191).then(n.bind(n,50896)),"@site/standards/scs-0117-v1-volume-backup-service.md",50896],ae009198:[()=>n.e(50676).then(n.bind(n,39104)),"@site/docs/04-operating-scs/components/status-page-deployment/docs/k3s.md",39104],aed2f698:[()=>n.e(85612).then(n.bind(n,27448)),"@site/docs/02-iaas/guides/user-guide/openstack/security-groups.md",27448],b08c16de:[()=>n.e(89390).then(n.bind(n,41365)),"@site/community/contribute/styleguides/ansible_styleguide.md",41365],b0ccdb87:[()=>n.e(6646).then(n.bind(n,4030)),"@site/docs/04-operating-scs/components/central-api/overview.md",4030],b0f0cb2b:[()=>n.e(86376).then(n.bind(n,95923)),"@site/standards/iaas/scs-0118.md",95923],b191927f:[()=>n.e(86452).then(n.bind(n,121)),"@site/standards/scs-compatible-iaas.md",121],b1bfccfc:[()=>Promise.all([n.e(71869),n.e(11159)]).then(n.bind(n,73750)),"@site/docs/02-iaas/guides/deploy-guide/rookify.md",73750],b1eed1ab:[()=>n.e(37362).then(n.bind(n,48377)),"@site/standards/kaas/scs-0214.md",48377],b1fd1705:[()=>n.e(78215).then(n.bind(n,76165)),"@site/docs/04-operating-scs/01-guides/openstack-health-monitor/Debian12-Install.md",76165],b262b314:[()=>n.e(53681).then(n.bind(n,66720)),"@site/standards/scs-0216-v1-requirements-for-testing-cluster-stacks.md",66720],b30e8b21:[()=>n.e(96578).then(n.bind(n,76807)),"@site/standards/scs-0217-v1-cluster-hardening.md",76807],b361e208:[()=>n.e(67548).then(n.bind(n,47631)),"@site/docs/04-operating-scs/components/automated-pentesting-kaas/tools.md",47631],b36e6e7c:[()=>n.e(25152).then(n.bind(n,67126)),"@site/standards/iaas/scs-0122.md",67126],b3e290f1:[()=>n.e(89031).then(n.bind(n,87390)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks.md",87390],b4038536:[()=>n.e(36084).then(n.bind(n,6935)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot.md",6935],b43d8ee7:[()=>n.e(8373).then(n.bind(n,22738)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow.md",22738],b4dfe8b3:[()=>n.e(59417).then(n.t.bind(n,36531,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-deployment-examples-f77.json",36531],b501f8e8:[()=>n.e(51528).then(n.bind(n,39976)),"@site/community/collaboration/team-container.md",39976],b5a6d29b:[()=>n.e(68226).then(n.bind(n,14307)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/resource-manager.md",14307],b5f86da1:[()=>n.e(67214).then(n.t.bind(n,65923,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-configuration-dc5.json",65923],b65fe363:[()=>n.e(33475).then(n.bind(n,66346)),"@site/docs/02-iaas/guides/configuration-guide/openstack/ironic.md",66346],b6ce023b:[()=>n.e(59346).then(n.bind(n,33551)),"@site/docs/04-operating-scs/components/status-page-openapi/docs/levels_of_consensus.md",33551],b6fc97b5:[()=>n.e(75717).then(n.t.bind(n,56676,19)),"@generated/docusaurus-plugin-content-docs/community/p/community-category-tools-6a3.json",56676],b74e5806:[()=>n.e(24730).then(n.bind(n,98768)),"@site/standards/iam/scs-0301.md",98768],b77ceb62:[()=>n.e(9689).then(n.bind(n,99502)),"@site/docs/02-iaas/guides/configuration-guide/openstack/ceilometer.md",99502],b7cec31e:[()=>n.e(57938).then(n.bind(n,8660)),"@site/community/collaboration/sig-community.md",8660],b8c7b97f:[()=>n.e(76443).then(n.bind(n,84212)),"@site/docs/05-iam/index.md",84212],b8fd74b5:[()=>n.e(93153).then(n.bind(n,92406)),"@site/docs/02-iaas/components/sandbox-manager.md",92406],bba00861:[()=>n.e(28439).then(n.t.bind(n,11885,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-pentesting-kaas-53d.json",11885],bccb1b42:[()=>n.e(56986).then(n.bind(n,68002)),"@site/docs/03-container/components/container-registry/docs/migration.md",68002],bceb927f:[()=>n.e(78081).then(n.bind(n,12162)),"@site/docs/02-iaas/guides/configuration-guide/openstack/neutron.md",12162],bd319452:[()=>n.e(66971).then(n.bind(n,975)),"@site/docs/02-iaas/guides/deploy-guide/examples/testbed.md",975],bd8a0ffe:[()=>n.e(24497).then(n.bind(n,43355)),"@site/standards/scs-0101-w1-entropy-implementation-testing.md",43355],bd8a97c5:[()=>n.e(43536).then(n.bind(n,85819)),"@site/docs/02-iaas/guides/configuration-guide/proxy.md",85819],bdaaff35:[()=>n.e(49063).then(n.bind(n,75305)),"@site/docs/02-iaas/guides/user-guide/openstack/index.md",75305],be01f2a0:[()=>n.e(89954).then(n.bind(n,23739)),"@site/docs/02-iaas/guides/configuration-guide/openstack/keystone.md",23739],befb6565:[()=>n.e(47020).then(n.bind(n,70295)),"@site/docs/02-iaas/guides/configuration-guide/openstack/heat.md",70295],c059aa33:[()=>n.e(44716).then(n.bind(n,48472)),"@site/docs/02-iaas/deployment-examples/artcodix/index.mdx",48472],c06491c2:[()=>n.e(70337).then(n.bind(n,66276)),"@site/user-docs/application-examples/opendesk-on-scs/overview.md",66276],c0cd111c:[()=>n.e(88477).then(n.bind(n,99134)),"@site/docs/02-iaas/overview/storage.md",99134],c0e025b3:[()=>n.e(52179).then(n.bind(n,94399)),"@site/docs/02-iaas/guides/configuration-guide/services/tuned.md",94399],c1172cc8:[()=>n.e(73739).then(n.bind(n,36758)),"@site/standards/scs-0102-w1-image-metadata-implementation-testing.md",36758],c12abb16:[()=>n.e(80281).then(n.bind(n,86672)),"@site/docs/04-operating-scs/components/status-page-web/docs/configuration.md",86672],c15d9823:[()=>n.e(18146).then(n.t.bind(n,29328,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-bd9.json",29328],c2f44c5f:[()=>n.e(660).then(n.bind(n,6515)),"@site/docs/02-iaas/guides/troubleshooting-guide/openstack.md",6515],c3529e0a:[()=>n.e(76871).then(n.bind(n,31239)),"@site/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests.md",31239],c49f9378:[()=>n.e(20126).then(n.bind(n,71575)),"@site/docs/02-iaas/components/simple-stress.md",71575],c5479f59:[()=>n.e(72283).then(n.bind(n,80016)),"@site/docs/03-container/components/container-registry/docs/rate_limit.md",80016],c5533f5e:[()=>n.e(69346).then(n.bind(n,97819)),"@site/standards/scs-0210-v1-k8s-new-version-policy.md",97819],c6e1beb6:[()=>n.e(67085).then(n.bind(n,31320)),"@site/docs/04-operating-scs/components/monitoring/docs/alertmanager.md",31320],c75320ff:[()=>n.e(11407).then(n.bind(n,61401)),"@site/docs/02-iaas/guides/upgrade-guide/logging-monitoring.md",61401],c7e8a920:[()=>n.e(81542).then(n.bind(n,93467)),"@site/standards/scs-0004-v1-achieving-certification.md",93467],c8d5479b:[()=>n.e(19289).then(n.bind(n,70027)),"@site/standards/iam/scs-0302.md",70027],c9581477:[()=>n.e(86293).then(n.bind(n,23242)),"@site/docs/02-iaas/guides/configuration-guide/openstack/nova.md",23242],c9b16325:[()=>n.e(82798).then(n.bind(n,16348)),"@site/contributor-docs/development/index.md",16348],ca219831:[()=>n.e(46471).then(n.bind(n,71535)),"@site/user-docs/application-examples/opendesk-on-scs/getting_started.md",71535],caeeb51c:[()=>n.e(25162).then(n.bind(n,57887)),"@site/docs/02-iaas/guides/concept-guide/index.md",57887],cb18db4b:[()=>n.e(69859).then(n.bind(n,30359)),"@site/docs/04-operating-scs/components/automated-pentesting-iaas/tools.md",30359],cbf20d25:[()=>n.e(35575).then(n.bind(n,77123)),"@site/contributor-docs/development/tests/test-implementation-guide.md",77123],ccc49370:[()=>Promise.all([n.e(71869),n.e(43498),n.e(3347),n.e(83249)]).then(n.bind(n,73858)),"@theme/BlogPostPage",73858],cd0ad4f0:[()=>n.e(64625).then(n.bind(n,54287)),"@site/docs/01-getting-started/containerization.md",54287],cd4fb20e:[()=>n.e(96165).then(n.bind(n,48115)),"@site/standards/scs-0100-v2-flavor-naming.md",48115],cd87bcd5:[()=>n.e(95113).then(n.bind(n,43063)),"@site/docs/04-operating-scs/components/status-page-api/docs/quickstart.md",43063],cda5fe29:[()=>n.e(62840).then(n.bind(n,7706)),"@site/docs/02-iaas/guides/deploy-guide/services/kubernetes.md",7706],cdb233b1:[()=>n.e(71755).then(n.t.bind(n,77296,19)),"@generated/docusaurus-plugin-content-docs/user-docs/p/user-docs-category-application-examples-405.json",77296],cdce7391:[()=>n.e(45350).then(n.t.bind(n,73488,19)),"@generated/docusaurus-plugin-content-docs/user-docs/p/user-docs-efc.json",73488],ce756c16:[()=>n.e(19807).then(n.bind(n,24268)),"@site/community/license-considerations.md",24268],cf99a16e:[()=>n.e(34855).then(n.bind(n,72775)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/simple-stress.md",72775],cffc493c:[()=>n.e(40714).then(n.bind(n,70984)),"@site/community/contribute/docs-workflow-explanation.md",70984],d0ee365b:[()=>n.e(26223).then(n.bind(n,40208)),"@site/docs/02-iaas/guides/configuration-guide/openstack/index.md",40208],d14d7097:[()=>n.e(37919).then(n.bind(n,64148)),"@site/docs/02-iaas/guides/operations-guide/openstack/neutron.md",64148],d1aa920e:[()=>n.e(53920).then(n.bind(n,42265)),"@site/docs/02-iaas/guides/operations-guide/openstack/index.md",42265],d1c3b532:[()=>n.e(68992).then(n.bind(n,93384)),"@site/docs/02-iaas/guides/operations-guide/infrastructure.md",93384],d2436a2b:[()=>n.e(60837).then(n.t.bind(n,19112,19)),"@generated/docusaurus-plugin-content-docs/community/p/community-038.json",19112],d341f8b3:[()=>n.e(24170).then(n.bind(n,21266)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration.md",21266],d35a3623:[()=>n.e(8655).then(n.bind(n,19176)),"@site/docs/02-iaas/guides/troubleshooting-guide/rookify.md",19176],d5658917:[()=>n.e(53156).then(n.bind(n,15003)),"@site/docs/03-container/components/cluster-stacks/components/csctl/how_to_use_csctl.md",15003],d5947e44:[()=>n.e(47861).then(n.bind(n,3252)),"@site/docs/02-iaas/guides/operations-guide/network.md",3252],d59f7d52:[()=>n.e(55139).then(n.bind(n,24907)),"@site/standards/scs-0301-v1-naming-conventions.md",24907],d71eca41:[()=>n.e(70467).then(n.bind(n,33978)),"@site/docs/02-iaas/guides/concept-guide/components/index.md",33978],d83cc1de:[()=>n.e(1396).then(n.bind(n,25641)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow.md",25641],d902a273:[()=>n.e(57695).then(n.bind(n,87380)),"@site/docs/04-operating-scs/components/status-page-deployment/docs/scs-public.md",87380],d98f39e0:[()=>n.e(18659).then(n.bind(n,80873)),"@site/docs/04-operating-scs/components/status-page-api/docs/overview.md",80873],da1a5473:[()=>n.e(77125).then(n.bind(n,18599)),"@site/docs/02-iaas/guides/other-guides/developer-guide/scripts.md",18599],db103552:[()=>n.e(90495).then(n.t.bind(n,36866,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-concepts-954.json",36866],db47e023:[()=>n.e(83160).then(n.bind(n,59497)),"@site/docs/04-operating-scs/components/automated-pentesting-iaas/quickstart.md",59497],dbde4c02:[()=>n.e(70445).then(n.bind(n,84858)),"@site/docs/02-iaas/guides/upgrade-guide/infrastructure.md",84858],dc09f893:[()=>n.e(13527).then(n.bind(n,31579)),"@site/docs/02-iaas/guides/user-guide/index.md",31579],dc218a96:[()=>n.e(63935).then(n.bind(n,92497)),"@site/docs/04-operating-scs/components/status-page-api/docs/contribute.md",92497],dc8e8e39:[()=>n.e(10488).then(n.t.bind(n,95102,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-community-623.json",95102],dcae780a:[()=>n.e(62350).then(n.bind(n,76318)),"@site/standards/scs-0118-w1-example-impacts-of-failure-scenarios.md",76318],dcbc8e94:[()=>n.e(59495).then(n.bind(n,25367)),"@site/docs/02-iaas/guides/configuration-guide/loadbalancer.md",25367],dcf2f717:[()=>n.e(78981).then(n.bind(n,35352)),"@site/docs/03-container/guides/guide1.md",35352],dd4ba739:[()=>n.e(27425).then(n.bind(n,31097)),"@site/standards/scs-0116-w1-key-manager-implementation-testing.md",31097],dd5128a0:[()=>n.e(37568).then(n.bind(n,59670)),"@site/docs/02-iaas/guides/configuration-guide/rookify.md",59670],dd9a4eb2:[()=>n.e(19512).then(n.t.bind(n,41346,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-guides-1-d9c.json",41346],de6833f9:[()=>n.e(42309).then(n.bind(n,98423)),"@site/docs/02-iaas/guides/configuration-guide/commons/resolvconf.md",98423],df35cf96:[()=>n.e(36831).then(n.bind(n,51629)),"@site/docs/02-iaas/guides/configuration-guide/commons/services.md",51629],dfce392e:[()=>n.e(84398).then(n.bind(n,93851)),"@site/standards/scs-0401-v1-status-page-reference-implementation-decision.md",93851],e0719818:[()=>n.e(15220).then(n.t.bind(n,68669,19)),"@generated/docusaurus-plugin-content-docs/community/__plugin.json",68669],e0c197a4:[()=>n.e(17051).then(n.bind(n,72799)),"@site/docs/02-iaas/guides/concept-guide/components/ironic.md",72799],e10bed52:[()=>n.e(2925).then(n.bind(n,36667)),"@site/docs/04-operating-scs/components/status-page-deployment/docs/configuration.md",36667],e1e9b906:[()=>n.e(6934).then(n.bind(n,63158)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/develop/develop.md",63158],e20b631f:[()=>n.e(80272).then(n.bind(n,27720)),"@site/docs/02-iaas/guides/configuration-guide/openstack/manila.md",27720],e24c1f8d:[()=>n.e(84480).then(n.bind(n,87392)),"@site/docs/02-iaas/guides/configuration-guide/commons/sysctl.md",87392],e2bda29d:[()=>n.e(96162).then(n.bind(n,51302)),"@site/docs/02-iaas/guides/user-guide/openstack/install-instance-from-iso.md",51302],e2dcdabe:[()=>n.e(91099).then(n.bind(n,40093)),"@site/standards/scs-XXXX-vN-decision-record-template.md",40093],e34f30ed:[()=>n.e(96211).then(n.bind(n,31412)),"@site/docs/04-operating-scs/components/monitoring/docs/iaas.md",31412],e4409f64:[()=>n.e(33559).then(n.bind(n,73330)),"@site/docs/02-iaas/guides/user-guide/migration-vmware-esxi.md",73330],e44168e5:[()=>n.e(31909).then(n.bind(n,49901)),"@site/docs/01-getting-started/virtualization.md",49901],e48c83c9:[()=>n.e(54252).then(n.bind(n,5492)),"@site/docs/02-iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine.md",5492],e4a5809a:[()=>n.e(12196).then(n.bind(n,92515)),"@site/docs/02-iaas/guides/operations-guide/rook.md",92515],e6263de7:[()=>Promise.all([n.e(71869),n.e(72111)]).then(n.bind(n,99966)),"@site/docs/02-iaas/guides/deploy-guide/services/rook.md",99966],e747ec83:[()=>n.e(39432).then(n.bind(n,93583)),"@site/docs/glossary.md",93583],e83ec39f:[()=>n.e(72439).then(n.bind(n,64832)),"@site/docs/02-iaas/guides/other-guides/developer-guide/style-guide.md",64832],e84ae951:[()=>n.e(10329).then(n.bind(n,5913)),"@site/standards/scs-0116-v1-key-manager-standard.md",5913],ea470413:[()=>n.e(38730).then(n.bind(n,72067)),"@site/community/collaboration/sig-monitoring.md",72067],ea6d9109:[()=>n.e(5912).then(n.t.bind(n,4355,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-web-23c.json",4355],eaf69a59:[()=>n.e(57633).then(n.bind(n,52705)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting.md",52705],eb99bfed:[()=>n.e(6063).then(n.bind(n,67420)),"@site/docs/02-iaas/guides/troubleshooting-guide/manager.md",67420],ecbad217:[()=>Promise.all([n.e(71869),n.e(96454)]).then(n.bind(n,52988)),"@site/docs/02-iaas/guides/upgrade-guide/manager.mdx",52988],edaafa5c:[()=>n.e(65981).then(n.bind(n,75394)),"@site/docs/04-operating-scs/components/status-page-api/docs/configuration.md",75394],edc931f8:[()=>n.e(12526).then(n.bind(n,15983)),"@site/community/index.md",15983],eea6a18c:[()=>n.e(79245).then(n.bind(n,85629)),"@site/standards/scs-0400-v1-status-page-create-decision.md",85629],ef682180:[()=>n.e(67731).then(n.bind(n,21763)),"@site/standards/kaas/scs-0215.md",21763],ef8b811a:[()=>n.e(38947).then(n.t.bind(n,56600,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-authors-790.json",56600],ef9d238d:[()=>Promise.all([n.e(71869),n.e(39864)]).then(n.bind(n,86769)),"@site/community/contribute/local-docusaurus-development-guide.mdx",86769],efbcd183:[()=>n.e(29093).then(n.bind(n,80436)),"@site/standards/scs-compatible-kaas.md",80436],f0e20cb6:[()=>n.e(41479).then(n.bind(n,33893)),"@site/docs/02-iaas/guides/configuration-guide/index.md",33893],f14428ad:[()=>n.e(83709).then(n.bind(n,70484)),"@site/user-docs/application-examples/opendesk-on-scs/contribute.md",70484],f1715aef:[()=>n.e(36647).then(n.bind(n,29221)),"@site/standards/iaas/scs-0100.md",29221],f17f9c44:[()=>n.e(4979).then(n.bind(n,56778)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers.md",56778],f2a59390:[()=>n.e(92078).then(n.bind(n,82697)),"@site/docs/02-iaas/guides/deploy-guide/services/openstack.md",82697],f385820d:[()=>Promise.all([n.e(71869),n.e(27841)]).then(n.bind(n,84088)),"@site/docs/02-iaas/guides/configuration-guide/openstack/horizon.md",84088],f39ce5f1:[()=>n.e(99115).then(n.bind(n,7643)),"@site/docs/04-operating-scs/components/status-page-openapi/docs/overview.md",7643],f40b2df0:[()=>n.e(3639).then(n.bind(n,32253)),"@site/docs/02-iaas/guides/operations-guide/openstack/octavia.md",32253],f4cdb2d9:[()=>n.e(49745).then(n.bind(n,86568)),"@site/docs/03-container/overview/knowledge.md",86568],f4daec3f:[()=>n.e(47475).then(n.bind(n,27860)),"@site/standards/iaas/scs-0117.md",27860],f4f96b66:[()=>n.e(34062).then(n.bind(n,92789)),"@site/docs/turnkey-solution/hardware-landscape.md",92789],f53abb4b:[()=>n.e(43862).then(n.t.bind(n,83760,19)),"@generated/docusaurus-plugin-content-docs/standards/__plugin.json",83760],f5b4e375:[()=>n.e(60778).then(n.bind(n,60106)),"@site/standards/scs-0210-v2-k8s-version-policy.md",60106],f5cc95ce:[()=>n.e(62312).then(n.bind(n,78068)),"@site/docs/04-operating-scs/components/status-page-openapi/docs/components.md",78068],f600298c:[()=>n.e(80639).then(n.bind(n,49282)),"@site/docs/04-operating-scs/components/automated-pentesting-iaas/reports.md",49282],f68824be:[()=>n.e(36070).then(n.bind(n,92291)),"@site/standards/scs-0300-v1-requirements-for-sso-identity-federation.md",92291],f699bead:[()=>n.e(1193).then(n.bind(n,60027)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/concept.md",60027],f6ed81c9:[()=>n.e(19653).then(n.t.bind(n,85297,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-category-status-page-e43.json",85297],f81c1134:[()=>n.e(48130).then(n.t.bind(n,77735,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-archive-f05.json",77735],f8869d03:[()=>n.e(25595).then(n.bind(n,18829)),"@site/standards/kaas/index.md",18829],f9ec068e:[()=>n.e(751).then(n.bind(n,72759)),"@site/standards/global/scs-0001.md",72759],f9fdfcc0:[()=>n.e(35210).then(n.bind(n,39596)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration.md",39596],fa7c4c29:[()=>n.e(35122).then(n.bind(n,1869)),"@site/docs/02-iaas/guides/upgrade-guide/network.md",1869],fbd7a1e9:[()=>n.e(9416).then(n.bind(n,47711)),"@site/docs/04-operating-scs/components/status-page-web/docs/requirements.md",47711],fc07b5ea:[()=>n.e(33760).then(n.bind(n,13846)),"@site/standards/certification/pipeline.md",13846],fc3b013c:[()=>n.e(46774).then(n.bind(n,6446)),"@site/docs/04-operating-scs/components/automated-pentesting-kaas/quickstart.md",6446],fc83dba0:[()=>n.e(7628).then(n.bind(n,2357)),"@site/docs/04-operating-scs/components/status-page-deployment/docs/kind.md",2357],fd34a958:[()=>n.e(39049).then(n.bind(n,29751)),"@site/standards/scs-0402-v1-status-page-openapi-spec-decision.md",29751],fe5fac7c:[()=>n.e(12479).then(n.bind(n,86916)),"@site/docs/03-container/deployment-examples/a/hardware.md",86916],ff45c01b:[()=>n.e(66290).then(n.bind(n,90857)),"@site/contributor-docs/development/tests/rfc2119-keyword-test-guide.md",90857],ff7b9a4c:[()=>n.e(45929).then(n.t.bind(n,87805,19)),"@generated/docusaurus-plugin-content-docs/standards/p/standards-446.json",87805],ffa81568:[()=>n.e(79728).then(n.bind(n,20189)),"@site/docs/04-operating-scs/components/automated-pentesting-iaas/overview.md",20189],ffd7fd32:[()=>n.e(31525).then(n.t.bind(n,10367,19)),"@generated/docusaurus-plugin-content-docs/contributor-docs/__plugin.json",10367],fff06078:[()=>n.e(92710).then(n.bind(n,18902)),"@site/docs/02-iaas/guides/concept-guide/components/k3s.md",18902],fff9aecb:[()=>n.e(53649).then(n.bind(n,19196)),"@site/docs/02-iaas/guides/upgrade-guide/index.md",19196]};var i=n(74848);function c(e){let{error:t,retry:n,pastDelay:s}=e;return t?(0,i.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,i.jsx)("p",{children:String(t)}),(0,i.jsx)("div",{children:(0,i.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):s?(0,i.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,i.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,i.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,i.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,i.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,i.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,i.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,i.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,i.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var d=n(86921),u=n(53102);function l(e,t){if("*"===e)return o()({loading:c,loader:()=>n.e(82237).then(n.bind(n,82237)),modules:["@theme/NotFound"],webpack:()=>[82237],render(e,t){const n=e.default;return(0,i.jsx)(u.W,{value:{plugin:{name:"native",id:"default"}},children:(0,i.jsx)(n,{...t})})}});const s=a[`${e}-${t}`],l={},p=[],m=[],g=(0,d.A)(s);return Object.entries(g).forEach((e=>{let[t,n]=e;const s=r[n];s&&(l[t]=s[0],p.push(s[1]),m.push(s[2]))})),o().Map({loading:c,loader:l,modules:p,webpack:()=>m,render(t,n){const o=JSON.parse(JSON.stringify(s));Object.entries(t).forEach((t=>{let[n,s]=t;const a=s.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(s).filter((e=>"default"!==e)).forEach((e=>{a[e]=s[e]}));let r=o;const i=n.split(".");i.slice(0,-1).forEach((e=>{r=r[e]})),r[i[i.length-1]]=a}));const a=o.__comp;delete o.__comp;const r=o.__context;delete o.__context;const c=o.__props;return delete o.__props,(0,i.jsx)(u.W,{value:r,children:(0,i.jsx)(a,{...o,...c,...n})})}})}const p=[{path:"/blog",component:l("/blog","5a1"),exact:!0},{path:"/blog/archive",component:l("/blog/archive","182"),exact:!0},{path:"/blog/authors",component:l("/blog/authors","0b7"),exact:!0},{path:"/blog/first-blog-post",component:l("/blog/first-blog-post","fa7"),exact:!0},{path:"/blog/tags",component:l("/blog/tags","287"),exact:!0},{path:"/blog/tags/community",component:l("/blog/tags/community","ef6"),exact:!0},{path:"/blog/tags/howto",component:l("/blog/tags/howto","5bd"),exact:!0},{path:"/search",component:l("/search","822"),exact:!0},{path:"/community",component:l("/community","874"),routes:[{path:"/community",component:l("/community","63f"),routes:[{path:"/community",component:l("/community","7eb"),routes:[{path:"/community/",component:l("/community/","067"),exact:!0,sidebar:"community"},{path:"/community/category/contribute-to-docs",component:l("/community/category/contribute-to-docs","5e1"),exact:!0,sidebar:"community"},{path:"/community/category/tools",component:l("/community/category/tools","c8f"),exact:!0,sidebar:"community"},{path:"/community/central-services/plusserver-gx-scs",component:l("/community/central-services/plusserver-gx-scs","8a6"),exact:!0},{path:"/community/cloud-resources/",component:l("/community/cloud-resources/","8ee"),exact:!0,sidebar:"community"},{path:"/community/cloud-resources/getting-started-openstack",component:l("/community/cloud-resources/getting-started-openstack","963"),exact:!0,sidebar:"community"},{path:"/community/cloud-resources/plusserver-gx-scs",component:l("/community/cloud-resources/plusserver-gx-scs","ec9"),exact:!0,sidebar:"community"},{path:"/community/cloud-resources/wavestack",component:l("/community/cloud-resources/wavestack","a83"),exact:!0,sidebar:"community"},{path:"/community/collaboration/",component:l("/community/collaboration/","147"),exact:!0,sidebar:"community"},{path:"/community/collaboration/sig-central-api",component:l("/community/collaboration/sig-central-api","b3d"),exact:!0,sidebar:"community"},{path:"/community/collaboration/sig-community",component:l("/community/collaboration/sig-community","c49"),exact:!0,sidebar:"community"},{path:"/community/collaboration/sig-documentation",component:l("/community/collaboration/sig-documentation","b1a"),exact:!0,sidebar:"community"},{path:"/community/collaboration/sig-monitoring",component:l("/community/collaboration/sig-monitoring","7fc"),exact:!0,sidebar:"community"},{path:"/community/collaboration/sig-standardization",component:l("/community/collaboration/sig-standardization","177"),exact:!0,sidebar:"community"},{path:"/community/collaboration/team-container",component:l("/community/collaboration/team-container","7b3"),exact:!0,sidebar:"community"},{path:"/community/collaboration/team-iaas",component:l("/community/collaboration/team-iaas","c05"),exact:!0,sidebar:"community"},{path:"/community/collaboration/team-iam",component:l("/community/collaboration/team-iam","202"),exact:!0,sidebar:"community"},{path:"/community/collaboration/team-ops",component:l("/community/collaboration/team-ops","960"),exact:!0,sidebar:"community"},{path:"/community/contribute/adding-docs-guide",component:l("/community/contribute/adding-docs-guide","cc6"),exact:!0,sidebar:"community"},{path:"/community/contribute/doc-files-structure-guide",component:l("/community/contribute/doc-files-structure-guide","195"),exact:!0,sidebar:"community"},{path:"/community/contribute/docs-workflow-explanation",component:l("/community/contribute/docs-workflow-explanation","d63"),exact:!0,sidebar:"community"},{path:"/community/contribute/linting-guide",component:l("/community/contribute/linting-guide","088"),exact:!0,sidebar:"community"},{path:"/community/contribute/local-docusaurus-development-guide",component:l("/community/contribute/local-docusaurus-development-guide","83e"),exact:!0,sidebar:"community"},{path:"/community/contribute/styleguide",component:l("/community/contribute/styleguide","a62"),exact:!0,sidebar:"community"},{path:"/community/contribute/styleguides/ansible_styleguide",component:l("/community/contribute/styleguides/ansible_styleguide","e67"),exact:!0},{path:"/community/hackathons/checklist",component:l("/community/hackathons/checklist","592"),exact:!0},{path:"/community/license-considerations",component:l("/community/license-considerations","150"),exact:!0,sidebar:"community"},{path:"/community/mission-statement",component:l("/community/mission-statement","532"),exact:!0,sidebar:"community"},{path:"/community/tools/github/branchprotection",component:l("/community/tools/github/branchprotection","f89"),exact:!0,sidebar:"community"},{path:"/community/tools/github/dco-and-licenses",component:l("/community/tools/github/dco-and-licenses","276"),exact:!0,sidebar:"community"},{path:"/community/tools/github/tips-and-tricks",component:l("/community/tools/github/tips-and-tricks","923"),exact:!0,sidebar:"community"},{path:"/community/tools/jitsi",component:l("/community/tools/jitsi","a31"),exact:!0,sidebar:"community"},{path:"/community/tools/mailinglists",component:l("/community/tools/mailinglists","85e"),exact:!0,sidebar:"community"},{path:"/community/tools/matrix",component:l("/community/tools/matrix","9e6"),exact:!0,sidebar:"community"},{path:"/community/tools/nextcloud",component:l("/community/tools/nextcloud","f9d"),exact:!0,sidebar:"community"},{path:"/community/tools/zuul",component:l("/community/tools/zuul","faa"),exact:!0,sidebar:"community"}]}]}]},{path:"/contributor-docs",component:l("/contributor-docs","a3e"),routes:[{path:"/contributor-docs",component:l("/contributor-docs","5fd"),routes:[{path:"/contributor-docs",component:l("/contributor-docs","60f"),routes:[{path:"/contributor-docs/",component:l("/contributor-docs/","5c4"),exact:!0,sidebar:"devDocs"},{path:"/contributor-docs/development/",component:l("/contributor-docs/development/","b39"),exact:!0,sidebar:"devDocs"},{path:"/contributor-docs/development/tests/rfc2119-keyword-test-guide",component:l("/contributor-docs/development/tests/rfc2119-keyword-test-guide","017"),exact:!0,sidebar:"devDocs"},{path:"/contributor-docs/development/tests/test-implementation-guide",component:l("/contributor-docs/development/tests/test-implementation-guide","8a6"),exact:!0,sidebar:"devDocs"},{path:"/contributor-docs/operations/iam/identity-federation-in-scs",component:l("/contributor-docs/operations/iam/identity-federation-in-scs","b16"),exact:!0,sidebar:"devDocs"},{path:"/contributor-docs/operations/iam/openstack-federation-via-oidc",component:l("/contributor-docs/operations/iam/openstack-federation-via-oidc","377"),exact:!0,sidebar:"devDocs"},{path:"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide",component:l("/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","ec0"),exact:!0,sidebar:"devDocs"}]}]}]},{path:"/docs",component:l("/docs","436"),routes:[{path:"/docs",component:l("/docs","fbe"),routes:[{path:"/docs",component:l("/docs","760"),routes:[{path:"/docs/",component:l("/docs/","6df"),exact:!0,sidebar:"docs"},{path:"/docs/category/api",component:l("/docs/category/api","be3"),exact:!0,sidebar:"docs"},{path:"/docs/category/automated-pentesting",component:l("/docs/category/automated-pentesting","357"),exact:!0,sidebar:"docs"},{path:"/docs/category/central-api",component:l("/docs/category/central-api","964"),exact:!0,sidebar:"docs"},{path:"/docs/category/cluster-stacks",component:l("/docs/category/cluster-stacks","b3a"),exact:!0,sidebar:"docs"},{path:"/docs/category/components",component:l("/docs/category/components","d2a"),exact:!0,sidebar:"docs"},{path:"/docs/category/components-1",component:l("/docs/category/components-1","6a9"),exact:!0,sidebar:"docs"},{path:"/docs/category/components-2",component:l("/docs/category/components-2","df4"),exact:!0,sidebar:"docs"},{path:"/docs/category/concepts",component:l("/docs/category/concepts","cd6"),exact:!0,sidebar:"docs"},{path:"/docs/category/configuration",component:l("/docs/category/configuration","cf7"),exact:!0,sidebar:"docs"},{path:"/docs/category/container-registry",component:l("/docs/category/container-registry","0a2"),exact:!0,sidebar:"docs"},{path:"/docs/category/deployment",component:l("/docs/category/deployment","d76"),exact:!0,sidebar:"docs"},{path:"/docs/category/deployment-examples",component:l("/docs/category/deployment-examples","e79"),exact:!0,sidebar:"docs"},{path:"/docs/category/guides-1",component:l("/docs/category/guides-1","377"),exact:!0,sidebar:"docs"},{path:"/docs/category/guides-2",component:l("/docs/category/guides-2","f14"),exact:!0,sidebar:"docs"},{path:"/docs/category/iaas-layer",component:l("/docs/category/iaas-layer","8da"),exact:!0,sidebar:"docs"},{path:"/docs/category/metering",component:l("/docs/category/metering","004"),exact:!0,sidebar:"docs"},{path:"/docs/category/monitoring",component:l("/docs/category/monitoring","eeb"),exact:!0,sidebar:"docs"},{path:"/docs/category/operating-scs",component:l("/docs/category/operating-scs","52c"),exact:!0,sidebar:"docs"},{path:"/docs/category/pentesting-iaas",component:l("/docs/category/pentesting-iaas","52a"),exact:!0,sidebar:"docs"},{path:"/docs/category/pentesting-kaas",component:l("/docs/category/pentesting-kaas","508"),exact:!0,sidebar:"docs"},{path:"/docs/category/releases",component:l("/docs/category/releases","358"),exact:!0,sidebar:"docs"},{path:"/docs/category/scs-health-monitor",component:l("/docs/category/scs-health-monitor","be7"),exact:!0,sidebar:"docs"},{path:"/docs/category/status-page",component:l("/docs/category/status-page","cd8"),exact:!0,sidebar:"docs"},{path:"/docs/category/turnkey-solution",component:l("/docs/category/turnkey-solution","67f"),exact:!0,sidebar:"docs"},{path:"/docs/category/web",component:l("/docs/category/web","e39"),exact:!0,sidebar:"docs"},{path:"/docs/container/",component:l("/docs/container/","6db"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow","5f7"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow","89d"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","c8a"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","74c"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow","3dc"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept","15a"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/","7f3"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration","c53"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing","e2e"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack","247"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology","fe2"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks","2e5"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","175"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot","8d7"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow","333"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","b05"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","2fa"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","057"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","ae8"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","408"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","d6e"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration",component:l("/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration","538"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/cluster-stacks/overview",component:l("/docs/container/components/cluster-stacks/components/cluster-stacks/overview","a87"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration",component:l("/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","2a9"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart",component:l("/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","20a"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/csctl/design",component:l("/docs/container/components/cluster-stacks/components/csctl/design","908"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl",component:l("/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","ce4"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/csctl/getting_started",component:l("/docs/container/components/cluster-stacks/components/csctl/getting_started","2ab"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl",component:l("/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl","476"),exact:!0},{path:"/docs/container/components/cluster-stacks/components/csctl/overview",component:l("/docs/container/components/cluster-stacks/components/csctl/overview","b0b"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/csctl/quickstart",component:l("/docs/container/components/cluster-stacks/components/csctl/quickstart","0dd"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/backup_and_restore",component:l("/docs/container/components/container-registry/docs/backup_and_restore","8f9"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/ha-deployment",component:l("/docs/container/components/container-registry/docs/ha-deployment","799"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/migration",component:l("/docs/container/components/container-registry/docs/migration","33a"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/persistence",component:l("/docs/container/components/container-registry/docs/persistence","90e"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/quickstart",component:l("/docs/container/components/container-registry/docs/quickstart","772"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/rate_limit",component:l("/docs/container/components/container-registry/docs/rate_limit","017"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/scs-deployment",component:l("/docs/container/components/container-registry/docs/scs-deployment","5f3"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/upgrade",component:l("/docs/container/components/container-registry/docs/upgrade","e27"),exact:!0,sidebar:"docs"},{path:"/docs/container/deployment-examples/a/",component:l("/docs/container/deployment-examples/a/","eab"),exact:!0},{path:"/docs/container/deployment-examples/a/hardware",component:l("/docs/container/deployment-examples/a/hardware","c9f"),exact:!0},{path:"/docs/container/deployment-examples/a/software",component:l("/docs/container/deployment-examples/a/software","4b1"),exact:!0},{path:"/docs/container/guides/guide1",component:l("/docs/container/guides/guide1","fe9"),exact:!0},{path:"/docs/container/overview/architecture",component:l("/docs/container/overview/architecture","96d"),exact:!0},{path:"/docs/container/overview/knowledge",component:l("/docs/container/overview/knowledge","b1b"),exact:!0},{path:"/docs/faq/",component:l("/docs/faq/","ab5"),exact:!0,sidebar:"docs"},{path:"/docs/getting-started/containerization",component:l("/docs/getting-started/containerization","6c3"),exact:!0},{path:"/docs/getting-started/overview",component:l("/docs/getting-started/overview","4b2"),exact:!0},{path:"/docs/getting-started/virtualization",component:l("/docs/getting-started/virtualization","01b"),exact:!0},{path:"/docs/glossary",component:l("/docs/glossary","c6d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/components/",component:l("/docs/iaas/components/","d45"),exact:!0},{path:"/docs/iaas/components/flavor-manager",component:l("/docs/iaas/components/flavor-manager","8e8"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/components/image-manager/",component:l("/docs/iaas/components/image-manager/","ceb"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/components/image-manager/update",component:l("/docs/iaas/components/image-manager/update","d83"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/components/openstack-health-monitor",component:l("/docs/iaas/components/openstack-health-monitor","d38"),exact:!0},{path:"/docs/iaas/components/project-manager",component:l("/docs/iaas/components/project-manager","b8e"),exact:!0},{path:"/docs/iaas/components/resource-manager",component:l("/docs/iaas/components/resource-manager","a61"),exact:!0},{path:"/docs/iaas/components/sandbox-manager",component:l("/docs/iaas/components/sandbox-manager","941"),exact:!0},{path:"/docs/iaas/components/simple-stress",component:l("/docs/iaas/components/simple-stress","9d1"),exact:!0},{path:"/docs/iaas/deployment-examples/artcodix/",component:l("/docs/iaas/deployment-examples/artcodix/","9e8"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/",component:l("/docs/iaas/guides/","df7"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/",component:l("/docs/iaas/guides/concept-guide/","879"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/",component:l("/docs/iaas/guides/concept-guide/components/","631"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/ceph",component:l("/docs/iaas/guides/concept-guide/components/ceph","7ba"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/clusterapi",component:l("/docs/iaas/guides/concept-guide/components/clusterapi","e03"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/gardener",component:l("/docs/iaas/guides/concept-guide/components/gardener","ab9"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/ironic",component:l("/docs/iaas/guides/concept-guide/components/ironic","4b7"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/k3s",component:l("/docs/iaas/guides/concept-guide/components/k3s","481"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/keycloak",component:l("/docs/iaas/guides/concept-guide/components/keycloak","7d2"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/netdata",component:l("/docs/iaas/guides/concept-guide/components/netdata","071"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/openstack",component:l("/docs/iaas/guides/concept-guide/components/openstack","5e1"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/prometheus",component:l("/docs/iaas/guides/concept-guide/components/prometheus","402"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/sonic",component:l("/docs/iaas/guides/concept-guide/components/sonic","133"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/teleport",component:l("/docs/iaas/guides/concept-guide/components/teleport","bef"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/design",component:l("/docs/iaas/guides/concept-guide/design","99a"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/hardware-bom",component:l("/docs/iaas/guides/concept-guide/hardware-bom","98f"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/layers",component:l("/docs/iaas/guides/concept-guide/layers","d21"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/nodes",component:l("/docs/iaas/guides/concept-guide/nodes","6f1"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/use-cases",component:l("/docs/iaas/guides/concept-guide/use-cases","fcd"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/",component:l("/docs/iaas/guides/configuration-guide/","2af"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/ceph",component:l("/docs/iaas/guides/configuration-guide/ceph","19e"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/",component:l("/docs/iaas/guides/configuration-guide/commons/","25b"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/certificates",component:l("/docs/iaas/guides/configuration-guide/commons/certificates","d0a"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/packages",component:l("/docs/iaas/guides/configuration-guide/commons/packages","3a4"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/resolvconf",component:l("/docs/iaas/guides/configuration-guide/commons/resolvconf","d42"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/services",component:l("/docs/iaas/guides/configuration-guide/commons/services","97a"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/sshconfig",component:l("/docs/iaas/guides/configuration-guide/commons/sshconfig","505"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/sysctl",component:l("/docs/iaas/guides/configuration-guide/commons/sysctl","635"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/timezone",component:l("/docs/iaas/guides/configuration-guide/commons/timezone","4b5"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/user",component:l("/docs/iaas/guides/configuration-guide/commons/user","8d4"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/configuration-repository",component:l("/docs/iaas/guides/configuration-guide/configuration-repository","b47"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/inventory",component:l("/docs/iaas/guides/configuration-guide/inventory","559"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/loadbalancer",component:l("/docs/iaas/guides/configuration-guide/loadbalancer","f93"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/manager",component:l("/docs/iaas/guides/configuration-guide/manager","3a7"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/network",component:l("/docs/iaas/guides/configuration-guide/network","7d8"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/",component:l("/docs/iaas/guides/configuration-guide/openstack/","318"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/aodh",component:l("/docs/iaas/guides/configuration-guide/openstack/aodh","9b8"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/barbican",component:l("/docs/iaas/guides/configuration-guide/openstack/barbican","d39"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/ceilometer",component:l("/docs/iaas/guides/configuration-guide/openstack/ceilometer","910"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/cinder",component:l("/docs/iaas/guides/configuration-guide/openstack/cinder","e9b"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/designate",component:l("/docs/iaas/guides/configuration-guide/openstack/designate","14f"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/glance",component:l("/docs/iaas/guides/configuration-guide/openstack/glance","c89"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/heat",component:l("/docs/iaas/guides/configuration-guide/openstack/heat","e58"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/horizon",component:l("/docs/iaas/guides/configuration-guide/openstack/horizon","f63"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/ironic",component:l("/docs/iaas/guides/configuration-guide/openstack/ironic","7b4"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/keystone",component:l("/docs/iaas/guides/configuration-guide/openstack/keystone","5bb"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/magnum",component:l("/docs/iaas/guides/configuration-guide/openstack/magnum","9df"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/manila",component:l("/docs/iaas/guides/configuration-guide/openstack/manila","2b1"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/neutron",component:l("/docs/iaas/guides/configuration-guide/openstack/neutron","efe"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/nova",component:l("/docs/iaas/guides/configuration-guide/openstack/nova","88d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/octavia",component:l("/docs/iaas/guides/configuration-guide/openstack/octavia","493"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/placement",component:l("/docs/iaas/guides/configuration-guide/openstack/placement","d48"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/skyline",component:l("/docs/iaas/guides/configuration-guide/openstack/skyline","f6d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/proxy",component:l("/docs/iaas/guides/configuration-guide/proxy","f21"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/rook",component:l("/docs/iaas/guides/configuration-guide/rook","aad"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/rookify",component:l("/docs/iaas/guides/configuration-guide/rookify","f93"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/services/",component:l("/docs/iaas/guides/configuration-guide/services/","4fe"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/services/chrony",component:l("/docs/iaas/guides/configuration-guide/services/chrony","6aa"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/services/docker",component:l("/docs/iaas/guides/configuration-guide/services/docker","bba"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/services/tuned",component:l("/docs/iaas/guides/configuration-guide/services/tuned","3ce"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/validations/",component:l("/docs/iaas/guides/configuration-guide/validations/","36a"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/",component:l("/docs/iaas/guides/deploy-guide/","0d0"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/bootstrap",component:l("/docs/iaas/guides/deploy-guide/bootstrap","4b5"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/examples/",component:l("/docs/iaas/guides/deploy-guide/examples/","d9c"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box",component:l("/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box","449"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/examples/testbed",component:l("/docs/iaas/guides/deploy-guide/examples/testbed","50d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/manager",component:l("/docs/iaas/guides/deploy-guide/manager","3b6"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/provisioning",component:l("/docs/iaas/guides/deploy-guide/provisioning","d32"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/rookify",component:l("/docs/iaas/guides/deploy-guide/rookify","8e7"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/seed",component:l("/docs/iaas/guides/deploy-guide/seed","159"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/",component:l("/docs/iaas/guides/deploy-guide/services/","38d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/ceph",component:l("/docs/iaas/guides/deploy-guide/services/ceph","daa"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/infrastructure",component:l("/docs/iaas/guides/deploy-guide/services/infrastructure","a32"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/kubernetes",component:l("/docs/iaas/guides/deploy-guide/services/kubernetes","22e"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/logging-monitoring",component:l("/docs/iaas/guides/deploy-guide/services/logging-monitoring","305"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/network",component:l("/docs/iaas/guides/deploy-guide/services/network","87b"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/openstack",component:l("/docs/iaas/guides/deploy-guide/services/openstack","ff3"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/rook",component:l("/docs/iaas/guides/deploy-guide/services/rook","045"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/rookify",component:l("/docs/iaas/guides/deploy-guide/services/rookify","974"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/",component:l("/docs/iaas/guides/operations-guide/","a65"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/ceph",component:l("/docs/iaas/guides/operations-guide/ceph","205"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/infrastructure",component:l("/docs/iaas/guides/operations-guide/infrastructure","4a9"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/manager/",component:l("/docs/iaas/guides/operations-guide/manager/","be8"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/manager/apply",component:l("/docs/iaas/guides/operations-guide/manager/apply","a48"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/manager/console",component:l("/docs/iaas/guides/operations-guide/manager/console","99f"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/manager/get",component:l("/docs/iaas/guides/operations-guide/manager/get","831"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/manager/log",component:l("/docs/iaas/guides/operations-guide/manager/log","be6"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/manager/task",component:l("/docs/iaas/guides/operations-guide/manager/task","78e"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/network",component:l("/docs/iaas/guides/operations-guide/network","061"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/",component:l("/docs/iaas/guides/operations-guide/openstack/","b4a"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/cinder",component:l("/docs/iaas/guides/operations-guide/openstack/cinder","186"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/keystone",component:l("/docs/iaas/guides/operations-guide/openstack/keystone","7d7"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/neutron",component:l("/docs/iaas/guides/operations-guide/openstack/neutron","675"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/nova",component:l("/docs/iaas/guides/operations-guide/openstack/nova","373"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/octavia",component:l("/docs/iaas/guides/operations-guide/openstack/octavia","639"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/",component:l("/docs/iaas/guides/operations-guide/openstack/tools/","cda"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager",component:l("/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","4fc"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/",component:l("/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","54e"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update",component:l("/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","3ac"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor",component:l("/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","049"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/project-manager",component:l("/docs/iaas/guides/operations-guide/openstack/tools/project-manager","87d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager",component:l("/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","b80"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager",component:l("/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager","849"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress",component:l("/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","144"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/rook",component:l("/docs/iaas/guides/operations-guide/rook","91c"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/rookify",component:l("/docs/iaas/guides/operations-guide/rookify","3de"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/",component:l("/docs/iaas/guides/other-guides/","895"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/cloud-in-a-box/",component:l("/docs/iaas/guides/other-guides/cloud-in-a-box/","a44"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine",component:l("/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","95f"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/contributor-guide",component:l("/docs/iaas/guides/other-guides/contributor-guide","815"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/developer-guide/",component:l("/docs/iaas/guides/other-guides/developer-guide/","6cc"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/developer-guide/releases",component:l("/docs/iaas/guides/other-guides/developer-guide/releases","f04"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/developer-guide/scripts",component:l("/docs/iaas/guides/other-guides/developer-guide/scripts","7e2"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/developer-guide/style-guide",component:l("/docs/iaas/guides/other-guides/developer-guide/style-guide","867"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/developer-guide/zuul",component:l("/docs/iaas/guides/other-guides/developer-guide/zuul","30c"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/testbed",component:l("/docs/iaas/guides/other-guides/testbed","5a6"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/troubleshooting-guide/",component:l("/docs/iaas/guides/troubleshooting-guide/","b72"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/troubleshooting-guide/ceph",component:l("/docs/iaas/guides/troubleshooting-guide/ceph","23b"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/troubleshooting-guide/manager",component:l("/docs/iaas/guides/troubleshooting-guide/manager","558"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/troubleshooting-guide/openstack",component:l("/docs/iaas/guides/troubleshooting-guide/openstack","ea9"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/troubleshooting-guide/rookify",component:l("/docs/iaas/guides/troubleshooting-guide/rookify","498"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/",component:l("/docs/iaas/guides/upgrade-guide/","f35"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/ceph",component:l("/docs/iaas/guides/upgrade-guide/ceph","29d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/docker",component:l("/docs/iaas/guides/upgrade-guide/docker","9f3"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/infrastructure",component:l("/docs/iaas/guides/upgrade-guide/infrastructure","12a"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/logging-monitoring",component:l("/docs/iaas/guides/upgrade-guide/logging-monitoring","ed7"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/manager",component:l("/docs/iaas/guides/upgrade-guide/manager","45f"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/network",component:l("/docs/iaas/guides/upgrade-guide/network","f8c"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/openstack",component:l("/docs/iaas/guides/upgrade-guide/openstack","9bc"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/",component:l("/docs/iaas/guides/user-guide/","fa4"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/migration-vmware-esxi",component:l("/docs/iaas/guides/user-guide/migration-vmware-esxi","b46"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/openstack/",component:l("/docs/iaas/guides/user-guide/openstack/","b9e"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso",component:l("/docs/iaas/guides/user-guide/openstack/install-instance-from-iso","842"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/openstack/openstackclient",component:l("/docs/iaas/guides/user-guide/openstack/openstackclient","f0b"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/openstack/security-groups",component:l("/docs/iaas/guides/user-guide/openstack/security-groups","ae9"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/openstack/user-data-backups",component:l("/docs/iaas/guides/user-guide/openstack/user-data-backups","5cd"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/security-groups/",component:l("/docs/iaas/guides/user-guide/security-groups/","486"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/user-data-backups",component:l("/docs/iaas/guides/user-guide/user-data-backups","a9b"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/overview/architecture",component:l("/docs/iaas/overview/architecture","74b"),exact:!0},{path:"/docs/iaas/overview/compute",component:l("/docs/iaas/overview/compute","d18"),exact:!0},{path:"/docs/iaas/overview/knowledge",component:l("/docs/iaas/overview/knowledge","a22"),exact:!0},{path:"/docs/iaas/overview/network",component:l("/docs/iaas/overview/network","abc"),exact:!0},{path:"/docs/iaas/overview/storage",component:l("/docs/iaas/overview/storage","187"),exact:!0},{path:"/docs/iam/",component:l("/docs/iam/","a74"),exact:!0,sidebar:"docs"},{path:"/docs/iam/domain-manager-setup-and-usage",component:l("/docs/iam/domain-manager-setup-and-usage","c6a"),exact:!0,sidebar:"docs"},{path:"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations",component:l("/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","e86"),exact:!0,sidebar:"docs"},{path:"/docs/iam/SCS-example-setup-configuration-description",component:l("/docs/iam/SCS-example-setup-configuration-description","fa9"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/audits/",component:l("/docs/operating-scs/audits/","bcc"),exact:!0},{path:"/docs/operating-scs/components/automated-pentesting-iaas/overview",component:l("/docs/operating-scs/components/automated-pentesting-iaas/overview","c28"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/automated-pentesting-iaas/quickstart",component:l("/docs/operating-scs/components/automated-pentesting-iaas/quickstart","83c"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/automated-pentesting-iaas/reports",component:l("/docs/operating-scs/components/automated-pentesting-iaas/reports","5a2"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/automated-pentesting-iaas/tools",component:l("/docs/operating-scs/components/automated-pentesting-iaas/tools","248"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/automated-pentesting-kaas/overview",component:l("/docs/operating-scs/components/automated-pentesting-kaas/overview","174"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/automated-pentesting-kaas/quickstart",component:l("/docs/operating-scs/components/automated-pentesting-kaas/quickstart","202"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/automated-pentesting-kaas/tools",component:l("/docs/operating-scs/components/automated-pentesting-kaas/tools","784"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/central-api/overview",component:l("/docs/operating-scs/components/central-api/overview","b4c"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/central-api/poc-setup",component:l("/docs/operating-scs/components/central-api/poc-setup","647"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/alertmanager",component:l("/docs/operating-scs/components/monitoring/docs/alertmanager","4f0"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/iaas",component:l("/docs/operating-scs/components/monitoring/docs/iaas","27c"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/infrastructure_services",component:l("/docs/operating-scs/components/monitoring/docs/infrastructure_services","b85"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/k3s",component:l("/docs/operating-scs/components/monitoring/docs/k3s","4af"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/kaas",component:l("/docs/operating-scs/components/monitoring/docs/kaas","819"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/oauth",component:l("/docs/operating-scs/components/monitoring/docs/oauth","e21"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/overview",component:l("/docs/operating-scs/components/monitoring/docs/overview","961"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/quickstart",component:l("/docs/operating-scs/components/monitoring/docs/quickstart","a9d"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/scs-deployment",component:l("/docs/operating-scs/components/monitoring/docs/scs-deployment","8be"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/status-page",component:l("/docs/operating-scs/components/monitoring/docs/status-page","28f"),exact:!0},{path:"/docs/operating-scs/components/monitoring/docs/tracing",component:l("/docs/operating-scs/components/monitoring/docs/tracing","207"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/tuning",component:l("/docs/operating-scs/components/monitoring/docs/tuning","374"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/zuul",component:l("/docs/operating-scs/components/monitoring/docs/zuul","6c6"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/scs-health-monitor/overview",component:l("/docs/operating-scs/components/scs-health-monitor/overview","2cd"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack",component:l("/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack","b20"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/scs-health-monitor/Testflow",component:l("/docs/operating-scs/components/scs-health-monitor/Testflow","ec7"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/scs-health-monitor/Workflow",component:l("/docs/operating-scs/components/scs-health-monitor/Workflow","cb0"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-api/docs/configuration",component:l("/docs/operating-scs/components/status-page-api/docs/configuration","2de"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-api/docs/contribute",component:l("/docs/operating-scs/components/status-page-api/docs/contribute","938"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-api/docs/example-requests",component:l("/docs/operating-scs/components/status-page-api/docs/example-requests","252"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-api/docs/overview",component:l("/docs/operating-scs/components/status-page-api/docs/overview","568"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-api/docs/quickstart",component:l("/docs/operating-scs/components/status-page-api/docs/quickstart","1f1"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-api/docs/requests",component:l("/docs/operating-scs/components/status-page-api/docs/requests","db7"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-api/docs/requirements",component:l("/docs/operating-scs/components/status-page-api/docs/requirements","46e"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-deployment/docs/admin-authentication",component:l("/docs/operating-scs/components/status-page-deployment/docs/admin-authentication","dd4"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-deployment/docs/configuration",component:l("/docs/operating-scs/components/status-page-deployment/docs/configuration","ce5"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-deployment/docs/contribute",component:l("/docs/operating-scs/components/status-page-deployment/docs/contribute","058"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-deployment/docs/faq",component:l("/docs/operating-scs/components/status-page-deployment/docs/faq","516"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-deployment/docs/k3s",component:l("/docs/operating-scs/components/status-page-deployment/docs/k3s","11c"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-deployment/docs/kind",component:l("/docs/operating-scs/components/status-page-deployment/docs/kind","c1f"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-deployment/docs/monitoring",component:l("/docs/operating-scs/components/status-page-deployment/docs/monitoring","0c8"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-deployment/docs/overview",component:l("/docs/operating-scs/components/status-page-deployment/docs/overview","e6f"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-deployment/docs/quickstart",component:l("/docs/operating-scs/components/status-page-deployment/docs/quickstart","0a0"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-deployment/docs/requirements",component:l("/docs/operating-scs/components/status-page-deployment/docs/requirements","d0f"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-deployment/docs/scs-public",component:l("/docs/operating-scs/components/status-page-deployment/docs/scs-public","a6a"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-deployment/docs/usage",component:l("/docs/operating-scs/components/status-page-deployment/docs/usage","78d"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-openapi/docs/component_overview",component:l("/docs/operating-scs/components/status-page-openapi/docs/component_overview","d26"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-openapi/docs/components",component:l("/docs/operating-scs/components/status-page-openapi/docs/components","199"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus",component:l("/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus","544"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-openapi/docs/overview",component:l("/docs/operating-scs/components/status-page-openapi/docs/overview","10a"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-web/docs/configuration",component:l("/docs/operating-scs/components/status-page-web/docs/configuration","c4b"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-web/docs/contribute",component:l("/docs/operating-scs/components/status-page-web/docs/contribute","cdf"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-web/docs/overview",component:l("/docs/operating-scs/components/status-page-web/docs/overview","588"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-web/docs/quickstart",component:l("/docs/operating-scs/components/status-page-web/docs/quickstart","ecd"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page-web/docs/requirements",component:l("/docs/operating-scs/components/status-page-web/docs/requirements","162"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install",component:l("/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","ec3"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/incident-management/",component:l("/docs/operating-scs/incident-management/","8c0"),exact:!0},{path:"/docs/operating-scs/lifecycle-management/",component:l("/docs/operating-scs/lifecycle-management/","88c"),exact:!0},{path:"/docs/operating-scs/logging/",component:l("/docs/operating-scs/logging/","ee2"),exact:!0},{path:"/docs/operating-scs/metering/meter_configuration",component:l("/docs/operating-scs/metering/meter_configuration","124"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/monitoring/",component:l("/docs/operating-scs/monitoring/","799"),exact:!0},{path:"/docs/operating-scs/overview",component:l("/docs/operating-scs/overview","061"),exact:!0},{path:"/docs/releases/Release0",component:l("/docs/releases/Release0","984"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release1",component:l("/docs/releases/Release1","1b3"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release2",component:l("/docs/releases/Release2","9c9"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release3",component:l("/docs/releases/Release3","e73"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release4",component:l("/docs/releases/Release4","9d8"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release5",component:l("/docs/releases/Release5","cb2"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release6",component:l("/docs/releases/Release6","b81"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release7",component:l("/docs/releases/Release7","b3c"),exact:!0,sidebar:"docs"},{path:"/docs/releases/ReleaseX",component:l("/docs/releases/ReleaseX","7e5"),exact:!0},{path:"/docs/standards/",component:l("/docs/standards/","109"),exact:!0},{path:"/docs/turnkey-solution/hardware-landscape",component:l("/docs/turnkey-solution/hardware-landscape","f10"),exact:!0,sidebar:"docs"},{path:"/docs/turnkey-solution/overview",component:l("/docs/turnkey-solution/overview","455"),exact:!0,sidebar:"docs"}]}]}]},{path:"/standards",component:l("/standards","241"),routes:[{path:"/standards",component:l("/standards","01d"),routes:[{path:"/standards",component:l("/standards","1d5"),routes:[{path:"/standards/",component:l("/standards/","9e3"),exact:!0,sidebar:"standards"},{path:"/standards/certification/overview",component:l("/standards/certification/overview","9ab"),exact:!0,sidebar:"standards"},{path:"/standards/certification/overview.template",component:l("/standards/certification/overview.template","562"),exact:!0},{path:"/standards/certification/pipeline",component:l("/standards/certification/pipeline","159"),exact:!0,sidebar:"standards"},{path:"/standards/certification/scopes-versions",component:l("/standards/certification/scopes-versions","ede"),exact:!0,sidebar:"standards"},{path:"/standards/global/",component:l("/standards/global/","f4a"),exact:!0,sidebar:"standards"},{path:"/standards/global/scs-0001",component:l("/standards/global/scs-0001","6bf"),exact:!0,sidebar:"standards"},{path:"/standards/global/scs-0002",component:l("/standards/global/scs-0002","08f"),exact:!0,sidebar:"standards"},{path:"/standards/global/scs-0003",component:l("/standards/global/scs-0003","9d4"),exact:!0,sidebar:"standards"},{path:"/standards/global/scs-0004",component:l("/standards/global/scs-0004","3df"),exact:!0,sidebar:"standards"},{path:"/standards/global/scs-0005",component:l("/standards/global/scs-0005","249"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/",component:l("/standards/iaas/","804"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0100",component:l("/standards/iaas/scs-0100","933"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0101",component:l("/standards/iaas/scs-0101","42d"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0102",component:l("/standards/iaas/scs-0102","78a"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0103",component:l("/standards/iaas/scs-0103","2e0"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0104",component:l("/standards/iaas/scs-0104","018"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0110",component:l("/standards/iaas/scs-0110","edb"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0111",component:l("/standards/iaas/scs-0111","fa3"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0112",component:l("/standards/iaas/scs-0112","536"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0113",component:l("/standards/iaas/scs-0113","819"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0114",component:l("/standards/iaas/scs-0114","514"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0115",component:l("/standards/iaas/scs-0115","eb1"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0116",component:l("/standards/iaas/scs-0116","82c"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0117",component:l("/standards/iaas/scs-0117","3ce"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0118",component:l("/standards/iaas/scs-0118","389"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0119",component:l("/standards/iaas/scs-0119","db8"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0120",component:l("/standards/iaas/scs-0120","618"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0121",component:l("/standards/iaas/scs-0121","37e"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0122",component:l("/standards/iaas/scs-0122","a6c"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0123",component:l("/standards/iaas/scs-0123","cd5"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0124",component:l("/standards/iaas/scs-0124","19d"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0125",component:l("/standards/iaas/scs-0125","2d1"),exact:!0,sidebar:"standards"},{path:"/standards/iam/",component:l("/standards/iam/","ac3"),exact:!0,sidebar:"standards"},{path:"/standards/iam/scs-0300",component:l("/standards/iam/scs-0300","171"),exact:!0,sidebar:"standards"},{path:"/standards/iam/scs-0301",component:l("/standards/iam/scs-0301","e8e"),exact:!0,sidebar:"standards"},{path:"/standards/iam/scs-0302",component:l("/standards/iam/scs-0302","469"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/",component:l("/standards/kaas/","a87"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0200",component:l("/standards/kaas/scs-0200","316"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0210",component:l("/standards/kaas/scs-0210","03c"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0211",component:l("/standards/kaas/scs-0211","a83"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0212",component:l("/standards/kaas/scs-0212","4a5"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0213",component:l("/standards/kaas/scs-0213","922"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0214",component:l("/standards/kaas/scs-0214","952"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0215",component:l("/standards/kaas/scs-0215","fcf"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0216",component:l("/standards/kaas/scs-0216","090"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0217",component:l("/standards/kaas/scs-0217","a99"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0218",component:l("/standards/kaas/scs-0218","c81"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0219",component:l("/standards/kaas/scs-0219","e54"),exact:!0,sidebar:"standards"},{path:"/standards/ops/",component:l("/standards/ops/","234"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0400",component:l("/standards/ops/scs-0400","24b"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0401",component:l("/standards/ops/scs-0401","a98"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0402",component:l("/standards/ops/scs-0402","b21"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0403",component:l("/standards/ops/scs-0403","425"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0410",component:l("/standards/ops/scs-0410","529"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0411",component:l("/standards/ops/scs-0411","44d"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0412",component:l("/standards/ops/scs-0412","8c6"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0001-v1-sovereign-cloud-standards",component:l("/standards/scs-0001-v1-sovereign-cloud-standards","695"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0002-v1-standards-docs-org",component:l("/standards/scs-0002-v1-standards-docs-org","0d6"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0002-v2-standards-docs-org",component:l("/standards/scs-0002-v2-standards-docs-org","33f"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",component:l("/standards/scs-0003-v1-sovereign-cloud-standards-yaml","27f"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0004-v1-achieving-certification",component:l("/standards/scs-0004-v1-achieving-certification","a54"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0005-v1-project-governance",component:l("/standards/scs-0005-v1-project-governance","948"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0100-v1-flavor-naming",component:l("/standards/scs-0100-v1-flavor-naming","678"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0100-v2-flavor-naming",component:l("/standards/scs-0100-v2-flavor-naming","c10"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0100-v3-flavor-naming",component:l("/standards/scs-0100-v3-flavor-naming","96d"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0100-w1-flavor-naming-implementation-testing",component:l("/standards/scs-0100-w1-flavor-naming-implementation-testing","6c8"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0101-v1-entropy",component:l("/standards/scs-0101-v1-entropy","474"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0101-w1-entropy-implementation-testing",component:l("/standards/scs-0101-w1-entropy-implementation-testing","bff"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0102-v1-image-metadata",component:l("/standards/scs-0102-v1-image-metadata","173"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0102-w1-image-metadata-implementation-testing",component:l("/standards/scs-0102-w1-image-metadata-implementation-testing","2f7"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0103-v1-standard-flavors",component:l("/standards/scs-0103-v1-standard-flavors","495"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0104-v1-standard-images",component:l("/standards/scs-0104-v1-standard-images","cd2"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0104-w1-standard-images-implementation",component:l("/standards/scs-0104-w1-standard-images-implementation","ba8"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0110-v1-ssd-flavors",component:l("/standards/scs-0110-v1-ssd-flavors","26f"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0111-v1-volume-type-decisions",component:l("/standards/scs-0111-v1-volume-type-decisions","8a3"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0112-v1-sonic",component:l("/standards/scs-0112-v1-sonic","a8a"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0113-v1-security-groups-decision-record",component:l("/standards/scs-0113-v1-security-groups-decision-record","148"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0114-v1-volume-type-standard",component:l("/standards/scs-0114-v1-volume-type-standard","161"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0115-v1-default-rules-for-security-groups",component:l("/standards/scs-0115-v1-default-rules-for-security-groups","e17"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0116-v1-key-manager-standard",component:l("/standards/scs-0116-v1-key-manager-standard","1f1"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0116-w1-key-manager-implementation-testing",component:l("/standards/scs-0116-w1-key-manager-implementation-testing","1e6"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0117-v1-volume-backup-service",component:l("/standards/scs-0117-v1-volume-backup-service","ba1"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0118-v1-taxonomy-of-failsafe-levels",component:l("/standards/scs-0118-v1-taxonomy-of-failsafe-levels","4e3"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0118-w1-example-impacts-of-failure-scenarios",component:l("/standards/scs-0118-w1-example-impacts-of-failure-scenarios","8da"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0119-v1-rook-decision",component:l("/standards/scs-0119-v1-rook-decision","32d"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0120-v1-capi-images",component:l("/standards/scs-0120-v1-capi-images","d92"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0121-v1-Availability-Zones-Standard",component:l("/standards/scs-0121-v1-Availability-Zones-Standard","46b"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0121-w1-Availability-Zones-Standard",component:l("/standards/scs-0121-w1-Availability-Zones-Standard","b4d"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0122-v1-node-to-node-encryption",component:l("/standards/scs-0122-v1-node-to-node-encryption","b32"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services",component:l("/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","f7e"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0124-v1-security-of-iaas-service-software",component:l("/standards/scs-0124-v1-security-of-iaas-service-software","903"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0124-w1-security-of-iaas-service-software",component:l("/standards/scs-0124-w1-security-of-iaas-service-software","ce8"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0125-v1-secure-connections",component:l("/standards/scs-0125-v1-secure-connections","9e2"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests",component:l("/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","7f6"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0210-v1-k8s-new-version-policy",component:l("/standards/scs-0210-v1-k8s-new-version-policy","267"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0210-v2-k8s-version-policy",component:l("/standards/scs-0210-v2-k8s-version-policy","76e"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0210-w1-k8s-version-policy-implementation-testing",component:l("/standards/scs-0210-w1-k8s-version-policy-implementation-testing","92b"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0211-v1-kaas-default-storage-class",component:l("/standards/scs-0211-v1-kaas-default-storage-class","70e"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0211-v2-kaas-default-storage-class",component:l("/standards/scs-0211-v2-kaas-default-storage-class","bf7"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing",component:l("/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing","254"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0212-v1-requirements-for-container-registries",component:l("/standards/scs-0212-v1-requirements-for-container-registries","6e1"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0213-v1-k8s-nodes-anti-affinity",component:l("/standards/scs-0213-v1-k8s-nodes-anti-affinity","8e6"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0214-v1-k8s-node-distribution",component:l("/standards/scs-0214-v1-k8s-node-distribution","317"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0214-v2-k8s-node-distribution",component:l("/standards/scs-0214-v2-k8s-node-distribution","69c"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing",component:l("/standards/scs-0214-w1-k8s-node-distribution-implementation-testing","155"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0215-v1-robustness-features",component:l("/standards/scs-0215-v1-robustness-features","38c"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks",component:l("/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","a90"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0217-v1-cluster-hardening",component:l("/standards/scs-0217-v1-cluster-hardening","75e"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation",component:l("/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","288"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0219-v1-kaas-networking",component:l("/standards/scs-0219-v1-kaas-networking","5ef"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0219-w1-kaas-networking",component:l("/standards/scs-0219-w1-kaas-networking","123"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0300-v1-requirements-for-sso-identity-federation",component:l("/standards/scs-0300-v1-requirements-for-sso-identity-federation","34f"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0301-v1-naming-conventions",component:l("/standards/scs-0301-v1-naming-conventions","6f1"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0302-v1-domain-manager-role",component:l("/standards/scs-0302-v1-domain-manager-role","b43"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0302-w1-domain-manager-implementation-notes",component:l("/standards/scs-0302-w1-domain-manager-implementation-notes","128"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0400-v1-status-page-create-decision",component:l("/standards/scs-0400-v1-status-page-create-decision","279"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0401-v1-status-page-reference-implementation-decision",component:l("/standards/scs-0401-v1-status-page-reference-implementation-decision","cc0"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0402-v1-status-page-openapi-spec-decision",component:l("/standards/scs-0402-v1-status-page-openapi-spec-decision","191"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0403-v1-csp-kaas-observability-stack",component:l("/standards/scs-0403-v1-csp-kaas-observability-stack","bb8"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0410-v1-gnocchi-as-metering-database",component:l("/standards/scs-0410-v1-gnocchi-as-metering-database","44a"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0411-v1-publishing_method_for_metering_data",component:l("/standards/scs-0411-v1-publishing_method_for_metering_data","dbc"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0412-v1-metering-json",component:l("/standards/scs-0412-v1-metering-json","3cc"),exact:!0,sidebar:"standards"},{path:"/standards/scs-compatible-iaas",component:l("/standards/scs-compatible-iaas","d6e"),exact:!0,sidebar:"standards"},{path:"/standards/scs-compatible-kaas",component:l("/standards/scs-compatible-kaas","dc7"),exact:!0,sidebar:"standards"},{path:"/standards/scs-XXXX-vN-decision-record-template",component:l("/standards/scs-XXXX-vN-decision-record-template","7f7"),exact:!0},{path:"/standards/scs-XXXX-vN-standard-template",component:l("/standards/scs-XXXX-vN-standard-template","a6a"),exact:!0},{path:"/standards/standards/overview",component:l("/standards/standards/overview","2a7"),exact:!0,sidebar:"standards"}]}]}]},{path:"/user-docs",component:l("/user-docs","75d"),routes:[{path:"/user-docs",component:l("/user-docs","051"),routes:[{path:"/user-docs",component:l("/user-docs","d7a"),routes:[{path:"/user-docs/",component:l("/user-docs/","b14"),exact:!0,sidebar:"userDocs"},{path:"/user-docs/application-examples/opendesk-on-scs/configuration",component:l("/user-docs/application-examples/opendesk-on-scs/configuration","729"),exact:!0,sidebar:"userDocs"},{path:"/user-docs/application-examples/opendesk-on-scs/contribute",component:l("/user-docs/application-examples/opendesk-on-scs/contribute","a2f"),exact:!0,sidebar:"userDocs"},{path:"/user-docs/application-examples/opendesk-on-scs/getting_started",component:l("/user-docs/application-examples/opendesk-on-scs/getting_started","7a9"),exact:!0,sidebar:"userDocs"},{path:"/user-docs/application-examples/opendesk-on-scs/overview",component:l("/user-docs/application-examples/opendesk-on-scs/overview","e94"),exact:!0,sidebar:"userDocs"},{path:"/user-docs/application-examples/opendesk-on-scs/quickstart",component:l("/user-docs/application-examples/opendesk-on-scs/quickstart","2a5"),exact:!0,sidebar:"userDocs"},{path:"/user-docs/application-examples/opendesk-on-scs/requirements",component:l("/user-docs/application-examples/opendesk-on-scs/requirements","1ed"),exact:!0,sidebar:"userDocs"},{path:"/user-docs/application-examples/opendesk-on-scs/user-import",component:l("/user-docs/application-examples/opendesk-on-scs/user-import","4de"),exact:!0,sidebar:"userDocs"},{path:"/user-docs/category/application-examples",component:l("/user-docs/category/application-examples","066"),exact:!0,sidebar:"userDocs"},{path:"/user-docs/category/opendesk-on-scs",component:l("/user-docs/category/opendesk-on-scs","8dc"),exact:!0,sidebar:"userDocs"}]}]}]},{path:"/",component:l("/","e5f"),exact:!0},{path:"*",component:l("*")}]},6125:(e,t,n)=>{"use strict";n.d(t,{o:()=>a,x:()=>r});var s=n(96540),o=n(74848);const a=s.createContext(!1);function r(e){let{children:t}=e;const[n,r]=(0,s.useState)(!1);return(0,s.useEffect)((()=>{r(!0)}),[]),(0,o.jsx)(a.Provider,{value:n,children:t})}},77815:(e,t,n)=>{"use strict";var s=n(96540),o=n(5338),a=n(80545),r=n(54625),i=n(4784),c=n(38193);const d=[n(10119),n(26134),n(76294),n(51043),n(45477)];var u=n(35947),l=n(56347),p=n(22831),m=n(74848);function g(e){let{children:t}=e;return(0,m.jsx)(m.Fragment,{children:t})}var f=n(5260),h=n(44586),b=n(86025),y=n(6342),v=n(61213),k=n(32131),x=n(14090);const w="default";var _=n(70440),S=n(41463);function E(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,h.A)(),s=(0,k.o)(),o=n[e].htmlLang,a=e=>e.replace("-","_");return(0,m.jsxs)(f.A,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,m.jsx)("link",{rel:"alternate",href:s.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,m.jsx)("link",{rel:"alternate",href:s.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,m.jsx)("meta",{property:"og:locale",content:a(o)}),Object.values(n).filter((e=>o!==e.htmlLang)).map((e=>(0,m.jsx)("meta",{property:"og:locale:alternate",content:a(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function C(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.A)(),s=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.A)(),{pathname:s}=(0,l.zy)();return e+(0,_.Ks)((0,b.Ay)(s),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:s;return(0,m.jsxs)(f.A,{children:[(0,m.jsx)("meta",{property:"og:url",content:o}),(0,m.jsx)("link",{rel:"canonical",href:o})]})}function T(){const{i18n:{currentLocale:e}}=(0,h.A)(),{metadata:t,image:n}=(0,y.p)();return(0,m.jsxs)(m.Fragment,{children:[(0,m.jsxs)(f.A,{children:[(0,m.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,m.jsx)("body",{className:x.w})]}),n&&(0,m.jsx)(v.be,{image:n}),(0,m.jsx)(C,{}),(0,m.jsx)(E,{}),(0,m.jsx)(S.A,{tag:w,locale:e}),(0,m.jsx)(f.A,{children:t.map(((e,t)=>(0,m.jsx)("meta",{...e},t)))})]})}const A=new Map;var j=n(6125),P=n(26988),L=n(205);function R(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),s=1;s<t;s++)n[s-1]=arguments[s];const o=d.map((t=>{const s=t.default?.[e]??t[e];return s?.(...n)}));return()=>o.forEach((e=>e?.()))}const N=function(e){let{children:t,location:n,previousLocation:s}=e;return(0,L.A)((()=>{s!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const s=t.pathname===n.pathname,o=t.hash===n.hash,a=t.search===n.search;if(s&&o&&!a)return;const{hash:r}=t;if(r){const e=decodeURIComponent(r.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:s}),R("onRouteDidUpdate",{previousLocation:s,location:n}))}),[s,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,p.u)(u.A,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class I extends s.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=c.A.canUseDOM?R("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=R("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),O(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,m.jsx)(N,{previousLocation:this.previousLocation,location:t,children:(0,m.jsx)(l.qh,{location:t,render:()=>e})})}}const D=I,F="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",z="__docusaurus-base-url-issue-banner-suggestion-container";function B(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${F}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="${M}" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${z}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n document.body.prepend(bannerContainer);\n var suggestionContainer = document.getElementById('${z}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function $(){const{siteConfig:{baseUrl:e}}=(0,h.A)();return(0,m.jsx)(m.Fragment,{children:!c.A.canUseDOM&&(0,m.jsx)(f.A,{children:(0,m.jsx)("script",{children:B(e)})})})}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,h.A)(),{pathname:n}=(0,l.zy)();return t&&n===e?(0,m.jsx)($,{}):null}function q(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:s,localeConfigs:o}}=(0,h.A)(),a=(0,b.Ay)(e),{htmlLang:r,direction:i}=o[s];return(0,m.jsxs)(f.A,{children:[(0,m.jsx)("html",{lang:r,dir:i}),(0,m.jsx)("title",{children:t}),(0,m.jsx)("meta",{property:"og:title",content:t}),(0,m.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&(0,m.jsx)("meta",{name:"robots",content:"noindex, nofollow"}),e&&(0,m.jsx)("link",{rel:"icon",href:a})]})}var Q=n(67489),V=n(92303);function H(){const e=(0,V.A)();return(0,m.jsx)(f.A,{children:(0,m.jsx)("html",{"data-has-hydrated":e})})}const W=(0,p.v)(u.A);function G(){const e=function(e){if(A.has(e.pathname))return{...e,pathname:A.get(e.pathname)};if((0,p.u)(u.A,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return A.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return A.set(e.pathname,t),{...e,pathname:t}}((0,l.zy)());return(0,m.jsx)(D,{location:e,children:W})}function X(){return(0,m.jsx)(Q.A,{children:(0,m.jsx)(P.l,{children:(0,m.jsxs)(j.x,{children:[(0,m.jsxs)(g,{children:[(0,m.jsx)(q,{}),(0,m.jsx)(T,{}),(0,m.jsx)(U,{}),(0,m.jsx)(G,{})]}),(0,m.jsx)(H,{})]})})})}var K=n(84054);const Z=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const s=document.createElement("link");s.setAttribute("rel","prefetch"),s.setAttribute("href",e),s.onload=()=>t(),s.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(s)}))}:function(e){return new Promise(((t,n)=>{const s=new XMLHttpRequest;s.open("GET",e,!0),s.withCredentials=!0,s.onload=()=>{200===s.status?t():n()},s.send(null)}))};var Y=n(86921);const J=new Set,ee=new Set,te=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ne={prefetch:e=>{if(!(e=>!te()&&!ee.has(e)&&!J.has(e))(e))return!1;J.add(e);const t=(0,p.u)(u.A,e).flatMap((e=>{return t=e.route.path,Object.entries(K).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Y.A)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Z(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!te()&&!ee.has(e))(e)&&(ee.add(e),O(e))},se=Object.freeze(ne);function oe(e){let{children:t}=e;return"hash"===i.default.future.experimental_router?(0,m.jsx)(r.I9,{children:t}):(0,m.jsx)(r.Kd,{children:t})}const ae=Boolean(!0);if(c.A.canUseDOM){window.docusaurus=se;const e=document.getElementById("__docusaurus"),t=(0,m.jsx)(a.vd,{children:(0,m.jsx)(oe,{children:(0,m.jsx)(X,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},r=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(ae)window.docusaurusRoot=o.hydrateRoot(e,t,{onRecoverableError:n});else{const s=o.createRoot(e,{onRecoverableError:n});s.render(t),window.docusaurusRoot=s}};O(window.location.pathname).then((()=>{(0,s.startTransition)(r)}))}},26988:(e,t,n)=>{"use strict";n.d(t,{o:()=>l,l:()=>p});var s=n(96540),o=n(4784);const a=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"index","docs":[{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/concept","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/develop/develop","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/terminology","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow"},{"id":"container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","path":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks"},{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","path":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","path":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","path":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","path":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","path":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting"},{"id":"container/components/cluster-stacks/components/cluster-stacks/continuous-integration","path":"/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration"},{"id":"container/components/cluster-stacks/components/cluster-stacks/overview","path":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","path":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","path":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/csctl/design","path":"/docs/container/components/cluster-stacks/components/csctl/design"},{"id":"container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","path":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/csctl/getting_started","path":"/docs/container/components/cluster-stacks/components/csctl/getting_started","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/csctl/how_to_use_csctl","path":"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl"},{"id":"container/components/cluster-stacks/components/csctl/overview","path":"/docs/container/components/cluster-stacks/components/csctl/overview","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/csctl/quickstart","path":"/docs/container/components/cluster-stacks/components/csctl/quickstart","sidebar":"docs"},{"id":"container/components/container-registry/docs/backup_and_restore","path":"/docs/container/components/container-registry/docs/backup_and_restore","sidebar":"docs"},{"id":"container/components/container-registry/docs/ha-deployment","path":"/docs/container/components/container-registry/docs/ha-deployment","sidebar":"docs"},{"id":"container/components/container-registry/docs/migration","path":"/docs/container/components/container-registry/docs/migration","sidebar":"docs"},{"id":"container/components/container-registry/docs/persistence","path":"/docs/container/components/container-registry/docs/persistence","sidebar":"docs"},{"id":"container/components/container-registry/docs/quickstart","path":"/docs/container/components/container-registry/docs/quickstart","sidebar":"docs"},{"id":"container/components/container-registry/docs/rate_limit","path":"/docs/container/components/container-registry/docs/rate_limit","sidebar":"docs"},{"id":"container/components/container-registry/docs/scs-deployment","path":"/docs/container/components/container-registry/docs/scs-deployment","sidebar":"docs"},{"id":"container/components/container-registry/docs/upgrade","path":"/docs/container/components/container-registry/docs/upgrade","sidebar":"docs"},{"id":"container/deployment-examples/a/hardware","path":"/docs/container/deployment-examples/a/hardware"},{"id":"container/deployment-examples/a/index","path":"/docs/container/deployment-examples/a/"},{"id":"container/deployment-examples/a/software","path":"/docs/container/deployment-examples/a/software"},{"id":"container/guides/guide1","path":"/docs/container/guides/guide1"},{"id":"container/index","path":"/docs/container/","sidebar":"docs"},{"id":"container/overview/architecture","path":"/docs/container/overview/architecture"},{"id":"container/overview/knowledge","path":"/docs/container/overview/knowledge"},{"id":"faq/index","path":"/docs/faq/","sidebar":"docs"},{"id":"getting-started/containerization","path":"/docs/getting-started/containerization"},{"id":"getting-started/overview","path":"/docs/getting-started/overview"},{"id":"getting-started/virtualization","path":"/docs/getting-started/virtualization"},{"id":"glossary","path":"/docs/glossary","sidebar":"docs"},{"id":"iaas/components/flavor-manager","path":"/docs/iaas/components/flavor-manager","sidebar":"docs"},{"id":"iaas/components/image-manager/index","path":"/docs/iaas/components/image-manager/","sidebar":"docs"},{"id":"iaas/components/image-manager/update","path":"/docs/iaas/components/image-manager/update","sidebar":"docs"},{"id":"iaas/components/index","path":"/docs/iaas/components/"},{"id":"iaas/components/openstack-health-monitor","path":"/docs/iaas/components/openstack-health-monitor"},{"id":"iaas/components/project-manager","path":"/docs/iaas/components/project-manager"},{"id":"iaas/components/resource-manager","path":"/docs/iaas/components/resource-manager"},{"id":"iaas/components/sandbox-manager","path":"/docs/iaas/components/sandbox-manager"},{"id":"iaas/components/simple-stress","path":"/docs/iaas/components/simple-stress"},{"id":"iaas/deployment-examples/artcodix/index","path":"/docs/iaas/deployment-examples/artcodix/","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/ceph","path":"/docs/iaas/guides/concept-guide/components/ceph","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/clusterapi","path":"/docs/iaas/guides/concept-guide/components/clusterapi","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/gardener","path":"/docs/iaas/guides/concept-guide/components/gardener","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/index","path":"/docs/iaas/guides/concept-guide/components/","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/ironic","path":"/docs/iaas/guides/concept-guide/components/ironic","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/k3s","path":"/docs/iaas/guides/concept-guide/components/k3s","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/keycloak","path":"/docs/iaas/guides/concept-guide/components/keycloak","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/netdata","path":"/docs/iaas/guides/concept-guide/components/netdata","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/openstack","path":"/docs/iaas/guides/concept-guide/components/openstack","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/prometheus","path":"/docs/iaas/guides/concept-guide/components/prometheus","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/sonic","path":"/docs/iaas/guides/concept-guide/components/sonic","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/teleport","path":"/docs/iaas/guides/concept-guide/components/teleport","sidebar":"docs"},{"id":"iaas/guides/concept-guide/design","path":"/docs/iaas/guides/concept-guide/design","sidebar":"docs"},{"id":"iaas/guides/concept-guide/hardware-bom","path":"/docs/iaas/guides/concept-guide/hardware-bom","sidebar":"docs"},{"id":"iaas/guides/concept-guide/index","path":"/docs/iaas/guides/concept-guide/","sidebar":"docs"},{"id":"iaas/guides/concept-guide/layers","path":"/docs/iaas/guides/concept-guide/layers","sidebar":"docs"},{"id":"iaas/guides/concept-guide/nodes","path":"/docs/iaas/guides/concept-guide/nodes","sidebar":"docs"},{"id":"iaas/guides/concept-guide/use-cases","path":"/docs/iaas/guides/concept-guide/use-cases","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/ceph","path":"/docs/iaas/guides/configuration-guide/ceph","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/certificates","path":"/docs/iaas/guides/configuration-guide/commons/certificates","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/index","path":"/docs/iaas/guides/configuration-guide/commons/","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/packages","path":"/docs/iaas/guides/configuration-guide/commons/packages","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/resolvconf","path":"/docs/iaas/guides/configuration-guide/commons/resolvconf","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/services","path":"/docs/iaas/guides/configuration-guide/commons/services","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/sshconfig","path":"/docs/iaas/guides/configuration-guide/commons/sshconfig","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/sysctl","path":"/docs/iaas/guides/configuration-guide/commons/sysctl","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/timezone","path":"/docs/iaas/guides/configuration-guide/commons/timezone","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/user","path":"/docs/iaas/guides/configuration-guide/commons/user","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/configuration-repository","path":"/docs/iaas/guides/configuration-guide/configuration-repository","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/index","path":"/docs/iaas/guides/configuration-guide/","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/inventory","path":"/docs/iaas/guides/configuration-guide/inventory","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/loadbalancer","path":"/docs/iaas/guides/configuration-guide/loadbalancer","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/manager","path":"/docs/iaas/guides/configuration-guide/manager","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/network","path":"/docs/iaas/guides/configuration-guide/network","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/aodh","path":"/docs/iaas/guides/configuration-guide/openstack/aodh","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/barbican","path":"/docs/iaas/guides/configuration-guide/openstack/barbican","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/ceilometer","path":"/docs/iaas/guides/configuration-guide/openstack/ceilometer","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/cinder","path":"/docs/iaas/guides/configuration-guide/openstack/cinder","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/designate","path":"/docs/iaas/guides/configuration-guide/openstack/designate","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/glance","path":"/docs/iaas/guides/configuration-guide/openstack/glance","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/heat","path":"/docs/iaas/guides/configuration-guide/openstack/heat","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/horizon","path":"/docs/iaas/guides/configuration-guide/openstack/horizon","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/index","path":"/docs/iaas/guides/configuration-guide/openstack/","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/ironic","path":"/docs/iaas/guides/configuration-guide/openstack/ironic","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/keystone","path":"/docs/iaas/guides/configuration-guide/openstack/keystone","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/magnum","path":"/docs/iaas/guides/configuration-guide/openstack/magnum","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/manila","path":"/docs/iaas/guides/configuration-guide/openstack/manila","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/neutron","path":"/docs/iaas/guides/configuration-guide/openstack/neutron","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/nova","path":"/docs/iaas/guides/configuration-guide/openstack/nova","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/octavia","path":"/docs/iaas/guides/configuration-guide/openstack/octavia","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/placement","path":"/docs/iaas/guides/configuration-guide/openstack/placement","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/skyline","path":"/docs/iaas/guides/configuration-guide/openstack/skyline","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/proxy","path":"/docs/iaas/guides/configuration-guide/proxy","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/rook","path":"/docs/iaas/guides/configuration-guide/rook","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/rookify","path":"/docs/iaas/guides/configuration-guide/rookify","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/services/chrony","path":"/docs/iaas/guides/configuration-guide/services/chrony","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/services/docker","path":"/docs/iaas/guides/configuration-guide/services/docker","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/services/index","path":"/docs/iaas/guides/configuration-guide/services/","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/services/tuned","path":"/docs/iaas/guides/configuration-guide/services/tuned","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/validations/index","path":"/docs/iaas/guides/configuration-guide/validations/","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/bootstrap","path":"/docs/iaas/guides/deploy-guide/bootstrap","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/examples/cloud-in-a-box","path":"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/examples/index","path":"/docs/iaas/guides/deploy-guide/examples/","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/examples/testbed","path":"/docs/iaas/guides/deploy-guide/examples/testbed","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/index","path":"/docs/iaas/guides/deploy-guide/","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/manager","path":"/docs/iaas/guides/deploy-guide/manager","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/provisioning","path":"/docs/iaas/guides/deploy-guide/provisioning","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/rookify","path":"/docs/iaas/guides/deploy-guide/rookify","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/seed","path":"/docs/iaas/guides/deploy-guide/seed","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/ceph","path":"/docs/iaas/guides/deploy-guide/services/ceph","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/index","path":"/docs/iaas/guides/deploy-guide/services/","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/infrastructure","path":"/docs/iaas/guides/deploy-guide/services/infrastructure","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/kubernetes","path":"/docs/iaas/guides/deploy-guide/services/kubernetes","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/logging-monitoring","path":"/docs/iaas/guides/deploy-guide/services/logging-monitoring","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/network","path":"/docs/iaas/guides/deploy-guide/services/network","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/openstack","path":"/docs/iaas/guides/deploy-guide/services/openstack","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/rook","path":"/docs/iaas/guides/deploy-guide/services/rook","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/rookify","path":"/docs/iaas/guides/deploy-guide/services/rookify","sidebar":"docs"},{"id":"iaas/guides/index","path":"/docs/iaas/guides/","sidebar":"docs"},{"id":"iaas/guides/operations-guide/ceph","path":"/docs/iaas/guides/operations-guide/ceph","sidebar":"docs"},{"id":"iaas/guides/operations-guide/index","path":"/docs/iaas/guides/operations-guide/","sidebar":"docs"},{"id":"iaas/guides/operations-guide/infrastructure","path":"/docs/iaas/guides/operations-guide/infrastructure","sidebar":"docs"},{"id":"iaas/guides/operations-guide/manager/apply","path":"/docs/iaas/guides/operations-guide/manager/apply","sidebar":"docs"},{"id":"iaas/guides/operations-guide/manager/console","path":"/docs/iaas/guides/operations-guide/manager/console","sidebar":"docs"},{"id":"iaas/guides/operations-guide/manager/get","path":"/docs/iaas/guides/operations-guide/manager/get","sidebar":"docs"},{"id":"iaas/guides/operations-guide/manager/index","path":"/docs/iaas/guides/operations-guide/manager/","sidebar":"docs"},{"id":"iaas/guides/operations-guide/manager/log","path":"/docs/iaas/guides/operations-guide/manager/log","sidebar":"docs"},{"id":"iaas/guides/operations-guide/manager/task","path":"/docs/iaas/guides/operations-guide/manager/task","sidebar":"docs"},{"id":"iaas/guides/operations-guide/network","path":"/docs/iaas/guides/operations-guide/network","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/cinder","path":"/docs/iaas/guides/operations-guide/openstack/cinder","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/index","path":"/docs/iaas/guides/operations-guide/openstack/","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/keystone","path":"/docs/iaas/guides/operations-guide/openstack/keystone","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/neutron","path":"/docs/iaas/guides/operations-guide/openstack/neutron","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/nova","path":"/docs/iaas/guides/operations-guide/openstack/nova","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/octavia","path":"/docs/iaas/guides/operations-guide/openstack/octavia","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/flavor-manager","path":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/image-manager/index","path":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/image-manager/update","path":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/index","path":"/docs/iaas/guides/operations-guide/openstack/tools/","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","path":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/project-manager","path":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/resource-manager","path":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/sandbox-manager","path":"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/simple-stress","path":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","sidebar":"docs"},{"id":"iaas/guides/operations-guide/rook","path":"/docs/iaas/guides/operations-guide/rook","sidebar":"docs"},{"id":"iaas/guides/operations-guide/rookify","path":"/docs/iaas/guides/operations-guide/rookify","sidebar":"docs"},{"id":"iaas/guides/other-guides/cloud-in-a-box/index","path":"/docs/iaas/guides/other-guides/cloud-in-a-box/","sidebar":"docs"},{"id":"iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","path":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","sidebar":"docs"},{"id":"iaas/guides/other-guides/contributor-guide","path":"/docs/iaas/guides/other-guides/contributor-guide","sidebar":"docs"},{"id":"iaas/guides/other-guides/developer-guide/index","path":"/docs/iaas/guides/other-guides/developer-guide/","sidebar":"docs"},{"id":"iaas/guides/other-guides/developer-guide/releases","path":"/docs/iaas/guides/other-guides/developer-guide/releases","sidebar":"docs"},{"id":"iaas/guides/other-guides/developer-guide/scripts","path":"/docs/iaas/guides/other-guides/developer-guide/scripts","sidebar":"docs"},{"id":"iaas/guides/other-guides/developer-guide/style-guide","path":"/docs/iaas/guides/other-guides/developer-guide/style-guide","sidebar":"docs"},{"id":"iaas/guides/other-guides/developer-guide/zuul","path":"/docs/iaas/guides/other-guides/developer-guide/zuul","sidebar":"docs"},{"id":"iaas/guides/other-guides/index","path":"/docs/iaas/guides/other-guides/","sidebar":"docs"},{"id":"iaas/guides/other-guides/testbed","path":"/docs/iaas/guides/other-guides/testbed","sidebar":"docs"},{"id":"iaas/guides/troubleshooting-guide/ceph","path":"/docs/iaas/guides/troubleshooting-guide/ceph","sidebar":"docs"},{"id":"iaas/guides/troubleshooting-guide/index","path":"/docs/iaas/guides/troubleshooting-guide/","sidebar":"docs"},{"id":"iaas/guides/troubleshooting-guide/manager","path":"/docs/iaas/guides/troubleshooting-guide/manager","sidebar":"docs"},{"id":"iaas/guides/troubleshooting-guide/openstack","path":"/docs/iaas/guides/troubleshooting-guide/openstack","sidebar":"docs"},{"id":"iaas/guides/troubleshooting-guide/rookify","path":"/docs/iaas/guides/troubleshooting-guide/rookify","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/ceph","path":"/docs/iaas/guides/upgrade-guide/ceph","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/docker","path":"/docs/iaas/guides/upgrade-guide/docker","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/index","path":"/docs/iaas/guides/upgrade-guide/","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/infrastructure","path":"/docs/iaas/guides/upgrade-guide/infrastructure","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/logging-monitoring","path":"/docs/iaas/guides/upgrade-guide/logging-monitoring","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/manager","path":"/docs/iaas/guides/upgrade-guide/manager","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/network","path":"/docs/iaas/guides/upgrade-guide/network","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/openstack","path":"/docs/iaas/guides/upgrade-guide/openstack","sidebar":"docs"},{"id":"iaas/guides/user-guide/index","path":"/docs/iaas/guides/user-guide/","sidebar":"docs"},{"id":"iaas/guides/user-guide/migration-vmware-esxi","path":"/docs/iaas/guides/user-guide/migration-vmware-esxi","sidebar":"docs"},{"id":"iaas/guides/user-guide/openstack/index","path":"/docs/iaas/guides/user-guide/openstack/","sidebar":"docs"},{"id":"iaas/guides/user-guide/openstack/install-instance-from-iso","path":"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso","sidebar":"docs"},{"id":"iaas/guides/user-guide/openstack/openstackclient","path":"/docs/iaas/guides/user-guide/openstack/openstackclient","sidebar":"docs"},{"id":"iaas/guides/user-guide/openstack/security-groups","path":"/docs/iaas/guides/user-guide/openstack/security-groups","sidebar":"docs"},{"id":"iaas/guides/user-guide/openstack/user-data-backups","path":"/docs/iaas/guides/user-guide/openstack/user-data-backups","sidebar":"docs"},{"id":"iaas/guides/user-guide/security-groups/security-groups","path":"/docs/iaas/guides/user-guide/security-groups/","sidebar":"docs"},{"id":"iaas/guides/user-guide/user-data-backups","path":"/docs/iaas/guides/user-guide/user-data-backups","sidebar":"docs"},{"id":"iaas/overview/architecture","path":"/docs/iaas/overview/architecture"},{"id":"iaas/overview/compute","path":"/docs/iaas/overview/compute"},{"id":"iaas/overview/knowledge","path":"/docs/iaas/overview/knowledge"},{"id":"iaas/overview/network","path":"/docs/iaas/overview/network"},{"id":"iaas/overview/storage","path":"/docs/iaas/overview/storage"},{"id":"iam/domain-manager-setup-and-usage","path":"/docs/iam/domain-manager-setup-and-usage","sidebar":"docs"},{"id":"iam/index","path":"/docs/iam/","sidebar":"docs"},{"id":"iam/intra-SCS-federation-setup-description-for-osism-doc-operations","path":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","sidebar":"docs"},{"id":"iam/SCS-example-setup-configuration-description","path":"/docs/iam/SCS-example-setup-configuration-description","sidebar":"docs"},{"id":"index","path":"/docs/","sidebar":"docs"},{"id":"operating-scs/audits/index","path":"/docs/operating-scs/audits/"},{"id":"operating-scs/components/automated-pentesting-iaas/overview","path":"/docs/operating-scs/components/automated-pentesting-iaas/overview","sidebar":"docs"},{"id":"operating-scs/components/automated-pentesting-iaas/quickstart","path":"/docs/operating-scs/components/automated-pentesting-iaas/quickstart","sidebar":"docs"},{"id":"operating-scs/components/automated-pentesting-iaas/reports","path":"/docs/operating-scs/components/automated-pentesting-iaas/reports","sidebar":"docs"},{"id":"operating-scs/components/automated-pentesting-iaas/tools","path":"/docs/operating-scs/components/automated-pentesting-iaas/tools","sidebar":"docs"},{"id":"operating-scs/components/automated-pentesting-kaas/overview","path":"/docs/operating-scs/components/automated-pentesting-kaas/overview","sidebar":"docs"},{"id":"operating-scs/components/automated-pentesting-kaas/quickstart","path":"/docs/operating-scs/components/automated-pentesting-kaas/quickstart","sidebar":"docs"},{"id":"operating-scs/components/automated-pentesting-kaas/tools","path":"/docs/operating-scs/components/automated-pentesting-kaas/tools","sidebar":"docs"},{"id":"operating-scs/components/central-api/overview","path":"/docs/operating-scs/components/central-api/overview","sidebar":"docs"},{"id":"operating-scs/components/central-api/poc-setup","path":"/docs/operating-scs/components/central-api/poc-setup","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/alertmanager","path":"/docs/operating-scs/components/monitoring/docs/alertmanager","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/iaas","path":"/docs/operating-scs/components/monitoring/docs/iaas","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/infrastructure_services","path":"/docs/operating-scs/components/monitoring/docs/infrastructure_services","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/k3s","path":"/docs/operating-scs/components/monitoring/docs/k3s","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/kaas","path":"/docs/operating-scs/components/monitoring/docs/kaas","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/oauth","path":"/docs/operating-scs/components/monitoring/docs/oauth","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/overview","path":"/docs/operating-scs/components/monitoring/docs/overview","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/quickstart","path":"/docs/operating-scs/components/monitoring/docs/quickstart","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/scs-deployment","path":"/docs/operating-scs/components/monitoring/docs/scs-deployment","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/status-page","path":"/docs/operating-scs/components/monitoring/docs/status-page"},{"id":"operating-scs/components/monitoring/docs/tracing","path":"/docs/operating-scs/components/monitoring/docs/tracing","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/tuning","path":"/docs/operating-scs/components/monitoring/docs/tuning","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/zuul","path":"/docs/operating-scs/components/monitoring/docs/zuul","sidebar":"docs"},{"id":"operating-scs/components/scs-health-monitor/overview","path":"/docs/operating-scs/components/scs-health-monitor/overview","sidebar":"docs"},{"id":"operating-scs/components/scs-health-monitor/SetupObservabilityStack","path":"/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack","sidebar":"docs"},{"id":"operating-scs/components/scs-health-monitor/Testflow","path":"/docs/operating-scs/components/scs-health-monitor/Testflow","sidebar":"docs"},{"id":"operating-scs/components/scs-health-monitor/Workflow","path":"/docs/operating-scs/components/scs-health-monitor/Workflow","sidebar":"docs"},{"id":"operating-scs/components/status-page-api/docs/configuration","path":"/docs/operating-scs/components/status-page-api/docs/configuration","sidebar":"docs"},{"id":"operating-scs/components/status-page-api/docs/contribute","path":"/docs/operating-scs/components/status-page-api/docs/contribute","sidebar":"docs"},{"id":"operating-scs/components/status-page-api/docs/example-requests","path":"/docs/operating-scs/components/status-page-api/docs/example-requests","sidebar":"docs"},{"id":"operating-scs/components/status-page-api/docs/overview","path":"/docs/operating-scs/components/status-page-api/docs/overview","sidebar":"docs"},{"id":"operating-scs/components/status-page-api/docs/quickstart","path":"/docs/operating-scs/components/status-page-api/docs/quickstart","sidebar":"docs"},{"id":"operating-scs/components/status-page-api/docs/requests","path":"/docs/operating-scs/components/status-page-api/docs/requests","sidebar":"docs"},{"id":"operating-scs/components/status-page-api/docs/requirements","path":"/docs/operating-scs/components/status-page-api/docs/requirements","sidebar":"docs"},{"id":"operating-scs/components/status-page-deployment/docs/admin-authentication","path":"/docs/operating-scs/components/status-page-deployment/docs/admin-authentication","sidebar":"docs"},{"id":"operating-scs/components/status-page-deployment/docs/configuration","path":"/docs/operating-scs/components/status-page-deployment/docs/configuration","sidebar":"docs"},{"id":"operating-scs/components/status-page-deployment/docs/contribute","path":"/docs/operating-scs/components/status-page-deployment/docs/contribute","sidebar":"docs"},{"id":"operating-scs/components/status-page-deployment/docs/faq","path":"/docs/operating-scs/components/status-page-deployment/docs/faq","sidebar":"docs"},{"id":"operating-scs/components/status-page-deployment/docs/k3s","path":"/docs/operating-scs/components/status-page-deployment/docs/k3s","sidebar":"docs"},{"id":"operating-scs/components/status-page-deployment/docs/kind","path":"/docs/operating-scs/components/status-page-deployment/docs/kind","sidebar":"docs"},{"id":"operating-scs/components/status-page-deployment/docs/monitoring","path":"/docs/operating-scs/components/status-page-deployment/docs/monitoring","sidebar":"docs"},{"id":"operating-scs/components/status-page-deployment/docs/overview","path":"/docs/operating-scs/components/status-page-deployment/docs/overview","sidebar":"docs"},{"id":"operating-scs/components/status-page-deployment/docs/quickstart","path":"/docs/operating-scs/components/status-page-deployment/docs/quickstart","sidebar":"docs"},{"id":"operating-scs/components/status-page-deployment/docs/requirements","path":"/docs/operating-scs/components/status-page-deployment/docs/requirements","sidebar":"docs"},{"id":"operating-scs/components/status-page-deployment/docs/scs-public","path":"/docs/operating-scs/components/status-page-deployment/docs/scs-public","sidebar":"docs"},{"id":"operating-scs/components/status-page-deployment/docs/usage","path":"/docs/operating-scs/components/status-page-deployment/docs/usage","sidebar":"docs"},{"id":"operating-scs/components/status-page-openapi/docs/component_overview","path":"/docs/operating-scs/components/status-page-openapi/docs/component_overview","sidebar":"docs"},{"id":"operating-scs/components/status-page-openapi/docs/components","path":"/docs/operating-scs/components/status-page-openapi/docs/components","sidebar":"docs"},{"id":"operating-scs/components/status-page-openapi/docs/levels_of_consensus","path":"/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus","sidebar":"docs"},{"id":"operating-scs/components/status-page-openapi/docs/overview","path":"/docs/operating-scs/components/status-page-openapi/docs/overview","sidebar":"docs"},{"id":"operating-scs/components/status-page-web/docs/configuration","path":"/docs/operating-scs/components/status-page-web/docs/configuration","sidebar":"docs"},{"id":"operating-scs/components/status-page-web/docs/contribute","path":"/docs/operating-scs/components/status-page-web/docs/contribute","sidebar":"docs"},{"id":"operating-scs/components/status-page-web/docs/overview","path":"/docs/operating-scs/components/status-page-web/docs/overview","sidebar":"docs"},{"id":"operating-scs/components/status-page-web/docs/quickstart","path":"/docs/operating-scs/components/status-page-web/docs/quickstart","sidebar":"docs"},{"id":"operating-scs/components/status-page-web/docs/requirements","path":"/docs/operating-scs/components/status-page-web/docs/requirements","sidebar":"docs"},{"id":"operating-scs/guides/openstack-health-monitor/Debian12-Install","path":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","sidebar":"docs"},{"id":"operating-scs/incident-management/index","path":"/docs/operating-scs/incident-management/"},{"id":"operating-scs/lifecycle-management/index","path":"/docs/operating-scs/lifecycle-management/"},{"id":"operating-scs/logging/index","path":"/docs/operating-scs/logging/"},{"id":"operating-scs/metering/meter_configuration","path":"/docs/operating-scs/metering/meter_configuration","sidebar":"docs"},{"id":"operating-scs/monitoring/index","path":"/docs/operating-scs/monitoring/"},{"id":"operating-scs/overview","path":"/docs/operating-scs/overview"},{"id":"releases/Release0","path":"/docs/releases/Release0","sidebar":"docs"},{"id":"releases/Release1","path":"/docs/releases/Release1","sidebar":"docs"},{"id":"releases/Release2","path":"/docs/releases/Release2","sidebar":"docs"},{"id":"releases/Release3","path":"/docs/releases/Release3","sidebar":"docs"},{"id":"releases/Release4","path":"/docs/releases/Release4","sidebar":"docs"},{"id":"releases/Release5","path":"/docs/releases/Release5","sidebar":"docs"},{"id":"releases/Release6","path":"/docs/releases/Release6","sidebar":"docs"},{"id":"releases/Release7","path":"/docs/releases/Release7","sidebar":"docs"},{"id":"releases/ReleaseX","path":"/docs/releases/ReleaseX"},{"id":"standards/index","path":"/docs/standards/"},{"id":"turnkey-solution/hardware-landscape","path":"/docs/turnkey-solution/hardware-landscape","sidebar":"docs"},{"id":"turnkey-solution/overview","path":"/docs/turnkey-solution/overview","sidebar":"docs"},{"id":"/category/iaas-layer","path":"/docs/category/iaas-layer","sidebar":"docs"},{"id":"/category/components","path":"/docs/category/components","sidebar":"docs"},{"id":"/category/deployment-examples","path":"/docs/category/deployment-examples","sidebar":"docs"},{"id":"/category/components-1","path":"/docs/category/components-1","sidebar":"docs"},{"id":"/category/cluster-stacks","path":"/docs/category/cluster-stacks","sidebar":"docs"},{"id":"/category/container-registry","path":"/docs/category/container-registry","sidebar":"docs"},{"id":"/category/operating-scs","path":"/docs/category/operating-scs","sidebar":"docs"},{"id":"/category/components-2","path":"/docs/category/components-2","sidebar":"docs"},{"id":"/category/status-page","path":"/docs/category/status-page","sidebar":"docs"},{"id":"/category/concepts","path":"/docs/category/concepts","sidebar":"docs"},{"id":"/category/api","path":"/docs/category/api","sidebar":"docs"},{"id":"/category/deployment","path":"/docs/category/deployment","sidebar":"docs"},{"id":"/category/configuration","path":"/docs/category/configuration","sidebar":"docs"},{"id":"/category/web","path":"/docs/category/web","sidebar":"docs"},{"id":"/category/monitoring","path":"/docs/category/monitoring","sidebar":"docs"},{"id":"/category/scs-health-monitor","path":"/docs/category/scs-health-monitor","sidebar":"docs"},{"id":"/category/central-api","path":"/docs/category/central-api","sidebar":"docs"},{"id":"/category/automated-pentesting","path":"/docs/category/automated-pentesting","sidebar":"docs"},{"id":"/category/pentesting-iaas","path":"/docs/category/pentesting-iaas","sidebar":"docs"},{"id":"/category/pentesting-kaas","path":"/docs/category/pentesting-kaas","sidebar":"docs"},{"id":"/category/guides-1","path":"/docs/category/guides-1","sidebar":"docs"},{"id":"/category/metering","path":"/docs/category/metering","sidebar":"docs"},{"id":"/category/guides-2","path":"/docs/category/guides-2","sidebar":"docs"},{"id":"/category/turnkey-solution","path":"/docs/category/turnkey-solution","sidebar":"docs"},{"id":"/category/releases","path":"/docs/category/releases","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/","label":"index"}}}}],"breadcrumbs":true},"community":{"path":"/community","versions":[{"name":"current","label":"Next","isLast":true,"path":"/community","mainDocId":"index","docs":[{"id":"central-services/plusserver-gx-scs","path":"/community/central-services/plusserver-gx-scs"},{"id":"cloud-resources/cloud-resources","path":"/community/cloud-resources/","sidebar":"community"},{"id":"cloud-resources/getting-started-openstack","path":"/community/cloud-resources/getting-started-openstack","sidebar":"community"},{"id":"cloud-resources/plusserver-gx-scs","path":"/community/cloud-resources/plusserver-gx-scs","sidebar":"community"},{"id":"cloud-resources/wavestack","path":"/community/cloud-resources/wavestack","sidebar":"community"},{"id":"collaboration/index","path":"/community/collaboration/","sidebar":"community"},{"id":"collaboration/sig-central-api","path":"/community/collaboration/sig-central-api","sidebar":"community"},{"id":"collaboration/sig-community","path":"/community/collaboration/sig-community","sidebar":"community"},{"id":"collaboration/sig-documentation","path":"/community/collaboration/sig-documentation","sidebar":"community"},{"id":"collaboration/sig-monitoring","path":"/community/collaboration/sig-monitoring","sidebar":"community"},{"id":"collaboration/sig-standardization","path":"/community/collaboration/sig-standardization","sidebar":"community"},{"id":"collaboration/team-container","path":"/community/collaboration/team-container","sidebar":"community"},{"id":"collaboration/team-iaas","path":"/community/collaboration/team-iaas","sidebar":"community"},{"id":"collaboration/team-iam","path":"/community/collaboration/team-iam","sidebar":"community"},{"id":"collaboration/team-ops","path":"/community/collaboration/team-ops","sidebar":"community"},{"id":"contribute/adding-docs-guide","path":"/community/contribute/adding-docs-guide","sidebar":"community"},{"id":"contribute/doc-files-structure-guide","path":"/community/contribute/doc-files-structure-guide","sidebar":"community"},{"id":"contribute/docs-workflow-explanation","path":"/community/contribute/docs-workflow-explanation","sidebar":"community"},{"id":"contribute/linting-guide","path":"/community/contribute/linting-guide","sidebar":"community"},{"id":"contribute/local-docusaurus-development-guide","path":"/community/contribute/local-docusaurus-development-guide","sidebar":"community"},{"id":"contribute/styleguide","path":"/community/contribute/styleguide","sidebar":"community"},{"id":"contribute/styleguides/ansible_styleguide","path":"/community/contribute/styleguides/ansible_styleguide"},{"id":"hackathons/checklist","path":"/community/hackathons/checklist"},{"id":"index","path":"/community/","sidebar":"community"},{"id":"license-considerations","path":"/community/license-considerations","sidebar":"community"},{"id":"mission-statement","path":"/community/mission-statement","sidebar":"community"},{"id":"tools/github/branchprotection","path":"/community/tools/github/branchprotection","sidebar":"community"},{"id":"tools/github/dco-and-licenses","path":"/community/tools/github/dco-and-licenses","sidebar":"community"},{"id":"tools/github/tips-and-tricks","path":"/community/tools/github/tips-and-tricks","sidebar":"community"},{"id":"tools/jitsi","path":"/community/tools/jitsi","sidebar":"community"},{"id":"tools/mailinglists","path":"/community/tools/mailinglists","sidebar":"community"},{"id":"tools/matrix","path":"/community/tools/matrix","sidebar":"community"},{"id":"tools/nextcloud","path":"/community/tools/nextcloud","sidebar":"community"},{"id":"tools/zuul","path":"/community/tools/zuul","sidebar":"community"},{"id":"/category/tools","path":"/community/category/tools","sidebar":"community"},{"id":"/category/contribute-to-docs","path":"/community/category/contribute-to-docs","sidebar":"community"}],"draftIds":[],"sidebars":{"community":{"link":{"path":"/community/","label":"index"}}}}],"breadcrumbs":true},"contributor-docs":{"path":"/contributor-docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/contributor-docs","mainDocId":"index","docs":[{"id":"development/index","path":"/contributor-docs/development/","sidebar":"devDocs"},{"id":"development/tests/rfc2119-keyword-test-guide","path":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","sidebar":"devDocs"},{"id":"development/tests/test-implementation-guide","path":"/contributor-docs/development/tests/test-implementation-guide","sidebar":"devDocs"},{"id":"index","path":"/contributor-docs/","sidebar":"devDocs"},{"id":"operations/iam/identity-federation-in-scs","path":"/contributor-docs/operations/iam/identity-federation-in-scs","sidebar":"devDocs"},{"id":"operations/iam/openstack-federation-via-oidc","path":"/contributor-docs/operations/iam/openstack-federation-via-oidc","sidebar":"devDocs"},{"id":"operations/operations/zuul-ci-cd-quickstart-user-guide","path":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","sidebar":"devDocs"}],"draftIds":[],"sidebars":{"devDocs":{"link":{"path":"/contributor-docs/development/","label":"Developer documentation"}}}}],"breadcrumbs":true},"user-docs":{"path":"/user-docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/user-docs","mainDocId":"index","docs":[{"id":"application-examples/opendesk-on-scs/configuration","path":"/user-docs/application-examples/opendesk-on-scs/configuration","sidebar":"userDocs"},{"id":"application-examples/opendesk-on-scs/contribute","path":"/user-docs/application-examples/opendesk-on-scs/contribute","sidebar":"userDocs"},{"id":"application-examples/opendesk-on-scs/getting_started","path":"/user-docs/application-examples/opendesk-on-scs/getting_started","sidebar":"userDocs"},{"id":"application-examples/opendesk-on-scs/overview","path":"/user-docs/application-examples/opendesk-on-scs/overview","sidebar":"userDocs"},{"id":"application-examples/opendesk-on-scs/quickstart","path":"/user-docs/application-examples/opendesk-on-scs/quickstart","sidebar":"userDocs"},{"id":"application-examples/opendesk-on-scs/requirements","path":"/user-docs/application-examples/opendesk-on-scs/requirements","sidebar":"userDocs"},{"id":"application-examples/opendesk-on-scs/user-import","path":"/user-docs/application-examples/opendesk-on-scs/user-import","sidebar":"userDocs"},{"id":"index","path":"/user-docs/","sidebar":"userDocs"},{"id":"/category/application-examples","path":"/user-docs/category/application-examples","sidebar":"userDocs"},{"id":"/category/opendesk-on-scs","path":"/user-docs/category/opendesk-on-scs","sidebar":"userDocs"}],"draftIds":[],"sidebars":{"userDocs":{"link":{"path":"/user-docs/","label":"index"}}}}],"breadcrumbs":true},"standards":{"path":"/standards","versions":[{"name":"current","label":"Next","isLast":true,"path":"/standards","mainDocId":"index","docs":[{"id":"certification/overview","path":"/standards/certification/overview","sidebar":"standards"},{"id":"certification/overview.template","path":"/standards/certification/overview.template"},{"id":"certification/pipeline","path":"/standards/certification/pipeline","sidebar":"standards"},{"id":"certification/scopes-versions","path":"/standards/certification/scopes-versions","sidebar":"standards"},{"id":"global/index","path":"/standards/global/","sidebar":"standards"},{"id":"global/scs-0001","path":"/standards/global/scs-0001","sidebar":"standards"},{"id":"global/scs-0002","path":"/standards/global/scs-0002","sidebar":"standards"},{"id":"global/scs-0003","path":"/standards/global/scs-0003","sidebar":"standards"},{"id":"global/scs-0004","path":"/standards/global/scs-0004","sidebar":"standards"},{"id":"global/scs-0005","path":"/standards/global/scs-0005","sidebar":"standards"},{"id":"iaas/index","path":"/standards/iaas/","sidebar":"standards"},{"id":"iaas/scs-0100","path":"/standards/iaas/scs-0100","sidebar":"standards"},{"id":"iaas/scs-0101","path":"/standards/iaas/scs-0101","sidebar":"standards"},{"id":"iaas/scs-0102","path":"/standards/iaas/scs-0102","sidebar":"standards"},{"id":"iaas/scs-0103","path":"/standards/iaas/scs-0103","sidebar":"standards"},{"id":"iaas/scs-0104","path":"/standards/iaas/scs-0104","sidebar":"standards"},{"id":"iaas/scs-0110","path":"/standards/iaas/scs-0110","sidebar":"standards"},{"id":"iaas/scs-0111","path":"/standards/iaas/scs-0111","sidebar":"standards"},{"id":"iaas/scs-0112","path":"/standards/iaas/scs-0112","sidebar":"standards"},{"id":"iaas/scs-0113","path":"/standards/iaas/scs-0113","sidebar":"standards"},{"id":"iaas/scs-0114","path":"/standards/iaas/scs-0114","sidebar":"standards"},{"id":"iaas/scs-0115","path":"/standards/iaas/scs-0115","sidebar":"standards"},{"id":"iaas/scs-0116","path":"/standards/iaas/scs-0116","sidebar":"standards"},{"id":"iaas/scs-0117","path":"/standards/iaas/scs-0117","sidebar":"standards"},{"id":"iaas/scs-0118","path":"/standards/iaas/scs-0118","sidebar":"standards"},{"id":"iaas/scs-0119","path":"/standards/iaas/scs-0119","sidebar":"standards"},{"id":"iaas/scs-0120","path":"/standards/iaas/scs-0120","sidebar":"standards"},{"id":"iaas/scs-0121","path":"/standards/iaas/scs-0121","sidebar":"standards"},{"id":"iaas/scs-0122","path":"/standards/iaas/scs-0122","sidebar":"standards"},{"id":"iaas/scs-0123","path":"/standards/iaas/scs-0123","sidebar":"standards"},{"id":"iaas/scs-0124","path":"/standards/iaas/scs-0124","sidebar":"standards"},{"id":"iaas/scs-0125","path":"/standards/iaas/scs-0125","sidebar":"standards"},{"id":"iam/index","path":"/standards/iam/","sidebar":"standards"},{"id":"iam/scs-0300","path":"/standards/iam/scs-0300","sidebar":"standards"},{"id":"iam/scs-0301","path":"/standards/iam/scs-0301","sidebar":"standards"},{"id":"iam/scs-0302","path":"/standards/iam/scs-0302","sidebar":"standards"},{"id":"index","path":"/standards/","sidebar":"standards"},{"id":"kaas/index","path":"/standards/kaas/","sidebar":"standards"},{"id":"kaas/scs-0200","path":"/standards/kaas/scs-0200","sidebar":"standards"},{"id":"kaas/scs-0210","path":"/standards/kaas/scs-0210","sidebar":"standards"},{"id":"kaas/scs-0211","path":"/standards/kaas/scs-0211","sidebar":"standards"},{"id":"kaas/scs-0212","path":"/standards/kaas/scs-0212","sidebar":"standards"},{"id":"kaas/scs-0213","path":"/standards/kaas/scs-0213","sidebar":"standards"},{"id":"kaas/scs-0214","path":"/standards/kaas/scs-0214","sidebar":"standards"},{"id":"kaas/scs-0215","path":"/standards/kaas/scs-0215","sidebar":"standards"},{"id":"kaas/scs-0216","path":"/standards/kaas/scs-0216","sidebar":"standards"},{"id":"kaas/scs-0217","path":"/standards/kaas/scs-0217","sidebar":"standards"},{"id":"kaas/scs-0218","path":"/standards/kaas/scs-0218","sidebar":"standards"},{"id":"kaas/scs-0219","path":"/standards/kaas/scs-0219","sidebar":"standards"},{"id":"ops/index","path":"/standards/ops/","sidebar":"standards"},{"id":"ops/scs-0400","path":"/standards/ops/scs-0400","sidebar":"standards"},{"id":"ops/scs-0401","path":"/standards/ops/scs-0401","sidebar":"standards"},{"id":"ops/scs-0402","path":"/standards/ops/scs-0402","sidebar":"standards"},{"id":"ops/scs-0403","path":"/standards/ops/scs-0403","sidebar":"standards"},{"id":"ops/scs-0410","path":"/standards/ops/scs-0410","sidebar":"standards"},{"id":"ops/scs-0411","path":"/standards/ops/scs-0411","sidebar":"standards"},{"id":"ops/scs-0412","path":"/standards/ops/scs-0412","sidebar":"standards"},{"id":"scs-0001-v1-sovereign-cloud-standards","path":"/standards/scs-0001-v1-sovereign-cloud-standards","sidebar":"standards"},{"id":"scs-0002-v1-standards-docs-org","path":"/standards/scs-0002-v1-standards-docs-org","sidebar":"standards"},{"id":"scs-0002-v2-standards-docs-org","path":"/standards/scs-0002-v2-standards-docs-org","sidebar":"standards"},{"id":"scs-0003-v1-sovereign-cloud-standards-yaml","path":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","sidebar":"standards"},{"id":"scs-0004-v1-achieving-certification","path":"/standards/scs-0004-v1-achieving-certification","sidebar":"standards"},{"id":"scs-0005-v1-project-governance","path":"/standards/scs-0005-v1-project-governance","sidebar":"standards"},{"id":"scs-0100-v1-flavor-naming","path":"/standards/scs-0100-v1-flavor-naming","sidebar":"standards"},{"id":"scs-0100-v2-flavor-naming","path":"/standards/scs-0100-v2-flavor-naming","sidebar":"standards"},{"id":"scs-0100-v3-flavor-naming","path":"/standards/scs-0100-v3-flavor-naming","sidebar":"standards"},{"id":"scs-0100-w1-flavor-naming-implementation-testing","path":"/standards/scs-0100-w1-flavor-naming-implementation-testing","sidebar":"standards"},{"id":"scs-0101-v1-entropy","path":"/standards/scs-0101-v1-entropy","sidebar":"standards"},{"id":"scs-0101-w1-entropy-implementation-testing","path":"/standards/scs-0101-w1-entropy-implementation-testing","sidebar":"standards"},{"id":"scs-0102-v1-image-metadata","path":"/standards/scs-0102-v1-image-metadata","sidebar":"standards"},{"id":"scs-0102-w1-image-metadata-implementation-testing","path":"/standards/scs-0102-w1-image-metadata-implementation-testing","sidebar":"standards"},{"id":"scs-0103-v1-standard-flavors","path":"/standards/scs-0103-v1-standard-flavors","sidebar":"standards"},{"id":"scs-0104-v1-standard-images","path":"/standards/scs-0104-v1-standard-images","sidebar":"standards"},{"id":"scs-0104-w1-standard-images-implementation","path":"/standards/scs-0104-w1-standard-images-implementation","sidebar":"standards"},{"id":"scs-0110-v1-ssd-flavors","path":"/standards/scs-0110-v1-ssd-flavors","sidebar":"standards"},{"id":"scs-0111-v1-volume-type-decisions","path":"/standards/scs-0111-v1-volume-type-decisions","sidebar":"standards"},{"id":"scs-0112-v1-sonic","path":"/standards/scs-0112-v1-sonic","sidebar":"standards"},{"id":"scs-0113-v1-security-groups-decision-record","path":"/standards/scs-0113-v1-security-groups-decision-record","sidebar":"standards"},{"id":"scs-0114-v1-volume-type-standard","path":"/standards/scs-0114-v1-volume-type-standard","sidebar":"standards"},{"id":"scs-0115-v1-default-rules-for-security-groups","path":"/standards/scs-0115-v1-default-rules-for-security-groups","sidebar":"standards"},{"id":"scs-0116-v1-key-manager-standard","path":"/standards/scs-0116-v1-key-manager-standard","sidebar":"standards"},{"id":"scs-0116-w1-key-manager-implementation-testing","path":"/standards/scs-0116-w1-key-manager-implementation-testing","sidebar":"standards"},{"id":"scs-0117-v1-volume-backup-service","path":"/standards/scs-0117-v1-volume-backup-service","sidebar":"standards"},{"id":"scs-0118-v1-taxonomy-of-failsafe-levels","path":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","sidebar":"standards"},{"id":"scs-0118-w1-example-impacts-of-failure-scenarios","path":"/standards/scs-0118-w1-example-impacts-of-failure-scenarios","sidebar":"standards"},{"id":"scs-0119-v1-rook-decision","path":"/standards/scs-0119-v1-rook-decision","sidebar":"standards"},{"id":"scs-0120-v1-capi-images","path":"/standards/scs-0120-v1-capi-images","sidebar":"standards"},{"id":"scs-0121-v1-Availability-Zones-Standard","path":"/standards/scs-0121-v1-Availability-Zones-Standard","sidebar":"standards"},{"id":"scs-0121-w1-Availability-Zones-Standard","path":"/standards/scs-0121-w1-Availability-Zones-Standard","sidebar":"standards"},{"id":"scs-0122-v1-node-to-node-encryption","path":"/standards/scs-0122-v1-node-to-node-encryption","sidebar":"standards"},{"id":"scs-0123-v1-mandatory-and-supported-IaaS-services","path":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","sidebar":"standards"},{"id":"scs-0124-v1-security-of-iaas-service-software","path":"/standards/scs-0124-v1-security-of-iaas-service-software","sidebar":"standards"},{"id":"scs-0124-w1-security-of-iaas-service-software","path":"/standards/scs-0124-w1-security-of-iaas-service-software","sidebar":"standards"},{"id":"scs-0125-v1-secure-connections","path":"/standards/scs-0125-v1-secure-connections","sidebar":"standards"},{"id":"scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","path":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","sidebar":"standards"},{"id":"scs-0210-v1-k8s-new-version-policy","path":"/standards/scs-0210-v1-k8s-new-version-policy","sidebar":"standards"},{"id":"scs-0210-v2-k8s-version-policy","path":"/standards/scs-0210-v2-k8s-version-policy","sidebar":"standards"},{"id":"scs-0210-w1-k8s-version-policy-implementation-testing","path":"/standards/scs-0210-w1-k8s-version-policy-implementation-testing","sidebar":"standards"},{"id":"scs-0211-v1-kaas-default-storage-class","path":"/standards/scs-0211-v1-kaas-default-storage-class","sidebar":"standards"},{"id":"scs-0211-v2-kaas-default-storage-class","path":"/standards/scs-0211-v2-kaas-default-storage-class","sidebar":"standards"},{"id":"scs-0211-w1-kaas-default-storage-class-implementation-testing","path":"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing","sidebar":"standards"},{"id":"scs-0212-v1-requirements-for-container-registries","path":"/standards/scs-0212-v1-requirements-for-container-registries","sidebar":"standards"},{"id":"scs-0213-v1-k8s-nodes-anti-affinity","path":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","sidebar":"standards"},{"id":"scs-0214-v1-k8s-node-distribution","path":"/standards/scs-0214-v1-k8s-node-distribution","sidebar":"standards"},{"id":"scs-0214-v2-k8s-node-distribution","path":"/standards/scs-0214-v2-k8s-node-distribution","sidebar":"standards"},{"id":"scs-0214-w1-k8s-node-distribution-implementation-testing","path":"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing","sidebar":"standards"},{"id":"scs-0215-v1-robustness-features","path":"/standards/scs-0215-v1-robustness-features","sidebar":"standards"},{"id":"scs-0216-v1-requirements-for-testing-cluster-stacks","path":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","sidebar":"standards"},{"id":"scs-0217-v1-cluster-hardening","path":"/standards/scs-0217-v1-cluster-hardening","sidebar":"standards"},{"id":"scs-0218-v1-container-registry-for-scs-standard-implementation","path":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","sidebar":"standards"},{"id":"scs-0219-v1-kaas-networking","path":"/standards/scs-0219-v1-kaas-networking","sidebar":"standards"},{"id":"scs-0219-w1-kaas-networking","path":"/standards/scs-0219-w1-kaas-networking","sidebar":"standards"},{"id":"scs-0300-v1-requirements-for-sso-identity-federation","path":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","sidebar":"standards"},{"id":"scs-0301-v1-naming-conventions","path":"/standards/scs-0301-v1-naming-conventions","sidebar":"standards"},{"id":"scs-0302-v1-domain-manager-role","path":"/standards/scs-0302-v1-domain-manager-role","sidebar":"standards"},{"id":"scs-0302-w1-domain-manager-implementation-notes","path":"/standards/scs-0302-w1-domain-manager-implementation-notes","sidebar":"standards"},{"id":"scs-0400-v1-status-page-create-decision","path":"/standards/scs-0400-v1-status-page-create-decision","sidebar":"standards"},{"id":"scs-0401-v1-status-page-reference-implementation-decision","path":"/standards/scs-0401-v1-status-page-reference-implementation-decision","sidebar":"standards"},{"id":"scs-0402-v1-status-page-openapi-spec-decision","path":"/standards/scs-0402-v1-status-page-openapi-spec-decision","sidebar":"standards"},{"id":"scs-0403-v1-csp-kaas-observability-stack","path":"/standards/scs-0403-v1-csp-kaas-observability-stack","sidebar":"standards"},{"id":"scs-0410-v1-gnocchi-as-metering-database","path":"/standards/scs-0410-v1-gnocchi-as-metering-database","sidebar":"standards"},{"id":"scs-0411-v1-publishing_method_for_metering_data","path":"/standards/scs-0411-v1-publishing_method_for_metering_data","sidebar":"standards"},{"id":"scs-0412-v1-metering-json","path":"/standards/scs-0412-v1-metering-json","sidebar":"standards"},{"id":"scs-compatible-iaas","path":"/standards/scs-compatible-iaas","sidebar":"standards"},{"id":"scs-compatible-kaas","path":"/standards/scs-compatible-kaas","sidebar":"standards"},{"id":"scs-XXXX-vN-decision-record-template","path":"/standards/scs-XXXX-vN-decision-record-template"},{"id":"scs-XXXX-vN-standard-template","path":"/standards/scs-XXXX-vN-standard-template"},{"id":"standards/overview","path":"/standards/standards/overview","sidebar":"standards"}],"draftIds":[],"sidebars":{"standards":{"link":{"path":"/standards/","label":"index"}}}}],"breadcrumbs":true}},"global-data-plugin":{"default":{"architecturalOverviewData":{"ops":[{"title":"Ops Layer","body":"Tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.","url":"/docs/category/operating-scs","buttonText":"Learn More","components":[{"title":"Status Page","url":"/docs/category/status-page","mandatory":"true","stable":"true"},{"title":"Monitoring","url":"/docs/category/monitoring","mandatory":"false","stable":"true"},{"title":"SCS Health Monitor","url":"/docs/operating-scs/components/scs-health-monitor/overview","mandatory":"true","stable":"true"},{"title":"Central API","url":"/docs/operating-scs/components/central-api/overview","mandatory":"true","stable":"true"},{"title":"Automated Pentesting IaaS","url":"/docs/operating-scs/components/automated-pentesting-iaas/overview","mandatory":"true","stable":"true"},{"title":"Automated Pentesting KaaS","url":"/docs/operating-scs/components/automated-pentesting-kaas/overview","mandatory":"true","stable":"true"}]}],"container":[{"title":"Container Layer","body":"SCS offers a robust solution for managing container workloads on a Kubernetes infrastructure.","url":"/docs/container","buttonText":"Learn More","components":[{"title":"KaaS V2: Cluster Stacks","url":"/docs/category/cluster-stacks","mandatory":"false","stable":"true"},{"title":"Container Registry","url":"/docs/category/container-registry","mandatory":"false","stable":"true"}]}],"iaas":[{"title":"IaaS Layer","body":"SCS offers OpenStack infrastructure solutions based on KVM virtualization to deploy VM workloads and enabling the container layer optionally.","url":"/docs/category/iaas-layer","buttonText":"Learn More","components":[{"title":"Image Manager","url":"/docs/iaas/components/image-manager","mandatory":"true","stable":"true"},{"title":"Flavor Manager","url":"/docs/iaas/components/flavor-manager","mandatory":"true","stable":"true"}]}],"iam":[{"title":"IAM Layer","body":"Working on Keycloak federated identity provider within our Team IAM.","url":"/docs/iam","buttonText":"Learn More","components":[{"title":"Keycloak","url":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","mandatory":"false","stable":"true"}]}]},"additionalResourcesData":[{"title":"Get in touch","body":"Come into our Matrix Chat in the SCS | Tech Room.","url":"https://matrix.to/#/#scs-tech:matrix.org","buttonText":"Join Now"},{"title":"Come to our Meet-Ups","body":"Our working groups and special interest groups meet weekly or biweekly. When? Find out within our public community calendar.","url":"/community/collaboration","buttonText":"Learn More"},{"title":"Standardization in progress","body":"Get to know our current Decision Records and Standards.","url":"/standards","buttonText":"Start Now"},{"title":"Deployment Examples","body":"Get to know different ways to deploy SCS with cloud resources or on bare metal.","url":"/docs/category/deployment-examples","buttonText":"Explore Cases"},{"title":"Application Examples","body":"Discover best practices to make the most of your cloud, from introductions to specific applications to advanced use cases.","url":"/user-docs/category/application-examples","buttonText":"Explore Cases"}],"featureContentData":[{"title":"Introduction to SCS","body":"Get to know SCS better and learn about the background.","url":"/docs","buttonText":"Get Started"},{"title":"Releases","body":"SCS is currently in Release 7. Check out the latest Release Notes.","url":"/docs/releases/Release7","buttonText":"Learn More"},{"title":"Frequently Asked Questions","body":"You are curious what SCS is all about, what it can do and what it can\'t?","url":"/docs/faq","buttonText":"Get Answers"},{"title":"Existing Public Clouds","body":"There are SCS compliant public clouds in production.","url":"/standards/certification/overview#compliant-cloud-environments","buttonText":"Test Them"}]}}}'),r=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var i=n(22654);const c=JSON.parse('{"docusaurusVersion":"3.6.3","siteVersion":"1.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.6.3"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.6.3"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.6.3"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.6.3"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.6.3"},"docusaurus-plugin-client-redirects":{"type":"package","name":"@docusaurus/plugin-client-redirects","version":"3.6.3"},"docusaurus-plugin-matomo-analytics":{"type":"project"},"global-data-plugin":{"type":"project"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"3.6.3"},"@easyops-cn/docusaurus-search-local":{"type":"package","name":"@easyops-cn/docusaurus-search-local","version":"0.45.0"}}}');var d=n(74848);const u={siteConfig:o.default,siteMetadata:c,globalData:a,i18n:r,codeTranslations:i},l=s.createContext(u);function p(e){let{children:t}=e;return(0,d.jsx)(l.Provider,{value:u,children:t})}},67489:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});var s=n(96540),o=n(38193),a=n(5260),r=n(70440),i=n(59504),c=n(53102),d=n(74848);function u(e){let{error:t,tryAgain:n}=e;return(0,d.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,d.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,d.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,d.jsx)(l,{error:t})]})}function l(e){let{error:t}=e;const n=(0,r.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,d.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function p(e){let{children:t}=e;return(0,d.jsx)(c.W,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:t})}function m(e){let{error:t,tryAgain:n}=e;return(0,d.jsx)(p,{children:(0,d.jsxs)(f,{fallback:()=>(0,d.jsx)(u,{error:t,tryAgain:n}),children:[(0,d.jsx)(a.A,{children:(0,d.jsx)("title",{children:"Page Error"})}),(0,d.jsx)(i.A,{children:(0,d.jsx)(u,{error:t,tryAgain:n})})]})})}const g=e=>(0,d.jsx)(m,{...e});class f extends s.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??g)(e)}return e??null}}},38193:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const s="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:s,canUseEventListeners:s&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:s&&"IntersectionObserver"in window,canUseViewport:s&&"screen"in window}},5260:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(96540);var s=n(80545),o=n(74848);function a(e){return(0,o.jsx)(s.mg,{...e})}},28774:(e,t,n)=>{"use strict";n.d(t,{A:()=>m});var s=n(96540),o=n(54625),a=n(70440),r=n(44586),i=n(16654),c=n(38193),d=n(63427),u=n(86025),l=n(74848);function p(e,t){let{isNavLink:n,to:p,href:m,activeClassName:g,isActive:f,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:v}=(0,r.A)(),{trailingSlash:k,baseUrl:x}=v,w=v.future.experimental_router,{withBaseUrl:_}=(0,u.hH)(),S=(0,d.A)(),E=(0,s.useRef)(null);(0,s.useImperativeHandle)(t,(()=>E.current));const C=p||m;const T=(0,i.A)(C),A=C?.replace("pathname://","");let j=void 0!==A?(P=A,b&&(e=>e.startsWith("/"))(P)?_(P):P):void 0;var P;"hash"===w&&j?.startsWith("./")&&(j=j?.slice(1)),j&&T&&(j=(0,a.Ks)(j,{trailingSlash:k,baseUrl:x}));const L=(0,s.useRef)(!1),R=n?o.k2:o.N_,N=c.A.canUseIntersectionObserver,O=(0,s.useRef)(),I=()=>{L.current||null==j||(window.docusaurus.preload(j),L.current=!0)};(0,s.useEffect)((()=>(!N&&T&&c.A.canUseDOM&&null!=j&&window.docusaurus.prefetch(j),()=>{N&&O.current&&O.current.disconnect()})),[O,j,N,T]);const D=j?.startsWith("#")??!1,F=!y.target||"_self"===y.target,M=!j||!T||!F||D&&"hash"!==w;h||!D&&M||S.collectLink(j),y.id&&S.collectAnchor(y.id);const z={};return M?(0,l.jsx)("a",{ref:E,href:j,...C&&!T&&{target:"_blank",rel:"noopener noreferrer"},...y,...z}):(0,l.jsx)(R,{...y,onMouseEnter:I,onTouchStart:I,innerRef:e=>{E.current=e,N&&e&&T&&(O.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(O.current.unobserve(e),O.current.disconnect(),null!=j&&window.docusaurus.prefetch(j))}))})),O.current.observe(e))},to:j,...n&&{isActive:f,activeClassName:g},...z})}const m=s.forwardRef(p)},21312:(e,t,n)=>{"use strict";n.d(t,{A:()=>d,T:()=>c});var s=n(96540),o=n(74848);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,s.isValidElement)(e)))?n.map(((e,t)=>(0,s.isValidElement)(e)?s.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var r=n(22654);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return r[t??n]??n??t}function c(e,t){let{message:n,id:s}=e;return a(i({message:n,id:s}),t)}function d(e){let{children:t,id:n,values:s}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const r=i({message:t,id:n});return(0,o.jsx)(o.Fragment,{children:a(r,s)})}},17065:(e,t,n)=>{"use strict";n.d(t,{W:()=>s});const s="default"},16654:(e,t,n)=>{"use strict";function s(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!s(e)}n.d(t,{A:()=>o,z:()=>s})},86025:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>i,hH:()=>r});var s=n(96540),o=n(44586),a=n(16654);function r(){const{siteConfig:e}=(0,o.A)(),{baseUrl:t,url:n}=e,r=e.future.experimental_router,i=(0,s.useCallback)(((e,s)=>function(e){let{siteUrl:t,baseUrl:n,url:s,options:{forcePrependBaseUrl:o=!1,absolute:r=!1}={},router:i}=e;if(!s||s.startsWith("#")||(0,a.z)(s))return s;if("hash"===i)return s.startsWith("/")?`.${s}`:`./${s}`;if(o)return n+s.replace(/^\//,"");if(s===n.replace(/\/$/,""))return n;const c=s.startsWith(n)?s:n+s.replace(/^\//,"");return r?t+c:c}({siteUrl:n,baseUrl:t,url:e,options:s,router:r})),[n,t,r]);return{withBaseUrl:i}}function i(e,t){void 0===t&&(t={});const{withBaseUrl:n}=r();return n(e,t)}},63427:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});var s=n(96540);n(74848);const o=s.createContext({collectAnchor:()=>{},collectLink:()=>{}}),a=()=>(0,s.useContext)(o);function r(){return a()}},44586:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var s=n(96540),o=n(26988);function a(){return(0,s.useContext)(o.o)}},92303:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var s=n(96540),o=n(6125);function a(){return(0,s.useContext)(o.o)}},205:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var s=n(96540);const o=n(38193).A.canUseDOM?s.useLayoutEffect:s.useEffect},36803:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var s=n(96540),o=n(53102);function a(){const e=s.useContext(o.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}},86921:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const s=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach((n=>{let[a,r]=n;const i=o?`${o}.${a}`:a;s(r)?e(r,i):t[i]=r}))}(e),t}},53102:(e,t,n)=>{"use strict";n.d(t,{W:()=>r,o:()=>a});var s=n(96540),o=n(74848);const a=s.createContext(null);function r(e){let{children:t,value:n}=e;const r=s.useContext(a),i=(0,s.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const s={...t.data,...n?.data};return{plugin:t.plugin,data:s}}({parent:r,value:n})),[r,n]);return(0,o.jsx)(a.Provider,{value:i,children:t})}},53886:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>h,XK:()=>v,g1:()=>y});var s=n(96540),o=n(44070),a=n(17065),r=n(6342),i=n(70679),c=n(89532),d=n(74848);const u=e=>`docs-preferred-version-${e}`,l={save:(e,t,n)=>{(0,i.Wf)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,i.Wf)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,i.Wf)(u(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const m=s.createContext(null);function g(){const e=(0,o.Gy)(),t=(0,r.p)().docs.versionPersistence,n=(0,s.useMemo)((()=>Object.keys(e)),[e]),[a,i]=(0,s.useState)((()=>p(n)));(0,s.useEffect)((()=>{i(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:s}=e;function o(e){const t=l.read(e,n);return s[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(l.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[a,(0,s.useMemo)((()=>({savePreferredVersion:function(e,n){l.save(e,t,n),i((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function f(e){let{children:t}=e;const n=g();return(0,d.jsx)(m.Provider,{value:n,children:t})}function h(e){let{children:t}=e;return(0,d.jsx)(f,{children:t})}function b(){const e=(0,s.useContext)(m);if(!e)throw new c.dV("DocsPreferredVersionContextProvider");return e}function y(e){void 0===e&&(e=a.W);const t=(0,o.ht)(e),[n,r]=b(),{preferredVersionName:i}=n[e];return{preferredVersion:t.versions.find((e=>e.name===i))??null,savePreferredVersionName:(0,s.useCallback)((t=>{r.savePreferredVersion(e,t)}),[r,e])}}function v(){const e=(0,o.Gy)(),[t]=b();function n(n){const s=e[n],{preferredVersionName:o}=t[n];return s.versions.find((e=>e.name===o))??null}const s=Object.keys(e);return Object.fromEntries(s.map((e=>[e,n(e)])))}},82565:(e,t,n)=>{"use strict";n.d(t,{k:()=>a,v:()=>r});var s=n(44070),o=n(53886);function a(e,t){return`docs-${e}-${t}`}function r(){const e=(0,s.Gy)(),t=(0,s.gk)(),n=(0,o.XK)();return[...Object.keys(e).map((function(s){const o=t?.activePlugin.pluginId===s?t.activeVersion:void 0,r=n[s],i=e[s].versions.find((e=>e.isLast));return a(s,(o??r??i).name)}))]}},60609:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,t:()=>d});var s=n(96540),o=n(89532),a=n(74848);const r=Symbol("EmptyContext"),i=s.createContext(r);function c(e){let{children:t,name:n,items:o}=e;const r=(0,s.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return(0,a.jsx)(i.Provider,{value:r,children:t})}function d(){const e=(0,s.useContext)(i);if(e===r)throw new o.dV("DocsSidebarProvider");return e}},26972:(e,t,n)=>{"use strict";n.d(t,{$S:()=>g,B5:()=>E,Nr:()=>m,OF:()=>x,QB:()=>S,Vd:()=>w,Y:()=>v,cC:()=>p,d1:()=>C,fW:()=>_,w8:()=>b});var s=n(96540),o=n(56347),a=n(22831),r=n(44070),i=n(99169),c=n(31682),d=n(53886),u=n(23025),l=n(60609);function p(e){const t=(0,u.r)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function m(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=m(t);if(e)return e}}(e):void 0:e.href}function g(){const{pathname:e}=(0,o.zy)(),t=(0,l.t)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=k({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const f=(e,t)=>void 0!==e&&(0,i.ys)(e,t),h=(e,t)=>e.some((e=>b(e,t)));function b(e,t){return"link"===e.type?f(e.href,t):"category"===e.type&&(f(e.href,t)||h(e.items,t))}function y(e,t){switch(e.type){case"category":return b(e,t)||e.items.some((e=>y(e,t)));case"link":return!e.unlisted||b(e,t);default:return!0}}function v(e,t){return(0,s.useMemo)((()=>e.filter((e=>y(e,t)))),[e,t])}function k(e){let{sidebarItems:t,pathname:n,onlyCategories:s=!1}=e;const o=[];return function e(t){for(const a of t)if("category"===a.type&&((0,i.ys)(a.href,n)||e(a.items))||"link"===a.type&&(0,i.ys)(a.href,n)){return s&&"category"!==a.type||o.unshift(a),!0}return!1}(t),o}function x(){const e=(0,l.t)(),{pathname:t}=(0,o.zy)(),n=(0,r.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?k({sidebarItems:e.items,pathname:t}):null}function w(e){const{activeVersion:t}=(0,r.zK)(e),{preferredVersion:n}=(0,d.g1)(e),o=(0,r.r7)(e);return(0,s.useMemo)((()=>(0,c.sb)([t,n,o].filter(Boolean))),[t,n,o])}function _(e,t){const n=w(t);return(0,s.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),s=t.find((t=>t[0]===e));if(!s)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return s[1]}),[e,n])}function S(e,t){const n=w(t);return(0,s.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),s=t.find((t=>t.id===e));if(!s){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,c.sb)(t.map((e=>e.id))).join("\n- ")}`)}return s}),[e,n])}function E(e){let{route:t}=e;const n=(0,o.zy)(),s=(0,u.r)(),r=t.routes,i=r.find((e=>(0,o.B6)(n.pathname,e)));if(!i)return null;const c=i.sidebar,d=c?s.docsSidebars[c]:void 0;return{docElement:(0,a.v)(r),sidebarName:c,sidebarItems:d}}function C(e){return e.filter((e=>!("category"===e.type||"link"===e.type)||!!m(e)))}},23025:(e,t,n)=>{"use strict";n.d(t,{n:()=>i,r:()=>c});var s=n(96540),o=n(89532),a=n(74848);const r=s.createContext(null);function i(e){let{children:t,version:n}=e;return(0,a.jsx)(r.Provider,{value:n,children:t})}function c(){const e=(0,s.useContext)(r);if(null===e)throw new o.dV("DocsVersionProvider");return e}},44070:(e,t,n)=>{"use strict";n.d(t,{d1:()=>u.d1,zK:()=>k,vT:()=>h,gk:()=>b,Gy:()=>g,$S:()=>u.$S,HW:()=>x,vF:()=>p.v,ht:()=>f,g1:()=>l.g1,r7:()=>v,jh:()=>y});var s=n(56347),o=n(44586),a=n(17065);function r(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const i=e=>e.versions.find((e=>e.isLast));function c(e,t){return[...e.versions].sort(((e,t)=>e.path===t.path?0:e.path.includes(t.path)?-1:t.path.includes(e.path)?1:0)).find((e=>!!(0,s.B6)(t,{path:e.path,exact:!1,strict:!1})))}function d(e,t){const n=c(e,t),o=n?.docs.find((e=>!!(0,s.B6)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((s=>{s.id===t&&(n[e.name]=s)}))})),n}(o.id):{}}}var u=n(26972),l=n(53886),p=n(82565);const m={},g=()=>r("docusaurus-plugin-content-docs")??m,f=e=>{try{return function(e,t,n){void 0===t&&(t=a.W),void 0===n&&(n={});const s=r(e),o=s?.[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function h(e){void 0===e&&(e={});const t=g(),{pathname:n}=(0,s.zy)();return function(e,t,n){void 0===n&&(n={});const o=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,s.B6)(t,{path:n.path,exact:!1,strict:!1})})),a=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!a&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return a}(t,n,e)}function b(e){void 0===e&&(e={});const t=h(e),{pathname:n}=(0,s.zy)();if(!t)return;return{activePlugin:t,activeVersion:c(t.pluginData,n)}}function y(e){return f(e).versions}function v(e){const t=f(e);return i(t)}function k(e){const t=f(e),{pathname:n}=(0,s.zy)();return d(t,n)}function x(e){const t=f(e),{pathname:n}=(0,s.zy)();return function(e,t){const n=i(e);return{latestDocSuggestion:d(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},76294:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var s=n(5947),o=n.n(s);o().configure({showSpinner:!1});const a={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},26134:(e,t,n)=>{"use strict";var s=n(78181),o=n(4784);!function(e){const{themeConfig:{prism:t}}=o.default,{additionalLanguages:s}=t,a=globalThis.Prism;globalThis.Prism=e,s.forEach((e=>{"php"===e&&n(19700),n(75430)(`./prism-${e}`)})),delete globalThis.Prism,void 0!==a&&(globalThis.Prism=e)}(s.My)},51107:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(96540);var s=n(18215),o=n(21312),a=n(6342),r=n(28774),i=n(63427);const c={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var d=n(74848);function u(e){let{as:t,id:n,...u}=e;const l=(0,i.A)(),{navbar:{hideOnScroll:p}}=(0,a.p)();if("h1"===t||!n)return(0,d.jsx)(t,{...u,id:void 0});l.collectAnchor(n);const m=(0,o.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return(0,d.jsxs)(t,{...u,className:(0,s.A)("anchor",p?c.anchorWithHideOnScrollNavbar:c.anchorWithStickyNavbar,u.className),id:n,children:[u.children,(0,d.jsx)(r.A,{className:"hash-link",to:`#${n}`,"aria-label":m,title:m,children:"\u200b"})]})}},43186:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(96540);const s={iconExternalLink:"iconExternalLink_nPIU"};var o=n(74848);function a(e){let{width:t=13.5,height:n=13.5}=e;return(0,o.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:s.iconExternalLink,children:(0,o.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},59504:(e,t,n)=>{"use strict";n.d(t,{A:()=>Rt});var s=n(96540),o=n(18215),a=n(67489),r=n(61213),i=n(56347),c=n(21312),d=n(75062),u=n(74848);const l="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function m(){const e=(0,s.useRef)(null),{action:t}=(0,i.W6)(),n=(0,s.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(l);t&&p(t)}),[]);return(0,d.$)((n=>{let{location:s}=n;e.current&&!s.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const g=(0,c.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function f(e){const t=e.children??g,{containerRef:n,onClick:s}=m();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":g,children:(0,u.jsx)("a",{...e,href:`#${l}`,onClick:s,children:t})})}var h=n(17559),b=n(14090);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(f,{className:y.skipToContent})}var k=n(6342),x=n(65041);function w(e){let{width:t=21,height:n=21,color:s="currentColor",strokeWidth:o=1.2,className:a,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...r,children:(0,u.jsx)("g",{stroke:s,strokeWidth:o,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const _={closeButton:"closeButton_CVFx"};function S(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,c.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.A)("clean-btn close",_.closeButton,e.className),children:(0,u.jsx)(w,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,k.p)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,o.A)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function A(){const{announcementBar:e}=(0,k.p)(),{isActive:t,close:n}=(0,x.M)();if(!t)return null;const{backgroundColor:s,textColor:o,isCloseable:a}=e;return(0,u.jsxs)("div",{className:T.announcementBar,style:{backgroundColor:s,color:o},role:"banner",children:[a&&(0,u.jsx)("div",{className:T.announcementBarPlaceholder}),(0,u.jsx)(C,{className:T.announcementBarContent}),a&&(0,u.jsx)(S,{onClick:n,className:T.announcementBarClose})]})}var j=n(22069),P=n(23104);var L=n(89532),R=n(75600);const N=s.createContext(null);function O(e){let{children:t}=e;const n=function(){const e=(0,j.M)(),t=(0,R.YL)(),[n,o]=(0,s.useState)(!1),a=null!==t.component,r=(0,L.ZC)(a);return(0,s.useEffect)((()=>{a&&!r&&o(!0)}),[a,r]),(0,s.useEffect)((()=>{a?e.shown||o(!0):o(!1)}),[e.shown,a]),(0,s.useMemo)((()=>[n,o]),[n])}();return(0,u.jsx)(N.Provider,{value:n,children:t})}function I(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function D(){const e=(0,s.useContext)(N);if(!e)throw new L.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,s.useCallback)((()=>n(!1)),[n]),a=(0,R.YL)();return(0,s.useMemo)((()=>({shown:t,hide:o,content:I(a)})),[o,a,t])}function F(e){let{header:t,primaryMenu:n,secondaryMenu:s}=e;const{shown:a}=D();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,o.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":a}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:s})]})]})}var M=n(95293),z=n(92303);function B(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function q(e){let{className:t,buttonClassName:n,value:s,onChange:a}=e;const r=(0,z.A)(),i=(0,c.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===s?(0,c.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,o.A)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,o.A)("clean-btn",U.toggleButton,!r&&U.toggleButtonDisabled,n),type:"button",onClick:()=>a("dark"===s?"light":"dark"),disabled:!r,title:i,"aria-label":i,"aria-live":"polite","aria-pressed":"dark"===s?"true":"false",children:[(0,u.jsx)(B,{className:(0,o.A)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)($,{className:(0,o.A)(U.toggleIcon,U.darkToggleIcon)})]})})}const Q=s.memo(q),V={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function H(e){let{className:t}=e;const n=(0,k.p)().navbar.style,s=(0,k.p)().colorMode.disableSwitch,{colorMode:o,setColorMode:a}=(0,M.G)();return s?null:(0,u.jsx)(Q,{className:t,buttonClassName:"dark"===n?V.darkNavbarColorModeToggle:void 0,value:o,onChange:a})}var W=n(23465);function G(){return(0,u.jsx)(W.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function X(){const e=(0,j.M)();return(0,u.jsx)("button",{type:"button","aria-label":(0,c.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(w,{color:"var(--ifm-color-emphasis-600)"})})}function K(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(G,{}),(0,u.jsx)(H,{className:"margin-right--md"}),(0,u.jsx)(X,{})]})}var Z=n(28774),Y=n(86025),J=n(16654);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(43186);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:s,href:o,label:a,html:r,isDropdownLink:i,prependBaseUrlToHref:c,...d}=e;const l=(0,Y.Ay)(s),p=(0,Y.Ay)(t),m=(0,Y.Ay)(o,{forcePrependBaseUrl:!0}),g=a&&o&&!(0,J.A)(o),f=r?{dangerouslySetInnerHTML:{__html:r}}:{children:(0,u.jsxs)(u.Fragment,{children:[a,g&&(0,u.jsx)(te.A,{...i&&{width:12,height:12}})]})};return o?(0,u.jsx)(Z.A,{href:c?m:o,...d,...f}):(0,u.jsx)(Z.A,{to:l,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(p)},...d,...f})}function se(e){let{className:t,isDropdownItem:n=!1,...s}=e;const a=(0,u.jsx)(ne,{className:(0,o.A)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...s});return n?(0,u.jsx)("li",{children:a}):a}function oe(e){let{className:t,isDropdownItem:n,...s}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,o.A)("menu__link",t),...s})})}function ae(e){let{mobile:t=!1,position:n,...s}=e;const o=t?oe:se;return(0,u.jsx)(o,{...s,activeClassName:s.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var re=n(41422),ie=n(99169),ce=n(44586);const de={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ue(e,t){return e.some((e=>function(e,t){return!!(0,ie.ys)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function le(e){let{items:t,position:n,className:a,onClick:r,...i}=e;const c=(0,s.useRef)(null),[d,l]=(0,s.useState)(!1);return(0,s.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&l(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),(0,u.jsxs)("div",{ref:c,className:(0,o.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":d}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":d,role:"button",href:i.to?void 0:"#",className:(0,o.A)("navbar__link",a),...i,onClick:i.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),l(!d))},children:i.children??i.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,s.createElement)(Ge,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function pe(e){let{items:t,className:n,position:a,onClick:r,...c}=e;const d=function(){const{siteConfig:{baseUrl:e}}=(0,ce.A)(),{pathname:t}=(0,i.zy)();return t.replace(e,"/")}(),l=ue(t,d),{collapsed:p,toggleCollapsed:m,setCollapsed:g}=(0,re.u)({initialState:()=>!l});return(0,s.useEffect)((()=>{l&&g(!l)}),[d,l,g]),(0,u.jsxs)("li",{className:(0,o.A)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,u.jsx)(ne,{role:"button",className:(0,o.A)(de.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...c,onClick:e=>{e.preventDefault(),m()},children:c.children??c.label}),(0,u.jsx)(re.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,s.createElement)(Ge,{mobile:!0,isDropdownItem:!0,onClick:r,activeClassName:"menu__link--active",...e,key:t})))})]})}function me(e){let{mobile:t=!1,...n}=e;const s=t?pe:le;return(0,u.jsx)(s,{...n})}var ge=n(32131);function fe(e){let{width:t=20,height:n=20,...s}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...s,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const he="iconLanguage_nlXk";var be=n(11088),ye=n(20053);var ve=n(44070),ke=n(5891),xe=n(32384),we=n(69913),_e=n(4471),Se=n(27674),Ee=n(86841),Ce=n(43810);const Te='<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17 6v12c0 .52-.2 1-1 1H4c-.7 0-1-.33-1-1V2c0-.55.42-1 1-1h8l5 5zM14 8h-3.13c-.51 0-.87-.34-.87-.87V4" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linejoin="round"></path></svg>',Ae='<svg width="20" height="20" viewBox="0 0 20 20"><path d="M13 13h4-4V8H7v5h6v4-4H7V8H3h4V3v5h6V3v5h4-4v5zm-6 0v4-4H3h4z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg>',je='<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17 5H3h14zm0 5H3h14zm0 5H3h14z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linejoin="round"></path></svg>',Pe='<svg width="20" height="20" viewBox="0 0 20 20"><g stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><path d="M18 3v4c0 2-2 4-4 4H2"></path><path d="M8 17l-6-6 6-6"></path></g></svg>',Le='<svg width="40" height="40" viewBox="0 0 20 20" fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M15.5 4.8c2 3 1.7 7-1 9.7h0l4.3 4.3-4.3-4.3a7.8 7.8 0 01-9.8 1m-2.2-2.2A7.8 7.8 0 0113.2 2.4M2 18L18 2"></path></svg>',Re='<svg viewBox="0 0 24 54"><g stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6v42M20 27H8.3"></path></g></svg>',Ne='<svg viewBox="0 0 24 54"><g stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6v21M20 27H8.3"></path></g></svg>',Oe={searchBar:"searchBar_RVTs",dropdownMenu:"dropdownMenu_qbY6",searchBarLeft:"searchBarLeft_MXDe",suggestion:"suggestion_fB_2",cursor:"cursor_eG29",hitTree:"hitTree_kk6K",hitIcon:"hitIcon_a7Zy",hitPath:"hitPath_ieM4",noResultsIcon:"noResultsIcon_EBY5",hitFooter:"hitFooter_E9YW",hitWrapper:"hitWrapper_sAK8",hitTitle:"hitTitle_vyVt",hitAction:"hitAction_NqkB",hideAction:"hideAction_vcyE",noResults:"noResults_l6Q3",searchBarContainer:"searchBarContainer_NW3z",searchBarLoadingRing:"searchBarLoadingRing_YnHq",searchClearButton:"searchClearButton_qk4g",searchIndexLoading:"searchIndexLoading_EJ1f",searchHintContainer:"searchHintContainer_Pkmr",searchHint:"searchHint_iIMx",focused:"focused_OWtg",input:"input_FOTf",hint:"hint_URu1",suggestions:"suggestions_X8XU",dataset:"dataset_QiCy",empty:"empty_eITn"};function Ie(e){let{document:t,type:n,page:s,metadata:o,tokens:a,isInterOfTree:r,isLastOfTree:i}=e;const c=n===we.i.Title,d=n===we.i.Keywords,u=c||d,l=n===we.i.Heading,p=[];r?p.push(Re):i&&p.push(Ne);const m=p.map((e=>`<span class="${Oe.hitTree}">${e}</span>`)),g=`<span class="${Oe.hitIcon}">${u?Te:l?Ae:je}</span>`,f=[`<span class="${Oe.hitTitle}">${d?(0,Ee.Z)(t.s,a):(0,Ce.C)(t.t,(0,Se.g)(o,"t"),a)}</span>`];if(!r&&!i&&be.tb){const e=s?s.b?.concat(s.t).concat(t.s&&t.s!==s.t?t.s:[]):t.b;f.push(`<span class="${Oe.hitPath}">${(0,_e.$)(e??[])}</span>`)}else u||f.push(`<span class="${Oe.hitPath}">${(0,Ee.Z)(s.t||(t.u.startsWith("/docs/api-reference/")?"API Reference":""),a)}</span>`);const h=`<span class="${Oe.hitAction}">${Pe}</span>`;return[...m,g,`<span class="${Oe.hitWrapper}">`,...f,"</span>",h].join("")}function De(){return`<span class="${Oe.noResults}"><span class="${Oe.noResultsIcon}">${Le}</span><span>${(0,c.T)({id:"theme.SearchBar.noResultsText",message:"No results"})}</span></span>`}var Fe=n(2849),Me=n(43385);async function ze(){const e=await Promise.all([n.e(90489),n.e(45741)]).then(n.t.bind(n,90489,23)),t=e.default;return t.noConflict?t.noConflict():e.noConflict&&e.noConflict(),t}const Be="_highlight";const $e=function(e){let{handleSearchBarToggle:t}=e;const o=(0,z.A)(),{siteConfig:{baseUrl:a},i18n:{currentLocale:r}}=(0,ce.A)(),d=(0,ve.vT)();let l=a;try{const{preferredVersion:e}=function(){return n(44070).g1(...arguments)}(d?.pluginId??be.UB);e&&!e.isLast&&(l=e.path+"/")}catch(M){if(be.I$&&!(M instanceof L.dV))throw M}const p=(0,i.W6)(),m=(0,i.zy)(),g=(0,s.useRef)(null),f=(0,s.useRef)(new Map),h=(0,s.useRef)(!1),[b,y]=(0,s.useState)(!1),[v,k]=(0,s.useState)(!1),[x,w]=(0,s.useState)(""),_=(0,s.useRef)(null),S=(0,s.useRef)(""),[E,C]=(0,s.useState)("");(0,s.useEffect)((()=>{if(!Array.isArray(be.Hg))return;let e="";if(m.pathname.startsWith(l)){const t=m.pathname.substring(l.length);let n;for(const e of be.Hg){const s="string"==typeof e?e:e.path;if(t===s||t.startsWith(`${s}/`)){n=s;break}}n&&(e=n)}S.current!==e&&(f.current.delete(e),S.current=e),C(e)}),[m.pathname,l]);const T=!!be.O6&&Array.isArray(be.Hg)&&""===E,A=(0,s.useCallback)((async()=>{if(T||f.current.get(E))return;f.current.set(E,"loading"),_.current?.autocomplete.destroy(),y(!0);const[{wrappedIndexes:e,zhDictionary:t},n]=await Promise.all([(0,ke.Z)(l,E),ze()]);if(_.current=n(g.current,{hint:!1,autoselect:!0,openOnFocus:!0,cssClasses:{root:(0,ye.A)(Oe.searchBar,{[Oe.searchBarLeft]:"left"===be.ZG}),noPrefix:!0,dropdownMenu:Oe.dropdownMenu,input:Oe.input,hint:Oe.hint,suggestions:Oe.suggestions,suggestion:Oe.suggestion,cursor:Oe.cursor,dataset:Oe.dataset,empty:Oe.empty}},[{source:(0,xe.m)(e,t,be.AT),templates:{suggestion:Ie,empty:De,footer:e=>{let{query:t,isEmpty:n}=e;if(n&&(!E||!be.dz))return;const s=(e=>{let{query:t,isEmpty:n}=e;const s=document.createElement("a"),o=new URLSearchParams;let i;if(o.set("q",t),E){const e=E&&Array.isArray(be.Hg)?be.Hg.find((e=>"string"==typeof e?e===E:e.path===E)):E,t=e?(0,Me.p)(e,r).label:E;i=be.dz&&n?(0,c.T)({id:"theme.SearchBar.seeAllOutsideContext",message:'See all results outside "{context}"'},{context:t}):(0,c.T)({id:"theme.SearchBar.searchInContext",message:'See all results within "{context}"'},{context:t})}else i=(0,c.T)({id:"theme.SearchBar.seeAll",message:"See all results"});if(!E||!Array.isArray(be.Hg)||be.dz&&n||o.set("ctx",E),l!==a){if(!l.startsWith(a))throw new Error(`Version url '${l}' does not start with base url '${a}', this is a bug of \`@easyops-cn/docusaurus-search-local\`, please report it.`);o.set("version",l.substring(a.length))}const d=`${a}search/?${o.toString()}`;return s.href=d,s.textContent=i,s.addEventListener("click",(e=>{e.ctrlKey||e.metaKey||(e.preventDefault(),_.current?.autocomplete.close(),p.push(d))})),s})({query:t,isEmpty:n}),o=document.createElement("div");return o.className=Oe.hitFooter,o.appendChild(s),o}}}]).on("autocomplete:selected",(function(e,t){let{document:{u:n,h:s},tokens:o}=t;g.current?.blur();let a=n;if(be.CU&&o.length>0){const e=new URLSearchParams;for(const t of o)e.append(Be,t);a+=`?${e.toString()}`}s&&(a+=s),p.push(a)})).on("autocomplete:closed",(()=>{g.current?.blur()})),f.current.set(E,"done"),y(!1),h.current){const e=g.current;e.value&&_.current?.autocomplete.open(),e.focus()}}),[T,E,l,a,p]);(0,s.useEffect)((()=>{if(!be.CU)return;const e=o?new URLSearchParams(m.search).getAll(Be):[];setTimeout((()=>{const t=document.querySelector("article");if(!t)return;const n=new be.CU(t);n.unmark(),0!==e.length&&n.mark(e),w(e.join(" ")),_.current?.autocomplete.setVal(e.join(" "))}))}),[o,m.search,m.pathname]);const[j,P]=(0,s.useState)(!1),R=(0,s.useCallback)((()=>{h.current=!0,A(),P(!0),t?.(!0)}),[t,A]),N=(0,s.useCallback)((()=>{P(!1),t?.(!1)}),[t]),O=(0,s.useCallback)((()=>{A()}),[A]),I=(0,s.useCallback)((e=>{w(e.target.value),e.target.value&&k(!0)}),[]),D=!!o&&/mac/i.test(navigator.userAgentData?.platform??navigator.platform);(0,s.useEffect)((()=>{if(!be.WW)return;const e=e=>{!(D?e.metaKey:e.ctrlKey)||"k"!==e.key&&"K"!==e.key||(e.preventDefault(),g.current?.focus(),R())};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}}),[D,R]);const F=(0,s.useCallback)((()=>{const e=new URLSearchParams(m.search);e.delete(Be);const t=e.toString(),n=m.pathname+(""!=t?`?${t}`:"")+m.hash;n!=m.pathname+m.search+m.hash&&p.push(n),w(""),_.current?.autocomplete.setVal("")}),[m.pathname,m.search,m.hash,p]);return(0,u.jsxs)("div",{className:(0,ye.A)("navbar__search",Oe.searchBarContainer,{[Oe.searchIndexLoading]:b&&v,[Oe.focused]:j}),hidden:T,dir:"ltr",children:[(0,u.jsx)("input",{placeholder:(0,c.T)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),"aria-label":"Search",className:"navbar__search-input",onMouseEnter:O,onFocus:R,onBlur:N,onChange:I,ref:g,value:x}),(0,u.jsx)(Fe.A,{className:Oe.searchBarLoadingRing}),be.WW&&be.pk&&(""!==x?(0,u.jsx)("button",{className:Oe.searchClearButton,onClick:F,children:"\u2715"}):o&&(0,u.jsxs)("div",{className:Oe.searchHintContainer,children:[(0,u.jsx)("kbd",{className:Oe.searchHint,children:D?"\u2318":"ctrl"}),(0,u.jsx)("kbd",{className:Oe.searchHint,children:"K"})]}))]})},Ue={navbarSearchContainer:"navbarSearchContainer_Bca1"};function qe(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,o.A)(n,Ue.navbarSearchContainer),children:t})}var Qe=n(26972);var Ve=n(53886);function He(e,t){return t.alternateDocVersions[e.name]??function(e){return e.docs.find((t=>t.id===e.mainDocId))}(e)}const We={default:ae,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:s,queryString:o="",...a}=e;const{i18n:{currentLocale:r,locales:d,localeConfigs:l}}=(0,ce.A)(),p=(0,ge.o)(),{search:m,hash:g}=(0,i.zy)(),f=[...n,...d.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${m}${g}${o}`;return{label:l[e].label,lang:l[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===r?t?"menu__link--active":"dropdown__link--active":""}})),...s],h=t?(0,c.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):l[r].label;return(0,u.jsx)(me,{...a,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(fe,{className:he}),h]}),items:f})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(qe,{className:n,children:(0,u.jsx)($e,{})})},dropdown:me,html:function(e){let{value:t,className:n,mobile:s=!1,isDropdownItem:a=!1}=e;const r=a?"li":"div";return(0,u.jsx)(r,{className:(0,o.A)({navbar__item:!s&&!a,"menu__list-item":s},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:s,...o}=e;const{activeDoc:a}=(0,ve.zK)(s),r=(0,Qe.QB)(t,s),i=a?.path===r?.path;return null===r||r.unlisted&&!i?null:(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>i||!!a?.sidebar&&a.sidebar===r.sidebar,label:n??r.id,to:r.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:s,...o}=e;const{activeDoc:a}=(0,ve.zK)(s),r=(0,Qe.fW)(t,s).link;if(!r)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>a?.sidebar===t,label:n??r.label,to:r.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:s,...o}=e;const a=(0,Qe.Vd)(s)[0],r=t??a.label,i=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(a).path;return(0,u.jsx)(ae,{...o,label:r,to:i})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:s,dropdownItemsBefore:o,dropdownItemsAfter:a,...r}=e;const{search:d,hash:l}=(0,i.zy)(),p=(0,ve.zK)(n),m=(0,ve.jh)(n),{savePreferredVersionName:g}=(0,Ve.g1)(n),f=[...o,...m.map((function(e){const t=He(e,p);return{label:e.label,to:`${t.path}${d}${l}`,isActive:()=>e===p.activeVersion,onClick:()=>g(e.name)}})),...a],h=(0,Qe.Vd)(n)[0],b=t&&f.length>1?(0,c.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):h.label,y=t&&f.length>1?void 0:He(h,p).path;return f.length<=1?(0,u.jsx)(ae,{...r,mobile:t,label:b,to:y,isActive:s?()=>!1:void 0}):(0,u.jsx)(me,{...r,mobile:t,label:b,to:y,items:f,isActive:s?()=>!1:void 0})}};function Ge(e){let{type:t,...n}=e;const s=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=We[s];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(o,{...n})}function Xe(){const e=(0,j.M)(),t=(0,k.p)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,s.createElement)(Ge,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ke(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(c.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Ze(){const e=0===(0,k.p)().navbar.items.length,t=D();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Ke,{onClick:()=>t.hide()}),t.content]})}function Ye(){const e=(0,j.M)();var t;return void 0===(t=e.shown)&&(t=!0),(0,s.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(F,{header:(0,u.jsx)(K,{}),primaryMenu:(0,u.jsx)(Xe,{}),secondaryMenu:(0,u.jsx)(Ze,{})}):null}const Je={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function et(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,o.A)("navbar-sidebar__backdrop",e.className)})}function tt(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:a}}=(0,k.p)(),r=(0,j.M)(),{navbarRef:i,isNavbarVisible:l}=function(e){const[t,n]=(0,s.useState)(e),o=(0,s.useRef)(!1),a=(0,s.useRef)(0),r=(0,s.useCallback)((e=>{null!==e&&(a.current=e.getBoundingClientRect().height)}),[]);return(0,P.Mq)(((t,s)=>{let{scrollY:r}=t;if(!e)return;if(r<a.current)return void n(!0);if(o.current)return void(o.current=!1);const i=s?.scrollY,c=document.documentElement.scrollHeight-a.current,d=window.innerHeight;i&&r>=i?n(!1):r+d<c&&n(!0)})),(0,d.$)((t=>{if(!e)return;const s=t.location.hash;if(s?document.getElementById(s.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:r,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:i,"aria-label":(0,c.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.A)("navbar","navbar--fixed-top",n&&[Je.navbarHideable,!l&&Je.navbarHidden],{"navbar--dark":"dark"===a,"navbar--primary":"primary"===a,"navbar-sidebar--show":r.shown}),children:[t,(0,u.jsx)(et,{onClick:r.toggle}),(0,u.jsx)(Ye,{})]})}var nt=n(12181);const st="right";function ot(e){let{width:t=30,height:n=30,className:s,...o}=e;return(0,u.jsx)("svg",{className:s,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function at(){const{toggle:e,shown:t}=(0,j.M)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,c.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(ot,{})})}const rt={colorModeToggle:"colorModeToggle_DEke"};function it(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(nt.k2,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(Ge,{...e})},t)))})}function ct(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function dt(){const e=(0,j.M)(),t=(0,k.p)().navbar.items,[n,s]=function(e){function t(e){return"left"===(e.position??st)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,u.jsx)(ct,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(at,{}),(0,u.jsx)(G,{}),(0,u.jsx)(it,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(it,{items:s}),(0,u.jsx)(H,{className:rt.colorModeToggle}),!o&&(0,u.jsx)(qe,{children:(0,u.jsx)($e,{})})]})})}function ut(){return(0,u.jsx)(tt,{children:(0,u.jsx)(dt,{})})}function lt(e){let{item:t}=e;const{to:n,href:s,label:o,prependBaseUrlToHref:a,...r}=t,i=(0,Y.Ay)(n),c=(0,Y.Ay)(s,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Z.A,{className:"footer__link-item",...s?{href:a?c:s}:{to:i},...r,children:[o,s&&!(0,J.A)(s)&&(0,u.jsx)(te.A,{})]})}function pt(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(lt,{item:t})},t.href??t.to)}function mt(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(pt,{item:e},t)))})]})}function gt(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(mt,{column:e},t)))})}function ft(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function ht(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(lt,{item:t})}function bt(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(s.Fragment,{children:[(0,u.jsx)(ht,{item:e}),t.length!==n+1&&(0,u.jsx)(ft,{})]},n)))})})}function yt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(gt,{columns:t}):(0,u.jsx)(bt,{links:t})}var vt=n(21122);const kt={footerLogoLink:"footerLogoLink_BH7S"};function xt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,Y.hH)(),s={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(vt.A,{className:(0,o.A)("footer__logo",t.className),alt:t.alt,sources:s,width:t.width,height:t.height,style:t.style})}function wt(e){let{logo:t}=e;return t.href?(0,u.jsx)(Z.A,{href:t.href,className:kt.footerLogoLink,target:t.target,children:(0,u.jsx)(xt,{logo:t})}):(0,u.jsx)(xt,{logo:t})}function _t(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function St(e){let{style:t,links:n,logo:s,copyright:a}=e;return(0,u.jsx)("footer",{className:(0,o.A)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(s||a)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[s&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:s}),a]})]})})}function Et(){const{footer:e}=(0,k.p)();if(!e)return null;const{copyright:t,links:n,logo:s,style:o}=e;return(0,u.jsx)(St,{style:o,links:n&&n.length>0&&(0,u.jsx)(yt,{links:n}),logo:s&&(0,u.jsx)(wt,{logo:s}),copyright:t&&(0,u.jsx)(_t,{copyright:t})})}const Ct=s.memo(Et),Tt=(0,L.fM)([M.a,x.o,P.Tv,Ve.VQ,r.Jx,function(e){let{children:t}=e;return(0,u.jsx)(R.y_,{children:(0,u.jsx)(j.e,{children:(0,u.jsx)(O,{children:t})})})}]);function At(e){let{children:t}=e;return(0,u.jsx)(Tt,{children:t})}var jt=n(51107);function Pt(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(jt.A,{as:"h1",className:"hero__title",children:(0,u.jsx)(c.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(nt.a2,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(nt.bq,{error:t})})]})})})}const Lt={mainWrapper:"mainWrapper_z2l0"};function Rt(e){const{children:t,noFooter:n,wrapperClassName:s,title:i,description:c}=e;return(0,b.J)(),(0,u.jsxs)(At,{children:[(0,u.jsx)(r.be,{title:i,description:c}),(0,u.jsx)(v,{}),(0,u.jsx)(A,{}),(0,u.jsx)(ut,{}),(0,u.jsx)("div",{id:l,className:(0,o.A)(h.G.wrapper.main,Lt.mainWrapper,s),children:(0,u.jsx)(a.A,{fallback:e=>(0,u.jsx)(Pt,{...e}),children:t})}),!n&&(0,u.jsx)(Ct,{})]})}},23465:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(96540);var s=n(28774),o=n(86025),a=n(44586),r=n(6342),i=n(21122),c=n(74848);function d(e){let{logo:t,alt:n,imageClassName:s}=e;const a={light:(0,o.Ay)(t.src),dark:(0,o.Ay)(t.srcDark||t.src)},r=(0,c.jsx)(i.A,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return s?(0,c.jsx)("div",{className:s,children:r}):r}function u(e){const{siteConfig:{title:t}}=(0,a.A)(),{navbar:{title:n,logo:i}}=(0,r.p)(),{imageClassName:u,titleClassName:l,...p}=e,m=(0,o.Ay)(i?.href||"/"),g=n?"":t,f=i?.alt??g;return(0,c.jsxs)(s.A,{to:m,...p,...i?.target&&{target:i.target},children:[i&&(0,c.jsx)(d,{logo:i,alt:f,imageClassName:u}),null!=n&&(0,c.jsx)("b",{className:l,children:n})]})}},41463:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(96540);var s=n(5260),o=n(74848);function a(e){let{locale:t,version:n,tag:a}=e;const r=t;return(0,o.jsxs)(s.A,{children:[t&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_version",content:n}),a&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:a}),r&&(0,o.jsx)("meta",{name:"docsearch:language",content:r}),n&&(0,o.jsx)("meta",{name:"docsearch:version",content:n}),a&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:a})]})}},21122:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});var s=n(96540),o=n(15066),a=n(92303),r=n(95293);const i={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var c=n(74848);function d(e){let{className:t,children:n}=e;const d=(0,a.A)(),{colorMode:u}=(0,r.G)();return(0,c.jsx)(c.Fragment,{children:(d?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const a=n({theme:e,className:(0,o.A)(t,i.themedComponent,i[`themedComponent--${e}`])});return(0,c.jsx)(s.Fragment,{children:a},e)}))})}function u(e){const{sources:t,className:n,alt:s,...o}=e;return(0,c.jsx)(d,{className:n,children:e=>{let{theme:n,className:a}=e;return(0,c.jsx)("img",{src:t[n],alt:s,className:a,...o})}})}},41422:(e,t,n)=>{"use strict";n.d(t,{N:()=>b,u:()=>d});var s=n(96540),o=n(38193),a=n(205),r=n(53109),i=n(74848);const c="ease-in-out";function d(e){let{initialState:t}=e;const[n,o]=(0,s.useState)(t??!1),a=(0,s.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:n,setCollapsed:o,toggleCollapsed:a}}const u={display:"none",overflow:"hidden",height:"0px"},l={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?u:l;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function m(e){let{collapsibleRef:t,collapsed:n,animation:o}=e;const a=(0,s.useRef)(!1);(0,s.useEffect)((()=>{const e=t.current;function s(){const t=e.scrollHeight,n=o?.duration??function(e){if((0,r.O)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${o?.easing??c}`,height:`${t}px`}}function i(){const t=s();e.style.transition=t.transition,e.style.height=t.height}if(!a.current)return p(e,n),void(a.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(i(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{i()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function g(e){if(!o.A.canUseDOM)return e?u:l}function f(e){let{as:t="div",collapsed:n,children:o,animation:a,onCollapseTransitionEnd:r,className:c,disableSSRStyle:d}=e;const u=(0,s.useRef)(null);return m({collapsibleRef:u,collapsed:n,animation:a}),(0,i.jsx)(t,{ref:u,style:d?void 0:g(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(u.current,n),r?.(n))},className:c,children:o})}function h(e){let{collapsed:t,...n}=e;const[o,r]=(0,s.useState)(!t),[c,d]=(0,s.useState)(t);return(0,a.A)((()=>{t||r(!0)}),[t]),(0,a.A)((()=>{o&&d(t)}),[o,t]),o?(0,i.jsx)(f,{...n,collapsed:c}):null}function b(e){let{lazy:t,...n}=e;const s=t?h:f;return(0,i.jsx)(s,{...n})}},65041:(e,t,n)=>{"use strict";n.d(t,{M:()=>f,o:()=>g});var s=n(96540),o=n(92303),a=n(70679),r=n(89532),i=n(6342),c=n(74848);const d=(0,a.Wf)("docusaurus.announcement.dismiss"),u=(0,a.Wf)("docusaurus.announcement.id"),l=()=>"true"===d.get(),p=e=>d.set(String(e)),m=s.createContext(null);function g(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,i.p)(),t=(0,o.A)(),[n,a]=(0,s.useState)((()=>!!t&&l()));(0,s.useEffect)((()=>{a(l())}),[]);const r=(0,s.useCallback)((()=>{p(!0),a(!0)}),[]);return(0,s.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const s=t!==n;u.set(t),s&&p(!1),!s&&l()||a(!1)}),[e]),(0,s.useMemo)((()=>({isActive:!!e&&!n,close:r})),[e,n,r])}();return(0,c.jsx)(m.Provider,{value:n,children:t})}function f(){const e=(0,s.useContext)(m);if(!e)throw new r.dV("AnnouncementBarProvider");return e}},95293:(e,t,n)=>{"use strict";n.d(t,{G:()=>b,a:()=>h});var s=n(96540),o=n(38193),a=n(89532),r=n(70679),i=n(6342),c=n(74848);const d=s.createContext(void 0),u="theme",l=(0,r.Wf)(u),p={light:"light",dark:"dark"},m=e=>e===p.dark?p.dark:p.light,g=e=>o.A.canUseDOM?m(document.documentElement.getAttribute("data-theme")):m(e),f=e=>{l.set(m(e))};function h(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,i.p)(),[o,a]=(0,s.useState)(g(e));(0,s.useEffect)((()=>{t&&l.del()}),[t]);const r=(0,s.useCallback)((function(t,s){void 0===s&&(s={});const{persist:o=!0}=s;t?(a(t),o&&f(t)):(a(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),l.del())}),[n,e]);(0,s.useEffect)((()=>{document.documentElement.setAttribute("data-theme",m(o))}),[o]),(0,s.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=l.get();null!==t&&r(m(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,r]);const c=(0,s.useRef)(!1);return(0,s.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),s=()=>{window.matchMedia("print").matches||c.current?c.current=window.matchMedia("print").matches:r(null)};return e.addListener(s),()=>e.removeListener(s)}),[r,t,n]),(0,s.useMemo)((()=>({colorMode:o,setColorMode:r,get isDarkTheme(){return o===p.dark},setLightTheme(){r(p.light)},setDarkTheme(){r(p.dark)}})),[o,r])}();return(0,c.jsx)(d.Provider,{value:n,children:t})}function b(){const e=(0,s.useContext)(d);if(null==e)throw new a.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},22069:(e,t,n)=>{"use strict";n.d(t,{M:()=>m,e:()=>p});var s=n(96540),o=n(75600),a=n(24581),r=n(57485),i=n(6342),c=n(89532),d=n(74848);const u=s.createContext(void 0);function l(){const e=function(){const e=(0,o.YL)(),{items:t}=(0,i.p)().navbar;return 0===t.length&&!e.component}(),t=(0,a.l)(),n=!e&&"mobile"===t,[c,d]=(0,s.useState)(!1);(0,r.$Z)((()=>{if(c)return d(!1),!1}));const u=(0,s.useCallback)((()=>{d((e=>!e))}),[]);return(0,s.useEffect)((()=>{"desktop"===t&&d(!1)}),[t]),(0,s.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:c})),[e,n,u,c])}function p(e){let{children:t}=e;const n=l();return(0,d.jsx)(u.Provider,{value:n,children:t})}function m(){const e=s.useContext(u);if(void 0===e)throw new c.dV("NavbarMobileSidebarProvider");return e}},75600:(e,t,n)=>{"use strict";n.d(t,{GX:()=>d,YL:()=>c,y_:()=>i});var s=n(96540),o=n(89532),a=n(74848);const r=s.createContext(null);function i(e){let{children:t}=e;const n=(0,s.useState)({component:null,props:null});return(0,a.jsx)(r.Provider,{value:n,children:t})}function c(){const e=(0,s.useContext)(r);if(!e)throw new o.dV("NavbarSecondaryMenuContentProvider");return e[0]}function d(e){let{component:t,props:n}=e;const a=(0,s.useContext)(r);if(!a)throw new o.dV("NavbarSecondaryMenuContentProvider");const[,i]=a,c=(0,o.Be)(n);return(0,s.useEffect)((()=>{i({component:t,props:c})}),[i,t,c]),(0,s.useEffect)((()=>()=>i({component:null,props:null})),[i]),null}},14090:(e,t,n)=>{"use strict";n.d(t,{w:()=>o,J:()=>a});var s=n(96540);const o="navigation-with-keyboard";function a(){(0,s.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},24581:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var s=n(96540),o=n(38193);const a={desktop:"desktop",mobile:"mobile",ssr:"ssr"},r=996;function i(e){let{desktopBreakpoint:t=r}=void 0===e?{}:e;const[n,i]=(0,s.useState)((()=>"ssr"));return(0,s.useEffect)((()=>{function e(){i(function(e){if(!o.A.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?a.desktop:a.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},17559:(e,t,n)=>{"use strict";n.d(t,{G:()=>s});const s={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",blogAuthorsListPage:"blog-authors-list-page",blogAuthorsPostsPage:"blog-authors-posts-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",draftBanner:"theme-draft-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},53109:(e,t,n)=>{"use strict";function s(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>s})},12181:(e,t,n)=>{"use strict";n.d(t,{bq:()=>u,MN:()=>d,a2:()=>c,k2:()=>l});var s=n(96540),o=n(21312),a=n(70440);const r={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};var i=n(74848);function c(e){return(0,i.jsx)("button",{type:"button",...e,children:(0,i.jsx)(o.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function d(e){let{error:t,tryAgain:n}=e;return(0,i.jsxs)("div",{className:r.errorBoundaryFallback,children:[(0,i.jsx)("p",{children:t.message}),(0,i.jsx)(c,{onClick:n})]})}function u(e){let{error:t}=e;const n=(0,a.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,i.jsx)("p",{className:r.errorBoundaryError,children:n})}class l extends s.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}},57485:(e,t,n)=>{"use strict";n.d(t,{$Z:()=>r,aZ:()=>c});var s=n(96540),o=n(56347),a=n(89532);function r(e){!function(e){const t=(0,o.W6)(),n=(0,a._q)(e);(0,s.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function i(e){const t=(0,o.W6)();return(0,s.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}function c(e){return i((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}},31682:(e,t,n)=>{"use strict";function s(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,s)=>e.findIndex((e=>t(e,n)))!==s))}function o(e){return Array.from(new Set(e))}function a(e,t){const n={};let s=0;for(const o of e){const e=t(o,s);n[e]??=[],n[e].push(o),s+=1}return n}n.d(t,{$z:()=>a,XI:()=>s,sb:()=>o})},61213:(e,t,n)=>{"use strict";n.d(t,{e3:()=>p,be:()=>u,Jx:()=>m});var s=n(96540),o=n(15066),a=n(5260),r=n(36803),i=n(86025),c=n(44586);var d=n(74848);function u(e){let{title:t,description:n,keywords:s,image:o,children:r}=e;const u=function(e){const{siteConfig:t}=(0,c.A)(),{title:n,titleDelimiter:s}=t;return e?.trim().length?`${e.trim()} ${s} ${n}`:n}(t),{withBaseUrl:l}=(0,i.hH)(),p=o?l(o,{absolute:!0}):void 0;return(0,d.jsxs)(a.A,{children:[t&&(0,d.jsx)("title",{children:u}),t&&(0,d.jsx)("meta",{property:"og:title",content:u}),n&&(0,d.jsx)("meta",{name:"description",content:n}),n&&(0,d.jsx)("meta",{property:"og:description",content:n}),s&&(0,d.jsx)("meta",{name:"keywords",content:Array.isArray(s)?s.join(","):s}),p&&(0,d.jsx)("meta",{property:"og:image",content:p}),p&&(0,d.jsx)("meta",{name:"twitter:image",content:p}),r]})}const l=s.createContext(void 0);function p(e){let{className:t,children:n}=e;const r=s.useContext(l),i=(0,o.A)(r,t);return(0,d.jsxs)(l.Provider,{value:i,children:[(0,d.jsx)(a.A,{children:(0,d.jsx)("html",{className:i})}),n]})}function m(e){let{children:t}=e;const n=(0,r.A)(),s=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const a=`plugin-id-${n.plugin.id}`;return(0,d.jsx)(p,{className:(0,o.A)(s,a),children:t})}},89532:(e,t,n)=>{"use strict";n.d(t,{Be:()=>d,ZC:()=>i,_q:()=>r,dV:()=>c,fM:()=>u});var s=n(96540),o=n(205),a=n(74848);function r(e){const t=(0,s.useRef)(e);return(0,o.A)((()=>{t.current=e}),[e]),(0,s.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,s.useRef)();return(0,o.A)((()=>{t.current=e})),t.current}class c extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function d(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,s.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,a.jsx)(a.Fragment,{children:e.reduceRight(((e,t)=>(0,a.jsx)(t,{children:e})),n)})}}},99169:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>i,ys:()=>r});var s=n(96540),o=n(35947),a=n(44586);function r(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function i(){const{baseUrl:e}=(0,a.A)().siteConfig;return(0,s.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function s(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(s)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.A,baseUrl:e})),[e])}},23104:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>m,Tv:()=>u,a_:()=>g,gk:()=>f});var s=n(96540),o=n(38193),a=n(92303),r=n(205),i=n(89532),c=n(74848);const d=s.createContext(void 0);function u(e){let{children:t}=e;const n=function(){const e=(0,s.useRef)(!0);return(0,s.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,c.jsx)(d.Provider,{value:n,children:t})}function l(){const e=(0,s.useContext)(d);if(null==e)throw new i.dV("ScrollControllerProvider");return e}const p=()=>o.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function m(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=l(),o=(0,s.useRef)(p()),a=(0,i._q)(e);(0,s.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=p();a(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[a,n,...t])}function g(){const e=l(),t=function(){const e=(0,s.useRef)({elem:null,top:0}),t=(0,s.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,s.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const s=t.getBoundingClientRect().top-n;return s&&window.scrollBy({left:0,top:s}),e.current={elem:null,top:0},{restored:0!==s}}),[]);return(0,s.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,s.useRef)(void 0),o=(0,s.useCallback)((s=>{t.save(s),e.disableScrollEvents(),n.current=()=>{const{restored:s}=t.restore();if(n.current=void 0,s){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,r.A)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:o}}function f(){const e=(0,s.useRef)(null),t=(0,a.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function s(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&o<e)&&(t=requestAnimationFrame(s),window.scrollTo(0,Math.floor(.85*(o-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},70679:(e,t,n)=>{"use strict";n.d(t,{Wf:()=>u,Dv:()=>l});var s=n(96540);const o=JSON.parse('{"N":"localStorage","M":""}'),a=o.N;function r(e){let{key:t,oldValue:n,newValue:s,storage:o}=e;if(n===s)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,t,n,s,window.location.href,o),window.dispatchEvent(a)}function i(e){if(void 0===e&&(e=a),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,c||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),c=!0),null}var t}let c=!1;const d={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function u(e,t){const n=`${e}${o.M}`;if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(n);const s=i(t?.persistence);return null===s?d:{get:()=>{try{return s.getItem(n)}catch(e){return console.error(`Docusaurus storage error, can't get key=${n}`,e),null}},set:e=>{try{const t=s.getItem(n);s.setItem(n,e),r({key:n,oldValue:t,newValue:e,storage:s})}catch(t){console.error(`Docusaurus storage error, can't set ${n}=${e}`,t)}},del:()=>{try{const e=s.getItem(n);s.removeItem(n),r({key:n,oldValue:e,newValue:null,storage:s})}catch(e){console.error(`Docusaurus storage error, can't delete key=${n}`,e)}},listen:e=>{try{const t=t=>{t.storageArea===s&&t.key===n&&e(t)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)}catch(t){return console.error(`Docusaurus storage error, can't listen for changes of key=${n}`,t),()=>{}}}}}function l(e,t){const n=(0,s.useRef)((()=>null===e?d:u(e,t))).current(),o=(0,s.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,s.useSyncExternalStore)(o,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},32131:(e,t,n)=>{"use strict";n.d(t,{o:()=>r});var s=n(44586),o=n(56347),a=n(70440);function r(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:r,currentLocale:i}}=(0,s.A)(),{pathname:c}=(0,o.zy)(),d=(0,a.Ks)(c,{trailingSlash:n,baseUrl:e}),u=i===r?e:e.replace(`/${i}/`,"/"),l=d.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:s}=e;return`${s?t:""}${function(e){return e===r?`${u}`:`${u}${e}/`}(n)}${l}`}}}},75062:(e,t,n)=>{"use strict";n.d(t,{$:()=>r});var s=n(96540),o=n(56347),a=n(89532);function r(e){const t=(0,o.zy)(),n=(0,a.ZC)(t),r=(0,a._q)(e);(0,s.useEffect)((()=>{n&&t!==n&&r({location:t,previousLocation:n})}),[r,t,n])}},6342:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var s=n(44586);function o(){return(0,s.A)().siteConfig.themeConfig}},12983:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addTrailingSlash=o,t.default=function(e,t){const{trailingSlash:n,baseUrl:s}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[r]=e.split(/[#?]/),i="/"===r||r===s?r:(c=r,d=n,d?o(c):a(c));var c,d;return e.replace(r,i)},t.addLeadingSlash=function(e){return(0,s.addPrefix)(e,"/")},t.removeTrailingSlash=a;const s=n(42566);function o(e){return e.endsWith("/")?e:`${e}/`}function a(e){return(0,s.removeSuffix)(e,"/")}},80253:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=function e(t){if(t.cause)return[t,...e(t.cause)];return[t]}},70440:(e,t,n)=>{"use strict";t.rA=t.Ks=t.LU=void 0;const s=n(31635);t.LU="__blog-post-container";var o=n(12983);Object.defineProperty(t,"Ks",{enumerable:!0,get:function(){return s.__importDefault(o).default}});var a=n(42566);var r=n(80253);Object.defineProperty(t,"rA",{enumerable:!0,get:function(){return r.getErrorCausalChain}})},42566:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){if(""===t)return e;return e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},2849:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});n(96540);var s=n(20053);const o={loadingRing:"loadingRing_RJI3","loading-ring":"loading-ring_FB5o"};var a=n(74848);function r(e){let{className:t}=e;return(0,a.jsxs)("div",{className:(0,s.A)(o.loadingRing,t),children:[(0,a.jsx)("div",{}),(0,a.jsx)("div",{}),(0,a.jsx)("div",{}),(0,a.jsx)("div",{})]})}},5891:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var s=n(58291),o=n.n(s),a=n(11088);const r=new Map;function i(e,t){const n=`${e}${t}`;let s=r.get(n);return s||(s=async function(e,t){{const n=`${e}${a.IH.replace("{dir}",t?`-${t.replace(/\//g,"-")}`:"")}`;if(new URL(n,location.origin).origin!==location.origin)throw new Error("Unexpected version url");const s=await(await fetch(n)).json(),r=s.map(((e,t)=>{let{documents:n,index:s}=e;return{type:t,documents:n,index:o().Index.load(s)}})),i=s.reduce(((e,t)=>{for(const n of t.index.invertedIndex)/\p{Unified_Ideograph}/u.test(n[0][0])&&e.add(n[0]);return e}),new Set);return{wrappedIndexes:r,zhDictionary:Array.from(i)}}return{wrappedIndexes:[],zhDictionary:[]}}(e,t),r.set(n,s)),s}},32384:(e,t,n)=>{"use strict";n.d(t,{m:()=>p});var s=n(58291),o=n.n(s);const a=12,r=a/2;var i=n(11088);function c(e,t){const n=function(e,t){const n=e.map((e=>/\p{Unified_Ideograph}/u.test(e)?function(e,t){const n=[];return function e(s,o){let a=0,r=!1;for(const i of t)if(s.substr(0,i.length)===i){const t={missed:o.missed,term:o.term.concat({value:i})};s.length>i.length?e(s.substr(i.length),t):n.push(t),r=!0}else for(let t=i.length-1;t>a;t-=1){const c=i.substr(0,t);if(s.substr(0,t)===c){a=t;const i={missed:o.missed,term:o.term.concat({value:c,trailing:!0})};s.length>t?e(s.substr(t),i):n.push(i),r=!0;break}}r||(s.length>0?e(s.substr(1),{missed:o.missed+1,term:o.term}):o.term.length>0&&n.push(o))}(e,{missed:0,term:[]}),n.sort(((e,t)=>{const n=e.missed>0?1:0,s=t.missed>0?1:0;return n!==s?n-s:e.term.length-t.term.length})).map((e=>e.term))}(e,t):[{value:e}])).slice(0,a),s=n.filter((e=>e.length>1));let o=1,i=!1;for(const d of s)if(i)d.splice(1,d.length-1);else{d.length>r&&d.splice(r,d.length-r);const e=o*d.length;if(e>=a){if(e>a){const e=Math.floor(a/o);d.splice(e,d.length-e),o*=e}else o=e;o>r&&(i=!0)}else o=e}const c=[];return function e(t,s){if(t===n.length||s.length>=a)c.push(s.slice(0,a));else for(const o of n[t])e(t+1,s.concat(o))}(0,[]),c}(e,t);if(0===n.length)return[{tokens:e,term:e.map((e=>({value:e,presence:o().Query.presence.REQUIRED,wildcard:o().Query.wildcard.LEADING|o().Query.wildcard.TRAILING})))}];for(const o of n)o[o.length-1].maybeTyping=!0;const s=[];for(const a of i.BH)if("en"===a)i.sx||s.unshift(o().stopWordFilter);else{const e=o()[a];e.stopWordFilter&&s.unshift(e.stopWordFilter)}let c;if(s.length>0){const e=e=>s.reduce(((e,t)=>e.filter((e=>t(e.value)))),e);c=[];const t=[];for(const s of n){const n=e(s);c.push(n),n.length<s.length&&n.length>0&&t.push(n)}n.push(...t)}else c=n.slice();const u=[];for(const o of c)if(o.length>2)for(let e=o.length-1;e>=0;e-=1)u.push(o.slice(0,e).concat(o.slice(e+1)));return d(n).concat(d(u))}function d(e){return u(e).concat(u(e.filter((e=>{const t=e[e.length-1];return!t.trailing&&t.maybeTyping})),!0))}function u(e,t){return e.map((e=>({tokens:e.map((e=>e.value)),term:e.map((e=>({value:e.value,presence:o().Query.presence.REQUIRED,wildcard:(t?e.trailing||e.maybeTyping:e.trailing)?o().Query.wildcard.TRAILING:o().Query.wildcard.NONE})))})))}var l=n(69913);function p(e,t,n){return function(s,a){const r=function(e,t){if(1===t.length&&["ja","jp","th"].includes(t[0]))return o()[t[0]].tokenizer(e).map((e=>e.toString()));let n=/[^-\s]+/g;return t.includes("zh")&&(n=/\w+|\p{Unified_Ideograph}+/gu),e.toLowerCase().match(n)||[]}(s,i.BH);if(0===r.length)return void a([]);const d=c(r,t),u=[];e:for(const{term:t,tokens:o}of d)for(const{documents:s,index:a,type:r}of e)if(u.push(...a.query((e=>{for(const n of t)e.term(n.value,{wildcard:n.wildcard,presence:n.presence})})).slice(0,n).filter((e=>!u.some((t=>t.document.i.toString()===e.ref)))).slice(0,n-u.length).map((t=>{const n=s.find((e=>e.i.toString()===t.ref));return{document:n,type:r,page:r!==l.i.Title&&e[0].documents.find((e=>e.i===n.p)),metadata:t.matchData.metadata,tokens:o,score:t.score}}))),u.length>=n)break e;!function(e){e.forEach(((e,t)=>{e.index=t})),e.sort(((t,n)=>{let s=t.type!==l.i.Heading&&t.type!==l.i.Content&&t.type!==l.i.Description||!t.page?t.index:e.findIndex((e=>e.document===t.page)),o=n.type!==l.i.Heading&&n.type!==l.i.Content&&n.type!==l.i.Description||!n.page?n.index:e.findIndex((e=>e.document===n.page));if(-1===s&&(s=t.index),-1===o&&(o=n.index),s===o){const e=(0===n.type?1:0)-(0===t.type?1:0);return 0===e?t.index-n.index:e}return s-o}))}(u),function(e){e.forEach(((t,n)=>{n>0&&t.page&&e.slice(0,n).some((e=>(e.type===l.i.Keywords?e.page:e.document)===t.page))&&(n<e.length-1&&e[n+1].page===t.page?t.isInterOfTree=!0:t.isLastOfTree=!0)}))}(u),a(u)}}},4471:(e,t,n)=>{"use strict";function s(e){return e.join(" \u203a ")}n.d(t,{$:()=>s})},53103:(e,t,n)=>{"use strict";function s(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}n.d(t,{Z:()=>s})},27674:(e,t,n)=>{"use strict";function s(e,t){const n=[];for(const s of Object.values(e))s[t]&&n.push(...s[t].position);return n.sort(((e,t)=>e[0]-t[0]||t[1]-e[1]))}n.d(t,{g:()=>s})},86841:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var s=n(53103);function o(e,t,n){const a=[];for(const r of t){const n=e.toLowerCase().indexOf(r);if(n>=0){n>0&&a.push(o(e.substr(0,n),t)),a.push(`<mark>${(0,s.Z)(e.substr(n,r.length))}</mark>`);const i=n+r.length;i<e.length&&a.push(o(e.substr(i),t));break}}return 0===a.length?n?`<mark>${(0,s.Z)(e)}</mark>`:(0,s.Z)(e):a.join("")}},43810:(e,t,n)=>{"use strict";n.d(t,{C:()=>c});var s=n(53103),o=n(86841);const a=/\w+|\p{Unified_Ideograph}/u;function r(e){const t=[];let n=0,s=e;for(;s.length>0;){const o=s.match(a);if(!o){t.push(s);break}o.index>0&&t.push(s.substring(0,o.index)),t.push(o[0]),n+=o.index+o[0].length,s=e.substring(n)}return t}var i=n(11088);function c(e,t,n,a){void 0===a&&(a=i.rG);const{chunkIndex:c,chunks:d}=function(e,t,n){const a=[];let i=0,c=0,d=-1;for(;i<t.length;){const[u,l]=t[i];if(i+=1,!(u<c)){if(u>c){const t=r(e.substring(c,u)).map((e=>({html:(0,s.Z)(e),textLength:e.length})));for(const e of t)a.push(e)}-1===d&&(d=a.length),c=u+l,a.push({html:(0,o.Z)(e.substring(u,c),n,!0),textLength:l})}}if(c<e.length){const t=r(e.substring(c)).map((e=>({html:(0,s.Z)(e),textLength:e.length})));for(const e of t)a.push(e)}return{chunkIndex:d,chunks:a}}(e,t,n),u=d.slice(0,c),l=d[c],p=[l.html],m=d.slice(c+1);let g=l.textLength,f=0,h=0,b=!1,y=!1;for(;g<a;)if((f<=h||0===m.length)&&u.length>0){const e=u.pop();g+e.textLength<=a?(p.unshift(e.html),f+=e.textLength,g+=e.textLength):(b=!0,u.length=0)}else{if(!(m.length>0))break;{const e=m.shift();g+e.textLength<=a?(p.push(e.html),h+=e.textLength,g+=e.textLength):(y=!0,m.length=0)}}return(b||u.length>0)&&p.unshift("\u2026"),(y||m.length>0)&&p.push("\u2026"),p.join("")}},43385:(e,t,n)=>{"use strict";function s(e,t){if("string"==typeof e)return{label:e,path:e};{const{label:n,path:s}=e;return"string"==typeof n?{label:n,path:s}:Object.prototype.hasOwnProperty.call(n,t)?{label:n[t],path:s}:{label:s,path:s}}}n.d(t,{p:()=>s})},11088:(e,t,n)=>{"use strict";n.d(t,{CU:()=>a,UB:()=>m,tb:()=>d,O6:()=>h,I$:()=>g,BH:()=>s,sx:()=>o,ZG:()=>p,WW:()=>u,pk:()=>l,Hg:()=>f,IH:()=>r,rG:()=>c,AT:()=>i,dz:()=>b});n(58291);const s=["en"],o=!1,a=null,r="search-index{dir}.json?_=0d506c80",i=8,c=50,d=!1,u=!0,l=!0,p="right",m=void 0,g=!0,f=null,h=!1,b=!1},69913:(e,t,n)=>{"use strict";var s;n.d(t,{i:()=>s}),function(e){e[e.Title=0]="Title",e[e.Heading=1]="Heading",e[e.Description=2]="Description",e[e.Keywords=3]="Keywords",e[e.Content=4]="Content"}(s||(s={}))},45477:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});const s=n(38193).A.canUseDOM?{onRouteUpdate(e){let{location:t}=e;_paq.push(["setCustomUrl",t.pathname]),_paq.push(["setDocumentTitle",document.title]),_paq.push(["trackPageView"])}}:null},20053:(e,t,n)=>{"use strict";function s(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=s(e[t]))&&(o&&(o+=" "),o+=n);else for(t in e)e[t]&&(o&&(o+=" "),o+=t);return o}n.d(t,{A:()=>o});const o=function(){for(var e,t,n=0,o="";n<arguments.length;)(e=arguments[n++])&&(t=s(e))&&(o&&(o+=" "),o+=t);return o}},31513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>k,TM:()=>C,yJ:()=>m,sC:()=>A,AO:()=>p});var s=n(58168);function o(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,s=n+1,o=e.length;s<o;n+=1,s+=1)e[n]=e[s];e.pop()}const r=function(e,t){void 0===t&&(t="");var n,s=e&&e.split("/")||[],r=t&&t.split("/")||[],i=e&&o(e),c=t&&o(t),d=i||c;if(e&&o(e)?r=s:s.length&&(r.pop(),r=r.concat(s)),!r.length)return"/";if(r.length){var u=r[r.length-1];n="."===u||".."===u||""===u}else n=!1;for(var l=0,p=r.length;p>=0;p--){var m=r[p];"."===m?a(r,p):".."===m?(a(r,p),l++):l&&(a(r,p),l--)}if(!d)for(;l--;l)r.unshift("..");!d||""===r[0]||r[0]&&o(r[0])||r.unshift("");var g=r.join("/");return n&&"/"!==g.substr(-1)&&(g+="/"),g};var i=n(11561);function c(e){return"/"===e.charAt(0)?e:"/"+e}function d(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function l(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,s=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),s&&"#"!==s&&(o+="#"===s.charAt(0)?s:"#"+s),o}function m(e,t,n,o){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",s="",o=t.indexOf("#");-1!==o&&(s=t.substr(o),t=t.substr(0,o));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===s?"":s}}(e),a.state=t):(void 0===(a=(0,s.A)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(i){throw i instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):i}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=r(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function g(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,s,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof s?s(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function s(){n&&e.apply(void 0,arguments)}return t.push(s),function(){n=!1,t=t.filter((function(e){return e!==s}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),s=0;s<e;s++)n[s]=arguments[s];t.forEach((function(e){return e.apply(void 0,n)}))}}}var f=!("undefined"==typeof window||!window.document||!window.document.createElement);function h(e,t){t(window.confirm(e))}var b="popstate",y="hashchange";function v(){try{return window.history.state||{}}catch(e){return{}}}function k(e){void 0===e&&(e={}),f||(0,i.A)(!1);var t,n=window.history,o=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,a=!(-1===window.navigator.userAgent.indexOf("Trident")),r=e,d=r.forceRefresh,k=void 0!==d&&d,x=r.getUserConfirmation,w=void 0===x?h:x,_=r.keyLength,S=void 0===_?6:_,E=e.basename?l(c(e.basename)):"";function C(e){var t=e||{},n=t.key,s=t.state,o=window.location,a=o.pathname+o.search+o.hash;return E&&(a=u(a,E)),m(a,s,n)}function T(){return Math.random().toString(36).substr(2,S)}var A=g();function j(e){(0,s.A)($,e),$.length=n.length,A.notifyListeners($.location,$.action)}function P(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||N(C(e.state))}function L(){N(C(v()))}var R=!1;function N(e){if(R)R=!1,j();else{A.confirmTransitionTo(e,"POP",w,(function(t){t?j({action:"POP",location:e}):function(e){var t=$.location,n=I.indexOf(t.key);-1===n&&(n=0);var s=I.indexOf(e.key);-1===s&&(s=0);var o=n-s;o&&(R=!0,F(o))}(e)}))}}var O=C(v()),I=[O.key];function D(e){return E+p(e)}function F(e){n.go(e)}var M=0;function z(e){1===(M+=e)&&1===e?(window.addEventListener(b,P),a&&window.addEventListener(y,L)):0===M&&(window.removeEventListener(b,P),a&&window.removeEventListener(y,L))}var B=!1;var $={length:n.length,action:"POP",location:O,createHref:D,push:function(e,t){var s="PUSH",a=m(e,t,T(),$.location);A.confirmTransitionTo(a,s,w,(function(e){if(e){var t=D(a),r=a.key,i=a.state;if(o)if(n.pushState({key:r,state:i},null,t),k)window.location.href=t;else{var c=I.indexOf($.location.key),d=I.slice(0,c+1);d.push(a.key),I=d,j({action:s,location:a})}else window.location.href=t}}))},replace:function(e,t){var s="REPLACE",a=m(e,t,T(),$.location);A.confirmTransitionTo(a,s,w,(function(e){if(e){var t=D(a),r=a.key,i=a.state;if(o)if(n.replaceState({key:r,state:i},null,t),k)window.location.replace(t);else{var c=I.indexOf($.location.key);-1!==c&&(I[c]=a.key),j({action:s,location:a})}else window.location.replace(t)}}))},go:F,goBack:function(){F(-1)},goForward:function(){F(1)},block:function(e){void 0===e&&(e=!1);var t=A.setPrompt(e);return B||(z(1),B=!0),function(){return B&&(B=!1,z(-1)),t()}},listen:function(e){var t=A.appendListener(e);return z(1),function(){z(-1),t()}}};return $}var x="hashchange",w={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+d(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:d,decodePath:c},slash:{encodePath:c,decodePath:c}};function _(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function S(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function E(e){window.location.replace(_(window.location.href)+"#"+e)}function C(e){void 0===e&&(e={}),f||(0,i.A)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),o=n.getUserConfirmation,a=void 0===o?h:o,r=n.hashType,d=void 0===r?"slash":r,b=e.basename?l(c(e.basename)):"",y=w[d],v=y.encodePath,k=y.decodePath;function C(){var e=k(S());return b&&(e=u(e,b)),m(e)}var T=g();function A(e){(0,s.A)(B,e),B.length=t.length,T.notifyListeners(B.location,B.action)}var j=!1,P=null;function L(){var e,t,n=S(),s=v(n);if(n!==s)E(s);else{var o=C(),r=B.location;if(!j&&(t=o,(e=r).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(P===p(o))return;P=null,function(e){if(j)j=!1,A();else{var t="POP";T.confirmTransitionTo(e,t,a,(function(n){n?A({action:t,location:e}):function(e){var t=B.location,n=I.lastIndexOf(p(t));-1===n&&(n=0);var s=I.lastIndexOf(p(e));-1===s&&(s=0);var o=n-s;o&&(j=!0,D(o))}(e)}))}}(o)}}var R=S(),N=v(R);R!==N&&E(N);var O=C(),I=[p(O)];function D(e){t.go(e)}var F=0;function M(e){1===(F+=e)&&1===e?window.addEventListener(x,L):0===F&&window.removeEventListener(x,L)}var z=!1;var B={length:t.length,action:"POP",location:O,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=_(window.location.href)),n+"#"+v(b+p(e))},push:function(e,t){var n="PUSH",s=m(e,void 0,void 0,B.location);T.confirmTransitionTo(s,n,a,(function(e){if(e){var t=p(s),o=v(b+t);if(S()!==o){P=t,function(e){window.location.hash=e}(o);var a=I.lastIndexOf(p(B.location)),r=I.slice(0,a+1);r.push(t),I=r,A({action:n,location:s})}else A()}}))},replace:function(e,t){var n="REPLACE",s=m(e,void 0,void 0,B.location);T.confirmTransitionTo(s,n,a,(function(e){if(e){var t=p(s),o=v(b+t);S()!==o&&(P=t,E(o));var a=I.indexOf(p(B.location));-1!==a&&(I[a]=t),A({action:n,location:s})}}))},go:D,goBack:function(){D(-1)},goForward:function(){D(1)},block:function(e){void 0===e&&(e=!1);var t=T.setPrompt(e);return z||(M(1),z=!0),function(){return z&&(z=!1,M(-1)),t()}},listen:function(e){var t=T.appendListener(e);return M(1),function(){M(-1),t()}}};return B}function T(e,t,n){return Math.min(Math.max(e,t),n)}function A(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,o=t.initialEntries,a=void 0===o?["/"]:o,r=t.initialIndex,i=void 0===r?0:r,c=t.keyLength,d=void 0===c?6:c,u=g();function l(e){(0,s.A)(k,e),k.length=k.entries.length,u.notifyListeners(k.location,k.action)}function f(){return Math.random().toString(36).substr(2,d)}var h=T(i,0,a.length-1),b=a.map((function(e){return m(e,void 0,"string"==typeof e?f():e.key||f())})),y=p;function v(e){var t=T(k.index+e,0,k.entries.length-1),s=k.entries[t];u.confirmTransitionTo(s,"POP",n,(function(e){e?l({action:"POP",location:s,index:t}):l()}))}var k={length:b.length,action:"POP",location:b[h],index:h,entries:b,createHref:y,push:function(e,t){var s="PUSH",o=m(e,t,f(),k.location);u.confirmTransitionTo(o,s,n,(function(e){if(e){var t=k.index+1,n=k.entries.slice(0);n.length>t?n.splice(t,n.length-t,o):n.push(o),l({action:s,location:o,index:t,entries:n})}}))},replace:function(e,t){var s="REPLACE",o=m(e,t,f(),k.location);u.confirmTransitionTo(o,s,n,(function(e){e&&(k.entries[k.index]=o,l({action:s,location:o}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=k.index+e;return t>=0&&t<k.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return k}},4146:(e,t,n)=>{"use strict";var s=n(44363),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},r={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},i={};function c(e){return s.isMemo(e)?r:i[e.$$typeof]||o}i[s.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},i[s.Memo]=r;var d=Object.defineProperty,u=Object.getOwnPropertyNames,l=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,m=Object.getPrototypeOf,g=Object.prototype;e.exports=function e(t,n,s){if("string"!=typeof n){if(g){var o=m(n);o&&o!==g&&e(t,o,s)}var r=u(n);l&&(r=r.concat(l(n)));for(var i=c(t),f=c(n),h=0;h<r.length;++h){var b=r[h];if(!(a[b]||s&&s[b]||f&&f[b]||i&&i[b])){var y=p(n,b);try{d(t,b,y)}catch(v){}}}}return t}},20311:e=>{"use strict";e.exports=function(e,t,n,s,o,a,r,i){if(!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var d=[n,s,o,a,r,i],u=0;(c=new Error(t.replace(/%s/g,(function(){return d[u++]})))).name="Invariant Violation"}throw c.framesToPop=1,c}}},64634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},58291:(e,t,n)=>{var s,o;!function(){var a,r,i,c,d,u,l,p,m,g,f,h,b,y,v,k,x,w,_,S,E,C,T,A,j,P,L,R,N,O,I=function(e){var t=new I.Builder;return t.pipeline.add(I.trimmer,I.stopWordFilter,I.stemmer),t.searchPipeline.add(I.stemmer),e.call(t,t),t.build()};I.version="2.3.9",I.utils={},I.utils.warn=(a=this,function(e){a.console&&console.warn&&console.warn(e)}),I.utils.asString=function(e){return null==e?"":e.toString()},I.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),s=0;s<n.length;s++){var o=n[s],a=e[o];if(Array.isArray(a))t[o]=a.slice();else{if("string"!=typeof a&&"number"!=typeof a&&"boolean"!=typeof a)throw new TypeError("clone is not deep and does not support nested objects");t[o]=a}}return t},I.FieldRef=function(e,t,n){this.docRef=e,this.fieldName=t,this._stringValue=n},I.FieldRef.joiner="/",I.FieldRef.fromString=function(e){var t=e.indexOf(I.FieldRef.joiner);if(-1===t)throw"malformed field ref string";var n=e.slice(0,t),s=e.slice(t+1);return new I.FieldRef(s,n,e)},I.FieldRef.prototype.toString=function(){return null==this._stringValue&&(this._stringValue=this.fieldName+I.FieldRef.joiner+this.docRef),this._stringValue},I.Set=function(e){if(this.elements=Object.create(null),e){this.length=e.length;for(var t=0;t<this.length;t++)this.elements[e[t]]=!0}else this.length=0},I.Set.complete={intersect:function(e){return e},union:function(){return this},contains:function(){return!0}},I.Set.empty={intersect:function(){return this},union:function(e){return e},contains:function(){return!1}},I.Set.prototype.contains=function(e){return!!this.elements[e]},I.Set.prototype.intersect=function(e){var t,n,s,o=[];if(e===I.Set.complete)return this;if(e===I.Set.empty)return e;this.length<e.length?(t=this,n=e):(t=e,n=this),s=Object.keys(t.elements);for(var a=0;a<s.length;a++){var r=s[a];r in n.elements&&o.push(r)}return new I.Set(o)},I.Set.prototype.union=function(e){return e===I.Set.complete?I.Set.complete:e===I.Set.empty?this:new I.Set(Object.keys(this.elements).concat(Object.keys(e.elements)))},I.idf=function(e,t){var n=0;for(var s in e)"_index"!=s&&(n+=Object.keys(e[s]).length);var o=(t-n+.5)/(n+.5);return Math.log(1+Math.abs(o))},I.Token=function(e,t){this.str=e||"",this.metadata=t||{}},I.Token.prototype.toString=function(){return this.str},I.Token.prototype.update=function(e){return this.str=e(this.str,this.metadata),this},I.Token.prototype.clone=function(e){return e=e||function(e){return e},new I.Token(e(this.str,this.metadata),this.metadata)},I.tokenizer=function(e,t){if(null==e||null==e)return[];if(Array.isArray(e))return e.map((function(e){return new I.Token(I.utils.asString(e).toLowerCase(),I.utils.clone(t))}));for(var n=e.toString().toLowerCase(),s=n.length,o=[],a=0,r=0;a<=s;a++){var i=a-r;if(n.charAt(a).match(I.tokenizer.separator)||a==s){if(i>0){var c=I.utils.clone(t)||{};c.position=[r,i],c.index=o.length,o.push(new I.Token(n.slice(r,a),c))}r=a+1}}return o},I.tokenizer.separator=/[\s\-]+/,I.Pipeline=function(){this._stack=[]},I.Pipeline.registeredFunctions=Object.create(null),I.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&I.utils.warn("Overwriting existing registered function: "+t),e.label=t,I.Pipeline.registeredFunctions[e.label]=e},I.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||I.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},I.Pipeline.load=function(e){var t=new I.Pipeline;return e.forEach((function(e){var n=I.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)})),t},I.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach((function(e){I.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},I.Pipeline.prototype.after=function(e,t){I.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},I.Pipeline.prototype.before=function(e,t){I.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},I.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},I.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n<t;n++){for(var s=this._stack[n],o=[],a=0;a<e.length;a++){var r=s(e[a],a,e);if(null!=r&&""!==r)if(Array.isArray(r))for(var i=0;i<r.length;i++)o.push(r[i]);else o.push(r)}e=o}return e},I.Pipeline.prototype.runString=function(e,t){var n=new I.Token(e,t);return this.run([n]).map((function(e){return e.toString()}))},I.Pipeline.prototype.reset=function(){this._stack=[]},I.Pipeline.prototype.toJSON=function(){return this._stack.map((function(e){return I.Pipeline.warnIfFunctionNotRegistered(e),e.label}))},I.Vector=function(e){this._magnitude=0,this.elements=e||[]},I.Vector.prototype.positionForIndex=function(e){if(0==this.elements.length)return 0;for(var t=0,n=this.elements.length/2,s=n-t,o=Math.floor(s/2),a=this.elements[2*o];s>1&&(a<e&&(t=o),a>e&&(n=o),a!=e);)s=n-t,o=t+Math.floor(s/2),a=this.elements[2*o];return a==e||a>e?2*o:a<e?2*(o+1):void 0},I.Vector.prototype.insert=function(e,t){this.upsert(e,t,(function(){throw"duplicate index"}))},I.Vector.prototype.upsert=function(e,t,n){this._magnitude=0;var s=this.positionForIndex(e);this.elements[s]==e?this.elements[s+1]=n(this.elements[s+1],t):this.elements.splice(s,0,e,t)},I.Vector.prototype.magnitude=function(){if(this._magnitude)return this._magnitude;for(var e=0,t=this.elements.length,n=1;n<t;n+=2){var s=this.elements[n];e+=s*s}return this._magnitude=Math.sqrt(e)},I.Vector.prototype.dot=function(e){for(var t=0,n=this.elements,s=e.elements,o=n.length,a=s.length,r=0,i=0,c=0,d=0;c<o&&d<a;)(r=n[c])<(i=s[d])?c+=2:r>i?d+=2:r==i&&(t+=n[c+1]*s[d+1],c+=2,d+=2);return t},I.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},I.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t<this.elements.length;t+=2,n++)e[n]=this.elements[t];return e},I.Vector.prototype.toJSON=function(){return this.elements},I.stemmer=(r={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},i={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},l="^("+(d="[^aeiou][^aeiouy]*")+")?"+(u=(c="[aeiouy]")+"[aeiou]*")+d+"("+u+")?$",p="^("+d+")?"+u+d+u+d,m="^("+d+")?"+c,g=new RegExp("^("+d+")?"+u+d),f=new RegExp(p),h=new RegExp(l),b=new RegExp(m),y=/^(.+?)(ss|i)es$/,v=/^(.+?)([^s])s$/,k=/^(.+?)eed$/,x=/^(.+?)(ed|ing)$/,w=/.$/,_=/(at|bl|iz)$/,S=new RegExp("([^aeiouylsz])\\1$"),E=new RegExp("^"+d+c+"[^aeiouwxy]$"),C=/^(.+?[^aeiou])y$/,T=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,A=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,j=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,P=/^(.+?)(s|t)(ion)$/,L=/^(.+?)e$/,R=/ll$/,N=new RegExp("^"+d+c+"[^aeiouwxy]$"),O=function(e){var t,n,s,o,a,c,d;if(e.length<3)return e;if("y"==(s=e.substr(0,1))&&(e=s.toUpperCase()+e.substr(1)),a=v,(o=y).test(e)?e=e.replace(o,"$1$2"):a.test(e)&&(e=e.replace(a,"$1$2")),a=x,(o=k).test(e)){var u=o.exec(e);(o=g).test(u[1])&&(o=w,e=e.replace(o,""))}else a.test(e)&&(t=(u=a.exec(e))[1],(a=b).test(t)&&(c=S,d=E,(a=_).test(e=t)?e+="e":c.test(e)?(o=w,e=e.replace(o,"")):d.test(e)&&(e+="e")));return(o=C).test(e)&&(e=(t=(u=o.exec(e))[1])+"i"),(o=T).test(e)&&(t=(u=o.exec(e))[1],n=u[2],(o=g).test(t)&&(e=t+r[n])),(o=A).test(e)&&(t=(u=o.exec(e))[1],n=u[2],(o=g).test(t)&&(e=t+i[n])),a=P,(o=j).test(e)?(t=(u=o.exec(e))[1],(o=f).test(t)&&(e=t)):a.test(e)&&(t=(u=a.exec(e))[1]+u[2],(a=f).test(t)&&(e=t)),(o=L).test(e)&&(t=(u=o.exec(e))[1],a=h,c=N,((o=f).test(t)||a.test(t)&&!c.test(t))&&(e=t)),a=f,(o=R).test(e)&&a.test(e)&&(o=w,e=e.replace(o,"")),"y"==s&&(e=s.toLowerCase()+e.substr(1)),e},function(e){return e.update(O)}),I.Pipeline.registerFunction(I.stemmer,"stemmer"),I.generateStopWordFilter=function(e){var t=e.reduce((function(e,t){return e[t]=t,e}),{});return function(e){if(e&&t[e.toString()]!==e.toString())return e}},I.stopWordFilter=I.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),I.Pipeline.registerFunction(I.stopWordFilter,"stopWordFilter"),I.trimmer=function(e){return e.update((function(e){return e.replace(/^\W+/,"").replace(/\W+$/,"")}))},I.Pipeline.registerFunction(I.trimmer,"trimmer"),I.TokenSet=function(){this.final=!1,this.edges={},this.id=I.TokenSet._nextId,I.TokenSet._nextId+=1},I.TokenSet._nextId=1,I.TokenSet.fromArray=function(e){for(var t=new I.TokenSet.Builder,n=0,s=e.length;n<s;n++)t.insert(e[n]);return t.finish(),t.root},I.TokenSet.fromClause=function(e){return"editDistance"in e?I.TokenSet.fromFuzzyString(e.term,e.editDistance):I.TokenSet.fromString(e.term)},I.TokenSet.fromFuzzyString=function(e,t){for(var n=new I.TokenSet,s=[{node:n,editsRemaining:t,str:e}];s.length;){var o=s.pop();if(o.str.length>0){var a,r=o.str.charAt(0);r in o.node.edges?a=o.node.edges[r]:(a=new I.TokenSet,o.node.edges[r]=a),1==o.str.length&&(a.final=!0),s.push({node:a,editsRemaining:o.editsRemaining,str:o.str.slice(1)})}if(0!=o.editsRemaining){if("*"in o.node.edges)var i=o.node.edges["*"];else{i=new I.TokenSet;o.node.edges["*"]=i}if(0==o.str.length&&(i.final=!0),s.push({node:i,editsRemaining:o.editsRemaining-1,str:o.str}),o.str.length>1&&s.push({node:o.node,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)}),1==o.str.length&&(o.node.final=!0),o.str.length>=1){if("*"in o.node.edges)var c=o.node.edges["*"];else{c=new I.TokenSet;o.node.edges["*"]=c}1==o.str.length&&(c.final=!0),s.push({node:c,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)})}if(o.str.length>1){var d,u=o.str.charAt(0),l=o.str.charAt(1);l in o.node.edges?d=o.node.edges[l]:(d=new I.TokenSet,o.node.edges[l]=d),1==o.str.length&&(d.final=!0),s.push({node:d,editsRemaining:o.editsRemaining-1,str:u+o.str.slice(2)})}}}return n},I.TokenSet.fromString=function(e){for(var t=new I.TokenSet,n=t,s=0,o=e.length;s<o;s++){var a=e[s],r=s==o-1;if("*"==a)t.edges[a]=t,t.final=r;else{var i=new I.TokenSet;i.final=r,t.edges[a]=i,t=i}}return n},I.TokenSet.prototype.toArray=function(){for(var e=[],t=[{prefix:"",node:this}];t.length;){var n=t.pop(),s=Object.keys(n.node.edges),o=s.length;n.node.final&&(n.prefix.charAt(0),e.push(n.prefix));for(var a=0;a<o;a++){var r=s[a];t.push({prefix:n.prefix.concat(r),node:n.node.edges[r]})}}return e},I.TokenSet.prototype.toString=function(){if(this._str)return this._str;for(var e=this.final?"1":"0",t=Object.keys(this.edges).sort(),n=t.length,s=0;s<n;s++){var o=t[s];e=e+o+this.edges[o].id}return e},I.TokenSet.prototype.intersect=function(e){for(var t=new I.TokenSet,n=void 0,s=[{qNode:e,output:t,node:this}];s.length;){n=s.pop();for(var o=Object.keys(n.qNode.edges),a=o.length,r=Object.keys(n.node.edges),i=r.length,c=0;c<a;c++)for(var d=o[c],u=0;u<i;u++){var l=r[u];if(l==d||"*"==d){var p=n.node.edges[l],m=n.qNode.edges[d],g=p.final&&m.final,f=void 0;l in n.output.edges?(f=n.output.edges[l]).final=f.final||g:((f=new I.TokenSet).final=g,n.output.edges[l]=f),s.push({qNode:m,output:f,node:p})}}}return t},I.TokenSet.Builder=function(){this.previousWord="",this.root=new I.TokenSet,this.uncheckedNodes=[],this.minimizedNodes={}},I.TokenSet.Builder.prototype.insert=function(e){var t,n=0;if(e<this.previousWord)throw new Error("Out of order word insertion");for(var s=0;s<e.length&&s<this.previousWord.length&&e[s]==this.previousWord[s];s++)n++;this.minimize(n),t=0==this.uncheckedNodes.length?this.root:this.uncheckedNodes[this.uncheckedNodes.length-1].child;for(s=n;s<e.length;s++){var o=new I.TokenSet,a=e[s];t.edges[a]=o,this.uncheckedNodes.push({parent:t,char:a,child:o}),t=o}t.final=!0,this.previousWord=e},I.TokenSet.Builder.prototype.finish=function(){this.minimize(0)},I.TokenSet.Builder.prototype.minimize=function(e){for(var t=this.uncheckedNodes.length-1;t>=e;t--){var n=this.uncheckedNodes[t],s=n.child.toString();s in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[s]:(n.child._str=s,this.minimizedNodes[s]=n.child),this.uncheckedNodes.pop()}},I.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},I.Index.prototype.search=function(e){return this.query((function(t){new I.QueryParser(e,t).parse()}))},I.Index.prototype.query=function(e){for(var t=new I.Query(this.fields),n=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),r=Object.create(null),i=0;i<this.fields.length;i++)s[this.fields[i]]=new I.Vector;e.call(t,t);for(i=0;i<t.clauses.length;i++){var c=t.clauses[i],d=null,u=I.Set.empty;d=c.usePipeline?this.pipeline.runString(c.term,{fields:c.fields}):[c.term];for(var l=0;l<d.length;l++){var p=d[l];c.term=p;var m=I.TokenSet.fromClause(c),g=this.tokenSet.intersect(m).toArray();if(0===g.length&&c.presence===I.Query.presence.REQUIRED){for(var f=0;f<c.fields.length;f++){a[L=c.fields[f]]=I.Set.empty}break}for(var h=0;h<g.length;h++){var b=g[h],y=this.invertedIndex[b],v=y._index;for(f=0;f<c.fields.length;f++){var k=y[L=c.fields[f]],x=Object.keys(k),w=b+"/"+L,_=new I.Set(x);if(c.presence==I.Query.presence.REQUIRED&&(u=u.union(_),void 0===a[L]&&(a[L]=I.Set.complete)),c.presence!=I.Query.presence.PROHIBITED){if(s[L].upsert(v,c.boost,(function(e,t){return e+t})),!o[w]){for(var S=0;S<x.length;S++){var E,C=x[S],T=new I.FieldRef(C,L),A=k[C];void 0===(E=n[T])?n[T]=new I.MatchData(b,L,A):E.add(b,L,A)}o[w]=!0}}else void 0===r[L]&&(r[L]=I.Set.empty),r[L]=r[L].union(_)}}}if(c.presence===I.Query.presence.REQUIRED)for(f=0;f<c.fields.length;f++){a[L=c.fields[f]]=a[L].intersect(u)}}var j=I.Set.complete,P=I.Set.empty;for(i=0;i<this.fields.length;i++){var L;a[L=this.fields[i]]&&(j=j.intersect(a[L])),r[L]&&(P=P.union(r[L]))}var R=Object.keys(n),N=[],O=Object.create(null);if(t.isNegated()){R=Object.keys(this.fieldVectors);for(i=0;i<R.length;i++){T=R[i];var D=I.FieldRef.fromString(T);n[T]=new I.MatchData}}for(i=0;i<R.length;i++){var F=(D=I.FieldRef.fromString(R[i])).docRef;if(j.contains(F)&&!P.contains(F)){var M,z=this.fieldVectors[D],B=s[D.fieldName].similarity(z);if(void 0!==(M=O[F]))M.score+=B,M.matchData.combine(n[D]);else{var $={ref:F,score:B,matchData:n[D]};O[F]=$,N.push($)}}}return N.sort((function(e,t){return t.score-e.score}))},I.Index.prototype.toJSON=function(){var e=Object.keys(this.invertedIndex).sort().map((function(e){return[e,this.invertedIndex[e]]}),this),t=Object.keys(this.fieldVectors).map((function(e){return[e,this.fieldVectors[e].toJSON()]}),this);return{version:I.version,fields:this.fields,fieldVectors:t,invertedIndex:e,pipeline:this.pipeline.toJSON()}},I.Index.load=function(e){var t={},n={},s=e.fieldVectors,o=Object.create(null),a=e.invertedIndex,r=new I.TokenSet.Builder,i=I.Pipeline.load(e.pipeline);e.version!=I.version&&I.utils.warn("Version mismatch when loading serialised index. Current version of lunr '"+I.version+"' does not match serialized index '"+e.version+"'");for(var c=0;c<s.length;c++){var d=(l=s[c])[0],u=l[1];n[d]=new I.Vector(u)}for(c=0;c<a.length;c++){var l,p=(l=a[c])[0],m=l[1];r.insert(p),o[p]=m}return r.finish(),t.fields=e.fields,t.fieldVectors=n,t.invertedIndex=o,t.tokenSet=r.root,t.pipeline=i,new I.Index(t)},I.Builder=function(){this._ref="id",this._fields=Object.create(null),this._documents=Object.create(null),this.invertedIndex=Object.create(null),this.fieldTermFrequencies={},this.fieldLengths={},this.tokenizer=I.tokenizer,this.pipeline=new I.Pipeline,this.searchPipeline=new I.Pipeline,this.documentCount=0,this._b=.75,this._k1=1.2,this.termIndex=0,this.metadataWhitelist=[]},I.Builder.prototype.ref=function(e){this._ref=e},I.Builder.prototype.field=function(e,t){if(/\//.test(e))throw new RangeError("Field '"+e+"' contains illegal character '/'");this._fields[e]=t||{}},I.Builder.prototype.b=function(e){this._b=e<0?0:e>1?1:e},I.Builder.prototype.k1=function(e){this._k1=e},I.Builder.prototype.add=function(e,t){var n=e[this._ref],s=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var o=0;o<s.length;o++){var a=s[o],r=this._fields[a].extractor,i=r?r(e):e[a],c=this.tokenizer(i,{fields:[a]}),d=this.pipeline.run(c),u=new I.FieldRef(n,a),l=Object.create(null);this.fieldTermFrequencies[u]=l,this.fieldLengths[u]=0,this.fieldLengths[u]+=d.length;for(var p=0;p<d.length;p++){var m=d[p];if(null==l[m]&&(l[m]=0),l[m]+=1,null==this.invertedIndex[m]){var g=Object.create(null);g._index=this.termIndex,this.termIndex+=1;for(var f=0;f<s.length;f++)g[s[f]]=Object.create(null);this.invertedIndex[m]=g}null==this.invertedIndex[m][a][n]&&(this.invertedIndex[m][a][n]=Object.create(null));for(var h=0;h<this.metadataWhitelist.length;h++){var b=this.metadataWhitelist[h],y=m.metadata[b];null==this.invertedIndex[m][a][n][b]&&(this.invertedIndex[m][a][n][b]=[]),this.invertedIndex[m][a][n][b].push(y)}}}},I.Builder.prototype.calculateAverageFieldLengths=function(){for(var e=Object.keys(this.fieldLengths),t=e.length,n={},s={},o=0;o<t;o++){var a=I.FieldRef.fromString(e[o]),r=a.fieldName;s[r]||(s[r]=0),s[r]+=1,n[r]||(n[r]=0),n[r]+=this.fieldLengths[a]}var i=Object.keys(this._fields);for(o=0;o<i.length;o++){var c=i[o];n[c]=n[c]/s[c]}this.averageFieldLength=n},I.Builder.prototype.createFieldVectors=function(){for(var e={},t=Object.keys(this.fieldTermFrequencies),n=t.length,s=Object.create(null),o=0;o<n;o++){for(var a=I.FieldRef.fromString(t[o]),r=a.fieldName,i=this.fieldLengths[a],c=new I.Vector,d=this.fieldTermFrequencies[a],u=Object.keys(d),l=u.length,p=this._fields[r].boost||1,m=this._documents[a.docRef].boost||1,g=0;g<l;g++){var f,h,b,y=u[g],v=d[y],k=this.invertedIndex[y]._index;void 0===s[y]?(f=I.idf(this.invertedIndex[y],this.documentCount),s[y]=f):f=s[y],h=f*((this._k1+1)*v)/(this._k1*(1-this._b+this._b*(i/this.averageFieldLength[r]))+v),h*=p,h*=m,b=Math.round(1e3*h)/1e3,c.insert(k,b)}e[a]=c}this.fieldVectors=e},I.Builder.prototype.createTokenSet=function(){this.tokenSet=I.TokenSet.fromArray(Object.keys(this.invertedIndex).sort())},I.Builder.prototype.build=function(){return this.calculateAverageFieldLengths(),this.createFieldVectors(),this.createTokenSet(),new I.Index({invertedIndex:this.invertedIndex,fieldVectors:this.fieldVectors,tokenSet:this.tokenSet,fields:Object.keys(this._fields),pipeline:this.searchPipeline})},I.Builder.prototype.use=function(e){var t=Array.prototype.slice.call(arguments,1);t.unshift(this),e.apply(this,t)},I.MatchData=function(e,t,n){for(var s=Object.create(null),o=Object.keys(n||{}),a=0;a<o.length;a++){var r=o[a];s[r]=n[r].slice()}this.metadata=Object.create(null),void 0!==e&&(this.metadata[e]=Object.create(null),this.metadata[e][t]=s)},I.MatchData.prototype.combine=function(e){for(var t=Object.keys(e.metadata),n=0;n<t.length;n++){var s=t[n],o=Object.keys(e.metadata[s]);null==this.metadata[s]&&(this.metadata[s]=Object.create(null));for(var a=0;a<o.length;a++){var r=o[a],i=Object.keys(e.metadata[s][r]);null==this.metadata[s][r]&&(this.metadata[s][r]=Object.create(null));for(var c=0;c<i.length;c++){var d=i[c];null==this.metadata[s][r][d]?this.metadata[s][r][d]=e.metadata[s][r][d]:this.metadata[s][r][d]=this.metadata[s][r][d].concat(e.metadata[s][r][d])}}}},I.MatchData.prototype.add=function(e,t,n){if(!(e in this.metadata))return this.metadata[e]=Object.create(null),void(this.metadata[e][t]=n);if(t in this.metadata[e])for(var s=Object.keys(n),o=0;o<s.length;o++){var a=s[o];a in this.metadata[e][t]?this.metadata[e][t][a]=this.metadata[e][t][a].concat(n[a]):this.metadata[e][t][a]=n[a]}else this.metadata[e][t]=n},I.Query=function(e){this.clauses=[],this.allFields=e},I.Query.wildcard=new String("*"),I.Query.wildcard.NONE=0,I.Query.wildcard.LEADING=1,I.Query.wildcard.TRAILING=2,I.Query.presence={OPTIONAL:1,REQUIRED:2,PROHIBITED:3},I.Query.prototype.clause=function(e){return"fields"in e||(e.fields=this.allFields),"boost"in e||(e.boost=1),"usePipeline"in e||(e.usePipeline=!0),"wildcard"in e||(e.wildcard=I.Query.wildcard.NONE),e.wildcard&I.Query.wildcard.LEADING&&e.term.charAt(0)!=I.Query.wildcard&&(e.term="*"+e.term),e.wildcard&I.Query.wildcard.TRAILING&&e.term.slice(-1)!=I.Query.wildcard&&(e.term=e.term+"*"),"presence"in e||(e.presence=I.Query.presence.OPTIONAL),this.clauses.push(e),this},I.Query.prototype.isNegated=function(){for(var e=0;e<this.clauses.length;e++)if(this.clauses[e].presence!=I.Query.presence.PROHIBITED)return!1;return!0},I.Query.prototype.term=function(e,t){if(Array.isArray(e))return e.forEach((function(e){this.term(e,I.utils.clone(t))}),this),this;var n=t||{};return n.term=e.toString(),this.clause(n),this},I.QueryParseError=function(e,t,n){this.name="QueryParseError",this.message=e,this.start=t,this.end=n},I.QueryParseError.prototype=new Error,I.QueryLexer=function(e){this.lexemes=[],this.str=e,this.length=e.length,this.pos=0,this.start=0,this.escapeCharPositions=[]},I.QueryLexer.prototype.run=function(){for(var e=I.QueryLexer.lexText;e;)e=e(this)},I.QueryLexer.prototype.sliceString=function(){for(var e=[],t=this.start,n=this.pos,s=0;s<this.escapeCharPositions.length;s++)n=this.escapeCharPositions[s],e.push(this.str.slice(t,n)),t=n+1;return e.push(this.str.slice(t,this.pos)),this.escapeCharPositions.length=0,e.join("")},I.QueryLexer.prototype.emit=function(e){this.lexemes.push({type:e,str:this.sliceString(),start:this.start,end:this.pos}),this.start=this.pos},I.QueryLexer.prototype.escapeCharacter=function(){this.escapeCharPositions.push(this.pos-1),this.pos+=1},I.QueryLexer.prototype.next=function(){if(this.pos>=this.length)return I.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},I.QueryLexer.prototype.width=function(){return this.pos-this.start},I.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},I.QueryLexer.prototype.backup=function(){this.pos-=1},I.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=I.QueryLexer.EOS&&this.backup()},I.QueryLexer.prototype.more=function(){return this.pos<this.length},I.QueryLexer.EOS="EOS",I.QueryLexer.FIELD="FIELD",I.QueryLexer.TERM="TERM",I.QueryLexer.EDIT_DISTANCE="EDIT_DISTANCE",I.QueryLexer.BOOST="BOOST",I.QueryLexer.PRESENCE="PRESENCE",I.QueryLexer.lexField=function(e){return e.backup(),e.emit(I.QueryLexer.FIELD),e.ignore(),I.QueryLexer.lexText},I.QueryLexer.lexTerm=function(e){if(e.width()>1&&(e.backup(),e.emit(I.QueryLexer.TERM)),e.ignore(),e.more())return I.QueryLexer.lexText},I.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(I.QueryLexer.EDIT_DISTANCE),I.QueryLexer.lexText},I.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(I.QueryLexer.BOOST),I.QueryLexer.lexText},I.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(I.QueryLexer.TERM)},I.QueryLexer.termSeparator=I.tokenizer.separator,I.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==I.QueryLexer.EOS)return I.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return I.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(I.QueryLexer.TERM),I.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(I.QueryLexer.TERM),I.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(I.QueryLexer.PRESENCE),I.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(I.QueryLexer.PRESENCE),I.QueryLexer.lexText;if(t.match(I.QueryLexer.termSeparator))return I.QueryLexer.lexTerm}else e.escapeCharacter()}},I.QueryParser=function(e,t){this.lexer=new I.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},I.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=I.QueryParser.parseClause;e;)e=e(this);return this.query},I.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},I.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},I.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},I.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case I.QueryLexer.PRESENCE:return I.QueryParser.parsePresence;case I.QueryLexer.FIELD:return I.QueryParser.parseField;case I.QueryLexer.TERM:return I.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new I.QueryParseError(n,t.start,t.end)}},I.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=I.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=I.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new I.QueryParseError(n,t.start,t.end)}var s=e.peekLexeme();if(null==s){n="expecting term or field, found nothing";throw new I.QueryParseError(n,t.start,t.end)}switch(s.type){case I.QueryLexer.FIELD:return I.QueryParser.parseField;case I.QueryLexer.TERM:return I.QueryParser.parseTerm;default:n="expecting term or field, found '"+s.type+"'";throw new I.QueryParseError(n,s.start,s.end)}}},I.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),s="unrecognised field '"+t.str+"', possible fields: "+n;throw new I.QueryParseError(s,t.start,t.end)}e.currentClause.fields=[t.str];var o=e.peekLexeme();if(null==o){s="expecting term, found nothing";throw new I.QueryParseError(s,t.start,t.end)}if(o.type===I.QueryLexer.TERM)return I.QueryParser.parseTerm;s="expecting term, found '"+o.type+"'";throw new I.QueryParseError(s,o.start,o.end)}},I.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case I.QueryLexer.TERM:return e.nextClause(),I.QueryParser.parseTerm;case I.QueryLexer.FIELD:return e.nextClause(),I.QueryParser.parseField;case I.QueryLexer.EDIT_DISTANCE:return I.QueryParser.parseEditDistance;case I.QueryLexer.BOOST:return I.QueryParser.parseBoost;case I.QueryLexer.PRESENCE:return e.nextClause(),I.QueryParser.parsePresence;default:var s="Unexpected lexeme type '"+n.type+"'";throw new I.QueryParseError(s,n.start,n.end)}else e.nextClause()}},I.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var s="edit distance must be numeric";throw new I.QueryParseError(s,t.start,t.end)}e.currentClause.editDistance=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case I.QueryLexer.TERM:return e.nextClause(),I.QueryParser.parseTerm;case I.QueryLexer.FIELD:return e.nextClause(),I.QueryParser.parseField;case I.QueryLexer.EDIT_DISTANCE:return I.QueryParser.parseEditDistance;case I.QueryLexer.BOOST:return I.QueryParser.parseBoost;case I.QueryLexer.PRESENCE:return e.nextClause(),I.QueryParser.parsePresence;default:s="Unexpected lexeme type '"+o.type+"'";throw new I.QueryParseError(s,o.start,o.end)}else e.nextClause()}},I.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var s="boost must be numeric";throw new I.QueryParseError(s,t.start,t.end)}e.currentClause.boost=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case I.QueryLexer.TERM:return e.nextClause(),I.QueryParser.parseTerm;case I.QueryLexer.FIELD:return e.nextClause(),I.QueryParser.parseField;case I.QueryLexer.EDIT_DISTANCE:return I.QueryParser.parseEditDistance;case I.QueryLexer.BOOST:return I.QueryParser.parseBoost;case I.QueryLexer.PRESENCE:return e.nextClause(),I.QueryParser.parsePresence;default:s="Unexpected lexeme type '"+o.type+"'";throw new I.QueryParseError(s,o.start,o.end)}else e.nextClause()}},void 0===(o="function"==typeof(s=function(){return I})?s.call(t,n,t,e):s)||(e.exports=o)}()},10119:(e,t,n)=>{"use strict";n.r(t)},51043:(e,t,n)=>{"use strict";n.r(t)},5947:function(e,t,n){var s,o;s=function(){var e,t,n={version:"0.2.0"},s=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function o(e,t,n){return e<t?t:e>n?n:e}function a(e){return 100*(-1+e)}function r(e,t,n){var o;return(o="translate3d"===s.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===s.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(s[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,s.minimum,1),n.status=1===e?null:e;var a=n.render(!t),d=a.querySelector(s.barSelector),u=s.speed,l=s.easing;return a.offsetWidth,i((function(t){""===s.positionUsing&&(s.positionUsing=n.getPositioningCSS()),c(d,r(e,u,l)),1===e?(c(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){c(a,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),s.trickleSpeed)};return s.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*s.trickleRate)},e=0,t=0,n.promise=function(s){return s&&"resolved"!==s.state()?(0===t&&n.start(),e++,t++,s.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=s.template;var o,r=t.querySelector(s.barSelector),i=e?"-100":a(n.status||0),d=document.querySelector(s.parent);return c(r,{transition:"all 0 linear",transform:"translate3d("+i+"%,0,0)"}),s.showSpinner||(o=t.querySelector(s.spinnerSelector))&&m(o),d!=document.body&&u(d,"nprogress-custom-parent"),d.appendChild(t),t},n.remove=function(){l(document.documentElement,"nprogress-busy"),l(document.querySelector(s.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&m(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var i=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),c=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function s(t){var n=document.body.style;if(t in n)return t;for(var s,o=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((s=e[o]+a)in n)return s;return t}function o(e){return e=n(e),t[e]||(t[e]=s(e))}function a(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,s,o=arguments;if(2==o.length)for(n in t)void 0!==(s=t[n])&&t.hasOwnProperty(n)&&a(e,n,s);else a(e,o[1],o[2])}}();function d(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),s=n+t;d(n,t)||(e.className=s.substring(1))}function l(e,t){var n,s=p(e);d(e,t)&&(n=s.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function m(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof s?s.call(t,n,t,e):s)||(e.exports=o)},35302:(e,t,n)=>{var s=n(64634);e.exports=g,e.exports.parse=a,e.exports.compile=function(e,t){return c(a(e,t),t)},e.exports.tokensToFunction=c,e.exports.tokensToRegExp=m;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function a(e,t){for(var n,s=[],a=0,i=0,c="",d=t&&t.delimiter||"/";null!=(n=o.exec(e));){var l=n[0],p=n[1],m=n.index;if(c+=e.slice(i,m),i=m+l.length,p)c+=p[1];else{var g=e[i],f=n[2],h=n[3],b=n[4],y=n[5],v=n[6],k=n[7];c&&(s.push(c),c="");var x=null!=f&&null!=g&&g!==f,w="+"===v||"*"===v,_="?"===v||"*"===v,S=f||d,E=b||y,C=f||("string"==typeof s[s.length-1]?s[s.length-1]:"");s.push({name:h||a++,prefix:f||"",delimiter:S,optional:_,repeat:w,partial:x,asterisk:!!k,pattern:E?u(E):k?".*":r(S,C)})}}return i<e.length&&(c+=e.substr(i)),c&&s.push(c),s}function r(e,t){return!t||t.indexOf(e)>-1?"[^"+d(e)+"]+?":d(t)+"|(?:(?!"+d(t)+")[^"+d(e)+"])+?"}function i(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function c(e,t){for(var n=new Array(e.length),o=0;o<e.length;o++)"object"==typeof e[o]&&(n[o]=new RegExp("^(?:"+e[o].pattern+")$",p(t)));return function(t,o){for(var a="",r=t||{},c=(o||{}).pretty?i:encodeURIComponent,d=0;d<e.length;d++){var u=e[d];if("string"!=typeof u){var l,p=r[u.name];if(null==p){if(u.optional){u.partial&&(a+=u.prefix);continue}throw new TypeError('Expected "'+u.name+'" to be defined')}if(s(p)){if(!u.repeat)throw new TypeError('Expected "'+u.name+'" to not repeat, but received `'+JSON.stringify(p)+"`");if(0===p.length){if(u.optional)continue;throw new TypeError('Expected "'+u.name+'" to not be empty')}for(var m=0;m<p.length;m++){if(l=c(p[m]),!n[d].test(l))throw new TypeError('Expected all "'+u.name+'" to match "'+u.pattern+'", but received `'+JSON.stringify(l)+"`");a+=(0===m?u.prefix:u.delimiter)+l}}else{if(l=u.asterisk?encodeURI(p).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):c(p),!n[d].test(l))throw new TypeError('Expected "'+u.name+'" to match "'+u.pattern+'", but received "'+l+'"');a+=u.prefix+l}}else a+=u}return a}}function d(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function u(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function l(e,t){return e.keys=t,e}function p(e){return e&&e.sensitive?"":"i"}function m(e,t,n){s(t)||(n=t||n,t=[]);for(var o=(n=n||{}).strict,a=!1!==n.end,r="",i=0;i<e.length;i++){var c=e[i];if("string"==typeof c)r+=d(c);else{var u=d(c.prefix),m="(?:"+c.pattern+")";t.push(c),c.repeat&&(m+="(?:"+u+m+")*"),r+=m=c.optional?c.partial?u+"("+m+")?":"(?:"+u+"("+m+"))?":u+"("+m+")"}}var g=d(n.delimiter||"/"),f=r.slice(-g.length)===g;return o||(r=(f?r.slice(0,-g.length):r)+"(?:"+g+"(?=$))?"),r+=a?"$":o&&f?"":"(?="+g+"|$)",l(new RegExp("^"+r,p(n)),t)}function g(e,t,n){return s(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var s=0;s<n.length;s++)t.push({name:s,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return l(e,t)}(e,t):s(e)?function(e,t,n){for(var s=[],o=0;o<e.length;o++)s.push(g(e[o],t,n).source);return l(new RegExp("(?:"+s.join("|")+")",p(n)),t)}(e,t,n):function(e,t,n){return m(a(e,n),t,n)}(e,t,n)}},19700:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,s,o,a){if(n.language===s){var r=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof a&&!a(e))return e;for(var o,i=r.length;-1!==n.code.indexOf(o=t(s,i));)++i;return r[i]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,s){if(n.language===s&&n.tokenStack){n.grammar=e.languages[s];var o=0,a=Object.keys(n.tokenStack);!function r(i){for(var c=0;c<i.length&&!(o>=a.length);c++){var d=i[c];if("string"==typeof d||d.content&&"string"==typeof d.content){var u=a[o],l=n.tokenStack[u],p="string"==typeof d?d:d.content,m=t(s,u),g=p.indexOf(m);if(g>-1){++o;var f=p.substring(0,g),h=new e.Token(s,e.tokenize(l,n.grammar),"language-"+s,l),b=p.substring(g+m.length),y=[];f&&y.push.apply(y,r([f])),y.push(h),b&&y.push.apply(y,r([b])),"string"==typeof d?i.splice.apply(i,[c,1].concat(y)):d.content=y}}else d.content&&r(d.content)}return i}(n.tokens)}}}})}(Prism)},30905:()=>{!function(e){var t=e.languages.powershell={comment:[{pattern:/(^|[^`])<#[\s\S]*?#>/,lookbehind:!0},{pattern:/(^|[^`])#.*/,lookbehind:!0}],string:[{pattern:/"(?:`[\s\S]|[^`"])*"/,greedy:!0,inside:null},{pattern:/'(?:[^']|'')*'/,greedy:!0}],namespace:/\[[a-z](?:\[(?:\[[^\]]*\]|[^\[\]])*\]|[^\[\]])*\]/i,boolean:/\$(?:false|true)\b/i,variable:/\$\w+\b/,function:[/\b(?:Add|Approve|Assert|Backup|Block|Checkpoint|Clear|Close|Compare|Complete|Compress|Confirm|Connect|Convert|ConvertFrom|ConvertTo|Copy|Debug|Deny|Disable|Disconnect|Dismount|Edit|Enable|Enter|Exit|Expand|Export|Find|ForEach|Format|Get|Grant|Group|Hide|Import|Initialize|Install|Invoke|Join|Limit|Lock|Measure|Merge|Move|New|Open|Optimize|Out|Ping|Pop|Protect|Publish|Push|Read|Receive|Redo|Register|Remove|Rename|Repair|Request|Reset|Resize|Resolve|Restart|Restore|Resume|Revoke|Save|Search|Select|Send|Set|Show|Skip|Sort|Split|Start|Step|Stop|Submit|Suspend|Switch|Sync|Tee|Test|Trace|Unblock|Undo|Uninstall|Unlock|Unprotect|Unpublish|Unregister|Update|Use|Wait|Watch|Where|Write)-[a-z]+\b/i,/\b(?:ac|cat|chdir|clc|cli|clp|clv|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|ebp|echo|epal|epcsv|epsn|erase|fc|fl|ft|fw|gal|gbp|gc|gci|gcs|gdr|gi|gl|gm|gp|gps|group|gsv|gu|gv|gwmi|iex|ii|ipal|ipcsv|ipsn|irm|iwmi|iwr|kill|lp|ls|measure|mi|mount|move|mp|mv|nal|ndr|ni|nv|ogv|popd|ps|pushd|pwd|rbp|rd|rdr|ren|ri|rm|rmdir|rni|rnp|rp|rv|rvpa|rwmi|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spps|spsv|start|sv|swmi|tee|trcm|type|write)\b/i],keyword:/\b(?:Begin|Break|Catch|Class|Continue|Data|Define|Do|DynamicParam|Else|ElseIf|End|Exit|Filter|Finally|For|ForEach|From|Function|If|InlineScript|Parallel|Param|Process|Return|Sequence|Switch|Throw|Trap|Try|Until|Using|Var|While|Workflow)\b/i,operator:{pattern:/(^|\W)(?:!|-(?:b?(?:and|x?or)|as|(?:Not)?(?:Contains|In|Like|Match)|eq|ge|gt|is(?:Not)?|Join|le|lt|ne|not|Replace|sh[lr])\b|-[-=]?|\+[+=]?|[*\/%]=?)/i,lookbehind:!0},punctuation:/[|{}[\];(),.]/};t.string[0].inside={function:{pattern:/(^|[^`])\$\((?:\$\([^\r\n()]*\)|(?!\$\()[^\r\n)])*\)/,lookbehind:!0,inside:t},boolean:t.boolean,variable:t.variable}}(Prism)},41648:()=>{!function(e){e.languages.ruby=e.languages.extend("clike",{comment:{pattern:/#.*|^=begin\s[\s\S]*?^=end/m,greedy:!0},"class-name":{pattern:/(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,operator:/\.{2,3}|&\.|===|<?=>|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),e.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var t={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:e.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete e.languages.ruby.function;var n="(?:"+[/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,/\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,/<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source].join("|")+")",s=/(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;e.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp(/%r/.source+n+/[egimnosux]{0,6}/.source),greedy:!0,inside:{interpolation:t,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:t,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp(/(^|[^:]):/.source+s),lookbehind:!0,greedy:!0},{pattern:RegExp(/([\r\n{(,][ \t]*)/.source+s+/(?=:(?!:))/.source),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),e.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp(/%[qQiIwWs]?/.source+n),greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:t,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp(/%x/.source+n),greedy:!0,inside:{interpolation:t,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:t,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete e.languages.ruby.string,e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),e.languages.rb=e.languages.ruby}(Prism)},75430:(e,t,n)=>{var s={"./prism-powershell":30905,"./prism-ruby":41648};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(s,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return s[e]}o.keys=function(){return Object.keys(s)},o.resolve=a,e.exports=o,o.id=75430},2694:(e,t,n)=>{"use strict";var s=n(6925);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,r){if(r!==s){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},5556:(e,t,n)=>{e.exports=n(2694)()},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},22551:(e,t,n)=>{"use strict";var s=n(96540),o=n(69982);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var r=new Set,i={};function c(e,t){d(e,t),d(e+"Capture",t)}function d(e,t){for(i[e]=t,e=0;e<t.length;e++)r.add(t[e])}var u=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),l=Object.prototype.hasOwnProperty,p=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,m={},g={};function f(e,t,n,s,o,a,r){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=s,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=a,this.removeEmptyString=r}var h={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){h[e]=new f(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];h[t]=new f(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){h[e]=new f(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){h[e]=new f(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){h[e]=new f(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){h[e]=new f(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){h[e]=new f(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){h[e]=new f(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){h[e]=new f(e,5,!1,e.toLowerCase(),null,!1,!1)}));var b=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function v(e,t,n,s){var o=h.hasOwnProperty(t)?h[t]:null;(null!==o?0!==o.type:s||!(2<t.length)||"o"!==t[0]&&"O"!==t[0]||"n"!==t[1]&&"N"!==t[1])&&(function(e,t,n,s){if(null==t||function(e,t,n,s){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!s&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,s))return!0;if(s)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,o,s)&&(n=null),s||null===o?function(e){return!!l.call(g,e)||!l.call(m,e)&&(p.test(e)?g[e]=!0:(m[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):o.mustUseProperty?e[o.propertyName]=null===n?3!==o.type&&"":n:(t=o.attributeName,s=o.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(o=o.type)||4===o&&!0===n?"":""+n,s?e.setAttributeNS(s,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(b,y);h[t]=new f(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(b,y);h[t]=new f(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(b,y);h[t]=new f(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){h[e]=new f(e,1,!1,e.toLowerCase(),null,!1,!1)})),h.xlinkHref=new f("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){h[e]=new f(e,1,!1,e.toLowerCase(),null,!0,!0)}));var k=s.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,x=Symbol.for("react.element"),w=Symbol.for("react.portal"),_=Symbol.for("react.fragment"),S=Symbol.for("react.strict_mode"),E=Symbol.for("react.profiler"),C=Symbol.for("react.provider"),T=Symbol.for("react.context"),A=Symbol.for("react.forward_ref"),j=Symbol.for("react.suspense"),P=Symbol.for("react.suspense_list"),L=Symbol.for("react.memo"),R=Symbol.for("react.lazy");Symbol.for("react.scope"),Symbol.for("react.debug_trace_mode");var N=Symbol.for("react.offscreen");Symbol.for("react.legacy_hidden"),Symbol.for("react.cache"),Symbol.for("react.tracing_marker");var O=Symbol.iterator;function I(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=O&&e[O]||e["@@iterator"])?e:null}var D,F=Object.assign;function M(e){if(void 0===D)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);D=t&&t[1]||""}return"\n"+D+e}var z=!1;function B(e,t){if(!e||z)return"";z=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(d){var s=d}Reflect.construct(e,[],t)}else{try{t.call()}catch(d){s=d}e.call(t.prototype)}else{try{throw Error()}catch(d){s=d}e()}}catch(d){if(d&&s&&"string"==typeof d.stack){for(var o=d.stack.split("\n"),a=s.stack.split("\n"),r=o.length-1,i=a.length-1;1<=r&&0<=i&&o[r]!==a[i];)i--;for(;1<=r&&0<=i;r--,i--)if(o[r]!==a[i]){if(1!==r||1!==i)do{if(r--,0>--i||o[r]!==a[i]){var c="\n"+o[r].replace(" at new "," at ");return e.displayName&&c.includes("<anonymous>")&&(c=c.replace("<anonymous>",e.displayName)),c}}while(1<=r&&0<=i);break}}}finally{z=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?M(e):""}function $(e){switch(e.tag){case 5:return M(e.type);case 16:return M("Lazy");case 13:return M("Suspense");case 19:return M("SuspenseList");case 0:case 2:case 15:return e=B(e.type,!1);case 11:return e=B(e.type.render,!1);case 1:return e=B(e.type,!0);default:return""}}function U(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case _:return"Fragment";case w:return"Portal";case E:return"Profiler";case S:return"StrictMode";case j:return"Suspense";case P:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case T:return(e.displayName||"Context")+".Consumer";case C:return(e._context.displayName||"Context")+".Provider";case A:var t=e.render;return(e=e.displayName)||(e=""!==(e=t.displayName||t.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case L:return null!==(t=e.displayName||null)?t:U(e.type)||"Memo";case R:t=e._payload,e=e._init;try{return U(e(t))}catch(n){}}return null}function q(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=(e=t.render).displayName||e.name||"",t.displayName||(""!==e?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return U(t);case 8:return t===S?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"==typeof t)return t.displayName||t.name||null;if("string"==typeof t)return t}return null}function Q(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":case"object":return e;default:return""}}function V(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function H(e){e._valueTracker||(e._valueTracker=function(e){var t=V(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),s=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var o=n.get,a=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(e){s=""+e,a.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return s},setValue:function(e){s=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function W(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),s="";return e&&(s=V(e)?e.checked?"true":"false":e.value),(e=s)!==n&&(t.setValue(e),!0)}function G(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function X(e,t){var n=t.checked;return F({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function K(e,t){var n=null==t.defaultValue?"":t.defaultValue,s=null!=t.checked?t.checked:t.defaultChecked;n=Q(null!=t.value?t.value:n),e._wrapperState={initialChecked:s,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function Z(e,t){null!=(t=t.checked)&&v(e,"checked",t,!1)}function Y(e,t){Z(e,t);var n=Q(t.value),s=t.type;if(null!=n)"number"===s?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===s||"reset"===s)return void e.removeAttribute("value");t.hasOwnProperty("value")?ee(e,t.type,n):t.hasOwnProperty("defaultValue")&&ee(e,t.type,Q(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function J(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var s=t.type;if(!("submit"!==s&&"reset"!==s||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function ee(e,t,n){"number"===t&&G(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var te=Array.isArray;function ne(e,t,n,s){if(e=e.options,t){t={};for(var o=0;o<n.length;o++)t["$"+n[o]]=!0;for(n=0;n<e.length;n++)o=t.hasOwnProperty("$"+e[n].value),e[n].selected!==o&&(e[n].selected=o),o&&s&&(e[n].defaultSelected=!0)}else{for(n=""+Q(n),t=null,o=0;o<e.length;o++){if(e[o].value===n)return e[o].selected=!0,void(s&&(e[o].defaultSelected=!0));null!==t||e[o].disabled||(t=e[o])}null!==t&&(t.selected=!0)}}function se(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(a(91));return F({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function oe(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(a(92));if(te(n)){if(1<n.length)throw Error(a(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:Q(n)}}function ae(e,t){var n=Q(t.value),s=Q(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=s&&(e.defaultValue=""+s)}function re(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}function ie(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function ce(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?ie(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var de,ue,le=(ue=function(e,t){if("http://www.w3.org/2000/svg"!==e.namespaceURI||"innerHTML"in e)e.innerHTML=t;else{for((de=de||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=de.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,s){MSApp.execUnsafeLocalFunction((function(){return ue(e,t)}))}:ue);function pe(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var me={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ge=["Webkit","ms","Moz","O"];function fe(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||me.hasOwnProperty(e)&&me[e]?(""+t).trim():t+"px"}function he(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var s=0===n.indexOf("--"),o=fe(n,t[n],s);"float"===n&&(n="cssFloat"),s?e.setProperty(n,o):e[n]=o}}Object.keys(me).forEach((function(e){ge.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),me[t]=me[e]}))}));var be=F({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ye(e,t){if(t){if(be[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(a(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(a(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(a(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(a(62))}}function ve(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var ke=null;function xe(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var we=null,_e=null,Se=null;function Ee(e){if(e=ko(e)){if("function"!=typeof we)throw Error(a(280));var t=e.stateNode;t&&(t=wo(t),we(e.stateNode,e.type,t))}}function Ce(e){_e?Se?Se.push(e):Se=[e]:_e=e}function Te(){if(_e){var e=_e,t=Se;if(Se=_e=null,Ee(e),t)for(e=0;e<t.length;e++)Ee(t[e])}}function Ae(e,t){return e(t)}function je(){}var Pe=!1;function Le(e,t,n){if(Pe)return e(t,n);Pe=!0;try{return Ae(e,t,n)}finally{Pe=!1,(null!==_e||null!==Se)&&(je(),Te())}}function Re(e,t){var n=e.stateNode;if(null===n)return null;var s=wo(n);if(null===s)return null;n=s[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(s=!s.disabled)||(s=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!s;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(a(231,t,typeof n));return n}var Ne=!1;if(u)try{var Oe={};Object.defineProperty(Oe,"passive",{get:function(){Ne=!0}}),window.addEventListener("test",Oe,Oe),window.removeEventListener("test",Oe,Oe)}catch(ue){Ne=!1}function Ie(e,t,n,s,o,a,r,i,c){var d=Array.prototype.slice.call(arguments,3);try{t.apply(n,d)}catch(u){this.onError(u)}}var De=!1,Fe=null,Me=!1,ze=null,Be={onError:function(e){De=!0,Fe=e}};function $e(e,t,n,s,o,a,r,i,c){De=!1,Fe=null,Ie.apply(Be,arguments)}function Ue(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{!!(4098&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function qe(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function Qe(e){if(Ue(e)!==e)throw Error(a(188))}function Ve(e){return null!==(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ue(e)))throw Error(a(188));return t!==e?null:e}for(var n=e,s=t;;){var o=n.return;if(null===o)break;var r=o.alternate;if(null===r){if(null!==(s=o.return)){n=s;continue}break}if(o.child===r.child){for(r=o.child;r;){if(r===n)return Qe(o),e;if(r===s)return Qe(o),t;r=r.sibling}throw Error(a(188))}if(n.return!==s.return)n=o,s=r;else{for(var i=!1,c=o.child;c;){if(c===n){i=!0,n=o,s=r;break}if(c===s){i=!0,s=o,n=r;break}c=c.sibling}if(!i){for(c=r.child;c;){if(c===n){i=!0,n=r,s=o;break}if(c===s){i=!0,s=r,n=o;break}c=c.sibling}if(!i)throw Error(a(189))}}if(n.alternate!==s)throw Error(a(190))}if(3!==n.tag)throw Error(a(188));return n.stateNode.current===n?e:t}(e))?He(e):null}function He(e){if(5===e.tag||6===e.tag)return e;for(e=e.child;null!==e;){var t=He(e);if(null!==t)return t;e=e.sibling}return null}var We=o.unstable_scheduleCallback,Ge=o.unstable_cancelCallback,Xe=o.unstable_shouldYield,Ke=o.unstable_requestPaint,Ze=o.unstable_now,Ye=o.unstable_getCurrentPriorityLevel,Je=o.unstable_ImmediatePriority,et=o.unstable_UserBlockingPriority,tt=o.unstable_NormalPriority,nt=o.unstable_LowPriority,st=o.unstable_IdlePriority,ot=null,at=null;var rt=Math.clz32?Math.clz32:function(e){return e>>>=0,0===e?32:31-(it(e)/ct|0)|0},it=Math.log,ct=Math.LN2;var dt=64,ut=4194304;function lt(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return 4194240&e;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return 130023424&e;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function pt(e,t){var n=e.pendingLanes;if(0===n)return 0;var s=0,o=e.suspendedLanes,a=e.pingedLanes,r=268435455&n;if(0!==r){var i=r&~o;0!==i?s=lt(i):0!==(a&=r)&&(s=lt(a))}else 0!==(r=n&~o)?s=lt(r):0!==a&&(s=lt(a));if(0===s)return 0;if(0!==t&&t!==s&&!(t&o)&&((o=s&-s)>=(a=t&-t)||16===o&&4194240&a))return t;if(4&s&&(s|=16&n),0!==(t=e.entangledLanes))for(e=e.entanglements,t&=s;0<t;)o=1<<(n=31-rt(t)),s|=e[n],t&=~o;return s}function mt(e,t){switch(e){case 1:case 2:case 4:return t+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;default:return-1}}function gt(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function ft(){var e=dt;return!(4194240&(dt<<=1))&&(dt=64),e}function ht(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function bt(e,t,n){e.pendingLanes|=t,536870912!==t&&(e.suspendedLanes=0,e.pingedLanes=0),(e=e.eventTimes)[t=31-rt(t)]=n}function yt(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var s=31-rt(n),o=1<<s;o&t|e[s]&t&&(e[s]|=t),n&=~o}}var vt=0;function kt(e){return 1<(e&=-e)?4<e?268435455&e?16:536870912:4:1}var xt,wt,_t,St,Et,Ct=!1,Tt=[],At=null,jt=null,Pt=null,Lt=new Map,Rt=new Map,Nt=[],Ot="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function It(e,t){switch(e){case"focusin":case"focusout":At=null;break;case"dragenter":case"dragleave":jt=null;break;case"mouseover":case"mouseout":Pt=null;break;case"pointerover":case"pointerout":Lt.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":Rt.delete(t.pointerId)}}function Dt(e,t,n,s,o,a){return null===e||e.nativeEvent!==a?(e={blockedOn:t,domEventName:n,eventSystemFlags:s,nativeEvent:a,targetContainers:[o]},null!==t&&(null!==(t=ko(t))&&wt(t)),e):(e.eventSystemFlags|=s,t=e.targetContainers,null!==o&&-1===t.indexOf(o)&&t.push(o),e)}function Ft(e){var t=vo(e.target);if(null!==t){var n=Ue(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=qe(n)))return e.blockedOn=t,void Et(e.priority,(function(){_t(n)}))}else if(3===t&&n.stateNode.current.memoizedState.isDehydrated)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function Mt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Xt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=ko(n))&&wt(t),e.blockedOn=n,!1;var s=new(n=e.nativeEvent).constructor(n.type,n);ke=s,n.target.dispatchEvent(s),ke=null,t.shift()}return!0}function zt(e,t,n){Mt(e)&&n.delete(t)}function Bt(){Ct=!1,null!==At&&Mt(At)&&(At=null),null!==jt&&Mt(jt)&&(jt=null),null!==Pt&&Mt(Pt)&&(Pt=null),Lt.forEach(zt),Rt.forEach(zt)}function $t(e,t){e.blockedOn===t&&(e.blockedOn=null,Ct||(Ct=!0,o.unstable_scheduleCallback(o.unstable_NormalPriority,Bt)))}function Ut(e){function t(t){return $t(t,e)}if(0<Tt.length){$t(Tt[0],e);for(var n=1;n<Tt.length;n++){var s=Tt[n];s.blockedOn===e&&(s.blockedOn=null)}}for(null!==At&&$t(At,e),null!==jt&&$t(jt,e),null!==Pt&&$t(Pt,e),Lt.forEach(t),Rt.forEach(t),n=0;n<Nt.length;n++)(s=Nt[n]).blockedOn===e&&(s.blockedOn=null);for(;0<Nt.length&&null===(n=Nt[0]).blockedOn;)Ft(n),null===n.blockedOn&&Nt.shift()}var qt=k.ReactCurrentBatchConfig,Qt=!0;function Vt(e,t,n,s){var o=vt,a=qt.transition;qt.transition=null;try{vt=1,Wt(e,t,n,s)}finally{vt=o,qt.transition=a}}function Ht(e,t,n,s){var o=vt,a=qt.transition;qt.transition=null;try{vt=4,Wt(e,t,n,s)}finally{vt=o,qt.transition=a}}function Wt(e,t,n,s){if(Qt){var o=Xt(e,t,n,s);if(null===o)Qs(e,t,s,Gt,n),It(e,s);else if(function(e,t,n,s,o){switch(t){case"focusin":return At=Dt(At,e,t,n,s,o),!0;case"dragenter":return jt=Dt(jt,e,t,n,s,o),!0;case"mouseover":return Pt=Dt(Pt,e,t,n,s,o),!0;case"pointerover":var a=o.pointerId;return Lt.set(a,Dt(Lt.get(a)||null,e,t,n,s,o)),!0;case"gotpointercapture":return a=o.pointerId,Rt.set(a,Dt(Rt.get(a)||null,e,t,n,s,o)),!0}return!1}(o,e,t,n,s))s.stopPropagation();else if(It(e,s),4&t&&-1<Ot.indexOf(e)){for(;null!==o;){var a=ko(o);if(null!==a&&xt(a),null===(a=Xt(e,t,n,s))&&Qs(e,t,s,Gt,n),a===o)break;o=a}null!==o&&s.stopPropagation()}else Qs(e,t,s,null,n)}}var Gt=null;function Xt(e,t,n,s){if(Gt=null,null!==(e=vo(e=xe(s))))if(null===(t=Ue(e)))e=null;else if(13===(n=t.tag)){if(null!==(e=qe(t)))return e;e=null}else if(3===n){if(t.stateNode.current.memoizedState.isDehydrated)return 3===t.tag?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null);return Gt=e,null}function Kt(e){switch(e){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch(Ye()){case Je:return 1;case et:return 4;case tt:case nt:return 16;case st:return 536870912;default:return 16}default:return 16}}var Zt=null,Yt=null,Jt=null;function en(){if(Jt)return Jt;var e,t,n=Yt,s=n.length,o="value"in Zt?Zt.value:Zt.textContent,a=o.length;for(e=0;e<s&&n[e]===o[e];e++);var r=s-e;for(t=1;t<=r&&n[s-t]===o[a-t];t++);return Jt=o.slice(e,1<t?1-t:void 0)}function tn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function nn(){return!0}function sn(){return!1}function on(e){function t(t,n,s,o,a){for(var r in this._reactName=t,this._targetInst=s,this.type=n,this.nativeEvent=o,this.target=a,this.currentTarget=null,e)e.hasOwnProperty(r)&&(t=e[r],this[r]=t?t(o):o[r]);return this.isDefaultPrevented=(null!=o.defaultPrevented?o.defaultPrevented:!1===o.returnValue)?nn:sn,this.isPropagationStopped=sn,this}return F(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=nn)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=nn)},persist:function(){},isPersistent:nn}),t}var an,rn,cn,dn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},un=on(dn),ln=F({},dn,{view:0,detail:0}),pn=on(ln),mn=F({},ln,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:En,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==cn&&(cn&&"mousemove"===e.type?(an=e.screenX-cn.screenX,rn=e.screenY-cn.screenY):rn=an=0,cn=e),an)},movementY:function(e){return"movementY"in e?e.movementY:rn}}),gn=on(mn),fn=on(F({},mn,{dataTransfer:0})),hn=on(F({},ln,{relatedTarget:0})),bn=on(F({},dn,{animationName:0,elapsedTime:0,pseudoElement:0})),yn=F({},dn,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),vn=on(yn),kn=on(F({},dn,{data:0})),xn={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},wn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},_n={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Sn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=_n[e])&&!!t[e]}function En(){return Sn}var Cn=F({},ln,{key:function(e){if(e.key){var t=xn[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=tn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?wn[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:En,charCode:function(e){return"keypress"===e.type?tn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?tn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),Tn=on(Cn),An=on(F({},mn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),jn=on(F({},ln,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:En})),Pn=on(F({},dn,{propertyName:0,elapsedTime:0,pseudoElement:0})),Ln=F({},mn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Rn=on(Ln),Nn=[9,13,27,32],On=u&&"CompositionEvent"in window,In=null;u&&"documentMode"in document&&(In=document.documentMode);var Dn=u&&"TextEvent"in window&&!In,Fn=u&&(!On||In&&8<In&&11>=In),Mn=String.fromCharCode(32),zn=!1;function Bn(e,t){switch(e){case"keyup":return-1!==Nn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function $n(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var Un=!1;var qn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Qn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!qn[e.type]:"textarea"===t}function Vn(e,t,n,s){Ce(s),0<(t=Hs(t,"onChange")).length&&(n=new un("onChange","change",null,n,s),e.push({event:n,listeners:t}))}var Hn=null,Wn=null;function Gn(e){Ms(e,0)}function Xn(e){if(W(xo(e)))return e}function Kn(e,t){if("change"===e)return t}var Zn=!1;if(u){var Yn;if(u){var Jn="oninput"in document;if(!Jn){var es=document.createElement("div");es.setAttribute("oninput","return;"),Jn="function"==typeof es.oninput}Yn=Jn}else Yn=!1;Zn=Yn&&(!document.documentMode||9<document.documentMode)}function ts(){Hn&&(Hn.detachEvent("onpropertychange",ns),Wn=Hn=null)}function ns(e){if("value"===e.propertyName&&Xn(Wn)){var t=[];Vn(t,Wn,e,xe(e)),Le(Gn,t)}}function ss(e,t,n){"focusin"===e?(ts(),Wn=n,(Hn=t).attachEvent("onpropertychange",ns)):"focusout"===e&&ts()}function os(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Xn(Wn)}function as(e,t){if("click"===e)return Xn(t)}function rs(e,t){if("input"===e||"change"===e)return Xn(t)}var is="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t};function cs(e,t){if(is(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),s=Object.keys(t);if(n.length!==s.length)return!1;for(s=0;s<n.length;s++){var o=n[s];if(!l.call(t,o)||!is(e[o],t[o]))return!1}return!0}function ds(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function us(e,t){var n,s=ds(e);for(e=0;s;){if(3===s.nodeType){if(n=e+s.textContent.length,e<=t&&n>=t)return{node:s,offset:t-e};e=n}e:{for(;s;){if(s.nextSibling){s=s.nextSibling;break e}s=s.parentNode}s=void 0}s=ds(s)}}function ls(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?ls(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function ps(){for(var e=window,t=G();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(s){n=!1}if(!n)break;t=G((e=t.contentWindow).document)}return t}function ms(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}function gs(e){var t=ps(),n=e.focusedElem,s=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&ls(n.ownerDocument.documentElement,n)){if(null!==s&&ms(n))if(t=s.start,void 0===(e=s.end)&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if((e=(t=n.ownerDocument||document)&&t.defaultView||window).getSelection){e=e.getSelection();var o=n.textContent.length,a=Math.min(s.start,o);s=void 0===s.end?a:Math.min(s.end,o),!e.extend&&a>s&&(o=s,s=a,a=o),o=us(n,a);var r=us(n,s);o&&r&&(1!==e.rangeCount||e.anchorNode!==o.node||e.anchorOffset!==o.offset||e.focusNode!==r.node||e.focusOffset!==r.offset)&&((t=t.createRange()).setStart(o.node,o.offset),e.removeAllRanges(),a>s?(e.addRange(t),e.extend(r.node,r.offset)):(t.setEnd(r.node,r.offset),e.addRange(t)))}for(t=[],e=n;e=e.parentNode;)1===e.nodeType&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for("function"==typeof n.focus&&n.focus(),n=0;n<t.length;n++)(e=t[n]).element.scrollLeft=e.left,e.element.scrollTop=e.top}}var fs=u&&"documentMode"in document&&11>=document.documentMode,hs=null,bs=null,ys=null,vs=!1;function ks(e,t,n){var s=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;vs||null==hs||hs!==G(s)||("selectionStart"in(s=hs)&&ms(s)?s={start:s.selectionStart,end:s.selectionEnd}:s={anchorNode:(s=(s.ownerDocument&&s.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:s.anchorOffset,focusNode:s.focusNode,focusOffset:s.focusOffset},ys&&cs(ys,s)||(ys=s,0<(s=Hs(bs,"onSelect")).length&&(t=new un("onSelect","select",null,t,n),e.push({event:t,listeners:s}),t.target=hs)))}function xs(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var ws={animationend:xs("Animation","AnimationEnd"),animationiteration:xs("Animation","AnimationIteration"),animationstart:xs("Animation","AnimationStart"),transitionend:xs("Transition","TransitionEnd")},_s={},Ss={};function Es(e){if(_s[e])return _s[e];if(!ws[e])return e;var t,n=ws[e];for(t in n)if(n.hasOwnProperty(t)&&t in Ss)return _s[e]=n[t];return e}u&&(Ss=document.createElement("div").style,"AnimationEvent"in window||(delete ws.animationend.animation,delete ws.animationiteration.animation,delete ws.animationstart.animation),"TransitionEvent"in window||delete ws.transitionend.transition);var Cs=Es("animationend"),Ts=Es("animationiteration"),As=Es("animationstart"),js=Es("transitionend"),Ps=new Map,Ls="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Rs(e,t){Ps.set(e,t),c(t,[e])}for(var Ns=0;Ns<Ls.length;Ns++){var Os=Ls[Ns];Rs(Os.toLowerCase(),"on"+(Os[0].toUpperCase()+Os.slice(1)))}Rs(Cs,"onAnimationEnd"),Rs(Ts,"onAnimationIteration"),Rs(As,"onAnimationStart"),Rs("dblclick","onDoubleClick"),Rs("focusin","onFocus"),Rs("focusout","onBlur"),Rs(js,"onTransitionEnd"),d("onMouseEnter",["mouseout","mouseover"]),d("onMouseLeave",["mouseout","mouseover"]),d("onPointerEnter",["pointerout","pointerover"]),d("onPointerLeave",["pointerout","pointerover"]),c("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),c("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),c("onBeforeInput",["compositionend","keypress","textInput","paste"]),c("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Is="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Ds=new Set("cancel close invalid load scroll toggle".split(" ").concat(Is));function Fs(e,t,n){var s=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,s,o,r,i,c,d){if($e.apply(this,arguments),De){if(!De)throw Error(a(198));var u=Fe;De=!1,Fe=null,Me||(Me=!0,ze=u)}}(s,t,void 0,e),e.currentTarget=null}function Ms(e,t){t=!!(4&t);for(var n=0;n<e.length;n++){var s=e[n],o=s.event;s=s.listeners;e:{var a=void 0;if(t)for(var r=s.length-1;0<=r;r--){var i=s[r],c=i.instance,d=i.currentTarget;if(i=i.listener,c!==a&&o.isPropagationStopped())break e;Fs(o,i,d),a=c}else for(r=0;r<s.length;r++){if(c=(i=s[r]).instance,d=i.currentTarget,i=i.listener,c!==a&&o.isPropagationStopped())break e;Fs(o,i,d),a=c}}}if(Me)throw e=ze,Me=!1,ze=null,e}function zs(e,t){var n=t[ho];void 0===n&&(n=t[ho]=new Set);var s=e+"__bubble";n.has(s)||(qs(t,e,2,!1),n.add(s))}function Bs(e,t,n){var s=0;t&&(s|=4),qs(n,e,s,t)}var $s="_reactListening"+Math.random().toString(36).slice(2);function Us(e){if(!e[$s]){e[$s]=!0,r.forEach((function(t){"selectionchange"!==t&&(Ds.has(t)||Bs(t,!1,e),Bs(t,!0,e))}));var t=9===e.nodeType?e:e.ownerDocument;null===t||t[$s]||(t[$s]=!0,Bs("selectionchange",!1,t))}}function qs(e,t,n,s){switch(Kt(t)){case 1:var o=Vt;break;case 4:o=Ht;break;default:o=Wt}n=o.bind(null,t,n,e),o=void 0,!Ne||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(o=!0),s?void 0!==o?e.addEventListener(t,n,{capture:!0,passive:o}):e.addEventListener(t,n,!0):void 0!==o?e.addEventListener(t,n,{passive:o}):e.addEventListener(t,n,!1)}function Qs(e,t,n,s,o){var a=s;if(!(1&t||2&t||null===s))e:for(;;){if(null===s)return;var r=s.tag;if(3===r||4===r){var i=s.stateNode.containerInfo;if(i===o||8===i.nodeType&&i.parentNode===o)break;if(4===r)for(r=s.return;null!==r;){var c=r.tag;if((3===c||4===c)&&((c=r.stateNode.containerInfo)===o||8===c.nodeType&&c.parentNode===o))return;r=r.return}for(;null!==i;){if(null===(r=vo(i)))return;if(5===(c=r.tag)||6===c){s=a=r;continue e}i=i.parentNode}}s=s.return}Le((function(){var s=a,o=xe(n),r=[];e:{var i=Ps.get(e);if(void 0!==i){var c=un,d=e;switch(e){case"keypress":if(0===tn(n))break e;case"keydown":case"keyup":c=Tn;break;case"focusin":d="focus",c=hn;break;case"focusout":d="blur",c=hn;break;case"beforeblur":case"afterblur":c=hn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":c=gn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":c=fn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":c=jn;break;case Cs:case Ts:case As:c=bn;break;case js:c=Pn;break;case"scroll":c=pn;break;case"wheel":c=Rn;break;case"copy":case"cut":case"paste":c=vn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":c=An}var u=!!(4&t),l=!u&&"scroll"===e,p=u?null!==i?i+"Capture":null:i;u=[];for(var m,g=s;null!==g;){var f=(m=g).stateNode;if(5===m.tag&&null!==f&&(m=f,null!==p&&(null!=(f=Re(g,p))&&u.push(Vs(g,f,m)))),l)break;g=g.return}0<u.length&&(i=new c(i,d,null,n,o),r.push({event:i,listeners:u}))}}if(!(7&t)){if(c="mouseout"===e||"pointerout"===e,(!(i="mouseover"===e||"pointerover"===e)||n===ke||!(d=n.relatedTarget||n.fromElement)||!vo(d)&&!d[fo])&&(c||i)&&(i=o.window===o?o:(i=o.ownerDocument)?i.defaultView||i.parentWindow:window,c?(c=s,null!==(d=(d=n.relatedTarget||n.toElement)?vo(d):null)&&(d!==(l=Ue(d))||5!==d.tag&&6!==d.tag)&&(d=null)):(c=null,d=s),c!==d)){if(u=gn,f="onMouseLeave",p="onMouseEnter",g="mouse","pointerout"!==e&&"pointerover"!==e||(u=An,f="onPointerLeave",p="onPointerEnter",g="pointer"),l=null==c?i:xo(c),m=null==d?i:xo(d),(i=new u(f,g+"leave",c,n,o)).target=l,i.relatedTarget=m,f=null,vo(o)===s&&((u=new u(p,g+"enter",d,n,o)).target=m,u.relatedTarget=l,f=u),l=f,c&&d)e:{for(p=d,g=0,m=u=c;m;m=Ws(m))g++;for(m=0,f=p;f;f=Ws(f))m++;for(;0<g-m;)u=Ws(u),g--;for(;0<m-g;)p=Ws(p),m--;for(;g--;){if(u===p||null!==p&&u===p.alternate)break e;u=Ws(u),p=Ws(p)}u=null}else u=null;null!==c&&Gs(r,i,c,u,!1),null!==d&&null!==l&&Gs(r,l,d,u,!0)}if("select"===(c=(i=s?xo(s):window).nodeName&&i.nodeName.toLowerCase())||"input"===c&&"file"===i.type)var h=Kn;else if(Qn(i))if(Zn)h=rs;else{h=os;var b=ss}else(c=i.nodeName)&&"input"===c.toLowerCase()&&("checkbox"===i.type||"radio"===i.type)&&(h=as);switch(h&&(h=h(e,s))?Vn(r,h,n,o):(b&&b(e,i,s),"focusout"===e&&(b=i._wrapperState)&&b.controlled&&"number"===i.type&&ee(i,"number",i.value)),b=s?xo(s):window,e){case"focusin":(Qn(b)||"true"===b.contentEditable)&&(hs=b,bs=s,ys=null);break;case"focusout":ys=bs=hs=null;break;case"mousedown":vs=!0;break;case"contextmenu":case"mouseup":case"dragend":vs=!1,ks(r,n,o);break;case"selectionchange":if(fs)break;case"keydown":case"keyup":ks(r,n,o)}var y;if(On)e:{switch(e){case"compositionstart":var v="onCompositionStart";break e;case"compositionend":v="onCompositionEnd";break e;case"compositionupdate":v="onCompositionUpdate";break e}v=void 0}else Un?Bn(e,n)&&(v="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(v="onCompositionStart");v&&(Fn&&"ko"!==n.locale&&(Un||"onCompositionStart"!==v?"onCompositionEnd"===v&&Un&&(y=en()):(Yt="value"in(Zt=o)?Zt.value:Zt.textContent,Un=!0)),0<(b=Hs(s,v)).length&&(v=new kn(v,e,null,n,o),r.push({event:v,listeners:b}),y?v.data=y:null!==(y=$n(n))&&(v.data=y))),(y=Dn?function(e,t){switch(e){case"compositionend":return $n(t);case"keypress":return 32!==t.which?null:(zn=!0,Mn);case"textInput":return(e=t.data)===Mn&&zn?null:e;default:return null}}(e,n):function(e,t){if(Un)return"compositionend"===e||!On&&Bn(e,t)?(e=en(),Jt=Yt=Zt=null,Un=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return Fn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(s=Hs(s,"onBeforeInput")).length&&(o=new kn("onBeforeInput","beforeinput",null,n,o),r.push({event:o,listeners:s}),o.data=y))}Ms(r,t)}))}function Vs(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Hs(e,t){for(var n=t+"Capture",s=[];null!==e;){var o=e,a=o.stateNode;5===o.tag&&null!==a&&(o=a,null!=(a=Re(e,n))&&s.unshift(Vs(e,a,o)),null!=(a=Re(e,t))&&s.push(Vs(e,a,o))),e=e.return}return s}function Ws(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Gs(e,t,n,s,o){for(var a=t._reactName,r=[];null!==n&&n!==s;){var i=n,c=i.alternate,d=i.stateNode;if(null!==c&&c===s)break;5===i.tag&&null!==d&&(i=d,o?null!=(c=Re(n,a))&&r.unshift(Vs(n,c,i)):o||null!=(c=Re(n,a))&&r.push(Vs(n,c,i))),n=n.return}0!==r.length&&e.push({event:t,listeners:r})}var Xs=/\r\n?/g,Ks=/\u0000|\uFFFD/g;function Zs(e){return("string"==typeof e?e:""+e).replace(Xs,"\n").replace(Ks,"")}function Ys(e,t,n){if(t=Zs(t),Zs(e)!==t&&n)throw Error(a(425))}function Js(){}var eo=null,to=null;function no(e,t){return"textarea"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var so="function"==typeof setTimeout?setTimeout:void 0,oo="function"==typeof clearTimeout?clearTimeout:void 0,ao="function"==typeof Promise?Promise:void 0,ro="function"==typeof queueMicrotask?queueMicrotask:void 0!==ao?function(e){return ao.resolve(null).then(e).catch(io)}:so;function io(e){setTimeout((function(){throw e}))}function co(e,t){var n=t,s=0;do{var o=n.nextSibling;if(e.removeChild(n),o&&8===o.nodeType)if("/$"===(n=o.data)){if(0===s)return e.removeChild(o),void Ut(t);s--}else"$"!==n&&"$?"!==n&&"$!"!==n||s++;n=o}while(n);Ut(t)}function uo(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break;if(8===t){if("$"===(t=e.data)||"$!"===t||"$?"===t)break;if("/$"===t)return null}}return e}function lo(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var po=Math.random().toString(36).slice(2),mo="__reactFiber$"+po,go="__reactProps$"+po,fo="__reactContainer$"+po,ho="__reactEvents$"+po,bo="__reactListeners$"+po,yo="__reactHandles$"+po;function vo(e){var t=e[mo];if(t)return t;for(var n=e.parentNode;n;){if(t=n[fo]||n[mo]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=lo(e);null!==e;){if(n=e[mo])return n;e=lo(e)}return t}n=(e=n).parentNode}return null}function ko(e){return!(e=e[mo]||e[fo])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function xo(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(a(33))}function wo(e){return e[go]||null}var _o=[],So=-1;function Eo(e){return{current:e}}function Co(e){0>So||(e.current=_o[So],_o[So]=null,So--)}function To(e,t){So++,_o[So]=e.current,e.current=t}var Ao={},jo=Eo(Ao),Po=Eo(!1),Lo=Ao;function Ro(e,t){var n=e.type.contextTypes;if(!n)return Ao;var s=e.stateNode;if(s&&s.__reactInternalMemoizedUnmaskedChildContext===t)return s.__reactInternalMemoizedMaskedChildContext;var o,a={};for(o in n)a[o]=t[o];return s&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=a),a}function No(e){return null!=(e=e.childContextTypes)}function Oo(){Co(Po),Co(jo)}function Io(e,t,n){if(jo.current!==Ao)throw Error(a(168));To(jo,t),To(Po,n)}function Do(e,t,n){var s=e.stateNode;if(t=t.childContextTypes,"function"!=typeof s.getChildContext)return n;for(var o in s=s.getChildContext())if(!(o in t))throw Error(a(108,q(e)||"Unknown",o));return F({},n,s)}function Fo(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Ao,Lo=jo.current,To(jo,e),To(Po,Po.current),!0}function Mo(e,t,n){var s=e.stateNode;if(!s)throw Error(a(169));n?(e=Do(e,t,Lo),s.__reactInternalMemoizedMergedChildContext=e,Co(Po),Co(jo),To(jo,e)):Co(Po),To(Po,n)}var zo=null,Bo=!1,$o=!1;function Uo(e){null===zo?zo=[e]:zo.push(e)}function qo(){if(!$o&&null!==zo){$o=!0;var e=0,t=vt;try{var n=zo;for(vt=1;e<n.length;e++){var s=n[e];do{s=s(!0)}while(null!==s)}zo=null,Bo=!1}catch(o){throw null!==zo&&(zo=zo.slice(e+1)),We(Je,qo),o}finally{vt=t,$o=!1}}return null}var Qo=[],Vo=0,Ho=null,Wo=0,Go=[],Xo=0,Ko=null,Zo=1,Yo="";function Jo(e,t){Qo[Vo++]=Wo,Qo[Vo++]=Ho,Ho=e,Wo=t}function ea(e,t,n){Go[Xo++]=Zo,Go[Xo++]=Yo,Go[Xo++]=Ko,Ko=e;var s=Zo;e=Yo;var o=32-rt(s)-1;s&=~(1<<o),n+=1;var a=32-rt(t)+o;if(30<a){var r=o-o%5;a=(s&(1<<r)-1).toString(32),s>>=r,o-=r,Zo=1<<32-rt(t)+o|n<<o|s,Yo=a+e}else Zo=1<<a|n<<o|s,Yo=e}function ta(e){null!==e.return&&(Jo(e,1),ea(e,1,0))}function na(e){for(;e===Ho;)Ho=Qo[--Vo],Qo[Vo]=null,Wo=Qo[--Vo],Qo[Vo]=null;for(;e===Ko;)Ko=Go[--Xo],Go[Xo]=null,Yo=Go[--Xo],Go[Xo]=null,Zo=Go[--Xo],Go[Xo]=null}var sa=null,oa=null,aa=!1,ra=null;function ia(e,t){var n=Ld(5,null,null,0);n.elementType="DELETED",n.stateNode=t,n.return=e,null===(t=e.deletions)?(e.deletions=[n],e.flags|=16):t.push(n)}function ca(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,sa=e,oa=uo(t.firstChild),!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,sa=e,oa=null,!0);case 13:return null!==(t=8!==t.nodeType?null:t)&&(n=null!==Ko?{id:Zo,overflow:Yo}:null,e.memoizedState={dehydrated:t,treeContext:n,retryLane:1073741824},(n=Ld(18,null,null,0)).stateNode=t,n.return=e,e.child=n,sa=e,oa=null,!0);default:return!1}}function da(e){return!(!(1&e.mode)||128&e.flags)}function ua(e){if(aa){var t=oa;if(t){var n=t;if(!ca(e,t)){if(da(e))throw Error(a(418));t=uo(n.nextSibling);var s=sa;t&&ca(e,t)?ia(s,n):(e.flags=-4097&e.flags|2,aa=!1,sa=e)}}else{if(da(e))throw Error(a(418));e.flags=-4097&e.flags|2,aa=!1,sa=e}}}function la(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;sa=e}function pa(e){if(e!==sa)return!1;if(!aa)return la(e),aa=!0,!1;var t;if((t=3!==e.tag)&&!(t=5!==e.tag)&&(t="head"!==(t=e.type)&&"body"!==t&&!no(e.type,e.memoizedProps)),t&&(t=oa)){if(da(e))throw ma(),Error(a(418));for(;t;)ia(e,t),t=uo(t.nextSibling)}if(la(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(a(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){oa=uo(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}oa=null}}else oa=sa?uo(e.stateNode.nextSibling):null;return!0}function ma(){for(var e=oa;e;)e=uo(e.nextSibling)}function ga(){oa=sa=null,aa=!1}function fa(e){null===ra?ra=[e]:ra.push(e)}var ha=k.ReactCurrentBatchConfig;function ba(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(a(309));var s=n.stateNode}if(!s)throw Error(a(147,e));var o=s,r=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===r?t.ref:(t=function(e){var t=o.refs;null===e?delete t[r]:t[r]=e},t._stringRef=r,t)}if("string"!=typeof e)throw Error(a(284));if(!n._owner)throw Error(a(290,e))}return e}function ya(e,t){throw e=Object.prototype.toString.call(t),Error(a(31,"[object Object]"===e?"object with keys {"+Object.keys(t).join(", ")+"}":e))}function va(e){return(0,e._init)(e._payload)}function ka(e){function t(t,n){if(e){var s=t.deletions;null===s?(t.deletions=[n],t.flags|=16):s.push(n)}}function n(n,s){if(!e)return null;for(;null!==s;)t(n,s),s=s.sibling;return null}function s(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function o(e,t){return(e=Nd(e,t)).index=0,e.sibling=null,e}function r(t,n,s){return t.index=s,e?null!==(s=t.alternate)?(s=s.index)<n?(t.flags|=2,n):s:(t.flags|=2,n):(t.flags|=1048576,n)}function i(t){return e&&null===t.alternate&&(t.flags|=2),t}function c(e,t,n,s){return null===t||6!==t.tag?((t=Fd(n,e.mode,s)).return=e,t):((t=o(t,n)).return=e,t)}function d(e,t,n,s){var a=n.type;return a===_?l(e,t,n.props.children,s,n.key):null!==t&&(t.elementType===a||"object"==typeof a&&null!==a&&a.$$typeof===R&&va(a)===t.type)?((s=o(t,n.props)).ref=ba(e,t,n),s.return=e,s):((s=Od(n.type,n.key,n.props,null,e.mode,s)).ref=ba(e,t,n),s.return=e,s)}function u(e,t,n,s){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Md(n,e.mode,s)).return=e,t):((t=o(t,n.children||[])).return=e,t)}function l(e,t,n,s,a){return null===t||7!==t.tag?((t=Id(n,e.mode,s,a)).return=e,t):((t=o(t,n)).return=e,t)}function p(e,t,n){if("string"==typeof t&&""!==t||"number"==typeof t)return(t=Fd(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case x:return(n=Od(t.type,t.key,t.props,null,e.mode,n)).ref=ba(e,null,t),n.return=e,n;case w:return(t=Md(t,e.mode,n)).return=e,t;case R:return p(e,(0,t._init)(t._payload),n)}if(te(t)||I(t))return(t=Id(t,e.mode,n,null)).return=e,t;ya(e,t)}return null}function m(e,t,n,s){var o=null!==t?t.key:null;if("string"==typeof n&&""!==n||"number"==typeof n)return null!==o?null:c(e,t,""+n,s);if("object"==typeof n&&null!==n){switch(n.$$typeof){case x:return n.key===o?d(e,t,n,s):null;case w:return n.key===o?u(e,t,n,s):null;case R:return m(e,t,(o=n._init)(n._payload),s)}if(te(n)||I(n))return null!==o?null:l(e,t,n,s,null);ya(e,n)}return null}function g(e,t,n,s,o){if("string"==typeof s&&""!==s||"number"==typeof s)return c(t,e=e.get(n)||null,""+s,o);if("object"==typeof s&&null!==s){switch(s.$$typeof){case x:return d(t,e=e.get(null===s.key?n:s.key)||null,s,o);case w:return u(t,e=e.get(null===s.key?n:s.key)||null,s,o);case R:return g(e,t,n,(0,s._init)(s._payload),o)}if(te(s)||I(s))return l(t,e=e.get(n)||null,s,o,null);ya(t,s)}return null}function f(o,a,i,c){for(var d=null,u=null,l=a,f=a=0,h=null;null!==l&&f<i.length;f++){l.index>f?(h=l,l=null):h=l.sibling;var b=m(o,l,i[f],c);if(null===b){null===l&&(l=h);break}e&&l&&null===b.alternate&&t(o,l),a=r(b,a,f),null===u?d=b:u.sibling=b,u=b,l=h}if(f===i.length)return n(o,l),aa&&Jo(o,f),d;if(null===l){for(;f<i.length;f++)null!==(l=p(o,i[f],c))&&(a=r(l,a,f),null===u?d=l:u.sibling=l,u=l);return aa&&Jo(o,f),d}for(l=s(o,l);f<i.length;f++)null!==(h=g(l,o,f,i[f],c))&&(e&&null!==h.alternate&&l.delete(null===h.key?f:h.key),a=r(h,a,f),null===u?d=h:u.sibling=h,u=h);return e&&l.forEach((function(e){return t(o,e)})),aa&&Jo(o,f),d}function h(o,i,c,d){var u=I(c);if("function"!=typeof u)throw Error(a(150));if(null==(c=u.call(c)))throw Error(a(151));for(var l=u=null,f=i,h=i=0,b=null,y=c.next();null!==f&&!y.done;h++,y=c.next()){f.index>h?(b=f,f=null):b=f.sibling;var v=m(o,f,y.value,d);if(null===v){null===f&&(f=b);break}e&&f&&null===v.alternate&&t(o,f),i=r(v,i,h),null===l?u=v:l.sibling=v,l=v,f=b}if(y.done)return n(o,f),aa&&Jo(o,h),u;if(null===f){for(;!y.done;h++,y=c.next())null!==(y=p(o,y.value,d))&&(i=r(y,i,h),null===l?u=y:l.sibling=y,l=y);return aa&&Jo(o,h),u}for(f=s(o,f);!y.done;h++,y=c.next())null!==(y=g(f,o,h,y.value,d))&&(e&&null!==y.alternate&&f.delete(null===y.key?h:y.key),i=r(y,i,h),null===l?u=y:l.sibling=y,l=y);return e&&f.forEach((function(e){return t(o,e)})),aa&&Jo(o,h),u}return function e(s,a,r,c){if("object"==typeof r&&null!==r&&r.type===_&&null===r.key&&(r=r.props.children),"object"==typeof r&&null!==r){switch(r.$$typeof){case x:e:{for(var d=r.key,u=a;null!==u;){if(u.key===d){if((d=r.type)===_){if(7===u.tag){n(s,u.sibling),(a=o(u,r.props.children)).return=s,s=a;break e}}else if(u.elementType===d||"object"==typeof d&&null!==d&&d.$$typeof===R&&va(d)===u.type){n(s,u.sibling),(a=o(u,r.props)).ref=ba(s,u,r),a.return=s,s=a;break e}n(s,u);break}t(s,u),u=u.sibling}r.type===_?((a=Id(r.props.children,s.mode,c,r.key)).return=s,s=a):((c=Od(r.type,r.key,r.props,null,s.mode,c)).ref=ba(s,a,r),c.return=s,s=c)}return i(s);case w:e:{for(u=r.key;null!==a;){if(a.key===u){if(4===a.tag&&a.stateNode.containerInfo===r.containerInfo&&a.stateNode.implementation===r.implementation){n(s,a.sibling),(a=o(a,r.children||[])).return=s,s=a;break e}n(s,a);break}t(s,a),a=a.sibling}(a=Md(r,s.mode,c)).return=s,s=a}return i(s);case R:return e(s,a,(u=r._init)(r._payload),c)}if(te(r))return f(s,a,r,c);if(I(r))return h(s,a,r,c);ya(s,r)}return"string"==typeof r&&""!==r||"number"==typeof r?(r=""+r,null!==a&&6===a.tag?(n(s,a.sibling),(a=o(a,r)).return=s,s=a):(n(s,a),(a=Fd(r,s.mode,c)).return=s,s=a),i(s)):n(s,a)}}var xa=ka(!0),wa=ka(!1),_a=Eo(null),Sa=null,Ea=null,Ca=null;function Ta(){Ca=Ea=Sa=null}function Aa(e){var t=_a.current;Co(_a),e._currentValue=t}function ja(e,t,n){for(;null!==e;){var s=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,null!==s&&(s.childLanes|=t)):null!==s&&(s.childLanes&t)!==t&&(s.childLanes|=t),e===n)break;e=e.return}}function Pa(e,t){Sa=e,Ca=Ea=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(!!(e.lanes&t)&&(vi=!0),e.firstContext=null)}function La(e){var t=e._currentValue;if(Ca!==e)if(e={context:e,memoizedValue:t,next:null},null===Ea){if(null===Sa)throw Error(a(308));Ea=e,Sa.dependencies={lanes:0,firstContext:e}}else Ea=Ea.next=e;return t}var Ra=null;function Na(e){null===Ra?Ra=[e]:Ra.push(e)}function Oa(e,t,n,s){var o=t.interleaved;return null===o?(n.next=n,Na(t)):(n.next=o.next,o.next=n),t.interleaved=n,Ia(e,s)}function Ia(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}var Da=!1;function Fa(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Ma(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function za(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function Ba(e,t,n){var s=e.updateQueue;if(null===s)return null;if(s=s.shared,2&Ac){var o=s.pending;return null===o?t.next=t:(t.next=o.next,o.next=t),s.pending=t,Ia(e,n)}return null===(o=s.interleaved)?(t.next=t,Na(s)):(t.next=o.next,o.next=t),s.interleaved=t,Ia(e,n)}function $a(e,t,n){if(null!==(t=t.updateQueue)&&(t=t.shared,4194240&n)){var s=t.lanes;n|=s&=e.pendingLanes,t.lanes=n,yt(e,n)}}function Ua(e,t){var n=e.updateQueue,s=e.alternate;if(null!==s&&n===(s=s.updateQueue)){var o=null,a=null;if(null!==(n=n.firstBaseUpdate)){do{var r={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===a?o=a=r:a=a.next=r,n=n.next}while(null!==n);null===a?o=a=t:a=a.next=t}else o=a=t;return n={baseState:s.baseState,firstBaseUpdate:o,lastBaseUpdate:a,shared:s.shared,effects:s.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function qa(e,t,n,s){var o=e.updateQueue;Da=!1;var a=o.firstBaseUpdate,r=o.lastBaseUpdate,i=o.shared.pending;if(null!==i){o.shared.pending=null;var c=i,d=c.next;c.next=null,null===r?a=d:r.next=d,r=c;var u=e.alternate;null!==u&&((i=(u=u.updateQueue).lastBaseUpdate)!==r&&(null===i?u.firstBaseUpdate=d:i.next=d,u.lastBaseUpdate=c))}if(null!==a){var l=o.baseState;for(r=0,u=d=c=null,i=a;;){var p=i.lane,m=i.eventTime;if((s&p)===p){null!==u&&(u=u.next={eventTime:m,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var g=e,f=i;switch(p=t,m=n,f.tag){case 1:if("function"==typeof(g=f.payload)){l=g.call(m,l,p);break e}l=g;break e;case 3:g.flags=-65537&g.flags|128;case 0:if(null==(p="function"==typeof(g=f.payload)?g.call(m,l,p):g))break e;l=F({},l,p);break e;case 2:Da=!0}}null!==i.callback&&0!==i.lane&&(e.flags|=64,null===(p=o.effects)?o.effects=[i]:p.push(i))}else m={eventTime:m,lane:p,tag:i.tag,payload:i.payload,callback:i.callback,next:null},null===u?(d=u=m,c=l):u=u.next=m,r|=p;if(null===(i=i.next)){if(null===(i=o.shared.pending))break;i=(p=i).next,p.next=null,o.lastBaseUpdate=p,o.shared.pending=null}}if(null===u&&(c=l),o.baseState=c,o.firstBaseUpdate=d,o.lastBaseUpdate=u,null!==(t=o.shared.interleaved)){o=t;do{r|=o.lane,o=o.next}while(o!==t)}else null===a&&(o.shared.lanes=0);Dc|=r,e.lanes=r,e.memoizedState=l}}function Qa(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var s=e[t],o=s.callback;if(null!==o){if(s.callback=null,s=n,"function"!=typeof o)throw Error(a(191,o));o.call(s)}}}var Va={},Ha=Eo(Va),Wa=Eo(Va),Ga=Eo(Va);function Xa(e){if(e===Va)throw Error(a(174));return e}function Ka(e,t){switch(To(Ga,t),To(Wa,e),To(Ha,Va),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:ce(null,"");break;default:t=ce(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}Co(Ha),To(Ha,t)}function Za(){Co(Ha),Co(Wa),Co(Ga)}function Ya(e){Xa(Ga.current);var t=Xa(Ha.current),n=ce(t,e.type);t!==n&&(To(Wa,e),To(Ha,n))}function Ja(e){Wa.current===e&&(Co(Ha),Co(Wa))}var er=Eo(0);function tr(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(128&t.flags)return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var nr=[];function sr(){for(var e=0;e<nr.length;e++)nr[e]._workInProgressVersionPrimary=null;nr.length=0}var or=k.ReactCurrentDispatcher,ar=k.ReactCurrentBatchConfig,rr=0,ir=null,cr=null,dr=null,ur=!1,lr=!1,pr=0,mr=0;function gr(){throw Error(a(321))}function fr(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!is(e[n],t[n]))return!1;return!0}function hr(e,t,n,s,o,r){if(rr=r,ir=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,or.current=null===e||null===e.memoizedState?Jr:ei,e=n(s,o),lr){r=0;do{if(lr=!1,pr=0,25<=r)throw Error(a(301));r+=1,dr=cr=null,t.updateQueue=null,or.current=ti,e=n(s,o)}while(lr)}if(or.current=Yr,t=null!==cr&&null!==cr.next,rr=0,dr=cr=ir=null,ur=!1,t)throw Error(a(300));return e}function br(){var e=0!==pr;return pr=0,e}function yr(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===dr?ir.memoizedState=dr=e:dr=dr.next=e,dr}function vr(){if(null===cr){var e=ir.alternate;e=null!==e?e.memoizedState:null}else e=cr.next;var t=null===dr?ir.memoizedState:dr.next;if(null!==t)dr=t,cr=e;else{if(null===e)throw Error(a(310));e={memoizedState:(cr=e).memoizedState,baseState:cr.baseState,baseQueue:cr.baseQueue,queue:cr.queue,next:null},null===dr?ir.memoizedState=dr=e:dr=dr.next=e}return dr}function kr(e,t){return"function"==typeof t?t(e):t}function xr(e){var t=vr(),n=t.queue;if(null===n)throw Error(a(311));n.lastRenderedReducer=e;var s=cr,o=s.baseQueue,r=n.pending;if(null!==r){if(null!==o){var i=o.next;o.next=r.next,r.next=i}s.baseQueue=o=r,n.pending=null}if(null!==o){r=o.next,s=s.baseState;var c=i=null,d=null,u=r;do{var l=u.lane;if((rr&l)===l)null!==d&&(d=d.next={lane:0,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null}),s=u.hasEagerState?u.eagerState:e(s,u.action);else{var p={lane:l,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null};null===d?(c=d=p,i=s):d=d.next=p,ir.lanes|=l,Dc|=l}u=u.next}while(null!==u&&u!==r);null===d?i=s:d.next=c,is(s,t.memoizedState)||(vi=!0),t.memoizedState=s,t.baseState=i,t.baseQueue=d,n.lastRenderedState=s}if(null!==(e=n.interleaved)){o=e;do{r=o.lane,ir.lanes|=r,Dc|=r,o=o.next}while(o!==e)}else null===o&&(n.lanes=0);return[t.memoizedState,n.dispatch]}function wr(e){var t=vr(),n=t.queue;if(null===n)throw Error(a(311));n.lastRenderedReducer=e;var s=n.dispatch,o=n.pending,r=t.memoizedState;if(null!==o){n.pending=null;var i=o=o.next;do{r=e(r,i.action),i=i.next}while(i!==o);is(r,t.memoizedState)||(vi=!0),t.memoizedState=r,null===t.baseQueue&&(t.baseState=r),n.lastRenderedState=r}return[r,s]}function _r(){}function Sr(e,t){var n=ir,s=vr(),o=t(),r=!is(s.memoizedState,o);if(r&&(s.memoizedState=o,vi=!0),s=s.queue,Dr(Tr.bind(null,n,s,e),[e]),s.getSnapshot!==t||r||null!==dr&&1&dr.memoizedState.tag){if(n.flags|=2048,Lr(9,Cr.bind(null,n,s,o,t),void 0,null),null===jc)throw Error(a(349));30&rr||Er(n,t,o)}return o}function Er(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},null===(t=ir.updateQueue)?(t={lastEffect:null,stores:null},ir.updateQueue=t,t.stores=[e]):null===(n=t.stores)?t.stores=[e]:n.push(e)}function Cr(e,t,n,s){t.value=n,t.getSnapshot=s,Ar(t)&&jr(e)}function Tr(e,t,n){return n((function(){Ar(t)&&jr(e)}))}function Ar(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!is(e,n)}catch(s){return!0}}function jr(e){var t=Ia(e,1);null!==t&&nd(t,e,1,-1)}function Pr(e){var t=yr();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:kr,lastRenderedState:e},t.queue=e,e=e.dispatch=Gr.bind(null,ir,e),[t.memoizedState,e]}function Lr(e,t,n,s){return e={tag:e,create:t,destroy:n,deps:s,next:null},null===(t=ir.updateQueue)?(t={lastEffect:null,stores:null},ir.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(s=n.next,n.next=e,e.next=s,t.lastEffect=e),e}function Rr(){return vr().memoizedState}function Nr(e,t,n,s){var o=yr();ir.flags|=e,o.memoizedState=Lr(1|t,n,void 0,void 0===s?null:s)}function Or(e,t,n,s){var o=vr();s=void 0===s?null:s;var a=void 0;if(null!==cr){var r=cr.memoizedState;if(a=r.destroy,null!==s&&fr(s,r.deps))return void(o.memoizedState=Lr(t,n,a,s))}ir.flags|=e,o.memoizedState=Lr(1|t,n,a,s)}function Ir(e,t){return Nr(8390656,8,e,t)}function Dr(e,t){return Or(2048,8,e,t)}function Fr(e,t){return Or(4,2,e,t)}function Mr(e,t){return Or(4,4,e,t)}function zr(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function Br(e,t,n){return n=null!=n?n.concat([e]):null,Or(4,4,zr.bind(null,t,e),n)}function $r(){}function Ur(e,t){var n=vr();t=void 0===t?null:t;var s=n.memoizedState;return null!==s&&null!==t&&fr(t,s[1])?s[0]:(n.memoizedState=[e,t],e)}function qr(e,t){var n=vr();t=void 0===t?null:t;var s=n.memoizedState;return null!==s&&null!==t&&fr(t,s[1])?s[0]:(e=e(),n.memoizedState=[e,t],e)}function Qr(e,t,n){return 21&rr?(is(n,t)||(n=ft(),ir.lanes|=n,Dc|=n,e.baseState=!0),t):(e.baseState&&(e.baseState=!1,vi=!0),e.memoizedState=n)}function Vr(e,t){var n=vt;vt=0!==n&&4>n?n:4,e(!0);var s=ar.transition;ar.transition={};try{e(!1),t()}finally{vt=n,ar.transition=s}}function Hr(){return vr().memoizedState}function Wr(e,t,n){var s=td(e);if(n={lane:s,action:n,hasEagerState:!1,eagerState:null,next:null},Xr(e))Kr(t,n);else if(null!==(n=Oa(e,t,n,s))){nd(n,e,s,ed()),Zr(n,t,s)}}function Gr(e,t,n){var s=td(e),o={lane:s,action:n,hasEagerState:!1,eagerState:null,next:null};if(Xr(e))Kr(t,o);else{var a=e.alternate;if(0===e.lanes&&(null===a||0===a.lanes)&&null!==(a=t.lastRenderedReducer))try{var r=t.lastRenderedState,i=a(r,n);if(o.hasEagerState=!0,o.eagerState=i,is(i,r)){var c=t.interleaved;return null===c?(o.next=o,Na(t)):(o.next=c.next,c.next=o),void(t.interleaved=o)}}catch(d){}null!==(n=Oa(e,t,o,s))&&(nd(n,e,s,o=ed()),Zr(n,t,s))}}function Xr(e){var t=e.alternate;return e===ir||null!==t&&t===ir}function Kr(e,t){lr=ur=!0;var n=e.pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Zr(e,t,n){if(4194240&n){var s=t.lanes;n|=s&=e.pendingLanes,t.lanes=n,yt(e,n)}}var Yr={readContext:La,useCallback:gr,useContext:gr,useEffect:gr,useImperativeHandle:gr,useInsertionEffect:gr,useLayoutEffect:gr,useMemo:gr,useReducer:gr,useRef:gr,useState:gr,useDebugValue:gr,useDeferredValue:gr,useTransition:gr,useMutableSource:gr,useSyncExternalStore:gr,useId:gr,unstable_isNewReconciler:!1},Jr={readContext:La,useCallback:function(e,t){return yr().memoizedState=[e,void 0===t?null:t],e},useContext:La,useEffect:Ir,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,Nr(4194308,4,zr.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Nr(4194308,4,e,t)},useInsertionEffect:function(e,t){return Nr(4,2,e,t)},useMemo:function(e,t){var n=yr();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var s=yr();return t=void 0!==n?n(t):t,s.memoizedState=s.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},s.queue=e,e=e.dispatch=Wr.bind(null,ir,e),[s.memoizedState,e]},useRef:function(e){return e={current:e},yr().memoizedState=e},useState:Pr,useDebugValue:$r,useDeferredValue:function(e){return yr().memoizedState=e},useTransition:function(){var e=Pr(!1),t=e[0];return e=Vr.bind(null,e[1]),yr().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var s=ir,o=yr();if(aa){if(void 0===n)throw Error(a(407));n=n()}else{if(n=t(),null===jc)throw Error(a(349));30&rr||Er(s,t,n)}o.memoizedState=n;var r={value:n,getSnapshot:t};return o.queue=r,Ir(Tr.bind(null,s,r,e),[e]),s.flags|=2048,Lr(9,Cr.bind(null,s,r,n,t),void 0,null),n},useId:function(){var e=yr(),t=jc.identifierPrefix;if(aa){var n=Yo;t=":"+t+"R"+(n=(Zo&~(1<<32-rt(Zo)-1)).toString(32)+n),0<(n=pr++)&&(t+="H"+n.toString(32)),t+=":"}else t=":"+t+"r"+(n=mr++).toString(32)+":";return e.memoizedState=t},unstable_isNewReconciler:!1},ei={readContext:La,useCallback:Ur,useContext:La,useEffect:Dr,useImperativeHandle:Br,useInsertionEffect:Fr,useLayoutEffect:Mr,useMemo:qr,useReducer:xr,useRef:Rr,useState:function(){return xr(kr)},useDebugValue:$r,useDeferredValue:function(e){return Qr(vr(),cr.memoizedState,e)},useTransition:function(){return[xr(kr)[0],vr().memoizedState]},useMutableSource:_r,useSyncExternalStore:Sr,useId:Hr,unstable_isNewReconciler:!1},ti={readContext:La,useCallback:Ur,useContext:La,useEffect:Dr,useImperativeHandle:Br,useInsertionEffect:Fr,useLayoutEffect:Mr,useMemo:qr,useReducer:wr,useRef:Rr,useState:function(){return wr(kr)},useDebugValue:$r,useDeferredValue:function(e){var t=vr();return null===cr?t.memoizedState=e:Qr(t,cr.memoizedState,e)},useTransition:function(){return[wr(kr)[0],vr().memoizedState]},useMutableSource:_r,useSyncExternalStore:Sr,useId:Hr,unstable_isNewReconciler:!1};function ni(e,t){if(e&&e.defaultProps){for(var n in t=F({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}function si(e,t,n,s){n=null==(n=n(s,t=e.memoizedState))?t:F({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var oi={isMounted:function(e){return!!(e=e._reactInternals)&&Ue(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var s=ed(),o=td(e),a=za(s,o);a.payload=t,null!=n&&(a.callback=n),null!==(t=Ba(e,a,o))&&(nd(t,e,o,s),$a(t,e,o))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var s=ed(),o=td(e),a=za(s,o);a.tag=1,a.payload=t,null!=n&&(a.callback=n),null!==(t=Ba(e,a,o))&&(nd(t,e,o,s),$a(t,e,o))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=ed(),s=td(e),o=za(n,s);o.tag=2,null!=t&&(o.callback=t),null!==(t=Ba(e,o,s))&&(nd(t,e,s,n),$a(t,e,s))}};function ai(e,t,n,s,o,a,r){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(s,a,r):!t.prototype||!t.prototype.isPureReactComponent||(!cs(n,s)||!cs(o,a))}function ri(e,t,n){var s=!1,o=Ao,a=t.contextType;return"object"==typeof a&&null!==a?a=La(a):(o=No(t)?Lo:jo.current,a=(s=null!=(s=t.contextTypes))?Ro(e,o):Ao),t=new t(n,a),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=oi,e.stateNode=t,t._reactInternals=e,s&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=o,e.__reactInternalMemoizedMaskedChildContext=a),t}function ii(e,t,n,s){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,s),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,s),t.state!==e&&oi.enqueueReplaceState(t,t.state,null)}function ci(e,t,n,s){var o=e.stateNode;o.props=n,o.state=e.memoizedState,o.refs={},Fa(e);var a=t.contextType;"object"==typeof a&&null!==a?o.context=La(a):(a=No(t)?Lo:jo.current,o.context=Ro(e,a)),o.state=e.memoizedState,"function"==typeof(a=t.getDerivedStateFromProps)&&(si(e,t,a,n),o.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof o.getSnapshotBeforeUpdate||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||(t=o.state,"function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),t!==o.state&&oi.enqueueReplaceState(o,o.state,null),qa(e,n,o,s),o.state=e.memoizedState),"function"==typeof o.componentDidMount&&(e.flags|=4194308)}function di(e,t){try{var n="",s=t;do{n+=$(s),s=s.return}while(s);var o=n}catch(a){o="\nError generating stack: "+a.message+"\n"+a.stack}return{value:e,source:t,stack:o,digest:null}}function ui(e,t,n){return{value:e,source:null,stack:null!=n?n:null,digest:null!=t?t:null}}function li(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}var pi="function"==typeof WeakMap?WeakMap:Map;function mi(e,t,n){(n=za(-1,n)).tag=3,n.payload={element:null};var s=t.value;return n.callback=function(){Qc||(Qc=!0,Vc=s),li(0,t)},n}function gi(e,t,n){(n=za(-1,n)).tag=3;var s=e.type.getDerivedStateFromError;if("function"==typeof s){var o=t.value;n.payload=function(){return s(o)},n.callback=function(){li(0,t)}}var a=e.stateNode;return null!==a&&"function"==typeof a.componentDidCatch&&(n.callback=function(){li(0,t),"function"!=typeof s&&(null===Hc?Hc=new Set([this]):Hc.add(this));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}function fi(e,t,n){var s=e.pingCache;if(null===s){s=e.pingCache=new pi;var o=new Set;s.set(t,o)}else void 0===(o=s.get(t))&&(o=new Set,s.set(t,o));o.has(n)||(o.add(n),e=Ed.bind(null,e,t,n),t.then(e,e))}function hi(e){do{var t;if((t=13===e.tag)&&(t=null===(t=e.memoizedState)||null!==t.dehydrated),t)return e;e=e.return}while(null!==e);return null}function bi(e,t,n,s,o){return 1&e.mode?(e.flags|=65536,e.lanes=o,e):(e===t?e.flags|=65536:(e.flags|=128,n.flags|=131072,n.flags&=-52805,1===n.tag&&(null===n.alternate?n.tag=17:((t=za(-1,1)).tag=2,Ba(n,t,1))),n.lanes|=1),e)}var yi=k.ReactCurrentOwner,vi=!1;function ki(e,t,n,s){t.child=null===e?wa(t,null,n,s):xa(t,e.child,n,s)}function xi(e,t,n,s,o){n=n.render;var a=t.ref;return Pa(t,o),s=hr(e,t,n,s,a,o),n=br(),null===e||vi?(aa&&n&&ta(t),t.flags|=1,ki(e,t,s,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,Qi(e,t,o))}function wi(e,t,n,s,o){if(null===e){var a=n.type;return"function"!=typeof a||Rd(a)||void 0!==a.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Od(n.type,null,s,t,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=a,_i(e,t,a,s,o))}if(a=e.child,!(e.lanes&o)){var r=a.memoizedProps;if((n=null!==(n=n.compare)?n:cs)(r,s)&&e.ref===t.ref)return Qi(e,t,o)}return t.flags|=1,(e=Nd(a,s)).ref=t.ref,e.return=t,t.child=e}function _i(e,t,n,s,o){if(null!==e){var a=e.memoizedProps;if(cs(a,s)&&e.ref===t.ref){if(vi=!1,t.pendingProps=s=a,!(e.lanes&o))return t.lanes=e.lanes,Qi(e,t,o);131072&e.flags&&(vi=!0)}}return Ci(e,t,n,s,o)}function Si(e,t,n){var s=t.pendingProps,o=s.children,a=null!==e?e.memoizedState:null;if("hidden"===s.mode)if(1&t.mode){if(!(1073741824&n))return e=null!==a?a.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,To(Nc,Rc),Rc|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},s=null!==a?a.baseLanes:n,To(Nc,Rc),Rc|=s}else t.memoizedState={baseLanes:0,cachePool:null,transitions:null},To(Nc,Rc),Rc|=n;else null!==a?(s=a.baseLanes|n,t.memoizedState=null):s=n,To(Nc,Rc),Rc|=s;return ki(e,t,o,n),t.child}function Ei(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function Ci(e,t,n,s,o){var a=No(n)?Lo:jo.current;return a=Ro(t,a),Pa(t,o),n=hr(e,t,n,s,a,o),s=br(),null===e||vi?(aa&&s&&ta(t),t.flags|=1,ki(e,t,n,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,Qi(e,t,o))}function Ti(e,t,n,s,o){if(No(n)){var a=!0;Fo(t)}else a=!1;if(Pa(t,o),null===t.stateNode)qi(e,t),ri(t,n,s),ci(t,n,s,o),s=!0;else if(null===e){var r=t.stateNode,i=t.memoizedProps;r.props=i;var c=r.context,d=n.contextType;"object"==typeof d&&null!==d?d=La(d):d=Ro(t,d=No(n)?Lo:jo.current);var u=n.getDerivedStateFromProps,l="function"==typeof u||"function"==typeof r.getSnapshotBeforeUpdate;l||"function"!=typeof r.UNSAFE_componentWillReceiveProps&&"function"!=typeof r.componentWillReceiveProps||(i!==s||c!==d)&&ii(t,r,s,d),Da=!1;var p=t.memoizedState;r.state=p,qa(t,s,r,o),c=t.memoizedState,i!==s||p!==c||Po.current||Da?("function"==typeof u&&(si(t,n,u,s),c=t.memoizedState),(i=Da||ai(t,n,i,s,p,c,d))?(l||"function"!=typeof r.UNSAFE_componentWillMount&&"function"!=typeof r.componentWillMount||("function"==typeof r.componentWillMount&&r.componentWillMount(),"function"==typeof r.UNSAFE_componentWillMount&&r.UNSAFE_componentWillMount()),"function"==typeof r.componentDidMount&&(t.flags|=4194308)):("function"==typeof r.componentDidMount&&(t.flags|=4194308),t.memoizedProps=s,t.memoizedState=c),r.props=s,r.state=c,r.context=d,s=i):("function"==typeof r.componentDidMount&&(t.flags|=4194308),s=!1)}else{r=t.stateNode,Ma(e,t),i=t.memoizedProps,d=t.type===t.elementType?i:ni(t.type,i),r.props=d,l=t.pendingProps,p=r.context,"object"==typeof(c=n.contextType)&&null!==c?c=La(c):c=Ro(t,c=No(n)?Lo:jo.current);var m=n.getDerivedStateFromProps;(u="function"==typeof m||"function"==typeof r.getSnapshotBeforeUpdate)||"function"!=typeof r.UNSAFE_componentWillReceiveProps&&"function"!=typeof r.componentWillReceiveProps||(i!==l||p!==c)&&ii(t,r,s,c),Da=!1,p=t.memoizedState,r.state=p,qa(t,s,r,o);var g=t.memoizedState;i!==l||p!==g||Po.current||Da?("function"==typeof m&&(si(t,n,m,s),g=t.memoizedState),(d=Da||ai(t,n,d,s,p,g,c)||!1)?(u||"function"!=typeof r.UNSAFE_componentWillUpdate&&"function"!=typeof r.componentWillUpdate||("function"==typeof r.componentWillUpdate&&r.componentWillUpdate(s,g,c),"function"==typeof r.UNSAFE_componentWillUpdate&&r.UNSAFE_componentWillUpdate(s,g,c)),"function"==typeof r.componentDidUpdate&&(t.flags|=4),"function"==typeof r.getSnapshotBeforeUpdate&&(t.flags|=1024)):("function"!=typeof r.componentDidUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof r.getSnapshotBeforeUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),t.memoizedProps=s,t.memoizedState=g),r.props=s,r.state=g,r.context=c,s=d):("function"!=typeof r.componentDidUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof r.getSnapshotBeforeUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),s=!1)}return Ai(e,t,n,s,a,o)}function Ai(e,t,n,s,o,a){Ei(e,t);var r=!!(128&t.flags);if(!s&&!r)return o&&Mo(t,n,!1),Qi(e,t,a);s=t.stateNode,yi.current=t;var i=r&&"function"!=typeof n.getDerivedStateFromError?null:s.render();return t.flags|=1,null!==e&&r?(t.child=xa(t,e.child,null,a),t.child=xa(t,null,i,a)):ki(e,t,i,a),t.memoizedState=s.state,o&&Mo(t,n,!0),t.child}function ji(e){var t=e.stateNode;t.pendingContext?Io(0,t.pendingContext,t.pendingContext!==t.context):t.context&&Io(0,t.context,!1),Ka(e,t.containerInfo)}function Pi(e,t,n,s,o){return ga(),fa(o),t.flags|=256,ki(e,t,n,s),t.child}var Li,Ri,Ni,Oi,Ii={dehydrated:null,treeContext:null,retryLane:0};function Di(e){return{baseLanes:e,cachePool:null,transitions:null}}function Fi(e,t,n){var s,o=t.pendingProps,r=er.current,i=!1,c=!!(128&t.flags);if((s=c)||(s=(null===e||null!==e.memoizedState)&&!!(2&r)),s?(i=!0,t.flags&=-129):null!==e&&null===e.memoizedState||(r|=1),To(er,1&r),null===e)return ua(t),null!==(e=t.memoizedState)&&null!==(e=e.dehydrated)?(1&t.mode?"$!"===e.data?t.lanes=8:t.lanes=1073741824:t.lanes=1,null):(c=o.children,e=o.fallback,i?(o=t.mode,i=t.child,c={mode:"hidden",children:c},1&o||null===i?i=Dd(c,o,0,null):(i.childLanes=0,i.pendingProps=c),e=Id(e,o,n,null),i.return=t,e.return=t,i.sibling=e,t.child=i,t.child.memoizedState=Di(n),t.memoizedState=Ii,e):Mi(t,c));if(null!==(r=e.memoizedState)&&null!==(s=r.dehydrated))return function(e,t,n,s,o,r,i){if(n)return 256&t.flags?(t.flags&=-257,zi(e,t,i,s=ui(Error(a(422))))):null!==t.memoizedState?(t.child=e.child,t.flags|=128,null):(r=s.fallback,o=t.mode,s=Dd({mode:"visible",children:s.children},o,0,null),(r=Id(r,o,i,null)).flags|=2,s.return=t,r.return=t,s.sibling=r,t.child=s,1&t.mode&&xa(t,e.child,null,i),t.child.memoizedState=Di(i),t.memoizedState=Ii,r);if(!(1&t.mode))return zi(e,t,i,null);if("$!"===o.data){if(s=o.nextSibling&&o.nextSibling.dataset)var c=s.dgst;return s=c,zi(e,t,i,s=ui(r=Error(a(419)),s,void 0))}if(c=!!(i&e.childLanes),vi||c){if(null!==(s=jc)){switch(i&-i){case 4:o=2;break;case 16:o=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:o=32;break;case 536870912:o=268435456;break;default:o=0}0!==(o=o&(s.suspendedLanes|i)?0:o)&&o!==r.retryLane&&(r.retryLane=o,Ia(e,o),nd(s,e,o,-1))}return fd(),zi(e,t,i,s=ui(Error(a(421))))}return"$?"===o.data?(t.flags|=128,t.child=e.child,t=Td.bind(null,e),o._reactRetry=t,null):(e=r.treeContext,oa=uo(o.nextSibling),sa=t,aa=!0,ra=null,null!==e&&(Go[Xo++]=Zo,Go[Xo++]=Yo,Go[Xo++]=Ko,Zo=e.id,Yo=e.overflow,Ko=t),t=Mi(t,s.children),t.flags|=4096,t)}(e,t,c,o,s,r,n);if(i){i=o.fallback,c=t.mode,s=(r=e.child).sibling;var d={mode:"hidden",children:o.children};return 1&c||t.child===r?(o=Nd(r,d)).subtreeFlags=14680064&r.subtreeFlags:((o=t.child).childLanes=0,o.pendingProps=d,t.deletions=null),null!==s?i=Nd(s,i):(i=Id(i,c,n,null)).flags|=2,i.return=t,o.return=t,o.sibling=i,t.child=o,o=i,i=t.child,c=null===(c=e.child.memoizedState)?Di(n):{baseLanes:c.baseLanes|n,cachePool:null,transitions:c.transitions},i.memoizedState=c,i.childLanes=e.childLanes&~n,t.memoizedState=Ii,o}return e=(i=e.child).sibling,o=Nd(i,{mode:"visible",children:o.children}),!(1&t.mode)&&(o.lanes=n),o.return=t,o.sibling=null,null!==e&&(null===(n=t.deletions)?(t.deletions=[e],t.flags|=16):n.push(e)),t.child=o,t.memoizedState=null,o}function Mi(e,t){return(t=Dd({mode:"visible",children:t},e.mode,0,null)).return=e,e.child=t}function zi(e,t,n,s){return null!==s&&fa(s),xa(t,e.child,null,n),(e=Mi(t,t.pendingProps.children)).flags|=2,t.memoizedState=null,e}function Bi(e,t,n){e.lanes|=t;var s=e.alternate;null!==s&&(s.lanes|=t),ja(e.return,t,n)}function $i(e,t,n,s,o){var a=e.memoizedState;null===a?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:s,tail:n,tailMode:o}:(a.isBackwards=t,a.rendering=null,a.renderingStartTime=0,a.last=s,a.tail=n,a.tailMode=o)}function Ui(e,t,n){var s=t.pendingProps,o=s.revealOrder,a=s.tail;if(ki(e,t,s.children,n),2&(s=er.current))s=1&s|2,t.flags|=128;else{if(null!==e&&128&e.flags)e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&Bi(e,n,t);else if(19===e.tag)Bi(e,n,t);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}s&=1}if(To(er,s),1&t.mode)switch(o){case"forwards":for(n=t.child,o=null;null!==n;)null!==(e=n.alternate)&&null===tr(e)&&(o=n),n=n.sibling;null===(n=o)?(o=t.child,t.child=null):(o=n.sibling,n.sibling=null),$i(t,!1,o,n,a);break;case"backwards":for(n=null,o=t.child,t.child=null;null!==o;){if(null!==(e=o.alternate)&&null===tr(e)){t.child=o;break}e=o.sibling,o.sibling=n,n=o,o=e}$i(t,!0,n,null,a);break;case"together":$i(t,!1,null,null,void 0);break;default:t.memoizedState=null}else t.memoizedState=null;return t.child}function qi(e,t){!(1&t.mode)&&null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2)}function Qi(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Dc|=t.lanes,!(n&t.childLanes))return null;if(null!==e&&t.child!==e.child)throw Error(a(153));if(null!==t.child){for(n=Nd(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Nd(e,e.pendingProps)).return=t;n.sibling=null}return t.child}function Vi(e,t){if(!aa)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var s=null;null!==n;)null!==n.alternate&&(s=n),n=n.sibling;null===s?t||null===e.tail?e.tail=null:e.tail.sibling=null:s.sibling=null}}function Hi(e){var t=null!==e.alternate&&e.alternate.child===e.child,n=0,s=0;if(t)for(var o=e.child;null!==o;)n|=o.lanes|o.childLanes,s|=14680064&o.subtreeFlags,s|=14680064&o.flags,o.return=e,o=o.sibling;else for(o=e.child;null!==o;)n|=o.lanes|o.childLanes,s|=o.subtreeFlags,s|=o.flags,o.return=e,o=o.sibling;return e.subtreeFlags|=s,e.childLanes=n,t}function Wi(e,t,n){var s=t.pendingProps;switch(na(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Hi(t),null;case 1:case 17:return No(t.type)&&Oo(),Hi(t),null;case 3:return s=t.stateNode,Za(),Co(Po),Co(jo),sr(),s.pendingContext&&(s.context=s.pendingContext,s.pendingContext=null),null!==e&&null!==e.child||(pa(t)?t.flags|=4:null===e||e.memoizedState.isDehydrated&&!(256&t.flags)||(t.flags|=1024,null!==ra&&(rd(ra),ra=null))),Ri(e,t),Hi(t),null;case 5:Ja(t);var o=Xa(Ga.current);if(n=t.type,null!==e&&null!=t.stateNode)Ni(e,t,n,s,o),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!s){if(null===t.stateNode)throw Error(a(166));return Hi(t),null}if(e=Xa(Ha.current),pa(t)){s=t.stateNode,n=t.type;var r=t.memoizedProps;switch(s[mo]=t,s[go]=r,e=!!(1&t.mode),n){case"dialog":zs("cancel",s),zs("close",s);break;case"iframe":case"object":case"embed":zs("load",s);break;case"video":case"audio":for(o=0;o<Is.length;o++)zs(Is[o],s);break;case"source":zs("error",s);break;case"img":case"image":case"link":zs("error",s),zs("load",s);break;case"details":zs("toggle",s);break;case"input":K(s,r),zs("invalid",s);break;case"select":s._wrapperState={wasMultiple:!!r.multiple},zs("invalid",s);break;case"textarea":oe(s,r),zs("invalid",s)}for(var c in ye(n,r),o=null,r)if(r.hasOwnProperty(c)){var d=r[c];"children"===c?"string"==typeof d?s.textContent!==d&&(!0!==r.suppressHydrationWarning&&Ys(s.textContent,d,e),o=["children",d]):"number"==typeof d&&s.textContent!==""+d&&(!0!==r.suppressHydrationWarning&&Ys(s.textContent,d,e),o=["children",""+d]):i.hasOwnProperty(c)&&null!=d&&"onScroll"===c&&zs("scroll",s)}switch(n){case"input":H(s),J(s,r,!0);break;case"textarea":H(s),re(s);break;case"select":case"option":break;default:"function"==typeof r.onClick&&(s.onclick=Js)}s=o,t.updateQueue=s,null!==s&&(t.flags|=4)}else{c=9===o.nodeType?o:o.ownerDocument,"http://www.w3.org/1999/xhtml"===e&&(e=ie(n)),"http://www.w3.org/1999/xhtml"===e?"script"===n?((e=c.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof s.is?e=c.createElement(n,{is:s.is}):(e=c.createElement(n),"select"===n&&(c=e,s.multiple?c.multiple=!0:s.size&&(c.size=s.size))):e=c.createElementNS(e,n),e[mo]=t,e[go]=s,Li(e,t,!1,!1),t.stateNode=e;e:{switch(c=ve(n,s),n){case"dialog":zs("cancel",e),zs("close",e),o=s;break;case"iframe":case"object":case"embed":zs("load",e),o=s;break;case"video":case"audio":for(o=0;o<Is.length;o++)zs(Is[o],e);o=s;break;case"source":zs("error",e),o=s;break;case"img":case"image":case"link":zs("error",e),zs("load",e),o=s;break;case"details":zs("toggle",e),o=s;break;case"input":K(e,s),o=X(e,s),zs("invalid",e);break;case"option":default:o=s;break;case"select":e._wrapperState={wasMultiple:!!s.multiple},o=F({},s,{value:void 0}),zs("invalid",e);break;case"textarea":oe(e,s),o=se(e,s),zs("invalid",e)}for(r in ye(n,o),d=o)if(d.hasOwnProperty(r)){var u=d[r];"style"===r?he(e,u):"dangerouslySetInnerHTML"===r?null!=(u=u?u.__html:void 0)&&le(e,u):"children"===r?"string"==typeof u?("textarea"!==n||""!==u)&&pe(e,u):"number"==typeof u&&pe(e,""+u):"suppressContentEditableWarning"!==r&&"suppressHydrationWarning"!==r&&"autoFocus"!==r&&(i.hasOwnProperty(r)?null!=u&&"onScroll"===r&&zs("scroll",e):null!=u&&v(e,r,u,c))}switch(n){case"input":H(e),J(e,s,!1);break;case"textarea":H(e),re(e);break;case"option":null!=s.value&&e.setAttribute("value",""+Q(s.value));break;case"select":e.multiple=!!s.multiple,null!=(r=s.value)?ne(e,!!s.multiple,r,!1):null!=s.defaultValue&&ne(e,!!s.multiple,s.defaultValue,!0);break;default:"function"==typeof o.onClick&&(e.onclick=Js)}switch(n){case"button":case"input":case"select":case"textarea":s=!!s.autoFocus;break e;case"img":s=!0;break e;default:s=!1}}s&&(t.flags|=4)}null!==t.ref&&(t.flags|=512,t.flags|=2097152)}return Hi(t),null;case 6:if(e&&null!=t.stateNode)Oi(e,t,e.memoizedProps,s);else{if("string"!=typeof s&&null===t.stateNode)throw Error(a(166));if(n=Xa(Ga.current),Xa(Ha.current),pa(t)){if(s=t.stateNode,n=t.memoizedProps,s[mo]=t,(r=s.nodeValue!==n)&&null!==(e=sa))switch(e.tag){case 3:Ys(s.nodeValue,n,!!(1&e.mode));break;case 5:!0!==e.memoizedProps.suppressHydrationWarning&&Ys(s.nodeValue,n,!!(1&e.mode))}r&&(t.flags|=4)}else(s=(9===n.nodeType?n:n.ownerDocument).createTextNode(s))[mo]=t,t.stateNode=s}return Hi(t),null;case 13:if(Co(er),s=t.memoizedState,null===e||null!==e.memoizedState&&null!==e.memoizedState.dehydrated){if(aa&&null!==oa&&1&t.mode&&!(128&t.flags))ma(),ga(),t.flags|=98560,r=!1;else if(r=pa(t),null!==s&&null!==s.dehydrated){if(null===e){if(!r)throw Error(a(318));if(!(r=null!==(r=t.memoizedState)?r.dehydrated:null))throw Error(a(317));r[mo]=t}else ga(),!(128&t.flags)&&(t.memoizedState=null),t.flags|=4;Hi(t),r=!1}else null!==ra&&(rd(ra),ra=null),r=!0;if(!r)return 65536&t.flags?t:null}return 128&t.flags?(t.lanes=n,t):((s=null!==s)!==(null!==e&&null!==e.memoizedState)&&s&&(t.child.flags|=8192,1&t.mode&&(null===e||1&er.current?0===Oc&&(Oc=3):fd())),null!==t.updateQueue&&(t.flags|=4),Hi(t),null);case 4:return Za(),Ri(e,t),null===e&&Us(t.stateNode.containerInfo),Hi(t),null;case 10:return Aa(t.type._context),Hi(t),null;case 19:if(Co(er),null===(r=t.memoizedState))return Hi(t),null;if(s=!!(128&t.flags),null===(c=r.rendering))if(s)Vi(r,!1);else{if(0!==Oc||null!==e&&128&e.flags)for(e=t.child;null!==e;){if(null!==(c=tr(e))){for(t.flags|=128,Vi(r,!1),null!==(s=c.updateQueue)&&(t.updateQueue=s,t.flags|=4),t.subtreeFlags=0,s=n,n=t.child;null!==n;)e=s,(r=n).flags&=14680066,null===(c=r.alternate)?(r.childLanes=0,r.lanes=e,r.child=null,r.subtreeFlags=0,r.memoizedProps=null,r.memoizedState=null,r.updateQueue=null,r.dependencies=null,r.stateNode=null):(r.childLanes=c.childLanes,r.lanes=c.lanes,r.child=c.child,r.subtreeFlags=0,r.deletions=null,r.memoizedProps=c.memoizedProps,r.memoizedState=c.memoizedState,r.updateQueue=c.updateQueue,r.type=c.type,e=c.dependencies,r.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return To(er,1&er.current|2),t.child}e=e.sibling}null!==r.tail&&Ze()>Uc&&(t.flags|=128,s=!0,Vi(r,!1),t.lanes=4194304)}else{if(!s)if(null!==(e=tr(c))){if(t.flags|=128,s=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),Vi(r,!0),null===r.tail&&"hidden"===r.tailMode&&!c.alternate&&!aa)return Hi(t),null}else 2*Ze()-r.renderingStartTime>Uc&&1073741824!==n&&(t.flags|=128,s=!0,Vi(r,!1),t.lanes=4194304);r.isBackwards?(c.sibling=t.child,t.child=c):(null!==(n=r.last)?n.sibling=c:t.child=c,r.last=c)}return null!==r.tail?(t=r.tail,r.rendering=t,r.tail=t.sibling,r.renderingStartTime=Ze(),t.sibling=null,n=er.current,To(er,s?1&n|2:1&n),t):(Hi(t),null);case 22:case 23:return ld(),s=null!==t.memoizedState,null!==e&&null!==e.memoizedState!==s&&(t.flags|=8192),s&&1&t.mode?!!(1073741824&Rc)&&(Hi(t),6&t.subtreeFlags&&(t.flags|=8192)):Hi(t),null;case 24:case 25:return null}throw Error(a(156,t.tag))}function Gi(e,t){switch(na(t),t.tag){case 1:return No(t.type)&&Oo(),65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 3:return Za(),Co(Po),Co(jo),sr(),65536&(e=t.flags)&&!(128&e)?(t.flags=-65537&e|128,t):null;case 5:return Ja(t),null;case 13:if(Co(er),null!==(e=t.memoizedState)&&null!==e.dehydrated){if(null===t.alternate)throw Error(a(340));ga()}return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 19:return Co(er),null;case 4:return Za(),null;case 10:return Aa(t.type._context),null;case 22:case 23:return ld(),null;default:return null}}Li=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Ri=function(){},Ni=function(e,t,n,s){var o=e.memoizedProps;if(o!==s){e=t.stateNode,Xa(Ha.current);var a,r=null;switch(n){case"input":o=X(e,o),s=X(e,s),r=[];break;case"select":o=F({},o,{value:void 0}),s=F({},s,{value:void 0}),r=[];break;case"textarea":o=se(e,o),s=se(e,s),r=[];break;default:"function"!=typeof o.onClick&&"function"==typeof s.onClick&&(e.onclick=Js)}for(u in ye(n,s),n=null,o)if(!s.hasOwnProperty(u)&&o.hasOwnProperty(u)&&null!=o[u])if("style"===u){var c=o[u];for(a in c)c.hasOwnProperty(a)&&(n||(n={}),n[a]="")}else"dangerouslySetInnerHTML"!==u&&"children"!==u&&"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&"autoFocus"!==u&&(i.hasOwnProperty(u)?r||(r=[]):(r=r||[]).push(u,null));for(u in s){var d=s[u];if(c=null!=o?o[u]:void 0,s.hasOwnProperty(u)&&d!==c&&(null!=d||null!=c))if("style"===u)if(c){for(a in c)!c.hasOwnProperty(a)||d&&d.hasOwnProperty(a)||(n||(n={}),n[a]="");for(a in d)d.hasOwnProperty(a)&&c[a]!==d[a]&&(n||(n={}),n[a]=d[a])}else n||(r||(r=[]),r.push(u,n)),n=d;else"dangerouslySetInnerHTML"===u?(d=d?d.__html:void 0,c=c?c.__html:void 0,null!=d&&c!==d&&(r=r||[]).push(u,d)):"children"===u?"string"!=typeof d&&"number"!=typeof d||(r=r||[]).push(u,""+d):"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&(i.hasOwnProperty(u)?(null!=d&&"onScroll"===u&&zs("scroll",e),r||c===d||(r=[])):(r=r||[]).push(u,d))}n&&(r=r||[]).push("style",n);var u=r;(t.updateQueue=u)&&(t.flags|=4)}},Oi=function(e,t,n,s){n!==s&&(t.flags|=4)};var Xi=!1,Ki=!1,Zi="function"==typeof WeakSet?WeakSet:Set,Yi=null;function Ji(e,t){var n=e.ref;if(null!==n)if("function"==typeof n)try{n(null)}catch(s){Sd(e,t,s)}else n.current=null}function ec(e,t,n){try{n()}catch(s){Sd(e,t,s)}}var tc=!1;function nc(e,t,n){var s=t.updateQueue;if(null!==(s=null!==s?s.lastEffect:null)){var o=s=s.next;do{if((o.tag&e)===e){var a=o.destroy;o.destroy=void 0,void 0!==a&&ec(t,n,a)}o=o.next}while(o!==s)}}function sc(e,t){if(null!==(t=null!==(t=t.updateQueue)?t.lastEffect:null)){var n=t=t.next;do{if((n.tag&e)===e){var s=n.create;n.destroy=s()}n=n.next}while(n!==t)}}function oc(e){var t=e.ref;if(null!==t){var n=e.stateNode;e.tag,e=n,"function"==typeof t?t(e):t.current=e}}function ac(e){var t=e.alternate;null!==t&&(e.alternate=null,ac(t)),e.child=null,e.deletions=null,e.sibling=null,5===e.tag&&(null!==(t=e.stateNode)&&(delete t[mo],delete t[go],delete t[ho],delete t[bo],delete t[yo])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function rc(e){return 5===e.tag||3===e.tag||4===e.tag}function ic(e){e:for(;;){for(;null===e.sibling;){if(null===e.return||rc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;5!==e.tag&&6!==e.tag&&18!==e.tag;){if(2&e.flags)continue e;if(null===e.child||4===e.tag)continue e;e.child.return=e,e=e.child}if(!(2&e.flags))return e.stateNode}}function cc(e,t,n){var s=e.tag;if(5===s||6===s)e=e.stateNode,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Js));else if(4!==s&&null!==(e=e.child))for(cc(e,t,n),e=e.sibling;null!==e;)cc(e,t,n),e=e.sibling}function dc(e,t,n){var s=e.tag;if(5===s||6===s)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==s&&null!==(e=e.child))for(dc(e,t,n),e=e.sibling;null!==e;)dc(e,t,n),e=e.sibling}var uc=null,lc=!1;function pc(e,t,n){for(n=n.child;null!==n;)mc(e,t,n),n=n.sibling}function mc(e,t,n){if(at&&"function"==typeof at.onCommitFiberUnmount)try{at.onCommitFiberUnmount(ot,n)}catch(i){}switch(n.tag){case 5:Ki||Ji(n,t);case 6:var s=uc,o=lc;uc=null,pc(e,t,n),lc=o,null!==(uc=s)&&(lc?(e=uc,n=n.stateNode,8===e.nodeType?e.parentNode.removeChild(n):e.removeChild(n)):uc.removeChild(n.stateNode));break;case 18:null!==uc&&(lc?(e=uc,n=n.stateNode,8===e.nodeType?co(e.parentNode,n):1===e.nodeType&&co(e,n),Ut(e)):co(uc,n.stateNode));break;case 4:s=uc,o=lc,uc=n.stateNode.containerInfo,lc=!0,pc(e,t,n),uc=s,lc=o;break;case 0:case 11:case 14:case 15:if(!Ki&&(null!==(s=n.updateQueue)&&null!==(s=s.lastEffect))){o=s=s.next;do{var a=o,r=a.destroy;a=a.tag,void 0!==r&&(2&a||4&a)&&ec(n,t,r),o=o.next}while(o!==s)}pc(e,t,n);break;case 1:if(!Ki&&(Ji(n,t),"function"==typeof(s=n.stateNode).componentWillUnmount))try{s.props=n.memoizedProps,s.state=n.memoizedState,s.componentWillUnmount()}catch(i){Sd(n,t,i)}pc(e,t,n);break;case 21:pc(e,t,n);break;case 22:1&n.mode?(Ki=(s=Ki)||null!==n.memoizedState,pc(e,t,n),Ki=s):pc(e,t,n);break;default:pc(e,t,n)}}function gc(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new Zi),t.forEach((function(t){var s=Ad.bind(null,e,t);n.has(t)||(n.add(t),t.then(s,s))}))}}function fc(e,t){var n=t.deletions;if(null!==n)for(var s=0;s<n.length;s++){var o=n[s];try{var r=e,i=t,c=i;e:for(;null!==c;){switch(c.tag){case 5:uc=c.stateNode,lc=!1;break e;case 3:case 4:uc=c.stateNode.containerInfo,lc=!0;break e}c=c.return}if(null===uc)throw Error(a(160));mc(r,i,o),uc=null,lc=!1;var d=o.alternate;null!==d&&(d.return=null),o.return=null}catch(u){Sd(o,t,u)}}if(12854&t.subtreeFlags)for(t=t.child;null!==t;)hc(t,e),t=t.sibling}function hc(e,t){var n=e.alternate,s=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(fc(t,e),bc(e),4&s){try{nc(3,e,e.return),sc(3,e)}catch(h){Sd(e,e.return,h)}try{nc(5,e,e.return)}catch(h){Sd(e,e.return,h)}}break;case 1:fc(t,e),bc(e),512&s&&null!==n&&Ji(n,n.return);break;case 5:if(fc(t,e),bc(e),512&s&&null!==n&&Ji(n,n.return),32&e.flags){var o=e.stateNode;try{pe(o,"")}catch(h){Sd(e,e.return,h)}}if(4&s&&null!=(o=e.stateNode)){var r=e.memoizedProps,i=null!==n?n.memoizedProps:r,c=e.type,d=e.updateQueue;if(e.updateQueue=null,null!==d)try{"input"===c&&"radio"===r.type&&null!=r.name&&Z(o,r),ve(c,i);var u=ve(c,r);for(i=0;i<d.length;i+=2){var l=d[i],p=d[i+1];"style"===l?he(o,p):"dangerouslySetInnerHTML"===l?le(o,p):"children"===l?pe(o,p):v(o,l,p,u)}switch(c){case"input":Y(o,r);break;case"textarea":ae(o,r);break;case"select":var m=o._wrapperState.wasMultiple;o._wrapperState.wasMultiple=!!r.multiple;var g=r.value;null!=g?ne(o,!!r.multiple,g,!1):m!==!!r.multiple&&(null!=r.defaultValue?ne(o,!!r.multiple,r.defaultValue,!0):ne(o,!!r.multiple,r.multiple?[]:"",!1))}o[go]=r}catch(h){Sd(e,e.return,h)}}break;case 6:if(fc(t,e),bc(e),4&s){if(null===e.stateNode)throw Error(a(162));o=e.stateNode,r=e.memoizedProps;try{o.nodeValue=r}catch(h){Sd(e,e.return,h)}}break;case 3:if(fc(t,e),bc(e),4&s&&null!==n&&n.memoizedState.isDehydrated)try{Ut(t.containerInfo)}catch(h){Sd(e,e.return,h)}break;case 4:default:fc(t,e),bc(e);break;case 13:fc(t,e),bc(e),8192&(o=e.child).flags&&(r=null!==o.memoizedState,o.stateNode.isHidden=r,!r||null!==o.alternate&&null!==o.alternate.memoizedState||($c=Ze())),4&s&&gc(e);break;case 22:if(l=null!==n&&null!==n.memoizedState,1&e.mode?(Ki=(u=Ki)||l,fc(t,e),Ki=u):fc(t,e),bc(e),8192&s){if(u=null!==e.memoizedState,(e.stateNode.isHidden=u)&&!l&&1&e.mode)for(Yi=e,l=e.child;null!==l;){for(p=Yi=l;null!==Yi;){switch(g=(m=Yi).child,m.tag){case 0:case 11:case 14:case 15:nc(4,m,m.return);break;case 1:Ji(m,m.return);var f=m.stateNode;if("function"==typeof f.componentWillUnmount){s=m,n=m.return;try{t=s,f.props=t.memoizedProps,f.state=t.memoizedState,f.componentWillUnmount()}catch(h){Sd(s,n,h)}}break;case 5:Ji(m,m.return);break;case 22:if(null!==m.memoizedState){xc(p);continue}}null!==g?(g.return=m,Yi=g):xc(p)}l=l.sibling}e:for(l=null,p=e;;){if(5===p.tag){if(null===l){l=p;try{o=p.stateNode,u?"function"==typeof(r=o.style).setProperty?r.setProperty("display","none","important"):r.display="none":(c=p.stateNode,i=null!=(d=p.memoizedProps.style)&&d.hasOwnProperty("display")?d.display:null,c.style.display=fe("display",i))}catch(h){Sd(e,e.return,h)}}}else if(6===p.tag){if(null===l)try{p.stateNode.nodeValue=u?"":p.memoizedProps}catch(h){Sd(e,e.return,h)}}else if((22!==p.tag&&23!==p.tag||null===p.memoizedState||p===e)&&null!==p.child){p.child.return=p,p=p.child;continue}if(p===e)break e;for(;null===p.sibling;){if(null===p.return||p.return===e)break e;l===p&&(l=null),p=p.return}l===p&&(l=null),p.sibling.return=p.return,p=p.sibling}}break;case 19:fc(t,e),bc(e),4&s&&gc(e);case 21:}}function bc(e){var t=e.flags;if(2&t){try{e:{for(var n=e.return;null!==n;){if(rc(n)){var s=n;break e}n=n.return}throw Error(a(160))}switch(s.tag){case 5:var o=s.stateNode;32&s.flags&&(pe(o,""),s.flags&=-33),dc(e,ic(e),o);break;case 3:case 4:var r=s.stateNode.containerInfo;cc(e,ic(e),r);break;default:throw Error(a(161))}}catch(i){Sd(e,e.return,i)}e.flags&=-3}4096&t&&(e.flags&=-4097)}function yc(e,t,n){Yi=e,vc(e,t,n)}function vc(e,t,n){for(var s=!!(1&e.mode);null!==Yi;){var o=Yi,a=o.child;if(22===o.tag&&s){var r=null!==o.memoizedState||Xi;if(!r){var i=o.alternate,c=null!==i&&null!==i.memoizedState||Ki;i=Xi;var d=Ki;if(Xi=r,(Ki=c)&&!d)for(Yi=o;null!==Yi;)c=(r=Yi).child,22===r.tag&&null!==r.memoizedState?wc(o):null!==c?(c.return=r,Yi=c):wc(o);for(;null!==a;)Yi=a,vc(a,t,n),a=a.sibling;Yi=o,Xi=i,Ki=d}kc(e)}else 8772&o.subtreeFlags&&null!==a?(a.return=o,Yi=a):kc(e)}}function kc(e){for(;null!==Yi;){var t=Yi;if(8772&t.flags){var n=t.alternate;try{if(8772&t.flags)switch(t.tag){case 0:case 11:case 15:Ki||sc(5,t);break;case 1:var s=t.stateNode;if(4&t.flags&&!Ki)if(null===n)s.componentDidMount();else{var o=t.elementType===t.type?n.memoizedProps:ni(t.type,n.memoizedProps);s.componentDidUpdate(o,n.memoizedState,s.__reactInternalSnapshotBeforeUpdate)}var r=t.updateQueue;null!==r&&Qa(t,r,s);break;case 3:var i=t.updateQueue;if(null!==i){if(n=null,null!==t.child)switch(t.child.tag){case 5:case 1:n=t.child.stateNode}Qa(t,i,n)}break;case 5:var c=t.stateNode;if(null===n&&4&t.flags){n=c;var d=t.memoizedProps;switch(t.type){case"button":case"input":case"select":case"textarea":d.autoFocus&&n.focus();break;case"img":d.src&&(n.src=d.src)}}break;case 6:case 4:case 12:case 19:case 17:case 21:case 22:case 23:case 25:break;case 13:if(null===t.memoizedState){var u=t.alternate;if(null!==u){var l=u.memoizedState;if(null!==l){var p=l.dehydrated;null!==p&&Ut(p)}}}break;default:throw Error(a(163))}Ki||512&t.flags&&oc(t)}catch(m){Sd(t,t.return,m)}}if(t===e){Yi=null;break}if(null!==(n=t.sibling)){n.return=t.return,Yi=n;break}Yi=t.return}}function xc(e){for(;null!==Yi;){var t=Yi;if(t===e){Yi=null;break}var n=t.sibling;if(null!==n){n.return=t.return,Yi=n;break}Yi=t.return}}function wc(e){for(;null!==Yi;){var t=Yi;try{switch(t.tag){case 0:case 11:case 15:var n=t.return;try{sc(4,t)}catch(c){Sd(t,n,c)}break;case 1:var s=t.stateNode;if("function"==typeof s.componentDidMount){var o=t.return;try{s.componentDidMount()}catch(c){Sd(t,o,c)}}var a=t.return;try{oc(t)}catch(c){Sd(t,a,c)}break;case 5:var r=t.return;try{oc(t)}catch(c){Sd(t,r,c)}}}catch(c){Sd(t,t.return,c)}if(t===e){Yi=null;break}var i=t.sibling;if(null!==i){i.return=t.return,Yi=i;break}Yi=t.return}}var _c,Sc=Math.ceil,Ec=k.ReactCurrentDispatcher,Cc=k.ReactCurrentOwner,Tc=k.ReactCurrentBatchConfig,Ac=0,jc=null,Pc=null,Lc=0,Rc=0,Nc=Eo(0),Oc=0,Ic=null,Dc=0,Fc=0,Mc=0,zc=null,Bc=null,$c=0,Uc=1/0,qc=null,Qc=!1,Vc=null,Hc=null,Wc=!1,Gc=null,Xc=0,Kc=0,Zc=null,Yc=-1,Jc=0;function ed(){return 6&Ac?Ze():-1!==Yc?Yc:Yc=Ze()}function td(e){return 1&e.mode?2&Ac&&0!==Lc?Lc&-Lc:null!==ha.transition?(0===Jc&&(Jc=ft()),Jc):0!==(e=vt)?e:e=void 0===(e=window.event)?16:Kt(e.type):1}function nd(e,t,n,s){if(50<Kc)throw Kc=0,Zc=null,Error(a(185));bt(e,n,s),2&Ac&&e===jc||(e===jc&&(!(2&Ac)&&(Fc|=n),4===Oc&&id(e,Lc)),sd(e,s),1===n&&0===Ac&&!(1&t.mode)&&(Uc=Ze()+500,Bo&&qo()))}function sd(e,t){var n=e.callbackNode;!function(e,t){for(var n=e.suspendedLanes,s=e.pingedLanes,o=e.expirationTimes,a=e.pendingLanes;0<a;){var r=31-rt(a),i=1<<r,c=o[r];-1===c?i&n&&!(i&s)||(o[r]=mt(i,t)):c<=t&&(e.expiredLanes|=i),a&=~i}}(e,t);var s=pt(e,e===jc?Lc:0);if(0===s)null!==n&&Ge(n),e.callbackNode=null,e.callbackPriority=0;else if(t=s&-s,e.callbackPriority!==t){if(null!=n&&Ge(n),1===t)0===e.tag?function(e){Bo=!0,Uo(e)}(cd.bind(null,e)):Uo(cd.bind(null,e)),ro((function(){!(6&Ac)&&qo()})),n=null;else{switch(kt(s)){case 1:n=Je;break;case 4:n=et;break;case 16:default:n=tt;break;case 536870912:n=st}n=jd(n,od.bind(null,e))}e.callbackPriority=t,e.callbackNode=n}}function od(e,t){if(Yc=-1,Jc=0,6&Ac)throw Error(a(327));var n=e.callbackNode;if(wd()&&e.callbackNode!==n)return null;var s=pt(e,e===jc?Lc:0);if(0===s)return null;if(30&s||s&e.expiredLanes||t)t=hd(e,s);else{t=s;var o=Ac;Ac|=2;var r=gd();for(jc===e&&Lc===t||(qc=null,Uc=Ze()+500,pd(e,t));;)try{yd();break}catch(c){md(e,c)}Ta(),Ec.current=r,Ac=o,null!==Pc?t=0:(jc=null,Lc=0,t=Oc)}if(0!==t){if(2===t&&(0!==(o=gt(e))&&(s=o,t=ad(e,o))),1===t)throw n=Ic,pd(e,0),id(e,s),sd(e,Ze()),n;if(6===t)id(e,s);else{if(o=e.current.alternate,!(30&s||function(e){for(var t=e;;){if(16384&t.flags){var n=t.updateQueue;if(null!==n&&null!==(n=n.stores))for(var s=0;s<n.length;s++){var o=n[s],a=o.getSnapshot;o=o.value;try{if(!is(a(),o))return!1}catch(i){return!1}}}if(n=t.child,16384&t.subtreeFlags&&null!==n)n.return=t,t=n;else{if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}(o)||(t=hd(e,s),2===t&&(r=gt(e),0!==r&&(s=r,t=ad(e,r))),1!==t)))throw n=Ic,pd(e,0),id(e,s),sd(e,Ze()),n;switch(e.finishedWork=o,e.finishedLanes=s,t){case 0:case 1:throw Error(a(345));case 2:case 5:xd(e,Bc,qc);break;case 3:if(id(e,s),(130023424&s)===s&&10<(t=$c+500-Ze())){if(0!==pt(e,0))break;if(((o=e.suspendedLanes)&s)!==s){ed(),e.pingedLanes|=e.suspendedLanes&o;break}e.timeoutHandle=so(xd.bind(null,e,Bc,qc),t);break}xd(e,Bc,qc);break;case 4:if(id(e,s),(4194240&s)===s)break;for(t=e.eventTimes,o=-1;0<s;){var i=31-rt(s);r=1<<i,(i=t[i])>o&&(o=i),s&=~r}if(s=o,10<(s=(120>(s=Ze()-s)?120:480>s?480:1080>s?1080:1920>s?1920:3e3>s?3e3:4320>s?4320:1960*Sc(s/1960))-s)){e.timeoutHandle=so(xd.bind(null,e,Bc,qc),s);break}xd(e,Bc,qc);break;default:throw Error(a(329))}}}return sd(e,Ze()),e.callbackNode===n?od.bind(null,e):null}function ad(e,t){var n=zc;return e.current.memoizedState.isDehydrated&&(pd(e,t).flags|=256),2!==(e=hd(e,t))&&(t=Bc,Bc=n,null!==t&&rd(t)),e}function rd(e){null===Bc?Bc=e:Bc.push.apply(Bc,e)}function id(e,t){for(t&=~Mc,t&=~Fc,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-rt(t),s=1<<n;e[n]=-1,t&=~s}}function cd(e){if(6&Ac)throw Error(a(327));wd();var t=pt(e,0);if(!(1&t))return sd(e,Ze()),null;var n=hd(e,t);if(0!==e.tag&&2===n){var s=gt(e);0!==s&&(t=s,n=ad(e,s))}if(1===n)throw n=Ic,pd(e,0),id(e,t),sd(e,Ze()),n;if(6===n)throw Error(a(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,xd(e,Bc,qc),sd(e,Ze()),null}function dd(e,t){var n=Ac;Ac|=1;try{return e(t)}finally{0===(Ac=n)&&(Uc=Ze()+500,Bo&&qo())}}function ud(e){null!==Gc&&0===Gc.tag&&!(6&Ac)&&wd();var t=Ac;Ac|=1;var n=Tc.transition,s=vt;try{if(Tc.transition=null,vt=1,e)return e()}finally{vt=s,Tc.transition=n,!(6&(Ac=t))&&qo()}}function ld(){Rc=Nc.current,Co(Nc)}function pd(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,oo(n)),null!==Pc)for(n=Pc.return;null!==n;){var s=n;switch(na(s),s.tag){case 1:null!=(s=s.type.childContextTypes)&&Oo();break;case 3:Za(),Co(Po),Co(jo),sr();break;case 5:Ja(s);break;case 4:Za();break;case 13:case 19:Co(er);break;case 10:Aa(s.type._context);break;case 22:case 23:ld()}n=n.return}if(jc=e,Pc=e=Nd(e.current,null),Lc=Rc=t,Oc=0,Ic=null,Mc=Fc=Dc=0,Bc=zc=null,null!==Ra){for(t=0;t<Ra.length;t++)if(null!==(s=(n=Ra[t]).interleaved)){n.interleaved=null;var o=s.next,a=n.pending;if(null!==a){var r=a.next;a.next=o,s.next=r}n.pending=s}Ra=null}return e}function md(e,t){for(;;){var n=Pc;try{if(Ta(),or.current=Yr,ur){for(var s=ir.memoizedState;null!==s;){var o=s.queue;null!==o&&(o.pending=null),s=s.next}ur=!1}if(rr=0,dr=cr=ir=null,lr=!1,pr=0,Cc.current=null,null===n||null===n.return){Oc=1,Ic=t,Pc=null;break}e:{var r=e,i=n.return,c=n,d=t;if(t=Lc,c.flags|=32768,null!==d&&"object"==typeof d&&"function"==typeof d.then){var u=d,l=c,p=l.tag;if(!(1&l.mode||0!==p&&11!==p&&15!==p)){var m=l.alternate;m?(l.updateQueue=m.updateQueue,l.memoizedState=m.memoizedState,l.lanes=m.lanes):(l.updateQueue=null,l.memoizedState=null)}var g=hi(i);if(null!==g){g.flags&=-257,bi(g,i,c,0,t),1&g.mode&&fi(r,u,t),d=u;var f=(t=g).updateQueue;if(null===f){var h=new Set;h.add(d),t.updateQueue=h}else f.add(d);break e}if(!(1&t)){fi(r,u,t),fd();break e}d=Error(a(426))}else if(aa&&1&c.mode){var b=hi(i);if(null!==b){!(65536&b.flags)&&(b.flags|=256),bi(b,i,c,0,t),fa(di(d,c));break e}}r=d=di(d,c),4!==Oc&&(Oc=2),null===zc?zc=[r]:zc.push(r),r=i;do{switch(r.tag){case 3:r.flags|=65536,t&=-t,r.lanes|=t,Ua(r,mi(0,d,t));break e;case 1:c=d;var y=r.type,v=r.stateNode;if(!(128&r.flags||"function"!=typeof y.getDerivedStateFromError&&(null===v||"function"!=typeof v.componentDidCatch||null!==Hc&&Hc.has(v)))){r.flags|=65536,t&=-t,r.lanes|=t,Ua(r,gi(r,c,t));break e}}r=r.return}while(null!==r)}kd(n)}catch(k){t=k,Pc===n&&null!==n&&(Pc=n=n.return);continue}break}}function gd(){var e=Ec.current;return Ec.current=Yr,null===e?Yr:e}function fd(){0!==Oc&&3!==Oc&&2!==Oc||(Oc=4),null===jc||!(268435455&Dc)&&!(268435455&Fc)||id(jc,Lc)}function hd(e,t){var n=Ac;Ac|=2;var s=gd();for(jc===e&&Lc===t||(qc=null,pd(e,t));;)try{bd();break}catch(o){md(e,o)}if(Ta(),Ac=n,Ec.current=s,null!==Pc)throw Error(a(261));return jc=null,Lc=0,Oc}function bd(){for(;null!==Pc;)vd(Pc)}function yd(){for(;null!==Pc&&!Xe();)vd(Pc)}function vd(e){var t=_c(e.alternate,e,Rc);e.memoizedProps=e.pendingProps,null===t?kd(e):Pc=t,Cc.current=null}function kd(e){var t=e;do{var n=t.alternate;if(e=t.return,32768&t.flags){if(null!==(n=Gi(n,t)))return n.flags&=32767,void(Pc=n);if(null===e)return Oc=6,void(Pc=null);e.flags|=32768,e.subtreeFlags=0,e.deletions=null}else if(null!==(n=Wi(n,t,Rc)))return void(Pc=n);if(null!==(t=t.sibling))return void(Pc=t);Pc=t=e}while(null!==t);0===Oc&&(Oc=5)}function xd(e,t,n){var s=vt,o=Tc.transition;try{Tc.transition=null,vt=1,function(e,t,n,s){do{wd()}while(null!==Gc);if(6&Ac)throw Error(a(327));n=e.finishedWork;var o=e.finishedLanes;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(a(177));e.callbackNode=null,e.callbackPriority=0;var r=n.lanes|n.childLanes;if(function(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var s=e.eventTimes;for(e=e.expirationTimes;0<n;){var o=31-rt(n),a=1<<o;t[o]=0,s[o]=-1,e[o]=-1,n&=~a}}(e,r),e===jc&&(Pc=jc=null,Lc=0),!(2064&n.subtreeFlags)&&!(2064&n.flags)||Wc||(Wc=!0,jd(tt,(function(){return wd(),null}))),r=!!(15990&n.flags),!!(15990&n.subtreeFlags)||r){r=Tc.transition,Tc.transition=null;var i=vt;vt=1;var c=Ac;Ac|=4,Cc.current=null,function(e,t){if(eo=Qt,ms(e=ps())){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{var s=(n=(n=e.ownerDocument)&&n.defaultView||window).getSelection&&n.getSelection();if(s&&0!==s.rangeCount){n=s.anchorNode;var o=s.anchorOffset,r=s.focusNode;s=s.focusOffset;try{n.nodeType,r.nodeType}catch(x){n=null;break e}var i=0,c=-1,d=-1,u=0,l=0,p=e,m=null;t:for(;;){for(var g;p!==n||0!==o&&3!==p.nodeType||(c=i+o),p!==r||0!==s&&3!==p.nodeType||(d=i+s),3===p.nodeType&&(i+=p.nodeValue.length),null!==(g=p.firstChild);)m=p,p=g;for(;;){if(p===e)break t;if(m===n&&++u===o&&(c=i),m===r&&++l===s&&(d=i),null!==(g=p.nextSibling))break;m=(p=m).parentNode}p=g}n=-1===c||-1===d?null:{start:c,end:d}}else n=null}n=n||{start:0,end:0}}else n=null;for(to={focusedElem:e,selectionRange:n},Qt=!1,Yi=t;null!==Yi;)if(e=(t=Yi).child,1028&t.subtreeFlags&&null!==e)e.return=t,Yi=e;else for(;null!==Yi;){t=Yi;try{var f=t.alternate;if(1024&t.flags)switch(t.tag){case 0:case 11:case 15:case 5:case 6:case 4:case 17:break;case 1:if(null!==f){var h=f.memoizedProps,b=f.memoizedState,y=t.stateNode,v=y.getSnapshotBeforeUpdate(t.elementType===t.type?h:ni(t.type,h),b);y.__reactInternalSnapshotBeforeUpdate=v}break;case 3:var k=t.stateNode.containerInfo;1===k.nodeType?k.textContent="":9===k.nodeType&&k.documentElement&&k.removeChild(k.documentElement);break;default:throw Error(a(163))}}catch(x){Sd(t,t.return,x)}if(null!==(e=t.sibling)){e.return=t.return,Yi=e;break}Yi=t.return}f=tc,tc=!1}(e,n),hc(n,e),gs(to),Qt=!!eo,to=eo=null,e.current=n,yc(n,e,o),Ke(),Ac=c,vt=i,Tc.transition=r}else e.current=n;if(Wc&&(Wc=!1,Gc=e,Xc=o),r=e.pendingLanes,0===r&&(Hc=null),function(e){if(at&&"function"==typeof at.onCommitFiberRoot)try{at.onCommitFiberRoot(ot,e,void 0,!(128&~e.current.flags))}catch(t){}}(n.stateNode),sd(e,Ze()),null!==t)for(s=e.onRecoverableError,n=0;n<t.length;n++)o=t[n],s(o.value,{componentStack:o.stack,digest:o.digest});if(Qc)throw Qc=!1,e=Vc,Vc=null,e;!!(1&Xc)&&0!==e.tag&&wd(),r=e.pendingLanes,1&r?e===Zc?Kc++:(Kc=0,Zc=e):Kc=0,qo()}(e,t,n,s)}finally{Tc.transition=o,vt=s}return null}function wd(){if(null!==Gc){var e=kt(Xc),t=Tc.transition,n=vt;try{if(Tc.transition=null,vt=16>e?16:e,null===Gc)var s=!1;else{if(e=Gc,Gc=null,Xc=0,6&Ac)throw Error(a(331));var o=Ac;for(Ac|=4,Yi=e.current;null!==Yi;){var r=Yi,i=r.child;if(16&Yi.flags){var c=r.deletions;if(null!==c){for(var d=0;d<c.length;d++){var u=c[d];for(Yi=u;null!==Yi;){var l=Yi;switch(l.tag){case 0:case 11:case 15:nc(8,l,r)}var p=l.child;if(null!==p)p.return=l,Yi=p;else for(;null!==Yi;){var m=(l=Yi).sibling,g=l.return;if(ac(l),l===u){Yi=null;break}if(null!==m){m.return=g,Yi=m;break}Yi=g}}}var f=r.alternate;if(null!==f){var h=f.child;if(null!==h){f.child=null;do{var b=h.sibling;h.sibling=null,h=b}while(null!==h)}}Yi=r}}if(2064&r.subtreeFlags&&null!==i)i.return=r,Yi=i;else e:for(;null!==Yi;){if(2048&(r=Yi).flags)switch(r.tag){case 0:case 11:case 15:nc(9,r,r.return)}var y=r.sibling;if(null!==y){y.return=r.return,Yi=y;break e}Yi=r.return}}var v=e.current;for(Yi=v;null!==Yi;){var k=(i=Yi).child;if(2064&i.subtreeFlags&&null!==k)k.return=i,Yi=k;else e:for(i=v;null!==Yi;){if(2048&(c=Yi).flags)try{switch(c.tag){case 0:case 11:case 15:sc(9,c)}}catch(w){Sd(c,c.return,w)}if(c===i){Yi=null;break e}var x=c.sibling;if(null!==x){x.return=c.return,Yi=x;break e}Yi=c.return}}if(Ac=o,qo(),at&&"function"==typeof at.onPostCommitFiberRoot)try{at.onPostCommitFiberRoot(ot,e)}catch(w){}s=!0}return s}finally{vt=n,Tc.transition=t}}return!1}function _d(e,t,n){e=Ba(e,t=mi(0,t=di(n,t),1),1),t=ed(),null!==e&&(bt(e,1,t),sd(e,t))}function Sd(e,t,n){if(3===e.tag)_d(e,e,n);else for(;null!==t;){if(3===t.tag){_d(t,e,n);break}if(1===t.tag){var s=t.stateNode;if("function"==typeof t.type.getDerivedStateFromError||"function"==typeof s.componentDidCatch&&(null===Hc||!Hc.has(s))){t=Ba(t,e=gi(t,e=di(n,e),1),1),e=ed(),null!==t&&(bt(t,1,e),sd(t,e));break}}t=t.return}}function Ed(e,t,n){var s=e.pingCache;null!==s&&s.delete(t),t=ed(),e.pingedLanes|=e.suspendedLanes&n,jc===e&&(Lc&n)===n&&(4===Oc||3===Oc&&(130023424&Lc)===Lc&&500>Ze()-$c?pd(e,0):Mc|=n),sd(e,t)}function Cd(e,t){0===t&&(1&e.mode?(t=ut,!(130023424&(ut<<=1))&&(ut=4194304)):t=1);var n=ed();null!==(e=Ia(e,t))&&(bt(e,t,n),sd(e,n))}function Td(e){var t=e.memoizedState,n=0;null!==t&&(n=t.retryLane),Cd(e,n)}function Ad(e,t){var n=0;switch(e.tag){case 13:var s=e.stateNode,o=e.memoizedState;null!==o&&(n=o.retryLane);break;case 19:s=e.stateNode;break;default:throw Error(a(314))}null!==s&&s.delete(t),Cd(e,n)}function jd(e,t){return We(e,t)}function Pd(e,t,n,s){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=s,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Ld(e,t,n,s){return new Pd(e,t,n,s)}function Rd(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Nd(e,t){var n=e.alternate;return null===n?((n=Ld(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=14680064&e.flags,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Od(e,t,n,s,o,r){var i=2;if(s=e,"function"==typeof e)Rd(e)&&(i=1);else if("string"==typeof e)i=5;else e:switch(e){case _:return Id(n.children,o,r,t);case S:i=8,o|=8;break;case E:return(e=Ld(12,n,t,2|o)).elementType=E,e.lanes=r,e;case j:return(e=Ld(13,n,t,o)).elementType=j,e.lanes=r,e;case P:return(e=Ld(19,n,t,o)).elementType=P,e.lanes=r,e;case N:return Dd(n,o,r,t);default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case C:i=10;break e;case T:i=9;break e;case A:i=11;break e;case L:i=14;break e;case R:i=16,s=null;break e}throw Error(a(130,null==e?e:typeof e,""))}return(t=Ld(i,n,t,o)).elementType=e,t.type=s,t.lanes=r,t}function Id(e,t,n,s){return(e=Ld(7,e,s,t)).lanes=n,e}function Dd(e,t,n,s){return(e=Ld(22,e,s,t)).elementType=N,e.lanes=n,e.stateNode={isHidden:!1},e}function Fd(e,t,n){return(e=Ld(6,e,null,t)).lanes=n,e}function Md(e,t,n){return(t=Ld(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function zd(e,t,n,s,o){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=ht(0),this.expirationTimes=ht(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=ht(0),this.identifierPrefix=s,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function Bd(e,t,n,s,o,a,r,i,c){return e=new zd(e,t,n,i,c),1===t?(t=1,!0===a&&(t|=8)):t=0,a=Ld(3,null,null,t),e.current=a,a.stateNode=e,a.memoizedState={element:s,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Fa(a),e}function $d(e){if(!e)return Ao;e:{if(Ue(e=e._reactInternals)!==e||1!==e.tag)throw Error(a(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(No(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(null!==t);throw Error(a(171))}if(1===e.tag){var n=e.type;if(No(n))return Do(e,n,t)}return t}function Ud(e,t,n,s,o,a,r,i,c){return(e=Bd(n,s,!0,e,0,a,0,i,c)).context=$d(null),n=e.current,(a=za(s=ed(),o=td(n))).callback=null!=t?t:null,Ba(n,a,o),e.current.lanes=o,bt(e,o,s),sd(e,s),e}function qd(e,t,n,s){var o=t.current,a=ed(),r=td(o);return n=$d(n),null===t.context?t.context=n:t.pendingContext=n,(t=za(a,r)).payload={element:e},null!==(s=void 0===s?null:s)&&(t.callback=s),null!==(e=Ba(o,t,r))&&(nd(e,o,r,a),$a(e,o,r)),r}function Qd(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function Vd(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function Hd(e,t){Vd(e,t),(e=e.alternate)&&Vd(e,t)}_c=function(e,t,n){if(null!==e)if(e.memoizedProps!==t.pendingProps||Po.current)vi=!0;else{if(!(e.lanes&n||128&t.flags))return vi=!1,function(e,t,n){switch(t.tag){case 3:ji(t),ga();break;case 5:Ya(t);break;case 1:No(t.type)&&Fo(t);break;case 4:Ka(t,t.stateNode.containerInfo);break;case 10:var s=t.type._context,o=t.memoizedProps.value;To(_a,s._currentValue),s._currentValue=o;break;case 13:if(null!==(s=t.memoizedState))return null!==s.dehydrated?(To(er,1&er.current),t.flags|=128,null):n&t.child.childLanes?Fi(e,t,n):(To(er,1&er.current),null!==(e=Qi(e,t,n))?e.sibling:null);To(er,1&er.current);break;case 19:if(s=!!(n&t.childLanes),128&e.flags){if(s)return Ui(e,t,n);t.flags|=128}if(null!==(o=t.memoizedState)&&(o.rendering=null,o.tail=null,o.lastEffect=null),To(er,er.current),s)break;return null;case 22:case 23:return t.lanes=0,Si(e,t,n)}return Qi(e,t,n)}(e,t,n);vi=!!(131072&e.flags)}else vi=!1,aa&&1048576&t.flags&&ea(t,Wo,t.index);switch(t.lanes=0,t.tag){case 2:var s=t.type;qi(e,t),e=t.pendingProps;var o=Ro(t,jo.current);Pa(t,n),o=hr(null,t,s,e,o,n);var r=br();return t.flags|=1,"object"==typeof o&&null!==o&&"function"==typeof o.render&&void 0===o.$$typeof?(t.tag=1,t.memoizedState=null,t.updateQueue=null,No(s)?(r=!0,Fo(t)):r=!1,t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,Fa(t),o.updater=oi,t.stateNode=o,o._reactInternals=t,ci(t,s,e,n),t=Ai(null,t,s,!0,r,n)):(t.tag=0,aa&&r&&ta(t),ki(null,t,o,n),t=t.child),t;case 16:s=t.elementType;e:{switch(qi(e,t),e=t.pendingProps,s=(o=s._init)(s._payload),t.type=s,o=t.tag=function(e){if("function"==typeof e)return Rd(e)?1:0;if(null!=e){if((e=e.$$typeof)===A)return 11;if(e===L)return 14}return 2}(s),e=ni(s,e),o){case 0:t=Ci(null,t,s,e,n);break e;case 1:t=Ti(null,t,s,e,n);break e;case 11:t=xi(null,t,s,e,n);break e;case 14:t=wi(null,t,s,ni(s.type,e),n);break e}throw Error(a(306,s,""))}return t;case 0:return s=t.type,o=t.pendingProps,Ci(e,t,s,o=t.elementType===s?o:ni(s,o),n);case 1:return s=t.type,o=t.pendingProps,Ti(e,t,s,o=t.elementType===s?o:ni(s,o),n);case 3:e:{if(ji(t),null===e)throw Error(a(387));s=t.pendingProps,o=(r=t.memoizedState).element,Ma(e,t),qa(t,s,null,n);var i=t.memoizedState;if(s=i.element,r.isDehydrated){if(r={element:s,isDehydrated:!1,cache:i.cache,pendingSuspenseBoundaries:i.pendingSuspenseBoundaries,transitions:i.transitions},t.updateQueue.baseState=r,t.memoizedState=r,256&t.flags){t=Pi(e,t,s,n,o=di(Error(a(423)),t));break e}if(s!==o){t=Pi(e,t,s,n,o=di(Error(a(424)),t));break e}for(oa=uo(t.stateNode.containerInfo.firstChild),sa=t,aa=!0,ra=null,n=wa(t,null,s,n),t.child=n;n;)n.flags=-3&n.flags|4096,n=n.sibling}else{if(ga(),s===o){t=Qi(e,t,n);break e}ki(e,t,s,n)}t=t.child}return t;case 5:return Ya(t),null===e&&ua(t),s=t.type,o=t.pendingProps,r=null!==e?e.memoizedProps:null,i=o.children,no(s,o)?i=null:null!==r&&no(s,r)&&(t.flags|=32),Ei(e,t),ki(e,t,i,n),t.child;case 6:return null===e&&ua(t),null;case 13:return Fi(e,t,n);case 4:return Ka(t,t.stateNode.containerInfo),s=t.pendingProps,null===e?t.child=xa(t,null,s,n):ki(e,t,s,n),t.child;case 11:return s=t.type,o=t.pendingProps,xi(e,t,s,o=t.elementType===s?o:ni(s,o),n);case 7:return ki(e,t,t.pendingProps,n),t.child;case 8:case 12:return ki(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(s=t.type._context,o=t.pendingProps,r=t.memoizedProps,i=o.value,To(_a,s._currentValue),s._currentValue=i,null!==r)if(is(r.value,i)){if(r.children===o.children&&!Po.current){t=Qi(e,t,n);break e}}else for(null!==(r=t.child)&&(r.return=t);null!==r;){var c=r.dependencies;if(null!==c){i=r.child;for(var d=c.firstContext;null!==d;){if(d.context===s){if(1===r.tag){(d=za(-1,n&-n)).tag=2;var u=r.updateQueue;if(null!==u){var l=(u=u.shared).pending;null===l?d.next=d:(d.next=l.next,l.next=d),u.pending=d}}r.lanes|=n,null!==(d=r.alternate)&&(d.lanes|=n),ja(r.return,n,t),c.lanes|=n;break}d=d.next}}else if(10===r.tag)i=r.type===t.type?null:r.child;else if(18===r.tag){if(null===(i=r.return))throw Error(a(341));i.lanes|=n,null!==(c=i.alternate)&&(c.lanes|=n),ja(i,n,t),i=r.sibling}else i=r.child;if(null!==i)i.return=r;else for(i=r;null!==i;){if(i===t){i=null;break}if(null!==(r=i.sibling)){r.return=i.return,i=r;break}i=i.return}r=i}ki(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,s=t.pendingProps.children,Pa(t,n),s=s(o=La(o)),t.flags|=1,ki(e,t,s,n),t.child;case 14:return o=ni(s=t.type,t.pendingProps),wi(e,t,s,o=ni(s.type,o),n);case 15:return _i(e,t,t.type,t.pendingProps,n);case 17:return s=t.type,o=t.pendingProps,o=t.elementType===s?o:ni(s,o),qi(e,t),t.tag=1,No(s)?(e=!0,Fo(t)):e=!1,Pa(t,n),ri(t,s,o),ci(t,s,o,n),Ai(null,t,s,!0,e,n);case 19:return Ui(e,t,n);case 22:return Si(e,t,n)}throw Error(a(156,t.tag))};var Wd="function"==typeof reportError?reportError:function(e){console.error(e)};function Gd(e){this._internalRoot=e}function Xd(e){this._internalRoot=e}function Kd(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType)}function Zd(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function Yd(){}function Jd(e,t,n,s,o){var a=n._reactRootContainer;if(a){var r=a;if("function"==typeof o){var i=o;o=function(){var e=Qd(r);i.call(e)}}qd(t,r,e,o)}else r=function(e,t,n,s,o){if(o){if("function"==typeof s){var a=s;s=function(){var e=Qd(r);a.call(e)}}var r=Ud(t,s,e,0,null,!1,0,"",Yd);return e._reactRootContainer=r,e[fo]=r.current,Us(8===e.nodeType?e.parentNode:e),ud(),r}for(;o=e.lastChild;)e.removeChild(o);if("function"==typeof s){var i=s;s=function(){var e=Qd(c);i.call(e)}}var c=Bd(e,0,!1,null,0,!1,0,"",Yd);return e._reactRootContainer=c,e[fo]=c.current,Us(8===e.nodeType?e.parentNode:e),ud((function(){qd(t,c,n,s)})),c}(n,t,e,o,s);return Qd(r)}Xd.prototype.render=Gd.prototype.render=function(e){var t=this._internalRoot;if(null===t)throw Error(a(409));qd(e,t,null,null)},Xd.prototype.unmount=Gd.prototype.unmount=function(){var e=this._internalRoot;if(null!==e){this._internalRoot=null;var t=e.containerInfo;ud((function(){qd(null,e,null,null)})),t[fo]=null}},Xd.prototype.unstable_scheduleHydration=function(e){if(e){var t=St();e={blockedOn:null,target:e,priority:t};for(var n=0;n<Nt.length&&0!==t&&t<Nt[n].priority;n++);Nt.splice(n,0,e),0===n&&Ft(e)}},xt=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var n=lt(t.pendingLanes);0!==n&&(yt(t,1|n),sd(t,Ze()),!(6&Ac)&&(Uc=Ze()+500,qo()))}break;case 13:ud((function(){var t=Ia(e,1);if(null!==t){var n=ed();nd(t,e,1,n)}})),Hd(e,1)}},wt=function(e){if(13===e.tag){var t=Ia(e,134217728);if(null!==t)nd(t,e,134217728,ed());Hd(e,134217728)}},_t=function(e){if(13===e.tag){var t=td(e),n=Ia(e,t);if(null!==n)nd(n,e,t,ed());Hd(e,t)}},St=function(){return vt},Et=function(e,t){var n=vt;try{return vt=e,t()}finally{vt=n}},we=function(e,t,n){switch(t){case"input":if(Y(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var s=n[t];if(s!==e&&s.form===e.form){var o=wo(s);if(!o)throw Error(a(90));W(s),Y(s,o)}}}break;case"textarea":ae(e,n);break;case"select":null!=(t=n.value)&&ne(e,!!n.multiple,t,!1)}},Ae=dd,je=ud;var eu={usingClientEntryPoint:!1,Events:[ko,xo,wo,Ce,Te,dd]},tu={findFiberByHostInstance:vo,bundleType:0,version:"18.3.1",rendererPackageName:"react-dom"},nu={bundleType:tu.bundleType,version:tu.version,rendererPackageName:tu.rendererPackageName,rendererConfig:tu.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:k.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=Ve(e))?null:e.stateNode},findFiberByHostInstance:tu.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1-next-f1338f8080-20240426"};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var su=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!su.isDisabled&&su.supportsFiber)try{ot=su.inject(nu),at=su}catch(ue){}}t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=eu,t.createPortal=function(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!Kd(t))throw Error(a(200));return function(e,t,n){var s=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:w,key:null==s?null:""+s,children:e,containerInfo:t,implementation:n}}(e,t,null,n)},t.createRoot=function(e,t){if(!Kd(e))throw Error(a(299));var n=!1,s="",o=Wd;return null!=t&&(!0===t.unstable_strictMode&&(n=!0),void 0!==t.identifierPrefix&&(s=t.identifierPrefix),void 0!==t.onRecoverableError&&(o=t.onRecoverableError)),t=Bd(e,1,!1,null,0,n,0,s,o),e[fo]=t.current,Us(8===e.nodeType?e.parentNode:e),new Gd(t)},t.findDOMNode=function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternals;if(void 0===t){if("function"==typeof e.render)throw Error(a(188));throw e=Object.keys(e).join(","),Error(a(268,e))}return e=null===(e=Ve(t))?null:e.stateNode},t.flushSync=function(e){return ud(e)},t.hydrate=function(e,t,n){if(!Zd(t))throw Error(a(200));return Jd(null,e,t,!0,n)},t.hydrateRoot=function(e,t,n){if(!Kd(e))throw Error(a(405));var s=null!=n&&n.hydratedSources||null,o=!1,r="",i=Wd;if(null!=n&&(!0===n.unstable_strictMode&&(o=!0),void 0!==n.identifierPrefix&&(r=n.identifierPrefix),void 0!==n.onRecoverableError&&(i=n.onRecoverableError)),t=Ud(t,null,e,1,null!=n?n:null,o,0,r,i),e[fo]=t.current,Us(e),s)for(e=0;e<s.length;e++)o=(o=(n=s[e])._getVersion)(n._source),null==t.mutableSourceEagerHydrationData?t.mutableSourceEagerHydrationData=[n,o]:t.mutableSourceEagerHydrationData.push(n,o);return new Xd(t)},t.render=function(e,t,n){if(!Zd(t))throw Error(a(200));return Jd(null,e,t,!1,n)},t.unmountComponentAtNode=function(e){if(!Zd(e))throw Error(a(40));return!!e._reactRootContainer&&(ud((function(){Jd(null,null,e,!1,(function(){e._reactRootContainer=null,e[fo]=null}))})),!0)},t.unstable_batchedUpdates=dd,t.unstable_renderSubtreeIntoContainer=function(e,t,n,s){if(!Zd(n))throw Error(a(200));if(null==e||void 0===e._reactInternals)throw Error(a(38));return Jd(e,t,n,!1,s)},t.version="18.3.1-next-f1338f8080-20240426"},5338:(e,t,n)=>{"use strict";var s=n(40961);t.createRoot=s.createRoot,t.hydrateRoot=s.hydrateRoot},40961:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(22551)},30115:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,s="function"==typeof Set,o="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function a(e,r){if(e===r)return!0;if(e&&r&&"object"==typeof e&&"object"==typeof r){if(e.constructor!==r.constructor)return!1;var i,c,d,u;if(Array.isArray(e)){if((i=e.length)!=r.length)return!1;for(c=i;0!=c--;)if(!a(e[c],r[c]))return!1;return!0}if(n&&e instanceof Map&&r instanceof Map){if(e.size!==r.size)return!1;for(u=e.entries();!(c=u.next()).done;)if(!r.has(c.value[0]))return!1;for(u=e.entries();!(c=u.next()).done;)if(!a(c.value[1],r.get(c.value[0])))return!1;return!0}if(s&&e instanceof Set&&r instanceof Set){if(e.size!==r.size)return!1;for(u=e.entries();!(c=u.next()).done;)if(!r.has(c.value[0]))return!1;return!0}if(o&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(r)){if((i=e.length)!=r.length)return!1;for(c=i;0!=c--;)if(e[c]!==r[c])return!1;return!0}if(e.constructor===RegExp)return e.source===r.source&&e.flags===r.flags;if(e.valueOf!==Object.prototype.valueOf&&"function"==typeof e.valueOf&&"function"==typeof r.valueOf)return e.valueOf()===r.valueOf();if(e.toString!==Object.prototype.toString&&"function"==typeof e.toString&&"function"==typeof r.toString)return e.toString()===r.toString();if((i=(d=Object.keys(e)).length)!==Object.keys(r).length)return!1;for(c=i;0!=c--;)if(!Object.prototype.hasOwnProperty.call(r,d[c]))return!1;if(t&&e instanceof Element)return!1;for(c=i;0!=c--;)if(("_owner"!==d[c]&&"__v"!==d[c]&&"__o"!==d[c]||!e.$$typeof)&&!a(e[d[c]],r[d[c]]))return!1;return!0}return e!=e&&r!=r}e.exports=function(e,t){try{return a(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},80545:(e,t,n)=>{"use strict";n.d(t,{mg:()=>J,vd:()=>V});var s=n(96540),o=n(5556),a=n.n(o),r=n(30115),i=n.n(r),c=n(20311),d=n.n(c),u=n(2833),l=n.n(u);function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(e[s]=n[s])}return e},p.apply(this,arguments)}function m(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,g(e,t)}function g(e,t){return g=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},g(e,t)}function f(e,t){if(null==e)return{};var n,s,o={},a=Object.keys(e);for(s=0;s<a.length;s++)t.indexOf(n=a[s])>=0||(o[n]=e[n]);return o}var h={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},y={type:["application/ld+json"]},v={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},k=Object.keys(h).map((function(e){return h[e]})),x={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},w=Object.keys(x).reduce((function(e,t){return e[x[t]]=t,e}),{}),_=function(e,t){for(var n=e.length-1;n>=0;n-=1){var s=e[n];if(Object.prototype.hasOwnProperty.call(s,t))return s[t]}return null},S=function(e){var t=_(e,h.TITLE),n=_(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var s=_(e,"defaultTitle");return t||s||void 0},E=function(e){return _(e,"onChangeClientState")||function(){}},C=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return p({},e,t)}),{})},T=function(e,t){return t.filter((function(e){return void 0!==e[h.BASE]})).map((function(e){return e[h.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var s=Object.keys(n),o=0;o<s.length;o+=1){var a=s[o].toLowerCase();if(-1!==e.indexOf(a)&&n[a])return t.concat(n)}return t}),[])},A=function(e,t,n){var s={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var o={};n.filter((function(e){for(var n,a=Object.keys(e),r=0;r<a.length;r+=1){var i=a[r],c=i.toLowerCase();-1===t.indexOf(c)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===c&&"stylesheet"===e[c].toLowerCase()||(n=c),-1===t.indexOf(i)||"innerHTML"!==i&&"cssText"!==i&&"itemprop"!==i||(n=i)}if(!n||!e[n])return!1;var d=e[n].toLowerCase();return s[n]||(s[n]={}),o[n]||(o[n]={}),!s[n][d]&&(o[n][d]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var a=Object.keys(o),r=0;r<a.length;r+=1){var i=a[r],c=p({},s[i],o[i]);s[i]=c}return e}),[]).reverse()},j=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},P=function(e){return Array.isArray(e)?e.join(""):e},L=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),s=0;s<n.length;s+=1)if(t[n[s]]&&t[n[s]].includes(e[n[s]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},R=function(e,t){var n;return p({},e,((n={})[t]=void 0,n))},N=[h.NOSCRIPT,h.SCRIPT,h.STYLE],O=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},I=function(e){return Object.keys(e).reduce((function(t,n){var s=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+s:s}),"")},D=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[x[n]||n]=e[n],t}),t)},F=function(e,t){return t.map((function(t,n){var o,a=((o={key:n})["data-rh"]=!0,o);return Object.keys(t).forEach((function(e){var n=x[e]||e;"innerHTML"===n||"cssText"===n?a.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:a[n]=t[e]})),s.createElement(e,a)}))},M=function(e,t,n){switch(e){case h.TITLE:return{toComponent:function(){return n=t.titleAttributes,(o={key:e=t.title})["data-rh"]=!0,a=D(n,o),[s.createElement(h.TITLE,a,e)];var e,n,o,a},toString:function(){return function(e,t,n,s){var o=I(n),a=P(t);return o?"<"+e+' data-rh="true" '+o+">"+O(a,s)+"</"+e+">":"<"+e+' data-rh="true">'+O(a,s)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return D(t)},toString:function(){return I(t)}};default:return{toComponent:function(){return F(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,s){var o=Object.keys(s).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var o=void 0===s[t]?t:t+'="'+O(s[t],n)+'"';return e?e+" "+o:o}),""),a=s.innerHTML||s.cssText||"",r=-1===N.indexOf(e);return t+"<"+e+' data-rh="true" '+o+(r?"/>":">"+a+"</"+e+">")}),"")}(e,t,n)}}}},z=function(e){var t=e.baseTag,n=e.bodyAttributes,s=e.encode,o=e.htmlAttributes,a=e.noscriptTags,r=e.styleTags,i=e.title,c=void 0===i?"":i,d=e.titleAttributes,u=e.linkTags,l=e.metaTags,p=e.scriptTags,m={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var g=function(e){var t=e.linkTags,n=e.scriptTags,s=e.encode,o=L(e.metaTags,v),a=L(t,b),r=L(n,y);return{priorityMethods:{toComponent:function(){return[].concat(F(h.META,o.priority),F(h.LINK,a.priority),F(h.SCRIPT,r.priority))},toString:function(){return M(h.META,o.priority,s)+" "+M(h.LINK,a.priority,s)+" "+M(h.SCRIPT,r.priority,s)}},metaTags:o.default,linkTags:a.default,scriptTags:r.default}}(e);m=g.priorityMethods,u=g.linkTags,l=g.metaTags,p=g.scriptTags}return{priority:m,base:M(h.BASE,t,s),bodyAttributes:M("bodyAttributes",n,s),htmlAttributes:M("htmlAttributes",o,s),link:M(h.LINK,u,s),meta:M(h.META,l,s),noscript:M(h.NOSCRIPT,a,s),script:M(h.SCRIPT,p,s),style:M(h.STYLE,r,s),title:M(h.TITLE,{title:c,titleAttributes:d},s)}},B=[],$=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?B:n.instances},add:function(e){(n.canUseDOM?B:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?B:n.instances).indexOf(e);(n.canUseDOM?B:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=z({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},U=s.createContext({}),q=a().shape({setHelmet:a().func,helmetInstances:a().shape({get:a().func,add:a().func,remove:a().func})}),Q="undefined"!=typeof document,V=function(e){function t(n){var s;return(s=e.call(this,n)||this).helmetData=new $(s.props.context,t.canUseDOM),s}return m(t,e),t.prototype.render=function(){return s.createElement(U.Provider,{value:this.helmetData.value},this.props.children)},t}(s.Component);V.canUseDOM=Q,V.propTypes={context:a().shape({helmet:a().shape()}),children:a().node.isRequired},V.defaultProps={context:{}},V.displayName="HelmetProvider";var H=function(e,t){var n,s=document.head||document.querySelector(h.HEAD),o=s.querySelectorAll(e+"[data-rh]"),a=[].slice.call(o),r=[];return t&&t.length&&t.forEach((function(t){var s=document.createElement(e);for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&("innerHTML"===o?s.innerHTML=t.innerHTML:"cssText"===o?s.styleSheet?s.styleSheet.cssText=t.cssText:s.appendChild(document.createTextNode(t.cssText)):s.setAttribute(o,void 0===t[o]?"":t[o]));s.setAttribute("data-rh","true"),a.some((function(e,t){return n=t,s.isEqualNode(e)}))?a.splice(n,1):r.push(s)})),a.forEach((function(e){return e.parentNode.removeChild(e)})),r.forEach((function(e){return s.appendChild(e)})),{oldTags:a,newTags:r}},W=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var s=n.getAttribute("data-rh"),o=s?s.split(","):[],a=[].concat(o),r=Object.keys(t),i=0;i<r.length;i+=1){var c=r[i],d=t[c]||"";n.getAttribute(c)!==d&&n.setAttribute(c,d),-1===o.indexOf(c)&&o.push(c);var u=a.indexOf(c);-1!==u&&a.splice(u,1)}for(var l=a.length-1;l>=0;l-=1)n.removeAttribute(a[l]);o.length===a.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==r.join(",")&&n.setAttribute("data-rh",r.join(","))}},G=function(e,t){var n=e.baseTag,s=e.htmlAttributes,o=e.linkTags,a=e.metaTags,r=e.noscriptTags,i=e.onChangeClientState,c=e.scriptTags,d=e.styleTags,u=e.title,l=e.titleAttributes;W(h.BODY,e.bodyAttributes),W(h.HTML,s),function(e,t){void 0!==e&&document.title!==e&&(document.title=P(e)),W(h.TITLE,t)}(u,l);var p={baseTag:H(h.BASE,n),linkTags:H(h.LINK,o),metaTags:H(h.META,a),noscriptTags:H(h.NOSCRIPT,r),scriptTags:H(h.SCRIPT,c),styleTags:H(h.STYLE,d)},m={},g={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,s=t.oldTags;n.length&&(m[e]=n),s.length&&(g[e]=p[e].oldTags)})),t&&t(),i(e,m,g)},X=null,K=function(e){function t(){for(var t,n=arguments.length,s=new Array(n),o=0;o<n;o++)s[o]=arguments[o];return(t=e.call.apply(e,[this].concat(s))||this).rendered=!1,t}m(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!l()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,s=n.setHelmet,o=null,a=(e=n.helmetInstances.get().map((function(e){var t=p({},e.props);return delete t.context,t})),{baseTag:T(["href"],e),bodyAttributes:C("bodyAttributes",e),defer:_(e,"defer"),encode:_(e,"encodeSpecialCharacters"),htmlAttributes:C("htmlAttributes",e),linkTags:A(h.LINK,["rel","href"],e),metaTags:A(h.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:A(h.NOSCRIPT,["innerHTML"],e),onChangeClientState:E(e),scriptTags:A(h.SCRIPT,["src","innerHTML"],e),styleTags:A(h.STYLE,["cssText"],e),title:S(e),titleAttributes:C("titleAttributes",e),prioritizeSeoTags:j(e,"prioritizeSeoTags")});V.canUseDOM?(t=a,X&&cancelAnimationFrame(X),t.defer?X=requestAnimationFrame((function(){G(t,(function(){X=null}))})):(G(t),X=null)):z&&(o=z(a)),s(o)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(s.Component);K.propTypes={context:q.isRequired},K.displayName="HelmetDispatcher";var Z=["children"],Y=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}m(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!i()(R(this.props,"helmetData"),R(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case h.SCRIPT:case h.NOSCRIPT:return{innerHTML:t};case h.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,s=e.arrayTypeChildren;return p({},s,((t={})[n.type]=[].concat(s[n.type]||[],[p({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,s=e.child,o=e.newProps,a=e.newChildProps,r=e.nestedChildren;switch(s.type){case h.TITLE:return p({},o,((t={})[s.type]=r,t.titleAttributes=p({},a),t));case h.BODY:return p({},o,{bodyAttributes:p({},a)});case h.HTML:return p({},o,{htmlAttributes:p({},a)});default:return p({},o,((n={})[s.type]=p({},a),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=p({},t);return Object.keys(e).forEach((function(t){var s;n=p({},n,((s={})[t]=e[t],s))})),n},n.warnOnInvalidChildren=function(e,t){return d()(k.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+k.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),d()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,o={};return s.Children.forEach(e,(function(e){if(e&&e.props){var s=e.props,a=s.children,r=f(s,Z),i=Object.keys(r).reduce((function(e,t){return e[w[t]||t]=r[t],e}),{}),c=e.type;switch("symbol"==typeof c?c=c.toString():n.warnOnInvalidChildren(e,a),c){case h.FRAGMENT:t=n.mapChildrenToProps(a,t);break;case h.LINK:case h.META:case h.NOSCRIPT:case h.SCRIPT:case h.STYLE:o=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:o,newChildProps:i,nestedChildren:a});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:i,nestedChildren:a})}}})),this.mapArrayTypeChildrenToProps(o,t)},n.render=function(){var e=this.props,t=e.children,n=f(e,Y),o=p({},n),a=n.helmetData;return t&&(o=this.mapChildrenToProps(t,o)),!a||a instanceof $||(a=new $(a.context,a.instances)),a?s.createElement(K,p({},o,{context:a.value,helmetData:void 0})):s.createElement(U.Consumer,null,(function(e){return s.createElement(K,p({},o,{context:e}))}))},t}(s.Component);J.propTypes={base:a().object,bodyAttributes:a().object,children:a().oneOfType([a().arrayOf(a().node),a().node]),defaultTitle:a().string,defer:a().bool,encodeSpecialCharacters:a().bool,htmlAttributes:a().object,link:a().arrayOf(a().object),meta:a().arrayOf(a().object),noscript:a().arrayOf(a().object),onChangeClientState:a().func,script:a().arrayOf(a().object),style:a().arrayOf(a().object),title:a().string,titleAttributes:a().object,titleTemplate:a().string,prioritizeSeoTags:a().bool,helmetData:a().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},22799:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,s=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,a=n?Symbol.for("react.fragment"):60107,r=n?Symbol.for("react.strict_mode"):60108,i=n?Symbol.for("react.profiler"):60114,c=n?Symbol.for("react.provider"):60109,d=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,l=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,m=n?Symbol.for("react.suspense"):60113,g=n?Symbol.for("react.suspense_list"):60120,f=n?Symbol.for("react.memo"):60115,h=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,y=n?Symbol.for("react.fundamental"):60117,v=n?Symbol.for("react.responder"):60118,k=n?Symbol.for("react.scope"):60119;function x(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case s:switch(e=e.type){case u:case l:case a:case i:case r:case m:return e;default:switch(e=e&&e.$$typeof){case d:case p:case h:case f:case c:return e;default:return t}}case o:return t}}}function w(e){return x(e)===l}t.AsyncMode=u,t.ConcurrentMode=l,t.ContextConsumer=d,t.ContextProvider=c,t.Element=s,t.ForwardRef=p,t.Fragment=a,t.Lazy=h,t.Memo=f,t.Portal=o,t.Profiler=i,t.StrictMode=r,t.Suspense=m,t.isAsyncMode=function(e){return w(e)||x(e)===u},t.isConcurrentMode=w,t.isContextConsumer=function(e){return x(e)===d},t.isContextProvider=function(e){return x(e)===c},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===s},t.isForwardRef=function(e){return x(e)===p},t.isFragment=function(e){return x(e)===a},t.isLazy=function(e){return x(e)===h},t.isMemo=function(e){return x(e)===f},t.isPortal=function(e){return x(e)===o},t.isProfiler=function(e){return x(e)===i},t.isStrictMode=function(e){return x(e)===r},t.isSuspense=function(e){return x(e)===m},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===a||e===l||e===i||e===r||e===m||e===g||"object"==typeof e&&null!==e&&(e.$$typeof===h||e.$$typeof===f||e.$$typeof===c||e.$$typeof===d||e.$$typeof===p||e.$$typeof===y||e.$$typeof===v||e.$$typeof===k||e.$$typeof===b)},t.typeOf=x},44363:(e,t,n)=>{"use strict";e.exports=n(22799)},53259:(e,t,n)=>{"use strict";function s(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function o(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(){return r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(e[s]=n[s])}return e},r.apply(this,arguments)}var i=n(96540),c=[],d=[];var u=i.createContext(null);function l(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function p(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(s){var o=l(e[s]);o.loading?t.loading=!0:(t.loaded[s]=o.loaded,t.error=o.error),n.push(o.promise),o.promise.then((function(e){t.loaded[s]=e})).catch((function(e){t.error=e}))}))}catch(s){t.error=s}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function m(e,t){return i.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function g(e,t){var l,p;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var g=r({loader:null,loading:null,delay:200,timeout:null,render:m,webpack:null,modules:null},t),f=null;function h(){return f||(f=e(g.loader)),f.promise}return c.push(h),"function"==typeof g.webpack&&d.push((function(){if((0,g.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return h()})),p=l=function(t){function n(n){var s;return a(o(o(s=t.call(this,n)||this)),"retry",(function(){s.setState({error:null,loading:!0,timedOut:!1}),f=e(g.loader),s._loadModule()})),h(),s.state={error:f.error,pastDelay:!1,timedOut:!1,loading:f.loading,loaded:f.loaded},s}s(n,t),n.preload=function(){return h()};var r=n.prototype;return r.UNSAFE_componentWillMount=function(){this._loadModule()},r.componentDidMount=function(){this._mounted=!0},r._loadModule=function(){var e=this;if(this.context&&Array.isArray(g.modules)&&g.modules.forEach((function(t){e.context.report(t)})),f.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof g.delay&&(0===g.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),g.delay)),"number"==typeof g.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),g.timeout));var n=function(){t({error:f.error,loaded:f.loaded,loading:f.loading}),e._clearTimeouts()};f.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},r.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},r._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},r.render=function(){return this.state.loading||this.state.error?i.createElement(g.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?g.render(this.state.loaded,this.props):null},n}(i.Component),a(l,"contextType",u),p}function f(e){return g(l,e)}f.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return g(p,e)};var h=function(e){function t(){return e.apply(this,arguments)||this}return s(t,e),t.prototype.render=function(){return i.createElement(u.Provider,{value:{report:this.props.report}},i.Children.only(this.props.children))},t}(i.Component);function b(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return b(e)}))}f.Capture=h,f.preloadAll=function(){return new Promise((function(e,t){b(c).then(e,t)}))},f.preloadReady=function(){return new Promise((function(e,t){b(d).then(e,e)}))},e.exports=f},22831:(e,t,n)=>{"use strict";n.d(t,{u:()=>r,v:()=>i});var s=n(56347),o=n(58168),a=n(96540);function r(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var o=e.path?(0,s.B6)(t,e):n.length?n[n.length-1].match:s.Ix.computeRootMatch(t);return o&&(n.push({route:e,match:o}),e.routes&&r(e.routes,t,n)),o})),n}function i(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?a.createElement(s.dO,n,e.map((function(e,n){return a.createElement(s.qh,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,o.A)({},n,{},t,{route:e})):a.createElement(e.component,(0,o.A)({},n,t,{route:e}))}})}))):null}},54625:(e,t,n)=>{"use strict";n.d(t,{I9:()=>l,Kd:()=>u,N_:()=>b,k2:()=>k});var s=n(56347),o=n(42892),a=n(96540),r=n(31513),i=n(58168),c=n(98587),d=n(11561),u=function(e){function t(){for(var t,n=arguments.length,s=new Array(n),o=0;o<n;o++)s[o]=arguments[o];return(t=e.call.apply(e,[this].concat(s))||this).history=(0,r.zR)(t.props),t}return(0,o.A)(t,e),t.prototype.render=function(){return a.createElement(s.Ix,{history:this.history,children:this.props.children})},t}(a.Component);var l=function(e){function t(){for(var t,n=arguments.length,s=new Array(n),o=0;o<n;o++)s[o]=arguments[o];return(t=e.call.apply(e,[this].concat(s))||this).history=(0,r.TM)(t.props),t}return(0,o.A)(t,e),t.prototype.render=function(){return a.createElement(s.Ix,{history:this.history,children:this.props.children})},t}(a.Component);var p=function(e,t){return"function"==typeof e?e(t):e},m=function(e,t){return"string"==typeof e?(0,r.yJ)(e,null,null,t):e},g=function(e){return e},f=a.forwardRef;void 0===f&&(f=g);var h=f((function(e,t){var n=e.innerRef,s=e.navigate,o=e.onClick,r=(0,c.A)(e,["innerRef","navigate","onClick"]),d=r.target,u=(0,i.A)({},r,{onClick:function(e){try{o&&o(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||d&&"_self"!==d||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),s())}});return u.ref=g!==f&&t||n,a.createElement("a",u)}));var b=f((function(e,t){var n=e.component,o=void 0===n?h:n,u=e.replace,l=e.to,b=e.innerRef,y=(0,c.A)(e,["component","replace","to","innerRef"]);return a.createElement(s.XZ.Consumer,null,(function(e){e||(0,d.A)(!1);var n=e.history,s=m(p(l,e.location),e.location),c=s?n.createHref(s):"",h=(0,i.A)({},y,{href:c,navigate:function(){var t=p(l,e.location),s=(0,r.AO)(e.location)===(0,r.AO)(m(t));(u||s?n.replace:n.push)(t)}});return g!==f?h.ref=t||b:h.innerRef=b,a.createElement(o,h)}))})),y=function(e){return e},v=a.forwardRef;void 0===v&&(v=y);var k=v((function(e,t){var n=e["aria-current"],o=void 0===n?"page":n,r=e.activeClassName,u=void 0===r?"active":r,l=e.activeStyle,g=e.className,f=e.exact,h=e.isActive,k=e.location,x=e.sensitive,w=e.strict,_=e.style,S=e.to,E=e.innerRef,C=(0,c.A)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return a.createElement(s.XZ.Consumer,null,(function(e){e||(0,d.A)(!1);var n=k||e.location,r=m(p(S,n),n),c=r.pathname,T=c&&c.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),A=T?(0,s.B6)(n.pathname,{path:T,exact:f,sensitive:x,strict:w}):null,j=!!(h?h(A,n):A),P="function"==typeof g?g(j):g,L="function"==typeof _?_(j):_;j&&(P=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(P,u),L=(0,i.A)({},L,l));var R=(0,i.A)({"aria-current":j&&o||null,className:P,style:L,to:r},C);return y!==v?R.ref=t||E:R.innerRef=E,a.createElement(b,R)}))}))},56347:(e,t,n)=>{"use strict";n.d(t,{B6:()=>_,Ix:()=>v,W6:()=>R,XZ:()=>y,dO:()=>P,qh:()=>S,zy:()=>N});var s=n(42892),o=n(96540),a=n(5556),r=n.n(a),i=n(31513),c=n(11561),d=n(58168),u=n(35302),l=n.n(u),p=(n(44363),n(98587)),m=(n(4146),1073741823),g="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var f=o.createContext||function(e,t){var n,a,i="__create-react-context-"+function(){var e="__global_unique_id__";return g[e]=(g[e]||0)+1}()+"__",c=function(e){function n(){for(var t,n,s,o=arguments.length,a=new Array(o),r=0;r<o;r++)a[r]=arguments[r];return(t=e.call.apply(e,[this].concat(a))||this).emitter=(n=t.props.value,s=[],{on:function(e){s.push(e)},off:function(e){s=s.filter((function(t){return t!==e}))},get:function(){return n},set:function(e,t){n=e,s.forEach((function(e){return e(n,t)}))}}),t}(0,s.A)(n,e);var o=n.prototype;return o.getChildContext=function(){var e;return(e={})[i]=this.emitter,e},o.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,s=this.props.value,o=e.value;((a=s)===(r=o)?0!==a||1/a==1/r:a!=a&&r!=r)?n=0:(n="function"==typeof t?t(s,o):m,0!==(n|=0)&&this.emitter.set(e.value,n))}var a,r},o.render=function(){return this.props.children},n}(o.Component);c.childContextTypes=((n={})[i]=r().object.isRequired,n);var d=function(t){function n(){for(var e,n=arguments.length,s=new Array(n),o=0;o<n;o++)s[o]=arguments[o];return(e=t.call.apply(t,[this].concat(s))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){(0|e.observedBits)&n&&e.setState({value:e.getValue()})},e}(0,s.A)(n,t);var o=n.prototype;return o.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?m:t},o.componentDidMount=function(){this.context[i]&&this.context[i].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?m:e},o.componentWillUnmount=function(){this.context[i]&&this.context[i].off(this.onUpdate)},o.getValue=function(){return this.context[i]?this.context[i].get():e},o.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(o.Component);return d.contextTypes=((a={})[i]=r().object,a),{Provider:c,Consumer:d}},h=function(e){var t=f();return t.displayName=e,t},b=h("Router-History"),y=h("Router"),v=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,s.A)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return o.createElement(y.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},o.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(o.Component);o.Component;o.Component;var k={},x=1e4,w=0;function _(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,s=n.path,o=n.exact,a=void 0!==o&&o,r=n.strict,i=void 0!==r&&r,c=n.sensitive,d=void 0!==c&&c;return[].concat(s).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var s=function(e,t){var n=""+t.end+t.strict+t.sensitive,s=k[n]||(k[n]={});if(s[e])return s[e];var o=[],a={regexp:l()(e,o,t),keys:o};return w<x&&(s[e]=a,w++),a}(n,{end:a,strict:i,sensitive:d}),o=s.regexp,r=s.keys,c=o.exec(e);if(!c)return null;var u=c[0],p=c.slice(1),m=e===u;return a&&!m?null:{path:n,url:"/"===n&&""===u?"/":u,isExact:m,params:r.reduce((function(e,t,n){return e[t.name]=p[n],e}),{})}}),null)}var S=function(e){function t(){return e.apply(this,arguments)||this}return(0,s.A)(t,e),t.prototype.render=function(){var e=this;return o.createElement(y.Consumer,null,(function(t){t||(0,c.A)(!1);var n=e.props.location||t.location,s=e.props.computedMatch?e.props.computedMatch:e.props.path?_(n.pathname,e.props):t.match,a=(0,d.A)({},t,{location:n,match:s}),r=e.props,i=r.children,u=r.component,l=r.render;return Array.isArray(i)&&function(e){return 0===o.Children.count(e)}(i)&&(i=null),o.createElement(y.Provider,{value:a},a.match?i?"function"==typeof i?i(a):i:u?o.createElement(u,a):l?l(a):null:"function"==typeof i?i(a):null)}))},t}(o.Component);function E(e){return"/"===e.charAt(0)?e:"/"+e}function C(e,t){if(!e)return t;var n=E(e);return 0!==t.pathname.indexOf(n)?t:(0,d.A)({},t,{pathname:t.pathname.substr(n.length)})}function T(e){return"string"==typeof e?e:(0,i.AO)(e)}function A(e){return function(){(0,c.A)(!1)}}function j(){}o.Component;var P=function(e){function t(){return e.apply(this,arguments)||this}return(0,s.A)(t,e),t.prototype.render=function(){var e=this;return o.createElement(y.Consumer,null,(function(t){t||(0,c.A)(!1);var n,s,a=e.props.location||t.location;return o.Children.forEach(e.props.children,(function(e){if(null==s&&o.isValidElement(e)){n=e;var r=e.props.path||e.props.from;s=r?_(a.pathname,(0,d.A)({},e.props,{path:r})):t.match}})),s?o.cloneElement(n,{location:a,computedMatch:s}):null}))},t}(o.Component);var L=o.useContext;function R(){return L(b)}function N(){return L(y).location}},21020:(e,t,n)=>{"use strict";var s=n(96540),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),r=Object.prototype.hasOwnProperty,i=s.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,c={key:!0,ref:!0,__self:!0,__source:!0};function d(e,t,n){var s,a={},d=null,u=null;for(s in void 0!==n&&(d=""+n),void 0!==t.key&&(d=""+t.key),void 0!==t.ref&&(u=t.ref),t)r.call(t,s)&&!c.hasOwnProperty(s)&&(a[s]=t[s]);if(e&&e.defaultProps)for(s in t=e.defaultProps)void 0===a[s]&&(a[s]=t[s]);return{$$typeof:o,type:e,key:d,ref:u,props:a,_owner:i.current}}t.Fragment=a,t.jsx=d,t.jsxs=d},15287:(e,t)=>{"use strict";var n=Symbol.for("react.element"),s=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),a=Symbol.for("react.strict_mode"),r=Symbol.for("react.profiler"),i=Symbol.for("react.provider"),c=Symbol.for("react.context"),d=Symbol.for("react.forward_ref"),u=Symbol.for("react.suspense"),l=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),m=Symbol.iterator;var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},f=Object.assign,h={};function b(e,t,n){this.props=e,this.context=t,this.refs=h,this.updater=n||g}function y(){}function v(e,t,n){this.props=e,this.context=t,this.refs=h,this.updater=n||g}b.prototype.isReactComponent={},b.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},b.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},y.prototype=b.prototype;var k=v.prototype=new y;k.constructor=v,f(k,b.prototype),k.isPureReactComponent=!0;var x=Array.isArray,w=Object.prototype.hasOwnProperty,_={current:null},S={key:!0,ref:!0,__self:!0,__source:!0};function E(e,t,s){var o,a={},r=null,i=null;if(null!=t)for(o in void 0!==t.ref&&(i=t.ref),void 0!==t.key&&(r=""+t.key),t)w.call(t,o)&&!S.hasOwnProperty(o)&&(a[o]=t[o]);var c=arguments.length-2;if(1===c)a.children=s;else if(1<c){for(var d=Array(c),u=0;u<c;u++)d[u]=arguments[u+2];a.children=d}if(e&&e.defaultProps)for(o in c=e.defaultProps)void 0===a[o]&&(a[o]=c[o]);return{$$typeof:n,type:e,key:r,ref:i,props:a,_owner:_.current}}function C(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}var T=/\/+/g;function A(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function j(e,t,o,a,r){var i=typeof e;"undefined"!==i&&"boolean"!==i||(e=null);var c=!1;if(null===e)c=!0;else switch(i){case"string":case"number":c=!0;break;case"object":switch(e.$$typeof){case n:case s:c=!0}}if(c)return r=r(c=e),e=""===a?"."+A(c,0):a,x(r)?(o="",null!=e&&(o=e.replace(T,"$&/")+"/"),j(r,t,o,"",(function(e){return e}))):null!=r&&(C(r)&&(r=function(e,t){return{$$typeof:n,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(r,o+(!r.key||c&&c.key===r.key?"":(""+r.key).replace(T,"$&/")+"/")+e)),t.push(r)),1;if(c=0,a=""===a?".":a+":",x(e))for(var d=0;d<e.length;d++){var u=a+A(i=e[d],d);c+=j(i,t,o,u,r)}else if(u=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=m&&e[m]||e["@@iterator"])?e:null}(e),"function"==typeof u)for(e=u.call(e),d=0;!(i=e.next()).done;)c+=j(i=i.value,t,o,u=a+A(i,d++),r);else if("object"===i)throw t=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.");return c}function P(e,t,n){if(null==e)return e;var s=[],o=0;return j(e,s,"","",(function(e){return t.call(n,e,o++)})),s}function L(e){if(-1===e._status){var t=e._result;(t=t()).then((function(t){0!==e._status&&-1!==e._status||(e._status=1,e._result=t)}),(function(t){0!==e._status&&-1!==e._status||(e._status=2,e._result=t)})),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var R={current:null},N={transition:null},O={ReactCurrentDispatcher:R,ReactCurrentBatchConfig:N,ReactCurrentOwner:_};function I(){throw Error("act(...) is not supported in production builds of React.")}t.Children={map:P,forEach:function(e,t,n){P(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return P(e,(function(){t++})),t},toArray:function(e){return P(e,(function(e){return e}))||[]},only:function(e){if(!C(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},t.Component=b,t.Fragment=o,t.Profiler=r,t.PureComponent=v,t.StrictMode=a,t.Suspense=u,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=O,t.act=I,t.cloneElement=function(e,t,s){if(null==e)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var o=f({},e.props),a=e.key,r=e.ref,i=e._owner;if(null!=t){if(void 0!==t.ref&&(r=t.ref,i=_.current),void 0!==t.key&&(a=""+t.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(d in t)w.call(t,d)&&!S.hasOwnProperty(d)&&(o[d]=void 0===t[d]&&void 0!==c?c[d]:t[d])}var d=arguments.length-2;if(1===d)o.children=s;else if(1<d){c=Array(d);for(var u=0;u<d;u++)c[u]=arguments[u+2];o.children=c}return{$$typeof:n,type:e.type,key:a,ref:r,props:o,_owner:i}},t.createContext=function(e){return(e={$$typeof:c,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null}).Provider={$$typeof:i,_context:e},e.Consumer=e},t.createElement=E,t.createFactory=function(e){var t=E.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:d,render:e}},t.isValidElement=C,t.lazy=function(e){return{$$typeof:p,_payload:{_status:-1,_result:e},_init:L}},t.memo=function(e,t){return{$$typeof:l,type:e,compare:void 0===t?null:t}},t.startTransition=function(e){var t=N.transition;N.transition={};try{e()}finally{N.transition=t}},t.unstable_act=I,t.useCallback=function(e,t){return R.current.useCallback(e,t)},t.useContext=function(e){return R.current.useContext(e)},t.useDebugValue=function(){},t.useDeferredValue=function(e){return R.current.useDeferredValue(e)},t.useEffect=function(e,t){return R.current.useEffect(e,t)},t.useId=function(){return R.current.useId()},t.useImperativeHandle=function(e,t,n){return R.current.useImperativeHandle(e,t,n)},t.useInsertionEffect=function(e,t){return R.current.useInsertionEffect(e,t)},t.useLayoutEffect=function(e,t){return R.current.useLayoutEffect(e,t)},t.useMemo=function(e,t){return R.current.useMemo(e,t)},t.useReducer=function(e,t,n){return R.current.useReducer(e,t,n)},t.useRef=function(e){return R.current.useRef(e)},t.useState=function(e){return R.current.useState(e)},t.useSyncExternalStore=function(e,t,n){return R.current.useSyncExternalStore(e,t,n)},t.useTransition=function(){return R.current.useTransition()},t.version="18.3.1"},96540:(e,t,n)=>{"use strict";e.exports=n(15287)},74848:(e,t,n)=>{"use strict";e.exports=n(21020)},7463:(e,t)=>{"use strict";function n(e,t){var n=e.length;e.push(t);e:for(;0<n;){var s=n-1>>>1,o=e[s];if(!(0<a(o,t)))break e;e[s]=t,e[n]=o,n=s}}function s(e){return 0===e.length?null:e[0]}function o(e){if(0===e.length)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;e:for(var s=0,o=e.length,r=o>>>1;s<r;){var i=2*(s+1)-1,c=e[i],d=i+1,u=e[d];if(0>a(c,n))d<o&&0>a(u,c)?(e[s]=u,e[d]=n,s=d):(e[s]=c,e[i]=n,s=i);else{if(!(d<o&&0>a(u,n)))break e;e[s]=u,e[d]=n,s=d}}}return t}function a(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if("object"==typeof performance&&"function"==typeof performance.now){var r=performance;t.unstable_now=function(){return r.now()}}else{var i=Date,c=i.now();t.unstable_now=function(){return i.now()-c}}var d=[],u=[],l=1,p=null,m=3,g=!1,f=!1,h=!1,b="function"==typeof setTimeout?setTimeout:null,y="function"==typeof clearTimeout?clearTimeout:null,v="undefined"!=typeof setImmediate?setImmediate:null;function k(e){for(var t=s(u);null!==t;){if(null===t.callback)o(u);else{if(!(t.startTime<=e))break;o(u),t.sortIndex=t.expirationTime,n(d,t)}t=s(u)}}function x(e){if(h=!1,k(e),!f)if(null!==s(d))f=!0,N(w);else{var t=s(u);null!==t&&O(x,t.startTime-e)}}function w(e,n){f=!1,h&&(h=!1,y(C),C=-1),g=!0;var a=m;try{for(k(n),p=s(d);null!==p&&(!(p.expirationTime>n)||e&&!j());){var r=p.callback;if("function"==typeof r){p.callback=null,m=p.priorityLevel;var i=r(p.expirationTime<=n);n=t.unstable_now(),"function"==typeof i?p.callback=i:p===s(d)&&o(d),k(n)}else o(d);p=s(d)}if(null!==p)var c=!0;else{var l=s(u);null!==l&&O(x,l.startTime-n),c=!1}return c}finally{p=null,m=a,g=!1}}"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var _,S=!1,E=null,C=-1,T=5,A=-1;function j(){return!(t.unstable_now()-A<T)}function P(){if(null!==E){var e=t.unstable_now();A=e;var n=!0;try{n=E(!0,e)}finally{n?_():(S=!1,E=null)}}else S=!1}if("function"==typeof v)_=function(){v(P)};else if("undefined"!=typeof MessageChannel){var L=new MessageChannel,R=L.port2;L.port1.onmessage=P,_=function(){R.postMessage(null)}}else _=function(){b(P,0)};function N(e){E=e,S||(S=!0,_())}function O(e,n){C=b((function(){e(t.unstable_now())}),n)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){f||g||(f=!0,N(w))},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):T=0<e?Math.floor(1e3/e):5},t.unstable_getCurrentPriorityLevel=function(){return m},t.unstable_getFirstCallbackNode=function(){return s(d)},t.unstable_next=function(e){switch(m){case 1:case 2:case 3:var t=3;break;default:t=m}var n=m;m=t;try{return e()}finally{m=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=function(){},t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=m;m=e;try{return t()}finally{m=n}},t.unstable_scheduleCallback=function(e,o,a){var r=t.unstable_now();switch("object"==typeof a&&null!==a?a="number"==typeof(a=a.delay)&&0<a?r+a:r:a=r,e){case 1:var i=-1;break;case 2:i=250;break;case 5:i=1073741823;break;case 4:i=1e4;break;default:i=5e3}return e={id:l++,callback:o,priorityLevel:e,startTime:a,expirationTime:i=a+i,sortIndex:-1},a>r?(e.sortIndex=a,n(u,e),null===s(d)&&e===s(u)&&(h?(y(C),C=-1):h=!0,O(x,a-r))):(e.sortIndex=i,n(d,e),f||g||(f=!0,N(w))),e},t.unstable_shouldYield=j,t.unstable_wrapCallback=function(e){var t=m;return function(){var n=m;m=t;try{return e.apply(this,arguments)}finally{m=n}}}},69982:(e,t,n)=>{"use strict";e.exports=n(7463)},2833:e=>{e.exports=function(e,t,n,s){var o=n?n.call(s,e,t):void 0;if(void 0!==o)return!!o;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var a=Object.keys(e),r=Object.keys(t);if(a.length!==r.length)return!1;for(var i=Object.prototype.hasOwnProperty.bind(t),c=0;c<a.length;c++){var d=a[c];if(!i(d))return!1;var u=e[d],l=t[d];if(!1===(o=n?n.call(s,u,l,d):void 0)||void 0===o&&u!==l)return!1}return!0}},4784:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});const s={title:"One platform \u2014 standardized, built and operated by many.",tagline:"Documentation and Community Platform for the Sovereign Cloud Stack",url:"https://docs.scs.community",baseUrl:"/",onBrokenLinks:"warn",onBrokenMarkdownLinks:"warn",favicon:"img/favicon.png",markdown:{mermaid:!0,format:"mdx",mdx1Compat:{comments:!0,admonitions:!0,headingIds:!0},anchors:{maintainCase:!1}},organizationName:"SovereignCloudStack",projectName:"docs",i18n:{defaultLocale:"en",locales:["en"],path:"i18n",localeConfigs:{}},presets:[["classic",{docs:{sidebarPath:"/home/runner/work/docs/docs/sidebarsDocs.js",editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/"},blog:{showReadingTime:!0,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/"},theme:{customCss:["/home/runner/work/docs/docs/src/css/custom.css"]}}]],plugins:[["@docusaurus/plugin-client-redirects",{redirects:[]}],["@docusaurus/plugin-content-docs",{id:"community",path:"community",routeBasePath:"community",sidebarPath:"/home/runner/work/docs/docs/sidebarsCommunity.js"}],["@docusaurus/plugin-content-docs",{id:"contributor-docs",path:"contributor-docs",routeBasePath:"contributor-docs",sidebarPath:"/home/runner/work/docs/docs/sidebarsContributorDocs.js"}],["@docusaurus/plugin-content-docs",{id:"user-docs",path:"user-docs",routeBasePath:"user-docs",sidebarPath:"/home/runner/work/docs/docs/sidebarsUserDocs.js"}],["@docusaurus/plugin-content-docs",{id:"standards",path:"standards",routeBasePath:"standards",sidebarPath:"/home/runner/work/docs/docs/sidebarsStandards.js"}],"./src/plugins/docusaurus-plugin-matomo-analytics/index.js","./src/plugins/docusaurus-plugin-global-data/index.js"],themeConfig:{metadata:[{title:"One platform \u2014 standardized, built and operated by many.",description:"Documentation and Community Platform for the Sovereign Cloud Stack"}],image:"img/scs-og-basic.png",navbar:{title:"",logo:{alt:"SCS",src:"img/logo.svg"},items:[{to:"/standards",label:"Standards",position:"left"},{to:"/docs",label:"For Operators",position:"left"},{to:"/contributor-docs",label:"For Contributors",position:"left"},{to:"/user-docs",label:"For Users",position:"left"},{to:"/community",label:"Community",position:"left"},{to:"/docs/faq",label:"FAQ",position:"left"},{href:"https://github.com/SovereignCloudStack/docs",label:"GitHub",position:"right"}],hideOnScroll:!1},footer:{style:"light",links:[{title:"Docs",items:[{label:"Contribute",to:"/docs"}]},{title:"Community",items:[{label:"Matrix",href:"https://matrix.to/#/!TiDqlLmEUaXqTemaLc:matrix.org?via=matrix.org"},{label:"Mastodon",href:"https://fosstodon.org/@sovereigncloudstack"}]},{title:"More",items:[{label:"GitHub",href:"https://github.com/SovereignCloudStack/docs"}]}],copyright:"Sovereign Cloud Stack, SCS and the logo are registered trademarks of the Open Source Business Alliance e.V. \u2014 Other trademarks are property of their respective owners."},prism:{theme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:["powershell","ruby"],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},matomoAnalytics:{matomoUrl:"https://matomo.scs.community/",siteId:"2",phpLoader:"matomo.php",jsLoader:"matomo.js",disableCookies:!0},colorMode:{defaultMode:"light",disableSwitch:!1,respectPrefersColorScheme:!1},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},blog:{sidebar:{groupByYear:!0}},tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3},mermaid:{theme:{dark:"dark",light:"default"},options:{}}},themes:["@docusaurus/theme-mermaid",["@easyops-cn/docusaurus-search-local",{hashed:!0,docsDir:["docs","community","standards","contributor-docs","user-docs"],docsRouteBasePath:["docs","community","standards","contributor-docs","user-docs"]}]],baseUrlIssueBanner:!0,future:{experimental_faster:{swcJsLoader:!1,swcJsMinimizer:!1,swcHtmlMinimizer:!1,lightningCssMinimizer:!1,mdxCrossCompilerCache:!1,rspackBundler:!1},experimental_storage:{type:"localStorage",namespace:!1},experimental_router:"browser"},onBrokenAnchors:"warn",onDuplicateRoutes:"warn",staticDirectories:["static"],customFields:{},scripts:[],headTags:[],stylesheets:[],clientModules:[],titleDelimiter:"|",noIndex:!1}},58168:(e,t,n)=>{"use strict";function s(){return s=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var s in n)({}).hasOwnProperty.call(n,s)&&(e[s]=n[s])}return e},s.apply(null,arguments)}n.d(t,{A:()=>s})},42892:(e,t,n)=>{"use strict";function s(e,t){return s=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},s(e,t)}function o(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,s(e,t)}n.d(t,{A:()=>o})},98587:(e,t,n)=>{"use strict";function s(e,t){if(null==e)return{};var n={};for(var s in e)if({}.hasOwnProperty.call(e,s)){if(t.includes(s))continue;n[s]=e[s]}return n}n.d(t,{A:()=>s})},18215:(e,t,n)=>{"use strict";function s(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e)){var a=e.length;for(t=0;t<a;t++)e[t]&&(n=s(e[t]))&&(o&&(o+=" "),o+=n)}else for(n in e)e[n]&&(o&&(o+=" "),o+=n);return o}n.d(t,{A:()=>o});const o=function(){for(var e,t,n=0,o="",a=arguments.length;n<a;n++)(e=arguments[n])&&(t=s(e))&&(o&&(o+=" "),o+=t);return o}},15066:(e,t,n)=>{"use strict";function s(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e)){var a=e.length;for(t=0;t<a;t++)e[t]&&(n=s(e[t]))&&(o&&(o+=" "),o+=n)}else for(n in e)e[n]&&(o&&(o+=" "),o+=n);return o}n.d(t,{A:()=>o});const o=function(){for(var e,t,n=0,o="",a=arguments.length;n<a;n++)(e=arguments[n])&&(t=s(e))&&(o&&(o+=" "),o+=t);return o}},78181:(e,t,n)=>{"use strict";n.d(t,{f4:()=>J,My:()=>C});var s=n(96540);function o(e){var t,n,s="";if("string"==typeof e||"number"==typeof e)s+=e;else if("object"==typeof e)if(Array.isArray(e)){var a=e.length;for(t=0;t<a;t++)e[t]&&(n=o(e[t]))&&(s&&(s+=" "),s+=n)}else for(n in e)e[n]&&(s&&(s+=" "),s+=n);return s}const a=function(){for(var e,t,n=0,s="",a=arguments.length;n<a;n++)(e=arguments[n])&&(t=o(e))&&(s&&(s+=" "),s+=t);return s};var r,i,c,d,u,l=Object.create,p=Object.defineProperty,m=Object.defineProperties,g=Object.getOwnPropertyDescriptor,f=Object.getOwnPropertyDescriptors,h=Object.getOwnPropertyNames,b=Object.getOwnPropertySymbols,y=Object.getPrototypeOf,v=Object.prototype.hasOwnProperty,k=Object.prototype.propertyIsEnumerable,x=(e,t,n)=>t in e?p(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,w=(e,t)=>{for(var n in t||(t={}))v.call(t,n)&&x(e,n,t[n]);if(b)for(var n of b(t))k.call(t,n)&&x(e,n,t[n]);return e},_=(e,t)=>m(e,f(t)),S=(e,t)=>{var n={};for(var s in e)v.call(e,s)&&t.indexOf(s)<0&&(n[s]=e[s]);if(null!=e&&b)for(var s of b(e))t.indexOf(s)<0&&k.call(e,s)&&(n[s]=e[s]);return n},E=(r={"../../node_modules/.pnpm/prismjs@1.29.0_patch_hash=vrxx3pzkik6jpmgpayxfjunetu/node_modules/prismjs/prism.js"(e,t){var n=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},s={util:{encode:function e(t){return t instanceof o?new o(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var o,a;switch(n=n||{},s.util.type(t)){case"Object":if(a=s.util.objId(t),n[a])return n[a];for(var r in o={},n[a]=o,t)t.hasOwnProperty(r)&&(o[r]=e(t[r],n));return o;case"Array":return a=s.util.objId(t),n[a]?n[a]:(o=[],n[a]=o,t.forEach((function(t,s){o[s]=e(t,n)})),o);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var s="no-"+t;e;){var o=e.classList;if(o.contains(t))return!0;if(o.contains(s))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=s.util.clone(s.languages[e]);for(var o in t)n[o]=t[o];return n},insertBefore:function(e,t,n,o){var a=(o=o||s.languages)[e],r={};for(var i in a)if(a.hasOwnProperty(i)){if(i==t)for(var c in n)n.hasOwnProperty(c)&&(r[c]=n[c]);n.hasOwnProperty(i)||(r[i]=a[i])}var d=o[e];return o[e]=r,s.languages.DFS(s.languages,(function(t,n){n===d&&t!=e&&(this[t]=r)})),r},DFS:function e(t,n,o,a){a=a||{};var r=s.util.objId;for(var i in t)if(t.hasOwnProperty(i)){n.call(t,i,t[i],o||i);var c=t[i],d=s.util.type(c);"Object"!==d||a[r(c)]?"Array"!==d||a[r(c)]||(a[r(c)]=!0,e(c,n,i,a)):(a[r(c)]=!0,e(c,n,null,a))}}},plugins:{},highlight:function(e,t,n){var a={code:e,grammar:t,language:n};if(s.hooks.run("before-tokenize",a),!a.grammar)throw new Error('The language "'+a.language+'" has no grammar.');return a.tokens=s.tokenize(a.code,a.grammar),s.hooks.run("after-tokenize",a),o.stringify(s.util.encode(a.tokens),a.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var s in n)t[s]=n[s];delete t.rest}var o=new i;return c(o,o.head,e),r(e,o,t,o.head,0),function(e){for(var t=[],n=e.head.next;n!==e.tail;)t.push(n.value),n=n.next;return t}(o)},hooks:{all:{},add:function(e,t){var n=s.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=s.hooks.all[e];if(n&&n.length)for(var o,a=0;o=n[a++];)o(t)}},Token:o};function o(e,t,n,s){this.type=e,this.content=t,this.alias=n,this.length=0|(s||"").length}function a(e,t,n,s){e.lastIndex=t;var o=e.exec(n);if(o&&s&&o[1]){var a=o[1].length;o.index+=a,o[0]=o[0].slice(a)}return o}function r(e,t,n,i,u,l){for(var p in n)if(n.hasOwnProperty(p)&&n[p]){var m=n[p];m=Array.isArray(m)?m:[m];for(var g=0;g<m.length;++g){if(l&&l.cause==p+","+g)return;var f=m[g],h=f.inside,b=!!f.lookbehind,y=!!f.greedy,v=f.alias;if(y&&!f.pattern.global){var k=f.pattern.toString().match(/[imsuy]*$/)[0];f.pattern=RegExp(f.pattern.source,k+"g")}for(var x=f.pattern||f,w=i.next,_=u;w!==t.tail&&!(l&&_>=l.reach);_+=w.value.length,w=w.next){var S=w.value;if(t.length>e.length)return;if(!(S instanceof o)){var E,C=1;if(y){if(!(E=a(x,_,e,b))||E.index>=e.length)break;var T=E.index,A=E.index+E[0].length,j=_;for(j+=w.value.length;T>=j;)j+=(w=w.next).value.length;if(_=j-=w.value.length,w.value instanceof o)continue;for(var P=w;P!==t.tail&&(j<A||"string"==typeof P.value);P=P.next)C++,j+=P.value.length;C--,S=e.slice(_,j),E.index-=_}else if(!(E=a(x,0,S,b)))continue;T=E.index;var L=E[0],R=S.slice(0,T),N=S.slice(T+L.length),O=_+S.length;l&&O>l.reach&&(l.reach=O);var I=w.prev;if(R&&(I=c(t,I,R),_+=R.length),d(t,I,C),w=c(t,I,new o(p,h?s.tokenize(L,h):L,v,L)),N&&c(t,w,N),C>1){var D={cause:p+","+g,reach:O};r(e,t,n,w.prev,_,D),l&&D.reach>l.reach&&(l.reach=D.reach)}}}}}}function i(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function c(e,t,n){var s=t.next,o={value:n,prev:t,next:s};return t.next=o,s.prev=o,e.length++,o}function d(e,t,n){for(var s=t.next,o=0;o<n&&s!==e.tail;o++)s=s.next;t.next=s,s.prev=t,e.length-=o}return o.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var o="";return t.forEach((function(t){o+=e(t,n)})),o}var a={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},r=t.alias;r&&(Array.isArray(r)?Array.prototype.push.apply(a.classes,r):a.classes.push(r)),s.hooks.run("wrap",a);var i="";for(var c in a.attributes)i+=" "+c+'="'+(a.attributes[c]||"").replace(/"/g,""")+'"';return"<"+a.tag+' class="'+a.classes.join(" ")+'"'+i+">"+a.content+"</"+a.tag+">"},s}();t.exports=n,n.default=n}},function(){return i||(0,r[h(r)[0]])((i={exports:{}}).exports,i),i.exports}),C=((e,t,n)=>(n=null!=e?l(y(e)):{},((e,t,n,s)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let o of h(t))v.call(e,o)||o===n||p(e,o,{get:()=>t[o],enumerable:!(s=g(t,o))||s.enumerable});return e})(!t&&e&&e.__esModule?n:p(n,"default",{value:e,enumerable:!0}),e)))(E());C.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},C.languages.markup.tag.inside["attr-value"].inside.entity=C.languages.markup.entity,C.languages.markup.doctype.inside["internal-subset"].inside=C.languages.markup,C.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(C.languages.markup.tag,"addInlined",{value:function(e,t){var n;(t=((n=((n={})["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:C.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i,{"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}}))["language-"+t]={pattern:/[\s\S]+/,inside:C.languages[t]},{}))[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:n},C.languages.insertBefore("markup","cdata",t)}}),Object.defineProperty(C.languages.markup.tag,"addAttribute",{value:function(e,t){C.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:C.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),C.languages.html=C.languages.markup,C.languages.mathml=C.languages.markup,C.languages.svg=C.languages.markup,C.languages.xml=C.languages.extend("markup",{}),C.languages.ssml=C.languages.xml,C.languages.atom=C.languages.xml,C.languages.rss=C.languages.xml,function(e){var t={pattern:/\\[\\(){}[\]^$+*?|.]/,alias:"escape"},n=/\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|0[0-7]{0,2}|[123][0-7]{2}|c[a-zA-Z]|.)/,s="(?:[^\\\\-]|"+n.source+")",o=(s=RegExp(s+"-"+s),{pattern:/(<|')[^<>']+(?=[>']$)/,lookbehind:!0,alias:"variable"});e.languages.regex={"char-class":{pattern:/((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,lookbehind:!0,inside:{"char-class-negation":{pattern:/(^\[)\^/,lookbehind:!0,alias:"operator"},"char-class-punctuation":{pattern:/^\[|\]$/,alias:"punctuation"},range:{pattern:s,inside:{escape:n,"range-punctuation":{pattern:/-/,alias:"operator"}}},"special-escape":t,"char-set":{pattern:/\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},escape:n}},"special-escape":t,"char-set":{pattern:/\.|\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},backreference:[{pattern:/\\(?![123][0-7]{2})[1-9]/,alias:"keyword"},{pattern:/\\k<[^<>']+>/,alias:"keyword",inside:{"group-name":o}}],anchor:{pattern:/[$^]|\\[ABbGZz]/,alias:"function"},escape:n,group:[{pattern:/\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|<?[=!]|[idmnsuxU]+(?:-[idmnsuxU]+)?:?))?/,alias:"punctuation",inside:{"group-name":o}},{pattern:/\)/,alias:"punctuation"}],quantifier:{pattern:/(?:[+*?]|\{\d+(?:,\d*)?\})[?+]?/,alias:"number"},alternation:{pattern:/\|/,alias:"keyword"}}}(C),C.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},C.languages.javascript=C.languages.extend("clike",{"class-name":[C.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),C.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,C.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:C.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:C.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:C.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:C.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:C.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),C.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:C.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),C.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),C.languages.markup&&(C.languages.markup.tag.addInlined("script","javascript"),C.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),C.languages.js=C.languages.javascript,C.languages.actionscript=C.languages.extend("javascript",{keyword:/\b(?:as|break|case|catch|class|const|default|delete|do|dynamic|each|else|extends|final|finally|for|function|get|if|implements|import|in|include|instanceof|interface|internal|is|namespace|native|new|null|override|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|use|var|void|while|with)\b/,operator:/\+\+|--|(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=?)=?|[~?@]/}),C.languages.actionscript["class-name"].alias="function",delete C.languages.actionscript.parameter,delete C.languages.actionscript["literal-property"],C.languages.markup&&C.languages.insertBefore("actionscript","string",{xml:{pattern:/(^|[^.])<\/?\w+(?:\s+[^\s>\/=]+=("|')(?:\\[\s\S]|(?!\2)[^\\])*\2)*\s*\/?>/,lookbehind:!0,inside:C.languages.markup}}),d=/#(?!\{).+/,u={pattern:/#\{[^}]+\}/,alias:"variable"},(c=C).languages.coffeescript=c.languages.extend("javascript",{comment:d,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:u}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),c.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:d,interpolation:u}}}),c.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:c.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:u}}]}),c.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete c.languages.coffeescript["template-string"],c.languages.coffee=c.languages.coffeescript,function(e){var t=e.languages.javadoclike={parameter:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*@(?:arg|arguments|param)\s+)\w+/m,lookbehind:!0},keyword:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*|\{)@[a-z][a-zA-Z-]+\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(t,"addSupport",{value:function(t,n){(t="string"==typeof t?[t]:t).forEach((function(t){var s=function(e){e.inside||(e.inside={}),e.inside.rest=n},o="doc-comment";if(a=e.languages[t]){var a,r=a[o];if((r=r||(a=e.languages.insertBefore(t,"comment",{"doc-comment":{pattern:/(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,lookbehind:!0,alias:"comment"}}))[o])instanceof RegExp&&(r=a[o]={pattern:r}),Array.isArray(r))for(var i=0,c=r.length;i<c;i++)r[i]instanceof RegExp&&(r[i]={pattern:r[i]}),s(r[i]);else s(r)}}))}}),t.addSupport(["java","javascript","php"],t)}(C),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;(t=(e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css,e.languages.markup))&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(C),function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,n=(t=(e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+t.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[t,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}}),{pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0}),{pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0});e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|RebeccaPurple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,number:n})}(C),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,s="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),a=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function r(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return s})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return s}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return s})).replace(/<<key>>/g,(function(){return"(?:"+o+"|"+a+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:r(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:r(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:r(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:r(a),lookbehind:!0,greedy:!0},number:{pattern:r(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(C),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var s=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,o=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return s})),a=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source,r=(e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+o+a+"(?:"+o+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+o+a+")(?:"+o+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(s),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+o+")"+a+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+o+"$"),inside:{"table-header":{pattern:RegExp(s),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,s=t.length;n<s;n++){var o,a=t[n];"code"!==a.type?e(a.content):(o=a.content[1],a=a.content[3],o&&a&&"code-language"===o.type&&"code-block"===a.type&&"string"==typeof o.content&&(o=o.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),o="language-"+(o=(/[a-z][\w-]*/i.exec(o)||[""])[0].toLowerCase()),a.alias?"string"==typeof a.alias?a.alias=[a.alias,o]:a.alias.push(o):a.alias=[o]))}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",s=0,o=t.classes.length;s<o;s++){var a=t.classes[s];if(a=/language-(.+)/.exec(a)){n=a[1];break}}var d,u=e.languages[n];u?t.content=e.highlight(t.content.replace(r,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;return"#"===(t=t.toLowerCase())[0]?(n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),c(n)):i[t]||e})),u,n):n&&"none"!==n&&e.plugins.autoloader&&(d="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random()),t.attributes.id=d,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(d);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))})))}})),RegExp(e.languages.markup.tag.pattern.source,"gi")),i={amp:"&",lt:"<",gt:">",quot:'"'},c=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(C),C.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:C.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},C.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var s=t[n++];if("keyword"===s.type&&"mutation"===s.content){var o=[];if(l(["definition-mutation","punctuation"])&&"("===u(1).content){n+=2;var a=p(/^\($/,/^\)$/);if(-1===a)continue;for(;n<a;n++){var r=u(0);"variable"===r.type&&(m(r,"variable-input"),o.push(r.content))}n=a+1}if(l(["punctuation","property-query"])&&"{"===u(0).content&&(n++,m(u(0),"property-mutation"),0<o.length)){var i=p(/^\{$/,/^\}$/);if(-1!==i)for(var c=n;c<i;c++){var d=t[c];"variable"===d.type&&0<=o.indexOf(d.content)&&m(d,"variable-input")}}}}function u(e){return t[n+e]}function l(e,t){t=t||0;for(var n=0;n<e.length;n++){var s=u(n+t);if(!s||s.type!==e[n])return}return 1}function p(e,s){for(var o=1,a=n;a<t.length;a++){var r=t[a],i=r.content;if("punctuation"===r.type&&"string"==typeof i)if(e.test(i))o++;else if(s.test(i)&&0==--o)return a}return-1}function m(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),C.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,s=t.inside.interpolation,o=s.inside["interpolation-punctuation"],a=s.pattern.source;function r(t,s){if(e.languages[t])return{pattern:RegExp("((?:"+s+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function i(t,n,s){return t={code:t,grammar:n,language:s},e.hooks.run("before-tokenize",t),t.tokens=e.tokenize(t.code,t.grammar),e.hooks.run("after-tokenize",t),t.tokens}function c(t,n,r){var c=e.tokenize(t,{interpolation:{pattern:RegExp(a),lookbehind:!0}}),d=0,u={},l=(c=i(c.map((function(e){if("string"==typeof e)return e;var n,s;for(e=e.content;-1!==t.indexOf((s=d++,n="___"+r.toUpperCase()+"_"+s+"___")););return u[n]=e,n})).join(""),n,r),Object.keys(u));return d=0,function t(n){for(var a=0;a<n.length;a++){if(d>=l.length)return;var r,c,p,m,g,f,h,b=n[a];"string"==typeof b||"string"==typeof b.content?(r=l[d],-1!==(h=(f="string"==typeof b?b:b.content).indexOf(r))&&(++d,c=f.substring(0,h),g=u[r],p=void 0,(m={})["interpolation-punctuation"]=o,3===(m=e.tokenize(g,m)).length&&((p=[1,1]).push.apply(p,i(m[1],e.languages.javascript,"javascript")),m.splice.apply(m,p)),p=new e.Token("interpolation",m,s.alias,g),m=f.substring(h+r.length),g=[],c&&g.push(c),g.push(p),m&&(t(f=[m]),g.push.apply(g,f)),"string"==typeof b?(n.splice.apply(n,[a,1].concat(g)),a+=g.length-1):b.content=g)):(h=b.content,Array.isArray(h)?t(h):t([h]))}}(c),new e.Token(r,c,"language-"+r,t)}e.languages.javascript["template-string"]=[r("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),r("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),r("svg",/\bsvg/.source),r("markdown",/\b(?:markdown|md)/.source),r("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),r("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function u(e){return"string"==typeof e?e:Array.isArray(e)?e.map(u).join(""):u(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var s=0,o=n.length;s<o;s++){var a,r,i,d=n[s];"string"!=typeof d&&(a=d.content,Array.isArray(a)?"template-string"===d.type?(d=a[1],3===a.length&&"string"!=typeof d&&"embedded-code"===d.type&&(r=u(d),d=d.alias,d=Array.isArray(d)?d[0]:d,i=e.languages[d])&&(a[1]=c(r,i,d))):t(a):"string"!=typeof a&&t([a]))}}(t.tokens)}))}(C),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(C),function(e){var t=e.languages.javascript,n=/\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})+\}/.source,s="(@(?:arg|argument|param|property)\\s+(?:"+n+"\\s+)?)";e.languages.jsdoc=e.languages.extend("javadoclike",{parameter:{pattern:RegExp(s+/(?:(?!\s)[$\w\xA0-\uFFFF.])+(?=\s|$)/.source),lookbehind:!0,inside:{punctuation:/\./}}}),e.languages.insertBefore("jsdoc","keyword",{"optional-parameter":{pattern:RegExp(s+/\[(?:(?!\s)[$\w\xA0-\uFFFF.])+(?:=[^[\]]+)?\](?=\s|$)/.source),lookbehind:!0,inside:{parameter:{pattern:/(^\[)[$\w\xA0-\uFFFF\.]+/,lookbehind:!0,inside:{punctuation:/\./}},code:{pattern:/(=)[\s\S]*(?=\]$)/,lookbehind:!0,inside:t,alias:"language-javascript"},punctuation:/[=[\]]/}},"class-name":[{pattern:RegExp(/(@(?:augments|class|extends|interface|memberof!?|template|this|typedef)\s+(?:<TYPE>\s+)?)[A-Z]\w*(?:\.[A-Z]\w*)*/.source.replace(/<TYPE>/g,(function(){return n}))),lookbehind:!0,inside:{punctuation:/\./}},{pattern:RegExp("(@[a-z]+\\s+)"+n),lookbehind:!0,inside:{string:t.string,number:t.number,boolean:t.boolean,keyword:e.languages.typescript.keyword,operator:/=>|\.\.\.|[&|?:*]/,punctuation:/[.,;=<>{}()[\]]/}}],example:{pattern:/(@example\s+(?!\s))(?:[^@\s]|\s+(?!\s))+?(?=\s*(?:\*\s*)?(?:@\w|\*\/))/,lookbehind:!0,inside:{code:{pattern:/^([\t ]*(?:\*\s*)?)\S.*$/m,lookbehind:!0,inside:t,alias:"language-javascript"}}}}),e.languages.javadoclike.addSupport("javascript",e.languages.jsdoc)}(C),function(e){e.languages.flow=e.languages.extend("javascript",{}),e.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Bb]oolean|Function|[Nn]umber|[Ss]tring|[Ss]ymbol|any|mixed|null|void)\b/,alias:"class-name"}]}),e.languages.flow["function-variable"].pattern=/(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/i,delete e.languages.flow.parameter,e.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),Array.isArray(e.languages.flow.keyword)||(e.languages.flow.keyword=[e.languages.flow.keyword]),e.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:Class|declare|opaque|type)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:Diff|Enum|Exact|Keys|ObjMap|PropertyType|Record|Shape|Subtype|Supertype|await)\b(?!\$)/,lookbehind:!0})}(C),C.languages.n4js=C.languages.extend("javascript",{keyword:/\b(?:Array|any|boolean|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|module|new|null|number|package|private|protected|public|return|set|static|string|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/}),C.languages.insertBefore("n4js","constant",{annotation:{pattern:/@+\w+/,alias:"operator"}}),C.languages.n4jsd=C.languages.n4js,function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],s=0;s<n.length;s++){var o=n[s],a=e.languages.javascript[o];o=(a="RegExp"===e.util.type(a)?e.languages.javascript[o]={pattern:a}:a).inside||{};(a.inside=o)["maybe-class-name"]=/^[A-Z][\s\S]*/}}(C),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,s=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,o=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function a(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return s})).replace(/<SPREAD>/g,(function(){return o})),RegExp(e,t)}function r(t){for(var n=[],s=0;s<t.length;s++){var o=t[s],a=!1;"string"!=typeof o&&("tag"===o.type&&o.content[0]&&"tag"===o.content[0].type?"</"===o.content[0].content[0].content?0<n.length&&n[n.length-1].tagName===i(o.content[0].content[1])&&n.pop():"/>"!==o.content[o.content.length-1].content&&n.push({tagName:i(o.content[0].content[1]),openedBraces:0}):0<n.length&&"punctuation"===o.type&&"{"===o.content?n[n.length-1].openedBraces++:0<n.length&&0<n[n.length-1].openedBraces&&"punctuation"===o.type&&"}"===o.content?n[n.length-1].openedBraces--:a=!0),(a||"string"==typeof o)&&0<n.length&&0===n[n.length-1].openedBraces&&(a=i(o),s<t.length-1&&("string"==typeof t[s+1]||"plain-text"===t[s+1].type)&&(a+=i(t[s+1]),t.splice(s+1,1)),0<s&&("string"==typeof t[s-1]||"plain-text"===t[s-1].type)&&(a=i(t[s-1])+a,t.splice(s-1,1),s--),t[s]=new e.Token("plain-text",a,null,a)),o.content&&"string"!=typeof o.content&&r(o.content)}}o=a(o).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=a(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:a(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:a(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||r(e.tokens)}))}(C),function(e){var t=e.util.clone(e.languages.typescript);(t=(e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"],e.languages.tsx.tag)).pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(C),C.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+/(?:elseif|if)\b/.source+"(?:[ \t]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},C.languages.swift["string-literal"].forEach((function(e){e.inside.interpolation.inside=C.languages.swift})),function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(C),C.languages.c=C.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),C.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),C.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},C.languages.c.string],char:C.languages.c.char,comment:C.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:C.languages.c}}}}),C.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete C.languages.c.boolean,C.languages.objectivec=C.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete C.languages.objectivec["class-name"],C.languages.objc=C.languages.objectivec,C.languages.reason=C.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),C.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete C.languages.reason.function,function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source,n=0;n<2;n++)t=t.replace(/<self>/g,(function(){return t}));t=t.replace(/<self>/g,(function(){return/[^\s\S]/.source})),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(C),C.languages.go=C.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),C.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete C.languages.go["class-name"],function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(C),C.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},C.languages.python["string-interpolation"].inside.interpolation.inside.rest=C.languages.python,C.languages.py=C.languages.python;((e,t)=>{for(var n in t)p(e,n,{get:t[n],enumerable:!0})})({},{dracula:()=>T,duotoneDark:()=>A,duotoneLight:()=>j,github:()=>P,jettwaveDark:()=>q,jettwaveLight:()=>Q,nightOwl:()=>L,nightOwlLight:()=>R,oceanicNext:()=>I,okaidia:()=>D,oneDark:()=>V,oneLight:()=>H,palenight:()=>F,shadesOfPurple:()=>M,synthwave84:()=>z,ultramin:()=>B,vsDark:()=>$,vsLight:()=>U});var T={plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},A={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]},j={plain:{backgroundColor:"#faf8f5",color:"#728fcb"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#b6ad9a"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#063289"}},{types:["property","function"],style:{color:"#b29762"}},{types:["tag-id","selector","atrule-id"],style:{color:"#2d2006"}},{types:["attr-name"],style:{color:"#896724"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule"],style:{color:"#728fcb"}},{types:["placeholder","variable"],style:{color:"#93abdc"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#896724"}}]},P={plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},L={plain:{color:"#d6deeb",backgroundColor:"#011627"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(99, 119, 119)",fontStyle:"italic"}},{types:["string","url"],style:{color:"rgb(173, 219, 103)"}},{types:["variable"],style:{color:"rgb(214, 222, 235)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation"],style:{color:"rgb(199, 146, 234)"}},{types:["selector","doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(255, 203, 139)"}},{types:["tag","operator","keyword"],style:{color:"rgb(127, 219, 202)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["property"],style:{color:"rgb(128, 203, 196)"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}}]},R={plain:{color:"#403f53",backgroundColor:"#FBFBFB"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(72, 118, 214)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(152, 159, 177)",fontStyle:"italic"}},{types:["string","builtin","char","constant","url"],style:{color:"rgb(72, 118, 214)"}},{types:["variable"],style:{color:"rgb(201, 103, 101)"}},{types:["number"],style:{color:"rgb(170, 9, 130)"}},{types:["punctuation"],style:{color:"rgb(153, 76, 195)"}},{types:["function","selector","doctype"],style:{color:"rgb(153, 76, 195)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(17, 17, 17)"}},{types:["tag"],style:{color:"rgb(153, 76, 195)"}},{types:["operator","property","keyword","namespace"],style:{color:"rgb(12, 150, 155)"}},{types:["boolean"],style:{color:"rgb(188, 84, 84)"}}]},N="#c5a5c5",O="#8dc891",I={plain:{backgroundColor:"#282c34",color:"#ffffff"},styles:[{types:["attr-name"],style:{color:N}},{types:["attr-value"],style:{color:O}},{types:["comment","block-comment","prolog","doctype","cdata","shebang"],style:{color:"#999999"}},{types:["property","number","function-name","constant","symbol","deleted"],style:{color:"#5a9bcf"}},{types:["boolean"],style:{color:"#ff8b50"}},{types:["tag"],style:{color:"#fc929e"}},{types:["string"],style:{color:O}},{types:["punctuation"],style:{color:O}},{types:["selector","char","builtin","inserted"],style:{color:"#D8DEE9"}},{types:["function"],style:{color:"#79b6f2"}},{types:["operator","entity","url","variable"],style:{color:"#d7deea"}},{types:["keyword"],style:{color:N}},{types:["atrule","class-name"],style:{color:"#FAC863"}},{types:["important"],style:{fontWeight:"400"}},{types:["bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}}]},D={plain:{color:"#f8f8f2",backgroundColor:"#272822"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"#f92672",fontStyle:"italic"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"#8292a2",fontStyle:"italic"}},{types:["string","url"],style:{color:"#a6e22e"}},{types:["variable"],style:{color:"#f8f8f2"}},{types:["number"],style:{color:"#ae81ff"}},{types:["builtin","char","constant","function","class-name"],style:{color:"#e6db74"}},{types:["punctuation"],style:{color:"#f8f8f2"}},{types:["selector","doctype"],style:{color:"#a6e22e",fontStyle:"italic"}},{types:["tag","operator","keyword"],style:{color:"#66d9ef"}},{types:["boolean"],style:{color:"#ae81ff"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)",opacity:.7}},{types:["tag","property"],style:{color:"#f92672"}},{types:["attr-name"],style:{color:"#a6e22e !important"}},{types:["doctype"],style:{color:"#8292a2"}},{types:["rule"],style:{color:"#e6db74"}}]},F={plain:{color:"#bfc7d5",backgroundColor:"#292d3e"},styles:[{types:["comment"],style:{color:"rgb(105, 112, 152)",fontStyle:"italic"}},{types:["string","inserted"],style:{color:"rgb(195, 232, 141)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation","selector"],style:{color:"rgb(199, 146, 234)"}},{types:["variable"],style:{color:"rgb(191, 199, 213)"}},{types:["class-name","attr-name"],style:{color:"rgb(255, 203, 107)"}},{types:["tag","deleted"],style:{color:"rgb(255, 85, 114)"}},{types:["operator"],style:{color:"rgb(137, 221, 255)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["keyword"],style:{fontStyle:"italic"}},{types:["doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}},{types:["url"],style:{color:"rgb(221, 221, 221)"}}]},M={plain:{color:"#9EFEFF",backgroundColor:"#2D2A55"},styles:[{types:["changed"],style:{color:"rgb(255, 238, 128)"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)"}},{types:["comment"],style:{color:"rgb(179, 98, 255)",fontStyle:"italic"}},{types:["punctuation"],style:{color:"rgb(255, 255, 255)"}},{types:["constant"],style:{color:"rgb(255, 98, 140)"}},{types:["string","url"],style:{color:"rgb(165, 255, 144)"}},{types:["variable"],style:{color:"rgb(255, 238, 128)"}},{types:["number","boolean"],style:{color:"rgb(255, 98, 140)"}},{types:["attr-name"],style:{color:"rgb(255, 180, 84)"}},{types:["keyword","operator","property","namespace","tag","selector","doctype"],style:{color:"rgb(255, 157, 0)"}},{types:["builtin","char","constant","function","class-name"],style:{color:"rgb(250, 208, 0)"}}]},z={plain:{backgroundColor:"linear-gradient(to bottom, #2a2139 75%, #34294f)",backgroundImage:"#34294f",color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"},styles:[{types:["comment","block-comment","prolog","doctype","cdata"],style:{color:"#495495",fontStyle:"italic"}},{types:["punctuation"],style:{color:"#ccc"}},{types:["tag","attr-name","namespace","number","unit","hexcode","deleted"],style:{color:"#e2777a"}},{types:["property","selector"],style:{color:"#72f1b8",textShadow:"0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475"}},{types:["function-name"],style:{color:"#6196cc"}},{types:["boolean","selector-id","function"],style:{color:"#fdfdfd",textShadow:"0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975"}},{types:["class-name","maybe-class-name","builtin"],style:{color:"#fff5f6",textShadow:"0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75"}},{types:["constant","symbol"],style:{color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"}},{types:["important","atrule","keyword","selector-class"],style:{color:"#f4eee4",textShadow:"0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575"}},{types:["string","char","attr-value","regex","variable"],style:{color:"#f87c32"}},{types:["parameter"],style:{fontStyle:"italic"}},{types:["entity","url"],style:{color:"#67cdcc"}},{types:["operator"],style:{color:"ffffffee"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["entity"],style:{cursor:"help"}},{types:["inserted"],style:{color:"green"}}]},B={plain:{color:"#282a2e",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(197, 200, 198)"}},{types:["string","number","builtin","variable"],style:{color:"rgb(150, 152, 150)"}},{types:["class-name","function","tag","attr-name"],style:{color:"rgb(40, 42, 46)"}}]},$={plain:{color:"#9CDCFE",backgroundColor:"#1E1E1E"},styles:[{types:["prolog"],style:{color:"rgb(0, 0, 128)"}},{types:["comment"],style:{color:"rgb(106, 153, 85)"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"rgb(86, 156, 214)"}},{types:["number","inserted"],style:{color:"rgb(181, 206, 168)"}},{types:["constant"],style:{color:"rgb(100, 102, 149)"}},{types:["attr-name","variable"],style:{color:"rgb(156, 220, 254)"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"rgb(206, 145, 120)"}},{types:["selector"],style:{color:"rgb(215, 186, 125)"}},{types:["tag"],style:{color:"rgb(78, 201, 176)"}},{types:["tag"],languages:["markup"],style:{color:"rgb(86, 156, 214)"}},{types:["punctuation","operator"],style:{color:"rgb(212, 212, 212)"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"rgb(220, 220, 170)"}},{types:["class-name"],style:{color:"rgb(78, 201, 176)"}},{types:["char"],style:{color:"rgb(209, 105, 105)"}}]},U={plain:{color:"#000000",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},q={plain:{color:"#f8fafc",backgroundColor:"#011627"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#569CD6"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#f8fafc"}},{types:["attr-name","variable"],style:{color:"#9CDCFE"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#cbd5e1"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#D4D4D4"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#7dd3fc"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},Q={plain:{color:"#0f172a",backgroundColor:"#f1f5f9"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#0c4a6e"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#0f172a"}},{types:["attr-name","variable"],style:{color:"#0c4a6e"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#64748b"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#475569"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#0e7490"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},V={plain:{backgroundColor:"hsl(220, 13%, 18%)",color:"hsl(220, 14%, 71%)",textShadow:"0 1px rgba(0, 0, 0, 0.3)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(220, 10%, 40%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(220, 14%, 71%)"}},{types:["attr-name","class-name","maybe-class-name","boolean","constant","number","atrule"],style:{color:"hsl(29, 54%, 61%)"}},{types:["keyword"],style:{color:"hsl(286, 60%, 67%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(355, 65%, 65%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value"],style:{color:"hsl(95, 38%, 62%)"}},{types:["variable","operator","function"],style:{color:"hsl(207, 82%, 66%)"}},{types:["url"],style:{color:"hsl(187, 47%, 55%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(220, 14%, 71%)"}}]},H={plain:{backgroundColor:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(230, 4%, 64%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(230, 8%, 24%)"}},{types:["attr-name","class-name","boolean","constant","number","atrule"],style:{color:"hsl(35, 99%, 36%)"}},{types:["keyword"],style:{color:"hsl(301, 63%, 40%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(5, 74%, 59%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value","punctuation"],style:{color:"hsl(119, 34%, 47%)"}},{types:["variable","operator","function"],style:{color:"hsl(221, 87%, 60%)"}},{types:["url"],style:{color:"hsl(198, 99%, 37%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(230, 8%, 24%)"}}]},W=(e,t)=>{const{plain:n}=e,s=e.styles.reduce(((e,n)=>{const{languages:s,style:o}=n;return s&&!s.includes(t)||n.types.forEach((t=>{const n=w(w({},e[t]),o);e[t]=n})),e}),{});return s.root=n,s.plain=_(w({},n),{backgroundColor:void 0}),s},G=/\r\n|\r|\n/,X=e=>{0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},K=(e,t)=>{const n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)},Z=e=>{const t=[[]],n=[e],s=[0],o=[e.length];let a=0,r=0,i=[];const c=[i];for(;r>-1;){for(;(a=s[r]++)<o[r];){let e,d=t[r];const u=n[r][a];if("string"==typeof u?(d=r>0?d:["plain"],e=u):(d=K(d,u.type),u.alias&&(d=K(d,u.alias)),e=u.content),"string"!=typeof e){r++,t.push(d),n.push(e),s.push(0),o.push(e.length);continue}const l=e.split(G),p=l.length;i.push({types:d,content:l[0]});for(let t=1;t<p;t++)X(i),c.push(i=[]),i.push({types:d,content:l[t]})}r--,t.pop(),n.pop(),s.pop(),o.pop()}return X(i),c},Y=({children:e,language:t,code:n,theme:o,prism:r})=>{const i=t.toLowerCase(),c=((e,t)=>{const[n,o]=(0,s.useState)(W(t,e)),a=(0,s.useRef)(),r=(0,s.useRef)();return(0,s.useEffect)((()=>{t===a.current&&e===r.current||(a.current=t,r.current=e,o(W(t,e)))}),[e,t]),n})(i,o),d=(e=>(0,s.useCallback)((t=>{var n=t,{className:s,style:o,line:r}=n,i=S(n,["className","style","line"]);const c=_(w({},i),{className:a("token-line",s)});return"object"==typeof e&&"plain"in e&&(c.style=e.plain),"object"==typeof o&&(c.style=w(w({},c.style||{}),o)),c}),[e]))(c),u=(e=>{const t=(0,s.useCallback)((({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map((t=>e[t])))}),[e]);return(0,s.useCallback)((e=>{var n=e,{token:s,className:o,style:r}=n,i=S(n,["token","className","style"]);const c=_(w({},i),{className:a("token",...s.types,o),children:s.content,style:t(s)});return null!=r&&(c.style=w(w({},c.style||{}),r)),c}),[t])})(c),l=(({prism:e,code:t,grammar:n,language:o})=>{const a=(0,s.useRef)(e);return(0,s.useMemo)((()=>{if(null==n)return Z([t]);const e={code:t,grammar:n,language:o,tokens:[]};return a.current.hooks.run("before-tokenize",e),e.tokens=a.current.tokenize(t,n),a.current.hooks.run("after-tokenize",e),Z(e.tokens)}),[t,n,o])})({prism:r,language:i,code:n,grammar:r.languages[i]});return e({tokens:l,className:`prism-code language-${i}`,style:null!=c?c.root:{},getLineProps:d,getTokenProps:u})},J=e=>(0,s.createElement)(Y,_(w({},e),{prism:e.prism||C,theme:e.theme||$,code:e.code,language:e.language}))},11561:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var s=!0,o="Invariant failed";function a(e,t){if(!e){if(s)throw new Error(o);var n="function"==typeof t?t():t,a=n?"".concat(o,": ").concat(n):o;throw new Error(a)}}},31635:(e,t,n)=>{"use strict";n.r(t),n.d(t,{__addDisposableResource:()=>O,__assign:()=>a,__asyncDelegator:()=>E,__asyncGenerator:()=>S,__asyncValues:()=>C,__await:()=>_,__awaiter:()=>g,__classPrivateFieldGet:()=>L,__classPrivateFieldIn:()=>N,__classPrivateFieldSet:()=>R,__createBinding:()=>h,__decorate:()=>i,__disposeResources:()=>D,__esDecorate:()=>d,__exportStar:()=>b,__extends:()=>o,__generator:()=>f,__importDefault:()=>P,__importStar:()=>j,__makeTemplateObject:()=>T,__metadata:()=>m,__param:()=>c,__propKey:()=>l,__read:()=>v,__rest:()=>r,__runInitializers:()=>u,__setFunctionName:()=>p,__spread:()=>k,__spreadArray:()=>w,__spreadArrays:()=>x,__values:()=>y,default:()=>F});var s=function(e,t){return s=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},s(e,t)};function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}s(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return a=Object.assign||function(e){for(var t,n=1,s=arguments.length;n<s;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},a.apply(this,arguments)};function r(e,t){var n={};for(var s in e)Object.prototype.hasOwnProperty.call(e,s)&&t.indexOf(s)<0&&(n[s]=e[s]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(s=Object.getOwnPropertySymbols(e);o<s.length;o++)t.indexOf(s[o])<0&&Object.prototype.propertyIsEnumerable.call(e,s[o])&&(n[s[o]]=e[s[o]])}return n}function i(e,t,n,s){var o,a=arguments.length,r=a<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,n):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,n,s);else for(var i=e.length-1;i>=0;i--)(o=e[i])&&(r=(a<3?o(r):a>3?o(t,n,r):o(t,n))||r);return a>3&&r&&Object.defineProperty(t,n,r),r}function c(e,t){return function(n,s){t(n,s,e)}}function d(e,t,n,s,o,a){function r(e){if(void 0!==e&&"function"!=typeof e)throw new TypeError("Function expected");return e}for(var i,c=s.kind,d="getter"===c?"get":"setter"===c?"set":"value",u=!t&&e?s.static?e:e.prototype:null,l=t||(u?Object.getOwnPropertyDescriptor(u,s.name):{}),p=!1,m=n.length-1;m>=0;m--){var g={};for(var f in s)g[f]="access"===f?{}:s[f];for(var f in s.access)g.access[f]=s.access[f];g.addInitializer=function(e){if(p)throw new TypeError("Cannot add initializers after decoration has completed");a.push(r(e||null))};var h=(0,n[m])("accessor"===c?{get:l.get,set:l.set}:l[d],g);if("accessor"===c){if(void 0===h)continue;if(null===h||"object"!=typeof h)throw new TypeError("Object expected");(i=r(h.get))&&(l.get=i),(i=r(h.set))&&(l.set=i),(i=r(h.init))&&o.unshift(i)}else(i=r(h))&&("field"===c?o.unshift(i):l[d]=i)}u&&Object.defineProperty(u,s.name,l),p=!0}function u(e,t,n){for(var s=arguments.length>2,o=0;o<t.length;o++)n=s?t[o].call(e,n):t[o].call(e);return s?n:void 0}function l(e){return"symbol"==typeof e?e:"".concat(e)}function p(e,t,n){return"symbol"==typeof t&&(t=t.description?"[".concat(t.description,"]"):""),Object.defineProperty(e,"name",{configurable:!0,value:n?"".concat(n," ",t):t})}function m(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function g(e,t,n,s){return new(n||(n=Promise))((function(o,a){function r(e){try{c(s.next(e))}catch(t){a(t)}}function i(e){try{c(s.throw(e))}catch(t){a(t)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(r,i)}c((s=s.apply(e,t||[])).next())}))}function f(e,t){var n,s,o,a,r={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function i(i){return function(c){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a&&(a=0,i[0]&&(r=0)),r;)try{if(n=1,s&&(o=2&i[0]?s.return:i[0]?s.throw||((o=s.return)&&o.call(s),0):s.next)&&!(o=o.call(s,i[1])).done)return o;switch(s=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return r.label++,{value:i[1],done:!1};case 5:r.label++,s=i[1],i=[0];continue;case 7:i=r.ops.pop(),r.trys.pop();continue;default:if(!(o=r.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){r=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){r.label=i[1];break}if(6===i[0]&&r.label<o[1]){r.label=o[1],o=i;break}if(o&&r.label<o[2]){r.label=o[2],r.ops.push(i);break}o[2]&&r.ops.pop(),r.trys.pop();continue}i=t.call(e,r)}catch(c){i=[6,c],s=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,c])}}}var h=Object.create?function(e,t,n,s){void 0===s&&(s=n);var o=Object.getOwnPropertyDescriptor(t,n);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,s,o)}:function(e,t,n,s){void 0===s&&(s=n),e[s]=t[n]};function b(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||h(t,e,n)}function y(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],s=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&s>=e.length&&(e=void 0),{value:e&&e[s++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function v(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var s,o,a=n.call(e),r=[];try{for(;(void 0===t||t-- >0)&&!(s=a.next()).done;)r.push(s.value)}catch(i){o={error:i}}finally{try{s&&!s.done&&(n=a.return)&&n.call(a)}finally{if(o)throw o.error}}return r}function k(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(v(arguments[t]));return e}function x(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var s=Array(e),o=0;for(t=0;t<n;t++)for(var a=arguments[t],r=0,i=a.length;r<i;r++,o++)s[o]=a[r];return s}function w(e,t,n){if(n||2===arguments.length)for(var s,o=0,a=t.length;o<a;o++)!s&&o in t||(s||(s=Array.prototype.slice.call(t,0,o)),s[o]=t[o]);return e.concat(s||Array.prototype.slice.call(t))}function _(e){return this instanceof _?(this.v=e,this):new _(e)}function S(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var s,o=n.apply(e,t||[]),a=[];return s={},r("next"),r("throw"),r("return"),s[Symbol.asyncIterator]=function(){return this},s;function r(e){o[e]&&(s[e]=function(t){return new Promise((function(n,s){a.push([e,t,n,s])>1||i(e,t)}))})}function i(e,t){try{(n=o[e](t)).value instanceof _?Promise.resolve(n.value.v).then(c,d):u(a[0][2],n)}catch(s){u(a[0][3],s)}var n}function c(e){i("next",e)}function d(e){i("throw",e)}function u(e,t){e(t),a.shift(),a.length&&i(a[0][0],a[0][1])}}function E(e){var t,n;return t={},s("next"),s("throw",(function(e){throw e})),s("return"),t[Symbol.iterator]=function(){return this},t;function s(s,o){t[s]=e[s]?function(t){return(n=!n)?{value:_(e[s](t)),done:!1}:o?o(t):t}:o}}function C(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=y(e),t={},s("next"),s("throw"),s("return"),t[Symbol.asyncIterator]=function(){return this},t);function s(n){t[n]=e[n]&&function(t){return new Promise((function(s,o){(function(e,t,n,s){Promise.resolve(s).then((function(t){e({value:t,done:n})}),t)})(s,o,(t=e[n](t)).done,t.value)}))}}}function T(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var A=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t};function j(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&h(t,e,n);return A(t,e),t}function P(e){return e&&e.__esModule?e:{default:e}}function L(e,t,n,s){if("a"===n&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!s:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?s:"a"===n?s.call(e):s?s.value:t.get(e)}function R(e,t,n,s,o){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!o:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?o.call(e,n):o?o.value=n:t.set(e,n),n}function N(e,t){if(null===t||"object"!=typeof t&&"function"!=typeof t)throw new TypeError("Cannot use 'in' operator on non-object");return"function"==typeof e?t===e:e.has(t)}function O(e,t,n){if(null!=t){if("object"!=typeof t&&"function"!=typeof t)throw new TypeError("Object expected.");var s;if(n){if(!Symbol.asyncDispose)throw new TypeError("Symbol.asyncDispose is not defined.");s=t[Symbol.asyncDispose]}if(void 0===s){if(!Symbol.dispose)throw new TypeError("Symbol.dispose is not defined.");s=t[Symbol.dispose]}if("function"!=typeof s)throw new TypeError("Object not disposable.");e.stack.push({value:t,dispose:s,async:n})}else n&&e.stack.push({async:!0});return t}var I="function"==typeof SuppressedError?SuppressedError:function(e,t,n){var s=new Error(n);return s.name="SuppressedError",s.error=e,s.suppressed=t,s};function D(e){function t(t){e.error=e.hasError?new I(t,e.error,"An error was suppressed during disposal."):t,e.hasError=!0}return function n(){for(;e.stack.length;){var s=e.stack.pop();try{var o=s.dispose&&s.dispose.call(s.value);if(s.async)return Promise.resolve(o).then(n,(function(e){return t(e),n()}))}catch(a){t(a)}}if(e.hasError)throw e.error}()}const F={__extends:o,__assign:a,__rest:r,__decorate:i,__param:c,__metadata:m,__awaiter:g,__generator:f,__createBinding:h,__exportStar:b,__values:y,__read:v,__spread:k,__spreadArrays:x,__spreadArray:w,__await:_,__asyncGenerator:S,__asyncDelegator:E,__asyncValues:C,__makeTemplateObject:T,__importStar:j,__importDefault:P,__classPrivateFieldGet:L,__classPrivateFieldSet:R,__classPrivateFieldIn:N,__addDisposableResource:O,__disposeResources:D}},22654:e=>{"use strict";e.exports={}},84054:e=>{"use strict";e.exports=JSON.parse('{"/blog-5a1":{"__comp":"a6aa9e1f","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"04fe2bfd"}],"__props":"c15d9823"},"/blog/archive-182":{"__comp":"9e4087bc","__context":{"plugin":"36994c47"},"__props":"f81c1134"},"/blog/authors-0b7":{"__comp":"621db11d","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","__props":"ef8b811a"},"/blog/first-blog-post-fa7":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"4468ebd1"},"/blog/tags-287":{"__comp":"01a85c17","__context":{"plugin":"36994c47"},"sidebar":"814f3328","__props":"3a2db09e"},"/blog/tags/community-ef6":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"04fe2bfd"}],"__props":"dc8e8e39"},"/blog/tags/howto-5bd":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"04fe2bfd"}],"__props":"a6a72687"},"/search-822":{"__comp":"1a4e3797","__context":{"plugin":"138e0e15"}},"/community-874":{"__comp":"5e95c892","__context":{"plugin":"e0719818"}},"/community-63f":{"__comp":"a7bd4aaa","__props":"d2436a2b"},"/community-7eb":{"__comp":"a94703ab"},"/community/-067":{"__comp":"17896441","content":"edc931f8"},"/community/category/contribute-to-docs-5e1":{"__comp":"14eb3368","__props":"1bb8290c"},"/community/category/tools-c8f":{"__comp":"14eb3368","__props":"b6fc97b5"},"/community/central-services/plusserver-gx-scs-8a6":{"__comp":"17896441","content":"9099a3d2"},"/community/cloud-resources/-8ee":{"__comp":"17896441","content":"1722e234"},"/community/cloud-resources/getting-started-openstack-963":{"__comp":"17896441","content":"7bd33c3d"},"/community/cloud-resources/plusserver-gx-scs-ec9":{"__comp":"17896441","content":"35fbae7a"},"/community/cloud-resources/wavestack-a83":{"__comp":"17896441","content":"1f34ee25"},"/community/collaboration/-147":{"__comp":"17896441","content":"5cc619f0"},"/community/collaboration/sig-central-api-b3d":{"__comp":"17896441","content":"87293620"},"/community/collaboration/sig-community-c49":{"__comp":"17896441","content":"b7cec31e"},"/community/collaboration/sig-documentation-b1a":{"__comp":"17896441","content":"a63812ab"},"/community/collaboration/sig-monitoring-7fc":{"__comp":"17896441","content":"ea470413"},"/community/collaboration/sig-standardization-177":{"__comp":"17896441","content":"a52c62d4"},"/community/collaboration/team-container-7b3":{"__comp":"17896441","content":"b501f8e8"},"/community/collaboration/team-iaas-c05":{"__comp":"17896441","content":"97ef9758"},"/community/collaboration/team-iam-202":{"__comp":"17896441","content":"62337dff"},"/community/collaboration/team-ops-960":{"__comp":"17896441","content":"36c47bdd"},"/community/contribute/adding-docs-guide-cc6":{"__comp":"17896441","content":"a8f67d60"},"/community/contribute/doc-files-structure-guide-195":{"__comp":"17896441","content":"29c2cfba"},"/community/contribute/docs-workflow-explanation-d63":{"__comp":"17896441","content":"cffc493c"},"/community/contribute/linting-guide-088":{"__comp":"17896441","content":"096c51c8"},"/community/contribute/local-docusaurus-development-guide-83e":{"__comp":"17896441","content":"ef9d238d"},"/community/contribute/styleguide-a62":{"__comp":"17896441","content":"931040e8"},"/community/contribute/styleguides/ansible_styleguide-e67":{"__comp":"17896441","content":"b08c16de"},"/community/hackathons/checklist-592":{"__comp":"17896441","content":"49bc3785"},"/community/license-considerations-150":{"__comp":"17896441","content":"ce756c16"},"/community/mission-statement-532":{"__comp":"17896441","content":"19f6a518"},"/community/tools/github/branchprotection-f89":{"__comp":"17896441","content":"2886628e"},"/community/tools/github/dco-and-licenses-276":{"__comp":"17896441","content":"03412b54"},"/community/tools/github/tips-and-tricks-923":{"__comp":"17896441","content":"03babb4a"},"/community/tools/jitsi-a31":{"__comp":"17896441","content":"4e607b99"},"/community/tools/mailinglists-85e":{"__comp":"17896441","content":"5b909c46"},"/community/tools/matrix-9e6":{"__comp":"17896441","content":"420452be"},"/community/tools/nextcloud-f9d":{"__comp":"17896441","content":"1e818dbe"},"/community/tools/zuul-faa":{"__comp":"17896441","content":"45bfeaeb"},"/contributor-docs-a3e":{"__comp":"5e95c892","__context":{"plugin":"ffd7fd32"}},"/contributor-docs-5fd":{"__comp":"a7bd4aaa","__props":"46a1aa97"},"/contributor-docs-60f":{"__comp":"a94703ab"},"/contributor-docs/-5c4":{"__comp":"17896441","content":"0050251a"},"/contributor-docs/development/-b39":{"__comp":"17896441","content":"c9b16325"},"/contributor-docs/development/tests/rfc2119-keyword-test-guide-017":{"__comp":"17896441","content":"ff45c01b"},"/contributor-docs/development/tests/test-implementation-guide-8a6":{"__comp":"17896441","content":"cbf20d25"},"/contributor-docs/operations/iam/identity-federation-in-scs-b16":{"__comp":"17896441","content":"9a7c0197"},"/contributor-docs/operations/iam/openstack-federation-via-oidc-377":{"__comp":"17896441","content":"8d25d5d4"},"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide-ec0":{"__comp":"17896441","content":"950c7487"},"/docs-436":{"__comp":"5e95c892","__context":{"plugin":"aba21aa0"}},"/docs-fbe":{"__comp":"a7bd4aaa","__props":"0058b4c6"},"/docs-760":{"__comp":"a94703ab"},"/docs/-6df":{"__comp":"17896441","content":"4edc808e"},"/docs/category/api-be3":{"__comp":"14eb3368","__props":"7fedb4ba"},"/docs/category/automated-pentesting-357":{"__comp":"14eb3368","__props":"582db9b7"},"/docs/category/central-api-964":{"__comp":"14eb3368","__props":"0c1b7bd3"},"/docs/category/cluster-stacks-b3a":{"__comp":"14eb3368","__props":"aaebd759"},"/docs/category/components-d2a":{"__comp":"14eb3368","__props":"4f2b2ca4"},"/docs/category/components-1-6a9":{"__comp":"14eb3368","__props":"5201921d"},"/docs/category/components-2-df4":{"__comp":"14eb3368","__props":"946bf800"},"/docs/category/concepts-cd6":{"__comp":"14eb3368","__props":"db103552"},"/docs/category/configuration-cf7":{"__comp":"14eb3368","__props":"b5f86da1"},"/docs/category/container-registry-0a2":{"__comp":"14eb3368","__props":"5f46a90e"},"/docs/category/deployment-d76":{"__comp":"14eb3368","__props":"26ef8bfb"},"/docs/category/deployment-examples-e79":{"__comp":"14eb3368","__props":"b4dfe8b3"},"/docs/category/guides-1-377":{"__comp":"14eb3368","__props":"dd9a4eb2"},"/docs/category/guides-2-f14":{"__comp":"14eb3368","__props":"16ee6b7c"},"/docs/category/iaas-layer-8da":{"__comp":"14eb3368","__props":"87086dc6"},"/docs/category/metering-004":{"__comp":"14eb3368","__props":"2f1a0bb3"},"/docs/category/monitoring-eeb":{"__comp":"14eb3368","__props":"2e505a53"},"/docs/category/operating-scs-52c":{"__comp":"14eb3368","__props":"7eea03ab"},"/docs/category/pentesting-iaas-52a":{"__comp":"14eb3368","__props":"56dd32bb"},"/docs/category/pentesting-kaas-508":{"__comp":"14eb3368","__props":"bba00861"},"/docs/category/releases-358":{"__comp":"14eb3368","__props":"732919ef"},"/docs/category/scs-health-monitor-be7":{"__comp":"14eb3368","__props":"749c6f3f"},"/docs/category/status-page-cd8":{"__comp":"14eb3368","__props":"f6ed81c9"},"/docs/category/turnkey-solution-67f":{"__comp":"14eb3368","__props":"28f8b1f8"},"/docs/category/web-e39":{"__comp":"14eb3368","__props":"ea6d9109"},"/docs/container/-6db":{"__comp":"17896441","content":"3ff13a62"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow-5f7":{"__comp":"17896441","content":"d83cc1de"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow-89d":{"__comp":"17896441","content":"b43d8ee7"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview-c8a":{"__comp":"17896441","content":"6019e202"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow-74c":{"__comp":"17896441","content":"500c8deb"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow-3dc":{"__comp":"17896441","content":"291e1144"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept-15a":{"__comp":"17896441","content":"f699bead"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/-7f3":{"__comp":"17896441","content":"e1e9b906"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration-c53":{"__comp":"17896441","content":"f9fdfcc0"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing-e2e":{"__comp":"17896441","content":"9975996a"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack-247":{"__comp":"17896441","content":"63768f60"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology-fe2":{"__comp":"17896441","content":"aca4bcb1"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks-2e5":{"__comp":"17896441","content":"05370f9a"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart-175":{"__comp":"17896441","content":"9f357fc0"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot-8d7":{"__comp":"17896441","content":"b4038536"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow-333":{"__comp":"17896441","content":"964e3c50"},"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks-b05":{"__comp":"17896441","content":"b3e290f1"},"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers-2fa":{"__comp":"17896441","content":"f17f9c44"},"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop-057":{"__comp":"17896441","content":"8493ac52"},"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview-ae8":{"__comp":"17896441","content":"452be0ad"},"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart-408":{"__comp":"17896441","content":"287cd167"},"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting-d6e":{"__comp":"17896441","content":"eaf69a59"},"/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration-538":{"__comp":"17896441","content":"777b847b"},"/docs/container/components/cluster-stacks/components/cluster-stacks/overview-a87":{"__comp":"17896441","content":"a022b847"},"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration-2a9":{"__comp":"17896441","content":"d341f8b3"},"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart-20a":{"__comp":"17896441","content":"7f57b062"},"/docs/container/components/cluster-stacks/components/csctl/design-908":{"__comp":"17896441","content":"8ed6f0f1"},"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl-ce4":{"__comp":"17896441","content":"a64829d3"},"/docs/container/components/cluster-stacks/components/csctl/getting_started-2ab":{"__comp":"17896441","content":"5af709c8"},"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl-476":{"__comp":"17896441","content":"d5658917"},"/docs/container/components/cluster-stacks/components/csctl/overview-b0b":{"__comp":"17896441","content":"34fc7a35"},"/docs/container/components/cluster-stacks/components/csctl/quickstart-0dd":{"__comp":"17896441","content":"31e2019b"},"/docs/container/components/container-registry/docs/backup_and_restore-8f9":{"__comp":"17896441","content":"7bed4829"},"/docs/container/components/container-registry/docs/ha-deployment-799":{"__comp":"17896441","content":"abd7a988"},"/docs/container/components/container-registry/docs/migration-33a":{"__comp":"17896441","content":"bccb1b42"},"/docs/container/components/container-registry/docs/persistence-90e":{"__comp":"17896441","content":"7850b12c"},"/docs/container/components/container-registry/docs/quickstart-772":{"__comp":"17896441","content":"657efcba"},"/docs/container/components/container-registry/docs/rate_limit-017":{"__comp":"17896441","content":"c5479f59"},"/docs/container/components/container-registry/docs/scs-deployment-5f3":{"__comp":"17896441","content":"1ca0f8e7"},"/docs/container/components/container-registry/docs/upgrade-e27":{"__comp":"17896441","content":"19cb43cd"},"/docs/container/deployment-examples/a/-eab":{"__comp":"17896441","content":"83100446"},"/docs/container/deployment-examples/a/hardware-c9f":{"__comp":"17896441","content":"fe5fac7c"},"/docs/container/deployment-examples/a/software-4b1":{"__comp":"17896441","content":"0bcc5672"},"/docs/container/guides/guide1-fe9":{"__comp":"17896441","content":"dcf2f717"},"/docs/container/overview/architecture-96d":{"__comp":"17896441","content":"a94c36cd"},"/docs/container/overview/knowledge-b1b":{"__comp":"17896441","content":"f4cdb2d9"},"/docs/faq/-ab5":{"__comp":"17896441","content":"94f31572"},"/docs/getting-started/containerization-6c3":{"__comp":"17896441","content":"cd0ad4f0"},"/docs/getting-started/overview-4b2":{"__comp":"17896441","content":"19afbcc8"},"/docs/getting-started/virtualization-01b":{"__comp":"17896441","content":"e44168e5"},"/docs/glossary-c6d":{"__comp":"17896441","content":"e747ec83"},"/docs/iaas/components/-d45":{"__comp":"17896441","content":"86ee3414"},"/docs/iaas/components/flavor-manager-8e8":{"__comp":"17896441","content":"88684b71"},"/docs/iaas/components/image-manager/-ceb":{"__comp":"17896441","content":"2ce1dccd"},"/docs/iaas/components/image-manager/update-d83":{"__comp":"17896441","content":"7023f74c"},"/docs/iaas/components/openstack-health-monitor-d38":{"__comp":"17896441","content":"8db05b07"},"/docs/iaas/components/project-manager-b8e":{"__comp":"17896441","content":"a708848c"},"/docs/iaas/components/resource-manager-a61":{"__comp":"17896441","content":"685813dc"},"/docs/iaas/components/sandbox-manager-941":{"__comp":"17896441","content":"b8fd74b5"},"/docs/iaas/components/simple-stress-9d1":{"__comp":"17896441","content":"c49f9378"},"/docs/iaas/deployment-examples/artcodix/-9e8":{"__comp":"17896441","content":"c059aa33"},"/docs/iaas/guides/-df7":{"__comp":"17896441","content":"502adbf6"},"/docs/iaas/guides/concept-guide/-879":{"__comp":"17896441","content":"caeeb51c"},"/docs/iaas/guides/concept-guide/components/-631":{"__comp":"17896441","content":"d71eca41"},"/docs/iaas/guides/concept-guide/components/ceph-7ba":{"__comp":"17896441","content":"3ad2c61e"},"/docs/iaas/guides/concept-guide/components/clusterapi-e03":{"__comp":"17896441","content":"2ee7a08a"},"/docs/iaas/guides/concept-guide/components/gardener-ab9":{"__comp":"17896441","content":"ad1cb202"},"/docs/iaas/guides/concept-guide/components/ironic-4b7":{"__comp":"17896441","content":"e0c197a4"},"/docs/iaas/guides/concept-guide/components/k3s-481":{"__comp":"17896441","content":"fff06078"},"/docs/iaas/guides/concept-guide/components/keycloak-7d2":{"__comp":"17896441","content":"6bcd11f8"},"/docs/iaas/guides/concept-guide/components/netdata-071":{"__comp":"17896441","content":"0bb6d954"},"/docs/iaas/guides/concept-guide/components/openstack-5e1":{"__comp":"17896441","content":"3a1d878d"},"/docs/iaas/guides/concept-guide/components/prometheus-402":{"__comp":"17896441","content":"2abb9c6f"},"/docs/iaas/guides/concept-guide/components/sonic-133":{"__comp":"17896441","content":"066abe51"},"/docs/iaas/guides/concept-guide/components/teleport-bef":{"__comp":"17896441","content":"193dc870"},"/docs/iaas/guides/concept-guide/design-99a":{"__comp":"17896441","content":"71acf54e"},"/docs/iaas/guides/concept-guide/hardware-bom-98f":{"__comp":"17896441","content":"012688b3"},"/docs/iaas/guides/concept-guide/layers-d21":{"__comp":"17896441","content":"95800b3e"},"/docs/iaas/guides/concept-guide/nodes-6f1":{"__comp":"17896441","content":"1bc8ea4c"},"/docs/iaas/guides/concept-guide/use-cases-fcd":{"__comp":"17896441","content":"61171858"},"/docs/iaas/guides/configuration-guide/-2af":{"__comp":"17896441","content":"f0e20cb6"},"/docs/iaas/guides/configuration-guide/ceph-19e":{"__comp":"17896441","content":"6c33bb99"},"/docs/iaas/guides/configuration-guide/commons/-25b":{"__comp":"17896441","content":"3d19221e"},"/docs/iaas/guides/configuration-guide/commons/certificates-d0a":{"__comp":"17896441","content":"6e45ed1a"},"/docs/iaas/guides/configuration-guide/commons/packages-3a4":{"__comp":"17896441","content":"60fc342f"},"/docs/iaas/guides/configuration-guide/commons/resolvconf-d42":{"__comp":"17896441","content":"de6833f9"},"/docs/iaas/guides/configuration-guide/commons/services-97a":{"__comp":"17896441","content":"df35cf96"},"/docs/iaas/guides/configuration-guide/commons/sshconfig-505":{"__comp":"17896441","content":"05e7973d"},"/docs/iaas/guides/configuration-guide/commons/sysctl-635":{"__comp":"17896441","content":"e24c1f8d"},"/docs/iaas/guides/configuration-guide/commons/timezone-4b5":{"__comp":"17896441","content":"a51f78bf"},"/docs/iaas/guides/configuration-guide/commons/user-8d4":{"__comp":"17896441","content":"119c53e5"},"/docs/iaas/guides/configuration-guide/configuration-repository-b47":{"__comp":"17896441","content":"767805d3"},"/docs/iaas/guides/configuration-guide/inventory-559":{"__comp":"17896441","content":"6db2ece2"},"/docs/iaas/guides/configuration-guide/loadbalancer-f93":{"__comp":"17896441","content":"dcbc8e94"},"/docs/iaas/guides/configuration-guide/manager-3a7":{"__comp":"17896441","content":"57b63ae3"},"/docs/iaas/guides/configuration-guide/network-7d8":{"__comp":"17896441","content":"8b8a137c"},"/docs/iaas/guides/configuration-guide/openstack/-318":{"__comp":"17896441","content":"d0ee365b"},"/docs/iaas/guides/configuration-guide/openstack/aodh-9b8":{"__comp":"17896441","content":"4d571bd0"},"/docs/iaas/guides/configuration-guide/openstack/barbican-d39":{"__comp":"17896441","content":"755df717"},"/docs/iaas/guides/configuration-guide/openstack/ceilometer-910":{"__comp":"17896441","content":"b77ceb62"},"/docs/iaas/guides/configuration-guide/openstack/cinder-e9b":{"__comp":"17896441","content":"4f363fd8"},"/docs/iaas/guides/configuration-guide/openstack/designate-14f":{"__comp":"17896441","content":"0f0de498"},"/docs/iaas/guides/configuration-guide/openstack/glance-c89":{"__comp":"17896441","content":"9490f32b"},"/docs/iaas/guides/configuration-guide/openstack/heat-e58":{"__comp":"17896441","content":"befb6565"},"/docs/iaas/guides/configuration-guide/openstack/horizon-f63":{"__comp":"17896441","content":"f385820d"},"/docs/iaas/guides/configuration-guide/openstack/ironic-7b4":{"__comp":"17896441","content":"b65fe363"},"/docs/iaas/guides/configuration-guide/openstack/keystone-5bb":{"__comp":"17896441","content":"be01f2a0"},"/docs/iaas/guides/configuration-guide/openstack/magnum-9df":{"__comp":"17896441","content":"7217b34c"},"/docs/iaas/guides/configuration-guide/openstack/manila-2b1":{"__comp":"17896441","content":"e20b631f"},"/docs/iaas/guides/configuration-guide/openstack/neutron-efe":{"__comp":"17896441","content":"bceb927f"},"/docs/iaas/guides/configuration-guide/openstack/nova-88d":{"__comp":"17896441","content":"c9581477"},"/docs/iaas/guides/configuration-guide/openstack/octavia-493":{"__comp":"17896441","content":"25cf6706"},"/docs/iaas/guides/configuration-guide/openstack/placement-d48":{"__comp":"17896441","content":"32dcd940"},"/docs/iaas/guides/configuration-guide/openstack/skyline-f6d":{"__comp":"17896441","content":"8e8909f7"},"/docs/iaas/guides/configuration-guide/proxy-f21":{"__comp":"17896441","content":"bd8a97c5"},"/docs/iaas/guides/configuration-guide/rook-aad":{"__comp":"17896441","content":"6fe5bbf3"},"/docs/iaas/guides/configuration-guide/rookify-f93":{"__comp":"17896441","content":"dd5128a0"},"/docs/iaas/guides/configuration-guide/services/-4fe":{"__comp":"17896441","content":"0047ab5d"},"/docs/iaas/guides/configuration-guide/services/chrony-6aa":{"__comp":"17896441","content":"a2317717"},"/docs/iaas/guides/configuration-guide/services/docker-bba":{"__comp":"17896441","content":"8679ddc4"},"/docs/iaas/guides/configuration-guide/services/tuned-3ce":{"__comp":"17896441","content":"c0e025b3"},"/docs/iaas/guides/configuration-guide/validations/-36a":{"__comp":"17896441","content":"16c50622"},"/docs/iaas/guides/deploy-guide/-0d0":{"__comp":"17896441","content":"09ba26e2"},"/docs/iaas/guides/deploy-guide/bootstrap-4b5":{"__comp":"17896441","content":"6c4198a1"},"/docs/iaas/guides/deploy-guide/examples/-d9c":{"__comp":"17896441","content":"6f1c571c"},"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box-449":{"__comp":"17896441","content":"5565c8ed"},"/docs/iaas/guides/deploy-guide/examples/testbed-50d":{"__comp":"17896441","content":"bd319452"},"/docs/iaas/guides/deploy-guide/manager-3b6":{"__comp":"17896441","content":"6f4a06ca"},"/docs/iaas/guides/deploy-guide/provisioning-d32":{"__comp":"17896441","content":"67dad519"},"/docs/iaas/guides/deploy-guide/rookify-8e7":{"__comp":"17896441","content":"b1bfccfc"},"/docs/iaas/guides/deploy-guide/seed-159":{"__comp":"17896441","content":"45f4377b"},"/docs/iaas/guides/deploy-guide/services/-38d":{"__comp":"17896441","content":"89ad43f4"},"/docs/iaas/guides/deploy-guide/services/ceph-daa":{"__comp":"17896441","content":"760c57f4"},"/docs/iaas/guides/deploy-guide/services/infrastructure-a32":{"__comp":"17896441","content":"589280f5"},"/docs/iaas/guides/deploy-guide/services/kubernetes-22e":{"__comp":"17896441","content":"cda5fe29"},"/docs/iaas/guides/deploy-guide/services/logging-monitoring-305":{"__comp":"17896441","content":"abecca15"},"/docs/iaas/guides/deploy-guide/services/network-87b":{"__comp":"17896441","content":"4b015924"},"/docs/iaas/guides/deploy-guide/services/openstack-ff3":{"__comp":"17896441","content":"f2a59390"},"/docs/iaas/guides/deploy-guide/services/rook-045":{"__comp":"17896441","content":"e6263de7"},"/docs/iaas/guides/deploy-guide/services/rookify-974":{"__comp":"17896441","content":"58af14fe"},"/docs/iaas/guides/operations-guide/-a65":{"__comp":"17896441","content":"5bd7bc3b"},"/docs/iaas/guides/operations-guide/ceph-205":{"__comp":"17896441","content":"5d54de92"},"/docs/iaas/guides/operations-guide/infrastructure-4a9":{"__comp":"17896441","content":"d1c3b532"},"/docs/iaas/guides/operations-guide/manager/-be8":{"__comp":"17896441","content":"8fc094a7"},"/docs/iaas/guides/operations-guide/manager/apply-a48":{"__comp":"17896441","content":"abfb0638"},"/docs/iaas/guides/operations-guide/manager/console-99f":{"__comp":"17896441","content":"670b12e1"},"/docs/iaas/guides/operations-guide/manager/get-831":{"__comp":"17896441","content":"5199876b"},"/docs/iaas/guides/operations-guide/manager/log-be6":{"__comp":"17896441","content":"96f8fd49"},"/docs/iaas/guides/operations-guide/manager/task-78e":{"__comp":"17896441","content":"6d890b23"},"/docs/iaas/guides/operations-guide/network-061":{"__comp":"17896441","content":"d5947e44"},"/docs/iaas/guides/operations-guide/openstack/-b4a":{"__comp":"17896441","content":"d1aa920e"},"/docs/iaas/guides/operations-guide/openstack/cinder-186":{"__comp":"17896441","content":"a12f05ab"},"/docs/iaas/guides/operations-guide/openstack/keystone-7d7":{"__comp":"17896441","content":"748dce39"},"/docs/iaas/guides/operations-guide/openstack/neutron-675":{"__comp":"17896441","content":"d14d7097"},"/docs/iaas/guides/operations-guide/openstack/nova-373":{"__comp":"17896441","content":"8aade8b1"},"/docs/iaas/guides/operations-guide/openstack/octavia-639":{"__comp":"17896441","content":"f40b2df0"},"/docs/iaas/guides/operations-guide/openstack/tools/-cda":{"__comp":"17896441","content":"853df457"},"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager-4fc":{"__comp":"17896441","content":"6a0c14a5"},"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/-54e":{"__comp":"17896441","content":"5c2c818b"},"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update-3ac":{"__comp":"17896441","content":"0d2860b1"},"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor-049":{"__comp":"17896441","content":"94b13e0d"},"/docs/iaas/guides/operations-guide/openstack/tools/project-manager-87d":{"__comp":"17896441","content":"0121636f"},"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager-b80":{"__comp":"17896441","content":"b5a6d29b"},"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager-849":{"__comp":"17896441","content":"1967361e"},"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress-144":{"__comp":"17896441","content":"cf99a16e"},"/docs/iaas/guides/operations-guide/rook-91c":{"__comp":"17896441","content":"e4a5809a"},"/docs/iaas/guides/operations-guide/rookify-3de":{"__comp":"17896441","content":"3abbf0e9"},"/docs/iaas/guides/other-guides/-895":{"__comp":"17896441","content":"26dd306b"},"/docs/iaas/guides/other-guides/cloud-in-a-box/-a44":{"__comp":"17896441","content":"2ab96e79"},"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine-95f":{"__comp":"17896441","content":"e48c83c9"},"/docs/iaas/guides/other-guides/contributor-guide-815":{"__comp":"17896441","content":"5b235e06"},"/docs/iaas/guides/other-guides/developer-guide/-6cc":{"__comp":"17896441","content":"40d9468c"},"/docs/iaas/guides/other-guides/developer-guide/releases-f04":{"__comp":"17896441","content":"49993131"},"/docs/iaas/guides/other-guides/developer-guide/scripts-7e2":{"__comp":"17896441","content":"da1a5473"},"/docs/iaas/guides/other-guides/developer-guide/style-guide-867":{"__comp":"17896441","content":"e83ec39f"},"/docs/iaas/guides/other-guides/developer-guide/zuul-30c":{"__comp":"17896441","content":"9d49bc50"},"/docs/iaas/guides/other-guides/testbed-5a6":{"__comp":"17896441","content":"35b359a4"},"/docs/iaas/guides/troubleshooting-guide/-b72":{"__comp":"17896441","content":"ac087500"},"/docs/iaas/guides/troubleshooting-guide/ceph-23b":{"__comp":"17896441","content":"441bd449"},"/docs/iaas/guides/troubleshooting-guide/manager-558":{"__comp":"17896441","content":"eb99bfed"},"/docs/iaas/guides/troubleshooting-guide/openstack-ea9":{"__comp":"17896441","content":"c2f44c5f"},"/docs/iaas/guides/troubleshooting-guide/rookify-498":{"__comp":"17896441","content":"d35a3623"},"/docs/iaas/guides/upgrade-guide/-f35":{"__comp":"17896441","content":"fff9aecb"},"/docs/iaas/guides/upgrade-guide/ceph-29d":{"__comp":"17896441","content":"070e71f0"},"/docs/iaas/guides/upgrade-guide/docker-9f3":{"__comp":"17896441","content":"26bc5a46"},"/docs/iaas/guides/upgrade-guide/infrastructure-12a":{"__comp":"17896441","content":"dbde4c02"},"/docs/iaas/guides/upgrade-guide/logging-monitoring-ed7":{"__comp":"17896441","content":"c75320ff"},"/docs/iaas/guides/upgrade-guide/manager-45f":{"__comp":"17896441","content":"ecbad217"},"/docs/iaas/guides/upgrade-guide/network-f8c":{"__comp":"17896441","content":"fa7c4c29"},"/docs/iaas/guides/upgrade-guide/openstack-9bc":{"__comp":"17896441","content":"6d32cafb"},"/docs/iaas/guides/user-guide/-fa4":{"__comp":"17896441","content":"dc09f893"},"/docs/iaas/guides/user-guide/migration-vmware-esxi-b46":{"__comp":"17896441","content":"e4409f64"},"/docs/iaas/guides/user-guide/openstack/-b9e":{"__comp":"17896441","content":"bdaaff35"},"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso-842":{"__comp":"17896441","content":"e2bda29d"},"/docs/iaas/guides/user-guide/openstack/openstackclient-f0b":{"__comp":"17896441","content":"526893f8"},"/docs/iaas/guides/user-guide/openstack/security-groups-ae9":{"__comp":"17896441","content":"aed2f698"},"/docs/iaas/guides/user-guide/openstack/user-data-backups-5cd":{"__comp":"17896441","content":"915e2cf4"},"/docs/iaas/guides/user-guide/security-groups/-486":{"__comp":"17896441","content":"7d3935d1"},"/docs/iaas/guides/user-guide/user-data-backups-a9b":{"__comp":"17896441","content":"8092c627"},"/docs/iaas/overview/architecture-74b":{"__comp":"17896441","content":"9f356e5b"},"/docs/iaas/overview/compute-d18":{"__comp":"17896441","content":"73956345"},"/docs/iaas/overview/knowledge-a22":{"__comp":"17896441","content":"0a757274"},"/docs/iaas/overview/network-abc":{"__comp":"17896441","content":"3e493f26"},"/docs/iaas/overview/storage-187":{"__comp":"17896441","content":"c0cd111c"},"/docs/iam/-a74":{"__comp":"17896441","content":"b8c7b97f"},"/docs/iam/domain-manager-setup-and-usage-c6a":{"__comp":"17896441","content":"67140352"},"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations-e86":{"__comp":"17896441","content":"88f37d1b"},"/docs/iam/SCS-example-setup-configuration-description-fa9":{"__comp":"17896441","content":"65742e9f"},"/docs/operating-scs/audits/-bcc":{"__comp":"17896441","content":"36f749d2"},"/docs/operating-scs/components/automated-pentesting-iaas/overview-c28":{"__comp":"17896441","content":"ffa81568"},"/docs/operating-scs/components/automated-pentesting-iaas/quickstart-83c":{"__comp":"17896441","content":"db47e023"},"/docs/operating-scs/components/automated-pentesting-iaas/reports-5a2":{"__comp":"17896441","content":"f600298c"},"/docs/operating-scs/components/automated-pentesting-iaas/tools-248":{"__comp":"17896441","content":"cb18db4b"},"/docs/operating-scs/components/automated-pentesting-kaas/overview-174":{"__comp":"17896441","content":"5c8ebdd1"},"/docs/operating-scs/components/automated-pentesting-kaas/quickstart-202":{"__comp":"17896441","content":"fc3b013c"},"/docs/operating-scs/components/automated-pentesting-kaas/tools-784":{"__comp":"17896441","content":"b361e208"},"/docs/operating-scs/components/central-api/overview-b4c":{"__comp":"17896441","content":"b0ccdb87"},"/docs/operating-scs/components/central-api/poc-setup-647":{"__comp":"17896441","content":"9b5d9131"},"/docs/operating-scs/components/monitoring/docs/alertmanager-4f0":{"__comp":"17896441","content":"c6e1beb6"},"/docs/operating-scs/components/monitoring/docs/iaas-27c":{"__comp":"17896441","content":"e34f30ed"},"/docs/operating-scs/components/monitoring/docs/infrastructure_services-b85":{"__comp":"17896441","content":"53f25e30"},"/docs/operating-scs/components/monitoring/docs/k3s-4af":{"__comp":"17896441","content":"20da611c"},"/docs/operating-scs/components/monitoring/docs/kaas-819":{"__comp":"17896441","content":"2d071e49"},"/docs/operating-scs/components/monitoring/docs/oauth-e21":{"__comp":"17896441","content":"320ccb30"},"/docs/operating-scs/components/monitoring/docs/overview-961":{"__comp":"17896441","content":"0cb1d654"},"/docs/operating-scs/components/monitoring/docs/quickstart-a9d":{"__comp":"17896441","content":"19e9bde5"},"/docs/operating-scs/components/monitoring/docs/scs-deployment-8be":{"__comp":"17896441","content":"0e4c395f"},"/docs/operating-scs/components/monitoring/docs/status-page-28f":{"__comp":"17896441","content":"6cdfddef"},"/docs/operating-scs/components/monitoring/docs/tracing-207":{"__comp":"17896441","content":"55e21dcd"},"/docs/operating-scs/components/monitoring/docs/tuning-374":{"__comp":"17896441","content":"6d8acf16"},"/docs/operating-scs/components/monitoring/docs/zuul-6c6":{"__comp":"17896441","content":"013c29c1"},"/docs/operating-scs/components/scs-health-monitor/overview-2cd":{"__comp":"17896441","content":"315ee77a"},"/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack-b20":{"__comp":"17896441","content":"31d44bea"},"/docs/operating-scs/components/scs-health-monitor/Testflow-ec7":{"__comp":"17896441","content":"137a0b1a"},"/docs/operating-scs/components/scs-health-monitor/Workflow-cb0":{"__comp":"17896441","content":"757d752e"},"/docs/operating-scs/components/status-page-api/docs/configuration-2de":{"__comp":"17896441","content":"edaafa5c"},"/docs/operating-scs/components/status-page-api/docs/contribute-938":{"__comp":"17896441","content":"dc218a96"},"/docs/operating-scs/components/status-page-api/docs/example-requests-252":{"__comp":"17896441","content":"81875c35"},"/docs/operating-scs/components/status-page-api/docs/overview-568":{"__comp":"17896441","content":"d98f39e0"},"/docs/operating-scs/components/status-page-api/docs/quickstart-1f1":{"__comp":"17896441","content":"cd87bcd5"},"/docs/operating-scs/components/status-page-api/docs/requests-db7":{"__comp":"17896441","content":"0fd39870"},"/docs/operating-scs/components/status-page-api/docs/requirements-46e":{"__comp":"17896441","content":"78bb765a"},"/docs/operating-scs/components/status-page-deployment/docs/admin-authentication-dd4":{"__comp":"17896441","content":"53cbe722"},"/docs/operating-scs/components/status-page-deployment/docs/configuration-ce5":{"__comp":"17896441","content":"e10bed52"},"/docs/operating-scs/components/status-page-deployment/docs/contribute-058":{"__comp":"17896441","content":"41f0af85"},"/docs/operating-scs/components/status-page-deployment/docs/faq-516":{"__comp":"17896441","content":"531f0326"},"/docs/operating-scs/components/status-page-deployment/docs/k3s-11c":{"__comp":"17896441","content":"ae009198"},"/docs/operating-scs/components/status-page-deployment/docs/kind-c1f":{"__comp":"17896441","content":"fc83dba0"},"/docs/operating-scs/components/status-page-deployment/docs/monitoring-0c8":{"__comp":"17896441","content":"473bdf69"},"/docs/operating-scs/components/status-page-deployment/docs/overview-e6f":{"__comp":"17896441","content":"4913574b"},"/docs/operating-scs/components/status-page-deployment/docs/quickstart-0a0":{"__comp":"17896441","content":"6a49ee0a"},"/docs/operating-scs/components/status-page-deployment/docs/requirements-d0f":{"__comp":"17896441","content":"0f1ad89c"},"/docs/operating-scs/components/status-page-deployment/docs/scs-public-a6a":{"__comp":"17896441","content":"d902a273"},"/docs/operating-scs/components/status-page-deployment/docs/usage-78d":{"__comp":"17896441","content":"43915cdf"},"/docs/operating-scs/components/status-page-openapi/docs/component_overview-d26":{"__comp":"17896441","content":"0935f628"},"/docs/operating-scs/components/status-page-openapi/docs/components-199":{"__comp":"17896441","content":"f5cc95ce"},"/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus-544":{"__comp":"17896441","content":"b6ce023b"},"/docs/operating-scs/components/status-page-openapi/docs/overview-10a":{"__comp":"17896441","content":"f39ce5f1"},"/docs/operating-scs/components/status-page-web/docs/configuration-c4b":{"__comp":"17896441","content":"c12abb16"},"/docs/operating-scs/components/status-page-web/docs/contribute-cdf":{"__comp":"17896441","content":"0c2cbcc3"},"/docs/operating-scs/components/status-page-web/docs/overview-588":{"__comp":"17896441","content":"406caaae"},"/docs/operating-scs/components/status-page-web/docs/quickstart-ecd":{"__comp":"17896441","content":"9b12e85c"},"/docs/operating-scs/components/status-page-web/docs/requirements-162":{"__comp":"17896441","content":"fbd7a1e9"},"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install-ec3":{"__comp":"17896441","content":"b1fd1705"},"/docs/operating-scs/incident-management/-8c0":{"__comp":"17896441","content":"09adb968"},"/docs/operating-scs/lifecycle-management/-88c":{"__comp":"17896441","content":"a9f40339"},"/docs/operating-scs/logging/-ee2":{"__comp":"17896441","content":"343a1afc"},"/docs/operating-scs/metering/meter_configuration-124":{"__comp":"17896441","content":"41ab9761"},"/docs/operating-scs/monitoring/-799":{"__comp":"17896441","content":"15e4a743"},"/docs/operating-scs/overview-061":{"__comp":"17896441","content":"09cf625e"},"/docs/releases/Release0-984":{"__comp":"17896441","content":"7b787d81"},"/docs/releases/Release1-1b3":{"__comp":"17896441","content":"a3e11933"},"/docs/releases/Release2-9c9":{"__comp":"17896441","content":"7f1a31c3"},"/docs/releases/Release3-e73":{"__comp":"17896441","content":"5c201b0a"},"/docs/releases/Release4-9d8":{"__comp":"17896441","content":"437bedbc"},"/docs/releases/Release5-cb2":{"__comp":"17896441","content":"a0b1bbd7"},"/docs/releases/Release6-b81":{"__comp":"17896441","content":"2cc9d448"},"/docs/releases/Release7-b3c":{"__comp":"17896441","content":"a7769c8a"},"/docs/releases/ReleaseX-7e5":{"__comp":"17896441","content":"1bc22123"},"/docs/standards/-109":{"__comp":"17896441","content":"89176cae"},"/docs/turnkey-solution/hardware-landscape-f10":{"__comp":"17896441","content":"f4f96b66"},"/docs/turnkey-solution/overview-455":{"__comp":"17896441","content":"2c36e6c1"},"/standards-241":{"__comp":"5e95c892","__context":{"plugin":"f53abb4b"}},"/standards-01d":{"__comp":"a7bd4aaa","__props":"ff7b9a4c"},"/standards-1d5":{"__comp":"a94703ab"},"/standards/-9e3":{"__comp":"17896441","content":"929c4e1b"},"/standards/certification/overview-9ab":{"__comp":"17896441","content":"0ea173ba"},"/standards/certification/overview.template-562":{"__comp":"17896441","content":"26c6a551"},"/standards/certification/pipeline-159":{"__comp":"17896441","content":"fc07b5ea"},"/standards/certification/scopes-versions-ede":{"__comp":"17896441","content":"5447d460"},"/standards/global/-f4a":{"__comp":"17896441","content":"38c9ef35"},"/standards/global/scs-0001-6bf":{"__comp":"17896441","content":"f9ec068e"},"/standards/global/scs-0002-08f":{"__comp":"17896441","content":"a70dabb3"},"/standards/global/scs-0003-9d4":{"__comp":"17896441","content":"7e7cf0e4"},"/standards/global/scs-0004-3df":{"__comp":"17896441","content":"9890ac63"},"/standards/global/scs-0005-249":{"__comp":"17896441","content":"22869887"},"/standards/iaas/-804":{"__comp":"17896441","content":"3f3928dc"},"/standards/iaas/scs-0100-933":{"__comp":"17896441","content":"f1715aef"},"/standards/iaas/scs-0101-42d":{"__comp":"17896441","content":"477ed06d"},"/standards/iaas/scs-0102-78a":{"__comp":"17896441","content":"184e5ead"},"/standards/iaas/scs-0103-2e0":{"__comp":"17896441","content":"6ad9ab45"},"/standards/iaas/scs-0104-018":{"__comp":"17896441","content":"97b1504a"},"/standards/iaas/scs-0110-edb":{"__comp":"17896441","content":"64f9507b"},"/standards/iaas/scs-0111-fa3":{"__comp":"17896441","content":"7ace79c4"},"/standards/iaas/scs-0112-536":{"__comp":"17896441","content":"779440a1"},"/standards/iaas/scs-0113-819":{"__comp":"17896441","content":"a3dd9468"},"/standards/iaas/scs-0114-514":{"__comp":"17896441","content":"23d0e2bb"},"/standards/iaas/scs-0115-eb1":{"__comp":"17896441","content":"34c3e4b2"},"/standards/iaas/scs-0116-82c":{"__comp":"17896441","content":"8ec565c1"},"/standards/iaas/scs-0117-3ce":{"__comp":"17896441","content":"f4daec3f"},"/standards/iaas/scs-0118-389":{"__comp":"17896441","content":"b0f0cb2b"},"/standards/iaas/scs-0119-db8":{"__comp":"17896441","content":"926668e5"},"/standards/iaas/scs-0120-618":{"__comp":"17896441","content":"6e84ad78"},"/standards/iaas/scs-0121-37e":{"__comp":"17896441","content":"abd5b058"},"/standards/iaas/scs-0122-a6c":{"__comp":"17896441","content":"b36e6e7c"},"/standards/iaas/scs-0123-cd5":{"__comp":"17896441","content":"41be304a"},"/standards/iaas/scs-0124-19d":{"__comp":"17896441","content":"23c48947"},"/standards/iaas/scs-0125-2d1":{"__comp":"17896441","content":"6fc3ae76"},"/standards/iam/-ac3":{"__comp":"17896441","content":"abb47370"},"/standards/iam/scs-0300-171":{"__comp":"17896441","content":"23e62f09"},"/standards/iam/scs-0301-e8e":{"__comp":"17896441","content":"b74e5806"},"/standards/iam/scs-0302-469":{"__comp":"17896441","content":"c8d5479b"},"/standards/kaas/-a87":{"__comp":"17896441","content":"f8869d03"},"/standards/kaas/scs-0200-316":{"__comp":"17896441","content":"4a61a7c1"},"/standards/kaas/scs-0210-03c":{"__comp":"17896441","content":"422fff4b"},"/standards/kaas/scs-0211-a83":{"__comp":"17896441","content":"59307471"},"/standards/kaas/scs-0212-4a5":{"__comp":"17896441","content":"65c1efe1"},"/standards/kaas/scs-0213-922":{"__comp":"17896441","content":"52ac6bcf"},"/standards/kaas/scs-0214-952":{"__comp":"17896441","content":"b1eed1ab"},"/standards/kaas/scs-0215-fcf":{"__comp":"17896441","content":"ef682180"},"/standards/kaas/scs-0216-090":{"__comp":"17896441","content":"7fd33963"},"/standards/kaas/scs-0217-a99":{"__comp":"17896441","content":"6ddb698c"},"/standards/kaas/scs-0218-c81":{"__comp":"17896441","content":"742db51e"},"/standards/kaas/scs-0219-e54":{"__comp":"17896441","content":"54451aca"},"/standards/ops/-234":{"__comp":"17896441","content":"178df98e"},"/standards/ops/scs-0400-24b":{"__comp":"17896441","content":"a52f8495"},"/standards/ops/scs-0401-a98":{"__comp":"17896441","content":"5abd544f"},"/standards/ops/scs-0402-b21":{"__comp":"17896441","content":"37a5cb6b"},"/standards/ops/scs-0403-425":{"__comp":"17896441","content":"22aa5ce0"},"/standards/ops/scs-0410-529":{"__comp":"17896441","content":"3d9e0922"},"/standards/ops/scs-0411-44d":{"__comp":"17896441","content":"093291a8"},"/standards/ops/scs-0412-8c6":{"__comp":"17896441","content":"03c8668f"},"/standards/scs-0001-v1-sovereign-cloud-standards-695":{"__comp":"17896441","content":"1c894279"},"/standards/scs-0002-v1-standards-docs-org-0d6":{"__comp":"17896441","content":"5b402526"},"/standards/scs-0002-v2-standards-docs-org-33f":{"__comp":"17896441","content":"7b449e09"},"/standards/scs-0003-v1-sovereign-cloud-standards-yaml-27f":{"__comp":"17896441","content":"32227eef"},"/standards/scs-0004-v1-achieving-certification-a54":{"__comp":"17896441","content":"c7e8a920"},"/standards/scs-0005-v1-project-governance-948":{"__comp":"17896441","content":"ab2759ca"},"/standards/scs-0100-v1-flavor-naming-678":{"__comp":"17896441","content":"9d1324c7"},"/standards/scs-0100-v2-flavor-naming-c10":{"__comp":"17896441","content":"cd4fb20e"},"/standards/scs-0100-v3-flavor-naming-96d":{"__comp":"17896441","content":"061d8128"},"/standards/scs-0100-w1-flavor-naming-implementation-testing-6c8":{"__comp":"17896441","content":"640bb4cf"},"/standards/scs-0101-v1-entropy-474":{"__comp":"17896441","content":"63c8fde6"},"/standards/scs-0101-w1-entropy-implementation-testing-bff":{"__comp":"17896441","content":"bd8a0ffe"},"/standards/scs-0102-v1-image-metadata-173":{"__comp":"17896441","content":"ad39e84b"},"/standards/scs-0102-w1-image-metadata-implementation-testing-2f7":{"__comp":"17896441","content":"c1172cc8"},"/standards/scs-0103-v1-standard-flavors-495":{"__comp":"17896441","content":"526992cf"},"/standards/scs-0104-v1-standard-images-cd2":{"__comp":"17896441","content":"a4833b52"},"/standards/scs-0104-w1-standard-images-implementation-ba8":{"__comp":"17896441","content":"1300cb4e"},"/standards/scs-0110-v1-ssd-flavors-26f":{"__comp":"17896441","content":"1109f10b"},"/standards/scs-0111-v1-volume-type-decisions-8a3":{"__comp":"17896441","content":"699c0e5c"},"/standards/scs-0112-v1-sonic-a8a":{"__comp":"17896441","content":"28d842ee"},"/standards/scs-0113-v1-security-groups-decision-record-148":{"__comp":"17896441","content":"7cf96b3e"},"/standards/scs-0114-v1-volume-type-standard-161":{"__comp":"17896441","content":"04437fec"},"/standards/scs-0115-v1-default-rules-for-security-groups-e17":{"__comp":"17896441","content":"7aa8d561"},"/standards/scs-0116-v1-key-manager-standard-1f1":{"__comp":"17896441","content":"e84ae951"},"/standards/scs-0116-w1-key-manager-implementation-testing-1e6":{"__comp":"17896441","content":"dd4ba739"},"/standards/scs-0117-v1-volume-backup-service-ba1":{"__comp":"17896441","content":"ad59ba68"},"/standards/scs-0118-v1-taxonomy-of-failsafe-levels-4e3":{"__comp":"17896441","content":"90c33bef"},"/standards/scs-0118-w1-example-impacts-of-failure-scenarios-8da":{"__comp":"17896441","content":"dcae780a"},"/standards/scs-0119-v1-rook-decision-32d":{"__comp":"17896441","content":"604a51e1"},"/standards/scs-0120-v1-capi-images-d92":{"__comp":"17896441","content":"7ac7e960"},"/standards/scs-0121-v1-Availability-Zones-Standard-46b":{"__comp":"17896441","content":"0eef3953"},"/standards/scs-0121-w1-Availability-Zones-Standard-b4d":{"__comp":"17896441","content":"36d4bf8b"},"/standards/scs-0122-v1-node-to-node-encryption-b32":{"__comp":"17896441","content":"6cdabe05"},"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services-f7e":{"__comp":"17896441","content":"86bbda6f"},"/standards/scs-0124-v1-security-of-iaas-service-software-903":{"__comp":"17896441","content":"9782cb54"},"/standards/scs-0124-w1-security-of-iaas-service-software-ce8":{"__comp":"17896441","content":"28c03198"},"/standards/scs-0125-v1-secure-connections-9e2":{"__comp":"17896441","content":"130ed5c1"},"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests-7f6":{"__comp":"17896441","content":"c3529e0a"},"/standards/scs-0210-v1-k8s-new-version-policy-267":{"__comp":"17896441","content":"c5533f5e"},"/standards/scs-0210-v2-k8s-version-policy-76e":{"__comp":"17896441","content":"f5b4e375"},"/standards/scs-0210-w1-k8s-version-policy-implementation-testing-92b":{"__comp":"17896441","content":"310c7ee8"},"/standards/scs-0211-v1-kaas-default-storage-class-70e":{"__comp":"17896441","content":"07d3bac7"},"/standards/scs-0211-v2-kaas-default-storage-class-bf7":{"__comp":"17896441","content":"631b9b66"},"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing-254":{"__comp":"17896441","content":"3180fd0e"},"/standards/scs-0212-v1-requirements-for-container-registries-6e1":{"__comp":"17896441","content":"a35d3433"},"/standards/scs-0213-v1-k8s-nodes-anti-affinity-8e6":{"__comp":"17896441","content":"9278f3d6"},"/standards/scs-0214-v1-k8s-node-distribution-317":{"__comp":"17896441","content":"27f24dfd"},"/standards/scs-0214-v2-k8s-node-distribution-69c":{"__comp":"17896441","content":"4aabd97d"},"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing-155":{"__comp":"17896441","content":"3a36ab0d"},"/standards/scs-0215-v1-robustness-features-38c":{"__comp":"17896441","content":"0476f709"},"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks-a90":{"__comp":"17896441","content":"b262b314"},"/standards/scs-0217-v1-cluster-hardening-75e":{"__comp":"17896441","content":"b30e8b21"},"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation-288":{"__comp":"17896441","content":"73512cb1"},"/standards/scs-0219-v1-kaas-networking-5ef":{"__comp":"17896441","content":"9e156860"},"/standards/scs-0219-w1-kaas-networking-123":{"__comp":"17896441","content":"27e03890"},"/standards/scs-0300-v1-requirements-for-sso-identity-federation-34f":{"__comp":"17896441","content":"f68824be"},"/standards/scs-0301-v1-naming-conventions-6f1":{"__comp":"17896441","content":"d59f7d52"},"/standards/scs-0302-v1-domain-manager-role-b43":{"__comp":"17896441","content":"4e6fa974"},"/standards/scs-0302-w1-domain-manager-implementation-notes-128":{"__comp":"17896441","content":"09539d9b"},"/standards/scs-0400-v1-status-page-create-decision-279":{"__comp":"17896441","content":"eea6a18c"},"/standards/scs-0401-v1-status-page-reference-implementation-decision-cc0":{"__comp":"17896441","content":"dfce392e"},"/standards/scs-0402-v1-status-page-openapi-spec-decision-191":{"__comp":"17896441","content":"fd34a958"},"/standards/scs-0403-v1-csp-kaas-observability-stack-bb8":{"__comp":"17896441","content":"70b53392"},"/standards/scs-0410-v1-gnocchi-as-metering-database-44a":{"__comp":"17896441","content":"0dfeccb2"},"/standards/scs-0411-v1-publishing_method_for_metering_data-dbc":{"__comp":"17896441","content":"1276f6ab"},"/standards/scs-0412-v1-metering-json-3cc":{"__comp":"17896441","content":"a15c4cb6"},"/standards/scs-compatible-iaas-d6e":{"__comp":"17896441","content":"b191927f"},"/standards/scs-compatible-kaas-dc7":{"__comp":"17896441","content":"efbcd183"},"/standards/scs-XXXX-vN-decision-record-template-7f7":{"__comp":"17896441","content":"e2dcdabe"},"/standards/scs-XXXX-vN-standard-template-a6a":{"__comp":"17896441","content":"a24f5044"},"/standards/standards/overview-2a7":{"__comp":"17896441","content":"6738f543"},"/user-docs-75d":{"__comp":"5e95c892","__context":{"plugin":"85f4c940"}},"/user-docs-051":{"__comp":"a7bd4aaa","__props":"cdce7391"},"/user-docs-d7a":{"__comp":"a94703ab"},"/user-docs/-b14":{"__comp":"17896441","content":"14a658e6"},"/user-docs/application-examples/opendesk-on-scs/configuration-729":{"__comp":"17896441","content":"5d51a55a"},"/user-docs/application-examples/opendesk-on-scs/contribute-a2f":{"__comp":"17896441","content":"f14428ad"},"/user-docs/application-examples/opendesk-on-scs/getting_started-7a9":{"__comp":"17896441","content":"ca219831"},"/user-docs/application-examples/opendesk-on-scs/overview-e94":{"__comp":"17896441","content":"c06491c2"},"/user-docs/application-examples/opendesk-on-scs/quickstart-2a5":{"__comp":"17896441","content":"440f3548"},"/user-docs/application-examples/opendesk-on-scs/requirements-1ed":{"__comp":"17896441","content":"2c0d30da"},"/user-docs/application-examples/opendesk-on-scs/user-import-4de":{"__comp":"17896441","content":"79a28527"},"/user-docs/category/application-examples-066":{"__comp":"14eb3368","__props":"cdb233b1"},"/user-docs/category/opendesk-on-scs-8dc":{"__comp":"14eb3368","__props":"1c94670e"},"/-e5f":{"__comp":"1df93b7f","__context":{"plugin":"a7456010"},"config":"5e9f5e1a"}}')}},e=>{e.O(0,[71869],(()=>{return t=77815,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/assets/js/main.f32cb623.js.LICENSE.txt b/assets/js/main.f32cb623.js.LICENSE.txt new file mode 100644 index 0000000000..5b49ae6363 --- /dev/null +++ b/assets/js/main.f32cb623.js.LICENSE.txt @@ -0,0 +1,126 @@ +/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT */ + +/*! + * lunr.Builder + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Set + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.TokenSet + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Vector + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.stemmer + * Copyright (C) 2020 Oliver Nightingale + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + */ + +/*! + * lunr.stopWordFilter + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.tokenizer + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.trimmer + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! Bundled license information: + +prismjs/prism.js: + (** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT <https://opensource.org/licenses/MIT> + * @author Lea Verou <https://lea.verou.me> + * @namespace + * @public + *) +*/ + +/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @license React + * react-jsx-runtime.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @license React + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */ + +/** @license React v16.13.1 + * react-is.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ diff --git a/assets/js/runtime~main.65aaf317.js b/assets/js/runtime~main.65aaf317.js new file mode 100644 index 0000000000..8660f25531 --- /dev/null +++ b/assets/js/runtime~main.65aaf317.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,c,b,d,a,f={},t={};function r(e){var c=t[e];if(void 0!==c)return c.exports;var b=t[e]={exports:{}};return f[e].call(b.exports,b,b.exports,r),b.exports}r.m=f,e=[],r.O=(c,b,d,a)=>{if(!b){var f=1/0;for(i=0;i<e.length;i++){b=e[i][0],d=e[i][1],a=e[i][2];for(var t=!0,o=0;o<b.length;o++)(!1&a||f>=a)&&Object.keys(r.O).every((e=>r.O[e](b[o])))?b.splice(o--,1):(t=!1,a<f&&(f=a));if(t){e.splice(i--,1);var n=d();void 0!==n&&(c=n)}}return c}a=a||0;for(var i=e.length;i>0&&e[i-1][2]>a;i--)e[i]=e[i-1];e[i]=[b,d,a]},r.n=e=>{var c=e&&e.__esModule?()=>e.default:()=>e;return r.d(c,{a:c}),c},b=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var a=Object.create(null);r.r(a);var f={};c=c||[null,b({}),b([]),b(b)];for(var t=2&d&&e;"object"==typeof t&&!~c.indexOf(t);t=b(t))Object.getOwnPropertyNames(t).forEach((c=>f[c]=()=>e[c]));return f.default=()=>e,r.d(a,f),a},r.d=(e,c)=>{for(var b in c)r.o(c,b)&&!r.o(e,b)&&Object.defineProperty(e,b,{enumerable:!0,get:c[b]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((c,b)=>(r.f[b](e,c),c)),[])),r.u=e=>"assets/js/"+({86:"32dcd940",644:"6fc3ae76",660:"c2f44c5f",751:"f9ec068e",974:"7ace79c4",1085:"0bcc5672",1193:"f699bead",1396:"d83cc1de",1591:"54451aca",1822:"5abd544f",1911:"420452be",2621:"5c201b0a",2683:"7d3935d1",2884:"89ad43f4",2925:"e10bed52",3453:"a12f05ab",3639:"f40b2df0",3714:"3d19221e",3813:"23c48947",4168:"63c8fde6",4365:"853df457",4880:"8092c627",4979:"f17f9c44",4980:"67dad519",5238:"5d51a55a",5546:"452be0ad",5658:"2ee7a08a",5912:"ea6d9109",6063:"eb99bfed",6148:"09adb968",6305:"8aade8b1",6337:"757d752e",6358:"640bb4cf",6646:"b0ccdb87",6934:"e1e9b906",6960:"8679ddc4",7344:"09539d9b",7628:"fc83dba0",7984:"a0b1bbd7",8209:"01a85c17",8373:"b43d8ee7",8514:"1bc8ea4c",8592:"49bc3785",8655:"d35a3623",8834:"6a0c14a5",9285:"9782cb54",9382:"03412b54",9416:"fbd7a1e9",9539:"57b63ae3",9647:"5e95c892",9689:"b77ceb62",9701:"6cdabe05",9755:"a24f5044",9766:"36c47bdd",10296:"86bbda6f",10329:"e84ae951",10488:"dc8e8e39",10667:"96f8fd49",11159:"b1bfccfc",11290:"a15c4cb6",11362:"7aa8d561",11407:"c75320ff",11572:"19cb43cd",11935:"28c03198",11945:"0050251a",11953:"685813dc",12106:"04fe2bfd",12196:"e4a5809a",12473:"56dd32bb",12479:"fe5fac7c",12526:"edc931f8",13043:"287cd167",13131:"38c9ef35",13527:"dc09f893",13605:"1109f10b",13974:"31e2019b",14111:"1bc22123",14132:"27f24dfd",14385:"760c57f4",14602:"36f749d2",14605:"4f363fd8",14712:"16c50622",14840:"19afbcc8",15058:"0047ab5d",15220:"e0719818",16218:"2c0d30da",16323:"23d0e2bb",16568:"9d1324c7",16594:"2f1a0bb3",17051:"e0c197a4",17491:"20da611c",18096:"6fe5bbf3",18121:"3a2db09e",18146:"c15d9823",18401:"17896441",18463:"a8f67d60",18519:"767805d3",18659:"d98f39e0",18872:"582db9b7",18897:"73512cb1",19289:"c8d5479b",19303:"130ed5c1",19407:"8e8909f7",19512:"dd9a4eb2",19653:"f6ed81c9",19691:"a52f8495",19745:"437bedbc",19807:"ce756c16",20082:"748dce39",20126:"c49f9378",20309:"71acf54e",20344:"0476f709",20717:"0c1b7bd3",20904:"9278f3d6",21009:"061d8128",21249:"531f0326",21698:"28f8b1f8",22151:"88684b71",22270:"6e84ad78",22339:"27e03890",22672:"779440a1",23008:"5199876b",23786:"0c2cbcc3",23844:"2ab96e79",23953:"5c8ebdd1",24170:"d341f8b3",24485:"1967361e",24497:"bd8a0ffe",24730:"b74e5806",24984:"7bed4829",25152:"b36e6e7c",25162:"caeeb51c",25429:"755df717",25595:"f8869d03",25930:"473bdf69",26018:"a3dd9468",26083:"73956345",26223:"d0ee365b",26529:"97ef9758",26590:"36d4bf8b",26608:"41f0af85",26918:"406caaae",27379:"137a0b1a",27425:"dd4ba739",27683:"35b359a4",27841:"f385820d",27980:"a708848c",28439:"bba00861",28460:"49993131",28965:"343a1afc",29093:"efbcd183",29226:"4d571bd0",30458:"07d3bac7",30675:"7850b12c",30825:"a51f78bf",31036:"0935f628",31525:"ffd7fd32",31669:"81875c35",31810:"55e21dcd",31909:"e44168e5",32233:"732919ef",32914:"26bc5a46",33384:"0e4c395f",33444:"19f6a518",33475:"b65fe363",33559:"e4409f64",33760:"fc07b5ea",34062:"f4f96b66",34257:"45bfeaeb",34312:"85f4c940",34583:"1df93b7f",34826:"16ee6b7c",34855:"cf99a16e",34870:"964e3c50",35122:"fa7c4c29",35210:"f9fdfcc0",35575:"cbf20d25",35742:"aba21aa0",35894:"7f57b062",36070:"f68824be",36084:"b4038536",36182:"0cb1d654",36647:"f1715aef",36707:"5b909c46",36831:"df35cf96",37074:"8b8a137c",37362:"b1eed1ab",37568:"dd5128a0",37643:"a6aa9e1f",37778:"2886628e",37810:"1ca0f8e7",37919:"d14d7097",38040:"9b12e85c",38384:"3ad2c61e",38411:"ac087500",38730:"ea470413",38781:"742db51e",38947:"ef8b811a",39049:"fd34a958",39432:"e747ec83",39464:"7f1a31c3",39864:"ef9d238d",40163:"34c3e4b2",40192:"7bd33c3d",40714:"cffc493c",40935:"31d44bea",41298:"9890ac63",41335:"1e818dbe",41479:"f0e20cb6",42140:"0fd39870",42309:"de6833f9",42372:"6f4a06ca",42441:"4e607b99",42456:"950c7487",42637:"59307471",42686:"7fedb4ba",42747:"abd7a988",43136:"2c36e6c1",43213:"3f3928dc",43400:"a2317717",43536:"bd8a97c5",43705:"4a61a7c1",43745:"58af14fe",43848:"26ef8bfb",43862:"f53abb4b",44657:"ad39e84b",44684:"1276f6ab",44716:"c059aa33",44810:"6c33bb99",44850:"87293620",45054:"8493ac52",45075:"a70dabb3",45123:"7b449e09",45147:"65742e9f",45350:"cdce7391",45568:"a52c62d4",45673:"89176cae",45676:"41ab9761",45929:"ff7b9a4c",45978:"6d32cafb",46008:"5af709c8",46098:"7217b34c",46125:"3a36ab0d",46251:"8fc094a7",46334:"83100446",46347:"0f1ad89c",46471:"ca219831",46774:"fc3b013c",46866:"8ec565c1",46969:"14eb3368",47020:"befb6565",47191:"ad59ba68",47475:"f4daec3f",47813:"52ac6bcf",47861:"d5947e44",48130:"f81c1134",48296:"0a757274",48561:"502adbf6",48625:"749c6f3f",49063:"bdaaff35",49648:"5cc619f0",49745:"f4cdb2d9",49851:"441bd449",50640:"6019e202",50676:"ae009198",51001:"5b402526",51276:"093291a8",51400:"61171858",51528:"b501f8e8",51548:"a94c36cd",52076:"4b015924",52179:"c0e025b3",52257:"7b787d81",52342:"26dd306b",52711:"9e4087bc",53156:"d5658917",53429:"32227eef",53530:"589280f5",53649:"fff9aecb",53652:"1bb8290c",53681:"b262b314",53767:"09cf625e",53894:"1f34ee25",53920:"d1aa920e",54252:"e48c83c9",54644:"291e1144",54725:"87086dc6",55139:"d59f7d52",55235:"14a658e6",55251:"012688b3",55663:"65c1efe1",55743:"3ff13a62",55790:"64f9507b",56699:"7eea03ab",56986:"bccb1b42",57013:"a022b847",57153:"5c2c818b",57633:"eaf69a59",57695:"d902a273",57743:"931040e8",57753:"a4833b52",57938:"b7cec31e",58407:"119c53e5",58523:"5b235e06",58561:"6ad9ab45",59075:"04437fec",59346:"b6ce023b",59417:"b4dfe8b3",59495:"dcbc8e94",60183:"4aabd97d",60778:"f5b4e375",60837:"d2436a2b",60953:"2d071e49",60988:"184e5ead",61235:"a7456010",61238:"657efcba",61329:"7ac7e960",61427:"9b5d9131",61902:"79a28527",61976:"604a51e1",62016:"5565c8ed",62069:"3d9e0922",62138:"1a4e3797",62294:"03babb4a",62312:"f5cc95ce",62350:"dcae780a",62673:"22869887",62840:"cda5fe29",63365:"86ee3414",63663:"8db05b07",63811:"9e156860",63919:"670b12e1",63935:"dc218a96",64175:"19e9bde5",64212:"621db11d",64277:"8d25d5d4",64625:"cd0ad4f0",64921:"138e0e15",65679:"6ddb698c",65770:"7cf96b3e",65981:"edaafa5c",66290:"ff45c01b",66846:"abd5b058",66910:"22aa5ce0",66947:"5f46a90e",66971:"bd319452",67085:"c6e1beb6",67098:"a7bd4aaa",67148:"0d2860b1",67214:"b5f86da1",67255:"070e71f0",67299:"5d54de92",67472:"814f3328",67548:"b361e208",67560:"abecca15",67677:"320ccb30",67731:"ef682180",67768:"53cbe722",68226:"b5a6d29b",68502:"6bcd11f8",68965:"45f4377b",68966:"23e62f09",68992:"d1c3b532",69110:"70b53392",69346:"c5533f5e",69356:"6db2ece2",69657:"a3e11933",69752:"94f31572",69859:"cb18db4b",70337:"c06491c2",70445:"dbde4c02",70467:"d71eca41",70557:"4e6fa974",70643:"5bd7bc3b",71001:"8ed6f0f1",71255:"1722e234",71351:"066abe51",71682:"631b9b66",71755:"cdb233b1",72111:"e6263de7",72283:"c5479f59",72439:"e83ec39f",73281:"6cdfddef",73374:"6d8acf16",73405:"28d842ee",73634:"500c8deb",73739:"c1172cc8",74507:"03c8668f",74612:"7e7cf0e4",75013:"0f0de498",75341:"0ea173ba",75515:"95800b3e",75717:"b6fc97b5",75804:"26c6a551",75875:"9d49bc50",76153:"ab2759ca",76372:"2abb9c6f",76443:"b8c7b97f",76793:"abfb0638",76871:"c3529e0a",77125:"da1a5473",77479:"0bb6d954",77609:"aaebd759",78031:"3a1d878d",78081:"bceb927f",78215:"b1fd1705",78340:"3180fd0e",78353:"315ee77a",78423:"0eef3953",78526:"7fd33963",78532:"9975996a",78981:"dcf2f717",79001:"777b847b",79048:"a94703ab",79089:"2e505a53",79245:"eea6a18c",79692:"90c33bef",79728:"ffa81568",80123:"a35d3433",80231:"3abbf0e9",80272:"e20b631f",80281:"c12abb16",80295:"310c7ee8",80332:"53f25e30",80639:"f600298c",81475:"526992cf",81542:"c7e8a920",81804:"1c894279",81903:"acecf23e",82336:"1c94670e",82346:"526893f8",82798:"c9b16325",83160:"db47e023",83249:"ccc49370",83292:"9f357fc0",83574:"2cc9d448",83709:"f14428ad",83725:"699c0e5c",83802:"929c4e1b",83874:"9490f32b",83881:"5447d460",84093:"a7769c8a",84331:"6d890b23",84398:"dfce392e",84480:"e24c1f8d",84813:"6875c492",85066:"6a49ee0a",85075:"abb47370",85609:"15e4a743",85612:"aed2f698",86164:"a9f40339",86227:"422fff4b",86273:"1300cb4e",86293:"c9581477",86376:"b0f0cb2b",86397:"63768f60",86452:"b191927f",86512:"43915cdf",87638:"6c4198a1",87701:"a6a72687",87915:"4f2b2ca4",88071:"6f1c571c",88142:"a64829d3",88477:"c0cd111c",89031:"b3e290f1",89260:"915e2cf4",89295:"78bb765a",89376:"62337dff",89390:"b08c16de",89823:"05e7973d",89858:"36994c47",89954:"be01f2a0",90205:"41be304a",90308:"4edc808e",90495:"db103552",90783:"40d9468c",90849:"0058b4c6",90923:"013c29c1",91026:"2ce1dccd",91099:"e2dcdabe",91384:"37a5cb6b",91617:"35fbae7a",91770:"926668e5",91844:"9f356e5b",92078:"f2a59390",92544:"096c51c8",92671:"6738f543",92710:"fff06078",92864:"05370f9a",93086:"ad1cb202",93153:"b8fd74b5",93402:"9a7c0197",93502:"477ed06d",93575:"67140352",93750:"aca4bcb1",94342:"0dfeccb2",94346:"97b1504a",94561:"46a1aa97",94604:"6e45ed1a",94869:"7023f74c",95113:"cd87bcd5",95369:"5201921d",95752:"0121636f",96029:"3e493f26",96147:"a63812ab",96162:"e2bda29d",96165:"cd4fb20e",96172:"9099a3d2",96211:"e34f30ed",96454:"ecbad217",96578:"b30e8b21",96707:"94b13e0d",96734:"88f37d1b",97104:"25cf6706",97399:"34fc7a35",98029:"178df98e",98220:"193dc870",98547:"29c2cfba",98805:"4468ebd1",98842:"946bf800",99084:"4913574b",99115:"f39ce5f1",99244:"09ba26e2",99417:"440f3548",99525:"60fc342f"}[e]||e)+"."+{86:"91903a0a",644:"848f939b",660:"5d661d61",751:"68698bfe",974:"ce536d3f",1085:"88b461b0",1193:"9990054f",1396:"b0074640",1591:"cfaeb709",1822:"b98c658e",1911:"2c62066d",2049:"521b0348",2621:"496063fc",2683:"c1d6c0c5",2884:"7fe772fe",2925:"df61e061",3347:"c5d6f453",3453:"9ccbfb1c",3639:"8c50ef9e",3714:"8a0b07e0",3813:"4f17eb98",4168:"2f7c854f",4365:"10d87070",4880:"8dbfdb0c",4979:"9f524a69",4980:"876abf01",5238:"1b9992ea",5546:"89efc290",5658:"2d5ef364",5912:"a6de4ddb",6063:"fbf47341",6148:"9cd91f6b",6305:"73db4d76",6337:"d944558e",6358:"796304ba",6646:"ef8f6cd2",6934:"d09031b2",6960:"72ea5f42",7344:"59dc480e",7628:"9b03d070",7984:"edd55850",8209:"38b15a38",8373:"1a648d6b",8514:"0307fde5",8592:"4e9d7a4e",8655:"1db1366c",8834:"d402eafd",8989:"29b1d9c8",8995:"d61fabd9",9285:"f1211dbe",9312:"1b4382f8",9382:"4d6caf84",9416:"e85339ad",9539:"f868e196",9647:"510adb24",9689:"e56cf4a5",9701:"08192f0c",9755:"a36944eb",9766:"094edef4",10296:"ec6e62bf",10329:"6420a661",10488:"7b411376",10667:"9a2a8354",10711:"74e33c32",11159:"76e67101",11290:"d48da5a3",11362:"00a49cfb",11407:"146dbcd8",11572:"a2a348a3",11935:"0fca2cc1",11945:"2b225ffc",11953:"ae72c5c6",12106:"00c9a014",12196:"42e8872f",12473:"ad20d845",12479:"9896d0a3",12526:"1cdfc14a",13043:"a1547f74",13131:"6b1b4eed",13527:"d46295ee",13605:"7aa2aa13",13974:"ad1d60d1",14111:"adc9690c",14132:"0e160ba7",14385:"e141c5f5",14602:"2c85dfe6",14605:"38359925",14712:"0126b3da",14840:"0b722e3d",15058:"5743080d",15220:"791bd268",15857:"19881860",16218:"93627fee",16323:"e4d271b6",16568:"524219d1",16594:"710e4e6d",17051:"04fb4e06",17491:"14fadce4",18096:"525f7f31",18121:"a962eb9b",18146:"6a506149",18401:"6f5cb6f8",18463:"246a5b3b",18519:"fde639bc",18659:"16de317a",18872:"0ca28036",18897:"aecc1b98",19289:"1facc27a",19303:"5f2d06ff",19407:"44847530",19512:"c92386f4",19653:"f623c022",19691:"7eb9c8a1",19745:"a0a08777",19807:"f16871e2",20082:"f0c56a18",20126:"4b59087c",20309:"7bd75dcf",20344:"59f3f3b0",20717:"62cd96f8",20904:"53a89b33",21009:"ded2488d",21176:"8b369431",21249:"7a5db3da",21689:"e6a22cb4",21698:"a20caeef",21987:"d9c4f162",22130:"0233c4cc",22151:"89e9c6a0",22270:"56a078df",22315:"26935523",22339:"02584dc7",22672:"5b3250e4",23008:"b6ef7c5d",23417:"726793c8",23687:"3e0df620",23786:"3647afbf",23844:"bb47bad9",23953:"b48f254f",24073:"f2ca0f12",24104:"f591bad1",24170:"ff4aa669",24485:"77da87d9",24497:"88762ccc",24730:"aaabaa3e",24984:"7e567bbb",25152:"3c11eda7",25162:"657fcbd3",25429:"1e39cd42",25595:"94ccab66",25930:"b1ee068d",26018:"afb100f4",26083:"997f14ed",26223:"2f7697ee",26529:"3e3e3ab4",26590:"49617d24",26608:"0ea3a7d8",26918:"533c43b8",27379:"d3bd71ef",27425:"4776bdf3",27683:"4bad58e8",27841:"e61458f8",27899:"de8c0f95",27980:"bb930b4d",28439:"4c43338c",28460:"a37e22c3",28965:"cd8b95a6",29093:"c107b2c9",29226:"0dba39e1",30458:"8fda13ab",30675:"6900b675",30825:"575e352a",31036:"14e0eee9",31329:"9487c967",31525:"5a60c8df",31669:"6b699ce6",31810:"9036e01a",31909:"c714f7d5",32233:"0cd1044f",32914:"b8c798b6",33384:"6819d356",33444:"9228f3d8",33475:"d5a40099",33559:"190e6014",33760:"41f626b2",34062:"e938f80d",34257:"2b7e3720",34312:"47e4267d",34583:"39dc7e68",34826:"283ab39f",34855:"9342a7aa",34870:"7dea5c6a",35122:"ba18c231",35210:"67bf78fc",35575:"f9a8d060",35742:"5d49a645",35860:"bf296fec",35894:"c96590ca",36070:"2624aad4",36084:"fce62e81",36182:"f5aaff36",36647:"857f8540",36707:"3fcb1277",36831:"26d44ffc",37074:"7fe34161",37362:"95975c42",37568:"7c8eac03",37643:"b0b42d8e",37778:"34d61deb",37810:"5b356902",37919:"b01d73d7",38040:"7cfd4145",38384:"ff4e783f",38411:"941ecada",38730:"59e25e2e",38781:"d20d3503",38947:"44f93fed",39049:"eb4a43e0",39432:"cdaefe9a",39464:"0547f437",39864:"64dfafa5",40163:"0ecfe87d",40192:"22c19cee",40714:"4c29b257",40935:"facefabd",41298:"1a13b384",41335:"462fbdf9",41479:"263154cd",42140:"3c6f1821",42309:"60fa945f",42372:"07e27793",42441:"5f1183b2",42456:"4bf72790",42637:"7a3949d7",42686:"5431b26b",42747:"ce89e052",43136:"61127581",43213:"56e36d76",43400:"6cbf1afd",43498:"6eca7dce",43536:"eafa0cca",43705:"e4fe4d53",43745:"340fce71",43848:"441bf3ab",43862:"36a5d3a8",44657:"931af984",44684:"73361147",44716:"292aac2a",44810:"9dde0a6a",44850:"8eba45f7",45054:"68e06ebf",45075:"97147162",45123:"2c162399",45147:"f8247f2b",45350:"0c8f9884",45568:"455d8dd1",45673:"fc177988",45676:"c95ba8c0",45741:"81122685",45929:"29b46cb9",45978:"e459fc70",46008:"b61d63bd",46098:"91fa3ac2",46125:"30a77aa2",46251:"9c1360a7",46334:"ccca8e9e",46347:"1bb16bc8",46471:"13d44dfe",46774:"c19f5a8a",46866:"b8273d7c",46969:"bce869b4",47020:"9a5015b1",47191:"acc0ad04",47475:"6aed5561",47813:"8a3524d7",47861:"777965a9",48130:"412030c3",48296:"588aeb9b",48561:"4d5032e2",48625:"84e9f1ed",48846:"2215b4ad",49063:"ab3b1d93",49648:"4875b8d9",49745:"b75924eb",49851:"1e4679b6",50141:"eccf700d",50640:"bd6b2e0c",50676:"054ba784",50971:"384492b6",51001:"b5a4ca2a",51169:"37d3e1c7",51276:"2a67108d",51400:"031dde5a",51528:"4820dcbe",51548:"b00c2914",52076:"98e11af0",52179:"a2028aa3",52257:"220d9003",52342:"baa3b0e4",52711:"adb8dec7",53156:"a0a8db03",53292:"ed8f5a00",53429:"57791a6a",53530:"5a1b93cc",53649:"45d0c1ff",53652:"c9447e76",53681:"6d6c1d38",53767:"62a9af43",53894:"dab9c4a7",53920:"94404ca3",54252:"0f77ba54",54644:"a80b3444",54725:"e66910db",55139:"cb222074",55235:"26921b79",55251:"ab8d0d7c",55663:"0d3c3932",55743:"4623da87",55790:"2e07f353",56625:"4f3f2239",56699:"50b38516",56986:"d92c74a9",57013:"57572d71",57153:"1f3d21ad",57633:"2b56db9e",57695:"09b18c45",57743:"f6c51dd2",57753:"a4bcc5e1",57938:"225821b8",58407:"ba041e2a",58523:"1e6a7888",58561:"44339de7",59075:"659ced76",59346:"22d2187b",59417:"2e391262",59495:"87f03815",60183:"dbedceb2",60778:"98fb71e1",60837:"5bb66ee4",60953:"e08425dd",60988:"246ccf4c",61235:"d921c339",61238:"b2a58c44",61329:"7c05b3ea",61427:"8e559210",61902:"29cdea05",61976:"853bf504",62016:"b7be1492",62069:"22db4721",62138:"14ddfd7e",62294:"9e0d0bfd",62312:"555c9990",62350:"12089a91",62673:"2b3d9b3d",62840:"29570c45",63365:"73e5b2c8",63663:"2b969d73",63811:"6bfbfbb9",63919:"e4675d98",63935:"6ba7c083",64175:"a29dc131",64212:"bdeb36a5",64277:"7179def6",64529:"568dd26f",64625:"89dc2191",64921:"8230ceeb",65679:"2ddb76c9",65770:"325281e7",65981:"9d47e0a3",66290:"a2c19573",66846:"ddc4f600",66910:"fa2cb810",66947:"dc07a7ac",66971:"ead4aaf5",67085:"237bf4df",67098:"8c94a49f",67148:"73e3b874",67214:"e7c50e28",67255:"11720dbf",67299:"a4e02751",67472:"1f680611",67548:"6471b5b4",67560:"c6b48db0",67677:"4f011db4",67731:"fc22b3a9",67768:"bc1489ef",68226:"a2e40d9d",68502:"2746e1bc",68965:"e52402bc",68966:"4919e30c",68992:"739f0858",69110:"154172c9",69346:"4312e23c",69356:"082b688c",69657:"e7101d2e",69752:"a38e1964",69859:"25b31e2e",70337:"ca853aa9",70445:"c1ec7a9b",70467:"63dcb63b",70557:"da72c9e2",70643:"e5b3ca33",71001:"517c99d9",71255:"0a4fa590",71351:"483c88c4",71682:"f4f4c562",71755:"e9079335",72111:"9d9463ef",72283:"3cd2d794",72439:"bb775013",73281:"8a31cf20",73374:"f2bd0ec7",73405:"e9a5c66c",73634:"9b501f1f",73739:"3d7136b0",74507:"3952c747",74612:"d71bb551",75013:"9b49c638",75341:"2a37f9e0",75515:"941f0ed8",75717:"89dbb78c",75804:"de394283",75875:"7940b5df",76153:"6af1358f",76372:"658c3960",76443:"0111641c",76793:"d59c1857",76871:"fd20a084",77125:"00cab2c3",77479:"24833c61",77609:"badbff06",78031:"38aa923b",78081:"22ef34a7",78215:"dfffdf58",78340:"24b8ae34",78353:"43c90a4c",78423:"9ab7cf8b",78526:"7807ee19",78532:"a094cb45",78981:"7fe3db53",79001:"7e264f36",79048:"68fdd05f",79089:"791a4104",79245:"1c0a20ad",79692:"0e31e6ea",79728:"dc6a50d4",80123:"082ebf56",80231:"9c0ef763",80272:"8f51fa59",80281:"f1b7276e",80295:"ba4abbd3",80332:"1cfdd75b",80639:"6a37af8c",81475:"5d92f843",81542:"2290b9a0",81804:"fd86a422",81903:"7516ff6f",82144:"09311b61",82237:"b1e220fa",82336:"716d1f7b",82346:"2f4ff1f6",82798:"c24a123d",83160:"024cc770",83249:"7d02ad21",83292:"0bb06e82",83574:"804fac55",83709:"606a7d10",83725:"e586dad1",83802:"d3bd3dc5",83874:"4fd635b9",83881:"3fb8c19c",84093:"7076b235",84331:"e2d6a950",84398:"dc8ba0a6",84480:"f1046400",84813:"d1eb8b03",85066:"b2514060",85075:"912c6252",85609:"7be84146",85612:"6961a962",85628:"087505cc",86164:"50671081",86227:"f89f91ff",86273:"81845503",86293:"5bb98b23",86376:"efce416d",86397:"450b8941",86452:"704e1471",86512:"5b6049bd",86770:"d286033f",87638:"92e8d0f7",87701:"9bf1523d",87915:"f39fe1fd",88071:"97bd125f",88142:"2b4d713a",88146:"59c80a39",88477:"3c50b3be",89031:"50a67625",89260:"f9eacce0",89295:"7bfa1d7f",89376:"287ce250",89390:"389bc875",89823:"690723a4",89858:"63c2e6ec",89954:"04e74b46",90205:"2cd07daf",90308:"f6c7122c",90489:"a37158f4",90495:"585bfc17",90783:"18cd8ac5",90849:"7244ccd9",90923:"a7e3cf87",91026:"7c208000",91099:"13cfa021",91384:"73cefc7d",91617:"f73644fd",91770:"2343e730",91844:"ee373634",92078:"c536ca08",92544:"3a7b9861",92671:"435cfaa6",92704:"fd1e7d31",92710:"afa5a33b",92864:"e603f28e",93086:"ee6712e8",93153:"d750270a",93402:"c49ff924",93502:"f275f379",93575:"53708a8c",93750:"15d839cf",94342:"f7dfd56f",94346:"e20afa14",94561:"feddc5a1",94564:"9666d094",94604:"7be08fca",94869:"082ec029",95113:"3055b308",95163:"5c1563b3",95369:"508dd58e",95752:"e159d662",96029:"c3d21fd8",96147:"46f4a502",96162:"8b3be122",96165:"47779d1c",96172:"0a60597a",96211:"9713edfa",96454:"01bde511",96578:"dde25c3d",96707:"62b81f20",96734:"f355f8d9",97104:"ef87443d",97399:"59c1b86e",98029:"ed94b47d",98220:"df956eb6",98547:"e82e0a7b",98805:"521491ee",98842:"dcf10896",99084:"736db4b7",99115:"bbfe99fa",99244:"0e3a26bb",99417:"d9ef556f",99525:"9123f07e"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,c)=>Object.prototype.hasOwnProperty.call(e,c),d={},a="docs:",r.l=(e,c,b,f)=>{if(d[e])d[e].push(c);else{var t,o;if(void 0!==b)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var u=n[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==a+b){t=u;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",a+b),t.src=e),d[e]=[c];var l=(c,b)=>{t.onerror=t.onload=null,clearTimeout(s);var a=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),a&&a.forEach((e=>e(b))),c)return c(b)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={17896441:"18401",22869887:"62673",49993131:"28460",59307471:"42637",61171858:"51400",67140352:"93575",73956345:"26083",83100446:"46334",87293620:"44850","32dcd940":"86","6fc3ae76":"644",c2f44c5f:"660",f9ec068e:"751","7ace79c4":"974","0bcc5672":"1085",f699bead:"1193",d83cc1de:"1396","54451aca":"1591","5abd544f":"1822","420452be":"1911","5c201b0a":"2621","7d3935d1":"2683","89ad43f4":"2884",e10bed52:"2925",a12f05ab:"3453",f40b2df0:"3639","3d19221e":"3714","23c48947":"3813","63c8fde6":"4168","853df457":"4365","8092c627":"4880",f17f9c44:"4979","67dad519":"4980","5d51a55a":"5238","452be0ad":"5546","2ee7a08a":"5658",ea6d9109:"5912",eb99bfed:"6063","09adb968":"6148","8aade8b1":"6305","757d752e":"6337","640bb4cf":"6358",b0ccdb87:"6646",e1e9b906:"6934","8679ddc4":"6960","09539d9b":"7344",fc83dba0:"7628",a0b1bbd7:"7984","01a85c17":"8209",b43d8ee7:"8373","1bc8ea4c":"8514","49bc3785":"8592",d35a3623:"8655","6a0c14a5":"8834","9782cb54":"9285","03412b54":"9382",fbd7a1e9:"9416","57b63ae3":"9539","5e95c892":"9647",b77ceb62:"9689","6cdabe05":"9701",a24f5044:"9755","36c47bdd":"9766","86bbda6f":"10296",e84ae951:"10329",dc8e8e39:"10488","96f8fd49":"10667",b1bfccfc:"11159",a15c4cb6:"11290","7aa8d561":"11362",c75320ff:"11407","19cb43cd":"11572","28c03198":"11935","0050251a":"11945","685813dc":"11953","04fe2bfd":"12106",e4a5809a:"12196","56dd32bb":"12473",fe5fac7c:"12479",edc931f8:"12526","287cd167":"13043","38c9ef35":"13131",dc09f893:"13527","1109f10b":"13605","31e2019b":"13974","1bc22123":"14111","27f24dfd":"14132","760c57f4":"14385","36f749d2":"14602","4f363fd8":"14605","16c50622":"14712","19afbcc8":"14840","0047ab5d":"15058",e0719818:"15220","2c0d30da":"16218","23d0e2bb":"16323","9d1324c7":"16568","2f1a0bb3":"16594",e0c197a4:"17051","20da611c":"17491","6fe5bbf3":"18096","3a2db09e":"18121",c15d9823:"18146",a8f67d60:"18463","767805d3":"18519",d98f39e0:"18659","582db9b7":"18872","73512cb1":"18897",c8d5479b:"19289","130ed5c1":"19303","8e8909f7":"19407",dd9a4eb2:"19512",f6ed81c9:"19653",a52f8495:"19691","437bedbc":"19745",ce756c16:"19807","748dce39":"20082",c49f9378:"20126","71acf54e":"20309","0476f709":"20344","0c1b7bd3":"20717","9278f3d6":"20904","061d8128":"21009","531f0326":"21249","28f8b1f8":"21698","88684b71":"22151","6e84ad78":"22270","27e03890":"22339","779440a1":"22672","5199876b":"23008","0c2cbcc3":"23786","2ab96e79":"23844","5c8ebdd1":"23953",d341f8b3:"24170","1967361e":"24485",bd8a0ffe:"24497",b74e5806:"24730","7bed4829":"24984",b36e6e7c:"25152",caeeb51c:"25162","755df717":"25429",f8869d03:"25595","473bdf69":"25930",a3dd9468:"26018",d0ee365b:"26223","97ef9758":"26529","36d4bf8b":"26590","41f0af85":"26608","406caaae":"26918","137a0b1a":"27379",dd4ba739:"27425","35b359a4":"27683",f385820d:"27841",a708848c:"27980",bba00861:"28439","343a1afc":"28965",efbcd183:"29093","4d571bd0":"29226","07d3bac7":"30458","7850b12c":"30675",a51f78bf:"30825","0935f628":"31036",ffd7fd32:"31525","81875c35":"31669","55e21dcd":"31810",e44168e5:"31909","732919ef":"32233","26bc5a46":"32914","0e4c395f":"33384","19f6a518":"33444",b65fe363:"33475",e4409f64:"33559",fc07b5ea:"33760",f4f96b66:"34062","45bfeaeb":"34257","85f4c940":"34312","1df93b7f":"34583","16ee6b7c":"34826",cf99a16e:"34855","964e3c50":"34870",fa7c4c29:"35122",f9fdfcc0:"35210",cbf20d25:"35575",aba21aa0:"35742","7f57b062":"35894",f68824be:"36070",b4038536:"36084","0cb1d654":"36182",f1715aef:"36647","5b909c46":"36707",df35cf96:"36831","8b8a137c":"37074",b1eed1ab:"37362",dd5128a0:"37568",a6aa9e1f:"37643","2886628e":"37778","1ca0f8e7":"37810",d14d7097:"37919","9b12e85c":"38040","3ad2c61e":"38384",ac087500:"38411",ea470413:"38730","742db51e":"38781",ef8b811a:"38947",fd34a958:"39049",e747ec83:"39432","7f1a31c3":"39464",ef9d238d:"39864","34c3e4b2":"40163","7bd33c3d":"40192",cffc493c:"40714","31d44bea":"40935","9890ac63":"41298","1e818dbe":"41335",f0e20cb6:"41479","0fd39870":"42140",de6833f9:"42309","6f4a06ca":"42372","4e607b99":"42441","950c7487":"42456","7fedb4ba":"42686",abd7a988:"42747","2c36e6c1":"43136","3f3928dc":"43213",a2317717:"43400",bd8a97c5:"43536","4a61a7c1":"43705","58af14fe":"43745","26ef8bfb":"43848",f53abb4b:"43862",ad39e84b:"44657","1276f6ab":"44684",c059aa33:"44716","6c33bb99":"44810","8493ac52":"45054",a70dabb3:"45075","7b449e09":"45123","65742e9f":"45147",cdce7391:"45350",a52c62d4:"45568","89176cae":"45673","41ab9761":"45676",ff7b9a4c:"45929","6d32cafb":"45978","5af709c8":"46008","7217b34c":"46098","3a36ab0d":"46125","8fc094a7":"46251","0f1ad89c":"46347",ca219831:"46471",fc3b013c:"46774","8ec565c1":"46866","14eb3368":"46969",befb6565:"47020",ad59ba68:"47191",f4daec3f:"47475","52ac6bcf":"47813",d5947e44:"47861",f81c1134:"48130","0a757274":"48296","502adbf6":"48561","749c6f3f":"48625",bdaaff35:"49063","5cc619f0":"49648",f4cdb2d9:"49745","441bd449":"49851","6019e202":"50640",ae009198:"50676","5b402526":"51001","093291a8":"51276",b501f8e8:"51528",a94c36cd:"51548","4b015924":"52076",c0e025b3:"52179","7b787d81":"52257","26dd306b":"52342","9e4087bc":"52711",d5658917:"53156","32227eef":"53429","589280f5":"53530",fff9aecb:"53649","1bb8290c":"53652",b262b314:"53681","09cf625e":"53767","1f34ee25":"53894",d1aa920e:"53920",e48c83c9:"54252","291e1144":"54644","87086dc6":"54725",d59f7d52:"55139","14a658e6":"55235","012688b3":"55251","65c1efe1":"55663","3ff13a62":"55743","64f9507b":"55790","7eea03ab":"56699",bccb1b42:"56986",a022b847:"57013","5c2c818b":"57153",eaf69a59:"57633",d902a273:"57695","931040e8":"57743",a4833b52:"57753",b7cec31e:"57938","119c53e5":"58407","5b235e06":"58523","6ad9ab45":"58561","04437fec":"59075",b6ce023b:"59346",b4dfe8b3:"59417",dcbc8e94:"59495","4aabd97d":"60183",f5b4e375:"60778",d2436a2b:"60837","2d071e49":"60953","184e5ead":"60988",a7456010:"61235","657efcba":"61238","7ac7e960":"61329","9b5d9131":"61427","79a28527":"61902","604a51e1":"61976","5565c8ed":"62016","3d9e0922":"62069","1a4e3797":"62138","03babb4a":"62294",f5cc95ce:"62312",dcae780a:"62350",cda5fe29:"62840","86ee3414":"63365","8db05b07":"63663","9e156860":"63811","670b12e1":"63919",dc218a96:"63935","19e9bde5":"64175","621db11d":"64212","8d25d5d4":"64277",cd0ad4f0:"64625","138e0e15":"64921","6ddb698c":"65679","7cf96b3e":"65770",edaafa5c:"65981",ff45c01b:"66290",abd5b058:"66846","22aa5ce0":"66910","5f46a90e":"66947",bd319452:"66971",c6e1beb6:"67085",a7bd4aaa:"67098","0d2860b1":"67148",b5f86da1:"67214","070e71f0":"67255","5d54de92":"67299","814f3328":"67472",b361e208:"67548",abecca15:"67560","320ccb30":"67677",ef682180:"67731","53cbe722":"67768",b5a6d29b:"68226","6bcd11f8":"68502","45f4377b":"68965","23e62f09":"68966",d1c3b532:"68992","70b53392":"69110",c5533f5e:"69346","6db2ece2":"69356",a3e11933:"69657","94f31572":"69752",cb18db4b:"69859",c06491c2:"70337",dbde4c02:"70445",d71eca41:"70467","4e6fa974":"70557","5bd7bc3b":"70643","8ed6f0f1":"71001","1722e234":"71255","066abe51":"71351","631b9b66":"71682",cdb233b1:"71755",e6263de7:"72111",c5479f59:"72283",e83ec39f:"72439","6cdfddef":"73281","6d8acf16":"73374","28d842ee":"73405","500c8deb":"73634",c1172cc8:"73739","03c8668f":"74507","7e7cf0e4":"74612","0f0de498":"75013","0ea173ba":"75341","95800b3e":"75515",b6fc97b5:"75717","26c6a551":"75804","9d49bc50":"75875",ab2759ca:"76153","2abb9c6f":"76372",b8c7b97f:"76443",abfb0638:"76793",c3529e0a:"76871",da1a5473:"77125","0bb6d954":"77479",aaebd759:"77609","3a1d878d":"78031",bceb927f:"78081",b1fd1705:"78215","3180fd0e":"78340","315ee77a":"78353","0eef3953":"78423","7fd33963":"78526","9975996a":"78532",dcf2f717:"78981","777b847b":"79001",a94703ab:"79048","2e505a53":"79089",eea6a18c:"79245","90c33bef":"79692",ffa81568:"79728",a35d3433:"80123","3abbf0e9":"80231",e20b631f:"80272",c12abb16:"80281","310c7ee8":"80295","53f25e30":"80332",f600298c:"80639","526992cf":"81475",c7e8a920:"81542","1c894279":"81804",acecf23e:"81903","1c94670e":"82336","526893f8":"82346",c9b16325:"82798",db47e023:"83160",ccc49370:"83249","9f357fc0":"83292","2cc9d448":"83574",f14428ad:"83709","699c0e5c":"83725","929c4e1b":"83802","9490f32b":"83874","5447d460":"83881",a7769c8a:"84093","6d890b23":"84331",dfce392e:"84398",e24c1f8d:"84480","6875c492":"84813","6a49ee0a":"85066",abb47370:"85075","15e4a743":"85609",aed2f698:"85612",a9f40339:"86164","422fff4b":"86227","1300cb4e":"86273",c9581477:"86293",b0f0cb2b:"86376","63768f60":"86397",b191927f:"86452","43915cdf":"86512","6c4198a1":"87638",a6a72687:"87701","4f2b2ca4":"87915","6f1c571c":"88071",a64829d3:"88142",c0cd111c:"88477",b3e290f1:"89031","915e2cf4":"89260","78bb765a":"89295","62337dff":"89376",b08c16de:"89390","05e7973d":"89823","36994c47":"89858",be01f2a0:"89954","41be304a":"90205","4edc808e":"90308",db103552:"90495","40d9468c":"90783","0058b4c6":"90849","013c29c1":"90923","2ce1dccd":"91026",e2dcdabe:"91099","37a5cb6b":"91384","35fbae7a":"91617","926668e5":"91770","9f356e5b":"91844",f2a59390:"92078","096c51c8":"92544","6738f543":"92671",fff06078:"92710","05370f9a":"92864",ad1cb202:"93086",b8fd74b5:"93153","9a7c0197":"93402","477ed06d":"93502",aca4bcb1:"93750","0dfeccb2":"94342","97b1504a":"94346","46a1aa97":"94561","6e45ed1a":"94604","7023f74c":"94869",cd87bcd5:"95113","5201921d":"95369","0121636f":"95752","3e493f26":"96029",a63812ab:"96147",e2bda29d:"96162",cd4fb20e:"96165","9099a3d2":"96172",e34f30ed:"96211",ecbad217:"96454",b30e8b21:"96578","94b13e0d":"96707","88f37d1b":"96734","25cf6706":"97104","34fc7a35":"97399","178df98e":"98029","193dc870":"98220","29c2cfba":"98547","4468ebd1":"98805","946bf800":"98842","4913574b":"99084",f39ce5f1:"99115","09ba26e2":"99244","440f3548":"99417","60fc342f":"99525"}[e]||e,r.p+r.u(e)},(()=>{var e={45354:0,71869:0};r.f.j=(c,b)=>{var d=r.o(e,c)?e[c]:void 0;if(0!==d)if(d)b.push(d[2]);else if(/^(45354|71869)$/.test(c))e[c]=0;else{var a=new Promise(((b,a)=>d=e[c]=[b,a]));b.push(d[2]=a);var f=r.p+r.u(c),t=new Error;r.l(f,(b=>{if(r.o(e,c)&&(0!==(d=e[c])&&(e[c]=void 0),d)){var a=b&&("load"===b.type?"missing":b.type),f=b&&b.target&&b.target.src;t.message="Loading chunk "+c+" failed.\n("+a+": "+f+")",t.name="ChunkLoadError",t.type=a,t.request=f,d[1](t)}}),"chunk-"+c,c)}},r.O.j=c=>0===e[c];var c=(c,b)=>{var d,a,f=b[0],t=b[1],o=b[2],n=0;if(f.some((c=>0!==e[c]))){for(d in t)r.o(t,d)&&(r.m[d]=t[d]);if(o)var i=o(r)}for(c&&c(b);n<f.length;n++)a=f[n],r.o(e,a)&&e[a]&&e[a][0](),e[a]=0;return r.O(i)},b=self.webpackChunkdocs=self.webpackChunkdocs||[];b.forEach(c.bind(null,0)),b.push=c.bind(null,b.push.bind(b))})()})(); \ No newline at end of file diff --git a/blog/archive/index.html b/blog/archive/index.html new file mode 100644 index 0000000000..ac66d80272 --- /dev/null +++ b/blog/archive/index.html @@ -0,0 +1,24 @@ +<!doctype html> +<html lang="en" dir="ltr" class="plugin-blog plugin-id-default" data-has-hydrated="false"> +<head> +<meta charset="UTF-8"> +<meta name="generator" content="Docusaurus v3.6.3"> +<title data-rh="true">Archive | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/blog/atom.xml b/blog/atom.xml new file mode 100644 index 0000000000..ab618a02ff --- /dev/null +++ b/blog/atom.xml @@ -0,0 +1,24 @@ + + + https://docs.scs.community/blog + One platform — standardized, built and operated by many. Blog + 2022-10-28T00:00:00.000Z + https://github.com/jpmonette/feed + + One platform — standardized, built and operated by many. Blog + https://docs.scs.community/img/favicon.png + + <![CDATA[First Blog Post]]> + https://docs.scs.community/blog/first-blog-post + + 2022-10-28T00:00:00.000Z + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

]]>
+ + Eduard Itrich + https://github.com/itrich + + + +
+
\ No newline at end of file diff --git a/blog/authors/index.html b/blog/authors/index.html new file mode 100644 index 0000000000..f19895a444 --- /dev/null +++ b/blog/authors/index.html @@ -0,0 +1,24 @@ + + + + + +Authors | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Authors

+ + \ No newline at end of file diff --git a/blog/first-blog-post/index.html b/blog/first-blog-post/index.html new file mode 100644 index 0000000000..a41181b0cf --- /dev/null +++ b/blog/first-blog-post/index.html @@ -0,0 +1,24 @@ + + + + + +First Blog Post | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

First Blog Post

· One min read
Eduard Itrich
Community Manager @ SCS

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

+ + \ No newline at end of file diff --git a/blog/index.html b/blog/index.html new file mode 100644 index 0000000000..da6869b542 --- /dev/null +++ b/blog/index.html @@ -0,0 +1,24 @@ + + + + + +Blog | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

First Blog Post

· One min read
Eduard Itrich
Community Manager @ SCS

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

+ + \ No newline at end of file diff --git a/blog/rss.xml b/blog/rss.xml new file mode 100644 index 0000000000..5a7a65d46d --- /dev/null +++ b/blog/rss.xml @@ -0,0 +1,22 @@ + + + + One platform — standardized, built and operated by many. Blog + https://docs.scs.community/blog + One platform — standardized, built and operated by many. Blog + Fri, 28 Oct 2022 00:00:00 GMT + https://validator.w3.org/feed/docs/rss2.html + https://github.com/jpmonette/feed + en + + <![CDATA[First Blog Post]]> + https://docs.scs.community/blog/first-blog-post + https://docs.scs.community/blog/first-blog-post + Fri, 28 Oct 2022 00:00:00 GMT + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

]]>
+ community + howto +
+
+
\ No newline at end of file diff --git a/blog/tags/community/community/index.html b/blog/tags/community/community/index.html new file mode 100644 index 0000000000..fe04b1108a --- /dev/null +++ b/blog/tags/community/community/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/blog/tags/community/index.html b/blog/tags/community/index.html new file mode 100644 index 0000000000..e2f4b9b038 --- /dev/null +++ b/blog/tags/community/index.html @@ -0,0 +1,24 @@ + + + + + +One post tagged with "community" | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

One post tagged with "community"

View All Tags

First Blog Post

· One min read
Eduard Itrich
Community Manager @ SCS

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

+ + \ No newline at end of file diff --git a/blog/tags/howto/index.html b/blog/tags/howto/index.html new file mode 100644 index 0000000000..58c721d7fd --- /dev/null +++ b/blog/tags/howto/index.html @@ -0,0 +1,24 @@ + + + + + +One post tagged with "howto" | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

One post tagged with "howto"

View All Tags

First Blog Post

· One min read
Eduard Itrich
Community Manager @ SCS

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

+ + \ No newline at end of file diff --git a/blog/tags/index.html b/blog/tags/index.html new file mode 100644 index 0000000000..b5142189c2 --- /dev/null +++ b/blog/tags/index.html @@ -0,0 +1,24 @@ + + + + + +Tags | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/community/category/contribute-to-docs/index.html b/community/category/contribute-to-docs/index.html new file mode 100644 index 0000000000..8be83be569 --- /dev/null +++ b/community/category/contribute-to-docs/index.html @@ -0,0 +1,24 @@ + + + + + +Contribute to Docs | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/community/category/tools/index.html b/community/category/tools/index.html new file mode 100644 index 0000000000..64d0cc63c6 --- /dev/null +++ b/community/category/tools/index.html @@ -0,0 +1,24 @@ + + + + + +Tools | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/community/central-services/plusserver-gx-scs/index.html b/community/central-services/plusserver-gx-scs/index.html new file mode 100644 index 0000000000..5db70666f8 --- /dev/null +++ b/community/central-services/plusserver-gx-scs/index.html @@ -0,0 +1,103 @@ + + + + + +Central services | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Central services

+

This document gives an overview of what SCS central services are deployed and who is responsible for them in plusserver gx-scs infrastructure.

+

Project p500924-harbor

+

K8s clusters

+

Harbor

+

Responsibility: @SovereignCloudStack/vp06c

+

Services:

+ +

Utilization:

+
    +
  • Instances: 7
  • +
  • VCPUs: 32
  • +
  • RAM: 64GB
  • +
+

Spec:

+
    +
  • version: v7.0.0 - R6
  • +
  • management cluster: +
      +
    • 1 instance: SCS-2V:4:20
    • +
    • image: Ubuntu 22.04 (20230416)
    • +
    • k8s: v1.25.3 - KinD
    • +
    +
  • +
  • workload cluster: +
      +
    • 6 instances: +
        +
      • 3 control-planes: SCS-2V-4-20s
      • +
      • 3 workers: SCS-8V:16:100
      • +
      +
    • +
    • image: ubuntu-capi-image-v1.28.7
    • +
    • k8s: v1.28.7
    • +
    +
  • +
+

Project p500924-sig-monitoring1

+

K8s clusters

+

Monitoring

+

Responsibility: @SovereignCloudStack/vp06c

+

Services:

+ +

Utilization:

+
    +
  • Instances: 7
  • +
  • VCPUs: 32
  • +
  • RAM: 64GB
  • +
+

Spec:

+
    +
  • version: v7.0.0 - R6
  • +
  • management cluster: +
      +
    • 1 instance: SCS-2V:4:20
    • +
    • image: Ubuntu 22.04 (20240125)
    • +
    • k8s: v1.27.3 - KinD
    • +
    +
  • +
  • workload cluster: +
      +
    • 6 instances: +
        +
      • 3 control-planes: SCS-2V-4-20s
      • +
      • 3 workers: SCS-8V:16:100
      • +
      +
    • +
    • image: ubuntu-capi-image-v1.28.7
    • +
    • k8s: v1.28.7
    • +
    +
  • +
+ + \ No newline at end of file diff --git a/community/cloud-resources/getting-started-openstack/index.html b/community/cloud-resources/getting-started-openstack/index.html new file mode 100644 index 0000000000..9bc2a576d1 --- /dev/null +++ b/community/cloud-resources/getting-started-openstack/index.html @@ -0,0 +1,87 @@ + + + + + +Getting Started with OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Getting Started with OpenStack

Getting Started with OpenStack CLI

+

OpenStackClient (CLI)

+

The OpenStackClient is installable via all major Linux Distributions:

+

for debian and ubuntu with apt:

+
sudo apt install python3-openstackclient
+

for ubuntu with snap openstack CLI is installable too:

+
sudo snap install openstackclients
+
+

[!NOTE] +Versions from Linux repository could be in a stable but old state.

+
+

Install it directly via pypi +from upstream is the recommend way.

+

Here for example RHEL:

+
sudo dnf install python3 python3-devel gcc python3-pip
+

Here for example Debian and Ubuntu:

+
sudo apt install python3-minimal python3-pip python3-venv python3-dev build-essential
+

Here as example for SUSE

+
sudo zypper in python3-pip python3-venv python3-dev
+

Here for example with Apple's MacOS

+
brew install python3
+
+

[!NOTE] +Python installation for windows systems please use the python installation guide +or recommend use the Linux Subsystem WSL

+
+

Python Virtualenv

+

It is also recommended to use virtual environments, here as an example for +Linux and MacOS:

+
python3 -m venv oscli
source oscli/bin/activate
pip install --upgrade pip
pip install python-openstackclient \
python-cinderclient \
python-designateclient \
python-glanceclient \
python-neutronclient \
python-novaclient \
python-octaviaclient \
python-barbicanclient

+

For further Information see the OpenStack Project upstream website +python-openstackclient.

+

This repo holds examples for clouds-public.yaml + clouds.yaml.

+

Alternatively you can download an OpenRC Environment file when you're logged +in to Horizon:

+
    +
  • upper right side ➡️ <your login name>
  • +
  • OpenStack RC File
  • +
+
$ source ./<$yourfile>-openrc.sh
Please enter your OpenStack Password for project XXX as user YYY:
+
openstack --help
+

when you're using clouds.yaml you can specify multiple endpoints and +select the specific endpoint by passing --os-cloud= to the +openstack cmdline or setting OS_CLOUD.

+
openstack --os-cloud MYCLOUD
+

or

+
export OS_CLOUD=MYCLOUD
openstack
+

OpenStack Client in action inside of the OSISM testbed: +Example OpenStackClient in testbed

+

Object Storage (S3)

+

Create AWS like credentials with openstack ec2 credentials create. +If you use libs3, store the access field in S3_ACCESS_KEY_ID and the secret +field inS3_SECRET_ACCESS_KEY and set S3_HOSTNAME=<Object Storage endpoint>. +You will see the same buckets (containers) and objects whether you access your +object store via the swift or via the s3 protocol.

+

References

+
+ + \ No newline at end of file diff --git a/community/cloud-resources/index.html b/community/cloud-resources/index.html new file mode 100644 index 0000000000..a9413ca0c6 --- /dev/null +++ b/community/cloud-resources/index.html @@ -0,0 +1,53 @@ + + + + + +Test and development cloud resources | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Test and development cloud resources

+

This document gives an overview of the test and development cloud resources currently provided by our partners.

+

How to request cloud resources

+

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, ...)

+

plusserver

+

Usage

+

A brief guide on how to use the resources provided by plusserver GmbH can be found here

+

Users

+

As suggested in #155 the username for non-"service users" will contain the users github handle and are prefixed with a plusserver default. +prefix-<$github handle>

+
+

Note +ATM this is not directly connected to the SovereignCloudStack github org membership, accounts will be created manually for now.

+
+

Example:

+
github handleplusserver login
frosty-geeku500924-frosty-geek
fkru500924-fkr
+
+

Note +To easy collaboration & transparency within the SCS team all users will have their default_project_id set to p500924-scs-community by default and will have full access on all projects listed below.

+
+

Service Users

+

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.

+
Unique IdentifierService User NameFull Access onCommunity ContactDescriptionNeeded until
9a1576af59644a2dbbace773ad17158du500924-svc-sig-monitoringp500924-sig-monitoring1fkrService User - SIG Monitoring31.12.2023
4925967416894fd78be6701689059653u500924-svc-cloudmonp500924-cloudmon-targetErik-Kostelansky-dNationService User - VP12 Test Project31.12.2024
f89b3d64ddff4d9d8cadb5e06fa22299u500924-svc-healthmonitorp500924-scs-healthmonitorgarloffService User - SCS Health Monitor
49cc3d72fbdf41fe8dc407f57f026dbfu500924-svc-standardsp500924-scs-healthmonitorgarloffService User - SCS Standards Compliance Check
1b6bb583fc5e40e49f2a7e9b4301de65u500924-svc-zuulp500924-scs-zuulo-otteService User - SCS Zuul30.11.2024
+

Projects

+
Unique IdentifierProject NameCommunity ContactDescriptionNeeded until
2237c767cf5f456da19359ed31c1c16bp500924-scs-communityfkrSCS Community Project
b43cfafbcf1f4eb08865b2886c29e09bp500924-cluster-api-sessiongarloffcluster-api hands on session
9b7a73e516be4cd1acbd63d543985c52p500924-gonicus-devo-otteGONICUS GmbH
3829cc7c8f034fc985f5055a1df6f247p500924-scs-healthmonitorgarloffSCS Health Monitor
b97d38bf128b4479981c4dbe2ef70cd5p500924-SIG-IAMfkrSIG IAM and VP08
9de7d8dc2d674e52be44904d6b338b0bp500924-cloudmonErik-Kostelansky-dNationVP12 Test Project31.12.2024
2c9e0e4ef8d44c36807df50b06b3c81dp500924-cloudmon-targetErik-Kostelansky-dNationTarget project for VP12 tests31.12.2024
3501db829014406884990a1016f3e25dp500924-sig-monitoring1fkrSIG Monitoring - cloudmon target
602778bad3d3470cbe58c4f7611e8eb7p500924-dnationchess-knightdNation dev for VP06c
91091d4039a6457db27d48d58bb1b4e4p500924-jschoonejschooneKaaS dev and evaluation
93956190702b4a7d8a8886806d57713fp500924-meteringcah-linkDev Environment for VP1331.12.2023
abbe6561cf6248b6af395334aa09af85p500924-harborchess-knightSCS Harbor for VP06c
e7622c1048ac4520a2d050ae141e826bp500924-tender-6amxmxchereDev Environment for VP06a
eeed7e0ad33f42f189fb4165116f5a1bp500924-dnation-k8smatofederdNation dev for VP06c
b342f37804f14459bdf703573169bf79p500924-minery90n20Testbed env for Pentesting30.11.2024
0fa3c3559f0d4f39ba7aa70c7f7188cap500924-tender-10-3tonifingerDev Environment for VP10-3
b682eb90fb834278afb1182018dd2133p500924-scoopexscoopexMarc's gx-scs project
021af0688c594bf88ed675b942d3bea8p500924-gx-cred-generatoranjastrunkSCS Gaia-X Self-Description Generator
a07c811315ad40f585945b2939ef12ddp500924-scs-zuulo-otteSCS Zuul30.11.2024
1846709967a744b69f9eb48cac89bb04p500924-scs-k8s-e2echess-knightE2E-Test for KaaS
6ee4b373cb6d42a5bb59d5080987b70dp500924-bitkeksbitkeksCluster Stacks and Sec
4ea22ba875474d039cb57d20b7f710b5p500924-kaas-playground0jschoonePlayground0 for Hackathon30.09.2024
476672f1023b4bac8837f95a76881757p500924-kaas-playground1jschoonePlayground1 for Hackathon30.09.2024
04dac2927f744479a5d4c23dd0a3c378p500924-kaas-playground2jschoonePlayground2 for Hackathon30.09.2024
75279777029847ab9b399390c0dd6042p500924-kaas-playground3jschoonePlayground3 for Hackathon30.09.2024
0b3c75f80b6743778daccec0da423465p500924-kaas-playground4jschoonePlayground4 for Hackathon30.09.2024
2340a73644ca47189329061e9c2a0bfep500924-kaas-playground5jschoonePlayground5 for Hackathon30.09.2024
3c5bae4a233c4a9d8ae2e4b799d757c9p500924-kaas-playground6jschoonePlayground6 for Hackathon30.09.2024
03783b4952344c849af37d26818d19f0p500924-kaas-playground7jschoonePlayground7 for Hackathon30.09.2024
5c6d4d7183834eafbc20108ad647a9c0p500924-kaas-playground8jschoonePlayground8 for Hackathon30.09.2024
7e18881932f749baa7d547ebd407b8d8p500924-kaas-playground9jschoonePlayground9 for Hackathon30.09.2024
d9dc2f33e76240219db484526e9f601dp500924-akafazovakafazovakafazov Testbed30.04.2024
b07ad6a84982471b9a344ef9947f0e0fp500924-gtemagtemaTestbed for gtema
e89ac8c9f66f46b5a983b2a05d2a66ecp500924-zuse-z3zuse-z3Josefine's gx-scs project
fc1f7a0e10a64d6083dcdbcb7ccf6ff4p500924-compliance-monitormbuechseSCS Compliance Monitor Deployment
eba5414a4f8549b28a62af199d82dab5p500924-tsmadotsmadotsmado's gx-scs project
+

Wavecon

+

Service Users

+
Unique IdentifierService User NameFull Access onCommunity ContactDescriptionNeeded until
df4af5376bbd4de587c4335622149be7scs-standardsscs-standardsitrichService User - SCS Standards Compliance Check
+

Projects

+
Unique IdentifierProject NameCommunity ContactDescriptionNeeded until
718964b4b87446688ac04b151519fb51scsgarloffSCS Health Monitor
c46ccc9e695c4b23bacee2ad11145d9ascs-health-monitorgarloffSCS Health Monitor
00de553df86949b49365baee6375fb5ascs-standardsitrichSCS Health Monitor
+ + \ No newline at end of file diff --git a/community/cloud-resources/plusserver-gx-scs/index.html b/community/cloud-resources/plusserver-gx-scs/index.html new file mode 100644 index 0000000000..0af1097714 --- /dev/null +++ b/community/cloud-resources/plusserver-gx-scs/index.html @@ -0,0 +1,39 @@ + + + + + +Getting Started Gaia-X Demonstrator @ plusserver | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Getting Started Gaia-X Demonstrator @ plusserver

Getting Started for the Gaia-X Demonstrator @ plusserver

+

URLs for access

+ +

Authentication (UI)

+

For your login you will need:

+
    +
  • Username (u500924-<$github-handle>)
  • +
  • Password
  • +
  • Domain (d500924)
  • +
+

Getting Started with OpenStack

+

See Getting Started with OpenStack

+ + \ No newline at end of file diff --git a/community/cloud-resources/wavestack/index.html b/community/cloud-resources/wavestack/index.html new file mode 100644 index 0000000000..815c33cba3 --- /dev/null +++ b/community/cloud-resources/wavestack/index.html @@ -0,0 +1,39 @@ + + + + + +Getting Started with Wavestack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/community/collaboration/index.html b/community/collaboration/index.html new file mode 100644 index 0000000000..323657024c --- /dev/null +++ b/community/collaboration/index.html @@ -0,0 +1,63 @@ + + + + + +Collaboration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Collaboration

+

We’re an open community

+

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!

+
+

Collaborating with issues and pull requests

+

We use the GitHub flow to track and discuss changes in issues, then propose and +review changes in pull requests. See the +GitHub documentation +for more details.

+

Meetings

+

Project updates

+
    +
  • Weekly with all teams on Thursday at 15:05 CEST (40 mins)
  • +
  • In some weeks we schedule an additional lightning talk at 15:40 CEST
  • +
+

Sprint review/Backlog refinement/Sprint planning meetings

+
    +
  • Weekly Team meetings (~1hr) for currently 4 teams: +
      +
    • Team IaaS
    • +
    • Team Container
    • +
    • Team IAM & Security
    • +
    • Team Operations
    • +
    +
  • +
  • Please refer to the public calendar above for details.
  • +
+

Special interest groups (SIGs) and hacking sessions

+
    +
  • There are a number of SIG meetings and hacking sessions that meet weekly or bi-weekly +
      +
    • SIG Monitoring and Logging
    • +
    • SIG Standardization and Certification
    • +
    • SIG Documentation
    • +
    • SIG Community
    • +
    • SIG Central API
    • +
    +
  • +
  • Please refer to the public calendar above for details.
  • +
+ + \ No newline at end of file diff --git a/community/collaboration/sig-central-api/index.html b/community/collaboration/sig-central-api/index.html new file mode 100644 index 0000000000..d51b21c097 --- /dev/null +++ b/community/collaboration/sig-central-api/index.html @@ -0,0 +1,29 @@ + + + + + +SIG Central API | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SIG Central API

+

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.

+

We want to define a single point of managment with consistent experience for managing the entire infrastructure.

+

We aim to establish an unified and central interface that provides customers +of the SCS clouds with the ability to manage cloud resources and/or services.

+

SIG explores the possibilities for a central API by creating a MVP.

+ + \ No newline at end of file diff --git a/community/collaboration/sig-community/index.html b/community/collaboration/sig-community/index.html new file mode 100644 index 0000000000..cc1f90dddc --- /dev/null +++ b/community/collaboration/sig-community/index.html @@ -0,0 +1,25 @@ + + + + + +SIG Community | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SIG Community

+

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!

+ + \ No newline at end of file diff --git a/community/collaboration/sig-documentation/index.html b/community/collaboration/sig-documentation/index.html new file mode 100644 index 0000000000..4370a0192b --- /dev/null +++ b/community/collaboration/sig-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +SIG Documentation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SIG Documentation

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.

+ + \ No newline at end of file diff --git a/community/collaboration/sig-monitoring/index.html b/community/collaboration/sig-monitoring/index.html new file mode 100644 index 0000000000..7bcd77a352 --- /dev/null +++ b/community/collaboration/sig-monitoring/index.html @@ -0,0 +1,25 @@ + + + + + +SIG Monitoring | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SIG Monitoring

+

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.

+ + \ No newline at end of file diff --git a/community/collaboration/sig-standardization/index.html b/community/collaboration/sig-standardization/index.html new file mode 100644 index 0000000000..46ede7c4f2 --- /dev/null +++ b/community/collaboration/sig-standardization/index.html @@ -0,0 +1,26 @@ + + + + + +SIG Standardization | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SIG Standardization

+

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.

+

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.

+ + \ No newline at end of file diff --git a/community/collaboration/team-container/index.html b/community/collaboration/team-container/index.html new file mode 100644 index 0000000000..cdc42804cd --- /dev/null +++ b/community/collaboration/team-container/index.html @@ -0,0 +1,28 @@ + + + + + +Team Container | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Team Container

+

The Team Container deals with all topics around Containers and Kubernetes.

+

at the moment: Kubernetes Deployments via ClusterAPI +in the future deployments via ClusterStacks +KaaS Standard

+ + \ No newline at end of file diff --git a/community/collaboration/team-iaas/index.html b/community/collaboration/team-iaas/index.html new file mode 100644 index 0000000000..e1aa058fc6 --- /dev/null +++ b/community/collaboration/team-iaas/index.html @@ -0,0 +1,25 @@ + + + + + +Team Iaas | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/community/collaboration/team-iam/index.html b/community/collaboration/team-iam/index.html new file mode 100644 index 0000000000..056487b0b3 --- /dev/null +++ b/community/collaboration/team-iam/index.html @@ -0,0 +1,27 @@ + + + + + +Team IAM | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Team IAM

+

The Team IAM deals with topics around Identity and Access Management.

+

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).

+

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.

+ + \ No newline at end of file diff --git a/community/collaboration/team-ops/index.html b/community/collaboration/team-ops/index.html new file mode 100644 index 0000000000..61adbeeb7e --- /dev/null +++ b/community/collaboration/team-ops/index.html @@ -0,0 +1,25 @@ + + + + + +Team Ops | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/community/community/category/contribute-to-docs/index.html b/community/community/category/contribute-to-docs/index.html new file mode 100644 index 0000000000..086e5958ca --- /dev/null +++ b/community/community/category/contribute-to-docs/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/category/tools/index.html b/community/community/category/tools/index.html new file mode 100644 index 0000000000..9d5452e9a9 --- /dev/null +++ b/community/community/category/tools/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/central-services/plusserver-gx-scs/index.html b/community/community/central-services/plusserver-gx-scs/index.html new file mode 100644 index 0000000000..ec337d67ad --- /dev/null +++ b/community/community/central-services/plusserver-gx-scs/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/cloud-resources/getting-started-openstack/index.html b/community/community/cloud-resources/getting-started-openstack/index.html new file mode 100644 index 0000000000..fc40aed3a6 --- /dev/null +++ b/community/community/cloud-resources/getting-started-openstack/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/cloud-resources/index.html b/community/community/cloud-resources/index.html new file mode 100644 index 0000000000..2e9f439d9b --- /dev/null +++ b/community/community/cloud-resources/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/cloud-resources/plusserver-gx-scs/index.html b/community/community/cloud-resources/plusserver-gx-scs/index.html new file mode 100644 index 0000000000..32216711a6 --- /dev/null +++ b/community/community/cloud-resources/plusserver-gx-scs/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/cloud-resources/wavestack/index.html b/community/community/cloud-resources/wavestack/index.html new file mode 100644 index 0000000000..b13d66f100 --- /dev/null +++ b/community/community/cloud-resources/wavestack/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/index.html b/community/community/collaboration/index.html new file mode 100644 index 0000000000..5bb45e6905 --- /dev/null +++ b/community/community/collaboration/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/sig-central-api/index.html b/community/community/collaboration/sig-central-api/index.html new file mode 100644 index 0000000000..96f1798e92 --- /dev/null +++ b/community/community/collaboration/sig-central-api/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/sig-community/index.html b/community/community/collaboration/sig-community/index.html new file mode 100644 index 0000000000..5d208ece86 --- /dev/null +++ b/community/community/collaboration/sig-community/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/sig-documentation/index.html b/community/community/collaboration/sig-documentation/index.html new file mode 100644 index 0000000000..5c60f11ec9 --- /dev/null +++ b/community/community/collaboration/sig-documentation/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/sig-monitoring/index.html b/community/community/collaboration/sig-monitoring/index.html new file mode 100644 index 0000000000..6ce28e5fae --- /dev/null +++ b/community/community/collaboration/sig-monitoring/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/sig-standardization/index.html b/community/community/collaboration/sig-standardization/index.html new file mode 100644 index 0000000000..9a6d34fe89 --- /dev/null +++ b/community/community/collaboration/sig-standardization/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/team-container/index.html b/community/community/collaboration/team-container/index.html new file mode 100644 index 0000000000..d6c30e0e5e --- /dev/null +++ b/community/community/collaboration/team-container/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/team-iaas/index.html b/community/community/collaboration/team-iaas/index.html new file mode 100644 index 0000000000..3b605c604a --- /dev/null +++ b/community/community/collaboration/team-iaas/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/team-iam/index.html b/community/community/collaboration/team-iam/index.html new file mode 100644 index 0000000000..5dd0756ef0 --- /dev/null +++ b/community/community/collaboration/team-iam/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/team-ops/index.html b/community/community/collaboration/team-ops/index.html new file mode 100644 index 0000000000..f7d24b9774 --- /dev/null +++ b/community/community/collaboration/team-ops/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/adding-docs-guide/index.html b/community/community/contribute/adding-docs-guide/index.html new file mode 100644 index 0000000000..706521ab60 --- /dev/null +++ b/community/community/contribute/adding-docs-guide/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/doc-files-structure-guide/index.html b/community/community/contribute/doc-files-structure-guide/index.html new file mode 100644 index 0000000000..81f157bc94 --- /dev/null +++ b/community/community/contribute/doc-files-structure-guide/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/docs-workflow-explanation/index.html b/community/community/contribute/docs-workflow-explanation/index.html new file mode 100644 index 0000000000..5009c317ac --- /dev/null +++ b/community/community/contribute/docs-workflow-explanation/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/linting-guide/index.html b/community/community/contribute/linting-guide/index.html new file mode 100644 index 0000000000..bf183e9f0b --- /dev/null +++ b/community/community/contribute/linting-guide/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/local-docusaurus-development-guide/index.html b/community/community/contribute/local-docusaurus-development-guide/index.html new file mode 100644 index 0000000000..9a044694f1 --- /dev/null +++ b/community/community/contribute/local-docusaurus-development-guide/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/styleguide/index.html b/community/community/contribute/styleguide/index.html new file mode 100644 index 0000000000..ba4e409a70 --- /dev/null +++ b/community/community/contribute/styleguide/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/styleguides/ansible_styleguide/index.html b/community/community/contribute/styleguides/ansible_styleguide/index.html new file mode 100644 index 0000000000..5234f1b100 --- /dev/null +++ b/community/community/contribute/styleguides/ansible_styleguide/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/hackathons/checklist/index.html b/community/community/hackathons/checklist/index.html new file mode 100644 index 0000000000..984523b3b9 --- /dev/null +++ b/community/community/hackathons/checklist/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/index.html b/community/community/index.html new file mode 100644 index 0000000000..43e45251f4 --- /dev/null +++ b/community/community/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/license-considerations/index.html b/community/community/license-considerations/index.html new file mode 100644 index 0000000000..88c63d3a58 --- /dev/null +++ b/community/community/license-considerations/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/mission-statement/index.html b/community/community/mission-statement/index.html new file mode 100644 index 0000000000..506b9afa59 --- /dev/null +++ b/community/community/mission-statement/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/github/branchprotection/index.html b/community/community/tools/github/branchprotection/index.html new file mode 100644 index 0000000000..ff9b117386 --- /dev/null +++ b/community/community/tools/github/branchprotection/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/github/dco-and-licenses/index.html b/community/community/tools/github/dco-and-licenses/index.html new file mode 100644 index 0000000000..9942300782 --- /dev/null +++ b/community/community/tools/github/dco-and-licenses/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/github/tips-and-tricks/index.html b/community/community/tools/github/tips-and-tricks/index.html new file mode 100644 index 0000000000..c83b1e2cc9 --- /dev/null +++ b/community/community/tools/github/tips-and-tricks/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/jitsi/index.html b/community/community/tools/jitsi/index.html new file mode 100644 index 0000000000..ad0d005f35 --- /dev/null +++ b/community/community/tools/jitsi/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/mailinglists/index.html b/community/community/tools/mailinglists/index.html new file mode 100644 index 0000000000..0e774e97be --- /dev/null +++ b/community/community/tools/mailinglists/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/matrix/index.html b/community/community/tools/matrix/index.html new file mode 100644 index 0000000000..b94ffe4852 --- /dev/null +++ b/community/community/tools/matrix/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/nextcloud/index.html b/community/community/tools/nextcloud/index.html new file mode 100644 index 0000000000..34888d5e22 --- /dev/null +++ b/community/community/tools/nextcloud/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/zuul/index.html b/community/community/tools/zuul/index.html new file mode 100644 index 0000000000..78e2d138db --- /dev/null +++ b/community/community/tools/zuul/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/contribute/adding-docs-guide/index.html b/community/contribute/adding-docs-guide/index.html new file mode 100644 index 0000000000..ebdb76065c --- /dev/null +++ b/community/contribute/adding-docs-guide/index.html @@ -0,0 +1,69 @@ + + + + + +Adding Docs Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Adding Docs Guide

+

In this Guide you will learn how to integrate your documentation to the SCS documentation, which you will find on docs.scs.community.

+

Step 1 – Documentation type

+

Determine the type of your documentation and click to continue.

+
    +
  1. Technical documentation
  2. +
  3. Operational documentation
  4. +
  5. Community documentation
  6. +
+

If unsure don't hestitate to ask us at Matrix

+

1. Technical Documentation

+

Step 1 – Checklist

+

Your repository containing the documentation has to...

+
    +
  • be a public repository
  • +
  • contain a directory named /doc or /docs within root, containing the documentation files
  • +
+

The documentation files have to be in markdown format and...

+ +

Step 2 – Adding your repo to the docs.json

+

File a Pull Request within the docs repository and add your repo to the docs.package.json:

+
[
{
"repo": "demo-organisation/demo-repository",
"source": "doc/*.md",
"target": "docs",
"label": "demo-repository-label"
}
]
+
keydescription
reporeference to github organisation and repository
sourcepath to content to copy: Either glob matching individual markdown files OR the path of a single directory
targetdirectory where the files should be copied to within the docs-page repo
labellabel for directory. only mandatory if source file is set to copy only *.md files and not the complete directory
+

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 page – now with your content.

+

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.

+

2. Operational documentation

+

Your doc files contain operational knowledge. Which layer in the stack do they belong to?

+
    +
  1. iaas
  2. +
  3. iam
  4. +
  5. kaas
  6. +
  7. operations
  8. +
+

File a Pull Request within the docs repository and add your markdown files to the fitting directory.

+

3. Community documentation

+

Your doc files contain knowledge regarding our community? Choose the right directory. If unsure don't hestitate to ask us at Matrix.

+

File a Pull Request within the docs repository and add your markdown files to the fitting directory.

+ + \ No newline at end of file diff --git a/community/contribute/doc-files-structure-guide/index.html b/community/contribute/doc-files-structure-guide/index.html new file mode 100644 index 0000000000..244b37e549 --- /dev/null +++ b/community/contribute/doc-files-structure-guide/index.html @@ -0,0 +1,59 @@ + + + + + +Documentation Files Structure | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Documentation Files Structure

+

Structure Best Practice

+

Overview - mandatory

+
    +
  • What is it and for what do I need this? What benefits does it have for users?
  • +
  • What organization/company does this belong to? (Link to company/organization)
  • +
  • Where am I – as module – within the bigger context of SCS?
  • +
+

Requirements - mandatory

+
    +
  • What minimal requirements do i need to quickstart?
  • +
+

Quickstart - optional. If it is possible, then mandatory

+
    +
  • Link to requirements
  • +
  • What is the aim of this quickstart guide?
  • +
  • Caution: only for testing, not for production
  • +
  • Rule: one line per command for easy copy&paste and one line for description where possible
  • +
  • Rule: only one working path for installation!
  • +
+

Getting Started - mandatory

+
    +
  • Aim is a production ready installation
  • +
+

Configuration – mandatory

+
    +
  • Showing all possible config options
  • +
+

Contribute – mandatory

+
    +
  • Description for how can i contribute with Link to Github repository
  • +
+

FAQ`s – optional

+
    +
  • Roadmap - optional
  • +
+ + \ No newline at end of file diff --git a/community/contribute/docs-workflow-explanation/index.html b/community/contribute/docs-workflow-explanation/index.html new file mode 100644 index 0000000000..eaaebf1462 --- /dev/null +++ b/community/contribute/docs-workflow-explanation/index.html @@ -0,0 +1,38 @@ + + + + + +Documentation workflow explanation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Documentation workflow explanation

+

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.

+

Information Architecture

+
    +
  • +

    All general docs are located within the SovereignCloudStack/docs repository.

    +
  • +
  • +

    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.

    +
  • +
+

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. In order to make this work we have developed a workflow that syncs all doc repositories and distills only the relevant markdown files.

+

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.

+

You'll find the script in the root directory of the SovereignCloudStack/docs-page repository:

+
getDocs.js
const fs = require('fs')
const { execSync } = require('child_process')

// Read the contents of the "docs.package.json" file and remove all whitespace
const reposJson = fs
.readFileSync('./docs.package.json', 'utf8')
.replace(/\s/g, '')

// Parse the JSON and create an array of repositories
const repos = JSON.parse(reposJson)
const ghUrl = 'https://github.com/'

// Clone each repository, remove git folders and README files, and copy the docs to the target directory
repos.forEach((repo) => {
const repoDir = `repo_to_be_edited/${repo.label}`

// Clone the repository
const cloneCommand = `git clone ${ghUrl + repo.repo} ${repoDir}`
execSync(cloneCommand)

// Remove git folders
const removeGitCommand = `rm -rf ${repoDir}/.git`
execSync(removeGitCommand)

// Remove README files
const removeReadmeCommand = `find ${repoDir} -name "README.md" | xargs rm -f`
execSync(removeReadmeCommand)

// Create the docusaurus subdirectory
const subDirPath = `${repo.target}/${repo.label}`
fs.mkdirSync(subDirPath, { recursive: true })

// Copy docs content from A to B
const copyDocsCommand = `cp -r ${repoDir}/${repo.source} ${subDirPath}`
execSync(copyDocsCommand)

// Remove the cloned repository
const removeRepoCommand = 'rm -rf repo_to_be_edited'
execSync(removeRepoCommand)
})
+ + \ No newline at end of file diff --git a/community/contribute/linting-guide/index.html b/community/contribute/linting-guide/index.html new file mode 100644 index 0000000000..369b158ae6 --- /dev/null +++ b/community/contribute/linting-guide/index.html @@ -0,0 +1,50 @@ + + + + + +Linting Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Linting Guide

+

In order to have a clean content repository regarding all markdown files we enforce linting on:

+
    +
  1. all staged files prior committing
  2. +
  3. all Pull Requests
  4. +
+

Pre Commit

+

Run markdownlint against staged git files with Husky git hook:

+
    +
  1. lint-staged
  2. +
  3. husky
  4. +
+

The rules are enforced on markdown files, for which we use:

+
    +
  1. markdownlint-cli2 for markdownlint
  2. +
  3. prettier for code formatting
  4. +
+

The markdownlint rules are defined in the configuration file .markdownlint-cli2.jsonc

+

Additionally we use markdownlint-rule-search-replace for fixing

+

Local Usage for development

+
npm run lint:md <file>
npm run fix:md <file>
+

Github Workflows

+

There are two actions running on every Pull Request on the main branch.

+
    +
  1. link-validator.ymlis checking every link in markdown files.
  2. +
  3. pr-markdownlint.ymlis checking all markdown files regarding to the rules defined within .markdownlint-cli2.jsonc
  4. +
+ + \ No newline at end of file diff --git a/community/contribute/local-docusaurus-development-guide/index.html b/community/contribute/local-docusaurus-development-guide/index.html new file mode 100644 index 0000000000..22d42a735a --- /dev/null +++ b/community/contribute/local-docusaurus-development-guide/index.html @@ -0,0 +1,51 @@ + + + + + +Installation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Installation

+

This Guide shows you how to setup docusaurus on your local machine to run this docs in your local development enviroment.

+

Requirements

+
    +
  • git
  • +
  • Node.js v16
  • +
+

Installation Guide

+

Step 1 – Installing Node.js via nvm

+

It is recommended to install Node.js via nvm – a node version manager – to have the possibility to switch between different node.js versions.

+

You must have macOS desktop access with administrator privileges.

Login to the macOS desktop system and install Homebrew on your system (if not already installed).

Install nvm via homebrew:

brew install nvm
+

Once installed you can check the available versions with

+
nvm list
+

If you have no other projects, where you need a different version, it is recommended to install the latest stable LTS version of node.

+
nvm install lts
+

nvm has now installed the latest node.js version with its package manager npm. Check if the installation has been successfull by checking it:

+
node --version
+

Step 2 – Cloning the repository

+

Clone the docs repository via your favourite method:

+
HTTPS
git clone https://github.com/SovereignCloudStack/docs.git
+

Step 3 – Installing dependencies

+

Change your working directory within your terminal to the root of the cloned repository /docs and install all dependencies:

+
npm install
+

Step 4 – Starting the development server

+

You can now run the local development server from your terminal:

+
npm start
+

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.

+ + \ No newline at end of file diff --git a/community/contribute/styleguide/index.html b/community/contribute/styleguide/index.html new file mode 100644 index 0000000000..2712c618ba --- /dev/null +++ b/community/contribute/styleguide/index.html @@ -0,0 +1,51 @@ + + + + + +Styleguide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Styleguide

+

Admonitions

+

We adopt the default Admonition colors for Note, Tip, Info, Caution, Danger by docusaurus:

+

Docusaurus Admonitons

+
note

Some content with Markdown syntax.

+
tip

Some content with Markdown syntax.

+
info

Some content with Markdown syntax.

+
caution

Some content with Markdown syntax.

+
danger

Some content with Markdown syntax.

+

Blockquotes

+

Blockquotes should be handled with standard markdown >

+

Example Blockquote:

+
+

The raw data format is really the only sensible format option to use with RBD. asdasdasdasd asd asd a +Technically, you could use other QEMU-supported formats +(such as qcow2 or vmdk), but doing so would add additional overhead, and would +also render the volume unsafe for virtual machine live +migration when caching (see below) is enabled.

+
+

Codeblocks

+

We support markdown language features for Codeblocks. +It is mandatory to define the language to be quoted, when using codeblocks. +Syntax Highlighting is also supported by Docusaurus via Prism. +We are using the GitHub language themeing as default.

+
Python example
def code_block():
# Everything in this function is part of the same code block
print (1)
print (2)

for i in range(4):
# Everyting in this loop is part of the same code block
print (i)
+
Javascript example
const code_block = () => {
console.log('inside code_block')
}
+
YAML example
---
doe: 'a deer, a female deer'
ray: 'a drop of golden sun'
pi: 3.14159
xmas: true
french-hens: 3
calling-birds:
- huey
- dewey
- louie
- fred
+
Ruby example
require 'redcarpet'
markdown = Redcarpet.new("Hello World!")
puts markdown.to_html
+ + \ No newline at end of file diff --git a/community/contribute/styleguides/ansible_styleguide/index.html b/community/contribute/styleguides/ansible_styleguide/index.html new file mode 100644 index 0000000000..0c54549657 --- /dev/null +++ b/community/contribute/styleguides/ansible_styleguide/index.html @@ -0,0 +1,77 @@ + + + + + +Ansible Style Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Ansible Style Guide

+

We use nearly all default rules of ansible lint. A listing of all these rules can be found in the Ansible Lint documentation: +https://ansible.readthedocs.io/projects/lint/rules/. +Please always use the ansible linting to check if the code complies with the default linting rules. +However, since in most cases we always use the latest version of packages and Ansible lint does not provide this, we decided to +disable the package_latest rule.

+

Task naming

+
    +
  • Tasks must always have names. The only exception allowed is for forked playbooks.
  • +
  • A name never starts with a small letter
  • +
  • Names are written in present tense
  • +
  • No punctuation is used in names
  • +
+

Key Order

+

To check the key order we use our own rule. This can be found here.

+

Positioning and use of the become directive

+

The become directive is only set when needed and is always set explicitly for each task that needs it.

+

Blocks, roles or playbooks are never executed in a privileged mode.

+

We always insert the become directive between the name of a task and the task itself. This also applies to related directives +like become_user or become_flags. This is for better visibility if a task is privileged or not.

+
- name: Copy hddtemp configuration file
become: true
ansible.builtin.copy:
src: "{{ ansible_os_family }}/hddtemp"
dest: "{{ hddtemp_conf_file }}"
owner: root
group: root
mode: 0644
notify: Restart hddtemp service
+

Position of the when condition

+

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 +easier to understand for others. Ansible lint provides the when condition under the task name for blocks. To keep the code clear +we decided against it. Please disable this with a noqa if necessary. For example:

+
- name: "Archive existing {{ resolvconf_file }} file"
become: true
ansible.posix.synchronize:
src: "/etc/resolv.conf"
dest: "/etc/resolv.conf.{{ ansible_date_time.date }}"
archive: true
delegate_to: "{{ inventory_hostname }}"
when: stat_resolvconf_file.stat.islnk is defined and not stat_resolvconf_file.stat.islnk
+

Usage of collections

+

Collections are always defined as in the following example.

+

netbox.netbox is here the collection that is used.

+
- name: Configure netbox manufacturers
netbox.netbox.netbox_manufacturer:
netbox_url: '{{ netbox_url }}'
netbox_token: '{{ netbox_token }}'
data:
name: '{{ item.value.name }}'
slug: '{{ item.value.slug }}'
description: "{{ item.value.description | default('') }}"
state: present
with_dict: '{{ netbox_data_manufacturers }}'
+

Please don´t declare it in this way!:

+
collections:
- netbox.netbox

tasks:
- name: Manage Discworld site
netbox_site:
netbox_url: "{{ netbox_url }}"
netbox_token: "{{ netbox_token }}"
validate_certs: false
data:
name: Discworld
slug: discworld
state: present
+

If you have to use collections please define them in a requirements.yml.

+

Example yaml:

+
roles:
- name: geerlingguy.certbot
version: master
type: git
src: git+https://github.com/geerlingguy/ansible-role-certbot.git
---
collections:
- name: ansible.netcommon
source: https://galaxy.ansible.com

- name: https://github.com/ansible-collections/ansible.posix.git
type: git
version: main
+

Usage of roles from other collections

+

If you want to reuse roles please do it in the following way:

+

First you have to declare the role or collection in the requirements.yml like shown in the example before.

+

Than you can use it in playbooks like this

+
roles:
- role: osism.services.auditd
+

Parameters that offer lists

+

Parameters that provide a list are always defined as in the following example.

+

docker_hosts_defaults sets the defaults in the role. Overriding is only possible with the ansible-defaults repository.

+

In the configuration repository, docker_hosts_extra is then used to add additional items to the list.

+

docker_hosts itself is never modified from the outside.

+
docker_hosts_defaults:
- 'unix:///var/run/docker.sock'
docker_hosts_extra: []
docker_hosts: '{{ docker_hosts_defaults + docker_hosts_extra }}'
+

Usage of changed_when

+

Please think twice before turning off changed_when. It's a fairly simple yet safety-relevant linting rule and is quite easy to +implement.

+

Disable linting rules

+

In principle, it is only allowed to disable rules if there is really no other possibility. +Please do not disable rules in general but only in individual cases via Noqa. Please use in this case the full rulename and not +the numbers, because them are depricated. If it makes sense to ignore a rule, please open up an issue in the +https://github.com/osism/issues repository with a label discussion.

+ + \ No newline at end of file diff --git a/community/hackathons/checklist/index.html b/community/hackathons/checklist/index.html new file mode 100644 index 0000000000..46fce770f8 --- /dev/null +++ b/community/hackathons/checklist/index.html @@ -0,0 +1,148 @@ + + + + + +Hackathon planning checklist | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Hackathon planning checklist

+

This checklist is designed to simplify the planning of hackathons and meetups. All items are suggestions and optionally adaptable +to the situation.

+

Checklist 6 months before Hackathon

+
DateTask
  • - [ ]
Clarify sponsorship
  • - [ ]
Clarify who is responsible for planning. Contact persons of the companies involved. These should then also be present at the hackathon.
  • - [ ]
Set a specific date.
  • - [ ]
Clarify responsibilities.
  • - [ ]
First advertising in form of advertising in meetings, LinkedIn post, mailing list or similar.
  • - [ ]
Clarify which advertising measures are required (see checklist advertising).
  • - [ ]
Determine venue.
  • - [ ]
Set the theme for the hackathon and apply it to the design.
+

Checklist advertising

+
TopicTask
  • - [ ]
Social MediaCreate content plan.
  • - [ ]
Which accounts/people/companies have to be mentioned as well.
  • - [ ]
Which persons must agree to a publication.
  • - [ ]
Should hashtags be used, if yes which ones.
  • - [ ]
NewsletterCreate content plan with possible content and frequency.
  • - [ ]
WebsiteContent plan: Blogposts.
  • - [ ]
Info landing page.
  • - [ ]
Registration page.
  • - [ ]
Special newsletter or just regular.
  • - [ ]
Other placementsSpread the word in meetings or at other events.
  • - [ ]
MediaShould be changeable, specify target audience, language, sources.
  • - [ ]
Media suggestionsVideo, images, PDF, texts, merch, graphics. Everything should be planned in advance precisely date, type, releases, scope, size, etc.
  • - [ ]
GraphicsSet design motto.
  • - [ ]
Key metricsShould the success be tracked by key metrics, if so which ones.
+

Checklist 5 months before Hackathon

+
DateTask
  • - [ ]
Clarify if extra merch is desired and start looking for vendors. Order samples.
  • - [ ]
Discuss concrete advertising measures.
  • - [ ]
Check hotels (see checklist hotel).
+

Checklist hotel

+

Iportant things

+
    +
  • Availabilities in the period.
  • +
  • Way from the hotel to the hackathon.
  • +
  • Parking at the hotel.
  • +
  • Way from train station to hotel.
  • +
  • Checkin / Checkout times.
  • +
  • Check barrier-free accessibility.
  • +
+

Nice-to-have things

+
    +
  • Bar in the hotel, for relaxed sitting together in the evening.
  • +
  • Clarify whether employees from on site are also allowed in the bar.
  • +
  • Clarify whether reservations must be made in the bar, if so, reserve for the evening before.
  • +
  • Possibility of contingent reservation.
  • +
+

Checklist 4 months before Hackathon

+
DateTask
  • - [ ]
Determine hotel final and make recommendation. Possibly reserve contingent if the hotel offers it.
  • - [ ]
Find the location for the evening before (see checklist for evening before location).
  • - [ ]
Start organizing venue. (See checklist rooms 1).
  • - [ ]
Roughly plan evening event (consider volume level and space available).
  • - [ ]
Promotional drumbeat. Social media, website, meetings, newsletter.
  • - [ ]
Order special merch.
  • - [ ]
Organize merch in general (see merch checklist).
  • - [ ]
Start collecting statements that need to be sent around. (Privacy statements, photo statements, data center statements, security statements).
  • - [ ]
Rough sequence of events to be able to plan more precisely at a later date.
+

Checklist for evening before location

+
    +
  • Volume level.
  • +
  • Consider food possibilities.
  • +
  • Enough space.
  • +
  • Availability.
  • +
  • If intermediate change from A to B, then plan and include firmly in the plan.
  • +
  • If it is necessary to choose two locations because of food, drink, coziness, distance to the hotel: plan both, ask for and book them.
  • +
  • Ask for flexibility in the reservation. If more people come as registered.
  • +
  • Plan times.
  • +
  • Price / performance ratio should fit.
  • +
  • Way from the hotel to the evening before location.
  • +
+

Checklist rooms 1

+
    +
  • Space available (Enough space available for: Work area, meet-up area, no-photo area, break room, restrooms?).
  • +
  • Provisional room plan.
  • +
  • How long are the rooms available?
  • +
  • Are there any legal/corporate issues to consider?
  • +
  • Do declarations need to be signed to enter the premises?
  • +
  • List what hackathon relevant equipment is on site and if anything needs to be organized. For example, screens, whiteboards, power sockets if necessary, +tables, chairs, wi-fi, etc.
  • +
+

Checklist merch (examples)

+
    +
  • Ballpens
  • +
  • Lanyards
  • +
  • Notepads
  • +
  • Stickers
  • +
  • ID card / name badge covers
  • +
  • Name badges
  • +
  • Snacks
  • +
+

Checklist 3 months before Hackathon

+
DateTask
  • - [ ]
Required declarations (photo/video usage rights, data center, premises, etc.) are available as a form. Have a look if you can have
them confirmed with the registration. Otherwise as a circular email to all who register with the registration confirmation. Well
visible. For the photo/video declaration: Give the option of refusing and explain the variant with the no-photo dot.
  • - [ ]
Promote again: Website, social media, newsletter, meetings, circular email, etc....
  • - [ ]
Make reservations for pre-evening event.
  • - [ ]
Plan evening event and reserve location / tables (see checklist evening event).
  • - [ ]
Create a provisional schedule.
  • - [ ]
Eventually invite people separately. (Special guests).
  • - [ ]
Schedule start time and arrival time. Allow enough time for everyone to arrive.
  • - [ ]
Set presentation time and end time.
  • - [ ]
Define arrival time evening event. Leave enough time to change, but also do not define too long.
  • - [ ]
Schedule a fixed cleanup time.
  • - [ ]
Plan break time.
  • - [ ]
Activate login page.
+

Checklist evening event

+
    +
  • Volume level (It should be possible to have relaxed conversations)
  • +
  • Available space
  • +
  • Price / performance ratio should be suitable
  • +
  • Check availabilities
  • +
  • Snacks should be possible
  • +
  • Request flexibility with reservation (number of participants)
  • +
  • Actions would be a nice-to-have, everyone has been sitting and working all day, so it's good to have a change.
  • +
  • Way from the hotel to the evening location.
  • +
+

Checklist 2 months before Hackathon

+
DateTask
  • - [ ]
Start collecting goals and topics.
  • - [ ]
Work out goals and topics yourself.
  • - [ ]
Check results from the checklist rooms 1 again.
  • - [ ]
Go through checklist rooms 2.
  • - [ ]
Advertising (social media, mailing list, website, blog post, newsletter, room plan video, etc).
  • - [ ]
Go through checklists again in general, was anything forgotten?
  • - [ ]
Plan food for the break.
  • - [ ]
Plan snacks / breakfast (See snacks checklist).
+

Snacks checklist

+

Breakfast examples

+
    +
  • Sandwiches (rolls)
  • +
  • Pretzel sandwiches
  • +
  • Sandwiches (toast)
  • +
  • Cocktail tomatoes
  • +
+

Snack exemples

+
    +
  • "Kinder Schokobons"
  • +
  • "Kinder Schokoriegel"
  • +
  • "Kinder Duplo"
  • +
  • Hanuta
  • +
  • Gummy bears
  • +
  • Apples
  • +
  • Bananas
  • +
  • Nuts
  • +
  • Grapes
  • +
  • Dried fruits
  • +
  • Salted sticks
  • +
  • Salted pretzels
  • +
+

Vegan snack examples

+
    +
  • "Katjes Fruchtgummi"
  • +
  • "Katjes Lakritz"
  • +
+

Checklist rooms 2

+
    +
  • Create a room plan for publication. In it, work areas, break areas, no-photo area, meet-up places should be clearly +visible. Gladly also again as a video.
  • +
  • If necessary route map.
  • +
  • Is wifi available without any problems?
  • +
  • Where will drinks be located?
  • +
  • Where to set up snacks?
  • +
  • Where the food for the break?
  • +
  • Are there enough plates, cups, glasses, cutlery, napkins, and bowls for snacks?
  • +
+

Checklist 1 month before Hackathon

+
DateTask
  • - [ ]
Fix and publish the agenda.
  • - [ ]
Check the declarations once again, has every declaration been send, have any answered yet?
  • - [ ]
Check reservations, expand if necessary.
  • - [ ]
Check whether all possible special features have been observed (location etc).
  • - [ ]
Pre-order food for in-between meals and for the lunch break.
  • - [ ]
Plan drinks, type and quantity (don't forget coffee, tea, milk, sugar).
+

Checklist 1 week before Hackathon

+
DateTask
  • - [ ]
Print statements and forms.
  • - [ ]
Advertise again.
  • - [ ]
Make a list for the snacks (See for inspiration checklist snacks).
  • - [ ]
Pre-order the food, if necessary, check whether the quantity still fits with the registrations.
Depending on expand. Firmly plan transport / pickup / delivery.
  • - [ ]
Create a room plan with the topics, where, when, what takes place.
  • - [ ]
Organize drinks.
  • - [ ]
Determine the time when the helpers / organizers meet.
  • - [ ]
If necessary create / organize lists and visitor cards.
+

Checklist one day before Hackathon

+
DateTask
  • - [ ]
Buy snacks.
  • - [ ]
Contact food supplier again if the delivery date is suitable.
  • - [ ]
Check technology for functionality.
  • - [ ]
Send around the room plan with the topics by email.
  • - [ ]
Prepare rooms if necessary / possible.
  • - [ ]
Put drinks in the refrigerator.
  • - [ ]
Provide coffee machine.
  • - [ ]
Provide dishes.
  • - [ ]
Label rooms.
  • - [ ]
Check visitor cards and lists for completeness.
+

Checklist Hackathon Day X

+
TimeTask
  • - [ ]
Place snacks on the tables in small bowls or similar.
  • - [ ]
Distribute merchandise.
  • - [ ]
Have declarations and forms ready for late deciders.
  • - [ ]
Have lists and visitor cards ready if necessary.
  • - [ ]
Check drinks in an interval.
  • - [ ]
Make coffee if necessary.
  • - [ ]
Provide tea, coffee, milk, sugar.
  • - [ ]
Provide breakfast / snacks.
  • - [ ]
Pick up lunch.
  • - [ ]
Lunch "build up"
  • - [ ]
Cleanup
  • - [ ]
Keep an eye on the process (keep times a little bit).
  • - [ ]
See if everyone feels picked up, no one is bored.
  • - [ ]
Makes Photos.
+

Checklist after Hackathon

+
DateTask
  • - [ ]
Collect photos and provide them in a link for review and approval.
  • - [ ]
Create and send feedback sheet.
  • - [ ]
Create Blog Post Article.
  • - [ ]
Eventually create retro video.
  • - [ ]
Create social media posts. (After all approvals).
  • - [ ]
Prepare debriefing.
  • - [ ]
Summarize and process feedback.
+ + \ No newline at end of file diff --git a/community/index.html b/community/index.html new file mode 100644 index 0000000000..7376f8e70b --- /dev/null +++ b/community/index.html @@ -0,0 +1,27 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

Welcome to our SCS Community

+

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.

+

We have created an open community space on the Matrix network. Feel free to join the several channels and start interacting with the community. A good starting point is entering the General & Announcements and the Tech channel.

+

Check out our Community Calendar to know when our several Teams and SIGs meet.

+ + \ No newline at end of file diff --git a/community/license-considerations/index.html b/community/license-considerations/index.html new file mode 100644 index 0000000000..c3cd370ff6 --- /dev/null +++ b/community/license-considerations/index.html @@ -0,0 +1,214 @@ + + + + + +License considerations for SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

License considerations for SCS

+

As Sovereign Cloud Stack (SCS), our mission is to provide Operators +(be it Cloud Service Providers or just internal IT departments) with a well working software +stack, that avoids exposing them to legal risks or additional restrictions that limits the +usefulness. Free software licenses have this intention but differ in how they achieve it and in +what kind of protections they provide. In the first approximation, all OSI-approved +open source licenses can be considered as valid options. As a matter of fact, +we do consider projects under such licenses as valid modules for SCS — where we +use such projects and adjust or extend them, we would provide our contributions +under the license terms of the respective project, so we can achieve our goal to feed back code +upstream to the respective project, contribute to it and avoid fragmentation.

+

Where we do create independent code, we do have additional preferences, though.

+

For our own code, we do prefer the Affero General Public License version 3 +(AGPLv3) as license. Likewise, for documentation, we prefer CC-BY-SA. +Where we create standard libraries to interface with our software, we would +consider the LGPLv3 for these, +as we don't want interaction with our platform to be seen as requiring licensing +code.

+

Reciprocity

+

The GPL family of licenses are reciprocal licenses — sometimes called copyleft +licenses — the recipient of the licensed code can make all sorts of modifications, +but if she uses the code to release software (GPL) or provide a networked service +(AGPL) to others, then she must grant the same rights to the recipients — this +includes making the modifications available under the same terms as the received software. +Microsoft has infamously attacked +copyleft licenses (and specifically the GPL) as cancerous "viral" license.

+

Reciprocity has many advantages:

+
    +
  • +

    Code that has been created as free software will stay free. While GPL code can be +combined in a larger software collection with proprietary software, the code itself +including its enhancements etc. (technically: all derived works, see below) will +remain free.

    +
  • +
  • +

    The obligation to make the changes available avoids fragmentation. As changed and +"improved" versions need to be made available, it is much easier to review and feed +those changes back and create a unified upstream codebase that reflects the needs of +the complete user base by including the needed changes. This was observed and +reported by Martin Fink (HP's former CTO).

    +
  • +
+

The hugely successful Linux kernel project uses the GNU GPL; +many of the more traditional key projects in the open source world use copyleft licenses such as +the AGPL, GNU GPL, GNU LGPL, MPL or the OSL.

+

Controversy

+
    +
  • +

    Not fulfilling the license terms of a software license typically leads to the ability for the +license owner to revoke the license — as it is relatively easy to not fulfill all obligations +of the GPL out of sheer negligence, the revocation without prior warning seems +disproportionate — this is sometimes called the GPL death penalty. The open source community +though has a strong interest in bringing every licensee into compliance by giving violators a +fair chance to correct their behavior. SCS explicitly supports the GPL Cooperation Commitment +and the respective document +from the Linux kernel developers and pledges to give violators a warning and a chance to correct action +by allowing for a cure period. This is a bit of a legacy issue — it is relevant to (L)GPLv2 +code only — v3 of L/A/GPL does already contain language that has cure provisions, so it's +clear by the licensing terms.

    +
  • +
  • +

    Many companies seem to be worried that they will inadvertently violate the GPL by negligence. +And it is true that a company needs a tighter control of the usage of inbound source code +which comes with a reciprocal license than the permissive BSD 3-clause or Apache Software (v2) +licenses. This advantage however quickly turns into a disadvantage as soon as the company does +significant outbound open source contributions under a permissive license — they rarely want +to give their competitors an opportunity to consume their contributions and then add +proprietary changes to gain an advantage. In general, companies are well advised to have a +detailed understanding of all code that is being used and contributed and their respective +license terms — for proprietary and open source code and for reciprocal and for permissive +licenses. Some companies have successfully installed license review boards or +open source review boards +to create oversight, recommendations and policies to ease the governance.

    +
  • +
+

Despite this, many of the recent open source projects, especially in the cloud world +have adopted permissive licenses, such as X11, BSD 3-clause, MIT and especially the popular +Apache software license (ASL2), as it +appears to allow for faster adoption by companies that may not have mature open source +policies in place or that simply have overly careful lawyers which may be influenced +by the scare tactics some bad companies have built on top of copyleft licenses.

+

Affero

+

The reciprocity of the GNU GPL does not apply on the creation of a derived work. A company +can consume GPL'ed code and change it to their own liking without ever making any the +changes available if only used in-house. The terms however do apply as soon as the derived +work is released, i.e. the software is passed on to a third party.

+

In modern times, software is often used to provide a networked service (think SaaS) to third +parties. Unlike the standard GPL, the Affero GPL (AGPL) does consider the act of making it +available in such a way as similar to releasing the software and does require that applied +changes to the software are being made available in this case.

+

The AGPL thus closes a shortcoming in the traditional non-Affero GPL for a world that +increasingly moves towards networked services.

+

The very successful Nextcloud project uses the AGPLv3.

+

Derived works and Strong vs. Weak Copyleft

+

What exactly constitutes derived work needs to be defined — it's one of the questions where +copyright law can get subtle. From a practical view, consuming (non-trivial) source code and +binary linking is typically considered creating derived works. Whereas interacting via a network +API or starting another process is typically considered a copyright boundary. To avoid any +unclarity, the Linux kernel community has explicitly called out using Linux system calls (which +includes using the interface definitions) is a copyright boundary and can thus be done by +applications without any license implications.

+

Considering linked code to be derived works (as is the case in the GPL and AGPL) and thus +requiring it under the same (or a compatible) copyleft license is considered a Strong Copyleft +license.

+

Libraries are often providing implementations for standard services and helpers; it may not be +reasonable to consider applications that want to use a library as derived works from that +library and requiring the application to thus be licensed under a (compatible) copyleft license. +For these libraries, a Weak Copyleft license (such as the LGPL +or the EPL can be used. This would still require changes to +the library itself to me made available under the copyleft license but would make binary +linking (including the use of interface definitions) a copyright barrier and thus allow for +non-copylefted code to be linked against a weakly copylefted library. This license is used by +many of the standard and system libraries in the Linux world and is often a good choice for +libraries of standardized services.

+

Patents

+

Free software licenses are intended to give users broad rights — the GNU GPL talks about the +four freedoms to use software for any purpose, to study and +adjust the software (this needs source code access), to redistribute the software and to improve +it and to make these improvements available.

+

Software patents can significantly subvert the intended rights — the open source community in +general dislikes software patents for this and many other reasons that are discussed +elsewhere . +In some countries, there are rules that prevent pure software from being patented, though not +all patent offices are fully following these rules.

+

As software patents are existing and a serious danger to the open source goals, there are a few +attempts to improve the situation. The Apache Software License (a permissive license), requires +code contributors to grant a patent license to all downstream recipients of the code +to use the contributed code by itself or in combination with the project that it was contributed +to and makes a possible patent holder lose its license rights should he nevertheless try to +assert a patent against the thus licensed use. The (A)GPLv3 has a similar clause.

+

The Open Invention Network (OIN) has a meanwhile +huge patent pool that is cross-licensed between all participants and which can freely be used +in a large list of covered open source software by everyone, except for those that raise patent +violation claims against any of the covered open source projects. This basically restricts +those patents to be only used defensively in the context of the covered open source projects.

+

Should SCS be in a position to make inventions that should be protected by a software patent, +it pledges to contribute these to the OIN pool.

+ +

Very few Open Source projects require copyright assignment; the GNU projects are the +only commonly used ones that the author is aware of. This results in fully centralized +copyright ownership. This puts the FSF into a very +strong position — a position to enforce copyright, to change licenses etc. This requires +a lot of trust towards the copyright assigneed.

+

Most open source projects prefer distributed copyright — the authors (or their +employers) retain the copyright to their works. They grant a license for the open +source project to use and integrate and redistribute the work — typically the +license grant is extended to the public. In a sufficiently distributed copyright model, +it is very hard to change a license, as all copyright holders would need to agree. +This can both be considered advantageous and disadvantageous.

+

Many software projects use Contributor License Agreements +(CLAs), documenting that contributed code grants certain rights to the project +owner (a foundation or sometimes a company). This ensures that the project owner +has all needed rights to use, protect, redistribute ... the code. If the CLA contains +copyright assignment, it also allows the project to change the license or to +create derived works under a different license.

+

While this is advantageous for the project owner, it is not necessarily advantageous for the +code contributor.

+

Copyright enforcement does not require all copyrights to be held by a legal entity. Any holder +of significant copyrights can actually enforce it against violators.

+

The Linux kernel and an increasing number of projects do not work with copyright assignments +nor CLAs, but with Developer Certificates of Origin +(DCO — the signed-off lines of kernel commits). This is deemed sufficient to document the origin and the authorization to +contribute code.

+

The SCS project will not change the license. There however might be cases, where potential users +can not consume AGPL'ed or LGPL'ed code (due to corporate policies, e.g. based on bad experience, +immature license governance practices or lawyers that panic). Our goal would be to ensure that our +licensing terms and all other pledges provide the assurance needed that users do not need to be +afraid of the AGPL. The cure provisions from v3 of the GPL license family actually also help to +avoid unnecessary fear. However, unfortunately, some "open source" companies in the past have +abused copyleft with a scare and sell a proprietary license tactics to make money, which has +hurt copyleft acceptance significantly. We might thus not be successful and need to somehow +accept not serving all users or come up with a relicensing scheme that can not corrupt +ourselves. We are following the copyleft-next discussion to work out how we can best achieve +this, but have not yet found the silver bullet. This might have an influence how we do DCOs, +maybe under a permissive license, or maybe need to use CLAs.

+

License in = License out

+

It is best practice that open source projects grant their downstream users the same +license rights as they received contributions under. Or worded the opposite direction: +It is best practice to require no more rights to be granted from upstream contributors +(in the CLA or DCO) than the projects grants to downstream consumers of the project. +SCS follows this best practice.

+

Further reading

+
+ + \ No newline at end of file diff --git a/community/mission-statement/index.html b/community/mission-statement/index.html new file mode 100644 index 0000000000..2d3de9dbef --- /dev/null +++ b/community/mission-statement/index.html @@ -0,0 +1,76 @@ + + + + + +Mission Statement | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Mission Statement

+

Sovereign Cloud Stack (SCS) offers more than just a software stack — it's the embodiment of a collaborative open-source spirit, united by the aim of achieving digital sovereignty. At the heart of this initiative is a foundational pillar: the community.

+

Open Source technology has become increasingly mature. However, the greatest software is useless if it cannot be developed and operated with full confidence. For this to happen, it is imperative that skills and knowledge be built up, fostered, and retained. In an increasingly competitive market for skilled people and complex IT systems, this is becoming an ever greater challenge for governments, institutions, and companies. How can we operate digital offerings in a self-determined, secure, and excellent manner?

+

The answer to this must be the collectivization of operational knowledge, just as it has been practiced for many years with software development.

+

In essence, the community is the core of the Sovereign Cloud Stack. It not only propels its evolution but also ensures its relevance, reliability, and resilience in an ever-evolving digital landscape.

+

Read our open operations manifesto or join our Community either by joining our team meetings or by joining our matrix channel.

+

Check out the different meetings and working topics within our team and SIG introductions.

+

Values of our collaboration

+

4+1 Open

+

For us as a community, the "Four Open" are more than a philosophy; rather, we see them as fundamental values that are essential for working collaborativly.

+

The Four Opens give us the frame to develop SCS as a community that can be considered an important cornerstone tomorrow. We can also contribute to future developments and play an active role in shaping them.

+

The 'Four Open"

+
    +
  • Open Source: source code - open software that can be modified without restriction, on the condition that it is not limited in functionality or performance
  • +
  • Open Design: the open process for designing the software
  • +
  • Open Development: the opportunity to participate in the transparent development process on an equal footing
  • +
  • Open Community: an equal community where everyone can be heard
  • +
+

+1 Open

+

For us, the 5th Open is the Open Operation. At its core, the manifesto encompasses the collective, transparent exchange of knowledge. It describes the way to encourage everyone - regardless of their level of knowledge - to contribute to the community. The 5th Open has the principle that we can only learn from mistakes and therefore has an open and friendly mistake tolerance.

+

Our SCS '5-Open' community is just as open as described above - join us and leave your mark on the technologies of tomorrow. Join our Open Operations Meetup.

+

Code of Conduct

+

Sovereign Cloud Stack Community

+

Sovereign Cloud Stack (SCS) is a network of organizations and individuals: providers, integrators, contributors, users, developers, operators, and associates of standardized sovereign cloud infrastructure. We join forces in defining, implementing and operating a fully open, federated, compatible, interoperable cloud infrastructure and platform.

+

We are committed to "The Four Opens" of the Open Infrastructure Foundation and align our actions according to these four non-negotiable core principles of open collaboration. To include the whole DevOps approach we added the fifth open: Open Operations.

+

We do believe that an open and welcoming environment is essential for an active and engaged community. As contributors and maintainers we pledge to make participation in our project and our community a harassment-free experience for everyone.

+

No list is ever exhaustive, so we encourage members of the SCS community to adhere to the spirit, rather than the letter, of this code, as that is how it will be enforced. Places where this code may be particularly applicable are GitHub issues and pull requests, chat, mailing lists, team meetings, discussions on social networks broadly directed at or between members of the community, and other direct interactions within the community. Violations may lead to verbal or even public warnings or - especially in case of continued or flagrant offenses - may affect an individual's (or organization's) ability to participate within the SCS community.

+

We encourage you to confront someone or a group of people that you observe to be in violation of the CoC (whether in letter or in spirit) with your observation, so that the person(s) can correct his/her/their behavior. If this is not successful or it is difficult for you to confront the people and you seek support for this, you may contact the SCS project lead at project-lead(at)lists.scs.community

+

A large fraction of SCS consists of contributions to upstream projects. All SCS contributors are expected to adhere to the respective upstream Codes of Conduct when interacting with such projects, or developing code intended for upstreaming.

+

Our Standards

+

We ask you to please adhere to the following basic rules:

+
    +
  • Be friendly and patient. We were all new or lacked knowledge at various points in time. Please try to remember what it felt like to be on that end, and treat people accordingly.
  • +
  • Use welcoming and inclusive language. We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, organization, color, immigration status, social and economic status, educational level, level of experience, sex characteristics, gender identity and expression, sexual orientation, gender identity and expression, age, body size and personal appearance, disability, family status, political belief, religion, and mental and physical ability.
  • +
  • Be helpful. By helping others to learn our entire ecosystem is enriched. We encourage members of the SCS community to mentor each other and help to raise the general level of knowledge in the community whenever possible.
  • +
  • Choose words that shows respect, empathy and promote constructive dialogue. We are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable. This includes, but is not limited to: +
      +
    • Violent threats or language directed against another person.
    • +
    • Discriminatory jokes and language.
    • +
    • Posting sexually explicit or violent material.
    • +
    • Posting (or threatening to post) other people's personally identifying information ("doxing"), regardless of whether it is publicly available.
    • +
    • Personal insults, especially those using racist, sexist, or otherwise discriminatory terms.
    • +
    • Deliberately referring to others by names or pronouns counter to their identity.
    • +
    • Unwelcome sexual attention.
    • +
    • Repeated harassment of others, e.g. not stopping behavior when someone asks you to stop.
    • +
    • Advocating for, or encouraging, any of the above behavior.
    • +
    +
  • +
  • Be respectful, accept differing viewpoints and focus on what is best for the community. Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It's important to remember that a community where people feel uncomfortable or threatened is not a productive one. Members of the SCS community should be respectful when dealing with other members as well as with people outside the SCS community.
  • +
  • When we disagree, try to understand why. Disagreements, both social and technical, happen all the time and SCS is no exception. It is important that we resolve disagreements and differing views constructively. Remember that we're different. The strength of SCS comes from its broad community, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn't mean that they're wrong. Don't forget that it is human to err and blaming each other doesn't get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes.
  • +
+

Attribution

+

This Code of Conduct is mainly adapted from the Asahi Linux Code of Conduct and the Contributor Covenant Code of Conduct.

+ + \ No newline at end of file diff --git a/community/tools/github/branchprotection/index.html b/community/tools/github/branchprotection/index.html new file mode 100644 index 0000000000..64b70b40a8 --- /dev/null +++ b/community/tools/github/branchprotection/index.html @@ -0,0 +1,46 @@ + + + + + +Branch Protection Rules | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Branch Protection Rules

+

To protect our source code from unwanted changes, we enforce the following branch protection rules for all repositories within our GitHub organization:

+
    +
  • Require a pull request before merging into our default branch main. +
      +
    • Require at least one approval before pull requests can be merged.
    • +
    • Dismiss stale pull request approvals when new commits are pushed
    • +
    +
  • +
  • Require status checks to pass before merging +
      +
    • Require branches to be up to date before merging
    • +
    • Status checks that are required: + +
    • +
    +
  • +
  • Do not allow bypassing the above settings
  • +
+

The branch protection rules are rolled out by our 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.

+

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.

+ + \ No newline at end of file diff --git a/community/tools/github/dco-and-licenses/index.html b/community/tools/github/dco-and-licenses/index.html new file mode 100644 index 0000000000..ff3645a29e --- /dev/null +++ b/community/tools/github/dco-and-licenses/index.html @@ -0,0 +1,48 @@ + + + + + +Developer Certificate of Origin + Licenses | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Developer Certificate of Origin + Licenses

+

The Developer Certificate of Origin (DCO) is a lightweight way for contributors +to certify that they wrote or otherwise have the right to submit the code they +are contributing to the Sovereign Cloud Stack.

+
By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or

(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or

(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.

(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
+

All contributions to the Sovereign Cloud Stack are licensed under the +(OSI approved) open source license of the upstream project being used therein +(very often this is the Apache Software License v2).

+

Where we create independent code, we prefer to use the GNU Affero General Public License 3, +except for interface code which we would put under LGPL-3 (weak copyleft). +Own documentation content is licensed under Creative Commons BY-SA 4.0.

+

Contributors sign-off that they adhere to these requirements by adding a Signed-off-by +line to commit messages.

+
My fancy commit message

Signed-off-by: Christian Berendt <berendt@osism.tech>
+

Git has a -s command line option to append this automatically to your commit message:

+
git commit -s -m 'My fancy commit message'
+

The status of a pull request is set to failed if commits do not contain a valid Signed-off-by line.

+

Failed DCO in GitHub

+

Considerations behind the choice of AGPLv3, CC-BY-SA and the usage of the DCO can be found license-considerations.md.

+

Further reading

+
+ + \ No newline at end of file diff --git a/community/tools/github/tips-and-tricks/index.html b/community/tools/github/tips-and-tricks/index.html new file mode 100644 index 0000000000..7728b9561c --- /dev/null +++ b/community/tools/github/tips-and-tricks/index.html @@ -0,0 +1,32 @@ + + + + + +Tips and Tricks | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Tips and Tricks

+

Octo Reminder - your friendly assistant

+

Are you tired of keeping track of planned changes or issues you scheduled for the future? Our Octo Reminder is here to safe you from unneeded cognitive load!

+

The app configuration is stored in our .github repository. Using the bot is fairly simple:

+
    +
  • 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.
  • +
  • If you don't specify a time for the reminder, the bot will use 9:00 CET as default reminder time.
  • +
  • The date and time can be anything that momentjs understands, e.g. an ISO 8601 string or a relative string such as tomorrow or next week.
  • +
+ + \ No newline at end of file diff --git a/community/tools/jitsi/index.html b/community/tools/jitsi/index.html new file mode 100644 index 0000000000..88910eabfa --- /dev/null +++ b/community/tools/jitsi/index.html @@ -0,0 +1,43 @@ + + + + + +Jitsi | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Jitsi

+

We use a self-hosted Jitsi Meet instance for video conferencing. +Thanks go to Cleura for providing the server for it.

+

The server uses an automated deployment based on the +heat-docker-jitsi-meet project.

+

Configuration is such everyone who knows the room can connect, unless the moderator +sets a password/PIN. Opening a new room requires authentication. (Contact Kurt if +you need a password.)

+

Links to the meeting room (as well as dial-in information) are in the appointments +in the public calendar.

+

Usage

+

Connect with a desktop browser (Chrome/Chromium or other blink based browser +recommended due to superior WebRTC implementation with SimulCast/SVC for VP8/VP9 -- +Safari & Firefox work, but cause higher data traffic). For mobile devices use +the Jitsi Meet App.

+

Use the little arrows in the control bar at the bottom to select speaker, microphone +and camera in case you lack audio/video. Occasionally, you can not hear all but +one participant; in this case reconnecting typically helps.

+

We have an asterisk connected to some conference rooms to provide dial-in capabilities +for folks that lack internet connectivity (but have a working phone connection).

+ + \ No newline at end of file diff --git a/community/tools/mailinglists/index.html b/community/tools/mailinglists/index.html new file mode 100644 index 0000000000..e37edf1faa --- /dev/null +++ b/community/tools/mailinglists/index.html @@ -0,0 +1,27 @@ + + + + + +Mailing Lists | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Mailing Lists

+

We have an announcements mailing list there announce@lists.scs.community and you +can subscribe via the mailman3 frontend +also without the SCS nextcloud account if you prefer.

+ + \ No newline at end of file diff --git a/community/tools/matrix/index.html b/community/tools/matrix/index.html new file mode 100644 index 0000000000..ea7a5a3954 --- /dev/null +++ b/community/tools/matrix/index.html @@ -0,0 +1,27 @@ + + + + + +Matrix | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Matrix

+

We have created an open community space on the Matrix federation. Feel free to join the several channels and start chatting with our community. A good starting point is entering the General & Announcements and the Tech channel.

+

Client and Registration

+

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. A list of curated Matrix clients is collected on the official Matrix website: https://matrix.org/clients/

+ + \ No newline at end of file diff --git a/community/tools/nextcloud/index.html b/community/tools/nextcloud/index.html new file mode 100644 index 0000000000..c4beefa750 --- /dev/null +++ b/community/tools/nextcloud/index.html @@ -0,0 +1,33 @@ + + + + + +Nextcloud | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Nextcloud

+

We have a Nextcloud +instance for sharing files, doing polls, ... +setup for things that are not public.

+

You can contribute to SCS via the github workflows, asking questions there (via +opening issues against the issues repository), submitting pull requests, ... +If you want to contribute on a regular basis, we are happy to also onboard you +to the nextcloud and do an onboarding call. Nextcloud onboarding also adds you +to the scs-member@lists.scs.community mailing list which also add you to the +announcement list (described in the next paragraph).

+ + \ No newline at end of file diff --git a/community/tools/zuul/index.html b/community/tools/zuul/index.html new file mode 100644 index 0000000000..f016f96eb4 --- /dev/null +++ b/community/tools/zuul/index.html @@ -0,0 +1,56 @@ + + + + + +Zuul | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Zuul

+

Zuul CI/CD pipelines and project gating

+

Since we are expecting a lot of pipelines beeing created and used GitHub actions won't keep up +well. We also expect cross-repository and even cross-project dependencies. Therefore we decided to +use Zuul as our main pipeline solution.

+

How to make a repo use Zuul

+
    +
  • Make Zuul aware of your repository in this repo
  • +
  • Create a file .zuul.yaml +
      +
    • An example can be found here
    • +
    • You can have a job section containing self-defined jobs which you need to write on your own
    • +
    • You have to have a project section containing +
        +
      • the default-branch name
      • +
      • the merge-mode which should be used to auto-merge
      • +
      • the jobs to run in each pipeline (gh_check, gh_gate, gh_post, gh_tag)
      • +
      • these pipelines are triggered by events which can be looked up here
      • +
      • some default jobs can be found here
      • +
      +
    • +
    +
  • +
  • If you have self-defined jobs, you need to create a folder .playbooks +
      +
    • this folder containers ansible playbooks which will be triggered
    • +
    +
  • +
+

General information about Zuul

+

Zuul does not take anything for granted. If you need to have something installed, +you should install it via ansible. Our test-machines are basically pimped +docker-containers, so we might run into issues some time. But for now, things work pretty good.

+ + \ No newline at end of file diff --git a/contributor-docs/development/index.html b/contributor-docs/development/index.html new file mode 100644 index 0000000000..6bf5e54d21 --- /dev/null +++ b/contributor-docs/development/index.html @@ -0,0 +1,26 @@ + + + + + +Developer documentation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Developer documentation

+

Welcome to the developer section of the contributor docs. Here you will find +guidelines for the implementation of tooling such as the SCS conformance tests.

+ + \ No newline at end of file diff --git a/contributor-docs/development/tests/rfc2119-keyword-test-guide/index.html b/contributor-docs/development/tests/rfc2119-keyword-test-guide/index.html new file mode 100644 index 0000000000..4f63b776bf --- /dev/null +++ b/contributor-docs/development/tests/rfc2119-keyword-test-guide/index.html @@ -0,0 +1,120 @@ + + + + + +SCS RFC2119 Keyword Test Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS RFC2119 Keyword Test Guide

Introduction

+

The development and validation of tests within the Sovereign Cloud Stack (SCS) is a critical endeavor aimed at ensuring that cloud technologies meet the highest standards of interoperability, security and sovereignty. This process is not only about aligning with the technical specifications and standards set by SCS but also about safeguarding the principles of open-source collaboration and the autonomy of cloud services. By thoroughly crafting tests that adhere to the stringent requirement levels as indicated by RFC2119 keywords, we ensure that the infrastructure, services and their integrations within the SCS ecosystem are robust, secure and sovereign.

+

This detailed process is crucial for stakeholders seeking to develop or utilize sovereign cloud services that are reliable, compliant and capable of standing up to the demands of modern cloud computing. It serves as an indispensable guide for developers, operators and policymakers who are involved in the creation, deployment and governance of cloud services within SCS. By understanding and implementing the standards and tests defined by the SCS, professionals can contribute to a cloud infrastructure that is not only technologically advanced but also aligns with the core values of sovereignty and open-source ethics.

+

Therefore, for individuals tasked with writing tests and defining standards within SCS, this document is particularly important. It serves as a base with guidelines on how to use and understand RFC2119 keywords in the context of SCS. Its insights are crucial for anyone from technical architects to regulatory bodies within the SCS ecosystem, underlining the foundational principles necessary for achieving a sovereign cloud environment.

+

1. Understanding SCS Standards and RFC2119 Keywords

+

SCS standards use RFC2119 keywords like:

+
    +
  • MUST (same as REQUIRED, SHALL),
  • +
  • MUST NOT (same as SHALL NOT),
  • +
  • SHOULD (same as RECOMMENDED),
  • +
  • SHOULD NOT (same as NOT RECOMMENDED),
  • +
  • MAY (same as OPTIONAL)
  • +
+

to define requirements for SCS-compatible IaaS and KaaS resources. These standards & tests are crucial for ensuring interoperability and sovereignty in cloud services, as they are built on open-source components such as Kubernetes and OpenStack.

+

To ensure readability and comprehensibility, only the main keywords MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are referred to below.

+

2. Interpreting RFC2119 Keywords in the Context of SCS

+
    +
  • MUST and MUST NOT: These are binary and straightforward to test. Compliance or +non-compliance directly affects whether the standard is satisfied. For visualization, fulfilled +requirements could be marked in green, unfulfilled ones in red.
  • +
  • SHOULD and SHOULD NOT: These represent recommendations. While fulfilling these do +not directly affect standard compliance, it is advised for future-proofing against +potential standard evolutions. Non-compliance could be visualized in yellow, possibly +with a valid reason for non-fulfillment.
  • +
  • MAY: This is more flexible and could be used to provide additional +information or best practices. Their impact on compliance is not as direct as MUST or +SHOULD categories. These can be marked as blue.
  • +
+

3. Channels for Output in Test Scripts

+

In test scripts, different channels are used to convey information of different importance to the user. These channels are based on the ubiquitous and de-facto standard logging levels of common logging libraries in scripting and programming languages, in particular Python: DEBUG, INFO, WARNING, ERROR and CRITICAL.

+

Alignment of the RFC2119 keywords with specific channels in test scripts:

+
    +
  • MUST and MUST NOT lead to the ERROR channel for failed tests
  • +
  • SHOULD and SHOULD NOT lead to the WARNING channel, the test is still passed
  • +
  • MAY leads to the INFO channel, the test is still passed
  • +
+

However, the CRITICAL level is not directly associated with any of the RFC2119 keywords; it is instead used to signify that a test was unable to complete or was interrupted due to various issues, such as runtime failures.

+

4. Compliance and Test Passing Criteria

+

A test is considered to pass if and only if it doesn't produce any messages on the +ERROR nor the CRITICAL channel. The presence of warnings or informational items from +SHOULD and MAY categories do not directly impact the pass/fail status but is +important for overall quality and compatibility with future standards.

+

That means a test can have one of three results:

+
    +
  • fail: if it has at least one message on ERROR
  • +
  • DNF (did not finish): if it has no message on ERROR, but at least one on CRITICAL
  • +
  • pass: otherwise
  • +
+

In addition, a test MUST exit with a non-zero exit code (e.g., via sys.exit(…)) if there are any ERROR or CRITICAL messages, thus signaling a failure to meet a standard.

+

In test scripts it is a MUST to redirect all channel outputs to standard error (stderr), which aligns with Python's default logging behavior. The format which MUST be used is CHANNEL: MESSAGE, where CHANNEL represents the log level (e.g., DEBUG, INFO, WARNING, ERROR, CRITICAL) and MESSAGE encapsulates the actual log message.

+

For instance, when logging an INFO regarding a Kubernetes cluster, the format on the command line should be like this:

+
INFO: Checking cluster specified by context 'my-cluster' in /path/to/.kube/config.
+

This example adheres to our proposed format by clearly indicating the severity level (INFO) followed by the specific message intended for the user or developer.

+

Examples

+

5.1 Example: Standards Document using RFC2119 Keywords

+

The following example of a fictitious document for a "Web Server Installation Standard" +is intended to illustrate the use of RFC2119 keywords in connection with the creation of +SCS-compliant standard documents.

+

Web Server Installation Standard

+

Purpose

+

This document provides a concise set of requirements for installing a secure web server.

+

Requirements

+
    +
  • +

    Web Server Software: Apache HTTP Server 2.4.x or Nginx 1.18.x MUST be installed. No +other web server software versions or types are permitted.

    +
  • +
  • +

    Operating System: The server MUST run on an OS that receives current security updates. +Unsupported versions MUST NOT be used.

    +
  • +
  • +

    TLS Configuration: TLS 1.2 or higher MUST be enabled for all connections. SSL and +earlier TLS versions MUST NOT be used.

    +
  • +
  • +

    Security Patches: The web server and OS MUST be kept up-to-date with security patches. +Critical patches SHOULD be applied within 48 hours of release.

    +
  • +
  • +

    Firewall Setup: The firewall SHOULD be configured to allow only necessary ports, +such as 80 (HTTP) and 443 (HTTPS). All unnecessary ports SHOULD NOT be open.

    +
  • +
  • +

    Backup Plan: Regular backups of the web server data MAY be performed, and it is +recommended that backup integrity checks are conducted to ensure recoverability.

    +
  • +
+

Compliance

+

Failure to comply with these requirements results in the web server being +considered non-compliant with the organization's security policies.

+

5.2 Example: Test script using RFC2119 Keywords

+

The following example of a fictitious code for a test of "process_requirements" +is intended to illustrate the use of RFC2119 keywords in connection with the +creation of SCS-compliant standard tests.

+

import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

def process_requirements(var1, var2):
try:
# debug log for input variables
logger.debug(f"Received input var1: {var1}, var2: {var2}")

# example of an error case (equivalent to MUST and MUST NOT)
if var1 < 0:
logger.error("var1 must be positive")
elif var1 > 100:
logger.error("var1 must not exceed 100")

# add debug log to confirm evaluation of var1
logger.debug(f"var1 evaluated: {var1 > 0 and var1 < 100}")

# example of a warning case (equivalent to SHOULD and SHOULD NOT)
if var2 < 10:
logger.warning("var2 should be at least 10 for optimal performance")
elif var2 > 50:
logger.warning("var2 should not exceed 50 for optimal performance")

# add debug log to confirm evaluation of var2
logger.debug(f"var2 evaluated: {var2 > 10 and var2 < 50}")

# example of an informative case (equivalent to MAY)
if var1 + var2 < 100:
logger.info("Combination is within recommended range")
else:
logger.info("Combination exceeds the recommended range but may still proceed")

# debug log before completing the process
logger.debug(f"Final evaluation before completion: var1 + var2 = {var1 + var2}")

# success log
logger.debug("Process completed successfully")

except ValueError as e:
# debug log before raising a critical error
logger.debug("Encountered a critical error about to log", exc_info=True)
logger.critical(f"Process failed: {e}", exc_info=True)

+

Note: The DEBUG channel is used for additional information for developers to better understand a process and does not apply to RFC2119 keywords.

+ + \ No newline at end of file diff --git a/contributor-docs/development/tests/test-implementation-guide/index.html b/contributor-docs/development/tests/test-implementation-guide/index.html new file mode 100644 index 0000000000..20b63a1585 --- /dev/null +++ b/contributor-docs/development/tests/test-implementation-guide/index.html @@ -0,0 +1,95 @@ + + + + + +SCS Conformance Test Implementation Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Conformance Test Implementation Guide

SovereignCloudStack (SCS) uses conformance tests to certify +compliance of a given cloud offering with respect to a given certificate +scope such as SCS Compatible IaaS v4. +Our aim is that these tests are reliable, consistent and comprehensible for +the users. +This document is a guideline for conformance test authors and summarizes the +current best practices to achieve this goal.

+

1. Mapping of RFC2119 Keywords

+

Test authors working on new and existing conformance tests for an SCS standard +must implement the keywords such as MUST and SHOULD according to the SCS +RFC2119 Keyword Test Guide.

+

2. Unit and Regression Tests

+

Test authors are strongly encouraged to include unit and regression tests for +the conformance test's logic. +Conformance tests will inevitably contain some non-trivial algorithms, be it for +parsing flavor names or evaluating CVE vulnerability reports. +Testing them automatically and regularly against valid and invalid inputs helps +test authors to find programming mistakes early on. +As a bonus, a well written unit test also makes it easier for reviewers to cross +check a given pull request with new, enhanced or refactored conformance tests.

+

In general, unit and regression tests for the conformance tests are located in +the same location as the conformance tests, that is, the Tests/ directory of +the SCS standards repository. +Setup and development of the unit tests is described in the SCS conformance +tests README.

+

Naming Conventions

+

Any module that ends in _test will be picked up as a unit test module by +pytest in our CI pipeline (in other words, all files matched by the pattern +Tests/**/*_test.py). +Pytest will execute any function prefixed with test_ as a test function, or, +alternatively, tests based on the unittest module from the Python standard +library.

+

Follow these naming rules:

+
    +
  • The name of a unit test module is constructed from the module to be unit +tested and the _test suffix. For example, unit tests for flavor_names.py +should reside in flavor_names_test.py.
  • +
  • The name of a Python module in general should be a valid Python +identifier, to allow imports via the import statement. +For example, use flavor_names.py instead of flavor-names.py.
  • +
+

Write Testable Conformance Tests

+

Software design fills complete book shelves and this section can only cover some +basic best practices. +As a general rule of thumb, the earlier you begin writing unit tests, the better +– it will force you to write modules that are easy to test.

+

Divide conformance tests scripts into smaller, loosely coupled units, i.e., +functions that serve one purpose each. +Use the dependency injection technique, i.e., pass externally +retrieved data as function arguments instead of hardcoding the calls to the +retrieval functions inside a function. +Avoid logging calls deep down in the call hierarchy and use explicit return +values or raise exceptions, instead. +Here is an abstract example of a conformance test which does exactly that:

+
# property_compliance.py

def retrieve(location):
"""Retrieve raw data via network."""
...

def parse(data):
"""Parse raw data and return a dict."""
...

def handle(...):
"""Evaluate parsed data."""
...

def main(args):
...
data = retrieve(location)
parsed = parse(data)
result = handle(parsed)
...
if result.some_prop != expected_value:
logging.warn("some_prop is not as expected: %s (vs. %s)", result.some_prop, expected_value)
...
return result.success

if __name__ == "__main__":
# using sys.exit(…) only here makes it possible to unit test main(…)
sys.exit(main(sys.argv))
+

Adhering to this style makes it easier to test an algorithm in isolation, +without actually making a call to some external service.

+

Pytest Test Example

+

Assuming we want to unit test some members of the module property_compliance +from the previous section, we would create a file property_compliance_test.py +with the following content as a starting point:

+
"""Unit tests for property_compliance.

(c) Your Name <your.name@example.com>, 4/2024
SPDX-License-Identifier: CC-BY-SA-4.0
"""

import pytest

from property_compliance import parse


def test_success():
assert parse("some valid input") == "expected output"


def test_failure():
with pytest.raises(ValueError):
parse("invalid input")
+

3. Conformance Tests Shouldn't Require Admin Privileges

+

Conformance tests are expected to be executable without admin privileges (see §2 of +Regulations for achieving SCS-compatible certification). +In particular, this means:

+
    +
  • The cloud credentials (e.g., kubeconfig and OpenStack clouds.yaml) passed to +the scripts are non-admin credentials.
  • +
  • Conformance tests scripts should not require root privileges, except for the +installation of operating system prerequisites (e.g., a Python interpreter).
  • +
+ + \ No newline at end of file diff --git a/contributor-docs/index.html b/contributor-docs/index.html new file mode 100644 index 0000000000..d82066326f --- /dev/null +++ b/contributor-docs/index.html @@ -0,0 +1,26 @@ + + + + + +Documentation for SCS Contributors | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Documentation for SCS Contributors

+

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.

+

If you want to contribute you can reach out to us via our Matrix Channel.

+ + \ No newline at end of file diff --git a/contributor-docs/operations/iam/identity-federation-in-scs/index.html b/contributor-docs/operations/iam/identity-federation-in-scs/index.html new file mode 100644 index 0000000000..c9e6cd17e8 --- /dev/null +++ b/contributor-docs/operations/iam/identity-federation-in-scs/index.html @@ -0,0 +1,43 @@ + + + + + +Identity Federation in SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Identity Federation in SCS

SovereignCloudStack wants to make it possible for operators to delegate +administration of user identities to the organizational entities that the +users are part of. Usually that's customer organizations but it could also +be the operator itself. Federation protocols like OpenID Connect can be used +to achieve that goal. To simplify connecting the different parts of SCS +to customer owned IAM solutions, SCS deploys Keycloak as central Identity +Provider (IdP) service.

+

Currently this is deployed automatically only in the osism/testbed, +which provides its own documentation for authentication with OIDC.

+

The following sections describe how this is done.

+

1. IaaS / OpenStack

+

To provide Infrastrucure as a Service SCS builds upon +OpenStack. See section OpenStack Federation via OpenID-Connect +for more details on identity federation for OpenStack.

+

2. CaaS

+

To provide Container as a Service SCS builds upon +Kubernetes. There is +work in progress +to optionally connect Kubernetes to Keycloak and to +map authorization decisions based on claims via cluster role bindings.

+ + \ No newline at end of file diff --git a/contributor-docs/operations/iam/openstack-federation-via-oidc/index.html b/contributor-docs/operations/iam/openstack-federation-via-oidc/index.html new file mode 100644 index 0000000000..74ea035e73 --- /dev/null +++ b/contributor-docs/operations/iam/openstack-federation-via-oidc/index.html @@ -0,0 +1,89 @@ + + + + + +OpenStack Federation via OpenID-Connect | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

OpenStack Federation via OpenID-Connect

Keystone supports federating authentication and authorization decisions via several mechanisms +as documented by the project.

+

In SCS OpenID Connect is used for federation between Keystone and the IdP, which is +currently provided by Keycloak +in SCS.

+

The following sections describe the setup.

+

1. Keystone

+

Keystone supports federated identities. +To allow SCS to consume identities managed in external IAM solutions, +federation protocols like OpenID Connect or SAML can be used. +Keystone currently makes use of third party apache modules like +mod_auth_openidc, +mod_oauth2 and +mod_auth_mellon to delegate +authentication to a SSO IdP (i.e. SAML IdP or OpenID Connect provider).

+

In OpenStack the apache modules are configured using the +wsgi-keystone.conf template.

+

In SCS we make use of the OAuth 2.0 Authorization Code Grant flow between Keystone and Keycloak +and use PKCE (RFC 7636) with the S256 challenge method.

+

In addition to the usual SSL CA of the environment, Keycloak uses separate certificates to sign the OIDC tokens.

+

Due to the way the Keystone container image runs apache (in the foreground) and keystone itself (as WSGI module), +reconfiguring the apache URL locations on the fly is not possible currently without a downtime of several seconds. +That is the reason why SCS currently makes use of a single central proxy realm in Keycloak, to which Keystone +connects.

+

1.1 Keycloak IdP realm discovery

+

Keycloak offers standard OIDC service discovery via .well-known documents to advertise its endpoints.

+

In SCS we want to represent each customer by a separate dedicated Keycloak realm, which can enventually be used +for customer self service and to federate out to customer owned IAM external solutions.

+

In the SCS testbed we currently experiment with the implications of using a single central proxy realm in Keycloak +and chaining federation from there to customer specific realms, also hosted in the same Keycloak instance. +To make this usable, SCS makes use of the +Keycloak Home IdP Discovery +extension.

+

1.2 Keystone mapping of token claims

+

Upon login of a user Keystone evaluates the credentials obtained from the ID token that the IdP issued. +These include group memberships and roles, which can be used to assign the user to a certain project. +Keystone maps these external identities to internal (shadow) users. +It can either attempt to map the obtained information to a local type user, which needs to be +provisioned before authentication by external tooling, or it can be instructed via the mapping to +generate an ephemeral type user. ephemeral users are cleaned up automatically after some time +of inactivity and with that, they lose access to projects, iff the access is granted indirectly +via group membership rather than directly to the user itself.

+

Group memberships for ephemeral users are only represented via their tokens, but not stored in the +Keystone backend database.

+

After successful authorization Keystone issues an OpenStack specific fernet token to the user, +which is the currency that is understood by other OpenStack services and can be used to access them.

+

In SCS we want to represent each customer by a sepatate dedicated OpenStack domain to host +their projects and (shadow) user accounts.

+

The processing of information from the OIDC tokens is configured by two parts. The first part is the +rules.json mapping which is described in the +OpenStack federation mapping combinations +document. This file is used to configure Keystones internal mapping engine +and it needs to be attached to some OpenStack domain, which is named keycloak by default in SCS.

+

The second (static) part is the [auth] and [mapped] sections in keystone.conf (see e.g. +the overlays currently used in the OSISM testbed +).

+

1.3 Horizon WebSSO for federated users

+

The Horizon dashboard supports login via OpenID Connect via Keystone endpoint. +SCS adjusted the logout behavior to invalidate both, the OpenID Connect session +with the IdP and the Keystone token.

+

1.4 OpenStack CLI and API access for federated users

+

To support OpenStack CLI and API access, SCS implemented support for the OIDC Device Authorization Grant +in Keystone. On top we added support for PKCE (RFC 7636) in combination with that.

+

1.5 SSO Federation between to SCS deployments

+

To show the potential of this approach to federation SCS created a +Howto for OIDC federation between SCS deployments.

+ + \ No newline at end of file diff --git a/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide/index.html b/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide/index.html new file mode 100644 index 0000000000..e2939b61d6 --- /dev/null +++ b/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide/index.html @@ -0,0 +1,245 @@ + + + + + +Zuul users guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Zuul users guide

+

Prerequisites

+
    +
  1. Repository is known by SCS Zuul
  2. +
  3. Basic ansible knowledge
  4. +
  5. Basic yaml knowledge
  6. +
  7. zuul-client installed (Only if you want to create secrets. See also)
  8. +
+

Check SCS Zuul projects for your repository to +be available. If it is missing you need an administrator to get your repository +configured to Zuul.

+

Who is it for?

+

You may have heard about Zuul and may ask yourself if it is capable to support you. +Basically everything you use ansible for can be done using Zuul. That is not always +a good thing since you may get careless and your workload will exceed the CI/CD concept.

+

If you find yourself doing things under the following list you are at the right place.

+
    +
  1. Code testing
  2. +
  3. Deployment tests using IaC
  4. +
+

If you want to, let's say, monitor something using Zuul, that is possible but not the +intended use case.

+

Where do I start?

+

Right in your project's repository! The only prerequisite is that +your repository you want Zuul to work on is known by Zuul. This is done by the Zuul's +tenant configuration. To update this configuration you need access to the Zuul instance +or ask an administrator for help.

+

We assume that Zuul knows about your repository so we can get started. There are three +topics that you should know about. To get jobs running you need the "job" itself. Jobs run +within a "pipeline". The third important thing is to provide a "project" definition.

+

Where to save the Zuul relevant data?

+

Zuul will parse all branches of the untrusted repositories that Zuul knows about. +Your repository is most likely an untrusted one since only the configuration repositories should +have the "trusted" state. +So it doesn't matter whether you have just one branch containing Zuul files or all branches. Zuul +is looking for the following pathes on your repositories root.

+
./zuul.yaml # everything is in here

./.zuul.yaml # ... or here

./zuul.d/ # use directory style to get a bit of a structure
├── jobs.yaml
└── project.yaml

./.zuul.d/ # the same as before just hidden
├── jobs.yaml
└── project.yaml
+

Just use exactly one of the four possibilities.

+

If using the directory style configuration all yaml files within this directory will be +processed. If your projects configuration is small enough you may put all information in +a single file called zuul.yaml. It is also possible to create the file or the directory +with a leading dot to hide them for non zuul related work within the repository.

+

Projects

+

If Zuul is configured to observe your repository it will have a look at your projects +definition. Minimal example:

+
- project:
name: my-org/my-repo
default-branch: main
merge-mode: "squash-merge"
my_pipeline1:
jobs:
- my_job1
- my_job2
......
my_pipeline2:
jobs:
- my_jobs
...

+

By default Zuul will observe all branches for such files. We have to set the repository name +that have to match the exact value that was set for Zuul. Set a default-branch where actions +that don't match an explicit branch are executed on. Set the merge-mode that Zuul has to use. +But beware that not all issue tracker support all methods. For github squash-merge will work.

+

After these three properties add the pipelines you want to use to the project definition. +With the jobs list you define which jobs to run in which pipeline.

+

See official documentation

+

Pipelines

+

Every Zuul instance will have at least one repository that is used for configuration. There +you will find the available pipelines. Pipelines are used to run your jobs on a periodic or +event driven base. Pipelines can be used to run other pipelines and to keep your jobs in a +defined order if you need this.

+

Have a look at the configuration repository to utilize the pipelines for your repository. +See available pipelines for SCS. +You are not able to define new pipelines outside of a so called "configuration" repository. Since, +by default your repo is considered "untrusted". So in the first place you don't need to +think about, how to create a pipeline. Just use one that fits your needs as close as possible. Next you will +find an enumeration and a small description about the available pipelines in SCS Zuul.

+

Pipelines available in SCS Zuul:

+

1. check

+
    +
  • event driven pipeline
  • +
  • runs if a pull request is created, changed or reopened
  • +
  • re-runs if a comment contains recheck
  • +
+

2. gate

+
    +
  • event driven pipeline
  • +
  • trigger events: pull_request_review, pull_request, check_run
  • +
+

3. post

+
    +
  • event driven pipeline
  • +
  • trigger event: post
  • +
+

4. tag

+
    +
  • event driven pipeline
  • +
  • trigger event: push
  • +
+

5. e2e-test

+
    +
  • event driven pipeline
  • +
  • trigger event: pull_request
  • +
+

6. e2e-quick-test

+
    +
  • event driven pipeline
  • +
  • trigger event: pull_request
  • +
+

7. unlabel-on-update-e2e-test

+
    +
  • event driven pipeline
  • +
  • trigger event: pull_request
  • +
+

8. unlabel-on-update-e2e-quick-test

+
    +
  • event driven pipeline
  • +
  • trigger event: pull_request
  • +
+

9. periodic-hourly

+
    +
  • time based pipeline that runs every hour
  • +
+

10. periodic-daily

+
    +
  • time based pipeline that runs every day at 3 o'clock am.
  • +
+

11. compliance_check

+
    +
  • time based pipeline that runs every 15 minutes
  • +
+

If you want to know more about pipelines: See official documentation

+

Reports

+

The SCS Zuul instance can transmit build reports through an MQTT connection +to the dedicated Matrix chat room SCS | Zuul Reports. Currently, this MQTT reporting +feature is activated for periodic pipelines (periodic-hourly, periodic-daily, +compliance_check), and reports are dispatched solely in the event of +failures occurring in builds triggered by the mentioned pipelines.

+

See an example pipeline that reports failed result to the SCS | Zuul Reports Matrix room:

+
- pipeline:
name: pipeline-that-reports-to-matrix
description: |
In the event of a failure, this pipeline transmits reports to
the SCS | Zuul Reports Matrix chat room.
failure:
mqtt:
topic: "zuul/{pipeline}/{project}/{branch}/{change}"
+

Visit the official Zuul documentation +and explore the configuration options available for Zuul's reporters.

+

Jobs

+

All jobs that your Zuul instances knows of can be used for your own purposes. +Call them directly or implement a job that uses an existing job as parent. +Didn't find the right job? Than we have to create a new one. Existing jobs +can be found in the web ui of your Zuul instance: Example

+

First have a look on a basic job example:

+
- job:
name: base
parent: null
description: |
The recommended base job.

All jobs ultimately inherit from this. It runs a pre-playbook
which copies all of the job's prepared git repos on to all of
the nodes in the nodeset.

It also sets a default timeout value (which may be overidden).
pre-run: playbooks/base/pre.yaml
post-run:
- playbooks/base/post.yaml
- playbooks/base/post-logs.yaml
roles:
- zuul: zuul/zuul-jobs
timeout: 1800
nodeset:
nodes:
- name: ubuntu-jammy
label: ubuntu-jammy
+

Each job needs a name that has to be unique within the whole tenant. +A useful convention to achieve this is to prepend the name of the repository. +Each job need to define whether there is parent job or not. +Jobs without a parent are called "base" jobs. Usually you don't want to implement base jobs since +there are already some base jobs that implement often used stuff. A description may not be mandatory +but is obviously useful.

+

Necessary for Zuul to do anything you just need to add a run or roles property. Within a job that is +like a noop job or just printing something to stdout that is everything you need to run your first job. +Since anything we want to do requires a little bit more you have to define a nodeset. The nodes +are used to run your playbooks on. In 99,9% you will need this too.

+

The properties pre-run and post-run are useful for bootstrap and cleanup. If your actual job wants to create +bootstrap some infrastructure you can to this in the pre-run. Using an cloud provider you want to release +no longer used resources. That can be done in the post-run. If you are using a parent job it is likely +that the parent job may has pre- and post-run playbooks. In this case your pre- and post-run playbooks are +"nested". Example:

+
    +
  1. pre-run parent
  2. +
  3. pre-run my job
  4. +
  5. post-run my job
  6. +
  7. post-run parent
  8. +
+

If your job exceeds the defined timeout, the job is considered as failed.

+

See official documentation

+

What about secrets?

+

Right now you should be able to run basic tasks. But what if you try to test something +that needs credentials to connect to an outside service? Or you have to address additional +ressources in an openstack environment and you have to use something like app credentials?

+

That is where job secrets are used. Example:

+
- job:
name: SOME_JOB
parent: base
description: |
A job basic job used as example
secrets:
- name: clouds_conf
secret: app_credential_cloud_conf
run: playbooks/my-playbook.yaml
+

Secrets for a job are simply defined by the keyword secrets. +Each secret needs a name that can be used in your playbooks. +The property secret references the secret that is defined within your project.

+

ATTENTION! If your job is using a secret job.post-review is automatically +set to true. For untrusted projects, that means that your job is only called +in piplines that have the pipeline.post-review flag set to true. In SCS context +that means you may run these jobs only with the pipelines tag and post.

+

If you want to run jobs on pipelines that have post-review set to false, which +is default, and your job needs a secret, the secret may be defined in the zuul-config repository.

+

Example:

+
- secret:
name: app_credential_cloud_conf
data:
credentials: my-secret-value
+

Within my-playbook.yaml you can reference the secret value using "{{ clouds_conf.credentials }}". +In this example my-secret-value is clear readable text. That is not something we want to keep +secrets. But how do you encrypt secrets in a way that they are secure and also can be decrypted by +Zuul?

+

For this purpose Zuul creates its own public/private key pair for each project. Everyone may use the +public key to create secrets. But only Zuul will be able to decrypt these values. To avoid the user +to be responsible for the correct encryption there is an zuul-client tool that will do this for you.

+

Example (reading from stdin and writing to stdout):

+
zuul-client --zuul-url ZUUL_URL encrypt --tenant SCS --project SovereignCloudStack/REPO
+

Add --infile INFILE or --outfile OUTFILE if you prefer to work with files directly.

+

The output might look like this:

+
- secret:
name: <name>
data:
<fieldname>: !encrypted/pkcs1-oaep
- IGZ2Wu47R9mEY4fjetbxSAUGNaz4HR1mjk9lCLq3HsUMjHGj9YPlb2MvnPQw1LCJSvpaK
ogth7hi2zYwrs5tNAik/qlVSB7AM+LQRP7lmlM4JmD6WOyR7DisHu7oMD1Gqem2ZuMggA
DIBn5+DeBIvnwihDOcS+BKPTVMEtXOJNkuObZHE8DweB/RQIGUvjyeq5yoAmz/y+qGVqe
0Vk4pTYFIBgk5DMzwVnDzDkqs/QokoOupMUoBcpapmM11do4ymjbDpeINjayoro6VXTtX
Mkk9fDv9wuJIQTuyHAOfMD+UYS/HqVSF/Hm9ScUvfhw02gTdzKCxliWhFHJOj7RbdUUMK
OYYcUkNp5cXZUYFnflMhxVEnzREbdAIklNPfoHOizsxLPaUZ9yk6XcFRflFfMvqBtUS00
LCx0Uh906NwdaEUrv2ZdrN123rwfwfw4333232rDFDFfsdfddsfdDFSFSdqrrtwms5Mi0
szUBaM4j+Mayep+41vl0cpsLU91GzXEATWMaPIN8OnEHF6qQIv0wB6VaKd5aeAyERisb3
wFdjEo4faLO70RWzR33k+4xqAYNIIFyTMpWJz21CUSfoYG8ygL6t7RJGgyjA+0KsVEyj+
ewEtiaUOLYyD7pXtqdw1HgzjqiXnfxk+wSv/y5y/TGGYpQj8zU76jS7Zj0ft/0=
+

You may use this content or the file to provide it as a secret. You just have to update the <name> and the +<fieldname> part.

+

The secret name has to be unique across all projects. Because of this, we have a naming convention in the +SovereignCloudStack organisation that ensures that a secret has a unique name.

+

Our convention is as follows. There is only one secret per Zuul configuration per project (for exceptions, +see below). This secret always has a name in the form +SECRET_REPOSITORY_NAME. For instance, if a secret in the SovereignCloudStack/k8s-cluster-api-provider +repository is +to be used, it is given the name SECRET_K8S_CLUSTER_API_PROVIDER. The name of the repository is +always written in capital letters. A dash is replaced with an underscore. Any number of values +(<fieldname>: !encrypted/pkcs1-oaep) can then be assigned to this one secret.

+

In certain cases, it can be undesireable to expose all secret information to all jobs in a project. +Then additional secrets may be used, whose names have to be formed by appending an underscore and some +upper-case prefix to the name of the primary secret. For instance, we might use the +name SECRET_REPOSITORY_NAME_FOOBAR.

+

Official documentation:

+
    +
  1. Secrets documentation
  2. +
  3. Encryption documentation
  4. +
+

Let's put it all together

+

For a basic but working example the following content may be written into a zuul.yaml file.

+
# zuul.yaml content
---
- secret:
name: SECRET_REPOSITORY_NAME
data:
secretValue1: !encrypted/pkcs1-oaep
- <ENCRYPTED_DATA>
secretValue2: !encrypted/pkcs1-oaep
- <ENCRYPTED_DATA>
secretValue3: !encrypted/pkcs1-oaep
- <ENCRYPTED_DATA>

- job:
name: myFirstTestJob
parent: base
secrets:
- name: secretName # The name of the secret that is used within "playbooks/testPlaybook.yaml"
secret: SECRET_REPOSITORY_NAME
run: playbooks/testPlaybook.yaml

- job:
name: mySecondTestJob
parent: base
run: playbooks/testPlaybookTwo.yaml

- project:
tag:
jobs:
- myFirstTestJob
check:
jobs:
- mySecondTestJob
+

This will run the job myFirstTestJob whenever the tag pipeline is triggered, and +mySecondTestJob whenever check is triggered.

+

Within SCS the check pipeline is always triggered if you open, change or reopen a pull request. +This pipeline can also be triggered manually if you write a comment on an already +existing pull request and place the string recheck in it.

+

Recall that the first test job cannot run on the same pipeline because it uses a secret. +The tag pipeline is run whenever a new tag is created.

+

The path to you playbook is always the full path within the repository. The playbook +contains the tasks you actually want to run on all or a specific subset of nodes. +Example playbook:

+
# playbooks/testPlaybook.yaml content
---
- hosts: all
tasks:
- debug:
msg: 'Debug print my secrets! {{ secretName.secretValue1 }}' # do not do this as it will expose your secrets
+ + \ No newline at end of file diff --git a/data/additionalResourcesData.json b/data/additionalResourcesData.json new file mode 100644 index 0000000000..0358ce2ff1 --- /dev/null +++ b/data/additionalResourcesData.json @@ -0,0 +1,32 @@ +[ + { + "title": "Get in touch", + "body": "Come into our Matrix Chat in the SCS | Tech Room.", + "url": "https://matrix.to/#/#scs-tech:matrix.org", + "buttonText": "Join Now" + }, + { + "title": "Come to our Meet-Ups", + "body": "Our working groups and special interest groups meet weekly or biweekly. When? Find out within our public community calendar.", + "url": "/community/collaboration", + "buttonText": "Learn More" + }, + { + "title": "Standardization in progress", + "body": "Get to know our current Decision Records and Standards.", + "url": "/standards", + "buttonText": "Start Now" + }, + { + "title": "Deployment Examples", + "body": "Get to know different ways to deploy SCS with cloud resources or on bare metal.", + "url": "/docs/category/deployment-examples", + "buttonText": "Explore Cases" + }, + { + "title": "Application Examples", + "body": "Discover best practices to make the most of your cloud, from introductions to specific applications to advanced use cases.", + "url": "/user-docs/category/application-examples", + "buttonText": "Explore Cases" + } +] diff --git a/data/architecturalOverviewData.json b/data/architecturalOverviewData.json new file mode 100644 index 0000000000..e5fffb0462 --- /dev/null +++ b/data/architecturalOverviewData.json @@ -0,0 +1,108 @@ +{ + "ops": [ + { + "title": "Ops Layer", + "body": "Tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.", + "url": "/docs/category/operating-scs", + "buttonText": "Learn More", + "components": [ + { + "title": "Status Page", + "url": "/docs/category/status-page", + "mandatory": "true", + "stable": "true" + }, + { + "title": "Monitoring", + "url": "/docs/category/monitoring", + "mandatory": "false", + "stable": "true" + }, + { + "title": "SCS Health Monitor", + "url": "/docs/operating-scs/components/scs-health-monitor/overview", + "mandatory": "true", + "stable": "true" + }, + { + "title": "Central API", + "url": "/docs/operating-scs/components/central-api/overview", + "mandatory": "true", + "stable": "true" + }, + { + "title": "Automated Pentesting IaaS", + "url": "/docs/operating-scs/components/automated-pentesting-iaas/overview", + "mandatory": "true", + "stable": "true" + }, + { + "title": "Automated Pentesting KaaS", + "url": "/docs/operating-scs/components/automated-pentesting-kaas/overview", + "mandatory": "true", + "stable": "true" + } + ] + } + ], + "container": [ + { + "title": "Container Layer", + "body": "SCS offers a robust solution for managing container workloads on a Kubernetes infrastructure.", + "url": "/docs/container", + "buttonText": "Learn More", + "components": [ + { + "title": "KaaS V2: Cluster Stacks", + "url": "/docs/category/cluster-stacks", + "mandatory": "false", + "stable": "true" + }, + { + "title": "Container Registry", + "url": "/docs/category/container-registry", + "mandatory": "false", + "stable": "true" + } + ] + } + ], + "iaas": [ + { + "title": "IaaS Layer", + "body": "SCS offers OpenStack infrastructure solutions based on KVM virtualization to deploy VM workloads and enabling the container layer optionally.", + "url": "/docs/category/iaas-layer", + "buttonText": "Learn More", + "components": [ + { + "title": "Image Manager", + "url": "/docs/iaas/components/image-manager", + "mandatory": "true", + "stable": "true" + }, + { + "title": "Flavor Manager", + "url": "/docs/iaas/components/flavor-manager", + "mandatory": "true", + "stable": "true" + } + ] + } + ], + "iam": [ + { + "title": "IAM Layer", + "body": "Working on Keycloak federated identity provider within our Team IAM.", + "url": "/docs/iam", + "buttonText": "Learn More", + "components": [ + { + "title": "Keycloak", + "url": "/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations", + "mandatory": "false", + "stable": "true" + } + ] + } + ] +} diff --git a/data/featureContentData.json b/data/featureContentData.json new file mode 100644 index 0000000000..99b1926de6 --- /dev/null +++ b/data/featureContentData.json @@ -0,0 +1,26 @@ +[ + { + "title": "Introduction to SCS", + "body": "Get to know SCS better and learn about the background.", + "url": "/docs", + "buttonText": "Get Started" + }, + { + "title": "Releases", + "body": "SCS is currently in Release 7. Check out the latest Release Notes.", + "url": "/docs/releases/Release7", + "buttonText": "Learn More" + }, + { + "title": "Frequently Asked Questions", + "body": "You are curious what SCS is all about, what it can do and what it can't?", + "url": "/docs/faq", + "buttonText": "Get Answers" + }, + { + "title": "Existing Public Clouds", + "body": "There are SCS compliant public clouds in production.", + "url": "/standards/certification/overview#compliant-cloud-environments", + "buttonText": "Test Them" + } +] diff --git a/docs/category/api/index.html b/docs/category/api/index.html new file mode 100644 index 0000000000..c42a4a73f2 --- /dev/null +++ b/docs/category/api/index.html @@ -0,0 +1,24 @@ + + + + + +API | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/category/automated-pentesting/index.html b/docs/category/automated-pentesting/index.html new file mode 100644 index 0000000000..e5bf8fe6e7 --- /dev/null +++ b/docs/category/automated-pentesting/index.html @@ -0,0 +1,24 @@ + + + + + +Automated Pentesting | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/central-api/index.html b/docs/category/central-api/index.html new file mode 100644 index 0000000000..4c4acc909b --- /dev/null +++ b/docs/category/central-api/index.html @@ -0,0 +1,24 @@ + + + + + +Central API | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/cluster-stacks/index.html b/docs/category/cluster-stacks/index.html new file mode 100644 index 0000000000..db79ff71ef --- /dev/null +++ b/docs/category/cluster-stacks/index.html @@ -0,0 +1,24 @@ + + + + + +Cluster Stacks | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/components-1/index.html b/docs/category/components-1/index.html new file mode 100644 index 0000000000..d43b0ebd32 --- /dev/null +++ b/docs/category/components-1/index.html @@ -0,0 +1,24 @@ + + + + + +Components | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/components-2/index.html b/docs/category/components-2/index.html new file mode 100644 index 0000000000..448385d492 --- /dev/null +++ b/docs/category/components-2/index.html @@ -0,0 +1,24 @@ + + + + + +Components | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/components/index.html b/docs/category/components/index.html new file mode 100644 index 0000000000..2a56765f96 --- /dev/null +++ b/docs/category/components/index.html @@ -0,0 +1,24 @@ + + + + + +Components | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/concepts/index.html b/docs/category/concepts/index.html new file mode 100644 index 0000000000..c9861282ee --- /dev/null +++ b/docs/category/concepts/index.html @@ -0,0 +1,24 @@ + + + + + +Concepts | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/configuration/index.html b/docs/category/configuration/index.html new file mode 100644 index 0000000000..62938b5f8c --- /dev/null +++ b/docs/category/configuration/index.html @@ -0,0 +1,24 @@ + + + + + +Configuration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/container-registry/index.html b/docs/category/container-registry/index.html new file mode 100644 index 0000000000..1d64426fe0 --- /dev/null +++ b/docs/category/container-registry/index.html @@ -0,0 +1,24 @@ + + + + + +Container Registry | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/deployment-examples/index.html b/docs/category/deployment-examples/index.html new file mode 100644 index 0000000000..72bd9d2942 --- /dev/null +++ b/docs/category/deployment-examples/index.html @@ -0,0 +1,24 @@ + + + + + +Deployment Examples | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/deployment/index.html b/docs/category/deployment/index.html new file mode 100644 index 0000000000..40d56a04a6 --- /dev/null +++ b/docs/category/deployment/index.html @@ -0,0 +1,24 @@ + + + + + +Deployment | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/category/guides-1/index.html b/docs/category/guides-1/index.html new file mode 100644 index 0000000000..fad3b11404 --- /dev/null +++ b/docs/category/guides-1/index.html @@ -0,0 +1,24 @@ + + + + + +Guides | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/guides-2/index.html b/docs/category/guides-2/index.html new file mode 100644 index 0000000000..4bf6c2d2e8 --- /dev/null +++ b/docs/category/guides-2/index.html @@ -0,0 +1,24 @@ + + + + + +Guides | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/iaas-layer/index.html b/docs/category/iaas-layer/index.html new file mode 100644 index 0000000000..ff4b85b8b5 --- /dev/null +++ b/docs/category/iaas-layer/index.html @@ -0,0 +1,24 @@ + + + + + +IaaS Layer | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/metering/index.html b/docs/category/metering/index.html new file mode 100644 index 0000000000..4bd723050d --- /dev/null +++ b/docs/category/metering/index.html @@ -0,0 +1,24 @@ + + + + + +Metering | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/monitoring/index.html b/docs/category/monitoring/index.html new file mode 100644 index 0000000000..6350178c06 --- /dev/null +++ b/docs/category/monitoring/index.html @@ -0,0 +1,24 @@ + + + + + +Monitoring | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Monitoring

+ + \ No newline at end of file diff --git a/docs/category/operating-scs/index.html b/docs/category/operating-scs/index.html new file mode 100644 index 0000000000..12ce395707 --- /dev/null +++ b/docs/category/operating-scs/index.html @@ -0,0 +1,24 @@ + + + + + +Operating SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/pentesting-iaas/index.html b/docs/category/pentesting-iaas/index.html new file mode 100644 index 0000000000..02e731fc9f --- /dev/null +++ b/docs/category/pentesting-iaas/index.html @@ -0,0 +1,24 @@ + + + + + +Pentesting IaaS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/pentesting-kaas/index.html b/docs/category/pentesting-kaas/index.html new file mode 100644 index 0000000000..03dddb38d2 --- /dev/null +++ b/docs/category/pentesting-kaas/index.html @@ -0,0 +1,24 @@ + + + + + +Pentesting KaaS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/releases/index.html b/docs/category/releases/index.html new file mode 100644 index 0000000000..020145df44 --- /dev/null +++ b/docs/category/releases/index.html @@ -0,0 +1,24 @@ + + + + + +Releases | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/scs-health-monitor/index.html b/docs/category/scs-health-monitor/index.html new file mode 100644 index 0000000000..2621bc90c7 --- /dev/null +++ b/docs/category/scs-health-monitor/index.html @@ -0,0 +1,24 @@ + + + + + +SCS Health Monitor | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/status-page/index.html b/docs/category/status-page/index.html new file mode 100644 index 0000000000..1c1fb2a1a0 --- /dev/null +++ b/docs/category/status-page/index.html @@ -0,0 +1,24 @@ + + + + + +Status Page | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/turnkey-solution/index.html b/docs/category/turnkey-solution/index.html new file mode 100644 index 0000000000..adb397d792 --- /dev/null +++ b/docs/category/turnkey-solution/index.html @@ -0,0 +1,24 @@ + + + + + +Turnkey Solution | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/web/index.html b/docs/category/web/index.html new file mode 100644 index 0000000000..7e16b998c7 --- /dev/null +++ b/docs/category/web/index.html @@ -0,0 +1,24 @@ + + + + + +Web | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow/index.html new file mode 100644 index 0000000000..cf0d173ba0 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow/index.html @@ -0,0 +1,29 @@ + + + + + +Management Cluster flow | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Management Cluster flow

+

In a Cluster API management cluster, the Cluster API operators run. In our management cluster, there are also the Cluster Stack operators.

+

The user controls workload clusters via custom resources. As the Cluster Stack approach uses ClusterClasses, the user has to create only a Cluster object and refer to a ClusterClass.

+

However, in order for this to work, the ClusterClass has to be applied as well as all other Cluster API objects that are referenced by the ClusterClass, such as MachineTemplates, etc.

+

These Cluster API objects are packaged in a Helm Chart that is part of every cluster stack. The clusterstackrelease-controller is responsible for applying this Helm chart, which is done by first calling helm template and then the "apply" method of the Kubernetes go-client.

+

The main resource is always the ClusterClass that follows a very specific naming pattern and is called in the exact same way as the ClusterStackRelease object that manages it. For example, docker-ferrol-1-27-v1, which refers to all defining properties of a specific release of a cluster stack for a certain provider.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow/index.html new file mode 100644 index 0000000000..1866b7210e --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow/index.html @@ -0,0 +1,25 @@ + + + + + +Node image flow | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Node image flow

+

The node image flow depends on each provider. There are various ways in which providers allow the use of custom images. We have documented the options in the cluster stacks repo.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview/index.html new file mode 100644 index 0000000000..4e2c825e28 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview/index.html @@ -0,0 +1,60 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

Architecture

+

Cluster Stacks

+

Cluster stacks

+

The cluster stacks are opinionated templates of clusters in which all configuration and all core components are defined. They can be implemented on any provider.

+

There can be multiple cluster stacks that acknowledge the many ways in which a cluster can be set up. There is no right or wrong and cluster stacks make sure that the flexibility is not lost.

+

At the same time, they offer ready-made templates for users, who do not have to spend a lot of thought on how to build clusters so that everything works well together.

+

Cluster stacks are implemented by two Helm charts. The first one contains all Cluster API objects and is applied in the management cluster. The second Helm chart contains the cluster addons, i.e. the core components every cluster needs, and is installed in the workload clusters.

+

Furthermore, there are node images that can look quite different depending on the provider.

+

To sum up, there are three components of a cluster stack:

+
    +
  1. Cluster addons: The cluster addons (CNI, CSI, CCM) have to be applied in each workload cluster that the user starts
  2. +
  3. Cluster API objects: The ClusterClass object makes it easier to use Cluster-API. The cluster stack contains a ClusterClass object and other Cluster-API objects that are necessary in order to use the ClusterClass. These objects have to be applied in the management cluster.
  4. +
  5. Node images: Node images can be provided to the user in different form. They are released and tested together with the other two components of the cluster stack.
  6. +
+

More information about cluster stacks and their three parts can be found in https://github.com/SovereignCloudStack/cluster-stacks/blob/main/README.md.

+

Cluster Stack Operator

+

The Cluster Stack Operator takes care of all steps that have to be done in order to use a certain cluster stack implementation.

+

It has to be installed in the management cluster and can be interacted with by applying custom resources. It extends the functionality of the Cluster API operators.

+

The Cluster Stack Operator mainly applies the two Helm charts from a cluster stack implementation. It is also able to automatically fetch a remote Github repository to see whether there are new releases of a certain cluster stack.

+

The first and second component of a cluster stack are handled by the Cluster Stack Operator.

+

The node images, on the other hand, have to be handled by separate provider integrations, similar to the ones that Cluster-API uses.

+

Cluster Stack Provider Integrations

+

The Cluster Stack Operator is accompanied by Cluster Stack Provider Integrations. A provider integration is also an operator that works together with the Cluster Stack Operator in a specific way, which is described in the docs about building provider integrations.

+

A provider integration makes sure that the node images are taken care of and made available to the user.

+

If there is no work to be done for node images, then the Cluster Stack Operator can work in noProvider mode and this Cluster Stack Provider Integration can be omitted.

+

Steps to make cluster stacks ready to use

+

There are many steps that are needed in order to make cluster stacks ready to use. In order to understand the full flow better and to get an idea of how much work there is and how many personas are involved, we will give an overview of how to start from scratch with a new cluster stack and provider.

+

We will assume that this operator exists, but that you want to use a new cluster stack and provider.

+

Defining a cluster stack

+

First, you need to define your cluster stack. Which cluster addons do you need? How do your node images look like? You need to take these decisions and write them down.

+

Implementing a cluster stack

+

The next step is to implement your cluster stack for your provider. You can take existing implementations as reference, but need to think of how the provider-specific custom resources are called and how the respective Cluster API Provider Integration works.

+

Implementing a Cluster Stack Provider Integration

+

We assume that you need to do some manual tasks in order to make node images accessible on your provider. These steps should be implemented in a Cluster Stack Provider Integration, which of course has to work together with the details of how you implemented your cluster stack.

+

Using everything

+

Finally, you can use the new cluster stack you defined and implemented on the infrastructure of your provider. Enjoy!

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow/index.html new file mode 100644 index 0000000000..9a71ac8b26 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow/index.html @@ -0,0 +1,45 @@ + + + + + +Deep dive: User flow | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Deep dive: User flow

+

It is essential to understand the flow of what you have to do as a user and what happens in the background.

+

The Quickstart guide goes over all small steps you have to do to. If you are just interested in getting started, then have a look there.

+

In the following, we will not go into the detail of every command, but will focus more on a high-level of what you have to do and of what happens in the background.

+

Steps to create a workload cluster

+

Get the right cluster stacks

+

The first step would be to make sure that you have the cluster stacks implemented that you want to use. Usually, you will use cluster stacks that have been implemented by others for the provider that you want to use. However, you can also build your own cluster stacks.

+

Apply cluster stack resource

+

If you have everything available, you can start your management cluster / bootstrap cluster. In this cluster, you have to apply the ClusterStack custom resource with your individual desired configuration.

+

Depending on your configuration, you will have to wait until all steps are done in the background.

+

The operator will perform all necessary steps to provide you with node images. If all node images are ready, it will apply the Cluster API resources that are required.

+

At the end, you will have node images and Cluster API objects ready to use. There is only one step more to create a cluster.

+

Use the ClusterClasses

+

That the previous step is done, you can see in the status of the ClusterStack object. However, you can also just check if you have certain ClusterClass objects. The ClusterClass objects will be applied by the Cluster Stack Operator as well. They follow a certain naming pattern. If you have the cluster stack "ferrol" for the docker provider and Kubernetes version 1.27 in version "v1", then you'll see a ClusterClass that has the name "docker-ferrol-1-27-v1".

+

You can use this ClusterClass by referencing it in a Cluster object. For details, you can check out the official Cluster-API documentation.

+

Wait until cluster addons are ready

+

If you created a workload cluster by applying a Cluster object, the cluster addons will be applied automatically. You just have to wait until everything is ready, e.g. that the CCM or CNI are installed.

+

Recap - how do Cluster API and Cluster Stacks work together?

+

The user triggers the flow by configuring and applying a ClusterStack custom resource. This will trigger some work in the background, to make node images and Cluster API objects ready to use.

+

This process is completed, when a ClusterClass with a certain name is created. This ClusterClass resource is used in order to create as many clusters as you want that look like the template specified in the ClusterClass.

+

Upgrades of clusters are done by changing the reference to a new ClusterClass, e.g. from docker-ferrol-1-27-v1 to docker-ferrol-1-27-v2.

+

To sum up: The Cluster Stack Operator takes care of steps that you would otherwise have to do manually. It does not change anything in the normal Cluster API flow, expcept that it enforces the use of ClusterClasses.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow/index.html new file mode 100644 index 0000000000..8da83266c3 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow/index.html @@ -0,0 +1,37 @@ + + + + + +The workload cluster flow | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

The workload cluster flow

+

The workload cluster flow is implemented by two controllers and one custom resource.

+

The ClusterAddon resource gets created by the ClusterAddonCreate controller for any Cluster resource that is applied.

+

The user never interacts with the ClusterAddon resource as it is created, updated, and deleted automatically.

+

It is updated by the ClusterAddon controller, which makes sure that all cluster addons are applied in the respective workload cluster.

+

The controller follows a simple pattern. When a cluster is created, it waits until the cluster is ready. If that is the case, it applies all objects from the ClusterAddon Helm Chart.

+

If a cluster is updated, it checks whether there has been an update of the cluster addons and only if that's the case, it applies the objects again. It also deletes objects that have been there in the previous version but are not there anymore.

+

Applying the objects has one additional step: we take the idea of the cluster-api-addon-provider-helm and add a few details about the Cluster and the ProviderCluster in there (https://github.com/kubernetes-sigs/cluster-api-addon-provider-helm/blob/main/internal/value_substitutions.go).

+

This is necessary, because normal templating could not inject these values that are only available at runtime but that are very important to the resources that we apply as cluster addons.

+

As this controller relies on the release assets to be downloaded - as do other controllers that do not download anything themselves - there is one issue after a container restart that we have to solve:

+

If the container restarts, then everything that was stored in memory or without external volume in the container, will be lost. Therefore, a container restart requires to fetch from Github again.

+

This takes a bit of time, even if it is just one second. If a ClusterAddon reconciles within this one second, it willl realize though, that the desired file is not available yet. Instead of throwing an error, we can intelligently requeue again.

+

The same pattern is followed in all other controllers as well, if needed.

+

This controller also sets intelligent conditions into the status of the objects to make sure that the user can understand what is going on.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept/index.html new file mode 100644 index 0000000000..64c420235f --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept/index.html @@ -0,0 +1,49 @@ + + + + + +Understanding the concept of Cluster Stacks | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Understanding the concept of Cluster Stacks

+

The Cluster Stack framework was developed as one of the building blocks of an open-source Kubernetes-as-a-Service. The goal was to make it easier and more user-friendly to manage Kubernetes and Cluster API.

+

Cluster Stacks and Cluster API

+

Do Cluster Stacks replace Cluster API? No! Do Cluster Stacks use Cluster API internally? No! The Cluster Stack framework accompanies Cluster API, but is on the same level of the hierarchy. The Cluster Stack approach does not wrap Cluster API into something else, but adds a few tools next to it. The Cluster Stacks are meant to take over some tasks that are relevant to the user, but for which Cluster API has no opinion.

+

As a user of Cluster Stacks, you will see that you have an opinionated way of using Cluster API, for example by enforcing the use of ClusterClasses, but in the end, it is still vanilla Cluster API. However, instead of, for example, having to manage core cluster components, the so-called cluster addons, yourself, the cluster-stack-operator takes care of this.

+

By installing the required CRDs as well as the cluster-stack-operator next to the Cluster API CRDs and operators into the Cluster API management cluster, you can start using the Cluster Stacks!

+

To sum up: everything you know about Cluster API still applies when using the Cluster Stack Framework!

+

Why cluster stacks?

+

Cluster stacks solve multiple issues users face when using Cluster API. Here a selection of them:

+
    +
  • Cluster API assumes that node images are available. This might mean some manual work for the user, which is completely out of scope for Cluster API.
  • +
  • Cluster API does not have a stable solution to manage core cluster components that every workload cluster needs (cloud controller manager, container network interface, etc.). There is some work around so-called "add-on providers", but this is a very recent development.
  • +
  • Upgrading clusters is challenging, as there might be incompatibilites between the various components (configurations, applications, etc.). Many users don't regularly upgrade clusters because of that.
  • +
  • Cluster API has some downsides with regards to user experience, as there are many different objects that a user has to apply and manage.
  • +
+

The cluster stack approach tries to solve all of the above issues and tries to connect everything that users need in order to manage a fleet of Kubernetes clusters efficiently and easily.

+

At the same time, it acknowledges the ease of Cluster API and uses it as its core component. Instead of re-inventing the wheel, Cluster API is extended with relevant and meaningful additions that improve the user experience.

+

What do cluster stacks NOT try to do?

+

Cluster stacks concentrate on providing users with all necessary Cluster API objects in the management cluster, on providing node images (according to the demands of the respective provider), as well as core components of the workload clusters. The cluster stacks aim to provide a way of testing and versioning full templates of clusters.

+

However, they also aim to fulfill their purpose in a similar way of Cluster API by concentrating on one very important part and do that very well.

+

If there are any other use cases, e.g. installing applications automatically in workload clusters (an observability stack, GitOps tools, etc.), then this is a use case that is outside of the cluster stacks functionality.

+

They are not intended to incorporate all features that users might want, but they can easily go hand-in-hand with other tools that enhance Cluster API.

+

Integrating cluster stacks with other tools

+

The Cluster API cosmos is large and there are many tools around that can prove useful. Cluster stacks should be compatible with most of the other tools that you might want to use or build, as long as they follow the same pattern of using the declaritive approach of having custom resources that are reconciled by operators.

+

The cluster stacks can be used via custom resources and an operator reconciling them. Custom resources allow users to extend the Kubernetes API according to their needs.

+

If you want to add your own functionality, you can also define your CRDs and write operators to reconcile them. If you think that your idea is very generic and might be interesting for the community in general, then reach out to the SCS team. Together, we will be able to improve the user experience even further!

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/index.html new file mode 100644 index 0000000000..586c41e263 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/index.html @@ -0,0 +1,51 @@ + + + + + +Contributing | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Contributing

+

Develop Cluster Stack Operator

+

Developing our operator is quite easy. First, you need to install some base requirements: Docker and Go. Second, you need to configure your environment variables. Then you can start developing with the local Kind cluster and the Tilt UI to create a workload cluster that is already pre-configured.

+

Setting Tilt up

+
    +
  1. Install Docker and Go. We expect you to run on a Linux OS.
  2. +
  3. Create an .envrc file and specify the values you need. See the .envrc.sample for details.
  4. +
+

Developing with Tilt

+

Tilt

+

Operator development requires a lot of iteration, and the “build, tag, push, update deployment” workflow can be very tedious. Tilt makes this process much simpler by watching for updates and automatically building and deploying them. To build a kind cluster and to start Tilt, run:

+
make tilt-up
+
+

To access the Tilt UI please go to: http://localhost:10351

+
+

You should make sure that everything in the UI looks green. If not, e.g. if the clusterstack has not been synced, you can trigger the Tilt workflow again. In case of the clusterstack button this might be necessary, as it cannot be applied right after startup of the cluster and fails. Tilt unfortunately does not include a waiting period.

+

If everything is green, then you can already check for your clusterstack that has been deployed. You can use a tool like k9s to have a look at the management cluster and its custom resources.

+

Example:

+
❯ kubectl get clusterstacks -A
NAMESPACE NAME PROVIDER CLUSTERSTACK K8S CHANNEL AUTOSUBSCRIBE USABLE LATEST AGE REASON MESSAGE
cluster clusterstack docker ferrol 1.27 stable false v2 docker-ferrol-1-27-v2 | v1.27.3 4m52s
+
❯ kubectl get clusterstackreleases.clusterstack.x-k8s.io -A
NAMESPACE NAME K8S VERSION READY AGE REASON MESSAGE
cluster docker-ferrol-1-27-v2 v1.27.3 true 7m51s
+

The above cluster stack was downloaded from SovereignCloudStack/cluster-stacks

+

In case your clusterstack shows that it is ready, you can deploy a workload cluster. This could be done through the Tilt UI, by pressing the button in the top right corner "Create Workload Cluster". This triggers the make create-workload-cluster-docker, which uses the environment variables and the cluster-template.

+

In case you want to change some code, you can do so and see that Tilt triggers on save. It will update the container of the operator automatically.

+

If you want to change something in your ClusterStack or Cluster custom resources, you can have a look at .cluster.yaml and .clusterstack.yaml, which Tilt uses.

+

To tear down the workload cluster press the "Delete Workload Cluster" button. After a few minutes the resources should be deleted.

+

To tear down the kind cluster, use:

+
$ make delete-bootstrap-cluster
+

If you have any trouble finding the right command, then you can use make help to get a list of all available make targets.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration/index.html new file mode 100644 index 0000000000..6bed9e647e --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration/index.html @@ -0,0 +1,24 @@ + + + + + +provider-integration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing/index.html new file mode 100644 index 0000000000..6e1dbefb37 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing/index.html @@ -0,0 +1,59 @@ + + + + + +releasing | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

releasing

Release Process

+

This document describes the release process of cluster-stack-operator. +The release process is done using GitHub actions. The release workflow triggers when a tag is pushed starting with v*

+
+

[!NOTE] +Before the release, please make sure that you've already updated metadata.yaml at the root of the repo. So, if you're using v1.2.0 then you'll also need to update the releaseSeries block in metadata.yaml. The tag used for releasing should be compatible with what we have defined in metadata.yaml

+
+

Creating a new release of cluster-stack-operator covers the following steps:

+

Step 1: Create and Push a tag

+
    +
  1. Create an annotated tag
  2. +
+
git switch main
git pull --rebase
# check older releases for semver compatibility
export RELEASE_TAG=<the tag of the release to be cut> (e.g. v0.0.1)
git tag -a ${RELEASE_TAG} -m ${RELEASE_TAG}
+
    +
  1. Push the tag to GitHub repository
  2. +
+
+

[!NOTE]
+origin should be the name of the remote pointing to https://github.com/SovereignCloudStack/cluster-stack-operator and you should have permission to push tags to the repository.

+
+

Once you confirm that origin is correct then push the tag by invoking the following command:

+
git push origin ${RELEASE_TAG}
+

This will automatically trigger a Github workflow to create a draft release in GitHub.

+

Step 2: Release in GitHub

+
    +
  1. Review the draft release manually and check if the image tags are correct in the released manifest.
  2. +
  3. After this, if you're going to cut a pre-release version then please append this line to the top of the release notes.
  4. +
+
+

[!WARNING] +🚨 This is a RELEASE CANDIDATE. If you find any bugs, please file an issue.

+
+
    +
  1. Before publishing the images make sure that images are already there in GitHub container registry. This can be checked in the packages section of the organisation.
  2. +
  3. Publish the release.
  4. +
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack/index.html new file mode 100644 index 0000000000..babc64661a --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack/index.html @@ -0,0 +1,35 @@ + + + + + +clusterstack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

clusterstack

ClusterStack

+

The ClusterStack object is the main resource for users to work with. It contains the most important details of a cluster stack and its releases (i.e. certain versions). In its status is the main source of information of the state of everything related to cluster stacks.

+

Lifecycle of a ClusterStack

+

The ClusterStack object has a sub-resource ClusterStackRelease for every release that should be provided to the user, either by specifying them manually in the versions array, or automatically through the auto-subscribe functionality.

+

The controller reconciles the two sources of information and checks whether for every release that should exist, there is actually one. It also deletes ClusterStackRelease objects that are not required anymore.

+

Additionally, it fetches information from the ClusterStackRelease objects and populates its own state with it.

+

In case that a provider integration is used, it will create ProviderClusterStackRelease objects in addition to ClusterStackRelease objects, based on the ProviderClusterStackReleaseTemplate objects given as reference in spec.providerRef.

+

Overview of ClusterStack.Spec

+
KeyTypeDefaultRequiredDescription
providerstringyesName of the provider, e.g. "docker". It is used in various places, e.g. while fetching the respective release assets or while naming resources (ClusterStackReleases, ProviderClusterStackResources, etc.).
namestringyesName of the cluster stack. It is used as well for fetching release assets and other tasks.
kubernetesVersionstringyesKubernetes version in the format <majorVersion>.<minorVersion>, e.g. 1.26. Specifies the Kubernetes minor version of the cluster stack that should be taken.
channelstringstablenoName of release channel that is used, e.g. stable channel ("v1", "v2", etc.) or beta channel (e.g. "v0-beta.1").
versions[]stringnoList of versions that the controller should make available of a cluster stack. Used only in case very specific versions are supposed to be used. Not required if always the latest versions should be made available.
autoSubscribebooltruenoSpecifies whether the controller should automatically check whether there are new releases of the cluster stack and if so automatically download them.
noProviderboolfalsenoIf set to true, the controller does not expect any provider-specific objects and just focuses on applying Cluster API objects in management cluster and cluster addons in all workload clusters.
providerRefobjectnoProviderRef has to be specified if spec.noProvider is false. It references the ProviderClusterStackReleaseTemplate that contains all information to create the ProviderClusterStackRelease objects.
+

Example of the ClusterStack object

+

You should create one of these objects for each of your bare metal servers that you want to use for your deployment.

+
apiVersion: clusterstack.x-k8s.io/v1alpha1
kind: ClusterStack
metadata:
name: clusterstack
namespace: cluster
spec:
provider: docker
name: ferrol
kubernetesVersion: "1.27"
channel: stable
autoSubscribe: true
noProvider: true
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology/index.html new file mode 100644 index 0000000000..ddb53759a1 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology/index.html @@ -0,0 +1,41 @@ + + + + + +Terminology | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Terminology

+

The Cluster Stacks are a framework and provide tools how to use them. The terminology is not perfect and if you have an idea how to improve it, please reach out. Right now there are the following terms:

+

Cluster Stack framework

+

The framework of cluster stacks refers to the fact that cluster stacks of any shape can be created for any provider that supports Cluster API. The framework has no opinion about how the Cluster Stacks have to look like, which configuration of node images and Kubernetes you use and which cluster addons you include.

+

As long as a cluster stack is implemented and released in a correct way, the cluster-stack-operator will be able to use it, fully independent of the detailed architectural decisions that were taken with regards to how the clusters that come out of this cluster stack should look like.

+

This flexibility is meant by the term "framework".

+

A definition of a cluster stack

+

A definition of a cluster stack is a document describing, independent of any provider, how a cluster stack xyz should look like. On a very high level, this could be something like "we want to use Ubuntu node images, basic Kubeadm and Cilium as CNI".

+

There is no template for such a definition and no pre-defined structure how such a definition should look like.

+

A definition of a cluster stack xyz can be used as a base to implement this cluster stack xyz for providers a and b.

+

An implementation of a cluster Stack

+

A cluster stack can be implemented for a certain provider. The collection of configuration code, Helm charts, etc. is what we call an implementation of a cluster stack. The release assets that have to be generated from that is what people actually use, usually with the Cluster Stack Operator.

+

Cluster Stack Operator

+

A Kubernetes operator that works with the release assets and applies resources in management and each workload cluster. It works together with Provider Integrations, if they are needed.

+

Cluster Stack Provider Integration

+

Provider integrations are needed if a user has to do manual steps on a provider to use custom node images for the nodes in a cluster. If no such steps are required, then the provider integration is not needed.

+

ClusterStack as custom resource definition

+

The ClusterStack is a CRD that the user interacts with directly. It shows in its status the state of the respective versions of this cluster stack that the user wants to have.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks/index.html new file mode 100644 index 0000000000..a4fae89d16 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks/index.html @@ -0,0 +1,28 @@ + + + + + +Managing ClusterStack objects | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Managing ClusterStack objects

+

The ClusterStack object is the central resource that you have to work with. You have to specify a provider, the name of the cluster stack you want to use, as well as the Kubernetes minor version.

+

If you want to use multiple different Kubernetes minor versions, you will have to create multiple ClusterStack objects. The same goes for multiple providers, or multiple cluster stacks (e.g. ferrol) that might have different features.

+

In order to use a cluster stack in a specific version, you have two options: first, you can specify a list of versions in spec.versions. Second, you can enable autoSubscribe, so that the operator will automatically check for the latest version and make it available to you.

+

Usually, you will always want to use auto-subscribe, so that the operator takes care of providing you with the latest versions.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart/index.html new file mode 100644 index 0000000000..b880d66747 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart/index.html @@ -0,0 +1,69 @@ + + + + + +Getting Started | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Getting Started

+

Quickstart

+

Currently, there is a demo that can be used to see how the Cluster Stack approach can work. It uses the Docker Provider Integration for Cluster API.

+

Installation

+

Prerequisites

+
- clusterctl
- envsubst
- kubectl
- Helm (optional)
+

Cluster API

+

We assume access to a Kubernetes cluster. To start +kind can be used for that. +This Kubernetes cluster must act as Cluster API management cluster. +If not already done, to make your Kubernetes cluster a management cluster by +installing the Cluster API objects, you can do

+
clusterctl init
+

Configure Release Source

+

The Cluster Stack Operator downloads Cluster Stack releases either from GitHub +Releases or from an OCI registry. +Depending on which method is preferred, environment variables must be set to +give the Cluster Stack Operator access to the specific source.

+

Using GitHub Releases

+
+

Be aware that GitHub enforces limitations on the number of API requests per +unit of time. To overcome this, it is recommended to configure a personal +access token for +authenticated calls. This will significantly increase the rate limit for GitHub +API requests. Fine grained PAT with Public Repositories (read-only) is +enough.

+
+

Following variables tells the Cluster Stack Operator to look for releases in +https://github.com/SovereignCloudStack/cluster-stacks

+
export GIT_PROVIDER_B64=Z2l0aHVi  # github
export GIT_ORG_NAME_B64=U292ZXJlaWduQ2xvdWRTdGFjaw== # SovereignCloudStack
export GIT_REPOSITORY_NAME_B64=Y2x1c3Rlci1zdGFja3M= # cluster-stacks
export GIT_ACCESS_TOKEN_B64=$(echo -n '<my-personal-access-token>' | base64 -w0)
+

Using OCI Registry

+

Following variables tells the Cluster Stack Operator to look for releases in +https://registry.scs.community/kaas/cluster-stacks

+
export OCI_REGISTRY_B64=cmVnaXN0cnkuc2NzLmNvbW11bml0eQ== # registry.scs.community
export OCI_REPOSITORY_B64=cmVnaXN0cnkuc2NzLmNvbW11bml0eS9rYWFzL2NsdXN0ZXItc3RhY2tzCg== # registry.scs.community/kaas/cluster-stacks
+

If the registry is not public the Cluster Stack Operator please also provide +OCI_USERNAME_B64 and OCI_PASSWORD_B64 or +OCI_ACCESS_TOKEN_B64

+

Install Cluster Stack Operator

+

Install by manifest

+
# Get the latest CSO release version and apply CSO manifests
curl -sSL https://github.com/SovereignCloudStack/cluster-stack-operator/releases/latest/download/cso-infrastructure-components.yaml | envsubst | kubectl apply -f -
+
Enable OCI registry as source
+

Since GitHub is set as default source for the Cluster Stack releases, this can be changed with a patch:

+
kubectl patch deployment -n cso-system cso-controller-manager --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/command", "value": ["/manager", "-source", "oci"]}]'
+

Install with Helm (experimental)

+

There are simple Helm charts available which were created especially to make the switch between the sources easier.

+
helm upgrade -i cso -n cso-system \
--create-namespace oci://registry.scs.community/cluster-stacks/cso \
--set controllerManager.manager.source=oci \
--set clusterStackVariables.ociRepository=registry.scs.community/kaas/cluster-stacks
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot/index.html new file mode 100644 index 0000000000..53e2c73ddb --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot/index.html @@ -0,0 +1,32 @@ + + + + + +Troubleshooting | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Troubleshooting

+

Check the latest events:

+
kubectl get events -A  --sort-by=.lastTimestamp
+

Check the conditions:

+
go run github.com/guettli/check-conditions@latest all
+

Check with clusterctl:

+
clusterctl describe cluster -n cluster my-cluster
+

Check the logs. List all logs from all deployments. Show the logs of the last ten minutes:

+
kubectl get deployment -A --no-headers | while read -r ns d _; do echo; echo "====== $ns $d"; kubectl logs --since=10m -n $ns deployment/$d; done
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow/index.html new file mode 100644 index 0000000000..5b21f5fc2c --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow/index.html @@ -0,0 +1,32 @@ + + + + + +Upgrade flow | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Upgrade flow

+

This flow assumes that you have an existing cluster that references a certain ClusterClass called docker-ferrol-1-27-v1.

+

There are two forms of updates: "normal" cluster stack updates, where you would update the above ClusterClass to docker-ferrol-1-27-v2, and updates of the Kubernetes minor version, e.g. docker-ferrol-1-28-v1.

+

In both cases, you need to make sure that you have the respective ClusterClass available. This works a bit different in the two cases, as you will need a new ClusterStack object in the latter case that works with Kubernetes minor version 1.28. This is one of the properties of a ClusterStack that you specify in the spec.

+

After you made sure that you have the ClusterClass ready to which you want to upgrade, you can edit your Cluster object according to the following pattern:

+

Update spec.topology.class to the name of the new ClusterClass and change spec.topology.version to the respective Kubernetes version. This can be, for example, "1.28.1". You have to find out the right Kubernetes version for the respective cluster stack.

+

You can either do this by checking the status of the ClusterStack object, or by fetching the ClusterStackRelease objects. You will find a ClusterStackRelease object that has the same name as your desired ClusterClass. This object has a property status.kubernetesVersion that shows you the version that you need to specify.

+

Another option is to check the documentation of the cluster stack to find information about the respective releases.

+

Please note that spec.topology.version does not have to be specified if a mutating webhook fills the property automatically for you. Check out the latest release notes of the operator to verify whether that is implemented already.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks/index.html new file mode 100644 index 0000000000..f92402d677 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks/index.html @@ -0,0 +1,74 @@ + + + + + +using-local-clusterstacks | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

using-local-clusterstacks

This is a quickstart guide on using the local clusterstacks.

+

Requirements:

+
    +
  • docker
  • +
  • kind
  • +
  • make
  • +
+

Introduction

+

Our controller interacts with cluster-stacks and they are stored inside GitHub releases when used in production. While this is the ideal combination to run our controller it's not a great experience when we want to develop or test new cluster-stacks. +To avoid this problem, we introduced local_mode and in this mode we start our controller by passing some flags and instead of using remote cluster-stacks, we put them inside a directory locally. +This way developers working on developing new cluster-stacks get a more better experience developing cluster-stacks and iterating fast on the same.

+

using right flags

+

Cluster stacks in local_mode do not fetch release assets directly from GitHub and to work with that we first need to download that and use the correct flags when we start the container. +The flags we are using in this repo is following:

+
  args:
- --leader-elect=true
- --release-dir=/tmp
- --local=true
+

What this means is that, the controller will look for release assets under /tmp directory inside the contanier. If the controller doesn't find release asset under /tmp directory then you can get an error in the status of clusterstackrelease object.

+

getting release assets

+

There are several ways to get release assets. Two common ways:

+
    +
  • From a Github release
  • +
  • From a directory created by csmctl
  • +
+

Overall it does not matter who you received the directory.

+

Tilt expects the release assets under .release directory of the repository.

+

getting release assets: From Github

+

To download a release asset from Github use the following commands.

+
mkdir -p .release/docker-ferrol-1-27-v2
cd .release/docker-ferrol-1-27-v2
gh release download -R sovereigncloudstack/cluster-stacks docker-ferrol-1-27-v2
+

You can also fetch the release asset manually. Using gh makes it a little bit easier to download all the release asset just by invoking one command.

+

Your local .release directory should have the following structure.

+
$ tree .release/
.release/
└── docker-ferrol-1-27-v2
├── cluster-addon-values.yaml
├── docker-ferrol-1-27-cluster-addon-v2.tgz
├── docker-ferrol-1-27-cluster-class-v2.tgz
├── metadata.yaml
├── node-images.yaml
└── topology-docker.yaml

2 directories, 6 files
+

NOTE: This directory structure is very important and you should have the same in order for the controller to work and sync.

+

getting release assets: From csmctl

+

If you use csmctl, then it creates the required directory under release.

+

Example:

+
❯ csmctl create tests/cluster-stacks/docker/ferrol -m hash
Created releases/docker-ferrol-1-27-v0-sha-7ff9188
+

Copy this directory to .release:

+
cp -a releases/docker-ferrol-1-27-v0-sha-7ff9188 ../cluster-stack-operator/.release
+

using local mode (toggling local mode)

+

From a user perspective who is using tilt to develop and test local cluster-stacks, we just have to make one change in Tiltfile and restart the complete setup all over again.

+

For making changes in tilt environment, we use tilt-settings.yaml file. If you don't have it then please copy it from tilt-settings.yaml.example which is at the root of the repo using the following command.

+
cp tilt-settings.yaml.example tilt-settings.yaml
+

Now, since you have your tilt-settings.yaml ready, you have to edit local_mode and make it to true +Your tilt-settings.yaml file should look following:

+
allowed_contexts:
- kind-cso
local_mode: false
# truncated
+

Once you're toggled local_mode to true, you're ready to start your tilt setup. Use the following command to start it.

+
make tilt-up
+

Once the setup is ready and you've the cluster-stack-operator pod running, you can exec into the container and check the /tmp directory for the presence of cluster-stacks.

+

Troubleshooting

+
$ kubectl -n cso-system exec -it cso-controller-manager-5bdc445647-j4p9p -- sh
/ # tree /tmp/
/tmp/
└── cluster-stacks
└── docker-ferrol-1-27-v2
├── cluster-addon-values.yaml
├── docker-ferrol-1-27-cluster-addon-v2.tgz
├── docker-ferrol-1-27-cluster-class-v2.tgz
├── metadata.yaml
├── node-images.yaml
└── topology-docker.yaml

2 directories, 6 files
+

You can now click on + button on the right hand side of tilt UI to create a workload cluster. Once the cluster is created you can check the status of the components via the following commands.

+
 $ kubectl get clusterstack -A
NAMESPACE NAME PROVIDER CLUSTERSTACK K8S CHANNEL AUTOSUBSCRIBE USABLE LATEST AGE REASON MESSAGE
cluster clusterstack docker ferrol 1.27 stable false v2 docker-ferrol-1-27-v2 | v1.27.3 5m16s

$ kubectl get clusterstackreleases.clusterstack.x-k8s.io -A
NAMESPACE NAME K8S VERSION READY AGE REASON MESSAGE
cluster docker-ferrol-1-27-v2 v1.27.3 true 5m16s

$ kubectl get clusters -A
NAMESPACE NAME CLUSTERCLASS PHASE AGE VERSION
cluster test-dfkhje docker-ferrol-1-27-v2 Provisioned 2m46s v1.27.3
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers/index.html new file mode 100644 index 0000000000..e66ce936ce --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers/index.html @@ -0,0 +1,42 @@ + + + + + +Controllers | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Controllers

+

OpenStackClusterStackRelease controller

+

The OpenStackClusterStackRelease controller’s main responsibilities are:

+
    +
  • Download release assets into the CSPO container
  • +
  • Create OpenStackNodeImageRelease resources based on the required NodeImages defined in the downloaded release asset node-images.yaml
  • +
  • Set an OwnerReference on the existing OpenStackNodeImageRelease resources that could be utilized by the ClusterStack release (multiple versions of one ClusterStack could share an image)
  • +
  • Update the OpenStackClusterStackRelease status to ready once all related OpenStackNodeImageReleases are also ready
  • +
+

OSCSR controller

+

OpenStackNodeImageRelease controller

+

The OpenStackNodeImageRelease controller’s main responsibilities are:

+
    +
  • Load the OpenStack Cloud configuration from the Secret referenced in spec.IdentityRef
  • +
  • Create an Image as defined by spec.Image if it does not already exist in the specified OpenStack project
  • +
  • Instruct the OpenStack Glance service to import an Image from the provided URL
  • +
  • Set the OpenStackNodeImageRelease status to ready once the image achieves an Active status
  • +
+

OSNIR controller

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop/index.html new file mode 100644 index 0000000000..6e424e0ea4 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop/index.html @@ -0,0 +1,82 @@ + + + + + +Developer Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Developer Guide

+

Developing Cluster Stack Provider OpenStack operator is quite straightforward. First, you need to install some basic prerequisites:

+
    +
  • Docker
  • +
  • Go
  • +
+

Next, configure your environment variables. Once that's done, you can initiate development using the local Kind cluster and the Tilt UI to create a workload cluster that comes pre-configured.

+

Setting Tilt up

+
    +
  1. Install Docker and Go. We expect you to run on a Linux OS.
  2. +
  3. Create an .envrc file and specify the values you need. See the .envrc.sample for details.
  4. +
+

Developing with Tilt

+

tilt

+

Operator development requires a lot of iteration, and the “build, tag, push, update deployment” workflow can be very tedious. Tilt makes this process much simpler by watching for updates and automatically building and deploying them. To build a kind cluster and to start Tilt, run:

+
make tilt-up
+
+

To access the Tilt UI please go to: http://localhost:10351

+
+

You should make sure that everything in the UI looks green. If not, you can trigger the Tilt workflow again.

+

Applying ClusterStack

+

When you start your tilt setup then the ClusterStack manifest gets copied from config/cspo directory to root of your repository. In order to apply the ClusterStack to the running local development cluster, you can click on the tilt UI. There should a click on the top-right hand side that is named as apply-clusterstack if you hover over it. +Once the ClusterStack is applied wait for the ClusterStack and ClusterStackRelease object to be ready. In case your ClusterStack shows that it is ready, you can deploy a workload cluster.

+

Creating workload cluster

+

This could be done through the Tilt UI, by pressing the button in the top right corner Create Workload Cluster. This triggers the make create-workload-cluster-openstack, which uses the environment variables and the cluster-template.

+

To interact with your freshly created workload cluster, you can use these commands:

+
make get-kubeconfig-workload-cluster #KUBECONFIG for the workload cluster is placed here: ".workload-cluster-kubeconfig.yaml"
export KUBECONFIG=$PWD/.workload-cluster-kubeconfig.yaml
+

In case you want to change some code, you can do so and see that Tilt triggers on save. It will update the container of the operator automatically.

+

If you want to change something in your ClusterStack or Cluster custom resources, you can have a look at .cluster.yaml and .clusterstack.yaml, which Tilt uses.

+

To delete the ClusterStack you can click on the delete-clusterstack button in the tilt UI.

+

To tear down the workload cluster, click on the Delete Workload Cluster button in the top right corner of the Tilt UI. This action triggers the execution of make delete-workload-cluster-openstack. After a few minutes, the resources should be successfully deleted.

+

To tear down the kind cluster, use:

+
make delete-bootstrap-cluster
+

If you have any trouble finding the right command, then you can use make help to get a list of all available make targets.

+

Toggle between local_mode and remote mode

+

We can retrieve cluster-stacks in two modes. One way is to let the controller fetch it from repository which is remote mode and other is we mount the cluster-stacks inside the container at /tmp/downloads/cluster-stacks directory.

+
+

[!NOTE]
+Using remote mode is the default behavior.

+
+

Switching between both modes is relatively simple if you're using Tilt. There is a file at the root of the repo tilt-settings.yaml.example +Make a copy of that file with the name of tilt-settings.yaml

+
cp tilt-settings.yaml.example tilt-settings.yaml
+

Now, open the file and set the local_mode to true to use cluster-stacks in local_mode. It should look the following content wise.

+
local_mode: true
+
+

[!NOTE] +In this mode you need to have cluster-stacks present locally.

+
+

Downloading cluster-stacks can be achieved by many ways but below is a simple way to download it quickly.

+
mkdir -p .release/openstack-scs-1-27-v1/
cd .release/openstack-scs-1-27-v1
gh release download --repo SovereignCloudStack/cluster-stacks openstack-scs-1-27-v1
+

Change the repo and tag as per the requirement. You can also download it directly from browser and move it to .release directory.

+

Please make sure the directory structure remains the same otherwise you'll not be able to start the tilt setup. Here's an example of structuring openstack-scs-1-27-v1 cluster-stack.

+
$ tree .release/openstack-scs-1-27-v1/
.release/openstack-scs-1-27-v1/
├── clusterstack.yaml
├── metadata.yaml
└── openstack-scs-1-27-cluster-class-v1.tgz
+
+

[!IMPORTANT] +There's an alternative way to get clusterstacks using csctl. You can follow the README of csctl for specific instructions and a good quickstart.

+
+

You can use csctl create subcommand to create clusterstack locally. You'll need a csctl.yaml file in the cluster-stack configuration directory. Please read more about creating configuration file for csctl in the csctl docs.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview/index.html new file mode 100644 index 0000000000..9aaabb7317 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview/index.html @@ -0,0 +1,27 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

The Cluster Stack Provider OpenStack (CSPO) works with the Cluster Stack Operator (CSO) and Cluster Stacks, enabling the creation of Kubernetes clusters in a Cluster-API-native (CAPI) fashion.

+

The primary goal of the CSPO is to facilitate the import of node images in a manner specific to OpenStack. These images are then used to create Kubernetes workload clusters on top of the OpenStack infrastructure.

+

To gain a comprehensive understanding of the entire concept, we recommend familiarizing yourself with the fundamental concepts and architecture outlined in CSO and Cluster Stacks.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart/index.html new file mode 100644 index 0000000000..9ab48c7e17 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart/index.html @@ -0,0 +1,26 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting/index.html new file mode 100644 index 0000000000..843305198d --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting/index.html @@ -0,0 +1,30 @@ + + + + + +Troubleshooting | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Troubleshooting

+

This guide explains general info on how to debug issues if a cluster creation fails.

+

providerClient authentication err

+

If you are using https, and when you encounter issues like:

+
kubectl logs -n cspo-system -l control-plane=controller-manager
...
[manager] 2024-04-15T15:20:07Z DEBUG events Post "https://10.0.3.15/identity/v3/auth/tokens": tls: failed to verify certificate: x509: certificate signed by unknown authority {"type": "Warning", "object": {"kind":"OpenStackNodeImageRelease","namespace":"cluster","name":"openstack-ferrol-1-27-ubuntu-capi-image-v1.27.8-v2","uid":"93d2c1c8-5a19-45f8-9f93-8e8bd5227ebf","apiVersion":"infrastructure.clusterstack.x-k8s.io/v1alpha1","resourceVersion":"3773"}, "reason": "OpenStackProviderClientNotSet"}
...
+

you must specify the CA certificate in your secret, which contains the access data to the OpenStack instance, then secret should look similar to this example:

+
apiVersion: v1
data:
cacert: <PEM_ENCODED_CA_CERT>
clouds.yaml: <ENCODED_CLOUDS_YAML>
kind: Secret
metadata:
labels:
clusterctl.cluster.x-k8s.io/move: "true"
name: "openstack"
namespace: cluster
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration/index.html b/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration/index.html new file mode 100644 index 0000000000..e172bd2762 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration/index.html @@ -0,0 +1,143 @@ + + + + + +Continuous integration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Continuous integration

+

Project cluster-stacks use the SCS Zuul CI platform to +drive its continuous integration tests. The project is registered under the SCS tenant +and therefore is able to use a set of pre-defined pipelines, jobs, and ansible roles that the +SCS Zuul instance defines and imports. If you want to explore currently available SCS pipelines, +visit the SCS zuul-config project. +If you want to see the full list of jobs that are available, visit the SCS Zuul UI. +And if you are looking for some handy ansible role that SCS Zuul imports, visit the source.

+

Refer to the SCS Zuul users guide and/or +Zuul docs for further details on how to define and use Zuul +CI/CD pipelines and jobs.

+
+

[!NOTE] +If you are interested in the Zuul CI platform and want to deploy your own development instance of it, +then read the official quick-start manual +or visit this tutorial which aims a connect +of Zuul CI platform with a GitHub organization.

+
+

Configuration

+

SCS Zuul automatically recognizes .zuul.yaml configuration file that is located in the +cluster-stacks's root. This file informs Zuul about the project's default-branch and +preferred merge-mode. +It also references SCS Zuul pipelines and +their jobs used by the cluster-stacks project. Then, jobs link Ansible playbooks that contain +tasks for actual CI testing.

+

See relevant CI configuration files:

+
├── .zuul.yaml
├── playbooks
│ ├── dependencies.yaml
│ ├── openstack
│ │ ├── e2e.yaml
│ │ ├── templates
│ │ │ ├── mgmt-cluster-config.yaml.j2
│ │ │ ├── cluster.yaml.j2
│ │ │ └── cluster-stack-template.yaml.j2
+

Pipelines

+

This section describes an SCS Zuul pipelines that are used by the cluster-stacks project.

+
    +
  • +

    e2e-test

    +
      +
    • It is triggered by the e2e-test label in the opened PR
    • +
    • It executes e2e-openstack-conformance job
    • +
    • It applies the PR label successful-e2e-test and leaves an informative PR comment when the e2e-openstack-conformance job succeeded
    • +
    • It applies the PR label failed-e2e-test and leaves an informative PR comment when the e2e-openstack-conformance job failed
    • +
    • It applies the PR label cancelled-e2e-test and leaves an informative PR comment when the e2e-openstack-conformance job is canceled
    • +
    +
  • +
  • +

    unlabel-on-update-e2e-test

    +
      +
    • It is triggered by the PR update only when PR contains the successful-e2e-test label
    • +
    • It ensures that any PR update invalidates a previous successful e2e test
    • +
    • It removes successful-e2e-test label from the PR
    • +
    +
  • +
  • +

    e2e-quick-test

    +
      +
    • It is triggered by the e2e-quick-test label in the opened PR
    • +
    • It executes e2e-openstack-quick job
    • +
    • It applies the PR label successful-e2e-quick-test and leaves an informative PR comment when the e2e-openstack-quick job succeeded
    • +
    • It applies the PR label failed-e2e-quick-test and leaves an informative PR comment when the e2e-openstack-quick job failed
    • +
    • It applies the PR label cancelled-e2e-quick-test and leaves an informative PR comment when the e2e-openstack-quick job is canceled
    • +
    +
  • +
  • +

    unlabel-on-update-e2e-quick-test

    +
      +
    • It is triggered by the PR update only when PR contains the successful-e2e-quick-test label
    • +
    • It ensures that any PR update invalidates a previous successful e2e test
    • +
    • It removes successful-e2e-quick-test label from the PR
    • +
    +
  • +
+

Jobs

+

This section describes Zuul jobs defined within the cluster-stacks project and linked in the above pipelines.

+
    +
  • +

    e2e-openstack-conformance

    +
      +
    • It runs a sonobuoy conformance test against Kubernetes cluster spawned by a specific cluster-stack
    • +
    • This job is a child job of openstack-access-base that ensures OpenStack credentials +availability in Zuul worker node. Parent job also defines a Zuul semaphore semaphore-openstack-access, +that ensures that a maximum of three openstack-access-base jobs (or their children) can run at a time
    • +
    • See a high level e2e-openstack-conformance job steps: +
        +
      • Pre-run playbook dependencies.yaml installs project prerequisites, e.g. clusterctl, KinD, csctl, etc.
      • +
      • Main playbook e2e.yaml spawns a k8s workload cluster using a specific cluster-stack in OpenStack, runs sonobuoy conformance test, SCS compliance test, and cleans created k8s workload cluster
      • +
      +
    • +
    +
  • +
  • +

    e2e-openstack-quick

    +
      +
    • It runs a sonobuoy quick test against Kubernetes cluster spawned by a specific cluster-stack
    • +
    • This job is a child job of openstack-access-base that ensures OpenStack credentials +availability in Zuul worker node. Parent job also defines a Zuul semaphore semaphore-openstack-access, +that ensures that a maximum of three openstack-access-base jobs (or their children) can run at a time
    • +
    • See a high level e2e-openstack-quick job steps: +
        +
      • Pre-run playbook dependencies.yaml installs project prerequisites, e.g. clusterctl, KinD, csctl, etc.
      • +
      • Main playbook e2e.yaml spawns a k8s workload cluster using a specific cluster-stack in OpenStack, runs sonobuoy quick test, SCS compliance test, and cleans created k8s workload cluster
      • +
      +
    • +
    +
  • +
+

Secrets

+

The parent job openstack-access-base, from which e2e jobs inherit, defines the secret variable openstack-application-credential. +This secret is stored directly in the SCS/zuul-config repository in an encrypted form. It contains OpenStack application credentials to access the OpenStack project dedicated to CI testing.

+

This secret is encrypted by the SCS/zuul-config repository RSA key that has been generated by SCS Zuul instance. +So only SCS Zuul instance is able to decrypt it (read the docs).

+

If you want to re-generate the mentioned secret or add another one using SCS/zuul-config repository RSA key, follow the below instructions:

+
    +
  • Install zuul-client
  • +
+
pip install zuul-client
+
    +
  • Encrypt "super-secret" string by the SCS/zuul-config repository public key from SCS Zuul
  • +
+
echo -n "super-secret" | \
zuul-client --zuul-url https://zuul.scs.community encrypt \
--tenant SCS \
--project github.com/SovereignCloudStack/zuul-config
+

Job customization

+

In a pull request (PR), you may want to run the end-to-end (e2e) test against the specific cluster-stack you are changing or adding, without modifying the cluster_stack variable in the e2e.yaml file in the repository.

+

To achieve this, include the following text in the body of the PR:

+
    ```ZUUL_CONFIG
cluster_stack = "openstack-alpha-1-29"
+

> [!NOTE]
> Please note that only cluster-stacks for OpenStack are currently supported.

### FAQ

#### How do developers/reviewers should proceed if they want to CI test this project?

A developer initiates a PR as usual. If a reviewer deems that the PR requires e2e testing, they can apply a specific label to the PR. Currently, the following labels could be applied:

- `e2e-test` (for comprehensive end-to-end (e2e) testing, including Kubernetes (k8s) workload cluster creation, execution of Sonobuoy conformance and SCS compliance tests, and cluster deletion.)
- `e2e-quick-test` (for comprehensive end-to-end (e2e) testing, including Kubernetes (k8s) workload cluster creation, execution of Sonobuoy quick and SCS compliance tests, and cluster deletion.)

After the e2e test has completed, the reviewer can examine the test results and respond accordingly, such as approving the PR if everything appears to be in order or requesting changes. Sonobuoy test results, along with a link to the e2e logs, are conveyed back to the PR via a comment. Additionally, the PR is labeled appropriately based on the overall e2e test results, using labels like
`successful-e2e-test`, `successful-e2e-quick-test`, `failed-e2e-test`, or `failed-e2e-quick-test`.

#### Why do we use PR `label` as an e2e pipeline trigger instead of e.g. PR `comment`?

We consider PR labels to be a more secure pipeline trigger compared to, for example, PR comments.
PR labels can only be applied by developers with [triage](https://docs.github.com/en/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization#permissions-for-each-role) repository access or higher.
In contrast, PR comments can be added by anyone with a GitHub account.

Members of the SCS GitHub organization are automatically granted 'write' access to SCS repositories. Consequently, the PR label mechanism ensures that only SCS organization members can trigger e2e pipelines.

#### How do we ensure that any PR update invalidates a previous successful e2e test?

In fact, two mechanisms ensure the invalidation of a previously successful test when a PR is updated.

Firstly, the pipelines `unlabel-on-update-<e2e-test-name>` remove the `successful-<e2e-test-name>` label
from the PR when it's updated after a successful e2e test has finished. If an e2e test is in progress and the PR is updated, the currently running e2e test is canceled, the `successful-<e2e-test-name>` label is removed (if it exists), and the `cancelled-<e2e-test-name>` label is applied along with an informative PR comment to inform the reviewer about the situation.
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stacks/overview/index.html b/docs/container/components/cluster-stacks/components/cluster-stacks/overview/index.html new file mode 100644 index 0000000000..5b972a87da --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stacks/overview/index.html @@ -0,0 +1,101 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

Cluster Stacks

+

Cluster Stacks is a comprehensive framework and reference implementations for defining and managing Kubernetes clusters via the Cluster API. It is designed to cater to multiple providers and supports a broad range of Kubernetes versions, offering a standardized approach to managing and configuring Kubernetes clusters.

+

It encapsulates multiple layers, including node configuration, Cluster API setup, and application-level configurations, such as the Container Network Interface (CNI). By packaging these interdependent configurations, the cluster stack allows for efficient management and deployment of Kubernetes clusters, offering standardized, resilient, and self-managed Kubernetes environments.

+

🔧 Usage

+

Follow our quickstart guide for an introduction on how to deploy cluster stacks on openstack.

+

Layers of a Cluster Stack

+

In essence, a cluster stack is an amalgamation of various components each of which serves a crucial role in setting up, maintaining, and operating a Kubernetes cluster. In the context of our framework, we categorize these components into three core layers: cluster-class, cluster-addons, and node-images. Let's delve deeper into understanding each of these layers:

+

📚 Cluster Class

+

The Cluster Class serves as a blueprint for creating and configuring Kubernetes clusters consistently. It encapsulates various aspects of a cluster, including:

+
    +
  • The infrastructure provider details
  • +
  • Networking configurations
  • +
  • Cluster-class templating
  • +
  • Other cluster-specific settings
  • +
+

Essentially, it defines the desired configuration and properties of a Kubernetes cluster. It leverages the ClusterClass feature of Cluster API, which provides a declarative, Kubernetes-style API for cluster creation, configuration, and management. Any change in this layer or in the node-image or cluster-addon layers triggers a version bump in the cluster class, hence the cluster stack.

+

🎁 Cluster Addons

+

Cluster Addons are core components or services required for the Kubernetes cluster to function correctly and efficiently. These are not user-facing applications but rather foundational services critical to the operation and management of a Kubernetes cluster. They're usually installed and configured after the cluster infrastructure has been provisioned and before the cluster is ready to serve workloads.

+

Cluster addons encompass a variety of functionalities, including but not limited to:

+
    +
  • Container Network Interfaces (CNI): These are plugins that facilitate container networking. A CNI is integral to setting up network connectivity and ensuring communication between pods in a Kubernetes cluster.
  • +
  • Cloud Controller Manager (CCM): The CCM is a Kubernetes control plane component that embeds the cloud-specific control logic. Its role is to manage the communication with the underlying cloud services.
  • +
  • Konnectivity service: This is a network proxy that enables connectivity from the control plane to nodes and vice versa. It is a critical component that supports Kubernetes API server connectivity.
  • +
  • Metrics Server: A cluster-wide aggregator of resource usage data, Metrics Server collects CPU, memory, and other metrics from nodes and pods, enabling features like Horizontal Pod Autoscaling.
  • +
+

It's important to note that cluster addons are not user-provided applications or services that can be installed multiple times, such as ingress controllers, application-level monitoring tools, or user-facing APIs. Those are left to the discretion and responsibility of the users, who install and manage them according to their specific needs and preferences.

+

Each addon version is independent and can be updated separately. However, a change in this layer also necessitates a version bump in the cluster class and the cluster stack, which is reflected in the metadata.yaml.

+

🎞️ Node Images

+

Node images provide the foundation for the operating system environment on each node of a Kubernetes cluster. They are typically a minimal operating system distribution, like a lightweight Linux distro, which may also include container runtime components such as Docker or containerd.

+

Node images are responsible for providing the necessary environment and dependencies to support Kubernetes components and workloads. This includes components like kubelet, kube-proxy, and other necessary system utilities and libraries.

+

The version of a node image can be different from that of the cluster stack or the cluster class. However, an update to a node image will trigger a version bump in the cluster class and hence the cluster stack.

+

In the cluster-stacks repository's directory structure, the build instructions for Node Images are always placed within the respective directory. The instructions outline the steps and configurations required to create the Node Image automatically. The specific method for releasing the Node Image may vary based on the provider's capabilities and requirements.

+

During the development phase, the build instructions serve as a reference within the repository itself. These instructions may utilize tools like Packer or other image-building techniques. This allows for flexibility and customization, enabling users to define their Node Images according to specific needs and requirements.

+

However, when it comes to the release of the cluster stack, the Node Image can be provided in different ways depending on the capabilities of the provider or the desired deployment method. Here are a few examples:

+
    +
  1. URL on a remote endpoint: In some cases, providers may support deploying a Node Image directly from a URL. In this scenario, the Node Image referenced in the cluster stack, specifically in the cluster class, would be provided as a URL pointing to a pre-built image accessible remotely.
  2. +
  3. Artifact: If the provider supports artifacts, the Node Image can be released as an artifact, such as a qcow2 file. The artifact would be uploaded to the provider, and the cluster stack references the artifact for node provisioning.
  4. +
  5. Build Instructions: In cases where the provider doesn't support direct URL deployment or artifact-based provisioning, the build instructions defined within the repository become critical. The build instructions serve as a comprehensive guide to build the Node Image, specifying all the necessary steps and configurations.
  6. +
+

Regardless of the release method, the cluster stack, specifically the cluster class, references the appropriate Node Image to be used for node provisioning.

+

By allowing flexibility in the release and deployment methods of Node Images, the cluster stack framework caters to various provider capabilities and user requirements. This adaptability ensures the cluster stack can be deployed in diverse environments while maintaining a consistent and manageable approach to managing Kubernetes clusters.

+

🌐 IaaS Provider, Kubernetes Service Provider, and Cluster API

+

In the context of the cluster-stacks, we distinguish between two types of providers:

+

An IaaS Provider, in general, offers Infrastructure as a Service - providing the fundamental compute, storage, and network resources on which workloads can be run. In the context of cluster-stacks, an IaaS Provider specifically refers to an entity that owns an API for their infrastructure. If an organization uses a common infrastructure API, such as OpenStack, they are not considered an IaaS Provider in this context. However, if the organization owns the API for its infrastructure, it becomes an IaaS Provider for the purposes of cluster-stacks.

+

A Kubernetes Service Provider, on the other hand, is an entity that implements a cluster stack. They do so on top of the IaaS Providers, potentially spanning across multiple IaaS Providers. They use the IaaS Provider's infrastructure services and integrate them into their cluster stack implementations.

+

The Cluster API (CAPI) is a Kubernetes project aimed at simplifying the process of managing Kubernetes clusters. It offers a declarative API that automates the creation, configuration, and management of clusters, providing a standardized way to interact with Kubernetes. The cluster stack approach leverages CAPI to deliver self-managed Kubernetes clusters.

+

📌 Defining and Adding Providers

+

The structure of this repository is specifically designed to handle multiple providers, multiple cluster stacks per provider, and multiple Kubernetes versions per cluster stack. This organized structure allows us to effectively manage, develop, and maintain multiple cluster stacks across various Kubernetes versions and providers, all in a single repository.

+

📁 Repository Structure

+

The repository maintains a specific structure:

+
    +
  • Each IaaS Provider has a directory under providers.
  • +
  • Each IaaS Provider can have multiple cluster stack implementations.
  • +
  • Each cluster stack supports multiple Kubernetes major and minor versions.
  • +
+
providers/
└── <provider_name>/
└── <cluster_stack_name>/
└── <k8s_major_minor_version>/
+

The directory structure for adding a new provider would look something like this:

+
providers/<provider_name>/<cluster_stack_name>/<k8s_major_minor_version>
# example
providers/openstack/scs/1-28
+

This granular, hierarchical structure allows us to manage different versions of Kubernetes and their associated cluster stacks across different providers.

+

We decided to support multiple Kubernetes major and minor versions to provide the flexibility to accommodate different implementation requirements of the provider. However, we deliberately chose not to support Kubernetes patch versions directly. The reason is the high frequency of patch versions release (often weekly), which would complicate maintenance efforts significantly.

+

Instead, we represent Kubernetes patch version updates through changes in our cluster stack version. For instance, if a patch version of Kubernetes necessitates a change in the node-image or the cluster-class configuration, this would trigger a version bump in the corresponding cluster stack, hence the cluster class, as reflected in the metadata.yaml.

+

In this way, our versioning system, our directory structure, and our approach to Kubernetes versioning are all interlinked, providing us a comprehensive, manageable, and resilient framework for maintaining various Kubernetes distributions or cluster stacks across multiple providers and versions.

+

📑 Versioning

+

Note: This section is subject to change, as our new tool csctl will incorporate future versioning capabilities.

+

A fundamental aspect of the cluster stack approach is the encapsulation of versioning within a cluster stack distribution. Each of the components can be updated independently, leading to a flexible and maintainable system.

+

However, the critical point to understand here is the relationship between these component versions and the cluster stack version. Whenever there's a change or an update to either the cluster addon or the node image, the version of the cluster stack must be bumped. And due to the connection between the cluster class and the cluster stack, the cluster class version must be updated to match the new cluster stack version.

+

The cluster stack version doesn't simply mirror the versions of its components, but rather, it reflects the "version of change". In essence, the cluster stack version is a reflection of the state of the entire stack as a whole at a particular point in time. Any change in the components warrants a new state, and therefore a new version of the cluster stack.

+

So, an update to the cluster addon component will bump the version of the cluster stack, irrespective of the existing version of the node image. The same applies vice versa. When such an update occurs, the version of the cluster class is also incremented to align with the new cluster stack version, maintaining the unity of the cluster stack framework.

+

This versioning approach ensures a clear and precise track of changes, promoting efficient management, and isolated testing. It offers enhanced resilience for the Kubernetes distribution or the cluster stack, ensuring safe and secure upgrades even in rapid update cycles. It's an efficient method of maintaining stability in the rapidly changing environment of a Kubernetes stack.

+

The versioning of the cluster stack is primarily managed through a file named metadata.yaml, located at the root directory of each cluster stack. This file serves as the source of truth for the versioning information of the cluster stack, cluster class, node images, and cluster addons.

+

Here is an example of how metadata.yaml could look like:

+
apiVersion: metadata.clusterstack.x-k8s.io/v1alpha1
versions:
clusterStack: v3
kubernetes: v1.27.3
components:
clusterAddon: v2
nodeImage: v1
+

In this example, the cluster stack (and thus the cluster class) is on version 3, while the cluster addon is on version 2 and node image is on version 1.

+

When there's a change or update in the node images or cluster addons, we would bump the version of the cluster stack and cluster class, while leaving the unaffected component's version intact. So if the node image was updated, the metadata.yaml might then look like this:

+
apiVersion: metadata.clusterstack.x-k8s.io/v1alpha1
versions:
clusterStack: v4
kubernetes: v1.27.3
components:
clusterAddon: v2
nodeImage: v2
+

Here, the cluster stack and cluster class versions were updated to v4, the node image version was bumped to v2 due to the changes, while the cluster addon remained on v2 as it was not affected by the update.

+

This versioning approach allows us to keep track of changes across different components, manage these components effectively, and conduct isolated testing. This ensures that our Kubernetes distribution or cluster stack remains resilient, and we can perform safe and secure upgrades even in the face of rapid update cycles. The metadata.yaml plays a critical role in maintaining this structure and providing an accurate representation of the state of the whole stack at any given time.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration/index.html b/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration/index.html new file mode 100644 index 0000000000..d01ff7522e --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration/index.html @@ -0,0 +1,31 @@ + + + + + +Configuration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Configuration

+

This page lists the custom configuration options available, including their default values and if they are optional. The following example shows how these variables can be used inside the cluster.yaml file under spec.topology.variables.

+

Example

+
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
name:
namespace:
labels:
managed-secret: cloud-config
spec:
clusterNetwork:
pods:
cidrBlocks:
- 192.168.0.0/16
serviceDomain: cluster.local
services:
cidrBlocks:
- 10.96.0.0/12
topology:
variables: // <-- variables from the table can be set here
- name: controller_flavor
value: "SCS-4V-8-20"
- name: worker_flavor
value: "SCS-4V-8-20"
- name: external_id
value: "ebfe5546-f09f-4f42-ab54-094e457d42ec"
class: openstack-alpha-1-29-v2
controlPlane:
replicas: 2
version: v1.29.3
workers:
machineDeployments:
- class: openstack-alpha-1-29-v2
failureDomain: nova
name: openstack-alpha-1-29-v2
replicas: 4
+

Variables from the table containing a . are to be used in an object with the part before the dot being the object name and the part behind the dot being the value names. The following example demonstrates this with oidc_config.

+
...
topology:
variables:
- name: oidc_config
value:
issuer_url: "https://dex.k8s.scs.community"
client_id: "kubectl"
...
+

Available variables

+
NameTypeDefaultExampleDescriptionRequired
external_idstring"""ebfe5546-f09f-4f42-ab54-094e457d42ec"ExternalNetworkID is the ID of an external OpenStack Network. This is necessary to get public internet to the VMs.False
controller_flavorstring"SCS-2V-4-20s""SCS-2V-4-20s"OpenStack instance flavor for control-plane nodes.False
worker_flavorstring"SCS-2V-4""SCS-2V-4"OpenStack instance flavor for worker nodes.False
controller_root_diskinteger25Root disk size in GiB for control-plane nodes. OpenStack volume will be created and used instead of an ephemeral disk defined in flavor. Should only be used for the diskless flavors.False
worker_root_diskinteger2525Root disk size in GiB for worker nodes. OpenStack volume will be created and used instead of an ephemeral disk defined in flavor. Should be used for the diskless flavors.False
yawol_flavor_idstring"""0a79590e-10d7-4c2c-8f69-ca0a2c6208d2"ID of the existing flavor used as a default yawol flavor.False
yawol_image_idstring"""f0b2ef46-f0ff-43d2-9c08-f58a5a6e9060"ID of the existing imaged used as a default yawol image.False
kube_vip_network_idstring"""40a51f6c-9e4b-4b24-9187-49851a410c97"ID of the existing network. The network should have one subnet with one port reserved as virtual IP.False
kube_vip_apiserver_virtual_ipstring"""10.0.0.197"Virtual IP address reserved in kube_vip_network_id.False
kube_vip_apiserver_public_ipstring""""Public IP address associated with kube_vip_apiserver_virtual_ip. It is needed only when the management cluster is on a different network as a workload cluster.False
openstack_security_groupsarray[]['security-group-1']The names of the security groups to assign to the instanceFalse
cloud_namestring"openstack""openstack"The name of the cloud to use from the clouds secretFalse
secret_namestring"openstack""openstack"The name of the clouds secretFalse
controller_server_group_idstring"""3adf4e92-bb33-4e44-8ad3-afda9dfe8ec3"The server group to assign the control plane nodes to.False
worker_server_group_idstring"""869fe071-1e56-46a9-9166-47c9f228e297"The server group to assign the worker nodes to.False
ssh_keystring"""capi-keypair"The ssh key to inject in the nodes.False
apiserver_loadbalancerstring"octavia-amphora""none, octavia-amphora, octavia-ovn, kube-vip""In this cluster-stack we have two kind of loadbalancers. Each of them has its own configuration variable. This setting here is to configure the loadbalancer that is placed in front of the apiserver.
To configure the loadbalancer for the workloads, see variable workload_loadbalancer.
You can choose from 4 options:

none:
No loadbalancer solution will be deployed

octavia-amphora:
(default) Uses openstack's loadbalancer service (provider:amphora)

octavia-ovn:
Uses openstack's loadbalancer service (provider:ovn)

kube-vip:
Uses kube-vip as loadbalancer.
You have to provide the following additional variables:
kube_vip_network_id
kube_vip_apiserver_virtual_ip
kube_vip_apiserver_public_ip

Requires Kubernetes version < 1.29
Also the settings node_cidr and dns_nameservers will no longer have an effect.
False
workload_loadbalancerstring"octavia-amphora""none, octavia-amphora, octavia-ovn, yawol""This setting here is to configure the loadbalancer solution for your services inside your cluster.
If you want to configure the loadbalancer in front of your apiserver, see variable apiserver_loadbalancer instead.
You can choose from 4 options:

none:
No loadbalancer solution will be deployed

octavia-amphora:
(default) Uses openstack's loadbalancer service (provider:amphora)

octavia-ovn:
Uses openstack's loadbalancer service (provider:ovn)

yawol:
Uses yawol as loadbalancer.
You have to provide the following additional variables:
yawol_flavor_id
yawol_image_id

Also note this setting does not work with application credentials (only username/password)"
False
dns_nameserversarray['5.1.66.255', '185.150.99.255']['5.1.66.255', '185.150.99.255']"DNSNameservers is the list of nameservers for the OpenStack Subnet being created. Set this value when you need to create a new network/subnet while the access through DNS is required.
This setting has no effect when apiserver_loadbalancer is set to kube-vip.
However you can set the dns server when creating the subnet for kube-vip."
False
node_cidrstring"10.8.0.0/20""10.8.0.0/20""NodeCIDR is the OpenStack Subnet to be created. Cluster actuator will create a network, a subnet with NodeCIDR, and a router connected to this subnet. If you leave this empty, no network will be created.
This setting has no effect when apiserver_loadbalancer is set to kube-vip.
However you can set the node_cidr when creating the subnet for kube-vip."
False
certSANsarray[]['mydomain.example']CertSANs sets extra Subject Alternative Names for the API Server signing cert.False
oidc_config.client_idstringkubectlA client id that all tokens must be issued for.
oidc_config.issuer_urlstringhttps://dex.k8s.scs.communityURL of the provider that allows the API server to dis cover public signing keys. Only URLs that use the https:// scheme are acc epted. This is typically the provider's discovery URL, changed to have an emp ty path
oidc_config.username_claimstringpreferred_usernamepreferred_usernameJWT claim to use as the user name. By default sub, whi ch is expected to be a unique identifier of the end user. Admins can choose oth er claims, such as email or name, depending on their provider. However, cla ims other than email will be prefixed with the issuer URL to prevent naming cla shes with other plugins.
oidc_config.groups_claimstringgroupsgroupsJWT claim to use as the user's group. If the claim is present it must be an array of strings.
oidc_config.username_prefixstringoidc:oidc:Prefix prepended to username claims to prevent cla shes with existing names (such as system: users). For example, the value oid c: will create usernames like oidc:jane.doe. If this flag isn't provided and --o idc-username-claim is a value other than email the prefix defaults to ( Iss uer URL )# where ( Issuer URL ) is the value of --oidc-issuer-url. The value - c an be used to disable all prefixing.
oidc_config.groups_prefixstringoidc:oidc:Prefix prepended to group claims to prevent clashes wit h existing names (such as system: groups). For example, the value oidc: will cre ate group names like oidc:engineering and oidc:infra.
network_mtuinteger1500NetworkMTU sets the maximum transmission unit (MTU) value to address fragmentation for the private network ID.False
controlPlaneAvailabilityZonesarray['nova']ControlPlaneAvailabilityZones is the set of availability zones which control plane machines may be deployed to.False
controlPlaneOmitAvailabilityZonebooleanTrueControlPlaneOmitAvailabilityZone causes availability zone to be omitted when creating control plane nodes, allowing the Nova scheduler to make a decision on which availability zone to use based on other scheduling constraints.False
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart/index.html b/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart/index.html new file mode 100644 index 0000000000..b4573f8afb --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart/index.html @@ -0,0 +1,83 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Quickstart

+

This quickstart guide contains steps to install the Cluster Stack Operator (CSO) utilizing the Cluster Stack Provider OpenStack (CSPO) to provide ClusterClasses which can be used with the Kubernetes Cluster API to create Kubernetes Clusters.

+

This section guides you through all the necessary steps to create a workload Kubernetes cluster on top of the OpenStack infrastructure. The guide describes a path that utilizes the clusterctl CLI tool to manage the lifecycle of a CAPI management cluster and employs kind to create a local non-production managemnt cluster.

+

Note that it is a common practice to create a temporary, local bootstrap cluster which is then used to provision a target management cluster on the selected infrastructure.

+

Prerequisites

+ +

Initialize the management cluster

+

Create the kind cluster:

+
kind create cluster
+

Transform the Kubernetes cluster into a management cluster by using clusterctl init and bootstrap it with CAPI and Cluster API Provider OpenStack (CAPO) components:

+
export CLUSTER_TOPOLOGY=true
export EXP_CLUSTER_RESOURCE_SET=true
export EXP_RUNTIME_SDK=true
clusterctl init --infrastructure openstack
+

CSO and CSPO variables preparation (CSP)

+

The CSO and CSPO must be directed to the Cluster Stacks repository housing releases for the OpenStack provider. +Modify and export the following environment variables if you wish to redirect CSO and CSPO to an alternative Git repository

+

Be aware that GitHub enforces limitations on the number of API requests per unit of time. To overcome this, +it is recommended to configure a personal access token for authenticated calls. This will significantly increase the rate limit for GitHub API requests. +Fine grained PAT with Public Repositories (read-only) is enough.

+
export GIT_PROVIDER_B64=Z2l0aHVi  # github
export GIT_ORG_NAME_B64=U292ZXJlaWduQ2xvdWRTdGFjaw== # SovereignCloudStack
export GIT_REPOSITORY_NAME_B64=Y2x1c3Rlci1zdGFja3M= # cluster-stacks
export GIT_ACCESS_TOKEN_B64=$(echo -n '<my-personal-access-token>' | base64 -w0)
+

CSO and CSPO deployment (CSP)

+

Install the envsubst Go package. It is required to enable the expansion of variables specified in CSPO and CSO manifests.

+
GOBIN=/tmp go install github.com/drone/envsubst/v2/cmd/envsubst@latest
+

Get the latest CSO release version and apply CSO manifests to the management cluster.

+
# Get the latest CSO release version and apply CSO manifests
curl -sSL https://github.com/SovereignCloudStack/cluster-stack-operator/releases/latest/download/cso-infrastructure-components.yaml | /tmp/envsubst | kubectl apply -f -
+

Get the latest CSPO release version and apply CSPO manifests to the management cluster.

+
# Get the latest CSPO release version and apply CSPO manifests
curl -sSL https://github.com/sovereignCloudStack/cluster-stack-provider-openstack/releases/latest/download/cspo-infrastructure-components.yaml | /tmp/envsubst | kubectl apply -f -
+

Define a namespace for a tenant (CSP/per tenant)

+
export CS_NAMESPACE=my-tenant
+

Deploy CSP-helper chart

+

The csp-helper chart is meant to create per tenant credentials as well as the tenants namespace where all resources for this tenant will live in.

+

Cloud and secret name default to openstack.

+

Example clouds.yaml

+
clouds:
openstack:
auth:
auth_url: https://api.gx-scs.sovereignit.cloud:5000/v3
application_credential_id: ""
application_credential_secret: ""
region_name: "RegionOne"
interface: "public"
identity_api_version: 3
auth_type: "v3applicationcredential"
+
helm upgrade -i csp-helper-"${CS_NAMESPACE}" -n "${CS_NAMESPACE}" --create-namespace https://github.com/SovereignCloudStack/openstack-csp-helper/releases/latest/download/openstack-csp-helper.tgz -f path/to/clouds.yaml
+

Create Cluster Stack definition (CSP/per tenant)

+

Configure the Cluster Stack you want to use:

+
# the name of the cluster stack (must match a name of a directory in https://github.com/SovereignCloudStack/cluster-stacks/tree/main/providers/openstack)
export CS_NAME=scs

# the kubernetes version of the cluster stack (must match a tag for the kubernetes version and the stack version)
export CS_K8S_VERSION=1.29

# the version of the cluster stack (must match a tag for the kubernetes version and the stack version)
export CS_VERSION=v1
export CS_CHANNEL=stable

# must match a cloud section name in the used clouds.yaml
export CS_CLOUDNAME=openstack
export CS_SECRETNAME="${CS_CLOUDNAME}"
+

This will use the cluster-stack as defined in the providers/openstack/scs directory.

+
cat >clusterstack.yaml <<EOF
apiVersion: clusterstack.x-k8s.io/v1alpha1
kind: ClusterStack
metadata:
name: clusterstack
namespace: ${CS_NAMESPACE}
spec:
provider: openstack
name: ${CS_NAME}
kubernetesVersion: "${CS_K8S_VERSION}"
channel: ${CS_CHANNEL}
autoSubscribe: false
providerRef:
apiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1
kind: OpenStackClusterStackReleaseTemplate
name: cspotemplate
versions:
- ${CS_VERSION}
---
apiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1
kind: OpenStackClusterStackReleaseTemplate
metadata:
name: cspotemplate
namespace: ${CS_NAMESPACE}
spec:
template:
spec:
identityRef:
kind: Secret
name: ${CS_SECRETNAME}
EOF

kubectl apply -f clusterstack.yaml
+
clusterstack.clusterstack.x-k8s.io/clusterstack created
openstackclusterstackreleasetemplate.infrastructure.clusterstack.x-k8s.io/cspotemplate created
+

Create the workload cluster resource (SCS-User/customer)

+

To create a workload cluster you must configure the following things:

+
export CS_CLUSTER_NAME=cs-cluster
# Note: if you need more than one POD_CIDR, please adjust the yaml file accordingly
export CS_POD_CIDR=192.168.0.0/16
# Note: if you need more than one SERVICE_CIDR, please adjust the yaml file accordingly
export CS_SERVICE_CIDR=10.96.0.0/12
export CS_EXTERNAL_ID=ebfe5546-f09f-4f42-ab54-094e457d42ec # gx-scs
export CS_CLASS_NAME=openstack-"${CS_NAME}"-"${CS_K8S_VERSION/./-}"-"${CS_VERSION}"
export CS_K8S_PATCH_VERSION=6
+

Create and apply cluster.yaml file to the management cluster.

+

Depending on your cluster-class and cluster addons, some more variables may have to be provided in the spec.topology.variables list. +An error message after applying the Cluster resource will tell you if more variables are necessary.

+
cat > cluster.yaml <<EOF
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
name: ${CS_CLUSTER_NAME}
namespace: ${CS_NAMESPACE}
labels:
managed-secret: cloud-config
spec:
clusterNetwork:
pods:
cidrBlocks:
- ${CS_POD_CIDR}
serviceDomain: cluster.local
services:
cidrBlocks:
- ${CS_SERVICE_CIDR}
topology:
variables:
- name: controller_flavor
value: "SCS-2V-4-50"
- name: worker_flavor
value: "SCS-2V-4-50"
- name: external_id
value: ${CS_EXTERNAL_ID}
class: ${CS_CLASS_NAME}
controlPlane:
replicas: 1
version: v${CS_K8S_VERSION}.${CS_K8S_PATCH_VERSION}
workers:
machineDeployments:
- class: default-worker
failureDomain: nova
name: default-worker
replicas: 3
EOF

kubectl apply -f cluster.yaml
+
cluster.cluster.x-k8s.io/cs-cluster created
+

Utilize a convenient CLI clusterctl to investigate the health of the cluster:

+
clusterctl -n ${CS_NAMESPACE} describe cluster ${CS_CLUSTER_NAME}
+

Once the cluster is provisioned and in good health, you can retrieve its kubeconfig and establish communication with the newly created workload cluster:

+
# Get the workload cluster kubeconfig
clusterctl -n "${CS_NAMESPACE}" get kubeconfig ${CS_CLUSTER_NAME} > kubeconfig.yaml
# Communicate with the workload cluster
kubectl --kubeconfig kubeconfig.yaml get nodes
+

Check the workload cluster health

+
$ kubectl --kubeconfig kubeconfig.yaml get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system cilium-8mzrx 1/1 Running 0 7m58s
kube-system cilium-jdxqm 1/1 Running 0 6m43s
kube-system cilium-operator-6bb4c7d6b6-c77tn 1/1 Running 0 7m57s
kube-system cilium-operator-6bb4c7d6b6-l2df8 1/1 Running 0 7m58s
kube-system cilium-p9tkv 1/1 Running 0 6m44s
kube-system cilium-thbc8 1/1 Running 0 6m45s
kube-system coredns-5dd5756b68-k68j4 1/1 Running 0 8m3s
kube-system coredns-5dd5756b68-vjg9r 1/1 Running 0 8m3s
kube-system etcd-cs-cluster-pwblg-xkptx 1/1 Running 0 8m3s
kube-system kube-apiserver-cs-cluster-pwblg-xkptx 1/1 Running 0 8m3s
kube-system kube-controller-manager-cs-cluster-pwblg-xkptx 1/1 Running 0 8m3s
kube-system kube-proxy-54f8w 1/1 Running 0 6m44s
kube-system kube-proxy-8z8kb 1/1 Running 0 6m43s
kube-system kube-proxy-jht46 1/1 Running 0 8m3s
kube-system kube-proxy-mt69p 1/1 Running 0 6m45s
kube-system kube-scheduler-cs-cluster-pwblg-xkptx 1/1 Running 0 8m3s
kube-system metrics-server-6578bd6756-vztzf 1/1 Running 0 7m57s
kube-system openstack-cinder-csi-controllerplugin-776696786b-ksf77 6/6 Running 0 7m57s
kube-system openstack-cinder-csi-nodeplugin-96dlg 3/3 Running 0 6m43s
kube-system openstack-cinder-csi-nodeplugin-crhc4 3/3 Running 0 6m44s
kube-system openstack-cinder-csi-nodeplugin-d7rzz 3/3 Running 0 7m58s
kube-system openstack-cinder-csi-nodeplugin-nkgq6 3/3 Running 0 6m44s
kube-system openstack-cloud-controller-manager-hp2n2 1/1 Running 0 7m9s
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/csctl/design/index.html b/docs/container/components/cluster-stacks/components/csctl/design/index.html new file mode 100644 index 0000000000..54f5df5709 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/csctl/design/index.html @@ -0,0 +1,100 @@ + + + + + +CSCTL - Design document | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

CSCTL - Design document

+

Introduction

+

The Cluster Stack Operator facilitates the usage of cluster stacks by automating all steps that can be automated. It takes cluster stacks release assets that consist mainly of two Helm charts, one to deploy in the management cluster, the other one to deploy in the workload clusters, as well as provider-specific node image (build) information.

+

Users can take existing releases of cluster stacks and the operator and will be able to create clusters easily.

+

However, there is no clear and nice way to work on cluster stacks, test, and release them.

+

This proposal will discuss a tool to improve the experience of developers implementing cluster stacks.

+

Motivation

+

The current process of building cluster stacks is rather cumbersome and error-prone. There are multiple issues with the current approach:

+
    +
  1. The release assets have to follow a very specific (naming) pattern, to be usable with the operator. Currently, they have to be created manually. There are no docs for this manual process.
  2. +
  3. The cluster stacks can be versioned following the pattern v1, v2, … This is perfect from the user perspective, but not good for people implementing cluster stacks, as they can only do local tests by artificially creating a v2 and not releasing it.
  4. +
  5. The versioning of the cluster stacks is not easy, as there are multiple versions involved. Cluster addons have their own version, for example. Currently, the versions have to be manually hard-coded in multiple places. This can be validated to some degree but is not developer-friendly and can still lead to mistakes.
  6. +
+

Proposal

+

We propose a CLI tool called “csctl”, which stands for cluster-stack-manager-ctl. This CLI tool should take over all manual work from a developer implementing cluster stacks that can be taken over. The developer should concentrate only on implementing the cluster stacks themselves.

+

There will be still a certain way of dealing with “cluster stack-specific” jobs, e.g. following a certain templating pattern. This is necessary, as the configuration and Helm Charts that developers implement are very generic.

+

The tool should generate release assets, e.g. by using helm package for the helm charts. It should be able to create these release assets for different use cases, e.g. for creating a stable release, for testing a certain commit, and for creating a beta release.

+

User stories

+

User story 1: Developer releasing cluster stacks

+

A developer who wants to release a cluster stack that was implemented can use the CLI tool to generate all release assets that are required. This should save much time compared to following a manual process.

+

User story 2: Developer versioning cluster stacks

+

A developer who has to think about how to version a cluster stack that was implemented can use the tool to do the job. This saves a lot of time, as the developer would have to manually check whether anything was updated for cluster addons or node images to find the appropriate version (”Did anything change in the cluster addons so that they need a new version or not?”).

+

User story 3: Multiple developers work in parallel on one cluster stack

+

If multiple developers work on one cluster stack, they might interfere with each other’s work. Assuming that node images have to be built, then one developer would upload the node images in version “v2”, as the previous version was “v1”. The second developer has the same thought and would either overwrite the already uploaded node images of the colleague or not be able to upload the images since they exist already.

+

The csctl allows both developers to have independent versioning based on a git commit hash.

+

User story 4: Developer updating cluster stack that is used in production

+

If a developer updates a cluster stack that is used in production, great care is needed. The csctl allows the developer to safely test cluster stacks, e.g. with a beta channel, without touching cluster stacks that are used in production. +If everything works well, a production release can be generated with csctl.

+

User story 5: Automated testing of cluster stacks

+

Cluster stacks cannot be tested in the CI and with a normal Git PR flow. The csctl allows this testing of individual PRs and therefore enables automated testing via CI.

+

Risks & Mitigations

+

Two forms of templating

+

Helm charts use Go templating with the notation {{ .values.myvalue }}. As a cluster stack consists usually of two Helm charts, this notation will be very common.

+

However, the csctl requires a different form of templating, additionally to the one of Helm. This comes from the versioning of the cluster stacks themselves. The Cluster addon version, for example, has to be the version of the respective Helm chart. The same goes for the ClusterClass object name.

+

Users have to use the additional templating notation << .ClusterAddonVersion >> while implementing cluster stacks.

+

The alternative to using a different notation for cluster stack templating would be to use the same one as Helm. However, this will be confusing for users, as they cannot differentiate it. Therefore, we cannot suggest to follow that path.

+

Design details

+

Generic vs provider-specific work

+

Just like the Cluster Stack Operator, the csctl also has a generic and a provider-specific part. The provider-specific part is optional.

+

The generic work is done with a CLI tool that exists in the repository csctl in SCS. The tool can be initialized with provider-specific binaries, similar to the way packer does it.

+

Generic work

+

The generic part of the csctl is

+
    +
  1. Calculate the right versions based on git commit hash or previous releases
  2. +
  3. Template everything with csctl templating (NOT Helm templating!!)
  4. +
  5. Package the ClusterClass Helm Chart
  6. +
  7. Package the ClusterAddon Helm Chart
  8. +
  9. Generate metadata.yaml
  10. +
+

Provider-specific work

+

The provider-specific part of csctl would do anything necessary to provide node images to users. One common task could be to use packer to build images and to upload them somewhere they can be accessed by users.

+

Of course, one task would also be to find the right version for the node images (e.g. v2 if something changed since v1, or simply the git commit hash)

+

Configuration

+

There are multiple ways of configuring the csctl. They all have specific use cases and will be explained in the following

+

Configuration file

+

There is a configuration file called csctl.yaml which contains all values that will never have to be changed for a specific cluster stack. It follows this pattern:

+
apiVersion: csctl.clusterstack.x-k8s.io/v1alpha1
config:
kubernetesVersion: v1.27.7
clusterStackName: ferrol
provider:
type: myprovider
apiVersion: myprovider.csctl.clusterstack.x-k8s.io/v1alpha1
config: xyz
+

There is mainly the Kubernetes version, the name of the cluster stack, as well as the provider. Additionally, there is a provider-specific configuration. Both the generic and the provider-specific configuration is versioned.

+

Flags

+

Via flags the user can specifiy everything that is important but which might change, e.g. the mode “stable” or “hash”, giving you release assets for a stable release or creating release assets based on the latest git commit hash.

+

Environment variables

+

Environment variables can be used, for example, to specify tokens and passwords. csctl has to validate that all required environment variables have been specified.

+

Commands of CLI tool

+

Multiple commands can make sense for developers. The most important one is the create command that creates release assets, as well as provider install to install the binary of a provider that carries out all provider-specific work.

+

This is a full list:

+
subcommands:
provider Is used for the provider lifecycle
create creates release assets of a cluster stack.
generate Generates a specific resource from a cluster stack
list show all cluster-stacks from a repo
version shows the version of this cli tool
help print a overview of available flags etc.

subcommands for provider:
install Installs a cluster-stack-release-provider at a version
installed Lists installed csctl release providers
remove removes a csctl release provider at a version `csctl provider remove docker <version>`
+

Modes

+

There are multiple modes to create release assets following different versioning patterns.

+

Stable

+

The stable mode requires the developer to specify an existing GitHub repository (in the future other ways of storing release assets are possible) via environment variables. The csctl will search for the latest release fitting to the configuration of provider, cluster stack name, and Kubernetes version (e.g. docker-ferrol-1-27-vXXX). Then it will download the required release assets and check whether anything has changed in the cluster addon and node image section. Depending on that information it will calculate the next version, e.g. v2 after v1, or will leave the version the same if nothing changed.

+

Hash

+

The hash mode is useful for developing cluster stacks. It will use the hash of the last git commit and generate a version of the form v0-hash.<hash>. following semver.

+

This version will be used for cluster class, cluster add-ons, and node images. Unlike the stable version, the versions in hash mode always update to the latest commit and do not depend on any previous release.

+

Beta

+

The beta mode is similar to the stable mode, except that it generates releases following the version pattern v0-beta.0, v0-beta.1, etc.

+

Custom (e.g. for PRs)

+

The custom mode is designed for PR purposes and supports automated testing. It accommodates versions formatted as v0.custom-pr123. Crucially, these versions must adhere to semantic versioning standards (semver) and are specifically intended as inputs for the csctl tool.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl/index.html b/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl/index.html new file mode 100644 index 0000000000..28bf5583e3 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl/index.html @@ -0,0 +1,44 @@ + + + + + +Developing and Testing csctl | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Developing and Testing csctl

+

Clone the Repo

+

Go to csctl at Github and clone the repository to your local device:

+
git clone git@github.com:SovereignCloudStack/csctl.git
+
cd csctl
+

Makefile

+

We use a Makefile to building the binary.

+

You can see the available build targets with make help.

+

make build

+

With make build you create the executable.

+

csctl --help

+

With ./csctl --help you can see the available sub-commands.

+

BTW: Be sure to use ./, so that you don't accidentally use a different csctl from your $PATH.

+

Up to now only create is a feasible sub-command.

+

go run main.go ...

+

If you modify the source of csctl, you can skip the build step by using go run:

+
go run main.go create --help
+

Create Docker Cluster Stack

+

In the tests directory is a cluster stack for the docker provider.

+

You can create the cluster stack like this:

+
❯ go run main.go create tests/cluster-stacks/docker/ferrol -m hash                                                                                                                  
Created releases/docker-ferrol-1-27-v0-sha-7ff9188
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/csctl/getting_started/index.html b/docs/container/components/cluster-stacks/components/csctl/getting_started/index.html new file mode 100644 index 0000000000..aff63eb835 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/csctl/getting_started/index.html @@ -0,0 +1,43 @@ + + + + + +Getting started | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Getting started

+

A Cluster Stack is full template of a Kubernetes cluster. A Cluster Stack can be configured on every provider that supports Cluster API.

+

The Cluster Stack Operator facilitates using Cluster Stacks by automating all steps that users would have to do manually given they have a Cluster API management cluster.

+

The csctl helps to generate all files and build node images based on provided scripts in a format that the Cluster Stack Operator can use.

+

The csctl requires a certain directory structure and uses a special form of templating to insert the right versions in your configuration files (e.g. Helm charts).

+

Overview

+

The directory structure is very important. If the directories are not configured properly, csctl will not be able to build the cluster-stack for you.

+

You should must have the following content inside your directory:

+
    +
  • csctl.yaml: the configuration of csctl
  • +
  • cluster-addon directory: the directory containing the Helm chart for cluster addons (Chart.yaml, templates and Helm related files if required)
  • +
  • cluster-class directory: the directory containing the Helm chart for Cluster API resources, e.g. ClusterClass (Chart.yaml, templates and Helm related files if required)
  • +
  • node-image directory (optional): the directory containing config and associated scripts to build node images
  • +
+

Configuring csctl

+

The configuration of csctl has to be specified in the csctl.yaml. It needs to follow this structure:

+
apiVersion: csctl.clusterstack.x-k8s.io/v1alpha1
config:
kubernetesVersion: v1.27.7
clusterStackName: ferrol
provider:
type: <myprovider>
apiVersion: <myprovider>.csctl.clusterstack.x-k8s.io/v1alpha1
config:
+

The apiVersion specifies the version of this configuration. Currently, there is only the version csctl.clusterstack.x-k8s.io/v1alpha1.

+

Furthermore, the Kubernetes version in the format v<major>.<minor>.<patch> (e.g. 1.27.5) has to be specified as well as the name that should be given to the Cluster Stack.

+

Depending on your plugin, there might be a provider-specific configuration.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl/index.html b/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl/index.html new file mode 100644 index 0000000000..36174a6d7e --- /dev/null +++ b/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl/index.html @@ -0,0 +1,58 @@ + + + + + +how_to_use_csctl | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+

Obsolete, content moved to overview.md and quickstart.md for use in docs.scs.community

+
+

Using csctl

+

What does csctl do?

+

As a user, you can create clusters based on Cluster Stacks with the help of the Cluster Stack Operator. The operator needs certain files, e.g. to apply the required Helm charts, and to get the necessary information about the versions in the cluster stack.

+

In order to not generate these files manually, this CLI tool takes a certain pre-defined directory structure, in which users can configure all necessary Helm charts and build scripts for node images, and generates the assets that the Cluster Stack Operator can process.

+

Therefore, this tool can be used to configure Cluster Stacks and to test them with the Cluster Stack Operator. It can also be used to release stable releases of Cluster Stacks that can be published for a broader community.

+

Different modes of csctl

+

The csctl has multiple modes that can be used for different use cases.

+

Hash mode

+

This mode is the most used one, as it allows quick iterations and testing of a cluster stack. It takes the hash of the content of the cluster stack and generates a semver version on this. You can combine it with the custom channel of Cluster Stack Operator and test your Cluster Stacks easily!

+

Stable mode

+

This mode checks for existing releases of cluster stacks and versions your cluster stack accordingly. If you have an existing release of "v1", then it would use "v2" for the new one. It also checks whether the node images and cluster addons have changed or not and will only update the versions if something actually changed.

+

Beta mode

+

Similar to stable mode, but for a beta release channel. It versions according to "v0-beta.1", etc.

+

Custom mode

+

The custom mode can be used to define your own version. You can input any semver version and your cluster stack will be versioned accordingly.

+

Installing csctl

+

You can click on the respective release of csctl on GitHub and download the binary.

+

Assuming, you have downloaded the csctl_0.0.2_linux_amd64 binary in your Downloads directory, you will need the following commands to rename the binary and to give it executable permissions.

+
$ sudo chmod u+x ~/Downloads/csctl_0.0.2_linux_amd64
$ sudo mv ~/Downloads/csctl_0.0.2_linux_amd64 /usr/local/bin/csctl # or use any bin directory from your PATH
+

Then you can check whether everything worked by printing the version of csctl.

+
$ csctl version
csctl version: 0.0.2
commit: f252304eb013014b35f8a91abf1f61aff2062601
+

If you don't see a version there, then something has gone wrong. Re-check above steps and open an issue if it still does not work!

+

If you're using gh CLI then you can also use the following to download it.

+
$ gh release download -p csctl_0.0.2_linux_amd64 -R SovereignCloudStack/csctl
+

Creating Cluster Stacks

+

The most important subcommand is create. This command takes a path to the directory where you configured your Cluster Stack and generates the necessary files in the output directory via the --output flag:

+
$ csctl create <path-to-cluster-stack-configuration-directory> --output <path-to-output-directory>
+

You can specify your node image registry with the flag --node-image-registry. The plugin of your provider will update the node images in the respective container registry.

+

You can use the --mode flag to specify the mode you want to use.

+

For example:

+
$ csctl create <path-to-cluster-stack-directory> --output <path-to-output-directory>  --mode hash --node-image-registry <url-of-registry>
+

You have to be authenticated to your cloud provider and container registry to which you want to upload the node images.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/csctl/overview/index.html b/docs/container/components/cluster-stacks/components/csctl/overview/index.html new file mode 100644 index 0000000000..92bf4d2ad7 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/csctl/overview/index.html @@ -0,0 +1,51 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

Introduction

+

The Cluster Stack Operator facilitates the usage of Cluster Stacks by automating all steps that can be automated. It takes Cluster Stacks release assets that consist mainly of two Helm charts, one to deploy in the management cluster, the other one to deploy in the workload clusters, as well as provider-specific node image (build) information.

+

Users can take existing releases of Cluster Stacks and the operator and will be able to create clusters easily.

+

This project facilitates building node image artifacts and release assets that can be used with the Cluster Stack Operator.

+

What does csctl do?

+

As a user, you can create clusters based on Cluster Stacks with the help of the Cluster Stack Operator. The operator needs certain files, e.g. to apply the required Helm charts, and to get the necessary information about the versions in the cluster stack.

+

In order to not generate these files manually, this CLI tool takes a certain pre-defined directory structure, in which users can configure all necessary Helm charts and build scripts for node images, and generates the assets that the Cluster Stack Operator can process.

+

Therefore, this tool can be used to configure Cluster Stacks and to test them with the Cluster Stack Operator. It can also be used to release stable releases of Cluster Stacks that can be published for a broader community.

+

Features of csctl

+
    +
  1. +

    Testing and quick iterations +csctl is created with a single focus of building Cluster Stacks and testing them with Cluster Stack Operator quickly. This tool helps in doing quick iterations and facilitates testing Cluster Stacks.

    +
  2. +
  3. +

    Versioning +When configuring Cluster Stacks, it is necessary to put versions in the configuration, e.g. to version a Helm chart or node images. This process is facilitated by the csctl through its own templating and mechanism to generate the right version, based on the content hash (for testing) or on a previous version (stable or beta channel). Users only have to use the right templating and the csctl will do all the versioning automatically.

    +
  4. +
  5. +

    Plugin mechanism for providers +The plugin mechanism of csctl allows providers to implement all provider-specific steps that are needed for this provider. This can contain a fully automated building and uploading process for node images, which can be referenced in the Cluster Stack (using the templating logic for versioning).

    +
  6. +
  7. +

    Automated testing of Cluster Stacks +The csctl enables automated testing of Cluster Stacks if integrated in a CI process that first builds all necessary files as well as node images (if needed) and then uses them to create a workload cluster based on the Cluster Stack.

    +
  8. +
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/csctl/quickstart/index.html b/docs/container/components/cluster-stacks/components/csctl/quickstart/index.html new file mode 100644 index 0000000000..970b3814ca --- /dev/null +++ b/docs/container/components/cluster-stacks/components/csctl/quickstart/index.html @@ -0,0 +1,51 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Quickstart

+

Installation

+

To download csctl there are two ways. +Go to https://github.com/SovereignCloudStack/csctl/releases/latest and then click on the binary. The name of the binary looks similar to this csctl_0.0.3_linux_amd64.tar.gz for Linux amd64 architecture.

+

This will download the binary in your ~/Downloads directory. Use the following commands to move it to your PATH.

+
tar xvzf ~/Downloads/csctl_<version>_linux_amd64.tar.gz
chmod u+x ~/Downloads/csctl
sudo mv ~/Downloads/csctl /usr/local/bin/csctl
+

Alternative way of installing the binary is to use [gh](https://github.com/cli/cli) command line tool. +Use the following command to download the latest binary from GitHub.

+
gh release download -p 'csctl_<version>_linux_amd64.tar.gz' -R SovereignCloudStack/csctl
tar xvzf csctl_<version>_linux_amd64.tar.gz
chmod u+x csctl
sudo mv ./csctl /usr/local/bin/csctl
+

For darwin based systems, the steps are similar, you'll have to choose darwin based binaries instead of linux one mentioned above. You'll also need to update your destination directory.

+

Creating Cluster Stacks

+

The most important subcommand is create. This command takes a path to the directory where you configured your Cluster Stack and generates the necessary files in the output directory via the --output flag:

+
$ csctl create <path-to-cluster-stack-configuration-directory> --output <path-to-output-directory>
+

You can specify your node image registry with the flag --node-image-registry. The plugin of your provider will update the node images in the respective container registry.

+

You can use the --mode flag to specify the mode you want to use.

+

For example:

+
$ csctl create <path-to-cluster-stack-directory> --output <path-to-output-directory>  --mode hash --node-image-registry <url-of-registry>
+

You have to be authenticated to your cloud provider and container registry to which you want to upload the node images.

+

Different modes of csctl

+

The csctl has multiple modes that can be used for different use cases.

+

Hash mode

+

This mode is the most used one, as it allows quick iterations and testing of a cluster stack. It takes the hash of the content of the cluster stack and generates a semver version on this. You can combine it with the custom channel of Cluster Stack Operator and test your Cluster Stacks easily!

+

Stable mode

+

This mode checks for existing releases of cluster stacks and versions your cluster stack accordingly. If you have an existing release of "v1", then it would use "v2" for the new one. It also checks whether the node images and cluster addons have changed or not and will only update the versions if something actually changed.

+

Beta mode

+

Similar to stable mode, but for a beta release channel. It versions according to "v0-beta.1", etc.

+

Custom mode

+

The custom mode can be used to define your own version. You can input any semver version and your cluster stack will be versioned accordingly.

+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/backup_and_restore/index.html b/docs/container/components/container-registry/docs/backup_and_restore/index.html new file mode 100644 index 0000000000..92c2430682 --- /dev/null +++ b/docs/container/components/container-registry/docs/backup_and_restore/index.html @@ -0,0 +1,194 @@ + + + + + +Backup and restore | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Backup and restore

+

This page aims at providing a step-by-step guide for backup and restore Harbor +container registry using Velero tool. +It extends the official Harbor backup-restore docs page +with up-to-date commands, explanations, and an extensive prerequisites section. This +guide references and uses Velero in v1.10.2 +as this is the latest stable version at the time of writing this guide.

+

It provides guidance and commands that readers are encouraged to try out by themselves +on Harbor deployment as described in the next sections. It does not aim at providing an +exhaustive list of commands nor all the possible ways how to use them.

+

The guide covers two strategies to save Harbor data:

+
    +
  • Backup: a regular backup created by the restic integration in Velero as described in the related docs
  • +
  • Snapshot: a point-in-time snapshot be the Container Storage Interface (CSI) snapshot support in Velero as described in the related docs
  • +
+

Before you choose the right strategy for your Harbor deployment backup, make sure that you understand +differences between the backup and snapshot. +In general, for long-term protection of Harbor data, you may use backup and for +temporary protection of data (e.g. before Harbor upgrade) you may use snapshot.

+

Note that this guide is not limited to Harbor deployments that utilize SCS environments, +but it is required to have a set of tools and services (e.g. Kubernetes CSI plugin with volume snapshot +support, S3 compatible object store for backups) for successful backup and restore procedure +(see the prerequisites section). These tools and services come out of +the box when the SCS infrastructure and KaaS are used for Harbor deployment, hence it is +convenient to use them.

+

Prerequisites

+

Kubernetes cluster

+

If you want to use snapshot to back up Harbor data ensure the following:

+
    +
  • Your cluster is Kubernetes version 1.20 or greater
  • +
  • Your cluster is running a CSI driver +capable of support volume snapshots at the v1 API level. +To enable creating volume snapshots, the snapshot-controller +and its CRDs should be deployed in the Kubernetes cluster as well. The snapshot-controller +is independent of any CSI Driver. These prerequisites come out of the box with the SCS KaaS solution.
  • +
+

If you want to create Harbor backup ensure the following:

+
    +
  • Your cluster is Kubernetes version 1.16 or greater
  • +
+

If your cluster meets the above, export its kubeconfig path in env. variable KUBECONFIG:

+
export KUBECONFIG=/path/to/kubeconfig
+

S3 bucket and EC2 credentials

+

This guide assumes that the public cloud's object store with S3-compatible API is available as +the storage backend for Velero. In this guide, we are using OpenStack Swift which +offers S3-compatible API. Let's create an S3 bucket on Swift object storage and EC2 credentials +that will be later used by Velero.

+

You should have access to your OpenStack project, and the OpenStack RC file that contains access +values. Set the environment variables by sourcing the OpenStack RC file:

+
source <project>-openrc.sh
+

Swift object store service does not support application credentials authentication +to access S3 API. To authenticate in S3 API, you should generate and use the EC2 credentials +mechanism. +Note that EC2 credentials are associated with a user and are scoped only to a specific project. +EC2 credentials are not protected by limited roles, expiration time, or +access rules, therefore they have the same access as the user who created them. If you +want to restrict EC2 credentials you could use application credentials for their creation, +then EC2 credentials should inherit a (potentially) limited subset of roles that creator +owns (see this for details).

+

You can generate EC2 credentials as follows:

+
$ openstack ec2 credentials create
+------------+----------------------------------------------------------------------------------------------------------+
| Field | Value |
+------------+----------------------------------------------------------------------------------------------------------+
| access | <aws_access_key_id> |
| links | {'self': 'https://api.gx-scs.sovereignit.cloud:5000/v3/users/<user_id>/credentials/OS-EC2/<project_id>'} |
| project_id | <project_id> |
| secret | <aws_secret_access_key> |
| trust_id | None |
| user_id | <user_id> |
+------------+----------------------------------------------------------------------------------------------------------+
+

Write down aws_access_key_id and aws_secret_access_key values from the output of openstack ec2 credentials create +command and store them in the ~/.aws/credentials file as follows:

+
mkdir ~/.aws
cat >~/.aws/credentials <<EOF
[default]
aws_access_key_id = <aws_access_key_id>
aws_secret_access_key = <aws_secret_access_key>
EOF
+

This credential file is then used as an access and secret source for AWS CLI tool and also +as a source for Velero. If your environment does not have AWS CLI installed, install it as follows:

+
pip3 install awscli awscli-plugin-endpoint
+

Finally, create a new bucket. Note that the following command contains endpoint-url +argument that points AWS CLI to the GX-SCS OpenStack Swift object store API.

+
aws --endpoint-url https://api.gx-scs.sovereignit.cloud:8080 s3 mb s3://velero-backup
+

Velero client

+

In this guide, we are using Velero to back up and restore a Harbor instance. +Velero is an open source tool to safely back up and restore, perform disaster recovery, +and migrate Kubernetes cluster resources.

+

Go through the official docs and +install the Velero client on your desired environment. If your environment is Linux distribution +you can use the following steps and install the Velero client from the GitHub release binaries:

+
wget https://github.com/vmware-tanzu/velero/releases/download/v1.10.2/velero-v1.10.2-linux-amd64.tar.gz 
tar -zxvf velero-v1.10.2-linux-amd64.tar.gz
sudo mv velero-v1.10.2-linux-amd64/velero /usr/local/bin/
+

Velero server

+

Install Velero server components along with the appropriate plugins, into the Kubernetes cluster. +This will create a namespace called velero, and place a deployment named velero in it. +Note that the installation command sets the bucket velero-backup that has been created a few steps +earlier as well as EC2 credentials located in ~/.aws/credentials file. Also note that +the region and s3Url parameters are GX-SCS specific. For further details about installation +options, supported storage providers, and more visit the official Velero docs.

+
    +
  • If you want to use snapshot to back up Harbor data: +
      +
    • Install Velero:
    • +
    +
     velero install \
    --features=EnableCSI \
    --provider aws \
    --plugins velero/velero-plugin-for-aws:v1.6.1,velero/velero-plugin-for-csi:v0.4.2 \
    --bucket velero-backup \
    --secret-file ~/.aws/credentials \
    --backup-location-config region=RegionOne,s3ForcePathStyle="true",s3Url=https://api.gx-scs.sovereignit.cloud:8080 \
    --snapshot-location-config region=RegionOne,enableSharedConfig=true
    +
      +
    • In order to allow Velero to do Volume Snapshots, we need to deploy a new VolumeSnapshotClass. Create a velero-snapclass.yaml file as follows:
    • +
    +
    cat > velero-snapclass.yaml << EOF
    apiVersion: snapshot.storage.k8s.io/v1
    deletionPolicy: Delete
    driver: cinder.csi.openstack.org
    kind: VolumeSnapshotClass
    metadata:
    name: csi-cinder-snapclass-in-use-v1-velero
    labels:
    velero.io/csi-volumesnapshot-class: "true"
    parameters:
    force-create: "true"
    EOF
    +
      +
    • Apply the new class:
    • +
    +
    kubectl apply -f velero-snapclass.yaml
    +
  • +
  • If you want to create Harbor backup with Restic: +
      +
    • Install Velero:
    • +
    +
    velero install \
    --provider aws \
    --plugins velero/velero-plugin-for-aws:v1.6.1 \
    --bucket velero-backup \
    --secret-file ~/.aws/credentials \
    --use-volume-snapshots=false \
    --uploader-type=restic \
    --use-node-agent \
    --backup-location-config region=RegionOne,s3ForcePathStyle="true",s3Url=https://api.gx-scs.sovereignit.cloud:8080
    +
  • +
+

Backup and restore

+

Note that the following backup steps mainly point to actions from an official Backup And Restore Harbor With Velero tutorial. +In this guide, find the added value from additional explanations/hints and up-to-date commands.

+

Harbor, by design, consists of multiple (micro)services that could store their data +variously, based on the Harbor configuration. See the Harbor persistence +docs for further information regarding the Harbor persistence layer. The following steps cover +cases when Harbor persistence is enabled and the "internal" databases (PostgreSQL and Redis) +are used.

+

Note that Redis key-value database is not backed up in both cases, i.e. when "internal" +or "external" Redis instance is used. As a result, the user sessions of logged users +that are stored in Redis will be lost. Hence, after the restore, users should log in +again. This data loss should be a low impact on your restored Harbor instance.

+

PostgreSQL database should be backed up as it stores important metadata of Harbor models, +like projects, users, roles, etc. The backup and restore of "internal" PostgreSQL instance +is covered by this guide. The "external" PostgreSQL backup is not supported by the +official tutorial and is out of the scope of this guide as well.

+

Also, keep an eye on the official backup and restore limitations +section to be aware of the potential impact on your Harbor instance. The limitation: +The upload purging process may cause backup failure mentioned that it is better to +increase registry upload purging interval (it is a background process that periodically +removes orphaned files from the upload directories of the registry, see the docs). +This interval is by default +set to 24h (helm value: registry.upload_purging.interval). If you do not want to change +the registry configuration at all you should ensure that the backup will be performed in +the middle of two rounds of purging. This background process starts when the registry +container is initialized, therefore is a good idea to check logs of the registry container +and determine when is a good time to do a backup, e.g. as follows:

+
$ kubectl logs -l component=registry -c registry --tail -1 | grep -i purge
time="2023-04-17T09:02:08.320514706Z" level=info msg="Starting upload purge in 24h0m0s" go.version=go1.15.6 instance.id=xxx service=registry version=v2.7.1.m
time="2023-04-17T09:09:08.321004645Z" level=info msg="PurgeUploads starting: olderThan=2023-04-10 09:09:08.320738572 +0000 UTC m=-604379.969424455, actuallyDelete=true"
time="2023-04-17T09:09:08.331433127Z" level=info msg="Purge uploads finished. Num deleted=0, num errors=0"
...
+

Backup Harbor Instance

+
    +
  1. +

    Set Harbor to the ReadOnly mode

    +
  2. +
  3. +

    Backup Harbor:

    +
      +
    • Using snapshot to back up Harbor data: +
        +
      • Exclude the volume of Redis in backup, we need to label the Redis pod, PVC and PV with specific label: +
        # label the Pod of Redis, replace the namespace and Pod name with yours
        kubectl -n default label pod/harbor-harbor-redis-0 velero.io/exclude-from-backup=true
        # label the PVC of Redis, replace the namespace and PVC name with yours
        kubectl -n default label pvc/data-harbor-harbor-redis-0 velero.io/exclude-from-backup=true
        # get the name of Redis PV, replace the namespace and PVC name with yours
        kubectl -n default get pvc data-harbor-harbor-redis-0 --template={{.spec.volumeName}}
        # label the PV of Redis, replace the pv-name with the one get from last command
        kubectl label pv/pv-name velero.io/exclude-from-backup=true
        +
      • +
      • Back up Harbor +
        # replace the namespace and backup name with yours
        velero backup create harbor-backup --include-namespaces default --snapshot-volumes --wait
        +
      • +
      +
    • +
    • Using Restic to back up Harbor data: +
        +
      • Exclude the volume of Redis in backup +
        # replace the namespace and pod name with yours
        kubectl -n default annotate pod/harbor-harbor-redis-0 backup.velero.io/backup-volumes-excludes=data
        +
      • +
      • Back up Harbor +
        velero backup create harbor-backup --include-namespaces default --default-volumes-to-fs-backup --wait
        +
      • +
      +
    • +
    +
  4. +
  5. +

    Unset Harbor from the ReadOnly mode

    +
  6. +
+

Restore Harbor Instance

+

Restore Harbor Instance

+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/ha-deployment/index.html b/docs/container/components/container-registry/docs/ha-deployment/index.html new file mode 100644 index 0000000000..f4cde5cb4a --- /dev/null +++ b/docs/container/components/container-registry/docs/ha-deployment/index.html @@ -0,0 +1,72 @@ + + + + + +HA deployment | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

HA deployment

+

Prerequisites

+
    +
  • Kubernetes cluster v1.20+ +
      +
    • Use existing cluster +
      export KUBECONFIG=/path/to/kubeconfig
      +
    • +
    • Alternatively, spawn some dev cluster, e.g. using KinD +
      kind create cluster
      +
    • +
    +
  • +
  • Flux CLI + +
  • +
+

Install and wait for operators

+
$ kubectl apply -k operators/
$ flux get helmrelease -n default
NAME REVISION SUSPENDED READY MESSAGE
cert-manager v1.11.0 False True Release reconciliation succeeded
ingress-nginx 4.5.2 False True Release reconciliation succeeded
postgres-operator 1.9.0 False True Release reconciliation succeeded
redis-operator 3.2.7 False True Release reconciliation succeeded
+
+

Note: Install separate operators by e.g.:

+
kubectl apply -k operators/redis/
kubectl apply -k operators/postgres/
+
+

Create redis and postgres clusters

+
envs/public-ha/redis/redis-secret.bash # pwgen needs to be installed
kubectl apply -k envs/public-ha/redis/
kubectl apply -k envs/public-ha/postgres/
+

Install Harbor

+
    +
  • +

    Replace the example.com URL in the harbor-config.yaml file with the desired one.

    +
  • +
  • +

    Take ingress-nginx-controller LoadBalancer IP address and create DNS record for Harbor.

    +
    kubectl get svc -n ingress-nginx
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    ingress-nginx-controller LoadBalancer 100.92.14.168 81.163.194.219 80:30799/TCP,443:32482/TCP 2m51s
    ingress-nginx-controller-admission ClusterIP 100.88.40.231 <none> 443/TCP 2m51s
    +
  • +
  • +

    Generate secrets and install Harbor:

    +
  • +
  • +

    It is recommended to replace admin@example.com email address in issuer.yaml with your own. +Let's Encrypt will use this to contact you about expiring certificates, and issues related to your account.

    +
    base/harbor-secrets.bash # pwgen and htpasswd need to be installed
    envs/public-ha/swift-secret.bash <username> <password>
    kubectl apply -k envs/public-ha/
    +
  • +
+

All in one installation using FluxCD Kustomization and GitRepository reconciliation

+
envs/public-ha/redis/redis-secret.bash
base/harbor-secrets.bash
envs/public-ha/swift-secret.bash <username> <password>
# --branch/tag can be specified, default to master
flux create source git k8s-harbor --url=https://github.com/SovereignCloudStack/k8s-harbor --interval=5m
kubectl apply -f envs/public-ha/public-ha.yaml
+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/migration/index.html b/docs/container/components/container-registry/docs/migration/index.html new file mode 100644 index 0000000000..e1852e74de --- /dev/null +++ b/docs/container/components/container-registry/docs/migration/index.html @@ -0,0 +1,127 @@ + + + + + +Migration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Migration

+

harbor_migration.png

+

This page aims at providing a step-by-step guide for lift and shift migration of Harbor +container registry, which operates in the Kubernetes environment and is deployed with Helm. +This migration scenario uses Velero tool which +enables moving your Harbor instance as-is from one Kubernetes environment to another +Kubernetes environment. The motivation behind this could be e.g. migration +from one cloud provider to another, an outdated Kubernetes environment of your Harbor +instance or avoiding the Harbor in-place upgrade.

+

Note that the official Harbor's documentation contains an "Upgrade Harbor and Migrate Data" page +that instructs users on how to upgrade and migrate Harbor data from one instance to +another. This tutorial supports only deployments that have been installed by Harbor installer script. +Hence, Harbor instances running in docker containers and spawned by docker-compose.

+

Note that this guide is not limited to Harbor deployments that utilize SCS environments. +Visit the prerequisites section to see what is required for a successful +migration. These prerequisites come out of the box when the SCS infrastructure and KaaS +are used for Harbor deployment, hence it is convenient to use them.

+

Prerequisites

+

As this scenario uses a backup and restore procedure for the migration process, this section +refers to the prerequisites section in Harbor - backup and restore +docs page.

+

Kubernetes clusters

+

This migration scenario expects that you want to migrate your Harbor instance +between different Kubernetes clusters that could live in different environments (e.g. +OpenStack projects) or even in different cloud providers. Let's call them Cluster_A and +Cluster_B. Cluster_A represents the Kubernetes cluster where your Harbor currently operates and +Cluster_B represents the target Kubernetes cluster to which you want to migrate your Harbor.

+

As Cluster_A and Cluster_B do not have to share the same infrastructure it is convenient to +use a full Harbor data backup (not a snapshot) using Restic +integration in Velero. In this case, Cluster_A and Cluster_B should have +Kubernetes version 1.16 or greater. +For further details about Restic-Velero integration refer to the
+related Velero docs.

+

Kubernetes versions of Cluster_A and Cluster_B may differ. In this case, it is +not unusual to see the Kubernetes API group versions differing between clusters. This +incompatibility may cause issues during the migration of your Harbor instance. By default, +Velero only backs up resources that use the preferred version of the Kubernetes API. +However, Velero also includes a feature, Enable API Group Versions, +that overcomes this limitation and backup all Kubernetes API group versions that are +supported on the source Cluster_A. Then, if this feature is also enabled on the Cluster_B, +Velero will make the best choice of Kubernetes API version which is defined in the group +name of both source Cluster_A and target Cluster_B based on API group version priority order, +read docs for further details. +If the above is the case consider installing Velero on both clusters +with a feature flag --features=EnableAPIGroupVersions. Note that this feature is still in beta.

+

S3 bucket and EC2 credentials

+

This guide assumes that the public cloud's object store with S3-compatible API is available as +the storage backend for Velero. Refer to the S3 bucket and EC2 credentials +section in the backup and restore docs and create a bucket that will be later used for +the migration.

+

Velero client

+

Install the Velero client on your local environment, refer to Velero client.

+

Velero server

+

Install Velero server components along with the appropriate plugins, into the both +(Cluster_A and Cluster_B) clusters. Keep in mind that we will use Restic uploader in +Velero, hence follows interactions on how to do that in the related docs section Velero server. +Do not forget to add --kubeconfig argument to install Velero server components +to the Cluster_A and then to the Cluster_B. The rest of arguments should be the same:

+
velero install \
--kubeconfig <path to the kubeconfig file of Cluster_[A,B]> \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.6.1 \
--bucket velero-backup \
--secret-file ~/.aws/credentials \
--use-volume-snapshots=false \
--uploader-type=restic \
--use-node-agent \
--backup-location-config region=RegionOne,s3ForcePathStyle="true",s3Url=https://api.gx-scs.sovereignit.cloud:8080
+

It is a good practice to configure the backup location in the Cluster_B as read-only. +This will make sure that the backup created from Cluster_A is not deleted from the object +store by mistake during the restore to Cluster_B. To do this you can just edit the default +BackupStorageLocation resource in Cluster_B.

+
$ kubectl -n velero --kubeconfig <path of Cluster_B kubeconfig> edit backupstoragelocations default
# Set the `accessMode` to `ReadOnly`
# spec:
# accessMode: ReadOnly
+

Migration

+

Before we start to migrate Harbor instance from one environment to another go through the +Backup and restore section and read +various limitations of the backup/restore process to be aware of the potential impact on +your Harbor instance.

+
    +
  1. Backup Harbor instance in Cluster_A +
      +
    • Set Harbor to the ReadOnly mode
    • +
    • Exclude the volume of Redis in backup in Cluster_A +
      # replace the namespace and pod name with yours
      kubectl -n default --kubeconfig <path of Cluster_A kubeconfig> annotate pod/harbor-harbor-redis-0 backup.velero.io/backup-volumes-excludes=data
      +
    • +
    • Back up Harbor in Cluster_A +
      velero backup create harbor-backup --kubeconfig <path of Cluster_A kubeconfig> --include-namespaces default --default-volumes-to-fs-backup --wait
      +This creates a full backup of all resources in the given namespace including their +persistent storages (besides Redis PV).
    • +
    • Optionally: Unset Harbor from the ReadOnly mode. +Keep in mind that the ReadOnly mode protects your Harbor instance from deleting +repository, artifact, tag, and pushing images. This ensures that the Harbor instance +in Cluster_A will be in sync with the Harbor instance in Cluster_B after you restored +Harbor instance from the backup in Cluster_B. Therefore, it is recommended to not +unset Harbor from the ReadOnly mode in Cluster_A.
    • +
    +
  2. +
  3. Restore Harbor instance in Cluster_B +
      +
    • Restore from the Backup +
      # replace the backup and restore names with yours
      velero restore create harbor-restore --from-backup harbor-backup --kubeconfig <path of Cluster_B kubeconfig> --wait
      +Velero backed up the whole namespace where the Harbor instance lives in Cluster_A, +therefore the restored namespace in Cluster_B may contain resources (e.g. service, +ingress, TLS certificates) that expose Harbor instance in the same way as in +Cluster_A. It is a good practice to test this Cluster_B instance before you allow +users to use it.
    • +
    • Unset Harbor from the ReadOnly mode. +As we set Harbor in Cluster_A to ReadOnly when doing the backup, the instance is +still in ReadOnly mode after restoring. Unset Harbor from the ReadOnly mode after +you check its functionality.
    • +
    +
  4. +
+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/persistence/index.html b/docs/container/components/container-registry/docs/persistence/index.html new file mode 100644 index 0000000000..9c82058d04 --- /dev/null +++ b/docs/container/components/container-registry/docs/persistence/index.html @@ -0,0 +1,147 @@ + + + + + +Persistence | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Persistence

+

This page briefly describes and provides pointers on how Harbor persists data when it is +deployed in a Kubernetes cluster environment. It points out the default persistence settings +of Harbor helm chart as well as available options.

+

Harbor, by design, consists of multiple (micro)services that could store their data +variously, based on the Harbor configuration, see the Architecture Overview of Harbor.

+

Data Access Layer

+

Redis

+
    +
  • Usage +
      +
    • Key value storage used as a login session cache, a registry manifest cache, and a queue for the jobservice (e.g. see Trivy)
    • +
    +
  • +
  • Default settings +
      +
    • Deployed as an "internal" single node database into the same Kubernetes cluster as Harbor (helm value: redis.type.internal)
    • +
    • Deployed as a StatefulSet with 1 replica
    • +
    • PV persistence is enabled by default (helm value: persistence.enabled.true), Redis POD mounts PV into the /var/lib/redis directory
    • +
    +
  • +
  • Additional settings +
      +
    • Harbor could be pointed to the "external" Redis (or Redis Sentinel) database (helm value: redis.type.external)
    • +
    • "Internal" Redis could be deployed without any persistence, i.e. it could use emptyDir (helm value: persistence.enabled.false)
    • +
    +
  • +
  • Notes + +
  • +
+

Database (PostgreSQL)

+
    +
  • Usage +
      +
    • Stores the related metadata of Harbor models, like projects, users, roles, replication policies, tag retention policies, scanners, charts, and images
    • +
    • Could store JobService logs (helm value: jobservice.jobLoggers.[database])
    • +
    +
  • +
  • Default settings +
      +
    • Deployed as an "internal" single node database into the same Kubernetes cluster as Harbor (helm value: database.type.internal)
    • +
    • Deployed as a StatefulSet with 1 replica
    • +
    • PV persistence is enabled by default (helm value: persistence.enabled.true), PostgreSQL POD mounts PV into the /var/lib/postgresql/data directory
    • +
    +
  • +
  • Additional settings +
      +
    • Harbor could be pointed to the "external" database (PostgreSQL) (helm value: database.type.external)
    • +
    • "Internal" database could be deployed without any persistence, i.e. it could use emptyDir (helm value: persistence.enabled.false)
    • +
    +
  • +
+

OCI Distribution Registry

+
    +
  • Usage +
      +
    • Backend storage of container images and charts
    • +
    +
  • +
  • Default settings +
      +
    • Images and charts are stored in registry POD filesystem directory /storage (helm value: persistence.imageChartStorage.type.filesystem), this directory is mounted to the PV
    • +
    +
  • +
  • Additional settings +
      +
    • Various object storage backends: "azure", "gcs", "s3", "swift", "oss" (helm value: persistence.imageChartStorage.type.<backend>)
    • +
    • Backend storage could beemptyDir (helm value: persistence.enabled.false)
    • +
    +
  • +
+

Fundamental Services

+

Proxy, Core, Web Portal

+
    +
  • These Harbor services are stateless
  • +
+

Trivy

+
    +
  • Usage +
      +
    • A 3rd party vulnerability scanner provided by Aqua Security
    • +
    +
  • +
  • Default settings +
      +
    • Deployed as a StatefulSet with 1 replica
    • +
    • PV persistence is enabled by default (helm value: persistence.enabled.true), Trivy POD mounts PV into the /home/scanner/.cache directory
    • +
    +
  • +
  • Additional settings +
      +
    • Trivy could be deployed without any persistence, i.e. it could use emptyDir (helm value: persistence.enabled.false)
    • +
    +
  • +
  • Notes + +
  • +
+

JobService

+
    +
  • Usage +
      +
    • General job execution queue service to let other components/services submit requests of running asynchronous tasks concurrently
    • +
    +
  • +
  • Default settings +
      +
    • Deployed as a Deployment with 1 replica
    • +
    • Store logs in the POD filesystem directory /var/log/jobs (helm value: jobservice.jobLoggers.[file]), this directory is mounted to the PV
    • +
    +
  • +
  • Additional settings +
      +
    • JobService could be deployed without any persistence, i.e. it could use emptyDir (helm value: persistence.enabled.false)
    • +
    • Logs could be stored in Harbor database (helm value: jobservice.jobLoggers.[database]) or just printed to the STDOUT (helm value: jobservice.jobLoggers.[stdout])
    • +
    +
  • +
+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/quickstart/index.html b/docs/container/components/container-registry/docs/quickstart/index.html new file mode 100644 index 0000000000..7307628198 --- /dev/null +++ b/docs/container/components/container-registry/docs/quickstart/index.html @@ -0,0 +1,56 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Quickstart

+

This guide shows you how to set up a working Harbor Container Registry that utilizes a Kubernetes cluster.

+

Prerequisites

+
    +
  • Kubernetes cluster v1.20+ +
      +
    • Use existing cluster +
      export KUBECONFIG=/path/to/kubeconfig
      +
    • +
    • Alternatively, spawn some dev cluster, e.g. using KinD +
      kind create cluster
      +
    • +
    +
  • +
  • Flux CLI + +
  • +
+

Install Harbor container registry

+

Apply kustomization manifest in envs/dev directory:

+
kubectl apply -k envs/dev/
+

Port-forward the Harbor container registry service:

+
kubectl port-forward svc/harbor 8080:80
+

Access the Harbor container registry UI and use Harbor's default credentials

+
    +
  • username: admin
  • +
  • password: Harbor12345
  • +
+
http://localhost:8080
+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/rate_limit/index.html b/docs/container/components/container-registry/docs/rate_limit/index.html new file mode 100644 index 0000000000..e4374eb8b8 --- /dev/null +++ b/docs/container/components/container-registry/docs/rate_limit/index.html @@ -0,0 +1,43 @@ + + + + + +Rate limit | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Rate limit

+

This page describes how the rate limiting can be set up for the Harbor container registry.

+

Harbor itself doesn't support rate limit protection yet, see open issue. +Therefore, we can take advantage of the ingress controller in front of the Harbor. In our case Nginx.

+

In the ingress-nginx controller, the rate-limiting options can be specified via annotations. +E.g. nginx.ingress.kubernetes.io/limit-rps: "1" means that ingress will allow only 1 request from a given IP per second. +Client IP is set based on the use of PROXY protocol or from the X-Forwarded-For header value. +In the SCS reference implementation, proxy protocol for ingress nginx is enabled by default. +This rate-limit annotation is ideal for DDoS attacks mitigation. When clients exceed this limit +503 status code is returned. This status code can be changed via nginx ingress controller configmap:

+
$ kubectl edit cm -n ingress-nginx ingress-nginx-controller
# data:
# limit-req-status-code: "429"
+

There are other useful annotations, such as limit concurrent connections, number of kilobytes per second or limit burst requests. +E.g. bursts can be configured via nginx.ingress.kubernetes.io/limit-burst-multiplier, which is by default 5. +It means that burst +will be set in this case to limit-rps * limit-burst-multiplier = 1 * 5 = 5.

+

More information about nginx rate-limiting and real-world examples can be seen in this nginx blog. +Also, there is a second option for how the rate limiting can be configured called global rate limiting. +Detailed research and comparison are done in this issue. +Furthermore, see this PR, +which adds a rate limit for the public(registry.scs.community) environment.

+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/scs-deployment/index.html b/docs/container/components/container-registry/docs/scs-deployment/index.html new file mode 100644 index 0000000000..d9e1995045 --- /dev/null +++ b/docs/container/components/container-registry/docs/scs-deployment/index.html @@ -0,0 +1,55 @@ + + + + + +SCS deployment | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS deployment

+

The following steps were utilized for deploying the SCS reference installation of the Harbor container registry, +which is available at https://registry.scs.community.

+

Prerequisites

+
    +
  • Kubernetes cluster v1.20+ +
      +
    • We used the R5 version of SCS KaaS V1, which includes an ingress controller and cert manager +
      export KUBECONFIG=/path/to/kubeconfig
      +
    • +
    +
  • +
  • Flux CLI (it is part of SCS KaaS V1) + +
  • +
  • kubectl
  • +
+

Install Harbor

+
    +
  • +

    Take ingress-nginx-controller LoadBalancer IP address and create DNS record for Harbor.

    +
    kubectl get svc -n ingress-nginx
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    ingress-nginx-controller LoadBalancer 100.92.14.168 81.163.194.219 80:30799/TCP,443:32482/TCP 2m51s
    ingress-nginx-controller-admission ClusterIP 100.88.40.231 <none> 443/TCP 2m51s
    +
  • +
  • +

    Generate secrets and install Harbor:

    +
    base/harbor-secrets.bash # pwgen and htpasswd need to be installed
    envs/public/s3-credentials.bash <accesskey> <secretkey>
    kubectl apply -k envs/public/
    +
  • +
+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/upgrade/index.html b/docs/container/components/container-registry/docs/upgrade/index.html new file mode 100644 index 0000000000..4cd8ae672e --- /dev/null +++ b/docs/container/components/container-registry/docs/upgrade/index.html @@ -0,0 +1,39 @@ + + + + + +Upgrade | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Upgrade

+

This page aims at providing additional information for upgrading Harbor +container registry, which operates in the Kubernetes environment and is deployed with Helm. +It extends the official Upgrading Harbor Deployed with Helm page, +where the upgrade process is well described. See the following upgrade hints:

+
    +
  • Always backup your Harbor instance before upgrade
  • +
  • Normally Harbor helm upgrade from 2 minor versions lower should be tested, but always +validate your planned upgrade path with recommendations in the official docs.
  • +
  • The step-by-step upgrade is needed because of possible DDL changes in the Harbor database. +Harbor core service executes the migrations scripts automatically. +The helm upgrade process may fail in the case of the failure of migration scripts. +Hence, it is a good idea to run migration scripts with a pre-upgrade job. Harbor Helm +has an option enableMigrateHelmHook which separates the database migration from Harbor core +and runs the migration job as a pre-upgrade hook.
  • +
+ + \ No newline at end of file diff --git a/docs/container/deployment-examples/a/hardware/index.html b/docs/container/deployment-examples/a/hardware/index.html new file mode 100644 index 0000000000..44fabf3ec2 --- /dev/null +++ b/docs/container/deployment-examples/a/hardware/index.html @@ -0,0 +1,25 @@ + + + + + +Hardware Requirements | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/deployment-examples/a/index.html b/docs/container/deployment-examples/a/index.html new file mode 100644 index 0000000000..a8d376abd2 --- /dev/null +++ b/docs/container/deployment-examples/a/index.html @@ -0,0 +1,25 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/deployment-examples/a/software/index.html b/docs/container/deployment-examples/a/software/index.html new file mode 100644 index 0000000000..337cb39eeb --- /dev/null +++ b/docs/container/deployment-examples/a/software/index.html @@ -0,0 +1,25 @@ + + + + + +Software Requirements | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/guides/guide1/index.html b/docs/container/guides/guide1/index.html new file mode 100644 index 0000000000..f3d1d4a5f4 --- /dev/null +++ b/docs/container/guides/guide1/index.html @@ -0,0 +1,25 @@ + + + + + +Guide 1 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/index.html b/docs/container/index.html new file mode 100644 index 0000000000..ec038fd342 --- /dev/null +++ b/docs/container/index.html @@ -0,0 +1,57 @@ + + + + + +Container Layer Introduction | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Container Layer Introduction

+

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:

+
    +
  • 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.
  • +
  • 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.
  • +
+

Target groups

+
    +
  • 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.
  • +
  • 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.
  • +
+

What is it not

+
    +
  • 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.
  • +
  • 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.
  • +
+

Prerequisites and Requirements

+
    +
  • Knowledge: Familiarity with Kubernetes, container orchestration, and basic cloud infrastructure principles is pivotal.
  • +
  • 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.
  • +
  • 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.
  • +
+

Features

+
    +
  • Automated Cluster Management: The Cluster API automates the process of creating, scaling, managing and updating Kubernetes clusters, thus significantly reducing the operational overhead.
  • +
  • Standardized Operations: Upholding SCS standards across various clusters ensures operational consistency and reliability.
  • +
  • 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.
  • +
  • Container Registry Integration: The container layer has an optional container registry, facilitating easy management and deployment of container images.
  • +
  • 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.
  • +
+

Limitations

+
    +
  • 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.
  • +
+ + \ No newline at end of file diff --git a/docs/container/overview/architecture/index.html b/docs/container/overview/architecture/index.html new file mode 100644 index 0000000000..33a1f49005 --- /dev/null +++ b/docs/container/overview/architecture/index.html @@ -0,0 +1,25 @@ + + + + + +Architecture | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/overview/knowledge/index.html b/docs/container/overview/knowledge/index.html new file mode 100644 index 0000000000..87e3eb1eb8 --- /dev/null +++ b/docs/container/overview/knowledge/index.html @@ -0,0 +1,25 @@ + + + + + +Knowledge | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/faq/index.html b/docs/faq/index.html new file mode 100644 index 0000000000..116f01ea1c --- /dev/null +++ b/docs/faq/index.html @@ -0,0 +1,73 @@ + + + + + +Frequently Asked Questions | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Frequently Asked Questions

+

What does SCS stand for?

+

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.

+

Who is SCS intended for?

+

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.

+

Who or what is behind SCS?

+

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.

+

Why is there a need for a standardized cloud environment?

+

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.

+

Where can I find the SCS standards?

+

The SCS standards are available on the standards pages within our documentation page. Find them here

+

How is the SCS different from other cloud environments (e.g. AWS, Azure,...)?

+

Unlike proprietary clouds, SCS emphasizes standardization, ensuring interoperability and reduced dependency on one provider.

+

My company already has a cloud environment. Can we still use the SCS?

+

Yes, SCS can complement existing environments, enhancing standardization and interoperability.

+

What does reference implementation mean?

+

Reference implementation is a concrete example or blueprint of how the SCS standards can be implemented.

+

Do I need to use the reference implementation to be SCS compliant?

+

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

+

Do I have to use all layers of the reference implementation (IaaS, CaaS)?

+

No, you can choose layers based on your needs and still be SCS compliant.

+

What does IaaS mean?

+

IaaS stands for Infrastructure as a Service, providing virtualized computing resources over the internet.

+

How is the IaaS layer structured?

+

IaaS typically comprises virtual machines, storage, and network resources, all offered as scalable services. Find the architecture here

+

What does CaaS mean? (Container Layer)

+

CaaS refers to Container as a Service, where providers offer container orchestration platforms.

+

I want to try out the SCS! Where do I start?

+

As a user:

+
    +
  • Existing SCS Clouds: Explore and test on any of the cloud providers offering SCS. Choose one from here
  • +
+

As a Cloud Service Provider:

+ +

I want to use an SCS Cloud! How do I get started?

+

As a user:

+ +

As a Cloud Service Provider:

+ +

I want to use the SCS in my company and build my own cloud! Where do I start?

+

Start by understanding SCS standards and then move on to the reference implementation. Link to guide.

+

I have a technical problem. Where can I find help?

+

Refer to our support section or check our community channels for assistance. Link to community.

+ + \ No newline at end of file diff --git a/docs/getting-started/containerization/index.html b/docs/getting-started/containerization/index.html new file mode 100644 index 0000000000..b851ca0c65 --- /dev/null +++ b/docs/getting-started/containerization/index.html @@ -0,0 +1,25 @@ + + + + + +Containerization | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/getting-started/overview/index.html b/docs/getting-started/overview/index.html new file mode 100644 index 0000000000..1cc6e62f8e --- /dev/null +++ b/docs/getting-started/overview/index.html @@ -0,0 +1,25 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/getting-started/virtualization/index.html b/docs/getting-started/virtualization/index.html new file mode 100644 index 0000000000..293d76e7c9 --- /dev/null +++ b/docs/getting-started/virtualization/index.html @@ -0,0 +1,25 @@ + + + + + +Virtualization | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/glossary/index.html b/docs/glossary/index.html new file mode 100644 index 0000000000..8a66060f8f --- /dev/null +++ b/docs/glossary/index.html @@ -0,0 +1,91 @@ + + + + + +Glossary | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Glossary

+

This file serves as the central glossary within SCS. It is intended to clearly +define terms used within SCS where there may be differing understandings. The +glossary is not intended to evaluate or standardize specific terms.

+

Definition of a Region

+

An OpenStack/SCS region consists of at least one or more Availability Zones that share a Control Plane with their services. As a result, they share one API. Also a Control Plane can share one CEPH cluster over different fire departments or each Availbility Zone can have its own CEPH cluster. Within the region, any Layer 2 networks are available to the user. Availbility Zones which build a region are connected by redundant low-latency (< 2ms ) high-bandwidth (10s of Gbps) connections.

+

Regions can be federated when the SCS code is ready.

+

Definition of a Availability Zone

+

An Availability Zone is a (physical) group of multiple compute nodes, controlled by the region's control plane that provides the API and interface.

+

An Availability Zone allows OpenStack compute hosts to be divided into logical groups and provides a form of physical isolation and redundancy from other Availability Zones, for example by using a separate power supply or network devices.

+

When users provision resources, they can specify in which Availability Zone their instances should be created. In this way, customers can ensure that their application resources are distributed across different failure domains to achieve high availability in the event of a hardware failure.

+

Definition of Host Aggregates

+

Host aggregates are a mechanism for partitioning compute nodes which is not explicitly visible to users in an OpenStack/SCS cloud. Host aggregates are based on arbitrary characteristics such as server type, processor type, GPU, disk speed, etc. +Administrators assign flavors to host aggregates by specifying metadata on the host aggregate and customizing the extra specifications of the flavor. It is then up to the Nova scheduler to determine the best match for the user request. Compute nodes can also be in more than one host aggregate.

+

Optionally, one can designate a host aggregate as an Availability Zone, e.g. for simplification reasons of the user selection of an availbility zone. +Availability Zones differ from Host Aggregates in that they are shown to the user as a Nova boot option, so Compute VMs can be started on them. +Compute Nodes, however, can only be in a single Availability Zone. We can configure a default Availability Zone where instances will be scheduled if the user does not specify an Availability Zone.

+

Info: A prerequisite for creating an Availability Zone is a host aggregate.

+

Definition of a Cell

+

The Cells paradigm simplifies the handling of large Openstack deployments.

+

Cells is an OpenStack Nova feature that improves scalability for Nova in OpenStack Platform. Each Cell has a separate database and message queue, which increases performance when scaling. One can provision additional Cells to handle large deployments, and compared to Regions, this allows access to a large number of compute nodes through a single API.

+

Each Cell has its own Cell controllers running the database server and RabbitMQ along with the Nova Conductor services.

+

Nova Conductor services, called "Super Conductor", continue to run on the main controller nodes.

+

The services in the Cell Controllers can still call placement APIs, but cannot access other API layer services via RPC, nor can they access global API databases on the control nodes.

+

Definition of a Control Plane

+

In Openstack/SCS, a Control Plane consists of at least 5 hardware nodes, which together serve several Availability Zones and thus provide a common usable API for a region. The Control Plane also shares the network (Neutron), the Scheduler and the CEPH services.

+

It includes the Controller Nodes (Galera Cluster, RabbitMQ) and the Manager Nodes, Maas,...

+

Definition of Control Node

+

The Control Node runs the Identity Service, Image Service , management processes for compute nodes, management processes for networking, various networking agents, and the Dashboard. It also includes supporting services such as an SQL database, a message queue, and NTP.

+

Optionally, the Controller Node runs parts of the Block Storage, Object Storage, Orchestration and Telemetry services.

+

The Controller Node requires at least two network interfaces.

+

Definition of Compute Node

+

A compute host runs the hypervisor part of compute that runs instances. By default, compute uses the KVM hypervisor. The compute host also runs a networking service agent that connects instances to virtual networks and provides firewall services to the instances through security groups.

+

If you offer hyper-converged infrastructure, a compute host also serves the Ceph. This makes the storage dynamically scalable (horizontally and vertically). For the Ceph services, 1 CPU core and 4 GB of RAM are reserved per OSD to ensure appropriate performance.

+

Definition of Manager Node

+

From here, the OSISM Ansible playbooks are applied to the environment. Furthermore, the following services often run here non-redundantly: Prometheus server,....

+

Definition of provider network

+

The provider network is the network that is "in front", i.e. at the output points of the openstack/SCS. This is usually a public network, but can also be a private network in individual cases. IPs from the provider network can be assigned to instances within the SCS. The same applies to load balancers, of course.

+

Definition of API

+

The Rest API provides the core of openstack/SCS and can be addressed for a whole region. It accepts and responds to end-user API calls. The service supports the OpenStack Compute API, the Amazon EC2 API, and a special Admin API for privileged users to perform administrative actions. Policies are enforced and most orchestration actions can be started, such as launching an instance.

+

Horizon

+

Horizon is openstack's preferred GUI for the end user, but also for the administrator for a quick overview. It runs on the controller node. Other GUIs are possible, also GUIs which replace the horizon interface

+

Message Queue

+

Most OpenStack services communicate with each other through the message queue. For example, Compute communicates with Block Storage services and Network services via the message queue. RabbitMQ, Qpid, and Zeromq are popular choices for a message queue service. When the message queue fails or becomes inaccessible, the cluster generally comes to a halt and ends up in a read-only state where the information is stuck at the point where the last message was sent. Therefore, this is clustered. RabbitMQ has shown itself to be the most widespread and best supported variant in the OpenStack context, Qpid occurs occasionally, ZeroMQ lacks HA functionality to date

+

Keystone

+

( The OpenStack Identity module called Keystone is used as an authentication and rights system between the OpenStack components. Keystone divides access to projects in the cloud into so-called "tenants". A tenant is a tenant of the cloud and has at least one assigned user. It is possible to create multiple users per tenant with different rights. Keystone uses a token system for authorization and also supports the connection to other authentication options such as LDAP. (wikipedia) )

+

Glance

+

The OpenStack Image Service, also called Glance, is a service that provides virtual machine images to OpenStack users. These images are used by Nova as a template to compile virtual machine instances. Both local hard disks and object storage solutions such as Swift or Ceph can be used as storage backends.

+

In addition to the images, Glance can also store metadata such as the operating system used or the kernel version. Access to both this metadata and the images themselves is via a REST API. Glance supports a number of formats such as VHD, VMDK and qcow2.

+

OSISM

+

The Open Source Infrastructure & Service Manager is a powerful deployment framework for OpenStack and Ceph as well as required services such as a RabbitMQ broker or a MariaDB Galera cluster.

+

Ceph

+

Ceph is an open source distributed storage solution. The core component is RADOS (Reliable Autonomic Distributed Object Store), an object store that can be distributed redundantly over any number of servers. Ceph offers the user three types of storage: An object store compatible with the Swift and S3 API (RADOS Gateway), virtual block devices (RADOS Block Devices) and CephFS, a distributed file system.

+

Nova

+

Nova is virtually a synonym for Compute. It is the part of the stack that can manage groups of virtual machines.

+

The virtualized systems can be distributed over any number of so-called compute nodes. Hypervisors supported include KVM, Xen Hyper-V and ESXI. In the community, KVM is considered to be set and best supported (we use KVM), which is controlled via libvirt. ESXI and Hyper-V can be used, sometimes with limited functionality.

+

Neutron

+

The OpenStack Networking module Neutron provides the networking service for OpenStack. Neutron can be used to manage networks, subnets, and IP addresses/floating IPs. A floating IP in OpenStack refers to an official IP that serves as an interface from the internal to the public network. In addition to a load balancer, HA proxy and health monitor, Neutron also supports techniques such as VLAN and VPN. To secure the networks, Neutron uses a firewall that allows versatile port rules, e.g. on a security group basis. For trademark reasons, the OpenStack networking module had to be renamed "Neutron". The previous name was "Quantum".

+

For the management of the data link layer, Neutron offers the possibility to use various already existing networking software such as Open vSwitch or the bridge functionality of the Linux kernel by means of plugins.

+

In the OpenStack releases since Ussuri, the "OpenVirtualNetwork"(OVN) has established itself, it replaces many of the Neutron components, e.g. L3 and DHCP agent, so that Neutron only has to talk directly to OVN.

+

Cinder

+

OpenStack Block Storage or Cinder provides virtual block storage in the form of virtualized storage media (hard disks, CDs, etc.). The block storage can be attached to virtual machines. An API interface allows Cinder to connect to Swift so that block storage media can communicate with object storage. Meanwhile, many other storage backends are also fully or partially supported. There is also the option of defining multiple backends and creating a volume type for each backend, so that when a new volume is created, it can be selected on which storage backend the volume is created.

+

Swift

+

Swift is the so-called object storage that can be used by Nova. This is responsible for redundant data storage. Swift can also be used as a backend for Cinder or Glance. Objects are stored in so-called containers, which are primarily used to group objects and store metadata and in turn belong to individual accounts. Objects and containers are accessed via a REST API.

+

Ceph OSD

+

A Ceph OSD (Object Storage Daemon) logically represents a storage device in a Ceph cluster, which can logically be a hard disk, which is the ideal case. In other cases it can also be a raid, which however leads to considerable performance limitations due to caching or other raid optimization.

+

Personas

+
PersonaDescription
SCS OperatorThe SCS Operator is the one who owns and operates a standardized cloud environment.
SCS Operations TeamThe team at the SCS Operator which actually runs the cloud environment.
SCS ConsumerThe SCS Consumer consumes a standardized SCS environment and operates and orchestrates applications on top of it. The SCS Consumer is typically a customer or user of the SCS Operator.
SCS IntegratorThe SCS Integrator assists in or is building up a standardized cloud environment. The SCS Integrator can be 2nd or 3rd level support for the SCS Operator.
SCS ProjectThe SCS Project oversees the overall activities around the Sovereign Cloud Stack.
SCS DeveloperThe SCS Developer actively contributes to technical elements of the Sovereign Cloud Stack.
+ + \ No newline at end of file diff --git a/docs/iaas/components/flavor-manager/index.html b/docs/iaas/components/flavor-manager/index.html new file mode 100644 index 0000000000..f759e8424b --- /dev/null +++ b/docs/iaas/components/flavor-manager/index.html @@ -0,0 +1,75 @@ + + + + + +Flavor Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Flavor Manager

+

Overview

+

The OpenStack Flavor Manager manages the creation, modification, and removal of flavors. +It operates as a facilitator that orchestrates compute flavors in alignment +with the standard SCS-0100: Flavor Naming +by utilizing YAML files provided by the SCS project.

+

Installation

+

The OpenStack Flavor Manager can be used via the OSISM CLI. This is the preferred way to use it. +No installation is then required. It is used via osism manage flavors.

+

For use independent of OSISM install the openstack-flavor-manager package with pip. It is likely +that additional dependencies such as pkg-config or libssl-dev must be installed in advance.

+
$ pip install openstack-flavor-manager
+

Or clone the repository osism/openstack-flavor-manager +and use the OpenStack Flavor Manager from source with tox.

+
$ tox -- --help
+

Usage

+

There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Flavor Manager +will be executed. When using the OSISM CLI, the files are expected in environments/openstack +in your configuration repository.

+

The cloud profile to be used can be specified via the optional --cloud parameter. +By default the cloud profile with the name admin is used. It must be possible to create and delete +flavors with the used cloud credentials.

+
$ openstack-flavor-manager --help

Usage: openstack-flavor-manager [OPTIONS]

╭─ Options ────────────────────────────────────────────────────────────────────────────────────╮
│ --name TEXT Name of flavor definitions. [default: scs] │
│ --debug Enable debug logging. │
│ --cloud TEXT Cloud name in clouds.yaml. [default: admin] │
│ --recommended Create recommended flavors. │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────╯
+

To create the mandatory flavors by the SCS-0100: Flavor Naming +standard, you run:

+
$ openstack-flavor-manager
+

To create the recommended flavors by the SCS Flavor Naming Standard, you run:

+
$ openstack-flavor-manager --recommended
+

The output should look like this:

+
2023-09-20 13:03:14 | INFO     | Flavor SCS-1V-4 created
2023-09-20 13:03:14 | INFO | Flavor SCS-2V-8 created
2023-09-20 13:03:14 | INFO | Flavor SCS-4V-16 created
2023-09-20 13:03:14 | INFO | Flavor SCS-8V-32 created
...
+

All recommended flavors are now be available in your OpenStack environment. +Check yourself by running:

+
$ openstack --os-cloud admin flavor list
+
$ openstack --os-cloud admin flavor show SCS-2V-4-20s
+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 0 |
| access_project_ids | None |
| description | None |
| disk | 20 |
| id | 652e3a6c-330e-4ee3-922b-b49c3c093062 |
| name | SCS-2V-4-20s |
| os-flavor-access:is_public | True |
| properties | hw_rng:allowed='true', scs:cpu-type='shared-core', scs:disk0-type='ssd', scs:name-v1='SCS-2V:4:20s', scs:name-v2='SCS-2V-4-20s' |
| ram | 4096 |
| rxtx_factor | 1.0 |
| swap | 0 |
| vcpus | 2 |
+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+
+

Definitions

+

There are two flavor definitions available by default. One for +SCS +and one for OSISM. +Each definition has its own set of mandatory and recommended flavors. The definition of OSISM contains +all definitions of SCS as well as some others.

+

To run the OpenStack Flavor Manager with a specific definition, either scs or osism, +use the optional --name parameter. By default the SCS-0100: Flavor Naming +standard definition will be used.

+
$ openstack-flavor-manager --name osism
+

Name parser and generator

+

A generator and parser for flavor names according to the SCS standard is available on +flavors.scs.community.

+

The flavor name SCS-2V-4-20s is inserted in field Flavor name:

+ +

The flavor SCS-2V-4-20s translated is +2 generic x86-64 vCPUs with 4.0 GiB RAM and SSD 20GB root volume:

+
+ + \ No newline at end of file diff --git a/docs/iaas/components/image-manager/index.html b/docs/iaas/components/image-manager/index.html new file mode 100644 index 0000000000..969d832fc1 --- /dev/null +++ b/docs/iaas/components/image-manager/index.html @@ -0,0 +1,165 @@ + + + + + +Image Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Image Manager

+

The OpenStack Image Manager is a tool for managing all +images on an OpenStack environment

+

Requirements

+

This information is only relevant for the operator of an OpenStack environment. You can skip this section if +you want to use OpenStack Image Manager as a normal user and you are not an operator of an openStack environment.

+

OpenStack Image Service (Glance)

+

The OpenStack Image Service (Glance) is required to upload and discover data assets that are used by other +services.

+

Since this script stores many images in a single project, the Glance quota must be set accordingly high or to unlimited.

+
[DEFAULT]
user_storage_quota = 1TB
+

With most storage backends it makes sense to convert the imported images directly to RAW. So it is required for using Ceph and it's +features too. Recited from the Ceph documentation QEMU and block devices and +Block devices and OpenStack.

+
info

The raw data format is really the only sensible format option to use with RBD. Technically, you could use other QEMU-supported formats +(such as qcow2 or vmdk), but doing so would add additional overhead, and would also render the volume unsafe for virtual machine live +migration when caching (see below) is enabled.

Important Ceph doesn't support QCOW2 for hosting a virtual machine disk. Thus if you want to boot virtual machines in Ceph (ephemeral +backend or boot from volume), the Glance image format must be RAW.

See the OpenStack Glance documentation +for more details.

+

This requires the following parameter for the image import workflow.

+
[taskflow_executor]
conversion_format = raw

[image_import_opts]
image_import_plugins = ['image_decompression', 'image_conversion']

[image_conversion]
output_format = raw
+

Object storage backend

+

If the mirror functionality is used, an object storage backend is required. The use of the mirror functionality +is optional and is not used by default.

+

Getting started

+

This Getting started will upload a private image to your OpenStack environment with +the help of the OpenStack Image Manager.

+
    +
  1. +

    Install the openstack-image-manager package with +pip.

    +
    pip3 install openstack-image-manager
    +

    The installation can also be done via pipenv.

    +

    A Pipefile file is created with this content. The latest version of openstack-image-manager +is used.

    +
    [[source]]
    url = "https://pypi.org/simple"
    verify_ssl = true
    name = "pypi"

    [packages]
    openstack-image-manager = "==0.20240403.0"

    [dev-packages]

    [requires]
    python_version = "3.10"
    +

    The dependencies are then installed and the shell is prepared for use:

    +
    pipenv install
    pipenv shell
    +
  2. +
  3. +

    Create a image definition in the file getting-started.yml in the local directory images.

    +
    ---
    images:
    - name: MyCirros
    enable: true
    format: qcow2
    login: cirros
    password: gocubsgo
    min_disk: 1
    min_ram: 32
    status: active
    visibility: private
    multi: false
    meta:
    architecture: x86_64
    hw_disk_bus: scsi
    hw_rng_model: virtio
    hw_scsi_model: virtio-scsi
    hw_watchdog_action: reset
    hypervisor_type: qemu
    os_distro: cirros
    replace_frequency: never
    uuid_validity: none
    provided_until: none
    tags: []
    versions:
    - version: '0.6.2'
    url: https://github.com/cirros-dev/cirros/releases/download/0.6.2/cirros-0.6.2-x86_64-disk.img
    checksum: "sha256:07e44a73e54c94d988028515403c1ed762055e01b83a767edf3c2b387f78ce00"
    build_date: 2023-05-30
    - version: '0.6.3'
    url: https://github.com/cirros-dev/cirros/releases/download/0.6.3/cirros-0.6.3-x86_64-disk.img
    checksum: "sha256:7d6355852aeb6dbcd191bcda7cd74f1536cfe5cbf8a10495a7283a8396e4b75b"
    build_date: 2024-09-26
    +
  4. +
  5. +

    Run the OpenStack Image Manager. It is assumed that a profile with the name openstack exists in the +clouds.yaml.

    +
    openstack-image-manager --cloud openstack --filter ".*Cirr.*" --images images/
    +
  6. +
+

Image definitions

+

The configuration consists of different parameter settings, such as values for +minimum RAM or the visibility of the image. Have a look at the examples below +for all parameters. After a change to the configuration, validate it with +tox -- --dry-run.

+

SCS image standard

+
    +
  • The value of login is stored as image_original_user in the metadata of an image.
  • +
  • If image_description is not set as meta information, image_description is set to the name of the image.
  • +
  • The value of build_date of a specific version of an image is stored as image_build_date in the metadata of an image.
  • +
  • The value of url of a specific version of an image is stored as image_source in the metadata of an image.
  • +
+

Image with regular rebuilds

+

This type of image definition is used for images that are rebuilt at regular +intervals. For example, this is the case for the daily builds of the Ubuntu +images.

+

The attribute multi: true is set.

+

With this type of image definition, the version of the distribution (or product, +whatever is contained in the image) used is already in the name of the image +definition. The version properties from the definition's versions list +are appended only to older iterations of the image as timestamp suffixes +in parentheses upon each rotation (except for the latest entry).

+
images:
- name: Ubuntu 24.04
format: qcow2
login: ubuntu
min_disk: 8
min_ram: 512
status: active
visibility: public
multi: true
meta:
architecture: x86_64
hw_disk_bus: scsi
hw_scsi_model: virtio-scsi
hw_watchdog_action: reset
os_distro: ubuntu
os_version: '24.04'
tags: []
versions:
- version: '20240416'
url: https://cloud-images.ubuntu.com/noble/20240416/noble-server-cloudimg-amd64.img
- version: '20240422'
url: https://cloud-images.ubuntu.com/noble/20240422/noble-server-cloudimg-amd64.img
+

This configuration creates the following images:

+
    +
  • Ubuntu 24.04 (20240416)
  • +
  • Ubuntu 24.04
  • +
+

If a newer build is added, the following rotation takes place:

+
    +
  • Ubuntu 24.04 (20240416) does not change
  • +
  • Ubuntu 24.04 becomes Ubuntu 24.04 (20240422)
  • +
  • the new image becomes Ubuntu 24.04
  • +
+

By default the last three images will be visible. When a fourth image is added, the visibility of +the last image in the list is changed to community and the image can be deleted in the future.

+

Image without regular rebuild

+

This type of image definition is used for images that are not rebuilt. For example, +this is the case for the flatcar images. For each release of Flatcar there is exactly +one image which will not be rebuilt in the future.

+

The attribute multi: false is set.

+

With this type of image definition, the version of the distribution (or product, +whatever is contained in the image) used is not in the name of the image definition. +Instead, the version properties from the image definition's versions list +are appended as static version suffixes to the images' names.

+
images:
- name: RancherOS
format: qcow2
login: rancher
min_disk: 8
min_ram: 2048
status: active
visibility: public
multi: false
meta:
architecture: x86_64
hw_disk_bus: scsi
hw_scsi_model: virtio-scsi
hw_watchdog_action: reset
tags: []
versions:
- version: '1.3.0'
url: https://github.com/rancher/os/releases/download/v1.3.0/rancheros-openstack.img
- version: '1.4.0'
url: https://github.com/rancher/os/releases/download/v1.4.0/rancheros-openstack.img
- version: '1.4.1'
url: https://github.com/rancher/os/releases/download/v1.4.1/rancheros-openstack.img
+

This configuration creates the following images:

+
    +
  • RancherOS 1.3.0
  • +
  • RancherOS 1.4.0
  • +
  • RancherOS 1.4.1
  • +
+

If a new version is added, no rotation takes place. The new version is added +as RancherOS x.y.z. Here also the visibility of older images is not changed.

+

Other properties

+

Image properties

+
    +
  • Removal of properties is not yet possible
  • +
  • URL, name and format can not be changed
  • +
  • Any keys can be added to meta, these will be added to the image
  • +
  • Existing keys in meta can be changed, the same applies to min_disk +and min_ram
  • +
+

Image tags

+

image status

+
    +
  • deactivation: change status to deactivated
  • +
  • reactivation: change status to active
  • +
+

Image visibility

+

A full documentation about the visibility of images can be found in the Image visibility section in the +OpenStack Image Service API Documentation.

+
    +
  • public: set visibility to public
  • +
  • community: set visibility to community
  • +
  • shared: set visibility to shared
  • +
  • private: set visibility to private
  • +
+

Usage

+

Mirroring images

+

Since the upstreams often only keep their images for a short time, we mirror most of the images on REGIO.cloud. +This makes us independent of the availability of the images in the individual upstreams.

+

Updating images

+

Some of the images are automatically updated by a CI job. The latest available build at the time of the CI job execution is mirrored and +made available as the current version.

+

Currently, the following images are updated once a week (every Sunday at 0 am):

+
    +
  • Almalinux
  • +
  • CentOS
  • +
  • Debian
  • +
  • Rockylinux
  • +
  • Ubuntu
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/components/image-manager/update/index.html b/docs/iaas/components/image-manager/update/index.html new file mode 100644 index 0000000000..63ca32206c --- /dev/null +++ b/docs/iaas/components/image-manager/update/index.html @@ -0,0 +1,46 @@ + + + + + +Image Manager update.py | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Image Manager update.py

+

Overview

+

The OpenStack Image Manager update.py Script updates the /etc/images/*.yaml files to the always latest release of the distributions, set S3 mirror URLs and uploads the images to the mirror.

+

These updated yaml files are later processed by the Image Manger itself.

+

Installation

+

Prepare to use the update.py script.

+
git clone https://github.com/osism/openstack-image-manager/
cd openstack-image-manager
pipenv install
pipenv shell
+

Usage

+
python contrib/update.py --help

Usage: update.py [OPTIONS]

╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --debug Enable debug logging │
│ --dry-run Do not perform any changes │
│ --minio-access-key TEXT Minio access key [env var: MINIO_ACCESS_KEY] [default: None] │
│ --minio-secret-key TEXT Minio secret key [env var: MINIO_SECRET_KEY] [default: None] │
│ --minio-server TEXT Minio server [env var: MINIO_SERVER] [default: swift.services.a.regiocloud.tech] │
│ --minio-bucket TEXT Minio bucket [env var: MINIO_BUCKET] [default: openstack-images] │
│ --swift-prefix TEXT Swift prefix [env var: SWIFT_PREFIX] [default: swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/] │
│ --install-completion Install completion for the current shell. │
│ --show-completion Show completion for the current shell, to copy it or customize the installation. │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+
note
    +
  • At this time the update.py expects all yaml files at /etc/images/, which can't be configured at the moment.
  • +
  • Mirroring can't be disabled at the moment.
  • +
+

Best run this script by cron or a CI job, to update all distribution files periodically to the latest release and afterwards run Openstack Image Manager. +The distribution image yaml files must exist before running the script, you can use the files from the Github repo at etc/images/ as template for your first run.

+
$ python contrib/update.py
2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/centos.yml
2024-04-24 09:29:44 | INFO | update_image:179 - Checking image CentOS Stream 9
2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-HEREBE\d+\.\dDRAGONS.x86_64.qcow2
2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cloud.centos.org/centos/9-stream/x86_64/images/CHECKSUM
2024-04-24 09:29:44 | INFO | get_latest_default:62 - Latest URL is now https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2
2024-04-24 09:29:44 | INFO | get_latest_default:63 - Latest filename is now CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2
2024-04-24 09:29:44 | INFO | update_image:192 - Checksum of current CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337
2024-04-24 09:29:44 | INFO | update_image:208 - Our checksum is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337
2024-04-24 09:29:44 | INFO | update_image:211 - Image CentOS Stream 9 is up-to-date, nothing to do
2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/debian.yml
2024-04-24 09:29:44 | INFO | update_image:179 - Checking image Debian 11
2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bullseye/latest/debian-11-genericcloud-amd64.raw
2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bullseye/latest/SHA512SUMS
2024-04-24 09:29:45 | INFO | update_image:192 - Checksum of current debian-11-genericcloud-amd64-20240211-1654.raw is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4
2024-04-24 09:29:45 | INFO | update_image:208 - Our checksum is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4
2024-04-24 09:29:45 | INFO | update_image:211 - Image Debian 11 is up-to-date, nothing to do
2024-04-24 09:29:45 | INFO | update_image:179 - Checking image Debian 12
2024-04-24 09:29:45 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.raw
2024-04-24 09:29:45 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS
2024-04-24 09:29:46 | INFO | update_image:192 - Checksum of current debian-12-genericcloud-amd64-daily-20240424-1727.raw is sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e
2024-04-24 09:29:46 | INFO | update_image:208 - Our checksum is sha512:5401f8c6361bb2a82c2c24b4b4606d95e77229152a80e61f9c613bc88e25de9257057d0ed68b0256b745c4059162a54970fe4a8daf456b2eb67b4f5db5c97fcc
2024-04-24 09:29:46 | INFO | update_image:229 - New values are {'version': '20240424', 'build_date': datetime.date(2024, 4, 24), 'checksum': 'sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e', 'url': 'https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240424-1727/debian-12-genericcloud-amd64-daily-20240424-1727.raw'}
2024-04-24 09:29:46 | INFO | main:300 - Processing file /etc/images/rockylinux.yml
2024-04-24 09:29:46 | INFO | update_image:179 - Checking image Rocky 9
2024-04-24 09:29:46 | INFO | update_image:182 - Latest download URL is https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2
2024-04-24 09:29:46 | INFO | update_image:185 - Getting checksums from https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2.CHECKSUM
2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current Rocky-9-GenericCloud.latest.x86_64.qcow2 is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651
2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651
2024-04-24 09:29:47 | INFO | update_image:211 - Image Rocky_9 is up-to-date, nothing to do
2024-04-24 09:29:47 | INFO | main:300 - Processing file /etc/images/ubuntu.yml
2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04
2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS
2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current jammy-server-cloudimg-amd64.img is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710
2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710
2024-04-24 09:29:47 | INFO | update_image:211 - Image Ubuntu_22.04 is up-to-date, nothing to do
2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04 Minimal
2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64.img
2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/minimal/releases/jammy/release/SHA256SUMS
2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current ubuntu-22.04-minimal-cloudimg-amd64.img is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65
2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65
2024-04-24 09:29:48 | INFO | update_image:211 - Image Ubuntu 22.04 Minimal is up-to-date, nothing to do
2024-04-24 09:29:48 | INFO | update_image:179 - Checking image Ubuntu 24.04
2024-04-24 09:29:48 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
2024-04-24 09:29:48 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/noble/current/SHA256SUMS
2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current noble-server-cloudimg-amd64.img is sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3
2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:d7ba8d5d1d073f2dc8351973bf4f35157c846a0ea6ee16fb2a9f45a78953e4a7
2024-04-24 09:29:48 | INFO | update_image:229 - New values are {'version': '20240423', 'build_date': datetime.date(2024, 4, 23), 'checksum': 'sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3', 'url': 'https://cloud-images.ubuntu.com/noble/20240423/noble-server-cloudimg-amd64.img'}
+

These yaml files are now extended with additional fields and the update.py will take care of the versions, checksum, url and build date to the latest release in the yaml file on every run.

+
    +
  • latest_checksum_url - URL of the distros checksum file
  • +
  • latest_url - URL of the distros latest image
  • +
  • mirror_url - URL of the Image File at the local S3 Mirror
  • +
+
someexample.yaml
---
images:
- name: Debian 12
enable: true
shortname: debian-12
format: qcow2
login: debian
min_disk: 8
min_ram: 512
status: active
visibility: public
multi: true
meta:
architecture: x86_64
hw_disk_bus: scsi
hw_rng_model: virtio
hw_scsi_model: virtio-scsi
hw_watchdog_action: reset
hypervisor_type: qemu
os_distro: debian
os_version: '12'
replace_frequency: quarterly
uuid_validity: last-3
provided_until: none
tags: []
latest_checksum_url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS
latest_url:
https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.qcow2
versions:
- build_date: 2024-04-11
checksum:
sha512:3d6f26616e2c8b705993ddef874232887cebe42f1e70fcc020827ac88e8990177d537d34538c71ae2afd3b8baca953fff71eaa7ef71e752e82532c93dcdca436
url:
https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240411-1714/debian-12-genericcloud-amd64-daily-20240411-1714.qcow2
mirror_url:
https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-images/debian-12/20240411-debian-12.qcow2
version: '20240411'

+ + \ No newline at end of file diff --git a/docs/iaas/components/index.html b/docs/iaas/components/index.html new file mode 100644 index 0000000000..65a44b91e8 --- /dev/null +++ b/docs/iaas/components/index.html @@ -0,0 +1,24 @@ + + + + + +Tools | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/components/openstack-health-monitor/index.html b/docs/iaas/components/openstack-health-monitor/index.html new file mode 100644 index 0000000000..5ebaf0b5a6 --- /dev/null +++ b/docs/iaas/components/openstack-health-monitor/index.html @@ -0,0 +1,306 @@ + + + + + +Setting up OpenStack health monitor on Debian | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Setting up OpenStack health monitor on Debian

+

Kurt Garloff, 2024-02-20

+

Intro

+

The development of openstack-health-monitor was done on openSUSE 15.x images, just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution.

+

Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here.

+

Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a successor project for the increasingly hard to maintain shell code, this may not be worth the trouble.

+

openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested. +The scenario is described in a bit more detail in the repository's README.md file.

+

The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the monitoring section of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up.

+

Setting up the driver VM

+

So we start a Debian 12 image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard; +the instructions use flavor names and image names from the SCS standards. +For many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack).

+

Internal vs external monitoring

+

There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor.

+

The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems.

+

Unprivileged operation

+

Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own.

+

If openstack availability zone list --compute fails for you without admin rights, please fix your openstack client, e.g. by applying the patch I mentioned in this issue. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Health-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)

+

Driver VM via openstack CLI

+

The author prefers to setup the VM via openstack CLI tooling. He has working entries for all clouds he uses in his ~/.config/openstack/clouds.yaml and secure.yaml and has exported the OS_CLOUD environment variable to point to the cloud he is working on to set up the driver VM. The author uses the bash shell. All of this of course could be scripted.

+

So here we go

+
    +
  1. Create the network setup for a VM in a network oshm-network with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network.
  2. +
+
PUBLIC=$(openstack network list --external -f value -c Name)
openstack router create oshm-router
openstack router set --external-gateway $PUBLIC oshm-driver-router
openstack network create oshm-network
openstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet
openstack router add subnet oshm-router oshm-subnet
+
    +
  1. Create a security group that allows ssh and ping access
  2. +
+
openstack security group create sshping
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping
openstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping
+
    +
  1. Being at it, we also create the security group for grafana
  2. +
+
openstack security group create grafana
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana
+
    +
  1. To connect to the VM via ssh later, we create an SSH keypair
  2. +
+
openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key
chmod og-r ~/.ssh/oshm-key.pem
+

Rather than creating a new key (and storing and protecting the private key), we could have passed --public-key and used an existing keypair.

+
    +
  1. Look up Debian 12 image UUID.
  2. +
+
IMGUUID=$(openstack image list --name "Debian 12" -f value -c ID | tr -d '\r')
echo $IMGUUID
+

Sidenote: The tr command is there to handle broken tooling that embeds a trailing \r in the output.

+
    +
  1. Boot the driver VM
  2. +
+
openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver
+

Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing --block-device. See diskless flavor blog article. For flavors with local root disks, you could have used the --image $IMGUUID parameter instead.

+
    +
  1. Wait for it to boot (optional) +You can look at the boot log with openstack console log show oshm-driver or connect to it via VNC at the URL given by openstack console url show oshm-driver. You can of course also query openstack on the status openstack server list or openstack server show oshm-driver. You can also just create a simple loop:
  2. +
+
declare -i ctr=0 RC=0
while [ $ctr -le 120 ]; do
STATUS="$(openstack server list --name oshm-driver -f value -c Status)"
if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi
if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi
if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi
sleep 2
let ctr+=1
done
# return $RC
if [ $RC != 0 ]; then false; fi
+
    +
  1. Attach a floating IP so it's reachable from the outside.
  2. +
+
FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks |  sed "s@^[^:]*:[^']*'\([0-9\.]*\)'.*\$@\1@")
FIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)
echo $FIXEDIP $FIXEDPORT
openstack floating ip create --port $FIXEDPORT $PUBLIC
FLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")
echo "Floating IP: $FLOATINGIP"
+

Remember this floating IP address.

+
    +
  1. Connect to it via ssh
  2. +
+
ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP
+

On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)

+

All the following commands are performed on the newly started driver VM.

+

Configuring openstack CLI on the driver VM

+

We need to install the openstack client utilities.

+
sudo apt-get update
sudo apt-get install python3-openstackclient
sudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient
+

Configure your cloud access in ~/.config/openstack/clouds.yaml

+
clouds:
CLOUDNAME:
interface: public
identity-api-version: 3
#region_name: REGION
auth:
auth_url: KEYSTONE_ENDPOINT
project_id: PROJECT_UUID
#alternatively project_name and project_domain_name
user_domain_name: default
# change to your real domain
+

and secure.yaml (in the same directory)

+
clouds:
CLOUDNAME:
auth:
username: USERNAME
password: PASSWORD
+

The CLOUDNAME can be freely chosen. This is the value passed to the openstack CLI with --os-cloud or exported to your environment in OS_CLOUD. The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample clouds.yaml file that works (but lacks the password).

+

Protect your secure.yaml from being read by others: chmod 0600 ~/.config/openstack/secure.yaml.

+

If you are using application credentials instead of username, password to authenticate, you don't need to specify project_id nor project's nor user's domain names in clouds.yaml. Just (in secure.yaml):

+
clouds:
CLOUDNAME:
auth_type: v3applicationcredential
auth:
application_credential_id: APPCRED_ID
application_credential_secret: "APPCRED_SECRET"
+

Configure this to be your default cloud:

+
export OS_CLOUD=CLOUDNAME
+

You might consider adding this to your ~/.bashrc for convenience. Being at it, you might want to add export CLIFF_FIT_WIDTH=1 there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste).

+

Verify that your openstack CLI works:

+
openstack catalog list
openstack server list
+

You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases.

+

Custom CA

+

If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in /etc/ssl/certs/ca-certificates.crt. You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the debian user.

+

Add it to your clouds.yaml

+
clouds:
CLOUDNAME:
cacert: /PATH/TO/CACERT.CRT
[...]
+

If you want to allow api_monitor.sh to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:

+
export OS_CACERT=/PATH/TO/CACERT.CRT
+

Consider adding this to your ~/.bashrc as well.

+

Your first api_monitor.sh iteration

+

Checkout openstack-health-monitor:

+
sudo apt-get install git bc jq netcat-traditional tmux zstd
git clone https://github.com/SovereignCloudStack/openstack-health-monitor
cd openstack-health-monitor
+

You may want to start a tmux (or screen) session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect.

+

The script api_monitor.sh is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the README.md file.

+

It is good practice to use tmux. This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to screen over tmux.

+

You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:

+
export IMG="Debian 12"
export JHIMG="Debian 12"
./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1
+

Leave out the -LL if you don't have a working loadbalancer service or replace -LL with -LO if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources).

+

Feel free to study the meaning of all the command line parameters by looking at the README.md. (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)

+

This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs DOWN, BUILD, creating are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual openstack RESOURCE list and openstack RESOURCE show NAME and RESOURCE being something like router, network, subnet, port, volume, server, floating ip, loadbalancer, loadbalancer pool, loadbalancer listener, security group, keypair, image, ...)

+

The api_monitor.sh uses and APIMonitor_TIMESTAMP prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong. +TIMESTAMP is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time).

+

This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least -N 2 to test the ability of the router to route traffic between networks. So expect -n 6 to become -N 2 -n 6 for a very small single-AZ cloud or -n 12 for a large 3 AZ cloud region. So, re-run the api_monitor.sh with the target sizing.

+

Resource impact and charging

+

Note that api_monitor.sh uses small flavors (SCS-1V-2 for the N jump hosts and SCS-1L-1 for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors.

+

If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run api_monitor.sh in a loop (which you will) with say 10 VMs (e.g. -N 2 -n 8) in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference.

+

Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of openstack volume list, openstack volume show BROKEN_VOLUME, openstack loadbalancer list, openstack loadbalancer show BROKEN_LB.)

+

Using -w -1 makes api_monitor.sh wait for interactive input whenever an error occurs; this can be convenient for debugging.

+

Once you have single iterations working nicely, we can proceed.

+

Automating startup and cleanup

+

Typically, we run api_monitor.sh with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here.

+
#!/bin/bash
# run_CLOUDNAME.sh
# Do some global settings
export IMG="Debian 12"
export JHIMG="Debian 12"
#export OS_CACERT=/home/debian/ca-certificates.pem
# Additional settings to override flavors or to
# configure email addresses for sending alarms can be set here

# Does openstack CLI work?
openstack server list >/dev/null || exit 1
# Upload log files to this swift container (which you need to create)
#export SWIFTCONTAINER=OS-HM-Logfiles

# CLEANUP
echo "Finding resources from previous runs to clean up ..."
# Find Floating IPs
FIPLIST=""
FIPS=$(openstack floating ip list -f value -c ID)
for fip in $FIPS; do
FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")
if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_
"; fi
done
FIPLIST=$(echo "$FIPLIST" | grep -v '^$' | sort -u)
# Cleanup previous interrupted runs
SERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)
KEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)
VOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)
NETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)
LOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)
ROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)
SECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)
echo CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS
for ENV in $FIPLIST; do
echo "******************************"
echo "CLEAN $ENV"
bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV
echo "******************************"
done
TOCLEAN=$(echo "$SERVERS
$KEYPAIR
$VOLUMES
$NETWORK
$LOADBAL
$ROUTERS
$SECGRPS
" | grep -v '^$' | sort -u)
for ENV in $TOCLEAN; do
echo "******************************"
echo "CLEAN $ENV"
bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV
echo "******************************"
done

# Now run the monitor
#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"
exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"
+

Compared to the previous run, we have explicitly set two networks here -N 2 and rely on the iterations being passed in as command line arguments. Add parameter -t if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (-LO) in this example rather than the amphora based one (-LL).

+

You may use one of the existing run_XXXX.sh scripts as example. Beware: eMail alerting with ALARM_EMAIL_ADDRESS and NOTE_EMAIL_ADDRESS (and limiting with -a and -R ) and reporting data to telegraf (option -S) may be present in the samples. Make this script executable (chmod +x run_CLOUDNAME.sh).

+

We wrap a loop around this in run_in_loop.sh:

+
#!/bin/bash
# run_in_loop.sh
rm stop-os-hm 2>/dev/null
while true; do
./run_CLOUDNAME.sh -i 200
if test -e stop-os-hm; then break; fi
echo -n "Hit ^C to abort ..."
sleep 15; echo
done
+

Also make this executable (chmod +x run_in_loop.sh). +To run this automatically in a tmux window whenever the system starts, we follow the steps in the startup README.md

+

Change OS_CLOUD in startup/run-apimon-in-tmux.sh. (If you need to set OS_CACERT, also add it in this file and pass it into the windows.)

+

Activate everything:

+
mkdir -p ~/.config/systemd/user/
cp -p startup/apimon.service ~/.config/systemd/user/
systemctl --user enable apimon
systemctl --user start apimon
sudo loginctl enable-linger debian
tmux attach -t oshealthmon
+

This assumes that you are using the user debian for this monitoring and have checked out the repository at ~/openstack-health-monitor/. Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)

+

Changing parameters and restarting

+

If you want to change the parameters passed to api_monitor.sh, you best do this by editing run_CLOUDNAME.sh, potentially after testing it with one iteration before.

+

To make the change effective, you can wait until the current 200 iterations are completed and the run_in_loop.sh calls run_CLOUDNAME.sh again. You can also hit ^C in the tmux window that hasapi_monitor.sh running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ^C during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ^C twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ./run_in_loop.sh again.

+

You can also issue the systemctl --user stop apimon command; it will basically do the same thing: Send ^C and then wait for everything to be completed and tear down the tmux session. +After waiting for that to complete, you can start it again with systemctl --user start apimon.

+

Multiple instances

+

You can run multiple instances of api_monitor.sh on the same driver VM. In this case, you should rename run_in_loop.sh to e.g. run_in_loop_CLOUDNAME1.sh and call run_CLOUDNAME1.sh from there. Don't forget to adjust startup/run-apimon-in-tmux.sh and startup/kill-apimon-in-tmux.sh to start more windows.

+

It is not recommended to run multiple instances against the same OpenStack project however. While the api_monitor.sh script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the run_CLOUDNAME.sh script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations.

+

Alarming and Logs

+

eMail

+

If wanted, the api_monitor.sh can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the -a N and -R options. In order to enable sending emails from the driver VM, it needs to have postfix (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly.

+

Once you have configured postfix, you can enable eMail notifications using the option -e. Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ALARM_EMAIL_ADDRESSES and NOTE_EMAIL_ADDRESSES environment variables to api_monitor.sh, e.g. by setting it in the run_CLOUDNAME.sh.

+

Log files

+

api_monitor.sh writes a log file with the name APIMonitor_TIMESTAMP.log. It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (TIMESTAMP is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)

+

Note that api_monitor.sh does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties.

+

The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable SWIFTCONTAINER has been set (in run_COULDNAME.sh) when starting api_monitor.sh. the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER

+

After the 200 iterations, a .psv file (pipe-separated values) is created Stats.STARTTIME-ENDTIME.psv (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured).

+

Data collection and dashboard

+

See https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md

+

Telegraf

+

To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:

+
sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key
echo "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list
sudo apt update
sudo apt -y install telegraf
+

In the config file /etc/telegraf/telegraf.conf, we enable

+
[[inputs.influxdb_listener]]
service_address = ":8186"

[[outputs.influxdb]]
urls = ["http://127.0.0.1:8086"]
+

and restart the service (sudo systemctl restart telegraf). +Enable it on system startup: sudo systemctl enable telegraf.

+

InfluxDB

+

We proceed to influxdb:

+
sudo apt-get install influxdb
+

In the configuration file /etc/influxdb/influxdb.conf, ensure that the http interface on port 8086 is enabled.

+
[http]
enabled = true
bind-address = ":8086"
+

Restart influxdb as needed with sudo systemctl restart influxdb. +Also enable it on system startup: sudo systemctl enable influxdb.

+

Add -S CLOUDNAME to your run_CLOUDNAME.sh script

+

You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter -S CLOUDNAME to the api_monitor.sh call in run_CLOUDNAME.sh. Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete).

+

Caddy (Reverse Proxy)

+

We're going to deploy Grafana behind Caddy as a reverse proxy. +Caddy is very easy to configure, comes with sensible defaults and can automatically provision TLS +certificates using Let's Encrypt.

+

Install Caddy

+

We follow https://caddyserver.com/docs/install#debian-ubuntu-raspbian to setup the stable APT repository:

+
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
+

And install Caddy:

+
sudo apt update
sudo apt install caddy
+

Ensure it's started and starts at boot with sudo systemctl enable --now caddy.

+

Allow HTTP traffic for oshm-driver

+

Caddy needs TCP port 80 opened to be able to process the Let's Encrypt HTTP challenge, so let's +configure an appropriate security group for oshm-driver:

+
openstack security group create http
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 80 http
openstack server add security group oshm-driver http
+

Configure Caddy

+

Create a file /etc/caddy/Caddyfile with the following contents:

+
https://health.YOURCLOUD.osba.sovereignit.cloud:3000 {
reverse_proxy localhost:3003
}
+

Replace health.YOURCLOUD.osba.sovereignit.cloud with your actual domain. +You can use a hostname of your liking, but Caddy will create TLS certificates for this host using +the HTTP challenge. +The sovereignit.cloud domain is controlled by the SCS project team and has been used for a number +of health mon instances.

+

Reload Caddy with sudo systemctl reload caddy. That's it.

+

You should now be able to access https://health.YOURCLOUD.sovereignit.cloud:3000 and see a proxy error +page because the Grafana service is not yet running (this is our next step). +The very first request will be a bit slower, because Caddy interacts with Let's Encrypt API to create +the TLS certificate behind the scenes.

+

Caddy logs can be accessed with sudo journalctl -u caddy.

+

Grafana

+

Install Grafana

+

We follow https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/ and setup the stable APT repository:

+
mkdir -p /etc/apt/keyrings
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
+

And install it:

+
sudo apt update
sudo apt -y install grafana
+

Basic config

+

The config file /etc/grafana/grafana.ini needs some adjustments.

+

We're going to deploy Grafana behind a reverse proxy (Caddy) and configure it as such.

+

Therefore, in the [server] section:

+
[server]
protocol = http
http_addr = 127.0.0.1
http_port = 3003
domain = health.YOURCLOUD.sovereignit.cloud
root_url = https://%(domain)s:3000/
+

Please replace health.YOURCLOUD.sovereignit.cloud with your actual domain.

+

Next, in the [security] section, set:

+
[security]
admin_user = admin
admin_password = SOME_SECRET_PASS
secret_key = SOME_SECRET_KEY
data_source_proxy_whitelist = localhost:8088 localhost:8086
cookie_secure = true
+

Please replace SOME_SECRET_PASS and SOME_SECRET_KEY with secure passwords (for example, you can use pwgen -s 20).

+

Finally, in the [users] section, set:

+
[users]
allow_sign_up = false
allow_org_create = false
+

The configuration file contains secrets and should be protected such that only root and group grafana +can read it:

+
sudo chown root:grafana /etc/grafana/grafana.ini
sudo chmod 0640 /etc/grafana/grafana.ini
+

We do the OIDC connection in the section [auth.github] later.

+

We can now restart the service: sudo systemctl restart grafana-server. +Being at it, also enable it on system startup: sudo systemctl enable grafana-server.

+

You should now be able to access your dashboard on https://health.YOURCLOUD.sovereignit.cloud:3000 and log in +via the configured username admin and your SOME_SECRET_PASS password.

+

Enable influx database in grafana

+

In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to http://localhost:8086 (despite this being the suggestion). Set the database name to telegraf. Save&test should succeed.

+

Importing the dashboard

+

Go to Home, Dashboards, New, Import. +Upload the dashboard .json file from the repository, user the Grafana-10 variant if you use Grafana 10 or newer.

+

In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.) +Save.

+

Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable).

+

No data displayed?

+

Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.

+

One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved.

+

Dashboard features

+

Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended.

+

The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously.

+

You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term.

+

GitHub OIDC Integration

+

The SCS providers do allow all GitHub users that belong to the SovereignCloudStack organization to get Viewer +access to the dashboards. +This allows to exchange experience and to get a feeling for the achievable stability. +(Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)

+

OIDC integration is achieved by adjusting the [auth.github] section in /etc/grafana/grafana.ini as follows:

+
[auth.github]
enabled = true
client_id = YOUR_CLIENT_ID
client_secret = YOUR_CLIENT_SECRET
allowed_organizations = ["SovereignCloudStack"]
role_attribute_path = "'Viewer'"
allow_assign_grafana_admin = false
skip_org_role_sync = true
+

This config maps all users to the Viewer role regardless of their role in the GitHub Org. +Please replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with the OAuth2 credentials that the SCS Org GitHub admins +provided to you. +Finally, don't forgot to restart Grafana with sudo systemctl restart grafana-server after adjusting the config.

+

More information can be found in the Grafana documentation for GitHub OAuth2.

+

Maintenance

+

The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained.

+

Unattended upgrades

+

It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See https://wiki.debian.org/UnattendedUpgrades. If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and Caddy/Grafana (port 3000).

+

If you use unattended-upgrades, you should review your settings in /etc/apt/apt.conf.d/50unattended-upgrades, +especially Unattended-Upgrade::Origins-Pattern. It controls which packages are upgraded. If you want Caddy to be +part of the automated updates, add an entry like the following:

+
Unattended-Upgrade::Origins-Pattern {
// ...
"origin=cloudsmith/caddy/stable";
};
+

(This corresponds to o=cloudsmith/caddy/stable in the output of apt-cache policy).

+

sshd setup

+

If you already use SSH keys to sign in to the driver VM, consider setting the following in your /etc/ssh/sshd_config +if not already set:

+
PasswordAuthentication no
+

Debian's openssh-server, by default, is also very open about its version, so you might consider disabling this via:

+
DebianBanner no
+

Updating openstack-health-monitor

+

You can just do a git update in the openstack-health-monitor directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ^C, see above in the restart section.

+

Backup

+

The system holds two things that you might consider valuable for long-term storage: +(1) The log files. These are compressed and uploaded to object storage if you enable the SWIFTCONTAINER setting, which probably means that these do not need any additional backing up then. +(2) The influx time series data. Back up the data in /var/lib/influxdb.

+

Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, clouds.yaml, etc. Be careful not to expose sensitive data by granting too generous access to your backed up files.

+

Troubleshooting

+

Debugging issues

+

In case there is trouble with your cloud, the normal course of action to analyze is as follows:

+
    +
  • Look at the dashboard (see above)
  • +
  • Connect to the driver VM and attach to the tmux session and look at the console output of api_monitor.sh
  • +
  • Analyze the logfile (locally on the driver VM or grab it from the object storage)
  • +
+

Analyzing failures

+

When VM instances are created successfully, but then end up in ERROR state, the api_monitor.sh does an explicit openstack server show, so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files.

+

Sometimes the VMs end up being ACTIVE as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail.

+

To gather more details, you can look at the console output openstack console log show VM (where VM is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ssh -i APIMonitor_XXXXX_JH.pem debian@FIP, whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP. Replace XXXXX with the number in your current APIMonitor prefix, FIP with the floating IP address of the responsible JumpHost and debian with the user name used by the images you boot. Use 223 to connect to the second VM in the network, 224 the third etc.

+

When logged in, look at /var/log/cloud-init-output.log and /var/log/cloud-init.log. You can find the metadata in /var/lib/cloud/instance/.

+

You will not have much time to look around -- the still running api_monitor.sh script does continue and clean things up again. So you might want to suspend it with ^Z (and continue it later with fg). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the run_CLOUDNAME.sh script as it would do cleanup against the running instance, but rather copy the api_monitor.sh command line from the bottom (without the exec), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach -w -1 to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work.

+

Cleaning things up

+

If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard).

+

There are a few things that may need support from a cloud admin:

+
    +
  • Volumes may end up permanently in a deleting or reserved state or may be in-use, attached to a VM that has long gone. The admin needs to set the state to error and then delete them.
  • +
  • Loadbalancers may end up in a PENDING_XXX state (XXX being CREATE, UPDATE or DELETE) without ever changing. This also needs the cloud admin to set the status to ERROR, so it can be cleaned up. amphorae are more prone to this than ovn LBs.
  • +
+

More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted.

+

The source of this document can be found in the SovereignCloudStack/openstack-health-monitor repository.

+

Author: SCS Community, License: CC by Attribution 4.0 International

+ + \ No newline at end of file diff --git a/docs/iaas/components/project-manager/index.html b/docs/iaas/components/project-manager/index.html new file mode 100644 index 0000000000..10f3e59802 --- /dev/null +++ b/docs/iaas/components/project-manager/index.html @@ -0,0 +1,87 @@ + + + + + +Project Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Project Manager

+

Overview

+

The OpenStack Project Manager manages the creation of Openstack Domains, Projects and Users.

+

Installation

+

Prepare to use the Openstack Project Manager.

+

During installation, ldap libraries are required under Linux; you should install libldap2-dev and libsasl2-dev beforehand.

+
git clone https://github.com/osism/openstack-project-manager
cd openstack-project-manager
pipenv install
pipenv shell
+

Defaults

+

create.py

+

The create.py command and his default options while executing the command.

+
 --admin-domain              default
--assign-admin-user true
--cloud admin
--create-admin-user true
--create-domain false
--create-user false
--domain-name-prefix true
--has-service-network false
--has-public-network true
--has-shared-images true
--internal-id unset
--random false
--managed-network-resources false
--name sandbox
--owner unset
--password unset
--password-length 16
--public-network public
--quota-class basic
--service-network-cidr unset
--quota-multiplier 1
--quota-multiplier-compute unset
--quota-multiplier-network unset
--quota-multiplier-storage unset
--quota-router 1
+

manage.py

+

The manage.py has also some defaults while executing and will touch all projects in your Openstack Cluster, if not --domain is used.

+
 --admin-domain        default
--assign-admin-user false
--classes etc/classes.yml
--domain unset
--dry-run false
--endpoints etc/endpoints.yml
--manage-endpoints false
--manage-homeprojects false
--name unset
+

Default Openstack Roles to users are set to member and load-balancer_member at this time, the behavior can only be changed in the code.

+

Usage

+

There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Project Manager will be executed, examples are provided within the git repository.

+

The cloud profile to be used can be specified via the optional --cloud parameter. By default the cloud profile with the name admin is used. It has to be and admin account, to create and modify domains, projects, users and quotas.

+

The Openstack Project Manager essentially consists of two parts, the create.py and the manage.py, there are more scripts for handling users using ldap which needs more configuration setup.

+

create.py

+

This command is used to create and modify domains, projects, users and quotas. As default the domain is used as prefix for all projects and users created for easy alloction in Openstack.

+
note

create.py can't delete once created objects, this must be done using Openstack commands to remove a project or domain.

+
python src/create.py -h
usage: create [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--create-admin-user] [--create-domain] [--create-user]
[--domain DOMAIN] [--domain-name-prefix] [--has-public-network] [--has-service-network] [--has-shared-images] [--internal-id INTERNAL_ID] [--managed-network-resources] [--name NAME]
[--noassign-admin-user] [--nocreate-admin-user] [--nocreate-domain] [--nocreate-user] [--nodomain-name-prefix] [--nohas-public-network] [--nohas-service-network]
[--nohas-shared-images] [--nomanaged-network-resources] [--norandom] [--owner OWNER] [--password PASSWORD] [--password-length PASSWORD_LENGTH] [--public-network PUBLIC_NETWORK]
[--quota-class QUOTA_CLASS] [--quota-multiplier QUOTA_MULTIPLIER] [--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE] [--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK]
[--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE] [--quota-router QUOTA_ROUTER] [--random] [--service-network-cidr SERVICE_NETWORK_CIDR]

options:
-h, --help show this help message and exit
--admin-domain ADMIN_DOMAIN
Admin domain
--assign-admin-user Assign admin user
--cloud CLOUD Managed cloud
--config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set
is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the
command-line.
--config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the
command-line.
--create-admin-user Create admin user
--create-domain Create domain only
--create-user Create user
--domain DOMAIN Domain
--domain-name-prefix Add domain name as prefix to the project name
--has-public-network Has public network infrastructure
--has-service-network
Has service network infrastructure
--has-shared-images Has shared images
--internal-id INTERNAL_ID
Internal ID
--managed-network-resources
Manage the network resources
--name NAME Projectname
--noassign-admin-user
The inverse of --assign-admin-user
--nocreate-admin-user
The inverse of --create-admin-user
--nocreate-domain The inverse of --create-domain
--nocreate-user The inverse of --create-user
--nodomain-name-prefix
The inverse of --domain-name-prefix
--nohas-public-network
The inverse of --has-public-network
--nohas-service-network
The inverse of --has-service-network
--nohas-shared-images
The inverse of --has-shared-images
--nomanaged-network-resources
The inverse of --managed-network-resources
--norandom The inverse of --random
--owner OWNER Owner of the project
--password PASSWORD Password
--password-length PASSWORD_LENGTH
Password length
--public-network PUBLIC_NETWORK
Public network
--quota-class QUOTA_CLASS
Quota class
--quota-multiplier QUOTA_MULTIPLIER
Quota multiplier
--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE
Quota multiplier compute
--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK
Quota multiplier network
--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE
Quota multiplier storage
--quota-router QUOTA_ROUTER
Quota router
--random Generate random names
--service-network-cidr SERVICE_NETWORK_CIDR
Service network CIDR
+

Create a Domain and inital project

+

When executing the create.py command, the first time with --domain, it will create a new domain, an admin account and the first project webshop. The admin account will be created in the default Domain of Openstack and can be used for the Service Provider to manager the complete domain.

+
$ python3 src/create.py --domain democompany --name webshop
+----------------+----------------------+----------------------------------+
| name | value | id |
|----------------+----------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-webshop | 645538bf67664cfeaed32476d58f95fb |
| admin | democompany-admin | cc8d6bf7b61d4199ba5a4230c4ec6d62 |
| admin_password | qawsEdfg2d45Fsxc | |
+----------------+----------------------+----------------------------------+
+

Create a User for a project

+
$ python3 src/create.py --domain democompany --name webshopuser --create-user             
+----------+-------------------------+----------------------------------+
| name | value | id |
|----------+-------------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-webshop | 5752b6701026478f9cac122fc54eb9cb |
| user | democompany-webshopuser | ce213655559d47d7800501124fed4d02 |
| password | vEvM9vgRESdffWE2 | |
+----------+-------------------------+----------------------------------+
+

Create additional project with unlimited quota

+
$ python3 src/create.py --domain democompany --name styles --quota-class unlimited
+----------+--------------------+----------------------------------+
| name | value | id |
|----------+--------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-styles | 666097e396fd4f9392d6aa55c76d8267 |
+----------+--------------------+----------------------------------+
+

Set quotas for a project

+

All quota information must be set as a property to the Openstack project within your Openstack Cluster, if no property is set, the basic quotaclass of etc/classes.yml will be applied. +It is possible to set a quota multiplier for any project.

+

The following command you set a multiplier of 256 of the basic quota:

+
$ openstack project set --property quotamultiplier=256 democompany-webshop
+

Adjusting gigabyte quota for storage with a multiplier of 20 of the basic quota for a project:

+
$ openstack project set  --property quotamultiplier_storage=20 democompany-webshop
+

This will override the general quotamultiplier only for storage.

+

Other possible multiplier which can be set individually are: quotamultiplier_compute, quotamultiplier_network, quota_router

+

To change the quotaclass to unlimited from the etc/classes.yaml

+
$ openstack project set  --property quotaclass=unlimited democompany-webshop
+

Special project: images

+

With this special Project you can share all images uploaded into this project to all other project in your domain which has set the property has-shared-images, which is by default set. +Alsoi only the domain-admin user has access to this project, other domain users won't see this, they will find the uploaded images in their projects. +If you want your grant other domain users also access to upload some images, you need to give them access to the images Project in Openstack.

+
$ python3 src/create.py --domain democompany --name images
+---------+---------------------+----------------------------------+
| name | value | id |
|---------+---------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-images | 6d57f39aacbe485d87733865b1e79d03 |
+---------+---------------------+----------------------------------+
+

Additionally you need to add the domain and domain-admin user to the clouds.yaml, it is always named opm-domainname-admin: so the manage.py can setup permissions to the projects later on and users are able to find the images.

+
  opm-democompany-admin:
auth:
auth_url: https://keystone.my.cloud:5000/v3
username: democompany-admin
password: yourpassword
user_domain_name: Default
project_domain_name: democompany
identity_api_version: 3
+

Special project: service

+

With this special project you can share installed services, like a harbor, to all other projects in your domain. Per default, only the domain admin has access to this project.

+
$ python3 src/create.py --domain democompany --name service
+---------+---------------------+----------------------------------+
| name | value | id |
|---------+---------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-service | a5558f7338f94adea5f41858636256b5 |
+---------+---------------------+----------------------------------+
+

manage.py

+
warning

This command applies quotas, networks and routers to all projects in the Openstack Cluster, not only to those have been configured previously with the create.py or openstack project set --property commands.

+

Best is to run this command by cron, every hour to apply all pending changes, it is also possible to run this at the command line to apply changes immediately.

+
python3 src/manage.py -h
usage: manage [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--classes CLASSES] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--domain DOMAIN] [--dry-run]
[--endpoints ENDPOINTS] [--manage-endpoints] [--manage-homeprojects] [--name NAME] [--noassign-admin-user] [--nodry-run] [--nomanage-endpoints] [--nomanage-homeprojects]

options:
-h, --help show this help message and exit
--admin-domain ADMIN_DOMAIN
Admin domain
--assign-admin-user Assign admin user
--classes CLASSES Path to the classes.yml file
--cloud CLOUD Cloud name in clouds.yaml
--config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set
is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the
command-line.
--config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the
command-line.
--domain DOMAIN Domain to be managed
--dry-run Do not really do anything
--endpoints ENDPOINTS
Path to the endpoints.yml file
--manage-endpoints Manage endpoints
--manage-homeprojects
Manage home projects
--name NAME Project to be managed
--noassign-admin-user
The inverse of --assign-admin-user
--nodry-run The inverse of --dry-run
--nomanage-endpoints The inverse of --manage-endpoints
--nomanage-homeprojects
The inverse of --manage-homeprojects
+

Manage a specific domain only

+
$ python3 src/manage.py --domain democompany

2024-04-19 14:24:02.873 | INFO | democompany - domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03
2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03, domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:04.953 | INFO | democompany-images - quotaclass {'compute': {'cores': 0, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 0, 'key_pairs': 0, 'metadata_items': 128, 'ram': 0, 'server_group_members': 0, 'server_groups': 0}, 'network': {'floatingip': 0, 'network': 0, 'port': 0, 'rbac_policy': 0, 'router': 0, 'security_group': 0, 'security_group_rule': 0, 'subnet': 0, 'subnetpool': 0}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 1000, 'per_volume_gigabytes': 25, 'snapshots': 0, 'volumes': 100}, 'parent': 'default'}
2024-04-19 14:24:04.953 | INFO | democompany-images - check network quota
2024-04-19 14:24:05.048 | INFO | democompany-images - check compute quota
2024-04-19 14:24:05.175 | INFO | democompany-images - check volume quota
2024-04-19 14:24:05.286 | INFO | democompany-images - check if external rbac policy must be deleted (public)
2024-04-19 14:24:05.349 | INFO | democompany-images - check if service rbac policy must be deleted (democompany-service)
2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5
2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5, domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:06.131 | INFO | democompany-service - quotaclass {'compute': {'cores': 256, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 256, 'key_pairs': 256, 'metadata_items': 128, 'ram': 262144, 'server_group_members': 256, 'server_groups': 256}, 'network': {'floatingip': 256, 'network': 256, 'port': 256, 'rbac_policy': 1024, 'router': 256, 'security_group': 256, 'security_group_rule': 1024, 'subnet': 256, 'subnetpool': 256}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 0, 'per_volume_gigabytes': 0, 'snapshots': 0, 'volumes': 0}, 'parent': 'default'}
2024-04-19 14:24:06.131 | INFO | democompany-service - check network quota
2024-04-19 14:24:06.212 | INFO | democompany-service - check compute quota
2024-04-19 14:24:06.330 | INFO | democompany-service - check volume quota
2024-04-19 14:24:06.467 | INFO | democompany-service - check if external rbac policy must be created (public)
2024-04-19 14:24:06.589 | INFO | democompany-service - check if service rbac policy must be deleted (democompany-service)
2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb
2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb, domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:06.915 | INFO | democompany-webshop - quotaclass {'compute': {'cores': 4, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': -1, 'key_pairs': 4, 'metadata_items': 128, 'ram': 8192, 'server_group_members': 4, 'server_groups': 4}, 'network': {'floatingip': 4, 'network': 1, 'port': 20, 'rbac_policy': 10, 'router': 0, 'security_group': 5, 'security_group_rule': 20, 'subnet': 2, 'subnetpool': 1}, 'volume': {'backup_gigabytes': 40, 'backups': 8, 'gigabytes': 20, 'per_volume_gigabytes': 200, 'snapshots': 4, 'volumes': 4}, 'parent': 'default'}
2024-04-19 14:24:06.915 | INFO | democompany-webshop - check network quota
2024-04-19 14:24:06.993 | INFO | democompany-webshop - check compute quota
2024-04-19 14:24:07.114 | INFO | democompany-webshop - check volume quota
2024-04-19 14:24:07.254 | INFO | democompany-webshop - check if external rbac policy must be created (public)
2024-04-19 14:24:07.334 | INFO | democompany-webshop - check if service rbac policy must be deleted (democompany-service)
+

Config files

+

The config files which can be used for create.py and manage.py are using the oslo.config format, you can set the command line options as key = value pair and create your own config files matching your setup.

+
democompany.conf
[DEFAULT]
cloud = admin
domain = democompany
+

Quota Templates

+

Edit the etc/classes.yml file if you want to change or add new quota templates

+

Setup Endpoints

+

Edit the etc/endpoints.yml file to fit your available endpoints

+ + \ No newline at end of file diff --git a/docs/iaas/components/resource-manager/index.html b/docs/iaas/components/resource-manager/index.html new file mode 100644 index 0000000000..c1b3c53609 --- /dev/null +++ b/docs/iaas/components/resource-manager/index.html @@ -0,0 +1,44 @@ + + + + + +Resource Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Resource Manager

+

Preparations

+

Prepare use of the OpenStack Resource Manager.

+
git clone https://github.com/osism/openstack-resource-manager
cd openstack-resource-manager
pipenv install
pipenv shell
+

Prepare cloud profile admin in clouds.yml and secure.yml (use clouds.yml.sample and secure.yml.sample +in the openstack-resource-manager repository as sample files).

+

Nova

+

Live migration

+

Live migrate all instances from compute node SOURCE to compute node TARGET.

+
python3 src/host-action.py --yes --disable --action live-migrate --host SOURCE --input TARGET
+

Evacuation

+

Evacuate all instances from compute node SOURCE to compute node TARGET.

+
python3 src/host-action.py --yes --action evacutate --host SOURCE --input TARGET
+

Octavia

+

Amphora rotation

+

Rotation of amphorae older than 30 days.

+
$ python3 src/amphora.py --rotate
2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa is older than 30 days
2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa of loadbalancer 9008d3d7-f593-4bc3-941c-a740c178148d is rotated by a loadbalancer failover
+

Cinder

+
$ python3 src/volume.py
2023-12-11 23:09:44 | INFO | Volume ad848454-ba1f-4c28-b9a8-edada17948b0 hangs in CREATING status for more than 2 hours
Delete volume ad848454-ba1f-4c28-b9a8-edada17948b0 [yes/no]:
+

Orphans

+
$ python3 src/orphan.py
2023-12-11 23:11:16 | INFO | Checking nova / server
2023-12-11 23:11:21 | INFO | Checking neutron / port
2023-12-11 23:11:23 | INFO | Checking neutron / router
2023-12-11 23:11:23 | INFO | Checking neutron / network
2023-12-11 23:11:24 | INFO | Checking neutron / subnet
2023-12-11 23:11:24 | INFO | Checking neutron / floatingip
2023-12-11 23:11:24 | INFO | Checking neutron / rbacpolicy
2023-12-11 23:11:24 | INFO | Checking neutron / securitygroup
2023-12-11 23:11:26 | INFO | Checking neutron / securitygrouprule
2023-12-11 23:11:27 | INFO | Checking glance / image
2023-12-11 23:11:30 | INFO | Checking glance / imagemember
[...]
+---------------+-------------------+--------------------------------------+----------------------------------+
| servicename | resourcename | resource_id | project_id |
|---------------+-------------------+--------------------------------------+----------------------------------|
| neutron | port | 561f8f76-18b0-470a-92cd-4336346b4b18 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | port | 6d1986e4-1e6d-4d4a-961d-97d372945bb1 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | port | 74f9bddc-9bfa-4d06-a147-ca87127e501e | 8268b05ef24b41d8806c0fe417576610 |
| neutron | port | f630a66b-7725-4a68-868b-caebbaf1c003 | 8268b05ef24b41d8806c0fe417576610 |
| neutron | router | c0c4e4aa-53ee-4fd1-8f53-84d52cf6c60b | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | router | c8f9a13b-adcd-4a8e-942b-338bcf4dde7c | 8268b05ef24b41d8806c0fe417576610 |
| neutron | network | 62d6ad2a-0cda-4d45-9325-963b8eb67000 | 8268b05ef24b41d8806c0fe417576610 |
| neutron | network | 63b8fea6-7d7b-40c3-9c31-bee4404a92d6 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | subnet | 0cd16262-330a-44ad-9160-daef84aded2d | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | subnet | 690dee14-ac12-464d-a911-a873c27ec818 | d33b0d15fd474131a335207216297a2a |
| neutron | subnet | 854e7c55-62e2-4679-9b18-805460b998ce | 8268b05ef24b41d8806c0fe417576610 |
| neutron | rbacpolicy | 00d7c2a2-6674-4f40-9f95-176a7858fcca | c8e4393b6d064a26a31014f82939172f |
| neutron | rbacpolicy | 0608c701-5b81-4712-989b-ba03cdcc255d | c8e4393b6d064a26a31014f82939172f |
[...]
| neutron | securitygrouprule | fd3c553f-168e-4c24-ab40-09aa934bab86 | 3a96207b719643ae9ea9a81d95116e9e |
| neutron | securitygrouprule | fdf337be-971c-4d5d-88ca-d90cdb468e88 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | securitygrouprule | ff8162fe-f053-49c9-8659-078061ce3e23 | d0b0add9ede0452791f71cb900e35242 |
| glance | imagemember | c7f2cb0c25d34c5d886ecaf483e5fda6 | c7f2cb0c25d34c5d886ecaf483e5fda6 |
| glance | imagemember | d4d0a161f9024fc8b517b0375eb97c89 | d4d0a161f9024fc8b517b0375eb97c89 |
| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |
| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |
| glance | imagemember | d33b0d15fd474131a335207216297a2a | d33b0d15fd474131a335207216297a2a |
| cinder | volume | e7c4b05c-b76a-40cc-8381-03262e57eb94 | 9b5f7f8ed70d410c81e3f45bf4e36498 |
+---------------+-------------------+--------------------------------------+----------------------------------+
+ + \ No newline at end of file diff --git a/docs/iaas/components/sandbox-manager/index.html b/docs/iaas/components/sandbox-manager/index.html new file mode 100644 index 0000000000..c41d9fcdda --- /dev/null +++ b/docs/iaas/components/sandbox-manager/index.html @@ -0,0 +1,24 @@ + + + + + +Sandbox Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/components/simple-stress/index.html b/docs/iaas/components/simple-stress/index.html new file mode 100644 index 0000000000..c960197ea6 --- /dev/null +++ b/docs/iaas/components/simple-stress/index.html @@ -0,0 +1,49 @@ + + + + + +Simple Stress | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Simple Stress

+

Overview

+

The OpenStack Simple Stress is a small stress test for your Openstack Cluster. You can use it for burnin tests or if you want to monitor your cluster perfomance. +It is able to start a predefined amount of Servers in specific networks in parallel and serial and removes them afterwards, so you can test your environment to the limits.

+

Installation

+

Prepare to use the Openstack Simple Stress.

+
git clone https://github.com/osism/openstack-simple-stress
cd openstack-simple-stress
pipenv install
pipenv shell
+

Defaults

+

The main.py command and the default options while executing the command.

+
 --cleanup       true
--cloud simple-stress
--compute-zone nova
--debug false
--delete true
--flavor SCS-2V-8
--floating false
--image Ubuntu 22.04
--interval 10 (seconds)
--keypair unset
--network simple-stress
--network-zone nova
--number 1
--parallel 1
--prefix simple-stress
--storage-zone simple-stress
--timeout 600 (seconds)
--volume false
--volume-number 1
--volume-size 1 (gigabyte)
--wait true
+

Usage

+

There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Simple Stress will be executed, examples are provided within the git repository.

+

The cloud profile to be used can be specified via the optional --cloud parameter. By default, the cloud profile with the name simple-stress is used.

+
$ python src/main.py -h
usage: main [-h] [--cleanup] [--cloud CLOUD] [--compute-zone COMPUTE_ZONE] [--config-dir DIR]
[--config-file PATH] [--debug] [--delete] [--flavor FLAVOR] [--floating] [--image IMAGE]
[--interval INTERVAL] [--keypair KEYPAIR] [--network NETWORK] [--network-zone NETWORK_ZONE]
[--nocleanup] [--nodebug] [--nodelete] [--nofloating] [--novolume] [--nowait]
[--number NUMBER] [--parallel PARALLEL] [--prefix PREFIX] [--storage-zone STORAGE_ZONE]
[--timeout TIMEOUT] [--volume] [--volume-number VOLUME_NUMBER] [--volume-size VOLUME_SIZE]
[--wait]

options:
-h, --help show this help message and exit
--cleanup
--cloud CLOUD Cloud name
--compute-zone COMPUTE_ZONE
Compute availability zone to use
--config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted,
so as to provide a predictable parse order if individual options are over-
ridden. The set is parsed after the file(s) specified via previous --config-
file, arguments hence over-ridden options in the directory take precedence. This
option must be set from the command-line.
--config-file PATH Path to a config file to use. Multiple config files can be specified, with
values in later files taking precedence. Defaults to None. This option must be
set from the command-line.
--debug
--delete
--flavor FLAVOR
--floating
--image IMAGE
--interval INTERVAL
--keypair KEYPAIR
--network NETWORK
--network-zone NETWORK_ZONE
Network availability zone to use
--nocleanup The inverse of --cleanup
--nodebug The inverse of --debug
--nodelete The inverse of --delete
--nofloating The inverse of --floating
--novolume The inverse of --volume
--nowait The inverse of --wait
--number NUMBER
--parallel PARALLEL
--prefix PREFIX
--storage-zone STORAGE_ZONE
Storage availability zone to use
--timeout TIMEOUT
--volume
--volume-number VOLUME_NUMBER
--volume-size VOLUME_SIZE
--wait
+

Running a small and simple test on your Openstack environment, using Ubuntu_22.04 image with the flavor of 2VCPUs and 8Gigabytes of RAM, starting 6 servers, 2 parallel each with a volume size of 20Gigabytes.

+
$ python src/main.py --network test-net --flavor SCS-2V-8 --image Ubuntu_22.04 --number 6 --parallel 2 --volume-size 20
2024-04-23 11:47:16 | INFO | Checking flavor SCS-2V-8
2024-04-23 11:47:17 | INFO | flavor.id = 926f952f-0714-4c55-92c2-7514191fecce
2024-04-23 11:47:17 | INFO | Checking image Ubuntu_22.04
2024-04-23 11:47:17 | INFO | image.id = 667649d6-e828-403b-8871-15dde7b9ce85
2024-04-23 11:47:17 | INFO | Checking network test-net
2024-04-23 11:47:18 | INFO | network.id = 9688192e-11dd-4618-a18c-99d3267f630a
2024-04-23 11:47:18 | INFO | Creating server simple-stress-0
2024-04-23 11:47:18 | INFO | Creating server simple-stress-1
2024-04-23 11:47:18 | INFO | Waiting for server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:18 | INFO | Waiting for server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:28 | INFO | Waiting for boot / test results of 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:29 | INFO | Waiting for boot / test results of e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:39 | INFO | Deleting server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:39 | INFO | Waiting for deletion of server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:39 | INFO | Deleting server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:40 | INFO | Waiting for deletion of server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:49 | INFO | Creating server simple-stress-2
2024-04-23 11:47:50 | INFO | Creating server simple-stress-3
2024-04-23 11:47:50 | INFO | Waiting for server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:47:51 | INFO | Waiting for server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:00 | INFO | Waiting for boot / test results of 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:48:01 | INFO | Waiting for boot / test results of a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:11 | INFO | Deleting server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:12 | INFO | Waiting for deletion of server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:12 | INFO | Deleting server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:48:12 | INFO | Waiting for deletion of server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:48:22 | INFO | Creating server simple-stress-4
2024-04-23 11:48:22 | INFO | Waiting for server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:22 | INFO | Creating server simple-stress-5
2024-04-23 11:48:23 | INFO | Waiting for server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:48:55 | INFO | Deleting server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:55 | INFO | Deleting server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:48:55 | INFO | Waiting for deletion of server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:55 | INFO | Waiting for deletion of server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:49:05 | INFO | Server 049bf974-b0fd-467f-aabd-3593b2a409a4 finished
2024-04-23 11:49:05 | INFO | Server e485697f-feae-458c-952d-000072374c3f finished
2024-04-23 11:49:05 | INFO | Server a098cc12-94ff-4036-bf42-4fc08287809f finished
2024-04-23 11:49:05 | INFO | Server 26595dd3-09d4-4758-8d1f-58a40b681d11 finished
2024-04-23 11:49:05 | INFO | Server 05b9f996-5a06-4359-b495-3463cc7b81e0 finished
2024-04-23 11:49:05 | INFO | Server 8d372de6-ca07-4afb-9e80-1589fd5242e8 finished
2024-04-23 11:49:05 | INFO | Runtime: 107.4460s
+

Using a config directory with configfiles to run the test.

+

Path to a config directory to pull *.conf files from. This file set is sorted, +so as to provide a predictable parse order if individual options are over-ridden. +The set is parsed after the file(s) specified via previous --config file, +arguments hence over-ridden options in the directory take precedence. This +option must be set from the command-line.

+
python src/main.py --config-dir /path/to/config-dir
+

Config files

+

The config files which can be used for main.py are using the oslo.config format, you can set the command line options as key = value pair and create your own config files matching your setup.

+
mytest.conf
[DEFAULT]
cloud = simple-stress
network = test-net
number = 6
parallel = 2
flavor = SCS-2V-8
image = Ubuntu_22.04
volume-size = 20
+ + \ No newline at end of file diff --git a/docs/iaas/deployment-examples/artcodix/index.html b/docs/iaas/deployment-examples/artcodix/index.html new file mode 100644 index 0000000000..93f0ccc09f --- /dev/null +++ b/docs/iaas/deployment-examples/artcodix/index.html @@ -0,0 +1,157 @@ + + + + + +artcodix | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

artcodix

+

Preface

+

This document describes a possible environment setup for a pre-production or minimal production setup. +In general hardware requirements can vary largely from environment to environment and this guide is not +a hardware sizing guide nor the best placement solution of services for every setup. This guide intends to +provide a starting point for a hardware based deployment of the SCS-IaaS reference implementation based on OSISM.

+

Node type definitions

+

Control Node

+

A control node runs all or most of the openstack services, that are responsible for API-services and the corresponding +runtimes. These nodes are necessary for any user to interact with the cloud and to keep the cloud in a managed state. +However these nodes are usualy not running user virtual machines. +Hence it is advisable to have the control nodes replicated. To have a RAFT-quorum three nodes are a good starting point.

+

Compute Node (HCI/no HCI)

+

Not Hyperconverged Infrastructure (no HCI)

+

Non HCI compute nodes are exclusively running user virtual machines. They are running no API-services, no storage daemons +and no network routers, except for the necessary network infrastructure to connect virtual machines.

+

Hyperconverged Infrastructure (HCI)

+

HCI nodes generally run at least user virtual machines and storage daemons. It is possible to place networking services +here as well but that is not considered good practice.

+

No HCI / vs HCI

+

Whether to use HCI nodes or not is in general not an easy question. For a getting started (pre production/smalles possible production) +environment however, it is the most cost efficent option. Therefore we will continue with HCI nodes (compute + storage).

+

Storage Node

+

A dedicated storage node runs only storage daemons. This can be necessary in larger deployments to protect the storage daemons from +ressource starvation through user workloads.

+

Not used in this setup.

+

Network Node

+

A dedicated network node runs the routing infrastructure for user virtual machines that connects these machines with provider / external +networks. In larger deployments these can be useful to enhance scaling and improve network performance.

+

Not used in this setup.

+

Nodes in this deployment example

+

As mentioned before we are running three dedicated control nodes. To be able to fully test an openstack environment it is +recommended to run three compute nodes (HCI) as well. Technically you can get a setup running with just one compute node. +See the following chapter (Use cases and validation) for more information.

+

Use cases and validation

+

The setup described allows for the following use cases / test cases:

+
    +
  • Highly available control plane +
      +
    • Control plane failure toleration test (Database, RabbitMQ, Ceph Mons, Routers)
    • +
    +
  • +
  • Highly available user virtual clusters (e.g. Kubernetes clusters) +
      +
    • Compute host failure simulation
    • +
    +
  • +
  • Host aggregates / compute node grouping
  • +
  • Host based storage replication (instead of OSD based) +
      +
    • Fully replicated storage / storage high availability test
    • +
    +
  • +
+

Control Node

+

General requirements

+

The control nodes do not run any user workloads. This means they are usually not sized as big as the compute nodes. +Relevant metrics for control nodes are:

+
    +
  • Fast and big enough discs. At least SATA-SSDs are recommended, NVMe will greatly improve the overall responsiveness.
  • +
  • A rather large amount of memory to house all the caches for databases and queues.
  • +
  • CPU performance should be average. A good compromise between amount of cores and speed should be used. However this is +the least important requirement on the list.
  • +
+

Hardware recommendation

+

The following server specs are just a starting point and can greatly vary between environments.

+

Example: +3x Dell R630/R640/R650 1HE Server

+
    +
  • Dual 8 Core 3,00 GHz Intel/AMD
  • +
  • 128 GB RAM
  • +
  • 2x 3,84 TB NVMe in (Software-) RAID 1
  • +
  • 2x 10/25/40 GBit 2 Port SFP+/QSFP Network Cards
  • +
+

Compute Node (HCI)

+

The compute nodes in this scenario run all the user virtual workloads and the storage infrastructure. To make sure +we don't starve these nodes, they should be of decent size.

+
+

This setup takes local storage tests into consideration. The SCS-standards require certain flavors with very fast disc speed +to house customer kubernetes control planes (etcd). These speeds are usually not achievable with shared storage. If you don't +intend to test this scenario, you can skip the NVMe discs.

+
+

Hardware recommendation

+

The following server specs are just a starting point and can greatly vary between environments. The sizing of the nodes needs to fit +the expected workloads (customer VMs).

+

Example: +3x Dell R730(xd)/R740(xd)/R750(xd) +or +3x Supermicro

+
    +
  • Dual 16 Core 2,8 GHz Intel/AMD
  • +
  • 512 GB RAM
  • +
  • 2x 3,84 TB NVMe in (Software-) RAID 1 if you want to have local storage available (optional)
  • +
+

For hyperconverged ceph osds:

+
    +
  • 4x 10 TB HDD -> This leads to ~30 TB of available HDD storage (optional)
  • +
  • 4x 7,68 TB SSD -> This leads to ~25 TB of available SSD storage (optional)
  • +
  • 2x 10/25/40 GBit 2 Port SFP+/QSFP Network Cards
  • +
+

Network

+

The network infrastructure can vary a lot from setup to setup. This guide does not intend to define the best networking solution +for every cluster but rather give two possible scenarios.

+ +

The smallest possible setup is just a single switch connected to all the nodes physically on one interface. The switch has to be +VLAN enabled. Openstack recommends multiple isolated networks but the following are at least recommended to be split:

+
    +
  • Out of Band network
  • +
  • Management networks
  • +
  • Storage backend network
  • +
  • Public / External network for virutal machines +If there is only one switch, these networks should all be defined as seperate VLANs. One of the networks can run in untagged default +VLAN 1.
  • +
+ +

The recommended setup uses two stacked switches connected in a LAG and at least three different physical network ports on each node.

+
    +
  • Physical Network 1: VLANs for Public / External network for virutal machines, Management networks
  • +
  • Physical Network 2: Storage backend network
  • +
  • Physical Network 3: Out of Band network
  • +
+

Network adapters

+

The out of band network does usually not need a lot of bandwith. Most modern servers come with 1Gbit/s adapters which are sufficient. +For small test clusters, it might also be sufficient to use 1Gbit/s networks for the other two physical networks. +For a minimum production cluster it is recommended to use the following:

+
    +
  • Out of Band Network: 1Gbit/s
  • +
  • VLANs for Public / External network for virutal machines, Management networks: 10 / 25 Gbit/s
  • +
  • Storage backend network: 10 / 25 / 40 Gbit/s
  • +
+

Whether you need a higher throughput for your storage backend services depends on your expected storage load. The faster the network +the faster storage data can be replicated between nodes. This usually leads to improved performance and better/faster fault tolerance.

+

How to continue

+

After implementing the recommended deployment example hardware, you can continue with the deployment guide.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/ceph/index.html b/docs/iaas/guides/concept-guide/components/ceph/index.html new file mode 100644 index 0000000000..4ffc24df6d --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/ceph/index.html @@ -0,0 +1,42 @@ + + + + + +Ceph | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Ceph

+

Ceph is an Open Source software defined storage platform designed to provide highly scalable +object, block and file-based storage in a unified system. Designed for flexibility, +Ceph integrates seamlessly with cloud infrastructures like OpenStack and supports +diverse workloads with robust, self-healing and self-managing capabilities.

+

Key benefits of Ceph include:

+
    +
  • Scalability: Ceph is designed to scale from terabytes to exabytes, easily meeting +the needs of small businesses to large enterprises.
  • +
  • Resilience: With built-in redundancy and data replication, Ceph ensures data +integrity and availability even in the face of hardware failures.
  • +
  • High performance: Using a distributed architecture, Ceph delivers high throughput +and low latency, making it ideal for high-demand workloads.
  • +
  • Cost-effective: As open source, Ceph eliminates licensing costs and its ability to +run on commodity hardware reduces CapEx.
  • +
  • Versatility: Ceph supports a variety of storage types - object, block and file - +on a single platform, simplifying storage management and reducing operational complexity.
  • +
+

Lifecycle Management of Ceph in OSISM

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/clusterapi/index.html b/docs/iaas/guides/concept-guide/components/clusterapi/index.html new file mode 100644 index 0000000000..33a14b26e6 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/clusterapi/index.html @@ -0,0 +1,59 @@ + + + + + +Cluster API | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Cluster API

+

Kubernetes as a Service (KaaS) is a cloud service model that simplifies the deployment, +management and scaling of Kubernetes clusters. By abstracting the underlying infrastructure, +KaaS allows organisations to focus on developing and deploying applications without the +complexities of cluster management. One of the most powerful tools for implementing KaaS +is the Cluster API, an official Kubernetes project that provides declarative APIs and tools +for managing the lifecycle of Kubernetes clusters.

+

Key benefits of Cluster API include:

+
    +
  • Declarative Cluster Management: Cluster API allows users to define the desired state of +clusters using YAML manifests. This declarative approach simplifies the process of creating, +updating, and deleting clusters, making it easier to automate and version control cluster +configurations.
  • +
  • Infrastructure Abstraction: Cluster API abstracts the underlying infrastructure, enabling +the deployment of Kubernetes clusters across various environments, including public clouds +(AWS, Azure, GCP), private clouds (OpenStack), and on-premises data centers. This abstraction +ensures that the same API can be used regardless of the infrastructure provider.
  • +
  • Consistent Lifecycle Management: Cluster API standardizes the lifecycle management of +Kubernetes clusters, including provisioning, scaling, upgrading, and deletion. This consistency +reduces operational overhead and ensures that clusters are managed uniformly across different +environments.
  • +
  • Extensibility and Customization: Cluster API’s modular architecture allows for extensibility +through the use of custom resource definitions (CRDs) and controllers. Organizations can tailor +the API to meet specific requirements, such as integrating with existing CI/CD pipelines or +adding custom operational logic.
  • +
  • Improved Operational Efficiency: By leveraging Cluster API, organizations can automate repetitive +tasks, reduce human error, and ensure that clusters are configured according to best practices. +This automation leads to increased operational efficiency and faster delivery of applications.
  • +
+

By using Kubernetes as a Service with Cluster API, organisations can achieve a highly automated, +scalable and consistent approach to managing Kubernetes clusters across different environments. +This allows them to focus more on application development, and less on the operational +complexities of managing Kubernetes infrastructure.

+

Lifecycle Management of Cluster API in OSISM

+

Cluster API with OpenStack Magnum

+

Cluster API with SCS Cluster Stacks

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/gardener/index.html b/docs/iaas/guides/concept-guide/components/gardener/index.html new file mode 100644 index 0000000000..f4dcb6ed7b --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/gardener/index.html @@ -0,0 +1,63 @@ + + + + + +Gardener | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Gardener

+

Kubernetes as a Service (KaaS) simplifies the deployment, management, and scaling of +Kubernetes clusters by abstracting the underlying infrastructure. Gardener by SAP is +an advanced KaaS solution that leverages a Kubernetes-native approach to manage +Kubernetes clusters at scale. Gardener is designed to provide consistent and efficient +cluster management across various cloud environments and on-premises data centers.

+

Key benefits of Gardener include:

+
    +
  • Kubernetes-Native Design: Gardener operates by treating Kubernetes clusters as first-class +citizens. It uses Kubernetes itself to orchestrate the deployment and management of other +Kubernetes clusters, ensuring that all operations are consistent and follow Kubernetes best +practices.
  • +
  • Shoot, Seed, and Garden Clusters: +
      +
    • Shoot Clusters: These are the user clusters managed by Gardener, running the workloads.
    • +
    • Seed Clusters: These clusters host the control planes of shoot clusters and are managed by +the Gardener infrastructure.
    • +
    • Garden Cluster: This is the central cluster where the Gardener components run and from which +all other clusters (seed and shoot) are managed.
    • +
    +
  • +
  • Multi-Cloud and Hybrid Cloud Support: Gardener supports deployment across various cloud providers, +including AWS, Azure, Google Cloud, and OpenStack, as well as on-premises environments. +This multi-cloud capability allows for a consistent Kubernetes experience regardless of the +underlying infrastructure.
  • +
  • Automated Cluster Management: Gardener automates the lifecycle management of Kubernetes clusters, +including provisioning, scaling, upgrading, and healing. This automation reduces operational +overhead and ensures clusters are always running optimally.
  • +
  • High Availability and Resilience: Gardener ensures high availability by distributing control +planes across multiple seed clusters and leveraging cloud provider features to enhance resilience. +This design minimizes downtime and enhances the reliability of managed clusters.
  • +
  • Extensibility and Customization: Gardener’s architecture allows for customization and extensibility +through extensions and webhooks. This flexibility enables organizations to tailor the solution to +meet specific requirements and integrate with existing tools and processes.
  • +
+

By using Gardener by SAP for Kubernetes as a Service, organisations can achieve a scalable, +automated and consistent approach to managing Kubernetes clusters across multiple environments. +This allows them to focus on delivering business value through their applications, rather +than dealing with the complexities of cluster management.

+

Lifecycle Management of Gardener in OSISM

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/index.html b/docs/iaas/guides/concept-guide/components/index.html new file mode 100644 index 0000000000..6896f44a86 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/index.html @@ -0,0 +1,37 @@ + + + + + +Components | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/ironic/index.html b/docs/iaas/guides/concept-guide/components/ironic/index.html new file mode 100644 index 0000000000..1907194991 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/ironic/index.html @@ -0,0 +1,60 @@ + + + + + +Ironic | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Ironic

+

OpenStack Ironic is a project that provides Baremetal as a Service (BMaaS), enabling the +provisioning and management of physical machines in a cloud-like manner. Unlike traditional +virtualization, where virtual machines run on top of a hypervisor, BMaaS allows users to +directly manage and utilize physical hardware, offering the full performance and isolation +of dedicated servers.

+

Key benefits of OpenStack Ironic:

+
    +
  • Hardware Provisioning: Ironic automates the provisioning of physical servers, including +the deployment of operating systems and configuration of hardware settings. This automation +streamlines the setup process, reducing the time and effort required to bring new servers +online.
  • +
  • Integration with OpenStack: Ironic integrates seamlessly with other OpenStack services, +such as Nova for compute management, Neutron for networking, and Glance for image services. +This integration allows users to manage both virtual and baremetal resources through a +unified OpenStack dashboard.
  • +
  • Support for Multiple Hardware Drivers: Ironic supports a wide range of hardware through +various drivers, including IPMI, Redfish, and vendor-specific drivers. This flexibility +ensures compatibility with a diverse set of hardware platforms and management interfaces.
  • +
  • Resource Management and Scheduling: Ironic leverages OpenStack’s scheduling capabilities +to manage the allocation of physical servers, ensuring optimal utilization of hardware +resources. Users can request specific hardware configurations and Ironic will match these +requests with available resources.
  • +
  • Provisioning States: Ironic manages the lifecycle of baremetal nodes through various +provisioning states, such as enroll, available, active, and maintenance. This state +management ensures that hardware is correctly tracked and managed throughout its lifecycle.
  • +
  • Network Integration: Ironic integrates with Neutron to provide networking services for +baremetal nodes, including support for VLANs, flat networks, and more complex networking +setups. This integration ensures that baremetal nodes can be seamlessly integrated into +existing network topologies.
  • +
+

By utilizing OpenStack Ironic, organizations can leverage the benefits of BMaaS, +providing users with the performance and control of physical hardware while maintaining +the flexibility and scalability of cloud infrastructure. This approach is particularly +beneficial for workloads that require high performance, low latency, or specific hardware +configurations that are not achievable with virtual machines.

+

Lifecycle Management of Ironic in OSISM

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/k3s/index.html b/docs/iaas/guides/concept-guide/components/k3s/index.html new file mode 100644 index 0000000000..054c7b7749 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/k3s/index.html @@ -0,0 +1,25 @@ + + + + + +K3S | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/keycloak/index.html b/docs/iaas/guides/concept-guide/components/keycloak/index.html new file mode 100644 index 0000000000..d212764ffd --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/keycloak/index.html @@ -0,0 +1,25 @@ + + + + + +Keycloak | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/netdata/index.html b/docs/iaas/guides/concept-guide/components/netdata/index.html new file mode 100644 index 0000000000..21a9826df5 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/netdata/index.html @@ -0,0 +1,25 @@ + + + + + +Netdata | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/openstack/index.html b/docs/iaas/guides/concept-guide/components/openstack/index.html new file mode 100644 index 0000000000..cf0e5751aa --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/openstack/index.html @@ -0,0 +1,64 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

OpenStack

+

Lifecycle Management of OpenStack in OSISM

+

The open source project Kolla from the OpenInfra Foundation is +used in OSISM for the life cycle management of OpenStack. Kolla’s mission is to provide +production-ready containers and deployment tools for operating OpenStack clouds. Kolla has +been actively developed by a very diverse team for 10 years and is one of the most common +(if not the most common) life cycle management tool for OpenStack.

+

The container images provided by Kolla are not only used by Kolla itself. They are also used +in TripleO, the basis for the now discontinued +RedHat OpenStack Platform, +and the OpenStack Kubernetes Operators, +the basis for the new +RedHat OpenStack Services on OpenShift.

+

OpenStack cluster

+

OpenStack cluster

+

Image source: Introduction to Red Hat OpenStack Services on OpenShift

+

OpenStack services architecture

+

OpenStack Services Architecture

+

Image source: Introduction to Red Hat OpenStack Services on OpenShift

+
    +
  • Swift: Object Storage
  • +
  • Manila: Shared Filesystems
  • +
  • Octavia: Load balancer
  • +
  • Designate: DNS
  • +
  • Heat: Orchestration
  • +
  • Placement
  • +
  • Barbican: Key Management
  • +
  • Nova: Compute
  • +
  • Cinder: Block Storage
  • +
  • Neutron: Networking
  • +
  • Glance: Image
  • +
  • Horizon: Dashboard
  • +
  • Ironic: Bare Metal Provisioning
  • +
  • Ceilometer: Metering
  • +
+

General architecture of OpenStack services

+

General Architecture of OpenStack Services

+

Image source: Red Hat OpenStack Services on OpenShift Architecture

+

Multitenancy with OpenStack

+

Multitenancy with OpenStack

+

Image source: Introduction to Red Hat OpenStack Services on OpenShift

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/prometheus/index.html b/docs/iaas/guides/concept-guide/components/prometheus/index.html new file mode 100644 index 0000000000..cb17846c44 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/prometheus/index.html @@ -0,0 +1,26 @@ + + + + + +Prometheus & Grafana | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/sonic/index.html b/docs/iaas/guides/concept-guide/components/sonic/index.html new file mode 100644 index 0000000000..49719cac32 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/sonic/index.html @@ -0,0 +1,27 @@ + + + + + +SONiC & OVN | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/teleport/index.html b/docs/iaas/guides/concept-guide/components/teleport/index.html new file mode 100644 index 0000000000..7fe9d18848 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/teleport/index.html @@ -0,0 +1,25 @@ + + + + + +Teleport | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/design/index.html b/docs/iaas/guides/concept-guide/design/index.html new file mode 100644 index 0000000000..6c5d73d156 --- /dev/null +++ b/docs/iaas/guides/concept-guide/design/index.html @@ -0,0 +1,32 @@ + + + + + +Cluster design | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/hardware-bom/index.html b/docs/iaas/guides/concept-guide/hardware-bom/index.html new file mode 100644 index 0000000000..be06e865ae --- /dev/null +++ b/docs/iaas/guides/concept-guide/hardware-bom/index.html @@ -0,0 +1,136 @@ + + + + + +Hardware Bill of Materials | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Hardware Bill of Materials

+
info

The brands, models and configurations listed are examples. There is no +single best specification for building a cluster. It always depends very +much on the requirements of the cluster and the situation. The examples +are not minimal and include various preferences of ours. The choice of +hardware always depends very much on the requirements, the available budget +and also the future plans of the cluster. There is no universal hardware +recommendation that fits all cases. These are all just examples.

+

Control nodes

+

A control node is responsible for running all or most of the OpenStack +services that manage API services and their associated runtimes. These +nodes are essential for users to interact with the cluster and maintain +its managed state.

+

However, control nodes typically do not run user virtual machines. It is +therefore advisable to replicate the control nodes to ensure high availability +and fault tolerance. A good starting point for achieving RAFT quorum is to have +three control nodes.

+
    +
  • 2x SSD with at least 480 GByte for the operating system
  • +
  • 4x NVMe with at least 960 GByte for the services
  • +
  • 128 GByte memory (it should be possible to upgrade to 256 GByte, or use 256 +GByte directly)
  • +
  • Dual port NIC with 25G or 100G (depending on which leaf switches are used)
  • +
  • 2 CPU sockets each with at least 32 cores or 1 CPU socket with at least 64 cores
  • +
+

Real world example:

+ +

Compute nodes

+

Compute nodes are dedicated to running users' virtual machines. They do not +host API services, storage services or network routers, other than the basic +network infrastructure required to connect virtual machines.

+
    +
  • 2x SSD or NVMe with at least 480 GByte for the operating system
  • +
  • 2x NVMe with at least 1.92 TByte for local storage recommended (if this is not implemented +at the start, the model should be selected so that NVMe devices can be added later, +the size depends on which CPU and how much memory is used, 7.68 TByte is more likely to be used)
  • +
  • Dual port NIC with 25G or 100G (depending on which leaf switches are used)
  • +
  • CPU sockets and memory depends on the requirement
  • +
+

Real world example:

+ +

Storage nodes

+

A dedicated storage node runs only storage services. This can be necessary in larger +deployments to protect the storage services from ressource starvation through user +workloads.

+

Read the Ceph hardware recommendations first.

+
    +
  • 2x SSD or NVMe with at least 480 GByte for the operating system
  • +
  • Dual port NIC with 100G (we recommend always using 100G for storage nodes)
  • +
  • Storage devices depends on the requirement
  • +
  • CPU sockets and memory depends on the storage devices used
  • +
+

Network nodes

+

A dedicated network node runs only network services. This is normally necessary to be +able to map safety zones. External networks terminate on the network nodes.

+

Real world example:

+
    +
  • +

    Supermicro SuperServer SYS-110D-8C-FRAN8TP

    +
      +
    • 2x SSD or NVMe with at least 480 GByte for the operating system
    • +
    • 2x DIMM slots with 32 GByte modules, leave 2 DIMM slots open for later expansion
    • +
    • If required, an additional dual port 25G or 100G NIC in the PCIe expansion slots
    • +
    • Intel Xeon Processor D-2733NT (this is onboard and not selectable)
    • +
    +
  • +
+

Manager nodes

+

The manager node, also known as the deploy node or deployment node, is designated +to manage the deployment process of all services. It is often also utilized to host +components of the monitoring services. It serves as the operator's entry point into +the cluster for operations.

+
    +
  • 2x SSD or NVMe with at least 1.92 TByte for the operating system and the services
  • +
  • 64 GByte memory (it should be possible to upgrade to 128 GByte, or use 128 GByte directly)
  • +
  • Dual port NIC with 25G or 100G (depending on which leaf switches are used)
  • +
  • 1 CPU socket with at least 16 cores
  • +
+

Real world example:

+ +

Switches

+

Management switches

+ +

Leaf switches

+

It is recommended to always use 100G for the data plane and the storage nodes. +Especially when using all-flash storage nodes, there is then enough bandwidth +available. The more and the larger flash devices you use, the more bandwidth is +required.

+

With the leaf switches for the compute plane, it depends on how large the compute +nodes are. The more CPU sockets/cores and the more memory the compute nodes have, +the more bandwidth is required on the compute nodes. Depending on how large the racks +are (or better how much power you can use in it), it may make sense to work with 100G +switches for the compute plane or with 25G switches if 4x 25G per compute node are used +instead of 2x 25G per compute node (if the compute nodes are large enough).

+ +

Spine switches

+ +

Network interface cards

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/index.html b/docs/iaas/guides/concept-guide/index.html new file mode 100644 index 0000000000..b701015052 --- /dev/null +++ b/docs/iaas/guides/concept-guide/index.html @@ -0,0 +1,72 @@ + + + + + +Concept Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/layers/index.html b/docs/iaas/guides/concept-guide/layers/index.html new file mode 100644 index 0000000000..2820234265 --- /dev/null +++ b/docs/iaas/guides/concept-guide/layers/index.html @@ -0,0 +1,30 @@ + + + + + +Layers in a cluster | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/nodes/index.html b/docs/iaas/guides/concept-guide/nodes/index.html new file mode 100644 index 0000000000..3ce9d24dde --- /dev/null +++ b/docs/iaas/guides/concept-guide/nodes/index.html @@ -0,0 +1,30 @@ + + + + + +Nodes in a cluster | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/use-cases/index.html b/docs/iaas/guides/concept-guide/use-cases/index.html new file mode 100644 index 0000000000..e28768aa8e --- /dev/null +++ b/docs/iaas/guides/concept-guide/use-cases/index.html @@ -0,0 +1,25 @@ + + + + + +Use cases | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/ceph/index.html b/docs/iaas/guides/configuration-guide/ceph/index.html new file mode 100644 index 0000000000..1995e61b25 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/ceph/index.html @@ -0,0 +1,415 @@ + + + + + +Ceph | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Ceph

+

The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/

+

It is strongly advised to use the documentation for the version being used.

+ +

Unique Identifier

+

The File System ID is a unique identifier for the cluster. +The identifier is set via the parameter fsid in environments/ceph/configuration.yml +and must be unique. It can be generated with uuidgen.

+
environments/ceph/configuration.yml
fsid: c2120a4a-669c-4769-a32c-b7e9d7b848f4
+

Client

+

The client.admin keyring is placed in the file environments/infrastructure/files/ceph/ceph.client.admin.keyring.

+

Swappiness

+

The swappiness is set via the os_tuning_params dictionary. The dictionary can +only be completely overwritten via an entry in the file environments/ceph/configuration.yml.

+

By default, the dictionary looks like this. If the swappiness of 10 is to be used, it is not +necessary to add the os_tuning_params dictionary to the configuration repository. This is only +necessary if the swappiness is to be customised.

+
environments/ceph/configuration.yml
os_tuning_params:
- { name: fs.file-max, value: 26234859 }
- { name: vm.zone_reclaim_mode, value: 0 }
- { name: vm.swappiness, value: 10 }
- { name: vm.min_free_kbytes, value: "{{ vm_min_free_kbytes }}" }
+

The sysctl paremeters are written to the file /etc/sysctl.d/ceph-tuning.conf +on the storage nodes.

+
# cat /etc/sysctl.d/ceph-tuning.conf
fs.aio-max-nr=1048576
fs.file-max=26234859
vm.zone_reclaim_mode=0
vm.swappiness=10
vm.min_free_kbytes=4194303
+

RGW service

+
    +
  1. +

    Add following configuration in environments/ceph/configuration.yml

    +
    environments/ceph/configuration.yml
    ceph_conf_overrides:
    "client.rgw.{{ hostvars[inventory_hostname]['ansible_hostname'] }}.rgw0":
    "rgw content length compat": "true"
    "rgw enable apis": "swift, s3, admin"
    "rgw keystone accepted roles": "member, admin"
    "rgw keystone accepted admin roles": "admin"
    "rgw keystone admin domain": "default"
    "rgw keystone admin password": "{{ ceph_rgw_keystone_password }}"
    "rgw keystone admin project": "service"
    "rgw keystone admin tenant": "service"
    "rgw keystone admin user": "ceph_rgw"
    "rgw keystone api version": "3"
    "rgw keystone url": "https://api-int.testbed.osism.xyz:5000"
    "rgw keystone verify ssl": "false"
    "rgw keystone implicit tenants": "true"
    "rgw s3 auth use keystone": "true"
    "rgw swift account in url": "true"
    "rgw swift versioning enabled": "true"
    +

    If the ceph_conf_overrides parameter already exists in environments/ceph/configuration.yml, +expand it and do not overwrite it.

    +

    If self-signed SSL certificates are used, two additional parameters must be set.

    +
    environments/ceph/configuration.yml
     "rgw keystone verify ssl": "false"
    "rgw verify ssl": "false"
    +

    For all possible configuration parameters visit the +Ceph configuration reference.

    +
  2. +
  3. +

    Add the ceph_rgw_keystone_password from environments/kolla/secrets.yml to +environments/ceph/secrets.yml.

    +
  4. +
  5. +

    Add following configuration in environments/kolla/configuration.yml

    +
    environments/kolla/configuration.yml
    enable_ceph_rgw: true
    enable_ceph_rgw_keystone: true

    ceph_rgw_swift_compatibility: false
    ceph_rgw_swift_account_in_url: true
    +
  6. +
  7. +

    On the nodes on which the RGW service is to be deployed, radowsgw_interface or +radosgw_address must be set in the host vars for the nodes in the inventory. +If radowsgw_interface is used, the first IPv4 address on this interface is used.

    +
    ##########################################################
    # ceph

    radosgw_address: 192.168.16.10
    +
  8. +
  9. +

    The nodes on which the RGW service is to be deployed can be defined in inventory group +ceph-rgw. By default, the RGW services are deployed on the Ceph control nodes..

    +
    inventory/20-roles
    [ceph-rgw:children]
    ceph-control
    +
  10. +
+

Extra pools

+

Extra pools can be defined via the openstack_pools_extra parameter.

+
environments/ceph/configuration.yml
openstack_extra001_pool:
name: extra001
pg_num: "{{ openstack_pool_default_pg_num }}"
pgp_num: "{{ openstack_pool_default_pg_num }}"
rule_name: "replicated_rule"
type: 1
erasure_profile: ""
expected_num_objects: ""
application: "rbd"
size: "{{ openstack_pool_default_size }}"
min_size: "{{ openstack_pool_default_min_size }}"
pg_autoscale_mode: false

openstack_pools_extra:
- "{{ openstack_extra001_pool }}"
+

If more than one Ceph cluster is managed with one manager, do not place the +parameters in environments/ceph/configuration.yml but in a corresponding file.

+

The defaults for these parameters are defined in the osism/defaults repository +as follows:

+
ParameterDefault value
openstack_pool_default_min_size0
openstack_pool_default_pg_num64
openstack_pool_default_size3
+

The extra pools can then be created by calling osism apply ceph-pools.

+

Extra keys

+

Extra keys can be defined via the openstack_keys_extra parameter.

+
environments/ceph/configuration.yml
openstack_extra001_key:
- name: client.extra001
caps:
mon: "profile rbd"
osd: "profile rbd pool={{ openstack_extra001_pool.name }}"
mode: "0600"

openstack_keys_extra:
- "{{ openstack_extra001_key }}"
+

The key is also added in the manager environment to copy it to the correct location.

+
environments/manager/configuration.yml
ceph_custom_keys:
- src: ceph.client.extra001.keyring
dest: "{{ configuration_directory }}/environments/infrastructure/files/ceph/ceph.client.extra001.keyring"
+

The extra keys can then be created by calling osism apply ceph-pools.

+

The extra keys can then be fetched and copied by calling osism apply ceph-copy-keys.

+

OSD devices

+
    +
  1. +

    For each Ceph storage node edit the file inventory/host_vars/<nodename>.yml +add a configuration like the following to it. Ensure that no devices parameter +is present in the file.

    +
      +
    1. +

      Parameters

      +
        +
      • +

        With the optional parameter ceph_osd_db_wal_devices_buffer_space_percent it is possible to +set the percentage of VGs to leave free. The parameter is not set by default. Can be helpful +for SSD performance of some older SSD models or to extend lifetime of SSDs in general.

        +
        ceph_osd_db_wal_devices_buffer_space_percent: 10
        +
      • +
      • +

        It is possible to configure the devices to be used with the parameters ceph_osd_devices, +ceph_db_devices, ceph_wal_devices, and ceph_db_wal_devices. This is described below.

        +
      • +
      • +

        It is always possible to use device names such as sda or device IDs such as +disk/by-id/wwn-<something> or disk/by-id/nvme-eui.<something>. /dev/ is not +prefixed and is added automatically.

        +
      • +
      • +

        The db_size parameter is optional and defaults to (VG size - buffer space (if enabled)) / num_osds.

        +
      • +
      • +

        The wal_size parameter is optional and defaults to 2 GB.

        +
      • +
      • +

        The num_osds parameter specifies the maximum number of OSDs that can be assigned to a WAL device or DB device.

        +
      • +
      • +

        The optional parameter wal_pv can be used to set the device that is to be used as the WAL device.

        +
      • +
      • +

        The optional parameter db_pv can be used to set the device that is to be used as the DB device.

        +
      • +
      +
    2. +
    3. +

      OSD only

      +

      The sda device will be used as an OSD device without WAL and DB device.

      +
      ceph_osd_devices:
      sda:
      +
    4. +
    5. +

      OSD + DB device

      +

      The nvme0n1 device will be used as an DB device. It is possible to use this DB device for up to 6 OSDs. Each +OSD is provided with 30 GB.

      +
      ceph_db_devices:
      nvme0n1:
      num_osds: 6
      db_size: 30 GB
      +

      The sda device will be used as an OSD device with nvme0n1 as DB device.

      +
      ceph_osd_devices:
      sda:
      db_pv: nvme0n1
      +
    6. +
    7. +

      OSD + WAL device

      +

      The nvme0n1 device will be used as an WAL device. It is possible to use this WAL device for up to 6 OSDs. Each +OSD is provided with 2 GB.

      +
      ceph_wal_devices:
      nvme0n1:
      num_osds: 6
      wal_size: 2 GB
      +

      The sda device will be used as an OSD device with nvme0n1 as WAL device.

      +
      ceph_osd_devices:
      sda:
      wal_pv: nvme0n1
      +
    8. +
    9. +

      OSD + DB device + WAL device (same device for DB + WAL)

      +

      The nvme0n1 device will be used as an DB device and a WAL device. It is possible to use those devices for up +to 6 OSDs.

      +
      ceph_db_wal_devices:
      nvme0n1:
      num_osds: 6
      db_size: 30 GB
      wal_size: 2 GB
      +

      The sda device will be used as an OSD device with nvme0n1 as DB device and nvme0n1 as WAL device.

      +
      ceph_osd_devices:
      sda:
      db_pv: nvme0n1
      wal_pv: nvme0n1
      +
    10. +
    11. +

      OSD + DB device + WAL device (different device for DB + WAL)

      +

      The nvme0n1 device will be used as an DB device. It is possible to use this DB device for up to 6 OSDs. Each +OSD is provided with 30 GB.

      +
      ceph_db_devices:
      nvme0n1:
      num_osds: 6
      db_size: 30 GB
      +

      The nvme1n1 device will be used as an WAL device. It is possible to use this WAL device for up to 6 OSDs. Each +OSD is provided with 2 GB.

      +
      ceph_wal_devices:
      nvme1n1:
      num_osds: 6
      wal_size: 2 GB
      +

      The sda device will be used as an OSD device with nvme0n1 as DB device and nvme1n1 as WAL device.

      +
      ceph_osd_devices:
      sda:
      db_pv: nvme0n1
      wal_pv: nvme1n1
      +
    12. +
    +
  2. +
  3. +

    Push the configuration to your configuration repository and after that do the following

    +
    $ osism apply configuration
    $ osism reconciler sync
    $ osism apply facts
    +
  4. +
  5. +

    After the configuration has been pulled and facts updated, +you can run the LVM configuration playbook:

    +
    $ osism apply ceph-configure-lvm-volumes
    +

    This will generate a new configuration file for each node in /tmp +on the first manager node named <nodename>-ceph-lvm-configuration.yml.

    +
  6. +
  7. +

    Take the generated configuration file from /tmp and replace the previously +configuration for each node.

    +

    In this example, the following content was in the host vars file before +osism apply ceph-configure-lvm-volumes was called.

    +
    ceph_osd_devices:
    sdb:
    sdc:
    +

    The following content has now been generated in the file in the /tmp directory by running +osism apply ceph-configure-lvm-volumes.

    +
    ceph_osd_devices:
    sdb:
    osd_lvm_uuid: 196aad32-7cc4-5350-8a45-1b03f50fc9bb
    sdc:
    osd_lvm_uuid: c6df96be-1264-5815-9cb2-da5eb453a6de
    lvm_volumes:
    - data: osd-block-196aad32-7cc4-5350-8a45-1b03f50fc9bb
    data_vg: ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb
    - data: osd-block-c6df96be-1264-5815-9cb2-da5eb453a6de
    data_vg: ceph-c6df96be-1264-5815-9cb2-da5eb453a6de
    +

    This content from the file in the /tmp directory is added in the host vars file. +The previous ceph_osd_devices is replaced with the new content.

    +
  8. +
  9. +

    Push the updated configuration again to your configuration repository and re-run:

    +
    $ osism apply configuration
    $ osism reconciler sync
    +
  10. +
  11. +

    Finally create the LVM devices.

    +
    $ osism apply ceph-create-lvm-devices
    +

    These PVs, VGs and LVs are created using the example from step 4.

    +
    $ sudo pvs
    PV VG Fmt Attr PSize PFree
    /dev/sdb ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb lvm2 a-- <20.00g 0
    /dev/sdc ceph-c6df96be-1264-5815-9cb2-da5eb453a6de lvm2 a-- <20.00g 0

    $ sudo vgs
    VG #PV #LV #SN Attr VSize VFree
    ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb 1 1 0 wz--n- <20.00g 0
    ceph-c6df96be-1264-5815-9cb2-da5eb453a6de 1 1 0 wz--n- <20.00g 0

    $ sudo lvs
    LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
    osd-block-196aad32-7cc4-5350-8a45-1b03f50fc9bb ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb -wi-a----- <20.00g
    osd-block-c6df96be-1264-5815-9cb2-da5eb453a6de ceph-c6df96be-1264-5815-9cb2-da5eb453a6de -wi-a----- <20.00g
    +
  12. +
  13. +

    Everything is now ready for the deployment of the OSDs. +Details on deploying Ceph in the Ceph deploy guide.

    +
  14. +
+

Full examples

+

Use of dedicated DB devices

+

The ceph_osd_devices and ceph_db_devices parameters with the following content are initially added +in the host vars of the node. Devices /dev/sda and /dev/sdb are used as OSD devices. The device /dev/sdd +is used as a DB device for up to 2 OSDs. For each OSD that uses /dev/sdd as DB device, an LV volume of +(in this case) 30 GByte is created. Please note that at least 30 GByte must be used for a DB device in production.

+
ceph_db_devices:
sdd:
num_osds: 2
db_size: 30 GB

ceph_osd_devices:
sdb:
db_pv: sdd
sdc:
db_pv: sdd
+

Then generate the required LVM2 device configuration with the ceph-configure-lvm-volumes play.

+
osism apply facts
osism reconciler sync
osism apply ceph-configure-lvm-volumes
+

Check the /tmp directory on the manager node for files like testbed-node-0.testbed.osism.xyz-ceph-lvm-configuration.yml. +Add this content to the host vars of the correspondingnode. The existing ceph_osd_devices parameter is replaced.

+
---
#
# This is Ceph LVM configuration for testbed-node-0.testbed.osism.xyz
# generated by ceph-configure-lvm-volumes playbook.
#
ceph_db_devices:
sdd:
db_size: 30 GB
num_osds: 2
vg_name: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb
ceph_osd_devices:
sdb:
db_pv: sdd
osd_lvm_uuid: 75960289-2e0e-525d-8bb5-dd8552531ef5
sdc:
db_pv: sdd
osd_lvm_uuid: ce2c2cb6-f911-52dd-b57f-4476bf7afe9f
lvm_volumes:
- data: osd-block-75960289-2e0e-525d-8bb5-dd8552531ef5
data_vg: ceph-75960289-2e0e-525d-8bb5-dd8552531ef5
db: osd-db-75960289-2e0e-525d-8bb5-dd8552531ef5
db_vg: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb
- data: osd-block-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f
data_vg: ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f
db: osd-db-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f
db_vg: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb
+

Finally, create the necessary PVs, VGs and LVs. The parameter -e ignore_db_too_small=true is only set +here in the example because we use less than 30 GByte for the size of the DB LV.

+
osism reconciler sync
osism apply ceph-create-lvm-devices -e ignore_db_too_small=true
+

You can check the PVs, VGs, and LVs on the node.

+
$ sudo pvs
PV VG Fmt Attr PSize PFree
/dev/sdb ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 lvm2 a-- <20.00g 0
/dev/sdc ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f lvm2 a-- <20.00g 0
/dev/sdd ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb lvm2 a-- <20.00g <10.00g

$ sudo vgs
VG #PV #LV #SN Attr VSize VFree
ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 1 1 0 wz--n- <20.00g 0
ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f 1 1 0 wz--n- <20.00g 0
ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb 1 2 0 wz--n- <20.00g <10.00g

$ sudo lvs
LV VG Attr LSize [...]
osd-block-75960289-2e0e-525d-8bb5-dd8552531ef5 ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 -wi-a----- <20.00g
osd-block-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f -wi-a----- <20.00g
osd-db-75960289-2e0e-525d-8bb5-dd8552531ef5 ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb -wi-a----- 5.00g
osd-db-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb -wi-a----- 5.00g
+

Use of partitions

+

The use of partitions presented in this example is not recommended for use in production but only for POCs.

+

First create partitions that should be used for Ceph. In this example we use a block device /dev/sdb +with four partitions that will be used for Ceph OSDs.

+
$ sudo fdisk -l /dev/sdb
Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 709B8C6C-51E1-4644-9ED4-0604607FCCEE

Device Start End Sectors Size Type
/dev/sdb1 2048 10487807 10485760 5G Linux filesystem
/dev/sdb2 10487808 20973567 10485760 5G Linux filesystem
/dev/sdb3 20973568 31459327 10485760 5G Linux filesystem
/dev/sdb4 31459328 41943006 10483679 5G Linux filesystem
+

The ceph_osd_devices parameter with the following content is initially added in the host vars of the node. +The partitions /dev/sda1, /dev/sdb1, /dev/sdc1 and /dev/sdd1, are to be used as OSD.

+
ceph_osd_devices:
sdb1:
sdb2:
sdb3:
sdb4:
+

Then generate the required LVM2 device configuration with the ceph-configure-lvm-volumes play.

+
osism apply facts
osism reconciler sync
osism apply ceph-configure-lvm-volumes
+

Check the /tmp directory on the manager node for files like testbed-node-0.testbed.osism.xyz-ceph-lvm-configuration.yml. +Add this content to the host vars of the correspondingnode. The existing ceph_osd_devices parameter is replaced.

+
---
#
# This is Ceph LVM configuration for testbed-node-0.testbed.osism.xyz
# generated by ceph-configure-lvm-volumes playbook.
#
ceph_osd_devices:
sdb1:
osd_lvm_uuid: 9e8799ae-c716-5212-8833-49f153ffbcef
sdb2:
osd_lvm_uuid: 8518d3a2-3194-5764-b55a-c51222b9b576
sdb3:
osd_lvm_uuid: a0da232a-e5b8-5823-8c42-8fb231442edc
sdb4:
osd_lvm_uuid: 56f7b5bc-82b0-5626-90a5-adf6078ceba6
lvm_volumes:
- data: osd-block-9e8799ae-c716-5212-8833-49f153ffbcef
data_vg: ceph-9e8799ae-c716-5212-8833-49f153ffbcef
- data: osd-block-8518d3a2-3194-5764-b55a-c51222b9b576
data_vg: ceph-8518d3a2-3194-5764-b55a-c51222b9b576
- data: osd-block-a0da232a-e5b8-5823-8c42-8fb231442edc
data_vg: ceph-a0da232a-e5b8-5823-8c42-8fb231442edc
- data: osd-block-56f7b5bc-82b0-5626-90a5-adf6078ceba6
data_vg: ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6
+

Finally, create the necessary PVs, VGs and LVs.

+
osism reconciler sync
osism apply ceph-create-lvm-devices
+

You can check the PVs, VGs, and LVs on the node.

+
$ sudo pvs
PV VG Fmt Attr PSize PFree
/dev/sdb1 ceph-9e8799ae-c716-5212-8833-49f153ffbcef lvm2 a-- <5.00g 0
/dev/sdb2 ceph-8518d3a2-3194-5764-b55a-c51222b9b576 lvm2 a-- <5.00g 0
/dev/sdb3 ceph-a0da232a-e5b8-5823-8c42-8fb231442edc lvm2 a-- <5.00g 0
/dev/sdb4 ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 lvm2 a-- <5.00g 0

$ sudo vgs
VG #PV #LV #SN Attr VSize VFree
ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 1 1 0 wz--n- <5.00g 0
ceph-8518d3a2-3194-5764-b55a-c51222b9b576 1 1 0 wz--n- <5.00g 0
ceph-9e8799ae-c716-5212-8833-49f153ffbcef 1 1 0 wz--n- <5.00g 0
ceph-a0da232a-e5b8-5823-8c42-8fb231442edc 1 1 0 wz--n- <5.00g 0

$ sudo lvs
LV VG Attr LSize [...]
osd-block-56f7b5bc-82b0-5626-90a5-adf6078ceba6 ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 -wi-a----- <5.00g
osd-block-8518d3a2-3194-5764-b55a-c51222b9b576 ceph-8518d3a2-3194-5764-b55a-c51222b9b576 -wi-a----- <5.00g
osd-block-9e8799ae-c716-5212-8833-49f153ffbcef ceph-9e8799ae-c716-5212-8833-49f153ffbcef -wi-a----- <5.00g
osd-block-a0da232a-e5b8-5823-8c42-8fb231442edc ceph-a0da232a-e5b8-5823-8c42-8fb231442edc -wi-a----- <5.00g
+

Add a new osd

+
    +
  1. +

    There is the following existing configuration in inventory/host_vars/<nodename>.yml.

    +
    ceph_osd_devices:
    sda:
    osd_lvm_uuid: 71e54cfb-65e5-5109-8f09-2be6b661f39c
    sdb:
    osd_lvm_uuid: acb56e1f-0700-587f-95d4-fbe905491fea
    lvm_volumes:
    - data: osd-block-71e54cfb-65e5-5109-8f09-2be6b661f39c
    data_vg: ceph-71e54cfb-65e5-5109-8f09-2be6b661f39c
    - data: osd-block-acb56e1f-0700-587f-95d4-fbe905491fea
    data_vg: ceph-acb56e1f-0700-587f-95d4-fbe905491fea
    +
  2. +
  3. +

    The block device sdc should be added as new OSD on nodename. Edit the existing +configuration in inventory/host_vars/<nodename>.yml and add sdc to the list +ceph_osd_devices.

    +
    ceph_osd_devices:
    sda:
    osd_lvm_uuid: 71e54cfb-65e5-5109-8f09-2be6b661f39c
    sdb:
    osd_lvm_uuid: acb56e1f-0700-587f-95d4-fbe905491fea
    sdc:
    lvm_volumes:
    - data: osd-block-71e54cfb-65e5-5109-8f09-2be6b661f39c
    data_vg: ceph-71e54cfb-65e5-5109-8f09-2be6b661f39c
    - data: osd-block-acb56e1f-0700-587f-95d4-fbe905491fea
    data_vg: ceph-acb56e1f-0700-587f-95d4-fbe905491fea
    +
  4. +
  5. +

    Commit changes in the configuration repository, sync the configuration repository on +the manager and reconcile the inventory with osism reconciler sync.

    +
  6. +
  7. +

    Regenerate the configuration with osism apply ceph-configure-lvm-volumes -l <nodename>. +Synchronise the contents of /tmp/<nodename>-ceph-lvm-configuration.yml with those in +inventory/host_vars/<nodename>.yml.

    +
    ceph_osd_devices:
    sda:
    osd_lvm_uuid: 71e54cfb-65e5-5109-8f09-2be6b661f39c
    sdb:
    osd_lvm_uuid: acb56e1f-0700-587f-95d4-fbe905491fea
    sdc:
    osd_lvm_uuid: ad1a16cd-b35e-58d1-8e40-80a14597f583
    lvm_volumes:
    - data: osd-block-71e54cfb-65e5-5109-8f09-2be6b661f39c
    data_vg: ceph-71e54cfb-65e5-5109-8f09-2be6b661f39c
    - data: osd-block-acb56e1f-0700-587f-95d4-fbe905491fea
    data_vg: ceph-acb56e1f-0700-587f-95d4-fbe905491fea
    - data: osd-block-ad1a16cd-b35e-58d1-8e40-80a14597f583
    data_vg: ceph-ad1a16cd-b35e-58d1-8e40-80a14597f583
    +

    Added in this case:

    +
    [...]
    sdc:
    osd_lvm_uuid: ad1a16cd-b35e-58d1-8e40-80a14597f583
    [...]
    - data: osd-block-ad1a16cd-b35e-58d1-8e40-80a14597f583
    data_vg: ceph-ad1a16cd-b35e-58d1-8e40-80a14597f583
    +
  8. +
  9. +

    Commit changes in the configuration repository, sync the configuration repository on +the manager and reconcile the inventory with osism reconciler sync.

    +
  10. +
  11. +

    Create new LVM devices.

    +
    osism apply ceph-create-lvm-devices -l <nodename>
    +
  12. +
  13. +

    Everything is now ready for the deployment of the new OSD. +Details on deploying the OSD service in the Ceph operations guide.

    +
  14. +
+

Dashboard

+

Password for the admin user of the Ceph dashboard is set via ceph_dashboard_password.

+
environments/ceph/secrets.yml
ceph_dashboard_password: password
+

User name of the admin user, port and listen IP address can be set via additional parameters.

+
environments/ceph/configuration.yml
ceph_dashboard_addr: 0.0.0.0
ceph_dashboard_port: 7000
ceph_dashboard_username: admin
+

The Ceph dashboard is bootstrapped with the ceph-bootstrap-dashboard play.

+
$ osism apply ceph-bootstrap-dashboard
+

Configuring the openstack loadbalancer to expose the ceph dashboard

+

The ceph dashboard runs in an active/standby configuration. In its default standby instances will +redirect to the active instance. Most deployments will want to use the openstack loadbalancer to +expose the ceph dashboard on the internal network and direct traffic directly to the active +instance.

+

In this scenario the dashboard should be configured to return an http error with status 404 on +standby instances.

+
environments/ceph/configuration.yml
ceph_dashboard_standby_behaviour: error
ceph_dashboard_standby_error_status_code: 404
+

Create a loadbalancer configuration

+
environments/kolla/files/overlays/haproxy/services.d/ceph_dashboard.cfg

{%- set internal_tls_bind_info = 'ssl crt /etc/haproxy/certificates/haproxy-internal.pem' if kolla_enable_tls_internal|bool else '' %}

listen ceph_dashboard
option httpchk
http-check expect status 200,404
http-check disable-on-404
{{ "bind %s:%s %s"|e|format(kolla_internal_vip_address, 8140, internal_tls_bind_info)|trim() }}
{% for host in groups['ceph-mgr'] %}
server {{ hostvars[host]['ansible_facts']['hostname'] }} {{ hostvars[host]['monitor_address'] }}:7000 check inter 2000 rise 2 fall 5
{% endfor %}
+

and apply it.

+
$ osism apply -a reconfigure loadbalancer
+

Second Ceph cluster

+

With OSISM, it is possible to manage any number of independent Ceph clusters via a single OSISM +manager service using sub-environments. A sub environment is basically nothing more than another directory +below the environments directory of the configuration repository with a special name.

+

A sub-environment for Ceph always has the name ceph.NAME. The ceph.NAME directory in the +configuration repository then contains the configuration.yml, images.yml and secrets.yml +files as usual.

+

In this example, a sub-environment ceph.rgw is created which is used for a Ceph cluster that +will only be used as an RGW cluster.

+

In comparison to the normal ceph environment, the groups to be used must be overwritten for a +Ceph sub-environment. In this case, two groups are defined: ceph.rgw and ceph.rgw.empty. +Any other groups can be used, e.g. ceph.rgw.osd. It is recommended to base the name of the +groups on the name of the sub-environments.

+

The ceph.rgw.empty group is important because there are plays in ceph-ansible that are executed +when nodes are in a specific group. To explicitly avoid this, certain groups are set to the empty +group.

+

All available group name parameters are listed in the [099-ceph.yml] +file of the osism/defaults repository.

+
environments/ceph.rgw/configuration.yml
##########################
# groups

ceph_group_name: ceph.rgw

client_group_name: ceph.rgw
grafana_server_group_name: ceph.rgw
iscsi_gw_group_name: ceph.rgw.empty
mds_group_name: ceph.rgw.empty
mgr_group_name: ceph.rgw
mon_group_name: ceph.rgw
nfs_group_name: ceph.rgw.empty
osd_group_name: ceph.rgw
rbdmirror_group_name: ceph.rgw.empty
restapi_group_name: ceph.rgw.empty
rgw_group_name: ceph.rgw
rgwloadbalancer_group_name: ceph.rgw.empty
+

The groups used are then added in the inventory in the 10-custom file.

+
inventory/10-custom
[ceph.rgw]
testbed-node-3.testbed.osism.xyz
testbed-node-4.testbed.osism.xyz
testbed-node-5.testbed.osism.xyz

[ceph.rgw.empty]
+

The sub environment can then be specified with all apply commands of the OSISM CLI. For example, +to deploy the Ceph mon services of the ceph.rgw sub environment:

+
osism apply --sub rgw ceph-osds
+

Resource limits

+

Resource limits for the individual Ceph services can be set via environments/ceph/configuration.yml. +The possible parameters and their defaults for memory limits and CPU limits are listed below.

+
    +
  • +

    Memory limits

    +
    ceph_mds_docker_memory_limit: "{{ ansible_facts['memtotal_mb'] }}m"
    ceph_mgr_docker_memory_limit: "{{ ansible_facts['memtotal_mb'] }}m"
    ceph_mon_docker_memory_limit: "{{ ansible_facts['memtotal_mb'] }}m"
    ceph_osd_docker_memory_limit: "{{ ansible_facts['memtotal_mb'] }}m"
    ceph_rbd_mirror_docker_memory_limit: "{{ ansible_facts['memtotal_mb'] }}m"
    ceph_rgw_docker_memory_limit: "4096m"
    +
  • +
  • +

    CPU limits

    +
    ceph_mds_docker_cpu_limit: 4
    ceph_mgr_docker_cpu_limit: 1
    ceph_mon_docker_cpu_limit: 1
    ceph_osd_docker_cpu_limit: 4
    ceph_rbd_mirror_docker_cpu_limit: 1
    ceph_rgw_docker_cpu_limit: 8
    +
  • +
+

CPU Pinning

+

CPU pinning and specifying the NUMA nodes to be used for the Ceph OSD and RGW services can be +set via environments/ceph/configuration.yml. +The possible parameters and possible values are listed below. The parameters are not enabled +by default.

+
    +
  • +

    Limit the specific CPUs or cores a container can use. A comma-separated list or +hyphen-separated range of CPUs a container can use, if you have more than one CPU. +The first CPU is numbered 0. A valid value might be 0-3 (to use the first, second, +third, and fourth CPU) or 1,3 (to use the second and fourth CPU).

    +
    # ceph_osd_docker_cpuset_cpus: "0,2,4,6,8,10,12,14,16"
    # ceph_rgw_docker_cpuset_cpus: "0,2,4,6,8,10,12,14,16"
    +
  • +
  • +

    Memory nodes in which to allow execution (e.g. 0-3, 0,1). Only effective on NUMA systems.

    +
    # ceph_osd_docker_cpuset_mems: "0"
    # ceph_rgw_docker_cpuset_mems: "0"
    +

    Available NUMA nodes on a node can be displayed with numactl. +In this example, there are 2 NUMA nodes. The pinned CPUs should all be assigned to the +specified NUMA node.

    +
    # numactl --hardware
    available: 2 nodes (0-1)
    node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
    node 0 size: 515581 MB
    node 0 free: 511680 MB
    node 1 cpus: 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
    node 1 size: 516078 MB
    node 1 free: 511865 MB
    node distances:
    node 0 1
    0: 10 20
    1: 20 10
    +
  • +
+

Use of RBDs for nodes

+
    +
  1. +

    Add an extra pool (see Extra pools).

    +
  2. +
  3. +

    Add a key for the new pool (see Extra keys).

    +
  4. +
  5. +

    Add nodes on which RBDs are to be used to the inventory group cephclient. The file +99-overwrite must be used for this. By default, the inventory group looks like this:

    +
    [cephclient:children]
    manager
    +

    It could look like this with the additional inventory group:

    +
    [cephclient:children]
    manager
    testbed-resource-nodes
    +
  6. +
  7. +

    Prepare the configuration of the Ceph client. Get the keyring with +ceph auth get client.extra001.

    +
  8. +
+
---
cephclient_install_type: package
cephclient_keyring_name: client.extra001
cephclient_keyring: |
[client.extra001]
key = AQBiHV9nAAAAABAAhtxl8rdW/EBvxiOGw4iMJw==
caps mon = "profile rbd"
caps osd = "profile rbd pool=extra001"
+

For Ubuntu 24.04 nodes also add the following parameter. At the moment no Ceph packages +are available for Ubuntu 24.04.

+
cephclient_debian_repository: "deb https://download.ceph.com/debian-{{ cephclient_version }} jammy main"
+
    +
  1. +

    Create new RBD in the new pool (run this command on the manager node). +In this example, the name of the node on which the RBD is to be used is +used as the name for the RBD.

    +
    rbd create testbed-node-5 --size 64 --pool extra001
    +
  2. +
  3. +

    On the node map the RBD as block device.

    +
    sudo rbd map testbed-node-5 --pool extra001 --id extra001
    +
  4. +
  5. +

    On the node check the mapped block device.

    +
    sudo rbd showmapped --id extra001
    id pool namespace image snap device
    0 extra001 testbed-node-5 - /dev/rbd0
    +
  6. +
  7. +

    Done. /dev/rbd0 can now be used like a normal block device.

    +
  8. +
  9. +

    The file /etc/ceph/rbdmap is used to persist the mapping. The service rbdmap.service +must be activated and started for this.

    +
    extra001/testbed-node-5 id=extra001,keyring=/etc/ceph/ceph.client.extra001.keyring
    +
  10. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/certificates/index.html b/docs/iaas/guides/configuration-guide/commons/certificates/index.html new file mode 100644 index 0000000000..1df8707dda --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/certificates/index.html @@ -0,0 +1,32 @@ + + + + + +Certificates | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Certificates

+

With the osism.commons.certificates role, it is possible to add custom CA certificates +on a node. The parameter should be used in the environments/configuration.yml file.

+
environments/configuration.yml
certificates_ca:
- name: custom.crt
certificate: |
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
+

The role is part of the bootstrap of a node. CA certificates can be added at a later +point in time via osism apply certificates on a node.

+

Further details on the use of self-signed certificates can be found in chapter +Self-signed certificates +of the configuration guide.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/index.html b/docs/iaas/guides/configuration-guide/commons/index.html new file mode 100644 index 0000000000..6e16dbc758 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/index.html @@ -0,0 +1,26 @@ + + + + + +Commons | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/packages/index.html b/docs/iaas/guides/configuration-guide/commons/packages/index.html new file mode 100644 index 0000000000..a594ddb630 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/packages/index.html @@ -0,0 +1,46 @@ + + + + + +Packages | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Packages

+

With the osism.commons.packages role, it is possible to add packages on a node +The parameters should be used in the inventory or in the +environments/configuration.yml file.

+

The role is applied during the bootstrap. The role can be applied manually using +osism apply packages.

+

The following packages are installed by default.

+
required_packages_default:
- curl
- dmidecode
- ethtool
- iotop
- jq
- lsscsi
- ltrace
- mtr
- nvme-cli
- pciutils
- rsyslog
- socat
- sysstat
- tmux
- tree
- whois
+

Additional packages can be added via the required_packages_extra parameter.

+
required_packages_extra: []
+

Distribution specific packages

+

Debian

+

With Debian, the packages listed in required_packages_distribution are installed by default.

+
required_packages_distribution:
- command-not-found
- debconf
- debsums
- htop
- iftop
- iperf
- multitail
- ncdu
- pv
- python-is-python3
- selinux-utils
- ssh
+

The apt_cache_valid_time parameter can be used to set the cache_valid_time paremter +of the ansible.builtin.apt module. The module updates the apt cache if it is older than +the cache_valid_time. The parameter is set in seconds and defaults to 3600.

+

CentOS

+

With CentOS, the packages listed in required_packages_distribution are installed by default.

+
required_packages_distribution:
- libselinux-utils
- openssh
+

Upgrade of packages

+

The upgrade_packages parameter can be used to configure the upgrade of packages. +The parameter is set to true by default.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/resolvconf/index.html b/docs/iaas/guides/configuration-guide/commons/resolvconf/index.html new file mode 100644 index 0000000000..7a12e94589 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/resolvconf/index.html @@ -0,0 +1,25 @@ + + + + + +Resolvconf | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/services/index.html b/docs/iaas/guides/configuration-guide/commons/services/index.html new file mode 100644 index 0000000000..3c99082e6f --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/services/index.html @@ -0,0 +1,33 @@ + + + + + +Services | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Services

+

With the osism.commons.services role, it is possible to manage services on a node +in a general form. This allows you to either activate any services or indicate that +specific services are running and should be deactivated.

+

Start and enable required services

+
services_required_default:
- cron
services_required_extra: []
services_required: "{{ services_required_default + services_required_extra }}"
+
note

services_required should not be overwritten. Use services_required_extra to add extra services.

+

Note on services that should be deactivated

+
services_warning_default:
- nscd
services_warning_extra: []
services_warning: "{{ services_warning_default + services_warning_extra }}"
+
note

services_warning should not be overwritten. Use services_warning_extra to add extra services.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/sshconfig/index.html b/docs/iaas/guides/configuration-guide/commons/sshconfig/index.html new file mode 100644 index 0000000000..4652d0598f --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/sshconfig/index.html @@ -0,0 +1,35 @@ + + + + + +SSH Config | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SSH Config

+

With the osism.commons.sshconfig role, it is possible to manage a SSH config +file in the home directory of the operator user.

+

Extra config

+

The sshconfig_extra parameter can be used to add any other SSH configuration to the .ssh/config file.

+
sshconfig_extra: |
Host github.com
ProxyCommand nc -X connect -x <web-proxy-hostname-or-ip>:<web-proxy-port>> ssh.github.com 443
+

Example

+

In the testbed +the /home/dragon/.ssh/config file is created on the manager node testbed-manager.

+
Example for an assembled /home/dragon/.ssh/config file
Host testbed-manager
HostName testbed-manager.testbed.osism.xyz
User dragon
Port 22
IdentityFile /opt/ansible/secrets/id_rsa.operator

####################
Host testbed-node-0
HostName testbed-node-0.testbed.osism.xyz
User dragon
Port 22
IdentityFile /opt/ansible/secrets/id_rsa.operator

####################
Host testbed-node-1
HostName testbed-node-1.testbed.osism.xyz
User dragon
Port 22
IdentityFile /opt/ansible/secrets/id_rsa.operator

####################
Host testbed-node-2
HostName testbed-node-2.testbed.osism.xyz
User dragon
Port 22
IdentityFile /opt/ansible/secrets/id_rsa.operator
+

Defaults

+
ParameterDefaultDescription
sshconfig_groupnameallAll nodes in this group are included.
sshconfig_order20The .ssh/config.d directory is used to prepare the .ssh/config file. You can add your own files in this directory. Everything with a filename prefix smaller than sshconfig_order is placed at the beginning of the assembled .ssh/config file. Anything with a filename prefix greater than sshconfig_order goes at the end.
sshconfig_port22The SSH port.
sshconfig_private_key_file/opt/ansible/secrets/id_rsa.operatorThe identity file to use. The file itself must already exist there. The file is created by the osism.services.manager role.
sshconfig_user"{{ operator_user }}"The user in which home directory the .ssh/config file will be generated.
sshconfig_extra""Add additional SSH configuration to the end of the .ssh/config file.
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/sysctl/index.html b/docs/iaas/guides/configuration-guide/commons/sysctl/index.html new file mode 100644 index 0000000000..db8b96891a --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/sysctl/index.html @@ -0,0 +1,31 @@ + + + + + +Sysctl | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Sysctl

+

With the osism.commons.sysctl role, it is possible to manage the attributes of the kernel +via sysctl on a node.

+

The following defaults are set via the parameter sysctl_defaults.

+
GroupAttributeDefault
elasticsearchvm.max_map_count262144
rabbitmqnet.ipv4.tcp_keepalive_time6
rabbitmqnet.ipv4.tcp_keepalive_intvl3
rabbitmqnet.ipv4.tcp_keepalive_probes3
rabbitmqnet.core.wmem_max16777216
rabbitmqnet.core.rmem_max16777216
rabbitmqnet.ipv4.tcp_fin_timeout20
rabbitmqnet.ipv4.tcp_tw_reuse1
rabbitmqnet.core.somaxconn4096
rabbitmqnet.ipv4.tcp_syncookies0
rabbitmqnet.ipv4.tcp_max_syn_backlog8192
genericvm.swappiness1
computenet.netfilter.nf_conntrack_max1048576
+

The sysctl_extra parameter can be used to set your own parameters or overwrite existing +parameters in the defaults.

+
Set attribute fs.inotify.max_user_instances to 256 for all nodes in group generic
sysctl_extra:
generic:
- name: fs.inotify.max_user_instances
value: 256
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/timezone/index.html b/docs/iaas/guides/configuration-guide/commons/timezone/index.html new file mode 100644 index 0000000000..96bd46b00d --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/timezone/index.html @@ -0,0 +1,28 @@ + + + + + +Timezone | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/user/index.html b/docs/iaas/guides/configuration-guide/commons/user/index.html new file mode 100644 index 0000000000..51a06b7ab3 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/user/index.html @@ -0,0 +1,37 @@ + + + + + +User | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

User

+

With the osism.commons.user role, it is possible to manage additional +user accounts on a node.

+

Users are managed via the user_list parameter.

+
user_list:
- name: testing
key: ssh-rsa AAAAB...
# default for groups is user_groups
# groups:
groups:
- docker
# default is a group with the name of the user
# or user_primary_group if set
# primary_group: dragon
- name: testing_github
key: https://github.com/testing.keys
+

By default a new group with the name of a user will be created and assigned as +primary group. It is possible to use an already existing group as primary group +for all users. Can be overwritten with the user specific primary_group key.

+
user_primary_group: dragon
+

If all users should be added to other specific groups by default, the user_groups +parameter can be used. Can be overwritten with the user specific groups key.

+
user_groups:
- docker
+

If users should be deleted, they are added to the user_delete list.

+
user_delete:
- user_to_delete_1
- user_to_delete_2
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/configuration-repository/index.html b/docs/iaas/guides/configuration-guide/configuration-repository/index.html new file mode 100644 index 0000000000..28874fa5e1 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/configuration-repository/index.html @@ -0,0 +1,272 @@ + + + + + +Configuration Repository | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Configuration Repository

+

The configuration required for an OSISM managed cluster is stored in a single Git +monorepo, the configuration repository.

+

Creating a new configuration repository

+

The initial content for this configuration repository is generated using the +Cookiecutter.

+

Cookiecutter generates a simple initial configuration for your new cluster by prompting +you for the basic details of the new cluster.

+

The configuration repository is not created on the future Manager node. It is created on a +local workstation. If the local workstation cannot be used for this purpose, a dedicated +virtual system can be used. For more information on this topic, refer to the +Seed Deploy Guide.

+

Step 1: Preparation

+

First decide where to store your Git repository The content generated by the cookiecutter in +the output/configuration directory is committed to a new Git repository. By default, the +configuration repository is assumed to be on GitHub. This can also be GitLab or an internal +Git service as well.

+

Host and path to the Git repository are specified by the git_ parameters. These are +requested in step 2. The git_ parameters do not specify the path to the cookiecutter +to use.

+
  [8/20] git_host (github.com):
[9/20] git_port (22):
[10/20] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY): regiocloud/configuration
[11/20] git_username (git):
[12/20] git_version (main):
+

In this case, the generated configuration in the output/configuration directory is +stored on GitHub in the regiocloud/configuration repository.

+

See the parameter reference for more details. The parameters +listed there will be queried during the execution of Cookiecutter.

+

Step 2: Run Cookiecutter

+
    +
  1. +

    The directory output is created and used as output volume. It is only necessary to create the empty +directory here.

    +
    mkdir output
    +
  2. +
  3. +

    The Cookiecutter runs inside a container. Docker must be usable on the system +where the Cookiecutter will be used. It should also work with Podman.

    +
    docker run \
    -e TARGET_UID="$(id -u)" \
    -e TARGET_GID="$(id -g)" \
    -v $(pwd)/output:/output \
    --rm -it quay.io/osism/cookiecutter
    +
  4. +
  5. +

    A few parameters are requested. The parameters are documented in detail in the parameter reference.

    +

    If you want to use the latest version, this is done using the manager_version parameter. By default, +this is always set to the latest stable version.

    +
    manager_version [7.0.4]: latest
    +

    If the manager_version parameter is set to latest it is also possible to explicitly +set the openstack_version and the ceph_version explicitly.

    +
    [1/19] with_ceph (1):
    [2/19] with_keycloak (0):
    [3/19] ceph_network(192.168.16.0/20):
    [4/19] ceph_version (quincy):
    [5/19] domain (osism.xyz):
    [6/19] fqdn_external (api.osism.xyz):
    [7/19] fqdn_internal (api-int.osism.xyz):
    [8/19] git_host (github.com):
    [9/19] git_port (22):
    [10/19] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY):
    [11/19] git_username (git):
    [12/19] git_version (main):
    [13/19] ip_external (192.168.16.254):
    [14/19] ip_internal (192.168.16.9):
    [15/19] manager_version (7.0.4):
    [16/19] name_server (149.112.112.112):
    [17/19] ntp_server (de.pool.ntp.org):
    [18/19] openstack_version (2023.2):
    [19/19] project_name (configuration):
    +
  6. +
+

Step 3: Upload the new configuration to the remote git repository

+

Add the initial configuration state to the repository. How to add a deploy key on GitHub is documented in +Managing deploy keys. +Read permissions are sufficient.

+
$ git clone git@github.com:YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY.git YOUR_NEW_CONFIGURATION_REPOSITORY
$ cp -r output/configuration/{*,.gitignore} YOUR_NEW_CONFIGURATION_REPOSITORY
$ cd YOUR_NEW_CONFIGURATION_REPOSITORY
$ git add -A .
$ git commit -m "Initial commit after bootstrap"
$ git push
+

The content is now committed to the Git repository that was created earlier in the process.

+
warning

The secrets directory is not stored in the Git repository. Its contents can be +stored in a trusted location.

The secrets directory contains an SSH key pair which is used as the deploy key to +make the configuration repository available on the manager node later. Write access +is not required. The public SSH key is stored in the secrets/id_rsa.configuration.pub file.

+

Step 4: Post-processing of the generated configuration

+

The configuration repository that is initially created with the Cookiecutter is not immediately usable. +For example, the inventory needs to be built. All other information can be found in the +Configuration Guide. Use git to version all your configuration changes.

+

The following 6 points must be changed after the initial creation of the configuration repository.

+
    +
  1. Secrets
  2. +
  3. Manager inventory
  4. +
  5. Global inventory
  6. +
  7. DNS servers
  8. +
  9. NTP servers
  10. +
  11. Certificates
  12. +
+

Secrets

+

The password for Ansible Vault encrypted files, is stored in secrets/vaultpass. Since the secrets directory +is not added to the configuration repository, it is important to store it in a password vault of your choice.

+

The password of the generated Keepass file is password. This should be changed when using the Keepass file. +If possible, an existing password vault should be used.

+

Manager inventory

+

The information required to perform the initial bootstrap of the manager node and the initial +deployment of the manager service from the seed Node is provided in the inventory of the manager +environment.

+

In the Cookiecutter, a node node01 is defined as an example in the manager inventory as well as +in the global inventory. The name of this node must be changed to match the name of the node used +as manager in your own cluster.

+

Roles

+
    +
  • +

    Manager role

    +

    The name of the node on which the manager service is to be deployed is +added to inventory group manager in file environments/manager/hosts.

    +

    Only the manager inventory group is available in environments/manager/hosts. There are no +other groups there.

    +
    environments/manager/hosts
    [manager]
    node01
    +
  • +
+

Host vars

+
    +
  • +

    Ansible section

    +

    The IP address where the node can be reached via SSH from the manager node. If DHCP is used after the +initial provisioning to assign an initial IP address to the nodes, the address assigned via DHCP is +initially used here and later changed to the static IP address.

    +
    environments/manager/host_vars/node01.yml
    ansible_host: 192.168.16.10
    +
  • +
  • +

    Generic section

    +

    The network interface on which the internal communication of the cluster will take place. If the +internal interface does not yet exist at the time the configuration is created, e.g. because it is a +bond interface or VLAN interface that is only created by the static network configuration, it can be +already used here.

    +
    environments/manager/host_vars/node01.yml
    internal_interface: eno1
    +
  • +
  • +

    Network section

    +

    The static and complete network configuration of the node. Further details on creating the +network configuration in the network configuration guide.

    +
    environments/manager/host_vars/node01.yml
    network_ethernets:
    eno1:
    addresses:
    - "192.168.16.10/20"
    gateway4: "192.168.16.1"
    mtu: 1500
    +
  • +
+

Global inventory

+

In the Cookiecutter, a node node01 is defined as an example in the manager inventory as well as +in the global inventory. The name of this node must be changed to match the name of the node used +as manager in your own cluster.

+

Roles

+
    +
  • +

    Generic role

    +
    inventory/20-roles
    # The "all" group is not used in OSISM. Therefore it is important
    # that all nodes are explicitly listed here.
    [generic]
    node01
    +
  • +
  • +

    Manager role

    +
    inventory/20-roles
    # Nodes that act as manager (sometimes called deployment node)
    # are included in this group.
    [manager]
    node01
    +
  • +
  • +

    Monitoring role

    +
    inventory/20-roles
    # Nodes which are intended for monitoring services belong to
    # this group
    [monitoring]
    +
  • +
  • +

    Control role

    +
    inventory/20-roles
    # Nodes that serve as controllers, so things like scheduler,
    # API or database run there, of the environment.
    [control]
    +
  • +
  • +

    Compute role

    +
    inventory/20-roles
    # Virtual systems managed by OpenStack Nova are placed on
    # nodes in this group.
    [compute]
    +
  • +
  • +

    Network role

    +
    inventory/20-roles
    # Network resources managed by OpenStack Neutron, such as
    # L3 routers, are placed on these nodes. This group has nothing
    # to do with the general network configuration.
    [network]
    +
  • +
  • +

    Ceph control role

    +
    inventory/20-roles
    # Nodes that serve as controllers for Ceph, so things like the
    # Ceph Monitor service run here.
    [ceph-control]
    +
  • +
  • +

    Ceph resource role

    +
    inventory/20-roles
    # The storage available in these systems is provided in the
    # form of OSDs for Ceph.
    [ceph-resource]
    +
  • +
  • +

    Ceph rgw role

    +
    inventory/20-roles
    [ceph-rgw:children]
    ceph-control
    +
  • +
+

Host vars

+
    +
  • +

    Ansible section

    +
    inventory/host_vars/node01.yml
    # NOTE: Address where the node can be reached via SSH.
    ansible_host: 192.168.16.10
    +
  • +
  • +

    Generic section

    +
    inventory/host_vars/node01.yml
    internal_interface: eno1

    # NOTE: The address of the internal interface.
    internal_address: 192.168.16.10
    +
  • +
  • +

    Netdata section

    +
    inventory/host_vars/node01.yml
    netdata_host_type: client

    # NOTE: Uncomment this when this node should be a Netdata server.
    # netdata_host_type: server
    +
  • +
  • +

    Network section

    +
    inventory/host_vars/node01.yml
    # NOTE: This is the initial management interface. Further interfaces can be added.
    # DOCS: https://osism.tech/docs/guides/configuration-guide/network

    network_ethernets:
    eno1:
    addresses:
    - "192.168.16.10/20"
    gateway4: "192.168.16.1"
    mtu: 1500
    +
  • +
  • +

    Kolla section

    +
    inventory/host_vars/node01.yml
    network_interface: eno1

    # api_interface:
    # bifrost_network_interface:
    # dns_interface:
    # kolla_external_vip_interface:
    # migration_interface:
    # neutron_external_interface:
    # octavia_network_interface:
    # storage_interface:
    # tunnel_interface:
    +
  • +
  • +

    Ceph section

    +
    inventory/host_vars/node01.yml
    # NOTE: Uncomment this when this node is a part of the Ceph cluster.
    # monitor_address:
    # radosgw_address:
    +
    inventory/host_vars/node01.yml
    # NOTE: Uncomment this when this node should be a OSD node.
    # DOCS: https://osism.tech/docs/guides/configuration-guide/ceph#lvm-devices

    # ceph_osd_devices:
    # sdb:
    # sdc:
    # sdd:
    # sde:
    +
  • +
+

DNS servers

+
environments/configuration.yml
resolvconf_nameserver:
- 8.8.8.8
- 9.9.9.9
+

NTP servers

+
environments/configuration.yml
chrony_servers:
- 1.de.pool.ntp.org
- 2.de.pool.ntp.org
- 3.de.pool.ntp.org
- 4.de.pool.ntp.org
+

Certificates

+

The certificates must be created and added in the configuration repository in the files +environments/kolla/certificates/haproxy.pem and environments/kolla/certificates/haproxy-internal.pem. Further information in the Loadbalancer Configuration Guide.

+

If no certificates are to be used, the encryption must be deactivated. This is not +recommended.

+
environments/kolla/configuration.yml
kolla_enable_tls_external: "yes"
kolla_enable_tls_internal: "yes"
+

Using latest

+

If you want to use the latest version, this is done using the manager_version parameter. By default, +this is always set to the latest stable version.

+
manager_version [7.0.0]: latest
+

If the manager_version parameter is set to latest it is also possible to explicitly +set the openstack_version and the ceph_version explicitly.

+

Parameter reference

+
ParameterDescriptionDefault
ceph_networkAddress range for Ceph's network192.168.16.0/20
ceph_versionThe version of Ceph. When using a stable OSISM release (manager_version != latest), this value is ignoredquincy
domainThe domain used by hostnamesosism.xyz
fqdn_externalExternal API FQDNapi.osism.xyz
fqdn_internalInternal API FQDNapi-int.osism.xyz
git_hostAddress of the used Git servergithub.com
git_portPort of the used Git server22
git_repositoryPath to the git configuration repositoryYOUR_ORG/YOUR_CONFIGURATION_REPOSITORY
git_usernameUsername of the git repositorygit
git_versionGit branch namemain
ip_externalThe external IP address of the API (resolves to fqdn_external)192.168.16.254
ip_internalThe internal IP address of the API (resolves to fqdn_internal)192.168.16.9
manager_versionThe version of OSISM. An overview of available OSISM releases can be found here7.0.4
name_serverNameserver. Only one nameserver is set here because the query of multiple values in Cookiecutter is weird. Add more nameservers afterward.149.112.112.112
ntp_serverNTP server. Only one NTP server is set here because the query of multiple values in Cookiecutter is weird. Add more NTP servers afterward.de.pool.ntp.org
openstack_versionThe version of OpenStack. When using a stable OSISM release (manager_version != latest), this value is ignored2023.2
project_nameName of the configuration repository directoryconfiguration
with_ceph1 to use Ceph, 0 to not use Ceph1
with_keycloak1 to prepare Keycloak integration , 0 to not prepare Keycloak integration0
+

Configuration repository layout

+

A configuration repository always has the same layout. This section describes +the content available in a configuration repository. In the section +Creating a new configuration repository is the creation +of a new configuration repository documented.

+
Directory/FileDescription
environments
inventory
netboxoptional
requirements.txtIn the requirements.txt the necessary dependencies are listed to be able to execute Gilt.
gilt.yml
Makefile
gilt.yamlGilt is a Git layering tool. We use Gilt to maintain the image versions, Ansible configuration and scripts within the environments/manager directory.
+

Synchronising the configuration repository

+

Once the manager has been deployed and the configuration repository has been initially +transferred to the manager node, the configuration repository can be updated using +osism apply configuration.

+

If local changes were made directly in the configuration repository on the manager node, +these are overwritten.

+

Locks

+

It is possible to lock parts of the configuration repository or the complete configuration +repository. It is then no longer possible to execute plays assigned to these parts in the +locked parts. This makes it possible to prevent the execution of plays in specific areas.

+

To lock an environment, a .lock file is created in the corresponding directory of the environment. +For example, the file environments/kolla/.lock locks the Kolla environment.

+

If you try to execute a play in the Kolla environment, an error message is displayed.

+
$ osism apply common
2024-06-02 10:52:44 | INFO | Task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) was prepared for execution.
2024-06-02 10:52:44 | INFO | It takes a moment until task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) has been started and output is visible here.
ERROR: The environment kolla is locked via the configuration repository.
+

File environments/.lock is created to lock everything.

+

If you try to execute a play, an error message is displayed.

+
$ osism apply facts
2024-06-02 10:53:08 | INFO | Task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) was prepared for execution.
2024-06-02 10:53:08 | INFO | It takes a moment until task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) has been started and output is visible here.
ERROR: The configuration repository is locked.
+

Working with encrypted files

+

To make it easier to work with encrypted files, the configuration repository has several make +targets that can be used to view encrypted files and to edit encrypted files.

+
    +
  • +

    Show secrets in all encrypted files.

    +

    This opens a pager, e.g. less, and you can search with / for specific files, keys and passwords.

    +
    make ansible_vault_show FILE=all
    make ansible_vault_show FILE=environments/secrets.yml
    +
  • +
  • +

    Change or add secrets in an encrypted file with the editor set in $EDITOR.

    +
    make ansible_vault_edit FILE=environments/secrets.yml EDITOR=nano
    +
  • +
  • +

    Re-encrypt all encrypted files with a new key.

    +

    This creates a new secrets/vaultpass and creates backups of the old to +secrets/vaultpass_backup_<timestamp>.

    +
    make ansible_vault_rekey
    +
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/index.html b/docs/iaas/guides/configuration-guide/index.html new file mode 100644 index 0000000000..9efc6fe1b4 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/index.html @@ -0,0 +1,24 @@ + + + + + +Configuration Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/inventory/index.html b/docs/iaas/guides/configuration-guide/inventory/index.html new file mode 100644 index 0000000000..b5724ed4f0 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/inventory/index.html @@ -0,0 +1,39 @@ + + + + + +Inventory | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Inventory

+

The inventory used for the environment is located in the inventory directory.

+

How an inventory works is described in detail in the Ansible documentation. +In this chapter, we only deal with special features in the context of OSISM.

+

Manager

+

The manager has his own inventory which is used exclusively for the seed phase of the manager. +It is located in the directory environments/manager. There is a hosts file with only the +manager node in it.

+

Reconciler

+

Inventory Reconciler

+

Host Vars

+

Group Vars

+

Define variable for all nodes

+

The Ansible group all is specifically used internally by OSISM, is reserved and is not supported +for additional variables. When variables are added in the configuration repository for the all group, +they are ignored. In OSISM the group generic can be used to store variables for all nodes.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/loadbalancer/index.html b/docs/iaas/guides/configuration-guide/loadbalancer/index.html new file mode 100644 index 0000000000..b1e206a715 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/loadbalancer/index.html @@ -0,0 +1,172 @@ + + + + + +Loadbalancer | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Loadbalancer

+

The settings of the following section rely on the mechanisms of Kolla-Ansible, +therefore it's a good idea to consult the upstream documentation +for finding out details which are not covered by this documentation.

+

IP addresses & FQDNs

+
environments/kolla/configuration.yml
kolla_internal_vip_address: 192.168.16.9
kolla_external_vip_address: 192.168.16.254
+
environments/kolla/configuration.yml
kolla_internal_fqdn: api-int.testbed.osism.xyz
kolla_external_fqdn: api.testbed.osism.xyz
+
environments/configuration.yml
hosts_additional_entries:
api-int.testbed.osism.xyz: 192.168.16.9
api.testbed.osism.xyz: 192.168.16.254
+

TLS certificates

+
warning

To avoid unnecessary additional work and debugging, it is recommended that you configure TLS with the intended target +configuration of the specific environment before executing the initial rollout procedures.

+

Changes to the configuration of TLS (i.e. enable or disable) or fully qualified domain names (FQDNs) will +result in new URLs (with and without the https prefix). +These addresses are often stored in the Openstack database on initial deployment and cannot +be updated by simply modifying the configuration repository and performing an additional rollout.

+

In the case of self-signed certificates, the CA certificate must be distributed to all participating +https clients in the correct dependency order and in a manner appropriate to the associated Openstack service.

+

As a result, at a minimum, the involved Ansible Plays must be run in the appropriate order, and not all Ansible Plays +are designed to to handle all possible configuration transitions on their own.

+

General procedure

+

To enable TLS encryption the following steps are needed.

+
    +
  1. Activate tls encryption for both endpoints
  2. +
+
    +
  • +

    To enable external TLS encryption:

    +
    environments/kolla/configuration.yml
    kolla_enable_tls_external: "yes"
    +
  • +
  • +

    To enable internal TLS encryption:

    +
    environments/kolla/configuration.yml
    kolla_enable_tls_internal: "yes"
    +
  • +
+
    +
  1. Add the combined server certificate and private key to the following locations in the configuration repository:
  2. +
+
    +
  • private key & certificates for kolla_external_fqdn: environments/kolla/certificates/haproxy.pem
  • +
  • private key & certificates for kolla_internal_fqdn: environments/kolla/certificates/haproxy-internal.pem
  • +
+
    +
  1. Encrypt the certificates using ansible vault: +
    make ansible_vault_edit FILE=environments/kolla/certificates/haproxy.pem
    make ansible_vault_edit FILE=environments/kolla/certificates/haproxy-internal.pem
    +
  2. +
  3. Add the changes to the Git repository +
    git add environments/kolla/certificates/haproxy.pem \
    environments/kolla/certificates/haproxy-internal.pem \
    environments/kolla/configuration.yml

    git commit -m "Add new certificates" environments/kolla/certificates/haproxy.pem \
    environments/kolla/certificates/haproxy-internal.pem \
    environments/kolla/configuration.yml
    +
  4. +
  5. Rollout changes +
    osism apply loadbalancer
    +
  6. +
+

Self-signed certificates

+

OSISM supports the usage of self-signed certificates with a custom CA i.e if you +are running a test installation or for interim purposes.

+

Two certificate files are required to use TLS securely with authentication, +which will be provided by your custom Certificate Authority:

+
    +
  • the server certificate with private key
  • +
  • the CA certificate with any intermediate certificates
  • +
+

The following procedure describes the preparation tasks for the CA, which is later followed +by the general procedure described above.

+
    +
  1. +

    Import custom CA

    +

    Any custom CA can be added via the certificates_ca parameter. +This is already done in the bootstrap of the nodes.

    +
    environments/configuration.yml
    certificates_ca:
    - name: custom.crt
    certificate: |
    -----BEGIN CERTIFICATE-----
    [...]
    -----END CERTIFICATE-----
    +
  2. +
  3. +

    Manager service

    +

    The local environment variable REQUESTS_CA_BUNDLE must be set explicitly so that +the manager service knows the custom CA in all necessary places.

    +
    environments/manager/configuration.yml
    manager_environment_extra:
    REQUESTS_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt
    +
  4. +
  5. +

    Use in OpenStack

    +
      +
    • Add the custom CA to the configuration repository in the directory environments/kolla/certificates/ca with the same +name like in step 1
    • +
    • Configure the custom CA to be copied to the OpenStack containers +
      environments/manager/configuration.yml
      kolla_copy_ca_into_containers: "yes"
      openstack_cacert: /etc/ssl/certs/ca-certificates.crt
      +
    • +
    +
  6. +
  7. +

    Import the ca certificate to all nodes so that the custom CA is known everywhere and the self-signed certificates are accepted as valid.

    +
    osism apply certificates
    +
  8. +
  9. +

    Execute all steps in the general procedure above

    +
  10. +
+

Generating TLS certificates with Let’s Encrypt

+

Using Let's encrypt certificates is a good alternative to traditional certificate authorities and +greatly simplifies the administration of TLS certificates.

+

For a working Let's Encrypt configuration, the API endpoints (configured by kolla_internal_fqdn and kolla_external_fqdn) +must be accessible from the internet.

+
    +
  1. +

    Activate Let's Encrypt tls encryption for both endpoints

    +
    environments/kolla/configuration.yml
    enable_letsencrypt: "yes"
    letsencrypt_email: "<The email used for registration and recovery contact>"
    kolla_enable_tls_external: "yes"
    kolla_enable_tls_internal: "yes"
    +
  2. +
  3. +

    Rollout changes

    +
    osism apply loadbalancer
    +
  4. +
+

For more details about this topic, we recommend the offical kolla-ansible documentation.

+

Second Loadbalancer

+
info

This feature is available from OSISM 7.0.5.

+

With OSISM, it is possible to manage any number of independent loadbalancers via a single OSISM +manager service using sub-environments. A sub environment is basically nothing more than another directory +below the environments directory of the configuration repository with a special name.

+

A sub-environment for an additional loadbalancer always has the name kolla.NAME as the loadbalancer +is provided as part of Kolla. The kolla.NAME directory in the configuration repository then contains +the configuration.yml, images.yml and secrets.yml files as usual.

+

The following directories and files are also required in a sub-environment for a loadbalancer.

+
FileDescription
certificates/ca/custom.crtThe file is optional. If a custom CA is used, it must be added here.
certificates/haproxy-internal.pemSSL certificate to be used.
files/overlays/haproxy/services.d/haproxy.cfgHAProxy configuration to be used on the loadbalancer.
+

In this example, a sub-environment kolla.external is created, which is used for an outward facing +loadbalancer that only offers certain API services.

+

In comparison to the normal kolla environment, the groups to be used must be overwritten for a +Kolla sub-environment. In this case, one group is defined: kolla.external.loadbalancer. It is +recommended to base the name of the groups on the name of the sub-environments.

+

The group kolla.external.loadbalancer is added to the global inventory in the 10-custom file. +In this example, testbed-node-2.testbed.osism.xyz is used for the second loadbalancer.

+
inventory/10-custom
[kolla.external.loadbalancer]
testbed-node-2.testbed.osism.xyz
+

It is also important to ensure that the nodes used for the second loadbalancer are not included in +the loadbalancer group. This can be checked with osism get hosts -l loadbalancer. If the nodes of +the second loadbalancer are also listed there, the loadbalancer group in the 99-overwrite file of +the global inventory must be overwritten. In this example, the loadbalaner group is overwritten so +that only testbed-node-0.testbed.osism.xyz and testbed-node-1.testbed.osism.xyz are left in the +loadbalancer group.

+
inventory/99-overwrite
[loadbalancer]
testbed-node-0.testbed.osism.xyz
testbed-node-1.testbed.osism.xyz
+

Furthermore, in a Kolla sub-environment that is only used for a loadbalancer, only a few additional +parameters are required in the configuration.yml file.

+

Don't get confused, only the kolla_*internal* parameters and the haproxy-internal.pem file are used +here in the example. This is because we only want to configure one virtual IP address on the external +loadbalancer and the loadbalancer managed by Kolla has the internal IP address by default. It is therefore +not possible with Kolla to use only the kolla_*external* parameters as an additional virtual IP address +with default values would then be configured by default.

+
environments/kolla.external/configuration.yml
---
##########################################################
# hosts

hosts_kolla_all: kolla.external.loadbalancer
hosts_kolla_loadbalancer: kolla.external.loadbalancer

##########################################################
# docker

docker_namespace: osism

##########################################################
# loadbalancer

kolla_internal_vip_address: 192.168.24.200
kolla_internal_fqdn: api.testbed.osism.com
kolla_enable_tls_internal: "yes"

# Required if a custom CA is used.
kolla_copy_ca_into_containers: "yes"
+

At the moment it is only possible to deploy the loadbalancer itself with its own configuration. It is currently +not possible to use the integrated service configurations of Kolla itself (Nova, Cinder, ..) on an additional +loadbalancer. This will be possible in the future.

+
osism apply --sub external loadbalancer-without-service-config
+

ProxySQL

+
environments/kolla/configuration.yml
enable_proxysql: "yes"
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/manager/index.html b/docs/iaas/guides/configuration-guide/manager/index.html new file mode 100644 index 0000000000..0ae281b643 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/manager/index.html @@ -0,0 +1,106 @@ + + + + + +Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Manager

+

Stable release

+
warning

Always read the release notes first to learn what has changed and what +adjustments are necessary. Read the release notes even if you are only updating from e.g. 7.0.2 to 7.0.5.

+

In the example, OSISM release 7.0.5 is used.

+
    +
  1. +

    Set the new manager version in the configuration repository.

    +
    MANAGER_VERSION="7.0.5"
    sed -i "~s,^manager_version:.*\$,manager_version: ${MANAGER_VERSION}," environments/manager/configuration.yml
    +
  2. +
  3. +

    If openstack_version or ceph_version are set in environments/manager/configuration.yml +(or anywhere else), they must be removed. If these are set, the stable release is not used for +these components.

    +
  4. +
  5. +

    Sync the image versions in the configuration repository.

    +
    make sync
    +
  6. +
  7. +

    Commit and push changes in the configuration repository. Since everyone here has their own +workflows for changes to the configuration repository, only a generic example for Git.

    +
    git commit -a -s -m "manager: use OSISM version ${MANAGER_VERSION?}"
    git push
    +
  8. +
+

Working with Git branches

+

For example, for compliance and security reasons, many organizations prefer to prepare changes to +production systems on dedicated Git branches, roll them out to the production environment +using the 4-eyes control principle and then finally transfer them to the main branch through a +review and release process.

+

A typical scenario is the Manager Upgrade.

+

OSISM offers the option of using specific Git branches on the manager.

+

The Git branch can be changed in the following way:

+
    +
  1. +

    Create a branch

    +
    git checkout -b YOUR-BRANCH-FOR-CHANGE-XYZ
    +
  2. +
  3. +

    Set the branch name of your deployment branch with the variable configuration_git_version in configuration.yml. +This needs always to be changed on the manager node later if you merge the current branch to another target branch.

    +
    BRANCH="$(git rev-parse --abbrev-ref HEAD)"
    sed -i "~s,^configuration_git_version:.*\$,configuration_git_version: ${BRANCH}," environments/manager/configuration.yml
    git commit -m "Starting to work on #<issue-id>" -s environments/manager/configuration.yml
    git push
    +
  4. +
  5. +

    Login to the manager and activate the branch +(not needed when performing a initial manager install)

    +
    cd /opt/configuration
    git fetch
    git checkout YOUR-BRANCH-FOR-CHANGE-XYZ
    osism apply configuration
    +
  6. +
  7. +

    Recommended: Rebuild inventories and update facts +(On changing branches there are oft potential changes in the inventory structure)

    +
    osism reconciler sync
    osism apply facts
    +
  8. +
  9. +

    Start your work on the topic and perfom a final review when the topic is complete

    +
  10. +
+

OpenSearch integration

+

With the command osism log opensearch it is possible to send SQL queries +to the OpenSearch service. For the command to be functional, the OpenSearch +integration must be activated in the manager environment and the OpenSearch +address and port must be set.

+
environments/manager/configuration.yml
manager_opensearch_enable: true
manager_opensearch_address: api-int.testbed.osism.xyz
manager_opensearch_port: 9200
manager_opensearch_protocol: https
+

The integration can also be enabled later. osism update manager is then +executed after the configuration has been changed.

+

OpenStack broker integration

+

If the Baremetal Service Integration in OSISM is used, the OpenStack Broker integration is +required. The integration itself is activated by setting the parameter enable_listener to true.

+

The hosts in the manager_listener_broker_hosts list are the control nodes of OpenStack. +The user is set via manager_listener_broker_username. On OpenStack's RabbitMQ broker, the user openstack +is present by default.

+
environments/manager/configuration.yml
enable_listener: true
manager_listener_broker_hosts:
- 192.168.16.10
- 192.168.16.11
- 192.168.16.12
manager_listener_broker_username: openstack
manager_listener_broker_uri: "{% for host in manager_listener_broker_hosts %}amqp://{{ manager_listener_broker_username }}:{{ manager_listener_broker_password }}@{{ host }}:5672/{% if not loop.last %};{% endif %}{% endfor %}"
+

The password used when using the openstack user is rabbitmq_password from environments/kolla/secrets.yml.

+
environments/manager/secrets.yml
manager_listener_broker_password: RABBITMQ_PASSWORD
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/network/index.html b/docs/iaas/guides/configuration-guide/network/index.html new file mode 100644 index 0000000000..ea6410ed67 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/network/index.html @@ -0,0 +1,65 @@ + + + + + +Network | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Network

+

Netplan

+
Since OSISM 6.1.0, the default network type is a netplan and no longer needs to be set explicitly
network_type: netplan
+

The configuration is written to /etc/netplan/01-osism.yaml by default. Can be changed +via the network_netplan_path and network_netplan_file parameters. The file permissions +are 0600 by default (cane be changed via the network_netplan_permissions parameter). +By default, all other files in /etc/netplan are removed. If you do not want this, you +can set network_netplan_remove_unmanaged_files to false. It is also possible to explicitly +list individual files that should not be deleted in network_netplan_managed_files_extra.

+

An existing /etc/intefaces file is replaced with a placeholder file. It is not possible +to use /etc/interfaces and Netplan in parallel.

+
This template is used as the base for the configuration
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
---
network:
version: {{ network_version }}
renderer: {{ network_renderer }}

bonds:
{{ network_bonds|to_nice_yaml(indent=4)|indent(4) }}

bridges:
{{ network_bridges|to_nice_yaml(indent=4)|indent(4) }}

ethernets:
{{ network_ethernets|to_nice_yaml(indent=4)|indent(4) }}

tunnels:
{{ network_tunnels|to_nice_yaml(indent=4)|indent(4) }}

vlans:
{{ network_vlans|to_nice_yaml(indent=4)|indent(4) }}

vrfs:
{{ network_vrfs|to_nice_yaml(indent=4)|indent(4) }}
+

The parameters listed in the following table can be used in the template.

+
ParameterDefaultDescription
network_version2Defines what version of the configuration format is used. The only value supported at the moment is 2.
network_renderernetworkdDefines what network configuration tool will be used to set up your configuration.
network_bonds{}https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bonds
network_bridges{}https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bridges
network_ethernets{}https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-ethernets
network_tunnels{}https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-tunnels
network_vlans{}https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vlans
network_vrfs{}https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vrfs
+

By default changes to the network configuration are not applied automatically. This is done on +purpose to allow a manual check in advance. Changes to the network configuration can +be applied either by rebooting or by executing netplan apply.

+
$ osism console --type clush all
Enter 'quit' to leave this interactive mode
Working with nodes: testbed-manager.testbed.osism.xyz,testbed-node-[0-2].testbed.osism.xyz
clush> sudo netplan apply
+

It is possible to execute the netplan apply automatically via a handler when changes are made. +The parameter network_allow_service_restart is used for this.

+
environments/configuration.yml
network_allow_service_restart: true
+

Example

+

The Netplan documentation contains a large number of example configurations. The following +example shows the use of How to create VLANs with the osism.commons.network role.

+
network_ethernets:
mainif:
match:
macaddress: "de:ad:be:ef:ca:fe"
set-name: mainif
addresses: [ "10.3.0.5/23" ]
nameservers:
addresses: [ "8.8.8.8", "8.8.4.4" ]
search: [ example.com ]
routes:
- to: default
via: 10.3.0.1

network_vlans:
vlan15:
id: 15
link: mainif
addresses: [ "10.3.99.5/24" ]
vlan10:
id: 10
link: mainif
addresses: [ "10.3.98.5/24" ]
nameservers:
addresses: [ "127.0.0.1" ]
search: [ domain1.example.com, domain2.example.com ]
+

Dispatcher scripts

+

Dummy interfaces

+

Dummy devices are created with the help of +systemd.netdev +and can then be used as a normal netowrk device in the Netplan configuration.

+
network_dummy_interfaces:
- dummy0
+

The MTU is set to 9000 by default and can be set via network_dummy_interface_mtu.

+

/etc/interfaces

+
If /etc/interfaces is to be used, the network_type must be explicitly set in environments/configuration.yml
network_type: interfaces
+

IPv6 fabric underlay

+

Example configuration for a node. The configuration is stored in the host_vars file for the node in inventory +directory in the configuration repository.

+
##########################################################
# ansible

ansible_host: 10.10.42.10
+
##########################################################
# generic

internal_interface: dummy0
+
##########################################################
# network

network_type: netplan
network_dummy_interfaces:
- dummy0
network_ethernets:
enp99s0f0np0:
mtu: 9100
enp99s0f1np1:
mtu: 9100
dummy0:
addresses:
- 10.10.42.10/32
- 2001:db8::10:10:42:10/128
+
##########################################################
# frr

frr_local_as: 4210042010
frr_loopback_v4: 10.10.42.10
frr_loopback_v6: 2001:db8::10:10:42:10
frr_uplinks:
- interface: enp99s0f0np0
remote_as: 65401
- interface: enp99s0f1np1
remote_as: 65402
+
##########################################################
# kolla

network_interface: "{{ internal_interface }}"
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/aodh/index.html b/docs/iaas/guides/configuration-guide/openstack/aodh/index.html new file mode 100644 index 0000000000..36f986026d --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/aodh/index.html @@ -0,0 +1,29 @@ + + + + + +Aodh | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/barbican/index.html b/docs/iaas/guides/configuration-guide/openstack/barbican/index.html new file mode 100644 index 0000000000..7058aa109f --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/barbican/index.html @@ -0,0 +1,29 @@ + + + + + +Barbican | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/ceilometer/index.html b/docs/iaas/guides/configuration-guide/openstack/ceilometer/index.html new file mode 100644 index 0000000000..ed28d15413 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/ceilometer/index.html @@ -0,0 +1,28 @@ + + + + + +Ceilometer | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/cinder/index.html b/docs/iaas/guides/configuration-guide/openstack/cinder/index.html new file mode 100644 index 0000000000..f5b5cbe61a --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/cinder/index.html @@ -0,0 +1,36 @@ + + + + + +Cinder | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/designate/index.html b/docs/iaas/guides/configuration-guide/openstack/designate/index.html new file mode 100644 index 0000000000..f05422c44e --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/designate/index.html @@ -0,0 +1,29 @@ + + + + + +Designate | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/glance/index.html b/docs/iaas/guides/configuration-guide/openstack/glance/index.html new file mode 100644 index 0000000000..b6f86b13e9 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/glance/index.html @@ -0,0 +1,28 @@ + + + + + +Glance | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/heat/index.html b/docs/iaas/guides/configuration-guide/openstack/heat/index.html new file mode 100644 index 0000000000..a6d29ae59a --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/heat/index.html @@ -0,0 +1,28 @@ + + + + + +Heat | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/horizon/index.html b/docs/iaas/guides/configuration-guide/openstack/horizon/index.html new file mode 100644 index 0000000000..0d654390ab --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/horizon/index.html @@ -0,0 +1,61 @@ + + + + + +Horizon | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Horizon

+ +

Problems uploading machine images larger than 1 GiB

+

By default, the LimitRequestBody is set to 1073741824 (1 GiB). +This is a security feature (CVE-2022-29404) +and not a bug. Further details in the +A new default for the LimitRequestBody directive in httpd configuration +article in the RedHat knowledgebase.

+

This limit can be increased via the parameter horizon_httpd_limitrequestbody.

+
environments/kolla/configuration.yml
horizon_httpd_limitrequestbody: 2147483648  # 2 GiB
+

Make clouds.yml file downloadable as an alternative to the RC file

+

By default, only the openrc file is offered for download in Horizon. It makes sense to also add the +clouds.yaml as a download. To do this, the menu is customised. The change can be deployed with +osism apply -a reconfigure horizon.

+
environments/kolla/files/overlays/horizon/_9999-custom-settings.py
SHOW_KEYSTONE_V2_RC = False
USER_MENU_LINKS = [
{'name': _('OpenStack clouds.yml File'),
'icon_classes': ['fa-download', ],
'url': 'horizon:project:api_access:clouds.yaml',
'external': False,
},
{'name': _('OpenStack RC File v3'),
'icon_classes': ['fa-download', ],
'url': 'horizon:project:api_access:openrc',
'external': False,
}
]
+

Custom themes

+
    +
  1. +

    Place the files and directories of the custom theme in +environments/kolla/files/overlays/horizon/themes/custom_theme. +Examples of custom themes can be found in the osism/openstack-themes +repository.

    +
  2. +
  3. +

    Add the custom theme to the horizon_custom_themes dictionary. +Use the name of the directory in environments/kolla/files/overlays/horizon/themes as +name.

    +
    environments/kolla/configuration.yml
    horizon_custom_themes:
    - name: custom_theme
    label: CustomTheme
    +
  4. +
  5. +

    If the custom theme should be the default then add the DEFAULT_THEME parameter.

    +
    environments/kolla/files/overlays/horizon/_9999-custom-settings.py
    DEFAULT_THEME = 'custom_theme'
    +
  6. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/index.html b/docs/iaas/guides/configuration-guide/openstack/index.html new file mode 100644 index 0000000000..4966cbccb5 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/index.html @@ -0,0 +1,174 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

OpenStack

+

Image tags

+

Sometimes it is necessary to specify the image tag to be used for a specific service or a specific image of a service. +All available images and tags are listed in the 002-images-kolla.yml +file.

+

The image tags can be set in the environments/kolla/images.yml file.

+
    +
  • +

    Use a specific tag for all images of a service:

    +
    environments/kolla/images.yml
    barbican_tag: "2023.1"
    +
  • +
  • +

    Use a specific tag for a specific image of a service:

    +
    environments/kolla/images.yml
    barbican_worker_tag: "2023.1"
    +
  • +
+

Endpoints

+

Public endpoints

+

The public endpoints used for the individual OpenStack services can be configured via the public_endpoint parameters. +These are defined as follows.

+
ParameterDefault value
aodh_public_endpointaodh_external_fqdn | kolla_url(public_protocol, aodh_api_public_port)
blazar_public_endpointblazar_external_fqdn | kolla_url(public_protocol, blazar_api_public_port, '/v1')
ceph_rgw_public_endpointceph_rgw_external_fqdn | kolla_url(public_protocol, ceph_rgw_public_port, ceph_rgw_endpoint_path)
cinder_v3_public_endpoint{{ cinder_public_base_endpoint }}/v3/%(tenant_id)s
cloudkitty_public_endpointcloudkitty_external_fqdn | kolla_url(public_protocol, cloudkitty_api_public_port)
cyborg_public_endpointcyborg_external_fqdn | kolla_url(public_protocol, cyborg_api_port, '/v2')
gnocchi_public_endpointgnocchi_external_fqdn | kolla_url(public_protocol, gnocchi_api_public_port)
heat_cfn_public_endpoint{{ heat_cfn_public_base_endpoint }}/v1
heat_public_endpointheat_external_fqdn | kolla_url(public_protocol, heat_api_public_port, '/v1/%(tenant_id)s')
ironic_inspector_public_endpointironic_inspector_external_fqdn | kolla_url(public_protocol, ironic_inspector_public_port)
magnum_public_endpointmagnum_external_fqdn | kolla_url(public_protocol, magnum_api_public_port, '/v1')
manila_public_endpoint{{ manila_public_base_endpoint }}/v1/%(tenant_id)s
manila_v2_public_endpoint{{ manila_public_base_endpoint }}/v2
masakari_public_endpointmasakari_external_fqdn | kolla_url(public_protocol, masakari_api_public_port)
mistral_public_endpointmistral_external_fqdn | kolla_url(public_protocol, mistral_api_public_port, '/v2')
nova_legacy_public_endpoint{{ nova_public_base_endpoint }}/v2/%(tenant_id)s
nova_public_endpoint{{ nova_public_base_endpoint }}/v2.1
placement_public_endpointplacement_external_fqdn | kolla_url(public_protocol, placement_api_public_port)
tacker_public_endpointtacker_external_fqdn | kolla_url(public_protocol, tacker_server_public_port)
trove_public_endpointtrove_external_fqdn | kolla_url(public_protocol, trove_api_public_port, '/v1.0/%(tenant_id)s')
venus_public_endpointvenus_external_fqdn | kolla_url(public_protocol, venus_api_port)
watcher_public_endpointwatcher_external_fqdn | kolla_url(public_protocol, watcher_api_public_port)
zun_public_endpointzun_external_fqdn | kolla_url(public_protocol, zun_api_public_port, '/v1/')
+

Some of the previous default values refer to a public_base_endpoint parameter. These are defined as follows.

+
ParameterDefault value
cinder_public_base_endpointcinder_external_fqdn | kolla_url(public_protocol, cinder_api_public_port)
heat_cfn_public_base_endpointheat_cfn_external_fqdn | kolla_url(public_protocol, heat_api_cfn_public_port)
manila_public_base_endpointmanila_external_fqdn | kolla_url(public_protocol, manila_api_public_port)
nova_public_base_endpointnova_external_fqdn | kolla_url(public_protocol, nova_api_public_port)
skyline_apiserver_public_base_endpointskyline_apiserver_external_fqdn | kolla_url(public_protocol, skyline_apiserver_public_port)
+

Example for the use of name-based endpoints

+

DNS records pointing to the kolla_external_vip_address are created in advance.

+

Additional configuration parameters to overwrite the public endpoints +are added in the environments/kolla/configuration.yml file. If certain services +are not used, they are removed. If other services are used, these are added (see the +table above).

+
environments/kolla/configuration.yml
barbican_public_endpoint: https://barbican.services.a.regiocloud.tech
cinder_public_base_endpoint: https://cinder.services.a.regiocloud.tech
designate_public_endpoint: https://designate.services.a.regiocloud.tech
glance_public_endpoint: https://glance.services.a.regiocloud.tech
ironic_public_endpoint: https://ironic.services.a.regiocloud.tech
keystone_public_url: https://keystone.services.a.regiocloud.tech
manila_public_endpoint: https://manila.services.a.regiocloud.tech
neutron_public_endpoint: https://neutron.services.a.regiocloud.tech
nova_public_base_endpoint: https://nova.services.a.regiocloud.tech
octavia_public_endpoint: https://octavia.services.a.regiocloud.tech
placement_public_endpoint: https://placement.services.a.regiocloud.tech
+

Since we bind the name_based_external_front frontend to the same ports as the +horizon_external_front, the external Horizon frontend must be disabled. This is +only possible as of OSISM 7.0.6.

+
environments/kolla/configuration.yml
haproxy_enable_horizon_external: false
+

Additional HAProxy configuration in haproxy/services.d/haproxy.cfg is required to map +the DNS records to the correct backends. Here too, unused services are removed or +additional services are added.

+
environments/kolla/files/overlays/haproxy/services.d/haproxy.cfg
frontend name_based_external_front
mode http
http-request del-header X-Forwarded-Proto
option httplog
option forwardfor
http-request set-header X-Forwarded-Proto https if { ssl_fc }
bind {{ kolla_external_vip_address }}:80
bind {{ kolla_external_vip_address }}:443 ssl crt /etc/haproxy/certificates/haproxy.pem
default_backend horizon_back

acl ACL_keystone.services.a.regiocloud.tech hdr(host) -i keystone.services.a.regiocloud.tech
use_backend keystone_external_back if ACL_keystone.services.a.regiocloud.tech

acl ACL_glance.services.a.regiocloud.tech hdr(host) -i glance.services.a.regiocloud.tech
use_backend glance_api_external_back if ACL_glance.services.a.regiocloud.tech

acl ACL_neutron.services.a.regiocloud.tech hdr(host) -i neutron.services.a.regiocloud.tech
use_backend neutron_server_external_back if ACL_neutron.services.a.regiocloud.tech

acl ACL_placement.services.a.regiocloud.tech hdr(host) -i placement.services.a.regiocloud.tech
use_backend placement_api_external_back if ACL_placement.services.a.regiocloud.tech

acl ACL_nova.services.a.regiocloud.tech hdr(host) -i nova.services.a.regiocloud.tech
use_backend nova_api_external_back if ACL_nova.services.a.regiocloud.tech

acl ACL_console.services.a.regiocloud.tech hdr(host) -i console.services.a.regiocloud.tech
use_backend nova_novncproxy_external_back if ACL_console.services.a.regiocloud.tech

acl ACL_designate.services.a.regiocloud.tech hdr(host) -i designate.services.a.regiocloud.tech
use_backend designate_api_external_back if ACL_designate.services.a.regiocloud.tech

acl ACL_cinder.services.a.regiocloud.tech hdr(host) -i cinder.services.a.regiocloud.tech
use_backend cinder_api_external_back if ACL_cinder.services.a.regiocloud.tech

acl ACL_octavia.services.a.regiocloud.tech hdr(host) -i octavia.services.a.regiocloud.tech
use_backend octavia_api_external_back if ACL_octavia.services.a.regiocloud.tech

acl ACL_swift.services.a.regiocloud.tech hdr(host) -i swift.services.a.regiocloud.tech
use_backend swift_api_external_back if ACL_swift.services.a.regiocloud.tech

acl ACL_ironic.services.a.regiocloud.tech hdr(host) -i ironic.services.a.regiocloud.tech
use_backend ironic_api_external_back if ACL_ironic.services.a.regiocloud.tech
+

Additional Nova configuration in nova.conf is required to use the URL for the NoVNC service.

+
environments/kolla/files/overlays/nova.conf
[vnc]
novncproxy_base_url = https://console.services.a.regiocloud.tech/vnc_lite.html
+

Network interfaces

+
ParameterDefaultDescription
network_interfaceeth0
neutron_external_interface{{ network_interface }}
kolla_external_vip_interface{{ network_interface }}
api_interface{{ network_interface }}
migration_interface{{ api_interface }}
tunnel_interface{{ network_interface }}
octavia_network_interface{{ 'o-hm0' if octavia_network_type == 'tenant' else api_interface }}
dns_interface{{ network_interface }}
dpdk_tunnel_interface{{ neutron_external_interface }}
ironic_http_interface{{ api_interface }}
ironic_tftp_interface{{ api_interface }}
+

Customization of the service configurations

+
info

The following content is based on the kolla-ansible uptream documentation.

+

OSISM will generally look for files in environments/kolla/files/overlays/CONFIGFILE, +environments/kolla/files/overlays/SERVICENAME/CONFIGFILE or environments/kolla/files/overlays/SERVICENAME/HOSTNAME/CONFIGFILE +in the configuration repository. These locations sometimes vary and you should check the config task in the appropriate +Ansible role for a full list of supported locations. For example, in the case of nova.conf the following locations are +supported, assuming that you have services using nova.conf running on hosts called ctl1, ctl2 and ctl3:

+
    +
  • environments/kolla/files/overlays/nova.conf
  • +
  • environments/kolla/files/overlays/nova/ctl1/nova.conf
  • +
  • environments/kolla/files/overlays/nova/ctl2/nova.conf
  • +
  • environments/kolla/files/overlays/nova/ctl3/nova.conf
  • +
  • environments/kolla/files/overlays/nova/nova-scheduler.conf
  • +
+

Using this mechanism, overrides can be configured per-project (Nova), per-project-service (Nova scheduler service) or +per-project-service-on-specified-host (Nova servies on ctl1).

+

Overriding an option is as simple as setting the option under the relevant section. For example, to set +override scheduler_max_attempts in the Nova scheduler service, the operator could create +environments/kolla/files/overlays/nova/nova-scheduler.conf in the configuration repository with this content:

+
[DEFAULT]
scheduler_max_attempts = 100
+

If the operator wants to configure the initial disk, cpu and ram allocation ratio on compute node com1, +the operator needs to create the file environments/kolla/files/overlays/nova/com1/nova.conf with this +content:

+
[DEFAULT]
initial_cpu_allocation_ratio = 3.0
initial_ram_allocation_ratio = 1.0
initial_disk_allocation_ratio = 1.0
+

Note that the numbers shown here with an initial_cpu_allocation_ratio of 3.0 do match the requirements +of the SCS-nV-* (moderate oversubscription) flavors. If you do not use SMT/hyperthreading, SCS would allow +5.0 here (for the V flavors).

+

This method of merging configuration sections is supported for all services using oslo.config, +which includes the vast majority of OpenStack services, and in some cases for services using YAML configuration. +Since the INI format is an informal standard, not all INI files can be merged in this way. In these cases OSISM supports +overriding the entire config file.

+

Additional flexibility can be introduced by using Jinja conditionals in the config files. For example, you may create +Nova cells which are homogeneous with respect to the hypervisor model. In each cell, you may wish to configure the +hypervisors differently, for example the following override shows one way of setting the bandwidth_poll_interval +variable as a function of the cell:

+
[DEFAULT]
{% if 'cell0001' in group_names %}
bandwidth_poll_interval = 100
{% elif 'cell0002' in group_names %}
bandwidth_poll_interval = -1
{% else %}
bandwidth_poll_interval = 300
{% endif %}
+

An alternative to Jinja conditionals would be to define a variable for the bandwidth_poll_interval and set +it in according to your requirements in the inventory group or host vars:

+
[DEFAULT]
bandwidth_poll_interval = {{ bandwidth_poll_interval }}
+

OSISM allows the operator to override configuration globally for all services. It will look for a file +called environments/kolla/files/overlays/global.conf in the configuration repository.

+

For example to modify database pool size connection for all services, the operator needs to create +environments/kolla/files/overlays/global.conf in the configuration repository with this content:

+
[database]
max_pool_size = 100
+

How does the configuration get into services?

+

It is explained with example of OpenSearch Service how the configuration for OpenSearch +is created and gets into the container.

+
    +
  • +

    The task Copying over opensearch service config file +merges the individual sources of the files.

    +
    Copying over opensearch service config file task
    - name: Copying over opensearch service config file
    merge_yaml:
    sources:
    - "{{ role_path }}/templates/opensearch.yml.j2"
    - "{{ node_custom_config }}/opensearch.yml"
    - "{{ node_custom_config }}/opensearch/opensearch.yml"
    - "{{ node_custom_config }}/opensearch/{{ inventory_hostname }}/opensearch.yml"
    dest: "{{ node_config_directory }}/opensearch/opensearch.yml"
    mode: "0660"
    become: true
    when:
    - inventory_hostname in groups['opensearch']
    - opensearch_services['opensearch'].enabled | bool
    notify:
    - Restart opensearch container
    +
  • +
  • +

    As a basis a template opensearch.yml.j2 +is used which is part of the OpenSearch service role.

    +
    opensearch.yml.j2 template
    {% set num_nodes = groups['opensearch'] | length %}
    {% set recover_after_nodes = (num_nodes * 2 / 3) | round(0, 'floor') | int if num_nodes > 1 else 1 %}
    plugins.security.disabled: "true"

    node.name: "{{ 'api' | kolla_address | put_address_in_context('url') }}"
    network.host: "{{ 'api' | kolla_address | put_address_in_context('url') }}"

    cluster.name: "{{ opensearch_cluster_name }}"
    cluster.initial_master_nodes: [{% for host in groups['opensearch'] %}"{{ 'api' | kolla_address(host) }}"{% if not loop.last %},{% endif %}{% endfor %}]
    node.master: true
    node.data: true
    discovery.seed_hosts: [{% for host in groups['opensearch'] %}"{{ 'api' | kolla_address(host) | put_address_in_context('url') }}"{% if not loop.last %},{% endif %}{% endfor %}]

    http.port: {{ opensearch_port }}
    gateway.expected_nodes: {{ num_nodes }}
    gateway.recover_after_time: "5m"
    gateway.recover_after_nodes: {{ recover_after_nodes }}
    path.data: "/var/lib/opensearch/data"
    path.logs: "/var/log/kolla/opensearch"
    indices.fielddata.cache.size: 40%
    action.auto_create_index: "true"
    +
  • +
  • +

    For OpenSearch, overlay files can additionally be stored in 3 places in the configuration repository.

    +
      +
    • environments/kolla/files/overlays/opensearch.yml
    • +
    • environments/kolla/files/overlays/opensearch/opensearch.yml
    • +
    • environments/kolla/files/overlays/opensearch/{{ inventory_hostname }}/opensearch.yml
    • +
    +

    When merging files, the last file found has the most weight. If there is a parameter node.master: true +in the service role template opensearch.yml.j2 of the OpenSearch service and you set e.g. +node.master: false in environments/kolla/files/overlays/opensearch.yml then accordingly in the finished opensearch.yml +node.master: false is used.

    +
  • +
  • +

    After the merge the task Copying over opensearch service config file copies the content into the +configuration directory /etc/kolla/opensearch of the service.

    +
    /etc/kolla/opensearch/opensearch.yml
    action.auto_create_index: 'true'
    cluster.initial_master_nodes:
    - 192.168.16.10
    cluster.name: kolla_logging
    discovery.seed_hosts:
    - 192.168.16.10
    gateway.expected_nodes: 1
    gateway.recover_after_nodes: 1
    gateway.recover_after_time: 5m
    http.port: 9200
    indices.fielddata.cache.size: 40%
    network.host: 192.168.16.10
    node.data: true
    node.master: true
    node.name: 192.168.16.10
    path.data: /var/lib/opensearch/data
    path.logs: /var/log/kolla/opensearch
    plugins.security.disabled: 'true'
    +
  • +
  • +

    The configuration directory /etc/kolla/opensearch is mounted in each container of the OpenSearch service +to /var/lib/kolla/config_files.

    +
    Output of docker inspect opensearch
    "Mounts": [
    {
    "Type": "bind",
    "Source": "/etc/kolla/opensearch",
    "Destination": "/var/lib/kolla/config_files",
    "Mode": "rw",
    "RW": true,
    "Propagation": "rprivate"
    },
    +
  • +
  • +

    Entrypoint of a service is always kolla_start. +This script calls a script set_configs.py. +This script takes care of copying files from /var/lib/kolla/config_files to the right place inside the container. +For this purpose, the container has a +config.json +in which the individual actions are configured.

    +

    The file /var/lib/kolla/config_files/opensearch.yml is copied to /etc/opensearch/opensearch.yml.

    +

    The permissions of /var/lib/opensearch and /var/log/kolla/opensearch are set accordingly.

    +
    /etc/kolla/opensearch/config.json
    {
    "command": "/usr/share/opensearch/bin/opensearch",
    "config_files": [
    {
    "source": "/var/lib/kolla/config_files/opensearch.yml",
    "dest": "/etc/opensearch/opensearch.yml",
    "owner": "opensearch",
    "perm": "0600"
    }
    ],
    "permissions": [
    {
    "path": "/var/lib/opensearch",
    "owner": "opensearch:opensearch",
    "recurse": true
    },
    {
    "path": "/var/log/kolla/opensearch",
    "owner": "opensearch:opensearch",
    "recurse": true
    }
    ]
    }
    +
  • +
  • +

    In the config.json of the service is also defined the command which will be executed after finishing the preparations. +In the case of OpenSearch this is /usr/share/opensearch/bin/opensearch.

    +
    /etc/kolla/opensearch/config.json
    {
    "command": "/usr/share/opensearch/bin/opensearch",
    "config_files": [
    {
    "source": "/var/lib/kolla/config_files/opensearch.yml",
    "dest": "/etc/opensearch/opensearch.yml",
    "owner": "opensearch",
    "perm": "0600"
    }
    ],
    "permissions": [
    {
    "path": "/var/lib/opensearch",
    "owner": "opensearch:opensearch",
    "recurse": true
    },
    {
    "path": "/var/log/kolla/opensearch",
    "owner": "opensearch:opensearch",
    "recurse": true
    }
    ]
    }
    +
  • +
+

Number of service workers

+

The number of workers used for the individual services can generally be configured using two parameters.

+
openstack_service_workers: "{{ [ansible_facts.processor_vcpus, 5] | min }}"
openstack_service_rpc_workers: "{{ [ansible_facts.processor_vcpus, 3] | min }}
+

The default for openstack_service_workers is set to 5 when using the cookiecutter for the initial creation +of the configuration.

+

This value can be overwritten for individual services. The default for all parameters in the following table is +{{ openstack_service_workers }}. The parameter aodh_api_workers can then be used to explicitly set the +number of workers for the AODH API, for example. A reconfigure must be made for the particular services in the +case of a change. osism apply -a reconfigure aodh in this example.

+

These parameters are all set in environments/kolla/configuration.yml.

+
Parameter
aodh_api_workers
barbican_api_workers
cinder_api_workers
designate_api_workers
designate_worker_workers
designate_producer_workers
designate_central_workers
designate_sink_workers
designate_mdns_workers
glance_api_workers
gnocchi_metricd_workers
gnocchi_api_workers
heat_api_cfn_workers
heat_api_workers
heat_engine_workers
horizon_wsgi_processes
ironic_api_workers
keystone_api_workers
proxysql_workers
magnum_api_workers
magnum_conductor_workers
manila_api_workers
neutron_api_workers
neutron_metadata_workers
nova_api_workers
nova_superconductor_workers
nova_metadata_api_workers
nova_scheduler_workers
nova_cell_conductor_workers
octavia_api_workers
octavia_healthmanager_health_workers
octavia_healthmanager_stats_workers
placement_api_workers
skyline_gunicorn_workers
+

Back-end TLS configuration

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/ironic/index.html b/docs/iaas/guides/configuration-guide/openstack/ironic/index.html new file mode 100644 index 0000000000..61f7baab88 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/ironic/index.html @@ -0,0 +1,28 @@ + + + + + +Ironic | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/keystone/index.html b/docs/iaas/guides/configuration-guide/openstack/keystone/index.html new file mode 100644 index 0000000000..bf31a75d7c --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/keystone/index.html @@ -0,0 +1,42 @@ + + + + + +Keystone | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Keystone

+ +

Domain manager policy

+

This policy is currently still in draft status. Its use in production is currently not recommended.

+
SCS Standard TrackSCS StandardSCS Documentation
IAMscs-0302Domain Manager configuration for Keystone
+

To configure and use the domain manager role from the SCS project, the +environments/kolla/files/overlays/keystone/policy.yaml file is created +in the configuration repository. The deployment and upgrade of the Keystone +service itself is then done as usual.

+
environments/kolla/files/overlays/keystone/policy.yaml
---
# SCS Domain Manager policy configuration

# Section A: OpenStack base definitons
# The entries beginning with "base_<rule>" should be exact copies of the
# default "identity:<rule>" definitions for the target OpenStack release.
# They will be extended upon for the domain manager role below this section.
"base_get_domain": "(role:reader and system_scope:all) or token.domain.id:%(target.domain.id)s or token.project.domain.id:%(target.domain.id)s"
"base_list_domains": "(role:reader and system_scope:all)"
"base_list_roles": "(role:reader and system_scope:all)"
"base_get_role": "(role:reader and system_scope:all)"
"base_list_users": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
"base_get_user": "(role:reader and system_scope:all) or (role:reader and token.domain.id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"
"base_create_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"
"base_update_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"
"base_delete_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"
"base_list_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
"base_get_project": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.project.domain_id)s) or project_id:%(target.project.id)s"
"base_create_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"
"base_update_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"
"base_delete_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"
"base_list_user_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"
"base_check_grant": "(role:reader and system_scope:all) or ((role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"
"base_list_grants": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)"
"base_create_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"
"base_revoke_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"
"base_list_role_assignments": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
"base_list_groups": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"
"base_get_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"
"base_create_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"
"base_update_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"
"base_delete_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"
"base_list_groups_for_user": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(user_id)s"
"base_list_users_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"
"base_remove_user_from_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"
"base_check_user_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"
"base_add_user_to_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"

# Section B: Domain Manager Extensions

# classify domain managers with a special role
"is_domain_manager": "role:manager"

# specify a rule that whitelists roles which domain admins are permitted
# to assign and revoke within their domain
"is_domain_managed_role": "'member':%(target.role.name)s or 'load-balancer_member':%(target.role.name)s or 'creator':%(target.role.name)s"

# allow domain admins to retrieve their own domain (does not need changes)
"identity:get_domain": "rule:base_get_domain or rule:admin_required"

# list_domains is needed for GET /v3/domains?name=... requests
# this is mandatory for things like
# `create user --domain $DOMAIN_NAME $USER_NAME` to correctly discover
# domains by name
"identity:list_domains": "rule:is_domain_manager or rule:base_list_domains or rule:admin_required"

# list_roles is needed for GET /v3/roles?name=... requests
# this is mandatory for things like `role add ... $ROLE_NAME`` to correctly
# discover roles by name
"identity:list_roles": "rule:is_domain_manager or rule:base_list_roles or rule:admin_required"

# get_role is needed for GET /v3/roles/{role_id} requests
# this is mandatory for the OpenStack SDK to properly process role assignments
# which are issued by role id instead of name
"identity:get_role": "(rule:is_domain_manager and rule:is_domain_managed_role) or rule:base_get_role or rule:admin_required"

# allow domain admins to manage users within their domain
"identity:list_users": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_users or rule:admin_required"
"identity:get_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_get_user or rule:admin_required"
"identity:create_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_create_user or rule:admin_required"
"identity:update_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_update_user or rule:admin_required"
"identity:delete_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_delete_user or rule:admin_required"

# allow domain admins to manage projects within their domain
"identity:list_projects": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_projects or rule:admin_required"
"identity:get_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_get_project or rule:admin_required"
"identity:create_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_create_project or rule:admin_required"
"identity:update_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_update_project or rule:admin_required"
"identity:delete_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_delete_project or rule:admin_required"
"identity:list_user_projects": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_user_projects or rule:admin_required"

# allow domain managers to manage role assignments within their domain
# (restricted to specific roles by the 'is_domain_managed_role' rule)
#
# project-level role assignment to user within domain
"is_domain_user_project_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s"
# project-level role assignment to group within domain
"is_domain_group_project_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.project.domain_id)s"
# domain-level role assignment to group
"is_domain_level_group_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.domain.id)s"
# domain-level role assignment to user
"is_domain_level_user_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.domain.id)s"
"domain_manager_grant": "rule:is_domain_manager and (rule:is_domain_user_project_grant or rule:is_domain_group_project_grant or rule:is_domain_level_group_grant or rule:is_domain_level_user_grant)"
"identity:check_grant": "rule:domain_manager_grant or rule:base_check_grant or rule:admin_required"
"identity:list_grants": "rule:domain_manager_grant or rule:base_list_grants or rule:admin_required"
"identity:create_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_create_grant or rule:admin_required"
"identity:revoke_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_revoke_grant or rule:admin_required"
"identity:list_role_assignments": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_role_assignments or rule:admin_required"


# allow domain managers to manage groups within their domain
"identity:list_groups": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_list_groups or rule:admin_required"
"identity:get_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_get_group or rule:admin_required"
"identity:create_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_create_group or rule:admin_required"
"identity:update_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_update_group or rule:admin_required"
"identity:delete_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_delete_group or rule:admin_required"
"identity:list_groups_for_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_groups_for_user or rule:admin_required"
"identity:list_users_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_list_users_in_group or rule:admin_required"
"identity:remove_user_from_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_remove_user_from_group or rule:admin_required"
"identity:check_user_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_check_user_in_group or rule:admin_required"
"identity:add_user_to_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_add_user_to_group or rule:admin_required"
+

The role manager is created using the OpenStack CLI. Alternatively, the role can +be added using Ansible or other tools.

+
$ openstack --os-cloud admin \
role create \
--or-show \
--description "Domain Manager Role" \
manager
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | Domain Manager Role |
| domain_id | None |
| id | 9b7140bfe628468ab9b86b365f9ac4c2 |
| name | manager |
| options | {} |
+-------------+----------------------------------+
+

A user can then be made a domain manager for a particular domain by assigning this role.

+
$ openstack --os-cloud admin \
role add \
--user test \
--domain test \
manager
+

OIDC Federation

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/magnum/index.html b/docs/iaas/guides/configuration-guide/openstack/magnum/index.html new file mode 100644 index 0000000000..986650170b --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/magnum/index.html @@ -0,0 +1,28 @@ + + + + + +Magnum | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/manila/index.html b/docs/iaas/guides/configuration-guide/openstack/manila/index.html new file mode 100644 index 0000000000..0a93f98bcf --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/manila/index.html @@ -0,0 +1,29 @@ + + + + + +Manila | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/neutron/index.html b/docs/iaas/guides/configuration-guide/openstack/neutron/index.html new file mode 100644 index 0000000000..9b7fe8c971 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/neutron/index.html @@ -0,0 +1,49 @@ + + + + + +Neutron | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Neutron

+ +

Neutron-Dynamic-Routing:

+ +

Neutron-VPNaaS:

+ +

MTU Considerations

+

Neutron uses the MTU of the underlying physical network to calculate the MTU for virtual network +components including instance network interfaces. By default, it assumes a standard 1500-byte MTU +for the underlying physical network.

+

Neutron only references the underlying physical network MTU. Changing the underlying physical network +device MTU requires configuration of physical network devices such as switches and routers.

+

The configuration is described in the Neutron admin guide. +The configuration files are placed under environments/kolla/files/overlays/neutron/ml2_conf.ini +and environments/kolla/files/overlays/neutron.conf.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/nova/index.html b/docs/iaas/guides/configuration-guide/openstack/nova/index.html new file mode 100644 index 0000000000..b6cf52caaf --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/nova/index.html @@ -0,0 +1,138 @@ + + + + + +Nova | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Nova

+ +

Nested virtualisation

+

AMD

+
echo "options kvm-amd nested=y" | sudo tee /etc/modprobe.d/kvm-nested-virtualization.conf
sudo modprobe -r kvm_amd
sudo modprobe kvm_amd
cat /sys/module/kvm_amd/parameters/nested
Y
docker restart nova_libvirt
+

Intel

+
echo "options kvm-intel nested=y" | sudo tee /etc/modprobe.d/kvm-nested-virtualization.conf
sudo modprobe -r kvm_intel
sudo modprobe kvm_intel
cat /sys/module/kvm_intel/parameters/nested
Y
docker restart nova_libvirt
+

Reserve compute node resources

+

How many resources you want to reserve on a compute node depends very much on which additional +services are running on the compute node.

+

Host memory

+ +
environments/kolla/files/overlays/nova/nova-compute.conf
[DEFAULT]
reserved_host_memory_mb = 32768
+

Host CPUs

+ +
environments/kolla/files/overlays/nova/nova-compute.conf
[DEFAULT]
reserved_host_cpus = 4
+

Dedicated cores for instances

+

This section will describe how to use dedicated cores for nova instances. There are a few configuration options involved, so please refer to the upstream documentation for a full overview of possible combinations and results.

+

Add NUMA topology filter to nova scheduler

+

Add the NUMATopologyFilter to the list of enabled nova filters. +The filter makes the nova scheduler NUMA aware, so that the instance will have pinned cores from the same NUMA node. +Get the list of currently enabled filters or use the list of default filters and add the NUMATopologyFilter in the nova-scheduler config, e.g.:

+
environments/kolla/files/overlays/nova/nova-scheduler.conf
[filter_scheduler]
enabled_filters = ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter,NUMATopologyFilter
+

Apply the configuration using the osism CLI on the manager

+
osism apply nova
+

Specify CPU cores to be used as dedicated cores

+

The nova compute service needs to be aware of which CPU threads should be used as dedicated cores on each hypervisor. The config option cpu_dedicated_set is used to do that. It takes a comma-separated list of CPU threads, ranges or threads to exclude. +Before deciding on the set of dedicated cores assess the number of services and their required CPU load to exclude the required number of threads from the list. +The following example will leave thread 0 and 1 for the compute node and use ansible facts to extend the range to the other available threads:

+

Warning: Do not use ansible_processor_* facts if you intend to use cpu_power_management_strategy=cpu_state as offline cores will not be shown and subsequent applies will result in a wrong range

+
environments/kolla/files/overlays/nova/nova-compute.conf
[compute]
cpu_dedicated_set=2-{{ ansible_facts['processor_nproc'] - 1 }}
+

You may use node specific configuration to override the dedicated set for specific compute nodes, e.g.:

+
environments/kolla/files/overlays/nova/$INVENTORY_HOSTNAME/nova-compute.conf
[compute]
cpu_dedicated_set=4-12,^8,15
+

Apply the configuration using the osism CLI on the manager

+
osism apply nova
+

Create flavors or images backed by dedicated cores

+

To make the configured dedicated cores available to users, create flavors with property hw:cpu_policy=dedicated, so that the given vcpus will be pinned to the threads in the dedicated set specified on the compute node, e.g.:

+
openstack flavor create --ram 4096 --disk 10 --vcpus 2 --property hw:cpu_policy=dedicated $FLAVOR_NAME 
+

Note that this configuration will pin the qemu emulator threads to the instances CPUs. This will be fine for most workloads, but might not be sufficient for real-time or latency sensitive workloads like loadbalancers. If you get reports of CPU steal on an instance with dedicated cores or know that you need this, you may pin the emulator threads to another dedicated core by setting the property hw:emulator_threads_policy=isolate.

+
openstack flavor set --property hw:emulator_threads_policy=isolate $FLAVOR_NAME 
+

Mixing dedicated and shared cores on a compute node

+

You may also mix dedicated and shared cores on a single compute node by adding cores to the shared CPU set, e.g.

+
environments/kolla/files/overlays/nova/nova-compute.conf
[compute]
cpu_shared_set=4-12,^8,15
+

This will allow nova to schedule instances with floating cores on this set of CPU cores. +When a shared CPU set is specified setting the property hw:emulator_threads_policy=share will pin the emulator threads to this set of cores.

+

Mixing dedicated and shared cores in a nova instance

+

It is possible to create instances with a mixed set of dedicated and shared CPU cores. Set the property hw:cpu_policy=mixed:

+
openstack flavor set --property hw:cpu_policy=mixed $MIXED_FLAVOR_NAME 
+

and specify a mask for the instance cores which are to be pinned with property hw:cpu_dedicated_mask. E.g.:

+
openstack flavor set --property hw:cpu_dedicated_mask=0-1 $MIXED_FLAVOR_NAME 
+

to pin instance cores 0 and 1.

+

Creating images with special CPU requirements

+

All properties used in this section may also be set on images to indicate that instances should use the specified mixed or dedicated cores or isolated emulator threads. Note however that properties set on flavors take precedence.

+

Back instance memory by hugepages

+

Qemu/KVM can make use of hugepages, which reduces the required number of TLB entries for the instances memory. Thus it will reduce the number TLB misses, which will result in faster memory access inside the instance. +As with dedicated cores usage will enable NUMA topologies and require the NUMA topology filter to be added to the nova-scheduler's enabled filters. +Since allocating hugepages requires contiguous regions of memory it is advisable to do so at boot time, by specifying the required size and number of hugepages on the kernel cmdline.

+

If you have configured dedicated cores, make sure to configure a matching hugepage reservation by NUMA node. +E.g. assuming a compute node with two NUMA nodes of 32GB where some cores and 8GB of 4k memory pages on the first NUMA node are reserved for the hypervisor services, while the rest should be used as hugepage-backed instance memory, the following cmdline could be used: default_hugepagesz=1G transparent_hugepage=never hugepagesz=1G hugepages=0:24,1:32 +This would set a default hugepage size of 1GB, turn off transparent hugepages, and reserve 24 1GB hugepages on NUMA node 0 and 32 1GB hugepages on NUMA node 1. +To set this via osism for a group of hosts defined in the inventory create or add to the file with the following content:

+
inventory/group_vars/INVENTORY_GROUP_NAME.yml
---
grub__configuration:
- name: cmdline_linux
value:
- default_hugepagesz=1G
- transparent_hugepage=never
- hugepagesz=1G
- hugepages=0:24,1:32
+

Of course the same configuration may also be set by host using host_vars in inventory/host_vars/INVENTORY_HOST_NAME.yml.

+

Sync the variables with the inventory by running

+
osism sync inventory
+

and apply the configuration with

+
osism apply grub
+

After rebooting the nodes the hugepages will be allocated. You may check this by, e.g. looking at the corresponding values in /proc/meminfo

+
grep Huge /proc/meminfo
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 24
HugePages_Free: 24
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 1048576 kB
Hugetlb: 25165824 kB
+

If you require hugepages for services on the compute node, make sure to configure nova to reserve them for the host by setting DEFAULT.reserved_huge_pages accordingly.

+

To back an instance's memory by hugepages add the property hw:mem_page_size=large to a flavor and create the instance from it, e.g.:

+
openstack flavor set --property hw:mem_page_size=large $FLAVOR_NAME
+

Local SSD storage

+

In this example, a local SSD is provided for use on compute node testbed-node-0. +By default, Nova accesses the local storage on a file basis.

+

It is also possible to work with logical volumes instead. However, this is not +recommended or supported by OSISM. More details in the +Nova Configuration Guide.

+

On the compute node, the local SSD to be used is formatted with a file system of +your choice and mounted to /var/lib/nova. When using more than one local SSD, a +software RAID 1 should be used It is recommended to automate the creation of the +file system and the creation of the mount point with a custom playbook.

+

A nova.conf configuration file is created as an overlay file for the compute node +testbed-node-0. The name of the directory must match the name of the host in the +inventory. If the compute node has a file with the name testbed-node-0.yml in the +host_vars directory in the inventory, then the name of the directory +in the overlays is testbed-node-0 accordingly. If the file name there were +testbed-node-0.testbed.osism.xyz.yml then the name of the directory would be +testbed-node-0.testbed.osism.xyz.

+
environments/kolla/files/overlays/nova/testbed-node-0/nova.conf
[libvirt]
images_type = raw

[glance]
enable_rbd_download = true
+

As Ceph is still used as the storage backend for Glance and Cinder, the image type is +set to raw. To allow to download and cache images from Ceph via rbd rather than the +Glance API via http enable_rbd_download is set to true.

+

Parameters must also be added in the inventory. This differs depending on the OSISM +version used.

+

Up to OSISM 6 it looks like this:

+

In the inventory, the parameter nova_instance_datadir_volume +is added in the section for the kolla environment.

+
inventory/host_vars/testbed-node-0.yml
##########################################################
# kolla

nova_instance_datadir_volume: /var/lib/nova
+

Starting with OSISM 7, it looks like this:

+

In the inventory, the parameters nova_instance_datadir_volume and nova_backend, +are added in the section for the kolla environment.

+
inventory/host_vars/testbed-node-0.yml
##########################################################
# kolla

nova_instance_datadir_volume: /var/lib/nova
nova_backend: default
+

It is currently not possible to completely deactivate the Ceph integration with Nova. +So if you have all compute nodes with local storage, you still have to do the Ceph +integration for Nova itself and convert each compute node specifically to local storage. +If this is not done, errors will occur when deploying Nova.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/octavia/index.html b/docs/iaas/guides/configuration-guide/openstack/octavia/index.html new file mode 100644 index 0000000000..40d47636dd --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/octavia/index.html @@ -0,0 +1,29 @@ + + + + + +Octavia | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/placement/index.html b/docs/iaas/guides/configuration-guide/openstack/placement/index.html new file mode 100644 index 0000000000..e41b1f05f4 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/placement/index.html @@ -0,0 +1,29 @@ + + + + + +Placement | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/skyline/index.html b/docs/iaas/guides/configuration-guide/openstack/skyline/index.html new file mode 100644 index 0000000000..ca683d509d --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/skyline/index.html @@ -0,0 +1,33 @@ + + + + + +Skyline | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/proxy/index.html b/docs/iaas/guides/configuration-guide/proxy/index.html new file mode 100644 index 0000000000..79afd19720 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/proxy/index.html @@ -0,0 +1,66 @@ + + + + + +Proxy | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Proxy

+

In the following examples, it is assumed that the Squid proxy integrated by OSISM +is used on the first manager node. Any other proxy accessible from the nodes can +also be used here. http://{{ groups['manager'][0] }}:3128 which is used here as an +example is then replaced accordingly with the address of the proxy.

+

Deployment of a Squid Proxy Server

+

The Squid service can be deployed on the first manager. This is useful if no proxy +can be used in the environment. The first manager node is then used by all other nodes +as a pass-through node. Please note that this is not a caching proxy or even an air gap. +This is also possible with OSISM, but not with the help of the Squid service.

+
osism apply squid
+

Configurations

+

It is advisable to exclude hosts that are locally accessible from using the HTTP proxy +if they use HTTP(S) communication, as otherwise communication will take place unnecessarily via the +proxy. In some cases the proxy does not have access to the internal networks (this depends on its location), +but this can also lead to higher latencies or to inferred availability problems +if the proxy is temporarily unavailable.

+
warning

As Gitlab has described in 2021, there are subtle differences depending on the technology, implementation and age as to whether environment variables should be lowercase or uppercase, or what types of exclusions are possible.

Furthermore, the documentation of certain implementations is not very clear in its statements.

It usually makes sense to exclude all private ipv4 networks when the involved technology supports this +because these private networks or network areas are typicall relatively rarely accessed via a proxy anyway but there is a high potential that a network +which is required to be reached directly is overlooked.

+

We therefore try to choose the clearest examples possible.

+

The example domain landscape.example.com is used for hosts of the following names:

+
    +
  • api.zone1.landscape.example.com
  • +
  • api-internal.zone1.landscape.example.com
  • +
  • manager.landscape.example.com
  • +
+

Docker

+

This allows Docker images to be pulled via a proxy.

+
environments/configuration.yml
##########################################################
# proxy

docker_configure_proxy: true
docker_proxy_http: "http://{{ groups['manager'][0] }}:3128"
docker_proxy_https: "{{ docker_proxy_http }}"

# Due to the fact, that Golang supports CIDR blocks its a good idea to exclude local networks,
# there might be cases where CIDR excludes are ignored when calling non-golang binaries.
docker_proxy_no_proxy_extra:
- landscape.example.com
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
+

APT

+

This allows APT packages to be downloaded via a proxy.

+
environments/configuration.yml
##########################################################
# proxy

proxy_proxies:
http: "http://{{ groups['manager'][0] }}:3128"
https: "http://{{ groups['manager'][0] }}:3128"

# Due to the fact, that APT and libcurl does not support CIDR blocks, we cannot use global excludes
# using CIDR expressions
proxy_no_proxy_extra:
- landscape.example.com
+

OpenStack

+

Proxy settings for containers such as Magnum that need internet access.

+

Exclude all internal adresses, especially the internal api endpoint.

+
environments/kolla/configuration.yml
##########################################################
# proxy

container_http_proxy: "http://{{ groups['manager'][0] }}:3128"
container_https_proxy: "http://{{ groups['manager'][0] }}:3128"

# Due to the fact, that openstacks relies on python, we cannot trust that global CIDR
# excludes are working in general but it they don't harm
container_no_proxy: "localhost,127.0.0.1,landscape.example.com,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
+

Kubernetes / K3s

+

Settings for the OSISM Kubernetes cluster, which is operated independently of Openstack. +These settings affect all http and https requests of the K3s installation as they are passed as environment variables via the systemd unit. +For this reason, NO_PROXY must be configured so that the network between the K8S nodes is explicitly excluded.

+

An example:

+
environments/configuration.yml
##########################################################
# proxy

proxy_env:
HTTP_PROXY: "http://{{ groups['manager'][0] }}:3128"
HTTPS_PROXY: "http://{{ groups['manager'][0] }}:3128"
# Due to the fact, that k8s is based on Golang supports CIDR blocks its a good idea to exclude local networks,
# there might be really rare cases where CIDR excludes are ignored when calling non-golang binaries.
NO_PROXY: "localhost,127.0.0.1,landscape.example.com,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/rook/index.html b/docs/iaas/guides/configuration-guide/rook/index.html new file mode 100644 index 0000000000..d65194af4e --- /dev/null +++ b/docs/iaas/guides/configuration-guide/rook/index.html @@ -0,0 +1,139 @@ + + + + + +Ceph via Rook (technical preview) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Ceph via Rook (technical preview)

+

The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/

+

It is strongly advised to use the documentation for the version being used.

+ +

Unique Identifier

+

The File System ID is a unique identifier for the cluster.

+

The identifier is set via the parameter fsid in environments/rook/configuration.yml +and must be unique. It can be generated with uuidgen.

+

It is generated automatically by the Rook Deployment.

+

TODO: To evaluate if we want and can pass a fsid. This is no out-of-the-box Rook feature, though.

+

Client

+

The client.admin keyring is placed in the file environments/infrastructure/files/ceph/ceph.client.admin.keyring.

+

There is no real Ceph client installed on the manager node, but a wrapper to enter the Rook Toolbox can be installed.

+

If the namespace of the rook cluster was changed this needs to be reflected as well as the install type of the client.

+
environments/infrastructure/configuration.yml
cephclient_install_type: rook

cephclient_rook_namespace: rook-ceph
+

After successfully configuring the environment for the client, run the installation:

+
osism apply cephclient
+

This will try to detect a prior installation of a Ceph client with the install type container or package and cleanup that previous installation.

+

Network configuration

+

Some useful ansible variables for the options from the Rook Network Configuration Settings are available. +If you want complete flexibility, you can also use the rook_network variable which abstracts all settings from Rook Network Configuration Settings.

+

Configuring addressRanges

+
environments/rook/configuration.yml
rook_network_public: "192.168.16.0/24"
rook_network_cluster: "192.168.17.0/24"
+

Configuring encryption, compression, msgr2

+
environments/rook/configuration.yml
rook_network_encryption: true
rook_network_compression: true
rook_network_require_msgr2: false
+

Flexible approach using rook_network

+
environments/rook/configuration.yml
rook_network_encryption: true
rook_network_compression: true
rook_network_require_msgr2: false
rook_network_public: "192.168.16.0/20"
rook_network_cluster: "{{ rook_network_public }}"
rook_network:
connections:
# Whether to encrypt the data in transit across the wire to prevent eavesdropping the data on the network.
# The default is false. When encryption is enabled, all communication between clients and Ceph daemons, or between Ceph daemons will be encrypted.
# When encryption is not enabled, clients still establish a strong initial authentication and data integrity is still validated with a crc check.
# IMPORTANT: Encryption requires the 5.11 kernel for the latest nbd and cephfs drivers. Alternatively for testing only,
# you can set the "mounter: rbd-nbd" in the rbd storage class, or "mounter: fuse" in the cephfs storage class.
# The nbd and fuse drivers are *not* recommended in production since restarting the csi driver pod will disconnect the volumes.
encryption:
enabled: "{{ rook_network_encryption }}"
# Whether to compress the data in transit across the wire. The default is false.
# Requires Ceph Quincy (v17) or newer. Also see the kernel requirements above for encryption.
compression:
enabled: "{{ rook_network_compression }}"
# Whether to require communication over msgr2. If true, the msgr v1 port (6789) will be disabled
# and clients will be required to connect to the Ceph cluster with the v2 port (3300).
# Requires a kernel that supports msgr v2 (kernel 5.11 or CentOS 8.4 or newer).
requireMsgr2: "{{ rook_network_require_msgr2 }}"
# enable host networking
provider: host
addressRanges:
public:
- "{{ rook_network_public }}"
cluster:
- "{{ rook_network_cluster }}"
+

RGW service - CephObjectStore CRD

+
info

OpenStack integration between Keystone/Swift and Rook is currently missing upstream in Rook. Please have a look at #1027 to get the current status of the integration in OSISM.

+

Have a look at CephObjectStore CRD Spec for details on how to configure the RGW service.

+
environments/rook/configuration.yml
rook_cephobjectstore_default_name: rgw
rook_cephobjectstore_replicated_default_size: 3
rook_cephobjectstore_erasurecoded_default_datachunks: 2
rook_cephobjectstore_erasurecoded_default_codingchunks: 1
rook_cephobjectstore_failuredomain: host
rook_cephobjectstore_default_port: 8081
rook_cephobjectstore_preservepoolsondelete: true
rook_cephobjectstore_keystone_acceptedRoles: []
# - admin
# - member
rook_cephobjectstore_keystone_implicitTenants: ""
rook_cephobjectstore_keystone_revocationInterval: 1200
rook_cephobjectstore_keystone_tokenCacheSize: 1000
rook_cephobjectstore_keystone_url: ""
rook_cephobjectstore_swift_accountInUrl: true
rook_cephobjectstore_swift_urlPrefix: ""
rook_cephobjectstore_swift_versioningEnabled: true
rook_cephobjectstore_s3_authKeystone: true
rook_cephobjectstore_s3_enable: true
# name of the secret that provides admin user credentials needs to be in same namespace
rook_cephobjectstore_keystone_serviceUserSecretName: ceph-rgw-usersecret
# the following settings belong to the usersecret
rook_cephobjectstore_keystone_auth_type: ""
rook_cephobjectstore_keystone_identity_api_version: 3
rook_cephobjectstore_keystone_password: ""
rook_cephobjectstore_keystone_project_domain_name: "Default"
rook_cephobjectstore_keystone_project_name: ""
rook_cephobjectstore_keystone_user_domain_name: "Default"
rook_cephobjectstore_keystone_username: ""
rook_cephobjectstores:
- name: "{{ rook_cephobjectstore_default_name }}"
spec:
metadataPool:
failureDomain: "{{ rook_cephobjectstore_failuredomain }}"
replicated:
size: "{{ rook_cephobjectstore_replicated_default_size }}"
# erasureCoded:
# dataChunks: "{{ rook_cephobjectstore_erasurecoded_default_datachunks }}"
# codingChunks: "{{ rook_cephobjectstore_erasurecoded_default_codingchunks }}"
dataPool:
failureDomain: "{{ rook_cephobjectstore_failuredomain }}"
replicated:
size: "{{ rook_cephobjectstore_replicated_default_size }}"
# erasureCoded:
# dataChunks: "{{ rook_cephobjectstore_erasurecoded_default_datachunks }}"
# codingChunks: "{{ rook_cephobjectstore_erasurecoded_default_codingchunks }}"
preservePoolsOnDelete: "{{ rook_cephobjectstore_preservepoolsondelete }}"
gateway:
port: "{{ rook_cephobjectstore_default_port }}"
resources: "{{ rook_resources_cephobjecstore }}"
# securePort: 443
# sslCertificateRef:
instances: 1
priorityClassName: system-cluster-critical
placement: "{{ rook_placement_cephobjectstore }}"
annotations: "{{ rook_annotations_cephobjecstore }}"
auth:
keystone:
acceptedRoles: "{{ rook_cephobjectstore_keystone_acceptedRoles }}"
implicitTenants: "{{ rook_cephobjectstore_keystone_implicitTenants }}"
revocationInterval: "{{ rook_cephobjectstore_keystone_revocationInterval }}"
serviceUserSecretName: "{{ rook_cephobjectstore_keystone_serviceUserSecretName }}"
tokenCacheSize: "{{ rook_cephobjectstore_keystone_tokenCacheSize }}"
url: "{{ rook_cephobjectstore_keystone_url }}"
protocols:
swift:
accountInUrl: "{{ rook_cephobjectstore_swift_accountInUrl }}"
urlPrefix: "{{ rook_cephobjectstore_swift_urlPrefix }}"
versioningEnabled: "{{ rook_cephobjectstore_swift_versioningEnabled }}"
s3:
authKeystone: "{{ rook_cephobjectstore_s3_authKeystone }}"
enable: "{{ rook_cephobjectstore_s3_enable }}"
storageClass:
enabled: false
+

Cephfs - CephFilesystem CRD

+

Have a look at CephFilesystem CRD Spec for details on how to configure Cephfs.

+
environments/rook/configuration.yml
rook_cephfilesystem_default_name: cephfs
rook_cephfilesystem_replicated_default_size: 3
rook_cephfilesystem_erasurecoded_default_datachunks: 2
rook_cephfilesystem_erasurecoded_default_codingchunks: 1
rook_cephfilesystem_default_metadatapool_parameters_compression_mode: none
rook_cephfilesystem_default_datapool_parameters_compression_mode: none
rook_cephfilesystems:
- name: "{{ rook_cephfilesystem_default_name }}"
spec:
metadataPool:
failureDomain: host
# The metadata pool spec must use replication.
replicated:
size: "{{ rook_cephfilesystem_replicated_default_size }}"
requireSafeReplicaSize: true
parameters:
compression_mode: "{{ rook_cephfilesystem_default_datapool_parameters_compression_mode }}"
# target_size_ratio: ".5"
dataPools:
- failureDomain: host
# The data pool spec can use replication or erasure coding.
replicated:
size: "{{ rook_cephfilesystem_replicated_default_size }}"
requireSafeReplicaSize: true
# erasureCoded:
# dataChunks: "{{ rook_cephfilesystem_erasurecoded_default_datachunks }}"
# codingChunks: "{{ rook_cephfilesystem_erasurecoded_default_codingchunks }}"
name: data0
parameters:
compression_mode: "{{ rook_cephfilesystem_default_datapool_parameters_compression_mode }}"
# target_size_ratio: ".5"
metadataServer:
activeCount: "{{ rook_mds_count }}"
activeStandby: true
resources: "{{ rook_resources_cephfilesystem }}"
priorityClassName: system-cluster-critical"
placement: "{{ rook_placement_cephfilesystem }}"
annotations: "{{ rook_annotations_cephfilesystem }}"
storageClass:
enabled: false
+

Extra pools - CephBlockPool CRD

+

Extra pools can be defined via the rook_cephblockpools parameter. Be sure to also include the default pools. +They will use the default values from the rook_cephblockpool_* variables.

+

Have a look at CephBlockPool CRD Spec for details.

+
environments/rook/configuration.yml
rook_cephblockpool_replicated_default_size: 3
rook_cephblockpool_erasurecoded_default_datachunks: 2
rook_cephblockpool_erasurecoded_default_codingchunks: 1
rook_cephblockpool_default_min_size: "0"
rook_cephblockpool_default_pg_num: "128"
rook_cephblockpools:
# default pools
- name: backups
spec:
failureDomain: host
replicated:
size: "{{ rook_cephblockpool_replicated_default_size }}"
parameters:
min_size: "{{ rook_cephblockpool_default_min_size }}"
pg_num: "{{ rook_cephblockpool_default_pg_num }}"
pgp_num: "{{ rook_cephblockpool_default_pg_num }}"
storageClass:
enabled: false
- name: volumes
spec:
failureDomain: host
replicated:
size: "{{ rook_cephblockpool_replicated_default_size }}"
parameters:
min_size: "{{ rook_cephblockpool_default_min_size }}"
pg_num: "{{ rook_cephblockpool_default_pg_num }}"
pgp_num: "{{ rook_cephblockpool_default_pg_num }}"
storageClass:
enabled: false
- name: images
spec:
failureDomain: host
replicated:
size: "{{ rook_cephblockpool_replicated_default_size }}"
parameters:
min_size: "{{ rook_cephblockpool_default_min_size }}"
pg_num: "{{ rook_cephblockpool_default_pg_num }}"
pgp_num: "{{ rook_cephblockpool_default_pg_num }}"
storageClass:
enabled: false
- name: metrics
spec:
failureDomain: host
replicated:
size: "{{ rook_cephblockpool_replicated_default_size }}"
parameters:
min_size: "{{ rook_cephblockpool_default_min_size }}"
pg_num: "{{ rook_cephblockpool_default_pg_num }}"
pgp_num: "{{ rook_cephblockpool_default_pg_num }}"
storageClass:
enabled: false
- name: vms
spec:
failureDomain: host
replicated:
size: "{{ rook_cephblockpool_replicated_default_size }}"
parameters:
min_size: "{{ rook_cephblockpool_default_min_size }}"
pg_num: "{{ rook_cephblockpool_default_pg_num }}"
pgp_num: "{{ rook_cephblockpool_default_pg_num }}"
storageClass:
enabled: false
# extra pools
- name: extra1
spec:
failureDomain: host
replicated:
size: "{{ rook_cephblockpool_replicated_default_size }}"
parameters:
min_size: "{{ rook_cephblockpool_default_min_size }}"
pg_num: "{{ rook_cephblockpool_default_pg_num }}"
pgp_num: "{{ rook_cephblockpool_default_pg_num }}"
storageClass:
enabled: false
- name: extra2
spec:
failureDomain: host
erasureCoded:
dataChunks: "{{ rook_cephblockpool_erasurecoded_default_datachunks }}"
codingChunks: "{{ rook_cephblockpool_erasurecoded_default_codingchunks }}"
parameters:
min_size: "{{ rook_cephblockpool_default_min_size }}"
pg_num: "{{ rook_cephblockpool_default_pg_num }}"
pgp_num: "{{ rook_cephblockpool_default_pg_num }}"
storageClass:
enabled: false
+

Storage configuration

+
info

In the default setup, no OSD will be deployed (better safe than sorry approach).

+

You have to pass a storage configuration via environments/rook/configuration.yml.

+

Some useful ansible variables for the options from the Rook Storage Selection Settings are available. +If you want complete flexibility, you can also use the rook_storage variable which abstracts all settings from Rook Storage Selection Settings.

+

Deploy OSDs on all nodes and found devices

+
environments/rook/configuration.yml
rook_storage_useallnodes: true
rook_storage_usealldevices: true
+

Deploy OSDs on specific nodes and devices based on a device filter

+
environments/rook/configuration.yml
rook_storage_useallnodes: false
rook_storage_usealldevices: false
rook_storage_devicefilter: "^sd[b-c]"
rook_storage_nodes:
- name: "testbed-node-0"
- name: "testbed-node-1"
- name: "testbed-node-2"
+

Deploy OSDs on specific nodes and devices based on device names

+
environments/rook/configuration.yml
rook_storage_useallnodes: false
rook_storage_usealldevices: false
rook_storage_nodes:
- name: "testbed-node-0"
devices:
- name: "/dev/sdb"
- name: "/dev/sdc"
- name: "/dev/sde"
- name: "testbed-node-1"
devices:
- name: "/dev/sdf"
- name: "/dev/sdg"
- name: "/dev/sdh"
- name: "testbed-node-2"
devices:
- name: "/dev/sdi"
- name: "/dev/sdj"
- name: "/dev/sdk"
+

Flexible approach using rook_storage

+
environments/rook/configuration.yml
# do not use all nodes
rook_storage_useallnodes: false
# do not use all found devices
rook_storage_usealldevices: false
rook_storage_config_osdsperdevice: "1"
# enable device encryption
rook_storage_config_encrypteddevice: "true"
# define a device filter where to create OSDs
rook_storage_devicefilter: ""
# name nodes where to create OSDs
rook_storage_nodes: []
# - name: "testbed-node-0"
# - name: "testbed-node-1"
# - name: "testbed-node-2"
rook_storage:
useAllNodes: "{{ rook_storage_useallnodes }}"
useAllDevices: "{{ rook_storage_usealldevices }}"
config:
crushRoot: "custom-root" # specify a non-default root label for the CRUSH map
metadataDevice: "md0" # specify a non-rotational storage so ceph-volume will use it as block db device of bluestore.
databaseSizeMB: "1024" # uncomment if the disks are smaller than 100 GB
osdsPerDevice: "{{ rook_storage_config_osdsperdevice }}" # this value can be overridden at the node or device level
encryptedDevice: "{{ rook_storage_config_encrypteddevice }}" # the default value for this option is "false"
# # Individual nodes and their config can be specified as well, but 'useAllNodes' above must be set to false. Then, only the named
# # nodes below will be used as storage resources. Each node's 'name' field should match their 'kubernetes.io/hostname' label.
nodes:
- name: "172.17.4.201"
devices: # specific devices to use for storage can be specified for each node
- name: "sdb"
- name: "nvme01" # multiple osds can be created on high performance devices
config:
osdsPerDevice: "5"
- name: "/dev/disk/by-id/ata-ST4000DM004-XXXX" # devices can be specified using full udev paths
config: # configuration can be specified at the node level which overrides the cluster level config
- name: "172.17.4.301"
deviceFilter: "^sd."
+

Encrypted OSDs

+

OSDs are encrypted by default. Rook creates a LUKS on LVM setup for this. Encryption keys are managed by Ceph, as usual.

+
info

Provisioning LUKS on already existing logical volumes is not supported currently by Rook.

+

Have a look at the Ceph documentation on LVM encryption and the Rook OSD Configuration Settings for details.

+

If you want complete flexibility, look into the details of the Helm Value File.

+

Dashboard

+

Password for the admin user of the Ceph dashboard is automatically generated by rook and can be retrieved like this:

+
kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}" | base64 --decode && echo
+

Have a look at the Rook Ceph Dashboard Documentation for details.

+

Some useful ansible variables for the options from the Rook Ceph Dashboard Documentation are available.

+

Enable dashboard and configure ssl and ports

+

The Ceph dashboard is deployed by default and also an LoadBalancer Service is created in Kubernetes.

+
environments/rook/configuration.yml
rook_dashboard_enabled: true
rook_dashboard_ssl: true
rook_dashboard_port: 7000
rook_dashboard_port_external: 443
+

Rook Cluster Name

+

The name that will be used internally for the Ceph cluster can be changed. Most commonly the name is the same as the namespace since multiple clusters are not supported in the same namespace.

+
environments/rook/configuration.yml
rook_cluster_name: rook-ceph
+

Kubernetes Namespaces

+

The Kubernetes namespace that will be created for the Rook cluster can be changed. The services, pods, and other resources created by the operator will be added to this namespace. The common scenario is to create a single Rook cluster. If multiple clusters are created, they must not have conflicting devices or host paths.

+

By default, both for the operator and the rook cluster, the namespace rook-ceph is used.

+
environments/rook/configuration.yml
rook_operator_namespace: rook-ceph
rook_namespace: rook-ceph
+

Number and Placement of Ceph Daemons

+

The number and placement of Ceph daemons can be changed.

+
environments/rook/configuration.yml
rook_mon_count: 3
rook_mds_count: 3
rook_mgr_count: 3
+

Please read Rook MON Settings, Rook MGR Settings and Rook MDS Settings to understand which configurations make sense.

+

The following inventory groups are defined with defaults and can be used to control the node affinity regarding the indicated Ceph components:

+
    +
  • rook-mds
  • +
  • rook-mgr
  • +
  • rook-mon
  • +
  • rook-osd
  • +
  • rook-rgw
  • +
+

To customise those inventory groups it is possible to do so in the following format:

+
inventory/20-roles
[rook-mds:children]
ceph-control

[rook-mgr:children]
ceph-control

[rook-mon:children]
ceph-control

[rook-osd:children]
ceph-resource

[rook-rgw:children]
ceph-control
+

Nodes assigned to those groups will be labeled and then be utilised during the scheduling of the pods with a configuration like the following for each component:

+
environments/rook/configuration.yml
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "node-role.osism.tech/{{ rook_placement_label_mon }}"
operator: In
values:
- "true"
+

If you decide after the initial deployment to move Ceph components to different nodes you can do so modifying inventory/20-roles and run osism apply rook-change-labels afterwards.

+

Crash Collector

+

The Ceph Crash Module is enabled by default. You can also configure how long to retain the crash reports.

+
environments/rook/configuration.yml
rook_crashcollector:
disable: false
daysToRetrain: 7
+

Log Collector

+

The log collector will run as a side-car next to each Ceph daemon. The Ceph configuration option log_to_file will be turned on, meaning Ceph daemons will log on files in addition to still logging to container's stdout. These logs will be rotated.

+

See Rook Cluster Settings for more details.

+
environments/rook/configuration.yml
rook_logcollector:
enabled: true
periodicity: daily # one of: hourly, daily, weekly, monthly
maxLogSize: 500M # SUFFIX may be 'M' or 'G'. Must be at least 1M.
+

Ceph Config

+
info

The Ceph Config feature is currently in an experimental state in the Rook project.

+

Please read Ceph Config for details on how to use and what to expect from this feature.

+
environments/rook/configuration.yml
rook_cephconfig:
global:
# All values must be quoted so they are considered a string in YAML
osd_pool_default_size: "3"
mon_warn_on_pool_no_redundancy: "false"
osd_crush_update_on_start: "false"
# Make sure to quote special characters
"osd.*":
osd_max_scrubs: "10"
+

Second Ceph cluster

+

In theory, this is completely customizable by deploying multiple helm releases. No evaluation has been done so far, though and this is currently not implemented in OSISM.

+

Helm Value File

+

The OSISM Rook role is an opinionated and sane default configuration. If you reach the limits of what is customizable via ansible variables or have a very custom setup, you can pass a custom or additional values.yml files or even any Rook CRD to the role and it will be jinja2 templated and roled out to the kubernetes cluster.

+

Just overwrite rook_configuration_directory and place any *.yml.j2 files that you want to apply there.

+
environments/rook/configuration.yml
rook_template_directory: "{{ configuration_directory }}/environments/rook/files"
+
    +
  • Helm values.yml files need to be named *-helm-values-*.yml.j2
  • +
  • custom CRDs need to be named *-CRD-*.yml.j2
  • +
+

It makes sense to also include the default templates and change them (to e.g. use already existing ansible variables) add your custom settings on top or change them to fit your use cases.

+

Get the default templates from the osism-ansible container or download them from github.

+
mkdir /opt/configuration/environments/rook/files
cd /opt/configuration/environments/rook/files
for file in 01-helm-values-all.yml.j2 02-CRD-CephClient.yml.j2 ; do
curl -O "https://raw.githubusercontent.com/osism/ansible-collection-services/main/roles/rook/templates/${file}"
done
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/rookify/index.html b/docs/iaas/guides/configuration-guide/rookify/index.html new file mode 100644 index 0000000000..2ca87a52ca --- /dev/null +++ b/docs/iaas/guides/configuration-guide/rookify/index.html @@ -0,0 +1,59 @@ + + + + + +Configure Rookify: Migrate from Ceph-Ansible to Rook (Technical Preview) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Configure Rookify: Migrate from Ceph-Ansible to Rook (Technical Preview)

+
warning

Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime. +Nevertheless, it is strongly advised to test Rookify in a controlled environment first, such as the OSISM testbed. Additionally ensure that precautionary backups are made and all other necessary safety measures are in place.

+

For a condensed summary of the information covered here, refer to the Rookify GitHub repository.

+

Config.yaml

+

The primary configuration file for Rookify is config.yaml. The repository includes an example file for general use, as well as one specifically tailored for OSISM based setups:

+ +

Parameters

+

General

+
config.example.yaml
general:
machine_pickle_file: data.pickle
+

The general section allows for the optional definition of a pickle file, which saves the state of the migration as serialized objects on disk. The pickle file can be named as desired.

+

Logging

+
config.example.yaml
logging:
level: INFO # level at which logging should start
format:
time: "%Y-%m-%d %H:%M.%S" # other example: "iso"
renderer: console # or: json
+

The logging section allows for specification of structlog. The level parameter can be set to any Python log-levels, such as NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAl, but using INFO is recommended.

+

Ceph

+
config.example.yaml

ceph:
config: ./.ceph/ceph.conf
keyring: ./.ceph/ceph.client.admin.keyring
+

The ceph section specifies the paths for the ceph.conf and ceph.client.admin.keyring files on the target system (the system where Ceph-Ansible needs to be migrated to Rook).

+

SSH

+
config.example.yaml
# specify the correct path to the private key
ssh:
private_key: /home/USER/.ssh/cloud.private
hosts:
testbed-node-0:
address: 192.168.16.10
user: dragon
testbed-node-1:
address: 192.168.16.11
user: dragon
testbed-node-2:
address: 192.168.16.12
user: dragon
+

The ssh section specifies the private_key and hosts. The hosts section includes hostnames or aliases (e.g. testbed-node-0), their IP addresses (e.g., for VPN connections, IPs starting with 192.186...), and the user for login. If you are using the OSISM testbed, ensure the private key does not contain any extra strings like EOF. The keys must be 'clean' to avoid connection errors.

+

Kubernetes

+
config.example.yaml

kubernetes:
config: ./k8s/config
+

The kubernetes section specifies the Kubernetes configuration (e.g. if you use kubectl, this is usually located in ~/.kube/config) for Rookify's Kubernetes library. Rookify needs to connect to the Kubernetes cluster on the target systems to use Rook.

+
config.example.yaml
rook:
cluster:
name: osism-ceph
namespace: rook-ceph
ceph:
image: quay.io/ceph/ceph:v18.2.1
+

The rook sections requires information about the Rook installation on the target system. For the cluster, Rookify needs the cluster name and namespace. Additionally, Rookify requires the Ceph version being used, i.e., the image version of the Ceph container.

+
note

Rookify does not install Rook for you. You need to provide a running Rook installation, i.e. a Rook Operator, on your target system.

+

For OSISM-specific migrations, Rookify needs additional information, such as the respective labels for the Rook resources:

+
config.example.osism.yaml
rook:
cluster:
name: osism-ceph
namespace: rook-ceph
mds_placement_label: node-role.osism.tech/rook-mds
mgr_placement_label: node-role.osism.tech/rook-mgr
mon_placement_label: node-role.osism.tech/rook-mon
osd_placement_label: node-role.osism.tech/rook-osd
rgw_placement_label: node-role.osism.tech/rook-rgw
ceph:
image: quay.io/ceph/ceph:v18.2.1
+

Migration_modules

+
config.example.yaml
migration_modules:
- analyze_ceph
- create_rook_cluster
- migrate_mons
- migrate_osds
- migrate_osd_pools
- migrate_mds
- migrate_mds_pools
- migrate_mgrs
- migrate_rgws
- migrate_rgw_pools
+

Rookify uses a modular structure, allowing you to migrate various parts of Ceph-Ansible to Rook. The migration_modules section specifies which modules need to be executed for the migration. Rookify contains more modules — check the src/rookify/module directory to see the currently implemented modules.

+
note

Many modules depend on each other. For example, the analyze_ceph module will automatically run with all other modules, so +there is no need to specify it. It’s included here for clarity.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/services/chrony/index.html b/docs/iaas/guides/configuration-guide/services/chrony/index.html new file mode 100644 index 0000000000..14c1d2f0db --- /dev/null +++ b/docs/iaas/guides/configuration-guide/services/chrony/index.html @@ -0,0 +1,26 @@ + + + + + +Chrony | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/services/docker/index.html b/docs/iaas/guides/configuration-guide/services/docker/index.html new file mode 100644 index 0000000000..57465c1a66 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/services/docker/index.html @@ -0,0 +1,40 @@ + + + + + +Docker | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Docker

+

With the osism.services.docker role, it is possible to manage Docker.

+

Configure logging drivers

+

Docker documentation: https://docs.docker.com/config/containers/logging/configure/

+

The role currently supports the following parameters with their respective defaults.

+
docker_log_driver: "json-file"
docker_log_level: info
docker_log_opts:
max-size: 10m
max-file: 3
+

The log driver to be used can be configured with docker_log_driver. By default, +json-file is used. +The log driver writes all logs of a container to a JSON file +in /var/lib/docker/containers. All supported log drivers can be found in the +Docker documentation.

+

The log level can be configured via docker_log_level.

+

Parameters for the log driver used can be set with the docker_log_opts dictionary. +By default, the maximum size of a JSON file is set to 10 MByte with max-size: 10m. +If it contains more, the file is rotated.

+

Furthermore, max-file: 3 specifies that up to 3 files should be available.

+

Existing containers don't use the new logging configuration automatically.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/services/index.html b/docs/iaas/guides/configuration-guide/services/index.html new file mode 100644 index 0000000000..62559665d9 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/services/index.html @@ -0,0 +1,26 @@ + + + + + +Services | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/services/tuned/index.html b/docs/iaas/guides/configuration-guide/services/tuned/index.html new file mode 100644 index 0000000000..7252c580e3 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/services/tuned/index.html @@ -0,0 +1,30 @@ + + + + + +Tuned | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Tuned

+

The roller can be applied with osism apply tuned. The role is applied to all +compute nodes by default. This can be changed via the hosts_tuned parameter.

+

The profile to be used can be set via tuned_profile. By default, virtual-host +is used.

+

The following profiles are available:

+
ProfileDescription
accelerator-performanceThroughput performance based tuning with disabled higher latency STOP states
atomic-guestOptimize virtual guests based on the Atomic variant
atomic-hostOptimize bare metal systems running the Atomic variant
balancedGeneral non-specialized tuned profile
cpu-partitioningOptimize for CPU partitioning
defaultLegacy default tuned profile
desktopOptimize for the desktop use-case
desktop-powersaveOptmize for the desktop use-case with power saving
enterprise-storageLegacy profile for RHEL6, for RHEL7, please use throughput-performance profile
hpc-computeOptimize for HPC compute workloads
intel-sstConfigure for Intel Speed Select Base Frequency
laptop-ac-powersaveOptimize for laptop with power savings
laptop-battery-powersaveOptimize laptop profile with more aggressive power saving
latency-performanceOptimize for deterministic performance at the cost of increased power consumption
mssqlOptimize for MS SQL Server
network-latencyOptimize for deterministic performance at the cost of increased power consumption, focused on low latency network performance
network-throughputOptimize for streaming network throughput, generally only necessary on older CPUs or 40G+ networks
optimize-serial-consoleOptimize for serial console use.
oracleOptimize for Oracle RDBMS
postgresqlOptimize for PostgreSQL server
powersaveOptimize for low power consumption
realtimeOptimize for realtime workloads
sap-hanaOptimize for SAP HANA
sap-netweaverOptimize for SAP NetWeaver
server-powersaveOptimize for server power savings
spectrumscale-eceOptimized for Spectrum Scale Erasure Code Edition Servers
spindown-diskOptimize for power saving by spinning-down rotational disks
throughput-performanceBroadly applicable tuning that provides excellent performance across a variety of common server workloads
virtual-guestOptimize for running inside a virtual guest
virtual-hostOptimize for running KVM guests
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/validations/index.html b/docs/iaas/guides/configuration-guide/validations/index.html new file mode 100644 index 0000000000..e61bbb6a76 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/validations/index.html @@ -0,0 +1,26 @@ + + + + + +Validations | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/bootstrap/index.html b/docs/iaas/guides/deploy-guide/bootstrap/index.html new file mode 100644 index 0000000000..861c04d005 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/bootstrap/index.html @@ -0,0 +1,129 @@ + + + + + +Bootstrap | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Bootstrap

+
info

The prerequisite for bootstraping the nodes of a cluster the Manager node has to be +prepares. What a Manager node is and how to prepare it is documented in the +Manager chapter of the Deploy Guide.

All the nodes must also have already been provisioned. How manual provisioning is done +is documented in the Provisioning chapter of the Deploy Guide.

+

Before the nodes can be bootstrapped, they must all have already been provisioned. +The guide for this can be found in the section Provisioning of bare-metal nodes.

+

The following steps are applied to bootstrap all nodes. After the completion of the bootstrap, +the nodes are already ready for use.

+
    +
  1. +

    Create operator user.

    +
    osism apply operator -u osism
    +
      +
    • +

      When using the osism/node-image the user is osism +and the password of this user is password. If you install Ubuntu manually the user usually +is ubuntu. If you want to use any other user here, with exception of dragon, that's no problem. +The later used operator user dragon is created during the bootstrap and should not be created +during the installation. Do not use dragon as username. It is important that +this user has sudo rights. The password according to what you have set yourself.

      +
    • +
    • +

      The operator public SSH key has to be added in advance on all nodes to authorized_keys file +of the user specified with -u. This key is stored as operator_public_key in the file +environments/configuration.yml.

      +

      Alternatively (not recommended), the password can be stored in plain text in a file /opt/configuration/secrets/conn_password. +The parameter --conn-pass-file /opt/configuration/secrets/conn_password must then also be specified:

      +
      osism apply operator -u osism \
      --conn-pass-file /opt/configuration/secrets/conn_password
      +
    • +
    • +

      It is important that this user has sudo rights with NOPASSWD.

      +

      Alternatively (not recommended), the password can be stored in plain text in a file /opt/configuration/secrets/become_password. +The parameter --become-pass-file /opt/configuration/secrets/become_password must then also be specified:

      +
      osism apply operator -u osism \
      --become-pass-file /opt/configuration/secrets/become_password
      +
    • +
    • +

      If a password is required for both sudo and login, use both arguments at the same time.

      +
      osism apply operator -u osism \
      --become-pass-file /opt/configuration/secrets/become_password \
      --conn-pass-file /opt/configuration/secrets/conn_password
      +
    • +
    • +

      When using the osism/node-image the user is osism and the password of this +user is password. If you install Ubuntu manually the user usually is ubuntu. The password according to what you +have set yourself

      +
    • +
    +
  2. +
  3. +

    Proxy deployment (optional). This is only necessary if you use the proxy on the manager to enable external access to +the nodes.

    +
    osism apply squid
    +
  4. +
  5. +

    Proxy configuration (optional). This is only necessary if you use the proxy on the manager to enable external access to +the nodes.

    +
    osism apply proxy
    +
  6. +
  7. +

    Network configuration. It is recommended to backup the existing network configuration.

    +
    osism apply network
    +
  8. +
  9. +

    Reboot (optional). The reboot at this point is recommended to ensure that the network configuration is working.

    +
    osism apply reboot -l 'all:!manager' -e ireallymeanit=yes
    +
  10. +
  11. +

    Check if all systems are reachable (you probably have to do this several times until all systems are accessible).

    +
    osism apply ping
    +
      +
    • +

      System is currently rebooting and is not yet accessible via network.

      +
      fatal: [net003]: UNREACHABLE! => {"changed": false, "msg": "Connection timed
      out.", "unreachable": true}``
      +
    • +
    • +

      System has already been rebooted and is not accessible via the network.

      +
      fatal: [net003]: UNREACHABLE! => {"changed": false, "msg": "EOF on stream;
      last 100 lines received:\nssh: connect to host 10.15.0.33 port 22: No route
      to host\r", "unreachable": true}
      +
    • +
    +
  12. +
  13. +

    Refresh facts.

    +
    osism apply facts
    +
  14. +
  15. +

    Bootstrap.

    +
    osism apply bootstrap
    +
  16. +
  17. +

    Reboot (non-optional). Since the kernel version often changes after the initial bootstrap, +the reboot should always be performed.

    +
    osism apply reboot -l 'all:!manager' -e ireallymeanit=yes
    +
  18. +
  19. +

    Check if all systems are reachable (you probably have to do this several times until all systems are accessible).

    +
    osism apply ping
    +
  20. +
  21. +

    Prepare the SSH configuration of the manager node.

    +
    osism apply sshconfig
    +
  22. +
  23. +

    Make all SSH public keys known.

    +
    osism apply known-hosts
    +
  24. +
+

Ready. All nodes are now bootstrapped and available to deploy services.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box/index.html b/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box/index.html new file mode 100644 index 0000000000..2b84457492 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box/index.html @@ -0,0 +1,27 @@ + + + + + +Cloud in a Box | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/examples/index.html b/docs/iaas/guides/deploy-guide/examples/index.html new file mode 100644 index 0000000000..e612cbc30e --- /dev/null +++ b/docs/iaas/guides/deploy-guide/examples/index.html @@ -0,0 +1,24 @@ + + + + + +Examples | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/examples/testbed/index.html b/docs/iaas/guides/deploy-guide/examples/testbed/index.html new file mode 100644 index 0000000000..173c2a90db --- /dev/null +++ b/docs/iaas/guides/deploy-guide/examples/testbed/index.html @@ -0,0 +1,27 @@ + + + + + +Testbed | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/index.html b/docs/iaas/guides/deploy-guide/index.html new file mode 100644 index 0000000000..630f095f32 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/index.html @@ -0,0 +1,36 @@ + + + + + +Deploy Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/manager/index.html b/docs/iaas/guides/deploy-guide/manager/index.html new file mode 100644 index 0000000000..88d47fe1d0 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/manager/index.html @@ -0,0 +1,165 @@ + + + + + +Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Manager

+
info

The prerequisite for deploying the Manager node is a Seed node. What a Seed node is +and how to prepare it is documented in the Seed chapter of the Deploy Guide.

+

The Manager node serves as the central administration instance for managing the cloud environment. +With the help of Ansible and other OSISM-specific components, the entire +life cycle of the system is coordinated from here (installation, customization, upgrades, etc.).

+

Requirements for the manager node:

+
    +
  • The system should have the following hardware features +
      +
    • at least 64 GB RAM (We assume here that the monitoring services are also run on the manager. +If the manager node is only used for the sanager Service, 32 GByte is sufficient and +with 16 GByte it will probably also work.
    • +
    • at least 256 GB hard disk space
    • +
    • the system should be initially and permanently accessible independently of the cloud environment +itself from the seed node
    • +
    • the system should have direct access to the network areas of the individual server systems in the +cloud environment
    • +
    +
  • +
  • An Ubuntu version matching the OSISM version should be provisioned on the system +(typically the latest Ubuntu LTS version, a system based on one of the OSISM node images +would be ideal)
  • +
  • No manual adjustments or installations should have been made on the system apart from the basic installation
  • +
  • The system has to be accessible from the seed node via SSH
  • +
+

Deploy the manager service

+

Change into the environments/manager directory of the configuration repository +on the seed node. The deployment of the seed node itself is documented in the +Deploy Guide for the seed node.

+
cd environments/manager
+

If you are working with Git branches, read the instructions.

+

Step 1: Create operator user

+

The operator user is created on each node. It is used as a service account for OSISM. All +containers run with this user. Ansible also uses this user to access the nodes. Commands +on the manager node need to be run as this user. The name of the operator user is always dragon.

+

With ANSIBLE_USER the existing user account is set after the provsioning of the management +node. When using the osism/node-image the user is osism +and the password of this user is password. If you install Ubuntu manually the user usually +is ubuntu. If you want to use any other user here, that's no problem. It is important that +this user has sudo rights. The password according to what you have set yourself.

+

The ANSIBLE_USER parameter is only required when executing operator play using the run.sh +script. After this step, the ANSIBLE_USER is always set to dragon in the run.sh script. +It is therefore important to only set this parameter for exactly this step.

+
ANSIBLE_BECOME_ASK_PASS=True \
ANSIBLE_ASK_VAULT_PASS=True \
ANSIBLE_ASK_PASS=True \
ANSIBLE_USER=osism \
./run.sh operator
+

When the ./run.sh operator is executed, the following prompts are displayed:

+
PromptValueComment
SSH password:Password so that the ANSIBLE_USER can loginEnabled by ANSIBLE_ASK_PASS
BECOME password[defaults to SSH password]:Password so that the ANSIBLE_USER can use sudoEnabled by ANSIBLE_BECOME_ASK_PASS
Vault password:Value of secrets/vaultpassEnabled by ANSIBLE_ASK_VAULT_PASS
+

Useful information if something goes wrong in the step described

+
    +
  • +

    If a password is required to login to the manager node, ANSIBLE_ASK_PASS=True must be set.

    +
  • +
  • +

    If an SSH key is required to login to the manager node, the key has to be added on the manager +node to ~/.ssh/authorized_keys in the home directory of the user specified as ANSIBLE_USER first.

    +
  • +
  • +

    If the error ERROR! Attempting to decrypt but no vault secrets found occurs, ANSIBLE_ASK_VAULT_PASS=True +has to be set.

    +
  • +
  • +

    If the error /bin/sh: 1: /usr/bin/python: not found occurs, Python has to be installed first on +the manager node:

    +
    ANSIBLE_USER=osism ./run.sh python3
    +
  • +
  • +

    If you receive the following error message ssh: Too many authentication failures set +ANSIBLE_SSH_ARGS environment variable to use only the operator ssh key for authentication.

    +
    export ANSIBLE_SSH_ARGS="-o IdentitiesOnly=yes"
    +
  • +
  • +

    The warning message [WARNING]: running playbook inside collection osism.manager can be ignored

    +
  • +
  • +

    If Ansible Vault is used, let Ansible ask for the Vault password:

    +
    export ANSIBLE_ASK_VAULT_PASS=True
    +
  • +
+

Details on all parameters can be found in +Ansible Configuration Settings +in the Ansible documentation.

+
Environment variableTypeDescription
ANSIBLE_ASK_PASSBooleanThis controls whether an Ansible playbook should prompt for a login password. If using SSH keys for authentication, you probably do not need to change this setting.
ANSIBLE_ASK_VAULT_PASSBooleanThis controls whether an Ansible playbook should prompt for a vault password.
ANSIBLE_BECOME_ASK_PASSBooleanToggle to prompt for privilege escalation password.
ANSIBLE_SSH_ARGSStringIf set, this will override the Ansible default ssh arguments.
ANSIBLE_USERStringThe user Ansible ‘logs in’ as.
+

To verify the proper creation of the operator user, use the private key file id_rsa.operator. Make +sure you purge all keys from ssh-agent identity cache using ssh-add -D. You can print the list +using ssh-add -l. The list should be empty.

+
ssh-add -D
ssh -o IdentitiesOnly=yes -i id_rsa.operator dragon@YOUR_MANAGER_NODE
+

Step 2: Apply the network configuration

+

Most of the parameters required for Ansible (ANSIBLE_BECOME_ASK_PASS, ANSIBLE_ASK_PASS, ANSIBLE_USER, ...) +in the previous step are no longer necessary. If Ansible Vault is used, however, ANSIBLE_ASK_VAULT_PASS +must still be set.

+
export ANSIBLE_ASK_VAULT_PASS=True
+

To prevent recurring installation of Ansible Collections, export INSTALL_ANSIBLE_ROLES=False can be set.

+

The network configuration, already present on a node should be backuped before this step. +Then you can deploy the network configuration with the network role.

+

Have a look to the network documentation and configure it before running this playbook.

+
./run.sh network
+

Upon completion of the network configuration, a node reboot should be performed to ensure the configuration +is functional and reboot safe. Since network services are not restarted automatically, later changes to the +network configuration are not effective without a manual apply of the network configuration or reboot of the +nodes.

+

Step 3: Bootstrap the manager node

+

Most of the parameters required for Ansible (ANSIBLE_BECOME_ASK_PASS, ANSIBLE_ASK_PASS, ANSIBLE_USER, ...) +in the previous step are no longer necessary.

+

If Ansible Vault is used, however, export ANSIBLE_ASK_VAULT_PASS=True must still be set.

+

To prevent recurring installation of Ansible Collections, export INSTALL_ANSIBLE_ROLES=False can be set. +This is recommended.

+
    +
  1. +

    Bootstrap the manager node.

    +
    ./run.sh bootstrap
    +
  2. +
  3. +

    Reboot the manager node.

    +
    ./run.sh reboot
    +
  4. +
+

Step 4: Deploy the manager service

+
    +
  1. +

    Transfer the configuration repository.

    +
    ./run.sh configuration
    +
  2. +
  3. +

    Deploy the Traefik service. This is optional and only necessary if the Traefik service is to be used.

    +
    ./run.sh traefik
    +
  4. +
  5. +

    Deploy the Netbox service. This is optional and only necessary if the Netbox service is to be used.

    +
    ./run.sh netbox
    +
  6. +
  7. +

    Deploy the manager service. +Have a look to the manager documentation and configure it before running this playbook.

    +
    ./run.sh manager
    +
  8. +
+

Step 5: Set vault password on the manager service

+

Finally, the Ansible Vault password is made known on the manager node. Before that, log in to the manager node +with the dragon user.

+
ssh -o IdentitiesOnly=yes -i  id_rsa.operator dragon@YOUR_MANAGER_NODE
osism set vault password
+

Ready. The manager is now prepared, and you can continue with the bootstrap of the other nodes. +The seed node used until here is now no longer necessary.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/provisioning/index.html b/docs/iaas/guides/deploy-guide/provisioning/index.html new file mode 100644 index 0000000000..39f6ca6fe5 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/provisioning/index.html @@ -0,0 +1,136 @@ + + + + + +Provisioning of bare-metal nodes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Provisioning of bare-metal nodes

+

For the initial deployment of the management plane and the control plane of OSISM, +the nodes must be pre-provisioned with Ubuntu 22.04. Currently, only Ubuntu 22.04 is supported +by OSISM.

+

Data plane nodes can be automatically provisioned after the initial deployment and +do not need to be pre-provisioned.

+

It is recommended not to install the initial nodes of the management plane and the +control plane manually. An ISO image is provided for this purpose which automatically +provisions a node. The ISO images are available for download in the +osism/node-image repository.

+

Automated Installation using Node Images

+

There are different variants of the ISO image. The variants differ in the disc layout.

+

The pre-build variants are described in the osism/node-image repository.

+

A good way to provision the nodes is to use virtual media mounts via the usually available Redfish +functionality of the BMC of the servers used. In this way, the basic installation can be carried +out without external dependencies such as adapting the switch configuration, DHCP, upstream connectivity, etc. +In many cases, this simplifies the process, makes it more automation-friendly and avoids potential sources of error.

+

OSISM also provides a tool to generate node images specific for you needs.

+

This makes particular sense for the node-provisioning in the following situations:

+
    +
  • Make complex configurations like layer3 underlay
  • +
  • Add your SSH keys to the image
  • +
  • Configure a specific root password
  • +
  • Change other characteristics of the setup +
      +
    • Templates
    • +
    • Partitioning
    • +
    • Packages
    • +
    • ...
    • +
    +
  • +
  • Develop new standard images
  • +
+

The procedures for building custom images are described in the +osism/node-image repository.

+

Manual provisioning

+

If none of the provided variants is suitable, this section describes the manual +installation with the help of the Ubuntu 22.04 live ISO image. The manual installation +is possible without network connectivity.

+
    +
  • Download the latest ISO image for Ubuntu 22.04 from releases.ubuntu.com. +
      +
    • Use the ubuntu-22.04.1-live-server-amd64.iso image.
    • +
    • The version number may be different, always use the latest available version of 22.04 LTS.
    • +
    +
  • +
  • Choose English as language.
  • +
  • Choose Install Ubuntu Server.
  • +
  • Choose English as language (again).
  • +
  • Choose your location (e.g. Germany).
  • +
  • Choose en_US.UTF-8 as locale.
  • +
  • Choose the keyboard layout from a list, use English (US).
  • +
  • Choose and configure the primary network interface. +
      +
    • Depending on the environment, the network may not work at this point. Then select any interface +and then select Do not configure the network at this time in the next step.
    • +
    +
  • +
  • Set the hostname. +
      +
    • The hostname is e.g. node and not a FQDN like node.systems.osism.xyz.
    • +
    +
  • +
  • Set osism as full name for the new user.
  • +
  • Set osism as the username for the account. +
      +
    • The later used operator user dragon is created during the bootstrap and should not be created during the installation. +Do not use dragon as username.
    • +
    • The account is only needed initially and can be deleted after completion of the bootstrap.
    • +
    +
  • +
  • Set a password for the account.
  • +
  • Choose Manual as partitioning method and execute the partitioning according to company specifications +
      +
    • The use of a UEFI is recommended
    • +
    • The use of a RAID is recommended. We prefer the use of software RAIDs to make us less dependent on hardware. +But there is nothing against using hardware RAIDs.
    • +
    • The use of a LVM2 is recommended. system is recommended as the name for the volume group.
    • +
    • Dedicated disks may be provided for /var/lib/docker on the controller nodes. In this case, do not +use an LV for /var/lib/docker but the devices provided for it.
    • +
    • Do not configure devices that are not required for the operating system.
    • +
    • The use of own file systems for the following mountpoints is recommended. The size of the partitions/LVs +is minimal. Depending on the node type, the partitions/LVs should be made larger. +
        +
      • / (10 GByte, logical volume root)
      • +
      • /home (2 GByte, logical volume home)
      • +
      • /tmp (5 GByte, logical volume tmp)
      • +
      • /var/lib/ceph (50 GByte, logical volume ceph) (optional for storage nodes)
      • +
      • /var/lib/docker (30 GByte, logical volume docker, do not set the nosuid flag on /var/lib/docker) +
          +
        • When using XFS as the file system for /var/lib/docker, note the following: Running on XFS without d_type support +causes Docker to skip the attempt to use the overlay or overlay2 driver.
        • +
        • 100 GB should be used on a control node at the beginning.
        • +
        • /var/lib/docker must be extended later during operation depending on the node type. You do this +in operation when you can see how many logs etc. are generated.
        • +
        +
      • +
      • /var/log/audit (1 GByte, logical volume audit)
      • +
      • /var (10 GByte, logical volume var)
      • +
      • swap (8 GByte, logical volume swap)
      • +
      +
    • +
    +
  • +
  • Choose No automatic updates.
  • +
  • Choose OpenSSH server as software to install. +
      +
    • Do not install any other software component. Everything you need will be installed later by OSISM. +In particular, it is not necessary to install a desktop environment.
    • +
    +
  • +
  • After completion, restart the system.
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/rookify/index.html b/docs/iaas/guides/deploy-guide/rookify/index.html new file mode 100644 index 0000000000..b308536432 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/rookify/index.html @@ -0,0 +1,70 @@ + + + + + +Deploy Rookify: Migrate to Rook from Ceph-Ansible (Technical Preview) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Deploy Rookify: Migrate to Rook from Ceph-Ansible (Technical Preview)

+
warning

Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime. +Nevertheless, it is strongly advised to test Rookify in a controlled environment first, such as the OSISM testbed. Additionally ensure that precautionary backups are made and all other necessary safety measures are in place.

+

It is currently recommended to install Rookify on your local machine and connect through VPNs to the target system (the one where Ceph-Ansible needs to be "rookified" 😉).

+

Rookify operates in place, meaning no parallel nodes are required. As noted earlier, Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime, but given the complexity of infrastructure, precautionary backups and safety measures are highly recommended.

+

For a condensed summary of the information covered here, refer to the Rookify GitHub repository.

+

Prerequisites & Requirements

+
    +
  • A functioning Ceph cluster deployed using traditional methods.
  • +
  • Access to a Kubernetes cluster with sufficient resources to host the migrated Ceph cluster.
  • +
  • Kubernetes nodes must be deployed on at least the OSD nodes.
  • +
  • Monitor and OSD daemons should stay in place. Former to ensure that the Ceph endpoints do not change during migration, the later ones to have access to the underlying hardware.
  • +
  • Rook operator version 1.13 or higher installed on the Kubernetes cluster.
  • +
  • radoslib version 2.0.0 installed.
  • +
  • For a dockerized setup, docker and docker compose are required.
  • +
  • In order to use the Makefile, GNU make is required.
  • +
+

Manual Installation

+

Download or Clone the Repository

+

Clone or download Rookify from the repository.

+

Install and Run Locally (without Docker)

+
    +
  1. Navigate to the tool directory:
  2. +
+
cd rookify
+
    +
  1. To install Rookify locally, Python's virtualenv will be used (Note: This will install pre-commit in your local user user context):
  2. +
+
tip

Checkout the included options in the Makefile by typing make.

+
make setup
+

This command also verifies if the required Python library radoslib is installed. Ensure it is available on your Linux distribution.

+
tip

Before running Rookify, check all available options by using rookify --help.

+

To run Rookify you can either run it directly from within Python's virtualenv or with help of the Makefile:

+
# directly
./.venv/bin/rookify --help
# using make
make run-local-rookify
+

Install and Run from within a Container

+
    +
  1. +

    Navigate to the tool directory:

    +
  2. +
  3. +

    To install Rookify in a container, you can use either Podman or Docker (Note: In both cases, Python’s radoslib library must be installed locally):

    +
  4. +
+
make check-radoslib
make up
+

This command uses docker compose, so ensure it is installed as well.

+

To run Rookify, you can either enter the container and run it from there or use make run-rookify.

+
note

Before running rookify, it's useful to check all options by using rookify --help.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/seed/index.html b/docs/iaas/guides/deploy-guide/seed/index.html new file mode 100644 index 0000000000..e1686c4526 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/seed/index.html @@ -0,0 +1,64 @@ + + + + + +Seed | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Seed

+
info

The prerequisite for the deployment of a cluster is a configuration repository. +What a configuration repository is and how it is created is described in the +Configuration Guide.

+

The seed node is used once for the initial bootstrap of the manager node. The seed node can +also be used to initially create and prepare the configuration repository. The seed node is +not the manager node itself. It is sufficient to use the local workstation. It doesn't have +to be a dedicated system. The seed node is no longer needed in the further process. The seed +node must be able to reach the manager node via SSH. It is important for the further process +that no packages are installed manually on the manager. Especially not Docker.

+

The use of Linux on the seed node is recommended. Other operating systems should also +work without problems. It is assumed in this documentation that Ubuntu 22.04 is used on +the seed node.

+

Install required packages

+
sudo apt-get install git python3-pip python3-virtualenv sshpass libssh-dev
+

Get a copy of the configuration repository

+

Each environment managed with OSISM is based on a configuration repository. This was +previously created with Cookiecutter and the osism/cfg-cookiecutter +repository.

+

The creation of the configuration repository is covered in chapter +Creation of a configuration repository +of the Configuration Guide.

+

A configuration repository is stored on a Git server (e.g. GitHub, Gitlab, ...). The +configuration repository is individual for each environment and is therefore not provided +by us.

+

The configuration repository to be used must be available on the seed node. In the following +example, replace YOUR_ORG and YOUR_NEW_CONFIGURATION_REPOSITORY accordingly.

+
git clone ssh://git@github.com:YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY.git
+

Examples:

+
    +
  • The repository is located in the regiocloud organisation on GitHub, has the name +configuration and can be accessed via SSH: ssh://git@github.com:regiocloud/configuration.git
  • +
  • The repository is located in the regiocloud organisation on Gitlab, has the name configuration +and can be accessed via SSH: ssh://git@gitlab.com:regiocloud/configuration.git
  • +
  • The repository is located in the regiocloud organisation on an internal Gitlab, has the name +configuration and can be accessed via SSH: ssh://git@git.services.osism.tech:regiocloud/configuration.git
  • +
+

If necessary, the configuration SSH key can be used for the initial transfer of the repository.

+

For this, the following content is added in ~/.ssh/config and the SSH privte key is stored in +~/.ssh/id_rsa.configuration.

+
Host github.com
HostName github.com
User git
Port 22
IdentityFile ~/.ssh/id_rsa.configuration
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/ceph/index.html b/docs/iaas/guides/deploy-guide/services/ceph/index.html new file mode 100644 index 0000000000..aba44afde7 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/ceph/index.html @@ -0,0 +1,144 @@ + + + + + +Ceph | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Ceph

+

In OSISM it is also possible to integrate and use existing Ceph clusters. It +is not necessary to deploy Ceph with OSISM. If Ceph is deployed with OSISM, it +should be noted that OSISM does not claim to provide all possible features of Ceph. +Ceph provided with OSISM is intended to provide the storage for Glance, Nova, Cinder +and Manila. In a specific way that has been implemented by OSISM for years. It +should be checked in advance whether the way in OSISM the Ceph deployment and the +provided features are sufficient. If this is not the case, it is recommended to +deploy Ceph in a different way directly and independently of OSISM. For possible +open source projects, please refer to +cephadm and +Rook.

+
warning

Before starting the Ceph deployment, the configuration and preparation of the +OSD devices must be completed. The steps that are required for this can be found in the +Ceph Configuration Guide.

+
    +
  1. +

    Deploy services.

    +
      +
    • +

      Deploy ceph-mon services

      +
      osism apply ceph-mons
      +
    • +
    • +

      Deploy ceph-mgr services

      +
      osism apply ceph-mgrs
      +
    • +
    • +

      Deploy ceph-osd services

      +
      osism apply ceph-osds
      +
    • +
    • +

      Generate pools and keys. This step is only necessary for OSISM >= 7.0.0.

      +
      osism apply ceph-pools
      +
    • +
    • +

      Deploy ceph-crash services

      +
      osism apply ceph-crash
      +
    • +
    +
    info

    It's all done step by step here. It is also possible to do this in a single step. +This speeds up the entire process and avoids unnecessary restarts of individual +services.

    osism apply ceph

    Generate pools and keys.

    osism apply ceph-pools
    +
  2. +
  3. +

    Get ceph keys. This places the necessary keys in /opt/configuration.

    +
    osism apply copy-ceph-keys
    +

    After run, these keys must be permanently added to the configuration repository +via Git.

    +
    environments/infrastructure/files/ceph/ceph.client.admin.keyring
    environments/kolla/files/overlays/gnocchi/ceph.client.gnocchi.keyring
    environments/kolla/files/overlays/nova/ceph.client.cinder.keyring
    environments/kolla/files/overlays/nova/ceph.client.nova.keyring
    environments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder.keyring
    environments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder-backup.keyring
    environments/kolla/files/overlays/cinder/cinder-volume/ceph.client.cinder.keyring
    environments/kolla/files/overlays/manila/ceph.client.manila.keyring
    environments/kolla/files/overlays/glance/ceph.client.glance.keyring
    +

    If the osism apply copy-ceph-keys fails because the keys are not found in the /share +directory, this can be ignored. The keys of the predefined keys (e.g. for Manila) were +then not created as they are not used. If you only use Ceph and do not need the predefined +keys for OpenStack at all, you can also overwrite the ceph_kolla_keys parameter to skip +these keys.

    +
    environments/ceph/configuration.yml
    ceph_kolla_keys: []
    +
  4. +
  5. +

    After the Ceph keys have been persisted in the configuration repository, the Ceph +client can be deployed.

    +
    osism apply cephclient
    +
  6. +
  7. +

    Enable and prepare the use of the Ceph dashboard.

    +
    osism apply ceph-bootstrap-dashboard
    +
  8. +
+

RGW service

+

Deployment of the Ceph RGW Service is optional. How the Ceph RGW service can be deployed +and integrated into OpenStack is described here.

+
info

If an initial deployment is performed and Ceph RGW is not added to an existing deployment, +steps 4 and 5 are not required.

Step 3 is then performed later after the OpenStack Keystone service has been deployed.

+
    +
  1. +

    Configure the RGW service

    +
  2. +
  3. +

    Apply role ceph-rgws to deploy the Ceph RGW services.

    +
    osism apply ceph-rgws
    +
  4. +
  5. +

    Apply role kolla-ceph-rgw to add the OpenStack endpoint. +If an initial deployment is performed and Ceph RGW is not added +to an existing deployment run this step later after the OpenStack +Keystone service has been deployed.

    +
    osism apply kolla-ceph-rgw
    +
  6. +
  7. +

    Apply role loadbalancer to add the HAProxy backend and frontend.

    +
    osism apply loadbalancer
    +
  8. +
  9. +

    Apply role horizon to enable the Swift dashboard.

    +
    osism apply horizon
    +
  10. +
+

Avoiding service restarts

+
info

Usable from OSISM 7.0.3 onwards.

+

If Ceph services are deployed sequentially, this can lead to unwanted service restarts. +This can also happen if, for example, new OSDs are added later or a new control node is +added.

+

The Ceph RGW services are deployed here without restarting the Ceph OSD services.

+
osism apply ceph-rgws -e ceph_handler_osds_restart=False
+

The following parameters are available. Any number of parameters can be used with a single command.

+
ceph_handler_crash_restart
ceph_handler_mdss_restart
ceph_handler_mgrs_restart
ceph_handler_mons_restart
ceph_handler_osds_restart
ceph_handler_rbdmirrors_restart
ceph_handler_rgws_restart
+

Throttling service restarts

+
info

Usable from OSISM 7.0.3 onwards.

+

Sometimes service restarts are required. For example, if the configuration has changed +or if new OSDs have been added. It may be necessary and useful to only restart the +services on a specific number of nodes at a specific time.

+

Further information on throttling can be found in the +Ansible documentation.

+

The Ceph OSD services are deployed here. If there is a restart required of other OSDs +that are already running, these restarts are executed on a maximum of 2 nodes at the +same time. The OSD services themselves on a node are always restarted one after the other +and never all at the same time.

+
osism apply ceph-osds -e ceph_handler_osds_restart_throttle=2
+

If the nodes are to be processed one after the other, ceph_handler_osds_restart_throttle=1 +can be used.

+

The following parameters are available. Any number of parameters can be used with a single command.

+
ceph_handler_crash_restart_throttle
ceph_handler_mdss_restart_throttle
ceph_handler_mgrs_restart_throttle
ceph_handler_mons_restart_throttle
ceph_handler_osds_restart_throttle
ceph_handler_rbdmirrors_restart_throttle
ceph_handler_rgws_restart_throttle
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/index.html b/docs/iaas/guides/deploy-guide/services/index.html new file mode 100644 index 0000000000..54f35320cb --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/index.html @@ -0,0 +1,39 @@ + + + + + +Services | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Services

+
info

The prerequisite for deploying the services of a cluster is the bootstrap of +the nodes. How to bootstrap the nodes is documented in the +Bootstrap chapter of the Deploy Guide.

+

When setting up a new cluster, the services are deployed in a specific order.

+
    +
  1. Infrastructure
  2. +
  3. Network
  4. +
  5. Logging & Monitoring
  6. +
  7. Ceph
  8. +
  9. OpenStack
  10. +
+

In the examples, the pull of images (if supported by a role) is always run first. While +this is optional, it is recommended to speed up the execution of the deploy action in +the second step. This significantly reduces the time required for the deployment of new +services.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/infrastructure/index.html b/docs/iaas/guides/deploy-guide/services/infrastructure/index.html new file mode 100644 index 0000000000..cb9e31cb0d --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/infrastructure/index.html @@ -0,0 +1,66 @@ + + + + + +Infrastructure | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Infrastructure

+

Common issues with deploying infrastructure services required by OpenStack +are documented in the OpenStack Troubleshooting Guide.

+
    +
  1. +

    Optional: In order to reduce the active observation time for the deployment of the components, +the container images for the following services can be downloaded in advance with the argument -a pull.

    +
    osism apply -a pull common
    osism apply -a pull loadbalancer
    osism apply -a pull redis
    osism apply -a pull memcached
    osism apply -a pull rabbitmq
    osism apply -a pull mariadb
    +
  2. +
  3. +

    Cron, Fluentd & Kolla Toolbox

    +

    The common role of Kolla is used to manage the services cron, fluentd +and kolla-toolbox.

    +

    It is important to do this deployment before any other deployements in the Kolla +environment, as parts of the other deployments depend on the kolla-toolbox +service.

    +
    osism apply common
    +
  4. +
  5. +

    Loadbalancer

    +

    Have a look to the loadbalancer documentation and configure it before deploying the service.

    +
    osism apply loadbalancer
    +

    It is important to do this deployment before any other deployements in the Kolla +environment, as parts of the other deployments depend on the loadbalancer +service.

    +
  6. +
  7. +

    Redis

    +
    osism apply redis
    +
  8. +
  9. +

    Memcached

    +
    osism apply memcached
    +
  10. +
  11. +

    RabbitMQ

    +
    osism apply rabbitmq
    +
  12. +
  13. +

    MariaDB

    +
    osism apply mariadb
    +
  14. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/kubernetes/index.html b/docs/iaas/guides/deploy-guide/services/kubernetes/index.html new file mode 100644 index 0000000000..1e91f1818f --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/kubernetes/index.html @@ -0,0 +1,49 @@ + + + + + +Kubernetes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Kubernetes

+
info

As of OSISM 7, it is possible to create a Kubernetes cluster on all nodes. +At the moment, this is still optional. In the future, it will be necessary +to deploy this Kubernetes cluster.

+
    +
  1. +

    Deploy the K3s cluster.

    +
    osism apply kubernetes
    +
  2. +
  3. +

    Deploy the Kubernetes dashboard:

    +
    osism apply kubernetes-dashboard
    +
  4. +
+

Cluster API

+
    +
  1. +

    Deploy the Cluster API management cluster on the K3s cluster:

    +
    osism apply clusterapi
    +
  2. +
  3. +

    Add the kubeconfig file to the configuration repository (required later by OpenStack +Magnum Service):

    +
    osism apply copy-kubeconfig
    +
  4. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/logging-monitoring/index.html b/docs/iaas/guides/deploy-guide/services/logging-monitoring/index.html new file mode 100644 index 0000000000..3ec1033155 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/logging-monitoring/index.html @@ -0,0 +1,41 @@ + + + + + +Logging & Monitoring | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Logging & Monitoring

+

Common issues with deploying logging & monitoring services provided by Kolla +are documented in the OpenStack Troubleshooting Guide.

+
    +
  1. +

    OpenSearch

    +

    OpenSearch dashboards is also deployed with the opensearch role.

    +
    osism apply -a pull opensearch
    osism apply opensearch
    +
  2. +
  3. +

    Prometheus

    +
    osism apply -a pull prometheus
    osism apply prometheus
    +
  4. +
  5. +

    Grafana

    +
    osism apply -a pull grafana
    osism apply grafana
    +
  6. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/network/index.html b/docs/iaas/guides/deploy-guide/services/network/index.html new file mode 100644 index 0000000000..393dd94e40 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/network/index.html @@ -0,0 +1,38 @@ + + + + + +Network | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Network

+
    +
  1. +

    Open vSwitch (OVS)

    +
    osism apply -a pull openvswitch
    osism apply openvswitch
    +
  2. +
  3. +

    Open Virtual Network (OVN)

    +

    In environments/kolla/configuration.yml the parameter neutron_plugin_agent is set to +ovn. The parameter is set to ovn by default in the Cookiecutter and is the OSISM default.

    +
    environments/kolla/configuration.yml
    # neutron
    neutron_plugin_agent: "ovn"
    +

    Before the deployment of OVN, the deployment of Open vSwitch must already have been done.

    +
    osism apply -a pull ovn
    osism apply ovn
    +
  4. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/openstack/index.html b/docs/iaas/guides/deploy-guide/services/openstack/index.html new file mode 100644 index 0000000000..479be8d6d6 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/openstack/index.html @@ -0,0 +1,103 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

OpenStack

+

Common issues with deploying OpenStack services are documented in the +OpenStack Troubleshooting Guide.

+
info

An OpenStack deployment contains a number of components providing APIs to access infrastructure resources. +The OpenStack Components +page lists the various services that can be deployed to provide such resources to cloud end users. +Unfortunately, not all of the OpenStack projects listed there are still active. +Not all of the services listed there are supported by OSISM.

+
    +
  1. +

    OpenStack client

    +
    osism apply openstackclient
    +
  2. +
  3. +

    Keystone

    +
    osism apply -a pull keystone
    osism apply keystone
    +
  4. +
  5. +

    Glance

    +
    osism apply -a pull glance
    osism apply glance
    +
  6. +
  7. +

    Designate

    +
    osism apply -a pull designate
    osism apply designate
    +
  8. +
  9. +

    Placement

    +
    osism apply -a pull placement
    osism apply placement
    +
  10. +
  11. +

    Cinder

    +
    osism apply -a pull cinder
    osism apply cinder
    +
  12. +
  13. +

    Neutron

    +
    osism apply -a pull neutron
    osism apply neutron
    +
  14. +
  15. +

    Nova

    +
    osism apply -a pull nova
    osism apply nova
    +
  16. +
  17. +

    Octavia

    +
    osism apply octavia-certificates
    osism apply copy-octavia-certificates
    +
    osism apply -a pull octavia
    osism apply octavia
    +
  18. +
  19. +

    Optional: Manage amphora image

    +
  20. +
+

This step is only necessary if the Amphora Driver is used. If OVN is used as the driver, +this step is not necessary.

+

We provide regularly updated images for Octavia in +osism/openstack-octavia/amphora-image.

+
    +
  • +

    Configure API Endpoint

    +

    For the command to be usable, a cloud profile for octavia must currently be added in the +clouds.yml file of the OpenStack environment. The auth_url is changed accordingly.

    +
    environments/openstack/clouds.yml
    clouds:
    [...]
    octavia:
    auth:
    username: octavia
    project_name: service
    auth_url: https://api.testbed.osism.xyz:5000/v3
    project_domain_name: default
    user_domain_name: default
    cacert: /etc/ssl/certs/ca-certificates.crt
    identity_api_version: 3
    +
  • +
  • +

    Configure the secret

    +

    The secret is added to the secure.yml file. The password is set in the parameter +octavia_keystone_password in the file environments/kolla/secrets.yml.

    +

    Get the secret with

    +
    make ansible_vault_show FILE=environments/kolla/secrets.yml |grep octavia_keystone_password
    +
    environments/openstack/secure.yml
    ---
    clouds:
    [...]
    octavia:
    auth:
    password: VALUE_OF_octavia_keystone_password
    +
  • +
  • +

    Upload the correct and current image depending on the current Openstack release:

    +
    osism manage image octavia
    +
  • +
+
    +
  1. +

    Horizon

    +
    osism apply -a pull horizon
    osism apply horizon
    +
  2. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/rook/index.html b/docs/iaas/guides/deploy-guide/services/rook/index.html new file mode 100644 index 0000000000..d3fbff9da5 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/rook/index.html @@ -0,0 +1,95 @@ + + + + + +Ceph via Rook (technical preview) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Ceph via Rook (technical preview)

+
warning

This is a technical preview and not recommended for production use yet.

+

In OSISM it is also possible to integrate and use existing Ceph clusters. It +is not necessary to deploy Ceph with OSISM. If Ceph is deployed with OSISM, it +should be noted that OSISM does not claim to provide all possible features of Ceph. +Ceph provided with OSISM is intended to provide the storage for Glance, Nova, Cinder +and Manila. In a specific way that has been implemented by OSISM for years. It +should be checked in advance whether the way in OSISM the Ceph deployment and the +provided features are sufficient. If this is not the case, it is recommended to +deploy Ceph in a different way directly and independently of OSISM. For possible +open source projects, please refer to +cephadm and +Rook.

+
    +
  1. Deploy services.
  2. +
+

When using rook, all services are deployed via a single helm chart and at the same time. This could be altered by passing custom CRDs. See Rook Configuration Guide.

+
    +
  • +

    Install Kubernetes Cluster

    +
  • +
  • +

    Deploy Rook Operator Helm Chart

    +
    osism apply rook-operator
    +
  • +
  • +

    Deploy complete Rook Ceph Cluster

    +
    osism apply rook
    +
  • +
  • +

    Copy ceph keyrings to kolla directories (if deploying OpenStack)

    +
    osism apply rook-fetch-keys
    +
  • +
+
    +
  1. +

    Get ceph keyrings. This places the necessary keys in /opt/configuration.

    +
    osism apply rook-fetch-keys
    +

    After run, these keys must be permanently added to the configuration repository +via Git.

    +
    environments/infrastructure/files/ceph/ceph.client.admin.keyring
    environments/kolla/files/overlays/gnocchi/ceph.client.gnocchi.keyring
    environments/kolla/files/overlays/nova/ceph.client.cinder.keyring
    environments/kolla/files/overlays/nova/ceph.client.nova.keyring
    environments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder.keyring
    environments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder-backup.keyring
    environments/kolla/files/overlays/cinder/cinder-volume/ceph.client.cinder.keyring
    environments/kolla/files/overlays/manila/ceph.client.manila.keyring
    environments/kolla/files/overlays/glance/ceph.client.glance.keyring
    +

    You can also overwrite the rook_cephclients parameter to skip +these keys.

    +
    environments/rook/configuration.yml
    rook_cephclients: {}
    +
  2. +
  3. +

    A Ceph client (a wrapper on the manager for entering the rook toolbox) can be deployed.

    +
    osism apply cephclient
    +

    You have to make sure the correct Configuration Options for the Rook Ceph Client Wrapper are net.

    +
  4. +
  5. +

    After getting the Ceph Keyrings, the OpenStack Deployment can optionally be done.

    +
  6. +
+

RGW service

+

Deployment of the Ceph RGW Service is enabled by default in rook. This is done by creating a default CephObjectStore CRD. How the Ceph RGW service can be deployed and integrated into OpenStack is described here.

+

In the environments/rook/configuration.yml file you have to adapt accordingly to your environment at least like shown below:

+
environments/rook/configuration.yml
rook_cephconfig:
client.rgw.rgw.a:
rgw_keystone_verify_ssl: "false"
rgw_verify_ssl: "false"
## keystone
rook_cephobjectstore_keystone_acceptedRoles:
- admin
- member
rook_cephobjectstore_keystone_implicitTenants: "true"
rook_cephobjectstore_keystone_url: "https://api-int.testbed.osism.xyz:5000"
rook_cephobjectstore_swift_urlPrefix: "swift"
## keystone user
rook_cephobjectstore_keystone_auth_type: "password"
rook_cephobjectstore_keystone_project_domain_name: "Default"
rook_cephobjectstore_keystone_project_name: "service"
rook_cephobjectstore_keystone_user_domain_name: "Default"
rook_cephobjectstore_keystone_username: "ceph_rgw"
+

As well as in the environments/rook/secrets.yml file:

+
environments/rook/secrets.yml
rook_cephobjectstore_keystone_passwor: supersecretpassword
+

Change node labels

+

In case you decided to move workloads to different nodes and changed the inventory groups e.g. like this:

+
inventory/20-roles
[rook-mds:children]
ceph-control

[rook-mgr:children]
ceph-control

[rook-mon:children]
ceph-control

[rook-osd:children]
ceph-resource

[rook-rgw:children]
ceph-control
+

You can apply the changes running:

+
osism apply rook-change-labels
+

This will remove all labels and apply the changed inventory groups as labels. After those steps are done it will trigger the rescheduling of the components so they get deployed on the adjusted nodes.

+

Cleanup

+
warning

This will permanently delete all your data in the Ceph Cluster. Be sure you know what you are doing before proceeding.

+

If you want to cleanup/delete the whole cluster, you can do that by enabling rook_cleanup.

+
environments/rook/configuration.yml
rook_cleanup: true
+

And running the rook-cleanup role.

+
osism apply rook-cleanup
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/rookify/index.html b/docs/iaas/guides/deploy-guide/services/rookify/index.html new file mode 100644 index 0000000000..cf4d8ced0f --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/rookify/index.html @@ -0,0 +1,26 @@ + + + + + +Migrate Ceph-Ansible via Rookify (technical preview) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/index.html b/docs/iaas/guides/index.html new file mode 100644 index 0000000000..cbf7101238 --- /dev/null +++ b/docs/iaas/guides/index.html @@ -0,0 +1,39 @@ + + + + + +Guides | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Guides

+
    +
  • The Concept Guide explains which components and modules make up OSISM. It also +explains the use cases.
  • +
  • The Deploy Guide explains how the nodes of a cluster are created and bootstrapped. +It also explains how the individual modules can be deployed.
  • +
  • The Upgrade Guide explains how the individual modules can be upgraded.
  • +
  • The Configuration Guide explains how the individual modules can be +configured.
  • +
  • The Operations Guide explains how individual tasks can be done in +day-to-day business in a running cluster.
  • +
  • The Troubleshooting Guide explains how to resolve problems. +It is an extension of the Operations Guide.
  • +
  • The User Guide is intended for users of the individual components. It contains +best practices, as well as other information.
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/ceph/index.html b/docs/iaas/guides/operations-guide/ceph/index.html new file mode 100644 index 0000000000..69e8aa6705 --- /dev/null +++ b/docs/iaas/guides/operations-guide/ceph/index.html @@ -0,0 +1,439 @@ + + + + + +Ceph | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Ceph

+

Where to find docs

+

The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/operations/

+

It is strongly advised to use the documentation for the version being used.

+ +
note

Do not take information in the documentation at face value. +Especially when it comes to advanced/rarely used/very new features it is strongly advised +to test any claims made in the documentation about any particular feature.

Never assume that things will work as written without actually testing it on a test setup +as close to your real workload scenario as possible.

+

Advice on Ceph releases

+

The current Ceph releases and their support status can be found on https://docs.ceph.com/en/latest/releases/

+

When a new Ceph stable version is released you are strongly advised +to not roll it out on any production cluster whatsoever. +Even though its listed as "stable" it doesn't mean that this is actually true. +Especially avoid using .0 releases on anything remotely production +unless you really, really now what you're doing and can live with a possible catastrophic failure.

+

Be very conservative about what version you run on production systems.

+

Shiny new features aren't worth the risk of total or partial data loss/corruption.

+

General maintenance

+

60 seconds cluster overview

+

The following commands can be used to quickly check the status of Ceph:

+
    +
  • +

    Print overall cluster status

    +
    ceph -s
    +
  • +
  • +

    Print detailed health information

    +
    ceph health detail
    +
  • +
  • +

    Display current OSD tree

    +
    ceph osd tree
    +
  • +
  • +

    Cluster storage usage by pool and storage class

    +
    ceph df
    +
  • +
  • +

    List pools with detailed configuration

    +
    ceph osd pool ls detail
    +
  • +
  • +

    Get usage stats for OSDs

    +
    ceph osd df {plain|tree} {class e.g. hdd|ssd}
    +
  • +
  • +

    Watch Ceph health messages sequentially

    +
    ceph -w
    +
  • +
  • +

    List daemon versions running in the cluster

    +
    ceph versions
    +
  • +
+

Also you can run the following on each node running ceph-daemons, +to provide further debug information about the environment:

+
# lscpu
# cat /proc/cpuinfo # if lscpu isn't available
# free -g
# ip l
# ethtool <device> # for each network adapter
+

Mute/Unmute a health warning

+
$ ceph health mute <what> <duration>
$ ceph health unmute <what>
+

Disable/Enable (deep-)scrubbing

+
$ ceph osd set noscrub
$ ceph osd set nodeep-scrub
$ ceph osd unset noscrub
$ ceph osd unset nodeep-scrub
+
warning

Use this sparingly only in emergency situations. +Setting these flags will cause a HEALTH_WARN status, +increase risk of data corruption and also the risk of generating +a HEALTH_WARN due to PGs not being (deep-)scrubbed in time.

+

Reboot a single node

+

The traditional way of doing this is by setting the noout flag, +do the appropriate maintenance work and after the node is back online +unset the flag like so:

+
ceph osd set noout
+

After maintenance is done and host is back up:

+
ceph osd unset noout
+

On versions Luminous or above you can set the flag individually for single +OSDs or entire CRUSH buckets, which can be a safer option in case of prolonged +maintenance periods.

+

Add noout for a OSD:

+
ceph osd add-noout osd.<ID>
+

Remove noout for a OSD:

+
ceph osd rm-noout osd.<ID>
+

Add noout for CRUSH bucket (e.g. host name as seen in ceph osd tree):

+
ceph osd set-group noout <crush-bucket-name>
+

Remove noout for CRUSH bucket:

+
ceph osd unset-group noout <crush-bucket-name>
+

Gathering information about block devices

+

Enumerate typical storage devices and LVM

+
# lsblk
# lsblk -S
# lsscsi
# nvme list
# pvs
# vgs
# lvs
+

SMART data for SATA/SAS and NVME devices

+
# smartctl -a /dev/sdX
# nvme smart-log /dev/nvmeXnY
+

Check format of a NVME device

+
# nvme id-ns -H /dev/nvmeXnY
+
note

Check the last lines named "LBA Format". +It will show which formats are supported, +which format is in use and which format offers the best performance +according to the vendor.

+

Format a NVME device to a different LBA format using nvme-cli

+
warning

This will destroy all data on the device!

+
# nvme format --lbaf=<id> /dev/nvmeXnY
+

Secure Erase a NVME drive using nvme-cli

+
warning

This will destroy all data on the device!

+
# nvme format -s2 /dev/nvmeXnY
# blkdiscard /dev/nvmeXnY
# nvme format -s1 /dev/nvmeXnY
+

Secure Erase a SATA/SAS drive using hdparm

+
warning

This will destroy all data on the device!

+
    +
  1. +

    Gather device info:

    +
    # hdparm -I /dev/sdX
    +
  2. +
+

Check that the output says "not frozen" and "not locked", +also it should list support for enhanced erase and list time estimates +for SECURITY ERASE UNIT and/or ENHANCED SECURITY ERASE UNIT

+
    +
  1. +

    Set a master password for the disk (required, will be automatically removed after wipe)

    +
    # hdparm --user-master wipeit --security-set-pass wipeit /dev/sdX
    # hdparm -I /dev/sdX
    +

    Check that "Security level" is now "high" and master password is now +"enabled" instead of "not enabled" before

    +
  2. +
  3. +

    Wipe the device

    +

    If device supports enhanced security erase (better), use the following:

    +
    # hdparm --user-master wipeit --security-erase-enhanced wipeit /dev/sdX
    +

    If not, use standard security erase:

    +
    # hdparm --user-master wipeit --security-erase wipeit /dev/sdX
    +
  4. +
+
note

On some systems the system firmware might "freeze" the device, +which makes it impossible to issue a secure erase or reformat the device. +In that case it might be necessary to either "unfreeze" the drive or +to install the drive in another system where it can be unfrozen. +Also make sure that the device is actually wiped. Its recommended to +at least perform a blanking pass on HDDs with a tool like nwipe.

+

OSD maintenance tasks

+

Locate a specific OSD in the cluster

+
$ ceph osd find osd.<ID>
+

Get OSD metadata (global and single OSD)

+
$ ceph osd metadata
$ ceph osd metadata osd.<ID>
+

Interesting fields:

+
    +
  • bluefs_db_rotational
  • +
  • bluefs_dedicated_db
  • +
  • bluefs_dedicated_wal
  • +
  • bluefs_wal_rotational
  • +
  • bluestore_bdev_rotational
  • +
  • device_ids
  • +
  • device_paths
  • +
  • devices
  • +
  • hostname
  • +
  • osd_objectstore
  • +
  • rotational
  • +
+

Add a new OSD

+
    +
  1. +

    Prepare the configuration for the new OSD first. Details on adding the configuration +for a new OSD in the Ceph configuration guide.

    +
  2. +
  3. +

    Deploy the new OSD service on <nodename>.

    +
    osism apply ceph-osds -l <nodename> -e ceph_handler_osds_restart=false
    +
  4. +
+

Replace a defect OSD

+

Remove a OSD

+

As with ‘Remove a single OSD node’. Except that the steps are only executed +for a single OSD and the node is not removed from the CRUSH map and the inventory. +Only the entries relating to the removed OSD are removed from the host vars.

+

Manual way

+
$ ceph osd crush reweight osd.<ID> 0.0
# Wait for rebalance to complete...
$ ceph osd out osd.<ID>
# systemctl stop ceph-osd@<ID>
# systemctl disable ceph-osd@<ID>
$ ceph osd purge osd.<ID> --yes-i-really-mean-it
+

The LV and VG defined in the inventory for this OSD must also be removed. The +OSD itself should be wiped.

+

Remove a single OSD node

+
    +
  1. +

    Get all OSDs of the node

    +
    $ ceph osd tree
    ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
    -1 0.11691 root default
    -3 0.03897 host testbed-node-0
    0 hdd 0.01949 osd.0 up 1.00000 1.00000
    4 hdd 0.01949 osd.4 up 1.00000 1.00000
    -5 0.03897 host testbed-node-1
    1 hdd 0.01949 osd.1 up 1.00000 1.00000
    3 hdd 0.01949 osd.3 up 1.00000 1.00000
    -7 0.03897 host testbed-node-2
    2 hdd 0.01949 osd.2 up 1.00000 1.00000
    5 hdd 0.01949 osd.5 up 1.00000 1.00000
    +
  2. +
  3. +

    Reduce the weighting of all OSDs on the node to 0. Do this for each OSD +in a row and wait after each adjustment until the Ceph cluster is balanced. +Depending on how large the Ceph cluster and the individual OSDs are, this +may take some time.

    +
    $ ceph osd crush reweight osd.2 0.0
    $ ceph osd crush reweight osd.5 0.0
    +

    The Ceph OSDs that are to be removed then have a weight of 0.

    +
    $ ceph osd tree
    ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
    -1 0.07794 root default
    -3 0.03897 host testbed-node-0
    0 hdd 0.01949 osd.0 up 1.00000 1.00000
    4 hdd 0.01949 osd.4 up 1.00000 1.00000
    -5 0.03897 host testbed-node-1
    1 hdd 0.01949 osd.1 up 1.00000 1.00000
    3 hdd 0.01949 osd.3 up 1.00000 1.00000
    -7 0 host testbed-node-2
    2 hdd 0 osd.2 up 1.00000 1.00000
    5 hdd 0 osd.5 up 1.00000 1.00000
    +
  4. +
  5. +

    Remove the OSDs and everything that belongs to them from the node. +This is a disruptive action that cannot be undone. The devices used +are also reset.

    +
    $ osism apply ceph-shrink-osd -e ireallymeanit=yes -e osd_to_kill=2,5
    +

    All OSDs were removed.

    +
    $ ceph osd tree
    ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
    -1 0.07794 root default
    -3 0.03897 host testbed-node-0
    0 hdd 0.01949 osd.0 up 1.00000 1.00000
    4 hdd 0.01949 osd.4 up 1.00000 1.00000
    -5 0.03897 host testbed-node-1
    1 hdd 0.01949 osd.1 up 1.00000 1.00000
    3 hdd 0.01949 osd.3 up 1.00000 1.00000
    -7 0 host testbed-node-2
    +
  6. +
  7. +

    Remove the node from the CRUSH map.

    +
    $ ceph osd crush remove testbed-node-2
    removed item id -7 name 'testbed-node-2' from crush map
    +
  8. +
  9. +

    Remove the node from all Ceph groups in the inventory.

    +
  10. +
  11. +

    Remove all Ceph-specific parameters from the host vars of the node from the +inventory

    +
  12. +
+

Remove an OSD (temporarily e.g. when replacing a broken disk)

+
$ ceph osd out osd.<ID>
# systemctl stop ceph-osd@<ID>
# systemctl disable ceph-osd@<ID>
+

Disable backfills/recovery completely

+
warning

Use only in emergency situations!

+
$ ceph osd set nobackfill
$ ceph osd set norecovery
$ ceph osd set norebalance
+

Unset the flags with ceph osd unset <flag>.

+

Rebalance OSDs

+

Placement Group maintenance

+

Dump placement groups

+

Usually only useful when parsing it, so here are two ways to get the data:

+
$ ceph pg dump
$ ceph pg dump --format=json-pretty
+

Query a PG about its status

+
$ ceph pg <pgid> query
+

Start (deep-)scrubbing of a placement group

+
$ ceph pg scrub <pgid>
$ ceph pg deep-scrub <pgid>
+
note

Instructing a PG to (deep-)scrub does not mean that it will do so immediately, +it can take some time for the scrub to start.

+

HEALTH_WARN - Large omap objects found...

+

Finding PGs which have large OMAP objects:

+
# ceph pg dump --format=json | jq '.pg_map.pg_stats[] |
select(.stat_sum.num_large_omap_objects != 0) |
(.pgid, .stat_sum.num_large_omap_objects, .up, .acting)'
+

(Remove the line breaks between the single quotes or jq might act weird!)

+

This will dump all PG IDs with large OMAP objects and their up/acting OSDs. +You then can grep the logs of these OSDs for "Large omap object" +to find the actual objects causing the health warning.

+

Also the PG ID before the dot is equal to the pool ID it belongs to.

+

In case the logs have been rotated, instruct those OSDs to do a deep-scrub +and watch the logs for the message to appear.

+

From there you can investigate the issue further, +mostly it'll be due to the index of a RGW bucket getting too big due to too many objects, +thus resharding that bucket's index will be necessary.

+

Instruct a PG to repair in case of scrub errors (inconsistent PG)

+
$ ceph pg repair <pgid>
+
note

Recovery might not start immediately and might take some time. +You can query the status of the recovery through ceph pg <pgid> query. +Be sure to read the Ceph manual about this topic thoroughly:

https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshooting-pg/

+

RADOS Pool maintenance

+
note

Read the RADOS pool operations documentation in detail before playing around with pools. +Especially when considering making changes to the CRUSH map. +Wrong decisions there can lead to data loss or other catastrophic failures.

https://docs.ceph.com/en/latest/rados/operations/pools/

+

Get pools and their configuration

+
$ ceph osd pool ls detail
+

Dump all CRUSH rules

+
$ ceph osd crush rule dump
+

Get autoscaler status

+
$ ceph osd pool autoscale-status
+

Create a replicated pool

+
$ ceph osd pool create <pool_name> <pg_num> <pgp_num> replicated [<crush_rule_name>]
+

Enabling an application on a pool

+

Required, otherwise a health warning will be raised after some time.

+
$ ceph osd pool application enable <pool_name> <application_name> # Syntax
$ ceph osd pool application enable cinder rbd # Example
+

Typical application names are: rbd, rgw, cephfs

+

Delete a pool

+
warning

This will delete all data in that pool. There is no undo/undelete.

+
$ ceph osd pool delete <pool_name> <pool_name> --yes-i-really-really-mean-it
+
note

In order to be able to delete pools, it has to be enabled on the monitors +by setting the mon_allow_pool_delete flag to true. Default is false.

See: https://docs.ceph.com/en/latest/rados/configuration/mon-config-ref

+

Set number of PGs for a pool

+

If no autoscaling of PGs is used, it is very important to adapt the PGs per pool to the +real world when operating a Ceph cluster. If, for example, OSDs are exchanged, added, new +nodes are added, etc., the number of PGs must also be taken into account.

+

The PG Calc Tool can be used +to calculate a reasonable number of PGs per pool depending on all ODSs and pools.

+

Further information on placement groups can be found in the +Ceph documentation. +You should definitely read FACTORS RELEVANT TO SPECIFYING PG_NUM and CHOOSING THE NUMBER OF PGS +there.

+
$ ceph osd pool set <poolname> pg_num <num_pgs>
+
note

Num PGs must be a power of two! Be careful about changing number of PGs. +Changing pg_num to a new value will gradually increase pgp_num on newer versions of Ceph.

In older versions one also has to set pgp_num manually, either in increments or in one big leap.

+

Create CRUSH rules for different storage classes

+
$ ceph osd crush rule create-replicated replicated_hdd default host hdd
$ ceph osd crush rule create-replicated replicated_ssd default host ssd
$ ceph osd crush rule create-replicated replicated_nvme default host nvme
+

Change CRUSH rule for a pool ("move pool")

+
$ ceph osd pool set <poolname> crush_rule <rule_name>
+

This can be used to move a pool from e.g. HDD to SSD or NVME class +or anything else that the new CRUSH rule specifies.

+

Advanced topics

+

Validating Ceph using OSISM playbooks

+

For Ceph, special playbooks were added to validate the deployment status of +the OSD, MON and MGR services. The commands for use are osism validate ceph-osds, +osism validate ceph-mons, and osism validate ceph-mgrs.

+

These playbooks will validate that the deployed Ceph environment matches +the configuration and is overall in a healthy state. The playbooks will +generate report files in JSON format on the first manager node in /opt/reports/validator.

+

Shutdown a Ceph cluster

+

In order to fully shutdown a Ceph cluster safely, you first do the following steps:

+
warning

Take GOOD NOTES of the unit names and OSD IDs running on each node. +You will need them to restart the cluster later.

+
    +
  1. +

    Stop the workload that is using the cluster

    +

    This will vary depending on your environment and is not covered here.

    +
  2. +
  3. +

    Pause/Stop operations on the cluster by setting flags

    +
    $ ceph osd set noout
    $ ceph osd set nobackfill
    $ ceph osd set norecover
    $ ceph osd set norebalance
    $ ceph osd set nodown
    $ ceph osd set pause
    +
  4. +
  5. +

    Stop and disable the radosgw services on all nodes (on each rgw node) (if RGW is used)

    +

    Get the name of the unit (globs not supported for disable) and +make a note of the unit name for that node:

    +
    # systemctl | grep ceph-radosgw
    +

    Then disable and stop the unit:

    +
    # systemctl disable --now ceph-radosgw@<name>.service
    +
  6. +
  7. +

    Stop all CephFS file systems (if CephFS is used)

    +

    List all Ceph file systems

    +
    $ ceph fs ls
    +

    For each CephFS do:

    +
    $ ceph fs <file system name> down true
    +
  8. +
  9. +

    After that disable and stop all ceph-mds services on all nodes (do this on each node)

    +

    Get the name of the unit (globs not supported for disable) and +make a note of the unit name for that node:

    +
    # systemctl | grep ceph-mds
    +
    # systemctl disable --now ceph-mds@<unit>.service
    +
  10. +
  11. +

    Stop and disable the ceph-mgr services on all nodes (do this on each node)

    +

    Get the name of the unit (globs not supported for disable) and +make a note of the unit name for that node:

    +
    # systemctl | grep ceph-mgr
    +
    # systemctl disable --now ceph-mgr@<unit>.service
    +
  12. +
  13. +

    Stop and disable the ceph-osd services on all nodes (do this on each node)

    +

    Get the names of the units (globs not supported for disable) and +make a note of the unit names for that node (best to save it to a file):

    +
    # systemctl | grep ceph-osd
    +

    For each OSD unit execute:

    +
    # systemctl disable ceph-osd@<osd-id>.service
    +

    Stop all OSDs at once:

    +
    # systemctl stop ceph-osd\*.service
    +
  14. +
  15. +

    Finally stop the ceph-mon services on all nodes (do this on each node)

    +

    Get the name of the unit (globs not supported for disable) and +make a note of the unit name for that node:

    +
    # systemctl | grep ceph-mon
    +
    # systemctl disable --now ceph-mon@<unit>.service
    +
  16. +
+

Restart a Ceph cluster after manual shutdown

+
warning

You will need the notes taken during shutdown of the unit names. +It can be done without, but then it'll be way more work finding out the names.

+

In order to restart a Ceph cluster after performing a manual shutdown like described +in the section above, you do the following:

+
    +
  1. +

    Enable & start the ceph-mon services on all nodes (do this on each node)

    +
    # systemctl enable --now ceph-mon@<unit-name>.service
    +
  2. +
  3. +

    Enable & start the ceph-osd services on all nodes (do this on each node)

    +

    For each Ceph OSD on that node do:

    +
    # systemctl enable --now ceph-osd@<osd-id>.service
    +

    Depending on the number of OSDs on that node it can take a while.

    +
  4. +
  5. +

    Enable & start the ceph-mgr services on all nodes (do this on each node)

    +
    # systemctl enable --now ceph-mgr@<unit-name>.service
    +
  6. +
  7. +

    Check the status of your cluster and wait for all OSDs to come online

    +

    You can watch the status periodically by running:

    +
    $ watch ceph -s
    +

    You should wait until all OSDs are up + in again, before removing flags.

    +
  8. +
  9. +

    Remove flags to unpause operations

    +
    $ ceph osd unset pause
    $ ceph osd unset nodown
    $ ceph osd unset noout
    $ ceph osd unset nobackfill
    $ ceph osd unset norecover
    $ ceph osd unset norebalance
    +
  10. +
  11. +

    Wait for cluster to resume operations

    +

    See step #4 of this SOP. +Now you wait until the cluster seems "happy enough" to accept clients. +(i.e. rebalancing finished etc.) +Maybe it will complain about MDS being down, but that's normal for now.

    +
  12. +
  13. +

    Enable & start the ceph-mds services on each node (if CephFS is used)

    +
    # systemctl enable --now ceph-mds@<unit>.service
    +
  14. +
  15. +

    Start CephFS file systems again

    +

    List all Ceph file systems

    +
    $ ceph fs ls
    +

    For each CephFS do:

    +
    $ ceph fs <file system name> down false
    +
  16. +
  17. +

    Enable & start the radosgw services on each node (if RGW is used)

    +
    # systemctl enable --now ceph-radosgw@<name>.service
    +
  18. +
+

Performance benchmark

+
# apt-get install -y fio
+
#!/usr/bin/env bash

BENCH_DEVICE="$2"
DATE=$(date +%s)
IOENGINE="libaio"
LOGPATH="$1"
SIZE=1G

mkdir -p $LOGPATH

for RW in "write" "randwrite" "read" "randread"
do
for BS in "4K" "64K" "1M" "4M" "16M" "64M"
do
(
echo "==== $RW - $BS - DIRECT ===="
echo 3 > /proc/sys/vm/drop_caches
fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json
sync
echo 3 > /proc/sys/vm/drop_caches
echo "==== $RW - $BS - DIRECT IODEPTH 32 ===="
fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --iodepth=32 --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-iod32-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json
sync
) | tee $LOGPATH/$RW.$BS-$(basename $BENCH_DEVICE).$DATE.log
echo
done
done
+

Where and how to get further help

+

Join the #ceph IRC channel on irc.oftc.net, state the problem with as many details as possible +including information about what steps have already been taken to solve the problem +also provide information from the command output from the "60 seconds cluster overview" above +through a pastebin or a similar service. In order for people to be able +to help, details and some patience are important.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/index.html b/docs/iaas/guides/operations-guide/index.html new file mode 100644 index 0000000000..2d6fd35f5d --- /dev/null +++ b/docs/iaas/guides/operations-guide/index.html @@ -0,0 +1,58 @@ + + + + + +Operations Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Operations Guide

+

Change Node states

+

A node can be in different states. Depending on the state, different actions +are possible or are triggered.

+

The individual states of a node can be retrieved via Ansible Facts and local +files on the node itself.

+

Maintenance

+
osism set maintenance NODE
osism noset maintenance NODE
+
    +
  • Ansible fact: ansible_local.osism.maintenance
  • +
  • State file: /etc/osism/maintenance
  • +
+

Bootstrap

+
osism set bootstrap NODE
osism noset bootstrap NODE
+
    +
  • Ansible fact: ansible_local.osism.bootstrap
  • +
  • State file: /etc/osism/bootstrap
  • +
+

Manage services

+
osism apply manage-service \
-e service_name=rsysloc \
-e service_state=restarted
+

Manage containers

+
osism apply manage-container \
-e container_name=nova_compute \
-e container_action=restart
+

Reboot nodes

+

When using reboot play, the node is rebooted directly. It is not ensured in +advance that there is no more payload on the node and no services etc. are +disabled.

+

Reboot node testbed-node-0.testbed.osism.xyz and wait until the reboot has +been completed and the system is accessible again.

+
osism apply reboot \
-e reboot_wait=True \
-e ireallymeanit=yes \
-l testbed-node-0.testbed.osism.xyz
+

Reboot node testbed-node-0.testbed.osism.xyz and do not wait for the reboot +to complete.

+
osism apply reboot \
-e ireallymeanit=yes \
-l testbed-node-0.testbed.osism.xyz
+

Working with the OOB Board via IPMI

+

Display the IP address

+
$ sudo ipmitool lan print | grep 'IP Address'
IP Address Source : DHCP Address
IP Address : 10.10.0.100
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/infrastructure/index.html b/docs/iaas/guides/operations-guide/infrastructure/index.html new file mode 100644 index 0000000000..fe3aa2754c --- /dev/null +++ b/docs/iaas/guides/operations-guide/infrastructure/index.html @@ -0,0 +1,120 @@ + + + + + +Infrastructure | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Infrastructure

+

Loadbalancer

+

For the manage-loadbalancer play to work, the internal control socket +of the HAProxy service must be set to admin level. As of OSISM 7.0.6 this +is the default. Before this, the parameter haproxy_socket_level_admin must +be added to the configuration repository and then a reconfigure +(osism apply -a reconfigure loadbalancer) must be done for the loadbalancer +service.

+
environments/kolla/configuration.yml
haproxy_socket_level_admin: "yes"
+

You can check in the HAProxy configuration whether the control socket is +configured correctly.

+
/etc/kolla/haproxy/haproxy.cfg
global
[...]
stats socket /var/lib/kolla/haproxy/haproxy.sock group kolla mode 660 level admin
+
    +
  • +

    Disable the host testbed-node-0 in all backends of the service keystone

    +
    osism apply manage-loadbalancer \
    -e manage_loadbalancer_action=disable \
    -e manage_loadbalancer_service=keystone \
    -e manage_loadbalancer_host=testbed-node-0
    +
  • +
  • +

    Enable the host testbed-node-0 in all backends of the service keystone

    +
    osism apply manage-loadbalancer \
    -e manage_loadbalancer_action=enable \
    -e manage_loadbalancer_service=keystone \
    -e manage_loadbalancer_host=testbed-node-0
    +
  • +
  • +

    Disable the host testbed-node-0 in all backends

    +
    osism apply manage-loadbalancer \
    -e manage_loadbalancer_action=disable \
    -e manage_loadbalancer_service=all \
    -e manage_loadbalancer_host=testbed-node-0
    +
  • +
  • +

    Enable the host testbed-node-0 in all backends

    +
    osism apply manage-loadbalancer \
    -e manage_loadbalancer_action=enable \
    -e manage_loadbalancer_service=all \
    -e manage_loadbalancer_host=testbed-node-0
    +
  • +
+

MariaDB

+

Backup

+

Mariabackup is used to create backups +of MariaDB. For more details about backups, you can use the offical +kolla-ansible documentation.

+
    +
  • +

    Create a full backup

    +
    osism apply mariadb_backup
    +
  • +
  • +

    Create a incremental backup (supported as of OSISM 7.0.6)

    +
    osism apply mariadb_backup -e mariadb_backup_type=incremental
    +
  • +
  • +

    Accessing created backups

    +

    There is a Docker volume mariadb_backup on the 1st control node. The backups +are stored in this volume. +(see also /var/lib/docker/volumes/mariadb_backup/)

    +
    $ docker run --rm -v mariadb_backup:/backup -it ubuntu:22.04 bash -c 'ls -la /backup'
    total 9728
    drwxr-xr-x 2 42434 42434 4096 Jun 3 18:46 .
    drwxr-xr-x 1 root root 4096 Jun 3 18:47 ..
    -rw-r--r-- 1 42434 42434 4530618 Jun 3 18:46 incremental-18-mysqlbackup-03-06-2024-1717440409.qp.xbc.xbs.gz
    -rw-r--r-- 1 42434 42434 11 Jun 3 18:45 last_full_date
    -rw-r--r-- 1 42434 42434 5411763 Jun 3 18:45 mysqlbackup-03-06-2024-1717440342.qp.xbc.xbs.gz
    +
  • +
+

Currently there is no offical scheduling and houskeeping (disk space) for mariadb backups. +You can create a simple cronjob on the manager or use your enterprise backup software.

+
cat /etc/cron.d/mariadb_backup <<'EOF'
0 7 * * * dragon osism apply mariadb_backup |logger -t mariadb_backup
EOF
+

Restore

+
    +
  • +

    Stop all MariaDb Instances

    +
    osism apply -s stop maria
    +
  • +
  • +

    Follow the restore procedure described in the kolla-ansible manual

    +
  • +
  • +

    Execute the recovery procedure with the node name where you executed the recovery

    +
    osism apply mariadb_recovery -e mariadb_recover_inventory_name=THE_NAME_OF_THE_RESTORE_NODE
    +
  • +
+

Recovery

+

If you stopped your mariadb galera cluster completly, you can use the following procedure +to start a recovery.

+
osism apply mariadb_recovery
+

Create database & user

+
    +
  1. +

    Create a custom play playbook-database-sample.yml in environments/kolla in +the configuration repository.

    +
    ---
    - name: Manage sample database
    hosts: control

    vars:
    database_sample_username: sample
    database_sample_name: sample

    tasks:
    - name: Create sample database
    become: true
    kolla_toolbox:
    container_engine: "{{ kolla_container_engine }}"
    module_name: mysql_db
    module_args:
    login_host: "{{ database_address }}"
    login_port: "{{ database_port }}"
    login_user: "root"
    login_password: "{{ database_password }}"
    name: "{{ database_sample_name }}"
    run_once: true

    - name: Create sample user
    become: true
    kolla_toolbox:
    container_engine: "{{ kolla_container_engine }}"
    module_name: mysql_user
    module_args:
    login_host: "{{ api_interface_address }}"
    login_port: "{{ mariadb_port }}"
    login_user: "root"
    login_password: "{{ database_password }}"
    name: "{{ database_sample_username }}"
    password: "{{ database_sample_password }}"
    host: "%"
    priv: "{{ database_sample_name }}.*:ALL"
    append_privs: True
    run_once: true
    +
  2. +
  3. +

    Add secret database_sample_password in environments/kolla/secrets.yml in the +configuration repository.

    +
  4. +
  5. +

    Commit the custom play and the secret. Sync the configuration on the manager +node with osism apply configuration.

    +
  6. +
  7. +

    Run osism apply xxx on the manager node.

    +
  8. +
+ +

Get all indices

+
$ curl https://api-int.testbed.osism.xyz:9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open flog-2024.04.17 1rCP3NpUQSS5wmulCn6Y5g 1 1 1657832 0 1gb 654.4mb
green open .opensearch-observability UnS2gFb-QhC8oIefL3C52Q 1 2 0 0 624b 208b
green open .plugins-ml-config hMdzW6ooRMGZ_0OGcdNSgA 1 1 1 0 7.8kb 3.9kb
green open .opendistro-job-scheduler-lock fa_Io8bJQ8qfGII4DypxFg 1 1 1 3 51.1kb 35.1kb
green open .kibana_1 v-aJ6ioSQsOwHQn_NNbeOg 1 1 0 0 416b 208b
+

Delete an index

+
$ curl -X DELETE https://api-int.testbed.osism.xyz:9200/flog-2024.04.17
{"acknowledged":true}
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/manager/apply/index.html b/docs/iaas/guides/operations-guide/manager/apply/index.html new file mode 100644 index 0000000000..de7e1b82d8 --- /dev/null +++ b/docs/iaas/guides/operations-guide/manager/apply/index.html @@ -0,0 +1,78 @@ + + + + + +Apply | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Apply

+

With the apply command it is possible to run Ansible plays. These are executed as +background activity via a queuing system so that, for example, the loss of an SSH connection +does not result in the execution being aborted. In this case, the logs can also be analyzed +retrospectively.

+

List all plays

+

The osism apply command can be used to list all integrated playbooks and their associated +environments. Custom plays that have been added in the configuration repository are not visible +in this list.

+
$ osism apply
2023-09-30 10:09:25 | INFO | No role given for execution. The roles listed in the table can be used.
+------------------------------------------------------------------+----------------+
| Role | Environment |
|------------------------------------------------------------------+----------------|
| aodh | kolla |
| barbican | kolla |
| bifrost | kolla |
| bifrost-keypair | kolla |
| ceilometer | kolla |
| certificates | generic |
| cinder | kolla |
| cloudkitty | kolla |
| collectd | kolla |
| common | kolla |
| designate | kolla |
| elasticsearch | kolla |
| etcd | kolla |
| glance | kolla |
| gnocchi | kolla |
| grafana | kolla |
| heat | kolla |
| horizon | kolla |
| ironic | kolla |
| iscsi | kolla |
...
+

Apply a play

+
$ osism apply operator -l node01
2024-06-14 09:33:10 | INFO | Task f94a2e6f-d199-421c-b7b7-743db4661305 (operator) was prepared for execution.
2024-06-14 09:33:10 | INFO | It takes a moment until task f94a2e6f-d199-421c-b7b7-743db4661305 (operator) has been started and output is visible here.

PLAY [Make ssh pipelining working] *********************************************

TASK [Do not require tty for all users] ****************************************
ok: [node01]
...
PLAY RECAP *********************************************************************
2024-06-14 09:34:14 | INFO | Play has been completed. There may now be a delay until all logs have been written.
2024-06-14 09:34:14 | INFO | Please wait and do not abort execution.
node01 : ok=11 changed=0 unreachable=0 failed=0 skipped=5 rescued=0 ignored=0
+

Use of custom plays

+

Custom plays can be used in all environments of the configuration repository to add +logic which should also be part of the configuration repository.

+
info

It seems to us to be a good idea to minimize the amount of such special solutions, as extensive in-house +solutions can potentially result in unexpected interactions or additional testing-, integration and maintenance +work.

We would also like to make a clear recommendation that, if possible, missing functions should be resolved by +contributing to OSISM.

+

Some facts about custom plays:

+
    +
  • +

    Plays must be stored under the following naming scheme so that they can be executed with the OSISM command. +environments/<environment>/playbook-<the name of the play>.yml

    +
  • +
  • +

    Without specifying a particular environment the custom environment is used.

    +
    # executes: environments/custom/playbook-setup-serial-device.yml
    osism apply setup-serial-device
    +
  • +
  • +

    Specifying a play of a environment:

    +
    # executes environments/deph/playbook-wipe-parititons.yml
    osism apply -e ceph wipe-parititons
    +
  • +
  • +

    Custom roles that are used for a specific environment must be stored under the following path so that +they can be found by plays.

    +

    environments/<environment>/roles/<role>/

    +
  • +
+

Example play with roles: Manage the infrastructure of the SCS testing environment

+

The SCS hardware landscape testing environment provides a selection of custom roles which are used +to manage some infrastructural aspects of this testing environment.

+ +

Example play: Wiping partitions

+

For example, this is a play to prepare all devices to be used for Ceph on a Ceph +resource node.

+
    +
  • It is saved in the configuration repository in the file environments/ceph/playbook-wipe-partitions.yml.
  • +
  • It is run with osism apply -e ceph wipe-parititons.
  • +
+
warning

Just to be on the safe side: The following example can be useful, but it can also cause a lot of damage. Be warned!

+
---
- name: Wipe partitions
hosts: ceph-resource
gather_facts: false

tasks:
- name: Find all logical devices with prefix ceph
ansible.builtin.find:
paths: /dev/mapper
recurse: false
file_type: link
patterns: "ceph*"
register: result

- name: Remove all ceph related logical devices
become: true
ansible.builtin.command: "dmsetup remove {{ item.path }}"
loop: "{{ result.files }}"
changed_when: true

- name: Wipe partitions with wipefs
become: true
ansible.builtin.command: "wipefs --all {{ item }}"
changed_when: true
loop: "{{ ansible_local.testbed_ceph_devices_all }}"

- name: Overwrite first 32M with zeros
become: true
ansible.builtin.command: "dd if=/dev/zero of={{ item }} bs=1M count=32 oflag=direct,dsync"
changed_when: true
loop: "{{ ansible_local.testbed_ceph_devices_all }}"
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/manager/console/index.html b/docs/iaas/guides/operations-guide/manager/console/index.html new file mode 100644 index 0000000000..c25775d272 --- /dev/null +++ b/docs/iaas/guides/operations-guide/manager/console/index.html @@ -0,0 +1,43 @@ + + + + + +Console | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Console

+

A console command is available in the OSISM CLI. This allows specific parts of the +environment to be operated interactively.

+

Ansible

+

Used tool: ansible-console

+
$ osism console --type ansible testbed-node-0
Welcome to the ansible console. Type help or ? to list commands.

dragon@testbed-node-0 (1)[f:5]$ !uptime
testbed-node-0 | CHANGED | rc=0 >>
18:14:15 up 80 days, 33 min, 0 users, load average: 4.00, 3.07, 2.67
dragon@testbed-node-0 (1)[f:5]$
+

Shortcut: osism console .testbed-node-0

+

Clush

+

Used tool: ClusterShell

+

The same groups as defined in the Ansible Inventory can be used.

+
$ osism console --type clush control
Enter 'quit' to leave this interactive mode
Working with nodes: testbed-node-[0-2]
clush>
+

Shortcut: osism console :control

+

Container

+

Used tool: Python Prompt Toolkit

+
$ osism console --type container testbed-node-0/fluentd
(fluentd)[td-agent@testbed-node-0 /]$ ps ax
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 dumb-init --single-child -- kolla_start
7 ? Sl 24:28 /opt/td-agent/bin/ruby /usr/sbin/td-agent -o /var/log/kolla/fluentd/fluent
25 ? Sl 3519:55 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /usr/sbin/td-agent -o /var
238 pts/0 Ss 0:00 bash
247 pts/0 R+ 0:00 ps ax
+

Shortcut: osism console testbed-node-0/fluentd

+

SSH

+

Used tool: OpenSSH

+
$ osism console --type ssh testbed-node-0
You have new mail.
Last login: Wed Sep 27 18:15:39 2023 from 192.168.16.5
dragon@testbed-node-0:~$ uptime
18:16:25 up 80 days, 35 min, 1 user, load average: 2.85, 3.04, 2.71
+

Shortcut: osism console testbed-node-0

+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/manager/get/index.html b/docs/iaas/guides/operations-guide/manager/get/index.html new file mode 100644 index 0000000000..181eb5203f --- /dev/null +++ b/docs/iaas/guides/operations-guide/manager/get/index.html @@ -0,0 +1,58 @@ + + + + + +Get | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Get

+

A get command is available in the OSISM CLI. This allows to gather specific information.

+

Hosts

+
    +
  • +

    Get all hosts defined in the inventory

    +
    $ osism get hosts
    +-----------------------------------+
    | Host |
    |-----------------------------------|
    | testbed-manager.testbed.osism.xyz |
    | testbed-node-0.testbed.osism.xyz |
    | testbed-node-1.testbed.osism.xyz |
    | testbed-node-2.testbed.osism.xyz |
    +-----------------------------------+
    +
  • +
  • +

    Get all hosts defined in the inventory that are member of a specific inventory group

    +
    $ osism get hosts -l manager
    +-----------------------------------+
    | Host |
    |-----------------------------------|
    | testbed-manager.testbed.osism.xyz |
    +-----------------------------------+

    $ osism get hosts -l control
    +----------------------------------+
    | Host |
    |----------------------------------|
    | testbed-node-0.testbed.osism.xyz |
    | testbed-node-1.testbed.osism.xyz |
    | testbed-node-2.testbed.osism.xyz |
    +----------------------------------+
    +
  • +
+

Host variables

+
    +
  • +

    Get all host vars of a specific node

    +
    osism get hostvars testbed-manager.testbed.osism.xyz
    +
  • +
  • +

    Get a specific host var of a specific node

    +
    $ osism get hostvars testbed-manager.testbed.osism.xyz ansible_host
    +-----------------------------------+--------------+----------------+
    | Host | Variable | Value |
    +===================================+==============+================+
    | testbed-manager.testbed.osism.xyz | ansible_host | '192.168.16.5' |
    +-----------------------------------+--------------+----------------+
    +
  • +
+

Host facts

+
    +
  • +

    Get all facts of a specific node

    +
    osism get facts testbed-manager.testbed.osism.xyz
    +
  • +
  • +

    Get a specific fact of a specific node

    +
    $ osism get facts testbed-manager.testbed.osism.xyz ansible_architecture
    +-----------------------------------+----------------------+----------+
    | Host | Fact | Value |
    +===================================+======================+==========+
    | testbed-manager.testbed.osism.xyz | ansible_architecture | 'x86_64' |
    +-----------------------------------+----------------------+----------+
    +
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/manager/index.html b/docs/iaas/guides/operations-guide/manager/index.html new file mode 100644 index 0000000000..67bf892cb0 --- /dev/null +++ b/docs/iaas/guides/operations-guide/manager/index.html @@ -0,0 +1,25 @@ + + + + + +Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/manager/log/index.html b/docs/iaas/guides/operations-guide/manager/log/index.html new file mode 100644 index 0000000000..0cb55cf882 --- /dev/null +++ b/docs/iaas/guides/operations-guide/manager/log/index.html @@ -0,0 +1,49 @@ + + + + + +Logging | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Logging

+

Ansible

+

Files

+

Each Ansible service has its own local Ansible log file. These log files are not persistent. The ARA service is +used for the persistence of Ansible logs. The log files can be used to view currently running Ansible Plays, +for example if they are running as a background task.

+
$ docker exec -it osism-ansible tail -f /ansible/logs/ansible.log
$ docker exec -it ceph-ansible tail -f /ansible/logs/ansible.log
$ docker exec -it kolla-ansible tail -f /ansible/logs/ansible.log
+

ARA - ARA Records Ansible

+
$ osism log ansible
(ara) help

Documented commands (use 'help -v' for verbose/'help <topic>' for details):
===========================================================================
alias exit history quit run_script shell
edit help macro run_pyscript set shortcuts

Application commands (type help <topic>):
=========================================
complete host metrics playbook delete record delete result show
expire host show playbook list record list task delete
help play delete playbook metrics record show task list
host delete play list playbook prune result delete task metrics
host list play show playbook show result list task show
+

Sample usage

+

As an example, the role common is run. Irrelevant parts of outputs have been removed.

+
$ osism apply common
+
$ osism log ansible
+
(ara) play list
+----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+
| id | status | name | playbook | tasks | results | started | duration |
+----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+
| 69 | completed | Apply role common | 49 | 21 | 68 | 2023-09-30T10:14:01.731212Z | 00:00:38.238032 |
+----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+
+
(ara) play show 69
+----------+------------------------------------------+
| Field | Value |
+----------+------------------------------------------+
| id | 69 |
| report | http://ara-server:8000/playbooks/49.html |
| status | completed |
| name | Apply role common |
| playbook | (49) /ansible/kolla-common.yml |
| started | 2023-09-30T10:14:01.731212Z |
| ended | 2023-09-30T10:14:39.969244Z |
| duration | 00:00:38.238032 |
| items | {'tasks': 21, 'results': 68} |
+----------+------------------------------------------+
+
(ara) task list
+-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+
| id | status | results | action | name | playbook | started | duration |
+-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+
| 910 | completed | 0 | meta | common : Flush handlers | 49 | 2023-09-30T10:14:37.126872Z | 00:00:02.552006 |
| 909 | completed | 4 | file | common : Link kolla_logs volume to /var/log/kolla | 49 | 2023-09-30T10:14:35.502754Z | 00:00:01.039468 |
| 908 | completed | 4 | kolla_docker | common : Creating log volume | 49 | 2023-09-30T10:14:34.134312Z | 00:00:01.076976 |
| 907 | completed | 4 | kolla_docker | common : Check common containers | 49 | 2023-09-30T10:14:31.411916Z | 00:00:02.146165 |
| 906 | completed | 4 | template | common : Copy rabbitmq erl_inetrc to kolla toolbox | 49 | 2023-09-30T10:14:29.500998Z | 00:00:01.327607 |
| 905 | completed | 4 | template | common : Copy rabbitmq-env.conf to kolla toolbox | 49 | 2023-09-30T10:14:27.979869Z | 00:00:01.231630 |
| 904 | completed | 4 | file | common : Ensuring config directories have correct owner and permission | 49 | 2023-09-30T10:14:26.422535Z | 00:00:01.263370 |
| 903 | completed | 4 | template | common : Ensure RabbitMQ Erlang cookie exists | 49 | 2023-09-30T10:14:24.880329Z | 00:00:01.255475 |
| 902 | completed | 4 | template | common : Copying over cron logrotate config file | 49 | 2023-09-30T10:14:23.199518Z | 00:00:01.392765 |
| 901 | completed | 4 | template | common : Copying over td-agent.conf | 49 | 2023-09-30T10:14:21.085351Z | 00:00:01.826039 |
| 900 | completed | 1 | find | common : Find custom fluentd output config files | 49 | 2023-09-30T10:14:19.859670Z | 00:00:00.939663 |
| 899 | completed | 1 | find | common : Find custom fluentd format config files | 49 | 2023-09-30T10:14:18.711171Z | 00:00:00.858586 |
| 898 | completed | 1 | find | common : Find custom fluentd filter config files | 49 | 2023-09-30T10:14:17.542234Z | 00:00:00.877270 |
| 897 | completed | 1 | find | common : Find custom fluentd input config files | 49 | 2023-09-30T10:14:15.911699Z | 00:00:01.315217 |
| 896 | completed | 4 | template | common : Copying over config.json files for services | 49 | 2023-09-30T10:14:13.588195Z | 00:00:02.031647 |
| 895 | completed | 4 | copy | service-cert-copy : common | Copying over backend internal TLS key | 49 | 2023-09-30T10:14:12.216984Z | 00:00:01.074853 |
| 894 | completed | 4 | copy | service-cert-copy : common | Copying over backend internal TLS certificate | 49 | 2023-09-30T10:14:10.895833Z | 00:00:01.022530 |
| 893 | completed | 4 | copy | service-cert-copy : common | Copying over extra CA certificates | 49 | 2023-09-30T10:14:08.551850Z | 00:00:02.040932 |
| 892 | completed | 4 | include_tasks | common : include_tasks | 49 | 2023-09-30T10:14:07.019883Z | 00:00:00.950605 |
| 891 | completed | 4 | file | common : Ensuring config directories exist | 49 | 2023-09-30T10:14:04.801633Z | 00:00:01.926842 |
| 890 | completed | 4 | include_tasks | common : include_tasks | 49 | 2023-09-30T10:14:03.054547Z | 00:00:01.166032 |
+-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+
+
(ara) task show 910
+----------+------------------------------------------+
| Field | Value |
+----------+------------------------------------------+
| id | 910 |
| uuid | 0242ac1f-6510-3867-9eea-00000000004f |
| report | http://ara-server:8000/playbooks/49.html |
| name | common : Flush handlers |
| action | meta |
| status | completed |
| path | /ansible/roles/common/tasks/deploy.yml |
| lineno | 8 |
| started | 2023-09-30T10:14:37.126872Z |
| ended | 2023-09-30T10:14:39.678878Z |
| duration | 00:00:02.552006 |
| tags | ['common'] |
| handler | False |
+----------+------------------------------------------+
+
(ara) playbook list
+----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+
| id | status | controller | user | ansible_version | path | tasks | results | hosts | started | duration |
+----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+
| 49 | completed | kolla-ansible.manager_default | dragon | 2.14.10 | /ansible/kolla-common.yml | 21 | 68 | 5 | 2023-09-30T10:14:01.410334Z | 00:00:39.135309 |
+----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+
+
(ara) playbook metrics
+---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+
| aggregate | count | duration_total | duration_avg | tasks | results | hosts | completed | failed | running |
+---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+
| /ansible/kolla-common.yml | 2 | 0:02:53.934432 | 0:01:26.967216 | 46 | 152 | 10 | 2 | 0 | 0 |
+---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+
+
(ara) host list
+-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+
| id | name | playbook | changed | failed | ok | skipped | unreachable | updated |
+-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+
| 164 | testbed-node-2.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.543599Z |
| 161 | testbed-manager.testbed.osism.xyz | 49 | 0 | 0 | 18 | 2 | 0 | 2023-09-30T10:14:40.283581Z |
| 163 | testbed-node-1.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.280601Z |
| 162 | testbed-node-0.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.279181Z |
| 165 | kolla-ansible.manager_default | 49 | 0 | 0 | 0 | 0 | 0 | 2023-09-30T10:14:16.932135Z |
+-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+
+
(ara) host show 164
+-------------+------------------------------------------+
| Field | Value |
+-------------+------------------------------------------+
| id | 164 |
| report | http://ara-server:8000/playbooks/49.html |
| name | testbed-node-2.testbed.osism.xyz |
| changed | 0 |
| failed | 0 |
| ok | 14 |
| skipped | 2 |
| unreachable | 0 |
| updated | 2023-09-30T10:14:40.543599Z |
+-------------+------------------------------------------+
+

Container

+
$ osism log container testbed-node-0 horizon
[...]
++++ APACHE_LOCK_DIR=/var/lock/apache2
++++ export APACHE_LOG_DIR=/var/log/apache2
++++ APACHE_LOG_DIR=/var/log/apache2
++++ export LANG=C
++++ LANG=C
++++ export LANG
+++ install -d /var/run/apache2/
+++ rm -rf '/var/run/apache2/*'
+++ [[ ubuntu =~ centos|rocky ]]
+ echo 'Running command: '\''/usr/sbin/apache2 -DFOREGROUND'\'''
+ exec /usr/sbin/apache2 -DFOREGROUND
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.16.10. Set the 'ServerName' directive globally to suppress this message
+

OpenSearch

+

OpenSearch can be queried with SQL.

+
$ osism log opensearch
>>> SELECT * FROM flog-2023.10.31 LIMIT 1;
Oct 31 10:45:36 testbed-node-0 docker[847573]: cluster 2023-10-31T10:45:35.498718+0000 mgr.testbed-node-0 (mgr.5184) 24194 : cluster [DBG] pgmap v24196: 321 pgs: 321 active+clean; 577 KiB data, 270 MiB used, 60 GiB / 60 GiB avail

>>> SELECT * FROM flog-2023.10.31 LIMIT 5;
Oct 31 11:19:57 testbed-node-2 docker[880827]: 2023-10-31T11:19:57.650+0000 7fa7e7c88700 0 [dashboard INFO root] Redirecting to active 'http://192.168.16.10:7000/'
Oct 31 11:19:57 testbed-node-2 docker[880827]: 2023-10-31T11:19:57.650+0000 7fa7e7c88700 0 [dashboard INFO request] [::ffff:192.168.16.11:56210] [OPTIONS] [302] [0.001s] [105.0B] [8a69cc7a-23db-410b-b744-cc5689cb4f4c] /
Oct 31 11:19:58 testbed-node-2 docker[844686]: cluster 2023-10-31T11:19:56.329684+0000 mgr.testbed-node-0 (mgr.5184) 25224 : cluster [DBG] pgmap v25226: 321 pgs: 321 active+clean; 577 KiB data, 270 MiB used, 60 GiB / 60 GiB avail
Oct 31 11:19:58 testbed-node-2 docker[844686]: debug 2023-10-31T11:19:58.566+0000 7fdbc9728700 1 mon.testbed-node-2@2(peon).osd e74 _set_new_cache_sizes cache_size:1020054731 inc_alloc: 348127232 full_alloc: 348127232 kv_alloc: 322961408
Oct 31 11:19:58 testbed-node-2 docker[880827]: 2023-10-31T11:19:58.710+0000 7fa7eb48f700 0 [dashboard INFO root] Redirecting to active 'http://192.168.16.10:7000/'

>>> SELECT * FROM flog-2023.10.31 WHERE Hostname = 'testbed-node-0' LIMIT 5
PATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29
REQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27
SCRIPT_NAME: `` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:28
192.168.16.10 - - [31/Oct/2023 10:57:33] "GET / HTTP/1.1" 300 1761 0.001253
(1039) accepted ('192.168.16.10', 58732) server /var/lib/kolla/venv/lib/python3.10/site-packages/eventlet/wsgi.py:1004

>>> SELECT * FROM flog-2023.10.31 WHERE Hostname = 'testbed-node-0' AND programname = 'keystone' LIMIT 5
PATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29
REQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27
SCRIPT_NAME: `` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:28
PATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29
REQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/manager/task/index.html b/docs/iaas/guides/operations-guide/manager/task/index.html new file mode 100644 index 0000000000..868ce08088 --- /dev/null +++ b/docs/iaas/guides/operations-guide/manager/task/index.html @@ -0,0 +1,36 @@ + + + + + +Task | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Task

+

List

+

All running or scheduled tasks can be listed with osism task list.

+
+----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------+
| Worker | ID | Name | Status | Start time | Arguments |
|----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------|
| celery@kolla-ansible | 8a553e69-c532-4ba0-a5d4-08a983bde692 | osism.tasks.kolla.run | ACTIVE | 2023-09-27 17:55:54.252250 | ['kolla', 'common', ['-e kolla_action=pull']] |
| celery@osism-ansible | dba72dd5-1885-408f-9262-e0ded111a007 | osism.tasks.ansible.run | ACTIVE | 2023-09-27 18:00:31.215879 | ['generic', 'facts', []] |
+----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------+
+

Broker reset

+

Sometimes tasks get stuck. Due to the internal locks it is then not possible to re-execute +plays with the same name. Also it is currently not possible to cancel already running tasks +(is on the todo list). The only way to unblock the situation is to stop the manager service +and start it again.

+
cd /opt/manager
docker compose down
docker compose up -d
+

In earlier versions of OSISM, the Redis service was not stateless. In these cases, it is +necessary to delete the Redis service volume before restarting the manager service.

+
docker volume rm manager_redis
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/network/index.html b/docs/iaas/guides/operations-guide/network/index.html new file mode 100644 index 0000000000..952b091036 --- /dev/null +++ b/docs/iaas/guides/operations-guide/network/index.html @@ -0,0 +1,59 @@ + + + + + +Network | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Network

+

OpenStack, OVN, and Open vSwitch all really like UUIDs.

+
$ openstack --os-cloud admin image list -f yaml
- ID: d64f0b9d-0ea1-40b0-b879-b98e46fc7bcf
Name: Cirros 0.6.0
Status: active
- ID: ee842bc5-dd29-4de5-a5db-1c9be759fe85
Name: Cirros 0.6.1
Status: active
- ID: cd28d95c-bd12-4e1e-8155-b9bf5ecbcb2f
Name: Cirros 0.6.2
Status: active
+

These UUIDs are great for uniqueness, but 36-character strings are terrible +for readability. Statistically, just the first few characters are enough for +uniqueness in small environments, so let’s define a helper to make things more +readable:

+
abbrev() { a='[0-9a-fA-F]' b=$a$a c=$b$b; sed "s/$b-$c-$c-$c-$c$c$c//g"; }
+

You can use this as a filter to abbreviate UUIDs. For example, use it to abbreviate +the above image list:

+
$ openstack --os-cloud admin image list -f yaml | abbrev
- ID: d64f0b
Name: Cirros 0.6.0
Status: active
- ID: ee842b
Name: Cirros 0.6.1
Status: active
- ID: cd28d9
Name: Cirros 0.6.2
Status: active
+

Source: https://docs.ovn.org/en/stable/tutorials/ovn-openstack.html#shortening-uuids

+

Open vSwitch (OVS)

+ +

Open vSwitch on a network node with external network vxlan0 and integration +with the Octavia service via ohm0.

+
$ docker exec -it openvswitch_vswitchd ovs-vsctl show
2e6227aa-33f1-4762-8831-ab678ce7272d
Bridge br-int
fail_mode: secure
datapath_type: system
Port ovn-testbe-0
Interface ovn-testbe-0
type: geneve
options: {csum="true", key=flow, remote_ip="192.168.16.12"}
Port br-int
Interface br-int
type: internal
Port ovn-testbe-1
Interface ovn-testbe-1
type: geneve
options: {csum="true", key=flow, remote_ip="192.168.16.11"}
Port tap8fe7d09b-90
Interface tap8fe7d09b-90
Port ohm0
Interface ohm0
type: internal
Bridge br-ex
Port vxlan0
Interface vxlan0
Port br-ex
Interface br-ex
type: internal
+

Open Virtual Network (OVN)

+ +

Get OVN NB and OVN SB connection information from the /etc/kolla/neutron-server/ml2_conf.ini +file.

+
ovn_nb_connection=$(sudo grep -P -o -e "(?<=^ovn_nb_connection = ).*" "/etc/kolla/neutron-server/ml2_conf.ini")
ovn_sb_connection=$(sudo grep -P -o -e "(?<=^ovn_sb_connection = ).*" "/etc/kolla/neutron-server/ml2_conf.ini")
+

The following examples are from a fresh osism/testbed +deployment with no payload running yet.

+

OVN NB DB entries:

+
$ docker exec ovn_northd ovn-nbctl --db "$ovn_nb_connection" show | abbrev
switch b5139b (neutron-8fe7d0) (aka lb-mgmt-net)
port 45a49e
type: localport
addresses: ["fa:16:3e:fa:99:ea 10.1.0.2"]
port 4d39a5 (aka octavia-listen-port-testbed-node-2)
addresses: ["fa:16:3e:dc:11:e4 10.1.0.45"]
port 8df1b7 (aka octavia-listen-port-testbed-node-0)
addresses: ["fa:16:3e:4d:63:a9 10.1.0.43"]
port ddb6aa (aka octavia-listen-port-testbed-node-1)
addresses: ["fa:16:3e:67:f3:3d 10.1.0.40"]
+

OVN SB DB entries:

+
$ docker exec ovn_northd ovn-sbctl --db "$ovn_sb_connection" show | abbrev
Chassis testbed-node-0
hostname: testbed-node-0
Encap geneve
ip: "192.168.16.10"
options: {csum="true"}
Port_Binding "8df1b7"
Chassis testbed-node-2
hostname: testbed-node-2
Encap geneve
ip: "192.168.16.12"
options: {csum="true"}
Port_Binding "4d39a5"
Chassis testbed-node-1
hostname: testbed-node-1
Encap geneve
ip: "192.168.16.11"
options: {csum="true"}
Port_Binding "ddb6aa
+

OVN NB status:

+
$ docker exec ovn_nb_db ovs-appctl -t /var/run/ovn/ovnnb_db.ctl cluster/status OVN_Northbound | abbrev
6d15
Name: OVN_Northbound
Cluster ID: f5eb (f5ebd8)
Server ID: 6d15 (6d159e)
Address: tcp:192.168.16.10:6643
Status: cluster member
Role: follower
Term: 5
Leader: 87d6
Vote: 87d6

Last Election started 41049332 ms ago, reason: timeout
Election timer: 1000
Log: [2, 54]
Entries not yet committed: 0
Entries not yet applied: 0
Connections: ->21d7 ->87d6 <-87d6 <-21d7
Disconnections: 6
Servers:
6d15 (6d15 at tcp:192.168.16.10:6643) (self)
87d6 (87d6 at tcp:192.168.16.11:6643) last msg 266 ms ago
21d7 (21d7 at tcp:192.168.16.12:6643) last msg 41048563 ms ago
+

OVN SB status:

+
$ docker exec ovn_sb_db ovs-appctl -t /var/run/ovn/ovnsb_db.ctl cluster/status OVN_Southbound | abbrev
be29
Name: OVN_Southbound
Cluster ID: bd0c (bd0c26)
Server ID: be29 (be2932)
Address: tcp:192.168.16.10:6644
Status: cluster member
Role: follower
Term: 6
Leader: dfdf
Vote: unknown

Last Election started 41063820 ms ago, reason: timeout
Election timer: 1000
Log: [2, 62]
Entries not yet committed: 0
Entries not yet applied: 0
Connections: ->dfdf ->085c <-dfdf <-085c
Disconnections: 7
Servers:
be29 (be29 at tcp:192.168.16.10:6644) (self)
dfdf (dfdf at tcp:192.168.16.11:6644) last msg 146 ms ago
085c (085c at tcp:192.168.16.12:6644) last msg 41063293 ms ago
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/cinder/index.html b/docs/iaas/guides/operations-guide/openstack/cinder/index.html new file mode 100644 index 0000000000..e73d1a9a00 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/cinder/index.html @@ -0,0 +1,77 @@ + + + + + +Cinder | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Cinder

+

Remove service

+
$ openstack --os-cloud admin volume service list
+------------------+-----------------------------------+----------+---------+-------+----------------------------+
| Binary | Host | Zone | Status | State | Updated At |
+------------------+-----------------------------------+----------+---------+-------+----------------------------+
| cinder-scheduler | testbed-node-0 | internal | enabled | up | 2023-10-01T08:53:14.000000 |
| cinder-scheduler | testbed-node-1 | internal | enabled | up | 2023-10-01T08:53:15.000000 |
| cinder-scheduler | testbed-node-2 | internal | enabled | up | 2023-10-01T08:53:15.000000 |
| cinder-volume | testbed-node-0@rbd-1 | nova | enabled | down | 2023-09-30T18:50:05.000000 |
| cinder-volume | testbed-node-2@rbd-1 | nova | enabled | down | 2023-09-30T18:50:05.000000 |
| cinder-volume | testbed-node-1@rbd-1 | nova | enabled | down | 2023-09-30T18:50:08.000000 |
+------------------+-----------------------------------+----------+---------+-------+----------------------------+
+
$ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-0@rbd-1
Service cinder-volume on host testbed-node-0@rbd-1 removed.
$ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-1@rbd-1
Service cinder-volume on host testbed-node-1@rbd-1 removed.
$ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-2@rbd-1
Service cinder-volume on host testbed-node-2@rbd-1 removed.
+
$ openstack --os-cloud admin volume service list
+------------------+-----------------------------------+----------+---------+-------+----------------------------+
| Binary | Host | Zone | Status | State | Updated At |
+------------------+-----------------------------------+----------+---------+-------+----------------------------+
| cinder-scheduler | testbed-node-0 | internal | enabled | up | 2023-10-01T08:56:24.000000 |
| cinder-scheduler | testbed-node-1 | internal | enabled | up | 2023-10-01T08:56:25.000000 |
| cinder-scheduler | testbed-node-2 | internal | enabled | up | 2023-10-01T08:56:25.000000 |
+------------------+-----------------------------------+----------+---------+-------+----------------------------+
+

Sync quota

+

It can happen that more block storage usage is stored in the database for a project than +is actually used. This can be corrected using cinder-manage.

+

For all projects:

+
$ docker exec -it cinder_api cinder-manage quota sync
+

Only for a specific project:

+
$ docker exec -it cinder_api cinder-manage quota sync --project-id PROJECT_ID
+

Quality of Service (QoS)

+ +

Create default volume QoS policy that allows 1000 read IOPS and 1000 write IOPS.

+
$ openstack --os-cloud admin volume qos create \
--consumer both \
--property read_iops_sec=1000 \
--property write_iops_sec=1000 \
default
+------------+---------------------------------------------+
| Field | Value |
+------------+---------------------------------------------+
| consumer | both |
| id | 48920d26-e85f-4920-8ed4-ff8d322c77b9 |
| name | testing |
| properties | read_iops_sec='1000', write_iops_sec='1000' |
+------------+---------------------------------------------+
+
$ openstack --os-cloud admin volume qos list
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
| ID | Name | Consumer | Associations | Properties |
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
| 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | | read_iops_sec='1000', write_iops_sec='1000' |
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
+

Assign the default volume QoS policy to the __DEFAULT volume type.

+
$ openstack --os-cloud admin volume qos associate default __DEFAULT__
+
$ openstack --os-cloud admin volume qos list
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
| ID | Name | Consumer | Associations | Properties |
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
| 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | __DEFAULT__ | read_iops_sec='1000', write_iops_sec='1000' |
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
+

Change the read IOPS from 1000 to 2000 and the write IOPS from 1000 to 2000 of the default volume QoS policy.

+
$ openstack --os-cloud admin volume qos set \
--property read_iops_sec=2000 \
--property write_iops_sec=2000 \
default
+
$ openstack --os-cloud admin volume qos list
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
| ID | Name | Consumer | Associations | Properties |
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
| 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | __DEFAULT__ | read_iops_sec='2000', write_iops_sec='2000' |
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
+

The following properties are available.

+

For Fixed IOPS per volume:

+
    +
  • read_iops_sec
  • +
  • write_iops_sec
  • +
  • total_iops_sec
  • +
+

For Burst IOPS per volume:

+
    +
  • read_iops_sec_max
  • +
  • write_iops_sec_max
  • +
  • total_iops_sec_max
  • +
+

For Fixed bandwidth per volume:

+
    +
  • read_bytes_sec
  • +
  • write_bytes_sec
  • +
  • total_bytes_sec
  • +
+

For Burst bandwidth per volume:

+
    +
  • read_bytes_sec_max
  • +
  • write_bytes_sec_max
  • +
  • total_bytes_sec_max
  • +
+

For burst bucket size:

+
    +
  • size_iops_sec
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/index.html b/docs/iaas/guides/operations-guide/openstack/index.html new file mode 100644 index 0000000000..9c083ecb62 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/index.html @@ -0,0 +1,166 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

OpenStack

+

Create an external network

+

The play network-external is available and usable as of OSISM 7.0.6.

+
osism apply network-external
+

Available parameters for the OpenStack Environment (environments/openstack/configuration.yml).

+
ParameterDefault
network_external_allocation_pool_end"192.168.112.200"
network_external_allocation_pool_start"192.168.112.100"
network_external_cidr"192.168.112.0/20"
network_external_cloudadmin
network_external_gateway_ip"192.168.112.5"
network_external_namepublic
network_external_provider_network_typeflat
network_external_provider_physical_networkphysnet1
network_external_statepresent
+

Reboot a compute node

+
    +
  1. +

    Live migrate all instances running on the compute node +with the help of the OpenStack Resource Manager

    +
  2. +
  3. +

    Ensure that no more instances are running on the compute node

    +
    ps ax | grep qemu
    +
  4. +
  5. +

    Reboot the compute node

    +
    osism apply reboot -l NODE -e ireallymeanit=yes
    +
  6. +
  7. +

    Wait for the compute node to reboot

    +
  8. +
  9. +

    Re-enable the compute service

    +
    openstack --os-cloud admin compute service set --enable --disable-reason "" NODE nova-compute
    +
  10. +
  11. +

    Check compute service

    +
    openstack --os-cloud admin compute service list --host NODE --service nova-compute
    +
  12. +
+

Add a new compute node

+
    +
  1. +

    Add the operater user

    +
    osism apply operator -u osism -l NODE
    +
  2. +
  3. +

    Run the bootstrap

    +
    osism apply bootstrap -l NODE
    +
  4. +
  5. +

    When a routed network fabric is used deploy the FRR service (optional)

    +
    osism apply frr -l NODE
    +
  6. +
  7. +

    Deploy logging service and Prometheus exporters

    +
    osism apply common -l NODE
    osism apply prometheus -l NODE
    osism apply scaphandre -l NODE
    +
  8. +
  9. +

    Deploy network services

    +
    osism apply openvswitch -l NODE
    osism apply ovn -l NODE
    osism apply neutron -l NODE
    +

    If you do not use the OVN SDN skip osism apply ovn -l NODE.

    +
  10. +
  11. +

    Deploy compute services

    +
    osism apply nova -l NODE
    +
  12. +
  13. +

    Deploy telemetry services (optional)

    +
    osism apply ceilometer -l NODE
    +
  14. +
  15. +

    Deploy Netdata service (optional)

    +
    osism apply netdata -l NODE
    +
  16. +
  17. +

    Add compute node to Prometheus monitoring

    +
    osism apply prometheus -l monitoring
    +
  18. +
  19. +

    Refresh the /etc/hosts file

    +
    osism apply hosts
    +
  20. +
  21. +

    Refresh the SSH client configuration file

    +
    osism apply sshconfig
    +
  22. +
  23. +

    Add compute node to the known hosts file

    +
    osism apply known-hosts
    +
  24. +
+

Containers that run on a compute node. Versions may differ. There is no ceilometer_compute container +if you have not deployed the optional OpenStack telemetry service.

+
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
559e5176695c quay.io/osism/nova-compute:27.1.1.20230919 "dumb-init --single-…" 5 minutes ago Up 5 minutes (healthy) nova_compute
31248d71ab7d quay.io/osism/nova-libvirt:8.0.0.20230919 "dumb-init --single-…" 6 minutes ago Up 6 minutes (healthy) nova_libvirt
9292030d706c quay.io/osism/nova-ssh:27.1.1.20230919 "dumb-init --single-…" 6 minutes ago Up 6 minutes (healthy) nova_ssh
fda4b6fb30c8 quay.io/osism/neutron-metadata-agent:22.0.3.20230919 "dumb-init --single-…" 2 hours ago Up 2 hours (healthy) neutron_ovn_metadata_agent
0e3ec450b668 quay.io/osism/ceilometer-compute:20.0.1.20230919 "dumb-init --single-…" 6 hours ago Up 6 hours (healthy) ceilometer_compute
25ff9702e0e5 quay.io/osism/prometheus-libvirt-exporter:6.0.0.20230919 "dumb-init --single-…" 6 hours ago Up 6 hours prometheus_libvirt_exporter
1bff2e29923b quay.io/osism/prometheus-cadvisor:0.45.0.20230919 "dumb-init --single-…" 6 hours ago Up 6 hours prometheus_cadvisor
602832daf237 quay.io/osism/prometheus-node-exporter:1.4.0.20230919 "dumb-init --single-…" 6 hours ago Up 6 hours prometheus_node_exporter
d4de2f32cdf8 quay.io/osism/ovn-controller:23.6.1.20230919 "dumb-init --single-…" 6 hours ago Up 6 hours ovn_controller
3bf43ae5a94f quay.io/osism/openvswitch-vswitchd:3.1.2.20230919 "dumb-init --single-…" 7 hours ago Up 7 hours (healthy) openvswitch_vswitchd
ebc048b02ab2 quay.io/osism/openvswitch-db-server:3.1.2.20230919 "dumb-init --single-…" 7 hours ago Up 7 hours (healthy) openvswitch_db
4f33dfa66c14 hubblo/scaphandre:0.5.0 "scaphandre promethe…" 7 hours ago Up 7 hours 10.10.129.64:9155->8080/tcp scaphandre
9b1f6342dc60 quay.io/osism/cron:3.0.20230919 "dumb-init --single-…" 7 hours ago Up 7 hours cron
718aecaddde1 quay.io/osism/kolla-toolbox:16.1.1.20230919 "dumb-init --single-…" 7 hours ago Up 7 hours kolla_toolbox
f6f9422c1853 quay.io/osism/fluentd:4.5.1.20230919 "dumb-init --single-…" 7 hours ago Up 7 hours fluentd
+

Remove a compute node

+
    +
  1. +

    In the configuration repository remove the compute node everywhere. Then update the configuration +repository on the manager with osism apply configuration

    +
  2. +
  3. +

    Live migrate all instances running on the compute node +with the help of the OpenStack Resource Manager

    +
  4. +
  5. +

    Evacuate all instances on the compute node +with the help of the OpenStack Resource Manager

    +
  6. +
  7. +

    Ensure that no more instances are running on the compute node

    +
    ps ax | grep qemu
    +
  8. +
  9. +

    Stop all OpenStack compute services on the compute node

    +
    systemctl stop kolla-nova_ssh-container.service
    systemctl stop kolla-nova_libvirt-container.service
    systemctl stop kolla-nova_compute-container.service
    +
  10. +
  11. +

    Delete the compute service

    +
    $ openstack --os-cloud admin compute service list --host NODE
    +--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+
    | ID | Binary | Host | Zone | Status | State | Updated At |
    +--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+
    | 90345eb5-cf2f-47ef-becc-758ee36fb132 | nova-compute | NODE | nova | enabled | down | 2023-12-21T11:53:00.000000 |
    +--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+
    +
    $ openstack --os-cloud admin compute service delete 90345eb5-cf2f-47ef-becc-758ee36fb132
    +
  12. +
  13. +

    Stop all OpenStack network services on the compute node

    +
    systemctl stop kolla-neutron_ovn_metadata_agent-container.service
    systemctl stop kolla-ovn_controller-container.service
    +
  14. +
  15. +

    Delete the network services

    +
    $ openstack --os-cloud admin network agent list --host NODE
    +--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+
    | ID | Agent Type | Host | Availability Zone | Alive | State | Binary |
    +--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+
    | 0a5708ea-ba8b-5fde-8187-c6b24d3cf5ed | OVN Metadata agent | NODE | | :-) | UP | neutron-ovn-metadata-agent |
    | NODE | OVN Controller agent | NODE | | :-) | UP | ovn-controller |
    +--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+

    $ openstack --os-cloud admin network agent delete 0a5708ea-ba8b-5fde-8187-c6b24d3cf5ed
    $ openstack --os-cloud admin network agent delete NODE
    +
  16. +
  17. +

    Refresh the facts

    +
    osism apply facts
    +
  18. +
  19. +

    Refresh the /etc/hosts file

    +
    osism apply hosts
    +
  20. +
  21. +

    Refresh the SSH client configuration file

    +
    osism apply sshconfig
    +
  22. +
  23. +

    Remove compute node from Prometheus monitoring

    +
    osism apply prometheus -l monitoring
    +
  24. +
  25. +

    Remove compute node from the known hosts file

    +
    osism apply known-hosts
    +
  26. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/keystone/index.html b/docs/iaas/guides/operations-guide/openstack/keystone/index.html new file mode 100644 index 0000000000..2d784ac5db --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/keystone/index.html @@ -0,0 +1,30 @@ + + + + + +Keystone | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Keystone

+
    +
  • +

    List all users of a project who have been assigned the member role

    +
    $ openstack --os-cloud admin role assignment list --names --role member --project test
    +--------+-----------+-------+-----------+--------+--------+-----------+
    | Role | User | Group | Project | Domain | System | Inherited |
    +--------+-----------+-------+-----------+--------+--------+-----------+
    | member | test@test | | test@test | | | False |
    +--------+-----------+-------+-----------+--------+--------+-----------+
    +
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/neutron/index.html b/docs/iaas/guides/operations-guide/openstack/neutron/index.html new file mode 100644 index 0000000000..02de21ef53 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/neutron/index.html @@ -0,0 +1,28 @@ + + + + + +Neutron | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/nova/index.html b/docs/iaas/guides/operations-guide/openstack/nova/index.html new file mode 100644 index 0000000000..682062ae1d --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/nova/index.html @@ -0,0 +1,55 @@ + + + + + +Nova | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Nova

+

Get all servers on a node

+
openstack --os-cloud admin server list --all-projects --host testbed-node-0
+

Stop all servers running on a node

+
for server in $(openstack --os-cloud admin server list --all-projects --host testbed-node-0 --vm-state active -f value -c ID | tr -d '\r'); do
echo stopping server $server
openstack --os-cloud admin server stop $server
sleep 2
done
+

Disable & enable a compute service

+
openstack --os-cloud admin compute service set --disable --description MAINTENANCE testbed-node-0 nova-compute
+
openstack --os-cloud admin compute service list --long
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
| ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | up | 2023-12-14T14:20:24.000000 | MAINTENANCE | False |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
+
openstack --os-cloud admin compute service set --enable testbed-node-0 nova-compute
+
openstack --os-cloud admin compute service list
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+
| ID | Binary | Host | Zone | Status | State | Updated At |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+
| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | enabled | up | 2023-12-14T14:22:54.000000 |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+
+

Force down & up a compute service

+
openstack --os-cloud admin --os-compute-api-version 2.12 compute service set --down testbed-node-0 nova-compute
+
openstack --os-cloud admin compute service list --long
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
| ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | down | 2023-12-14T14:21:47.000000 | None | True |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
+
openstack --os-cloud admin --os-compute-api-version 2.12 compute service set --up testbed-node-0 nova-compute
+
openstack --os-cloud admin compute service list --long
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
| ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | up | 2023-12-14T14:20:24.000000 | None | False |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
+

Huge pages

+
$ grep Huge /proc/meminfo
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
+
$ sudo sudo hugeadm --pool-list
libhugetlbfs: ERROR: Line too long when parsing mounts
Size Minimum Current Maximum Default
2097152 0 0 0 *
1073741824 0 0 0
+
/etc/default/grub
GRUB_CMDLINE_LINUX="default_hugepagesz=1G hugepagesz=1G hugepages=512 transparent_hugepage=never"
+
update-grub
reboot
+
$ grep Huge /proc/meminfo
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 512
HugePages_Free: 512
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 1048576 kB
Hugetlb: 536870912 kB
+
$ sudo hugeadm --pool-list
libhugetlbfs: ERROR: Line too long when parsing mounts
Size Minimum Current Maximum Default
2097152 0 0 0 *
1073741824 512 512 512
+

Quality of Service (QoS)

+ +

Host aggregates

+

Host aggregates can be managed with the playbook. The playbook is used with +osism apply -e openstack host-aggregates.

+

Further arguments for host aggregates can be found in the +documentation for the openstack.cloud.host_aggregate Ansible module.

+
environments/openstack/playbook-host-aggregates.yml
---
- name: Manage host aggregates
hosts: localhost
connection: local

vars:
host_aggregates:
- name: aggregate1
hosts:
- host1
- host2
- host3

tasks:
- name: Create host aggregate
openstack.cloud.host_aggregate:
cloud: admin
state: present
name: "{{ item.name }}"
hosts: "{{ item.hosts }}"
loop: "{{ host_aggregates }}"
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/octavia/index.html b/docs/iaas/guides/operations-guide/openstack/octavia/index.html new file mode 100644 index 0000000000..6bc1135d8e --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/octavia/index.html @@ -0,0 +1,43 @@ + + + + + +Octavia | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Octavia

+

Cleanup of amphorae missing from the DB

+
/var/log/kolla/octavia/octavia-health-manager.log
2023-10-25 16:43:52.547 22 WARNING octavia.amphorae.drivers.health.heartbeat_udp [-]
The amphora 2a33a889-4f9a-4340-84a5-e58a7a8af17e with IP 10.1.0.79 is missing from the
DB, so it cannot be automatically deleted (the compute_id is unknown). An operator must
manually delete it from the compute service.
+

SSH access to amphorae

+
    +
  1. +

    Get the local IP address (lb_network_ip) of the amphora you want to access via +openstack --os-cloud admin loadbalancer amphora list.

    +
  2. +
  3. +

    Connect to one of the nodes that you use for Octavia. Normally the control- +or network nodes.

    +
  4. +
  5. +

    You can now use SSH to access the amphora. The use of sudo is required here because +you cannot access /etc/kolla/octavia-worker/octavia_ssh_key with the operator user +account. Replace lb_network_ip with the local IP address of the amphora.

    +
    sudo ssh -i /etc/kolla/octavia-worker/octavia_ssh_key ubuntu@lb_network_ip
    +
  6. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager/index.html b/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager/index.html new file mode 100644 index 0000000000..36fd9c14b5 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager/index.html @@ -0,0 +1,75 @@ + + + + + +Flavor Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Flavor Manager

+

Overview

+

The OpenStack Flavor Manager manages the creation, modification, and removal of flavors. +It operates as a facilitator that orchestrates compute flavors in alignment +with the standard SCS-0100: Flavor Naming +by utilizing YAML files provided by the SCS project.

+

Installation

+

The OpenStack Flavor Manager can be used via the OSISM CLI. This is the preferred way to use it. +No installation is then required. It is used via osism manage flavors.

+

For use independent of OSISM install the openstack-flavor-manager package with pip. It is likely +that additional dependencies such as pkg-config or libssl-dev must be installed in advance.

+
$ pip install openstack-flavor-manager
+

Or clone the repository osism/openstack-flavor-manager +and use the OpenStack Flavor Manager from source with tox.

+
$ tox -- --help
+

Usage

+

There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Flavor Manager +will be executed. When using the OSISM CLI, the files are expected in environments/openstack +in your configuration repository.

+

The cloud profile to be used can be specified via the optional --cloud parameter. +By default the cloud profile with the name admin is used. It must be possible to create and delete +flavors with the used cloud credentials.

+
$ openstack-flavor-manager --help

Usage: openstack-flavor-manager [OPTIONS]

╭─ Options ────────────────────────────────────────────────────────────────────────────────────╮
│ --name TEXT Name of flavor definitions. [default: scs] │
│ --debug Enable debug logging. │
│ --cloud TEXT Cloud name in clouds.yaml. [default: admin] │
│ --recommended Create recommended flavors. │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────╯
+

To create the mandatory flavors by the SCS-0100: Flavor Naming +standard, you run:

+
$ openstack-flavor-manager
+

To create the recommended flavors by the SCS Flavor Naming Standard, you run:

+
$ openstack-flavor-manager --recommended
+

The output should look like this:

+
2023-09-20 13:03:14 | INFO     | Flavor SCS-1V-4 created
2023-09-20 13:03:14 | INFO | Flavor SCS-2V-8 created
2023-09-20 13:03:14 | INFO | Flavor SCS-4V-16 created
2023-09-20 13:03:14 | INFO | Flavor SCS-8V-32 created
...
+

All recommended flavors are now be available in your OpenStack environment. +Check yourself by running:

+
$ openstack --os-cloud admin flavor list
+
$ openstack --os-cloud admin flavor show SCS-2V-4-20s
+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 0 |
| access_project_ids | None |
| description | None |
| disk | 20 |
| id | 652e3a6c-330e-4ee3-922b-b49c3c093062 |
| name | SCS-2V-4-20s |
| os-flavor-access:is_public | True |
| properties | hw_rng:allowed='true', scs:cpu-type='shared-core', scs:disk0-type='ssd', scs:name-v1='SCS-2V:4:20s', scs:name-v2='SCS-2V-4-20s' |
| ram | 4096 |
| rxtx_factor | 1.0 |
| swap | 0 |
| vcpus | 2 |
+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+
+

Definitions

+

There are two flavor definitions available by default. One for +SCS +and one for OSISM. +Each definition has its own set of mandatory and recommended flavors. The definition of OSISM contains +all definitions of SCS as well as some others.

+

To run the OpenStack Flavor Manager with a specific definition, either scs or osism, +use the optional --name parameter. By default the SCS-0100: Flavor Naming +standard definition will be used.

+
$ openstack-flavor-manager --name osism
+

Name parser and generator

+

A generator and parser for flavor names according to the SCS standard is available on +flavors.scs.community.

+

The flavor name SCS-2V-4-20s is inserted in field Flavor name:

+ +

The flavor SCS-2V-4-20s translated is +2 generic x86-64 vCPUs with 4.0 GiB RAM and SSD 20GB root volume:

+
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/image-manager/index.html b/docs/iaas/guides/operations-guide/openstack/tools/image-manager/index.html new file mode 100644 index 0000000000..74b95d4787 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/image-manager/index.html @@ -0,0 +1,165 @@ + + + + + +Image Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Image Manager

+

The OpenStack Image Manager is a tool for managing all +images on an OpenStack environment

+

Requirements

+

This information is only relevant for the operator of an OpenStack environment. You can skip this section if +you want to use OpenStack Image Manager as a normal user and you are not an operator of an openStack environment.

+

OpenStack Image Service (Glance)

+

The OpenStack Image Service (Glance) is required to upload and discover data assets that are used by other +services.

+

Since this script stores many images in a single project, the Glance quota must be set accordingly high or to unlimited.

+
[DEFAULT]
user_storage_quota = 1TB
+

With most storage backends it makes sense to convert the imported images directly to RAW. So it is required for using Ceph and it's +features too. Recited from the Ceph documentation QEMU and block devices and +Block devices and OpenStack.

+
info

The raw data format is really the only sensible format option to use with RBD. Technically, you could use other QEMU-supported formats +(such as qcow2 or vmdk), but doing so would add additional overhead, and would also render the volume unsafe for virtual machine live +migration when caching (see below) is enabled.

Important Ceph doesn't support QCOW2 for hosting a virtual machine disk. Thus if you want to boot virtual machines in Ceph (ephemeral +backend or boot from volume), the Glance image format must be RAW.

See the OpenStack Glance documentation +for more details.

+

This requires the following parameter for the image import workflow.

+
[taskflow_executor]
conversion_format = raw

[image_import_opts]
image_import_plugins = ['image_decompression', 'image_conversion']

[image_conversion]
output_format = raw
+

Object storage backend

+

If the mirror functionality is used, an object storage backend is required. The use of the mirror functionality +is optional and is not used by default.

+

Getting started

+

This Getting started will upload a private image to your OpenStack environment with +the help of the OpenStack Image Manager.

+
    +
  1. +

    Install the openstack-image-manager package with +pip.

    +
    pip3 install openstack-image-manager
    +

    The installation can also be done via pipenv.

    +

    A Pipefile file is created with this content. The latest version of openstack-image-manager +is used.

    +
    [[source]]
    url = "https://pypi.org/simple"
    verify_ssl = true
    name = "pypi"

    [packages]
    openstack-image-manager = "==0.20240403.0"

    [dev-packages]

    [requires]
    python_version = "3.10"
    +

    The dependencies are then installed and the shell is prepared for use:

    +
    pipenv install
    pipenv shell
    +
  2. +
  3. +

    Create a image definition in the file getting-started.yml in the local directory images.

    +
    ---
    images:
    - name: MyCirros
    enable: true
    format: qcow2
    login: cirros
    password: gocubsgo
    min_disk: 1
    min_ram: 32
    status: active
    visibility: private
    multi: false
    meta:
    architecture: x86_64
    hw_disk_bus: scsi
    hw_rng_model: virtio
    hw_scsi_model: virtio-scsi
    hw_watchdog_action: reset
    hypervisor_type: qemu
    os_distro: cirros
    replace_frequency: never
    uuid_validity: none
    provided_until: none
    tags: []
    versions:
    - version: '0.6.2'
    url: https://github.com/cirros-dev/cirros/releases/download/0.6.2/cirros-0.6.2-x86_64-disk.img
    checksum: "sha256:07e44a73e54c94d988028515403c1ed762055e01b83a767edf3c2b387f78ce00"
    build_date: 2023-05-30
    - version: '0.6.3'
    url: https://github.com/cirros-dev/cirros/releases/download/0.6.3/cirros-0.6.3-x86_64-disk.img
    checksum: "sha256:7d6355852aeb6dbcd191bcda7cd74f1536cfe5cbf8a10495a7283a8396e4b75b"
    build_date: 2024-09-26
    +
  4. +
  5. +

    Run the OpenStack Image Manager. It is assumed that a profile with the name openstack exists in the +clouds.yaml.

    +
    openstack-image-manager --cloud openstack --filter ".*Cirr.*" --images images/
    +
  6. +
+

Image definitions

+

The configuration consists of different parameter settings, such as values for +minimum RAM or the visibility of the image. Have a look at the examples below +for all parameters. After a change to the configuration, validate it with +tox -- --dry-run.

+

SCS image standard

+
    +
  • The value of login is stored as image_original_user in the metadata of an image.
  • +
  • If image_description is not set as meta information, image_description is set to the name of the image.
  • +
  • The value of build_date of a specific version of an image is stored as image_build_date in the metadata of an image.
  • +
  • The value of url of a specific version of an image is stored as image_source in the metadata of an image.
  • +
+

Image with regular rebuilds

+

This type of image definition is used for images that are rebuilt at regular +intervals. For example, this is the case for the daily builds of the Ubuntu +images.

+

The attribute multi: true is set.

+

With this type of image definition, the version of the distribution (or product, +whatever is contained in the image) used is already in the name of the image +definition. The version properties from the definition's versions list +are appended only to older iterations of the image as timestamp suffixes +in parentheses upon each rotation (except for the latest entry).

+
images:
- name: Ubuntu 24.04
format: qcow2
login: ubuntu
min_disk: 8
min_ram: 512
status: active
visibility: public
multi: true
meta:
architecture: x86_64
hw_disk_bus: scsi
hw_scsi_model: virtio-scsi
hw_watchdog_action: reset
os_distro: ubuntu
os_version: '24.04'
tags: []
versions:
- version: '20240416'
url: https://cloud-images.ubuntu.com/noble/20240416/noble-server-cloudimg-amd64.img
- version: '20240422'
url: https://cloud-images.ubuntu.com/noble/20240422/noble-server-cloudimg-amd64.img
+

This configuration creates the following images:

+
    +
  • Ubuntu 24.04 (20240416)
  • +
  • Ubuntu 24.04
  • +
+

If a newer build is added, the following rotation takes place:

+
    +
  • Ubuntu 24.04 (20240416) does not change
  • +
  • Ubuntu 24.04 becomes Ubuntu 24.04 (20240422)
  • +
  • the new image becomes Ubuntu 24.04
  • +
+

By default the last three images will be visible. When a fourth image is added, the visibility of +the last image in the list is changed to community and the image can be deleted in the future.

+

Image without regular rebuild

+

This type of image definition is used for images that are not rebuilt. For example, +this is the case for the flatcar images. For each release of Flatcar there is exactly +one image which will not be rebuilt in the future.

+

The attribute multi: false is set.

+

With this type of image definition, the version of the distribution (or product, +whatever is contained in the image) used is not in the name of the image definition. +Instead, the version properties from the image definition's versions list +are appended as static version suffixes to the images' names.

+
images:
- name: RancherOS
format: qcow2
login: rancher
min_disk: 8
min_ram: 2048
status: active
visibility: public
multi: false
meta:
architecture: x86_64
hw_disk_bus: scsi
hw_scsi_model: virtio-scsi
hw_watchdog_action: reset
tags: []
versions:
- version: '1.3.0'
url: https://github.com/rancher/os/releases/download/v1.3.0/rancheros-openstack.img
- version: '1.4.0'
url: https://github.com/rancher/os/releases/download/v1.4.0/rancheros-openstack.img
- version: '1.4.1'
url: https://github.com/rancher/os/releases/download/v1.4.1/rancheros-openstack.img
+

This configuration creates the following images:

+
    +
  • RancherOS 1.3.0
  • +
  • RancherOS 1.4.0
  • +
  • RancherOS 1.4.1
  • +
+

If a new version is added, no rotation takes place. The new version is added +as RancherOS x.y.z. Here also the visibility of older images is not changed.

+

Other properties

+

Image properties

+
    +
  • Removal of properties is not yet possible
  • +
  • URL, name and format can not be changed
  • +
  • Any keys can be added to meta, these will be added to the image
  • +
  • Existing keys in meta can be changed, the same applies to min_disk +and min_ram
  • +
+

Image tags

+

image status

+
    +
  • deactivation: change status to deactivated
  • +
  • reactivation: change status to active
  • +
+

Image visibility

+

A full documentation about the visibility of images can be found in the Image visibility section in the +OpenStack Image Service API Documentation.

+
    +
  • public: set visibility to public
  • +
  • community: set visibility to community
  • +
  • shared: set visibility to shared
  • +
  • private: set visibility to private
  • +
+

Usage

+

Mirroring images

+

Since the upstreams often only keep their images for a short time, we mirror most of the images on REGIO.cloud. +This makes us independent of the availability of the images in the individual upstreams.

+

Updating images

+

Some of the images are automatically updated by a CI job. The latest available build at the time of the CI job execution is mirrored and +made available as the current version.

+

Currently, the following images are updated once a week (every Sunday at 0 am):

+
    +
  • Almalinux
  • +
  • CentOS
  • +
  • Debian
  • +
  • Rockylinux
  • +
  • Ubuntu
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update/index.html b/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update/index.html new file mode 100644 index 0000000000..a69fbbc997 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update/index.html @@ -0,0 +1,46 @@ + + + + + +Image Manager update.py | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Image Manager update.py

+

Overview

+

The OpenStack Image Manager update.py Script updates the /etc/images/*.yaml files to the always latest release of the distributions, set S3 mirror URLs and uploads the images to the mirror.

+

These updated yaml files are later processed by the Image Manger itself.

+

Installation

+

Prepare to use the update.py script.

+
git clone https://github.com/osism/openstack-image-manager/
cd openstack-image-manager
pipenv install
pipenv shell
+

Usage

+
python contrib/update.py --help

Usage: update.py [OPTIONS]

╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --debug Enable debug logging │
│ --dry-run Do not perform any changes │
│ --minio-access-key TEXT Minio access key [env var: MINIO_ACCESS_KEY] [default: None] │
│ --minio-secret-key TEXT Minio secret key [env var: MINIO_SECRET_KEY] [default: None] │
│ --minio-server TEXT Minio server [env var: MINIO_SERVER] [default: swift.services.a.regiocloud.tech] │
│ --minio-bucket TEXT Minio bucket [env var: MINIO_BUCKET] [default: openstack-images] │
│ --swift-prefix TEXT Swift prefix [env var: SWIFT_PREFIX] [default: swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/] │
│ --install-completion Install completion for the current shell. │
│ --show-completion Show completion for the current shell, to copy it or customize the installation. │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+
note
    +
  • At this time the update.py expects all yaml files at /etc/images/, which can't be configured at the moment.
  • +
  • Mirroring can't be disabled at the moment.
  • +
+

Best run this script by cron or a CI job, to update all distribution files periodically to the latest release and afterwards run Openstack Image Manager. +The distribution image yaml files must exist before running the script, you can use the files from the Github repo at etc/images/ as template for your first run.

+
$ python contrib/update.py
2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/centos.yml
2024-04-24 09:29:44 | INFO | update_image:179 - Checking image CentOS Stream 9
2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-HEREBE\d+\.\dDRAGONS.x86_64.qcow2
2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cloud.centos.org/centos/9-stream/x86_64/images/CHECKSUM
2024-04-24 09:29:44 | INFO | get_latest_default:62 - Latest URL is now https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2
2024-04-24 09:29:44 | INFO | get_latest_default:63 - Latest filename is now CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2
2024-04-24 09:29:44 | INFO | update_image:192 - Checksum of current CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337
2024-04-24 09:29:44 | INFO | update_image:208 - Our checksum is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337
2024-04-24 09:29:44 | INFO | update_image:211 - Image CentOS Stream 9 is up-to-date, nothing to do
2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/debian.yml
2024-04-24 09:29:44 | INFO | update_image:179 - Checking image Debian 11
2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bullseye/latest/debian-11-genericcloud-amd64.raw
2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bullseye/latest/SHA512SUMS
2024-04-24 09:29:45 | INFO | update_image:192 - Checksum of current debian-11-genericcloud-amd64-20240211-1654.raw is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4
2024-04-24 09:29:45 | INFO | update_image:208 - Our checksum is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4
2024-04-24 09:29:45 | INFO | update_image:211 - Image Debian 11 is up-to-date, nothing to do
2024-04-24 09:29:45 | INFO | update_image:179 - Checking image Debian 12
2024-04-24 09:29:45 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.raw
2024-04-24 09:29:45 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS
2024-04-24 09:29:46 | INFO | update_image:192 - Checksum of current debian-12-genericcloud-amd64-daily-20240424-1727.raw is sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e
2024-04-24 09:29:46 | INFO | update_image:208 - Our checksum is sha512:5401f8c6361bb2a82c2c24b4b4606d95e77229152a80e61f9c613bc88e25de9257057d0ed68b0256b745c4059162a54970fe4a8daf456b2eb67b4f5db5c97fcc
2024-04-24 09:29:46 | INFO | update_image:229 - New values are {'version': '20240424', 'build_date': datetime.date(2024, 4, 24), 'checksum': 'sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e', 'url': 'https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240424-1727/debian-12-genericcloud-amd64-daily-20240424-1727.raw'}
2024-04-24 09:29:46 | INFO | main:300 - Processing file /etc/images/rockylinux.yml
2024-04-24 09:29:46 | INFO | update_image:179 - Checking image Rocky 9
2024-04-24 09:29:46 | INFO | update_image:182 - Latest download URL is https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2
2024-04-24 09:29:46 | INFO | update_image:185 - Getting checksums from https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2.CHECKSUM
2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current Rocky-9-GenericCloud.latest.x86_64.qcow2 is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651
2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651
2024-04-24 09:29:47 | INFO | update_image:211 - Image Rocky_9 is up-to-date, nothing to do
2024-04-24 09:29:47 | INFO | main:300 - Processing file /etc/images/ubuntu.yml
2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04
2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS
2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current jammy-server-cloudimg-amd64.img is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710
2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710
2024-04-24 09:29:47 | INFO | update_image:211 - Image Ubuntu_22.04 is up-to-date, nothing to do
2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04 Minimal
2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64.img
2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/minimal/releases/jammy/release/SHA256SUMS
2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current ubuntu-22.04-minimal-cloudimg-amd64.img is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65
2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65
2024-04-24 09:29:48 | INFO | update_image:211 - Image Ubuntu 22.04 Minimal is up-to-date, nothing to do
2024-04-24 09:29:48 | INFO | update_image:179 - Checking image Ubuntu 24.04
2024-04-24 09:29:48 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
2024-04-24 09:29:48 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/noble/current/SHA256SUMS
2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current noble-server-cloudimg-amd64.img is sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3
2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:d7ba8d5d1d073f2dc8351973bf4f35157c846a0ea6ee16fb2a9f45a78953e4a7
2024-04-24 09:29:48 | INFO | update_image:229 - New values are {'version': '20240423', 'build_date': datetime.date(2024, 4, 23), 'checksum': 'sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3', 'url': 'https://cloud-images.ubuntu.com/noble/20240423/noble-server-cloudimg-amd64.img'}
+

These yaml files are now extended with additional fields and the update.py will take care of the versions, checksum, url and build date to the latest release in the yaml file on every run.

+
    +
  • latest_checksum_url - URL of the distros checksum file
  • +
  • latest_url - URL of the distros latest image
  • +
  • mirror_url - URL of the Image File at the local S3 Mirror
  • +
+
someexample.yaml
---
images:
- name: Debian 12
enable: true
shortname: debian-12
format: qcow2
login: debian
min_disk: 8
min_ram: 512
status: active
visibility: public
multi: true
meta:
architecture: x86_64
hw_disk_bus: scsi
hw_rng_model: virtio
hw_scsi_model: virtio-scsi
hw_watchdog_action: reset
hypervisor_type: qemu
os_distro: debian
os_version: '12'
replace_frequency: quarterly
uuid_validity: last-3
provided_until: none
tags: []
latest_checksum_url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS
latest_url:
https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.qcow2
versions:
- build_date: 2024-04-11
checksum:
sha512:3d6f26616e2c8b705993ddef874232887cebe42f1e70fcc020827ac88e8990177d537d34538c71ae2afd3b8baca953fff71eaa7ef71e752e82532c93dcdca436
url:
https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240411-1714/debian-12-genericcloud-amd64-daily-20240411-1714.qcow2
mirror_url:
https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-images/debian-12/20240411-debian-12.qcow2
version: '20240411'

+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/index.html b/docs/iaas/guides/operations-guide/openstack/tools/index.html new file mode 100644 index 0000000000..9d5e3c35e9 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/index.html @@ -0,0 +1,24 @@ + + + + + +Tools | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor/index.html b/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor/index.html new file mode 100644 index 0000000000..c08a9f2b24 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor/index.html @@ -0,0 +1,306 @@ + + + + + +Setting up OpenStack health monitor on Debian | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Setting up OpenStack health monitor on Debian

+

Kurt Garloff, 2024-02-20

+

Intro

+

The development of openstack-health-monitor was done on openSUSE 15.x images, just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution.

+

Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here.

+

Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a successor project for the increasingly hard to maintain shell code, this may not be worth the trouble.

+

openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested. +The scenario is described in a bit more detail in the repository's README.md file.

+

The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the monitoring section of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up.

+

Setting up the driver VM

+

So we start a Debian 12 image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard; +the instructions use flavor names and image names from the SCS standards. +For many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack).

+

Internal vs external monitoring

+

There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor.

+

The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems.

+

Unprivileged operation

+

Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own.

+

If openstack availability zone list --compute fails for you without admin rights, please fix your openstack client, e.g. by applying the patch I mentioned in this issue. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Health-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)

+

Driver VM via openstack CLI

+

The author prefers to setup the VM via openstack CLI tooling. He has working entries for all clouds he uses in his ~/.config/openstack/clouds.yaml and secure.yaml and has exported the OS_CLOUD environment variable to point to the cloud he is working on to set up the driver VM. The author uses the bash shell. All of this of course could be scripted.

+

So here we go

+
    +
  1. Create the network setup for a VM in a network oshm-network with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network.
  2. +
+
PUBLIC=$(openstack network list --external -f value -c Name)
openstack router create oshm-router
openstack router set --external-gateway $PUBLIC oshm-driver-router
openstack network create oshm-network
openstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet
openstack router add subnet oshm-router oshm-subnet
+
    +
  1. Create a security group that allows ssh and ping access
  2. +
+
openstack security group create sshping
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping
openstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping
+
    +
  1. Being at it, we also create the security group for grafana
  2. +
+
openstack security group create grafana
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana
+
    +
  1. To connect to the VM via ssh later, we create an SSH keypair
  2. +
+
openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key
chmod og-r ~/.ssh/oshm-key.pem
+

Rather than creating a new key (and storing and protecting the private key), we could have passed --public-key and used an existing keypair.

+
    +
  1. Look up Debian 12 image UUID.
  2. +
+
IMGUUID=$(openstack image list --name "Debian 12" -f value -c ID | tr -d '\r')
echo $IMGUUID
+

Sidenote: The tr command is there to handle broken tooling that embeds a trailing \r in the output.

+
    +
  1. Boot the driver VM
  2. +
+
openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver
+

Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing --block-device. See diskless flavor blog article. For flavors with local root disks, you could have used the --image $IMGUUID parameter instead.

+
    +
  1. Wait for it to boot (optional) +You can look at the boot log with openstack console log show oshm-driver or connect to it via VNC at the URL given by openstack console url show oshm-driver. You can of course also query openstack on the status openstack server list or openstack server show oshm-driver. You can also just create a simple loop:
  2. +
+
declare -i ctr=0 RC=0
while [ $ctr -le 120 ]; do
STATUS="$(openstack server list --name oshm-driver -f value -c Status)"
if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi
if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi
if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi
sleep 2
let ctr+=1
done
# return $RC
if [ $RC != 0 ]; then false; fi
+
    +
  1. Attach a floating IP so it's reachable from the outside.
  2. +
+
FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks |  sed "s@^[^:]*:[^']*'\([0-9\.]*\)'.*\$@\1@")
FIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)
echo $FIXEDIP $FIXEDPORT
openstack floating ip create --port $FIXEDPORT $PUBLIC
FLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")
echo "Floating IP: $FLOATINGIP"
+

Remember this floating IP address.

+
    +
  1. Connect to it via ssh
  2. +
+
ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP
+

On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)

+

All the following commands are performed on the newly started driver VM.

+

Configuring openstack CLI on the driver VM

+

We need to install the openstack client utilities.

+
sudo apt-get update
sudo apt-get install python3-openstackclient
sudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient
+

Configure your cloud access in ~/.config/openstack/clouds.yaml

+
clouds:
CLOUDNAME:
interface: public
identity-api-version: 3
#region_name: REGION
auth:
auth_url: KEYSTONE_ENDPOINT
project_id: PROJECT_UUID
#alternatively project_name and project_domain_name
user_domain_name: default
# change to your real domain
+

and secure.yaml (in the same directory)

+
clouds:
CLOUDNAME:
auth:
username: USERNAME
password: PASSWORD
+

The CLOUDNAME can be freely chosen. This is the value passed to the openstack CLI with --os-cloud or exported to your environment in OS_CLOUD. The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample clouds.yaml file that works (but lacks the password).

+

Protect your secure.yaml from being read by others: chmod 0600 ~/.config/openstack/secure.yaml.

+

If you are using application credentials instead of username, password to authenticate, you don't need to specify project_id nor project's nor user's domain names in clouds.yaml. Just (in secure.yaml):

+
clouds:
CLOUDNAME:
auth_type: v3applicationcredential
auth:
application_credential_id: APPCRED_ID
application_credential_secret: "APPCRED_SECRET"
+

Configure this to be your default cloud:

+
export OS_CLOUD=CLOUDNAME
+

You might consider adding this to your ~/.bashrc for convenience. Being at it, you might want to add export CLIFF_FIT_WIDTH=1 there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste).

+

Verify that your openstack CLI works:

+
openstack catalog list
openstack server list
+

You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases.

+

Custom CA

+

If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in /etc/ssl/certs/ca-certificates.crt. You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the debian user.

+

Add it to your clouds.yaml

+
clouds:
CLOUDNAME:
cacert: /PATH/TO/CACERT.CRT
[...]
+

If you want to allow api_monitor.sh to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:

+
export OS_CACERT=/PATH/TO/CACERT.CRT
+

Consider adding this to your ~/.bashrc as well.

+

Your first api_monitor.sh iteration

+

Checkout openstack-health-monitor:

+
sudo apt-get install git bc jq netcat-traditional tmux zstd
git clone https://github.com/SovereignCloudStack/openstack-health-monitor
cd openstack-health-monitor
+

You may want to start a tmux (or screen) session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect.

+

The script api_monitor.sh is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the README.md file.

+

It is good practice to use tmux. This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to screen over tmux.

+

You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:

+
export IMG="Debian 12"
export JHIMG="Debian 12"
./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1
+

Leave out the -LL if you don't have a working loadbalancer service or replace -LL with -LO if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources).

+

Feel free to study the meaning of all the command line parameters by looking at the README.md. (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)

+

This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs DOWN, BUILD, creating are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual openstack RESOURCE list and openstack RESOURCE show NAME and RESOURCE being something like router, network, subnet, port, volume, server, floating ip, loadbalancer, loadbalancer pool, loadbalancer listener, security group, keypair, image, ...)

+

The api_monitor.sh uses and APIMonitor_TIMESTAMP prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong. +TIMESTAMP is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time).

+

This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least -N 2 to test the ability of the router to route traffic between networks. So expect -n 6 to become -N 2 -n 6 for a very small single-AZ cloud or -n 12 for a large 3 AZ cloud region. So, re-run the api_monitor.sh with the target sizing.

+

Resource impact and charging

+

Note that api_monitor.sh uses small flavors (SCS-1V-2 for the N jump hosts and SCS-1L-1 for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors.

+

If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run api_monitor.sh in a loop (which you will) with say 10 VMs (e.g. -N 2 -n 8) in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference.

+

Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of openstack volume list, openstack volume show BROKEN_VOLUME, openstack loadbalancer list, openstack loadbalancer show BROKEN_LB.)

+

Using -w -1 makes api_monitor.sh wait for interactive input whenever an error occurs; this can be convenient for debugging.

+

Once you have single iterations working nicely, we can proceed.

+

Automating startup and cleanup

+

Typically, we run api_monitor.sh with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here.

+
#!/bin/bash
# run_CLOUDNAME.sh
# Do some global settings
export IMG="Debian 12"
export JHIMG="Debian 12"
#export OS_CACERT=/home/debian/ca-certificates.pem
# Additional settings to override flavors or to
# configure email addresses for sending alarms can be set here

# Does openstack CLI work?
openstack server list >/dev/null || exit 1
# Upload log files to this swift container (which you need to create)
#export SWIFTCONTAINER=OS-HM-Logfiles

# CLEANUP
echo "Finding resources from previous runs to clean up ..."
# Find Floating IPs
FIPLIST=""
FIPS=$(openstack floating ip list -f value -c ID)
for fip in $FIPS; do
FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")
if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_
"; fi
done
FIPLIST=$(echo "$FIPLIST" | grep -v '^$' | sort -u)
# Cleanup previous interrupted runs
SERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)
KEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)
VOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)
NETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)
LOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)
ROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)
SECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)
echo CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS
for ENV in $FIPLIST; do
echo "******************************"
echo "CLEAN $ENV"
bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV
echo "******************************"
done
TOCLEAN=$(echo "$SERVERS
$KEYPAIR
$VOLUMES
$NETWORK
$LOADBAL
$ROUTERS
$SECGRPS
" | grep -v '^$' | sort -u)
for ENV in $TOCLEAN; do
echo "******************************"
echo "CLEAN $ENV"
bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV
echo "******************************"
done

# Now run the monitor
#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"
exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"
+

Compared to the previous run, we have explicitly set two networks here -N 2 and rely on the iterations being passed in as command line arguments. Add parameter -t if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (-LO) in this example rather than the amphora based one (-LL).

+

You may use one of the existing run_XXXX.sh scripts as example. Beware: eMail alerting with ALARM_EMAIL_ADDRESS and NOTE_EMAIL_ADDRESS (and limiting with -a and -R ) and reporting data to telegraf (option -S) may be present in the samples. Make this script executable (chmod +x run_CLOUDNAME.sh).

+

We wrap a loop around this in run_in_loop.sh:

+
#!/bin/bash
# run_in_loop.sh
rm stop-os-hm 2>/dev/null
while true; do
./run_CLOUDNAME.sh -i 200
if test -e stop-os-hm; then break; fi
echo -n "Hit ^C to abort ..."
sleep 15; echo
done
+

Also make this executable (chmod +x run_in_loop.sh). +To run this automatically in a tmux window whenever the system starts, we follow the steps in the startup README.md

+

Change OS_CLOUD in startup/run-apimon-in-tmux.sh. (If you need to set OS_CACERT, also add it in this file and pass it into the windows.)

+

Activate everything:

+
mkdir -p ~/.config/systemd/user/
cp -p startup/apimon.service ~/.config/systemd/user/
systemctl --user enable apimon
systemctl --user start apimon
sudo loginctl enable-linger debian
tmux attach -t oshealthmon
+

This assumes that you are using the user debian for this monitoring and have checked out the repository at ~/openstack-health-monitor/. Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)

+

Changing parameters and restarting

+

If you want to change the parameters passed to api_monitor.sh, you best do this by editing run_CLOUDNAME.sh, potentially after testing it with one iteration before.

+

To make the change effective, you can wait until the current 200 iterations are completed and the run_in_loop.sh calls run_CLOUDNAME.sh again. You can also hit ^C in the tmux window that hasapi_monitor.sh running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ^C during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ^C twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ./run_in_loop.sh again.

+

You can also issue the systemctl --user stop apimon command; it will basically do the same thing: Send ^C and then wait for everything to be completed and tear down the tmux session. +After waiting for that to complete, you can start it again with systemctl --user start apimon.

+

Multiple instances

+

You can run multiple instances of api_monitor.sh on the same driver VM. In this case, you should rename run_in_loop.sh to e.g. run_in_loop_CLOUDNAME1.sh and call run_CLOUDNAME1.sh from there. Don't forget to adjust startup/run-apimon-in-tmux.sh and startup/kill-apimon-in-tmux.sh to start more windows.

+

It is not recommended to run multiple instances against the same OpenStack project however. While the api_monitor.sh script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the run_CLOUDNAME.sh script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations.

+

Alarming and Logs

+

eMail

+

If wanted, the api_monitor.sh can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the -a N and -R options. In order to enable sending emails from the driver VM, it needs to have postfix (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly.

+

Once you have configured postfix, you can enable eMail notifications using the option -e. Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ALARM_EMAIL_ADDRESSES and NOTE_EMAIL_ADDRESSES environment variables to api_monitor.sh, e.g. by setting it in the run_CLOUDNAME.sh.

+

Log files

+

api_monitor.sh writes a log file with the name APIMonitor_TIMESTAMP.log. It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (TIMESTAMP is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)

+

Note that api_monitor.sh does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties.

+

The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable SWIFTCONTAINER has been set (in run_COULDNAME.sh) when starting api_monitor.sh. the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER

+

After the 200 iterations, a .psv file (pipe-separated values) is created Stats.STARTTIME-ENDTIME.psv (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured).

+

Data collection and dashboard

+

See https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md

+

Telegraf

+

To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:

+
sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key
echo "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list
sudo apt update
sudo apt -y install telegraf
+

In the config file /etc/telegraf/telegraf.conf, we enable

+
[[inputs.influxdb_listener]]
service_address = ":8186"

[[outputs.influxdb]]
urls = ["http://127.0.0.1:8086"]
+

and restart the service (sudo systemctl restart telegraf). +Enable it on system startup: sudo systemctl enable telegraf.

+

InfluxDB

+

We proceed to influxdb:

+
sudo apt-get install influxdb
+

In the configuration file /etc/influxdb/influxdb.conf, ensure that the http interface on port 8086 is enabled.

+
[http]
enabled = true
bind-address = ":8086"
+

Restart influxdb as needed with sudo systemctl restart influxdb. +Also enable it on system startup: sudo systemctl enable influxdb.

+

Add -S CLOUDNAME to your run_CLOUDNAME.sh script

+

You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter -S CLOUDNAME to the api_monitor.sh call in run_CLOUDNAME.sh. Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete).

+

Caddy (Reverse Proxy)

+

We're going to deploy Grafana behind Caddy as a reverse proxy. +Caddy is very easy to configure, comes with sensible defaults and can automatically provision TLS +certificates using Let's Encrypt.

+

Install Caddy

+

We follow https://caddyserver.com/docs/install#debian-ubuntu-raspbian to setup the stable APT repository:

+
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
+

And install Caddy:

+
sudo apt update
sudo apt install caddy
+

Ensure it's started and starts at boot with sudo systemctl enable --now caddy.

+

Allow HTTP traffic for oshm-driver

+

Caddy needs TCP port 80 opened to be able to process the Let's Encrypt HTTP challenge, so let's +configure an appropriate security group for oshm-driver:

+
openstack security group create http
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 80 http
openstack server add security group oshm-driver http
+

Configure Caddy

+

Create a file /etc/caddy/Caddyfile with the following contents:

+
https://health.YOURCLOUD.osba.sovereignit.cloud:3000 {
reverse_proxy localhost:3003
}
+

Replace health.YOURCLOUD.osba.sovereignit.cloud with your actual domain. +You can use a hostname of your liking, but Caddy will create TLS certificates for this host using +the HTTP challenge. +The sovereignit.cloud domain is controlled by the SCS project team and has been used for a number +of health mon instances.

+

Reload Caddy with sudo systemctl reload caddy. That's it.

+

You should now be able to access https://health.YOURCLOUD.sovereignit.cloud:3000 and see a proxy error +page because the Grafana service is not yet running (this is our next step). +The very first request will be a bit slower, because Caddy interacts with Let's Encrypt API to create +the TLS certificate behind the scenes.

+

Caddy logs can be accessed with sudo journalctl -u caddy.

+

Grafana

+

Install Grafana

+

We follow https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/ and setup the stable APT repository:

+
mkdir -p /etc/apt/keyrings
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
+

And install it:

+
sudo apt update
sudo apt -y install grafana
+

Basic config

+

The config file /etc/grafana/grafana.ini needs some adjustments.

+

We're going to deploy Grafana behind a reverse proxy (Caddy) and configure it as such.

+

Therefore, in the [server] section:

+
[server]
protocol = http
http_addr = 127.0.0.1
http_port = 3003
domain = health.YOURCLOUD.sovereignit.cloud
root_url = https://%(domain)s:3000/
+

Please replace health.YOURCLOUD.sovereignit.cloud with your actual domain.

+

Next, in the [security] section, set:

+
[security]
admin_user = admin
admin_password = SOME_SECRET_PASS
secret_key = SOME_SECRET_KEY
data_source_proxy_whitelist = localhost:8088 localhost:8086
cookie_secure = true
+

Please replace SOME_SECRET_PASS and SOME_SECRET_KEY with secure passwords (for example, you can use pwgen -s 20).

+

Finally, in the [users] section, set:

+
[users]
allow_sign_up = false
allow_org_create = false
+

The configuration file contains secrets and should be protected such that only root and group grafana +can read it:

+
sudo chown root:grafana /etc/grafana/grafana.ini
sudo chmod 0640 /etc/grafana/grafana.ini
+

We do the OIDC connection in the section [auth.github] later.

+

We can now restart the service: sudo systemctl restart grafana-server. +Being at it, also enable it on system startup: sudo systemctl enable grafana-server.

+

You should now be able to access your dashboard on https://health.YOURCLOUD.sovereignit.cloud:3000 and log in +via the configured username admin and your SOME_SECRET_PASS password.

+

Enable influx database in grafana

+

In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to http://localhost:8086 (despite this being the suggestion). Set the database name to telegraf. Save&test should succeed.

+

Importing the dashboard

+

Go to Home, Dashboards, New, Import. +Upload the dashboard .json file from the repository, user the Grafana-10 variant if you use Grafana 10 or newer.

+

In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.) +Save.

+

Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable).

+

No data displayed?

+

Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.

+

One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved.

+

Dashboard features

+

Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended.

+

The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously.

+

You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term.

+

GitHub OIDC Integration

+

The SCS providers do allow all GitHub users that belong to the SovereignCloudStack organization to get Viewer +access to the dashboards. +This allows to exchange experience and to get a feeling for the achievable stability. +(Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)

+

OIDC integration is achieved by adjusting the [auth.github] section in /etc/grafana/grafana.ini as follows:

+
[auth.github]
enabled = true
client_id = YOUR_CLIENT_ID
client_secret = YOUR_CLIENT_SECRET
allowed_organizations = ["SovereignCloudStack"]
role_attribute_path = "'Viewer'"
allow_assign_grafana_admin = false
skip_org_role_sync = true
+

This config maps all users to the Viewer role regardless of their role in the GitHub Org. +Please replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with the OAuth2 credentials that the SCS Org GitHub admins +provided to you. +Finally, don't forgot to restart Grafana with sudo systemctl restart grafana-server after adjusting the config.

+

More information can be found in the Grafana documentation for GitHub OAuth2.

+

Maintenance

+

The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained.

+

Unattended upgrades

+

It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See https://wiki.debian.org/UnattendedUpgrades. If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and Caddy/Grafana (port 3000).

+

If you use unattended-upgrades, you should review your settings in /etc/apt/apt.conf.d/50unattended-upgrades, +especially Unattended-Upgrade::Origins-Pattern. It controls which packages are upgraded. If you want Caddy to be +part of the automated updates, add an entry like the following:

+
Unattended-Upgrade::Origins-Pattern {
// ...
"origin=cloudsmith/caddy/stable";
};
+

(This corresponds to o=cloudsmith/caddy/stable in the output of apt-cache policy).

+

sshd setup

+

If you already use SSH keys to sign in to the driver VM, consider setting the following in your /etc/ssh/sshd_config +if not already set:

+
PasswordAuthentication no
+

Debian's openssh-server, by default, is also very open about its version, so you might consider disabling this via:

+
DebianBanner no
+

Updating openstack-health-monitor

+

You can just do a git update in the openstack-health-monitor directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ^C, see above in the restart section.

+

Backup

+

The system holds two things that you might consider valuable for long-term storage: +(1) The log files. These are compressed and uploaded to object storage if you enable the SWIFTCONTAINER setting, which probably means that these do not need any additional backing up then. +(2) The influx time series data. Back up the data in /var/lib/influxdb.

+

Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, clouds.yaml, etc. Be careful not to expose sensitive data by granting too generous access to your backed up files.

+

Troubleshooting

+

Debugging issues

+

In case there is trouble with your cloud, the normal course of action to analyze is as follows:

+
    +
  • Look at the dashboard (see above)
  • +
  • Connect to the driver VM and attach to the tmux session and look at the console output of api_monitor.sh
  • +
  • Analyze the logfile (locally on the driver VM or grab it from the object storage)
  • +
+

Analyzing failures

+

When VM instances are created successfully, but then end up in ERROR state, the api_monitor.sh does an explicit openstack server show, so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files.

+

Sometimes the VMs end up being ACTIVE as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail.

+

To gather more details, you can look at the console output openstack console log show VM (where VM is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ssh -i APIMonitor_XXXXX_JH.pem debian@FIP, whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP. Replace XXXXX with the number in your current APIMonitor prefix, FIP with the floating IP address of the responsible JumpHost and debian with the user name used by the images you boot. Use 223 to connect to the second VM in the network, 224 the third etc.

+

When logged in, look at /var/log/cloud-init-output.log and /var/log/cloud-init.log. You can find the metadata in /var/lib/cloud/instance/.

+

You will not have much time to look around -- the still running api_monitor.sh script does continue and clean things up again. So you might want to suspend it with ^Z (and continue it later with fg). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the run_CLOUDNAME.sh script as it would do cleanup against the running instance, but rather copy the api_monitor.sh command line from the bottom (without the exec), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach -w -1 to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work.

+

Cleaning things up

+

If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard).

+

There are a few things that may need support from a cloud admin:

+
    +
  • Volumes may end up permanently in a deleting or reserved state or may be in-use, attached to a VM that has long gone. The admin needs to set the state to error and then delete them.
  • +
  • Loadbalancers may end up in a PENDING_XXX state (XXX being CREATE, UPDATE or DELETE) without ever changing. This also needs the cloud admin to set the status to ERROR, so it can be cleaned up. amphorae are more prone to this than ovn LBs.
  • +
+

More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted.

+

The source of this document can be found in the SovereignCloudStack/openstack-health-monitor repository.

+

Author: SCS Community, License: CC by Attribution 4.0 International

+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/project-manager/index.html b/docs/iaas/guides/operations-guide/openstack/tools/project-manager/index.html new file mode 100644 index 0000000000..235d16516d --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/project-manager/index.html @@ -0,0 +1,87 @@ + + + + + +Project Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Project Manager

+

Overview

+

The OpenStack Project Manager manages the creation of Openstack Domains, Projects and Users.

+

Installation

+

Prepare to use the Openstack Project Manager.

+

During installation, ldap libraries are required under Linux; you should install libldap2-dev and libsasl2-dev beforehand.

+
git clone https://github.com/osism/openstack-project-manager
cd openstack-project-manager
pipenv install
pipenv shell
+

Defaults

+

create.py

+

The create.py command and his default options while executing the command.

+
 --admin-domain              default
--assign-admin-user true
--cloud admin
--create-admin-user true
--create-domain false
--create-user false
--domain-name-prefix true
--has-service-network false
--has-public-network true
--has-shared-images true
--internal-id unset
--random false
--managed-network-resources false
--name sandbox
--owner unset
--password unset
--password-length 16
--public-network public
--quota-class basic
--service-network-cidr unset
--quota-multiplier 1
--quota-multiplier-compute unset
--quota-multiplier-network unset
--quota-multiplier-storage unset
--quota-router 1
+

manage.py

+

The manage.py has also some defaults while executing and will touch all projects in your Openstack Cluster, if not --domain is used.

+
 --admin-domain        default
--assign-admin-user false
--classes etc/classes.yml
--domain unset
--dry-run false
--endpoints etc/endpoints.yml
--manage-endpoints false
--manage-homeprojects false
--name unset
+

Default Openstack Roles to users are set to member and load-balancer_member at this time, the behavior can only be changed in the code.

+

Usage

+

There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Project Manager will be executed, examples are provided within the git repository.

+

The cloud profile to be used can be specified via the optional --cloud parameter. By default the cloud profile with the name admin is used. It has to be and admin account, to create and modify domains, projects, users and quotas.

+

The Openstack Project Manager essentially consists of two parts, the create.py and the manage.py, there are more scripts for handling users using ldap which needs more configuration setup.

+

create.py

+

This command is used to create and modify domains, projects, users and quotas. As default the domain is used as prefix for all projects and users created for easy alloction in Openstack.

+
note

create.py can't delete once created objects, this must be done using Openstack commands to remove a project or domain.

+
python src/create.py -h
usage: create [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--create-admin-user] [--create-domain] [--create-user]
[--domain DOMAIN] [--domain-name-prefix] [--has-public-network] [--has-service-network] [--has-shared-images] [--internal-id INTERNAL_ID] [--managed-network-resources] [--name NAME]
[--noassign-admin-user] [--nocreate-admin-user] [--nocreate-domain] [--nocreate-user] [--nodomain-name-prefix] [--nohas-public-network] [--nohas-service-network]
[--nohas-shared-images] [--nomanaged-network-resources] [--norandom] [--owner OWNER] [--password PASSWORD] [--password-length PASSWORD_LENGTH] [--public-network PUBLIC_NETWORK]
[--quota-class QUOTA_CLASS] [--quota-multiplier QUOTA_MULTIPLIER] [--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE] [--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK]
[--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE] [--quota-router QUOTA_ROUTER] [--random] [--service-network-cidr SERVICE_NETWORK_CIDR]

options:
-h, --help show this help message and exit
--admin-domain ADMIN_DOMAIN
Admin domain
--assign-admin-user Assign admin user
--cloud CLOUD Managed cloud
--config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set
is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the
command-line.
--config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the
command-line.
--create-admin-user Create admin user
--create-domain Create domain only
--create-user Create user
--domain DOMAIN Domain
--domain-name-prefix Add domain name as prefix to the project name
--has-public-network Has public network infrastructure
--has-service-network
Has service network infrastructure
--has-shared-images Has shared images
--internal-id INTERNAL_ID
Internal ID
--managed-network-resources
Manage the network resources
--name NAME Projectname
--noassign-admin-user
The inverse of --assign-admin-user
--nocreate-admin-user
The inverse of --create-admin-user
--nocreate-domain The inverse of --create-domain
--nocreate-user The inverse of --create-user
--nodomain-name-prefix
The inverse of --domain-name-prefix
--nohas-public-network
The inverse of --has-public-network
--nohas-service-network
The inverse of --has-service-network
--nohas-shared-images
The inverse of --has-shared-images
--nomanaged-network-resources
The inverse of --managed-network-resources
--norandom The inverse of --random
--owner OWNER Owner of the project
--password PASSWORD Password
--password-length PASSWORD_LENGTH
Password length
--public-network PUBLIC_NETWORK
Public network
--quota-class QUOTA_CLASS
Quota class
--quota-multiplier QUOTA_MULTIPLIER
Quota multiplier
--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE
Quota multiplier compute
--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK
Quota multiplier network
--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE
Quota multiplier storage
--quota-router QUOTA_ROUTER
Quota router
--random Generate random names
--service-network-cidr SERVICE_NETWORK_CIDR
Service network CIDR
+

Create a Domain and inital project

+

When executing the create.py command, the first time with --domain, it will create a new domain, an admin account and the first project webshop. The admin account will be created in the default Domain of Openstack and can be used for the Service Provider to manager the complete domain.

+
$ python3 src/create.py --domain democompany --name webshop
+----------------+----------------------+----------------------------------+
| name | value | id |
|----------------+----------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-webshop | 645538bf67664cfeaed32476d58f95fb |
| admin | democompany-admin | cc8d6bf7b61d4199ba5a4230c4ec6d62 |
| admin_password | qawsEdfg2d45Fsxc | |
+----------------+----------------------+----------------------------------+
+

Create a User for a project

+
$ python3 src/create.py --domain democompany --name webshopuser --create-user             
+----------+-------------------------+----------------------------------+
| name | value | id |
|----------+-------------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-webshop | 5752b6701026478f9cac122fc54eb9cb |
| user | democompany-webshopuser | ce213655559d47d7800501124fed4d02 |
| password | vEvM9vgRESdffWE2 | |
+----------+-------------------------+----------------------------------+
+

Create additional project with unlimited quota

+
$ python3 src/create.py --domain democompany --name styles --quota-class unlimited
+----------+--------------------+----------------------------------+
| name | value | id |
|----------+--------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-styles | 666097e396fd4f9392d6aa55c76d8267 |
+----------+--------------------+----------------------------------+
+

Set quotas for a project

+

All quota information must be set as a property to the Openstack project within your Openstack Cluster, if no property is set, the basic quotaclass of etc/classes.yml will be applied. +It is possible to set a quota multiplier for any project.

+

The following command you set a multiplier of 256 of the basic quota:

+
$ openstack project set --property quotamultiplier=256 democompany-webshop
+

Adjusting gigabyte quota for storage with a multiplier of 20 of the basic quota for a project:

+
$ openstack project set  --property quotamultiplier_storage=20 democompany-webshop
+

This will override the general quotamultiplier only for storage.

+

Other possible multiplier which can be set individually are: quotamultiplier_compute, quotamultiplier_network, quota_router

+

To change the quotaclass to unlimited from the etc/classes.yaml

+
$ openstack project set  --property quotaclass=unlimited democompany-webshop
+

Special project: images

+

With this special Project you can share all images uploaded into this project to all other project in your domain which has set the property has-shared-images, which is by default set. +Alsoi only the domain-admin user has access to this project, other domain users won't see this, they will find the uploaded images in their projects. +If you want your grant other domain users also access to upload some images, you need to give them access to the images Project in Openstack.

+
$ python3 src/create.py --domain democompany --name images
+---------+---------------------+----------------------------------+
| name | value | id |
|---------+---------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-images | 6d57f39aacbe485d87733865b1e79d03 |
+---------+---------------------+----------------------------------+
+

Additionally you need to add the domain and domain-admin user to the clouds.yaml, it is always named opm-domainname-admin: so the manage.py can setup permissions to the projects later on and users are able to find the images.

+
  opm-democompany-admin:
auth:
auth_url: https://keystone.my.cloud:5000/v3
username: democompany-admin
password: yourpassword
user_domain_name: Default
project_domain_name: democompany
identity_api_version: 3
+

Special project: service

+

With this special project you can share installed services, like a harbor, to all other projects in your domain. Per default, only the domain admin has access to this project.

+
$ python3 src/create.py --domain democompany --name service
+---------+---------------------+----------------------------------+
| name | value | id |
|---------+---------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-service | a5558f7338f94adea5f41858636256b5 |
+---------+---------------------+----------------------------------+
+

manage.py

+
warning

This command applies quotas, networks and routers to all projects in the Openstack Cluster, not only to those have been configured previously with the create.py or openstack project set --property commands.

+

Best is to run this command by cron, every hour to apply all pending changes, it is also possible to run this at the command line to apply changes immediately.

+
python3 src/manage.py -h
usage: manage [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--classes CLASSES] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--domain DOMAIN] [--dry-run]
[--endpoints ENDPOINTS] [--manage-endpoints] [--manage-homeprojects] [--name NAME] [--noassign-admin-user] [--nodry-run] [--nomanage-endpoints] [--nomanage-homeprojects]

options:
-h, --help show this help message and exit
--admin-domain ADMIN_DOMAIN
Admin domain
--assign-admin-user Assign admin user
--classes CLASSES Path to the classes.yml file
--cloud CLOUD Cloud name in clouds.yaml
--config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set
is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the
command-line.
--config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the
command-line.
--domain DOMAIN Domain to be managed
--dry-run Do not really do anything
--endpoints ENDPOINTS
Path to the endpoints.yml file
--manage-endpoints Manage endpoints
--manage-homeprojects
Manage home projects
--name NAME Project to be managed
--noassign-admin-user
The inverse of --assign-admin-user
--nodry-run The inverse of --dry-run
--nomanage-endpoints The inverse of --manage-endpoints
--nomanage-homeprojects
The inverse of --manage-homeprojects
+

Manage a specific domain only

+
$ python3 src/manage.py --domain democompany

2024-04-19 14:24:02.873 | INFO | democompany - domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03
2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03, domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:04.953 | INFO | democompany-images - quotaclass {'compute': {'cores': 0, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 0, 'key_pairs': 0, 'metadata_items': 128, 'ram': 0, 'server_group_members': 0, 'server_groups': 0}, 'network': {'floatingip': 0, 'network': 0, 'port': 0, 'rbac_policy': 0, 'router': 0, 'security_group': 0, 'security_group_rule': 0, 'subnet': 0, 'subnetpool': 0}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 1000, 'per_volume_gigabytes': 25, 'snapshots': 0, 'volumes': 100}, 'parent': 'default'}
2024-04-19 14:24:04.953 | INFO | democompany-images - check network quota
2024-04-19 14:24:05.048 | INFO | democompany-images - check compute quota
2024-04-19 14:24:05.175 | INFO | democompany-images - check volume quota
2024-04-19 14:24:05.286 | INFO | democompany-images - check if external rbac policy must be deleted (public)
2024-04-19 14:24:05.349 | INFO | democompany-images - check if service rbac policy must be deleted (democompany-service)
2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5
2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5, domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:06.131 | INFO | democompany-service - quotaclass {'compute': {'cores': 256, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 256, 'key_pairs': 256, 'metadata_items': 128, 'ram': 262144, 'server_group_members': 256, 'server_groups': 256}, 'network': {'floatingip': 256, 'network': 256, 'port': 256, 'rbac_policy': 1024, 'router': 256, 'security_group': 256, 'security_group_rule': 1024, 'subnet': 256, 'subnetpool': 256}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 0, 'per_volume_gigabytes': 0, 'snapshots': 0, 'volumes': 0}, 'parent': 'default'}
2024-04-19 14:24:06.131 | INFO | democompany-service - check network quota
2024-04-19 14:24:06.212 | INFO | democompany-service - check compute quota
2024-04-19 14:24:06.330 | INFO | democompany-service - check volume quota
2024-04-19 14:24:06.467 | INFO | democompany-service - check if external rbac policy must be created (public)
2024-04-19 14:24:06.589 | INFO | democompany-service - check if service rbac policy must be deleted (democompany-service)
2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb
2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb, domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:06.915 | INFO | democompany-webshop - quotaclass {'compute': {'cores': 4, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': -1, 'key_pairs': 4, 'metadata_items': 128, 'ram': 8192, 'server_group_members': 4, 'server_groups': 4}, 'network': {'floatingip': 4, 'network': 1, 'port': 20, 'rbac_policy': 10, 'router': 0, 'security_group': 5, 'security_group_rule': 20, 'subnet': 2, 'subnetpool': 1}, 'volume': {'backup_gigabytes': 40, 'backups': 8, 'gigabytes': 20, 'per_volume_gigabytes': 200, 'snapshots': 4, 'volumes': 4}, 'parent': 'default'}
2024-04-19 14:24:06.915 | INFO | democompany-webshop - check network quota
2024-04-19 14:24:06.993 | INFO | democompany-webshop - check compute quota
2024-04-19 14:24:07.114 | INFO | democompany-webshop - check volume quota
2024-04-19 14:24:07.254 | INFO | democompany-webshop - check if external rbac policy must be created (public)
2024-04-19 14:24:07.334 | INFO | democompany-webshop - check if service rbac policy must be deleted (democompany-service)
+

Config files

+

The config files which can be used for create.py and manage.py are using the oslo.config format, you can set the command line options as key = value pair and create your own config files matching your setup.

+
democompany.conf
[DEFAULT]
cloud = admin
domain = democompany
+

Quota Templates

+

Edit the etc/classes.yml file if you want to change or add new quota templates

+

Setup Endpoints

+

Edit the etc/endpoints.yml file to fit your available endpoints

+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/resource-manager/index.html b/docs/iaas/guides/operations-guide/openstack/tools/resource-manager/index.html new file mode 100644 index 0000000000..a1afffb660 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/resource-manager/index.html @@ -0,0 +1,44 @@ + + + + + +Resource Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Resource Manager

+

Preparations

+

Prepare use of the OpenStack Resource Manager.

+
git clone https://github.com/osism/openstack-resource-manager
cd openstack-resource-manager
pipenv install
pipenv shell
+

Prepare cloud profile admin in clouds.yml and secure.yml (use clouds.yml.sample and secure.yml.sample +in the openstack-resource-manager repository as sample files).

+

Nova

+

Live migration

+

Live migrate all instances from compute node SOURCE to compute node TARGET.

+
python3 src/host-action.py --yes --disable --action live-migrate --host SOURCE --input TARGET
+

Evacuation

+

Evacuate all instances from compute node SOURCE to compute node TARGET.

+
python3 src/host-action.py --yes --action evacutate --host SOURCE --input TARGET
+

Octavia

+

Amphora rotation

+

Rotation of amphorae older than 30 days.

+
$ python3 src/amphora.py --rotate
2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa is older than 30 days
2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa of loadbalancer 9008d3d7-f593-4bc3-941c-a740c178148d is rotated by a loadbalancer failover
+

Cinder

+
$ python3 src/volume.py
2023-12-11 23:09:44 | INFO | Volume ad848454-ba1f-4c28-b9a8-edada17948b0 hangs in CREATING status for more than 2 hours
Delete volume ad848454-ba1f-4c28-b9a8-edada17948b0 [yes/no]:
+

Orphans

+
$ python3 src/orphan.py
2023-12-11 23:11:16 | INFO | Checking nova / server
2023-12-11 23:11:21 | INFO | Checking neutron / port
2023-12-11 23:11:23 | INFO | Checking neutron / router
2023-12-11 23:11:23 | INFO | Checking neutron / network
2023-12-11 23:11:24 | INFO | Checking neutron / subnet
2023-12-11 23:11:24 | INFO | Checking neutron / floatingip
2023-12-11 23:11:24 | INFO | Checking neutron / rbacpolicy
2023-12-11 23:11:24 | INFO | Checking neutron / securitygroup
2023-12-11 23:11:26 | INFO | Checking neutron / securitygrouprule
2023-12-11 23:11:27 | INFO | Checking glance / image
2023-12-11 23:11:30 | INFO | Checking glance / imagemember
[...]
+---------------+-------------------+--------------------------------------+----------------------------------+
| servicename | resourcename | resource_id | project_id |
|---------------+-------------------+--------------------------------------+----------------------------------|
| neutron | port | 561f8f76-18b0-470a-92cd-4336346b4b18 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | port | 6d1986e4-1e6d-4d4a-961d-97d372945bb1 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | port | 74f9bddc-9bfa-4d06-a147-ca87127e501e | 8268b05ef24b41d8806c0fe417576610 |
| neutron | port | f630a66b-7725-4a68-868b-caebbaf1c003 | 8268b05ef24b41d8806c0fe417576610 |
| neutron | router | c0c4e4aa-53ee-4fd1-8f53-84d52cf6c60b | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | router | c8f9a13b-adcd-4a8e-942b-338bcf4dde7c | 8268b05ef24b41d8806c0fe417576610 |
| neutron | network | 62d6ad2a-0cda-4d45-9325-963b8eb67000 | 8268b05ef24b41d8806c0fe417576610 |
| neutron | network | 63b8fea6-7d7b-40c3-9c31-bee4404a92d6 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | subnet | 0cd16262-330a-44ad-9160-daef84aded2d | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | subnet | 690dee14-ac12-464d-a911-a873c27ec818 | d33b0d15fd474131a335207216297a2a |
| neutron | subnet | 854e7c55-62e2-4679-9b18-805460b998ce | 8268b05ef24b41d8806c0fe417576610 |
| neutron | rbacpolicy | 00d7c2a2-6674-4f40-9f95-176a7858fcca | c8e4393b6d064a26a31014f82939172f |
| neutron | rbacpolicy | 0608c701-5b81-4712-989b-ba03cdcc255d | c8e4393b6d064a26a31014f82939172f |
[...]
| neutron | securitygrouprule | fd3c553f-168e-4c24-ab40-09aa934bab86 | 3a96207b719643ae9ea9a81d95116e9e |
| neutron | securitygrouprule | fdf337be-971c-4d5d-88ca-d90cdb468e88 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | securitygrouprule | ff8162fe-f053-49c9-8659-078061ce3e23 | d0b0add9ede0452791f71cb900e35242 |
| glance | imagemember | c7f2cb0c25d34c5d886ecaf483e5fda6 | c7f2cb0c25d34c5d886ecaf483e5fda6 |
| glance | imagemember | d4d0a161f9024fc8b517b0375eb97c89 | d4d0a161f9024fc8b517b0375eb97c89 |
| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |
| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |
| glance | imagemember | d33b0d15fd474131a335207216297a2a | d33b0d15fd474131a335207216297a2a |
| cinder | volume | e7c4b05c-b76a-40cc-8381-03262e57eb94 | 9b5f7f8ed70d410c81e3f45bf4e36498 |
+---------------+-------------------+--------------------------------------+----------------------------------+
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager/index.html b/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager/index.html new file mode 100644 index 0000000000..44ee0941b3 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager/index.html @@ -0,0 +1,24 @@ + + + + + +Sandbox Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/simple-stress/index.html b/docs/iaas/guides/operations-guide/openstack/tools/simple-stress/index.html new file mode 100644 index 0000000000..76a0bf8e45 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/simple-stress/index.html @@ -0,0 +1,49 @@ + + + + + +Simple Stress | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Simple Stress

+

Overview

+

The OpenStack Simple Stress is a small stress test for your Openstack Cluster. You can use it for burnin tests or if you want to monitor your cluster perfomance. +It is able to start a predefined amount of Servers in specific networks in parallel and serial and removes them afterwards, so you can test your environment to the limits.

+

Installation

+

Prepare to use the Openstack Simple Stress.

+
git clone https://github.com/osism/openstack-simple-stress
cd openstack-simple-stress
pipenv install
pipenv shell
+

Defaults

+

The main.py command and the default options while executing the command.

+
 --cleanup       true
--cloud simple-stress
--compute-zone nova
--debug false
--delete true
--flavor SCS-2V-8
--floating false
--image Ubuntu 22.04
--interval 10 (seconds)
--keypair unset
--network simple-stress
--network-zone nova
--number 1
--parallel 1
--prefix simple-stress
--storage-zone simple-stress
--timeout 600 (seconds)
--volume false
--volume-number 1
--volume-size 1 (gigabyte)
--wait true
+

Usage

+

There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Simple Stress will be executed, examples are provided within the git repository.

+

The cloud profile to be used can be specified via the optional --cloud parameter. By default, the cloud profile with the name simple-stress is used.

+
$ python src/main.py -h
usage: main [-h] [--cleanup] [--cloud CLOUD] [--compute-zone COMPUTE_ZONE] [--config-dir DIR]
[--config-file PATH] [--debug] [--delete] [--flavor FLAVOR] [--floating] [--image IMAGE]
[--interval INTERVAL] [--keypair KEYPAIR] [--network NETWORK] [--network-zone NETWORK_ZONE]
[--nocleanup] [--nodebug] [--nodelete] [--nofloating] [--novolume] [--nowait]
[--number NUMBER] [--parallel PARALLEL] [--prefix PREFIX] [--storage-zone STORAGE_ZONE]
[--timeout TIMEOUT] [--volume] [--volume-number VOLUME_NUMBER] [--volume-size VOLUME_SIZE]
[--wait]

options:
-h, --help show this help message and exit
--cleanup
--cloud CLOUD Cloud name
--compute-zone COMPUTE_ZONE
Compute availability zone to use
--config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted,
so as to provide a predictable parse order if individual options are over-
ridden. The set is parsed after the file(s) specified via previous --config-
file, arguments hence over-ridden options in the directory take precedence. This
option must be set from the command-line.
--config-file PATH Path to a config file to use. Multiple config files can be specified, with
values in later files taking precedence. Defaults to None. This option must be
set from the command-line.
--debug
--delete
--flavor FLAVOR
--floating
--image IMAGE
--interval INTERVAL
--keypair KEYPAIR
--network NETWORK
--network-zone NETWORK_ZONE
Network availability zone to use
--nocleanup The inverse of --cleanup
--nodebug The inverse of --debug
--nodelete The inverse of --delete
--nofloating The inverse of --floating
--novolume The inverse of --volume
--nowait The inverse of --wait
--number NUMBER
--parallel PARALLEL
--prefix PREFIX
--storage-zone STORAGE_ZONE
Storage availability zone to use
--timeout TIMEOUT
--volume
--volume-number VOLUME_NUMBER
--volume-size VOLUME_SIZE
--wait
+

Running a small and simple test on your Openstack environment, using Ubuntu_22.04 image with the flavor of 2VCPUs and 8Gigabytes of RAM, starting 6 servers, 2 parallel each with a volume size of 20Gigabytes.

+
$ python src/main.py --network test-net --flavor SCS-2V-8 --image Ubuntu_22.04 --number 6 --parallel 2 --volume-size 20
2024-04-23 11:47:16 | INFO | Checking flavor SCS-2V-8
2024-04-23 11:47:17 | INFO | flavor.id = 926f952f-0714-4c55-92c2-7514191fecce
2024-04-23 11:47:17 | INFO | Checking image Ubuntu_22.04
2024-04-23 11:47:17 | INFO | image.id = 667649d6-e828-403b-8871-15dde7b9ce85
2024-04-23 11:47:17 | INFO | Checking network test-net
2024-04-23 11:47:18 | INFO | network.id = 9688192e-11dd-4618-a18c-99d3267f630a
2024-04-23 11:47:18 | INFO | Creating server simple-stress-0
2024-04-23 11:47:18 | INFO | Creating server simple-stress-1
2024-04-23 11:47:18 | INFO | Waiting for server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:18 | INFO | Waiting for server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:28 | INFO | Waiting for boot / test results of 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:29 | INFO | Waiting for boot / test results of e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:39 | INFO | Deleting server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:39 | INFO | Waiting for deletion of server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:39 | INFO | Deleting server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:40 | INFO | Waiting for deletion of server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:49 | INFO | Creating server simple-stress-2
2024-04-23 11:47:50 | INFO | Creating server simple-stress-3
2024-04-23 11:47:50 | INFO | Waiting for server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:47:51 | INFO | Waiting for server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:00 | INFO | Waiting for boot / test results of 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:48:01 | INFO | Waiting for boot / test results of a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:11 | INFO | Deleting server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:12 | INFO | Waiting for deletion of server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:12 | INFO | Deleting server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:48:12 | INFO | Waiting for deletion of server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:48:22 | INFO | Creating server simple-stress-4
2024-04-23 11:48:22 | INFO | Waiting for server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:22 | INFO | Creating server simple-stress-5
2024-04-23 11:48:23 | INFO | Waiting for server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:48:55 | INFO | Deleting server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:55 | INFO | Deleting server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:48:55 | INFO | Waiting for deletion of server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:55 | INFO | Waiting for deletion of server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:49:05 | INFO | Server 049bf974-b0fd-467f-aabd-3593b2a409a4 finished
2024-04-23 11:49:05 | INFO | Server e485697f-feae-458c-952d-000072374c3f finished
2024-04-23 11:49:05 | INFO | Server a098cc12-94ff-4036-bf42-4fc08287809f finished
2024-04-23 11:49:05 | INFO | Server 26595dd3-09d4-4758-8d1f-58a40b681d11 finished
2024-04-23 11:49:05 | INFO | Server 05b9f996-5a06-4359-b495-3463cc7b81e0 finished
2024-04-23 11:49:05 | INFO | Server 8d372de6-ca07-4afb-9e80-1589fd5242e8 finished
2024-04-23 11:49:05 | INFO | Runtime: 107.4460s
+

Using a config directory with configfiles to run the test.

+

Path to a config directory to pull *.conf files from. This file set is sorted, +so as to provide a predictable parse order if individual options are over-ridden. +The set is parsed after the file(s) specified via previous --config file, +arguments hence over-ridden options in the directory take precedence. This +option must be set from the command-line.

+
python src/main.py --config-dir /path/to/config-dir
+

Config files

+

The config files which can be used for main.py are using the oslo.config format, you can set the command line options as key = value pair and create your own config files matching your setup.

+
mytest.conf
[DEFAULT]
cloud = simple-stress
network = test-net
number = 6
parallel = 2
flavor = SCS-2V-8
image = Ubuntu_22.04
volume-size = 20
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/rook/index.html b/docs/iaas/guides/operations-guide/rook/index.html new file mode 100644 index 0000000000..49bc54bd1a --- /dev/null +++ b/docs/iaas/guides/operations-guide/rook/index.html @@ -0,0 +1,273 @@ + + + + + +Ceph via Rook (technical preview) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Ceph via Rook (technical preview)

+
warning

This is a technical preview and not recommended for production use yet. This whole +document has to be reworkded with more rook like handling. Do not take it for +granted yet.

+

Where to find docs

+

The official Rook documentation starts here https://rook.io/docs/rook/latest-release/Getting-Started/intro/

+

Some sections to point out are:

+ +

The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/operations/

+

It is strongly advised to use the documentation for the version being used.

+ +
note

Do not take information in the documentation at face value. +Especially when it comes to advanced/rarely used/very new features it is strongly advised +to test any claims made in the documentation about any particular feature.

Never assume that things will work as written without actually testing it on a test setup +as close to your real workload scenario as possible.

+

Advice on Ceph releases

+

The current Ceph releases and their support status can be found on https://docs.ceph.com/en/latest/releases/

+

When a new Ceph stable version is released you are strongly advised +to not roll it out on any production cluster whatsoever. +Even though its listed as "stable" it doesn't mean that this is actually true. +Especially avoid using .0 releases on anything remotely production +unless you really, really now what you're doing and can live with a possible catastrophic failure.

+

Be very conservative about what version you run on production systems.

+

Shiny new features aren't worth the risk of total or partial data loss/corruption.

+

Troubleshooting

+

Please have a look at the Rook Troubleshooting documentation.

+

The Rook toolbox is available via the ceph command on the manager node, after you deployed the wrapper via osism apply cephclient. You have to make sure the correct Configuration Options for the Rook Ceph Client Wrapper are net.

+

Monitoring

+

Dashboard

+ +

The password is stored in the secret rook-ceph-dashboard-password.

+
kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}" | base64 --decode && echo
+

Updating

+

Rook Upgrades

+

Please have a look at the Rook Upgrades documentation. Take note of update instructions specific to your version.

+

Usually you can simply update by bumping the rook_operator_image_tag ansible variable and applying osism apply rook-operator.

+

Ceph Upgrades

+

Please have a look at the Rook Ceph Upgrades documentation. Take note of update instructions specific to your version.

+

Usually you can simply update by bumping the rook_ceph_image_tag ansible variable and applying osism apply rook.

+

General maintenance

+

60 seconds cluster overview

+

The following commands can be used to quickly check the status of Ceph:

+
    +
  • +

    Print overall cluster status

    +
    ceph -s
    +
  • +
  • +

    Print detailed health information

    +
    ceph health detail
    +
  • +
  • +

    Display current OSD tree

    +
    ceph osd tree
    +
  • +
  • +

    Cluster storage usage by pool and storage class

    +
    ceph df
    +
  • +
  • +

    List pools with detailed configuration

    +
    ceph osd pool ls detail
    +
  • +
  • +

    Get usage stats for OSDs

    +
    ceph osd df {plain|tree} {class e.g. hdd|ssd}
    +
  • +
  • +

    Watch Ceph health messages sequentially

    +
    ceph -w
    +
  • +
  • +

    List daemon versions running in the cluster

    +
    ceph versions
    +
  • +
+

Also you can run the following on each node running ceph-daemons, +to provide further debug information about the environment:

+
# lscpu
# cat /proc/cpuinfo # if lscpu isn't available
# free -g
# ip l
# ethtool <device> # for each network adapter
+

Mute/Unmute a health warning

+
$ ceph health mute <what> <duration>
$ ceph health unmute <what>
+

Disable/Enable (deep-)scrubbing

+
$ ceph osd set noscrub
$ ceph osd set nodeep-scrub
$ ceph osd unset noscrub
$ ceph osd unset nodeep-scrub
+
warning

Use this sparingly only in emergency situations. +Setting these flags will cause a HEALTH_WARN status, +increase risk of data corruption and also the risk of generating +a HEALTH_WARN due to PGs not being (deep-)scrubbed in time.

+

Reboot a single node

+

The traditional way of doing this is by setting the noout flag, +do the appropriate maintenance work and after the node is back online +unset the flag like so:

+
ceph osd set noout
+

After maintenance is done and host is back up:

+
ceph osd unset noout
+

On versions Luminous or above you can set the flag individually for single +OSDs or entire CRUSH buckets, which can be a safer option in case of prolonged +maintenance periods.

+

Add noout for a OSD:

+
ceph osd add-noout osd.<ID>
+

Remove noout for a OSD:

+
ceph osd rm-noout osd.<ID>
+

Add noout for CRUSH bucket (e.g. host name as seen in ceph osd tree):

+
ceph osd set-group noout <crush-bucket-name>
+

Remove noout for CRUSH bucket:

+
ceph osd unset-group noout <crush-bucket-name>
+

Gathering information about block devices

+

Enumerate typical storage devices and LVM

+
# lsblk
# lsblk -S
# lsscsi
# nvme list
# pvs
# vgs
# lvs
+

SMART data for SATA/SAS and NVME devices

+
# smartctl -a /dev/sdX
# nvme smart-log /dev/nvmeXnY
+

Check format of a NVME device

+
# nvme id-ns -H /dev/nvmeXnY
+
note

Check the last lines named "LBA Format". +It will show which formats are supported, +which format is in use and which format offers the best performance +according to the vendor.

+

Format a NVME device to a different LBA format using nvme-cli

+
warning

This will destroy all data on the device!

+
# nvme format --lbaf=<id> /dev/nvmeXnY
+

Secure Erase a NVME drive using nvme-cli

+
warning

This will destroy all data on the device!

+
# nvme format -s2 /dev/nvmeXnY
# blkdiscard /dev/nvmeXnY
# nvme format -s1 /dev/nvmeXnY
+

Secure Erase a SATA/SAS drive using hdparm

+
warning

This will destroy all data on the device!

+
    +
  1. +

    Gather device info:

    +
    # hdparm -I /dev/sdX
    +
  2. +
+

Check that the output says "not frozen" and "not locked", +also it should list support for enhanced erase and list time estimates +for SECURITY ERASE UNIT and/or ENHANCED SECURITY ERASE UNIT

+
    +
  1. +

    Set a master password for the disk (required, will be automatically removed after wipe)

    +
    # hdparm --user-master wipeit --security-set-pass wipeit /dev/sdX
    # hdparm -I /dev/sdX
    +

    Check that "Security level" is now "high" and master password is now +"enabled" instead of "not enabled" before

    +
  2. +
  3. +

    Wipe the device

    +

    If device supports enhanced security erase (better), use the following:

    +
    # hdparm --user-master wipeit --security-erase-enhanced wipeit /dev/sdX
    +

    If not, use standard security erase:

    +
    # hdparm --user-master wipeit --security-erase wipeit /dev/sdX
    +
  4. +
+
note

On some systems the system firmware might "freeze" the device, +which makes it impossible to issue a secure erase or reformat the device. +In that case it might be necessary to either "unfreeze" the drive or +to install the drive in another system where it can be unfrozen. +Also make sure that the device is actually wiped. Its recommended to +at least perform a blanking pass on HDDs with a tool like nwipe.

+

OSD maintenance tasks

+

Please have a look at the Rook Ceph OSD Management documentation

+

Disable backfills/recovery completely

+
warning

Use only in emergency situations!

+
$ ceph osd set nobackfill
$ ceph osd set norecovery
$ ceph osd set norebalance
+

Unset the flags with ceph osd unset <flag>.

+

Rebalance OSDs

+

Placement Group maintenance

+

Dump placement groups

+

Usually only useful when parsing it, so here are two ways to get the data:

+
$ ceph pg dump
$ ceph pg dump --format=json-pretty
+

Query a PG about its status

+
$ ceph pg <pgid> query
+

Start (deep-)scrubbing of a placement group

+
$ ceph pg scrub <pgid>
$ ceph pg deep-scrub <pgid>
+
note

Instructing a PG to (deep-)scrub does not mean that it will do so immediately, +it can take some time for the scrub to start.

+

HEALTH_WARN - Large omap objects found...

+

Finding PGs which have large OMAP objects:

+
# ceph pg dump --format=json | jq '.pg_map.pg_stats[] |
select(.stat_sum.num_large_omap_objects != 0) |
(.pgid, .stat_sum.num_large_omap_objects, .up, .acting)'
+

(Remove the line breaks between the single quotes or jq might act weird!)

+

This will dump all PG IDs with large OMAP objects and their up/acting OSDs. +You then can grep the logs of these OSDs for "Large omap object" +to find the actual objects causing the health warning.

+

Also the PG ID before the dot is equal to the pool ID it belongs to.

+

In case the logs have been rotated, instruct those OSDs to do a deep-scrub +and watch the logs for the message to appear.

+

From there you can investigate the issue further, +mostly it'll be due to the index of a RGW bucket getting too big due to too many objects, +thus resharding that bucket's index will be necessary.

+

Instruct a PG to repair in case of scrub errors (inconsistent PG)

+
$ ceph pg repair <pgid>
+
note

Recovery might not start immediately and might take some time. +You can query the status of the recovery through ceph pg <pgid> query. +Be sure to read the Ceph manual about this topic thoroughly:

https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshooting-pg/

+

RADOS Pool maintenance

+
note

Read the RADOS pool operations documentation in detail before playing around with pools. +Especially when considering making changes to the CRUSH map. +Wrong decisions there can lead to data loss or other catastrophic failures.

https://docs.ceph.com/en/latest/rados/operations/pools/

+

Get pools and their configuration

+
$ ceph osd pool ls detail
+

Dump all CRUSH rules

+
$ ceph osd crush rule dump
+

Get autoscaler status

+

Autoscaler is enabled by default in a Rook Ceph cluster.

+
$ ceph osd pool autoscale-status
+

Create a replicated pool

+

This should be done by updating your values.yml file via the variables in Rook Extra pools - CephBlockPoolC CRD.

+

It also can be done by hand but Rook will not know about the pool in this case.

+
$ ceph osd pool create <pool_name> <pg_num> <pgp_num> replicated [<crush_rule_name>]
+

Enabling an application on a pool

+

Required, otherwise a health warning will be raised after some time.

+
$ ceph osd pool application enable <pool_name> <application_name> # Syntax
$ ceph osd pool application enable cinder rbd # Example
+

Typical application names are: rbd, rgw, cephfs

+

Delete a pool

+

This should be done by updating your values.yml file via the variables in Rook Extra pools - CephBlockPoolC CRD.

+

It also can be done by hand but Rook will not know about the pool in this case.

+
warning

This will delete all data in that pool. There is no undo/undelete.

+

Set number of PGs for a pool

+
note

PG autoscaling is enabled by default in Rook managed Ceph Clusters.

+

If no autoscaling of PGs is used, it is very important to adapt the PGs per pool to the +real world when operating a Ceph cluster. If, for example, OSDs are exchanged, added, new +nodes are added, etc., the number of PGs must also be taken into account.

+

The PG Calc Tool can be used +to calculate a reasonable number of PGs per pool depending on all ODSs and pools.

+

Further information on placement groups can be found in the +Ceph documentation. +You should definitely read FACTORS RELEVANT TO SPECIFYING PG_NUM and CHOOSING THE NUMBER OF PGS +there.

+
$ ceph osd pool set <poolname> pg_num <num_pgs>
+
note

Num PGs must be a power of two! Be careful about changing number of PGs. +Changing pg_num to a new value will gradually increase pgp_num on newer versions of Ceph.

In older versions one also has to set pgp_num manually, either in increments or in one big leap.

+

Create CRUSH rules for different storage classes

+
$ ceph osd crush rule create-replicated replicated_hdd default host hdd
$ ceph osd crush rule create-replicated replicated_ssd default host ssd
$ ceph osd crush rule create-replicated replicated_nvme default host nvme
+

Change CRUSH rule for a pool ("move pool")

+
$ ceph osd pool set <poolname> crush_rule <rule_name>
+

This can be used to move a pool from e.g. HDD to SSD or NVME class +or anything else that the new CRUSH rule specifies.

+

Advanced topics

+

Performance benchmark

+
# apt-get install -y fio
+
#!/usr/bin/env bash

BENCH_DEVICE="$2"
DATE=$(date +%s)
IOENGINE="libaio"
LOGPATH="$1"
SIZE=1G

mkdir -p $LOGPATH

for RW in "write" "randwrite" "read" "randread"
do
for BS in "4K" "64K" "1M" "4M" "16M" "64M"
do
(
echo "==== $RW - $BS - DIRECT ===="
echo 3 > /proc/sys/vm/drop_caches
fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json
sync
echo 3 > /proc/sys/vm/drop_caches
echo "==== $RW - $BS - DIRECT IODEPTH 32 ===="
fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --iodepth=32 --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-iod32-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json
sync
) | tee $LOGPATH/$RW.$BS-$(basename $BENCH_DEVICE).$DATE.log
echo
done
done
+

Where and how to get further help

+

Join the #ceph IRC channel on irc.oftc.net, state the problem with as many details as possible +including information about what steps have already been taken to solve the problem +also provide information from the command output from the "60 seconds cluster overview" above +through a pastebin or a similar service. In order for people to be able +to help, details and some patience are important.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/rookify/index.html b/docs/iaas/guides/operations-guide/rookify/index.html new file mode 100644 index 0000000000..bd5ff60fe7 --- /dev/null +++ b/docs/iaas/guides/operations-guide/rookify/index.html @@ -0,0 +1,59 @@ + + + + + +Use Rookify: Migrate to Rook from Ceph Ansible (Technical Preview) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Use Rookify: Migrate to Rook from Ceph Ansible (Technical Preview)

+
warning

Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime. +Nevertheless, it is strongly advised to test Rookify in a controlled environment first, such as the OSISM testbed. Additionally ensure that precautionary backups are made and all other necessary safety measures are in place.

+

For a condensed summary of the information covered here, refer to the Rookify GitHub repository.

+

Consider Using a Pickle File

+

To track the migration, you can add a pickle file. Specify this option in the config.yaml:

+
config.example.yaml
general:
machine_pickle_file: data.pickle
+

You can then view the migration progress by running rookify --show-states.

+
warning

Rookify treats the pickle file as a source of truth for its operations. If you want to start a clean migration, ensure you delete the file first.

+

Rookify CLI

+

Run

+
note

By default, Rookify runs in preflight mode (--dry-run).

+

Rookify runs in preflight mode by default, meaning it performs all preflight checks on the modules and their dependent modules, as configured in config.yaml, without executing the migration.

+

--dry-run

+
tip

Run preflight-mode to ensure Rookify can connect to your target systems.

+

Rookify's preflight-mode allows you to verify that basic commands and connections to the target systems are functioning correctly. Running --dry-run or -d mode ensures no migration processes are executed.

+

--migrate

+
tip

Ensure that you use the correct data.pickle file. If you used the pickle file for other setups previously, be sure to delete it.

+

Rookify's execution-mode allows you to run the migration. This is a point of no (easy) return. Be sure to check all your configurations. Run --migrate or -m to execute the migration process.

+

--help

+

Run rookify --help to view the various CLI options available.

+

--show-states

+

Run --show-states or -s to display the status of your migration process. Note that if you specified a pickle file, Rookify will use it to determine the state of migration.

+

Debugging and Testing

+

If you encounter issues with Rookify, you can start by setting the logging level to DEBUG. +If further troubleshooting is needed, you can run the tests included in the Rookify code.

+

Set logging to debug level

+

Edit the config.yaml and set the logging level to "DEBUG":

+
config.example.yaml
logging:
level: DEBUG
format:
time: "%Y-%m-%d %H:%M.%S" # other example: "iso"
renderer: console # or: json
+

You can also customize other formatting options, as shown in the comments. For more details, refer to the structlog.

+

Run tests

+

To run tests on Rookify, ensure you have access to the Rookify code on your system. Then:

+
    +
  1. Run make run-tests-locally from the working directory of the Rookify repository. If you prefer a containerized setup, use make run-tests.
  2. +
  3. Alternatively, run .venv/bin/python -m pytest from the virtual environment of your installation.
  4. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/cloud-in-a-box/index.html b/docs/iaas/guides/other-guides/cloud-in-a-box/index.html new file mode 100644 index 0000000000..d27d813e40 --- /dev/null +++ b/docs/iaas/guides/other-guides/cloud-in-a-box/index.html @@ -0,0 +1,281 @@ + + + + + +Cloud in a Box | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Cloud in a Box

+

💡 Cloud in a Box (CiaB) is a minimalistic installation of the latest stable OSISM release with only services which are needed to +make it work with Kubernetes. It is intended for use as a development system on bare-metal or for use in edge environments or for +training purposes. Its flexibility makes it ideal for building, testing, and refining cloud infrastructure setups in controlled +environments, enabling teams to experiment with different configurations and scenarios before deploying them to production

+
warning

At the moment the secrets are stored in plain text in the osism/cloud-in-a-box +repository and are not secure. Do not use for public accessible systems. In the future, the secrets will be generated automatically.

+

Requirements

+

The system to be used as Cloud in a Box must fulfill these minimum requirements.

+
Type of resourceAmountNote
CPUat least 1 socket with 4 coresMore is better here. This is the minimum where you can't use much payload (LBaaS, VMs). The use of Kubernetes with Cluster API is not possible with this minimum size.
RAMat least 32 GByteMore is better here. In principle, it also works with 8 GByte, but then no payload (LBaaS, VMs) can be used. Kubernetes with Cluster API cannot be used then.
Storageat least 1 TByteHas to be available as /dev/sda or /dev/nvme0n1. Less than 1 TByte is also possible, the smaller the less storage is available for use in Ceph.
Networkat least 1 network interface (DHCP and internet access)An optional 2nd network interface can be used for external connectivity.
USB stickat least 2 GByteInstallation media for Cloud in a Box bootstrapping
+

Types

+

There are three types of Cloud in a Box.

+
    +
  1. +

    The sandbox type is intended for developers and demonstrations. A full OSISM installation +is one there which also includes Ceph and OpenSearch, for example. In the course of the +installation, necessary images, networks, etc. are also created.

    +
  2. +
  3. +

    The edge type is intended to be deployed as an appliance to provide an edge cloud on a +single node. Compared to the sandbox, certain services are not provided there or are +implemented differently. For example, OpenSearch is not deployed because the logs are +delivered to a central location. The storage backend will also be implemented differently there +in the future instead of Ceph.

    +
  4. +
  5. +

    The kubernetes type is intended to be deployed as an appliance to provide a edge Kubernetes +cluster on a single node.

    +
  6. +
+

Installation

+ +

The images currently download and install the +latest state of the installation scripts, +therefore it is mandatory to update the installation media at least when the underlying Ubuntu operating +system release changes. The installation of older releases is currently not supported.

+
    +
  1. +

    Download one of the Cloud in a Box images of type sandbox

    + +
  2. +
  3. +

    Use a tool like balenaEtcher or dd to create a bootable USB stick with the Cloud +in a Box image.

    +
  4. +
  5. +

    Boot from the USB stick. Make sure that the boot from USB is activated in the BIOS.

    +
    warning

    When booting from this USB stick, all data on the hard disks will be destroyed +without confirmation.

    +
  6. +
  7. +

    The installation of the operating system (Ubuntu 22.04) will start and take a few minutes. After that the system +will shutdown.

    +
  8. +
  9. +

    The first start of the system

    +
      +
    • Remove the USB storage device +(The USB stick is only needed again if the Cloud in a Box system is to be fully reinstalled.)
    • +
    • Connect the first network interface to an ethernet interface that provides access to the internet via DHCP configuration
    • +
    • Boot the system from the internal hard disk device
    • +
    +
  10. +
  11. +

    The deployment will start. This takes some time and the system will shutdown when the +deployment is finished. This takes roughly an hour, possibly longer depending on the +hardware and internet connection.

    +
  12. +
  13. +

    Start the system again. System is ready for use, by default DHCP is tried on the first network device.

    +
  14. +
  15. +

    Login via SSH. Use the user dragon with the password password.

    +
    ssh dragon@IP_ADDRESS_FROM_YOUR_SERVER
    +
    info

    You can obtain the IP address by inspecting the logs of your DHCP server or from the issue text of the virtual consoles of the system.

    Cloud in a Box Issue Text

    +
  16. +
+

Manual installation

+

The scripts are not idempotent yet. In case there is any fail during bootstrap.sh or deploy.sh you have to +start over with fresh installation.

+
    +
  1. +

    Follow the provisioning guide, +skip the part about disk layout and do it this way:

    +

    Disk layout

    +
      +
    1. Create a 1 GByte ext4 partition mounted in /boot
    2. +
    3. Create a 8 GByte swap partition
    4. +
    5. Create a 120 GByte unformatted partition
    6. +
    7. Use a Create volume group (LVM) to create a volume group called system with the size of +120 GByte on the partition 4 you just created
    8. +
    9. Create a logical volume by selecting the Free Space option under system LVM. This volume +should be mounted in / and have size of 100 GByte
    10. +
    11. Create a partition with the size of the rest of the drive's space
    12. +
    13. Create a new LVM volume group on partition 5 called osd-vg (will be used for Ceph)
    14. +
    +
  2. +
  3. +

    After the Ubuntu installation, the system will be rebooted

    +
  4. +
  5. +

    Log into the machine via console to get its IP address and then use SSH to connect to the machine

    +
  6. +
  7. +

    Clone the osism/cloud-in-a-box repository into /opt/cloud-in-a-box

    +
    sudo git clone https://github.com/osism/cloud-in-a-box /opt/cloud-in-a-box
    +
  8. +
  9. +

    Disable conflicting services from the default Ubuntu installation

    +
    sudo /opt/cloud-in-a-box/cleanup.sh
    +
  10. +
  11. +

    Install upgrades

    +
    sudo apt update
    sudo apt upgrade
    +
  12. +
  13. +

    Run the bootstrap.sh script with the required type (use of sandbox is recommended)

    +
    sudo /opt/cloud-in-a-box/bootstrap.sh sandbox
    +
  14. +
  15. +

    Run the deploy.sh script with the same type as in step 8 to deploy services like Ceph and OpenStack

    +
    sudo /opt/cloud-in-a-box/deploy.sh sandbox
    +
  16. +
  17. +

    Shutdown the system

    +
    sudo shutdown -h now
    +
  18. +
  19. +

    Start the system again. System is ready for use, by default DHCP is tried on the first network device.

    +
  20. +
  21. +

    Login via SSH. Use the user dragon with the password password.

    +
    ssh dragon@IP_ADDRESS_FROM_YOUR_SERVER
    +
    info

    You can obtain the IP address by inspecting the logs of your DHCP server or from the issue text of the virtual consoles of the system.

    Cloud in a Box Issue Text

    +
  22. +
+

Usage

+

Wireguard VPN service access

+

Copy the /home/dragon/wireguard-client.conf file from Cloud in a Box to your workstation. This is necessary +for using the web endpoints on your workstation. Rename the Wireguard config file to something +like cloud-in-a-box.conf.

+

If you want to connect to the Cloud in a Box system from multiple clients, change the client IP +address in the config file to be different on each client.

+
scp dragon@IP_ADDRESS_FROM_YOUR_SERVER:/home/dragon/wireguard-client.conf $HOME/cloud-in-a-box.conf
+

Install Wireguard on your workstation, if you have not done this before. For instructions how to do +it on your workstation, please have a look on the documentation of your used distribution. The +Wireguard documentation you will find here.

+

Start the Wireguard tunnel.

+
sudo wg-quick up $HOME/cloud-in-a-box.conf
+

Once the Wireguard tunnel has been set up, it is possible to access individual services on a name-based basis. +As a test, you can try whether the name api.in-a-box.cloud resolves correctly to the IP address 192.168.16.254.

+
dig +short A api.in-a-box.cloud
192.168.16.254
+

If this does not work, a DNS filter such as Pi-hole or AdGuard will most likely be used. This ensures that private +IP ranges such as 192.168.16.0/20 are not resolved via a public DNS server. If this is the case, the following +entries must be added to the local /etc/hosts file for the name resolution to work.

+
192.166.16.10	cgit.services.in-a-box.cloud
192.166.16.10 netbox.services.in-a-box.cloud
192.168.16.10 ara.services.in-a-box.cloud
192.168.16.10 flower.services.in-a-box.cloud
192.168.16.10 homer.services.in-a-box.cloud
192.168.16.10 phpmyadmin.services.in-a-box.cloud
192.168.16.10 manager.systems.in-a-box.cloud
192.168.16.254 api.in-a-box.cloud
+

Webinterfaces

+

If you want to access the services please choose the URL from the following list:

+
NameURLUsernamePasswordNote
ARAhttps://ara.services.in-a-box.cloudarapassword
Cephhttp://manager.systems.in-a-box.cloud:7000adminpassword
Configurationhttps://cgit.services.in-a-box.cloud--
Flowerhttps://flower.services.in-a-box.cloud--
Grafanahttps://api.in-a-box.cloud:3000adminpassword
HAProxyhttp://manager.systems.in-a-box.cloud:1984openstackpassword
Homerhttps://homer.services.in-a-box.cloud--
Horizonhttps://api.in-a-box.cloudadmin
test
password
test
domain: default, project: admin
domain: test, project: test
Netboxhttps://netbox.services.in-a-box.cloudadminpassword
Netdatahttp://manager.systems.in-a-box.cloud:19999--
OpenSearch Dashboardshttps://api.in-a-box.cloud:5601opensearchpassword
RabbitMQhttps://api.in-a-box.cloud:15672openstackpassword
Skylinehttps://api.in-a-box.cloud:9999admin
test
password
test
domain: default, project: admin
domain: test, project: test
phpMyAdminhttps://phpmyadmin.services.in-a-box.cloudroot_shard_0password
+

Command-line interfaces

+

Login to Cloud in a Box as described in step 8 of the installation chapter.

+
    +
  • Select one of the preconfigured environments: +
      +
    • system
    • +
    • admin
    • +
    • test
    • +
    +
  • +
  • Set the environment by exporting the environment variable: OS_CLOUD: +
    export OS_CLOUD=admin
    +
  • +
  • Use OpenStack CLI via the command openstack. +
    openstack availability zone list
    openstack image list
    openstack server list # After installation there are no servers
    +
  • +
+

Import of additional images

+

The OpenStack Image Manager is used to manage images. +In the example, the Garden Linux image is imported.

+
osism manage images --cloud=admin --filter 'Garden Linux'
+

All available images can be found in the osism/openstack-image-manager repository.

+

Upgrade

+

It is best to execute the commands within a screen session, it takes some time. Please note +that you cannot update the Ceph deployment at the moment. This will be enabled in the future.

+
osism apply configuration
/opt/configuration/upgrade.sh
docker system prune -a
+

Customisations

+

Use of 2nd NIC for external network

+

In the default configuration, the Cloud in a Box is built in such a way that an internal +VLAN101 is used as an simulated external network and this is made usable via the 1st network +interface using masquerading. This makes it possible for instances running on the Cloud +in a Box to reach the internet. The disadvantage of this is that the instances themselves +can only be reached via floating IP addresses from the Cloud in a Box system itself or +via the Wireguard tunnel. Especially in edge environments, however, one would usually like +to have this differently and the instances should be directly accessible via the local +network.

+

To make this work, first identify the name of a 2nd network card to be used.

+
dragon@manager:~$ sudo lshw -class network -short
H/W path Device Class Description
============================================================
/0/100/2.2/0 eno7 network Ethernet Connection X552 10 GbE SFP+
/0/100/2.2/0.1 eno8 network Ethernet Connection X552 10 GbE SFP+
/0/100/1c/0 eno1 network I210 Gigabit Network Connection
/0/100/1c.1/0 eno2 network I210 Gigabit Network Connection
/0/100/1c.4/0 eno3 network I350 Gigabit Network Connection
/0/100/1c.4/0.1 eno4 network I350 Gigabit Network Connection
/0/100/1c.4/0.2 eno5 network I350 Gigabit Network Connection
/0/100/1c.4/0.3 eno6 network I350 Gigabit Network Connection
+

In the following we use eno7. Activate the device manually with sudo ip link set up dev eno7. +Then check that a link is actually present.

+
dragon@manager:~$ ethtool eno7
Settings for eno7:
Supported ports: [ FIBRE ]
Supported link modes: 10000baseT/Full
[...]
Link detected: yes
+

Now this device is made permanently known in the network configuration. Select the MTU +accordingly. For 1 GBit rather 1500 than 9100. The 2nd network interface should be +configured without IP configuration (neither static nor DHCP).

+
    +
  • /opt/configuration/inventory/group_vars/generic/network.yml
  • +
  • /opt/configuration/environments/manager/group_vars/manager.yml
  • +
+
network_ethernets:
eno1:
dhcp4: true
eno7:
mtu: 9100
+

Then, this change is deployed and applied.

+
osism apply network
sudo netplan apply
+

Now the configuration for Neutron and OVN is prepared. network_workload_interface +is expanded by the 2nd network interface. The order is not random, first vlan101 +then eno7. neutron_bridge_name is added.

+
    +
  • /opt/configuration/inventory/group_vars/generic/network.yml
  • +
  • /opt/configuration/environments/manager/group_vars/manager.yml
  • +
+
network_workload_interface: "vlan101,eno7"
neutron_bridge_name: "br-ex,br-add"
+

Then, this change is deployed.

+
osism reconciler sync
osism apply openvswitch
osism apply ovn
osism apply neutron
+

Now segments and/or subnets can be configured. In this case, eno7 is configured as an +untagged port on the remote side.

+
    +
  • /opt/configuration/environments/openstack/playbook-additional-public-network.yml
  • +
+
- name: Create additional public network
hosts: localhost
connection: local

tasks:
- name: Create additional public network
openstack.cloud.network:
cloud: admin
state: present
name: public-add
external: true
provider_network_type: flat
provider_physical_network: physnet2

- name: Create additional public subnet
openstack.cloud.subnet:
cloud: admin
state: present
name: subnet-public-add
network_name: public-add
cidr: 192.168.23.0/24
enable_dhcp: false
allocation_pool_start: 192.168.23.100
allocation_pool_end: 192.168.23.200
gateway_ip: 192.168.23.1
dns_nameservers:
- 8.8.8.8
- 9.9.9.9
+

The additional public network can now be made known with +osism apply -e openstack additional-public-network.

+

There is now a 2nd floating IP address pool with the name public-add +available for use. If instances are to be started directly in this network, +enable_dhcp: true must be set. In this case, it should be clarified in +advance with the provider of the external network whether the use of DHCP +is permitted there.

+

Troubleshooting

+

Broken disk setup

+

This error means that your disk setup is broken. Use cfdisk and delete all partitions on +the system on which you want to install the Cloud in a Box image.

+

With lsblk you can verify if the partitions are empty.

+

Development

+

For the further development of the scripts and the mechanisms of the Cloud in a Box, +you need to know the following.

+
    +
  • The operating system is brought onto the node via an automatic Ubuntu installation +that uses cloud-init
  • +
  • The installation starts the script init.sh which performs +an initial clone of the osism/cloud-in-a-box repository and a checkout of +the main branch. It also executes the deploy.sh and +bootstrap.sh scripts.
  • +
  • The installation persists the kernel parameters of the initial boot to the file /etc/.initial-kernel-commandline
  • +
  • The status and activities of the deployment are logged in /var/log/install-cloud-in-a-box.log. For proper colors use less -r. +Search for OVERALL STATUS to find the result of the specific installation steps.
  • +
  • Branch and location of the osism/cloud-in-a-box repository can be overriden +by setting the kernel parameters ciab_repo_url (a public repository address without authentication) and ciab_branch +(a name of a branch, use only ASCII chars, -, and _).
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine/index.html b/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine/index.html new file mode 100644 index 0000000000..64e080a0a3 --- /dev/null +++ b/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine/index.html @@ -0,0 +1,110 @@ + + + + + +Running on a virtual machine | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Running on a virtual machine

+

KVM

+

Nested virtualization

+

You likely want to run virtual machines on top of your Cloud in a Box. +The host machine has to support and enabled nested virtualization.

+

To enable nested virtualization the CPU configuration of the VM has to be host-passthrough or host-model

+ +

The linked guide can be used in other distributions as well.

+

Disk space saving

+

When using Cloud in a Box in a VM, you can utilize the qcow2 disk image or similar technology to save space. +In that case, the base installation requires just around 70 GB instead of a full 1 TB. +(The drive still needs to be made with a capacity of at least 1TB; however, the actual disk space usage is lower.)

+

Also in case you want to experiment a bit more and "hack around" using the manual installation +you can make disk snapshots when turned off after the Ubuntu installs, bootstrap.sh and deploy.sh to speed up your +progress.

+

If you use qemu, you can use following command to do snapshots.

+
sudo virsh snapshot-create-as --domain cib bootstrap "run of bootstrap.sh" --disk-only --diskspec sda,snapshot=external,file=/var/lib/libvirt/images/ub2022_cib_boostrap.qcow2 --atomic
+

QEMU guest agent

+

When running inside QEMU, it may be worth it to install the QEMU guest agent.

+
sudo apt -y install qemu-guest-agent
sudo systemctl enable qemu-guest-agent
sudo systemctl start qemu-guest-agent
+

VMware vSphere/ESXi

+

When running Cloud in a Box on a VMware vSphere/ESXi virtual machine, you can use the below specs to configure the virtual machine:

+

Guest OS:

+
    +
  • Compatibility set to current running vSphere/ESXi version
  • +
  • Guest OS family set to "Linux"
  • +
  • Guest OS version set to "Ubuntu Linux (64-bit)"
  • +
+

Hardware:

+
    +
  • 32GB RAM
  • +
  • 8 vCores
  • +
  • SCSI Controller 0 set to LSI Logic Parallel
  • +
  • SCSI Disk with 500GB
  • +
  • CDROM/DVD drive mounted with ubuntu-autoinstall-cloud-in-a-box-1.iso image
  • +
  • Firmware set to "EFI" (VM Options > Boot Options > Firmware > choose EFI)
  • +
+

This configuration has been successfully tested with VMware ESXi 7.0 U1.

+

VirtualBox

+

When running Cloud in a Box on a VirtualBox, you can use the the blow specs for configure the virtual machine:

+

General:

+
    +
  • Type Linux
  • +
  • Version Ubuntu (64-bit)
  • +
+

System:

+
    +
  • 32GB RAM
  • +
  • 8 Processors
  • +
  • Enable PAE/NX
  • +
  • Enable Nested VT-x/AMD-v
  • +
  • Extended Feature: Enable EFI (special OSes only)
  • +
+

Storage:

+
    +
  • +

    Controller: SATA

    +
  • +
  • +

    Type AHCI

    +
  • +
  • +

    Use Host I/O Cache

    +
  • +
  • +

    Disc Size 600 GB

    +
  • +
  • +

    Controller: IDE

    +
  • +
  • +

    Optical Drive: IDE Secondary Device

    +
  • +
  • +

    Live CD/DVD

    +
  • +
  • +

    Insert the ubuntu-autoinstall-cloud-in-a-box-1.iso image

    +
  • +
  • +

    Boot Order: Set Optical as first boot device

    +
  • +
+

This configuration has been successfully tested with VirtualBox 6.1.50 using an Ubuntu 22.04 Host with HWE Kernel 6.5.0 +The more CPU, RAM and Disc the better, as this is the bare minimum for a basic installation.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/contributor-guide/index.html b/docs/iaas/guides/other-guides/contributor-guide/index.html new file mode 100644 index 0000000000..c606402ac5 --- /dev/null +++ b/docs/iaas/guides/other-guides/contributor-guide/index.html @@ -0,0 +1,34 @@ + + + + + +Contributor Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Contributor Guide

+

We welcome any issues, change requests or general feedback. Do not hestiate to open an issue.

+

We use GitHub Issues to capture feature requests, feedback, bugs, etc. The tracker is available in the +osism/issues repository. There are no specific requirements for the creation of an issue. +Error cases should be described in such a way that they are directly reproducible. The more outputs there are, +the better.

+

We use GitHub pull requests for contributions. The use of pull requets is documented in the +official GitHub documentation. +The process in detail for the creation of a fork, branch etc. is also documented in the +official GitHub documentation. +It is recommended to use the GitHub CLI. Makes many steps easier.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/developer-guide/index.html b/docs/iaas/guides/other-guides/developer-guide/index.html new file mode 100644 index 0000000000..7c471e5834 --- /dev/null +++ b/docs/iaas/guides/other-guides/developer-guide/index.html @@ -0,0 +1,39 @@ + + + + + +Developer Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Developer Guide

+

How to add a new service

+

If you want to add a new service to OSISM, this is done via an Ansible role and (most often) +a container image. The following steps are necessary and are demonstrated using the example +of osism.services.cgit.

+
DescriptionExample
Add the Ansible role in one of the Ansible collection repositorieshttps://github.com/osism/ansible-collection-services/pull/578/files
Add the Ansible playbookhttps://github.com/osism/ansible-playbooks/pull/215/files
Add the Ansible inventory grouphttps://github.com/osism/cfg-generics/pull/225/files
Add the used container image(s) to the release repositoryhttps://github.com/osism/release/pull/278/files
Add the container images(s) to osism-ansible container imagehttps://github.com/osism/container-image-osism-ansible/pull/215/files
Add the container image registry/registries and host(s) to the defaults repositoryhttps://github.com/osism/defaults/pull/54/files
Add a sample deployment to the testbedhttps://github.com/osism/testbed/pull/1043/files
+

How to add a new container image

+

If required, add a new container image in the osism/container-images +repository. The example here is from the osism.services.keycloak role: https://github.com/osism/container-images/pull/34/files.

+

Whenever possible, upstream container images should be used. If only minor customizations are necessary, +always work with overlay container images based on upstream container images.

+

How service deployment works

+

Docker

+

Service deployment with Docker

+

Kubernetes

+

Service deployment with Kubernetes

+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/developer-guide/releases/index.html b/docs/iaas/guides/other-guides/developer-guide/releases/index.html new file mode 100644 index 0000000000..a94355c24d --- /dev/null +++ b/docs/iaas/guides/other-guides/developer-guide/releases/index.html @@ -0,0 +1,166 @@ + + + + + +Releases | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Releases

+

How we handle releases

+

Currently we do a major release every 6 months. Minor releases we do when +needed and about every 2 weeks.

+

In a minor release, only updates, bug fixes, etc. take place. There are also +no major upgrades of included components such as OpenStack, Keycloak or Ceph +in a minor release.

+

It is possible to jump from any minor version within a major version to higher +minor versions without any intervention.

+

Deprecations, removals, etc. take place in a major release. New mandatory +features are also added in a major release. Upgrades of the included components +can also take place during a major release (e.g. OpenStack Xena -> OpenStack Yoga).

+

It is possible to jump from the previous major version to the next major version. +It may be that manual intervention is necessary. For example, configuration +parameters may need to be added or services that no longer exist may need to be +removed.

+

How to make a release

+
    +
  1. +

    On all repositories that are used, check that the versions to be used have an +appropriate version tag (e.g. v0.20230308.0).

    +
    osism/ansible-collection-commons
    osism/ansible-collection-services
    osism/ansible-collection-validations
    osism/ansible-defaults
    osism/ansible-playbooks
    osism/ansible-playbooks-manager
    osism/cf-generics
    osism/kolla-operations
    osism/python-osism
    +
  2. +
  3. +

    Copy the latest directory. The release to be created is used as the new name.

    +
    latest -> 6.0.0b
    +
  4. +
  5. +

    Remove all # renovate lines from the base.yml file.

    +
  6. +
  7. +

    Remove all Ceph and OpenStack releases that should not be part of the pre-release. +There is only one OpenStack version and one Ceph version per (pre-)release.

    +
  8. +
  9. +

    Ensure that the symlinks openstack.yml and ceph.yml point to the releases +to be used in this pre-release.

    +
    base.yml
    ceph-pacific.yml
    ceph.yml -> ceph-pacific.yml
    openstack-zed.yml
    openstack.yml -> openstack-zed.yml
    +
  10. +
  11. +

    Run src/prepare-release.py.

    +
    RELEASE=6.0.0b python3 src/prepare-release.py
    +
  12. +
  13. +

    Do the steps from the Stable release starting from the 4th step.

    +
  14. +
+

Stable release

+
    +
  1. +

    Copy the directory of the last pre-release or the previous stable release. +The release to be created is used as the new name.

    +
    5.0.0a -> 5.0.0b
    5.0.0b -> 5.0.0
    5.0.0 -> 5.1.0
    5.1.0 -> 5.2.0
    5.2.0 -> 5.3.0
    +
  2. +
  3. +

    Change all necessary versions in the YAML files within the new directory. +In any case, the version of the pre-release or the version of the stable +release must be replaced by the release to be created.

    +
  4. +
  5. +

    The release to be created is submitted as a pull request as usual and then +merged.

    +
  6. +
  7. +

    Add a tag with the name of the new release to the listed repositories.

    +
    osism/container-image-ceph-ansible
    osism/container-image-inventory-reconciler
    osism/container-image-osism-ansible
    osism/container-images-kolla
    +
  8. +
  9. +

    After completing the creation of the images in repository container-images-kolla, +the file images.yml must be added to repository osism/sbom as +5.0.0/openstack.yml (instead of 5.0.0, the corresponding release is used). +The file is available as a build artefact of the Release container images action +on the created tag.

    +

    Before the file is added, it is enhanced with the checksums of the images. The script +is available in the osism/sbom repository.

    +
    VERSION=5.0.0 python3 scripts/add-image-checksum.py
    +
  10. +
  11. +

    If 5.0.0/openstack.yml is present in osism/sbom, repository +osism/container-image-kolla-ansible can be tagged like the other +repositories before.

    +
  12. +
  13. +

    Add the created SPDX files from the listed repositories to the osism/sbom repository. +The file are available as build artefacts of the Build container image action +on the created tags.

    +
    osism/container-image-ceph-ansible
    osism/container-image-kolla-ansible
    osism/container-image-osism-ansible
    +
  14. +
  15. +

    Add and run temporary CI jobs in osism/testbed that uses the pre-release.

    +
    - job:
    name: testbed-deploy-stable-next
    parent: testbed-deploy
    vars:
    manager_version: "5.0.0a"
    refstack: true
    nodeset: testbed-orchestrator

    - job:
    name: testbed-upgrade-stable-next
    parent: testbed-deploy
    vars:
    manager_version: "4.2.0"
    manager_version_next: "5.0.0a"
    nodeset: testbed-orchestrator
    +
  16. +
  17. +

    Test. Test. Test.

    +
  18. +
  19. +

    Prepare a PR to change the stable version to the new stable version in the following Zuul jobs +in the osism/testbed repository. All tests there must pass successfully before the tag is +set on this repository in the next step. The temporary CI jobs (step 8) are removed again with +this PR.

    +
    testbed-deploy-stable
    testbed-update-stable
    testbed-update-stable
    testbed-upgrade-stable
    +
  20. +
  21. +

    Add a new release notes file to doc/sorce/notes. Generate the versions table with the +help of the release-table.py script in the osism/sbom repository.

    +
  22. +
  23. +

    After all known issues are documented, a corresponding tag, e.g. 5.0.0, is set on the +osism/release repository.

    +
  24. +
  25. +

    Create a GitHub release with the new tag on the +osism/release repository. The release is +now public available.

    +
  26. +
  27. +

    As the last of the release process, the previously prepared PR is merged on the +osism/testbed repository to change the stable version.

    +
  28. +
+

How we write release notes

+

We use Reno to manage the release notes.

+

Installation

+

Reno is provided as a Python package and can be installed with pip.

+
pip3 install reno
+

Usage

+

For each change in a repository, a release note is created with Reno. +Something meaningful is used as the name for the note. For example, if the +requirements file for Ansible is removed, remove-ansible-requirements is a good name.

+
$ reno new remove-ansible-requirements
no configuration file in: ./releasenotes/config.yaml, ./reno.yaml
Created new notes file in releasenotes/notes/remove-ansible-requirements-6c6eba43f616bc6b.yaml
+

The created file contains prepared entries for several categories. It is described briefly +in each instance which contents belong in which category. What is not needed is deleted.

+
prelude: >
Replace this text with content to appear at the top of the section for this
release. All of the prelude content is merged together and then rendered
separately from the items listed in other parts of the file, so the text
needs to be worded so that both the prelude and the other items make sense
when read independently. This may mean repeating some details. Not every
release note requires a prelude. Usually only notes describing major
features or adding release theme details should have a prelude.
features:
- |
List new features here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
issues:
- |
List known issues here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
upgrade:
- |
List upgrade notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
deprecations:
- |
List deprecations notes here, or remove this section. All of the list
items in this section are combined when the release notes are rendered, so
the text needs to be worded so that it does not depend on any information
only available in another section, such as the prelude. This may mean
repeating some details.
critical:
- |
Add critical notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
security:
- |
Add security notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
fixes:
- |
Add normal bug fixes here, or remove this section. All of the list items
in this section are combined when the release notes are rendered, so the
text needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
other:
- |
Add other notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
+

Example

+

Here is an example of a commit from the osism/cfg-generics repository.

+
---
features:
- |
The `requirements.yml` has been removed. The version will be set in the `run.sh`
script for the seed process in the future exactly as later in the update process
via the parameters `ANSIBLE_COLLECTION_SERVICES_VERSION` and
`ANSIBLE_PLAYBOOKS_MANAGER_VERSION`.
upgrade:
- |
In existing configuration repositories, the `environments/manager/requirements.yml`
file can be removed after the generics have been synced.
+

Repositories without release notes

+

We do not create release notes in the following repositories:

+
    +
  • osism/github-manager
  • +
  • osism/osism.github.io
  • +
  • osism/release
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/developer-guide/scripts/index.html b/docs/iaas/guides/other-guides/developer-guide/scripts/index.html new file mode 100644 index 0000000000..e4f1375307 --- /dev/null +++ b/docs/iaas/guides/other-guides/developer-guide/scripts/index.html @@ -0,0 +1,79 @@ + + + + + +Scripts | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Scripts

+

Scripts are included in container images to simplify development work and to enable +testing and hotfixes in running environments. What scripts are available and how to +use them is described in this chapter.

+

The change.sh script may be used to update repositories to development branches. Different +targets may be passed as a first parameter and existing branch names as a second. The availability +of targets depends on the container it is run in.

+ +

In this example, the main branch of osism/ansible-collection-services +is used in the osism-ansible container.

+
docker exec -u root -it osism-ansible /change.sh services main
+

The respective container should always be restarted after a change.

+
docker restart osism-ansible
+

If something has been changed in the defaults and is to be tested, this must be +changed in the inventory reconciler service. Regardless of which of the Ansible services +the customised defaults are intended for.

+
docker exec -u root -it manager-inventory_reconciler-1 /change.sh defaults main
docker restart manager-inventory_reconciler-1
+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/developer-guide/style-guide/index.html b/docs/iaas/guides/other-guides/developer-guide/style-guide/index.html new file mode 100644 index 0000000000..c5a19afcf2 --- /dev/null +++ b/docs/iaas/guides/other-guides/developer-guide/style-guide/index.html @@ -0,0 +1,80 @@ + + + + + +Style Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Style Guide

+

Ansible

+

We implement all the default rules of Ansible Lint. All default rules can be found in the +Ansible Lint documentation.

+

Task names

+
    +
  • Tasks must always have names. The only exception allowed is for forked playbooks.
  • +
  • A name never starts with a small letter
  • +
  • Names are written in present tense
  • +
  • No punctuation is used in names
  • +
+

become directive

+

The become directive is only set when needed and is always set explicitly for each task that needs it.

+

Blocks, roles, or playbooks are never executed in a privileged mode.

+

We always insert the become directive between the name of a task and the task itself. This also applies +to related directives like become_user or become_flags. This is for better visibility if a task is +privileged or not.

+
- name: Copy hddtemp configuration file
become: true
ansible.builtin.copy:
src: "{{ ansible_os_family }}/hddtemp"
dest: "{{ hddtemp_conf_file }}"
owner: root
group: root
mode: 0644
notify: Restart hddtemp service
+

when directive

+

If you need to use the when directive add this at the end-section from the task where it is needed. This +makes the code easier to understand for others.

+
- name: "Archive existing {{ resolvconf_file }} file"
become: true
ansible.posix.synchronize:
src: "/etc/resolv.conf"
dest: "/etc/resolv.conf.{{ ansible_date_time.date }}"
archive: true
delegate_to: "{{ inventory_hostname }}"
when: stat_resolvconf_file.stat.islnk is defined and not stat_resolvconf_file.stat.islnk
+

Lists as defaults

+

Defaults that provide a list are always defined as in the following example.

+

docker_hosts_defaults sets the defaults in the role. Overriding is only possible with the defaults repository.

+

In the configuration repository, docker_hosts_extra is then used to add additional items to the list.

+

docker_hosts itself is never modified from the outside.

+
docker_hosts_defaults:
- "unix:///var/run/docker.sock"
docker_hosts_extra: []
docker_hosts: "{{ docker_hosts_defaults + docker_hosts_extra }}"
+

Containerfiles

+

Commit messages

+

Python

+

Black is a popular Python code formatter that automatically +formats your code to adhere to a consistent style. We use it to automatically format the +syntax of Python. A job is running in the CI that checks, if Black has been applied. Therefore, +format the files with Black accordingly in advance.

+

Installation

+

pip install black

+

Formatting a Single File

+

black myfile.py

+

Formatting Multiple Files and/or directories

+

black file1.py file2.py dir/

+

Formatting an Entire Project

+

This command will format all Python files in the current directory and its subdirectories:

+

black .

+

Check Mode (Dry Run)

+

Running Black with the --check option performs a dry run and reports files that would be +changed without actually modifying them:

+

black --check myfile.py

+

Excluding Files or Directories

+

You can exclude files or directories from formatting using the --exclude option:

+

black --exclude=dir_to_exclude/ .

+

Integration with Code Editors

+

Many code editors have extensions or plugins that can automatically run Black on your code. +For example, if you're using VSCode or PyCharm, you can easily integrate it into your IDE.

+

Example of failed python-black Zuul job

+

job-output.txt:

+
[…]
2023-11-16 14:38:14.149756 | TASK [python-black : Install pip module black]
2023-11-16 14:38:18.717886 | ubuntu-jammy | changed
2023-11-16 14:38:18.723062 |
2023-11-16 14:38:18.723137 | TASK [python-black : Format code with Black if there is nothing to exclude]
2023-11-16 14:38:19.138060 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/adminer.py
2023-11-16 14:38:19.151965 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/bird.py
2023-11-16 14:38:19.163608 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/auditd.py
2023-11-16 14:38:19.187772 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cephclient/package.py
2023-11-16 14:38:19.192695 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cephclient/container.py
2023-11-16 14:38:19.219694 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cgit.py
2023-11-16 14:38:19.230577 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/dnsdist.py
2023-11-16 14:38:19.275681 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/hddtemp/redhat.py
2023-11-16 14:38:19.300350 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/homer.py
2023-11-16 14:38:19.310641 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/lldpd.py
2023-11-16 14:38:19.318096 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/docker.py
2023-11-16 14:38:19.329099 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/osquery.py
2023-11-16 14:38:19.344766 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/rsyslog.py
2023-11-16 14:38:19.358190 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/smartd.py
2023-11-16 14:38:19.363578 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/tuned.py
2023-11-16 14:38:19.389205 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/util/util.py
2023-11-16 14:38:19.406360 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_container_facts.py
2023-11-16 14:38:19.415046 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/filter/address.py
2023-11-16 14:38:19.473508 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_toolbox.py
2023-11-16 14:38:19.908963 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_docker.py
2023-11-16 14:38:19.914395 | ubuntu-jammy |
2023-11-16 14:38:19.914412 | ubuntu-jammy | Oh no! 💥 💔 💥
2023-11-16 14:38:19.914419 | ubuntu-jammy | 20 files would be reformatted, 18 files would be left unchanged.
2023-11-16 14:38:20.249358 | ubuntu-jammy | ERROR
2023-11-16 14:38:20.249501 | ubuntu-jammy | {
2023-11-16 14:38:20.249533 | ubuntu-jammy | "delta": "0:00:01.053565",
2023-11-16 14:38:20.249553 | ubuntu-jammy | "end": "2023-11-16 14:38:19.932073",
2023-11-16 14:38:20.249571 | ubuntu-jammy | "msg": "non-zero return code",
2023-11-16 14:38:20.249587 | ubuntu-jammy | "rc": 1,
2023-11-16 14:38:20.249603 | ubuntu-jammy | "start": "2023-11-16 14:38:18.878508"
2023-11-16 14:38:20.249618 | ubuntu-jammy | }
[…]
+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/developer-guide/zuul/index.html b/docs/iaas/guides/other-guides/developer-guide/zuul/index.html new file mode 100644 index 0000000000..81a9057622 --- /dev/null +++ b/docs/iaas/guides/other-guides/developer-guide/zuul/index.html @@ -0,0 +1,138 @@ + + + + + +Zuul CI | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Zuul CI

+
note

We use Zuul CI as a CI service for OSISM. The service is not required for +the use of OSISM itself. However, as we deploy and provide Zuul CI ourselves, +the documentation for this is also included in the OSISM Developer Guide.

Our Zuul CI instance is available at +zuul.services.betacloud.xyz.

+

osism.services.zuul is the Ansible role to set up Zuul CI as a single-node +installation with Docker Compose.

+

The zuul label

+

On CI jobs that consume a lot of resources and have long runtimes we use a label +zuul to run these jobs.

+

These CI jobs run in the label pipeline +and are only started once after the label has been assigned. If changes are made +to a PR, the label must first be removed and then reassigned for a new run of the +CI jobs.

+

The zuul label is usable in the following repositories:

+ +

Installation

+

Server preparation

+

Set up a server (VM) with Ubuntu Server 22.04 LTS and make +sure that these packages are installed:

+
    +
  • docker.io
  • +
  • docker-compose
  • +
  • python3-docker
  • +
  • python3-openstackclient
  • +
+

Also configure your deploy user to be in the docker group and set up the +account for the zuul user. TCP-Ports 80 and 443 should be accessible +from the internet, port 22 for management via SSH will also often be +useful, but not required.

+

If you have an OpenStack tenant where you want to deploy the Zuul +server, you can download and adapt this example +playbook:

+
---
- name: Setup zuul server
hosts: localhost
vars:
cloud: mycloud
flavor: myflavor
image: Ubuntu 22.04
keypair: mykeypair
network: myprivatenet
project: myproject
zuul_domain: mydomain.xyz.
zuul_fqdn: "zuul01.services.{{ zuul_domain }}"
zuul_host: zuul01

tasks:
- name: Create security group
openstack.cloud.security_group:
cloud: "{{ cloud }}"
name: "{{ project }}-zuul"
description: "Default security group for {{ project }}-zuul"

- name: Create security group rule (icmp)
openstack.cloud.security_group_rule:
cloud: "{{ cloud }}"
security_group: "{{ project }}-zuul"
protocol: icmp
remote_ip_prefix: 0.0.0.0/0

- name: Create security group rules (tcp)
openstack.cloud.security_group_rule:
cloud: "{{ cloud }}"
security_group: "{{ project }}-zuul"
protocol: tcp
remote_ip_prefix: 0.0.0.0/0
port_range_min: "{{ item }}"
port_range_max: "{{ item }}"
loop:
- 22
- 80
- 443

- name: Create zuul server
openstack.cloud.server:
cloud: "{{ cloud }}"
flavor: "{{ flavor }}"
image: "{{ image }}"
key_name: "{{ keypair }}"
name: "{{ zuul_host }}"
network: "{{ network }}"
security_groups:
- default
- "{{ project }}-zuul"
meta:
hostname: "{{ zuul_host }}"
register: zuul_server

- name: Add host
ansible.builtin.add_host:
name: "{{ zuul_server.openstack.accessIPv4 }}"
groups: zuul
ansible_user: ubuntu

- name: Initialize zuul server
hosts: zuul
gather_facts: false
vars:
zuul_user: zuul

tasks:
- name: Wait for system to become reachable
ansible.builtin.wait_for_connection:

- name: Update all packages
ansible.builtin.apt:
update_cache: true
name: '*'
state: latest
become: true

- name: Install required packages
ansible.builtin.apt:
name:
- docker.io
- docker-compose
- python3-docker
- python3-openstackclient
become: true

- name: Add user to docker group
ansible.builtin.user:
name: "{{ ansible_ssh_user }}"
groups: docker
append: true
become: true

- name: Add group
ansible.builtin.group:
name: "{{ zuul_user }}"
become: true

- name: Add user
ansible.builtin.user:
name: "{{ zuul_user }}"
uid: 10001
shell: /bin/bash
group: "{{ zuul_user }}"
groups: sudo
append: true
home: "/home/{{ zuul_user }}"
become: true
+

Define secrets

+

There need to be some secrets handed to the deployment, the suggested +method is to have a dedicated file that contains them, which will be +included in the example playbook below via a vars_files statement. +This allows you to easily protect all your secrets by applying +ansible-vault encrypt to that file. The contents of this file should +look like:

+
---
zuul_auth_secret: secret used for zuul web auth
webhook_token: token defined for github webhooks
db_user_pass: DB password for the zuul user
db_root_pass: DB root password
+

In addition you need to prepare some further data that needs to be +placed into a files directory in order to be consumed by the zuul +role. These are:

+
    +
  1. A clouds.yaml file for nodepool. This will be used by +nodepool-builder to upload the newly created images and by +nodepool-launcher to start instances running these images, these +will then be handed over to Zuul as CI nodes.
  2. +
  3. An SSH private key in the file nodepool and the matching public +key in nodepool.pub. These will be used by nodepool and zuul to +access the CI nodes via SSH.
  4. +
  5. An SSL private key and certificate pasted together in a file +named server.crt. This file will be used in the https setup by +the webserver. The certificate should cover both zuul_webserver_fqdn +and zuul_logserver_fqdn.
  6. +
+

Github App setup

+

In order for zuul to be able to interact with repositories hosted on +github, you need to set up a github application. Follow the instructions +at https://zuul-ci.org/docs/zuul/latest/drivers/github.html#application +to do this. The webhook token to use is the one defined in the +pervious section. Use github in place of <connection-name> for the +Webhook URL in the app configuration. After the app has been created, +place the PEM files that you downloaded into a +directory named pem-files:

+
$ mkdir -p pem-files
$ cp ~/Downloads/my-org-zuul.*.private-key.pem pem-files/my-org-zuul.pem
+

Now add the information about your github app to vars.yml:

+
github_app_id: 000000
github_pem_name: my-org-zuul
+

Example Playbook

+

Save this file as main.yaml:

+
---
- name: Set up zuul
hosts: zuul.example.com
vars_files:
- vars.yml
pre_tasks:
- name: Create /etc/openstack/
ansible.builtin.file:
state: directory
path: /etc/openstack
owner: root
group: root
mode: 0755
become: true

- name: Deploy clouds.yaml file
ansible.builtin.copy:
src: clouds.yaml
dest: /etc/openstack/clouds.yaml
owner: root
group: zuul
mode: '0640'
become: true

- name: Create keypair in the cloud
openstack.cloud.keypair:
cloud: osism-ci
name: osism-zuul
public_key: "{{ lookup('file', 'nodepool.pub') }}"
become: true

roles:
- name: Execute zuul role
role: zuul
vars:
zuul_connections:
github:
driver: github
webhook_token: "{{ webhook_token }}"
app_id: "{{ github_app_id }}"
app_key: "/etc/zuul/pem-files/{{ github_pem_name }}.pem"
opendevorg:
name: opendev
driver: git
baseurl: https://opendev.org
zuul_tenants:
- tenant:
name: my-tenant-name
source:
opendevorg:
untrusted-projects:
- zuul/zuul-jobs:
include:
- job
github:
config-projects:
- my-org/zuul_demo_config:
load-branch: main
untrusted-projects:
- my-org/zuul_demo_repo
become: true
+

Create an inventory file containing the login information for your zuul +server, it might look like:

+
zuul.example.com ansible_host=192.0.2.2 ansible_user=ubuntu
+

Then you can deploy your zuul server by running:

+
ansible-playbook -i inventory main.yaml
+

This will deploy a simple zuul setup with sample example repos being +referenced. You can fork the example repos from the +https://github.com/osism tenant or just use them as a guide for how +to build your own.

+

For further information about how to tune this setup for +you specific environment, have a look at the sections covering +nodepool and tenant configuration.

+

Troubleshooting

+

Your git repos are not displayed?

+

Have you thought of naming your repos with the prefix of your organization? release should be osism/release for example.

+

Your git repos are using the wrong branch?

+

For config-projects you set this value in the tenant-configuration with the load-branch stanza. +For untrusted-projects you set this value in the config-projects project sections AND in EVERY untrusted-project. +Each project section needs to have the default-branch stanza.

+

Your logs are not displayed in the web-UI?

+

Check, if the IP of the logfile server is really correct. In combination with GitHub there is a +bug which keeps the GitHub App posting to the old IP even if the webhook IP was changed. Current +workaround: Delete the old GitHub App and create a new one.

+

Hanging jobs in a pipeline?

+

Sometimes jobs get stuck in a pipeline and are never scheduled. They must then be removed manually +so that they do not block other jobs.

+

Hanging jobs in a pipeline

+

First create a local .zuul.conf configuration file in your home directory.

+
+

[osism] +url=https://zuul.services.betacloud.xyz/ +auth_token=TOKEN +tenant=osism

+

The required auth token can be generated on the Zuul control node with the `zuul-admin` client.

+

docker exec -it zuul_scheduler zuul-admin create-auth-token --user USER --tenant osism --expires-in 3600 --auth-config zuul_operator

+

With the [zuul-client](https://zuul-ci.org/docs/zuul-client/index.html) it is possible to
remove the two hanging jobs from the screenshot.

+

zuul-client --use-config osism dequeue --pipeline periodic-daily --project osism/k8s-capi-images --ref refs/heads/main +zuul-client --use-config osism dequeue --pipeline periodic-daily --project osism/cfg-generics --ref refs/heads/main

+

## Important daily CI jobs

* [osism/container-image-ceph-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-ceph-ansible&pipeline=periodic-daily&skip=0)
* [osism/container-image-kolla-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-kolla-ansible&pipeline=periodic-daily&skip=0)
* [osism/container-image-osism-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-osism-ansible&pipeline=periodic-daily&skip=0)
* [osism/container-images-kolla](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-images-kolla&pipeline=periodic-midnight&skip=0)
* [osism/testbed](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Ftestbed&pipeline=periodic-daily&skip=0)
+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/index.html b/docs/iaas/guides/other-guides/index.html new file mode 100644 index 0000000000..890b42920f --- /dev/null +++ b/docs/iaas/guides/other-guides/index.html @@ -0,0 +1,24 @@ + + + + + +Other Guides | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/testbed/index.html b/docs/iaas/guides/other-guides/testbed/index.html new file mode 100644 index 0000000000..238a1afe4a --- /dev/null +++ b/docs/iaas/guides/other-guides/testbed/index.html @@ -0,0 +1,440 @@ + + + + + +Testbed | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Testbed

+

With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack +deployment on an existing OpenStack environment such as Cleura or REGIO.cloud.

+

OSISM is the reference implementation for the Infrastructure as a Service (IaaS) layer in the +Sovereign Cloud Stack (SCS) project. The OSISM Testbed is therefore +used in the SCS project to test and work on the Instrastructure as a Service layer.

+

The OSISM Testbed is intended as a playground. Further services and integration will +be added over time. A increasing number of best practices and experiences from the productive +deployments will be included here in the future. It will become more production-like +over time. However, at no point does it claim to represent a production setup exactly.

+

Requirements

+

Cloud access

+

The usual prerequisite is to have an account on one of the supported OpenStack cloud providers. +As the OSISM Testbed also virtualizes systems itself, the OpenStack cluster should provide +the capabilities for nested virtualization.

+

It is not part of this guide to describe the registration with the individual cloud +providers. Please contact the respective cloud provider for this.

+
ProductProviderProfile nameNote
CleuraCleuracleura
Fuga CloudFUGAfuga
HuaweiCloudHuaweiCloudhuaweicloud
OVHOVHovh
OpenTelekomCloudT-Systemsotc
pluscloud openplusserverpluscloudopen
pluscloud SCS Testplusservergx-scs
REGIO.cloudOSISMregiocloud
REGIO.cloudOSISMregio-fastboot from NVMe SSD backed volumes
Wavestacknoris networkwavestack
CNDS Cloudartcodixartcodix
+

For each cloud provider listed in the table, a predefined profile is available in the +terraform/environments directory. This profile contains the name of the public +network, which flavors to use, etc.

+

Here is an example from the profile for REGIO.cloud.

+
flavor_manager            = "SCS-4V-16-50"
flavor_node = "SCS-8V-32-50"
volume_type = "ssd"
image = "Ubuntu 22.04"
image_node = "Ubuntu 22.04"
public = "public"
availability_zone = "nova"
volume_availability_zone = "nova"
network_availability_zone = "nova"
+

Cloud resources

+

The OSISM Testbed requires at least the following project quota when using the default flavors:

+
QuantityResourceNote
4Instances28 VCPUs + 112 GByte RAM (3 modes, 1 manager)
9Volumes90 GByte volume storage
1Floating IP
1Keypair
3Security group
16Security group rules
1Network
1Subetwork
6Ports
1Router
+

Software

+
    +
  • make must be installed on the system
  • +
  • Wireguard or sshuttle must be installed on your system for VPN access
  • +
  • Python must be installed, the Python version used must be at least 3.10, otherwise +the current Ansible release cannot be used (details in the +Ansible support matrix)
  • +
  • python3-venv must be installed for managing Python dependencies like Ansible
  • +
+

Deployment

+

This section describes step by step how to deploy the OSISM Testbed.

+
    +
  1. +

    Request access from the administrator of the respective cloud or get access to an OpenStack cloud.

    +
  2. +
  3. +

    Clone the osism/testbed repository.

    +

    The repository can also be cloned to any other location.

    +
    mkdir -p ~/src/github.com/osism
    git clone https://github.com/osism/testbed ~/src/github.com/osism/testbed
    cd ~/src/github.com/osism/testbed
    +
  4. +
  5. +

    Configure your cloud access profile

    +

    The access data for the cloud provider used is stored in terraform/clouds.yaml and (optionally) +in terraform/secure.yaml (same structure, if you want to store credentials on a separate place).

    +

    In file terraform/clouds.yaml.sample +you will find examples of typical setups. Settings that are identical for all users of a cloud can be defined +centrally via the profiles of the file +terraform/clouds-public.yaml. +You can reference these settings by using the profile parameter in cloud-specific +definition in terraform/clouds.yaml.

    +

    The user specific settings of the clouds.yaml file are provided by the cloud provider. Please check the +documentation of the cloud provider you are using or their support for details.

    +

    REGIO.cloud is used as an example here. The cloud name in clouds.yaml +and the environment name (value of ENVIRONMENT) are regiocloud in this case. It is important that +the name of the cloud in clouds.yaml matches the name of the environment to be used. The names must +be identical. It is currently not possible to name the cloud regiocloud-123 in clouds.yaml if the +environment is regiocloud.

    +

    If another cloud is used, replace regiocloud with the respective profile name from the table above.

    +

    The use of application credentials is preferred. This way it is not necessary to store +details like username, project name or sensitive information like the password in the +clouds.yaml file.

    The application credentials can be found in Horizon under Identity. Use OSISM Testbed as +name and click Create Application Credential.

    terraform/clouds.yaml
    clouds:
    regiocloud:
    profile: regiocloud
    auth:
    application_credential_id: ID
    application_credential_secret: SECRET
    auth_type: "v3applicationcredential"

    If you want to make use of terraform/secure.yaml add your application credential secret there +instead of terraform/clouds.yaml.

    terraform/secure.yaml
    clouds:
    regiocloud:
    auth:
    application_credential_secret: SECRET
    +
  6. +
  7. +

    Prepare the deployment.

    +

    The versions of Ansible and OpenTofu are managed +automatically and necessary dependencies are cloned.

    +
    make prepare
    +

    If any error occurs during preparation and you want to run the preparation +again, it is important to run make wipe-local-install first. Otherwise the +preparation will not be redone completely and necessary parts will be missing +later on.

    +
  8. +
  9. +

    Create the infrastructure with OpenTofu.

    +
    make ENVIRONMENT=regiocloud create
    +
  10. +
  11. +

    Deploy the OSISM manager and bootstrap all nodes.

    +
    make ENVIRONMENT=regiocloud manager
    +

    Replace the version with the version you prefer. +Check the OSISM release notes +to find out what's available.

    +
  12. +
  13. +

    After the bootstrap, you can log in to the manager via SSH.

    +
    make ENVIRONMENT=regiocloud login
    +

    Yo can log in to the nodes of the cluster via the manager.

    +
    osism console testbed-node-0
    +
  14. +
  15. +

    Deploy all services.

    +

    It is also possible to deploy the services step by step on the +manager. To do this, first log in to the manager with make ENVIRONMENT=regiocloud login +and then execute the deploy scripts one after the other. It is recommended to do this +within a screen session.

    Deploying the services takes some time and depends on how much bandwidth is available, +how the instances are equipped, etc. 90-120 minutes is not unusual when Ceph and OpenStack +are fully deployed.

    To speed up the Ansible playbooks, ARA can be disabled. This +is done by executing /opt/configuration/scripts/disable-ara.sh. Run this script before the deployment scripts. +Afterwards no more logs are available in the ARA web +interface. To re-enable ARA use /opt/configuration/scripts/enable-ara.sh.

    There is also the option of pre-population of images with /opt/configuration/scripts/pull-images.sh +so that deployments do not have to be lengthy. Run this script before the deployment scripts.

    /opt/configuration/scripts/deploy/001-helper-services.sh
    /opt/configuration/scripts/deploy/005-kubernetes.sh
    /opt/configuration/scripts/deploy/100-ceph-services.sh
    /opt/configuration/scripts/deploy/200-infrastructure-services-basic.sh
    /opt/configuration/scripts/deploy/300-openstack-services-basic.sh
    /opt/configuration/scripts/deploy/400-monitoring-services.sh

    Prepare OpenStack resources like public network, flavors and images by running +/opt/configuration/scripts/bootstrap.sh. Run this script after the deployment scripts.

    info

    If you only want to deploy the monitoring services with /opt/configuration/scripts/deploy/400-monitoring-services.sh, +a few dependencies must be deployed first. You can then use the monitoring services without having to install a +complete OpenStack & Ceph environment.

    osism apply common
    osism apply loadbalancer
    osism apply opensearch
    osism apply mariadb
    +
  16. +
  17. +

    If you want to verify the deployment with refstack run +/opt/configuration/scripts/check.sh. This step will take some time and is optional.

    +
  18. +
  19. +

    The machine images required for the use of Kubernetes Cluster API and the amphora driver of OpenStack Octavia +service are not provided by default to save resources on the OSISM Testbed and improve deployment time. +These can be provisioned if required.

    +
    /opt/configuration/scripts/bootstrap/301-openstack-octavia-amhpora-image.sh
    /opt/configuration/scripts/bootstrap/302-openstack-k8s-clusterapi-images.sh
    +
  20. +
  21. +

    If you want you can create a test project with a test user after login. It also +creates an instance with a volume attached to a network with a router. This step is optional.

    +
    osism apply --environment openstack test
    +
  22. +
  23. +

    When the OSISM Testbed is no longer needed, it can be deleted.

    +
    make ENVIRONMENT=regiocloud clean
    +
  24. +
+

Usage

+

Deployment must be completed at this point.

+

Custom CA

+

The OSISM Testbed deployment currently uses hostnames in the domain testbed.osism.xyz. This is a real domain +and we provide the DNS records matching the addresses used in the OSISM Testbed, so that once you connect to your testbed via a direct +link or Wireguard, you can access hosts and servers by their hostname (e.g. ssh testbed-manager.testbed.osism.xyz).

+

We also provide a wildcard TLS certificate signed by a custom CA for testbed.osism.xyz and *.testbed.osism.xyz. +This CA is always used for each testbed. The CA is not regenerated and it is not planned to change this for the next 10 years.

+

In order for these certificates to be recognized locally as valid, the CA +environments/kolla/certificates/ca/testbed.crt +must be imported locally.

+

VPN access

+

Wireguard

+

Install wireguard on your workstation, if you have not done this before. For instructions how to do +it on your workstation, please have a look on the documentation of your used distribution. The +wireguard documentation you will find here.

+

Start the wireguard tunnel. +(Press CTRL+c to keep the tunnel running forever. The make target also launches a browser tab with references to all services)

+
make vpn-wireguard ENVIRONMENT=regiocloud
+

If you want to connect to the OSISM Testbed from multiple clients, change the client IP +address in the downloaded configuration file to be different on each client.

+

If you only want to download the Wireguard configuration, you can use the vpn-wireguard-config +target. The configuration is then available in the file wg-testbed-regiocloud.conf, for example.

+
make vpn-wireguard-config ENVIRONMENT=regiocloud
+

sshuttle

+

If you do not want to use Wireguard you can also work with sshuttle.

+
make vpn-sshuttle ENVIRONMENT=regiocloud
killall sshuttle
+

Static entries in /etc/hosts

+

If you are unable to access the following domains, you can customize your local /etc/hosts +with the following static entries. This may be necessary, for example, if you use Pi-hole and +all DNS entries from a public DNS with a non-public IP address are filtered.

+
# OSISM Testbed hosts
192.168.16.5 ara.testbed.osism.xyz ara
192.168.16.5 cgit.testbed.osism.xyz cgit
192.168.16.5 flower.testbed.osism.xyz flower
192.168.16.5 homer.testbed.osism.xyz homer
192.168.16.5 netbox.testbed.osism.xyz netbox
192.168.16.5 testbed-manager.testbed.osism.xyz testbed-manager
192.168.16.5 nexus.testbed.osism.xyz nexus
192.168.16.5 phpmyadmin.testbed.osism.xyz phpmyadmin
192.168.16.9 api-int.testbed.osism.xyz api-int
192.168.16.10 testbed-node-0.testbed.osism.xyz testbed-node-0
192.168.16.11 testbed-node-1.testbed.osism.xyz testbed-node-1
192.168.16.12 testbed-node-2.testbed.osism.xyz testbed-node-2
192.168.16.13 testbed-node-3.testbed.osism.xyz testbed-node-3
192.168.16.14 testbed-node-4.testbed.osism.xyz testbed-node-4
192.168.16.15 testbed-node-5.testbed.osism.xyz testbed-node-5
192.168.16.16 testbed-node-6.testbed.osism.xyz testbed-node-6
192.168.16.17 testbed-node-7.testbed.osism.xyz testbed-node-7
192.168.16.18 testbed-node-8.testbed.osism.xyz testbed-node-8
192.168.16.19 testbed-node-9.testbed.osism.xyz testbed-node-9
192.168.16.100 keycloak.testbed.osism.xyz keycloak
192.168.16.254 api.testbed.osism.xyz api
+

Webinterfaces

+

All SSL enabled services within the OSISM Testbed use certs which are signed by the self-signed +OSISM Testbed CA +(Download the file and import it as certification authority to your browser).

+

If you want to access the services please choose the URL from the following table.

+
NameURLUsernamePasswordNote
ARAhttps://ara.testbed.osism.xyzarapassword
Cephhttps://api-int.testbed.osism.xyz:8140adminpassword
Flowerhttps://flower.testbed.osism.xyz
Grafanahttps://api-int.testbed.osism.xyz:3000adminpassword
HAProxy (testbed-node-0)http://testbed-node-0.testbed.osism.xyz:1984openstackpassword
HAProxy (testbed-node-1)http://testbed-node-1.testbed.osism.xyz:1984openstackpassword
HAProxy (testbed-node-2)http://testbed-node-2.testbed.osism.xyz:1984openstackpassword
Homerhttps://homer.testbed.osism.xyz
Horizon (via Keycloak)https://api.testbed.osism.xyzalicepassword
Horizon (via Keystone)https://api.testbed.osism.xyzadminpassworddomain: default
Horizon (via Keystone)https://api.testbed.osism.xyztesttestdomain: test
Keycloakhttps://keycloak.testbed.osism.xyz/authadminpassword
Netboxhttps://netbox.testbed.osism.xyzadminpassword
Netdatahttp://testbed-manager.testbed.osism.xyz:19999
Nexushttps://nexus.testbed.osism.xyzadminpassword
OpenSearch Dashboardshttps://api.testbed.osism.xyz:5601opensearchpassword
Prometheushttps://api-int.testbed.osism.xyz:9091adminpassword
RabbitMQhttps://api-int.testbed.osism.xyz:15672openstackpassword
phpMyAdminhttps://phpmyadmin.testbed.osism.xyzrootpassword
+

Authentication with OIDC

+

Authentication with OpenID Connect (OIDC) is possible via Keycloak, which is automatically configured for the OIDC mechanism.

+

OpenStack web dashboard (Horizon) login via OIDC

+

For logging in via OIDC, open your browser at OpenStack Dashboard Login Page, select Authenticate via Keycloak, after being +redirected to the Keycloak login page, perform the login with the credentials alice and password. +After that you will be redirected back to the Horizon dashboard, where you will be logged in with the user alice.

+

OpenStack web dashboard (Horizon) logout

+

Keep in mind, that clicking Sign Out on the Horizon dashboard currently doesn't revoke your OIDC token, and any consequent +attempt to Authenticate via Keycloak will succeed without providing the credentials.

+

The expiration time of the Single Sign On tokens can be controlled on multiple levels in Keycloak.

+
    +
  1. +

    On realm level under Realm Settings > Tokens. +Assuming the keycloak_realm ansible variable is the default osism, and keycloak is listening on +keycloak.testbed.osism.xyz, then the configuration form is available +here.

    +

    Detailed information is available in the Keycloak Server Administrator Documentation +Session and Token Timeouts section.

    +
  2. +
  3. +

    In a realm down on the client level +select the client (keystone), and under Settings > Advanced Settings.

    +

    It is recommended to keep the Access Token Lifespan on a relatively low value, with the trend of blocking third party +cookies. For further information see the Keycloak documentation's Browsers with Blocked Third-Party Cookies section.

    +
  4. +
+

Usage of the OpenStack CLI

+

The environments/openstack folder contains the needed files for the openstack client:

+
cd environments/openstack
export OS_CLOUD=<the cloud environment> # i.e. admin
openstack floating ip list
+

OpenStack CLI operations with OpenID Connect password

+

Using the OpenStack cli is also possible via OIDC, assuming you provisioned the user alice with password password, +then you can perform a simple project list operation like this:

+

See chapter "Usage the OpenStack CLI" for basic openstack usage.

+
openstack \
--os-cacert /etc/ssl/certs/ca-certificates.crt \
--os-auth-url https://api.testbed.osism.xyz:5000/v3 \
--os-auth-type v3oidcpassword \
--os-client-id keystone \
--os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \
--os-username alice \
--os-password password \
--os-identity-provider keycloak \
--os-protocol openid \
--os-identity-api-version 3 \
--os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \
project list
+

OpenStack CLI token issue with OpenID Connect

+

It is also possible to exchange your username/password to a token, for further use with the cli. +The token issue subcommand returns an SQL table, in which the id column's value field contains the token:

+

See chapter "Usage the OpenStack CLI" for basic openstack usage.

+
openstack \
--os-cacert /etc/ssl/certs/ca-certificates.crt \
--os-auth-url https://api.testbed.osism.xyz:5000/v3 \
--os-auth-type v3oidcpassword \
--os-client-id keystone \
--os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \
--os-username alice \
--os-password password \
--os-identity-provider keycloak \
--os-protocol openid \
--os-identity-api-version 3 \
--os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \
--os-openid-scope "openid profile email" \
token issue \
-c id
-f value
+

An example token is like:

+
gAAAAABhC98gL8nsQWknro3JWDXWLFCG3CDr3Mi9OIlvVAZMjy2mNgYtlXv_0yAIy-
nSlLAaLIGhht17-mwf8uclKgRuNVsYLSmgUpB163l89-ch2w2_OFe9zNSQNWf4qfd8
Cl7E7XvvUoFr1N8Gh09vaYLvRvYgCGV05xBUSs76qCHa0qElPUsk56s5ft4ALrSrzD
4cEQRVb5PXNjywdZk9_gtJziz31A7sD4LPIy82O5N9NryDoDw
+
    +
  • TODO: OpenStack CLI operations with token
  • +
  • TODO: OpenStack CLI token revoke
  • +
+

Advanced Usage

+

External API

+

It is possible to provide the OpenStack APIs and the OpenStack Dashboard via the manager's public IP address. +This is not enabled by default, with the exception of the OTC profile. To provide the OpenStack APIs and the +OpenStack dashboard via the public IP address of the manager, the following changes are necessary in the +terraform/environments/regiocloud.tfvars file. If a cloud other than the REGIO.cloud is used, the profile +of the other cloud is changed accordingly.

+
    +
  1. +

    Add the customisation external_api. This customisation makes sure that the required security group rules +are created for the various OpenStack APIs and the OpenStack dashboard.

    +
    # customisation:external_api
    +
  2. +
  3. +

    Set parameter external_api to true. This makes sure that all necessary changes are made in the configuration +repository when the manager service is deployed. It is correct that this is added as a comment.

    +
    external_api = true
    +
  4. +
  5. +

    After the deployment of the manager service and the OpenStack services, the OpenStack APIs and the OpenStack +dashboard can be reached via a DNS name. The service traefik.me is used for the DNS record. +Run the following two commands on the manager node to get the DNS record.

    +
    $ source /opt/manager-vars.sh
    $ echo "api-${MANAGER_PUBLIC_IP_ADDRESS//./-}.traefik.me"
    api-80-158-46-219.traefik.me
    +
  6. +
+

Change versions

+
    +
  1. Go to /opt/configuration on testbed-manager
  2. +
  3. Run ./scripts/set-openstack-version.sh 2024.2 to set the OpenStack version to 2024.2
  4. +
  5. Run ./scripts/set-ceph-version.sh reef to set the Ceph version to reef
  6. +
  7. Run osism update manager to update the manager service
  8. +
+

Deploy services

+
ScriptDescription
/opt/configuration/scripts/deploy/000-manager-service.sh
/opt/configuration/scripts/deploy/001-helper-services.sh
/opt/configuration/scripts/deploy/100-ceph-services.shAlternative to ceph-ansible
/opt/configuration/scripts/deploy/100-rook-services.sh
/opt/configuration/scripts/deploy/200-infrastructure-services.sh
/opt/configuration/scripts/deploy/300-openstack-services.sh
/opt/configuration/scripts/deploy/310-openstack-services-extended.sh
/opt/configuration/scripts/deploy/400-monitoring-services.sh
/opt/configuration/scripts/deploy/500-kubernetes.sh
/opt/configuration/scripts/deploy/510-clusterapi.sh
+

Upgrade services

+
ScriptDescription
/opt/configuration/scripts/upgrade/100-ceph-services.sh
/opt/configuration/scripts/upgrade/100-rook-services.shAlternative to ceph-ansible
/opt/configuration/scripts/upgrade/200-infrastructure-services.sh
/opt/configuration/scripts/upgrade/300-openstack-services.sh
/opt/configuration/scripts/upgrade/310-openstack-services-extended.sh
/opt/configuration/scripts/upgrade/400-monitoring-services.sh
/opt/configuration/scripts/upgrade/500-kubernetes.sh
/opt/configuration/scripts/upgrade/510-clusterapi.sh
+

Add new OSD in Ceph

+

In the testbed, three volumes per node are provided for use by Ceph by default. Two of +these devices are used as OSDs during the initial deployment. The third device is intended +for testing the addition of a further OSD to the Ceph cluster.

+
    +
  1. Add sdd to ceph_osd_devices in /opt/configuration/inventory/host_vars/testbed-node-0/ceph-lvm-configuration.yml. +The following content is an example, the IDs look different everywhere. Do not copy 1:1 +but only add sdd to the file.
  2. +
+
---
#
# This is Ceph LVM configuration for testbed-node-0
# generated by ceph-configure-lvm-volumes playbook.
#
ceph_osd_devices:
sdb:
osd_lvm_uuid: 95a9a2e0-b23f-55b2-a04f-e02ddfc0e82a
sdc:
osd_lvm_uuid: 29899765-42bf-557b-ae9c-5c7c984b2243
sdd:
lvm_volumes:
- data: osd-block-95a9a2e0-b23f-55b2-a04f-e02ddfc0e82a
data_vg: ceph-95a9a2e0-b23f-55b2-a04f-e02ddfc0e82a
- data: osd-block-29899765-42bf-557b-ae9c-5c7c984b2243
data_vg: ceph-29899765-42bf-557b-ae9c-5c7c984b2243
+
    +
  1. +

    Run osism apply ceph-configure-lvm-volumes -l testbed-node-0

    +
  2. +
  3. +

    Run cp /tmp/testbed-node-0-ceph-lvm-configuration.yml /opt/configuration/inventory/host_vars/testbed-node-0/ceph-lvm-configuration.yml.

    +
  4. +
  5. +

    Run osism reconciler sync

    +
  6. +
  7. +

    Run osism apply ceph-create-lvm-devices -l testbed-node-0

    +
  8. +
  9. +

    Run osism apply ceph-osds -l testbed-node-0 -e ceph_handler_osds_restart=false

    +
  10. +
  11. +

    Check the OSD tree

    +
    $ ceph osd tree
    ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
    -1 0.13640 root default
    -3 0.05846 host testbed-node-0
    2 hdd 0.01949 osd.2 up 1.00000 1.00000
    4 hdd 0.01949 osd.4 up 1.00000 1.00000
    6 hdd 0.01949 osd.6 up 1.00000 1.00000
    -5 0.03897 host testbed-node-1
    0 hdd 0.01949 osd.0 up 1.00000 1.00000
    5 hdd 0.01949 osd.5 up 1.00000 1.00000
    -7 0.03897 host testbed-node-2
    1 hdd 0.01949 osd.1 up 1.00000 1.00000
    3 hdd 0.01949 osd.3 up 1.00000 1.00000
    +
  12. +
+

Ceph via Rook (technical preview)

+

Please have a look at Deploy Guide - Services - Rook and Configuration Guide - Rook for details on how to configure Rook.

+

To deploy this in the testbed, you can use an environment variable in your make target.

+
make CEPH_STACK=rook manager
make CEPH_STACK=rook ceph
+

This will make sure /opt/manager-vars.sh gets CEPH_STACK=rook set which is later being used by:

+
/opt/configuration/scripts/deploy-services.sh
/opt/configuration/scripts/deploy-ceph-services.sh
/opt/configuration/scripts/upgrade/100-rook-services.sh
+

Using testbed for OpenStack development

+

Testbed may be used for doing development on OpenStack services through kolla_dev_mode. +kolla_dev_mode may be activated for all supported service by adding

+
kolla_dev_mode: true
+

to environments/kolla/configuration.yml. This will check out the git repositories of all supported and enabled OpenStack services under /opt/stack and bind mount them into the appropriate containers. +Since this will fetch a lot of repositories it is advisable to enable this only selectively for the services you are going to work on. You can do so by adding a boolean variable to environments/kolla/configuration.yml consisting of the service name and the suffix _dev_mode, e.g.:

+
cinder_dev_mode: true
+

You may customise the used git repository by adding kolla_repos_git to environments/kolla/configuration.yml to specify a common root for the repositories of all services, which will be completed by the service's name, e.g.:

+
kolla_repos_git: "https://github.com/openstack"
+

will pull services from their github mirror. E.g. pull nova from https://github.com/openstack/nova +The complete repository of a single service may be changed by adding a variable consisting of the service name and the suffix _git_repository, e.g.

+
cinder_git_repository: "https://github.com/myorg/my_custom_cinder_fork"
+

You may Specify the git reference globally by setting

+
kolla_source_version: my_feature_branch
+

in environments/kolla/configuration.yml or for specific services via service name and suffix _source_version, e.g.

+
cinder_source_version: my_cinder_feature
+

In order to update the git repositories on kolla-ansible deployments set either

+
kolla_dev_repos_pull: true
+

or, e.g.

+
cinder_dev_repos_pull: true
+

in environments/kolla/configuration.yml to set the setting for all repositories or a service specific one.

+

Thus, as an example for a development workflow:

+
    +
  • Create a git mirror of the OpenStack service you want to work on
  • +
  • In environments/kolla/configuration.yml +
      +
    • Set the corresponding <service name>_dev_mode variable to true
    • +
    • Set the corresponding <service name>_git_repository variable to your development mirror created above
    • +
    • Set the corresponding <service name>_source_version variable to a branch name you intend to push your changes to
    • +
    • Set the corresponding <service name>_dev_repos_pull variable to true
    • +
    +
  • +
  • Commit your changes and push them to the specified branch in the specified mirror
  • +
  • Run osism apply <service name> on the manager to checkout the code on every testbed node
  • +
  • Restart the service containers to actually pick up the new code
  • +
+

Troubleshooting

+

Ansible errors

+

Ansible errors that have something to do with undefined variables (e.g. AnsibleUndefined) are most likely due to cached +facts that are no longer valid. The facts can be updated by running osism apply facts.

+

Unsupported locale setting

+
$ make prepare
ansible-playbook -i localhost, ansible/check-local-versions.yml
ERROR: Ansible could not initialize the preferred locale: unsupported locale setting
make: *** [prepare] Error 1
+

To solve the problem you have to modify the Makefile. Change the 1st line as follows.

+
export LC_ALL=en_US.UTF-8
+

To find out the locale used on the system printenv can be used.

+
$ printenv | grep -i lang|locale
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=
+

Appendix

+

Configuration

+

This section describes how to configure and customise the OSISM Testbed.

+

Variables

+

The defaults for the OpenTofu variables are intended for REGIO.cloud.

+
VariableDefaultNote
availability_zonenova
ceph_versionquincy
cloud_providerregiocloud
configuration_versionmain
deploy_monitoringfalse
dns_nameservers["8.8.8.8", "9.9.9.9"]
enable_config_drivetrue
external_apifalse
flavor_managerSCS-4V-16-50
flavor_nodeSCS-8V-32-50
imageUbuntu 22.04Only Ubuntu 22.04 is currently supported
image_nodeUbuntu 22.04Only Ubuntu 22.04 is currently supported
keypairtestbed
manager_versionlatest
network_availability_zonenova
number_of_nodes3
number_of_volumes3
openstack_version2023.2
prefixtestbed
publicexternal
refstackfalse
volume_availability_zonenova
volume_size_base30
volume_size_storage10
volume_type__DEFAULT__
+

Overrides

+
NameDescription
manager_boot_from_image
manager_boot_from_volume
neutron_availability_zone_hints_network
neutron_availability_zone_hints_router
neutron_router_enable_snat
nodes_boot_from_image
nodes_boot_from_volume
nodes_use_ephemeral_storage
+

Customisations

+
NameDescription
access_floatingip
access_ipv4
access_ipv6
default
external_api
neutron_floatingip
+

Notes

+
    +
  • The configuration is intentionally kept quite static. Please create no PRs to make the configuration more flexible/dynamic.
  • +
  • The OSISM documentation uses hostnames, examples, addresses etc. from OSISM Testbed.
  • +
  • The third volume (/dev/sdd) is not enabled for Ceph by default. This is to test the scaling of Ceph.
  • +
  • The manager is used as pull through cache for Docker images and Ubuntu packages. This reduces the amount of traffic consumed.
  • +
+

Supported releases

+

The following stable Ceph and OpenStack releases are supported.

+

The deployment of Ceph is based on ceph-ansible.

+
    +
  • Ceph Quincy (default)
  • +
  • Ceph Reef
  • +
  • Ceph Squid
  • +
+

The deployment of OpenStack is based on kolla-ansible.

+
    +
  • OpenStack 2023.1
  • +
  • OpenStack 2023.2
  • +
  • OpenStack 2024.1 (default)
  • +
+

The deployment of Kubernetes is based on k3s-ansible.

+
    +
  • Kubernetes v1.30 (default)
  • +
+

Included services

+

The following services can currently be used with the OSISM Testbed without further adjustments.

+

Infrastructure

+
    +
  • Ceph
  • +
  • Cluster API Management Cluster
  • +
  • Fluentd
  • +
  • Gnocchi
  • +
  • Grafana
  • +
  • Haproxy
  • +
  • Keepalived
  • +
  • Keycloak
  • +
  • Kubernetes
  • +
  • Mariadb
  • +
  • Memcached
  • +
  • Netbox
  • +
  • Netdata
  • +
  • Opensearch
  • +
  • Openvswitch
  • +
  • Prometheus exporters
  • +
  • Rabbitmq
  • +
  • Redis
  • +
+

OpenStack

+
    +
  • Barbican
  • +
  • Ceilometer
  • +
  • Cinder
  • +
  • Designate
  • +
  • Glance
  • +
  • Heat
  • +
  • Horizon
  • +
  • Ironic
  • +
  • Keystone
  • +
  • Magnum
  • +
  • Manila
  • +
  • Neutron
  • +
  • Nova (with Libvirt/KVM)
  • +
  • Octavia
  • +
  • Skyline
  • +
+

Makefile reference

+
$ make help

Usage:
make <target>
help Display this help.
clean Destroy infrastructure with OpenTofu.
wipe-local-install Wipe the software dependencies in `venv`.
create Create required infrastructure with OpenTofu.
login Log in on the manager.
vpn-wireguard Establish a wireguard vpn tunnel.
vpn-sshuttle Establish a sshuttle vpn tunnel.
bootstrap Bootstrap everything.
manager Deploy only the manager service.
identity Deploy only identity services.
ceph Deploy only ceph services.
deploy Deploy everything and then check it.
prepare Run local preperations.
deps Install software preconditions to `venv`.

$ make <TAB> <TAB>
+

CI jobs

+

You can inspect the results of the daily zuul jobs.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/troubleshooting-guide/ceph/index.html b/docs/iaas/guides/troubleshooting-guide/ceph/index.html new file mode 100644 index 0000000000..06d0d9135e --- /dev/null +++ b/docs/iaas/guides/troubleshooting-guide/ceph/index.html @@ -0,0 +1,47 @@ + + + + + +Ceph | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Ceph

+

Where to find docs

+

The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/troubleshooting/

+

It is strongly advised to use the documentation for the version being used.

+ +

Critical medium error

+

The block device sdf has errors. You can see this in the kernel ring buffer, for example.

+
$ sudo dmesg
[...]
[14062414.575715] sd 14:0:5:0: [sdf] tag#2120 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=1s
[14062414.575722] sd 14:0:5:0: [sdf] tag#2120 Sense Key : Medium Error [current] [descriptor]
[14062414.575725] sd 14:0:5:0: [sdf] tag#2120 Add. Sense: Unrecovered read error
[14062414.575728] sd 14:0:5:0: [sdf] tag#2120 CDB: Read(16) 88 00 00 00 00 01 09 7c d9 50 00 00 00 80 00 00
[14062414.575730] critical medium error, dev sdf, sector 4454144360 op 0x0:(READ) flags 0x0 phys_seg 13 prio class 2
+

It may also be displayed in the health details of Ceph.

+
$ ceph -s
[...]
health: HEALTH_WARN
Too many repaired reads on 1 OSDs
[...]

$ ceph health detail
HEALTH_WARN Too many repaired reads on 1 OSDs
[WRN] OSD_TOO_MANY_REPAIRS: Too many repaired reads on 1 OSDs
osd.17 had 13 reads repaire
+

In this case the block device sdf is in the storage node sto1001. The OSD assigned +to this block device can be determined.

+
$ ceph device ls | grep 'sto1001:sdf'
SEAGATE_ST16000NM004J_ZR604ZDZ0000C210PWE9 sto1001:sdf osd.17
+

If you only know the OSD ID, you can also determine the associated block device and the storage node.

+
$ ceph device ls | grep osd.17
[...]
SEAGATE_ST16000NM004J_ZR604ZDZ0000C210PWE9 sto1001:sdf osd.17
+

The broken OSD can be removed from the Ceph cluster. The Ceph cluster is then rebalanced. +This can take some time and cause a high level of activity on the Ceph cluster.

+
$ ceph osd out osd.17
marked out osd.17.
+

On the storage node disable the OSD service for the OSD.

+
$ sudo systemctl stop ceph-osd@17.service
+ + \ No newline at end of file diff --git a/docs/iaas/guides/troubleshooting-guide/index.html b/docs/iaas/guides/troubleshooting-guide/index.html new file mode 100644 index 0000000000..535d033de3 --- /dev/null +++ b/docs/iaas/guides/troubleshooting-guide/index.html @@ -0,0 +1,25 @@ + + + + + +Troubleshooting Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/troubleshooting-guide/manager/index.html b/docs/iaas/guides/troubleshooting-guide/manager/index.html new file mode 100644 index 0000000000..7f7261041f --- /dev/null +++ b/docs/iaas/guides/troubleshooting-guide/manager/index.html @@ -0,0 +1,62 @@ + + + + + +Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Manager

+

Reset

+

Sometimes it is necessary to reset the entire manager service.

+
warning

This is a disruptive action. Data is lost in the process. For example, the database +of the ARA service.

+
    +
  1. +

    Stop the manager service

    +
    sudo systemctl stop docker-compose@manager.service
    +
  2. +
  3. +

    Files on the /share volume are backed up in advance and restored after +the manager service is started.

    +
    docker run --rm \
    --mount source=manager_share,target=/share \
    --volume $(pwd):/backup \
    busybox \
    tar -czvf /backup/manager-share-$(date +%Y%m%d).tar.gz /share
    +
  4. +
  5. +

    Delete the manager service. This is a disruptive action.

    +
    docker compose --project-directory /opt/manager down -v
    +
  6. +
  7. +

    Start the manager service

    +
    sudo systemctl start docker-compose@manager.service
    +
  8. +
  9. +

    Restore the files on the /share volume.

    +
    docker run --rm \
    --mount source=manager_share,target=/share \
    --volume $(pwd):/backup \
    busybox \
    tar -xzvf /backup/manager-share-$(date +%Y%m%d).tar.gz -C /
    +
  10. +
  11. +

    Check that manager service is healthy

    +
    docker compose --project-directory /opt/manager ps
    +

    Depending on what the manager service looks like, this output may vary.

    +
    NAME                             IMAGE                                        COMMAND                  SERVICE                CREATED              STATUS                        PORTS
    ceph-ansible quay.io/osism/ceph-ansible:quincy "/entrypoint.sh osis…" ceph-ansible About a minute ago Up About a minute (healthy)
    kolla-ansible quay.io/osism/kolla-ansible:2023.2 "/entrypoint.sh osis…" kolla-ansible About a minute ago Up About a minute (healthy)
    manager-api-1 quay.io/osism/osism:latest "osism service api" api About a minute ago Up About a minute (healthy) 192.168.16.5:8000->8000/tcp
    manager-ara-server-1 quay.io/osism/ara-server:latest "sh -c '/wait && /ru…" ara-server About a minute ago Up About a minute (healthy) 8000/tcp
    manager-beat-1 quay.io/osism/osism:latest "osism service beat" beat About a minute ago Up About a minute (healthy)
    manager-conductor-1 quay.io/osism/osism:latest "osism worker conduc…" conductor About a minute ago Up About a minute (healthy)
    manager-flower-1 quay.io/osism/osism:latest "osism service flower" flower About a minute ago Up About a minute (healthy)
    manager-inventory_reconciler-1 quay.io/osism/inventory-reconciler:latest "/sbin/tini -- /entr…" inventory_reconciler About a minute ago Up About a minute (healthy)
    manager-listener-1 quay.io/osism/osism:latest "osism service liste…" listener About a minute ago Up About a minute (healthy)
    manager-mariadb-1 index.docker.io/library/mariadb:11.3.2 "docker-entrypoint.s…" mariadb About a minute ago Up About a minute (healthy) 3306/tcp
    manager-netbox-1 quay.io/osism/osism-netbox:latest "osism worker netbox" netbox About a minute ago Up About a minute (healthy)
    manager-openstack-1 quay.io/osism/osism:latest "osism worker openst…" openstack About a minute ago Up About a minute (healthy)
    manager-redis-1 index.docker.io/library/redis:7.2.4-alpine "docker-entrypoint.s…" redis About a minute ago Up About a minute (healthy) 6379/tcp
    manager-watchdog-1 quay.io/osism/osism:latest "osism service watch…" watchdog About a minute ago Up About a minute (healthy)
    osism-ansible quay.io/osism/osism-ansible:latest "/entrypoint.sh osis…" osism-ansible About a minute ago Up About a minute (healthy)
    osismclient quay.io/osism/osism:latest "sleep infinity" osismclient About a minute ago Up About a minute
    +
  12. +
  13. +

    When the manager service is healthy, the inventory and the fact cache +must be rebuilt.

    +
    osism reconciler sync
    osism apply facts
    +
  14. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/troubleshooting-guide/openstack/index.html b/docs/iaas/guides/troubleshooting-guide/openstack/index.html new file mode 100644 index 0000000000..64e08647e5 --- /dev/null +++ b/docs/iaas/guides/troubleshooting-guide/openstack/index.html @@ -0,0 +1,69 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

OpenStack

+

Database creation fails

+

Problem:

+
TASK [keystone : Creating keystone database] ***********************************
fatal: [testbed-node-0]: FAILED! => changed=false
action: mysql_db
msg: 'unable to find /var/lib/ansible/.my.cnf. Exception message: (2003, "Can''t connect to MySQL server on ''api-int.local'' ([Errno 111] Connection refused)")'
+

Solution:

+

Restart the kolla_toolbox container. in this case on the node testbed-node-0.

+
$ osism console testbed-node-0/
testbed-node-0>>> restart kolla_toolbox
kolla_toolbox
testbed-node-0>>>
+

Ceph connections not working

+
    +
  • +

    Problem: auth: error parsing file or auth: failed to load

    +
    $ docker exec -ti nova_compute ceph -k /etc/ceph/ceph.client.nova.keyring -n client.nova -s
    2024-06-28T06:43:05.660+0000 7d5df526b640 -1 auth: error parsing file /etc/ceph/ceph.client.nova.keyring: cannot parse buffer: Malformed input
    2024-06-28T06:43:05.660+0000 7d5df526b640 -1 auth: failed to load /etc/ceph/ceph.client.nova.keyring: (5) Input/output error
    2024-06-28T06:43:05.664+0000 7d5df526b640 -1 auth: error parsing file /etc/ceph/ceph.client.nova.keyring: cannot parse buffer: Malformed input
    2024-06-28T06:43:05.664+0000 7d5df526b640 -1 auth: failed to load /etc/ceph/ceph.client.nova.keyring: (5) Input/output error
    2024-06-28T06:43:05.664+0000 7d5df526b640 -1 auth: error parsing file /etc/ceph/ceph.client.nova.keyring: cannot parse buffer: Malformed input
    2024-06-28T06:43:05.664+0000 7d5df526b640 -1 auth: failed to load /etc/ceph/ceph.client.nova.keyring: (5) Input/output error
    2024-06-28T06:43:05.664+0000 7d5df526b640 -1 auth: error parsing file /etc/ceph/ceph.client.nova.keyring: cannot parse buffer: Malformed input
    2024-06-28T06:43:05.664+0000 7d5df526b640 -1 auth: failed to load /etc/ceph/ceph.client.nova.keyring: (5) Input/output error
    2024-06-28T06:43:05.664+0000 7d5df526b640 -1 monclient: keyring not found
    [errno 5] RADOS I/O error (error connecting to the cluster)
    +

    Solution:

    +

    Check your Ceph keyfiles. Probably a missing newline at the EOF.

    +
  • +
+

Cinder volume create failure

+
    +
  • +

    Problem: Volume creation is stuck after creation of the database object with no host assigned.

    +

    Solution:

    +

    Database objects are created by the API service for valid request while the host is assigned by the scheduler.

    +
      +
    • Check the scheduler logs for errors
    • +
    • If there is nothing wrong with the scheduler itself, check the communication between the services via oslo.messaging +Usually this is done via rabbitmq: +
        +
      • Check cluster status on every node for status, alarms and network partitions +
        docker exec rabbitmq rabbitmqctl cluster_status
        +
      • +
      • Check rabbitmq logs for errors
      • +
      • Check rabbitmq queues for errors or accumulated messages +
        docker exec rabbitmq rabbitmqctl list_queues name type state consumers messages | grep -E '^cinder'
        +
      • +
      +
    • +
    • If everything seems fine check network connectivity to rule out network issues +
      osism validate kolla-connectivity
      +
    • +
    • If networking is fine then as a last resort a reset of rabbitmq may be considered +Beware that this will destroy rabbitmq state which may result in inconsitent resource states +
      osism apply rabbitmq-reset-state
      +
    • +
    +
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/troubleshooting-guide/rookify/index.html b/docs/iaas/guides/troubleshooting-guide/rookify/index.html new file mode 100644 index 0000000000..ce20924e99 --- /dev/null +++ b/docs/iaas/guides/troubleshooting-guide/rookify/index.html @@ -0,0 +1,43 @@ + + + + + +Rookify (Technical Preview) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Rookify (Technical Preview)

+
warning

Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime. +Nevertheless, it is strongly advised to test Rookify in a controlled environment first, such as the OSISM testbed. Additionally ensure that precautionary backups are made and all other necessary safety measures are in place.

+

For a condensed summary of the information covered here, refer to the Rookify GitHub repository.

+

SSH Issues

+

"Failed to load private key"

+
    +
  • Ensure the id-rsa keys are "clean" and do not contain unexpected strings like "<<EOF".
  • +
  • Clean the keys manually, or use the following command to reformat the keyfile: ssh-keygen -p -N "" -f ssh.key.
  • +
+

"Too many authentications error"

+
    +
  • This can occur if too many keys are loaded by the ssh-agent.
  • +
  • Disable the ssh-agent on your machine. You can do this manually or by allowing direnv to use .envrc with the command direnv allow. To install direnv on your machine refer to Direnv's documentation
  • +
+

Frozen State

+
    +
  • If the Rookify process freezes, check your connections.
  • +
  • In the OSISM testbed, ensure the VPN connection is active. For help to setup the VPN connection for the Testbed refer to OSISM's documentation for testbed setup.
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/ceph/index.html b/docs/iaas/guides/upgrade-guide/ceph/index.html new file mode 100644 index 0000000000..7fe6cd1c6a --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/ceph/index.html @@ -0,0 +1,27 @@ + + + + + +Ceph | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/docker/index.html b/docs/iaas/guides/upgrade-guide/docker/index.html new file mode 100644 index 0000000000..af25c60ab9 --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/docker/index.html @@ -0,0 +1,83 @@ + + + + + +Docker | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Docker

+

The Docker version used is defined via the parameter docker_version in the file +environments/configuration.yml.

+
docker_version: '5:20.10.24'
+

All installable versions can be displayed with apt-cache madison docker-ce.

+
$ apt-cache madison docker-ce
docker-ce | 5:24.0.6-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:24.0.5-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:24.0.4-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:24.0.3-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:24.0.2-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:24.0.1-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:24.0.0-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.6-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.5-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.4-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.3-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.2-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.1-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.0-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.24~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.23~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.22~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.21~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.20~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.19~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.18~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.17~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.16~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.15~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.14~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.13~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
+

If, for example, you want to change the Docker version from 20.10.24 to 24.0.6, docker_version in +environments/configuration.yml is changed accordingly. The 5: prefix is placed in front of the version. Commit and push the changes to your configuration repository afterwards.

+

The upgrade of Docker is then done with the OSISM CLI. Docker on the manager itself is updated differently. +This does not work on the manager itself because the Docker service may be started during the upgrade and +individual containers may be started as a result. This would interrupt the run of the role itself.

+
osism apply docker -l 'docker:!manager'
+

By default, serial is set to 1 so that the the hosts are upgrade one after the other. +To adjust this, either use the osism_serial dictionary in the environments/configuration.yml file +to change the value in docker or append -e serial=10% to upgrade, for example, 10% +with each iteration.

+

Please note that it is not a good idea to upgrade more than one Docker service at a time. +This can lead to anomalies, especially on storage nodes and control nodes. It is recommended +not to change the default of 1.

+
osism_serial:
docker: 10%
+

On the manager itself, the run.sh script in the manager environment of the configuration must +currently be used to upgrade the Docker service. In a future release a dedicated osism update docker +command will be available for this purpose.

+
cd /opt/configuration/environments/manager
ANSIBLE_ASK_VAULT_PASS=True ./run.sh docker
+

Restart behaviour

+

When upgrading, the Docker service is restarted. As a result, it can come to a restart of the +running containers. This can lead to interruptions in individual services. A change in +/etc/docker/daemon.json due to a new configuration parameter etc. can also result in a +required restart.

+

Whether the containers are restarted when the Docker Service is restarted depends on whether the +Live Restore feature is used. +This can be configured via the parameter docker_live_restore. Live restore is enabled by default.

+

It is important to set the docker_live_restore parameter explicitly as a string. This means +docker_live_restore: "false" or docker_live_restore: "true".

+

But even if the Live Restore feature is enabled, certain upgrades will cause running containers +to be restarted:

+
+

Live restore allows you to keep containers running across Docker daemon updates, but is only +supported when installing patch releases (YY.MM.x), not for major (YY.MM) daemon upgrades.

+
+

There are two ways to prevent a restart of the Docker service during an upgrade.

+

If the restart behaviour of the Docker service is changed, always make sure to restart the +Docker service manually afterwards (e.g. by a system reboot).

+
    +
  1. +

    A host group can be defined via the parameter docker_ignore_restart_groupname. The +restart of the Docker service is not triggered for all hosts in this group. By default, +docker_ignore_restart_groupname is set to manager. The parameter is best set in the +environments/configuration.yml file when making an adjustment. For example, to prevent +the restart on all hosts, docker_ignore_restart_groupname is set to generic.

    +
    docker_ignore_restart_groupname: generic
    +
  2. +
  3. +

    With the parameter docker_allow_restart, the restart of the Docker service can be +prevented. By default, docker_allow_restart is set to true. It is recommended to set +this parameter only at runtime. Otherwise, the best place for the parameter is the +environments/configuration.yml file.

    +
    osism apply docker -e docker_allow_restart=false
    +
  4. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/index.html b/docs/iaas/guides/upgrade-guide/index.html new file mode 100644 index 0000000000..c2eeae657b --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/index.html @@ -0,0 +1,28 @@ + + + + + +Upgrade Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Upgrade Guide

+

In the examples, the pull of images (if supported by a role) is always run first. While +this is optional, it is recommended to speed up the execution of the upgrade action in +the second step. This significantly reduces the times required for the restart from a +service.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/infrastructure/index.html b/docs/iaas/guides/upgrade-guide/infrastructure/index.html new file mode 100644 index 0000000000..d21669e203 --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/infrastructure/index.html @@ -0,0 +1,61 @@ + + + + + +Infrastructure | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Infrastructure

+
    +
  1. +

    Kubernetes

    +

    This is only necessary if the internal Kubernetes cluster has also been deployed. +This can be checked by executing kubectl get nodes on the manager node.

    +
    osism apply k3s-upgrade
    +
  2. +
  3. +

    Cron, Fluentd & Kolla Toolbox

    +

    The common role of Kolla is used to manage the services cron, fluentd +and kolla-toolbox.

    +

    It is important to do this upgrade before any other upgrades in the Kolla +environment, as parts of the other upgrades depend on the kolla-toolbox +service.

    +
    osism apply -a pull common
    osism apply -a upgrade common
    +
  4. +
  5. +

    Loadbalancer

    +
    osism apply -a pull loadbalancer
    osism apply -a upgrade loadbalancer
    +
  6. +
  7. +

    Redis

    +
    osism apply -a pull redis
    osism apply -a upgrade redis
    +
  8. +
  9. +

    Memcached

    +
    osism apply -a pull memcached
    osism apply -a upgrade memcached
    +
  10. +
  11. +

    RabbitMQ

    +
    osism apply -a pull rabbitmq
    osism apply -a upgrade rabbitmq
    +
  12. +
  13. +

    MariaDB

    +
    osism apply -a pull mariadb
    osism apply -a upgrade mariadb
    +
  14. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/logging-monitoring/index.html b/docs/iaas/guides/upgrade-guide/logging-monitoring/index.html new file mode 100644 index 0000000000..12bac158aa --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/logging-monitoring/index.html @@ -0,0 +1,39 @@ + + + + + +Logging & Monitoring | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Logging & Monitoring

+
    +
  1. +

    OpenSearch

    +

    OpenSearch dashboards is also upgraded with the opensearch role.

    +
    osism apply -a pull opensearch
    osism apply -a upgrade opensearch
    +
  2. +
  3. +

    Prometheus

    +
    osism apply -a pull prometheus
    osism apply prometheus
    +
  4. +
  5. +

    Grafana

    +
    osism apply -a pull grafana
    osism apply -a upgrade grafana
    +
  6. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/manager/index.html b/docs/iaas/guides/upgrade-guide/manager/index.html new file mode 100644 index 0000000000..5224c63bda --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/manager/index.html @@ -0,0 +1,78 @@ + + + + + +Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Manager

+
warning

Always read the release notes first to learn what has changed and what +adjustments are necessary. Read the release notes even if you are only updating from e.g. 7.0.2 to 7.0.5.

+

The update of a manager service with a stable release of OSISM is described here. +In the example, OSISM release 7.0.5 is used.

+
    +
  1. +

    Change the OSISM release in the configuration repository.

    +

    1.1. Set the new OSISM version in the configuration repository.

    +
    MANAGER_VERSION=7.0.5
    sed -i -e "s/manager_version: .*/manager_version: ${MANAGER_VERSION}/g" environments/manager/configuration.yml
    +

    1.2. If openstack_version or ceph_version are set in environments/manager/configuration.yml +(or anywhere else), they must be removed. If these are set, the stable release is not used for +these components.

    +

    1.3. Sync the image versions and files in the configuration repository.

    +
    make sync
    +

    1.4. Commit and push all changes in the configuration repository. Since everyone here has their own +workflows for changes to the configuration repository, only a generic example for Git.

    +
    git commit -a -s -m "manager: use OSISM version 7.0.5"
    git push
    +
  2. +
  3. +

    Update the configuration repository on the manager node.

    +
    osism apply configuration
    +
  4. +
  5. +

    Update the manager service on the manager node.

    +
    osism update manager
    +
      +
    • If Ansible Vault was used to encrypt environments/manager/secrets.yml, the parameter +--ask-vault-pass is also appended. From OSISM >= 8.0.0 this is no longer necessary.
    • +
    • If osism update manager does not work yet, use osism-update-manager instead.
    • +
    +
  6. +
  7. +

    Refresh the facts cache.

    +
    osism apply facts
    +
  8. +
  9. +

    If Traefik is used on the manager node (traefik_enable: true in environments/infrastructure/configuration.yml) +then Traefik should also be upgraded.

    +
    osism apply traefik
    +
  10. +
  11. +

    Finally, the Ansible vault password must be made known again.

    +
    osism set vault password
    +
  12. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/network/index.html b/docs/iaas/guides/upgrade-guide/network/index.html new file mode 100644 index 0000000000..1b9e75e6ee --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/network/index.html @@ -0,0 +1,38 @@ + + + + + +Network | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Network

+
    +
  1. +

    Open vSwitch (OVS)

    +
    osism apply -a pull openvswitch
    osism apply -a upgrade openvswitch
    +
  2. +
  3. +

    Open Virtual Network (OVN)

    +

    In environments/kolla/configuration.yml the parameter neutron_plugin_agent is set to +ovn. The parameter is set to ovn by default in the Cookiecutter and is the OSISM default.

    +
    environments/kolla/configuration.yml
    # neutron
    neutron_plugin_agent: "ovn"
    +

    Before the upgrade of OVN, the upgrade of Open vSwitch must already have been done.

    +
    osism apply -a pull ovn
    osism apply -a upgrade ovn
    +
  4. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/openstack/index.html b/docs/iaas/guides/upgrade-guide/openstack/index.html new file mode 100644 index 0000000000..5f571cc1d4 --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/openstack/index.html @@ -0,0 +1,80 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

OpenStack

+
info

When upgrade the different OpenStack services, all containers must be +restarted. When restarting the API services, there is a short downtime +of the APIs. This downtime is usually less than 1 minute.

+
    +
  1. +

    OpenStack client

    +
    osism apply openstackclient
    +
  2. +
  3. +

    Keystone

    +
    osism apply -a pull keystone
    osism apply -a upgrade keystone
    +
  4. +
  5. +

    Glance

    +
    osism apply -a pull glance
    osism apply -a upgrade glance
    +
  6. +
  7. +

    Designate

    +
    osism apply -a pull designate
    osism apply -a upgrade designate
    +
  8. +
  9. +

    Placement

    +
    osism apply -a pull placement
    osism apply -a upgrade placement
    +
  10. +
  11. +

    Cinder

    +
    osism apply -a pull cinder
    osism apply -a upgrade cinder
    +
  12. +
  13. +

    Neutron

    +
    osism apply -a pull neutron
    osism apply -a upgrade neutron
    +
  14. +
  15. +

    Nova

    +
    osism apply -a pull nova
    osism apply -a upgrade nova
    +
  16. +
  17. +

    Octavia

    +
    osism apply -a pull octavia
    osism apply -a upgrade octavia
    +

    9.1. Update amphora image

    +

    This step is only necessary if the Amphora Driver is used. If OVN is used as the driver, +this step is not necessary.

    +

    We provide regularly updated images for Octavia in +osism/openstack-octavia/amphora-image. +The OSISM CLI can be used to upload the correct image depending on the OpenStack release +used.

    +
    osism manage image octavia
    +

    9.2. Amphora rotation

    +

    This step is only necessary if the Amphora driver is used. If OVN is used as the driver, +this step is not necessary.

    +
  18. +
  19. +

    Horizon

    +
    osism apply -a pull horizon
    osism apply -a upgrade horizon
    +
  20. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/index.html b/docs/iaas/guides/user-guide/index.html new file mode 100644 index 0000000000..b5e1844d96 --- /dev/null +++ b/docs/iaas/guides/user-guide/index.html @@ -0,0 +1,24 @@ + + + + + +User Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/migration-vmware-esxi/index.html b/docs/iaas/guides/user-guide/migration-vmware-esxi/index.html new file mode 100644 index 0000000000..33b25daaa4 --- /dev/null +++ b/docs/iaas/guides/user-guide/migration-vmware-esxi/index.html @@ -0,0 +1,153 @@ + + + + + +Migrate from VMware ESXi to OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Migrate from VMware ESXi to OpenStack

+

This guide is an example of how to perform a manual migration from a VMware ESXi host to OpenStack. +Migration to OpenStack always depends very much on the use case. It is not possible to document an +approach or to write a tool that works for all use cases. This guide shows one possible way. There are many ways to +perform a migration. A migration must always be carefully prepared and tested in advance.

+

At this point, we would also like to point out the open source project +cloudbase/coriolis from Cloudbase. There are also commercial +providers that perform migration from VMware ESXi to OpenStack. One of the offerings is +Hystax Acura Live Cloud Migration. +Migratekit from Vexxhost is another option for migrating VMWare to OpenStack.

+

A good overview and comparison of VMWare resources and their OpenStack counterparts is available here.

+

Scenario

+
    +
  • Source: ESXi 7.0 host
  • +
  • Destination: OpenStack
  • +
  • a security group (web_ssh) is already available at the destination
  • +
  • a Linux converter host is installed and ready, we also have root access to it
  • +
  • an IPv4 address (10.50.40.230) will be given manually out of a preconfigured network
  • +
  • we migrate one host with a kernel newer then 2.6.25 with two scsi harddrives attached and one networkcard
  • +
  • destination openstack using Libvirt/KVM as virtualisation
  • +
  • the converter host has access to ESXi and the OpenStack environment over IP network
  • +
+

Requirements

+
    +
  • +

    VMware credentials

    +
      +
    • SSH enabled on ESXi host
    • +
    • access to the webinterface of the ESXi host
    • +
    +
  • +
  • +

    OpenStack credentials

    +
  • +
  • +

    Linux packages installed on the coverter, in this case it is an Ubuntu 22.04

    +
    apt-get install qemu-utils python3-openstackclient
    +
  • +
  • +

    twice the space of the largest vmdk disc image on the converter or nfs access to the image files with enough storage

    +
  • +
+

Prechecks

+

Check the /etc/fstab file of your VMware ESXi host you want to move. See how all the discs or paritions are mounted. +If they are all mounted by LVM or UUID you do not need to change anything.

+
cat /etc/fstab
/dev/mapper/vg00-lvroot /               ext4    errors=remount-ro 0       1
/dev/mapper/vg00-lvboot /boot ext2 defaults 0 2
/dev/mapper/vg00-lvhome /home ext4 defaults 0 2
/dev/mapper/vg00-lvvar /var ext4 defaults 0 2
/dev/mapper/vg00-lvswap none swap sw 0 0
/dev/mapper/vgdata-lvsrv /srv ext4 defaults 0 2
+

If they are mounted like /dev/sda it is better to change the /etc/fstab to UUID mounting using blkid.

+

Replace these entries with UUID=filesystems_uuid and add the rest of the line same as with the devicenames.

+

Example:

+
example devicename fstab
/dev/sda1 /boot     ext2  defaults          0       2
/dev/sda2 / ext4 errors=remount-ro 0 1
+

Change it to something like this:

+
example uuid fstab
UUID=574c96bf-f2cb-49b8-9196-232a24047f94 /boot     ext2  defaults          0       2
UUID=93cc3b34-36c3-422e-b7a6-c80439e8f431 / ext4 errors=remount-ro 0 1
+
caution

When creating a new server, OpenStack uses /dev/vd* or /dev/sd* as devices for volumes. +Using UUID/LVM mounts will ensure that the kernel will find your devices while booting. +Using old device names may lead to the boot sequence to get stuck, due to missing devices.

+

Also check your NIC interface configuration as the devicenames can change to a new devicename.

+

This depends on the udev or systemd setup of your specific system.

+

It needs to be changed to either DCHP if you want to use floating IPs or static IP of the new network.

+

Migration

+
note

Shutdown the host in VMware as the movement is only possible while the host is offline. +Otherwise you will get corrupted disc files.

+

You can use either the webinterface or SSH to identify and copy the *.vmdk files of your VMware ESXi host.

+

While using the web interface you need to locate the datastore and the directoy where the disc files are +located and start downloading all vmdk files. You will always get files files for a disc, a smaller and a +larger one, both are required.

+

When using SSh, please also copy both vmdk files for the disc to the converter host. Start looking up your +files under /vmfs/volumes/.

+

How to copy vmdk images

+

Example SSH copy and path of all vmdk files to the converter host using the scp command for our testing-host:

+
scp user@vmhost:/vmfs/volumes/datastore1/testing-host/*.vmdk .
+

After copying is finished, we find several vmdk files in our directory. +We copied two disc images:

+
testing-host-disc0-flat.vmdk testing-host-disc1.vmdk
testing-host-disc0.vmdk testing-host-disc1-flat.vmdk
+

How to convert vmdk to raw

+
note

Now convert those vmdk files into raw images with the following flags:

-p show progress (optional)
-f Input Format
-O Output Format

Raw files are required to import images into OpenStack.

+
qemu-img convert -p -f vmdk -O raw testing-host-disc0.vmdk testing-host-disc0.raw
+

Repeat this step for each disc image you need to convert.

+

Edit the raw Images (optional)

+
note

This step is completely optional and you should have some Linux knowledge to do this.

+

After converting the images of a Linux host, you now have the possibilty to edit some settings offline before importing the images into OpenStack.

+

By mounting the raw image files you can edit the configuration files to, e.g.:

+
    +
  • disable mountpoints at the fstab, like nfs server
  • +
  • change the ip config of the networkcard to dhcp or fixed ip
  • +
  • adjust resolv.conf
  • +
  • adjust routing
  • +
+

On Ubuntu you can use losetup to mount the raw image as a loopdevice to mount it somewhere you have access to.

+
losetup -f -P testing-host-disc0.raw
losetup -l

mount /dev/loop0p1 /mnt/test/
or
lvscan and mount the lvm volume
+

How to import Images

+

First of all you need your OpenStack credentials, having them in an my-project-openrc.sh file and source them to your shell.

+

The openstack cli client is now able to connect to the cloud environment and do all the following steps.

+

To get your credentials please check with your OpenStack provider.

+

If you want to preserve the /dev/sd* device names of the mountpoints, you must inject the new image and add some properties while uploading it into the OpenStack environment or add them later on to the images with Horzion web interface or openstack cli client.

+
openstack image create --progress --property hw_disk_bus=scsi --property hw_scsi_model=virtio-scsi --property hw_watchdog_action=reset --disk-format raw --private --file testing-host-disc0.raw  testing-host-image-disc0
+
openstack image list
+--------------------------------------+------------------------------+--------+
| ID | Name | Status |
+--------------------------------------+------------------------------+--------+
| 2a12b545-5d09-4ca1-9a76-b57f8d2489be | testing-host-disc0 | active |
| b34744f7-6ef6-4282-a001-08a06812e381 | testing-host-disc1 | active |
+--------------------------------------+------------------------------+--------+
+

How to create your server

+

The previously imported images need to be copied to a volume so the server is also able to evict to other hosts in the cluster, +so lets create and start our server in OpenStack.

+

Select one flavor for the host, in this case SCS-8V-16, which means 8 Virtual CPUs and 16GB of RAM, get a list of all your available flavors by executing +openstack flavor list and select the best matching one.

+

As the images are 20GB, you tell openstack that you need a boot volume with a size of 20 and a block-device for the additional device also with a size of 20GB.

+

In this guide there is already a security group which fits our needs, if not, create one or you will not be able to communicate with your new host.

+
openstack security group list
+--------------------------------------+-----------------+------------------------------+----------------------------------+------+
| ID | Name | Description | Project | Tags |
+--------------------------------------+-----------------+------------------------------+----------------------------------+------+
| 4fd1d060-bf1d-4f5a-8e80-fde975d41f5f | default | Default security group | c9aa53cc3c654692b14a8f81a88cfa2f | [] |
| 73967e73-e8d5-4318-b621-a06e7496fec3 | web_ssh | Webserver security group | c9aa53cc3c654692b14a8f81a88cfa2f | [] |
+--------------------------------------+-----------------+------------------------------+----------------------------------+------+
+

The web_ssh group will be attached to the server.

+

Now you need to tell which network you want to deploy your host on, optionally including a fixed IPv4 address.

+

You can repeat the --nic for additional nics in your server, in this guide it's the my_corp_net.

+
openstack network list
+--------------------------------------+-------------------+--------------------------------------+
| ID | Name | Subnets |
+--------------------------------------+-------------------+--------------------------------------+
| 9688192e-11dd-4618-a18c-99d3267f630a | my_corp_net | 0d502fdb-be73-457a-8678-79eb6088a9a1 |
| 98842b77-c070-4532-a2a9-99d588c4e947 | internet | 2dfc3916-972f-44d1-afdb-6f89488ef3a4 |
| c846238a-b00a-4c73-87e3-3614d94f46fd | my_other_corp_net | b8210b4e-5d91-425a-b05c-ca5d4bf8329a |
+--------------------------------------+-------------------+--------------------------------------+
+

As last parameter, you give the server name of your migrated system.

+

As we are starting an already configured system we do not need to inject SSH keys or passwords as they should already be present on the host.

+
openstack server create --flavor SCS-8V-16 \
--image 2a12b545-5d09-4ca1-9a76-b57f8d2489be --boot-from-volume 20 \
--security-group 73967e73-e8d5-4318-b621-a06e7496fec3 \
--nic net-id=9688192e-11dd-4618-a18c-99d3267f630a,v4-fixed-ip=10.50.40.230 \
--block-device uuid=b34744f7-6ef6-4282-a001-08a06812e381,source_type=image,destination_type=volume,volume_size=20 \
--os-compute-api-version 2.90 testing-host
+

Show your new server

+
openstack server list
+--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+
| 71a8b930-4212-434a-8891-afdeeb1802dc | testing-host | ACTIVE | my_network=10.50.40.230 | N/A (booted from volume) | SCS-8V-16 |
+--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+
+

To see the attached volumes and their mountpoints:

+
openstack server volume list 71a8b930-4212-434a-8891-afdeeb1802dc
+----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+
| Device | Server ID | Volume ID | Tag | Delete On Termination? | Attachment ID | BlockDeviceMapping UUID |
+----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+
| /dev/sda | 71a8b930-4212-434a-8891-afdeeb1802dc | 71902b03-48ea-483c-a6a3-6c47b9d8537b | None | False | 3cd241ff-5296-4bb1-9ba0-d743cb8c8f31 | 2d08e835-156f-4f71-8c95-7ff828230b8e |
| /dev/sdb | 71a8b930-4212-434a-8891-afdeeb1802dc | 15a835a3-5149-49a8-8e2b-a81ef8097c35 | None | False | 9deeb06b-718b-49d4-84a4-87dabc34ba56 | 04483f95-0333-4b37-92e6-db604e4ddc7c |
+----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+
+

How to access the VNC console

+

To get the VNC URL for console login use:

+
openstack console url show 71a8b930-4212-434a-8891-afdeeb1802dc
+----------+-------------------------------------------------------------------------------------------+
| Field | Value |
+----------+-------------------------------------------------------------------------------------------+
| protocol | vnc |
| type | novnc |
| url | https://vnc.your.cloud/vnc_lite.html?path=%3Ftoken%3Db9b6920d-e533-4728-8132-a5a0adfc24e5 |
+----------+-------------------------------------------------------------------------------------------+
+

This will print out the VNC URL for the videoconsole connection to your host.

+

Now the server will boot and be available.

+

Maybe you need to tweak the network setup if it is still not accessible. +To do this, you could use the VNC console of the OpenStack host:

+

Login and then setup the network card if you have not already done that before host had been shutdown.

+

You now can remove the imported images, as they are no longer required - except you want to generate +another host with the same images.

+

Last words

+

In this little guide, we only can give a sneak peak of what you need to do with a simple VMware ESXi host. +More complex setups needs consulting, planning and testing as there a several scenarios out there which +cannot be handled like this. +Especially if you have terrabytes of data to move or graphics- or AIcards in you VMware ESXi hosts.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/openstack/index.html b/docs/iaas/guides/user-guide/openstack/index.html new file mode 100644 index 0000000000..f18460f5f5 --- /dev/null +++ b/docs/iaas/guides/user-guide/openstack/index.html @@ -0,0 +1,24 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/openstack/install-instance-from-iso/index.html b/docs/iaas/guides/user-guide/openstack/install-instance-from-iso/index.html new file mode 100644 index 0000000000..1fbf3abe0f --- /dev/null +++ b/docs/iaas/guides/user-guide/openstack/install-instance-from-iso/index.html @@ -0,0 +1,56 @@ + + + + + +Install instance from ISO image | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Install instance from ISO image

+

While in general it is considered best practice to create instances from existing or specially crafted images, sometimes it is necessary to install an instance using a traditional installer packaged in an ISO image. +One way to do this in OpenStack is to leverage the instance rescue mechanism, which allows to boot an instance from another image while providing access to the instances storage.

+

Upload the ISO image

+

If the required ISO image is not available in the image store yet upload it first:

+
PATH_TO_ISO_IMAGE=""
IMAGE_NAME=""
openstack image create \
--disk-format iso \
--file $PATH_TO_ISO_IMAGE \
--property hw_rescue_device=disk \
--property hw_rescue_bus=virtio \
$IMAGE_NAME
+

The hw_rescue_device and hw_rescue_bus properties may be omitted if you do not intent to create an instance from a boot volume.

+

Creating the instance

+

Using nova local storage

+

Create an instance with a blank local boot device, e.g.:

+

Until this bug is fixed, one cannot create an instance with a blank local boot device. As a workaround create an unbootable dummy image first, e.g.:

+
DUMMY_IMAGE_NAME="dummy"
dd if=/dev/zero of="$DUMMY_IMAGE_NAME" bs=1k count=1
openstack image create \
--file "$DUMMY_IMAGE_NAME" \
"$DUMMY_IMAGE_NAME"
rm "$DUMMY_IMAGE_NAME"
+

Create the instance:

+
INSTANCE_NAME=""
FLAVOR=""
openstack server create \
--flavor "$FLAVOR" \
--image "$DUMMY_IMAGE_NAME" \
--no-network \
"$INSTANCE_NAME"
+

Once the bug is fixed the instance may be created directly:

+
INSTANCE_NAME=""
FLAVOR=""
openstack server create \
--flavor "$FLAVOR" \
--block-device "source_type=blank,destination_type=local,guest_format=raw,boot_index=0" \
--no-network \
"$INSTANCE_NAME"
+

Using boot from volume

+

Create an instance with a blank boot volume

+
INSTANCE_NAME=""
FLAVOR=""
BOOT_VOLUME_SIZE=""
openstack server create \
--flavor "$FLAVOR" \
--block-device "source_type=blank,destination_type=volume,volume_size=$BOOT_VOLUME_SIZE,boot_index=0" \
--no-network \
"$INSTANCE_NAME"
+

Set the created volume to bootable

+
openstack volume set --bootable $(openstack server show $INSTANCE_NAME -f json -c attached_volumes | jq -r '.attached_volumes | first | .id')
+

Install the created instance from the uploaded ISO

+

Use the rescue mechanism to boot the ISO, e.g.:

+
openstack server rescue \
--image $IMAGE_NAME \
$INSTANCE_NAME
+

Wait for the instance to be rescued. This will take a moment, as a soft reboot is tried before issueing a hard reboot. +Watch the instance task_state and status to see the latter change from ACTIVE to RESCUE.

+
watch openstack server show $INSTANCE_NAME -f value -c status -c task_state
+

Start the installation procedure, e.g. by opening the instance's console

+
openstack console url show $INSTANCE_NAME
+

The instances storage device should be available as a destination for the installation. +Rebooting the instance in this state will lead to the rescue image being booted again. +To boot the instance from its freshly provisioned boot device unrescue the instance:

+
openstack server unrescue $INSTANCE_NAME
+ + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/openstack/openstackclient/index.html b/docs/iaas/guides/user-guide/openstack/openstackclient/index.html new file mode 100644 index 0000000000..d6faf85403 --- /dev/null +++ b/docs/iaas/guides/user-guide/openstack/openstackclient/index.html @@ -0,0 +1,58 @@ + + + + + +Client | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Client

+

OpenStackClient looks for a clouds.yaml configuration file in the following locations:

+
    +
  • current directory
  • +
  • ~/.config/openstack
  • +
  • /etc/openstack
  • +
+

With the OpenStack client you can specify the cloud profile specified in the clouds.yaml +configuration file by providing the --os-cloud <cloud identifier> parameter.

+
openstack --os-cloud openstack network list
+

Migration from openrc to clouds.yaml

+

If you have your openrc file but you need this information in a clouds.yaml file, +this can easily be converted.

+

With an editor

+

Example content of a openrc file downloaded from Horizon dashboard.

+
PROJECT-openrc.sh
#!/usr/bin/env bash
# To use an OpenStack cloud you need to authenticate against the Identity
# service named keystone, which returns a **Token** and **Service Catalog**.
# The catalog contains the endpoints for all services the user/tenant has
# access to - such as Compute, Image Service, Identity, Object Storage, Block
# Storage, and Networking (code-named nova, glance, keystone, swift,
# cinder, and neutron).
#
# *NOTE*: Using the 3 *Identity API* does not necessarily mean any other
# OpenStack API is version 3. For example, your cloud provider may implement
# Image API v1.1, Block Storage API v2, and Compute API v2.0. OS_AUTH_URL is
# only for the Identity API served through keystone.
export OS_AUTH_URL=https://api.testbed.osism.xyz:5000/v3
# With the addition of Keystone we have standardized on the term **project**
# as the entity that owns the resources.
export OS_PROJECT_ID=PROJECT_ID
export OS_PROJECT_NAME="PROJECT"
export OS_USER_DOMAIN_NAME="DOMAIN"
if [ -z "$OS_USER_DOMAIN_NAME" ]; then unset OS_USER_DOMAIN_NAME; fi
export OS_PROJECT_DOMAIN_ID="DOMAIN_ID"
if [ -z "$OS_PROJECT_DOMAIN_ID" ]; then unset OS_PROJECT_DOMAIN_ID; fi
# unset v2.0 items in case set
unset OS_TENANT_ID
unset OS_TENANT_NAME
# In addition to the owning entity (tenant), OpenStack stores the entity
# performing the action as the **user**.
export OS_USERNAME="USERNAME"
# With Keystone you pass the keystone password.
echo "Please enter your OpenStack Password for project $OS_PROJECT_NAME as user $OS_USERNAME: "
read -sr OS_PASSWORD_INPUT
export OS_PASSWORD=$OS_PASSWORD_INPUT
# If your configuration has multiple regions, we set that information here.
# OS_REGION_NAME is optional and only valid in certain environments.
export OS_REGION_NAME="RegionOne"
# Don't leave a blank variable, unset it if it was empty
if [ -z "$OS_REGION_NAME" ]; then unset OS_REGION_NAME; fi
export OS_INTERFACE=public
export OS_IDENTITY_API_VERSION=3
+

First you need to create a clouds.yaml file. Take care of the indentation and +use spaces instead of tabs.

+
clouds.yaml
clouds:
openstack:
auth:
auth_url: <OS_AUTH_URL goes here>
password: <OS_PASSWORD goes here, if not set, enter you password here>
project_domain_name: <OS_PROJECT_DOMAIN_NAME goes here>
project_name: <OS_PROJECT_NAME goes here>
user_domain_name: <OS_USER_DOMAIN_NAME goes here>
username: <OS_USERNAME goes here>
region_name: <OS_REGION_NAME goes here>
identity_api_version: <OS_IDENTITY_API_VERSION goes here>
interface: <OS_INTERFACE goes here>
+

The final clouds.yaml for your openrc will then look like this one. The content +from the previous PROJECT-openrc.sh example was used here.

+
clouds.yaml
clouds:
openstack:
auth:
auth_url: https://api.testbed.osism.xyz:5000/v3
password: PASSWORD
project_domain_name: DOMAIN
project_name: PROJECT
user_domain_name: DOMAIN
username: USERNAME
region_name: RegionOne
identity_api_version: 3
interface: public
+

With a script

+

Python

+
clouds.py
import os
import yaml

clouds = {
"clouds":{
"openstack": {
"auth" : {
"auth_url" : os.environ["OS_AUTH_URL"],
"project_name": os.environ["OS_PROJECT_NAME"],
"project_domain_name": os.environ["OS_PROJECT_DOMAIN_NAME"],
"username": os.environ["OS_USERNAME"],
"user_domain_name": os.environ["OS_USER_DOMAIN_NAME"],
"password": os.environ["OS_PASSWORD"],
},
"region_name": os.environ["OS_REGION_NAME"],
"identity_api_version": os.environ["OS_IDENTITY_API_VERSION"],
"interface": "public"
}
}
}

print(yaml.dump(clouds))
+

Source: Adam Young's Web Log

+

First you need to source your openrc file so that the OS_ variables are available.

+
source PROJECT-openrc.sh
+

Now you can execute the Python script and a clouds.yaml will be written.

+
python3 clouds.py > clouds.yaml
+

Bash

+

You need to point the source line to your openrc file first. Then execute the Bash script. +This will create the clouds.yaml file in your currect directory

+
#!/bin/bash

source PROJECT-openrc.sh

PROJECT_ID=$(openstack project list | grep $OS_PROJECT_NAME | awk '{print $2}')

cat << EOF > clouds.yaml
clouds:
openstack:
auth:
auth_url: $OS_AUTH_URL
username: "$OS_USERNAME"
password: "$OS_PASSWORD"
project_name: "$OS_PROJECT_NAME"
project_id: "$PROJECT_ID"
user_domain_name: "$OS_USER_DOMAIN_NAME"
region_name: "$OS_REGION_NAME"
interface: "public"
identity_api_version: $OS_IDENTITY_API_VERSION
EOF
+

Source: Andreas Karis Blog

+ + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/openstack/security-groups/index.html b/docs/iaas/guides/user-guide/openstack/security-groups/index.html new file mode 100644 index 0000000000..f7365e5add --- /dev/null +++ b/docs/iaas/guides/user-guide/openstack/security-groups/index.html @@ -0,0 +1,108 @@ + + + + + +How to configure and use security groups | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

How to configure and use security groups

+

Security groups in OpenStack are part of the network security mechanisms provided for the users. +They resemble sets of simple firewall rules allowing specific network traffic at a Port of a VM that connects it to a network. +The rules allow specific network port numbers and protocols while also differentiating between ingress and egress directions. +Usually security groups are assigned to the Port(s) when a virtual machine is created, but assignments can also be changed at runtime later on. +Multiple security groups can be assigned to a VM or Port simultaneously and in such case they will be combined as the union of all their rules.

+
caution

Security groups are mutable resources. +Their rules can be adjusted at any time after creation. +Changing the rules of a security group will immediately apply the changes to all Ports or VMs it is assigned to. +It is advisable to always review resources which use a security group before making changes to it.

+

Identify the requirements of your setup

+

Every virtual machine that is created may need different firewall rules. +These requirements can also change over time. +Adding or removing security groups will allow users to adapt the firewall rules specifically to their virtual machines.

+

To harden the firewall settings for your virtual machine you may follow these steps:

+
    +
  1. Before creating a virtual machine its purpose is usually already known. Use this information to identify all incoming and outgoing traffic rules that will be needed based on the communication patterns of the services it is meant to deploy. This includes communication protocols, port numbers, communication directions and optionally target/source address ranges.
  2. +
  3. Look through already existing security groups and their rules. If a security group allows more traffic than needed it SHOULD NOT be used. If a security group contains only a subset of the required rules it MAY be used in combination with other security groups that contain rules which fulfill the remaining required traffic rules from point 1.
  4. +
  5. If you were not successful in finding an appropriate combination of existing security groups or you need additional specific rules to cover all requirements, you MAY create one or more new Security Groups in which you can add the required rules.
  6. +
  7. After ensuring the existence of one or more security groups that fulfill your requirements, you can create the VM with those security groups already specified in the creation command.
  8. +
+

Further security considerations

+

When implementing network security requirements, firewall rules alone are not always sufficient and might need to be augmented with additional configuration or time-based constraints. Notable examples are:

+

SSH +SSH is needed on many virtual machines to operate their guest operating system. +In a security group the port 22 can be opened for the TCP protocol to allow incoming SSH connections. +But that only should be done while also restricting the SSH configuration to public key authentication only (the recommended way) or having a strong username and password policy already applied to the operating system of the virtual machine. +Otherwise default usernames and passwords which are often preconfigured in system images may be exploited through the exposed SSH port which enables attackers to compromise the virtual machine.

+

ICMP +It might be useful to be able to ping a virtual machine or use other ICMP requests. +But for some virtual machine configurations this is either not necessary at all or only temporarily needed. +One benefit of security groups among other things is the ability to be easily added to and removed from existing virtual machines. +So a dedicated security group allowing ICMP could be added temporarily to a virtual machine for debugging purposes and removed from it afterwards.

+

How to create security groups

+

Security groups are managed within a project. +So every project will have a different set of security groups. +They can be added dynamically to each virtual machine, during their creation or afterwards. +Additionally, they may also be removed from VMs at any point.

+

Every project has its own default security group, which rules can be edited. +Additionally other security groups can be added until the project's quota is exhausted. +To add a security group, use the following command:

+
openstack security group create $SECURITY_GROUP
+

Within every security group rules can be added up unto a defined maximum of rules, that usually is about 100. +Rules can be added to security groups with the following command:

+
openstack security group rule create [...] $SECURITY_GROUP
+

To delete rules from a security group, the rule id has to be used. +It is listed in the details of the rules section of the security group.

+
openstack security group rule delete $RULE_ID
+

Default security group

+

Unless specified otherwise, the default security group is assigned to all VMs or Ports at creation. +To use any other than the default security group at creation it is necessary to specify the desired security group(s) during the creation process.

+

To review which rules are defined in a security group, the following command can be used:

+
openstack security group show default
+ +

While projects can use very different aspects in security group rules and thus the security groups will always differ between projects, there are some security groups that are widely used. +Through the nature of security groups being seen as a set of rules that can be combined, having some basic security groups that allow basic protocols is a commonly used setup. +This section will demonstrate how to create some security groups for commonly used protocols and ports.

+
    +
  1. A security groups, that allows incoming SSH traffic:
  2. +
+
openstack security group create ssh
openstack security group rule create --ingress --protocol tcp --dst-port 22 ssh
+
    +
  1. A security group, that allows incoming HTTP requests:
  2. +
+
openstack security group create http
openstack security group rule create --ingress --protocol tcp --dst-port 80 http
+
    +
  1. A security group, that allows incoming HTTPS requests:
  2. +
+
openstack security group create https
openstack security group rule create --ingress --protocol tcp --dst-port 443 https
+
    +
  1. A security group, that allows incoming ICMP requests:
  2. +
+
openstack security group create icmp
openstack security group rule create --protocol icmp icmp
+

How to use security groups

+
info

Security groups can be assigned to multiple resources simultaneously (such as VMs or Ports). +This means that security groups are reusable and don't need to be recreated for each applicable resource individually.

+

Usually, initial security groups are added at the time of the creation of a VM. +During creation, multiple security groups can also be added at the same time by repeating the --security-group argument:

+
openstack server create [...] --security-group $SECURITY_GROUP_1 --security-group $SECURITY_GROUP_2 $SERVER_NAME
+

To add a security group to an existing VM, the following command can be used:

+
openstack server add security group $SERVER_NAME $SECURITY_GROUP
+

To remove a security group from a VM, the following command can be used:

+
openstack server remove security group $SERVER_NAME $SECURITY_GROUP
+

The source of this document can be found in the SovereignCloudStack/docs repository.

+

Author: SCS Community, License: CC by Attribution 4.0 International

+ + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/openstack/user-data-backups/index.html b/docs/iaas/guides/user-guide/openstack/user-data-backups/index.html new file mode 100644 index 0000000000..2df986130a --- /dev/null +++ b/docs/iaas/guides/user-guide/openstack/user-data-backups/index.html @@ -0,0 +1,251 @@ + + + + + +User Data Backups | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

User Data Backups

+

This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.

+

Glossary

+
TermExplanation
Virtual MachineEquals the server resource in Nova.
Ephemeral StorageDisk storage directly supplied to a virtual machine by Nova. Different from volumes.
(Glance) ImageIaaS resource usually storing raw disk data. Managed by the Glance service.
(Cinder) VolumeIaaS resource representing block storage disk that can be attached as a virtual disk to virtual machines. Managed by the Cinder service.
(Volume) SnapshotThinly-provisioned copy-on-write snapshots of volumes. Stored in the same Cinder storage backend as volumes.
Volume TypeAttribute of volumes determining storage details of a volume such as backend location or whether the volume will be encrypted.
(Barbican) SecretIaaS resource storing cryptographic assets such as encryption keys. Managed by the Barbican service.
+

Scope

+

User data in the context of this guide describes data accumulated in cloud resources of a user at runtime. +This concerns primarily storage data of virtual machines stored at at-rest. +This does not cover in-transit or in-use data such as network traffic, virtual machines' RAM contents or IaaS configuration and metadata of cloud resources.

+

Overview of applicable User Data

+

Given the mentioned scope, the following can be classified as user data:

+
    +
  • images stored in Glance
  • +
  • virtual machine disks, either: +
      +
    • Ephemeral Storage stored in Nova
    • +
    • volumes stored in Cinder
    • +
    +
  • +
  • encryption keys stored as secrets in Barbican
  • +
+

The following sections will describe backup procedures for each of those resources individually.

+

Image backup using download

+

Glance images may act as backup targets for other resources (such as volumes) but don't have a dedicated backup service for themselves.

+

When an image is to be backed up, it can be downloaded from the Glance image service and stored outside of the IaaS infrastructure for backup purposes. +In this case it is the user's responsibility to establish the backup procedure and appropriate target storage.

+
caution

When creating images from volumes with a volume type that uses encryption, the resulting image will contain the raw LUKS-encrypted blocks of the volume. +When transferred outside of the IaaS infrastructure, this data is only useful as a backup together with the corresponding encryption key.

Such images can be identified by an attribute called cinder_encryption_key_id in the properties metadata field of the image. +It only exists for encrypted images and references the encryption key in Barbican. +Refer to the Barbican secrets section for instructions on how to backup the key.

+

The API or the OpenStack client may be used to initiate the download, for example:

+
openstack image save --file $TARGET_FILE_PATH $IMAGE_NAME_OR_ID
+

This or the underlying API request may be automated as part of a regular backup schedule involving the backup storage target on the user side.

+

Ephemeral Storage backup using Glance images

+
caution

When using the createImage Compute API action (e.g. via the openstack server image create command) on a virtual machine that has volumes attached to it in addition to its Ephemeral Storage disk, the volumes will not be backed up into the image. Instead, a snapshot will be created for each attached volume and referenced in the image metadata. This does not replace genuine volume backups.

See the corresponding appendix section for further details.

+

Ephemeral Storage disks of virtual machines can be backed up to Glance images easily by using the createImage Compute API action or the corresponding OpenStack client command:

+
openstack server image create --name $IMAGE_NAME $SERVER_NAME_OR_ID
+

This will create a Glance image containing a one-to-one copy of the data on the Ephemeral Storage disk at the time of execution.

+

If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.

+

Volume data backup using Cinder Backup API

+

The following instructions only apply if the infrastructure offers the Cinder Backup API.

+
note

Backups of volumes using a volume type that uses encryption will retain their encryption and a clone of the original encryption key is created in Barbican linked to the backup. +These backups can only be restored when the Barbican service is available and still has the corresponding copy of the encryption key.

Also, it is advised to take note of the exact volume type when creating a backup of an encrypted volume, because this information will be needed to restore the backup. +See restoring an encrypted volume backup.

+
info

It might be difficult or even impossible for a user to transfer backups created by the Cinder Backup API outside of the IaaS infrastructure, depending on the backup backend. +A more easily accessible backup of volumes can be created by using Glance images. +See the section about volume data backup using Glance images for details.

+

Backup of detached volumes

+

Backups can be created using the Cinder Backup API or the corresponding OpenStack client commands:

+
openstack volume backup create $VOLUME_NAME_OR_ID
+

Further backups of the same volume can subsequently be created as incremental backups using the following command:

+
openstack volume backup create --incremental $VOLUME_NAME_OR_ID
+

Backup of attached volumes

+
note

When creating backups of attached (in-use) volumes, the state of the full volume is captured at runtime. Backups created this way will be crash-consistent but not app-consistent.

+

In case of attached (in-use) volumes, backups can only be created while also specfiying the force parameter:

+
openstack volume backup create --force $VOLUME_NAME_OR_ID
+

Further backups of the same volume can subsequently be created as incremental backups using the following command:

+
openstack volume backup create --force --incremental $VOLUME_NAME_OR_ID
+

Volume data backup using Glance images

+

In case the Cinder Backup storage is not available in the IaaS infrastructure, Glance images can be used as a backup target instead. +Such images may also subsequently be downloaded to transfer the backup outside of the IaaS infrastructure.

+
note

Glance image backups of Cinder volumes only allow full backup copies and do not offer incremental or differential backup mechanisms.

+

Glance image backups of detached volumes

+

Volumes not attached to virtual machines can be directly copied into an image. +Such volumes can be identified by their status being available. +To backup a detached volume to a Glance image, directly use the corresponding image creation action:

+
openstack image create --volume $VOLUME_NAME_OR_ID $IMAGE_NAME
+

After the image creation has finished, a full backup copy of the volume will reside in the Glance storage backend.

+

If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.

+

Glance image backups of attached (in-use) volumes

+

Cinder is unable to directly create Glance images from volumes which are attached to virtual machines. +To create backups of such volumes regardless, a detour using volume snapshots can be used which will be described below.

+
note

When creating snapshots of attached (in-use) volumes, the force parameter has to be used. These snapshots capture a state of the full volume at runtime. They will be crash-consistent but not app-consistent.

+
    +
  1. Create a snapshot of the target volume while including the force parameter in the request: +
      +
    • openstack volume snapshot create --volume $VOLUME_NAME_OR_ID $SNAPSHOT_NAME
    • +
    +
  2. +
  3. Create a new temporary volume based on the snapshot to act as backup source: +
      +
    • openstack volume create --snapshot $SNAPSHOT_NAME $TEMP_VOLUME_NAME
    • +
    +
  4. +
  5. Wait until the volume creation is finished and the temporary volume reaches the available status.
  6. +
  7. Create a backup image of the temporary volume: +
      +
    • openstack image create --volume $TEMP_VOLUME_NAME $IMAGE_NAME
    • +
    +
  8. +
  9. Wait until the image creation finishes and the target image reaches the active status.
  10. +
  11. Delete the temporary volume and snapshot: +
      +
    • openstack volume delete $TEMP_VOLUME_NAME
    • +
    • openstack volume snapshot delete $SNAPSHOT_NAME
    • +
    +
  12. +
+

A full backup copy of the volume now resides in the Glance storage backend.

+

If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.

+

Barbican secrets backup using download

+
danger

Secrets downloaded from Barbican will be in plaintext, which means that the secret is unprotected once received from the API. +Before downloading secrets from Barbican make sure that a secure target environment is established for receiving and securely storing the secret's contents.

+

Barbican secrets can be downloaded in plaintext using the corresponding API or client command:

+
openstack secret get --file $TARGET_FILE_PATH --payload_content_type "application/octet-stream" $SECRET_ID
+
tip

In case the secret needs to be restored into an OpenStack Barbican later on, it is recommended to also note down the following attributes shown by openstack secret get $SECRET_ID:

    +
  • Algorithm
  • +
  • Bit length
  • +
  • Secret type
  • +
  • Mode
  • +
+

Retrieving encryption keys from Barbican

+

In case of encrypted volumes (i.e. using a volume type with encryption), a corresponding encryption key is stored in Barbican. +When an image is created from such a volume, the encryption key is duplicated in Barbican for the image. +In order to backup those keys, the corresponding secret must first be identified.

+

For volumes, this is possible starting with the Volume API microversion 3.64:

+
openstack volume show --os-volume-api-version 3.64 $VOLUME_NAME_OR_ID
+

The response will contain an encryption_key_id field with the ID of the Barbican secret.

+

For images, the secret reference is stored in the properties field instead:

+
openstack image show -f value -c properties $IMAGE_NAME_OR_ID
+

In case of images created from encrypted volumes, the resulting output will have a nested cinder_encryption_key_id field that contains the ID of the Barbican secret.

+

The resulting IDs can be used to retrieve the corresponding key using the Barbican instructions above.

+
caution

Note that the key retrieved from the secret is not immediately usable as LUKS passphrase to the image data of the volume. +OpenStack does some processing to the key before it is passed to the LUKS encryption, which must be mimicked accordingly in order to unlock the encryption outside of OpenStack!

See the example procedure for converting the LUKS key in the appendix section.

+

Restore

+

The following sections will illustrate how to restore the individual resource backups that have been documented above.

+

Restoring a backup of a Barbican secret

+
note

Note that restoring a Barbican secret by re-uploading it via the Barbican API will lead to the secret receiving a new ID. +Existing resources referencing an old secret ID cannot make use of the restored copy.

+
openstack secret store --algorithm aes --bit-length 256 --mode cbc \
--secret-type symmetric --file $KEY_FILE_PATH --name $SECRET_NAME
+

Notes:

+
    +
  • Attributes like algorithm, bit length, mode and secret type are not verified by Barbican. Their main purpose is to classify the secret on a metadata level. Make sure to align the attributes with the original secret.
  • +
  • $KEY_FILE_PATH is the local file path of the secret backup as created originally using the instructions above.
  • +
  • $SECRET_NAME is entirely optional but helps identifying the restored secret later on and to distinguish it from secrets created by OpenStack itself. It is best to not put whitespace characters in the name, otherwise it has to be surrounded by quotes.
  • +
+

The successful registration of the restored secret can subsequently be verified using:

+
openstack secret list --name $SECRET_NAME
+

Restoring a backup of an unencrypted image

+

Unencrypted image backups can simply be restored using the regular image upload functionality and specifying the backup file:

+
openstack image create --file $IMAGE_FILE_PATH $IMAGE_NAME
+
note

In case the original image backup was not based on a volume originally, the image may have had a non-default disk or container format. +In this case, add the command parameters --container-format and --disk-format to the command accordingly.

+

Restoring a backup of an encrypted image

+

The following section only applies to image backups that were originally created from images of encrypted volumes.

+

First, restore the corresponding secret of the image using the instructions above. +The restored secret will receive a new ID in the form of a UUID. +Note down the ID of the restored secret and insert it in place of $SECRET_ID in the command below.

+
openstack image create --file $IMAGE_FILE_PATH \
--property cinder_encryption_key_id=$SECRET_ID \
--property cinder_encryption_key_deletion_policy=on_image_deletion \
$IMAGE_NAME
+

The cinder_encryption_key_deletion_policy attribute is optional. +If not specified, the referenced secret will not be deleted on image deletion automatically. +In contrast, if set to on_image_deletion, the referenced secret will be deleted as soon as the image referencing it is deleted.

+

Restoring a volume backup from an image

+

To restore a volume from an image backup, simply use the volume creation action and specify the image as source.

+

Depending on whether the original volume the image was created from was encrypted or not, the target volume type might need to be specified accordingly. +Whether this is the case can be identified by inspecting the image's metadata using openstack image show $IMAGE_NAME_OR_ID and looking for a "cinder_encryption_key_id" field within "properties". +If it exists, the source volume of the image was encrypted.

+

To restore the image of an unencrypted volume:

+
openstack volume create --image $IMAGE_NAME_OR_ID \
--size $VOLUME_SIZE_IN_GB $VOLUME_NAME
+

To restore the image of an encrypted volume:

+
openstack volume create --image $IMAGE_NAME_OR_ID \
--type $ENCRYPTED_VOLUME_TYPE \
--size $VOLUME_SIZE_IN_GB $VOLUME_NAME
+

If restoring an encrypted image, make sure to specify $ENCRYPTED_VOLUME_TYPE correctly and have it reference a volume type which also supports the encryption. +Otherwise the volume will be unbootable or unusable by Nova instances.

+

Restoring a volume backup from the Cinder Backup service

+

The Cinder Backup service offers dedicated API actions and commands for restoring volume backups created using the service. +These backups can be restored in one of two ways:

+
    +
  1. Letting the Cinder Backup service create a new volume based on the backup.
  2. +
  3. Overwriting an existing volume with the backup data.
  4. +
+
note

If the volume backup was originally created from a volume that used a non-default encrypted volume type, letting Cinder Backup create a new volume for backup restoration does not work and the volume type must match exactly. +In such case provision an empty volume with the correct type first and then restore the backup onto it as explained further down.

+

Restoring to a new volume (Cinder Backup)

+
openstack volume backup restore $BACKUP_NAME_OR_ID $TARGET_NAME
+

... where $TARGET_NAME is the desired name of the new volume to be created. +Make sure that no volume with this name already exists. +The Cinder Backup service will create the volume with the same size as the backup indicates.

+

Restoring on an existing volume (Cinder Backup)

+

As an alternative to creating a new volume as the restore target, the backup can also be restored on an existing volume:

+
openstack volume backup restore --force $BACKUP_NAME_OR_ID $VOLUME_NAME_OR_ID
+

... which will overwrite the data on the existing volume, regardless of whether it is empty or not!

+

The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.

+

Restoring an encrypted volume backup (Cinder Backup)

+

When restoring a volume backup of a volume that was using a non-default encrypted volume type, a new volume of that type needs to be created first and then the backup restored onto it. +Otherwise, the restoration will fail with the target volume ending up in the "error_restoring" state. +For this procedure to succeed it is necessary to know the exact volume type of the volume the backup was created from.

+

If the source volume of the backup still exists, the original volume type can be determined by inspecting the backup's volume_id attribute and then using it to look up the corresponding volume and its type attribute. +The following client command can be used for this (fill in the value for BACKUP_ID):

+
export BACKUP_ID=...

SOURCE_VOLUME_ID="$(openstack volume backup show $BACKUP_ID -f value -c volume_id)"
openstack volume show -f value -c type "$SOURCE_VOLUME_ID"
+

This returns the name of the original volume type. +If the source volume does not exist anymore, rely on documentation about the backup to determine the type, if available.

+

First, create a new empty volume as the restore target and use the backup's size metadata attribute to match the size of the volume to the backup:

+
openstack volume create --size $BACKUP_SIZE --type $VOLUME_TYPE $TARGET_NAME
+

... where $TARGET_NAME is the desired name of the new volume.

+

Once the volume reaches "available" state, restore the backup onto it:

+
openstack volume backup restore --force $BACKUP_NAME_OR_ID $TARGET_NAME
+

The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.

+

Appendix

+

Image creation action for servers with attached volumes

+

When the createImage action of the Compute API (openstack server image create) is used on virtual machines that have at least one volume attached, a snapshot will be created for each attached volume individually and referenced in the resulting image's metadata.

+

This happens regardless of whether the virtual machine has an Ephemeral Storage disk attached. +In case of an Ephemeral Storage disk, only the Ephemeral Storage is copied into the Glance image as a 1:1 copy.

+

In case of a virtual machine that has no Ephemeral Storage but only volumes, the createImage action leads to a Glance image that only consists of metadata (including the resulting volume snapshot references) but carries no actual binary data.

+

Figure: createImage action flow involving Ephemeral Storage and/or volumes

+

LUKS encryption key conversion to decrypt volume images

+

The volume encryption keys stored in Barbican are not directly used as LUKS passphrases by OpenStack because they are in binary format. +OpenStack converts them to ASCII internally before passing them to the encryption layer. +This behavior needs to be reproduced if a decryption of a volume image is desired outside of OpenStack.

+
danger

The instructions below will expose plaintext data of encryption keys and encrypted volume images. +Make sure to only execute these steps in a secure and trusted environment.

+

First, download the image:

+
openstack image save --file image.raw $IMAGE_NAME_OR_ID
+

Next, inspect the image metadata, determine the reference to the encryption key (cinder_encryption_key_id property) and download the encryption key:

+
openstack image show -f value -c properties $IMAGE_NAME_OR_ID
# (use the value of `cinder_encryption_key_id` as `$SECRET_ID` below)
openstack secret get --file image.key --payload_content_type "application/octet-stream" $SECRET_ID
+

This will result in the following local files:

+
    +
  • image.raw = the raw encrypted image downloaded from Glance
  • +
  • image.key = the LUKS encryption key in binary format (plaintext)
  • +
+

Since OpenStack internally uses Python's binascii.hexlify() to convert the binary encryption key before passing it as a passphrase to the LUKS encryption, as a last step this conversion must be mimicked to unlock the encryption:

+
python3 -c "import binascii; \
f = open('image.key', 'rb'); \
print(binascii.hexlify(f.read()).decode('utf-8'))" \
| sudo cryptsetup luksOpen ./image.raw decrypted_image
+

The decrypted image is now accessible at /dev/mapper/decrypted_image. +Note that this is a live en-/decryption operation on the image.raw file. +The image is not converted, the encryption is simply unlocked in-memory using LUKS and dm-crypt until the encryption is closed again.

+

The /dev/mapper/decrypted_image can now be handled like a raw block device (e.g. mounted as a filesystem) or snapshotted in decrypted form.

+

To close the encryption execute:

+
sudo cryptsetup luksClose decrypted_image
+

The source of this document can be found in the SovereignCloudStack/docs repository.

+

Author: SCS Community, License: CC by Attribution 4.0 International

+ + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/security-groups/index.html b/docs/iaas/guides/user-guide/security-groups/index.html new file mode 100644 index 0000000000..045fdbce02 --- /dev/null +++ b/docs/iaas/guides/user-guide/security-groups/index.html @@ -0,0 +1,106 @@ + + + + + +Best Practise: How to configure and use security groups | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Best Practise: How to configure and use security groups

+

Security groups in OpenStack are part of the network security mechanisms provided for the users. +They resemble sets of simple firewall rules allowing specific network traffic at a Port of a VM that connects it to a network. +The rules allow specific network port numbers and protocols while also differentiating between ingress and egress directions. +Usually security groups are assigned to the Port(s) when a virtual machine is created, but assignments can also be changed at runtime later on. +Multiple security groups can be assigned to a VM or Port simultaneously and in such case they will be combined as the union of all their rules.

+
caution

Security groups are mutable resources. +Their rules can be adjusted at any time after creation. +Changing the rules of a security group will immediately apply the changes to all Ports or VMs it is assigned to. +It is advisable to always review resources which use a security group before making changes to it.

+

Identify the requirements of your setup

+

Every virtual machine that is created may need different firewall rules. +These requirements can also change over time. +Adding or removing security groups will allow users to adapt the firewall rules specifically to their virtual machines.

+

To harden the firewall settings for your virtual machine you may follow these steps:

+
    +
  1. Before creating a virtual machine its purpose is usually already known. Use this information to identify all incoming and outgoing traffic rules that will be needed based on the communication patterns of the services it is meant to deploy. This includes communication protocols, port numbers, communication directions and optionally target/source address ranges.
  2. +
  3. Look through already existing security groups and their rules. If a security group allows more traffic than needed it SHOULD NOT be used. If a security group contains only a subset of the required rules it MAY be used in combination with other security groups that contain rules which fulfill the remaining required traffic rules from point 1.
  4. +
  5. If you were not successful in finding an appropriate combination of existing security groups or you need additional specific rules to cover all requirements, you MAY create one or more new Security Groups in which you can add the required rules.
  6. +
  7. After ensuring the existence of one or more security groups that fulfill your requirements, you can create the VM with those security groups already specified in the creation command.
  8. +
+

Further security considerations

+

When implementing network security requirements, firewall rules alone are not always sufficient and might need to be augmented with additional configuration or time-based constraints. Notable examples are:

+

SSH +SSH is needed on many virtual machines to operate their guest operating system. +In a security group the port 22 can be opened for the TCP protocol to allow incoming SSH connections. +But that only should be done while also restricting the SSH configuration to public key authentication only (the recommended way) or having a strong username and password policy already applied to the operating system of the virtual machine. +Otherwise default usernames and passwords which are often preconfigured in system images may be exploited through the exposed SSH port which enables attackers to compromise the virtual machine.

+

ICMP +It might be useful to be able to ping a virtual machine or use other ICMP requests. +But for some virtual machine configurations this is either not necessary at all or only temporarily needed. +One benefit of security groups among other things is the ability to be easily added to and removed from existing virtual machines. +So a dedicated security group allowing ICMP could be added temporarily to a virtual machine for debugging purposes and removed from it afterwards.

+

How to create security groups

+

Security groups are managed within a project. +So every project will have a different set of security groups. +They can be added dynamically to each virtual machine, during their creation or afterwards. +Additionally, they may also be removed from VMs at any point.

+

Every project has its own default security group, which rules can be edited. +Additionally other security groups can be added until the project's quota is exhausted. +To add a security group, use the following command:

+
openstack security group create $SECURITY_GROUP
+

Within every security group rules can be added up unto a defined maximum of rules, that usually is about 100. +Rules can be added to security groups with the following command:

+
openstack security group rule create [...] $SECURITY_GROUP
+

To delete rules from a security group, the rule id has to be used. +It is listed in the details of the rules section of the security group.

+
openstack security group rule delete $RULE_ID
+

Default security group

+

Unless specified otherwise, the default security group is assigned to all VMs or Ports at creation. +To use any other than the default security group at creation it is necessary to specify the desired security group(s) during the creation process.

+

To review which rules are defined in a security group, the following command can be used:

+
openstack security group show default
+ +

While projects can use very different aspects in security group rules and thus the security groups will always differ between projects, there are some security groups that are widely used. +Through the nature of security groups being seen as a set of rules that can be combined, having some basic security groups that allow basic protocols is a commonly used setup. +This section will demonstrate how to create some security groups for commonly used protocols and ports.

+
    +
  1. A security groups, that allows incoming SSH traffic:
  2. +
+
openstack security group create ssh
openstack security group rule create --ingress --protocol tcp --dst-port 22 ssh
+
    +
  1. A security group, that allows incoming HTTP requests:
  2. +
+
openstack security group create http
openstack security group rule create --ingress --protocol tcp --dst-port 80 http
+
    +
  1. A security group, that allows incoming HTTPS requests:
  2. +
+
openstack security group create https
openstack security group rule create --ingress --protocol tcp --dst-port 443 https
+
    +
  1. A security group, that allows incoming ICMP requests:
  2. +
+
openstack security group create icmp
openstack security group rule create --protocol icmp icmp
+

How to use security groups

+
info

Security groups can be assigned to multiple resources simultaneously (such as VMs or Ports). +This means that security groups are reusable and don't need to be recreated for each applicable resource individually.

+

Usually, initial security groups are added at the time of the creation of a VM. +During creation, multiple security groups can also be added at the same time by repeating the --security-group argument:

+
openstack server create [...] --security-group $SECURITY_GROUP_1 --security-group $SECURITY_GROUP_2 $SERVER_NAME
+

To add a security group to an existing VM, the following command can be used:

+
openstack server add security group $SERVER_NAME $SECURITY_GROUP
+

To remove a security group from a VM, the following command can be used:

+
openstack server remove security group $SERVER_NAME $SECURITY_GROUP
+ + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/user-data-backups/index.html b/docs/iaas/guides/user-guide/user-data-backups/index.html new file mode 100644 index 0000000000..9e21ab24d7 --- /dev/null +++ b/docs/iaas/guides/user-guide/user-data-backups/index.html @@ -0,0 +1,249 @@ + + + + + +User Data Backups | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

User Data Backups

+

This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.

+

Glossary

+
TermExplanation
Virtual MachineEquals the server resource in Nova.
Ephemeral StorageDisk storage directly supplied to a virtual machine by Nova. Different from volumes.
(Glance) ImageIaaS resource usually storing raw disk data. Managed by the Glance service.
(Cinder) VolumeIaaS resource representing block storage disk that can be attached as a virtual disk to virtual machines. Managed by the Cinder service.
(Volume) SnapshotThinly-provisioned copy-on-write snapshots of volumes. Stored in the same Cinder storage backend as volumes.
Volume TypeAttribute of volumes determining storage details of a volume such as backend location or whether the volume will be encrypted.
(Barbican) SecretIaaS resource storing cryptographic assets such as encryption keys. Managed by the Barbican service.
+

Scope

+

User data in the context of this guide describes data accumulated in cloud resources of a user at runtime. +This concerns primarily storage data of virtual machines stored at at-rest. +This does not cover in-transit or in-use data such as network traffic, virtual machines' RAM contents or IaaS configuration and metadata of cloud resources.

+

Overview of applicable User Data

+

Given the mentioned scope, the following can be classified as user data:

+
    +
  • images stored in Glance
  • +
  • virtual machine disks, either: +
      +
    • Ephemeral Storage stored in Nova
    • +
    • volumes stored in Cinder
    • +
    +
  • +
  • encryption keys stored as secrets in Barbican
  • +
+

The following sections will describe backup procedures for each of those resources individually.

+

Image backup using download

+

Glance images may act as backup targets for other resources (such as volumes) but don't have a dedicated backup service for themselves.

+

When an image is to be backed up, it can be downloaded from the Glance image service and stored outside of the IaaS infrastructure for backup purposes. +In this case it is the user's responsibility to establish the backup procedure and appropriate target storage.

+
caution

When creating images from volumes with a volume type that uses encryption, the resulting image will contain the raw LUKS-encrypted blocks of the volume. +When transferred outside of the IaaS infrastructure, this data is only useful as a backup together with the corresponding encryption key.

Such images can be identified by an attribute called cinder_encryption_key_id in the properties metadata field of the image. +It only exists for encrypted images and references the encryption key in Barbican. +Refer to the Barbican secrets section for instructions on how to backup the key.

+

The API or the OpenStack client may be used to initiate the download, for example:

+
openstack image save --file $TARGET_FILE_PATH $IMAGE_NAME_OR_ID
+

This or the underlying API request may be automated as part of a regular backup schedule involving the backup storage target on the user side.

+

Ephemeral Storage backup using Glance images

+
caution

When using the createImage Compute API action (e.g. via the openstack server image create command) on a virtual machine that has volumes attached to it in addition to its Ephemeral Storage disk, the volumes will not be backed up into the image. Instead, a snapshot will be created for each attached volume and referenced in the image metadata. This does not replace genuine volume backups.

See the corresponding appendix section for further details.

+

Ephemeral Storage disks of virtual machines can be backed up to Glance images easily by using the createImage Compute API action or the corresponding OpenStack client command:

+
openstack server image create --name $IMAGE_NAME $SERVER_NAME_OR_ID
+

This will create a Glance image containing a one-to-one copy of the data on the Ephemeral Storage disk at the time of execution.

+

If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.

+

Volume data backup using Cinder Backup API

+

The following instructions only apply if the infrastructure offers the Cinder Backup API.

+
note

Backups of volumes using a volume type that uses encryption will retain their encryption and a clone of the original encryption key is created in Barbican linked to the backup. +These backups can only be restored when the Barbican service is available and still has the corresponding copy of the encryption key.

Also, it is advised to take note of the exact volume type when creating a backup of an encrypted volume, because this information will be needed to restore the backup. +See restoring an encrypted volume backup.

+
info

It might be difficult or even impossible for a user to transfer backups created by the Cinder Backup API outside of the IaaS infrastructure, depending on the backup backend. +A more easily accessible backup of volumes can be created by using Glance images. +See the section about volume data backup using Glance images for details.

+

Backup of detached volumes

+

Backups can be created using the Cinder Backup API or the corresponding OpenStack client commands:

+
openstack volume backup create $VOLUME_NAME_OR_ID
+

Further backups of the same volume can subsequently be created as incremental backups using the following command:

+
openstack volume backup create --incremental $VOLUME_NAME_OR_ID
+

Backup of attached volumes

+
note

When creating backups of attached (in-use) volumes, the state of the full volume is captured at runtime. Backups created this way will be crash-consistent but not app-consistent.

+

In case of attached (in-use) volumes, backups can only be created while also specfiying the force parameter:

+
openstack volume backup create --force $VOLUME_NAME_OR_ID
+

Further backups of the same volume can subsequently be created as incremental backups using the following command:

+
openstack volume backup create --force --incremental $VOLUME_NAME_OR_ID
+

Volume data backup using Glance images

+

In case the Cinder Backup storage is not available in the IaaS infrastructure, Glance images can be used as a backup target instead. +Such images may also subsequently be downloaded to transfer the backup outside of the IaaS infrastructure.

+
note

Glance image backups of Cinder volumes only allow full backup copies and do not offer incremental or differential backup mechanisms.

+

Glance image backups of detached volumes

+

Volumes not attached to virtual machines can be directly copied into an image. +Such volumes can be identified by their status being available. +To backup a detached volume to a Glance image, directly use the corresponding image creation action:

+
openstack image create --volume $VOLUME_NAME_OR_ID $IMAGE_NAME
+

After the image creation has finished, a full backup copy of the volume will reside in the Glance storage backend.

+

If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.

+

Glance image backups of attached (in-use) volumes

+

Cinder is unable to directly create Glance images from volumes which are attached to virtual machines. +To create backups of such volumes regardless, a detour using volume snapshots can be used which will be described below.

+
note

When creating snapshots of attached (in-use) volumes, the force parameter has to be used. These snapshots capture a state of the full volume at runtime. They will be crash-consistent but not app-consistent.

+
    +
  1. Create a snapshot of the target volume while including the force parameter in the request: +
      +
    • openstack volume snapshot create --volume $VOLUME_NAME_OR_ID $SNAPSHOT_NAME
    • +
    +
  2. +
  3. Create a new temporary volume based on the snapshot to act as backup source: +
      +
    • openstack volume create --snapshot $SNAPSHOT_NAME $TEMP_VOLUME_NAME
    • +
    +
  4. +
  5. Wait until the volume creation is finished and the temporary volume reaches the available status.
  6. +
  7. Create a backup image of the temporary volume: +
      +
    • openstack image create --volume $TEMP_VOLUME_NAME $IMAGE_NAME
    • +
    +
  8. +
  9. Wait until the image creation finishes and the target image reaches the active status.
  10. +
  11. Delete the temporary volume and snapshot: +
      +
    • openstack volume delete $TEMP_VOLUME_NAME
    • +
    • openstack volume snapshot delete $SNAPSHOT_NAME
    • +
    +
  12. +
+

A full backup copy of the volume now resides in the Glance storage backend.

+

If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.

+

Barbican secrets backup using download

+
danger

Secrets downloaded from Barbican will be in plaintext, which means that the secret is unprotected once received from the API. +Before downloading secrets from Barbican make sure that a secure target environment is established for receiving and securely storing the secret's contents.

+

Barbican secrets can be downloaded in plaintext using the corresponding API or client command:

+
openstack secret get --file $TARGET_FILE_PATH --payload_content_type "application/octet-stream" $SECRET_ID
+
tip

In case the secret needs to be restored into an OpenStack Barbican later on, it is recommended to also note down the following attributes shown by openstack secret get $SECRET_ID:

    +
  • Algorithm
  • +
  • Bit length
  • +
  • Secret type
  • +
  • Mode
  • +
+

Retrieving encryption keys from Barbican

+

In case of encrypted volumes (i.e. using a volume type with encryption), a corresponding encryption key is stored in Barbican. +When an image is created from such a volume, the encryption key is duplicated in Barbican for the image. +In order to backup those keys, the corresponding secret must first be identified.

+

For volumes, this is possible starting with the Volume API microversion 3.64:

+
openstack volume show --os-volume-api-version 3.64 $VOLUME_NAME_OR_ID
+

The response will contain an encryption_key_id field with the ID of the Barbican secret.

+

For images, the secret reference is stored in the properties field instead:

+
openstack image show -f value -c properties $IMAGE_NAME_OR_ID
+

In case of images created from encrypted volumes, the resulting output will have a nested cinder_encryption_key_id field that contains the ID of the Barbican secret.

+

The resulting IDs can be used to retrieve the corresponding key using the Barbican instructions above.

+
caution

Note that the key retrieved from the secret is not immediately usable as LUKS passphrase to the image data of the volume. +OpenStack does some processing to the key before it is passed to the LUKS encryption, which must be mimicked accordingly in order to unlock the encryption outside of OpenStack!

See the example procedure for converting the LUKS key in the appendix section.

+

Restore

+

The following sections will illustrate how to restore the individual resource backups that have been documented above.

+

Restoring a backup of a Barbican secret

+
note

Note that restoring a Barbican secret by re-uploading it via the Barbican API will lead to the secret receiving a new ID. +Existing resources referencing an old secret ID cannot make use of the restored copy.

+
openstack secret store --algorithm aes --bit-length 256 --mode cbc \
--secret-type symmetric --file $KEY_FILE_PATH --name $SECRET_NAME
+

Notes:

+
    +
  • Attributes like algorithm, bit length, mode and secret type are not verified by Barbican. Their main purpose is to classify the secret on a metadata level. Make sure to align the attributes with the original secret.
  • +
  • $KEY_FILE_PATH is the local file path of the secret backup as created originally using the instructions above.
  • +
  • $SECRET_NAME is entirely optional but helps identifying the restored secret later on and to distinguish it from secrets created by OpenStack itself. It is best to not put whitespace characters in the name, otherwise it has to be surrounded by quotes.
  • +
+

The successful registration of the restored secret can subsequently be verified using:

+
openstack secret list --name $SECRET_NAME
+

Restoring a backup of an unencrypted image

+

Unencrypted image backups can simply be restored using the regular image upload functionality and specifying the backup file:

+
openstack image create --file $IMAGE_FILE_PATH $IMAGE_NAME
+
note

In case the original image backup was not based on a volume originally, the image may have had a non-default disk or container format. +In this case, add the command parameters --container-format and --disk-format to the command accordingly.

+

Restoring a backup of an encrypted image

+

The following section only applies to image backups that were originally created from images of encrypted volumes.

+

First, restore the corresponding secret of the image using the instructions above. +The restored secret will receive a new ID in the form of a UUID. +Note down the ID of the restored secret and insert it in place of $SECRET_ID in the command below.

+
openstack image create --file $IMAGE_FILE_PATH \
--property cinder_encryption_key_id=$SECRET_ID \
--property cinder_encryption_key_deletion_policy=on_image_deletion \
$IMAGE_NAME
+

The cinder_encryption_key_deletion_policy attribute is optional. +If not specified, the referenced secret will not be deleted on image deletion automatically. +In contrast, if set to on_image_deletion, the referenced secret will be deleted as soon as the image referencing it is deleted.

+

Restoring a volume backup from an image

+

To restore a volume from an image backup, simply use the volume creation action and specify the image as source.

+

Depending on whether the original volume the image was created from was encrypted or not, the target volume type might need to be specified accordingly. +Whether this is the case can be identified by inspecting the image's metadata using openstack image show $IMAGE_NAME_OR_ID and looking for a "cinder_encryption_key_id" field within "properties". +If it exists, the source volume of the image was encrypted.

+

To restore the image of an unencrypted volume:

+
openstack volume create --image $IMAGE_NAME_OR_ID \
--size $VOLUME_SIZE_IN_GB $VOLUME_NAME
+

To restore the image of an encrypted volume:

+
openstack volume create --image $IMAGE_NAME_OR_ID \
--type $ENCRYPTED_VOLUME_TYPE \
--size $VOLUME_SIZE_IN_GB $VOLUME_NAME
+

If restoring an encrypted image, make sure to specify $ENCRYPTED_VOLUME_TYPE correctly and have it reference a volume type which also supports the encryption. +Otherwise the volume will be unbootable or unusable by Nova instances.

+

Restoring a volume backup from the Cinder Backup service

+

The Cinder Backup service offers dedicated API actions and commands for restoring volume backups created using the service. +These backups can be restored in one of two ways:

+
    +
  1. Letting the Cinder Backup service create a new volume based on the backup.
  2. +
  3. Overwriting an existing volume with the backup data.
  4. +
+
note

If the volume backup was originally created from a volume that used a non-default encrypted volume type, letting Cinder Backup create a new volume for backup restoration does not work and the volume type must match exactly. +In such case provision an empty volume with the correct type first and then restore the backup onto it as explained further down.

+

Restoring to a new volume (Cinder Backup)

+
openstack volume backup restore $BACKUP_NAME_OR_ID $TARGET_NAME
+

... where $TARGET_NAME is the desired name of the new volume to be created. +Make sure that no volume with this name already exists. +The Cinder Backup service will create the volume with the same size as the backup indicates.

+

Restoring on an existing volume (Cinder Backup)

+

As an alternative to creating a new volume as the restore target, the backup can also be restored on an existing volume:

+
openstack volume backup restore --force $BACKUP_NAME_OR_ID $VOLUME_NAME_OR_ID
+

... which will overwrite the data on the existing volume, regardless of whether it is empty or not!

+

The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.

+

Restoring an encrypted volume backup (Cinder Backup)

+

When restoring a volume backup of a volume that was using a non-default encrypted volume type, a new volume of that type needs to be created first and then the backup restored onto it. +Otherwise, the restoration will fail with the target volume ending up in the "error_restoring" state. +For this procedure to succeed it is necessary to know the exact volume type of the volume the backup was created from.

+

If the source volume of the backup still exists, the original volume type can be determined by inspecting the backup's volume_id attribute and then using it to look up the corresponding volume and its type attribute. +The following client command can be used for this (fill in the value for BACKUP_ID):

+
export BACKUP_ID=...

SOURCE_VOLUME_ID="$(openstack volume backup show $BACKUP_ID -f value -c volume_id)"
openstack volume show -f value -c type "$SOURCE_VOLUME_ID"
+

This returns the name of the original volume type. +If the source volume does not exist anymore, rely on documentation about the backup to determine the type, if available.

+

First, create a new empty volume as the restore target and use the backup's size metadata attribute to match the size of the volume to the backup:

+
openstack volume create --size $BACKUP_SIZE --type $VOLUME_TYPE $TARGET_NAME
+

... where $TARGET_NAME is the desired name of the new volume.

+

Once the volume reaches "available" state, restore the backup onto it:

+
openstack volume backup restore --force $BACKUP_NAME_OR_ID $TARGET_NAME
+

The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.

+

Appendix

+

Image creation action for servers with attached volumes

+

When the createImage action of the Compute API (openstack server image create) is used on virtual machines that have at least one volume attached, a snapshot will be created for each attached volume individually and referenced in the resulting image's metadata.

+

This happens regardless of whether the virtual machine has an Ephemeral Storage disk attached. +In case of an Ephemeral Storage disk, only the Ephemeral Storage is copied into the Glance image as a 1:1 copy.

+

In case of a virtual machine that has no Ephemeral Storage but only volumes, the createImage action leads to a Glance image that only consists of metadata (including the resulting volume snapshot references) but carries no actual binary data.

+

Figure: createImage action flow involving Ephemeral Storage and/or volumes

+

LUKS encryption key conversion to decrypt volume images

+

The volume encryption keys stored in Barbican are not directly used as LUKS passphrases by OpenStack because they are in binary format. +OpenStack converts them to ASCII internally before passing them to the encryption layer. +This behavior needs to be reproduced if a decryption of a volume image is desired outside of OpenStack.

+
danger

The instructions below will expose plaintext data of encryption keys and encrypted volume images. +Make sure to only execute these steps in a secure and trusted environment.

+

First, download the image:

+
openstack image save --file image.raw $IMAGE_NAME_OR_ID
+

Next, inspect the image metadata, determine the reference to the encryption key (cinder_encryption_key_id property) and download the encryption key:

+
openstack image show -f value -c properties $IMAGE_NAME_OR_ID
# (use the value of `cinder_encryption_key_id` as `$SECRET_ID` below)
openstack secret get --file image.key --payload_content_type "application/octet-stream" $SECRET_ID
+

This will result in the following local files:

+
    +
  • image.raw = the raw encrypted image downloaded from Glance
  • +
  • image.key = the LUKS encryption key in binary format (plaintext)
  • +
+

Since OpenStack internally uses Python's binascii.hexlify() to convert the binary encryption key before passing it as a passphrase to the LUKS encryption, as a last step this conversion must be mimicked to unlock the encryption:

+
python3 -c "import binascii; \
f = open('image.key', 'rb'); \
print(binascii.hexlify(f.read()).decode('utf-8'))" \
| sudo cryptsetup luksOpen ./image.raw decrypted_image
+

The decrypted image is now accessible at /dev/mapper/decrypted_image. +Note that this is a live en-/decryption operation on the image.raw file. +The image is not converted, the encryption is simply unlocked in-memory using LUKS and dm-crypt until the encryption is closed again.

+

The /dev/mapper/decrypted_image can now be handled like a raw block device (e.g. mounted as a filesystem) or snapshotted in decrypted form.

+

To close the encryption execute:

+
sudo cryptsetup luksClose decrypted_image
+ + \ No newline at end of file diff --git a/docs/iaas/overview/architecture/index.html b/docs/iaas/overview/architecture/index.html new file mode 100644 index 0000000000..12b4f3612d --- /dev/null +++ b/docs/iaas/overview/architecture/index.html @@ -0,0 +1,25 @@ + + + + + +Architecture | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/overview/compute/index.html b/docs/iaas/overview/compute/index.html new file mode 100644 index 0000000000..7728e80609 --- /dev/null +++ b/docs/iaas/overview/compute/index.html @@ -0,0 +1,25 @@ + + + + + +Compute | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/overview/knowledge/index.html b/docs/iaas/overview/knowledge/index.html new file mode 100644 index 0000000000..d3f1a2d8cb --- /dev/null +++ b/docs/iaas/overview/knowledge/index.html @@ -0,0 +1,25 @@ + + + + + +Knowledge | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/overview/network/index.html b/docs/iaas/overview/network/index.html new file mode 100644 index 0000000000..a4be538718 --- /dev/null +++ b/docs/iaas/overview/network/index.html @@ -0,0 +1,25 @@ + + + + + +Network | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/overview/storage/index.html b/docs/iaas/overview/storage/index.html new file mode 100644 index 0000000000..a2c55eb67c --- /dev/null +++ b/docs/iaas/overview/storage/index.html @@ -0,0 +1,25 @@ + + + + + +Storage | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iam/SCS-example-setup-configuration-description/index.html b/docs/iam/SCS-example-setup-configuration-description/index.html new file mode 100644 index 0000000000..affa331f58 --- /dev/null +++ b/docs/iam/SCS-example-setup-configuration-description/index.html @@ -0,0 +1,50 @@ + + + + + +Example setup configuration in SCS deployment explained | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Example setup configuration in SCS deployment explained

+

The following document explains the idea behind the example configuration is done. +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 +to be able to use the home-IdP-discovery plugin to redirect to the correct customer realm and an example user. +SCS operators can find the playbook that creates the setup here.

+
    +
  1. +

    In the first place a proxy realm called osism on the example deployment. That realm will +become the realm that will be conected to Keystone

    +
  2. +
  3. +

    A customer realm called CustomerA is created. On that realm a OIDC client is created to hook +up the realm to the proxy realm. This is done via Identity Brokering in the proxy realm.

    +
  4. +
  5. +

    An Identity provider is configured in the osism realm, this is configured to be connected to +the CustomerA realm. For that, a set of mappers are created, the default ones are a hardcoded-attribute +that sets the domain where the user came from, and an attribute-importer mapper for the openstack-default-project that comes +in the OIDC claim from the customer realm.

    +
  6. +
  7. +

    A new login flow has been created in the osism realm, this login flow is needed to use the home-IdP-discovery plugin.

    +
  8. +
  9. +

    Creation of an example user called Alice.

    +
  10. +
+ + \ No newline at end of file diff --git a/docs/iam/domain-manager-setup-and-usage/index.html b/docs/iam/domain-manager-setup-and-usage/index.html new file mode 100644 index 0000000000..4c9dd0519e --- /dev/null +++ b/docs/iam/domain-manager-setup-and-usage/index.html @@ -0,0 +1,145 @@ + + + + + +Domain Manager setup and usage | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Domain Manager setup and usage

+
info

The following documentation refers to a SCS standard that is still in draft state. +It is not meant for productive use yet but CSPs are encouraged to test-drive and provide feedback!

+

Preface

+

SCS defines the Domain Manager standard, introducing a special persona to the OpenStack Keystone identity manager. +This persona offers a properly domain-scoped permission set to manage users, groups, projects and role assignments within a domain. +Its intended use case is to offer extensive identity management self-service capabilities to tenants mapped to a domain.

+

This guide will explain setup, configuration and usage of the SCS Domain Manager standard.

+

Warning regarding the exposure of domain names

+

Due to architectural limitations currently existing in OpenStack Keystone, assigning the manager role to users while the configuration of the SCS Domain Manager standard has been applied will enable them to see the IDs and names of all existing domains. +This includes domains other than their own, meaning that other tenant's identities might be exposed depending on the relation between them and the name of their domain. +CSPs aiming to appoint Domain Manager users must be aware of this limitation and should exclusively use pseudonymized domain names across the whole infrastructure. +If CSPs strictly follow the SCS naming conventions for domains this is already addressed. +If this is not feasible for the CSP, they may opt to refrain from making use of the Domain Manager functionality at all, i.e. never assign the manager role to tenant users.

+
info

This architectural limitation will be fixed in upcoming OpenStack and SCS releases.

See https://bugs.launchpad.net/keystone/+bug/2041611

+

Infrastructure configuration

+

An initial infrastructure configuration of the Domain Manager persona must be completed before it can be used. +This includes adjusting the Keystone API policy configuration and the registration of the manager role.

+

The following sections describe the configuration to be implemented on the infrastructure-level. +This requires infrastructure access and OpenStack admin rights. +For tasks marked with "[Initial]" the described procedure only has to happen once initially. +For tasks marked with "[Runtime]" the described procedure may be repeated later on to make adjustments.

+

[Initial] Keystone API policy adjustments

+

First, incorporate the Keystone API policy definitions as described in the SCS Domain Manager standard. +This is usually done in "/etc/keystone/policy.yaml" of the Keystone API service. +Otherwise, an entry called "policy_file" under the "[oslo_policy]" section of "/etc/keystone/keystone.conf" might exist that points to a different policy file path. +In such case, adjust or create the file at the specified path.

+

When incorporating the policy definitions from the standard make sure to properly merge it with existing policy definitions, if any exist. +Also choose the definition of manageable roles in the "is_domain_managed_role" rule of the policy carefully according to your requirements and environment. +See the standard for more details on this rule.

+

Depending on the deployment method used, the adjustments may also need to be persisted in the corresponding infrastructure management solution, such as Ansible.

+

[Initial] Keystone role creation

+

The role manager has to exist in Keystone. +If the role does not exist, it needs to be created in Keystone once. +This can be done with the OpenStackClient using the following command:

+
openstack role create manager
+

[Runtime] Domain Manager managed roles adjustment

+

The list of roles that a Domain Manager can assign within a domain is configured using the "is_domain_managed_role" rule of the policy definitions. +The SCS Domain Manager standard allows flexibility in defining the set of roles a Domain Manager may assign and revoke within a domain and enables adjustments at runtime1.

+

The set of roles can be adjusted independently from the rest of the policy by changing only the "is_domain_managed_role" line it Keystone's API policy file. +Changes will apply to existing and future Domain Manager users. +This means that changes can be implemented at runtime1.

+

The following example entry adjusts the rule to allow both member and reader roles to be managed by Domain Managers:

+
'is_domain_managed_role': "'member':%(target.role.name)s or 'reader':%(target.role.name)s"
+

Refer to the SCS Domain Manager standard for more information.

+

Administrative operation

+

The following sections describe actions available to CSP operators that possess the admin role.

+

Creating domains

+
caution

It is highly recommended to use pseudonymized domain names when creating domains, since Domain Managers will currently be able to see the names of all existing domains. +See Warning regarding the exposure of domain names for more details.

+

For each tenant for which a self-service area (i.e. a domain) is to be established, a domain should be created before creating any users, projects or groups for this tenant:

+
openstack domain create $DOMAIN
+

Any creation of users, projects or group for a tenant should happen strictly within the tenant's domain by passing the "--domain" flag to the corresponding creation commands, regardless of whether the commands are executed by an administrator or a Domain Manager. +See the Domain Manager operation section further down for reference.

+

Creating a Domain Manager user

+
info

Creating the first Domain Manager users for a domain is an action reserved for CSP administrators. +Depending on whether the manager role has been approved as a domain-managed role in the policy configuration by the CSP, Domain Manager users may be able to appoint further Domain Managers within the domain on their own later on.

+

First, create the user for the Domain Manager. +You may create the Domain Manager user either directly in the target tenant's domain or in a different domain. +The domain a Domain Manager will effectively be able to manage solely depends on where its role assignment of the manager role is scoped, not the domain the Domain Manager user was originally created in.

+
openstack user create --domain $MANAGER_DOMAIN $USER_NAME
+
note

$MANAGER_DOMAIN can be the same as the tenant domain $DOMAIN or an entirely different one, depending on the desired origin domain of the user. +In the following sections $DOMAIN will denote the tenant domain that the user is intended to manage as the Domain Manager persona.

+

Next, assign the manager role in a domain-scoped fashion to the tenant domain:

+
openstack role add --user $USER_NAME --domain $DOMAIN manager
+

Assigning the Domain Manager role to an existing user

+
openstack role add --user $USER_NAME --domain $DOMAIN manager
+

Revoking the Domain Manager role

+

In case the manager role is to be revoked from an existing Domain Manager user, the following command can be used:

+
openstack role remove --user $USER_NAME --domain $DOMAIN manager
+

Domain Manager operation

+

The following sections describe actions available to Domain Managers that possess the manager role.

+

Managing users within a domain

+

Creating a user within a domain:

+
openstack user create --domain $DOMAIN $USER_NAME
+
note

The explicit domain-scoping is only required for the creation command, any other user-centric commands like "user set" or "user delete" do not require the "--domain" flag and are automatically scoped to the domain for Domain Managers.

+

Managing projects within a domain

+

Creating a project within a domain:

+
openstack project create --domain $DOMAIN $PROJECT_NAME
+
note

The explicit domain-scoping is only required for the creation command, any other project-centric commands like "project set" or "project delete" do not require the "--domain" flag and are automatically scoped to the domain for Domain Managers.

+

Deleting projects

+

Note that before deleting projects, make sure that all cloud resources (servers, volumes etc.) belonging to that project have been removed beforehand. +Otherwise such resources might become orphaned and inaccessible without involving the CSP.

+

Managing groups within a domain

+

Creating a group within a domain:

+
openstack group create --domain $DOMAIN $GROUP_NAME
+
note

The explicit domain-scoping is only required for the creation command, any other group-centric commands like "group set" or "group delete" do not require the "--domain" flag and are automatically scoped to the domain for Domain Managers.

+

Managing group membership

+

Adding a user to a group:

+
openstack group add user $GROUP $USER
+

Removing a user from a group:

+
openstack group remove user $GROUP $USER
+

Managing role assignments within a domain

+

Role assignments managed by a Domain Manager work as usual with the exception that the roles that can be assigned and revoked are limited to a defined set which is explicitly approved for Domain Managers by the CSP. +This may or may not include the manager role itself, meaning that Domain Managers may either be able to appoint other Domain Managers by themselves or have to ask the CSP to do so.

+

Managing user role assignments

+

Assigning a role to a user within a project:

+
openstack role add --project $PROJECT --user $USER $ROLE
+

Assigning a role to a user domain-wide:

+
openstack role add --domain $DOMAIN --user $USER $ROLE
+

Revoking a project-level role assignment from a user:

+
openstack role remove --project $PROJECT --user $USER $ROLE
+

Revoking a domain-wide role assignment from a user:

+
openstack role remove --domain $DOMAIN --user $USER $ROLE
+

Managing group role assignments

+

Assigning a role to a group within a project:

+
openstack role add --project $PROJECT --group $GROUP $ROLE
+

Assigning a role to a group domain-wide:

+
openstack role add --domain $DOMAIN --group $GROUP $ROLE
+

Revoking a project-level role assignment from a group:

+
openstack role remove --project $PROJECT --group $GROUP $ROLE
+

Revoking a domain-wide role assignment from a group:

+
openstack role remove --domain $DOMAIN --group $GROUP $ROLE
+ +

Footnotes

+
    +
  1. +

    "at runtime" in this context means that the configuration may be changed repeatedly after the initial configuration of Keystone and take effect immediately. +Depending on the infrastructure management solution and high-availability configuration the described adjustments may or may not require a restart of the Keystone API service or lead to a downtime of the service. 2

    +
  2. +
+
+ + \ No newline at end of file diff --git a/docs/iam/index.html b/docs/iam/index.html new file mode 100644 index 0000000000..b6910a7566 --- /dev/null +++ b/docs/iam/index.html @@ -0,0 +1,82 @@ + + + + + +Introduction on Identity Management and Federation in SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Introduction on Identity Management and Federation in SCS

+

Sovereign Cloud Stack wants to make it possible for operators to delegate +administration of user identities to the organizational entities that the +users are part of. Usually that's customer organizations but it could also +be the operator itself. Federation protocols like OpenID Connect can be used +to achieve that goal. To simplify connecting the different parts of SCS +to customer owned IAM solutions, the SCS reference implementation offers +Keycloak as central Identity Provider (IdP) service.

+

Deployment

+

Keycloak can be deployed by running

+
osism apply keycloak
+

The required Keycloak client configuration that allows Keystone to obtain +OIDC token from Keycloak needs to be deployed by running

+
osism apply keycloak-oidc-client-config
+

After these steps Keystone should be able to obtain token using the +Device Authorization Grant with PKCE, which is configured by default in the +wsgi-keystone.conf deployed in SCS.

+

Accessing Keycloak

+

Currently deployed on the manager node, by default under https://keycloak.<yourdomain>. +Details TODO.

+

Identity Mapping

+

The idea is that customer can create groups with specific names in their own IAM. +These shall be mapped to a claim groups to be included in the OIDC token. +Via the Keystone mapping +they shall be mapped to roles on OpenStack projects. +The corresponding section for Developers may be interesting for more technical details. +Please be aware that currently there are still some technical challenges to be solved +within the OpenStack Keystone mapping engine and the mapping rules to make this work +seamlessly.

+

SCS to SCS federation

+

Federation between separate deployments of SCS is possible via the IdP by +means of OpenID Connect. +The section on inter SCS federation setup explains the required steps in some detail.

+

Prerequisites and Requirements

+
    +
  • Knowledge: Familiarity with Keycloak, OIDC federation, and basic SSL and web security principles is pivotal.
  • +
  • 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.
  • +
+

Features

+
    +
  • Horizon Web SSO
  • +
  • OpenStack CLI use via the Device Authorization Grant
  • +
+

Limitations

+
    +
  • Keystone currently still has limitations in its mapping engine, which are addressed by the SCS development team as we +see possibilities and alignement with upstream OpenDev development plans. Automatically creating ephemeral users in +their specific OpenStack domains, as specified in their OIDC token is one example, currently beeing worked on. Please +check carefully if the technical results meet the security demands of your specific environment.
  • +
  • Keystone currently has another limitation which is being addressed by the SCS development team aligned +with upstream OpenDev development plans: The roles for federated users are stored on the database for the ephemeral users +created during a federated login. This limits the ability to modify users roles from the identity source directly, as roles of +the epehemeral users do not get cleaned up or updated based on changes in the claims contained in the OpenID-Connect token.
  • +
+

Current state and future Outlook

+

Currently SCS exemplifies deploying Keycloak on the management plane. This shall be moved to a Kubernetes based +management plane to improve scalability and architecture.

+

In the near future, the Container layer shall be able to make use of the IdP to allow federated users to access Kubernetes. +In the mid term, workloads on Kubernetes shall be able to make use of OAuth tokens to access resources on the IaaS layer.

+ + \ No newline at end of file diff --git a/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations/index.html b/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations/index.html new file mode 100644 index 0000000000..73efa0c6d3 --- /dev/null +++ b/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations/index.html @@ -0,0 +1,89 @@ + + + + + +Proposal for documentation for Keycloak to Keycloak Federation (WebSSO) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)

+

The followig section is a reasonably detailed hands on description of how +to configure a federation between two separate SCS compliant domains by means +of Keycloak Identity Brokering. If we decide to use Keycloak as a component +to allow self service by tenants, then this documentation may be a useful addition +to some tenant facing documentation (or for the SCS operators too).

+

OTOH one could probably also script pretty much everything of this to allow +tenants to use a CLI tool to automate the setup. For that purpose the documentation +may be useful to guide the implementation of such a scripted solution.

+

Detailed tutorial on how to configure Federation (OpenID Connect) between two Keycloak instances in two separate SCS domains

+

Assume you have two CSPs using SCS. The first one wants to grant access to users of the other. +So let's call the first domain "resource domain" and the second one "accounts domain". +Both domains need to agree upon a name for the "OIDC RP" (which Keycloak calls Clients). +The Keycloak in the "resource domain" will be the OIDC RP and the Keycloak in the "accounts domain" will be the OIDC OP. +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.

+
    +
  1. +

    In the accounts domain (bar) open Keycloak realm osism, click on Clients in the sidebar and click on Create client. +Leave the client type as OpenID Connect and enter the Client ID, e.g. oidc-rp-foo. +Turn on Client authentication for it and click Save.

    +

    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.

    +
  2. +
  3. +

    In the resource domain (foo) open Keycloak realm osism, click on Identity providers +and create a new provider definition of type OpenID Connect v1.0. As Alias choose a name, +e.g. oidc-op-bar. Don't copy the Redirect URI given at the top yet, because is will change depending +on the chosen Alias. Instead, scroll down to the mandatory field Discovery endpoint and paste +the OpenID Connect metadata URL of the KEycloak realm osism in the "accounts domain" (bar). +The operator of the "accounts domain" (bar) may easily copy that URL from the Realm Settins in the +sidebar of his Keycloak instance, where the Endpoints are listed on the bottom of that form. +The URL may have the format https://bar.com/auth/realms/osism/.well-known/openid-configuration. +Once you leave that input field, Keycloak will attempt to fetch the metadata and extract the required +details about protocol enspoints from the retrieved document. If this shows an error, it will give you +an HTTP status code. If this shows an error code of 500, then this may be caused by a failure in +certificate verification. In that case you may want to check the output of docker logs keycloak for +java stack traces. If you find any, the top of those stack traces may indicate what kind of problem +occurred to the java code. From here we will assume that the emtadata URL could be fecthed without +any issues.

    +

    Now, go to the bottom of that form and insert tjhe Client ID (oidc-rp-foo) and the +Client secret that was provided by the operator of the "accounts domain" (bar). +Finally click on Add. From the Provider Details page on the top for the Settings tab copy the value of the +Redirect URI and communicate it back to the operator of the "accounts domain" (bar).

    +
  4. +
  5. +

    In the accounts domain (bar) open Keycloak realm osism, click on Clients in the sidebar and click +on the name of the OIDC RP clinent that you created for domain foo (e.g. oidc-rp-foo). +On the Client details page on the tab Settings fill in the field Valid redirect URIs with the value +obtained from the resource domain (foo), which should look similar to +https://foo.com/auth/realms/osism/broker/oidc-op-bar/endpoint. Additionally the +Valid post logout redirect URIs need to be set to something like https://foo.com/auth/realms/osism/*.

    +
  6. +
  7. +

    To test federated login in the "resource domain" (foo) open the URL of the Keycloak admin console for +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). +Ignore the top section of the login form titled +Sign in to your account and choose one of the OIDC OP federation choises below the line Or sign in with. +In this example it would be oidc-op-bar. This should redirect your browser to the authentication endpoint +of the "accounts domain" (https://bar.com/auth/realms/osism/protocol/openid-connect/auth?scope=openid&...) +where you should be able to log in with credentials that are valid in the "accounts domain" (bar). +After successull authentication your broser should be redirected to admin console of the "resource domain", +which may offer you a "first login flow" form where you can choose a username, email, firstname and lastname. +The details depend on the Mappers that have been configured for the Identity Provider oidc-op-bar. +After that you will be presented with a Keycloak themed page with the error message Request failed with status code 403, +which is normal because the test account is not authorized to access any elements of the Keycloak admin console.

    +
  8. +
+ + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000000..2758fa4614 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,66 @@ + + + + + +Introduction | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Introduction

About

+

The Sovereign Cloud Stack combines the best of Cloud Computing in one unified standard. +SCS is built, backed, and operated by an active open-source community worldwide.

+

Architectural Overview

+ +

Use Cases and Deployment Examples

+

IaaS Layer

+

Quick Start with Cloud-In-A-Box

+

The fastest way to get in touch with SCS is to deploy a SCS cloud virtually. The Cloud-In-A-Box was built explicitly for this scenario. Check it out here

+

Reference Implementation Testbed

+

This means that you set up an SCS test installation including all the infrastructure +pieces such as database, message queueing, ceph, monitoring and logging, IAM, the +OpenStack core services, and (soon) the Container layer +on top of an existing IaaS platform.

+

The SCS IaaS reference implementation is based on OSISM. Read on the +OSISM testbed docs to learn how to get the +testbed running. Please read carefully through the +deployment section of the +manual.

+

Container Layer

+

Cluster Stacks

+

With the Cluster Stacks, in the V2 KaaS reference implementation, we provide an opinionated optimized configuration of Kubernetes clusters. Through better packaging, integrated testing, and bundled configuration, SCS-based Kubernetes clusters provide easier individualization. +Throughout the R6 development cycle Cluster Stacks are taken from a technical preview to be functional and available on top of the IaaS reference implementation as well to replace the V1 KaaS reference implementation k8s-cluster-api-provider. +The Cluster Stacks can already be tried with the demo repository. Although this is based on the not-production-ready Docker provider, the usage is the same for every provider.

+

Public SCS Clouds in production

+

Find the current list of scs compatible clouds here.

+

Development of SCS

+

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:

+
    +
  • CNCF projects,
  • +
  • OpenStack,
  • +
  • kolla-ansible,
  • +
  • OSISM and others.
  • +
+

All code not pushed upstream can be found in the SCS Github organization.

+

Issues and Bugs

+

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. We appreciate PRs as well as issues; please don't forget to sign off your contributions see contributor guide.

+

Contribute and Connect

+

Please see the SCS contributor guide.

+

Releases and Roadmap

+

See our Release Notes here

+

Standards, Conformity and Certification

+

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.

+ + \ No newline at end of file diff --git a/docs/operating-scs/audits/index.html b/docs/operating-scs/audits/index.html new file mode 100644 index 0000000000..fd164e46f8 --- /dev/null +++ b/docs/operating-scs/audits/index.html @@ -0,0 +1,25 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/automated-pentesting-iaas/overview/index.html b/docs/operating-scs/components/automated-pentesting-iaas/overview/index.html new file mode 100644 index 0000000000..7c51edbca3 --- /dev/null +++ b/docs/operating-scs/components/automated-pentesting-iaas/overview/index.html @@ -0,0 +1,76 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

Introdution

+

Modern cloud infrastructure security is a complex and critical aspect of maintaining robust and resilient cloud services. Moreover, as organizations increasingly rely on cloud environments for their operations, the security of these infrastructures becomes paramount.

+

The SCS Software stack, and more specifically its Infrastructure-as-a-Service layer, is susceptible to various security threats, including but not limited to misconfigurations, vulnerabilities and external attacks. To address these concerns, continuous and automated security testing is essential.

+

Cloud Security Concerns

+

Cloud infrastructure security involves protecting data, applications, and services from unauthorized access and threats. Key concerns include:

+
    +
  • Data Breaches: Unauthorized access to sensitive data.
  • +
  • Misconfigurations: Incorrect settings that expose systems to vulnerabilities.
  • +
  • Compliance Violations: Failure to meet regulatory and industry standards.
  • +
  • Advanced Persistent Threats (APTs): Prolonged and targeted cyber-attacks.
  • +
  • Insider Threats: Malicious actions by authorized users.
  • +
+

To mitigate these risks, security practices like Static Application Security Testing (SAST) and Dynamic Application Security Testing (DAST) are employed. However, if you look at it from an automation perspective, a basic distinction of tooling is needed to be considered:

+
    +
  • +

    SAST involves analyzing the source code, bytecode, or binary code of applications to identify vulnerabilities without executing them. It helps in detecting issues like SQL injection, XSS, and other code-related vulnerabilities early in the development lifecycle.

    +
  • +
  • +

    DAST involves testing the application in its running state, as well as deployed infrastructure, to identify vulnerabilities that could be exploited in real-time. It focuses on the application's exposed interfaces and is crucial for detecting issues like authentication problems, server misconfigurations, and injection flaws.

    +
  • +
+

In this project we solely focus on DAST.

+

SCS automated pentesting

+

The automated pentesting pipeline is based on a proposed methodology for the Sovereign Cloud Stack community. It integrates state-of-the-art tools to conduct dynamic security testing and ensure continuous security assurance for SCS based cloud infrastructures.

+

The pipeline has been developed from a DevSecOps perspective, which ensures that security is deeply embedded into the fabric of the cloud infrastructure. It aligns with the following principles:

+
    +
  • Integrated Security Testing: The pipeline integrates DAST tools directly into the workflow managed by SCS Zuul. This ensures that every target is automatically tested for security vulnerabilities.
  • +
  • Continuous Monitoring: Scheduled daily and weekly scans maintain continuous oversight of the infrastructure’s security posture, ensuring that any new vulnerabilities are quickly identified and addressed.
  • +
  • Automated Feedback Loop: The results from security tests are automatically fed back to the a central vulnerabilities repository, enabling quick remediation and continuous improvement.
  • +
  • Cultural Shift: By adopting a DevSecOps approach, the pipeline fosters a culture where security is a shared responsibility, encouraging all team members to prioritize and contribute to security efforts.
  • +
+

Following this approach, each each tool has it's own use case and they build up onto each other over two different pipelines: A fast daily scan and a comprehensive weekly scan.

+
    +
  • Naabu -> Identify open ports
  • +
  • Httpx -> Identify web services from previous result
  • +
  • Nuclei -> Scan web services based on community templates
  • +
  • ZAP Proxy -> Scan web services based on OWASP rulesets
  • +
  • Greenbone Community Edition (OpenVAS) -> Full scan targets
  • +
  • Defect Dojo -> Vulnerabilities management
  • +
+

scs_automated_pentesting_workflow.png

+

Color meaning:

+
    +
  • Green: Daily triggered pipeline
  • +
  • Blue: Weekly triggered pipeline
  • +
+

Quickstart Guide

+

See the quickstart page.

+

Tools

+

See the tools page.

+

Source

+

github.com/SovereignCloudStack/security-infra-scan-pipeline.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/automated-pentesting-iaas/quickstart/index.html b/docs/operating-scs/components/automated-pentesting-iaas/quickstart/index.html new file mode 100644 index 0000000000..979414f78b --- /dev/null +++ b/docs/operating-scs/components/automated-pentesting-iaas/quickstart/index.html @@ -0,0 +1,143 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Quickstart

+

This page covers the process of setting up an IaaS layer automated pentesting pipeline.

+

The provided configuration options result in a simple and working deployment that allows to scan a set of defined targets. However, it is possible to adapt each tool behaviour adding additional capabilities, which are defined in their specific documentation.

+

Prerequisites

+ +

Configuration

+

DefectDojo

+

After installing DefectDojo, a few key configurations are necessary to start using the platform effectively, ensuring that a streamlined process for managing security assessments, tracking vulnerabilities, and integrating with existing tools and processes is set up based on SCS Standards.

+
    +
  • +

    Products:

    +
      +
    • Definition: In DefectDojo, a "Product" represents an application, system, or any entity that is being tested or tracked for vulnerabilities.
    • +
    • Configuration: +
        +
      • Navigate to the "Products" section and click "Add Product."
      • +
      • Fill in the necessary details such as the product name, description, and criticality.
      • +
      • Assign product type, enable/disable tracking of findings, and set the product's authorization configuration.
      • +
      +
    • +
    +
  • +
  • +

    Engagements:

    +
      +
    • Definition: An "Engagement" refers to a specific instance of testing or assessment activity against a product. This could be a penetration test, vulnerability assessment, or any other security-related activity.
    • +
    • Configuration: +
        +
      • In the "Engagements" section, click "Add Engagement."
      • +
      • Choose the product you want to engage with, define the type of engagement (e.g., pen test, code review), and set the time frame.
      • +
      • Once created, note the engagement id that has been generated, as it will be needed for pipeline configuration (just pick the id number from the URL, in the form of https://<instance_url>/engagement/<engagement_id>)
      • +
      • Optionally, link the engagement to an external test plan, define test lead, and add team members.
      • +
      +
    • +
    • Recommended setup: Add at least the following engagements. +
        +
      • Daily Automated Scan
      • +
      • Weekly Automated Scan
      • +
      +
    • +
    +
  • +
  • +

    Importing Findings from Tools:

    +
      +
    • Definition: DefectDojo can import findings from various security tools, allowing centralized tracking and management.
    • +
    • Configuration: +
        +
      • Tasks on the automated pipelines leverage DefectDojo API to automate imports by sending scan results directly to the system using specific endpoints for supported tools.
      • +
      • The import POST request to the api needs to be authenticated. Several methods are availiable, but taking into accounts security measures, the use of tokens/keys are encouraged.
      • +
      • To get a working API key, under user menu head to "API v2 Key" or directly access the endpoint https://<instance_url>/api/key-v2. If it is needed, generate a new one.
      • +
      • Alternatively, it is possible to use the "Import Scan Results" option within an engagement to manually import results from tools like OWASP ZAP, Burp Suite, Nessus, etc.
      • +
      +
    • +
    +
  • +
  • +

    User and Role Management:

    +
      +
    • Configuration: +
        +
      • It is possible to directly set up users and assign roles (Admin, Staff, Developer, etc.) based on the level of access required. Using Keycloak based login is encouraged.
      • +
      • Manage permissions and ensure users have the correct access to products, engagements, and reports.
      • +
      +
    • +
    +
  • +
  • +

    Notifications and Reports:

    +
      +
    • Configuration: +
        +
      • Set up notifications to alert users about new findings, engagement updates, or product changes.
      • +
      • Generate reports to summarize findings, trends, and metrics for stakeholders.
      • +
      +
    • +
    +
  • +
+

Zuul

+

Based on how the jobs and tasks are defined across the automated scan pipelines, it is neccesary to define some variables and secrets at Zuul level in the .zuul.d/ folder of the repo.

+
    +
  • config.yaml +
      +
    • This file contains project specific zuul configuration related to jobs.
    • +
    • During checks, the pipeline is run with a mock test configuration in order to debug canges and determine if it works as expected.
    • +
    • Configuration: +
        +
      • scan_targets variable, under scs-security-scan-base job, controls what will be scanned. Only use IPv4 addresses and/or full domain names (Otherwise pipeline will fail).
      • +
      • It is mandatory to set timeout values based on the targets being defined for scanning, especially for the scs-greenbone-security-scan-base job, as greenbone ecosystem deployment and full scanning takes a very long time, which could cause workers to finish earlier than expected.
      • +
      +
    • +
    +
  • +
  • secrets.yaml +
      +
    • This file contains encrypted variables which may contain sensitive data: +
        +
      • dojo_api_key: API Token generated during DefecDojo configuration.
      • +
      • dojo_url: DefecDojo endpoint for importing scans in the form of https://<instance_url>/api/v2/import-scan/.
      • +
      • daily_scan_engagement_id: Engagement id for daily scans generated during DefecDojo configuration.
      • +
      • weekly_scan_engagement_id: Engagement id for weekly scans generated during DefecDojo configuration.
      • +
      +
    • +
    • In order to generate secrets it is recommended to use zuul-cli tool. As an example: echo -n "secret" | zuul-client --zuul-url https://zuul.sovereignit.cloud encrypt --tenant scs --project SovereignCloudStack/security-infra-scan-pipeline --field-name <variable_name>
    • +
    +
  • +
+

Aditional notes

+

With this configuration pipeline should work with its default configuration, uploading each scan results to DefctDojo for further analysis and tracking of the vulnerabilities found.

+

However, depending on user needs, it is possible to leverage included tools functionalities modifying the command being launched in their respective playbook. Options include, but not limited to, ports being scanned, requests rate-limit, threads spawned, templates/rules being used or response codes filtering, among others.

+

This provides a complete and very customizable toolkit to perform vulnerability assessments across a wide range of targers.

+

For further details refer to each tool official documentation.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/automated-pentesting-iaas/reports/index.html b/docs/operating-scs/components/automated-pentesting-iaas/reports/index.html new file mode 100644 index 0000000000..c3b64959fd --- /dev/null +++ b/docs/operating-scs/components/automated-pentesting-iaas/reports/index.html @@ -0,0 +1,146 @@ + + + + + +Using Automated Pentesting Reports for CSPs, Operators, and Users | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Using Automated Pentesting Reports for CSPs, Operators, and Users

+

This section outlines how Infrastructure Operators (Cloud Service Providers - CSPs) and users can leverage automated pentesting reports focused on Infrastructure-as-a-Service (IaaS) and Container-as-a-Service (CaaS) environments. +It explains the importance of daily and weekly reports for identifying and mitigating vulnerabilities, configuration issues, and security gaps in cloud infrastructure. Additionally, this documentation describes actionable +processes for vulnerability management, tailored for both environments, and provides insights for operations with and without a Security Operations Center (SOC).

+

Understanding the Pentesting Reports for IaaS and CaaS

+

Pentesting reports for IaaS and CaaS layers focus on identifying security weaknesses in cloud infrastructure and containerized environments. These reports are generated by automated tools designed to scan for:

+
    +
  • Open Ports and exposed services in IaaS environments.
  • +
  • Container Security: Assessing containerized environments for misconfigurations, unpatched vulnerabilities, and insecure networking settings.
  • +
  • Cloud Misconfigurations: Ensuring proper IAM (Identity and Access Management) policies, storage bucket configurations, and other cloud resource settings.
  • +
  • Compliance Gaps: Ensuring alignment with security policies and regulatory frameworks like CIS benchmarks and industry-specific standards.
  • +
+

Importance of Daily and Weekly Reports

+

Daily Reports

+

Daily reports provide real-time insights into the current state of cloud infrastructure. They focus on:

+
    +
  • Immediate Vulnerabilities: New misconfigurations, exposed services or detected container security flaws.
  • +
  • Rapid Incident Response: Helping CSPs and operators address critical issues quickly, reducing the window of exposure.
  • +
  • Change Monitoring: Keeping track of changes in cloud and container environments that could introduce risks, particularly for systems with continuous updates.
  • +
+

Weekly Reports

+

Weekly reports give a broader view of security health, highlighting trends and recurring issues. They are used to:

+
    +
  • Strategize Long-term Remediation: Address systemic problems like consistently misconfigured security groups or recurring container vulnerabilities.
  • +
  • Track Progress: Monitor how quickly vulnerabilities are being resolved and track overall improvement in security posture.
  • +
  • Policy Compliance: Provide a comprehensive overview for audits and compliance reporting, ensuring that security frameworks are being adhered to.
  • +
+

Key Characteristics and Capabilities of Reports

+
    +
  • Actionable Insights: Each report prioritizes vulnerabilities by severity, allowing teams to act efficiently and allocate resources accordingly.
  • +
  • Compliance Assurance: Continuous monitoring and scanning ensure compliance with security standards such as GDPR, HIPAA, and CIS benchmarks.
  • +
  • Detailed Analysis: Reports encompass vulnerabilities at different layers—network, applications, and containers—identifying open ports, unpatched software, and web app flaws.
  • +
+

Role and Responsibilities of Operators and Users

+

For Operators (high-level view):

+

Operators (CSPs) have a responsibility to ensure the security of the IaaS and CaaS layers they manage to protect their services and customer data. Key responsibilities include:

+
    +
  • Daily Monitoring: Use tools like Naabu and Httpx for open port discovery and service monitoring. Remediate any critical issues immediately, especially for public-facing services.
  • +
  • Configuration Audits: Regularly assess cloud resource configurations using Nuclei and other compliance-focused tools to ensure adherence to security policies.
  • +
  • Container Vulnerability Management: Ensure that containerized environments are properly isolated, updated, and hardened against known vulnerabilities.
  • +
+

For Operator's staff:

+

Operators are responsible for managing the security of cloud infrastructure, taking action based on the findings in the pentesting reports. Responsibilities include:

+
    +
  • Triage and Response: Review daily reports to prioritize high-risk vulnerabilities such as misconfigurations or container escape risks. Act immediately to close exposed ports or restrict access where needed.
  • +
  • Patch Management: Use weekly reports to identify vulnerabilities that require patching or configuration changes, especially in CaaS environments where container images may have known flaws.
  • +
  • Long-term Fixes: Address recurring issues by implementing security controls that reduce the likelihood of similar vulnerabilities appearing in the future.
  • +
+

For Users (DevOps):

+

DevOps teams must integrate security into the development lifecycle for IaaS and CaaS environments:

+
    +
  • Embed Tools in CI/CD: Automated scanning tools should be part of the CI/CD pipeline to catch vulnerabilities before production deployment.
  • +
  • Infrastructure as Code: Use pentesting insights to continuously improve cloud configuration templates, ensuring best practices are embedded in every deployment.
  • +
  • Monitor Application Security: Continuously review reports to ensure that containerized applications are not introducing new vulnerabilities or compliance issues.
  • +
+

Actions Based on Pentesting Reports

+
    +
  • Review Daily Reports +
      +
    • Prioritize Critical Vulnerabilities: Focus first on critical issues such as open ports, misconfigurations, and unpatched containers. Use tools like Naabu for open ports and ZAP Proxy for application layer vulnerabilities.
    • +
    • Validate Exposed Services: Ensure any services flagged as exposed are necessary. If not, restrict or close access.
    • +
    +
  • +
  • Immediate Response +
      +
    • Apply Patches: For vulnerabilities in container images or cloud configurations, apply patches immediately using automated pipelines where possible.
    • +
    • Remediate Misconfigurations: Correct any misconfigurations flagged in identity, access management (IAM), or resource policies to prevent exploitation.
    • +
    +
  • +
  • Automate Responses +
      +
    • Use Predefined Rules: Set up automatic responses for common issues such as closing ports or restarting vulnerable services. Implement this via configuration management tools or CI/CD pipelines.
    • +
    • Integration with Monitoring Tools: Integrate the pentesting results with monitoring tools for real-time alerting and response automation, reducing manual efforts.
    • +
    +
  • +
  • Document Actions +
      +
    • Track Resolutions: Use vulnerability management platforms like DefectDojo to track issues resolved throughout the day. Ensure all critical vulnerabilities are documented and tracked to completion.
    • +
    • Generate Daily Reports for Management: Summarize critical vulnerabilities addressed and ongoing risks for reporting purposes.
    • +
    +
  • +
  • Plan for Continuous Scans +
      +
    • Rerun Scans After Fixes: Ensure new scans are initiated after significant patches or configuration changes to validate that vulnerabilities have been fully mitigated.
    • +
    +
  • +
  • Feedback Loop +
      +
    • Refine Pipelines: Use insights from recurring vulnerabilities or issues to improve your IaaS and CaaS configuration templates and pentesting configurations.
    • +
    +
  • +
+

By following these steps daily, teams can ensure they stay on top of vulnerabilities, continuously improving their cloud infrastructure security posture.

+

SOC Operations

+

A SOC (Security Operations Center) is crucial for larger organizations to centralize threat detection, vulnerability management, and incident response. +It allows for rapid response to vulnerabilities identified in pentesting reports, providing 24/7 monitoring and remediation capabilities. +However it is also possible for smaller teams (without a dedicated SOC) to take advantage of these reports.

+

With a SOC

+
    +
  • Daily Triage and Monitoring: SOC teams use pentesting reports to triage vulnerabilities, prioritizing critical risks such as exposed ports, misconfigurations, and unpatched containers.
  • +
  • Vulnerability Ticketing: Use platforms like DefectDojo to assign vulnerabilities to appropriate teams, tracking their resolution.
  • +
  • Incident Response: High-priority vulnerabilities are immediately addressed, with automated workflows in place to deploy fixes or isolate compromised services.
  • +
  • Documentation: Weekly reports are used for documenting resolved vulnerabilities and tracking recurring issues, providing a basis for long-term improvements.
  • +
+

Without a SOC:

+
    +
  • Manual Review: Without a SOC, designated IT or DevOps teams must manually review daily pentesting reports. High-risk vulnerabilities should be addressed immediately, while lower-risk issues can be prioritized based on business impact.
  • +
  • Automation: Automate remediation processes where possible (e.g., automated patching of containers or closing of exposed ports) to reduce manual effort and response time.
  • +
  • Long-term Monitoring: Use weekly reports to monitor recurring vulnerabilities and address the root causes, ensuring systemic issues are resolved over time.
  • +
+

Future Policy Development

+

Pentesting reports not only drive immediate security actions but also form the backbone for long-term security policy development. +They provide a continuous stream of vulnerability data that can be used to craft policies around patch management, incident response, and compliance enforcement. This continuous cycle of vulnerability identification and remediation supports the development of:

+
    +
  • Risk-Based Patch Management Policies: Define timelines for addressing vulnerabilities based on their severity and potential impact on cloud services.
  • +
  • Security Audits and Compliance: Use the reports as evidence of compliance with industry standards, like CIS benchmarks ir GPDR, allowing for continuous audits and ensuring regulatory alignment.
  • +
  • Incident Response Plans: Establish guidelines for handling vulnerabilities identified in pentesting reports, ensuring quick and effective responses to critical risks.
  • +
+

Conclusion

+

Pentesting reports provide crucial insights that enable CSPs, operators, and users to maintain a proactive security posture. +SOC teams, or in their absence, designated personnel, should use these reports to address vulnerabilities, manage risks, and improve infrastructure security. +Daily and weekly reports guide both immediate and long-term actions, ensuring that vulnerabilities are addressed promptly and systemic issues are resolved through strategic security improvements.

+

By using pentesting reports effectively, organizations can improve their vulnerability management processes, maintain compliance, and enhance their overall security strategy.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/automated-pentesting-iaas/tools/index.html b/docs/operating-scs/components/automated-pentesting-iaas/tools/index.html new file mode 100644 index 0000000000..0638b01869 --- /dev/null +++ b/docs/operating-scs/components/automated-pentesting-iaas/tools/index.html @@ -0,0 +1,103 @@ + + + + + +Tools Description | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Tools Description

+

The following tools make up the automated pentesting pipeline.

+

Naabu

+
    +
  • Functionality: Naabu is a port scanning tool used for identifying open ports on a target host or IP range, crucial for initial reconnaissance in penetration testing.
  • +
  • Capabilities: +
      +
    • Fast Scanning: Utilizes a high-speed, asynchronous approach for efficient port scanning.
    • +
    • Multiple Output Formats: Supports text, JSON, and XML formats for integration with other tools.
    • +
    • Flexible Target Specification: Capable of scanning individual hosts, IP ranges, or CIDR notations.
    • +
    • Custom Port Ranges: Allows scanning specific port ranges or using standard lists of common ports.
    • +
    +
  • +
  • Updates: Regularly updated for performance improvements and new features.
  • +
+

HTTPx

+
    +
  • Functionality: HTTPx is a powerful HTTP toolkit for web server fingerprinting, crucial for identifying web technologies and analyzing responses from web servers.
  • +
  • Capabilities: +
      +
    • High-Speed HTTP Detection: Efficient in analyzing HTTP servers and responses.
    • +
    • Status Code Retrieval: Collects HTTP status codes to identify live hosts and valid endpoints.
    • +
    • Custom Headers and Methods: Supports advanced HTTP requests for detailed analysis.
    • +
    • Automation-Friendly: Easily integrates into automated workflows and pipelines.
    • +
    +
  • +
  • Updates: Continuously updated with enhancements for speed, accuracy, and additional features.
  • +
+

Nuclei

+
    +
  • Functionality: Nuclei is a template-based vulnerability scanner, essential for detecting known vulnerabilities using predefined and community-driven templates.
  • +
  • Capabilities: +
      +
    • Extensive Template Library: Wide range of continuously updated templates for various vulnerabilities.
    • +
    • Custom Template Creation: Allows creation of tailored templates for specific environment needs.
    • +
    • Broad Vulnerability Coverage: Capable of scanning a variety of security weaknesses and exposures.
    • +
    • Integration-Ready: Designed to fit seamlessly into CI/CD pipelines.
    • +
    +
  • +
  • Updates: Community and developers regularly update templates and tool features.
  • +
+

Greenbone Community Edition (OpenVAS)

+
    +
  • Functionality: Greenbone CE, known as OpenVAS, is a full-featured vulnerability scanner for comprehensive assessments of networks, hosts, and applications.
  • +
  • Capabilities: +
      +
    • Wide Range of Tests: Offers a broad spectrum of network and application vulnerability tests.
    • +
    • Regular Feed Updates: The vulnerability feed is frequently updated for new threats.
    • +
    • Scan Customization: Supports various scan configurations and scheduling.
    • +
    • Detailed Reporting: Generates comprehensive reports for compliance and remediation planning.
    • +
    +
  • +
  • Updates: Maintained with regular updates to the vulnerability feed and software enhancements.
  • +
+

ZAP Proxy

+
    +
  • Functionality: ZAP Proxy is an intercepting proxy for dynamic application security testing (DAST), vital for identifying vulnerabilities in web applications.
  • +
  • Capabilities: +
      +
    • Passive and Active Scanning: Provides both passive scanning (traffic analysis) and active scanning (direct testing).
    • +
    • Comprehensive Web App Mapping: Includes tools like Spider and AJAX Spider for thorough application mapping.
    • +
    • Supports Various Authentication Types: Handles different web application authentication mechanisms.
    • +
    • Extensibility: Offers a range of plugins and extensions for additional functionalities.
    • +
    +
  • +
  • Updates: Regularly updated with new features and security tests.
  • +
+

Defect Dojo

+
    +
  • Functionality: Defect Dojo is a security program and vulnerability management tool. It centralizes and streamlines the management of security programs, allowing for efficient tracking, measurement, and reporting of vulnerabilities.
  • +
  • Capabilities: +
      +
    • Vulnerability Management: Enables tracking and management of vulnerabilities discovered across different tools and tests.
    • +
    • Reporting and Metrics: Offers comprehensive reporting features for understanding security postures and metrics.
    • +
    • Integration with CI/CD: Seamlessly integrates with CI/CD pipelines for automated importing of scan results.
    • +
    • Customization and Flexibility: Allows customizations to fit various workflow requirements and integrates with other tools via APIs.
    • +
    +
  • +
  • Updates: Regularly updated with enhancements for functionality, usability, and security.
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/automated-pentesting-kaas/overview/index.html b/docs/operating-scs/components/automated-pentesting-kaas/overview/index.html new file mode 100644 index 0000000000..5ca141f7ab --- /dev/null +++ b/docs/operating-scs/components/automated-pentesting-kaas/overview/index.html @@ -0,0 +1,65 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

Introdution

+

When we talk about Kubernetes and cloud operations, we're discussing two scenarios with potential vulnerabilities. It's not like other situations where you can have a single focus; here, you need to be constantly vigilant about what's happening. As a platform for deploying applications, Kubernetes becomes a critical system.Modern cloud infrastructure security is a complex and critical aspect of maintaining robust and resilient cloud services. Moreover, as organizations increasingly rely on cloud environments for their operations, the security of these infrastructures becomes paramount

+

The Container-as-a-Service layer in SCS, is susceptible to various security threats. To address these concerns, continuous and automated security is essential when we working with applications.

+

For this reason, the generated reports are also used to track all these issues, and continuous monitoring is applied to ensure the resolution of the vulnerabilities found.

+

Kubernetes Security Concerns

+

Cloud infrastructure security involves protecting data, applications, and services from unauthorized access and threats security challenges, in Kubernetes, you must covering both infrastructure and application-related issues:

+

Infrastructure Security Challenges in Kubernetes:

+
    +
  1. Misconfigured Cluster Components: Kubernetes clusters consist of various components like the API server, etcd, kubelet, and controller manager. Misconfigurations in these components can lead to unauthorized access, data leakage, and service disruptions.
  2. +
  3. Inadequate Network Policies: Without proper network policies, unauthorized services might communicate with each other, leading to potential lateral movement of threats across the cluster.
  4. +
  5. Unsecured API Server: The Kubernetes API server is the central control point for the entire cluster. Weak authentication and authorization mechanisms can expose the cluster to unauthorized access and potential exploits.
  6. +
  7. Insufficient TLS Encryption: Communication between Kubernetes components, including the API server, etcd, and nodes, should be encrypted using TLS. Lack of proper encryption can lead to man-in-the-middle attacks and data interception.
  8. +
  9. Vulnerable etcd Configuration: etcd stores all the cluster data, including secrets and configurations. If not properly secured, an attacker could gain access to sensitive information, potentially compromising the entire cluster.
  10. +
  11. Improper Use of Privileged Containers: Running containers with elevated privileges or allowing access to the host filesystem can lead to a compromise of the host system or other containers.
  12. +
  13. Insecure Container Images: Using container images from untrusted sources or without scanning them for vulnerabilities can introduce security risks into the cluster.
  14. +
+

Application Security Challenges in Kubernetes:

+
    +
  1. Insecure Container Images: Similar to infrastructure, deploying applications with unverified or outdated container images can introduce known vulnerabilities, increasing the attack surface.
  2. +
  3. Excessive Container Privileges: Applications running with more privileges than necessary can lead to potential security breaches if the application is compromised.
  4. +
  5. Lack of Resource Quotas and Limits: Without setting resource quotas and limits, a compromised application could exhaust cluster resources, leading to Denial of Service (DoS) attacks.
  6. +
  7. Improper Secret Management: Storing application secrets (e.g., API keys, credentials) in unsecured locations or without proper encryption can expose them to unauthorized access.
  8. +
  9. Vulnerable Dependencies: Applications often rely on third-party libraries and dependencies. Without regular updates and vulnerability scanning, these dependencies can introduce security risks.
  10. +
  11. Unsecured Service Exposures: Exposing application services without proper security measures (like ingress controllers with TLS, firewalls, etc.) can make them vulnerable to external attacks.
  12. +
  13. Lack of Security Context and Policies: Applications should be deployed with defined security contexts and policies to ensure they run with the least privilege necessary. Without these, applications are more susceptible to attacks.
  14. +
+

In summary, securing Kubernetes requires a comprehensive approach that addresses both the infrastructure and the applications deployed on it. This includes proper configuration, encryption, privilege management, and regular security audits to identify and mitigate potential vulnerabilities.

+

Infrastructure and application scanning

+

Here’s an overview in English of what Trivy does when scanning images, infrastructure, and using the Trivy operator for internal scanning:

+

Scanning Images with Trivy:

+

When Trivy scans container images, it performs a deep inspection of the image layers. Internally, Trivy pulls the image from a container registry and unpacks it to examine the filesystem and all the packages installed within the image. It looks for known vulnerabilities by comparing the image's software packages against a database of known CVEs (Common Vulnerabilities and Exposures). Trivy supports various package managers (e.g., apt, yum, pip, npm) and can detect vulnerabilities in operating system packages as well as application dependencies. Trivy also checks for misconfigurations, such as insecure file permissions or exposed secrets, that could pose security risks.

+

Scanning Infrastructure with Trivy:

+

For infrastructure-as-code (IaC) scanning, Trivy inspects configuration files like Terraform, Kubernetes manifests, Dockerfiles, and other IaC templates. Internally, it parses these files and checks them against a set of security rules and best practices. Trivy identifies misconfigurations that could lead to security issues, such as overly permissive access controls, unencrypted data storage, and insecure network configurations. The scanning process is rule-based, and the results highlight potential risks before the infrastructure is deployed, allowing teams to address them early in the development process.

+

Trivy Operator for Internal Scanning:

+

The Trivy operator is designed to work within a Kubernetes cluster, performing continuous security scans of running workloads. Internally, the operator automatically scans Kubernetes resources, including pods, images, and configurations, as they are deployed or updated in the cluster. It integrates directly with Kubernetes, using Kubernetes events and controllers to trigger scans. The operator then reports on vulnerabilities, misconfigurations, and compliance issues directly within the cluster environment. The results can be surfaced via Kubernetes CRDs (Custom Resource Definitions) and integrated with other tools or CI/CD pipelines for further action.

+

Quickstart Guide

+

See the quickstart page.

+

Tools

+

See the tools page.

+

Source

+

github.com/SovereignCloudStack/security-k8s-scan-pipeline.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/automated-pentesting-kaas/quickstart/index.html b/docs/operating-scs/components/automated-pentesting-kaas/quickstart/index.html new file mode 100644 index 0000000000..45c948281d --- /dev/null +++ b/docs/operating-scs/components/automated-pentesting-kaas/quickstart/index.html @@ -0,0 +1,92 @@ + + + + + +Quickstart Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Quickstart Guide

+

This document provides a quick guide to setting up and running the security scanning infrastructure using Trivy and other related tools.

+

Prerequisites

+

Before you begin, make sure you have the following prerequisites installed in your environment:

+
    +
  • Kubernetes Cluster
  • +
  • Helm 3.x
  • +
  • Credential setup in HashiCorp Vault
  • +
  • Access to OpenStack (for storing results)
  • +
+

Project Structure

+

The project structure is organized as follows:

+
.
├── cronjob
│ ├── configmap.yaml
│ └── trivy-cronjob.yaml
├── trivy-operator
│ └── values.yaml
└── trivy-reporter
└── values.yaml
+

Main Files

+

1. cronjob/configmap.yaml

+

This file defines a ConfigMap that is used to store configurations and scripts necessary for executing the CronJob that performs security scans using Trivy.

+
    +
  • Primary Use: Store scripts and configurations that will be used by the CronJob.
  • +
  • Important: Ensure that the scripts stored in this ConfigMap are correctly formatted and configured to run in the Kubernetes environment.
  • +
+

2. cronjob/trivy-cronjob.yaml

+

This file defines a CronJob in Kubernetes that is responsible for periodically running the security scan using Trivy.

+
    +
  • Schedule: The CronJob is configured to run at specific intervals defined in the file.
  • +
  • Containers: It uses several containers, including trivy-reports-getter for fetching the reports and trivy-reports-uploader for uploading the results to an external storage like OpenStack.
  • +
  • Configurations: Ensure that all configurations, including volumes and initContainers, are correctly set up before deploying this CronJob.
  • +
+

3. trivy-operator/trivy_results.json

+

This file contains an example JSON output generated by Trivy after performing a security scan.

+
    +
  • Usage: Used as an example or reference to analyze the results of the scans.
  • +
  • Important: This file can be used to conduct local tests on scripts that process Trivy's scan results.
  • +
+

4. trivy-operator/values.yaml

+

This file contains specific configurations for deploying the trivy-operator using Helm.

+
    +
  • Configuration: Defines the values to customize the deployment of the Trivy operator in the Kubernetes cluster.
  • +
  • Note: Ensure to customize this file according to your environment's needs before deploying.
  • +
+

5. trivy-reporter/values.yaml

+

This file contains specific configurations for the trivy-reporter tool.

+
    +
  • Purpose: Used to configure how reports should be generated and processed after Trivy performs a scan.
  • +
  • Configuration: Customize this file according to the environment and the report you wish to generate.
  • +
+

Deployment

+

To deploy the security scanning infrastructure, follow the steps below:

+
    +
  1. +

    Configure ConfigMaps and Secrets: +Ensure all necessary ConfigMaps and Secrets are properly created in your Kubernetes cluster.

    +
     kubectl apply -f cronjob/configmap.yaml
    +
  2. +
  3. +

    Deploy the CronJob: +Deploy the CronJob that will run the periodic scans.

    +
     kubectl apply -f cronjob/trivy-cronjob.yaml
    +
  4. +
  5. +

    Deploy Trivy Operator: +Use Helm to deploy the trivy-operator in your cluster.

    +
     helm install trivy-operator trivy-operator/ -f trivy-operator/values.yaml
    +
  6. +
  7. +

    Deploy Trivy Reporter: +Use Helm to deploy the trivy-reporter in your cluster.

    +
     helm repo add trivy-dojo-report-operator https://telekom-mms.github.io/trivy-dojo-report-operator/
    helm repo update
    helm install chart-name trivy-dojo-report-operator/trivy-dojo-report-operator --values trivy-reporter/values.yaml
    +
  8. +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/automated-pentesting-kaas/tools/index.html b/docs/operating-scs/components/automated-pentesting-kaas/tools/index.html new file mode 100644 index 0000000000..a571a0550d --- /dev/null +++ b/docs/operating-scs/components/automated-pentesting-kaas/tools/index.html @@ -0,0 +1,84 @@ + + + + + +Tools Description | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Tools Description

+

The following tools make up the automated scanning pipeline and report sending.

+

Trivy Container

+
    +
  • Functionality: Trivy is a open source scanner for docker and kubernetes, is commonly used to find vulnerabilities even in infrastructure side.
  • +
  • Capabilities: +
      +
    • Multiple Output Formats: Supports text, JSON, CyclonDX and XML formats for integration with other tools.
    • +
    • Flexible Target Specification: Capable of scanning individual namespaces, whole cluster and specific resource.
    • +
    • Broad Vulnerability Coverage: Capable of scanning a variety of security weaknesses and exposures.
    • +
    • Automation-Friendly: Easily integrates into automated workflows and pipelines.
    • +
    +
  • +
  • Updates: Twice per day updated DB for keep all vulnerability in scope.
  • +
+

Trivy Operator

+
    +
  • Functionality: Same as above but the big different is it is inside kubernete and is triggered automatically when is a new change in any kubernetes component or application.
  • +
  • Capabilities: +
      +
    • Fast Scanning: Run diffrents scanners at the same time making parallelism.
    • +
    • Automation-Friendly: Is triggered automatically when a new resourse is deployed.
    • +
    • Broad Vulnerability Coverage: Capable of scanning a variety of security weaknesses and exposures.
    • +
    • Detailed Reporting: Generates comprehensive reports for vulnerabilities or compliance and remediation planning.
    • +
    +
  • +
  • Updates: Continuously updated with enhancements for speed, accuracy, and additional features.
  • +
+

Trivy Reporter

+
    +
  • Functionality: This operator is used to send report to Defect Dojo automatically once is genereted by Trivy Operator.
  • +
  • Capabilities: +
      +
    • Integration-Ready: Designed to fit with trivy operator.
    • +
    +
  • +
  • Updates: Community and developers regularly update tool features.
  • +
+

Kubernetes CronJob

+
    +
  • Functionality: This is a specfic developed component to send whole reports to S3 bucket to maintain all information saved in one place.
  • +
  • Capabilities: +
      +
    • Automation-Friendly: Is triggered automatically depending when we want to sent the reports.
    • +
    +
  • +
  • Updates: Maintained with regular updates to the vulnerability feed and software enhancements.
  • +
+

Defect Dojo

+
    +
  • Functionality: Defect Dojo is a security program and vulnerability management tool. It centralizes and streamlines the management of security programs, allowing for efficient tracking, measurement, and reporting of vulnerabilities.
  • +
  • Capabilities: +
      +
    • Vulnerability Management: Enables tracking and management of vulnerabilities discovered across different tools and tests.
    • +
    • Reporting and Metrics: Offers comprehensive reporting features for understanding security postures and metrics.
    • +
    • Integration with CI/CD: Seamlessly integrates with CI/CD pipelines for automated importing of scan results.
    • +
    • Customization and Flexibility: Allows customizations to fit various workflow requirements and integrates with other tools via APIs.
    • +
    +
  • +
  • Updates: Regularly updated with enhancements for functionality, usability, and security.
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/central-api/overview/index.html b/docs/operating-scs/components/central-api/overview/index.html new file mode 100644 index 0000000000..861924f44f --- /dev/null +++ b/docs/operating-scs/components/central-api/overview/index.html @@ -0,0 +1,144 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

Premise

+

By embracing existing open source solutions and bundling them, SCS provides a viable +alternative to widely adopted proprietary cloud offerings, including +Infrastructure-as-a-Service offerings, Kubernetes-as-a-Service offerings and other +X-as-a-Service offerings.

+

The choice to embrace existing technology has huge advantages over starting from +scratch. +By not reinventing wheels, a lot of effort is saved and existing communities are +strengthened. The adoption of existing open standards is supported, reducing +market fragmentation and increasing interoperability.

+

Challenge

+

The challenge: Using popular open source components at cloud service providers +does not result in a consistent experience for their users, yet.

+

Each part of the stack is consistent within its own scope: E.g. The +OpenStack Networking API is sort of +consistent with the +OpenStack Load Balancer API.

+

The OpenStack API's share API idioms like the used AuthN/AuthZ +(Authentication/Authorization) mechanisms. But these are not applicable beyond +OpenStack services.

+

Entering general IAM (Identity and Access Management), Keycloak has its own set of +API endpoints and authentication flows. +Entering Kubernetes, CAPI (Kubernetes Cluster API) +uses the Kubernetes API with its own authentication configuration, RBAC (Role Based +Access Control) and opinionated resource management idioms.

+

So, without a central API harmonizing at least the semantics of AuthN/AuthZ and +resource management, users are left with a bunch of semantically incompatible API's. +If resources in different API's are somehow interconnected, the users have to take +care of bridging these differences themselves.

+

Providing a consistent API across many different offerings with sort of consistent +API idioms is something that primarily the big proprietary cloud providers manage to +do. And while that serves users well in that regard, it also serves as an effective +vendor lock-in feature.

+

The chosen approach to pursue

+ +

Goal: Provide a "semantically" consistent API modelling most cloud resources +that are in scope for SCS.

+

In other words: Bring each cloud resource type - as it is - into the central API.

+

An OpenStack Compute Instance continues to be as-is with all of its usual +properties and implementation details. +A Keycloak Realm continues to be as-is with all of its usual properties +and implementation details.

+

That is not to say that abstractions are absolutely not planned as further steps. +There were discussions happening about that already: Regarding IAM management 1 +and Kubernetes management 2.

+

However, the main benefit is that all offered API objects can be managed +using the same API idioms (AuthN/AuthZ/REST) with the same client tooling 3.

+

Kubernetes API

+

Instead of creating SCS-specific API idioms and building the implementation +from scratch, the Kubernetes API will be "reused". Essentially, the Kubernetes +API is just an opinionated REST API which has opinions on how a resource +is defined, how it looks like, how it is reconciled/handled, how AuthN/AuthZ +can be implemented. The Kubernetes ecosystem provides much tooling for working +with such (custom) resource definitions: For creating the definitions +themselves, building controllers, making them discoverable and deployable.

+

As such, Kubernetes is a great choice for building any sort of resource +management API - with some caveats regarding its deployment and the legacy +of starting off as container orchestration tooling.

+

Crossplane tooling

+

Crossplane even extends the Kubernetes API with +"Compositions" and +"Composite Resource Definitions" +(XRD) to make Kubernetes the base for platform engineering within organizations.

+

Secondly, it provides an API machinery to bring any cloud resource into Kubernetes +using backend-specific "providers" (roughly comparable with Terraform providers). +As such, Crossplane with its provider ecosystem actually already did most of +the heavy lifting for providing e.g. OpenStack or Keycloak resources inside of Kubernetes.

+

On top, the platform engineering concepts in Crossplane make building multi-tenancy +systems pretty straight-forward, even for +single clusters.

+

Alright. Crossplane takes care of exposing OpenStack resources and does some +fancy stuff regarding multi-tenancy. What about providing actual Kubernetes +workload clusters?

+

Cluster stacks / Cluster API

+

Cluster stacks do +not replace the use of Cluster API. +Instead, they are complementing Cluster API by providing ClusterClasses, node +images (if required) and workload cluster addons.

+

It is still to be determined how to bring multi-tenancy concepts from Crossplane +into ClusterStacks/CAPI, if even required.

+

Should the provider be responsible for creating ClusterClasses? +If yes, enforcing some parameters inside via a ClusterClass may be enough +to provide multi-tenancy, already. That is to be determined, though.

+

Implementation

+

Disregarding any potential further abstractions, most work in automation for +the providers will be about installing the central API and securely distributing +credentials for backing services like OpenStack or Keycloak. +For that, there is no production implementation yet. See +the POC for inspiration for now. It includes access to an OpenStack API +through Kubernetes/Crossplane.

+ +

Footnotes

+
    +
  1. +

    There were discussions to build a generic SCS API to support +SCS installations powered by Zitadel. Approaching the issue a little +bit like the "Abstract all the things!" consideration above, but focusing +on two basic use cases (Firstly, setting up an identity federation to some +existing identity provider; Secondly, managing users without remote identity +provider). While not in scope for the first steps, this probably could be +elegantly implemented as one generic Crossplane "Composite Resource Definition" +backed by a Crossplane "Composition" defining either Keycloak objects OR +Zitadel objects (given that Zitadel gets a Crossplane provider or a similar +Kubernetes controller before).

    +
  2. +
  3. +

    In order to cover providers that use Gardnener, a generic Crossplane +"Composite Resource Definition" like in 1 may be created. Alternatively, +Gardnener CRD's could maybe just be mirrored in their Central API instance, +still creating an interoperability benefit through "semantic" compatibility.

    +
  4. +
  5. +

    Which is also not to say that it will be suggested to providers to disable +their public OpenStack/Keycloak/... API's, preventing use of native +OpenStack/Keycloak/... tooling and breaking existing solutions. +Extensively using these API's together with the central API may compromise +the benefits of its uniform AuthZ, though.

    +
  6. +
+
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/central-api/poc-setup/index.html b/docs/operating-scs/components/central-api/poc-setup/index.html new file mode 100644 index 0000000000..615327fe88 --- /dev/null +++ b/docs/operating-scs/components/central-api/poc-setup/index.html @@ -0,0 +1,47 @@ + + + + + +Central API MVP | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Central API MVP

+

Right now, this repository implements issue 374. +It contains a script (gen.py) to mirror all crossplane openstack provider cluster-scoped resources to namespaced resources in an SCS API group.

+

Also, these instructions are striving to implement namespaces as isolation mechanism to implement a multi-tenant system backed by a single Kubernetes cluster.

+

crossplane-contrib/x-generation might be used as soon as the required feature for namespace mapping is implemented.

+

Quick Start

+
    +
  1. Setup testing Kubernetes cluster
  2. +
  3. Install crossplane
  4. +
  5. Select fitting configuration package (containing provider definitions, XRD's and composites) and install it +
    export VERSION=...
    export XPKG=... # openstack / kubernetes
    crossplane xpkg install configuration registry.scs.community/central-api/$XPKG:$VERSION
    +
  6. +
  7. Setup provider config (wearing CSP hat) +
    apiVersion: v1
    kind: Namespace
    metadata:
    name: tenant-name
    ---
    apiVersion: openstack.upbound.io/v1beta1
    kind: ProviderConfig
    metadata:
    name: tenant-name
    spec:
    credentials:
    secretRef:
    namespace: crossplane-system
    name: tenant-name-clouds-yaml
    key: clouds.json
    source: Secret
    ---
    apiVersion: v1
    kind: Secret
    metadata:
    name: tenant-name-clouds-yaml
    namespace: crossplane-system
    stringData:
    clouds.json: |
    {
    "auth_url": "https://api.gx-scs.sovereignit.cloud:5000",
    "application_credential_id": "...",
    "application_credential_secret": "...",
    "tenant_name": "tenant-name"
    }
    +
  8. +
  9. Setup RBAC for tenants (wearing CSP hat) +
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
    name: tenant
    rules:
    - apiGroups:
    - api.scs.community
    resources:
    - '*'
    verbs:
    - '*'
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
    name: tenant
    namespace: tenant-name
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
    name: scs-bind
    namespace: tenant-name
    roleRef:
    apiGroup: rbac.authorization.k8s.io
    kind: ClusterRole
    name: tenant
    subjects:
    - kind: ServiceAccount
    name: tenant
    namespace: tenant-name
    +
  10. +
  11. Create resource (wearing tenant hat, kubectl --as system:serviceaccount:tenant-name:tenant -n tenant-name) +
    apiVersion: api.scs.community/v1alpha1
    kind: KeypairV2
    metadata:
    name: admin
    namespace: tenant-name
    spec:
    name: admin-keypair
    publicKey: |-
    ssh-rsa ...
    ---
    apiVersion: api.scs.community/v1alpha1
    kind: InstanceV2
    metadata:
    name: testing-vm
    namespace: tenant-name
    spec:
    name: testing-vm
    keyPair: admin-keyPair
    imageName: 'Debian 12'
    flavorName: 'SCS-1V:1:20'
    +
  12. +
  13. Observe creation of resources
  14. +
+

Right now, it would be expected to hand out the ServiceAccount token to the actual tenant; When AuthN is done via OIDC (or other means), the ServiceAccount tenant-name/tenant may be dropped and RoleBinding tenant-name/scs-bind may point to an actual user/group.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/alertmanager/index.html b/docs/operating-scs/components/monitoring/docs/alertmanager/index.html new file mode 100644 index 0000000000..5e15ac495a --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/alertmanager/index.html @@ -0,0 +1,32 @@ + + + + + +Alertmanager notifications in Matrix chat | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Alertmanager notifications in Matrix chat

+

This page contains instructions on how to enable the Alertmanager to Matrix chat notifications in the Observer solution.

+

Project https://github.com/metio/matrix-alertmanager-receiver is used for forwarding alerts to a Matrix room.

+

To use it, fill your matrix credentials in matrix-alertmanager/matrix-alertmanager-receiver.yaml ConfigMap and deploy it:

+
kubectl apply -f matrix-alertmanager/matrix-alertmanager-receiver.yaml
+

You can modify other settings according to the mentioned project docs +in the ConfigMap.

+

You have to also uncomment a related section in values-observer.yaml alertmanager section. +The sections related to Alertmanager notifications in the values-observer-scs.yaml values file are already uncommented.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/iaas/index.html b/docs/operating-scs/components/monitoring/docs/iaas/index.html new file mode 100644 index 0000000000..d8c8143cb5 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/iaas/index.html @@ -0,0 +1,136 @@ + + + + + +IaaS monitoring (experimental) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

IaaS monitoring (experimental)

+

This component is marked as experimental, and it is not part of the reference SCS installation available +at https://monitoring.scs.community.

+

IaaS monitoring currently integrates and is able to observe the following targets:

+ +

Prerequisites

+

To test the Monitoring of the IaaS layer we expect running Kubernetes cluster that already contains +SCS monitoring platform.

+

Local environment use case - KinD/K3s cluster deployed locally

+

KinD

+

Install the SCS monitoring solution into the KinD Kubernetes cluster following the instructions provided in +the quickstart guide.

+

K3s

+

Install the SCS monitoring solution into the K3s Kubernetes cluster following the instructions provided in +the k3s guide.

+

OSISM use case - K3s cluster in OSISM deployment

+

OSISM utilizes the k3s distribution of Kubernetes +as a management cluster for the OSISM IaaS platform. This management cluster is then used as a host for +the SCS monitoring solution. Subsequently, the management cluster becomes an Observer cluster as it hosts +the SCS monitoring solution. +From that point, the Observer cluster observes itself (i.e., k3s cluster control plane components and nodes) and is used +for observing the IaaS layer around the k3s cluster.

+

In the case of the existing OSISM IaaS deployment >= 7.0.3 on +baremetal, testbed or cloud in the box +we expect a management k3s Kubernetes cluster with the deployed SCS monitoring platform. +If your OSISM installation does not meet the above requirements, apply the following plays:

+
osism apply kubernetes
osism apply kubernetes-monitoring
+

Deploy IaaS monitoring components

+

OpenStack

+

Prometheus metrics and alerts

+

The OpenStack exporter for Prometheus could be deployed using the SCS openstack-exporter-helm-chart. +This exporter contains a bunch of Prometheus alerts and rules +that are deployed together with the exporter. +Visit the iaas/openstack-exporter-values.yaml file to validate the Helm configuration options. +Ensure valid OpenStack API credentials are set under the clouds_yaml_config section. This MUST be overridden!

+
helm upgrade --install prometheus-openstack-exporter oci://registry.scs.community/openstack-exporter/prometheus-openstack-exporter \
--version 0.4.5 \
-f iaas/openstack-exporter-values.yaml # --set "endpoint_type=public" --set "serviceMonitor.scrapeTimeout=1m"
+

Tip: If you want to test the exporter basic functionality with public OpenStack API, configure endpoint_type +to public (--set "endpoint_type=public"). Note that configuring endpoint_type as public will result in +incomplete functionality for the Grafana dashboard.

+

Tip: Requesting and collecting metrics from the OpenStack API can be time-consuming, especially if the API is not +performing well. In such cases, you may observe timeouts on the Prometheus server when it tries to fetch OpenStack +metrics. To mitigate this, consider increasing the scrape interval to e.g. 1 minute (--set "serviceMonitor.scrapeTimeout=1m").

+

Grafana dashboards

+

The Grafana dashboard designed to visualize metrics collected from an OpenStack cloud through the OpenStack exporter +is publicly available at https://grafana.com/grafana/dashboards/21085. Its source code is located in the +iaas/dashboards directory. Feel free to import it to the Grafana via its source or ID. +For automatic integration into the SCS monitoring solution proceed to the next step.

+

Update the SCS monitoring deployment

+

This step deploys the Grafana dashboards and instructs the monitoring stack to add the OpenStack exporter target into the Prometheus configuration:

+
helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack --reset-then-reuse-values -f iaas/values-observer-iaas.yaml
+
    +
  • Note: The --reset-then-reuse-values option requires Helm v3.14.0 or later. Alternatively, you can use the original values +by applying -f values-observer.yaml, see full command: helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml -f iaas/values-observer-iaas.yaml
  • +
+

Access the OpenStack dashboard

+

At this point, you should have the ability to access the Grafana UI, and OpenStack dashboard.

+

Log in to the Grafana UI and find the OpenStack dashboard in IaaS directory:

+
http://localhost:30000
+

or directly access the OpenStack dashboard:

+
http://localhost:30000/d/openstack-overview
+
    +
  • Use the following credentials: +
      +
    • username: admin
    • +
    • password: pass
    • +
    +
  • +
+

Ceph

+

The SCS IaaS reference implementation (OSISM) currently supports ceph-ansible +method for deploying Ceph. Support for the rook operator deployment method will be available soon.

+

This guide covers Ceph cluster monitoring for both deployment methods. While both expose the same metrics via the same +endpoint, there are some differences in Prometheus configuration and alerts.

+

Prometheus metrics and alerts

+

Ceph contains 2 build-in sources of metrics a.k.a. exporters. +The Ceph exporter (introduced in Reef release of Ceph) is the main source of Ceph performance metrics. It runs as a +dedicated daemon. This daemon runs on every Ceph cluster host and exposes a metrics end point where all the performance +counters exposed by all the Ceph daemons running in the host are published in the form of Prometheus metrics.

+

The second source of metrics is the Prometheus manager module. It exposes metrics related to the whole cluster, +basically metrics that are not produced by individual Ceph daemons.

+

Read the related Ceph docs. +Since these exporters are integrated with Ceph, deploying a third-party Ceph exporter is unnecessary.

+

Prometheus alerts

+

Both Ceph deployment strategies use the ceph-mixins project as a source of alerts. The ceph-ansible and rook projects +each maintain a rendered version of these alerts, but the rook repository contains some differences, primarily because +rook does not use the cephadm tool as a backend. +Therefore, find and apply one of the following commands to create a custom observer rules values file for either the +ceph-ansible or ceph-rook deployment (yq tool required):

+
# ceph-ansible
curl -s https://raw.githubusercontent.com/ceph/ceph/main/monitoring/ceph-mixin/prometheus_alerts.yml | \
yq '{"kube-prometheus-stack": {"additionalPrometheusRulesMap": {"ceph-ansible-rules": (. + {"additionalLabels": {"prometheus_rule": "1"}})}}}' > iaas/values-observer-ceph-rules.yaml

# rook
curl -s https://raw.githubusercontent.com/rook/rook/master/deploy/charts/rook-ceph-cluster/prometheus/localrules.yaml | \
yq '{"kube-prometheus-stack": {"additionalPrometheusRulesMap": {"ceph-rook-rules": (. + {"additionalLabels": {"prometheus_rule": "1"}})}}}' > iaas/values-observer-ceph-rules.yaml
+

Grafana dashboards

+

We've tested and could recommend 2 sources of Grafana dashboards that are suitable for both Ceph deployment strategies (ansible and rook):

+ +

We consider the dashboards created within the Rook project as a solid starting point for Ceph metrics visualization. +If you want to see more detailed dashboards, uncomment and use the ceph-mixin dashboards in the values-observer-ceph-rook.yaml +or values-observer-ceph-ansible.yaml file. You can use both.

+

Update the SCS monitoring deployment

+

This step deploys Grafana dashboards, Prometheus rules and instruct monitoring stack to add the Ceph exporter targets into the Prometheus configuration. +Ensure that you add the monitoring targets' IPs and ports to values-observer-ceph-ansible.yaml for Ceph-ansible deployment.

+
helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack --reset-then-reuse-values \
-f iaas/values-observer-ceph-rules.yaml \
-f iaas/values-observer-ceph-[rook|ansible].yaml # use values file for either the ceph-ansible or ceph-rook deployment
+
    +
  • Note: The --reset-then-reuse-values option requires Helm v3.14.0 or later. Alternatively, you can use the original values +by applying -f values-observer.yaml, see full command: helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml -f iaas/values-observer-ceph-rules.yaml -f iaas/values-observer-ceph-[rook|ansible].yaml
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/infrastructure_services/index.html b/docs/operating-scs/components/monitoring/docs/infrastructure_services/index.html new file mode 100644 index 0000000000..553d3adf51 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/infrastructure_services/index.html @@ -0,0 +1,30 @@ + + + + + +Infrastructure service endpoints | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Infrastructure service endpoints

+

This page contains instructions on how to enable probing of infrastructure service endpoints using blackbox exporter.

+

Infrastructure service endpoints can be probed using protocols such as HTTP, HTTPS, DNS, TCP, ICMP, and gRPC.

+

Blackbox exporter is a component of the monitoring stack. +Therefore, it can be deployed into the Observer cluster and configured simply by using the Helm chart values.

+

To enable probing of infrastructure service endpoints with blackbox exporter, locate and uncomment the related section in values-observer.yaml. +The sections related to blackbox exporter in the values-observer-scs.yaml values file are already uncommented.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/k3s/index.html b/docs/operating-scs/components/monitoring/docs/k3s/index.html new file mode 100644 index 0000000000..e5d78ba38c --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/k3s/index.html @@ -0,0 +1,92 @@ + + + + + +K3s support | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

K3s support

+

K3s is a certified Kubernetes distribution optimized for production environments, particularly in remote locations +or resource-constrained environments. Within the OSISM IaaS distribution, it serves as the management cluster, +accommodating various management software. Our aim is to integrate the SCS Observability platform as an observer solution +for the IaaS layer. To achieve this, we deploy the SCS Observability solution within the IaaS k3s management cluster. +This setup enables us to monitor not only the management k3s cluster itself but also the surrounding IaaS control +plane components.

+

This page contains information on how to develop and/or test the Observer solution as a monitoring solution for a k3s +cluster. It guides the user to create an HA k3s cluster via k3d (a wrapper to run k3s in Docker) and bootstrap +it with the Observer solution.

+

Note that the following tutorial guides you to deploy an HA K3s cluster consisting of 3 control plane nodes (servers) +and one worker node (agent). The reason is that the HA K3s cluster utilizes an embedded etcd cluster as cluster storage +(refer to https://docs.k3s.io/datastore/ha-embedded) and the HA mode is also used in OSISM Testbed and productive bare +metal deployments. +Using a single-node K3s cluster that uses the SQLite database (default) requires additional tweaks of monitoring values, +which are not covered in this guide.

+

Prerequisites

+ +

Prepare K3s Kubernetes cluster via K3d

+
k3d cluster create --config k3s-config.yaml --image rancher/k3s:v1.28.8-k3s1 observer
+

If you opt not to use K3D with the custom config we provided here, and prefer utilizing another Kubernetes cluster, +ensure that the metric endpoints for various control plane components are properly exposed. +Refer to the docs.

+

Deploy Observer monitoring solution

+

K3s consolidates all Kubernetes control plane components into a single process, which means that the metrics for these +control plane components are exposed on the K3d hosts rather than through individual Kubernetes Services/PODs. +To customize monitoring values for K3s, refer to the specific custom HELM values file values-observer-k3s.yaml. +This file contains the necessary configurations and adjustments needed to monitor K3s. +Note that list of control plane node IPs (endpoints) should be overridden.

+

Get and store the K3d control plane node IPs:

+
NODE_IPS=$(kubectl get nodes -l node-role.kubernetes.io/control-plane=true -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}' | tr ' ' ',' | sed 's/^/{&/;s/$/}/')
+

Install the monitoring stack and set the control plane component endpoints

+
helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/
helm repo update dnationcloud
helm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer-k3s.yaml \
--set "kube-prometheus-stack.kubeEtcd.endpoints=$NODE_IPS" \
--set "kube-prometheus-stack.kubeProxy.endpoints=$NODE_IPS" \
--set "kube-prometheus-stack.kubeControllerManager.endpoints=$NODE_IPS" \
--set "kube-prometheus-stack.kubeScheduler.endpoints=$NODE_IPS"
+

Access the Observer monitoring UIs

+

At this point, you should have the ability to access the Grafana, Alertmanager and Prometheus UIs +within the Observer monitoring cluster.

+
    +
  • +

    Grafana UI

    +
    http://localhost:30000
    + +
  • +
  • +

    Alertmanager UI

    +
    http://localhost:30001
    +
  • +
  • +

    Prometheus UI

    +
    http://localhost:30002
    +
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/kaas/index.html b/docs/operating-scs/components/monitoring/docs/kaas/index.html new file mode 100644 index 0000000000..815e4a7c5e --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/kaas/index.html @@ -0,0 +1,92 @@ + + + + + +KaaS monitoring (experimental) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

KaaS monitoring (experimental)

+

This component is marked as experimental, and it is not part of the reference SCS installation available +at https://monitoring.scs.community.

+

Enable KaaS layer monitoring

+

TODO: Provide clear instructions on how to enable KaaS layer monitoring.

+

Please check out the mvp-0 tag and find the related comments on what needs to be done in the monitoring +values to enable KaaS monitoring in your Observer cluster.

+

KaaS metric importer

+

To test the Monitoring of the KaaS layer use case, deploy the Kaas-metric-importer +into the Observer cluster.

+

The Kaas-metric-importer is a simple service through which the KaaS software registers +and unregisters newly created or deleted KaaS clusters in the Observer monitoring. +This functionality enables the Observer monitoring to differentiate between KaaS clusters deleted intentionally +and those that have stopped writing metrics to the Observer monitoring for any reason.

+
kubectl apply -f kaas/kaas-metric-importer.yaml
+

The Kaas-metric-importer uses an image built from https://github.com/m3dbx/prometheus_remote_client_golang. +It has mounted configmap and based on configmap keys it pushes custom metric kaas +with label cluster and value 1 into the thanos receiver.

+

Example of configmap:

+
data:
workload-cluster: ""
+

It pushes metric e.g. kaas{cluster="workload-cluster"} 1 to the Observer. +It is important to keep the configmap up-to-date with your KaaS offering. This is automated e.g. +in the KaaS mock service below.

+

KaaS mock service

+

To evaluate the Monitoring of the KaaS layer use case and view actual metrics in your +Observer monitoring cluster, you can launch the KaaS mock service.

+

Put your Observer monitoring cluster kubeconfig into the ./kaas/manifests/ directory and name +it observer-kubeconfig.yaml (or adjust kaas service ./kaas/app/config.py accordingly).

+

If you're utilizing the KinD Observer deployment outlined in this tutorial, collect the kubeconfig using the following command:

+
kind get kubeconfig --name observer > ./kaas/manifests/observer-kubeconfig.yaml
+

All KaaS mock service dependencies can be installed via the corresponding ./kaas/requirements.txt file. +Installing them into a Python virtualenv is recommended.

+
cd kaas
python3 -m venv .venv # Optional
source .venv/bin/activate # Optional
# Install kaas dependencies
pip install -r requirements.txt

# Launch the KaaS mock service
make kaas
+

At this point, you should have the ability to access the KaaS mock service Swagger UI:

+
http://127.0.0.1:8080/kaas
+
    +
  • +

    Create KaaS cluster through Swagger UI: Create Cluster or +call directly the KaaS service API via some client, e.g.:

    +
    curl -X POST -H "Content-Type: application/json" http://127.0.0.1:8080/api/clusters/ -d '{"name": "kaas"}'
    +

    Navigate to the KaaS Monitoring dashboard +in the Observer monitoring. After a few minutes (approximately 4), your KaaS cluster should become visible. +Click on the cluster box to dive into KaaS cluster dashboards at a more detailed level. +Repeat the process to explore further and gain deeper insights.

    +

    Note: The disk utilization expression for the Docker environment has not been adjusted, +so you will encounter non-realistic numbers in the nodes/disk sections. However, +the other sections should accurately reflect the reality.

    +
  • +
  • +

    Retrieve a list of all KaaS clusters and check their status. Swagger UI: Get List of Clusters or +call directly the KaaS service API via some client, e.g.:

    +
    curl -s -X GET -H 'accept: application/json' http://127.0.0.1:8080/api/clusters/
    +
  • +
  • +

    Get Kaas Cluster kubeconfig by its name through Swagger UI: Get Cluster kubeconfig or +call directly the KaaS service API via some client and save it, e.g.:

    +
    curl -s -X GET -H 'accept: application/json' http://127.0.0.1:8080/api/clusters/kaas > kaas-kube
    +
  • +
  • +

    Now, you have the opportunity to play with your KaaS cluster and experiment with triggering +monitoring alerts by initiating actions like destroying certain components 😎.

    +
    kubectl --kubeconfig kaas-kube get po -A
    +
  • +
  • +

    Finally, delete your KaaS cluster by its name through Swagger UI: Delete Cluster or +call directly the KaaS service API via some client and save it, e.g.:

    +
    curl -X DELETE http://127.0.0.1:8080/api/clusters/?name=kaas
    +
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/oauth/index.html b/docs/operating-scs/components/monitoring/docs/oauth/index.html new file mode 100644 index 0000000000..6638b319ae --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/oauth/index.html @@ -0,0 +1,61 @@ + + + + + +OAUTH | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

OAUTH

+

We set up oauth2 with GitHub provider for the https://monitoring.scs.community according to the https://kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/.

+

To use it, inspect oauth/oauth2-proxy.yaml and modify it according to your needs. +You want to change at least these:

+
    +
  • OAUTH2_PROXY_CLIENT_ID
  • +
  • OAUTH2_PROXY_CLIENT_SECRET
  • +
  • OAUTH2_PROXY_COOKIE_SECRET
  • +
  • ingress host
  • +
+

Then deploy oauth2-proxy as follows:

+
kubectl apply -f oauth/oauth2-proxy.yaml
+

We set up OAuth authentication for these components:

+
    +
  • Thanos Query +
      +
    • it is exposed via ingress on monitoring.scs.community/thanos
    • +
    • modified with --web.external-prefix=thanos extra flag +
        +
      • ruler query endpoint and grafana datasource url need to be modified
      • +
      +
    • +
    +
  • +
  • Alertmanager +
      +
    • it is exposed via ingress on monitoring.scs.community/alertmanager
    • +
    • modified with routePrefix: /alertmanager alertmanagerSpec +
        +
      • ruler alertmanager url needs to be modified
      • +
      +
    • +
    +
  • +
+

You have to also uncomment a related sections in values-observer.yaml for exposing +the components via ingress. +The sections related to OAUTH in the values-observer-scs.yaml values file are already uncommented.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/overview/index.html b/docs/operating-scs/components/monitoring/docs/overview/index.html new file mode 100644 index 0000000000..a3d9ac6dd2 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/overview/index.html @@ -0,0 +1,49 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

This repository aims to build an Observer monitoring solution intended to offer a global metrics +view of the CSP infrastructure. It is the platform where CSP infrastructure metrics +are fetched, processed, stored, and visualized. Note that this monitoring solution could +be extended, and the other two observability signals (logs and traces) from the CSP +infrastructure could also be processed here.

+

The Observer monitoring solution is developed on the foundation of the dNation monitoring solution. +and it is intended to become an SCS product.

+

This repository includes the manifest for the stable deployment of the Observer monitoring solution, +as well as experimental and illustrative examples of how this monitoring solution can be extended and utilized.

+

The stable version of the Observer monitoring solution empowers its reference SCS installation available +at https://monitoring.scs.community. This deployment covers the monitoring of core SCS infrastructure services, +subsequently referred to as 'Monitoring of infrastructure services'. Refer to the details here. +The high-level architecture could be visualized as follows:

+

monitoring_scs_high_level.png

+

Some illustrative and experimental examples of how this monitoring solution can be utilized have been introduced +within the MVP-0 version of this project (refer to the mvp-0 tag, related comments, and docs sections: kaas, iaas). +These examples include:

+
    +
  • Monitoring of the KaaS layer
  • +
  • Monitoring of the IaaS layer
  • +
+

The above experimental components are not part of the reference SCS installation available +at https://monitoring.scs.community. +The high-level architecture of these experimental components could be visualized as follows:

+

monitoring_scs_experimental.png

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/quickstart/index.html b/docs/operating-scs/components/monitoring/docs/quickstart/index.html new file mode 100644 index 0000000000..82f75a1d56 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/quickstart/index.html @@ -0,0 +1,83 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Quickstart

+

These page covers the process of deploying the Observer monitoring solution +into the Kubernetes cluster.

+

The configuration options used in this tutorial result in a non-productive and simple +deployment of the Observer monitoring solution. The steps do not guide users to register +certain observer targets, such as existing Kubernetes clusters or virtual machines. +Additionally, the tutorial lacks guidance for deploying optional and experimental components +like IaaS and KaaS monitoring.

+

At the end of this tutorial, the reader should end up with a Kubernetes cluster where the Observer solution will +be installed and will monitor the Kubernetes cluster hosting it.

+

Prerequisites

+ +

Prepare Kubernetes cluster

+

The Observer monitoring solution is designed to operate on Kubernetes clusters. We have continuously tested it with +various Kubernetes distributions, including vanilla Kubernetes, OKD, SCS KaaS V1, +and SCS KaaS V2.

+

To set up the SCS KaaS V2 Kubernetes cluster, please refer to the quickstart guide.

+

For local testing purposes, we recommend using KinD (Kubernetes in Docker) as follows:

+
kind create cluster --config kind-observer-config.yaml --image kindest/node:v1.27.3 --name observer
+

If you opt not to use KinD with the custom config we provided here, and prefer utilizing another Kubernetes cluster, +ensure that the metric endpoints for various control plane components are properly exposed. +Refer to the docs.

+

Deploy Observer monitoring solution

+
helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/
helm repo update dnationcloud
helm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml
+

Access the Observer monitoring UIs

+

At this point, you should have the ability to access the Grafana, Alertmanager and Thanos UIs +within the Observer monitoring cluster.

+
    +
  • +

    Grafana UI

    +
    http://localhost:30000
    + +
  • +
  • +

    Alertmanager UI

    +
    http://localhost:30001
    +
  • +
  • +

    Thanos UI

    +
    http://localhost:30002
    +
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/scs-deployment/index.html b/docs/operating-scs/components/monitoring/docs/scs-deployment/index.html new file mode 100644 index 0000000000..b4d77564f5 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/scs-deployment/index.html @@ -0,0 +1,69 @@ + + + + + +SCS deployment | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS deployment

+

The following steps were utilized to deploy the SCS reference installation of the Observer monitoring solution, +which is available at https://monitoring.scs.community.

+

Architecture

+

Currently, the detailed architecture diagram can be visualized as follows:

+

monitoring_scs_detailed.png

+

The SCS Observer includes the Loki deployment along with the Promtail +agent on each Observer node. This setup ensures that the SCS Observer platform collects logs from itself and can also +serve as a global, horizontally scalable, highly available, multi-tenant log aggregation system.

+

Prerequisites

+
    +
  • Kubernetes cluster +
      +
    • We used the R5 version of SCS KaaS V1, which includes an ingress controller and cert manager +
      export KUBECONFIG=/path/to/kubeconfig
      +
    • +
    +
  • +
  • kubectl
  • +
  • helm
  • +
+

Install Observer solution

+
    +
  • +

    Apply SCS brand secrets and letsencrypt issuer manifest.

    +
    kubectl apply -f scs/logo.yaml
    kubectl apply -f scs/brand.yaml
    kubectl apply -f scs/issuer.yaml
    +
  • +
  • +

    Deploy the Zuul monitoring related Helm chart and all associated manifests according to the instructions provided on this documentation page.

    +
  • +
  • +

    Deploy the Alertmanager to Matrix chat notifications related manifest according to the instructions provided on this documentation page.

    +
  • +
  • +

    Deploy the OAUTH related manifest according to the instructions provided on this documentation page.

    +
  • +
  • +

    Review the values-observer-scs.yaml file and locate all instances of the placeholder text "replace-me". +These values relate to configuring access to the object stores (for Thanos and Loki), the Grafana admin password and +Loki API basic auth username and password.

    +
  • +
  • +

    Finally, install the monitoring stack using values that incorporate all the configurations mentioned above

    +
  • +
+
helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/
helm repo update dnationcloud
helm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer-scs.yaml
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/status-page/index.html b/docs/operating-scs/components/monitoring/docs/status-page/index.html new file mode 100644 index 0000000000..0542e20761 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/status-page/index.html @@ -0,0 +1,65 @@ + + + + + +Status page monitoring | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Status page monitoring

+

Prerequisites

+

To test the Monitoring of the SCS Status page we expect running Kubernetes cluster that already contains +SCS monitoring platform and Status page deployed in the dedicated status-page namespace.

+

Local environment use case - KinD/K3s cluster deployed locally

+

KinD

+

Install the SCS monitoring solution into the KinD Kubernetes cluster following the instructions provided in +the quickstart guide.

+

K3s

+

Install the SCS monitoring solution into the K3s Kubernetes cluster following the instructions provided in +the k3s guide.

+

OSISM use case - K3s cluster in OSISM deployment

+

OSISM utilizes the k3s distribution of Kubernetes +as a management cluster for the OSISM IaaS platform. This management cluster is then used as a host for +the SCS monitoring solution. Subsequently, the management cluster becomes an Observer cluster as it hosts +the SCS monitoring solution. +From that point, the Observer cluster observes itself (i.e., k3s cluster control plane components and nodes) and is used +for observing the IaaS layer around the k3s cluster.

+

In the case of the existing OSISM IaaS deployment >= 7.0.3 on +baremetal, testbed or cloud in the box +we expect a management k3s Kubernetes cluster with the deployed SCS monitoring platform. +If your OSISM installation does not meet the above requirements, apply the following plays:

+
osism apply kubernetes
osism apply kubernetes-monitoring
+

Deploy Status page monitoring

+

This step deploys the Grafana dashboards and instructs the monitoring stack to add the Status Page metrics targets into the Prometheus configuration:

+
helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack --reset-then-reuse-values -f status-page/status-page-values.yaml
+
    +
  • Note: The --reset-then-reuse-values option requires Helm v3.14.0 or later. Alternatively, you can use the original values +by applying -f values-observer.yaml, see full command: helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml -f status-page/status-page-values.yaml
  • +
+

Access the Status page dashboards

+

At this point, you should have the ability to access the Grafana UI, and Status page dashboards.

+

Log in to the Grafana UI and find the Status page dashboard in StatusPage directory:

+
http://localhost:30000
+
    +
  • Use the following credentials: +
      +
    • username: admin
    • +
    • password: pass
    • +
    +
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/tracing/index.html b/docs/operating-scs/components/monitoring/docs/tracing/index.html new file mode 100644 index 0000000000..66443a26db --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/tracing/index.html @@ -0,0 +1,37 @@ + + + + + +Traces | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Traces

+

This page contains a guide on how to enable traces in Thanos. Traces are not enabled by default.

+

Thanos supports different tracing backends that implements opentracing.Tracer interface. +All clients could be configured by --tracing.config-file parameter to reference to the configuration file or by --tracing.config +parameter to put yaml config directly. Recommended way is to pass configuration directly as it gives an explicit static view of +configuration for each component, and it also saves you the fuss of creating and managing additional files.

+

Example

+

Here is the example of the configuration how to enable jaeger in Thanos. This configuration can be applied for multiple components e.g. query-frontend, query or thanos-sidecar.

+
thanos:
queryFrontend:
extraFlags:
- |-
--tracing.config="config":
"sampler_param": 2
"sampler_type": "ratelimiting"
"service_name": "thanos-query-frontend"
"agent_host": "jaeger-agent.<namespace>.svc"
"agent_port": 5775
"type": "JAEGER"
+

Usage

+

Once tracing is enabled, Thanos will generate traces for all gRPC and HTTP APIs thanks to generic “middlewares”. +Some more interesting to observe APIs like query or query_range have more low-level spans with focused metadata showing +latency for important functionalities. For example, Jaeger view of query_range HTTP API call might look as follows: +Jaeger-example

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/tuning/index.html b/docs/operating-scs/components/monitoring/docs/tuning/index.html new file mode 100644 index 0000000000..095eccdafe --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/tuning/index.html @@ -0,0 +1,63 @@ + + + + + +Tuning | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Tuning

+

This page contains recommended parameters to set for the Thanos components to improve performance in terms of query time. +The following parameters have already been incorporated into the upstream dNation monitoring repositories, +and therefore are already included in the SCS observability deployment.

+

Query Frontend

+
queryFrontend:
extraFlags:
- --query-range.split-interval=12h
- --query-frontend.log-queries-longer-than=10s
- --query-frontend.compress-responses
- |-
--query-range.response-cache-config="config":
"max_size": "500MB"
"max_size_items": 0
"validity": 0s
"type": "in-memory"
+
    +
  • Notes on the parameters for query frontend: +
      +
    • query-range.split-interval - splits a long query into multiple short queries to improve query time. Default=24h.
    • +
    • query-frontend.log-queries-longer-than=10s - log queries running longer than 10s, which helps to identify new querries, which should be improved)
    • +
    • query-frontend.compress-responses - compress HTTP responses, helps with query time
    • +
    • query-range.response-cache-config - cahcing is common solution to speed up response time(https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/)
    • +
    +
  • +
+

Compactor

+
compactor:
retentionResolutionRaw: 2d
retentionResolution5m: 10d
retentionResolution1h: 15d
extraFlags:
- --compact.concurrency=3
- --downsample.concurrency=3
+
    +
  • Notes on the parameters for compactor: +
      +
    • retentionResolutionRaw - how long to retain raw samples in bucket. Minimum is two days, because just after 40 hours 5m downsampled data are created.
    • +
    • retentionResolution5m - how long to retain samples of resolution 1 (5 minutes) in bucket. Setting this to 0d will retain samples of this resolution forever. One hour downsampled data are created only after 10 days, so this is minimum if you want also 1h downsampled data.
    • +
    • retentionResolution1h - how long to retain samples of resolution 2 hour) in bucket.
    • +
    • delete-delay - make sure you have set this parameter. It is time before a block marked for deletion is deleted from bucket. Note that deleting blocks immediately can cause query failures, if store gateway still has the block loaded, or compactor is ignoring the deletion because it's compacting the block at the same time. Default=48h.
    • +
    • compact.concurrency - number of goroutines to use when compacting groups(https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/). Default=1.
    • +
    • downsample.concurrency - number of goroutines to use when downsampling block(https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/). Default=1.
    • +
    +
  • +
+

Query

+
query:
extraFlags:
- --query.auto-downsampling
- --query.replica-label=prometheus_replica
+
    +
  • Notes on the parameters for query: +
      +
    • query.auto-downsampling - enable automatic adjustment (step / 5) to what source of data should be used in store gateways if no max_source_resolution param is specified. Default step for range queries is equal to 1s and it is only used when step is not set in UI. Can be changed by setting --query.default-step parameter. Hovewer, when you are using Grafana as your UI, the step is taken from min_step. The preferred options is to set HTTP URL/FORM parameter max_source_resolution to auto, which selects downsample resolution automatically based on the query.
    • +
    • query.replica-label - labels to treat as a replica indicator along which data is deduplicated.
    • +
    +
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/zuul/index.html b/docs/operating-scs/components/monitoring/docs/zuul/index.html new file mode 100644 index 0000000000..e2cc3c78b3 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/zuul/index.html @@ -0,0 +1,36 @@ + + + + + +Zuul monitoring | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Zuul monitoring

+

This page contains instructions on how to enable the Zuul monitoring in the Observer solution.

+

Zuul comes with support for the statsd protocol, hence the graphite instance is needed when +we want directly consume Zuul metrics.

+

Graphite deployment:

+
helm add repo kiwigrid https://kiwigrid.github.io
helm upgrade --install graphite kiwigrid/graphite -f zuul/values-zuul.yaml
+

A UDP load balancer that exposes the Graphite receiver service:

+
kubectl apply -f zuul/udp-lb-service.yaml
+

Zuul dashboards:

+
kubectl apply -f zuul/zuul-status-dashboard.yaml
kubectl apply -f zuul/zuul-nodepool-dashboard.yaml
kubectl create -f zuul/zuul-zookeeper-dashboard.yaml
+

Find and uncomment a related section in values-observer.yaml if you want to link the above +dashboards to the L1 Zuul host dashboard. +The sections related to Zuul in the values-observer-scs.yaml values file are already uncommented.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack/index.html b/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack/index.html new file mode 100644 index 0000000000..f562c5f7ec --- /dev/null +++ b/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack/index.html @@ -0,0 +1,69 @@ + + + + + +Observability stack quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Observability stack quickstart

+

Prerequisites

+

Kubernetes is required to setup this observability stack consisting of Prometheus, Grafana and Prometheus push gateway. +One recommendation for setting up a local Kubernetes environment is to use KIND (Kubernetes in Docker). KIND provides a lightweight way to create Kubernetes clusters using Docker containers. Docker Desktop also has support for kubernetes.

+

Setup process

+

To set up Prometheus stack and Prometheus Pushgateway on local Kubernetes using Helm, you can follow these steps:

+
    +
  1. Add Helm Chart Repositories:
  2. +
+
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
+
    +
  1. Install Prometheus Stack:
  2. +
+
helm install my-kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 57.0.3 -f "./Values/PrometheusStackValues.yaml"
+

This command will install the Prometheus stack on your Kubernetes cluster using these values.

+
    +
  1. Install Prometheus Pushgateway:
  2. +
+
helm install my-prometheus-pushgateway prometheus-community/prometheus-pushgateway --version 2.8.0 -f "./Values/PrometheusPushGateway.yaml"
+

This command will install Prometheus Pushgateway on your Kubernetes cluster using these values.

+
    +
  1. Set Docker Context:
  2. +
+
kubectl config get-contexts
kubectl config use-context docker-desktop
+

Ensure that the Docker context is correctly set to your local Kubernetes cluster.

+
    +
  1. Expose Services Locally:
  2. +
+
kubectl apply -f ./k8s/nodePorts.yaml
+

This command will apply the configuration to expose services using nodePort service on Kubernetes.

+

An alternative to using NodePort for exposing services to localhost in a local Kubernetes setup is to use kubectl port-forward. This command allows you to forward local ports to a port on a specific pod within the Kubernetes cluster. Here's how you can use it:

+
    +
  1. Port Forwarding for Prometheus Stack:
  2. +
+

kubectl port-forward svc/<prometheus-service-name> <local-port>:<prometheus-port>
+

Replace <prometheus-service-name> with the actual name of the Prometheus service in your Kubernetes cluster. <local-port> is the port number on your localhost where you want to access Prometheus, and <prometheus-port> is the port on which Prometheus is running within the cluster. The same applies to prometheus push gateway or any other service you may want to expose.

+

For example:

+
kubectl port-forward svc/my-kube-prometheus-stack-prometheus 9090:9090
kubectl port-forward svc/my-prometheus-pushgateway 9091:9091
+

Make sure to replace "./Values/PrometheusStackValues" with the actual path to your Prometheus Stack values file. Also, adjust the path to the nodePorts.yaml file if it's located in a different directory.

+

Remember to replace placeholders such as my-kube-prometheus-stack and my-prometheus-pushgateway with appropriate names for your deployments.

+

Once you've executed these commands, Prometheus stack and Prometheus Pushgateway should be set up and accessible on your local Kubernetes cluster.

+
    +
  1. Uninstall helm chart +If you want to reinstall or remove the deployed observability stack, you can use the following commands:
  2. +
+
# List deployed helm charts
helm list

# Delete helm chart (all deployed k8s resources) with name <chart_name>
helm uninstall <chart_name>
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/scs-health-monitor/Testflow/index.html b/docs/operating-scs/components/scs-health-monitor/Testflow/index.html new file mode 100644 index 0000000000..88070ab543 --- /dev/null +++ b/docs/operating-scs/components/scs-health-monitor/Testflow/index.html @@ -0,0 +1,102 @@ + + + + + +Testflow-Infrastructure | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Testflow-Infrastructure

+

Quick Intro:

+
    +
  • After following the steps to set up the environment including setting up the monitornig, you should be able to start testing with ./scs-health-monitor behave a testing framwork. On the Cloud-Level you have several features that describe Test Scenerios for single components of the Openstack functionality, like the openstack_create_network.feature. +So if you want to test whether you are able to create a network you can use that feature like this:
  • +
+
./scs-health-monitor behave openstack_create_network.feature
+

or aswell:

+
./scs-health-monitor behavex openstack_create_network.feature
+

and a test on whether you are able to create a network is running.

+
    +
  • If you want to test whether you can create and delete all openstack resources you simply need this command (for openstack_testflow.feature includes all the steps from the creation and delition features):
  • +
+
./scs-health-monitor behave openstack_testflow.feature
+
    +
  • The Use Case for the openstack_testflow.feature and all the creation and deletion features is mostly debugging, because to run a whole infrastructure test this is not sadisfying the dependencies of the variouse resources. But you can set some parameters like the quantity of the resources, if you aim to see if you have a certain quota f.e. +To get a more detailed view on the test run you have the option --no-capture and you will receive prints or informational logs during the test run.
  • +
+
./scs-health-monitor behave --no-capture openstack_create_network.feature
+
    +
  • After the run each built resource will be deleted to avoid a DuplicateResource-Error. If you should still encounter this Error, you will have to delete the resource in question by hand ether in the openstack cli tool or in the plus cloud open dashboard. But make sure this resource is not in use!
  • +
+

Real Testing:

+
    +
  • +

    As we provide an automated Infrastructure Testing the real deal lies in the openstack_benchmark_build_infra.feature. This Feature is creating all resources and configures them in order to build a complete infrastructure with virtual machine (vm) networks that are accessible through jumphosts (jh) that get certain floating ip and allow a port forwarding to the vms. That means it automatically sets up the ssh-access and the security group rules and makes sure applications like iperf3 are installed on the hosts. This infrastructure emulates a common openstack infrastructure and allows to run a number of benchmark tests to see whether it has the needed capacity.

    +
  • +
  • +

    You start an infrastructure test by:

    +
  • +
+
./scs-health-monitor behave openstack_benchmark_build_infra.feature
+

or aswell:

+
./scs-health-monitor behavex openstack_benchmark_build_infra.feature
+
    +
  • +

    It will take some time but you can follow allong, if the infrastructure is builds up successfully. +After the run it deletes all resources.

    +
  • +
  • +

    If you want run benchmarktests (which is the main goal of this approach), you will have to run the benchmark features together with the openstack_benchmark_build_infra.feature like so:

    +
  • +
+
./scs-health-monitor behave openstack_benchmark_build_infra.feature cloud_level_testing/features/openstack_benchmark_iperf3.feature cloud_level_testing/features/openstack_benchmark_pingVM.feature cloud_level_testing/features/openstack_benchmark_4000pi.feature
+

The first feature always has to be the openstack_benchmark_build_infra.feature. After that you can use the other features, as they only depend on the infrastructure, they don't need to follow a special order.

+
    +
  • Note all features that fail and have a @create or @delete tag assigned to them will lead to a deletion of the build up resources right after the feature run. Hence if they are followed by a feature depending on those resources this feature will inevitably fail.
  • +
+

Extended Description:

+
    +
  • Our approach to use the behave-framework to build up and test an openstack infrastructure automated relies on certain peculiarities of this framework. First of all you have to understand the basic entities of a testrun:
  • +
+
    +
  1. +

    1 testrun can contain multiple features
    +1 feature can contain multiple steps
    +1 step can contain multiple substeps

    +
  2. +
  3. +

    In the environment.py you can define what actions have to be done
    +before_all (in the beginning of the testrun),
    +after_feature (after every feature) and
    +after_all (in the end of the testrun)
    +To calculate for exemple the total duration of the run we set the timer in the before_all section and get the result in the after_all section, where we also collect the metrics and push them to the prometheus gateway or delete all resources. In the after_feature section, we delete ressources if a creation or deletion feature has failed.

    +
  4. +
  5. +

    We tried to keep the steps and features as independent and self contained as possible. But in an infrastructure this is almost impossible, if you don't want to create monolytic steps and functions. Therefore we create an oblect called context and an object called Collector in the before_all section. We store every information, that has to be passed between the steps into the context like the connection to the openstack client. The Collector fetches each resource-id, when a resource is created to ensure that all and only resources that were created in the test run are deleted in the end.

    +
  6. +
  7. +

    However, if we run features, that rely on another feature like on the openstack_benchmark_build_infra.feature the problem occures that the context attributes that are created during a feature run are deleted after each feature. Therefore we created a SharedContext Object that is already initialised before_all and stores the data that is necessary for the following features like the test-prefix (context.test_name) and the floating ip and portforwarding (context.redirs).
    +So in the end of openstack_benchmark_build_infra.feature the following step must be performed: Then I can pass the context to another feature (to store the needed information into the SharedContext) +and the following features have to begin with the step: Given I can get the shared context from previouse feature (to transfer the shared informations into the new context object).

    +
  8. +
+

Scaling the Benchmark Infrastructure

+

First of all is the scale of the benchmark infrastructure highly dependent on the amount of availability zones in the project. The number of availability zones determines how many jumphosts (jhs) and networks are built. If there are for example two availbility zones, two jumphosts are created and and attached to a floating ip each.\ +The jumphosts are connected through a shared network but each of them is also attached to another network of virtual machines (vms). The quantity of vms can be adjusted in the table of openstack_benchmark_build_infra.feature. The vms can be reached from outside the network via port forwarding. Which is enabled by the jh. You can reach the vms by addressing the floating ip of the associated jh and the port number. +The range of the port numbers can also be specified in the openstack_benchmark_build_infra.feature the default range is set from 222 to 229.
+Apart from that, you cannot change quantities because the infrastructure automatically adjusts in scale depending on the dependencies.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/scs-health-monitor/Workflow/index.html b/docs/operating-scs/components/scs-health-monitor/Workflow/index.html new file mode 100644 index 0000000000..d75215d1e2 --- /dev/null +++ b/docs/operating-scs/components/scs-health-monitor/Workflow/index.html @@ -0,0 +1,173 @@ + + + + + +Kubernetes BDD Testing Framework Documentation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Kubernetes BDD Testing Framework Documentation

+

Overview

+

This framework is designed to facilitate Behavior-Driven Development (BDD) for both cloud level testing +and container level testing. The framework allows you to write human-readable tests that validate Kubernetes clusters, +pods, services, and other resources.

+

Before you begin, ensure you have the following installed on your machine:

+

Python 3.8+ +pip (Python package installer) +kubectl (Kubernetes command-line tool) +Helm (Kubernetes package manager)

+

Usage

+
    +
  1. Clone the Repository:
  2. +
+
git clone https://github.com/SovereignCloudStack/scs-health-monitor
cd scs-health-monitor
+
    +
  1. Set Up a Virtual Environment:
  2. +
+

It's recommended to use a virtual environment to avoid conflicts with other Python packages.

+
# create python virtual environment
python3 -m venv <environment_name>

# activate the python virtual environment in windows command prompt
<environment_name>/Scripts/activate

# activate the python virtual environment in Unix or MacOS
source <environment_name>/bin/activate

# install all the python dependencies
python -m pip install -r requirements.txt
+
    +
  1. Install Required Python Packages:
  2. +
+

Install all necessary Python packages using pip.

+
pip install -r requirements.txt
+
    +
  1. Install Additional Tools (Optional) or run script install_env.py:
  2. +
+

If you need to install and manage an NGINX Ingress controller, you'll need helm.

+

For MacOS:

+
brew install helm
+

For Linux:

+
sudo apt-get install helm
+

For Windows:

+

The easeiest way is to use linux kernel for windows and proceed there.

+
+

In this repository (under main directory) you have to create two files that will be referenced by env.yaml and clouds.yaml

+
    +
  • env.yaml:
  • +
+
   OS_AUTH_TYPE: ""
OS_AUTH_URL: ""
OS_IDENTITY_API_VERSION: ""
OS_REGION_NAME: ""
OS_INTERFACE: ""
OS_APPLICATION_CREDENTIAL_ID: ""
OS_APPLICATION_CREDENTIAL_SECRET: ""
OS_PROJECT_NAME: ""
OS_USER_DOMAIN_NAME: ""
OS_PROJECT_DOMAIN_NAME: ""

+
    +
  • clouds.yaml:
  • +
+
clouds:
gx:
region_name:
auth_type:
auth_url:
identity_api_version:
interface:
application_credential_id:
application_credential_secret:
+

Configuration

+

Kubernetes Configuration

+

Ensure that your Kubernetes configuration file (kubeconfig) is correctly set up. This file is typically located at +~/.kube/config. The framework uses this configuration to interact with your Kubernetes cluster.

+

If you want to use a specific context from your kubeconfig, you can set it using:

+
kubectl config use-context scs-vp12
+

Helm Configuration

+

For Ingress management, you need to add the NGINX Ingress repository and install the Ingress controller.

+
helm install nginx-ingress ingress-nginx/ingress-nginx --namespace ingress-nginx --create-namespace
+

Running Tests

+

Writing Test Scenarios

+

Tests are written in .feature files using Gherkin syntax. Each scenario represents a feature of the application you want to test.

+

Example feature file (container_creation.feature):

+

Feature: Container Management

Scenario: Creating a simple container
Given a Kubernetes cluster
When I create a container named test-container
Then the container test-container should be running

Scenario: Creating a service for the container
Given a container running a web server named web-container
When I create a service for the container named web-container on 80
Then the service for web-container should be running
When I send an HTTP request to web-container
Then the response status code should be 200
+

Running the Tests

+

You can run the tests using the behave command from the root of your project:

+
./scs-health-monitor behave
+

This will execute all the scenarios defined in the .feature files within the features directory.

+

Example Command to Run a Specific Feature File

+

To run a specific feature file, use:

+
./scs-health-monitor behave container_level_testing/features/container_creation_deletion.feature
+

Adding New Features

+

Creating New Step Definitions

+

To add new behavior or extend existing features, define new steps in the Python files located in container_level_testing/features/steps/. These files map Gherkin steps to Python code.

+
@given('describe what test is doing')
def name_of_the_test(context):
## Body of the test
+

Creating New Feature Files

+
    +
  1. Create a New Feature File:
  2. +
+

Add a new .feature file in the features directory.

+
    +
  1. Write Scenarios in Gherkin Syntax:
  2. +
+

Define the behavior you want to test using Given-When-Then steps.

+
Feature: New Kubernetes Feature

Scenario: A new feature scenario
Given name of the function
When name of another function with logic
Then step with assertion to verify if step before was succeded
+
    +
  1. Implement the Step Definitions:
  2. +
+

Add the corresponding step definitions in the appropriate .py file under features/steps/.

+

Modifying Existing Features

+
    +
  1. Update the Feature File:
  2. +
+

Modify the .feature file to reflect the new behavior or changes.

+
    +
  1. Update the Step Definitions:
  2. +
+

Modify the corresponding step definitions in the .py file.

+

Setting Up Ingress

+

To add ingress resources:

+

Create Ingress YAML:

+

Create an ingress resource file my-ingress.yaml with the desired settings.

+
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: my-project.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80

+
    +
  1. Apply the Ingress Resource:
  2. +
+

Use the following command to apply the ingress resource:

+
kubectl apply -f my-ingress.yaml
+

Troubleshooting

+

Common Errors

+
    +
  • +

    Connection Errors: Ensure that Kubernetes and Ingress services are correctly configured and running.

    +
  • +
  • +

    Port Conflicts: Ensure that the specified ports are not already in use. Modify the nodePort or use dynamic assignment.

    +
  • +
  • +

    Timeouts: Adjust the timeout settings in the test code if the service or container takes longer to initialize.

    +
  • +
+

Debugging Tips

+
    +
  • Check Pod Logs:
  • +
+
kubectl logs <pod-name>
+
    +
  • Check Service and Pod Status:
  • +
+
kubectl get services
kubectl get pods
+

Observability stack

+

For more informations about setting up Observability Stack, please use this +file

+
+

Adding fixes/new functionalities to the project flow:

+
    +
  1. Create branch for issue git checkout -b SPACECAT-<issue_number>-<issue_name>.
  2. +
  3. Add the changes made git add -u or git add <file_name>.
  4. +
  5. Commit the changes using git commit -s -m "message". +
      +
    • The "-s" flag is important, the commit won't go through otherwise
    • +
    +
  6. +
  7. To push the current branch and the changes and set the remote as upstream, use git push --set-upstream origin SPACECAT-<issue_number>-<issue_name>. +
      +
    • Alternatively push the changes if the branch already exists in the remote repository.
    • +
    +
  8. +
  9. After work is done, create a pull request for the branch.
  10. +
  11. Ask another team member to review the changes, when he approves the changes, merge the chages into main branch.
  12. +
+
+

Conclusion

+

This framework provides a robust, BDD-based approach to testing Kubernetes clusters and resources. By following the above instructions, you can extend, modify, and run tests tailored to your specific needs.

+

Feel free to customize the framework to accommodate new Kubernetes features and application requirements.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/scs-health-monitor/overview/index.html b/docs/operating-scs/components/scs-health-monitor/overview/index.html new file mode 100644 index 0000000000..f5df0f6169 --- /dev/null +++ b/docs/operating-scs/components/scs-health-monitor/overview/index.html @@ -0,0 +1,131 @@ + + + + + +SCS Health Monitor | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Health Monitor

+

Welcome to the SCS Health Monitor project! This repository is dedicated to setting up scenarios for functionality and load testing on a deployed OpenStack environment. We utilize Gherkin language to write testing scenarios, and Python's Behave library to execute these tests.

+

Description

+

The SCS Health Monitor project aims to ensure the robustness and reliability of OpenStack environments by simulating various scenarios and assessing their performance under different loads. By employing Gherkin language and Behave library, we can define clear, human-readable test cases that cover a wide range of functionalities, from basic system checks to complex stress tests.

+

Getting Started

+

To get started with the SCS Health Monitor project, follow these steps:

+
    +
  1. +

    Clone healt-monitor repository to your local machine.

    +
    git clone git@github.com:SovereignCloudStack/scs-health-monitor.git
    cd scs-health-monitor
    +
  2. +
  3. +

    Install the required dependencies

    +
      +
    • listed in the [Dockerfile](https://github.com/SovereignCloudStack/scs-health-monitor/blob/main/Dockerfile) file +(see: apt-get ...)
    • +
    • listed in the [requirements.txt](https://github.com/SovereignCloudStack/scs-health-monitor/blob/main/requirements.txt) file by executing the following command: +
      ./scs-health-monitor deps
      +
    • +
    +
  4. +
  5. +

    Review the existing Gherkin scenarios in the [cloud_level_testing/features](https://github.com/SovereignCloudStack/scs-health-monitor/tree/main/cloud_level_testing/features) and [container_level_testing/features](https://github.com/SovereignCloudStack/scs-health-monitor/tree/main/container_level_testing/features) directories to understand the testing coverage.

    +
  6. +
  7. +

    Create a openstack project with a user with "manager" privileges and suitable quotas:

    +
      +
    • cores: 50
    • +
    • instances: 30
    • +
    • ram: 128000
    • +
    • volumes: 20
    • +
    • gigabytes: 200
    • +
    • security_groups: 50
    • +
    +

    You can use the openstack workload mananger

    +
    ${OPENSTACK_WORKLOAD_MANAGER_INSTALLATION_DIR?the installation dir}/openstack_workload_generator \
    --create_domains scs-health-monitor \
    --create_projects test-project \
    --create_machines none \
    --clouds_yaml $PWD/clouds.yaml \
    --config ${OPENSTACK_WORKLOAD_MANAGER_INSTALLATION_DIR}/profiles/health-mon.yaml
    +
  8. +
  9. +

    Create a clouds.yaml (example) file in the root of the repository-clone to configure API access to OpenStack.

    +
  10. +
  11. +

    Create a env.yaml (example) file containing configuration needed for performing the tests. +(Configure at least the CLOUD_NAME to specify which project should be used)

    +
  12. +
  13. +

    Execute the tests using Behave library to validate the functionality and performance of your OpenStack environment. +(see next section)

    +
  14. +
+

Using the test framework

+

Execute a specific test

+
./scs-health-monitor behave cloud_level_testing/features/openstack_create_network.feature
+

Here are some basic commands to run the tests:

+

Execute a series of tests

+
    +
  • +

    Run all scenarios for IaaS

    +
    ./scs-health-monitor behave cloud_level_testing/features/
    +
  • +
  • +

    Run all scenarios for KaaS

    +
    ./scs-health-monitor behave container_level_testing/features/
    +
  • +
  • +

    Run all scenarios for IaaS with the "network" and the "cleanup" tag

    +
    ./scs-health-monitor behave --tags=network  cloud_level_testing/features/
    ./scs-health-monitor behave --tags=cleanup cloud_level_testing/features/
    +
  • +
  • +

    Run all of the IaaS scenarios, but parallel only the features

    +
    ./scs-health-monitor behavex --parallel-scheme cloud_level_testing/features/
    +
  • +
+

There is a possibility to run it on the behavex framework as well. To get more information, here is a link to the documentation.

+

Publish results to Prometheus

+

The scs-health-monitor is capable to puhlish the results to a prometheus instance. +Details of the available measurements are available in the METRIC OVERVIEW.

+

Setting up Prometheus and Prometheus Push Gateway locally

+

For the purposes of gathering information from the test cases being performed against OpenStack, Prometheus metrics are being gathered during excecution of the test, then later these metrics are pushed to a Prometheus Push Gateway.

+

Here you can find a useful quickstart quide on setting up Promethus Stack and Prometheus push gateway locally.

+

Exporting metrics to Prometheus Push Gateway

+

To be able to push the metrics gathered during test executions, you must first configure the prometheus push gateway endpoint. You achieve this by adding these lines to a env.yaml:

+
# Required
# If not present the metrics won't
# be pushed by the test scenarios
PROMETHEUS_ENDPOINT: "localhost:30001"

# Optional (default: "SCS-Health-Monitor")
# Specify the job label value that
# gets added to the metrics
PROMETHEUS_BATCH_NAME: "SCS-Health-Monitor"

# Required
# The name of the cloud from clouds.yaml
# that the test scenarios will be ran on
CLOUD_NAME: "gx"

# Optional (default: true)
# Apply start time and stop time to prometheus batch name
APPEND_TIMESTAMP_TO_BATCH_NAME: true
+

This env.yaml file must be placed in the root of the repository. This is where you should be also issuing all the behave <...> commands to execute the test scenarios.

+

Use a docker image

+
    +
  • Create a docker image +
    docker build --progress plain -t scs-health-monitor -f Dockerfile .
    +
  • +
  • Execute a docker image +
    sudo chown 1001:1001 ./env.yaml ./clouds.yaml ./ca-certificates.crt
    DOCKER_MOUNTS="-v ./env.yaml:/installation/env.yaml -v ./clouds.yaml:/installation/clouds.yaml -v ./ca-certificates.crt:/installation/ca-certificates.crt"
    # A shell
    docker run -ti ${DOCKER_MOUNTS?not set} --rm --entrypoint /bin/bash --name scs-health-monitor scs-health-monitor
    # Entrypoint execution
    docker run -ti ${DOCKER_MOUNTS?not set} --rm --name scs-health-monitor scs-health-monitor behave <ARGUMENTS>
    docker run -ti ${DOCKER_MOUNTS?not set} --rm --name scs-health-monitor scs-health-monitor behave cloud_level_testing/features/openstack_create_network.feature
    +
  • +
+

Collaborators

+ + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-api/docs/configuration/index.html b/docs/operating-scs/components/status-page-api/docs/configuration/index.html new file mode 100644 index 0000000000..4253512356 --- /dev/null +++ b/docs/operating-scs/components/status-page-api/docs/configuration/index.html @@ -0,0 +1,27 @@ + + + + + +Configuration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Configuration

+

Configuration can be done by environment variables or flags to the binary.

+

Code to the configuration can be found at internal/app/config/config.go.

+
Environment keyFlagDescriptionTypeDefault
General settings
STATUS_PAGE_PROVISIONING_FILE--provisioning-fileYAML file containing the initial valuesPath./provisioning.yaml
STATUS_PAGE_SHUTDOWN_TIMEOUT--shutdown-timeoutTimeout to gracefully stop the serverDuration10s
STATUS_PAGE_VERBOSE-v / --verboseIncrease log levelCounter0
Server settings
STATUS_PAGE_SERVER_ADDRESS--server-addressAPI server listen addressString:3000
↳ Swagger settings
STATUS_PAGE_SERVER_SWAGGER_UI_ENABLED--server-swagger-ui-enabledEnable the swagger UI at /swaggerBooleanfalse
↳ CORS settings
STATUS_PAGE_SERVER_CORS_ENABLED--server-cors-enabledServer handles CORS.Booleantrue
STATUS_PAGE_SERVER_CORS_ALLOWED_ORIGINS--server-cors-allowed-originsList of allowed CORS originsString Arrayhttp://127.0.0.1, http://localhost
Database settings
STATUS_PAGE_DATABASE_CONNECTION_STRING--database-connection-stringPostgreSQL connection stringString
Metrics settings
STATUS_PAGE_METRICS_ADDRESS--metrics-addressEnable and set metrics server listen addressString
STATUS_PAGE_METRICS_NAMESPACE--metrics-namespaceMetrics namespaceStringstatus_page
STATUS_PAGE_METRICS_SUBSYSTEM--metrics-subsystemMetrics subsystem nameStringapi
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-api/docs/contribute/index.html b/docs/operating-scs/components/status-page-api/docs/contribute/index.html new file mode 100644 index 0000000000..f560dfa18d --- /dev/null +++ b/docs/operating-scs/components/status-page-api/docs/contribute/index.html @@ -0,0 +1,25 @@ + + + + + +Contribute | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-api/docs/example-requests/index.html b/docs/operating-scs/components/status-page-api/docs/example-requests/index.html new file mode 100644 index 0000000000..c3b4465c68 --- /dev/null +++ b/docs/operating-scs/components/status-page-api/docs/example-requests/index.html @@ -0,0 +1,62 @@ + + + + + +Example requests | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Example requests

+

Example request for common API requests.

+

Request can either be performed against the local API server at localhost:3000 or against the public release of the API server at status-api.k8s.scs.community. When using the public release authorization via bearer token must be included. Please refer to the status page deployment. +Local instances of the API can use STATUS_PAGE_SWAGGER_UI_ENABLED=true to perform request with swagger at localhost:3000/swagger. Any instance of the API can be used with the included Bruno collection.

+

All examples include the public release with authorization header.

+

List phases

+
$ curl -sL \
https://status-api.k8s.scs.community/phases

{"data":{"generation":1,"phases":["Scheduled","Investigation ongoing","Working on it","Potential fix deployed","Done"]}}
+

Create phases

+
$ curl -sL \
-X POST \
-H 'Authorization: Bearer <your-id-token>' \
-H 'Content-Type: application/json' \
-d '{"phases": ["Phase 1", "Phase 2", "Phase 3"]}' \
https://status-api.k8s.scs.community/phases

{"generation":2}
+

List impact types

+
$ curl -sL \
https://status-api.k8s.scs.community/impacttypes

{"data":[{"displayName":"Performance Degradation","id":"63645189-ffbc-4e6c-b991-99e14ade3edc"},{"displayName":"Connectivity Problems","id":"9fcf0039-9e24-45b0-b76a-80e6246a803b"},{"displayName":"Unknown","id":"6cadd69a-5702-4824-b7a6-d5509c54b8cb"}]}
+

Create impact type

+
$ curl -sL \
-X 'POST' \
-H 'Authorization: Bearer <your-id-token>' \
-H 'Content-Type: application/json' \
-d '{"displayName": "Test impact type"}' \
https://status-api.k8s.scs.community/impacttypes

{"id":"52d178d2-0fe9-4654-834b-42502283454d"}
+

Get impact type

+
$ curl -sL \
https://status-api.k8s.scs.community/impacttypes/52d178d2-0fe9-4654-834b-42502283454d

{"data":{"displayName":"Test impact type","id":"52d178d2-0fe9-4654-834b-42502283454d"}}
+

List severities

+
$ curl -sL \
https://status-api.k8s.scs.community/severities

{"data":[{"displayName":"operational","value":25},{"displayName":"maintenance","value":50},{"displayName":"limited","value":75},{"displayName":"broken","value":100}]}
+

Create severity

+
curl -sL \
-X POST \
-H 'Authorization: Bearer <your-id-token>' \
-H 'Content-Type: application/json' \
-d '{"displayName": "test","value": 60}'
https://status-api.k8s.scs.community/severities
+

Get severity

+
$ curl -sL \
https://status-api.k8s.scs.community/severities/test

{"data":{"displayName":"test","value":60}}
+

List components

+
$ curl -sL \
https://status-api.k8s.scs.community/components

{"data":[{"activelyAffectedBy":[],"displayName":"Storage","id":"871584dc-e425-4155-8fde-47ca588689f3","labels":{}},{"activelyAffectedBy":[],"displayName":"Network","id":"414d764f-0c94-4c4d-90e6-c97cce00cce3","labels":{}},...]}
+

Create component

+
curl -sL \
-X POST \
-H 'Authorization: Bearer <your-id-token>' \
-H 'Content-Type: application/json' \
-d '{"displayName":"Test-Component"}'\
https://status-api.k8s.scs.community/components

{"id":"3ebed33a-a80c-4888-b3d3-2677e87c25e7"}
+

Get component

+
$ curl -sL \
https://status-api.k8s.scs.community/components/3ebed33a-a80c-4888-b3d3-2677e87c25e7

{"data":{"activelyAffectedBy":[{"reference":"09f471bb-b0af-4528-a021-f23f31e2d1c9","severity":90,"type":"52d178d2-0fe9-4654-834b-42502283454d"}],"displayName":"Test-Component","id":"3ebed33a-a80c-4888-b3d3-2677e87c25e7"}}
+

List incidents

+
$ curl -sL \
'http://localhost:3000/incidents?start=2024-04-01T10%3A10%3A10.010Z&end=2024-04-30T10%3A10%3A10.010Z'

{"data":[{"affects":[{"reference":"3ebed33a-a80c-4888-b3d3-2677e87c25e7","type":"52d178d2-0fe9-4654-834b-42502283454d"}],"beganAt":"2024-04-03T08:00:00+02:00","description":"A test incident.","displayName":"Test-Incident","endedAt":null,"id":"09f471bb-b0af-4528-a021-f23f31e2d1c9","phase":{"generation":0,"order":0},"updates":[]}]}
+

Create incident

+
$ curl -sL \
-X POST \
-H 'Authorization: Bearer <your-id-token>' \
-H 'Content-Type: application/json' \
-d '{"affects":[{"reference":"3ebed33a-a80c-4888-b3d3-2677e87c25e7","severity":90,"type":"52d178d2-0fe9-4654-834b-42502283454d"}],"beganAt":"2024-04-03T06:00:00.000Z","description":"A test incident.","displayName":"Test-Incident","phase":{}}' \
https://status-api.k8s.scs.community/incidents

{"id":"09f471bb-b0af-4528-a021-f23f31e2d1c9"}
+

Get incident

+
$ curl -sL \
https://status-api.k8s.scs.community/incidents/09f471bb-b0af-4528-a021-f23f31e2d1c9

{"data":{"affects":[{"reference":"3ebed33a-a80c-4888-b3d3-2677e87c25e7","type":"52d178d2-0fe9-4654-834b-42502283454d"}],"beganAt":"2024-04-03T08:00:00+02:00","description":"A test incident.","displayName":"Test-Incident","endedAt":null,"id":"09f471bb-b0af-4528-a021-f23f31e2d1c9","phase":{"generation":0,"order":0},"updates":[]}}
+

List incident update

+
$ curl -sL \
https://status-api.k8s.scs.community/incidents/09f471bb-b0af-4528-a021-f23f31e2d1c9/updates

{"data":[{"createdAt":"2024-04-03T08:15:00+02:00","description":"Example update for test incident","displayName":"Example Update","order":0}]}
+

Create incident update

+
$ curl -sL \
-X POST \
-H 'Authorization: Bearer <your-id-token>' \
-H 'Content-Type: application/json' \
-d '{"createdAt":"2024-04-03T06:15:00.000Z","description":"Example update for test incident","displayName":"Example Update"}' \
https://status-api.k8s.scs.community/incidents/09f471bb-b0af-4528-a021-f23f31e2d1c9/updates

{"order": 0}
+

Get incident update

+
$ curl -sL \
https://status-api.k8s.scs.community/incidents/09f471bb-b0af-4528-a021-f23f31e2d1c9/updates/0

{"data":{"createdAt":"2024-04-03T08:15:00+02:00","description":"Example update for test incident","displayName":"Example Update","order":0}}
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-api/docs/overview/index.html b/docs/operating-scs/components/status-page-api/docs/overview/index.html new file mode 100644 index 0000000000..07d43c4bdb --- /dev/null +++ b/docs/operating-scs/components/status-page-api/docs/overview/index.html @@ -0,0 +1,27 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

The status-page-api repository strives to provide a reference implementation of the concepts being outlined by status-page-openapi.

+

For the implementation go was used, as rational see the decision record.

+

Code under the pkg/ directory, is considered as public reference or even library code to implement your own API server, while code in internal/ is implementation specific to this application, but can serve as reference, too.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-api/docs/quickstart/index.html b/docs/operating-scs/components/status-page-api/docs/quickstart/index.html new file mode 100644 index 0000000000..69fa4c20dd --- /dev/null +++ b/docs/operating-scs/components/status-page-api/docs/quickstart/index.html @@ -0,0 +1,38 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Quickstart

+

See requirements

+

Run as container

+

The quickest way to start working with the API server, is to run the container directly.

+
docker run --rm --network host -e STATUS_PAGE_DATABASE_CONNECTION_STRING="host=localhost user=postgres dbname=postgres port=5432 password=debug sslmode=disable" -e STATUS_PAGE_VERBOSE=3 registry.scs.community/status-page/status-page-api:latest
+

Compile and run the binary

+

Compiling the binary and running it is equally easy.

+
go build -o /bin/status-page-api cmd/status-page-api/main.go

STATUS_PAGE_DATABASE_CONNECTION_STRING="host=localhost user=postgres dbname=postgres port=5432 password=debug sslmode=disable" STATUS_PAGE_VERBOSE=3 ./bin/status-page-api
+

Running tests

+

The status page API server tests it's API handler and database code with a plethora of tests. These tests can be run with go.

+
go test ./...
+

Furthermore test can be run to create a coverage profile.

+
go test -coverprofile coverage.out ./...
+

This cover profile can be used to analyze code coverage

+
# per function coverage
go tool cover -func coverage.out
# HTML representation of tested code
go tool cover -html coverage.out
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-api/docs/requests/index.html b/docs/operating-scs/components/status-page-api/docs/requests/index.html new file mode 100644 index 0000000000..3a588098c3 --- /dev/null +++ b/docs/operating-scs/components/status-page-api/docs/requests/index.html @@ -0,0 +1,47 @@ + + + + + +Requests | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Requests

+

As defined by the OpenAPI spec and status page OpenAPI decision the general API objects are used as request bodies and responses to generalize data structures. Not all object fields are handled by all requests, some are read only and some are write only. GET request wrap their return in a object field called data.

+

Please refer to example requests to see these request in action.

+

Phases

+

Phases are always handled as lists, so GET as well as POST operations on phases always require the full list. When getting the phase list, it's accompanied be a generation annotation.

+
{
"generation": 1, // omitted on POST and PATCH
"phases": [
"Phase 1",
"Phase 2",
"Pahse 3"
]
}
+

Impact types

+

Requesting (GET) an impact type, will return all fields, while POST and PATCH operations omit the id field.

+
{
"id": "UUID", // omit on POST and PATCH
"description": "Description of the impact type.",
"displayName": "Name"
}
+

Severities

+

For all request types (GET, POST, PATCH), all fields of the severity are handled.

+
{
"displayName": "string",
"value": 100
}
+

As displayName is the identifier it must be unique, even when modified by PATCH

+

Components

+

When GETing a component, all fields can be expected to be filled, while requests for POST (creation) and PATCH operations only handle certain fields.

+
{
"id": "UUID", // omitted on POST and PATCH
"activelyAffectedBy": [ // omitted on POST and PATCH
{
"reference": "Incident-UUID",
"severity": 100,
"type": "ImpactType-UUID"
}
],
"displayName": "Name",
"labels": {
"key": "value",
}
}
+

Incidents

+

It is expected that incidents are the most used API object and have the most data to transmit.

+
{
"id": "UUID", // omitted on POST and PATCH
"affects": [
{
"reference": "Component-UUID",
"severity": 100,
"type": "ImpactType-UUID"
}
],
"beganAt": "2024-01-01T06:00:00.000Z",
"description": "Description of the incident.",
"displayName": "Name",
"endedAt": "2024-01-01T08:00:00.000Z", // or null, when incident is still ongoing.
"phase": {
"generation": 1,
"order": 1
},
"updates": [ // omitted on POST and PATCH
0,
1,
2
]
}
+

The affects field can, in theory, have as many entries as there are components. The updates field is an ongoing list of updates. All changes to phase should correlate to an update.

+

When performing POST or PATCH operations on incidents the affects field is of utmost importance, as it creates the impact. Only when referencing a component to an incident via the affects field, an impact is created, that can be retrieved via the affected component.

+

Incident update

+

Whenever an incident changes, an update should be issued. When doing a GET request, the order field is filled, updates should be displayed in ascending order.

+
{
"order": 0, // omitted on POST and PATCH
"createdAt": "2024-01-01T06:15:00.000Z",
"description": "Description of the update.",
"displayName": "Name"
}
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-api/docs/requirements/index.html b/docs/operating-scs/components/status-page-api/docs/requirements/index.html new file mode 100644 index 0000000000..c770917a82 --- /dev/null +++ b/docs/operating-scs/components/status-page-api/docs/requirements/index.html @@ -0,0 +1,26 @@ + + + + + +Requirements | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-deployment/docs/admin-authentication/index.html b/docs/operating-scs/components/status-page-deployment/docs/admin-authentication/index.html new file mode 100644 index 0000000000..ac1eea8a6d --- /dev/null +++ b/docs/operating-scs/components/status-page-deployment/docs/admin-authentication/index.html @@ -0,0 +1,28 @@ + + + + + +Admin authentication | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Admin authentication

+

As the write operations of the API server are protected by Oathkeeper and use identities provided by Dex an Administrator is considered to be a person that can authenticate on Dex.

+

On the public SCS deployment, these persons are members of the SovereignCloudStack organization.

+

This sequence diagram displays a simplified flow how an administrator authenticates himself with Dex and GitHub, to authorize using the write operations.

+
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-deployment/docs/configuration/index.html b/docs/operating-scs/components/status-page-deployment/docs/configuration/index.html new file mode 100644 index 0000000000..e11fc6e261 --- /dev/null +++ b/docs/operating-scs/components/status-page-deployment/docs/configuration/index.html @@ -0,0 +1,41 @@ + + + + + +Configure status page | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Configure status page

+

A minimal configuration of the status page deployment.

+

API server

+

Configure the allowed origins via api/api.env to include the domain from the web frontend. CORS origins need to include the protocol, too. Example: https://frontend.<your-domain>.

+

Database

+

Set a password for the database at database/db-secrets.env and configure the connection string in api/api-secrets.env

+

Dex

+

Dex needs a GitHub Applications Client Secret in dex/dex-secrets.env, please refer to dex/dex-secrets-example.env.

+

Set the issuer and redirectURI at dex/config.yaml to your domain. Keep in mind, that dex needs it's own domain or subdomain.

+

Other Dex related configuration is located in dex/dex.env, web/web-secrets.env and web/web.env to fill the configuration template dex/config.yaml.

+

Oathkeeper

+

Set your domain in oathkeeper/config.yaml at authenticators.jwt.config.jwks_urls and authenticators.jwt.config.trusted_issuers to point towards Dex.

+

Web frontend

+

In web/web.env configure the OIDC authentication callback and the API url. The API URL must be pointing to the external domain, not the K8s service name.

+

Ingress

+

In ingress.yaml set your domains for Dex, Oathkeeper and the web frontend respectively. Oathkeeper acts as the auth proxy for the API server. Exposing the API server directly, opens up the possibility of unsupervised write actions.

+

Issuer

+

Set the e-mail address in issuer.yaml to your desired e-mail address.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-deployment/docs/contribute/index.html b/docs/operating-scs/components/status-page-deployment/docs/contribute/index.html new file mode 100644 index 0000000000..cf098c3e6d --- /dev/null +++ b/docs/operating-scs/components/status-page-deployment/docs/contribute/index.html @@ -0,0 +1,25 @@ + + + + + +Contribute | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-deployment/docs/faq/index.html b/docs/operating-scs/components/status-page-deployment/docs/faq/index.html new file mode 100644 index 0000000000..04e842003b --- /dev/null +++ b/docs/operating-scs/components/status-page-deployment/docs/faq/index.html @@ -0,0 +1,32 @@ + + + + + +FAQ | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

FAQ

+

Dex needs a GitHub client secret. Where can I get it?

+

The examples are directly linked to the SCS Gatekeeper OAuth app that allows access for SovereignCloudStack members. It's recommended to create an own OAuth app in GitHub or any other supported provider. If you need quick and easy access as developer or tester, get in contact on matrix.

+

I want to deploy on XY, can you do that?

+

Yes, all ways that are shown here to deploy the status page can be seen as examples and templates. Fork the repository and build your own deployment. Maybe start a pull request to share your way.

+

I want to deploy another database, reverse proxy, ingress, AuthN, AuthZ, etc. Can you do that?

+

Yes, see above.

+

I want another web frontend and API server, can you do that?

+

Currently no. The reference implementation only supplies one API server and one web frontend. You can implement your own, when conforming to SovereignCloudStack/status-page-openapi.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-deployment/docs/k3s/index.html b/docs/operating-scs/components/status-page-deployment/docs/k3s/index.html new file mode 100644 index 0000000000..71149c205a --- /dev/null +++ b/docs/operating-scs/components/status-page-deployment/docs/k3s/index.html @@ -0,0 +1,62 @@ + + + + + +k3s - A simple deployment on a single host | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

k3s - A simple deployment on a single host

+

From a new machine to a working status page in ~15 minutes.

+

Prerequisites

+

A VM or bare metal host with a public IP. Optional: A domain pointing to the public IP.

+

k3s setup

+

Setting up k3s to run k8s workloads on the machine.

+

Firewall settings

+

Allow communication to and from the cluster.

+

Incoming:

+
    +
  • 6443 Kubernetes API server
  • +
  • 80 HTTP ingress
  • +
  • 443 HTTPS ingress
  • +
+

Internal:

+
    +
  • 10.42.0.0/16 - Pod communication
  • +
  • 10.43.0.0/16 - Service communication
  • +
+

ufw example

+
ufw allow 6443/tcp # api server
ufw allow from 10.42.0.0/16 to any # pods
ufw allow from 10.43.0.0/16 to any # services

ufw allow 80/tcp # http
ufw allow 443/tcp # https
+

Install

+

Configure and install k3s directly via install script. See the k3s server config.

+
curl -sfL https://get.k3s.io | sh -s - server \
--tls-san <your-ip> \
--tls-san <your-domain>
+

Setting the SANs enables the k3s server to be available via your domain and server ip.

+

Deployment

+

Deploy services to the cluster, to get the status page running.

+

If you don't have access to a domain name, consider using nip.io to use as (sub)domains for Dex, Oathkeeper (API server) and the web frontend.

+

Kube config

+

The newly generated kube config for the cluster is located at /etc/rancher/k3s/k3s.yaml. Copy to your machine to configure access to the cluster.

+

Change the URI at .clusters[0].cluster.server to the URI you added to the SAN config.

+

Deploy cert manager

+

Deploy cert-manager on the cluster to automatically receive LetsEncrypt certificates.

+

See issuer.yaml for settings.

+

Configure and deploy status page

+

For in depth configuration see configuration.md.

+

Assemble and deploy the k3s deployment.

+
kubectl kustomize kubernetes/environments/k3s/ > k3s_out.yaml
kubectl apply -f k3s_out.yaml
# or
kubectl apply -k kubernetes/environments/k3s/
+

The deployment creates a namespace called status-page where all services, ingress, etc. gets deployed.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-deployment/docs/kind/index.html b/docs/operating-scs/components/status-page-deployment/docs/kind/index.html new file mode 100644 index 0000000000..8b6aec6e4d --- /dev/null +++ b/docs/operating-scs/components/status-page-deployment/docs/kind/index.html @@ -0,0 +1,65 @@ + + + + + +kind - Local development environment | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

kind - Local development environment

+

kind is a tool to quickly setup a local development environment, to test and debug the deployment.

+

NOTE: kind is not considered to be used as any kind of productive deployment.

+

"Secrets"

+

All "secrets" shared in kubernetes/environments/kind are example values to get a local environment up and running. These values should be substituted by real and secure secrets.

+

Per Installation Steps

+
    +
  • Install kind from the official website.
  • +
  • Clone the status-page-deployment repository +
    git clone git@github.com:SovereignCloudStack/status-page-deployment.git
    +
  • +
  • Create a Github OAuth app for testing, see example data: +(Note: It is not critical to share the data listed here, as this is only a test application which is reachable from localhost) + +
  • +
+

Setup

+

Create a local kind cluster with:

+
make cluster
+

Deploy

+

All needed configurations and secrets, except Dex's GitHub app secrets, are set up in a ready to use kustomization: kubernetes/environments/kind/kustomization.yaml, just assemble and deploy:

+
    +
  • Create Github application
  • +
  • Create and configure OAUTH config files +
    cp kubernetes/environments/kind/dex/dex-secrets-example.env kubernetes/environments/kind/dex/secrets.env
    vim kubernetes/environments/kind/dex/dex.env # configure GITHUB_CLIENT_ID
    vim kubernetes/environments/kind/dex/secrets.env # configure GITHUB_CLIENT_SECRET
    +
  • +
  • Deploy Application +
    make deploy
    +
  • +
+

For further configuration see configuration.md.

+

Port forward

+

The local kind deployment uses Caddy as reverse proxy, instead of Ingress and IngressControllers, to the cluster services. +Port forward to the reverse proxy to start using the deployment locally.

+

For example:

+
make forward
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-deployment/docs/monitoring/index.html b/docs/operating-scs/components/status-page-deployment/docs/monitoring/index.html new file mode 100644 index 0000000000..1d9197acb0 --- /dev/null +++ b/docs/operating-scs/components/status-page-deployment/docs/monitoring/index.html @@ -0,0 +1,38 @@ + + + + + +Monitoring | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Monitoring

+

All backend components of the status page can be instrumented to supply metrics. These metrics can be collected and visualized by monitoring technologies like Prometheus and Grafana.

+

Endpoints

+

The services expose their metrics endpoints on different ports.

+
ServicePort (Name)Endpoint
api-db9187 (metrics)/metrics
api9000 (metrics)/metrics
dex5558 (telemetry)/metrics
oathkeeper9000 (metrics)/metrics
+

Dashboards

+

To visualize the supplied metrics, some dashboards are needed.

+

For the used database and exporter the PostgreSQL Database dashboard is recommended.

+

Go runtime metrics can be visualized by the Go Metrics dashboard.

+

Hand crafted dashboard for Dex, Oathkeeper and the status-page-api are located at kubernetes/feature/monitoring/grafana/dashboards and have according prefixes.

+

KinD

+

The KinD deployment deploys Grafana and Prometheus pods and sets up the data source and dashboards, to work with the rest of the deployment out of the box.

+

The Grafana frontend can be accessed by port forwarding the reverse proxy:

+
kubectl --context kind-status-page -n status-page port-forward pods/status-page-reverse-proxy-78d588d58b-7rdn6 8080:8080
+

Afterwards Grafana can be accessed by navigating to monitoring.localhost:8080. Use the username admin and password s3cr3t.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-deployment/docs/overview/index.html b/docs/operating-scs/components/status-page-deployment/docs/overview/index.html new file mode 100644 index 0000000000..3566c64a51 --- /dev/null +++ b/docs/operating-scs/components/status-page-deployment/docs/overview/index.html @@ -0,0 +1,46 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

The status page needs some components additional to the API server to be usable by operators and customers. As the API server does not implement any kind of authorization or authentication some components need to be deployed to protect the write operations of the API from unauthorized access.

+

Components

+

These components are picked as examples and can be exchanged with any technology that is fitting the use case.

+

The used components are Oathkeeper and Dex to implement AuthN1 and AuthZ2. Oathkeeper is a proxy that handles incoming requests and authorization, while Dex is used as an identity broker, used for authentication, to be used in conjunction with Oathkeeper to secure the API server.

+

Furthermore the API server needs a running database, for this PostgreSQL is used.

+

Last but not least the the status page is completed by a web front. For this the reference implementation from the status-page-web repository.

+

Some deployments use reverse proxies, ingress controllers or can even use the gateway API. These are deployment specific and can be used as the use case requires.

+

Component overview

+ +

Deployment repository

+

The deployment repository contains a local development environment using KinD, templates for other deployments, in example using k3s and the skeleton of the deployment for the public SCS cluster.

+ +

Footnotes

+
    +
  1. +

    Authentication

    +
  2. +
  3. +

    Authorization

    +
  4. +
+
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-deployment/docs/quickstart/index.html b/docs/operating-scs/components/status-page-deployment/docs/quickstart/index.html new file mode 100644 index 0000000000..735cce67bf --- /dev/null +++ b/docs/operating-scs/components/status-page-deployment/docs/quickstart/index.html @@ -0,0 +1,26 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-deployment/docs/requirements/index.html b/docs/operating-scs/components/status-page-deployment/docs/requirements/index.html new file mode 100644 index 0000000000..3be7d2fc48 --- /dev/null +++ b/docs/operating-scs/components/status-page-deployment/docs/requirements/index.html @@ -0,0 +1,30 @@ + + + + + +Requirements | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Requirements

+

The requirements are specific for the relevant environment.

+

In general a running k8s cluster is needed, as well as tooling to interface with the given cluster, e.g. kubectl.

+

For a local development cluster KinD, minikube or similar can be used. KinD is the currently tested method.

+

For a single machine deployment k3s is the currently recommended method.

+

A production deployment needs a production ready k8s cluster, in which ever form is deemed practical.

+

Please refer to the used method of deployment for more specific information about setup and requirements.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-deployment/docs/scs-public/index.html b/docs/operating-scs/components/status-page-deployment/docs/scs-public/index.html new file mode 100644 index 0000000000..b88322a33a --- /dev/null +++ b/docs/operating-scs/components/status-page-deployment/docs/scs-public/index.html @@ -0,0 +1,28 @@ + + + + + +SCS Public | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Public

+

Data present in kubernetes/environments/scs-public is the deployment specified for the provided SCS Cluster, which is already fully setup to run k8s workloads.

+

Configure the provided .envs. For secrets, the provided examples drop the -example part of their file names to be used as .env for that secret.

+

For in depth configuration see configuration.

+

Deploy kubernetes/environments/scs-public/kustomization.yaml to your desired cluster.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-deployment/docs/usage/index.html b/docs/operating-scs/components/status-page-deployment/docs/usage/index.html new file mode 100644 index 0000000000..feea39d9b3 --- /dev/null +++ b/docs/operating-scs/components/status-page-deployment/docs/usage/index.html @@ -0,0 +1,44 @@ + + + + + +Usage | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Usage

+

You can use and test the API via any API client (Bruno, built in Swagger UI, etc.), CLI tool (like curl) or the web frontend.

+

All examples provided use curl, the most manual methods and the public SCS release.

+

Receive auth code

+

Visit the openid-configuration of the running Dex and build an auth URL from the provided information and your desired parameters.

+

For example:

+

https:///login

+
https://status-idp.k8s.scs.community/auth?client_id=status-page-web&redirect_uri=https%3A%2F%2Fstatus.k8s.scs.community%2Flogin&response_type=code&scope=openid+profile+email+offline_access
+

And visit the generated URL to start the Authorization Code Flow.

+

After authentication you get redirect to https://status.k8s.scs.community/login?code=<your-code>&state=

+

Exchange token

+

Copy your code and send it to the token URL.

+

For example:

+
$ curl -sL \
-X POST \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id=status-page-web' \
-d 'client_secret=<your-secret>' \
-d 'code=<your-code>' \
-d 'redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Flogin' \
-d 'grant_type=authorization_code' \
https://status-idp.k8s.scs.community/token

{
"access_token": "<your-access-token>",
"token_type": "bearer",
"expires_in": 86399,
"refresh_token": "<your-refresh-token>",
"id_token": "<your-id-token>"
}
+

NOTE: Be extremely careful with your code and client secret as they represent credentials!

+

Use API

+

Copy your id token and use it as bearer token in writing requests.

+

For example creating a new component:

+
curl -sL \
-X POST \
-H 'Authorization: Bearer <your-id-token>' \
-H 'Content-Type: application/json' \
-d '{"displayName":"Test-Component"}'\
https://status-api.k8s.scs.community/components
+

NOTE: Be extremely careful with your id token and access token as they represent credentials!

+

More usage examples can be found at SovereignCloudStack/status-page-api/docs/example-requests.md

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-openapi/docs/component_overview/index.html b/docs/operating-scs/components/status-page-openapi/docs/component_overview/index.html new file mode 100644 index 0000000000..b9f65881f2 --- /dev/null +++ b/docs/operating-scs/components/status-page-openapi/docs/component_overview/index.html @@ -0,0 +1,32 @@ + + + + + +Component Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-openapi/docs/components/index.html b/docs/operating-scs/components/status-page-openapi/docs/components/index.html new file mode 100644 index 0000000000..33f8202477 --- /dev/null +++ b/docs/operating-scs/components/status-page-openapi/docs/components/index.html @@ -0,0 +1,27 @@ + + + + + +Components | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus/index.html b/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus/index.html new file mode 100644 index 0000000000..e6235bbeca --- /dev/null +++ b/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus/index.html @@ -0,0 +1,64 @@ + + + + + +"Levels of consensus" | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

"Levels of consensus"

+

When implementing any system to be used by a group of potential users, there will be varying use cases and opinions about API's, programming languages, persistence models, authentication, authorization, deployment options and so on. +Hence, building a complete one-fits-all solution is difficult, but (while offering a pretty un-opinionated reference implementation) even finding consensus on a few basic concepts may make adaptation and integration of different solutions possible.

+

The "levels" of consensus could be split into:

+

Consensus on...

+
    +
  1. Resource Definition +
      +
    • "What is an incident?"
    • +
    • Core REST API Spec
    • +
    +
  2. +
  3. General Architecture +
      +
    • "Monolithic Web App or multiple components?"
    • +
    • "Use static password file or rely on OIDC provider?"
    • +
    • (If any:) Interfaces between components: +
        +
      • AuthN mechanisms
      • +
      • AuthZ decisions
      • +
      +
    • +
    +
  4. +
  5. Implementation of core component(s) +
      +
    • "Use reference implementation components?"
    • +
    • "Go vs. JavaScript?"
    • +
    • "Postgres vs. MySQL?"
    • +
    +
  6. +
  7. Choice of all used components +
      +
    • "Policy: Istio vs. traefik?"
    • +
    • "Deployment: Helm vs. ansible?"
    • +
    • "dex vs. keycloak vs. zitadel?"
    • +
    +
  8. +
+

Every user of the Status Page (API) should be able to either make full use of the full reference implementation, building little to none on their own; Or just pick core concepts/API's/automation and build partial compatibility.

+

E.g. while the value on agreeing on every aspect would bring the most value, this most likely is not likely to happen, but adopting only the "Resource Definition", should ideally bring value already.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-openapi/docs/overview/index.html b/docs/operating-scs/components/status-page-openapi/docs/overview/index.html new file mode 100644 index 0000000000..e3fd7c590d --- /dev/null +++ b/docs/operating-scs/components/status-page-openapi/docs/overview/index.html @@ -0,0 +1,70 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

Service providers often times want to communicate the status of their systems transparently to their users. +A commonly used pattern is to provide a "status page" web application, where the current system health as well as recent incidents are made available.

+

SCS strives to implement a status page that works well, while being interoperable with other systems.

+
note

How was the decision to implement a new status page application made? What were the requirements? See the decision record.

+

To be easily interoperable with other software, being "API-first" is a priority. +As such, the status page should not need to be a typical monolithic web application (even though it could be), hence making it possible to split functionality into an API server and a frontend component.

+

The SCS status page API

+

The SCS status page API (as opposed to actual implementations) is supposed to be as un-opinionated as possible regarding deployment, user management, persistence and tech stack, to allow operators/developers (1) to make their own decisions regarding these topics and (2) to quickly implement the API with their own tech stack opinions, if the reference implementation does not fit theirs.

+

In particular, the API has no opinion about:

+
    +
  • How authentication/authorization is done (apart from splitting Read-only from Read-write 1; See below)
  • +
  • Server implementation, used database, deployment automation, high availability
  • +
+

However, as un-opinionated the API (in its first iteration) strives to be, it is...:

+
    +
  • a REST API (no GRPC/GraphQL/...)
  • +
  • defined using an OpenAPI file to make use of OpenAPI tooling
  • +
  • split in two parts 1: +
      +
    1. Read-only anonymous access
    2. +
    3. Read-write authenticated access
    4. +
    +
  • +
+

Reference implementation

+

It is envisioned to have a well-maintained reference implementation of the status page API with some basic tech stack decisions made, to not require anyone to implement the API themselves:

+
    +
  • Programming Language: Go
  • +
  • Persistence: Postgres compatible database
  • +
+

The SCS status page frontend

+

The SCS status page frontend is supposed to be an application which uses the status page API to get information. This could be an CLI tool as well as an web application.

+

Reference implementation

+

It is envisioned to have a well-maintained reference implementation of an status page frontend with some basic tech stack decisions made:

+
    +
  • Platform: Web (HTML/JS/...)
  • +
  • Framework: VueJS, Vuetify
  • +
+ +

Footnotes

+
    +
  1. +

    In the future 2

    +
  2. +
+
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-web/docs/configuration/index.html b/docs/operating-scs/components/status-page-web/docs/configuration/index.html new file mode 100644 index 0000000000..9b15222c74 --- /dev/null +++ b/docs/operating-scs/components/status-page-web/docs/configuration/index.html @@ -0,0 +1,36 @@ + + + + + +Configuration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Configuration

+

The SPA expects a configuration file called config.json to be present in the src/assets folder. The very same folder also contains a template for this configuration file, called config.tmpl.json. The resulting configuration, in the static build of the SPA, will be located at dist/scs-statuspage/browser/assets.

+

Configuration File

+

The following table explains all settings available in the configuration file. Explanations for non-basic field types can be found below the table.

+
Configuration KeyDescriptionTypeDefault
apiServerUrlThe URL of the API server supplying data.Stringempty
redirectUrlURL you are being redirected to after Dex.Stringempty
dexUrlThe URL of your Dex server.Stringempty
dexIdID your application uses for Dex.Stringempty
noOfDaysNumber of days to display incidents for.Number90
dateFormatThe format to use for dates displayed.Format"YYYY-MM-DD HH:mm:ss z"
longDateFormatLong format for dates, including day names.Format"dddd, Do MMMM YYYY, HH:mm:ss z"
severitiesMaps severities to colors to use.Objectsee below
unknownColorColor to use for unknown severity values.Color"lightsteelblue"
aboutTextShort text that appears in the "About" section.Stringempty
maintenancePreviewDaysNumber of days in the future to check for maintenance events.number30
hideManagementPageMakes the old management page inaccessible.Booleantrue
dayDefaultSeveritySeverity value used for days where no incidents occuredNumber1
+

The severities map contains one entry for each severity level specified in the API server. The default configuration included in the template file looks like this:

+

Note: The noOfDays field is not recommended to be edited. Unexpected results may occur.

+
"severities": {
// Maintenance is a special case and uses only the severity value 0
"maintenance": {
"start": 0,
"end": 0,
"color": "#50c3a5",
"colorblind": "#e1be6a"
},
"operational": {
// Start value is explicit
"start": 1,
// End value
"end": 33,
// Normal mode color
// Colors can be specified as in CSS
"color": "#50c3a5",
// Color to use for colorblind mode
"colorblind": "#8ce05d"
},
"limited": {
"start": 34,
"end": 66,
"color": "#f5c451",
"colorblind": "#5d3a9b"
},
"broken": {
"start": 67,
"end": 100,
"color": "#ee6a5f",
"colorblind": "#d62c13"
}
}
+

Field Types

+
    +
  • Format: A format string using the format specifiers provided by Day.js, including the ones provided by the AdvancedFormat plugin.
  • +
  • Color: A string containing a color value, specified using CSS notation. Allows for color names, hex values using a leading # or the rgb(...) syntax.
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-web/docs/contribute/index.html b/docs/operating-scs/components/status-page-web/docs/contribute/index.html new file mode 100644 index 0000000000..ef44699d36 --- /dev/null +++ b/docs/operating-scs/components/status-page-web/docs/contribute/index.html @@ -0,0 +1,30 @@ + + + + + +Contribute | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Contribute

+

To start developing for the status page web frontend, start by cloning the repo. Remember to run git submodule update --init afterwards to also retrieve the OpenAPI client included in the sources.

+

Now you should follow the Quickstart guide of the status-page-deployment repo and deploy and configure a local kind environment. You may have to modify your hosts file to re-route requests to the available components:

+
127.0.0.1   api.localhost dex.localhost oathkeeper.localhost web.localhost monitoring.localhost
+

You can now copy the configuration file template and set the apiServerUrl and dexUrl properties to http://api.localhost:8080 and http://dex.localhost:8080, respectively. Set your dexId to status-page-web and the redirectUrl to http://localhost:4200/login.

+

You are now ready to run npm install to retrieve all dependencies. Afterwards, you can start the application locally by running npx ng serve. The status page will be available under http://localhost:4200.

+

This repo also contains Devcontainer files for Visual Studio Code and we suggest using this to quickly set up your development environment.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-web/docs/overview/index.html b/docs/operating-scs/components/status-page-web/docs/overview/index.html new file mode 100644 index 0000000000..d1f582e296 --- /dev/null +++ b/docs/operating-scs/components/status-page-web/docs/overview/index.html @@ -0,0 +1,26 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

This repository supplies a SPA (Single Page Application), written in Angular, that uses the status-page-openapi client to connect to the API server to show components, incidents and their impacts on the system. The SPA also offers a management page, allowing authorized users to create, update and delete incidents (including future incidents, the so-called maintenance events).

+

The SPA is released as a container running nginx to serve the static build of the application. No other server components are needed to serve the application.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-web/docs/quickstart/index.html b/docs/operating-scs/components/status-page-web/docs/quickstart/index.html new file mode 100644 index 0000000000..87182bd63b --- /dev/null +++ b/docs/operating-scs/components/status-page-web/docs/quickstart/index.html @@ -0,0 +1,26 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page-web/docs/requirements/index.html b/docs/operating-scs/components/status-page-web/docs/requirements/index.html new file mode 100644 index 0000000000..0109275282 --- /dev/null +++ b/docs/operating-scs/components/status-page-web/docs/requirements/index.html @@ -0,0 +1,25 @@ + + + + + +Requirements | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install/index.html b/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install/index.html new file mode 100644 index 0000000000..764fdff7b7 --- /dev/null +++ b/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install/index.html @@ -0,0 +1,304 @@ + + + + + +Guide: Setting up openstack-health-monitor on Debian 12 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Guide: Setting up openstack-health-monitor on Debian 12

+

Kurt Garloff, 2024-02-20

+

Intro

+

The development of openstack-health-monitor was done on openSUSE 15.x images, just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution.

+

Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here.

+

Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a successor project for the increasingly hard to maintain shell code, this may not be worth the trouble.

+

openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested. +The scenario is described in a bit more detail in the repository's README.md file.

+

The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the monitoring section of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up.

+

Setting up the driver VM

+

So we start a Debian 12 image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard; +the instructions use flavor names and image names from the SCS standards. +For many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack).

+

Internal vs external monitoring

+

There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor.

+

The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems.

+

Unprivileged operation

+

Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own.

+

If openstack availability zone list --compute fails for you without admin rights, please fix your openstack client, e.g. by applying the patch I mentioned in this issue. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Health-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)

+

Driver VM via openstack CLI

+

The author prefers to setup the VM via openstack CLI tooling. He has working entries for all clouds he uses in his ~/.config/openstack/clouds.yaml and secure.yaml and has exported the OS_CLOUD environment variable to point to the cloud he is working on to set up the driver VM. The author uses the bash shell. All of this of course could be scripted.

+

So here we go

+
    +
  1. Create the network setup for a VM in a network oshm-network with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network.
  2. +
+
PUBLIC=$(openstack network list --external -f value -c Name)
openstack router create oshm-router
openstack router set --external-gateway $PUBLIC oshm-driver-router
openstack network create oshm-network
openstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet
openstack router add subnet oshm-router oshm-subnet
+
    +
  1. Create a security group that allows ssh and ping access
  2. +
+
openstack security group create sshping
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping
openstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping
+
    +
  1. Being at it, we also create the security group for grafana
  2. +
+
openstack security group create grafana
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana
+
    +
  1. To connect to the VM via ssh later, we create an SSH keypair
  2. +
+
openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key
chmod og-r ~/.ssh/oshm-key.pem
+

Rather than creating a new key (and storing and protecting the private key), we could have passed --public-key and used an existing keypair.

+
    +
  1. Look up Debian 12 image UUID.
  2. +
+
IMGUUID=$(openstack image list --name "Debian 12" -f value -c ID | tr -d '\r')
echo $IMGUUID
+

Sidenote: The tr command is there to handle broken tooling that embeds a trailing \r in the output.

+
    +
  1. Boot the driver VM
  2. +
+
openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver
+

Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing --block-device. See diskless flavor blog article. For flavors with local root disks, you could have used the --image $IMGUUID parameter instead.

+
    +
  1. Wait for it to boot (optional) +You can look at the boot log with openstack console log show oshm-driver or connect to it via VNC at the URL given by openstack console url show oshm-driver. You can of course also query openstack on the status openstack server list or openstack server show oshm-driver. You can also just create a simple loop:
  2. +
+
declare -i ctr=0 RC=0
while [ $ctr -le 120 ]; do
STATUS="$(openstack server list --name oshm-driver -f value -c Status)"
if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi
if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi
if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi
sleep 2
let ctr+=1
done
# return $RC
if [ $RC != 0 ]; then false; fi
+
    +
  1. Attach a floating IP so it's reachable from the outside.
  2. +
+
FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks |  sed "s@^[^:]*:[^']*'\([0-9\.]*\)'.*\$@\1@")
FIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)
echo $FIXEDIP $FIXEDPORT
openstack floating ip create --port $FIXEDPORT $PUBLIC
FLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")
echo "Floating IP: $FLOATINGIP"
+

Remember this floating IP address.

+
    +
  1. Connect to it via ssh
  2. +
+
ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP
+

On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)

+

All the following commands are performed on the newly started driver VM.

+

Configuring openstack CLI on the driver VM

+

We need to install the openstack client utilities.

+
sudo apt-get update
sudo apt-get install python3-openstackclient
sudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient
+

Configure your cloud access in ~/.config/openstack/clouds.yaml

+
clouds:
CLOUDNAME:
interface: public
identity-api-version: 3
#region_name: REGION
auth:
auth_url: KEYSTONE_ENDPOINT
project_id: PROJECT_UUID
#alternatively project_name and project_domain_name
user_domain_name: default
# change to your real domain
+

and secure.yaml (in the same directory)

+
clouds:
CLOUDNAME:
auth:
username: USERNAME
password: PASSWORD
+

The CLOUDNAME can be freely chosen. This is the value passed to the openstack CLI with --os-cloud or exported to your environment in OS_CLOUD. The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample clouds.yaml file that works (but lacks the password).

+

Protect your secure.yaml from being read by others: chmod 0600 ~/.config/openstack/secure.yaml.

+

If you are using application credentials instead of username, password to authenticate, you don't need to specify project_id nor project's nor user's domain names in clouds.yaml. Just (in secure.yaml):

+
clouds:
CLOUDNAME:
auth_type: v3applicationcredential
auth:
application_credential_id: APPCRED_ID
application_credential_secret: "APPCRED_SECRET"
+

Configure this to be your default cloud:

+
export OS_CLOUD=CLOUDNAME
+

You might consider adding this to your ~/.bashrc for convenience. Being at it, you might want to add export CLIFF_FIT_WIDTH=1 there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste).

+

Verify that your openstack CLI works:

+
openstack catalog list
openstack server list
+

You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases.

+

Custom CA

+

If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in /etc/ssl/certs/ca-certificates.crt. You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the debian user.

+

Add it to your clouds.yaml

+
clouds:
CLOUDNAME:
cacert: /PATH/TO/CACERT.CRT
[...]
+

If you want to allow api_monitor.sh to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:

+
export OS_CACERT=/PATH/TO/CACERT.CRT
+

Consider adding this to your ~/.bashrc as well.

+

Your first api_monitor.sh iteration

+

Checkout openstack-health-monitor:

+
sudo apt-get install git bc jq netcat-traditional tmux zstd
git clone https://github.com/SovereignCloudStack/openstack-health-monitor
cd openstack-health-monitor
+

You may want to start a tmux (or screen) session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect.

+

The script api_monitor.sh is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the README.md file.

+

It is good practice to use tmux. This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to screen over tmux.

+

You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:

+
export IMG="Debian 12"
export JHIMG="Debian 12"
./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1
+

Leave out the -LL if you don't have a working loadbalancer service or replace -LL with -LO if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources).

+

Feel free to study the meaning of all the command line parameters by looking at the README.md. (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)

+

This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs DOWN, BUILD, creating are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual openstack RESOURCE list and openstack RESOURCE show NAME and RESOURCE being something like router, network, subnet, port, volume, server, floating ip, loadbalancer, loadbalancer pool, loadbalancer listener, security group, keypair, image, ...)

+

The api_monitor.sh uses and APIMonitor_TIMESTAMP prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong. +TIMESTAMP is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time).

+

This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least -N 2 to test the ability of the router to route traffic between networks. So expect -n 6 to become -N 2 -n 6 for a very small single-AZ cloud or -n 12 for a large 3 AZ cloud region. So, re-run the api_monitor.sh with the target sizing.

+

Resource impact and charging

+

Note that api_monitor.sh uses small flavors (SCS-1V-2 for the N jump hosts and SCS-1L-1 for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors.

+

If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run api_monitor.sh in a loop (which you will) with say 10 VMs (e.g. -N 2 -n 8) in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference.

+

Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of openstack volume list, openstack volume show BROKEN_VOLUME, openstack loadbalancer list, openstack loadbalancer show BROKEN_LB.)

+

Using -w -1 makes api_monitor.sh wait for interactive input whenever an error occurs; this can be convenient for debugging.

+

Once you have single iterations working nicely, we can proceed.

+

Automating startup and cleanup

+

Typically, we run api_monitor.sh with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here.

+
#!/bin/bash
# run_CLOUDNAME.sh
# Do some global settings
export IMG="Debian 12"
export JHIMG="Debian 12"
#export OS_CACERT=/home/debian/ca-certificates.pem
# Additional settings to override flavors or to
# configure email addresses for sending alarms can be set here

# Does openstack CLI work?
openstack server list >/dev/null || exit 1
# Upload log files to this swift container (which you need to create)
#export SWIFTCONTAINER=OS-HM-Logfiles

# CLEANUP
echo "Finding resources from previous runs to clean up ..."
# Find Floating IPs
FIPLIST=""
FIPS=$(openstack floating ip list -f value -c ID)
for fip in $FIPS; do
FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")
if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_
"; fi
done
FIPLIST=$(echo "$FIPLIST" | grep -v '^$' | sort -u)
# Cleanup previous interrupted runs
SERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)
KEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)
VOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)
NETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)
LOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)
ROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)
SECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)
echo CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS
for ENV in $FIPLIST; do
echo "******************************"
echo "CLEAN $ENV"
bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV
echo "******************************"
done
TOCLEAN=$(echo "$SERVERS
$KEYPAIR
$VOLUMES
$NETWORK
$LOADBAL
$ROUTERS
$SECGRPS
" | grep -v '^$' | sort -u)
for ENV in $TOCLEAN; do
echo "******************************"
echo "CLEAN $ENV"
bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV
echo "******************************"
done

# Now run the monitor
#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"
exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"
+

Compared to the previous run, we have explicitly set two networks here -N 2 and rely on the iterations being passed in as command line arguments. Add parameter -t if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (-LO) in this example rather than the amphora based one (-LL).

+

You may use one of the existing run_XXXX.sh scripts as example. Beware: eMail alerting with ALARM_EMAIL_ADDRESS and NOTE_EMAIL_ADDRESS (and limiting with -a and -R ) and reporting data to telegraf (option -S) may be present in the samples. Make this script executable (chmod +x run_CLOUDNAME.sh).

+

We wrap a loop around this in run_in_loop.sh:

+
#!/bin/bash
# run_in_loop.sh
rm stop-os-hm 2>/dev/null
while true; do
./run_CLOUDNAME.sh -i 200
if test -e stop-os-hm; then break; fi
echo -n "Hit ^C to abort ..."
sleep 15; echo
done
+

Also make this executable (chmod +x run_in_loop.sh). +To run this automatically in a tmux window whenever the system starts, we follow the steps in the startup README.md

+

Change OS_CLOUD in startup/run-apimon-in-tmux.sh. (If you need to set OS_CACERT, also add it in this file and pass it into the windows.)

+

Activate everything:

+
mkdir -p ~/.config/systemd/user/
cp -p startup/apimon.service ~/.config/systemd/user/
systemctl --user enable apimon
systemctl --user start apimon
sudo loginctl enable-linger debian
tmux attach -t oshealthmon
+

This assumes that you are using the user debian for this monitoring and have checked out the repository at ~/openstack-health-monitor/. Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)

+

Changing parameters and restarting

+

If you want to change the parameters passed to api_monitor.sh, you best do this by editing run_CLOUDNAME.sh, potentially after testing it with one iteration before.

+

To make the change effective, you can wait until the current 200 iterations are completed and the run_in_loop.sh calls run_CLOUDNAME.sh again. You can also hit ^C in the tmux window that hasapi_monitor.sh running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ^C during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ^C twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ./run_in_loop.sh again.

+

You can also issue the systemctl --user stop apimon command; it will basically do the same thing: Send ^C and then wait for everything to be completed and tear down the tmux session. +After waiting for that to complete, you can start it again with systemctl --user start apimon.

+

Multiple instances

+

You can run multiple instances of api_monitor.sh on the same driver VM. In this case, you should rename run_in_loop.sh to e.g. run_in_loop_CLOUDNAME1.sh and call run_CLOUDNAME1.sh from there. Don't forget to adjust startup/run-apimon-in-tmux.sh and startup/kill-apimon-in-tmux.sh to start more windows.

+

It is not recommended to run multiple instances against the same OpenStack project however. While the api_monitor.sh script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the run_CLOUDNAME.sh script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations.

+

Alarming and Logs

+

eMail

+

If wanted, the api_monitor.sh can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the -a N and -R options. In order to enable sending emails from the driver VM, it needs to have postfix (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly.

+

Once you have configured postfix, you can enable eMail notifications using the option -e. Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ALARM_EMAIL_ADDRESSES and NOTE_EMAIL_ADDRESSES environment variables to api_monitor.sh, e.g. by setting it in the run_CLOUDNAME.sh.

+

Log files

+

api_monitor.sh writes a log file with the name APIMonitor_TIMESTAMP.log. It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (TIMESTAMP is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)

+

Note that api_monitor.sh does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties.

+

The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable SWIFTCONTAINER has been set (in run_COULDNAME.sh) when starting api_monitor.sh. the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER

+

After the 200 iterations, a .psv file (pipe-separated values) is created Stats.STARTTIME-ENDTIME.psv (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured).

+

Data collection and dashboard

+

See https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md

+

Telegraf

+

To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:

+
sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key
echo "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list
sudo apt update
sudo apt -y install telegraf
+

In the config file /etc/telegraf/telegraf.conf, we enable

+
[[inputs.influxdb_listener]]
service_address = ":8186"

[[outputs.influxdb]]
urls = ["http://127.0.0.1:8086"]
+

and restart the service (sudo systemctl restart telegraf). +Enable it on system startup: sudo systemctl enable telegraf.

+

InfluxDB

+

We proceed to influxdb:

+
sudo apt-get install influxdb
+

In the configuration file /etc/influxdb/influxdb.conf, ensure that the http interface on port 8086 is enabled.

+
[http]
enabled = true
bind-address = ":8086"
+

Restart influxdb as needed with sudo systemctl restart influxdb. +Also enable it on system startup: sudo systemctl enable influxdb.

+

Add -S CLOUDNAME to your run_CLOUDNAME.sh script

+

You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter -S CLOUDNAME to the api_monitor.sh call in run_CLOUDNAME.sh. Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete).

+

Caddy (Reverse Proxy)

+

We're going to deploy Grafana behind Caddy as a reverse proxy. +Caddy is very easy to configure, comes with sensible defaults and can automatically provision TLS +certificates using Let's Encrypt.

+

Install Caddy

+

We follow https://caddyserver.com/docs/install#debian-ubuntu-raspbian to setup the stable APT repository:

+
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
+

And install Caddy:

+
sudo apt update
sudo apt install caddy
+

Ensure it's started and starts at boot with sudo systemctl enable --now caddy.

+

Allow HTTP traffic for oshm-driver

+

Caddy needs TCP port 80 opened to be able to process the Let's Encrypt HTTP challenge, so let's +configure an appropriate security group for oshm-driver:

+
openstack security group create http
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 80 http
openstack server add security group oshm-driver http
+

Configure Caddy

+

Create a file /etc/caddy/Caddyfile with the following contents:

+
https://health.YOURCLOUD.osba.sovereignit.cloud:3000 {
reverse_proxy localhost:3003
}
+

Replace health.YOURCLOUD.osba.sovereignit.cloud with your actual domain. +You can use a hostname of your liking, but Caddy will create TLS certificates for this host using +the HTTP challenge. +The sovereignit.cloud domain is controlled by the SCS project team and has been used for a number +of health mon instances.

+

Reload Caddy with sudo systemctl reload caddy. That's it.

+

You should now be able to access https://health.YOURCLOUD.sovereignit.cloud:3000 and see a proxy error +page because the Grafana service is not yet running (this is our next step). +The very first request will be a bit slower, because Caddy interacts with Let's Encrypt API to create +the TLS certificate behind the scenes.

+

Caddy logs can be accessed with sudo journalctl -u caddy.

+

Grafana

+

Install Grafana

+

We follow https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/ and setup the stable APT repository:

+
mkdir -p /etc/apt/keyrings
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
+

And install it:

+
sudo apt update
sudo apt -y install grafana
+

Basic config

+

The config file /etc/grafana/grafana.ini needs some adjustments.

+

We're going to deploy Grafana behind a reverse proxy (Caddy) and configure it as such.

+

Therefore, in the [server] section:

+
[server]
protocol = http
http_addr = 127.0.0.1
http_port = 3003
domain = health.YOURCLOUD.sovereignit.cloud
root_url = https://%(domain)s:3000/
+

Please replace health.YOURCLOUD.sovereignit.cloud with your actual domain.

+

Next, in the [security] section, set:

+
[security]
admin_user = admin
admin_password = SOME_SECRET_PASS
secret_key = SOME_SECRET_KEY
data_source_proxy_whitelist = localhost:8088 localhost:8086
cookie_secure = true
+

Please replace SOME_SECRET_PASS and SOME_SECRET_KEY with secure passwords (for example, you can use pwgen -s 20).

+

Finally, in the [users] section, set:

+
[users]
allow_sign_up = false
allow_org_create = false
+

The configuration file contains secrets and should be protected such that only root and group grafana +can read it:

+
sudo chown root:grafana /etc/grafana/grafana.ini
sudo chmod 0640 /etc/grafana/grafana.ini
+

We do the OIDC connection in the section [auth.github] later.

+

We can now restart the service: sudo systemctl restart grafana-server. +Being at it, also enable it on system startup: sudo systemctl enable grafana-server.

+

You should now be able to access your dashboard on https://health.YOURCLOUD.sovereignit.cloud:3000 and log in +via the configured username admin and your SOME_SECRET_PASS password.

+

Enable influx database in grafana

+

In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to http://localhost:8086 (despite this being the suggestion). Set the database name to telegraf. Save&test should succeed.

+

Importing the dashboard

+

Go to Home, Dashboards, New, Import. +Upload the dashboard .json file from the repository, user the Grafana-10 variant if you use Grafana 10 or newer.

+

In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.) +Save.

+

Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable).

+

No data displayed?

+

Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.

+

One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved.

+

Dashboard features

+

Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended.

+

The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously.

+

You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term.

+

GitHub OIDC Integration

+

The SCS providers do allow all GitHub users that belong to the SovereignCloudStack organization to get Viewer +access to the dashboards. +This allows to exchange experience and to get a feeling for the achievable stability. +(Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)

+

OIDC integration is achieved by adjusting the [auth.github] section in /etc/grafana/grafana.ini as follows:

+
[auth.github]
enabled = true
client_id = YOUR_CLIENT_ID
client_secret = YOUR_CLIENT_SECRET
allowed_organizations = ["SovereignCloudStack"]
role_attribute_path = "'Viewer'"
allow_assign_grafana_admin = false
skip_org_role_sync = true
+

This config maps all users to the Viewer role regardless of their role in the GitHub Org. +Please replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with the OAuth2 credentials that the SCS Org GitHub admins +provided to you. +Finally, don't forgot to restart Grafana with sudo systemctl restart grafana-server after adjusting the config.

+

More information can be found in the Grafana documentation for GitHub OAuth2.

+

Maintenance

+

The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained.

+

Unattended upgrades

+

It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See https://wiki.debian.org/UnattendedUpgrades. If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and Caddy/Grafana (port 3000).

+

If you use unattended-upgrades, you should review your settings in /etc/apt/apt.conf.d/50unattended-upgrades, +especially Unattended-Upgrade::Origins-Pattern. It controls which packages are upgraded. If you want Caddy to be +part of the automated updates, add an entry like the following:

+
Unattended-Upgrade::Origins-Pattern {
// ...
"origin=cloudsmith/caddy/stable";
};
+

(This corresponds to o=cloudsmith/caddy/stable in the output of apt-cache policy).

+

sshd setup

+

If you already use SSH keys to sign in to the driver VM, consider setting the following in your /etc/ssh/sshd_config +if not already set:

+
PasswordAuthentication no
+

Debian's openssh-server, by default, is also very open about its version, so you might consider disabling this via:

+
DebianBanner no
+

Updating openstack-health-monitor

+

You can just do a git update in the openstack-health-monitor directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ^C, see above in the restart section.

+

Backup

+

The system holds two things that you might consider valuable for long-term storage: +(1) The log files. These are compressed and uploaded to object storage if you enable the SWIFTCONTAINER setting, which probably means that these do not need any additional backing up then. +(2) The influx time series data. Back up the data in /var/lib/influxdb.

+

Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, clouds.yaml, etc. Be careful not to expose sensitive data by granting too generous access to your backed up files.

+

Troubleshooting

+

Debugging issues

+

In case there is trouble with your cloud, the normal course of action to analyze is as follows:

+
    +
  • Look at the dashboard (see above)
  • +
  • Connect to the driver VM and attach to the tmux session and look at the console output of api_monitor.sh
  • +
  • Analyze the logfile (locally on the driver VM or grab it from the object storage)
  • +
+

Analyzing failures

+

When VM instances are created successfully, but then end up in ERROR state, the api_monitor.sh does an explicit openstack server show, so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files.

+

Sometimes the VMs end up being ACTIVE as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail.

+

To gather more details, you can look at the console output openstack console log show VM (where VM is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ssh -i APIMonitor_XXXXX_JH.pem debian@FIP, whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP. Replace XXXXX with the number in your current APIMonitor prefix, FIP with the floating IP address of the responsible JumpHost and debian with the user name used by the images you boot. Use 223 to connect to the second VM in the network, 224 the third etc.

+

When logged in, look at /var/log/cloud-init-output.log and /var/log/cloud-init.log. You can find the metadata in /var/lib/cloud/instance/.

+

You will not have much time to look around -- the still running api_monitor.sh script does continue and clean things up again. So you might want to suspend it with ^Z (and continue it later with fg). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the run_CLOUDNAME.sh script as it would do cleanup against the running instance, but rather copy the api_monitor.sh command line from the bottom (without the exec), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach -w -1 to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work.

+

Cleaning things up

+

If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard).

+

There are a few things that may need support from a cloud admin:

+
    +
  • Volumes may end up permanently in a deleting or reserved state or may be in-use, attached to a VM that has long gone. The admin needs to set the state to error and then delete them.
  • +
  • Loadbalancers may end up in a PENDING_XXX state (XXX being CREATE, UPDATE or DELETE) without ever changing. This also needs the cloud admin to set the status to ERROR, so it can be cleaned up. amphorae are more prone to this than ovn LBs.
  • +
+

More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted.

+ + \ No newline at end of file diff --git a/docs/operating-scs/incident-management/index.html b/docs/operating-scs/incident-management/index.html new file mode 100644 index 0000000000..ed7ae1d325 --- /dev/null +++ b/docs/operating-scs/incident-management/index.html @@ -0,0 +1,25 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/lifecycle-management/index.html b/docs/operating-scs/lifecycle-management/index.html new file mode 100644 index 0000000000..63eff28813 --- /dev/null +++ b/docs/operating-scs/lifecycle-management/index.html @@ -0,0 +1,25 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/logging/index.html b/docs/operating-scs/logging/index.html new file mode 100644 index 0000000000..cc945bbebe --- /dev/null +++ b/docs/operating-scs/logging/index.html @@ -0,0 +1,25 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/metering/meter_configuration/index.html b/docs/operating-scs/metering/meter_configuration/index.html new file mode 100644 index 0000000000..fdeca5caea --- /dev/null +++ b/docs/operating-scs/metering/meter_configuration/index.html @@ -0,0 +1,44 @@ + + + + + +Metering Configuration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Metering Configuration

The Metrics and events we want to use in the metering process can be defined in two ways. The first one is to allow ceilometer to poll distinct metrics and events. +This can be achived by setting up ceilometers config files.

+

1. ceilometer metering configuration

+

there is the polling.yaml file that describes what metrics to poll and when. It allows to create multiple sources for the ceilometer pipeline with different metrics and intervals.

+

ceilometer polling +ceilometer polling metrics

+

1.1 polling.yaml

+
---
sources:
- name: billing_source # 'source name'
interval: 300 # 'how often the samples should be generated'
meters:
- "volume.size" # 'meter filter'
# - "*" # 'using all pollsters
+

in the event_definitions file all data structure of events are defined. If a message with a distinct event_type appears, the Fields and values from the message are matched with the Event-object.

+

ceilometer events +ceilometer event_definitions

+

1.2 event_definitions.yaml

+
---
- event_type: "compute.instance.*"
traits: &instance_traits
tenant_id:
fields: payload.tenant_id
user_id:
fields: payload.user_id
instance_id:
fields: payload.instance_id
display_name:
fields: payload.display_name
resource_id:
fields: payload.instance_id
cell_name:
fields: payload.cell_name
host:
fields: publisher_id.`split(., 1, 1)`
service:
fields: publisher_id.`split(., 0, -1)`
memory_mb:
type: int
fields: payload.memory_mb
disk_gb:
type: int
fields: payload.disk_gb
root_gb:
type: int
fields: payload.root_gb
ephemeral_gb:
type: int
fields: payload.ephemeral_gb
vcpus:
type: int
fields: payload.vcpus
instance_type_id:
fields: payload.instance_type_id
instance_type:
fields: payload.instance_type
state:
fields: payload.state
os_architecture:
fields: payload.image_meta.'org.openstack__1__architecture'
os_version:
fields: payload.image_meta.'org.openstack__1__os_version'
os_distro:
fields: payload.image_meta.'org.openstack__1__os_distro'
launched_at:
type: datetime
fields: payload.launched_at
deleted_at:
type: datetime
fields: payload.deleted_at
- event_type: compute.instance.create.end
traits:
<<: *instance_traits
availability_zone:
fields: payload.availability_zone
- event_type: compute.instance.update
traits:
<<: *instance_traits
old_state:
fields: payload.old_state
- event_type: compute.instance.exists
traits:
<<: *instance_traits
audit_period_beginning:
type: datetime
fields: payload.audit_period_beginning
audit_period_ending:
type: datetime
fields: payload.audit_period_ending
- event_type:
[
"volume.exists",
"volume.retype",
"volume.create.*",
"volume.delete.*",
"volume.resize.*",
"volume.attach.*",
"volume.detach.*",
"volume.update.*",
"snapshot.exists",
"snapshot.create.*",
"snapshot.delete.*",
"snapshot.update.*",
"volume.transfer.accept.end",
"snapshot.transfer.accept.end",
]
traits: &cinder_traits
user_id:
fields: payload.user_id
project_id:
fields: payload.tenant_id
availability_zone:
fields: payload.availability_zone
display_name:
fields: payload.display_name
replication_status:
fields: payload.replication_status
status:
fields: payload.status
created_at:
type: datetime
fields: payload.created_at
image_id:
fields: payload.glance_metadata[?key=image_id].value
instance_id:
fields: payload.volume_attachment[0].server_id
- event_type:
[
"volume.transfer.*",
"volume.exists",
"volume.retype",
"volume.create.*",
"volume.delete.*",
"volume.resize.*",
"volume.attach.*",
"volume.detach.*",
"volume.update.*",
"snapshot.transfer.accept.end",
]
traits:
<<: *cinder_traits
resource_id:
fields: payload.volume_id
host:
fields: payload.host
size:
type: int
fields: payload.size
type:
fields: payload.volume_type
replication_status:
fields: payload.replication_status
- event_type: ["snapshot.transfer.accept.end"]
traits:
<<: *cinder_traits
resource_id:
fields: payload.snapshot_id
project_id:
fields: payload.tenant_id
- event_type:
["share.create.*", "share.delete.*", "share.extend.*", "share.shrink.*"]
traits: &share_traits
share_id:
fields: payload.share_id
user_id:
fields: payload.user_id
project_id:
fields: payload.tenant_id
snapshot_id:
fields: payload.snapshot_id
availability_zone:
fields: payload.availability_zone
status:
fields: payload.status
created_at:
type: datetime
fields: payload.created_at
share_group_id:
fields: payload.share_group_id
size:
type: int
fields: payload.size
name:
fields: payload.name
proto:
fields: payload.proto
is_public:
fields: payload.is_public
description:
fields: payload.description
host:
fields: payload.host
- event_type:
[
"snapshot.exists",
"snapshot.create.*",
"snapshot.delete.*",
"snapshot.update.*",
]
traits:
<<: *cinder_traits
resource_id:
fields: payload.snapshot_id
volume_id:
fields: payload.volume_id
- event_type: ["image_volume_cache.*"]
traits:
image_id:
fields: payload.image_id
host:
fields: payload.host
- event_type: ["image.create", "image.update", "image.upload", "image.delete"]
traits: &glance_crud
project_id:
fields: payload.owner
resource_id:
fields: payload.id
name:
fields: payload.name
status:
fields: payload.status
created_at:
type: datetime
fields: payload.created_at
user_id:
fields: payload.owner
deleted_at:
type: datetime
fields: payload.deleted_at
size:
type: int
fields: payload.size
- event_type: image.send
traits: &glance_send
receiver_project:
fields: payload.receiver_tenant_id
receiver_user:
fields: payload.receiver_user_id
user_id:
fields: payload.owner_id
image_id:
fields: payload.image_id
destination_ip:
fields: payload.destination_ip
bytes_sent:
type: int
fields: payload.bytes_sent
- event_type: orchestration.stack.*
traits: &orchestration_crud
project_id:
fields: payload.tenant_id
user_id:
fields: ["ctxt.trustor_user_id", "ctxt.user_id"]
resource_id:
fields: payload.stack_identity
name:
fields: payload.name
- event_type: sahara.cluster.*
traits: &sahara_crud
project_id:
fields: payload.project_id
user_id:
fields: ctxt.user_id
resource_id:
fields: payload.cluster_id
name:
fields: payload.name
- event_type: sahara.cluster.health
traits: &sahara_health
<<: *sahara_crud
verification_id:
fields: payload.verification_id
health_check_status:
fields: payload.health_check_status
health_check_name:
fields: payload.health_check_name
health_check_description:
fields: payload.health_check_description
created_at:
type: datetime
fields: payload.created_at
updated_at:
type: datetime
fields: payload.updated_at
- event_type:
[
"identity.user.*",
"identity.project.*",
"identity.group.*",
"identity.role.*",
"identity.OS-TRUST:trust.*",
"identity.region.*",
"identity.service.*",
"identity.endpoint.*",
"identity.policy.*",
]
traits: &identity_crud
resource_id:
fields: payload.resource_info
initiator_id:
fields: payload.initiator.id
project_id:
fields: payload.initiator.project_id
domain_id:
fields: payload.initiator.domain_id
- event_type: identity.role_assignment.*
traits: &identity_role_assignment
role:
fields: payload.role
group:
fields: payload.group
domain:
fields: payload.domain
user:
fields: payload.user
project:
fields: payload.project
- event_type: identity.authenticate
traits: &identity_authenticate
typeURI:
fields: payload.typeURI
id:
fields: payload.id
action:
fields: payload.action
eventType:
fields: payload.eventType
eventTime:
type: datetime
fields: payload.eventTime
outcome:
fields: payload.outcome
initiator_typeURI:
fields: payload.initiator.typeURI
initiator_id:
fields: payload.initiator.id
initiator_name:
fields: payload.initiator.name
initiator_host_agent:
fields: payload.initiator.host.agent
initiator_host_addr:
fields: payload.initiator.host.address
target_typeURI:
fields: payload.target.typeURI
target_id:
fields: payload.target.id
observer_typeURI:
fields: payload.observer.typeURI
observer_id:
fields: payload.observer.id
- event_type: objectstore.http.request
traits: &objectstore_request
typeURI:
fields: payload.typeURI
id:
fields: payload.id
action:
fields: payload.action
eventType:
fields: payload.eventType
eventTime:
type: datetime
fields: payload.eventTime
outcome:
fields: payload.outcome
initiator_typeURI:
fields: payload.initiator.typeURI
initiator_id:
fields: payload.initiator.id
initiator_project_id:
fields: payload.initiator.project_id
target_typeURI:
fields: payload.target.typeURI
target_id:
fields: payload.target.id
target_action:
fields: payload.target.action
target_metadata_path:
fields: payload.target.metadata.path
target_metadata_version:
fields: payload.target.metadata.version
target_metadata_container:
fields: payload.target.metadata.container
target_metadata_object:
fields: payload.target.metadata.object
observer_id:
fields: payload.observer.id
- event_type:
[
"network.*",
"subnet.*",
"port.*",
"router.*",
"floatingip.*",
"firewall.*",
"firewall_policy.*",
"firewall_rule.*",
"vpnservice.*",
"ipsecpolicy.*",
"ikepolicy.*",
"ipsec_site_connection.*",
]
traits: &network_traits
user_id:
fields: ctxt.user_id
project_id:
fields: ctxt.tenant_id
- event_type: network.*
traits:
<<: *network_traits
name:
fields: payload.network.name
resource_id:
fields: ["payload.network.id", "payload.id"]
- event_type: subnet.*
traits:
<<: *network_traits
name:
fields: payload.subnet.name
resource_id:
fields: ["payload.subnet.id", "payload.id"]
- event_type: port.*
traits:
<<: *network_traits
name:
fields: payload.port.name
resource_id:
fields: ["payload.port.id", "payload.id"]
- event_type: router.*
traits:
<<: *network_traits
name:
fields: payload.router.name
resource_id:
fields: ["payload.router.id", "payload.id"]
- event_type: floatingip.*
traits:
<<: *network_traits
resource_id:
fields: ["payload.floatingip.id", "payload.id"]
- event_type: firewall.*
traits:
<<: *network_traits
name:
fields: payload.firewall.name
resource_id:
fields: ["payload.firewall.id", "payload.id"]
- event_type: firewall_policy.*
traits:
<<: *network_traits
name:
fields: payload.firewall_policy.name
resource_id:
fields: ["payload.firewall_policy.id", "payload.id"]
- event_type: firewall_rule.*
traits:
<<: *network_traits
name:
fields: payload.firewall_rule.name
resource_id:
fields: ["payload.firewall_rule.id", "payload.id"]
- event_type: vpnservice.*
traits:
<<: *network_traits
name:
fields: payload.vpnservice.name
resource_id:
fields: ["payload.vpnservice.id", "payload.id"]
- event_type: ipsecpolicy.*
traits:
<<: *network_traits
name:
fields: payload.ipsecpolicy.name
resource_id:
fields: ["payload.ipsecpolicy.id", "payload.id"]
- event_type: ikepolicy.*
traits:
<<: *network_traits
name:
fields: payload.ikepolicy.name
resource_id:
fields: ["payload.ikepolicy.id", "payload.id"]
- event_type: ipsec_site_connection.*
traits:
<<: *network_traits
resource_id:
fields: ["payload.ipsec_site_connection.id", "payload.id"]
- event_type: "*http.*"
traits: &http_audit
project_id:
fields: payload.initiator.project_id
user_id:
fields: payload.initiator.id
typeURI:
fields: payload.typeURI
eventType:
fields: payload.eventType
action:
fields: payload.action
outcome:
fields: payload.outcome
id:
fields: payload.id
eventTime:
type: datetime
fields: payload.eventTime
requestPath:
fields: payload.requestPath
observer_id:
fields: payload.observer.id
target_id:
fields: payload.target.id
target_typeURI:
fields: payload.target.typeURI
target_name:
fields: payload.target.name
initiator_typeURI:
fields: payload.initiator.typeURI
initiator_id:
fields: payload.initiator.id
initiator_name:
fields: payload.initiator.name
initiator_host_address:
fields: payload.initiator.host.address
- event_type: "*http.response"
traits:
<<: *http_audit
reason_code:
fields: payload.reason.reasonCode
- event_type: ["dns.domain.create", "dns.domain.update", "dns.domain.delete"]
traits: &dns_domain_traits
status:
fields: payload.status
retry:
fields: payload.retry
description:
fields: payload.description
expire:
fields: payload.expire
email:
fields: payload.email
ttl:
fields: payload.ttl
action:
fields: payload.action
name:
fields: payload.name
resource_id:
fields: payload.id
created_at:
type: datetime
fields: payload.created_at
updated_at:
type: datetime
fields: payload.updated_at
version:
fields: payload.version
parent_domain_id:
fields: parent_domain_id
serial:
fields: payload.serial
- event_type: dns.domain.exists
traits:
<<: *dns_domain_traits
audit_period_beginning:
type: datetime
fields: payload.audit_period_beginning
audit_period_ending:
type: datetime
fields: payload.audit_period_ending
- event_type: trove.*
traits: &trove_base_traits
instance_type:
fields: payload.instance_type
user_id:
fields: payload.user_id
resource_id:
fields: payload.instance_id
instance_type_id:
fields: payload.instance_type_id
launched_at:
type: datetime
fields: payload.launched_at
instance_name:
fields: payload.instance_name
state:
fields: payload.state
nova_instance_id:
fields: payload.nova_instance_id
service_id:
fields: payload.service_id
created_at:
type: datetime
fields: payload.created_at
region:
fields: payload.region
- event_type:
[
"trove.instance.create",
"trove.instance.modify_volume",
"trove.instance.modify_flavor",
"trove.instance.delete",
]
traits: &trove_common_traits
name:
fields: payload.name
availability_zone:
fields: payload.availability_zone
instance_size:
type: int
fields: payload.instance_size
volume_size:
type: int
fields: payload.volume_size
nova_volume_id:
fields: payload.nova_volume_id
- event_type: trove.instance.create
traits:
<<: [*trove_base_traits, *trove_common_traits]
- event_type: trove.instance.modify_volume
traits:
<<: [*trove_base_traits, *trove_common_traits]
old_volume_size:
type: int
fields: payload.old_volume_size
modify_at:
type: datetime
fields: payload.modify_at
- event_type: trove.instance.modify_flavor
traits:
<<: [*trove_base_traits, *trove_common_traits]
old_instance_size:
type: int
fields: payload.old_instance_size
modify_at:
type: datetime
fields: payload.modify_at
- event_type: trove.instance.delete
traits:
<<: [*trove_base_traits, *trove_common_traits]
deleted_at:
type: datetime
fields: payload.deleted_at
- event_type: trove.instance.exists
traits:
<<: *trove_base_traits
display_name:
fields: payload.display_name
audit_period_beginning:
type: datetime
fields: payload.audit_period_beginning
audit_period_ending:
type: datetime
fields: payload.audit_period_ending
- event_type: profiler.*
traits:
project:
fields: payload.project
service:
fields: payload.service
name:
fields: payload.name
base_id:
fields: payload.base_id
trace_id:
fields: payload.trace_id
parent_id:
fields: payload.parent_id
timestamp:
type: datetime
fields: payload.timestamp
host:
fields: payload.info.host
path:
fields: payload.info.request.path
query:
fields: payload.info.request.query
method:
fields: payload.info.request.method
scheme:
fields: payload.info.request.scheme
db.statement:
fields: payload.info.db.statement
db.params:
fields: payload.info.db.params
- event_type: "magnum.cluster.*"
traits: &magnum_cluster_crud
id:
fields: payload.id
typeURI:
fields: payload.typeURI
eventType:
fields: payload.eventType
eventTime:
type: datetime
fields: payload.eventTime
action:
fields: payload.action
outcome:
fields: payload.outcome
initiator_id:
fields: payload.initiator.id
initiator_typeURI:
fields: payload.initiator.typeURI
initiator_name:
fields: payload.initiator.name
initiator_host_agent:
fields: payload.initiator.host.agent
initiator_host_address:
fields: payload.initiator.host.address
target_id:
fields: payload.target.id
target_typeURI:
fields: payload.target.typeURI
observer_id:
fields: payload.observer.id
observer_typeURI:
fields: payload.observer.typeURI
- event_type: "alarm.*"
traits:
id:
fields: payload.alarm_id
user_id:
fields: payload.user_id
project_id:
fields: payload.project_id
on_behalf_of:
fields: payload.on_behalf_of
severity:
fields: payload.severity
detail:
fields: payload.detail
type:
fields: payload.type
+

The event_pipeline can be used to filter events and pipeline them to different publishers. +the notifier publisher is the message queue broadcasster (RabbitMQ).

+

1.3 event_pipeline.yaml

+
---
sources:
- name: event_source # 'source name'
events:
- "*" # 'event filter'
sinks:
- event_sink # 'sink name'
sinks:
- name: event_sink # 'sink name'
publishers: # 'list of publishers'
- notifier://
- http://localhost:8088/post_json
+

The pipeline.yaml can be used to filter and pipeline all metrics and events since events send via the notifier also appears in the meters and send them to different publishers.

+

In our case we want to push to the metering api.

+

1.4 pipeline.yaml

+
---
sources:
- name: meter_source
meters:
- "*"
sinks:
- meter_sink
sinks:
- name: meter_sink
publishers:
- gnocchi://?archive_policy=ceilometer-low&filter_project=service
- http://localhost:8088/post_json
+ + \ No newline at end of file diff --git a/docs/operating-scs/monitoring/index.html b/docs/operating-scs/monitoring/index.html new file mode 100644 index 0000000000..8f87e33265 --- /dev/null +++ b/docs/operating-scs/monitoring/index.html @@ -0,0 +1,25 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/overview/index.html b/docs/operating-scs/overview/index.html new file mode 100644 index 0000000000..8951d37d4f --- /dev/null +++ b/docs/operating-scs/overview/index.html @@ -0,0 +1,25 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/releases/Release0/index.html b/docs/releases/Release0/index.html new file mode 100644 index 0000000000..b33ff00655 --- /dev/null +++ b/docs/releases/Release0/index.html @@ -0,0 +1,81 @@ + + + + + +Release Notes for SCS Release 0 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Release Notes for SCS Release 0

+

(Release Date: 2021-07-15)

+

Scope

+

The main focus of R0 is to demonstrate the viability of our approach to a much broader +audience by providing a well-documented testbed. This will allow anyone interested +to study the system in real-life, test, contribute, compare, ... it.

+

Also we learn performing the release process.

+

Features

+

Fully automated virtual (testbed setup) with ansible (terraform bootstrap to create +storage, networking and VM resources for bootstrapping via cloud-init injected +scripts that call ansible).)

+

The infrastructure, management and openstack services are all deployed in containers.

+

Included tools for Operations: ARA, Netbox, Cockpit, Netdata, Skydive (opt-in), +Patchman, phpMyAdmin, Elasticsearch (b/f license change), Kibana, Grafana, influxdb

+

Validation: Rally, Refstack

+

Infrastructure: Linux, KVM, ceph (pacific), OpenVSwitch, OVN, MariaDB, RabbitMQ, Redis, +Etcd, HAproxy, Keepalived, Memcached, Keycloak

+

IaaS (OpenStack - Wallaby): keystone, nova, glance, cinder, neutron, octavia, horizon

+

Optional OpenStack services: designate, heat, gnocchi, ceilometer, aodh, panko, senlin, +barbican, manila, magnum

+

See testbed SBOM for +a complete list. The exact versions of the contained components can be retrieved from the +release repo of OSISM.

+

Get SCS

+

See main README.

+

Known Bugs

+

Nothing major known yet.

+

Technical Previews

+

While already in productive use (on bare metal) by two providers, the bare metal +setup currently has a few more manual steps than we would like. This will improve +with the next releases.

+

We have worked hard on supporting identity federation (OIDC and SAML) during the last +few months. We have also spent significant effort on getting the k8s stack with +k8s cluster API into a good shape. However, we have determined that we do not +yet consider those two key pieces as production-ready. The goal is to change that +for R1 (see below).

+

For now, you can use the software to see where SCS is going and test our technical +preview code. We really appreciate feedback we get on these pieces as well. +However keep in mind that we do not guarantee to ship technical previews from +a Release as production-ready software in one of the next releases. We certainly +hope to do so.

+

To test how our k8s aaS platform will look like, have a look at the +k8s-cluster-api-provider repository +You can follow the documentation to set up the k8s cluster API on an SCS +cloud (or other well configured OpenStack clouds that support octavia).

+

The openstack-health-monitor +is used by us to monitor that the API works and successfully creates working resources +in finite time. We plan to integrate it with a dashboard and an alarming mechanism in +the next releases.

+

Release tagging

+

See Release Numbering scheme. +The containers have version number v1.0.0 for R0.

+

Updates

+

Updating the software can conveniently be done from the manager node by running the +ansible playbooks again. Details are in the +OSISM testbed documentation.

+

Bug reporting

+

See main README file.

+ + \ No newline at end of file diff --git a/docs/releases/Release1/index.html b/docs/releases/Release1/index.html new file mode 100644 index 0000000000..69d5ffa73f --- /dev/null +++ b/docs/releases/Release1/index.html @@ -0,0 +1,179 @@ + + + + + +Release Notes for SCS Release 1 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Release Notes for SCS Release 1

+

(Release Date: 2021-09-29)

+

Scope

+

Main goals for Release 1 (R1) was the strengthening of our CI test coverage and +integration, the operational tooling (metrics collection, dashboards, logging), +latest versions of upstream software (OpenStack Wallaby, Kubernetes-1.21.5), +support for Bare Metal service, progress on user federation for clouds, and +progress on the integration of the container layer with k8s Cluster API (now in +version 0.4.x).

+

CI framework

+

Zuul-CI

+

For our internal development workflows we are planning to switch from GitHub +Actions to Zuul-CI (mostly). The infrastructure itself is already available, +yet most of the repositories in the SovereignCloudStack organisation have not +switched over. Reasons for switching include cross-dependencies, scalability +and costs. Reasons for using Zuul-CI include the close connection to the +OpenStack project and the enormous flexibility in comparison to other similar +tools. On top of that you have also gating instead of only CI. A quick example +for a Zuul-CI operated repository can be found here: +https://github.com/SovereignCloudStack/zuul-sandbox.

+

Metrics collection and dashboards

+

Prometheus exporters and Grafana dashboards

+

We provide generic configuration examples and blueprints for prometheus rules +and grafana dashboards. The examples need to be understood and adapted to the +particular needs of your environment. You can find the examples at +https://github.com/osism/kolla-operations].

+

With R2 we plan to implement a basic set of these alerts and dashboards in the +testbed deployment in order to make them even easier consumable for new users. +Feel free to give feedback on the examples and contribute your own generic +examples.

+

We're working on bringing a basic set of prometheus exporters to the +OpenStack-kolla upstream community.

+

As part of our effort to add more monitoring tooling, we're integrating further +prometheus exporters such as +libvirt and +ovn. Integration is +targeted for R2.

+

More detailed information on monitoring topics will be continously provided in +the corresponding design document.

+

openstack-health-monitor

+

We have made some progress with openstack-health-monitor since R0, but we have +not yet created ready-to-be-used influx data collection and the grafana +dashboard. While the black box monitoring is perceived as very useful, the +script certainly has reached a complexity that is not handled well with bash +scripting and makes it a difficult to maintain and even to use tool, so the +usefulness of shipping it with SCS to make it available for Ops teams to +monitor has been questioned. Instead an expectation has been expressed that the +SCS uses this to monitor all SCS partner clouds and provides some transparency +this way to the public -- and detailed statistics via e.g. a prometheus +exporter to the respective cloud provider. This is currently under consideration.

+

Logging

+

Central logging

+

OSISM now enables kolla-ansible centralized logging by default. The default +rules need to be further refined to suit your needs. We plan to implement a +more generic set of rules for R2.

+

Federation

+

OIDC support via keycloak

+

Logging in to Horizon by authenticating with OIDC via Keycloak is now possible. +For details see the testbed documentation.

+

non-TLS restrictions (testbed)

+

Only TLS secured deployments get full support. +Without TLS, certain browsers won't be able to log in. +For deatils see the testbed documentation

+

Known Issue with OIDC Logout

+

Clicking Sign Out on the Horizon dashboard doesn't perform +a proper OIDC logout. This is documented in osism testbed, +with some Keycloak settings that can be relevant for alleviating the issue, +but in Release 1 there is no solution for this yet.

+

Bare Metal Service

+

The ironic Bare Metal service can be deployed with the SCS (OSISM) +installation. For it to get full test coverage, a virtual BMC +solution has been created, so bare metal can be validated in our testbed +setup just as nicely as the other components. While most pieces +are ready, the final integration steps are still work-in-progress +and will happen after R1.

+

Container Layer

+

Overview and Goals for R1

+

The container layer on SCS is implemented as a Self-Service, +leveraging the Kubernetes cluster API +technology. This was provided as a technical preview from the +SCS k8s-cluster-api-provider +repository for R0 back in July.

+

The focus for R1 was to make it ready for production, so DevOps teams can +use this to create and manage their k8s clusters in self-service for +development, testing, deployment and production.

+

To achieve this, a lot of work has been invested, updating the +cluster API to 0.4 along the way, fixing snapshot classes, enabling +optional metrics and ingress services, using application credentials +and much improved management scripts. The sonobuoy test automation has +been included and successfully used to validate the created clusters. +Real-world testing has happened though the Gaia-X Hackathon #1, where +clusters were provided on the fly for the various work streams.

+

The detailed list of changes for R1 is covered in the +k8s capi provider Release Notes.

+

Still in technical preview, but very promising are the helm charts +based k8s cluster management templates also documented there.

+

Beyond CAPI

+

Some of our partners are using Gardener as a layer to manage +large fleets of (optionally cross-cloud) k8s clusters. While there is a bit of +overlap in functionality, they do happily coexist and our partner is actually +using k8s capi to bootstrap clusters on SCS clouds for Gardener management.

+

Standardization

+

As of this writing, the list of SCS defined standards still comprises +two standards:

+ +

As before, we continue to rely on OpenStack and CNCF defined standards +in addition to this -- the k8s clusters need to pass the conformance +tests with sonobuoy and the OpenStack environment the OpenStack powered +guidelines (with refstack).

+

There is a discussion on a glossary, detailing what we expect from regions, +availability zones etc. Some major parts of it still need to be agreed +before a useful doc can be published -- this will happen in due time and +is expected before R2.

+ +

We stand on the shoulders of giants: +Without all the great work from many open source communities, we would +not get anywhere.

+

We are working on automation to create a complete list for all the software +that is used and deployed with SCS, so we have a complete Software Bill +of Materials (SBoM). The reason this is non-trivial is that we are not +aggregating it all ourselves, but rely on pre-integrated pieces, such +as Linux distributions, OpenStack, CNCF projects etc. The good news is +that these projects are diligent in their work, making sure we don't need +to be too worried about security risks or legal risks introduced this way. +Nevertheless, the goal of creating a complete graph remains.

+

We have started to put SPDX license identifiers into the SCS produced +code, so we make it easier for downstream consumers of our software to +automate the license compliance checks when assembling an SBoM.

+

For R1, some of the major projects we build on have had releases that we +incorporated and whose release notes we want to link here for convenience:

+ +

Release tagging

+

See Release Numbering scheme -- unchanged from R0. +We have added the tag v2.0.0 to the relevant repositories to designate the SCS_RELEASE_R1.

+

List of known issues & restrictions in R1

+
+ + \ No newline at end of file diff --git a/docs/releases/Release2/index.html b/docs/releases/Release2/index.html new file mode 100644 index 0000000000..36412e327f --- /dev/null +++ b/docs/releases/Release2/index.html @@ -0,0 +1,236 @@ + + + + + +Release Notes for SCS Release 2 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Release Notes for SCS Release 2

+

(Release Date: 2022-03-23)

+

Scope

+

Main goals for Release 2 (R2) were massive improvements in bare +metal deployment and our cluster management layer gaining the +ability to handle many clusters independently with a number +of optional services.

+

Component Versions and User-visible improvements (highlights)

+
    +
  • +

    We support the latest Kubernetes 1.22 and +1.23 releases.

    +
  • +
  • +

    The Kubernetes Cluster API is now available in a stable v1beta1 +release 1.0.x +with the corresponding cluster-api-provider-openstack 0.5.x.

    +
  • +
  • +

    There are a number of new standard services available for the +k8s capi +managed clusters, amongst which cert-manager and flux. The clusters +have better default settings for the nginx-ingress, anti-affinity +for the nodes and the ability to chose cilium over calico and +to have stable multi-controller node setups on clouds without +low-latency local storage. +Please consult the +k8s capi provider release notes +for more details.

    +
  • +
  • +

    OpenStack Xena release

    +
      +
    • We have also enabled SPICE support in addition to noVNC to +access the graphical console of VMs.
    • +
    +
  • +
  • +

    The base infrastructure is provided by +OSISM 3.0.0 +which in turn build on top of kolla and kolla-ansible.

    +
  • +
+

New Features (Highlights)

+

Operator focused improvements

+
    +
  • +

    The Cluster Management Node is now well prepared to manage numerous +clusters with independent settings and different feature sets by +creating default settings and then keeping track of various workload +clusters in own directories. Documentation has been vastly improved.

    +
  • +
  • +

    The Cluster Management node now gets its artifacts directly from +git, making incremental updates to it a lot easier, thus also +avoiding to disrupt workload clusters through redeployed management +nodes to roll out updates.

    +
  • +
  • +

    Added dashboards for the operators:

    +
      +
    • Homer
    • +
    • Flower
    • +
    • Grafana dashboards
    • +
    +
  • +
  • +

    Work is underway to supersede openstack-health-monitor +with a solution that is using tempest and rally. The health-monitor +has received improvements though and is at this point still fully +supported and recommended -- it has surfaced a number of issues with +test clouds, especially failed metadata services.

    +
  • +
  • +

    User federation has been prepared to be ready for Gaia-X federation integration

    +
      +
    • Keystone can consume users from Keycloak via OpenID-Connect
    • +
    • Keycloak uses the highly-available Galera database cluster now
    • +
    • mod_oauth2 support for Keystone
    • +
    +
  • +
  • +

    Vast improvements in the SCS Deployment automation

    +
      +
    • Full automation of bare metal deployment with Bifrost and Ironic
    • +
    • Using NetBox as central source of truth for the complete setup
    • +
    +
  • +
  • +

    New services available (opt-in)

    +
      +
    • ClamAV, dnsdist, cgit, FRRouting, Nexus, Tang
    • +
    +
  • +
  • +

    Traefik centrally routes the connections to Nexus, NetBox, phpMyAdmin, Homer, Flower, ARA, cgit

    +
  • +
+

SCS Developer focused improvements (testbed)

+

We now have scripts that allow us to connect to the workload cluster node network +for debugging purposes.

+

The configuration of the testbed was minimized and the deployment was made more production-oriented.

+

Further noteworthy improvements to testbed:

+
    +
  • TLS is implemented throughout the services also in testbed
  • +
  • Virtual BMC in testbed
  • +
  • Public DNS for testbed (testbed.osism.xyz)
  • +
+

We have a Zuul CI framework running and started migrating CI testing from github actions to +using our Zuul infrastructure.

+

Renovate is being used to keep the pinned versions up-to-date and consistent across the +many repositories.

+

An overview over the used software versions is available from the +OSISM release repository as input +for a complete SBOM. This allows to e.g. investigate the contents of the +used (v3.0.0) images.

+

Upgrade/Migration notes

+

Cluster Management

+

The names of a few settings have changed since R1 -- if you have diverged from the defaults, +this may require adjusting the environment.tfvars or the clusterctl.yaml files. +See k8s-cluster-api-provider Release Notes +for more details.

+

The updating approach has fundamentally changed: +If you were used to deploy fresh management nodes regularly to +benefit from the upstream improvements, this need has been vastly reduced now, +allowing for long-living management nodes and workload clusters managed by them.

+

OSISM

+
    +
  • +

    Playbook generic-configuration.yml was deprecated. From now on, please use the playbook of +the same name in the manager environment (manager-configuration.yml). All configuration +parameters from environments/configuration.yml should be moved to environments/manager/configuration.yml.

    +
  • +
  • +

    In kolla-ansible the haproxy role was renamed to loadbalancer. Accordingly, loadbalancer must now be +used for the deployment of HAProxy.

    +
  • +
+

Removals

+
    +
  • OpenStack Victoria images are no longer built and thus no longer kept updated
  • +
  • Support for Zabbix has been removed, Prometheus will be used as the only monitoring stack in the future
  • +
  • Heimdall as a service was removed, as an alternative Homer is now available
  • +
+

Deprecations

+

Deprecations happen according to our deprecation policy.

+
    +
  • Cockpit is deprecated in favor of Boundary by HashiCorp or Teleport
  • +
  • ceph-ansible is deprecated in preparation for cephadm
  • +
  • All osism- scripts on the manager are deprecated and will be replaced by the new OSISM CLI. The scripts will be removed in the next release
  • +
  • The following services are currently not used and are deprecated and scheduled for removal as of now: Falco, Jenkins, Rundeck, Lynis, Trivy
  • +
  • Heat will no longer be offered by default in the testbed in the future
  • +
  • The docker-compose CLI will be removed and replaced by the new compose plugin for Docker. +docker-compose is then no longer available and docker compose must be used instead
  • +
+

Security Fixes

+
    +
  • The Elasticsearch container included in OSISM testbed was exposed to the log4j +issue -- new images were provided for addressing this. See the +security advisory
  • +
+

Resolved Issues

+
    +
  • +

    The nginx-ingress loadbalancer could run into name conflicts before. +The loadbalancer now uses a health monitor to avoid routing to the wrong +nodes, which typically resulted in 10s delays when connecting to the service +behind the ingress controller.

    +
  • +
  • +

    cAdvisor has now reduced number of Prometheus metrics and labels exported by +default - this will ease the load on the system. +This implies that corresponding time series data will no longer be created.

    +
  • +
+

Standards Conformance

+

The clusters created with our cluster-API cluster management solution pass +the CNCF conformance tests +as reported by sonobuoy.

+

The OpenStack layer passes the +OIF trademark tests, so cloud providers +leveraging the stack should easily be able to achieve the +"OpenStack powered compute" +trademark certification.

+

Our partner plusserver has achieved +a BSI C5 +security certification for their SCS implementation pluscloud open.

+

We are working within Gaia-X to further the power +of Gaia-X self-descriptions and are closely working with the +GXFS project +to jointly deliver a standard toolbox for Gaia-X compliant +infrastructure and service offerings.

+

The SCS standards for flavor naming and +image metadata +are largely unchanged since R1. We have however +made progress in our reference implementation fully implementing +them without any further tweaks.

+

Release Tagging

+

See Release Numbering scheme -- unchanged from R0. +We have added the tag v3.0.0 to the relevant repositories to designate the SCS_RELEASE_R2.

+

Note that we will release R3 (v4.0.0) in September 2022 and stop providing maintenance +updates for R2 at the end of October.

+

List of known issues & restrictions in R2

+

Future directions (selected Highlights)

+

Alongside with R2 we published a blog post on some first thoughts on +future directions towards R3.

+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our contributor guide. +We also have worked on a Code of Conduct +to document the expected behavior of contributors and how we deal with +cases where individuals fail to meet the expectation.

+ + \ No newline at end of file diff --git a/docs/releases/Release3/index.html b/docs/releases/Release3/index.html new file mode 100644 index 0000000000..696d254ac8 --- /dev/null +++ b/docs/releases/Release3/index.html @@ -0,0 +1,206 @@ + + + + + +Release Notes for SCS Release 3 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Release Notes for SCS Release 3

+

(Release Date: 2022-09-21)

+

Scope

+

Main goals for Release 3 (R3) were user federation, increase in deployment and upgrade +velocity by improving automated test coverage as well as bringing disk encryption based on +tang from the state of a technical preview to be fully supported.

+

Component Versions and User-visible improvements (highlights)

+ +

New Features (Highlights)

+

Operator focused improvements

+
    +
  • +

    Work is underway to supersede openstack-health-monitor +with a comprehensive approach using scenarios with ansible playbooks +that has been developed and used by T-Systems for their Open Telekom Cloud. +Meanwhile, openstack-health-monitor has seen the addition of data +collection with telegraf and influxdb as well as a good dashboard +with grafana.

    +
  • +
  • +

    We have used our keystone to keycloak federation to use keycloak as identity +broker to federate identities from other (SCS) clouds' keycloaks. +This works well for the Web-Interface; we have still some work to do to also make it smooth +also for API/CLI usage. We have documented the current status

    +
  • +
  • +

    We believe that Gaia-X self-descriptions should also contain a description of +technical properties of services; higher-level services and workloads can than +declare their requirements and be matched against lower level services / platforms. +In good platforms, most (or all) technical properties are discoverable. In the +Gaia-X Hackathon #4, we have worked on a demonstrator that characterizes some +aspects of an OpenStack-based IaaS platform and which produces self-descriptions +that can be submitted to the Gaia-X trust service, pass the tests and you can +be awared a verifiable credential. Code is available in the +gx-self-description-generator repo

    +
  • +
+

SCS Developer focused improvements (testbed and k8s cluster management)

+
    +
  • +

    Following significant discussions on how to standardize our cluster management solution, +there is a draft concept as part of R3 now, which will be further worked on during +the R4 cycle. See Cluster standardization +section of the release notes from k8s-cluster-api-provider. +While our reference implementation uses the concepts and code from k8s cluster API on +top of our SCS reference implementation (OpenStack automated by OSISM), we want to +assure that non-OpenStack IaaS and solutions that diverge from cluster-API have the possibility +to be SCS compliant.

    +
  • +
  • +

    Workload clusters managed by our SCS cluster management solutions can now much +more easily receive k8s version upgrades, as the cluster-template no longer needs +to be touched for this. There is an Upgrade Guide available now.

    +
  • +
  • +

    LUKS encryption is now documented and enabled in the testbed by default.

    +
  • +
  • +

    Further noteworthy improvements to testbed:

    +
      +
    • Public DNS for testbed is now available (testbed.osism.xyz), allowing to access services +via TLS protected by a wildcard CA certificate.
    • +
    • The wireguard VPN service is deployed in the testbed by default.
    • +
    +
  • +
+

An overview over the used software versions is available from the +OSISM release repository as input +for a complete SBOM. This allows to e.g. investigate the contents of the +used (v4.0.0) images.

+

Upgrade/Migration notes

+

Cluster Management

+

Upgrade from R2 to R3 for cluster management and clusters: +See k8s-cluster-api-provider Release Notes +for more details. There is an Upgrade Guide written specifically to address the steps needed for upgrading +your cluster management and the workload clusters.

+

OSISM

+
    +
  • +

    In environments/kolla/secrets.yml the parameter neutron_ssh_key must be +added.

    +
    neutron_ssh_key:
    private_key:
    public_key:
    +

    The ssh key can be generated as follows: ssh-keygen -t rsa -b 4096 -N "" -f id_rsa.neutron -C "" -m PEM

    +
  • +
+

Removals

+
    +
  • The Cockpit service has been removed.
  • +
+

Deprecations

+

Deprecations happen according to our deprecation policy.

+
    +
  • Linux bridge support has been deprecated by the Neutron team and marked as experimental. +If Linux bridge is used in deployments, migrating to OpenVSwitch is recommended.
  • +
  • Debian dropped hddtemp (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1002484), +therefore the hddtemp service will be removed from the next OSISM release, as there is +no package available for Ubuntu 22.04.
  • +
  • Heat will no longer be offered by default in the testbed in the future
  • +
  • The following services are currently not used and are deprecated and scheduled for removal as of now: Falco, Jenkins, Rundeck, Lynis, Trivy
  • +
  • The docker-compose CLI will be removed and replaced by the new compose plugin for Docker. +docker-compose is then no longer available and docker compose must be used instead
  • +
  • The cleanup-elasticsearch playbook is deprecated. In the future, +the elasticsearch-curator service (part of Kolla) has to be used +for Elasticsearch cleanup.
  • +
  • All osism- scripts on the manager are deprecated and will be replaced by the new OSISM CLI. The scripts will be removed in the next release
  • +
+

Security Fixes

+

No severe security issues need to be highlighted since Release 2. However, by updating to the latest stable version of +the integrated open source components, we benefit from the upstream security fixes and thus recommend to upgrade all +SCS environments. Please note that Release 2 maintenance by the SCS project team will end by the end of October.

+

Resolved Issues

+
    +
  • Certificates in k8s clusters are subject to expiration - typically after one year. +We ensure these are renewed on control-plane upgrades, but operators may need manual attention +in case upgrades are not performed for extended periods of time. This is documented in +the k8s-cluster-api-provider's +Maintenance and Troubleshooting Guide.
  • +
+

Standards Conformance

+

The clusters created with our cluster-API cluster management solution pass +the CNCF conformance tests +as reported by sonobuoy.

+

The OpenStack layer passes the +OIF trademark tests, so cloud providers +leveraging the stack should easily be able to achieve the +"OpenStack powered compute" +trademark certification.

+

Our partner plusserver has achieved +a BSI C5 +security certification for their SCS implementation pluscloud open.

+

We are working within Gaia-X to further the power +of Gaia-X self-descriptions and are closely working with the +GXFS project +to jointly deliver a standard toolbox for Gaia-X compliant +infrastructure and service offerings.

+

The SCS standards for flavor naming and +image metadata +are largely unchanged since R1. We have however +made progress in our reference implementation fully implementing +them without any further tweaks. The +conformance test for the flavor naming +has seen minor improvements; a +conformance test for the image metadata +has been added.

+

Release Tagging

+

See Release Numbering scheme -- unchanged from R0. +We have added the tag v4.0.0 to the relevant repositories to designate the SCS_RELEASE_R3.

+

Note that we will release R4 (v5.0.0) in March 2023 and stop providing maintenance +updates for R3 at the end of April 2023.

+

List of known issues & restrictions in R3

+
    +
  • Distributed Virtual Routing (DVR) is not officially supported by OSISM, not tested and not recommended.
  • +
+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our How to contribute page.

+

Thanks

+

The work for R3 has been done by many contributors from our community. +We have not collected detailed stats that would split out the individual contributor's +and companies shares ... we may do so in the future. We are grateful to have such an +active and engaged community that has done so much work! Thanks to our contributors!

+

Of course we are leveraging a huge amount of open source technology that has been +created by our friends in other communities, many of which are part of the +CNCF, Linux Foudation, OIF, and others. We participate and contribute where +we can and definitely want to acknowledge the great work that we build upon.

+ + \ No newline at end of file diff --git a/docs/releases/Release4/index.html b/docs/releases/Release4/index.html new file mode 100644 index 0000000000..518babdcca --- /dev/null +++ b/docs/releases/Release4/index.html @@ -0,0 +1,146 @@ + + + + + +Release Notes for SCS Release 4 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Release Notes for SCS Release 4

+

(Release Date: 2023-03-22)

+

Scope

+

Release 4 has been developed alongside a set of associated outcomes. These outcomes are comprised of:

+
    +
  • SCS is standardized
  • +
  • SCS is federated
  • +
  • SCS is continuously built and tested
  • +
  • SCS is understandable
  • +
  • SCS enables Operators with an excellent toolbox
  • +
+

The SCS project is completely developed in the open, based on the principles of the four opens. Due to this a lot of our work can be tracked and used continuously without waiting for the half-year releases. Especially, but not limited to, this includes our efforts in regards to documentation and our standards.

+

One of the major highlights that happened in the R4 development cycle is our work on assuring SCS is understandable. +Be sure to look at our new documentation entry point. +We have created a systematic approach to structure documentation which already has been implemented for the OpenStack Image Manager, +the OSISM testbed and the K8s Cluster API Provider. More will follow in a continuous manner.

+

Our community has created a growing amount of blog articles which also help to understand the SCS project, its community and the technology that is worked on.

+

Component Versions and User-visible improvements (highlights)

+
    +
  • OpenStack Zed release
  • +
  • Ceph Quincy is available, the default release of Ceph is still Pacific.
  • +
  • The base infrastructure is provided by +OSISM 5.0.0 +which in turn builds on top of kolla and kolla-ansible.
  • +
  • With Cloud-in-a-Box there is an easy way to get SCS up and running on a single hardware node as a test environment. There are two blog posts (part 1 and part2) covering it.
  • +
  • For new deployments of the IaaS reference implementation Ubuntu 22.04 is recommended while existing installations can be upgraded to R4 while staying on Ubuntu 20.04. With Release 5, upgrading to Ubuntu 22.04 will be required.
  • +
  • With osism/node-image an iso image for much easier bootstrapping of new OSISM environments is available now
  • +
  • The software for our Kubernetes Cluster-API reference implementation has been updated and highlights are covered in own release notes.
  • +
+

New Features (Highlights)

+

Operator focused improvements

+
    +
  • The Openstack Image Manager has seen many improvements and is the reference command to assure the images available comply with the SCS Image Standard
  • +
  • For Ceph, special playbooks were added to validate the deployment status of the OSD, MON and MGR services in OSISM. The commands for use are osism validate ceph-osds, osism validate ceph-mons, and osism validate ceph-mgrs.
  • +
  • OVN has been updated to version 22.09.
  • +
  • OVS has been updated to version 3.0.1.
  • +
  • The testbed uses per default a proxy for container pulling. This will allow for airgapped installations out of the box. Please note: a full airgap support (with local mirrors, etc.) will follow in a future release.
  • +
  • The efforts to create a well-maintained status page with well-defined interfaces resulted in an OpenAPI specification (within its own repository) which is intended to be implementable by multiple implementations.
  • +
  • The dashboard of the OpenStack Health Monitor is in use by the SCS operators and has proven helpful a number of times in detecting and addressing issues. That said, it only received a few fixes and minor enhancements, as we plan to replace it with a more generic and more maintainable solution soon.
  • +
  • The k8s clusters built with our k8s-capi implementation now allow controlling the versions of more components; the latest tested and stable versions are used by default (if enabled). The latest version for the cilium CNI for example allows testing the upcoming k8s gateway API.
  • +
  • The k8s cluster now allows filtering access to the kubernetes API by IP ranges.
  • +
  • The k8s clusters now have the proxy protocol enabled with the nginx-ingress controller, so client IPs are visible; the previous issue that blocked internal access could be worked around.
  • +
+

SCS Developer focused improvements (testbed and k8s cluster management)

+
    +
  • The testbed has been significantly simplified for new operators and developers and a Quick Start guide has been added.
  • +
+

Upgrade/Migration notes

+
    +
  • For the IaaS reference implementation, please refer to the OSISM 5.0.0 Upgrade Notes.
  • +
  • The k8s Cluster Management solution has an enhanced upgrade guide that covers the upgrade of clusters as well as the upgrade of the cluster management server.
  • +
+

Removals

+
    +
  • The ospurge wrapper script has been removed from the osism.services.openstackclient role. The ospurge project is no longer compatible with the current OpenStack SDK. The command openstack project purge can be used as an alternative.
  • +
  • The docker-compose package is uninstalled by the osism.commons.docker_compose role. The Compose v2 plugin for Docker is now used instead of the old standalone docker-compose CLI. A dummy script has been added to /usr/local/bin which displays a corresponding message when using docker-compose.
  • +
  • Further removals from the IaaS reference implementation, please refer to the OSISM 5.0.0 Removals Section.
  • +
  • The k8s cluster parameter ETCD_PRIO_BOOST that was already unused has been removed as announced with R3.
  • +
+

Deprecations

+

Deprecations via OSISM

+

For these please also refer to the upstream deprecation notices

+
    +
  • The role osism.services.bird is deprecated. In future, FRRouting (osism.services.frr) will be used.
  • +
  • The role osism.services.minikube is deprecated. In future osism.services.k8s will be used.
  • +
  • Heat is deprecated in favor of more generic Infrastructure as Code tools like Terraform as of now and will be removed in the future (exact removal date is not yet known)
  • +
  • Swift (currently available as Technical Preview) will be removed in favor of Ceph RGW
  • +
  • Trove (currently available as Technical Preview) will be removed in favor of Kubernetes database operators
  • +
  • Skydive (currently available as Technical Preview) will be removed in the future, the project is not maintained anymore, last commit is 8th Jan 2022: https://review.opendev.org/c/openstack/kolla/+/869191
  • +
  • The login to a registry with the osism.services.docker role is deprecated in favor of the new osism.commons.docker_login role.
  • +
+

Security Fixes

+

Throughout the Release 4 development cycle, the SCS project issued two security advisories for upstream components:

+ +

Fixes were delivered via maintenance updates to existing R3 deployments, but of course also included in the main development branch that became R4.

+

Resolved Issues

+
    +
  • Breakage with old kustomize syntax has been addressed.(k8s-capi/#328)
  • +
  • The move of k8s container images from k8s.gcr.io to registry.k8s.io needed adjustments.(k8s-capi/#321)
  • +
+

Standards Conformance

+

The last months saw intense work in the standardization area. The process how standards are created has been documented. +The standards are collected in its own standards repository. +A machine readable file lists the required (and optional) standards that apply to "SCS-compatible" conformance at +the IaaS and the Container (KaaS) layer. The referenced executables are used by the compliance checking framework +to test existing implementations for compliance. To run the checker, the tester needs access to the infrastructure +under test (normal user privileges are sufficient) and standard openstack and kubernetes client tools -- or just +use the docker container that is provided.

+

The public clouds based on the SCS reference implementation from plusserver and Noris/Wavecon are tested automatically +from us and the live result is visible in standards page. +We will enhance the standardization and test coverage significantly in the next months and we hope to list a number +of more clouds there soon.

+

Release Tagging

+

The code in OSISM and a number of SCS repositories will receive the v5.0.0 tag; some repositories use +maintained/v5.0.x and maintained/v5.x branches for providing code that only gets bug- and security fixes (5.0.x) +or only those plus selected, backwards-compatible enhancements (5.x).

+

List of known issues & restrictions in R4

+
    +
  • The k8s cluster-API code does not work well with OpenStack API endpoints that require trusting a custom CA.
  • +
  • The OpenStack component Horizon has two issues when working with Swift endpoints. One issue is a known bug when uploading objects to Swift endpoints. A workaround will be released shortly after R4. The second issue is that existing Swift containers can not be set to public.
  • +
+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our How to contribute page.

+

Thanks

+

The work for R4 has been done by many contributors from our community. +The special thanks goes out to our contributors who participate in our community +on a very regular base - without these the various team calls and events like +the hackathons would be much less successful and fun.

+

Of course we are leveraging a huge amount of open source technology that has been +created by our friends in other communities, many of which are part of the +CNCF, Linux Foudation, OIF, and others. We participate and contribute where +we can and definitely want to acknowledge the great work that we build upon.

+ + \ No newline at end of file diff --git a/docs/releases/Release5/index.html b/docs/releases/Release5/index.html new file mode 100644 index 0000000000..ae598be2ac --- /dev/null +++ b/docs/releases/Release5/index.html @@ -0,0 +1,176 @@ + + + + + +Release Notes for SCS Release 5 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Release Notes for SCS Release 5

+

(Release Date: 2023-09-20)

+

Scope

+

Just as our previous release, Release 5 has been developed alongside a set of associated outcomes. +These outcomes are comprised of:

+
    +
  • SCS is standardized
  • +
  • SCS is understandable
  • +
  • SCS is transparent
  • +
  • SCS is continuously built and tested
  • +
  • SCS is opinionated
  • +
  • SCS enables
  • +
+

Component Versions and User-visible improvements (highlights)

+

IaaS

+
    +
  • The IaaS reference implementation is based on OSISM 6.0.0.
  • +
  • OpenStack 2023.1 (Antelope)
  • +
  • Default Ceph version is now Ceph Quincy.
  • +
  • OVN and OVS have been updated to their latest versions (OVN: 23.06.1, OVS: 3.2.0).
  • +
  • IPv6 east-west and north-south support is present and documented upstream.
  • +
  • Cloud-in-a-Box now comes with Swift enabled as well as the option +for secondary NIC for external connectivity.
  • +
+

Container Management

+
    +
  • The Kubernetes Cluster Management solution is available as version 6.0.0
  • +
  • Kubernetes v1.24 .. 1.27 are officially supported. v1.28 also works (technical preview until officially supported by capo) as do older versions (with downgrading nginx-ingress), matching OCCM and CSI versions.
  • +
  • Cluster-API (capi) v1.5.1, Cluster-API provider for Openstack (capo) v0.7.3
  • +
  • The node images now use Ubuntu 22.04, the management host can use Ubuntu 22.04 or Debian 12.
  • +
  • Cilium v1.14.1, default now, though Calico (3.26.x) is still supported.
  • +
  • Cilium also brings the upcoming gateway API (opt-in) as technical preview.
  • +
  • The Harbor container registry can now be rolled out with each cluster.
  • +
  • The clusters can use a registry as cache to upstream dockerhub or gcr registries.
  • +
  • The cluster management now works also on OpenStack clouds with a custom CA.
  • +
  • Storage snapshots are supported now (fix was also backported to maintained branches).
  • +
  • Diskless flavors are supported everywhere (cluster-management, health-monitor).
  • +
  • etcd defragmentation and backup.
  • +
  • Controls for pod and service IP ranges.
  • +
+

Preview: Cluster-Stacks

+

The old scripts that are used to create, change and delete Kubernetes clusters with +Cluster API will be replaced by a proper Operator in the next release. A description can be found at the +cluster-stacks +and cluster-stack-operator +repositories. The technical preview can be tried with the cluster-stacks-demo. +This solution will fit more nicely into the CNCF landscape and +also allow for easier support of IaaS solutions that do not comply to our SCS +IaaS standards.

+ +
    +
  • A number of improvements when using identity federation via OIDC has been added, including +addressing openstack CLI usage with PKCE Device Authz Grant, logout, and the usage of a +proxy realm in keycloak. Improvements have been contributed to upstream keystone.
  • +
  • With the openstack-resource-manager a new day 2 operations tool has been added. +Furthermore an osism role for tuned to optimize system profiles is now present.
  • +
  • The openstack-flavor-manager is now able to create all standard, mandatory SCS flavors for you.
  • +
  • Scaphandre Prometheus Exporter has been added to export power consumption metrics more easily.
  • +
  • To optimize system profiles an osism role for tuned is now present.
  • +
  • Full support for air-gapped installation and operation of environments.
  • +
  • A migration script and guide for moving from R4 to R5 clusters is available.
  • +
  • Metering has been improved and a reference billing API implementation is available as technical preview.
  • +
+

SCS Developer focused improvements (Cloud-in-a-Box, testbed and k8s cluster management)

+
    +
  • Documentation on testbed and Cloud-in-a-Box have been reworked.
  • +
  • Reflecting CiaB's usage as edge cloud appliance, it now receives more automated testing.
  • +
+

Project Infrastructure

+
    +
  • zuul.scs.community now complements OSISM's existing zuul infrastructure and is used also +by the container layer to execute the CNCF e2e tests.
  • +
  • registry.scs.community has been migrated to a new IaaS location (documented in a blog +article) and is kept up-to-date now.
  • +
+

Upgrade/Migration notes

+ +

Removals

+
    +
  • +

    Please check the removals for OSISM in the upstream removal notices.

    +
  • +
  • +

    The services minio.services.osism.tech and harbor.services.osism.tech are deprecated and will be turned of on October 20th, 2023.

    +
  • +
+

Deprecations

+

Deprecations via OSISM

+

For these please also refer to the upstream deprecation notices.

+
    +
  • +

    It is again noted that the old scripts of the form osism- will be removed in the future. +A note has been added to the scripts showing this when they are executed.

    +
  • +
  • +

    The following services are deprecated and will be removed with R6 (OSISM 6.1.0):

    +
      +
    • Patchman
    • +
    • Adminer
    • +
    • Patchman Client
    • +
    • Virtualbmc
    • +
    • Bird
    • +
    +
  • +
+

Security Fixes

+

Throughout the Release 5 development cycle, the SCS project issued two security advisories for upstream components:

+
    +
  • +

    In April 2023 an advisory in Open vSwitch (OvS) (CVE-2023-1668 was issued. +Our advisory.

    +
  • +
  • +

    In May 2023 an advisory affecting the OpenStack component Cinder (CVE-2023-2088) was issued. +Our advisory.

    +
  • +
+

Resolved Issues

+

Numerous minor issue have been resolved. The most important steps on the IaaS side probably being the move to ceph Quincy +to avoid running out of upstream support. On the container side, the fix of storage snapshots is probably most significant.

+

For details, we again refer to the OSISM and +k8s-cluster-api-provider release notes.

+

Standards Conformance

+

A new certification set is expected in December. It will ensure we +run all automated tests also for all new standards, such as +v3 flavor naming, +and the (previously included) v1 standard flavors -- which includes the new SSD flavors, the v1 entropy standard. We have also split image naming and standard image recommendations into v1 standards images.

+

Requirements for k8s version recency, default storage class as well as requirements to the container registry have been captured.

+

The IAM area has seen ADRs on the chosen architecture.

+

The (design) decisions on the metering work as well as on the status page project have also been +captured.

+

The standards and the standards compliance of our operators' clouds can be seen in the +standards section of our doc pages while the raw content is developed +and discussed in the respective github standards repository.

+

The SCS reference implementation follows all approved SCS standards.

+

Release Tagging

+

Relevant repositories have been tagged with v6.0.0 tag. +For some repositories maintained/v6.x and maintained/v6.0.x branches have been created.

+

List of known issues & restrictions in R5

+

Nothing that we are aware of at this point.

+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our How to contribute page.

+

Thanks

+

Our wonderful community of integrators, operators, contractors and volunteers +made R5 possible. The project management team is employed by the OSB Alliance +and we as well as the contractors are paid thanks to funding from the German +Ministry for economic affairs and climate action. We build on top of a lot of +existing open source code from the CNCF, the OIF and various others and we +try to contribute back as much as we can.

+ + \ No newline at end of file diff --git a/docs/releases/Release6/index.html b/docs/releases/Release6/index.html new file mode 100644 index 0000000000..ecbb91ebee --- /dev/null +++ b/docs/releases/Release6/index.html @@ -0,0 +1,278 @@ + + + + + +Release Notes for SCS Release 6 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Release Notes for SCS Release 6

+

SCS Release 6 has been published on 2024-03-20.

+

Scope

+

Just as our previous release, Release 6 has been developed alongside a set of associated outcomes. +Overall with Release 6 it becomes apparent that SCS is efficient to operate.

+
    +
  • SCS is standardized
  • +
  • SCS is understandable
  • +
  • SCS enables
  • +
  • SCS is transparent
  • +
  • SCS is continuously built and tested
  • +
  • SCS is opinionated
  • +
  • SCS charters new territory
  • +
+

Component Versions and User-visible improvements (highlights)

+

IaaS

+

The IaaS reference implementation is based on OSISM 7.0.0 +and delivers the following components:

+ +

KaaS

+

On the KaaS level, the development of the Cluster Stacks as KaaS V2 has reached a state where the approach is finally usable. With Cluster Stacks it is possible to bundle all components of Kubernetes clusters, i.e. node images, Kubernetes configuration, and cluster addons (core applications necessary to use a Kubernetes cluster) together and use the bundles to create and update clusters with one simple command.

+

One bundle, a Cluster Stack, can be tested extensively and is only released if both creating and upgrading clusters works smoothly. Users of these Cluster Stacks profit from the Cluster Stack Operator that works alongside with Cluster API to create and update ready-to-use clusters easily.

+
    +
  • k8s-cluster-api-provider (KaaS v1) +
      +
    • Moved to OpenTofu
    • +
    • Migrated to ClusterClass (last not least to ease the migration to Cluster Stacks)
    • +
    • HTTP_Proxy configurable
    • +
    • OVN LB
    • +
    +
  • +
  • Cluster Stacks (KaaS v2) + +
  • +
+

Operations

+

Observability

+

The Observability stack reference implementation is based on dNation Kubernetes monitoring stack v3.5.0 +and delivers the following components:

+ +

Zuul

+
    +
  • Created a development deployment for advancement testing.
  • +
  • Simplified the installation requirements.
  • +
  • Updated the Zuul repository's README file to include complete installation instructions for Terraform an Ansible.
  • +
  • Added the clouds data into the ansible vault.
  • +
  • Created an independent ansible Zuul role.
  • +
  • Moved the custom Zuul tasks from the playbook and incorporated them into the role.
  • +
  • Moved the custom Zuul variables from the playbook into the role's variables.
  • +
  • Included the installation of Letsencrypt which adds certificates as part of the installation.
  • +
  • Added a volume on the VM for the MariaDB instance to use for continuity.
  • +
  • Added volumes on the VM for Zookeeper to use for the data snapshots and datalog.
  • +
+

IAM

+ +

New Features (Highlights)

+

Operator focused improvements

+

A Kubernetes engine, via k3s, has been introduced to the control plane of the IaaS reference +implementation.

+

osism now deploys Keycloak to k3s via codecentric/keycloakx helm chart and CloudNativePG operator.

+

Rotation of the Octavia Amphora images has been added to the osism command. osism manage image octavia will rotate +the image, which is rebuilt on a daily basis.

+

OpenStack Health Monitor

+

A new monitoring stack will replace the old +openstack-health-monitor. +Nevertheless, it is currently still in heavy use and has thus seen a few improvements +responding to challenges observed in real-life clouds:

+
    +
  • A new installation guide
  • +
  • Robustness against leaking volumes even with overloaded cinder API
  • +
  • Robustness against leaking ports from OVN LB health-monitor
  • +
  • Robustness against leftover keypairs
  • +
  • Avoid some followup errors when VM creation failed
  • +
  • Add logic to startup os-health-mon in tmux windows via systemctl --user
  • +
+

SCS Developer focused improvements (testbed and k8s cluster management)

+

KaaS

+
    +
  • Every component of Cluster Stacks brings a Tilt environment for local test and development
  • +
  • With csctl Cluster Stacks assets can be created and tested locally without uploading to GitHub
  • +
+

Preview: Domain Manager Persona

+

A Domain Manager role has been established in a standard draft in SCS aiming to allow self-service capabilities for customers at the identity API. +Work is in progress to contribute this functionality to OpenStack Keystone and the corresponding upstream spec is currently under review. +The feature is expected to be available in the next SCS release.

+

Preview: Central API

+

To improve the experience of SCS cloud customers, the idea of a "Central API" was discussed. Such API should enable customers to manage various "as-a-Service" resources. For example: OpenStack instances as well as Kubernetes clusters as well as Keycloak OAuth2 clients. +Read about the trade-offs and ideas in the central-api repository and feel free to test out the POC.

+

Preview: Keycloak Home-IdP-discovery

+

To improve flexibility of onboarding new customer domains via IdP federation, SCS now deploys Keycloak with the Home-IdP-discovery plugin. The idea is, that Keystone federates out to a single Keycloak "proxy" realm (called osism in the testbed) and using the plugin, Keycloak can identify the user specific realm from an email-format login-ID. Operators can create dedicated realms for each customer and Keycloak uses internal federation to redirect from the "proxy" realm to the specific customer realm. In the customer ream they can configure IdP federation (OpenID-Connect or SAML) to their own IAM solution. The IAM section of the SCS documentation shall be extended to detail the configuration. SCS is working upstream to contribute required enhancements in the +mapping of users, groups and roles from OpenID-Connect token claims to the OpenStack Keystone access management.

+

Upgrade/Migration notes

+ +

Removals

+ +

Deprecations

+
    +
  • +

    KaaSv1 is still provided with R6, but we do not intend to include it in R7 again. +We want to rather focus on the feature completeness of the much more future-proof +cluster-stacks.

    +
  • +
  • +

    In upstream OSISM the role for deploying the Tang service (osism.services.tang) has been deprecated. +We would like to encourage active contributions in this area via the deprecation, since this piece of +code is currently not actively maintained nor -- to our knowledge -- actively used.

    +
  • +
+

Security Fixes

+

During the R6 development cycle a few security issues were reported and we issued security +advisories and addressed them via maintenance updates. All of these issues are also fixed +in the upcoming R6 release. These include:

+ +

Other security topics were covered in our community blog as well:

+ +

Security assessment for IaaS

+

We invested in a range of penetration tests of the IaaS layer which resulted in valuable insight in possible improvements (e.g. applying hardening measures):

+
    +
  • External pentesting of components (scanning, blackbox testing)
  • +
  • Internal pentesting of components with privileged and unprivileged system users (scanning from inside the cluster)
  • +
  • Scanning and pentesting the environment from a customer workload machine
  • +
+

The vision of SCS is to have continuous security assurance by adding security checks and pentesting tooling +to our CI pipelines; this is currently in implementation. Next step will then be to also cover other parts +(beyond the IaaS layer) of our stack with manual and then +automated penetration testing.

+

Resolved Issues

+

Preview: proper scope filtering for domain list API

+

A fix to a bug where listing domains via Keystone API would return domains not intended to be visible to the requesting entity was contributed and merged upstream. +The fix is expected to be available by the next SCS release.

+

Documentation

+

The docs page has come a long way in the last 6 months. +It pulls in a lot more content from the various projects and structures it in a much +more accessible way. Look at the standards pages +there to get an impression.

+

Highlighted blog posts

+ +

IAM

+

The documentation now contains an IAM overview document which explains current +limitations for the dynamic mapping of user roles and shall be extended to explain configuration options for Operators.

+

Standards Conformance

+

The standards have evolved, increasing the amount of guarantees that software developers +and operators have for workloads that work across SCS-compatible clouds. +The SCS-compatible IaaS-v4 +has seen improvements and better test coverage; the OSISM IaaS reference implementation +fulfills all of these standards in the default configuration.

+

For the Kubernetes layer, we have our first set of standards almost finalized. +Some of the standards for SCS-compatible KaaS-v1 +are unfortunately hard to test, so we are working on adding some more tests before +we cut it in stone. We aim for both KaaSv1 and v2 to fulfill the standards. +(Future standards will likely not be fulfilled by KaaSv1 as it's being deprecated.)

+

Release Tagging

+

A number of repositories follow OSISM's example and use the 7.0.0 or v7.0.0 tag +to denote SCS Release 6.

+

List of known issues & restrictions in R6

+

IaaS

+

Loadbalancer service (octavia)

+
    +
  • Creating loadbalancers in Cloud-in-a-Box installations fails with the +error message that the VIP subnet does not exist. OSISM #890
  • +
  • When using --provider ovn with a loadbalancer health-monitor, we leak ports ovn-lb-hm-$SUBNETID in all +but the VIP subnet, if we clean up the LB members before the health-monitor. This is tracked as +OSISM issue #921. Deleting the health-monitor before the +members or using openstack loadbalancer delete --cascade avoids this issue.
  • +
  • With amphora loadbalancers, we can end up in situations that LB deletion does no longer work due to +a failover or a failed creation of the vrrp port. This is tracked in +OSISM issue #925. An upstream fix exists and a backport +is already underway.
  • +
+

We expect to resolve these issues with a maintenance update.

+

KaaS

+

Some features of KaaS v1 are not available yet in KaaS v2 because they are WIP in upstream CAPO. +This includes the creation of some of the optional components such as e.g. the deployment +of ingress service, cert-manager, flux, harbor. More importantly, we do not yet have the +handling of restrictive security groups implemented nor the ability to avoid OpenStack +scheduling more than one control plane node on the same host (hypervisor).

+

For this reason, we are including KaaS v1 (k8s-cluster-api-provider) in the R6 release, +so existing users can upgrade to the latest upstream code and continuing using it as +a maintained solution while they evaluate the migration to KaaS v2 (cluster-stacks).

+

We will address most of the gaps during the next release cycle.

+

KaaS v1 should not be used for new deployments; we intend to remove it with the next +release (R7).

+

IAM

+

Since Keycloak is a Java application it requires importing certificates into its certificate store. +As the Keycloak pod in k3s now runs the service as non-root user, it gets more challenging to import +custom certificates from arbitrary customers for IdP federation. In case this topic is interesting for +specific deployments, the SCS project team would like to hear from users and discuss how to best +expose such a capability.

+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our How to contribute page.

+

Thanks

+

We have had considerable help from many partners and upstream projects during +the R6 development cycle. We continue to be grateful for the generous support +from providers that support with infrastructure that we can use for testing and +development. plusserver has been particularly generous and also helped us +finding a few issues during the pre-release phase by upgrading test +environments and testing them.

+ + \ No newline at end of file diff --git a/docs/releases/Release7/index.html b/docs/releases/Release7/index.html new file mode 100644 index 0000000000..f6d1c04b48 --- /dev/null +++ b/docs/releases/Release7/index.html @@ -0,0 +1,259 @@ + + + + + +Release Notes for SCS Release 7 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Release Notes for SCS Release 7

+

Release 7 has been published on September 11, 2024.

+

Scope

+

We had stated the goals of previous releases in terms of desired outcomes. For R7, we built on top of +R6 and continued in the same direction.

+

With R7 being the last release during the original funded SCS project, we put a lot of focus on finalizing +the work on many of the components. Major progress was achieved for example in the area of observability +(status page, new health monitor) and of course again in the cluster stacks, our Kubernetes as a Service +framework. Finalizing also means a lot of non-feature work, such as ensuring that tests exist and pass, +documentation, guides and blog articles are written and upstream contributions are done. An extra +focus was put on integrating the components well with each other and documenting the performance of a +complete SCS deployment better. One result of this is the +turnkey solution overview table, +another one the Technical Preview for our +Central API where we +demonstrate our vision of one API for all of the SCS stack in a usable form.

+

Component Versions and User-visible improvements (highlights)

+

IaaS

+

The IaaS reference implementation is based on OSISM 8.0.0 +and delivers the following components:

+ +

Throughout the R7 development cycle numerous, eight in total, minor releases of OSISM have been released. +One of the core ideas of SCS is to move towards a very incremental approach so that keeping infrastructure +up to date is made easy - as such many of the features and improvements that are now part of the Release 7 +have been shipped as part of one of the minor releases working towards Release 7.

+

KaaS

+

Cluster Stack SCS

+

SCS KaaS v2, better known as SCS Cluster Stacks are the new reference implementation for managing SCS compliant Kubernetes on SCS compliant infrastructure. +While we recommend to build Cluster Stacks for own purposes, the SCS projects provides preassembled Cluster Stacks to try out on OpenStack. These are simply called SCS and come with a number of configuration options, which can be found in the SCS Docs.

+

Host Cluster Stack release assets on an OCI registry

+

With the first versions of SCS Cluster Stacks the only way to host the release assets was GitHub Releases. This made cross-team testing harder and lead to an unusual amount of releases on specific GitHub repositories.
+With SCS R7 it will be possible to put publish the Cluster Stack release assets on an OCI registry.

+

Build node images with csctl for use in openstack

+

The csctl-plugin-openstack can now be used to build node images and upload them directly to Swift Object Store.

+

New Features (Highlights)

+

Operator focused improvements

+

IaaS

+
    +
  • The Prometheus node-exporter is now deployed on all nodes by default.
  • +
  • cAdvisor is now deployed on all nodes by default.
  • +
  • It is now possible to manage custom images with osism manage images.
  • +
  • It is now possible to manage custom flavors with osism manage flavors.
  • +
  • Various commands for disabling nodes, such as osism apply disable-compute-node have been added.
  • +
  • With the osism manage image octavia command it is possible to rotate the Octavia Amphora image, which is rebuilt daily.
  • +
  • With the osism manage image clusterapi command it is possible to import all currently stable Cluster API images
  • +
+

SCS Developer focused improvements (testbed and k8s cluster management)

+

Tech Preview: Central API

+

The idea of a central API for all API services in SCS was further evaluated, conceptualized and a PoC implemented. This implementation is now available as a Tech Preview for CSPs to deploy it at their own site.

+

Deploying the Central API is done into a dedicated Kubernetes cluster, which will then host the Crossplane operator for connections to backend systems.

+

End-customers will then be able to create Kubernetes resources in the api.scs.community group, for example a Cluster resource to create a new Kubernetes workload cluster.

+ +

Tech Preview: Automated pentesting for IaaS and KaaS

+

The security team has worked on a methodology for automated security scans that are specifically put together for SCS. This covers both the infrastructure-as-a-service layer and the Kubernetes container layer.

+

For IaaS, a pipeline of tools is executed, with each tool covering different aspects of security weaknesses and the anticipated attack surface of the layer.

+

For KaaS, the focus currently lies on the Trivy scanner, which can be deployed both as an ad-hoc scan and as a continuously running Operator in Kubernetes. This also includes a custom-made exporter for reports.

+

Since both layers produce vulnerability reports, which CSPs might want to delegate to their security teams, the deployment of DefectDojo is part of the Tech Preview.

+

For non-vulnerability reports, an export to S3/Swift was implemented and can be adjusted according to the CSP's needs.

+ +

Tech Preview: SCS Health Monitor

+

As announced in the Release Notes for R6, a new health monitor was in the works during the last months. With R7 we are now at the state of releasing the first Tech Preview of the new SCS Health Monitor. It not only covers the infrastructure-as-a-service layer, but also has workflows for Kubernetes tests.

+

While the SCSHM took many IaaS-related inspirations from the OSHM, the developer team for the new SCSHM has built an entirely new foundation for behavior-driven testing in SCS. The implementation is based on the Python behave framework, using the Gherkin language for test definitions. Using Python allows the tool to then use Python-native API clients for OpenStack and Kubernetes, with room for extension for many other tools in SCS as well.

+

During the test run, metrics and results are collected and exported via a Prometheus Push Gateway into a Grafana-based dashboard.

+ +

Status Page: 1.0 Full Release

+

The Status Page, formerly available as a tech preview, has now been feature-complete for its first full release as version 1.0.

+

The status page is the web frontend to our status API server, a record keeper of any incidents that may limit or break parts of your SCS infrastructure. While the tech preview version was limited to displaying this data, this full release contains not just improvements to the code working in the background, but also two new features:

+
    +
  • The new Maintenance Events are a type of incident that are set in the future and allow you to announce planned times of limited or non-existent service well in advance, right on the status page.
  • +
  • The Management Page provides a convenient interface to create and update incidents and maintenance events using a web UI, secured behind an authorization system using OpenID.
  • +
+

The status-page-deployment repository and its documentation contain full example and development setups. Check the Quickstart Guide to see what you need to run your own API server with status page or visit the SCS project's publicly hosted installation to get an impression.

+ +

Also see the Tech preview announcement post.

+

KaaS

+

Multi-Stage-Addons support in Cluster Stack Operator

+

The Multi-Stage-Addons mark a key feature of the Cluster Stacks approach. It enables the Cluster Stack Operator to upgrade clusters in predefined ways using Cluster API Lifecycle Hooks. Cluster upgrades can be painful, if e.g. new Kubernetes versions won't support the current used CNI. With the Multi-Stage-Addons the order of upgrades can be defined in a specific order which ensures the compatibility of components.

+

Tech Preview: Cluster Gen - GUI for generating Cluster objects

+

As a user of a ClusterAPI based managed Kubernetes the interface is the Cluster object. To define this can be complicated and depends on the used ClusterClass. With Cluster-Gen the possible options will be pulled from an existing ClusterClass to provide a form which can be used to create the Cluster object to apply it to the management cluster, which results in the usable workload cluster.

+

Tech Preview: Kamaji

+

Kamaji is a Control Plane manager which makes it possible to host Control Planes on pods instead on dedicated VMs. This makes them highly scalable and safes a lot of resources. We now provide Cluster Stacks using Kamaji as Control Plane provider, which can be especially interesting for smaller CSPs.

+

Openstack csp helper

+

The openstack-csp-helper is a simple Helm Chart to build and deploy the needed secrets used in the management cluster (to create the machines) and in the workload cluster (to get persistent volumes and loadbalancers) from a usual clouds.yaml file.

+

IAM

+

The keycloak container has been updated and the build process has seen further automation. +The container is now deployed into the internal infrastructure k3s, using the modern +Kubernetes-based interfaces that OSISM has provided to allow providers to plug-in +additional components at the management layer.

+

The work that SCS has done on a clean role model including the domain manager role +needed for self-service user and role management has successfully been discussed +upstream and contributed there. This means that the SCS downstream implementation +can be dropped and replaced by the upstream one in the next release R8.

+

Upgrade/Migration notes

+ +

Removals

+
    +
  • The following roles have been removed from OSISM, most of them do not affect the SCS operators in any real matter: +
      +
    • osism.services.bird
    • +
    • osism.commons.kompose
    • +
    • osism.services.openldap
    • +
    • osism.services.openstack_health_monitor
    • +
    • osism.validations.refstack
    • +
    +
  • +
+

Deprecations

+
    +
  • KaaS v1 (k8s-cluster-api-provider)
  • +
+

Security Fixes

+

During the R7 development cycle a few security issues were reported and we issued security +advisories and addressed them via maintenance updates for R6 (and some also R5). All of these +issues are also fixed in the upcoming R7 release. These include:

+ +

Standards Conformance

+

This release brings quality-of-life improvements such as:

+
    +
  • improved documentation of the certification scopes: they now include formal parameters, +such as the image spec file for the standard on standard images (SCS-compatible IaaS +v4),
  • +
  • removal of unnecessary strictness from the standard +scs-0103-v1 +on standard flavors, enabling operators to provide more meaningful information via extra_specs,
  • +
  • improved output and documentation of the main check script,
  • +
  • and bug fixes on the test scripts.
  • +
+

We are quite pleased that it could be shown in May that compliance with the certificate scope +SCS-compatible IaaS v4 can be achieved with an alternative implementation (other than our reference +implementation), namely Yaook, +with reasonable effort.

+

Finally, we are also happy that we could welcome new partners to our table of SCS clouds, namely AOV, +SysEleven, and, with proof-of-concept environments, the companies KDO Service GmbH and Cloud&Heat +Technologies GmbH.

+

Release Tagging

+

OSISM uses the tag 8.0.0 for SCS R7 and some of the related repositories in the SCS project +use a similar tag. Some repositories use maintained (stable) branches where the amount of changes +is limited to mainly bug and security fixes to make life easier for our operators that need to +stay on top of our security fixes without incurring too much change. Please note that by default, +we will stop maintaining the old R6 branches after October. Also note that we have been +able to establish a larger number of smaller changes during the R6 lifecycle to facilitate +the increasing insight that 4 (well-tested) small changes are less risky that one step with +3x the amount of changes. We will continue to work with our operators to ensure there is a +good balance between effort (4 small changes is more operational effort!) and risk.

+

List of known issues & restrictions in R7

+

IAM

+

The most underestimated topic for SCS as probably the creation of a self-service federated +Identity- and Access Management. While we were able to connect an external Identity Provider +via OpenID Connect and fix the issues with API access before, we still have not achieved +the full vision with customers being able to configuring everything via self-service. +Our work on the domain-manager role (persona) in OpenStack has been contributed upstream, so +we have an aligned view on this finally. Unfortunately, we will only get the results of +this into the next release (R8) when we use OpenStack 2024.2 (Dalamatian). Discussing with +our operators, we also learned about new requirements where some user identities need to +work across several tenants and thus escape our simple view of users always belonging to +a tenant. This topic will keep us busy for the next few releases.

+

KaaS

+

As already in R6, we do not yet have the handling of restrictive security +groups implemented nor the ability to avoid OpenStack scheduling more than one +control plane node on the same host (hypervisor). +Those features are in review upstream.

+

OVN Loadbalancers

+

The octavia ovn load balancer provider has a file descriptor leak which can lead +to a dysfunctional octavia-api service. The bug +is still in analysis; for now, +restarting the octavia-api service before the exhaustion is the workaround.

+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our How to contribute page.

+

On to R8 ...

+

We expect the continuation of our half-yearly cycle and thus an R8 in March. A lot of the work on the +SCS components was done via tenders paid for and managed by the OSBA (with the funding from the german +government / BMWK). The inclusion and exclusion of software components in future releases will depend +more on the willingness of the component maintainers than on the setup of the SCS work packages; we +anticipate more projects to seek alignment with SCS while existing projects can more easily work +with loser coupling. We will make this transparent to the community in order to ensure that we +maintain predictability for operators that rely on our technology.

+

Thanks

+

Even more contribution from upstream communities and partners in the SCS ecosystem, too many +to mention here. Technology can only be improved to a certain degree in the hands of capable +development teams; the real push comes through usage and very well-working feedback loops +from operators and users back into engineering. Not everyone realizes it, but Open Source +allows for extremely direct feedback, as users have the full bandwidth of option from just +channeling a requirement or idea into the development via a full bug analysis up to code +contributions. So let us use the opportunity for calling out to our operators and users. +We have been working on growing the SCS adoption further and are looking forward to +further announcements during the next weeks.

+ + \ No newline at end of file diff --git a/docs/releases/ReleaseX/index.html b/docs/releases/ReleaseX/index.html new file mode 100644 index 0000000000..198be5ab3e --- /dev/null +++ b/docs/releases/ReleaseX/index.html @@ -0,0 +1,45 @@ + + + + + +Release Notes for SCS Release X | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Release Notes for SCS Release X

+

This document is work in progress for the upcoming Release X. +Release X will be released in Months/Year. +This note will be removed, once Release X is released and these notes are valid.

+

Scope

+

Component Versions and User-visible improvements (highlights)

+

New Features (Highlights)

+

Operator focused improvements

+

SCS Developer focused improvements (testbed and k8s cluster management)

+

Upgrade/Migration notes

+

Removals

+

Deprecations

+

Security Fixes

+

Resolved Issues

+

Standards Conformance

+

Release Tagging

+

List of known issues & restrictions in RX

+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our How to contribute page.

+

Thanks

+ + \ No newline at end of file diff --git a/docs/standards/index.html b/docs/standards/index.html new file mode 100644 index 0000000000..d785da7f9d --- /dev/null +++ b/docs/standards/index.html @@ -0,0 +1,25 @@ + + + + + +Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/turnkey-solution/hardware-landscape/index.html b/docs/turnkey-solution/hardware-landscape/index.html new file mode 100644 index 0000000000..28279adca6 --- /dev/null +++ b/docs/turnkey-solution/hardware-landscape/index.html @@ -0,0 +1,146 @@ + + + + + +The SCS Hardware-Landscape | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

The SCS Hardware-Landscape

+

An image of the SCS hardware landscape rack

+

General information

+

The general aim of this environment is to install and operate the SCS reference implementation on hardware. +In addition to the classic tasks in the area of quality assurance, the environment is also used to evaluate +new concepts in the underlay/overlay network area, as a test environment for hardware-related developments, +as a demonstration environment for interested parties and as a publicly accessible blueprint for users. +The environment is designed for long-term use which a varying circle of users.

+

The environment consists of 21 server and 12 switch components. The selection of hardware and the +functions and properties used was designed so that the focus is on generally available or characteristic +functions and dependency on manufacturer-specific functions is avoided. Instead of the x86 servers or SONiC +switches used here, the realised environment could also be realised with hardware from other manufacturers.

+

From 1 January 2025, the environment will be operated by forum SCS-Standards +and the participating companies.

+

Tasks and Objectives

+

The tasks and objectives of the environments can be summarised as follows:

+
    +
  • The division into several environments makes it possible to run a lab as well as to map a productive environment (near-live operation).
  • +
  • Operation of the compliance monitor (automated test for conformity with the SCS standards)
  • +
  • Implementation and validation of the developed standards in a reference environment
  • +
  • Analysis of problems in the interaction with the standards
  • +
  • Provision of proof-of-concept installations for interested parties who want to use, promote or further develop the project
  • +
  • The environment can be used by members of the SCS Standards forum and by contributors to the SCS community +as a development and test environment for open-source development in connection with the further development +of the SCS standards, SCS reference implementation and other relevant software components ('open-lab'/'near-live laboratory').
  • +
  • Continuous Integration Environment ('Zuul as a Service') - Operation of non-critical zuul worker instances
  • +
+

Installation details

+

The available hardware was divided into two distinct application areas:

+
    +
  • The lab environment consists exclusively of switch hardware used to evaluate, test and develop +concepts in the area of 'Software Defined Networking'. This means that various switch models can be +used to test and implement development tasks in the area of the open SONiC NOS +(a network operating system based on Debian Linux) or provisioning automation tasks in the SONiC environment with the +open-source system Netbox, a solution that is used primarily for IPAM and DCIM (IP Address Management, Data Center Infrastructure Management).
  • +
  • The production environment is an exemplary installation of the relevant or most reference implementations with regard to an +SCS system. It follows a configuration or approach that is based on the needs and circumstances of a real and much larger environment. +To this end, characteristic infrastructure components were automatically installed on the manager nodes used for the installation.
  • +
+

The setup of the entire environment is designed in such a way that it can be reproducibly restored or reset. +Therefore, the Ansible automation available via OSISM was used in many areas. +Areas that could not be usefully automated using Ansible were implemented using a Python command-line tooling stored in the GIT repository.

+

Available documentation

+

The primary point of information and orientation is the readme file +which is stored at the top level of the configuration repository.

+

The relevant References section refers here to the individual documentation areas.

+

Specific installation and configuration details

+
    +
  • Processes for access management to the environment (2 VPN gateways, SSH logins, SSH profiles,..) have been implemented
  • +
  • The production and lab environments have been set up, automated and documented as described above
  • +
  • The complete environment is managed in a GIT repository, +adjustments and further developments are managed via GIT merge requests
  • +
  • Almost all installation steps are documented and automated +based on a pure rack installation (The setup is extensively documented, in particular the few manual steps) +
      +
    • The entire customized setup of the nodes is implemented by OSISM/Ansible
    • +
    • All secrets (e.g. passwords) of the environment are stored and versioned in the encrypted Ansible Vault in +the repository (when access is transferred, rekeying can be used to change the access or the rights to it).
    • +
    • A far-reaching or in-depth automation has been created that allows the environment to be re-set up or parts of it to +be re-set up with a reasonable amount of personnel.
    • +
    • The setup of the basic environment was implemented appropriately with Ansible and using the OSISM environment (the reference implementation)
    • +
    • Python tooling was created that adds areas that are specific to the use case of the environment and provides functions that simplify the operation of the infrastructure
    • +
    • Server systems +
        +
      • Backup and restore of the hardware configuration
      • +
      • Templating of the BMC configuration
      • +
      • Automatic installation of the operating system base image via Redfish Virtual Media
      • +
      • Control of the server status via command line (to stop and start the system for test, maintenance and energy-saving purposes)
      • +
      • Generation of base profiles for the Ansible Inventory based on the hardware key data stored in the documentation
      • +
      +
    • +
    • Switches +
        +
      • Backup and restore of the switch configuration
      • +
      • Generation of base profiles for the Ansible Inventory based on the hardware key data stored in the documentation
      • +
      +
    • +
    +
  • +
  • Network setup +
      +
    • The two management hosts act as redundant VPN gateways, ssh jumphosts, routers and uplink routers
    • +
    • The system is deployed with a layer 3 underlay concept
    • +
    • An "eBGP router on the host" is implemented for the node-interconnectivity +(all nodes and all switches are running FRR instances)
    • +
    • All Ceph and Openstack nodes of the system do not have a direct upstream routing +(access is configured and provided by HTTP-, NTP and DNS-proxies)
    • +
    • For security reasons, the system itself can only be accessed via VPN. +The provider network of the production environment is realized with a VXLAN which is terminated on the managers for routing +('a virtual provider network')).
    • +
    • The basic node installation was realised in such a way that specific node images +are created for the respective rack, which make the operation or reconfiguration of network equipment for PXE bootstrap +unnecessary. (Preliminary stage for rollout via OpenStack Ironic)
    • +
    • The management of the hardware (BMC and switch management) is implemented with a VLAN
    • +
    • Routing, firewalling and NAT is managed by a NFTables Script which adds rules in a idempotent way to the existing rules +of the manager nodes.
    • +
    +
  • +
  • The openstack workload generator is used put test workloads +on the system +
      +
    • Automated creation of OpenStack domains, projects, servers, networks, users, etc.
    • +
    • Launching test workloads
    • +
    • Dismantling test workloads
    • +
    +
  • +
  • An observability stack was built +
      +
    • Prometheus for metrics
    • +
    • Opensearch for log aggregation
    • +
    • Central syslog server for the switches on the managers (recorded via the manager nodes in Opensearch)
    • +
    +
  • +
  • Specific documentation created for the project +
      +
    • Details of the hardware installed in the environment
    • +
    • The physical structure of the environment was documented in detail (rack installation and cabling)
    • +
    • The technical and logical structure of the environment was documented in detail
    • +
    • A FAQ for handling the open-source network operating system SONiC was created with relevant topics for the test environment
    • +
    • As part of the development, the documentation and implementation of the OSISM reference implementation was significantly improved (essentially resulting from
    • +
    +
  • +
+ + \ No newline at end of file diff --git a/docs/turnkey-solution/overview/index.html b/docs/turnkey-solution/overview/index.html new file mode 100644 index 0000000000..9308ff9768 --- /dev/null +++ b/docs/turnkey-solution/overview/index.html @@ -0,0 +1,43 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

Scope of this document

+

The Sovereign Cloud Stack software (reference implementation) consists of numerous modules. This is intentional, as we have various operators that have deployed preexisting technology or have specific requirements and expect SCS to fit into it. It is good practice to build technology in a modular way, as this allows different pieces to move at its own speed and ensures that work is invested into proper abstractions and interfaces to build a losely coupled system that is resilient.

+

That said, the most value is derived by operators that consume the complete stack. We thus provide an overview over all components and some hints of how to deploy them.

+

We start with the functional stack at the bottom, where a deployment on server hardware is automated.

+

Overview table

+
LayerComponentSubcomponentPurposeStatusRequirementsDocumentation
InfraOSISMManager, Netbox, ...Lifecycle Manage deploymentProdHWhttps://docs.scs.community/docs/iaas/guides/configuration-guide/
OpsOSISMPrometheus, Netdata, AlertMgr, ...Monitor Infra layerProdHWhttps://docs.scs.community/docs/iaas/guides/concept-guide/#components-in-a-cluster
SDSOSISMcephStorage (Block, Object)ProdHWhttps://docs.scs.community/docs/iaas/guides/concept-guide/components/ceph
SDNOSISMOVNNetworkingProdHWhttps://docs.scs.community/docs/iaas/guides/concept-guide/components/sonic#-lifecycle-management-of-open-virtual-network-ovn-in-osism
IaaSOSISMOpenStackVirtualizationProdHWhttps://docs.scs.community/docs/iaas/guides/concept-guide/components/openstack
KaaSClusterStacksCAPI, CAPO, ClusterStacks, CSO, CSPOK8s cluster managementStableIaaShttps://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stacks/overview
PaaSRegistryharborContainer registryProdKaaShttps://docs.scs.community/docs/category/container-registry
APICentral APICentral APIAPI for IAM, IaaS, KaaSTech PreviewKaaShttps://scs.community/tech/2024/08/13/central-api-tech-preview-release/
OpsOS Health MonitorOSHM (old)IaaS monitorDeprecatedIaaShttps://docs.scs.community/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install
OpsHealth MonitorOSHM (new)IaaS monitorStableIaaShttps://docs.scs.community/docs/category/scs-health-monitor
OpsHealth MonitorSCS monitoringK8s cluster monitorProdKaaShttps://docs.scs.community/docs/category/monitoring
OpsStatus PageSCS Status PagePublication of platform statusTechnical PreviewKaaShttps://docs.scs.community/docs/category/status-page
OpsMeteringSCS meteringUsage data collectionTech PreviewIaaShttps://docs.scs.community/docs/category/metering
OpsSCS ComplianceSCS compliance testsTestsuiteStableIaaS+KaaShttps://docs.scs.community/standards/scs-0004-v1-achieving-certification
CISCS pipelineszuulAutomation and validationStableIaaS (KaaS optional)https://docs.scs.community/community/tools/zuul
SecPentestingSCS PentestingAutomated security assessentStablezuulhttps://docs.scs.community/docs/operating-scs/components/automated-pentesting-iaas/overview#scs-automated-pentesting
IAMKeycloakKeycloakID provider and broker for federationStableIaaShttps://docs.scs.community/contributor-docs/operations/iam/identity-federation-in-scs
+

Legend for status:

+
    +
  • Prod = Proven in numerous production environments
  • +
  • Stable = Stable release, fully supported, may not be removed without prior deprecation
  • +
  • Tech Preview = Technical preview, may not be depended upon yet and may undergo significant change or removal in the future
  • +
  • Deprecated = Still supported, but to be removed in the future
  • +
+

Notes:

+
    +
  • OSISM comes with numerous components to manage the hardware deployment of the Infra and IaaS stack, such as homer (the portal), ARA, netbox, netdata, ... which are not all listed here. Their deployment is covered with a standard OSISM deployment and thus no separate deployment guides are linked here.
  • +
  • Similarly, Cluster Stacks, building on top of Kubernetes Cluster API, consists of a set of components that are all meant to be used together and are thus covered in one set of documents. This also includes the cluster-add-ons to integrate with the underlaying IaaS. Note that while Cluster Stack has been designed and implemented to work very well on SCS IaaS, it does also fully support other IaaS environments (such as e.g. docker for development or Hetzner for production).
  • +
  • The journey to provide seamless self-service federation across all layers of the SCS stack is a long one; while the IAM solution included is stable, it is still limited in scope, which has prevented broad adoption thus far. Work is underway to address this, which is reflected in the linked documentation.
  • +
+ + \ No newline at end of file diff --git a/img/favicon.ico b/img/favicon.ico new file mode 100644 index 0000000000..8e0002e27e Binary files /dev/null and b/img/favicon.ico differ diff --git a/img/favicon.png b/img/favicon.png new file mode 100644 index 0000000000..cb271eaff4 Binary files /dev/null and b/img/favicon.png differ diff --git a/img/github-failed-dco.png b/img/github-failed-dco.png new file mode 100644 index 0000000000..a21febb629 Binary files /dev/null and b/img/github-failed-dco.png differ diff --git a/img/logo.svg b/img/logo.svg new file mode 100644 index 0000000000..b92fddce2e --- /dev/null +++ b/img/logo.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/img/scs-og-basic.png b/img/scs-og-basic.png new file mode 100644 index 0000000000..1a65ebf2a5 Binary files /dev/null and b/img/scs-og-basic.png differ diff --git a/img/summit-social.png b/img/summit-social.png new file mode 100644 index 0000000000..66a362e6f5 Binary files /dev/null and b/img/summit-social.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000000..332f6b4e27 --- /dev/null +++ b/index.html @@ -0,0 +1,24 @@ + + + + + +One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Welcome to the SCS Documentation

Find user guides, code samples, deployment examples, reference, community pages and more.

Introduction to SCS

Get to know SCS better and learn about the background.

Releases

SCS is currently in Release 7. Check out the latest Release Notes.

Frequently Asked Questions

You are curious what SCS is all about, what it can do and what it can't?

Existing Public Clouds

There are SCS compliant public clouds in production.

Architectural Layers

Ops Layer

Tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.

Container Layer

SCS offers a robust solution for managing container workloads on a Kubernetes infrastructure.

IaaS Layer

SCS offers OpenStack infrastructure solutions based on KVM virtualization to deploy VM workloads and enabling the container layer optionally.

IAM Layer

Working on Keycloak federated identity provider within our Team IAM.

Additional Resources

Get in touch

Come into our Matrix Chat in the SCS | Tech Room.

Come to our Meet-Ups

Our working groups and special interest groups meet weekly or biweekly. When? Find out within our public community calendar.

Standardization in progress

Get to know our current Decision Records and Standards.

Deployment Examples

Get to know different ways to deploy SCS with cloud resources or on bare metal.

Application Examples

Discover best practices to make the most of your cloud, from introductions to specific applications to advanced use cases.

+ + \ No newline at end of file diff --git a/search-index.json b/search-index.json new file mode 100644 index 0000000000..40a092f5ac --- /dev/null +++ b/search-index.json @@ -0,0 +1 @@ +[{"documents":[{"i":1,"t":"","u":"/blog/archive","b":[]},{"i":2,"t":"First Blog Post","u":"/blog/first-blog-post","b":[]},{"i":4,"t":"","u":"/blog/authors","b":[]},{"i":5,"t":"Overview","u":"/community/","b":["Community"]},{"i":8,"t":"Central services","u":"/community/central-services/plusserver-gx-scs","b":["Community"]},{"i":16,"t":"Test and development cloud resources","u":"/community/cloud-resources/","b":["Community","Tools","Cloud Resources"]},{"i":34,"t":"Getting Started with OpenStack","u":"/community/cloud-resources/getting-started-openstack","b":["Community","Tools","Cloud Resources"]},{"i":42,"t":"Getting Started Gaia-X Demonstrator @ plusserver","u":"/community/cloud-resources/plusserver-gx-scs","b":["Community","Tools","Cloud Resources"]},{"i":50,"t":"Getting Started with Wavestack","u":"/community/cloud-resources/wavestack","b":["Community","Tools","Cloud Resources"]},{"i":57,"t":"Collaboration","u":"/community/collaboration/","b":["Community","Collaboration"]},{"i":69,"t":"SIG Central API","u":"/community/collaboration/sig-central-api","b":["Community","Collaboration"]},{"i":71,"t":"SIG Community","u":"/community/collaboration/sig-community","b":["Community","Collaboration"]},{"i":73,"t":"SIG Documentation","u":"/community/collaboration/sig-documentation","b":["Community","Collaboration"]},{"i":75,"t":"SIG Monitoring","u":"/community/collaboration/sig-monitoring","b":["Community","Collaboration"]},{"i":77,"t":"SIG Standardization","u":"/community/collaboration/sig-standardization","b":["Community","Collaboration"]},{"i":79,"t":"Team Container","u":"/community/collaboration/team-container","b":["Community","Collaboration"]},{"i":81,"t":"Team Iaas","u":"/community/collaboration/team-iaas","b":["Community","Collaboration"]},{"i":83,"t":"Team IAM","u":"/community/collaboration/team-iam","b":["Community","Collaboration"]},{"i":85,"t":"Team Ops","u":"/community/collaboration/team-ops","b":["Community","Collaboration"]},{"i":87,"t":"Adding Docs Guide","u":"/community/contribute/adding-docs-guide","b":["Community","Contribute to Docs"]},{"i":100,"t":"Documentation Files Structure","u":"/community/contribute/doc-files-structure-guide","b":["Community","Contribute to Docs"]},{"i":116,"t":"Linting Guide","u":"/community/contribute/linting-guide","b":["Community","Contribute to Docs"]},{"i":124,"t":"Installation","u":"/community/contribute/local-docusaurus-development-guide","b":["Community","Contribute to Docs"]},{"i":137,"t":"Styleguide","u":"/community/contribute/styleguide","b":["Community","Contribute to Docs"]},{"i":144,"t":"Ansible Style Guide","u":"/community/contribute/styleguides/ansible_styleguide","b":["Community"]},{"i":164,"t":"Documentation workflow explanation","u":"/community/contribute/docs-workflow-explanation","b":["Community","Contribute to Docs"]},{"i":168,"t":"License considerations for SCS","u":"/community/license-considerations","b":["Community"]},{"i":186,"t":"Mission Statement","u":"/community/mission-statement","b":["Community"]},{"i":200,"t":"Branch Protection Rules","u":"/community/tools/github/branchprotection","b":["Community","Tools","GitHub"]},{"i":202,"t":"Hackathon planning checklist","u":"/community/hackathons/checklist","b":["Community"]},{"i":248,"t":"Developer Certificate of Origin + Licenses","u":"/community/tools/github/dco-and-licenses","b":["Community","Tools","GitHub"]},{"i":252,"t":"Jitsi","u":"/community/tools/jitsi","b":["Community","Tools"]},{"i":256,"t":"Tips and Tricks","u":"/community/tools/github/tips-and-tricks","b":["Community","Tools","GitHub"]},{"i":259,"t":"Mailing Lists","u":"/community/tools/mailinglists","b":["Community","Tools"]},{"i":261,"t":"Matrix","u":"/community/tools/matrix","b":["Community","Tools"]},{"i":265,"t":"Nextcloud","u":"/community/tools/nextcloud","b":["Community","Tools"]},{"i":267,"t":"Zuul","u":"/community/tools/zuul","b":["Community","Tools"]},{"i":274,"t":"Documentation for SCS Contributors","u":"/contributor-docs/","b":["For Contributors"]},{"i":276,"t":"Developer documentation","u":"/contributor-docs/development/","b":["For Contributors","Developer documentation"]},{"i":278,"t":"SCS RFC2119 Keyword Test Guide","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","b":["For Contributors","Developer documentation","tests"]},{"i":296,"t":"SCS Conformance Test Implementation Guide","u":"/contributor-docs/development/tests/test-implementation-guide","b":["For Contributors","Developer documentation","tests"]},{"i":310,"t":"Identity Federation in SCS","u":"/contributor-docs/operations/iam/identity-federation-in-scs","b":["For Contributors","operations","iam"]},{"i":316,"t":"OpenStack Federation via OpenID-Connect","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","b":["For Contributors","operations","iam"]},{"i":330,"t":"Introduction","u":"/docs/","b":["For Operators"]},{"i":352,"t":"Zuul users guide","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","b":["For Contributors","operations","operations"]},{"i":369,"t":"Container Layer Introduction","u":"/docs/container/","b":["For Operators","Container Layer"]},{"i":381,"t":"Management Cluster flow","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow","b":["For Operators"]},{"i":383,"t":"Node image flow","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow","b":["For Operators"]},{"i":385,"t":"Deep dive: User flow","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","b":["For Operators"]},{"i":398,"t":"Overview","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","b":["For Operators","Container Layer","Components","Cluster Stacks","Cluster Stack Operator"]},{"i":416,"t":"The workload cluster flow","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow","b":["For Operators"]},{"i":418,"t":"Understanding the concept of Cluster Stacks","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept","b":["For Operators"]},{"i":428,"t":"Contributing","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/","b":["For Operators","Container Layer","Components","Cluster Stacks","Cluster Stack Operator"]},{"i":435,"t":"provider-integration","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integration","b":["For Operators"]},{"i":436,"t":"releasing","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing","b":["For Operators"]},{"i":443,"t":"Terminology","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology","b":["For Operators"]},{"i":457,"t":"clusterstack","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack","b":["For Operators"]},{"i":466,"t":"Getting Started","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","b":["For Operators","Container Layer","Components","Cluster Stacks","Cluster Stack Operator"]},{"i":476,"t":"Managing ClusterStack objects","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks","b":["For Operators"]},{"i":478,"t":"Upgrade flow","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow","b":["For Operators"]},{"i":480,"t":"Troubleshooting","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot","b":["For Operators","Container Layer","Components","Cluster Stacks","Cluster Stack Operator"]},{"i":482,"t":"using-local-clusterstacks","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","b":["For Operators"]},{"i":494,"t":"Controllers","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","b":["For Operators","Container Layer","Components","Cluster Stacks","Cluster Stack Provider OpenStack"]},{"i":499,"t":"Overview","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","b":["For Operators","Container Layer","Components","Cluster Stacks","Cluster Stack Provider OpenStack"]},{"i":501,"t":"Quickstart","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","b":["For Operators","Container Layer","Components","Cluster Stacks","Cluster Stack Provider OpenStack"]},{"i":503,"t":"Developer Guide","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","b":["For Operators","Container Layer","Components","Cluster Stacks","Cluster Stack Provider OpenStack"]},{"i":515,"t":"Troubleshooting","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","b":["For Operators"]},{"i":519,"t":"Continuous integration","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration","b":["For Operators"]},{"i":531,"t":"Overview","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","b":["For Operators","Container Layer","Components","Cluster Stacks"]},{"i":552,"t":"Configuration","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","b":["For Operators","Container Layer","Components","Cluster Stacks","Predefined Cluster Stacks","Openstack"]},{"i":558,"t":"Developing and Testing csctl","u":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","b":["For Operators","Container Layer","Components","Cluster Stacks","csctl"]},{"i":571,"t":"Quickstart","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","b":["For Operators","Container Layer","Components","Cluster Stacks","Predefined Cluster Stacks","Openstack"]},{"i":591,"t":"CSCTL - Design document","u":"/docs/container/components/cluster-stacks/components/csctl/design","b":["For Operators"]},{"i":639,"t":"Using csctl","u":"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl","b":["For Operators"]},{"i":656,"t":"Getting started","u":"/docs/container/components/cluster-stacks/components/csctl/getting_started","b":["For Operators","Container Layer","Components","Cluster Stacks","csctl"]},{"i":662,"t":"Overview","u":"/docs/container/components/cluster-stacks/components/csctl/overview","b":["For Operators","Container Layer","Components","Cluster Stacks","csctl"]},{"i":669,"t":"Quickstart","u":"/docs/container/components/cluster-stacks/components/csctl/quickstart","b":["For Operators","Container Layer","Components","Cluster Stacks","csctl"]},{"i":684,"t":"HA deployment","u":"/docs/container/components/container-registry/docs/ha-deployment","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":695,"t":"Backup and restore","u":"/docs/container/components/container-registry/docs/backup_and_restore","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":711,"t":"Persistence","u":"/docs/container/components/container-registry/docs/persistence","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":727,"t":"Migration","u":"/docs/container/components/container-registry/docs/migration","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":740,"t":"Rate limit","u":"/docs/container/components/container-registry/docs/rate_limit","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":742,"t":"SCS deployment","u":"/docs/container/components/container-registry/docs/scs-deployment","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":748,"t":"Quickstart","u":"/docs/container/components/container-registry/docs/quickstart","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":754,"t":"Upgrade","u":"/docs/container/components/container-registry/docs/upgrade","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":756,"t":"Hardware Requirements","u":"/docs/container/deployment-examples/a/hardware","b":["For Operators"]},{"i":758,"t":"Overview","u":"/docs/container/deployment-examples/a/","b":["For Operators"]},{"i":760,"t":"Software Requirements","u":"/docs/container/deployment-examples/a/software","b":["For Operators"]},{"i":762,"t":"Guide 1","u":"/docs/container/guides/guide1","b":["For Operators"]},{"i":764,"t":"Architecture","u":"/docs/container/overview/architecture","b":["For Operators"]},{"i":766,"t":"Knowledge","u":"/docs/container/overview/knowledge","b":["For Operators"]},{"i":768,"t":"Containerization","u":"/docs/getting-started/containerization","b":["For Operators"]},{"i":770,"t":"Frequently Asked Questions","u":"/docs/faq/","b":["For Operators"]},{"i":805,"t":"Overview","u":"/docs/getting-started/overview","b":["For Operators"]},{"i":807,"t":"Virtualization","u":"/docs/getting-started/virtualization","b":["For Operators"]},{"i":809,"t":"Glossary","u":"/docs/glossary","b":["For Operators"]},{"i":855,"t":"Tools","u":"/docs/iaas/components/","b":["For Operators"]},{"i":856,"t":"Image Manager","u":"/docs/iaas/components/image-manager/","b":["For Operators","IaaS Layer","Components","Openstack Image Manager"]},{"i":881,"t":"Image Manager update.py","u":"/docs/iaas/components/image-manager/update","b":["For Operators","IaaS Layer","Components","Openstack Image Manager"]},{"i":888,"t":"Flavor Manager","u":"/docs/iaas/components/flavor-manager","b":["For Operators","IaaS Layer","Components"]},{"i":899,"t":"Project Manager","u":"/docs/iaas/components/project-manager","b":["For Operators"]},{"i":921,"t":"Setting up OpenStack health monitor on Debian","u":"/docs/iaas/components/openstack-health-monitor","b":["For Operators"]},{"i":981,"t":"Resource Manager","u":"/docs/iaas/components/resource-manager","b":["For Operators"]},{"i":996,"t":"Sandbox Manager","u":"/docs/iaas/components/sandbox-manager","b":["For Operators"]},{"i":997,"t":"Simple Stress","u":"/docs/iaas/components/simple-stress","b":["For Operators"]},{"i":1008,"t":"Guides","u":"/docs/iaas/guides/","b":["For Operators","IaaS Layer","Guides"]},{"i":1010,"t":"Concept Guide","u":"/docs/iaas/guides/concept-guide/","b":["For Operators","IaaS Layer","Guides","Concept Guide"]},{"i":1023,"t":"artcodix","u":"/docs/iaas/deployment-examples/artcodix/","b":["For Operators","IaaS Layer","Deployment Examples"]},{"i":1053,"t":"Components","u":"/docs/iaas/guides/concept-guide/components/","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":1055,"t":"Cluster API","u":"/docs/iaas/guides/concept-guide/components/clusterapi","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":1060,"t":"Ceph","u":"/docs/iaas/guides/concept-guide/components/ceph","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":1063,"t":"Gardener","u":"/docs/iaas/guides/concept-guide/components/gardener","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":1066,"t":"Ironic","u":"/docs/iaas/guides/concept-guide/components/ironic","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":1069,"t":"K3S","u":"/docs/iaas/guides/concept-guide/components/k3s","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":1071,"t":"OpenStack","u":"/docs/iaas/guides/concept-guide/components/openstack","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":1082,"t":"Keycloak","u":"/docs/iaas/guides/concept-guide/components/keycloak","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":1084,"t":"Netdata","u":"/docs/iaas/guides/concept-guide/components/netdata","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":1086,"t":"Prometheus & Grafana","u":"/docs/iaas/guides/concept-guide/components/prometheus","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":1089,"t":"SONiC & OVN","u":"/docs/iaas/guides/concept-guide/components/sonic","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":1093,"t":"Teleport","u":"/docs/iaas/guides/concept-guide/components/teleport","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":1095,"t":"Cluster design","u":"/docs/iaas/guides/concept-guide/design","b":["For Operators","IaaS Layer","Guides","Concept Guide"]},{"i":1102,"t":"Hardware Bill of Materials","u":"/docs/iaas/guides/concept-guide/hardware-bom","b":["For Operators","IaaS Layer","Guides","Concept Guide"]},{"i":1122,"t":"Nodes in a cluster","u":"/docs/iaas/guides/concept-guide/nodes","b":["For Operators","IaaS Layer","Guides","Concept Guide"]},{"i":1129,"t":"Layers in a cluster","u":"/docs/iaas/guides/concept-guide/layers","b":["For Operators","IaaS Layer","Guides","Concept Guide"]},{"i":1136,"t":"Use cases","u":"/docs/iaas/guides/concept-guide/use-cases","b":["For Operators","IaaS Layer","Guides","Concept Guide"]},{"i":1138,"t":"Configuration Guide","u":"/docs/iaas/guides/configuration-guide/","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1139,"t":"Commons","u":"/docs/iaas/guides/configuration-guide/commons/","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1141,"t":"Certificates","u":"/docs/iaas/guides/configuration-guide/commons/certificates","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1143,"t":"Packages","u":"/docs/iaas/guides/configuration-guide/commons/packages","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1152,"t":"Resolvconf","u":"/docs/iaas/guides/configuration-guide/commons/resolvconf","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1154,"t":"Services","u":"/docs/iaas/guides/configuration-guide/commons/services","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1160,"t":"Ceph","u":"/docs/iaas/guides/configuration-guide/ceph","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1192,"t":"SSH Config","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1200,"t":"Sysctl","u":"/docs/iaas/guides/configuration-guide/commons/sysctl","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1202,"t":"Timezone","u":"/docs/iaas/guides/configuration-guide/commons/timezone","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1204,"t":"User","u":"/docs/iaas/guides/configuration-guide/commons/user","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1206,"t":"Inventory","u":"/docs/iaas/guides/configuration-guide/inventory","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1215,"t":"Configuration Repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1239,"t":"Loadbalancer","u":"/docs/iaas/guides/configuration-guide/loadbalancer","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1255,"t":"Manager","u":"/docs/iaas/guides/configuration-guide/manager","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1264,"t":"Network","u":"/docs/iaas/guides/configuration-guide/network","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1276,"t":"Aodh","u":"/docs/iaas/guides/configuration-guide/openstack/aodh","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1278,"t":"Ceilometer","u":"/docs/iaas/guides/configuration-guide/openstack/ceilometer","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1280,"t":"Barbican","u":"/docs/iaas/guides/configuration-guide/openstack/barbican","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1282,"t":"Cinder","u":"/docs/iaas/guides/configuration-guide/openstack/cinder","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1286,"t":"Designate","u":"/docs/iaas/guides/configuration-guide/openstack/designate","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1288,"t":"Glance","u":"/docs/iaas/guides/configuration-guide/openstack/glance","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1290,"t":"OpenStack","u":"/docs/iaas/guides/configuration-guide/openstack/","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1307,"t":"Heat","u":"/docs/iaas/guides/configuration-guide/openstack/heat","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1309,"t":"Horizon","u":"/docs/iaas/guides/configuration-guide/openstack/horizon","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1317,"t":"Ironic","u":"/docs/iaas/guides/configuration-guide/openstack/ironic","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1319,"t":"Magnum","u":"/docs/iaas/guides/configuration-guide/openstack/magnum","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1321,"t":"Keystone","u":"/docs/iaas/guides/configuration-guide/openstack/keystone","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1326,"t":"Manila","u":"/docs/iaas/guides/configuration-guide/openstack/manila","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1328,"t":"Neutron","u":"/docs/iaas/guides/configuration-guide/openstack/neutron","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1332,"t":"Placement","u":"/docs/iaas/guides/configuration-guide/openstack/placement","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1334,"t":"Octavia","u":"/docs/iaas/guides/configuration-guide/openstack/octavia","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1336,"t":"Skyline","u":"/docs/iaas/guides/configuration-guide/openstack/skyline","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1341,"t":"Proxy","u":"/docs/iaas/guides/configuration-guide/proxy","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1355,"t":"Nova","u":"/docs/iaas/guides/configuration-guide/openstack/nova","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1386,"t":"Configure Rookify: Migrate from Ceph-Ansible to Rook (Technical Preview)","u":"/docs/iaas/guides/configuration-guide/rookify","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1392,"t":"Ceph via Rook (technical preview)","u":"/docs/iaas/guides/configuration-guide/rook","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1444,"t":"Services","u":"/docs/iaas/guides/configuration-guide/services/","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Services"]},{"i":1446,"t":"Chrony","u":"/docs/iaas/guides/configuration-guide/services/chrony","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Services"]},{"i":1448,"t":"Docker","u":"/docs/iaas/guides/configuration-guide/services/docker","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Services"]},{"i":1452,"t":"Validations","u":"/docs/iaas/guides/configuration-guide/validations/","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1454,"t":"Tuned","u":"/docs/iaas/guides/configuration-guide/services/tuned","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Services"]},{"i":1456,"t":"Bootstrap","u":"/docs/iaas/guides/deploy-guide/bootstrap","b":["For Operators","IaaS Layer","Guides","Deploy Guide"]},{"i":1458,"t":"Examples","u":"/docs/iaas/guides/deploy-guide/examples/","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Examples"]},{"i":1459,"t":"Deploy Guide","u":"/docs/iaas/guides/deploy-guide/","b":["For Operators","IaaS Layer","Guides","Deploy Guide"]},{"i":1461,"t":"Provisioning of bare-metal nodes","u":"/docs/iaas/guides/deploy-guide/provisioning","b":["For Operators","IaaS Layer","Guides","Deploy Guide"]},{"i":1467,"t":"Manager","u":"/docs/iaas/guides/deploy-guide/manager","b":["For Operators","IaaS Layer","Guides","Deploy Guide"]},{"i":1481,"t":"Testbed","u":"/docs/iaas/guides/deploy-guide/examples/testbed","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Examples"]},{"i":1483,"t":"Deploy Rookify: Migrate to Rook from Ceph-Ansible (Technical Preview)","u":"/docs/iaas/guides/deploy-guide/rookify","b":["For Operators","IaaS Layer","Guides","Deploy Guide"]},{"i":1494,"t":"Cloud in a Box","u":"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Examples"]},{"i":1496,"t":"Seed","u":"/docs/iaas/guides/deploy-guide/seed","b":["For Operators","IaaS Layer","Guides","Deploy Guide"]},{"i":1502,"t":"Ceph","u":"/docs/iaas/guides/deploy-guide/services/ceph","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1510,"t":"Services","u":"/docs/iaas/guides/deploy-guide/services/","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1512,"t":"Infrastructure","u":"/docs/iaas/guides/deploy-guide/services/infrastructure","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1514,"t":"Kubernetes","u":"/docs/iaas/guides/deploy-guide/services/kubernetes","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1518,"t":"Network","u":"/docs/iaas/guides/deploy-guide/services/network","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1520,"t":"Logging & Monitoring","u":"/docs/iaas/guides/deploy-guide/services/logging-monitoring","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1522,"t":"OpenStack","u":"/docs/iaas/guides/deploy-guide/services/openstack","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1524,"t":"Ceph via Rook (technical preview)","u":"/docs/iaas/guides/deploy-guide/services/rook","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1532,"t":"Operations Guide","u":"/docs/iaas/guides/operations-guide/","b":["For Operators","IaaS Layer","Guides","Operations Guide"]},{"i":1548,"t":"Migrate Ceph-Ansible via Rookify (technical preview)","u":"/docs/iaas/guides/deploy-guide/services/rookify","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1550,"t":"Infrastructure","u":"/docs/iaas/guides/operations-guide/infrastructure","b":["For Operators","IaaS Layer","Guides","Operations Guide"]},{"i":1567,"t":"Ceph","u":"/docs/iaas/guides/operations-guide/ceph","b":["For Operators","IaaS Layer","Guides","Operations Guide"]},{"i":1653,"t":"Manager","u":"/docs/iaas/guides/operations-guide/manager/","b":["For Operators","IaaS Layer","Guides","Operations Guide","Manager"]},{"i":1654,"t":"Apply","u":"/docs/iaas/guides/operations-guide/manager/apply","b":["For Operators","IaaS Layer","Guides","Operations Guide","Manager"]},{"i":1666,"t":"Console","u":"/docs/iaas/guides/operations-guide/manager/console","b":["For Operators","IaaS Layer","Guides","Operations Guide","Manager"]},{"i":1676,"t":"Get","u":"/docs/iaas/guides/operations-guide/manager/get","b":["For Operators","IaaS Layer","Guides","Operations Guide","Manager"]},{"i":1684,"t":"Task","u":"/docs/iaas/guides/operations-guide/manager/task","b":["For Operators","IaaS Layer","Guides","Operations Guide","Manager"]},{"i":1689,"t":"Logging","u":"/docs/iaas/guides/operations-guide/manager/log","b":["For Operators","IaaS Layer","Guides","Operations Guide","Manager"]},{"i":1699,"t":"Network","u":"/docs/iaas/guides/operations-guide/network","b":["For Operators","IaaS Layer","Guides","Operations Guide"]},{"i":1705,"t":"OpenStack","u":"/docs/iaas/guides/operations-guide/openstack/","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack"]},{"i":1714,"t":"Cinder","u":"/docs/iaas/guides/operations-guide/openstack/cinder","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack"]},{"i":1721,"t":"Neutron","u":"/docs/iaas/guides/operations-guide/openstack/neutron","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack"]},{"i":1724,"t":"Keystone","u":"/docs/iaas/guides/operations-guide/openstack/keystone","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack"]},{"i":1726,"t":"Nova","u":"/docs/iaas/guides/operations-guide/openstack/nova","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack"]},{"i":1741,"t":"Octavia","u":"/docs/iaas/guides/operations-guide/openstack/octavia","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack"]},{"i":1746,"t":"Flavor Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1757,"t":"Image Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools","Image Manager"]},{"i":1782,"t":"Tools","u":"/docs/iaas/guides/operations-guide/openstack/tools/","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1783,"t":"Project Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1805,"t":"Image Manager update.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools","Image Manager"]},{"i":1812,"t":"Setting up OpenStack health monitor on Debian","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1872,"t":"Resource Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1887,"t":"Sandbox Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1888,"t":"Simple Stress","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1899,"t":"Ceph via Rook (technical preview)","u":"/docs/iaas/guides/operations-guide/rook","b":["For Operators","IaaS Layer","Guides","Operations Guide"]},{"i":1978,"t":"Use Rookify: Migrate to Rook from Ceph Ansible (Technical Preview)","u":"/docs/iaas/guides/operations-guide/rookify","b":["For Operators","IaaS Layer","Guides","Operations Guide"]},{"i":1999,"t":"Other Guides","u":"/docs/iaas/guides/other-guides/","b":["For Operators","IaaS Layer","Guides","Other Guides"]},{"i":2000,"t":"Running on a virtual machine","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","b":["For Operators","IaaS Layer","Guides","Other Guides","Cloud in a Box Guide"]},{"i":2022,"t":"Contributor Guide","u":"/docs/iaas/guides/other-guides/contributor-guide","b":["For Operators","IaaS Layer","Guides","Other Guides"]},{"i":2024,"t":"Cloud in a Box","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","b":["For Operators","IaaS Layer","Guides","Other Guides","Cloud in a Box Guide"]},{"i":2053,"t":"Releases","u":"/docs/iaas/guides/other-guides/developer-guide/releases","b":["For Operators","IaaS Layer","Guides","Other Guides","Developer Guide"]},{"i":2070,"t":"Scripts","u":"/docs/iaas/guides/other-guides/developer-guide/scripts","b":["For Operators","IaaS Layer","Guides","Other Guides","Developer Guide"]},{"i":2072,"t":"Developer Guide","u":"/docs/iaas/guides/other-guides/developer-guide/","b":["For Operators","IaaS Layer","Guides","Other Guides","Developer Guide"]},{"i":2080,"t":"Style Guide","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","b":["For Operators","IaaS Layer","Guides","Other Guides","Developer Guide"]},{"i":2111,"t":"Zuul CI","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","b":["For Operators","IaaS Layer","Guides","Other Guides","Developer Guide"]},{"i":2133,"t":"Troubleshooting Guide","u":"/docs/iaas/guides/troubleshooting-guide/","b":["For Operators","IaaS Layer","Guides","Troubleshooting Guide"]},{"i":2135,"t":"Ceph","u":"/docs/iaas/guides/troubleshooting-guide/ceph","b":["For Operators","IaaS Layer","Guides","Troubleshooting Guide"]},{"i":2140,"t":"OpenStack","u":"/docs/iaas/guides/troubleshooting-guide/openstack","b":["For Operators","IaaS Layer","Guides","Troubleshooting Guide"]},{"i":2147,"t":"Rookify (Technical Preview)","u":"/docs/iaas/guides/troubleshooting-guide/rookify","b":["For Operators","IaaS Layer","Guides","Troubleshooting Guide"]},{"i":2153,"t":"Manager","u":"/docs/iaas/guides/troubleshooting-guide/manager","b":["For Operators","IaaS Layer","Guides","Troubleshooting Guide"]},{"i":2156,"t":"Upgrade Guide","u":"/docs/iaas/guides/upgrade-guide/","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":2158,"t":"Ceph","u":"/docs/iaas/guides/upgrade-guide/ceph","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":2162,"t":"Docker","u":"/docs/iaas/guides/upgrade-guide/docker","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":2166,"t":"Infrastructure","u":"/docs/iaas/guides/upgrade-guide/infrastructure","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":2168,"t":"Logging & Monitoring","u":"/docs/iaas/guides/upgrade-guide/logging-monitoring","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":2170,"t":"Manager","u":"/docs/iaas/guides/upgrade-guide/manager","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":2172,"t":"Network","u":"/docs/iaas/guides/upgrade-guide/network","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":2174,"t":"Testbed","u":"/docs/iaas/guides/other-guides/testbed","b":["For Operators","IaaS Layer","Guides","Other Guides"]},{"i":2230,"t":"OpenStack","u":"/docs/iaas/guides/upgrade-guide/openstack","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":2232,"t":"User Guide","u":"/docs/iaas/guides/user-guide/","b":["For Operators","IaaS Layer","Guides","User Guide"]},{"i":2233,"t":"Migrate from VMware ESXi to OpenStack","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","b":["For Operators","IaaS Layer","Guides","User Guide"]},{"i":2259,"t":"OpenStack","u":"/docs/iaas/guides/user-guide/openstack/","b":["For Operators","IaaS Layer","Guides","User Guide","OpenStack"]},{"i":2260,"t":"Install instance from ISO image","u":"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso","b":["For Operators","IaaS Layer","Guides","User Guide","OpenStack"]},{"i":2271,"t":"Client","u":"/docs/iaas/guides/user-guide/openstack/openstackclient","b":["For Operators","IaaS Layer","Guides","User Guide","OpenStack"]},{"i":2282,"t":"How to configure and use security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","b":["For Operators","IaaS Layer","Guides","User Guide","OpenStack"]},{"i":2296,"t":"Best Practise: How to configure and use security groups","u":"/docs/iaas/guides/user-guide/security-groups/","b":["For Operators","IaaS Layer","Guides","User Guide"]},{"i":2310,"t":"Architecture","u":"/docs/iaas/overview/architecture","b":["For Operators"]},{"i":2312,"t":"Compute","u":"/docs/iaas/overview/compute","b":["For Operators"]},{"i":2314,"t":"Knowledge","u":"/docs/iaas/overview/knowledge","b":["For Operators"]},{"i":2316,"t":"User Data Backups","u":"/docs/iaas/guides/user-guide/user-data-backups","b":["For Operators","IaaS Layer","Guides","User Guide"]},{"i":2361,"t":"Network","u":"/docs/iaas/overview/network","b":["For Operators"]},{"i":2363,"t":"Storage","u":"/docs/iaas/overview/storage","b":["For Operators"]},{"i":2365,"t":"Introduction on Identity Management and Federation in SCS","u":"/docs/iam/","b":["For Operators","Identity and Access Management (IAM)"]},{"i":2383,"t":"User Data Backups","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","b":["For Operators","IaaS Layer","Guides","User Guide","OpenStack"]},{"i":2428,"t":"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)","u":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","b":["For Operators","Identity and Access Management (IAM)"]},{"i":2432,"t":"Example setup configuration in SCS deployment explained","u":"/docs/iam/SCS-example-setup-configuration-description","b":["For Operators","Identity and Access Management (IAM)","Guides"]},{"i":2434,"t":"Domain Manager setup and usage","u":"/docs/iam/domain-manager-setup-and-usage","b":["For Operators","Identity and Access Management (IAM)","Guides"]},{"i":2470,"t":"Overview","u":"/docs/operating-scs/audits/","b":["For Operators"]},{"i":2472,"t":"Quickstart","u":"/docs/operating-scs/components/automated-pentesting-iaas/quickstart","b":["For Operators","Operating SCS","Components","Automated Pentesting","Pentesting IaaS"]},{"i":2483,"t":"Overview","u":"/docs/operating-scs/components/automated-pentesting-iaas/overview","b":["For Operators","Operating SCS","Components","Automated Pentesting","Pentesting IaaS"]},{"i":2496,"t":"Using Automated Pentesting Reports for CSPs, Operators, and Users","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","b":["For Operators","Operating SCS","Components","Automated Pentesting","Pentesting IaaS"]},{"i":2523,"t":"Overview","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","b":["For Operators","Operating SCS","Components","Automated Pentesting","Pentesting KaaS"]},{"i":2546,"t":"Tools Description","u":"/docs/operating-scs/components/automated-pentesting-iaas/tools","b":["For Operators","Operating SCS","Components","Automated Pentesting","Pentesting IaaS"]},{"i":2560,"t":"Quickstart Guide","u":"/docs/operating-scs/components/automated-pentesting-kaas/quickstart","b":["For Operators","Operating SCS","Components","Automated Pentesting","Pentesting KaaS"]},{"i":2570,"t":"Overview","u":"/docs/operating-scs/components/central-api/overview","b":["For Operators","Operating SCS","Components","Central API"]},{"i":2587,"t":"Tools Description","u":"/docs/operating-scs/components/automated-pentesting-kaas/tools","b":["For Operators","Operating SCS","Components","Automated Pentesting","Pentesting KaaS"]},{"i":2599,"t":"Central API MVP","u":"/docs/operating-scs/components/central-api/poc-setup","b":["For Operators","Operating SCS","Components","Central API"]},{"i":2603,"t":"Alertmanager notifications in Matrix chat","u":"/docs/operating-scs/components/monitoring/docs/alertmanager","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2605,"t":"Infrastructure service endpoints","u":"/docs/operating-scs/components/monitoring/docs/infrastructure_services","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2607,"t":"K3s support","u":"/docs/operating-scs/components/monitoring/docs/k3s","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2617,"t":"Overview","u":"/docs/operating-scs/components/monitoring/docs/overview","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2619,"t":"KaaS monitoring (experimental)","u":"/docs/operating-scs/components/monitoring/docs/kaas","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2627,"t":"OAUTH","u":"/docs/operating-scs/components/monitoring/docs/oauth","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2629,"t":"SCS deployment","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2637,"t":"IaaS monitoring (experimental)","u":"/docs/operating-scs/components/monitoring/docs/iaas","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2650,"t":"Quickstart","u":"/docs/operating-scs/components/monitoring/docs/quickstart","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2660,"t":"Traces","u":"/docs/operating-scs/components/monitoring/docs/tracing","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2666,"t":"Status page monitoring","u":"/docs/operating-scs/components/monitoring/docs/status-page","b":["For Operators"]},{"i":2677,"t":"Zuul monitoring","u":"/docs/operating-scs/components/monitoring/docs/zuul","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2679,"t":"Tuning","u":"/docs/operating-scs/components/monitoring/docs/tuning","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2687,"t":"SCS Health Monitor","u":"/docs/operating-scs/components/scs-health-monitor/overview","b":["For Operators","Operating SCS","Components","SCS Health Monitor"]},{"i":2710,"t":"Testflow-Infrastructure","u":"/docs/operating-scs/components/scs-health-monitor/Testflow","b":["For Operators","Operating SCS","Components","SCS Health Monitor"]},{"i":2719,"t":"Configuration","u":"/docs/operating-scs/components/status-page-api/docs/configuration","b":["For Operators","Operating SCS","Components","Status Page","API"]},{"i":2721,"t":"Kubernetes BDD Testing Framework Documentation","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","b":["For Operators","Operating SCS","Components","SCS Health Monitor"]},{"i":2750,"t":"Contribute","u":"/docs/operating-scs/components/status-page-api/docs/contribute","b":["For Operators","Operating SCS","Components","Status Page","API"]},{"i":2752,"t":"Observability stack quickstart","u":"/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack","b":["For Operators","Operating SCS","Components","SCS Health Monitor"]},{"i":2757,"t":"Example requests","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","b":["For Operators","Operating SCS","Components","Status Page","API"]},{"i":2793,"t":"Overview","u":"/docs/operating-scs/components/status-page-api/docs/overview","b":["For Operators","Operating SCS","Components","Status Page","API"]},{"i":2795,"t":"Quickstart","u":"/docs/operating-scs/components/status-page-api/docs/quickstart","b":["For Operators","Operating SCS","Components","Status Page","API"]},{"i":2803,"t":"Requests","u":"/docs/operating-scs/components/status-page-api/docs/requests","b":["For Operators","Operating SCS","Components","Status Page","API"]},{"i":2817,"t":"Requirements","u":"/docs/operating-scs/components/status-page-api/docs/requirements","b":["For Operators","Operating SCS","Components","Status Page","API"]},{"i":2819,"t":"Configure status page","u":"/docs/operating-scs/components/status-page-deployment/docs/configuration","b":["For Operators","Operating SCS","Components","Status Page","Deployment","Configuration"]},{"i":2835,"t":"Admin authentication","u":"/docs/operating-scs/components/status-page-deployment/docs/admin-authentication","b":["For Operators","Operating SCS","Components","Status Page","Deployment"]},{"i":2837,"t":"FAQ","u":"/docs/operating-scs/components/status-page-deployment/docs/faq","b":["For Operators","Operating SCS","Components","Status Page","Deployment"]},{"i":2846,"t":"k3s - A simple deployment on a single host","u":"/docs/operating-scs/components/status-page-deployment/docs/k3s","b":["For Operators","Operating SCS","Components","Status Page","Deployment","Configuration"]},{"i":2864,"t":"Contribute","u":"/docs/operating-scs/components/status-page-deployment/docs/contribute","b":["For Operators","Operating SCS","Components","Status Page","Deployment"]},{"i":2866,"t":"Monitoring","u":"/docs/operating-scs/components/status-page-deployment/docs/monitoring","b":["For Operators","Operating SCS","Components","Status Page","Deployment"]},{"i":2874,"t":"kind - Local development environment","u":"/docs/operating-scs/components/status-page-deployment/docs/kind","b":["For Operators","Operating SCS","Components","Status Page","Deployment","Configuration"]},{"i":2886,"t":"Overview","u":"/docs/operating-scs/components/status-page-deployment/docs/overview","b":["For Operators","Operating SCS","Components","Status Page","Deployment"]},{"i":2895,"t":"Quickstart","u":"/docs/operating-scs/components/status-page-deployment/docs/quickstart","b":["For Operators","Operating SCS","Components","Status Page","Deployment"]},{"i":2897,"t":"Requirements","u":"/docs/operating-scs/components/status-page-deployment/docs/requirements","b":["For Operators","Operating SCS","Components","Status Page","Deployment"]},{"i":2899,"t":"SCS Public","u":"/docs/operating-scs/components/status-page-deployment/docs/scs-public","b":["For Operators","Operating SCS","Components","Status Page","Deployment","Configuration"]},{"i":2901,"t":"Component Overview","u":"/docs/operating-scs/components/status-page-openapi/docs/component_overview","b":["For Operators","Operating SCS","Components","Status Page","Concepts"]},{"i":2903,"t":"Usage","u":"/docs/operating-scs/components/status-page-deployment/docs/usage","b":["For Operators","Operating SCS","Components","Status Page","Deployment"]},{"i":2911,"t":"Components","u":"/docs/operating-scs/components/status-page-openapi/docs/components","b":["For Operators","Operating SCS","Components","Status Page","Concepts"]},{"i":2913,"t":"\"Levels of consensus\"","u":"/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus","b":["For Operators","Operating SCS","Components","Status Page","Concepts"]},{"i":2915,"t":"Overview","u":"/docs/operating-scs/components/status-page-openapi/docs/overview","b":["For Operators","Operating SCS","Components","Status Page","Concepts"]},{"i":2927,"t":"Configuration","u":"/docs/operating-scs/components/status-page-web/docs/configuration","b":["For Operators","Operating SCS","Components","Status Page","Web"]},{"i":2933,"t":"Contribute","u":"/docs/operating-scs/components/status-page-web/docs/contribute","b":["For Operators","Operating SCS","Components","Status Page","Web"]},{"i":2935,"t":"Quickstart","u":"/docs/operating-scs/components/status-page-web/docs/quickstart","b":["For Operators","Operating SCS","Components","Status Page","Web"]},{"i":2937,"t":"Requirements","u":"/docs/operating-scs/components/status-page-web/docs/requirements","b":["For Operators","Operating SCS","Components","Status Page","Web"]},{"i":2939,"t":"Overview","u":"/docs/operating-scs/components/status-page-web/docs/overview","b":["For Operators","Operating SCS","Components","Status Page","Web"]},{"i":2941,"t":"Overview","u":"/docs/operating-scs/incident-management/","b":["For Operators"]},{"i":2943,"t":"Overview","u":"/docs/operating-scs/lifecycle-management/","b":["For Operators"]},{"i":2945,"t":"Guide: Setting up openstack-health-monitor on Debian 12","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","b":["For Operators","Operating SCS","Guides"]},{"i":3005,"t":"Overview","u":"/docs/operating-scs/logging/","b":["For Operators"]},{"i":3007,"t":"Overview","u":"/docs/operating-scs/monitoring/","b":["For Operators"]},{"i":3009,"t":"Overview","u":"/docs/operating-scs/overview","b":["For Operators"]},{"i":3011,"t":"Release Notes for SCS Release 0","u":"/docs/releases/Release0","b":["For Operators","Releases"]},{"i":3029,"t":"Metering Configuration","u":"/docs/operating-scs/metering/meter_configuration","b":["For Operators","Operating SCS","Metering"]},{"i":3041,"t":"Release Notes for SCS Release 1","u":"/docs/releases/Release1","b":["For Operators","Releases"]},{"i":3078,"t":"Release Notes for SCS Release 2","u":"/docs/releases/Release2","b":["For Operators","Releases"]},{"i":3111,"t":"Release Notes for SCS Release 3","u":"/docs/releases/Release3","b":["For Operators","Releases"]},{"i":3145,"t":"Release Notes for SCS Release 4","u":"/docs/releases/Release4","b":["For Operators","Releases"]},{"i":3177,"t":"Release Notes for SCS Release 5","u":"/docs/releases/Release5","b":["For Operators","Releases"]},{"i":3215,"t":"Release Notes for SCS Release 6","u":"/docs/releases/Release6","b":["For Operators","Releases"]},{"i":3273,"t":"Release Notes for SCS Release 7","u":"/docs/releases/Release7","b":["For Operators","Releases"]},{"i":3324,"t":"Release Notes for SCS Release X","u":"/docs/releases/ReleaseX","b":["For Operators"]},{"i":3342,"t":"The SCS Hardware-Landscape","u":"/docs/turnkey-solution/hardware-landscape","b":["For Operators","Turnkey Solution"]},{"i":3353,"t":"Overview","u":"/docs/turnkey-solution/overview","b":["For Operators","Turnkey Solution"]},{"i":3358,"t":"Standards","u":"/docs/standards/","b":["For Operators"]},{"i":3360,"t":"Introduction","u":"/standards/","b":["Standards"]},{"i":3362,"t":"Certification","u":"/standards/certification/overview","b":["Standards","Certification"]},{"i":3368,"t":"Certification","u":"/standards/certification/overview.template","b":["Standards"]},{"i":3374,"t":"SCS Compliance Check Pipeline Manual","u":"/standards/certification/pipeline","b":["Standards","Certification"]},{"i":3385,"t":"Scopes and versions","u":"/standards/certification/scopes-versions","b":["Standards","Certification","Scopes and Versions"]},{"i":3387,"t":"scs-0002: Standards, Docs and Organisation","u":"/standards/global/scs-0002","b":["Standards","Standards","Global","scs-0002"]},{"i":3389,"t":"Global Standards","u":"/standards/global/","b":["Standards","Standards","Global"]},{"i":3391,"t":"scs-0001: Sovereign Cloud Standards","u":"/standards/global/scs-0001","b":["Standards","Standards","Global","scs-0001"]},{"i":3393,"t":"scs-0003: Sovereign Cloud Standards YAML","u":"/standards/global/scs-0003","b":["Standards","Standards","Global","scs-0003"]},{"i":3395,"t":"scs-0005: Governance of the SCS community","u":"/standards/global/scs-0005","b":["Standards","Standards","Global","scs-0005"]},{"i":3397,"t":"IaaS Standards","u":"/standards/iaas/","b":["Standards","Standards","IaaS"]},{"i":3399,"t":"scs-0004: Regulations for achieving SCS-compatible certification","u":"/standards/global/scs-0004","b":["Standards","Standards","Global","scs-0004"]},{"i":3401,"t":"scs-0100: SCS Flavor Naming Standard","u":"/standards/iaas/scs-0100","b":["Standards","Standards","IaaS","scs-0100"]},{"i":3405,"t":"scs-0101: SCS Entropy","u":"/standards/iaas/scs-0101","b":["Standards","Standards","IaaS","scs-0101"]},{"i":3409,"t":"scs-0102: SCS Image Metadata","u":"/standards/iaas/scs-0102","b":["Standards","Standards","IaaS","scs-0102"]},{"i":3413,"t":"scs-0104: SCS Standard Images","u":"/standards/iaas/scs-0104","b":["Standards","Standards","IaaS","scs-0104"]},{"i":3417,"t":"scs-0103: SCS Standard Flavors and Properties","u":"/standards/iaas/scs-0103","b":["Standards","Standards","IaaS","scs-0103"]},{"i":3419,"t":"scs-0111: Decisions for the Volume Type Standard","u":"/standards/iaas/scs-0111","b":["Standards","Standards","IaaS","scs-0111"]},{"i":3421,"t":"scs-0112: SONiC Support in SCS","u":"/standards/iaas/scs-0112","b":["Standards","Standards","IaaS","scs-0112"]},{"i":3423,"t":"scs-0113: Security Groups Decision Record","u":"/standards/iaas/scs-0113","b":["Standards","Standards","IaaS","scs-0113"]},{"i":3425,"t":"scs-0114: SCS Volume Types","u":"/standards/iaas/scs-0114","b":["Standards","Standards","IaaS","scs-0114"]},{"i":3427,"t":"scs-0115: Default Rules for Security Groups","u":"/standards/iaas/scs-0115","b":["Standards","Standards","IaaS","scs-0115"]},{"i":3429,"t":"scs-0110: SSD Flavors","u":"/standards/iaas/scs-0110","b":["Standards","Standards","IaaS","scs-0110"]},{"i":3431,"t":"scs-0118: SCS Taxonomy of Failsafe Levels","u":"/standards/iaas/scs-0118","b":["Standards","Standards","IaaS","scs-0118"]},{"i":3435,"t":"scs-0117: Volume Backup Functionality","u":"/standards/iaas/scs-0117","b":["Standards","Standards","IaaS","scs-0117"]},{"i":3437,"t":"scs-0116: SCS Key Manager Standard","u":"/standards/iaas/scs-0116","b":["Standards","Standards","IaaS","scs-0116"]},{"i":3441,"t":"scs-0119: Replacement of the deprecated ceph-ansible tool","u":"/standards/iaas/scs-0119","b":["Standards","Standards","IaaS","scs-0119"]},{"i":3443,"t":"scs-0120: Cluster-API images","u":"/standards/iaas/scs-0120","b":["Standards","Standards","IaaS","scs-0120"]},{"i":3445,"t":"scs-0121: SCS Availability Zones","u":"/standards/iaas/scs-0121","b":["Standards","Standards","IaaS","scs-0121"]},{"i":3449,"t":"scs-0122: End-to-End Encryption between Customer Workloads","u":"/standards/iaas/scs-0122","b":["Standards","Standards","IaaS","scs-0122"]},{"i":3451,"t":"scs-0123: Mandatory and Supported IaaS Services","u":"/standards/iaas/scs-0123","b":["Standards","Standards","IaaS","scs-0123"]},{"i":3453,"t":"scs-0124: Standard for the security of IaaS service software","u":"/standards/iaas/scs-0124","b":["Standards","Standards","IaaS","scs-0124"]},{"i":3457,"t":"scs-0125: Secure Connections","u":"/standards/iaas/scs-0125","b":["Standards","Standards","IaaS","scs-0125"]},{"i":3459,"t":"scs-0300: Requirements for SSO identity federation","u":"/standards/iam/scs-0300","b":["Standards","Standards","IAM","scs-0300"]},{"i":3461,"t":"scs-0302: Domain Manager configuration for Keystone","u":"/standards/iam/scs-0302","b":["Standards","Standards","IAM","scs-0302"]},{"i":3465,"t":"scs-0301: Naming for domains/groups/roles/project when onboarding new customers","u":"/standards/iam/scs-0301","b":["Standards","Standards","IAM","scs-0301"]},{"i":3467,"t":"KaaS Standards","u":"/standards/kaas/","b":["Standards","Standards","KaaS"]},{"i":3469,"t":"IAM Standards","u":"/standards/iam/","b":["Standards","Standards","IAM"]},{"i":3471,"t":"scs-0200: Using Sonobuoy for KaaS conformance tests","u":"/standards/kaas/scs-0200","b":["Standards","Standards","KaaS","scs-0200"]},{"i":3473,"t":"scs-0211: SCS KaaS default storage class","u":"/standards/kaas/scs-0211","b":["Standards","Standards","KaaS","scs-0211"]},{"i":3477,"t":"scs-0210: SCS K8S Version Policy","u":"/standards/kaas/scs-0210","b":["Standards","Standards","KaaS","scs-0210"]},{"i":3481,"t":"scs-0212: Requirements for container registries","u":"/standards/kaas/scs-0212","b":["Standards","Standards","KaaS","scs-0212"]},{"i":3483,"t":"scs-0213: Kubernetes Nodes Anti Affinity","u":"/standards/kaas/scs-0213","b":["Standards","Standards","KaaS","scs-0213"]},{"i":3485,"t":"scs-0214: Kubernetes Node Distribution and Availability","u":"/standards/kaas/scs-0214","b":["Standards","Standards","KaaS","scs-0214"]},{"i":3489,"t":"scs-0215: Robustness features for Kubernetes clusters","u":"/standards/kaas/scs-0215","b":["Standards","Standards","KaaS","scs-0215"]},{"i":3491,"t":"scs-0216: Requirements for testing cluster-stacks","u":"/standards/kaas/scs-0216","b":["Standards","Standards","KaaS","scs-0216"]},{"i":3493,"t":"scs-0218: Container registry for SCS standard implementation","u":"/standards/kaas/scs-0218","b":["Standards","Standards","KaaS","scs-0218"]},{"i":3495,"t":"scs-0219: KaaS Networking Standard","u":"/standards/kaas/scs-0219","b":["Standards","Standards","KaaS","scs-0219"]},{"i":3499,"t":"scs-0217: Kubernetes cluster hardening","u":"/standards/kaas/scs-0217","b":["Standards","Standards","KaaS","scs-0217"]},{"i":3501,"t":"Ops Standards","u":"/standards/ops/","b":["Standards","Standards","Ops"]},{"i":3503,"t":"scs-0400: Status Page create decision","u":"/standards/ops/scs-0400","b":["Standards","Standards","Ops","scs-0400"]},{"i":3505,"t":"scs-0401: Status page reference implementation decision","u":"/standards/ops/scs-0401","b":["Standards","Standards","Ops","scs-0401"]},{"i":3507,"t":"scs-0402: Status page OpenAPI decision","u":"/standards/ops/scs-0402","b":["Standards","Standards","Ops","scs-0402"]},{"i":3509,"t":"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer","u":"/standards/ops/scs-0403","b":["Standards","Standards","Ops","scs-0403"]},{"i":3511,"t":"scs-0411: Push-based approach for providing usage data","u":"/standards/ops/scs-0411","b":["Standards","Standards","Ops","scs-0411"]},{"i":3513,"t":"scs-0410: Gnocchi as database for metering","u":"/standards/ops/scs-0410","b":["Standards","Standards","Ops","scs-0410"]},{"i":3515,"t":"scs-0412: Exposition of IaaS metering data as JSON","u":"/standards/ops/scs-0412","b":["Standards","Standards","Ops","scs-0412"]},{"i":3517,"t":"Sovereign Cloud Standards","u":"/standards/scs-0001-v1-sovereign-cloud-standards","b":["Standards","Standards","Global","scs-0001"]},{"i":3552,"t":"Standards, Docs and Organisation","u":"/standards/scs-0002-v1-standards-docs-org","b":["Standards","Standards","Global","scs-0002"]},{"i":3559,"t":"SCS Documentation structure","u":"/standards/scs-0002-v2-standards-docs-org","b":["Standards","Standards","Global","scs-0002"]},{"i":3580,"t":"Sovereign Cloud Standards YAML","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","b":["Standards","Standards","Global","scs-0003"]},{"i":3619,"t":"Governance of the SCS community","u":"/standards/scs-0005-v1-project-governance","b":["Standards","Standards","Global","scs-0005"]},{"i":3649,"t":"SCS Flavor Naming Standard","u":"/standards/scs-0100-v1-flavor-naming","b":["Standards","Standards","IaaS","scs-0100"]},{"i":3686,"t":"SCS Flavor Naming Standard","u":"/standards/scs-0100-v3-flavor-naming","b":["Standards","Standards","IaaS","scs-0100"]},{"i":3725,"t":"Regulations for achieving SCS-compatible certification","u":"/standards/scs-0004-v1-achieving-certification","b":["Standards","Standards","Global","scs-0004"]},{"i":3736,"t":"SCS Flavor Naming Standard: Implementation and Testing Notes","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","b":["Standards","Standards","IaaS","scs-0100"]},{"i":3754,"t":"SCS Entropy","u":"/standards/scs-0101-v1-entropy","b":["Standards","Standards","IaaS","scs-0101"]},{"i":3773,"t":"SCS Flavor Naming Standard","u":"/standards/scs-0100-v2-flavor-naming","b":["Standards","Standards","IaaS","scs-0100"]},{"i":3818,"t":"SCS Image Metadata","u":"/standards/scs-0102-v1-image-metadata","b":["Standards","Standards","IaaS","scs-0102"]},{"i":3838,"t":"SCS Image Metadata: Implementation and Testing Notes","u":"/standards/scs-0102-w1-image-metadata-implementation-testing","b":["Standards","Standards","IaaS","scs-0102"]},{"i":3848,"t":"SCS Entropy: Implementation and Testing Notes","u":"/standards/scs-0101-w1-entropy-implementation-testing","b":["Standards","Standards","IaaS","scs-0101"]},{"i":3862,"t":"SCS Standard Images","u":"/standards/scs-0104-v1-standard-images","b":["Standards","Standards","IaaS","scs-0104"]},{"i":3886,"t":"SCS Standard Flavors and Properties","u":"/standards/scs-0103-v1-standard-flavors","b":["Standards","Standards","IaaS","scs-0103"]},{"i":3911,"t":"SCS Standard Images: Implementation Notes","u":"/standards/scs-0104-w1-standard-images-implementation","b":["Standards","Standards","IaaS","scs-0104"]},{"i":3921,"t":"SSD Flavors","u":"/standards/scs-0110-v1-ssd-flavors","b":["Standards","Standards","IaaS","scs-0110"]},{"i":3939,"t":"Decisions for the Volume Type Standard","u":"/standards/scs-0111-v1-volume-type-decisions","b":["Standards","Standards","IaaS","scs-0111"]},{"i":3954,"t":"SONiC Support in SCS","u":"/standards/scs-0112-v1-sonic","b":["Standards","Standards","IaaS","scs-0112"]},{"i":3976,"t":"Security Groups Decision Record","u":"/standards/scs-0113-v1-security-groups-decision-record","b":["Standards","Standards","IaaS","scs-0113"]},{"i":4003,"t":"SCS Volume Types","u":"/standards/scs-0114-v1-volume-type-standard","b":["Standards","Standards","IaaS","scs-0114"]},{"i":4035,"t":"Default Rules for Security Groups","u":"/standards/scs-0115-v1-default-rules-for-security-groups","b":["Standards","Standards","IaaS","scs-0115"]},{"i":4058,"t":"SCS Key Manager Standard: Implementation and Testing Notes","u":"/standards/scs-0116-w1-key-manager-implementation-testing","b":["Standards","Standards","IaaS","scs-0116"]},{"i":4071,"t":"SCS Key Manager Standard","u":"/standards/scs-0116-v1-key-manager-standard","b":["Standards","Standards","IaaS","scs-0116"]},{"i":4092,"t":"SCS Taxonomy of Failsafe Levels","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","b":["Standards","Standards","IaaS","scs-0118"]},{"i":4114,"t":"Volume Backup Functionality","u":"/standards/scs-0117-v1-volume-backup-service","b":["Standards","Standards","IaaS","scs-0117"]},{"i":4131,"t":"SCS Taxonomy of Failsafe Levels: Examples of Failure Cases and their impact on IaaS and KaaS resources","u":"/standards/scs-0118-w1-example-impacts-of-failure-scenarios","b":["Standards","Standards","IaaS","scs-0118"]},{"i":4140,"t":"Replacement of the deprecated ceph-ansible tool","u":"/standards/scs-0119-v1-rook-decision","b":["Standards","Standards","IaaS","scs-0119"]},{"i":4151,"t":"SCS Availability Zones","u":"/standards/scs-0121-v1-Availability-Zones-Standard","b":["Standards","Standards","IaaS","scs-0121"]},{"i":4174,"t":"SCS Availability Zones: Implementation and Testing Notes","u":"/standards/scs-0121-w1-Availability-Zones-Standard","b":["Standards","Standards","IaaS","scs-0121"]},{"i":4183,"t":"Cluster-API images","u":"/standards/scs-0120-v1-capi-images","b":["Standards","Standards","IaaS","scs-0120"]},{"i":4196,"t":"Mandatory and Supported IaaS Services","u":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","b":["Standards","Standards","IaaS","scs-0123"]},{"i":4213,"t":"_End-to-End Encryption between Customer Workloads_","u":"/standards/scs-0122-v1-node-to-node-encryption","b":["Standards","Standards","IaaS","scs-0122"]},{"i":4247,"t":"Standard for the security of IaaS service software","u":"/standards/scs-0124-v1-security-of-iaas-service-software","b":["Standards","Standards","IaaS","scs-0124"]},{"i":4264,"t":"SCS Standard for the security of IaaS service software: Implementation and Testing Notes","u":"/standards/scs-0124-w1-security-of-iaas-service-software","b":["Standards","Standards","IaaS","scs-0124"]},{"i":4271,"t":"Using Sonobuoy for KaaS conformance tests","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","b":["Standards","Standards","KaaS","scs-0200"]},{"i":4292,"t":"Secure Connections","u":"/standards/scs-0125-v1-secure-connections","b":["Standards","Standards","IaaS","scs-0125"]},{"i":4338,"t":"SCS K8S Version Policy for new Kubernetes versions","u":"/standards/scs-0210-v1-k8s-new-version-policy","b":["Standards","Standards","KaaS","scs-0210"]},{"i":4349,"t":"SCS K8S Version Policy","u":"/standards/scs-0210-v2-k8s-version-policy","b":["Standards","Standards","KaaS","scs-0210"]},{"i":4360,"t":"SCS K8S Version Policy: Implementation and Testing Notes","u":"/standards/scs-0210-w1-k8s-version-policy-implementation-testing","b":["Standards","Standards","KaaS","scs-0210"]},{"i":4368,"t":"SCS KaaS default storage class","u":"/standards/scs-0211-v2-kaas-default-storage-class","b":["Standards","Standards","KaaS","scs-0211"]},{"i":4383,"t":"SCS KaaS default storage class: Implementation and Testing Notes","u":"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing","b":["Standards","Standards","KaaS","scs-0211"]},{"i":4393,"t":"SCS KaaS default storage class","u":"/standards/scs-0211-v1-kaas-default-storage-class","b":["Standards","Standards","KaaS","scs-0211"]},{"i":4408,"t":"Requirements for container registries","u":"/standards/scs-0212-v1-requirements-for-container-registries","b":["Standards","Standards","KaaS","scs-0212"]},{"i":4425,"t":"Kubernetes Nodes Anti Affinity","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","b":["Standards","Standards","KaaS","scs-0213"]},{"i":4438,"t":"Kubernetes Node Distribution and Availability","u":"/standards/scs-0214-v1-k8s-node-distribution","b":["Standards","Standards","KaaS","scs-0214"]},{"i":4449,"t":"Kubernetes Node Distribution and Availability","u":"/standards/scs-0214-v2-k8s-node-distribution","b":["Standards","Standards","KaaS","scs-0214"]},{"i":4462,"t":"Kubernetes Node Distribution and Availability: Implementation and Testing Notes","u":"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing","b":["Standards","Standards","KaaS","scs-0214"]},{"i":4469,"t":"Robustness features for Kubernetes clusters","u":"/standards/scs-0215-v1-robustness-features","b":["Standards","Standards","KaaS","scs-0215"]},{"i":4500,"t":"Requirements for testing cluster-stacks","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","b":["Standards","Standards","KaaS","scs-0216"]},{"i":4523,"t":"Kubernetes cluster hardening","u":"/standards/scs-0217-v1-cluster-hardening","b":["Standards","Standards","KaaS","scs-0217"]},{"i":4552,"t":"Container registry for SCS standard implementation","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","b":["Standards","Standards","KaaS","scs-0218"]},{"i":4567,"t":"KaaS Networking Standard: Implementation Notes","u":"/standards/scs-0219-w1-kaas-networking","b":["Standards","Standards","KaaS","scs-0219"]},{"i":4570,"t":"KaaS Networking Standard","u":"/standards/scs-0219-v1-kaas-networking","b":["Standards","Standards","KaaS","scs-0219"]},{"i":4585,"t":"Requirements for SSO identity federation","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","b":["Standards","Standards","IAM","scs-0300"]},{"i":4602,"t":"Domain Manager configuration for Keystone","u":"/standards/scs-0302-v1-domain-manager-role","b":["Standards","Standards","IAM","scs-0302"]},{"i":4635,"t":"Naming for domains/groups/roles/project when onboarding new customers","u":"/standards/scs-0301-v1-naming-conventions","b":["Standards","Standards","IAM","scs-0301"]},{"i":4652,"t":"Status Page create decision","u":"/standards/scs-0400-v1-status-page-create-decision","b":["Standards","Standards","Ops","scs-0400"]},{"i":4663,"t":"Domain Manager implementation notes","u":"/standards/scs-0302-w1-domain-manager-implementation-notes","b":["Standards","Standards","IAM","scs-0302"]},{"i":4672,"t":"Status page reference implementation decision","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","b":["Standards","Standards","Ops","scs-0401"]},{"i":4682,"t":"Status page OpenAPI decision","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","b":["Standards","Standards","Ops","scs-0402"]},{"i":4720,"t":"Architecture for the Cloud Service provider Observability System for the KaaS Layer","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","b":["Standards","Standards","Ops","scs-0403"]},{"i":4734,"t":"Gnocchi as database for metering","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","b":["Standards","Standards","Ops","scs-0410"]},{"i":4753,"t":"Push-based approach for providing usage data","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","b":["Standards","Standards","Ops","scs-0411"]},{"i":4772,"t":"SCS-compatible IaaS","u":"/standards/scs-compatible-iaas","b":["Standards","Certification","Scopes and Versions"]},{"i":4774,"t":"SCS-compatible KaaS","u":"/standards/scs-compatible-kaas","b":["Standards","Certification","Scopes and Versions"]},{"i":4776,"t":"_Descriptive title_","u":"/standards/scs-XXXX-vN-decision-record-template","b":["Standards"]},{"i":4789,"t":"Exposition of IaaS metering data as JSON","u":"/standards/scs-0412-v1-metering-json","b":["Standards","Standards","Ops","scs-0412"]},{"i":4806,"t":"_Descriptive title_","u":"/standards/scs-XXXX-vN-standard-template","b":["Standards"]},{"i":4825,"t":"Overview","u":"/standards/standards/overview","b":["Standards","Standards"]},{"i":4827,"t":"Introduction","u":"/user-docs/","b":["For Users"]},{"i":4830,"t":"Configuration","u":"/user-docs/application-examples/opendesk-on-scs/configuration","b":["For Users","Application Examples","OpenDesk on SCS"]},{"i":4836,"t":"Contribute","u":"/user-docs/application-examples/opendesk-on-scs/contribute","b":["For Users","Application Examples","OpenDesk on SCS"]},{"i":4838,"t":"Overview","u":"/user-docs/application-examples/opendesk-on-scs/overview","b":["For Users","Application Examples","OpenDesk on SCS"]},{"i":4840,"t":"Getting started: Deployment from a local machine","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","b":["For Users","Application Examples","OpenDesk on SCS"]},{"i":4860,"t":"Quickstart","u":"/user-docs/application-examples/opendesk-on-scs/quickstart","b":["For Users","Application Examples","OpenDesk on SCS"]},{"i":4862,"t":"User import","u":"/user-docs/application-examples/opendesk-on-scs/user-import","b":["For Users","Application Examples","OpenDesk on SCS"]},{"i":4864,"t":"Requirements","u":"/user-docs/application-examples/opendesk-on-scs/requirements","b":["For Users","Application Examples","OpenDesk on SCS"]}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/1",[]],["t/2",[0,5.545,1,5.545,2,5.545]],["t/4",[]],["t/5",[3,3.928]],["t/8",[4,5.513,5,4.077]],["t/16",[6,2.726,7,3.49,8,3.29,9,3.922]],["t/34",[10,4.127,11,4.127,12,3.42]],["t/42",[10,2.626,11,2.626,13,3.529,14,3.214,15,3.529,16,2.626,17,3.529]],["t/50",[10,4.127,11,4.127,18,5.545]],["t/57",[19,7.763]],["t/69",[4,4.726,20,4.289,21,4.289]],["t/71",[20,5.004,22,5.513]],["t/73",[20,5.004,23,4.387]],["t/75",[20,5.004,24,4.077]],["t/77",[20,5.004,25,2.868]],["t/79",[26,5.23,27,4.815]],["t/81",[26,5.23,28,4.077]],["t/83",[26,5.23,29,5.893]],["t/85",[26,5.23,30,5.893]],["t/87",[31,5.545,32,4.726,33,2.926]],["t/100",[23,3.76,34,5.545,35,5.051]],["t/116",[33,3.414,36,6.469]],["t/124",[37,7.072]],["t/137",[38,7.763]],["t/144",[33,2.926,39,3.989,40,5.051]],["t/164",[23,3.76,41,5.545,42,5.545]],["t/168",[43,5.051,44,5.545,45,1.47]],["t/186",[46,6.469,47,6.469]],["t/200",[48,5.545,49,5.545,50,4.726]],["t/202",[51,5.545,52,5.545,53,5.545]],["t/248",[7,3.102,16,3.21,43,3.929,54,3.21,55,4.313]],["t/252",[56,7.763]],["t/256",[57,6.469,58,6.469]],["t/259",[59,6.469,60,6.469]],["t/261",[61,7.072]],["t/265",[62,7.763]],["t/267",[63,6.276]],["t/274",[23,3.76,45,1.47,64,5.051]],["t/276",[7,4.654,23,4.387]],["t/278",[6,2.423,33,2.276,45,1.143,65,4.313,66,4.313]],["t/296",[6,2.423,33,2.276,45,1.143,67,3.676,68,2.465]],["t/310",[45,1.47,69,4.483,70,4.127]],["t/316",[12,2.66,70,3.21,71,3.336,72,4.313,73,3.676]],["t/330",[74,6.004]],["t/352",[33,2.926,63,4.483,75,3.868]],["t/369",[27,4.127,74,4.289,76,4.483]],["t/381",[77,2.732,78,3.287,79,4.289]],["t/383",[79,4.289,80,3.76,81,3.351]],["t/385",[75,3.384,79,3.753,82,4.852,83,4.852]],["t/398",[3,3.928]],["t/416",[78,3.287,79,4.289,84,5.051]],["t/418",[78,2.876,85,4.852,86,4.42,87,3.922]],["t/428",[88,6.004]],["t/435",[89,5.004,90,5.893]],["t/436",[91,5.006]],["t/443",[92,7.763]],["t/457",[93,6.616]],["t/466",[10,4.815,11,4.815]],["t/476",[77,2.732,93,4.726,94,5.545]],["t/478",[79,5.004,95,5.513]],["t/480",[96,6.616]],["t/482",[93,4.726,97,3.76,98,4.726]],["t/494",[99,7.763]],["t/499",[3,3.928]],["t/501",[100,4.893]],["t/503",[7,4.654,33,3.414]],["t/515",[96,6.616]],["t/519",[90,5.893,101,6.469]],["t/531",[3,3.928]],["t/552",[102,4.692]],["t/558",[6,3.116,7,3.989,103,4.726]],["t/571",[100,4.893]],["t/591",[23,3.76,103,4.726,104,4.726]],["t/639",[97,4.387,103,5.513]],["t/656",[10,4.815,11,4.815]],["t/662",[3,3.928]],["t/669",[100,4.893]],["t/684",[105,6.469,106,4.512]],["t/695",[107,5.004,108,6.469]],["t/711",[109,7.763]],["t/727",[110,5.778]],["t/740",[111,6.469,112,6.469]],["t/742",[45,1.715,106,4.512]],["t/748",[100,4.893]],["t/754",[95,6.616]],["t/756",[113,5.513,114,4.077]],["t/758",[3,3.928]],["t/760",[114,4.077,115,5.23]],["t/762",[33,3.414,116,5.893]],["t/764",[117,6.276]],["t/766",[118,7.072]],["t/768",[119,7.763]],["t/770",[120,5.545,121,5.545,122,5.545]],["t/805",[3,3.928]],["t/807",[123,7.072]],["t/809",[124,7.763]],["t/855",[125,5.778]],["t/856",[77,3.188,81,3.91]],["t/881",[77,2.732,81,3.351,126,5.051]],["t/888",[77,3.188,127,4.171]],["t/899",[77,3.188,128,5.893]],["t/921",[12,2.394,24,2.446,129,3.308,130,3.308,131,3.138,132,3.308]],["t/981",[9,5.23,77,3.188]],["t/996",[77,3.188,133,5.893]],["t/997",[134,5.513,135,5.893]],["t/1008",[33,4.097]],["t/1010",[33,3.414,86,5.893]],["t/1023",[136,7.763]],["t/1053",[137,6.616]],["t/1055",[21,5.004,78,3.835]],["t/1060",[138,4.602]],["t/1063",[139,7.763]],["t/1066",[140,7.072]],["t/1069",[141,6.616]],["t/1071",[12,4.789]],["t/1082",[142,7.072]],["t/1084",[143,7.763]],["t/1086",[16,4.127,144,5.545,145,5.545]],["t/1089",[16,4.127,146,4.726,147,5.545]],["t/1093",[148,7.763]],["t/1095",[78,3.835,104,5.513]],["t/1102",[113,4.726,149,5.545,150,5.545]],["t/1122",[78,3.835,80,4.387]],["t/1129",[76,5.23,78,3.835]],["t/1136",[97,4.387,151,5.893]],["t/1138",[33,3.414,102,3.91]],["t/1139",[152,7.763]],["t/1141",[54,5.778]],["t/1143",[153,7.763]],["t/1152",[154,7.763]],["t/1154",[5,4.893]],["t/1160",[138,4.602]],["t/1192",[155,6.469,156,6.469]],["t/1200",[157,7.763]],["t/1202",[158,7.763]],["t/1204",[75,5.415]],["t/1206",[159,7.763]],["t/1215",[102,3.91,160,6.469]],["t/1239",[161,7.763]],["t/1255",[77,3.825]],["t/1264",[162,5.415]],["t/1276",[163,7.763]],["t/1278",[164,7.763]],["t/1280",[165,7.763]],["t/1282",[166,7.072]],["t/1286",[104,6.616]],["t/1288",[167,7.763]],["t/1290",[12,4.789]],["t/1307",[168,7.763]],["t/1309",[169,7.763]],["t/1317",[140,7.072]],["t/1319",[170,7.763]],["t/1321",[171,6.276]],["t/1326",[172,7.763]],["t/1328",[173,7.072]],["t/1332",[174,7.763]],["t/1334",[175,7.072]],["t/1336",[176,7.763]],["t/1341",[177,7.763]],["t/1355",[178,7.072]],["t/1386",[39,2.327,102,1.955,110,2.407,138,1.917,179,2.502,180,2.407,181,2.256,182,2.256]],["t/1392",[71,3.336,138,2.556,180,3.21,181,3.008,182,3.008]],["t/1444",[5,4.893]],["t/1446",[183,7.763]],["t/1448",[184,7.072]],["t/1452",[185,7.763]],["t/1454",[186,7.072]],["t/1456",[187,7.763]],["t/1458",[188,6.276]],["t/1459",[33,3.414,106,4.512]],["t/1461",[80,3.29,189,4.852,190,4.852,191,4.852]],["t/1467",[77,3.825]],["t/1481",[192,7.072]],["t/1483",[39,2.327,106,2.256,110,2.407,138,1.917,179,2.502,180,2.407,181,2.256,182,2.256]],["t/1494",[8,4.387,193,5.893]],["t/1496",[194,7.763]],["t/1502",[138,4.602]],["t/1510",[5,4.893]],["t/1512",[195,6.004]],["t/1514",[196,4.789]],["t/1518",[162,5.415]],["t/1520",[16,4.127,24,3.495,197,4.726]],["t/1522",[12,4.789]],["t/1524",[71,3.336,138,2.556,180,3.21,181,3.008,182,3.008]],["t/1532",[33,3.414,198,5.893]],["t/1548",[39,2.538,71,2.729,110,2.626,138,2.092,179,2.729,181,2.461,182,2.461]],["t/1550",[195,6.004]],["t/1567",[138,4.602]],["t/1653",[77,3.825]],["t/1654",[199,7.763]],["t/1666",[200,7.763]],["t/1676",[]],["t/1684",[201,7.763]],["t/1689",[197,6.616]],["t/1699",[162,5.415]],["t/1705",[12,4.789]],["t/1714",[166,7.072]],["t/1721",[173,7.072]],["t/1724",[171,6.276]],["t/1726",[178,7.072]],["t/1741",[175,7.072]],["t/1746",[77,3.188,127,4.171]],["t/1757",[77,3.188,81,3.91]],["t/1782",[125,5.778]],["t/1783",[77,3.188,128,5.893]],["t/1805",[77,2.732,81,3.351,126,5.051]],["t/1812",[12,2.394,24,2.446,129,3.308,130,3.308,131,3.138,132,3.308]],["t/1872",[9,5.23,77,3.188]],["t/1887",[77,3.188,133,5.893]],["t/1888",[134,5.513,135,5.893]],["t/1899",[71,3.336,138,2.556,180,3.21,181,3.008,182,3.008]],["t/1978",[39,2.327,97,2.193,110,2.407,138,1.917,179,2.502,180,2.407,181,2.256,182,2.256]],["t/1999",[33,4.097]],["t/2000",[123,5.051,202,5.545,203,5.051]],["t/2022",[33,3.414,64,5.893]],["t/2024",[8,4.387,193,5.893]],["t/2053",[91,5.006]],["t/2070",[204,7.763]],["t/2072",[7,4.654,33,3.414]],["t/2080",[33,3.414,40,5.893]],["t/2111",[63,5.23,205,6.469]],["t/2133",[33,3.414,96,5.513]],["t/2135",[138,4.602]],["t/2140",[12,4.789]],["t/2147",[179,4.289,181,3.868,182,3.868]],["t/2153",[77,3.825]],["t/2156",[33,3.414,95,5.513]],["t/2158",[138,4.602]],["t/2162",[184,7.072]],["t/2166",[195,6.004]],["t/2168",[16,4.127,24,3.495,197,4.726]],["t/2170",[77,3.825]],["t/2172",[162,5.415]],["t/2174",[192,7.072]],["t/2230",[12,4.789]],["t/2232",[33,3.414,75,4.512]],["t/2233",[12,2.993,110,3.611,206,4.852,207,4.852]],["t/2259",[12,4.789]],["t/2260",[37,4.42,81,2.932,208,4.852,209,4.852]],["t/2271",[210,7.763]],["t/2282",[97,3.29,102,2.932,211,3.128,212,3.611]],["t/2296",[97,2.632,102,2.346,211,2.503,212,2.889,213,3.881,214,3.881]],["t/2310",[117,6.276]],["t/2312",[215,7.763]],["t/2314",[118,7.072]],["t/2316",[75,3.868,107,4.289,216,4.127]],["t/2361",[162,5.415]],["t/2363",[217,6.004]],["t/2365",[45,1.143,69,3.487,70,3.21,74,3.336,77,2.125]],["t/2383",[75,3.868,107,4.289,216,4.127]],["t/2428",[23,2.632,70,2.889,142,5.408,218,3.881,219,3.881]],["t/2432",[45,1.029,102,2.346,106,2.707,188,3.138,220,3.536,221,3.881]],["t/2434",[77,2.391,220,4.42,222,3.922,223,3.922]],["t/2470",[3,3.928]],["t/2472",[100,4.893]],["t/2483",[3,3.928]],["t/2496",[75,2.461,97,2.393,198,3.214,224,3.529,225,3.529,226,3.529,227,3.529]],["t/2523",[3,3.928]],["t/2546",[125,4.815,228,5.893]],["t/2560",[33,3.414,100,4.077]],["t/2570",[3,3.928]],["t/2587",[125,4.815,228,5.893]],["t/2599",[4,4.726,21,4.289,229,5.545]],["t/2603",[61,4.42,230,4.852,231,4.852,232,4.852]],["t/2605",[5,3.495,195,4.289,233,5.545]],["t/2607",[141,5.513,234,5.004]],["t/2617",[3,3.928]],["t/2619",[24,3.495,235,3.287,236,5.051]],["t/2627",[237,7.763]],["t/2629",[45,1.715,106,4.512]],["t/2637",[24,3.495,28,3.495,236,5.051]],["t/2650",[100,4.893]],["t/2660",[238,7.763]],["t/2666",[24,3.495,239,3.868,240,3.868]],["t/2677",[24,4.077,63,5.23]],["t/2679",[186,7.072]],["t/2687",[24,3.495,45,1.47,131,4.483]],["t/2710",[195,5.004,241,6.469]],["t/2719",[102,4.692]],["t/2721",[6,2.423,23,2.925,196,2.66,242,4.313,243,4.313]],["t/2750",[88,6.004]],["t/2752",[87,4.483,100,3.495,244,4.726]],["t/2757",[188,5.23,245,5.893]],["t/2793",[3,3.928]],["t/2795",[100,4.893]],["t/2803",[245,7.072]],["t/2817",[114,4.893]],["t/2819",[102,3.351,239,3.868,240,3.868]],["t/2835",[246,6.469,247,6.469]],["t/2837",[248,7.763]],["t/2846",[106,3.008,134,3.676,141,3.676,249,4.313,250,4.313]],["t/2864",[88,6.004]],["t/2866",[24,4.893]],["t/2874",[7,3.49,98,4.135,251,4.852,252,4.852]],["t/2886",[3,3.928]],["t/2895",[100,4.893]],["t/2897",[114,4.893]],["t/2899",[45,1.715,253,6.469]],["t/2901",[3,3.273,137,5.513]],["t/2903",[223,6.276]],["t/2911",[137,6.616]],["t/2913",[254,5.23,255,6.469]],["t/2915",[3,3.928]],["t/2927",[102,4.692]],["t/2933",[88,6.004]],["t/2935",[100,4.893]],["t/2937",[114,4.893]],["t/2939",[3,3.928]],["t/2941",[3,3.928]],["t/2943",[3,3.928]],["t/2945",[12,1.995,24,2.039,33,1.707,129,2.757,130,2.757,131,2.615,132,2.757,256,3.235]],["t/3005",[3,3.928]],["t/3007",[3,3.928]],["t/3009",[3,3.928]],["t/3011",[45,1.143,91,4.145,257,2.31,258,4.313]],["t/3029",[102,3.91,259,5.004]],["t/3041",[45,1.143,91,4.145,116,3.929,257,2.31]],["t/3078",[45,1.143,91,4.145,257,2.31,260,4.313]],["t/3111",[45,1.143,91,4.145,257,2.31,261,4.313]],["t/3145",[45,1.143,91,4.145,257,2.31,262,4.313]],["t/3177",[45,1.143,91,4.145,257,2.31,263,4.313]],["t/3215",[45,1.143,91,4.145,257,2.31,264,4.313]],["t/3273",[45,1.143,91,4.145,257,2.31,265,4.313]],["t/3324",[14,3.929,45,1.143,91,4.145,257,2.31]],["t/3342",[45,1.47,113,4.726,266,5.545]],["t/3353",[3,3.928]],["t/3358",[25,3.442]],["t/3360",[74,6.004]],["t/3362",[54,5.778]],["t/3368",[54,5.778]],["t/3374",[45,1.143,267,4.313,268,4.313,269,4.313,270,4.313]],["t/3385",[271,6.469,272,5.004]],["t/3387",[25,1.912,32,3.676,45,1.143,273,4.313,274,3.929]],["t/3389",[25,2.868,275,6.469]],["t/3391",[8,2.925,25,1.912,45,1.143,276,4.313,277,3.487]],["t/3393",[8,2.632,25,1.721,45,1.029,277,3.138,278,3.881,279,3.536]],["t/3395",[22,3.676,45,1.704,280,4.313,281,3.929]],["t/3397",[25,2.868,28,4.077]],["t/3399",[45,1.462,54,2.626,282,3.529,283,3.214,284,3.214,285,2.853]],["t/3401",[25,1.721,45,1.573,127,2.503,286,3.881,287,2.792]],["t/3405",[45,1.857,288,4.852,289,4.135]],["t/3409",[45,1.704,81,2.607,290,4.313,291,3.676]],["t/3413",[25,1.912,45,1.704,81,2.607,292,4.313]],["t/3417",[25,1.721,45,1.573,127,2.503,293,3.881,294,3.536]],["t/3419",[25,1.721,45,1.029,295,3.881,296,2.564,297,2.889,298,3.138]],["t/3421",[45,1.704,146,3.676,234,3.336,299,4.313]],["t/3423",[45,1.029,211,2.503,212,2.889,296,2.564,300,3.881,301,3.536]],["t/3425",[45,1.704,297,3.21,298,3.487,302,4.313]],["t/3427",[45,1.029,50,3.308,211,2.503,212,2.889,303,3.881,304,2.889]],["t/3429",[45,1.286,127,3.128,305,4.852,306,4.42]],["t/3431",[45,1.573,254,3.138,307,3.881,308,3.308,309,3.308]],["t/3435",[45,1.143,107,3.336,297,3.21,310,4.313,311,3.929]],["t/3437",[25,1.721,45,1.573,77,1.913,312,3.881,313,3.308]],["t/3441",[39,2.538,45,0.935,125,2.626,138,2.092,314,3.529,315,3.214,316,3.214]],["t/3443",[21,3.336,45,1.143,78,2.556,81,2.607,317,4.313]],["t/3445",[45,1.704,318,4.313,319,3.102,320,3.676]],["t/3449",[45,0.857,84,2.946,321,3.235,322,4.69,323,2.946,324,2.946,325,2.615]],["t/3451",[5,2.446,28,2.446,45,1.029,234,3.002,326,3.881,327,3.536]],["t/3453",[5,2.224,25,1.565,28,2.224,45,0.935,115,2.853,211,2.275,328,3.529]],["t/3457",[45,1.286,73,4.135,211,3.128,329,4.852]],["t/3459",[45,1.029,69,3.138,70,2.889,114,2.446,330,3.881,331,3.536]],["t/3461",[45,1.029,77,1.913,102,2.346,171,3.138,222,3.138,332,3.881]],["t/3465",[45,0.935,287,2.538,325,2.853,333,3.529,334,3.214,335,3.214,336,3.007]],["t/3467",[25,2.868,235,3.835]],["t/3469",[25,2.868,29,5.893]],["t/3471",[6,1.983,45,0.935,67,3.007,97,2.393,235,2.092,337,3.529,338,3.214]],["t/3473",[45,1.462,217,2.729,235,2.092,304,2.626,339,3.529,340,2.853]],["t/3477",[45,1.573,272,3.002,341,3.881,342,3.138,343,3.138]],["t/3481",[27,3.21,45,1.143,114,2.718,344,4.313,345,3.487]],["t/3483",[45,1.029,80,2.632,196,2.394,346,3.881,347,3.536,348,3.536]],["t/3485",[45,1.029,80,2.632,196,2.394,319,2.792,349,3.881,350,3.138]],["t/3489",[45,1.029,78,2.301,196,2.394,351,3.881,352,3.536,353,3.536]],["t/3491",[6,2.181,45,1.029,78,2.301,87,3.138,114,2.446,354,3.881]],["t/3493",[25,1.565,27,2.626,45,1.462,68,2.017,345,2.853,355,3.529]],["t/3495",[25,1.912,45,1.143,162,3.008,235,2.556,356,4.313]],["t/3499",[45,1.143,78,2.556,196,2.66,357,4.313,358,3.929]],["t/3501",[25,2.868,30,5.893]],["t/3503",[45,1.029,239,2.707,240,2.707,296,2.564,359,3.881,360,3.536]],["t/3505",[45,0.935,68,2.017,239,2.461,240,2.461,296,2.331,361,3.529,362,3.214]],["t/3507",[45,1.029,239,2.707,240,2.707,296,2.564,363,3.881,364,3.536]],["t/3509",[5,1.747,8,1.88,45,0.735,76,2.241,89,2.144,117,2.241,235,1.643,244,2.363,365,2.772,366,2.525]],["t/3511",[45,0.857,89,2.502,216,2.407,223,2.615,367,3.235,368,2.946,369,2.946,370,2.946]],["t/3513",[45,1.143,259,3.336,371,4.313,372,3.929,373,3.929]],["t/3515",[28,2.224,45,0.935,216,2.626,259,2.729,374,3.529,375,3.214,376,3.214]],["t/3517",[8,3.76,25,2.459,277,4.483]],["t/3552",[25,2.459,32,4.726,274,5.051]],["t/3559",[23,3.76,35,5.051,45,1.47]],["t/3580",[8,3.29,25,2.151,277,3.922,279,4.42]],["t/3619",[22,4.726,45,1.47,281,5.051]],["t/3649",[25,2.151,45,1.286,127,3.128,287,3.49]],["t/3686",[25,2.151,45,1.286,127,3.128,287,3.49]],["t/3725",[45,1.143,54,3.21,283,3.929,284,3.929,285,3.487]],["t/3736",[6,1.983,25,1.565,45,0.935,68,2.017,127,2.275,257,1.89,287,2.538]],["t/3754",[45,1.715,289,5.513]],["t/3773",[25,2.151,45,1.286,127,3.128,287,3.49]],["t/3818",[45,1.47,81,3.351,291,4.726]],["t/3838",[6,2.181,45,1.029,68,2.219,81,2.346,257,2.079,291,3.308]],["t/3848",[6,2.423,45,1.143,68,2.465,257,2.31,289,3.676]],["t/3862",[25,2.459,45,1.47,81,3.351]],["t/3886",[25,2.151,45,1.286,127,3.128,294,4.42]],["t/3911",[25,1.912,45,1.143,68,2.465,81,2.607,257,2.31]],["t/3921",[127,4.171,306,5.893]],["t/3939",[25,2.151,296,3.205,297,3.611,298,3.922]],["t/3954",[45,1.47,146,4.726,234,4.289]],["t/3976",[211,3.128,212,3.611,296,3.205,301,4.42]],["t/4003",[45,1.47,297,4.127,298,4.483]],["t/4035",[50,4.135,211,3.128,212,3.611,304,3.611]],["t/4058",[6,1.983,25,1.565,45,0.935,68,2.017,77,1.739,257,1.89,313,3.007]],["t/4071",[25,2.151,45,1.286,77,2.391,313,4.135]],["t/4092",[45,1.286,254,3.922,308,4.135,309,4.135]],["t/4114",[107,4.289,297,4.127,311,5.051]],["t/4131",[9,2.092,28,1.631,45,0.686,151,2.357,188,2.092,235,1.534,254,2.092,308,2.205,309,2.205,377,2.588,378,2.588]],["t/4140",[39,3.102,125,3.21,138,2.556,315,3.929,316,3.929]],["t/4151",[45,1.47,319,3.989,320,4.726]],["t/4174",[6,2.181,45,1.029,68,2.219,257,2.079,319,2.792,320,3.308]],["t/4183",[21,4.289,78,3.287,81,3.351]],["t/4196",[5,3.058,28,3.058,234,3.753,327,4.42]],["t/4213",[322,3.536,323,3.536,324,3.536,325,3.138,379,3.881,380,3.881]],["t/4247",[5,2.718,25,1.912,28,2.718,115,3.487,211,2.781]],["t/4264",[5,1.882,6,1.678,25,1.324,28,1.882,45,0.791,68,1.707,115,2.414,211,1.925,257,1.599]],["t/4271",[6,2.423,67,3.676,97,2.925,235,2.556,338,3.929]],["t/4292",[73,5.513,211,4.171]],["t/4338",[45,0.935,196,2.177,272,4.265,336,3.007,342,2.853,343,2.853]],["t/4349",[45,1.286,272,3.753,342,3.922,343,3.922]],["t/4360",[6,1.983,45,0.935,68,2.017,257,1.89,272,2.729,342,2.853,343,2.853]],["t/4368",[45,1.143,217,3.336,235,2.556,304,3.21,340,3.487]],["t/4383",[6,1.817,45,0.857,68,1.849,217,2.502,235,1.917,257,1.733,304,2.407,340,2.615]],["t/4393",[45,1.143,217,3.336,235,2.556,304,3.21,340,3.487]],["t/4408",[27,4.127,114,3.495,345,4.483]],["t/4425",[80,3.29,196,2.993,347,4.42,348,4.42]],["t/4438",[80,3.29,196,2.993,319,3.49,350,3.922]],["t/4449",[80,3.29,196,2.993,319,3.49,350,3.922]],["t/4462",[6,1.983,68,2.017,80,2.393,196,2.177,257,1.89,319,2.538,350,2.853]],["t/4469",[78,2.876,196,2.993,352,4.42,353,4.42]],["t/4500",[6,2.726,78,2.876,87,3.922,114,3.058]],["t/4523",[78,3.287,196,3.42,358,5.051]],["t/4552",[25,1.912,27,3.21,45,1.143,68,2.465,345,3.487]],["t/4567",[25,1.912,68,2.465,162,3.008,235,2.556,257,2.31]],["t/4570",[25,2.459,162,3.868,235,3.287]],["t/4585",[69,3.922,70,3.611,114,3.058,331,4.42]],["t/4602",[77,2.391,102,2.932,171,3.922,222,3.922]],["t/4635",[287,3.102,325,3.487,334,3.929,335,3.929,336,3.676]],["t/4652",[239,3.384,240,3.384,296,3.205,360,4.42]],["t/4663",[68,2.773,77,2.391,222,3.922,257,2.599]],["t/4672",[68,2.465,239,3.008,240,3.008,296,2.849,362,3.929]],["t/4682",[239,3.384,240,3.384,296,3.205,364,4.42]],["t/4720",[5,2.039,8,2.193,76,2.615,89,2.502,117,2.615,235,1.917,244,2.757,366,2.946]],["t/4734",[259,4.289,372,5.051,373,5.051]],["t/4753",[89,3.002,216,2.889,223,3.138,368,3.536,369,3.536,370,3.536]],["t/4772",[28,3.495,45,1.47,285,4.483]],["t/4774",[45,1.47,235,3.287,285,4.483]],["t/4776",[381,5.893,382,5.893]],["t/4789",[28,2.718,216,3.21,259,3.336,375,3.929,376,3.929]],["t/4806",[381,5.893,382,5.893]],["t/4825",[3,3.928]],["t/4827",[74,6.004]],["t/4830",[102,4.692]],["t/4836",[88,6.004]],["t/4838",[3,3.928]],["t/4840",[10,3.21,11,3.21,98,3.676,106,3.008,203,3.929]],["t/4860",[100,4.893]],["t/4862",[75,4.512,383,6.469]],["t/4864",[114,4.893]]],"invertedIndex":[["",{"_index":16,"t":{"42":{"position":[[36,1]]},"248":{"position":[[32,1]]},"1086":{"position":[[11,1]]},"1089":{"position":[[6,1]]},"1520":{"position":[[8,1]]},"2168":{"position":[[8,1]]}}}],["0",{"_index":258,"t":{"3011":{"position":[[30,1]]}}}],["0001",{"_index":276,"t":{"3391":{"position":[[4,5]]}}}],["0002",{"_index":273,"t":{"3387":{"position":[[4,5]]}}}],["0003",{"_index":278,"t":{"3393":{"position":[[4,5]]}}}],["0004",{"_index":282,"t":{"3399":{"position":[[4,5]]}}}],["0005",{"_index":280,"t":{"3395":{"position":[[4,5]]}}}],["0100",{"_index":286,"t":{"3401":{"position":[[4,5]]}}}],["0101",{"_index":288,"t":{"3405":{"position":[[4,5]]}}}],["0102",{"_index":290,"t":{"3409":{"position":[[4,5]]}}}],["0103",{"_index":293,"t":{"3417":{"position":[[4,5]]}}}],["0104",{"_index":292,"t":{"3413":{"position":[[4,5]]}}}],["0110",{"_index":305,"t":{"3429":{"position":[[4,5]]}}}],["0111",{"_index":295,"t":{"3419":{"position":[[4,5]]}}}],["0112",{"_index":299,"t":{"3421":{"position":[[4,5]]}}}],["0113",{"_index":300,"t":{"3423":{"position":[[4,5]]}}}],["0114",{"_index":302,"t":{"3425":{"position":[[4,5]]}}}],["0115",{"_index":303,"t":{"3427":{"position":[[4,5]]}}}],["0116",{"_index":312,"t":{"3437":{"position":[[4,5]]}}}],["0117",{"_index":310,"t":{"3435":{"position":[[4,5]]}}}],["0118",{"_index":307,"t":{"3431":{"position":[[4,5]]}}}],["0119",{"_index":314,"t":{"3441":{"position":[[4,5]]}}}],["0120",{"_index":317,"t":{"3443":{"position":[[4,5]]}}}],["0121",{"_index":318,"t":{"3445":{"position":[[4,5]]}}}],["0122",{"_index":321,"t":{"3449":{"position":[[4,5]]}}}],["0123",{"_index":326,"t":{"3451":{"position":[[4,5]]}}}],["0124",{"_index":328,"t":{"3453":{"position":[[4,5]]}}}],["0125",{"_index":329,"t":{"3457":{"position":[[4,5]]}}}],["0200",{"_index":337,"t":{"3471":{"position":[[4,5]]}}}],["0210",{"_index":341,"t":{"3477":{"position":[[4,5]]}}}],["0211",{"_index":339,"t":{"3473":{"position":[[4,5]]}}}],["0212",{"_index":344,"t":{"3481":{"position":[[4,5]]}}}],["0213",{"_index":346,"t":{"3483":{"position":[[4,5]]}}}],["0214",{"_index":349,"t":{"3485":{"position":[[4,5]]}}}],["0215",{"_index":351,"t":{"3489":{"position":[[4,5]]}}}],["0216",{"_index":354,"t":{"3491":{"position":[[4,5]]}}}],["0217",{"_index":357,"t":{"3499":{"position":[[4,5]]}}}],["0218",{"_index":355,"t":{"3493":{"position":[[4,5]]}}}],["0219",{"_index":356,"t":{"3495":{"position":[[4,5]]}}}],["0300",{"_index":330,"t":{"3459":{"position":[[4,5]]}}}],["0301",{"_index":333,"t":{"3465":{"position":[[4,5]]}}}],["0302",{"_index":332,"t":{"3461":{"position":[[4,5]]}}}],["0400",{"_index":359,"t":{"3503":{"position":[[4,5]]}}}],["0401",{"_index":361,"t":{"3505":{"position":[[4,5]]}}}],["0402",{"_index":363,"t":{"3507":{"position":[[4,5]]}}}],["0403",{"_index":365,"t":{"3509":{"position":[[4,5]]}}}],["0410",{"_index":371,"t":{"3513":{"position":[[4,5]]}}}],["0411",{"_index":367,"t":{"3511":{"position":[[4,5]]}}}],["0412",{"_index":374,"t":{"3515":{"position":[[4,5]]}}}],["1",{"_index":116,"t":{"762":{"position":[[6,1]]},"3041":{"position":[[30,1]]}}}],["12",{"_index":256,"t":{"2945":{"position":[[53,2]]}}}],["2",{"_index":260,"t":{"3078":{"position":[[30,1]]}}}],["3",{"_index":261,"t":{"3111":{"position":[[30,1]]}}}],["4",{"_index":262,"t":{"3145":{"position":[[30,1]]}}}],["5",{"_index":263,"t":{"3177":{"position":[[30,1]]}}}],["6",{"_index":264,"t":{"3215":{"position":[[30,1]]}}}],["7",{"_index":265,"t":{"3273":{"position":[[30,1]]}}}],["_descript",{"_index":381,"t":{"4776":{"position":[[0,12]]},"4806":{"position":[[0,12]]}}}],["_end",{"_index":379,"t":{"4213":{"position":[[0,4]]}}}],["achiev",{"_index":284,"t":{"3399":{"position":[[26,9]]},"3725":{"position":[[16,9]]}}}],["ad",{"_index":31,"t":{"87":{"position":[[0,6]]}}}],["admin",{"_index":246,"t":{"2835":{"position":[[0,5]]}}}],["affin",{"_index":348,"t":{"3483":{"position":[[32,8]]},"4425":{"position":[[22,8]]}}}],["alertmanag",{"_index":230,"t":{"2603":{"position":[[0,12]]}}}],["ansibl",{"_index":39,"t":{"144":{"position":[[0,7]]},"1386":{"position":[[37,7]]},"1483":{"position":[[42,7]]},"1548":{"position":[[13,7]]},"1978":{"position":[[39,7]]},"3441":{"position":[[45,7]]},"4140":{"position":[[35,7]]}}}],["anti",{"_index":347,"t":{"3483":{"position":[[27,4]]},"4425":{"position":[[17,4]]}}}],["aodh",{"_index":163,"t":{"1276":{"position":[[0,4]]}}}],["api",{"_index":21,"t":{"69":{"position":[[12,3]]},"1055":{"position":[[8,3]]},"2599":{"position":[[8,3]]},"3443":{"position":[[18,3]]},"4183":{"position":[[8,3]]}}}],["appli",{"_index":199,"t":{"1654":{"position":[[0,5]]}}}],["approach",{"_index":370,"t":{"3511":{"position":[[21,8]]},"4753":{"position":[[11,8]]}}}],["architectur",{"_index":117,"t":{"764":{"position":[[0,12]]},"2310":{"position":[[0,12]]},"3509":{"position":[[10,12]]},"4720":{"position":[[0,12]]}}}],["artcodix",{"_index":136,"t":{"1023":{"position":[[0,8]]}}}],["ask",{"_index":121,"t":{"770":{"position":[[11,5]]}}}],["authent",{"_index":247,"t":{"2835":{"position":[[6,14]]}}}],["autom",{"_index":224,"t":{"2496":{"position":[[6,9]]}}}],["avail",{"_index":319,"t":{"3445":{"position":[[14,12]]},"3485":{"position":[[43,12]]},"4151":{"position":[[4,12]]},"4174":{"position":[[4,12]]},"4438":{"position":[[33,12]]},"4449":{"position":[[33,12]]},"4462":{"position":[[33,13]]}}}],["backup",{"_index":107,"t":{"695":{"position":[[0,6]]},"2316":{"position":[[10,7]]},"2383":{"position":[[10,7]]},"3435":{"position":[[17,6]]},"4114":{"position":[[7,6]]}}}],["barbican",{"_index":165,"t":{"1280":{"position":[[0,8]]}}}],["bare",{"_index":190,"t":{"1461":{"position":[[16,4]]}}}],["base",{"_index":369,"t":{"3511":{"position":[[15,5]]},"4753":{"position":[[5,5]]}}}],["bdd",{"_index":242,"t":{"2721":{"position":[[11,3]]}}}],["best",{"_index":213,"t":{"2296":{"position":[[0,4]]}}}],["between",{"_index":324,"t":{"3449":{"position":[[32,7]]},"4213":{"position":[[23,7]]}}}],["bill",{"_index":149,"t":{"1102":{"position":[[9,4]]}}}],["blog",{"_index":1,"t":{"2":{"position":[[6,4]]}}}],["bootstrap",{"_index":187,"t":{"1456":{"position":[[0,9]]}}}],["box",{"_index":193,"t":{"1494":{"position":[[11,3]]},"2024":{"position":[[11,3]]}}}],["branch",{"_index":48,"t":{"200":{"position":[[0,6]]}}}],["case",{"_index":151,"t":{"1136":{"position":[[4,5]]},"4131":{"position":[[53,5]]}}}],["ceilomet",{"_index":164,"t":{"1278":{"position":[[0,10]]}}}],["central",{"_index":4,"t":{"8":{"position":[[0,7]]},"69":{"position":[[4,7]]},"2599":{"position":[[0,7]]}}}],["ceph",{"_index":138,"t":{"1060":{"position":[[0,4]]},"1160":{"position":[[0,4]]},"1386":{"position":[[32,4]]},"1392":{"position":[[0,4]]},"1483":{"position":[[37,4]]},"1502":{"position":[[0,4]]},"1524":{"position":[[0,4]]},"1548":{"position":[[8,4]]},"1567":{"position":[[0,4]]},"1899":{"position":[[0,4]]},"1978":{"position":[[34,4]]},"2135":{"position":[[0,4]]},"2158":{"position":[[0,4]]},"3441":{"position":[[40,4]]},"4140":{"position":[[30,4]]}}}],["certif",{"_index":54,"t":{"248":{"position":[[10,11]]},"1141":{"position":[[0,12]]},"3362":{"position":[[0,13]]},"3368":{"position":[[0,13]]},"3399":{"position":[[51,13]]},"3725":{"position":[[41,13]]}}}],["chat",{"_index":232,"t":{"2603":{"position":[[37,4]]}}}],["check",{"_index":268,"t":{"3374":{"position":[[15,5]]}}}],["checklist",{"_index":53,"t":{"202":{"position":[[19,9]]}}}],["chroni",{"_index":183,"t":{"1446":{"position":[[0,6]]}}}],["ci",{"_index":205,"t":{"2111":{"position":[[5,2]]}}}],["cinder",{"_index":166,"t":{"1282":{"position":[[0,6]]},"1714":{"position":[[0,6]]}}}],["class",{"_index":340,"t":{"3473":{"position":[[35,5]]},"4368":{"position":[[25,5]]},"4383":{"position":[[25,6]]},"4393":{"position":[[25,5]]}}}],["client",{"_index":210,"t":{"2271":{"position":[[0,6]]}}}],["cloud",{"_index":8,"t":{"16":{"position":[[21,5]]},"1494":{"position":[[0,5]]},"2024":{"position":[[0,5]]},"3391":{"position":[[20,5]]},"3393":{"position":[[20,5]]},"3509":{"position":[[31,5]]},"3517":{"position":[[10,5]]},"3580":{"position":[[10,5]]},"4720":{"position":[[21,5]]}}}],["cluster",{"_index":78,"t":{"381":{"position":[[11,7]]},"416":{"position":[[13,7]]},"418":{"position":[[29,7]]},"1055":{"position":[[0,7]]},"1095":{"position":[[0,7]]},"1122":{"position":[[11,7]]},"1129":{"position":[[12,7]]},"3443":{"position":[[10,7]]},"3489":{"position":[[45,8]]},"3491":{"position":[[35,7]]},"3499":{"position":[[21,7]]},"4183":{"position":[[0,7]]},"4469":{"position":[[35,8]]},"4500":{"position":[[25,7]]},"4523":{"position":[[11,7]]}}}],["clusterstack",{"_index":93,"t":{"457":{"position":[[0,12]]},"476":{"position":[[9,12]]},"482":{"position":[[12,13]]}}}],["collabor",{"_index":19,"t":{"57":{"position":[[0,13]]}}}],["common",{"_index":152,"t":{"1139":{"position":[[0,7]]}}}],["commun",{"_index":22,"t":{"71":{"position":[[4,9]]},"3395":{"position":[[32,9]]},"3619":{"position":[[22,9]]}}}],["compat",{"_index":285,"t":{"3399":{"position":[[40,10]]},"3725":{"position":[[30,10]]},"4772":{"position":[[4,10]]},"4774":{"position":[[4,10]]}}}],["complianc",{"_index":267,"t":{"3374":{"position":[[4,10]]}}}],["compon",{"_index":137,"t":{"1053":{"position":[[0,10]]},"2901":{"position":[[0,9]]},"2911":{"position":[[0,10]]}}}],["comput",{"_index":215,"t":{"2312":{"position":[[0,7]]}}}],["concept",{"_index":86,"t":{"418":{"position":[[18,7]]},"1010":{"position":[[0,7]]}}}],["config",{"_index":156,"t":{"1192":{"position":[[4,6]]}}}],["configur",{"_index":102,"t":{"552":{"position":[[0,13]]},"1138":{"position":[[0,13]]},"1215":{"position":[[0,13]]},"1386":{"position":[[0,9]]},"2282":{"position":[[7,9]]},"2296":{"position":[[22,9]]},"2432":{"position":[[14,13]]},"2719":{"position":[[0,13]]},"2819":{"position":[[0,9]]},"2927":{"position":[[0,13]]},"3029":{"position":[[9,13]]},"3461":{"position":[[25,13]]},"4602":{"position":[[15,13]]},"4830":{"position":[[0,13]]}}}],["conform",{"_index":67,"t":{"296":{"position":[[4,11]]},"3471":{"position":[[34,11]]},"4271":{"position":[[24,11]]}}}],["connect",{"_index":73,"t":{"316":{"position":[[32,7]]},"3457":{"position":[[17,11]]},"4292":{"position":[[7,11]]}}}],["consensu",{"_index":255,"t":{"2913":{"position":[[11,10]]}}}],["consider",{"_index":44,"t":{"168":{"position":[[8,14]]}}}],["consol",{"_index":200,"t":{"1666":{"position":[[0,7]]}}}],["contain",{"_index":27,"t":{"79":{"position":[[5,9]]},"369":{"position":[[0,9]]},"3481":{"position":[[27,9]]},"3493":{"position":[[10,9]]},"4408":{"position":[[17,9]]},"4552":{"position":[[0,9]]}}}],["container",{"_index":119,"t":{"768":{"position":[[0,16]]}}}],["continu",{"_index":101,"t":{"519":{"position":[[0,10]]}}}],["contribut",{"_index":88,"t":{"428":{"position":[[0,12]]},"2750":{"position":[[0,10]]},"2864":{"position":[[0,10]]},"2933":{"position":[[0,10]]},"4836":{"position":[[0,10]]}}}],["contributor",{"_index":64,"t":{"274":{"position":[[22,12]]},"2022":{"position":[[0,11]]}}}],["control",{"_index":99,"t":{"494":{"position":[[0,11]]}}}],["creat",{"_index":360,"t":{"3503":{"position":[[22,6]]},"4652":{"position":[[12,6]]}}}],["csctl",{"_index":103,"t":{"558":{"position":[[23,5]]},"591":{"position":[[0,5]]},"639":{"position":[[6,5]]}}}],["csp",{"_index":227,"t":{"2496":{"position":[[39,5]]}}}],["custom",{"_index":325,"t":{"3449":{"position":[[40,8]]},"3465":{"position":[[70,9]]},"4213":{"position":[[31,8]]},"4635":{"position":[[60,9]]}}}],["data",{"_index":216,"t":{"2316":{"position":[[5,4]]},"2383":{"position":[[5,4]]},"3511":{"position":[[50,4]]},"3515":{"position":[[38,4]]},"4753":{"position":[[40,4]]},"4789":{"position":[[28,4]]}}}],["databas",{"_index":373,"t":{"3513":{"position":[[21,8]]},"4734":{"position":[[11,8]]}}}],["debian",{"_index":132,"t":{"921":{"position":[[39,6]]},"1812":{"position":[[39,6]]},"2945":{"position":[[46,6]]}}}],["decis",{"_index":296,"t":{"3419":{"position":[[10,9]]},"3423":{"position":[[26,8]]},"3503":{"position":[[29,8]]},"3505":{"position":[[47,8]]},"3507":{"position":[[30,8]]},"3939":{"position":[[0,9]]},"3976":{"position":[[16,8]]},"4652":{"position":[[19,8]]},"4672":{"position":[[37,8]]},"4682":{"position":[[20,8]]}}}],["deep",{"_index":82,"t":{"385":{"position":[[0,4]]}}}],["default",{"_index":304,"t":{"3427":{"position":[[10,7]]},"3473":{"position":[[19,7]]},"4035":{"position":[[0,7]]},"4368":{"position":[[9,7]]},"4383":{"position":[[9,7]]},"4393":{"position":[[9,7]]}}}],["demonstr",{"_index":15,"t":{"42":{"position":[[23,12]]}}}],["deploy",{"_index":106,"t":{"684":{"position":[[3,10]]},"742":{"position":[[4,10]]},"1459":{"position":[[0,6]]},"1483":{"position":[[0,6]]},"2432":{"position":[[35,10]]},"2629":{"position":[[4,10]]},"2846":{"position":[[15,10]]},"4840":{"position":[[17,10]]}}}],["deprec",{"_index":316,"t":{"3441":{"position":[[29,10]]},"4140":{"position":[[19,10]]}}}],["descript",{"_index":228,"t":{"2546":{"position":[[6,11]]},"2587":{"position":[[6,11]]}}}],["design",{"_index":104,"t":{"591":{"position":[[8,6]]},"1095":{"position":[[8,6]]},"1286":{"position":[[0,9]]}}}],["develop",{"_index":7,"t":{"16":{"position":[[9,11]]},"248":{"position":[[0,9]]},"276":{"position":[[0,9]]},"503":{"position":[[0,9]]},"558":{"position":[[0,10]]},"2072":{"position":[[0,9]]},"2874":{"position":[[13,11]]}}}],["distribut",{"_index":350,"t":{"3485":{"position":[[26,12]]},"4438":{"position":[[16,12]]},"4449":{"position":[[16,12]]},"4462":{"position":[[16,12]]}}}],["dive",{"_index":83,"t":{"385":{"position":[[5,5]]}}}],["doc",{"_index":32,"t":{"87":{"position":[[7,4]]},"3387":{"position":[[21,4]]},"3552":{"position":[[11,4]]}}}],["docker",{"_index":184,"t":{"1448":{"position":[[0,6]]},"2162":{"position":[[0,6]]}}}],["document",{"_index":23,"t":{"73":{"position":[[4,13]]},"100":{"position":[[0,13]]},"164":{"position":[[0,13]]},"274":{"position":[[0,13]]},"276":{"position":[[10,13]]},"591":{"position":[[15,8]]},"2428":{"position":[[13,13]]},"2721":{"position":[[33,13]]},"3559":{"position":[[4,13]]}}}],["domain",{"_index":222,"t":{"2434":{"position":[[0,6]]},"3461":{"position":[[10,6]]},"4602":{"position":[[0,6]]},"4663":{"position":[[0,6]]}}}],["domains/groups/roles/project",{"_index":334,"t":{"3465":{"position":[[21,28]]},"4635":{"position":[[11,28]]}}}],["encrypt",{"_index":323,"t":{"3449":{"position":[[21,10]]},"4213":{"position":[[12,10]]}}}],["end",{"_index":322,"t":{"3449":{"position":[[10,3],[17,3]]},"4213":{"position":[[8,3]]}}}],["endpoint",{"_index":233,"t":{"2605":{"position":[[23,9]]}}}],["entropi",{"_index":289,"t":{"3405":{"position":[[14,7]]},"3754":{"position":[[4,7]]},"3848":{"position":[[4,8]]}}}],["environ",{"_index":252,"t":{"2874":{"position":[[25,11]]}}}],["esxi",{"_index":207,"t":{"2233":{"position":[[20,4]]}}}],["exampl",{"_index":188,"t":{"1458":{"position":[[0,8]]},"2432":{"position":[[0,7]]},"2757":{"position":[[0,7]]},"4131":{"position":[[33,8]]}}}],["experiment",{"_index":236,"t":{"2619":{"position":[[16,14]]},"2637":{"position":[[16,14]]}}}],["explain",{"_index":221,"t":{"2432":{"position":[[46,9]]}}}],["explan",{"_index":42,"t":{"164":{"position":[[23,11]]}}}],["exposit",{"_index":375,"t":{"3515":{"position":[[10,10]]},"4789":{"position":[[0,10]]}}}],["failsaf",{"_index":309,"t":{"3431":{"position":[[26,8]]},"4092":{"position":[[16,8]]},"4131":{"position":[[16,8]]}}}],["failur",{"_index":377,"t":{"4131":{"position":[[45,7]]}}}],["faq",{"_index":248,"t":{"2837":{"position":[[0,3]]}}}],["featur",{"_index":353,"t":{"3489":{"position":[[21,8]]},"4469":{"position":[[11,8]]}}}],["feder",{"_index":70,"t":{"310":{"position":[[9,10]]},"316":{"position":[[10,10]]},"2365":{"position":[[40,10]]},"2428":{"position":[[52,10]]},"3459":{"position":[[40,10]]},"4585":{"position":[[30,10]]}}}],["file",{"_index":34,"t":{"100":{"position":[[14,5]]}}}],["first",{"_index":0,"t":{"2":{"position":[[0,5]]}}}],["flavor",{"_index":127,"t":{"888":{"position":[[0,6]]},"1746":{"position":[[0,6]]},"3401":{"position":[[14,6]]},"3417":{"position":[[23,7]]},"3429":{"position":[[14,7]]},"3649":{"position":[[4,6]]},"3686":{"position":[[4,6]]},"3736":{"position":[[4,6]]},"3773":{"position":[[4,6]]},"3886":{"position":[[13,7]]},"3921":{"position":[[4,7]]}}}],["flow",{"_index":79,"t":{"381":{"position":[[19,4]]},"383":{"position":[[11,4]]},"385":{"position":[[16,4]]},"416":{"position":[[21,4]]},"478":{"position":[[8,4]]}}}],["framework",{"_index":243,"t":{"2721":{"position":[[23,9]]}}}],["frequent",{"_index":120,"t":{"770":{"position":[[0,10]]}}}],["function",{"_index":311,"t":{"3435":{"position":[[24,13]]},"4114":{"position":[[14,13]]}}}],["gaia",{"_index":13,"t":{"42":{"position":[[16,4]]}}}],["garden",{"_index":139,"t":{"1063":{"position":[[0,8]]}}}],["get",{"_index":10,"t":{"34":{"position":[[0,7]]},"42":{"position":[[0,7]]},"50":{"position":[[0,7]]},"466":{"position":[[0,7]]},"656":{"position":[[0,7]]},"4840":{"position":[[0,7]]}}}],["glanc",{"_index":167,"t":{"1288":{"position":[[0,6]]}}}],["global",{"_index":275,"t":{"3389":{"position":[[0,6]]}}}],["glossari",{"_index":124,"t":{"809":{"position":[[0,8]]}}}],["gnocchi",{"_index":372,"t":{"3513":{"position":[[10,7]]},"4734":{"position":[[0,7]]}}}],["govern",{"_index":281,"t":{"3395":{"position":[[10,10]]},"3619":{"position":[[0,10]]}}}],["grafana",{"_index":145,"t":{"1086":{"position":[[13,7]]}}}],["group",{"_index":212,"t":{"2282":{"position":[[34,6]]},"2296":{"position":[[49,6]]},"3423":{"position":[[19,6]]},"3427":{"position":[[37,6]]},"3976":{"position":[[9,6]]},"4035":{"position":[[27,6]]}}}],["guid",{"_index":33,"t":{"87":{"position":[[12,5]]},"116":{"position":[[8,5]]},"144":{"position":[[14,5]]},"278":{"position":[[25,5]]},"296":{"position":[[36,5]]},"352":{"position":[[11,5]]},"503":{"position":[[10,5]]},"762":{"position":[[0,5]]},"1008":{"position":[[0,6]]},"1010":{"position":[[8,5]]},"1138":{"position":[[14,5]]},"1459":{"position":[[7,5]]},"1532":{"position":[[11,5]]},"1999":{"position":[[6,6]]},"2022":{"position":[[12,5]]},"2072":{"position":[[10,5]]},"2080":{"position":[[6,5]]},"2133":{"position":[[16,5]]},"2156":{"position":[[8,5]]},"2232":{"position":[[5,5]]},"2560":{"position":[[11,5]]},"2945":{"position":[[0,6]]}}}],["ha",{"_index":105,"t":{"684":{"position":[[0,2]]}}}],["hackathon",{"_index":51,"t":{"202":{"position":[[0,9]]}}}],["harden",{"_index":358,"t":{"3499":{"position":[[29,9]]},"4523":{"position":[[19,9]]}}}],["hardwar",{"_index":113,"t":{"756":{"position":[[0,8]]},"1102":{"position":[[0,8]]},"3342":{"position":[[8,8]]}}}],["health",{"_index":131,"t":{"921":{"position":[[21,6]]},"1812":{"position":[[21,6]]},"2687":{"position":[[4,6]]},"2945":{"position":[[28,6]]}}}],["heat",{"_index":168,"t":{"1307":{"position":[[0,4]]}}}],["horizon",{"_index":169,"t":{"1309":{"position":[[0,7]]}}}],["host",{"_index":250,"t":{"2846":{"position":[[38,4]]}}}],["iaa",{"_index":28,"t":{"81":{"position":[[5,4]]},"2637":{"position":[[0,4]]},"3397":{"position":[[0,4]]},"3451":{"position":[[34,4]]},"3453":{"position":[[39,4]]},"3515":{"position":[[24,4]]},"4131":{"position":[[79,4]]},"4196":{"position":[[24,4]]},"4247":{"position":[[29,4]]},"4264":{"position":[[33,4]]},"4772":{"position":[[15,4]]},"4789":{"position":[[14,4]]}}}],["iam",{"_index":29,"t":{"83":{"position":[[5,3]]},"3469":{"position":[[0,3]]}}}],["ident",{"_index":69,"t":{"310":{"position":[[0,8]]},"2365":{"position":[[16,8]]},"3459":{"position":[[31,8]]},"4585":{"position":[[21,8]]}}}],["imag",{"_index":81,"t":{"383":{"position":[[5,5]]},"856":{"position":[[0,5]]},"881":{"position":[[0,5]]},"1757":{"position":[[0,5]]},"1805":{"position":[[0,5]]},"2260":{"position":[[26,5]]},"3409":{"position":[[14,5]]},"3413":{"position":[[23,6]]},"3443":{"position":[[22,6]]},"3818":{"position":[[4,5]]},"3838":{"position":[[4,5]]},"3862":{"position":[[13,6]]},"3911":{"position":[[13,7]]},"4183":{"position":[[12,6]]}}}],["impact",{"_index":378,"t":{"4131":{"position":[[69,6]]}}}],["implement",{"_index":68,"t":{"296":{"position":[[21,14]]},"3493":{"position":[[46,14]]},"3505":{"position":[[32,14]]},"3736":{"position":[[28,14]]},"3838":{"position":[[20,14]]},"3848":{"position":[[13,14]]},"3911":{"position":[[21,14]]},"4058":{"position":[[26,14]]},"4174":{"position":[[24,14]]},"4264":{"position":[[56,14]]},"4360":{"position":[[24,14]]},"4383":{"position":[[32,14]]},"4462":{"position":[[47,14]]},"4552":{"position":[[36,14]]},"4567":{"position":[[26,14]]},"4663":{"position":[[15,14]]},"4672":{"position":[[22,14]]}}}],["import",{"_index":383,"t":{"4862":{"position":[[5,6]]}}}],["infrastructur",{"_index":195,"t":{"1512":{"position":[[0,14]]},"1550":{"position":[[0,14]]},"2166":{"position":[[0,14]]},"2605":{"position":[[0,14]]},"2710":{"position":[[9,14]]}}}],["instal",{"_index":37,"t":{"124":{"position":[[0,12]]},"2260":{"position":[[0,7]]}}}],["instanc",{"_index":208,"t":{"2260":{"position":[[8,8]]}}}],["integr",{"_index":90,"t":{"435":{"position":[[9,11]]},"519":{"position":[[11,11]]}}}],["introduct",{"_index":74,"t":{"330":{"position":[[0,12]]},"369":{"position":[[16,12]]},"2365":{"position":[[0,12]]},"3360":{"position":[[0,12]]},"4827":{"position":[[0,12]]}}}],["inventori",{"_index":159,"t":{"1206":{"position":[[0,9]]}}}],["iron",{"_index":140,"t":{"1066":{"position":[[0,6]]},"1317":{"position":[[0,6]]}}}],["iso",{"_index":209,"t":{"2260":{"position":[[22,3]]}}}],["jitsi",{"_index":56,"t":{"252":{"position":[[0,5]]}}}],["json",{"_index":376,"t":{"3515":{"position":[[46,4]]},"4789":{"position":[[36,4]]}}}],["k3",{"_index":141,"t":{"1069":{"position":[[0,3]]},"2607":{"position":[[0,3]]},"2846":{"position":[[0,3]]}}}],["k8",{"_index":342,"t":{"3477":{"position":[[14,3]]},"4338":{"position":[[4,3]]},"4349":{"position":[[4,3]]},"4360":{"position":[[4,3]]}}}],["kaa",{"_index":235,"t":{"2619":{"position":[[0,4]]},"3467":{"position":[[0,4]]},"3471":{"position":[[29,4]]},"3473":{"position":[[14,4]]},"3495":{"position":[[10,4]]},"3509":{"position":[[83,4]]},"4131":{"position":[[88,4]]},"4271":{"position":[[19,4]]},"4368":{"position":[[4,4]]},"4383":{"position":[[4,4]]},"4393":{"position":[[4,4]]},"4567":{"position":[[0,4]]},"4570":{"position":[[0,4]]},"4720":{"position":[[73,4]]},"4774":{"position":[[15,4]]}}}],["key",{"_index":313,"t":{"3437":{"position":[[14,3]]},"4058":{"position":[[4,3]]},"4071":{"position":[[4,3]]}}}],["keycloak",{"_index":142,"t":{"1082":{"position":[[0,8]]},"2428":{"position":[[31,8],[43,8]]}}}],["keyston",{"_index":171,"t":{"1321":{"position":[[0,8]]},"1724":{"position":[[0,8]]},"3461":{"position":[[43,8]]},"4602":{"position":[[33,8]]}}}],["keyword",{"_index":66,"t":{"278":{"position":[[12,7]]}}}],["kind",{"_index":251,"t":{"2874":{"position":[[0,4]]}}}],["knowledg",{"_index":118,"t":{"766":{"position":[[0,9]]},"2314":{"position":[[0,9]]}}}],["kubernet",{"_index":196,"t":{"1514":{"position":[[0,10]]},"2721":{"position":[[0,10]]},"3483":{"position":[[10,10]]},"3485":{"position":[[10,10]]},"3489":{"position":[[34,10]]},"3499":{"position":[[10,10]]},"4338":{"position":[[31,10]]},"4425":{"position":[[0,10]]},"4438":{"position":[[0,10]]},"4449":{"position":[[0,10]]},"4462":{"position":[[0,10]]},"4469":{"position":[[24,10]]},"4523":{"position":[[0,10]]}}}],["landscap",{"_index":266,"t":{"3342":{"position":[[17,9]]}}}],["layer",{"_index":76,"t":{"369":{"position":[[10,5]]},"1129":{"position":[[0,6]]},"3509":{"position":[[88,5]]},"4720":{"position":[[78,5]]}}}],["level",{"_index":254,"t":{"2913":{"position":[[0,7]]},"3431":{"position":[[35,6]]},"4092":{"position":[[25,6]]},"4131":{"position":[[25,7]]}}}],["licens",{"_index":43,"t":{"168":{"position":[[0,7]]},"248":{"position":[[34,8]]}}}],["limit",{"_index":112,"t":{"740":{"position":[[5,5]]}}}],["lint",{"_index":36,"t":{"116":{"position":[[0,7]]}}}],["list",{"_index":60,"t":{"259":{"position":[[8,5]]}}}],["loadbalanc",{"_index":161,"t":{"1239":{"position":[[0,12]]}}}],["local",{"_index":98,"t":{"482":{"position":[[6,5]]},"2874":{"position":[[7,5]]},"4840":{"position":[[35,5]]}}}],["log",{"_index":197,"t":{"1520":{"position":[[0,7]]},"1689":{"position":[[0,7]]},"2168":{"position":[[0,7]]}}}],["machin",{"_index":203,"t":{"2000":{"position":[[21,7]]},"4840":{"position":[[41,7]]}}}],["magnum",{"_index":170,"t":{"1319":{"position":[[0,6]]}}}],["mail",{"_index":59,"t":{"259":{"position":[[0,7]]}}}],["manag",{"_index":77,"t":{"381":{"position":[[0,10]]},"476":{"position":[[0,8]]},"856":{"position":[[6,7]]},"881":{"position":[[6,7]]},"888":{"position":[[7,7]]},"899":{"position":[[8,7]]},"981":{"position":[[9,7]]},"996":{"position":[[8,7]]},"1255":{"position":[[0,7]]},"1467":{"position":[[0,7]]},"1653":{"position":[[0,7]]},"1746":{"position":[[7,7]]},"1757":{"position":[[6,7]]},"1783":{"position":[[8,7]]},"1805":{"position":[[6,7]]},"1872":{"position":[[9,7]]},"1887":{"position":[[8,7]]},"2153":{"position":[[0,7]]},"2170":{"position":[[0,7]]},"2365":{"position":[[25,10]]},"2434":{"position":[[7,7]]},"3437":{"position":[[18,7]]},"3461":{"position":[[17,7]]},"4058":{"position":[[8,7]]},"4071":{"position":[[8,7]]},"4602":{"position":[[7,7]]},"4663":{"position":[[7,7]]}}}],["mandatori",{"_index":327,"t":{"3451":{"position":[[10,9]]},"4196":{"position":[[0,9]]}}}],["manila",{"_index":172,"t":{"1326":{"position":[[0,6]]}}}],["manual",{"_index":270,"t":{"3374":{"position":[[30,6]]}}}],["materi",{"_index":150,"t":{"1102":{"position":[[17,9]]}}}],["matrix",{"_index":61,"t":{"261":{"position":[[0,6]]},"2603":{"position":[[30,6]]}}}],["metadata",{"_index":291,"t":{"3409":{"position":[[20,8]]},"3818":{"position":[[10,8]]},"3838":{"position":[[10,9]]}}}],["metal",{"_index":191,"t":{"1461":{"position":[[21,5]]}}}],["meter",{"_index":259,"t":{"3029":{"position":[[0,8]]},"3513":{"position":[[34,8]]},"3515":{"position":[[29,8]]},"4734":{"position":[[24,8]]},"4789":{"position":[[19,8]]}}}],["migrat",{"_index":110,"t":{"727":{"position":[[0,9]]},"1386":{"position":[[19,7]]},"1483":{"position":[[16,7]]},"1548":{"position":[[0,7]]},"1978":{"position":[[13,7]]},"2233":{"position":[[0,7]]}}}],["mission",{"_index":46,"t":{"186":{"position":[[0,7]]}}}],["monitor",{"_index":24,"t":{"75":{"position":[[4,10]]},"921":{"position":[[28,7]]},"1520":{"position":[[10,10]]},"1812":{"position":[[28,7]]},"2168":{"position":[[10,10]]},"2619":{"position":[[5,10]]},"2637":{"position":[[5,10]]},"2666":{"position":[[12,10]]},"2677":{"position":[[5,10]]},"2687":{"position":[[11,7]]},"2866":{"position":[[0,10]]},"2945":{"position":[[35,7]]}}}],["mvp",{"_index":229,"t":{"2599":{"position":[[12,3]]}}}],["name",{"_index":287,"t":{"3401":{"position":[[21,6]]},"3465":{"position":[[10,6]]},"3649":{"position":[[11,6]]},"3686":{"position":[[11,6]]},"3736":{"position":[[11,6]]},"3773":{"position":[[11,6]]},"4635":{"position":[[0,6]]}}}],["netdata",{"_index":143,"t":{"1084":{"position":[[0,7]]}}}],["network",{"_index":162,"t":{"1264":{"position":[[0,7]]},"1518":{"position":[[0,7]]},"1699":{"position":[[0,7]]},"2172":{"position":[[0,7]]},"2361":{"position":[[0,7]]},"3495":{"position":[[15,10]]},"4567":{"position":[[5,10]]},"4570":{"position":[[5,10]]}}}],["neutron",{"_index":173,"t":{"1328":{"position":[[0,7]]},"1721":{"position":[[0,7]]}}}],["new",{"_index":336,"t":{"3465":{"position":[[66,3]]},"4338":{"position":[[27,3]]},"4635":{"position":[[56,3]]}}}],["nextcloud",{"_index":62,"t":{"265":{"position":[[0,9]]}}}],["node",{"_index":80,"t":{"383":{"position":[[0,4]]},"1122":{"position":[[0,5]]},"1461":{"position":[[27,5]]},"3483":{"position":[[21,5]]},"3485":{"position":[[21,4]]},"4425":{"position":[[11,5]]},"4438":{"position":[[11,4]]},"4449":{"position":[[11,4]]},"4462":{"position":[[11,4]]}}}],["note",{"_index":257,"t":{"3011":{"position":[[8,5]]},"3041":{"position":[[8,5]]},"3078":{"position":[[8,5]]},"3111":{"position":[[8,5]]},"3145":{"position":[[8,5]]},"3177":{"position":[[8,5]]},"3215":{"position":[[8,5]]},"3273":{"position":[[8,5]]},"3324":{"position":[[8,5]]},"3736":{"position":[[55,5]]},"3838":{"position":[[47,5]]},"3848":{"position":[[40,5]]},"3911":{"position":[[36,5]]},"4058":{"position":[[53,5]]},"4174":{"position":[[51,5]]},"4264":{"position":[[83,5]]},"4360":{"position":[[51,5]]},"4383":{"position":[[59,5]]},"4462":{"position":[[74,5]]},"4567":{"position":[[41,5]]},"4663":{"position":[[30,5]]}}}],["notif",{"_index":231,"t":{"2603":{"position":[[13,13]]}}}],["nova",{"_index":178,"t":{"1355":{"position":[[0,4]]},"1726":{"position":[[0,4]]}}}],["oauth",{"_index":237,"t":{"2627":{"position":[[0,5]]}}}],["object",{"_index":94,"t":{"476":{"position":[[22,7]]}}}],["observ",{"_index":244,"t":{"2752":{"position":[[0,13]]},"3509":{"position":[[54,13]]},"4720":{"position":[[44,13]]}}}],["octavia",{"_index":175,"t":{"1334":{"position":[[0,7]]},"1741":{"position":[[0,7]]}}}],["onboard",{"_index":335,"t":{"3465":{"position":[[55,10]]},"4635":{"position":[[45,10]]}}}],["op",{"_index":30,"t":{"85":{"position":[[5,3]]},"3501":{"position":[[0,3]]}}}],["openapi",{"_index":364,"t":{"3507":{"position":[[22,7]]},"4682":{"position":[[12,7]]}}}],["openid",{"_index":72,"t":{"316":{"position":[[25,6]]}}}],["openstack",{"_index":12,"t":{"34":{"position":[[21,9]]},"316":{"position":[[0,9]]},"921":{"position":[[11,9]]},"1071":{"position":[[0,9]]},"1290":{"position":[[0,9]]},"1522":{"position":[[0,9]]},"1705":{"position":[[0,9]]},"1812":{"position":[[11,9]]},"2140":{"position":[[0,9]]},"2230":{"position":[[0,9]]},"2233":{"position":[[28,9]]},"2259":{"position":[[0,9]]},"2945":{"position":[[18,9]]}}}],["oper",{"_index":198,"t":{"1532":{"position":[[0,10]]},"2496":{"position":[[45,10]]}}}],["organis",{"_index":274,"t":{"3387":{"position":[[30,12]]},"3552":{"position":[[20,12]]}}}],["origin",{"_index":55,"t":{"248":{"position":[[25,6]]}}}],["overview",{"_index":3,"t":{"5":{"position":[[0,8]]},"398":{"position":[[0,8]]},"499":{"position":[[0,8]]},"531":{"position":[[0,8]]},"662":{"position":[[0,8]]},"758":{"position":[[0,8]]},"805":{"position":[[0,8]]},"2470":{"position":[[0,8]]},"2483":{"position":[[0,8]]},"2523":{"position":[[0,8]]},"2570":{"position":[[0,8]]},"2617":{"position":[[0,8]]},"2793":{"position":[[0,8]]},"2886":{"position":[[0,8]]},"2901":{"position":[[10,8]]},"2915":{"position":[[0,8]]},"2939":{"position":[[0,8]]},"2941":{"position":[[0,8]]},"2943":{"position":[[0,8]]},"3005":{"position":[[0,8]]},"3007":{"position":[[0,8]]},"3009":{"position":[[0,8]]},"3353":{"position":[[0,8]]},"4825":{"position":[[0,8]]},"4838":{"position":[[0,8]]}}}],["ovn",{"_index":147,"t":{"1089":{"position":[[8,3]]}}}],["packag",{"_index":153,"t":{"1143":{"position":[[0,8]]}}}],["page",{"_index":240,"t":{"2666":{"position":[[7,4]]},"2819":{"position":[[17,4]]},"3503":{"position":[[17,4]]},"3505":{"position":[[17,4]]},"3507":{"position":[[17,4]]},"4652":{"position":[[7,4]]},"4672":{"position":[[7,4]]},"4682":{"position":[[7,4]]}}}],["pentest",{"_index":225,"t":{"2496":{"position":[[16,10]]}}}],["persist",{"_index":109,"t":{"711":{"position":[[0,11]]}}}],["pipelin",{"_index":269,"t":{"3374":{"position":[[21,8]]}}}],["placement",{"_index":174,"t":{"1332":{"position":[[0,9]]}}}],["plan",{"_index":52,"t":{"202":{"position":[[10,8]]}}}],["plusserv",{"_index":17,"t":{"42":{"position":[[38,10]]}}}],["polici",{"_index":343,"t":{"3477":{"position":[[26,6]]},"4338":{"position":[[16,6]]},"4349":{"position":[[16,6]]},"4360":{"position":[[16,7]]}}}],["post",{"_index":2,"t":{"2":{"position":[[11,4]]}}}],["practis",{"_index":214,"t":{"2296":{"position":[[5,9]]}}}],["preview",{"_index":182,"t":{"1386":{"position":[[64,8]]},"1392":{"position":[[25,8]]},"1483":{"position":[[61,8]]},"1524":{"position":[[25,8]]},"1548":{"position":[[44,8]]},"1899":{"position":[[25,8]]},"1978":{"position":[[58,8]]},"2147":{"position":[[19,8]]}}}],["project",{"_index":128,"t":{"899":{"position":[[0,7]]},"1783":{"position":[[0,7]]}}}],["prometheu",{"_index":144,"t":{"1086":{"position":[[0,10]]}}}],["properti",{"_index":294,"t":{"3417":{"position":[[35,10]]},"3886":{"position":[[25,10]]}}}],["propos",{"_index":218,"t":{"2428":{"position":[[0,8]]}}}],["protect",{"_index":49,"t":{"200":{"position":[[7,10]]}}}],["provid",{"_index":89,"t":{"435":{"position":[[0,8]]},"3509":{"position":[[45,8]]},"3511":{"position":[[34,9]]},"4720":{"position":[[35,8]]},"4753":{"position":[[24,9]]}}}],["provis",{"_index":189,"t":{"1461":{"position":[[0,12]]}}}],["proxi",{"_index":177,"t":{"1341":{"position":[[0,5]]}}}],["public",{"_index":253,"t":{"2899":{"position":[[4,6]]}}}],["push",{"_index":368,"t":{"3511":{"position":[[10,4]]},"4753":{"position":[[0,4]]}}}],["question",{"_index":122,"t":{"770":{"position":[[17,9]]}}}],["quickstart",{"_index":100,"t":{"501":{"position":[[0,10]]},"571":{"position":[[0,10]]},"669":{"position":[[0,10]]},"748":{"position":[[0,10]]},"2472":{"position":[[0,10]]},"2560":{"position":[[0,10]]},"2650":{"position":[[0,10]]},"2752":{"position":[[20,10]]},"2795":{"position":[[0,10]]},"2895":{"position":[[0,10]]},"2935":{"position":[[0,10]]},"4860":{"position":[[0,10]]}}}],["rate",{"_index":111,"t":{"740":{"position":[[0,4]]}}}],["record",{"_index":301,"t":{"3423":{"position":[[35,6]]},"3976":{"position":[[25,6]]}}}],["refer",{"_index":362,"t":{"3505":{"position":[[22,9]]},"4672":{"position":[[12,9]]}}}],["registri",{"_index":345,"t":{"3481":{"position":[[37,10]]},"3493":{"position":[[20,8]]},"4408":{"position":[[27,10]]},"4552":{"position":[[10,8]]}}}],["regul",{"_index":283,"t":{"3399":{"position":[[10,11]]},"3725":{"position":[[0,11]]}}}],["releas",{"_index":91,"t":{"436":{"position":[[0,9]]},"2053":{"position":[[0,8]]},"3011":{"position":[[0,7],[22,7]]},"3041":{"position":[[0,7],[22,7]]},"3078":{"position":[[0,7],[22,7]]},"3111":{"position":[[0,7],[22,7]]},"3145":{"position":[[0,7],[22,7]]},"3177":{"position":[[0,7],[22,7]]},"3215":{"position":[[0,7],[22,7]]},"3273":{"position":[[0,7],[22,7]]},"3324":{"position":[[0,7],[22,7]]}}}],["replac",{"_index":315,"t":{"3441":{"position":[[10,11]]},"4140":{"position":[[0,11]]}}}],["report",{"_index":226,"t":{"2496":{"position":[[27,7]]}}}],["repositori",{"_index":160,"t":{"1215":{"position":[[14,10]]}}}],["request",{"_index":245,"t":{"2757":{"position":[[8,8]]},"2803":{"position":[[0,8]]}}}],["requir",{"_index":114,"t":{"756":{"position":[[9,12]]},"760":{"position":[[9,12]]},"2817":{"position":[[0,12]]},"2897":{"position":[[0,12]]},"2937":{"position":[[0,12]]},"3459":{"position":[[10,12]]},"3481":{"position":[[10,12]]},"3491":{"position":[[10,12]]},"4408":{"position":[[0,12]]},"4500":{"position":[[0,12]]},"4585":{"position":[[0,12]]},"4864":{"position":[[0,12]]}}}],["resolvconf",{"_index":154,"t":{"1152":{"position":[[0,10]]}}}],["resourc",{"_index":9,"t":{"16":{"position":[[27,9]]},"981":{"position":[[0,8]]},"1872":{"position":[[0,8]]},"4131":{"position":[[93,9]]}}}],["restor",{"_index":108,"t":{"695":{"position":[[11,7]]}}}],["rfc2119",{"_index":65,"t":{"278":{"position":[[4,7]]}}}],["robust",{"_index":352,"t":{"3489":{"position":[[10,10]]},"4469":{"position":[[0,10]]}}}],["rook",{"_index":180,"t":{"1386":{"position":[[48,4]]},"1392":{"position":[[9,4]]},"1483":{"position":[[27,4]]},"1524":{"position":[[9,4]]},"1899":{"position":[[9,4]]},"1978":{"position":[[24,4]]}}}],["rookifi",{"_index":179,"t":{"1386":{"position":[[10,8]]},"1483":{"position":[[7,8]]},"1548":{"position":[[25,7]]},"1978":{"position":[[4,8]]},"2147":{"position":[[0,7]]}}}],["rule",{"_index":50,"t":{"200":{"position":[[18,5]]},"3427":{"position":[[18,5]]},"4035":{"position":[[8,5]]}}}],["run",{"_index":202,"t":{"2000":{"position":[[0,7]]}}}],["sandbox",{"_index":133,"t":{"996":{"position":[[0,7]]},"1887":{"position":[[0,7]]}}}],["sc",{"_index":45,"t":{"168":{"position":[[27,3]]},"274":{"position":[[18,3]]},"278":{"position":[[0,3]]},"296":{"position":[[0,3]]},"310":{"position":[[23,3]]},"742":{"position":[[0,3]]},"2365":{"position":[[54,3]]},"2432":{"position":[[31,3]]},"2629":{"position":[[0,3]]},"2687":{"position":[[0,3]]},"2899":{"position":[[0,3]]},"3011":{"position":[[18,3]]},"3041":{"position":[[18,3]]},"3078":{"position":[[18,3]]},"3111":{"position":[[18,3]]},"3145":{"position":[[18,3]]},"3177":{"position":[[18,3]]},"3215":{"position":[[18,3]]},"3273":{"position":[[18,3]]},"3324":{"position":[[18,3]]},"3342":{"position":[[4,3]]},"3374":{"position":[[0,3]]},"3387":{"position":[[0,3]]},"3391":{"position":[[0,3]]},"3393":{"position":[[0,3]]},"3395":{"position":[[0,3],[28,3]]},"3399":{"position":[[0,3],[36,3]]},"3401":{"position":[[0,3],[10,3]]},"3405":{"position":[[0,3],[10,3]]},"3409":{"position":[[0,3],[10,3]]},"3413":{"position":[[0,3],[10,3]]},"3417":{"position":[[0,3],[10,3]]},"3419":{"position":[[0,3]]},"3421":{"position":[[0,3],[27,3]]},"3423":{"position":[[0,3]]},"3425":{"position":[[0,3],[10,3]]},"3427":{"position":[[0,3]]},"3429":{"position":[[0,3]]},"3431":{"position":[[0,3],[10,3]]},"3435":{"position":[[0,3]]},"3437":{"position":[[0,3],[10,3]]},"3441":{"position":[[0,3]]},"3443":{"position":[[0,3]]},"3445":{"position":[[0,3],[10,3]]},"3449":{"position":[[0,3]]},"3451":{"position":[[0,3]]},"3453":{"position":[[0,3]]},"3457":{"position":[[0,3]]},"3459":{"position":[[0,3]]},"3461":{"position":[[0,3]]},"3465":{"position":[[0,3]]},"3471":{"position":[[0,3]]},"3473":{"position":[[0,3],[10,3]]},"3477":{"position":[[0,3],[10,3]]},"3481":{"position":[[0,3]]},"3483":{"position":[[0,3]]},"3485":{"position":[[0,3]]},"3489":{"position":[[0,3]]},"3491":{"position":[[0,3]]},"3493":{"position":[[0,3],[33,3]]},"3495":{"position":[[0,3]]},"3499":{"position":[[0,3]]},"3503":{"position":[[0,3]]},"3505":{"position":[[0,3]]},"3507":{"position":[[0,3]]},"3509":{"position":[[0,3]]},"3511":{"position":[[0,3]]},"3513":{"position":[[0,3]]},"3515":{"position":[[0,3]]},"3559":{"position":[[0,3]]},"3619":{"position":[[18,3]]},"3649":{"position":[[0,3]]},"3686":{"position":[[0,3]]},"3725":{"position":[[26,3]]},"3736":{"position":[[0,3]]},"3754":{"position":[[0,3]]},"3773":{"position":[[0,3]]},"3818":{"position":[[0,3]]},"3838":{"position":[[0,3]]},"3848":{"position":[[0,3]]},"3862":{"position":[[0,3]]},"3886":{"position":[[0,3]]},"3911":{"position":[[0,3]]},"3954":{"position":[[17,3]]},"4003":{"position":[[0,3]]},"4058":{"position":[[0,3]]},"4071":{"position":[[0,3]]},"4092":{"position":[[0,3]]},"4131":{"position":[[0,3]]},"4151":{"position":[[0,3]]},"4174":{"position":[[0,3]]},"4264":{"position":[[0,3]]},"4338":{"position":[[0,3]]},"4349":{"position":[[0,3]]},"4360":{"position":[[0,3]]},"4368":{"position":[[0,3]]},"4383":{"position":[[0,3]]},"4393":{"position":[[0,3]]},"4552":{"position":[[23,3]]},"4772":{"position":[[0,3]]},"4774":{"position":[[0,3]]}}}],["scope",{"_index":271,"t":{"3385":{"position":[[0,6]]}}}],["script",{"_index":204,"t":{"2070":{"position":[[0,7]]}}}],["secur",{"_index":211,"t":{"2282":{"position":[[25,8]]},"2296":{"position":[[40,8]]},"3423":{"position":[[10,8]]},"3427":{"position":[[28,8]]},"3453":{"position":[[27,8]]},"3457":{"position":[[10,6]]},"3976":{"position":[[0,8]]},"4035":{"position":[[18,8]]},"4247":{"position":[[17,8]]},"4264":{"position":[[21,8]]},"4292":{"position":[[0,6]]}}}],["seed",{"_index":194,"t":{"1496":{"position":[[0,4]]}}}],["servic",{"_index":5,"t":{"8":{"position":[[8,8]]},"1154":{"position":[[0,8]]},"1444":{"position":[[0,8]]},"1510":{"position":[[0,8]]},"2605":{"position":[[15,7]]},"3451":{"position":[[39,8]]},"3453":{"position":[[44,7]]},"3509":{"position":[[37,7]]},"4196":{"position":[[29,8]]},"4247":{"position":[[34,7]]},"4264":{"position":[[38,7]]},"4720":{"position":[[27,7]]}}}],["set",{"_index":129,"t":{"921":{"position":[[0,7]]},"1812":{"position":[[0,7]]},"2945":{"position":[[7,7]]}}}],["setup",{"_index":220,"t":{"2432":{"position":[[8,5]]},"2434":{"position":[[15,5]]}}}],["sig",{"_index":20,"t":{"69":{"position":[[0,3]]},"71":{"position":[[0,3]]},"73":{"position":[[0,3]]},"75":{"position":[[0,3]]},"77":{"position":[[0,3]]}}}],["simpl",{"_index":134,"t":{"997":{"position":[[0,6]]},"1888":{"position":[[0,6]]},"2846":{"position":[[8,6]]}}}],["singl",{"_index":249,"t":{"2846":{"position":[[31,6]]}}}],["skylin",{"_index":176,"t":{"1336":{"position":[[0,7]]}}}],["softwar",{"_index":115,"t":{"760":{"position":[[0,8]]},"3453":{"position":[[52,8]]},"4247":{"position":[[42,8]]},"4264":{"position":[[46,9]]}}}],["sonic",{"_index":146,"t":{"1089":{"position":[[0,5]]},"3421":{"position":[[10,5]]},"3954":{"position":[[0,5]]}}}],["sonobuoy",{"_index":338,"t":{"3471":{"position":[[16,8]]},"4271":{"position":[[6,8]]}}}],["sovereign",{"_index":277,"t":{"3391":{"position":[[10,9]]},"3393":{"position":[[10,9]]},"3517":{"position":[[0,9]]},"3580":{"position":[[0,9]]}}}],["ssd",{"_index":306,"t":{"3429":{"position":[[10,3]]},"3921":{"position":[[0,3]]}}}],["ssh",{"_index":155,"t":{"1192":{"position":[[0,3]]}}}],["sso",{"_index":331,"t":{"3459":{"position":[[27,3]]},"4585":{"position":[[17,3]]}}}],["stack",{"_index":87,"t":{"418":{"position":[[37,6]]},"2752":{"position":[[14,5]]},"3491":{"position":[[43,6]]},"4500":{"position":[[33,6]]}}}],["standard",{"_index":25,"t":{"77":{"position":[[4,15]]},"3358":{"position":[[0,9]]},"3387":{"position":[[10,10]]},"3389":{"position":[[7,9]]},"3391":{"position":[[26,9]]},"3393":{"position":[[26,9]]},"3397":{"position":[[5,9]]},"3401":{"position":[[28,8]]},"3413":{"position":[[14,8]]},"3417":{"position":[[14,8]]},"3419":{"position":[[40,8]]},"3437":{"position":[[26,8]]},"3453":{"position":[[10,8]]},"3467":{"position":[[5,9]]},"3469":{"position":[[4,9]]},"3493":{"position":[[37,8]]},"3495":{"position":[[26,8]]},"3501":{"position":[[4,9]]},"3517":{"position":[[16,9]]},"3552":{"position":[[0,10]]},"3580":{"position":[[16,9]]},"3649":{"position":[[18,8]]},"3686":{"position":[[18,8]]},"3736":{"position":[[18,9]]},"3773":{"position":[[18,8]]},"3862":{"position":[[4,8]]},"3886":{"position":[[4,8]]},"3911":{"position":[[4,8]]},"3939":{"position":[[30,8]]},"4058":{"position":[[16,9]]},"4071":{"position":[[16,8]]},"4247":{"position":[[0,8]]},"4264":{"position":[[4,8]]},"4552":{"position":[[27,8]]},"4567":{"position":[[16,9]]},"4570":{"position":[[16,8]]}}}],["start",{"_index":11,"t":{"34":{"position":[[8,7]]},"42":{"position":[[8,7]]},"50":{"position":[[8,7]]},"466":{"position":[[8,7]]},"656":{"position":[[8,7]]},"4840":{"position":[[8,8]]}}}],["statement",{"_index":47,"t":{"186":{"position":[[8,9]]}}}],["statu",{"_index":239,"t":{"2666":{"position":[[0,6]]},"2819":{"position":[[10,6]]},"3503":{"position":[[10,6]]},"3505":{"position":[[10,6]]},"3507":{"position":[[10,6]]},"4652":{"position":[[0,6]]},"4672":{"position":[[0,6]]},"4682":{"position":[[0,6]]}}}],["storag",{"_index":217,"t":{"2363":{"position":[[0,7]]},"3473":{"position":[[27,7]]},"4368":{"position":[[17,7]]},"4383":{"position":[[17,7]]},"4393":{"position":[[17,7]]}}}],["stress",{"_index":135,"t":{"997":{"position":[[7,6]]},"1888":{"position":[[7,6]]}}}],["structur",{"_index":35,"t":{"100":{"position":[[20,9]]},"3559":{"position":[[18,9]]}}}],["style",{"_index":40,"t":{"144":{"position":[[8,5]]},"2080":{"position":[[0,5]]}}}],["styleguid",{"_index":38,"t":{"137":{"position":[[0,10]]}}}],["support",{"_index":234,"t":{"2607":{"position":[[4,7]]},"3421":{"position":[[16,7]]},"3451":{"position":[[24,9]]},"3954":{"position":[[6,7]]},"4196":{"position":[[14,9]]}}}],["sysctl",{"_index":157,"t":{"1200":{"position":[[0,6]]}}}],["system",{"_index":366,"t":{"3509":{"position":[[68,6]]},"4720":{"position":[[58,6]]}}}],["task",{"_index":201,"t":{"1684":{"position":[[0,4]]}}}],["taxonomi",{"_index":308,"t":{"3431":{"position":[[14,8]]},"4092":{"position":[[4,8]]},"4131":{"position":[[4,8]]}}}],["team",{"_index":26,"t":{"79":{"position":[[0,4]]},"81":{"position":[[0,4]]},"83":{"position":[[0,4]]},"85":{"position":[[0,4]]}}}],["technic",{"_index":181,"t":{"1386":{"position":[[53,10]]},"1392":{"position":[[14,10]]},"1483":{"position":[[50,10]]},"1524":{"position":[[14,10]]},"1548":{"position":[[33,10]]},"1899":{"position":[[14,10]]},"1978":{"position":[[47,10]]},"2147":{"position":[[8,10]]}}}],["teleport",{"_index":148,"t":{"1093":{"position":[[0,8]]}}}],["terminolog",{"_index":92,"t":{"443":{"position":[[0,11]]}}}],["test",{"_index":6,"t":{"16":{"position":[[0,4]]},"278":{"position":[[20,4]]},"296":{"position":[[16,4]]},"558":{"position":[[15,7]]},"2721":{"position":[[15,7]]},"3471":{"position":[[46,5]]},"3491":{"position":[[27,7]]},"3736":{"position":[[47,7]]},"3838":{"position":[[39,7]]},"3848":{"position":[[32,7]]},"4058":{"position":[[45,7]]},"4174":{"position":[[43,7]]},"4264":{"position":[[75,7]]},"4271":{"position":[[36,5]]},"4360":{"position":[[43,7]]},"4383":{"position":[[51,7]]},"4462":{"position":[[66,7]]},"4500":{"position":[[17,7]]}}}],["testb",{"_index":192,"t":{"1481":{"position":[[0,7]]},"2174":{"position":[[0,7]]}}}],["testflow",{"_index":241,"t":{"2710":{"position":[[0,8]]}}}],["timezon",{"_index":158,"t":{"1202":{"position":[[0,8]]}}}],["tip",{"_index":57,"t":{"256":{"position":[[0,4]]}}}],["title_",{"_index":382,"t":{"4776":{"position":[[13,6]]},"4806":{"position":[[13,6]]}}}],["tool",{"_index":125,"t":{"855":{"position":[[0,5]]},"1782":{"position":[[0,5]]},"2546":{"position":[[0,5]]},"2587":{"position":[[0,5]]},"3441":{"position":[[53,4]]},"4140":{"position":[[43,4]]}}}],["trace",{"_index":238,"t":{"2660":{"position":[[0,6]]}}}],["trick",{"_index":58,"t":{"256":{"position":[[9,6]]}}}],["troubleshoot",{"_index":96,"t":{"480":{"position":[[0,15]]},"515":{"position":[[0,15]]},"2133":{"position":[[0,15]]}}}],["tune",{"_index":186,"t":{"1454":{"position":[[0,5]]},"2679":{"position":[[0,6]]}}}],["type",{"_index":298,"t":{"3419":{"position":[[35,4]]},"3425":{"position":[[21,5]]},"3939":{"position":[[25,4]]},"4003":{"position":[[11,5]]}}}],["understand",{"_index":85,"t":{"418":{"position":[[0,13]]}}}],["up",{"_index":130,"t":{"921":{"position":[[8,2]]},"1812":{"position":[[8,2]]},"2945":{"position":[[15,2]]}}}],["update.pi",{"_index":126,"t":{"881":{"position":[[14,9]]},"1805":{"position":[[14,9]]}}}],["upgrad",{"_index":95,"t":{"478":{"position":[[0,7]]},"754":{"position":[[0,7]]},"2156":{"position":[[0,7]]}}}],["us",{"_index":97,"t":{"482":{"position":[[0,5]]},"639":{"position":[[0,5]]},"1136":{"position":[[0,3]]},"1978":{"position":[[0,3]]},"2282":{"position":[[21,3]]},"2296":{"position":[[36,3]]},"2496":{"position":[[0,5]]},"3471":{"position":[[10,5]]},"4271":{"position":[[0,5]]}}}],["usag",{"_index":223,"t":{"2434":{"position":[[25,5]]},"2903":{"position":[[0,5]]},"3511":{"position":[[44,5]]},"4753":{"position":[[34,5]]}}}],["user",{"_index":75,"t":{"352":{"position":[[5,5]]},"385":{"position":[[11,4]]},"1204":{"position":[[0,4]]},"2232":{"position":[[0,4]]},"2316":{"position":[[0,4]]},"2383":{"position":[[0,4]]},"2496":{"position":[[60,5]]},"4862":{"position":[[0,4]]}}}],["valid",{"_index":185,"t":{"1452":{"position":[[0,11]]}}}],["version",{"_index":272,"t":{"3385":{"position":[[11,8]]},"3477":{"position":[[18,7]]},"4338":{"position":[[8,7],[42,8]]},"4349":{"position":[[8,7]]},"4360":{"position":[[8,7]]}}}],["via",{"_index":71,"t":{"316":{"position":[[21,3]]},"1392":{"position":[[5,3]]},"1524":{"position":[[5,3]]},"1548":{"position":[[21,3]]},"1899":{"position":[[5,3]]}}}],["virtual",{"_index":123,"t":{"807":{"position":[[0,14]]},"2000":{"position":[[13,7]]}}}],["vmware",{"_index":206,"t":{"2233":{"position":[[13,6]]}}}],["volum",{"_index":297,"t":{"3419":{"position":[[28,6]]},"3425":{"position":[[14,6]]},"3435":{"position":[[10,6]]},"3939":{"position":[[18,6]]},"4003":{"position":[[4,6]]},"4114":{"position":[[0,6]]}}}],["wavestack",{"_index":18,"t":{"50":{"position":[[21,9]]}}}],["websso",{"_index":219,"t":{"2428":{"position":[[63,8]]}}}],["workflow",{"_index":41,"t":{"164":{"position":[[14,8]]}}}],["workload",{"_index":84,"t":{"416":{"position":[[4,8]]},"3449":{"position":[[49,9]]}}}],["workloads_",{"_index":380,"t":{"4213":{"position":[[40,10]]}}}],["x",{"_index":14,"t":{"42":{"position":[[21,1]]},"3324":{"position":[[30,1]]}}}],["yaml",{"_index":279,"t":{"3393":{"position":[[36,4]]},"3580":{"position":[[26,4]]}}}],["zone",{"_index":320,"t":{"3445":{"position":[[27,5]]},"4151":{"position":[[17,5]]},"4174":{"position":[[17,6]]}}}],["zuul",{"_index":63,"t":{"267":{"position":[[0,4]]},"352":{"position":[[0,4]]},"2111":{"position":[[0,4]]},"2677":{"position":[[0,4]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":6,"t":"Welcome to our SCS Community","u":"/community/","h":"#welcome-to-our-scs-community","p":5},{"i":10,"t":"Project p500924-harbor","u":"/community/central-services/plusserver-gx-scs","h":"#project-p500924-harbor","p":8},{"i":11,"t":"K8s clusters","u":"/community/central-services/plusserver-gx-scs","h":"#k8s-clusters","p":8},{"i":13,"t":"Project p500924-sig-monitoring1","u":"/community/central-services/plusserver-gx-scs","h":"#project-p500924-sig-monitoring1","p":8},{"i":14,"t":"K8s clusters","u":"/community/central-services/plusserver-gx-scs","h":"#k8s-clusters-1","p":8},{"i":18,"t":"How to request cloud resources","u":"/community/cloud-resources/","h":"#how-to-request-cloud-resources","p":16},{"i":20,"t":"plusserver","u":"/community/cloud-resources/","h":"#plusserver","p":16},{"i":21,"t":"Usage","u":"/community/cloud-resources/","h":"#usage","p":16},{"i":23,"t":"Users","u":"/community/cloud-resources/","h":"#users","p":16},{"i":25,"t":"Service Users","u":"/community/cloud-resources/","h":"#service-users","p":16},{"i":27,"t":"Projects","u":"/community/cloud-resources/","h":"#projects","p":16},{"i":29,"t":"Wavecon","u":"/community/cloud-resources/","h":"#wavecon","p":16},{"i":30,"t":"Service Users","u":"/community/cloud-resources/","h":"#service-users-1","p":16},{"i":32,"t":"Projects","u":"/community/cloud-resources/","h":"#projects-1","p":16},{"i":35,"t":"Getting Started with OpenStack CLI","u":"/community/cloud-resources/getting-started-openstack","h":"#getting-started-with-openstack-cli","p":34},{"i":36,"t":"OpenStackClient (CLI)","u":"/community/cloud-resources/getting-started-openstack","h":"#openstackclient-cli","p":34},{"i":38,"t":"Object Storage (S3)","u":"/community/cloud-resources/getting-started-openstack","h":"#object-storage-s3","p":34},{"i":40,"t":"References","u":"/community/cloud-resources/getting-started-openstack","h":"#references","p":34},{"i":43,"t":"Getting Started for the Gaia-X Demonstrator @ plusserver","u":"/community/cloud-resources/plusserver-gx-scs","h":"#getting-started-for-the-gaia-x-demonstrator--plusserver","p":42},{"i":44,"t":"URLs for access","u":"/community/cloud-resources/plusserver-gx-scs","h":"#urls-for-access","p":42},{"i":46,"t":"Authentication (UI)","u":"/community/cloud-resources/plusserver-gx-scs","h":"#authentication-ui","p":42},{"i":48,"t":"Getting Started with OpenStack","u":"/community/cloud-resources/plusserver-gx-scs","h":"#getting-started-with-openstack","p":42},{"i":51,"t":"URLs for access","u":"/community/cloud-resources/wavestack","h":"#urls-for-access","p":50},{"i":53,"t":"Authentication (UI)","u":"/community/cloud-resources/wavestack","h":"#authentication-ui","p":50},{"i":55,"t":"OpenStackClient (CLI)","u":"/community/cloud-resources/wavestack","h":"#openstackclient-cli","p":50},{"i":58,"t":"We’re an open community","u":"/community/collaboration/","h":"#were-an-open-community","p":57},{"i":60,"t":"Collaborating with issues and pull requests","u":"/community/collaboration/","h":"#collaborating-with-issues-and-pull-requests","p":57},{"i":62,"t":"Meetings","u":"/community/collaboration/","h":"#meetings","p":57},{"i":63,"t":"Project updates","u":"/community/collaboration/","h":"#project-updates","p":57},{"i":65,"t":"Sprint review/Backlog refinement/Sprint planning meetings","u":"/community/collaboration/","h":"#sprint-reviewbacklog-refinementsprint-planning-meetings","p":57},{"i":67,"t":"Special interest groups (SIGs) and hacking sessions","u":"/community/collaboration/","h":"#special-interest-groups-sigs-and-hacking-sessions","p":57},{"i":89,"t":"Step 1 – Documentation type","u":"/community/contribute/adding-docs-guide","h":"#step-1--documentation-type","p":87},{"i":91,"t":"1. Technical Documentation","u":"/community/contribute/adding-docs-guide","h":"#1-technical-documentation","p":87},{"i":92,"t":"Step 1 – Checklist","u":"/community/contribute/adding-docs-guide","h":"#step-1--checklist","p":87},{"i":94,"t":"Step 2 – Adding your repo to the docs.json","u":"/community/contribute/adding-docs-guide","h":"#step-2--adding-your-repo-to-the-docsjson","p":87},{"i":96,"t":"2. Operational documentation","u":"/community/contribute/adding-docs-guide","h":"#2-operational-documentation","p":87},{"i":98,"t":"3. Community documentation","u":"/community/contribute/adding-docs-guide","h":"#3-community-documentation","p":87},{"i":101,"t":"Structure Best Practice","u":"/community/contribute/doc-files-structure-guide","h":"#structure-best-practice","p":100},{"i":102,"t":"Overview - mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#overview---mandatory","p":100},{"i":104,"t":"Requirements - mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#requirements---mandatory","p":100},{"i":106,"t":"Quickstart - optional. If it is possible, then mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#quickstart---optional-if-it-is-possible-then-mandatory","p":100},{"i":108,"t":"Getting Started - mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#getting-started---mandatory","p":100},{"i":110,"t":"Configuration – mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#configuration--mandatory","p":100},{"i":112,"t":"Contribute – mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#contribute--mandatory","p":100},{"i":114,"t":"FAQ`s – optional","u":"/community/contribute/doc-files-structure-guide","h":"#faqs--optional","p":100},{"i":118,"t":"Pre Commit","u":"/community/contribute/linting-guide","h":"#pre-commit","p":116},{"i":120,"t":"Local Usage for development","u":"/community/contribute/linting-guide","h":"#local-usage-for-development","p":116},{"i":122,"t":"Github Workflows","u":"/community/contribute/linting-guide","h":"#github-workflows","p":116},{"i":126,"t":"Requirements","u":"/community/contribute/local-docusaurus-development-guide","h":"#requirements","p":124},{"i":128,"t":"Installation Guide","u":"/community/contribute/local-docusaurus-development-guide","h":"#installation-guide","p":124},{"i":129,"t":"Step 1 – Installing Node.js via nvm","u":"/community/contribute/local-docusaurus-development-guide","h":"#step-1--installing-nodejs-via-nvm","p":124},{"i":131,"t":"Step 2 – Cloning the repository","u":"/community/contribute/local-docusaurus-development-guide","h":"#step-2-cloning-the-repository","p":124},{"i":133,"t":"Step 3 – Installing dependencies","u":"/community/contribute/local-docusaurus-development-guide","h":"#step-3--installing-dependencies","p":124},{"i":135,"t":"Step 4 – Starting the development server","u":"/community/contribute/local-docusaurus-development-guide","h":"#step-4--starting-the-development-server","p":124},{"i":138,"t":"Admonitions","u":"/community/contribute/styleguide","h":"#admonitions","p":137},{"i":140,"t":"Blockquotes","u":"/community/contribute/styleguide","h":"#blockquotes","p":137},{"i":142,"t":"Codeblocks","u":"/community/contribute/styleguide","h":"#codeblocks","p":137},{"i":146,"t":"Task naming","u":"/community/contribute/styleguides/ansible_styleguide","h":"#task-naming","p":144},{"i":148,"t":"Key Order","u":"/community/contribute/styleguides/ansible_styleguide","h":"#key-order","p":144},{"i":150,"t":"Positioning and use of the become directive","u":"/community/contribute/styleguides/ansible_styleguide","h":"#positioning-and-use-of-the-become-directive","p":144},{"i":152,"t":"Position of the when condition","u":"/community/contribute/styleguides/ansible_styleguide","h":"#position-of-the-when-condition","p":144},{"i":154,"t":"Usage of collections","u":"/community/contribute/styleguides/ansible_styleguide","h":"#usage-of-collections","p":144},{"i":156,"t":"Usage of roles from other collections","u":"/community/contribute/styleguides/ansible_styleguide","h":"#usage-of-roles-from-other-collections","p":144},{"i":158,"t":"Parameters that offer lists","u":"/community/contribute/styleguides/ansible_styleguide","h":"#parameters-that-offer-lists","p":144},{"i":160,"t":"Usage of changed_when","u":"/community/contribute/styleguides/ansible_styleguide","h":"#usage-of-changed_when","p":144},{"i":162,"t":"Disable linting rules","u":"/community/contribute/styleguides/ansible_styleguide","h":"#disable-linting-rules","p":144},{"i":166,"t":"Information Architecture","u":"/community/contribute/docs-workflow-explanation","h":"#information-architecture","p":164},{"i":170,"t":"Reciprocity","u":"/community/license-considerations","h":"#reciprocity","p":168},{"i":172,"t":"Controversy","u":"/community/license-considerations","h":"#controversy","p":168},{"i":174,"t":"Affero","u":"/community/license-considerations","h":"#affero","p":168},{"i":176,"t":"Derived works and Strong vs. Weak Copyleft","u":"/community/license-considerations","h":"#derived-works-and-strong-vs-weak-copyleft","p":168},{"i":178,"t":"Patents","u":"/community/license-considerations","h":"#patents","p":168},{"i":180,"t":"Copyright Assignments and Contributor License Agreements","u":"/community/license-considerations","h":"#copyright-assignments-and-contributor-license-agreements","p":168},{"i":182,"t":"License in = License out","u":"/community/license-considerations","h":"#license-in--license-out","p":168},{"i":184,"t":"Further reading","u":"/community/license-considerations","h":"#further-reading","p":168},{"i":188,"t":"Values of our collaboration","u":"/community/mission-statement","h":"#values-of-our-collaboration","p":186},{"i":189,"t":"4+1 Open","u":"/community/mission-statement","h":"#41-open","p":186},{"i":191,"t":"The 'Four Open\"","u":"/community/mission-statement","h":"#the-four-open","p":186},{"i":193,"t":"+1 Open","u":"/community/mission-statement","h":"#1-open","p":186},{"i":195,"t":"Code of Conduct","u":"/community/mission-statement","h":"#code-of-conduct","p":186},{"i":196,"t":"Sovereign Cloud Stack Community","u":"/community/mission-statement","h":"#sovereign-cloud-stack-community","p":186},{"i":198,"t":"Our Standards","u":"/community/mission-statement","h":"#our-standards","p":186},{"i":204,"t":"Checklist 6 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-6-months-before-hackathon","p":202},{"i":206,"t":"Checklist advertising","u":"/community/hackathons/checklist","h":"#checklist-advertising","p":202},{"i":208,"t":"Checklist 5 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-5-months-before-hackathon","p":202},{"i":210,"t":"Checklist hotel","u":"/community/hackathons/checklist","h":"#checklist-hotel","p":202},{"i":211,"t":"Iportant things","u":"/community/hackathons/checklist","h":"#iportant-things","p":202},{"i":213,"t":"Nice-to-have things","u":"/community/hackathons/checklist","h":"#nice-to-have-things","p":202},{"i":215,"t":"Checklist 4 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-4-months-before-hackathon","p":202},{"i":217,"t":"Checklist for evening before location","u":"/community/hackathons/checklist","h":"#checklist-for-evening-before-location","p":202},{"i":219,"t":"Checklist rooms 1","u":"/community/hackathons/checklist","h":"#checklist-rooms-1","p":202},{"i":221,"t":"Checklist merch (examples)","u":"/community/hackathons/checklist","h":"#checklist-merch-examples","p":202},{"i":223,"t":"Checklist 3 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-3-months-before-hackathon","p":202},{"i":225,"t":"Checklist evening event","u":"/community/hackathons/checklist","h":"#checklist-evening-event","p":202},{"i":227,"t":"Checklist 2 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-2-months-before-hackathon","p":202},{"i":229,"t":"Snacks checklist","u":"/community/hackathons/checklist","h":"#snacks-checklist","p":202},{"i":230,"t":"Breakfast examples","u":"/community/hackathons/checklist","h":"#breakfast-examples","p":202},{"i":232,"t":"Snack exemples","u":"/community/hackathons/checklist","h":"#snack-exemples","p":202},{"i":234,"t":"Vegan snack examples","u":"/community/hackathons/checklist","h":"#vegan-snack-examples","p":202},{"i":236,"t":"Checklist rooms 2","u":"/community/hackathons/checklist","h":"#checklist-rooms-2","p":202},{"i":238,"t":"Checklist 1 month before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-1-month-before-hackathon","p":202},{"i":240,"t":"Checklist 1 week before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-1-week-before-hackathon","p":202},{"i":242,"t":"Checklist one day before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-one-day-before-hackathon","p":202},{"i":244,"t":"Checklist Hackathon Day X","u":"/community/hackathons/checklist","h":"#checklist-hackathon-day-x","p":202},{"i":246,"t":"Checklist after Hackathon","u":"/community/hackathons/checklist","h":"#checklist-after-hackathon","p":202},{"i":250,"t":"Further reading","u":"/community/tools/github/dco-and-licenses","h":"#further-reading","p":248},{"i":254,"t":"Usage","u":"/community/tools/jitsi","h":"#usage","p":252},{"i":257,"t":"Octo Reminder - your friendly assistant","u":"/community/tools/github/tips-and-tricks","h":"#octo-reminder---your-friendly-assistant","p":256},{"i":263,"t":"Client and Registration","u":"/community/tools/matrix","h":"#client-and-registration","p":261},{"i":268,"t":"Zuul CI/CD pipelines and project gating","u":"/community/tools/zuul","h":"#zuul-cicd-pipelines-and-project-gating","p":267},{"i":270,"t":"How to make a repo use Zuul","u":"/community/tools/zuul","h":"#how-to-make-a-repo-use-zuul","p":267},{"i":272,"t":"General information about Zuul","u":"/community/tools/zuul","h":"#general-information-about-zuul","p":267},{"i":279,"t":"Introduction","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#introduction","p":278},{"i":281,"t":"1. Understanding SCS Standards and RFC2119 Keywords","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#1-understanding-scs-standards-and-rfc2119-keywords","p":278},{"i":283,"t":"2. Interpreting RFC2119 Keywords in the Context of SCS","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#2-interpreting-rfc2119-keywords-in-the-context-of-scs","p":278},{"i":285,"t":"3. Channels for Output in Test Scripts","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#3-channels-for-output-in-test-scripts","p":278},{"i":287,"t":"4. Compliance and Test Passing Criteria","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#4-compliance-and-test-passing-criteria","p":278},{"i":289,"t":"Examples","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#examples","p":278},{"i":290,"t":"5.1 Example: Standards Document using RFC2119 Keywords","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#51-example-standards-document-using-rfc2119-keywords","p":278},{"i":292,"t":"Web Server Installation Standard","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#web-server-installation-standard","p":278},{"i":294,"t":"5.2 Example: Test script using RFC2119 Keywords","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#52-example-test-script-using-rfc2119-keywords","p":278},{"i":298,"t":"1. Mapping of RFC2119 Keywords","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#1-mapping-of-rfc2119-keywords","p":296},{"i":300,"t":"2. Unit and Regression Tests","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#2-unit-and-regression-tests","p":296},{"i":302,"t":"Naming Conventions","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#naming-conventions","p":296},{"i":304,"t":"Write Testable Conformance Tests","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#write-testable-conformance-tests","p":296},{"i":306,"t":"Pytest Test Example","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#pytest-test-example","p":296},{"i":308,"t":"3. Conformance Tests Shouldn't Require Admin Privileges","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#3-conformance-tests-shouldnt-require-admin-privileges","p":296},{"i":312,"t":"1. IaaS / OpenStack","u":"/contributor-docs/operations/iam/identity-federation-in-scs","h":"#1-iaas--openstack","p":310},{"i":314,"t":"2. CaaS","u":"/contributor-docs/operations/iam/identity-federation-in-scs","h":"#2-caas","p":310},{"i":318,"t":"1. Keystone","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#1-keystone","p":316},{"i":320,"t":"1.1 Keycloak IdP realm discovery","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#11-keycloak-idp-realm-discovery","p":316},{"i":322,"t":"1.2 Keystone mapping of token claims","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#12-keystone-mapping-of-token-claims","p":316},{"i":324,"t":"1.3 Horizon WebSSO for federated users","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#13-horizon-websso-for-federated-users","p":316},{"i":326,"t":"1.4 OpenStack CLI and API access for federated users","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#14-openstack-cli-and-api-access-for-federated-users","p":316},{"i":328,"t":"1.5 SSO Federation between to SCS deployments","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#15-sso-federation-between-to-scs-deployments","p":316},{"i":331,"t":"About","u":"/docs/","h":"#about","p":330},{"i":333,"t":"Architectural Overview","u":"/docs/","h":"#architectural-overview","p":330},{"i":335,"t":"Use Cases and Deployment Examples","u":"/docs/","h":"#use-cases-and-deployment-examples","p":330},{"i":336,"t":"IaaS Layer","u":"/docs/","h":"#iaas-layer","p":330},{"i":338,"t":"Container Layer","u":"/docs/","h":"#container-layer","p":330},{"i":340,"t":"Public SCS Clouds in production","u":"/docs/","h":"#public-scs-clouds-in-production","p":330},{"i":342,"t":"Development of SCS","u":"/docs/","h":"#development-of-scs","p":330},{"i":344,"t":"Issues and Bugs","u":"/docs/","h":"#issues-and-bugs","p":330},{"i":346,"t":"Contribute and Connect","u":"/docs/","h":"#contribute-and-connect","p":330},{"i":348,"t":"Releases and Roadmap","u":"/docs/","h":"#releases-and-roadmap","p":330},{"i":350,"t":"Standards, Conformity and Certification","u":"/docs/","h":"#standards-conformity-and-certification","p":330},{"i":353,"t":"Prerequisites","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#prerequisites","p":352},{"i":355,"t":"Who is it for?","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#who-is-it-for","p":352},{"i":357,"t":"Where do I start?","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#where-do-i-start","p":352},{"i":359,"t":"Where to save the Zuul relevant data?","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#where-to-save-the-zuul-relevant-data","p":352},{"i":361,"t":"Projects","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#projects","p":352},{"i":363,"t":"Pipelines","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#pipelines","p":352},{"i":365,"t":"Reports","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#reports","p":352},{"i":367,"t":"Jobs","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#jobs","p":352},{"i":371,"t":"Target groups","u":"/docs/container/","h":"#target-groups","p":369},{"i":373,"t":"What is it not","u":"/docs/container/","h":"#what-is-it-not","p":369},{"i":375,"t":"Prerequisites and Requirements","u":"/docs/container/","h":"#prerequisites-and-requirements","p":369},{"i":377,"t":"Features","u":"/docs/container/","h":"#features","p":369},{"i":379,"t":"Limitations","u":"/docs/container/","h":"#limitations","p":369},{"i":387,"t":"Steps to create a workload cluster","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","h":"#steps-to-create-a-workload-cluster","p":385},{"i":388,"t":"Get the right cluster stacks","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","h":"#get-the-right-cluster-stacks","p":385},{"i":390,"t":"Apply cluster stack resource","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","h":"#apply-cluster-stack-resource","p":385},{"i":392,"t":"Use the ClusterClasses","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","h":"#use-the-clusterclasses","p":385},{"i":394,"t":"Wait until cluster addons are ready","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","h":"#wait-until-cluster-addons-are-ready","p":385},{"i":396,"t":"Recap - how do Cluster API and Cluster Stacks work together?","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","h":"#recap---how-do-cluster-api-and-cluster-stacks-work-together","p":385},{"i":399,"t":"Architecture","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","h":"#architecture","p":398},{"i":400,"t":"Cluster stacks","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","h":"#cluster-stacks","p":398},{"i":402,"t":"Cluster Stack Operator","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","h":"#cluster-stack-operator","p":398},{"i":404,"t":"Cluster Stack Provider Integrations","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","h":"#cluster-stack-provider-integrations","p":398},{"i":406,"t":"Steps to make cluster stacks ready to use","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","h":"#steps-to-make-cluster-stacks-ready-to-use","p":398},{"i":408,"t":"Defining a cluster stack","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","h":"#defining-a-cluster-stack","p":398},{"i":410,"t":"Implementing a cluster stack","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","h":"#implementing-a-cluster-stack","p":398},{"i":412,"t":"Implementing a Cluster Stack Provider Integration","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","h":"#implementing-a-cluster-stack-provider-integration","p":398},{"i":414,"t":"Using everything","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","h":"#using-everything","p":398},{"i":420,"t":"Cluster Stacks and Cluster API","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept","h":"#cluster-stacks-and-cluster-api","p":418},{"i":422,"t":"Why cluster stacks?","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept","h":"#why-cluster-stacks","p":418},{"i":424,"t":"What do cluster stacks NOT try to do?","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept","h":"#what-do-cluster-stacks-not-try-to-do","p":418},{"i":426,"t":"Integrating cluster stacks with other tools","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept","h":"#integrating-cluster-stacks-with-other-tools","p":418},{"i":429,"t":"Develop Cluster Stack Operator","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/","h":"#develop-cluster-stack-operator","p":428},{"i":431,"t":"Setting Tilt up","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/","h":"#setting-tilt-up","p":428},{"i":433,"t":"Developing with Tilt","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/","h":"#developing-with-tilt","p":428},{"i":437,"t":"Release Process","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing","h":"#release-process","p":436},{"i":439,"t":"Step 1: Create and Push a tag","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing","h":"#step-1-create-and-push-a-tag","p":436},{"i":441,"t":"Step 2: Release in GitHub","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing","h":"#step-2-release-in-github","p":436},{"i":445,"t":"Cluster Stack framework","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology","h":"#cluster-stack-framework","p":443},{"i":447,"t":"A definition of a cluster stack","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology","h":"#a-definition-of-a-cluster-stack","p":443},{"i":449,"t":"An implementation of a cluster Stack","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology","h":"#an-implementation-of-a-cluster-stack","p":443},{"i":451,"t":"Cluster Stack Operator","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology","h":"#cluster-stack-operator","p":443},{"i":453,"t":"Cluster Stack Provider Integration","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology","h":"#cluster-stack-provider-integration","p":443},{"i":455,"t":"ClusterStack as custom resource definition","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology","h":"#clusterstack-as-custom-resource-definition","p":443},{"i":458,"t":"ClusterStack","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack","h":"#clusterstack","p":457},{"i":460,"t":"Lifecycle of a ClusterStack","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack","h":"#lifecycle-of-a-clusterstack","p":457},{"i":462,"t":"Overview of ClusterStack.Spec","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack","h":"#overview-of-clusterstackspec","p":457},{"i":464,"t":"Example of the ClusterStack object","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack","h":"#example-of-the-clusterstack-object","p":457},{"i":467,"t":"Quickstart","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","h":"#quickstart","p":466},{"i":469,"t":"Installation","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","h":"#installation","p":466},{"i":470,"t":"Prerequisites","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","h":"#prerequisites","p":466},{"i":472,"t":"Configure Release Source","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","h":"#configure-release-source","p":466},{"i":474,"t":"Install Cluster Stack Operator","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","h":"#install-cluster-stack-operator","p":466},{"i":484,"t":"Introduction","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","h":"#introduction","p":482},{"i":486,"t":"using right flags","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","h":"#using-right-flags","p":482},{"i":488,"t":"getting release assets","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","h":"#getting-release-assets","p":482},{"i":490,"t":"using local mode (toggling local mode)","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","h":"#using-local-mode-toggling-local-mode","p":482},{"i":492,"t":"Troubleshooting","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","h":"#troubleshooting","p":482},{"i":495,"t":"OpenStackClusterStackRelease controller","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","h":"#openstackclusterstackrelease-controller","p":494},{"i":497,"t":"OpenStackNodeImageRelease controller","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","h":"#openstacknodeimagerelease-controller","p":494},{"i":505,"t":"Setting Tilt up","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#setting-tilt-up","p":503},{"i":507,"t":"Developing with Tilt","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#developing-with-tilt","p":503},{"i":509,"t":"Applying ClusterStack","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#applying-clusterstack","p":503},{"i":511,"t":"Creating workload cluster","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#creating-workload-cluster","p":503},{"i":513,"t":"Toggle between local_mode and remote mode","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#toggle-between-local_mode-and-remote-mode","p":503},{"i":517,"t":"providerClient authentication err","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","h":"#providerclient-authentication-err","p":515},{"i":521,"t":"Configuration","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration","h":"#configuration","p":519},{"i":523,"t":"Pipelines","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration","h":"#pipelines","p":519},{"i":525,"t":"Jobs","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration","h":"#jobs","p":519},{"i":527,"t":"Secrets","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration","h":"#secrets","p":519},{"i":529,"t":"Job customization","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration","h":"#job-customization","p":519},{"i":532,"t":"Cluster Stacks","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","h":"#cluster-stacks","p":531},{"i":534,"t":"🔧 Usage","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","h":"#-usage","p":531},{"i":536,"t":"Layers of a Cluster Stack","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","h":"#layers-of-a-cluster-stack","p":531},{"i":538,"t":"📚 Cluster Class","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","h":"#-cluster-class","p":531},{"i":540,"t":"🎁 Cluster Addons","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","h":"#-cluster-addons","p":531},{"i":542,"t":"🎞️ Node Images","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","h":"#️-node-images","p":531},{"i":544,"t":"🌐 IaaS Provider, Kubernetes Service Provider, and Cluster API","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","h":"#-iaas-provider-kubernetes-service-provider-and-cluster-api","p":531},{"i":546,"t":"📌 Defining and Adding Providers","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","h":"#-defining-and-adding-providers","p":531},{"i":548,"t":"📁 Repository Structure","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","h":"#-repository-structure","p":531},{"i":550,"t":"📑 Versioning","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","h":"#-versioning","p":531},{"i":554,"t":"Example","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","h":"#example","p":552},{"i":556,"t":"Available variables","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","h":"#available-variables","p":552},{"i":559,"t":"Clone the Repo","u":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","h":"#clone-the-repo","p":558},{"i":561,"t":"Makefile","u":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","h":"#makefile","p":558},{"i":563,"t":"make build","u":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","h":"#make-build","p":558},{"i":565,"t":"csctl --help","u":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","h":"#csctl---help","p":558},{"i":567,"t":"go run main.go ...","u":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","h":"#go-run-maingo-","p":558},{"i":569,"t":"Create Docker Cluster Stack","u":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","h":"#create-docker-cluster-stack","p":558},{"i":573,"t":"Prerequisites","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","h":"#prerequisites","p":571},{"i":575,"t":"Initialize the management cluster","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","h":"#initialize-the-management-cluster","p":571},{"i":577,"t":"CSO and CSPO variables preparation (CSP)","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","h":"#cso-and-cspo-variables-preparation-csp","p":571},{"i":579,"t":"CSO and CSPO deployment (CSP)","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","h":"#cso-and-cspo-deployment-csp","p":571},{"i":581,"t":"Define a namespace for a tenant (CSP/per tenant)","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","h":"#define-a-namespace-for-a-tenant-cspper-tenant","p":571},{"i":583,"t":"Deploy CSP-helper chart","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","h":"#deploy-csp-helper-chart","p":571},{"i":585,"t":"Create Cluster Stack definition (CSP/per tenant)","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","h":"#create-cluster-stack-definition-cspper-tenant","p":571},{"i":587,"t":"Create the workload cluster resource (SCS-User/customer)","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","h":"#create-the-workload-cluster-resource-scs-usercustomer","p":571},{"i":589,"t":"Check the workload cluster health","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","h":"#check-the-workload-cluster-health","p":571},{"i":592,"t":"Introduction","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"","p":591},{"i":594,"t":"Motivation","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"","p":591},{"i":596,"t":"Proposal","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"","p":591},{"i":598,"t":"User stories","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"","p":591},{"i":599,"t":"User story 1: Developer releasing cluster stacks","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#user-story-1-developer-releasing-cluster-stacks","p":591},{"i":601,"t":"User story 2: Developer versioning cluster stacks","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#user-story-2-developer-versioning-cluster-stacks","p":591},{"i":603,"t":"User story 3: Multiple developers work in parallel on one cluster stack","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#user-story-3-multiple-developers-work-in-parallel-on-one-cluster-stack","p":591},{"i":605,"t":"User story 4: Developer updating cluster stack that is used in production","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#user-story-4-developer-updating-cluster-stack-that-is-used-in-production","p":591},{"i":607,"t":"User story 5: Automated testing of cluster stacks","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#user-story-5-automated-testing-of-cluster-stacks","p":591},{"i":609,"t":"Risks & Mitigations","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"","p":591},{"i":610,"t":"Two forms of templating","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#two-forms-of-templating","p":591},{"i":612,"t":"Design details","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"","p":591},{"i":613,"t":"Generic vs provider-specific work","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#generic-vs-provider-specific-work","p":591},{"i":615,"t":"Generic work","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#generic-work","p":591},{"i":617,"t":"Provider-specific work","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#provider-specific-work","p":591},{"i":619,"t":"Configuration","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#configuration","p":591},{"i":621,"t":"Configuration file","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#configuration-file","p":591},{"i":623,"t":"Flags","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#flags","p":591},{"i":625,"t":"Environment variables","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#environment-variables","p":591},{"i":627,"t":"Commands of CLI tool","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#commands-of-cli-tool","p":591},{"i":629,"t":"Modes","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#modes","p":591},{"i":631,"t":"Stable","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#stable","p":591},{"i":633,"t":"Hash","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#hash","p":591},{"i":635,"t":"Beta","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#beta","p":591},{"i":637,"t":"Custom (e.g. for PRs)","u":"/docs/container/components/cluster-stacks/components/csctl/design","h":"#custom-eg-for-prs","p":591},{"i":640,"t":"What does csctl do?","u":"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl","h":"#what-does-csctl-do","p":639},{"i":642,"t":"Different modes of csctl","u":"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl","h":"#different-modes-of-csctl","p":639},{"i":644,"t":"Hash mode","u":"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl","h":"#hash-mode","p":639},{"i":646,"t":"Stable mode","u":"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl","h":"#stable-mode","p":639},{"i":648,"t":"Beta mode","u":"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl","h":"#beta-mode","p":639},{"i":650,"t":"Custom mode","u":"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl","h":"#custom-mode","p":639},{"i":652,"t":"Installing csctl","u":"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl","h":"#installing-csctl","p":639},{"i":654,"t":"Creating Cluster Stacks","u":"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl","h":"#creating-cluster-stacks","p":639},{"i":658,"t":"Overview","u":"/docs/container/components/cluster-stacks/components/csctl/getting_started","h":"#overview","p":656},{"i":660,"t":"Configuring csctl","u":"/docs/container/components/cluster-stacks/components/csctl/getting_started","h":"#configuring-csctl","p":656},{"i":663,"t":"Introduction","u":"/docs/container/components/cluster-stacks/components/csctl/overview","h":"#introduction","p":662},{"i":665,"t":"What does csctl do?","u":"/docs/container/components/cluster-stacks/components/csctl/overview","h":"#what-does-csctl-do","p":662},{"i":667,"t":"Features of csctl","u":"/docs/container/components/cluster-stacks/components/csctl/overview","h":"#features-of-csctl","p":662},{"i":670,"t":"Installation","u":"/docs/container/components/cluster-stacks/components/csctl/quickstart","h":"#installation","p":669},{"i":672,"t":"Creating Cluster Stacks","u":"/docs/container/components/cluster-stacks/components/csctl/quickstart","h":"#creating-cluster-stacks","p":669},{"i":674,"t":"Different modes of csctl","u":"/docs/container/components/cluster-stacks/components/csctl/quickstart","h":"#different-modes-of-csctl","p":669},{"i":676,"t":"Hash mode","u":"/docs/container/components/cluster-stacks/components/csctl/quickstart","h":"#hash-mode","p":669},{"i":678,"t":"Stable mode","u":"/docs/container/components/cluster-stacks/components/csctl/quickstart","h":"#stable-mode","p":669},{"i":680,"t":"Beta mode","u":"/docs/container/components/cluster-stacks/components/csctl/quickstart","h":"#beta-mode","p":669},{"i":682,"t":"Custom mode","u":"/docs/container/components/cluster-stacks/components/csctl/quickstart","h":"#custom-mode","p":669},{"i":685,"t":"Prerequisites","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#prerequisites","p":684},{"i":687,"t":"Install and wait for operators","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#install-and-wait-for-operators","p":684},{"i":689,"t":"Create redis and postgres clusters","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#create-redis-and-postgres-clusters","p":684},{"i":691,"t":"Install Harbor","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#install-harbor","p":684},{"i":693,"t":"All in one installation using FluxCD Kustomization and GitRepository reconciliation","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#all-in-one-installation-using-fluxcd-kustomization-and-gitrepository-reconciliation","p":684},{"i":697,"t":"Prerequisites","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#prerequisites","p":695},{"i":698,"t":"Kubernetes cluster","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#kubernetes-cluster","p":695},{"i":700,"t":"S3 bucket and EC2 credentials","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#s3-bucket-and-ec2-credentials","p":695},{"i":702,"t":"Velero client","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#velero-client","p":695},{"i":704,"t":"Velero server","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#velero-server","p":695},{"i":707,"t":"Backup Harbor Instance","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#backup-harbor-instance","p":695},{"i":709,"t":"Restore Harbor Instance","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#restore-harbor-instance","p":695},{"i":713,"t":"Data Access Layer","u":"/docs/container/components/container-registry/docs/persistence","h":"#data-access-layer","p":711},{"i":714,"t":"Redis","u":"/docs/container/components/container-registry/docs/persistence","h":"#redis","p":711},{"i":716,"t":"Database (PostgreSQL)","u":"/docs/container/components/container-registry/docs/persistence","h":"#database-postgresql","p":711},{"i":718,"t":"OCI Distribution Registry","u":"/docs/container/components/container-registry/docs/persistence","h":"#oci-distribution-registry","p":711},{"i":720,"t":"Fundamental Services","u":"/docs/container/components/container-registry/docs/persistence","h":"#fundamental-services","p":711},{"i":721,"t":"Proxy, Core, Web Portal","u":"/docs/container/components/container-registry/docs/persistence","h":"#proxy-core-web-portal","p":711},{"i":723,"t":"Trivy","u":"/docs/container/components/container-registry/docs/persistence","h":"#trivy","p":711},{"i":725,"t":"JobService","u":"/docs/container/components/container-registry/docs/persistence","h":"#jobservice","p":711},{"i":729,"t":"Prerequisites","u":"/docs/container/components/container-registry/docs/migration","h":"#prerequisites","p":727},{"i":731,"t":"Kubernetes clusters","u":"/docs/container/components/container-registry/docs/migration","h":"#kubernetes-clusters","p":727},{"i":733,"t":"S3 bucket and EC2 credentials","u":"/docs/container/components/container-registry/docs/migration","h":"#s3-bucket-and-ec2-credentials","p":727},{"i":735,"t":"Velero client","u":"/docs/container/components/container-registry/docs/migration","h":"#velero-client","p":727},{"i":737,"t":"Velero server","u":"/docs/container/components/container-registry/docs/migration","h":"#velero-server","p":727},{"i":744,"t":"Prerequisites","u":"/docs/container/components/container-registry/docs/scs-deployment","h":"#prerequisites","p":742},{"i":746,"t":"Install Harbor","u":"/docs/container/components/container-registry/docs/scs-deployment","h":"#install-harbor","p":742},{"i":750,"t":"Prerequisites","u":"/docs/container/components/container-registry/docs/quickstart","h":"#prerequisites","p":748},{"i":752,"t":"Install Harbor container registry","u":"/docs/container/components/container-registry/docs/quickstart","h":"#install-harbor-container-registry","p":748},{"i":771,"t":"What does SCS stand for?","u":"/docs/faq/","h":"#what-does-scs-stand-for","p":770},{"i":773,"t":"Who is SCS intended for?","u":"/docs/faq/","h":"#who-is-scs-intended-for","p":770},{"i":775,"t":"Who or what is behind SCS?","u":"/docs/faq/","h":"#who-or-what-is-behind-scs","p":770},{"i":777,"t":"Why is there a need for a standardized cloud environment?","u":"/docs/faq/","h":"#why-is-there-a-need-for-a-standardized-cloud-environment","p":770},{"i":779,"t":"Where can I find the SCS standards?","u":"/docs/faq/","h":"#where-can-i-find-the-scs-standards","p":770},{"i":781,"t":"How is the SCS different from other cloud environments (e.g. AWS, Azure,...)?","u":"/docs/faq/","h":"#how-is-the-scs-different-from-other-cloud-environments-eg-aws-azure","p":770},{"i":783,"t":"My company already has a cloud environment. Can we still use the SCS?","u":"/docs/faq/","h":"#my-company-already-has-a-cloud-environment-can-we-still-use-the-scs","p":770},{"i":785,"t":"What does reference implementation mean?","u":"/docs/faq/","h":"#what-does-reference-implementation-mean","p":770},{"i":787,"t":"Do I need to use the reference implementation to be SCS compliant?","u":"/docs/faq/","h":"#do-i-need-to-use-the-reference-implementation-to-be-scs-compliant","p":770},{"i":789,"t":"Do I have to use all layers of the reference implementation (IaaS, CaaS)?","u":"/docs/faq/","h":"#do-i-have-to-use-all-layers-of-the-reference-implementation-iaas-caas","p":770},{"i":791,"t":"What does IaaS mean?","u":"/docs/faq/","h":"#what-does-iaas-mean","p":770},{"i":793,"t":"How is the IaaS layer structured?","u":"/docs/faq/","h":"#how-is-the-iaas-layer-structured","p":770},{"i":795,"t":"What does CaaS mean? (Container Layer)","u":"/docs/faq/","h":"#what-does-caas-mean-container-layer","p":770},{"i":797,"t":"I want to try out the SCS! Where do I start?","u":"/docs/faq/","h":"#i-want-to-try-out-the-scs-where-do-i-start","p":770},{"i":799,"t":"I want to use an SCS Cloud! How do I get started?","u":"/docs/faq/","h":"#i-want-to-use-an-scs-cloud-how-do-i-get-started","p":770},{"i":801,"t":"I want to use the SCS in my company and build my own cloud! Where do I start?","u":"/docs/faq/","h":"#i-want-to-use-the-scs-in-my-company-and-build-my-own-cloud-where-do-i-start","p":770},{"i":803,"t":"I have a technical problem. Where can I find help?","u":"/docs/faq/","h":"#i-have-a-technical-problem-where-can-i-find-help","p":770},{"i":811,"t":"Definition of a Region","u":"/docs/glossary","h":"#definition-of-a-region","p":809},{"i":813,"t":"Definition of a Availability Zone","u":"/docs/glossary","h":"#definition-of-a-availability-zone","p":809},{"i":815,"t":"Definition of Host Aggregates","u":"/docs/glossary","h":"#definition-of-host-aggregates","p":809},{"i":817,"t":"Definition of a Cell","u":"/docs/glossary","h":"#definition-of-a-cell","p":809},{"i":819,"t":"Definition of a Control Plane","u":"/docs/glossary","h":"#definition-of-a-control-plane","p":809},{"i":821,"t":"Definition of Control Node","u":"/docs/glossary","h":"#definition-of-control-node","p":809},{"i":823,"t":"Definition of Compute Node","u":"/docs/glossary","h":"#definition-of-compute-node","p":809},{"i":825,"t":"Definition of Manager Node","u":"/docs/glossary","h":"#definition-of-manager-node","p":809},{"i":827,"t":"Definition of provider network","u":"/docs/glossary","h":"#definition-of-provider-network","p":809},{"i":829,"t":"Definition of API","u":"/docs/glossary","h":"#definition-of-api","p":809},{"i":831,"t":"Horizon","u":"/docs/glossary","h":"#horizon","p":809},{"i":833,"t":"Message Queue","u":"/docs/glossary","h":"#message-queue","p":809},{"i":835,"t":"Keystone","u":"/docs/glossary","h":"#keystone","p":809},{"i":837,"t":"Glance","u":"/docs/glossary","h":"#glance","p":809},{"i":839,"t":"OSISM","u":"/docs/glossary","h":"#osism","p":809},{"i":841,"t":"Ceph","u":"/docs/glossary","h":"#ceph","p":809},{"i":843,"t":"Nova","u":"/docs/glossary","h":"#nova","p":809},{"i":845,"t":"Neutron","u":"/docs/glossary","h":"#neutron","p":809},{"i":847,"t":"Cinder","u":"/docs/glossary","h":"#cinder","p":809},{"i":849,"t":"Swift","u":"/docs/glossary","h":"#swift","p":809},{"i":851,"t":"Ceph OSD","u":"/docs/glossary","h":"#ceph-osd","p":809},{"i":853,"t":"Personas","u":"/docs/glossary","h":"#personas","p":809},{"i":858,"t":"Requirements","u":"/docs/iaas/components/image-manager/","h":"#requirements","p":856},{"i":860,"t":"OpenStack Image Service (Glance)","u":"/docs/iaas/components/image-manager/","h":"#openstack-image-service-glance","p":856},{"i":862,"t":"Object storage backend","u":"/docs/iaas/components/image-manager/","h":"#object-storage-backend","p":856},{"i":864,"t":"Getting started","u":"/docs/iaas/components/image-manager/","h":"#getting-started","p":856},{"i":866,"t":"Image definitions","u":"/docs/iaas/components/image-manager/","h":"#image-definitions","p":856},{"i":868,"t":"SCS image standard","u":"/docs/iaas/components/image-manager/","h":"#scs-image-standard","p":856},{"i":870,"t":"Image with regular rebuilds","u":"/docs/iaas/components/image-manager/","h":"#image-with-regular-rebuilds","p":856},{"i":872,"t":"Image without regular rebuild","u":"/docs/iaas/components/image-manager/","h":"#image-without-regular-rebuild","p":856},{"i":874,"t":"Other properties","u":"/docs/iaas/components/image-manager/","h":"#other-properties","p":856},{"i":876,"t":"Usage","u":"/docs/iaas/components/image-manager/","h":"#usage","p":856},{"i":877,"t":"Mirroring images","u":"/docs/iaas/components/image-manager/","h":"#mirroring-images","p":856},{"i":879,"t":"Updating images","u":"/docs/iaas/components/image-manager/","h":"#updating-images","p":856},{"i":882,"t":"Overview","u":"/docs/iaas/components/image-manager/update","h":"#overview","p":881},{"i":884,"t":"Installation","u":"/docs/iaas/components/image-manager/update","h":"#installation","p":881},{"i":886,"t":"Usage","u":"/docs/iaas/components/image-manager/update","h":"#usage","p":881},{"i":889,"t":"Overview","u":"/docs/iaas/components/flavor-manager","h":"#overview","p":888},{"i":891,"t":"Installation","u":"/docs/iaas/components/flavor-manager","h":"#installation","p":888},{"i":893,"t":"Usage","u":"/docs/iaas/components/flavor-manager","h":"#usage","p":888},{"i":895,"t":"Definitions","u":"/docs/iaas/components/flavor-manager","h":"#definitions","p":888},{"i":897,"t":"Name parser and generator","u":"/docs/iaas/components/flavor-manager","h":"#name-parser-and-generator","p":888},{"i":900,"t":"Overview","u":"/docs/iaas/components/project-manager","h":"#overview","p":899},{"i":902,"t":"Installation","u":"/docs/iaas/components/project-manager","h":"#installation","p":899},{"i":904,"t":"Defaults","u":"/docs/iaas/components/project-manager","h":"#defaults","p":899},{"i":905,"t":"create.py","u":"/docs/iaas/components/project-manager","h":"#createpy","p":899},{"i":907,"t":"manage.py","u":"/docs/iaas/components/project-manager","h":"#managepy","p":899},{"i":909,"t":"Usage","u":"/docs/iaas/components/project-manager","h":"#usage","p":899},{"i":911,"t":"create.py","u":"/docs/iaas/components/project-manager","h":"#createpy-1","p":899},{"i":913,"t":"manage.py","u":"/docs/iaas/components/project-manager","h":"#managepy-1","p":899},{"i":915,"t":"Config files","u":"/docs/iaas/components/project-manager","h":"#config-files","p":899},{"i":917,"t":"Quota Templates","u":"/docs/iaas/components/project-manager","h":"#quota-templates","p":899},{"i":919,"t":"Setup Endpoints","u":"/docs/iaas/components/project-manager","h":"#setup-endpoints","p":899},{"i":923,"t":"Intro","u":"/docs/iaas/components/openstack-health-monitor","h":"#intro","p":921},{"i":925,"t":"Setting up the driver VM","u":"/docs/iaas/components/openstack-health-monitor","h":"#setting-up-the-driver-vm","p":921},{"i":927,"t":"Internal vs external monitoring","u":"/docs/iaas/components/openstack-health-monitor","h":"#internal-vs-external-monitoring","p":921},{"i":929,"t":"Unprivileged operation","u":"/docs/iaas/components/openstack-health-monitor","h":"#unprivileged-operation","p":921},{"i":931,"t":"Driver VM via openstack CLI","u":"/docs/iaas/components/openstack-health-monitor","h":"#driver-vm-via-openstack-cli","p":921},{"i":933,"t":"Configuring openstack CLI on the driver VM","u":"/docs/iaas/components/openstack-health-monitor","h":"#configuring-openstack-cli-on-the-driver-vm","p":921},{"i":935,"t":"Custom CA","u":"/docs/iaas/components/openstack-health-monitor","h":"#custom-ca","p":921},{"i":937,"t":"Your first api_monitor.sh iteration","u":"/docs/iaas/components/openstack-health-monitor","h":"#your-first-api_monitorsh-iteration","p":921},{"i":939,"t":"Resource impact and charging","u":"/docs/iaas/components/openstack-health-monitor","h":"#resource-impact-and-charging","p":921},{"i":941,"t":"Automating startup and cleanup","u":"/docs/iaas/components/openstack-health-monitor","h":"#automating-startup-and-cleanup","p":921},{"i":943,"t":"Changing parameters and restarting","u":"/docs/iaas/components/openstack-health-monitor","h":"#changing-parameters-and-restarting","p":921},{"i":945,"t":"Multiple instances","u":"/docs/iaas/components/openstack-health-monitor","h":"#multiple-instances","p":921},{"i":947,"t":"Alarming and Logs","u":"/docs/iaas/components/openstack-health-monitor","h":"#alarming-and-logs","p":921},{"i":948,"t":"eMail","u":"/docs/iaas/components/openstack-health-monitor","h":"#email","p":921},{"i":950,"t":"Log files","u":"/docs/iaas/components/openstack-health-monitor","h":"#log-files","p":921},{"i":952,"t":"Data collection and dashboard","u":"/docs/iaas/components/openstack-health-monitor","h":"#data-collection-and-dashboard","p":921},{"i":954,"t":"Telegraf","u":"/docs/iaas/components/openstack-health-monitor","h":"#telegraf","p":921},{"i":956,"t":"InfluxDB","u":"/docs/iaas/components/openstack-health-monitor","h":"#influxdb","p":921},{"i":958,"t":"Add -S CLOUDNAME to your run_CLOUDNAME.sh script","u":"/docs/iaas/components/openstack-health-monitor","h":"#add--s-cloudname-to-your-run_cloudnamesh-script","p":921},{"i":960,"t":"Caddy (Reverse Proxy)","u":"/docs/iaas/components/openstack-health-monitor","h":"#caddy-reverse-proxy","p":921},{"i":962,"t":"Grafana","u":"/docs/iaas/components/openstack-health-monitor","h":"#grafana","p":921},{"i":964,"t":"Maintenance","u":"/docs/iaas/components/openstack-health-monitor","h":"#maintenance","p":921},{"i":966,"t":"Unattended upgrades","u":"/docs/iaas/components/openstack-health-monitor","h":"#unattended-upgrades","p":921},{"i":968,"t":"sshd setup","u":"/docs/iaas/components/openstack-health-monitor","h":"#sshd-setup","p":921},{"i":970,"t":"Updating openstack-health-monitor","u":"/docs/iaas/components/openstack-health-monitor","h":"#updating-openstack-health-monitor","p":921},{"i":972,"t":"Backup","u":"/docs/iaas/components/openstack-health-monitor","h":"#backup","p":921},{"i":974,"t":"Troubleshooting","u":"/docs/iaas/components/openstack-health-monitor","h":"#troubleshooting","p":921},{"i":975,"t":"Debugging issues","u":"/docs/iaas/components/openstack-health-monitor","h":"#debugging-issues","p":921},{"i":977,"t":"Analyzing failures","u":"/docs/iaas/components/openstack-health-monitor","h":"#analyzing-failures","p":921},{"i":979,"t":"Cleaning things up","u":"/docs/iaas/components/openstack-health-monitor","h":"#cleaning-things-up","p":921},{"i":982,"t":"Preparations","u":"/docs/iaas/components/resource-manager","h":"#preparations","p":981},{"i":984,"t":"Nova","u":"/docs/iaas/components/resource-manager","h":"#nova","p":981},{"i":985,"t":"Live migration","u":"/docs/iaas/components/resource-manager","h":"#live-migration","p":981},{"i":987,"t":"Evacuation","u":"/docs/iaas/components/resource-manager","h":"#evacuation","p":981},{"i":989,"t":"Octavia","u":"/docs/iaas/components/resource-manager","h":"#octavia","p":981},{"i":990,"t":"Amphora rotation","u":"/docs/iaas/components/resource-manager","h":"#amphora-rotation","p":981},{"i":992,"t":"Cinder","u":"/docs/iaas/components/resource-manager","h":"#cinder","p":981},{"i":994,"t":"Orphans","u":"/docs/iaas/components/resource-manager","h":"#orphans","p":981},{"i":998,"t":"Overview","u":"/docs/iaas/components/simple-stress","h":"#overview","p":997},{"i":1000,"t":"Installation","u":"/docs/iaas/components/simple-stress","h":"#installation","p":997},{"i":1002,"t":"Defaults","u":"/docs/iaas/components/simple-stress","h":"#defaults","p":997},{"i":1004,"t":"Usage","u":"/docs/iaas/components/simple-stress","h":"#usage","p":997},{"i":1006,"t":"Config files","u":"/docs/iaas/components/simple-stress","h":"#config-files","p":997},{"i":1011,"t":"Highlevel Overview","u":"/docs/iaas/guides/concept-guide/","h":"#highlevel-overview","p":1010},{"i":1012,"t":"Components in a cluster","u":"/docs/iaas/guides/concept-guide/","h":"#components-in-a-cluster","p":1010},{"i":1014,"t":"Requirements","u":"/docs/iaas/guides/concept-guide/","h":"#requirements","p":1010},{"i":1015,"t":"Layers in a cluster","u":"/docs/iaas/guides/concept-guide/","h":"#layers-in-a-cluster","p":1010},{"i":1017,"t":"Cluster design","u":"/docs/iaas/guides/concept-guide/","h":"#cluster-design","p":1010},{"i":1019,"t":"Use cases","u":"/docs/iaas/guides/concept-guide/","h":"#use-cases","p":1010},{"i":1021,"t":"Hardware Bill of Materials","u":"/docs/iaas/guides/concept-guide/","h":"#hardware-bill-of-materials","p":1010},{"i":1024,"t":"Preface","u":"/docs/iaas/deployment-examples/artcodix/","h":"#preface","p":1023},{"i":1026,"t":"Node type definitions","u":"/docs/iaas/deployment-examples/artcodix/","h":"#node-type-definitions","p":1023},{"i":1027,"t":"Control Node","u":"/docs/iaas/deployment-examples/artcodix/","h":"#control-node","p":1023},{"i":1029,"t":"Compute Node (HCI/no HCI)","u":"/docs/iaas/deployment-examples/artcodix/","h":"#compute-node-hcino-hci","p":1023},{"i":1031,"t":"Storage Node","u":"/docs/iaas/deployment-examples/artcodix/","h":"#storage-node","p":1023},{"i":1033,"t":"Network Node","u":"/docs/iaas/deployment-examples/artcodix/","h":"#network-node","p":1023},{"i":1035,"t":"Nodes in this deployment example","u":"/docs/iaas/deployment-examples/artcodix/","h":"#nodes-in-this-deployment-example","p":1023},{"i":1037,"t":"Use cases and validation","u":"/docs/iaas/deployment-examples/artcodix/","h":"#use-cases-and-validation","p":1023},{"i":1039,"t":"Control Node","u":"/docs/iaas/deployment-examples/artcodix/","h":"#control-node-1","p":1023},{"i":1041,"t":"Compute Node (HCI)","u":"/docs/iaas/deployment-examples/artcodix/","h":"#compute-node-hci","p":1023},{"i":1043,"t":"Network","u":"/docs/iaas/deployment-examples/artcodix/","h":"#network","p":1023},{"i":1045,"t":"Scenario A: Not recommended for production","u":"/docs/iaas/deployment-examples/artcodix/","h":"#scenario-a-not-recommended-for-production","p":1023},{"i":1047,"t":"Scenario B: Minimum recommended setup for small production environments","u":"/docs/iaas/deployment-examples/artcodix/","h":"#scenario-b-minimum-recommended-setup-for-small-production-environments","p":1023},{"i":1049,"t":"Network adapters","u":"/docs/iaas/deployment-examples/artcodix/","h":"#network-adapters","p":1023},{"i":1051,"t":"How to continue","u":"/docs/iaas/deployment-examples/artcodix/","h":"#how-to-continue","p":1023},{"i":1057,"t":"Lifecycle Management of Cluster API in OSISM","u":"/docs/iaas/guides/concept-guide/components/clusterapi","h":"#lifecycle-management-of-cluster-api-in-osism","p":1055},{"i":1058,"t":"Cluster API with OpenStack Magnum","u":"/docs/iaas/guides/concept-guide/components/clusterapi","h":"#cluster-api-with-openstack-magnum","p":1055},{"i":1059,"t":"Cluster API with SCS Cluster Stacks","u":"/docs/iaas/guides/concept-guide/components/clusterapi","h":"#cluster-api-with-scs-cluster-stacks","p":1055},{"i":1062,"t":"Lifecycle Management of Ceph in OSISM","u":"/docs/iaas/guides/concept-guide/components/ceph","h":"#lifecycle-management-of-ceph-in-osism","p":1060},{"i":1065,"t":"Lifecycle Management of Gardener in OSISM","u":"/docs/iaas/guides/concept-guide/components/gardener","h":"#lifecycle-management-of-gardener-in-osism","p":1063},{"i":1068,"t":"Lifecycle Management of Ironic in OSISM","u":"/docs/iaas/guides/concept-guide/components/ironic","h":"#lifecycle-management-of-ironic-in-osism","p":1066},{"i":1070,"t":"Lifecycle Management of K3S in OSISM","u":"/docs/iaas/guides/concept-guide/components/k3s","h":"#lifecycle-management-of-k3s-in-osism","p":1069},{"i":1072,"t":"Lifecycle Management of OpenStack in OSISM","u":"/docs/iaas/guides/concept-guide/components/openstack","h":"#lifecycle-management-of-openstack-in-osism","p":1071},{"i":1074,"t":"OpenStack cluster","u":"/docs/iaas/guides/concept-guide/components/openstack","h":"#openstack-cluster","p":1071},{"i":1076,"t":"OpenStack services architecture","u":"/docs/iaas/guides/concept-guide/components/openstack","h":"#openstack-services-architecture","p":1071},{"i":1078,"t":"General architecture of OpenStack services","u":"/docs/iaas/guides/concept-guide/components/openstack","h":"","p":1071},{"i":1080,"t":"Multitenancy with OpenStack","u":"/docs/iaas/guides/concept-guide/components/openstack","h":"","p":1071},{"i":1083,"t":"Lifecycle Management of Keycloak in OSISM","u":"/docs/iaas/guides/concept-guide/components/keycloak","h":"#lifecycle-management-of-keycloak-in-osism","p":1082},{"i":1085,"t":"Lifecycle Management of Netdata in OSISM","u":"/docs/iaas/guides/concept-guide/components/netdata","h":"#lifecycle-management-of-netdata-in-osism","p":1084},{"i":1087,"t":"Lifecycle Management of Prometheus in OSISM","u":"/docs/iaas/guides/concept-guide/components/prometheus","h":"#lifecycle-management-of-prometheus-in-osism","p":1086},{"i":1088,"t":"Lifecycle Management of Grafana in OSISM","u":"/docs/iaas/guides/concept-guide/components/prometheus","h":"#lifecycle-management-of-grafana-in-osism","p":1086},{"i":1090,"t":"## Lifecycle Management of SONiC in OSISM","u":"/docs/iaas/guides/concept-guide/components/sonic","h":"#-lifecycle-management-of-sonic-in-osism","p":1089},{"i":1091,"t":"## Lifecycle Management of Open Virtual Network (OVN) in OSISM","u":"/docs/iaas/guides/concept-guide/components/sonic","h":"#-lifecycle-management-of-open-virtual-network-ovn-in-osism","p":1089},{"i":1092,"t":"## Lifecycle Management of Open vSwitch (OVS) in OSISM","u":"/docs/iaas/guides/concept-guide/components/sonic","h":"#-lifecycle-management-of-open-vswitch-ovs-in-osism","p":1089},{"i":1094,"t":"Lifecycle Management of Teleport in OSISM","u":"/docs/iaas/guides/concept-guide/components/teleport","h":"#lifecycle-management-of-teleport-in-osism","p":1093},{"i":1097,"t":"Compute architecture","u":"/docs/iaas/guides/concept-guide/design","h":"#compute-architecture","p":1095},{"i":1098,"t":"Control plane architecture","u":"/docs/iaas/guides/concept-guide/design","h":"#control-plane-architecture","p":1095},{"i":1099,"t":"Storage architecture","u":"/docs/iaas/guides/concept-guide/design","h":"#storage-architecture","p":1095},{"i":1100,"t":"Network architecture","u":"/docs/iaas/guides/concept-guide/design","h":"#network-architecture","p":1095},{"i":1101,"t":"Identity architecture","u":"/docs/iaas/guides/concept-guide/design","h":"#identity-architecture","p":1095},{"i":1104,"t":"Control nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#control-nodes","p":1102},{"i":1106,"t":"Compute nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#compute-nodes","p":1102},{"i":1108,"t":"Storage nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#storage-nodes","p":1102},{"i":1110,"t":"Network nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#network-nodes","p":1102},{"i":1112,"t":"Manager nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#manager-nodes","p":1102},{"i":1114,"t":"Switches","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#switches","p":1102},{"i":1115,"t":"Management switches","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#management-switches","p":1102},{"i":1117,"t":"Leaf switches","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#leaf-switches","p":1102},{"i":1119,"t":"Spine switches","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#spine-switches","p":1102},{"i":1121,"t":"Network interface cards","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#network-interface-cards","p":1102},{"i":1123,"t":"Compute Node","u":"/docs/iaas/guides/concept-guide/nodes","h":"#compute-node","p":1122},{"i":1124,"t":"Control Node","u":"/docs/iaas/guides/concept-guide/nodes","h":"#control-node","p":1122},{"i":1125,"t":"Data Node","u":"/docs/iaas/guides/concept-guide/nodes","h":"#data-node","p":1122},{"i":1126,"t":"Management Node","u":"/docs/iaas/guides/concept-guide/nodes","h":"#management-node","p":1122},{"i":1127,"t":"Monitoring Node","u":"/docs/iaas/guides/concept-guide/nodes","h":"#monitoring-node","p":1122},{"i":1128,"t":"Network Node","u":"/docs/iaas/guides/concept-guide/nodes","h":"#network-node","p":1122},{"i":1130,"t":"Compute Plane","u":"/docs/iaas/guides/concept-guide/layers","h":"#compute-plane","p":1129},{"i":1131,"t":"Control Plane","u":"/docs/iaas/guides/concept-guide/layers","h":"#control-plane","p":1129},{"i":1132,"t":"Data Plane","u":"/docs/iaas/guides/concept-guide/layers","h":"#data-plane","p":1129},{"i":1133,"t":"Management Plane","u":"/docs/iaas/guides/concept-guide/layers","h":"#management-plane","p":1129},{"i":1134,"t":"Monitoring Plane","u":"/docs/iaas/guides/concept-guide/layers","h":"#monitoring-plane","p":1129},{"i":1135,"t":"Network Plane","u":"/docs/iaas/guides/concept-guide/layers","h":"#network-plane","p":1129},{"i":1137,"t":"Hyper-converged infrastructure (HCI)","u":"/docs/iaas/guides/concept-guide/use-cases","h":"#hyper-converged-infrastructure-hci","p":1136},{"i":1145,"t":"Distribution specific packages","u":"/docs/iaas/guides/configuration-guide/commons/packages","h":"#distribution-specific-packages","p":1143},{"i":1146,"t":"Debian","u":"/docs/iaas/guides/configuration-guide/commons/packages","h":"#debian","p":1143},{"i":1148,"t":"CentOS","u":"/docs/iaas/guides/configuration-guide/commons/packages","h":"#centos","p":1143},{"i":1150,"t":"Upgrade of packages","u":"/docs/iaas/guides/configuration-guide/commons/packages","h":"#upgrade-of-packages","p":1143},{"i":1156,"t":"Start and enable required services","u":"/docs/iaas/guides/configuration-guide/commons/services","h":"#start-and-enable-required-services","p":1154},{"i":1158,"t":"Note on services that should be deactivated","u":"/docs/iaas/guides/configuration-guide/commons/services","h":"#note-on-services-that-should-be-deactivated","p":1154},{"i":1162,"t":"Unique Identifier","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#unique-identifier","p":1160},{"i":1164,"t":"Client","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#client","p":1160},{"i":1166,"t":"Swappiness","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#swappiness","p":1160},{"i":1168,"t":"RGW service","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#rgw-service","p":1160},{"i":1170,"t":"Extra pools","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#extra-pools","p":1160},{"i":1172,"t":"Extra keys","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#extra-keys","p":1160},{"i":1174,"t":"OSD devices","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#osd-devices","p":1160},{"i":1176,"t":"Full examples","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#full-examples","p":1160},{"i":1178,"t":"Add a new osd","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#add-a-new-osd","p":1160},{"i":1180,"t":"Dashboard","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#dashboard","p":1160},{"i":1182,"t":"Configuring the openstack loadbalancer to expose the ceph dashboard","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#configuring-the-openstack-loadbalancer-to-expose-the-ceph-dashboard","p":1160},{"i":1184,"t":"Second Ceph cluster","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#second-ceph-cluster","p":1160},{"i":1186,"t":"Resource limits","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#resource-limits","p":1160},{"i":1188,"t":"CPU Pinning","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#cpu-pinning","p":1160},{"i":1190,"t":"Use of RBDs for nodes","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#use-of-rbds-for-nodes","p":1160},{"i":1194,"t":"Extra config","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","h":"#extra-config","p":1192},{"i":1196,"t":"Example","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","h":"#example","p":1192},{"i":1198,"t":"Defaults","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","h":"#defaults","p":1192},{"i":1208,"t":"Manager","u":"/docs/iaas/guides/configuration-guide/inventory","h":"#manager","p":1206},{"i":1210,"t":"Reconciler","u":"/docs/iaas/guides/configuration-guide/inventory","h":"#reconciler","p":1206},{"i":1211,"t":"Host Vars","u":"/docs/iaas/guides/configuration-guide/inventory","h":"#host-vars","p":1206},{"i":1212,"t":"Group Vars","u":"/docs/iaas/guides/configuration-guide/inventory","h":"#group-vars","p":1206},{"i":1213,"t":"Define variable for all nodes","u":"/docs/iaas/guides/configuration-guide/inventory","h":"#define-variable-for-all-nodes","p":1206},{"i":1217,"t":"Creating a new configuration repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#creating-a-new-configuration-repository","p":1215},{"i":1219,"t":"Step 1: Preparation","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#step-1-preparation","p":1215},{"i":1221,"t":"Step 2: Run Cookiecutter","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#step-2-run-cookiecutter","p":1215},{"i":1223,"t":"Step 3: Upload the new configuration to the remote git repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#step-3-upload-the-new-configuration-to-the-remote-git-repository","p":1215},{"i":1225,"t":"Step 4: Post-processing of the generated configuration","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#step-4-post-processing-of-the-generated-configuration","p":1215},{"i":1227,"t":"Using latest","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#using-latest","p":1215},{"i":1229,"t":"Parameter reference","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#parameter-reference","p":1215},{"i":1231,"t":"Configuration repository layout","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#configuration-repository-layout","p":1215},{"i":1233,"t":"Synchronising the configuration repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#synchronising-the-configuration-repository","p":1215},{"i":1235,"t":"Locks","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#locks","p":1215},{"i":1237,"t":"Working with encrypted files","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#working-with-encrypted-files","p":1215},{"i":1241,"t":"IP addresses & FQDNs","u":"/docs/iaas/guides/configuration-guide/loadbalancer","h":"#ip-addresses--fqdns","p":1239},{"i":1243,"t":"TLS certificates","u":"/docs/iaas/guides/configuration-guide/loadbalancer","h":"#tls-certificates","p":1239},{"i":1245,"t":"General procedure","u":"/docs/iaas/guides/configuration-guide/loadbalancer","h":"#general-procedure","p":1239},{"i":1247,"t":"Self-signed certificates","u":"/docs/iaas/guides/configuration-guide/loadbalancer","h":"#self-signed-certificates","p":1239},{"i":1249,"t":"Generating TLS certificates with Let’s Encrypt","u":"/docs/iaas/guides/configuration-guide/loadbalancer","h":"#generating-tls-certificates-with-lets-encrypt","p":1239},{"i":1251,"t":"Second Loadbalancer","u":"/docs/iaas/guides/configuration-guide/loadbalancer","h":"#second-loadbalancer","p":1239},{"i":1253,"t":"ProxySQL","u":"/docs/iaas/guides/configuration-guide/loadbalancer","h":"#proxysql","p":1239},{"i":1256,"t":"Stable release","u":"/docs/iaas/guides/configuration-guide/manager","h":"#stable-release","p":1255},{"i":1258,"t":"Working with Git branches","u":"/docs/iaas/guides/configuration-guide/manager","h":"#working-with-git-branches","p":1255},{"i":1260,"t":"OpenSearch integration","u":"/docs/iaas/guides/configuration-guide/manager","h":"#opensearch-integration","p":1255},{"i":1262,"t":"OpenStack broker integration","u":"/docs/iaas/guides/configuration-guide/manager","h":"#openstack-broker-integration","p":1255},{"i":1265,"t":"Netplan","u":"/docs/iaas/guides/configuration-guide/network","h":"#netplan","p":1264},{"i":1267,"t":"Example","u":"/docs/iaas/guides/configuration-guide/network","h":"#example","p":1264},{"i":1269,"t":"Dispatcher scripts","u":"/docs/iaas/guides/configuration-guide/network","h":"#dispatcher-scripts","p":1264},{"i":1270,"t":"Dummy interfaces","u":"/docs/iaas/guides/configuration-guide/network","h":"#dummy-interfaces","p":1264},{"i":1272,"t":"/etc/interfaces","u":"/docs/iaas/guides/configuration-guide/network","h":"#etcinterfaces","p":1264},{"i":1274,"t":"IPv6 fabric underlay","u":"/docs/iaas/guides/configuration-guide/network","h":"#ipv6-fabric-underlay","p":1264},{"i":1284,"t":"Pure Storage FlashArray","u":"/docs/iaas/guides/configuration-guide/openstack/cinder","h":"#pure-storage-flasharray","p":1282},{"i":1291,"t":"Image tags","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#image-tags","p":1290},{"i":1293,"t":"Endpoints","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#endpoints","p":1290},{"i":1294,"t":"Public endpoints","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#public-endpoints","p":1290},{"i":1296,"t":"Example for the use of name-based endpoints","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#example-for-the-use-of-name-based-endpoints","p":1290},{"i":1298,"t":"Network interfaces","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#network-interfaces","p":1290},{"i":1300,"t":"Customization of the service configurations","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#customization-of-the-service-configurations","p":1290},{"i":1302,"t":"How does the configuration get into services?","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#how-does-the-configuration-get-into-services","p":1290},{"i":1304,"t":"Number of service workers","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#number-of-service-workers","p":1290},{"i":1306,"t":"Back-end TLS configuration","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#back-end-tls-configuration","p":1290},{"i":1311,"t":"Problems uploading machine images larger than 1 GiB","u":"/docs/iaas/guides/configuration-guide/openstack/horizon","h":"#problems-uploading-machine-images-larger-than-1-gib","p":1309},{"i":1313,"t":"Make clouds.yml file downloadable as an alternative to the RC file","u":"/docs/iaas/guides/configuration-guide/openstack/horizon","h":"#make-cloudsyml-file-downloadable-as-an-alternative-to-the-rc-file","p":1309},{"i":1315,"t":"Custom themes","u":"/docs/iaas/guides/configuration-guide/openstack/horizon","h":"#custom-themes","p":1309},{"i":1323,"t":"Domain manager policy","u":"/docs/iaas/guides/configuration-guide/openstack/keystone","h":"#domain-manager-policy","p":1321},{"i":1325,"t":"OIDC Federation","u":"/docs/iaas/guides/configuration-guide/openstack/keystone","h":"#oidc-federation","p":1321},{"i":1330,"t":"MTU Considerations","u":"/docs/iaas/guides/configuration-guide/openstack/neutron","h":"#mtu-considerations","p":1328},{"i":1337,"t":"Skyline APIServer","u":"/docs/iaas/guides/configuration-guide/openstack/skyline","h":"#skyline-apiserver","p":1336},{"i":1339,"t":"Skyline Console","u":"/docs/iaas/guides/configuration-guide/openstack/skyline","h":"#skyline-console","p":1336},{"i":1343,"t":"Deployment of a Squid Proxy Server","u":"/docs/iaas/guides/configuration-guide/proxy","h":"#deployment-of-a-squid-proxy-server","p":1341},{"i":1345,"t":"Configurations","u":"/docs/iaas/guides/configuration-guide/proxy","h":"#configurations","p":1341},{"i":1347,"t":"Docker","u":"/docs/iaas/guides/configuration-guide/proxy","h":"#docker","p":1341},{"i":1349,"t":"APT","u":"/docs/iaas/guides/configuration-guide/proxy","h":"#apt","p":1341},{"i":1351,"t":"OpenStack","u":"/docs/iaas/guides/configuration-guide/proxy","h":"#openstack","p":1341},{"i":1353,"t":"Kubernetes / K3s","u":"/docs/iaas/guides/configuration-guide/proxy","h":"#kubernetes--k3s","p":1341},{"i":1357,"t":"Nested virtualisation","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#nested-virtualisation","p":1355},{"i":1358,"t":"AMD","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#amd","p":1355},{"i":1360,"t":"Intel","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#intel","p":1355},{"i":1362,"t":"Reserve compute node resources","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#reserve-compute-node-resources","p":1355},{"i":1364,"t":"Host memory","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#host-memory","p":1355},{"i":1366,"t":"Host CPUs","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#host-cpus","p":1355},{"i":1368,"t":"Dedicated cores for instances","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#dedicated-cores-for-instances","p":1355},{"i":1370,"t":"Add NUMA topology filter to nova scheduler","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#add-numa-topology-filter-to-nova-scheduler","p":1355},{"i":1372,"t":"Specify CPU cores to be used as dedicated cores","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#specify-cpu-cores-to-be-used-as-dedicated-cores","p":1355},{"i":1374,"t":"Create flavors or images backed by dedicated cores","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#create-flavors-or-images-backed-by-dedicated-cores","p":1355},{"i":1376,"t":"Mixing dedicated and shared cores on a compute node","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#mixing-dedicated-and-shared-cores-on-a-compute-node","p":1355},{"i":1378,"t":"Mixing dedicated and shared cores in a nova instance","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#mixing-dedicated-and-shared-cores-in-a-nova-instance","p":1355},{"i":1380,"t":"Creating images with special CPU requirements","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#creating-images-with-special-cpu-requirements","p":1355},{"i":1382,"t":"Back instance memory by hugepages","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#back-instance-memory-by-hugepages","p":1355},{"i":1384,"t":"Local SSD storage","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#local-ssd-storage","p":1355},{"i":1388,"t":"Config.yaml","u":"/docs/iaas/guides/configuration-guide/rookify","h":"#configyaml","p":1386},{"i":1390,"t":"Parameters","u":"/docs/iaas/guides/configuration-guide/rookify","h":"#parameters","p":1386},{"i":1394,"t":"Unique Identifier","u":"/docs/iaas/guides/configuration-guide/rook","h":"#unique-identifier","p":1392},{"i":1396,"t":"Client","u":"/docs/iaas/guides/configuration-guide/rook","h":"#client","p":1392},{"i":1398,"t":"Network configuration","u":"/docs/iaas/guides/configuration-guide/rook","h":"#network-configuration","p":1392},{"i":1400,"t":"Configuring addressRanges","u":"/docs/iaas/guides/configuration-guide/rook","h":"#configuring-addressranges","p":1392},{"i":1402,"t":"Configuring encryption, compression, msgr2","u":"/docs/iaas/guides/configuration-guide/rook","h":"#configuring-encryption-compression-msgr2","p":1392},{"i":1404,"t":"Flexible approach using rook_network","u":"/docs/iaas/guides/configuration-guide/rook","h":"#flexible-approach-using-rook_network","p":1392},{"i":1406,"t":"RGW service - CephObjectStore CRD","u":"/docs/iaas/guides/configuration-guide/rook","h":"#rgw-service---cephobjectstore-crd","p":1392},{"i":1408,"t":"Cephfs - CephFilesystem CRD","u":"/docs/iaas/guides/configuration-guide/rook","h":"#cephfs---cephfilesystem-crd","p":1392},{"i":1410,"t":"Extra pools - CephBlockPool CRD","u":"/docs/iaas/guides/configuration-guide/rook","h":"#extra-pools---cephblockpool-crd","p":1392},{"i":1412,"t":"Storage configuration","u":"/docs/iaas/guides/configuration-guide/rook","h":"#storage-configuration","p":1392},{"i":1414,"t":"Deploy OSDs on all nodes and found devices","u":"/docs/iaas/guides/configuration-guide/rook","h":"#deploy-osds-on-all-nodes-and-found-devices","p":1392},{"i":1416,"t":"Deploy OSDs on specific nodes and devices based on a device filter","u":"/docs/iaas/guides/configuration-guide/rook","h":"#deploy-osds-on-specific-nodes-and-devices-based-on-a-device-filter","p":1392},{"i":1418,"t":"Deploy OSDs on specific nodes and devices based on device names","u":"/docs/iaas/guides/configuration-guide/rook","h":"#deploy-osds-on-specific-nodes-and-devices-based-on-device-names","p":1392},{"i":1420,"t":"Flexible approach using rook_storage","u":"/docs/iaas/guides/configuration-guide/rook","h":"#flexible-approach-using-rook_storage","p":1392},{"i":1422,"t":"Encrypted OSDs","u":"/docs/iaas/guides/configuration-guide/rook","h":"#encrypted-osds","p":1392},{"i":1424,"t":"Dashboard","u":"/docs/iaas/guides/configuration-guide/rook","h":"#dashboard","p":1392},{"i":1426,"t":"Enable dashboard and configure ssl and ports","u":"/docs/iaas/guides/configuration-guide/rook","h":"#enable-dashboard-and-configure-ssl-and-ports","p":1392},{"i":1428,"t":"Rook Cluster Name","u":"/docs/iaas/guides/configuration-guide/rook","h":"#rook-cluster-name","p":1392},{"i":1430,"t":"Kubernetes Namespaces","u":"/docs/iaas/guides/configuration-guide/rook","h":"#kubernetes-namespaces","p":1392},{"i":1432,"t":"Number and Placement of Ceph Daemons","u":"/docs/iaas/guides/configuration-guide/rook","h":"#number-and-placement-of-ceph-daemons","p":1392},{"i":1434,"t":"Crash Collector","u":"/docs/iaas/guides/configuration-guide/rook","h":"#crash-collector","p":1392},{"i":1436,"t":"Log Collector","u":"/docs/iaas/guides/configuration-guide/rook","h":"#log-collector","p":1392},{"i":1438,"t":"Ceph Config","u":"/docs/iaas/guides/configuration-guide/rook","h":"#ceph-config","p":1392},{"i":1440,"t":"Second Ceph cluster","u":"/docs/iaas/guides/configuration-guide/rook","h":"#second-ceph-cluster","p":1392},{"i":1442,"t":"Helm Value File","u":"/docs/iaas/guides/configuration-guide/rook","h":"#helm-value-file","p":1392},{"i":1450,"t":"Configure logging drivers","u":"/docs/iaas/guides/configuration-guide/services/docker","h":"#configure-logging-drivers","p":1448},{"i":1463,"t":"Automated Installation using Node Images","u":"/docs/iaas/guides/deploy-guide/provisioning","h":"#automated-installation-using-node-images","p":1461},{"i":1465,"t":"Manual provisioning","u":"/docs/iaas/guides/deploy-guide/provisioning","h":"#manual-provisioning","p":1461},{"i":1469,"t":"Deploy the manager service","u":"/docs/iaas/guides/deploy-guide/manager","h":"#deploy-the-manager-service","p":1467},{"i":1471,"t":"Step 1: Create operator user","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-1-create-operator-user","p":1467},{"i":1473,"t":"Step 2: Apply the network configuration","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-2-apply-the-network-configuration","p":1467},{"i":1475,"t":"Step 3: Bootstrap the manager node","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-3-bootstrap-the-manager-node","p":1467},{"i":1477,"t":"Step 4: Deploy the manager service","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-4-deploy-the-manager-service","p":1467},{"i":1479,"t":"Step 5: Set vault password on the manager service","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-5-set-vault-password-on-the-manager-service","p":1467},{"i":1485,"t":"Prerequisites & Requirements","u":"/docs/iaas/guides/deploy-guide/rookify","h":"#prerequisites--requirements","p":1483},{"i":1487,"t":"Manual Installation","u":"/docs/iaas/guides/deploy-guide/rookify","h":"#manual-installation","p":1483},{"i":1488,"t":"Download or Clone the Repository","u":"/docs/iaas/guides/deploy-guide/rookify","h":"#download-or-clone-the-repository","p":1483},{"i":1490,"t":"Install and Run Locally (without Docker)","u":"/docs/iaas/guides/deploy-guide/rookify","h":"#install-and-run-locally-without-docker","p":1483},{"i":1492,"t":"Install and Run from within a Container","u":"/docs/iaas/guides/deploy-guide/rookify","h":"#install-and-run-from-within-a-container","p":1483},{"i":1498,"t":"Install required packages","u":"/docs/iaas/guides/deploy-guide/seed","h":"#install-required-packages","p":1496},{"i":1500,"t":"Get a copy of the configuration repository","u":"/docs/iaas/guides/deploy-guide/seed","h":"#get-a-copy-of-the-configuration-repository","p":1496},{"i":1504,"t":"RGW service","u":"/docs/iaas/guides/deploy-guide/services/ceph","h":"#rgw-service","p":1502},{"i":1506,"t":"Avoiding service restarts","u":"/docs/iaas/guides/deploy-guide/services/ceph","h":"#avoiding-service-restarts","p":1502},{"i":1508,"t":"Throttling service restarts","u":"/docs/iaas/guides/deploy-guide/services/ceph","h":"#throttling-service-restarts","p":1502},{"i":1516,"t":"Cluster API","u":"/docs/iaas/guides/deploy-guide/services/kubernetes","h":"#cluster-api","p":1514},{"i":1526,"t":"RGW service","u":"/docs/iaas/guides/deploy-guide/services/rook","h":"#rgw-service","p":1524},{"i":1528,"t":"Change node labels","u":"/docs/iaas/guides/deploy-guide/services/rook","h":"#change-node-labels","p":1524},{"i":1530,"t":"Cleanup","u":"/docs/iaas/guides/deploy-guide/services/rook","h":"#cleanup","p":1524},{"i":1533,"t":"Change Node states","u":"/docs/iaas/guides/operations-guide/","h":"#change-node-states","p":1532},{"i":1535,"t":"Maintenance","u":"/docs/iaas/guides/operations-guide/","h":"#maintenance","p":1532},{"i":1537,"t":"Bootstrap","u":"/docs/iaas/guides/operations-guide/","h":"#bootstrap","p":1532},{"i":1539,"t":"Manage services","u":"/docs/iaas/guides/operations-guide/","h":"#manage-services","p":1532},{"i":1541,"t":"Manage containers","u":"/docs/iaas/guides/operations-guide/","h":"#manage-containers","p":1532},{"i":1543,"t":"Reboot nodes","u":"/docs/iaas/guides/operations-guide/","h":"#reboot-nodes","p":1532},{"i":1545,"t":"Working with the OOB Board via IPMI","u":"/docs/iaas/guides/operations-guide/","h":"#working-with-the-oob-board-via-ipmi","p":1532},{"i":1546,"t":"Display the IP address","u":"/docs/iaas/guides/operations-guide/","h":"#display-the-ip-address","p":1532},{"i":1551,"t":"Loadbalancer","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#loadbalancer","p":1550},{"i":1553,"t":"MariaDB","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#mariadb","p":1550},{"i":1554,"t":"Backup","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#backup","p":1550},{"i":1556,"t":"Restore","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#restore","p":1550},{"i":1558,"t":"Recovery","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#recovery","p":1550},{"i":1560,"t":"Create database & user","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#create-database--user","p":1550},{"i":1562,"t":"Open Search","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#open-search","p":1550},{"i":1563,"t":"Get all indices","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#get-all-indices","p":1550},{"i":1565,"t":"Delete an index","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#delete-an-index","p":1550},{"i":1568,"t":"Where to find docs","u":"/docs/iaas/guides/operations-guide/ceph","h":"#where-to-find-docs","p":1567},{"i":1570,"t":"Advice on Ceph releases","u":"/docs/iaas/guides/operations-guide/ceph","h":"#advice-on-ceph-releases","p":1567},{"i":1572,"t":"General maintenance","u":"/docs/iaas/guides/operations-guide/ceph","h":"#general-maintenance","p":1567},{"i":1573,"t":"60 seconds cluster overview","u":"/docs/iaas/guides/operations-guide/ceph","h":"#60-seconds-cluster-overview","p":1567},{"i":1575,"t":"Mute/Unmute a health warning","u":"/docs/iaas/guides/operations-guide/ceph","h":"#muteunmute-a-health-warning","p":1567},{"i":1577,"t":"Disable/Enable (deep-)scrubbing","u":"/docs/iaas/guides/operations-guide/ceph","h":"#disableenable-deep-scrubbing","p":1567},{"i":1579,"t":"Reboot a single node","u":"/docs/iaas/guides/operations-guide/ceph","h":"#reboot-a-single-node","p":1567},{"i":1581,"t":"Gathering information about block devices","u":"/docs/iaas/guides/operations-guide/ceph","h":"#gathering-information-about-block-devices","p":1567},{"i":1582,"t":"Enumerate typical storage devices and LVM","u":"/docs/iaas/guides/operations-guide/ceph","h":"#enumerate-typical-storage-devices-and-lvm","p":1567},{"i":1584,"t":"SMART data for SATA/SAS and NVME devices","u":"/docs/iaas/guides/operations-guide/ceph","h":"#smart-data-for-satasas-and-nvme-devices","p":1567},{"i":1586,"t":"Check format of a NVME device","u":"/docs/iaas/guides/operations-guide/ceph","h":"#check-format-of-a-nvme-device","p":1567},{"i":1588,"t":"Format a NVME device to a different LBA format using nvme-cli","u":"/docs/iaas/guides/operations-guide/ceph","h":"#format-a-nvme-device-to-a-different-lba-format-using-nvme-cli","p":1567},{"i":1590,"t":"Secure Erase a NVME drive using nvme-cli","u":"/docs/iaas/guides/operations-guide/ceph","h":"#secure-erase-a-nvme-drive-using-nvme-cli","p":1567},{"i":1592,"t":"Secure Erase a SATA/SAS drive using hdparm","u":"/docs/iaas/guides/operations-guide/ceph","h":"#secure-erase-a-satasas-drive-using-hdparm","p":1567},{"i":1594,"t":"OSD maintenance tasks","u":"/docs/iaas/guides/operations-guide/ceph","h":"#osd-maintenance-tasks","p":1567},{"i":1595,"t":"Locate a specific OSD in the cluster","u":"/docs/iaas/guides/operations-guide/ceph","h":"#locate-a-specific-osd-in-the-cluster","p":1567},{"i":1597,"t":"Get OSD metadata (global and single OSD)","u":"/docs/iaas/guides/operations-guide/ceph","h":"#get-osd-metadata-global-and-single-osd","p":1567},{"i":1599,"t":"Add a new OSD","u":"/docs/iaas/guides/operations-guide/ceph","h":"#add-a-new-osd","p":1567},{"i":1601,"t":"Replace a defect OSD","u":"/docs/iaas/guides/operations-guide/ceph","h":"#replace-a-defect-osd","p":1567},{"i":1602,"t":"Remove a OSD","u":"/docs/iaas/guides/operations-guide/ceph","h":"#remove-a-osd","p":1567},{"i":1604,"t":"Remove a single OSD node","u":"/docs/iaas/guides/operations-guide/ceph","h":"#remove-a-single-osd-node","p":1567},{"i":1606,"t":"Remove an OSD (temporarily e.g. when replacing a broken disk)","u":"/docs/iaas/guides/operations-guide/ceph","h":"#remove-an-osd-temporarily-eg-when-replacing-a-broken-disk","p":1567},{"i":1608,"t":"Disable backfills/recovery completely","u":"/docs/iaas/guides/operations-guide/ceph","h":"#disable-backfillsrecovery-completely","p":1567},{"i":1610,"t":"Rebalance OSDs","u":"/docs/iaas/guides/operations-guide/ceph","h":"#rebalance-osds","p":1567},{"i":1611,"t":"Placement Group maintenance","u":"/docs/iaas/guides/operations-guide/ceph","h":"#placement-group-maintenance","p":1567},{"i":1612,"t":"Dump placement groups","u":"/docs/iaas/guides/operations-guide/ceph","h":"#dump-placement-groups","p":1567},{"i":1614,"t":"Query a PG about its status","u":"/docs/iaas/guides/operations-guide/ceph","h":"#query-a-pg-about-its-status","p":1567},{"i":1616,"t":"Start (deep-)scrubbing of a placement group","u":"/docs/iaas/guides/operations-guide/ceph","h":"#start-deep-scrubbing-of-a-placement-group","p":1567},{"i":1618,"t":"HEALTH_WARN - Large omap objects found...","u":"/docs/iaas/guides/operations-guide/ceph","h":"#health_warn---large-omap-objects-found","p":1567},{"i":1620,"t":"Instruct a PG to repair in case of scrub errors (inconsistent PG)","u":"/docs/iaas/guides/operations-guide/ceph","h":"#instruct-a-pg-to-repair-in-case-of-scrub-errors-inconsistent-pg","p":1567},{"i":1622,"t":"RADOS Pool maintenance","u":"/docs/iaas/guides/operations-guide/ceph","h":"#rados-pool-maintenance","p":1567},{"i":1624,"t":"Get pools and their configuration","u":"/docs/iaas/guides/operations-guide/ceph","h":"#get-pools-and-their-configuration","p":1567},{"i":1626,"t":"Dump all CRUSH rules","u":"/docs/iaas/guides/operations-guide/ceph","h":"#dump-all-crush-rules","p":1567},{"i":1628,"t":"Get autoscaler status","u":"/docs/iaas/guides/operations-guide/ceph","h":"#get-autoscaler-status","p":1567},{"i":1630,"t":"Create a replicated pool","u":"/docs/iaas/guides/operations-guide/ceph","h":"#create-a-replicated-pool","p":1567},{"i":1632,"t":"Enabling an application on a pool","u":"/docs/iaas/guides/operations-guide/ceph","h":"#enabling-an-application-on-a-pool","p":1567},{"i":1634,"t":"Delete a pool","u":"/docs/iaas/guides/operations-guide/ceph","h":"#delete-a-pool","p":1567},{"i":1636,"t":"Set number of PGs for a pool","u":"/docs/iaas/guides/operations-guide/ceph","h":"#set-number-of-pgs-for-a-pool","p":1567},{"i":1638,"t":"Create CRUSH rules for different storage classes","u":"/docs/iaas/guides/operations-guide/ceph","h":"#create-crush-rules-for-different-storage-classes","p":1567},{"i":1640,"t":"Change CRUSH rule for a pool (\"move pool\")","u":"/docs/iaas/guides/operations-guide/ceph","h":"#change-crush-rule-for-a-pool-move-pool","p":1567},{"i":1642,"t":"Advanced topics","u":"/docs/iaas/guides/operations-guide/ceph","h":"#advanced-topics","p":1567},{"i":1643,"t":"Validating Ceph using OSISM playbooks","u":"/docs/iaas/guides/operations-guide/ceph","h":"#validating-ceph-using-osism-playbooks","p":1567},{"i":1645,"t":"Shutdown a Ceph cluster","u":"/docs/iaas/guides/operations-guide/ceph","h":"#shutdown-a-ceph-cluster","p":1567},{"i":1647,"t":"Restart a Ceph cluster after manual shutdown","u":"/docs/iaas/guides/operations-guide/ceph","h":"#restart-a-ceph-cluster-after-manual-shutdown","p":1567},{"i":1649,"t":"Performance benchmark","u":"/docs/iaas/guides/operations-guide/ceph","h":"#performance-benchmark","p":1567},{"i":1651,"t":"Where and how to get further help","u":"/docs/iaas/guides/operations-guide/ceph","h":"#where-and-how-to-get-further-help","p":1567},{"i":1656,"t":"List all plays","u":"/docs/iaas/guides/operations-guide/manager/apply","h":"#list-all-plays","p":1654},{"i":1658,"t":"Apply a play","u":"/docs/iaas/guides/operations-guide/manager/apply","h":"#apply-a-play","p":1654},{"i":1660,"t":"Use of custom plays","u":"/docs/iaas/guides/operations-guide/manager/apply","h":"#use-of-custom-plays","p":1654},{"i":1662,"t":"Example play with roles: Manage the infrastructure of the SCS testing environment","u":"/docs/iaas/guides/operations-guide/manager/apply","h":"#example-play-with-roles-manage-the-infrastructure-of-the-scs-testing-environment","p":1654},{"i":1664,"t":"Example play: Wiping partitions","u":"/docs/iaas/guides/operations-guide/manager/apply","h":"#example-play-wiping-partitions","p":1654},{"i":1668,"t":"Ansible","u":"/docs/iaas/guides/operations-guide/manager/console","h":"#ansible","p":1666},{"i":1670,"t":"Clush","u":"/docs/iaas/guides/operations-guide/manager/console","h":"#clush","p":1666},{"i":1672,"t":"Container","u":"/docs/iaas/guides/operations-guide/manager/console","h":"#container","p":1666},{"i":1674,"t":"SSH","u":"/docs/iaas/guides/operations-guide/manager/console","h":"#ssh","p":1666},{"i":1678,"t":"Hosts","u":"/docs/iaas/guides/operations-guide/manager/get","h":"#hosts","p":1676},{"i":1680,"t":"Host variables","u":"/docs/iaas/guides/operations-guide/manager/get","h":"#host-variables","p":1676},{"i":1682,"t":"Host facts","u":"/docs/iaas/guides/operations-guide/manager/get","h":"#host-facts","p":1676},{"i":1685,"t":"List","u":"/docs/iaas/guides/operations-guide/manager/task","h":"#list","p":1684},{"i":1687,"t":"Broker reset","u":"/docs/iaas/guides/operations-guide/manager/task","h":"#broker-reset","p":1684},{"i":1690,"t":"Ansible","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#ansible","p":1689},{"i":1691,"t":"Files","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#files","p":1689},{"i":1693,"t":"ARA - ARA Records Ansible","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#ara---ara-records-ansible","p":1689},{"i":1695,"t":"Container","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#container","p":1689},{"i":1697,"t":"OpenSearch","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#opensearch","p":1689},{"i":1701,"t":"Open vSwitch (OVS)","u":"/docs/iaas/guides/operations-guide/network","h":"#open-vswitch-ovs","p":1699},{"i":1703,"t":"Open Virtual Network (OVN)","u":"/docs/iaas/guides/operations-guide/network","h":"#open-virtual-network-ovn","p":1699},{"i":1706,"t":"Create an external network","u":"/docs/iaas/guides/operations-guide/openstack/","h":"#create-an-external-network","p":1705},{"i":1708,"t":"Reboot a compute node","u":"/docs/iaas/guides/operations-guide/openstack/","h":"#reboot-a-compute-node","p":1705},{"i":1710,"t":"Add a new compute node","u":"/docs/iaas/guides/operations-guide/openstack/","h":"#add-a-new-compute-node","p":1705},{"i":1712,"t":"Remove a compute node","u":"/docs/iaas/guides/operations-guide/openstack/","h":"#remove-a-compute-node","p":1705},{"i":1715,"t":"Remove service","u":"/docs/iaas/guides/operations-guide/openstack/cinder","h":"#remove-service","p":1714},{"i":1717,"t":"Sync quota","u":"/docs/iaas/guides/operations-guide/openstack/cinder","h":"#sync-quota","p":1714},{"i":1719,"t":"Quality of Service (QoS)","u":"/docs/iaas/guides/operations-guide/openstack/cinder","h":"#quality-of-service-qos","p":1714},{"i":1722,"t":"Quality of Service (QoS)","u":"/docs/iaas/guides/operations-guide/openstack/neutron","h":"#quality-of-service-qos","p":1721},{"i":1727,"t":"Get all servers on a node","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#get-all-servers-on-a-node","p":1726},{"i":1729,"t":"Stop all servers running on a node","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#stop-all-servers-running-on-a-node","p":1726},{"i":1731,"t":"Disable & enable a compute service","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#disable--enable-a-compute-service","p":1726},{"i":1733,"t":"Force down & up a compute service","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#force-down--up-a-compute-service","p":1726},{"i":1735,"t":"Huge pages","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#huge-pages","p":1726},{"i":1737,"t":"Quality of Service (QoS)","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#quality-of-service-qos","p":1726},{"i":1739,"t":"Host aggregates","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#host-aggregates","p":1726},{"i":1742,"t":"Cleanup of amphorae missing from the DB","u":"/docs/iaas/guides/operations-guide/openstack/octavia","h":"#cleanup-of-amphorae-missing-from-the-db","p":1741},{"i":1744,"t":"SSH access to amphorae","u":"/docs/iaas/guides/operations-guide/openstack/octavia","h":"#ssh-access-to-amphorae","p":1741},{"i":1747,"t":"Overview","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#overview","p":1746},{"i":1749,"t":"Installation","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#installation","p":1746},{"i":1751,"t":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#usage","p":1746},{"i":1753,"t":"Definitions","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#definitions","p":1746},{"i":1755,"t":"Name parser and generator","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#name-parser-and-generator","p":1746},{"i":1759,"t":"Requirements","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#requirements","p":1757},{"i":1761,"t":"OpenStack Image Service (Glance)","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#openstack-image-service-glance","p":1757},{"i":1763,"t":"Object storage backend","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#object-storage-backend","p":1757},{"i":1765,"t":"Getting started","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#getting-started","p":1757},{"i":1767,"t":"Image definitions","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#image-definitions","p":1757},{"i":1769,"t":"SCS image standard","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#scs-image-standard","p":1757},{"i":1771,"t":"Image with regular rebuilds","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#image-with-regular-rebuilds","p":1757},{"i":1773,"t":"Image without regular rebuild","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#image-without-regular-rebuild","p":1757},{"i":1775,"t":"Other properties","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#other-properties","p":1757},{"i":1777,"t":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#usage","p":1757},{"i":1778,"t":"Mirroring images","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#mirroring-images","p":1757},{"i":1780,"t":"Updating images","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#updating-images","p":1757},{"i":1784,"t":"Overview","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#overview","p":1783},{"i":1786,"t":"Installation","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#installation","p":1783},{"i":1788,"t":"Defaults","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#defaults","p":1783},{"i":1789,"t":"create.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#createpy","p":1783},{"i":1791,"t":"manage.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#managepy","p":1783},{"i":1793,"t":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#usage","p":1783},{"i":1795,"t":"create.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#createpy-1","p":1783},{"i":1797,"t":"manage.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#managepy-1","p":1783},{"i":1799,"t":"Config files","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#config-files","p":1783},{"i":1801,"t":"Quota Templates","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#quota-templates","p":1783},{"i":1803,"t":"Setup Endpoints","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#setup-endpoints","p":1783},{"i":1806,"t":"Overview","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","h":"#overview","p":1805},{"i":1808,"t":"Installation","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","h":"#installation","p":1805},{"i":1810,"t":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","h":"#usage","p":1805},{"i":1814,"t":"Intro","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#intro","p":1812},{"i":1816,"t":"Setting up the driver VM","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#setting-up-the-driver-vm","p":1812},{"i":1818,"t":"Internal vs external monitoring","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#internal-vs-external-monitoring","p":1812},{"i":1820,"t":"Unprivileged operation","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#unprivileged-operation","p":1812},{"i":1822,"t":"Driver VM via openstack CLI","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#driver-vm-via-openstack-cli","p":1812},{"i":1824,"t":"Configuring openstack CLI on the driver VM","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#configuring-openstack-cli-on-the-driver-vm","p":1812},{"i":1826,"t":"Custom CA","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#custom-ca","p":1812},{"i":1828,"t":"Your first api_monitor.sh iteration","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#your-first-api_monitorsh-iteration","p":1812},{"i":1830,"t":"Resource impact and charging","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#resource-impact-and-charging","p":1812},{"i":1832,"t":"Automating startup and cleanup","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#automating-startup-and-cleanup","p":1812},{"i":1834,"t":"Changing parameters and restarting","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#changing-parameters-and-restarting","p":1812},{"i":1836,"t":"Multiple instances","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#multiple-instances","p":1812},{"i":1838,"t":"Alarming and Logs","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#alarming-and-logs","p":1812},{"i":1839,"t":"eMail","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#email","p":1812},{"i":1841,"t":"Log files","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#log-files","p":1812},{"i":1843,"t":"Data collection and dashboard","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#data-collection-and-dashboard","p":1812},{"i":1845,"t":"Telegraf","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#telegraf","p":1812},{"i":1847,"t":"InfluxDB","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#influxdb","p":1812},{"i":1849,"t":"Add -S CLOUDNAME to your run_CLOUDNAME.sh script","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#add--s-cloudname-to-your-run_cloudnamesh-script","p":1812},{"i":1851,"t":"Caddy (Reverse Proxy)","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#caddy-reverse-proxy","p":1812},{"i":1853,"t":"Grafana","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#grafana","p":1812},{"i":1855,"t":"Maintenance","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#maintenance","p":1812},{"i":1857,"t":"Unattended upgrades","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#unattended-upgrades","p":1812},{"i":1859,"t":"sshd setup","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#sshd-setup","p":1812},{"i":1861,"t":"Updating openstack-health-monitor","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#updating-openstack-health-monitor","p":1812},{"i":1863,"t":"Backup","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#backup","p":1812},{"i":1865,"t":"Troubleshooting","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#troubleshooting","p":1812},{"i":1866,"t":"Debugging issues","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#debugging-issues","p":1812},{"i":1868,"t":"Analyzing failures","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#analyzing-failures","p":1812},{"i":1870,"t":"Cleaning things up","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#cleaning-things-up","p":1812},{"i":1873,"t":"Preparations","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#preparations","p":1872},{"i":1875,"t":"Nova","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#nova","p":1872},{"i":1876,"t":"Live migration","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#live-migration","p":1872},{"i":1878,"t":"Evacuation","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#evacuation","p":1872},{"i":1880,"t":"Octavia","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#octavia","p":1872},{"i":1881,"t":"Amphora rotation","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#amphora-rotation","p":1872},{"i":1883,"t":"Cinder","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#cinder","p":1872},{"i":1885,"t":"Orphans","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#orphans","p":1872},{"i":1889,"t":"Overview","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#overview","p":1888},{"i":1891,"t":"Installation","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#installation","p":1888},{"i":1893,"t":"Defaults","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#defaults","p":1888},{"i":1895,"t":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#usage","p":1888},{"i":1897,"t":"Config files","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#config-files","p":1888},{"i":1901,"t":"Where to find docs","u":"/docs/iaas/guides/operations-guide/rook","h":"#where-to-find-docs","p":1899},{"i":1903,"t":"Advice on Ceph releases","u":"/docs/iaas/guides/operations-guide/rook","h":"#advice-on-ceph-releases","p":1899},{"i":1905,"t":"Troubleshooting","u":"/docs/iaas/guides/operations-guide/rook","h":"#troubleshooting","p":1899},{"i":1907,"t":"Monitoring","u":"/docs/iaas/guides/operations-guide/rook","h":"#monitoring","p":1899},{"i":1908,"t":"Dashboard","u":"/docs/iaas/guides/operations-guide/rook","h":"#dashboard","p":1899},{"i":1910,"t":"Updating","u":"/docs/iaas/guides/operations-guide/rook","h":"#updating","p":1899},{"i":1911,"t":"Rook Upgrades","u":"/docs/iaas/guides/operations-guide/rook","h":"#rook-upgrades","p":1899},{"i":1913,"t":"Ceph Upgrades","u":"/docs/iaas/guides/operations-guide/rook","h":"#ceph-upgrades","p":1899},{"i":1915,"t":"General maintenance","u":"/docs/iaas/guides/operations-guide/rook","h":"#general-maintenance","p":1899},{"i":1916,"t":"60 seconds cluster overview","u":"/docs/iaas/guides/operations-guide/rook","h":"#60-seconds-cluster-overview","p":1899},{"i":1918,"t":"Mute/Unmute a health warning","u":"/docs/iaas/guides/operations-guide/rook","h":"#muteunmute-a-health-warning","p":1899},{"i":1920,"t":"Disable/Enable (deep-)scrubbing","u":"/docs/iaas/guides/operations-guide/rook","h":"#disableenable-deep-scrubbing","p":1899},{"i":1922,"t":"Reboot a single node","u":"/docs/iaas/guides/operations-guide/rook","h":"#reboot-a-single-node","p":1899},{"i":1924,"t":"Gathering information about block devices","u":"/docs/iaas/guides/operations-guide/rook","h":"#gathering-information-about-block-devices","p":1899},{"i":1925,"t":"Enumerate typical storage devices and LVM","u":"/docs/iaas/guides/operations-guide/rook","h":"#enumerate-typical-storage-devices-and-lvm","p":1899},{"i":1927,"t":"SMART data for SATA/SAS and NVME devices","u":"/docs/iaas/guides/operations-guide/rook","h":"#smart-data-for-satasas-and-nvme-devices","p":1899},{"i":1929,"t":"Check format of a NVME device","u":"/docs/iaas/guides/operations-guide/rook","h":"#check-format-of-a-nvme-device","p":1899},{"i":1931,"t":"Format a NVME device to a different LBA format using nvme-cli","u":"/docs/iaas/guides/operations-guide/rook","h":"#format-a-nvme-device-to-a-different-lba-format-using-nvme-cli","p":1899},{"i":1933,"t":"Secure Erase a NVME drive using nvme-cli","u":"/docs/iaas/guides/operations-guide/rook","h":"#secure-erase-a-nvme-drive-using-nvme-cli","p":1899},{"i":1935,"t":"Secure Erase a SATA/SAS drive using hdparm","u":"/docs/iaas/guides/operations-guide/rook","h":"#secure-erase-a-satasas-drive-using-hdparm","p":1899},{"i":1937,"t":"OSD maintenance tasks","u":"/docs/iaas/guides/operations-guide/rook","h":"#osd-maintenance-tasks","p":1899},{"i":1939,"t":"Disable backfills/recovery completely","u":"/docs/iaas/guides/operations-guide/rook","h":"#disable-backfillsrecovery-completely","p":1899},{"i":1941,"t":"Rebalance OSDs","u":"/docs/iaas/guides/operations-guide/rook","h":"#rebalance-osds","p":1899},{"i":1942,"t":"Placement Group maintenance","u":"/docs/iaas/guides/operations-guide/rook","h":"#placement-group-maintenance","p":1899},{"i":1943,"t":"Dump placement groups","u":"/docs/iaas/guides/operations-guide/rook","h":"#dump-placement-groups","p":1899},{"i":1945,"t":"Query a PG about its status","u":"/docs/iaas/guides/operations-guide/rook","h":"#query-a-pg-about-its-status","p":1899},{"i":1947,"t":"Start (deep-)scrubbing of a placement group","u":"/docs/iaas/guides/operations-guide/rook","h":"#start-deep-scrubbing-of-a-placement-group","p":1899},{"i":1949,"t":"HEALTH_WARN - Large omap objects found...","u":"/docs/iaas/guides/operations-guide/rook","h":"#health_warn---large-omap-objects-found","p":1899},{"i":1951,"t":"Instruct a PG to repair in case of scrub errors (inconsistent PG)","u":"/docs/iaas/guides/operations-guide/rook","h":"#instruct-a-pg-to-repair-in-case-of-scrub-errors-inconsistent-pg","p":1899},{"i":1953,"t":"RADOS Pool maintenance","u":"/docs/iaas/guides/operations-guide/rook","h":"#rados-pool-maintenance","p":1899},{"i":1955,"t":"Get pools and their configuration","u":"/docs/iaas/guides/operations-guide/rook","h":"#get-pools-and-their-configuration","p":1899},{"i":1957,"t":"Dump all CRUSH rules","u":"/docs/iaas/guides/operations-guide/rook","h":"#dump-all-crush-rules","p":1899},{"i":1959,"t":"Get autoscaler status","u":"/docs/iaas/guides/operations-guide/rook","h":"#get-autoscaler-status","p":1899},{"i":1961,"t":"Create a replicated pool","u":"/docs/iaas/guides/operations-guide/rook","h":"#create-a-replicated-pool","p":1899},{"i":1963,"t":"Enabling an application on a pool","u":"/docs/iaas/guides/operations-guide/rook","h":"#enabling-an-application-on-a-pool","p":1899},{"i":1965,"t":"Delete a pool","u":"/docs/iaas/guides/operations-guide/rook","h":"#delete-a-pool","p":1899},{"i":1967,"t":"Set number of PGs for a pool","u":"/docs/iaas/guides/operations-guide/rook","h":"#set-number-of-pgs-for-a-pool","p":1899},{"i":1969,"t":"Create CRUSH rules for different storage classes","u":"/docs/iaas/guides/operations-guide/rook","h":"#create-crush-rules-for-different-storage-classes","p":1899},{"i":1971,"t":"Change CRUSH rule for a pool (\"move pool\")","u":"/docs/iaas/guides/operations-guide/rook","h":"#change-crush-rule-for-a-pool-move-pool","p":1899},{"i":1973,"t":"Advanced topics","u":"/docs/iaas/guides/operations-guide/rook","h":"#advanced-topics","p":1899},{"i":1974,"t":"Performance benchmark","u":"/docs/iaas/guides/operations-guide/rook","h":"#performance-benchmark","p":1899},{"i":1976,"t":"Where and how to get further help","u":"/docs/iaas/guides/operations-guide/rook","h":"#where-and-how-to-get-further-help","p":1899},{"i":1980,"t":"Consider Using a Pickle File","u":"/docs/iaas/guides/operations-guide/rookify","h":"#consider-using-a-pickle-file","p":1978},{"i":1982,"t":"Rookify CLI","u":"/docs/iaas/guides/operations-guide/rookify","h":"#rookify-cli","p":1978},{"i":1983,"t":"Run","u":"/docs/iaas/guides/operations-guide/rookify","h":"#run","p":1978},{"i":1985,"t":"--dry-run","u":"/docs/iaas/guides/operations-guide/rookify","h":"#--dry-run","p":1978},{"i":1987,"t":"--migrate","u":"/docs/iaas/guides/operations-guide/rookify","h":"#--migrate","p":1978},{"i":1989,"t":"--help","u":"/docs/iaas/guides/operations-guide/rookify","h":"#--help","p":1978},{"i":1991,"t":"--show-states","u":"/docs/iaas/guides/operations-guide/rookify","h":"#--show-states","p":1978},{"i":1993,"t":"Debugging and Testing","u":"/docs/iaas/guides/operations-guide/rookify","h":"#debugging-and-testing","p":1978},{"i":1995,"t":"Set logging to debug level","u":"/docs/iaas/guides/operations-guide/rookify","h":"#set-logging-to-debug-level","p":1978},{"i":1997,"t":"Run tests","u":"/docs/iaas/guides/operations-guide/rookify","h":"#run-tests","p":1978},{"i":2001,"t":"KVM","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","h":"#kvm","p":2000},{"i":2002,"t":"Nested virtualization","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","h":"#nested-virtualization","p":2000},{"i":2004,"t":"Disk space saving","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","h":"#disk-space-saving","p":2000},{"i":2006,"t":"QEMU guest agent","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","h":"#qemu-guest-agent","p":2000},{"i":2008,"t":"VMware vSphere/ESXi","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","h":"#vmware-vsphereesxi","p":2000},{"i":2010,"t":"Guest OS:","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","h":"#guest-os","p":2000},{"i":2012,"t":"Hardware:","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","h":"#hardware","p":2000},{"i":2014,"t":"VirtualBox","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","h":"#virtualbox","p":2000},{"i":2016,"t":"General:","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","h":"#general","p":2000},{"i":2018,"t":"System:","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","h":"#system","p":2000},{"i":2020,"t":"Storage:","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","h":"#storage","p":2000},{"i":2026,"t":"Requirements","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#requirements","p":2024},{"i":2028,"t":"Types","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#types","p":2024},{"i":2030,"t":"Installation","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#installation","p":2024},{"i":2031,"t":"Automated installation (recommended)","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#automated-installation-recommended","p":2024},{"i":2033,"t":"Manual installation","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#manual-installation","p":2024},{"i":2035,"t":"Usage","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#usage","p":2024},{"i":2036,"t":"Wireguard VPN service access","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#wireguard-vpn-service-access","p":2024},{"i":2038,"t":"Webinterfaces","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#webinterfaces","p":2024},{"i":2040,"t":"Command-line interfaces","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#command-line-interfaces","p":2024},{"i":2042,"t":"Import of additional images","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#import-of-additional-images","p":2024},{"i":2044,"t":"Upgrade","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#upgrade","p":2024},{"i":2046,"t":"Customisations","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#customisations","p":2024},{"i":2047,"t":"Use of 2nd NIC for external network","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#use-of-2nd-nic-for-external-network","p":2024},{"i":2049,"t":"Troubleshooting","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#troubleshooting","p":2024},{"i":2051,"t":"Development","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","h":"#development","p":2024},{"i":2054,"t":"How we handle releases","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#how-we-handle-releases","p":2053},{"i":2056,"t":"How to make a release","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#how-to-make-a-release","p":2053},{"i":2058,"t":"Stable release","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#stable-release","p":2053},{"i":2060,"t":"How we write release notes","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#how-we-write-release-notes","p":2053},{"i":2062,"t":"Installation","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#installation","p":2053},{"i":2064,"t":"Usage","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#usage","p":2053},{"i":2066,"t":"Example","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#example","p":2053},{"i":2068,"t":"Repositories without release notes","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#repositories-without-release-notes","p":2053},{"i":2073,"t":"How to add a new service","u":"/docs/iaas/guides/other-guides/developer-guide/","h":"#how-to-add-a-new-service","p":2072},{"i":2075,"t":"How to add a new container image","u":"/docs/iaas/guides/other-guides/developer-guide/","h":"#how-to-add-a-new-container-image","p":2072},{"i":2077,"t":"How service deployment works","u":"/docs/iaas/guides/other-guides/developer-guide/","h":"#how-service-deployment-works","p":2072},{"i":2078,"t":"Docker","u":"/docs/iaas/guides/other-guides/developer-guide/","h":"#docker","p":2072},{"i":2079,"t":"Kubernetes","u":"/docs/iaas/guides/other-guides/developer-guide/","h":"#kubernetes","p":2072},{"i":2081,"t":"Ansible","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#ansible","p":2080},{"i":2083,"t":"Task names","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#task-names","p":2080},{"i":2085,"t":"become directive","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#become-directive","p":2080},{"i":2087,"t":"when directive","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#when-directive","p":2080},{"i":2089,"t":"Lists as defaults","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#lists-as-defaults","p":2080},{"i":2091,"t":"Containerfiles","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#containerfiles","p":2080},{"i":2092,"t":"Commit messages","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#commit-messages","p":2080},{"i":2093,"t":"Python","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#python","p":2080},{"i":2095,"t":"Installation","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#installation","p":2080},{"i":2097,"t":"Formatting a Single File","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#formatting-a-single-file","p":2080},{"i":2099,"t":"Formatting Multiple Files and/or directories","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#formatting-multiple-files-andor-directories","p":2080},{"i":2101,"t":"Formatting an Entire Project","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#formatting-an-entire-project","p":2080},{"i":2103,"t":"Check Mode (Dry Run)","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#check-mode-dry-run","p":2080},{"i":2105,"t":"Excluding Files or Directories","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#excluding-files-or-directories","p":2080},{"i":2107,"t":"Integration with Code Editors","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#integration-with-code-editors","p":2080},{"i":2109,"t":"Example of failed python-black Zuul job","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","h":"#example-of-failed-python-black-zuul-job","p":2080},{"i":2113,"t":"The zuul label","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#the-zuul-label","p":2111},{"i":2115,"t":"Installation","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#installation","p":2111},{"i":2116,"t":"Server preparation","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#server-preparation","p":2111},{"i":2118,"t":"Define secrets","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#define-secrets","p":2111},{"i":2120,"t":"Github App setup","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#github-app-setup","p":2111},{"i":2122,"t":"Example Playbook","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#example-playbook","p":2111},{"i":2124,"t":"Troubleshooting","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#troubleshooting","p":2111},{"i":2125,"t":"Your git repos are not displayed?","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#your-git-repos-are-not-displayed","p":2111},{"i":2127,"t":"Your git repos are using the wrong branch?","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#your-git-repos-are-using-the-wrong-branch","p":2111},{"i":2129,"t":"Your logs are not displayed in the web-UI?","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#your-logs-are-not-displayed-in-the-web-ui","p":2111},{"i":2131,"t":"Hanging jobs in a pipeline?","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#hanging-jobs-in-a-pipeline","p":2111},{"i":2136,"t":"Where to find docs","u":"/docs/iaas/guides/troubleshooting-guide/ceph","h":"#where-to-find-docs","p":2135},{"i":2138,"t":"Critical medium error","u":"/docs/iaas/guides/troubleshooting-guide/ceph","h":"#critical-medium-error","p":2135},{"i":2141,"t":"Database creation fails","u":"/docs/iaas/guides/troubleshooting-guide/openstack","h":"#database-creation-fails","p":2140},{"i":2143,"t":"Ceph connections not working","u":"/docs/iaas/guides/troubleshooting-guide/openstack","h":"#ceph-connections-not-working","p":2140},{"i":2145,"t":"Cinder volume create failure","u":"/docs/iaas/guides/troubleshooting-guide/openstack","h":"#cinder-volume-create-failure","p":2140},{"i":2149,"t":"SSH Issues","u":"/docs/iaas/guides/troubleshooting-guide/rookify","h":"#ssh-issues","p":2147},{"i":2151,"t":"Frozen State","u":"/docs/iaas/guides/troubleshooting-guide/rookify","h":"#frozen-state","p":2147},{"i":2154,"t":"Reset","u":"/docs/iaas/guides/troubleshooting-guide/manager","h":"#reset","p":2153},{"i":2160,"t":"Ceph via Rook (technical preview)","u":"/docs/iaas/guides/upgrade-guide/ceph","h":"","p":2158},{"i":2164,"t":"Restart behaviour","u":"/docs/iaas/guides/upgrade-guide/docker","h":"#restart-behaviour","p":2162},{"i":2176,"t":"Requirements","u":"/docs/iaas/guides/other-guides/testbed","h":"#requirements","p":2174},{"i":2177,"t":"Cloud access","u":"/docs/iaas/guides/other-guides/testbed","h":"#cloud-access","p":2174},{"i":2179,"t":"Cloud resources","u":"/docs/iaas/guides/other-guides/testbed","h":"#cloud-resources","p":2174},{"i":2181,"t":"Software","u":"/docs/iaas/guides/other-guides/testbed","h":"#software","p":2174},{"i":2183,"t":"Deployment","u":"/docs/iaas/guides/other-guides/testbed","h":"#deployment","p":2174},{"i":2185,"t":"Usage","u":"/docs/iaas/guides/other-guides/testbed","h":"#usage","p":2174},{"i":2187,"t":"Custom CA","u":"/docs/iaas/guides/other-guides/testbed","h":"#custom-ca","p":2174},{"i":2189,"t":"VPN access","u":"/docs/iaas/guides/other-guides/testbed","h":"#vpn-access","p":2174},{"i":2191,"t":"Static entries in /etc/hosts","u":"/docs/iaas/guides/other-guides/testbed","h":"#static-entries-in-etchosts","p":2174},{"i":2193,"t":"Webinterfaces","u":"/docs/iaas/guides/other-guides/testbed","h":"#webinterfaces","p":2174},{"i":2195,"t":"Authentication with OIDC","u":"/docs/iaas/guides/other-guides/testbed","h":"#authentication-with-oidc","p":2174},{"i":2197,"t":"Advanced Usage","u":"/docs/iaas/guides/other-guides/testbed","h":"#advanced-usage","p":2174},{"i":2198,"t":"External API","u":"/docs/iaas/guides/other-guides/testbed","h":"#external-api","p":2174},{"i":2200,"t":"Change versions","u":"/docs/iaas/guides/other-guides/testbed","h":"#change-versions","p":2174},{"i":2202,"t":"Deploy services","u":"/docs/iaas/guides/other-guides/testbed","h":"#deploy-services","p":2174},{"i":2204,"t":"Upgrade services","u":"/docs/iaas/guides/other-guides/testbed","h":"#upgrade-services","p":2174},{"i":2206,"t":"Add new OSD in Ceph","u":"/docs/iaas/guides/other-guides/testbed","h":"#add-new-osd-in-ceph","p":2174},{"i":2208,"t":"Ceph via Rook (technical preview)","u":"/docs/iaas/guides/other-guides/testbed","h":"#ceph-via-rook-technical-preview","p":2174},{"i":2210,"t":"Using testbed for OpenStack development","u":"/docs/iaas/guides/other-guides/testbed","h":"#using-testbed-for-openstack-development","p":2174},{"i":2212,"t":"Troubleshooting","u":"/docs/iaas/guides/other-guides/testbed","h":"#troubleshooting","p":2174},{"i":2213,"t":"Ansible errors","u":"/docs/iaas/guides/other-guides/testbed","h":"#ansible-errors","p":2174},{"i":2215,"t":"Unsupported locale setting","u":"/docs/iaas/guides/other-guides/testbed","h":"#unsupported-locale-setting","p":2174},{"i":2217,"t":"Appendix","u":"/docs/iaas/guides/other-guides/testbed","h":"#appendix","p":2174},{"i":2218,"t":"Configuration","u":"/docs/iaas/guides/other-guides/testbed","h":"#configuration","p":2174},{"i":2220,"t":"Notes","u":"/docs/iaas/guides/other-guides/testbed","h":"#notes","p":2174},{"i":2222,"t":"Supported releases","u":"/docs/iaas/guides/other-guides/testbed","h":"#supported-releases","p":2174},{"i":2224,"t":"Included services","u":"/docs/iaas/guides/other-guides/testbed","h":"#included-services","p":2174},{"i":2226,"t":"Makefile reference","u":"/docs/iaas/guides/other-guides/testbed","h":"#makefile-reference","p":2174},{"i":2228,"t":"CI jobs","u":"/docs/iaas/guides/other-guides/testbed","h":"#ci-jobs","p":2174},{"i":2235,"t":"Scenario","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","h":"#scenario","p":2233},{"i":2237,"t":"Requirements","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","h":"#requirements","p":2233},{"i":2239,"t":"Prechecks","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","h":"#prechecks","p":2233},{"i":2241,"t":"Migration","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","h":"#migration","p":2233},{"i":2243,"t":"How to copy vmdk images","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","h":"#how-to-copy-vmdk-images","p":2233},{"i":2245,"t":"How to convert vmdk to raw","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","h":"#how-to-convert-vmdk-to-raw","p":2233},{"i":2247,"t":"Edit the raw Images (optional)","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","h":"#edit-the-raw-images-optional","p":2233},{"i":2249,"t":"How to import Images","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","h":"#how-to-import-images","p":2233},{"i":2251,"t":"How to create your server","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","h":"#how-to-create-your-server","p":2233},{"i":2253,"t":"Show your new server","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","h":"#show-your-new-server","p":2233},{"i":2255,"t":"How to access the VNC console","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","h":"#how-to-access-the-vnc-console","p":2233},{"i":2257,"t":"Last words","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","h":"#last-words","p":2233},{"i":2262,"t":"Upload the ISO image","u":"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso","h":"#upload-the-iso-image","p":2260},{"i":2264,"t":"Creating the instance","u":"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso","h":"#creating-the-instance","p":2260},{"i":2265,"t":"Using nova local storage","u":"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso","h":"#using-nova-local-storage","p":2260},{"i":2267,"t":"Using boot from volume","u":"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso","h":"#using-boot-from-volume","p":2260},{"i":2269,"t":"Install the created instance from the uploaded ISO","u":"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso","h":"#install-the-created-instance-from-the-uploaded-iso","p":2260},{"i":2273,"t":"Migration from openrc to clouds.yaml","u":"/docs/iaas/guides/user-guide/openstack/openstackclient","h":"#migration-from-openrc-to-cloudsyaml","p":2271},{"i":2275,"t":"With an editor","u":"/docs/iaas/guides/user-guide/openstack/openstackclient","h":"#with-an-editor","p":2271},{"i":2277,"t":"With a script","u":"/docs/iaas/guides/user-guide/openstack/openstackclient","h":"#with-a-script","p":2271},{"i":2278,"t":"Python","u":"/docs/iaas/guides/user-guide/openstack/openstackclient","h":"#python","p":2271},{"i":2280,"t":"Bash","u":"/docs/iaas/guides/user-guide/openstack/openstackclient","h":"#bash","p":2271},{"i":2284,"t":"Identify the requirements of your setup","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#identify-the-requirements-of-your-setup","p":2282},{"i":2286,"t":"Further security considerations","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#further-security-considerations","p":2282},{"i":2288,"t":"How to create security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#how-to-create-security-groups","p":2282},{"i":2290,"t":"Default security group","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#default-security-group","p":2282},{"i":2292,"t":"Recommended security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#recommended-security-groups","p":2282},{"i":2294,"t":"How to use security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#how-to-use-security-groups","p":2282},{"i":2298,"t":"Identify the requirements of your setup","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#identify-the-requirements-of-your-setup","p":2296},{"i":2300,"t":"Further security considerations","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#further-security-considerations","p":2296},{"i":2302,"t":"How to create security groups","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#how-to-create-security-groups","p":2296},{"i":2304,"t":"Default security group","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#default-security-group","p":2296},{"i":2306,"t":"Recommended security groups","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#recommended-security-groups","p":2296},{"i":2308,"t":"How to use security groups","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#how-to-use-security-groups","p":2296},{"i":2318,"t":"Glossary","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#glossary","p":2316},{"i":2320,"t":"Scope","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#scope","p":2316},{"i":2322,"t":"Overview of applicable User Data","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#overview-of-applicable-user-data","p":2316},{"i":2324,"t":"Image backup using download","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#image-backup-using-download","p":2316},{"i":2326,"t":"Ephemeral Storage backup using Glance images","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#ephemeral-storage-backup-using-glance-images","p":2316},{"i":2328,"t":"Volume data backup using Cinder Backup API","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#volume-data-backup-using-cinder-backup-api","p":2316},{"i":2330,"t":"Backup of detached volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#backup-of-detached-volumes","p":2316},{"i":2332,"t":"Backup of attached volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#backup-of-attached-volumes","p":2316},{"i":2334,"t":"Volume data backup using Glance images","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#volume-data-backup-using-glance-images","p":2316},{"i":2336,"t":"Glance image backups of detached volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#glance-image-backups-of-detached-volumes","p":2316},{"i":2338,"t":"Glance image backups of attached (in-use) volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#glance-image-backups-of-attached-in-use-volumes","p":2316},{"i":2340,"t":"Barbican secrets backup using download","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#barbican-secrets-backup-using-download","p":2316},{"i":2342,"t":"Retrieving encryption keys from Barbican","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#retrieving-encryption-keys-from-barbican","p":2316},{"i":2344,"t":"Restore","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restore","p":2316},{"i":2346,"t":"Restoring a backup of a Barbican secret","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-backup-of-a-barbican-secret","p":2316},{"i":2348,"t":"Restoring a backup of an unencrypted image","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-backup-of-an-unencrypted-image","p":2316},{"i":2350,"t":"Restoring a backup of an encrypted image","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-backup-of-an-encrypted-image","p":2316},{"i":2352,"t":"Restoring a volume backup from an image","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-volume-backup-from-an-image","p":2316},{"i":2354,"t":"Restoring a volume backup from the Cinder Backup service","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-volume-backup-from-the-cinder-backup-service","p":2316},{"i":2356,"t":"Appendix","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#appendix","p":2316},{"i":2357,"t":"Image creation action for servers with attached volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#image-creation-action-for-servers-with-attached-volumes","p":2316},{"i":2359,"t":"LUKS encryption key conversion to decrypt volume images","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#luks-encryption-key-conversion-to-decrypt-volume-images","p":2316},{"i":2367,"t":"Deployment","u":"/docs/iam/","h":"#deployment","p":2365},{"i":2369,"t":"Accessing Keycloak","u":"/docs/iam/","h":"#accessing-keycloak","p":2365},{"i":2371,"t":"Identity Mapping","u":"/docs/iam/","h":"#identity-mapping","p":2365},{"i":2373,"t":"SCS to SCS federation","u":"/docs/iam/","h":"#scs-to-scs-federation","p":2365},{"i":2375,"t":"Prerequisites and Requirements","u":"/docs/iam/","h":"#prerequisites-and-requirements","p":2365},{"i":2377,"t":"Features","u":"/docs/iam/","h":"#features","p":2365},{"i":2379,"t":"Limitations","u":"/docs/iam/","h":"#limitations","p":2365},{"i":2381,"t":"Current state and future Outlook","u":"/docs/iam/","h":"#current-state-and-future-outlook","p":2365},{"i":2385,"t":"Glossary","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#glossary","p":2383},{"i":2387,"t":"Scope","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#scope","p":2383},{"i":2389,"t":"Overview of applicable User Data","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#overview-of-applicable-user-data","p":2383},{"i":2391,"t":"Image backup using download","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#image-backup-using-download","p":2383},{"i":2393,"t":"Ephemeral Storage backup using Glance images","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#ephemeral-storage-backup-using-glance-images","p":2383},{"i":2395,"t":"Volume data backup using Cinder Backup API","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#volume-data-backup-using-cinder-backup-api","p":2383},{"i":2397,"t":"Backup of detached volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#backup-of-detached-volumes","p":2383},{"i":2399,"t":"Backup of attached volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#backup-of-attached-volumes","p":2383},{"i":2401,"t":"Volume data backup using Glance images","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#volume-data-backup-using-glance-images","p":2383},{"i":2403,"t":"Glance image backups of detached volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#glance-image-backups-of-detached-volumes","p":2383},{"i":2405,"t":"Glance image backups of attached (in-use) volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#glance-image-backups-of-attached-in-use-volumes","p":2383},{"i":2407,"t":"Barbican secrets backup using download","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#barbican-secrets-backup-using-download","p":2383},{"i":2409,"t":"Retrieving encryption keys from Barbican","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#retrieving-encryption-keys-from-barbican","p":2383},{"i":2411,"t":"Restore","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restore","p":2383},{"i":2413,"t":"Restoring a backup of a Barbican secret","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-backup-of-a-barbican-secret","p":2383},{"i":2415,"t":"Restoring a backup of an unencrypted image","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-backup-of-an-unencrypted-image","p":2383},{"i":2417,"t":"Restoring a backup of an encrypted image","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-backup-of-an-encrypted-image","p":2383},{"i":2419,"t":"Restoring a volume backup from an image","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-volume-backup-from-an-image","p":2383},{"i":2421,"t":"Restoring a volume backup from the Cinder Backup service","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-volume-backup-from-the-cinder-backup-service","p":2383},{"i":2423,"t":"Appendix","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#appendix","p":2383},{"i":2424,"t":"Image creation action for servers with attached volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#image-creation-action-for-servers-with-attached-volumes","p":2383},{"i":2426,"t":"LUKS encryption key conversion to decrypt volume images","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#luks-encryption-key-conversion-to-decrypt-volume-images","p":2383},{"i":2430,"t":"Detailed tutorial on how to configure Federation (OpenID Connect) between two Keycloak instances in two separate SCS domains","u":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","h":"#detailed-tutorial-on-how-to-configure-federation-openid-connect-between-two-keycloak-instances-in-two-separate-scs-domains","p":2428},{"i":2436,"t":"Preface","u":"/docs/iam/domain-manager-setup-and-usage","h":"#preface","p":2434},{"i":2438,"t":"Warning regarding the exposure of domain names","u":"/docs/iam/domain-manager-setup-and-usage","h":"#warning-regarding-the-exposure-of-domain-names","p":2434},{"i":2440,"t":"Infrastructure configuration","u":"/docs/iam/domain-manager-setup-and-usage","h":"#infrastructure-configuration","p":2434},{"i":2442,"t":"[Initial] Keystone API policy adjustments","u":"/docs/iam/domain-manager-setup-and-usage","h":"#initial-keystone-api-policy-adjustments","p":2434},{"i":2444,"t":"[Initial] Keystone role creation","u":"/docs/iam/domain-manager-setup-and-usage","h":"#initial-keystone-role-creation","p":2434},{"i":2446,"t":"[Runtime] Domain Manager managed roles adjustment","u":"/docs/iam/domain-manager-setup-and-usage","h":"#runtime-domain-manager-managed-roles-adjustment","p":2434},{"i":2448,"t":"Administrative operation","u":"/docs/iam/domain-manager-setup-and-usage","h":"#administrative-operation","p":2434},{"i":2450,"t":"Creating domains","u":"/docs/iam/domain-manager-setup-and-usage","h":"#creating-domains","p":2434},{"i":2452,"t":"Creating a Domain Manager user","u":"/docs/iam/domain-manager-setup-and-usage","h":"#creating-a-domain-manager-user","p":2434},{"i":2454,"t":"Assigning the Domain Manager role to an existing user","u":"/docs/iam/domain-manager-setup-and-usage","h":"#assigning-the-domain-manager-role-to-an-existing-user","p":2434},{"i":2456,"t":"Revoking the Domain Manager role","u":"/docs/iam/domain-manager-setup-and-usage","h":"#revoking-the-domain-manager-role","p":2434},{"i":2458,"t":"Domain Manager operation","u":"/docs/iam/domain-manager-setup-and-usage","h":"#domain-manager-operation","p":2434},{"i":2460,"t":"Managing users within a domain","u":"/docs/iam/domain-manager-setup-and-usage","h":"#managing-users-within-a-domain","p":2434},{"i":2462,"t":"Managing projects within a domain","u":"/docs/iam/domain-manager-setup-and-usage","h":"#managing-projects-within-a-domain","p":2434},{"i":2464,"t":"Managing groups within a domain","u":"/docs/iam/domain-manager-setup-and-usage","h":"#managing-groups-within-a-domain","p":2434},{"i":2466,"t":"Managing role assignments within a domain","u":"/docs/iam/domain-manager-setup-and-usage","h":"#managing-role-assignments-within-a-domain","p":2434},{"i":2468,"t":"Footnotes","u":"/docs/iam/domain-manager-setup-and-usage","h":"#footnote-label","p":2434},{"i":2474,"t":"Prerequisites","u":"/docs/operating-scs/components/automated-pentesting-iaas/quickstart","h":"#prerequisites","p":2472},{"i":2476,"t":"Configuration","u":"/docs/operating-scs/components/automated-pentesting-iaas/quickstart","h":"#configuration","p":2472},{"i":2477,"t":"DefectDojo","u":"/docs/operating-scs/components/automated-pentesting-iaas/quickstart","h":"#defectdojo","p":2472},{"i":2479,"t":"Zuul","u":"/docs/operating-scs/components/automated-pentesting-iaas/quickstart","h":"#zuul","p":2472},{"i":2481,"t":"Aditional notes","u":"/docs/operating-scs/components/automated-pentesting-iaas/quickstart","h":"#aditional-notes","p":2472},{"i":2484,"t":"Introdution","u":"/docs/operating-scs/components/automated-pentesting-iaas/overview","h":"#introdution","p":2483},{"i":2486,"t":"Cloud Security Concerns","u":"/docs/operating-scs/components/automated-pentesting-iaas/overview","h":"#cloud-security-concerns","p":2483},{"i":2488,"t":"SCS automated pentesting","u":"/docs/operating-scs/components/automated-pentesting-iaas/overview","h":"#scs-automated-pentesting","p":2483},{"i":2490,"t":"Quickstart Guide","u":"/docs/operating-scs/components/automated-pentesting-iaas/overview","h":"#quickstart-guide","p":2483},{"i":2492,"t":"Tools","u":"/docs/operating-scs/components/automated-pentesting-iaas/overview","h":"#tools","p":2483},{"i":2494,"t":"Source","u":"/docs/operating-scs/components/automated-pentesting-iaas/overview","h":"#source","p":2483},{"i":2498,"t":"Understanding the Pentesting Reports for IaaS and CaaS","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#understanding-the-pentesting-reports-for-iaas-and-caas","p":2496},{"i":2500,"t":"Importance of Daily and Weekly Reports","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#importance-of-daily-and-weekly-reports","p":2496},{"i":2502,"t":"Key Characteristics and Capabilities of Reports","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#key-characteristics-and-capabilities-of-reports","p":2496},{"i":2504,"t":"Role and Responsibilities of Operators and Users","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#role-and-responsibilities-of-operators-and-users","p":2496},{"i":2505,"t":"For Operators (high-level view):","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#for-operators-high-level-view","p":2496},{"i":2507,"t":"For Operator's staff:","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#for-operators-staff","p":2496},{"i":2509,"t":"For Users (DevOps):","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#for-users-devops","p":2496},{"i":2511,"t":"Actions Based on Pentesting Reports","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#actions-based-on-pentesting-reports","p":2496},{"i":2513,"t":"SOC Operations","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#soc-operations","p":2496},{"i":2515,"t":"With a SOC","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#with-a-soc","p":2496},{"i":2517,"t":"Without a SOC:","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#without-a-soc","p":2496},{"i":2519,"t":"Future Policy Development","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#future-policy-development","p":2496},{"i":2521,"t":"Conclusion","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","h":"#conclusion","p":2496},{"i":2524,"t":"Introdution","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","h":"#introdution","p":2523},{"i":2526,"t":"Kubernetes Security Concerns","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","h":"#kubernetes-security-concerns","p":2523},{"i":2528,"t":"Infrastructure Security Challenges in Kubernetes:","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","h":"#infrastructure-security-challenges-in-kubernetes","p":2523},{"i":2530,"t":"Application Security Challenges in Kubernetes:","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","h":"#application-security-challenges-in-kubernetes","p":2523},{"i":2532,"t":"Infrastructure and application scanning","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","h":"#infrastructure-and-application-scanning","p":2523},{"i":2534,"t":"Scanning Images with Trivy:","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","h":"#scanning-images-with-trivy","p":2523},{"i":2536,"t":"Scanning Infrastructure with Trivy:","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","h":"#scanning-infrastructure-with-trivy","p":2523},{"i":2538,"t":"Trivy Operator for Internal Scanning:","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","h":"#trivy-operator-for-internal-scanning","p":2523},{"i":2540,"t":"Quickstart Guide","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","h":"#quickstart-guide","p":2523},{"i":2542,"t":"Tools","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","h":"#tools","p":2523},{"i":2544,"t":"Source","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","h":"#source","p":2523},{"i":2548,"t":"Naabu","u":"/docs/operating-scs/components/automated-pentesting-iaas/tools","h":"#naabu","p":2546},{"i":2550,"t":"HTTPx","u":"/docs/operating-scs/components/automated-pentesting-iaas/tools","h":"#httpx","p":2546},{"i":2552,"t":"Nuclei","u":"/docs/operating-scs/components/automated-pentesting-iaas/tools","h":"#nuclei","p":2546},{"i":2554,"t":"Greenbone Community Edition (OpenVAS)","u":"/docs/operating-scs/components/automated-pentesting-iaas/tools","h":"#greenbone-community-edition-openvas","p":2546},{"i":2556,"t":"ZAP Proxy","u":"/docs/operating-scs/components/automated-pentesting-iaas/tools","h":"#zap-proxy","p":2546},{"i":2558,"t":"Defect Dojo","u":"/docs/operating-scs/components/automated-pentesting-iaas/tools","h":"#defect-dojo","p":2546},{"i":2562,"t":"Prerequisites","u":"/docs/operating-scs/components/automated-pentesting-kaas/quickstart","h":"#prerequisites","p":2560},{"i":2564,"t":"Project Structure","u":"/docs/operating-scs/components/automated-pentesting-kaas/quickstart","h":"#project-structure","p":2560},{"i":2566,"t":"Main Files","u":"/docs/operating-scs/components/automated-pentesting-kaas/quickstart","h":"#main-files","p":2560},{"i":2568,"t":"Deployment","u":"/docs/operating-scs/components/automated-pentesting-kaas/quickstart","h":"#deployment","p":2560},{"i":2571,"t":"Premise","u":"/docs/operating-scs/components/central-api/overview","h":"#premise","p":2570},{"i":2573,"t":"Challenge","u":"/docs/operating-scs/components/central-api/overview","h":"#challenge","p":2570},{"i":2575,"t":"The chosen approach to pursue","u":"/docs/operating-scs/components/central-api/overview","h":"#the-chosen-approach-to-pursue","p":2570},{"i":2577,"t":"Kubernetes API","u":"/docs/operating-scs/components/central-api/overview","h":"#kubernetes-api","p":2570},{"i":2579,"t":"Crossplane tooling","u":"/docs/operating-scs/components/central-api/overview","h":"#crossplane-tooling","p":2570},{"i":2581,"t":"Cluster stacks / Cluster API","u":"/docs/operating-scs/components/central-api/overview","h":"#cluster-stacks--cluster-api","p":2570},{"i":2583,"t":"Implementation","u":"/docs/operating-scs/components/central-api/overview","h":"#implementation","p":2570},{"i":2585,"t":"Footnotes","u":"/docs/operating-scs/components/central-api/overview","h":"#footnote-label","p":2570},{"i":2589,"t":"Trivy Container","u":"/docs/operating-scs/components/automated-pentesting-kaas/tools","h":"#trivy-container","p":2587},{"i":2591,"t":"Trivy Operator","u":"/docs/operating-scs/components/automated-pentesting-kaas/tools","h":"#trivy-operator","p":2587},{"i":2593,"t":"Trivy Reporter","u":"/docs/operating-scs/components/automated-pentesting-kaas/tools","h":"#trivy-reporter","p":2587},{"i":2595,"t":"Kubernetes CronJob","u":"/docs/operating-scs/components/automated-pentesting-kaas/tools","h":"#kubernetes-cronjob","p":2587},{"i":2597,"t":"Defect Dojo","u":"/docs/operating-scs/components/automated-pentesting-kaas/tools","h":"#defect-dojo","p":2587},{"i":2601,"t":"Quick Start","u":"/docs/operating-scs/components/central-api/poc-setup","h":"#quick-start","p":2599},{"i":2609,"t":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"#prerequisites","p":2607},{"i":2611,"t":"Prepare K3s Kubernetes cluster via K3d","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"#prepare-k3s-kubernetes-cluster-via-k3d","p":2607},{"i":2613,"t":"Deploy Observer monitoring solution","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"#deploy-observer-monitoring-solution","p":2607},{"i":2615,"t":"Access the Observer monitoring UIs","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"","p":2607},{"i":2621,"t":"Enable KaaS layer monitoring","u":"/docs/operating-scs/components/monitoring/docs/kaas","h":"#enable-kaas-layer-monitoring","p":2619},{"i":2623,"t":"KaaS metric importer","u":"/docs/operating-scs/components/monitoring/docs/kaas","h":"#kaas-metric-importer","p":2619},{"i":2625,"t":"KaaS mock service","u":"/docs/operating-scs/components/monitoring/docs/kaas","h":"#kaas-mock-service","p":2619},{"i":2631,"t":"Architecture","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","h":"#architecture","p":2629},{"i":2633,"t":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","h":"#prerequisites","p":2629},{"i":2635,"t":"Install Observer solution","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","h":"#install-observer-solution","p":2629},{"i":2639,"t":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#prerequisites","p":2637},{"i":2641,"t":"Local environment use case - KinD/K3s cluster deployed locally","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#local-environment-use-case---kindk3s-cluster-deployed-locally","p":2637},{"i":2643,"t":"OSISM use case - K3s cluster in OSISM deployment","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#osism-use-case---k3s-cluster-in-osism-deployment","p":2637},{"i":2645,"t":"Deploy IaaS monitoring components","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#deploy-iaas-monitoring-components","p":2637},{"i":2646,"t":"OpenStack","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#openstack","p":2637},{"i":2648,"t":"Ceph","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#ceph","p":2637},{"i":2652,"t":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"#prerequisites","p":2650},{"i":2654,"t":"Prepare Kubernetes cluster","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"#prepare-kubernetes-cluster","p":2650},{"i":2656,"t":"Deploy Observer monitoring solution","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"#deploy-observer-monitoring-solution","p":2650},{"i":2658,"t":"Access the Observer monitoring UIs","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"#access-the-observer-monitoring-uis","p":2650},{"i":2662,"t":"Example","u":"/docs/operating-scs/components/monitoring/docs/tracing","h":"#example","p":2660},{"i":2664,"t":"Usage","u":"/docs/operating-scs/components/monitoring/docs/tracing","h":"#usage","p":2660},{"i":2667,"t":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/status-page","h":"#prerequisites","p":2666},{"i":2669,"t":"Local environment use case - KinD/K3s cluster deployed locally","u":"/docs/operating-scs/components/monitoring/docs/status-page","h":"#local-environment-use-case---kindk3s-cluster-deployed-locally","p":2666},{"i":2671,"t":"OSISM use case - K3s cluster in OSISM deployment","u":"/docs/operating-scs/components/monitoring/docs/status-page","h":"#osism-use-case---k3s-cluster-in-osism-deployment","p":2666},{"i":2673,"t":"Deploy Status page monitoring","u":"/docs/operating-scs/components/monitoring/docs/status-page","h":"#deploy-status-page-monitoring","p":2666},{"i":2675,"t":"Access the Status page dashboards","u":"/docs/operating-scs/components/monitoring/docs/status-page","h":"#access-the-status-page-dashboards","p":2666},{"i":2681,"t":"Query Frontend","u":"/docs/operating-scs/components/monitoring/docs/tuning","h":"#query-frontend","p":2679},{"i":2683,"t":"Compactor","u":"/docs/operating-scs/components/monitoring/docs/tuning","h":"#compactor","p":2679},{"i":2685,"t":"Query","u":"/docs/operating-scs/components/monitoring/docs/tuning","h":"#query","p":2679},{"i":2689,"t":"Description","u":"/docs/operating-scs/components/scs-health-monitor/overview","h":"#description","p":2687},{"i":2691,"t":"Getting Started","u":"/docs/operating-scs/components/scs-health-monitor/overview","h":"#getting-started","p":2687},{"i":2693,"t":"Using the test framework","u":"/docs/operating-scs/components/scs-health-monitor/overview","h":"#using-the-test-framework","p":2687},{"i":2694,"t":"Execute a specific test","u":"/docs/operating-scs/components/scs-health-monitor/overview","h":"#execute-a-specific-test","p":2687},{"i":2696,"t":"Execute a series of tests","u":"/docs/operating-scs/components/scs-health-monitor/overview","h":"#execute-a-series-of-tests","p":2687},{"i":2698,"t":"Publish results to Prometheus","u":"/docs/operating-scs/components/scs-health-monitor/overview","h":"#publish-results-to-prometheus","p":2687},{"i":2700,"t":"Setting up Prometheus and Prometheus Push Gateway locally","u":"/docs/operating-scs/components/scs-health-monitor/overview","h":"#setting-up-prometheus-and-prometheus-push-gateway-locally","p":2687},{"i":2702,"t":"Exporting metrics to Prometheus Push Gateway","u":"/docs/operating-scs/components/scs-health-monitor/overview","h":"#exporting-metrics-to-prometheus-push-gateway","p":2687},{"i":2704,"t":"Use a docker image","u":"/docs/operating-scs/components/scs-health-monitor/overview","h":"#use-a-docker-image","p":2687},{"i":2706,"t":"Collaborators","u":"/docs/operating-scs/components/scs-health-monitor/overview","h":"#collaborators","p":2687},{"i":2708,"t":"Useful links and references","u":"/docs/operating-scs/components/scs-health-monitor/overview","h":"#useful-links-and-references","p":2687},{"i":2711,"t":"Quick Intro:","u":"/docs/operating-scs/components/scs-health-monitor/Testflow","h":"#quick-intro","p":2710},{"i":2713,"t":"Real Testing:","u":"/docs/operating-scs/components/scs-health-monitor/Testflow","h":"#real-testing","p":2710},{"i":2715,"t":"Extended Description:","u":"/docs/operating-scs/components/scs-health-monitor/Testflow","h":"#extended-description","p":2710},{"i":2717,"t":"Scaling the Benchmark Infrastructure","u":"/docs/operating-scs/components/scs-health-monitor/Testflow","h":"#scaling-the-benchmark-infrastructure","p":2710},{"i":2722,"t":"Overview","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#overview","p":2721},{"i":2724,"t":"Usage","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#usage","p":2721},{"i":2726,"t":"Configuration","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#configuration","p":2721},{"i":2727,"t":"Kubernetes Configuration","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#kubernetes-configuration","p":2721},{"i":2729,"t":"Helm Configuration","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#helm-configuration","p":2721},{"i":2731,"t":"Running Tests","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#running-tests","p":2721},{"i":2733,"t":"Running the Tests","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#running-the-tests","p":2721},{"i":2735,"t":"Example Command to Run a Specific Feature File","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#example-command-to-run-a-specific-feature-file","p":2721},{"i":2737,"t":"Adding New Features","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#adding-new-features","p":2721},{"i":2739,"t":"Creating New Feature Files","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#creating-new-feature-files","p":2721},{"i":2741,"t":"Troubleshooting","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#troubleshooting","p":2721},{"i":2742,"t":"Common Errors","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#common-errors","p":2721},{"i":2744,"t":"Observability stack","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#observability-stack","p":2721},{"i":2746,"t":"Adding fixes/new functionalities to the project flow:","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#adding-fixesnew-functionalities-to-the-project-flow","p":2721},{"i":2748,"t":"Conclusion","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","h":"#conclusion","p":2721},{"i":2753,"t":"Prerequisites","u":"/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack","h":"#prerequisites","p":2752},{"i":2755,"t":"Setup process","u":"/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack","h":"#setup-process","p":2752},{"i":2759,"t":"List phases","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#list-phases","p":2757},{"i":2761,"t":"Create phases","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#create-phases","p":2757},{"i":2763,"t":"List impact types","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#list-impact-types","p":2757},{"i":2765,"t":"Create impact type","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#create-impact-type","p":2757},{"i":2767,"t":"Get impact type","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#get-impact-type","p":2757},{"i":2769,"t":"List severities","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#list-severities","p":2757},{"i":2771,"t":"Create severity","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#create-severity","p":2757},{"i":2773,"t":"Get severity","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#get-severity","p":2757},{"i":2775,"t":"List components","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#list-components","p":2757},{"i":2777,"t":"Create component","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#create-component","p":2757},{"i":2779,"t":"Get component","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#get-component","p":2757},{"i":2781,"t":"List incidents","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#list-incidents","p":2757},{"i":2783,"t":"Create incident","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#create-incident","p":2757},{"i":2785,"t":"Get incident","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#get-incident","p":2757},{"i":2787,"t":"List incident update","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#list-incident-update","p":2757},{"i":2789,"t":"Create incident update","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#create-incident-update","p":2757},{"i":2791,"t":"Get incident update","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","h":"#get-incident-update","p":2757},{"i":2797,"t":"Run as container","u":"/docs/operating-scs/components/status-page-api/docs/quickstart","h":"#run-as-container","p":2795},{"i":2799,"t":"Compile and run the binary","u":"/docs/operating-scs/components/status-page-api/docs/quickstart","h":"#compile-and-run-the-binary","p":2795},{"i":2801,"t":"Running tests","u":"/docs/operating-scs/components/status-page-api/docs/quickstart","h":"#running-tests","p":2795},{"i":2805,"t":"Phases","u":"/docs/operating-scs/components/status-page-api/docs/requests","h":"#phases","p":2803},{"i":2807,"t":"Impact types","u":"/docs/operating-scs/components/status-page-api/docs/requests","h":"#impact-types","p":2803},{"i":2809,"t":"Severities","u":"/docs/operating-scs/components/status-page-api/docs/requests","h":"#severities","p":2803},{"i":2811,"t":"Components","u":"/docs/operating-scs/components/status-page-api/docs/requests","h":"#components","p":2803},{"i":2813,"t":"Incidents","u":"/docs/operating-scs/components/status-page-api/docs/requests","h":"#incidents","p":2803},{"i":2815,"t":"Incident update","u":"/docs/operating-scs/components/status-page-api/docs/requests","h":"#incident-update","p":2803},{"i":2821,"t":"API server","u":"/docs/operating-scs/components/status-page-deployment/docs/configuration","h":"#api-server","p":2819},{"i":2823,"t":"Database","u":"/docs/operating-scs/components/status-page-deployment/docs/configuration","h":"#database","p":2819},{"i":2825,"t":"Dex","u":"/docs/operating-scs/components/status-page-deployment/docs/configuration","h":"#dex","p":2819},{"i":2827,"t":"Oathkeeper","u":"/docs/operating-scs/components/status-page-deployment/docs/configuration","h":"#oathkeeper","p":2819},{"i":2829,"t":"Web frontend","u":"/docs/operating-scs/components/status-page-deployment/docs/configuration","h":"#web-frontend","p":2819},{"i":2831,"t":"Ingress","u":"/docs/operating-scs/components/status-page-deployment/docs/configuration","h":"#ingress","p":2819},{"i":2833,"t":"Issuer","u":"/docs/operating-scs/components/status-page-deployment/docs/configuration","h":"#issuer","p":2819},{"i":2838,"t":"Dex needs a GitHub client secret. Where can I get it?","u":"/docs/operating-scs/components/status-page-deployment/docs/faq","h":"#dex-needs-a-github-client-secret-where-can-i-get-it","p":2837},{"i":2840,"t":"I want to deploy on XY, can you do that?","u":"/docs/operating-scs/components/status-page-deployment/docs/faq","h":"#i-want-to-deploy-on-xy-can-you-do-that","p":2837},{"i":2842,"t":"I want to deploy another database, reverse proxy, ingress, AuthN, AuthZ, etc. Can you do that?","u":"/docs/operating-scs/components/status-page-deployment/docs/faq","h":"#i-want-to-deploy-another-database-reverse-proxy-ingress-authn-authz-etc-can-you-do-that","p":2837},{"i":2844,"t":"I want another web frontend and API server, can you do that?","u":"/docs/operating-scs/components/status-page-deployment/docs/faq","h":"#i-want-another-web-frontend-and-api-server-can-you-do-that","p":2837},{"i":2848,"t":"Prerequisites","u":"/docs/operating-scs/components/status-page-deployment/docs/k3s","h":"#prerequisites","p":2846},{"i":2850,"t":"k3s setup","u":"/docs/operating-scs/components/status-page-deployment/docs/k3s","h":"#k3s-setup","p":2846},{"i":2852,"t":"Firewall settings","u":"/docs/operating-scs/components/status-page-deployment/docs/k3s","h":"#firewall-settings","p":2846},{"i":2854,"t":"Install","u":"/docs/operating-scs/components/status-page-deployment/docs/k3s","h":"#install","p":2846},{"i":2856,"t":"Deployment","u":"/docs/operating-scs/components/status-page-deployment/docs/k3s","h":"#deployment","p":2846},{"i":2858,"t":"Kube config","u":"/docs/operating-scs/components/status-page-deployment/docs/k3s","h":"#kube-config","p":2846},{"i":2860,"t":"Deploy cert manager","u":"/docs/operating-scs/components/status-page-deployment/docs/k3s","h":"#deploy-cert-manager","p":2846},{"i":2862,"t":"Configure and deploy status page","u":"/docs/operating-scs/components/status-page-deployment/docs/k3s","h":"#configure-and-deploy-status-page","p":2846},{"i":2868,"t":"Endpoints","u":"/docs/operating-scs/components/status-page-deployment/docs/monitoring","h":"#endpoints","p":2866},{"i":2870,"t":"Dashboards","u":"/docs/operating-scs/components/status-page-deployment/docs/monitoring","h":"#dashboards","p":2866},{"i":2872,"t":"KinD","u":"/docs/operating-scs/components/status-page-deployment/docs/monitoring","h":"#kind","p":2866},{"i":2876,"t":"\"Secrets\"","u":"/docs/operating-scs/components/status-page-deployment/docs/kind","h":"#secrets","p":2874},{"i":2878,"t":"Per Installation Steps","u":"/docs/operating-scs/components/status-page-deployment/docs/kind","h":"#per-installation--steps","p":2874},{"i":2880,"t":"Setup","u":"/docs/operating-scs/components/status-page-deployment/docs/kind","h":"#setup","p":2874},{"i":2882,"t":"Deploy","u":"/docs/operating-scs/components/status-page-deployment/docs/kind","h":"#deploy","p":2874},{"i":2884,"t":"Port forward","u":"/docs/operating-scs/components/status-page-deployment/docs/kind","h":"#port-forward","p":2874},{"i":2888,"t":"Components","u":"/docs/operating-scs/components/status-page-deployment/docs/overview","h":"#components","p":2886},{"i":2890,"t":"Component overview","u":"/docs/operating-scs/components/status-page-deployment/docs/overview","h":"#component-overview","p":2886},{"i":2891,"t":"Deployment repository","u":"/docs/operating-scs/components/status-page-deployment/docs/overview","h":"#deployment-repository","p":2886},{"i":2893,"t":"Footnotes","u":"/docs/operating-scs/components/status-page-deployment/docs/overview","h":"#footnote-label","p":2886},{"i":2905,"t":"Receive auth code","u":"/docs/operating-scs/components/status-page-deployment/docs/usage","h":"#receive-auth-code","p":2903},{"i":2907,"t":"Exchange token","u":"/docs/operating-scs/components/status-page-deployment/docs/usage","h":"#exchange-token","p":2903},{"i":2909,"t":"Use API","u":"/docs/operating-scs/components/status-page-deployment/docs/usage","h":"#use-api","p":2903},{"i":2917,"t":"The SCS status page API","u":"/docs/operating-scs/components/status-page-openapi/docs/overview","h":"#the-scs-status-page-api","p":2915},{"i":2919,"t":"Reference implementation","u":"/docs/operating-scs/components/status-page-openapi/docs/overview","h":"#reference-implementation","p":2915},{"i":2921,"t":"The SCS status page frontend","u":"/docs/operating-scs/components/status-page-openapi/docs/overview","h":"#the-scs-status-page-frontend","p":2915},{"i":2923,"t":"Reference implementation","u":"/docs/operating-scs/components/status-page-openapi/docs/overview","h":"#reference-implementation-1","p":2915},{"i":2925,"t":"Footnotes","u":"/docs/operating-scs/components/status-page-openapi/docs/overview","h":"#footnote-label","p":2915},{"i":2929,"t":"Configuration File","u":"/docs/operating-scs/components/status-page-web/docs/configuration","h":"#configuration-file","p":2927},{"i":2931,"t":"Field Types","u":"/docs/operating-scs/components/status-page-web/docs/configuration","h":"#field-types","p":2927},{"i":2947,"t":"Intro","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#intro","p":2945},{"i":2949,"t":"Setting up the driver VM","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#setting-up-the-driver-vm","p":2945},{"i":2951,"t":"Internal vs external monitoring","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#internal-vs-external-monitoring","p":2945},{"i":2953,"t":"Unprivileged operation","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#unprivileged-operation","p":2945},{"i":2955,"t":"Driver VM via openstack CLI","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#driver-vm-via-openstack-cli","p":2945},{"i":2957,"t":"Configuring openstack CLI on the driver VM","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#configuring-openstack-cli-on-the-driver-vm","p":2945},{"i":2959,"t":"Custom CA","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#custom-ca","p":2945},{"i":2961,"t":"Your first api_monitor.sh iteration","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#your-first-api_monitorsh-iteration","p":2945},{"i":2963,"t":"Resource impact and charging","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#resource-impact-and-charging","p":2945},{"i":2965,"t":"Automating startup and cleanup","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#automating-startup-and-cleanup","p":2945},{"i":2967,"t":"Changing parameters and restarting","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#changing-parameters-and-restarting","p":2945},{"i":2969,"t":"Multiple instances","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#multiple-instances","p":2945},{"i":2971,"t":"Alarming and Logs","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#alarming-and-logs","p":2945},{"i":2972,"t":"eMail","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#email","p":2945},{"i":2974,"t":"Log files","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#log-files","p":2945},{"i":2976,"t":"Data collection and dashboard","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#data-collection-and-dashboard","p":2945},{"i":2978,"t":"Telegraf","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#telegraf","p":2945},{"i":2980,"t":"InfluxDB","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#influxdb","p":2945},{"i":2982,"t":"Add -S CLOUDNAME to your run_CLOUDNAME.sh script","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#add--s-cloudname-to-your-run_cloudnamesh-script","p":2945},{"i":2984,"t":"Caddy (Reverse Proxy)","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#caddy-reverse-proxy","p":2945},{"i":2986,"t":"Grafana","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#grafana","p":2945},{"i":2988,"t":"Maintenance","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#maintenance","p":2945},{"i":2990,"t":"Unattended upgrades","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#unattended-upgrades","p":2945},{"i":2992,"t":"sshd setup","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#sshd-setup","p":2945},{"i":2994,"t":"Updating openstack-health-monitor","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#updating-openstack-health-monitor","p":2945},{"i":2996,"t":"Backup","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#backup","p":2945},{"i":2998,"t":"Troubleshooting","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#troubleshooting","p":2945},{"i":2999,"t":"Debugging issues","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#debugging-issues","p":2945},{"i":3001,"t":"Analyzing failures","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#analyzing-failures","p":2945},{"i":3003,"t":"Cleaning things up","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#cleaning-things-up","p":2945},{"i":3013,"t":"Scope","u":"/docs/releases/Release0","h":"#scope","p":3011},{"i":3015,"t":"Features","u":"/docs/releases/Release0","h":"#features","p":3011},{"i":3017,"t":"Get SCS","u":"/docs/releases/Release0","h":"#get-scs","p":3011},{"i":3019,"t":"Known Bugs","u":"/docs/releases/Release0","h":"#known-bugs","p":3011},{"i":3021,"t":"Technical Previews","u":"/docs/releases/Release0","h":"#technical-previews","p":3011},{"i":3023,"t":"Release tagging","u":"/docs/releases/Release0","h":"#release-tagging","p":3011},{"i":3025,"t":"Updates","u":"/docs/releases/Release0","h":"#updates","p":3011},{"i":3027,"t":"Bug reporting","u":"/docs/releases/Release0","h":"#bug-reporting","p":3011},{"i":3031,"t":"1. ceilometer metering configuration","u":"/docs/operating-scs/metering/meter_configuration","h":"#1-ceilometer-metering-configuration","p":3029},{"i":3033,"t":"1.1 polling.yaml","u":"/docs/operating-scs/metering/meter_configuration","h":"#11-pollingyaml","p":3029},{"i":3035,"t":"1.2 event_definitions.yaml","u":"/docs/operating-scs/metering/meter_configuration","h":"#12-event_definitionsyaml","p":3029},{"i":3037,"t":"1.3 event_pipeline.yaml","u":"/docs/operating-scs/metering/meter_configuration","h":"#13-event_pipelineyaml","p":3029},{"i":3039,"t":"1.4 pipeline.yaml","u":"/docs/operating-scs/metering/meter_configuration","h":"#14-pipelineyaml","p":3029},{"i":3043,"t":"Scope","u":"/docs/releases/Release1","h":"#scope","p":3041},{"i":3045,"t":"CI framework","u":"/docs/releases/Release1","h":"#ci-framework","p":3041},{"i":3046,"t":"Zuul-CI","u":"/docs/releases/Release1","h":"#zuul-ci","p":3041},{"i":3048,"t":"Metrics collection and dashboards","u":"/docs/releases/Release1","h":"#metrics-collection-and-dashboards","p":3041},{"i":3049,"t":"Prometheus exporters and Grafana dashboards","u":"/docs/releases/Release1","h":"#prometheus-exporters-and-grafana-dashboards","p":3041},{"i":3051,"t":"openstack-health-monitor","u":"/docs/releases/Release1","h":"#openstack-health-monitor","p":3041},{"i":3053,"t":"Logging","u":"/docs/releases/Release1","h":"#logging","p":3041},{"i":3054,"t":"Central logging","u":"/docs/releases/Release1","h":"#central-logging","p":3041},{"i":3056,"t":"Federation","u":"/docs/releases/Release1","h":"#federation","p":3041},{"i":3057,"t":"OIDC support via keycloak","u":"/docs/releases/Release1","h":"#oidc-support-via-keycloak","p":3041},{"i":3059,"t":"non-TLS restrictions (testbed)","u":"/docs/releases/Release1","h":"#non-tls-restrictions-testbed","p":3041},{"i":3061,"t":"Known Issue with OIDC Logout","u":"/docs/releases/Release1","h":"#known-issue-with-oidc-logout","p":3041},{"i":3063,"t":"Bare Metal Service","u":"/docs/releases/Release1","h":"#bare-metal-service","p":3041},{"i":3065,"t":"Container Layer","u":"/docs/releases/Release1","h":"#container-layer","p":3041},{"i":3066,"t":"Overview and Goals for R1","u":"/docs/releases/Release1","h":"#overview-and-goals-for-r1","p":3041},{"i":3068,"t":"Beyond CAPI","u":"/docs/releases/Release1","h":"#beyond-capi","p":3041},{"i":3070,"t":"Standardization","u":"/docs/releases/Release1","h":"#standardization","p":3041},{"i":3072,"t":"SBOM and Links","u":"/docs/releases/Release1","h":"#sbom-and-links","p":3041},{"i":3074,"t":"Release tagging","u":"/docs/releases/Release1","h":"#release-tagging","p":3041},{"i":3076,"t":"List of known issues & restrictions in R1","u":"/docs/releases/Release1","h":"#list-of-known-issues--restrictions-in-r1","p":3041},{"i":3080,"t":"Scope","u":"/docs/releases/Release2","h":"#scope","p":3078},{"i":3082,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release2","h":"#component-versions-and-user-visible-improvements-highlights","p":3078},{"i":3084,"t":"New Features (Highlights)","u":"/docs/releases/Release2","h":"#new-features-highlights","p":3078},{"i":3085,"t":"Operator focused improvements","u":"/docs/releases/Release2","h":"#operator-focused-improvements","p":3078},{"i":3087,"t":"SCS Developer focused improvements (testbed)","u":"/docs/releases/Release2","h":"#scs-developer-focused-improvements-testbed","p":3078},{"i":3089,"t":"Upgrade/Migration notes","u":"/docs/releases/Release2","h":"#upgrademigration-notes","p":3078},{"i":3090,"t":"Cluster Management","u":"/docs/releases/Release2","h":"#cluster-management","p":3078},{"i":3092,"t":"OSISM","u":"/docs/releases/Release2","h":"#osism","p":3078},{"i":3094,"t":"Removals","u":"/docs/releases/Release2","h":"#removals","p":3078},{"i":3096,"t":"Deprecations","u":"/docs/releases/Release2","h":"#deprecations","p":3078},{"i":3098,"t":"Security Fixes","u":"/docs/releases/Release2","h":"#security-fixes","p":3078},{"i":3100,"t":"Resolved Issues","u":"/docs/releases/Release2","h":"#resolved-issues","p":3078},{"i":3102,"t":"Standards Conformance","u":"/docs/releases/Release2","h":"#standards-conformance","p":3078},{"i":3104,"t":"Release Tagging","u":"/docs/releases/Release2","h":"#release-tagging","p":3078},{"i":3106,"t":"List of known issues & restrictions in R2","u":"/docs/releases/Release2","h":"#list-of-known-issues--restrictions-in-r2","p":3078},{"i":3107,"t":"Future directions (selected Highlights)","u":"/docs/releases/Release2","h":"#future-directions-selected-highlights","p":3078},{"i":3109,"t":"Contributing","u":"/docs/releases/Release2","h":"#contributing","p":3078},{"i":3113,"t":"Scope","u":"/docs/releases/Release3","h":"#scope","p":3111},{"i":3115,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release3","h":"#component-versions-and-user-visible-improvements-highlights","p":3111},{"i":3117,"t":"New Features (Highlights)","u":"/docs/releases/Release3","h":"#new-features-highlights","p":3111},{"i":3118,"t":"Operator focused improvements","u":"/docs/releases/Release3","h":"#operator-focused-improvements","p":3111},{"i":3120,"t":"SCS Developer focused improvements (testbed and k8s cluster management)","u":"/docs/releases/Release3","h":"#scs-developer-focused-improvements-testbed-and-k8s-cluster-management","p":3111},{"i":3122,"t":"Upgrade/Migration notes","u":"/docs/releases/Release3","h":"#upgrademigration-notes","p":3111},{"i":3123,"t":"Cluster Management","u":"/docs/releases/Release3","h":"#cluster-management","p":3111},{"i":3125,"t":"OSISM","u":"/docs/releases/Release3","h":"#osism","p":3111},{"i":3127,"t":"Removals","u":"/docs/releases/Release3","h":"#removals","p":3111},{"i":3129,"t":"Deprecations","u":"/docs/releases/Release3","h":"#deprecations","p":3111},{"i":3131,"t":"Security Fixes","u":"/docs/releases/Release3","h":"#security-fixes","p":3111},{"i":3133,"t":"Resolved Issues","u":"/docs/releases/Release3","h":"#resolved-issues","p":3111},{"i":3135,"t":"Standards Conformance","u":"/docs/releases/Release3","h":"#standards-conformance","p":3111},{"i":3137,"t":"Release Tagging","u":"/docs/releases/Release3","h":"#release-tagging","p":3111},{"i":3139,"t":"List of known issues & restrictions in R3","u":"/docs/releases/Release3","h":"#list-of-known-issues--restrictions-in-r3","p":3111},{"i":3141,"t":"Contributing","u":"/docs/releases/Release3","h":"#contributing","p":3111},{"i":3143,"t":"Thanks","u":"/docs/releases/Release3","h":"#thanks","p":3111},{"i":3147,"t":"Scope","u":"/docs/releases/Release4","h":"#scope","p":3145},{"i":3149,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release4","h":"#component-versions-and-user-visible-improvements-highlights","p":3145},{"i":3151,"t":"New Features (Highlights)","u":"/docs/releases/Release4","h":"#new-features-highlights","p":3145},{"i":3152,"t":"Operator focused improvements","u":"/docs/releases/Release4","h":"#operator-focused-improvements","p":3145},{"i":3154,"t":"SCS Developer focused improvements (testbed and k8s cluster management)","u":"/docs/releases/Release4","h":"#scs-developer-focused-improvements-testbed-and-k8s-cluster-management","p":3145},{"i":3156,"t":"Upgrade/Migration notes","u":"/docs/releases/Release4","h":"#upgrademigration-notes","p":3145},{"i":3158,"t":"Removals","u":"/docs/releases/Release4","h":"#removals","p":3145},{"i":3160,"t":"Deprecations","u":"/docs/releases/Release4","h":"#deprecations","p":3145},{"i":3161,"t":"Deprecations via OSISM","u":"/docs/releases/Release4","h":"#deprecations-via-osism","p":3145},{"i":3163,"t":"Security Fixes","u":"/docs/releases/Release4","h":"#security-fixes","p":3145},{"i":3165,"t":"Resolved Issues","u":"/docs/releases/Release4","h":"#resolved-issues","p":3145},{"i":3167,"t":"Standards Conformance","u":"/docs/releases/Release4","h":"#standards-conformance","p":3145},{"i":3169,"t":"Release Tagging","u":"/docs/releases/Release4","h":"#release-tagging","p":3145},{"i":3171,"t":"List of known issues & restrictions in R4","u":"/docs/releases/Release4","h":"#list-of-known-issues--restrictions-in-r4","p":3145},{"i":3173,"t":"Contributing","u":"/docs/releases/Release4","h":"#contributing","p":3145},{"i":3175,"t":"Thanks","u":"/docs/releases/Release4","h":"#thanks","p":3145},{"i":3179,"t":"Scope","u":"/docs/releases/Release5","h":"#scope","p":3177},{"i":3181,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release5","h":"#component-versions-and-user-visible-improvements-highlights","p":3177},{"i":3182,"t":"IaaS","u":"/docs/releases/Release5","h":"#iaas","p":3177},{"i":3184,"t":"Container Management","u":"/docs/releases/Release5","h":"#container-management","p":3177},{"i":3186,"t":"Preview: Cluster-Stacks","u":"/docs/releases/Release5","h":"#preview-cluster-stacks","p":3177},{"i":3188,"t":"Operations and IAM related","u":"/docs/releases/Release5","h":"#operations-and-iam-related","p":3177},{"i":3190,"t":"SCS Developer focused improvements (Cloud-in-a-Box, testbed and k8s cluster management)","u":"/docs/releases/Release5","h":"#scs-developer-focused-improvements-cloud-in-a-box-testbed-and-k8s-cluster-management","p":3177},{"i":3192,"t":"Project Infrastructure","u":"/docs/releases/Release5","h":"#project-infrastructure","p":3177},{"i":3194,"t":"Upgrade/Migration notes","u":"/docs/releases/Release5","h":"#upgrademigration-notes","p":3177},{"i":3196,"t":"Removals","u":"/docs/releases/Release5","h":"#removals","p":3177},{"i":3198,"t":"Deprecations","u":"/docs/releases/Release5","h":"#deprecations","p":3177},{"i":3199,"t":"Deprecations via OSISM","u":"/docs/releases/Release5","h":"#deprecations-via-osism","p":3177},{"i":3201,"t":"Security Fixes","u":"/docs/releases/Release5","h":"#security-fixes","p":3177},{"i":3203,"t":"Resolved Issues","u":"/docs/releases/Release5","h":"#resolved-issues","p":3177},{"i":3205,"t":"Standards Conformance","u":"/docs/releases/Release5","h":"#standards-conformance","p":3177},{"i":3207,"t":"Release Tagging","u":"/docs/releases/Release5","h":"#release-tagging","p":3177},{"i":3209,"t":"List of known issues & restrictions in R5","u":"/docs/releases/Release5","h":"#list-of-known-issues--restrictions-in-r5","p":3177},{"i":3211,"t":"Contributing","u":"/docs/releases/Release5","h":"#contributing","p":3177},{"i":3213,"t":"Thanks","u":"/docs/releases/Release5","h":"#thanks","p":3177},{"i":3217,"t":"Scope","u":"/docs/releases/Release6","h":"#scope","p":3215},{"i":3219,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release6","h":"#component-versions-and-user-visible-improvements-highlights","p":3215},{"i":3220,"t":"IaaS","u":"/docs/releases/Release6","h":"#iaas","p":3215},{"i":3222,"t":"KaaS","u":"/docs/releases/Release6","h":"#kaas","p":3215},{"i":3224,"t":"Operations","u":"/docs/releases/Release6","h":"#operations","p":3215},{"i":3226,"t":"IAM","u":"/docs/releases/Release6","h":"#iam","p":3215},{"i":3228,"t":"New Features (Highlights)","u":"/docs/releases/Release6","h":"#new-features-highlights","p":3215},{"i":3229,"t":"Operator focused improvements","u":"/docs/releases/Release6","h":"#operator-focused-improvements","p":3215},{"i":3231,"t":"SCS Developer focused improvements (testbed and k8s cluster management)","u":"/docs/releases/Release6","h":"#scs-developer-focused-improvements-testbed-and-k8s-cluster-management","p":3215},{"i":3233,"t":"Preview: Domain Manager Persona","u":"/docs/releases/Release6","h":"#preview-domain-manager-persona","p":3215},{"i":3235,"t":"Preview: Central API","u":"/docs/releases/Release6","h":"#preview-central-api","p":3215},{"i":3237,"t":"Preview: Keycloak Home-IdP-discovery","u":"/docs/releases/Release6","h":"#preview-keycloak-home-idp-discovery","p":3215},{"i":3239,"t":"Upgrade/Migration notes","u":"/docs/releases/Release6","h":"#upgrademigration-notes","p":3215},{"i":3241,"t":"Removals","u":"/docs/releases/Release6","h":"#removals","p":3215},{"i":3243,"t":"Deprecations","u":"/docs/releases/Release6","h":"#deprecations","p":3215},{"i":3245,"t":"Security Fixes","u":"/docs/releases/Release6","h":"#security-fixes","p":3215},{"i":3247,"t":"Security assessment for IaaS","u":"/docs/releases/Release6","h":"#security-assessment-for-iaas","p":3215},{"i":3249,"t":"Resolved Issues","u":"/docs/releases/Release6","h":"#resolved-issues","p":3215},{"i":3250,"t":"Preview: proper scope filtering for domain list API","u":"/docs/releases/Release6","h":"#preview-proper-scope-filtering-for-domain-list-api","p":3215},{"i":3252,"t":"Documentation","u":"/docs/releases/Release6","h":"#documentation","p":3215},{"i":3254,"t":"Highlighted blog posts","u":"/docs/releases/Release6","h":"#highlighted-blog-posts","p":3215},{"i":3256,"t":"IAM","u":"/docs/releases/Release6","h":"#iam-1","p":3215},{"i":3258,"t":"Standards Conformance","u":"/docs/releases/Release6","h":"#standards-conformance","p":3215},{"i":3260,"t":"Release Tagging","u":"/docs/releases/Release6","h":"#release-tagging","p":3215},{"i":3262,"t":"List of known issues & restrictions in R6","u":"/docs/releases/Release6","h":"#list-of-known-issues--restrictions-in-r6","p":3215},{"i":3263,"t":"IaaS","u":"/docs/releases/Release6","h":"#iaas-1","p":3215},{"i":3265,"t":"KaaS","u":"/docs/releases/Release6","h":"#kaas-2","p":3215},{"i":3267,"t":"IAM","u":"/docs/releases/Release6","h":"#iam-2","p":3215},{"i":3269,"t":"Contributing","u":"/docs/releases/Release6","h":"#contributing","p":3215},{"i":3271,"t":"Thanks","u":"/docs/releases/Release6","h":"#thanks","p":3215},{"i":3275,"t":"Scope","u":"/docs/releases/Release7","h":"#scope","p":3273},{"i":3277,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release7","h":"#component-versions-and-user-visible-improvements-highlights","p":3273},{"i":3278,"t":"IaaS","u":"/docs/releases/Release7","h":"#iaas","p":3273},{"i":3280,"t":"KaaS","u":"/docs/releases/Release7","h":"#kaas","p":3273},{"i":3282,"t":"New Features (Highlights)","u":"/docs/releases/Release7","h":"#new-features-highlights","p":3273},{"i":3283,"t":"Operator focused improvements","u":"/docs/releases/Release7","h":"#operator-focused-improvements","p":3273},{"i":3284,"t":"IaaS","u":"/docs/releases/Release7","h":"#iaas-1","p":3273},{"i":3286,"t":"SCS Developer focused improvements (testbed and k8s cluster management)","u":"/docs/releases/Release7","h":"#scs-developer-focused-improvements-testbed-and-k8s-cluster-management","p":3273},{"i":3287,"t":"Tech Preview: Central API","u":"/docs/releases/Release7","h":"#tech-preview-central-api","p":3273},{"i":3289,"t":"Tech Preview: Automated pentesting for IaaS and KaaS","u":"/docs/releases/Release7","h":"#tech-preview-automated-pentesting-for-iaas-and-kaas","p":3273},{"i":3291,"t":"Tech Preview: SCS Health Monitor","u":"/docs/releases/Release7","h":"#tech-preview-scs-health-monitor","p":3273},{"i":3293,"t":"Status Page: 1.0 Full Release","u":"/docs/releases/Release7","h":"#status-page-10-full-release","p":3273},{"i":3295,"t":"KaaS","u":"/docs/releases/Release7","h":"#kaas-1","p":3273},{"i":3297,"t":"IAM","u":"/docs/releases/Release7","h":"#iam","p":3273},{"i":3299,"t":"Upgrade/Migration notes","u":"/docs/releases/Release7","h":"#upgrademigration-notes","p":3273},{"i":3301,"t":"Removals","u":"/docs/releases/Release7","h":"#removals","p":3273},{"i":3303,"t":"Deprecations","u":"/docs/releases/Release7","h":"#deprecations","p":3273},{"i":3305,"t":"Security Fixes","u":"/docs/releases/Release7","h":"#security-fixes","p":3273},{"i":3307,"t":"Standards Conformance","u":"/docs/releases/Release7","h":"#standards-conformance","p":3273},{"i":3309,"t":"Release Tagging","u":"/docs/releases/Release7","h":"#release-tagging","p":3273},{"i":3311,"t":"List of known issues & restrictions in R7","u":"/docs/releases/Release7","h":"#list-of-known-issues--restrictions-in-r7","p":3273},{"i":3312,"t":"IAM","u":"/docs/releases/Release7","h":"#iam-1","p":3273},{"i":3314,"t":"KaaS","u":"/docs/releases/Release7","h":"#kaas-2","p":3273},{"i":3316,"t":"OVN Loadbalancers","u":"/docs/releases/Release7","h":"#ovn-loadbalancers","p":3273},{"i":3318,"t":"Contributing","u":"/docs/releases/Release7","h":"#contributing","p":3273},{"i":3320,"t":"On to R8 ...","u":"/docs/releases/Release7","h":"#on-to-r8-","p":3273},{"i":3322,"t":"Thanks","u":"/docs/releases/Release7","h":"#thanks","p":3273},{"i":3326,"t":"Scope","u":"/docs/releases/ReleaseX","h":"#scope","p":3324},{"i":3327,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/ReleaseX","h":"#component-versions-and-user-visible-improvements-highlights","p":3324},{"i":3328,"t":"New Features (Highlights)","u":"/docs/releases/ReleaseX","h":"#new-features-highlights","p":3324},{"i":3329,"t":"Operator focused improvements","u":"/docs/releases/ReleaseX","h":"#operator-focused-improvements","p":3324},{"i":3330,"t":"SCS Developer focused improvements (testbed and k8s cluster management)","u":"/docs/releases/ReleaseX","h":"#scs-developer-focused-improvements-testbed-and-k8s-cluster-management","p":3324},{"i":3331,"t":"Upgrade/Migration notes","u":"/docs/releases/ReleaseX","h":"#upgrademigration-notes","p":3324},{"i":3332,"t":"Removals","u":"/docs/releases/ReleaseX","h":"#removals","p":3324},{"i":3333,"t":"Deprecations","u":"/docs/releases/ReleaseX","h":"#deprecations","p":3324},{"i":3334,"t":"Security Fixes","u":"/docs/releases/ReleaseX","h":"#security-fixes","p":3324},{"i":3335,"t":"Resolved Issues","u":"/docs/releases/ReleaseX","h":"#resolved-issues","p":3324},{"i":3336,"t":"Standards Conformance","u":"/docs/releases/ReleaseX","h":"#standards-conformance","p":3324},{"i":3337,"t":"Release Tagging","u":"/docs/releases/ReleaseX","h":"#release-tagging","p":3324},{"i":3338,"t":"List of known issues & restrictions in RX","u":"/docs/releases/ReleaseX","h":"#list-of-known-issues--restrictions-in-rx","p":3324},{"i":3339,"t":"Contributing","u":"/docs/releases/ReleaseX","h":"#contributing","p":3324},{"i":3341,"t":"Thanks","u":"/docs/releases/ReleaseX","h":"#thanks","p":3324},{"i":3343,"t":"General information","u":"/docs/turnkey-solution/hardware-landscape","h":"#general-information","p":3342},{"i":3345,"t":"Tasks and Objectives","u":"/docs/turnkey-solution/hardware-landscape","h":"#tasks-and-objectives","p":3342},{"i":3347,"t":"Installation details","u":"/docs/turnkey-solution/hardware-landscape","h":"#installation-details","p":3342},{"i":3349,"t":"Available documentation","u":"/docs/turnkey-solution/hardware-landscape","h":"#available-documentation","p":3342},{"i":3351,"t":"Specific installation and configuration details","u":"/docs/turnkey-solution/hardware-landscape","h":"#specific-installation-and-configuration-details","p":3342},{"i":3354,"t":"Scope of this document","u":"/docs/turnkey-solution/overview","h":"#scope-of-this-document","p":3353},{"i":3356,"t":"Overview table","u":"/docs/turnkey-solution/overview","h":"#overview-table","p":3353},{"i":3364,"t":"Becoming certified","u":"/standards/certification/overview","h":"#becoming-certified","p":3362},{"i":3366,"t":"Compliant cloud environments","u":"/standards/certification/overview","h":"#compliant-cloud-environments","p":3362},{"i":3370,"t":"Becoming certified","u":"/standards/certification/overview.template","h":"#becoming-certified","p":3368},{"i":3372,"t":"Compliant cloud environments","u":"/standards/certification/overview.template","h":"#compliant-cloud-environments","p":3368},{"i":3376,"t":"Common requirements for the compliance checks","u":"/standards/certification/pipeline","h":"#common-requirements-for-the-compliance-checks","p":3374},{"i":3377,"t":"for SCS-compatible IaaS","u":"/standards/certification/pipeline","h":"#for-scs-compatible-iaas","p":3374},{"i":3379,"t":"How to add a new test subject to the official pipeline","u":"/standards/certification/pipeline","h":"#how-to-add-a-new-test-subject-to-the-official-pipeline","p":3374},{"i":3380,"t":"for SCS-compatible IaaS","u":"/standards/certification/pipeline","h":"#for-scs-compatible-iaas-1","p":3374},{"i":3382,"t":"How to feed the compliance monitor yourself","u":"/standards/certification/pipeline","h":"#how-to-feed-the-compliance-monitor-yourself","p":3374},{"i":3383,"t":"for SCS-compatible IaaS","u":"/standards/certification/pipeline","h":"#for-scs-compatible-iaas-2","p":3374},{"i":3403,"t":"Supplement: Implementation and Testing Notes","u":"/standards/iaas/scs-0100","h":"#supplement-implementation-and-testing-notes","p":3401},{"i":3407,"t":"Supplement: Implementation and Testing Notes","u":"/standards/iaas/scs-0101","h":"#supplement-implementation-and-testing-notes","p":3405},{"i":3411,"t":"Supplement: Implementation and Testing Notes","u":"/standards/iaas/scs-0102","h":"#supplement-implementation-and-testing-notes","p":3409},{"i":3415,"t":"Supplement: Implementation Notes","u":"/standards/iaas/scs-0104","h":"#supplement-implementation-notes","p":3413},{"i":3433,"t":"Supplement: Examples of Failure Cases and their impact on IaaS and KaaS resources","u":"/standards/iaas/scs-0118","h":"#supplement-examples-of-failure-cases-and-their-impact-on-iaas-and-kaas-resources","p":3431},{"i":3439,"t":"Supplement: Implementation and Testing Notes","u":"/standards/iaas/scs-0116","h":"#supplement-implementation-and-testing-notes","p":3437},{"i":3447,"t":"Supplement: Implementation and Testing Notes","u":"/standards/iaas/scs-0121","h":"#supplement-implementation-and-testing-notes","p":3445},{"i":3455,"t":"Supplement: SCS Standard for the security of IaaS service software: Implementation and Testing Notes","u":"/standards/iaas/scs-0124","h":"#supplement-scs-standard-for-the-security-of-iaas-service-software-implementation-and-testing-notes","p":3453},{"i":3463,"t":"Supplement: Domain Manager implementation notes","u":"/standards/iam/scs-0302","h":"#supplement-domain-manager-implementation-notes","p":3461},{"i":3475,"t":"Supplement: Implementation and Testing Notes","u":"/standards/kaas/scs-0211","h":"#supplement-implementation-and-testing-notes","p":3473},{"i":3479,"t":"Supplement: Implementation and Testing Notes","u":"/standards/kaas/scs-0210","h":"#supplement-implementation-and-testing-notes","p":3477},{"i":3487,"t":"Supplement: Implementation and Testing Notes","u":"/standards/kaas/scs-0214","h":"#supplement-implementation-and-testing-notes","p":3485},{"i":3497,"t":"Supplement: Implementation Notes","u":"/standards/kaas/scs-0219","h":"#supplement-implementation-notes","p":3495},{"i":3518,"t":"Introduction","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#introduction","p":3517},{"i":3520,"t":"Requirements","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#requirements","p":3517},{"i":3522,"t":"Sovereign Cloud Standard documents","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#sovereign-cloud-standard-documents","p":3517},{"i":3524,"t":"Types of documents","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#types-of-documents","p":3517},{"i":3526,"t":"Document format","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#document-format","p":3517},{"i":3528,"t":"Sections","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#sections","p":3517},{"i":3530,"t":"Process","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#process","p":3517},{"i":3532,"t":"Proposal phase","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#proposal-phase","p":3517},{"i":3534,"t":"Development phase (Draft)","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#development-phase-draft","p":3517},{"i":3536,"t":"Stabilized phase (Stable)","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#stabilized-phase-stable","p":3517},{"i":3538,"t":"Deprecation phase (Deprecated)","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#deprecation-phase-deprecated","p":3517},{"i":3540,"t":"Rejection","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#rejection","p":3517},{"i":3542,"t":"Open Questions","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#open-questions","p":3517},{"i":3543,"t":"Stabilization criteria","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#stabilization-criteria","p":3517},{"i":3545,"t":"Breaking change criteria","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#breaking-change-criteria","p":3517},{"i":3547,"t":"Design Considerations","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#design-considerations","p":3517},{"i":3548,"t":"Versioning","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#versioning","p":3517},{"i":3550,"t":"Acknowledgements","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#acknowledgements","p":3517},{"i":3553,"t":"Introduction","u":"/standards/scs-0002-v1-standards-docs-org","h":"#introduction","p":3552},{"i":3555,"t":"Motivation","u":"/standards/scs-0002-v1-standards-docs-org","h":"#motivation","p":3552},{"i":3557,"t":"Suggested cleanup (step 1)","u":"/standards/scs-0002-v1-standards-docs-org","h":"#suggested-cleanup-step-1","p":3552},{"i":3560,"t":"Introduction","u":"/standards/scs-0002-v2-standards-docs-org","h":"#introduction","p":3559},{"i":3562,"t":"Motivation","u":"/standards/scs-0002-v2-standards-docs-org","h":"#motivation","p":3559},{"i":3564,"t":"Distributed Documentation","u":"/standards/scs-0002-v2-standards-docs-org","h":"#distributed-documentation","p":3559},{"i":3566,"t":"Methodology and Taxonomy","u":"/standards/scs-0002-v2-standards-docs-org","h":"#methodology-and-taxonomy","p":3559},{"i":3568,"t":"Structure Template","u":"/standards/scs-0002-v2-standards-docs-org","h":"#structure-template","p":3559},{"i":3570,"t":"Single Component/Component","u":"/standards/scs-0002-v2-standards-docs-org","h":"#single-componentcomponent","p":3559},{"i":3572,"t":"Technical Implementation","u":"/standards/scs-0002-v2-standards-docs-org","h":"#technical-implementation","p":3559},{"i":3574,"t":"Writing Style and Format – Style Guide","u":"/standards/scs-0002-v2-standards-docs-org","h":"#writing-style-and-format--style-guide","p":3559},{"i":3576,"t":"Open Questions","u":"/standards/scs-0002-v2-standards-docs-org","h":"#open-questions","p":3559},{"i":3578,"t":"Reference","u":"/standards/scs-0002-v2-standards-docs-org","h":"#reference","p":3559},{"i":3581,"t":"Introduction","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#introduction","p":3580},{"i":3583,"t":"Motivation","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#motivation","p":3580},{"i":3585,"t":"Overview of mandatory SCS standards","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#overview-of-mandatory-scs-standards","p":3580},{"i":3587,"t":"Lifecycle of certificate scopes","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#lifecycle-of-certificate-scopes","p":3580},{"i":3589,"t":"Machine-readability for further processing","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#machine-readability-for-further-processing","p":3580},{"i":3591,"t":"Basic concepts","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#basic-concepts","p":3580},{"i":3593,"t":"SCS Certification YAML","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#scs-certification-yaml","p":3580},{"i":3595,"t":"Prerequisite descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#prerequisite-descriptor","p":3580},{"i":3597,"t":"Version descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#version-descriptor","p":3580},{"i":3599,"t":"Module descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#module-descriptor","p":3580},{"i":3601,"t":"Check descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#check-descriptor","p":3580},{"i":3603,"t":"Test-case descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#test-case-descriptor","p":3580},{"i":3605,"t":"Timeline entry","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#timeline-entry","p":3580},{"i":3607,"t":"Process","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#process","p":3580},{"i":3609,"t":"Design Considerations","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#design-considerations","p":3580},{"i":3610,"t":"File format","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#file-format","p":3580},{"i":3612,"t":"Dependency graph for certifications","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#dependency-graph-for-certifications","p":3580},{"i":3614,"t":"Tooling","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#tooling","p":3580},{"i":3616,"t":"Open Questions","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#open-questions","p":3580},{"i":3617,"t":"Acknowledgements","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#acknowledgements","p":3580},{"i":3620,"t":"Introduction","u":"/standards/scs-0005-v1-project-governance","h":"#introduction","p":3619},{"i":3622,"t":"Role of the SCS Project Board","u":"/standards/scs-0005-v1-project-governance","h":"#role-of-the-scs-project-board","p":3619},{"i":3624,"t":"Definitions","u":"/standards/scs-0005-v1-project-governance","h":"#definitions","p":3619},{"i":3626,"t":"Roles in the SCS GitHub Organization","u":"/standards/scs-0005-v1-project-governance","h":"#roles-in-the-scs-github-organization","p":3619},{"i":3628,"t":"Joining the SCS GitHub Organization","u":"/standards/scs-0005-v1-project-governance","h":"#joining-the-scs-github-organization","p":3619},{"i":3630,"t":"Election of the SCS Project Board","u":"/standards/scs-0005-v1-project-governance","h":"#election-of-the-scs-project-board","p":3619},{"i":3631,"t":"Term","u":"/standards/scs-0005-v1-project-governance","h":"#term","p":3619},{"i":3633,"t":"Seats on the board","u":"/standards/scs-0005-v1-project-governance","h":"#seats-on-the-board","p":3619},{"i":3635,"t":"Nominations","u":"/standards/scs-0005-v1-project-governance","h":"#nominations","p":3619},{"i":3637,"t":"Eligible for voting","u":"/standards/scs-0005-v1-project-governance","h":"#eligible-for-voting","p":3619},{"i":3639,"t":"Electoral management","u":"/standards/scs-0005-v1-project-governance","h":"#electoral-management","p":3619},{"i":3641,"t":"Voting period","u":"/standards/scs-0005-v1-project-governance","h":"#voting-period","p":3619},{"i":3643,"t":"Announcement","u":"/standards/scs-0005-v1-project-governance","h":"#announcement","p":3619},{"i":3645,"t":"Mechanisms","u":"/standards/scs-0005-v1-project-governance","h":"#mechanisms","p":3619},{"i":3647,"t":"Roles in the SCS Project Board","u":"/standards/scs-0005-v1-project-governance","h":"#roles-in-the-scs-project-board","p":3619},{"i":3650,"t":"Introduction","u":"/standards/scs-0100-v1-flavor-naming","h":"#introduction","p":3649},{"i":3652,"t":"Motivation","u":"/standards/scs-0100-v1-flavor-naming","h":"#motivation","p":3649},{"i":3654,"t":"Proposal","u":"/standards/scs-0100-v1-flavor-naming","h":"#proposal","p":3649},{"i":3655,"t":"Type of information included","u":"/standards/scs-0100-v1-flavor-naming","h":"#type-of-information-included","p":3649},{"i":3657,"t":"Complete Proposal","u":"/standards/scs-0100-v1-flavor-naming","h":"#complete-proposal","p":3649},{"i":3659,"t":"Proposal Details","u":"/standards/scs-0100-v1-flavor-naming","h":"#proposal-details","p":3649},{"i":3660,"t":"[REQUIRED] CPU Suffixes","u":"/standards/scs-0100-v1-flavor-naming","h":"#required-cpu-suffixes","p":3649},{"i":3662,"t":"[REQUIRED] Memory","u":"/standards/scs-0100-v1-flavor-naming","h":"#required-memory","p":3649},{"i":3664,"t":"[OPTIONAL] Disk sizes and types","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-disk-sizes-and-types","p":3649},{"i":3666,"t":"[OPTIONAL] Hypervisor","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-hypervisor","p":3649},{"i":3668,"t":"[OPTIONAL] Hardware virtualization / Nested virtualization","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-hardware-virtualization--nested-virtualization","p":3649},{"i":3670,"t":"[OPTIONAL] CPU Architecture Details","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-cpu-architecture-details","p":3649},{"i":3672,"t":"[OPTIONAL] Extra features","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-extra-features","p":3649},{"i":3674,"t":"Proposal Examples","u":"/standards/scs-0100-v1-flavor-naming","h":"#proposal-examples","p":3649},{"i":3676,"t":"Standard SCS flavors","u":"/standards/scs-0100-v1-flavor-naming","h":"#standard-scs-flavors","p":3649},{"i":3678,"t":"Naming policies","u":"/standards/scs-0100-v1-flavor-naming","h":"#naming-policies","p":3649},{"i":3680,"t":"Rationale","u":"/standards/scs-0100-v1-flavor-naming","h":"#rationale","p":3649},{"i":3682,"t":"Validation","u":"/standards/scs-0100-v1-flavor-naming","h":"#validation","p":3649},{"i":3684,"t":"Beyond SCS: Gaia-X","u":"/standards/scs-0100-v1-flavor-naming","h":"#beyond-scs-gaia-x","p":3649},{"i":3687,"t":"Introduction","u":"/standards/scs-0100-v3-flavor-naming","h":"#introduction","p":3686},{"i":3689,"t":"Motivation","u":"/standards/scs-0100-v3-flavor-naming","h":"#motivation","p":3686},{"i":3691,"t":"Design Considerations","u":"/standards/scs-0100-v3-flavor-naming","h":"#design-considerations","p":3686},{"i":3692,"t":"Type of information included","u":"/standards/scs-0100-v3-flavor-naming","h":"#type-of-information-included","p":3686},{"i":3694,"t":"Complete Proposal for systematic flavor naming","u":"/standards/scs-0100-v3-flavor-naming","h":"#complete-proposal-for-systematic-flavor-naming","p":3686},{"i":3696,"t":"Proposal Details","u":"/standards/scs-0100-v3-flavor-naming","h":"#proposal-details","p":3686},{"i":3697,"t":"[REQUIRED] CPU Suffixes","u":"/standards/scs-0100-v3-flavor-naming","h":"#required-cpu-suffixes","p":3686},{"i":3699,"t":"[REQUIRED] Memory","u":"/standards/scs-0100-v3-flavor-naming","h":"#required-memory","p":3686},{"i":3701,"t":"[OPTIONAL] Disk sizes and types","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-disk-sizes-and-types","p":3686},{"i":3703,"t":"Naming policy compliance","u":"/standards/scs-0100-v3-flavor-naming","h":"#naming-policy-compliance","p":3686},{"i":3705,"t":"Extensions","u":"/standards/scs-0100-v3-flavor-naming","h":"#extensions","p":3686},{"i":3707,"t":"[OPTIONAL] Hypervisor","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-hypervisor","p":3686},{"i":3709,"t":"[OPTIONAL] Hardware virtualization / Nested virtualization","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-hardware-virtualization--nested-virtualization","p":3686},{"i":3711,"t":"[OPTIONAL] CPU Architecture Details","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-cpu-architecture-details","p":3686},{"i":3713,"t":"[OPTIONAL] GPU support","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-gpu-support","p":3686},{"i":3715,"t":"[OPTIONAL] Infiniband","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-infiniband","p":3686},{"i":3717,"t":"Naming options advice","u":"/standards/scs-0100-v3-flavor-naming","h":"#naming-options-advice","p":3686},{"i":3719,"t":"Proposal Examples","u":"/standards/scs-0100-v3-flavor-naming","h":"#proposal-examples","p":3686},{"i":3721,"t":"Previous standard versions","u":"/standards/scs-0100-v3-flavor-naming","h":"#previous-standard-versions","p":3686},{"i":3723,"t":"Beyond SCS","u":"/standards/scs-0100-v3-flavor-naming","h":"#beyond-scs","p":3686},{"i":3726,"t":"Introduction","u":"/standards/scs-0004-v1-achieving-certification","h":"#introduction","p":3725},{"i":3728,"t":"Motivation","u":"/standards/scs-0004-v1-achieving-certification","h":"#motivation","p":3725},{"i":3730,"t":"Regulations","u":"/standards/scs-0004-v1-achieving-certification","h":"#regulations","p":3725},{"i":3732,"t":"Design Considerations","u":"/standards/scs-0004-v1-achieving-certification","h":"#design-considerations","p":3725},{"i":3733,"t":"Open Questions","u":"/standards/scs-0004-v1-achieving-certification","h":"#open-questions","p":3725},{"i":3734,"t":"Related Documents","u":"/standards/scs-0004-v1-achieving-certification","h":"#related-documents","p":3725},{"i":3737,"t":"Introduction","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#introduction","p":3736},{"i":3739,"t":"Implementation notes","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#implementation-notes","p":3736},{"i":3741,"t":"Operational tooling","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#operational-tooling","p":3736},{"i":3743,"t":"GPU table","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#gpu-table","p":3736},{"i":3745,"t":"Automated tests","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#automated-tests","p":3736},{"i":3746,"t":"Errors","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#errors","p":3736},{"i":3748,"t":"Warnings","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#warnings","p":3736},{"i":3750,"t":"Implementation","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#implementation","p":3736},{"i":3752,"t":"Manual tests","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#manual-tests","p":3736},{"i":3755,"t":"Introduction","u":"/standards/scs-0101-v1-entropy","h":"#introduction","p":3754},{"i":3756,"t":"Entropy in information technology","u":"/standards/scs-0101-v1-entropy","h":"#entropy-in-information-technology","p":3754},{"i":3758,"t":"Real-world uses of entropy","u":"/standards/scs-0101-v1-entropy","h":"#real-world-uses-of-entropy","p":3754},{"i":3760,"t":"Sources of entropy","u":"/standards/scs-0101-v1-entropy","h":"#sources-of-entropy","p":3754},{"i":3762,"t":"Entropy in virtual instances","u":"/standards/scs-0101-v1-entropy","h":"#entropy-in-virtual-instances","p":3754},{"i":3764,"t":"Motivation","u":"/standards/scs-0101-v1-entropy","h":"#motivation","p":3754},{"i":3766,"t":"Entropy in SCS clouds","u":"/standards/scs-0101-v1-entropy","h":"#entropy-in-scs-clouds","p":3754},{"i":3767,"t":"Flavors","u":"/standards/scs-0101-v1-entropy","h":"#flavors","p":3754},{"i":3769,"t":"Images","u":"/standards/scs-0101-v1-entropy","h":"#images","p":3754},{"i":3771,"t":"Compute nodes","u":"/standards/scs-0101-v1-entropy","h":"#compute-nodes","p":3754},{"i":3774,"t":"Introduction","u":"/standards/scs-0100-v2-flavor-naming","h":"#introduction","p":3773},{"i":3776,"t":"Motivation","u":"/standards/scs-0100-v2-flavor-naming","h":"#motivation","p":3773},{"i":3778,"t":"Design Considerations","u":"/standards/scs-0100-v2-flavor-naming","h":"#design-considerations","p":3773},{"i":3779,"t":"Type of information included","u":"/standards/scs-0100-v2-flavor-naming","h":"#type-of-information-included","p":3773},{"i":3781,"t":"Complete Proposal for systematic flavor naming","u":"/standards/scs-0100-v2-flavor-naming","h":"#complete-proposal-for-systematic-flavor-naming","p":3773},{"i":3783,"t":"Proposal Details","u":"/standards/scs-0100-v2-flavor-naming","h":"#proposal-details","p":3773},{"i":3784,"t":"[REQUIRED] CPU Suffixes","u":"/standards/scs-0100-v2-flavor-naming","h":"#required-cpu-suffixes","p":3773},{"i":3786,"t":"[REQUIRED] Memory","u":"/standards/scs-0100-v2-flavor-naming","h":"#required-memory","p":3773},{"i":3788,"t":"[OPTIONAL] Disk sizes and types","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-disk-sizes-and-types","p":3773},{"i":3790,"t":"Standard SCS flavors","u":"/standards/scs-0100-v2-flavor-naming","h":"#standard-scs-flavors","p":3773},{"i":3792,"t":"Naming policy compliance","u":"/standards/scs-0100-v2-flavor-naming","h":"#naming-policy-compliance","p":3773},{"i":3794,"t":"Validation","u":"/standards/scs-0100-v2-flavor-naming","h":"#validation","p":3773},{"i":3796,"t":"Operational tooling","u":"/standards/scs-0100-v2-flavor-naming","h":"#operational-tooling","p":3773},{"i":3798,"t":"Extensions","u":"/standards/scs-0100-v2-flavor-naming","h":"#extensions","p":3773},{"i":3800,"t":"[OPTIONAL] Hypervisor","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-hypervisor","p":3773},{"i":3802,"t":"[OPTIONAL] Hardware virtualization / Nested virtualization","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-hardware-virtualization--nested-virtualization","p":3773},{"i":3804,"t":"[OPTIONAL] CPU Architecture Details","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-cpu-architecture-details","p":3773},{"i":3806,"t":"[OPTIONAL] GPU support","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-gpu-support","p":3773},{"i":3808,"t":"[OPTIONAL] Infiniband","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-infiniband","p":3773},{"i":3810,"t":"Naming options advice","u":"/standards/scs-0100-v2-flavor-naming","h":"#naming-options-advice","p":3773},{"i":3812,"t":"Proposal Examples","u":"/standards/scs-0100-v2-flavor-naming","h":"#proposal-examples","p":3773},{"i":3814,"t":"Previous standard versions","u":"/standards/scs-0100-v2-flavor-naming","h":"#previous-standard-versions","p":3773},{"i":3816,"t":"Beyond SCS","u":"/standards/scs-0100-v2-flavor-naming","h":"#beyond-scs","p":3773},{"i":3819,"t":"Motivation","u":"/standards/scs-0102-v1-image-metadata","h":"#motivation","p":3818},{"i":3821,"t":"Overview","u":"/standards/scs-0102-v1-image-metadata","h":"#overview","p":3818},{"i":3823,"t":"Naming","u":"/standards/scs-0102-v1-image-metadata","h":"#naming","p":3818},{"i":3825,"t":"Technical requirements and features","u":"/standards/scs-0102-v1-image-metadata","h":"#technical-requirements-and-features","p":3818},{"i":3827,"t":"Image handling","u":"/standards/scs-0102-v1-image-metadata","h":"#image-handling","p":3818},{"i":3828,"t":"Image updating","u":"/standards/scs-0102-v1-image-metadata","h":"#image-updating","p":3818},{"i":3830,"t":"Image Origin","u":"/standards/scs-0102-v1-image-metadata","h":"#image-origin","p":3818},{"i":3832,"t":"Image build info","u":"/standards/scs-0102-v1-image-metadata","h":"#image-build-info","p":3818},{"i":3834,"t":"Licensing / Maintenance subscription / Support","u":"/standards/scs-0102-v1-image-metadata","h":"#licensing--maintenance-subscription--support","p":3818},{"i":3836,"t":"Conformance Tests","u":"/standards/scs-0102-v1-image-metadata","h":"#conformance-tests","p":3818},{"i":3839,"t":"Implementation notes","u":"/standards/scs-0102-w1-image-metadata-implementation-testing","h":"#implementation-notes","p":3838},{"i":3841,"t":"Automated tests","u":"/standards/scs-0102-w1-image-metadata-implementation-testing","h":"#automated-tests","p":3838},{"i":3842,"t":"Images sample","u":"/standards/scs-0102-w1-image-metadata-implementation-testing","h":"#images-sample","p":3838},{"i":3844,"t":"Implementation","u":"/standards/scs-0102-w1-image-metadata-implementation-testing","h":"#implementation","p":3838},{"i":3846,"t":"Manual tests","u":"/standards/scs-0102-w1-image-metadata-implementation-testing","h":"#manual-tests","p":3838},{"i":3849,"t":"Implementation notes","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#implementation-notes","p":3848},{"i":3851,"t":"Automated tests","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#automated-tests","p":3848},{"i":3852,"t":"Images sample","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#images-sample","p":3848},{"i":3854,"t":"Errors","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#errors","p":3848},{"i":3856,"t":"Warnings","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#warnings","p":3848},{"i":3858,"t":"Implementation","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#implementation","p":3848},{"i":3860,"t":"Manual tests","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#manual-tests","p":3848},{"i":3863,"t":"Introduction","u":"/standards/scs-0104-v1-standard-images","h":"#introduction","p":3862},{"i":3865,"t":"Motivation","u":"/standards/scs-0104-v1-standard-images","h":"#motivation","p":3862},{"i":3867,"t":"Uploading custom images","u":"/standards/scs-0104-v1-standard-images","h":"#uploading-custom-images","p":3862},{"i":3869,"t":"Standard images YAML","u":"/standards/scs-0104-v1-standard-images","h":"#standard-images-yaml","p":3862},{"i":3871,"t":"Image specification, single image","u":"/standards/scs-0104-v1-standard-images","h":"#image-specification-single-image","p":3862},{"i":3873,"t":"Image specification, class of images","u":"/standards/scs-0104-v1-standard-images","h":"#image-specification-class-of-images","p":3862},{"i":3875,"t":"Full example","u":"/standards/scs-0104-v1-standard-images","h":"#full-example","p":3862},{"i":3877,"t":"Lifecycle considerations","u":"/standards/scs-0104-v1-standard-images","h":"#lifecycle-considerations","p":3862},{"i":3878,"t":"YAML lifecycle","u":"/standards/scs-0104-v1-standard-images","h":"#yaml-lifecycle","p":3862},{"i":3880,"t":"Image lifecycle","u":"/standards/scs-0104-v1-standard-images","h":"#image-lifecycle","p":3862},{"i":3882,"t":"Conformance Tests","u":"/standards/scs-0104-v1-standard-images","h":"#conformance-tests","p":3862},{"i":3884,"t":"Operational tooling","u":"/standards/scs-0104-v1-standard-images","h":"#operational-tooling","p":3862},{"i":3887,"t":"Introduction","u":"/standards/scs-0103-v1-standard-flavors","h":"#introduction","p":3886},{"i":3889,"t":"Terminology","u":"/standards/scs-0103-v1-standard-flavors","h":"#terminology","p":3886},{"i":3891,"t":"Motivation","u":"/standards/scs-0103-v1-standard-flavors","h":"#motivation","p":3886},{"i":3893,"t":"Properties (extra_specs)","u":"/standards/scs-0103-v1-standard-flavors","h":"#properties-extra_specs","p":3886},{"i":3895,"t":"Standard SCS flavors","u":"/standards/scs-0103-v1-standard-flavors","h":"#standard-scs-flavors","p":3886},{"i":3897,"t":"Mandatory","u":"/standards/scs-0103-v1-standard-flavors","h":"#mandatory","p":3886},{"i":3899,"t":"Recommended","u":"/standards/scs-0103-v1-standard-flavors","h":"#recommended","p":3886},{"i":3901,"t":"Guarantees and properties","u":"/standards/scs-0103-v1-standard-flavors","h":"#guarantees-and-properties","p":3886},{"i":3903,"t":"Remarks","u":"/standards/scs-0103-v1-standard-flavors","h":"#remarks","p":3886},{"i":3905,"t":"Conformance Tests","u":"/standards/scs-0103-v1-standard-flavors","h":"#conformance-tests","p":3886},{"i":3907,"t":"Operational tooling","u":"/standards/scs-0103-v1-standard-flavors","h":"#operational-tooling","p":3886},{"i":3909,"t":"Previous standard versions","u":"/standards/scs-0103-v1-standard-flavors","h":"#previous-standard-versions","p":3886},{"i":3912,"t":"Introduction","u":"/standards/scs-0104-w1-standard-images-implementation","h":"#introduction","p":3911},{"i":3914,"t":"Step-by-step walkthrough","u":"/standards/scs-0104-w1-standard-images-implementation","h":"#step-by-step-walkthrough","p":3911},{"i":3915,"t":"Option A: pragmatic","u":"/standards/scs-0104-w1-standard-images-implementation","h":"#option-a-pragmatic","p":3911},{"i":3917,"t":"Option B: principled","u":"/standards/scs-0104-w1-standard-images-implementation","h":"#option-b-principled","p":3911},{"i":3919,"t":"Operational Tooling","u":"/standards/scs-0104-w1-standard-images-implementation","h":"#operational-tooling","p":3911},{"i":3922,"t":"Introduction","u":"/standards/scs-0110-v1-ssd-flavors","h":"#introduction","p":3921},{"i":3924,"t":"Motivation","u":"/standards/scs-0110-v1-ssd-flavors","h":"#motivation","p":3921},{"i":3926,"t":"Design Considerations","u":"/standards/scs-0110-v1-ssd-flavors","h":"#design-considerations","p":3921},{"i":3927,"t":"Options considered","u":"/standards/scs-0110-v1-ssd-flavors","h":"#options-considered","p":3921},{"i":3929,"t":"Decision","u":"/standards/scs-0110-v1-ssd-flavors","h":"#decision","p":3921},{"i":3931,"t":"Out of Scope","u":"/standards/scs-0110-v1-ssd-flavors","h":"#out-of-scope","p":3921},{"i":3933,"t":"Implementation note","u":"/standards/scs-0110-v1-ssd-flavors","h":"#implementation-note","p":3921},{"i":3935,"t":"Related Documents","u":"/standards/scs-0110-v1-ssd-flavors","h":"#related-documents","p":3921},{"i":3937,"t":"Conformance Tests","u":"/standards/scs-0110-v1-ssd-flavors","h":"#conformance-tests","p":3921},{"i":3940,"t":"Introduction","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#introduction","p":3939},{"i":3942,"t":"Motivation","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#motivation","p":3939},{"i":3944,"t":"Design Considerations","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#design-considerations","p":3939},{"i":3946,"t":"Options considered","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#options-considered","p":3939},{"i":3948,"t":"Open questions","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#open-questions","p":3939},{"i":3950,"t":"Decision","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#decision","p":3939},{"i":3952,"t":"Related Documents","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#related-documents","p":3939},{"i":3955,"t":"Introduction","u":"/standards/scs-0112-v1-sonic","h":"#introduction","p":3954},{"i":3957,"t":"Motivation","u":"/standards/scs-0112-v1-sonic","h":"#motivation","p":3954},{"i":3959,"t":"SONiC as a network OS where dynamic network configuration in Openstack is required","u":"/standards/scs-0112-v1-sonic","h":"#sonic-as-a-network-os-where-dynamic-network-configuration-in-openstack-is-required","p":3954},{"i":3961,"t":"Automation and tooling for SONiC","u":"/standards/scs-0112-v1-sonic","h":"#automation-and-tooling-for-sonic","p":3954},{"i":3963,"t":"OVN for SONiC","u":"/standards/scs-0112-v1-sonic","h":"#ovn-for-sonic","p":3954},{"i":3965,"t":"Design Considerations","u":"/standards/scs-0112-v1-sonic","h":"#design-considerations","p":3954},{"i":3967,"t":"Options considered","u":"/standards/scs-0112-v1-sonic","h":"#options-considered","p":3954},{"i":3969,"t":"Open questions","u":"/standards/scs-0112-v1-sonic","h":"#open-questions","p":3954},{"i":3970,"t":"State of SONiC community?","u":"/standards/scs-0112-v1-sonic","h":"#state-of-sonic-community","p":3954},{"i":3972,"t":"Decision","u":"/standards/scs-0112-v1-sonic","h":"#decision","p":3954},{"i":3974,"t":"Related Documents","u":"/standards/scs-0112-v1-sonic","h":"#related-documents","p":3954},{"i":3977,"t":"Introduction","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#introduction","p":3976},{"i":3979,"t":"Terminology","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#terminology","p":3976},{"i":3981,"t":"Context","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#context","p":3976},{"i":3983,"t":"Reasons for and against a standard for security groups","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#reasons-for-and-against-a-standard-for-security-groups","p":3976},{"i":3985,"t":"Technical limitations","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#technical-limitations","p":3976},{"i":3987,"t":"Option 0: Pre-Requirement: default rules for the (default) security group","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#option-0-pre-requirement-default-rules-for-the-default-security-group","p":3976},{"i":3989,"t":"Option 1: operator usage of network rbac","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#option-1-operator-usage-of-network-rbac","p":3976},{"i":3991,"t":"Option 2: stay project-scoped","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#option-2-stay-project-scoped","p":3976},{"i":3993,"t":"Option 3: security-focused guide","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#option-3-security-focused-guide","p":3976},{"i":3995,"t":"Decisions","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#decisions","p":3976},{"i":3997,"t":"Consequences","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#consequences","p":3976},{"i":3999,"t":"Related Documents","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#related-documents","p":3976},{"i":4001,"t":"Footnotes","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#footnote-label","p":3976},{"i":4004,"t":"Introduction","u":"/standards/scs-0114-v1-volume-type-standard","h":"#introduction","p":4003},{"i":4006,"t":"Glossary","u":"/standards/scs-0114-v1-volume-type-standard","h":"#glossary","p":4003},{"i":4008,"t":"Motivation","u":"/standards/scs-0114-v1-volume-type-standard","h":"#motivation","p":4003},{"i":4010,"t":"Design Considerations","u":"/standards/scs-0114-v1-volume-type-standard","h":"#design-considerations","p":4003},{"i":4012,"t":"Systematic Description of Volume Types","u":"/standards/scs-0114-v1-volume-type-standard","h":"#systematic-description-of-volume-types","p":4003},{"i":4014,"t":"Standardized Aspects","u":"/standards/scs-0114-v1-volume-type-standard","h":"#standardized-aspects","p":4003},{"i":4016,"t":"DEFAULT volume type","u":"/standards/scs-0114-v1-volume-type-standard","h":"#default-volume-type","p":4003},{"i":4018,"t":"REQUIRED volume types","u":"/standards/scs-0114-v1-volume-type-standard","h":"#required-volume-types","p":4003},{"i":4020,"t":"RECOMMENDED volume types","u":"/standards/scs-0114-v1-volume-type-standard","h":"#recommended-volume-types","p":4003},{"i":4022,"t":"OPTIONAL volume types","u":"/standards/scs-0114-v1-volume-type-standard","h":"#optional-volume-types","p":4003},{"i":4024,"t":"Implementation Details","u":"/standards/scs-0114-v1-volume-type-standard","h":"#implementation-details","p":4003},{"i":4025,"t":"Encryption","u":"/standards/scs-0114-v1-volume-type-standard","h":"#encryption","p":4003},{"i":4027,"t":"Replication","u":"/standards/scs-0114-v1-volume-type-standard","h":"#replication","p":4003},{"i":4029,"t":"Example","u":"/standards/scs-0114-v1-volume-type-standard","h":"#example","p":4003},{"i":4031,"t":"Related Documents","u":"/standards/scs-0114-v1-volume-type-standard","h":"#related-documents","p":4003},{"i":4033,"t":"Conformance Tests","u":"/standards/scs-0114-v1-volume-type-standard","h":"#conformance-tests","p":4003},{"i":4036,"t":"Introduction","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#introduction","p":4035},{"i":4038,"t":"Terminology","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#terminology","p":4035},{"i":4040,"t":"Default Security Groups, Custom Security Groups and default Security Group Rules","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#default-security-groups-custom-security-groups-and-default-security-group-rules","p":4035},{"i":4042,"t":"Motivation","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#motivation","p":4035},{"i":4044,"t":"Design Considerations","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#design-considerations","p":4035},{"i":4046,"t":"Further Annotations","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#further-annotations","p":4035},{"i":4048,"t":"Standard","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#standard","p":4035},{"i":4050,"t":"Example","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#example","p":4035},{"i":4052,"t":"Related Documents","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#related-documents","p":4035},{"i":4054,"t":"Conformance Tests","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#conformance-tests","p":4035},{"i":4056,"t":"Footnotes","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#footnote-label","p":4035},{"i":4059,"t":"Implementation","u":"/standards/scs-0116-w1-key-manager-implementation-testing","h":"#implementation","p":4058},{"i":4061,"t":"Policies","u":"/standards/scs-0116-w1-key-manager-implementation-testing","h":"#policies","p":4058},{"i":4063,"t":"Automated Tests","u":"/standards/scs-0116-w1-key-manager-implementation-testing","h":"#automated-tests","p":4058},{"i":4065,"t":"Implementation","u":"/standards/scs-0116-w1-key-manager-implementation-testing","h":"#implementation-1","p":4058},{"i":4067,"t":"Manual Tests","u":"/standards/scs-0116-w1-key-manager-implementation-testing","h":"#manual-tests","p":4058},{"i":4069,"t":"Footnotes","u":"/standards/scs-0116-w1-key-manager-implementation-testing","h":"#footnote-label","p":4058},{"i":4072,"t":"Introduction","u":"/standards/scs-0116-v1-key-manager-standard","h":"#introduction","p":4071},{"i":4074,"t":"Terminology","u":"/standards/scs-0116-v1-key-manager-standard","h":"#terminology","p":4071},{"i":4076,"t":"Motivation","u":"/standards/scs-0116-v1-key-manager-standard","h":"#motivation","p":4071},{"i":4078,"t":"Design Considerations","u":"/standards/scs-0116-v1-key-manager-standard","h":"#design-considerations","p":4071},{"i":4080,"t":"Options considered","u":"/standards/scs-0116-v1-key-manager-standard","h":"#options-considered","p":4071},{"i":4082,"t":"Key Manager Standard","u":"/standards/scs-0116-v1-key-manager-standard","h":"#key-manager-standard","p":4071},{"i":4084,"t":"Key Manager Policies","u":"/standards/scs-0116-v1-key-manager-standard","h":"#key-manager-policies","p":4071},{"i":4086,"t":"Related Documents","u":"/standards/scs-0116-v1-key-manager-standard","h":"#related-documents","p":4071},{"i":4088,"t":"Conformance Tests","u":"/standards/scs-0116-v1-key-manager-standard","h":"#conformance-tests","p":4071},{"i":4090,"t":"Footnotes","u":"/standards/scs-0116-v1-key-manager-standard","h":"#footnote-label","p":4071},{"i":4093,"t":"Abstract","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","h":"#abstract","p":4092},{"i":4095,"t":"Glossary","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","h":"#glossary","p":4092},{"i":4097,"t":"Context","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","h":"#context","p":4092},{"i":4099,"t":"Goal of this Decision Record","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","h":"#goal-of-this-decision-record","p":4092},{"i":4101,"t":"Differentiation between failsafe levels and high availability, disaster recovery, redundancy and backups","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","h":"#differentiation-between-failsafe-levels-and-high-availability-disaster-recovery-redundancy-and-backups","p":4092},{"i":4103,"t":"Failsafe Levels and RTO","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","h":"#failsafe-levels-and-rto","p":4092},{"i":4105,"t":"Decision","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","h":"#decision","p":4092},{"i":4106,"t":"Failsafe Levels","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","h":"#failsafe-levels","p":4092},{"i":4108,"t":"Failure Scenarios","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","h":"#failure-scenarios","p":4092},{"i":4110,"t":"Consequences","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","h":"#consequences","p":4092},{"i":4112,"t":"Affected Resources","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","h":"#affected-resources","p":4092},{"i":4115,"t":"Introduction","u":"/standards/scs-0117-v1-volume-backup-service","h":"#introduction","p":4114},{"i":4117,"t":"Terminology","u":"/standards/scs-0117-v1-volume-backup-service","h":"#terminology","p":4114},{"i":4119,"t":"Motivation","u":"/standards/scs-0117-v1-volume-backup-service","h":"#motivation","p":4114},{"i":4121,"t":"Design Considerations","u":"/standards/scs-0117-v1-volume-backup-service","h":"#design-considerations","p":4114},{"i":4123,"t":"Options considered","u":"/standards/scs-0117-v1-volume-backup-service","h":"#options-considered","p":4114},{"i":4125,"t":"Standard","u":"/standards/scs-0117-v1-volume-backup-service","h":"#standard","p":4114},{"i":4127,"t":"Related Documents","u":"/standards/scs-0117-v1-volume-backup-service","h":"#related-documents","p":4114},{"i":4129,"t":"Conformance Tests","u":"/standards/scs-0117-v1-volume-backup-service","h":"#conformance-tests","p":4114},{"i":4132,"t":"Examples of the impact from certain failure scenarios on Cloud Resources","u":"/standards/scs-0118-w1-example-impacts-of-failure-scenarios","h":"#examples-of-the-impact-from-certain-failure-scenarios-on-cloud-resources","p":4131},{"i":4134,"t":"Impact on IaaS Resources (IaaS Layer)","u":"/standards/scs-0118-w1-example-impacts-of-failure-scenarios","h":"#impact-on-iaas-resources-iaas-layer","p":4131},{"i":4136,"t":"Impact on Kubernetes Resources (KaaS layer)","u":"/standards/scs-0118-w1-example-impacts-of-failure-scenarios","h":"#impact-on-kubernetes-resources-kaas-layer","p":4131},{"i":4138,"t":"Footnotes","u":"/standards/scs-0118-w1-example-impacts-of-failure-scenarios","h":"#footnote-label","p":4131},{"i":4141,"t":"Abstract","u":"/standards/scs-0119-v1-rook-decision","h":"#abstract","p":4140},{"i":4143,"t":"Context","u":"/standards/scs-0119-v1-rook-decision","h":"#context","p":4140},{"i":4145,"t":"Comparison of Features","u":"/standards/scs-0119-v1-rook-decision","h":"#comparison-of-features","p":4140},{"i":4147,"t":"Decision","u":"/standards/scs-0119-v1-rook-decision","h":"#decision","p":4140},{"i":4149,"t":"Consequences","u":"/standards/scs-0119-v1-rook-decision","h":"#consequences","p":4140},{"i":4152,"t":"Introduction","u":"/standards/scs-0121-v1-Availability-Zones-Standard","h":"#introduction","p":4151},{"i":4154,"t":"Terminology","u":"/standards/scs-0121-v1-Availability-Zones-Standard","h":"#terminology","p":4151},{"i":4156,"t":"Motivation","u":"/standards/scs-0121-v1-Availability-Zones-Standard","h":"#motivation","p":4151},{"i":4158,"t":"Design Considerations","u":"/standards/scs-0121-v1-Availability-Zones-Standard","h":"#design-considerations","p":4151},{"i":4160,"t":"Scope of the Availability Zone Standard","u":"/standards/scs-0121-v1-Availability-Zones-Standard","h":"#scope-of-the-availability-zone-standard","p":4151},{"i":4162,"t":"Options considered","u":"/standards/scs-0121-v1-Availability-Zones-Standard","h":"#options-considered","p":4151},{"i":4164,"t":"Cross-Attaching volumes from one AZ to another compute AZ","u":"/standards/scs-0121-v1-Availability-Zones-Standard","h":"#cross-attaching-volumes-from-one-az-to-another-compute-az","p":4151},{"i":4166,"t":"Standard","u":"/standards/scs-0121-v1-Availability-Zones-Standard","h":"#standard","p":4151},{"i":4168,"t":"Related Documents","u":"/standards/scs-0121-v1-Availability-Zones-Standard","h":"#related-documents","p":4151},{"i":4170,"t":"Conformance Tests","u":"/standards/scs-0121-v1-Availability-Zones-Standard","h":"#conformance-tests","p":4151},{"i":4172,"t":"Footnotes","u":"/standards/scs-0121-v1-Availability-Zones-Standard","h":"#footnote-label","p":4151},{"i":4175,"t":"Automated Tests","u":"/standards/scs-0121-w1-Availability-Zones-Standard","h":"#automated-tests","p":4174},{"i":4177,"t":"Required Documentation","u":"/standards/scs-0121-w1-Availability-Zones-Standard","h":"#required-documentation","p":4174},{"i":4179,"t":"Alternative Documentation","u":"/standards/scs-0121-w1-Availability-Zones-Standard","h":"#alternative-documentation","p":4174},{"i":4181,"t":"Physical Audits","u":"/standards/scs-0121-w1-Availability-Zones-Standard","h":"#physical-audits","p":4174},{"i":4184,"t":"Abstract","u":"/standards/scs-0120-v1-capi-images","h":"#abstract","p":4183},{"i":4186,"t":"Terminology","u":"/standards/scs-0120-v1-capi-images","h":"#terminology","p":4183},{"i":4188,"t":"Design considerations","u":"/standards/scs-0120-v1-capi-images","h":"#design-considerations","p":4183},{"i":4190,"t":"Decision","u":"/standards/scs-0120-v1-capi-images","h":"#decision","p":4183},{"i":4192,"t":"Consequences","u":"/standards/scs-0120-v1-capi-images","h":"#consequences","p":4183},{"i":4194,"t":"Open questions","u":"/standards/scs-0120-v1-capi-images","h":"#open-questions","p":4183},{"i":4197,"t":"Introduction","u":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","h":"#introduction","p":4196},{"i":4199,"t":"Motivation","u":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","h":"#motivation","p":4196},{"i":4201,"t":"Mandatory IaaS APIs","u":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","h":"#mandatory-iaas-apis","p":4196},{"i":4203,"t":"Supported IaaS APIs","u":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","h":"#supported-iaas-apis","p":4196},{"i":4205,"t":"Unsupported IaaS APIs","u":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","h":"#unsupported-iaas-apis","p":4196},{"i":4207,"t":"Related Documents","u":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","h":"#related-documents","p":4196},{"i":4209,"t":"Conformance Tests","u":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","h":"#conformance-tests","p":4196},{"i":4211,"t":"Footnotes","u":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","h":"#footnote-label","p":4196},{"i":4214,"t":"Abstract","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#abstract","p":4213},{"i":4216,"t":"Terminology","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#terminology","p":4213},{"i":4218,"t":"Context","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#context","p":4213},{"i":4219,"t":"Motivation","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#motivation","p":4213},{"i":4221,"t":"Potential threats in detail","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#potential-threats-in-detail","p":4213},{"i":4223,"t":"Preliminary considerations","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#preliminary-considerations","p":4213},{"i":4225,"t":"Exploration of technologies","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#exploration-of-technologies","p":4213},{"i":4227,"t":"Solution proposals","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#solution-proposals","p":4213},{"i":4229,"t":"Proof of concept implementations","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#proof-of-concept-implementations","p":4213},{"i":4231,"t":"Decision","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#decision","p":4213},{"i":4233,"t":"Utilize existing solutions","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#utilize-existing-solutions-1","p":4213},{"i":4235,"t":"Address threat modeling issues","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#address-threat-modeling-issues-1","p":4213},{"i":4237,"t":"Avoid redundant encryption","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#avoid-redundant-encryption-1","p":4213},{"i":4239,"t":"Performance impact and ease of use","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#performance-impact-and-ease-of-use-1","p":4213},{"i":4241,"t":"Upstream integration","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#upstream-integration-1","p":4213},{"i":4243,"t":"References","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#references","p":4213},{"i":4245,"t":"Footnotes","u":"/standards/scs-0122-v1-node-to-node-encryption","h":"#footnote-label","p":4213},{"i":4248,"t":"Introduction","u":"/standards/scs-0124-v1-security-of-iaas-service-software","h":"#introduction","p":4247},{"i":4250,"t":"Terminology","u":"/standards/scs-0124-v1-security-of-iaas-service-software","h":"#terminology","p":4247},{"i":4252,"t":"Motivation","u":"/standards/scs-0124-v1-security-of-iaas-service-software","h":"#motivation","p":4247},{"i":4254,"t":"Design Considerations","u":"/standards/scs-0124-v1-security-of-iaas-service-software","h":"#design-considerations","p":4247},{"i":4256,"t":"Options considered","u":"/standards/scs-0124-v1-security-of-iaas-service-software","h":"#options-considered","p":4247},{"i":4258,"t":"Standard for a minimum IaaS Layer Software version","u":"/standards/scs-0124-v1-security-of-iaas-service-software","h":"#standard-for-a-minimum-iaas-layer-software-version","p":4247},{"i":4260,"t":"Conformance Tests","u":"/standards/scs-0124-v1-security-of-iaas-service-software","h":"#conformance-tests","p":4247},{"i":4262,"t":"Footnotes","u":"/standards/scs-0124-v1-security-of-iaas-service-software","h":"#footnote-label","p":4247},{"i":4265,"t":"Testing or Detecting security updates in software","u":"/standards/scs-0124-w1-security-of-iaas-service-software","h":"#testing-or-detecting-security-updates-in-software","p":4264},{"i":4267,"t":"Procedure to become compliant to the security of IaaS service software Standard","u":"/standards/scs-0124-w1-security-of-iaas-service-software","h":"#procedure-to-become-compliant-to-the-security-of-iaas-service-software-standard","p":4264},{"i":4269,"t":"Procedure when new vulnerabilites are discovered","u":"/standards/scs-0124-w1-security-of-iaas-service-software","h":"#procedure-when-new-vulnerabilites-are-discovered","p":4264},{"i":4272,"t":"Motivation","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#motivation","p":4271},{"i":4274,"t":"Short Sonobuoy Introduction","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#short-sonobuoy-introduction","p":4271},{"i":4276,"t":"Design Considerations","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#design-considerations","p":4271},{"i":4278,"t":"Option 1 Golang based approach 1: Pick a framework from the Sonobuoy plugin examples","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-1-golang-based-approach-1-pick-a-framework-from-the-sonobuoy-plugin-examples","p":4271},{"i":4280,"t":"Option 2 Golang based approach 2: Reuse the Kubernetes own e2e test infrastructure and framework","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-2-golang-based-approach-2-reuse-the-kubernetes-own-e2e-test-infrastructure-and-framework","p":4271},{"i":4282,"t":"Option 3 Write Python scripts for tests","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-3-write-python-scripts-for-tests","p":4271},{"i":4284,"t":"Approaches to providing a Sonobuoy plugin image","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#approaches-to-providing-a-sonobuoy-plugin-image","p":4271},{"i":4286,"t":"Option 1 Public container registry","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-1-public-container-registry","p":4271},{"i":4288,"t":"Option 2 Local image upload","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-2-local-image-upload","p":4271},{"i":4290,"t":"Decision","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#decision","p":4271},{"i":4293,"t":"Introduction","u":"/standards/scs-0125-v1-secure-connections","h":"#introduction","p":4292},{"i":4295,"t":"Terminology","u":"/standards/scs-0125-v1-secure-connections","h":"#terminology","p":4292},{"i":4297,"t":"Motivation","u":"/standards/scs-0125-v1-secure-connections","h":"#motivation","p":4292},{"i":4299,"t":"Design Considerations","u":"/standards/scs-0125-v1-secure-connections","h":"#design-considerations","p":4292},{"i":4301,"t":"Communication Channels","u":"/standards/scs-0125-v1-secure-connections","h":"#communication-channels","p":4292},{"i":4303,"t":"libvirt Hypervisor Interface on Compute Nodes","u":"/standards/scs-0125-v1-secure-connections","h":"#libvirt-hypervisor-interface-on-compute-nodes","p":4292},{"i":4305,"t":"TLS Configuration Recommendations","u":"/standards/scs-0125-v1-secure-connections","h":"#tls-configuration-recommendations","p":4292},{"i":4307,"t":"Storage network protection","u":"/standards/scs-0125-v1-secure-connections","h":"#storage-network-protection","p":4292},{"i":4309,"t":"Options considered","u":"/standards/scs-0125-v1-secure-connections","h":"#options-considered","p":4292},{"i":4311,"t":"Open questions","u":"/standards/scs-0125-v1-secure-connections","h":"#open-questions","p":4292},{"i":4312,"t":"Choosing the best protection mechanism for the libvirt hypervisor interface","u":"/standards/scs-0125-v1-secure-connections","h":"#choosing-the-best-protection-mechanism-for-the-libvirt-hypervisor-interface","p":4292},{"i":4314,"t":"Verifying standard conformance for internal mechanisms","u":"/standards/scs-0125-v1-secure-connections","h":"#verifying-standard-conformance-for-internal-mechanisms","p":4292},{"i":4316,"t":"Standard","u":"/standards/scs-0125-v1-secure-connections","h":"#standard","p":4292},{"i":4318,"t":"Transport Layer Security (TLS)","u":"/standards/scs-0125-v1-secure-connections","h":"#transport-layer-security-tls","p":4292},{"i":4320,"t":"API Interfaces","u":"/standards/scs-0125-v1-secure-connections","h":"#api-interfaces","p":4292},{"i":4322,"t":"Database Connections","u":"/standards/scs-0125-v1-secure-connections","h":"#database-connections","p":4292},{"i":4324,"t":"Message Queue Connections","u":"/standards/scs-0125-v1-secure-connections","h":"#message-queue-connections","p":4292},{"i":4326,"t":"Hypervisor and Live Migration Connections","u":"/standards/scs-0125-v1-secure-connections","h":"#hypervisor-and-live-migration-connections","p":4292},{"i":4328,"t":"External VM Connections","u":"/standards/scs-0125-v1-secure-connections","h":"#external-vm-connections","p":4292},{"i":4330,"t":"Internal Neutron Connections","u":"/standards/scs-0125-v1-secure-connections","h":"#internal-neutron-connections","p":4292},{"i":4332,"t":"Storage Connections","u":"/standards/scs-0125-v1-secure-connections","h":"#storage-connections","p":4292},{"i":4334,"t":"Related Documents","u":"/standards/scs-0125-v1-secure-connections","h":"#related-documents","p":4292},{"i":4336,"t":"Conformance Tests","u":"/standards/scs-0125-v1-secure-connections","h":"#conformance-tests","p":4292},{"i":4339,"t":"Introduction","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#introduction","p":4338},{"i":4341,"t":"Motivation","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#motivation","p":4338},{"i":4343,"t":"Decision","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#decision","p":4338},{"i":4345,"t":"Related Documents","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#related-documents","p":4338},{"i":4347,"t":"Conformance Tests","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#conformance-tests","p":4338},{"i":4350,"t":"Introduction","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#introduction","p":4349},{"i":4352,"t":"Motivation","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#motivation","p":4349},{"i":4354,"t":"Decision","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#decision","p":4349},{"i":4356,"t":"Related Documents","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#related-documents","p":4349},{"i":4358,"t":"Conformance Tests","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#conformance-tests","p":4349},{"i":4361,"t":"Implementation notes","u":"/standards/scs-0210-w1-k8s-version-policy-implementation-testing","h":"#implementation-notes","p":4360},{"i":4363,"t":"Automated tests","u":"/standards/scs-0210-w1-k8s-version-policy-implementation-testing","h":"#automated-tests","p":4360},{"i":4364,"t":"Implementation","u":"/standards/scs-0210-w1-k8s-version-policy-implementation-testing","h":"#implementation","p":4360},{"i":4366,"t":"Manual tests","u":"/standards/scs-0210-w1-k8s-version-policy-implementation-testing","h":"#manual-tests","p":4360},{"i":4369,"t":"Introduction","u":"/standards/scs-0211-v2-kaas-default-storage-class","h":"#introduction","p":4368},{"i":4371,"t":"Motivation","u":"/standards/scs-0211-v2-kaas-default-storage-class","h":"#motivation","p":4368},{"i":4373,"t":"Decision","u":"/standards/scs-0211-v2-kaas-default-storage-class","h":"#decision","p":4368},{"i":4375,"t":"Recommended non-performance-related properties","u":"/standards/scs-0211-v2-kaas-default-storage-class","h":"#recommended-non-performance-related-properties","p":4368},{"i":4377,"t":"Required performance-related properties","u":"/standards/scs-0211-v2-kaas-default-storage-class","h":"#required-performance-related-properties","p":4368},{"i":4379,"t":"Previous standard versions","u":"/standards/scs-0211-v2-kaas-default-storage-class","h":"#previous-standard-versions","p":4368},{"i":4381,"t":"Conformance Tests","u":"/standards/scs-0211-v2-kaas-default-storage-class","h":"#conformance-tests","p":4368},{"i":4384,"t":"Implementation notes","u":"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing","h":"#implementation-notes","p":4383},{"i":4386,"t":"Automated tests","u":"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing","h":"#automated-tests","p":4383},{"i":4387,"t":"Notes","u":"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing","h":"#notes","p":4383},{"i":4389,"t":"Implementation","u":"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing","h":"#implementation","p":4383},{"i":4391,"t":"Manual tests","u":"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing","h":"#manual-tests","p":4383},{"i":4394,"t":"Introduction","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#introduction","p":4393},{"i":4396,"t":"Motivation","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#motivation","p":4393},{"i":4398,"t":"Decision","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#decision","p":4393},{"i":4400,"t":"Required non-performance-related properties","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#required-non-performance-related-properties","p":4393},{"i":4402,"t":"Required performance-related properties","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#required-performance-related-properties","p":4393},{"i":4404,"t":"Related Documents","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#related-documents","p":4393},{"i":4406,"t":"Conformance Tests","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#conformance-tests","p":4393},{"i":4409,"t":"Introduction","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#introduction","p":4408},{"i":4411,"t":"Terminology","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#terminology","p":4408},{"i":4413,"t":"Motivation","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#motivation","p":4408},{"i":4415,"t":"Design considerations","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#design-considerations","p":4408},{"i":4417,"t":"OSS health check","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#oss-health-check","p":4408},{"i":4419,"t":"Required and desirable features check","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#required-and-desirable-features-check","p":4408},{"i":4421,"t":"Standard","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#standard","p":4408},{"i":4423,"t":"Related Documents","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#related-documents","p":4408},{"i":4426,"t":"Introduction","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#introduction","p":4425},{"i":4428,"t":"Glossary","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#glossary","p":4425},{"i":4430,"t":"Motivation","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#motivation","p":4425},{"i":4432,"t":"Design considerations","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#design-considerations","p":4425},{"i":4434,"t":"Decision","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#decision","p":4425},{"i":4436,"t":"Documents","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#documents","p":4425},{"i":4439,"t":"Introduction","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#introduction","p":4438},{"i":4441,"t":"Glossary","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#glossary","p":4438},{"i":4443,"t":"Motivation","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#motivation","p":4438},{"i":4445,"t":"Design Considerations","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#design-considerations","p":4438},{"i":4447,"t":"Decision","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#decision","p":4438},{"i":4450,"t":"Introduction","u":"/standards/scs-0214-v2-k8s-node-distribution","h":"#introduction","p":4449},{"i":4452,"t":"Glossary","u":"/standards/scs-0214-v2-k8s-node-distribution","h":"#glossary","p":4449},{"i":4454,"t":"Motivation","u":"/standards/scs-0214-v2-k8s-node-distribution","h":"#motivation","p":4449},{"i":4456,"t":"Design Considerations","u":"/standards/scs-0214-v2-k8s-node-distribution","h":"#design-considerations","p":4449},{"i":4458,"t":"Decision","u":"/standards/scs-0214-v2-k8s-node-distribution","h":"#decision","p":4449},{"i":4460,"t":"Previous standard versions","u":"/standards/scs-0214-v2-k8s-node-distribution","h":"#previous-standard-versions","p":4449},{"i":4463,"t":"Implementation notes","u":"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing","h":"#implementation-notes","p":4462},{"i":4465,"t":"Automated tests","u":"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing","h":"#automated-tests","p":4462},{"i":4467,"t":"Manual tests","u":"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing","h":"#manual-tests","p":4462},{"i":4470,"t":"Introduction","u":"/standards/scs-0215-v1-robustness-features","h":"#introduction","p":4469},{"i":4472,"t":"Glossary","u":"/standards/scs-0215-v1-robustness-features","h":"#glossary","p":4469},{"i":4474,"t":"Motivation","u":"/standards/scs-0215-v1-robustness-features","h":"#motivation","p":4469},{"i":4476,"t":"Design Considerations","u":"/standards/scs-0215-v1-robustness-features","h":"#design-considerations","p":4469},{"i":4478,"t":"Kube-API rate limiting","u":"/standards/scs-0215-v1-robustness-features","h":"#kube-api-rate-limiting","p":4469},{"i":4480,"t":"etcd maintenance","u":"/standards/scs-0215-v1-robustness-features","h":"#etcd-maintenance","p":4469},{"i":4482,"t":"etcd backup","u":"/standards/scs-0215-v1-robustness-features","h":"#etcd-backup","p":4469},{"i":4484,"t":"Certificate rotation","u":"/standards/scs-0215-v1-robustness-features","h":"#certificate-rotation","p":4469},{"i":4486,"t":"Decision","u":"/standards/scs-0215-v1-robustness-features","h":"#decision","p":4469},{"i":4488,"t":"Kube-API rate limiting","u":"/standards/scs-0215-v1-robustness-features","h":"#kube-api-rate-limiting-1","p":4469},{"i":4490,"t":"etcd compaction","u":"/standards/scs-0215-v1-robustness-features","h":"#etcd-compaction","p":4469},{"i":4492,"t":"etcd backup","u":"/standards/scs-0215-v1-robustness-features","h":"#etcd-backup-1","p":4469},{"i":4494,"t":"Certificate rotation","u":"/standards/scs-0215-v1-robustness-features","h":"#certificate-rotation-1","p":4469},{"i":4496,"t":"Related Documents","u":"/standards/scs-0215-v1-robustness-features","h":"#related-documents","p":4469},{"i":4498,"t":"Conformance Tests","u":"/standards/scs-0215-v1-robustness-features","h":"#conformance-tests","p":4469},{"i":4501,"t":"Introduction","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#introduction","p":4500},{"i":4503,"t":"Motivation","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#motivation","p":4500},{"i":4505,"t":"Design Considerations","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#design-considerations","p":4500},{"i":4507,"t":"Required Features","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#required-features","p":4500},{"i":4509,"t":"Pros and Cons of Different Approaches","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#pros-and-cons-of-different-approaches","p":4500},{"i":4511,"t":"IaaS Provider (OpenStack, Hetzner, AWS)","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#iaas-provider-openstack-hetzner-aws","p":4500},{"i":4513,"t":"Local Environment (Docker, KubeVirt)","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#local-environment-docker-kubevirt","p":4500},{"i":4515,"t":"Beyond Docker: Virtual Machine based Approach","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#beyond-docker-virtual-machine-based-approach","p":4500},{"i":4517,"t":"Virtual Machine Based Approach","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#virtual-machine-based-approach","p":4500},{"i":4519,"t":"Proposed Path Forward","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#proposed-path-forward","p":4500},{"i":4521,"t":"Conclusion","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#conclusion","p":4500},{"i":4524,"t":"Introduction","u":"/standards/scs-0217-v1-cluster-hardening","h":"#introduction","p":4523},{"i":4526,"t":"Terminology","u":"/standards/scs-0217-v1-cluster-hardening","h":"#terminology","p":4523},{"i":4528,"t":"Motivation","u":"/standards/scs-0217-v1-cluster-hardening","h":"#motivation","p":4523},{"i":4530,"t":"Hardening Kubernetes","u":"/standards/scs-0217-v1-cluster-hardening","h":"#hardening-kubernetes","p":4523},{"i":4532,"t":"Regular updates","u":"/standards/scs-0217-v1-cluster-hardening","h":"#regular-updates","p":4523},{"i":4534,"t":"Securing etcd","u":"/standards/scs-0217-v1-cluster-hardening","h":"#securing-etcd","p":4523},{"i":4536,"t":"Securing endpoints","u":"/standards/scs-0217-v1-cluster-hardening","h":"#securing-endpoints","p":4523},{"i":4538,"t":"API security, authentication and authorization","u":"/standards/scs-0217-v1-cluster-hardening","h":"#api-security-authentication-and-authorization","p":4523},{"i":4540,"t":"Kubelet access control","u":"/standards/scs-0217-v1-cluster-hardening","h":"#kubelet-access-control","p":4523},{"i":4542,"t":"Pod security policies","u":"/standards/scs-0217-v1-cluster-hardening","h":"#pod-security-policies","p":4523},{"i":4544,"t":"Further measurements","u":"/standards/scs-0217-v1-cluster-hardening","h":"#further-measurements","p":4523},{"i":4546,"t":"Standard","u":"/standards/scs-0217-v1-cluster-hardening","h":"#standard","p":4523},{"i":4548,"t":"Conformance Tests","u":"/standards/scs-0217-v1-cluster-hardening","h":"#conformance-tests","p":4523},{"i":4550,"t":"Related Documents","u":"/standards/scs-0217-v1-cluster-hardening","h":"#related-documents","p":4523},{"i":4553,"t":"Introduction","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#introduction","p":4552},{"i":4555,"t":"Terminology","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#terminology","p":4552},{"i":4557,"t":"Motivation","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#motivation","p":4552},{"i":4559,"t":"Evaluated projects","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#evaluated-projects","p":4552},{"i":4561,"t":"Deeper look into selected projects","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#deeper-look-into-selected-projects","p":4552},{"i":4563,"t":"Decision","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#decision","p":4552},{"i":4565,"t":"Related Documents","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#related-documents","p":4552},{"i":4568,"t":"List of compliant CNI Plugins","u":"/standards/scs-0219-w1-kaas-networking","h":"#list-of-compliant-cni-plugins","p":4567},{"i":4571,"t":"Introduction","u":"/standards/scs-0219-v1-kaas-networking","h":"#introduction","p":4570},{"i":4573,"t":"Terminology","u":"/standards/scs-0219-v1-kaas-networking","h":"#terminology","p":4570},{"i":4575,"t":"Motivation","u":"/standards/scs-0219-v1-kaas-networking","h":"#motivation","p":4570},{"i":4577,"t":"Design Considerations","u":"/standards/scs-0219-v1-kaas-networking","h":"#design-considerations","p":4570},{"i":4579,"t":"Options considered","u":"/standards/scs-0219-v1-kaas-networking","h":"#options-considered","p":4570},{"i":4581,"t":"Decision","u":"/standards/scs-0219-v1-kaas-networking","h":"#decision","p":4570},{"i":4583,"t":"Conformance Tests","u":"/standards/scs-0219-v1-kaas-networking","h":"#conformance-tests","p":4570},{"i":4586,"t":"Introduction","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#introduction","p":4585},{"i":4588,"t":"Motivation for this document","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#motivation-for-this-document","p":4585},{"i":4590,"t":"Design Considerations","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#design-considerations","p":4585},{"i":4592,"t":"Options considered","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#options-considered","p":4585},{"i":4594,"t":"Open questions","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#open-questions","p":4585},{"i":4596,"t":"Decision","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#decision","p":4585},{"i":4598,"t":"Related Documents","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#related-documents","p":4585},{"i":4600,"t":"Conformance Tests","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#conformance-tests","p":4585},{"i":4601,"t":"Conformance Tests, OPTIONAL","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#conformance-tests-optional","p":4585},{"i":4603,"t":"Introduction","u":"/standards/scs-0302-v1-domain-manager-role","h":"#introduction","p":4602},{"i":4605,"t":"Terminology","u":"/standards/scs-0302-v1-domain-manager-role","h":"#terminology","p":4602},{"i":4607,"t":"Motivation","u":"/standards/scs-0302-v1-domain-manager-role","h":"#motivation","p":4602},{"i":4609,"t":"Desired Workflow","u":"/standards/scs-0302-v1-domain-manager-role","h":"#desired-workflow","p":4602},{"i":4611,"t":"Design Considerations","u":"/standards/scs-0302-v1-domain-manager-role","h":"#design-considerations","p":4602},{"i":4613,"t":"Options considered","u":"/standards/scs-0302-v1-domain-manager-role","h":"#options-considered","p":4602},{"i":4615,"t":"Decision","u":"/standards/scs-0302-v1-domain-manager-role","h":"#decision","p":4602},{"i":4617,"t":"For OpenStack Keystone 2024.2 or later","u":"/standards/scs-0302-v1-domain-manager-role","h":"#for-openstack-keystone-20242-or-later","p":4602},{"i":4619,"t":"For OpenStack Keystone 2024.1 or below","u":"/standards/scs-0302-v1-domain-manager-role","h":"#for-openstack-keystone-20241-or-below","p":4602},{"i":4621,"t":"Related Documents","u":"/standards/scs-0302-v1-domain-manager-role","h":"#related-documents","p":4602},{"i":4622,"t":"Upstream contribution spec for the Domain Manager functionality","u":"/standards/scs-0302-v1-domain-manager-role","h":"#upstream-contribution-spec-for-the-domain-manager-functionality","p":4602},{"i":4624,"t":"\"admin\"-ness not properly scoped","u":"/standards/scs-0302-v1-domain-manager-role","h":"#admin-ness-not-properly-scoped","p":4602},{"i":4626,"t":"Consistent and Secure Default RBAC","u":"/standards/scs-0302-v1-domain-manager-role","h":"#consistent-and-secure-default-rbac","p":4602},{"i":4628,"t":"Conformance Tests","u":"/standards/scs-0302-v1-domain-manager-role","h":"#conformance-tests","p":4602},{"i":4630,"t":"Appendix","u":"/standards/scs-0302-v1-domain-manager-role","h":"#appendix","p":4602},{"i":4631,"t":"Decision Record","u":"/standards/scs-0302-v1-domain-manager-role","h":"#decision-record","p":4602},{"i":4633,"t":"Footnotes","u":"/standards/scs-0302-v1-domain-manager-role","h":"#footnote-label","p":4602},{"i":4636,"t":"Introduction","u":"/standards/scs-0301-v1-naming-conventions","h":"#introduction","p":4635},{"i":4638,"t":"Motivation","u":"/standards/scs-0301-v1-naming-conventions","h":"#motivation","p":4635},{"i":4640,"t":"Design Considerations","u":"/standards/scs-0301-v1-naming-conventions","h":"#design-considerations","p":4635},{"i":4642,"t":"Options considered","u":"/standards/scs-0301-v1-naming-conventions","h":"#options-considered","p":4635},{"i":4644,"t":"Open questions","u":"/standards/scs-0301-v1-naming-conventions","h":"#open-questions","p":4635},{"i":4646,"t":"Decision","u":"/standards/scs-0301-v1-naming-conventions","h":"#decision","p":4635},{"i":4648,"t":"Related Documents","u":"/standards/scs-0301-v1-naming-conventions","h":"#related-documents","p":4635},{"i":4650,"t":"Conformance Tests","u":"/standards/scs-0301-v1-naming-conventions","h":"#conformance-tests","p":4635},{"i":4653,"t":"Introduction","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#introduction","p":4652},{"i":4655,"t":"Existing Applications","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#existing-applications","p":4652},{"i":4657,"t":"Decision","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#decision","p":4652},{"i":4659,"t":"Status Page Requirements","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#status-page-requirements","p":4652},{"i":4661,"t":"Comparison matrix","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#comparison-matrix","p":4652},{"i":4664,"t":"Implementation notes","u":"/standards/scs-0302-w1-domain-manager-implementation-notes","h":"#implementation-notes","p":4663},{"i":4666,"t":"Policy adjustments","u":"/standards/scs-0302-w1-domain-manager-implementation-notes","h":"#policy-adjustments","p":4663},{"i":4668,"t":"Impact","u":"/standards/scs-0302-w1-domain-manager-implementation-notes","h":"#impact","p":4663},{"i":4670,"t":"Footnotes","u":"/standards/scs-0302-w1-domain-manager-implementation-notes","h":"#footnote-label","p":4663},{"i":4673,"t":"Introduction","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#introduction","p":4672},{"i":4675,"t":"Motivation","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#motivation","p":4672},{"i":4677,"t":"Decision","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#decision","p":4672},{"i":4678,"t":"Programming Language","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#programming-language","p":4672},{"i":4680,"t":"Database","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#database","p":4672},{"i":4683,"t":"Introduction","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#introduction","p":4682},{"i":4685,"t":"Requirements","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#requirements","p":4682},{"i":4687,"t":"Motivation","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#motivation","p":4682},{"i":4689,"t":"Decision","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#decision","p":4682},{"i":4690,"t":"Common definitions","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#common-definitions","p":4682},{"i":4692,"t":"API objects","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#api-objects","p":4682},{"i":4694,"t":"API object fields","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#api-object-fields","p":4682},{"i":4696,"t":"Endpoint naming","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#endpoint-naming","p":4682},{"i":4698,"t":"Incidents","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#incidents","p":4682},{"i":4700,"t":"Phase list","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#phase-list","p":4682},{"i":4702,"t":"Labels","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#labels","p":4682},{"i":4704,"t":"Impact","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#impact","p":4682},{"i":4706,"t":"Severity","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#severity","p":4682},{"i":4708,"t":"Component impacts","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#component-impacts","p":4682},{"i":4710,"t":"Maintenance","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#maintenance","p":4682},{"i":4712,"t":"Return of POST requests","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#return-of-post-requests","p":4682},{"i":4714,"t":"Return of PATCH requests","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#return-of-patch-requests","p":4682},{"i":4716,"t":"PATCH vs PUT for updating resources","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#patch-vs-put-for-updating-resources","p":4682},{"i":4718,"t":"Authentication and authorization","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#authentication-and-authorization","p":4682},{"i":4721,"t":"Introduction","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#introduction","p":4720},{"i":4723,"t":"Motivation","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#motivation","p":4720},{"i":4725,"t":"Requirements","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#requirements","p":4720},{"i":4727,"t":"Options considered","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#options-considered","p":4720},{"i":4729,"t":"Decisions","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#decisions","p":4720},{"i":4731,"t":"Reference","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#reference","p":4720},{"i":4732,"t":"Outcome of the CSP Survey about Requirements for KaaS Observability","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#outcome-of-the-csp-survey-about-requirements-for-kaas-observability","p":4720},{"i":4735,"t":"Introduction","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#introduction","p":4734},{"i":4737,"t":"Definitions","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#definitions","p":4734},{"i":4739,"t":"Motivation","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#motivation","p":4734},{"i":4741,"t":"Design Considerations","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#design-considerations","p":4734},{"i":4743,"t":"Options","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#options","p":4734},{"i":4745,"t":"Decision","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#decision","p":4734},{"i":4747,"t":"Open questions","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#open-questions","p":4734},{"i":4749,"t":"Related Documents","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#related-documents","p":4734},{"i":4751,"t":"Conformance Tests","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#conformance-tests","p":4734},{"i":4754,"t":"Introduction","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#introduction","p":4753},{"i":4756,"t":"Definitions","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#definitions","p":4753},{"i":4758,"t":"Motivation","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#motivation","p":4753},{"i":4760,"t":"Design Considerations","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#design-considerations","p":4753},{"i":4762,"t":"Options","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#options","p":4753},{"i":4764,"t":"Open questions","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#open-questions","p":4753},{"i":4766,"t":"Decision","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#decision","p":4753},{"i":4768,"t":"Related Documents","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#related-documents","p":4753},{"i":4770,"t":"Conformance Tests","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#conformance-tests","p":4753},{"i":4777,"t":"Abstract","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#abstract","p":4776},{"i":4779,"t":"Terminology","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#terminology","p":4776},{"i":4781,"t":"Context","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#context","p":4776},{"i":4783,"t":"Decision","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#decision","p":4776},{"i":4785,"t":"Consequences","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#consequences","p":4776},{"i":4787,"t":"Related Documents","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#related-documents","p":4776},{"i":4790,"t":"Introduction","u":"/standards/scs-0412-v1-metering-json","h":"#introduction","p":4789},{"i":4792,"t":"Motivation","u":"/standards/scs-0412-v1-metering-json","h":"#motivation","p":4789},{"i":4794,"t":"Design Considerations","u":"/standards/scs-0412-v1-metering-json","h":"#design-considerations","p":4789},{"i":4796,"t":"Options considered","u":"/standards/scs-0412-v1-metering-json","h":"#options-considered","p":4789},{"i":4798,"t":"Open questions","u":"/standards/scs-0412-v1-metering-json","h":"#open-questions","p":4789},{"i":4800,"t":"Decision","u":"/standards/scs-0412-v1-metering-json","h":"#decision","p":4789},{"i":4802,"t":"Related Documents","u":"/standards/scs-0412-v1-metering-json","h":"#related-documents","p":4789},{"i":4804,"t":"Conformance Tests","u":"/standards/scs-0412-v1-metering-json","h":"#conformance-tests","p":4789},{"i":4807,"t":"Introduction","u":"/standards/scs-XXXX-vN-standard-template","h":"#introduction","p":4806},{"i":4809,"t":"Terminology","u":"/standards/scs-XXXX-vN-standard-template","h":"#terminology","p":4806},{"i":4811,"t":"Motivation","u":"/standards/scs-XXXX-vN-standard-template","h":"#motivation","p":4806},{"i":4813,"t":"Design Considerations","u":"/standards/scs-XXXX-vN-standard-template","h":"#design-considerations","p":4806},{"i":4815,"t":"Options considered","u":"/standards/scs-XXXX-vN-standard-template","h":"#options-considered","p":4806},{"i":4817,"t":"Open questions","u":"/standards/scs-XXXX-vN-standard-template","h":"#open-questions","p":4806},{"i":4819,"t":"Standard","u":"/standards/scs-XXXX-vN-standard-template","h":"#standard","p":4806},{"i":4821,"t":"Related Documents","u":"/standards/scs-XXXX-vN-standard-template","h":"#related-documents","p":4806},{"i":4823,"t":"Conformance Tests","u":"/standards/scs-XXXX-vN-standard-template","h":"#conformance-tests","p":4806},{"i":4828,"t":"Welcome to the User Documentation of the Sovereign Cloud Stack (SCS)","u":"/user-docs/","h":"#welcome-to-the-user-documentation-of-the-sovereign-cloud-stack-scs","p":4827},{"i":4832,"t":"Basic components","u":"/user-docs/application-examples/opendesk-on-scs/configuration","h":"#basic-components","p":4830},{"i":4834,"t":"Apps","u":"/user-docs/application-examples/opendesk-on-scs/configuration","h":"#apps","p":4830},{"i":4842,"t":"Clone the openDesk repository","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#clone-the-opendesk-repository","p":4840},{"i":4844,"t":"Add settings for your environment","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#add-settings-for-your-environment","p":4840},{"i":4846,"t":"Choose your components","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#choose-your-components","p":4840},{"i":4848,"t":"Basic configuration","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#basic-configuration","p":4840},{"i":4850,"t":"Namespace","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#namespace","p":4840},{"i":4852,"t":"Deploy an ingress resource inside the namespace","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#deploy-an-ingress-resource-inside-the-namespace","p":4840},{"i":4854,"t":"Deployment","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#deployment","p":4840},{"i":4856,"t":"First login","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#first-login","p":4840},{"i":4858,"t":"Deploy the desired apps","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#deploy-the-desired-apps","p":4840},{"i":4866,"t":"Preparation of your local environment","u":"/user-docs/application-examples/opendesk-on-scs/requirements","h":"#preparation-of-your-local-environment","p":4864},{"i":4867,"t":"Command line tools","u":"/user-docs/application-examples/opendesk-on-scs/requirements","h":"#command-line-tools","p":4864},{"i":4869,"t":"KUBECONFIG","u":"/user-docs/application-examples/opendesk-on-scs/requirements","h":"#kubeconfig","p":4864},{"i":4871,"t":"Preparation of the nameserver","u":"/user-docs/application-examples/opendesk-on-scs/requirements","h":"#preparation-of-the-nameserver","p":4864},{"i":4873,"t":"Preparation of the Kubernetes cluster","u":"/user-docs/application-examples/opendesk-on-scs/requirements","h":"#preparation-of-the-kubernetes-cluster","p":4864},{"i":4874,"t":"Install cert-manager","u":"/user-docs/application-examples/opendesk-on-scs/requirements","h":"#install-cert-manager","p":4864},{"i":4876,"t":"Deploy a certificate issuer","u":"/user-docs/application-examples/opendesk-on-scs/requirements","h":"#deploy-a-certificate-issuer","p":4864},{"i":4878,"t":"Ingress Controller","u":"/user-docs/application-examples/opendesk-on-scs/requirements","h":"#ingress-controller","p":4864},{"i":4880,"t":"Prometheus","u":"/user-docs/application-examples/opendesk-on-scs/requirements","h":"#prometheus","p":4864},{"i":4882,"t":"Storage","u":"/user-docs/application-examples/opendesk-on-scs/requirements","h":"#storage","p":4864},{"i":4884,"t":"Optional: Credentials for a mail relay","u":"/user-docs/application-examples/opendesk-on-scs/requirements","h":"#optional-credentials-for-a-mail-relay","p":4864}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/6",[0,6.281,1,3.419,2,5.261]],["t/10",[3,4.422,4,6.281,5,5.394]],["t/11",[6,6.056,7,3.612]],["t/13",[3,3.844,4,5.46,8,5.46,9,5.872]],["t/14",[6,6.056,7,3.612]],["t/18",[10,5.735,11,4.422,12,4.474]],["t/20",[13,8.984]],["t/21",[14,5.952]],["t/23",[15,5.751]],["t/25",[15,4.733,16,4.322]],["t/27",[3,6.325]],["t/29",[17,9.662]],["t/30",[15,4.733,16,4.322]],["t/32",[3,6.325]],["t/35",[18,4.472,19,3.937,20,3.415,21,3.937]],["t/36",[21,5.331,22,7.393]],["t/38",[23,5.041,24,4.327,25,5.969]],["t/40",[26,6.846]],["t/43",[13,3.921,18,3.212,19,2.827,27,3.921,28,3.726,29,4.218,30,2.214]],["t/44",[31,7.393,32,5.472]],["t/46",[33,6.349,34,6.531]],["t/48",[18,5.145,19,4.529,20,3.928]],["t/51",[31,7.393,32,5.472]],["t/53",[33,6.349,34,6.531]],["t/55",[21,5.331,22,7.393]],["t/58",[2,5.261,35,6.755,36,4.2]],["t/60",[10,4.985,37,5.188,38,3.686,39,5.872]],["t/62",[40,8.984]],["t/63",[3,5.205,41,5.266]],["t/65",[40,4.828,42,5.193,43,5.193,44,5.193,45,5.193]],["t/67",[8,4.328,46,4.328,47,4.655,48,2.951,49,4.655,50,4.655]],["t/89",[30,2.727,51,3.229,52,3.26,53,2.773,54,3.326]],["t/91",[52,4.241,53,3.607,55,5.145]],["t/92",[30,3.083,51,3.651,52,3.686,56,3.802]],["t/94",[30,2.444,51,2.894,57,3.16,58,3.952,59,3.823,60,4.655]],["t/96",[53,3.607,57,4.587,61,3.928]],["t/98",[2,5.261,53,3.607,62,4.948]],["t/101",[63,5.549,64,6.281,65,6.755]],["t/102",[66,4.944,67,5.934]],["t/104",[67,5.934,68,4.376]],["t/106",[67,4.382,69,4.985,70,2.987,71,5.872]],["t/108",[18,5.145,19,4.529,67,5.041]],["t/110",[30,3.547,67,5.041,72,3.628]],["t/112",[30,3.547,67,5.041,73,4.948]],["t/114",[30,3.547,70,3.436,74,6.755]],["t/118",[75,7.393,76,7.393]],["t/120",[14,4.162,77,4.786,78,4.283]],["t/122",[79,6.349,80,7.393]],["t/126",[68,5.318]],["t/128",[81,4.376,82,6.531]],["t/129",[30,2.214,51,2.622,52,2.648,81,2.321,83,4.218,84,3.037,85,4.218]],["t/131",[30,2.727,51,3.229,57,3.526,86,4.409,87,3.739]],["t/133",[30,2.727,51,3.229,62,3.804,81,2.858,88,4.828]],["t/135",[19,3.12,30,2.444,51,2.894,78,2.951,89,3.717,90,3.203]],["t/138",[91,9.662]],["t/140",[92,9.662]],["t/142",[93,9.662]],["t/146",[94,6.531,95,5.205]],["t/148",[96,5.934,97,7.951]],["t/150",[98,5.46,99,2.836,100,4.823,101,4.985]],["t/152",[98,7.393,102,7.951]],["t/154",[14,4.898,103,6.349]],["t/156",[14,4.162,103,5.394,104,4.864]],["t/158",[105,5.394,106,6.755,107,4.283]],["t/160",[14,4.898,108,7.951]],["t/162",[109,5.735,110,6.755,111,5.041]],["t/166",[112,5.934,113,5.472]],["t/170",[114,9.662]],["t/172",[115,9.662]],["t/174",[116,9.662]],["t/176",[117,4.655,118,3.351,119,4.655,120,3.717,121,4.655,122,4.655]],["t/178",[123,9.662]],["t/180",[124,5.193,125,4.588,126,5.193,127,4.588,128,5.193]],["t/182",[30,3.083,127,7.591,129,5.188]],["t/184",[130,5.934,131,7.393]],["t/188",[37,7.025,132,7.393]],["t/189",[36,4.944,133,7.951]],["t/191",[36,4.944,134,7.951]],["t/193",[36,4.944,52,4.991]],["t/195",[135,7.025,136,7.951]],["t/196",[2,4.573,11,3.844,137,5.188,138,3.253]],["t/198",[139,5.19]],["t/204",[56,3.362,140,5.193,141,4.146,142,3.875,143,3.804]],["t/206",[56,5.148,144,7.951]],["t/208",[56,3.362,141,4.146,142,3.875,143,3.804,145,4.588]],["t/210",[56,5.148,146,7.951]],["t/211",[147,7.951,148,6.531]],["t/213",[148,6.531,149,7.951]],["t/215",[56,3.362,89,4.146,141,4.146,142,3.875,143,3.804]],["t/217",[56,3.802,142,4.382,150,5.46,151,5.46]],["t/219",[52,4.241,56,4.374,152,6.281]],["t/221",[56,4.374,153,6.755,154,3.928]],["t/223",[56,3.362,62,3.804,141,4.146,142,3.875,143,3.804]],["t/225",[56,4.374,150,6.281,155,6.755]],["t/227",[56,3.362,57,3.526,141,4.146,142,3.875,143,3.804]],["t/229",[56,5.148,156,7.025]],["t/230",[154,4.624,157,7.951]],["t/232",[156,7.025,158,7.951]],["t/234",[154,3.928,156,5.969,159,6.755]],["t/236",[56,4.374,57,4.587,152,6.281]],["t/238",[52,3.26,56,3.362,141,4.146,142,3.875,143,3.804]],["t/240",[52,3.26,56,3.362,142,3.875,143,3.804,160,5.193]],["t/242",[56,3.362,142,3.875,143,3.804,161,4.409,162,4.828]],["t/244",[28,5.188,56,3.802,143,4.301,162,5.46]],["t/246",[56,5.148,143,5.825]],["t/250",[130,5.934,131,7.393]],["t/254",[14,5.952]],["t/257",[163,5.872,164,5.872,165,5.872,166,5.872]],["t/263",[167,6.349,168,7.951]],["t/268",[3,3.4,169,3.955,170,5.193,171,4.266,172,5.193]],["t/270",[59,4.823,99,2.836,169,4.472,173,4.823]],["t/272",[112,5.041,169,5.145,174,4.715]],["t/279",[175,4.866]],["t/281",[1,2.356,52,2.922,139,2.5,176,4.328,177,3.823,178,3.823]],["t/283",[1,2.356,57,3.16,177,3.823,178,3.823,179,4.655,180,3.717]],["t/285",[62,3.804,181,4.828,182,5.193,183,2.405,184,3.955]],["t/287",[89,4.146,183,2.405,185,4.266,186,5.193,187,4.588]],["t/289",[154,5.619]],["t/290",[53,2.252,99,2.037,139,2.265,154,2.453,177,3.464,178,3.464,188,4.218]],["t/292",[81,3.232,90,4.041,139,3.154,189,4.823]],["t/294",[99,2.037,154,2.453,177,3.464,178,3.464,183,1.953,184,3.212,190,4.218]],["t/298",[52,3.686,177,4.823,178,4.823,191,5.188]],["t/300",[57,3.987,183,2.72,192,5.872,193,5.872]],["t/302",[95,5.205,194,7.951]],["t/304",[183,2.72,195,4.985,196,5.872,197,3.253]],["t/306",[154,3.928,183,3.129,198,6.755]],["t/308",[62,3.089,68,2.321,183,1.953,197,2.336,199,4.218,200,3.921,201,4.218]],["t/312",[20,3.415,30,3.083,52,3.686,202,3.524]],["t/314",[57,5.399,203,6.751]],["t/318",[52,4.991,204,6.192]],["t/320",[205,4.828,206,4.146,207,4.828,208,5.193,209,4.828]],["t/322",[191,4.588,204,4.044,210,4.828,211,4.828,212,5.193]],["t/324",[15,3.091,213,4.828,214,4.828,215,5.193,216,4.044]],["t/326",[15,2.511,20,2.453,21,2.827,32,2.902,216,3.285,217,3.921,218,2.453]],["t/328",[1,2.356,216,3.625,219,4.655,220,4.655,221,3.952,222,2.63]],["t/331",[]],["t/333",[66,4.944,113,5.472]],["t/335",[99,2.836,154,3.415,222,3.318,223,4.228]],["t/336",[202,4.772,224,5.472]],["t/338",[224,5.472,225,5.55]],["t/340",[1,2.972,11,3.844,226,5.188,227,4.985]],["t/342",[1,4.025,78,5.041]],["t/344",[38,4.991,228,7.025]],["t/346",[73,5.825,229,5.934]],["t/348",[230,4.855,231,7.951]],["t/350",[139,3.628,197,3.742,232,4.948]],["t/353",[233,6.126]],["t/355",[]],["t/357",[19,6.477]],["t/359",[169,4.472,234,5.46,235,5.872,236,3.987]],["t/361",[3,6.325]],["t/363",[171,7.937]],["t/365",[237,7.525]],["t/367",[238,7.715]],["t/371",[48,5.041,239,7.951]],["t/373",[]],["t/375",[68,4.376,233,5.041]],["t/377",[240,6.325]],["t/379",[241,7.715]],["t/387",[7,2.667,51,3.651,242,3.341,243,4.985]],["t/388",[7,3.069,138,3.742,244,6.281]],["t/390",[7,2.667,12,3.889,138,3.253,245,4.985]],["t/392",[99,3.84,246,7.951]],["t/394",[7,2.359,247,4.828,248,5.193,249,4.828,250,4.828]],["t/396",[7,3.032,118,3.037,138,2.336,218,2.453,251,4.218,252,4.218]],["t/399",[113,6.649]],["t/400",[7,3.612,138,4.404]],["t/402",[7,3.069,61,3.928,138,3.742]],["t/404",[7,2.667,138,3.253,253,4.301,254,4.472]],["t/406",[7,2.114,51,2.894,99,2.248,138,2.578,173,3.823,250,4.328]],["t/408",[7,3.069,138,3.742,255,5.549]],["t/410",[7,3.069,138,3.742,256,3.718]],["t/412",[7,2.359,138,2.876,253,3.804,254,3.955,256,2.858]],["t/414",[99,3.84,257,7.951]],["t/420",[7,3.903,138,3.253,218,3.415]],["t/422",[7,3.612,138,4.404]],["t/424",[7,3.069,138,3.742,258,6.281]],["t/426",[7,2.667,138,3.253,254,4.472,259,4.098]],["t/429",[7,2.667,61,3.415,78,3.723,138,3.253]],["t/431",[260,4.715,261,5.735,262,4.948]],["t/433",[78,5.041,261,6.751]],["t/437",[230,4.855,263,6.349]],["t/439",[51,3.229,52,3.26,242,2.955,264,4.588,265,3.739]],["t/441",[51,3.651,57,3.987,79,4.688,230,3.585]],["t/445",[7,3.069,138,3.742,266,5.549]],["t/447",[7,3.069,138,3.742,267,4.241]],["t/449",[7,3.069,138,3.742,256,3.718]],["t/451",[7,3.069,61,3.928,138,3.742]],["t/453",[7,2.667,138,3.253,253,4.301,254,4.472]],["t/455",[12,3.889,267,3.686,268,4.823,269,4.041]],["t/458",[268,7.937]],["t/460",[268,6.531,270,5.148]],["t/462",[66,4.944,271,7.951]],["t/464",[23,5.041,154,3.928,268,5.549]],["t/467",[69,8.203]],["t/469",[81,5.318]],["t/470",[233,6.126]],["t/472",[72,3.628,230,4.124,272,5.735]],["t/474",[7,2.667,61,3.415,81,3.232,138,3.253]],["t/484",[175,4.866]],["t/486",[99,3.263,244,6.281,273,6.281]],["t/488",[18,5.145,230,4.124,274,6.755]],["t/490",[77,5.11,99,2.248,275,4.963,276,4.328]],["t/492",[277,7.211]],["t/495",[278,7.951,279,5.634]],["t/497",[279,5.634,280,7.951]],["t/505",[260,4.715,261,5.735,262,4.948]],["t/507",[78,5.041,261,6.751]],["t/509",[245,6.751,268,6.531]],["t/511",[7,3.069,242,3.844,243,5.735]],["t/513",[221,4.409,275,3.574,276,4.828,281,5.193,282,4.828]],["t/517",[33,5.394,283,6.755,284,6.755]],["t/521",[72,5.19]],["t/523",[171,7.937]],["t/525",[238,7.715]],["t/527",[285,7.358]],["t/529",[238,6.349,269,5.472]],["t/532",[7,3.612,138,4.404]],["t/534",[14,4.898,30,4.175]],["t/536",[7,3.069,138,3.742,224,4.649]],["t/538",[7,3.069,30,3.547,286,5.735]],["t/540",[7,3.069,30,3.547,249,6.281]],["t/542",[30,3.547,287,3.587,288,3.292]],["t/544",[7,1.751,16,2.096,30,2.024,202,2.314,218,2.242,253,4.552,289,2.524]],["t/546",[30,3.083,58,4.985,253,4.301,255,4.823]],["t/548",[30,3.547,63,5.549,87,4.864]],["t/550",[30,4.175,290,5.205]],["t/554",[154,5.619]],["t/556",[291,6.531,292,6.531]],["t/559",[59,6.531,86,6.751]],["t/561",[293,8.984]],["t/563",[173,6.531,294,7.025]],["t/565",[295,6.056,296,6.531]],["t/567",[30,3.083,297,5.872,298,3.987,299,5.872]],["t/569",[7,2.667,138,3.253,242,3.341,300,4.573]],["t/573",[233,6.126]],["t/575",[7,3.069,301,5.969,302,3.402]],["t/577",[292,4.266,303,4.828,304,4.828,305,3.804,306,4.409]],["t/579",[222,3.318,303,5.46,304,5.46,306,4.985]],["t/581",[255,4.266,307,4.409,308,7.291,309,4.828]],["t/583",[222,3.318,306,4.985,310,5.872,311,5.872]],["t/585",[7,2.114,138,2.578,242,2.649,267,2.922,308,4.328,309,4.328]],["t/587",[1,2.356,7,2.114,12,3.083,242,2.649,243,3.952,312,4.655]],["t/589",[7,2.667,243,4.985,313,4.472,314,4.382]],["t/592",[175,4.866]],["t/594",[315,5.045]],["t/596",[316,6.649]],["t/598",[15,4.733,317,6.349]],["t/599",[7,1.916,15,2.511,52,2.648,78,2.674,138,2.336,230,2.575,317,3.367]],["t/601",[7,1.916,15,2.511,57,2.864,78,2.674,138,2.336,290,2.761,317,3.367]],["t/603",[7,1.495,15,1.959,62,2.41,78,2.086,118,2.369,138,1.823,161,2.794,317,2.627,318,2.703,319,3.291]],["t/605",[7,1.613,15,2.114,41,2.352,78,2.251,89,2.835,99,1.715,138,1.967,227,3.014,317,2.835]],["t/607",[7,1.916,15,2.511,138,2.336,145,3.726,183,1.953,317,3.367,320,2.793]],["t/609",[30,3.547,321,6.755,322,6.755]],["t/610",[323,6.281,324,6.755,325,5.735]],["t/612",[326,4.556,327,5.634]],["t/613",[118,3.739,120,4.146,174,3.625,253,3.804,328,3.739]],["t/615",[118,5.725,174,5.55]],["t/617",[118,4.864,253,4.948,328,4.864]],["t/619",[72,5.19]],["t/621",[72,4.271,329,5.041]],["t/623",[273,8.984]],["t/625",[292,6.531,330,5.55]],["t/627",[21,4.529,259,4.715,331,5.735]],["t/629",[275,6.649]],["t/631",[332,7.715]],["t/633",[333,8.537]],["t/635",[334,8.537]],["t/637",[269,4.649,335,5.969,336,6.755]],["t/640",[295,7.358]],["t/642",[275,4.649,295,5.145,337,5.145]],["t/644",[275,5.472,333,7.025]],["t/646",[275,5.472,332,6.349]],["t/648",[275,5.472,334,7.025]],["t/650",[269,5.472,275,5.472]],["t/652",[81,4.376,295,6.056]],["t/654",[7,3.069,138,3.742,242,3.844]],["t/658",[66,6.008]],["t/660",[72,4.271,295,6.056]],["t/663",[175,4.866]],["t/665",[295,7.358]],["t/667",[240,5.205,295,6.056]],["t/670",[81,5.318]],["t/672",[7,3.069,138,3.742,242,3.844]],["t/674",[275,4.649,295,5.145,337,5.145]],["t/676",[275,5.472,333,7.025]],["t/678",[275,5.472,332,6.349]],["t/680",[275,5.472,334,7.025]],["t/682",[269,5.472,275,5.472]],["t/685",[233,6.126]],["t/687",[61,3.928,81,3.718,247,6.281]],["t/689",[7,2.667,242,3.341,338,5.46,339,5.872]],["t/691",[5,6.349,81,4.376]],["t/693",[81,2.321,99,2.037,161,3.581,340,4.218,341,4.218,342,4.218,343,4.218]],["t/697",[233,6.126]],["t/698",[7,3.612,289,5.205]],["t/700",[25,5.188,344,5.46,345,5.46,346,5.188]],["t/702",[167,6.349,347,6.751]],["t/704",[90,5.472,347,6.751]],["t/707",[5,5.394,348,3.791,349,4.786]],["t/709",[5,5.394,349,4.786,350,4.649]],["t/713",[32,4.649,224,4.649,236,4.587]],["t/714",[338,8.984]],["t/716",[351,6.192,352,7.951]],["t/718",[353,6.755,354,5.969,355,5.969]],["t/720",[16,4.322,356,7.951]],["t/721",[189,4.823,357,4.573,358,4.688,359,5.872]],["t/723",[360,7.525]],["t/725",[361,9.662]],["t/729",[233,6.126]],["t/731",[7,3.612,289,5.205]],["t/733",[25,5.188,344,5.46,345,5.46,346,5.188]],["t/735",[167,6.349,347,6.751]],["t/737",[90,5.472,347,6.751]],["t/744",[233,6.126]],["t/746",[5,6.349,81,4.376]],["t/750",[233,6.126]],["t/752",[5,4.688,81,3.232,225,4.098,355,5.188]],["t/771",[1,4.025,362,7.951]],["t/773",[1,4.025,363,7.951]],["t/775",[1,4.025,364,7.951]],["t/777",[11,3.844,139,3.154,330,4.098,365,5.188]],["t/779",[1,3.419,139,3.628,366,5.549]],["t/781",[1,2.135,11,2.761,330,2.944,335,3.726,337,3.212,367,3.921,368,4.218]],["t/783",[1,2.135,11,2.761,99,2.037,330,2.944,369,3.921,370,4.218,371,4.218]],["t/785",[26,4.786,256,3.718,372,5.969]],["t/787",[1,2.356,26,3.298,99,2.248,256,2.562,365,4.113,373,3.823]],["t/789",[26,3.298,99,2.248,202,2.794,203,3.952,224,3.203,256,2.562]],["t/791",[202,4.772,372,7.025]],["t/793",[63,5.549,202,4.054,224,4.649]],["t/795",[203,4.985,224,4.041,225,4.098,372,5.188]],["t/797",[1,2.628,19,3.481,129,4.588,258,4.828,374,4.146]],["t/799",[1,2.628,11,3.4,19,3.481,99,2.508,374,4.146]],["t/801",[1,2.135,11,2.761,19,2.827,99,2.037,294,3.726,369,3.921,374,3.367]],["t/803",[55,4.472,296,4.823,366,4.823,375,5.46]],["t/811",[267,4.991,376,7.951]],["t/813",[267,4.241,291,5.549,377,6.281]],["t/815",[267,4.241,378,5.145,379,6.281]],["t/817",[267,4.991,380,7.951]],["t/819",[267,4.241,279,4.786,381,5.145]],["t/821",[267,4.241,279,4.786,287,3.587]],["t/823",[267,4.241,287,3.587,382,4.474]],["t/825",[267,4.241,287,3.587,302,3.402]],["t/827",[253,4.948,267,4.241,383,4.374]],["t/829",[218,4.624,267,4.991]],["t/831",[214,8.984]],["t/833",[384,7.025,385,7.393]],["t/835",[204,7.525]],["t/837",[386,6.957]],["t/839",[387,6.065]],["t/841",[388,6.256]],["t/843",[389,7.715]],["t/845",[390,8.984]],["t/847",[391,7.358]],["t/849",[392,9.662]],["t/851",[388,5.148,393,5.148]],["t/853",[394,8.984]],["t/858",[68,5.318]],["t/860",[16,3.192,20,3.415,288,2.861,386,4.228]],["t/862",[23,5.041,24,4.327,395,6.281]],["t/864",[18,6.056,19,5.331]],["t/866",[267,4.991,288,3.875]],["t/868",[1,3.419,139,3.628,288,3.292]],["t/870",[288,3.292,396,5.549,397,5.735]],["t/872",[288,2.861,396,4.823,397,4.985,398,4.823]],["t/874",[399,7.358]],["t/876",[14,5.952]],["t/877",[288,3.875,400,7.393]],["t/879",[41,5.266,288,3.875]],["t/882",[66,6.008]],["t/884",[81,5.318]],["t/886",[14,5.952]],["t/889",[66,6.008]],["t/891",[81,5.318]],["t/893",[14,5.952]],["t/895",[267,6.065]],["t/897",[95,4.422,174,4.715,401,6.281]],["t/900",[66,6.008]],["t/902",[81,5.318]],["t/904",[402,6.846]],["t/905",[403,8.203]],["t/907",[404,8.203]],["t/909",[14,5.952]],["t/911",[403,8.203]],["t/913",[404,8.203]],["t/915",[329,5.041,405,6.192]],["t/917",[325,6.751,406,7.025]],["t/919",[407,5.634,408,6.056]],["t/923",[409,8.203]],["t/925",[260,4.098,262,4.301,410,4.301,411,4.301]],["t/927",[120,4.688,412,4.688,413,4.573,414,3.802]],["t/929",[61,4.624,415,7.025]],["t/931",[20,3.02,21,3.481,84,3.739,410,3.804,411,3.804]],["t/933",[20,3.02,21,3.481,72,2.789,410,3.804,411,3.804]],["t/935",[269,5.472,416,6.751]],["t/937",[417,5.735,418,5.969,419,5.969]],["t/939",[12,4.474,420,4.587,421,5.969]],["t/941",[320,4.474,422,5.969,423,5.394]],["t/943",[105,5.394,424,5.041,425,5.261]],["t/945",[318,6.531,349,5.634]],["t/947",[426,7.025,427,5.634]],["t/948",[428,8.537]],["t/950",[329,5.041,427,5.634]],["t/952",[103,5.394,236,4.587,429,4.786]],["t/954",[430,8.537]],["t/956",[431,8.537]],["t/958",[184,3.955,432,3.679,433,4.588,434,4.588,435,4.588]],["t/960",[357,5.261,436,5.969,437,5.735]],["t/962",[438,7.937]],["t/964",[439,6.56]],["t/966",[440,7.025,441,6.056]],["t/968",[407,5.634,442,7.025]],["t/970",[20,3.415,41,3.889,314,4.382,414,3.802]],["t/972",[348,5.423]],["t/974",[277,7.211]],["t/975",[38,4.991,443,6.531]],["t/977",[444,7.025,445,6.192]],["t/979",[148,5.549,262,4.948,446,5.969]],["t/982",[305,7.078]],["t/984",[389,7.715]],["t/985",[447,7.025,448,6.349]],["t/987",[449,8.984]],["t/989",[450,8.984]],["t/990",[451,6.751,452,6.751]],["t/992",[391,7.358]],["t/994",[453,8.984]],["t/998",[66,6.008]],["t/1000",[81,5.318]],["t/1002",[402,6.846]],["t/1004",[14,5.952]],["t/1006",[329,5.041,405,6.192]],["t/1011",[66,4.944,454,7.951]],["t/1012",[7,3.612,455,5.205]],["t/1014",[68,5.318]],["t/1015",[7,3.612,224,5.472]],["t/1017",[7,3.612,326,4.556]],["t/1019",[99,3.84,223,5.725]],["t/1021",[456,5.549,457,6.755,458,6.755]],["t/1024",[459,8.984]],["t/1026",[54,4.327,267,4.241,287,3.587]],["t/1027",[279,5.634,287,4.222]],["t/1029",[287,3.118,382,3.889,460,5.872,461,5.188]],["t/1031",[24,5.093,287,4.222]],["t/1033",[287,4.222,383,5.148]],["t/1035",[154,3.928,222,3.817,287,3.587]],["t/1037",[99,3.263,223,4.864,462,5.735]],["t/1039",[279,5.634,287,4.222]],["t/1041",[287,3.587,382,4.474,461,5.969]],["t/1043",[383,6.256]],["t/1045",[227,5.735,463,5.549,464,5.041]],["t/1047",[227,3.273,330,2.691,407,2.732,463,3.167,464,2.877,465,3.585,466,3.585,467,3.856]],["t/1049",[383,5.148,468,7.951]],["t/1051",[469,9.662]],["t/1057",[7,2.359,218,3.02,270,3.362,302,2.615,387,3.26]],["t/1058",[7,2.667,20,3.415,218,3.415,470,5.872]],["t/1059",[1,2.628,7,3.562,138,2.876,218,3.02]],["t/1062",[270,3.802,302,2.957,387,3.686,388,3.802]],["t/1065",[270,3.802,302,2.957,387,3.686,471,5.872]],["t/1068",[270,3.802,302,2.957,387,3.686,472,5.872]],["t/1070",[270,3.802,302,2.957,387,3.686,473,4.688]],["t/1072",[20,3.415,270,3.802,302,2.957,387,3.686]],["t/1074",[7,3.612,20,4.624]],["t/1076",[16,3.672,20,3.928,113,4.649]],["t/1078",[16,3.192,20,3.415,113,4.041,174,4.098]],["t/1080",[20,4.624,474,7.951]],["t/1083",[206,4.688,270,3.802,302,2.957,387,3.686]],["t/1085",[270,3.802,302,2.957,387,3.686,475,5.872]],["t/1087",[270,3.802,302,2.957,387,3.686,476,4.688]],["t/1088",[270,3.802,302,2.957,387,3.686,438,4.823]],["t/1090",[30,2.727,270,3.362,302,2.615,387,3.26,477,4.266]],["t/1091",[30,2.024,36,2.397,270,2.496,302,1.942,383,2.496,387,2.42,478,2.877,479,3.273]],["t/1092",[30,2.214,36,2.622,270,2.731,302,2.124,387,2.648,480,3.921,481,3.921]],["t/1094",[270,3.802,302,2.957,387,3.686,482,5.872]],["t/1097",[113,5.472,382,5.266]],["t/1098",[113,4.649,279,4.786,381,5.145]],["t/1099",[24,5.093,113,5.472]],["t/1100",[113,5.472,383,5.148]],["t/1101",[113,5.472,483,7.393]],["t/1104",[279,5.634,287,4.222]],["t/1106",[287,4.222,382,5.266]],["t/1108",[24,5.093,287,4.222]],["t/1110",[287,4.222,383,5.148]],["t/1112",[287,4.222,302,4.005]],["t/1114",[484,8.203]],["t/1115",[302,4.005,484,6.751]],["t/1117",[484,6.751,485,7.951]],["t/1119",[484,6.751,486,7.951]],["t/1121",[383,4.374,487,5.261,488,6.755]],["t/1123",[287,4.222,382,5.266]],["t/1124",[279,5.634,287,4.222]],["t/1125",[236,5.399,287,4.222]],["t/1126",[287,4.222,302,4.005]],["t/1127",[287,4.222,414,5.148]],["t/1128",[287,4.222,383,5.148]],["t/1130",[381,6.056,382,5.266]],["t/1131",[279,5.634,381,6.056]],["t/1132",[236,5.399,381,6.056]],["t/1133",[302,4.005,381,6.056]],["t/1134",[381,6.056,414,5.148]],["t/1135",[381,6.056,383,5.148]],["t/1137",[461,5.188,489,5.872,490,5.872,491,4.382]],["t/1145",[328,4.864,354,5.969,492,5.969]],["t/1146",[493,9.662]],["t/1148",[494,9.662]],["t/1150",[441,6.056,492,7.025]],["t/1156",[16,3.192,19,3.937,68,3.232,495,4.688]],["t/1158",[16,3.672,496,3.871,497,6.755]],["t/1162",[498,7.393,499,6.751]],["t/1164",[167,7.715]],["t/1166",[500,9.662]],["t/1168",[16,4.322,501,6.751]],["t/1170",[502,6.531,503,5.331]],["t/1172",[96,5.934,502,6.531]],["t/1174",[393,5.148,504,5.472]],["t/1176",[154,4.624,505,7.025]],["t/1178",[393,4.374,432,4.786,506,4.374]],["t/1180",[429,6.846]],["t/1182",[20,2.707,72,2.5,388,3.014,429,3.298,507,3.952,508,4.655]],["t/1184",[7,3.069,388,4.374,509,5.549]],["t/1186",[12,5.266,241,6.349]],["t/1188",[510,5.825,511,7.951]],["t/1190",[99,3.263,287,3.587,512,6.755]],["t/1194",[405,6.192,502,6.531]],["t/1196",[154,5.619]],["t/1198",[402,6.846]],["t/1208",[302,4.866]],["t/1210",[513,9.662]],["t/1211",[378,6.056,514,7.393]],["t/1212",[48,5.041,514,7.393]],["t/1213",[255,5.549,287,3.587,292,5.549]],["t/1217",[72,3.154,87,4.228,242,3.341,506,3.802]],["t/1219",[51,4.2,52,4.241,305,4.948]],["t/1221",[51,3.651,57,3.987,298,3.987,515,5.872]],["t/1223",[51,2.397,62,2.824,72,2.071,87,2.776,282,3.585,506,2.496,516,3.078,517,3.273]],["t/1225",[51,2.894,72,2.5,89,3.717,174,3.249,263,3.717,518,4.113]],["t/1227",[99,3.84,519,7.951]],["t/1229",[26,5.634,105,6.349]],["t/1231",[72,3.628,87,4.864,520,6.755]],["t/1233",[72,3.628,87,4.864,521,6.755]],["t/1235",[522,9.662]],["t/1237",[118,4.864,329,4.283,523,4.786]],["t/1241",[30,3.083,524,5.46,525,5.188,526,5.872]],["t/1243",[232,5.825,527,6.349]],["t/1245",[174,5.55,528,7.025]],["t/1247",[232,4.948,529,6.755,530,6.755]],["t/1249",[174,3.625,232,3.804,523,3.679,527,4.146,531,5.193]],["t/1251",[507,6.751,509,6.531]],["t/1253",[532,9.662]],["t/1256",[230,4.855,332,6.349]],["t/1258",[118,4.864,517,5.735,533,6.281]],["t/1260",[254,6.056,534,7.393]],["t/1262",[20,3.928,254,5.145,535,6.281]],["t/1265",[536,9.662]],["t/1267",[154,5.619]],["t/1269",[184,6.056,537,7.951]],["t/1270",[487,6.192,538,7.951]],["t/1272",[539,9.662]],["t/1274",[540,6.755,541,6.755,542,6.755]],["t/1284",[24,4.327,543,6.755,544,6.755]],["t/1291",[265,5.725,288,3.875]],["t/1293",[408,7.358]],["t/1294",[226,7.025,408,6.056]],["t/1296",[95,3.4,99,2.508,154,3.02,408,3.955,545,3.955]],["t/1298",[383,5.148,487,6.192]],["t/1300",[16,3.672,72,3.628,269,4.649]],["t/1302",[16,4.322,72,4.271]],["t/1304",[16,3.672,546,5.735,547,6.755]],["t/1306",[72,3.154,527,4.688,548,5.188,549,5.872]],["t/1311",[52,2.648,288,2.055,375,3.921,516,3.367,550,3.581,551,4.218,552,4.218]],["t/1313",[173,3.464,329,4.233,553,4.218,554,3.367,555,3.921,556,4.218]],["t/1315",[269,5.472,557,7.951]],["t/1323",[302,3.402,558,4.474,559,4.948]],["t/1325",[216,6.192,560,6.751]],["t/1330",[561,7.951,562,4.463]],["t/1337",[563,7.393,564,7.951]],["t/1339",[563,7.393,565,7.393]],["t/1343",[90,4.041,222,3.318,357,4.573,566,5.872]],["t/1345",[72,5.19]],["t/1347",[300,7.525]],["t/1349",[567,9.662]],["t/1351",[20,5.619]],["t/1353",[30,3.547,289,4.422,473,5.394]],["t/1357",[568,6.531,569,7.951]],["t/1358",[570,9.662]],["t/1360",[571,9.662]],["t/1362",[12,3.889,287,3.118,382,3.889,572,5.872]],["t/1364",[378,6.056,573,6.531]],["t/1366",[378,6.056,510,5.825]],["t/1368",[349,4.786,358,5.394,574,5.549]],["t/1370",[389,3.717,432,3.298,575,4.655,576,4.655,577,4.113,578,4.655]],["t/1372",[99,2.248,358,5.758,510,3.41,574,3.823,579,4.655]],["t/1374",[242,2.649,288,2.268,358,3.717,548,4.113,574,3.823,580,3.625]],["t/1376",[287,2.471,358,3.717,382,3.083,574,3.823,581,4.328,582,4.328]],["t/1378",[349,3.298,358,3.717,389,3.717,574,3.823,581,4.328,582,4.328]],["t/1380",[46,4.828,68,2.858,242,2.955,288,2.531,510,3.804]],["t/1382",[349,4.161,548,5.188,573,4.823,583,5.872]],["t/1384",[24,4.327,77,4.786,584,6.755]],["t/1388",[585,9.662]],["t/1390",[105,7.715]],["t/1394",[498,7.393,499,6.751]],["t/1396",[167,7.715]],["t/1398",[72,4.271,383,5.148]],["t/1400",[72,4.271,586,7.951]],["t/1402",[72,3.154,523,4.161,587,5.872,588,5.872]],["t/1404",[99,2.836,589,5.46,590,4.382,591,5.872]],["t/1406",[16,3.192,501,4.985,592,5.872,593,5.188]],["t/1408",[593,5.969,594,6.755,595,6.755]],["t/1410",[502,4.823,503,3.937,593,5.188,596,5.872]],["t/1412",[24,5.093,72,4.271]],["t/1414",[222,2.934,287,2.757,393,3.362,504,3.574,597,4.588]],["t/1416",[222,2.179,287,2.047,328,2.776,393,2.496,504,4.276,545,2.936,577,3.406]],["t/1418",[95,2.524,222,2.179,287,2.047,328,2.776,393,2.496,504,4.276,545,2.936]],["t/1420",[99,2.836,589,5.46,590,4.382,598,5.872]],["t/1422",[393,5.148,523,5.634]],["t/1424",[429,6.846]],["t/1426",[72,2.789,429,3.679,495,4.146,599,5.193,600,4.828]],["t/1428",[7,3.069,95,4.422,601,5.735]],["t/1430",[289,5.205,307,6.751]],["t/1432",[388,3.802,546,4.985,602,4.573,603,5.872]],["t/1434",[604,7.951,605,7.393]],["t/1436",[427,5.634,605,7.393]],["t/1438",[388,5.148,405,6.192]],["t/1440",[7,3.069,388,4.374,509,5.549]],["t/1442",[132,6.281,329,4.283,606,6.281]],["t/1450",[72,3.628,410,4.948,427,4.786]],["t/1463",[81,2.858,99,2.508,287,2.757,288,2.531,320,3.439]],["t/1465",[607,5.725,608,7.951]],["t/1469",[16,3.672,222,3.817,302,3.402]],["t/1471",[15,3.091,51,3.229,52,3.26,61,3.02,242,2.955]],["t/1473",[51,3.229,57,3.526,72,2.789,245,4.409,383,3.362]],["t/1475",[51,3.229,62,3.804,287,2.757,302,2.615,609,4.828]],["t/1477",[16,2.823,51,3.229,89,4.146,222,2.934,302,2.615]],["t/1479",[16,2.293,51,2.622,145,3.726,260,2.944,302,2.124,610,4.218,611,4.218]],["t/1485",[30,3.547,68,3.718,233,4.283]],["t/1487",[81,4.376,607,5.725]],["t/1488",[86,5.735,87,4.864,554,5.394]],["t/1490",[77,3.679,81,2.858,298,3.526,300,4.044,398,4.266]],["t/1492",[81,3.232,225,4.098,298,3.987,612,4.823]],["t/1498",[68,3.718,81,3.718,492,5.969]],["t/1500",[72,3.628,87,4.864,613,6.281]],["t/1504",[16,4.322,501,6.751]],["t/1506",[16,3.672,425,5.261,614,6.281]],["t/1508",[16,3.672,425,5.261,615,6.755]],["t/1516",[7,3.612,218,4.624]],["t/1526",[16,4.322,501,6.751]],["t/1528",[287,3.587,424,5.041,616,5.969]],["t/1530",[423,7.715]],["t/1533",[287,3.587,424,5.041,617,5.549]],["t/1535",[439,6.56]],["t/1537",[609,8.984]],["t/1539",[16,4.322,302,4.005]],["t/1541",[225,5.55,302,4.005]],["t/1543",[287,4.222,618,6.751]],["t/1545",[84,3.739,118,3.739,619,5.193,620,4.266,621,5.193]],["t/1546",[524,6.281,525,5.969,622,5.969]],["t/1551",[507,8.203]],["t/1553",[623,9.662]],["t/1554",[348,5.423]],["t/1556",[350,6.649]],["t/1558",[624,8.984]],["t/1560",[15,3.495,30,3.083,242,3.341,351,4.573]],["t/1562",[36,4.944,625,7.951]],["t/1563",[626,9.662]],["t/1565",[627,7.025,628,7.951]],["t/1568",[366,6.531,629,7.025]],["t/1570",[230,4.124,388,4.374,630,5.735]],["t/1572",[174,5.55,439,5.399]],["t/1573",[7,2.667,66,3.651,509,4.823,631,5.46]],["t/1575",[314,5.041,632,6.281,633,5.549]],["t/1577",[634,6.281,635,5.735,636,5.394]],["t/1579",[287,3.587,618,5.735,637,5.261]],["t/1581",[112,4.382,504,4.041,638,5.46,639,5.46]],["t/1582",[24,3.326,504,3.574,640,4.828,641,4.828,642,4.828]],["t/1584",[236,3.526,504,3.574,643,4.828,644,4.409,645,3.955]],["t/1586",[313,4.472,504,4.041,645,4.472,646,4.301]],["t/1588",[21,2.38,99,1.715,337,2.704,504,2.443,645,4.426,646,4.257,647,3.301]],["t/1590",[21,2.827,99,2.037,645,5.084,648,2.321,649,3.581,650,3.581]],["t/1592",[99,2.248,644,3.952,648,2.562,649,3.952,650,3.952,651,4.328]],["t/1594",[94,5.549,393,4.374,439,4.587]],["t/1595",[7,2.667,151,5.46,328,4.228,393,3.802]],["t/1597",[393,5.077,637,4.044,652,5.193,653,5.193]],["t/1599",[393,4.374,432,4.786,506,4.374]],["t/1601",[393,4.374,654,6.281,655,5.969]],["t/1602",[393,5.148,656,5.634]],["t/1604",[287,3.118,393,3.802,637,4.573,656,4.161]],["t/1606",[335,3.726,393,2.731,654,3.921,656,2.988,657,4.218,658,4.218,659,3.464]],["t/1608",[109,5.735,660,6.281,661,5.549]],["t/1610",[393,5.148,662,7.393]],["t/1611",[48,4.283,439,4.587,602,5.261]],["t/1612",[48,4.283,602,5.261,663,5.735]],["t/1614",[664,5.735,665,5.394,666,4.864]],["t/1616",[19,3.481,48,3.292,602,4.044,635,4.409,636,4.146]],["t/1618",[23,3.875,597,4.588,667,4.828,668,4.828,669,4.828]],["t/1620",[223,2.776,636,3.078,665,4.962,670,3.585,671,3.585,672,3.003,673,3.585]],["t/1622",[439,4.587,503,4.529,674,6.281]],["t/1624",[72,4.271,503,5.331]],["t/1626",[111,5.041,663,5.735,675,5.394]],["t/1628",[666,5.725,676,7.393]],["t/1630",[242,3.844,503,4.529,677,5.969]],["t/1632",[495,5.394,503,4.529,678,5.261]],["t/1634",[503,5.331,627,7.025]],["t/1636",[260,4.098,503,3.937,546,4.985,665,4.688]],["t/1638",[24,2.982,111,3.474,242,2.649,286,3.952,337,3.545,675,3.717]],["t/1640",[111,3.474,424,3.474,503,4.835,675,3.717,679,4.328]],["t/1642",[680,7.025,681,7.393]],["t/1643",[99,2.508,387,3.26,388,3.362,462,4.409,682,4.828]],["t/1645",[7,3.069,388,4.374,683,6.281]],["t/1647",[7,2.359,388,3.362,425,4.044,607,3.739,683,4.828]],["t/1649",[684,6.192,685,7.025]],["t/1651",[130,5.934,296,6.531]],["t/1656",[107,5.041,686,6.531]],["t/1658",[245,6.751,686,6.531]],["t/1660",[99,3.263,269,4.649,686,5.549]],["t/1662",[1,1.951,104,2.776,154,2.242,183,1.786,302,1.942,330,2.691,491,2.877,686,3.167]],["t/1664",[154,3.415,686,4.823,687,5.872,688,5.872]],["t/1668",[689,7.937]],["t/1670",[690,9.662]],["t/1672",[225,6.744]],["t/1674",[691,8.537]],["t/1678",[378,7.358]],["t/1680",[292,6.531,378,6.056]],["t/1682",[378,6.056,692,7.951]],["t/1685",[107,6.126]],["t/1687",[535,7.393,693,7.393]],["t/1690",[689,7.937]],["t/1691",[329,6.126]],["t/1693",[689,4.823,694,8.592,695,5.188]],["t/1695",[225,6.744]],["t/1697",[534,8.984]],["t/1701",[36,4.2,480,6.281,481,6.281]],["t/1703",[36,3.651,383,3.802,478,4.382,479,4.985]],["t/1706",[242,3.844,383,4.374,413,5.261]],["t/1708",[287,3.587,382,4.474,618,5.735]],["t/1710",[287,3.118,382,3.889,432,4.161,506,3.802]],["t/1712",[287,3.587,382,4.474,656,4.786]],["t/1715",[16,4.322,656,5.634]],["t/1717",[406,7.025,696,7.951]],["t/1719",[16,3.672,697,5.969,698,5.969]],["t/1722",[16,3.672,697,5.969,698,5.969]],["t/1727",[90,5.472,287,4.222]],["t/1729",[90,4.041,287,3.118,298,3.987,699,5.872]],["t/1731",[16,2.823,30,2.727,109,4.409,382,3.439,495,4.146]],["t/1733",[16,2.53,30,2.444,262,3.41,382,3.083,700,4.655,701,4.655]],["t/1735",[702,7.951,703,6.056]],["t/1737",[16,3.672,697,5.969,698,5.969]],["t/1739",[378,6.056,379,7.393]],["t/1742",[423,4.688,451,4.985,704,5.872,705,5.872]],["t/1744",[32,4.649,451,5.735,691,5.969]],["t/1747",[66,6.008]],["t/1749",[81,5.318]],["t/1751",[14,5.952]],["t/1753",[267,6.065]],["t/1755",[95,4.422,174,4.715,401,6.281]],["t/1759",[68,5.318]],["t/1761",[16,3.192,20,3.415,288,2.861,386,4.228]],["t/1763",[23,5.041,24,4.327,395,6.281]],["t/1765",[18,6.056,19,5.331]],["t/1767",[267,4.991,288,3.875]],["t/1769",[1,3.419,139,3.628,288,3.292]],["t/1771",[288,3.292,396,5.549,397,5.735]],["t/1773",[288,2.861,396,4.823,397,4.985,398,4.823]],["t/1775",[399,7.358]],["t/1777",[14,5.952]],["t/1778",[288,3.875,400,7.393]],["t/1780",[41,5.266,288,3.875]],["t/1784",[66,6.008]],["t/1786",[81,5.318]],["t/1788",[402,6.846]],["t/1789",[403,8.203]],["t/1791",[404,8.203]],["t/1793",[14,5.952]],["t/1795",[403,8.203]],["t/1797",[404,8.203]],["t/1799",[329,5.041,405,6.192]],["t/1801",[325,6.751,406,7.025]],["t/1803",[407,5.634,408,6.056]],["t/1806",[66,6.008]],["t/1808",[81,5.318]],["t/1810",[14,5.952]],["t/1814",[409,8.203]],["t/1816",[260,4.098,262,4.301,410,4.301,411,4.301]],["t/1818",[120,4.688,412,4.688,413,4.573,414,3.802]],["t/1820",[61,4.624,415,7.025]],["t/1822",[20,3.02,21,3.481,84,3.739,410,3.804,411,3.804]],["t/1824",[20,3.02,21,3.481,72,2.789,410,3.804,411,3.804]],["t/1826",[269,5.472,416,6.751]],["t/1828",[417,5.735,418,5.969,419,5.969]],["t/1830",[12,4.474,420,4.587,421,5.969]],["t/1832",[320,4.474,422,5.969,423,5.394]],["t/1834",[105,5.394,424,5.041,425,5.261]],["t/1836",[318,6.531,349,5.634]],["t/1838",[426,7.025,427,5.634]],["t/1839",[428,8.537]],["t/1841",[329,5.041,427,5.634]],["t/1843",[103,5.394,236,4.587,429,4.786]],["t/1845",[430,8.537]],["t/1847",[431,8.537]],["t/1849",[184,3.955,432,3.679,433,4.588,434,4.588,435,4.588]],["t/1851",[357,5.261,436,5.969,437,5.735]],["t/1853",[438,7.937]],["t/1855",[439,6.56]],["t/1857",[440,7.025,441,6.056]],["t/1859",[407,5.634,442,7.025]],["t/1861",[20,3.415,41,3.889,314,4.382,414,3.802]],["t/1863",[348,5.423]],["t/1865",[277,7.211]],["t/1866",[38,4.991,443,6.531]],["t/1868",[444,7.025,445,6.192]],["t/1870",[148,5.549,262,4.948,446,5.969]],["t/1873",[305,7.078]],["t/1875",[389,7.715]],["t/1876",[447,7.025,448,6.349]],["t/1878",[449,8.984]],["t/1880",[450,8.984]],["t/1881",[451,6.751,452,6.751]],["t/1883",[391,7.358]],["t/1885",[453,8.984]],["t/1889",[66,6.008]],["t/1891",[81,5.318]],["t/1893",[402,6.846]],["t/1895",[14,5.952]],["t/1897",[329,5.041,405,6.192]],["t/1901",[366,6.531,629,7.025]],["t/1903",[230,4.124,388,4.374,630,5.735]],["t/1905",[277,7.211]],["t/1907",[414,6.256]],["t/1908",[429,6.846]],["t/1910",[41,6.399]],["t/1911",[441,6.056,601,6.751]],["t/1913",[388,5.148,441,6.056]],["t/1915",[174,5.55,439,5.399]],["t/1916",[7,2.667,66,3.651,509,4.823,631,5.46]],["t/1918",[314,5.041,632,6.281,633,5.549]],["t/1920",[634,6.281,635,5.735,636,5.394]],["t/1922",[287,3.587,618,5.735,637,5.261]],["t/1924",[112,4.382,504,4.041,638,5.46,639,5.46]],["t/1925",[24,3.326,504,3.574,640,4.828,641,4.828,642,4.828]],["t/1927",[236,3.526,504,3.574,643,4.828,644,4.409,645,3.955]],["t/1929",[313,4.472,504,4.041,645,4.472,646,4.301]],["t/1931",[21,2.38,99,1.715,337,2.704,504,2.443,645,4.426,646,4.257,647,3.301]],["t/1933",[21,2.827,99,2.037,645,5.084,648,2.321,649,3.581,650,3.581]],["t/1935",[99,2.248,644,3.952,648,2.562,649,3.952,650,3.952,651,4.328]],["t/1937",[94,5.549,393,4.374,439,4.587]],["t/1939",[109,5.735,660,6.281,661,5.549]],["t/1941",[393,5.148,662,7.393]],["t/1942",[48,4.283,439,4.587,602,5.261]],["t/1943",[48,4.283,602,5.261,663,5.735]],["t/1945",[664,5.735,665,5.394,666,4.864]],["t/1947",[19,3.481,48,3.292,602,4.044,635,4.409,636,4.146]],["t/1949",[23,3.875,597,4.588,667,4.828,668,4.828,669,4.828]],["t/1951",[223,2.776,636,3.078,665,4.962,670,3.585,671,3.585,672,3.003,673,3.585]],["t/1953",[439,4.587,503,4.529,674,6.281]],["t/1955",[72,4.271,503,5.331]],["t/1957",[111,5.041,663,5.735,675,5.394]],["t/1959",[666,5.725,676,7.393]],["t/1961",[242,3.844,503,4.529,677,5.969]],["t/1963",[495,5.394,503,4.529,678,5.261]],["t/1965",[503,5.331,627,7.025]],["t/1967",[260,4.098,503,3.937,546,4.985,665,4.688]],["t/1969",[24,2.982,111,3.474,242,2.649,286,3.952,337,3.545,675,3.717]],["t/1971",[111,3.474,424,3.474,503,4.835,675,3.717,679,4.328]],["t/1973",[680,7.025,681,7.393]],["t/1974",[684,6.192,685,7.025]],["t/1976",[130,5.934,296,6.531]],["t/1980",[99,2.836,329,3.723,706,3.937,707,5.872]],["t/1982",[21,5.331,708,7.951]],["t/1983",[298,6.56]],["t/1985",[298,5.399,709,7.393]],["t/1987",[448,7.715]],["t/1989",[296,7.937]],["t/1991",[617,6.531,710,7.393]],["t/1993",[183,3.683,443,6.531]],["t/1995",[260,4.098,427,4.161,443,4.823,711,4.823]],["t/1997",[183,3.683,298,5.399]],["t/2001",[712,9.662]],["t/2002",[478,5.934,568,6.531]],["t/2004",[234,6.281,659,5.549,713,6.755]],["t/2006",[714,6.755,715,6.281,716,6.755]],["t/2008",[717,7.951,718,7.951]],["t/2010",[715,7.393,719,7.393]],["t/2012",[456,7.937]],["t/2014",[720,9.662]],["t/2016",[174,6.744]],["t/2018",[721,9.662]],["t/2020",[24,6.189]],["t/2026",[68,5.318]],["t/2028",[54,6.189]],["t/2030",[81,5.318]],["t/2031",[81,3.718,320,4.474,464,5.041]],["t/2033",[81,4.376,607,5.725]],["t/2035",[14,5.952]],["t/2036",[16,3.192,32,4.041,722,5.872,723,5.46]],["t/2038",[724,8.984]],["t/2040",[331,5.735,487,5.261,725,6.281]],["t/2042",[288,3.292,726,5.735,727,6.755]],["t/2044",[441,7.358]],["t/2046",[728,9.662]],["t/2047",[99,2.508,383,3.362,413,4.044,729,5.193,730,5.193]],["t/2049",[277,7.211]],["t/2051",[78,6.126]],["t/2054",[230,4.855,731,7.393]],["t/2056",[173,6.531,230,4.855]],["t/2058",[230,4.855,332,6.349]],["t/2060",[195,5.735,230,4.124,496,3.871]],["t/2062",[81,5.318]],["t/2064",[14,5.952]],["t/2066",[154,5.619]],["t/2068",[87,4.228,230,3.585,398,4.823,496,3.365]],["t/2073",[16,3.672,432,4.786,506,4.374]],["t/2075",[225,4.098,288,2.861,432,4.161,506,3.802]],["t/2077",[16,3.672,118,4.864,222,3.817]],["t/2078",[300,7.525]],["t/2079",[289,6.325]],["t/2081",[689,7.937]],["t/2083",[94,6.531,95,5.205]],["t/2085",[100,6.531,101,6.751]],["t/2087",[101,8.203]],["t/2089",[107,5.041,402,5.634]],["t/2091",[732,9.662]],["t/2092",[76,7.393,384,7.025]],["t/2093",[733,8.203]],["t/2095",[81,5.318]],["t/2097",[329,4.283,637,5.261,646,4.948]],["t/2099",[318,4.266,329,3.292,646,3.804,734,5.193,735,4.828]],["t/2101",[3,4.422,646,4.948,736,6.755]],["t/2103",[275,4.041,298,3.987,313,4.472,709,5.46]],["t/2105",[329,4.283,735,6.281,737,6.755]],["t/2107",[135,5.969,254,5.145,738,6.281]],["t/2109",[154,2.707,169,3.545,238,3.717,733,3.952,739,4.328,740,4.655]],["t/2113",[169,6.056,616,7.025]],["t/2115",[81,5.318]],["t/2116",[90,5.472,305,5.825]],["t/2118",[255,6.531,285,6.056]],["t/2120",[79,5.394,407,4.786,741,5.969]],["t/2122",[154,4.624,682,7.393]],["t/2124",[277,7.211]],["t/2125",[59,5.549,517,5.735,622,5.969]],["t/2127",[59,4.266,99,2.508,517,4.409,533,4.828,742,5.193]],["t/2129",[34,4.823,189,4.823,427,4.161,622,5.188]],["t/2131",[171,5.549,238,5.394,743,6.755]],["t/2136",[366,6.531,629,7.025]],["t/2138",[672,5.261,744,6.755,745,6.755]],["t/2141",[351,5.261,739,6.281,746,5.735]],["t/2143",[118,4.864,229,5.041,388,4.374]],["t/2145",[242,3.341,391,4.472,445,4.573,747,3.495]],["t/2149",[38,4.991,691,7.025]],["t/2151",[617,6.531,748,7.951]],["t/2154",[693,8.984]],["t/2160",[55,3.955,84,3.739,388,3.362,601,4.409,749,3.739]],["t/2164",[425,6.192,750,7.951]],["t/2176",[68,5.318]],["t/2177",[11,5.205,32,5.472]],["t/2179",[11,5.205,12,5.266]],["t/2181",[751,7.937]],["t/2183",[222,5.46]],["t/2185",[14,5.952]],["t/2187",[269,5.472,416,6.751]],["t/2189",[32,5.472,723,7.393]],["t/2191",[752,6.755,753,6.281,754,6.755]],["t/2193",[724,8.984]],["t/2195",[33,6.349,560,6.751]],["t/2197",[14,4.898,680,7.025]],["t/2198",[218,4.624,413,6.192]],["t/2200",[290,5.205,424,5.934]],["t/2202",[16,4.322,222,4.493]],["t/2204",[16,4.322,441,6.056]],["t/2206",[388,3.802,393,3.802,432,4.161,506,3.802]],["t/2208",[55,3.955,84,3.739,388,3.362,601,4.409,749,3.739]],["t/2210",[20,3.415,78,3.723,99,2.836,755,4.382]],["t/2212",[277,7.211]],["t/2213",[672,6.192,689,6.531]],["t/2215",[77,4.786,260,4.715,756,6.281]],["t/2217",[757,8.203]],["t/2218",[72,5.19]],["t/2220",[496,5.537]],["t/2222",[230,4.855,758,6.349]],["t/2224",[16,4.322,759,6.751]],["t/2226",[26,5.634,293,7.393]],["t/2228",[238,6.349,760,7.025]],["t/2235",[463,7.937]],["t/2237",[68,5.318]],["t/2239",[761,9.662]],["t/2241",[448,7.715]],["t/2243",[288,3.292,613,6.281,762,6.281]],["t/2245",[762,6.281,763,6.755,764,6.281]],["t/2247",[70,2.987,288,2.861,764,5.46,765,5.46]],["t/2249",[288,3.875,726,6.751]],["t/2251",[90,5.472,242,4.524]],["t/2253",[90,4.649,506,4.374,710,6.281]],["t/2255",[32,4.649,565,6.281,766,6.755]],["t/2257",[767,7.951,768,7.951]],["t/2262",[288,3.292,516,5.394,769,6.281]],["t/2264",[242,4.524,349,5.634]],["t/2265",[24,3.761,77,4.161,99,2.836,389,4.688]],["t/2267",[99,3.263,747,4.021,770,6.755]],["t/2269",[81,2.858,242,2.955,349,3.679,516,4.146,769,4.828]],["t/2273",[448,5.394,771,6.755,772,6.755]],["t/2275",[738,8.984]],["t/2277",[184,7.358]],["t/2278",[733,8.203]],["t/2280",[773,9.662]],["t/2284",[68,3.718,407,4.786,499,5.735]],["t/2286",[130,5.041,562,3.791,648,3.718]],["t/2288",[48,4.283,242,3.844,648,3.718]],["t/2290",[48,4.283,402,4.786,648,3.718]],["t/2292",[48,4.283,464,5.041,648,3.718]],["t/2294",[48,4.283,99,3.263,648,3.718]],["t/2298",[68,3.718,407,4.786,499,5.735]],["t/2300",[130,5.041,562,3.791,648,3.718]],["t/2302",[48,4.283,242,3.844,648,3.718]],["t/2304",[48,4.283,402,4.786,648,3.718]],["t/2306",[48,4.283,464,5.041,648,3.718]],["t/2308",[48,4.283,99,3.263,648,3.718]],["t/2318",[774,7.358]],["t/2320",[775,6.325]],["t/2322",[15,3.495,66,3.651,236,3.987,678,4.573]],["t/2324",[99,2.836,288,2.861,348,3.296,554,4.688]],["t/2326",[24,2.982,99,2.248,288,2.268,348,2.612,386,3.351,776,4.328]],["t/2328",[99,2.037,218,2.453,236,2.864,348,3.747,391,3.212,747,2.511]],["t/2330",[348,3.791,747,4.021,777,5.735]],["t/2332",[348,3.791,747,4.021,778,5.261]],["t/2334",[99,2.248,236,3.16,288,2.268,348,2.612,386,3.351,747,2.771]],["t/2336",[288,2.531,348,2.915,386,3.739,747,3.091,777,4.409]],["t/2338",[99,2.248,288,2.268,348,2.612,386,3.351,747,2.771,778,3.625]],["t/2340",[99,2.508,285,3.955,348,2.915,554,4.146,779,4.146]],["t/2342",[96,4.382,523,4.161,779,4.688,780,5.46]],["t/2344",[350,6.649]],["t/2346",[285,4.472,348,3.296,350,4.041,779,4.688]],["t/2348",[288,2.861,348,3.296,350,4.041,781,5.46]],["t/2350",[288,2.861,348,3.296,350,4.041,523,4.161]],["t/2352",[288,2.861,348,3.296,350,4.041,747,3.495]],["t/2354",[16,2.53,348,4.048,350,3.203,391,3.545,747,2.771]],["t/2356",[757,8.203]],["t/2357",[90,3.203,288,2.268,746,3.952,747,2.771,778,3.625,782,4.113]],["t/2359",[96,3.147,288,2.055,523,2.988,747,2.511,783,3.921,784,3.921,785,3.921]],["t/2367",[222,5.46]],["t/2369",[32,5.472,206,6.349]],["t/2371",[191,7.025,483,7.393]],["t/2373",[1,4.809,216,5.261]],["t/2375",[68,4.376,233,5.041]],["t/2377",[240,6.325]],["t/2379",[241,7.715]],["t/2381",[617,4.823,786,5.872,787,5.188,788,5.872]],["t/2385",[774,7.358]],["t/2387",[775,6.325]],["t/2389",[15,3.495,66,3.651,236,3.987,678,4.573]],["t/2391",[99,2.836,288,2.861,348,3.296,554,4.688]],["t/2393",[24,2.982,99,2.248,288,2.268,348,2.612,386,3.351,776,4.328]],["t/2395",[99,2.037,218,2.453,236,2.864,348,3.747,391,3.212,747,2.511]],["t/2397",[348,3.791,747,4.021,777,5.735]],["t/2399",[348,3.791,747,4.021,778,5.261]],["t/2401",[99,2.248,236,3.16,288,2.268,348,2.612,386,3.351,747,2.771]],["t/2403",[288,2.531,348,2.915,386,3.739,747,3.091,777,4.409]],["t/2405",[99,2.248,288,2.268,348,2.612,386,3.351,747,2.771,778,3.625]],["t/2407",[99,2.508,285,3.955,348,2.915,554,4.146,779,4.146]],["t/2409",[96,4.382,523,4.161,779,4.688,780,5.46]],["t/2411",[350,6.649]],["t/2413",[285,4.472,348,3.296,350,4.041,779,4.688]],["t/2415",[288,2.861,348,3.296,350,4.041,781,5.46]],["t/2417",[288,2.861,348,3.296,350,4.041,523,4.161]],["t/2419",[288,2.861,348,3.296,350,4.041,747,3.495]],["t/2421",[16,2.53,348,4.048,350,3.203,391,3.545,747,2.771]],["t/2423",[757,8.203]],["t/2424",[90,3.203,288,2.268,746,3.952,747,2.771,778,3.625,782,4.113]],["t/2426",[96,3.147,288,2.055,523,2.988,747,2.511,783,3.921,784,3.921,785,3.921]],["t/2430",[1,1.288,72,1.367,206,2.032,216,1.982,221,2.16,229,1.899,323,4.083,327,1.803,349,1.803,558,1.685,789,2.545,790,2.545,791,2.545]],["t/2436",[459,8.984]],["t/2438",[95,3.4,558,3.439,633,4.266,792,5.193,793,5.193]],["t/2440",[72,4.271,491,5.934]],["t/2442",[204,4.044,218,3.02,301,4.588,559,3.804,794,4.588]],["t/2444",[104,4.228,204,4.573,301,5.188,746,4.985]],["t/2446",[104,3.351,302,3.632,558,3.083,794,4.113,795,4.655]],["t/2448",[61,4.624,796,7.951]],["t/2450",[242,4.524,558,5.266]],["t/2452",[15,3.495,242,3.341,302,2.957,558,3.889]],["t/2454",[15,2.771,104,3.351,125,4.113,302,2.344,558,3.083,797,4.113]],["t/2456",[104,4.228,302,2.957,558,3.889,798,5.872]],["t/2458",[61,3.928,302,3.402,558,4.474]],["t/2460",[15,3.495,302,2.957,558,3.889,612,4.823]],["t/2462",[3,3.844,302,2.957,558,3.889,612,4.823]],["t/2464",[48,3.723,302,2.957,558,3.889,612,4.823]],["t/2466",[104,3.739,125,4.588,302,2.615,558,3.439,612,4.266]],["t/2468",[799,6.56]],["t/2474",[233,6.126]],["t/2476",[72,5.19]],["t/2477",[800,9.662]],["t/2479",[169,7.358]],["t/2481",[496,4.556,801,7.951]],["t/2484",[802,8.984]],["t/2486",[11,4.422,648,3.718,803,6.281]],["t/2488",[1,3.419,320,4.474,804,5.735]],["t/2490",[69,6.751,82,6.531]],["t/2492",[259,6.744]],["t/2494",[272,8.203]],["t/2498",[176,4.828,202,3.117,203,4.409,237,4.044,804,4.409]],["t/2500",[237,4.573,726,4.985,805,5.872,806,5.872]],["t/2502",[96,4.382,237,4.573,807,5.872,808,5.872]],["t/2504",[15,3.495,61,3.415,104,4.228,809,5.872]],["t/2505",[61,3.415,711,4.823,810,5.46,811,5.872]],["t/2507",[812,7.951,813,7.951]],["t/2509",[15,4.733,814,7.951]],["t/2511",[237,4.573,545,4.472,782,5.188,804,4.985]],["t/2513",[61,4.624,815,7.025]],["t/2515",[815,8.537]],["t/2517",[398,6.531,815,7.025]],["t/2519",[78,4.283,559,4.948,787,5.969]],["t/2521",[816,8.537]],["t/2524",[802,8.984]],["t/2526",[289,4.422,648,3.718,803,6.281]],["t/2528",[289,3.844,491,4.382,648,3.232,817,5.188]],["t/2530",[289,3.844,648,3.232,678,4.573,817,5.188]],["t/2532",[491,5.041,678,5.261,818,5.735]],["t/2534",[288,3.292,360,5.261,818,5.735]],["t/2536",[360,5.261,491,5.041,818,5.735]],["t/2538",[61,3.415,360,4.573,412,4.688,818,4.985]],["t/2540",[69,6.751,82,6.531]],["t/2542",[259,6.744]],["t/2544",[272,8.203]],["t/2548",[819,9.662]],["t/2550",[820,9.662]],["t/2552",[821,9.662]],["t/2554",[2,4.573,765,5.46,822,5.872,823,5.872]],["t/2556",[357,6.192,824,7.951]],["t/2558",[655,7.025,825,7.393]],["t/2562",[233,6.126]],["t/2564",[3,5.205,63,6.531]],["t/2566",[329,5.041,826,7.951]],["t/2568",[222,5.46]],["t/2571",[827,9.662]],["t/2573",[817,8.537]],["t/2575",[590,5.041,828,6.755,829,6.755]],["t/2577",[218,4.624,289,5.205]],["t/2579",[259,5.55,830,7.951]],["t/2581",[7,3.562,30,2.727,138,2.876,218,3.02]],["t/2583",[256,5.318]],["t/2585",[799,6.56]],["t/2589",[225,5.55,360,6.192]],["t/2591",[61,4.624,360,6.192]],["t/2593",[237,6.192,360,6.192]],["t/2595",[289,5.205,831,7.951]],["t/2597",[655,7.025,825,7.393]],["t/2601",[19,5.331,832,7.393]],["t/2609",[233,6.126]],["t/2611",[7,2.114,84,3.351,289,3.047,305,3.41,473,3.717,833,4.655]],["t/2613",[222,3.318,414,3.802,834,4.573,835,4.823]],["t/2615",[32,4.041,34,4.823,414,3.802,834,4.573]],["t/2621",[224,4.041,414,3.802,495,4.688,836,4.161]],["t/2623",[726,5.735,836,4.786,837,5.969]],["t/2625",[16,3.672,836,4.786,838,6.755]],["t/2631",[113,6.649]],["t/2633",[233,6.126]],["t/2635",[81,3.718,834,5.261,835,5.549]],["t/2639",[233,6.126]],["t/2641",[7,1.751,77,4.403,99,1.862,222,2.179,223,2.776,330,2.691,839,3.585]],["t/2643",[7,1.916,99,2.037,222,2.383,223,3.037,387,4.191,473,3.367]],["t/2645",[202,3.524,222,3.318,414,3.802,455,3.844]],["t/2646",[20,5.619]],["t/2648",[388,6.256]],["t/2652",[233,6.126]],["t/2654",[7,3.069,289,4.422,305,4.948]],["t/2656",[222,3.318,414,3.802,834,4.573,835,4.823]],["t/2658",[32,4.041,34,4.823,414,3.802,834,4.573]],["t/2662",[154,5.619]],["t/2664",[14,5.952]],["t/2667",[233,6.126]],["t/2669",[7,1.751,77,4.403,99,1.862,222,2.179,223,2.776,330,2.691,839,3.585]],["t/2671",[7,1.916,99,2.037,222,2.383,223,3.037,387,4.191,473,3.367]],["t/2673",[222,3.318,414,3.802,666,4.228,703,4.472]],["t/2675",[32,4.041,429,4.161,666,4.228,703,4.472]],["t/2681",[664,6.751,840,6.751]],["t/2683",[841,9.662]],["t/2685",[664,8.203]],["t/2689",[842,8.537]],["t/2691",[18,6.056,19,5.331]],["t/2693",[99,3.263,183,3.129,266,5.549]],["t/2694",[183,3.129,328,4.864,843,6.281]],["t/2696",[183,3.129,843,6.281,844,6.755]],["t/2698",[476,5.394,845,6.755,846,6.755]],["t/2700",[77,2.988,260,2.944,262,3.089,264,3.726,476,5.33,847,3.921]],["t/2702",[264,4.588,476,4.146,837,4.588,847,4.828,848,4.828]],["t/2704",[99,3.263,288,3.292,300,5.261]],["t/2706",[37,8.537]],["t/2708",[26,4.786,99,3.263,849,6.281]],["t/2711",[409,6.751,832,7.393]],["t/2713",[183,3.683,850,7.393]],["t/2715",[842,7.025,851,7.951]],["t/2717",[491,5.041,685,5.969,852,6.755]],["t/2722",[66,6.008]],["t/2724",[14,5.952]],["t/2726",[72,5.19]],["t/2727",[72,4.271,289,5.205]],["t/2729",[72,4.271,606,7.393]],["t/2731",[183,3.683,298,5.399]],["t/2733",[183,3.683,298,5.399]],["t/2735",[154,2.707,240,3.047,298,3.16,328,3.351,329,2.951,331,3.952]],["t/2737",[58,5.735,240,4.422,506,4.374]],["t/2739",[240,3.844,242,3.341,329,3.723,506,3.802]],["t/2741",[277,7.211]],["t/2742",[672,6.192,853,7.025]],["t/2744",[138,4.404,834,6.192]],["t/2746",[3,3.4,58,4.409,854,5.193,855,4.828,856,5.193]],["t/2748",[816,8.537]],["t/2753",[233,6.126]],["t/2755",[263,6.349,407,5.634]],["t/2759",[107,5.041,857,6.056]],["t/2761",[242,4.524,857,6.056]],["t/2763",[54,4.327,107,4.283,420,4.587]],["t/2765",[54,4.327,242,3.844,420,4.587]],["t/2767",[54,5.093,420,5.399]],["t/2769",[107,5.041,858,6.531]],["t/2771",[242,4.524,858,6.531]],["t/2773",[858,7.937]],["t/2775",[107,5.041,455,5.205]],["t/2777",[242,4.524,455,5.205]],["t/2779",[455,6.325]],["t/2781",[107,5.041,859,5.934]],["t/2783",[242,4.524,859,5.934]],["t/2785",[859,7.211]],["t/2787",[41,4.474,107,4.283,859,5.041]],["t/2789",[41,4.474,242,3.844,859,5.041]],["t/2791",[41,5.266,859,5.934]],["t/2797",[225,5.55,298,5.399]],["t/2799",[298,4.587,860,6.755,861,6.755]],["t/2801",[183,3.683,298,5.399]],["t/2805",[857,7.358]],["t/2807",[54,5.093,420,5.399]],["t/2809",[858,7.937]],["t/2811",[455,6.325]],["t/2813",[859,7.211]],["t/2815",[41,5.266,859,5.934]],["t/2821",[90,5.472,218,4.624]],["t/2823",[351,7.525]],["t/2825",[862,8.984]],["t/2827",[863,9.662]],["t/2829",[189,6.531,840,6.751]],["t/2831",[864,8.203]],["t/2833",[865,8.984]],["t/2838",[79,4.146,167,4.146,285,3.955,365,4.588,862,4.828]],["t/2840",[222,3.817,374,5.394,866,6.755]],["t/2842",[222,1.859,351,2.563,357,2.563,374,2.627,437,2.794,864,2.794,867,2.907,868,3.291,869,3.291,870,3.291]],["t/2844",[90,3.203,189,3.823,218,2.707,374,3.717,840,3.952,867,4.113]],["t/2848",[233,6.126]],["t/2850",[407,5.634,473,6.349]],["t/2852",[260,5.55,871,7.951]],["t/2854",[81,5.318]],["t/2856",[222,5.46]],["t/2858",[405,6.192,872,7.025]],["t/2860",[222,3.817,302,3.402,873,6.281]],["t/2862",[72,3.154,222,3.318,666,4.228,703,4.472]],["t/2868",[408,7.358]],["t/2870",[429,6.846]],["t/2872",[874,9.662]],["t/2876",[285,7.358]],["t/2878",[51,4.2,81,3.718,875,6.755]],["t/2880",[407,6.846]],["t/2882",[222,5.46]],["t/2884",[600,7.393,876,7.393]],["t/2888",[455,6.325]],["t/2890",[66,4.944,455,5.205]],["t/2891",[87,5.725,222,4.493]],["t/2893",[799,6.56]],["t/2905",[135,5.969,877,6.755,878,6.755]],["t/2907",[211,7.393,879,7.951]],["t/2909",[99,3.84,218,4.624]],["t/2917",[1,2.972,218,3.415,666,4.228,703,4.472]],["t/2919",[26,5.634,256,4.376]],["t/2921",[1,2.972,666,4.228,703,4.472,840,4.985]],["t/2923",[26,5.634,256,4.376]],["t/2925",[799,6.56]],["t/2929",[72,4.271,329,5.041]],["t/2931",[54,5.093,880,7.393]],["t/2947",[409,8.203]],["t/2949",[260,4.098,262,4.301,410,4.301,411,4.301]],["t/2951",[120,4.688,412,4.688,413,4.573,414,3.802]],["t/2953",[61,4.624,415,7.025]],["t/2955",[20,3.02,21,3.481,84,3.739,410,3.804,411,3.804]],["t/2957",[20,3.02,21,3.481,72,2.789,410,3.804,411,3.804]],["t/2959",[269,5.472,416,6.751]],["t/2961",[417,5.735,418,5.969,419,5.969]],["t/2963",[12,4.474,420,4.587,421,5.969]],["t/2965",[320,4.474,422,5.969,423,5.394]],["t/2967",[105,5.394,424,5.041,425,5.261]],["t/2969",[318,6.531,349,5.634]],["t/2971",[426,7.025,427,5.634]],["t/2972",[428,8.537]],["t/2974",[329,5.041,427,5.634]],["t/2976",[103,5.394,236,4.587,429,4.786]],["t/2978",[430,8.537]],["t/2980",[431,8.537]],["t/2982",[184,3.955,432,3.679,433,4.588,434,4.588,435,4.588]],["t/2984",[357,5.261,436,5.969,437,5.735]],["t/2986",[438,7.937]],["t/2988",[439,6.56]],["t/2990",[440,7.025,441,6.056]],["t/2992",[407,5.634,442,7.025]],["t/2994",[20,3.415,41,3.889,314,4.382,414,3.802]],["t/2996",[348,5.423]],["t/2998",[277,7.211]],["t/2999",[38,4.991,443,6.531]],["t/3001",[444,7.025,445,6.192]],["t/3003",[148,5.549,262,4.948,446,5.969]],["t/3013",[775,6.325]],["t/3015",[240,6.325]],["t/3017",[1,4.89]],["t/3019",[228,7.025,881,5.825]],["t/3021",[55,6.056,749,5.725]],["t/3023",[230,4.855,265,5.725]],["t/3025",[41,6.399]],["t/3027",[228,7.025,237,6.192]],["t/3031",[52,3.686,72,3.154,882,5.872,883,5.872]],["t/3033",[205,7.393,884,7.951]],["t/3035",[210,7.393,885,7.951]],["t/3037",[213,7.393,886,7.951]],["t/3039",[217,7.393,887,7.951]],["t/3043",[775,6.325]],["t/3045",[266,6.531,760,7.025]],["t/3046",[169,6.056,760,7.025]],["t/3048",[103,5.394,429,4.786,837,5.969]],["t/3049",[429,4.161,438,4.823,476,4.688,848,5.46]],["t/3051",[20,3.928,314,5.041,414,4.374]],["t/3053",[427,6.846]],["t/3054",[427,5.634,888,7.025]],["t/3056",[216,7.525]],["t/3057",[84,4.228,206,4.688,560,4.985,758,4.688]],["t/3059",[527,4.688,755,4.382,889,5.188,890,4.382]],["t/3061",[38,3.686,560,4.985,881,4.301,891,5.872]],["t/3063",[16,3.672,892,6.755,893,6.755]],["t/3065",[224,5.472,225,5.55]],["t/3066",[66,4.2,894,6.281,895,6.281]],["t/3068",[896,6.531,897,7.951]],["t/3070",[139,5.19]],["t/3072",[849,7.393,898,7.951]],["t/3074",[230,4.855,265,5.725]],["t/3076",[30,2.444,38,2.922,107,2.951,881,3.41,890,3.474,895,4.328]],["t/3080",[775,6.325]],["t/3082",[15,2.771,290,3.047,455,3.047,899,3.625,900,2.982,901,3.16]],["t/3084",[240,4.422,506,4.374,901,4.587]],["t/3085",[61,3.928,900,4.327,902,4.649]],["t/3087",[1,2.628,78,3.292,755,3.875,900,3.326,902,3.574]],["t/3089",[496,4.556,903,6.192]],["t/3090",[7,3.612,302,4.005]],["t/3092",[387,6.065]],["t/3094",[656,6.846]],["t/3096",[904,7.078]],["t/3098",[648,4.376,905,6.192]],["t/3100",[38,4.991,906,6.349]],["t/3102",[139,4.271,197,4.404]],["t/3104",[230,4.855,265,5.725]],["t/3106",[30,2.444,38,2.922,107,2.951,881,3.41,890,3.474,907,4.655]],["t/3107",[101,4.985,787,5.188,901,3.987,908,5.46]],["t/3109",[73,7.078]],["t/3113",[775,6.325]],["t/3115",[15,2.771,290,3.047,455,3.047,899,3.625,900,2.982,901,3.16]],["t/3117",[240,4.422,506,4.374,901,4.587]],["t/3118",[61,3.928,900,4.327,902,4.649]],["t/3120",[1,1.951,6,2.936,7,1.751,78,2.444,302,1.942,755,2.877,900,2.47,902,2.653]],["t/3122",[496,4.556,903,6.192]],["t/3123",[7,3.612,302,4.005]],["t/3125",[387,6.065]],["t/3127",[656,6.846]],["t/3129",[904,7.078]],["t/3131",[648,4.376,905,6.192]],["t/3133",[38,4.991,906,6.349]],["t/3135",[139,4.271,197,4.404]],["t/3137",[230,4.855,265,5.725]],["t/3139",[30,2.444,38,2.922,107,2.951,881,3.41,890,3.474,909,4.655]],["t/3141",[73,7.078]],["t/3143",[910,7.715]],["t/3147",[775,6.325]],["t/3149",[15,2.771,290,3.047,455,3.047,899,3.625,900,2.982,901,3.16]],["t/3151",[240,4.422,506,4.374,901,4.587]],["t/3152",[61,3.928,900,4.327,902,4.649]],["t/3154",[1,1.951,6,2.936,7,1.751,78,2.444,302,1.942,755,2.877,900,2.47,902,2.653]],["t/3156",[496,4.556,903,6.192]],["t/3158",[656,6.846]],["t/3160",[904,7.078]],["t/3161",[84,4.864,387,4.241,904,4.948]],["t/3163",[648,4.376,905,6.192]],["t/3165",[38,4.991,906,6.349]],["t/3167",[139,4.271,197,4.404]],["t/3169",[230,4.855,265,5.725]],["t/3171",[30,2.444,38,2.922,107,2.951,881,3.41,890,3.474,911,4.655]],["t/3173",[73,7.078]],["t/3175",[910,7.715]],["t/3179",[775,6.325]],["t/3181",[15,2.771,290,3.047,455,3.047,899,3.625,900,2.982,901,3.16]],["t/3182",[202,5.799]],["t/3184",[225,5.55,302,4.005]],["t/3186",[7,3.069,138,3.742,749,4.864]],["t/3188",[61,3.928,912,5.394,913,3.899]],["t/3190",[1,1.665,6,2.506,7,1.495,11,2.154,78,2.086,302,1.657,755,2.456,900,2.108,902,2.264,914,3.291]],["t/3192",[3,5.205,491,5.934]],["t/3194",[496,4.556,903,6.192]],["t/3196",[656,6.846]],["t/3198",[904,7.078]],["t/3199",[84,4.864,387,4.241,904,4.948]],["t/3201",[648,4.376,905,6.192]],["t/3203",[38,4.991,906,6.349]],["t/3205",[139,4.271,197,4.404]],["t/3207",[230,4.855,265,5.725]],["t/3209",[30,2.444,38,2.922,107,2.951,881,3.41,890,3.474,915,4.655]],["t/3211",[73,7.078]],["t/3213",[910,7.715]],["t/3217",[775,6.325]],["t/3219",[15,2.771,290,3.047,455,3.047,899,3.625,900,2.982,901,3.16]],["t/3220",[202,5.799]],["t/3222",[836,6.846]],["t/3224",[61,5.619]],["t/3226",[912,7.715]],["t/3228",[240,4.422,506,4.374,901,4.587]],["t/3229",[61,3.928,900,4.327,902,4.649]],["t/3231",[1,1.951,6,2.936,7,1.751,78,2.444,302,1.942,755,2.877,900,2.47,902,2.653]],["t/3233",[302,2.957,394,5.46,558,3.889,749,4.228]],["t/3235",[218,3.928,749,4.864,888,5.969]],["t/3237",[206,4.146,207,4.828,209,4.828,749,3.739,916,5.193]],["t/3239",[496,4.556,903,6.192]],["t/3241",[656,6.846]],["t/3243",[904,7.078]],["t/3245",[648,4.376,905,6.192]],["t/3247",[202,4.054,648,3.718,917,6.755]],["t/3249",[38,4.991,906,6.349]],["t/3250",[107,2.674,218,2.453,558,2.793,577,3.726,749,3.037,775,2.761,918,4.218]],["t/3252",[53,5.16]],["t/3254",[518,5.969,901,4.587,919,6.755]],["t/3256",[912,7.715]],["t/3258",[139,4.271,197,4.404]],["t/3260",[230,4.855,265,5.725]],["t/3262",[30,2.444,38,2.922,107,2.951,881,3.41,890,3.474,920,4.655]],["t/3263",[202,5.799]],["t/3265",[836,6.846]],["t/3267",[912,7.715]],["t/3269",[73,7.078]],["t/3271",[910,7.715]],["t/3275",[775,6.325]],["t/3277",[15,2.771,290,3.047,455,3.047,899,3.625,900,2.982,901,3.16]],["t/3278",[202,5.799]],["t/3280",[836,6.846]],["t/3282",[240,4.422,506,4.374,901,4.587]],["t/3283",[61,3.928,900,4.327,902,4.649]],["t/3284",[202,5.799]],["t/3286",[1,1.951,6,2.936,7,1.751,78,2.444,302,1.942,755,2.877,900,2.47,902,2.653]],["t/3287",[218,3.415,749,4.228,888,5.188,921,5.188]],["t/3289",[202,2.794,320,3.083,749,3.351,804,3.952,836,3.298,921,4.113]],["t/3291",[1,2.628,314,3.875,414,3.362,749,3.739,921,4.588]],["t/3293",[230,3.171,505,4.588,666,3.739,703,3.955,922,5.193]],["t/3295",[836,6.846]],["t/3297",[912,7.715]],["t/3299",[496,4.556,903,6.192]],["t/3301",[656,6.846]],["t/3303",[904,7.078]],["t/3305",[648,4.376,905,6.192]],["t/3307",[139,4.271,197,4.404]],["t/3309",[230,4.855,265,5.725]],["t/3311",[30,2.444,38,2.922,107,2.951,881,3.41,890,3.474,923,4.655]],["t/3312",[912,7.715]],["t/3314",[836,6.846]],["t/3316",[479,6.751,507,6.751]],["t/3318",[73,7.078]],["t/3320",[30,4.175,924,7.951]],["t/3322",[910,7.715]],["t/3326",[775,6.325]],["t/3327",[15,2.771,290,3.047,455,3.047,899,3.625,900,2.982,901,3.16]],["t/3328",[240,4.422,506,4.374,901,4.587]],["t/3329",[61,3.928,900,4.327,902,4.649]],["t/3330",[1,1.951,6,2.936,7,1.751,78,2.444,302,1.942,755,2.877,900,2.47,902,2.653]],["t/3331",[496,4.556,903,6.192]],["t/3332",[656,6.846]],["t/3333",[904,7.078]],["t/3334",[648,4.376,905,6.192]],["t/3335",[38,4.991,906,6.349]],["t/3336",[139,4.271,197,4.404]],["t/3337",[230,4.855,265,5.725]],["t/3338",[30,2.444,38,2.922,107,2.951,881,3.41,890,3.474,925,4.655]],["t/3339",[73,7.078]],["t/3341",[910,7.715]],["t/3343",[112,5.934,174,5.55]],["t/3345",[23,5.934,94,6.531]],["t/3347",[81,4.376,327,5.634]],["t/3349",[53,4.246,291,6.531]],["t/3351",[72,3.154,81,3.232,327,4.161,328,4.228]],["t/3354",[53,4.246,775,5.205]],["t/3356",[66,4.944,926,7.393]],["t/3364",[100,6.531,927,7.393]],["t/3366",[11,4.422,330,4.715,373,5.549]],["t/3370",[100,6.531,927,7.393]],["t/3372",[11,4.422,330,4.715,373,5.549]],["t/3376",[68,3.232,185,4.823,313,4.472,853,5.188]],["t/3377",[1,3.419,202,4.054,928,5.969]],["t/3379",[171,3.823,183,2.156,432,3.298,506,3.014,929,4.655,930,4.655]],["t/3380",[1,3.419,202,4.054,928,5.969]],["t/3382",[185,4.823,414,3.802,931,5.872,932,5.872]],["t/3383",[1,3.419,202,4.054,928,5.969]],["t/3403",[183,2.72,256,3.232,496,3.365,933,4.098]],["t/3407",[183,2.72,256,3.232,496,3.365,933,4.098]],["t/3411",[183,2.72,256,3.232,496,3.365,933,4.098]],["t/3415",[256,3.718,496,3.871,933,4.715]],["t/3433",[12,2.553,154,2.242,202,2.314,223,2.776,420,2.618,445,3.003,836,2.732,933,2.691]],["t/3439",[183,2.72,256,3.232,496,3.365,933,4.098]],["t/3447",[183,2.72,256,3.232,496,3.365,933,4.098]],["t/3455",[1,1.665,16,1.789,139,1.767,183,1.524,202,1.975,256,1.811,496,1.886,648,1.811,751,2.703,933,2.297]],["t/3463",[256,2.858,302,2.615,496,2.976,558,3.439,933,3.625]],["t/3475",[183,2.72,256,3.232,496,3.365,933,4.098]],["t/3479",[183,2.72,256,3.232,496,3.365,933,4.098]],["t/3487",[183,2.72,256,3.232,496,3.365,933,4.098]],["t/3497",[256,3.718,496,3.871,933,4.715]],["t/3518",[175,4.866]],["t/3520",[68,5.318]],["t/3522",[11,3.844,53,3.136,137,5.188,139,3.154]],["t/3524",[53,4.246,54,5.093]],["t/3526",[53,4.246,646,5.825]],["t/3528",[934,9.662]],["t/3530",[263,7.715]],["t/3532",[316,5.472,857,6.056]],["t/3534",[78,4.283,857,5.145,935,6.755]],["t/3536",[332,5.394,857,5.145,936,6.281]],["t/3538",[857,5.145,904,6.959]],["t/3540",[937,9.662]],["t/3542",[36,4.944,938,5.472]],["t/3543",[187,7.025,936,7.393]],["t/3545",[187,5.969,424,5.041,939,6.755]],["t/3547",[326,4.556,562,4.463]],["t/3548",[290,6.325]],["t/3550",[940,8.984]],["t/3553",[175,4.866]],["t/3555",[315,5.045]],["t/3557",[51,3.651,52,3.686,423,4.688,941,5.872]],["t/3560",[175,4.866]],["t/3562",[315,5.045]],["t/3564",[53,4.246,354,7.025]],["t/3566",[942,7.951,943,7.951]],["t/3568",[63,6.531,325,6.751]],["t/3570",[637,6.192,944,7.951]],["t/3572",[55,6.056,256,4.376]],["t/3574",[30,2.444,82,3.823,195,3.952,646,3.41,945,7.212]],["t/3576",[36,4.944,938,5.472]],["t/3578",[26,6.846]],["t/3581",[175,4.866]],["t/3583",[315,5.045]],["t/3585",[1,2.972,66,3.651,67,4.382,139,3.154]],["t/3587",[232,4.948,270,4.374,775,4.422]],["t/3589",[130,4.382,263,4.688,550,4.985,946,5.872]],["t/3591",[947,7.025,948,7.393]],["t/3593",[1,3.419,232,4.948,949,5.969]],["t/3595",[233,5.041,950,6.531]],["t/3597",[290,5.205,950,6.531]],["t/3599",[950,6.531,951,7.951]],["t/3601",[313,6.056,950,6.531]],["t/3603",[183,3.129,223,4.864,950,5.549]],["t/3605",[753,7.393,952,7.951]],["t/3607",[263,7.715]],["t/3609",[326,4.556,562,4.463]],["t/3610",[329,5.041,646,5.825]],["t/3612",[88,6.281,232,4.948,953,6.755]],["t/3614",[259,6.744]],["t/3616",[36,4.944,938,5.472]],["t/3617",[940,8.984]],["t/3620",[175,4.866]],["t/3622",[1,2.972,3,3.844,104,4.228,620,4.823]],["t/3624",[267,6.065]],["t/3626",[1,2.972,79,4.688,104,4.228,954,5.46]],["t/3628",[1,2.972,79,4.688,954,5.46,955,5.872]],["t/3630",[1,2.972,3,3.844,620,4.823,956,5.872]],["t/3631",[957,9.662]],["t/3633",[620,6.531,958,7.951]],["t/3635",[959,9.662]],["t/3637",[960,7.951,961,7.393]],["t/3639",[302,4.005,962,7.951]],["t/3641",[961,7.393,963,7.951]],["t/3643",[964,9.662]],["t/3645",[965,8.537]],["t/3647",[1,2.972,3,3.844,104,4.228,620,4.823]],["t/3650",[175,4.866]],["t/3652",[315,5.045]],["t/3654",[316,6.649]],["t/3655",[54,4.327,112,5.041,759,5.735]],["t/3657",[316,5.472,661,6.531]],["t/3659",[316,5.472,327,5.634]],["t/3660",[68,3.718,510,4.948,966,5.969]],["t/3662",[68,4.376,573,6.531]],["t/3664",[54,3.761,70,2.987,659,4.823,967,5.188]],["t/3666",[70,4.045,968,6.349]],["t/3668",[30,2.444,70,2.368,456,3.823,478,5.382,568,3.823]],["t/3670",[70,2.987,113,4.041,327,4.161,510,4.301]],["t/3672",[70,3.436,240,4.422,502,5.549]],["t/3674",[154,4.624,316,5.472]],["t/3676",[1,3.419,139,3.628,580,5.261]],["t/3678",[95,5.205,559,5.825]],["t/3680",[969,9.662]],["t/3682",[462,8.203]],["t/3684",[1,2.972,27,5.46,28,5.188,896,4.823]],["t/3687",[175,4.866]],["t/3689",[315,5.045]],["t/3691",[326,4.556,562,4.463]],["t/3692",[54,4.327,112,5.041,759,5.735]],["t/3694",[95,3.4,316,3.574,580,4.044,661,4.266,970,4.588]],["t/3696",[316,5.472,327,5.634]],["t/3697",[68,3.718,510,4.948,966,5.969]],["t/3699",[68,4.376,573,6.531]],["t/3701",[54,3.761,70,2.987,659,4.823,967,5.188]],["t/3703",[95,4.422,185,5.549,559,4.948]],["t/3705",[971,8.984]],["t/3707",[70,4.045,968,6.349]],["t/3709",[30,2.444,70,2.368,456,3.823,478,5.382,568,3.823]],["t/3711",[70,2.987,113,4.041,327,4.161,510,4.301]],["t/3713",[70,3.436,758,5.394,972,5.969]],["t/3715",[70,4.045,973,7.393]],["t/3717",[70,3.436,95,4.422,630,5.735]],["t/3719",[154,4.624,316,5.472]],["t/3721",[139,3.628,290,4.422,974,5.549]],["t/3723",[1,4.025,896,6.531]],["t/3726",[175,4.866]],["t/3728",[315,5.045]],["t/3730",[975,9.662]],["t/3732",[326,4.556,562,4.463]],["t/3733",[36,4.944,938,5.472]],["t/3734",[53,4.246,913,4.59]],["t/3737",[175,4.866]],["t/3739",[256,4.376,496,4.556]],["t/3741",[61,4.624,259,5.55]],["t/3743",[926,7.393,972,7.025]],["t/3745",[183,3.683,320,5.266]],["t/3746",[672,7.525]],["t/3748",[633,7.937]],["t/3750",[256,5.318]],["t/3752",[183,3.683,607,5.725]],["t/3755",[175,4.866]],["t/3756",[112,5.041,976,5.549,977,6.281]],["t/3758",[99,2.836,850,5.46,976,4.823,978,5.872]],["t/3760",[272,6.751,976,6.531]],["t/3762",[349,4.786,478,5.041,976,5.549]],["t/3764",[315,5.045]],["t/3766",[1,3.419,11,4.422,976,5.549]],["t/3767",[580,7.525]],["t/3769",[288,4.708]],["t/3771",[287,4.222,382,5.266]],["t/3774",[175,4.866]],["t/3776",[315,5.045]],["t/3778",[326,4.556,562,4.463]],["t/3779",[54,4.327,112,5.041,759,5.735]],["t/3781",[95,3.4,316,3.574,580,4.044,661,4.266,970,4.588]],["t/3783",[316,5.472,327,5.634]],["t/3784",[68,3.718,510,4.948,966,5.969]],["t/3786",[68,4.376,573,6.531]],["t/3788",[54,3.761,70,2.987,659,4.823,967,5.188]],["t/3790",[1,3.419,139,3.628,580,5.261]],["t/3792",[95,4.422,185,5.549,559,4.948]],["t/3794",[462,8.203]],["t/3796",[61,4.624,259,5.55]],["t/3798",[971,8.984]],["t/3800",[70,4.045,968,6.349]],["t/3802",[30,2.444,70,2.368,456,3.823,478,5.382,568,3.823]],["t/3804",[70,2.987,113,4.041,327,4.161,510,4.301]],["t/3806",[70,3.436,758,5.394,972,5.969]],["t/3808",[70,4.045,973,7.393]],["t/3810",[70,3.436,95,4.422,630,5.735]],["t/3812",[154,4.624,316,5.472]],["t/3814",[139,3.628,290,4.422,974,5.549]],["t/3816",[1,4.025,896,6.531]],["t/3819",[315,5.045]],["t/3821",[66,6.008]],["t/3823",[95,6.325]],["t/3825",[55,5.145,68,3.718,240,4.422]],["t/3827",[288,3.875,731,7.393]],["t/3828",[41,5.266,288,3.875]],["t/3830",[288,3.875,979,7.951]],["t/3832",[288,3.292,294,5.969,980,6.755]],["t/3834",[30,3.787,127,4.113,439,3.16,758,3.717,981,4.655]],["t/3836",[183,3.683,197,4.404]],["t/3839",[256,4.376,496,4.556]],["t/3841",[183,3.683,320,5.266]],["t/3842",[288,3.875,982,7.393]],["t/3844",[256,5.318]],["t/3846",[183,3.683,607,5.725]],["t/3849",[256,4.376,496,4.556]],["t/3851",[183,3.683,320,5.266]],["t/3852",[288,3.875,982,7.393]],["t/3854",[672,7.525]],["t/3856",[633,7.937]],["t/3858",[256,5.318]],["t/3860",[183,3.683,607,5.725]],["t/3863",[175,4.866]],["t/3865",[315,5.045]],["t/3867",[269,4.649,288,3.292,516,5.394]],["t/3869",[139,3.628,288,3.292,949,5.969]],["t/3871",[288,4.187,328,4.228,637,4.573]],["t/3873",[286,4.985,288,4.187,328,4.228]],["t/3875",[154,4.624,505,7.025]],["t/3877",[270,5.148,562,4.463]],["t/3878",[270,5.148,949,7.025]],["t/3880",[270,5.148,288,3.875]],["t/3882",[183,3.683,197,4.404]],["t/3884",[61,4.624,259,5.55]],["t/3887",[175,4.866]],["t/3889",[983,6.399]],["t/3891",[315,5.045]],["t/3893",[399,6.056,984,7.951]],["t/3895",[1,3.419,139,3.628,580,5.261]],["t/3897",[67,7.211]],["t/3899",[464,7.211]],["t/3901",[399,6.056,985,7.951]],["t/3903",[986,9.662]],["t/3905",[183,3.683,197,4.404]],["t/3907",[61,4.624,259,5.55]],["t/3909",[139,3.628,290,4.422,974,5.549]],["t/3912",[175,4.866]],["t/3914",[51,5.907,987,6.755]],["t/3915",[70,4.045,988,7.951]],["t/3917",[70,3.436,465,6.281,989,6.755]],["t/3919",[61,4.624,259,5.55]],["t/3922",[175,4.866]],["t/3924",[315,5.045]],["t/3926",[326,4.556,562,4.463]],["t/3927",[70,4.045,706,5.331]],["t/3929",[990,5.577]],["t/3931",[129,7.025,775,5.205]],["t/3933",[256,4.376,496,4.556]],["t/3935",[53,4.246,913,4.59]],["t/3937",[183,3.683,197,4.404]],["t/3940",[175,4.866]],["t/3942",[315,5.045]],["t/3944",[326,4.556,562,4.463]],["t/3946",[70,4.045,706,5.331]],["t/3948",[36,4.944,938,5.472]],["t/3950",[990,5.577]],["t/3952",[53,4.246,913,4.59]],["t/3955",[175,4.866]],["t/3957",[315,5.045]],["t/3959",[20,2.242,68,2.122,72,2.071,383,4.023,477,3.167,719,3.585,991,3.856]],["t/3961",[259,4.715,320,4.474,477,5.549]],["t/3963",[477,6.531,479,6.751]],["t/3965",[326,4.556,562,4.463]],["t/3967",[70,4.045,706,5.331]],["t/3969",[36,4.944,938,5.472]],["t/3970",[2,5.261,477,5.549,617,5.549]],["t/3972",[990,5.577]],["t/3974",[53,4.246,913,4.59]],["t/3977",[175,4.866]],["t/3979",[983,6.399]],["t/3981",[180,7.715]],["t/3983",[48,3.292,139,2.789,648,2.858,992,5.193,993,5.193]],["t/3985",[55,6.056,241,6.349]],["t/3987",[48,2.251,68,1.954,70,1.806,75,3.301,111,2.65,402,4.118,648,1.954,994,3.551]],["t/3989",[14,2.868,52,2.922,61,2.707,70,2.368,383,3.014,995,4.328]],["t/3991",[3,3.4,57,3.526,70,2.642,775,3.4,996,5.193]],["t/3993",[62,3.804,70,2.642,82,4.266,648,2.858,902,3.574]],["t/3995",[990,5.577]],["t/3997",[997,7.937]],["t/3999",[53,4.246,913,4.59]],["t/4001",[799,6.56]],["t/4004",[175,4.866]],["t/4006",[774,7.358]],["t/4008",[315,5.045]],["t/4010",[326,4.556,562,4.463]],["t/4012",[54,3.761,747,3.495,842,5.188,970,5.188]],["t/4014",[139,4.271,998,7.951]],["t/4016",[54,4.327,402,4.786,747,4.021]],["t/4018",[54,4.327,68,3.718,747,4.021]],["t/4020",[54,4.327,464,5.041,747,4.021]],["t/4022",[54,4.327,70,3.436,747,4.021]],["t/4024",[256,4.376,327,5.634]],["t/4025",[523,6.846]],["t/4027",[677,8.537]],["t/4029",[154,5.619]],["t/4031",[53,4.246,913,4.59]],["t/4033",[183,3.683,197,4.404]],["t/4036",[175,4.866]],["t/4038",[983,6.399]],["t/4040",[48,4.435,111,2.456,269,2.264,402,3.868,648,3.85]],["t/4042",[315,5.045]],["t/4044",[326,4.556,562,4.463]],["t/4046",[130,5.934,999,7.951]],["t/4048",[139,5.19]],["t/4050",[154,5.619]],["t/4052",[53,4.246,913,4.59]],["t/4054",[183,3.683,197,4.404]],["t/4056",[799,6.56]],["t/4059",[256,5.318]],["t/4061",[559,7.078]],["t/4063",[183,3.683,320,5.266]],["t/4065",[256,5.318]],["t/4067",[183,3.683,607,5.725]],["t/4069",[799,6.56]],["t/4072",[175,4.866]],["t/4074",[983,6.399]],["t/4076",[315,5.045]],["t/4078",[326,4.556,562,4.463]],["t/4080",[70,4.045,706,5.331]],["t/4082",[96,5.041,139,3.628,302,3.402]],["t/4084",[96,5.041,302,3.402,559,4.948]],["t/4086",[53,4.246,913,4.59]],["t/4088",[183,3.683,197,4.404]],["t/4090",[799,6.56]],["t/4093",[1000,7.937]],["t/4095",[774,7.358]],["t/4097",[180,7.715]],["t/4099",[695,5.969,894,6.281,990,3.899]],["t/4101",[221,2.794,291,2.703,348,1.847,624,3.059,711,2.703,810,3.059,1001,3.291,1002,2.907,1003,3.291,1004,3.059]],["t/4103",[711,5.549,1002,5.969,1005,6.755]],["t/4105",[990,5.577]],["t/4106",[711,6.531,1002,7.025]],["t/4108",[445,6.192,463,6.531]],["t/4110",[997,7.937]],["t/4112",[12,5.266,1006,7.951]],["t/4115",[175,4.866]],["t/4117",[983,6.399]],["t/4119",[315,5.045]],["t/4121",[326,4.556,562,4.463]],["t/4123",[70,4.045,706,5.331]],["t/4125",[139,5.19]],["t/4127",[53,4.246,913,4.59]],["t/4129",[183,3.683,197,4.404]],["t/4132",[11,2.761,12,2.793,154,2.453,420,2.864,445,3.285,463,3.464,1007,4.218]],["t/4134",[12,3.439,202,4.706,224,3.574,420,3.526]],["t/4136",[12,3.439,224,3.574,289,3.4,420,3.526,836,3.679]],["t/4138",[799,6.56]],["t/4141",[1000,7.937]],["t/4143",[180,7.715]],["t/4145",[240,5.205,1008,7.393]],["t/4147",[990,5.577]],["t/4149",[997,7.937]],["t/4152",[175,4.866]],["t/4154",[983,6.399]],["t/4156",[315,5.045]],["t/4158",[326,4.556,562,4.463]],["t/4160",[139,3.154,291,4.823,377,5.46,775,3.844]],["t/4162",[70,4.045,706,5.331]],["t/4164",[161,3.273,382,2.553,747,2.295,778,3.003,867,3.406,1009,3.856,1010,6.214]],["t/4166",[139,5.19]],["t/4168",[53,4.246,913,4.59]],["t/4170",[183,3.683,197,4.404]],["t/4172",[799,6.56]],["t/4175",[183,3.683,320,5.266]],["t/4177",[53,4.246,68,4.376]],["t/4179",[53,4.246,555,7.393]],["t/4181",[1011,7.951,1012,7.951]],["t/4184",[1000,7.937]],["t/4186",[983,6.399]],["t/4188",[326,4.556,562,4.463]],["t/4190",[990,5.577]],["t/4192",[997,7.937]],["t/4194",[36,4.944,938,5.472]],["t/4197",[175,4.866]],["t/4199",[315,5.045]],["t/4201",[67,5.041,202,4.054,218,3.928]],["t/4203",[202,4.054,218,3.928,758,5.394]],["t/4205",[202,4.054,218,3.928,756,6.281]],["t/4207",[53,4.246,913,4.59]],["t/4209",[183,3.683,197,4.404]],["t/4211",[799,6.56]],["t/4214",[1000,7.937]],["t/4216",[983,6.399]],["t/4218",[180,7.715]],["t/4219",[315,5.045]],["t/4221",[327,4.786,1013,6.755,1014,6.281]],["t/4223",[562,4.463,1015,7.951]],["t/4225",[977,7.393,1016,7.951]],["t/4227",[316,5.472,835,6.531]],["t/4229",[256,3.718,948,6.281,1017,6.755]],["t/4231",[990,5.577]],["t/4233",[797,5.969,835,5.549,1018,6.755]],["t/4235",[38,3.686,525,5.188,1014,5.46,1019,5.872]],["t/4237",[523,4.786,614,6.281,1004,6.281]],["t/4239",[99,2.836,420,3.987,684,4.573,1020,5.872]],["t/4241",[254,6.056,1021,7.393]],["t/4243",[26,6.846]],["t/4245",[799,6.56]],["t/4248",[175,4.866]],["t/4250",[983,6.399]],["t/4252",[315,5.045]],["t/4254",[326,4.556,562,4.463]],["t/4256",[70,4.045,706,5.331]],["t/4258",[139,2.5,202,2.794,224,3.203,290,3.047,466,4.328,751,3.823]],["t/4260",[183,3.683,197,4.404]],["t/4262",[799,6.56]],["t/4265",[41,3.439,183,2.405,648,2.858,751,4.266,1022,5.193]],["t/4267",[16,2.096,100,3.167,139,2.071,202,2.314,373,3.167,528,3.406,648,2.122,751,3.167]],["t/4269",[506,3.802,528,5.188,1023,5.872,1024,5.872]],["t/4272",[315,5.045]],["t/4274",[175,3.402,1025,6.755,1026,5.969]],["t/4276",[326,4.556,562,4.463]],["t/4278",[52,3.23,70,1.56,154,1.783,266,2.518,545,2.335,590,2.288,1026,2.709,1027,2.851,1028,3.066,1029,2.709]],["t/4280",[57,3.305,70,1.46,183,1.329,266,2.357,289,1.879,491,2.142,545,2.186,590,2.142,1027,2.668,1030,2.87,1031,2.87]],["t/4282",[62,3.41,70,2.368,183,2.156,184,3.545,195,3.952,733,3.952]],["t/4284",[253,3.804,288,2.531,590,3.875,1026,4.588,1029,4.588]],["t/4286",[52,3.26,70,2.642,225,3.625,226,4.588,355,4.588]],["t/4288",[57,3.526,70,2.642,77,3.679,288,2.531,516,4.146]],["t/4290",[990,5.577]],["t/4293",[175,4.866]],["t/4295",[983,6.399]],["t/4297",[315,5.045]],["t/4299",[326,4.556,562,4.463]],["t/4301",[2,6.192,181,7.393]],["t/4303",[287,2.757,382,3.439,487,4.044,968,4.146,1032,4.828]],["t/4305",[72,3.628,464,5.041,527,5.394]],["t/4307",[24,4.327,383,4.374,1033,6.281]],["t/4309",[70,4.045,706,5.331]],["t/4311",[36,4.944,938,5.472]],["t/4312",[64,3.921,487,3.285,965,3.726,968,3.367,1032,3.921,1033,3.921,1034,3.921]],["t/4314",[139,2.789,197,2.876,412,4.146,965,4.588,1035,5.193]],["t/4316",[139,5.19]],["t/4318",[224,4.041,527,4.688,648,3.232,1036,5.872]],["t/4320",[218,4.624,487,6.192]],["t/4322",[229,5.934,351,6.192]],["t/4324",[229,5.041,384,5.969,385,6.281]],["t/4326",[229,4.382,447,5.188,448,4.688,968,4.688]],["t/4328",[229,5.041,411,4.948,413,5.261]],["t/4330",[229,5.041,390,6.281,412,5.394]],["t/4332",[24,5.093,229,5.934]],["t/4334",[53,4.246,913,4.59]],["t/4336",[183,3.683,197,4.404]],["t/4339",[175,4.866]],["t/4341",[315,5.045]],["t/4343",[990,5.577]],["t/4345",[53,4.246,913,4.59]],["t/4347",[183,3.683,197,4.404]],["t/4350",[175,4.866]],["t/4352",[315,5.045]],["t/4354",[990,5.577]],["t/4356",[53,4.246,913,4.59]],["t/4358",[183,3.683,197,4.404]],["t/4361",[256,4.376,496,4.556]],["t/4363",[183,3.683,320,5.266]],["t/4364",[256,5.318]],["t/4366",[183,3.683,607,5.725]],["t/4369",[175,4.866]],["t/4371",[315,5.045]],["t/4373",[990,5.577]],["t/4375",[399,3.955,464,3.875,684,4.044,889,4.588,913,2.997]],["t/4377",[68,3.232,399,4.472,684,4.573,913,3.389]],["t/4379",[139,3.628,290,4.422,974,5.549]],["t/4381",[183,3.683,197,4.404]],["t/4384",[256,4.376,496,4.556]],["t/4386",[183,3.683,320,5.266]],["t/4387",[496,5.537]],["t/4389",[256,5.318]],["t/4391",[183,3.683,607,5.725]],["t/4394",[175,4.866]],["t/4396",[315,5.045]],["t/4398",[990,5.577]],["t/4400",[68,2.858,399,3.955,684,4.044,889,4.588,913,2.997]],["t/4402",[68,3.232,399,4.472,684,4.573,913,3.389]],["t/4404",[53,4.246,913,4.59]],["t/4406",[183,3.683,197,4.404]],["t/4409",[175,4.866]],["t/4411",[983,6.399]],["t/4413",[315,5.045]],["t/4415",[326,4.556,562,4.463]],["t/4417",[313,5.145,314,5.041,1037,6.755]],["t/4419",[68,3.232,240,3.844,313,4.472,1038,5.188]],["t/4421",[139,5.19]],["t/4423",[53,4.246,913,4.59]],["t/4426",[175,4.866]],["t/4428",[774,7.358]],["t/4430",[315,5.045]],["t/4432",[326,4.556,562,4.463]],["t/4434",[990,5.577]],["t/4436",[53,5.16]],["t/4439",[175,4.866]],["t/4441",[774,7.358]],["t/4443",[315,5.045]],["t/4445",[326,4.556,562,4.463]],["t/4447",[990,5.577]],["t/4450",[175,4.866]],["t/4452",[774,7.358]],["t/4454",[315,5.045]],["t/4456",[326,4.556,562,4.463]],["t/4458",[990,5.577]],["t/4460",[139,3.628,290,4.422,974,5.549]],["t/4463",[256,4.376,496,4.556]],["t/4465",[183,3.683,320,5.266]],["t/4467",[183,3.683,607,5.725]],["t/4470",[175,4.866]],["t/4472",[774,7.358]],["t/4474",[315,5.045]],["t/4476",[326,4.556,562,4.463]],["t/4478",[218,3.415,241,4.688,872,5.188,1039,5.46]],["t/4480",[439,5.399,1040,6.531]],["t/4482",[348,4.463,1040,6.531]],["t/4484",[232,5.825,452,6.751]],["t/4486",[990,5.577]],["t/4488",[218,3.415,241,4.688,872,5.188,1039,5.46]],["t/4490",[1040,6.531,1041,7.951]],["t/4492",[348,4.463,1040,6.531]],["t/4494",[232,5.825,452,6.751]],["t/4496",[53,4.246,913,4.59]],["t/4498",[183,3.683,197,4.404]],["t/4501",[175,4.866]],["t/4503",[315,5.045]],["t/4505",[326,4.556,562,4.463]],["t/4507",[68,4.376,240,5.205]],["t/4509",[337,4.472,590,4.382,1042,5.872,1043,5.872]],["t/4511",[20,3.02,202,3.117,253,3.804,367,4.828,1044,5.193]],["t/4513",[77,4.161,300,4.573,330,4.098,1045,5.872]],["t/4515",[300,3.625,478,3.474,545,3.545,550,3.952,590,3.474,896,3.823]],["t/4517",[478,4.382,545,4.472,550,4.985,590,4.382]],["t/4519",[316,4.649,876,6.281,1046,6.755]],["t/4521",[816,8.537]],["t/4524",[175,4.866]],["t/4526",[983,6.399]],["t/4528",[315,5.045]],["t/4530",[289,5.205,1047,7.951]],["t/4532",[41,5.266,396,6.531]],["t/4534",[648,4.376,1040,6.531]],["t/4536",[408,6.056,648,4.376]],["t/4538",[33,4.688,218,3.415,648,3.232,1048,5.46]],["t/4540",[32,4.649,279,4.786,1049,6.755]],["t/4542",[559,4.948,648,3.718,1050,6.755]],["t/4544",[130,5.934,1051,7.951]],["t/4546",[139,5.19]],["t/4548",[183,3.683,197,4.404]],["t/4550",[53,4.246,913,4.59]],["t/4553",[175,4.866]],["t/4555",[983,6.399]],["t/4557",[315,5.045]],["t/4559",[3,5.205,1052,7.951]],["t/4561",[3,3.844,908,5.46,1053,5.872,1054,5.872]],["t/4563",[990,5.577]],["t/4565",[53,4.246,913,4.59]],["t/4568",[107,3.723,373,4.823,1029,5.188,1055,5.872]],["t/4571",[175,4.866]],["t/4573",[983,6.399]],["t/4575",[315,5.045]],["t/4577",[326,4.556,562,4.463]],["t/4579",[70,4.045,706,5.331]],["t/4581",[990,5.577]],["t/4583",[183,3.683,197,4.404]],["t/4586",[175,4.866]],["t/4588",[53,4.246,315,4.152]],["t/4590",[326,4.556,562,4.463]],["t/4592",[70,4.045,706,5.331]],["t/4594",[36,4.944,938,5.472]],["t/4596",[990,5.577]],["t/4598",[53,4.246,913,4.59]],["t/4600",[183,3.683,197,4.404]],["t/4601",[70,3.436,183,3.129,197,3.742]],["t/4603",[175,4.866]],["t/4605",[983,6.399]],["t/4607",[315,5.045]],["t/4609",[80,7.393,1038,7.025]],["t/4611",[326,4.556,562,4.463]],["t/4613",[70,4.045,706,5.331]],["t/4615",[990,5.577]],["t/4617",[20,3.415,204,4.573,1056,5.872,1057,5.872]],["t/4619",[20,3.415,204,4.573,1058,5.872,1059,5.872]],["t/4621",[53,4.246,913,4.59]],["t/4622",[73,3.41,302,2.344,558,3.083,855,4.328,1021,4.328,1060,4.655]],["t/4624",[200,5.46,775,3.844,1061,5.872,1062,5.872]],["t/4626",[402,4.161,648,3.232,995,5.46,1063,5.872]],["t/4628",[183,3.683,197,4.404]],["t/4630",[757,8.203]],["t/4631",[695,7.025,990,4.59]],["t/4633",[799,6.56]],["t/4636",[175,4.866]],["t/4638",[315,5.045]],["t/4640",[326,4.556,562,4.463]],["t/4642",[70,4.045,706,5.331]],["t/4644",[36,4.944,938,5.472]],["t/4646",[990,5.577]],["t/4648",[53,4.246,913,4.59]],["t/4650",[183,3.683,197,4.404]],["t/4653",[175,4.866]],["t/4655",[678,6.192,797,7.025]],["t/4657",[990,5.577]],["t/4659",[68,3.718,666,4.864,703,5.145]],["t/4661",[1008,7.393,1064,7.951]],["t/4664",[256,4.376,496,4.556]],["t/4666",[559,5.825,794,7.025]],["t/4668",[420,6.56]],["t/4670",[799,6.56]],["t/4673",[175,4.866]],["t/4675",[315,5.045]],["t/4677",[990,5.577]],["t/4678",[1065,7.951,1066,7.951]],["t/4680",[351,7.525]],["t/4683",[175,4.866]],["t/4685",[68,5.318]],["t/4687",[315,5.045]],["t/4689",[990,5.577]],["t/4690",[267,4.991,853,7.025]],["t/4692",[23,5.934,218,4.624]],["t/4694",[23,5.041,218,3.928,880,6.281]],["t/4696",[95,5.205,408,6.056]],["t/4698",[859,7.211]],["t/4700",[107,5.041,857,6.056]],["t/4702",[616,8.537]],["t/4704",[420,6.56]],["t/4706",[858,7.937]],["t/4708",[420,5.399,455,5.205]],["t/4710",[439,6.56]],["t/4712",[10,5.735,518,5.969,1067,6.281]],["t/4714",[10,5.735,1067,6.281,1068,6.281]],["t/4716",[12,3.439,41,3.439,120,4.146,1068,4.828,1069,5.193]],["t/4718",[33,6.349,1048,7.393]],["t/4721",[175,4.866]],["t/4723",[315,5.045]],["t/4725",[68,5.318]],["t/4727",[70,4.045,706,5.331]],["t/4729",[990,5.577]],["t/4731",[26,6.846]],["t/4732",[68,2.562,306,3.952,834,3.625,836,3.298,1070,4.655,1071,4.655]],["t/4735",[175,4.866]],["t/4737",[267,6.065]],["t/4739",[315,5.045]],["t/4741",[326,4.556,562,4.463]],["t/4743",[70,4.915]],["t/4745",[990,5.577]],["t/4747",[36,4.944,938,5.472]],["t/4749",[53,4.246,913,4.59]],["t/4751",[183,3.683,197,4.404]],["t/4754",[175,4.866]],["t/4756",[267,6.065]],["t/4758",[315,5.045]],["t/4760",[326,4.556,562,4.463]],["t/4762",[70,4.915]],["t/4764",[36,4.944,938,5.472]],["t/4766",[990,5.577]],["t/4768",[53,4.246,913,4.59]],["t/4770",[183,3.683,197,4.404]],["t/4777",[1000,7.937]],["t/4779",[983,6.399]],["t/4781",[180,7.715]],["t/4783",[990,5.577]],["t/4785",[997,7.937]],["t/4787",[53,4.246,913,4.59]],["t/4790",[175,4.866]],["t/4792",[315,5.045]],["t/4794",[326,4.556,562,4.463]],["t/4796",[70,4.045,706,5.331]],["t/4798",[36,4.944,938,5.472]],["t/4800",[990,5.577]],["t/4802",[53,4.246,913,4.59]],["t/4804",[183,3.683,197,4.404]],["t/4807",[175,4.866]],["t/4809",[983,6.399]],["t/4811",[315,5.045]],["t/4813",[326,4.556,562,4.463]],["t/4815",[70,4.045,706,5.331]],["t/4817",[36,4.944,938,5.472]],["t/4819",[139,5.19]],["t/4821",[53,4.246,913,4.59]],["t/4823",[183,3.683,197,4.404]],["t/4828",[0,3.921,1,2.135,11,2.761,15,2.511,53,2.252,137,3.726,138,2.336]],["t/4832",[455,5.205,947,7.025]],["t/4834",[741,8.537]],["t/4842",[86,5.735,87,4.864,1072,6.755]],["t/4844",[260,4.715,330,4.715,432,4.786]],["t/4846",[455,5.205,1034,7.393]],["t/4848",[72,4.271,947,7.025]],["t/4850",[307,8.203]],["t/4852",[12,3.439,222,2.934,307,4.409,864,4.409,1073,5.193]],["t/4854",[222,5.46]],["t/4856",[417,6.751,1074,7.951]],["t/4858",[222,3.817,741,5.969,1038,5.969]],["t/4866",[77,4.786,305,4.948,330,4.715]],["t/4867",[259,4.715,331,5.735,725,6.281]],["t/4869",[1075,9.662]],["t/4871",[305,5.825,1076,7.951]],["t/4873",[7,3.069,289,4.422,305,4.948]],["t/4874",[81,3.718,302,3.402,873,6.281]],["t/4876",[222,3.817,232,4.948,865,6.281]],["t/4878",[279,5.634,864,6.751]],["t/4880",[476,7.715]],["t/4882",[24,6.189]],["t/4884",[70,2.987,346,5.188,1077,5.872,1078,5.872]]],"invertedIndex":[["",{"_index":30,"t":{"43":{"position":[[44,1]]},"89":{"position":[[7,1]]},"92":{"position":[[7,1]]},"94":{"position":[[7,1]]},"110":{"position":[[14,1]]},"112":{"position":[[11,1]]},"114":{"position":[[6,1]]},"129":{"position":[[7,1]]},"131":{"position":[[7,1]]},"133":{"position":[[7,1]]},"135":{"position":[[7,1]]},"182":{"position":[[11,1]]},"312":{"position":[[8,1]]},"534":{"position":[[0,2]]},"538":{"position":[[0,2]]},"540":{"position":[[0,2]]},"542":{"position":[[0,3]]},"544":{"position":[[0,2]]},"546":{"position":[[0,2]]},"548":{"position":[[0,2]]},"550":{"position":[[0,2]]},"567":{"position":[[15,3]]},"609":{"position":[[6,1]]},"1090":{"position":[[0,2]]},"1091":{"position":[[0,2]]},"1092":{"position":[[0,2]]},"1241":{"position":[[13,1]]},"1353":{"position":[[11,1]]},"1485":{"position":[[14,1]]},"1560":{"position":[[16,1]]},"1731":{"position":[[8,1]]},"1733":{"position":[[11,1]]},"2581":{"position":[[15,1]]},"3076":{"position":[[21,1]]},"3106":{"position":[[21,1]]},"3139":{"position":[[21,1]]},"3171":{"position":[[21,1]]},"3209":{"position":[[21,1]]},"3262":{"position":[[21,1]]},"3311":{"position":[[21,1]]},"3320":{"position":[[9,3]]},"3338":{"position":[[21,1]]},"3574":{"position":[[25,1]]},"3668":{"position":[[35,1]]},"3709":{"position":[[35,1]]},"3802":{"position":[[35,1]]},"3834":{"position":[[10,1],[37,1]]}}}],["0",{"_index":994,"t":{"3987":{"position":[[7,2]]}}}],["1",{"_index":52,"t":{"89":{"position":[[5,1]]},"91":{"position":[[0,2]]},"92":{"position":[[5,1]]},"129":{"position":[[5,1]]},"193":{"position":[[0,2]]},"219":{"position":[[16,1]]},"238":{"position":[[10,1]]},"240":{"position":[[10,1]]},"281":{"position":[[0,2]]},"298":{"position":[[0,2]]},"312":{"position":[[0,2]]},"318":{"position":[[0,2]]},"439":{"position":[[5,2]]},"599":{"position":[[11,2]]},"1219":{"position":[[5,2]]},"1311":{"position":[[46,1]]},"1471":{"position":[[5,2]]},"3031":{"position":[[0,2]]},"3557":{"position":[[24,2]]},"3989":{"position":[[7,2]]},"4278":{"position":[[7,1],[31,2]]},"4286":{"position":[[7,1]]}}}],["1.0",{"_index":922,"t":{"3293":{"position":[[13,3]]}}}],["1.1",{"_index":205,"t":{"320":{"position":[[0,3]]},"3033":{"position":[[0,3]]}}}],["1.2",{"_index":210,"t":{"322":{"position":[[0,3]]},"3035":{"position":[[0,3]]}}}],["1.3",{"_index":213,"t":{"324":{"position":[[0,3]]},"3037":{"position":[[0,3]]}}}],["1.4",{"_index":217,"t":{"326":{"position":[[0,3]]},"3039":{"position":[[0,3]]}}}],["1.5",{"_index":219,"t":{"328":{"position":[[0,3]]}}}],["2",{"_index":57,"t":{"94":{"position":[[5,1]]},"96":{"position":[[0,2]]},"131":{"position":[[5,1]]},"227":{"position":[[10,1]]},"236":{"position":[[16,1]]},"283":{"position":[[0,2]]},"300":{"position":[[0,2]]},"314":{"position":[[0,2]]},"441":{"position":[[5,2]]},"601":{"position":[[11,2]]},"1221":{"position":[[5,2]]},"1473":{"position":[[5,2]]},"3991":{"position":[[7,2]]},"4280":{"position":[[7,1],[31,2]]},"4288":{"position":[[7,1]]}}}],["2024.1",{"_index":1058,"t":{"4619":{"position":[[23,6]]}}}],["2024.2",{"_index":1056,"t":{"4617":{"position":[[23,6]]}}}],["2nd",{"_index":729,"t":{"2047":{"position":[[7,3]]}}}],["3",{"_index":62,"t":{"98":{"position":[[0,2]]},"133":{"position":[[5,1]]},"223":{"position":[[10,1]]},"285":{"position":[[0,2]]},"308":{"position":[[0,2]]},"603":{"position":[[11,2]]},"1223":{"position":[[5,2]]},"1475":{"position":[[5,2]]},"3993":{"position":[[7,2]]},"4282":{"position":[[7,1]]}}}],["4",{"_index":89,"t":{"135":{"position":[[5,1]]},"215":{"position":[[10,1]]},"287":{"position":[[0,2]]},"605":{"position":[[11,2]]},"1225":{"position":[[5,2]]},"1477":{"position":[[5,2]]}}}],["4+1",{"_index":133,"t":{"189":{"position":[[0,3]]}}}],["5",{"_index":145,"t":{"208":{"position":[[10,1]]},"607":{"position":[[11,2]]},"1479":{"position":[[5,2]]}}}],["5.1",{"_index":188,"t":{"290":{"position":[[0,3]]}}}],["5.2",{"_index":190,"t":{"294":{"position":[[0,3]]}}}],["6",{"_index":140,"t":{"204":{"position":[[10,1]]}}}],["60",{"_index":631,"t":{"1573":{"position":[[0,2]]},"1916":{"position":[[0,2]]}}}],["abstract",{"_index":1000,"t":{"4093":{"position":[[0,8]]},"4141":{"position":[[0,8]]},"4184":{"position":[[0,8]]},"4214":{"position":[[0,8]]},"4777":{"position":[[0,8]]}}}],["access",{"_index":32,"t":{"44":{"position":[[9,6]]},"51":{"position":[[9,6]]},"326":{"position":[[26,6]]},"713":{"position":[[5,6]]},"1744":{"position":[[4,6]]},"2036":{"position":[[22,6]]},"2177":{"position":[[6,6]]},"2189":{"position":[[4,6]]},"2255":{"position":[[7,6]]},"2369":{"position":[[0,9]]},"2615":{"position":[[0,6]]},"2658":{"position":[[0,6]]},"2675":{"position":[[0,6]]},"4540":{"position":[[8,6]]}}}],["acknowledg",{"_index":940,"t":{"3550":{"position":[[0,16]]},"3617":{"position":[[0,16]]}}}],["action",{"_index":782,"t":{"2357":{"position":[[15,6]]},"2424":{"position":[[15,6]]},"2511":{"position":[[0,7]]}}}],["ad",{"_index":58,"t":{"94":{"position":[[9,6]]},"546":{"position":[[16,6]]},"2737":{"position":[[0,6]]},"2746":{"position":[[0,6]]}}}],["adapt",{"_index":468,"t":{"1049":{"position":[[8,8]]}}}],["add",{"_index":432,"t":{"958":{"position":[[0,3]]},"1178":{"position":[[0,3]]},"1370":{"position":[[0,3]]},"1599":{"position":[[0,3]]},"1710":{"position":[[0,3]]},"1849":{"position":[[0,3]]},"2073":{"position":[[7,3]]},"2075":{"position":[[7,3]]},"2206":{"position":[[0,3]]},"2982":{"position":[[0,3]]},"3379":{"position":[[7,3]]},"4844":{"position":[[0,3]]}}}],["addit",{"_index":727,"t":{"2042":{"position":[[10,10]]}}}],["addon",{"_index":249,"t":{"394":{"position":[[19,6]]},"540":{"position":[[11,6]]}}}],["address",{"_index":525,"t":{"1241":{"position":[[3,9]]},"1546":{"position":[[15,7]]},"4235":{"position":[[0,7]]}}}],["addressrang",{"_index":586,"t":{"1400":{"position":[[12,13]]}}}],["adit",{"_index":801,"t":{"2481":{"position":[[0,9]]}}}],["adjust",{"_index":794,"t":{"2442":{"position":[[30,11]]},"2446":{"position":[[39,10]]},"4666":{"position":[[7,11]]}}}],["admin",{"_index":200,"t":{"308":{"position":[[39,5]]},"4624":{"position":[[0,7]]}}}],["administr",{"_index":796,"t":{"2448":{"position":[[0,14]]}}}],["admonit",{"_index":91,"t":{"138":{"position":[[0,11]]}}}],["advanc",{"_index":680,"t":{"1642":{"position":[[0,8]]},"1973":{"position":[[0,8]]},"2197":{"position":[[0,8]]}}}],["advertis",{"_index":144,"t":{"206":{"position":[[10,11]]}}}],["advic",{"_index":630,"t":{"1570":{"position":[[0,6]]},"1903":{"position":[[0,6]]},"3717":{"position":[[15,6]]},"3810":{"position":[[15,6]]}}}],["affect",{"_index":1006,"t":{"4112":{"position":[[0,8]]}}}],["affero",{"_index":116,"t":{"174":{"position":[[0,6]]}}}],["against",{"_index":993,"t":{"3983":{"position":[[16,7]]}}}],["agent",{"_index":716,"t":{"2006":{"position":[[11,5]]}}}],["aggreg",{"_index":379,"t":{"815":{"position":[[19,10]]},"1739":{"position":[[5,10]]}}}],["agreement",{"_index":128,"t":{"180":{"position":[[46,10]]}}}],["alarm",{"_index":426,"t":{"947":{"position":[[0,8]]},"1838":{"position":[[0,8]]},"2971":{"position":[[0,8]]}}}],["alreadi",{"_index":370,"t":{"783":{"position":[[11,7]]}}}],["altern",{"_index":555,"t":{"1313":{"position":[[40,11]]},"4179":{"position":[[0,11]]}}}],["amd",{"_index":570,"t":{"1358":{"position":[[0,3]]}}}],["amphora",{"_index":451,"t":{"990":{"position":[[0,7]]},"1742":{"position":[[11,8]]},"1744":{"position":[[14,8]]},"1881":{"position":[[0,7]]}}}],["analyz",{"_index":444,"t":{"977":{"position":[[0,9]]},"1868":{"position":[[0,9]]},"3001":{"position":[[0,9]]}}}],["and/or",{"_index":734,"t":{"2099":{"position":[[26,6]]}}}],["annot",{"_index":999,"t":{"4046":{"position":[[8,11]]}}}],["announc",{"_index":964,"t":{"3643":{"position":[[0,12]]}}}],["anoth",{"_index":867,"t":{"2842":{"position":[[17,7]]},"2844":{"position":[[7,7]]},"4164":{"position":[[39,7]]}}}],["ansibl",{"_index":689,"t":{"1668":{"position":[[0,7]]},"1690":{"position":[[0,7]]},"1693":{"position":[[18,7]]},"2081":{"position":[[0,7]]},"2213":{"position":[[0,7]]}}}],["api",{"_index":218,"t":{"326":{"position":[[22,3]]},"396":{"position":[[23,3]]},"420":{"position":[[27,3]]},"544":{"position":[[59,3]]},"829":{"position":[[14,3]]},"1057":{"position":[[32,3]]},"1058":{"position":[[8,3]]},"1059":{"position":[[8,3]]},"1516":{"position":[[8,3]]},"2198":{"position":[[9,3]]},"2328":{"position":[[39,3]]},"2395":{"position":[[39,3]]},"2442":{"position":[[19,3]]},"2577":{"position":[[11,3]]},"2581":{"position":[[25,3]]},"2821":{"position":[[0,3]]},"2844":{"position":[[32,3]]},"2909":{"position":[[4,3]]},"2917":{"position":[[20,3]]},"3235":{"position":[[17,3]]},"3250":{"position":[[48,3]]},"3287":{"position":[[22,3]]},"4201":{"position":[[15,4]]},"4203":{"position":[[15,4]]},"4205":{"position":[[17,4]]},"4320":{"position":[[0,3]]},"4478":{"position":[[5,3]]},"4488":{"position":[[5,3]]},"4538":{"position":[[0,3]]},"4692":{"position":[[0,3]]},"4694":{"position":[[0,3]]}}}],["api_monitor.sh",{"_index":418,"t":{"937":{"position":[[11,14]]},"1828":{"position":[[11,14]]},"2961":{"position":[[11,14]]}}}],["apiserv",{"_index":564,"t":{"1337":{"position":[[8,9]]}}}],["app",{"_index":741,"t":{"2120":{"position":[[7,3]]},"4834":{"position":[[0,4]]},"4858":{"position":[[19,4]]}}}],["appendix",{"_index":757,"t":{"2217":{"position":[[0,8]]},"2356":{"position":[[0,8]]},"2423":{"position":[[0,8]]},"4630":{"position":[[0,8]]}}}],["appli",{"_index":245,"t":{"390":{"position":[[0,5]]},"509":{"position":[[0,8]]},"1473":{"position":[[8,5]]},"1658":{"position":[[0,5]]}}}],["applic",{"_index":678,"t":{"1632":{"position":[[12,11]]},"1963":{"position":[[12,11]]},"2322":{"position":[[12,10]]},"2389":{"position":[[12,10]]},"2530":{"position":[[0,11]]},"2532":{"position":[[19,11]]},"4655":{"position":[[9,12]]}}}],["approach",{"_index":590,"t":{"1404":{"position":[[9,8]]},"1420":{"position":[[9,8]]},"2575":{"position":[[11,8]]},"4278":{"position":[[22,8]]},"4280":{"position":[[22,8]]},"4284":{"position":[[0,10]]},"4509":{"position":[[27,10]]},"4515":{"position":[[37,8]]},"4517":{"position":[[22,8]]}}}],["apt",{"_index":567,"t":{"1349":{"position":[[0,3]]}}}],["ara",{"_index":694,"t":{"1693":{"position":[[0,3],[6,3]]}}}],["architectur",{"_index":113,"t":{"166":{"position":[[12,12]]},"333":{"position":[[0,13]]},"399":{"position":[[0,12]]},"1076":{"position":[[19,12]]},"1078":{"position":[[8,12]]},"1097":{"position":[[8,12]]},"1098":{"position":[[14,12]]},"1099":{"position":[[8,12]]},"1100":{"position":[[8,12]]},"1101":{"position":[[9,12]]},"2631":{"position":[[0,12]]},"3670":{"position":[[15,12]]},"3711":{"position":[[15,12]]},"3804":{"position":[[15,12]]}}}],["aspect",{"_index":998,"t":{"4014":{"position":[[13,7]]}}}],["assess",{"_index":917,"t":{"3247":{"position":[[9,10]]}}}],["asset",{"_index":274,"t":{"488":{"position":[[16,6]]}}}],["assign",{"_index":125,"t":{"180":{"position":[[10,11]]},"2454":{"position":[[0,9]]},"2466":{"position":[[14,11]]}}}],["assist",{"_index":166,"t":{"257":{"position":[[30,9]]}}}],["attach",{"_index":778,"t":{"2332":{"position":[[10,8]]},"2338":{"position":[[24,8]]},"2357":{"position":[[39,8]]},"2399":{"position":[[10,8]]},"2405":{"position":[[24,8]]},"2424":{"position":[[39,8]]},"4164":{"position":[[6,9]]}}}],["audit",{"_index":1012,"t":{"4181":{"position":[[9,6]]}}}],["auth",{"_index":878,"t":{"2905":{"position":[[8,4]]}}}],["authent",{"_index":33,"t":{"46":{"position":[[0,14]]},"53":{"position":[[0,14]]},"517":{"position":[[15,14]]},"2195":{"position":[[0,14]]},"4538":{"position":[[14,14]]},"4718":{"position":[[0,14]]}}}],["authn",{"_index":868,"t":{"2842":{"position":[[59,6]]}}}],["author",{"_index":1048,"t":{"4538":{"position":[[33,13]]},"4718":{"position":[[19,13]]}}}],["authz",{"_index":869,"t":{"2842":{"position":[[66,6]]}}}],["autom",{"_index":320,"t":{"607":{"position":[[14,9]]},"941":{"position":[[0,10]]},"1463":{"position":[[0,9]]},"1832":{"position":[[0,10]]},"2031":{"position":[[0,9]]},"2488":{"position":[[4,9]]},"2965":{"position":[[0,10]]},"3289":{"position":[[14,9]]},"3745":{"position":[[0,9]]},"3841":{"position":[[0,9]]},"3851":{"position":[[0,9]]},"3961":{"position":[[0,10]]},"4063":{"position":[[0,9]]},"4175":{"position":[[0,9]]},"4363":{"position":[[0,9]]},"4386":{"position":[[0,9]]},"4465":{"position":[[0,9]]}}}],["autoscal",{"_index":676,"t":{"1628":{"position":[[4,10]]},"1959":{"position":[[4,10]]}}}],["avail",{"_index":291,"t":{"556":{"position":[[0,9]]},"813":{"position":[[16,12]]},"3349":{"position":[[0,9]]},"4101":{"position":[[49,13]]},"4160":{"position":[[13,12]]}}}],["avoid",{"_index":614,"t":{"1506":{"position":[[0,8]]},"4237":{"position":[[0,5]]}}}],["aw",{"_index":367,"t":{"781":{"position":[[61,4]]},"4511":{"position":[[35,4]]}}}],["az",{"_index":1010,"t":{"4164":{"position":[[33,2],[55,2]]}}}],["azur",{"_index":368,"t":{"781":{"position":[[66,11]]}}}],["b",{"_index":465,"t":{"1047":{"position":[[9,2]]},"3917":{"position":[[7,2]]}}}],["back",{"_index":548,"t":{"1306":{"position":[[0,4]]},"1374":{"position":[[25,6]]},"1382":{"position":[[0,4]]}}}],["backend",{"_index":395,"t":{"862":{"position":[[15,7]]},"1763":{"position":[[15,7]]}}}],["backfills/recoveri",{"_index":660,"t":{"1608":{"position":[[8,18]]},"1939":{"position":[[8,18]]}}}],["backup",{"_index":348,"t":{"707":{"position":[[0,6]]},"972":{"position":[[0,6]]},"1554":{"position":[[0,6]]},"1863":{"position":[[0,6]]},"2324":{"position":[[6,6]]},"2326":{"position":[[18,6]]},"2328":{"position":[[12,6],[32,6]]},"2330":{"position":[[0,6]]},"2332":{"position":[[0,6]]},"2334":{"position":[[12,6]]},"2336":{"position":[[13,7]]},"2338":{"position":[[13,7]]},"2340":{"position":[[17,6]]},"2346":{"position":[[12,6]]},"2348":{"position":[[12,6]]},"2350":{"position":[[12,6]]},"2352":{"position":[[19,6]]},"2354":{"position":[[19,6],[42,6]]},"2391":{"position":[[6,6]]},"2393":{"position":[[18,6]]},"2395":{"position":[[12,6],[32,6]]},"2397":{"position":[[0,6]]},"2399":{"position":[[0,6]]},"2401":{"position":[[12,6]]},"2403":{"position":[[13,7]]},"2405":{"position":[[13,7]]},"2407":{"position":[[17,6]]},"2413":{"position":[[12,6]]},"2415":{"position":[[12,6]]},"2417":{"position":[[12,6]]},"2419":{"position":[[19,6]]},"2421":{"position":[[19,6],[42,6]]},"2996":{"position":[[0,6]]},"4101":{"position":[[97,7]]},"4482":{"position":[[5,6]]},"4492":{"position":[[5,6]]}}}],["barbican",{"_index":779,"t":{"2340":{"position":[[0,8]]},"2342":{"position":[[32,8]]},"2346":{"position":[[24,8]]},"2407":{"position":[[0,8]]},"2409":{"position":[[32,8]]},"2413":{"position":[[24,8]]}}}],["bare",{"_index":892,"t":{"3063":{"position":[[0,4]]}}}],["base",{"_index":545,"t":{"1296":{"position":[[28,5]]},"1416":{"position":[[42,5]]},"1418":{"position":[[42,5]]},"2511":{"position":[[8,5]]},"4278":{"position":[[16,5]]},"4280":{"position":[[16,5]]},"4515":{"position":[[31,5]]},"4517":{"position":[[16,5]]}}}],["bash",{"_index":773,"t":{"2280":{"position":[[0,4]]}}}],["basic",{"_index":947,"t":{"3591":{"position":[[0,5]]},"4832":{"position":[[0,5]]},"4848":{"position":[[0,5]]}}}],["becom",{"_index":100,"t":{"150":{"position":[[27,6]]},"2085":{"position":[[0,6]]},"3364":{"position":[[0,8]]},"3370":{"position":[[0,8]]},"4267":{"position":[[13,6]]}}}],["befor",{"_index":142,"t":{"204":{"position":[[19,6]]},"208":{"position":[[19,6]]},"215":{"position":[[19,6]]},"217":{"position":[[22,6]]},"223":{"position":[[19,6]]},"227":{"position":[[19,6]]},"238":{"position":[[18,6]]},"240":{"position":[[17,6]]},"242":{"position":[[18,6]]}}}],["behaviour",{"_index":750,"t":{"2164":{"position":[[8,9]]}}}],["behind",{"_index":364,"t":{"775":{"position":[[15,6]]}}}],["below",{"_index":1059,"t":{"4619":{"position":[[33,5]]}}}],["benchmark",{"_index":685,"t":{"1649":{"position":[[12,9]]},"1974":{"position":[[12,9]]},"2717":{"position":[[12,9]]}}}],["best",{"_index":64,"t":{"101":{"position":[[10,4]]},"4312":{"position":[[13,4]]}}}],["beta",{"_index":334,"t":{"635":{"position":[[0,4]]},"648":{"position":[[0,4]]},"680":{"position":[[0,4]]}}}],["between",{"_index":221,"t":{"328":{"position":[[19,7]]},"513":{"position":[[7,7]]},"2430":{"position":[[66,7]]},"4101":{"position":[[16,7]]}}}],["beyond",{"_index":896,"t":{"3068":{"position":[[0,6]]},"3684":{"position":[[0,6]]},"3723":{"position":[[0,6]]},"3816":{"position":[[0,6]]},"4515":{"position":[[0,6]]}}}],["bill",{"_index":457,"t":{"1021":{"position":[[9,4]]}}}],["binari",{"_index":861,"t":{"2799":{"position":[[20,6]]}}}],["black",{"_index":740,"t":{"2109":{"position":[[25,5]]}}}],["block",{"_index":639,"t":{"1581":{"position":[[28,5]]},"1924":{"position":[[28,5]]}}}],["blockquot",{"_index":92,"t":{"140":{"position":[[0,11]]}}}],["blog",{"_index":919,"t":{"3254":{"position":[[12,4]]}}}],["board",{"_index":620,"t":{"1545":{"position":[[21,5]]},"3622":{"position":[[24,5]]},"3630":{"position":[[28,5]]},"3633":{"position":[[13,5]]},"3647":{"position":[[25,5]]}}}],["boot",{"_index":770,"t":{"2267":{"position":[[6,4]]}}}],["bootstrap",{"_index":609,"t":{"1475":{"position":[[8,9]]},"1537":{"position":[[0,9]]}}}],["box",{"_index":914,"t":{"3190":{"position":[[47,4]]}}}],["branch",{"_index":533,"t":{"1258":{"position":[[17,8]]},"2127":{"position":[[35,7]]}}}],["break",{"_index":939,"t":{"3545":{"position":[[0,8]]}}}],["breakfast",{"_index":157,"t":{"230":{"position":[[0,9]]}}}],["broken",{"_index":658,"t":{"1606":{"position":[[49,6]]}}}],["broker",{"_index":535,"t":{"1262":{"position":[[10,6]]},"1687":{"position":[[0,6]]}}}],["bucket",{"_index":344,"t":{"700":{"position":[[3,6]]},"733":{"position":[[3,6]]}}}],["bug",{"_index":228,"t":{"344":{"position":[[11,4]]},"3019":{"position":[[6,4]]},"3027":{"position":[[0,3]]}}}],["build",{"_index":294,"t":{"563":{"position":[[5,5]]},"801":{"position":[[40,5]]},"3832":{"position":[[6,5]]}}}],["ca",{"_index":416,"t":{"935":{"position":[[7,2]]},"1826":{"position":[[7,2]]},"2187":{"position":[[7,2]]},"2959":{"position":[[7,2]]}}}],["caa",{"_index":203,"t":{"314":{"position":[[3,4]]},"789":{"position":[[67,6]]},"795":{"position":[[10,4]]},"2498":{"position":[[50,4]]}}}],["caddi",{"_index":436,"t":{"960":{"position":[[0,5]]},"1851":{"position":[[0,5]]},"2984":{"position":[[0,5]]}}}],["capabl",{"_index":808,"t":{"2502":{"position":[[24,12]]}}}],["capi",{"_index":897,"t":{"3068":{"position":[[7,4]]}}}],["card",{"_index":488,"t":{"1121":{"position":[[18,5]]}}}],["case",{"_index":223,"t":{"335":{"position":[[4,5]]},"1019":{"position":[[4,5]]},"1037":{"position":[[4,5]]},"1620":{"position":[[27,4]]},"1951":{"position":[[27,4]]},"2641":{"position":[[22,4]]},"2643":{"position":[[10,4]]},"2669":{"position":[[22,4]]},"2671":{"position":[[10,4]]},"3433":{"position":[[32,5]]},"3603":{"position":[[5,4]]}}}],["ceilomet",{"_index":882,"t":{"3031":{"position":[[3,10]]}}}],["cell",{"_index":380,"t":{"817":{"position":[[16,4]]}}}],["cento",{"_index":494,"t":{"1148":{"position":[[0,6]]}}}],["central",{"_index":888,"t":{"3054":{"position":[[0,7]]},"3235":{"position":[[9,7]]},"3287":{"position":[[14,7]]}}}],["ceph",{"_index":388,"t":{"841":{"position":[[0,4]]},"851":{"position":[[0,4]]},"1062":{"position":[[24,4]]},"1182":{"position":[[53,4]]},"1184":{"position":[[7,4]]},"1432":{"position":[[24,4]]},"1438":{"position":[[0,4]]},"1440":{"position":[[7,4]]},"1570":{"position":[[10,4]]},"1643":{"position":[[11,4]]},"1645":{"position":[[11,4]]},"1647":{"position":[[10,4]]},"1903":{"position":[[10,4]]},"1913":{"position":[[0,4]]},"2143":{"position":[[0,4]]},"2160":{"position":[[0,4]]},"2206":{"position":[[15,4]]},"2208":{"position":[[0,4]]},"2648":{"position":[[0,4]]}}}],["cephblockpool",{"_index":596,"t":{"1410":{"position":[[14,13]]}}}],["cephf",{"_index":594,"t":{"1408":{"position":[[0,6]]}}}],["cephfilesystem",{"_index":595,"t":{"1408":{"position":[[9,14]]}}}],["cephobjectstor",{"_index":592,"t":{"1406":{"position":[[14,15]]}}}],["cert",{"_index":873,"t":{"2860":{"position":[[7,4]]},"4874":{"position":[[8,4]]}}}],["certain",{"_index":1007,"t":{"4132":{"position":[[28,7]]}}}],["certif",{"_index":232,"t":{"350":{"position":[[26,13]]},"1243":{"position":[[4,12]]},"1247":{"position":[[12,12]]},"1249":{"position":[[15,12]]},"3587":{"position":[[13,11]]},"3593":{"position":[[4,13]]},"3612":{"position":[[21,14]]},"4484":{"position":[[0,11]]},"4494":{"position":[[0,11]]},"4876":{"position":[[9,11]]}}}],["certifi",{"_index":927,"t":{"3364":{"position":[[9,9]]},"3370":{"position":[[9,9]]}}}],["challeng",{"_index":817,"t":{"2528":{"position":[[24,10]]},"2530":{"position":[[21,10]]},"2573":{"position":[[0,9]]}}}],["chang",{"_index":424,"t":{"943":{"position":[[0,8]]},"1528":{"position":[[0,6]]},"1533":{"position":[[0,6]]},"1640":{"position":[[0,6]]},"1834":{"position":[[0,8]]},"1971":{"position":[[0,6]]},"2200":{"position":[[0,6]]},"2967":{"position":[[0,8]]},"3545":{"position":[[9,6]]}}}],["changed_when",{"_index":108,"t":{"160":{"position":[[9,12]]}}}],["channel",{"_index":181,"t":{"285":{"position":[[3,8]]},"4301":{"position":[[14,8]]}}}],["characterist",{"_index":807,"t":{"2502":{"position":[[4,15]]}}}],["charg",{"_index":421,"t":{"939":{"position":[[20,8]]},"1830":{"position":[[20,8]]},"2963":{"position":[[20,8]]}}}],["chart",{"_index":311,"t":{"583":{"position":[[18,5]]}}}],["check",{"_index":313,"t":{"589":{"position":[[0,5]]},"1586":{"position":[[0,5]]},"1929":{"position":[[0,5]]},"2103":{"position":[[0,5]]},"3376":{"position":[[39,6]]},"3601":{"position":[[0,5]]},"4417":{"position":[[11,5]]},"4419":{"position":[[32,5]]}}}],["checklist",{"_index":56,"t":{"92":{"position":[[9,9]]},"204":{"position":[[0,9]]},"206":{"position":[[0,9]]},"208":{"position":[[0,9]]},"210":{"position":[[0,9]]},"215":{"position":[[0,9]]},"217":{"position":[[0,9]]},"219":{"position":[[0,9]]},"221":{"position":[[0,9]]},"223":{"position":[[0,9]]},"225":{"position":[[0,9]]},"227":{"position":[[0,9]]},"229":{"position":[[7,9]]},"236":{"position":[[0,9]]},"238":{"position":[[0,9]]},"240":{"position":[[0,9]]},"242":{"position":[[0,9]]},"244":{"position":[[0,9]]},"246":{"position":[[0,9]]}}}],["choos",{"_index":1034,"t":{"4312":{"position":[[0,8]]},"4846":{"position":[[0,6]]}}}],["chosen",{"_index":828,"t":{"2575":{"position":[[4,6]]}}}],["ci",{"_index":760,"t":{"2228":{"position":[[0,2]]},"3045":{"position":[[0,2]]},"3046":{"position":[[5,2]]}}}],["ci/cd",{"_index":170,"t":{"268":{"position":[[5,5]]}}}],["cinder",{"_index":391,"t":{"847":{"position":[[0,6]]},"992":{"position":[[0,6]]},"1883":{"position":[[0,6]]},"2145":{"position":[[0,6]]},"2328":{"position":[[25,6]]},"2354":{"position":[[35,6]]},"2395":{"position":[[25,6]]},"2421":{"position":[[35,6]]}}}],["claim",{"_index":212,"t":{"322":{"position":[[30,6]]}}}],["class",{"_index":286,"t":{"538":{"position":[[11,5]]},"1638":{"position":[[41,7]]},"1969":{"position":[[41,7]]},"3873":{"position":[[21,5]]}}}],["clean",{"_index":446,"t":{"979":{"position":[[0,8]]},"1870":{"position":[[0,8]]},"3003":{"position":[[0,8]]}}}],["cleanup",{"_index":423,"t":{"941":{"position":[[23,7]]},"1530":{"position":[[0,7]]},"1742":{"position":[[0,7]]},"1832":{"position":[[23,7]]},"2965":{"position":[[23,7]]},"3557":{"position":[[10,7]]}}}],["cli",{"_index":21,"t":{"35":{"position":[[31,3]]},"36":{"position":[[16,5]]},"55":{"position":[[16,5]]},"326":{"position":[[14,3]]},"627":{"position":[[12,3]]},"931":{"position":[[24,3]]},"933":{"position":[[22,3]]},"1588":{"position":[[58,3]]},"1590":{"position":[[37,3]]},"1822":{"position":[[24,3]]},"1824":{"position":[[22,3]]},"1931":{"position":[[58,3]]},"1933":{"position":[[37,3]]},"1982":{"position":[[8,3]]},"2955":{"position":[[24,3]]},"2957":{"position":[[22,3]]}}}],["client",{"_index":167,"t":{"263":{"position":[[0,6]]},"702":{"position":[[7,6]]},"735":{"position":[[7,6]]},"1164":{"position":[[0,6]]},"1396":{"position":[[0,6]]},"2838":{"position":[[19,6]]}}}],["clone",{"_index":86,"t":{"131":{"position":[[9,7]]},"559":{"position":[[0,5]]},"1488":{"position":[[12,5]]},"4842":{"position":[[0,5]]}}}],["cloud",{"_index":11,"t":{"18":{"position":[[15,5]]},"196":{"position":[[10,5]]},"340":{"position":[[11,6]]},"777":{"position":[[39,5]]},"781":{"position":[[36,5]]},"783":{"position":[[25,5]]},"799":{"position":[[21,6]]},"801":{"position":[[53,6]]},"2177":{"position":[[0,5]]},"2179":{"position":[[0,5]]},"2486":{"position":[[0,5]]},"3190":{"position":[[35,6]]},"3366":{"position":[[10,5]]},"3372":{"position":[[10,5]]},"3522":{"position":[[10,5]]},"3766":{"position":[[15,6]]},"4132":{"position":[[57,5]]},"4828":{"position":[[51,5]]}}}],["cloudnam",{"_index":434,"t":{"958":{"position":[[7,9]]},"1849":{"position":[[7,9]]},"2982":{"position":[[7,9]]}}}],["clouds.yaml",{"_index":772,"t":{"2273":{"position":[[25,11]]}}}],["clouds.yml",{"_index":553,"t":{"1313":{"position":[[5,10]]}}}],["clush",{"_index":690,"t":{"1670":{"position":[[0,5]]}}}],["cluster",{"_index":7,"t":{"11":{"position":[[4,8]]},"14":{"position":[[4,8]]},"387":{"position":[[27,7]]},"388":{"position":[[14,7]]},"390":{"position":[[6,7]]},"394":{"position":[[11,7]]},"396":{"position":[[15,7],[31,7]]},"400":{"position":[[0,7]]},"402":{"position":[[0,7]]},"404":{"position":[[0,7]]},"406":{"position":[[14,7]]},"408":{"position":[[11,7]]},"410":{"position":[[15,7]]},"412":{"position":[[15,7]]},"420":{"position":[[0,7],[19,7]]},"422":{"position":[[4,7]]},"424":{"position":[[8,7]]},"426":{"position":[[12,7]]},"429":{"position":[[8,7]]},"445":{"position":[[0,7]]},"447":{"position":[[18,7]]},"449":{"position":[[23,7]]},"451":{"position":[[0,7]]},"453":{"position":[[0,7]]},"474":{"position":[[8,7]]},"511":{"position":[[18,7]]},"532":{"position":[[0,7]]},"536":{"position":[[12,7]]},"538":{"position":[[3,7]]},"540":{"position":[[3,7]]},"544":{"position":[[51,7]]},"569":{"position":[[14,7]]},"575":{"position":[[26,7]]},"585":{"position":[[7,7]]},"587":{"position":[[20,7]]},"589":{"position":[[19,7]]},"599":{"position":[[34,7]]},"601":{"position":[[35,7]]},"603":{"position":[[58,7]]},"605":{"position":[[33,7]]},"607":{"position":[[35,7]]},"654":{"position":[[9,7]]},"672":{"position":[[9,7]]},"689":{"position":[[26,8]]},"698":{"position":[[11,7]]},"731":{"position":[[11,8]]},"1012":{"position":[[16,7]]},"1015":{"position":[[12,7]]},"1017":{"position":[[0,7]]},"1057":{"position":[[24,7]]},"1058":{"position":[[0,7]]},"1059":{"position":[[0,7],[21,7]]},"1074":{"position":[[10,7]]},"1184":{"position":[[12,7]]},"1428":{"position":[[5,7]]},"1440":{"position":[[12,7]]},"1516":{"position":[[0,7]]},"1573":{"position":[[11,7]]},"1595":{"position":[[29,7]]},"1645":{"position":[[16,7]]},"1647":{"position":[[15,7]]},"1916":{"position":[[11,7]]},"2581":{"position":[[0,7],[17,7]]},"2611":{"position":[[23,7]]},"2641":{"position":[[38,7]]},"2643":{"position":[[21,7]]},"2654":{"position":[[19,7]]},"2669":{"position":[[38,7]]},"2671":{"position":[[21,7]]},"3090":{"position":[[0,7]]},"3120":{"position":[[52,7]]},"3123":{"position":[[0,7]]},"3154":{"position":[[52,7]]},"3186":{"position":[[9,7]]},"3190":{"position":[[68,7]]},"3231":{"position":[[52,7]]},"3286":{"position":[[52,7]]},"3330":{"position":[[52,7]]},"4873":{"position":[[30,7]]}}}],["clusterclass",{"_index":246,"t":{"392":{"position":[[8,14]]}}}],["clusterstack",{"_index":268,"t":{"455":{"position":[[0,12]]},"458":{"position":[[0,12]]},"460":{"position":[[15,12]]},"464":{"position":[[15,12]]},"509":{"position":[[9,12]]}}}],["clusterstack.spec",{"_index":271,"t":{"462":{"position":[[12,17]]}}}],["cni",{"_index":1055,"t":{"4568":{"position":[[18,3]]}}}],["code",{"_index":135,"t":{"195":{"position":[[0,4]]},"2107":{"position":[[17,4]]},"2905":{"position":[[13,4]]}}}],["codeblock",{"_index":93,"t":{"142":{"position":[[0,10]]}}}],["collabor",{"_index":37,"t":{"60":{"position":[[0,13]]},"188":{"position":[[14,13]]},"2706":{"position":[[0,13]]}}}],["collect",{"_index":103,"t":{"154":{"position":[[9,11]]},"156":{"position":[[26,11]]},"952":{"position":[[5,10]]},"1843":{"position":[[5,10]]},"2976":{"position":[[5,10]]},"3048":{"position":[[8,10]]}}}],["collector",{"_index":605,"t":{"1434":{"position":[[6,9]]},"1436":{"position":[[4,9]]}}}],["command",{"_index":331,"t":{"627":{"position":[[0,8]]},"2040":{"position":[[0,7]]},"2735":{"position":[[8,7]]},"4867":{"position":[[0,7]]}}}],["commit",{"_index":76,"t":{"118":{"position":[[4,6]]},"2092":{"position":[[0,6]]}}}],["common",{"_index":853,"t":{"2742":{"position":[[0,6]]},"3376":{"position":[[0,6]]},"4690":{"position":[[0,6]]}}}],["commun",{"_index":2,"t":{"6":{"position":[[19,9]]},"58":{"position":[[14,9]]},"98":{"position":[[3,9]]},"196":{"position":[[22,9]]},"2554":{"position":[[10,9]]},"3970":{"position":[[15,10]]},"4301":{"position":[[0,13]]}}}],["compact",{"_index":1041,"t":{"4490":{"position":[[5,10]]}}}],["compactor",{"_index":841,"t":{"2683":{"position":[[0,9]]}}}],["compani",{"_index":369,"t":{"783":{"position":[[3,7]]},"801":{"position":[[28,7]]}}}],["comparison",{"_index":1008,"t":{"4145":{"position":[[0,10]]},"4661":{"position":[[0,10]]}}}],["compat",{"_index":928,"t":{"3377":{"position":[[8,10]]},"3380":{"position":[[8,10]]},"3383":{"position":[[8,10]]}}}],["compil",{"_index":860,"t":{"2799":{"position":[[0,7]]}}}],["complet",{"_index":661,"t":{"1608":{"position":[[27,10]]},"1939":{"position":[[27,10]]},"3657":{"position":[[0,8]]},"3694":{"position":[[0,8]]},"3781":{"position":[[0,8]]}}}],["complianc",{"_index":185,"t":{"287":{"position":[[3,10]]},"3376":{"position":[[28,10]]},"3382":{"position":[[16,10]]},"3703":{"position":[[14,10]]},"3792":{"position":[[14,10]]}}}],["compliant",{"_index":373,"t":{"787":{"position":[[56,10]]},"3366":{"position":[[0,9]]},"3372":{"position":[[0,9]]},"4267":{"position":[[20,9]]},"4568":{"position":[[8,9]]}}}],["compon",{"_index":455,"t":{"1012":{"position":[[0,10]]},"2645":{"position":[[23,10]]},"2775":{"position":[[5,10]]},"2777":{"position":[[7,9]]},"2779":{"position":[[4,9]]},"2811":{"position":[[0,10]]},"2888":{"position":[[0,10]]},"2890":{"position":[[0,9]]},"3082":{"position":[[0,9]]},"3115":{"position":[[0,9]]},"3149":{"position":[[0,9]]},"3181":{"position":[[0,9]]},"3219":{"position":[[0,9]]},"3277":{"position":[[0,9]]},"3327":{"position":[[0,9]]},"4708":{"position":[[0,9]]},"4832":{"position":[[6,10]]},"4846":{"position":[[12,10]]}}}],["component/compon",{"_index":944,"t":{"3570":{"position":[[7,19]]}}}],["compress",{"_index":587,"t":{"1402":{"position":[[24,12]]}}}],["comput",{"_index":382,"t":{"823":{"position":[[14,7]]},"1029":{"position":[[0,7]]},"1041":{"position":[[0,7]]},"1097":{"position":[[0,7]]},"1106":{"position":[[0,7]]},"1123":{"position":[[0,7]]},"1130":{"position":[[0,7]]},"1362":{"position":[[8,7]]},"1376":{"position":[[39,7]]},"1708":{"position":[[9,7]]},"1710":{"position":[[10,7]]},"1712":{"position":[[9,7]]},"1731":{"position":[[19,7]]},"1733":{"position":[[18,7]]},"3771":{"position":[[0,7]]},"4164":{"position":[[47,7]]},"4303":{"position":[[32,7]]}}}],["con",{"_index":1043,"t":{"4509":{"position":[[9,4]]}}}],["concept",{"_index":948,"t":{"3591":{"position":[[6,8]]},"4229":{"position":[[9,7]]}}}],["concern",{"_index":803,"t":{"2486":{"position":[[15,8]]},"2526":{"position":[[20,8]]}}}],["conclus",{"_index":816,"t":{"2521":{"position":[[0,10]]},"2748":{"position":[[0,10]]},"4521":{"position":[[0,10]]}}}],["condit",{"_index":102,"t":{"152":{"position":[[21,9]]}}}],["conduct",{"_index":136,"t":{"195":{"position":[[8,7]]}}}],["config",{"_index":405,"t":{"915":{"position":[[0,6]]},"1006":{"position":[[0,6]]},"1194":{"position":[[6,6]]},"1438":{"position":[[5,6]]},"1799":{"position":[[0,6]]},"1897":{"position":[[0,6]]},"2858":{"position":[[5,6]]}}}],["config.yaml",{"_index":585,"t":{"1388":{"position":[[0,11]]}}}],["configur",{"_index":72,"t":{"110":{"position":[[0,13]]},"472":{"position":[[0,9]]},"521":{"position":[[0,13]]},"619":{"position":[[0,13]]},"621":{"position":[[0,13]]},"660":{"position":[[0,11]]},"933":{"position":[[0,11]]},"1182":{"position":[[0,11]]},"1217":{"position":[[15,13]]},"1223":{"position":[[23,13]]},"1225":{"position":[[41,13]]},"1231":{"position":[[0,13]]},"1233":{"position":[[18,13]]},"1300":{"position":[[29,14]]},"1302":{"position":[[13,13]]},"1306":{"position":[[13,13]]},"1345":{"position":[[0,14]]},"1398":{"position":[[8,13]]},"1400":{"position":[[0,11]]},"1402":{"position":[[0,11]]},"1412":{"position":[[8,13]]},"1426":{"position":[[21,9]]},"1450":{"position":[[0,9]]},"1473":{"position":[[26,13]]},"1500":{"position":[[18,13]]},"1624":{"position":[[20,13]]},"1824":{"position":[[0,11]]},"1955":{"position":[[20,13]]},"2218":{"position":[[0,13]]},"2430":{"position":[[28,9]]},"2440":{"position":[[15,13]]},"2476":{"position":[[0,13]]},"2726":{"position":[[0,13]]},"2727":{"position":[[11,13]]},"2729":{"position":[[5,13]]},"2862":{"position":[[0,9]]},"2929":{"position":[[0,13]]},"2957":{"position":[[0,11]]},"3031":{"position":[[23,13]]},"3351":{"position":[[26,13]]},"3959":{"position":[[44,13]]},"4305":{"position":[[4,13]]},"4848":{"position":[[6,13]]}}}],["conform",{"_index":197,"t":{"304":{"position":[[15,11]]},"308":{"position":[[3,11]]},"350":{"position":[[11,10]]},"3102":{"position":[[10,11]]},"3135":{"position":[[10,11]]},"3167":{"position":[[10,11]]},"3205":{"position":[[10,11]]},"3258":{"position":[[10,11]]},"3307":{"position":[[10,11]]},"3336":{"position":[[10,11]]},"3836":{"position":[[0,11]]},"3882":{"position":[[0,11]]},"3905":{"position":[[0,11]]},"3937":{"position":[[0,11]]},"4033":{"position":[[0,11]]},"4054":{"position":[[0,11]]},"4088":{"position":[[0,11]]},"4129":{"position":[[0,11]]},"4170":{"position":[[0,11]]},"4209":{"position":[[0,11]]},"4260":{"position":[[0,11]]},"4314":{"position":[[19,11]]},"4336":{"position":[[0,11]]},"4347":{"position":[[0,11]]},"4358":{"position":[[0,11]]},"4381":{"position":[[0,11]]},"4406":{"position":[[0,11]]},"4498":{"position":[[0,11]]},"4548":{"position":[[0,11]]},"4583":{"position":[[0,11]]},"4600":{"position":[[0,11]]},"4601":{"position":[[0,11]]},"4628":{"position":[[0,11]]},"4650":{"position":[[0,11]]},"4751":{"position":[[0,11]]},"4770":{"position":[[0,11]]},"4804":{"position":[[0,11]]},"4823":{"position":[[0,11]]}}}],["connect",{"_index":229,"t":{"346":{"position":[[15,7]]},"2143":{"position":[[5,11]]},"2430":{"position":[[57,8]]},"4322":{"position":[[9,11]]},"4324":{"position":[[14,11]]},"4326":{"position":[[30,11]]},"4328":{"position":[[12,11]]},"4330":{"position":[[17,11]]},"4332":{"position":[[8,11]]}}}],["consequ",{"_index":997,"t":{"3997":{"position":[[0,12]]},"4110":{"position":[[0,12]]},"4149":{"position":[[0,12]]},"4192":{"position":[[0,12]]},"4785":{"position":[[0,12]]}}}],["consid",{"_index":706,"t":{"1980":{"position":[[0,8]]},"3927":{"position":[[8,10]]},"3946":{"position":[[8,10]]},"3967":{"position":[[8,10]]},"4080":{"position":[[8,10]]},"4123":{"position":[[8,10]]},"4162":{"position":[[8,10]]},"4256":{"position":[[8,10]]},"4309":{"position":[[8,10]]},"4579":{"position":[[8,10]]},"4592":{"position":[[8,10]]},"4613":{"position":[[8,10]]},"4642":{"position":[[8,10]]},"4727":{"position":[[8,10]]},"4796":{"position":[[8,10]]},"4815":{"position":[[8,10]]}}}],["consider",{"_index":562,"t":{"1330":{"position":[[4,14]]},"2286":{"position":[[17,14]]},"2300":{"position":[[17,14]]},"3547":{"position":[[7,14]]},"3609":{"position":[[7,14]]},"3691":{"position":[[7,14]]},"3732":{"position":[[7,14]]},"3778":{"position":[[7,14]]},"3877":{"position":[[10,14]]},"3926":{"position":[[7,14]]},"3944":{"position":[[7,14]]},"3965":{"position":[[7,14]]},"4010":{"position":[[7,14]]},"4044":{"position":[[7,14]]},"4078":{"position":[[7,14]]},"4121":{"position":[[7,14]]},"4158":{"position":[[7,14]]},"4188":{"position":[[7,14]]},"4223":{"position":[[12,14]]},"4254":{"position":[[7,14]]},"4276":{"position":[[7,14]]},"4299":{"position":[[7,14]]},"4415":{"position":[[7,14]]},"4432":{"position":[[7,14]]},"4445":{"position":[[7,14]]},"4456":{"position":[[7,14]]},"4476":{"position":[[7,14]]},"4505":{"position":[[7,14]]},"4577":{"position":[[7,14]]},"4590":{"position":[[7,14]]},"4611":{"position":[[7,14]]},"4640":{"position":[[7,14]]},"4741":{"position":[[7,14]]},"4760":{"position":[[7,14]]},"4794":{"position":[[7,14]]},"4813":{"position":[[7,14]]}}}],["consist",{"_index":1063,"t":{"4626":{"position":[[0,10]]}}}],["consol",{"_index":565,"t":{"1339":{"position":[[8,7]]},"2255":{"position":[[22,7]]}}}],["contain",{"_index":225,"t":{"338":{"position":[[0,9]]},"752":{"position":[[15,9]]},"795":{"position":[[21,10]]},"1492":{"position":[[30,9]]},"1541":{"position":[[7,10]]},"1672":{"position":[[0,9]]},"1695":{"position":[[0,9]]},"2075":{"position":[[17,9]]},"2589":{"position":[[6,9]]},"2797":{"position":[[7,9]]},"3065":{"position":[[0,9]]},"3184":{"position":[[0,9]]},"4286":{"position":[[16,9]]}}}],["containerfil",{"_index":732,"t":{"2091":{"position":[[0,14]]}}}],["context",{"_index":180,"t":{"283":{"position":[[40,7]]},"3981":{"position":[[0,7]]},"4097":{"position":[[0,7]]},"4143":{"position":[[0,7]]},"4218":{"position":[[0,7]]},"4781":{"position":[[0,7]]}}}],["continu",{"_index":469,"t":{"1051":{"position":[[7,8]]}}}],["contribut",{"_index":73,"t":{"112":{"position":[[0,10]]},"346":{"position":[[0,10]]},"3109":{"position":[[0,12]]},"3141":{"position":[[0,12]]},"3173":{"position":[[0,12]]},"3211":{"position":[[0,12]]},"3269":{"position":[[0,12]]},"3318":{"position":[[0,12]]},"3339":{"position":[[0,12]]},"4622":{"position":[[9,12]]}}}],["contributor",{"_index":126,"t":{"180":{"position":[[26,11]]}}}],["control",{"_index":279,"t":{"495":{"position":[[29,10]]},"497":{"position":[[26,10]]},"819":{"position":[[16,7]]},"821":{"position":[[14,7]]},"1027":{"position":[[0,7]]},"1039":{"position":[[0,7]]},"1098":{"position":[[0,7]]},"1104":{"position":[[0,7]]},"1124":{"position":[[0,7]]},"1131":{"position":[[0,7]]},"4540":{"position":[[15,7]]},"4878":{"position":[[8,10]]}}}],["controversi",{"_index":115,"t":{"172":{"position":[[0,11]]}}}],["convent",{"_index":194,"t":{"302":{"position":[[7,11]]}}}],["converg",{"_index":490,"t":{"1137":{"position":[[6,9]]}}}],["convers",{"_index":784,"t":{"2359":{"position":[[20,10]]},"2426":{"position":[[20,10]]}}}],["convert",{"_index":763,"t":{"2245":{"position":[[7,7]]}}}],["cookiecutt",{"_index":515,"t":{"1221":{"position":[[12,12]]}}}],["copi",{"_index":613,"t":{"1500":{"position":[[6,4]]},"2243":{"position":[[7,4]]}}}],["copyleft",{"_index":122,"t":{"176":{"position":[[34,8]]}}}],["copyright",{"_index":124,"t":{"180":{"position":[[0,9]]}}}],["core",{"_index":358,"t":{"721":{"position":[[7,5]]},"1368":{"position":[[10,5]]},"1372":{"position":[[12,5],[42,5]]},"1374":{"position":[[45,5]]},"1376":{"position":[[28,5]]},"1378":{"position":[[28,5]]}}}],["cpu",{"_index":510,"t":{"1188":{"position":[[0,3]]},"1366":{"position":[[5,4]]},"1372":{"position":[[8,3]]},"1380":{"position":[[29,3]]},"3660":{"position":[[11,3]]},"3670":{"position":[[11,3]]},"3697":{"position":[[11,3]]},"3711":{"position":[[11,3]]},"3784":{"position":[[11,3]]},"3804":{"position":[[11,3]]}}}],["crash",{"_index":604,"t":{"1434":{"position":[[0,5]]}}}],["crd",{"_index":593,"t":{"1406":{"position":[[30,3]]},"1408":{"position":[[24,3]]},"1410":{"position":[[28,3]]}}}],["creat",{"_index":242,"t":{"387":{"position":[[9,6]]},"439":{"position":[[8,6]]},"511":{"position":[[0,8]]},"569":{"position":[[0,6]]},"585":{"position":[[0,6]]},"587":{"position":[[0,6]]},"654":{"position":[[0,8]]},"672":{"position":[[0,8]]},"689":{"position":[[0,6]]},"1217":{"position":[[0,8]]},"1374":{"position":[[0,6]]},"1380":{"position":[[0,8]]},"1471":{"position":[[8,6]]},"1560":{"position":[[0,6]]},"1630":{"position":[[0,6]]},"1638":{"position":[[0,6]]},"1706":{"position":[[0,6]]},"1961":{"position":[[0,6]]},"1969":{"position":[[0,6]]},"2145":{"position":[[14,6]]},"2251":{"position":[[7,6]]},"2264":{"position":[[0,8]]},"2269":{"position":[[12,7]]},"2288":{"position":[[7,6]]},"2302":{"position":[[7,6]]},"2450":{"position":[[0,8]]},"2452":{"position":[[0,8]]},"2739":{"position":[[0,8]]},"2761":{"position":[[0,6]]},"2765":{"position":[[0,6]]},"2771":{"position":[[0,6]]},"2777":{"position":[[0,6]]},"2783":{"position":[[0,6]]},"2789":{"position":[[0,6]]}}}],["create.pi",{"_index":403,"t":{"905":{"position":[[0,9]]},"911":{"position":[[0,9]]},"1789":{"position":[[0,9]]},"1795":{"position":[[0,9]]}}}],["creation",{"_index":746,"t":{"2141":{"position":[[9,8]]},"2357":{"position":[[6,8]]},"2424":{"position":[[6,8]]},"2444":{"position":[[24,8]]}}}],["credenti",{"_index":346,"t":{"700":{"position":[[18,11]]},"733":{"position":[[18,11]]},"4884":{"position":[[10,11]]}}}],["criteria",{"_index":187,"t":{"287":{"position":[[31,8]]},"3543":{"position":[[14,8]]},"3545":{"position":[[16,8]]}}}],["critic",{"_index":744,"t":{"2138":{"position":[[0,8]]}}}],["cronjob",{"_index":831,"t":{"2595":{"position":[[11,7]]}}}],["cross",{"_index":1009,"t":{"4164":{"position":[[0,5]]}}}],["crossplan",{"_index":830,"t":{"2579":{"position":[[0,10]]}}}],["crush",{"_index":675,"t":{"1626":{"position":[[9,5]]},"1638":{"position":[[7,5]]},"1640":{"position":[[7,5]]},"1957":{"position":[[9,5]]},"1969":{"position":[[7,5]]},"1971":{"position":[[7,5]]}}}],["csctl",{"_index":295,"t":{"565":{"position":[[0,5]]},"640":{"position":[[10,5]]},"642":{"position":[[19,5]]},"652":{"position":[[11,5]]},"660":{"position":[[12,5]]},"665":{"position":[[10,5]]},"667":{"position":[[12,5]]},"674":{"position":[[19,5]]}}}],["cso",{"_index":303,"t":{"577":{"position":[[0,3]]},"579":{"position":[[0,3]]}}}],["csp",{"_index":306,"t":{"577":{"position":[[35,5]]},"579":{"position":[[24,5]]},"583":{"position":[[7,3]]},"4732":{"position":[[15,3]]}}}],["csp/per",{"_index":309,"t":{"581":{"position":[[32,8]]},"585":{"position":[[32,8]]}}}],["cspo",{"_index":304,"t":{"577":{"position":[[8,4]]},"579":{"position":[[8,4]]}}}],["current",{"_index":786,"t":{"2381":{"position":[[0,7]]}}}],["custom",{"_index":269,"t":{"455":{"position":[[16,6]]},"529":{"position":[[4,13]]},"637":{"position":[[0,6]]},"650":{"position":[[0,6]]},"682":{"position":[[0,6]]},"935":{"position":[[0,6]]},"1300":{"position":[[0,13]]},"1315":{"position":[[0,6]]},"1660":{"position":[[7,6]]},"1826":{"position":[[0,6]]},"2187":{"position":[[0,6]]},"2959":{"position":[[0,6]]},"3867":{"position":[[10,6]]},"4040":{"position":[[25,6]]}}}],["customis",{"_index":728,"t":{"2046":{"position":[[0,14]]}}}],["daemon",{"_index":603,"t":{"1432":{"position":[[29,7]]}}}],["daili",{"_index":805,"t":{"2500":{"position":[[14,5]]}}}],["dashboard",{"_index":429,"t":{"952":{"position":[[20,9]]},"1180":{"position":[[0,9]]},"1182":{"position":[[58,9]]},"1424":{"position":[[0,9]]},"1426":{"position":[[7,9]]},"1843":{"position":[[20,9]]},"1908":{"position":[[0,9]]},"2675":{"position":[[23,10]]},"2870":{"position":[[0,10]]},"2976":{"position":[[20,9]]},"3048":{"position":[[23,10]]},"3049":{"position":[[33,10]]}}}],["data",{"_index":236,"t":{"359":{"position":[[32,5]]},"713":{"position":[[0,4]]},"952":{"position":[[0,4]]},"1125":{"position":[[0,4]]},"1132":{"position":[[0,4]]},"1584":{"position":[[6,4]]},"1843":{"position":[[0,4]]},"1927":{"position":[[6,4]]},"2322":{"position":[[28,4]]},"2328":{"position":[[7,4]]},"2334":{"position":[[7,4]]},"2389":{"position":[[28,4]]},"2395":{"position":[[7,4]]},"2401":{"position":[[7,4]]},"2976":{"position":[[0,4]]}}}],["databas",{"_index":351,"t":{"716":{"position":[[0,8]]},"1560":{"position":[[7,8]]},"2141":{"position":[[0,8]]},"2823":{"position":[[0,8]]},"2842":{"position":[[25,9]]},"4322":{"position":[[0,8]]},"4680":{"position":[[0,8]]}}}],["day",{"_index":162,"t":{"242":{"position":[[14,3]]},"244":{"position":[[20,3]]}}}],["db",{"_index":705,"t":{"1742":{"position":[[37,2]]}}}],["deactiv",{"_index":497,"t":{"1158":{"position":[[32,11]]}}}],["debian",{"_index":493,"t":{"1146":{"position":[[0,6]]}}}],["debug",{"_index":443,"t":{"975":{"position":[[0,9]]},"1866":{"position":[[0,9]]},"1993":{"position":[[0,9]]},"1995":{"position":[[15,5]]},"2999":{"position":[[0,9]]}}}],["decis",{"_index":990,"t":{"3929":{"position":[[0,8]]},"3950":{"position":[[0,8]]},"3972":{"position":[[0,8]]},"3995":{"position":[[0,9]]},"4099":{"position":[[13,8]]},"4105":{"position":[[0,8]]},"4147":{"position":[[0,8]]},"4190":{"position":[[0,8]]},"4231":{"position":[[0,8]]},"4290":{"position":[[0,8]]},"4343":{"position":[[0,8]]},"4354":{"position":[[0,8]]},"4373":{"position":[[0,8]]},"4398":{"position":[[0,8]]},"4434":{"position":[[0,8]]},"4447":{"position":[[0,8]]},"4458":{"position":[[0,8]]},"4486":{"position":[[0,8]]},"4563":{"position":[[0,8]]},"4581":{"position":[[0,8]]},"4596":{"position":[[0,8]]},"4615":{"position":[[0,8]]},"4631":{"position":[[0,8]]},"4646":{"position":[[0,8]]},"4657":{"position":[[0,8]]},"4677":{"position":[[0,8]]},"4689":{"position":[[0,8]]},"4729":{"position":[[0,9]]},"4745":{"position":[[0,8]]},"4766":{"position":[[0,8]]},"4783":{"position":[[0,8]]},"4800":{"position":[[0,8]]}}}],["decrypt",{"_index":785,"t":{"2359":{"position":[[34,7]]},"2426":{"position":[[34,7]]}}}],["dedic",{"_index":574,"t":{"1368":{"position":[[0,9]]},"1372":{"position":[[32,9]]},"1374":{"position":[[35,9]]},"1376":{"position":[[7,9]]},"1378":{"position":[[7,9]]}}}],["deep",{"_index":635,"t":{"1577":{"position":[[15,5]]},"1616":{"position":[[6,5]]},"1920":{"position":[[15,5]]},"1947":{"position":[[6,5]]}}}],["deeper",{"_index":1053,"t":{"4561":{"position":[[0,6]]}}}],["default",{"_index":402,"t":{"904":{"position":[[0,8]]},"1002":{"position":[[0,8]]},"1198":{"position":[[0,8]]},"1788":{"position":[[0,8]]},"1893":{"position":[[0,8]]},"2089":{"position":[[9,8]]},"2290":{"position":[[0,7]]},"2304":{"position":[[0,7]]},"3987":{"position":[[27,7],[49,9]]},"4016":{"position":[[0,7]]},"4040":{"position":[[0,7],[52,7]]},"4626":{"position":[[22,7]]}}}],["defect",{"_index":655,"t":{"1601":{"position":[[10,6]]},"2558":{"position":[[0,6]]},"2597":{"position":[[0,6]]}}}],["defectdojo",{"_index":800,"t":{"2477":{"position":[[0,10]]}}}],["defin",{"_index":255,"t":{"408":{"position":[[0,8]]},"546":{"position":[[3,8]]},"581":{"position":[[0,6]]},"1213":{"position":[[0,6]]},"2118":{"position":[[0,6]]}}}],["definit",{"_index":267,"t":{"447":{"position":[[2,10]]},"455":{"position":[[32,10]]},"585":{"position":[[21,10]]},"811":{"position":[[0,10]]},"813":{"position":[[0,10]]},"815":{"position":[[0,10]]},"817":{"position":[[0,10]]},"819":{"position":[[0,10]]},"821":{"position":[[0,10]]},"823":{"position":[[0,10]]},"825":{"position":[[0,10]]},"827":{"position":[[0,10]]},"829":{"position":[[0,10]]},"866":{"position":[[6,11]]},"895":{"position":[[0,11]]},"1026":{"position":[[10,11]]},"1753":{"position":[[0,11]]},"1767":{"position":[[6,11]]},"3624":{"position":[[0,11]]},"4690":{"position":[[7,11]]},"4737":{"position":[[0,11]]},"4756":{"position":[[0,11]]}}}],["delet",{"_index":627,"t":{"1565":{"position":[[0,6]]},"1634":{"position":[[0,6]]},"1965":{"position":[[0,6]]}}}],["demonstr",{"_index":29,"t":{"43":{"position":[[31,12]]}}}],["depend",{"_index":88,"t":{"133":{"position":[[20,12]]},"3612":{"position":[[0,10]]}}}],["deploy",{"_index":222,"t":{"328":{"position":[[34,11]]},"335":{"position":[[14,10]]},"579":{"position":[[13,10]]},"583":{"position":[[0,6]]},"1035":{"position":[[14,10]]},"1343":{"position":[[0,10]]},"1414":{"position":[[0,6]]},"1416":{"position":[[0,6]]},"1418":{"position":[[0,6]]},"1469":{"position":[[0,6]]},"1477":{"position":[[8,6]]},"2077":{"position":[[12,10]]},"2183":{"position":[[0,10]]},"2202":{"position":[[0,6]]},"2367":{"position":[[0,10]]},"2568":{"position":[[0,10]]},"2613":{"position":[[0,6]]},"2641":{"position":[[46,8]]},"2643":{"position":[[38,10]]},"2645":{"position":[[0,6]]},"2656":{"position":[[0,6]]},"2669":{"position":[[46,8]]},"2671":{"position":[[38,10]]},"2673":{"position":[[0,6]]},"2840":{"position":[[10,6]]},"2842":{"position":[[10,6]]},"2856":{"position":[[0,10]]},"2860":{"position":[[0,6]]},"2862":{"position":[[14,6]]},"2882":{"position":[[0,6]]},"2891":{"position":[[0,10]]},"4852":{"position":[[0,6]]},"4854":{"position":[[0,10]]},"4858":{"position":[[0,6]]},"4876":{"position":[[0,6]]}}}],["deprec",{"_index":904,"t":{"3096":{"position":[[0,12]]},"3129":{"position":[[0,12]]},"3160":{"position":[[0,12]]},"3161":{"position":[[0,12]]},"3198":{"position":[[0,12]]},"3199":{"position":[[0,12]]},"3243":{"position":[[0,12]]},"3303":{"position":[[0,12]]},"3333":{"position":[[0,12]]},"3538":{"position":[[0,11],[18,12]]}}}],["deriv",{"_index":117,"t":{"176":{"position":[[0,7]]}}}],["descript",{"_index":842,"t":{"2689":{"position":[[0,11]]},"2715":{"position":[[9,12]]},"4012":{"position":[[11,11]]}}}],["descriptor",{"_index":950,"t":{"3595":{"position":[[13,10]]},"3597":{"position":[[8,10]]},"3599":{"position":[[7,10]]},"3601":{"position":[[6,10]]},"3603":{"position":[[10,10]]}}}],["design",{"_index":326,"t":{"612":{"position":[[0,6]]},"1017":{"position":[[8,6]]},"3547":{"position":[[0,6]]},"3609":{"position":[[0,6]]},"3691":{"position":[[0,6]]},"3732":{"position":[[0,6]]},"3778":{"position":[[0,6]]},"3926":{"position":[[0,6]]},"3944":{"position":[[0,6]]},"3965":{"position":[[0,6]]},"4010":{"position":[[0,6]]},"4044":{"position":[[0,6]]},"4078":{"position":[[0,6]]},"4121":{"position":[[0,6]]},"4158":{"position":[[0,6]]},"4188":{"position":[[0,6]]},"4254":{"position":[[0,6]]},"4276":{"position":[[0,6]]},"4299":{"position":[[0,6]]},"4415":{"position":[[0,6]]},"4432":{"position":[[0,6]]},"4445":{"position":[[0,6]]},"4456":{"position":[[0,6]]},"4476":{"position":[[0,6]]},"4505":{"position":[[0,6]]},"4577":{"position":[[0,6]]},"4590":{"position":[[0,6]]},"4611":{"position":[[0,6]]},"4640":{"position":[[0,6]]},"4741":{"position":[[0,6]]},"4760":{"position":[[0,6]]},"4794":{"position":[[0,6]]},"4813":{"position":[[0,6]]}}}],["desir",{"_index":1038,"t":{"4419":{"position":[[13,9]]},"4609":{"position":[[0,7]]},"4858":{"position":[[11,7]]}}}],["detach",{"_index":777,"t":{"2330":{"position":[[10,8]]},"2336":{"position":[[24,8]]},"2397":{"position":[[10,8]]},"2403":{"position":[[24,8]]}}}],["detail",{"_index":327,"t":{"612":{"position":[[7,7]]},"2430":{"position":[[0,8]]},"3347":{"position":[[13,7]]},"3351":{"position":[[40,7]]},"3659":{"position":[[9,7]]},"3670":{"position":[[28,7]]},"3696":{"position":[[9,7]]},"3711":{"position":[[28,7]]},"3783":{"position":[[9,7]]},"3804":{"position":[[28,7]]},"4024":{"position":[[15,7]]},"4221":{"position":[[21,6]]}}}],["detect",{"_index":1022,"t":{"4265":{"position":[[11,9]]}}}],["develop",{"_index":78,"t":{"120":{"position":[[16,11]]},"135":{"position":[[22,11]]},"342":{"position":[[0,11]]},"429":{"position":[[0,7]]},"433":{"position":[[0,10]]},"507":{"position":[[0,10]]},"599":{"position":[[14,9]]},"601":{"position":[[14,9]]},"603":{"position":[[23,10]]},"605":{"position":[[14,9]]},"2051":{"position":[[0,11]]},"2210":{"position":[[28,11]]},"2519":{"position":[[14,11]]},"3087":{"position":[[4,9]]},"3120":{"position":[[4,9]]},"3154":{"position":[[4,9]]},"3190":{"position":[[4,9]]},"3231":{"position":[[4,9]]},"3286":{"position":[[4,9]]},"3330":{"position":[[4,9]]},"3534":{"position":[[0,11]]}}}],["devic",{"_index":504,"t":{"1174":{"position":[[4,7]]},"1414":{"position":[[35,7]]},"1416":{"position":[[34,7],[53,6]]},"1418":{"position":[[34,7],[51,6]]},"1581":{"position":[[34,7]]},"1582":{"position":[[26,7]]},"1584":{"position":[[33,7]]},"1586":{"position":[[23,6]]},"1588":{"position":[[14,6]]},"1924":{"position":[[34,7]]},"1925":{"position":[[26,7]]},"1927":{"position":[[33,7]]},"1929":{"position":[[23,6]]},"1931":{"position":[[14,6]]}}}],["devop",{"_index":814,"t":{"2509":{"position":[[10,9]]}}}],["dex",{"_index":862,"t":{"2825":{"position":[[0,3]]},"2838":{"position":[[0,3]]}}}],["differ",{"_index":337,"t":{"642":{"position":[[0,9]]},"674":{"position":[[0,9]]},"781":{"position":[[15,9]]},"1588":{"position":[[26,9]]},"1638":{"position":[[23,9]]},"1931":{"position":[[26,9]]},"1969":{"position":[[23,9]]},"4509":{"position":[[17,9]]}}}],["differenti",{"_index":1001,"t":{"4101":{"position":[[0,15]]}}}],["direct",{"_index":101,"t":{"150":{"position":[[34,9]]},"2085":{"position":[[7,9]]},"2087":{"position":[[5,9]]},"3107":{"position":[[7,10]]}}}],["directori",{"_index":735,"t":{"2099":{"position":[[33,11]]},"2105":{"position":[[19,11]]}}}],["disabl",{"_index":109,"t":{"162":{"position":[[0,7]]},"1608":{"position":[[0,7]]},"1731":{"position":[[0,7]]},"1939":{"position":[[0,7]]}}}],["disable/en",{"_index":634,"t":{"1577":{"position":[[0,14]]},"1920":{"position":[[0,14]]}}}],["disast",{"_index":1003,"t":{"4101":{"position":[[63,8]]}}}],["discov",{"_index":1024,"t":{"4269":{"position":[[38,10]]}}}],["discoveri",{"_index":209,"t":{"320":{"position":[[23,9]]},"3237":{"position":[[27,9]]}}}],["disk",{"_index":659,"t":{"1606":{"position":[[56,5]]},"2004":{"position":[[0,4]]},"3664":{"position":[[11,4]]},"3701":{"position":[[11,4]]},"3788":{"position":[[11,4]]}}}],["dispatch",{"_index":537,"t":{"1269":{"position":[[0,10]]}}}],["display",{"_index":622,"t":{"1546":{"position":[[0,7]]},"2125":{"position":[[23,10]]},"2129":{"position":[[18,9]]}}}],["distribut",{"_index":354,"t":{"718":{"position":[[4,12]]},"1145":{"position":[[0,12]]},"3564":{"position":[[0,11]]}}}],["doc",{"_index":629,"t":{"1568":{"position":[[14,4]]},"1901":{"position":[[14,4]]},"2136":{"position":[[14,4]]}}}],["docker",{"_index":300,"t":{"569":{"position":[[7,6]]},"1347":{"position":[[0,6]]},"1490":{"position":[[33,7]]},"2078":{"position":[[0,6]]},"2704":{"position":[[6,6]]},"4513":{"position":[[18,8]]},"4515":{"position":[[7,7]]}}}],["docs.json",{"_index":60,"t":{"94":{"position":[[33,9]]}}}],["document",{"_index":53,"t":{"89":{"position":[[9,13]]},"91":{"position":[[13,13]]},"96":{"position":[[15,13]]},"98":{"position":[[13,13]]},"290":{"position":[[23,8]]},"3252":{"position":[[0,13]]},"3349":{"position":[[10,13]]},"3354":{"position":[[14,8]]},"3522":{"position":[[25,9]]},"3524":{"position":[[9,9]]},"3526":{"position":[[0,8]]},"3564":{"position":[[12,13]]},"3734":{"position":[[8,9]]},"3935":{"position":[[8,9]]},"3952":{"position":[[8,9]]},"3974":{"position":[[8,9]]},"3999":{"position":[[8,9]]},"4031":{"position":[[8,9]]},"4052":{"position":[[8,9]]},"4086":{"position":[[8,9]]},"4127":{"position":[[8,9]]},"4168":{"position":[[8,9]]},"4177":{"position":[[9,13]]},"4179":{"position":[[12,13]]},"4207":{"position":[[8,9]]},"4334":{"position":[[8,9]]},"4345":{"position":[[8,9]]},"4356":{"position":[[8,9]]},"4404":{"position":[[8,9]]},"4423":{"position":[[8,9]]},"4436":{"position":[[0,9]]},"4496":{"position":[[8,9]]},"4550":{"position":[[8,9]]},"4565":{"position":[[8,9]]},"4588":{"position":[[20,8]]},"4598":{"position":[[8,9]]},"4621":{"position":[[8,9]]},"4648":{"position":[[8,9]]},"4749":{"position":[[8,9]]},"4768":{"position":[[8,9]]},"4787":{"position":[[8,9]]},"4802":{"position":[[8,9]]},"4821":{"position":[[8,9]]},"4828":{"position":[[20,13]]}}}],["dojo",{"_index":825,"t":{"2558":{"position":[[7,4]]},"2597":{"position":[[7,4]]}}}],["domain",{"_index":558,"t":{"1323":{"position":[[0,6]]},"2430":{"position":[[117,7]]},"2438":{"position":[[34,6]]},"2446":{"position":[[10,6]]},"2450":{"position":[[9,7]]},"2452":{"position":[[11,6]]},"2454":{"position":[[14,6]]},"2456":{"position":[[13,6]]},"2458":{"position":[[0,6]]},"2460":{"position":[[24,6]]},"2462":{"position":[[27,6]]},"2464":{"position":[[25,6]]},"2466":{"position":[[35,6]]},"3233":{"position":[[9,6]]},"3250":{"position":[[36,6]]},"3463":{"position":[[12,6]]},"4622":{"position":[[35,6]]}}}],["down",{"_index":701,"t":{"1733":{"position":[[6,4]]}}}],["download",{"_index":554,"t":{"1313":{"position":[[21,12]]},"1488":{"position":[[0,8]]},"2324":{"position":[[19,8]]},"2340":{"position":[[30,8]]},"2391":{"position":[[19,8]]},"2407":{"position":[[30,8]]}}}],["draft",{"_index":935,"t":{"3534":{"position":[[18,7]]}}}],["dri",{"_index":709,"t":{"1985":{"position":[[2,3]]},"2103":{"position":[[11,4]]}}}],["drive",{"_index":650,"t":{"1590":{"position":[[20,5]]},"1592":{"position":[[24,5]]},"1933":{"position":[[20,5]]},"1935":{"position":[[24,5]]}}}],["driver",{"_index":410,"t":{"925":{"position":[[15,6]]},"931":{"position":[[0,6]]},"933":{"position":[[33,6]]},"1450":{"position":[[18,7]]},"1816":{"position":[[15,6]]},"1822":{"position":[[0,6]]},"1824":{"position":[[33,6]]},"2949":{"position":[[15,6]]},"2955":{"position":[[0,6]]},"2957":{"position":[[33,6]]}}}],["dummi",{"_index":538,"t":{"1270":{"position":[[0,5]]}}}],["dump",{"_index":663,"t":{"1612":{"position":[[0,4]]},"1626":{"position":[[0,4]]},"1943":{"position":[[0,4]]},"1957":{"position":[[0,4]]}}}],["dynam",{"_index":991,"t":{"3959":{"position":[[28,7]]}}}],["e.g",{"_index":335,"t":{"637":{"position":[[7,5]]},"781":{"position":[[55,5]]},"1606":{"position":[[27,4]]}}}],["e2",{"_index":1031,"t":{"4280":{"position":[[59,3]]}}}],["eas",{"_index":1020,"t":{"4239":{"position":[[23,4]]}}}],["ec2",{"_index":345,"t":{"700":{"position":[[14,3]]},"733":{"position":[[14,3]]}}}],["edit",{"_index":765,"t":{"2247":{"position":[[0,4]]},"2554":{"position":[[20,7]]}}}],["editor",{"_index":738,"t":{"2107":{"position":[[22,7]]},"2275":{"position":[[8,6]]}}}],["elect",{"_index":956,"t":{"3630":{"position":[[0,8]]}}}],["elector",{"_index":962,"t":{"3639":{"position":[[0,9]]}}}],["elig",{"_index":960,"t":{"3637":{"position":[[0,8]]}}}],["email",{"_index":428,"t":{"948":{"position":[[0,5]]},"1839":{"position":[[0,5]]},"2972":{"position":[[0,5]]}}}],["enabl",{"_index":495,"t":{"1156":{"position":[[10,6]]},"1426":{"position":[[0,6]]},"1632":{"position":[[0,8]]},"1731":{"position":[[10,6]]},"1963":{"position":[[0,8]]},"2621":{"position":[[0,6]]}}}],["encrypt",{"_index":523,"t":{"1237":{"position":[[13,9]]},"1249":{"position":[[39,7]]},"1402":{"position":[[12,11]]},"1422":{"position":[[0,9]]},"2342":{"position":[[11,10]]},"2350":{"position":[[25,9]]},"2359":{"position":[[5,10]]},"2409":{"position":[[11,10]]},"2417":{"position":[[25,9]]},"2426":{"position":[[5,10]]},"4025":{"position":[[0,10]]},"4237":{"position":[[16,10]]}}}],["end",{"_index":549,"t":{"1306":{"position":[[5,3]]}}}],["endpoint",{"_index":408,"t":{"919":{"position":[[6,9]]},"1293":{"position":[[0,9]]},"1294":{"position":[[7,9]]},"1296":{"position":[[34,9]]},"1803":{"position":[[6,9]]},"2868":{"position":[[0,9]]},"4536":{"position":[[9,9]]},"4696":{"position":[[0,8]]}}}],["entir",{"_index":736,"t":{"2101":{"position":[[14,6]]}}}],["entri",{"_index":753,"t":{"2191":{"position":[[7,7]]},"3605":{"position":[[9,5]]}}}],["entropi",{"_index":976,"t":{"3756":{"position":[[0,7]]},"3758":{"position":[[19,7]]},"3760":{"position":[[11,7]]},"3762":{"position":[[0,7]]},"3766":{"position":[[0,7]]}}}],["enumer",{"_index":640,"t":{"1582":{"position":[[0,9]]},"1925":{"position":[[0,9]]}}}],["environ",{"_index":330,"t":{"625":{"position":[[0,11]]},"777":{"position":[[45,12]]},"781":{"position":[[42,12]]},"783":{"position":[[31,12]]},"1047":{"position":[[59,12]]},"1662":{"position":[[70,11]]},"2641":{"position":[[6,11]]},"2669":{"position":[[6,11]]},"3366":{"position":[[16,12]]},"3372":{"position":[[16,12]]},"4513":{"position":[[6,11]]},"4844":{"position":[[22,11]]},"4866":{"position":[[26,11]]}}}],["ephemer",{"_index":776,"t":{"2326":{"position":[[0,9]]},"2393":{"position":[[0,9]]}}}],["eras",{"_index":649,"t":{"1590":{"position":[[7,5]]},"1592":{"position":[[7,5]]},"1933":{"position":[[7,5]]},"1935":{"position":[[7,5]]}}}],["err",{"_index":284,"t":{"517":{"position":[[30,3]]}}}],["error",{"_index":672,"t":{"1620":{"position":[[41,6]]},"1951":{"position":[[41,6]]},"2138":{"position":[[16,5]]},"2213":{"position":[[8,6]]},"2742":{"position":[[7,6]]},"3746":{"position":[[0,6]]},"3854":{"position":[[0,6]]}}}],["etc",{"_index":870,"t":{"2842":{"position":[[73,4]]}}}],["etc/host",{"_index":754,"t":{"2191":{"position":[[18,10]]}}}],["etc/interfac",{"_index":539,"t":{"1272":{"position":[[0,15]]}}}],["etcd",{"_index":1040,"t":{"4480":{"position":[[0,4]]},"4482":{"position":[[0,4]]},"4490":{"position":[[0,4]]},"4492":{"position":[[0,4]]},"4534":{"position":[[9,4]]}}}],["evacu",{"_index":449,"t":{"987":{"position":[[0,10]]},"1878":{"position":[[0,10]]}}}],["evalu",{"_index":1052,"t":{"4559":{"position":[[0,9]]}}}],["even",{"_index":150,"t":{"217":{"position":[[14,7]]},"225":{"position":[[10,7]]}}}],["event",{"_index":155,"t":{"225":{"position":[[18,5]]}}}],["event_definitions.yaml",{"_index":885,"t":{"3035":{"position":[[4,22]]}}}],["event_pipeline.yaml",{"_index":886,"t":{"3037":{"position":[[4,19]]}}}],["everyth",{"_index":257,"t":{"414":{"position":[[6,10]]}}}],["exampl",{"_index":154,"t":{"221":{"position":[[16,10]]},"230":{"position":[[10,8]]},"234":{"position":[[12,8]]},"289":{"position":[[0,8]]},"290":{"position":[[4,8]]},"294":{"position":[[4,8]]},"306":{"position":[[12,7]]},"335":{"position":[[25,8]]},"464":{"position":[[0,7]]},"554":{"position":[[0,7]]},"1035":{"position":[[25,7]]},"1176":{"position":[[5,8]]},"1196":{"position":[[0,7]]},"1267":{"position":[[0,7]]},"1296":{"position":[[0,7]]},"1662":{"position":[[0,7]]},"1664":{"position":[[0,7]]},"2066":{"position":[[0,7]]},"2109":{"position":[[0,7]]},"2122":{"position":[[0,7]]},"2662":{"position":[[0,7]]},"2735":{"position":[[0,7]]},"3433":{"position":[[12,8]]},"3674":{"position":[[9,8]]},"3719":{"position":[[9,8]]},"3812":{"position":[[9,8]]},"3875":{"position":[[5,7]]},"4029":{"position":[[0,7]]},"4050":{"position":[[0,7]]},"4132":{"position":[[0,8]]},"4278":{"position":[[76,8]]}}}],["exchang",{"_index":879,"t":{"2907":{"position":[[0,8]]}}}],["exclud",{"_index":737,"t":{"2105":{"position":[[0,9]]}}}],["execut",{"_index":843,"t":{"2694":{"position":[[0,7]]},"2696":{"position":[[0,7]]}}}],["exempl",{"_index":158,"t":{"232":{"position":[[6,8]]}}}],["exist",{"_index":797,"t":{"2454":{"position":[[40,8]]},"4233":{"position":[[8,8]]},"4655":{"position":[[0,8]]}}}],["explor",{"_index":1016,"t":{"4225":{"position":[[0,11]]}}}],["export",{"_index":848,"t":{"2702":{"position":[[0,9]]},"3049":{"position":[[11,9]]}}}],["expos",{"_index":508,"t":{"1182":{"position":[[42,6]]}}}],["exposur",{"_index":793,"t":{"2438":{"position":[[22,8]]}}}],["extend",{"_index":851,"t":{"2715":{"position":[[0,8]]}}}],["extens",{"_index":971,"t":{"3705":{"position":[[0,10]]},"3798":{"position":[[0,10]]}}}],["extern",{"_index":413,"t":{"927":{"position":[[12,8]]},"1706":{"position":[[10,8]]},"1818":{"position":[[12,8]]},"2047":{"position":[[19,8]]},"2198":{"position":[[0,8]]},"2951":{"position":[[12,8]]},"4328":{"position":[[0,8]]}}}],["extra",{"_index":502,"t":{"1170":{"position":[[0,5]]},"1172":{"position":[[0,5]]},"1194":{"position":[[0,5]]},"1410":{"position":[[0,5]]},"3672":{"position":[[11,5]]}}}],["extra_spec",{"_index":984,"t":{"3893":{"position":[[11,13]]}}}],["fabric",{"_index":541,"t":{"1274":{"position":[[5,6]]}}}],["fact",{"_index":692,"t":{"1682":{"position":[[5,5]]}}}],["fail",{"_index":739,"t":{"2109":{"position":[[11,6]]},"2141":{"position":[[18,5]]}}}],["failsaf",{"_index":1002,"t":{"4101":{"position":[[24,8]]},"4103":{"position":[[0,8]]},"4106":{"position":[[0,8]]}}}],["failur",{"_index":445,"t":{"977":{"position":[[10,8]]},"1868":{"position":[[10,8]]},"2145":{"position":[[21,7]]},"3001":{"position":[[10,8]]},"3433":{"position":[[24,7]]},"4108":{"position":[[0,7]]},"4132":{"position":[[36,7]]}}}],["faq`",{"_index":74,"t":{"114":{"position":[[0,5]]}}}],["featur",{"_index":240,"t":{"377":{"position":[[0,8]]},"667":{"position":[[0,8]]},"2377":{"position":[[0,8]]},"2735":{"position":[[34,7]]},"2737":{"position":[[11,8]]},"2739":{"position":[[13,7]]},"3015":{"position":[[0,8]]},"3084":{"position":[[4,8]]},"3117":{"position":[[4,8]]},"3151":{"position":[[4,8]]},"3228":{"position":[[4,8]]},"3282":{"position":[[4,8]]},"3328":{"position":[[4,8]]},"3672":{"position":[[17,8]]},"3825":{"position":[[27,8]]},"4145":{"position":[[14,8]]},"4419":{"position":[[23,8]]},"4507":{"position":[[9,8]]}}}],["feder",{"_index":216,"t":{"324":{"position":[[23,9]]},"326":{"position":[[37,9]]},"328":{"position":[[8,10]]},"1325":{"position":[[5,10]]},"2373":{"position":[[11,10]]},"2430":{"position":[[38,10]]},"3056":{"position":[[0,10]]}}}],["feed",{"_index":931,"t":{"3382":{"position":[[7,4]]}}}],["field",{"_index":880,"t":{"2931":{"position":[[0,5]]},"4694":{"position":[[11,6]]}}}],["file",{"_index":329,"t":{"621":{"position":[[14,4]]},"915":{"position":[[7,5]]},"950":{"position":[[4,5]]},"1006":{"position":[[7,5]]},"1237":{"position":[[23,5]]},"1313":{"position":[[16,4],[62,4]]},"1442":{"position":[[11,4]]},"1691":{"position":[[0,5]]},"1799":{"position":[[7,5]]},"1841":{"position":[[4,5]]},"1897":{"position":[[7,5]]},"1980":{"position":[[24,4]]},"2097":{"position":[[20,4]]},"2099":{"position":[[20,5]]},"2105":{"position":[[10,5]]},"2566":{"position":[[5,5]]},"2735":{"position":[[42,4]]},"2739":{"position":[[21,5]]},"2929":{"position":[[14,4]]},"2974":{"position":[[4,5]]},"3610":{"position":[[0,4]]}}}],["filter",{"_index":577,"t":{"1370":{"position":[[18,6]]},"1416":{"position":[[60,6]]},"3250":{"position":[[22,9]]}}}],["find",{"_index":366,"t":{"779":{"position":[[12,4]]},"803":{"position":[[40,4]]},"1568":{"position":[[9,4]]},"1901":{"position":[[9,4]]},"2136":{"position":[[9,4]]}}}],["firewal",{"_index":871,"t":{"2852":{"position":[[0,8]]}}}],["first",{"_index":417,"t":{"937":{"position":[[5,5]]},"1828":{"position":[[5,5]]},"2961":{"position":[[5,5]]},"4856":{"position":[[0,5]]}}}],["fix",{"_index":905,"t":{"3098":{"position":[[9,5]]},"3131":{"position":[[9,5]]},"3163":{"position":[[9,5]]},"3201":{"position":[[9,5]]},"3245":{"position":[[9,5]]},"3305":{"position":[[9,5]]},"3334":{"position":[[9,5]]}}}],["fixes/new",{"_index":854,"t":{"2746":{"position":[[7,9]]}}}],["flag",{"_index":273,"t":{"486":{"position":[[12,5]]},"623":{"position":[[0,5]]}}}],["flasharray",{"_index":544,"t":{"1284":{"position":[[13,10]]}}}],["flavor",{"_index":580,"t":{"1374":{"position":[[7,7]]},"3676":{"position":[[13,7]]},"3694":{"position":[[33,6]]},"3767":{"position":[[0,7]]},"3781":{"position":[[33,6]]},"3790":{"position":[[13,7]]},"3895":{"position":[[13,7]]}}}],["flexibl",{"_index":589,"t":{"1404":{"position":[[0,8]]},"1420":{"position":[[0,8]]}}}],["flow",{"_index":856,"t":{"2746":{"position":[[48,5]]}}}],["fluxcd",{"_index":340,"t":{"693":{"position":[[30,6]]}}}],["focus",{"_index":902,"t":{"3085":{"position":[[9,7]]},"3087":{"position":[[14,7]]},"3118":{"position":[[9,7]]},"3120":{"position":[[14,7]]},"3152":{"position":[[9,7]]},"3154":{"position":[[14,7]]},"3190":{"position":[[14,7]]},"3229":{"position":[[9,7]]},"3231":{"position":[[14,7]]},"3283":{"position":[[9,7]]},"3286":{"position":[[14,7]]},"3329":{"position":[[9,7]]},"3330":{"position":[[14,7]]},"3993":{"position":[[19,7]]}}}],["footnot",{"_index":799,"t":{"2468":{"position":[[0,9]]},"2585":{"position":[[0,9]]},"2893":{"position":[[0,9]]},"2925":{"position":[[0,9]]},"4001":{"position":[[0,9]]},"4056":{"position":[[0,9]]},"4069":{"position":[[0,9]]},"4090":{"position":[[0,9]]},"4138":{"position":[[0,9]]},"4172":{"position":[[0,9]]},"4211":{"position":[[0,9]]},"4245":{"position":[[0,9]]},"4262":{"position":[[0,9]]},"4633":{"position":[[0,9]]},"4670":{"position":[[0,9]]}}}],["forc",{"_index":700,"t":{"1733":{"position":[[0,5]]}}}],["form",{"_index":324,"t":{"610":{"position":[[4,5]]}}}],["format",{"_index":646,"t":{"1586":{"position":[[6,6]]},"1588":{"position":[[0,6],[40,6]]},"1929":{"position":[[6,6]]},"1931":{"position":[[0,6],[40,6]]},"2097":{"position":[[0,10]]},"2099":{"position":[[0,10]]},"2101":{"position":[[0,10]]},"3526":{"position":[[9,6]]},"3574":{"position":[[18,6]]},"3610":{"position":[[5,6]]}}}],["forward",{"_index":876,"t":{"2884":{"position":[[5,7]]},"4519":{"position":[[14,7]]}}}],["found",{"_index":597,"t":{"1414":{"position":[[29,5]]},"1618":{"position":[[33,8]]},"1949":{"position":[[33,8]]}}}],["four",{"_index":134,"t":{"191":{"position":[[4,5]]}}}],["fqdn",{"_index":526,"t":{"1241":{"position":[[15,5]]}}}],["framework",{"_index":266,"t":{"445":{"position":[[14,9]]},"2693":{"position":[[15,9]]},"3045":{"position":[[3,9]]},"4278":{"position":[[41,9]]},"4280":{"position":[[87,9]]}}}],["friendli",{"_index":165,"t":{"257":{"position":[[21,8]]}}}],["frontend",{"_index":840,"t":{"2681":{"position":[[6,8]]},"2829":{"position":[[4,8]]},"2844":{"position":[[19,8]]},"2921":{"position":[[20,8]]}}}],["frozen",{"_index":748,"t":{"2151":{"position":[[0,6]]}}}],["full",{"_index":505,"t":{"1176":{"position":[[0,4]]},"3293":{"position":[[17,4]]},"3875":{"position":[[0,4]]}}}],["function",{"_index":855,"t":{"2746":{"position":[[17,15]]},"4622":{"position":[[50,13]]}}}],["fundament",{"_index":356,"t":{"720":{"position":[[0,11]]}}}],["further",{"_index":130,"t":{"184":{"position":[[0,7]]},"250":{"position":[[0,7]]},"1651":{"position":[[21,7]]},"1976":{"position":[[21,7]]},"2286":{"position":[[0,7]]},"2300":{"position":[[0,7]]},"3589":{"position":[[24,7]]},"4046":{"position":[[0,7]]},"4544":{"position":[[0,7]]}}}],["futur",{"_index":787,"t":{"2381":{"position":[[18,6]]},"2519":{"position":[[0,6]]},"3107":{"position":[[0,6]]}}}],["gaia",{"_index":27,"t":{"43":{"position":[[24,4]]},"3684":{"position":[[12,4]]}}}],["garden",{"_index":471,"t":{"1065":{"position":[[24,8]]}}}],["gate",{"_index":172,"t":{"268":{"position":[[33,6]]}}}],["gateway",{"_index":847,"t":{"2700":{"position":[[42,7]]},"2702":{"position":[[37,7]]}}}],["gather",{"_index":638,"t":{"1581":{"position":[[0,9]]},"1924":{"position":[[0,9]]}}}],["gener",{"_index":174,"t":{"272":{"position":[[0,7]]},"613":{"position":[[0,7]]},"615":{"position":[[0,7]]},"897":{"position":[[16,9]]},"1078":{"position":[[0,7]]},"1225":{"position":[[31,9]]},"1245":{"position":[[0,7]]},"1249":{"position":[[0,10]]},"1572":{"position":[[0,7]]},"1755":{"position":[[16,9]]},"1915":{"position":[[0,7]]},"2016":{"position":[[0,8]]},"3343":{"position":[[0,7]]}}}],["get",{"_index":18,"t":{"35":{"position":[[0,7]]},"43":{"position":[[0,7]]},"48":{"position":[[0,7]]},"108":{"position":[[0,7]]},"488":{"position":[[0,7]]},"864":{"position":[[0,7]]},"1765":{"position":[[0,7]]},"2691":{"position":[[0,7]]}}}],["gib",{"_index":552,"t":{"1311":{"position":[[48,3]]}}}],["git",{"_index":517,"t":{"1223":{"position":[[51,3]]},"1258":{"position":[[13,3]]},"2125":{"position":[[5,3]]},"2127":{"position":[[5,3]]}}}],["github",{"_index":79,"t":{"122":{"position":[[0,6]]},"441":{"position":[[19,6]]},"2120":{"position":[[0,6]]},"2838":{"position":[[12,6]]},"3626":{"position":[[17,6]]},"3628":{"position":[[16,6]]}}}],["gitrepositori",{"_index":342,"t":{"693":{"position":[[55,13]]}}}],["glanc",{"_index":386,"t":{"837":{"position":[[0,6]]},"860":{"position":[[24,8]]},"1761":{"position":[[24,8]]},"2326":{"position":[[31,6]]},"2334":{"position":[[25,6]]},"2336":{"position":[[0,6]]},"2338":{"position":[[0,6]]},"2393":{"position":[[31,6]]},"2401":{"position":[[25,6]]},"2403":{"position":[[0,6]]},"2405":{"position":[[0,6]]}}}],["global",{"_index":653,"t":{"1597":{"position":[[17,7]]}}}],["glossari",{"_index":774,"t":{"2318":{"position":[[0,8]]},"2385":{"position":[[0,8]]},"4006":{"position":[[0,8]]},"4095":{"position":[[0,8]]},"4428":{"position":[[0,8]]},"4441":{"position":[[0,8]]},"4452":{"position":[[0,8]]},"4472":{"position":[[0,8]]}}}],["go",{"_index":297,"t":{"567":{"position":[[0,2]]}}}],["goal",{"_index":894,"t":{"3066":{"position":[[13,5]]},"4099":{"position":[[0,4]]}}}],["golang",{"_index":1027,"t":{"4278":{"position":[[9,6]]},"4280":{"position":[[9,6]]}}}],["gpu",{"_index":972,"t":{"3713":{"position":[[11,3]]},"3743":{"position":[[0,3]]},"3806":{"position":[[11,3]]}}}],["grafana",{"_index":438,"t":{"962":{"position":[[0,7]]},"1088":{"position":[[24,7]]},"1853":{"position":[[0,7]]},"2986":{"position":[[0,7]]},"3049":{"position":[[25,7]]}}}],["graph",{"_index":953,"t":{"3612":{"position":[[11,5]]}}}],["greenbon",{"_index":822,"t":{"2554":{"position":[[0,9]]}}}],["group",{"_index":48,"t":{"67":{"position":[[17,6]]},"371":{"position":[[7,6]]},"1212":{"position":[[0,5]]},"1611":{"position":[[10,5]]},"1612":{"position":[[15,6]]},"1616":{"position":[[38,5]]},"1942":{"position":[[10,5]]},"1943":{"position":[[15,6]]},"1947":{"position":[[38,5]]},"2288":{"position":[[23,6]]},"2290":{"position":[[17,5]]},"2292":{"position":[[21,6]]},"2294":{"position":[[20,6]]},"2302":{"position":[[23,6]]},"2304":{"position":[[17,5]]},"2306":{"position":[[21,6]]},"2308":{"position":[[20,6]]},"2464":{"position":[[9,6]]},"3983":{"position":[[48,6]]},"3987":{"position":[[68,5]]},"4040":{"position":[[17,7],[41,6],[69,5]]}}}],["guarante",{"_index":985,"t":{"3901":{"position":[[0,10]]}}}],["guest",{"_index":715,"t":{"2006":{"position":[[5,5]]},"2010":{"position":[[0,5]]}}}],["guid",{"_index":82,"t":{"128":{"position":[[13,5]]},"2490":{"position":[[11,5]]},"2540":{"position":[[11,5]]},"3574":{"position":[[33,5]]},"3993":{"position":[[27,5]]}}}],["hack",{"_index":49,"t":{"67":{"position":[[35,7]]}}}],["hackathon",{"_index":143,"t":{"204":{"position":[[26,9]]},"208":{"position":[[26,9]]},"215":{"position":[[26,9]]},"223":{"position":[[26,9]]},"227":{"position":[[26,9]]},"238":{"position":[[25,9]]},"240":{"position":[[24,9]]},"242":{"position":[[25,9]]},"244":{"position":[[10,9]]},"246":{"position":[[16,9]]}}}],["handl",{"_index":731,"t":{"2054":{"position":[[7,6]]},"3827":{"position":[[6,8]]}}}],["hang",{"_index":743,"t":{"2131":{"position":[[0,7]]}}}],["harbor",{"_index":5,"t":{"10":{"position":[[16,6]]},"691":{"position":[[8,6]]},"707":{"position":[[7,6]]},"709":{"position":[[8,6]]},"746":{"position":[[8,6]]},"752":{"position":[[8,6]]}}}],["harden",{"_index":1047,"t":{"4530":{"position":[[0,9]]}}}],["hardwar",{"_index":456,"t":{"1021":{"position":[[0,8]]},"2012":{"position":[[0,9]]},"3668":{"position":[[11,8]]},"3709":{"position":[[11,8]]},"3802":{"position":[[11,8]]}}}],["hash",{"_index":333,"t":{"633":{"position":[[0,4]]},"644":{"position":[[0,4]]},"676":{"position":[[0,4]]}}}],["hci",{"_index":461,"t":{"1029":{"position":[[21,4]]},"1041":{"position":[[13,5]]},"1137":{"position":[[31,5]]}}}],["hci/no",{"_index":460,"t":{"1029":{"position":[[13,7]]}}}],["hdparm",{"_index":651,"t":{"1592":{"position":[[36,6]]},"1935":{"position":[[36,6]]}}}],["health",{"_index":314,"t":{"589":{"position":[[27,6]]},"970":{"position":[[19,6]]},"1575":{"position":[[14,6]]},"1861":{"position":[[19,6]]},"1918":{"position":[[14,6]]},"2994":{"position":[[19,6]]},"3051":{"position":[[10,6]]},"3291":{"position":[[18,6]]},"4417":{"position":[[4,6]]}}}],["health_warn",{"_index":667,"t":{"1618":{"position":[[0,11]]},"1949":{"position":[[0,11]]}}}],["helm",{"_index":606,"t":{"1442":{"position":[[0,4]]},"2729":{"position":[[0,4]]}}}],["help",{"_index":296,"t":{"565":{"position":[[8,4]]},"803":{"position":[[45,5]]},"1651":{"position":[[29,4]]},"1976":{"position":[[29,4]]},"1989":{"position":[[2,4]]}}}],["helper",{"_index":310,"t":{"583":{"position":[[11,6]]}}}],["hetzner",{"_index":1044,"t":{"4511":{"position":[[26,8]]}}}],["high",{"_index":810,"t":{"2505":{"position":[[14,5]]},"4101":{"position":[[44,4]]}}}],["highlevel",{"_index":454,"t":{"1011":{"position":[[0,9]]}}}],["highlight",{"_index":901,"t":{"3082":{"position":[[49,12]]},"3084":{"position":[[13,12]]},"3107":{"position":[[28,11]]},"3115":{"position":[[49,12]]},"3117":{"position":[[13,12]]},"3149":{"position":[[49,12]]},"3151":{"position":[[13,12]]},"3181":{"position":[[49,12]]},"3219":{"position":[[49,12]]},"3228":{"position":[[13,12]]},"3254":{"position":[[0,11]]},"3277":{"position":[[49,12]]},"3282":{"position":[[13,12]]},"3327":{"position":[[49,12]]},"3328":{"position":[[13,12]]}}}],["home",{"_index":916,"t":{"3237":{"position":[[18,4]]}}}],["horizon",{"_index":214,"t":{"324":{"position":[[4,7]]},"831":{"position":[[0,7]]}}}],["host",{"_index":378,"t":{"815":{"position":[[14,4]]},"1211":{"position":[[0,4]]},"1364":{"position":[[0,4]]},"1366":{"position":[[0,4]]},"1678":{"position":[[0,5]]},"1680":{"position":[[0,4]]},"1682":{"position":[[0,4]]},"1739":{"position":[[0,4]]}}}],["hotel",{"_index":146,"t":{"210":{"position":[[10,5]]}}}],["httpx",{"_index":820,"t":{"2550":{"position":[[0,5]]}}}],["huge",{"_index":702,"t":{"1735":{"position":[[0,4]]}}}],["hugepag",{"_index":583,"t":{"1382":{"position":[[24,9]]}}}],["hyper",{"_index":489,"t":{"1137":{"position":[[0,5]]}}}],["hypervisor",{"_index":968,"t":{"3666":{"position":[[11,10]]},"3707":{"position":[[11,10]]},"3800":{"position":[[11,10]]},"4303":{"position":[[8,10]]},"4312":{"position":[[55,10]]},"4326":{"position":[[0,10]]}}}],["iaa",{"_index":202,"t":{"312":{"position":[[3,4]]},"336":{"position":[[0,4]]},"544":{"position":[[3,4]]},"789":{"position":[[60,6]]},"791":{"position":[[10,4]]},"793":{"position":[[11,4]]},"2498":{"position":[[41,4]]},"2645":{"position":[[7,4]]},"3182":{"position":[[0,4]]},"3220":{"position":[[0,4]]},"3247":{"position":[[24,4]]},"3263":{"position":[[0,4]]},"3278":{"position":[[0,4]]},"3284":{"position":[[0,4]]},"3289":{"position":[[39,4]]},"3377":{"position":[[19,4]]},"3380":{"position":[[19,4]]},"3383":{"position":[[19,4]]},"3433":{"position":[[58,4]]},"3455":{"position":[[45,4]]},"4134":{"position":[[10,4],[25,5]]},"4201":{"position":[[10,4]]},"4203":{"position":[[10,4]]},"4205":{"position":[[12,4]]},"4258":{"position":[[23,4]]},"4267":{"position":[[49,4]]},"4511":{"position":[[0,4]]}}}],["iam",{"_index":912,"t":{"3188":{"position":[[15,3]]},"3226":{"position":[[0,3]]},"3256":{"position":[[0,3]]},"3267":{"position":[[0,3]]},"3297":{"position":[[0,3]]},"3312":{"position":[[0,3]]}}}],["ident",{"_index":483,"t":{"1101":{"position":[[0,8]]},"2371":{"position":[[0,8]]}}}],["identifi",{"_index":499,"t":{"1162":{"position":[[7,10]]},"1394":{"position":[[7,10]]},"2284":{"position":[[0,8]]},"2298":{"position":[[0,8]]}}}],["idp",{"_index":207,"t":{"320":{"position":[[13,3]]},"3237":{"position":[[23,3]]}}}],["imag",{"_index":288,"t":{"542":{"position":[[9,6]]},"860":{"position":[[10,5]]},"866":{"position":[[0,5]]},"868":{"position":[[4,5]]},"870":{"position":[[0,5]]},"872":{"position":[[0,5]]},"877":{"position":[[10,6]]},"879":{"position":[[9,6]]},"1291":{"position":[[0,5]]},"1311":{"position":[[27,6]]},"1374":{"position":[[18,6]]},"1380":{"position":[[9,6]]},"1463":{"position":[[34,6]]},"1761":{"position":[[10,5]]},"1767":{"position":[[0,5]]},"1769":{"position":[[4,5]]},"1771":{"position":[[0,5]]},"1773":{"position":[[0,5]]},"1778":{"position":[[10,6]]},"1780":{"position":[[9,6]]},"2042":{"position":[[21,6]]},"2075":{"position":[[27,5]]},"2243":{"position":[[17,6]]},"2247":{"position":[[13,6]]},"2249":{"position":[[14,6]]},"2262":{"position":[[15,5]]},"2324":{"position":[[0,5]]},"2326":{"position":[[38,6]]},"2334":{"position":[[32,6]]},"2336":{"position":[[7,5]]},"2338":{"position":[[7,5]]},"2348":{"position":[[37,5]]},"2350":{"position":[[35,5]]},"2352":{"position":[[34,5]]},"2357":{"position":[[0,5]]},"2359":{"position":[[49,6]]},"2391":{"position":[[0,5]]},"2393":{"position":[[38,6]]},"2401":{"position":[[32,6]]},"2403":{"position":[[7,5]]},"2405":{"position":[[7,5]]},"2415":{"position":[[37,5]]},"2417":{"position":[[35,5]]},"2419":{"position":[[34,5]]},"2424":{"position":[[0,5]]},"2426":{"position":[[49,6]]},"2534":{"position":[[9,6]]},"2704":{"position":[[13,5]]},"3769":{"position":[[0,6]]},"3827":{"position":[[0,5]]},"3828":{"position":[[0,5]]},"3830":{"position":[[0,5]]},"3832":{"position":[[0,5]]},"3842":{"position":[[0,6]]},"3852":{"position":[[0,6]]},"3867":{"position":[[17,6]]},"3869":{"position":[[9,6]]},"3871":{"position":[[0,5],[28,5]]},"3873":{"position":[[0,5],[30,6]]},"3880":{"position":[[0,5]]},"4284":{"position":[[42,5]]},"4288":{"position":[[15,5]]}}}],["impact",{"_index":420,"t":{"939":{"position":[[9,6]]},"1830":{"position":[[9,6]]},"2763":{"position":[[5,6]]},"2765":{"position":[[7,6]]},"2767":{"position":[[4,6]]},"2807":{"position":[[0,6]]},"2963":{"position":[[9,6]]},"3433":{"position":[[48,6]]},"4132":{"position":[[16,6]]},"4134":{"position":[[0,6]]},"4136":{"position":[[0,6]]},"4239":{"position":[[12,6]]},"4668":{"position":[[0,6]]},"4704":{"position":[[0,6]]},"4708":{"position":[[10,7]]}}}],["implement",{"_index":256,"t":{"410":{"position":[[0,12]]},"412":{"position":[[0,12]]},"449":{"position":[[3,14]]},"785":{"position":[[20,14]]},"787":{"position":[[31,14]]},"789":{"position":[[45,14]]},"2583":{"position":[[0,14]]},"2919":{"position":[[10,14]]},"2923":{"position":[[10,14]]},"3403":{"position":[[12,14]]},"3407":{"position":[[12,14]]},"3411":{"position":[[12,14]]},"3415":{"position":[[12,14]]},"3439":{"position":[[12,14]]},"3447":{"position":[[12,14]]},"3455":{"position":[[68,14]]},"3463":{"position":[[27,14]]},"3475":{"position":[[12,14]]},"3479":{"position":[[12,14]]},"3487":{"position":[[12,14]]},"3497":{"position":[[12,14]]},"3572":{"position":[[10,14]]},"3739":{"position":[[0,14]]},"3750":{"position":[[0,14]]},"3839":{"position":[[0,14]]},"3844":{"position":[[0,14]]},"3849":{"position":[[0,14]]},"3858":{"position":[[0,14]]},"3933":{"position":[[0,14]]},"4024":{"position":[[0,14]]},"4059":{"position":[[0,14]]},"4065":{"position":[[0,14]]},"4229":{"position":[[17,15]]},"4361":{"position":[[0,14]]},"4364":{"position":[[0,14]]},"4384":{"position":[[0,14]]},"4389":{"position":[[0,14]]},"4463":{"position":[[0,14]]},"4664":{"position":[[0,14]]}}}],["import",{"_index":726,"t":{"2042":{"position":[[0,6]]},"2249":{"position":[[7,6]]},"2500":{"position":[[0,10]]},"2623":{"position":[[12,8]]}}}],["improv",{"_index":900,"t":{"3082":{"position":[[36,12]]},"3085":{"position":[[17,12]]},"3087":{"position":[[22,12]]},"3115":{"position":[[36,12]]},"3118":{"position":[[17,12]]},"3120":{"position":[[22,12]]},"3149":{"position":[[36,12]]},"3152":{"position":[[17,12]]},"3154":{"position":[[22,12]]},"3181":{"position":[[36,12]]},"3190":{"position":[[22,12]]},"3219":{"position":[[36,12]]},"3229":{"position":[[17,12]]},"3231":{"position":[[22,12]]},"3277":{"position":[[36,12]]},"3283":{"position":[[17,12]]},"3286":{"position":[[22,12]]},"3327":{"position":[[36,12]]},"3329":{"position":[[17,12]]},"3330":{"position":[[22,12]]}}}],["incid",{"_index":859,"t":{"2781":{"position":[[5,9]]},"2783":{"position":[[7,8]]},"2785":{"position":[[4,8]]},"2787":{"position":[[5,8]]},"2789":{"position":[[7,8]]},"2791":{"position":[[4,8]]},"2813":{"position":[[0,9]]},"2815":{"position":[[0,8]]},"4698":{"position":[[0,9]]}}}],["includ",{"_index":759,"t":{"2224":{"position":[[0,8]]},"3655":{"position":[[20,8]]},"3692":{"position":[[20,8]]},"3779":{"position":[[20,8]]}}}],["inconsist",{"_index":673,"t":{"1620":{"position":[[48,13]]},"1951":{"position":[[48,13]]}}}],["index",{"_index":628,"t":{"1565":{"position":[[10,5]]}}}],["indic",{"_index":626,"t":{"1563":{"position":[[8,7]]}}}],["infiniband",{"_index":973,"t":{"3715":{"position":[[11,10]]},"3808":{"position":[[11,10]]}}}],["influxdb",{"_index":431,"t":{"956":{"position":[[0,8]]},"1847":{"position":[[0,8]]},"2980":{"position":[[0,8]]}}}],["info",{"_index":980,"t":{"3832":{"position":[[12,4]]}}}],["inform",{"_index":112,"t":{"166":{"position":[[0,11]]},"272":{"position":[[8,11]]},"1581":{"position":[[10,11]]},"1924":{"position":[[10,11]]},"3343":{"position":[[8,11]]},"3655":{"position":[[8,11]]},"3692":{"position":[[8,11]]},"3756":{"position":[[11,11]]},"3779":{"position":[[8,11]]}}}],["infrastructur",{"_index":491,"t":{"1137":{"position":[[16,14]]},"1662":{"position":[[36,14]]},"2440":{"position":[[0,14]]},"2528":{"position":[[0,14]]},"2532":{"position":[[0,14]]},"2536":{"position":[[9,14]]},"2717":{"position":[[22,14]]},"3192":{"position":[[8,14]]},"4280":{"position":[[68,14]]}}}],["ingress",{"_index":864,"t":{"2831":{"position":[[0,7]]},"2842":{"position":[[50,8]]},"4852":{"position":[[10,7]]},"4878":{"position":[[0,7]]}}}],["initi",{"_index":301,"t":{"575":{"position":[[0,10]]},"2442":{"position":[[0,9]]},"2444":{"position":[[0,9]]}}}],["insid",{"_index":1073,"t":{"4852":{"position":[[27,6]]}}}],["instal",{"_index":81,"t":{"128":{"position":[[0,12]]},"129":{"position":[[9,10]]},"133":{"position":[[9,10]]},"292":{"position":[[11,12]]},"469":{"position":[[0,12]]},"474":{"position":[[0,7]]},"652":{"position":[[0,10]]},"670":{"position":[[0,12]]},"687":{"position":[[0,7]]},"691":{"position":[[0,7]]},"693":{"position":[[11,12]]},"746":{"position":[[0,7]]},"752":{"position":[[0,7]]},"884":{"position":[[0,12]]},"891":{"position":[[0,12]]},"902":{"position":[[0,12]]},"1000":{"position":[[0,12]]},"1463":{"position":[[10,12]]},"1487":{"position":[[7,12]]},"1490":{"position":[[0,7]]},"1492":{"position":[[0,7]]},"1498":{"position":[[0,7]]},"1749":{"position":[[0,12]]},"1786":{"position":[[0,12]]},"1808":{"position":[[0,12]]},"1891":{"position":[[0,12]]},"2030":{"position":[[0,12]]},"2031":{"position":[[10,12]]},"2033":{"position":[[7,12]]},"2062":{"position":[[0,12]]},"2095":{"position":[[0,12]]},"2115":{"position":[[0,12]]},"2269":{"position":[[0,7]]},"2635":{"position":[[0,7]]},"2854":{"position":[[0,7]]},"2878":{"position":[[4,12]]},"3347":{"position":[[0,12]]},"3351":{"position":[[9,12]]},"4874":{"position":[[0,7]]}}}],["instanc",{"_index":349,"t":{"707":{"position":[[14,8]]},"709":{"position":[[15,8]]},"945":{"position":[[9,9]]},"1368":{"position":[[20,9]]},"1378":{"position":[[44,8]]},"1382":{"position":[[5,8]]},"1836":{"position":[[9,9]]},"2264":{"position":[[13,8]]},"2269":{"position":[[20,8]]},"2430":{"position":[[87,9]]},"2969":{"position":[[9,9]]},"3762":{"position":[[19,9]]}}}],["instruct",{"_index":670,"t":{"1620":{"position":[[0,8]]},"1951":{"position":[[0,8]]}}}],["integr",{"_index":254,"t":{"404":{"position":[[23,12]]},"412":{"position":[[38,11]]},"426":{"position":[[0,11]]},"453":{"position":[[23,11]]},"1260":{"position":[[11,11]]},"1262":{"position":[[17,11]]},"2107":{"position":[[0,11]]},"4241":{"position":[[9,11]]}}}],["intel",{"_index":571,"t":{"1360":{"position":[[0,5]]}}}],["intend",{"_index":363,"t":{"773":{"position":[[11,8]]}}}],["interest",{"_index":47,"t":{"67":{"position":[[8,8]]}}}],["interfac",{"_index":487,"t":{"1121":{"position":[[8,9]]},"1270":{"position":[[6,10]]},"1298":{"position":[[8,10]]},"2040":{"position":[[13,10]]},"4303":{"position":[[19,9]]},"4312":{"position":[[66,9]]},"4320":{"position":[[4,10]]}}}],["intern",{"_index":412,"t":{"927":{"position":[[0,8]]},"1818":{"position":[[0,8]]},"2538":{"position":[[19,8]]},"2951":{"position":[[0,8]]},"4314":{"position":[[35,8]]},"4330":{"position":[[0,8]]}}}],["interpret",{"_index":179,"t":{"283":{"position":[[3,12]]}}}],["intro",{"_index":409,"t":{"923":{"position":[[0,5]]},"1814":{"position":[[0,5]]},"2711":{"position":[[6,6]]},"2947":{"position":[[0,5]]}}}],["introduct",{"_index":175,"t":{"279":{"position":[[0,12]]},"484":{"position":[[0,12]]},"592":{"position":[[0,12]]},"663":{"position":[[0,12]]},"3518":{"position":[[0,12]]},"3553":{"position":[[0,12]]},"3560":{"position":[[0,12]]},"3581":{"position":[[0,12]]},"3620":{"position":[[0,12]]},"3650":{"position":[[0,12]]},"3687":{"position":[[0,12]]},"3726":{"position":[[0,12]]},"3737":{"position":[[0,12]]},"3755":{"position":[[0,12]]},"3774":{"position":[[0,12]]},"3863":{"position":[[0,12]]},"3887":{"position":[[0,12]]},"3912":{"position":[[0,12]]},"3922":{"position":[[0,12]]},"3940":{"position":[[0,12]]},"3955":{"position":[[0,12]]},"3977":{"position":[[0,12]]},"4004":{"position":[[0,12]]},"4036":{"position":[[0,12]]},"4072":{"position":[[0,12]]},"4115":{"position":[[0,12]]},"4152":{"position":[[0,12]]},"4197":{"position":[[0,12]]},"4248":{"position":[[0,12]]},"4274":{"position":[[15,12]]},"4293":{"position":[[0,12]]},"4339":{"position":[[0,12]]},"4350":{"position":[[0,12]]},"4369":{"position":[[0,12]]},"4394":{"position":[[0,12]]},"4409":{"position":[[0,12]]},"4426":{"position":[[0,12]]},"4439":{"position":[[0,12]]},"4450":{"position":[[0,12]]},"4470":{"position":[[0,12]]},"4501":{"position":[[0,12]]},"4524":{"position":[[0,12]]},"4553":{"position":[[0,12]]},"4571":{"position":[[0,12]]},"4586":{"position":[[0,12]]},"4603":{"position":[[0,12]]},"4636":{"position":[[0,12]]},"4653":{"position":[[0,12]]},"4673":{"position":[[0,12]]},"4683":{"position":[[0,12]]},"4721":{"position":[[0,12]]},"4735":{"position":[[0,12]]},"4754":{"position":[[0,12]]},"4790":{"position":[[0,12]]},"4807":{"position":[[0,12]]}}}],["introdut",{"_index":802,"t":{"2484":{"position":[[0,11]]},"2524":{"position":[[0,11]]}}}],["ip",{"_index":524,"t":{"1241":{"position":[[0,2]]},"1546":{"position":[[12,2]]}}}],["ipmi",{"_index":621,"t":{"1545":{"position":[[31,4]]}}}],["iport",{"_index":147,"t":{"211":{"position":[[0,8]]}}}],["ipv6",{"_index":540,"t":{"1274":{"position":[[0,4]]}}}],["iron",{"_index":472,"t":{"1068":{"position":[[24,6]]}}}],["iso",{"_index":769,"t":{"2262":{"position":[[11,3]]},"2269":{"position":[[47,3]]}}}],["issu",{"_index":38,"t":{"60":{"position":[[19,6]]},"344":{"position":[[0,6]]},"975":{"position":[[10,6]]},"1866":{"position":[[10,6]]},"2149":{"position":[[4,6]]},"2999":{"position":[[10,6]]},"3061":{"position":[[6,5]]},"3076":{"position":[[14,6]]},"3100":{"position":[[9,6]]},"3106":{"position":[[14,6]]},"3133":{"position":[[9,6]]},"3139":{"position":[[14,6]]},"3165":{"position":[[9,6]]},"3171":{"position":[[14,6]]},"3203":{"position":[[9,6]]},"3209":{"position":[[14,6]]},"3249":{"position":[[9,6]]},"3262":{"position":[[14,6]]},"3311":{"position":[[14,6]]},"3335":{"position":[[9,6]]},"3338":{"position":[[14,6]]},"4235":{"position":[[24,6]]}}}],["issuer",{"_index":865,"t":{"2833":{"position":[[0,6]]},"4876":{"position":[[21,6]]}}}],["iter",{"_index":419,"t":{"937":{"position":[[26,9]]},"1828":{"position":[[26,9]]},"2961":{"position":[[26,9]]}}}],["job",{"_index":238,"t":{"367":{"position":[[0,4]]},"525":{"position":[[0,4]]},"529":{"position":[[0,3]]},"2109":{"position":[[36,3]]},"2131":{"position":[[8,4]]},"2228":{"position":[[3,4]]}}}],["jobservic",{"_index":361,"t":{"725":{"position":[[0,10]]}}}],["join",{"_index":955,"t":{"3628":{"position":[[0,7]]}}}],["k3",{"_index":473,"t":{"1070":{"position":[[24,3]]},"1353":{"position":[[13,3]]},"2611":{"position":[[8,3]]},"2643":{"position":[[17,3]]},"2671":{"position":[[17,3]]},"2850":{"position":[[0,3]]}}}],["k3d",{"_index":833,"t":{"2611":{"position":[[35,3]]}}}],["k8",{"_index":6,"t":{"11":{"position":[[0,3]]},"14":{"position":[[0,3]]},"3120":{"position":[[48,3]]},"3154":{"position":[[48,3]]},"3190":{"position":[[64,3]]},"3231":{"position":[[48,3]]},"3286":{"position":[[48,3]]},"3330":{"position":[[48,3]]}}}],["kaa",{"_index":836,"t":{"2621":{"position":[[7,4]]},"2623":{"position":[[0,4]]},"2625":{"position":[[0,4]]},"3222":{"position":[[0,4]]},"3265":{"position":[[0,4]]},"3280":{"position":[[0,4]]},"3289":{"position":[[48,4]]},"3295":{"position":[[0,4]]},"3314":{"position":[[0,4]]},"3433":{"position":[[67,4]]},"4136":{"position":[[31,5]]},"4732":{"position":[[49,4]]}}}],["key",{"_index":96,"t":{"148":{"position":[[0,3]]},"1172":{"position":[[6,4]]},"2342":{"position":[[22,4]]},"2359":{"position":[[16,3]]},"2409":{"position":[[22,4]]},"2426":{"position":[[16,3]]},"2502":{"position":[[0,3]]},"4082":{"position":[[0,3]]},"4084":{"position":[[0,3]]}}}],["keycloak",{"_index":206,"t":{"320":{"position":[[4,8]]},"1083":{"position":[[24,8]]},"2369":{"position":[[10,8]]},"2430":{"position":[[78,8]]},"3057":{"position":[[17,8]]},"3237":{"position":[[9,8]]}}}],["keyston",{"_index":204,"t":{"318":{"position":[[3,8]]},"322":{"position":[[4,8]]},"835":{"position":[[0,8]]},"2442":{"position":[[10,8]]},"2444":{"position":[[10,8]]},"4617":{"position":[[14,8]]},"4619":{"position":[[14,8]]}}}],["keyword",{"_index":178,"t":{"281":{"position":[[43,8]]},"283":{"position":[[24,8]]},"290":{"position":[[46,8]]},"294":{"position":[[39,8]]},"298":{"position":[[22,8]]}}}],["kind",{"_index":874,"t":{"2872":{"position":[[0,4]]}}}],["kind/k3",{"_index":839,"t":{"2641":{"position":[[29,8]]},"2669":{"position":[[29,8]]}}}],["known",{"_index":881,"t":{"3019":{"position":[[0,5]]},"3061":{"position":[[0,5]]},"3076":{"position":[[8,5]]},"3106":{"position":[[8,5]]},"3139":{"position":[[8,5]]},"3171":{"position":[[8,5]]},"3209":{"position":[[8,5]]},"3262":{"position":[[8,5]]},"3311":{"position":[[8,5]]},"3338":{"position":[[8,5]]}}}],["kube",{"_index":872,"t":{"2858":{"position":[[0,4]]},"4478":{"position":[[0,4]]},"4488":{"position":[[0,4]]}}}],["kubeconfig",{"_index":1075,"t":{"4869":{"position":[[0,10]]}}}],["kubelet",{"_index":1049,"t":{"4540":{"position":[[0,7]]}}}],["kubernet",{"_index":289,"t":{"544":{"position":[[18,10]]},"698":{"position":[[0,10]]},"731":{"position":[[0,10]]},"1353":{"position":[[0,10]]},"1430":{"position":[[0,10]]},"2079":{"position":[[0,10]]},"2526":{"position":[[0,10]]},"2528":{"position":[[38,11]]},"2530":{"position":[[35,11]]},"2577":{"position":[[0,10]]},"2595":{"position":[[0,10]]},"2611":{"position":[[12,10]]},"2654":{"position":[[8,10]]},"2727":{"position":[[0,10]]},"4136":{"position":[[10,10]]},"4280":{"position":[[44,10]]},"4530":{"position":[[10,10]]},"4873":{"position":[[19,10]]}}}],["kubevirt",{"_index":1045,"t":{"4513":{"position":[[27,9]]}}}],["kustom",{"_index":341,"t":{"693":{"position":[[37,13]]}}}],["kvm",{"_index":712,"t":{"2001":{"position":[[0,3]]}}}],["label",{"_index":616,"t":{"1528":{"position":[[12,6]]},"2113":{"position":[[9,5]]},"4702":{"position":[[0,6]]}}}],["languag",{"_index":1066,"t":{"4678":{"position":[[12,8]]}}}],["larg",{"_index":668,"t":{"1618":{"position":[[14,5]]},"1949":{"position":[[14,5]]}}}],["larger",{"_index":551,"t":{"1311":{"position":[[34,6]]}}}],["last",{"_index":767,"t":{"2257":{"position":[[0,4]]}}}],["later",{"_index":1057,"t":{"4617":{"position":[[33,5]]}}}],["latest",{"_index":519,"t":{"1227":{"position":[[6,6]]}}}],["layer",{"_index":224,"t":{"336":{"position":[[5,5]]},"338":{"position":[[10,5]]},"536":{"position":[[0,6]]},"713":{"position":[[12,5]]},"789":{"position":[[21,6]]},"793":{"position":[[16,5]]},"795":{"position":[[32,6]]},"1015":{"position":[[0,6]]},"2621":{"position":[[12,5]]},"3065":{"position":[[10,5]]},"4134":{"position":[[31,6]]},"4136":{"position":[[37,6]]},"4258":{"position":[[28,5]]},"4318":{"position":[[10,5]]}}}],["layout",{"_index":520,"t":{"1231":{"position":[[25,6]]}}}],["lba",{"_index":647,"t":{"1588":{"position":[[36,3]]},"1931":{"position":[[36,3]]}}}],["leaf",{"_index":485,"t":{"1117":{"position":[[0,4]]}}}],["let’",{"_index":531,"t":{"1249":{"position":[[33,5]]}}}],["level",{"_index":711,"t":{"1995":{"position":[[21,5]]},"2505":{"position":[[20,5]]},"4101":{"position":[[33,6]]},"4103":{"position":[[9,6]]},"4106":{"position":[[9,6]]}}}],["libvirt",{"_index":1032,"t":{"4303":{"position":[[0,7]]},"4312":{"position":[[47,7]]}}}],["licens",{"_index":127,"t":{"180":{"position":[[38,7]]},"182":{"position":[[0,7],[13,7]]},"3834":{"position":[[0,9]]}}}],["lifecycl",{"_index":270,"t":{"460":{"position":[[0,9]]},"1057":{"position":[[0,9]]},"1062":{"position":[[0,9]]},"1065":{"position":[[0,9]]},"1068":{"position":[[0,9]]},"1070":{"position":[[0,9]]},"1072":{"position":[[0,9]]},"1083":{"position":[[0,9]]},"1085":{"position":[[0,9]]},"1087":{"position":[[0,9]]},"1088":{"position":[[0,9]]},"1090":{"position":[[3,9]]},"1091":{"position":[[3,9]]},"1092":{"position":[[3,9]]},"1094":{"position":[[0,9]]},"3587":{"position":[[0,9]]},"3877":{"position":[[0,9]]},"3878":{"position":[[5,9]]},"3880":{"position":[[6,9]]}}}],["limit",{"_index":241,"t":{"379":{"position":[[0,11]]},"1186":{"position":[[9,6]]},"2379":{"position":[[0,11]]},"3985":{"position":[[10,11]]},"4478":{"position":[[14,8]]},"4488":{"position":[[14,8]]}}}],["line",{"_index":725,"t":{"2040":{"position":[[8,4]]},"4867":{"position":[[8,4]]}}}],["link",{"_index":849,"t":{"2708":{"position":[[7,5]]},"3072":{"position":[[9,5]]}}}],["lint",{"_index":110,"t":{"162":{"position":[[8,7]]}}}],["list",{"_index":107,"t":{"158":{"position":[[22,5]]},"1656":{"position":[[0,4]]},"1685":{"position":[[0,4]]},"2089":{"position":[[0,5]]},"2759":{"position":[[0,4]]},"2763":{"position":[[0,4]]},"2769":{"position":[[0,4]]},"2775":{"position":[[0,4]]},"2781":{"position":[[0,4]]},"2787":{"position":[[0,4]]},"3076":{"position":[[0,4]]},"3106":{"position":[[0,4]]},"3139":{"position":[[0,4]]},"3171":{"position":[[0,4]]},"3209":{"position":[[0,4]]},"3250":{"position":[[43,4]]},"3262":{"position":[[0,4]]},"3311":{"position":[[0,4]]},"3338":{"position":[[0,4]]},"4568":{"position":[[0,4]]},"4700":{"position":[[6,4]]}}}],["live",{"_index":447,"t":{"985":{"position":[[0,4]]},"1876":{"position":[[0,4]]},"4326":{"position":[[15,4]]}}}],["loadbalanc",{"_index":507,"t":{"1182":{"position":[[26,12]]},"1251":{"position":[[7,12]]},"1551":{"position":[[0,12]]},"3316":{"position":[[4,13]]}}}],["local",{"_index":77,"t":{"120":{"position":[[0,5]]},"490":{"position":[[6,5],[27,5]]},"1384":{"position":[[0,5]]},"1490":{"position":[[16,7]]},"2215":{"position":[[12,6]]},"2265":{"position":[[11,5]]},"2641":{"position":[[0,5],[55,7]]},"2669":{"position":[[0,5],[55,7]]},"2700":{"position":[[50,7]]},"4288":{"position":[[9,5]]},"4513":{"position":[[0,5]]},"4866":{"position":[[20,5]]}}}],["local_mod",{"_index":281,"t":{"513":{"position":[[15,10]]}}}],["locat",{"_index":151,"t":{"217":{"position":[[29,8]]},"1595":{"position":[[0,6]]}}}],["lock",{"_index":522,"t":{"1235":{"position":[[0,5]]}}}],["log",{"_index":427,"t":{"947":{"position":[[13,4]]},"950":{"position":[[0,3]]},"1436":{"position":[[0,3]]},"1450":{"position":[[10,7]]},"1838":{"position":[[13,4]]},"1841":{"position":[[0,3]]},"1995":{"position":[[4,7]]},"2129":{"position":[[5,4]]},"2971":{"position":[[13,4]]},"2974":{"position":[[0,3]]},"3053":{"position":[[0,7]]},"3054":{"position":[[8,7]]}}}],["login",{"_index":1074,"t":{"4856":{"position":[[6,5]]}}}],["logout",{"_index":891,"t":{"3061":{"position":[[22,6]]}}}],["look",{"_index":1054,"t":{"4561":{"position":[[7,4]]}}}],["luk",{"_index":783,"t":{"2359":{"position":[[0,4]]},"2426":{"position":[[0,4]]}}}],["lvm",{"_index":642,"t":{"1582":{"position":[[38,3]]},"1925":{"position":[[38,3]]}}}],["machin",{"_index":550,"t":{"1311":{"position":[[19,7]]},"3589":{"position":[[0,7]]},"4515":{"position":[[23,7]]},"4517":{"position":[[8,7]]}}}],["magnum",{"_index":470,"t":{"1058":{"position":[[27,6]]}}}],["mail",{"_index":1077,"t":{"4884":{"position":[[28,4]]}}}],["main",{"_index":826,"t":{"2566":{"position":[[0,4]]}}}],["main.go",{"_index":299,"t":{"567":{"position":[[7,7]]}}}],["mainten",{"_index":439,"t":{"964":{"position":[[0,11]]},"1535":{"position":[[0,11]]},"1572":{"position":[[8,11]]},"1594":{"position":[[4,11]]},"1611":{"position":[[16,11]]},"1622":{"position":[[11,11]]},"1855":{"position":[[0,11]]},"1915":{"position":[[8,11]]},"1937":{"position":[[4,11]]},"1942":{"position":[[16,11]]},"1953":{"position":[[11,11]]},"2988":{"position":[[0,11]]},"3834":{"position":[[12,11]]},"4480":{"position":[[5,11]]},"4710":{"position":[[0,11]]}}}],["make",{"_index":173,"t":{"270":{"position":[[7,4]]},"406":{"position":[[9,4]]},"563":{"position":[[0,4]]},"1313":{"position":[[0,4]]},"2056":{"position":[[7,4]]}}}],["makefil",{"_index":293,"t":{"561":{"position":[[0,8]]},"2226":{"position":[[0,8]]}}}],["manag",{"_index":302,"t":{"575":{"position":[[15,10]]},"825":{"position":[[14,7]]},"1057":{"position":[[10,10]]},"1062":{"position":[[10,10]]},"1065":{"position":[[10,10]]},"1068":{"position":[[10,10]]},"1070":{"position":[[10,10]]},"1072":{"position":[[10,10]]},"1083":{"position":[[10,10]]},"1085":{"position":[[10,10]]},"1087":{"position":[[10,10]]},"1088":{"position":[[10,10]]},"1090":{"position":[[13,10]]},"1091":{"position":[[13,10]]},"1092":{"position":[[13,10]]},"1094":{"position":[[10,10]]},"1112":{"position":[[0,7]]},"1115":{"position":[[0,10]]},"1126":{"position":[[0,10]]},"1133":{"position":[[0,10]]},"1208":{"position":[[0,7]]},"1323":{"position":[[7,7]]},"1469":{"position":[[11,7]]},"1475":{"position":[[22,7]]},"1477":{"position":[[19,7]]},"1479":{"position":[[34,7]]},"1539":{"position":[[0,6]]},"1541":{"position":[[0,6]]},"1662":{"position":[[25,6]]},"2446":{"position":[[17,7],[25,7]]},"2452":{"position":[[18,7]]},"2454":{"position":[[21,7]]},"2456":{"position":[[20,7]]},"2458":{"position":[[7,7]]},"2460":{"position":[[0,8]]},"2462":{"position":[[0,8]]},"2464":{"position":[[0,8]]},"2466":{"position":[[0,8]]},"2860":{"position":[[12,7]]},"3090":{"position":[[8,10]]},"3120":{"position":[[60,11]]},"3123":{"position":[[8,10]]},"3154":{"position":[[60,11]]},"3184":{"position":[[10,10]]},"3190":{"position":[[76,11]]},"3231":{"position":[[60,11]]},"3233":{"position":[[16,7]]},"3286":{"position":[[60,11]]},"3330":{"position":[[60,11]]},"3463":{"position":[[19,7]]},"3639":{"position":[[10,10]]},"4082":{"position":[[4,7]]},"4084":{"position":[[4,7]]},"4622":{"position":[[42,7]]},"4874":{"position":[[13,7]]}}}],["manage.pi",{"_index":404,"t":{"907":{"position":[[0,9]]},"913":{"position":[[0,9]]},"1791":{"position":[[0,9]]},"1797":{"position":[[0,9]]}}}],["mandatori",{"_index":67,"t":{"102":{"position":[[11,9]]},"104":{"position":[[15,9]]},"106":{"position":[[47,9]]},"108":{"position":[[18,9]]},"110":{"position":[[16,9]]},"112":{"position":[[13,9]]},"3585":{"position":[[12,9]]},"3897":{"position":[[0,9]]},"4201":{"position":[[0,9]]}}}],["manual",{"_index":607,"t":{"1465":{"position":[[0,6]]},"1487":{"position":[[0,6]]},"1647":{"position":[[29,6]]},"2033":{"position":[[0,6]]},"3752":{"position":[[0,6]]},"3846":{"position":[[0,6]]},"3860":{"position":[[0,6]]},"4067":{"position":[[0,6]]},"4366":{"position":[[0,6]]},"4391":{"position":[[0,6]]},"4467":{"position":[[0,6]]}}}],["map",{"_index":191,"t":{"298":{"position":[[3,7]]},"322":{"position":[[13,7]]},"2371":{"position":[[9,7]]}}}],["mariadb",{"_index":623,"t":{"1553":{"position":[[0,7]]}}}],["materi",{"_index":458,"t":{"1021":{"position":[[17,9]]}}}],["matrix",{"_index":1064,"t":{"4661":{"position":[[11,6]]}}}],["mean",{"_index":372,"t":{"785":{"position":[[35,5]]},"791":{"position":[[15,5]]},"795":{"position":[[15,5]]}}}],["measur",{"_index":1051,"t":{"4544":{"position":[[8,12]]}}}],["mechan",{"_index":965,"t":{"3645":{"position":[[0,10]]},"4312":{"position":[[29,9]]},"4314":{"position":[[44,10]]}}}],["medium",{"_index":745,"t":{"2138":{"position":[[9,6]]}}}],["meet",{"_index":40,"t":{"62":{"position":[[0,8]]},"65":{"position":[[49,8]]}}}],["memori",{"_index":573,"t":{"1364":{"position":[[5,6]]},"1382":{"position":[[14,6]]},"3662":{"position":[[11,6]]},"3699":{"position":[[11,6]]},"3786":{"position":[[11,6]]}}}],["merch",{"_index":153,"t":{"221":{"position":[[10,5]]}}}],["messag",{"_index":384,"t":{"833":{"position":[[0,7]]},"2092":{"position":[[7,8]]},"4324":{"position":[[0,7]]}}}],["metadata",{"_index":652,"t":{"1597":{"position":[[8,8]]}}}],["metal",{"_index":893,"t":{"3063":{"position":[[5,5]]}}}],["meter",{"_index":883,"t":{"3031":{"position":[[14,8]]}}}],["methodolog",{"_index":942,"t":{"3566":{"position":[[0,11]]}}}],["metric",{"_index":837,"t":{"2623":{"position":[[5,6]]},"2702":{"position":[[10,7]]},"3048":{"position":[[0,7]]}}}],["migrat",{"_index":448,"t":{"985":{"position":[[5,9]]},"1876":{"position":[[5,9]]},"1987":{"position":[[2,7]]},"2241":{"position":[[0,9]]},"2273":{"position":[[0,9]]},"4326":{"position":[[20,9]]}}}],["minimum",{"_index":466,"t":{"1047":{"position":[[12,7]]},"4258":{"position":[[15,7]]}}}],["mirror",{"_index":400,"t":{"877":{"position":[[0,9]]},"1778":{"position":[[0,9]]}}}],["miss",{"_index":704,"t":{"1742":{"position":[[20,7]]}}}],["mitig",{"_index":322,"t":{"609":{"position":[[8,11]]}}}],["mix",{"_index":581,"t":{"1376":{"position":[[0,6]]},"1378":{"position":[[0,6]]}}}],["mock",{"_index":838,"t":{"2625":{"position":[[5,4]]}}}],["mode",{"_index":275,"t":{"490":{"position":[[12,4],[33,5]]},"513":{"position":[[37,4]]},"629":{"position":[[0,5]]},"642":{"position":[[10,5]]},"644":{"position":[[5,4]]},"646":{"position":[[7,4]]},"648":{"position":[[5,4]]},"650":{"position":[[7,4]]},"674":{"position":[[10,5]]},"676":{"position":[[5,4]]},"678":{"position":[[7,4]]},"680":{"position":[[5,4]]},"682":{"position":[[7,4]]},"2103":{"position":[[6,4]]}}}],["model",{"_index":1019,"t":{"4235":{"position":[[15,8]]}}}],["modul",{"_index":951,"t":{"3599":{"position":[[0,6]]}}}],["monitor",{"_index":414,"t":{"927":{"position":[[21,10]]},"970":{"position":[[26,7]]},"1127":{"position":[[0,10]]},"1134":{"position":[[0,10]]},"1818":{"position":[[21,10]]},"1861":{"position":[[26,7]]},"1907":{"position":[[0,10]]},"2613":{"position":[[16,10]]},"2615":{"position":[[20,10]]},"2621":{"position":[[18,10]]},"2645":{"position":[[12,10]]},"2656":{"position":[[16,10]]},"2658":{"position":[[20,10]]},"2673":{"position":[[19,10]]},"2951":{"position":[[21,10]]},"2994":{"position":[[26,7]]},"3051":{"position":[[17,7]]},"3291":{"position":[[25,7]]},"3382":{"position":[[27,7]]}}}],["monitoring1",{"_index":9,"t":{"13":{"position":[[20,11]]}}}],["month",{"_index":141,"t":{"204":{"position":[[12,6]]},"208":{"position":[[12,6]]},"215":{"position":[[12,6]]},"223":{"position":[[12,6]]},"227":{"position":[[12,6]]},"238":{"position":[[12,5]]}}}],["motiv",{"_index":315,"t":{"594":{"position":[[0,10]]},"3555":{"position":[[0,10]]},"3562":{"position":[[0,10]]},"3583":{"position":[[0,10]]},"3652":{"position":[[0,10]]},"3689":{"position":[[0,10]]},"3728":{"position":[[0,10]]},"3764":{"position":[[0,10]]},"3776":{"position":[[0,10]]},"3819":{"position":[[0,10]]},"3865":{"position":[[0,10]]},"3891":{"position":[[0,10]]},"3924":{"position":[[0,10]]},"3942":{"position":[[0,10]]},"3957":{"position":[[0,10]]},"4008":{"position":[[0,10]]},"4042":{"position":[[0,10]]},"4076":{"position":[[0,10]]},"4119":{"position":[[0,10]]},"4156":{"position":[[0,10]]},"4199":{"position":[[0,10]]},"4219":{"position":[[0,10]]},"4252":{"position":[[0,10]]},"4272":{"position":[[0,10]]},"4297":{"position":[[0,10]]},"4341":{"position":[[0,10]]},"4352":{"position":[[0,10]]},"4371":{"position":[[0,10]]},"4396":{"position":[[0,10]]},"4413":{"position":[[0,10]]},"4430":{"position":[[0,10]]},"4443":{"position":[[0,10]]},"4454":{"position":[[0,10]]},"4474":{"position":[[0,10]]},"4503":{"position":[[0,10]]},"4528":{"position":[[0,10]]},"4557":{"position":[[0,10]]},"4575":{"position":[[0,10]]},"4588":{"position":[[0,10]]},"4607":{"position":[[0,10]]},"4638":{"position":[[0,10]]},"4675":{"position":[[0,10]]},"4687":{"position":[[0,10]]},"4723":{"position":[[0,10]]},"4739":{"position":[[0,10]]},"4758":{"position":[[0,10]]},"4792":{"position":[[0,10]]},"4811":{"position":[[0,10]]}}}],["move",{"_index":679,"t":{"1640":{"position":[[29,6]]},"1971":{"position":[[29,6]]}}}],["msgr2",{"_index":588,"t":{"1402":{"position":[[37,5]]}}}],["mtu",{"_index":561,"t":{"1330":{"position":[[0,3]]}}}],["multipl",{"_index":318,"t":{"603":{"position":[[14,8]]},"945":{"position":[[0,8]]},"1836":{"position":[[0,8]]},"2099":{"position":[[11,8]]},"2969":{"position":[[0,8]]}}}],["multiten",{"_index":474,"t":{"1080":{"position":[[0,12]]}}}],["mute/unmut",{"_index":632,"t":{"1575":{"position":[[0,11]]},"1918":{"position":[[0,11]]}}}],["naabu",{"_index":819,"t":{"2548":{"position":[[0,5]]}}}],["name",{"_index":95,"t":{"146":{"position":[[5,6]]},"302":{"position":[[0,6]]},"897":{"position":[[0,4]]},"1296":{"position":[[23,4]]},"1418":{"position":[[58,5]]},"1428":{"position":[[13,4]]},"1755":{"position":[[0,4]]},"2083":{"position":[[5,5]]},"2438":{"position":[[41,5]]},"3678":{"position":[[0,6]]},"3694":{"position":[[40,6]]},"3703":{"position":[[0,6]]},"3717":{"position":[[0,6]]},"3781":{"position":[[40,6]]},"3792":{"position":[[0,6]]},"3810":{"position":[[0,6]]},"3823":{"position":[[0,6]]},"4696":{"position":[[9,6]]}}}],["nameserv",{"_index":1076,"t":{"4871":{"position":[[19,10]]}}}],["namespac",{"_index":307,"t":{"581":{"position":[[9,9]]},"1430":{"position":[[11,10]]},"4850":{"position":[[0,9]]},"4852":{"position":[[38,9]]}}}],["need",{"_index":365,"t":{"777":{"position":[[15,4]]},"787":{"position":[[5,4]]},"2838":{"position":[[4,5]]}}}],["ness",{"_index":1061,"t":{"4624":{"position":[[8,4]]}}}],["nest",{"_index":568,"t":{"1357":{"position":[[0,6]]},"2002":{"position":[[0,6]]},"3668":{"position":[[37,6]]},"3709":{"position":[[37,6]]},"3802":{"position":[[37,6]]}}}],["netdata",{"_index":475,"t":{"1085":{"position":[[24,7]]}}}],["netplan",{"_index":536,"t":{"1265":{"position":[[0,7]]}}}],["network",{"_index":383,"t":{"827":{"position":[[23,7]]},"1033":{"position":[[0,7]]},"1043":{"position":[[0,7]]},"1049":{"position":[[0,7]]},"1091":{"position":[[40,7]]},"1100":{"position":[[0,7]]},"1110":{"position":[[0,7]]},"1121":{"position":[[0,7]]},"1128":{"position":[[0,7]]},"1135":{"position":[[0,7]]},"1298":{"position":[[0,7]]},"1398":{"position":[[0,7]]},"1473":{"position":[[18,7]]},"1703":{"position":[[13,7]]},"1706":{"position":[[19,7]]},"2047":{"position":[[28,7]]},"3959":{"position":[[11,7],[36,7]]},"3989":{"position":[[28,7]]},"4307":{"position":[[8,7]]}}}],["neutron",{"_index":390,"t":{"845":{"position":[[0,7]]},"4330":{"position":[[9,7]]}}}],["new",{"_index":506,"t":{"1178":{"position":[[6,3]]},"1217":{"position":[[11,3]]},"1223":{"position":[[19,3]]},"1599":{"position":[[6,3]]},"1710":{"position":[[6,3]]},"2073":{"position":[[13,3]]},"2075":{"position":[[13,3]]},"2206":{"position":[[4,3]]},"2253":{"position":[[10,3]]},"2737":{"position":[[7,3]]},"2739":{"position":[[9,3]]},"3084":{"position":[[0,3]]},"3117":{"position":[[0,3]]},"3151":{"position":[[0,3]]},"3228":{"position":[[0,3]]},"3282":{"position":[[0,3]]},"3328":{"position":[[0,3]]},"3379":{"position":[[13,3]]},"4269":{"position":[[15,3]]}}}],["nic",{"_index":730,"t":{"2047":{"position":[[11,3]]}}}],["nice",{"_index":149,"t":{"213":{"position":[[0,4]]}}}],["node",{"_index":287,"t":{"542":{"position":[[4,4]]},"821":{"position":[[22,4]]},"823":{"position":[[22,4]]},"825":{"position":[[22,4]]},"1026":{"position":[[0,4]]},"1027":{"position":[[8,4]]},"1029":{"position":[[8,4]]},"1031":{"position":[[8,4]]},"1033":{"position":[[8,4]]},"1035":{"position":[[0,5]]},"1039":{"position":[[8,4]]},"1041":{"position":[[8,4]]},"1104":{"position":[[8,5]]},"1106":{"position":[[8,5]]},"1108":{"position":[[8,5]]},"1110":{"position":[[8,5]]},"1112":{"position":[[8,5]]},"1123":{"position":[[8,4]]},"1124":{"position":[[8,4]]},"1125":{"position":[[5,4]]},"1126":{"position":[[11,4]]},"1127":{"position":[[11,4]]},"1128":{"position":[[8,4]]},"1190":{"position":[[16,5]]},"1213":{"position":[[24,5]]},"1362":{"position":[[16,4]]},"1376":{"position":[[47,4]]},"1414":{"position":[[19,5]]},"1416":{"position":[[24,5]]},"1418":{"position":[[24,5]]},"1463":{"position":[[29,4]]},"1475":{"position":[[30,4]]},"1528":{"position":[[7,4]]},"1533":{"position":[[7,4]]},"1543":{"position":[[7,5]]},"1579":{"position":[[16,4]]},"1604":{"position":[[20,4]]},"1708":{"position":[[17,4]]},"1710":{"position":[[18,4]]},"1712":{"position":[[17,4]]},"1727":{"position":[[21,4]]},"1729":{"position":[[30,4]]},"1922":{"position":[[16,4]]},"3771":{"position":[[8,5]]},"4303":{"position":[[40,5]]}}}],["node.j",{"_index":83,"t":{"129":{"position":[[20,7]]}}}],["nomin",{"_index":959,"t":{"3635":{"position":[[0,11]]}}}],["non",{"_index":889,"t":{"3059":{"position":[[0,3]]},"4375":{"position":[[12,3]]},"4400":{"position":[[9,3]]}}}],["note",{"_index":496,"t":{"1158":{"position":[[0,4]]},"2060":{"position":[[21,5]]},"2068":{"position":[[29,5]]},"2220":{"position":[[0,5]]},"2481":{"position":[[10,5]]},"3089":{"position":[[18,5]]},"3122":{"position":[[18,5]]},"3156":{"position":[[18,5]]},"3194":{"position":[[18,5]]},"3239":{"position":[[18,5]]},"3299":{"position":[[18,5]]},"3331":{"position":[[18,5]]},"3403":{"position":[[39,5]]},"3407":{"position":[[39,5]]},"3411":{"position":[[39,5]]},"3415":{"position":[[27,5]]},"3439":{"position":[[39,5]]},"3447":{"position":[[39,5]]},"3455":{"position":[[95,5]]},"3463":{"position":[[42,5]]},"3475":{"position":[[39,5]]},"3479":{"position":[[39,5]]},"3487":{"position":[[39,5]]},"3497":{"position":[[27,5]]},"3739":{"position":[[15,5]]},"3839":{"position":[[15,5]]},"3849":{"position":[[15,5]]},"3933":{"position":[[15,4]]},"4361":{"position":[[15,5]]},"4384":{"position":[[15,5]]},"4387":{"position":[[0,5]]},"4463":{"position":[[15,5]]},"4664":{"position":[[15,5]]}}}],["nova",{"_index":389,"t":{"843":{"position":[[0,4]]},"984":{"position":[[0,4]]},"1370":{"position":[[28,4]]},"1378":{"position":[[39,4]]},"1875":{"position":[[0,4]]},"2265":{"position":[[6,4]]}}}],["nuclei",{"_index":821,"t":{"2552":{"position":[[0,6]]}}}],["numa",{"_index":575,"t":{"1370":{"position":[[4,4]]}}}],["number",{"_index":546,"t":{"1304":{"position":[[0,6]]},"1432":{"position":[[0,6]]},"1636":{"position":[[4,6]]},"1967":{"position":[[4,6]]}}}],["nvm",{"_index":85,"t":{"129":{"position":[[32,3]]}}}],["nvme",{"_index":645,"t":{"1584":{"position":[[28,4]]},"1586":{"position":[[18,4]]},"1588":{"position":[[9,4],[53,4]]},"1590":{"position":[[15,4],[32,4]]},"1927":{"position":[[28,4]]},"1929":{"position":[[18,4]]},"1931":{"position":[[9,4],[53,4]]},"1933":{"position":[[15,4],[32,4]]}}}],["oathkeep",{"_index":863,"t":{"2827":{"position":[[0,10]]}}}],["object",{"_index":23,"t":{"38":{"position":[[0,6]]},"464":{"position":[[28,6]]},"862":{"position":[[0,6]]},"1618":{"position":[[25,7]]},"1763":{"position":[[0,6]]},"1949":{"position":[[25,7]]},"3345":{"position":[[10,10]]},"4692":{"position":[[4,7]]},"4694":{"position":[[4,6]]}}}],["observ",{"_index":834,"t":{"2613":{"position":[[7,8]]},"2615":{"position":[[11,8]]},"2635":{"position":[[8,8]]},"2656":{"position":[[7,8]]},"2658":{"position":[[11,8]]},"2744":{"position":[[0,13]]},"4732":{"position":[[54,13]]}}}],["oci",{"_index":353,"t":{"718":{"position":[[0,3]]}}}],["octavia",{"_index":450,"t":{"989":{"position":[[0,7]]},"1880":{"position":[[0,7]]}}}],["octo",{"_index":163,"t":{"257":{"position":[[0,4]]}}}],["offer",{"_index":106,"t":{"158":{"position":[[16,5]]}}}],["offici",{"_index":930,"t":{"3379":{"position":[[37,8]]}}}],["oidc",{"_index":560,"t":{"1325":{"position":[[0,4]]},"2195":{"position":[[20,4]]},"3057":{"position":[[0,4]]},"3061":{"position":[[17,4]]}}}],["omap",{"_index":669,"t":{"1618":{"position":[[20,4]]},"1949":{"position":[[20,4]]}}}],["on",{"_index":161,"t":{"242":{"position":[[10,3]]},"603":{"position":[[54,3]]},"693":{"position":[[7,3]]},"4164":{"position":[[29,3]]}}}],["oob",{"_index":619,"t":{"1545":{"position":[[17,3]]}}}],["open",{"_index":36,"t":{"58":{"position":[[9,4]]},"189":{"position":[[4,4]]},"191":{"position":[[10,5]]},"193":{"position":[[3,4]]},"1091":{"position":[[27,4]]},"1092":{"position":[[27,4]]},"1562":{"position":[[0,4]]},"1701":{"position":[[0,4]]},"1703":{"position":[[0,4]]},"3542":{"position":[[0,4]]},"3576":{"position":[[0,4]]},"3616":{"position":[[0,4]]},"3733":{"position":[[0,4]]},"3948":{"position":[[0,4]]},"3969":{"position":[[0,4]]},"4194":{"position":[[0,4]]},"4311":{"position":[[0,4]]},"4594":{"position":[[0,4]]},"4644":{"position":[[0,4]]},"4747":{"position":[[0,4]]},"4764":{"position":[[0,4]]},"4798":{"position":[[0,4]]},"4817":{"position":[[0,4]]}}}],["opendesk",{"_index":1072,"t":{"4842":{"position":[[10,8]]}}}],["openid",{"_index":790,"t":{"2430":{"position":[[49,7]]}}}],["openrc",{"_index":771,"t":{"2273":{"position":[[15,6]]}}}],["opensearch",{"_index":534,"t":{"1260":{"position":[[0,10]]},"1697":{"position":[[0,10]]}}}],["openstack",{"_index":20,"t":{"35":{"position":[[21,9]]},"48":{"position":[[21,9]]},"312":{"position":[[10,9]]},"326":{"position":[[4,9]]},"860":{"position":[[0,9]]},"931":{"position":[[14,9]]},"933":{"position":[[12,9]]},"970":{"position":[[9,9]]},"1058":{"position":[[17,9]]},"1072":{"position":[[24,9]]},"1074":{"position":[[0,9]]},"1076":{"position":[[0,9]]},"1078":{"position":[[24,9]]},"1080":{"position":[[18,9]]},"1182":{"position":[[16,9]]},"1262":{"position":[[0,9]]},"1351":{"position":[[0,9]]},"1761":{"position":[[0,9]]},"1822":{"position":[[14,9]]},"1824":{"position":[[12,9]]},"1861":{"position":[[9,9]]},"2210":{"position":[[18,9]]},"2646":{"position":[[0,9]]},"2955":{"position":[[14,9]]},"2957":{"position":[[12,9]]},"2994":{"position":[[9,9]]},"3051":{"position":[[0,9]]},"3959":{"position":[[61,9]]},"4511":{"position":[[14,11]]},"4617":{"position":[[4,9]]},"4619":{"position":[[4,9]]}}}],["openstackcli",{"_index":22,"t":{"36":{"position":[[0,15]]},"55":{"position":[[0,15]]}}}],["openstackclusterstackreleas",{"_index":278,"t":{"495":{"position":[[0,28]]}}}],["openstacknodeimagereleas",{"_index":280,"t":{"497":{"position":[[0,25]]}}}],["openva",{"_index":823,"t":{"2554":{"position":[[28,9]]}}}],["oper",{"_index":61,"t":{"96":{"position":[[3,11]]},"402":{"position":[[14,8]]},"429":{"position":[[22,8]]},"451":{"position":[[14,8]]},"474":{"position":[[22,8]]},"687":{"position":[[21,9]]},"929":{"position":[[13,9]]},"1471":{"position":[[15,8]]},"1820":{"position":[[13,9]]},"2448":{"position":[[15,9]]},"2458":{"position":[[15,9]]},"2504":{"position":[[29,9]]},"2505":{"position":[[4,9]]},"2513":{"position":[[4,10]]},"2538":{"position":[[6,8]]},"2591":{"position":[[6,8]]},"2953":{"position":[[13,9]]},"3085":{"position":[[0,8]]},"3118":{"position":[[0,8]]},"3152":{"position":[[0,8]]},"3188":{"position":[[0,10]]},"3224":{"position":[[0,10]]},"3229":{"position":[[0,8]]},"3283":{"position":[[0,8]]},"3329":{"position":[[0,8]]},"3741":{"position":[[0,11]]},"3796":{"position":[[0,11]]},"3884":{"position":[[0,11]]},"3907":{"position":[[0,11]]},"3919":{"position":[[0,11]]},"3989":{"position":[[10,8]]}}}],["operator'",{"_index":812,"t":{"2507":{"position":[[4,10]]}}}],["option",{"_index":70,"t":{"106":{"position":[[13,9]]},"114":{"position":[[8,8]]},"2247":{"position":[[20,10]]},"3664":{"position":[[0,10]]},"3666":{"position":[[0,10]]},"3668":{"position":[[0,10]]},"3670":{"position":[[0,10]]},"3672":{"position":[[0,10]]},"3701":{"position":[[0,10]]},"3707":{"position":[[0,10]]},"3709":{"position":[[0,10]]},"3711":{"position":[[0,10]]},"3713":{"position":[[0,10]]},"3715":{"position":[[0,10]]},"3717":{"position":[[7,7]]},"3788":{"position":[[0,10]]},"3800":{"position":[[0,10]]},"3802":{"position":[[0,10]]},"3804":{"position":[[0,10]]},"3806":{"position":[[0,10]]},"3808":{"position":[[0,10]]},"3810":{"position":[[7,7]]},"3915":{"position":[[0,6]]},"3917":{"position":[[0,6]]},"3927":{"position":[[0,7]]},"3946":{"position":[[0,7]]},"3967":{"position":[[0,7]]},"3987":{"position":[[0,6]]},"3989":{"position":[[0,6]]},"3991":{"position":[[0,6]]},"3993":{"position":[[0,6]]},"4022":{"position":[[0,8]]},"4080":{"position":[[0,7]]},"4123":{"position":[[0,7]]},"4162":{"position":[[0,7]]},"4256":{"position":[[0,7]]},"4278":{"position":[[0,6]]},"4280":{"position":[[0,6]]},"4282":{"position":[[0,6]]},"4286":{"position":[[0,6]]},"4288":{"position":[[0,6]]},"4309":{"position":[[0,7]]},"4579":{"position":[[0,7]]},"4592":{"position":[[0,7]]},"4601":{"position":[[19,8]]},"4613":{"position":[[0,7]]},"4642":{"position":[[0,7]]},"4727":{"position":[[0,7]]},"4743":{"position":[[0,7]]},"4762":{"position":[[0,7]]},"4796":{"position":[[0,7]]},"4815":{"position":[[0,7]]},"4884":{"position":[[0,9]]}}}],["order",{"_index":97,"t":{"148":{"position":[[4,5]]}}}],["organ",{"_index":954,"t":{"3626":{"position":[[24,12]]},"3628":{"position":[[23,12]]}}}],["origin",{"_index":979,"t":{"3830":{"position":[[6,6]]}}}],["orphan",{"_index":453,"t":{"994":{"position":[[0,7]]},"1885":{"position":[[0,7]]}}}],["os",{"_index":719,"t":{"2010":{"position":[[6,3]]},"3959":{"position":[[19,2]]}}}],["osd",{"_index":393,"t":{"851":{"position":[[5,3]]},"1174":{"position":[[0,3]]},"1178":{"position":[[10,3]]},"1414":{"position":[[7,4]]},"1416":{"position":[[7,4]]},"1418":{"position":[[7,4]]},"1422":{"position":[[10,4]]},"1594":{"position":[[0,3]]},"1595":{"position":[[18,3]]},"1597":{"position":[[4,3],[36,4]]},"1599":{"position":[[10,3]]},"1601":{"position":[[17,3]]},"1602":{"position":[[9,3]]},"1604":{"position":[[16,3]]},"1606":{"position":[[10,3]]},"1610":{"position":[[10,4]]},"1937":{"position":[[0,3]]},"1941":{"position":[[10,4]]},"2206":{"position":[[8,3]]}}}],["osism",{"_index":387,"t":{"839":{"position":[[0,5]]},"1057":{"position":[[39,5]]},"1062":{"position":[[32,5]]},"1065":{"position":[[36,5]]},"1068":{"position":[[34,5]]},"1070":{"position":[[31,5]]},"1072":{"position":[[37,5]]},"1083":{"position":[[36,5]]},"1085":{"position":[[35,5]]},"1087":{"position":[[38,5]]},"1088":{"position":[[35,5]]},"1090":{"position":[[36,5]]},"1091":{"position":[[57,5]]},"1092":{"position":[[49,5]]},"1094":{"position":[[36,5]]},"1643":{"position":[[22,5]]},"2643":{"position":[[0,5],[32,5]]},"2671":{"position":[[0,5],[32,5]]},"3092":{"position":[[0,5]]},"3125":{"position":[[0,5]]},"3161":{"position":[[17,5]]},"3199":{"position":[[17,5]]}}}],["oss",{"_index":1037,"t":{"4417":{"position":[[0,3]]}}}],["out",{"_index":129,"t":{"182":{"position":[[21,3]]},"797":{"position":[[14,3]]},"3931":{"position":[[0,3]]}}}],["outcom",{"_index":1070,"t":{"4732":{"position":[[0,7]]}}}],["outlook",{"_index":788,"t":{"2381":{"position":[[25,7]]}}}],["output",{"_index":182,"t":{"285":{"position":[[16,6]]}}}],["ov",{"_index":481,"t":{"1092":{"position":[[40,5]]},"1701":{"position":[[13,5]]}}}],["overview",{"_index":66,"t":{"102":{"position":[[0,8]]},"333":{"position":[[14,8]]},"462":{"position":[[0,8]]},"658":{"position":[[0,8]]},"882":{"position":[[0,8]]},"889":{"position":[[0,8]]},"900":{"position":[[0,8]]},"998":{"position":[[0,8]]},"1011":{"position":[[10,8]]},"1573":{"position":[[19,8]]},"1747":{"position":[[0,8]]},"1784":{"position":[[0,8]]},"1806":{"position":[[0,8]]},"1889":{"position":[[0,8]]},"1916":{"position":[[19,8]]},"2322":{"position":[[0,8]]},"2389":{"position":[[0,8]]},"2722":{"position":[[0,8]]},"2890":{"position":[[10,8]]},"3066":{"position":[[0,8]]},"3356":{"position":[[0,8]]},"3585":{"position":[[0,8]]},"3821":{"position":[[0,8]]}}}],["ovn",{"_index":479,"t":{"1091":{"position":[[48,5]]},"1703":{"position":[[21,5]]},"3316":{"position":[[0,3]]},"3963":{"position":[[0,3]]}}}],["p500924",{"_index":4,"t":{"10":{"position":[[8,7]]},"13":{"position":[[8,7]]}}}],["packag",{"_index":492,"t":{"1145":{"position":[[22,8]]},"1150":{"position":[[11,8]]},"1498":{"position":[[17,8]]}}}],["page",{"_index":703,"t":{"1735":{"position":[[5,5]]},"2673":{"position":[[14,4]]},"2675":{"position":[[18,4]]},"2862":{"position":[[28,4]]},"2917":{"position":[[15,4]]},"2921":{"position":[[15,4]]},"3293":{"position":[[7,5]]},"4659":{"position":[[7,4]]}}}],["parallel",{"_index":319,"t":{"603":{"position":[[42,8]]}}}],["paramet",{"_index":105,"t":{"158":{"position":[[0,10]]},"943":{"position":[[9,10]]},"1229":{"position":[[0,9]]},"1390":{"position":[[0,10]]},"1834":{"position":[[9,10]]},"2967":{"position":[[9,10]]}}}],["parser",{"_index":401,"t":{"897":{"position":[[5,6]]},"1755":{"position":[[5,6]]}}}],["partit",{"_index":688,"t":{"1664":{"position":[[21,10]]}}}],["pass",{"_index":186,"t":{"287":{"position":[[23,7]]}}}],["password",{"_index":611,"t":{"1479":{"position":[[18,8]]}}}],["patch",{"_index":1068,"t":{"4714":{"position":[[10,5]]},"4716":{"position":[[0,5]]}}}],["patent",{"_index":123,"t":{"178":{"position":[[0,7]]}}}],["path",{"_index":1046,"t":{"4519":{"position":[[9,4]]}}}],["pentest",{"_index":804,"t":{"2488":{"position":[[14,10]]},"2498":{"position":[[18,10]]},"2511":{"position":[[17,10]]},"3289":{"position":[[24,10]]}}}],["per",{"_index":875,"t":{"2878":{"position":[[0,3]]}}}],["perform",{"_index":684,"t":{"1649":{"position":[[0,11]]},"1974":{"position":[[0,11]]},"4239":{"position":[[0,11]]},"4375":{"position":[[16,11]]},"4377":{"position":[[9,11]]},"4400":{"position":[[13,11]]},"4402":{"position":[[9,11]]}}}],["period",{"_index":963,"t":{"3641":{"position":[[7,6]]}}}],["persona",{"_index":394,"t":{"853":{"position":[[0,8]]},"3233":{"position":[[24,7]]}}}],["pg",{"_index":665,"t":{"1614":{"position":[[8,2]]},"1620":{"position":[[11,2],[62,3]]},"1636":{"position":[[14,3]]},"1945":{"position":[[8,2]]},"1951":{"position":[[11,2],[62,3]]},"1967":{"position":[[14,3]]}}}],["phase",{"_index":857,"t":{"2759":{"position":[[5,6]]},"2761":{"position":[[7,6]]},"2805":{"position":[[0,6]]},"3532":{"position":[[9,5]]},"3534":{"position":[[12,5]]},"3536":{"position":[[11,5]]},"3538":{"position":[[12,5]]},"4700":{"position":[[0,5]]}}}],["physic",{"_index":1011,"t":{"4181":{"position":[[0,8]]}}}],["pick",{"_index":1028,"t":{"4278":{"position":[[34,4]]}}}],["pickl",{"_index":707,"t":{"1980":{"position":[[17,6]]}}}],["pin",{"_index":511,"t":{"1188":{"position":[[4,7]]}}}],["pipelin",{"_index":171,"t":{"268":{"position":[[11,9]]},"363":{"position":[[0,9]]},"523":{"position":[[0,9]]},"2131":{"position":[[18,9]]},"3379":{"position":[[46,8]]}}}],["pipeline.yaml",{"_index":887,"t":{"3039":{"position":[[4,13]]}}}],["placement",{"_index":602,"t":{"1432":{"position":[[11,9]]},"1611":{"position":[[0,9]]},"1612":{"position":[[5,9]]},"1616":{"position":[[28,9]]},"1942":{"position":[[0,9]]},"1943":{"position":[[5,9]]},"1947":{"position":[[28,9]]}}}],["plan",{"_index":45,"t":{"65":{"position":[[40,8]]}}}],["plane",{"_index":381,"t":{"819":{"position":[[24,5]]},"1098":{"position":[[8,5]]},"1130":{"position":[[8,5]]},"1131":{"position":[[8,5]]},"1132":{"position":[[5,5]]},"1133":{"position":[[11,5]]},"1134":{"position":[[11,5]]},"1135":{"position":[[8,5]]}}}],["play",{"_index":686,"t":{"1656":{"position":[[9,5]]},"1658":{"position":[[8,4]]},"1660":{"position":[[14,5]]},"1662":{"position":[[8,4]]},"1664":{"position":[[8,5]]}}}],["playbook",{"_index":682,"t":{"1643":{"position":[[28,9]]},"2122":{"position":[[8,8]]}}}],["plugin",{"_index":1029,"t":{"4278":{"position":[[69,6]]},"4284":{"position":[[35,6]]},"4568":{"position":[[22,7]]}}}],["plusserv",{"_index":13,"t":{"20":{"position":[[0,10]]},"43":{"position":[[46,10]]}}}],["pod",{"_index":1050,"t":{"4542":{"position":[[0,3]]}}}],["polici",{"_index":559,"t":{"1323":{"position":[[15,6]]},"2442":{"position":[[23,6]]},"2519":{"position":[[7,6]]},"3678":{"position":[[7,8]]},"3703":{"position":[[7,6]]},"3792":{"position":[[7,6]]},"4061":{"position":[[0,8]]},"4084":{"position":[[12,8]]},"4542":{"position":[[13,8]]},"4666":{"position":[[0,6]]}}}],["polling.yaml",{"_index":884,"t":{"3033":{"position":[[4,12]]}}}],["pool",{"_index":503,"t":{"1170":{"position":[[6,5]]},"1410":{"position":[[6,5]]},"1622":{"position":[[6,4]]},"1624":{"position":[[4,5]]},"1630":{"position":[[20,4]]},"1632":{"position":[[29,4]]},"1634":{"position":[[9,4]]},"1636":{"position":[[24,4]]},"1640":{"position":[[24,4],[36,6]]},"1953":{"position":[[6,4]]},"1955":{"position":[[4,5]]},"1961":{"position":[[20,4]]},"1963":{"position":[[29,4]]},"1965":{"position":[[9,4]]},"1967":{"position":[[24,4]]},"1971":{"position":[[24,4],[36,6]]}}}],["port",{"_index":600,"t":{"1426":{"position":[[39,5]]},"2884":{"position":[[0,4]]}}}],["portal",{"_index":359,"t":{"721":{"position":[[17,6]]}}}],["posit",{"_index":98,"t":{"150":{"position":[[0,11]]},"152":{"position":[[0,8]]}}}],["possibl",{"_index":71,"t":{"106":{"position":[[32,9]]}}}],["post",{"_index":518,"t":{"1225":{"position":[[8,4]]},"3254":{"position":[[17,5]]},"4712":{"position":[[10,4]]}}}],["postgr",{"_index":339,"t":{"689":{"position":[[17,8]]}}}],["postgresql",{"_index":352,"t":{"716":{"position":[[9,12]]}}}],["potenti",{"_index":1013,"t":{"4221":{"position":[[0,9]]}}}],["pr",{"_index":336,"t":{"637":{"position":[[17,4]]}}}],["practic",{"_index":65,"t":{"101":{"position":[[15,8]]}}}],["pragmat",{"_index":988,"t":{"3915":{"position":[[10,9]]}}}],["pre",{"_index":75,"t":{"118":{"position":[[0,3]]},"3987":{"position":[[10,3]]}}}],["precheck",{"_index":761,"t":{"2239":{"position":[[0,9]]}}}],["prefac",{"_index":459,"t":{"1024":{"position":[[0,7]]},"2436":{"position":[[0,7]]}}}],["preliminari",{"_index":1015,"t":{"4223":{"position":[[0,11]]}}}],["premis",{"_index":827,"t":{"2571":{"position":[[0,7]]}}}],["prepar",{"_index":305,"t":{"577":{"position":[[23,11]]},"982":{"position":[[0,12]]},"1219":{"position":[[8,11]]},"1873":{"position":[[0,12]]},"2116":{"position":[[7,11]]},"2611":{"position":[[0,7]]},"2654":{"position":[[0,7]]},"4866":{"position":[[0,11]]},"4871":{"position":[[0,11]]},"4873":{"position":[[0,11]]}}}],["prerequisit",{"_index":233,"t":{"353":{"position":[[0,13]]},"375":{"position":[[0,13]]},"470":{"position":[[0,13]]},"573":{"position":[[0,13]]},"685":{"position":[[0,13]]},"697":{"position":[[0,13]]},"729":{"position":[[0,13]]},"744":{"position":[[0,13]]},"750":{"position":[[0,13]]},"1485":{"position":[[0,13]]},"2375":{"position":[[0,13]]},"2474":{"position":[[0,13]]},"2562":{"position":[[0,13]]},"2609":{"position":[[0,13]]},"2633":{"position":[[0,13]]},"2639":{"position":[[0,13]]},"2652":{"position":[[0,13]]},"2667":{"position":[[0,13]]},"2753":{"position":[[0,13]]},"2848":{"position":[[0,13]]},"3595":{"position":[[0,12]]}}}],["preview",{"_index":749,"t":{"2160":{"position":[[25,8]]},"2208":{"position":[[25,8]]},"3021":{"position":[[10,8]]},"3186":{"position":[[0,8]]},"3233":{"position":[[0,8]]},"3235":{"position":[[0,8]]},"3237":{"position":[[0,8]]},"3250":{"position":[[0,8]]},"3287":{"position":[[5,8]]},"3289":{"position":[[5,8]]},"3291":{"position":[[5,8]]}}}],["previou",{"_index":974,"t":{"3721":{"position":[[0,8]]},"3814":{"position":[[0,8]]},"3909":{"position":[[0,8]]},"4379":{"position":[[0,8]]},"4460":{"position":[[0,8]]}}}],["principl",{"_index":989,"t":{"3917":{"position":[[10,10]]}}}],["privileg",{"_index":201,"t":{"308":{"position":[[45,10]]}}}],["pro",{"_index":1042,"t":{"4509":{"position":[[0,4]]}}}],["problem",{"_index":375,"t":{"803":{"position":[[19,8]]},"1311":{"position":[[0,8]]}}}],["procedur",{"_index":528,"t":{"1245":{"position":[[8,9]]},"4267":{"position":[[0,9]]},"4269":{"position":[[0,9]]}}}],["process",{"_index":263,"t":{"437":{"position":[[8,7]]},"1225":{"position":[[13,10]]},"2755":{"position":[[6,7]]},"3530":{"position":[[0,7]]},"3589":{"position":[[32,10]]},"3607":{"position":[[0,7]]}}}],["product",{"_index":227,"t":{"340":{"position":[[21,10]]},"605":{"position":[[63,10]]},"1045":{"position":[[32,10]]},"1047":{"position":[[48,10]]}}}],["program",{"_index":1065,"t":{"4678":{"position":[[0,11]]}}}],["project",{"_index":3,"t":{"10":{"position":[[0,7]]},"13":{"position":[[0,7]]},"27":{"position":[[0,8]]},"32":{"position":[[0,8]]},"63":{"position":[[0,7]]},"268":{"position":[[25,7]]},"361":{"position":[[0,8]]},"2101":{"position":[[21,7]]},"2462":{"position":[[9,8]]},"2564":{"position":[[0,7]]},"2746":{"position":[[40,7]]},"3192":{"position":[[0,7]]},"3622":{"position":[[16,7]]},"3630":{"position":[[20,7]]},"3647":{"position":[[17,7]]},"3991":{"position":[[15,7]]},"4559":{"position":[[10,8]]},"4561":{"position":[[26,8]]}}}],["prometheu",{"_index":476,"t":{"1087":{"position":[[24,10]]},"2698":{"position":[[19,10]]},"2700":{"position":[[11,10],[26,10]]},"2702":{"position":[[21,10]]},"3049":{"position":[[0,10]]},"4880":{"position":[[0,10]]}}}],["proof",{"_index":1017,"t":{"4229":{"position":[[0,5]]}}}],["proper",{"_index":918,"t":{"3250":{"position":[[9,6]]}}}],["properli",{"_index":1062,"t":{"4624":{"position":[[17,8]]}}}],["properti",{"_index":399,"t":{"874":{"position":[[6,10]]},"1775":{"position":[[6,10]]},"3893":{"position":[[0,10]]},"3901":{"position":[[15,10]]},"4375":{"position":[[36,10]]},"4377":{"position":[[29,10]]},"4400":{"position":[[33,10]]},"4402":{"position":[[29,10]]}}}],["propos",{"_index":316,"t":{"596":{"position":[[0,8]]},"3532":{"position":[[0,8]]},"3654":{"position":[[0,8]]},"3657":{"position":[[9,8]]},"3659":{"position":[[0,8]]},"3674":{"position":[[0,8]]},"3694":{"position":[[9,8]]},"3696":{"position":[[0,8]]},"3719":{"position":[[0,8]]},"3781":{"position":[[9,8]]},"3783":{"position":[[0,8]]},"3812":{"position":[[0,8]]},"4227":{"position":[[9,9]]},"4519":{"position":[[0,8]]}}}],["protect",{"_index":1033,"t":{"4307":{"position":[[16,10]]},"4312":{"position":[[18,10]]}}}],["provid",{"_index":253,"t":{"404":{"position":[[14,8]]},"412":{"position":[[29,8]]},"453":{"position":[[14,8]]},"544":{"position":[[8,9],[37,9]]},"546":{"position":[[23,9]]},"613":{"position":[[11,8]]},"617":{"position":[[0,8]]},"827":{"position":[[14,8]]},"4284":{"position":[[14,9]]},"4511":{"position":[[5,8]]}}}],["providercli",{"_index":283,"t":{"517":{"position":[[0,14]]}}}],["provis",{"_index":608,"t":{"1465":{"position":[[7,12]]}}}],["proxi",{"_index":357,"t":{"721":{"position":[[0,6]]},"960":{"position":[[15,6]]},"1343":{"position":[[22,5]]},"1851":{"position":[[15,6]]},"2556":{"position":[[4,5]]},"2842":{"position":[[43,6]]},"2984":{"position":[[15,6]]}}}],["proxysql",{"_index":532,"t":{"1253":{"position":[[0,8]]}}}],["public",{"_index":226,"t":{"340":{"position":[[0,6]]},"1294":{"position":[[0,6]]},"4286":{"position":[[9,6]]}}}],["publish",{"_index":845,"t":{"2698":{"position":[[0,7]]}}}],["pull",{"_index":39,"t":{"60":{"position":[[30,4]]}}}],["pure",{"_index":543,"t":{"1284":{"position":[[0,4]]}}}],["pursu",{"_index":829,"t":{"2575":{"position":[[23,6]]}}}],["push",{"_index":264,"t":{"439":{"position":[[19,4]]},"2700":{"position":[[37,4]]},"2702":{"position":[[32,4]]}}}],["put",{"_index":1069,"t":{"4716":{"position":[[9,3]]}}}],["pytest",{"_index":198,"t":{"306":{"position":[[0,6]]}}}],["python",{"_index":733,"t":{"2093":{"position":[[0,6]]},"2109":{"position":[[18,6]]},"2278":{"position":[[0,6]]},"4282":{"position":[[15,6]]}}}],["qemu",{"_index":714,"t":{"2006":{"position":[[0,4]]}}}],["qo",{"_index":698,"t":{"1719":{"position":[[19,5]]},"1722":{"position":[[19,5]]},"1737":{"position":[[19,5]]}}}],["qualiti",{"_index":697,"t":{"1719":{"position":[[0,7]]},"1722":{"position":[[0,7]]},"1737":{"position":[[0,7]]}}}],["queri",{"_index":664,"t":{"1614":{"position":[[0,5]]},"1945":{"position":[[0,5]]},"2681":{"position":[[0,5]]},"2685":{"position":[[0,5]]}}}],["question",{"_index":938,"t":{"3542":{"position":[[5,9]]},"3576":{"position":[[5,9]]},"3616":{"position":[[5,9]]},"3733":{"position":[[5,9]]},"3948":{"position":[[5,9]]},"3969":{"position":[[5,9]]},"4194":{"position":[[5,9]]},"4311":{"position":[[5,9]]},"4594":{"position":[[5,9]]},"4644":{"position":[[5,9]]},"4747":{"position":[[5,9]]},"4764":{"position":[[5,9]]},"4798":{"position":[[5,9]]},"4817":{"position":[[5,9]]}}}],["queue",{"_index":385,"t":{"833":{"position":[[8,5]]},"4324":{"position":[[8,5]]}}}],["quick",{"_index":832,"t":{"2601":{"position":[[0,5]]},"2711":{"position":[[0,5]]}}}],["quickstart",{"_index":69,"t":{"106":{"position":[[0,10]]},"467":{"position":[[0,10]]},"2490":{"position":[[0,10]]},"2540":{"position":[[0,10]]}}}],["quota",{"_index":406,"t":{"917":{"position":[[0,5]]},"1717":{"position":[[5,5]]},"1801":{"position":[[0,5]]}}}],["r1",{"_index":895,"t":{"3066":{"position":[[23,2]]},"3076":{"position":[[39,2]]}}}],["r2",{"_index":907,"t":{"3106":{"position":[[39,2]]}}}],["r3",{"_index":909,"t":{"3139":{"position":[[39,2]]}}}],["r4",{"_index":911,"t":{"3171":{"position":[[39,2]]}}}],["r5",{"_index":915,"t":{"3209":{"position":[[39,2]]}}}],["r6",{"_index":920,"t":{"3262":{"position":[[39,2]]}}}],["r7",{"_index":923,"t":{"3311":{"position":[[39,2]]}}}],["r8",{"_index":924,"t":{"3320":{"position":[[6,2]]}}}],["rado",{"_index":674,"t":{"1622":{"position":[[0,5]]},"1953":{"position":[[0,5]]}}}],["rate",{"_index":1039,"t":{"4478":{"position":[[9,4]]},"4488":{"position":[[9,4]]}}}],["rational",{"_index":969,"t":{"3680":{"position":[[0,9]]}}}],["raw",{"_index":764,"t":{"2245":{"position":[[23,3]]},"2247":{"position":[[9,3]]}}}],["rbac",{"_index":995,"t":{"3989":{"position":[[36,4]]},"4626":{"position":[[30,4]]}}}],["rbd",{"_index":512,"t":{"1190":{"position":[[7,4]]}}}],["rc",{"_index":556,"t":{"1313":{"position":[[59,2]]}}}],["read",{"_index":131,"t":{"184":{"position":[[8,7]]},"250":{"position":[[8,7]]}}}],["readabl",{"_index":946,"t":{"3589":{"position":[[8,11]]}}}],["readi",{"_index":250,"t":{"394":{"position":[[30,5]]},"406":{"position":[[29,5]]}}}],["real",{"_index":850,"t":{"2713":{"position":[[0,4]]},"3758":{"position":[[0,4]]}}}],["realm",{"_index":208,"t":{"320":{"position":[[17,5]]}}}],["reason",{"_index":992,"t":{"3983":{"position":[[0,7]]}}}],["rebal",{"_index":662,"t":{"1610":{"position":[[0,9]]},"1941":{"position":[[0,9]]}}}],["reboot",{"_index":618,"t":{"1543":{"position":[[0,6]]},"1579":{"position":[[0,6]]},"1708":{"position":[[0,6]]},"1922":{"position":[[0,6]]}}}],["rebuild",{"_index":397,"t":{"870":{"position":[[19,8]]},"872":{"position":[[22,7]]},"1771":{"position":[[19,8]]},"1773":{"position":[[22,7]]}}}],["recap",{"_index":251,"t":{"396":{"position":[[0,5]]}}}],["receiv",{"_index":877,"t":{"2905":{"position":[[0,7]]}}}],["reciproc",{"_index":114,"t":{"170":{"position":[[0,11]]}}}],["recommend",{"_index":464,"t":{"1045":{"position":[[16,11]]},"1047":{"position":[[20,11]]},"2031":{"position":[[23,13]]},"2292":{"position":[[0,11]]},"2306":{"position":[[0,11]]},"3899":{"position":[[0,11]]},"4020":{"position":[[0,11]]},"4305":{"position":[[18,15]]},"4375":{"position":[[0,11]]}}}],["reconcil",{"_index":513,"t":{"1210":{"position":[[0,10]]}}}],["reconcili",{"_index":343,"t":{"693":{"position":[[69,14]]}}}],["record",{"_index":695,"t":{"1693":{"position":[[10,7]]},"4099":{"position":[[22,6]]},"4631":{"position":[[9,6]]}}}],["recoveri",{"_index":624,"t":{"1558":{"position":[[0,8]]},"4101":{"position":[[72,9]]}}}],["redi",{"_index":338,"t":{"689":{"position":[[7,5]]},"714":{"position":[[0,5]]}}}],["redund",{"_index":1004,"t":{"4101":{"position":[[82,10]]},"4237":{"position":[[6,9]]}}}],["refer",{"_index":26,"t":{"40":{"position":[[0,10]]},"785":{"position":[[10,9]]},"787":{"position":[[21,9]]},"789":{"position":[[35,9]]},"1229":{"position":[[10,9]]},"2226":{"position":[[9,9]]},"2708":{"position":[[17,10]]},"2919":{"position":[[0,9]]},"2923":{"position":[[0,9]]},"3578":{"position":[[0,9]]},"4243":{"position":[[0,10]]},"4731":{"position":[[0,9]]}}}],["refinement/sprint",{"_index":44,"t":{"65":{"position":[[22,17]]}}}],["regard",{"_index":792,"t":{"2438":{"position":[[8,9]]}}}],["region",{"_index":376,"t":{"811":{"position":[[16,6]]}}}],["registr",{"_index":168,"t":{"263":{"position":[[11,12]]}}}],["registri",{"_index":355,"t":{"718":{"position":[[17,8]]},"752":{"position":[[25,8]]},"4286":{"position":[[26,8]]}}}],["regress",{"_index":193,"t":{"300":{"position":[[12,10]]}}}],["regul",{"_index":975,"t":{"3730":{"position":[[0,11]]}}}],["regular",{"_index":396,"t":{"870":{"position":[[11,7]]},"872":{"position":[[14,7]]},"1771":{"position":[[11,7]]},"1773":{"position":[[14,7]]},"4532":{"position":[[0,7]]}}}],["reject",{"_index":937,"t":{"3540":{"position":[[0,9]]}}}],["relat",{"_index":913,"t":{"3188":{"position":[[19,7]]},"3734":{"position":[[0,7]]},"3935":{"position":[[0,7]]},"3952":{"position":[[0,7]]},"3974":{"position":[[0,7]]},"3999":{"position":[[0,7]]},"4031":{"position":[[0,7]]},"4052":{"position":[[0,7]]},"4086":{"position":[[0,7]]},"4127":{"position":[[0,7]]},"4168":{"position":[[0,7]]},"4207":{"position":[[0,7]]},"4334":{"position":[[0,7]]},"4345":{"position":[[0,7]]},"4356":{"position":[[0,7]]},"4375":{"position":[[28,7]]},"4377":{"position":[[21,7]]},"4400":{"position":[[25,7]]},"4402":{"position":[[21,7]]},"4404":{"position":[[0,7]]},"4423":{"position":[[0,7]]},"4496":{"position":[[0,7]]},"4550":{"position":[[0,7]]},"4565":{"position":[[0,7]]},"4598":{"position":[[0,7]]},"4621":{"position":[[0,7]]},"4648":{"position":[[0,7]]},"4749":{"position":[[0,7]]},"4768":{"position":[[0,7]]},"4787":{"position":[[0,7]]},"4802":{"position":[[0,7]]},"4821":{"position":[[0,7]]}}}],["relay",{"_index":1078,"t":{"4884":{"position":[[33,5]]}}}],["releas",{"_index":230,"t":{"348":{"position":[[0,8]]},"437":{"position":[[0,7]]},"441":{"position":[[8,7]]},"472":{"position":[[10,7]]},"488":{"position":[[8,7]]},"599":{"position":[[24,9]]},"1256":{"position":[[7,7]]},"1570":{"position":[[15,8]]},"1903":{"position":[[15,8]]},"2054":{"position":[[14,8]]},"2056":{"position":[[14,7]]},"2058":{"position":[[7,7]]},"2060":{"position":[[13,7]]},"2068":{"position":[[21,7]]},"2222":{"position":[[10,8]]},"3023":{"position":[[0,7]]},"3074":{"position":[[0,7]]},"3104":{"position":[[0,7]]},"3137":{"position":[[0,7]]},"3169":{"position":[[0,7]]},"3207":{"position":[[0,7]]},"3260":{"position":[[0,7]]},"3293":{"position":[[22,7]]},"3309":{"position":[[0,7]]},"3337":{"position":[[0,7]]}}}],["relev",{"_index":235,"t":{"359":{"position":[[23,8]]}}}],["remark",{"_index":986,"t":{"3903":{"position":[[0,7]]}}}],["remind",{"_index":164,"t":{"257":{"position":[[5,8]]}}}],["remot",{"_index":282,"t":{"513":{"position":[[30,6]]},"1223":{"position":[[44,6]]}}}],["remov",{"_index":656,"t":{"1602":{"position":[[0,6]]},"1604":{"position":[[0,6]]},"1606":{"position":[[0,6]]},"1712":{"position":[[0,6]]},"1715":{"position":[[0,6]]},"3094":{"position":[[0,8]]},"3127":{"position":[[0,8]]},"3158":{"position":[[0,8]]},"3196":{"position":[[0,8]]},"3241":{"position":[[0,8]]},"3301":{"position":[[0,8]]},"3332":{"position":[[0,8]]}}}],["repair",{"_index":671,"t":{"1620":{"position":[[17,6]]},"1951":{"position":[[17,6]]}}}],["replac",{"_index":654,"t":{"1601":{"position":[[0,7]]},"1606":{"position":[[37,9]]}}}],["replic",{"_index":677,"t":{"1630":{"position":[[9,10]]},"1961":{"position":[[9,10]]},"4027":{"position":[[0,11]]}}}],["repo",{"_index":59,"t":{"94":{"position":[[21,4]]},"270":{"position":[[14,4]]},"559":{"position":[[10,4]]},"2125":{"position":[[9,5]]},"2127":{"position":[[9,5]]}}}],["report",{"_index":237,"t":{"365":{"position":[[0,7]]},"2498":{"position":[[29,7]]},"2500":{"position":[[31,7]]},"2502":{"position":[[40,7]]},"2511":{"position":[[28,7]]},"2593":{"position":[[6,8]]},"3027":{"position":[[4,9]]}}}],["repositori",{"_index":87,"t":{"131":{"position":[[21,10]]},"548":{"position":[[3,10]]},"1217":{"position":[[29,10]]},"1223":{"position":[[55,10]]},"1231":{"position":[[14,10]]},"1233":{"position":[[32,10]]},"1488":{"position":[[22,10]]},"1500":{"position":[[32,10]]},"2068":{"position":[[0,12]]},"2891":{"position":[[11,10]]},"4842":{"position":[[19,10]]}}}],["request",{"_index":10,"t":{"18":{"position":[[7,7]]},"60":{"position":[[35,8]]},"4712":{"position":[[15,8]]},"4714":{"position":[[16,8]]}}}],["requir",{"_index":68,"t":{"104":{"position":[[0,12]]},"126":{"position":[[0,12]]},"308":{"position":[[31,7]]},"375":{"position":[[18,12]]},"858":{"position":[[0,12]]},"1014":{"position":[[0,12]]},"1156":{"position":[[17,8]]},"1380":{"position":[[33,12]]},"1485":{"position":[[16,12]]},"1498":{"position":[[8,8]]},"1759":{"position":[[0,12]]},"2026":{"position":[[0,12]]},"2176":{"position":[[0,12]]},"2237":{"position":[[0,12]]},"2284":{"position":[[13,12]]},"2298":{"position":[[13,12]]},"2375":{"position":[[18,12]]},"3376":{"position":[[7,12]]},"3520":{"position":[[0,12]]},"3660":{"position":[[0,10]]},"3662":{"position":[[0,10]]},"3697":{"position":[[0,10]]},"3699":{"position":[[0,10]]},"3784":{"position":[[0,10]]},"3786":{"position":[[0,10]]},"3825":{"position":[[10,12]]},"3959":{"position":[[74,8]]},"3987":{"position":[[14,12]]},"4018":{"position":[[0,8]]},"4177":{"position":[[0,8]]},"4377":{"position":[[0,8]]},"4400":{"position":[[0,8]]},"4402":{"position":[[0,8]]},"4419":{"position":[[0,8]]},"4507":{"position":[[0,8]]},"4659":{"position":[[12,12]]},"4685":{"position":[[0,12]]},"4725":{"position":[[0,12]]},"4732":{"position":[[32,12]]}}}],["reserv",{"_index":572,"t":{"1362":{"position":[[0,7]]}}}],["reset",{"_index":693,"t":{"1687":{"position":[[7,5]]},"2154":{"position":[[0,5]]}}}],["resolv",{"_index":906,"t":{"3100":{"position":[[0,8]]},"3133":{"position":[[0,8]]},"3165":{"position":[[0,8]]},"3203":{"position":[[0,8]]},"3249":{"position":[[0,8]]},"3335":{"position":[[0,8]]}}}],["resourc",{"_index":12,"t":{"18":{"position":[[21,9]]},"390":{"position":[[20,8]]},"455":{"position":[[23,8]]},"587":{"position":[[28,8]]},"939":{"position":[[0,8]]},"1186":{"position":[[0,8]]},"1362":{"position":[[21,9]]},"1830":{"position":[[0,8]]},"2179":{"position":[[6,9]]},"2963":{"position":[[0,8]]},"3433":{"position":[[72,9]]},"4112":{"position":[[9,9]]},"4132":{"position":[[63,9]]},"4134":{"position":[[15,9]]},"4136":{"position":[[21,9]]},"4716":{"position":[[26,9]]},"4852":{"position":[[18,8]]}}}],["respons",{"_index":809,"t":{"2504":{"position":[[9,16]]}}}],["restart",{"_index":425,"t":{"943":{"position":[[24,10]]},"1506":{"position":[[17,8]]},"1508":{"position":[[19,8]]},"1647":{"position":[[0,7]]},"1834":{"position":[[24,10]]},"2164":{"position":[[0,7]]},"2967":{"position":[[24,10]]}}}],["restor",{"_index":350,"t":{"709":{"position":[[0,7]]},"1556":{"position":[[0,7]]},"2344":{"position":[[0,7]]},"2346":{"position":[[0,9]]},"2348":{"position":[[0,9]]},"2350":{"position":[[0,9]]},"2352":{"position":[[0,9]]},"2354":{"position":[[0,9]]},"2411":{"position":[[0,7]]},"2413":{"position":[[0,9]]},"2415":{"position":[[0,9]]},"2417":{"position":[[0,9]]},"2419":{"position":[[0,9]]},"2421":{"position":[[0,9]]}}}],["restrict",{"_index":890,"t":{"3059":{"position":[[8,12]]},"3076":{"position":[[23,12]]},"3106":{"position":[[23,12]]},"3139":{"position":[[23,12]]},"3171":{"position":[[23,12]]},"3209":{"position":[[23,12]]},"3262":{"position":[[23,12]]},"3311":{"position":[[23,12]]},"3338":{"position":[[23,12]]}}}],["result",{"_index":846,"t":{"2698":{"position":[[8,7]]}}}],["retriev",{"_index":780,"t":{"2342":{"position":[[0,10]]},"2409":{"position":[[0,10]]}}}],["return",{"_index":1067,"t":{"4712":{"position":[[0,6]]},"4714":{"position":[[0,6]]}}}],["reus",{"_index":1030,"t":{"4280":{"position":[[34,5]]}}}],["revers",{"_index":437,"t":{"960":{"position":[[6,8]]},"1851":{"position":[[6,8]]},"2842":{"position":[[35,7]]},"2984":{"position":[[6,8]]}}}],["review/backlog",{"_index":43,"t":{"65":{"position":[[7,14]]}}}],["revok",{"_index":798,"t":{"2456":{"position":[[0,8]]}}}],["rfc2119",{"_index":177,"t":{"281":{"position":[[35,7]]},"283":{"position":[[16,7]]},"290":{"position":[[38,7]]},"294":{"position":[[31,7]]},"298":{"position":[[14,7]]}}}],["rgw",{"_index":501,"t":{"1168":{"position":[[0,3]]},"1406":{"position":[[0,3]]},"1504":{"position":[[0,3]]},"1526":{"position":[[0,3]]}}}],["right",{"_index":244,"t":{"388":{"position":[[8,5]]},"486":{"position":[[6,5]]}}}],["risk",{"_index":321,"t":{"609":{"position":[[0,5]]}}}],["roadmap",{"_index":231,"t":{"348":{"position":[[13,7]]}}}],["role",{"_index":104,"t":{"156":{"position":[[9,5]]},"1662":{"position":[[18,6]]},"2444":{"position":[[19,4]]},"2446":{"position":[[33,5]]},"2454":{"position":[[29,4]]},"2456":{"position":[[28,4]]},"2466":{"position":[[9,4]]},"2504":{"position":[[0,4]]},"3622":{"position":[[0,4]]},"3626":{"position":[[0,5]]},"3647":{"position":[[0,5]]}}}],["rook",{"_index":601,"t":{"1428":{"position":[[0,4]]},"1911":{"position":[[0,4]]},"2160":{"position":[[9,4]]},"2208":{"position":[[9,4]]}}}],["rook_network",{"_index":591,"t":{"1404":{"position":[[24,12]]}}}],["rook_storag",{"_index":598,"t":{"1420":{"position":[[24,12]]}}}],["rookifi",{"_index":708,"t":{"1982":{"position":[[0,7]]}}}],["room",{"_index":152,"t":{"219":{"position":[[10,5]]},"236":{"position":[[10,5]]}}}],["rotat",{"_index":452,"t":{"990":{"position":[[8,8]]},"1881":{"position":[[8,8]]},"4484":{"position":[[12,8]]},"4494":{"position":[[12,8]]}}}],["rto",{"_index":1005,"t":{"4103":{"position":[[20,3]]}}}],["rule",{"_index":111,"t":{"162":{"position":[[16,5]]},"1626":{"position":[[15,5]]},"1638":{"position":[[13,5]]},"1640":{"position":[[13,4]]},"1957":{"position":[[15,5]]},"1969":{"position":[[13,5]]},"1971":{"position":[[13,4]]},"3987":{"position":[[35,5]]},"4040":{"position":[[75,5]]}}}],["run",{"_index":298,"t":{"567":{"position":[[3,3]]},"1221":{"position":[[8,3]]},"1490":{"position":[[12,3]]},"1492":{"position":[[12,3]]},"1729":{"position":[[17,7]]},"1983":{"position":[[0,3]]},"1985":{"position":[[6,3]]},"1997":{"position":[[0,3]]},"2103":{"position":[[16,4]]},"2731":{"position":[[0,7]]},"2733":{"position":[[0,7]]},"2735":{"position":[[19,3]]},"2797":{"position":[[0,3]]},"2799":{"position":[[12,3]]},"2801":{"position":[[0,7]]}}}],["run_cloudname.sh",{"_index":435,"t":{"958":{"position":[[25,16]]},"1849":{"position":[[25,16]]},"2982":{"position":[[25,16]]}}}],["runtim",{"_index":795,"t":{"2446":{"position":[[0,9]]}}}],["rx",{"_index":925,"t":{"3338":{"position":[[39,2]]}}}],["s",{"_index":433,"t":{"958":{"position":[[5,1]]},"1849":{"position":[[5,1]]},"2982":{"position":[[5,1]]}}}],["s3",{"_index":25,"t":{"38":{"position":[[15,4]]},"700":{"position":[[0,2]]},"733":{"position":[[0,2]]}}}],["sampl",{"_index":982,"t":{"3842":{"position":[[7,6]]},"3852":{"position":[[7,6]]}}}],["sata/sa",{"_index":644,"t":{"1584":{"position":[[15,8]]},"1592":{"position":[[15,8]]},"1927":{"position":[[15,8]]},"1935":{"position":[[15,8]]}}}],["save",{"_index":234,"t":{"359":{"position":[[9,4]]},"2004":{"position":[[11,6]]}}}],["sbom",{"_index":898,"t":{"3072":{"position":[[0,4]]}}}],["sc",{"_index":1,"t":{"6":{"position":[[15,3]]},"281":{"position":[[17,3]]},"283":{"position":[[51,3]]},"328":{"position":[[30,3]]},"340":{"position":[[7,3]]},"342":{"position":[[15,3]]},"587":{"position":[[37,4]]},"771":{"position":[[10,3]]},"773":{"position":[[7,3]]},"775":{"position":[[22,4]]},"779":{"position":[[21,3]]},"781":{"position":[[11,3]]},"783":{"position":[[65,4]]},"787":{"position":[[52,3]]},"797":{"position":[[22,4]]},"799":{"position":[[17,3]]},"801":{"position":[[18,3]]},"868":{"position":[[0,3]]},"1059":{"position":[[17,3]]},"1662":{"position":[[58,3]]},"1769":{"position":[[0,3]]},"2373":{"position":[[0,3],[7,3]]},"2430":{"position":[[113,3]]},"2488":{"position":[[0,3]]},"2917":{"position":[[4,3]]},"2921":{"position":[[4,3]]},"3017":{"position":[[4,3]]},"3087":{"position":[[0,3]]},"3120":{"position":[[0,3]]},"3154":{"position":[[0,3]]},"3190":{"position":[[0,3]]},"3231":{"position":[[0,3]]},"3286":{"position":[[0,3]]},"3291":{"position":[[14,3]]},"3330":{"position":[[0,3]]},"3377":{"position":[[4,3]]},"3380":{"position":[[4,3]]},"3383":{"position":[[4,3]]},"3455":{"position":[[12,3]]},"3585":{"position":[[22,3]]},"3593":{"position":[[0,3]]},"3622":{"position":[[12,3]]},"3626":{"position":[[13,3]]},"3628":{"position":[[12,3]]},"3630":{"position":[[16,3]]},"3647":{"position":[[13,3]]},"3676":{"position":[[9,3]]},"3684":{"position":[[7,4]]},"3723":{"position":[[7,3]]},"3766":{"position":[[11,3]]},"3790":{"position":[[9,3]]},"3816":{"position":[[7,3]]},"3895":{"position":[[9,3]]},"4828":{"position":[[63,5]]}}}],["scale",{"_index":852,"t":{"2717":{"position":[[0,7]]}}}],["scan",{"_index":818,"t":{"2532":{"position":[[31,8]]},"2534":{"position":[[0,8]]},"2536":{"position":[[0,8]]},"2538":{"position":[[28,9]]}}}],["scenario",{"_index":463,"t":{"1045":{"position":[[0,8]]},"1047":{"position":[[0,8]]},"2235":{"position":[[0,8]]},"4108":{"position":[[8,9]]},"4132":{"position":[[44,9]]}}}],["schedul",{"_index":578,"t":{"1370":{"position":[[33,9]]}}}],["scope",{"_index":775,"t":{"2320":{"position":[[0,5]]},"2387":{"position":[[0,5]]},"3013":{"position":[[0,5]]},"3043":{"position":[[0,5]]},"3080":{"position":[[0,5]]},"3113":{"position":[[0,5]]},"3147":{"position":[[0,5]]},"3179":{"position":[[0,5]]},"3217":{"position":[[0,5]]},"3250":{"position":[[16,5]]},"3275":{"position":[[0,5]]},"3326":{"position":[[0,5]]},"3354":{"position":[[0,5]]},"3587":{"position":[[25,6]]},"3931":{"position":[[7,5]]},"3991":{"position":[[23,6]]},"4160":{"position":[[0,5]]},"4624":{"position":[[26,6]]}}}],["script",{"_index":184,"t":{"285":{"position":[[31,7]]},"294":{"position":[[18,6]]},"958":{"position":[[42,6]]},"1269":{"position":[[11,7]]},"1849":{"position":[[42,6]]},"2277":{"position":[[7,6]]},"2982":{"position":[[42,6]]},"4282":{"position":[[22,7]]}}}],["scrub",{"_index":636,"t":{"1577":{"position":[[21,10]]},"1616":{"position":[[12,10]]},"1620":{"position":[[35,5]]},"1920":{"position":[[21,10]]},"1947":{"position":[[12,10]]},"1951":{"position":[[35,5]]}}}],["search",{"_index":625,"t":{"1562":{"position":[[5,6]]}}}],["seat",{"_index":958,"t":{"3633":{"position":[[0,5]]}}}],["second",{"_index":509,"t":{"1184":{"position":[[0,6]]},"1251":{"position":[[0,6]]},"1440":{"position":[[0,6]]},"1573":{"position":[[3,7]]},"1916":{"position":[[3,7]]}}}],["secret",{"_index":285,"t":{"527":{"position":[[0,7]]},"2118":{"position":[[7,7]]},"2340":{"position":[[9,7]]},"2346":{"position":[[33,6]]},"2407":{"position":[[9,7]]},"2413":{"position":[[33,6]]},"2838":{"position":[[26,7]]},"2876":{"position":[[0,9]]}}}],["section",{"_index":934,"t":{"3528":{"position":[[0,8]]}}}],["secur",{"_index":648,"t":{"1590":{"position":[[0,6]]},"1592":{"position":[[0,6]]},"1933":{"position":[[0,6]]},"1935":{"position":[[0,6]]},"2286":{"position":[[8,8]]},"2288":{"position":[[14,8]]},"2290":{"position":[[8,8]]},"2292":{"position":[[12,8]]},"2294":{"position":[[11,8]]},"2300":{"position":[[8,8]]},"2302":{"position":[[14,8]]},"2304":{"position":[[8,8]]},"2306":{"position":[[12,8]]},"2308":{"position":[[11,8]]},"2486":{"position":[[6,8]]},"2526":{"position":[[11,8]]},"2528":{"position":[[15,8]]},"2530":{"position":[[12,8]]},"3098":{"position":[[0,8]]},"3131":{"position":[[0,8]]},"3163":{"position":[[0,8]]},"3201":{"position":[[0,8]]},"3245":{"position":[[0,8]]},"3247":{"position":[[0,8]]},"3305":{"position":[[0,8]]},"3334":{"position":[[0,8]]},"3455":{"position":[[33,8]]},"3983":{"position":[[39,8]]},"3987":{"position":[[59,8]]},"3993":{"position":[[10,8]]},"4040":{"position":[[8,8],[32,8],[60,8]]},"4265":{"position":[[21,8]]},"4267":{"position":[[37,8]]},"4318":{"position":[[16,8]]},"4534":{"position":[[0,8]]},"4536":{"position":[[0,8]]},"4538":{"position":[[4,9]]},"4542":{"position":[[4,8]]},"4626":{"position":[[15,6]]}}}],["select",{"_index":908,"t":{"3107":{"position":[[18,9]]},"4561":{"position":[[17,8]]}}}],["self",{"_index":529,"t":{"1247":{"position":[[0,4]]}}}],["separ",{"_index":791,"t":{"2430":{"position":[[104,8]]}}}],["seri",{"_index":844,"t":{"2696":{"position":[[10,6]]}}}],["server",{"_index":90,"t":{"135":{"position":[[34,6]]},"292":{"position":[[4,6]]},"704":{"position":[[7,6]]},"737":{"position":[[7,6]]},"1343":{"position":[[28,6]]},"1727":{"position":[[8,7]]},"1729":{"position":[[9,7]]},"2116":{"position":[[0,6]]},"2251":{"position":[[19,6]]},"2253":{"position":[[14,6]]},"2357":{"position":[[26,7]]},"2424":{"position":[[26,7]]},"2821":{"position":[[4,6]]},"2844":{"position":[[36,7]]}}}],["servic",{"_index":16,"t":{"25":{"position":[[0,7]]},"30":{"position":[[0,7]]},"544":{"position":[[29,7]]},"720":{"position":[[12,8]]},"860":{"position":[[16,7]]},"1076":{"position":[[10,8]]},"1078":{"position":[[34,8]]},"1156":{"position":[[26,8]]},"1158":{"position":[[8,8]]},"1168":{"position":[[4,7]]},"1300":{"position":[[21,7]]},"1302":{"position":[[36,9]]},"1304":{"position":[[10,7]]},"1406":{"position":[[4,7]]},"1469":{"position":[[19,7]]},"1477":{"position":[[27,7]]},"1479":{"position":[[42,7]]},"1504":{"position":[[4,7]]},"1506":{"position":[[9,7]]},"1508":{"position":[[11,7]]},"1526":{"position":[[4,7]]},"1539":{"position":[[7,8]]},"1715":{"position":[[7,7]]},"1719":{"position":[[11,7]]},"1722":{"position":[[11,7]]},"1731":{"position":[[27,7]]},"1733":{"position":[[26,7]]},"1737":{"position":[[11,7]]},"1761":{"position":[[16,7]]},"2036":{"position":[[14,7]]},"2073":{"position":[[17,7]]},"2077":{"position":[[4,7]]},"2202":{"position":[[7,8]]},"2204":{"position":[[8,8]]},"2224":{"position":[[9,8]]},"2354":{"position":[[49,7]]},"2421":{"position":[[49,7]]},"2625":{"position":[[10,7]]},"3063":{"position":[[11,7]]},"3455":{"position":[[50,7]]},"4267":{"position":[[54,7]]}}}],["session",{"_index":50,"t":{"67":{"position":[[43,8]]}}}],["set",{"_index":260,"t":{"431":{"position":[[0,7]]},"505":{"position":[[0,7]]},"925":{"position":[[0,7]]},"1479":{"position":[[8,3]]},"1636":{"position":[[0,3]]},"1816":{"position":[[0,7]]},"1967":{"position":[[0,3]]},"1995":{"position":[[0,3]]},"2215":{"position":[[19,7]]},"2700":{"position":[[0,7]]},"2852":{"position":[[9,8]]},"2949":{"position":[[0,7]]},"4844":{"position":[[4,8]]}}}],["setup",{"_index":407,"t":{"919":{"position":[[0,5]]},"968":{"position":[[5,5]]},"1047":{"position":[[32,5]]},"1803":{"position":[[0,5]]},"1859":{"position":[[5,5]]},"2120":{"position":[[11,5]]},"2284":{"position":[[34,5]]},"2298":{"position":[[34,5]]},"2755":{"position":[[0,5]]},"2850":{"position":[[4,5]]},"2880":{"position":[[0,5]]},"2992":{"position":[[5,5]]}}}],["sever",{"_index":858,"t":{"2769":{"position":[[5,10]]},"2771":{"position":[[7,8]]},"2773":{"position":[[4,8]]},"2809":{"position":[[0,10]]},"4706":{"position":[[0,8]]}}}],["share",{"_index":582,"t":{"1376":{"position":[[21,6]]},"1378":{"position":[[21,6]]}}}],["short",{"_index":1025,"t":{"4274":{"position":[[0,5]]}}}],["shouldn't",{"_index":199,"t":{"308":{"position":[[21,9]]}}}],["show",{"_index":710,"t":{"1991":{"position":[[2,4]]},"2253":{"position":[[0,4]]}}}],["shutdown",{"_index":683,"t":{"1645":{"position":[[0,8]]},"1647":{"position":[[36,8]]}}}],["sig",{"_index":8,"t":{"13":{"position":[[16,3]]},"67":{"position":[[24,6]]}}}],["sign",{"_index":530,"t":{"1247":{"position":[[5,6]]}}}],["singl",{"_index":637,"t":{"1579":{"position":[[9,6]]},"1597":{"position":[[29,6]]},"1604":{"position":[[9,6]]},"1922":{"position":[[9,6]]},"2097":{"position":[[13,6]]},"3570":{"position":[[0,6]]},"3871":{"position":[[21,6]]}}}],["size",{"_index":967,"t":{"3664":{"position":[[16,5]]},"3701":{"position":[[16,5]]},"3788":{"position":[[16,5]]}}}],["skylin",{"_index":563,"t":{"1337":{"position":[[0,7]]},"1339":{"position":[[0,7]]}}}],["small",{"_index":467,"t":{"1047":{"position":[[42,5]]}}}],["smart",{"_index":643,"t":{"1584":{"position":[[0,5]]},"1927":{"position":[[0,5]]}}}],["snack",{"_index":156,"t":{"229":{"position":[[0,6]]},"232":{"position":[[0,5]]},"234":{"position":[[6,5]]}}}],["soc",{"_index":815,"t":{"2513":{"position":[[0,3]]},"2515":{"position":[[7,3]]},"2517":{"position":[[10,4]]}}}],["softwar",{"_index":751,"t":{"2181":{"position":[[0,8]]},"3455":{"position":[[58,9]]},"4258":{"position":[[34,8]]},"4265":{"position":[[41,8]]},"4267":{"position":[[62,8]]}}}],["solut",{"_index":835,"t":{"2613":{"position":[[27,8]]},"2635":{"position":[[17,8]]},"2656":{"position":[[27,8]]},"4227":{"position":[[0,8]]},"4233":{"position":[[17,9]]}}}],["sonic",{"_index":477,"t":{"1090":{"position":[[27,5]]},"3959":{"position":[[0,5]]},"3961":{"position":[[27,5]]},"3963":{"position":[[8,5]]},"3970":{"position":[[9,5]]}}}],["sonobuoy",{"_index":1026,"t":{"4274":{"position":[[6,8]]},"4278":{"position":[[60,8]]},"4284":{"position":[[26,8]]}}}],["sourc",{"_index":272,"t":{"472":{"position":[[18,6]]},"2494":{"position":[[0,6]]},"2544":{"position":[[0,6]]},"3760":{"position":[[0,7]]}}}],["sovereign",{"_index":137,"t":{"196":{"position":[[0,9]]},"3522":{"position":[[0,9]]},"4828":{"position":[[41,9]]}}}],["space",{"_index":713,"t":{"2004":{"position":[[5,5]]}}}],["spec",{"_index":1060,"t":{"4622":{"position":[[22,4]]}}}],["special",{"_index":46,"t":{"67":{"position":[[0,7]]},"1380":{"position":[[21,7]]}}}],["specif",{"_index":328,"t":{"613":{"position":[[20,8]]},"617":{"position":[[9,8]]},"1145":{"position":[[13,8]]},"1416":{"position":[[15,8]]},"1418":{"position":[[15,8]]},"1595":{"position":[[9,8]]},"2694":{"position":[[10,8]]},"2735":{"position":[[25,8]]},"3351":{"position":[[0,8]]},"3871":{"position":[[6,14]]},"3873":{"position":[[6,14]]}}}],["specifi",{"_index":579,"t":{"1372":{"position":[[0,7]]}}}],["spine",{"_index":486,"t":{"1119":{"position":[[0,5]]}}}],["sprint",{"_index":42,"t":{"65":{"position":[[0,6]]}}}],["squid",{"_index":566,"t":{"1343":{"position":[[16,5]]}}}],["ssd",{"_index":584,"t":{"1384":{"position":[[6,3]]}}}],["ssh",{"_index":691,"t":{"1674":{"position":[[0,3]]},"1744":{"position":[[0,3]]},"2149":{"position":[[0,3]]}}}],["sshd",{"_index":442,"t":{"968":{"position":[[0,4]]},"1859":{"position":[[0,4]]},"2992":{"position":[[0,4]]}}}],["ssl",{"_index":599,"t":{"1426":{"position":[[31,3]]}}}],["sso",{"_index":220,"t":{"328":{"position":[[4,3]]}}}],["stabil",{"_index":936,"t":{"3536":{"position":[[0,10]]},"3543":{"position":[[0,13]]}}}],["stabl",{"_index":332,"t":{"631":{"position":[[0,6]]},"646":{"position":[[0,6]]},"678":{"position":[[0,6]]},"1256":{"position":[[0,6]]},"2058":{"position":[[0,6]]},"3536":{"position":[[17,8]]}}}],["stack",{"_index":138,"t":{"196":{"position":[[16,5]]},"388":{"position":[[22,6]]},"390":{"position":[[14,5]]},"396":{"position":[[39,6]]},"400":{"position":[[8,6]]},"402":{"position":[[8,5]]},"404":{"position":[[8,5]]},"406":{"position":[[22,6]]},"408":{"position":[[19,5]]},"410":{"position":[[23,5]]},"412":{"position":[[23,5]]},"420":{"position":[[8,6]]},"422":{"position":[[12,7]]},"424":{"position":[[16,6]]},"426":{"position":[[20,6]]},"429":{"position":[[16,5]]},"445":{"position":[[8,5]]},"447":{"position":[[26,5]]},"449":{"position":[[31,5]]},"451":{"position":[[8,5]]},"453":{"position":[[8,5]]},"474":{"position":[[16,5]]},"532":{"position":[[8,6]]},"536":{"position":[[20,5]]},"569":{"position":[[22,5]]},"585":{"position":[[15,5]]},"599":{"position":[[42,6]]},"601":{"position":[[43,6]]},"603":{"position":[[66,5]]},"605":{"position":[[41,5]]},"607":{"position":[[43,6]]},"654":{"position":[[17,6]]},"672":{"position":[[17,6]]},"1059":{"position":[[29,6]]},"2581":{"position":[[8,6]]},"2744":{"position":[[14,5]]},"3186":{"position":[[17,6]]},"4828":{"position":[[57,5]]}}}],["staff",{"_index":813,"t":{"2507":{"position":[[15,6]]}}}],["stand",{"_index":362,"t":{"771":{"position":[[14,5]]}}}],["standard",{"_index":139,"t":{"198":{"position":[[4,9]]},"281":{"position":[[21,9]]},"290":{"position":[[13,9]]},"292":{"position":[[24,8]]},"350":{"position":[[0,10]]},"777":{"position":[[26,12]]},"779":{"position":[[25,10]]},"868":{"position":[[10,8]]},"1769":{"position":[[10,8]]},"3070":{"position":[[0,15]]},"3102":{"position":[[0,9]]},"3135":{"position":[[0,9]]},"3167":{"position":[[0,9]]},"3205":{"position":[[0,9]]},"3258":{"position":[[0,9]]},"3307":{"position":[[0,9]]},"3336":{"position":[[0,9]]},"3455":{"position":[[16,8]]},"3522":{"position":[[16,8]]},"3585":{"position":[[26,9]]},"3676":{"position":[[0,8]]},"3721":{"position":[[9,8]]},"3790":{"position":[[0,8]]},"3814":{"position":[[9,8]]},"3869":{"position":[[0,8]]},"3895":{"position":[[0,8]]},"3909":{"position":[[9,8]]},"3983":{"position":[[26,8]]},"4014":{"position":[[0,12]]},"4048":{"position":[[0,8]]},"4082":{"position":[[12,8]]},"4125":{"position":[[0,8]]},"4160":{"position":[[31,8]]},"4166":{"position":[[0,8]]},"4258":{"position":[[0,8]]},"4267":{"position":[[71,8]]},"4314":{"position":[[10,8]]},"4316":{"position":[[0,8]]},"4379":{"position":[[9,8]]},"4421":{"position":[[0,8]]},"4460":{"position":[[9,8]]},"4546":{"position":[[0,8]]},"4819":{"position":[[0,8]]}}}],["start",{"_index":19,"t":{"35":{"position":[[8,7]]},"43":{"position":[[8,7]]},"48":{"position":[[8,7]]},"108":{"position":[[8,7]]},"135":{"position":[[9,8]]},"357":{"position":[[11,6]]},"797":{"position":[[38,6]]},"799":{"position":[[41,8]]},"801":{"position":[[71,6]]},"864":{"position":[[8,7]]},"1156":{"position":[[0,5]]},"1616":{"position":[[0,5]]},"1765":{"position":[[8,7]]},"1947":{"position":[[0,5]]},"2601":{"position":[[6,5]]},"2691":{"position":[[8,7]]}}}],["startup",{"_index":422,"t":{"941":{"position":[[11,7]]},"1832":{"position":[[11,7]]},"2965":{"position":[[11,7]]}}}],["state",{"_index":617,"t":{"1533":{"position":[[12,6]]},"1991":{"position":[[7,6]]},"2151":{"position":[[7,5]]},"2381":{"position":[[8,5]]},"3970":{"position":[[0,5]]}}}],["static",{"_index":752,"t":{"2191":{"position":[[0,6]]}}}],["statu",{"_index":666,"t":{"1614":{"position":[[21,6]]},"1628":{"position":[[15,6]]},"1945":{"position":[[21,6]]},"1959":{"position":[[15,6]]},"2673":{"position":[[7,6]]},"2675":{"position":[[11,6]]},"2862":{"position":[[21,6]]},"2917":{"position":[[8,6]]},"2921":{"position":[[8,6]]},"3293":{"position":[[0,6]]},"4659":{"position":[[0,6]]}}}],["stay",{"_index":996,"t":{"3991":{"position":[[10,4]]}}}],["step",{"_index":51,"t":{"89":{"position":[[0,4]]},"92":{"position":[[0,4]]},"94":{"position":[[0,4]]},"129":{"position":[[0,4]]},"131":{"position":[[0,4]]},"133":{"position":[[0,4]]},"135":{"position":[[0,4]]},"387":{"position":[[0,5]]},"406":{"position":[[0,5]]},"439":{"position":[[0,4]]},"441":{"position":[[0,4]]},"1219":{"position":[[0,4]]},"1221":{"position":[[0,4]]},"1223":{"position":[[0,4]]},"1225":{"position":[[0,4]]},"1471":{"position":[[0,4]]},"1473":{"position":[[0,4]]},"1475":{"position":[[0,4]]},"1477":{"position":[[0,4]]},"1479":{"position":[[0,4]]},"2878":{"position":[[18,5]]},"3557":{"position":[[18,5]]},"3914":{"position":[[0,4],[8,4]]}}}],["still",{"_index":371,"t":{"783":{"position":[[51,5]]}}}],["stop",{"_index":699,"t":{"1729":{"position":[[0,4]]}}}],["storag",{"_index":24,"t":{"38":{"position":[[7,7]]},"862":{"position":[[7,7]]},"1031":{"position":[[0,7]]},"1099":{"position":[[0,7]]},"1108":{"position":[[0,7]]},"1284":{"position":[[5,7]]},"1384":{"position":[[10,7]]},"1412":{"position":[[0,7]]},"1582":{"position":[[18,7]]},"1638":{"position":[[33,7]]},"1763":{"position":[[7,7]]},"1925":{"position":[[18,7]]},"1969":{"position":[[33,7]]},"2020":{"position":[[0,8]]},"2265":{"position":[[17,7]]},"2326":{"position":[[10,7]]},"2393":{"position":[[10,7]]},"4307":{"position":[[0,7]]},"4332":{"position":[[0,7]]},"4882":{"position":[[0,7]]}}}],["stori",{"_index":317,"t":{"598":{"position":[[5,7]]},"599":{"position":[[5,5]]},"601":{"position":[[5,5]]},"603":{"position":[[5,5]]},"605":{"position":[[5,5]]},"607":{"position":[[5,5]]}}}],["strong",{"_index":119,"t":{"176":{"position":[[18,6]]}}}],["structur",{"_index":63,"t":{"101":{"position":[[0,9]]},"548":{"position":[[14,9]]},"793":{"position":[[22,11]]},"2564":{"position":[[8,9]]},"3568":{"position":[[0,9]]}}}],["style",{"_index":945,"t":{"3574":{"position":[[8,5],[27,5]]}}}],["subject",{"_index":929,"t":{"3379":{"position":[[22,7]]}}}],["subscript",{"_index":981,"t":{"3834":{"position":[[24,12]]}}}],["suffix",{"_index":966,"t":{"3660":{"position":[[15,8]]},"3697":{"position":[[15,8]]},"3784":{"position":[[15,8]]}}}],["suggest",{"_index":941,"t":{"3557":{"position":[[0,9]]}}}],["supplement",{"_index":933,"t":{"3403":{"position":[[0,11]]},"3407":{"position":[[0,11]]},"3411":{"position":[[0,11]]},"3415":{"position":[[0,11]]},"3433":{"position":[[0,11]]},"3439":{"position":[[0,11]]},"3447":{"position":[[0,11]]},"3455":{"position":[[0,11]]},"3463":{"position":[[0,11]]},"3475":{"position":[[0,11]]},"3479":{"position":[[0,11]]},"3487":{"position":[[0,11]]},"3497":{"position":[[0,11]]}}}],["support",{"_index":758,"t":{"2222":{"position":[[0,9]]},"3057":{"position":[[5,7]]},"3713":{"position":[[15,7]]},"3806":{"position":[[15,7]]},"3834":{"position":[[39,7]]},"4203":{"position":[[0,9]]}}}],["survey",{"_index":1071,"t":{"4732":{"position":[[19,6]]}}}],["swappi",{"_index":500,"t":{"1166":{"position":[[0,10]]}}}],["swift",{"_index":392,"t":{"849":{"position":[[0,5]]}}}],["switch",{"_index":484,"t":{"1114":{"position":[[0,8]]},"1115":{"position":[[11,8]]},"1117":{"position":[[5,8]]},"1119":{"position":[[6,8]]}}}],["sync",{"_index":696,"t":{"1717":{"position":[[0,4]]}}}],["synchronis",{"_index":521,"t":{"1233":{"position":[[0,13]]}}}],["system",{"_index":721,"t":{"2018":{"position":[[0,7]]}}}],["systemat",{"_index":970,"t":{"3694":{"position":[[22,10]]},"3781":{"position":[[22,10]]},"4012":{"position":[[0,10]]}}}],["tabl",{"_index":926,"t":{"3356":{"position":[[9,5]]},"3743":{"position":[[4,5]]}}}],["tag",{"_index":265,"t":{"439":{"position":[[26,3]]},"1291":{"position":[[6,4]]},"3023":{"position":[[8,7]]},"3074":{"position":[[8,7]]},"3104":{"position":[[8,7]]},"3137":{"position":[[8,7]]},"3169":{"position":[[8,7]]},"3207":{"position":[[8,7]]},"3260":{"position":[[8,7]]},"3309":{"position":[[8,7]]},"3337":{"position":[[8,7]]}}}],["target",{"_index":239,"t":{"371":{"position":[[0,6]]}}}],["task",{"_index":94,"t":{"146":{"position":[[0,4]]},"1594":{"position":[[16,5]]},"1937":{"position":[[16,5]]},"2083":{"position":[[0,4]]},"3345":{"position":[[0,5]]}}}],["taxonomi",{"_index":943,"t":{"3566":{"position":[[16,8]]}}}],["tech",{"_index":921,"t":{"3287":{"position":[[0,4]]},"3289":{"position":[[0,4]]},"3291":{"position":[[0,4]]}}}],["technic",{"_index":55,"t":{"91":{"position":[[3,9]]},"803":{"position":[[9,9]]},"2160":{"position":[[14,10]]},"2208":{"position":[[14,10]]},"3021":{"position":[[0,9]]},"3572":{"position":[[0,9]]},"3825":{"position":[[0,9]]},"3985":{"position":[[0,9]]}}}],["technolog",{"_index":977,"t":{"3756":{"position":[[23,10]]},"4225":{"position":[[15,12]]}}}],["telegraf",{"_index":430,"t":{"954":{"position":[[0,8]]},"1845":{"position":[[0,8]]},"2978":{"position":[[0,8]]}}}],["teleport",{"_index":482,"t":{"1094":{"position":[[24,8]]}}}],["templat",{"_index":325,"t":{"610":{"position":[[13,10]]},"917":{"position":[[6,9]]},"1801":{"position":[[6,9]]},"3568":{"position":[[10,8]]}}}],["temporarili",{"_index":657,"t":{"1606":{"position":[[14,12]]}}}],["tenant",{"_index":308,"t":{"581":{"position":[[25,6],[41,7]]},"585":{"position":[[41,7]]}}}],["term",{"_index":957,"t":{"3631":{"position":[[0,4]]}}}],["terminolog",{"_index":983,"t":{"3889":{"position":[[0,11]]},"3979":{"position":[[0,11]]},"4038":{"position":[[0,11]]},"4074":{"position":[[0,11]]},"4117":{"position":[[0,11]]},"4154":{"position":[[0,11]]},"4186":{"position":[[0,11]]},"4216":{"position":[[0,11]]},"4250":{"position":[[0,11]]},"4295":{"position":[[0,11]]},"4411":{"position":[[0,11]]},"4526":{"position":[[0,11]]},"4555":{"position":[[0,11]]},"4573":{"position":[[0,11]]},"4605":{"position":[[0,11]]},"4779":{"position":[[0,11]]},"4809":{"position":[[0,11]]}}}],["test",{"_index":183,"t":{"285":{"position":[[26,4]]},"287":{"position":[[18,4]]},"294":{"position":[[13,4]]},"300":{"position":[[23,5]]},"304":{"position":[[27,5]]},"306":{"position":[[7,4]]},"308":{"position":[[15,5]]},"607":{"position":[[24,7]]},"1662":{"position":[[62,7]]},"1993":{"position":[[14,7]]},"1997":{"position":[[4,5]]},"2693":{"position":[[10,4]]},"2694":{"position":[[19,4]]},"2696":{"position":[[20,5]]},"2713":{"position":[[5,8]]},"2731":{"position":[[8,5]]},"2733":{"position":[[12,5]]},"2801":{"position":[[8,5]]},"3379":{"position":[[17,4]]},"3403":{"position":[[31,7]]},"3407":{"position":[[31,7]]},"3411":{"position":[[31,7]]},"3439":{"position":[[31,7]]},"3447":{"position":[[31,7]]},"3455":{"position":[[87,7]]},"3475":{"position":[[31,7]]},"3479":{"position":[[31,7]]},"3487":{"position":[[31,7]]},"3603":{"position":[[0,4]]},"3745":{"position":[[10,5]]},"3752":{"position":[[7,5]]},"3836":{"position":[[12,5]]},"3841":{"position":[[10,5]]},"3846":{"position":[[7,5]]},"3851":{"position":[[10,5]]},"3860":{"position":[[7,5]]},"3882":{"position":[[12,5]]},"3905":{"position":[[12,5]]},"3937":{"position":[[12,5]]},"4033":{"position":[[12,5]]},"4054":{"position":[[12,5]]},"4063":{"position":[[10,5]]},"4067":{"position":[[7,5]]},"4088":{"position":[[12,5]]},"4129":{"position":[[12,5]]},"4170":{"position":[[12,5]]},"4175":{"position":[[10,5]]},"4209":{"position":[[12,5]]},"4260":{"position":[[12,5]]},"4265":{"position":[[0,7]]},"4280":{"position":[[63,4]]},"4282":{"position":[[34,5]]},"4336":{"position":[[12,5]]},"4347":{"position":[[12,5]]},"4358":{"position":[[12,5]]},"4363":{"position":[[10,5]]},"4366":{"position":[[7,5]]},"4381":{"position":[[12,5]]},"4386":{"position":[[10,5]]},"4391":{"position":[[7,5]]},"4406":{"position":[[12,5]]},"4465":{"position":[[10,5]]},"4467":{"position":[[7,5]]},"4498":{"position":[[12,5]]},"4548":{"position":[[12,5]]},"4583":{"position":[[12,5]]},"4600":{"position":[[12,5]]},"4601":{"position":[[12,6]]},"4628":{"position":[[12,5]]},"4650":{"position":[[12,5]]},"4751":{"position":[[12,5]]},"4770":{"position":[[12,5]]},"4804":{"position":[[12,5]]},"4823":{"position":[[12,5]]}}}],["testabl",{"_index":196,"t":{"304":{"position":[[6,8]]}}}],["testb",{"_index":755,"t":{"2210":{"position":[[6,7]]},"3059":{"position":[[21,9]]},"3087":{"position":[[35,9]]},"3120":{"position":[[35,8]]},"3154":{"position":[[35,8]]},"3190":{"position":[[52,7]]},"3231":{"position":[[35,8]]},"3286":{"position":[[35,8]]},"3330":{"position":[[35,8]]}}}],["thank",{"_index":910,"t":{"3143":{"position":[[0,6]]},"3175":{"position":[[0,6]]},"3213":{"position":[[0,6]]},"3271":{"position":[[0,6]]},"3322":{"position":[[0,6]]},"3341":{"position":[[0,6]]}}}],["theme",{"_index":557,"t":{"1315":{"position":[[7,6]]}}}],["thing",{"_index":148,"t":{"211":{"position":[[9,6]]},"213":{"position":[[13,6]]},"979":{"position":[[9,6]]},"1870":{"position":[[9,6]]},"3003":{"position":[[9,6]]}}}],["threat",{"_index":1014,"t":{"4221":{"position":[[10,7]]},"4235":{"position":[[8,6]]}}}],["throttl",{"_index":615,"t":{"1508":{"position":[[0,10]]}}}],["tilt",{"_index":261,"t":{"431":{"position":[[8,4]]},"433":{"position":[[16,4]]},"505":{"position":[[8,4]]},"507":{"position":[[16,4]]}}}],["timelin",{"_index":952,"t":{"3605":{"position":[[0,8]]}}}],["tl",{"_index":527,"t":{"1243":{"position":[[0,3]]},"1249":{"position":[[11,3]]},"1306":{"position":[[9,3]]},"3059":{"position":[[4,3]]},"4305":{"position":[[0,3]]},"4318":{"position":[[25,5]]}}}],["togeth",{"_index":252,"t":{"396":{"position":[[51,9]]}}}],["toggl",{"_index":276,"t":{"490":{"position":[[17,9]]},"513":{"position":[[0,6]]}}}],["token",{"_index":211,"t":{"322":{"position":[[24,5]]},"2907":{"position":[[9,5]]}}}],["tool",{"_index":259,"t":{"426":{"position":[[38,5]]},"627":{"position":[[16,4]]},"2492":{"position":[[0,5]]},"2542":{"position":[[0,5]]},"2579":{"position":[[11,7]]},"3614":{"position":[[0,7]]},"3741":{"position":[[12,7]]},"3796":{"position":[[12,7]]},"3884":{"position":[[12,7]]},"3907":{"position":[[12,7]]},"3919":{"position":[[12,7]]},"3961":{"position":[[15,7]]},"4867":{"position":[[13,5]]}}}],["topic",{"_index":681,"t":{"1642":{"position":[[9,6]]},"1973":{"position":[[9,6]]}}}],["topolog",{"_index":576,"t":{"1370":{"position":[[9,8]]}}}],["transport",{"_index":1036,"t":{"4318":{"position":[[0,9]]}}}],["tri",{"_index":258,"t":{"424":{"position":[[27,3]]},"797":{"position":[[10,3]]}}}],["trivi",{"_index":360,"t":{"723":{"position":[[0,5]]},"2534":{"position":[[21,6]]},"2536":{"position":[[29,6]]},"2538":{"position":[[0,5]]},"2589":{"position":[[0,5]]},"2591":{"position":[[0,5]]},"2593":{"position":[[0,5]]}}}],["troubleshoot",{"_index":277,"t":{"492":{"position":[[0,15]]},"974":{"position":[[0,15]]},"1865":{"position":[[0,15]]},"1905":{"position":[[0,15]]},"2049":{"position":[[0,15]]},"2124":{"position":[[0,15]]},"2212":{"position":[[0,15]]},"2741":{"position":[[0,15]]},"2998":{"position":[[0,15]]}}}],["tutori",{"_index":789,"t":{"2430":{"position":[[9,8]]}}}],["two",{"_index":323,"t":{"610":{"position":[[0,3]]},"2430":{"position":[[74,3],[100,3]]}}}],["type",{"_index":54,"t":{"89":{"position":[[23,4]]},"1026":{"position":[[5,4]]},"2028":{"position":[[0,5]]},"2763":{"position":[[12,5]]},"2765":{"position":[[14,4]]},"2767":{"position":[[11,4]]},"2807":{"position":[[7,5]]},"2931":{"position":[[6,5]]},"3524":{"position":[[0,5]]},"3655":{"position":[[0,4]]},"3664":{"position":[[26,5]]},"3692":{"position":[[0,4]]},"3701":{"position":[[26,5]]},"3779":{"position":[[0,4]]},"3788":{"position":[[26,5]]},"4012":{"position":[[33,5]]},"4016":{"position":[[15,4]]},"4018":{"position":[[16,5]]},"4020":{"position":[[19,5]]},"4022":{"position":[[16,5]]}}}],["typic",{"_index":641,"t":{"1582":{"position":[[10,7]]},"1925":{"position":[[10,7]]}}}],["ui",{"_index":34,"t":{"46":{"position":[[15,4]]},"53":{"position":[[15,4]]},"2129":{"position":[[39,3]]},"2615":{"position":[[31,3]]},"2658":{"position":[[31,3]]}}}],["unattend",{"_index":440,"t":{"966":{"position":[[0,10]]},"1857":{"position":[[0,10]]},"2990":{"position":[[0,10]]}}}],["underlay",{"_index":542,"t":{"1274":{"position":[[12,8]]}}}],["understand",{"_index":176,"t":{"281":{"position":[[3,13]]},"2498":{"position":[[0,13]]}}}],["unencrypt",{"_index":781,"t":{"2348":{"position":[[25,11]]},"2415":{"position":[[25,11]]}}}],["uniqu",{"_index":498,"t":{"1162":{"position":[[0,6]]},"1394":{"position":[[0,6]]}}}],["unit",{"_index":192,"t":{"300":{"position":[[3,4]]}}}],["unprivileg",{"_index":415,"t":{"929":{"position":[[0,12]]},"1820":{"position":[[0,12]]},"2953":{"position":[[0,12]]}}}],["unsupport",{"_index":756,"t":{"2215":{"position":[[0,11]]},"4205":{"position":[[0,11]]}}}],["until",{"_index":248,"t":{"394":{"position":[[5,5]]}}}],["up",{"_index":262,"t":{"431":{"position":[[13,2]]},"505":{"position":[[13,2]]},"925":{"position":[[8,2]]},"979":{"position":[[16,2]]},"1733":{"position":[[13,2]]},"1816":{"position":[[8,2]]},"1870":{"position":[[16,2]]},"2700":{"position":[[8,2]]},"2949":{"position":[[8,2]]},"3003":{"position":[[16,2]]}}}],["updat",{"_index":41,"t":{"63":{"position":[[8,7]]},"605":{"position":[[24,8]]},"879":{"position":[[0,8]]},"970":{"position":[[0,8]]},"1780":{"position":[[0,8]]},"1861":{"position":[[0,8]]},"1910":{"position":[[0,8]]},"2787":{"position":[[14,6]]},"2789":{"position":[[16,6]]},"2791":{"position":[[13,6]]},"2815":{"position":[[9,6]]},"2994":{"position":[[0,8]]},"3025":{"position":[[0,7]]},"3828":{"position":[[6,8]]},"4265":{"position":[[30,7]]},"4532":{"position":[[8,7]]},"4716":{"position":[[17,8]]}}}],["upgrad",{"_index":441,"t":{"966":{"position":[[11,8]]},"1150":{"position":[[0,7]]},"1857":{"position":[[11,8]]},"1911":{"position":[[5,8]]},"1913":{"position":[[5,8]]},"2044":{"position":[[0,7]]},"2204":{"position":[[0,7]]},"2990":{"position":[[11,8]]}}}],["upgrade/migr",{"_index":903,"t":{"3089":{"position":[[0,17]]},"3122":{"position":[[0,17]]},"3156":{"position":[[0,17]]},"3194":{"position":[[0,17]]},"3239":{"position":[[0,17]]},"3299":{"position":[[0,17]]},"3331":{"position":[[0,17]]}}}],["upload",{"_index":516,"t":{"1223":{"position":[[8,6]]},"1311":{"position":[[9,9]]},"2262":{"position":[[0,6]]},"2269":{"position":[[38,8]]},"3867":{"position":[[0,9]]},"4288":{"position":[[21,6]]}}}],["upstream",{"_index":1021,"t":{"4241":{"position":[[0,8]]},"4622":{"position":[[0,8]]}}}],["url",{"_index":31,"t":{"44":{"position":[[0,4]]},"51":{"position":[[0,4]]}}}],["us",{"_index":99,"t":{"150":{"position":[[16,3]]},"270":{"position":[[19,3]]},"290":{"position":[[32,5]]},"294":{"position":[[25,5]]},"335":{"position":[[0,3]]},"392":{"position":[[0,3]]},"406":{"position":[[38,3]]},"414":{"position":[[0,5]]},"486":{"position":[[0,5]]},"490":{"position":[[0,5]]},"605":{"position":[[55,4]]},"693":{"position":[[24,5]]},"783":{"position":[[57,3]]},"787":{"position":[[13,3]]},"789":{"position":[[13,3]]},"799":{"position":[[10,3]]},"801":{"position":[[10,3]]},"1019":{"position":[[0,3]]},"1037":{"position":[[0,3]]},"1190":{"position":[[0,3]]},"1227":{"position":[[0,5]]},"1296":{"position":[[16,3]]},"1372":{"position":[[24,4]]},"1404":{"position":[[18,5]]},"1420":{"position":[[18,5]]},"1463":{"position":[[23,5]]},"1588":{"position":[[47,5]]},"1590":{"position":[[26,5]]},"1592":{"position":[[30,5]]},"1643":{"position":[[16,5]]},"1660":{"position":[[0,3]]},"1931":{"position":[[47,5]]},"1933":{"position":[[26,5]]},"1935":{"position":[[30,5]]},"1980":{"position":[[9,5]]},"2047":{"position":[[0,3]]},"2127":{"position":[[19,5]]},"2210":{"position":[[0,5]]},"2265":{"position":[[0,5]]},"2267":{"position":[[0,5]]},"2294":{"position":[[7,3]]},"2308":{"position":[[7,3]]},"2324":{"position":[[13,5]]},"2326":{"position":[[25,5]]},"2328":{"position":[[19,5]]},"2334":{"position":[[19,5]]},"2338":{"position":[[37,4]]},"2340":{"position":[[24,5]]},"2391":{"position":[[13,5]]},"2393":{"position":[[25,5]]},"2395":{"position":[[19,5]]},"2401":{"position":[[19,5]]},"2405":{"position":[[37,4]]},"2407":{"position":[[24,5]]},"2641":{"position":[[18,3]]},"2643":{"position":[[6,3]]},"2669":{"position":[[18,3]]},"2671":{"position":[[6,3]]},"2693":{"position":[[0,5]]},"2704":{"position":[[0,3]]},"2708":{"position":[[0,6]]},"2909":{"position":[[0,3]]},"3758":{"position":[[11,4]]},"4239":{"position":[[31,3]]}}}],["usag",{"_index":14,"t":{"21":{"position":[[0,5]]},"120":{"position":[[6,5]]},"154":{"position":[[0,5]]},"156":{"position":[[0,5]]},"160":{"position":[[0,5]]},"254":{"position":[[0,5]]},"534":{"position":[[3,5]]},"876":{"position":[[0,5]]},"886":{"position":[[0,5]]},"893":{"position":[[0,5]]},"909":{"position":[[0,5]]},"1004":{"position":[[0,5]]},"1751":{"position":[[0,5]]},"1777":{"position":[[0,5]]},"1793":{"position":[[0,5]]},"1810":{"position":[[0,5]]},"1895":{"position":[[0,5]]},"2035":{"position":[[0,5]]},"2064":{"position":[[0,5]]},"2185":{"position":[[0,5]]},"2197":{"position":[[9,5]]},"2664":{"position":[[0,5]]},"2724":{"position":[[0,5]]},"3989":{"position":[[19,5]]}}}],["user",{"_index":15,"t":{"23":{"position":[[0,5]]},"25":{"position":[[8,5]]},"30":{"position":[[8,5]]},"324":{"position":[[33,5]]},"326":{"position":[[47,5]]},"598":{"position":[[0,4]]},"599":{"position":[[0,4]]},"601":{"position":[[0,4]]},"603":{"position":[[0,4]]},"605":{"position":[[0,4]]},"607":{"position":[[0,4]]},"1471":{"position":[[24,4]]},"1560":{"position":[[18,4]]},"2322":{"position":[[23,4]]},"2389":{"position":[[23,4]]},"2452":{"position":[[26,4]]},"2454":{"position":[[49,4]]},"2460":{"position":[[9,5]]},"2504":{"position":[[43,5]]},"2509":{"position":[[4,5]]},"3082":{"position":[[23,4]]},"3115":{"position":[[23,4]]},"3149":{"position":[[23,4]]},"3181":{"position":[[23,4]]},"3219":{"position":[[23,4]]},"3277":{"position":[[23,4]]},"3327":{"position":[[23,4]]},"4828":{"position":[[15,4]]}}}],["user/custom",{"_index":312,"t":{"587":{"position":[[42,14]]}}}],["util",{"_index":1018,"t":{"4233":{"position":[[0,7]]}}}],["valid",{"_index":462,"t":{"1037":{"position":[[14,10]]},"1643":{"position":[[0,10]]},"3682":{"position":[[0,10]]},"3794":{"position":[[0,10]]}}}],["valu",{"_index":132,"t":{"188":{"position":[[0,6]]},"1442":{"position":[[5,5]]}}}],["var",{"_index":514,"t":{"1211":{"position":[[5,4]]},"1212":{"position":[[6,4]]}}}],["variabl",{"_index":292,"t":{"556":{"position":[[10,9]]},"577":{"position":[[13,9]]},"625":{"position":[[12,9]]},"1213":{"position":[[7,8]]},"1680":{"position":[[5,9]]}}}],["vault",{"_index":610,"t":{"1479":{"position":[[12,5]]}}}],["vegan",{"_index":159,"t":{"234":{"position":[[0,5]]}}}],["velero",{"_index":347,"t":{"702":{"position":[[0,6]]},"704":{"position":[[0,6]]},"735":{"position":[[0,6]]},"737":{"position":[[0,6]]}}}],["verifi",{"_index":1035,"t":{"4314":{"position":[[0,9]]}}}],["version",{"_index":290,"t":{"550":{"position":[[3,10]]},"601":{"position":[[24,10]]},"2200":{"position":[[7,8]]},"3082":{"position":[[10,8]]},"3115":{"position":[[10,8]]},"3149":{"position":[[10,8]]},"3181":{"position":[[10,8]]},"3219":{"position":[[10,8]]},"3277":{"position":[[10,8]]},"3327":{"position":[[10,8]]},"3548":{"position":[[0,10]]},"3597":{"position":[[0,7]]},"3721":{"position":[[18,8]]},"3814":{"position":[[18,8]]},"3909":{"position":[[18,8]]},"4258":{"position":[[43,7]]},"4379":{"position":[[18,8]]},"4460":{"position":[[18,8]]}}}],["via",{"_index":84,"t":{"129":{"position":[[28,3]]},"931":{"position":[[10,3]]},"1545":{"position":[[27,3]]},"1822":{"position":[[10,3]]},"2160":{"position":[[5,3]]},"2208":{"position":[[5,3]]},"2611":{"position":[[31,3]]},"2955":{"position":[[10,3]]},"3057":{"position":[[13,3]]},"3161":{"position":[[13,3]]},"3199":{"position":[[13,3]]}}}],["view",{"_index":811,"t":{"2505":{"position":[[26,6]]}}}],["virtual",{"_index":478,"t":{"1091":{"position":[[32,7]]},"1703":{"position":[[5,7]]},"2002":{"position":[[7,14]]},"3668":{"position":[[20,14],[44,14]]},"3709":{"position":[[20,14],[44,14]]},"3762":{"position":[[11,7]]},"3802":{"position":[[20,14],[44,14]]},"4515":{"position":[[15,7]]},"4517":{"position":[[0,7]]}}}],["virtualbox",{"_index":720,"t":{"2014":{"position":[[0,10]]}}}],["virtualis",{"_index":569,"t":{"1357":{"position":[[7,14]]}}}],["visibl",{"_index":899,"t":{"3082":{"position":[[28,7]]},"3115":{"position":[[28,7]]},"3149":{"position":[[28,7]]},"3181":{"position":[[28,7]]},"3219":{"position":[[28,7]]},"3277":{"position":[[28,7]]},"3327":{"position":[[28,7]]}}}],["vm",{"_index":411,"t":{"925":{"position":[[22,2]]},"931":{"position":[[7,2]]},"933":{"position":[[40,2]]},"1816":{"position":[[22,2]]},"1822":{"position":[[7,2]]},"1824":{"position":[[40,2]]},"2949":{"position":[[22,2]]},"2955":{"position":[[7,2]]},"2957":{"position":[[40,2]]},"4328":{"position":[[9,2]]}}}],["vmdk",{"_index":762,"t":{"2243":{"position":[[12,4]]},"2245":{"position":[[15,4]]}}}],["vmware",{"_index":717,"t":{"2008":{"position":[[0,6]]}}}],["vnc",{"_index":766,"t":{"2255":{"position":[[18,3]]}}}],["volum",{"_index":747,"t":{"2145":{"position":[[7,6]]},"2267":{"position":[[16,6]]},"2328":{"position":[[0,6]]},"2330":{"position":[[19,7]]},"2332":{"position":[[19,7]]},"2334":{"position":[[0,6]]},"2336":{"position":[[33,7]]},"2338":{"position":[[42,7]]},"2352":{"position":[[12,6]]},"2354":{"position":[[12,6]]},"2357":{"position":[[48,7]]},"2359":{"position":[[42,6]]},"2395":{"position":[[0,6]]},"2397":{"position":[[19,7]]},"2399":{"position":[[19,7]]},"2401":{"position":[[0,6]]},"2403":{"position":[[33,7]]},"2405":{"position":[[42,7]]},"2419":{"position":[[12,6]]},"2421":{"position":[[12,6]]},"2424":{"position":[[48,7]]},"2426":{"position":[[42,6]]},"4012":{"position":[[26,6]]},"4016":{"position":[[8,6]]},"4018":{"position":[[9,6]]},"4020":{"position":[[12,6]]},"4022":{"position":[[9,6]]},"4164":{"position":[[16,7]]}}}],["vote",{"_index":961,"t":{"3637":{"position":[[13,6]]},"3641":{"position":[[0,6]]}}}],["vpn",{"_index":723,"t":{"2036":{"position":[[10,3]]},"2189":{"position":[[0,3]]}}}],["vs",{"_index":120,"t":{"176":{"position":[[25,3]]},"613":{"position":[[8,2]]},"927":{"position":[[9,2]]},"1818":{"position":[[9,2]]},"2951":{"position":[[9,2]]},"4716":{"position":[[6,2]]}}}],["vsphere/esxi",{"_index":718,"t":{"2008":{"position":[[7,12]]}}}],["vswitch",{"_index":480,"t":{"1092":{"position":[[32,7]]},"1701":{"position":[[5,7]]}}}],["vulnerabilit",{"_index":1023,"t":{"4269":{"position":[[19,14]]}}}],["wait",{"_index":247,"t":{"394":{"position":[[0,4]]},"687":{"position":[[12,4]]}}}],["walkthrough",{"_index":987,"t":{"3914":{"position":[[13,11]]}}}],["want",{"_index":374,"t":{"797":{"position":[[2,4]]},"799":{"position":[[2,4]]},"801":{"position":[[2,4]]},"2840":{"position":[[2,4]]},"2842":{"position":[[2,4]]},"2844":{"position":[[2,4]]}}}],["warn",{"_index":633,"t":{"1575":{"position":[[21,7]]},"1918":{"position":[[21,7]]},"2438":{"position":[[0,7]]},"3748":{"position":[[0,8]]},"3856":{"position":[[0,8]]}}}],["wavecon",{"_index":17,"t":{"29":{"position":[[0,7]]}}}],["weak",{"_index":121,"t":{"176":{"position":[[29,4]]}}}],["web",{"_index":189,"t":{"292":{"position":[[0,3]]},"721":{"position":[[13,3]]},"2129":{"position":[[35,3]]},"2829":{"position":[[0,3]]},"2844":{"position":[[15,3]]}}}],["webinterfac",{"_index":724,"t":{"2038":{"position":[[0,13]]},"2193":{"position":[[0,13]]}}}],["websso",{"_index":215,"t":{"324":{"position":[[12,6]]}}}],["week",{"_index":160,"t":{"240":{"position":[[12,4]]}}}],["weekli",{"_index":806,"t":{"2500":{"position":[[24,6]]}}}],["welcom",{"_index":0,"t":{"6":{"position":[[0,7]]},"4828":{"position":[[0,7]]}}}],["we’r",{"_index":35,"t":{"58":{"position":[[0,5]]}}}],["wipe",{"_index":687,"t":{"1664":{"position":[[14,6]]}}}],["wireguard",{"_index":722,"t":{"2036":{"position":[[0,9]]}}}],["within",{"_index":612,"t":{"1492":{"position":[[21,6]]},"2460":{"position":[[15,6]]},"2462":{"position":[[18,6]]},"2464":{"position":[[16,6]]},"2466":{"position":[[26,6]]}}}],["without",{"_index":398,"t":{"872":{"position":[[6,7]]},"1490":{"position":[[24,8]]},"1773":{"position":[[6,7]]},"2068":{"position":[[13,7]]},"2517":{"position":[[0,7]]}}}],["word",{"_index":768,"t":{"2257":{"position":[[5,5]]}}}],["work",{"_index":118,"t":{"176":{"position":[[8,5]]},"396":{"position":[[46,4]]},"603":{"position":[[34,4]]},"613":{"position":[[29,4]]},"615":{"position":[[8,4]]},"617":{"position":[[18,4]]},"1237":{"position":[[0,7]]},"1258":{"position":[[0,7]]},"1545":{"position":[[0,7]]},"2077":{"position":[[23,5]]},"2143":{"position":[[21,7]]}}}],["worker",{"_index":547,"t":{"1304":{"position":[[18,7]]}}}],["workflow",{"_index":80,"t":{"122":{"position":[[7,9]]},"4609":{"position":[[8,8]]}}}],["workload",{"_index":243,"t":{"387":{"position":[[18,8]]},"511":{"position":[[9,8]]},"587":{"position":[[11,8]]},"589":{"position":[[10,8]]}}}],["world",{"_index":978,"t":{"3758":{"position":[[5,5]]}}}],["write",{"_index":195,"t":{"304":{"position":[[0,5]]},"2060":{"position":[[7,5]]},"3574":{"position":[[0,7]]},"4282":{"position":[[9,5]]}}}],["wrong",{"_index":742,"t":{"2127":{"position":[[29,5]]}}}],["x",{"_index":28,"t":{"43":{"position":[[29,1]]},"244":{"position":[[24,1]]},"3684":{"position":[[17,1]]}}}],["xy",{"_index":866,"t":{"2840":{"position":[[20,3]]}}}],["yaml",{"_index":949,"t":{"3593":{"position":[[18,4]]},"3869":{"position":[[16,4]]},"3878":{"position":[[0,4]]}}}],["yourself",{"_index":932,"t":{"3382":{"position":[[35,8]]}}}],["zap",{"_index":824,"t":{"2556":{"position":[[0,3]]}}}],["zone",{"_index":377,"t":{"813":{"position":[[29,4]]},"4160":{"position":[[26,4]]}}}],["zuul",{"_index":169,"t":{"268":{"position":[[0,4]]},"270":{"position":[[23,4]]},"272":{"position":[[26,4]]},"359":{"position":[[18,4]]},"2109":{"position":[[31,4]]},"2113":{"position":[[4,4]]},"2479":{"position":[[0,4]]},"3046":{"position":[[0,4]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":1,"t":"Archive","s":"","u":"/blog/archive","p":1},{"i":2,"t":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet","s":"First Blog Post","u":"/blog/first-blog-post","p":2},{"i":5,"t":"Welcome to our SCS Community","s":"Overview","u":"/community/","p":5},{"i":8,"t":"This document gives an overview of what SCS central services are deployed and who is responsible for them in plusserver gx-scs infrastructure.","s":"Central services","u":"/community/central-services/plusserver-gx-scs","p":8},{"i":16,"t":"This document gives an overview of the test and development cloud resources currently provided by our partners.","s":"Test and development cloud resources","u":"/community/cloud-resources/","p":16},{"i":34,"t":"Getting Started with OpenStack CLI","s":"Getting Started with OpenStack","u":"/community/cloud-resources/getting-started-openstack","p":34},{"i":42,"t":"Getting Started for the Gaia-X Demonstrator @ plusserver","s":"Getting Started Gaia-X Demonstrator @ plusserver","u":"/community/cloud-resources/plusserver-gx-scs","p":42},{"i":50,"t":"Getting Started with Wavestack","s":"Getting Started with Wavestack","u":"/community/cloud-resources/wavestack","p":50},{"i":57,"t":"We’re an open community","s":"Collaboration","u":"/community/collaboration/","p":57},{"i":69,"t":"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.","s":"SIG Central API","u":"/community/collaboration/sig-central-api","p":69},{"i":71,"t":"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!","s":"SIG Community","u":"/community/collaboration/sig-community","p":71},{"i":73,"t":"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.","s":"SIG Documentation","u":"/community/collaboration/sig-documentation","p":73},{"i":75,"t":"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.","s":"SIG Monitoring","u":"/community/collaboration/sig-monitoring","p":75},{"i":77,"t":"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.","s":"SIG Standardization","u":"/community/collaboration/sig-standardization","p":77},{"i":79,"t":"The Team Container deals with all topics around Containers and Kubernetes.","s":"Team Container","u":"/community/collaboration/team-container","p":79},{"i":81,"t":"We build the reference implementation of the IaaS parts of SCS that informs and adheres to the SCS IaaS standards.","s":"Team Iaas","u":"/community/collaboration/team-iaas","p":81},{"i":83,"t":"The Team IAM deals with topics around Identity and Access Management.","s":"Team IAM","u":"/community/collaboration/team-iam","p":83},{"i":85,"t":"We build tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.","s":"Team Ops","u":"/community/collaboration/team-ops","p":85},{"i":87,"t":"In this Guide you will learn how to integrate your documentation to the SCS documentation, which you will find on docs.scs.community.","s":"Adding Docs Guide","u":"/community/contribute/adding-docs-guide","p":87},{"i":100,"t":"Structure Best Practice","s":"Documentation Files Structure","u":"/community/contribute/doc-files-structure-guide","p":100},{"i":116,"t":"In order to have a clean content repository regarding all markdown files we enforce linting on:","s":"Linting Guide","u":"/community/contribute/linting-guide","p":116},{"i":124,"t":"This Guide shows you how to setup docusaurus on your local machine to run this docs in your local development enviroment.","s":"Installation","u":"/community/contribute/local-docusaurus-development-guide","p":124},{"i":137,"t":"Admonitions","s":"Styleguide","u":"/community/contribute/styleguide","p":137},{"i":144,"t":"We use nearly all default rules of ansible lint. A listing of all these rules can be found in the Ansible Lint documentation:","s":"Ansible Style Guide","u":"/community/contribute/styleguides/ansible_styleguide","p":144},{"i":164,"t":"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.","s":"Documentation workflow explanation","u":"/community/contribute/docs-workflow-explanation","p":164},{"i":168,"t":"As Sovereign Cloud Stack (SCS), our mission is to provide Operators","s":"License considerations for SCS","u":"/community/license-considerations","p":168},{"i":186,"t":"Sovereign Cloud Stack (SCS) offers more than just a software stack — it's the embodiment of a collaborative open-source spirit, united by the aim of achieving digital sovereignty. At the heart of this initiative is a foundational pillar: the community.","s":"Mission Statement","u":"/community/mission-statement","p":186},{"i":200,"t":"To protect our source code from unwanted changes, we enforce the following branch protection rules for all repositories within our GitHub organization:","s":"Branch Protection Rules","u":"/community/tools/github/branchprotection","p":200},{"i":202,"t":"This checklist is designed to simplify the planning of hackathons and meetups. All items are suggestions and optionally adaptable","s":"Hackathon planning checklist","u":"/community/hackathons/checklist","p":202},{"i":248,"t":"The Developer Certificate of Origin (DCO) is a lightweight way for contributors","s":"Developer Certificate of Origin + Licenses","u":"/community/tools/github/dco-and-licenses","p":248},{"i":252,"t":"We use a self-hosted Jitsi Meet instance for video conferencing.","s":"Jitsi","u":"/community/tools/jitsi","p":252},{"i":256,"t":"Octo Reminder - your friendly assistant","s":"Tips and Tricks","u":"/community/tools/github/tips-and-tricks","p":256},{"i":259,"t":"We have an announcements mailing list there announce@lists.scs.community and you","s":"Mailing Lists","u":"/community/tools/mailinglists","p":259},{"i":261,"t":"We have created an open community space on the Matrix federation. Feel free to join the several channels and start chatting with our community. A good starting point is entering the General & Announcements and the Tech channel.","s":"Matrix","u":"/community/tools/matrix","p":261},{"i":265,"t":"We have a Nextcloud","s":"Nextcloud","u":"/community/tools/nextcloud","p":265},{"i":267,"t":"Zuul CI/CD pipelines and project gating","s":"Zuul","u":"/community/tools/zuul","p":267},{"i":274,"t":"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.","s":"Documentation for SCS Contributors","u":"/contributor-docs/","p":274},{"i":276,"t":"Welcome to the developer section of the contributor docs. Here you will find","s":"Developer documentation","u":"/contributor-docs/development/","p":276},{"i":278,"t":"Introduction","s":"SCS RFC2119 Keyword Test Guide","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","p":278},{"i":296,"t":"SovereignCloudStack (SCS) uses conformance tests to certify","s":"SCS Conformance Test Implementation Guide","u":"/contributor-docs/development/tests/test-implementation-guide","p":296},{"i":310,"t":"SovereignCloudStack wants to make it possible for operators to delegate","s":"Identity Federation in SCS","u":"/contributor-docs/operations/iam/identity-federation-in-scs","p":310},{"i":316,"t":"Keystone supports federating authentication and authorization decisions via several mechanisms","s":"OpenStack Federation via OpenID-Connect","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","p":316},{"i":330,"t":"About","s":"Introduction","u":"/docs/","p":330},{"i":352,"t":"Prerequisites","s":"Zuul users guide","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","p":352},{"i":369,"t":"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:","s":"Container Layer Introduction","u":"/docs/container/","p":369},{"i":381,"t":"In a Cluster API management cluster, the Cluster API operators run. In our management cluster, there are also the Cluster Stack operators.","s":"Management Cluster flow","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flow","p":381},{"i":383,"t":"The node image flow depends on each provider. There are various ways in which providers allow the use of custom images. We have documented the options in the cluster stacks repo.","s":"Node image flow","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flow","p":383},{"i":385,"t":"It is essential to understand the flow of what you have to do as a user and what happens in the background.","s":"Deep dive: User flow","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flow","p":385},{"i":398,"t":"Architecture","s":"Overview","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overview","p":398},{"i":416,"t":"The workload cluster flow is implemented by two controllers and one custom resource.","s":"The workload cluster flow","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flow","p":416},{"i":418,"t":"The Cluster Stack framework was developed as one of the building blocks of an open-source Kubernetes-as-a-Service. The goal was to make it easier and more user-friendly to manage Kubernetes and Cluster API.","s":"Understanding the concept of Cluster Stacks","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/concept","p":418},{"i":428,"t":"Develop Cluster Stack Operator","s":"Contributing","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/","p":428},{"i":436,"t":"Release Process","s":"releasing","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasing","p":436},{"i":443,"t":"The Cluster Stacks are a framework and provide tools how to use them. The terminology is not perfect and if you have an idea how to improve it, please reach out. Right now there are the following terms:","s":"Terminology","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminology","p":443},{"i":457,"t":"ClusterStack","s":"clusterstack","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstack","p":457},{"i":466,"t":"Quickstart","s":"Getting Started","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstart","p":466},{"i":476,"t":"The ClusterStack object is the central resource that you have to work with. You have to specify a provider, the name of the cluster stack you want to use, as well as the Kubernetes minor version.","s":"Managing ClusterStack objects","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacks","p":476},{"i":478,"t":"This flow assumes that you have an existing cluster that references a certain ClusterClass called docker-ferrol-1-27-v1.","s":"Upgrade flow","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flow","p":478},{"i":480,"t":"Check the latest events:","s":"Troubleshooting","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshoot","p":480},{"i":482,"t":"This is a quickstart guide on using the local clusterstacks.","s":"using-local-clusterstacks","u":"/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacks","p":482},{"i":494,"t":"OpenStackClusterStackRelease controller","s":"Controllers","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","p":494},{"i":499,"t":"The Cluster Stack Provider OpenStack (CSPO) works with the Cluster Stack Operator (CSO) and Cluster Stacks, enabling the creation of Kubernetes clusters in a Cluster-API-native (CAPI) fashion.","s":"Overview","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","p":499},{"i":501,"t":"This document has been moved.","s":"Quickstart","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","p":501},{"i":503,"t":"Developing Cluster Stack Provider OpenStack operator is quite straightforward. First, you need to install some basic prerequisites:","s":"Developer Guide","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","p":503},{"i":515,"t":"This guide explains general info on how to debug issues if a cluster creation fails.","s":"Troubleshooting","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","p":515},{"i":519,"t":"Project cluster-stacks use the SCS Zuul CI platform to","s":"Continuous integration","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integration","p":519},{"i":531,"t":"Cluster Stacks","s":"Overview","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/overview","p":531},{"i":552,"t":"This page lists the custom configuration options available, including their default values and if they are optional. The following example shows how these variables can be used inside the cluster.yaml file under spec.topology.variables.","s":"Configuration","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configuration","p":552},{"i":558,"t":"Clone the Repo","s":"Developing and Testing csctl","u":"/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctl","p":558},{"i":571,"t":"This quickstart guide contains steps to install the Cluster Stack Operator (CSO) utilizing the Cluster Stack Provider OpenStack (CSPO) to provide ClusterClasses which can be used with the Kubernetes Cluster API to create Kubernetes Clusters.","s":"Quickstart","u":"/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstart","p":571},{"i":591,"t":"The Cluster Stack Operator facilitates the usage of cluster stacks by automating all steps that can be automated. It takes cluster stacks release assets that consist mainly of two Helm charts, one to deploy in the management cluster, the other one to deploy in the workload clusters, as well as provider-specific node image (build) information.","s":"CSCTL - Design document","u":"/docs/container/components/cluster-stacks/components/csctl/design","p":591},{"i":639,"t":"Obsolete, content moved to overview.md and quickstart.md for use in docs.scs.community","s":"Using csctl","u":"/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctl","p":639},{"i":656,"t":"A Cluster Stack is full template of a Kubernetes cluster. A Cluster Stack can be configured on every provider that supports Cluster API.","s":"Getting started","u":"/docs/container/components/cluster-stacks/components/csctl/getting_started","p":656},{"i":662,"t":"Introduction","s":"Overview","u":"/docs/container/components/cluster-stacks/components/csctl/overview","p":662},{"i":669,"t":"Installation","s":"Quickstart","u":"/docs/container/components/cluster-stacks/components/csctl/quickstart","p":669},{"i":684,"t":"Prerequisites","s":"HA deployment","u":"/docs/container/components/container-registry/docs/ha-deployment","p":684},{"i":695,"t":"This page aims at providing a step-by-step guide for backup and restore Harbor","s":"Backup and restore","u":"/docs/container/components/container-registry/docs/backup_and_restore","p":695},{"i":711,"t":"This page briefly describes and provides pointers on how Harbor persists data when it is","s":"Persistence","u":"/docs/container/components/container-registry/docs/persistence","p":711},{"i":727,"t":"harbormigration.png","s":"Migration","u":"/docs/container/components/container-registry/docs/migration","p":727},{"i":740,"t":"This page describes how the rate limiting can be set up for the Harbor container registry.","s":"Rate limit","u":"/docs/container/components/container-registry/docs/rate_limit","p":740},{"i":742,"t":"The following steps were utilized for deploying the SCS reference installation of the Harbor container registry,","s":"SCS deployment","u":"/docs/container/components/container-registry/docs/scs-deployment","p":742},{"i":748,"t":"This guide shows you how to set up a working Harbor Container Registry that utilizes a Kubernetes cluster.","s":"Quickstart","u":"/docs/container/components/container-registry/docs/quickstart","p":748},{"i":754,"t":"This page aims at providing additional information for upgrading Harbor","s":"Upgrade","u":"/docs/container/components/container-registry/docs/upgrade","p":754},{"i":756,"t":"TODO","s":"Hardware Requirements","u":"/docs/container/deployment-examples/a/hardware","p":756},{"i":758,"t":"TODO","s":"Overview","u":"/docs/container/deployment-examples/a/","p":758},{"i":760,"t":"TODO","s":"Software Requirements","u":"/docs/container/deployment-examples/a/software","p":760},{"i":762,"t":"TODO","s":"Guide 1","u":"/docs/container/guides/guide1","p":762},{"i":764,"t":"TODO","s":"Architecture","u":"/docs/container/overview/architecture","p":764},{"i":766,"t":"TODO","s":"Knowledge","u":"/docs/container/overview/knowledge","p":766},{"i":768,"t":"TODO","s":"Containerization","u":"/docs/getting-started/containerization","p":768},{"i":770,"t":"What does SCS stand for?","s":"Frequently Asked Questions","u":"/docs/faq/","p":770},{"i":805,"t":"TODO","s":"Overview","u":"/docs/getting-started/overview","p":805},{"i":807,"t":"TODO","s":"Virtualization","u":"/docs/getting-started/virtualization","p":807},{"i":809,"t":"This file serves as the central glossary within SCS. It is intended to clearly","s":"Glossary","u":"/docs/glossary","p":809},{"i":856,"t":"The OpenStack Image Manager is a tool for managing all","s":"Image Manager","u":"/docs/iaas/components/image-manager/","p":856},{"i":881,"t":"Overview","s":"Image Manager update.py","u":"/docs/iaas/components/image-manager/update","p":881},{"i":888,"t":"Overview","s":"Flavor Manager","u":"/docs/iaas/components/flavor-manager","p":888},{"i":899,"t":"Overview","s":"Project Manager","u":"/docs/iaas/components/project-manager","p":899},{"i":921,"t":"Kurt Garloff, 2024-02-20","s":"Setting up OpenStack health monitor on Debian","u":"/docs/iaas/components/openstack-health-monitor","p":921},{"i":981,"t":"Preparations","s":"Resource Manager","u":"/docs/iaas/components/resource-manager","p":981},{"i":997,"t":"Overview","s":"Simple Stress","u":"/docs/iaas/components/simple-stress","p":997},{"i":1008,"t":"* The Concept Guide explains which components and modules make up OSISM. It also","s":"Guides","u":"/docs/iaas/guides/","p":1008},{"i":1010,"t":"Highlevel Overview","s":"Concept Guide","u":"/docs/iaas/guides/concept-guide/","p":1010},{"i":1023,"t":"Preface","s":"artcodix","u":"/docs/iaas/deployment-examples/artcodix/","p":1023},{"i":1053,"t":"* Infrastructure as a Service (IaaS) with OpenStack","s":"Components","u":"/docs/iaas/guides/concept-guide/components/","p":1053},{"i":1055,"t":"Kubernetes as a Service (KaaS) is a cloud service model that simplifies the deployment,","s":"Cluster API","u":"/docs/iaas/guides/concept-guide/components/clusterapi","p":1055},{"i":1060,"t":"Ceph is an Open Source software defined storage platform designed to provide highly scalable","s":"Ceph","u":"/docs/iaas/guides/concept-guide/components/ceph","p":1060},{"i":1063,"t":"Kubernetes as a Service (KaaS) simplifies the deployment, management, and scaling of","s":"Gardener","u":"/docs/iaas/guides/concept-guide/components/gardener","p":1063},{"i":1066,"t":"OpenStack Ironic is a project that provides Baremetal as a Service (BMaaS), enabling the","s":"Ironic","u":"/docs/iaas/guides/concept-guide/components/ironic","p":1066},{"i":1069,"t":"Lifecycle Management of K3S in OSISM","s":"K3S","u":"/docs/iaas/guides/concept-guide/components/k3s","p":1069},{"i":1071,"t":"Lifecycle Management of OpenStack in OSISM","s":"OpenStack","u":"/docs/iaas/guides/concept-guide/components/openstack","p":1071},{"i":1082,"t":"Lifecycle Management of Keycloak in OSISM","s":"Keycloak","u":"/docs/iaas/guides/concept-guide/components/keycloak","p":1082},{"i":1084,"t":"Lifecycle Management of Netdata in OSISM","s":"Netdata","u":"/docs/iaas/guides/concept-guide/components/netdata","p":1084},{"i":1086,"t":"Lifecycle Management of Prometheus in OSISM","s":"Prometheus & Grafana","u":"/docs/iaas/guides/concept-guide/components/prometheus","p":1086},{"i":1089,"t":"Lifecycle Management of SONiC in OSISM","s":"SONiC & OVN","u":"/docs/iaas/guides/concept-guide/components/sonic","p":1089},{"i":1093,"t":"Lifecycle Management of Teleport in OSISM","s":"Teleport","u":"/docs/iaas/guides/concept-guide/components/teleport","p":1093},{"i":1095,"t":"Parts of this chapter are based on the OpenStack Architecture Design Guide.","s":"Cluster design","u":"/docs/iaas/guides/concept-guide/design","p":1095},{"i":1102,"t":"The brands, models and configurations listed are examples. There is no","s":"Hardware Bill of Materials","u":"/docs/iaas/guides/concept-guide/hardware-bom","p":1102},{"i":1122,"t":"Compute Node","s":"Nodes in a cluster","u":"/docs/iaas/guides/concept-guide/nodes","p":1122},{"i":1129,"t":"Compute Plane","s":"Layers in a cluster","u":"/docs/iaas/guides/concept-guide/layers","p":1129},{"i":1136,"t":"Hyper-converged infrastructure (HCI)","s":"Use cases","u":"/docs/iaas/guides/concept-guide/use-cases","p":1136},{"i":1139,"t":"This section contains the documentation of the Ansible collection osism.commons.","s":"Commons","u":"/docs/iaas/guides/configuration-guide/commons/","p":1139},{"i":1141,"t":"With the osism.commons.certificates role, it is possible to add custom CA certificates","s":"Certificates","u":"/docs/iaas/guides/configuration-guide/commons/certificates","p":1141},{"i":1143,"t":"With the osism.commons.packages role, it is possible to add packages on a node","s":"Packages","u":"/docs/iaas/guides/configuration-guide/commons/packages","p":1143},{"i":1152,"t":"With the osism.commons.resolvconf role, it is possible to manage the used DNS servers on a node.","s":"Resolvconf","u":"/docs/iaas/guides/configuration-guide/commons/resolvconf","p":1152},{"i":1154,"t":"With the osism.commons.services role, it is possible to manage services on a node","s":"Services","u":"/docs/iaas/guides/configuration-guide/commons/services","p":1154},{"i":1160,"t":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/","s":"Ceph","u":"/docs/iaas/guides/configuration-guide/ceph","p":1160},{"i":1192,"t":"With the osism.commons.sshconfig role, it is possible to manage a SSH config","s":"SSH Config","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","p":1192},{"i":1200,"t":"With the osism.commons.sysctl role, it is possible to manage the attributes of the kernel","s":"Sysctl","u":"/docs/iaas/guides/configuration-guide/commons/sysctl","p":1200},{"i":1202,"t":"With the osism.commons.timezone role, it is possible to manage the used timezone on a node.","s":"Timezone","u":"/docs/iaas/guides/configuration-guide/commons/timezone","p":1202},{"i":1204,"t":"With the osism.commons.user role, it is possible to manage additional","s":"User","u":"/docs/iaas/guides/configuration-guide/commons/user","p":1204},{"i":1206,"t":"The inventory used for the environment is located in the inventory directory.","s":"Inventory","u":"/docs/iaas/guides/configuration-guide/inventory","p":1206},{"i":1215,"t":"The configuration required for an OSISM managed cluster is stored in a single Git","s":"Configuration Repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","p":1215},{"i":1239,"t":"The settings of the following section rely on the mechanisms of Kolla-Ansible,","s":"Loadbalancer","u":"/docs/iaas/guides/configuration-guide/loadbalancer","p":1239},{"i":1255,"t":"Stable release","s":"Manager","u":"/docs/iaas/guides/configuration-guide/manager","p":1255},{"i":1264,"t":"Netplan","s":"Network","u":"/docs/iaas/guides/configuration-guide/network","p":1264},{"i":1276,"t":"* Aodh admin guide","s":"Aodh","u":"/docs/iaas/guides/configuration-guide/openstack/aodh","p":1276},{"i":1278,"t":"* Ceilometer admin guide","s":"Ceilometer","u":"/docs/iaas/guides/configuration-guide/openstack/ceilometer","p":1278},{"i":1280,"t":"* Barbican admin guide","s":"Barbican","u":"/docs/iaas/guides/configuration-guide/openstack/barbican","p":1280},{"i":1282,"t":"* Cinder admin guide","s":"Cinder","u":"/docs/iaas/guides/configuration-guide/openstack/cinder","p":1282},{"i":1286,"t":"* Designate admin guide","s":"Designate","u":"/docs/iaas/guides/configuration-guide/openstack/designate","p":1286},{"i":1288,"t":"* Glance admin guide","s":"Glance","u":"/docs/iaas/guides/configuration-guide/openstack/glance","p":1288},{"i":1290,"t":"Image tags","s":"OpenStack","u":"/docs/iaas/guides/configuration-guide/openstack/","p":1290},{"i":1307,"t":"* Heat admin guide","s":"Heat","u":"/docs/iaas/guides/configuration-guide/openstack/heat","p":1307},{"i":1309,"t":"* Horizon admin guide","s":"Horizon","u":"/docs/iaas/guides/configuration-guide/openstack/horizon","p":1309},{"i":1317,"t":"* Ironic admin guide","s":"Ironic","u":"/docs/iaas/guides/configuration-guide/openstack/ironic","p":1317},{"i":1319,"t":"* Magnum admin guide","s":"Magnum","u":"/docs/iaas/guides/configuration-guide/openstack/magnum","p":1319},{"i":1321,"t":"* Keystone admin guide","s":"Keystone","u":"/docs/iaas/guides/configuration-guide/openstack/keystone","p":1321},{"i":1326,"t":"* Manila admin guide","s":"Manila","u":"/docs/iaas/guides/configuration-guide/openstack/manila","p":1326},{"i":1328,"t":"* Neutron admin guide","s":"Neutron","u":"/docs/iaas/guides/configuration-guide/openstack/neutron","p":1328},{"i":1332,"t":"* Placement admin guide","s":"Placement","u":"/docs/iaas/guides/configuration-guide/openstack/placement","p":1332},{"i":1334,"t":"* Octavia admin guide","s":"Octavia","u":"/docs/iaas/guides/configuration-guide/openstack/octavia","p":1334},{"i":1336,"t":"Skyline APIServer","s":"Skyline","u":"/docs/iaas/guides/configuration-guide/openstack/skyline","p":1336},{"i":1341,"t":"In the following examples, it is assumed that the Squid proxy integrated by OSISM","s":"Proxy","u":"/docs/iaas/guides/configuration-guide/proxy","p":1341},{"i":1355,"t":"* Nova admin guide","s":"Nova","u":"/docs/iaas/guides/configuration-guide/openstack/nova","p":1355},{"i":1386,"t":"Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime.","s":"Configure Rookify: Migrate from Ceph-Ansible to Rook (Technical Preview)","u":"/docs/iaas/guides/configuration-guide/rookify","p":1386},{"i":1392,"t":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/","s":"Ceph via Rook (technical preview)","u":"/docs/iaas/guides/configuration-guide/rook","p":1392},{"i":1444,"t":"This section contains the documentation of the Ansible collection","s":"Services","u":"/docs/iaas/guides/configuration-guide/services/","p":1444},{"i":1446,"t":"With the osism.services.chrony role, it is possible to manage the used NTP servers on a node.","s":"Chrony","u":"/docs/iaas/guides/configuration-guide/services/chrony","p":1446},{"i":1448,"t":"With the osism.services.docker role, it is possible to manage Docker.","s":"Docker","u":"/docs/iaas/guides/configuration-guide/services/docker","p":1448},{"i":1452,"t":"This section contains the documentation of the Ansible collection","s":"Validations","u":"/docs/iaas/guides/configuration-guide/validations/","p":1452},{"i":1454,"t":"The roller can be applied with osism apply tuned. The role is applied to all","s":"Tuned","u":"/docs/iaas/guides/configuration-guide/services/tuned","p":1454},{"i":1456,"t":"The prerequisite for bootstraping the nodes of a cluster the Manager node has to be","s":"Bootstrap","u":"/docs/iaas/guides/deploy-guide/bootstrap","p":1456},{"i":1459,"t":"OSISM is deployed in a series of successive steps. The steps are documented in the Deploy Guide.","s":"Deploy Guide","u":"/docs/iaas/guides/deploy-guide/","p":1459},{"i":1461,"t":"For the initial deployment of the management plane and the control plane of OSISM,","s":"Provisioning of bare-metal nodes","u":"/docs/iaas/guides/deploy-guide/provisioning","p":1461},{"i":1467,"t":"The prerequisite for deploying the Manager node is a Seed node. What a Seed node is","s":"Manager","u":"/docs/iaas/guides/deploy-guide/manager","p":1467},{"i":1481,"t":"This section has moved. You can now find the content in the","s":"Testbed","u":"/docs/iaas/guides/deploy-guide/examples/testbed","p":1481},{"i":1483,"t":"Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime.","s":"Deploy Rookify: Migrate to Rook from Ceph-Ansible (Technical Preview)","u":"/docs/iaas/guides/deploy-guide/rookify","p":1483},{"i":1494,"t":"This section has moved. You can now find the content in the","s":"Cloud in a Box","u":"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box","p":1494},{"i":1496,"t":"The prerequisite for the deployment of a cluster is a configuration repository.","s":"Seed","u":"/docs/iaas/guides/deploy-guide/seed","p":1496},{"i":1502,"t":"In OSISM it is also possible to integrate and use existing Ceph clusters. It","s":"Ceph","u":"/docs/iaas/guides/deploy-guide/services/ceph","p":1502},{"i":1510,"t":"The prerequisite for deploying the services of a cluster is the bootstrap of","s":"Services","u":"/docs/iaas/guides/deploy-guide/services/","p":1510},{"i":1512,"t":"Common issues with deploying infrastructure services required by OpenStack","s":"Infrastructure","u":"/docs/iaas/guides/deploy-guide/services/infrastructure","p":1512},{"i":1514,"t":"As of OSISM 7, it is possible to create a Kubernetes cluster on all nodes.","s":"Kubernetes","u":"/docs/iaas/guides/deploy-guide/services/kubernetes","p":1514},{"i":1518,"t":"1. Open vSwitch (OVS)","s":"Network","u":"/docs/iaas/guides/deploy-guide/services/network","p":1518},{"i":1520,"t":"Common issues with deploying logging & monitoring services provided by Kolla","s":"Logging & Monitoring","u":"/docs/iaas/guides/deploy-guide/services/logging-monitoring","p":1520},{"i":1522,"t":"Common issues with deploying OpenStack services are documented in the","s":"OpenStack","u":"/docs/iaas/guides/deploy-guide/services/openstack","p":1522},{"i":1524,"t":"This is a technical preview and not recommended for production use yet.","s":"Ceph via Rook (technical preview)","u":"/docs/iaas/guides/deploy-guide/services/rook","p":1524},{"i":1532,"t":"Change Node states","s":"Operations Guide","u":"/docs/iaas/guides/operations-guide/","p":1532},{"i":1548,"t":"This is a technical preview and not recommended for production use yet.","s":"Migrate Ceph-Ansible via Rookify (technical preview)","u":"/docs/iaas/guides/deploy-guide/services/rookify","p":1548},{"i":1550,"t":"Loadbalancer","s":"Infrastructure","u":"/docs/iaas/guides/operations-guide/infrastructure","p":1550},{"i":1567,"t":"Where to find docs","s":"Ceph","u":"/docs/iaas/guides/operations-guide/ceph","p":1567},{"i":1653,"t":"OSISM orchestrator","s":"Manager","u":"/docs/iaas/guides/operations-guide/manager/","p":1653},{"i":1654,"t":"With the apply command it is possible to run Ansible plays. These are executed as","s":"Apply","u":"/docs/iaas/guides/operations-guide/manager/apply","p":1654},{"i":1666,"t":"A console command is available in the OSISM CLI. This allows specific parts of the","s":"Console","u":"/docs/iaas/guides/operations-guide/manager/console","p":1666},{"i":1676,"t":"A get command is available in the OSISM CLI. This allows to gather specific information.","s":"Get","u":"/docs/iaas/guides/operations-guide/manager/get","p":1676},{"i":1684,"t":"List","s":"Task","u":"/docs/iaas/guides/operations-guide/manager/task","p":1684},{"i":1689,"t":"Ansible","s":"Logging","u":"/docs/iaas/guides/operations-guide/manager/log","p":1689},{"i":1699,"t":"OpenStack, OVN, and Open vSwitch all really like UUIDs.","s":"Network","u":"/docs/iaas/guides/operations-guide/network","p":1699},{"i":1705,"t":"Create an external network","s":"OpenStack","u":"/docs/iaas/guides/operations-guide/openstack/","p":1705},{"i":1714,"t":"Remove service","s":"Cinder","u":"/docs/iaas/guides/operations-guide/openstack/cinder","p":1714},{"i":1721,"t":"Quality of Service (QoS)","s":"Neutron","u":"/docs/iaas/guides/operations-guide/openstack/neutron","p":1721},{"i":1724,"t":"* List all users of a project who have been assigned the member role","s":"Keystone","u":"/docs/iaas/guides/operations-guide/openstack/keystone","p":1724},{"i":1726,"t":"Get all servers on a node","s":"Nova","u":"/docs/iaas/guides/operations-guide/openstack/nova","p":1726},{"i":1741,"t":"Cleanup of amphorae missing from the DB","s":"Octavia","u":"/docs/iaas/guides/operations-guide/openstack/octavia","p":1741},{"i":1746,"t":"Overview","s":"Flavor Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","p":1746},{"i":1757,"t":"The OpenStack Image Manager is a tool for managing all","s":"Image Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","p":1757},{"i":1783,"t":"Overview","s":"Project Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","p":1783},{"i":1805,"t":"Overview","s":"Image Manager update.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","p":1805},{"i":1812,"t":"Kurt Garloff, 2024-02-20","s":"Setting up OpenStack health monitor on Debian","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","p":1812},{"i":1872,"t":"Preparations","s":"Resource Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","p":1872},{"i":1888,"t":"Overview","s":"Simple Stress","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","p":1888},{"i":1899,"t":"This is a technical preview and not recommended for production use yet. This whole","s":"Ceph via Rook (technical preview)","u":"/docs/iaas/guides/operations-guide/rook","p":1899},{"i":1978,"t":"Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime.","s":"Use Rookify: Migrate to Rook from Ceph Ansible (Technical Preview)","u":"/docs/iaas/guides/operations-guide/rookify","p":1978},{"i":2000,"t":"KVM","s":"Running on a virtual machine","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machine","p":2000},{"i":2022,"t":"We welcome any issues, change requests or general feedback. Do not hestiate to open an issue.","s":"Contributor Guide","u":"/docs/iaas/guides/other-guides/contributor-guide","p":2022},{"i":2024,"t":"💡 Cloud in a Box (CiaB) is a minimalistic installation of the latest stable OSISM release with only services which are needed to","s":"Cloud in a Box","u":"/docs/iaas/guides/other-guides/cloud-in-a-box/","p":2024},{"i":2053,"t":"How we handle releases","s":"Releases","u":"/docs/iaas/guides/other-guides/developer-guide/releases","p":2053},{"i":2070,"t":"Scripts are included in container images to simplify development work and to enable","s":"Scripts","u":"/docs/iaas/guides/other-guides/developer-guide/scripts","p":2070},{"i":2072,"t":"How to add a new service","s":"Developer Guide","u":"/docs/iaas/guides/other-guides/developer-guide/","p":2072},{"i":2080,"t":"Ansible","s":"Style Guide","u":"/docs/iaas/guides/other-guides/developer-guide/style-guide","p":2080},{"i":2111,"t":"We use Zuul CI as a CI service for OSISM. The service is not required for","s":"Zuul CI","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","p":2111},{"i":2133,"t":"💡 The Troubleshooting Guide describe how to solve issues.","s":"Troubleshooting Guide","u":"/docs/iaas/guides/troubleshooting-guide/","p":2133},{"i":2135,"t":"Where to find docs","s":"Ceph","u":"/docs/iaas/guides/troubleshooting-guide/ceph","p":2135},{"i":2140,"t":"Database creation fails","s":"OpenStack","u":"/docs/iaas/guides/troubleshooting-guide/openstack","p":2140},{"i":2147,"t":"Rookify is developed to migrate from Ceph-Ansible to Rook in place and without downtime.","s":"Rookify (Technical Preview)","u":"/docs/iaas/guides/troubleshooting-guide/rookify","p":2147},{"i":2153,"t":"Reset","s":"Manager","u":"/docs/iaas/guides/troubleshooting-guide/manager","p":2153},{"i":2156,"t":"In the examples, the pull of images (if supported by a role) is always run first. While","s":"Upgrade Guide","u":"/docs/iaas/guides/upgrade-guide/","p":2156},{"i":2158,"t":"See Rook Operations.","s":"Ceph","u":"/docs/iaas/guides/upgrade-guide/ceph","p":2158},{"i":2162,"t":"The Docker version used is defined via the parameter docker_version in the file","s":"Docker","u":"/docs/iaas/guides/upgrade-guide/docker","p":2162},{"i":2166,"t":"1. Kubernetes","s":"Infrastructure","u":"/docs/iaas/guides/upgrade-guide/infrastructure","p":2166},{"i":2168,"t":"1. OpenSearch","s":"Logging & Monitoring","u":"/docs/iaas/guides/upgrade-guide/logging-monitoring","p":2168},{"i":2170,"t":"Always read the release notes first to learn what has changed and what","s":"Manager","u":"/docs/iaas/guides/upgrade-guide/manager","p":2170},{"i":2172,"t":"1. Open vSwitch (OVS)","s":"Network","u":"/docs/iaas/guides/upgrade-guide/network","p":2172},{"i":2174,"t":"With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack","s":"Testbed","u":"/docs/iaas/guides/other-guides/testbed","p":2174},{"i":2230,"t":"When upgrade the different OpenStack services, all containers must be","s":"OpenStack","u":"/docs/iaas/guides/upgrade-guide/openstack","p":2230},{"i":2233,"t":"This guide is an example of how to perform a manual migration from a VMware ESXi host to OpenStack.","s":"Migrate from VMware ESXi to OpenStack","u":"/docs/iaas/guides/user-guide/migration-vmware-esxi","p":2233},{"i":2260,"t":"While in general it is considered best practice to create instances from existing or specially crafted images, sometimes it is necessary to install an instance using a traditional installer packaged in an ISO image.","s":"Install instance from ISO image","u":"/docs/iaas/guides/user-guide/openstack/install-instance-from-iso","p":2260},{"i":2271,"t":"OpenStackClient looks for a clouds.yaml configuration file in the following locations:","s":"Client","u":"/docs/iaas/guides/user-guide/openstack/openstackclient","p":2271},{"i":2282,"t":"Security groups in OpenStack are part of the network security mechanisms provided for the users.","s":"How to configure and use security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","p":2282},{"i":2296,"t":"Security groups in OpenStack are part of the network security mechanisms provided for the users.","s":"Best Practise: How to configure and use security groups","u":"/docs/iaas/guides/user-guide/security-groups/","p":2296},{"i":2310,"t":"TODO","s":"Architecture","u":"/docs/iaas/overview/architecture","p":2310},{"i":2312,"t":"TODO","s":"Compute","u":"/docs/iaas/overview/compute","p":2312},{"i":2314,"t":"TODO","s":"Knowledge","u":"/docs/iaas/overview/knowledge","p":2314},{"i":2316,"t":"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.","s":"User Data Backups","u":"/docs/iaas/guides/user-guide/user-data-backups","p":2316},{"i":2361,"t":"TODO","s":"Network","u":"/docs/iaas/overview/network","p":2361},{"i":2363,"t":"TODO","s":"Storage","u":"/docs/iaas/overview/storage","p":2363},{"i":2365,"t":"Sovereign Cloud Stack wants to make it possible for operators to delegate","s":"Introduction on Identity Management and Federation in SCS","u":"/docs/iam/","p":2365},{"i":2383,"t":"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.","s":"User Data Backups","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","p":2383},{"i":2428,"t":"The followig section is a reasonably detailed hands on description of how","s":"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)","u":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","p":2428},{"i":2432,"t":"The following document explains the idea behind the example configuration is done.","s":"Example setup configuration in SCS deployment explained","u":"/docs/iam/SCS-example-setup-configuration-description","p":2432},{"i":2434,"t":"The following documentation refers to a SCS standard that is still in draft state.","s":"Domain Manager setup and usage","u":"/docs/iam/domain-manager-setup-and-usage","p":2434},{"i":2470,"t":"TODO","s":"Overview","u":"/docs/operating-scs/audits/","p":2470},{"i":2472,"t":"This page covers the process of setting up an IaaS layer automated pentesting pipeline.","s":"Quickstart","u":"/docs/operating-scs/components/automated-pentesting-iaas/quickstart","p":2472},{"i":2483,"t":"Introdution","s":"Overview","u":"/docs/operating-scs/components/automated-pentesting-iaas/overview","p":2483},{"i":2496,"t":"This section outlines how Infrastructure Operators (Cloud Service Providers - CSPs) and users can leverage automated pentesting reports focused on Infrastructure-as-a-Service (IaaS) and Container-as-a-Service (CaaS) environments.","s":"Using Automated Pentesting Reports for CSPs, Operators, and Users","u":"/docs/operating-scs/components/automated-pentesting-iaas/reports","p":2496},{"i":2523,"t":"Introdution","s":"Overview","u":"/docs/operating-scs/components/automated-pentesting-kaas/overview","p":2523},{"i":2546,"t":"The following tools make up the automated pentesting pipeline.","s":"Tools Description","u":"/docs/operating-scs/components/automated-pentesting-iaas/tools","p":2546},{"i":2560,"t":"This document provides a quick guide to setting up and running the security scanning infrastructure using Trivy and other related tools.","s":"Quickstart Guide","u":"/docs/operating-scs/components/automated-pentesting-kaas/quickstart","p":2560},{"i":2570,"t":"Premise","s":"Overview","u":"/docs/operating-scs/components/central-api/overview","p":2570},{"i":2587,"t":"The following tools make up the automated scanning pipeline and report sending.","s":"Tools Description","u":"/docs/operating-scs/components/automated-pentesting-kaas/tools","p":2587},{"i":2599,"t":"Right now, this repository implements issue 374.","s":"Central API MVP","u":"/docs/operating-scs/components/central-api/poc-setup","p":2599},{"i":2603,"t":"This page contains instructions on how to enable the Alertmanager to Matrix chat notifications in the Observer solution.","s":"Alertmanager notifications in Matrix chat","u":"/docs/operating-scs/components/monitoring/docs/alertmanager","p":2603},{"i":2605,"t":"This page contains instructions on how to enable probing of infrastructure service endpoints using blackbox exporter.","s":"Infrastructure service endpoints","u":"/docs/operating-scs/components/monitoring/docs/infrastructure_services","p":2605},{"i":2607,"t":"K3s is a certified Kubernetes distribution optimized for production environments, particularly in remote locations","s":"K3s support","u":"/docs/operating-scs/components/monitoring/docs/k3s","p":2607},{"i":2617,"t":"This repository aims to build an Observer monitoring solution intended to offer a global metrics","s":"Overview","u":"/docs/operating-scs/components/monitoring/docs/overview","p":2617},{"i":2619,"t":"This component is marked as experimental, and it is not part of the reference SCS installation available","s":"KaaS monitoring (experimental)","u":"/docs/operating-scs/components/monitoring/docs/kaas","p":2619},{"i":2627,"t":"We set up oauth2 with GitHub provider for the https//kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/.","s":"OAUTH","u":"/docs/operating-scs/components/monitoring/docs/oauth","p":2627},{"i":2629,"t":"The following steps were utilized to deploy the SCS reference installation of the Observer monitoring solution,","s":"SCS deployment","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","p":2629},{"i":2637,"t":"This component is marked as experimental, and it is not part of the reference SCS installation available","s":"IaaS monitoring (experimental)","u":"/docs/operating-scs/components/monitoring/docs/iaas","p":2637},{"i":2650,"t":"These page covers the process of deploying the Observer monitoring solution","s":"Quickstart","u":"/docs/operating-scs/components/monitoring/docs/quickstart","p":2650},{"i":2660,"t":"This page contains a guide on how to enable traces in Thanos. Traces are not enabled by default.","s":"Traces","u":"/docs/operating-scs/components/monitoring/docs/tracing","p":2660},{"i":2666,"t":"Prerequisites","s":"Status page monitoring","u":"/docs/operating-scs/components/monitoring/docs/status-page","p":2666},{"i":2677,"t":"This page contains instructions on how to enable the Zuul monitoring in the Observer solution.","s":"Zuul monitoring","u":"/docs/operating-scs/components/monitoring/docs/zuul","p":2677},{"i":2679,"t":"This page contains recommended parameters to set for the Thanos components to improve performance in terms of query time.","s":"Tuning","u":"/docs/operating-scs/components/monitoring/docs/tuning","p":2679},{"i":2687,"t":"Welcome to the SCS Health Monitor project! This repository is dedicated to setting up scenarios for functionality and load testing on a deployed OpenStack environment. We utilize Gherkin language to write testing scenarios, and Python's Behave library to execute these tests.","s":"SCS Health Monitor","u":"/docs/operating-scs/components/scs-health-monitor/overview","p":2687},{"i":2710,"t":"Quick Intro:","s":"Testflow-Infrastructure","u":"/docs/operating-scs/components/scs-health-monitor/Testflow","p":2710},{"i":2719,"t":"Configuration can be done by environment variables or flags to the binary.","s":"Configuration","u":"/docs/operating-scs/components/status-page-api/docs/configuration","p":2719},{"i":2721,"t":"Overview","s":"Kubernetes BDD Testing Framework Documentation","u":"/docs/operating-scs/components/scs-health-monitor/Workflow","p":2721},{"i":2750,"t":"Contributions are welcome at SovereignCloudStack/status-page-api.","s":"Contribute","u":"/docs/operating-scs/components/status-page-api/docs/contribute","p":2750},{"i":2752,"t":"Prerequisites","s":"Observability stack quickstart","u":"/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStack","p":2752},{"i":2757,"t":"Example request for common API requests.","s":"Example requests","u":"/docs/operating-scs/components/status-page-api/docs/example-requests","p":2757},{"i":2793,"t":"The status-page-api repository strives to provide a reference implementation of the concepts being outlined by status-page-openapi.","s":"Overview","u":"/docs/operating-scs/components/status-page-api/docs/overview","p":2793},{"i":2795,"t":"See requirements","s":"Quickstart","u":"/docs/operating-scs/components/status-page-api/docs/quickstart","p":2795},{"i":2803,"t":"As defined by the OpenAPI spec and status page OpenAPI decision the general API objects are used as request bodies and responses to generalize data structures. Not all object fields are handled by all requests, some are read only and some are write only. GET request wrap their return in a object field called data.","s":"Requests","u":"/docs/operating-scs/components/status-page-api/docs/requests","p":2803},{"i":2817,"t":"The status page API server requires a PostgreSQL database.","s":"Requirements","u":"/docs/operating-scs/components/status-page-api/docs/requirements","p":2817},{"i":2819,"t":"A minimal configuration of the status page deployment.","s":"Configure status page","u":"/docs/operating-scs/components/status-page-deployment/docs/configuration","p":2819},{"i":2835,"t":"As the write operations of the API server are protected by Oathkeeper and use identities provided by Dex an Administrator is considered to be a person that can authenticate on Dex.","s":"Admin authentication","u":"/docs/operating-scs/components/status-page-deployment/docs/admin-authentication","p":2835},{"i":2837,"t":"Dex needs a GitHub client secret. Where can I get it?","s":"FAQ","u":"/docs/operating-scs/components/status-page-deployment/docs/faq","p":2837},{"i":2846,"t":"From a new machine to a working status page in ~15 minutes.","s":"k3s - A simple deployment on a single host","u":"/docs/operating-scs/components/status-page-deployment/docs/k3s","p":2846},{"i":2864,"t":"Contributions are welcome at SovereignCloudStack/status-page-deployment.","s":"Contribute","u":"/docs/operating-scs/components/status-page-deployment/docs/contribute","p":2864},{"i":2866,"t":"All backend components of the status page can be instrumented to supply metrics. These metrics can be collected and visualized by monitoring technologies like Prometheus and Grafana.","s":"Monitoring","u":"/docs/operating-scs/components/status-page-deployment/docs/monitoring","p":2866},{"i":2874,"t":"kind is a tool to quickly setup a local development environment, to test and debug the deployment.","s":"kind - Local development environment","u":"/docs/operating-scs/components/status-page-deployment/docs/kind","p":2874},{"i":2886,"t":"The status page needs some components additional to the API server to be usable by operators and customers. As the API server does not implement any kind of authorization or authentication some components need to be deployed to protect the write operations of the API from unauthorized access.","s":"Overview","u":"/docs/operating-scs/components/status-page-deployment/docs/overview","p":2886},{"i":2895,"t":"To get a quickstart, please refer to the KinD or k3s guide.","s":"Quickstart","u":"/docs/operating-scs/components/status-page-deployment/docs/quickstart","p":2895},{"i":2897,"t":"The requirements are specific for the relevant environment.","s":"Requirements","u":"/docs/operating-scs/components/status-page-deployment/docs/requirements","p":2897},{"i":2899,"t":"Data present in kubernetes/environments/scs-public is the deployment specified for the provided SCS Cluster, which is already fully setup to run k8s workloads.","s":"SCS Public","u":"/docs/operating-scs/components/status-page-deployment/docs/scs-public","p":2899},{"i":2901,"t":"This represents a part of the decision process related to the overall structure the API wants to represent.","s":"Component Overview","u":"/docs/operating-scs/components/status-page-openapi/docs/component_overview","p":2901},{"i":2903,"t":"You can use and test the API via any API client (Bruno, built in Swagger UI, etc.), CLI tool (like curl) or the web frontend.","s":"Usage","u":"/docs/operating-scs/components/status-page-deployment/docs/usage","p":2903},{"i":2911,"t":"Illustrating multiple interchangeable logical \"layers\" of possible Status Page application stacks:","s":"Components","u":"/docs/operating-scs/components/status-page-openapi/docs/components","p":2911},{"i":2913,"t":"When implementing any system to be used by a group of potential users, there will be varying use cases and opinions about API's, programming languages, persistence models, authentication, authorization, deployment options and so on.","s":"\"Levels of consensus\"","u":"/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensus","p":2913},{"i":2915,"t":"Service providers often times want to communicate the status of their systems transparently to their users.","s":"Overview","u":"/docs/operating-scs/components/status-page-openapi/docs/overview","p":2915},{"i":2927,"t":"The SPA expects a configuration file called config.json to be present in the src/assets folder. The very same folder also contains a template for this configuration file, called config.tmpl.json. The resulting configuration, in the static build of the SPA, will be located at dist/scs-statuspage/browser/assets.","s":"Configuration","u":"/docs/operating-scs/components/status-page-web/docs/configuration","p":2927},{"i":2933,"t":"To start developing for the status page web frontend, start by cloning the repo. Remember to run git submodule update --init afterwards to also retrieve the OpenAPI client included in the sources.","s":"Contribute","u":"/docs/operating-scs/components/status-page-web/docs/contribute","p":2933},{"i":2935,"t":"To quickly start hosting the status page frontend, refer to the Quickstart guide of the status-page-deployment repository.","s":"Quickstart","u":"/docs/operating-scs/components/status-page-web/docs/quickstart","p":2935},{"i":2937,"t":"Compiling the status page frontend requires Angular 17+.","s":"Requirements","u":"/docs/operating-scs/components/status-page-web/docs/requirements","p":2937},{"i":2939,"t":"This repository supplies a SPA (Single Page Application), written in Angular, that uses the status-page-openapi client to connect to the API server to show components, incidents and their impacts on the system. The SPA also offers a management page, allowing authorized users to create, update and delete incidents (including future incidents, the so-called maintenance events).","s":"Overview","u":"/docs/operating-scs/components/status-page-web/docs/overview","p":2939},{"i":2941,"t":"TODO","s":"Overview","u":"/docs/operating-scs/incident-management/","p":2941},{"i":2943,"t":"TODO","s":"Overview","u":"/docs/operating-scs/lifecycle-management/","p":2943},{"i":2945,"t":"Kurt Garloff, 2024-02-20","s":"Guide: Setting up openstack-health-monitor on Debian 12","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","p":2945},{"i":3005,"t":"TODO","s":"Overview","u":"/docs/operating-scs/logging/","p":3005},{"i":3007,"t":"TODO","s":"Overview","u":"/docs/operating-scs/monitoring/","p":3007},{"i":3009,"t":"TODO","s":"Overview","u":"/docs/operating-scs/overview","p":3009},{"i":3011,"t":"(Release Date: 2021-07-15)","s":"Release Notes for SCS Release 0","u":"/docs/releases/Release0","p":3011},{"i":3029,"t":"The Metrics and events we want to use in the metering process can be defined in two ways. The first one is to allow ceilometer to poll distinct metrics and events.","s":"Metering Configuration","u":"/docs/operating-scs/metering/meter_configuration","p":3029},{"i":3041,"t":"(Release Date: 2021-09-29)","s":"Release Notes for SCS Release 1","u":"/docs/releases/Release1","p":3041},{"i":3078,"t":"(Release Date: 2022-03-23)","s":"Release Notes for SCS Release 2","u":"/docs/releases/Release2","p":3078},{"i":3111,"t":"(Release Date: 2022-09-21)","s":"Release Notes for SCS Release 3","u":"/docs/releases/Release3","p":3111},{"i":3145,"t":"(Release Date: 2023-03-22)","s":"Release Notes for SCS Release 4","u":"/docs/releases/Release4","p":3145},{"i":3177,"t":"(Release Date: 2023-09-20)","s":"Release Notes for SCS Release 5","u":"/docs/releases/Release5","p":3177},{"i":3215,"t":"SCS Release 6 has been published on 2024-03-20.","s":"Release Notes for SCS Release 6","u":"/docs/releases/Release6","p":3215},{"i":3273,"t":"Release 7 has been published on September 11, 2024.","s":"Release Notes for SCS Release 7","u":"/docs/releases/Release7","p":3273},{"i":3324,"t":"This document is work in progress for the upcoming Release X.","s":"Release Notes for SCS Release X","u":"/docs/releases/ReleaseX","p":3324},{"i":3342,"t":"An image of the SCS hardware landscape rack","s":"The SCS Hardware-Landscape","u":"/docs/turnkey-solution/hardware-landscape","p":3342},{"i":3353,"t":"Scope of this document","s":"Overview","u":"/docs/turnkey-solution/overview","p":3353},{"i":3358,"t":"TODO","s":"Standards","u":"/docs/standards/","p":3358},{"i":3360,"t":"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.","s":"Introduction","u":"/standards/","p":3360},{"i":3362,"t":"SCS certificates come with various scopes. See Scopes and Versions for details.","s":"Certification","u":"/standards/certification/overview","p":3362},{"i":3368,"t":"SCS certificates come with various scopes. See Scopes and Versions for details.","s":"Certification","u":"/standards/certification/overview.template","p":3368},{"i":3374,"t":"The SCS compliance check suite runs automated tests, generates a signed report for the run, and feeds it to","s":"SCS Compliance Check Pipeline Manual","u":"/standards/certification/pipeline","p":3374},{"i":3385,"t":"SCS provides a certification framework consisting of six different kinds of certificates of varying scope.","s":"Scopes and versions","u":"/standards/certification/scopes-versions","p":3385},{"i":3387,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0002: Standards, Docs and Organisation","u":"/standards/global/scs-0002","p":3387},{"i":3389,"t":"This track encompasses the foundational standards that guide the overall structure, documentation, and general topics related to the Sovereign Cloud Stack. It serves as the core framework, ensuring consistency, clarity, and comprehensibility across all aspects of the cloud stack, fostering an environment where information is easily accessible and understood.","s":"Global Standards","u":"/standards/global/","p":3389},{"i":3391,"t":"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision","s":"scs-0001: Sovereign Cloud Standards","u":"/standards/global/scs-0001","p":3391},{"i":3393,"t":"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,","s":"scs-0003: Sovereign Cloud Standards YAML","u":"/standards/global/scs-0003","p":3393},{"i":3395,"t":"SCS-0005 outlines the structure and governance of the SCS community by the SCS Project Board and how this is elected.","s":"scs-0005: Governance of the SCS community","u":"/standards/global/scs-0005","p":3395},{"i":3397,"t":"The IaaS Layer Standards track focuses on the protocols, guidelines, and specifications that govern the infrastructure as a service layer. This encompasses standards for virtual machines, storage, networking, and other foundational resources, ensuring seamless, efficient, and secure operation, interoperability, and management of the underlying cloud infrastructure.","s":"IaaS Standards","u":"/standards/iaas/","p":3397},{"i":3399,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0004: Regulations for achieving SCS-compatible certification","u":"/standards/global/scs-0004","p":3399},{"i":3401,"t":"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack","s":"scs-0100: SCS Flavor Naming Standard","u":"/standards/iaas/scs-0100","p":3401},{"i":3405,"t":"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations","s":"scs-0101: SCS Entropy","u":"/standards/iaas/scs-0101","p":3405},{"i":3409,"t":"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating","s":"scs-0102: SCS Image Metadata","u":"/standards/iaas/scs-0102","p":3409},{"i":3413,"t":"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,","s":"scs-0104: SCS Standard Images","u":"/standards/iaas/scs-0104","p":3413},{"i":3417,"t":"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack","s":"scs-0103: SCS Standard Flavors and Properties","u":"/standards/iaas/scs-0103","p":3417},{"i":3419,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0111: Decisions for the Volume Type Standard","u":"/standards/iaas/scs-0111","p":3419},{"i":3421,"t":"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.","s":"scs-0112: SONiC Support in SCS","u":"/standards/iaas/scs-0112","p":3421},{"i":3423,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0113: Security Groups Decision Record","u":"/standards/iaas/scs-0113","p":3423},{"i":3425,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0114: SCS Volume Types","u":"/standards/iaas/scs-0114","p":3425},{"i":3427,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0115: Default Rules for Security Groups","u":"/standards/iaas/scs-0115","p":3427},{"i":3429,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0110: SSD Flavors","u":"/standards/iaas/scs-0110","p":3429},{"i":3431,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0118: SCS Taxonomy of Failsafe Levels","u":"/standards/iaas/scs-0118","p":3431},{"i":3435,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0117: Volume Backup Functionality","u":"/standards/iaas/scs-0117","p":3435},{"i":3437,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0116: SCS Key Manager Standard","u":"/standards/iaas/scs-0116","p":3437},{"i":3441,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0119: Replacement of the deprecated ceph-ansible tool","u":"/standards/iaas/scs-0119","p":3441},{"i":3443,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0120: Cluster-API images","u":"/standards/iaas/scs-0120","p":3443},{"i":3445,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0121: SCS Availability Zones","u":"/standards/iaas/scs-0121","p":3445},{"i":3449,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0122: End-to-End Encryption between Customer Workloads","u":"/standards/iaas/scs-0122","p":3449},{"i":3451,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0123: Mandatory and Supported IaaS Services","u":"/standards/iaas/scs-0123","p":3451},{"i":3453,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0124: Standard for the security of IaaS service software","u":"/standards/iaas/scs-0124","p":3453},{"i":3457,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0125: Secure Connections","u":"/standards/iaas/scs-0125","p":3457},{"i":3459,"t":"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign","s":"scs-0300: Requirements for SSO identity federation","u":"/standards/iam/scs-0300","p":3459},{"i":3461,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0302: Domain Manager configuration for Keystone","u":"/standards/iam/scs-0302","p":3461},{"i":3465,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0301: Naming for domains/groups/roles/project when onboarding new customers","u":"/standards/iam/scs-0301","p":3465},{"i":3467,"t":"Standards in this track are concerned with Kubernetes as a Service layer, outlining norms and best practices for deploying, managing, and operating Kubernetes clusters. These standards aim to ensure that the orchestration of containers is streamlined, secure, and compatible across various cloud environments and platforms.","s":"KaaS Standards","u":"/standards/kaas/","p":3467},{"i":3469,"t":"This track revolves around Identity and Access Management (IAM) standards, providing guidelines for ensuring secure and efficient user authentication, authorization, and administration. It addresses issues related to user identity, permissions, roles, and policies, aiming to safeguard and streamline access to cloud resources and services.","s":"IAM Standards","u":"/standards/iam/","p":3469},{"i":3471,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0200: Using Sonobuoy for KaaS conformance tests","u":"/standards/kaas/scs-0200","p":3471},{"i":3473,"t":"The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).","s":"scs-0211: SCS KaaS default storage class","u":"/standards/kaas/scs-0211","p":3473},{"i":3477,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0210: SCS K8S Version Policy","u":"/standards/kaas/scs-0210","p":3477},{"i":3481,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0212: Requirements for container registries","u":"/standards/kaas/scs-0212","p":3481},{"i":3483,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0213: Kubernetes Nodes Anti Affinity","u":"/standards/kaas/scs-0213","p":3483},{"i":3485,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0214: Kubernetes Node Distribution and Availability","u":"/standards/kaas/scs-0214","p":3485},{"i":3489,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0215: Robustness features for Kubernetes clusters","u":"/standards/kaas/scs-0215","p":3489},{"i":3491,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0216: Requirements for testing cluster-stacks","u":"/standards/kaas/scs-0216","p":3491},{"i":3493,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0218: Container registry for SCS standard implementation","u":"/standards/kaas/scs-0218","p":3493},{"i":3495,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0219: KaaS Networking Standard","u":"/standards/kaas/scs-0219","p":3495},{"i":3499,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0217: Kubernetes cluster hardening","u":"/standards/kaas/scs-0217","p":3499},{"i":3501,"t":"Operational Tooling Standards cover the protocols and guidelines associated with tools and utilities used for monitoring, management, and maintenance of the cloud environment. This includes standards for status pages, alerts, logs, and other operational tools, aiming to optimize the reliability, performance, and security of cloud services and resources.","s":"Ops Standards","u":"/standards/ops/","p":3501},{"i":3503,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0400: Status Page create decision","u":"/standards/ops/scs-0400","p":3503},{"i":3505,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0401: Status page reference implementation decision","u":"/standards/ops/scs-0401","p":3505},{"i":3507,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0402: Status page OpenAPI decision","u":"/standards/ops/scs-0402","p":3507},{"i":3509,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer","u":"/standards/ops/scs-0403","p":3509},{"i":3511,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0411: Push-based approach for providing usage data","u":"/standards/ops/scs-0411","p":3511},{"i":3513,"t":"| Version | Type | State | stabilized | deprecated |","s":"scs-0410: Gnocchi as database for metering","u":"/standards/ops/scs-0410","p":3513},{"i":3515,"t":"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format","s":"scs-0412: Exposition of IaaS metering data as JSON","u":"/standards/ops/scs-0412","p":3515},{"i":3517,"t":"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision\nrecords within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in\nthe development and maintenance of interoperable and transparent cloud infrastructure standards.\n","s":"Sovereign Cloud Standards","u":"/standards/scs-0001-v1-sovereign-cloud-standards","p":3517},{"i":3552,"t":"Introduction","s":"Standards, Docs and Organisation","u":"/standards/scs-0002-v1-standards-docs-org","p":3552},{"i":3559,"t":"SCS-0002 outlines the standardized structure and maintenance processes for easily accessible and\ncomprehensible content of the SCS project.\n","s":"SCS Documentation structure","u":"/standards/scs-0002-v2-standards-docs-org","p":3559},{"i":3580,"t":"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,\ncategorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning\nin a machine-readable YAML format for clarity, traceability, and tool integration.\n","s":"Sovereign Cloud Standards YAML","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","p":3580},{"i":3619,"t":"SCS-0005 outlines the structure and governance of the SCS community by the SCS Project Board and how this is elected.\n","s":"Governance of the SCS community","u":"/standards/scs-0005-v1-project-governance","p":3619},{"i":3649,"t":"Introduction","s":"SCS Flavor Naming Standard","u":"/standards/scs-0100-v1-flavor-naming","p":3649},{"i":3686,"t":"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack\nenvironments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM,\nand Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for\nusability and portability across all SCS flavors.\n","s":"SCS Flavor Naming Standard","u":"/standards/scs-0100-v3-flavor-naming","p":3686},{"i":3725,"t":"Introduction","s":"Regulations for achieving SCS-compatible certification","u":"/standards/scs-0004-v1-achieving-certification","p":3725},{"i":3736,"t":"Introduction","s":"SCS Flavor Naming Standard: Implementation and Testing Notes","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","p":3736},{"i":3754,"t":"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations\nsuch as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and\nactivating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy\naccessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into\nvirtual instances and ensures the availability and quality of entropy in virtual environments, promoting system\nsecurity and efficiency.\n","s":"SCS Entropy","u":"/standards/scs-0101-v1-entropy","p":3754},{"i":3773,"t":"Introduction","s":"SCS Flavor Naming Standard","u":"/standards/scs-0100-v2-flavor-naming","p":3773},{"i":3818,"t":"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating\nsystem images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements,\nimage handling protocols including updating and origin, and licensing/support details. These guidelines ensure\nthat users can understand, access, and utilize OS images effectively, with clear information on features, updates,\nand licensing provided through well-defined metadata properties.\n","s":"SCS Image Metadata","u":"/standards/scs-0102-v1-image-metadata","p":3818},{"i":3838,"t":"Implementation notes","s":"SCS Image Metadata: Implementation and Testing Notes","u":"/standards/scs-0102-w1-image-metadata-implementation-testing","p":3838},{"i":3848,"t":"Implementation notes","s":"SCS Entropy: Implementation and Testing Notes","u":"/standards/scs-0101-w1-entropy-implementation-testing","p":3848},{"i":3862,"t":"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,\nspecifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined\ndeployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard's\nmachine-readable document facilitates automated processing for compliance and integration purposes, promoting\nconsistency and reliability in cloud environments.\n","s":"SCS Standard Images","u":"/standards/scs-0104-v1-standard-images","p":3862},{"i":3886,"t":"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack\nenvironments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific\nconfigurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs:name-vN, scs:cpu-type,\nand scs:diskN-type to detail the flavor's specifications. This standard facilitates guaranteed availability and\nconsistency of flavors, simplifying the deployment process for DevOps teams.\n","s":"SCS Standard Flavors and Properties","u":"/standards/scs-0103-v1-standard-flavors","p":3886},{"i":3911,"t":"Introduction","s":"SCS Standard Images: Implementation Notes","u":"/standards/scs-0104-w1-standard-images-implementation","p":3911},{"i":3921,"t":"Introduction","s":"SSD Flavors","u":"/standards/scs-0110-v1-ssd-flavors","p":3921},{"i":3939,"t":"Introduction","s":"Decisions for the Volume Type Standard","u":"/standards/scs-0111-v1-volume-type-decisions","p":3939},{"i":3954,"t":"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.\n","s":"SONiC Support in SCS","u":"/standards/scs-0112-v1-sonic","p":3954},{"i":3976,"t":"Introduction","s":"Security Groups Decision Record","u":"/standards/scs-0113-v1-security-groups-decision-record","p":3976},{"i":4003,"t":"Introduction","s":"SCS Volume Types","u":"/standards/scs-0114-v1-volume-type-standard","p":4003},{"i":4035,"t":"Introduction","s":"Default Rules for Security Groups","u":"/standards/scs-0115-v1-default-rules-for-security-groups","p":4035},{"i":4058,"t":"Implementation","s":"SCS Key Manager Standard: Implementation and Testing Notes","u":"/standards/scs-0116-w1-key-manager-implementation-testing","p":4058},{"i":4071,"t":"Introduction","s":"SCS Key Manager Standard","u":"/standards/scs-0116-v1-key-manager-standard","p":4071},{"i":4092,"t":"Abstract","s":"SCS Taxonomy of Failsafe Levels","u":"/standards/scs-0118-v1-taxonomy-of-failsafe-levels","p":4092},{"i":4114,"t":"Introduction","s":"Volume Backup Functionality","u":"/standards/scs-0117-v1-volume-backup-service","p":4114},{"i":4131,"t":"Examples of the impact from certain failure scenarios on Cloud Resources","s":"SCS Taxonomy of Failsafe Levels: Examples of Failure Cases and their impact on IaaS and KaaS resources","u":"/standards/scs-0118-w1-example-impacts-of-failure-scenarios","p":4131},{"i":4140,"t":"Abstract","s":"Replacement of the deprecated ceph-ansible tool","u":"/standards/scs-0119-v1-rook-decision","p":4140},{"i":4151,"t":"Introduction","s":"SCS Availability Zones","u":"/standards/scs-0121-v1-Availability-Zones-Standard","p":4151},{"i":4174,"t":"Automated Tests","s":"SCS Availability Zones: Implementation and Testing Notes","u":"/standards/scs-0121-w1-Availability-Zones-Standard","p":4174},{"i":4183,"t":"Abstract","s":"Cluster-API images","u":"/standards/scs-0120-v1-capi-images","p":4183},{"i":4196,"t":"Introduction","s":"Mandatory and Supported IaaS Services","u":"/standards/scs-0123-v1-mandatory-and-supported-IaaS-services","p":4196},{"i":4213,"t":"Abstract","s":"_End-to-End Encryption between Customer Workloads_","u":"/standards/scs-0122-v1-node-to-node-encryption","p":4213},{"i":4247,"t":"Introduction","s":"Standard for the security of IaaS service software","u":"/standards/scs-0124-v1-security-of-iaas-service-software","p":4247},{"i":4264,"t":"Testing or Detecting security updates in software","s":"SCS Standard for the security of IaaS service software: Implementation and Testing Notes","u":"/standards/scs-0124-w1-security-of-iaas-service-software","p":4264},{"i":4271,"t":"Motivation","s":"Using Sonobuoy for KaaS conformance tests","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","p":4271},{"i":4292,"t":"Introduction","s":"Secure Connections","u":"/standards/scs-0125-v1-secure-connections","p":4292},{"i":4338,"t":"The SCS-0210 standard outlines the expected pace at which providers should adopt new Kubernetes versions, aiming\nfor alignment with the rapid development cycle of Kubernetes. Providers must offer the latest minor version within\nfour months of its release and the newest patch version within a week, ensuring users have timely access to security\nupdates, bug fixes, and features. The standard emphasizes the need for expedited updates for critical CVEs and\nexpects providers to thoroughly test new versions before deployment.\n","s":"SCS K8S Version Policy for new Kubernetes versions","u":"/standards/scs-0210-v1-k8s-new-version-policy","p":4338},{"i":4349,"t":"Introduction","s":"SCS K8S Version Policy","u":"/standards/scs-0210-v2-k8s-version-policy","p":4349},{"i":4360,"t":"Implementation notes","s":"SCS K8S Version Policy: Implementation and Testing Notes","u":"/standards/scs-0210-w1-k8s-version-policy-implementation-testing","p":4360},{"i":4368,"t":"The SCS-0211 standard ensures that a default StorageClass with specific characteristics is available to KaaS users.\n","s":"SCS KaaS default storage class","u":"/standards/scs-0211-v2-kaas-default-storage-class","p":4368},{"i":4383,"t":"Implementation notes","s":"SCS KaaS default storage class: Implementation and Testing Notes","u":"/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing","p":4383},{"i":4393,"t":"The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).\nThe standard ensures that the default StorageClass, identified by the \"storageclass.kubernetes.io/is-default-class\"\nannotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or\nhost hardware failures.\n","s":"SCS KaaS default storage class","u":"/standards/scs-0211-v1-kaas-default-storage-class","p":4393},{"i":4408,"t":"Introduction","s":"Requirements for container registries","u":"/standards/scs-0212-v1-requirements-for-container-registries","p":4408},{"i":4425,"t":"Introduction","s":"Kubernetes Nodes Anti Affinity","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","p":4425},{"i":4438,"t":"Introduction","s":"Kubernetes Node Distribution and Availability","u":"/standards/scs-0214-v1-k8s-node-distribution","p":4438},{"i":4449,"t":"Introduction","s":"Kubernetes Node Distribution and Availability","u":"/standards/scs-0214-v2-k8s-node-distribution","p":4449},{"i":4462,"t":"Implementation notes","s":"Kubernetes Node Distribution and Availability: Implementation and Testing Notes","u":"/standards/scs-0214-w1-k8s-node-distribution-implementation-testing","p":4462},{"i":4469,"t":"Introduction","s":"Robustness features for Kubernetes clusters","u":"/standards/scs-0215-v1-robustness-features","p":4469},{"i":4500,"t":"Introduction","s":"Requirements for testing cluster-stacks","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","p":4500},{"i":4523,"t":"Introduction","s":"Kubernetes cluster hardening","u":"/standards/scs-0217-v1-cluster-hardening","p":4523},{"i":4552,"t":"Introduction","s":"Container registry for SCS standard implementation","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","p":4552},{"i":4567,"t":"List of compliant CNI Plugins","s":"KaaS Networking Standard: Implementation Notes","u":"/standards/scs-0219-w1-kaas-networking","p":4567},{"i":4570,"t":"Introduction","s":"KaaS Networking Standard","u":"/standards/scs-0219-v1-kaas-networking","p":4570},{"i":4585,"t":"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign\nCloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed\nexternally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard\nfocuses on delegating authentication to external identity providers and mapping users to roles within SCS for\nauthorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity\nProvider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible.\n","s":"Requirements for SSO identity federation","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","p":4585},{"i":4602,"t":"Introduction","s":"Domain Manager configuration for Keystone","u":"/standards/scs-0302-v1-domain-manager-role","p":4602},{"i":4635,"t":"","s":"Gnocchi as database for metering","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","p":4734},{"i":4753,"t":"for more info. -->","s":"Push-based approach for providing usage data","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","p":4753},{"i":4772,"t":"| Scope versions -> | v3 | v4 | v5.1 |","s":"SCS-compatible IaaS","u":"/standards/scs-compatible-iaas","p":4772},{"i":4774,"t":"| Scope versions -> | v1 |","s":"SCS-compatible KaaS","u":"/standards/scs-compatible-kaas","p":4774},{"i":4776,"t":"| Example: [ { \"displayName\": \"operational\", \"value\": 33 }, { \"displayName\": \"limited\", \"value\": 66 }, { \"displayName\": \"broken\", \"value\": 100 } ] A special severity of type \"maintenance\" is given the exact value of 0. This means: maintenance at 0 operational from 1 to 33 limited from 34 to 66 broken from 67 to 100. A value of 100 is the maximum of the severity value. A severity with the value of 100 MUST always be supplied. This is the highest severity for the system. If no severity with a value of 100 exists, e.g. the highest severity value is set at 90, an Impact with a higher SeverityValue WILL be considered to be an unknown severity.","s":"Severity","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#severity","p":4682},{"i":4709,"t":"Components list their impacts, which they are affected by, as read only. Only an incident creates an impact on a component. Components MUST only list their currently active impacts. An optional at parameter can be supplied, to set a reference time to show all incidents, active at that time, even when they are inactive currently.","s":"Component impacts","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#component-impacts","p":4682},{"i":4711,"t":"Any impact that has the reserved SeverityValue of 0 is a maintenance time slot. As such it MUST include a start and end time. However, both are allowed to be set in the future.","s":"Maintenance","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#maintenance","p":4682},{"i":4713,"t":"Generally POST requests create new resources. These endpoints do not return the new resource, but a unique identifier to the resource e.g. a UUID. In most cases the new resource won't be used directly after creation. Most often list calls are used. If the new resource is used directly, it can be retrieved by the returned identifier. Payloads to POST requests SHALL NOT include ID or Incremental typed fields, it lies in the responsibility of the API server to assign IDs and Incrementals to objects.","s":"Return of POST requests","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#return-of-post-requests","p":4682},{"i":4715,"t":"Most commonly PATCH requests are used to partially or fully change a resource. These requests do not respond with the changed resource, nor an identifier. Both the old state as well as the new state are known on the client at that point in time and if they need to load the actual recent version from the server, the identifier is already known.","s":"Return of PATCH requests","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#return-of-patch-requests","p":4682},{"i":4717,"t":"The PUT requests is most commonly used to update full objects, whereas PATCH is used for partial updates. PATCH is used as the default method for updating resources because it does not require the full object for an update, but does not discourage the use of the complete object.","s":"PATCH vs PUT for updating resources","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#patch-vs-put-for-updating-resources","p":4682},{"i":4719,"t":"The API spec does not include either authentication (AuthN) nor authorization (AuthZ) of any kind. The API server MUST be secured by a reverse/auth proxy.","s":"Authentication and authorization","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#authentication-and-authorization","p":4682},{"i":4722,"t":"Cloud Service Providers offer a variety of products to a customer. Those can include compute resources like virtual machines, networking, and identity and access management. As customers of those services build their applications upon those offered services the service provider needs to ensure a certain quality level of their offerings. This is done by observing the infrastructure. Observability systems leverage different types of telemetry data which include: Metrics: Usually time series data about different parameters of a system which can include e.g. CPU usage, number of active requests, health status, etc. Logs: Messages of software events during runtime Traces: A more developer-oriented form of logging to provide insights into an application or to analyze request flows in distributed systems. Based on those data, an alerting system can be used to send out notifications to an Operations Team if a system behaves abnormally. Based on the telemetry data the Operations Team can find the issue, work on it, and mitigate future incidents.","s":"Introduction","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#introduction","p":4720},{"i":4724,"t":"Currently, only the IaaS Layer of the SCS Reference Implementation has an Observability Stack consisting of tools like Prometheus, Grafana, and Alertmanager as well as several Exporters to extract monitoring data from the several OpenStack components and additional software that is involved in the Reference Implementation. As the Kubernetes as a Service Layer becomes more and more important and the work on the Cluster API approach to create customer clusters progresses further, an observability solution for this layer is also needed. CSP should be able to watch over customer clusters and intervene if a cluster gets in a malfunctioning state. For this, a toolset and architecture are needed which is proposed in this ADR.","s":"Motivation","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#motivation","p":4720},{"i":4726,"t":"A survey was conducted to gather the needs and requirements of a CSP when providing Kubernetes as a Service. The feedback of the survey led to the following requirement on a Kubernetes as a Service Observability System: Telemetry Data that MUST be fetched: CPU, RAM, Disk, Network HTTP Connectivity Metrics Control Plane and Pod metrics (States, Ready, etc.) K8s certs metrics Metrics of underlying node Logs of control plane, kubelet and containerd Telemetry Data that MAY be fetched: K8s resources (exporters, kubestate metrics, cadvisor, parts of the kubelet) Ingress controller exporter (http error rate, cert metrics like expiration date) Telemetry Data that SHOULD NOT BE fetched: Any metrics or logs a CSP does not need to provide support with respect to their SLA with a Customer. Telemetry Data that MUST NOT be fetched: Secrets Customer Specific Workload Metrics The Alerting Mechanism MUST include a default ruleset The Observability Stack MUST run on the CSP Infrastructure The Observability Stack MUST be High Available The Observability Stack MUST be able to observe itself Observed Clusters SHOULD have a low resource impact on the used software to provide telemetry data for the Observability Stack","s":"Requirements","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#requirements","p":4720},{"i":4728,"t":"Use of the dNation Observability Stack as a base​ The dNation monitoring stack offers a lot of basic capabilities needed on an observability stack for Kubernetes like Prometheus Operator, Grafana, Alertmanager, Loki, Promtail and Thanos. Pull-based Architecture​ Each customer cluster has Thanos and Prometheus installed in addition to Thanos and Prometheus on the Observer Cluster. Metrics of a customer cluster are pulled from Thanos (Customer Cluster) for short term queries, as for long term queries the data of all Thanos instances is stored in an external Object Store of the CSP. Push-based Archtitecture​ Here, Thanos and Prometheus are only used on the CSP side to store and manage all observability data. For the customer clusters only the Prometheus Agent will be used. Prometheus Agent will push all metrics of a Customer Cluster to the central Thanos instance and is preserved in an external Object Store. This introduces less complexity and resource consumption on the customer workload clusters. Scope of the Observability Architecture​ The Observability Cluster and Architecture SHOULD be defined in a modular way so that it can be used to not only observe the Kubernetes Layer of an SCS Stack, but every aspect of an SCS Stack. Observing the Observability Infrastructure​ For usage in production, it needs to be possible to observe the Observability Cluster itself. Alerting Rulesets​ Use a mix of kubernetes-mixin alerts and dNation Alerts Ruleset, as they offer an extensive and well reviewed set of default Alerts covering the important Parts of a Kubernetes Deployment (Nodes, Controlplane, K8s Resources, etc.)","s":"Options considered","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#options-considered","p":4720},{"i":4730,"t":"Base the MVP-0 Implementation on the dNation Kubernetes Monitoring Stack. The Push-based Architecture was chosen over the Pull-based Approach. The Observability Stack will be created based on the dNation observability stack The Observability Stack can be used as a standalone component to use with the Kubernetes Layer. It should be possible to observe other parts of an SCS Stack like the status of the OpenStack components, but this will not be mandatory. The Observability Stack should be designed that it is possible to provision two observer clusters side by side, observing each other. To do this is only a recommendation for production usage. The MVP-0 will consist of the following features: Observability data from KaaS Clusters is scraped K8s cluster that hosts observer deployment is deployed S3 compatible bucket as a storage for long term metrics is configured thanos query-frontend is deployed and configured thanos query is deployed and configured thanos receiver is deployed and configured (simple deployment, non HA, without router) thanos ruler is deployed and configured thanos compactor is deployed and configured thanos bucket-web is deployed and configured thanos storegateway is deployed and configured prometheus server is deployed and configured prometheus alertmanager is deployed and configured prometheus black-box exporter is deployed and configured kaas-metric-importer is deployed and configured (service aims to differentiate between intentional deletion of KaaS instances and failures in the KaaS monitoring agent) Alerts are defined on the KaaS Clusters metrics all prometheus alerts are working as expected There exist Dashboards for KaaS Cluster Health KaaS L0 dashboard counters are working correctly Dedicated L0 dashboards are deployed for KaaS and for IaaS monitoring layers There exist Dashboards for SCS services endpoints health (BlackBox exporter) There exist Dashboards for IaaS layer health Automatic Setup of Exporters for Observability of managed K8s clusters KaaS service is mocked VM that will host a mock of KaaS service is deployed a script that deploys a multiple KinD clusters and register them in observer is created Automatic Setup of Thanos sidecar for Observability of IaaS layer (testbed) IaaS service is mocked OSISM testbed is deployed implement an option to deploy thanos sidecar with some simple config in OSISM testbed There exist Dashboards for Harbor Registry Health Alerts are defined on the Harbor Registry metrics","s":"Decisions","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#decisions","p":4720},{"i":4733,"t":"A survey was conducted to gather the needs and requirements of a CSP when providing Kubernetes as a Service. The results of the Survey (Questions with answers) were the following: What is your understanding of a managed Kubernetes Offering: Hassle-Free Installation and Maintenance (customer viewpoint); Providing control plane and worker nodes and responsibility for correct function but agnostic to workload Day0, 1 and 2 (~planning, provisioning, operations) full lifecycle management or let customer manages some parts of that, depending on customer contract What Type and Depth of observability is needed CPU, RAM, HDD and Network usage, Health and Function of Cluster Nodes, control plane and if desired Customer Workload Do you have an observability infrastructure, if yes, how it is built Grafana/Thanos/Prometheus/Loki/Promtail/Alertmanger Stack, i.e. Example Infrastructure Data Must haves CPU, RAM, Disk, Network HTTP Connectivity Metrics Control Plane and Pod metrics (States, Ready, etc.) Workload specific metrics Node Stats K8s resources (exporters, kubestate metrics, cadvisor, parts of the kubelet) Ingress controller exporter (http error rate, cert metrics like expiration date) K8s certs metrics Metrics of underlying node Logs of control plane, kubelet and containerd Must Not haves Secrets, otherwise as much as possible for anomaly detection over long time data Must have Alerts Dependent on SLAs and SLA Types, highly individual Use of kubernetes-mixin alerts and dNation Alerts Ruleset Must NOT Alert on Should not wake people, nothing that does not lead to Action items Observability from Within Or Outside KaaS. How does the architecture look like? Monitoring Infra on CSP Side Data from Customer Clusters and Mon Infra on CSP and KaaS, get both data. KaaS Monitoring can also be used by customer Special Constraints HA Setup in different Clusters on Different Sites","s":"Outcome of the CSP Survey about Requirements for KaaS Observability","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#outcome-of-the-csp-survey-about-requirements-for-kaas-observability","p":4720},{"i":4736,"t":"In the past we noticed missing events in the telemetry stack of OpenStack. This results in situations where the Cloud Service Provider (CSP) may think that a resource is still in use while the owner shut it down, or may not be aware of a resource which has been created. Such inaccurate data is a problem, when it is supposed to be used for billing purposes. This document discusses how such metering data should be stored within the SCS. In particular, it provides rationale for the choice of Gnocchi as time-series database for metering data within SCS.","s":"Introduction","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#introduction","p":4734},{"i":4738,"t":"TSDB, time-series database: Database which is specialised for storing data which is keyed by a timestamp. Popular examples are InfluxDB, Graphite, rrd, and Prometheus. Metering: Collection of usage data of a cloud, for the specific purpose of creating invoices to bill customers for the resources they have allocated. backfilling: The process of adding and modifying data in the past within a time-series database. Metric: A single time-series vector. Typically, a metric represents a single property of a resource, such as CPU usage of an instance. Resource metrics: A group of metrics belonging to a single resource. A compute instance, for instance, may have a metric indicating the number of CPUs allocated, another metric indicating the amount of RAM allocated, etc.","s":"Definitions","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#definitions","p":4734},{"i":4740,"t":"Being able to hold users accountable for the resources they use is a prerequisite for commercially operating a cloud. The SCS project wants to deliver a cloud stack which can be used for that purpose, hence providing reliable metering data is a requirement. As metering data is inherently keyed by time, a time-series database is required. The choice of time-series database is an important one as different databases come with different trade-offs. Not all databases are suitable for the kind of data which is collected in a metering context.","s":"Motivation","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#motivation","p":4734},{"i":4742,"t":"The following requirements for a time-series database exist: MUST support backfilling: As we need to catch up on changes to resources which may have happened during a brief network interruption, we need to be able to modify data after it has been written to the TSDB. MUST be able to handle lots of resources: As billing should happen with a resource-level granularity, we expect a lot of different metrics inside the TSDB. MUST scale to different timescales: We expect to have metrics which change frequently (e.g. object store usage) and metrics which change rarely (e.g. cinder volume sizes). The TSDB must be able to cope with both types of metrics efficiently. SHOULD provide an efficient way to query all currently alive resources. SHOULD allow truncation of storage to remove old data. MUST be available under an appropriate Open Source license, even for productive use cases.","s":"Design Considerations","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#design-considerations","p":4734},{"i":4744,"t":"Using Gnocchi​ Gnocchi is a time-series database which has its origins in the OpenStack ecosystem. It supports all requirements except truncation, which might have to be implemented. Using Prometheus​ Prometheus is a widely used time-series database with its focus on monitoring and incident response. While it is considered efficient for this use-case, it has shortcomings which make it unsuitable for the metering use case: Explicit recommendation against high-cardinality metrics: As we would have to label metrics by resource IDs and project IDs, we have to expect a very high cardinality, also with a significant amount of metric churn. Backfilling, albeit possible, is not well-supported. Using InfluxDB​ InfluxDB is a widely used time-series database with its focus on monitoring. In contrast to Prometheus, it does support backfilling. However, like Prometheus, it seems to run into scalability issues in high-cardinality scenarios. In addition, clustering is only available in commercial licensing options. Creating a custom TSDB implementation​ A custom TSDB implementation is a non-trivial project to pursue.","s":"Options","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#options","p":4734},{"i":4746,"t":"We use Gnocchi. According to research, it mostly fulfills the requirements. While some small development efforts may be needed, to make it fully usable, the amount of work is anticipated much less than making Prometheus or Influx fit the bill (due to backfilling / cardinality scaling constraints), let alone rolling a custom implementation.","s":"Decision","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#decision","p":4734},{"i":4748,"t":"What will be the granularity of the events meta information? If we decide to use resource metadata as a place to store slow-changing information (e.g. instance flavors, volume sizes), we need to know what the granularity of that is.","s":"Open questions","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#open-questions","p":4734},{"i":4750,"t":"SCS-0411-v1","s":"Related Documents","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#related-documents","p":4734},{"i":4752,"t":"None (this is a decision record).","s":"Conformance Tests","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#conformance-tests","p":4734},{"i":4755,"t":"In the past we noticed missing events in the telemetry stack of OpenStack. This results in situations where the Cloud Service Provider (CSP) may think that a resource is still in use while the owner shut it down, or may not be aware of a resource which has been created. Such inaccurate data is a problem, when it is supposed to be used for billing purposes. This document discusses how such metering data should be made available to the cloud service provider for forwarding into their own billing solution.","s":"Introduction","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#introduction","p":4753},{"i":4757,"t":"Push-based flow: In a push-based flow, the system generating data actively sends that data to a consumer. Pull-based flow: In a pull-based flow, the system generating data waits for the system consuming the data to ask for that data. Metering: Collection of usage data of a cloud, for the specific purpose of creating invoices to bill customers for the resources they have allocated. Billing: The entire process of creation, management and sending of invoices generated from metering data.","s":"Definitions","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#definitions","p":4753},{"i":4759,"t":"Being able to bill users for the resources they use is a prerequisite for commercially operating a cloud. The SCS project wants to deliver a cloud stack which can be used for that purpose, hence providing reliable metering data is a requirement. We generally expect that cloud providers already have some kind of customer-relation management or billing system in place. Hence, it is important that the SCS is not too opinionated on this implementation detail, but provides a system which can easily interface with other systems. This is similar to how the SCS specified the monitoring stack.","s":"Motivation","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#motivation","p":4753},{"i":4761,"t":"The following requirements exist for the process for providing metrics to the cloud service provider: MUST scale to different timescales: We expect to have metrics which change frequently (e.g. object store usage) and metrics which change rarely (e.g. cinder volume sizes).","s":"Design Considerations","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#design-considerations","p":4753},{"i":4763,"t":"Push-based flow​ In a push-based flow, the to-be-implemented metering system pushes events to the sink as soon as it is reasonably confident that the event can be used for billing purposes. Poll-based flow​ In the poll-based flow, whichever system the CSP runs would be responsible for polling the metering API in a frequency sufficient to capture all data with sufficient granularity.","s":"Options","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#options","p":4753},{"i":4765,"t":"What is necessary to extend the availability of sending to various sinks? How does the configuration look like that is needed to push to a sink from the same type that will be already implemented?","s":"Open questions","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#open-questions","p":4753},{"i":4767,"t":"As we need to support very different time scales of data, the push-based flow is more suitable: it allows the producer of the data, which knows about the interval in which it changes, when to provide new data to the consumer. In contrast to that, a poll-based flow would need the consumer to know about change intervals, or alternatively poll in the highest change frequency ever expected.","s":"Decision","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#decision","p":4753},{"i":4769,"t":"SCS-0410-v1","s":"Related Documents","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#related-documents","p":4753},{"i":4771,"t":"None (this is a decision record).","s":"Conformance Tests","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#conformance-tests","p":4753},{"i":4773,"t":"Scope versions -> v3 v4 v5.1 State Deprecated Effective Effective Stabilized at 2024-02-28 2024-02-28 2024-12-19 Modules OpenStack Powered Compute v2022.11 X X X scs-0100-v3.1: Flavor naming v3.1 X X X scs-0101-v1: Entropy v1 X X scs-0102-v1: Image metadata v1 X X X scs-0103-v1: Standard flavors X X scs-0104-v1: Standard images X (image_spec) X (image_spec) scs-0114-v1: Volume Types X scs-0115-v1: Default rules for security groups X scs-0116-v1: Key manager X scs-0117-v1: Volume backup X scs-0121-v1: Availability Zones X scs-0123-v1: Mandatory and Supported IaaS Services X scs-0302-v1: Domain Manager Role X","s":"SCS-compatible IaaS","u":"/standards/scs-compatible-iaas","h":"","p":4772},{"i":4775,"t":"Scope versions -> v1 State Effective Stabilized at 2024-11-26 Modules CNCF Kubernetes conformance X scs-0210-v2: Kubernetes version policy X scs-0214-v2: Kubernetes node distribution and availability X scs-0219-v1: KaaS networking X","s":"SCS-compatible KaaS","u":"/standards/scs-compatible-kaas","h":"","p":4774},{"i":4778,"t":"Very short introduction about the topic of this document.","s":"Abstract","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#abstract","p":4776},{"i":4780,"t":"Example (abbr. Ex) This is the description for an example terminology.","s":"Terminology","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#terminology","p":4776},{"i":4782,"t":"What is the issue that we're seeing that is motivating this decision or change?","s":"Context","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#context","p":4776},{"i":4784,"t":"What is the decision that we're proposing and/or doing? Should also include reasoning for this decision","s":"Decision","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#decision","p":4776},{"i":4786,"t":"What becomes easier or more difficult to do because of this change?","s":"Consequences","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#consequences","p":4776},{"i":4788,"t":"Related Documents, OPTIONAL","s":"Related Documents","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#related-documents","p":4776},{"i":4791,"t":"The Sovereign Cloud Stack project intends to standardise an infrastructure-as-a-service (IaaS) layer. In order to economically sustainably run a cloud, it is generally useful to know which user or tenant consumes which amount of resources in which time frame. Similarly to how the SCS provides an interface for connecting monitoring services to detect outages, this standard aims for providing an interface for connecting systems which aggregate customer resource usage.","s":"Introduction","u":"/standards/scs-0412-v1-metering-json","h":"#introduction","p":4789},{"i":4793,"t":"In general, users of the SCS (i.e. cloud operators) may already have different systems in place for tracking customer relationships as well as billing. Those systems are unlikely to have a uniform interface across all possible implementations. Likewise, those systems are unlikely to have a way to interface with OpenStack, the reference IaaS layer in SCS. In order to provide SCS operators with a way to integrate the SCS IaaS layer with their billing, this document shall provide a standard format, upon which shim conversion layers (to whichever billing system is in place) can be built.","s":"Motivation","u":"/standards/scs-0412-v1-metering-json","h":"#motivation","p":4789},{"i":4795,"t":"In order to define a standard, the various options for formats need to be considered. However, all formats also come with different implementation costs. These aspects are weighed in this section.","s":"Design Considerations","u":"/standards/scs-0412-v1-metering-json","h":"#design-considerations","p":4789},{"i":4797,"t":"Use Ceilometer HTTP hook format​ The OpenStack Ceilometer project, which serves as a hub for all things telemetry and metering, provides an HTTP-based hook to extract metering data. This hook receives JSON-formatted data. Using this data has the advantage that we do not need to implement another component to translate the format which may in turn be a point of failure. Use another format​ In this option, a format for metering data is researched and reused, or defined and specified by the SCS project. This option was not explored deeply, for the reasons explained in the decision.","s":"Options considered","u":"/standards/scs-0412-v1-metering-json","h":"#options-considered","p":4789},{"i":4799,"t":"None.","s":"Open questions","u":"/standards/scs-0412-v1-metering-json","h":"#open-questions","p":4789},{"i":4801,"t":"We chose the Ceilometer HTTP hook format, described below, for the following reasons: Ceilometer is a component which needs to be there anyway for successful metering of OpenStack. Re-using the format makes sense. Using any other format requires a translation layer. However, users will likely need their own translation layer anyway, to integrate the metering with their own infrastructure. Hence, it makes more sense to expose the data from Ceilometer directly. A notable downside of this approach is that a change in Ceilometers format will inevitably cause issues in all downstream consumers.","s":"Decision","u":"/standards/scs-0412-v1-metering-json","h":"#decision","p":4789},{"i":4803,"t":"SCS-0410-v1 SCS-0411-v1","s":"Related Documents","u":"/standards/scs-0412-v1-metering-json","h":"#related-documents","p":4789},{"i":4805,"t":"None.","s":"Conformance Tests","u":"/standards/scs-0412-v1-metering-json","h":"#conformance-tests","p":4789},{"i":4808,"t":"Introduction","s":"Introduction","u":"/standards/scs-XXXX-vN-standard-template","h":"#introduction","p":4806},{"i":4810,"t":"Example (abbr. Ex) This is the description for an example terminology.","s":"Terminology","u":"/standards/scs-XXXX-vN-standard-template","h":"#terminology","p":4806},{"i":4812,"t":"Motivation","s":"Motivation","u":"/standards/scs-XXXX-vN-standard-template","h":"#motivation","p":4806},{"i":4814,"t":"OPTIONAL","s":"Design Considerations","u":"/standards/scs-XXXX-vN-standard-template","h":"#design-considerations","p":4806},{"i":4816,"t":"Option 1​ Option 1 description Option 2​ Option 2 description","s":"Options considered","u":"/standards/scs-XXXX-vN-standard-template","h":"#options-considered","p":4806},{"i":4818,"t":"RECOMMENDED","s":"Open questions","u":"/standards/scs-XXXX-vN-standard-template","h":"#open-questions","p":4806},{"i":4820,"t":"What is the essence of this standard? Adjust heading accordingly.","s":"Standard","u":"/standards/scs-XXXX-vN-standard-template","h":"#standard","p":4806},{"i":4822,"t":"Related Documents, OPTIONAL","s":"Related Documents","u":"/standards/scs-XXXX-vN-standard-template","h":"#related-documents","p":4806},{"i":4824,"t":"Conformance Tests, OPTIONAL","s":"Conformance Tests","u":"/standards/scs-XXXX-vN-standard-template","h":"#conformance-tests","p":4806},{"i":4826,"t":"Standards are the core deliverable of SCS. By standardizing the open source software components of a cloud computing stack, their versions, how they are to be configured, deployed and utilized, SCS guarantees the reproducibility of a certain behavior of this technology. SCS standards are discussed, developed and maintained in the community by the corresponding teams (see Track in the table below), which naturally include existing users of SCS. *Legend to the column headings and entries: Document states: Draft, Effective, Deprecated (and no longer effective) Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future Entries in the effective column marked with a † will turn deprecated in the near future Standard Track Description Draft Effective Deprecated* scs-0001 Global Sovereign Cloud Standards - v1 - scs-0002 Global Standards, Docs and Organisation v2 v1 - scs-0003 Global Sovereign Cloud Standards YAML v1 - - scs-0004 Global Regulations for achieving SCS-compatible certification v1 - - scs-0005 Global Governance of the SCS community v1 - - scs-0100 IaaS SCS Flavor Naming Standard - v3 v1, v2 Supplement: Implementation and Testing Notes w1 - - scs-0101 IaaS SCS Entropy - v1 - Supplement: Implementation and Testing Notes w1 - - scs-0102 IaaS SCS Image Metadata - v1 - Supplement: Implementation and Testing Notes w1 - - scs-0103 IaaS SCS Standard Flavors and Properties - v1 - scs-0104 IaaS SCS Standard Images - v1 - Supplement: Implementation Notes w1 - - scs-0110 IaaS SSD Flavors - v1 - scs-0111 IaaS Decisions for the Volume Type Standard v1 - - scs-0112 IaaS SONiC Support in SCS v1 - - scs-0113 IaaS Security Groups Decision Record v1 - - scs-0114 IaaS SCS Volume Types - v1 - scs-0115 IaaS Default Rules for Security Groups - v1 - scs-0116 IaaS SCS Key Manager Standard - v1 - Supplement: Implementation and Testing Notes w1 - - scs-0117 IaaS Volume Backup Functionality - v1 - scs-0118 IaaS SCS Taxonomy of Failsafe Levels v1 - - Supplement: Examples of Failure Cases and their impact on IaaS and KaaS resources w1 - - scs-0119 IaaS Replacement of the deprecated ceph-ansible tool v1 - - scs-0120 IaaS Cluster-API images v1 - - scs-0121 IaaS SCS Availability Zones - v1 - Supplement: Implementation and Testing Notes w1 - - scs-0122 IaaS End-to-End Encryption between Customer Workloads v1 - - scs-0123 IaaS Mandatory and Supported IaaS Services - v1 - scs-0124 IaaS Standard for the security of IaaS service software v1 - - Supplement: SCS Standard for the security of IaaS service software: Implementation and Testing Notes w1 - - scs-0125 IaaS Secure Connections v1 - - scs-0200 KaaS Using Sonobuoy for KaaS conformance tests v1 - - scs-0210 KaaS SCS K8S Version Policy - v2 v1 Supplement: Implementation and Testing Notes w1 - - scs-0211 KaaS SCS KaaS default storage class v2 v1 - Supplement: Implementation and Testing Notes w1 - - scs-0212 KaaS Requirements for container registries v1 - - scs-0213 KaaS Kubernetes Nodes Anti Affinity v1 - - scs-0214 KaaS Kubernetes Node Distribution and Availability - v1, v2 - Supplement: Implementation and Testing Notes w1 - - scs-0215 KaaS Robustness features for Kubernetes clusters v1 - - scs-0216 KaaS Requirements for testing cluster-stacks v1 - - scs-0217 KaaS Kubernetes cluster hardening v1 - - scs-0218 KaaS Container registry for SCS standard implementation v1 - - scs-0219 KaaS KaaS Networking Standard - v1 - Supplement: Implementation Notes w1 - - scs-0300 IAM Requirements for SSO identity federation - v1 - scs-0301 IAM Naming for domains/groups/roles/project when onboarding new customers v1 - - scs-0302 IAM Domain Manager configuration for Keystone - v1 - Supplement: Domain Manager implementation notes w1 - - scs-0400 Ops Status Page create decision v1 - - scs-0401 Ops Status page reference implementation decision v1 - - scs-0402 Ops Status page OpenAPI decision v1 - - scs-0403 Ops Architecture for the Cloud Service provider Observability System for the KaaS Layer v1 - - scs-0410 Ops Gnocchi as database for metering v1 - - scs-0411 Ops Push-based approach for providing usage data v1 - - scs-0412 Ops Exposition of IaaS metering data as JSON v1 - -","s":"Overview","u":"/standards/standards/overview","h":"","p":4825},{"i":4829,"t":"In this section, users will find helpful information and practical guides for working with SCS clouds. We provide insights into various application use cases, migration tutorials between different SCS cloud service providers, and showcase ways to communicate remotely with your cloud without a user interface. Discover best practices to make the most of your cloud, from introductions to specific applications to advanced use cases. Stay tuned for upcoming content designed to simplify your cloud experience.","s":"Welcome to the User Documentation of the Sovereign Cloud Stack (SCS)","u":"/user-docs/","h":"#welcome-to-the-user-documentation-of-the-sovereign-cloud-stack-scs","p":4827},{"i":4831,"t":"openDesk has many configuration options. You can view them and their default values in your copy of openDesk:","s":"Configuration","u":"/user-docs/application-examples/opendesk-on-scs/configuration","h":"","p":4830},{"i":4833,"t":"For the configuration of the basic components please have a look at the .yaml files in helmfile/environments/default. $ ls helmfile/environments/default cache.yaml certificate.yaml charts.yaml cluster.yaml database.yaml debug.yaml enterprise.yaml functional.yaml global.generated.yaml global.gotmpl _helper.yaml images.yaml ingress.yaml monitoring.yaml objectstores.yaml opendesk_main.gotmpl persistence.yaml replicas.yaml repositories.yaml resources.yaml secrets.gotmpl security.yaml selinux.yaml smtp.gotmpl theme.gotmpl turn.gotmpl To overwrite a specific default setting, copy the snippet into you own values.yaml.gotmpl file and change the values to your need.","s":"Basic components","u":"/user-docs/application-examples/opendesk-on-scs/configuration","h":"#basic-components","p":4830},{"i":4835,"t":"The settings of the apps reside underneath helmfile/apps (just like their helmfiles). As you see, the different apps have different numbers of values files. Review them carefully and edit your own values.yaml.gotmpl to overwrite any default setting. $ tree helmfile/apps/ helmfile/apps/ ├── collabora │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ └── values.yaml.gotmpl ├── cryptpad │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ └── values.yaml.gotmpl ├── element │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ ├── values-element.yaml.gotmpl │ ├── values-synapse-web.yaml.gotmpl │ ├── values-synapse.yaml.gotmpl │ └── values-well-known.yaml.gotmpl ├── intercom-service │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ └── values.yaml.gotmpl ├── jitsi │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ └── values-jitsi.yaml.gotmpl ├── migrations-post │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ └── values.yaml.gotmpl ├── migrations-pre │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ └── values.yaml.gotmpl ├── nextcloud │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ ├── values-nextcloud-mgmt.yaml.gotmpl │ └── values-nextcloud.yaml.gotmpl ├── nubus │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ ├── values-nubus.yaml.gotmpl │ ├── values-opendesk-customization.yaml.gotmpl │ ├── values-opendesk-images.yaml.gotmpl │ └── values-opendesk-keycloak-bootstrap.yaml.gotmpl ├── openproject │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ └── values.yaml.gotmpl ├── openproject-bootstrap │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ └── values.yaml.gotmpl ├── open-xchange │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ ├── values-dovecot.yaml.gotmpl │ ├── values-openxchange-bootstrap.yaml.gotmpl │ ├── values-openxchange-enterprise-contact-picker.yaml.gotmpl │ └── values-openxchange.yaml.gotmpl ├── provisioning │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ └── values-oxconnector.yaml.gotmpl ├── services │ ├── helmfile-child.yaml.gotmpl │ ├── helmfile.yaml.gotmpl │ ├── values-certificates.yaml.gotmpl │ ├── values-clamav-distributed.yaml.gotmpl │ ├── values-clamav-simple.yaml.gotmpl │ ├── values-dkimpy.yaml.gotmpl │ ├── values-home.yaml.gotmpl │ ├── values-mariadb.yaml.gotmpl │ ├── values-memcached.yaml.gotmpl │ ├── values-minio.yaml.gotmpl │ ├── values-otterize.yaml.gotmpl │ ├── values-postfix.yaml.gotmpl │ ├── values-postgresql.yaml.gotmpl │ └── values-redis.yaml.gotmpl └── xwiki ├── helmfile-child.yaml.gotmpl ├── helmfile.yaml.gotmpl └── values.yaml.gotmpl","s":"Apps","u":"/user-docs/application-examples/opendesk-on-scs/configuration","h":"#apps","p":4830},{"i":4837,"t":"Contributions to this documentation are welcome and can be submitted to this repository.","s":"Contribute","u":"/user-docs/application-examples/opendesk-on-scs/contribute","h":"","p":4836},{"i":4839,"t":"This guide takes you through the steps to deploy openDesk on a Sovereign Cloud Stack Kubernetes cluster. openDesk is a Kubernetes based, open-source and cloud-native digital workplace suite provided by the Zentrum für Digitale Souveränität der Öffentlichen Verwaltung (ZenDiS) GmbH. It bundles a number of modular software components for collaboration in organizations, such as an identity and access management system with a web based portal (Univention Nubus), a groupware (OX App Suite), tools for knowledge and project management (XWiki, OpenProject), file sharing (Nextcloud), video conferencing (Jitsi), chat (Element), and weboffice tools for online editing (Collabora, Cryptpad). An increasing number of public administrations migrate their work environments to free/libre and/or open source-based solutions. These environments are nowadays built on the container orchestration software Kubernetes. Public administrations strive to be as independent as possible from a few large global companies. Therefore, it is important for them to also have a choice of implementations of the underlying stack for their deployments. The same criteria of openness, standardization and interoperability that apply to the actual tools delivered by openDesk can be applied to the underlying cluster infastructure when running on a Sovereign Cloud Stack cluster. This howto describes the steps to deploy an openDesk environment from a local machine to a Kubernetes cluster in the simplest possible way. It is meant to support Kubernetes beginners in getting started with a deployment in SCS. The goal is to get a single node openDesk installation with a portal and a configurable number of modules that are accessible via a web browser. openDesk also provides information about deployment via Gitlab CI which is not covered here. Please refer to the openDesk documentation for further details.","s":"Overview","u":"/user-docs/application-examples/opendesk-on-scs/overview","h":"","p":4838},{"i":4841,"t":"Please note the general Getting Started documentation by openDesk.","s":"Getting started: Deployment from a local machine","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"","p":4840},{"i":4843,"t":"Clone the openDesk repository to your local computer: git clone https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk cd opendesk","s":"Clone the openDesk repository","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#clone-the-opendesk-repository","p":4840},{"i":4845,"t":"Create your own directory for one or more environments: mkdir -p helmfile/environments/example-env/dev/ In the folder you created, add one or more files with the configuration for your environment, e.g. values.yaml.gotmpl (see the Getting Started chapter for an example). Reference the environment you want to deploy in helmfile.yaml: cat helmfile.yaml <<__EOF__ example-env: values: - \"helmfile/environments/example-env/dev/*.yaml.gotmpl\" __EOF__","s":"Add settings for your environment","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#add-settings-for-your-environment","p":4840},{"i":4847,"t":"Decide which components you want to deploy. If you start with some apps only, you can enable the rest of them later. In the example configuration below all apps are enabled for the initial rollout.","s":"Choose your components","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#choose-your-components","p":4840},{"i":4849,"t":"You can use the following example settings as a starting point for your helmfile/environments/example-env/dev/values.yaml.gotmpl file. Please see the configuration chapter for more details. {{/* SPDX-FileCopyrightText: 2024 Zentrum für Digitale Souveränität der Öffentlichen Verwaltung (ZenDiS) GmbH SPDX-FileCopyrightText: 2023 Bundesministerium des Innern und für Heimat, PG ZenDiS \"Projektgruppe für Aufbau ZenDiS\" SPDX-License-Identifier: Apache-2.0 */}} --- grafana: dashboards: annotations: \"grafana-dashboard-folder\": \"openDesk: {{ env \"NAMESPACE\" | default \"Main\" }}\" enabled: true functional: authentication: twoFactor: # Define a list of groups to enable 2FA for. # Note: Removing a group from the list will not disable 2FA for the removed group. groups: [] certificate: issuerRef: name: \"letsencrypt-prod\" wildcard: true ingress: ingressClassName: \"nginx\" persistence: storageClassNames: RWX: \"csi-cinder-sc-delete\" RWO: \"csi-cinder-sc-delete\" smtp: host: \"host.example-relay.org\" username: \"some-account\" port: 587 turn: server: host: \"turn.example.org\" port: \"3478\" tls: host: \"turn.example.org\" port: \"5349\" cluster: service: type: \"ClusterIP\" api: domain: \"api.example.org\" port: 6443 networking: ingressGatewayIP: \"YOUR-PUBLIC-IP\" prometheus: serviceMonitors: enabled: true podMonitors: enabled: true prometheusRules: enabled: true security: clusterPostfix: namespace: \"swp-cross-instance-mail\" debug: enabled: true databases: oxAppsuite: host: \"mariadb\" # DB name has to set or else \"configdb\" will used while \"openxchange\" is created. name: \"openxchange\" username: \"root\" collabora: enabled: true cryptpad: enabled: true element: enabled: true intercom: enabled: true jitsi: enabled: true nextcloud: enabled: true openproject: enabled: true oxAppsuite: enabled: true oxConnector: enabled: true xwiki: enabled: true ...","s":"Basic configuration","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#basic-configuration","p":4840},{"i":4851,"t":"Create a namespace in your SCS cluster: kubectl create namespace your-namespace","s":"Namespace","u":"/user-docs/application-examples/opendesk-on-scs/getting_started","h":"#namespace","p":4840},{"i":4853,"t":"Create an ingress resource: cat >ingress-resource.yaml </dev/nul",{"_index":3922,"t":{"942":{"position":[[3125,11]]},"1833":{"position":[[3125,11]]},"2966":{"position":[[3125,11]]}}}],["2@2(peon).osd",{"_index":6936,"t":{"1698":{"position":[[1103,13]]}}}],["2@rbd",{"_index":7167,"t":{"1716":{"position":[[738,5],[1401,5],[1452,5]]}}}],["2].testbed.osism.xyz",{"_index":5281,"t":{"1266":{"position":[[2764,20]]}}}],["2^30",{"_index":10828,"t":{"3826":{"position":[[486,4]]}}}],["2a12b545",{"_index":8154,"t":{"2250":{"position":[[984,8]]},"2252":{"position":[[2555,8]]}}}],["2a33a889",{"_index":7240,"t":{"1743":{"position":[[147,8]]}}}],["2a4a82a879bb",{"_index":4705,"t":{"1177":{"position":[[1178,12],[1549,12],[1755,12],[2305,12],[2548,12],[2916,12],[3022,12]]}}}],["2be6b661f39c",{"_index":4782,"t":{"1179":{"position":[[146,12],[270,12],[321,12],[674,12],[803,12],[854,12],[1396,12],[1576,12],[1627,12]]}}}],["2c",{"_index":10525,"t":{"3698":{"position":[[2363,2]]},"3700":{"position":[[376,2],[389,2],[404,2],[418,2],[432,2],[447,2]]},"3702":{"position":[[1604,2],[1617,2],[1630,2],[1650,2],[1697,2],[1719,2],[1757,2],[1776,2],[1845,2],[1862,2],[1907,2],[1924,2],[1952,2],[1965,2],[2070,2],[2086,2],[2152,2]]},"3708":{"position":[[272,2],[285,2],[302,2]]},"3710":{"position":[[661,2],[723,2],[784,2],[831,2],[925,2]]},"3712":{"position":[[1891,2],[1904,2],[1919,2],[1935,2],[1952,2],[1970,2],[1989,2],[2009,2],[2029,2],[2050,2]]},"3720":{"position":[[21,2]]},"3785":{"position":[[2061,2]]},"3787":{"position":[[376,2],[389,2],[404,2],[418,2],[432,2],[447,2]]},"3789":{"position":[[1463,2],[1476,2],[1489,2],[1509,2],[1556,2],[1578,2],[1616,2],[1635,2],[1704,2],[1721,2],[1766,2],[1783,2],[1811,2],[1824,2],[1929,2],[1945,2],[2044,2],[2131,2],[2197,2]]},"3801":{"position":[[260,2],[273,2],[290,2]]},"3803":{"position":[[648,2],[710,2],[771,2],[818,2],[912,2]]},"3805":{"position":[[989,2],[1002,2],[1017,2],[1033,2],[1050,2],[1068,2],[1087,2],[1107,2],[1127,2],[1148,2]]},"3813":{"position":[[21,2]]}}}],["2c9e0e4ef8d44c36807df50b06b3c81d",{"_index":231,"t":{"28":{"position":[[596,32]]}}}],["2c:3.5:10n",{"_index":10346,"t":{"3663":{"position":[[366,10]]}}}],["2c:4",{"_index":10362,"t":{"3665":{"position":[[1515,5],[1560,5],[1577,5],[1605,5],[1618,4],[1723,4]]}}}],["2c:4:1.5n",{"_index":10367,"t":{"3665":{"position":[[1990,9]]}}}],["2c:4:10",{"_index":10358,"t":{"3665":{"position":[[1270,8],[1283,8],[1372,7],[1410,7]]},"3669":{"position":[[647,7],[709,7],[729,7],[776,7]]}}}],["2c:4:10n",{"_index":10334,"t":{"3661":{"position":[[1709,8]]},"3663":{"position":[[353,8]]},"3665":{"position":[[1257,8]]},"3667":{"position":[[260,8],[273,8],[290,8]]},"3671":{"position":[[882,8],[895,8],[910,8],[926,8],[943,8],[961,8],[980,8],[1000,8],[1020,8],[1041,8]]},"3675":{"position":[[21,8]]}}}],["2c:4:3x",{"_index":10365,"t":{"3665":{"position":[[1739,7],[1837,8]]}}}],["2c:4:3x10",{"_index":10359,"t":{"3665":{"position":[[1303,10],[1350,10],[1924,9]]}}}],["2c:4:n",{"_index":10361,"t":{"3665":{"position":[[1429,6],[1498,6]]}}}],["2c:4o:10n",{"_index":10348,"t":{"3663":{"position":[[395,9]]}}}],["2c:4ou:10n",{"_index":10350,"t":{"3663":{"position":[[424,10]]}}}],["2c:4u:10n",{"_index":10347,"t":{"3663":{"position":[[381,9]]}}}],["2c:4uo:10n",{"_index":10349,"t":{"3663":{"position":[[409,10]]}}}],["2d",{"_index":8864,"t":{"2684":{"position":[[35,2]]}}}],["2d08e835",{"_index":8228,"t":{"2254":{"position":[[1407,8]]}}}],["2dfc3916",{"_index":8188,"t":{"2252":{"position":[[2052,8]]}}}],["2e0e",{"_index":4707,"t":{"1177":{"position":[[1248,4],[1383,4],[1434,4],[1482,4],[2147,4],[2400,4],[2643,4],[2685,4],[2856,4]]}}}],["2e6227aa",{"_index":7000,"t":{"1702":{"position":[[232,8]]}}}],["2f25f55f",{"_index":5142,"t":{"1236":{"position":[[587,8],[719,8]]}}}],["2fa",{"_index":11942,"t":{"4849":{"position":[[665,3],[730,3]]}}}],["2gib",{"_index":10935,"t":{"3928":{"position":[[1517,4]]}}}],["2it",{"_index":10530,"t":{"3698":{"position":[[2464,3]]},"3785":{"position":[[2162,3]]}}}],["2it:4:10n",{"_index":10340,"t":{"3661":{"position":[[1810,9]]}}}],["2k",{"_index":11659,"t":{"4560":{"position":[[4597,3]]}}}],["2l",{"_index":10528,"t":{"3698":{"position":[[2402,2]]},"3785":{"position":[[2100,2]]}}}],["2l:4:10n",{"_index":10337,"t":{"3661":{"position":[[1748,8]]}}}],["2li",{"_index":10529,"t":{"3698":{"position":[[2415,3]]},"3785":{"position":[[2113,3]]}}}],["2li:4:10n",{"_index":10338,"t":{"3661":{"position":[[1761,9]]}}}],["2m",{"_index":3285,"t":{"812":{"position":[[441,3]]}}}],["2m46",{"_index":2522,"t":{"493":{"position":[[1050,5]]}}}],["2m51",{"_index":3046,"t":{"692":{"position":[[341,5],[421,5]]},"747":{"position":[[260,5],[340,5]]}}}],["2nd",{"_index":3357,"t":{"854":{"position":[[529,3]]},"2027":{"position":[[737,3]]},"2048":{"position":[[682,3],[1758,3],[2212,3],[3546,3]]}}}],["2t",{"_index":10527,"t":{"3698":{"position":[[2376,2]]},"3785":{"position":[[2074,2]]}}}],["2t:4:10n",{"_index":10335,"t":{"3661":{"position":[[1722,8]]}}}],["2v",{"_index":111,"t":{"12":{"position":[[306,2]]},"15":{"position":[[304,2]]},"557":{"position":[[259,2],[274,2],[367,2],[378,2]]},"588":{"position":[[1186,2],[1229,2]]},"894":{"position":[[1314,2],[1628,2],[2174,2],[2356,2]]},"898":{"position":[[129,2],[187,2]]},"932":{"position":[[2072,2]]},"1003":{"position":[[171,2]]},"1005":{"position":[[2451,2],[2567,2]]},"1007":{"position":[[292,2]]},"1752":{"position":[[1314,2],[1628,2],[2174,2],[2356,2]]},"1756":{"position":[[129,2],[187,2]]},"1823":{"position":[[2072,2]]},"1894":{"position":[[171,2]]},"1896":{"position":[[2451,2],[2567,2]]},"1898":{"position":[[292,2]]},"2956":{"position":[[2072,2]]},"3698":{"position":[[2389,2]]},"3704":{"position":[[638,2],[658,2]]},"3785":{"position":[[2087,2]]},"3791":{"position":[[235,2],[245,2],[345,2],[355,2],[486,2],[497,2]]},"3898":{"position":[[97,2],[241,2],[266,2],[408,2]]},"3900":{"position":[[109,2],[261,2],[454,2]]},"3930":{"position":[[31,2]]}}}],["2v:16",{"_index":10476,"t":{"3677":{"position":[[488,6]]}}}],["2v:16:50",{"_index":10477,"t":{"3677":{"position":[[499,8]]}}}],["2v:4",{"_index":10461,"t":{"3677":{"position":[[347,5]]}}}],["2v:4:10",{"_index":10462,"t":{"3677":{"position":[[357,7]]}}}],["2v:4:10n",{"_index":10336,"t":{"3661":{"position":[[1735,8]]}}}],["2v:4:20",{"_index":99,"t":{"12":{"position":[[194,7]]},"15":{"position":[[192,7]]},"894":{"position":[[2328,10]]},"1752":{"position":[[2328,10]]}}}],["2v:8",{"_index":10449,"t":{"3677":{"position":[[237,5]]}}}],["2v:8:20",{"_index":10450,"t":{"3677":{"position":[[247,7]]}}}],["2vcpu",{"_index":4275,"t":{"1005":{"position":[[2297,6]]},"1896":{"position":[[2297,6]]}}}],["2x",{"_index":4388,"t":{"1040":{"position":[[747,2],[785,2]]},"1042":{"position":[[785,2],[1056,2]]},"1105":{"position":[[486,2]]},"1107":{"position":[[214,2],[278,2]]},"1109":{"position":[[225,2]]},"1111":{"position":[[225,2],[289,2]]},"1113":{"position":[[278,2]]},"1118":{"position":[[682,2]]},"2171":{"position":[[1074,3]]}}}],["2x200gb",{"_index":10439,"t":{"3675":{"position":[[452,7]]},"3720":{"position":[[455,7]]},"3813":{"position":[[452,7]]}}}],["2x200p_a1",{"_index":10633,"t":{"3720":{"position":[[397,9]]},"3813":{"position":[[394,9]]}}}],["3",{"_index":108,"t":{"12":{"position":[[284,1],[315,1]]},"15":{"position":[[282,1],[313,1]]},"28":{"position":[[1484,1],[1522,1]]},"143":{"position":[[637,1]]},"169":{"position":[[997,1]]},"173":{"position":[[1138,1],[2031,1]]},"249":{"position":[[1528,2],[1587,1]]},"364":{"position":[[1063,2],[1588,1]]},"551":{"position":[[2416,2]]},"584":{"position":[[421,1]]},"588":{"position":[[1489,1]]},"887":{"position":[[9427,1]]},"912":{"position":[[7924,1]]},"934":{"position":[[346,1]]},"938":{"position":[[2788,1]]},"1005":{"position":[[4034,1],[4239,2],[4477,2],[4577,2],[4692,2]]},"1048":{"position":[[292,2]]},"1169":{"position":[[614,3]]},"1171":{"position":[[877,1]]},"1189":{"position":[[461,1],[715,2],[1061,1]]},"1201":{"position":[[317,1],[358,1]]},"1303":{"position":[[1022,2],[2034,1]]},"1305":{"position":[[248,2]]},"1407":{"position":[[391,1],[1425,1]]},"1409":{"position":[[201,1]]},"1411":{"position":[[314,1]]},"1433":{"position":[[109,1],[127,1],[145,1]]},"1439":{"position":[[328,3]]},"1451":{"position":[[263,1],[809,1],[832,1]]},"1460":{"position":[[369,2]]},"1505":{"position":[[271,1]]},"1523":{"position":[[1748,1]]},"1555":{"position":[[615,1],[657,1],[705,1],[808,1],[868,1]]},"1564":{"position":[[442,1]]},"1605":{"position":[[116,1],[294,1],[909,1],[1087,1],[1552,1],[1730,1]]},"1650":{"position":[[277,1],[546,1]]},"1796":{"position":[[7924,1]]},"1811":{"position":[[9427,1]]},"1825":{"position":[[346,1]]},"1829":{"position":[[2788,1]]},"1896":{"position":[[4034,1],[4239,2],[4477,2],[4577,2],[4692,2]]},"1975":{"position":[[277,1],[546,1]]},"2180":{"position":[[156,2],[235,1]]},"2192":{"position":[[949,1]]},"2196":{"position":[[2420,1],[3225,1]]},"2207":{"position":[[1414,1],[1740,1]]},"2219":{"position":[[643,1],[663,1]]},"2276":{"position":[[524,1],[604,2],[2965,1]]},"2567":{"position":[[962,2]]},"2576":{"position":[[737,2]]},"2608":{"position":[[944,1]]},"2762":{"position":[[151,5]]},"2806":{"position":[[273,2]]},"2958":{"position":[[346,1]]},"2962":{"position":[[2788,1]]},"3114":{"position":[[23,1]]},"3352":{"position":[[2020,1]]},"3381":{"position":[[447,1]]},"3384":{"position":[[1050,1]]},"3527":{"position":[[1619,1]]},"3665":{"position":[[1509,1]]},"3671":{"position":[[429,1],[444,1]]},"3712":{"position":[[741,1],[756,1]]},"3731":{"position":[[1387,1]]},"3744":{"position":[[2373,1],[2375,4],[2732,4]]},"3805":{"position":[[520,1],[535,1]]},"3829":{"position":[[1515,1]]},"3855":{"position":[[290,1]]},"3910":{"position":[[92,2]]},"3968":{"position":[[1548,2],[1646,2]]},"3971":{"position":[[504,1]]},"3973":{"position":[[35,2]]},"3996":{"position":[[526,3]]},"4098":{"position":[[594,1]]},"4107":{"position":[[651,1],[1445,2]]},"4109":{"position":[[3820,1]]},"4137":{"position":[[352,2],[422,2],[568,2]]},"4139":{"position":[[55,2],[125,2],[271,2]]},"4159":{"position":[[266,1],[528,2]]},"4163":{"position":[[3378,2]]},"4165":{"position":[[384,2]]},"4171":{"position":[[573,2]]},"4173":{"position":[[90,2]]},"4226":{"position":[[2690,2],[3317,2]]},"4244":{"position":[[80,2],[123,2],[178,2],[192,2],[279,2],[295,2],[334,2],[372,2],[416,2],[446,2],[740,2]]},"4246":{"position":[[69,2],[112,2],[167,2],[181,2],[268,2],[284,2],[323,2],[361,2],[405,2],[435,2],[729,2]]},"4257":{"position":[[5939,1],[5972,1],[6035,1]]},"4261":{"position":[[524,2],[594,2]]},"4263":{"position":[[49,2],[119,2]]},"4270":{"position":[[629,1],[662,1],[725,1]]},"4291":{"position":[[2543,1]]},"4302":{"position":[[363,1]]},"4310":{"position":[[1605,2]]},"4340":{"position":[[257,1],[562,1]]},"4351":{"position":[[794,1]]},"4431":{"position":[[1328,3]]},"4433":{"position":[[2415,1]]},"4437":{"position":[[118,1]]},"4493":{"position":[[272,1]]},"4539":{"position":[[453,2]]},"4662":{"position":[[1613,1]]}}}],["3,00",{"_index":4385,"t":{"1040":{"position":[[717,4]]}}}],["3,84",{"_index":4389,"t":{"1040":{"position":[[750,4]]},"1042":{"position":[[788,4]]}}}],["3.0",{"_index":5509,"t":{"1301":{"position":[[1677,3],[1825,3]]},"3722":{"position":[[32,3]]}}}],["3.0.0",{"_index":9715,"t":{"3083":{"position":[[785,5]]}}}],["3.0.1",{"_index":9784,"t":{"3153":{"position":[[444,6]]}}}],["3.04",{"_index":6741,"t":{"1675":{"position":[[224,5]]}}}],["3.07",{"_index":6709,"t":{"1669":{"position":[[271,5]]}}}],["3.10",{"_index":3379,"t":{"865":{"position":[[535,6]]},"1766":{"position":[[535,6]]},"2182":{"position":[[174,5]]}}}],["3.14159",{"_index":818,"t":{"143":{"position":[[605,7]]}}}],["3.2.0",{"_index":9828,"t":{"3183":{"position":[[203,7]]}}}],["3.2.7",{"_index":3031,"t":{"688":{"position":[[314,5]]}}}],["3.25ghz",{"_index":10393,"t":{"3671":{"position":[[828,8]]},"3712":{"position":[[1837,8],[2099,7]]},"3805":{"position":[[935,8],[1202,7]]}}}],["3.26.x",{"_index":9841,"t":{"3185":{"position":[[495,8]]}}}],["3.3.0",{"_index":9872,"t":{"3221":{"position":[[267,5]]}}}],["3.5",{"_index":10342,"t":{"3663":{"position":[[140,5]]},"3700":{"position":[[134,5],[392,3]]},"3787":{"position":[[134,5],[392,3]]}}}],["3.64",{"_index":8374,"t":{"2343":{"position":[[386,5],[438,4]]},"2410":{"position":[[386,5],[438,4]]}}}],["3.75ghz",{"_index":10395,"t":{"3671":{"position":[[850,8]]},"3712":{"position":[[1859,8]]},"3805":{"position":[[957,8]]}}}],["3.8",{"_index":9010,"t":{"2723":{"position":[[342,4]]}}}],["3.9",{"_index":11411,"t":{"4257":{"position":[[6029,5]]},"4270":{"position":[[719,5]]}}}],["3.9kb",{"_index":6461,"t":{"1564":{"position":[[365,5]]}}}],["3.de.pool.ntp.org",{"_index":5119,"t":{"1226":{"position":[[5761,17]]}}}],["3.testbed.osism.xyz",{"_index":4852,"t":{"1185":{"position":[[1834,19]]},"2192":{"position":[[916,19]]}}}],["3.x",{"_index":8611,"t":{"2563":{"position":[[120,3]]}}}],["3/19",{"_index":5044,"t":{"1222":{"position":[[880,6]]}}}],["3/3",{"_index":2949,"t":{"590":{"position":[[1185,3],[1255,3],[1325,3],[1395,3]]}}}],["30",{"_index":3410,"t":{"865":{"position":[[1353,2]]},"991":{"position":[[32,2],[163,2]]},"1042":{"position":[[938,3]]},"1175":{"position":[[1585,2],[1639,2],[2303,2],[2667,2],[2721,2]]},"1177":{"position":[[351,2],[398,2],[494,2],[1119,2],[1915,2]]},"1189":{"position":[[1254,2]]},"1466":{"position":[[2316,3]]},"1657":{"position":[[222,2]]},"1766":{"position":[[1353,2]]},"1882":{"position":[[32,2],[163,2]]},"2219":{"position":[[783,2]]},"2692":{"position":[[1037,2]]},"2930":{"position":[[971,2]]},"3402":{"position":[[504,2]]},"3582":{"position":[[1815,2]]},"3829":{"position":[[4756,3]]},"3971":{"position":[[131,2]]},"4560":{"position":[[3344,3]]}}}],["30.04.2024",{"_index":304,"t":{"28":{"position":[[3078,10]]}}}],["30.09.2024",{"_index":283,"t":{"28":{"position":[[2055,10],[2159,10],[2263,10],[2367,10],[2471,10],[2575,10],[2679,10],[2783,10],[2887,10],[2991,10]]}}}],["30.11.2024",{"_index":217,"t":{"26":{"position":[[875,10]]},"28":{"position":[[1422,10],[1783,10]]}}}],["300",{"_index":5524,"t":{"1301":{"position":[[2916,3]]},"1698":{"position":[[1953,3]]},"3034":{"position":[[62,3]]}}}],["3000",{"_index":3775,"t":{"932":{"position":[[1361,4]]},"967":{"position":[[424,6]]},"1823":{"position":[[1361,4]]},"1858":{"position":[[424,6]]},"2720":{"position":[[582,5]]},"2956":{"position":[[1361,4]]},"2991":{"position":[[424,6]]}}}],["30000",{"_index":11609,"t":{"4537":{"position":[[1554,5]]},"4547":{"position":[[1522,5]]}}}],["3003",{"_index":4025,"t":{"963":{"position":[[741,4]]},"1854":{"position":[[741,4]]},"2987":{"position":[[741,4]]}}}],["302",{"_index":6920,"t":{"1698":{"position":[[694,5]]}}}],["304",{"_index":10759,"t":{"3744":{"position":[[2618,3],[2636,3],[2668,3],[2686,3]]}}}],["30t10%3a10%3a10.010z",{"_index":9126,"t":{"2782":{"position":[[93,21]]}}}],["30t10:14:01.410334z",{"_index":6867,"t":{"1694":{"position":[[6765,19]]}}}],["30t10:14:01.731212z",{"_index":6775,"t":{"1694":{"position":[[1242,19],[1767,19]]}}}],["30t10:14:03.054547z",{"_index":6854,"t":{"1694":{"position":[[5252,19]]}}}],["30t10:14:04.801633z",{"_index":6851,"t":{"1694":{"position":[[5134,19]]}}}],["30t10:14:07.019883z",{"_index":6848,"t":{"1694":{"position":[[5005,19]]}}}],["30t10:14:08.551850z",{"_index":6844,"t":{"1694":{"position":[[4887,19]]}}}],["30t10:14:10.895833z",{"_index":6841,"t":{"1694":{"position":[[4737,19]]}}}],["30t10:14:12.216984z",{"_index":6838,"t":{"1694":{"position":[[4576,19]]}}}],["30t10:14:13.588195z",{"_index":6835,"t":{"1694":{"position":[[4423,19]]}}}],["30t10:14:15.911699z",{"_index":6832,"t":{"1694":{"position":[[4280,19]]}}}],["30t10:14:16.932135z",{"_index":6883,"t":{"1694":{"position":[[8533,19]]}}}],["30t10:14:17.542234z",{"_index":6829,"t":{"1694":{"position":[[4146,19]]}}}],["30t10:14:18.711171z",{"_index":6826,"t":{"1694":{"position":[[4011,19]]}}}],["30t10:14:19.859670z",{"_index":6823,"t":{"1694":{"position":[[3876,19]]}}}],["30t10:14:21.085351z",{"_index":6820,"t":{"1694":{"position":[[3741,19]]}}}],["30t10:14:23.199518z",{"_index":6815,"t":{"1694":{"position":[[3615,19]]}}}],["30t10:14:24.880329z",{"_index":6811,"t":{"1694":{"position":[[3476,19]]}}}],["30t10:14:26.422535z",{"_index":6806,"t":{"1694":{"position":[[3340,19]]}}}],["30t10:14:27.979869z",{"_index":6803,"t":{"1694":{"position":[[3183,19]]}}}],["30t10:14:29.500998z",{"_index":6799,"t":{"1694":{"position":[[3044,19]]}}}],["30t10:14:31.411916z",{"_index":6795,"t":{"1694":{"position":[[2903,19]]}}}],["30t10:14:34.134312z",{"_index":6792,"t":{"1694":{"position":[[2776,19]]}}}],["30t10:14:35.502754z",{"_index":6788,"t":{"1694":{"position":[[2653,19]]}}}],["30t10:14:37.126872z",{"_index":6784,"t":{"1694":{"position":[[2517,19],[5918,19]]}}}],["30t10:14:39.678878z",{"_index":6863,"t":{"1694":{"position":[[5958,19]]}}}],["30t10:14:39.969244z",{"_index":6781,"t":{"1694":{"position":[[1807,19]]}}}],["30t10:14:40.279181z",{"_index":6881,"t":{"1694":{"position":[[8438,19]]}}}],["30t10:14:40.280601z",{"_index":6879,"t":{"1694":{"position":[[8339,19]]}}}],["30t10:14:40.283581z",{"_index":6877,"t":{"1694":{"position":[[8240,19]]}}}],["30t10:14:40.543599z",{"_index":6875,"t":{"1694":{"position":[[8140,19],[9054,19]]}}}],["30t18:50:05.000000",{"_index":7166,"t":{"1716":{"position":[[686,18],[780,18]]}}}],["30t18:50:08.000000",{"_index":7169,"t":{"1716":{"position":[[874,18]]}}}],["31",{"_index":4905,"t":{"1189":{"position":[[1257,2]]},"1698":{"position":[[106,2],[379,2],[543,2],[763,2],[993,2],[1231,2]]},"3402":{"position":[[450,2]]},"3410":{"position":[[594,2]]},"3582":{"position":[[1751,2]]},"3829":{"position":[[4782,3]]}}}],["31.12.2023",{"_index":197,"t":{"26":{"position":[[353,10]]},"28":{"position":[[1070,10]]}}}],["31.12.2024",{"_index":205,"t":{"26":{"position":[[500,10]]},"28":{"position":[[585,10],[708,10]]}}}],["31/oct/2023",{"_index":6955,"t":{"1698":{"position":[[1913,12]]}}}],["31248d71ab7d",{"_index":7107,"t":{"1711":{"position":[[1304,12]]}}}],["3128",{"_index":5807,"t":{"1342":{"position":[[213,7]]},"1348":{"position":[[230,8]]},"1350":{"position":[[206,8],[254,8]]},"1352":{"position":[[299,8],[363,8]]},"1354":{"position":[[505,8],[559,8]]}}}],["31459327",{"_index":4746,"t":{"1177":{"position":[[3824,8]]}}}],["31459328",{"_index":4748,"t":{"1177":{"position":[[3872,8]]}}}],["3194",{"_index":4764,"t":{"1177":{"position":[[4795,4],[5083,4],[5134,4],[5661,4],[5968,4],[6306,4],[6348,4]]}}}],["31t10:45:35.498718+0000",{"_index":6901,"t":{"1698":{"position":[[165,23]]}}}],["31t11:19:56.329684+0000",{"_index":6930,"t":{"1698":{"position":[[822,23]]}}}],["31t11:19:57.650+0000",{"_index":6916,"t":{"1698":{"position":[[430,20],[594,20]]}}}],["31t11:19:58.566+0000",{"_index":6933,"t":{"1698":{"position":[[1050,20]]}}}],["31t11:19:58.710+0000",{"_index":6945,"t":{"1698":{"position":[[1282,20]]}}}],["32",{"_index":89,"t":{"12":{"position":[[118,2]]},"15":{"position":[[116,2]]},"865":{"position":[[840,2]]},"894":{"position":[[1424,2]]},"1105":{"position":[[791,2]]},"1111":{"position":[[308,2]]},"1189":{"position":[[1260,2]]},"1383":{"position":[[1136,2]]},"1468":{"position":[[676,2]]},"1650":{"position":[[613,2]]},"1752":{"position":[[1424,2]]},"1766":{"position":[[840,2]]},"1975":{"position":[[613,2]]},"2027":{"position":[[325,2]]},"2178":{"position":[[1077,2]]},"2219":{"position":[[426,2]]},"3704":{"position":[[1271,2]]},"3720":{"position":[[94,2]]},"3791":{"position":[[294,3],[305,2],[432,3],[444,2],[518,3],[529,2]]},"3793":{"position":[[803,2]]},"3813":{"position":[[94,2]]},"3898":{"position":[[192,2],[209,2],[358,2],[376,2],[438,2],[455,2]]},"3900":{"position":[[188,2],[209,2],[378,2],[400,2],[496,2],[517,2]]}}}],["321",{"_index":6908,"t":{"1698":{"position":[[255,3],[264,3],[912,3],[921,3]]}}}],["322961408",{"_index":6944,"t":{"1698":{"position":[[1217,9]]}}}],["32498",{"_index":9939,"t":{"3306":{"position":[[338,6]]}}}],["3261",{"_index":11106,"t":{"3990":{"position":[[2374,4]]}}}],["32767",{"_index":11610,"t":{"4537":{"position":[[1560,5]]},"4547":{"position":[[1528,7]]}}}],["32768",{"_index":5857,"t":{"1365":{"position":[[190,5]]}}}],["32d",{"_index":4504,"t":{"1120":{"position":[[66,3]]}}}],["32gb",{"_index":5894,"t":{"1383":{"position":[[709,4]]},"2013":{"position":[[0,4]]},"2019":{"position":[[0,4]]}}}],["32gib",{"_index":10424,"t":{"3675":{"position":[[150,5]]},"3720":{"position":[[150,5]]},"3813":{"position":[[150,5]]}}}],["32m",{"_index":6698,"t":{"1665":{"position":[[970,3]]}}}],["32x",{"_index":4500,"t":{"1118":{"position":[[812,3]]},"1120":{"position":[[31,3]]}}}],["33",{"_index":4906,"t":{"1189":{"position":[[1263,2]]},"1669":{"position":[[234,2]]},"2930":{"position":[[1632,3]]},"3744":{"position":[[1838,2],[1854,2]]},"4707":{"position":[[616,2],[832,2]]}}}],["3300",{"_index":6000,"t":{"1405":{"position":[[1465,7]]}}}],["3306/tcp",{"_index":7771,"t":{"2155":{"position":[[2447,8]]}}}],["330a",{"_index":4204,"t":{"995":{"position":[[1725,4]]},"1886":{"position":[[1725,4]]}}}],["330e",{"_index":3581,"t":{"894":{"position":[[2131,4]]},"1752":{"position":[[2131,4]]}}}],["336",{"_index":10677,"t":{"3744":{"position":[[507,3]]}}}],["338bcf4dde7c",{"_index":4192,"t":{"995":{"position":[[1453,12]]},"1886":{"position":[[1453,12]]}}}],["33f1",{"_index":7001,"t":{"1702":{"position":[[241,4]]}}}],["34",{"_index":4907,"t":{"1189":{"position":[[1266,2]]},"2930":{"position":[[1799,3]]},"4707":{"position":[[848,2]]}}}],["3456",{"_index":10695,"t":{"3744":{"position":[[1014,4]]}}}],["3463cc7b81e0",{"_index":4336,"t":{"1005":{"position":[[5043,12],[5326,12],[5545,12],[5760,12],[6294,12]]},"1896":{"position":[[5043,12],[5326,12],[5545,12],[5760,12],[6294,12]]}}}],["3478",{"_index":11952,"t":{"4849":{"position":[[1072,6]]}}}],["348127232",{"_index":6941,"t":{"1698":{"position":[[1175,9],[1197,9]]}}}],["35",{"_index":4908,"t":{"1189":{"position":[[1269,2]]},"1675":{"position":[[188,2]]}}}],["35.1kb",{"_index":6465,"t":{"1564":{"position":[[451,6]]}}}],["3501db829014406884990a1016f3e25d",{"_index":232,"t":{"28":{"position":[[719,32]]}}}],["3519:55",{"_index":6728,"t":{"1673":{"position":[[307,7]]}}}],["3584",{"_index":10681,"t":{"3744":{"position":[[812,4],[926,4]]}}}],["3593b2a409a4",{"_index":4304,"t":{"1005":{"position":[[3112,12],[3334,12],[3553,12],[3668,12],[5966,12]]},"1896":{"position":[[3112,12],[3334,12],[3553,12],[3668,12],[5966,12]]}}}],["36",{"_index":4909,"t":{"1189":{"position":[[1272,2]]},"1700":{"position":[[377,2]]}}}],["3600",{"_index":4542,"t":{"1147":{"position":[[496,5]]},"2132":{"position":[[487,4]]}}}],["3602",{"_index":9802,"t":{"3164":{"position":[[164,4]]}}}],["3614d94f46fd",{"_index":8197,"t":{"2252":{"position":[[2117,12]]}}}],["36c3",{"_index":8122,"t":{"2240":{"position":[[941,4]]}}}],["37",{"_index":4910,"t":{"1189":{"position":[[1275,2]]}}}],["374",{"_index":8666,"t":{"2600":{"position":[[44,4]]}}}],["3786",{"_index":9803,"t":{"3164":{"position":[[182,4]]}}}],["38",{"_index":4911,"t":{"1189":{"position":[[1278,2]]}}}],["3829cc7c8f034fc985f5055a1df6f247",{"_index":226,"t":{"28":{"position":[[332,32]]}}}],["3867",{"_index":6858,"t":{"1694":{"position":[[5678,4]]}}}],["39",{"_index":4912,"t":{"1189":{"position":[[1281,2]]}}}],["394d8e71",{"_index":11036,"t":{"3990":{"position":[[602,8]]}}}],["3a96207b719643ae9ea9a81d95116e9",{"_index":4235,"t":{"995":{"position":[[2255,32]]},"1886":{"position":[[2255,32]]}}}],["3adf4e92",{"_index":2746,"t":{"557":{"position":[[1951,9]]}}}],["3b585d348820",{"_index":11149,"t":{"4051":{"position":[[1243,12]]}}}],["3bf43ae5a94f",{"_index":7133,"t":{"1711":{"position":[[2369,12]]}}}],["3c249ba0e010",{"_index":11068,"t":{"3990":{"position":[[1921,12],[2626,12],[2840,12]]}}}],["3c5bae4a233c4a9d8ae2e4b799d757c9",{"_index":294,"t":{"28":{"position":[[2586,32]]}}}],["3cd241ff",{"_index":8223,"t":{"2254":{"position":[[1368,8]]}}}],["3cfa8679f5d8429382b95d4d2dd80f79",{"_index":4166,"t":{"995":{"position":[[999,32],[1092,32],[1373,32],[1660,32],[1755,32],[2361,32]]},"1886":{"position":[[999,32],[1092,32],[1373,32],[1660,32],[1755,32],[2361,32]]}}}],["3k",{"_index":11643,"t":{"4560":{"position":[[1399,3]]}}}],["3rd",{"_index":3196,"t":{"724":{"position":[[8,3]]},"854":{"position":[[536,3]]},"3835":{"position":[[2034,3]]},"4251":{"position":[[281,3]]},"4587":{"position":[[429,3],[524,3]]},"4593":{"position":[[574,3]]}}}],["3x",{"_index":4380,"t":{"1040":{"position":[[671,2]]},"1042":{"position":[[691,2],[729,2]]},"3310":{"position":[[654,2]]},"3661":{"position":[[336,2]]},"3698":{"position":[[428,2]]},"3785":{"position":[[428,2]]},"3789":{"position":[[1950,2],[2049,3]]}}}],["3x/thread",{"_index":10330,"t":{"3661":{"position":[[1232,9]]},"3698":{"position":[[1886,9]]},"3785":{"position":[[1584,9]]}}}],["3x10",{"_index":10536,"t":{"3702":{"position":[[1655,5],[2091,4]]},"3789":{"position":[[1514,5],[2136,4]]}}}],["3x10s_bms_z3",{"_index":10537,"t":{"3702":{"position":[[1702,12]]},"3789":{"position":[[1561,12]]}}}],["4",{"_index":112,"t":{"12":{"position":[[309,1]]},"15":{"position":[[307,1]]},"66":{"position":[[42,1]]},"364":{"position":[[1114,2]]},"555":{"position":[[659,1]]},"557":{"position":[[262,1],[277,1],[370,2],[381,2],[2652,1],[3483,1]]},"588":{"position":[[1189,1],[1232,1]]},"824":{"position":[[483,1]]},"887":{"position":[[4835,2],[8491,2]]},"894":{"position":[[1264,1],[1631,1],[2177,1],[2359,1]]},"898":{"position":[[132,1],[190,1]]},"914":{"position":[[5134,2],[5259,2],[5322,2],[5342,3],[5372,2],[5620,2],[5634,3]]},"932":{"position":[[2075,1]]},"1005":{"position":[[4969,1],[5071,2],[5354,2],[5573,2],[5788,2]]},"1175":{"position":[[4664,2]]},"1187":{"position":[[632,1],[719,1]]},"1189":{"position":[[1063,1]]},"1259":{"position":[[198,1]]},"1367":{"position":[[180,1]]},"1460":{"position":[[409,2]]},"1505":{"position":[[240,1]]},"1605":{"position":[[185,1],[978,1],[1621,1]]},"1648":{"position":[[1205,2]]},"1694":{"position":[[2577,1],[2713,1],[2836,1],[2963,1],[3104,1],[3243,1],[3400,1],[3536,1],[3675,1],[4340,1],[4483,1],[4636,1],[4797,1],[4947,1],[5065,1],[5194,1]]},"1752":{"position":[[1264,1],[1631,1],[2177,1],[2359,1]]},"1756":{"position":[[132,1],[190,1]]},"1798":{"position":[[5134,2],[5259,2],[5322,2],[5342,3],[5372,2],[5620,2],[5634,3]]},"1811":{"position":[[4835,2],[8491,2]]},"1823":{"position":[[2075,1]]},"1896":{"position":[[4969,1],[5071,2],[5354,2],[5573,2],[5788,2]]},"2027":{"position":[[137,1]]},"2034":{"position":[[463,1]]},"2180":{"position":[[119,1]]},"2192":{"position":[[1011,1]]},"2207":{"position":[[1483,1]]},"2567":{"position":[[1273,2]]},"2626":{"position":[[1324,3]]},"2956":{"position":[[2075,1]]},"3119":{"position":[[980,3]]},"3148":{"position":[[8,1]]},"3164":{"position":[[23,1]]},"3310":{"position":[[590,1],[773,2]]},"3367":{"position":[[620,2]]},"3386":{"position":[[748,1]]},"3527":{"position":[[1625,1]]},"3582":{"position":[[1908,1]]},"3606":{"position":[[1766,1]]},"3671":{"position":[[477,1],[483,1]]},"3675":{"position":[[404,1]]},"3698":{"position":[[2366,1],[2379,1],[2392,1],[2405,1],[2419,1],[2431,3],[2468,1]]},"3700":{"position":[[379,1]]},"3702":{"position":[[1607,1],[1620,1],[1633,1],[1653,1],[1700,1],[1722,1],[1760,1],[1779,1],[1848,1],[1865,1],[1910,1],[1927,1],[1955,1],[1968,1],[2089,1],[2155,1]]},"3704":{"position":[[641,1],[661,1]]},"3708":{"position":[[275,1],[288,1],[305,1]]},"3710":{"position":[[664,1],[726,1],[787,1],[834,1],[928,1]]},"3712":{"position":[[791,1],[813,1],[1242,1],[1894,1],[1907,1],[1922,1],[1938,1],[1955,1],[1973,1],[1992,1],[2012,1],[2032,1],[2053,1]]},"3720":{"position":[[24,1],[407,1]]},"3744":{"position":[[395,1],[722,1],[1351,1],[1650,1],[2494,1]]},"3775":{"position":[[42,2]]},"3785":{"position":[[2064,1],[2077,1],[2090,1],[2103,1],[2117,1],[2129,3],[2166,1]]},"3787":{"position":[[379,1]]},"3789":{"position":[[1466,1],[1479,1],[1492,1],[1512,1],[1559,1],[1581,1],[1619,1],[1638,1],[1707,1],[1724,1],[1769,1],[1786,1],[1814,1],[1827,1],[1948,1],[2047,1],[2134,1],[2200,1]]},"3791":{"position":[[212,2],[222,1],[348,2],[358,1]]},"3801":{"position":[[263,1],[276,1],[293,1]]},"3803":{"position":[[651,1],[713,1],[774,1],[821,1],[915,1]]},"3805":{"position":[[568,1],[590,1],[992,1],[1005,1],[1020,1],[1036,1],[1053,1],[1071,1],[1090,1],[1110,1],[1130,1],[1151,1]]},"3813":{"position":[[24,1],[404,1]]},"3898":{"position":[[75,1],[91,1],[128,1],[160,1],[244,1],[260,1],[269,1],[289,1],[307,1],[441,1]]},"3900":{"position":[[75,1],[94,1],[155,1],[264,1],[283,1],[306,1],[503,1]]},"3930":{"position":[[34,1]]},"3968":{"position":[[2291,2]]},"4107":{"position":[[389,2],[742,1],[1592,2]]},"4137":{"position":[[355,2],[425,2],[571,2]]},"4139":{"position":[[58,2],[128,2],[274,2]]},"4159":{"position":[[1082,1]]},"4244":{"position":[[83,2],[126,2],[195,2],[298,2],[337,2],[375,2],[743,2]]},"4246":{"position":[[72,2],[115,2],[184,2],[287,2],[326,2],[364,2],[732,2]]},"4261":{"position":[[597,2]]},"4263":{"position":[[122,2]]},"4302":{"position":[[482,1]]},"4344":{"position":[[48,1]]},"4351":{"position":[[753,1]]},"4355":{"position":[[245,1]]},"4433":{"position":[[2900,3]]},"4437":{"position":[[148,1]]},"4541":{"position":[[821,1]]}}}],["4.0",{"_index":1729,"t":{"249":{"position":[[1673,4]]},"307":{"position":[[322,3]]},"898":{"position":[[238,3]]},"980":{"position":[[1192,3]]},"1756":{"position":[[238,3]]},"1871":{"position":[[1192,3]]},"2295":{"position":[[950,3]]},"2427":{"position":[[2169,3]]},"4257":{"position":[[5991,3]]},"4270":{"position":[[681,3]]}}}],["4.0.0",{"_index":9757,"t":{"3116":{"position":[[499,5]]}}}],["4.00",{"_index":6708,"t":{"1669":{"position":[[265,5]]}}}],["4.2.0",{"_index":7463,"t":{"2059":{"position":[[1943,7]]}}}],["4.5.2",{"_index":3027,"t":{"688":{"position":[[181,5]]}}}],["4.de.pool.ntp.org",{"_index":5120,"t":{"1226":{"position":[[5781,17]]}}}],["4.testbed.osism.xyz",{"_index":4853,"t":{"1185":{"position":[[1867,19]]},"2192":{"position":[[978,19]]}}}],["4/",{"_index":10943,"t":{"3928":{"position":[[2510,5]]}}}],["4/19",{"_index":5046,"t":{"1222":{"position":[[918,6]]}}}],["4/2024",{"_index":2014,"t":{"307":{"position":[[281,6]]}}}],["40",{"_index":482,"t":{"64":{"position":[[48,3]]},"914":{"position":[[5543,3]]},"1050":{"position":[[479,2]]},"1189":{"position":[[1105,2]]},"1303":{"position":[[1937,3],[3085,3]]},"1798":{"position":[[5543,3]]},"2684":{"position":[[305,2]]},"3971":{"position":[[51,2]]}}}],["400g",{"_index":4501,"t":{"1120":{"position":[[35,5]]}}}],["401",{"_index":11628,"t":{"4541":{"position":[[1497,3]]}}}],["403",{"_index":8459,"t":{"2431":{"position":[[4356,4]]}}}],["4036",{"_index":4324,"t":{"1005":{"position":[[4201,4],[4439,4],[4539,4],[4654,4],[6120,4]]},"1896":{"position":[[4201,4],[4439,4],[4539,4],[4654,4],[6120,4]]}}}],["403b",{"_index":4290,"t":{"1005":{"position":[[2761,4]]},"1896":{"position":[[2761,4]]}}}],["404",{"_index":4804,"t":{"1183":{"position":[[385,3],[529,3],[868,3]]}}}],["4062",{"_index":11103,"t":{"3990":{"position":[[2339,4]]}}}],["40767",{"_index":9940,"t":{"3306":{"position":[[431,6]]}}}],["408f",{"_index":6757,"t":{"1686":{"position":[[693,4]]}}}],["4096",{"_index":3594,"t":{"894":{"position":[[2376,4]]},"1201":{"position":[[530,4]]},"1375":{"position":[[255,4]]},"1555":{"position":[[606,4],[648,4]]},"1752":{"position":[[2376,4]]},"3126":{"position":[[183,4]]}}}],["4096m",{"_index":4862,"t":{"1187":{"position":[[586,7]]}}}],["40a51f6c",{"_index":2732,"t":{"557":{"position":[[1149,9]]}}}],["40b0",{"_index":6966,"t":{"1700":{"position":[[124,4]]}}}],["40c3",{"_index":4200,"t":{"995":{"position":[[1635,4]]},"1886":{"position":[[1635,4]]}}}],["40cc",{"_index":4252,"t":{"995":{"position":[[3011,4]]},"1886":{"position":[[3011,4]]}}}],["40g",{"_index":6214,"t":{"1455":{"position":[[1500,4]]},"3744":{"position":[[1022,3],[1800,3]]}}}],["40h",{"_index":10697,"t":{"3744":{"position":[[1040,3],[1816,3]]}}}],["41",{"_index":4885,"t":{"1189":{"position":[[1108,2]]}}}],["41048563",{"_index":7067,"t":{"1704":{"position":[[2109,8]]}}}],["41049332",{"_index":7060,"t":{"1704":{"position":[[1768,8]]}}}],["41063293",{"_index":7082,"t":{"1704":{"position":[[2788,8]]}}}],["41063820",{"_index":7077,"t":{"1704":{"position":[[2447,8]]}}}],["410b",{"_index":6925,"t":{"1698":{"position":[[733,4]]}}}],["4155",{"_index":9103,"t":{"2776":{"position":[[139,4]]}}}],["416b",{"_index":6468,"t":{"1564":{"position":[[510,4]]}}}],["41943006",{"_index":4749,"t":{"1177":{"position":[[3881,8]]}}}],["41943040",{"_index":4724,"t":{"1177":{"position":[[3401,8]]}}}],["41cf",{"_index":4702,"t":{"1177":{"position":[[1163,4],[1534,4],[1740,4],[2290,4],[2533,4],[2901,4],[3007,4]]}}}],["42",{"_index":4886,"t":{"1189":{"position":[[1111,2]]}}}],["4210042010",{"_index":5312,"t":{"1275":{"position":[[680,10]]}}}],["4212",{"_index":8211,"t":{"2254":{"position":[[372,4],[724,4],[1284,4],[1468,4]]},"2256":{"position":[[78,4]]}}}],["421c",{"_index":6661,"t":{"1659":{"position":[[81,4],[215,4]]}}}],["4224",{"_index":10727,"t":{"3744":{"position":[[1833,4]]}}}],["422e",{"_index":8123,"t":{"2240":{"position":[[946,4]]}}}],["42434",{"_index":6398,"t":{"1555":{"position":[[594,5],[600,5],[681,5],[687,5],[789,5],[795,5],[844,5],[850,5]]}}}],["42502283454d",{"_index":9091,"t":{"2766":{"position":[[231,14]]},"2768":{"position":[[86,12],[171,15]]}}}],["42502283454d\"}],\"beganat\":\"2024",{"_index":9129,"t":{"2782":{"position":[[220,31]]},"2784":{"position":[[220,31]]},"2786":{"position":[[201,31]]}}}],["42502283454d\"}],\"displayname\":\"test",{"_index":9122,"t":{"2780":{"position":[[227,35]]}}}],["425a",{"_index":8201,"t":{"2252":{"position":[[2166,4]]}}}],["4282",{"_index":8161,"t":{"2250":{"position":[[1069,4]]},"2252":{"position":[[2783,4]]}}}],["429",{"_index":3232,"t":{"741":{"position":[[957,5]]}}}],["42a6",{"_index":11093,"t":{"3990":{"position":[[2215,4]]}}}],["42bf",{"_index":8001,"t":{"2207":{"position":[[686,4],[865,4],[916,4]]}}}],["43",{"_index":4887,"t":{"1189":{"position":[[1114,2]]}}}],["4318",{"_index":8174,"t":{"2252":{"position":[[1167,4],[2647,4]]}}}],["432",{"_index":10688,"t":{"3744":{"position":[[965,3],[1142,3]]}}}],["4336346b4b18",{"_index":4165,"t":{"995":{"position":[[984,12]]},"1886":{"position":[[984,12]]}}}],["4340",{"_index":7242,"t":{"1743":{"position":[[161,4]]}}}],["434a",{"_index":8212,"t":{"2254":{"position":[[377,4],[729,4],[1289,4],[1473,4]]},"2256":{"position":[[83,4]]}}}],["4359",{"_index":4334,"t":{"1005":{"position":[[5033,4],[5316,4],[5535,4],[5750,4],[6284,4]]},"1896":{"position":[[5033,4],[5316,4],[5535,4],[5750,4],[6284,4]]}}}],["43d2",{"_index":2728,"t":{"557":{"position":[[1032,4]]}}}],["44",{"_index":4888,"t":{"1189":{"position":[[1117,2]]}}}],["443",{"_index":1919,"t":{"293":{"position":[[755,3]]},"1195":{"position":[[227,3]]},"1297":{"position":[[1905,6]]},"1407":{"position":[[2574,3]]},"1427":{"position":[[247,3]]},"2117":{"position":[[280,3],[1394,3]]},"2293":{"position":[[976,3]]},"2307":{"position":[[976,3]]},"2853":{"position":[[98,3]]},"4853":{"position":[[465,3]]}}}],["443/tcp",{"_index":3050,"t":{"692":{"position":[[413,7]]},"747":{"position":[[332,7]]},"2853":{"position":[[363,7]]}}}],["4454144360",{"_index":7702,"t":{"2139":{"position":[[558,10]]}}}],["4476bf7afe9f",{"_index":4715,"t":{"1177":{"position":[[1330,12],[1604,12],[1655,12],[1703,12],[2232,12],[2480,12],[2766,12],[2808,12],[2977,12]]}}}],["44ad",{"_index":4205,"t":{"995":{"position":[[1730,4]]},"1886":{"position":[[1730,4]]}}}],["44d1",{"_index":8190,"t":{"2252":{"position":[[2066,4]]}}}],["44d2",{"_index":4128,"t":{"991":{"position":[[126,4],[222,4]]},"1882":{"position":[[126,4],[222,4]]}}}],["45",{"_index":4889,"t":{"1189":{"position":[[1120,2]]}}}],["4506",{"_index":11072,"t":{"3990":{"position":[[1971,4]]}}}],["4528",{"_index":9119,"t":{"2780":{"position":[[157,4]]},"2782":{"position":[[372,4]]},"2784":{"position":[[419,4]]},"2786":{"position":[[74,4],[353,4]]},"2788":{"position":[[74,4]]},"2790":{"position":[[295,4]]},"2792":{"position":[[74,4]]}}}],["4530618",{"_index":6402,"t":{"1555":{"position":[[693,7]]}}}],["4532",{"_index":8185,"t":{"2252":{"position":[[2016,4]]}}}],["457a",{"_index":8180,"t":{"2252":{"position":[[1975,4]]}}}],["458c",{"_index":4307,"t":{"1005":{"position":[[3205,4],[3443,4],[3758,4],[3873,4],[6038,4]]},"1896":{"position":[[3205,4],[3443,4],[3758,4],[3873,4],[6038,4]]}}}],["45a49",{"_index":7030,"t":{"1704":{"position":[[625,6]]}}}],["45ab",{"_index":11021,"t":{"3988":{"position":[[1003,4]]}}}],["45b0",{"_index":9081,"t":{"2764":{"position":[[216,4]]}}}],["45e0a707",{"_index":11091,"t":{"3990":{"position":[[2201,8]]}}}],["45f8",{"_index":2563,"t":{"518":{"position":[[472,4]]}}}],["46",{"_index":4890,"t":{"1189":{"position":[[1123,2]]},"1694":{"position":[[7517,2]]},"2199":{"position":[[1278,2]]}}}],["4618",{"_index":4297,"t":{"1005":{"position":[[2895,4]]},"1896":{"position":[[2895,4]]},"2252":{"position":[[1922,4],[2699,4]]}}}],["4644",{"_index":4734,"t":{"1177":{"position":[[3637,4]]}}}],["464d",{"_index":4210,"t":{"995":{"position":[[1825,4]]},"1886":{"position":[[1825,4]]}}}],["4654",{"_index":9089,"t":{"2766":{"position":[[221,4]]},"2768":{"position":[[76,4],[161,4]]},"2780":{"position":[[217,4]]},"2782":{"position":[[210,4]]},"2784":{"position":[[210,4]]},"2786":{"position":[[191,4]]}}}],["4679",{"_index":4216,"t":{"995":{"position":[[1920,4]]},"1886":{"position":[[1920,4]]}}}],["467f",{"_index":4302,"t":{"1005":{"position":[[3102,4],[3324,4],[3543,4],[3658,4],[5956,4]]},"1896":{"position":[[3102,4],[3324,4],[3543,4],[3658,4],[5956,4]]}}}],["46a9",{"_index":2754,"t":{"557":{"position":[[2099,4]]}}}],["46f9",{"_index":11061,"t":{"3990":{"position":[[1838,4],[2611,4],[2825,4]]}}}],["47",{"_index":4891,"t":{"1189":{"position":[[1126,2]]}}}],["470a",{"_index":4163,"t":{"995":{"position":[[974,4]]},"1886":{"position":[[974,4]]}}}],["4712",{"_index":4227,"t":{"995":{"position":[[2118,4]]},"1886":{"position":[[2118,4]]}}}],["4728",{"_index":8250,"t":{"2256":{"position":[[445,4]]}}}],["4756",{"_index":5151,"t":{"1236":{"position":[[1067,4],[1198,4]]}}}],["4758",{"_index":4318,"t":{"1005":{"position":[[4098,4],[4320,4],[4754,4],[4869,4],[6202,4]]},"1896":{"position":[[4098,4],[4320,4],[4754,4],[4869,4],[6202,4]]}}}],["4762",{"_index":7002,"t":{"1702":{"position":[[246,4]]}}}],["476672f1023b4bac8837f95a76881757",{"_index":284,"t":{"28":{"position":[[2066,32]]}}}],["4769",{"_index":4566,"t":{"1163":{"position":[[253,4]]}}}],["47951",{"_index":9806,"t":{"3164":{"position":[[272,5]]}}}],["47a9",{"_index":11044,"t":{"3990":{"position":[[669,4]]}}}],["47b929fd",{"_index":11014,"t":{"3988":{"position":[[865,8]]},"4051":{"position":[[764,8]]}}}],["47c9f228e297",{"_index":2756,"t":{"557":{"position":[[2109,13]]}}}],["47ca588689f3\",\"labels\":{}},{\"activelyaffectedby\":[],\"displayname\":\"network\",\"id\":\"414d764f",{"_index":9105,"t":{"2776":{"position":[[149,90]]}}}],["47ef",{"_index":7154,"t":{"1713":{"position":[[1056,4],[1349,4]]}}}],["48",{"_index":1914,"t":{"293":{"position":[[631,2]]},"1189":{"position":[[1129,2]]},"3744":{"position":[[537,2],[1500,2],[1541,2],[1583,2]]},"3829":{"position":[[2724,2]]}}}],["480",{"_index":4459,"t":{"1105":{"position":[[507,3]]},"1107":{"position":[[243,3]]},"1109":{"position":[[254,3]]},"1111":{"position":[[254,3]]}}}],["4824",{"_index":9084,"t":{"2764":{"position":[[286,4]]}}}],["483c",{"_index":8220,"t":{"2254":{"position":[[1328,4]]}}}],["486b",{"_index":7954,"t":{"2196":{"position":[[2265,4],[3070,4]]}}}],["4888",{"_index":9113,"t":{"2778":{"position":[[212,4]]},"2780":{"position":[[75,4],[294,4]]},"2782":{"position":[[164,4]]},"2784":{"position":[[150,4]]},"2786":{"position":[[145,4]]}}}],["48920d26",{"_index":7179,"t":{"1720":{"position":[[457,8],[983,8],[1693,8],[2507,8]]}}}],["48a8",{"_index":11097,"t":{"3990":{"position":[[2255,4]]}}}],["48ea",{"_index":8219,"t":{"2254":{"position":[[1323,4]]}}}],["48g",{"_index":10680,"t":{"3744":{"position":[[520,3],[1482,3],[1522,3],[1563,3],[2880,3]]}}}],["48h",{"_index":10774,"t":{"3744":{"position":[[2897,3]]}}}],["48hr",{"_index":10843,"t":{"3829":{"position":[[2790,6]]}}}],["49",{"_index":4892,"t":{"1189":{"position":[[1132,2]]},"1694":{"position":[[1219,2],[1714,4],[2504,2],[2640,2],[2763,2],[2890,2],[3031,2],[3170,2],[3327,2],[3463,2],[3602,2],[3728,2],[3863,2],[3998,2],[4133,2],[4267,2],[4410,2],[4563,2],[4724,2],[4874,2],[4992,2],[5121,2],[5239,2],[6647,2],[8106,2],[8206,2],[8305,2],[8404,2],[8500,2]]}}}],["4920",{"_index":7181,"t":{"1720":{"position":[[471,4],[997,4],[1707,4],[2521,4]]}}}],["4925967416894fd78be6701689059653",{"_index":198,"t":{"26":{"position":[[364,32]]}}}],["4972",{"_index":7209,"t":{"1732":{"position":[[678,4],[1489,4]]},"1734":{"position":[[679,4],[1683,4]]}}}],["49851a410c97",{"_index":2736,"t":{"557":{"position":[[1174,13]]}}}],["49a8",{"_index":8235,"t":{"2254":{"position":[[1512,4]]}}}],["49b8",{"_index":8118,"t":{"2240":{"position":[[880,4]]}}}],["49c9",{"_index":4243,"t":{"995":{"position":[[2442,4]]},"1886":{"position":[[2442,4]]}}}],["49cc3d72fbdf41fe8dc407f57f026dbf",{"_index":210,"t":{"26":{"position":[[640,32]]}}}],["49d4",{"_index":8240,"t":{"2254":{"position":[[1566,4]]}}}],["49f153ffbcef",{"_index":4762,"t":{"1177":{"position":[[4753,12],[4992,12],[5043,12],[5606,12],[6047,12],[6428,12],[6470,12]]}}}],["4:16",{"_index":10451,"t":{"3677":{"position":[[255,4]]},"3791":{"position":[[253,4]]}}}],["4:32",{"_index":10478,"t":{"3677":{"position":[[508,4]]},"3791":{"position":[[506,4]]}}}],["4:8",{"_index":10463,"t":{"3677":{"position":[[365,3]]},"3791":{"position":[[363,3]]}}}],["4_bms_z3",{"_index":10544,"t":{"3702":{"position":[[2073,8]]},"3789":{"position":[[1932,8]]}}}],["4a01",{"_index":11076,"t":{"3990":{"position":[[2008,4]]}}}],["4a581354983f",{"_index":11100,"t":{"3990":{"position":[[2306,12]]}}}],["4a68",{"_index":4180,"t":{"995":{"position":[[1253,4]]},"1886":{"position":[[1253,4]]}}}],["4a6c",{"_index":5144,"t":{"1236":{"position":[[601,4],[733,4]]}}}],["4a8e",{"_index":4190,"t":{"995":{"position":[[1443,4]]},"1886":{"position":[[1443,4]]}}}],["4aa0",{"_index":11127,"t":{"4026":{"position":[[901,4]]},"4030":{"position":[[848,4]]}}}],["4afb",{"_index":4340,"t":{"1005":{"position":[[5197,4],[5435,4],[5635,4],[5865,4],[6366,4]]},"1896":{"position":[[5197,4],[5435,4],[5635,4],[5865,4],[6366,4]]}}}],["4b01",{"_index":10253,"t":{"3594":{"position":[[316,4]]}}}],["4b24",{"_index":2734,"t":{"557":{"position":[[1164,4]]}}}],["4b37",{"_index":8245,"t":{"2254":{"position":[[1605,4]]}}}],["4ba0",{"_index":6748,"t":{"1686":{"position":[[519,4]]}}}],["4bb1",{"_index":8225,"t":{"2254":{"position":[[1382,4]]}}}],["4bc3",{"_index":4133,"t":{"991":{"position":[[275,4]]},"1882":{"position":[[275,4]]}}}],["4c",{"_index":10582,"t":{"3712":{"position":[[1260,2]]},"3720":{"position":[[391,2]]},"3813":{"position":[[388,2]]}}}],["4c0a",{"_index":11066,"t":{"3990":{"position":[[1887,4],[2883,4]]}}}],["4c24",{"_index":4232,"t":{"995":{"position":[[2230,4]]},"1886":{"position":[[2230,4]]}}}],["4c28",{"_index":4141,"t":{"993":{"position":[[74,4],[172,4]]},"1884":{"position":[[74,4],[172,4]]}}}],["4c2c",{"_index":2721,"t":{"557":{"position":[[904,4]]}}}],["4c4d",{"_index":9107,"t":{"2776":{"position":[[245,4]]}}}],["4c55",{"_index":4284,"t":{"1005":{"position":[[2627,4]]},"1896":{"position":[[2627,4]]}}}],["4c5b",{"_index":11038,"t":{"3990":{"position":[[616,4]]}}}],["4c73",{"_index":8195,"t":{"2252":{"position":[[2107,4]]}}}],["4c:16:2x200p",{"_index":10434,"t":{"3675":{"position":[[388,12]]}}}],["4ca1",{"_index":8156,"t":{"2250":{"position":[[998,4]]},"2252":{"position":[[2569,4]]}}}],["4cd2",{"_index":11062,"t":{"3990":{"position":[[1843,4],[2616,4],[2830,4]]}}}],["4ceqrvb5pxnjywdzk9_gtjziz31a7sd4lpiy82o5n9nrydodw",{"_index":7965,"t":{"2196":{"position":[[3640,49]]}}}],["4d06",{"_index":4174,"t":{"995":{"position":[[1160,4]]},"1886":{"position":[[1160,4]]}}}],["4d1f",{"_index":11031,"t":{"3988":{"position":[[1260,4]]}}}],["4d39a5",{"_index":7034,"t":{"1704":{"position":[[695,6],[1315,8]]}}}],["4d45",{"_index":4195,"t":{"995":{"position":[[1539,4]]},"1886":{"position":[[1539,4]]}}}],["4d4a",{"_index":4169,"t":{"995":{"position":[[1067,4]]},"1886":{"position":[[1067,4]]}}}],["4d5d",{"_index":4238,"t":{"995":{"position":[[2336,4]]},"1886":{"position":[[2336,4]]}}}],["4d61",{"_index":11052,"t":{"3990":{"position":[[1715,4]]}}}],["4daa",{"_index":11082,"t":{"3990":{"position":[[2092,4]]}}}],["4db3",{"_index":11086,"t":{"3990":{"position":[[2129,4]]}}}],["4de5",{"_index":6972,"t":{"1700":{"position":[[201,4]]}}}],["4df2",{"_index":11107,"t":{"3990":{"position":[[2379,4]]}}}],["4e1e",{"_index":6978,"t":{"1700":{"position":[[278,4]]}}}],["4e42",{"_index":11147,"t":{"4051":{"position":[[1164,4]]}}}],["4e44",{"_index":2748,"t":{"557":{"position":[[1966,4]]}}}],["4e6c",{"_index":9076,"t":{"2764":{"position":[[132,4]]}}}],["4ea22ba875474d039cb57d20b7f710b5",{"_index":280,"t":{"28":{"position":[[1962,32]]}}}],["4ec1",{"_index":11142,"t":{"4051":{"position":[[1031,4]]}}}],["4ee3",{"_index":3582,"t":{"894":{"position":[[2136,4]]},"1752":{"position":[[2136,4]]}}}],["4f22",{"_index":11016,"t":{"3988":{"position":[[879,4]]},"4051":{"position":[[778,4]]}}}],["4f33dfa66c14",{"_index":7139,"t":{"1711":{"position":[[2644,12]]}}}],["4f40",{"_index":4221,"t":{"995":{"position":[[2019,4]]},"1886":{"position":[[2019,4]]}}}],["4f42",{"_index":2695,"t":{"555":{"position":[[439,4]]},"557":{"position":[[84,4]]},"588":{"position":[[382,4]]}}}],["4f5a",{"_index":8168,"t":{"2252":{"position":[[1051,4]]}}}],["4f71",{"_index":8230,"t":{"2254":{"position":[[1421,4]]}}}],["4f9a",{"_index":7241,"t":{"1743":{"position":[[156,4]]}}}],["4fb7",{"_index":11056,"t":{"3990":{"position":[[1759,4]]}}}],["4fc08287809f",{"_index":4326,"t":{"1005":{"position":[[4211,12],[4449,12],[4549,12],[4664,12],[6130,12]]},"1896":{"position":[[4211,12],[4449,12],[4549,12],[4664,12],[6130,12]]}}}],["4fd1",{"_index":4185,"t":{"995":{"position":[[1348,4]]},"1886":{"position":[[1348,4]]}}}],["4fd1d060",{"_index":8166,"t":{"2252":{"position":[[1037,8]]}}}],["4fef",{"_index":11026,"t":{"3988":{"position":[[1131,4]]},"4051":{"position":[[902,4]]}}}],["4gib",{"_index":10421,"t":{"3675":{"position":[[58,4]]},"3720":{"position":[[58,4]]},"3813":{"position":[[58,4]]}}}],["4k",{"_index":5896,"t":{"1383":{"position":[[742,2]]},"1650":{"position":[[198,4]]},"1975":{"position":[[198,4]]},"4560":{"position":[[2000,3]]}}}],["4m",{"_index":6625,"t":{"1650":{"position":[[214,4]]},"1975":{"position":[[214,4]]}}}],["4m52",{"_index":2362,"t":{"434":{"position":[[1109,5]]}}}],["4o",{"_index":10532,"t":{"3700":{"position":[[421,2]]},"3787":{"position":[[421,2]]}}}],["4ou",{"_index":10534,"t":{"3700":{"position":[[450,3]]},"3787":{"position":[[450,3]]}}}],["4th",{"_index":7448,"t":{"2057":{"position":[[1016,3]]}}}],["4u",{"_index":10531,"t":{"3700":{"position":[[407,2]]},"3787":{"position":[[407,2]]}}}],["4uo",{"_index":10533,"t":{"3700":{"position":[[435,3]]},"3787":{"position":[[435,3]]}}}],["4v",{"_index":2690,"t":{"555":{"position":[[345,2],[388,2]]},"894":{"position":[[1367,2]]},"1752":{"position":[[1367,2]]},"2178":{"position":[[1045,2]]},"2219":{"position":[[398,2]]},"3695":{"position":[[352,2]]},"3782":{"position":[[352,2]]},"3791":{"position":[[262,2],[273,2],[371,2],[381,2],[515,2],[526,2]]},"3894":{"position":[[1791,2]]},"3898":{"position":[[122,2],[149,2],[302,2],[435,2]]},"3900":{"position":[[146,2],[298,2],[493,2]]},"3930":{"position":[[48,2]]}}}],["4v:16",{"_index":10452,"t":{"3677":{"position":[[264,6]]}}}],["4v:16:50",{"_index":10453,"t":{"3677":{"position":[[275,8]]}}}],["4v:32",{"_index":10479,"t":{"3677":{"position":[[517,6]]}}}],["4v:32:100",{"_index":10480,"t":{"3677":{"position":[[528,9]]}}}],["4v:8",{"_index":10464,"t":{"3677":{"position":[[373,5]]}}}],["4v:8:20",{"_index":10465,"t":{"3677":{"position":[[383,7]]}}}],["4vcpu",{"_index":10522,"t":{"3695":{"position":[[379,6]]},"3782":{"position":[[379,6]]}}}],["4x",{"_index":4399,"t":{"1042":{"position":[[908,2],[981,2]]},"1105":{"position":[[542,2]]},"1118":{"position":[[638,2]]}}}],["5",{"_index":1386,"t":{"194":{"position":[[386,2]]},"364":{"position":[[1164,2]]},"741":{"position":[[1199,2],[1291,1],[1295,2]]},"820":{"position":[[55,1]]},"914":{"position":[[2578,2],[3887,2],[5226,2],[5451,2]]},"1005":{"position":[[5133,1],[5235,2],[5473,2],[5673,2],[5903,2]]},"1183":{"position":[[1136,1]]},"1189":{"position":[[1065,1]]},"1191":{"position":[[1143,1],[1238,1],[1407,1],[1628,1]]},"1305":{"position":[[168,2],[313,1]]},"1409":{"position":[[842,4],[1343,4]]},"1421":{"position":[[1568,3]]},"1460":{"position":[[454,2]]},"1466":{"position":[[2195,2]]},"1505":{"position":[[246,1]]},"1605":{"position":[[225,1],[403,1],[1018,1],[1184,1],[1661,1]]},"1694":{"position":[[6753,1]]},"1698":{"position":[[372,2],[1465,1],[2193,1]]},"1704":{"position":[[1720,1]]},"1711":{"position":[[1254,1],[1271,1]]},"1798":{"position":[[2578,2],[3887,2],[5226,2],[5451,2]]},"1896":{"position":[[5133,1],[5235,2],[5473,2],[5673,2],[5903,2]]},"2034":{"position":[[730,1]]},"2144":{"position":[[395,3],[663,3],[931,3],[1199,3],[1303,2]]},"2163":{"position":[[3318,2]]},"2192":{"position":[[1073,1]]},"2207":{"position":[[1562,1],[1631,1]]},"2567":{"position":[[1595,2]]},"2684":{"position":[[414,2]]},"2686":{"position":[[187,2]]},"3150":{"position":[[554,2]]},"3180":{"position":[[38,1]]},"3202":{"position":[[23,1]]},"3677":{"position":[[96,2]]},"3702":{"position":[[36,2]]},"3704":{"position":[[548,1],[587,2]]},"3712":{"position":[[847,1],[870,1],[1572,1]]},"3720":{"position":[[187,1]]},"3789":{"position":[[36,2]]},"3791":{"position":[[94,2],[335,1],[559,1]]},"3793":{"position":[[341,1]]},"3813":{"position":[[187,1]]},"3900":{"position":[[231,1],[249,1],[539,1],[558,1]]},"4137":{"position":[[358,2],[428,2],[574,2]]},"4139":{"position":[[61,2],[131,2],[277,2]]},"4244":{"position":[[86,2],[129,2],[198,2],[301,2],[378,2]]},"4246":{"position":[[75,2],[118,2],[187,2],[290,2],[367,2]]},"4302":{"position":[[609,1]]},"4433":{"position":[[2504,3]]},"4437":{"position":[[192,1]]},"4541":{"position":[[823,1]]},"4560":{"position":[[5104,3]]},"4662":{"position":[[1635,1]]}}}],["5.0",{"_index":5515,"t":{"1301":{"position":[[1962,3]]}}}],["5.0.0",{"_index":7451,"t":{"2059":{"position":[[153,5],[159,5],[879,6],[2625,6]]},"3150":{"position":[[139,5]]},"3157":{"position":[[65,5]]},"3159":{"position":[[609,5]]}}}],["5.0.0/openstack.yml",{"_index":7457,"t":{"2059":{"position":[[847,19],[1207,19]]}}}],["5.0.0a",{"_index":7449,"t":{"2059":{"position":[[126,6],[1802,8],[1973,8]]}}}],["5.0.0b",{"_index":7450,"t":{"2059":{"position":[[136,6],[143,6]]}}}],["5.0.x",{"_index":9821,"t":{"3170":{"position":[[207,7]]}}}],["5.00g",{"_index":4719,"t":{"1177":{"position":[[2940,5],[3046,5],[5628,6],[5698,6],[5768,6],[5838,6],[5945,6],[6009,6],[6073,6],[6137,6],[6280,6],[6387,6],[6494,6],[6601,6]]}}}],["5.1.0",{"_index":7452,"t":{"2059":{"position":[[168,5],[174,5]]}}}],["5.1.66.255",{"_index":2776,"t":{"557":{"position":[[3934,14],[3967,14]]}}}],["5.11",{"_index":5991,"t":{"1405":{"position":[[684,4],[1523,4]]}}}],["5.17",{"_index":10802,"t":{"3761":{"position":[[1341,4]]}}}],["5.18",{"_index":10127,"t":{"3406":{"position":[[203,4]]},"3761":{"position":[[1242,5]]},"3770":{"position":[[70,4]]},"3850":{"position":[[167,4]]},"3855":{"position":[[241,6]]}}}],["5.2.0",{"_index":7453,"t":{"2059":{"position":[[183,5],[189,5]]}}}],["5.3.0",{"_index":7454,"t":{"2059":{"position":[[198,5]]}}}],["5.4",{"_index":10790,"t":{"3761":{"position":[[303,3]]}}}],["5.testbed.osism.xyz",{"_index":4854,"t":{"1185":{"position":[[1900,19]]},"2192":{"position":[[1040,19]]}}}],["5.x",{"_index":9823,"t":{"3170":{"position":[[278,6]]}}}],["5/19",{"_index":5047,"t":{"1222":{"position":[[948,6]]}}}],["50",{"_index":1940,"t":{"295":{"position":[[862,3],[905,2],[1033,5]]},"588":{"position":[[1191,3],[1234,3]]},"1189":{"position":[[1135,2]]},"1466":{"position":[[2239,3]]},"2139":{"position":[[480,2]]},"2178":{"position":[[1051,3],[1080,3]]},"2219":{"position":[[404,2],[429,2]]},"2692":{"position":[[1023,2],[1096,2]]},"3677":{"position":[[107,3]]},"3679":{"position":[[518,3]]},"3695":{"position":[[358,2]]},"3702":{"position":[[47,3]]},"3718":{"position":[[644,2],[889,2]]},"3782":{"position":[[358,2]]},"3789":{"position":[[47,3]]},"3791":{"position":[[105,3],[279,2],[415,2],[503,2]]},"3793":{"position":[[521,3]]},"3811":{"position":[[644,2],[889,2]]},"3900":{"position":[[152,2],[172,2],[341,2],[361,2],[460,2],[480,2]]},"4560":{"position":[[2838,3],[4567,3]]}}}],["500",{"_index":8436,"t":{"2431":{"position":[[1948,4]]},"3677":{"position":[[121,4]]},"3702":{"position":[[61,4]]},"3789":{"position":[[61,4]]},"3791":{"position":[[119,4]]}}}],["5000",{"_index":11566,"t":{"4489":{"position":[[874,4]]}}}],["500gb",{"_index":7275,"t":{"2013":{"position":[[77,5]]}}}],["500m",{"_index":6160,"t":{"1437":{"position":[[432,4]]}}}],["500mb",{"_index":8855,"t":{"2682":{"position":[[210,7]]}}}],["500s_gna",{"_index":10618,"t":{"3714":{"position":[[2032,8]]}}}],["503",{"_index":3228,"t":{"741":{"position":[[763,3]]}}}],["50c3a5",{"_index":9318,"t":{"2930":{"position":[[1518,10],[1703,10]]}}}],["50gb",{"_index":10425,"t":{"3675":{"position":[[161,4]]},"3695":{"position":[[435,4]]},"3720":{"position":[[161,4]]},"3782":{"position":[[435,4]]},"3813":{"position":[[161,4]]}}}],["50n",{"_index":10624,"t":{"3718":{"position":[[669,4]]},"3811":{"position":[[669,4]]}}}],["50n_a2",{"_index":10819,"t":{"3811":{"position":[[705,6]]}}}],["50n_i2",{"_index":10625,"t":{"3718":{"position":[[684,6]]},"3811":{"position":[[684,6]]}}}],["50n_z2",{"_index":10626,"t":{"3718":{"position":[[705,6]]}}}],["50p_i1",{"_index":10628,"t":{"3720":{"position":[[97,6]]},"3813":{"position":[[97,6]]}}}],["51",{"_index":4893,"t":{"1189":{"position":[[1138,2]]}}}],["51.1kb",{"_index":6464,"t":{"1564":{"position":[[444,6]]}}}],["5109",{"_index":4780,"t":{"1179":{"position":[[136,4],[260,4],[311,4],[664,4],[793,4],[844,4],[1386,4],[1566,4],[1617,4]]}}}],["511680",{"_index":4903,"t":{"1189":{"position":[[1201,6]]}}}],["511865",{"_index":4933,"t":{"1189":{"position":[[1380,6]]}}}],["512",{"_index":3432,"t":{"871":{"position":[[640,3]]},"887":{"position":[[9152,3]]},"1042":{"position":[[774,3]]},"1177":{"position":[[3466,3],[3472,3],[3514,3],[3526,3],[3564,3],[3576,3]]},"1736":{"position":[[592,3],[612,3],[845,3],[849,3],[853,3]]},"1772":{"position":[[640,3]]},"1811":{"position":[[9152,3]]}}}],["5149",{"_index":8234,"t":{"2254":{"position":[[1507,4]]}}}],["515581",{"_index":4902,"t":{"1189":{"position":[[1178,6]]}}}],["516078",{"_index":4932,"t":{"1189":{"position":[[1357,6]]}}}],["51e1",{"_index":4733,"t":{"1177":{"position":[[3632,4]]}}}],["52",{"_index":4894,"t":{"1189":{"position":[[1141,2]]},"3971":{"position":[[54,2]]}}}],["5212",{"_index":4760,"t":{"1177":{"position":[[4743,4],[4982,4],[5033,4],[5596,4],[6037,4],[6418,4],[6460,4]]}}}],["522e",{"_index":4703,"t":{"1177":{"position":[[1168,4],[1539,4],[1745,4],[2295,4],[2538,4],[2906,4],[3012,4]]}}}],["5258",{"_index":11020,"t":{"3988":{"position":[[998,4]]}}}],["525d",{"_index":4708,"t":{"1177":{"position":[[1253,4],[1388,4],[1439,4],[1487,4],[2152,4],[2405,4],[2648,4],[2690,4],[2861,4]]}}}],["528",{"_index":10720,"t":{"3744":{"position":[[1744,3],[1914,3]]}}}],["5296",{"_index":8224,"t":{"2254":{"position":[[1377,4]]}}}],["52dd",{"_index":4713,"t":{"1177":{"position":[[1320,4],[1594,4],[1645,4],[1693,4],[2222,4],[2470,4],[2756,4],[2798,4],[2967,4]]}}}],["53",{"_index":4895,"t":{"1189":{"position":[[1144,2]]}}}],["5349",{"_index":11953,"t":{"4849":{"position":[[1115,6]]}}}],["5350",{"_index":4670,"t":{"1175":{"position":[[3948,4],[4072,4],[4123,4],[4733,4],[4907,4],[5120,4],[5162,4]]}}}],["5358",{"_index":11025,"t":{"3988":{"position":[[1126,4]]},"4051":{"position":[[897,4]]}}}],["536870912",{"_index":7222,"t":{"1736":{"position":[[686,9]]}}}],["53ee",{"_index":4184,"t":{"995":{"position":[[1343,4]]},"1886":{"position":[[1343,4]]}}}],["54",{"_index":4896,"t":{"1189":{"position":[[1147,2]]},"1704":{"position":[[1831,3]]},"3744":{"position":[[1019,2]]}}}],["5411763",{"_index":6408,"t":{"1555":{"position":[[856,7]]}}}],["5428",{"_index":11071,"t":{"3990":{"position":[[1966,4]]}}}],["54f8w",{"_index":2936,"t":{"590":{"position":[[743,5]]}}}],["54h",{"_index":10696,"t":{"3744":{"position":[[1036,3]]}}}],["54t",{"_index":4488,"t":{"1116":{"position":[[20,3],[54,3]]}}}],["55",{"_index":4897,"t":{"1189":{"position":[[1150,2]]}}}],["5558",{"_index":9226,"t":{"2869":{"position":[[156,4]]}}}],["557b",{"_index":8002,"t":{"2207":{"position":[[691,4],[870,4],[921,4]]}}}],["559e5176695c",{"_index":7103,"t":{"1711":{"position":[[1175,12]]}}}],["55b2",{"_index":7997,"t":{"2207":{"position":[[635,4],[764,4],[815,4]]}}}],["56",{"_index":4898,"t":{"1189":{"position":[[1153,2]]},"3744":{"position":[[817,2],[833,2],[886,2],[931,2],[2869,2],[2877,2],[2894,2]]}}}],["561f8f76",{"_index":4161,"t":{"995":{"position":[[960,8]]},"1886":{"position":[[960,8]]}}}],["5626",{"_index":4775,"t":{"1177":{"position":[[4914,4],[5300,4],[5351,4],[5806,4],[5909,4],[6204,4],[6246,4]]}}}],["5672",{"_index":5238,"t":{"1263":{"position":[[757,10]]}}}],["568",{"_index":10713,"t":{"3744":{"position":[[1468,3],[1508,3],[1549,3]]}}}],["56f7b5bc",{"_index":4773,"t":{"1177":{"position":[[4900,8],[5286,8],[5337,8],[5792,8],[5895,8],[6190,8],[6232,8]]}}}],["56h",{"_index":10687,"t":{"3744":{"position":[[948,3]]}}}],["56x",{"_index":4497,"t":{"1118":{"position":[[777,3]]}}}],["57",{"_index":4899,"t":{"1189":{"position":[[1156,2]]}}}],["57.0.3",{"_index":9044,"t":{"2756":{"position":[[363,6]]}}}],["5702",{"_index":9083,"t":{"2764":{"position":[[281,4]]}}}],["5752b6701026478f9cac122fc54eb9cb",{"_index":3653,"t":{"912":{"position":[[4955,32]]},"914":{"position":[[4866,32],[4967,33]]},"1796":{"position":[[4955,32]]},"1798":{"position":[[4866,32],[4967,33]]}}}],["5764",{"_index":4765,"t":{"1177":{"position":[[4800,4],[5088,4],[5139,4],[5666,4],[5973,4],[6311,4],[6353,4]]}}}],["577",{"_index":6910,"t":{"1698":{"position":[[282,3],[939,3]]}}}],["5775",{"_index":8830,"t":{"2663":{"position":[[393,4]]}}}],["57b1dfc8639f",{"_index":11069,"t":{"3990":{"position":[[1938,12],[2893,12]]}}}],["58",{"_index":4900,"t":{"1189":{"position":[[1159,2]]},"3744":{"position":[[1441,2],[1458,2]]}}}],["5815",{"_index":4675,"t":{"1175":{"position":[[4004,4],[4178,4],[4229,4],[4803,4],[4972,4],[5228,4],[5270,4]]}}}],["5823",{"_index":4770,"t":{"1177":{"position":[[4857,4],[5194,4],[5245,4],[5736,4],[6101,4],[6525,4],[6567,4]]}}}],["587",{"_index":11950,"t":{"4849":{"position":[[1023,3]]}}}],["58732",{"_index":6961,"t":{"1698":{"position":[[2005,6]]}}}],["587f",{"_index":4785,"t":{"1179":{"position":[[192,4],[366,4],[417,4],[720,4],[899,4],[950,4],[1442,4],[1672,4],[1723,4]]}}}],["58a40b681d11",{"_index":4320,"t":{"1005":{"position":[[4108,12],[4330,12],[4764,12],[4879,12],[6212,12]]},"1896":{"position":[[4108,12],[4330,12],[4764,12],[4879,12],[6212,12]]}}}],["58d1",{"_index":4793,"t":{"1179":{"position":[[1498,4],[1778,4],[1829,4],[1911,4],[1972,4],[2023,4]]}}}],["59",{"_index":4901,"t":{"1189":{"position":[[1162,2]]}}}],["5:20.10.13~3",{"_index":7815,"t":{"2163":{"position":[[3062,12]]}}}],["5:20.10.14~3",{"_index":7814,"t":{"2163":{"position":[[2951,12]]}}}],["5:20.10.15~3",{"_index":7813,"t":{"2163":{"position":[[2840,12]]}}}],["5:20.10.16~3",{"_index":7812,"t":{"2163":{"position":[[2729,12]]}}}],["5:20.10.17~3",{"_index":7811,"t":{"2163":{"position":[[2618,12]]}}}],["5:20.10.18~3",{"_index":7810,"t":{"2163":{"position":[[2507,12]]}}}],["5:20.10.19~3",{"_index":7809,"t":{"2163":{"position":[[2396,12]]}}}],["5:20.10.20~3",{"_index":7808,"t":{"2163":{"position":[[2285,12]]}}}],["5:20.10.21~3",{"_index":7807,"t":{"2163":{"position":[[2174,12]]}}}],["5:20.10.22~3",{"_index":7806,"t":{"2163":{"position":[[2063,12]]}}}],["5:20.10.23~3",{"_index":7805,"t":{"2163":{"position":[[1952,12]]}}}],["5:20.10.24",{"_index":7783,"t":{"2163":{"position":[[128,12]]}}}],["5:20.10.24~3",{"_index":7803,"t":{"2163":{"position":[[1841,12]]}}}],["5:23.0.0",{"_index":7802,"t":{"2163":{"position":[[1728,8]]}}}],["5:23.0.1",{"_index":7801,"t":{"2163":{"position":[[1615,8]]}}}],["5:23.0.2",{"_index":7800,"t":{"2163":{"position":[[1502,8]]}}}],["5:23.0.3",{"_index":7799,"t":{"2163":{"position":[[1389,8]]}}}],["5:23.0.4",{"_index":7798,"t":{"2163":{"position":[[1276,8]]}}}],["5:23.0.5",{"_index":7797,"t":{"2163":{"position":[[1163,8]]}}}],["5:23.0.6",{"_index":7796,"t":{"2163":{"position":[[1050,8]]}}}],["5:24.0.0",{"_index":7795,"t":{"2163":{"position":[[937,8]]}}}],["5:24.0.1",{"_index":7794,"t":{"2163":{"position":[[824,8]]}}}],["5:24.0.2",{"_index":7793,"t":{"2163":{"position":[[711,8]]}}}],["5:24.0.3",{"_index":7792,"t":{"2163":{"position":[[598,8]]}}}],["5:24.0.4",{"_index":7791,"t":{"2163":{"position":[[485,8]]}}}],["5:24.0.5",{"_index":7790,"t":{"2163":{"position":[[372,8]]}}}],["5:24.0.6",{"_index":7786,"t":{"2163":{"position":[[259,8]]}}}],["5a06",{"_index":4333,"t":{"1005":{"position":[[5028,4],[5311,4],[5530,4],[5745,4],[6279,4]]},"1896":{"position":[[5028,4],[5311,4],[5530,4],[5745,4],[6279,4]]}}}],["5a19",{"_index":2562,"t":{"518":{"position":[[467,4]]}}}],["5b81",{"_index":4226,"t":{"995":{"position":[[2113,4]]},"1886":{"position":[[2113,4]]}}}],["5bdc445647",{"_index":2517,"t":{"493":{"position":[[56,10]]}}}],["5c",{"_index":10585,"t":{"3712":{"position":[[1590,2]]}}}],["5c6d4d7183834eafbc20108ad647a9c0",{"_index":298,"t":{"28":{"position":[[2794,32]]}}}],["5c7c984b2243",{"_index":8004,"t":{"2207":{"position":[[701,12],[880,12],[931,12]]}}}],["5d09",{"_index":8155,"t":{"2250":{"position":[[993,4]]},"2252":{"position":[[2564,4]]}}}],["5d3a9b",{"_index":9324,"t":{"2930":{"position":[[1848,9]]}}}],["5d91",{"_index":8200,"t":{"2252":{"position":[[2161,4]]}}}],["5dd5756b68",{"_index":2928,"t":{"590":{"position":[[422,10],[478,10]]}}}],["5f22e42",{"_index":11064,"t":{"3990":{"position":[[1873,8],[2869,8]]}}}],["5fde",{"_index":7160,"t":{"1713":{"position":[[2002,4],[2369,4]]}}}],["5g",{"_index":4740,"t":{"1177":{"position":[[3728,2],[3785,2],[3842,2],[3899,2]]}}}],["5gb",{"_index":10428,"t":{"3675":{"position":[[241,3]]},"3720":{"position":[[241,3]]},"3813":{"position":[[241,3]]}}}],["5m",{"_index":5559,"t":{"1303":{"position":[[1770,4],[3036,2]]},"2684":{"position":[[314,2]]}}}],["5m16",{"_index":2519,"t":{"493":{"position":[[757,5],[918,5]]}}}],["5n",{"_index":10550,"t":{"3704":{"position":[[508,2]]},"3793":{"position":[[398,2]]}}}],["5th",{"_index":1377,"t":{"194":{"position":[[12,3],[256,3]]}}}],["5x",{"_index":10318,"t":{"3661":{"position":[[320,2]]},"3698":{"position":[[412,2]]},"3785":{"position":[[412,2]]}}}],["5x/core",{"_index":10329,"t":{"3661":{"position":[[1219,7]]},"3698":{"position":[[1873,7]]},"3785":{"position":[[1571,7]]}}}],["6",{"_index":107,"t":{"12":{"position":[[271,1]]},"15":{"position":[[269,1]]},"364":{"position":[[1227,2]]},"489":{"position":[[980,1]]},"493":{"position":[[342,1]]},"938":{"position":[[907,1],[2712,1],[2732,1]]},"940":{"position":[[658,2]]},"942":{"position":[[2318,1],[2402,1]]},"1005":{"position":[[2336,1],[2486,1]]},"1007":{"position":[[264,1]]},"1175":{"position":[[1551,1],[1628,1],[1870,1],[1947,1],[2244,1],[2292,1],[2633,1],[2710,1],[2825,1],[2902,1]]},"1189":{"position":[[1067,1]]},"1201":{"position":[[277,1]]},"1226":{"position":[[278,1]]},"1385":{"position":[[1580,1]]},"1460":{"position":[[496,2]]},"1704":{"position":[[1948,1],[2396,1]]},"1711":{"position":[[1382,1],[1399,1],[1507,1],[1524,1],[1787,1],[1802,1],[1932,1],[1947,1],[2069,1],[2084,1],[2202,1],[2217,1],[2331,1],[2346,1]]},"1829":{"position":[[907,1],[2712,1],[2732,1]]},"1831":{"position":[[658,2]]},"1833":{"position":[[2318,1],[2402,1]]},"1896":{"position":[[2336,1],[2486,1]]},"1898":{"position":[[264,1]]},"2055":{"position":[[38,1]]},"2180":{"position":[[298,1]]},"2192":{"position":[[1135,1]]},"2207":{"position":[[1522,1]]},"2962":{"position":[[907,1],[2712,1],[2732,1]]},"2964":{"position":[[658,2]]},"2966":{"position":[[2318,1],[2402,1]]},"3216":{"position":[[12,1]]},"3218":{"position":[[38,1],[120,1]]},"3253":{"position":[[46,1]]},"3261":{"position":[[102,2]]},"3386":{"position":[[753,1]]},"3582":{"position":[[1913,1]]},"3606":{"position":[[1771,1]]},"3712":{"position":[[905,1]]},"3714":{"position":[[2112,1]]},"3744":{"position":[[911,1]]},"3971":{"position":[[113,1]]},"4137":{"position":[[361,2],[431,2],[577,2]]},"4139":{"position":[[64,2],[134,2],[280,2]]},"4244":{"position":[[89,2],[132,2],[201,2],[304,2],[381,2]]},"4246":{"position":[[78,2],[121,2],[190,2],[293,2],[370,2]]},"4302":{"position":[[736,1]]}}}],["6+n",{"_index":3864,"t":{"938":{"position":[[2423,3]]},"1829":{"position":[[2423,3]]},"2962":{"position":[[2423,3]]}}}],["6.0.0",{"_index":5212,"t":{"1257":{"position":[[1309,6]]},"2171":{"position":[[1449,6]]},"3183":{"position":[[52,6]]},"3185":{"position":[[67,5]]},"3195":{"position":[[65,5]]}}}],["6.0.0b",{"_index":7439,"t":{"2057":{"position":[[455,6]]}}}],["6.1.0",{"_index":5243,"t":{"1266":{"position":[[12,6]]},"3200":{"position":[[301,7]]}}}],["6.1.50",{"_index":7291,"t":{"2021":{"position":[[293,6]]}}}],["6.3.0",{"_index":3755,"t":{"930":{"position":[[649,5]]},"1821":{"position":[[649,5]]},"2954":{"position":[[649,5]]}}}],["6.4.0",{"_index":3756,"t":{"930":{"position":[[659,5]]},"1821":{"position":[[659,5]]},"2954":{"position":[[659,5]]}}}],["6.5.0",{"_index":7293,"t":{"2021":{"position":[[343,5]]}}}],["6.9",{"_index":11409,"t":{"4257":{"position":[[5997,5]]},"4270":{"position":[[687,5]]}}}],["6.testbed.osism.xyz",{"_index":7919,"t":{"2192":{"position":[[1102,19]]}}}],["6/19",{"_index":5049,"t":{"1222":{"position":[[975,6]]}}}],["6/6",{"_index":2946,"t":{"590":{"position":[[1115,3]]}}}],["60",{"_index":4913,"t":{"1189":{"position":[[1284,2]]},"1652":{"position":[[237,3]]},"1698":{"position":[[310,2],[319,2],[967,2],[976,2]]},"1977":{"position":[[237,3]]},"2772":{"position":[[140,4]]},"3744":{"position":[[1096,3]]}}}],["600",{"_index":4262,"t":{"1003":{"position":[[384,3]]},"1894":{"position":[[384,3]]},"2021":{"position":[[56,3]]}}}],["602778bad3d3470cbe58c4f7611e8eb7",{"_index":233,"t":{"28":{"position":[[815,32]]}}}],["602832daf237",{"_index":7126,"t":{"1711":{"position":[[2112,12]]}}}],["604379.969424455",{"_index":3148,"t":{"706":{"position":[[2459,17]]}}}],["61",{"_index":4914,"t":{"1189":{"position":[[1287,2]]}}}],["62",{"_index":4915,"t":{"1189":{"position":[[1290,2]]},"1704":{"position":[[2510,3]]}}}],["624b",{"_index":6456,"t":{"1564":{"position":[[288,4]]}}}],["62d6ad2a",{"_index":4193,"t":{"995":{"position":[[1525,8]]},"1886":{"position":[[1525,8]]}}}],["62e2",{"_index":4215,"t":{"995":{"position":[[1915,4]]},"1886":{"position":[[1915,4]]}}}],["63",{"_index":4916,"t":{"1189":{"position":[[1293,2]]}}}],["6379/tcp",{"_index":7777,"t":{"2155":{"position":[[2845,8]]}}}],["63b8fea6",{"_index":4198,"t":{"995":{"position":[[1621,8]]},"1886":{"position":[[1621,8]]}}}],["64",{"_index":3602,"t":{"898":{"position":[[224,2]]},"1105":{"position":[[830,2]]},"1113":{"position":[[360,2]]},"1171":{"position":[[846,2]]},"1189":{"position":[[1296,2]]},"1191":{"position":[[1152,2]]},"1468":{"position":[[534,2]]},"1756":{"position":[[224,2]]},"2011":{"position":[[127,3]]},"2017":{"position":[[26,3]]},"3671":{"position":[[221,4],[250,3],[265,3]]},"3675":{"position":[[53,4],[351,2]]},"3677":{"position":[[64,4]]},"3679":{"position":[[40,2]]},"3712":{"position":[[273,2],[295,2],[321,2],[562,3],[577,3]]},"3714":{"position":[[2029,2]]},"3720":{"position":[[53,4],[271,2]]},"3744":{"position":[[302,2],[704,2],[2164,2],[2513,2]]},"3791":{"position":[[62,4]]},"3793":{"position":[[40,2]]},"3805":{"position":[[221,4],[341,3],[356,3]]},"3813":{"position":[[53,4],[271,2],[351,2]]},"3896":{"position":[[66,4]]}}}],["6443",{"_index":9208,"t":{"2853":{"position":[[55,4]]},"4537":{"position":[[967,4]]},"4539":{"position":[[374,4]]},"4547":{"position":[[1481,5]]},"4849":{"position":[[1195,4]]}}}],["6443/tcp",{"_index":9212,"t":{"2853":{"position":[[219,8]]}}}],["645538bf67664cfeaed32476d58f95fb",{"_index":3648,"t":{"912":{"position":[[4367,32]]},"1796":{"position":[[4367,32]]}}}],["64_ib",{"_index":10542,"t":{"3702":{"position":[[1942,5]]},"3789":{"position":[[1801,5]]},"3813":{"position":[[283,5]]}}}],["64g",{"_index":10743,"t":{"3744":{"position":[[2255,3]]}}}],["64gb",{"_index":91,"t":{"12":{"position":[[126,4]]},"15":{"position":[[124,4]]}}}],["64gib",{"_index":10431,"t":{"3675":{"position":[[311,5]]},"3677":{"position":[[871,5]]},"3720":{"position":[[314,5]]},"3791":{"position":[[893,5]]},"3813":{"position":[[311,5]]},"3904":{"position":[[296,5]]}}}],["64h",{"_index":10745,"t":{"3744":{"position":[[2273,3]]}}}],["64k",{"_index":6624,"t":{"1650":{"position":[[203,5]]},"1975":{"position":[[203,5]]}}}],["64m",{"_index":6627,"t":{"1650":{"position":[[225,5]]},"1975":{"position":[[225,5]]}}}],["65",{"_index":4917,"t":{"1189":{"position":[[1299,2]]}}}],["6510",{"_index":6857,"t":{"1694":{"position":[[5673,4]]}}}],["652e",{"_index":11030,"t":{"3988":{"position":[[1255,4]]}}}],["652e3a6c",{"_index":3580,"t":{"894":{"position":[[2122,8]]},"1752":{"position":[[2122,8]]}}}],["654.4mb",{"_index":6453,"t":{"1564":{"position":[[212,7]]}}}],["65401",{"_index":5318,"t":{"1275":{"position":[[809,5]]}}}],["65402",{"_index":5319,"t":{"1275":{"position":[[852,5]]}}}],["6578bd6756",{"_index":2940,"t":{"590":{"position":[[1011,10]]}}}],["65ac",{"_index":11102,"t":{"3990":{"position":[[2334,4]]}}}],["65e5",{"_index":4779,"t":{"1179":{"position":[[131,4],[255,4],[306,4],[659,4],[788,4],[839,4],[1381,4],[1561,4],[1612,4]]}}}],["66",{"_index":4918,"t":{"1189":{"position":[[1302,2]]},"2930":{"position":[[1810,3]]},"3744":{"position":[[1797,2],[1813,2],[1971,2],[1988,2]]},"4707":{"position":[[659,2],[854,2]]}}}],["660",{"_index":6379,"t":{"1552":{"position":[[644,3]]}}}],["6656",{"_index":10741,"t":{"3744":{"position":[[2246,4]]}}}],["66595ea9fb21",{"_index":11129,"t":{"4026":{"position":[[911,12]]},"4030":{"position":[[858,12]]}}}],["666097e396fd4f9392d6aa55c76d8267",{"_index":3656,"t":{"912":{"position":[[5552,32]]},"1796":{"position":[[5552,32]]}}}],["6674",{"_index":4220,"t":{"995":{"position":[[2014,4]]},"1886":{"position":[[2014,4]]}}}],["667649d6",{"_index":4288,"t":{"1005":{"position":[[2747,8]]},"1896":{"position":[[2747,8]]}}}],["669c",{"_index":4565,"t":{"1163":{"position":[[248,4]]}}}],["67",{"_index":4919,"t":{"1189":{"position":[[1305,2]]},"2930":{"position":[[1882,3]]},"4707":{"position":[[869,2]]}}}],["6789",{"_index":5999,"t":{"1405":{"position":[[1362,6]]}}}],["68",{"_index":4920,"t":{"1189":{"position":[[1308,2]]},"1694":{"position":[[1229,2],[1895,3],[6748,2]]}}}],["69",{"_index":4921,"t":{"1189":{"position":[[1311,2]]},"1694":{"position":[[1182,2],[1450,2],[1590,2]]}}}],["690dee14",{"_index":4208,"t":{"995":{"position":[[1811,8]]},"1886":{"position":[[1811,8]]}}}],["6912",{"_index":10689,"t":{"3744":{"position":[[969,4],[1146,4]]}}}],["6a",{"_index":250,"t":{"28":{"position":[[1213,2]]}}}],["6ac9a526",{"_index":5149,"t":{"1236":{"position":[[1053,8],[1184,8]]}}}],["6ace51bb",{"_index":11019,"t":{"3988":{"position":[[989,8]]}}}],["6bb4c7d6b6",{"_index":2919,"t":{"590":{"position":[[210,10],[275,10]]}}}],["6c47b9d8537b",{"_index":8222,"t":{"2254":{"position":[[1338,12]]}}}],["6c6eba43f616bc6b.yaml",{"_index":7471,"t":{"2065":{"position":[[409,21]]}}}],["6d15",{"_index":7052,"t":{"1704":{"position":[[1567,4],[1630,4],[1959,4],[1964,5]]}}}],["6d159e",{"_index":7055,"t":{"1704":{"position":[[1635,8]]}}}],["6d1986e4",{"_index":4167,"t":{"995":{"position":[[1053,8]]},"1886":{"position":[[1053,8]]}}}],["6d57f39aacbe485d87733865b1e79d03",{"_index":3668,"t":{"912":{"position":[[7389,32]]},"914":{"position":[[2220,32],[2320,33]]},"1796":{"position":[[7389,32]]},"1798":{"position":[[2220,32],[2320,33]]}}}],["6ee4b373cb6d42a5bb59d5080987b70d",{"_index":277,"t":{"28":{"position":[[1880,32]]}}}],["6ef6",{"_index":8160,"t":{"2250":{"position":[[1064,4]]},"2252":{"position":[[2778,4]]}}}],["6f89488ef3a4",{"_index":8192,"t":{"2252":{"position":[[2076,12]]}}}],["6g",{"_index":10684,"t":{"3744":{"position":[[896,2]]}}}],["6h",{"_index":10619,"t":{"3714":{"position":[[2044,2]]}}}],["6m43",{"_index":2918,"t":{"590":{"position":[[176,5],[812,5],[1199,5]]}}}],["6m44",{"_index":2924,"t":{"590":{"position":[[351,5],[763,5],[1269,5],[1409,5]]}}}],["6m45",{"_index":2926,"t":{"590":{"position":[[396,5],[909,5]]}}}],["7",{"_index":87,"t":{"12":{"position":[[109,1]]},"15":{"position":[[107,1]]},"364":{"position":[[1296,2]]},"938":{"position":[[1395,2]]},"1189":{"position":[[1069,1]]},"1385":{"position":[[1884,2]]},"1435":{"position":[[193,1]]},"1515":{"position":[[17,2]]},"1555":{"position":[[1143,1]]},"1605":{"position":[[334,1],[1127,1],[1770,1],[1886,1]]},"1673":{"position":[[211,1]]},"1704":{"position":[[2627,1]]},"1711":{"position":[[2455,1],[2470,1],[2596,1],[2611,1],[2704,1],[2719,1],[2834,1],[2849,1],[2942,1],[2957,1],[3052,1],[3067,1]]},"1829":{"position":[[1395,2]]},"2192":{"position":[[1197,1]]},"2207":{"position":[[1671,1]]},"2962":{"position":[[1395,2]]},"3274":{"position":[[8,1]]},"3279":{"position":[[592,1],[673,2]]},"4137":{"position":[[364,2],[434,2],[580,2]]},"4139":{"position":[[67,2],[137,2],[283,2]]},"4244":{"position":[[92,2],[204,2],[384,2]]},"4246":{"position":[[81,2],[193,2],[373,2]]},"4302":{"position":[[842,1]]},"4370":{"position":[[40,2]]}}}],["7,2",{"_index":10911,"t":{"3894":{"position":[[398,3]]}}}],["7,68",{"_index":4401,"t":{"1042":{"position":[[984,4]]}}}],["7.0",{"_index":7280,"t":{"2013":{"position":[[297,3]]},"2236":{"position":[[13,3]]},"4257":{"position":[[5960,3]]},"4270":{"position":[[650,3]]}}}],["7.0.0",{"_index":5125,"t":{"1228":{"position":[[166,8]]},"1257":{"position":[[691,5],[705,5]]},"1503":{"position":[[1127,6],[1393,5],[1407,5]]},"2171":{"position":[[853,5],[867,5]]},"3221":{"position":[[52,5]]},"3240":{"position":[[65,5]]},"3261":{"position":[[60,5]]}}}],["7.0.2",{"_index":5204,"t":{"1257":{"position":[[169,5]]},"2171":{"position":[[169,5]]}}}],["7.0.3",{"_index":6316,"t":{"1507":{"position":[[23,5]]},"1509":{"position":[[23,5]]},"2644":{"position":[[516,5]]},"2672":{"position":[[516,5]]}}}],["7.0.4",{"_index":5037,"t":{"1222":{"position":[[673,8],[1330,8]]},"1230":{"position":[[901,5]]}}}],["7.0.5",{"_index":5184,"t":{"1252":{"position":[[42,6]]},"1257":{"position":[[178,6],[215,5]]},"2171":{"position":[[178,6],[297,5],[2036,6]]}}}],["7.0.6",{"_index":5433,"t":{"1297":{"position":[[1300,6]]},"1552":{"position":[[133,5]]},"1555":{"position":[[234,6]]},"1707":{"position":[[62,6]]}}}],["7.2h",{"_index":10331,"t":{"3661":{"position":[[1356,4]]},"3698":{"position":[[2010,4]]},"3785":{"position":[[1708,4]]}}}],["7.2h/month",{"_index":10320,"t":{"3661":{"position":[[506,12]]},"3698":{"position":[[611,12]]},"3785":{"position":[[611,12]]}}}],["7.68",{"_index":4471,"t":{"1107":{"position":[[512,4]]}}}],["7.8kb",{"_index":6460,"t":{"1564":{"position":[[359,5]]}}}],["7.testbed.osism.xyz",{"_index":7921,"t":{"2192":{"position":[[1164,19]]}}}],["7/19",{"_index":5052,"t":{"1222":{"position":[[1013,6]]}}}],["70",{"_index":4922,"t":{"1189":{"position":[[1314,2]]},"2005":{"position":[[166,2]]},"4261":{"position":[[585,3]]},"4263":{"position":[[110,3]]}}}],["7000",{"_index":4800,"t":{"1181":{"position":[[330,4]]},"1183":{"position":[[1099,7]]},"1427":{"position":[[212,4]]}}}],["709b8c6c",{"_index":4732,"t":{"1177":{"position":[[3623,8]]}}}],["70g",{"_index":10733,"t":{"3744":{"position":[[1974,3]]}}}],["70h",{"_index":10734,"t":{"3744":{"position":[[1991,3]]}}}],["71",{"_index":4923,"t":{"1189":{"position":[[1317,2]]}}}],["7168",{"_index":10772,"t":{"3744":{"position":[[2872,4]]}}}],["718964b4b87446688ac04b151519fb51",{"_index":318,"t":{"33":{"position":[[74,32]]}}}],["718aecaddde1",{"_index":7146,"t":{"1711":{"position":[[2862,12]]}}}],["718b",{"_index":8239,"t":{"2254":{"position":[[1561,4]]}}}],["71902b03",{"_index":8218,"t":{"2254":{"position":[[1314,8]]}}}],["71a8b930",{"_index":8210,"t":{"2254":{"position":[[363,8],[715,8],[1275,8],[1459,8]]},"2256":{"position":[[69,8]]}}}],["71e54cfb",{"_index":4778,"t":{"1179":{"position":[[122,8],[246,8],[297,8],[650,8],[779,8],[830,8],[1372,8],[1552,8],[1603,8]]}}}],["72",{"_index":4924,"t":{"1189":{"position":[[1320,2]]},"3720":{"position":[[283,2],[354,2]]},"3744":{"position":[[480,2],[497,2],[1870,3]]}}}],["73",{"_index":4925,"t":{"1189":{"position":[[1323,2]]}}}],["73967e73",{"_index":8172,"t":{"2252":{"position":[[1153,8],[2633,8]]}}}],["73edb86b",{"_index":11084,"t":{"3990":{"position":[[2115,8]]}}}],["74",{"_index":4926,"t":{"1189":{"position":[[1326,2]]}}}],["7413",{"_index":11051,"t":{"3990":{"position":[[1710,4]]}}}],["7424",{"_index":10710,"t":{"3744":{"position":[[1436,4]]}}}],["743db4661305",{"_index":6663,"t":{"1659":{"position":[[91,12],[225,12]]}}}],["74f9bddc",{"_index":4172,"t":{"995":{"position":[[1146,8]]},"1886":{"position":[[1146,8]]}}}],["75",{"_index":4927,"t":{"1189":{"position":[[1329,2]]}}}],["7514191fecc",{"_index":4286,"t":{"1005":{"position":[[2637,12]]},"1896":{"position":[[2637,12]]}}}],["75279777029847ab9b399390c0dd6042",{"_index":288,"t":{"28":{"position":[[2274,32]]}}}],["758ee36fb132",{"_index":7156,"t":{"1713":{"position":[[1066,12],[1359,12]]}}}],["75960289",{"_index":4706,"t":{"1177":{"position":[[1239,8],[1374,8],[1425,8],[1473,8],[2138,8],[2391,8],[2634,8],[2676,8],[2847,8]]}}}],["76",{"_index":4928,"t":{"1189":{"position":[[1332,2]]}}}],["7636",{"_index":2052,"t":{"319":{"position":[[569,5]]},"327":{"position":[[156,5]]}}}],["77",{"_index":4929,"t":{"1189":{"position":[[1335,2]]}}}],["7725",{"_index":4179,"t":{"995":{"position":[[1248,4]]},"1886":{"position":[[1248,4]]}}}],["776696786b",{"_index":2944,"t":{"590":{"position":[[1098,10]]}}}],["78",{"_index":4930,"t":{"1189":{"position":[[1338,2]]}}}],["78d588d58b",{"_index":9229,"t":{"2873":{"position":[[325,10]]}}}],["79",{"_index":4931,"t":{"1189":{"position":[[1341,2]]}}}],["79eb6088a9a1",{"_index":8182,"t":{"2252":{"position":[[1985,12]]}}}],["7c",{"_index":7699,"t":{"2139":{"position":[[474,2]]}}}],["7c8bd5a49fdd",{"_index":7211,"t":{"1732":{"position":[[688,12],[1499,12]]},"1734":{"position":[[689,12],[1693,12]]}}}],["7cc4",{"_index":4669,"t":{"1175":{"position":[[3943,4],[4067,4],[4118,4],[4728,4],[4902,4],[5115,4],[5157,4]]}}}],["7d4f64d10909",{"_index":11018,"t":{"3988":{"position":[[954,12]]},"4051":{"position":[[853,12]]}}}],["7d5df526b640",{"_index":7726,"t":{"2144":{"position":[[179,12],[322,12],[447,12],[590,12],[715,12],[858,12],[983,12],[1126,12],[1251,12]]}}}],["7d7b",{"_index":4199,"t":{"995":{"position":[[1630,4]]},"1886":{"position":[[1630,4]]}}}],["7e18881932f749baa7d547ebd407b8d8",{"_index":300,"t":{"28":{"position":[[2898,32]]}}}],["7fa7e7c88700",{"_index":6917,"t":{"1698":{"position":[[451,12],[615,12]]}}}],["7fa7eb48f700",{"_index":6946,"t":{"1698":{"position":[[1303,12]]}}}],["7fdbc9728700",{"_index":6934,"t":{"1698":{"position":[[1071,12]]}}}],["7ff828230b8e",{"_index":8232,"t":{"2254":{"position":[[1431,12]]}}}],["7ff9188",{"_index":2507,"t":{"489":{"position":[[1333,7],[1415,7]]},"570":{"position":[[221,7]]}}}],["7m51",{"_index":2365,"t":{"434":{"position":[[1270,5]]}}}],["7m57",{"_index":2921,"t":{"590":{"position":[[241,5],[1042,5],[1129,5]]}}}],["7m58",{"_index":2916,"t":{"590":{"position":[[131,5],[306,5],[1339,5]]}}}],["7m9",{"_index":2954,"t":{"590":{"position":[[1482,4]]}}}],["7rdn6",{"_index":9230,"t":{"2873":{"position":[[336,5]]}}}],["8",{"_index":2148,"t":{"364":{"position":[[1377,2]]},"555":{"position":[[348,1],[391,1]]},"871":{"position":[[629,1]]},"873":{"position":[[623,1]]},"887":{"position":[[9141,1]]},"894":{"position":[[1317,1]]},"914":{"position":[[5558,2]]},"932":{"position":[[1162,1]]},"940":{"position":[[452,2],[503,1]]},"1003":{"position":[[174,1]]},"1005":{"position":[[2454,1],[2570,1]]},"1007":{"position":[[295,1]]},"1040":{"position":[[710,1]]},"1187":{"position":[[784,1]]},"1189":{"position":[[1071,1]]},"1466":{"position":[[573,1],[2889,2]]},"1694":{"position":[[5894,1]]},"1752":{"position":[[1317,1]]},"1772":{"position":[[629,1]]},"1774":{"position":[[623,1]]},"1798":{"position":[[5558,2]]},"1811":{"position":[[9141,1]]},"1823":{"position":[[1162,1]]},"1831":{"position":[[452,2],[503,1]]},"1894":{"position":[[174,1]]},"1896":{"position":[[2454,1],[2570,1]]},"1898":{"position":[[295,1]]},"2013":{"position":[[9,1]]},"2019":{"position":[[9,1]]},"2027":{"position":[[388,1]]},"2034":{"position":[[284,1],[1405,1]]},"2041":{"position":[[45,1]]},"2059":{"position":[[2284,2]]},"2192":{"position":[[1259,1]]},"2216":{"position":[[302,1],[417,2],[442,2],[459,2],[485,2],[511,2],[536,2],[558,2]]},"2252":{"position":[[246,1]]},"2360":{"position":[[1479,5]]},"2427":{"position":[[1479,5]]},"2956":{"position":[[1162,1]]},"2964":{"position":[[452,2],[503,1]]},"3661":{"position":[[735,2]]},"3675":{"position":[[104,1]]},"3688":{"position":[[42,2]]},"3698":{"position":[[845,2]]},"3704":{"position":[[470,1]]},"3720":{"position":[[104,1]]},"3744":{"position":[[2448,1]]},"3785":{"position":[[830,2]]},"3791":{"position":[[238,2],[248,1],[374,2],[384,1],[462,2],[472,1]]},"3813":{"position":[[104,1]]},"3824":{"position":[[118,3]]},"3898":{"position":[[100,1],[116,1],[195,1],[305,1],[321,1],[333,1],[386,1],[402,1]]},"3900":{"position":[[112,1],[131,1],[195,1],[301,1],[320,1],[344,1],[420,1],[439,1]]},"4137":{"position":[[583,2]]},"4139":{"position":[[286,2]]},"4244":{"position":[[95,2],[207,2],[387,2]]},"4246":{"position":[[84,2],[196,2],[376,2]]},"4302":{"position":[[1037,1]]},"4344":{"position":[[184,2]]},"4355":{"position":[[489,1]]}}}],["8.0.0",{"_index":5637,"t":{"1314":{"position":[[240,5],[254,5]]},"1316":{"position":[[541,5],[555,5]]},"2171":{"position":[[2338,5]]},"3279":{"position":[[52,5]]},"3300":{"position":[[65,5]]},"3310":{"position":[[19,5]]}}}],["8.4",{"_index":6001,"t":{"1405":{"position":[[1538,3]]}}}],["8.8.4.4",{"_index":5288,"t":{"1268":{"position":[[322,9]]}}}],["8.8.8.8",{"_index":5114,"t":{"1226":{"position":[[5641,7]]},"1268":{"position":[[311,10]]},"2048":{"position":[[3404,7]]},"2219":{"position":[[312,11]]}}}],["8.9",{"_index":11408,"t":{"4257":{"position":[[5966,5]]},"4270":{"position":[[656,5]]}}}],["8.testbed.osism.xyz",{"_index":7923,"t":{"2192":{"position":[[1226,19]]}}}],["8/19",{"_index":5055,"t":{"1222":{"position":[[1055,6]]}}}],["8/20",{"_index":5018,"t":{"1220":{"position":[[472,6]]}}}],["80",{"_index":1918,"t":{"293":{"position":[[741,2]]},"940":{"position":[[700,3]]},"961":{"position":[[862,2],[1121,2]]},"1297":{"position":[[1864,5]]},"1669":{"position":[[225,2]]},"1675":{"position":[[179,2]]},"1831":{"position":[[700,3]]},"1852":{"position":[[862,2],[1121,2]]},"2117":{"position":[[273,2],[1389,2]]},"2139":{"position":[[492,2]]},"2199":{"position":[[1271,2]]},"2293":{"position":[[802,2]]},"2307":{"position":[[802,2]]},"2732":{"position":[[569,2]]},"2740":{"position":[[1047,2]]},"2853":{"position":[[82,2]]},"2964":{"position":[[700,3]]},"2985":{"position":[[862,2],[1121,2]]}}}],["80/tcp",{"_index":9213,"t":{"2853":{"position":[[339,6]]}}}],["8000/tcp",{"_index":7759,"t":{"2155":{"position":[[1507,9],[1651,8]]}}}],["802.1ae",{"_index":11341,"t":{"4226":{"position":[[1670,8]]}}}],["805460b998ce",{"_index":4218,"t":{"995":{"position":[[1930,12]]},"1886":{"position":[[1930,12]]}}}],["8080/tcp",{"_index":7143,"t":{"1711":{"position":[[2745,9]]}}}],["8080:80",{"_index":3250,"t":{"753":{"position":[[163,7]]}}}],["8080:8080",{"_index":9231,"t":{"2873":{"position":[[342,9]]}}}],["8081",{"_index":6013,"t":{"1407":{"position":[[583,4]]}}}],["8086",{"_index":3986,"t":{"957":{"position":[[148,4],[202,7]]},"1848":{"position":[[148,4],[202,7]]},"2981":{"position":[[148,4],[202,7]]}}}],["80:30799/tcp,443:32482/tcp",{"_index":3045,"t":{"692":{"position":[[314,26]]},"747":{"position":[[233,26]]}}}],["80a14597f583",{"_index":4795,"t":{"1179":{"position":[[1508,12],[1788,12],[1839,12],[1921,12],[1982,12],[2033,12]]}}}],["80af",{"_index":11063,"t":{"3990":{"position":[[1848,4],[2621,4],[2835,4]]}}}],["80e6246a803b\"},{\"displayname\":\"unknown\",\"id\":\"6cadd69a",{"_index":9082,"t":{"2764":{"position":[[226,54]]}}}],["80g",{"_index":10691,"t":{"3744":{"position":[[978,3],[1155,3],[1758,3]]}}}],["80h",{"_index":10693,"t":{"3744":{"position":[[997,3],[1173,3],[1775,3]]}}}],["81.163.194.219",{"_index":3044,"t":{"692":{"position":[[299,14]]},"747":{"position":[[218,14]]}}}],["8132",{"_index":8251,"t":{"2256":{"position":[[450,4]]}}}],["8140",{"_index":4818,"t":{"1183":{"position":[[928,5]]}}}],["8155",{"_index":6979,"t":{"1700":{"position":[[283,4]]}}}],["8186",{"_index":3981,"t":{"955":{"position":[[538,7]]},"1846":{"position":[[538,7]]},"2979":{"position":[[538,7]]}}}],["8187",{"_index":7161,"t":{"1713":{"position":[[2007,4],[2374,4]]}}}],["8192",{"_index":3720,"t":{"914":{"position":[[5292,5]]},"1201":{"position":[[608,4]]},"1798":{"position":[[5292,5]]}}}],["822665f46070",{"_index":11028,"t":{"3988":{"position":[[1211,12]]},"4051":{"position":[[982,12]]}}}],["8268b05ef24b41d8806c0fe417576610",{"_index":4177,"t":{"995":{"position":[[1185,32],[1278,32],[1468,32],[1564,32],[1945,32]]},"1886":{"position":[[1185,32],[1278,32],[1468,32],[1564,32],[1945,32]]}}}],["826a",{"_index":10252,"t":{"3594":{"position":[[311,4]]}}}],["82b0",{"_index":4774,"t":{"1177":{"position":[[4909,4],[5295,4],[5346,4],[5801,4],[5904,4],[6199,4],[6241,4]]}}}],["82b7",{"_index":11087,"t":{"3990":{"position":[[2134,4]]}}}],["834b",{"_index":9090,"t":{"2766":{"position":[[226,4]]},"2768":{"position":[[81,4],[166,4]]},"2780":{"position":[[222,4]]},"2782":{"position":[[215,4]]},"2784":{"position":[[215,4]]},"2786":{"position":[[196,4]]}}}],["8381",{"_index":4253,"t":{"995":{"position":[[3016,4]]},"1886":{"position":[[3016,4]]}}}],["84",{"_index":10679,"t":{"3744":{"position":[[517,2],[534,2]]}}}],["8448",{"_index":10726,"t":{"3744":{"position":[[1792,4]]}}}],["84a4",{"_index":8241,"t":{"2254":{"position":[[1571,4]]}}}],["84a5",{"_index":7243,"t":{"1743":{"position":[[166,4]]}}}],["84d52cf6c60b",{"_index":4187,"t":{"995":{"position":[[1358,12]]},"1886":{"position":[[1358,12]]}}}],["84ea",{"_index":7210,"t":{"1732":{"position":[[683,4],[1494,4]]},"1734":{"position":[[684,4],[1688,4]]}}}],["8518d3a2",{"_index":4763,"t":{"1177":{"position":[[4786,8],[5074,8],[5125,8],[5652,8],[5959,8],[6297,8],[6339,8]]}}}],["854e7c55",{"_index":4214,"t":{"995":{"position":[[1906,8]]},"1886":{"position":[[1906,8]]}}}],["8601",{"_index":1797,"t":{"258":{"position":[[629,4]]}}}],["86399",{"_index":9273,"t":{"2908":{"position":[[445,6]]}}}],["8651",{"_index":11067,"t":{"3990":{"position":[[1892,4],[2888,4]]}}}],["8659",{"_index":4244,"t":{"995":{"position":[[2447,4]]},"1886":{"position":[[2447,4]]}}}],["8678",{"_index":8181,"t":{"2252":{"position":[[1980,4]]}}}],["868b",{"_index":4181,"t":{"995":{"position":[[1258,4]]},"1886":{"position":[[1258,4]]}}}],["869fe071",{"_index":2752,"t":{"557":{"position":[[2084,9]]}}}],["87d6",{"_index":7057,"t":{"1704":{"position":[[1730,4],[1741,4],[1912,5],[1920,4],[2004,4],[2009,5]]}}}],["87dabc34ba56",{"_index":8242,"t":{"2254":{"position":[[1576,12]]}}}],["87e3",{"_index":8196,"t":{"2252":{"position":[[2112,4]]}}}],["88",{"_index":7697,"t":{"2139":{"position":[[453,2]]}}}],["8831",{"_index":7003,"t":{"1702":{"position":[[251,4]]}}}],["8833",{"_index":4761,"t":{"1177":{"position":[[4748,4],[4987,4],[5038,4],[5601,4],[6042,4],[6423,4],[6465,4]]}}}],["8871",{"_index":4291,"t":{"1005":{"position":[[2766,4]]},"1896":{"position":[[2766,4]]}}}],["8891",{"_index":8213,"t":{"2254":{"position":[[382,4],[734,4],[1294,4],[1478,4]]},"2256":{"position":[[88,4]]}}}],["88ca",{"_index":4239,"t":{"995":{"position":[[2341,4]]},"1886":{"position":[[2341,4]]}}}],["890",{"_index":6853,"t":{"1694":{"position":[[5176,3]]},"3264":{"position":[[158,4]]}}}],["891",{"_index":6850,"t":{"1694":{"position":[[5047,3]]}}}],["892",{"_index":6846,"t":{"1694":{"position":[[4929,3]]}}}],["893",{"_index":6843,"t":{"1694":{"position":[[4779,3]]}}}],["893d",{"_index":11077,"t":{"3990":{"position":[[2013,4]]}}}],["894",{"_index":6840,"t":{"1694":{"position":[[4618,3]]}}}],["895",{"_index":6837,"t":{"1694":{"position":[[4465,3]]}}}],["896",{"_index":6834,"t":{"1694":{"position":[[4322,3]]},"3744":{"position":[[889,3]]}}}],["897",{"_index":6831,"t":{"1694":{"position":[[4188,3]]}}}],["898",{"_index":6828,"t":{"1694":{"position":[[4053,3]]}}}],["899",{"_index":6825,"t":{"1694":{"position":[[3918,3]]}}}],["8:16",{"_index":10466,"t":{"3677":{"position":[[391,4]]},"3791":{"position":[[389,4]]}}}],["8:32",{"_index":10454,"t":{"3677":{"position":[[284,4]]},"3791":{"position":[[282,4]]}}}],["8a45",{"_index":4671,"t":{"1175":{"position":[[3953,4],[4077,4],[4128,4],[4738,4],[4912,4],[5125,4],[5167,4]]}}}],["8a553e69",{"_index":6746,"t":{"1686":{"position":[[505,8]]}}}],["8a69cc7a",{"_index":6923,"t":{"1698":{"position":[[718,9]]}}}],["8ad3",{"_index":2749,"t":{"557":{"position":[[1971,4]]}}}],["8b03",{"_index":11104,"t":{"3990":{"position":[[2344,4]]}}}],["8bb5",{"_index":4709,"t":{"1177":{"position":[[1258,4],[1393,4],[1444,4],[1492,4],[2157,4],[2410,4],[2653,4],[2695,4],[2866,4]]}}}],["8bit",{"_index":6731,"t":{"1673":{"position":[[357,4]]}}}],["8bit:ascii",{"_index":6730,"t":{"1673":{"position":[[346,10]]}}}],["8c",{"_index":4476,"t":{"1111":{"position":[[214,2]]}}}],["8c42",{"_index":4771,"t":{"1177":{"position":[[4862,4],[5199,4],[5250,4],[5741,4],[6106,4],[6530,4],[6572,4]]}}}],["8c73",{"_index":11108,"t":{"3990":{"position":[[2384,4]]}}}],["8c95",{"_index":8231,"t":{"2254":{"position":[[1426,4]]}}}],["8c:16:50",{"_index":10506,"t":{"3681":{"position":[[844,8]]}}}],["8ce05d",{"_index":9322,"t":{"2930":{"position":[[1764,9]]}}}],["8d1f",{"_index":4319,"t":{"1005":{"position":[[4103,4],[4325,4],[4759,4],[4874,4],[6207,4]]},"1896":{"position":[[4103,4],[4325,4],[4759,4],[4874,4],[6207,4]]}}}],["8d372de6",{"_index":4338,"t":{"1005":{"position":[[5183,8],[5421,8],[5621,8],[5851,8],[6352,8]]},"1896":{"position":[[5183,8],[5421,8],[5621,8],[5851,8],[6352,8]]}}}],["8d7e",{"_index":4704,"t":{"1177":{"position":[[1173,4],[1544,4],[1750,4],[2300,4],[2543,4],[2911,4],[3017,4]]}}}],["8df1b7",{"_index":7037,"t":{"1704":{"position":[[791,6],[1189,8]]}}}],["8e23",{"_index":11073,"t":{"3990":{"position":[[1976,4]]}}}],["8e2b",{"_index":8236,"t":{"2254":{"position":[[1517,4]]}}}],["8e40",{"_index":4794,"t":{"1179":{"position":[[1503,4],[1783,4],[1834,4],[1916,4],[1977,4],[2028,4]]}}}],["8e80",{"_index":8169,"t":{"2252":{"position":[[1056,4]]}}}],["8e8bd5227ebf\",\"apiversion\":\"infrastructure.clusterstack.x",{"_index":2565,"t":{"518":{"position":[[482,57]]}}}],["8ed4",{"_index":7182,"t":{"1720":{"position":[[476,4],[1002,4],[1712,4],[2526,4]]}}}],["8f09",{"_index":4781,"t":{"1179":{"position":[[141,4],[265,4],[316,4],[669,4],[798,4],[849,4],[1391,4],[1571,4],[1622,4]]}}}],["8f53",{"_index":4186,"t":{"995":{"position":[[1353,4]]},"1886":{"position":[[1353,4]]}}}],["8f69",{"_index":2722,"t":{"557":{"position":[[909,4]]}}}],["8fb231442edc",{"_index":4772,"t":{"1177":{"position":[[4867,12],[5204,12],[5255,12],[5746,12],[6111,12],[6535,12],[6577,12]]}}}],["8fde",{"_index":9104,"t":{"2776":{"position":[[144,4]]}}}],["8fe7d0",{"_index":7028,"t":{"1704":{"position":[[594,7]]}}}],["8gb",{"_index":5895,"t":{"1383":{"position":[[735,3]]}}}],["8gib",{"_index":10494,"t":{"3679":{"position":[[537,4]]},"3690":{"position":[[1191,4]]},"3777":{"position":[[1292,4]]},"3793":{"position":[[540,4]]}}}],["8gigabyt",{"_index":4276,"t":{"1005":{"position":[[2308,10]]},"1896":{"position":[[2308,10]]}}}],["8h",{"_index":11567,"t":{"4491":{"position":[[300,2]]}}}],["8m3",{"_index":2930,"t":{"590":{"position":[[453,4],[509,4],[568,4],[637,4],[715,4],[861,4],[979,4]]}}}],["8mzrx",{"_index":2914,"t":{"590":{"position":[[111,5]]}}}],["8s",{"_index":10548,"t":{"3704":{"position":[[435,2]]},"3793":{"position":[[499,2]]}}}],["8t",{"_index":10623,"t":{"3718":{"position":[[638,2],[663,2],[678,2],[699,2],[883,2]]},"3811":{"position":[[638,2],[663,2],[678,2],[699,2],[883,2]]}}}],["8t:16:50",{"_index":10501,"t":{"3681":{"position":[[599,8]]}}}],["8t:16:50n",{"_index":10502,"t":{"3681":{"position":[[624,10],[639,9],[660,9]]}}}],["8th",{"_index":9797,"t":{"3162":{"position":[[754,3]]}}}],["8ti",{"_index":10627,"t":{"3720":{"position":[[90,3]]},"3813":{"position":[[90,3]]}}}],["8ti:32:50p",{"_index":10422,"t":{"3675":{"position":[[90,10]]}}}],["8v",{"_index":3574,"t":{"894":{"position":[[1421,2]]},"1752":{"position":[[1421,2]]},"2178":{"position":[[1074,2]]},"2219":{"position":[[423,2]]},"2252":{"position":[[227,2],[2539,2]]},"2254":{"position":[[483,2]]},"3704":{"position":[[1268,2]]},"3791":{"position":[[291,2],[302,2],[398,2],[409,2]]},"3793":{"position":[[800,2]]},"3898":{"position":[[189,2],[327,2]]},"3900":{"position":[[185,2],[335,2]]}}}],["8v:16",{"_index":10467,"t":{"3677":{"position":[[400,6]]}}}],["8v:16:100",{"_index":115,"t":{"12":{"position":[[330,9]]},"15":{"position":[[328,9]]}}}],["8v:16:50",{"_index":10468,"t":{"3677":{"position":[[411,8]]}}}],["8v:32",{"_index":10455,"t":{"3677":{"position":[[293,6]]}}}],["8v:32:100",{"_index":10456,"t":{"3677":{"position":[[304,9]]},"3679":{"position":[[638,11]]}}}],["8z8kb",{"_index":2937,"t":{"590":{"position":[[792,5]]}}}],["9",{"_index":2149,"t":{"364":{"position":[[1464,2]]},"887":{"position":[[1799,1],[1954,1],[2278,1],[2407,1],[2528,1],[2833,1],[5279,1],[5416,1],[5586,1],[5704,1]]},"942":{"position":[[963,5]]},"1189":{"position":[[1073,1]]},"1811":{"position":[[1799,1],[1954,1],[2278,1],[2407,1],[2528,1],[2833,1],[5279,1],[5416,1],[5586,1],[5704,1]]},"1833":{"position":[[963,5]]},"2180":{"position":[[177,1]]},"2192":{"position":[[1321,1]]},"2966":{"position":[[963,5]]},"3279":{"position":[[258,1]]},"3874":{"position":[[189,6]]},"3876":{"position":[[230,6]]},"4137":{"position":[[586,2]]},"4139":{"position":[[289,2]]},"4244":{"position":[[98,2],[210,2],[390,2]]},"4246":{"position":[[87,2],[199,2],[379,2]]},"4302":{"position":[[1198,1]]},"4560":{"position":[[4257,2]]}}}],["9.0",{"_index":10844,"t":{"3829":{"position":[[2874,3]]},"4257":{"position":[[5926,3]]},"4270":{"position":[[616,3]]}}}],["9.1",{"_index":8076,"t":{"2231":{"position":[[785,4]]}}}],["9.2",{"_index":8077,"t":{"2231":{"position":[[1140,4]]}}}],["9.9.9.9",{"_index":5115,"t":{"1226":{"position":[[5651,7]]},"2048":{"position":[[3414,7]]},"2219":{"position":[[324,10]]}}}],["9.testbed.osism.xyz",{"_index":7925,"t":{"2192":{"position":[[1288,19]]}}}],["9/19",{"_index":5056,"t":{"1222":{"position":[[1085,6]]}}}],["9/20",{"_index":5020,"t":{"1220":{"position":[[502,6]]}}}],["90",{"_index":7014,"t":{"1702":{"position":[[612,2],[637,2]]},"2180":{"position":[[187,2]]},"2184":{"position":[[4144,2]]},"2930":{"position":[[485,2]]},"4707":{"position":[[1121,3]]}}}],["900",{"_index":6822,"t":{"1694":{"position":[[3783,3]]}}}],["9000",{"_index":5301,"t":{"1271":{"position":[[189,4]]},"2869":{"position":[[128,4],[193,4]]}}}],["9001",{"_index":11246,"t":{"4180":{"position":[[72,5]]}}}],["9008d3d7",{"_index":4131,"t":{"991":{"position":[[261,8]]},"1882":{"position":[[261,8]]}}}],["901",{"_index":6817,"t":{"1694":{"position":[[3657,3]]}}}],["902",{"_index":6813,"t":{"1694":{"position":[[3518,3]]}}}],["903",{"_index":6808,"t":{"1694":{"position":[[3382,3]]}}}],["90345eb5",{"_index":7152,"t":{"1713":{"position":[[1042,8],[1335,8]]}}}],["904",{"_index":6805,"t":{"1694":{"position":[[3225,3]]}}}],["905",{"_index":6801,"t":{"1694":{"position":[[3086,3]]}}}],["906",{"_index":6797,"t":{"1694":{"position":[[2945,3]]}}}],["9066",{"_index":11128,"t":{"4026":{"position":[[906,4]]},"4030":{"position":[[853,4]]}}}],["907",{"_index":6794,"t":{"1694":{"position":[[2818,3]]}}}],["908",{"_index":6790,"t":{"1694":{"position":[[2695,3]]}}}],["909",{"_index":6786,"t":{"1694":{"position":[[2559,3]]}}}],["9090:9090",{"_index":9053,"t":{"2756":{"position":[[1932,9]]}}}],["9091:9091",{"_index":9054,"t":{"2756":{"position":[[1993,9]]}}}],["90a5",{"_index":4776,"t":{"1177":{"position":[[4919,4],[5305,4],[5356,4],[5811,4],[5914,4],[6209,4],[6251,4]]}}}],["90e6",{"_index":9108,"t":{"2776":{"position":[[250,4]]}}}],["90n20",{"_index":257,"t":{"28":{"position":[[1389,5]]}}}],["910",{"_index":6782,"t":{"1694":{"position":[[2449,3],[5508,3],[5649,3]]}}}],["9100",{"_index":5306,"t":{"1275":{"position":[[508,4],[532,4]]},"2048":{"position":[[1748,5],[2024,4]]}}}],["91091d4039a6457db27d48d58bb1b4e4",{"_index":237,"t":{"28":{"position":[[901,32]]}}}],["9160",{"_index":4206,"t":{"995":{"position":[[1735,4]]},"1886":{"position":[[1735,4]]}}}],["9166",{"_index":2755,"t":{"557":{"position":[[2104,4]]}}}],["9187",{"_index":2735,"t":{"557":{"position":[[1169,4]]},"2869":{"position":[[100,4]]}}}],["9196",{"_index":8119,"t":{"2240":{"position":[[885,4]]}}}],["91c0",{"_index":7208,"t":{"1732":{"position":[[673,4],[1484,4]]},"1734":{"position":[[674,4],[1678,4]]}}}],["9200",{"_index":5228,"t":{"1261":{"position":[[405,4]]},"1303":{"position":[[3050,4]]}}}],["921",{"_index":9904,"t":{"3264":{"position":[[374,5]]}}}],["9216",{"_index":10673,"t":{"3744":{"position":[[475,4]]}}}],["922b",{"_index":3583,"t":{"894":{"position":[[2141,4]]},"1752":{"position":[[2141,4]]}}}],["925",{"_index":9907,"t":{"3264":{"position":[[676,5]]}}}],["9262",{"_index":6758,"t":{"1686":{"position":[[698,4]]}}}],["926f952f",{"_index":4282,"t":{"1005":{"position":[[2613,8]]},"1896":{"position":[[2613,8]]}}}],["9292030d706c",{"_index":7109,"t":{"1711":{"position":[[1432,12]]}}}],["92a79600",{"_index":11024,"t":{"3988":{"position":[[1117,8]]},"4051":{"position":[[888,8]]}}}],["92c2",{"_index":4285,"t":{"1005":{"position":[[2632,4]]},"1896":{"position":[[2632,4]]}}}],["92cd",{"_index":4164,"t":{"995":{"position":[[979,4]]},"1886":{"position":[[979,4]]}}}],["92e6",{"_index":8246,"t":{"2254":{"position":[[1610,4]]}}}],["9325",{"_index":4196,"t":{"995":{"position":[[1544,4]]},"1886":{"position":[[1544,4]]}}}],["93956190702b4a7d8a8886806d57713f",{"_index":241,"t":{"28":{"position":[[986,32]]}}}],["93e35d0c",{"_index":11140,"t":{"4051":{"position":[[1017,8]]}}}],["941c",{"_index":4134,"t":{"991":{"position":[[280,4]]},"1882":{"position":[[280,4]]}}}],["942b",{"_index":4191,"t":{"995":{"position":[[1448,4]]},"1886":{"position":[[1448,4]]}}}],["94ff",{"_index":4323,"t":{"1005":{"position":[[4196,4],[4434,4],[4534,4],[4649,4],[6115,4]]},"1896":{"position":[[4196,4],[4434,4],[4534,4],[4649,4],[6115,4]]}}}],["952d",{"_index":4308,"t":{"1005":{"position":[[3210,4],[3448,4],[3763,4],[3878,4],[6043,4]]},"1896":{"position":[[3210,4],[3448,4],[3763,4],[3878,4],[6043,4]]}}}],["95a07c43",{"_index":4126,"t":{"991":{"position":[[112,8],[208,8]]},"1882":{"position":[[112,8],[208,8]]}}}],["95a9a2e0",{"_index":7995,"t":{"2207":{"position":[[621,8],[750,8],[801,8]]}}}],["95d4",{"_index":4786,"t":{"1179":{"position":[[197,4],[371,4],[422,4],[725,4],[904,4],[955,4],[1447,4],[1677,4],[1728,4]]}}}],["95dc",{"_index":11065,"t":{"3990":{"position":[[1882,4],[2878,4]]}}}],["960",{"_index":4461,"t":{"1105":{"position":[[564,3]]},"3744":{"position":[[1100,4]]}}}],["961d",{"_index":4170,"t":{"995":{"position":[[1072,4]]},"1886":{"position":[[1072,4]]}}}],["963b8eb67000",{"_index":4197,"t":{"995":{"position":[[1549,12]]},"1886":{"position":[[1549,12]]}}}],["9688192e",{"_index":4295,"t":{"1005":{"position":[[2881,8]]},"1896":{"position":[[2881,8]]},"2252":{"position":[[1908,8]]}}}],["96ae",{"_index":5143,"t":{"1236":{"position":[[596,4],[728,4]]}}}],["96dlg",{"_index":2948,"t":{"590":{"position":[[1179,5]]}}}],["971c",{"_index":4237,"t":{"995":{"position":[[2331,4]]},"1886":{"position":[[2331,4]]}}}],["9728",{"_index":6395,"t":{"1555":{"position":[[576,4]]}}}],["972f",{"_index":8189,"t":{"2252":{"position":[[2061,4]]}}}],["97507e4c",{"_index":11050,"t":{"3990":{"position":[[1701,8]]}}}],["97d372945bb1",{"_index":4171,"t":{"995":{"position":[[1077,12]]},"1886":{"position":[[1077,12]]}}}],["98842b77",{"_index":8183,"t":{"2252":{"position":[[2002,8]]}}}],["989b",{"_index":4228,"t":{"995":{"position":[[2123,4]]},"1886":{"position":[[2123,4]]}}}],["99",{"_index":4935,"t":{"1191":{"position":[[165,2]]},"1252":{"position":[[1932,2]]},"3661":{"position":[[244,4],[469,4]]},"3698":{"position":[[336,4],[574,4]]},"3785":{"position":[[336,4],[574,4]]},"3894":{"position":[[335,4]]},"3984":{"position":[[1287,3]]}}}],["99,9",{"_index":2186,"t":{"368":{"position":[[1586,5]]}}}],["99.x",{"_index":10657,"t":{"3731":{"position":[[2872,4]]}}}],["9917",{"_index":11075,"t":{"3990":{"position":[[2003,4]]}}}],["997bb0c2",{"_index":11029,"t":{"3988":{"position":[[1246,8]]}}}],["99d3267f630a",{"_index":4299,"t":{"1005":{"position":[[2905,12]]},"1896":{"position":[[2905,12]]},"2252":{"position":[[1932,12]]}}}],["99d3267f630a,v4",{"_index":8205,"t":{"2252":{"position":[[2709,15]]}}}],["99d588c4e947",{"_index":8187,"t":{"2252":{"position":[[2026,12]]}}}],["99e14ade3edc\"},{\"displayname\":\"connect",{"_index":9078,"t":{"2764":{"position":[[142,43]]}}}],["9:00",{"_index":1793,"t":{"258":{"position":[[521,4]]}}}],["9\\.]*\\)'.*\\$@\\1",{"_index":3803,"t":{"932":{"position":[[3372,18]]},"1823":{"position":[[3372,18]]},"2956":{"position":[[3372,18]]}}}],["9]*_",{"_index":3902,"t":{"942":{"position":[[1176,5],[1251,5],[1325,5],[1400,5],[1480,5],[1554,5],[1636,5]]},"1833":{"position":[[1176,5],[1251,5],[1325,5],[1400,5],[1480,5],[1554,5],[1636,5]]},"2966":{"position":[[1176,5],[1251,5],[1325,5],[1400,5],[1480,5],[1554,5],[1636,5]]}}}],["9]+(.[0",{"_index":10894,"t":{"3874":{"position":[[181,7]]}}}],["9]+(\\\\.[0",{"_index":10899,"t":{"3876":{"position":[[220,9]]}}}],["9].[0",{"_index":10893,"t":{"3874":{"position":[[175,5]]}}}],["9]\\\\.[0",{"_index":10898,"t":{"3876":{"position":[[212,7]]}}}],["9a",{"_index":6984,"t":{"1700":{"position":[[594,2]]}}}],["9a1576af59644a2dbbace773ad17158d",{"_index":194,"t":{"26":{"position":[[235,32]]}}}],["9a76",{"_index":8157,"t":{"2250":{"position":[[1003,4]]},"2252":{"position":[[2574,4]]}}}],["9b18",{"_index":4217,"t":{"995":{"position":[[1925,4]]},"1886":{"position":[[1925,4]]}}}],["9b1f6342dc60",{"_index":7144,"t":{"1711":{"position":[[2766,12]]}}}],["9b39",{"_index":11015,"t":{"3988":{"position":[[874,4]]},"4051":{"position":[[773,4]]}}}],["9b5f7f8ed70d410c81e3f45bf4e36498",{"_index":4255,"t":{"995":{"position":[[3036,32]]},"1886":{"position":[[3036,32]]}}}],["9b7140bfe628468ab9b86b365f9ac4c2",{"_index":5800,"t":{"1324":{"position":[[12946,32]]}}}],["9b7a73e516be4cd1acbd63d543985c52",{"_index":223,"t":{"28":{"position":[[257,32]]}}}],["9ba0",{"_index":8226,"t":{"2254":{"position":[[1387,4]]}}}],["9ba9",{"_index":11022,"t":{"3988":{"position":[[1077,4]]}}}],["9bfa",{"_index":4173,"t":{"995":{"position":[[1155,4]]},"1886":{"position":[[1155,4]]}}}],["9c08",{"_index":2729,"t":{"557":{"position":[[1037,4]]}}}],["9c31",{"_index":4201,"t":{"995":{"position":[[1640,4]]},"1886":{"position":[[1640,4]]}}}],["9cb2",{"_index":4676,"t":{"1175":{"position":[[4009,4],[4183,4],[4234,4],[4808,4],[4977,4],[5233,4],[5275,4]]}}}],["9de7d8dc2d674e52be44904d6b338b0b",{"_index":230,"t":{"28":{"position":[[492,32]]}}}],["9deeb06b",{"_index":8238,"t":{"2254":{"position":[[1552,8]]}}}],["9e24",{"_index":9080,"t":{"2764":{"position":[[211,4]]}}}],["9e4b",{"_index":2733,"t":{"557":{"position":[[1159,4]]}}}],["9e80",{"_index":4341,"t":{"1005":{"position":[[5202,4],[5440,4],[5640,4],[5870,4],[6371,4]]},"1896":{"position":[[5202,4],[5440,4],[5640,4],[5870,4],[6371,4]]}}}],["9e8799a",{"_index":4758,"t":{"1177":{"position":[[4729,8],[4968,8],[5019,8],[5582,8],[6023,8],[6404,8],[6446,8]]}}}],["9ed4",{"_index":4735,"t":{"1177":{"position":[[3642,4]]}}}],["9ed6",{"_index":11045,"t":{"3990":{"position":[[674,4]]}}}],["9eea",{"_index":6859,"t":{"1694":{"position":[[5683,4]]}}}],["9f93",{"_index":2564,"t":{"518":{"position":[[477,4]]}}}],["9f95",{"_index":4222,"t":{"995":{"position":[[2024,4]]},"1886":{"position":[[2024,4]]}}}],["9fbd",{"_index":11143,"t":{"4051":{"position":[[1036,4]]}}}],["9fc7",{"_index":11057,"t":{"3990":{"position":[[1764,4]]}}}],["9wvgt",{"_index":11558,"t":{"4485":{"position":[[2661,5]]}}}],["_",{"_index":2473,"t":{"481":{"position":[[372,2]]},"2052":{"position":[[989,3]]},"3722":{"position":[[274,1]]},"3815":{"position":[[138,1]]},"4660":{"position":[[849,1],[1107,1],[1260,1],[1435,1]]}}}],["_('openstack",{"_index":5642,"t":{"1314":{"position":[[384,12],[531,12],[781,12],[928,12]]}}}],["_/g",{"_index":10638,"t":{"3722":{"position":[[621,5]]},"3815":{"position":[[485,5]]}}}],["_[g/g]x[n",{"_index":10597,"t":{"3714":{"position":[[8,10]]}}}],["__default",{"_index":7186,"t":{"1720":{"position":[[1254,9]]}}}],["__default__",{"_index":7187,"t":{"1720":{"position":[[1335,11],[1749,11],[2563,11]]},"2219":{"position":[[821,11]]},"4017":{"position":[[196,12],[467,12]]}}}],["__eof__",{"_index":11931,"t":{"4845":{"position":[[353,9],[440,7]]},"4861":{"position":[[676,9],[763,7]]}}}],["__main__",{"_index":2006,"t":{"305":{"position":[[1191,11]]}}}],["__name__",{"_index":2005,"t":{"305":{"position":[[1179,8]]}}}],["_api",{"_index":11775,"t":{"4660":{"position":[[1082,4]]}}}],["_arch[n][h",{"_index":10569,"t":{"3712":{"position":[[8,11]]}}}],["_bms_z3",{"_index":10540,"t":{"3702":{"position":[[1912,7]]},"3789":{"position":[[1771,7]]}}}],["_bms_z3h_gna",{"_index":10541,"t":{"3702":{"position":[[1929,12]]},"3789":{"position":[[1788,12]]}}}],["_dev_mod",{"_index":8013,"t":{"2211":{"position":[[641,10]]}}}],["_ext",{"_index":10520,"t":{"3695":{"position":[[114,6]]},"3782":{"position":[[114,6]]}}}],["_g",{"_index":10559,"t":{"3706":{"position":[[1999,2],[2039,2]]}}}],["_git_repositori",{"_index":8019,"t":{"2211":{"position":[[1177,16]]}}}],["_gx[n",{"_index":10817,"t":{"3807":{"position":[[0,7],[108,7]]}}}],["_helper.yaml",{"_index":11857,"t":{"4833":{"position":[[299,12]]}}}],["_hwv",{"_index":10563,"t":{"3710":{"position":[[8,4],[140,4],[465,4]]},"3803":{"position":[[127,4],[452,4]]}}}],["_hyp",{"_index":10560,"t":{"3708":{"position":[[8,4]]}}}],["_hyp][_hwv][_[arch[n][h][_[g/g]x[n",{"_index":10815,"t":{"3799":{"position":[[1676,37]]}}}],["_hyp][_hwv][_arch[n][h]][_[g/g]x[n",{"_index":10557,"t":{"3706":{"position":[[1679,37]]}}}],["_ib",{"_index":10543,"t":{"3702":{"position":[[1957,3]]},"3716":{"position":[[8,3]]},"3789":{"position":[[1816,3]]},"3809":{"position":[[0,3]]}}}],["_set_new_cache_s",{"_index":6938,"t":{"1698":{"position":[[1121,20]]}}}],["_source_vers",{"_index":8024,"t":{"2211":{"position":[[1458,16]]}}}],["_test",{"_index":1967,"t":{"303":{"position":[[24,5],[446,5]]}}}],["_thi",{"_index":11776,"t":{"4660":{"position":[[1202,5]]}}}],["_to",{"_index":11771,"t":{"4660":{"position":[[691,3]]}}}],["_web",{"_index":11778,"t":{"4660":{"position":[[1392,4]]}}}],["_without",{"_index":10487,"t":{"3677":{"position":[[1278,8]]}}}],["a)gplv3",{"_index":1245,"t":{"179":{"position":[[1149,8]]}}}],["a.k.a",{"_index":8797,"t":{"2649":{"position":[[448,6]]}}}],["a001",{"_index":8162,"t":{"2250":{"position":[[1074,4]]},"2252":{"position":[[2788,4]]}}}],["a021",{"_index":9120,"t":{"2780":{"position":[[162,4]]},"2782":{"position":[[377,4]]},"2784":{"position":[[424,4]]},"2786":{"position":[[79,4],[358,4]]},"2788":{"position":[[79,4]]},"2790":{"position":[[300,4]]},"2792":{"position":[[79,4]]}}}],["a04f",{"_index":7998,"t":{"2207":{"position":[[640,4],[769,4],[820,4]]}}}],["a06e7496fec3",{"_index":8176,"t":{"2252":{"position":[[1177,12],[2657,12]]}}}],["a07c811315ad40f585945b2939ef12dd",{"_index":274,"t":{"28":{"position":[[1717,32]]}}}],["a098cc12",{"_index":4322,"t":{"1005":{"position":[[4187,8],[4425,8],[4525,8],[4640,8],[6106,8]]},"1896":{"position":[[4187,8],[4425,8],[4525,8],[4640,8],[6106,8]]}}}],["a0da232a",{"_index":4768,"t":{"1177":{"position":[[4843,8],[5180,8],[5231,8],[5722,8],[6087,8],[6511,8],[6553,8]]}}}],["a1",{"_index":10435,"t":{"3675":{"position":[[401,2]]}}}],["a10",{"_index":10667,"t":{"3744":{"position":[[335,5],[467,3]]}}}],["a100",{"_index":10665,"t":{"3744":{"position":[[311,5],[956,4],[1001,4],[1044,4],[1087,4]]}}}],["a100x",{"_index":10705,"t":{"3744":{"position":[[1132,5]]}}}],["a147",{"_index":4175,"t":{"995":{"position":[[1165,4]]},"1886":{"position":[[1165,4]]}}}],["a18c",{"_index":4298,"t":{"1005":{"position":[[2900,4]]},"1896":{"position":[[2900,4]]},"2252":{"position":[[1927,4],[2704,4]]}}}],["a2",{"_index":10504,"t":{"3681":{"position":[[670,2]]}}}],["a2a9",{"_index":8186,"t":{"2252":{"position":[[2021,4]]}}}],["a30",{"_index":10622,"t":{"3714":{"position":[[2207,4]]},"3744":{"position":[[305,5],[800,3],[839,3],[878,3]]}}}],["a30x",{"_index":10685,"t":{"3744":{"position":[[913,4]]}}}],["a32c",{"_index":4567,"t":{"1163":{"position":[[258,4]]}}}],["a390",{"_index":11027,"t":{"3988":{"position":[[1206,4]]},"4051":{"position":[[907,4]]}}}],["a40",{"_index":10668,"t":{"3744":{"position":[[341,5],[503,3]]}}}],["a5558f7338f94adea5f41858636256b5",{"_index":3675,"t":{"912":{"position":[[8442,32]]},"914":{"position":[[3525,32],[3626,33]]},"1796":{"position":[[8442,32]]},"1798":{"position":[[3525,32],[3626,33]]}}}],["a5a0adfc24e5",{"_index":8252,"t":{"2256":{"position":[[455,12]]}}}],["a5d4",{"_index":6749,"t":{"1686":{"position":[[524,4]]}}}],["a5db",{"_index":6973,"t":{"1700":{"position":[[206,4]]}}}],["a6a3",{"_index":8221,"t":{"2254":{"position":[[1333,4]]}}}],["a6ad",{"_index":7955,"t":{"2196":{"position":[[2270,4],[3075,4]]}}}],["a71x/neon2",{"_index":10387,"t":{"3671":{"position":[[454,10]]},"3805":{"position":[[545,10]]}}}],["a71x/neon2/v2(armv9",{"_index":10572,"t":{"3712":{"position":[[766,20]]}}}],["a72f",{"_index":11039,"t":{"3990":{"position":[[621,4]]}}}],["a72x/neon3/v3(av9.2",{"_index":10579,"t":{"3712":{"position":[[880,20]]}}}],["a740c178148d",{"_index":4135,"t":{"991":{"position":[[285,12]]},"1882":{"position":[[285,12]]}}}],["a76",{"_index":10380,"t":{"3671":{"position":[[325,3]]},"3712":{"position":[[637,3]]},"3720":{"position":[[431,4]]},"3805":{"position":[[416,3]]},"3813":{"position":[[428,4]]}}}],["a76/neon1",{"_index":10382,"t":{"3671":{"position":[[358,9]]},"3712":{"position":[[670,9]]},"3805":{"position":[[449,9]]}}}],["a78",{"_index":10437,"t":{"3675":{"position":[[428,4]]}}}],["a78/x1/neov1",{"_index":10384,"t":{"3671":{"position":[[406,12]]},"3712":{"position":[[718,12]]},"3805":{"position":[[497,12]]}}}],["a80c",{"_index":9112,"t":{"2778":{"position":[[207,4]]},"2780":{"position":[[70,4],[289,4]]},"2782":{"position":[[159,4]]},"2784":{"position":[[145,4]]},"2786":{"position":[[140,4]]}}}],["a81ef8097c35",{"_index":8237,"t":{"2254":{"position":[[1522,12]]}}}],["a8549ef5d3d14f938b127a1cdefe3788",{"_index":3647,"t":{"912":{"position":[[4298,32],[4886,32],[5484,32],[7321,32],[8373,32]]},"914":{"position":[[2120,32],[2366,32],[3672,32],[5013,32]]},"1796":{"position":[[4298,32],[4886,32],[5484,32],[7321,32],[8373,32]]},"1798":{"position":[[2120,32],[2366,32],[3672,32],[5013,32]]}}}],["a873c27ec818",{"_index":4212,"t":{"995":{"position":[[1835,12]]},"1886":{"position":[[1835,12]]}}}],["a911",{"_index":4211,"t":{"995":{"position":[[1830,4]]},"1886":{"position":[[1830,4]]}}}],["a989e52427fa",{"_index":4130,"t":{"991":{"position":[[136,12],[232,12]]},"1882":{"position":[[136,12],[232,12]]}}}],["a='[0",{"_index":6983,"t":{"1700":{"position":[[588,5]]}}}],["a=amper",{"_index":10409,"t":{"3673":{"position":[[791,9]]},"3714":{"position":[[717,9]]},"3807":{"position":[[421,9]]}}}],["aa",{"_index":9365,"t":{"3022":{"position":[[886,3]]}}}],["aaaab",{"_index":5002,"t":{"1205":{"position":[[182,8]]}}}],["aabd",{"_index":4303,"t":{"1005":{"position":[[3107,4],[3329,4],[3548,4],[3663,4],[5961,4]]},"1896":{"position":[[3107,4],[3329,4],[3548,4],[3663,4],[5961,4]]}}}],["aarch64",{"_index":10376,"t":{"3671":{"position":[[271,9]]},"3712":{"position":[[341,7],[583,9]]},"3805":{"position":[[362,9]]}}}],["ab21",{"_index":11053,"t":{"3990":{"position":[[1720,4]]}}}],["ab40",{"_index":4233,"t":{"995":{"position":[[2235,4]]},"1886":{"position":[[2235,4]]}}}],["ab54",{"_index":2696,"t":{"555":{"position":[[444,4]]},"557":{"position":[[89,4]]},"588":{"position":[[387,4]]}}}],["ab678ce7272d",{"_index":7004,"t":{"1702":{"position":[[256,12]]}}}],["abac",{"_index":11588,"t":{"4527":{"position":[[86,4]]},"4539":{"position":[[1109,5],[5212,4],[5250,4],[6220,5]]},"4547":{"position":[[2501,5]]}}}],["abandon",{"_index":10916,"t":{"3894":{"position":[[1342,7]]},"4215":{"position":[[365,11]]},"4230":{"position":[[198,9]]},"4656":{"position":[[960,9]]},"4662":{"position":[[1722,9]]}}}],["abbe6561cf6248b6af395334aa09af85",{"_index":247,"t":{"28":{"position":[[1081,32]]}}}],["abbr",{"_index":11007,"t":{"3980":{"position":[[128,6]]},"4039":{"position":[[15,6],[103,6],[191,6]]},"4412":{"position":[[23,6],[103,6]]},"4556":{"position":[[23,6],[119,6]]},"4780":{"position":[[8,6]]},"4810":{"position":[[8,6]]}}}],["abbrev",{"_index":5217,"t":{"1259":{"position":[[790,6]]},"1700":{"position":[[577,8],[808,6]]},"1704":{"position":[[564,6],[1065,6],[1560,6],[2236,6]]}}}],["abbrevi",{"_index":6989,"t":{"1700":{"position":[[684,10],[725,10]]},"3529":{"position":[[580,14],[1692,14]]},"4118":{"position":[[93,12]]},"4473":{"position":[[77,12]]}}}],["abc5",{"_index":11017,"t":{"3988":{"position":[[949,4]]},"4051":{"position":[[783,4]]}}}],["abid",{"_index":11472,"t":{"4310":{"position":[[1269,5]]},"4420":{"position":[[357,5]]}}}],["abil",{"_index":510,"t":{"70":{"position":[[399,7]]},"173":{"position":[[78,7]]},"197":{"position":[[1444,7]]},"199":{"position":[[799,8]]},"938":{"position":[[2642,7]]},"1061":{"position":[[856,7]]},"1829":{"position":[[2642,7]]},"2287":{"position":[[1082,7]]},"2301":{"position":[[1082,7]]},"2380":{"position":[[724,7]]},"2616":{"position":[[35,7]]},"2626":{"position":[[917,7]]},"2647":{"position":[[2484,7]]},"2659":{"position":[[35,7]]},"2676":{"position":[[35,7]]},"2962":{"position":[[2642,7]]},"3081":{"position":[[126,7]]},"3083":{"position":[[423,7]]},"3266":{"position":[[336,7]]},"3315":{"position":[[101,7]]},"3656":{"position":[[258,7]]},"3693":{"position":[[317,7]]},"3706":{"position":[[877,7]]},"3780":{"position":[[317,7]]},"3799":{"position":[[877,7]]},"3932":{"position":[[505,7]]},"3968":{"position":[[1223,7]]},"4116":{"position":[[368,7]]},"4228":{"position":[[1329,7]]},"4308":{"position":[[466,7]]},"4420":{"position":[[419,7],[1932,7],[2463,7],[2820,7]]},"4459":{"position":[[823,7]]},"4504":{"position":[[537,7]]},"4506":{"position":[[1651,7],[1732,7]]},"4514":{"position":[[46,7]]},"4516":{"position":[[487,7]]},"4539":{"position":[[5649,7]]},"4660":{"position":[[1773,7]]}}}],["abnorm",{"_index":10784,"t":{"3759":{"position":[[217,10]]},"4722":{"position":[[930,11]]}}}],["abort",{"_index":3923,"t":{"942":{"position":[[3235,5]]},"944":{"position":[[891,5]]},"1655":{"position":[[214,8]]},"1659":{"position":[[719,5]]},"1833":{"position":[[3235,5]]},"1835":{"position":[[891,5]]},"2966":{"position":[[3235,5]]},"2968":{"position":[[891,5]]}}}],["abouttext",{"_index":9314,"t":{"2930":{"position":[[808,9]]}}}],["abov",{"_index":493,"t":{"66":{"position":[[148,5]]},"68":{"position":[[235,5]]},"194":{"position":[[434,5]]},"199":{"position":[[1967,5]]},"201":{"position":[[509,5],[696,5],[824,5]]},"423":{"position":[[907,5]]},"434":{"position":[[1280,5]]},"479":{"position":[[212,5]]},"526":{"position":[[93,5]]},"653":{"position":[[676,5]]},"671":{"position":[[967,6]]},"699":{"position":[[607,6]]},"732":{"position":[[1594,5]]},"938":{"position":[[1746,6],[2454,5]]},"959":{"position":[[180,6]]},"965":{"position":[[84,5]]},"971":{"position":[[232,5]]},"976":{"position":[[123,6]]},"978":{"position":[[1658,5]]},"1248":{"position":[[496,6],[1611,5]]},"1297":{"position":[[320,7]]},"1405":{"position":[[1212,5]]},"1421":{"position":[[1171,5]]},"1580":{"position":[[269,5]]},"1648":{"position":[[252,6]]},"1652":{"position":[[267,5]]},"1700":{"position":[[740,5]]},"1829":{"position":[[1746,6],[2454,5]]},"1850":{"position":[[180,6]]},"1856":{"position":[[84,5]]},"1862":{"position":[[232,5]]},"1867":{"position":[[123,6]]},"1869":{"position":[[1658,5]]},"1923":{"position":[[269,5]]},"1977":{"position":[[267,5]]},"2184":{"position":[[1635,6]]},"2211":{"position":[[2084,5]]},"2343":{"position":[[951,6]]},"2345":{"position":[[112,6]]},"2347":{"position":[[675,6]]},"2351":{"position":[[191,6]]},"2410":{"position":[[951,6]]},"2412":{"position":[[112,6]]},"2414":{"position":[[675,6]]},"2418":{"position":[[191,6]]},"2584":{"position":[[574,6]]},"2586":{"position":[[184,6]]},"2592":{"position":[[23,5]]},"2618":{"position":[[1445,5]]},"2636":{"position":[[898,5]]},"2644":{"position":[[698,5]]},"2672":{"position":[[698,5]]},"2678":{"position":[[733,5]]},"2749":{"position":[[116,5]]},"2843":{"position":[[9,6]]},"2962":{"position":[[1746,6],[2454,5]]},"2983":{"position":[[180,6]]},"2989":{"position":[[84,5]]},"2995":{"position":[[232,5]]},"3000":{"position":[[123,6]]},"3002":{"position":[[1658,5]]},"3352":{"position":[[211,5]]},"3361":{"position":[[680,6]]},"3592":{"position":[[2373,6]]},"3596":{"position":[[37,6]]},"3598":{"position":[[2065,6]]},"3600":{"position":[[801,6]]},"3661":{"position":[[729,5]]},"3673":{"position":[[1257,5]]},"3679":{"position":[[1365,5]]},"3681":{"position":[[114,5]]},"3698":{"position":[[839,5],[1396,6]]},"3704":{"position":[[138,6],[278,5]]},"3706":{"position":[[1832,5]]},"3714":{"position":[[1998,5]]},"3716":{"position":[[181,5]]},"3718":{"position":[[114,5]]},"3763":{"position":[[95,6],[145,5]]},"3765":{"position":[[10,6]]},"3785":{"position":[[824,5]]},"3793":{"position":[[1601,5]]},"3795":{"position":[[655,5]]},"3809":{"position":[[158,5]]},"3811":{"position":[[114,5]]},"3881":{"position":[[569,6]]},"3928":{"position":[[2292,5]]},"3934":{"position":[[326,5]]},"3947":{"position":[[4366,5]]},"4124":{"position":[[2430,6]]},"4137":{"position":[[84,5]]},"4163":{"position":[[1777,5],[3502,5]]},"4291":{"position":[[1353,6],[1662,5]]},"4298":{"position":[[13,6]]},"4422":{"position":[[383,5]]},"4562":{"position":[[794,5]]},"4667":{"position":[[13291,5]]},"4669":{"position":[[1046,7]]},"4695":{"position":[[735,6]]},"4855":{"position":[[241,5]]}}}],["absenc",{"_index":8579,"t":{"2522":{"position":[[148,8]]},"3918":{"position":[[638,7],[749,7]]},"4005":{"position":[[316,7]]},"4055":{"position":[[43,7]]}}}],["absolut",{"_index":4060,"t":{"963":{"position":[[3555,8],[3710,8]]},"1854":{"position":[[3555,8],[3710,8]]},"2576":{"position":[[440,10]]},"2987":{"position":[[3555,8],[3710,8]]}}}],["abstract",{"_index":588,"t":{"78":{"position":[[639,8]]},"305":{"position":[[660,8]]},"370":{"position":[[746,11]]},"1056":{"position":[[138,11],[840,12],[865,9],[1088,11]]},"1064":{"position":[[108,11]]},"1399":{"position":[[189,9]]},"1413":{"position":[[353,9]]},"2576":{"position":[[423,12]]},"2584":{"position":[[35,13],[533,9]]},"2586":{"position":[[143,9]]},"3355":{"position":[[406,12]]},"3529":{"position":[[1280,8]]},"3690":{"position":[[1513,11]]},"3777":{"position":[[1614,11]]},"3941":{"position":[[95,9]]},"4077":{"position":[[1015,9]]},"4081":{"position":[[276,10]]},"4100":{"position":[[385,8]]},"4146":{"position":[[2207,10]]},"4157":{"position":[[203,11]]},"4226":{"position":[[1222,11]]},"4279":{"position":[[298,8]]},"4591":{"position":[[411,11]]},"4606":{"position":[[411,8]]}}}],["abus",{"_index":1300,"t":{"181":{"position":[[2400,6]]},"4304":{"position":[[691,7]]},"4612":{"position":[[520,5]]}}}],["ac",{"_index":6207,"t":{"1455":{"position":[[984,2]]}}}],["ac12",{"_index":4209,"t":{"995":{"position":[[1820,4]]},"1886":{"position":[[1820,4]]}}}],["acb56e1f",{"_index":4783,"t":{"1179":{"position":[[178,8],[352,8],[403,8],[706,8],[885,8],[936,8],[1428,8],[1658,8],[1709,8]]}}}],["acc",{"_index":2793,"t":{"557":{"position":[[5139,3]]}}}],["acceler",{"_index":553,"t":{"74":{"position":[[271,11]]},"1455":{"position":[[299,11]]},"3246":{"position":[[279,12]]},"3669":{"position":[[68,11]]},"3710":{"position":[[81,11]]},"3803":{"position":[[68,11]]},"3941":{"position":[[1225,12]]}}}],["accept",{"_index":1304,"t":{"181":{"position":[[2507,10],[2585,6]]},"199":{"position":[[1298,11],[1998,6]]},"830":{"position":[[92,7]]},"932":{"position":[[3844,6]]},"1169":{"position":[[286,8],[333,8]]},"1248":{"position":[[1524,8]]},"1648":{"position":[[1276,6]]},"1698":{"position":[[1978,8]]},"1823":{"position":[[3844,6]]},"2626":{"position":[[1921,8],[2158,8]]},"2956":{"position":[[3844,6]]},"3381":{"position":[[1163,8]]},"3527":{"position":[[609,10]]},"3533":{"position":[[1458,10],[1745,8]]},"3535":{"position":[[173,10]]},"3549":{"position":[[1299,10]]},"3698":{"position":[[1659,8]]},"3722":{"position":[[818,6]]},"3815":{"position":[[816,6]]},"4096":{"position":[[708,10]]},"4189":{"position":[[729,10]]},"4191":{"position":[[54,10]]},"4222":{"position":[[3692,9]]},"4257":{"position":[[4155,11]]},"4302":{"position":[[2491,8]]},"4306":{"position":[[360,8]]},"4325":{"position":[[251,6]]},"4420":{"position":[[228,10]]},"4479":{"position":[[587,8]]},"4656":{"position":[[708,6]]}}}],["acceptedrol",{"_index":6048,"t":{"1407":{"position":[[2774,14]]}}}],["access",{"_index":128,"t":{"19":{"position":[[11,6]]},"24":{"position":[[550,6]]},"26":{"position":[[104,6],[182,6]]},"31":{"position":[[41,6]]},"39":{"position":[[95,6],[286,6]]},"70":{"position":[[163,6]]},"84":{"position":[[51,6],[81,6],[190,6]]},"130":{"position":[[190,6]]},"179":{"position":[[197,8]]},"212":{"position":[[167,14]]},"323":{"position":[[599,6],[627,6],[1027,6]]},"327":{"position":[[33,7]]},"358":{"position":[[212,6]]},"413":{"position":[[77,10]]},"434":{"position":[[298,6]]},"471":{"position":[[75,6]]},"473":{"position":[[222,6],[426,6],[971,6]]},"508":{"position":[[298,6]]},"518":{"position":[[702,6]]},"526":{"position":[[272,6],[414,7],[469,6],[1021,6],[1163,7],[1218,6]]},"528":{"position":[[25,6],[265,6]]},"530":{"position":[[1882,6],[2025,6],[2187,6]]},"543":{"position":[[1898,10]]},"557":{"position":[[4153,6]]},"578":{"position":[[386,6],[800,6]]},"618":{"position":[[193,8]]},"701":{"position":[[324,6],[398,6],[591,6],[860,6],[903,6],[1500,6],[2246,6]]},"753":{"position":[[171,6]]},"818":{"position":[[364,6],[724,6],[778,6]]},"836":{"position":[[146,6]]},"838":{"position":[[422,6]]},"850":{"position":[[345,8]]},"887":{"position":[[298,6],[320,6]]},"912":{"position":[[6822,6],[6982,6],[7034,6],[8104,6]]},"924":{"position":[[1463,6],[1640,6]]},"928":{"position":[[363,6]]},"930":{"position":[[387,6]]},"932":{"position":[[922,6]]},"934":{"position":[[245,6]]},"951":{"position":[[472,8]]},"961":{"position":[[1747,6],[2060,8]]},"963":{"position":[[1769,6],[4404,6]]},"973":{"position":[[600,6]]},"978":{"position":[[318,8],[753,10]]},"1013":{"position":[[316,6],[359,6]]},"1054":{"position":[[316,6],[359,6]]},"1224":{"position":[[829,6]]},"1250":{"position":[[286,10]]},"1342":{"position":[[133,10]]},"1346":{"position":[[50,10],[232,6],[928,8]]},"1352":{"position":[[64,7]]},"1383":{"position":[[189,6]]},"1385":{"position":[[98,8]]},"1457":{"position":[[2658,6],[2807,6],[3224,12],[3299,10],[3474,10],[4041,12]]},"1468":{"position":[[824,10],[930,6],[1332,10]]},"1472":{"position":[[152,6]]},"1486":{"position":[[63,6],[358,6]]},"1501":{"position":[[845,8],[1019,8],[1205,8]]},"1523":{"position":[[182,6]]},"1544":{"position":[[269,10]]},"1555":{"position":[[303,9]]},"1745":{"position":[[68,6],[250,6],[322,6]]},"1796":{"position":[[6822,6],[6982,6],[7034,6],[8104,6]]},"1811":{"position":[[298,6],[320,6]]},"1815":{"position":[[1463,6],[1640,6]]},"1819":{"position":[[363,6]]},"1821":{"position":[[387,6]]},"1823":{"position":[[922,6]]},"1825":{"position":[[245,6]]},"1842":{"position":[[472,8]]},"1852":{"position":[[1747,6],[2060,8]]},"1854":{"position":[[1769,6],[4404,6]]},"1864":{"position":[[600,6]]},"1869":{"position":[[318,8],[753,10]]},"1998":{"position":[[41,6]]},"2025":{"position":[[651,10]]},"2027":{"position":[[717,7]]},"2032":{"position":[[1145,6]]},"2037":{"position":[[855,6]]},"2039":{"position":[[15,6]]},"2048":{"position":[[600,10]]},"2117":{"position":[[294,10]]},"2119":{"position":[[1027,6]]},"2182":{"position":[[100,6]]},"2184":{"position":[[77,6],[138,6],[422,6],[441,6]]},"2188":{"position":[[271,6]]},"2192":{"position":[[21,6]]},"2194":{"position":[[206,6]]},"2196":{"position":[[1335,6]]},"2236":{"position":[[177,6],[462,6]]},"2238":{"position":[[44,6],[309,6]]},"2248":{"position":[[561,6]]},"2256":{"position":[[757,11]]},"2261":{"position":[[362,6]]},"2276":{"position":[[333,6]]},"2329":{"position":[[809,10]]},"2360":{"position":[[1569,10]]},"2382":{"position":[[275,6],[380,6]]},"2396":{"position":[[809,10]]},"2427":{"position":[[1569,10]]},"2431":{"position":[[65,6],[4423,6]]},"2441":{"position":[[341,6]]},"2478":{"position":[[2134,6],[2548,6],[2660,6]]},"2487":{"position":[[101,6],[171,6]]},"2499":{"position":[[464,6]]},"2508":{"position":[[352,6]]},"2512":{"position":[[350,7],[605,6]]},"2527":{"position":[[101,6]]},"2529":{"position":[[207,7],[631,6],[1048,6],[1221,6]]},"2531":{"position":[[707,7]]},"2537":{"position":[[353,6]]},"2563":{"position":[[160,6]]},"2574":{"position":[[494,6],[717,6]]},"2584":{"position":[[321,6]]},"2616":{"position":[[46,6]]},"2626":{"position":[[928,6]]},"2636":{"position":[[672,6]]},"2647":{"position":[[2417,6],[2495,6],[2655,6]]},"2659":{"position":[[46,6]]},"2676":{"position":[[46,6]]},"2692":{"position":[[1541,6]]},"2714":{"position":[[264,10],[411,6]]},"2756":{"position":[[1665,6],[2450,10]]},"2839":{"position":[[77,6],[231,6]]},"2857":{"position":[[82,6]]},"2859":{"position":[[123,6]]},"2873":{"position":[[184,8],[378,8]]},"2887":{"position":[[286,7]]},"2908":{"position":[[391,6]]},"2910":{"position":[[346,6]]},"2918":{"position":[[837,6],[869,6]]},"2948":{"position":[[1463,6],[1640,6]]},"2952":{"position":[[363,6]]},"2954":{"position":[[387,6]]},"2956":{"position":[[922,6]]},"2958":{"position":[[245,6]]},"2975":{"position":[[472,8]]},"2985":{"position":[[1747,6],[2060,8]]},"2987":{"position":[[1769,6],[4404,6]]},"2997":{"position":[[600,6]]},"3002":{"position":[[318,8],[753,10]]},"3083":{"position":[[703,6]]},"3121":{"position":[[976,6]]},"3153":{"position":[[1494,6],[1693,6]]},"3168":{"position":[[496,6]]},"3238":{"position":[[861,6]]},"3253":{"position":[[146,10]]},"3255":{"position":[[32,6]]},"3306":{"position":[[288,6]]},"3313":{"position":[[105,6],[231,6]]},"3344":{"position":[[396,10]]},"3352":{"position":[[14,6],[714,6],[772,6],[2250,7],[2368,8]]},"3381":{"position":[[291,6],[1454,6]]},"3390":{"position":[[334,10]]},"3406":{"position":[[332,9]]},"3410":{"position":[[364,7]]},"3460":{"position":[[168,6]]},"3470":{"position":[[40,6],[301,6]]},"3474":{"position":[[274,6]]},"3531":{"position":[[454,6]]},"3561":{"position":[[441,6]]},"3569":{"position":[[1262,6]]},"3575":{"position":[[187,10]]},"3627":{"position":[[254,6]]},"3731":{"position":[[615,6],[1015,7]]},"3763":{"position":[[1061,6]]},"3772":{"position":[[56,9]]},"3829":{"position":[[478,10],[3738,10],[4998,10]]},"3835":{"position":[[1188,6]]},"3855":{"position":[[497,9]]},"3923":{"position":[[531,6]]},"3925":{"position":[[401,6]]},"3930":{"position":[[1024,10]]},"3947":{"position":[[2343,10]]},"3978":{"position":[[221,11]]},"3980":{"position":[[212,6],[290,6]]},"3990":{"position":[[64,6],[901,6]]},"4060":{"position":[[898,6]]},"4075":{"position":[[367,6]]},"4096":{"position":[[1024,7]]},"4113":{"position":[[1342,10],[2235,10],[2312,11]]},"4182":{"position":[[238,6]]},"4220":{"position":[[1987,6],[2094,6]]},"4222":{"position":[[389,6],[420,6],[1194,6],[2126,10],[2422,7],[2435,6],[2834,6]]},"4226":{"position":[[640,10],[1548,6],[3790,6]]},"4289":{"position":[[433,6]]},"4302":{"position":[[2930,6]]},"4304":{"position":[[599,6],[1717,7],[1848,6],[1926,6],[2392,6],[2453,6],[2640,10]]},"4315":{"position":[[264,6]]},"4337":{"position":[[260,6]]},"4376":{"position":[[568,6]]},"4401":{"position":[[34,6]]},"4410":{"position":[[72,9],[305,10],[417,6],[455,7]]},"4420":{"position":[[816,6],[848,6]]},"4464":{"position":[[334,6]]},"4466":{"position":[[71,6]]},"4481":{"position":[[119,8]]},"4506":{"position":[[859,7],[1551,6]]},"4508":{"position":[[1028,13]]},"4527":{"position":[[107,6],[138,6]]},"4535":{"position":[[125,6],[240,6],[285,6],[734,6],[1403,10],[2045,6],[2273,7],[2381,6],[2590,6],[2639,6],[2732,6],[2801,6],[3079,6],[3571,6],[4282,6]]},"4537":{"position":[[153,7],[403,10],[519,6],[868,9],[955,6],[1339,6],[1418,6]]},"4539":{"position":[[72,6],[186,6],[1308,9],[2702,7],[2774,9],[4279,6],[4325,6],[5234,6],[5262,6],[5449,6],[5507,6],[5554,6]]},"4541":{"position":[[257,6],[904,13],[959,10],[1993,6],[2064,6],[2083,6]]},"4543":{"position":[[115,6]]},"4547":{"position":[[517,6],[634,6],[645,6],[915,6],[993,6],[1344,6],[2730,6],[2771,10]]},"4551":{"position":[[92,6]]},"4554":{"position":[[72,9]]},"4562":{"position":[[3343,6]]},"4580":{"position":[[1287,6]]},"4587":{"position":[[94,6],[1055,6],[1331,6]]},"4591":{"position":[[120,6]]},"4593":{"position":[[4722,6]]},"4606":{"position":[[101,6],[385,6]]},"4612":{"position":[[182,6]]},"4632":{"position":[[2912,6]]},"4634":{"position":[[36,6]]},"4643":{"position":[[889,6],[1030,6],[1967,6]]},"4660":{"position":[[172,6],[218,6]]},"4722":{"position":[[155,6]]},"4839":{"position":[[394,6],[1698,10]]},"4870":{"position":[[18,6],[86,6]]},"4872":{"position":[[616,7],[934,7],[1053,6]]},"4877":{"position":[[476,6],[501,6],[863,6],[1250,6]]}}}],["access:is_publ",{"_index":3585,"t":{"894":{"position":[[2197,16]]},"1752":{"position":[[2197,16]]}}}],["access_as_extern",{"_index":11088,"t":{"3990":{"position":[[2142,18]]}}}],["access_as_shar",{"_index":11035,"t":{"3990":{"position":[[367,16],[576,16],[1772,16],[1900,16],[2021,16],[2268,16],[2392,16],[2790,16]]}}}],["access_floatingip",{"_index":8064,"t":{"2219":{"position":[[1122,17]]}}}],["access_ipv4",{"_index":8065,"t":{"2219":{"position":[[1140,11]]}}}],["access_ipv6",{"_index":8066,"t":{"2219":{"position":[[1152,11]]}}}],["access_project_id",{"_index":3579,"t":{"894":{"position":[[2050,18]]},"1752":{"position":[[2050,18]]},"4026":{"position":[[785,18]]},"4030":{"position":[[635,18]]}}}],["access_token",{"_index":9270,"t":{"2908":{"position":[[368,15]]}}}],["accesskey",{"_index":3245,"t":{"747":{"position":[[482,11]]}}}],["accesskeyid",{"_index":11997,"t":{"4877":{"position":[[780,12],[1167,12]]}}}],["accessmod",{"_index":3221,"t":{"738":{"position":[[1244,12],[1281,11]]}}}],["accident",{"_index":2838,"t":{"566":{"position":[[102,12]]}}}],["accommod",{"_index":2658,"t":{"549":{"position":[[776,11]]},"638":{"position":[[79,12]]},"2608":{"position":[[226,13]]},"2749":{"position":[[247,11]]},"3561":{"position":[[114,11]]}}}],["accompani",{"_index":2304,"t":{"405":{"position":[[30,11]]},"421":{"position":[[121,11]]},"2806":{"position":[[144,11]]},"3606":{"position":[[750,11]]},"3731":{"position":[[2402,11]]},"4660":{"position":[[2456,11]]}}}],["accomplish",{"_index":10233,"t":{"3573":{"position":[[915,12]]},"3761":{"position":[[1267,12]]},"4539":{"position":[[5766,10]]}}}],["accord",{"_index":1391,"t":{"197":{"position":[[444,9]]},"299":{"position":[[131,9]]},"425":{"position":[[137,10]]},"427":{"position":[[468,9]]},"479":{"position":[[772,9]]},"541":{"position":[[1602,9]]},"543":{"position":[[1373,9]]},"649":{"position":[[68,9]]},"681":{"position":[[68,9]]},"898":{"position":[[40,9]]},"1056":{"position":[[1950,9]]},"1301":{"position":[[3045,9]]},"1457":{"position":[[1148,9],[2511,9]]},"1466":{"position":[[1379,9]]},"1472":{"position":[[645,9]]},"1587":{"position":[[185,9]]},"1756":{"position":[[40,9]]},"1930":{"position":[[185,9]]},"2443":{"position":[[660,9]]},"2567":{"position":[[1539,9],[1835,9]]},"2604":{"position":[[454,9]]},"2628":{"position":[[79,9],[232,9]]},"2636":{"position":[[228,9],[365,9],[466,9]]},"2871":{"position":[[354,9]]},"3097":{"position":[[20,9]]},"3130":{"position":[[20,9]]},"3290":{"position":[[833,9]]},"3537":{"position":[[275,9]]},"3575":{"position":[[707,9],[1120,9]]},"3602":{"position":[[989,9]]},"3613":{"position":[[134,10]]},"3646":{"position":[[52,9]]},"3667":{"position":[[139,9]]},"3679":{"position":[[98,9]]},"3708":{"position":[[151,9]]},"3793":{"position":[[98,9]]},"3801":{"position":[[139,9]]},"3829":{"position":[[3089,10],[4191,9]]},"3894":{"position":[[204,9],[1305,9],[1637,9]]},"3906":{"position":[[625,9]]},"3932":{"position":[[1114,9]]},"4041":{"position":[[970,9]]},"4098":{"position":[[279,9]]},"4100":{"position":[[50,9]]},"4206":{"position":[[444,7]]},"4257":{"position":[[970,9]]},"4259":{"position":[[229,9],[423,9]]},"4270":{"position":[[559,9]]},"4281":{"position":[[1138,9]]},"4355":{"position":[[491,9],[1031,9],[1101,9]]},"4359":{"position":[[299,9]]},"4431":{"position":[[550,9],[1079,9],[1502,9]]},"4479":{"position":[[816,9]]},"4485":{"position":[[1503,9]]},"4541":{"position":[[152,9]]},"4558":{"position":[[124,10]]},"4562":{"position":[[1066,9]]},"4667":{"position":[[13329,9]]},"4746":{"position":[[16,9]]},"4883":{"position":[[120,9]]}}}],["accordingli",{"_index":1426,"t":{"199":{"position":[[223,12]]},"530":{"position":[[1183,12]]},"588":{"position":[[176,11],[298,11]]},"647":{"position":[[89,12]]},"651":{"position":[[130,12]]},"679":{"position":[[89,12]]},"683":{"position":[[130,12]]},"861":{"position":[[204,11]]},"963":{"position":[[3803,12]]},"1303":{"position":[[2539,11],[4098,12]]},"1342":{"position":[[271,11]]},"1383":{"position":[[2224,12]]},"1385":{"position":[[964,12]]},"1501":{"position":[[638,12]]},"1523":{"position":[[1464,12]]},"1527":{"position":[[278,11]]},"1762":{"position":[[204,11]]},"1854":{"position":[[3803,12]]},"2048":{"position":[[1707,12]]},"2094":{"position":[[273,11]]},"2163":{"position":[[3301,12]]},"2199":{"position":[[460,12]]},"2343":{"position":[[1197,11]]},"2349":{"position":[[418,12]]},"2353":{"position":[[253,12]]},"2410":{"position":[[1197,11]]},"2416":{"position":[[418,12]]},"2420":{"position":[[253,12]]},"2503":{"position":[[131,12]]},"2626":{"position":[[320,13]]},"2987":{"position":[[3803,12]]},"3093":{"position":[[348,12]]},"3567":{"position":[[80,12]]},"3594":{"position":[[1375,12]]},"4200":{"position":[[642,12]]},"4300":{"position":[[833,12]]},"4667":{"position":[[12836,12],[14885,12]]},"4820":{"position":[[53,12]]}}}],["accordingly[^4",{"_index":11455,"t":{"4304":{"position":[[1798,15]]}}}],["account",{"_index":169,"t":{"24":{"position":[[253,8]]},"260":{"position":[[152,7]]},"264":{"position":[[54,7]]},"323":{"position":[[1164,9]]},"530":{"position":[[2105,8]]},"692":{"position":[[654,8]]},"850":{"position":[[308,9]]},"910":{"position":[[332,8]]},"912":{"position":[[3856,7],[3905,7]]},"963":{"position":[[3745,7]]},"1169":{"position":[[800,7]]},"1205":{"position":[[75,8]]},"1466":{"position":[[1031,8],[1194,7],[1304,8]]},"1472":{"position":[[67,7],[312,7]]},"1637":{"position":[[243,8]]},"1745":{"position":[[394,8]]},"1794":{"position":[[332,8]]},"1796":{"position":[[3856,7],[3905,7]]},"1854":{"position":[[3745,7]]},"1968":{"position":[[316,8]]},"2117":{"position":[[236,7]]},"2178":{"position":[[37,7]]},"2431":{"position":[[163,9],[353,9],[445,9],[534,8],[1378,9],[1423,9],[2442,9],[2634,9],[2666,8],[3522,7],[3724,9],[3898,9],[4394,7]]},"2478":{"position":[[1992,8]]},"2987":{"position":[[3745,7]]},"3460":{"position":[[317,9]]},"4226":{"position":[[1047,10]]},"4310":{"position":[[2398,7]]},"4313":{"position":[[666,8]]},"4323":{"position":[[252,8],[388,8]]},"4420":{"position":[[772,7]]},"4504":{"position":[[235,7],[366,7]]},"4512":{"position":[[163,7],[271,8]]},"4535":{"position":[[1276,8]]},"4539":{"position":[[255,9],[1640,7],[2170,7],[2195,7],[2288,8],[2428,7],[2452,8],[2724,7]]},"4547":{"position":[[2124,7]]},"4562":{"position":[[5824,8],[5841,8]]},"4587":{"position":[[721,7],[826,7],[1221,11],[1266,8]]},"4589":{"position":[[138,8]]},"4593":{"position":[[2842,7]]},"4629":{"position":[[153,9]]},"4643":{"position":[[1903,8],[2124,9]]},"4740":{"position":[[25,11]]},"4849":{"position":[[1008,8]]},"4857":{"position":[[4,9],[34,8]]},"4863":{"position":[[60,8],[144,7]]},"4877":{"position":[[652,7],[1047,7]]}}}],["accountinurl",{"_index":6053,"t":{"1407":{"position":[[3206,13]]}}}],["accounts/people/compani",{"_index":1534,"t":{"207":{"position":[[63,25]]}}}],["accumul",{"_index":7736,"t":{"2146":{"position":[[596,11]]},"2317":{"position":[[90,11]]},"2321":{"position":[[54,11]]},"2384":{"position":[[90,11]]},"2388":{"position":[[54,11]]},"4257":{"position":[[601,10]]}}}],["accur",{"_index":2678,"t":{"551":{"position":[[3523,8]]},"2626":{"position":[[1716,10]]},"4516":{"position":[[1398,8]]},"4518":{"position":[[22,8]]},"4520":{"position":[[406,8]]},"4522":{"position":[[777,11],[1057,8]]}}}],["accuraci",{"_index":8603,"t":{"2551":{"position":[[569,9]]},"2592":{"position":[[612,9]]}}}],["achiev",{"_index":950,"t":{"165":{"position":[[128,7]]},"169":{"position":[[330,7],[731,7]]},"181":{"position":[[2757,7]]},"187":{"position":[[149,9]]},"280":{"position":[[1682,9]]},"297":{"position":[[361,7]]},"309":{"position":[[100,9]]},"311":{"position":[[301,7]]},"368":{"position":[[908,7]]},"498":{"position":[[405,8]]},"514":{"position":[[781,8]]},"530":{"position":[[221,7]]},"814":{"position":[[617,7]]},"963":{"position":[[4494,10],[4597,10],[4647,8]]},"1042":{"position":[[381,10]]},"1056":{"position":[[2143,7]]},"1064":{"position":[[2298,7]]},"1067":{"position":[[2486,10]]},"1105":{"position":[[432,9]]},"1854":{"position":[[4494,10],[4597,10],[4647,8]]},"2366":{"position":[[303,7]]},"2608":{"position":[[371,7]]},"2703":{"position":[[131,7]]},"2987":{"position":[[4494,10],[4597,10],[4647,8]]},"3067":{"position":[[417,7]]},"3103":{"position":[[244,7],[336,8]]},"3136":{"position":[[244,7],[336,8]]},"3276":{"position":[[304,8]]},"3308":{"position":[[615,8]]},"3313":{"position":[[264,8]]},"3357":{"position":[[1977,9]]},"3390":{"position":[[899,9]]},"3661":{"position":[[274,8]]},"3698":{"position":[[366,8]]},"3731":{"position":[[1099,9]]},"3785":{"position":[[366,8]]},"3947":{"position":[[2823,7],[4727,7]]},"4028":{"position":[[180,9]]},"4047":{"position":[[738,7],[769,8]]},"4049":{"position":[[260,8]]},"4060":{"position":[[317,8]]},"4077":{"position":[[608,8]]},"4094":{"position":[[570,8]]},"4102":{"position":[[714,10]]},"4104":{"position":[[291,7]]},"4159":{"position":[[156,8]]},"4163":{"position":[[670,8],[2114,9]]},"4226":{"position":[[3892,8]]},"4230":{"position":[[4976,7]]},"4268":{"position":[[53,7]]},"4342":{"position":[[47,7]]},"4353":{"position":[[375,7],[535,11]]},"4385":{"position":[[682,7]]},"4433":{"position":[[267,7],[545,9]]},"4435":{"position":[[336,8]]},"4481":{"position":[[782,8]]},"4516":{"position":[[1383,7]]},"4522":{"position":[[1838,7]]},"4525":{"position":[[191,7]]},"4591":{"position":[[756,10]]},"4826":{"position":[[1020,9]]}}}],["achiv",{"_index":9368,"t":{"3030":{"position":[[176,7]]}}}],["acid",{"_index":10952,"t":{"3928":{"position":[[3297,4]]}}}],["acknowledg",{"_index":2295,"t":{"401":{"position":[[204,11]]},"423":{"position":[[1063,12]]},"3144":{"position":[[591,11]]},"3176":{"position":[[547,11]]},"3925":{"position":[[506,12]]},"3928":{"position":[[3230,13]]},"4304":{"position":[[707,12]]},"4541":{"position":[[1075,12]]}}}],["acknowledged\":tru",{"_index":6470,"t":{"1566":{"position":[[72,21]]}}}],["acl",{"_index":5446,"t":{"1297":{"position":[[1987,3],[2158,3],[2325,3],[2499,3],[2678,3],[2837,3],[3012,3],[3191,3],[3358,3],[3529,3],[3692,3]]},"4226":{"position":[[3811,5]]},"4535":{"position":[[702,3],[2250,3],[2767,3],[2822,5],[3489,3],[4466,3]]},"4547":{"position":[[928,3]]}}}],["acl_cinder.services.a.regiocloud.tech",{"_index":5470,"t":{"1297":{"position":[[3195,37],[3320,37]]}}}],["acl_console.services.a.regiocloud.tech",{"_index":5464,"t":{"1297":{"position":[[2841,38],[2973,38]]}}}],["acl_designate.services.a.regiocloud.tech",{"_index":5467,"t":{"1297":{"position":[[3016,40],[3150,40]]}}}],["acl_glance.services.a.regiocloud.tech",{"_index":5452,"t":{"1297":{"position":[[2162,37],[2287,37]]}}}],["acl_ironic.services.a.regiocloud.tech",{"_index":5478,"t":{"1297":{"position":[[3696,37],[3821,37]]}}}],["acl_keystone.services.a.regiocloud.tech",{"_index":5447,"t":{"1297":{"position":[[1991,39],[2118,39]]}}}],["acl_neutron.services.a.regiocloud.tech",{"_index":5455,"t":{"1297":{"position":[[2329,38],[2460,38]]}}}],["acl_nova.services.a.regiocloud.tech",{"_index":5461,"t":{"1297":{"position":[[2682,35],[2801,35]]}}}],["acl_octavia.services.a.regiocloud.tech",{"_index":5473,"t":{"1297":{"position":[[3362,38],[3490,38]]}}}],["acl_placement.services.a.regiocloud.tech",{"_index":5458,"t":{"1297":{"position":[[2503,40],[2637,40]]}}}],["acl_swift.services.a.regiocloud.tech",{"_index":5476,"t":{"1297":{"position":[[3533,36],[3655,36]]}}}],["acm",{"_index":11988,"t":{"4877":{"position":[[165,4],[611,5],[1006,5]]}}}],["acquir",{"_index":10239,"t":{"3586":{"position":[[223,7]]},"3947":{"position":[[3712,8]]}}}],["act",{"_index":1183,"t":{"175":{"position":[[502,3]]},"471":{"position":[[172,3]]},"1226":{"position":[[3113,3]]},"1619":{"position":[[194,9],[266,3]]},"1950":{"position":[[194,9],[266,3]]},"2325":{"position":[[18,3]]},"2339":{"position":[[658,3]]},"2392":{"position":[[18,3]]},"2406":{"position":[[658,3]]},"2503":{"position":[[92,3]]},"2508":{"position":[[301,3]]},"2832":{"position":[[99,4]]},"3352":{"position":[[1911,3]]},"3855":{"position":[[399,3]]},"4124":{"position":[[186,3]]},"4226":{"position":[[3584,3]]}}}],["action",{"_index":412,"t":{"37":{"position":[[1886,6]]},"123":{"position":[[14,7]]},"173":{"position":[[673,6]]},"197":{"position":[[436,7]]},"226":{"position":[[237,7]]},"269":{"position":[[73,7]]},"362":{"position":[[454,7]]},"438":{"position":[[112,8]]},"512":{"position":[[1023,6]]},"706":{"position":[[53,7]]},"776":{"position":[[156,6]]},"830":{"position":[[275,8],[329,7]]},"976":{"position":[[63,6]]},"986":{"position":[[121,6]]},"988":{"position":[[107,6]]},"1303":{"position":[[3900,7]]},"1511":{"position":[[481,6]]},"1534":{"position":[[69,7]]},"1605":{"position":[[1305,6]]},"1694":{"position":[[2199,6],[5794,6]]},"1867":{"position":[[63,6]]},"1877":{"position":[[121,6]]},"1879":{"position":[[107,6]]},"2059":{"position":[[996,6],[1507,6]]},"2142":{"position":[[140,7]]},"2155":{"position":[[92,7],[564,7]]},"2157":{"position":[[165,6]]},"2276":{"position":[[1401,6]]},"2327":{"position":[[47,6],[580,6]]},"2337":{"position":[[236,7]]},"2353":{"position":[[73,6]]},"2355":{"position":[[47,7]]},"2358":{"position":[[21,6],[562,6]]},"2394":{"position":[[47,6],[580,6]]},"2404":{"position":[[236,7]]},"2420":{"position":[[73,6]]},"2422":{"position":[[47,7]]},"2425":{"position":[[21,6],[562,6]]},"2449":{"position":[[32,7]]},"2453":{"position":[[64,6]]},"2459":{"position":[[32,7]]},"2487":{"position":[[450,7]]},"2497":{"position":[[441,10]]},"2503":{"position":[[0,10]]},"2508":{"position":[[84,6]]},"2512":{"position":[[1061,7]]},"2520":{"position":[[53,7]]},"2522":{"position":[[343,8]]},"2539":{"position":[[653,7]]},"2626":{"position":[[2361,7]]},"2716":{"position":[[376,7]]},"2804":{"position":[[373,7]]},"2832":{"position":[[223,8]]},"3000":{"position":[[63,6]]},"3036":{"position":[[6120,7],[6835,7],[9830,7],[10775,7],[13911,7]]},"3047":{"position":[[77,7]]},"3088":{"position":[[457,7]]},"3214":{"position":[[275,7]]},"3575":{"position":[[953,7]]},"3990":{"position":[[360,6],[567,6],[1590,6],[2781,6]]},"4094":{"position":[[670,7]]},"4107":{"position":[[1811,7]]},"4220":{"position":[[358,7]]},"4475":{"position":[[113,7]]},"4504":{"position":[[97,6]]},"4525":{"position":[[172,6]]},"4539":{"position":[[1020,6]]},"4543":{"position":[[1415,6]]},"4593":{"position":[[3738,7],[3864,7],[6024,7]]},"4632":{"position":[[2438,6]]},"4669":{"position":[[601,6]]},"4733":{"position":[[1582,6]]}}}],["action.auto_create_index",{"_index":5566,"t":{"1303":{"position":[[1941,25],[2806,25]]}}}],["action.pi",{"_index":4121,"t":{"986":{"position":[[93,9]]},"988":{"position":[[89,9]]},"1877":{"position":[[93,9]]},"1879":{"position":[[89,9]]}}}],["activ",{"_index":35,"t":{"7":{"position":[[174,8]]},"78":{"position":[[57,10]]},"190":{"position":[[335,6]]},"197":{"position":[[674,6]]},"224":{"position":[[1011,8]]},"332":{"position":[[129,6]]},"366":{"position":[[172,9]]},"498":{"position":[[417,6]]},"854":{"position":[[625,10],[702,8]]},"865":{"position":[[851,6]]},"871":{"position":[[652,6]]},"873":{"position":[[647,6]]},"875":{"position":[[343,6]]},"887":{"position":[[9164,6]]},"932":{"position":[[2978,8]]},"942":{"position":[[3572,8]]},"978":{"position":[[278,6]]},"1067":{"position":[[1691,7]]},"1073":{"position":[[247,8]]},"1155":{"position":[[127,8]]},"1183":{"position":[[114,6],[280,6]]},"1191":{"position":[[1574,9]]},"1246":{"position":[[57,8]]},"1250":{"position":[[316,8]]},"1259":{"position":[[1053,8]]},"1261":{"position":[[169,9]]},"1263":{"position":[[127,9]]},"1513":{"position":[[163,6]]},"1523":{"position":[[411,7]]},"1655":{"position":[[93,8]]},"1686":{"position":[[568,6],[744,6]]},"1698":{"position":[[503,6],[1355,6]]},"1700":{"position":[[174,6],[251,6],[328,6],[855,6],[902,6],[949,6]]},"1730":{"position":[[103,6]]},"1766":{"position":[[851,6]]},"1772":{"position":[[652,6]]},"1774":{"position":[[647,6]]},"1776":{"position":[[343,6]]},"1811":{"position":[[9164,6]]},"1823":{"position":[[2978,8]]},"1833":{"position":[[3572,8]]},"1869":{"position":[[278,6]]},"2032":{"position":[[656,9]]},"2048":{"position":[[1372,8]]},"2052":{"position":[[555,10]]},"2139":{"position":[[1471,8]]},"2152":{"position":[[107,7]]},"2211":{"position":[[110,9]]},"2250":{"position":[[1044,6],[1115,6]]},"2254":{"position":[[417,6]]},"2270":{"position":[[301,6]]},"2339":{"position":[[1027,6]]},"2406":{"position":[[1027,6]]},"2478":{"position":[[807,8],[925,9]]},"2557":{"position":[[184,6],[255,6]]},"2725":{"position":[[308,8],[412,8]]},"2956":{"position":[[2978,8]]},"2966":{"position":[[3572,8]]},"3002":{"position":[[278,6]]},"3144":{"position":[[243,6]]},"3244":{"position":[[308,6],[405,8],[452,8]]},"3406":{"position":[[222,10]]},"3549":{"position":[[299,6]]},"3563":{"position":[[44,8]]},"3627":{"position":[[172,8]]},"3629":{"position":[[343,8]]},"3770":{"position":[[213,8]]},"4007":{"position":[[270,8]]},"4222":{"position":[[1029,6],[1541,8],[2736,6],[2767,6],[2943,8],[3946,6],[4217,11]]},"4224":{"position":[[1903,6]]},"4270":{"position":[[368,8]]},"4304":{"position":[[1500,6]]},"4351":{"position":[[150,8]]},"4365":{"position":[[299,6]]},"4418":{"position":[[549,8]]},"4420":{"position":[[467,8]]},"4489":{"position":[[484,8],[918,8]]},"4547":{"position":[[2379,8],[3411,9],[3652,9],[3821,9]]},"4554":{"position":[[462,6]]},"4560":{"position":[[947,8],[1972,8],[2271,8],[3335,8],[3514,8],[3785,8],[4558,8],[5055,8],[5508,8],[5617,8]]},"4562":{"position":[[530,8],[4274,6]]},"4587":{"position":[[1445,6]]},"4593":{"position":[[1463,6],[3175,6]]},"4662":{"position":[[1676,10],[1696,10]]},"4681":{"position":[[219,6]]},"4699":{"position":[[330,6]]},"4709":{"position":[[166,6],[271,6]]},"4722":{"position":[[582,6]]},"4757":{"position":[[66,8]]}}}],["active+clean",{"_index":6909,"t":{"1698":{"position":[[268,13],[925,13]]}}}],["active/standbi",{"_index":4802,"t":{"1183":{"position":[[30,14]]}}}],["activecount",{"_index":6072,"t":{"1409":{"position":[[1364,12]]}}}],["activelyaffectedbi",{"_index":9174,"t":{"2812":{"position":[[195,21]]}}}],["activestandbi",{"_index":6074,"t":{"1409":{"position":[[1400,14]]}}}],["actor",{"_index":11591,"t":{"4535":{"position":[[188,5],[1095,5],[1592,6]]},"4537":{"position":[[248,5]]},"4539":{"position":[[42,7]]},"4543":{"position":[[74,6]]},"4547":{"position":[[1309,7]]}}}],["actual",{"_index":1281,"t":{"181":{"position":[[1497,8],[2284,8]]},"288":{"position":[[986,6]]},"305":{"position":[[1379,8]]},"368":{"position":[[1698,6],[7691,8]]},"450":{"position":[[239,8]]},"461":{"position":[[357,8]]},"522":{"position":[[340,6]]},"647":{"position":[[308,8]]},"679":{"position":[[308,8]]},"854":{"position":[[172,8]]},"928":{"position":[[319,8]]},"961":{"position":[[1407,6]]},"963":{"position":[[886,6]]},"1569":{"position":[[631,8]]},"1571":{"position":[[298,8]]},"1593":{"position":[[1136,8]]},"1619":{"position":[[431,6]]},"1718":{"position":[[92,8]]},"1819":{"position":[[319,8]]},"1852":{"position":[[1407,6]]},"1854":{"position":[[886,6]]},"1902":{"position":[[781,8]]},"1904":{"position":[[298,8]]},"1936":{"position":[[1136,8]]},"1950":{"position":[[431,6]]},"2005":{"position":[[276,6]]},"2048":{"position":[[1462,8]]},"2104":{"position":[[105,8]]},"2211":{"position":[[2477,8]]},"2358":{"position":[[692,6]]},"2425":{"position":[[692,6]]},"2580":{"position":[[394,8],[792,6]]},"2602":{"position":[[2021,6],[2188,6]]},"2626":{"position":[[63,6]]},"2756":{"position":[[1531,6],[2066,6]]},"2912":{"position":[[144,8]]},"2918":{"position":[[39,6]]},"2952":{"position":[[319,8]]},"2985":{"position":[[1407,6]]},"2987":{"position":[[886,6]]},"3069":{"position":[[209,8]]},"3529":{"position":[[276,6],[1460,6]]},"3592":{"position":[[2596,6]]},"3679":{"position":[[370,8]]},"3793":{"position":[[369,8]]},"3833":{"position":[[299,6]]},"3913":{"position":[[80,8]]},"3918":{"position":[[680,6]]},"3928":{"position":[[991,8]]},"3960":{"position":[[60,6]]},"3971":{"position":[[820,8]]},"4124":{"position":[[274,6],[1727,6],[2379,8]]},"4257":{"position":[[4518,8]]},"4310":{"position":[[1293,8],[1546,6]]},"4516":{"position":[[1337,6]]},"4518":{"position":[[214,6]]},"4580":{"position":[[1616,8]]},"4669":{"position":[[900,6]]},"4691":{"position":[[93,6]]},"4715":{"position":[[274,6]]},"4839":{"position":[[1215,6]]}}}],["actuallydelete=tru",{"_index":3149,"t":{"706":{"position":[[2477,20]]}}}],["actuat",{"_index":2784,"t":{"557":{"position":[[4443,8]]}}}],["acura",{"_index":8082,"t":{"2234":{"position":[[632,5]]}}}],["ad",{"_index":1394,"t":{"197":{"position":[[562,5]]},"249":{"position":[[1742,6]]},"327":{"position":[[128,5]]},"530":{"position":[[125,7],[2075,5]]},"549":{"position":[[358,6]]},"706":{"position":[[150,5]]},"871":{"position":[[1163,6],[1399,6]]},"873":{"position":[[1229,6],[1280,5]]},"875":{"position":[[116,5],[145,5]]},"934":{"position":[[1483,6]]},"936":{"position":[[720,6]]},"959":{"position":[[82,6]]},"1056":{"position":[[1752,6]]},"1107":{"position":[[440,5]]},"1142":{"position":[[381,5]]},"1144":{"position":[[517,5]]},"1173":{"position":[[318,5]]},"1175":{"position":[[852,5],[4304,5]]},"1177":{"position":[[122,5],[3990,5]]},"1179":{"position":[[471,5],[1852,5]]},"1185":{"position":[[1744,5]]},"1205":{"position":[[701,5],[896,5]]},"1214":{"position":[[142,5]]},"1226":{"position":[[567,5],[1373,5],[4753,6],[5850,5]]},"1248":{"position":[[541,5]]},"1252":{"position":[[801,5],[1435,5]]},"1257":{"position":[[1381,5]]},"1297":{"position":[[153,5],[299,5],[1575,6]]},"1324":{"position":[[12621,5]]},"1377":{"position":[[72,6]]},"1383":{"position":[[318,5]]},"1385":{"position":[[1494,5],[1666,5],[1991,5]]},"1431":{"position":[[155,5]]},"1457":{"position":[[1227,5]]},"1472":{"position":[[1680,5]]},"1501":{"position":[[1417,5]]},"1503":{"position":[[1638,5]]},"1505":{"position":[[201,5],[570,5]]},"1507":{"position":[[177,5],[214,6]]},"1509":{"position":[[150,6]]},"1523":{"position":[[1381,5],[1785,5]]},"1525":{"position":[[1337,5]]},"1552":{"position":[[222,5]]},"1600":{"position":[[60,6]]},"1637":{"position":[[167,6],[188,6]]},"1644":{"position":[[33,5]]},"1657":{"position":[[132,5]]},"1772":{"position":[[1163,6],[1399,6]]},"1774":{"position":[[1229,6],[1280,5]]},"1776":{"position":[[116,5],[145,5]]},"1825":{"position":[[1483,6]]},"1827":{"position":[[720,6]]},"1850":{"position":[[82,6]]},"1968":{"position":[[240,6],[261,6]]},"2037":{"position":[[1306,5]]},"2048":{"position":[[2308,6]]},"2055":{"position":[[492,5],[822,5]]},"2059":{"position":[[813,5],[1042,6]]},"2065":{"position":[[1073,6]]},"2171":{"position":[[1521,5]]},"2175":{"position":[[488,5]]},"2199":{"position":[[864,5]]},"2211":{"position":[[149,6],[529,6],[725,6],[1113,6]]},"2285":{"position":[[119,6]]},"2287":{"position":[[1103,5],[1209,5]]},"2289":{"position":[[121,5],[382,5],[569,5],[651,5]]},"2295":{"position":[[254,5],[351,5]]},"2299":{"position":[[119,6]]},"2301":{"position":[[1103,5],[1209,5]]},"2303":{"position":[[121,5],[382,5],[569,5],[651,5]]},"2309":{"position":[[254,5],[351,5]]},"2465":{"position":[[356,6]]},"2473":{"position":[[264,6]]},"2703":{"position":[[147,6],[385,5]]},"2859":{"position":[[207,5]]},"2958":{"position":[[1483,6]]},"2960":{"position":[[720,6]]},"2983":{"position":[[82,6]]},"3075":{"position":[[59,5]]},"3086":{"position":[[493,5]]},"3105":{"position":[[59,5]]},"3126":{"position":[[72,6]]},"3136":{"position":[[967,6]]},"3138":{"position":[[59,5]]},"3153":{"position":[[183,5]]},"3155":{"position":[[112,6]]},"3159":{"position":[[436,5]]},"3189":{"position":[[74,6],[334,6],[557,5]]},"3200":{"position":[[170,5]]},"3225":{"position":[[621,5],[963,5],[1036,5]]},"3230":{"position":[[256,5]]},"3248":{"position":[[471,6]]},"3259":{"position":[[520,6]]},"3285":{"position":[[349,6]]},"3290":{"position":[[457,2]]},"3533":{"position":[[2567,6]]},"3600":{"position":[[588,5]]},"3608":{"position":[[254,5]]},"3636":{"position":[[168,6],[390,5]]},"3879":{"position":[[215,6]]},"3910":{"position":[[619,6]]},"3923":{"position":[[752,6]]},"3928":{"position":[[3797,6]]},"3930":{"position":[[63,5]]},"3936":{"position":[[20,5]]},"3938":{"position":[[65,5]]},"3982":{"position":[[87,5],[184,6]]},"4144":{"position":[[341,6]]},"4185":{"position":[[365,2]]},"4230":{"position":[[3290,5]]},"4266":{"position":[[172,5]]},"4310":{"position":[[1553,5]]},"4539":{"position":[[7195,6]]},"4593":{"position":[[2228,5],[5100,5]]},"4618":{"position":[[612,5]]},"4632":{"position":[[1416,6]]},"4643":{"position":[[208,5],[1920,5],[2148,5]]},"4667":{"position":[[14833,6]]},"4691":{"position":[[1112,5]]},"4707":{"position":[[237,6]]},"4738":{"position":[[346,6]]}}}],["ad1a16cd",{"_index":4791,"t":{"1179":{"position":[[1484,8],[1764,8],[1815,8],[1897,8],[1958,8],[2009,8]]}}}],["ad1cc1",{"_index":11105,"t":{"3990":{"position":[[2365,8]]}}}],["ad848454",{"_index":4139,"t":{"993":{"position":[[60,8],[158,8]]},"1884":{"position":[[60,8],[158,8]]}}}],["ada",{"_index":10706,"t":{"3744":{"position":[[1298,3]]}}}],["adam",{"_index":8319,"t":{"2279":{"position":[[533,4]]}}}],["adapt",{"_index":1511,"t":{"199":{"position":[[3228,7]]},"203":{"position":[[120,9]]},"543":{"position":[[2804,12]]},"1050":{"position":[[103,8]]},"1464":{"position":[[398,8]]},"1527":{"position":[[272,5]]},"1574":{"position":[[733,7]]},"1637":{"position":[[58,5]]},"1917":{"position":[[733,7]]},"1968":{"position":[[131,5]]},"2117":{"position":[[495,5]]},"2285":{"position":[[174,5]]},"2299":{"position":[[174,5]]},"2473":{"position":[[238,5]]},"2914":{"position":[[422,10]]},"3050":{"position":[[141,7]]},"3384":{"position":[[22,5]]},"3588":{"position":[[278,5]]},"4150":{"position":[[283,5]]},"4281":{"position":[[87,7],[466,7]]},"4291":{"position":[[2392,5]]},"4489":{"position":[[401,7]]},"4493":{"position":[[66,5],[419,7]]},"4562":{"position":[[2352,8]]},"4632":{"position":[[1640,5]]}}}],["adcd",{"_index":4189,"t":{"995":{"position":[[1438,4]]},"1886":{"position":[[1438,4]]}}}],["add",{"_index":641,"t":{"95":{"position":[[51,3]]},"97":{"position":[[166,3]]},"99":{"position":[[184,3]]},"141":{"position":[[277,3]]},"153":{"position":[[45,3]]},"159":{"position":[[266,3]]},"173":{"position":[[1440,3]]},"266":{"position":[[409,4],[480,3]]},"295":{"position":[[598,3],[936,3]]},"362":{"position":[[679,3]]},"368":{"position":[[1298,3],[4241,3]]},"417":{"position":[[982,3]]},"421":{"position":[[267,4]]},"423":{"position":[[458,4]]},"427":{"position":[[509,3]]},"528":{"position":[[548,3]]},"634":{"position":[[221,3]]},"738":{"position":[[281,3]]},"741":{"position":[[1590,4]]},"861":{"position":[[695,3]]},"912":{"position":[[2227,3],[7518,3]]},"918":{"position":[[55,3]]},"932":{"position":[[838,3]]},"934":{"position":[[1561,3]]},"936":{"position":[[397,3]]},"942":{"position":[[2574,3],[3521,3]]},"955":{"position":[[45,3]]},"961":{"position":[[1146,3]]},"963":{"position":[[2021,3],[2506,3]]},"967":{"position":[[685,3]]},"1142":{"position":[[60,3]]},"1144":{"position":[[56,3]]},"1157":{"position":[[222,3]]},"1159":{"position":[[215,3]]},"1167":{"position":[[277,3]]},"1169":{"position":[[0,3],[1250,3],[1355,3]]},"1175":{"position":[[76,3]]},"1177":{"position":[[845,3],[4448,3]]},"1179":{"position":[[575,3]]},"1191":{"position":[[0,3],[37,3],[82,3],[749,3]]},"1195":{"position":[[45,3]]},"1199":{"position":[[188,3],[778,3]]},"1224":{"position":[[0,3],[62,3],[392,3]]},"1230":{"position":[[1026,3],[1192,3]]},"1238":{"position":[[403,3]]},"1246":{"position":[[310,3],[824,3],[866,3],[1022,4]]},"1248":{"position":[[1076,3]]},"1314":{"position":[[92,3]]},"1316":{"position":[[199,3],[499,3]]},"1324":{"position":[[6866,3],[13193,3]]},"1371":{"position":[[0,3],[262,3]]},"1383":{"position":[[1247,3],[2279,3]]},"1443":{"position":[[772,3]]},"1464":{"position":[[791,3]]},"1472":{"position":[[3313,3],[3354,3],[3392,3]]},"1505":{"position":[[484,3],[732,3]]},"1517":{"position":[[85,3]]},"1561":{"position":[[999,3]]},"1580":{"position":[[420,3],[450,3],[520,3]]},"1661":{"position":[[80,3]]},"1711":{"position":[[0,3],[687,3],[876,3]]},"1762":{"position":[[695,3]]},"1796":{"position":[[2227,3],[7518,3]]},"1802":{"position":[[55,3]]},"1823":{"position":[[838,3]]},"1825":{"position":[[1561,3]]},"1827":{"position":[[397,3]]},"1833":{"position":[[2574,3],[3521,3]]},"1846":{"position":[[45,3]]},"1852":{"position":[[1146,3]]},"1854":{"position":[[2021,3],[2506,3]]},"1858":{"position":[[685,3]]},"1923":{"position":[[420,3],[450,3],[520,3]]},"1981":{"position":[[32,3]]},"2048":{"position":[[2512,4],[3021,3],[3216,3],[3241,3],[3596,3]]},"2059":{"position":[[489,3],[1350,3],[1642,3],[2408,3]]},"2065":{"position":[[2431,3],[2753,3],[3072,3],[3393,3]]},"2074":{"position":[[15,3],[229,3],[364,3],[447,3],[532,3],[638,3],[769,3],[900,3]]},"2076":{"position":[[13,3]]},"2088":{"position":[[38,3]]},"2090":{"position":[[256,3]]},"2117":{"position":[[1703,3],[2251,3],[2378,3],[2456,3]]},"2121":{"position":[[586,3]]},"2139":{"position":[[358,4]]},"2184":{"position":[[2232,3],[2608,3]]},"2199":{"position":[[473,3]]},"2207":{"position":[[241,3],[451,3]]},"2240":{"position":[[646,3]]},"2250":{"position":[[401,3],[474,3]]},"2285":{"position":[[1253,3]]},"2289":{"position":[[431,3]]},"2295":{"position":[[534,3],[626,3]]},"2299":{"position":[[1253,3]]},"2303":{"position":[[431,3]]},"2309":{"position":[[534,3],[626,3]]},"2349":{"position":[[339,3]]},"2416":{"position":[[339,3]]},"2431":{"position":[[2484,4]]},"2453":{"position":[[1127,3]]},"2455":{"position":[[15,3]]},"2465":{"position":[[398,3]]},"2467":{"position":[[489,3],[586,3],[944,3],[1044,3]]},"2478":{"position":[[501,4],[986,4],[1428,3],[1465,3]]},"2569":{"position":[[596,3]]},"2614":{"position":[[823,3]]},"2636":{"position":[[914,3]]},"2647":{"position":[[1857,3]]},"2649":{"position":[[2919,3],[3000,3]]},"2657":{"position":[[10,3]]},"2674":{"position":[[79,3]]},"2678":{"position":[[252,3]]},"2730":{"position":[[36,3]]},"2738":{"position":[[33,3]]},"2740":{"position":[[27,3],[407,3],[727,3]]},"2747":{"position":[[78,3],[103,3],[117,3]]},"2756":{"position":[[114,3],[153,3]]},"2956":{"position":[[838,3]]},"2958":{"position":[[1561,3]]},"2960":{"position":[[397,3]]},"2966":{"position":[[2574,3],[3521,3]]},"2979":{"position":[[45,3]]},"2985":{"position":[[1146,3]]},"2987":{"position":[[2021,3],[2506,3]]},"2991":{"position":[[685,3]]},"3050":{"position":[[640,3]]},"3225":{"position":[[916,4]]},"3230":{"position":[[846,3]]},"3352":{"position":[[1143,4],[2963,4]]},"3357":{"position":[[3339,3]]},"3378":{"position":[[602,3],[695,3],[813,3]]},"3381":{"position":[[85,4],[159,4],[759,3],[874,3],[1062,3],[1184,3],[1383,3],[2650,4]]},"3384":{"position":[[1639,4]]},"3533":{"position":[[717,3],[2186,3]]},"3608":{"position":[[329,3],[376,3]]},"3679":{"position":[[1606,3]]},"3704":{"position":[[1614,3]]},"3793":{"position":[[1868,3]]},"3824":{"position":[[179,3]]},"3968":{"position":[[1588,3],[1740,3]]},"3973":{"position":[[75,3],[489,3]]},"3986":{"position":[[336,3]]},"4081":{"position":[[204,4]]},"4148":{"position":[[829,3]]},"4226":{"position":[[3497,4]]},"4230":{"position":[[2110,4]]},"4234":{"position":[[113,4]]},"4304":{"position":[[1415,3]]},"4516":{"position":[[1121,3]]},"4582":{"position":[[502,3]]},"4593":{"position":[[5761,3]]},"4643":{"position":[[1687,3],[1770,3],[2062,3],[2258,3],[2725,3],[3376,3]]},"4667":{"position":[[6860,3]]},"4845":{"position":[[131,3]]},"4859":{"position":[[3,3]]},"4861":{"position":[[479,3]]},"4863":{"position":[[45,3]]},"4875":{"position":[[132,3]]},"4877":{"position":[[187,3]]},"4881":{"position":[[39,3]]}}}],["add2",{"_index":11146,"t":{"4051":{"position":[[1159,4]]}}}],["addit",{"_index":486,"t":{"64":{"position":[[87,10]]},"141":{"position":[[281,10]]},"159":{"position":[[270,10]]},"169":{"position":[[212,10],[892,10]]},"284":{"position":[[587,10]]},"288":{"position":[[512,9]]},"295":{"position":[[1670,10]]},"319":{"position":[[610,8]]},"368":{"position":[[2411,10],[6079,10]]},"380":{"position":[[140,10]]},"417":{"position":[[905,10]]},"423":{"position":[[1223,9]]},"461":{"position":[[656,8]]},"557":{"position":[[2936,10],[3761,10]]},"611":{"position":[[482,10]]},"706":{"position":[[167,10]]},"715":{"position":[[443,10]]},"717":{"position":[[562,10]]},"719":{"position":[[242,10]]},"724":{"position":[[261,10]]},"726":{"position":[[328,10]]},"755":{"position":[[28,10]]},"818":{"position":[[281,10]]},"838":{"position":[[310,8]]},"846":{"position":[[291,8]]},"861":{"position":[[699,10]]},"887":{"position":[[8714,10]]},"892":{"position":[[270,10]]},"912":{"position":[[5175,10]]},"942":{"position":[[441,10]]},"973":{"position":[[245,10]]},"1111":{"position":[[386,10]]},"1144":{"position":[[490,10]]},"1169":{"position":[[1036,10]]},"1181":{"position":[[221,10]]},"1191":{"position":[[313,10]]},"1199":{"position":[[782,10]]},"1205":{"position":[[59,10]]},"1214":{"position":[[101,10]]},"1244":{"position":[[29,10],[549,10]]},"1252":{"position":[[363,10],[2361,10],[2810,10],[3681,10]]},"1297":{"position":[[79,10],[1383,10],[1551,10],[3859,10]]},"1301":{"position":[[2356,10]]},"1363":{"position":[[84,10]]},"1391":{"position":[[2441,10]]},"1437":{"position":[[170,8]]},"1443":{"position":[[194,10]]},"1661":{"position":[[322,10]]},"1750":{"position":[[270,10]]},"1762":{"position":[[699,10]]},"1796":{"position":[[5175,10]]},"1811":{"position":[[8714,10]]},"1833":{"position":[[441,10]]},"1864":{"position":[[245,10]]},"2048":{"position":[[2801,10],[2846,10],[2929,10],[3119,10],[3426,10],[3504,10]]},"2090":{"position":[[260,10]]},"2119":{"position":[[528,8]]},"2207":{"position":[[194,8]]},"2252":{"position":[[504,10],[1591,10]]},"2276":{"position":[[852,8],[1316,8]]},"2285":{"position":[[1136,10]]},"2287":{"position":[[132,10]]},"2299":{"position":[[1136,10]]},"2301":{"position":[[132,10]]},"2327":{"position":[[163,8]]},"2394":{"position":[[163,8]]},"2429":{"position":[[302,8]]},"2473":{"position":[[271,10]]},"2551":{"position":[[583,10]]},"2557":{"position":[[557,10]]},"2592":{"position":[[626,10]]},"2608":{"position":[[1315,10]]},"2661":{"position":[[533,10]]},"2725":{"position":[[711,10]]},"2887":{"position":[[38,10]]},"2966":{"position":[[441,10]]},"2997":{"position":[[245,10]]},"3071":{"position":[[246,8]]},"3083":{"position":[[682,8]]},"3119":{"position":[[249,8]]},"3298":{"position":[[258,10]]},"3344":{"position":[[111,8]]},"3361":{"position":[[393,9]]},"3460":{"position":[[292,10]]},"3516":{"position":[[430,10]]},"3521":{"position":[[196,9]]},"3525":{"position":[[623,10]]},"3527":{"position":[[1630,8]]},"3529":{"position":[[598,9],[1829,9]]},"3582":{"position":[[975,9]]},"3592":{"position":[[1329,10]]},"3602":{"position":[[200,10]]},"3661":{"position":[[1449,10]]},"3679":{"position":[[1249,10],[1331,10]]},"3698":{"position":[[2103,10]]},"3722":{"position":[[1377,8]]},"3735":{"position":[[225,10]]},"3747":{"position":[[324,9]]},"3763":{"position":[[960,9]]},"3785":{"position":[[1801,10]]},"3793":{"position":[[1475,10],[1567,10]]},"3815":{"position":[[1375,8]]},"3888":{"position":[[187,9]]},"3890":{"position":[[12,10]]},"3896":{"position":[[131,10]]},"3902":{"position":[[144,9]]},"3928":{"position":[[1656,10],[5898,10],[5997,10]]},"3930":{"position":[[309,10]]},"3936":{"position":[[294,10]]},"4026":{"position":[[314,10]]},"4028":{"position":[[589,10]]},"4041":{"position":[[660,10]]},"4060":{"position":[[224,10]]},"4094":{"position":[[659,10]]},"4163":{"position":[[1359,10]]},"4189":{"position":[[545,10]]},"4222":{"position":[[2517,10]]},"4226":{"position":[[155,10],[3067,8]]},"4230":{"position":[[3431,10],[4242,10]]},"4236":{"position":[[374,10]]},"4257":{"position":[[2493,10],[3591,10]]},"4273":{"position":[[790,10]]},"4279":{"position":[[1319,8]]},"4302":{"position":[[1805,10]]},"4420":{"position":[[2312,10],[2371,8]]},"4485":{"position":[[1622,10]]},"4506":{"position":[[1138,10]]},"4516":{"position":[[1125,10]]},"4520":{"position":[[621,8]]},"4537":{"position":[[703,10]]},"4543":{"position":[[1608,8]]},"4562":{"position":[[4863,9],[6753,10],[7542,10]]},"4576":{"position":[[200,10]]},"4587":{"position":[[700,10],[1079,8]]},"4643":{"position":[[3384,10]]},"4658":{"position":[[263,10],[372,9]]},"4660":{"position":[[2471,10]]},"4662":{"position":[[420,10],[1154,10]]},"4667":{"position":[[13891,8]]},"4686":{"position":[[196,9]]},"4724":{"position":[[255,10]]},"4728":{"position":[[324,8]]},"4744":{"position":[[944,9]]},"4863":{"position":[[49,10]]}}}],["addition",{"_index":708,"t":{"119":{"position":[[291,12]]},"461":{"position":[[446,13]]},"530":{"position":[[1382,13]]},"611":{"position":[[222,12]]},"622":{"position":[[468,13]]},"912":{"position":[[7493,12]]},"1303":{"position":[[2008,12]]},"1387":{"position":[[212,12]]},"1391":{"position":[[2151,13]]},"1484":{"position":[[212,12]]},"1796":{"position":[[7493,12]]},"1979":{"position":[[212,12]]},"2148":{"position":[[212,12]]},"2289":{"position":[[201,13],[340,12]]},"2303":{"position":[[201,13],[340,12]]},"2431":{"position":[[3077,12]]},"2497":{"position":[[398,13]]},"2651":{"position":[[364,13]]},"3575":{"position":[[874,13]]},"3843":{"position":[[196,13]]},"3883":{"position":[[330,13]]},"4026":{"position":[[181,12]]},"4133":{"position":[[1870,13]]},"4159":{"position":[[2024,12]]},"4163":{"position":[[3685,12]]},"4200":{"position":[[406,12]]},"4257":{"position":[[1017,12]]},"4266":{"position":[[357,12]]},"4275":{"position":[[1018,13]]},"4304":{"position":[[1762,12]]},"4420":{"position":[[2279,12]]},"4475":{"position":[[569,13]]},"4481":{"position":[[548,13]]},"4535":{"position":[[4134,13]]},"4539":{"position":[[3212,13]]},"4547":{"position":[[3348,13]]},"4614":{"position":[[1015,13]]}}}],["additionallabel",{"_index":8803,"t":{"2649":{"position":[[1811,20],[2119,20]]}}}],["additionalprometheusrulesmap",{"_index":8802,"t":{"2649":{"position":[[1750,32],[2061,32]]}}}],["addon",{"_index":2270,"t":{"378":{"position":[[673,7]]},"395":{"position":[[76,6]]},"401":{"position":[[705,7],[960,7],[980,6]]},"409":{"position":[[60,6]]},"417":{"position":[[393,6],[714,6],[958,5],[1099,5],[1343,7]]},"421":{"position":[[718,7]]},"446":{"position":[[296,6]]},"463":{"position":[[1291,6]]},"489":{"position":[[795,5],[844,5]]},"493":{"position":[[157,5],[206,5]]},"537":{"position":[[280,7]]},"539":{"position":[[584,5]]},"541":{"position":[[8,6],[415,6],[1330,6],[1658,5]]},"551":{"position":[[527,5],[1146,5],[2131,7],[2437,5],[2553,7],[3054,5]]},"588":{"position":[[634,7]]},"595":{"position":[[673,6]]},"602":{"position":[[232,6],[323,6]]},"611":{"position":[[332,5]]},"632":{"position":[[439,5]]},"647":{"position":[[234,6]]},"659":{"position":[[263,5],[332,6]]},"679":{"position":[[234,6]]},"2582":{"position":[[174,7]]},"3223":{"position":[[266,6]]},"3296":{"position":[[12,6],[70,6],[362,6]]}}}],["address",{"_index":2190,"t":{"368":{"position":[[2403,7]]},"557":{"position":[[1359,7],[1458,7],[6529,7]]},"692":{"position":[[127,7],[517,7]]},"747":{"position":[[46,7]]},"830":{"position":[[59,9]]},"924":{"position":[[894,9]]},"932":{"position":[[3620,7],[3662,9],[3730,8]]},"942":{"position":[[505,9]]},"957":{"position":[[192,7]]},"978":{"position":[[908,8],[1057,7]]},"1169":{"position":[[1787,7]]},"1181":{"position":[[198,7]]},"1226":{"position":[[1629,7],[1769,7],[1795,7],[1879,8],[2591,10],[4237,7],[4396,7],[4852,10]]},"1230":{"position":[[43,7],[369,7],[655,7],[745,7]]},"1244":{"position":[[385,9]]},"1252":{"position":[[2605,7],[2700,7],[2832,7]]},"1261":{"position":[[225,7]]},"1268":{"position":[[256,10],[298,10],[437,10],[495,10],[538,10]]},"1275":{"position":[[545,10]]},"1342":{"position":[[292,7]]},"1391":{"position":[[1048,8],[1100,8],[1152,8],[1321,9]]},"1547":{"position":[[37,8],[49,7],[71,7],[82,7]]},"1704":{"position":[[648,10],[743,10],[839,10],[935,10],[1644,8],[2320,8]]},"1745":{"position":[[17,7],[443,7]]},"1815":{"position":[[894,9]]},"1823":{"position":[[3620,7],[3662,9],[3730,8]]},"1833":{"position":[[505,9]]},"1848":{"position":[[192,7]]},"1869":{"position":[[908,8],[1057,7]]},"2032":{"position":[[1679,7]]},"2034":{"position":[[876,7],[1766,7]]},"2037":{"position":[[325,7],[993,7]]},"2048":{"position":[[396,9],[3562,7]]},"2052":{"position":[[891,7]]},"2188":{"position":[[153,9]]},"2190":{"position":[[535,7]]},"2192":{"position":[[240,7]]},"2199":{"position":[[101,8],[257,7]]},"2221":{"position":[[174,9]]},"2236":{"position":[[198,7]]},"2252":{"position":[[1553,8]]},"2285":{"position":[[671,7]]},"2299":{"position":[[671,7]]},"2380":{"position":[[74,9],[506,9]]},"2439":{"position":[[666,10]]},"2480":{"position":[[515,9]]},"2485":{"position":[[486,7]]},"2489":{"position":[[846,10]]},"2501":{"position":[[276,7],[665,7]]},"2508":{"position":[[580,7]]},"2512":{"position":[[1340,9]]},"2516":{"position":[[380,10]]},"2518":{"position":[[143,9],[487,7]]},"2520":{"position":[[451,10]]},"2522":{"position":[[207,7],[386,9]]},"2525":{"position":[[680,7]]},"2531":{"position":[[1401,9]]},"2537":{"position":[[568,7]]},"2718":{"position":[[683,10]]},"2720":{"position":[[541,7],[567,7],[1149,7],[1194,7]]},"2834":{"position":[[15,7],[61,8]]},"2948":{"position":[[894,9]]},"2956":{"position":[[3620,7],[3662,9],[3730,8]]},"2966":{"position":[[505,9]]},"2981":{"position":[[192,7]]},"3002":{"position":[[908,8],[1057,7]]},"3099":{"position":[[117,10]]},"3124":{"position":[[170,7]]},"3153":{"position":[[1014,10]]},"3189":{"position":[[91,10]]},"3246":{"position":[[106,9]]},"3266":{"position":[[704,7]]},"3306":{"position":[[106,9]]},"3348":{"position":[[547,7]]},"3357":{"position":[[3842,7]]},"3460":{"position":[[132,9]]},"3470":{"position":[[189,9]]},"3516":{"position":[[22,9]]},"3567":{"position":[[0,10]]},"3571":{"position":[[478,10]]},"3644":{"position":[[153,7]]},"3690":{"position":[[963,7]]},"3777":{"position":[[1064,7]]},"3928":{"position":[[1802,7],[2245,7],[3061,7],[5813,9]]},"3988":{"position":[[580,7],[1704,9]]},"4051":{"position":[[477,7]]},"4107":{"position":[[962,9]]},"4146":{"position":[[3217,7]]},"4153":{"position":[[380,7]]},"4222":{"position":[[3198,8],[3634,7]]},"4224":{"position":[[1640,7],[1757,7]]},"4230":{"position":[[4342,7],[5288,7]]},"4236":{"position":[[257,9]]},"4266":{"position":[[558,9]]},"4298":{"position":[[465,7]]},"4300":{"position":[[615,7]]},"4302":{"position":[[3369,8]]},"4304":{"position":[[2558,9]]},"4308":{"position":[[814,7]]},"4310":{"position":[[272,10]]},"4313":{"position":[[223,8]]},"4321":{"position":[[141,8],[291,8]]},"4342":{"position":[[206,7]]},"4353":{"position":[[742,9]]},"4475":{"position":[[244,10]]},"4502":{"position":[[141,7]]},"4560":{"position":[[3277,7],[4500,7]]},"4580":{"position":[[211,7]]},"4608":{"position":[[623,7]]},"4614":{"position":[[759,10]]},"4872":{"position":[[430,8]]}}}],["address=$fixedip,subnet=oshm",{"_index":3805,"t":{"932":{"position":[[3437,28]]},"1823":{"position":[[3437,28]]},"2956":{"position":[[3437,28]]}}}],["addressed.(k8",{"_index":9809,"t":{"3166":{"position":[[44,14]]}}}],["addresses/flo",{"_index":3342,"t":{"846":{"position":[[143,18]]}}}],["addressrang",{"_index":6003,"t":{"1405":{"position":[[1642,14]]}}}],["adequ",{"_index":10125,"t":{"3406":{"position":[[38,8]]},"4298":{"position":[[757,8]]},"4302":{"position":[[2634,8],[4792,8]]}}}],["adf6078ceba6",{"_index":4777,"t":{"1177":{"position":[[4924,12],[5310,12],[5361,12],[5816,12],[5919,12],[6214,12],[6256,12]]}}}],["adguard",{"_index":7332,"t":{"2037":{"position":[[1119,7]]}}}],["adher",{"_index":598,"t":{"82":{"position":[[80,7]]},"197":{"position":[[920,6],[2004,6]]},"199":{"position":[[21,6]]},"249":{"position":[[1710,6]]},"280":{"position":[[459,6]]},"288":{"position":[[1221,7]]},"305":{"position":[[1297,8]]},"638":{"position":[[162,6]]},"788":{"position":[[71,8]]},"2094":{"position":[[81,6]]},"2501":{"position":[[1034,7]]},"2506":{"position":[[483,9]]},"3525":{"position":[[110,8]]},"3627":{"position":[[381,6]]},"3685":{"position":[[66,6]]},"3986":{"position":[[209,6]]},"3992":{"position":[[10,8]]},"4319":{"position":[[103,6]]},"4667":{"position":[[13501,7]]}}}],["adipisc",{"_index":6,"t":{"3":{"position":[[40,10]]}}}],["adit",{"_index":11691,"t":{"4576":{"position":[[38,9]]}}}],["adjust",{"_index":1032,"t":{"169":{"position":[[612,6]]},"179":{"position":[[153,6]]},"325":{"position":[[83,8]]},"376":{"position":[[327,12]]},"588":{"position":[[155,6],[277,6]]},"912":{"position":[[6069,9]]},"934":{"position":[[818,8]]},"942":{"position":[[3938,6]]},"946":{"position":[[208,6]]},"963":{"position":[[546,12],[4659,9],[5277,9]]},"1257":{"position":[[79,11]]},"1468":{"position":[[1212,11]]},"1529":{"position":[[541,8]]},"1605":{"position":[[543,10]]},"1796":{"position":[[6069,9]]},"1825":{"position":[[818,8]]},"1833":{"position":[[3938,6]]},"1837":{"position":[[208,6]]},"1854":{"position":[[546,12],[4659,9],[5277,9]]},"2163":{"position":[[3878,6]]},"2165":{"position":[[1501,11]]},"2171":{"position":[[79,11]]},"2225":{"position":[[84,12]]},"2248":{"position":[[427,6],[446,6]]},"2283":{"position":[[704,8]]},"2297":{"position":[[704,8]]},"2376":{"position":[[349,11]]},"2441":{"position":[[125,9],[560,12]]},"2443":{"position":[[364,6],[801,11]]},"2447":{"position":[[295,11],[344,8],[625,7]]},"2467":{"position":[[1586,11]]},"2469":{"position":[[259,11]]},"2614":{"position":[[394,11]]},"2626":{"position":[[279,6],[1599,9]]},"2686":{"position":[[168,10]]},"2718":{"position":[[495,8],[980,7]]},"2743":{"position":[[230,6]]},"2756":{"position":[[2122,6]]},"2958":{"position":[[818,8]]},"2966":{"position":[[3938,6]]},"2970":{"position":[[208,6]]},"2987":{"position":[[546,12],[4659,9],[5277,9]]},"3091":{"position":[[110,9]]},"3290":{"position":[[824,8]]},"3352":{"position":[[274,11]]},"4015":{"position":[[145,9]]},"4041":{"position":[[1044,8],[1199,8]]},"4043":{"position":[[311,9]]},"4045":{"position":[[1791,9]]},"4081":{"position":[[2137,6]]},"4085":{"position":[[75,8]]},"4591":{"position":[[174,11]]},"4593":{"position":[[768,8]]},"4608":{"position":[[787,11]]},"4614":{"position":[[1062,8]]},"4618":{"position":[[426,8],[503,6],[1015,11]]},"4667":{"position":[[13320,8],[14195,9]]},"4820":{"position":[[38,6]]}}}],["adjustments.(k8",{"_index":9813,"t":{"3166":{"position":[[145,16]]}}}],["admin",{"_index":737,"t":{"130":{"position":[[464,5]]},"309":{"position":[[56,5],[265,5]]},"557":{"position":[[5414,6]]},"753":{"position":[[258,5]]},"830":{"position":[[218,5]]},"894":{"position":[[353,5],[768,6],[1565,5],[1606,5]]},"906":{"position":[[77,5],[107,5],[131,5],[146,5]]},"908":{"position":[[135,5],[165,5]]},"910":{"position":[[294,5],[326,5]]},"912":{"position":[[357,5],[394,5],[472,5],[712,5],[736,5],[1408,5],[1434,5],[1456,5],[1474,5],[2093,5],[2111,5],[2553,5],[2588,5],[2610,5],[2645,5],[3850,5],[3899,5],[4404,5],[4424,5],[6807,5],[7544,5],[7609,6],[7735,6],[7814,5],[8094,5]]},"914":{"position":[[422,5],[459,5],[672,5],[801,5],[827,5],[849,5],[867,5],[1786,5],[1821,5]]},"916":{"position":[[243,5]]},"930":{"position":[[30,5],[537,5],[730,5]]},"963":{"position":[[963,5],[1881,5],[5163,6]]},"980":{"position":[[358,6],[487,5],[681,5]]},"983":{"position":[[189,5]]},"1169":{"position":[[265,6],[312,6],[342,5],[356,7],[378,5],[417,5],[483,5],[523,5],[562,5]]},"1181":{"position":[[17,5],[167,5],[360,5]]},"1277":{"position":[[5,5]]},"1279":{"position":[[11,5]]},"1281":{"position":[[9,5]]},"1283":{"position":[[7,5]]},"1287":{"position":[[10,5]]},"1289":{"position":[[7,5]]},"1308":{"position":[[5,5]]},"1310":{"position":[[8,5]]},"1318":{"position":[[7,5]]},"1320":{"position":[[7,5]]},"1322":{"position":[[9,5]]},"1324":{"position":[[6131,6],[6349,6],[7343,6],[8113,6],[12680,5],[13180,5]]},"1327":{"position":[[7,5]]},"1329":{"position":[[8,5],[129,5],[264,5]]},"1331":{"position":[[472,5]]},"1333":{"position":[[10,5]]},"1335":{"position":[[8,5]]},"1340":{"position":[[16,5]]},"1356":{"position":[[5,5]]},"1407":{"position":[[689,5],[1153,5]]},"1425":{"position":[[17,5]]},"1527":{"position":[[524,5]]},"1552":{"position":[[108,5],[654,5]]},"1700":{"position":[[79,5],[781,5]]},"1707":{"position":[[387,5]]},"1709":{"position":[[342,5],[458,5]]},"1713":{"position":[[687,5],[1306,5],[1599,5],[2328,5],[2415,5]]},"1716":{"position":[[23,5],[1492,5]]},"1720":{"position":[[173,5],[660,5],[1300,5],[1370,5],[2065,5],[2184,5]]},"1725":{"position":[[90,5]]},"1728":{"position":[[21,5]]},"1730":{"position":[[37,5],[193,5]]},"1732":{"position":[[21,5],[132,5],[1032,5],[1116,5]]},"1734":{"position":[[21,5],[133,5],[1027,5],[1137,5]]},"1740":{"position":[[516,5]]},"1745":{"position":[[100,5]]},"1752":{"position":[[353,5],[768,6],[1565,5],[1606,5]]},"1790":{"position":[[77,5],[107,5],[131,5],[146,5]]},"1792":{"position":[[135,5],[165,5]]},"1794":{"position":[[294,5],[326,5]]},"1796":{"position":[[357,5],[394,5],[472,5],[712,5],[736,5],[1408,5],[1434,5],[1456,5],[1474,5],[2093,5],[2111,5],[2553,5],[2588,5],[2610,5],[2645,5],[3850,5],[3899,5],[4404,5],[4424,5],[6807,5],[7544,5],[7609,6],[7735,6],[7814,5],[8094,5]]},"1798":{"position":[[422,5],[459,5],[672,5],[801,5],[827,5],[849,5],[867,5],[1786,5],[1821,5]]},"1800":{"position":[[243,5]]},"1821":{"position":[[30,5],[537,5],[730,5]]},"1854":{"position":[[963,5],[1881,5],[5163,6]]},"1871":{"position":[[358,6],[487,5],[681,5]]},"1874":{"position":[[189,5]]},"2039":{"position":[[215,5],[375,5],[543,5],[594,5],[674,5],[920,5],[971,5]]},"2041":{"position":[[129,5]]},"2048":{"position":[[2987,5],[3175,5]]},"2132":{"position":[[372,6],[423,5]]},"2194":{"position":[[397,5],[499,5],[940,5],[1096,5],[1151,5],[1259,5],[1401,5]]},"2196":{"position":[[1727,5]]},"2431":{"position":[[3280,5],[3442,5],[3991,5],[4459,5]]},"2441":{"position":[[362,5]]},"2449":{"position":[[84,5]]},"2478":{"position":[[2494,7]]},"2602":{"position":[[1629,5],[1670,5],[1852,5]]},"2616":{"position":[[213,5]]},"2636":{"position":[[735,5]]},"2647":{"position":[[2772,5]]},"2659":{"position":[[209,5]]},"2676":{"position":[[246,5]]},"2873":{"position":[[448,5]]},"2954":{"position":[[30,5],[537,5],[730,5]]},"2987":{"position":[[963,5],[1881,5],[5163,6]]},"3004":{"position":[[358,6],[487,5],[681,5]]},"3200":{"position":[[318,7]]},"3731":{"position":[[314,5]]},"3947":{"position":[[105,5],[199,5],[2061,7],[3608,5],[3890,6],[4425,6]]},"3951":{"position":[[435,5]]},"3980":{"position":[[393,5]]},"3990":{"position":[[135,7],[1123,6]]},"3992":{"position":[[97,5],[465,6]]},"4026":{"position":[[93,5]]},"4039":{"position":[[198,6],[252,5]]},"4045":{"position":[[402,6],[583,7]]},"4130":{"position":[[135,5]]},"4226":{"position":[[654,5]]},"4289":{"position":[[44,5]]},"4485":{"position":[[1602,5]]},"4587":{"position":[[534,5]]},"4604":{"position":[[332,5]]},"4606":{"position":[[634,5],[695,5]]},"4608":{"position":[[62,5],[186,5],[365,5]]},"4610":{"position":[[10,5],[138,5],[253,5]]},"4612":{"position":[[723,7]]},"4614":{"position":[[22,5],[155,5],[323,5],[643,5]]},"4618":{"position":[[589,5]]},"4625":{"position":[[81,5],[142,5],[186,5],[279,5],[361,7]]},"4632":{"position":[[1427,7],[2631,7],[2684,5],[2953,7]]},"4634":{"position":[[77,7]]},"4643":{"position":[[456,5],[482,5],[671,6],[809,7],[1055,7],[1181,5],[1225,5],[1318,5],[1445,5],[1886,5],[1941,6],[2179,6]]},"4667":{"position":[[6159,6],[6343,6],[7337,6],[8107,6],[13582,7]]},"4857":{"position":[[17,5],[90,5]]},"4877":{"position":[[77,5]]}}}],["admin@example.com",{"_index":3051,"t":{"692":{"position":[[493,17]]}}}],["admin_domain",{"_index":3620,"t":{"912":{"position":[[370,13],[1421,12]]},"914":{"position":[[435,13],[814,12]]},"1796":{"position":[[370,13],[1421,12]]},"1798":{"position":[[435,13],[814,12]]}}}],["admin_password",{"_index":3650,"t":{"912":{"position":[[4469,14]]},"963":{"position":[[969,14]]},"1796":{"position":[[4469,14]]},"1854":{"position":[[969,14]]},"2987":{"position":[[969,14]]}}}],["admin_us",{"_index":4029,"t":{"963":{"position":[[950,10]]},"1854":{"position":[[950,10]]},"2987":{"position":[[950,10]]}}}],["administ",{"_index":11744,"t":{"4632":{"position":[[3083,13]]},"4634":{"position":[[207,13]]}}}],["administr",{"_index":732,"t":{"130":{"position":[[202,13],[530,13]]},"311":{"position":[[72,14]]},"354":{"position":[[236,13]]},"358":{"position":[[250,13]]},"816":{"position":[[245,14]]},"830":{"position":[[260,14]]},"832":{"position":[[72,13]]},"1250":{"position":[[121,14]]},"1468":{"position":[[205,14]]},"2184":{"position":[[93,13]]},"2196":{"position":[[1135,13]]},"2366":{"position":[[74,14]]},"2451":{"position":[[681,13]]},"2453":{"position":[[88,15]]},"2836":{"position":[[108,13],[334,13]]},"3470":{"position":[[170,15]]},"3627":{"position":[[527,14]]},"3947":{"position":[[1519,15]]},"3980":{"position":[[315,14]]},"3996":{"position":[[183,13]]},"4039":{"position":[[177,13]]},"4041":{"position":[[1225,14]]},"4043":{"position":[[725,14]]},"4045":{"position":[[283,14]]},"4217":{"position":[[264,14]]},"4222":{"position":[[327,14],[1165,14]]},"4224":{"position":[[2585,14]]},"4240":{"position":[[230,14]]},"4315":{"position":[[249,14]]},"4420":{"position":[[2780,14]]},"4525":{"position":[[418,13]]},"4535":{"position":[[270,14]]},"4539":{"position":[[7426,14]]},"4562":{"position":[[7047,14]]},"4593":{"position":[[523,14],[1737,14],[2717,14]]},"4612":{"position":[[389,15],[662,15],[924,15]]},"4614":{"position":[[993,14]]},"4623":{"position":[[594,14]]},"4839":{"position":[[719,15],[914,15]]},"4863":{"position":[[77,14],[129,14]]}}}],["administrators12",{"_index":11135,"t":{"4043":{"position":[[361,17]]}}}],["adminnetworkpolici",{"_index":11682,"t":{"4569":{"position":[[108,18],[711,19],[838,18]]},"4580":{"position":[[1646,18],[2089,18]]},"4582":{"position":[[204,18]]}}}],["admiss",{"_index":3047,"t":{"692":{"position":[[372,9]]},"747":{"position":[[291,9]]},"4479":{"position":[[1065,9],[1151,9],[1386,9]]},"4489":{"position":[[519,9]]},"4539":{"position":[[1239,9],[2570,9],[6544,9],[6567,9],[6869,9],[6946,9],[7308,9]]},"4543":{"position":[[1104,9],[1214,9]]},"4547":{"position":[[3382,9],[3787,9],[3939,9]]}}}],["admit",{"_index":10917,"t":{"3894":{"position":[[1415,5]]}}}],["admonit",{"_index":761,"t":{"139":{"position":[[21,10]]}}}],["admoniton",{"_index":766,"t":{"139":{"position":[[102,10]]}}}],["adopt",{"_index":760,"t":{"139":{"position":[[3,5]]},"173":{"position":[[1985,7],[2138,8]]},"800":{"position":[[106,5]]},"2489":{"position":[[1060,8]]},"2572":{"position":[[107,7],[452,8]]},"2914":{"position":[[1396,8]]},"3323":{"position":[[675,8]]},"3357":{"position":[[3803,8]]},"3516":{"position":[[296,6]]},"3567":{"position":[[101,7]]},"3968":{"position":[[2261,5],[2307,5]]},"3971":{"position":[[531,8],[638,9],[667,8]]},"3973":{"position":[[217,8],[280,5]]},"4146":{"position":[[331,8],[1840,5]]},"4148":{"position":[[104,8]]},"4226":{"position":[[751,7]]},"4228":{"position":[[337,9]]},"4242":{"position":[[27,8]]},"4257":{"position":[[1283,5],[3246,5]]},"4506":{"position":[[1250,8]]},"4522":{"position":[[499,9]]},"4560":{"position":[[1787,7],[2050,7],[3412,7]]},"4593":{"position":[[876,8]]}}}],["adr",{"_index":9858,"t":{"3206":{"position":[[504,4]]},"3554":{"position":[[135,6]]},"3558":{"position":[[258,4]]},"3938":{"position":[[130,3]]},"4724":{"position":[[724,4]]}}}],["adress",{"_index":5834,"t":{"1352":{"position":[[93,9]]}}}],["advanc",{"_index":1553,"t":{"207":{"position":[[672,7]]},"280":{"position":[[1200,8]]},"892":{"position":[[348,8]]},"1064":{"position":[[173,8]]},"1266":{"position":[[2505,8]]},"1297":{"position":[[70,8]]},"1457":{"position":[[1236,7]]},"1503":{"position":[[425,7]]},"1513":{"position":[[294,7]]},"1525":{"position":[[505,7]]},"1544":{"position":[[76,7]]},"1750":{"position":[[348,8]]},"2048":{"position":[[3747,7]]},"2094":{"position":[[288,8]]},"2155":{"position":[[295,7]]},"2196":{"position":[[1286,8]]},"2234":{"position":[[396,8]]},"2487":{"position":[[349,8]]},"2551":{"position":[[385,8]]},"3225":{"position":[[444,11]]},"3294":{"position":[[624,8]]},"3588":{"position":[[352,8]]},"3608":{"position":[[628,7]]},"3661":{"position":[[385,8]]},"3698":{"position":[[477,8]]},"3785":{"position":[[477,8]]},"4512":{"position":[[45,8]]},"4560":{"position":[[5307,8]]},"4829":{"position":[[413,8]]}}}],["advanced/rar",{"_index":6475,"t":{"1569":{"position":[[440,15]]},"1902":{"position":[[590,15]]}}}],["advancedformat",{"_index":9328,"t":{"2932":{"position":[[107,14]]}}}],["advantag",{"_index":963,"t":{"167":{"position":[[696,9]]},"171":{"position":[[544,11]]},"173":{"position":[[1186,9],[1475,10]]},"181":{"position":[[798,12],[1275,12],[1333,12]]},"741":{"position":[[187,9]]},"928":{"position":[[870,12]]},"1819":{"position":[[870,12]]},"2514":{"position":[[370,9]]},"2572":{"position":[[314,10]]},"2952":{"position":[[870,12]]},"3549":{"position":[[377,10]]},"3592":{"position":[[800,9]]},"3600":{"position":[[836,11]]},"3665":{"position":[[425,10]]},"3702":{"position":[[497,10]]},"3789":{"position":[[497,10]]},"3934":{"position":[[113,9]]},"3968":{"position":[[729,9],[1355,10]]},"4281":{"position":[[963,10]]},"4435":{"position":[[108,10]]},"4446":{"position":[[300,10]]},"4457":{"position":[[300,10]]},"4520":{"position":[[50,10]]},"4522":{"position":[[197,10]]},"4797":{"position":[[246,9]]},"4859":{"position":[[174,9]]}}}],["advert",{"_index":10846,"t":{"3829":{"position":[[4208,10]]}}}],["advertis",{"_index":1528,"t":{"205":{"position":[[249,11],[272,11],[357,11],[406,13]]},"209":{"position":[[119,11]]},"228":{"position":[[189,11]]},"241":{"position":[[50,9]]},"321":{"position":[[77,9]]},"3361":{"position":[[485,9]]},"3894":{"position":[[1503,11]]},"3928":{"position":[[5711,10]]},"3930":{"position":[[447,10]]},"4009":{"position":[[225,11]]},"4185":{"position":[[911,9]]},"4189":{"position":[[520,9]]},"4191":{"position":[[181,9]]}}}],["advic",{"_index":11393,"t":{"4251":{"position":[[379,7]]},"4362":{"position":[[452,6]]}}}],["advis",{"_index":1146,"t":{"173":{"position":[[1517,7]]},"284":{"position":[[368,7]]},"1028":{"position":[[315,9]]},"1105":{"position":[[316,9]]},"1161":{"position":[[114,7]]},"1346":{"position":[[6,9]]},"1383":{"position":[[436,9]]},"1387":{"position":[[126,7]]},"1393":{"position":[[114,7]]},"1484":{"position":[[126,7]]},"1569":{"position":[[111,7],[494,7]]},"1571":{"position":[[169,7]]},"1902":{"position":[[322,7],[644,7]]},"1904":{"position":[[169,7]]},"1979":{"position":[[126,7]]},"2137":{"position":[[116,7]]},"2148":{"position":[[126,7]]},"2211":{"position":[[427,9]]},"2283":{"position":[[860,9]]},"2297":{"position":[[860,9]]},"2329":{"position":[[418,7]]},"2396":{"position":[[418,7]]},"3829":{"position":[[2133,6]]},"4257":{"position":[[1593,8],[2934,10],[3602,6],[3669,6],[4527,6],[5841,7]]},"4304":{"position":[[1875,7]]},"4340":{"position":[[781,10]]},"4351":{"position":[[518,10]]},"4533":{"position":[[205,7]]},"4535":{"position":[[1165,7]]}}}],["advisori",{"_index":9739,"t":{"3099":{"position":[[151,8]]},"3164":{"position":[[80,10],[136,8],[214,9],[244,8],[337,9]]},"3202":{"position":[[80,10],[133,8],[195,9],[220,8],[302,9]]},"3246":{"position":[[91,10]]},"3306":{"position":[[91,10],[261,8],[356,8],[449,8]]},"4109":{"position":[[3786,11]]},"4251":{"position":[[346,10]]}}}],["advoc",{"_index":1484,"t":{"199":{"position":[[1924,10]]}}}],["ae",{"_index":8379,"t":{"2347":{"position":[[248,3]]},"2414":{"position":[[248,3]]}}}],["ae9c",{"_index":8003,"t":{"2207":{"position":[[696,4],[875,4],[926,4]]}}}],["aeb4",{"_index":5145,"t":{"1236":{"position":[[606,4],[738,4]]}}}],["af82",{"_index":11092,"t":{"3990":{"position":[[2210,4]]}}}],["afda9dfe8ec3",{"_index":2750,"t":{"557":{"position":[[1976,13]]}}}],["afdb",{"_index":8191,"t":{"2252":{"position":[[2071,4]]}}}],["afdeeb1802dc",{"_index":8214,"t":{"2254":{"position":[[387,12],[739,12],[1299,12],[1483,12]]},"2256":{"position":[[93,12]]}}}],["aff",{"_index":6538,"t":{"1605":{"position":[[87,3],[880,3],[1523,3]]},"2207":{"position":[[1385,3]]}}}],["affair",{"_index":9867,"t":{"3214":{"position":[[255,7]]}}}],["affect",{"_index":1407,"t":{"197":{"position":[[1401,6]]},"284":{"position":[[103,7],[334,6]]},"345":{"position":[[24,8]]},"551":{"position":[[3089,8]]},"963":{"position":[[3944,6]]},"967":{"position":[[334,6]]},"978":{"position":[[610,8]]},"1354":{"position":[[104,6]]},"1854":{"position":[[3944,6]]},"1858":{"position":[[334,6]]},"1869":{"position":[[610,8]]},"2814":{"position":[[140,10],[526,7],[761,7],[883,7],[950,8]]},"2987":{"position":[[3944,6]]},"2991":{"position":[[334,6]]},"3002":{"position":[[610,8]]},"3202":{"position":[[229,9]]},"3302":{"position":[[70,6]]},"3608":{"position":[[552,6]]},"3829":{"position":[[2308,6],[2893,7]]},"3928":{"position":[[737,8],[1150,9],[4388,8]]},"4107":{"position":[[2211,9]]},"4109":{"position":[[1752,8],[1820,8],[1895,8],[1968,8],[3261,6],[4430,8],[4524,8],[5154,6]]},"4113":{"position":[[55,8],[1627,9],[1661,8]]},"4133":{"position":[[1031,8],[1094,8],[1169,8],[1242,8],[1630,8],[1724,8],[1949,8]]},"4163":{"position":[[2376,6],[2727,8],[3879,6],[4113,6],[5115,8]]},"4259":{"position":[[19,8],[394,8],[652,8]]},"4270":{"position":[[493,9],[818,8],[1034,8]]},"4539":{"position":[[1035,8]]},"4699":{"position":[[198,8]]},"4705":{"position":[[87,8],[138,6]]},"4709":{"position":[[46,8]]}}}],["affects\":[{\"reference\":\"3ebed33a",{"_index":9134,"t":{"2784":{"position":[[109,35]]}}}],["affero",{"_index":1042,"t":{"169":{"position":[[959,6]]},"175":{"position":[[466,6],[731,6]]},"249":{"position":[[1498,6]]}}}],["affin",{"_index":6139,"t":{"1433":{"position":[[358,8]]},"3083":{"position":[[392,8]]},"3468":{"position":[[1033,8]]},"4431":{"position":[[400,8],[417,8],[494,8],[512,8],[861,8],[883,8],[896,8],[917,8],[1166,10],[1194,9],[1310,8],[1431,11],[1459,9],[1599,8],[2053,8],[2259,8]]},"4433":{"position":[[33,8],[98,8],[142,8],[445,8],[1142,9],[1370,8],[1669,8],[2549,8],[2861,8]]},"4435":{"position":[[142,8],[1437,8]]},"4437":{"position":[[91,8],[109,8]]},"4446":{"position":[[112,8]]},"4448":{"position":[[1111,8]]},"4457":{"position":[[112,8]]},"4826":{"position":[[3025,8]]}}}],["afford",{"_index":10945,"t":{"3928":{"position":[[2585,8]]}}}],["aforement",{"_index":11506,"t":{"4407":{"position":[[306,14]]},"4489":{"position":[[997,14]]},"4535":{"position":[[206,14]]}}}],["afraid",{"_index":1295,"t":{"181":{"position":[[2210,6]]}}}],["after_al",{"_index":8980,"t":{"2716":{"position":[[486,9],[648,9]]}}}],["after_featur",{"_index":8979,"t":{"2716":{"position":[[446,13],[773,13]]}}}],["afterward",{"_index":3480,"t":{"887":{"position":[[1414,10]]},"999":{"position":[[274,11]]},"1230":{"position":[[1047,10],[1213,10]]},"1433":{"position":[[1281,11]]},"1811":{"position":[[1414,10]]},"1890":{"position":[[274,11]]},"2163":{"position":[[3424,11]]},"2165":{"position":[[1157,10]]},"2184":{"position":[[4390,10]]},"2287":{"position":[[1291,11]]},"2289":{"position":[[189,11]]},"2301":{"position":[[1291,11]]},"2303":{"position":[[189,11]]},"2873":{"position":[[352,10]]},"2934":{"position":[[125,10],[832,11]]},"3731":{"position":[[1397,11]]},"4268":{"position":[[650,10]]},"4270":{"position":[[734,10]]}}}],["ag",{"_index":1442,"t":{"199":{"position":[[680,4]]},"434":{"position":[[1002,3],[1208,3]]},"493":{"position":[[650,3],[856,3],[984,3]]},"590":{"position":[[88,3]]},"692":{"position":[[243,3]]},"747":{"position":[[162,3]]},"1346":{"position":[[535,3]]},"4485":{"position":[[2622,3]]}}}],["ag/wavecon",{"_index":10050,"t":{"3367":{"position":[[1194,10]]}}}],["again",{"_index":1628,"t":{"224":{"position":[[407,6]]},"228":{"position":[[140,6],[313,5]]},"237":{"position":[[137,5]]},"239":{"position":[[78,6]]},"241":{"position":[[60,6]]},"243":{"position":[[56,5]]},"417":{"position":[[773,6],[1742,6],[1987,6]]},"434":{"position":[[502,6]]},"491":{"position":[[168,6]]},"508":{"position":[[456,6]]},"706":{"position":[[835,6]]},"924":{"position":[[313,5],[1208,5]]},"944":{"position":[[301,6],[1049,6],[1292,5]]},"978":{"position":[[1482,6],[2026,6]]},"1175":{"position":[[4428,5]]},"1257":{"position":[[1493,5]]},"1466":{"position":[[510,8]]},"1544":{"position":[[280,6]]},"1648":{"position":[[939,6],[1542,5]]},"1688":{"position":[[288,6]]},"1815":{"position":[[313,5],[1208,5]]},"1835":{"position":[[301,6],[1049,6],[1292,5]]},"1869":{"position":[[1482,6],[2026,6]]},"2032":{"position":[[1006,5],[1464,6]]},"2034":{"position":[[1551,6]]},"2059":{"position":[[2299,5]]},"2171":{"position":[[1633,5],[2717,6]]},"2184":{"position":[[2947,6]]},"2270":{"position":[[678,6]]},"2355":{"position":[[1445,5],[3121,5]]},"2360":{"position":[[1812,6]]},"2422":{"position":[[1445,5],[3121,5]]},"2427":{"position":[[1812,6]]},"2948":{"position":[[313,5],[1208,5]]},"2968":{"position":[[301,6],[1049,6],[1292,5]]},"3002":{"position":[[1482,6],[2026,6]]},"3026":{"position":[[102,6]]},"3200":{"position":[[71,5]]},"3204":{"position":[[262,5]]},"3244":{"position":[[75,6]]},"3276":{"position":[[402,5]]},"3381":{"position":[[1299,6]]},"3592":{"position":[[2272,5]]},"3731":{"position":[[885,5]]},"3947":{"position":[[2789,5]]},"3960":{"position":[[472,6]]},"4104":{"position":[[360,5]]},"4422":{"position":[[504,5]]},"4665":{"position":[[136,5]]}}}],["against",{"_index":137,"t":{"19":{"position":[[148,7]]},"119":{"position":[[17,7]]},"153":{"position":[[267,7]]},"177":{"position":[[1419,7]]},"179":{"position":[[1114,7],[1436,7]]},"181":{"position":[[1517,7]]},"199":{"position":[[1385,7]]},"201":{"position":[[736,7]]},"266":{"position":[[198,7]]},"284":{"position":[[396,7]]},"301":{"position":[[292,7]]},"345":{"position":[[60,7]]},"526":{"position":[[172,7],[921,7]]},"530":{"position":[[70,7]]},"928":{"position":[[437,7]]},"946":{"position":[[351,7]]},"967":{"position":[[208,7]]},"978":{"position":[[1749,7],[1837,7],[2276,7]]},"980":{"position":[[943,7]]},"1466":{"position":[[1578,7]]},"1819":{"position":[[437,7]]},"1837":{"position":[[351,7]]},"1858":{"position":[[208,7]]},"1869":{"position":[[1749,7],[1837,7],[2276,7]]},"1871":{"position":[[943,7]]},"2276":{"position":[[159,7]]},"2478":{"position":[[816,7]]},"2506":{"position":[[635,7]]},"2535":{"position":[[314,7]]},"2537":{"position":[[204,7]]},"2701":{"position":[[78,7]]},"2758":{"position":[[73,7],[123,7]]},"2952":{"position":[[437,7]]},"2970":{"position":[[351,7]]},"2991":{"position":[[208,7]]},"3002":{"position":[[1749,7],[1837,7],[2276,7]]},"3004":{"position":[[943,7]]},"3119":{"position":[[842,7]]},"3230":{"position":[[642,7],[709,7],[769,7]]},"3246":{"position":[[312,7]]},"3367":{"position":[[57,7]]},"3373":{"position":[[57,7]]},"3474":{"position":[[311,7]]},"3533":{"position":[[116,7],[2090,7]]},"3575":{"position":[[572,7]]},"3590":{"position":[[163,7]]},"3606":{"position":[[632,8],[722,8],[900,8],[998,8],[1168,8],[1303,7]]},"3661":{"position":[[571,7],[1499,7]]},"3698":{"position":[[678,7],[2153,7]]},"3722":{"position":[[993,7]]},"3785":{"position":[[678,7],[1851,7]]},"3815":{"position":[[991,7]]},"3928":{"position":[[3102,7]]},"4045":{"position":[[998,7]]},"4159":{"position":[[1045,7]]},"4224":{"position":[[1862,7]]},"4337":{"position":[[550,7]]},"4365":{"position":[[92,7]]},"4376":{"position":[[341,7]]},"4385":{"position":[[206,7]]},"4401":{"position":[[71,7]]},"4420":{"position":[[78,7],[380,8]]},"4435":{"position":[[247,7]]},"4471":{"position":[[478,7]]},"4479":{"position":[[1682,7]]},"4489":{"position":[[116,7]]},"4535":{"position":[[1127,7]]},"4539":{"position":[[30,7],[1907,7],[3125,8],[4632,7],[5187,7],[5956,7]]},"4541":{"position":[[1715,7]]},"4562":{"position":[[5645,8]]},"4744":{"position":[[450,7]]}}}],["agenda",{"_index":1680,"t":{"239":{"position":[[36,7]]}}}],["agent",{"_index":3117,"t":{"705":{"position":[[1768,5]]},"738":{"position":[[700,5]]},"822":{"position":[[156,7]]},"824":{"position":[[165,5]]},"846":{"position":[[1006,6]]},"1472":{"position":[[3282,5]]},"1673":{"position":[[260,5],[375,5]]},"1713":{"position":[[1613,5],[1782,5],[2040,5],[2089,5],[2121,5],[2342,5],[2429,5]]},"2007":{"position":[[71,6],[109,5],[148,5],[186,5]]},"2150":{"position":[[314,6],[337,5]]},"2608":{"position":[[996,8]]},"2632":{"position":[[145,5]]},"4220":{"position":[[1964,5]]},"4226":{"position":[[926,5],[969,5],[1469,6]]},"4228":{"position":[[1746,5],[1790,6]]},"4240":{"position":[[162,5]]},"4541":{"position":[[24,5]]},"4728":{"position":[[761,5],[792,5]]},"4730":{"position":[[1541,6]]}}}],["agent..svc",{"_index":8828,"t":{"2663":{"position":[[356,22]]}}}],["agent.conf",{"_index":6819,"t":{"1694":{"position":[[3715,10]]}}}],["agent/bin/rubi",{"_index":6725,"t":{"1673":{"position":[[232,14],[323,14]]}}}],["agent:22.0.3.20230919",{"_index":7114,"t":{"1711":{"position":[[1597,21]]}}}],["agent@testb",{"_index":6715,"t":{"1673":{"position":[[102,13]]}}}],["agent_host",{"_index":8827,"t":{"2663":{"position":[[334,13]]}}}],["agent_port",{"_index":8829,"t":{"2663":{"position":[[379,13]]}}}],["aggreg",{"_index":2629,"t":{"541":{"position":[[1132,10]]},"816":{"position":[[5,10],[136,10],[283,10],[329,9],[529,10],[577,9],[726,10],[1096,10]]},"1038":{"position":[[282,10]]},"1694":{"position":[[7187,9]]},"1740":{"position":[[5,10],[106,11],[145,10],[321,10],[467,9]]},"2632":{"position":[[340,11]]},"3073":{"position":[[345,11]]},"3352":{"position":[[3321,11]]},"3706":{"position":[[1180,11],[1556,12],[1636,10]]},"3799":{"position":[[1180,11],[1553,12],[1633,10]]},"3932":{"position":[[134,10]]},"4275":{"position":[[270,10],[424,11]]},"4791":{"position":[[436,9]]}}}],["aggregate1",{"_index":7230,"t":{"1740":{"position":[[398,10]]}}}],["aggregates.yml",{"_index":7227,"t":{"1740":{"position":[[282,14]]}}}],["aggress",{"_index":6209,"t":{"1455":{"position":[[1095,10]]}}}],["agil",{"_index":2252,"t":{"370":{"position":[[575,5]]},"3973":{"position":[[262,5]]}}}],["agnost",{"_index":11828,"t":{"4733":{"position":[[389,8]]}}}],["ago",{"_index":7061,"t":{"1704":{"position":[[1780,4],[2058,3],[2121,3],[2459,4],[2737,3],[2800,3]]},"1711":{"position":[[1264,3],[1392,3],[1517,3],[1650,3],[1795,3],[1940,3],[2077,3],[2210,3],[2339,3],[2463,3],[2604,3],[2712,3],[2842,3],[2950,3],[3060,3]]},"2155":{"position":[[1212,3],[1345,3],[1457,3],[1619,3],[1743,3],[1870,3],[1991,3],[2155,3],[2280,3],[2415,3],[2551,3],[2678,3],[2813,3],[2947,3],[3080,3],[3195,3]]},"4560":{"position":[[4266,4]]}}}],["agpl",{"_index":1058,"t":{"171":{"position":[[244,6],[1350,5]]},"175":{"position":[[477,6],[677,4]]},"177":{"position":[[681,5]]},"181":{"position":[[2224,5]]}}}],["agpl'",{"_index":1288,"t":{"181":{"position":[[1933,7]]}}}],["agplv3",{"_index":1043,"t":{"169":{"position":[[999,8]]},"175":{"position":[[853,7]]},"249":{"position":[[2133,7]]}}}],["agre",{"_index":1272,"t":{"181":{"position":[[763,6]]},"199":{"position":[[2090,5]]},"207":{"position":[[144,5]]},"249":{"position":[[946,5]]},"2431":{"position":[[203,5]]},"2914":{"position":[[1297,8]]},"3071":{"position":[[552,6]]}}}],["agreement",{"_index":1273,"t":{"181":{"position":[[879,10]]},"185":{"position":[[453,11]]},"251":{"position":[[123,11]]},"3835":{"position":[[198,10]]}}}],["ah",{"_index":11349,"t":{"4226":{"position":[[2976,4]]}}}],["ah00558",{"_index":6892,"t":{"1696":{"position":[[420,8]]}}}],["ahci",{"_index":7287,"t":{"2021":{"position":[[22,4]]}}}],["ahead",{"_index":10199,"t":{"3539":{"position":[[125,5]]},"3928":{"position":[[3577,5]]}}}],["aicard",{"_index":8258,"t":{"2258":{"position":[[306,7]]}}}],["aid",{"_index":10163,"t":{"3516":{"position":[[165,3]]}}}],["aim",{"_index":508,"t":{"70":{"position":[[298,3]]},"72":{"position":[[323,3]]},"107":{"position":[[33,3]]},"109":{"position":[[0,3]]},"165":{"position":[[4,3]]},"187":{"position":[[142,3]]},"280":{"position":[[102,5]]},"297":{"position":[[175,3]]},"425":{"position":[[264,3],[358,3]]},"520":{"position":[[852,4]]},"545":{"position":[[987,5]]},"696":{"position":[[10,4],[529,3]]},"728":{"position":[[10,4]]},"755":{"position":[[10,4]]},"2439":{"position":[[428,6]]},"2608":{"position":[[273,3]]},"2618":{"position":[[16,4]]},"2690":{"position":[[31,4]]},"2712":{"position":[[1206,3]]},"3234":{"position":[[70,6]]},"3259":{"position":[[573,3]]},"3344":{"position":[[12,3]]},"3386":{"position":[[646,3]]},"3402":{"position":[[299,4]]},"3468":{"position":[[185,3]]},"3470":{"position":[[266,6]]},"3502":{"position":[[261,6]]},"3561":{"position":[[325,4]]},"3571":{"position":[[1297,3]]},"3582":{"position":[[1845,3]]},"3592":{"position":[[1450,3]]},"4073":{"position":[[528,4]]},"4079":{"position":[[43,3]]},"4081":{"position":[[1045,3]]},"4094":{"position":[[739,4]]},"4120":{"position":[[509,4]]},"4142":{"position":[[193,4]]},"4157":{"position":[[620,4]]},"4224":{"position":[[334,4],[3005,3]]},"4226":{"position":[[3225,4]]},"4228":{"position":[[43,5]]},"4291":{"position":[[878,3]]},"4479":{"position":[[1179,4]]},"4502":{"position":[[477,3]]},"4520":{"position":[[709,3]]},"4562":{"position":[[1969,3]]},"4627":{"position":[[106,4]]},"4730":{"position":[[1436,4]]},"4791":{"position":[[375,4]]}}}],["air",{"_index":5808,"t":{"1344":{"position":[[250,3]]},"3189":{"position":[[697,3]]},"4660":{"position":[[1323,3]]}}}],["airgap",{"_index":9785,"t":{"3153":{"position":[[531,9],[591,6]]}}}],["aj6iosqsowhqn_nnbeog",{"_index":6467,"t":{"1564":{"position":[[481,20]]}}}],["ajax",{"_index":8609,"t":{"2557":{"position":[[351,4]]}}}],["aka",{"_index":7029,"t":{"1704":{"position":[[602,4],[702,4],[798,4],[894,4]]},"4587":{"position":[[1182,4]]}}}],["akafazov",{"_index":303,"t":{"28":{"position":[[3043,8],[3052,8],[3061,8]]}}}],["alarm",{"_index":3753,"t":{"928":{"position":[[967,6]]},"942":{"position":[[527,6]]},"978":{"position":[[193,5]]},"1819":{"position":[[967,6]]},"1833":{"position":[[527,6]]},"1869":{"position":[[193,5]]},"2146":{"position":[[451,6]]},"2952":{"position":[[967,6]]},"2966":{"position":[[527,6]]},"3002":{"position":[[193,5]]},"3022":{"position":[[1295,8]]},"3036":{"position":[[14430,9]]},"4481":{"position":[[419,6]]}}}],["alarm_email_address",{"_index":3918,"t":{"942":{"position":[[2831,19]]},"949":{"position":[[971,21]]},"1833":{"position":[[2831,19]]},"1840":{"position":[[971,21]]},"2966":{"position":[[2831,19]]},"2973":{"position":[[971,21]]}}}],["alasca",{"_index":10644,"t":{"3724":{"position":[[181,6]]},"3817":{"position":[[181,6]]}}}],["albeit",{"_index":10782,"t":{"3759":{"position":[[34,6]]},"4146":{"position":[[2103,6]]},"4744":{"position":[[655,6]]}}}],["alert",{"_index":3917,"t":{"942":{"position":[[2817,8]]},"1833":{"position":[[2817,8]]},"2478":{"position":[[2772,5]]},"2512":{"position":[[993,8]]},"2604":{"position":[[206,6]]},"2626":{"position":[[2340,6]]},"2647":{"position":[[23,7],[177,6]]},"2649":{"position":[[365,7],[396,7],[1133,6],[1215,7],[1300,7]]},"2966":{"position":[[2817,8]]},"3050":{"position":[[317,6]]},"3502":{"position":[[218,7]]},"4722":{"position":[[834,8]]},"4726":{"position":[[877,8]]},"4728":{"position":[[1383,8],[1432,6],[1451,6],[1527,6]]},"4730":{"position":[[1548,6],[1611,6],[2433,6]]},"4733":{"position":[[1394,6],[1476,6],[1495,6],[1519,5]]}}}],["alertmanag",{"_index":8702,"t":{"2604":{"position":[[53,12],[161,12],[301,12],[397,12],[581,12],[627,12]]},"2616":{"position":[[66,12],[412,12]]},"2628":{"position":[[709,12],[816,13],[853,12]]},"2636":{"position":[[306,12]]},"2659":{"position":[[66,12],[408,12]]},"4724":{"position":[[144,12]]},"4728":{"position":[[197,13]]},"4730":{"position":[[1282,12]]}}}],["alertmanager/matrix",{"_index":8704,"t":{"2604":{"position":[[281,19],[377,19]]}}}],["alertmanagerspec",{"_index":8773,"t":{"2628":{"position":[[830,16]]}}}],["alertmgr",{"_index":9992,"t":{"3357":{"position":[[236,9]]}}}],["algorithm",{"_index":1958,"t":{"301":{"position":[[167,11]]},"305":{"position":[[1347,9]]},"2341":{"position":[[676,9]]},"2347":{"position":[[238,9],[371,10]]},"2408":{"position":[[676,9]]},"2414":{"position":[[238,9],[371,10]]},"3761":{"position":[[1252,9]]},"4306":{"position":[[112,11]]}}}],["alia",{"_index":6768,"t":{"1694":{"position":[[183,5]]},"2431":{"position":[[1095,5],[1231,6]]},"4643":{"position":[[2851,7]]}}}],["alias",{"_index":5950,"t":{"1391":{"position":[[1281,7]]},"3724":{"position":[[269,7]]},"3817":{"position":[[269,7]]}}}],["alic",{"_index":7938,"t":{"2194":{"position":[[872,5]]},"2196":{"position":[[378,5],[505,6],[1900,5],[2304,5],[3109,5]]},"2433":{"position":[[1285,6]]}}}],["align",{"_index":565,"t":{"78":{"position":[[47,5],[251,5],[352,5]]},"197":{"position":[[426,5]]},"280":{"position":[[249,8],[1218,6]]},"286":{"position":[[316,9]]},"288":{"position":[[774,6]]},"551":{"position":[[1375,5]]},"890":{"position":[[155,9]]},"1748":{"position":[[155,9]]},"2347":{"position":[[524,5]]},"2380":{"position":[[140,10],[544,7]]},"2414":{"position":[[524,5]]},"2489":{"position":[[418,6]]},"2499":{"position":[[585,9]]},"2520":{"position":[[725,10]]},"3313":{"position":[[463,7]]},"3321":{"position":[[440,9]]},"3623":{"position":[[209,10]]},"3627":{"position":[[694,9]]},"3724":{"position":[[212,10]]},"3817":{"position":[[212,10]]},"4146":{"position":[[803,8]]},"4165":{"position":[[194,5]]},"4522":{"position":[[1622,6]]},"4632":{"position":[[48,5]]},"4667":{"position":[[352,5]]}}}],["alik",{"_index":458,"t":{"59":{"position":[[103,6]]},"3980":{"position":[[249,6]]}}}],["aliquam",{"_index":16,"t":{"3":{"position":[[133,7]]}}}],["aliv",{"_index":3742,"t":{"924":{"position":[[2221,5]]},"940":{"position":[[584,5]]},"1713":{"position":[[1822,5]]},"1815":{"position":[[2221,5]]},"1831":{"position":[[584,5]]},"2948":{"position":[[2221,5]]},"2964":{"position":[[584,5]]},"3928":{"position":[[1059,5]]},"4742":{"position":[[721,5]]}}}],["all.yml.j2",{"_index":6179,"t":{"1443":{"position":[[1053,10]]}}}],["all:!manag",{"_index":6232,"t":{"1457":{"position":[[3087,14],[3904,14]]}}}],["allevi",{"_index":9691,"t":{"3062":{"position":[[171,11]]}}}],["allianc",{"_index":3260,"t":{"776":{"position":[[78,8]]},"3214":{"position":[[147,8]]},"3623":{"position":[[173,9]]},"3731":{"position":[[1805,8],[1911,8]]}}}],["alloc",{"_index":4438,"t":{"1067":{"position":[[1360,10]]},"1301":{"position":[[1486,10]]},"1383":{"position":[[371,10],[1771,10]]},"2503":{"position":[[112,8]]},"3665":{"position":[[718,8],[838,10]]},"3677":{"position":[[1131,8],[1388,9]]},"3702":{"position":[[931,8],[1051,10]]},"3789":{"position":[[790,8],[910,10]]},"3791":{"position":[[1154,8],[1410,9]]},"3904":{"position":[[683,8],[941,9]]},"3930":{"position":[[1128,9]]},"4738":{"position":[[307,10],[701,10],[756,10]]},"4757":{"position":[[373,10]]}}}],["allocation_pool_end",{"_index":7413,"t":{"2048":{"position":[[3324,20]]}}}],["allocation_pool_start",{"_index":7411,"t":{"2048":{"position":[[3286,22]]}}}],["alloct",{"_index":3618,"t":{"912":{"position":[[163,9]]},"1796":{"position":[[163,9]]}}}],["allong",{"_index":8969,"t":{"2714":{"position":[[894,7]]}}}],["allow",{"_index":844,"t":{"147":{"position":[[49,7]]},"163":{"position":[[25,7]]},"173":{"position":[[683,8],[2121,5]]},"177":{"position":[[1376,5]]},"181":{"position":[[1166,6]]},"199":{"position":[[2245,5]]},"201":{"position":[[489,5],[809,5]]},"214":{"position":[[111,7]]},"224":{"position":[[758,5]]},"293":{"position":[[705,5]]},"303":{"position":[[622,5]]},"319":{"position":[[43,5]]},"374":{"position":[[109,6]]},"384":{"position":[[88,5]]},"427":{"position":[[427,5]]},"533":{"position":[[555,6]]},"543":{"position":[[1288,6],[2633,8]]},"547":{"position":[[203,6]]},"549":{"position":[[562,6]]},"551":{"position":[[3138,6]]},"557":{"position":[[5040,6],[6901,8]]},"604":{"position":[[429,6]]},"606":{"position":[[99,6]]},"608":{"position":[[83,6]]},"645":{"position":[[38,6]]},"668":{"position":[[737,6]]},"677":{"position":[[38,6]]},"705":{"position":[[1006,5]]},"739":{"position":[[1823,5]]},"741":{"position":[[431,5]]},"814":{"position":[[169,6]]},"818":{"position":[[357,6]]},"846":{"position":[[457,6]]},"848":{"position":[[203,6]]},"932":{"position":[[902,6]]},"936":{"position":[[492,5]]},"938":{"position":[[584,6],[2133,6]]},"949":{"position":[[558,8],[814,6]]},"961":{"position":[[805,5]]},"963":{"position":[[4315,5],[4435,6]]},"1038":{"position":[[20,6]]},"1056":{"position":[[186,6],[582,6],[1539,6],[2272,6]]},"1064":{"position":[[1337,6],[2009,6],[2419,6]]},"1067":{"position":[[254,6],[892,6]]},"1155":{"position":[[106,6]]},"1189":{"position":[[691,5]]},"1266":{"position":[[2481,5]]},"1301":{"position":[[1956,5],[3185,6]]},"1324":{"position":[[6336,5],[7330,5],[8100,5],[9074,5],[10719,5]]},"1348":{"position":[[5,6]]},"1350":{"position":[[5,6]]},"1377":{"position":[[216,5]]},"1385":{"position":[[1345,5]]},"1391":{"position":[[91,6],[449,6],[3155,8]]},"1667":{"position":[[54,6]]},"1677":{"position":[[50,6]]},"1720":{"position":[[107,6]]},"1823":{"position":[[902,6]]},"1827":{"position":[[492,5]]},"1829":{"position":[[584,6],[2133,6]]},"1840":{"position":[[558,8],[814,6]]},"1852":{"position":[[805,5]]},"1854":{"position":[[4315,5],[4435,6]]},"1986":{"position":[[102,6]]},"1988":{"position":[[158,6]]},"2084":{"position":[[49,7]]},"2119":{"position":[[211,6]]},"2150":{"position":[[391,8],[445,6]]},"2165":{"position":[[790,6]]},"2261":{"position":[[300,6]]},"2283":{"position":[[141,8],[234,5]]},"2285":{"position":[[159,5],[770,6]]},"2287":{"position":[[360,5],[1186,8]]},"2293":{"position":[[317,5],[493,6],[661,6],[833,6],[1009,6]]},"2297":{"position":[[141,8],[234,5]]},"2299":{"position":[[159,5],[770,6]]},"2301":{"position":[[360,5],[1186,8]]},"2307":{"position":[[317,5],[493,6],[661,6],[833,6],[1009,6]]},"2335":{"position":[[289,5]]},"2368":{"position":[[105,6]]},"2382":{"position":[[250,5]]},"2402":{"position":[[289,5]]},"2429":{"position":[[231,5],[449,5]]},"2447":{"position":[[180,6],[645,5]]},"2473":{"position":[[170,6]]},"2478":{"position":[[1651,8]]},"2503":{"position":[[74,8]]},"2514":{"position":[[155,6]]},"2520":{"position":[[670,8]]},"2529":{"position":[[1212,8]]},"2537":{"position":[[550,8]]},"2549":{"position":[[484,6]]},"2553":{"position":[[302,6]]},"2559":{"position":[[152,8],[619,6]]},"2598":{"position":[[152,8],[619,6]]},"2714":{"position":[[331,5],[582,6]]},"2720":{"position":[[879,7],[903,7]]},"2723":{"position":[[147,6]]},"2756":{"position":[[1248,6]]},"2822":{"position":[[14,7]]},"2839":{"position":[[70,6]]},"2853":{"position":[[0,5],[213,5],[245,5],[287,5],[333,5],[357,5]]},"2918":{"position":[[181,5]]},"2932":{"position":[[202,6]]},"2940":{"position":[[250,8]]},"2956":{"position":[[902,6]]},"2960":{"position":[[492,5]]},"2962":{"position":[[584,6],[2133,6]]},"2973":{"position":[[558,8],[814,6]]},"2985":{"position":[[805,5]]},"2987":{"position":[[4315,5],[4435,6]]},"3014":{"position":[[146,5]]},"3030":{"position":[[110,5]]},"3032":{"position":[[80,6]]},"3088":{"position":[[25,5],[732,6]]},"3091":{"position":[[425,8]]},"3121":{"position":[[964,8],[1231,6]]},"3153":{"position":[[521,5],[1239,5],[1412,6],[1477,6]]},"3187":{"position":[[378,5]]},"3234":{"position":[[80,5]]},"3292":{"position":[[605,6]]},"3294":{"position":[[545,5]]},"3298":{"position":[[231,5]]},"3323":{"position":[[366,6]]},"3352":{"position":[[861,6]]},"3355":{"position":[[311,6]]},"3378":{"position":[[35,6]]},"3406":{"position":[[388,6]]},"3414":{"position":[[293,8]]},"3527":{"position":[[240,5],[272,8]]},"3573":{"position":[[465,6]]},"3588":{"position":[[262,6]]},"3596":{"position":[[291,8]]},"3613":{"position":[[19,6]]},"3663":{"position":[[105,7]]},"3665":{"position":[[363,5]]},"3669":{"position":[[764,7]]},"3677":{"position":[[629,6],[819,6]]},"3679":{"position":[[165,6],[272,7]]},"3681":{"position":[[282,5],[857,5],[1192,5]]},"3693":{"position":[[674,6],[755,6]]},"3700":{"position":[[99,7]]},"3702":{"position":[[435,5]]},"3704":{"position":[[346,7]]},"3706":{"position":[[1507,5]]},"3710":{"position":[[819,7]]},"3712":{"position":[[1421,6]]},"3714":{"position":[[1530,6]]},"3718":{"position":[[282,5],[896,5],[1219,5]]},"3722":{"position":[[455,5]]},"3768":{"position":[[148,7]]},"3780":{"position":[[674,6],[755,6]]},"3787":{"position":[[99,7]]},"3789":{"position":[[435,5]]},"3791":{"position":[[651,6],[841,6]]},"3793":{"position":[[165,6],[272,7]]},"3799":{"position":[[1504,5]]},"3803":{"position":[[806,7]]},"3811":{"position":[[282,5],[896,5],[1196,5]]},"3815":{"position":[[319,5]]},"3820":{"position":[[154,5]]},"3868":{"position":[[32,7]]},"3876":{"position":[[802,9]]},"3904":{"position":[[123,6],[244,6]]},"3923":{"position":[[241,6]]},"3928":{"position":[[5638,6]]},"3936":{"position":[[649,5]]},"3968":{"position":[[481,5]]},"3973":{"position":[[246,5],[334,8]]},"3982":{"position":[[487,5]]},"3992":{"position":[[263,7]]},"4037":{"position":[[149,8]]},"4045":{"position":[[701,5],[803,8],[1785,5],[1852,8]]},"4047":{"position":[[638,5]]},"4049":{"position":[[72,5],[191,5],[339,5],[514,5]]},"4051":{"position":[[95,7]]},"4055":{"position":[[201,7]]},"4081":{"position":[[2275,7]]},"4083":{"position":[[25,5]]},"4111":{"position":[[102,5]]},"4142":{"position":[[256,8]]},"4146":{"position":[[567,6]]},"4148":{"position":[[568,5]]},"4159":{"position":[[1907,7]]},"4163":{"position":[[5808,5]]},"4165":{"position":[[405,5],[528,8],[1056,5]]},"4226":{"position":[[991,6],[1682,6],[3708,7]]},"4228":{"position":[[362,7]]},"4238":{"position":[[339,5],[506,5]]},"4251":{"position":[[151,6]]},"4257":{"position":[[5,5],[1493,5],[2074,8],[2710,8],[3534,8],[4091,8]]},"4273":{"position":[[446,6]]},"4279":{"position":[[758,6]]},"4289":{"position":[[216,6]]},"4304":{"position":[[309,6]]},"4310":{"position":[[848,6],[2473,8]]},"4420":{"position":[[1625,6]]},"4431":{"position":[[529,6],[699,5],[926,6],[1346,5],[1614,5],[1731,5]]},"4485":{"position":[[2528,6]]},"4506":{"position":[[1443,5]]},"4508":{"position":[[150,6],[486,8],[557,5]]},"4518":{"position":[[85,6]]},"4535":{"position":[[3042,8]]},"4539":{"position":[[806,5],[907,7],[2758,5],[4671,6],[4928,6],[7053,7]]},"4543":{"position":[[630,7],[796,6],[918,6],[1698,8],[1784,8]]},"4547":{"position":[[904,7],[964,6]]},"4562":{"position":[[2202,5],[3389,6]]},"4580":{"position":[[1759,5],[2600,6]]},"4593":{"position":[[1138,6],[6240,5]]},"4595":{"position":[[303,5]]},"4608":{"position":[[875,8]]},"4614":{"position":[[943,6]]},"4632":{"position":[[843,5],[1158,5],[1856,8],[2249,8]]},"4643":{"position":[[2610,5]]},"4660":{"position":[[479,5],[589,6],[882,7],[952,5],[1114,6],[1213,6],[1759,5],[2238,5],[3127,5]]},"4667":{"position":[[6330,5],[7324,5],[8094,5],[9068,5],[10713,5]]},"4669":{"position":[[206,6]]},"4695":{"position":[[46,6]]},"4711":{"position":[[144,7]]},"4742":{"position":[[745,5]]},"4767":{"position":[[99,6]]}}}],["allow_assign_grafana_admin",{"_index":4072,"t":{"963":{"position":[[4907,26]]},"1854":{"position":[[4907,26]]},"2987":{"position":[[4907,26]]}}}],["allow_org_cr",{"_index":4038,"t":{"963":{"position":[[1295,16]]},"1854":{"position":[[1295,16]]},"2987":{"position":[[1295,16]]}}}],["allow_sign_up",{"_index":4037,"t":{"963":{"position":[[1273,13]]},"1854":{"position":[[1273,13]]},"2987":{"position":[[1273,13]]}}}],["allowed_context",{"_index":2512,"t":{"491":{"position":[[582,17]]}}}],["allowed_organ",{"_index":4070,"t":{"963":{"position":[[4826,21]]},"1854":{"position":[[4826,21]]},"2987":{"position":[[4826,21]]}}}],["allowlist",{"_index":11138,"t":{"4047":{"position":[[576,12]]}}}],["allowsnippetannotations=tru",{"_index":12000,"t":{"4879":{"position":[[103,31]]}}}],["allowvolumeexpansion=tru",{"_index":11500,"t":{"4376":{"position":[[1192,28]]}}}],["almalinux",{"_index":3460,"t":{"880":{"position":[[256,9]]},"1781":{"position":[[256,9]]}}}],["alon",{"_index":8335,"t":{"2287":{"position":[[64,5]]},"2301":{"position":[[64,5]]},"3714":{"position":[[1695,5]]},"4133":{"position":[[1921,5]]},"4279":{"position":[[150,5]]},"4313":{"position":[[1502,5]]},"4746":{"position":[[303,5]]}}}],["along",{"_index":2604,"t":{"530":{"position":[[1304,5],[2902,5]]},"705":{"position":[[33,5]]},"738":{"position":[[33,5]]},"818":{"position":[[508,5]]},"951":{"position":[[199,5]]},"1842":{"position":[[199,5]]},"2632":{"position":[[121,5]]},"2686":{"position":[[745,5]]},"2975":{"position":[[199,5]]},"3067":{"position":[[496,5]]},"3679":{"position":[[1205,5]]},"3928":{"position":[[2026,5]]},"4313":{"position":[[839,5],[1404,5]]}}}],["alongsid",{"_index":9752,"t":{"3108":{"position":[[0,9]]},"3148":{"position":[[29,9]]},"3180":{"position":[[59,9]]},"3218":{"position":[[59,9]]},"3223":{"position":[[627,9]]},"3418":{"position":[[288,9]]}}}],["alpha",{"_index":2598,"t":{"530":{"position":[[327,5]]},"555":{"position":[[480,5],[585,5],[635,5]]}}}],["alphabet",{"_index":11120,"t":{"4013":{"position":[[499,14]]}}}],["alpin",{"_index":7776,"t":{"2155":{"position":[[2762,6]]}}}],["alreadi",{"_index":735,"t":{"130":{"position":[[306,7]]},"173":{"position":[[803,7]]},"339":{"position":[[559,7]]},"368":{"position":[[1131,7],[7373,7]]},"430":{"position":[[274,7]]},"434":{"position":[[730,7]]},"438":{"position":[[246,7]]},"442":{"position":[[361,7]]},"471":{"position":[[218,7]]},"479":{"position":[[1724,8]]},"498":{"position":[[212,7]]},"604":{"position":[[311,7],[410,8]]},"846":{"position":[[724,7]]},"871":{"position":[[320,7]]},"963":{"position":[[2879,8]]},"969":{"position":[[7,7],[124,7]]},"1169":{"position":[[900,7]]},"1199":{"position":[[572,7]]},"1205":{"position":[[535,7]]},"1226":{"position":[[2273,7]]},"1248":{"position":[[590,7]]},"1423":{"position":[[147,7]]},"1443":{"position":[[736,7]]},"1457":{"position":[[231,7],[409,7],[625,7],[3441,7]]},"1474":{"position":[[397,7]]},"1509":{"position":[[439,7]]},"1519":{"position":[[418,7]]},"1652":{"position":[[139,7]]},"1688":{"position":[[161,7]]},"1772":{"position":[[320,7]]},"1854":{"position":[[2879,8]]},"1860":{"position":[[7,7],[124,7]]},"1977":{"position":[[139,7]]},"2173":{"position":[[423,7]]},"2236":{"position":[[75,7]]},"2252":{"position":[[571,7],[2382,7],[2470,7]]},"2256":{"position":[[888,7]]},"2285":{"position":[[381,7],[700,7],[1418,7]]},"2287":{"position":[[570,7]]},"2299":{"position":[[381,7],[700,7],[1418,7]]},"2301":{"position":[[570,7]]},"2355":{"position":[[884,7]]},"2422":{"position":[[884,7]]},"2439":{"position":[[658,7]]},"2576":{"position":[[525,8]]},"2580":{"position":[[403,7]]},"2582":{"position":[[470,8]]},"2604":{"position":[[702,7]]},"2606":{"position":[[630,7]]},"2628":{"position":[[1080,7]]},"2640":{"position":[[83,7]]},"2668":{"position":[[88,7]]},"2678":{"position":[[858,7]]},"2680":{"position":[[152,7],[247,7]]},"2716":{"position":[[1737,7]]},"2743":{"position":[[157,7]]},"2747":{"position":[[446,7]]},"2900":{"position":[[118,7]]},"2914":{"position":[[1464,8]]},"2987":{"position":[[2879,8]]},"2993":{"position":[[7,7],[124,7]]},"3022":{"position":[[6,7]]},"3047":{"position":[[135,7]]},"3148":{"position":[[800,7]]},"3159":{"position":[[684,7]]},"3264":{"position":[[723,7]]},"3315":{"position":[[3,7]]},"3582":{"position":[[1068,7],[1315,7]]},"3712":{"position":[[1389,7]]},"3738":{"position":[[244,7]]},"3770":{"position":[[100,7]]},"3835":{"position":[[1131,7]]},"3857":{"position":[[283,7]]},"3947":{"position":[[2600,7]]},"3968":{"position":[[942,7],[2671,7]]},"4023":{"position":[[169,7]]},"4045":{"position":[[637,7],[1155,7],[1639,7]]},"4104":{"position":[[505,7]]},"4109":{"position":[[3210,7]]},"4146":{"position":[[1735,7],[1949,7]]},"4148":{"position":[[259,7]]},"4157":{"position":[[499,7]]},"4161":{"position":[[139,7],[360,7]]},"4163":{"position":[[322,7],[2251,7],[3025,7],[3192,7],[3321,7],[3754,7]]},"4178":{"position":[[942,7]]},"4180":{"position":[[16,7]]},"4224":{"position":[[617,7],[2864,7]]},"4230":{"position":[[4524,7]]},"4234":{"position":[[171,7]]},"4257":{"position":[[454,7],[1300,7],[5722,7]]},"4281":{"position":[[33,7],[792,7]]},"4283":{"position":[[977,7]]},"4291":{"position":[[1098,7]]},"4302":{"position":[[4950,7]]},"4313":{"position":[[1200,7]]},"4431":{"position":[[994,7]]},"4483":{"position":[[345,7]]},"4539":{"position":[[4068,7]]},"4547":{"position":[[2812,7]]},"4580":{"position":[[3269,7]]},"4587":{"position":[[327,7]]},"4610":{"position":[[111,7]]},"4618":{"position":[[69,7]]},"4632":{"position":[[585,7]]},"4715":{"position":[[331,7]]},"4759":{"position":[[287,7]]},"4765":{"position":[[176,7]]},"4793":{"position":[[56,7]]}}}],["alright",{"_index":8650,"t":{"2580":{"position":[[657,8]]}}}],["alsoi",{"_index":3667,"t":{"912":{"position":[[6785,5]]},"1796":{"position":[[6785,5]]}}}],["alter",{"_index":6349,"t":{"1525":{"position":[[903,7]]},"4222":{"position":[[4081,5]]}}}],["altern",{"_index":383,"t":{"37":{"position":[[1369,13]]},"76":{"position":[[72,12]]},"303":{"position":[[247,14]]},"374":{"position":[[30,11]]},"514":{"position":[[1503,11]]},"557":{"position":[[4813,11]]},"578":{"position":[[209,11]]},"611":{"position":[[579,11]]},"671":{"position":[[485,11]]},"686":{"position":[[85,14]]},"751":{"position":[[85,14]]},"934":{"position":[[428,14]]},"1250":{"position":[[43,11]]},"1301":{"position":[[2935,11]]},"1324":{"position":[[12590,14]]},"1405":{"position":[[735,13]]},"1457":{"position":[[1398,13],[1777,13]]},"1825":{"position":[[428,14]]},"1998":{"position":[[228,14]]},"2203":{"position":[[188,11]]},"2205":{"position":[[131,11]]},"2355":{"position":[[1048,11]]},"2376":{"position":[[414,12]]},"2422":{"position":[[1048,11]]},"2478":{"position":[[2226,14]]},"2572":{"position":[[85,11]]},"2584":{"position":[[1209,14]]},"2586":{"position":[[819,14]]},"2647":{"position":[[2159,14]]},"2649":{"position":[[3470,14]]},"2674":{"position":[[388,14]]},"2747":{"position":[[401,13]]},"2756":{"position":[[1110,11]]},"2958":{"position":[[428,14]]},"3095":{"position":[[223,11]]},"3159":{"position":[[220,12]]},"3308":{"position":[[632,11]]},"3375":{"position":[[389,14]]},"3378":{"position":[[611,14]]},"3549":{"position":[[3,11]]},"3731":{"position":[[714,14]]},"3763":{"position":[[212,14]]},"3971":{"position":[[728,13]]},"4124":{"position":[[52,12],[71,11],[2046,12]]},"4144":{"position":[[134,13]]},"4146":{"position":[[547,14]]},"4217":{"position":[[126,13]]},"4222":{"position":[[1696,11]]},"4224":{"position":[[1146,11]]},"4226":{"position":[[3421,11]]},"4230":{"position":[[4883,11]]},"4257":{"position":[[4410,11]]},"4302":{"position":[[2792,12]]},"4304":{"position":[[1997,11]]},"4327":{"position":[[237,12]]},"4580":{"position":[[1673,11],[3570,11]]},"4582":{"position":[[634,13]]},"4604":{"position":[[810,11]]},"4767":{"position":[[324,13]]},"4863":{"position":[[237,14]]}}}],["although",{"_index":2107,"t":{"339":{"position":[[602,8]]},"374":{"position":[[193,8]]},"376":{"position":[[254,8]]},"928":{"position":[[449,8]]},"940":{"position":[[1106,8]]},"1819":{"position":[[449,8]]},"1831":{"position":[[1106,8]]},"2952":{"position":[[449,8]]},"2964":{"position":[[1106,8]]},"3843":{"position":[[263,8]]},"3928":{"position":[[620,8]]},"4041":{"position":[[998,8]]},"4124":{"position":[[643,8]]},"4146":{"position":[[1706,8]]},"4222":{"position":[[1627,8]]},"4310":{"position":[[1154,8]]},"4313":{"position":[[915,8]]},"4520":{"position":[[263,8]]}}}],["altogeth",{"_index":11636,"t":{"4547":{"position":[[1640,10]]}}}],["alway",{"_index":837,"t":{"145":{"position":[[186,6],[311,6]]},"147":{"position":[[11,6]]},"151":{"position":[[52,6],[174,6]]},"155":{"position":[[16,6]]},"159":{"position":[[35,6]]},"356":{"position":[[161,6]]},"368":{"position":[[5559,6],[5801,6],[7236,6],[7611,6]]},"382":{"position":[[801,6]]},"463":{"position":[[875,6]]},"477":{"position":[[723,6]]},"543":{"position":[[831,6]]},"634":{"position":[[300,6]]},"755":{"position":[[308,6],[437,6]]},"883":{"position":[[89,6]]},"912":{"position":[[7581,6]]},"1064":{"position":[[1653,6]]},"1103":{"position":[[129,6],[301,6]]},"1109":{"position":[[327,6]]},"1118":{"position":[[21,6]]},"1175":{"position":[[690,6]]},"1185":{"position":[[316,6]]},"1222":{"position":[[616,6]]},"1228":{"position":[[109,6]]},"1232":{"position":[[27,6]]},"1252":{"position":[[387,6]]},"1257":{"position":[[8,6]]},"1259":{"position":[[659,6]]},"1303":{"position":[[3649,6]]},"1457":{"position":[[3861,6]]},"1466":{"position":[[371,6]]},"1472":{"position":[[261,6],[821,6]]},"1509":{"position":[[568,6]]},"1511":{"position":[[381,6]]},"1796":{"position":[[7581,6]]},"1807":{"position":[[89,6]]},"2071":{"position":[[1856,6]]},"2076":{"position":[[302,6]]},"2084":{"position":[[11,6]]},"2086":{"position":[[52,6],[175,6]]},"2090":{"position":[[33,6]]},"2157":{"position":[[64,6]]},"2165":{"position":[[1101,6]]},"2171":{"position":[[8,6]]},"2188":{"position":[[483,6]]},"2234":{"position":[[123,6],[353,6]]},"2242":{"position":[[405,6]]},"2283":{"position":[[873,6]]},"2287":{"position":[[78,6]]},"2293":{"position":[[104,6]]},"2297":{"position":[[873,6]]},"2301":{"position":[[78,6]]},"2307":{"position":[[104,6]]},"2714":{"position":[[1454,6]]},"2806":{"position":[[11,6],[80,6]]},"3313":{"position":[[789,6]]},"3381":{"position":[[1517,6]]},"3549":{"position":[[1029,6]]},"3592":{"position":[[1873,6]]},"3651":{"position":[[92,6]]},"3653":{"position":[[922,6]]},"3688":{"position":[[92,6]]},"3690":{"position":[[821,6]]},"3706":{"position":[[632,6]]},"3775":{"position":[[92,6]]},"3777":{"position":[[922,6]]},"3799":{"position":[[632,6]]},"3829":{"position":[[126,6]]},"3857":{"position":[[366,6]]},"3941":{"position":[[447,6]]},"3947":{"position":[[893,6]]},"3978":{"position":[[205,6],[300,6]]},"3982":{"position":[[174,6]]},"3992":{"position":[[406,6]]},"4017":{"position":[[9,6],[134,6]]},"4047":{"position":[[513,6]]},"4107":{"position":[[1906,6]]},"4109":{"position":[[4593,6]]},"4159":{"position":[[796,6]]},"4163":{"position":[[1684,6]]},"4176":{"position":[[204,6]]},"4202":{"position":[[665,6]]},"4266":{"position":[[10,6]]},"4291":{"position":[[678,6]]},"4444":{"position":[[231,6]]},"4455":{"position":[[231,6]]},"4471":{"position":[[76,6]]},"4525":{"position":[[50,6]]},"4593":{"position":[[698,6],[1963,6]]},"4707":{"position":[[971,6]]}}}],["alwaysallow",{"_index":11629,"t":{"4541":{"position":[[1893,12]]}}}],["amalgam",{"_index":2615,"t":{"537":{"position":[[34,12]]}}}],["amazon",{"_index":3319,"t":{"830":{"position":[[188,6]]}}}],["amber",{"_index":3856,"t":{"938":{"position":[[1502,5]]},"963":{"position":[[3622,5]]},"1829":{"position":[[1502,5]]},"1854":{"position":[[3622,5]]},"2962":{"position":[[1502,5]]},"2987":{"position":[[3622,5]]}}}],["ambigu",{"_index":10201,"t":{"3546":{"position":[[146,9]]},"4041":{"position":[[63,10]]},"4578":{"position":[[359,10]]},"4691":{"position":[[1459,10]]}}}],["amd",{"_index":5844,"t":{"1359":{"position":[[18,3]]},"3246":{"position":[[463,3]]},"3656":{"position":[[337,4]]},"3669":{"position":[[248,5]]},"3671":{"position":[[256,4]]},"3673":{"position":[[691,3],[807,3]]},"3681":{"position":[[761,3]]},"3690":{"position":[[1280,3]]},"3693":{"position":[[396,4]]},"3706":{"position":[[918,3]]},"3710":{"position":[[261,5],[911,4]]},"3712":{"position":[[307,3],[568,4],[2082,3]]},"3714":{"position":[[568,3],[768,3]]},"3718":{"position":[[800,3]]},"3744":{"position":[[2120,3],[2186,3],[2542,3]]},"3777":{"position":[[1381,3]]},"3780":{"position":[[396,4]]},"3799":{"position":[[918,3]]},"3803":{"position":[[248,5],[898,4]]},"3805":{"position":[[279,3],[347,4]]},"3807":{"position":[[314,3],[456,3]]},"3811":{"position":[[800,3]]},"3850":{"position":[[77,3]]}}}],["amd64",{"_index":3005,"t":{"671":{"position":[[221,5]]},"887":{"position":[[3407,5],[4093,5],[4345,5],[5095,5],[9652,5],[9949,5]]},"1811":{"position":[[3407,5],[4093,5],[4345,5],[5095,5],[9652,5],[9949,5]]},"2163":{"position":[[345,5],[458,5],[571,5],[684,5],[797,5],[910,5],[1023,5],[1136,5],[1249,5],[1362,5],[1475,5],[1588,5],[1701,5],[1814,5],[1925,5],[2036,5],[2147,5],[2258,5],[2369,5],[2480,5],[2591,5],[2702,5],[2813,5],[2924,5],[3035,5],[3146,5]]}}}],["amd64.img",{"_index":3438,"t":{"871":{"position":[[941,9],[1047,9]]},"887":{"position":[[6335,9],[6563,9],[7128,9],[7381,9],[7921,9],[8149,9],[8663,11]]},"1772":{"position":[[941,9],[1047,9]]},"1811":{"position":[[6335,9],[6563,9],[7128,9],[7381,9],[7921,9],[8149,9],[8663,11]]}}}],["amd64.iso",{"_index":6247,"t":{"1466":{"position":[[317,9]]}}}],["amd64.raw",{"_index":3504,"t":{"887":{"position":[[3167,9]]},"1811":{"position":[[3167,9]]}}}],["amd64.tar.gz",{"_index":3094,"t":{"703":{"position":[[524,12],[568,12]]}}}],["amd64/velero",{"_index":3096,"t":{"703":{"position":[[610,12]]}}}],["amend",{"_index":10088,"t":{"3384":{"position":[[840,5]]},"3936":{"position":[[435,5]]}}}],["america",{"_index":11654,"t":{"4560":{"position":[[3578,8]]}}}],["amet",{"_index":4,"t":{"3":{"position":[[22,5],[174,4]]}}}],["amhpora",{"_index":7895,"t":{"2184":{"position":[[6306,7]]}}}],["amongst",{"_index":9711,"t":{"3083":{"position":[[285,7]]}}}],["amount",{"_index":3881,"t":{"942":{"position":[[48,6]]},"999":{"position":[[195,6]]},"1040":{"position":[[310,6],[438,6]]},"1661":{"position":[[203,6]]},"1833":{"position":[[48,6]]},"1890":{"position":[[195,6]]},"2027":{"position":[[98,6]]},"2221":{"position":[[408,6]]},"2718":{"position":[[82,6]]},"2966":{"position":[[48,6]]},"3144":{"position":[[363,6]]},"3148":{"position":[[991,6]]},"3176":{"position":[[319,6]]},"3259":{"position":[[43,6]]},"3281":{"position":[[648,6]]},"3310":{"position":[[172,6],[661,6]]},"3352":{"position":[[949,6]]},"3582":{"position":[[842,7]]},"3592":{"position":[[49,7]]},"3656":{"position":[[188,6],[202,6]]},"3677":{"position":[[1229,6]]},"3693":{"position":[[247,6],[261,6]]},"3706":{"position":[[1316,6]]},"3714":{"position":[[329,6],[1724,6]]},"3757":{"position":[[108,6],[185,6],[250,6]]},"3759":{"position":[[233,6]]},"3761":{"position":[[37,6]]},"3768":{"position":[[156,6]]},"3780":{"position":[[247,6],[261,6]]},"3791":{"position":[[1252,6]]},"3799":{"position":[[1316,6]]},"3902":{"position":[[48,6]]},"3904":{"position":[[783,6]]},"3928":{"position":[[3001,6]]},"4013":{"position":[[571,6]]},"4077":{"position":[[362,6]]},"4116":{"position":[[268,7]]},"4163":{"position":[[1193,6]]},"4281":{"position":[[815,6]]},"4479":{"position":[[546,6]]},"4506":{"position":[[938,6]]},"4738":{"position":[[742,6]]},"4744":{"position":[[618,6]]},"4746":{"position":[[157,6]]},"4791":{"position":[[219,6]]}}}],["amper",{"_index":10433,"t":{"3675":{"position":[[373,6]]},"3714":{"position":[[2089,6]]},"3720":{"position":[[376,6]]},"3744":{"position":[[247,6],[291,6]]},"3813":{"position":[[373,6]]}}}],["ampereon",{"_index":10574,"t":{"3712":{"position":[[823,9]]}}}],["amphora",{"_index":2761,"t":{"557":{"position":[[2291,8],[2315,8],[2719,8],[3195,8],[3219,8],[3550,8]]},"938":{"position":[[1076,8]]},"942":{"position":[[2714,7]]},"980":{"position":[[740,8]]},"991":{"position":[[12,8],[104,7],[200,7]]},"1523":{"position":[[1061,7],[1110,7]]},"1743":{"position":[[139,7]]},"1745":{"position":[[48,7],[119,7],[261,8],[458,8]]},"1829":{"position":[[1076,8]]},"1833":{"position":[[2714,7]]},"1871":{"position":[[740,8]]},"1882":{"position":[[12,8],[104,7],[200,7]]},"2184":{"position":[[6069,7]]},"2231":{"position":[[797,7],[846,7],[1145,7],[1197,7]]},"2962":{"position":[[1076,8]]},"2966":{"position":[[2714,7]]},"3004":{"position":[[740,8]]},"3230":{"position":[[232,7]]},"3264":{"position":[[500,7]]},"3285":{"position":[[437,7]]}}}],["amplifi",{"_index":10217,"t":{"3563":{"position":[[218,10]]}}}],["amqp",{"_index":5236,"t":{"1263":{"position":[[662,11]]},"4302":{"position":[[2077,4]]}}}],["analysi",{"_index":8517,"t":{"2482":{"position":[[130,8]]},"2503":{"position":[[293,9]]},"2551":{"position":[[421,9]]},"2557":{"position":[[241,9]]},"3317":{"position":[[141,9]]},"3323":{"position":[[526,8]]},"3346":{"position":[[386,8]]},"4100":{"position":[[549,9],[639,8]]},"4107":{"position":[[252,9]]},"4146":{"position":[[201,8]]},"4169":{"position":[[220,8]]},"4595":{"position":[[363,8]]}}}],["analyz",{"_index":4054,"t":{"963":{"position":[[2969,8]]},"976":{"position":[[73,7],[235,7]]},"978":{"position":[[2326,10]]},"1655":{"position":[[258,8]]},"1854":{"position":[[2969,8]]},"1867":{"position":[[73,7],[235,7]]},"1869":{"position":[[2326,10]]},"2487":{"position":[[765,9]]},"2551":{"position":[[124,9],[216,9]]},"2567":{"position":[[1137,7]]},"2802":{"position":[[273,7]]},"2987":{"position":[[2969,8]]},"3000":{"position":[[73,7],[235,7]]},"3002":{"position":[[2326,10]]},"4077":{"position":[[482,7]]},"4656":{"position":[[291,8]]},"4722":{"position":[[764,7]]}}}],["analyze_ceph",{"_index":5963,"t":{"1391":{"position":[[2952,12],[3481,12]]}}}],["ancient",{"_index":10372,"t":{"3669":{"position":[[330,7]]},"3710":{"position":[[343,7]]},"3803":{"position":[[330,7]]}}}],["and/or",{"_index":511,"t":{"70":{"position":[[433,6]]},"520":{"position":[[578,6]]},"1593":{"position":[[244,6]]},"1936":{"position":[[244,6]]},"2048":{"position":[[2643,6]]},"2480":{"position":[[525,6]]},"2608":{"position":[[647,6]]},"3529":{"position":[[1168,6],[1798,6]]},"3829":{"position":[[4971,6]]},"3936":{"position":[[687,6]]},"4096":{"position":[[900,6]]},"4111":{"position":[[270,6]]},"4304":{"position":[[803,6]]},"4433":{"position":[[42,6]]},"4539":{"position":[[6694,6]]},"4547":{"position":[[2283,6]]},"4784":{"position":[[42,6]]},"4839":{"position":[[781,6]]}}}],["andrea",{"_index":8325,"t":{"2281":{"position":[[605,7]]}}}],["angular",{"_index":9345,"t":{"2938":{"position":[[44,7]]},"2940":{"position":[[69,8]]}}}],["anjastrunk",{"_index":270,"t":{"28":{"position":[[1666,10]]}}}],["annot",{"_index":2379,"t":{"440":{"position":[[10,9]]},"708":{"position":[[1108,8]]},"739":{"position":[[467,8]]},"741":{"position":[[346,12],[683,10],[986,12]]},"1407":{"position":[[2705,12]]},"1409":{"position":[[1562,12]]},"2806":{"position":[[172,11]]},"3474":{"position":[[235,11]]},"4374":{"position":[[112,9]]},"4385":{"position":[[88,11]]},"4399":{"position":[[95,11]]},"4459":{"position":[[926,8]]},"4543":{"position":[[1629,10]]},"4849":{"position":[[484,12]]},"4853":{"position":[[146,12]]},"4879":{"position":[[91,11]]}}}],["announc",{"_index":63,"t":{"7":{"position":[[538,13]]},"59":{"position":[[26,9]]},"260":{"position":[[11,13]]},"262":{"position":[[192,13]]},"266":{"position":[[495,12]]},"3159":{"position":[[719,9]]},"3292":{"position":[[3,9]]},"3294":{"position":[[558,8],[1474,12]]},"3323":{"position":[[727,13]]},"3539":{"position":[[115,9]]},"3608":{"position":[[607,9]]},"3644":{"position":[[19,9],[88,14]]},"4109":{"position":[[4163,10]]},"4257":{"position":[[4851,9]]},"4270":{"position":[[433,13]]},"4562":{"position":[[7292,9],[7581,9]]}}}],["announce@lists.scs.commun",{"_index":1799,"t":{"260":{"position":[[44,28]]}}}],["annoy",{"_index":11780,"t":{"4660":{"position":[[1516,6]]}}}],["anomali",{"_index":7821,"t":{"2163":{"position":[[4184,10]]},"4733":{"position":[[1346,7]]}}}],["anonhugepag",{"_index":5908,"t":{"1383":{"position":[[1887,14]]},"1736":{"position":[[26,14],[514,14]]}}}],["anonym",{"_index":9290,"t":{"2918":{"position":[[827,9]]},"4541":{"position":[[1302,9],[1462,9]]},"4547":{"position":[[2988,9],[3072,9]]}}}],["anoth",{"_index":1204,"t":{"177":{"position":[[298,7]]},"199":{"position":[[1393,7]]},"479":{"position":[[1385,7]]},"528":{"position":[[552,7]]},"728":{"position":[[304,7],[414,8],[704,8]]},"739":{"position":[[67,7]]},"938":{"position":[[1697,7]]},"946":{"position":[[749,7]]},"949":{"position":[[474,7]]},"978":{"position":[[1562,7]]},"1185":{"position":[[185,7]]},"1252":{"position":[[234,7]]},"1259":{"position":[[741,7]]},"1375":{"position":[[678,7]]},"1593":{"position":[[1061,7]]},"1829":{"position":[[1697,7]]},"1837":{"position":[[749,7]]},"1840":{"position":[[474,7]]},"1869":{"position":[[1562,7]]},"1936":{"position":[[1061,7]]},"2065":{"position":[[1370,7],[1689,7],[2010,7],[2341,7],[2663,7],[2985,7],[3306,7],[3622,7]]},"2184":{"position":[[1545,7]]},"2234":{"position":[[688,7]]},"2256":{"position":[[1038,7]]},"2261":{"position":[[332,7]]},"2380":{"position":[[472,7]]},"2612":{"position":[[174,7]]},"2655":{"position":[[575,7]]},"2716":{"position":[[1499,7],[2057,7]]},"2718":{"position":[[425,7]]},"2740":{"position":[[284,7]]},"2747":{"position":[[549,7]]},"2962":{"position":[[1697,7]]},"2970":{"position":[[749,7]]},"2973":{"position":[[474,7]]},"3002":{"position":[[1562,7]]},"3276":{"position":[[854,7]]},"3932":{"position":[[719,7]]},"3941":{"position":[[1079,7],[1211,7]]},"3947":{"position":[[1673,7],[1863,7],[3099,7]]},"3986":{"position":[[125,7]]},"4060":{"position":[[413,7]]},"4079":{"position":[[106,7],[359,7]]},"4083":{"position":[[245,7]]},"4109":{"position":[[3227,7]]},"4159":{"position":[[490,7],[2289,7]]},"4163":{"position":[[913,7],[1886,7],[1933,7],[2854,8],[4962,7],[5749,7],[5840,7]]},"4165":{"position":[[503,7],[815,7]]},"4167":{"position":[[430,7]]},"4222":{"position":[[3066,7]]},"4226":{"position":[[691,7]]},"4228":{"position":[[930,7]]},"4230":{"position":[[3173,7]]},"4405":{"position":[[85,7]]},"4414":{"position":[[354,7]]},"4420":{"position":[[2489,7]]},"4431":{"position":[[1180,7]]},"4539":{"position":[[1659,7]]},"4547":{"position":[[1859,7],[2468,7],[2685,7]]},"4549":{"position":[[41,7]]},"4738":{"position":[[712,7]]},"4797":{"position":[[289,7],[376,7]]}}}],["ansibl",{"_index":433,"t":{"41":{"position":[[36,7]]},"145":{"position":[[35,7],[98,7],[201,7],[357,7]]},"153":{"position":[[160,7]]},"159":{"position":[[169,7]]},"271":{"position":[[581,7]]},"273":{"position":[[108,8]]},"343":{"position":[[313,8]]},"354":{"position":[[38,7]]},"356":{"position":[[113,7]]},"520":{"position":[[213,7],[490,7]]},"522":{"position":[[299,7]]},"826":{"position":[[21,7]]},"924":{"position":[[834,7]]},"1140":{"position":[[47,7]]},"1185":{"position":[[1001,7]]},"1207":{"position":[[131,7]]},"1214":{"position":[[4,7]]},"1226":{"position":[[469,7],[1606,7],[4182,7]]},"1232":{"position":[[522,7]]},"1240":{"position":[[70,8]]},"1244":{"position":[[821,7],[885,7]]},"1246":{"position":[[654,7]]},"1250":{"position":[[685,7]]},"1275":{"position":[[214,7]]},"1301":{"position":[[49,7],[411,7]]},"1324":{"position":[[12633,7]]},"1373":{"position":[[490,7]]},"1387":{"position":[[50,7]]},"1391":{"position":[[867,7],[3201,7]]},"1399":{"position":[[12,7]]},"1413":{"position":[[180,7]]},"1425":{"position":[[319,7]]},"1443":{"position":[[122,7],[753,7],[883,7]]},"1445":{"position":[[47,7]]},"1453":{"position":[[47,7]]},"1468":{"position":[[282,7]]},"1472":{"position":[[121,7],[2391,7],[2418,7],[2531,7],[2569,7],[2680,7],[2876,7],[3068,7],[3128,7]]},"1474":{"position":[[36,7],[156,7],[302,7]]},"1476":{"position":[[36,7],[156,7],[279,7]]},"1480":{"position":[[13,7]]},"1484":{"position":[[50,7],[457,7],[621,7]]},"1509":{"position":[[321,7]]},"1534":{"position":[[161,7]]},"1536":{"position":[[56,7]]},"1538":{"position":[[52,7]]},"1555":{"position":[[112,7]]},"1557":{"position":[[105,7]]},"1655":{"position":[[45,7]]},"1669":{"position":[[11,7],[50,7],[88,7]]},"1671":{"position":[[58,7]]},"1686":{"position":[[495,7],[669,7]]},"1692":{"position":[[5,7],[39,7],[140,7],[206,7],[299,7],[364,7],[430,7]]},"1694":{"position":[[12,7],[779,7]]},"1740":{"position":[[229,7]]},"1815":{"position":[[834,7]]},"1912":{"position":[[183,7]]},"1914":{"position":[[184,7]]},"1979":{"position":[[50,7]]},"2059":{"position":[[587,7],[666,7],[1292,7],[1562,7],[1598,7],[1634,7]]},"2065":{"position":[[167,7],[194,7],[249,7],[388,7]]},"2071":{"position":[[868,7],[1230,7],[1407,7],[1587,7],[1632,7],[1742,7],[1791,7],[1913,7],[2073,7]]},"2074":{"position":[[63,7],[237,7],[264,7],[372,7],[455,7],[675,7]]},"2082":{"position":[[38,7],[90,7]]},"2112":{"position":[[324,7]]},"2119":{"position":[[269,7]]},"2123":{"position":[[1298,7]]},"2148":{"position":[[50,7]]},"2155":{"position":[[1119,7],[1189,7],[1250,7],[1322,7],[2985,7],[3057,7]]},"2171":{"position":[[2207,7],[2675,7]]},"2182":{"position":[[202,7],[249,7],[342,7]]},"2184":{"position":[[2773,7],[4234,7]]},"2196":{"position":[[935,7]]},"2203":{"position":[[208,7]]},"2205":{"position":[[151,7]]},"2211":{"position":[[1570,7]]},"2214":{"position":[[0,7]]},"2216":{"position":[[15,7],[86,7]]},"2223":{"position":[[104,8],[202,8],[317,8]]},"2443":{"position":[[908,8]]},"2649":{"position":[[70,7],[1232,7],[1548,7],[1607,7],[1790,7],[2349,8],[3088,7],[3363,7]]},"2914":{"position":[[1003,9]]},"2948":{"position":[[834,7]]},"3016":{"position":[[45,7],[181,10]]},"3026":{"position":[[84,7]]},"3055":{"position":[[24,7]]},"3083":{"position":[[837,8]]},"3093":{"position":[[294,7]]},"3097":{"position":[[130,7]]},"3116":{"position":[[552,8]]},"3119":{"position":[[106,7]]},"3150":{"position":[[192,8]]},"3225":{"position":[[612,8],[652,7],[690,7]]},"3348":{"position":[[1121,7],[1233,7]]},"3352":{"position":[[676,7],[1040,7],[1626,7],[1795,7]]},"3398":{"position":[[1706,7]]},"3460":{"position":[[661,8]]},"4144":{"position":[[52,8]]},"4146":{"position":[[380,7]]},"4224":{"position":[[1623,7]]},"4230":{"position":[[3462,7]]},"4240":{"position":[[566,8]]},"4244":{"position":[[425,7]]},"4246":{"position":[[414,7]]},"4304":{"position":[[912,7]]},"4420":{"position":[[2889,7]]},"4562":{"position":[[7113,8]]},"4593":{"position":[[609,7]]},"4597":{"position":[[788,8]]},"4826":{"position":[[2160,7]]}}}],["ansible&pipeline=period",{"_index":7670,"t":{"2132":{"position":[[1048,25],[1217,25],[1386,25]]}}}],["ansible.builtin.add_host",{"_index":7596,"t":{"2117":{"position":[[1712,25]]}}}],["ansible.builtin.apt",{"_index":4541,"t":{"1147":{"position":[[345,19]]},"2117":{"position":[[2020,20],[2131,20]]}}}],["ansible.builtin.command",{"_index":6692,"t":{"1665":{"position":[[670,24],[823,24],[998,24]]}}}],["ansible.builtin.copi",{"_index":866,"t":{"151":{"position":[[446,21]]},"2086":{"position":[[447,21]]},"2123":{"position":[[282,21]]}}}],["ansible.builtin.fil",{"_index":7635,"t":{"2123":{"position":[[142,21]]}}}],["ansible.builtin.find",{"_index":6689,"t":{"1665":{"position":[[502,21]]}}}],["ansible.builtin.group",{"_index":7603,"t":{"2117":{"position":[[2388,22]]}}}],["ansible.builtin.us",{"_index":7601,"t":{"2117":{"position":[[2276,21],[2465,21]]}}}],["ansible.builtin.wait_for_connect",{"_index":7599,"t":{"2117":{"position":[[1955,36]]}}}],["ansible.manager_default",{"_index":6865,"t":{"1694":{"position":[[6670,23],[8474,23]]}}}],["ansible.netcommon",{"_index":917,"t":{"155":{"position":[[931,17]]}}}],["ansible.posix.synchron",{"_index":885,"t":{"153":{"position":[[405,26]]},"2088":{"position":[[220,26]]}}}],["ansible.yaml",{"_index":8811,"t":{"2649":{"position":[[2756,12],[3066,12]]}}}],["ansible/check",{"_index":8035,"t":{"2216":{"position":[[46,13]]}}}],["ansible/kolla",{"_index":6779,"t":{"1694":{"position":[[1719,14],[6715,14],[7451,14]]}}}],["ansible/logs/ansible.log",{"_index":6766,"t":{"1692":{"position":[[315,25],[380,25],[446,25]]}}}],["ansible/pull/215/fil",{"_index":7495,"t":{"2074":{"position":[[746,22]]}}}],["ansible/roles/common/tasks/deploy.yml",{"_index":6861,"t":{"1694":{"position":[[5842,38]]}}}],["ansible13",{"_index":11375,"t":{"4230":{"position":[[3752,10]]},"4234":{"position":[[24,9]]}}}],["ansible:2023.2",{"_index":7756,"t":{"2155":{"position":[[1278,14]]}}}],["ansible:latest",{"_index":7779,"t":{"2155":{"position":[[3013,14]]}}}],["ansible:quinci",{"_index":7754,"t":{"2155":{"position":[[1146,14]]}}}],["ansible[^ak",{"_index":11366,"t":{"4230":{"position":[[709,12]]}}}],["ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2fcontain",{"_index":7669,"t":{"2132":{"position":[[951,85],[1119,85],[1288,85]]}}}],["ansible_architectur",{"_index":6744,"t":{"1683":{"position":[[174,20],[401,20]]}}}],["ansible_ask_pass",{"_index":6272,"t":{"1472":{"position":[[1231,16],[2630,16]]},"1474":{"position":[[70,17]]},"1476":{"position":[[70,17]]}}}],["ansible_ask_pass=tru",{"_index":6270,"t":{"1472":{"position":[[1001,21],[1571,21]]}}}],["ansible_ask_vault_pass",{"_index":6275,"t":{"1472":{"position":[[1427,22],[2820,22]]},"1474":{"position":[[188,22]]}}}],["ansible_ask_vault_pass=tru",{"_index":6269,"t":{"1472":{"position":[[971,27],[1876,27],[2461,27]]},"1474":{"position":[[237,27]]},"1476":{"position":[[195,27]]},"2163":{"position":[[4600,27]]}}}],["ansible_become_ask_pass",{"_index":6274,"t":{"1472":{"position":[[1349,23],[2929,23]]},"1474":{"position":[[44,25]]},"1476":{"position":[[44,25]]}}}],["ansible_become_ask_pass=tru",{"_index":6268,"t":{"1472":{"position":[[940,28]]}}}],["ansible_collection_services_vers",{"_index":7473,"t":{"2067":{"position":[[270,37]]}}}],["ansible_date_time.d",{"_index":887,"t":{"153":{"position":[[483,22]]},"2088":{"position":[[298,22]]}}}],["ansible_facts.processor_vcpu",{"_index":5592,"t":{"1305":{"position":[[136,31],[216,31]]}}}],["ansible_facts['memtotal_mb",{"_index":4856,"t":{"1187":{"position":[[243,28],[311,28],[379,28],[447,28],[522,28]]}}}],["ansible_facts['processor_nproc",{"_index":5872,"t":{"1373":{"position":[[840,32]]}}}],["ansible_host",{"_index":5086,"t":{"1226":{"position":[[1930,13],[4284,13]]},"1275":{"position":[[222,13]]},"1681":{"position":[[188,12],[407,12]]}}}],["ansible_host=192.0.2.2",{"_index":7652,"t":{"2123":{"position":[[1206,22]]}}}],["ansible_local.osism.bootstrap",{"_index":6364,"t":{"1538":{"position":[[66,29]]}}}],["ansible_local.osism.mainten",{"_index":6362,"t":{"1536":{"position":[[70,31]]}}}],["ansible_local.testbed_ceph_devices_al",{"_index":6697,"t":{"1665":{"position":[[903,38],[1118,38]]}}}],["ansible_os_famili",{"_index":868,"t":{"151":{"position":[[477,17]]},"2086":{"position":[[478,17]]}}}],["ansible_playbooks_manager_vers",{"_index":7474,"t":{"2067":{"position":[[312,36]]}}}],["ansible_processor_",{"_index":5867,"t":{"1373":{"position":[[576,19]]}}}],["ansible_ssh_arg",{"_index":6279,"t":{"1472":{"position":[[2154,16],[2252,18],[3013,16]]}}}],["ansible_ssh_us",{"_index":7602,"t":{"2117":{"position":[[2308,16]]}}}],["ansible_us",{"_index":6265,"t":{"1472":{"position":[[281,12],[690,12],[805,12],[1197,12],[1312,12],[1779,12],[3099,12]]},"1474":{"position":[[88,13]]},"1476":{"position":[[88,13]]},"2117":{"position":[[1798,13]]}}}],["ansible_user=os",{"_index":6271,"t":{"1472":{"position":[[1025,18],[2033,18]]}}}],["ansible_user=ubuntu",{"_index":7653,"t":{"2123":{"position":[[1229,19]]}}}],["ansible_vault_edit",{"_index":5159,"t":{"1238":{"position":[[473,18]]},"1246":{"position":[[674,18],[747,18]]}}}],["ansible_vault_rekey",{"_index":5162,"t":{"1238":{"position":[[695,19]]}}}],["ansible_vault_show",{"_index":5155,"t":{"1238":{"position":[[311,18],[344,18]]},"1523":{"position":[[1947,18]]}}}],["ansible_vers",{"_index":6864,"t":{"1694":{"position":[[6369,15]]}}}],["ansibleundefin",{"_index":8034,"t":{"2214":{"position":[[72,17]]}}}],["answer",{"_index":1353,"t":{"187":{"position":[[774,6]]},"239":{"position":[[127,8]]},"258":{"position":[[363,6]]},"3571":{"position":[[602,9]]},"3947":{"position":[[2721,7]]},"4733":{"position":[[151,8]]}}}],["antelop",{"_index":9826,"t":{"3183":{"position":[[76,10]]},"4045":{"position":[[25,10]]}}}],["anti",{"_index":9712,"t":{"3083":{"position":[[387,4]]},"3468":{"position":[[1028,4]]},"4431":{"position":[[412,4],[912,4],[1188,5],[2254,4]]},"4433":{"position":[[28,4],[93,4],[137,4],[440,4],[1136,5],[1365,4],[1664,4],[2544,4]]},"4435":{"position":[[137,4],[1432,4]]},"4437":{"position":[[104,4]]},"4446":{"position":[[107,4]]},"4448":{"position":[[1104,6]]},"4457":{"position":[[107,4]]},"4826":{"position":[[3020,4]]}}}],["anticip",{"_index":9919,"t":{"3290":{"position":[[326,11]]},"3321":{"position":[[407,10]]},"4587":{"position":[[1474,11]]},"4746":{"position":[[175,11]]}}}],["antrea",{"_index":11684,"t":{"4569":{"position":[[320,6]]}}}],["anyhow",{"_index":3872,"t":{"940":{"position":[[1098,7]]},"1831":{"position":[[1098,7]]},"2964":{"position":[[1098,7]]}}}],["anymor",{"_index":2315,"t":{"417":{"position":[[867,8]]},"461":{"position":[[437,8]]},"2355":{"position":[[2503,8]]},"2422":{"position":[[2503,8]]},"3162":{"position":[[730,8]]},"3539":{"position":[[365,8]]},"4104":{"position":[[1065,8]]},"4163":{"position":[[4918,8]]},"4249":{"position":[[354,8]]},"4253":{"position":[[505,8],[670,8],[723,7]]},"4257":{"position":[[3982,7]]},"4270":{"position":[[810,7]]},"4313":{"position":[[711,7]]},"4662":{"position":[[1813,7]]}}}],["anyon",{"_index":1854,"t":{"280":{"position":[[1548,6]]},"530":{"position":[[2084,6]]},"2920":{"position":[[149,6]]},"3014":{"position":[[152,6]]},"4504":{"position":[[130,7]]}}}],["anyth",{"_index":1604,"t":{"220":{"position":[[331,8]]},"228":{"position":[[335,8]]},"258":{"position":[[581,8]]},"273":{"position":[[19,8]]},"368":{"position":[[1272,8],[1458,8]]},"397":{"position":[[673,8]]},"417":{"position":[[1463,8]]},"602":{"position":[[199,8],[292,8]]},"618":{"position":[[45,8]]},"632":{"position":[[403,8]]},"914":{"position":[[1600,8]]},"924":{"position":[[215,8]]},"934":{"position":[[1941,8]]},"946":{"position":[[610,8]]},"1199":{"position":[[351,8]]},"1571":{"position":[[351,8]]},"1641":{"position":[[124,8]]},"1798":{"position":[[1600,8]]},"1815":{"position":[[215,8]]},"1825":{"position":[[1941,8]]},"1837":{"position":[[610,8]]},"1904":{"position":[[351,8]]},"1972":{"position":[[124,8]]},"2240":{"position":[[182,9]]},"2948":{"position":[[215,8]]},"2958":{"position":[[1941,8]]},"2970":{"position":[[610,8]]},"4308":{"position":[[272,8]]}}}],["anyway",{"_index":5818,"t":{"1346":{"position":[[949,6]]},"4801":{"position":[[136,6],[327,7]]}}}],["anywher",{"_index":1507,"t":{"199":{"position":[[3102,9]]},"1257":{"position":[[516,8]]},"2171":{"position":[[663,8]]},"3073":{"position":[[116,9]]}}}],["aodh",{"_index":5320,"t":{"1277":{"position":[[0,4],[17,4],[42,4]]},"1305":{"position":[[631,4],[761,4]]},"1657":{"position":[[512,4]]},"3016":{"position":[[758,5]]}}}],["aodh_api_public_port",{"_index":5336,"t":{"1295":{"position":[[241,21]]}}}],["aodh_api_work",{"_index":5594,"t":{"1305":{"position":[[549,16],[863,16]]}}}],["aodh_external_fqdn",{"_index":5334,"t":{"1295":{"position":[[193,18]]}}}],["aodh_public_endpoint",{"_index":5333,"t":{"1295":{"position":[[172,20]]}}}],["aov",{"_index":9946,"t":{"3308":{"position":[[837,4]]},"3367":{"position":[[421,3]]}}}],["aov.cloud",{"_index":10028,"t":{"3367":{"position":[[381,9]]}}}],["apach",{"_index":1134,"t":{"173":{"position":[[1150,6],[2072,6]]},"179":{"position":[[767,6]]},"249":{"position":[[1410,6]]},"293":{"position":[[133,6]]},"319":{"position":[[216,6],[386,6],[769,6],[852,6]]},"1096":{"position":[[190,6]]},"4325":{"position":[[195,6],[279,6]]},"4560":{"position":[[1218,6],[2704,6],[3924,6]]},"4849":{"position":[[443,6]]}}}],["apache2",{"_index":6893,"t":{"1696":{"position":[[429,8]]}}}],["apache_lock_dir=/var/lock/apache2",{"_index":6884,"t":{"1696":{"position":[[56,33]]}}}],["apache_log_dir=/var/log/apache2",{"_index":6885,"t":{"1696":{"position":[[102,31],[139,31]]}}}],["apart",{"_index":6264,"t":{"1468":{"position":[[1277,5]]},"2718":{"position":[[893,5]]},"2918":{"position":[[475,6]]},"4273":{"position":[[387,5]]},"4275":{"position":[[872,5]]}}}],["api",{"_index":220,"t":{"28":{"position":[[206,3],[234,3]]},"45":{"position":[[51,3]]},"52":{"position":[[46,3]]},"68":{"position":[[195,3]]},"70":{"position":[[495,3]]},"167":{"position":[[191,3]]},"177":{"position":[[282,3]]},"327":{"position":[[29,3]]},"334":{"position":[[78,3]]},"339":{"position":[[522,3]]},"368":{"position":[[5678,3]]},"376":{"position":[[197,4]]},"378":{"position":[[42,3]]},"382":{"position":[[13,3],[49,3],[422,3],[520,3]]},"391":{"position":[[439,3],[522,3]]},"393":{"position":[[582,3]]},"397":{"position":[[166,3],[704,3]]},"401":{"position":[[608,3],[1076,3],[1144,4],[1216,3]]},"403":{"position":[[278,3],[740,3]]},"411":{"position":[[226,3]]},"417":{"position":[[954,3],[1095,3]]},"419":{"position":[[202,4]]},"421":{"position":[[34,4],[73,3],[141,4],[238,3],[402,3],[514,4],[615,4],[873,3],[913,3],[1022,3]]},"423":{"position":[[67,4],[106,3],[242,4],[255,3],[725,3],[1096,3],[1178,3]]},"425":{"position":[[73,3],[415,3],[854,4]]},"427":{"position":[[12,3],[464,3]]},"446":{"position":[[138,4]]},"463":{"position":[[1245,3]]},"468":{"position":[[144,4]]},"471":{"position":[[60,4],[187,3],[311,3]]},"473":{"position":[[335,3],[523,3]]},"500":{"position":[[166,3]]},"533":{"position":[[136,4],[391,3]]},"539":{"position":[[418,4],[470,3]]},"541":{"position":[[1076,3],[1502,5]]},"545":{"position":[[346,3],[424,4],[544,3],[952,3],[1077,3]]},"557":{"position":[[4839,3],[5051,3]]},"572":{"position":[[207,3]]},"576":{"position":[[168,3]]},"578":{"position":[[295,3],[483,3]]},"657":{"position":[[132,4],[284,3]]},"659":{"position":[[475,3]]},"699":{"position":[[207,3]]},"701":{"position":[[75,3],[198,4],[601,4],[628,4],[2596,4]]},"732":{"position":[[901,3],[1124,4],[1177,3],[1254,3],[1420,3],[1522,3]]},"734":{"position":[[75,3]]},"812":{"position":[[152,4]]},"814":{"position":[[129,3]]},"818":{"position":[[423,4],[707,5],[737,3],[792,3]]},"820":{"position":[[154,3]]},"830":{"position":[[9,3],[125,3],[179,4],[199,4],[224,3]]},"838":{"position":[[491,4]]},"842":{"position":[[302,3]]},"848":{"position":[[189,3]]},"850":{"position":[[365,4]]},"875":{"position":[[496,3]]},"928":{"position":[[171,3],[427,3],[917,3]]},"934":{"position":[[333,3],[2196,3]]},"944":{"position":[[600,3]]},"961":{"position":[[1989,3]]},"963":{"position":[[3358,3],[4178,3],[4548,3]]},"1013":{"position":[[301,3]]},"1028":{"position":[[84,3]]},"1030":{"position":[[133,3]]},"1054":{"position":[[301,3]]},"1056":{"position":[[373,4],[435,4],[525,3],[578,3],[861,3],[1122,3],[1222,3],[1664,3],[1840,4],[2120,4]]},"1105":{"position":[[92,3]]},"1107":{"position":[[81,3]]},"1169":{"position":[[246,6],[600,3]]},"1222":{"position":[[1034,4]]},"1226":{"position":[[3427,3]]},"1230":{"position":[[287,3],[333,3],[342,3],[670,3],[760,3]]},"1242":{"position":[[179,3],[305,3]]},"1250":{"position":[[204,3]]},"1252":{"position":[[1111,3]]},"1261":{"position":[[354,3]]},"1303":{"position":[[1127,5],[1203,5],[1380,5],[1558,5]]},"1305":{"position":[[636,4]]},"1346":{"position":[[1231,3]]},"1352":{"position":[[127,3]]},"1385":{"position":[[1421,3]]},"1517":{"position":[[19,3]]},"1523":{"position":[[174,4],[1292,3]]},"1734":{"position":[[40,3],[1046,3]]},"1776":{"position":[[496,3]]},"1819":{"position":[[171,3],[427,3],[917,3]]},"1825":{"position":[[333,3],[2196,3]]},"1835":{"position":[[600,3]]},"1852":{"position":[[1989,3]]},"1854":{"position":[[3358,3],[4178,3],[4548,3]]},"2027":{"position":[[268,3],[467,3]]},"2142":{"position":[[265,5]]},"2146":{"position":[[141,3]]},"2155":{"position":[[1385,3],[1433,4],[1438,3]]},"2184":{"position":[[6057,3]]},"2192":{"position":[[669,3],[695,3],[1411,3]]},"2196":{"position":[[2408,3],[3213,3]]},"2199":{"position":[[40,4],[206,4],[616,4],[990,4],[1216,4],[1267,3]]},"2225":{"position":[[126,3]]},"2231":{"position":[[106,3],[153,5]]},"2252":{"position":[[2878,3]]},"2276":{"position":[[536,4],[589,3],[662,3],[686,3],[706,3],[755,3]]},"2325":{"position":[[991,3],[1157,3]]},"2327":{"position":[[43,3],[576,3]]},"2329":{"position":[[85,4],[722,3]]},"2331":{"position":[[47,3]]},"2341":{"position":[[128,4],[362,3]]},"2343":{"position":[[369,3],[426,3]]},"2347":{"position":[[79,3]]},"2355":{"position":[[43,3]]},"2358":{"position":[[43,3]]},"2392":{"position":[[991,3],[1157,3]]},"2394":{"position":[[43,3],[576,3]]},"2396":{"position":[[85,4],[722,3]]},"2398":{"position":[[47,3]]},"2408":{"position":[[128,4],[362,3]]},"2410":{"position":[[369,3],[426,3]]},"2414":{"position":[[79,3]]},"2422":{"position":[[43,3]]},"2425":{"position":[[43,3]]},"2441":{"position":[[148,3]]},"2443":{"position":[[32,3],[172,3]]},"2447":{"position":[[460,3]]},"2467":{"position":[[1647,3]]},"2469":{"position":[[320,3]]},"2478":{"position":[[1765,3],[1913,3],[2076,3],[2109,4]]},"2480":{"position":[[961,3]]},"2529":{"position":[[93,3],[452,3],[479,3],[750,3]]},"2531":{"position":[[600,3]]},"2559":{"position":[[714,5]]},"2574":{"position":[[233,3],[292,4],[323,3],[542,3],[628,4],[653,3],[799,3],[1095,3],[1155,3]]},"2576":{"position":[[42,3],[181,4],[636,3],[678,3]]},"2578":{"position":[[33,3],[105,3],[155,3],[187,3],[612,3]]},"2580":{"position":[[39,3],[206,3]]},"2582":{"position":[[49,4],[94,3]]},"2584":{"position":[[128,3],[344,3],[436,3],[1286,3],[1642,3]]},"2586":{"position":[[46,3],[896,3],[1252,3]]},"2598":{"position":[[714,5]]},"2600":{"position":[[182,3]]},"2626":{"position":[[1085,3],[1876,3],[2101,3],[2564,3]]},"2636":{"position":[[759,3]]},"2647":{"position":[[358,3],[786,4],[1028,3],[1073,3]]},"2665":{"position":[[75,4],[146,4],[317,3]]},"2692":{"position":[[1537,3]]},"2720":{"position":[[549,3],[1376,3]]},"2751":{"position":[[61,4]]},"2758":{"position":[[27,3],[91,3],[157,3],[347,3],[474,3]]},"2794":{"position":[[16,3],[313,3]]},"2798":{"position":[[43,3]]},"2800":{"position":[[82,3],[281,3]]},"2802":{"position":[[16,3],[38,3]]},"2804":{"position":[[76,3]]},"2814":{"position":[[48,3]]},"2818":{"position":[[16,3],[78,3]]},"2830":{"position":[[66,3],[79,3]]},"2832":{"position":[[130,3],[155,3]]},"2836":{"position":[[31,3]]},"2845":{"position":[[61,3]]},"2853":{"position":[[71,3],[230,3]]},"2857":{"position":[[172,4]]},"2869":{"position":[[93,3],[124,3]]},"2871":{"position":[[277,3]]},"2887":{"position":[[56,3],[115,3],[264,3]]},"2889":{"position":[[380,3],[408,3],[703,4]]},"2902":{"position":[[84,3]]},"2904":{"position":[[25,3],[37,3]]},"2914":{"position":[[598,3],[1075,5]]},"2916":{"position":[[543,4],[737,3]]},"2918":{"position":[[20,3],[296,3],[408,3],[647,3],[708,3]]},"2920":{"position":[[87,3],[173,3]]},"2922":{"position":[[89,3]]},"2930":{"position":[[219,3],[1213,3]]},"2940":{"position":[[137,3]]},"2952":{"position":[[171,3],[427,3],[917,3]]},"2958":{"position":[[333,3],[2196,3]]},"2968":{"position":[[600,3]]},"2985":{"position":[[1989,3]]},"2987":{"position":[[3358,3],[4178,3],[4548,3]]},"3022":{"position":[[365,3],[946,3],[1029,3],[1178,3]]},"3038":{"position":[[459,4]]},"3044":{"position":[[381,3]]},"3067":{"position":[[95,3],[177,3],[485,3]]},"3073":{"position":[[1087,3],[1112,3]]},"3083":{"position":[[80,3],[166,3]]},"3091":{"position":[[189,3]]},"3103":{"position":[[38,3]]},"3116":{"position":[[71,3],[157,3],[210,3],[314,3]]},"3121":{"position":[[260,3],[353,3],[514,3]]},"3124":{"position":[[75,3]]},"3134":{"position":[[281,3]]},"3136":{"position":[[38,3]]},"3148":{"position":[[900,3]]},"3150":{"position":[[749,3]]},"3153":{"position":[[1452,4],[1519,3]]},"3172":{"position":[[16,3],[59,3]]},"3185":{"position":[[291,3],[318,3],[564,3]]},"3187":{"position":[[92,3]]},"3189":{"position":[[880,3]]},"3204":{"position":[[303,3]]},"3223":{"position":[[650,3],[717,3]]},"3230":{"position":[[694,3]]},"3234":{"position":[[142,4]]},"3236":{"position":[[73,4],[98,3],[321,3]]},"3251":{"position":[[50,3]]},"3255":{"position":[[28,3]]},"3266":{"position":[[493,3]]},"3276":{"position":[[904,3],[947,3]]},"3285":{"position":[[577,3]]},"3288":{"position":[[22,3],[34,3],[233,3],[593,4]]},"3292":{"position":[[647,3]]},"3294":{"position":[[178,3],[1003,3],[1177,3],[1181,4]]},"3296":{"position":[[219,3]]},"3304":{"position":[[21,3]]},"3313":{"position":[[227,3]]},"3317":{"position":[[108,3],[183,3]]},"3357":{"position":[[1076,3],[1088,3],[1100,3],[1104,3],[1192,3],[3186,4]]},"3398":{"position":[[1743,3]]},"3569":{"position":[[991,3]]},"3751":{"position":[[60,3]]},"3795":{"position":[[461,3]]},"3876":{"position":[[918,3]]},"3925":{"position":[[1087,3]]},"3928":{"position":[[2409,3]]},"4005":{"position":[[426,4]]},"4041":{"position":[[201,4]]},"4045":{"position":[[309,4],[422,4]]},"4075":{"position":[[13,3],[80,3]]},"4081":{"position":[[260,3],[1578,3]]},"4083":{"position":[[91,3]]},"4089":{"position":[[151,4]]},"4107":{"position":[[1330,3]]},"4120":{"position":[[53,3],[490,4]]},"4124":{"position":[[133,4]]},"4126":{"position":[[204,3]]},"4128":{"position":[[34,3]]},"4130":{"position":[[75,3],[328,4],[424,3],[482,3]]},"4137":{"position":[[269,3]]},"4185":{"position":[[98,3]]},"4187":{"position":[[96,3],[117,3],[182,4],[295,3]]},"4198":{"position":[[136,4],[473,4],[549,4]]},"4200":{"position":[[25,4],[321,4],[382,4],[637,4],[727,5],[786,4]]},"4202":{"position":[[19,4],[152,3],[419,3],[472,3]]},"4204":{"position":[[19,4],[187,3]]},"4206":{"position":[[36,4]]},"4210":{"position":[[40,4]]},"4222":{"position":[[3852,5]]},"4226":{"position":[[686,4],[1965,4]]},"4244":{"position":[[487,3]]},"4246":{"position":[[476,3]]},"4253":{"position":[[105,4],[318,5]]},"4257":{"position":[[4085,5]]},"4273":{"position":[[21,3]]},"4283":{"position":[[729,3]]},"4291":{"position":[[412,3],[513,3]]},"4300":{"position":[[486,3]]},"4302":{"position":[[493,3],[620,3],[2250,3],[2426,4],[2540,3]]},"4304":{"position":[[176,3]]},"4308":{"position":[[994,3]]},"4321":{"position":[[9,3],[159,3]]},"4329":{"position":[[278,3]]},"4337":{"position":[[93,3],[131,4],[372,3],[401,3]]},"4429":{"position":[[273,3]]},"4442":{"position":[[249,3]]},"4453":{"position":[[249,3]]},"4475":{"position":[[260,3]]},"4479":{"position":[[295,3],[464,3],[497,3],[648,3],[1235,3],[1339,3],[1671,3],[1834,3],[1868,3],[2003,3]]},"4485":{"position":[[1070,3]]},"4489":{"position":[[40,3],[58,3],[942,3]]},"4529":{"position":[[242,5]]},"4535":{"position":[[690,3],[2483,3],[2700,3],[3557,3]]},"4537":{"position":[[976,3],[1084,3],[1145,3],[1448,3],[1509,3]]},"4539":{"position":[[82,3],[327,4],[347,3],[2091,3],[2317,3],[2503,3],[2691,3],[2788,3],[2997,3],[4573,3],[4595,3],[4965,3],[6626,3]]},"4541":{"position":[[76,3],[239,4],[1138,3],[1681,3],[2140,3],[2215,3]]},"4547":{"position":[[580,3],[1461,3],[1558,3],[2845,4],[3146,3],[3257,3]]},"4562":{"position":[[2268,4]]},"4569":{"position":[[30,3],[409,4],[789,4]]},"4572":{"position":[[303,3],[323,4]]},"4574":{"position":[[433,3]]},"4578":{"position":[[15,3],[154,3],[225,3],[307,4],[412,3],[493,3]]},"4580":{"position":[[14,4],[1665,4],[1739,3],[2008,3],[2056,3],[2280,3],[2429,4],[2579,4],[2596,3]]},"4582":{"position":[[86,3],[296,3]]},"4593":{"position":[[515,3],[1711,3],[2061,3],[2690,3],[3795,5],[4471,3],[5033,4],[5251,4]]},"4604":{"position":[[450,3]]},"4608":{"position":[[776,3]]},"4614":{"position":[[904,3],[986,3],[1082,3],[1280,3],[1361,3],[1487,3]]},"4618":{"position":[[149,3],[487,3],[720,3]]},"4620":{"position":[[99,3],[294,3]]},"4629":{"position":[[91,3]]},"4660":{"position":[[1061,3]]},"4662":{"position":[[457,3],[502,3],[1761,3]]},"4669":{"position":[[42,3]]},"4674":{"position":[[52,3]]},"4679":{"position":[[43,3],[98,3]]},"4688":{"position":[[119,3]]},"4691":{"position":[[414,4]]},"4713":{"position":[[448,3]]},"4719":{"position":[[4,3],[103,3]]},"4724":{"position":[[422,3]]},"4763":{"position":[[307,3]]},"4826":{"position":[[2202,3]]},"4849":{"position":[[1158,4]]},"4872":{"position":[[612,3],[930,3],[1049,3]]}}}],["api'",{"_index":3834,"t":{"936":{"position":[[14,5]]},"1827":{"position":[[14,5]]},"2574":{"position":[[311,5],[935,6],[968,5]]},"2584":{"position":[[1490,6],[1610,5]]},"2586":{"position":[[1100,6],[1220,5]]},"2914":{"position":[[122,6]]},"2960":{"position":[[14,5]]},"4614":{"position":[[1044,5]]}}}],["api.example.org",{"_index":11954,"t":{"4849":{"position":[[1171,17]]}}}],["api.in",{"_index":7328,"t":{"2037":{"position":[[945,6],[1030,6],[1702,6]]}}}],["api.k8s.scs.commun",{"_index":9060,"t":{"2758":{"position":[[178,22]]}}}],["api.k8s.scs.community/compon",{"_index":9100,"t":{"2776":{"position":[[28,32]]},"2778":{"position":[[158,32]]},"2910":{"position":[[263,32]]}}}],["api.k8s.scs.community/components/3ebed33a",{"_index":9116,"t":{"2780":{"position":[[28,41]]}}}],["api.k8s.scs.community/impacttyp",{"_index":9072,"t":{"2764":{"position":[[28,33]]},"2766":{"position":[[166,33]]}}}],["api.k8s.scs.community/impacttypes/52d178d2",{"_index":9092,"t":{"2768":{"position":[[28,42]]}}}],["api.k8s.scs.community/incid",{"_index":9138,"t":{"2784":{"position":[[366,31]]}}}],["api.k8s.scs.community/incidents/09f471bb",{"_index":9141,"t":{"2786":{"position":[[28,40]]},"2788":{"position":[[28,40]]},"2790":{"position":[[249,40]]},"2792":{"position":[[28,40]]}}}],["api.k8s.scs.community/phas",{"_index":9066,"t":{"2760":{"position":[[28,28]]},"2762":{"position":[[174,28]]}}}],["api.k8s.scs.community/sever",{"_index":9095,"t":{"2770":{"position":[[28,32]]},"2772":{"position":[[160,32]]}}}],["api.k8s.scs.community/severities/test",{"_index":9098,"t":{"2774":{"position":[[28,37]]}}}],["api.localhost",{"_index":9332,"t":{"2934":{"position":[[425,13]]}}}],["api.osism.xyz",{"_index":5051,"t":{"1222":{"position":[[996,16]]},"1230":{"position":[[296,13]]}}}],["api.scs.commun",{"_index":8683,"t":{"2602":{"position":[[1061,17]]},"3288":{"position":[[433,17]]}}}],["api.scs.community/v1alpha1",{"_index":8691,"t":{"2602":{"position":[[1570,26],[1726,26]]}}}],["api.testbed.osism.com",{"_index":5202,"t":{"1252":{"position":[[3343,21]]}}}],["api.testbed.osism.xyz",{"_index":5169,"t":{"1242":{"position":[[226,21],[345,22]]},"2192":{"position":[[1389,21]]}}}],["api.zone1.landscape.example.com",{"_index":5822,"t":{"1346":{"position":[[1199,31]]}}}],["api/$xpkg:$vers",{"_index":8672,"t":{"2602":{"position":[[289,18]]}}}],["api/api",{"_index":9189,"t":{"2824":{"position":[[98,7]]}}}],["api/api.env",{"_index":9185,"t":{"2822":{"position":[[34,11]]}}}],["api/cli",{"_index":9762,"t":{"3119":{"position":[[590,7]]}}}],["api/docs/exampl",{"_index":9277,"t":{"2910":{"position":[[458,16]]}}}],["api/main.go",{"_index":9166,"t":{"2800":{"position":[[102,11]]}}}],["api/poc",{"_index":9918,"t":{"3288":{"position":[[685,7]]}}}],["api1",{"_index":11263,"t":{"4202":{"position":[[834,5]]}}}],["api15",{"_index":11346,"t":{"4226":{"position":[[2569,5]]}}}],["api:latest",{"_index":9163,"t":{"2798":{"position":[[322,10]]}}}],["api_interfac",{"_index":5101,"t":{"1226":{"position":[[4990,14]]},"1299":{"position":[[157,13],[218,13],[354,13],[489,13],[531,13]]}}}],["api_interface_address",{"_index":6436,"t":{"1561":{"position":[[712,21]]}}}],["api_monitor.sh",{"_index":3839,"t":{"936":{"position":[[498,14]]},"938":{"position":[[340,14],[878,16],[2042,14],[2822,14]]},"940":{"position":[[10,14],[380,14],[1585,14]]},"942":{"position":[[18,14],[1893,16],[2170,16],[2284,16],[2368,16]]},"944":{"position":[[47,15]]},"946":{"position":[[34,14],[405,14]]},"949":{"position":[[15,14],[1043,15]]},"951":{"position":[[0,14],[318,14],[805,15]]},"959":{"position":[[123,14]]},"976":{"position":[[220,14]]},"978":{"position":[[80,14],[1426,14],[1887,14]]},"1827":{"position":[[498,14]]},"1829":{"position":[[340,14],[878,16],[2042,14],[2822,14]]},"1831":{"position":[[10,14],[380,14],[1585,14]]},"1833":{"position":[[18,14],[1893,16],[2170,16],[2284,16],[2368,16]]},"1835":{"position":[[47,15]]},"1837":{"position":[[34,14],[405,14]]},"1840":{"position":[[15,14],[1043,15]]},"1842":{"position":[[0,14],[318,14],[805,15]]},"1850":{"position":[[123,14]]},"1867":{"position":[[220,14]]},"1869":{"position":[[80,14],[1426,14],[1887,14]]},"2960":{"position":[[498,14]]},"2962":{"position":[[340,14],[878,16],[2042,14],[2822,14]]},"2964":{"position":[[10,14],[380,14],[1585,14]]},"2966":{"position":[[18,14],[1893,16],[2170,16],[2284,16],[2368,16]]},"2968":{"position":[[47,15]]},"2970":{"position":[[34,14],[405,14]]},"2973":{"position":[[15,14],[1043,15]]},"2975":{"position":[[0,14],[318,14],[805,15]]},"2983":{"position":[[123,14]]},"3000":{"position":[[220,14]]},"3002":{"position":[[80,14],[1426,14],[1887,14]]}}}],["apigroup",{"_index":8682,"t":{"2602":{"position":[[1048,10],[1315,9]]}}}],["apimon",{"_index":3925,"t":{"942":{"position":[[3466,6],[3703,6],[3733,6]]},"944":{"position":[[1101,6],[1326,7]]},"946":{"position":[[227,6],[262,6]]},"1833":{"position":[[3466,6],[3703,6],[3733,6]]},"1835":{"position":[[1101,6],[1326,7]]},"1837":{"position":[[227,6],[262,6]]},"2966":{"position":[[3466,6],[3703,6],[3733,6]]},"2968":{"position":[[1101,6],[1326,7]]},"2970":{"position":[[227,6],[262,6]]}}}],["apimonitor",{"_index":4103,"t":{"978":{"position":[[1013,10]]},"1869":{"position":[[1013,10]]},"3002":{"position":[[1013,10]]}}}],["apimonitor_[0",{"_index":3897,"t":{"942":{"position":[[948,14],[1161,14],[1236,14],[1310,14],[1385,14],[1465,14],[1539,14],[1621,14]]},"1833":{"position":[[948,14],[1161,14],[1236,14],[1310,14],[1385,14],[1465,14],[1539,14],[1621,14]]},"2966":{"position":[[948,14],[1161,14],[1236,14],[1310,14],[1385,14],[1465,14],[1539,14],[1621,14]]}}}],["apimonitor_timestamp",{"_index":3859,"t":{"938":{"position":[[2066,20]]},"1829":{"position":[[2066,20]]},"2962":{"position":[[2066,20]]}}}],["apimonitor_timestamp.log",{"_index":3953,"t":{"951":{"position":[[47,25]]},"1842":{"position":[[47,25]]},"2975":{"position":[[47,25]]}}}],["apimonitor_xxxxx_jh.pem",{"_index":4098,"t":{"978":{"position":[[775,23]]},"1869":{"position":[[775,23]]},"3002":{"position":[[775,23]]}}}],["apimonitor_xxxxx_vm.pem",{"_index":4100,"t":{"978":{"position":[[924,23]]},"1869":{"position":[[924,23]]},"3002":{"position":[[924,23]]}}}],["apiserv",{"_index":2767,"t":{"557":{"position":[[2536,10],[3407,10]]},"590":{"position":[[590,9]]},"1338":{"position":[[8,9]]},"4537":{"position":[[1041,10]]}}}],["apiserver_loadbalanc",{"_index":2759,"t":{"557":{"position":[[2252,22],[3431,22],[4217,22],[4623,22]]}}}],["apiserverurl",{"_index":9300,"t":{"2930":{"position":[[191,12]]},"2934":{"position":[[570,12]]}}}],["apivers",{"_index":2414,"t":{"465":{"position":[[117,11]]},"518":{"position":[[790,11]]},"551":{"position":[[2196,11],[2763,11]]},"555":{"position":[[0,11]]},"586":{"position":[[749,11],[1006,11],[1156,11]]},"588":{"position":[[848,11]]},"622":{"position":[[164,11],[300,11]]},"661":{"position":[[101,11],[239,11],[313,10]]},"705":{"position":[[1171,11]]},"2602":{"position":[[348,11],[411,11],[626,11],[957,11],[1113,11],[1199,11],[1558,11],[1714,11]]},"2740":{"position":[[846,11]]},"4489":{"position":[[793,11]]},"4853":{"position":[[65,11]]},"4877":{"position":[[403,11],[518,11],[916,11]]}}}],["api’",{"_index":4416,"t":{"1056":{"position":[[1512,5]]}}}],["app",{"_index":1767,"t":{"255":{"position":[[254,4]]},"258":{"position":[[162,3]]},"368":{"position":[[2496,3]]},"2121":{"position":[[363,3],[392,3],[624,3]]},"2130":{"position":[[123,3],[227,3]]},"2333":{"position":[[168,3]]},"2339":{"position":[[420,3]]},"2400":{"position":[[168,3]]},"2406":{"position":[[420,3]]},"2503":{"position":[[447,3]]},"2557":{"position":[[307,3]]},"2839":{"position":[[61,3],[157,3]]},"2879":{"position":[[178,3]]},"2883":{"position":[[59,3]]},"2914":{"position":[[644,3]]},"4835":{"position":[[20,4],[112,4]]},"4839":{"position":[[479,3]]},"4847":{"position":[[67,4],[156,4]]},"4859":{"position":[[10,3]]}}}],["app'",{"_index":11976,"t":{"4859":{"position":[[99,5]]}}}],["app_credential_cloud_conf",{"_index":2194,"t":{"368":{"position":[[2677,25],[3441,25]]}}}],["app_id",{"_index":7642,"t":{"2123":{"position":[[690,7]]}}}],["app_key",{"_index":7643,"t":{"2123":{"position":[[720,8]]}}}],["appar",{"_index":9868,"t":{"3218":{"position":[[133,8]]}}}],["appcred_id",{"_index":3821,"t":{"934":{"position":[[1338,10]]},"1825":{"position":[[1338,10]]},"2958":{"position":[[1338,10]]}}}],["appcred_secret",{"_index":3822,"t":{"934":{"position":[[1380,16]]},"1825":{"position":[[1380,16]]},"2958":{"position":[[1380,16]]}}}],["appctl",{"_index":7048,"t":{"1704":{"position":[[1492,6],[2168,6]]}}}],["appear",{"_index":1160,"t":{"173":{"position":[[2110,7]]},"199":{"position":[[708,11]]},"530":{"position":[[1235,7]]},"963":{"position":[[3233,7]]},"1619":{"position":[[656,7]]},"1854":{"position":[[3233,7]]},"1950":{"position":[[656,7]]},"2065":{"position":[[656,6]]},"2508":{"position":[[693,9]]},"2930":{"position":[[834,7]]},"2987":{"position":[[3233,7]]},"3034":{"position":[[296,8]]},"3038":{"position":[[354,7]]},"3706":{"position":[[1799,6]]},"3761":{"position":[[691,7],[852,6],[1187,6]]},"3763":{"position":[[507,7]]},"3971":{"position":[[444,7]]},"3990":{"position":[[1387,7]]},"4109":{"position":[[3871,6]]},"4222":{"position":[[3897,9]]}}}],["append",{"_index":1735,"t":{"249":{"position":[[1904,6]]},"368":{"position":[[6144,9]]},"442":{"position":[[169,6]]},"871":{"position":[[428,8]]},"873":{"position":[[500,8]]},"1772":{"position":[[428,8]]},"1774":{"position":[[500,8]]},"2117":{"position":[[2344,7],[2577,7]]},"2163":{"position":[[4006,6]]},"2171":{"position":[[2314,9]]},"3608":{"position":[[200,6]]},"3706":{"position":[[295,8]]},"3716":{"position":[[99,8]]},"3799":{"position":[[295,8]]},"3809":{"position":[[76,8]]},"4667":{"position":[[13979,8]]}}}],["append_priv",{"_index":6440,"t":{"1561":{"position":[[965,13]]}}}],["append_timestamp_to_batch_nam",{"_index":8933,"t":{"2703":{"position":[[645,31]]}}}],["appendix",{"_index":8356,"t":{"2327":{"position":[[420,8]]},"2343":{"position":[[1326,8]]},"2394":{"position":[[420,8]]},"2410":{"position":[[1326,8]]},"4667":{"position":[[13026,8]]}}}],["appl",{"_index":1656,"t":{"233":{"position":[[76,6]]}}}],["apple'",{"_index":353,"t":{"37":{"position":[[672,7]]}}}],["appli",{"_index":134,"t":{"19":{"position":[[94,5]]},"151":{"position":[[267,7]]},"175":{"position":[[40,5],[239,5],[602,7]]},"205":{"position":[[485,5]]},"293":{"position":[[616,7]]},"295":{"position":[[1752,5]]},"382":{"position":[[385,7],[652,8],[736,7]]},"391":{"position":[[122,5],[421,5]]},"393":{"position":[[194,7]]},"395":{"position":[[37,8],[91,7]]},"397":{"position":[[46,8]]},"401":{"position":[[627,7],[1014,7],[1306,7]]},"403":{"position":[[207,8],[327,7]]},"417":{"position":[[194,8],[404,7],[577,7],[753,7],[876,8],[1326,5]]},"421":{"position":[[1032,7]]},"423":{"position":[[836,5]]},"434":{"position":[[585,7]]},"452":{"position":[[61,7]]},"463":{"position":[[1228,8]]},"475":{"position":[[62,5],[235,5]]},"510":{"position":[[141,5],[301,5],[367,7]]},"524":{"position":[[199,7],[329,7],[452,7],[929,7],[1059,7],[1182,7]]},"530":{"position":[[621,5],[696,8],[1791,7],[2894,7]]},"551":{"position":[[1271,7]]},"580":{"position":[[232,5],[320,5],[498,5],[549,5],[639,5],[829,5]]},"586":{"position":[[1396,5]]},"588":{"position":[[539,5],[746,8],[1503,5]]},"641":{"position":[[146,5]]},"666":{"position":[[146,5]]},"688":{"position":[[10,5],[414,5],[448,5]]},"690":{"position":[[77,5],[116,5]]},"692":{"position":[[793,5]]},"694":{"position":[[282,5]]},"705":{"position":[[1434,5],[1463,5]]},"747":{"position":[[514,5]]},"753":{"position":[[0,5],[60,5]]},"826":{"position":[[43,7]]},"828":{"position":[[277,7]]},"875":{"position":[[211,7]]},"912":{"position":[[5857,8]]},"914":{"position":[[21,7],[266,5],[348,5]]},"930":{"position":[[593,8]]},"963":{"position":[[3173,6],[3212,6]]},"1142":{"position":[[422,5]]},"1144":{"position":[[185,7],[231,7],[260,5]]},"1171":{"position":[[932,5]]},"1173":{"position":[[638,5],[719,5]]},"1175":{"position":[[3167,5],[3219,5],[3342,5],[3694,5],[3863,5],[4487,5],[4571,5]]},"1177":{"position":[[651,5],[691,5],[1979,5],[4254,5],[4294,5],[5450,5]]},"1179":{"position":[[1166,5],[2229,5]]},"1181":{"position":[[449,5]]},"1183":{"position":[[1155,5],[1173,5]]},"1185":{"position":[[1988,5],[2105,5]]},"1234":{"position":[[176,5]]},"1236":{"position":[[540,5],[1007,5]]},"1246":{"position":[[1205,5]]},"1248":{"position":[[1549,5]]},"1250":{"position":[[600,5]]},"1252":{"position":[[3749,5]]},"1259":{"position":[[1206,5],[1386,5]]},"1266":{"position":[[2431,7],[2558,7],[2610,6],[2805,5],[2849,5]]},"1305":{"position":[[740,5]]},"1314":{"position":[[201,5]]},"1344":{"position":[[343,5]]},"1371":{"position":[[558,5],[623,5]]},"1373":{"position":[[713,7],[1100,5],[1165,5]]},"1383":{"position":[[1677,5],[1712,5]]},"1397":{"position":[[554,5]]},"1433":{"position":[[1256,5]]},"1443":{"position":[[418,5]]},"1455":{"position":[[18,7],[37,5],[62,7]]},"1457":{"position":[[540,7],[676,5],[1631,5],[2016,5],[2198,5],[2685,5],[2834,5],[2939,5],[3071,5],[3243,5],[3707,5],[3736,5],[3888,5],[4060,5],[4128,5],[4182,5]]},"1474":{"position":[[907,5]]},"1503":{"position":[[951,5],[998,5],[1045,5],[1140,5],[1190,5],[1419,5],[1461,5],[1484,5],[1575,5],[2352,5],[2870,5],[2943,5]]},"1505":{"position":[[379,5],[439,5],[455,5],[684,5],[705,5],[776,5],[795,5],[851,5]]},"1507":{"position":[[309,5]]},"1509":{"position":[[643,5]]},"1513":{"position":[[335,5],[362,5],[395,5],[421,5],[451,5],[480,5],[792,5],[917,5],[1112,5],[1140,5],[1171,5],[1200,5]]},"1515":{"position":[[220,5],[276,5]]},"1517":{"position":[[68,5],[193,5]]},"1519":{"position":[[25,5],[57,5],[448,5],[472,5]]},"1521":{"position":[[214,5],[245,5],[279,5],[310,5],[341,5],[369,5]]},"1523":{"position":[[503,5],[540,5],[569,5],[597,5],[624,5],[653,5],[683,5],[715,5],[745,5],[774,5],[801,5],[828,5],[856,5],[881,5],[906,5],[931,5],[964,5],[1002,5],[1030,5],[2268,5],[2296,5]]},"1525":{"position":[[1030,5],[1090,5],[1172,5],[1273,5],[2263,5]]},"1529":{"position":[[299,5],[332,5],[389,5]]},"1531":{"position":[[314,5]]},"1540":{"position":[[6,5]]},"1542":{"position":[[6,5]]},"1544":{"position":[[293,5],[484,5]]},"1552":{"position":[[290,5],[738,5],[968,5],[1174,5],[1375,5]]},"1555":{"position":[[162,5],[247,5],[1164,5]]},"1557":{"position":[[33,5],[208,5]]},"1559":{"position":[[117,5]]},"1561":{"position":[[1195,5],[1226,5]]},"1600":{"position":[[180,5]]},"1605":{"position":[[1376,5]]},"1655":{"position":[[9,5]]},"1657":{"position":[[10,5],[208,5]]},"1659":{"position":[[8,5]]},"1661":{"position":[[858,5],[984,5]]},"1665":{"position":[[221,5]]},"1694":{"position":[[754,5],[1199,5],[1681,5]]},"1704":{"position":[[1880,8],[2559,8]]},"1707":{"position":[[75,5]]},"1709":{"position":[[213,5]]},"1711":{"position":[[28,5],[84,5],[185,5],[257,5],[284,5],[315,5],[370,5],[402,5],[426,5],[489,5],[538,5],[600,5],[665,5],[735,5],[800,5],[860,5],[923,5]]},"1713":{"position":[[135,5],[2471,5],[2517,5],[2577,5],[2646,5],[2729,5]]},"1740":{"position":[[82,5]]},"1776":{"position":[[211,7]]},"1796":{"position":[[5857,8]]},"1798":{"position":[[21,7],[266,5],[348,5]]},"1821":{"position":[[593,8]]},"1854":{"position":[[3173,6],[3212,6]]},"1906":{"position":[[175,5]]},"1912":{"position":[[204,8],[219,5]]},"1914":{"position":[[205,8],[220,5]]},"2045":{"position":[[192,5]]},"2048":{"position":[[2063,8],[2078,5],[2105,5],[2576,5],[2600,5],[2616,5],[3485,5]]},"2086":{"position":[[268,7]]},"2094":{"position":[[225,8]]},"2119":{"position":[[260,8]]},"2146":{"position":[[1011,5]]},"2155":{"position":[[3332,5]]},"2159":{"position":[[6,5],[59,5]]},"2163":{"position":[[3755,5]]},"2165":{"position":[[1948,5]]},"2167":{"position":[[171,5],[469,5],[496,5],[539,5],[572,5],[614,5],[640,5],[679,5],[709,5],[751,5],[780,5],[820,5],[848,5]]},"2169":{"position":[[82,5],[113,5],[158,5],[189,5],[220,5],[248,5]]},"2171":{"position":[[2115,5],[2481,5],[2648,5]]},"2173":{"position":[[25,5],[57,5],[453,5],[477,5]]},"2184":{"position":[[5519,5],[5538,5],[5563,5],[5586,5],[6579,5]]},"2207":{"position":[[954,5],[1177,5],[1235,5]]},"2211":{"position":[[2364,5]]},"2214":{"position":[[194,5]]},"2231":{"position":[[227,5],[264,5],[293,5],[332,5],[359,5],[399,5],[429,5],[472,5],[502,5],[542,5],[569,5],[607,5],[635,5],[671,5],[696,5],[732,5],[760,5],[1293,5],[1321,5]]},"2283":{"position":[[797,5]]},"2287":{"position":[[578,7]]},"2297":{"position":[[797,5]]},"2301":{"position":[[578,7]]},"2329":{"position":[[32,5]]},"2351":{"position":[[27,7]]},"2368":{"position":[[42,5],[194,5]]},"2396":{"position":[[32,5]]},"2418":{"position":[[27,7]]},"2439":{"position":[[179,7]]},"2447":{"position":[[490,5]]},"2512":{"position":[[377,5],[457,5]]},"2525":{"position":[[895,7]]},"2569":{"position":[[207,5],[320,5]]},"2604":{"position":[[361,5]]},"2624":{"position":[[487,5]]},"2628":{"position":[[427,5]]},"2636":{"position":[[0,5],[65,5],[96,5],[128,5]]},"2644":{"position":[[718,5],[751,5],[774,5]]},"2647":{"position":[[2209,8]]},"2649":{"position":[[1446,5],[3520,8]]},"2663":{"position":[[99,7]]},"2672":{"position":[[718,5],[751,5],[774,5]]},"2674":{"position":[[438,8]]},"2678":{"position":[[444,5],[503,5],[552,5]]},"2703":{"position":[[589,5]]},"2740":{"position":[[1050,5],[1107,5],[1143,5]]},"2756":{"position":[[978,5],[1026,5],[1778,7]]},"2863":{"position":[[159,5],[194,5]]},"2954":{"position":[[593,8]]},"2987":{"position":[[3173,6],[3212,6]]},"3168":{"position":[[255,5]]},"3248":{"position":[[128,8]]},"3285":{"position":[[312,5]]},"3296":{"position":[[848,5]]},"3546":{"position":[[40,7]]},"3712":{"position":[[1557,7]]},"3932":{"position":[[423,5]]},"3960":{"position":[[156,6]]},"3978":{"position":[[73,7]]},"3980":{"position":[[47,7]]},"3984":{"position":[[830,5],[1035,8]]},"4041":{"position":[[1107,7]]},"4043":{"position":[[541,7],[620,7]]},"4045":{"position":[[1399,5]]},"4047":{"position":[[29,7],[489,7],[543,5]]},"4073":{"position":[[360,7]]},"4081":{"position":[[1377,5]]},"4094":{"position":[[134,5]]},"4098":{"position":[[777,7]]},"4100":{"position":[[435,6]]},"4102":{"position":[[263,7]]},"4137":{"position":[[96,5]]},"4153":{"position":[[271,5]]},"4222":{"position":[[2191,7]]},"4230":{"position":[[2435,7]]},"4273":{"position":[[488,5]]},"4275":{"position":[[156,7]]},"4302":{"position":[[5118,7]]},"4308":{"position":[[622,7],[702,5]]},"4410":{"position":[[403,5]]},"4473":{"position":[[238,5]]},"4489":{"position":[[742,8]]},"4506":{"position":[[543,7]]},"4539":{"position":[[204,7]]},"4543":{"position":[[281,5],[1823,7]]},"4580":{"position":[[963,6]]},"4610":{"position":[[119,8]]},"4665":{"position":[[157,7],[255,7]]},"4667":{"position":[[28,7]]},"4669":{"position":[[0,8],[880,8]]},"4839":{"position":[[1202,5],[1257,7]]},"4853":{"position":[[532,5]]},"4855":{"position":[[137,5]]},"4877":{"position":[[262,8]]}}}],["applianc",{"_index":7305,"t":{"2029":{"position":[[331,9],[722,9]]},"3191":{"position":[[102,10]]}}}],["applic",{"_index":1209,"t":{"177":{"position":[[559,12],[918,12],[1011,11]]},"197":{"position":[[1059,10]]},"370":{"position":[[320,13]]},"374":{"position":[[179,13]]},"378":{"position":[[738,12]]},"423":{"position":[[635,13]]},"425":{"position":[[536,12]]},"528":{"position":[[105,11],[238,11]]},"533":{"position":[[406,11]]},"541":{"position":[[148,12],[1359,12],[1451,11]]},"557":{"position":[[3856,11]]},"701":{"position":[[549,11],[994,11]]},"814":{"position":[[543,11]]},"854":{"position":[[309,12]]},"930":{"position":[[327,11]]},"934":{"position":[[1066,11]]},"1056":{"position":[[244,12],[2060,13],[2301,11]]},"1064":{"position":[[2483,13]]},"1171":{"position":[[319,12]]},"1455":{"position":[[2036,10]]},"1633":{"position":[[85,11],[160,11],[208,11]]},"1694":{"position":[[267,11]]},"1821":{"position":[[327,11]]},"1825":{"position":[[1066,11]]},"1964":{"position":[[85,11],[160,11],[208,11]]},"2121":{"position":[[105,12]]},"2184":{"position":[[1642,11],[1695,11],[1879,11],[1986,11],[2241,11]]},"2295":{"position":[[183,10]]},"2309":{"position":[[183,10]]},"2478":{"position":[[353,12]]},"2487":{"position":[[56,13],[535,11],[583,11],[820,12],[1040,11]]},"2503":{"position":[[366,13]]},"2510":{"position":[[408,11],[487,12]]},"2512":{"position":[[208,11]]},"2525":{"position":[[274,13],[772,13]]},"2527":{"position":[[56,13],[198,11]]},"2531":{"position":[[64,12],[222,12],[326,11],[448,11],[573,11],[740,12],[946,11],[1138,12],[1284,12],[1443,12]]},"2535":{"position":[[525,11]]},"2555":{"position":[[142,13],[230,11]]},"2557":{"position":[[62,11],[144,13],[376,11],[458,11]]},"2574":{"position":[[421,10]]},"2592":{"position":[[160,12]]},"2714":{"position":[[462,12]]},"2732":{"position":[[123,11]]},"2749":{"position":[[287,11]]},"2794":{"position":[[384,12]]},"2826":{"position":[[19,12]]},"2879":{"position":[[293,11]]},"2883":{"position":[[205,11],[525,11]]},"2912":{"position":[[79,11]]},"2916":{"position":[[166,12],[418,11],[642,11]]},"2922":{"position":[[50,11],[157,12]]},"2930":{"position":[[389,11]]},"2934":{"position":[[862,11]]},"2940":{"position":[[44,13],[461,12],[525,12]]},"2954":{"position":[[327,11]]},"2958":{"position":[[1066,11]]},"3067":{"position":[[590,11]]},"3223":{"position":[[279,12]]},"3268":{"position":[[25,11]]},"3348":{"position":[[53,11]]},"3378":{"position":[[240,11]]},"3381":{"position":[[1580,11],[1872,11],[2116,11]]},"3533":{"position":[[395,10]]},"3537":{"position":[[137,12]]},"3653":{"position":[[782,13]]},"3665":{"position":[[522,12]]},"3690":{"position":[[681,13]]},"3702":{"position":[[594,12]]},"3731":{"position":[[1956,11]]},"3759":{"position":[[54,11]]},"3765":{"position":[[74,13]]},"3777":{"position":[[782,13]]},"3789":{"position":[[594,12]]},"3925":{"position":[[222,11]]},"3928":{"position":[[4190,11],[5471,12],[5589,11]]},"4075":{"position":[[17,11]]},"4113":{"position":[[1983,11],[2035,11],[2158,11]]},"4273":{"position":[[145,12]]},"4300":{"position":[[764,10]]},"4310":{"position":[[2222,11]]},"4317":{"position":[[218,11]]},"4333":{"position":[[433,11]]},"4376":{"position":[[1047,12],[1114,11]]},"4506":{"position":[[607,14]]},"4537":{"position":[[1158,12],[1522,12]]},"4541":{"position":[[517,12]]},"4593":{"position":[[4810,13]]},"4610":{"position":[[304,10]]},"4612":{"position":[[444,10]]},"4632":{"position":[[3097,12]]},"4634":{"position":[[221,12]]},"4654":{"position":[[351,12],[463,11],[663,12]]},"4656":{"position":[[196,12],[262,12],[452,12]]},"4658":{"position":[[528,12]]},"4660":{"position":[[16,11],[460,11],[1163,13],[2567,11],[2749,11],[2955,11]]},"4667":{"position":[[13680,10]]},"4674":{"position":[[251,10]]},"4679":{"position":[[16,11]]},"4722":{"position":[[217,12],[746,11]]},"4829":{"position":[[136,11],[397,12]]}}}],["application'",{"_index":8535,"t":{"2487":{"position":[[1194,13]]}}}],["application/json",{"_index":8751,"t":{"2626":{"position":[[1143,17],[1930,17],[2167,17]]},"2762":{"position":[[86,17]]},"2766":{"position":[[88,17]]},"2772":{"position":[[84,17]]},"2778":{"position":[[84,17]]},"2784":{"position":[[86,17]]},"2790":{"position":[[86,17]]},"2910":{"position":[[189,17]]}}}],["application/octet",{"_index":8370,"t":{"2341":{"position":[[454,18]]},"2360":{"position":[[934,18]]},"2408":{"position":[[454,18]]},"2427":{"position":[[934,18]]}}}],["application/x",{"_index":9261,"t":{"2908":{"position":[[99,13]]}}}],["application_credential_id",{"_index":2860,"t":{"584":{"position":[[290,26]]},"934":{"position":[[1311,26]]},"1825":{"position":[[1311,26]]},"2184":{"position":[[2078,26]]},"2602":{"position":[[809,28]]},"2725":{"position":[[1463,26]]},"2958":{"position":[[1311,26]]},"3381":{"position":[[511,26]]},"3384":{"position":[[1114,26],[1141,27]]}}}],["application_credential_secret",{"_index":2861,"t":{"584":{"position":[[320,30]]},"934":{"position":[[1349,30]]},"1825":{"position":[[1349,30]]},"2184":{"position":[[2108,30],[2359,30]]},"2602":{"position":[[845,32]]},"2725":{"position":[[1490,30]]},"2958":{"position":[[1349,30]]},"3381":{"position":[[577,30]]},"3384":{"position":[[1169,30],[1200,31]]}}}],["application_nam",{"_index":6575,"t":{"1633":{"position":[[116,18]]},"1964":{"position":[[116,18]]}}}],["appoint",{"_index":1753,"t":{"253":{"position":[[461,12]]},"2439":{"position":[[438,7]]},"2453":{"position":[[261,7]]},"2467":{"position":[[320,7]]}}}],["appreci",{"_index":470,"t":{"59":{"position":[[366,12]]},"345":{"position":[[184,10]]},"3022":{"position":[[640,10]]},"3110":{"position":[[3,10]]},"3142":{"position":[[3,10]]},"3174":{"position":[[3,10]]},"3212":{"position":[[3,10]]},"3270":{"position":[[3,10]]},"3319":{"position":[[3,10]]},"3340":{"position":[[3,10]]}}}],["approach",{"_index":566,"t":{"78":{"position":[[72,8]]},"197":{"position":[[550,8]]},"329":{"position":[[30,8]]},"382":{"position":[[218,8]]},"421":{"position":[[207,8]]},"423":{"position":[[872,8]]},"427":{"position":[[254,8]]},"468":{"position":[[73,8]]},"533":{"position":[[262,8]]},"543":{"position":[[2929,8]]},"545":{"position":[[1229,8]]},"549":{"position":[[1481,8]]},"551":{"position":[[154,8],[1487,8],[3129,8]]},"595":{"position":[[128,9]]},"1056":{"position":[[674,8],[2195,8]]},"1064":{"position":[[231,8],[2343,8]]},"1067":{"position":[[2343,8]]},"1413":{"position":[[75,10]]},"2234":{"position":[[199,8]]},"2489":{"position":[[1081,9],[1259,9]]},"2531":{"position":[[1387,8]]},"2549":{"position":[[231,8]]},"2584":{"position":[[489,11]]},"2586":{"position":[[99,11]]},"2714":{"position":[[1054,10]]},"2716":{"position":[[4,8]]},"2749":{"position":[[44,8]]},"3014":{"position":[[60,8]]},"3091":{"position":[[247,8]]},"3119":{"position":[[76,8]]},"3148":{"position":[[758,8]]},"3223":{"position":[[98,8]]},"3279":{"position":[[447,8]]},"3296":{"position":[[118,9]]},"3348":{"position":[[773,8]]},"3402":{"position":[[53,8]]},"3502":{"position":[[1050,8]]},"3549":{"position":[[399,8],[673,8]]},"3565":{"position":[[41,9]]},"3573":{"position":[[621,8]]},"3706":{"position":[[348,8]]},"3799":{"position":[[348,8]]},"3829":{"position":[[2632,8]]},"3932":{"position":[[408,8]]},"3956":{"position":[[127,10]]},"3966":{"position":[[91,10]]},"3968":{"position":[[47,9],[467,8]]},"4045":{"position":[[449,8]]},"4124":{"position":[[742,8],[1901,8],[2442,8]]},"4148":{"position":[[57,8],[154,9]]},"4224":{"position":[[325,8]]},"4228":{"position":[[309,8]]},"4257":{"position":[[3570,8]]},"4277":{"position":[[20,10],[155,10]]},"4283":{"position":[[748,8]]},"4289":{"position":[[135,10],[529,11]]},"4291":{"position":[[1786,8],[2469,8],[2644,10]]},"4294":{"position":[[127,9]]},"4302":{"position":[[3500,8]]},"4304":{"position":[[2355,8]]},"4313":{"position":[[467,8],[970,8],[1096,8],[1306,10]]},"4327":{"position":[[138,8],[722,9],[984,11]]},"4433":{"position":[[717,10]]},"4510":{"position":[[14,10],[167,11]]},"4516":{"position":[[940,8],[1510,8],[1543,8]]},"4520":{"position":[[88,9],[683,9]]},"4522":{"position":[[99,11],[930,9],[957,8],[1764,8]]},"4535":{"position":[[2208,8]]},"4541":{"position":[[2241,8]]},"4562":{"position":[[5198,8]]},"4593":{"position":[[5998,8]]},"4614":{"position":[[687,8]]},"4632":{"position":[[469,8]]},"4643":{"position":[[3,8]]},"4724":{"position":[[426,8]]},"4730":{"position":[[133,9]]},"4801":{"position":[[491,8]]},"4826":{"position":[[4110,8]]}}}],["appropri",{"_index":1719,"t":{"249":{"position":[[517,11]]},"530":{"position":[[1414,13]]},"543":{"position":[[2573,11]]},"602":{"position":[[266,11]]},"705":{"position":[[48,11]]},"738":{"position":[[48,11]]},"824":{"position":[[526,11]]},"961":{"position":[[950,11]]},"1244":{"position":[[732,11],[854,11]]},"1301":{"position":[[399,11]]},"1580":{"position":[[71,11]]},"1852":{"position":[[950,11]]},"1923":{"position":[[71,11]]},"2057":{"position":[[78,11]]},"2211":{"position":[[353,11]]},"2285":{"position":[[1072,11]]},"2299":{"position":[[1072,11]]},"2325":{"position":[[371,11]]},"2376":{"position":[[323,11]]},"2392":{"position":[[371,11]]},"2516":{"position":[[269,11]]},"2740":{"position":[[453,11]]},"2756":{"position":[[2308,11]]},"2985":{"position":[[950,11]]},"3352":{"position":[[1021,13]]},"3384":{"position":[[732,15]]},"3698":{"position":[[1305,11]]},"3932":{"position":[[107,11]]},"4124":{"position":[[838,11]]},"4230":{"position":[[3145,11]]},"4304":{"position":[[2420,13]]},"4317":{"position":[[40,11]]},"4608":{"position":[[755,11]]},"4742":{"position":[[820,11]]}}}],["approv",{"_index":659,"t":{"95":{"position":[[608,8]]},"169":{"position":[[423,8]]},"201":{"position":[[241,8],[313,9]]},"247":{"position":[[73,9],[234,11]]},"249":{"position":[[1313,9]]},"530":{"position":[[1204,9]]},"2453":{"position":[[151,8]]},"2467":{"position":[[175,8]]},"2747":{"position":[[600,8]]},"3206":{"position":[[907,8]]},"4485":{"position":[[2087,8],[2164,9],[2255,8],[2346,7],[2566,9],[2607,9]]},"4539":{"position":[[1167,7]]}}}],["approxim",{"_index":1026,"t":{"169":{"position":[[400,14]]},"2626":{"position":[[1309,14]]}}}],["april",{"_index":9773,"t":{"3138":{"position":[[254,5]]},"3202":{"position":[[119,5]]},"4593":{"position":[[3016,5]]}}}],["apt",{"_index":328,"t":{"37":{"position":[[97,4],[107,3],[492,3]]},"934":{"position":[[56,3],[76,3],[121,3]]},"938":{"position":[[40,3]]},"955":{"position":[[53,3],[393,3],[409,3]]},"957":{"position":[[29,3]]},"961":{"position":[[300,3],[321,3],[374,3],[692,3],[708,3]]},"963":{"position":[[123,3],[441,3],[457,3]]},"967":{"position":[[864,3]]},"1147":{"position":[[396,3]]},"1350":{"position":[[12,3],[287,3]]},"1499":{"position":[[5,3]]},"1650":{"position":[[2,3]]},"1825":{"position":[[56,3],[76,3],[121,3]]},"1829":{"position":[[40,3]]},"1846":{"position":[[53,3],[393,3],[409,3]]},"1848":{"position":[[29,3]]},"1852":{"position":[[300,3],[321,3],[374,3],[692,3],[708,3]]},"1854":{"position":[[123,3],[441,3],[457,3]]},"1858":{"position":[[864,3]]},"1975":{"position":[[2,3]]},"2007":{"position":[[83,3]]},"2034":{"position":[[1193,3],[1209,3]]},"2163":{"position":[[188,3],[219,3]]},"2238":{"position":[[187,3]]},"2487":{"position":[[377,7]]},"2535":{"position":[[434,4]]},"2692":{"position":[[368,3]]},"2725":{"position":[[895,3]]},"2958":{"position":[[56,3],[76,3],[121,3]]},"2962":{"position":[[40,3]]},"2979":{"position":[[53,3],[393,3],[409,3]]},"2981":{"position":[[29,3]]},"2985":{"position":[[300,3],[321,3],[374,3],[692,3],[708,3]]},"2987":{"position":[[123,3],[441,3],[457,3]]},"2991":{"position":[[864,3]]}}}],["apt_cache_valid_tim",{"_index":4538,"t":{"1147":{"position":[[258,20]]}}}],["aqbihv9naaaaabaahtxl8rdw/ebvxiogw4imjw",{"_index":4940,"t":{"1191":{"position":[[616,40]]}}}],["aqua",{"_index":3197,"t":{"724":{"position":[[52,4]]}}}],["ara",{"_index":6765,"t":{"1692":{"position":[[97,3]]},"1694":{"position":[[20,5],[787,5],[1434,5],[1957,5],[5492,5],[6109,5],[7009,5],[7698,5],[8688,5]]},"2039":{"position":[[114,3],[154,3]]},"2155":{"position":[[162,3],[1525,3],[1593,3]]},"2184":{"position":[[4253,3],[4435,3],[4467,3]]},"2192":{"position":[[319,3]]},"2194":{"position":[[306,3],[340,3]]},"3016":{"position":[[309,4]]},"3086":{"position":[[1447,4]]},"3357":{"position":[[2947,4]]}}}],["ara.services.in",{"_index":7337,"t":{"2037":{"position":[[1476,15]]}}}],["ara.sh",{"_index":7878,"t":{"2184":{"position":[[4335,7],[4509,7]]}}}],["ara.testbed.osism.xyz",{"_index":7906,"t":{"2192":{"position":[[297,21]]}}}],["arbitrari",{"_index":3291,"t":{"816":{"position":[[160,9]]},"3268":{"position":[[226,9]]},"3306":{"position":[[273,9]]},"4120":{"position":[[413,9]]},"4302":{"position":[[2503,9]]},"4304":{"position":[[670,9]]},"4310":{"position":[[2282,9]]}}}],["arbitrarili",{"_index":11692,"t":{"4578":{"position":[[35,12]]}}}],["arc(12.7/dg2)=3",{"_index":10612,"t":{"3714":{"position":[[892,15]]}}}],["arch",{"_index":10375,"t":{"3671":{"position":[[0,4],[178,4]]},"3712":{"position":[[98,6],[173,4]]},"3805":{"position":[[0,4],[178,4]]},"3968":{"position":[[130,4]]}}}],["arch[n][h",{"_index":10312,"t":{"3658":{"position":[[150,12]]}}}],["architect",{"_index":1855,"t":{"280":{"position":[[1570,10]]}}}],["architectur",{"_index":546,"t":{"74":{"position":[[82,12]]},"275":{"position":[[141,12]]},"446":{"position":[[474,13]]},"500":{"position":[[537,12]]},"671":{"position":[[227,13]]},"712":{"position":[[371,12]]},"794":{"position":[[118,12]]},"865":{"position":[[897,13]]},"871":{"position":[[696,13]]},"873":{"position":[[692,13]]},"887":{"position":[[9208,13]]},"1018":{"position":[[8,12],[29,12],[50,12],[72,12],[99,12]]},"1056":{"position":[[1526,12]]},"1061":{"position":[[680,13]]},"1064":{"position":[[1996,12]]},"1079":{"position":[[54,12]]},"1096":{"position":[[54,12]]},"1766":{"position":[[897,13]]},"1772":{"position":[[696,13]]},"1774":{"position":[[692,13]]},"1811":{"position":[[9208,13]]},"2382":{"position":[[156,13]]},"2439":{"position":[[7,13],[860,13]]},"2618":{"position":[[1085,12],[1584,12]]},"2632":{"position":[[24,12]]},"2914":{"position":[[615,12]]},"3206":{"position":[[523,13]]},"3422":{"position":[[19,13]]},"3502":{"position":[[890,12]]},"3554":{"position":[[105,12]]},"3563":{"position":[[334,13]]},"3569":{"position":[[92,13],[380,12],[802,12]]},"3571":{"position":[[92,13]]},"3573":{"position":[[579,12]]},"3712":{"position":[[241,12]]},"3826":{"position":[[237,13]]},"3894":{"position":[[1987,13]]},"3956":{"position":[[495,15],[546,13]]},"4068":{"position":[[285,12]]},"4130":{"position":[[848,13]]},"4226":{"position":[[559,12]]},"4228":{"position":[[948,12]]},"4230":{"position":[[1251,13]]},"4244":{"position":[[626,12]]},"4246":{"position":[[615,12]]},"4302":{"position":[[4711,13]]},"4321":{"position":[[368,13]]},"4422":{"position":[[565,13]]},"4431":{"position":[[1950,13]]},"4562":{"position":[[5508,13]]},"4587":{"position":[[1401,13]]},"4608":{"position":[[309,13]]},"4614":{"position":[[241,13]]},"4625":{"position":[[54,13]]},"4658":{"position":[[399,12]]},"4667":{"position":[[13389,12]]},"4724":{"position":[[674,12]]},"4728":{"position":[[249,13],[1038,13],[1082,12]]},"4730":{"position":[[89,12]]},"4733":{"position":[[1651,12]]},"4826":{"position":[[3942,12]]}}}],["archiv",{"_index":883,"t":{"153":{"position":[[346,8],[510,8]]},"961":{"position":[[358,7],[522,7]]},"1852":{"position":[[358,7],[522,7]]},"2088":{"position":[[161,8],[325,8]]},"2985":{"position":[[358,7],[522,7]]},"3549":{"position":[[1313,10]]},"4662":{"position":[[1709,8]]}}}],["archive_compat.key",{"_index":3970,"t":{"955":{"position":[[148,18],[199,18],[268,19]]},"1846":{"position":[[148,18],[199,18],[268,19]]},"2979":{"position":[[148,18],[199,18],[268,19]]}}}],["archtitectur",{"_index":11824,"t":{"4728":{"position":[[598,14]]}}}],["area",{"_index":1596,"t":{"220":{"position":[[50,5],[64,5],[79,5]]},"237":{"position":[[48,6],[61,6],[77,5]]},"1236":{"position":[[264,6]]},"1346":{"position":[[891,5]]},"1468":{"position":[[952,5]]},"2451":{"position":[[287,4]]},"3168":{"position":[[56,5]]},"3206":{"position":[[490,4]]},"3244":{"position":[[337,4]]},"3276":{"position":[[332,4]]},"3344":{"position":[[148,4],[261,5]]},"3348":{"position":[[65,6],[183,4],[319,4],[1177,6],[1184,5]]},"3350":{"position":[[210,6]]},"3352":{"position":[[1148,5]]},"3964":{"position":[[391,4]]},"3973":{"position":[[736,5]]},"4487":{"position":[[175,6]]},"4593":{"position":[[4424,6],[5051,5]]}}}],["aren't",{"_index":1463,"t":{"199":{"position":[[1291,6]]},"1571":{"position":[[569,6]]},"1904":{"position":[[569,6]]},"4220":{"position":[[1435,6]]},"4222":{"position":[[128,6]]},"4257":{"position":[[745,6]]},"4529":{"position":[[598,6]]},"4535":{"position":[[1951,6]]},"4539":{"position":[[3612,6]]}}}],["arg",{"_index":2482,"t":{"487":{"position":[[236,5]]},"3602":{"position":[[606,4],[771,5]]}}}],["argon2_cffi",{"_index":10086,"t":{"3384":{"position":[[636,11]]}}}],["arguabl",{"_index":11137,"t":{"4047":{"position":[[317,8]]}}}],["argument",{"_index":1989,"t":{"305":{"position":[[448,9]]},"701":{"position":[[2524,8]]},"738":{"position":[[298,8],[399,9]]},"912":{"position":[[1767,9]]},"914":{"position":[[1219,9]]},"942":{"position":[[2563,10]]},"1005":{"position":[[1285,9],[6740,9]]},"1457":{"position":[[2164,9]]},"1472":{"position":[[3088,10]]},"1513":{"position":[[311,8]]},"1686":{"position":[[290,9]]},"1740":{"position":[[126,9]]},"1796":{"position":[[1767,9]]},"1798":{"position":[[1219,9]]},"1833":{"position":[[2563,10]]},"1896":{"position":[[1285,9],[6740,9]]},"2295":{"position":[[408,9]]},"2309":{"position":[[408,9]]},"2705":{"position":[[579,11]]},"2966":{"position":[[2563,10]]},"3602":{"position":[[640,9]]},"3883":{"position":[[129,9]]},"3906":{"position":[[131,9]]},"4279":{"position":[[606,9],[867,9]]},"4348":{"position":[[319,10]]},"4485":{"position":[[1436,9]]}}}],["aris",{"_index":8359,"t":{"2327":{"position":[[848,6]]},"2337":{"position":[[439,6]]},"2339":{"position":[[1267,6]]},"2394":{"position":[[848,6]]},"2404":{"position":[[439,6]]},"2406":{"position":[[1267,6]]},"4506":{"position":[[1511,5]]},"4560":{"position":[[2557,7]]}}}],["arm",{"_index":10300,"t":{"3656":{"position":[[342,4]]},"3693":{"position":[[401,4]]},"3712":{"position":[[333,3]]},"3780":{"position":[[401,4]]},"3805":{"position":[[300,3]]},"3850":{"position":[[95,3]]}}}],["arm64",{"_index":10436,"t":{"3675":{"position":[[416,5]]},"3720":{"position":[[419,5]]},"3761":{"position":[[471,7]]},"3772":{"position":[[121,7]]},"3813":{"position":[[416,5]]}}}],["armv8.6",{"_index":10575,"t":{"3712":{"position":[[833,9]]}}}],["armv9",{"_index":10388,"t":{"3671":{"position":[[465,7]]},"3805":{"position":[[556,7]]}}}],["around",{"_index":593,"t":{"80":{"position":[[41,6]]},"84":{"position":[[31,6]]},"216":{"position":[[550,7]]},"243":{"position":[[149,6]]},"423":{"position":[[441,6]]},"427":{"position":[[57,6]]},"854":{"position":[[636,6]]},"942":{"position":[[3051,6]]},"963":{"position":[[3028,6]]},"978":{"position":[[1398,6]]},"1623":{"position":[[75,6]]},"1833":{"position":[[3051,6]]},"1854":{"position":[[3028,6]]},"1869":{"position":[[1398,6]]},"1954":{"position":[[75,6]]},"2005":{"position":[[159,6],[368,7]]},"2520":{"position":[[221,6]]},"2644":{"position":[[439,6]]},"2672":{"position":[[439,6]]},"2966":{"position":[[3051,6]]},"2987":{"position":[[3028,6]]},"3002":{"position":[[1398,6]]},"3153":{"position":[[1716,7]]},"3470":{"position":[[20,6]]},"3549":{"position":[[1152,6],[1274,6]]},"3968":{"position":[[1312,6]]},"4275":{"position":[[609,6]]},"4351":{"position":[[364,6],[746,6]]},"4353":{"position":[[672,6]]},"4560":{"position":[[5064,6]]}}}],["arp",{"_index":11304,"t":{"4222":{"position":[[3154,3],[3194,3]]},"4226":{"position":[[1782,4]]}}}],["array",{"_index":979,"t":{"167":{"position":[[1204,5]]},"461":{"position":[[169,6]]},"557":{"position":[[1640,5],[3928,5],[4755,5],[5739,5],[6615,5]]},"2720":{"position":[[931,5]]},"3561":{"position":[[133,5]]},"3594":{"position":[[567,5],[647,5],[725,5],[1103,5]]},"3598":{"position":[[109,5]]},"3600":{"position":[[365,5],[468,5]]},"3928":{"position":[[5197,6]]}}}],["arriv",{"_index":1633,"t":{"224":{"position":[[744,7],[792,7],[855,7]]},"3761":{"position":[[1442,7]]},"4340":{"position":[[424,6]]}}}],["arrow",{"_index":1768,"t":{"255":{"position":[[274,6]]}}}],["art",{"_index":8538,"t":{"2489":{"position":[[137,3]]},"3539":{"position":[[361,3]]},"3582":{"position":[[1428,3]]},"4226":{"position":[[3343,3]]}}}],["artcodix",{"_index":7851,"t":{"2178":{"position":[[751,8],[760,8]]},"3367":{"position":[[577,8]]},"3381":{"position":[[1218,8]]}}}],["artefact",{"_index":7458,"t":{"2059":{"position":[[955,8],[1468,9]]}}}],["articl",{"_index":1708,"t":{"247":{"position":[[144,8]]},"932":{"position":[[2394,8]]},"1312":{"position":[[217,7]]},"1823":{"position":[[2394,8]]},"2956":{"position":[[2394,8]]},"3148":{"position":[[1006,8]]},"3193":{"position":[[229,8]]},"3276":{"position":[[594,8]]}}}],["articul",{"_index":10229,"t":{"3571":{"position":[[539,12]]}}}],["artifact",{"_index":2645,"t":{"543":{"position":[[1919,9],[1954,10],[2002,9],[2038,8],[2119,8],[2240,8]]},"664":{"position":[[502,9]]},"739":{"position":[[986,9]]},"3086":{"position":[[312,9]]},"4420":{"position":[[2302,9],[2323,9],[2387,10]]},"4562":{"position":[[6774,9],[6796,10],[6819,10],[7563,10]]}}}],["artifactori",{"_index":11662,"t":{"4560":{"position":[[5339,11]]}}}],["artifici",{"_index":2957,"t":{"595":{"position":[[525,12]]}}}],["as4610",{"_index":4487,"t":{"1116":{"position":[[13,6]]}}}],["as5835",{"_index":4491,"t":{"1116":{"position":[[47,6]]}}}],["as7326",{"_index":4496,"t":{"1118":{"position":[[770,6]]}}}],["as7726",{"_index":4499,"t":{"1118":{"position":[[805,6]]},"1120":{"position":[[24,6]]}}}],["as9716",{"_index":4503,"t":{"1120":{"position":[[59,6]]}}}],["asahi",{"_index":1512,"t":{"199":{"position":[[3245,5]]}}}],["ascend",{"_index":9182,"t":{"2816":{"position":[[142,9]]}}}],["ascii",{"_index":7428,"t":{"2052":{"position":[[969,5]]},"2360":{"position":[[163,5]]},"2427":{"position":[[163,5]]},"3527":{"position":[[728,5]]}}}],["asd",{"_index":775,"t":{"141":{"position":[[167,3],[171,3]]}}}],["asdasdasdasd",{"_index":774,"t":{"141":{"position":[[154,12]]}}}],["ask",{"_index":627,"t":{"90":{"position":[[167,3]]},"99":{"position":[[115,3]]},"199":{"position":[[3,3],[1906,4]]},"218":{"position":[[260,3],[283,3]]},"266":{"position":[[155,6]]},"356":{"position":[[38,3]]},"358":{"position":[[243,3]]},"932":{"position":[[2301,5]]},"1472":{"position":[[2426,3]]},"1823":{"position":[[2301,5]]},"2171":{"position":[[2291,3]]},"2467":{"position":[[375,3]]},"2747":{"position":[[545,3]]},"2956":{"position":[[2301,5]]},"3378":{"position":[[563,3]]},"3533":{"position":[[1583,5]]},"3636":{"position":[[371,5]]},"3646":{"position":[[23,5]]},"3681":{"position":[[1211,3]]},"3718":{"position":[[1238,3]]},"3731":{"position":[[2017,3]]},"3811":{"position":[[1215,3]]},"4593":{"position":[[3394,5]]},"4632":{"position":[[568,5]]},"4757":{"position":[[215,3]]}}}],["asl2",{"_index":1159,"t":{"173":{"position":[[2096,7]]}}}],["asm",{"_index":10083,"t":{"3381":{"position":[[2646,3]]},"3384":{"position":[[1635,3]]}}}],["aspect",{"_index":577,"t":{"78":{"position":[[396,7]]},"539":{"position":[[127,7]]},"551":{"position":[[126,6]]},"963":{"position":[[3152,6]]},"1663":{"position":[[130,7]]},"1854":{"position":[[3152,6]]},"2293":{"position":[[38,7]]},"2307":{"position":[[38,7]]},"2485":{"position":[[63,6]]},"2525":{"position":[[388,6]]},"2914":{"position":[[1315,6]]},"2987":{"position":[[3152,6]]},"3119":{"position":[[1041,7]]},"3290":{"position":[[287,7]]},"3390":{"position":[[253,7]]},"3571":{"position":[[1523,7]]},"3582":{"position":[[748,7]]},"3592":{"position":[[2038,7]]},"3625":{"position":[[334,8]]},"3653":{"position":[[813,7]]},"3690":{"position":[[712,7]]},"3777":{"position":[[813,7]]},"3822":{"position":[[105,7],[143,7]]},"3943":{"position":[[162,7]]},"3945":{"position":[[309,7]]},"3947":{"position":[[512,6]]},"3951":{"position":[[0,6]]},"4007":{"position":[[231,6]]},"4009":{"position":[[250,7]]},"4013":{"position":[[59,8],[226,7],[277,8],[476,7],[524,6]]},"4015":{"position":[[32,7],[162,6],[183,6],[449,7],[536,7]]},"4023":{"position":[[10,7],[411,8]]},"4026":{"position":[[260,6],[325,9]]},"4028":{"position":[[534,6],[600,9]]},"4111":{"position":[[170,7]]},"4124":{"position":[[1790,7]]},"4302":{"position":[[3358,7]]},"4310":{"position":[[578,7]]},"4313":{"position":[[932,7]]},"4487":{"position":[[37,7]]},"4516":{"position":[[455,6]]},"4562":{"position":[[697,8]]},"4593":{"position":[[2702,7]]},"4728":{"position":[[1221,6]]},"4795":{"position":[[160,7]]}}}],["aspect2",{"_index":11118,"t":{"4013":{"position":[[436,8]]}}}],["aspectn",{"_index":11119,"t":{"4013":{"position":[[450,11]]}}}],["assembl",{"_index":4959,"t":{"1197":{"position":[[112,9]]},"1199":{"position":[[323,9]]},"2863":{"position":[[49,8]]},"2883":{"position":[[170,8]]},"3073":{"position":[[881,10]]}}}],["assert",{"_index":1244,"t":{"179":{"position":[[1098,6]]},"307":{"position":[[402,6]]},"2740":{"position":[[327,9]]},"3704":{"position":[[50,10]]}}}],["assess",{"_index":5866,"t":{"1373":{"position":[[298,6]]},"2478":{"position":[[167,12],[796,10],[883,11]]},"2482":{"position":[[587,11]]},"2499":{"position":[[284,9]]},"2506":{"position":[[388,6]]},"2555":{"position":[[106,11]]},"2690":{"position":[[139,9]]},"3357":{"position":[[2174,9]]},"3731":{"position":[[1751,10],[2115,10]]},"4224":{"position":[[2388,6]]},"4300":{"position":[[264,10]]},"4310":{"position":[[1746,6]]},"4315":{"position":[[337,6]]},"4416":{"position":[[107,6]]},"4418":{"position":[[571,10]]},"4560":{"position":[[265,10],[1096,10],[2366,10],[3621,10],[4718,10]]},"4593":{"position":[[5619,6]]}}}],["asset",{"_index":2321,"t":{"417":{"position":[[1392,6]]},"450":{"position":[[181,6]]},"452":{"position":[[50,6]]},"463":{"position":[[168,6],[345,6]]},"487":{"position":[[50,6],[362,6],[451,5]]},"489":{"position":[[38,7],[204,6],[271,7],[314,5],[545,5],[627,5],[1128,7]]},"496":{"position":[[90,6],[231,5]]},"593":{"position":[[146,6]]},"595":{"position":[[150,6]]},"597":{"position":[[542,7],[640,6]]},"600":{"position":[[115,6]]},"624":{"position":[[138,6],[186,6]]},"628":{"position":[[115,7],[333,6]]},"630":{"position":[[43,6]]},"632":{"position":[[125,6],[378,6]]},"641":{"position":[[474,6]]},"664":{"position":[[146,6],[524,6]]},"666":{"position":[[474,6]]},"861":{"position":[[77,6]]},"1762":{"position":[[77,6]]},"2319":{"position":[[736,6]]},"2386":{"position":[[736,6]]},"3223":{"position":[[1110,6]]},"3232":{"position":[[123,6]]},"3281":{"position":[[455,6],[561,6],[773,6]]},"3731":{"position":[[2452,7]]},"4113":{"position":[[1092,6]]}}}],["assign",{"_index":142,"t":{"19":{"position":[[206,6]]},"84":{"position":[[317,8]]},"181":{"position":[[48,11],[1146,11],[1617,11]]},"323":{"position":[[168,6]]},"368":{"position":[[5945,8]]},"557":{"position":[[1706,6],[2010,6],[2143,6]]},"816":{"position":[[260,6]]},"828":{"position":[[230,8]]},"836":{"position":[[259,8]]},"906":{"position":[[100,6]]},"908":{"position":[[158,6]]},"912":{"position":[[387,6],[1449,6],[1467,6],[2581,6]]},"914":{"position":[[452,6],[842,6],[860,6],[1814,6]]},"934":{"position":[[2106,8]]},"1175":{"position":[[1102,8]]},"1189":{"position":[[959,8]]},"1205":{"position":[[483,8]]},"1226":{"position":[[1748,6],[1803,8]]},"1236":{"position":[[150,8]]},"1324":{"position":[[6157,6],[7145,11],[9111,11],[9236,10],[9415,10],[9596,10],[9753,10],[13136,9]]},"1433":{"position":[[729,8]]},"1720":{"position":[[1210,6]]},"1725":{"position":[[42,8],[101,10]]},"1790":{"position":[[100,6]]},"1792":{"position":[[158,6]]},"1796":{"position":[[387,6],[1449,6],[1467,6],[2581,6]]},"1798":{"position":[[452,6],[842,6],[860,6],[1814,6]]},"1825":{"position":[[2106,8]]},"2114":{"position":[[196,9]]},"2139":{"position":[[981,8]]},"2146":{"position":[[85,9],[189,8]]},"2283":{"position":[[378,8],[441,11],[526,8],[841,8]]},"2291":{"position":[[58,8]]},"2295":{"position":[[28,8]]},"2297":{"position":[[378,8],[441,11],[526,8],[841,8]]},"2305":{"position":[[58,8]]},"2309":{"position":[[28,8]]},"2437":{"position":[[218,11]]},"2439":{"position":[[75,9],[809,6]]},"2447":{"position":[[44,6],[249,6]]},"2453":{"position":[[588,10],[1039,6]]},"2467":{"position":[[5,11],[105,8],[416,12],[429,9],[531,9],[656,10],[768,10],[870,12],[883,9],[988,9],[1116,10],[1231,10]]},"2478":{"position":[[602,6],[2481,6]]},"2516":{"position":[[243,6]]},"2714":{"position":[[1707,8]]},"2743":{"position":[[208,11]]},"2958":{"position":[[2106,8]]},"3527":{"position":[[77,8]]},"3533":{"position":[[1529,8]]},"3594":{"position":[[1211,10]]},"3598":{"position":[[1030,8]]},"3600":{"position":[[610,10]]},"3602":{"position":[[1015,10]]},"3627":{"position":[[79,8]]},"3673":{"position":[[574,9]]},"3693":{"position":[[586,9]]},"3712":{"position":[[1691,11]]},"3714":{"position":[[224,9]]},"3780":{"position":[[586,9]]},"3807":{"position":[[195,9]]},"4041":{"position":[[530,8],[591,8]]},"4109":{"position":[[3179,8]]},"4327":{"position":[[621,6]]},"4433":{"position":[[1555,6]]},"4593":{"position":[[4963,6]]},"4608":{"position":[[169,12],[247,8],[420,8]]},"4610":{"position":[[327,7],[578,11]]},"4612":{"position":[[369,6],[535,10]]},"4614":{"position":[[42,11],[135,6],[569,11],[1203,11],[1537,11]]},"4625":{"position":[[197,10]]},"4632":{"position":[[383,8]]},"4643":{"position":[[1640,6]]},"4667":{"position":[[6185,6],[7139,11],[9105,11],[9230,10],[9409,10],[9590,10],[9747,10]]},"4669":{"position":[[183,9],[300,11],[436,6],[496,9],[736,9]]},"4713":{"position":[[462,6]]}}}],["assign/revok",{"_index":11737,"t":{"4618":{"position":[[555,14]]},"4632":{"position":[[896,13],[1067,13]]}}}],["assigne",{"_index":1266,"t":{"181":{"position":[[349,10]]}}}],["assigned/revok",{"_index":11804,"t":{"4667":{"position":[[13851,16]]}}}],["assist",{"_index":3278,"t":{"804":{"position":[[65,11]]},"854":{"position":[[440,7]]},"3573":{"position":[[251,7]]},"4329":{"position":[[26,6]]}}}],["associ",{"_index":1390,"t":{"197":{"position":[[147,10]]},"286":{"position":[[627,10]]},"549":{"position":[[625,10]]},"557":{"position":[[1466,10]]},"659":{"position":[[636,10]]},"701":{"position":[[722,10]]},"1105":{"position":[[115,10]]},"1244":{"position":[[751,10]]},"1657":{"position":[[79,10]]},"1720":{"position":[[830,12],[1317,9],[1540,12],[2354,12]]},"2139":{"position":[[1186,10]]},"2636":{"position":[[207,10]]},"2718":{"position":[[717,10]]},"3148":{"position":[[48,10]]},"3180":{"position":[[78,10]]},"3218":{"position":[[78,10]]},"3502":{"position":[[65,10]]},"3527":{"position":[[320,10]]},"3602":{"position":[[128,9]]},"3947":{"position":[[3549,10],[3910,10],[4042,11]]},"4130":{"position":[[578,10]]},"4226":{"position":[[3193,12],[3666,11]]},"4230":{"position":[[5079,10]]},"4304":{"position":[[570,10]]},"4337":{"position":[[601,10]]},"4407":{"position":[[218,10]]},"4435":{"position":[[1524,10]]},"4446":{"position":[[418,10]]},"4457":{"position":[[418,10]]},"4479":{"position":[[1215,10]]},"4502":{"position":[[164,10],[454,10]]},"4504":{"position":[[312,10]]},"4533":{"position":[[16,10]]},"4539":{"position":[[2518,10]]},"4629":{"position":[[290,10]]}}}],["assum",{"_index":2010,"t":{"307":{"position":[[0,8]]},"358":{"position":[[277,6]]},"407":{"position":[[309,6]]},"413":{"position":[[3,6]]},"423":{"position":[[110,7]]},"471":{"position":[[68,6]]},"479":{"position":[[10,7]]},"604":{"position":[[95,8]]},"653":{"position":[[84,9]]},"701":{"position":[[11,7]]},"734":{"position":[[11,7]]},"865":{"position":[[1616,7]]},"942":{"position":[[3807,7]]},"1220":{"position":[[210,7]]},"1301":{"position":[[541,8]]},"1331":{"position":[[162,7]]},"1342":{"position":[[33,7]]},"1383":{"position":[[662,8]]},"1468":{"position":[[548,6]]},"1497":{"position":[[839,7]]},"1569":{"position":[[583,6]]},"1766":{"position":[[1616,7]]},"1833":{"position":[[3807,7]]},"1902":{"position":[[733,6]]},"2196":{"position":[[907,8],[1866,8]]},"2431":{"position":[[0,6],[392,8],[2238,6]]},"2966":{"position":[[3807,7]]},"3667":{"position":[[26,7]]},"3671":{"position":[[608,7]]},"3708":{"position":[[39,7]]},"3712":{"position":[[1040,7]]},"3801":{"position":[[26,7]]},"3805":{"position":[[715,7]]},"3941":{"position":[[423,6]]},"4206":{"position":[[318,6]]},"4222":{"position":[[7,8]]},"4302":{"position":[[4125,7]]},"4372":{"position":[[52,6]]},"4485":{"position":[[1864,7]]}}}],["assumpt",{"_index":10354,"t":{"3665":{"position":[[212,11]]},"3702":{"position":[[284,11]]},"3789":{"position":[[284,11]]},"4222":{"position":[[815,11]]},"4471":{"position":[[62,10]]},"4587":{"position":[[4,10]]},"4877":{"position":[[40,10]]}}}],["assumt",{"_index":11233,"t":{"4161":{"position":[[496,9]]}}}],["assur",{"_index":1294,"t":{"181":{"position":[[2164,9]]},"2489":{"position":[[214,9]]},"2503":{"position":[[155,10]]},"3121":{"position":[[443,6]]},"3148":{"position":[[643,8]]},"3153":{"position":[[87,6]]},"3248":{"position":[[458,9]]},"3344":{"position":[[164,10]]},"4257":{"position":[[4177,6]]}}}],["asterisk",{"_index":1777,"t":{"255":{"position":[[495,8]]}}}],["aswel",{"_index":8957,"t":{"2712":{"position":[[513,7]]},"2714":{"position":[[775,7]]}}}],["asynchron",{"_index":3200,"t":{"726":{"position":[[102,12]]},"2549":{"position":[[218,12]]}}}],["at",{"_index":2821,"t":{"557":{"position":[[6389,3]]}}}],["atm",{"_index":163,"t":{"24":{"position":[[168,3]]}}}],["atom",{"_index":6199,"t":{"1455":{"position":[[400,6],[450,6],[465,6],[517,6]]},"2005":{"position":[[772,6]]},"3598":{"position":[[1148,5],[1320,4],[1436,4],[1448,4],[1513,4],[1656,5],[1751,6]]},"4660":{"position":[[1749,4]]}}}],["attach",{"_index":2085,"t":{"323":{"position":[[1456,8]]},"848":{"position":[[156,8]]},"932":{"position":[[3216,6]]},"942":{"position":[[3780,6]]},"976":{"position":[[159,6]]},"978":{"position":[[2037,6]]},"980":{"position":[[446,8]]},"1823":{"position":[[3216,6]]},"1833":{"position":[[3780,6]]},"1867":{"position":[[159,6]]},"1869":{"position":[[2037,6]]},"1871":{"position":[[446,8]]},"2184":{"position":[[6513,8]]},"2236":{"position":[[352,8]]},"2252":{"position":[[1427,8]]},"2254":{"position":[[646,8],[1019,10]]},"2319":{"position":[[337,8]]},"2327":{"position":[[145,8],[298,8]]},"2333":{"position":[[30,8],[195,8]]},"2337":{"position":[[12,8]]},"2339":{"position":[[73,8],[256,8]]},"2358":{"position":[[137,9],[183,8],[347,9]]},"2386":{"position":[[337,8]]},"2394":{"position":[[145,8],[298,8]]},"2400":{"position":[[30,8],[195,8]]},"2404":{"position":[[12,8]]},"2406":{"position":[[73,8],[256,8]]},"2425":{"position":[[137,9],[183,8],[347,9]]},"2718":{"position":[[302,8],[413,8]]},"2956":{"position":[[3216,6]]},"2966":{"position":[[3780,6]]},"3000":{"position":[[159,6]]},"3002":{"position":[[2037,6]]},"3004":{"position":[[446,8]]},"3677":{"position":[[1293,8]]},"3791":{"position":[[1315,8]]},"3829":{"position":[[427,9],[4386,9]]},"3835":{"position":[[298,8]]},"3904":{"position":[[846,8]]},"3928":{"position":[[6081,8]]},"3932":{"position":[[194,8]]},"3941":{"position":[[1067,8]]},"3947":{"position":[[1560,8],[2236,6]]},"4113":{"position":[[652,8]]},"4116":{"position":[[168,8]]},"4118":{"position":[[314,8]]},"4159":{"position":[[2234,9]]},"4165":{"position":[[67,9],[427,9],[1068,7]]},"4167":{"position":[[371,9],[471,7]]},"4222":{"position":[[1456,10]]},"4304":{"position":[[430,9],[531,12]]},"4703":{"position":[[246,8]]}}}],["attached_volum",{"_index":8276,"t":{"2268":{"position":[[391,16],[416,18]]}}}],["attack",{"_index":1063,"t":{"171":{"position":[[439,8]]},"199":{"position":[[2292,7]]},"741":{"position":[[712,7]]},"2287":{"position":[[783,9]]},"2301":{"position":[[783,9]]},"2485":{"position":[[474,8]]},"2487":{"position":[[414,8]]},"2529":{"position":[[866,7],[1028,8]]},"2531":{"position":[[174,6],[528,8],[1090,8],[1321,8]]},"3290":{"position":[[338,6]]},"3984":{"position":[[955,7]]},"4081":{"position":[[633,6]]},"4096":{"position":[[962,7]]},"4107":{"position":[[735,6]]},"4109":{"position":[[4365,6],[4462,6],[4797,6],[4905,6],[4979,7],[5033,8],[5103,7],[5195,6],[5315,7],[5403,8]]},"4133":{"position":[[1570,6],[1662,6]]},"4222":{"position":[[791,7],[970,8],[1057,7],[2291,8],[2782,7],[2935,7],[3041,8],[3172,8],[3466,8],[3575,8],[3808,8],[3986,9]]},"4224":{"position":[[1937,8]]},"4257":{"position":[[5419,7]]},"4261":{"position":[[308,7]]},"4266":{"position":[[403,6]]},"4270":{"position":[[960,6]]},"4475":{"position":[[560,8]]},"4533":{"position":[[183,6]]},"4537":{"position":[[294,6],[332,6]]},"4547":{"position":[[1286,6]]}}}],["attack/threat",{"_index":11174,"t":{"4096":{"position":[[948,13]]}}}],["attacker'",{"_index":11306,"t":{"4222":{"position":[[3301,10]]}}}],["attain",{"_index":10645,"t":{"3727":{"position":[[274,6]]}}}],["attempt",{"_index":1236,"t":{"179":{"position":[[728,8]]},"323":{"position":[[288,7]]},"1466":{"position":[[2536,7]]},"1472":{"position":[[1819,10]]},"2196":{"position":[[677,7]]},"2431":{"position":[[1738,7]]},"3731":{"position":[[2948,7]]},"4228":{"position":[[1187,8]]},"4230":{"position":[[2962,9]]},"4397":{"position":[[254,8]]}}}],["attent",{"_index":1481,"t":{"199":{"position":[[1824,10]]},"368":{"position":[[2936,10]]},"3134":{"position":[[168,9]]},"4593":{"position":[[4232,9]]}}}],["attr",{"_index":4682,"t":{"1175":{"position":[[4688,4],[4871,4],[5035,4]]},"1177":{"position":[[2107,4],[2369,4],[2607,4],[5550,4],[5873,4],[6163,4]]}}}],["attract",{"_index":10972,"t":{"3947":{"position":[[754,10]]},"4410":{"position":[[529,7]]},"4562":{"position":[[4223,8]]}}}],["attribut",{"_index":1509,"t":{"199":{"position":[[3184,12]]},"871":{"position":[[165,9]]},"873":{"position":[[225,9]]},"980":{"position":[[1180,11]]},"1201":{"position":[[65,10],[184,9],[804,9]]},"1772":{"position":[[165,9]]},"1774":{"position":[[225,9]]},"1871":{"position":[[1180,11]]},"2295":{"position":[[938,11]]},"2319":{"position":[[555,9]]},"2325":{"position":[[734,9]]},"2341":{"position":[[623,10]]},"2347":{"position":[[355,10],[534,10]]},"2351":{"position":[[583,9]]},"2355":{"position":[[2079,9],[2156,10],[2678,9]]},"2386":{"position":[[555,9]]},"2392":{"position":[[734,9]]},"2408":{"position":[[623,10]]},"2414":{"position":[[355,10],[534,10]]},"2418":{"position":[[583,9]]},"2422":{"position":[[2079,9],[2156,10],[2678,9]]},"2427":{"position":[[2157,11]]},"2433":{"position":[[954,9],[1018,9]]},"2716":{"position":[[1604,10]]},"3406":{"position":[[258,9]]},"3768":{"position":[[54,10],[99,10]]},"3770":{"position":[[226,9]]},"3850":{"position":[[248,10]]},"3857":{"position":[[87,9],[140,9]]},"4113":{"position":[[904,9]]},"4527":{"position":[[91,9]]},"4539":{"position":[[5217,10],[5307,10],[5328,11],[5349,10],[5375,11],[5420,10]]},"4580":{"position":[[266,10]]},"4643":{"position":[[3449,10]]}}}],["audienc",{"_index":1547,"t":{"207":{"position":[[543,9]]},"3014":{"position":[[87,8]]}}}],["audio/video",{"_index":1773,"t":{"255":{"position":[[372,12]]}}}],["audit",{"_index":560,"t":{"76":{"position":[[94,5]]},"1466":{"position":[[2841,6]]},"2501":{"position":[[957,6]]},"2506":{"position":[[370,7]]},"2520":{"position":[[551,6],[694,6]]},"2531":{"position":[[1563,6]]},"3569":{"position":[[1169,6]]},"3592":{"position":[[1246,7]]},"3984":{"position":[[423,8]]},"3996":{"position":[[197,7]]},"4068":{"position":[[115,6],[318,10]]},"4081":{"position":[[1452,5]]},"4171":{"position":[[207,6],[349,7]]},"4182":{"position":[[83,5],[218,6]]},"4315":{"position":[[400,5]]},"4337":{"position":[[237,7]]},"4420":{"position":[[408,5],[444,9]]},"4543":{"position":[[1567,5],[1623,5],[1669,5]]},"4562":{"position":[[5763,5]]},"4593":{"position":[[4092,5]]}}}],["audit_period_begin",{"_index":9417,"t":{"3036":{"position":[[1358,23],[11143,23],[12979,23]]}}}],["audit_period_end",{"_index":9419,"t":{"3036":{"position":[[1436,20],[11221,20],[13057,20]]}}}],["auditor",{"_index":11248,"t":{"4182":{"position":[[118,7],[252,7]]}}}],["aufbau",{"_index":11940,"t":{"4849":{"position":[[403,6]]}}}],["augment",{"_index":8336,"t":{"2287":{"position":[[117,9]]},"2301":{"position":[[117,9]]}}}],["auth",{"_index":439,"t":{"45":{"position":[[55,4]]},"52":{"position":[[50,4]]},"323":{"position":[[1566,6]]},"584":{"position":[[229,5]]},"912":{"position":[[7742,5]]},"934":{"position":[[369,5],[594,5],[1305,5]]},"1169":{"position":[[762,4]]},"1191":{"position":[[466,4]]},"1407":{"position":[[2758,5]]},"1523":{"position":[[1534,5],[2095,5]]},"1796":{"position":[[7742,5]]},"1825":{"position":[[369,5],[594,5],[1305,5]]},"2119":{"position":[[396,4]]},"2132":{"position":[[304,4],[436,4],[494,4]]},"2144":{"position":[[9,5],[37,5],[195,5],[338,5],[463,5],[606,5],[731,5],[874,5],[999,5],[1142,5]]},"2184":{"position":[[2072,5],[2353,5],[2459,5],[2708,5]]},"2196":{"position":[[2125,4],[2179,4],[2930,4],[2984,4]]},"2276":{"position":[[2156,5],[2753,5]]},"2279":{"position":[[69,6]]},"2281":{"position":[[316,5]]},"2628":{"position":[[168,6]]},"2636":{"position":[[769,4]]},"2832":{"position":[[111,4]]},"2906":{"position":[[63,4]]},"2958":{"position":[[369,5],[594,5],[1305,5]]},"3381":{"position":[[486,5]]},"3384":{"position":[[1089,5]]},"4660":{"position":[[1449,4]]},"4662":{"position":[[597,4],[606,4],[648,4]]}}}],["auth.github",{"_index":4042,"t":{"963":{"position":[[1566,13],[4673,13],[4735,13]]},"1854":{"position":[[1566,13],[4673,13],[4735,13]]},"2987":{"position":[[1566,13],[4673,13],[4735,13]]}}}],["auth=fals",{"_index":11627,"t":{"4541":{"position":[[1472,11]]}}}],["auth=tru",{"_index":11598,"t":{"4535":{"position":[[3139,10]]}}}],["auth_token=token",{"_index":7658,"t":{"2132":{"position":[[261,16]]}}}],["auth_typ",{"_index":2865,"t":{"584":{"position":[[423,10]]},"934":{"position":[[1270,10]]},"1825":{"position":[[1270,10]]},"2184":{"position":[[2146,10]]},"2725":{"position":[[1409,10]]},"2958":{"position":[[1270,10]]},"3381":{"position":[[449,10]]},"3384":{"position":[[1052,10]]}}}],["auth_url",{"_index":2858,"t":{"584":{"position":[[235,9]]},"912":{"position":[[7748,9]]},"934":{"position":[[375,9]]},"1523":{"position":[[1444,8],[1580,9]]},"1796":{"position":[[7748,9]]},"1825":{"position":[[375,9]]},"2276":{"position":[[2162,9],[2759,9]]},"2279":{"position":[[80,10]]},"2281":{"position":[[322,9]]},"2602":{"position":[[752,11]]},"2725":{"position":[[1420,9]]},"2958":{"position":[[375,9]]},"3381":{"position":[[492,9],[502,8]]},"3384":{"position":[[1095,9],[1105,8]]}}}],["authent",{"_index":599,"t":{"84":{"position":[[131,12],[636,14]]},"253":{"position":[[336,15]]},"311":{"position":[[577,14]]},"317":{"position":[[29,14]]},"319":{"position":[[297,14]]},"323":{"position":[[387,14]]},"473":{"position":[[443,13]]},"578":{"position":[[403,13]]},"655":{"position":[[706,13]]},"673":{"position":[[706,13]]},"701":{"position":[[573,14],[609,12]]},"836":{"position":[[62,14],[437,14]]},"934":{"position":[[1123,13]]},"1248":{"position":[[198,15]]},"1405":{"position":[[576,14]]},"1472":{"position":[[2126,14],[2229,15],[2755,15]]},"1825":{"position":[[1123,13]]},"2052":{"position":[[907,15]]},"2150":{"position":[[237,15]]},"2196":{"position":[[0,14],[261,12],[688,12]]},"2276":{"position":[[146,12]]},"2287":{"position":[[480,14]]},"2301":{"position":[[480,14]]},"2431":{"position":[[741,14],[3693,14],[3940,14]]},"2478":{"position":[[1929,14]]},"2487":{"position":[[1268,14]]},"2529":{"position":[[548,14]]},"2557":{"position":[[414,14],[470,14]]},"2574":{"position":[[560,14],[670,14]]},"2628":{"position":[[476,14]]},"2830":{"position":[[34,14]]},"2836":{"position":[[160,12],[348,13]]},"2887":{"position":[[174,14]]},"2889":{"position":[[308,15]]},"2892":{"position":[[207,14]]},"2894":{"position":[[0,14]]},"2906":{"position":[[420,14]]},"2914":{"position":[[172,15]]},"2918":{"position":[[855,13]]},"2958":{"position":[[1123,13]]},"3058":{"position":[[25,14]]},"3225":{"position":[[335,14]]},"3460":{"position":[[362,14]]},"3470":{"position":[[135,15]]},"4224":{"position":[[2065,14]]},"4226":{"position":[[2703,14],[2954,14],[3079,14],[3997,13]]},"4228":{"position":[[709,13]]},"4230":{"position":[[1901,15]]},"4298":{"position":[[151,14]]},"4302":{"position":[[4051,14]]},"4313":{"position":[[761,12],[824,14]]},"4323":{"position":[[540,15],[560,14]]},"4327":{"position":[[602,14]]},"4420":{"position":[[507,14],[555,14],[672,14],[717,14],[1039,12]]},"4529":{"position":[[266,14]]},"4535":{"position":[[1001,15],[1114,12],[2832,14],[2942,14],[2999,14],[3164,14],[3303,12],[4416,14]]},"4539":{"position":[[598,14],[649,14],[692,14],[1340,15],[1395,14],[1512,14],[1804,14],[2209,13],[2831,12],[2918,14],[3572,14],[3699,14],[3840,15],[3908,14],[3938,14],[3961,14],[4473,14],[4771,14],[6640,14]]},"4541":{"position":[[1264,14],[1583,14],[1702,12],[1818,14]]},"4547":{"position":[[1048,14],[1170,14],[1823,14],[1889,14],[2003,14],[2079,15],[2197,14],[3006,14],[3128,14],[3163,14]]},"4562":{"position":[[1222,16],[5780,14],[5852,14]]},"4587":{"position":[[917,14]]},"4589":{"position":[[315,15]]},"4593":{"position":[[3491,14]]},"4660":{"position":[[406,14]]},"4719":{"position":[[37,14]]},"4849":{"position":[[602,15]]}}}],["authentication/author",{"_index":8633,"t":{"2574":{"position":[[360,30]]},"2918":{"position":[[438,28]]}}}],["authenticators.jwt.config.jwks_url",{"_index":9200,"t":{"2828":{"position":[[45,35]]}}}],["authenticators.jwt.config.trusted_issu",{"_index":9201,"t":{"2828":{"position":[[85,41]]}}}],["authkeyston",{"_index":6056,"t":{"1407":{"position":[[3400,13]]}}}],["authn",{"_index":8698,"t":{"2602":{"position":[[2041,5]]},"2914":{"position":[[767,5]]},"4719":{"position":[[52,7]]}}}],["authn/authz",{"_index":8632,"t":{"2574":{"position":[[348,11],[841,11]]},"2578":{"position":[[293,11]]}}}],["authn/authz/rest",{"_index":8638,"t":{"2576":{"position":[[689,18]]}}}],["authn1",{"_index":9249,"t":{"2889":{"position":[[167,6]]}}}],["author",{"_index":601,"t":{"84":{"position":[[164,14]]},"181":{"position":[[118,6],[421,7],[1786,13]]},"297":{"position":[[308,7]]},"299":{"position":[[5,7]]},"301":{"position":[[5,7],[336,7]]},"315":{"position":[[144,13]]},"317":{"position":[[48,13]]},"319":{"position":[[491,13]]},"323":{"position":[[861,13]]},"327":{"position":[[85,13]]},"518":{"position":[[293,9]]},"836":{"position":[[381,13]]},"924":{"position":[[95,6]]},"928":{"position":[[825,6]]},"932":{"position":[[4,6],[282,6]]},"980":{"position":[[1142,7]]},"1248":{"position":[[264,10]]},"1250":{"position":[[82,11]]},"1815":{"position":[[95,6]]},"1819":{"position":[[825,6]]},"1823":{"position":[[4,6],[282,6]]},"1871":{"position":[[1142,7]]},"2194":{"position":[[163,9]]},"2295":{"position":[[900,7]]},"2368":{"position":[[303,13]]},"2378":{"position":[[49,13]]},"2427":{"position":[[2119,7]]},"2431":{"position":[[4409,10]]},"2478":{"position":[[682,13]]},"2487":{"position":[[461,10]]},"2529":{"position":[[567,13]]},"2758":{"position":[[231,13],[571,13]]},"2762":{"position":[[26,15]]},"2766":{"position":[[28,15]]},"2772":{"position":[[24,15]]},"2778":{"position":[[24,15]]},"2784":{"position":[[26,15]]},"2790":{"position":[[26,15]]},"2836":{"position":[[394,9]]},"2879":{"position":[[407,13]]},"2887":{"position":[[157,13]]},"2889":{"position":[[243,14]]},"2892":{"position":[[224,13]]},"2894":{"position":[[17,13]]},"2906":{"position":[[389,13]]},"2910":{"position":[[129,15]]},"2914":{"position":[[188,14]]},"2940":{"position":[[259,10]]},"2948":{"position":[[95,6]]},"2952":{"position":[[825,6]]},"2956":{"position":[[4,6],[282,6]]},"3294":{"position":[[799,13]]},"3460":{"position":[[450,14]]},"3470":{"position":[[151,14]]},"3744":{"position":[[1253,6],[2075,6]]},"3984":{"position":[[1099,9]]},"4073":{"position":[[330,13]]},"4249":{"position":[[240,7]]},"4296":{"position":[[28,9]]},"4420":{"position":[[791,13]]},"4473":{"position":[[110,9]]},"4475":{"position":[[334,9]]},"4485":{"position":[[116,9]]},"4527":{"position":[[57,9]]},"4529":{"position":[[248,13]]},"4539":{"position":[[853,13],[872,10],[1082,13],[1209,11],[2975,9],[4426,14],[4441,13],[4562,10],[4795,9],[4830,13],[5200,11],[5883,13],[5932,13],[6016,13],[6243,13],[6463,10],[6659,13]]},"4541":{"position":[[1837,13],[1933,10],[2227,13]]},"4547":{"position":[[1842,13],[2300,13],[2401,13],[2450,13],[2523,13],[3202,13],[3280,13]]},"4562":{"position":[[5965,13]]},"4587":{"position":[[1020,13]]},"4589":{"position":[[151,14]]},"4593":{"position":[[3510,13],[5129,13],[5290,13]]},"4597":{"position":[[657,13]]},"4667":{"position":[[14725,9]]},"4719":{"position":[[64,13]]},"4872":{"position":[[691,9]]}}}],["authorit",{"_index":10170,"t":{"3525":{"position":[[725,14]]},"3531":{"position":[[573,14]]},"4531":{"position":[[20,13]]}}}],["authorized_key",{"_index":6225,"t":{"1457":{"position":[[1260,15]]}}}],["authz",{"_index":8660,"t":{"2584":{"position":[[1689,6]]},"2586":{"position":[[1299,6]]},"2914":{"position":[[784,5]]},"3189":{"position":[[139,5]]},"4719":{"position":[[78,7]]}}}],["authz2",{"_index":9250,"t":{"2889":{"position":[[178,7]]}}}],["auto",{"_index":1823,"t":{"271":{"position":[[303,4]]},"461":{"position":[[205,4]]},"477":{"position":[[742,4]]},"2686":{"position":[[608,5]]},"4481":{"position":[[1040,4],[1061,4]]},"4491":{"position":[[240,4],[272,4]]}}}],["autoinstal",{"_index":7277,"t":{"2013":{"position":[[119,11]]},"2021":{"position":[[145,11]]},"2032":{"position":[[345,11],[423,11]]}}}],["autom",{"_index":1746,"t":{"253":{"position":[[137,9]]},"334":{"position":[[82,9],[108,9]]},"378":{"position":[[0,9],[46,9]]},"545":{"position":[[1086,9]]},"593":{"position":[[70,10],[103,10]]},"608":{"position":[[143,9]]},"638":{"position":[[57,9]]},"657":{"position":[[200,10]]},"664":{"position":[[70,10],[103,10]]},"668":{"position":[[855,9],[1003,9],[1057,9]]},"924":{"position":[[777,11],[814,8]]},"965":{"position":[[67,8]]},"967":{"position":[[666,9]]},"1056":{"position":[[772,8],[1863,8],[1984,10],[2160,10]]},"1064":{"position":[[1428,9],[1467,9],[1588,10],[2318,9]]},"1067":{"position":[[447,9],[586,10]]},"1385":{"position":[[515,8]]},"1464":{"position":[[525,10]]},"1815":{"position":[[777,11],[814,8]]},"1856":{"position":[[67,8]]},"1858":{"position":[[666,9]]},"2325":{"position":[[1176,9]]},"2392":{"position":[[1176,9]]},"2429":{"position":[[484,8]]},"2473":{"position":[[57,9]]},"2478":{"position":[[1511,9],[1533,9],[1725,9],[1772,8]]},"2480":{"position":[[55,9]]},"2485":{"position":[[525,9]]},"2487":{"position":[[668,10]]},"2489":{"position":[[4,9],[857,9]]},"2497":{"position":[[107,9]]},"2499":{"position":[[172,9]]},"2510":{"position":[[122,9]]},"2512":{"position":[[489,9],[676,8],[1015,11]]},"2516":{"position":[[396,9]]},"2518":{"position":[[235,11],[247,8],[300,9]]},"2525":{"position":[[719,9]]},"2547":{"position":[[32,9]]},"2551":{"position":[[431,10],[475,9]]},"2559":{"position":[[551,9]]},"2584":{"position":[[62,10]]},"2588":{"position":[[32,9]]},"2590":{"position":[[471,10],[515,9]]},"2592":{"position":[[262,10]]},"2596":{"position":[[150,10]]},"2598":{"position":[[551,9]]},"2624":{"position":[[979,9]]},"2714":{"position":[[17,9]]},"2716":{"position":[[90,9]]},"2918":{"position":[[586,11]]},"2948":{"position":[[777,11],[814,8]]},"2989":{"position":[[67,8]]},"2991":{"position":[[666,9]]},"3016":{"position":[[6,9]]},"3067":{"position":[[670,10]]},"3073":{"position":[[144,10],[837,8]]},"3086":{"position":[[1144,10],[1160,10]]},"3114":{"position":[[109,9]]},"3121":{"position":[[411,9]]},"3191":{"position":[[134,9]]},"3206":{"position":[[75,9]]},"3248":{"position":[[682,9]]},"3290":{"position":[[50,9]]},"3298":{"position":[[79,11]]},"3346":{"position":[[247,10]]},"3348":{"position":[[413,10],[1129,10],[1217,9]]},"3352":{"position":[[173,9],[395,9],[828,10],[3112,9]]},"3355":{"position":[[746,10]]},"3357":{"position":[[2023,10],[2155,9],[2292,9]]},"3375":{"position":[[36,9]]},"3414":{"position":[[387,9]]},"3588":{"position":[[317,10]]},"3602":{"position":[[262,9],[283,9]]},"3731":{"position":[[2713,9],[2846,9]]},"3925":{"position":[[1091,12]]},"4030":{"position":[[87,9]]},"4146":{"position":[[2015,10]]},"4176":{"position":[[310,9]]},"4189":{"position":[[365,9]]},"4224":{"position":[[2702,9]]},"4228":{"position":[[210,8]]},"4230":{"position":[[5021,9]]},"4337":{"position":[[166,9]]},"4370":{"position":[[173,11]]},"4395":{"position":[[129,11]]},"4420":{"position":[[864,10]]},"4466":{"position":[[11,9]]},"4485":{"position":[[2223,8]]},"4562":{"position":[[5985,10],[7165,11]]},"4574":{"position":[[118,9]]}}}],["automat",{"_index":1736,"t":{"249":{"position":[[1916,13]]},"301":{"position":[[264,13]]},"311":{"position":[[495,13]]},"323":{"position":[[530,13]]},"368":{"position":[[2996,13]]},"395":{"position":[[99,14]]},"403":{"position":[[411,13]]},"417":{"position":[[298,14]]},"425":{"position":[[549,13]]},"434":{"position":[[191,13],[1805,14]]},"440":{"position":[[571,13]]},"461":{"position":[[179,13]]},"463":{"position":[[995,13],[1077,13]]},"477":{"position":[[632,13]]},"479":{"position":[[1612,13]]},"508":{"position":[[191,13]]},"512":{"position":[[633,14]]},"522":{"position":[[9,13]]},"530":{"position":[[2157,13]]},"543":{"position":[[966,14]]},"668":{"position":[[661,14]]},"755":{"position":[[665,14]]},"880":{"position":[[23,13]]},"942":{"position":[[3331,13]]},"961":{"position":[[133,13]]},"967":{"position":[[61,14]]},"1175":{"position":[[858,14]]},"1266":{"position":[[2439,14],[2855,13]]},"1391":{"position":[[3506,13]]},"1395":{"position":[[213,13]]},"1425":{"position":[[53,13]]},"1451":{"position":[[921,14]]},"1462":{"position":[[212,13],[461,13]]},"1466":{"position":[[2930,9]]},"1474":{"position":[[814,14]]},"1593":{"position":[[334,13]]},"1743":{"position":[[242,13]]},"1781":{"position":[[23,13]]},"1833":{"position":[[3331,13]]},"1852":{"position":[[133,13]]},"1858":{"position":[[61,14]]},"1936":{"position":[[334,13]]},"2025":{"position":[[716,14]]},"2052":{"position":[[170,9]]},"2094":{"position":[[46,13],[124,13]]},"2108":{"position":[[54,13]]},"2184":{"position":[[2806,13]]},"2196":{"position":[[77,13]]},"2351":{"position":[[684,14]]},"2380":{"position":[[192,13]]},"2418":{"position":[[684,14]]},"2461":{"position":[[267,13]]},"2463":{"position":[[285,13]]},"2465":{"position":[[273,13]]},"2489":{"position":[[602,13],[918,13]]},"2512":{"position":[[724,9]]},"2539":{"position":[[152,13]]},"2592":{"position":[[94,13],[296,13]]},"2594":{"position":[[67,13]]},"2596":{"position":[[184,13]]},"2647":{"position":[[1659,9]]},"2686":{"position":[[158,9],[650,13]]},"2714":{"position":[[381,13]]},"2718":{"position":[[966,13]]},"2861":{"position":[[38,13]]},"2966":{"position":[[3331,13]]},"2985":{"position":[[133,13]]},"2991":{"position":[[61,14]]},"3168":{"position":[[786,13]]},"3348":{"position":[[925,13]]},"3352":{"position":[[1380,9]]},"3533":{"position":[[2976,13]]},"3573":{"position":[[804,13]]},"3600":{"position":[[872,13]]},"3665":{"position":[[828,9]]},"3702":{"position":[[1041,9]]},"3789":{"position":[[900,9]]},"3833":{"position":[[1159,13]]},"3941":{"position":[[721,13]]},"4028":{"position":[[346,9]]},"4041":{"position":[[345,13],[513,13]]},"4043":{"position":[[146,13],[527,13]]},"4047":{"position":[[475,13]]},"4068":{"position":[[78,13]]},"4159":{"position":[[594,13]]},"4163":{"position":[[4530,13]]},"4167":{"position":[[205,13]]},"4171":{"position":[[78,13]]},"4224":{"position":[[87,13]]},"4228":{"position":[[853,13]]},"4266":{"position":[[29,13]]},"4370":{"position":[[141,13]]},"4395":{"position":[[97,13]]},"4485":{"position":[[323,14],[456,14],[944,9],[1683,13],[1764,10],[2017,9]]},"4497":{"position":[[167,9]]},"4539":{"position":[[2482,13]]},"4562":{"position":[[3913,13]]},"4580":{"position":[[1034,13],[1688,13]]},"4660":{"position":[[2912,13]]},"4669":{"position":[[422,13]]},"4730":{"position":[[1937,9],[2172,9]]},"4857":{"position":[[47,13]]},"4863":{"position":[[273,13]]}}}],["autonom",{"_index":3335,"t":{"842":{"position":[[91,9]]}}}],["autonomi",{"_index":1838,"t":{"280":{"position":[[397,8]]},"370":{"position":[[503,8]]}}}],["autopopul",{"_index":11536,"t":{"4459":{"position":[[1431,13],[2010,13]]}}}],["autosc",{"_index":2632,"t":{"541":{"position":[[1281,12]]},"1637":{"position":[[6,11]]},"1968":{"position":[[8,11],[79,11]]}}}],["autoscal",{"_index":6572,"t":{"1629":{"position":[[16,9]]},"1960":{"position":[[0,10],[73,9]]}}}],["autosubscrib",{"_index":2361,"t":{"434":{"position":[[974,13]]},"463":{"position":[[928,13]]},"465":{"position":[[305,14]]},"477":{"position":[[591,14]]},"493":{"position":[[622,13]]},"586":{"position":[[972,14]]}}}],["avaiabl",{"_index":11227,"t":{"4153":{"position":[[448,11]]}}}],["avail",{"_index":743,"t":{"130":{"position":[[681,9]]},"171":{"position":[[357,9],[851,9],[934,10]]},"175":{"position":[[185,9],[519,9],[649,9]]},"177":{"position":[[1235,9]]},"179":{"position":[[284,10]]},"199":{"position":[[1623,10]]},"212":{"position":[[0,14]]},"216":{"position":[[328,11]]},"218":{"position":[[57,13]]},"220":{"position":[[6,9],[30,9],[156,10]]},"224":{"position":[[98,9]]},"226":{"position":[[67,9],[134,14]]},"237":{"position":[[187,9]]},"339":{"position":[[400,9]]},"354":{"position":[[196,10]]},"364":{"position":[[110,9],[401,9],[780,9],[823,9]]},"366":{"position":[[777,9]]},"391":{"position":[[23,10]]},"405":{"position":[[347,9]]},"417":{"position":[[1252,9],[1913,9]]},"423":{"position":[[139,10]]},"434":{"position":[[2278,9]]},"463":{"position":[[763,9],[917,10]]},"475":{"position":[[638,9]]},"477":{"position":[[687,9]]},"479":{"position":[[409,10]]},"512":{"position":[[1328,9]]},"520":{"position":[[308,9],[418,10]]},"526":{"position":[[319,12],[1068,12]]},"553":{"position":[[49,10]]},"557":{"position":[[6674,12],[6834,12],[6957,12]]},"562":{"position":[[58,9]]},"566":{"position":[[36,9]]},"628":{"position":[[529,9]]},"701":{"position":[[82,9]]},"712":{"position":[[214,9]]},"734":{"position":[[82,9]]},"743":{"position":[[122,9]]},"780":{"position":[[22,9]]},"812":{"position":[[57,12],[337,9]]},"814":{"position":[[3,12],[151,12],[302,12],[445,12],[630,12]]},"816":{"position":[[593,12],[690,12],[882,12],[928,12],[1012,12],[1068,12]]},"820":{"position":[[102,12]]},"878":{"position":[[145,12]]},"880":{"position":[[69,9],[142,9]]},"894":{"position":[[1474,9]]},"896":{"position":[[33,9]]},"898":{"position":[[73,9]]},"920":{"position":[[44,9]]},"928":{"position":[[492,9]]},"930":{"position":[[482,12]]},"1005":{"position":[[1004,12],[1752,12],[2075,12]]},"1038":{"position":[[76,9],[186,9],[411,12]]},"1042":{"position":[[857,9],[948,9],[1023,9]]},"1061":{"position":[[590,12]]},"1064":{"position":[[1684,12],[1735,12]]},"1067":{"position":[[1537,9],[1680,10]]},"1103":{"position":[[351,9]]},"1105":{"position":[[372,12]]},"1118":{"position":[[157,10]]},"1185":{"position":[[1136,9]]},"1189":{"position":[[826,9],[1017,10]]},"1191":{"position":[[813,9]]},"1224":{"position":[[786,9]]},"1226":{"position":[[1478,9],[4019,9]]},"1230":{"position":[[858,9]]},"1232":{"position":[[90,9]]},"1252":{"position":[[21,9]]},"1266":{"position":[[881,9]]},"1292":{"position":[[123,9]]},"1346":{"position":[[354,12]]},"1373":{"position":[[537,9]]},"1375":{"position":[[39,9]]},"1399":{"position":[[95,10]]},"1413":{"position":[[259,10]]},"1425":{"position":[[400,10]]},"1451":{"position":[[850,10]]},"1455":{"position":[[268,10]]},"1457":{"position":[[4242,9]]},"1462":{"position":[[513,9]]},"1464":{"position":[[241,9]]},"1466":{"position":[[393,9]]},"1491":{"position":[[345,9],[421,9]]},"1501":{"position":[[529,9]]},"1507":{"position":[[389,10]]},"1509":{"position":[[832,10]]},"1549":{"position":[[100,9]]},"1574":{"position":[[668,9]]},"1667":{"position":[[21,9]]},"1677":{"position":[[17,9]]},"1698":{"position":[[326,5],[983,5]]},"1707":{"position":[[29,9],[98,9]]},"1713":{"position":[[1802,12]]},"1720":{"position":[[2775,10]]},"1752":{"position":[[1474,9]]},"1754":{"position":[[33,9]]},"1756":{"position":[[73,9]]},"1779":{"position":[[145,12]]},"1781":{"position":[[69,9],[142,9]]},"1804":{"position":[[44,9]]},"1819":{"position":[[492,9]]},"1821":{"position":[[482,12]]},"1896":{"position":[[1004,12],[1752,12],[2075,12]]},"1906":{"position":[[82,9]]},"1917":{"position":[[668,9]]},"1990":{"position":[[51,10]]},"2023":{"position":[[180,9]]},"2027":{"position":[[527,9],[634,9]]},"2041":{"position":[[286,12]]},"2043":{"position":[[168,9]]},"2048":{"position":[[3600,9]]},"2059":{"position":[[934,9],[1112,9],[1449,9],[2772,10]]},"2065":{"position":[[1357,9],[1676,9],[1997,9],[2328,9],[2650,9],[2972,9],[3293,9],[3609,9]]},"2071":{"position":[[147,9],[384,12]]},"2112":{"position":[[255,9]]},"2163":{"position":[[4529,9]]},"2178":{"position":[[838,9]]},"2184":{"position":[[3490,10],[4096,10],[4418,9]]},"2190":{"position":[[741,9]]},"2196":{"position":[[1062,9],[1102,9]]},"2234":{"position":[[825,9]]},"2236":{"position":[[83,9]]},"2252":{"position":[[301,9]]},"2256":{"position":[[685,10]]},"2263":{"position":[[33,9]]},"2270":{"position":[[549,9]]},"2279":{"position":[[626,10]]},"2329":{"position":[[336,9]]},"2335":{"position":[[41,9]]},"2337":{"position":[[132,10]]},"2339":{"position":[[828,9]]},"2355":{"position":[[1427,11],[2577,10],[2898,11],[3103,11]]},"2396":{"position":[[336,9]]},"2402":{"position":[[41,9]]},"2404":{"position":[[132,10]]},"2406":{"position":[[828,9]]},"2422":{"position":[[1427,11],[2577,10],[2898,11],[3103,11]]},"2449":{"position":[[40,9]]},"2459":{"position":[[40,9]]},"2467":{"position":[[1545,12]]},"2469":{"position":[[218,12]]},"2475":{"position":[[20,10],[94,9]]},"2618":{"position":[[852,9],[1522,9]]},"2620":{"position":[[95,9]]},"2630":{"position":[[121,9]]},"2632":{"position":[[312,10]]},"2638":{"position":[[95,9]]},"2647":{"position":[[1475,9]]},"2649":{"position":[[161,9]]},"2699":{"position":[[98,9],[125,9]]},"2718":{"position":[[92,12],[141,12]]},"2855":{"position":[[222,9]]},"2916":{"position":[[248,10]]},"2918":{"position":[[603,12]]},"2930":{"position":[[42,9]]},"2934":{"position":[[393,9],[931,9]]},"2952":{"position":[[492,9]]},"2954":{"position":[[482,12]]},"3047":{"position":[[143,10]]},"3052":{"position":[[425,9]]},"3071":{"position":[[488,12]]},"3083":{"position":[[91,9],[240,9]]},"3086":{"position":[[1034,9],[1296,9]]},"3088":{"position":[[653,9]]},"3095":{"position":[[248,9]]},"3097":{"position":[[653,9]]},"3116":{"position":[[82,9],[397,10],[626,10]]},"3119":{"position":[[1243,9]]},"3121":{"position":[[771,9],[933,9],[1152,9]]},"3130":{"position":[[409,9],[771,9]]},"3150":{"position":[[37,10],[695,9]]},"3153":{"position":[[105,9]]},"3162":{"position":[[442,9],[528,9],[637,9]]},"3185":{"position":[[46,9]]},"3189":{"position":[[818,10],[902,9]]},"3234":{"position":[[315,9]]},"3251":{"position":[[190,9]]},"3266":{"position":[[33,9]]},"3279":{"position":[[173,9]]},"3288":{"position":[[142,9]]},"3294":{"position":[[26,9]]},"3344":{"position":[[682,9]]},"3348":{"position":[[4,9],[1140,9]]},"3365":{"position":[[210,9]]},"3371":{"position":[[210,9]]},"3398":{"position":[[1774,12]]},"3406":{"position":[[58,9],[476,12]]},"3418":{"position":[[437,12]]},"3468":{"position":[[1091,12]]},"3653":{"position":[[477,9]]},"3656":{"position":[[219,9]]},"3669":{"position":[[257,10]]},"3693":{"position":[[278,9]]},"3698":{"position":[[1353,10],[1454,9]]},"3710":{"position":[[270,10]]},"3731":{"position":[[2589,9]]},"3759":{"position":[[151,9]]},"3761":{"position":[[270,10],[392,10]]},"3763":{"position":[[641,9],[764,9],[923,9]]},"3765":{"position":[[142,9]]},"3777":{"position":[[477,9]]},"3780":{"position":[[278,9]]},"3803":{"position":[[257,10]]},"3829":{"position":[[2531,9]]},"3831":{"position":[[546,9]]},"3843":{"position":[[66,9]]},"3855":{"position":[[523,9]]},"3892":{"position":[[369,9]]},"3923":{"position":[[92,9]]},"3925":{"position":[[918,9]]},"3928":{"position":[[6056,9]]},"3947":{"position":[[1085,12],[1105,12]]},"3968":{"position":[[2492,9]]},"4007":{"position":[[326,12]]},"4030":{"position":[[772,12]]},"4037":{"position":[[325,9]]},"4043":{"position":[[348,9]]},"4060":{"position":[[682,10]]},"4081":{"position":[[593,9]]},"4096":{"position":[[17,12]]},"4102":{"position":[[167,13],[585,12],[612,12]]},"4104":{"position":[[350,9]]},"4107":{"position":[[1496,12]]},"4111":{"position":[[286,13]]},"4120":{"position":[[82,9]]},"4122":{"position":[[50,9]]},"4124":{"position":[[1098,13],[1285,9],[1933,12],[2085,12],[2324,12],[2505,13]]},"4130":{"position":[[548,10]]},"4146":{"position":[[829,9],[3130,9]]},"4153":{"position":[[79,12],[277,12]]},"4155":{"position":[[17,12]]},"4157":{"position":[[331,12],[702,12],[730,12],[940,12],[1075,12]]},"4159":{"position":[[0,12],[393,12],[567,12],[812,12],[999,12],[1283,12],[1423,12],[1550,12],[1956,12],[2037,12],[2060,9],[2209,12],[2390,12]]},"4161":{"position":[[713,12],[948,12],[1030,12]]},"4163":{"position":[[15,12],[75,12],[255,12],[538,12],[586,12],[936,12],[1414,12],[1828,12],[1941,12],[2017,12],[2059,10],[2129,12],[2649,12],[2762,9],[2833,12],[3387,12],[4124,12],[4218,12],[4908,9],[5336,12],[5447,12]]},"4165":{"position":[[153,12],[217,12],[462,12],[654,12],[750,12]]},"4167":{"position":[[11,12],[326,12],[409,12],[446,12],[515,12]]},"4169":{"position":[[262,13]]},"4171":{"position":[[34,12],[254,9],[576,12],[620,12]]},"4173":{"position":[[93,12],[137,12]]},"4176":{"position":[[143,12],[177,12],[256,12]]},"4178":{"position":[[26,12],[123,12]]},"4204":{"position":[[380,12]]},"4220":{"position":[[983,13]]},"4230":{"position":[[4627,9]]},"4249":{"position":[[67,9]]},"4257":{"position":[[2840,9],[3799,9]]},"4283":{"position":[[985,9]]},"4287":{"position":[[22,9]]},"4302":{"position":[[3847,9]]},"4304":{"position":[[1085,9],[2607,9]]},"4353":{"position":[[778,9]]},"4362":{"position":[[160,9],[216,9]]},"4376":{"position":[[1098,12]]},"4388":{"position":[[85,9]]},"4390":{"position":[[101,12]]},"4418":{"position":[[305,9]]},"4431":{"position":[[183,13],[216,12],[1874,13]]},"4433":{"position":[[315,12],[408,12],[614,13],[693,9],[2283,12],[2381,12],[2485,12]]},"4435":{"position":[[891,12]]},"4437":{"position":[[16,12],[61,12]]},"4444":{"position":[[465,13]]},"4446":{"position":[[168,12],[261,9]]},"4448":{"position":[[123,9]]},"4455":{"position":[[465,13]]},"4457":{"position":[[168,12],[261,9]]},"4459":{"position":[[123,9]]},"4479":{"position":[[523,9],[885,9]]},"4520":{"position":[[244,9]]},"4535":{"position":[[1687,12],[1770,13],[1831,12]]},"4541":{"position":[[605,10]]},"4547":{"position":[[2895,9]]},"4560":{"position":[[1198,9],[1651,9],[2684,9],[3020,9],[3904,9],[4161,9],[4783,9]]},"4562":{"position":[[3040,9]]},"4576":{"position":[[329,9]]},"4593":{"position":[[5356,9]]},"4597":{"position":[[972,9]]},"4632":{"position":[[1506,9]]},"4667":{"position":[[208,9]]},"4726":{"position":[[1023,9]]},"4742":{"position":[[801,9]]},"4744":{"position":[[973,9]]},"4755":{"position":[[421,9]]},"4765":{"position":[[32,12]]},"4773":{"position":[[506,12]]},"4775":{"position":[[187,12]]},"4826":{"position":[[2238,12],[3088,12]]},"4883":{"position":[[161,9]]}}}],["availability_zon",{"_index":7857,"t":{"2178":{"position":[[1173,17]]},"2219":{"position":[[176,17]]},"3036":{"position":[[1134,18],[1912,18],[3118,18],[12005,18]]}}}],["availabilti",{"_index":11239,"t":{"4167":{"position":[[78,11],[258,11]]}}}],["availbl",{"_index":3282,"t":{"812":{"position":[[245,11],[360,11]]},"816":{"position":[[672,11]]},"2718":{"position":[[249,11]]}}}],["availi",{"_index":8491,"t":{"2478":{"position":[[1964,11]]}}}],["averag",{"_index":4378,"t":{"1040":{"position":[[403,8]]},"1669":{"position":[[256,8]]},"1675":{"position":[[209,8]]}}}],["avert",{"_index":11287,"t":{"4222":{"position":[[936,8]]}}}],["avoid",{"_index":1018,"t":{"169":{"position":[[173,6],[823,5]]},"171":{"position":[[861,6]]},"177":{"position":[[363,5]]},"181":{"position":[[2306,5]]},"305":{"position":[[536,5]]},"368":{"position":[[3985,5]]},"485":{"position":[[254,5]]},"728":{"position":[[485,8]]},"924":{"position":[[369,6]]},"936":{"position":[[569,5]]},"944":{"position":[[725,5]]},"946":{"position":[[474,6]]},"980":{"position":[[183,5]]},"1185":{"position":[[1077,5]]},"1244":{"position":[[11,5]]},"1391":{"position":[[1546,5]]},"1464":{"position":[[549,6]]},"1503":{"position":[[1332,6]]},"1571":{"position":[[324,5]]},"1815":{"position":[[369,6]]},"1827":{"position":[[569,5]]},"1835":{"position":[[725,5]]},"1837":{"position":[[474,6]]},"1871":{"position":[[183,5]]},"1904":{"position":[[324,5]]},"2712":{"position":[[1525,5]]},"2725":{"position":[[191,5]]},"2948":{"position":[[369,6]]},"2960":{"position":[[569,5]]},"2968":{"position":[[725,5]]},"2970":{"position":[[474,6]]},"3004":{"position":[[183,5]]},"3086":{"position":[[398,8]]},"3101":{"position":[[115,5]]},"3204":{"position":[[125,5]]},"3230":{"position":[[795,5]]},"3264":{"position":[[476,6]]},"3266":{"position":[[347,5]]},"3315":{"position":[[112,5]]},"3344":{"position":[[773,8]]},"3516":{"position":[[408,8]]},"3556":{"position":[[204,8]]},"3651":{"position":[[133,5]]},"3681":{"position":[[384,5]]},"3688":{"position":[[133,5]]},"3706":{"position":[[1355,5]]},"3718":{"position":[[384,5]]},"3775":{"position":[[133,5]]},"3799":{"position":[[1355,5]]},"3811":{"position":[[384,5]]},"3829":{"position":[[4052,5]]},"3928":{"position":[[120,8],[1340,5],[1856,5],[3952,6],[5256,6]]},"4015":{"position":[[363,5]]},"4041":{"position":[[57,5]]},"4043":{"position":[[743,5]]},"4109":{"position":[[4835,7]]},"4135":{"position":[[637,5]]},"4161":{"position":[[899,5]]},"4163":{"position":[[1353,5]]},"4224":{"position":[[2756,5],[2831,5]]},"4236":{"position":[[288,8]]},"4238":{"position":[[355,5]]},"4253":{"position":[[792,7]]},"4255":{"position":[[75,5]]},"4257":{"position":[[3448,5]]},"4304":{"position":[[2437,5]]},"4435":{"position":[[404,8]]},"4475":{"position":[[360,9],[460,8]]},"4485":{"position":[[220,5]]},"4495":{"position":[[13,8],[104,5],[288,5]]},"4578":{"position":[[349,5],[465,5],[512,5]]},"4587":{"position":[[653,6]]},"4593":{"position":[[2114,5]]},"4604":{"position":[[299,5]]},"4632":{"position":[[2650,5]]},"4643":{"position":[[2992,5]]},"4660":{"position":[[3472,5]]}}}],["aw",{"_index":415,"t":{"39":{"position":[[7,3]]},"701":{"position":[[2067,6],[2275,3],[2355,3],[2545,3],[2601,3]]},"705":{"position":[[660,3],[1587,3]]},"738":{"position":[[519,3]]},"1056":{"position":[[1006,5]]},"1064":{"position":[[1231,4]]}}}],["awar",{"_index":1261,"t":{"181":{"position":[[128,5]]},"271":{"position":[[10,5]]},"473":{"position":[[279,5]]},"578":{"position":[[239,5]]},"706":{"position":[[1322,5]]},"739":{"position":[[182,5]]},"1371":{"position":[[105,6]]},"1373":{"position":[[37,5]]},"2372":{"position":[[332,5]]},"2439":{"position":[[475,5]]},"3119":{"position":[[1203,6]]},"3210":{"position":[[20,5]]},"3629":{"position":[[496,5]]},"3947":{"position":[[924,5]]},"4310":{"position":[[1181,9]]},"4420":{"position":[[1256,5]]},"4539":{"position":[[7259,5]]},"4543":{"position":[[1796,6]]},"4562":{"position":[[5281,5],[5471,5]]},"4736":{"position":[[227,5]]},"4755":{"position":[[227,5]]}}}],["award",{"_index":10248,"t":{"3592":{"position":[[1979,8]]}}}],["away",{"_index":10515,"t":{"3690":{"position":[[1457,4]]},"3777":{"position":[[1558,4]]}}}],["awesom",{"_index":11767,"t":{"4656":{"position":[[513,7]]}}}],["awk",{"_index":8324,"t":{"2281":{"position":[[254,3]]}}}],["aws/credenti",{"_index":3084,"t":{"701":{"position":[[2025,18],[2078,19]]},"705":{"position":[[330,18],[789,18],[1680,18]]},"738":{"position":[[612,18]]}}}],["aws:v1.6.1",{"_index":3114,"t":{"705":{"position":[[1628,10]]},"738":{"position":[[560,10]]}}}],["aws:v1.6.1,velero/velero",{"_index":3102,"t":{"705":{"position":[[701,24]]}}}],["aws_access_key_id",{"_index":3077,"t":{"701":{"position":[[1509,19],[1892,17],[2114,17],[2134,19]]}}}],["aws_secret_access_key",{"_index":3081,"t":{"701":{"position":[[1689,23],[1914,21],[2154,21],[2178,23]]}}}],["awscli",{"_index":3086,"t":{"701":{"position":[[2410,6],[2417,6]]}}}],["ax",{"_index":6717,"t":{"1673":{"position":[[130,2],[433,2]]},"1709":{"position":[[168,2]]},"1713":{"position":[[414,2]]}}}],["az",{"_index":3759,"t":{"930":{"position":[[785,2]]},"938":{"position":[[2488,5],[2562,2],[2758,2],[2790,2]]},"1821":{"position":[[785,2]]},"1829":{"position":[[2488,5],[2562,2],[2758,2],[2790,2]]},"2954":{"position":[[785,2]]},"2962":{"position":[[2488,5],[2562,2],[2758,2],[2790,2]]},"3947":{"position":[[1298,4],[1454,4],[1494,3],[1586,4]]},"3951":{"position":[[136,3]]},"4007":{"position":[[323,2]]},"4096":{"position":[[42,3]]},"4107":{"position":[[1561,3]]},"4155":{"position":[[42,3]]},"4157":{"position":[[438,3],[573,4],[1203,3]]},"4159":{"position":[[453,3],[498,2],[645,4],[1669,2],[1866,2],[2262,2],[2297,3]]},"4161":{"position":[[761,3]]},"4163":{"position":[[1007,3],[1078,3],[1097,2],[1184,4],[1344,4],[1494,3],[1569,3],[2045,3],[2695,3],[2863,3],[3464,4],[3553,3],[3680,4],[4320,3],[4405,3],[4429,4],[4641,3],[5238,2],[5575,3],[5604,2],[5757,2],[5848,3],[5925,2],[6135,4]]},"4165":{"position":[[23,3],[112,4],[178,3],[282,2],[299,2],[335,2],[352,2],[511,3],[823,2],[903,3],[996,3]]},"4167":{"position":[[790,3]]},"4176":{"position":[[340,4]]},"4178":{"position":[[342,2],[422,2],[495,2],[561,2],[850,3]]},"4180":{"position":[[271,2]]},"4376":{"position":[[828,3]]},"4401":{"position":[[356,3]]},"4437":{"position":[[160,2]]},"4660":{"position":[[637,5]]}}}],["az'",{"_index":11496,"t":{"4376":{"position":[[901,5]]},"4401":{"position":[[438,4]]}}}],["azs3",{"_index":11236,"t":{"4163":{"position":[[5515,5]]}}}],["azur",{"_index":3190,"t":{"719":{"position":[[295,8]]},"1056":{"position":[[1012,6]]},"1064":{"position":[[1236,6]]},"4569":{"position":[[1003,5]]}}}],["b",{"_index":1006,"t":{"167":{"position":[[1986,1]]},"218":{"position":[[104,2]]},"249":{"position":[[413,3],[886,3]]},"448":{"position":[[476,2]]},"938":{"position":[[913,1],[916,1]]},"942":{"position":[[2331,1],[2334,1],[2415,1],[2418,1]]},"1259":{"position":[[507,1]]},"1324":{"position":[[5967,2]]},"1829":{"position":[[913,1],[916,1]]},"1833":{"position":[[2331,1],[2334,1],[2415,1],[2418,1]]},"2747":{"position":[[38,1]]},"2962":{"position":[[913,1],[916,1]]},"2966":{"position":[[2331,1],[2334,1],[2415,1],[2418,1]]},"3126":{"position":[[181,1]]},"3378":{"position":[[470,1]]},"3857":{"position":[[352,3]]},"4667":{"position":[[5995,2],[12783,2],[13071,2]]}}}],["b/f",{"_index":9352,"t":{"3016":{"position":[[394,4]]}}}],["b/w",{"_index":10505,"t":{"3681":{"position":[[734,3]]},"3718":{"position":[[773,3]]},"3811":{"position":[[773,3]]}}}],["b00a",{"_index":8194,"t":{"2252":{"position":[[2102,4]]}}}],["b05c",{"_index":8202,"t":{"2252":{"position":[[2171,4]]}}}],["b07ad6a84982471b9a344ef9947f0e0f",{"_index":305,"t":{"28":{"position":[[3089,32]]}}}],["b0a7",{"_index":11148,"t":{"4051":{"position":[[1169,4]]}}}],["b0af",{"_index":9118,"t":{"2780":{"position":[[152,4]]},"2782":{"position":[[367,4]]},"2784":{"position":[[414,4]]},"2786":{"position":[[69,4],[348,4]]},"2788":{"position":[[69,4]]},"2790":{"position":[[290,4]]},"2792":{"position":[[69,4]]}}}],["b0fd",{"_index":4301,"t":{"1005":{"position":[[3097,4],[3319,4],[3538,4],[3653,4],[5951,4]]},"1896":{"position":[[3097,4],[3319,4],[3538,4],[3653,4],[5951,4]]}}}],["b222",{"_index":11083,"t":{"3990":{"position":[[2097,4]]}}}],["b23f",{"_index":7996,"t":{"2207":{"position":[[630,4],[759,4],[810,4]]}}}],["b342f37804f14459bdf703573169bf79",{"_index":255,"t":{"28":{"position":[[1341,32]]}}}],["b34744f7",{"_index":8159,"t":{"2250":{"position":[[1055,8]]}}}],["b35e",{"_index":4792,"t":{"1179":{"position":[[1493,4],[1773,4],[1824,4],[1906,4],[1967,4],[2018,4]]}}}],["b3d3",{"_index":9114,"t":{"2778":{"position":[[217,4]]},"2780":{"position":[[80,4],[299,4]]},"2782":{"position":[[169,4]]},"2784":{"position":[[155,4]]},"2786":{"position":[[150,4]]}}}],["b43cfafbcf1f4eb08865b2886c29e09b",{"_index":219,"t":{"28":{"position":[[157,32]]}}}],["b48f65f76f43",{"_index":10255,"t":{"3594":{"position":[[326,12]]}}}],["b495",{"_index":4335,"t":{"1005":{"position":[[5038,4],[5321,4],[5540,4],[5755,4],[6289,4]]},"1896":{"position":[[5038,4],[5321,4],[5540,4],[5755,4],[6289,4]]}}}],["b49c3c093062",{"_index":3584,"t":{"894":{"position":[[2146,12]]},"1752":{"position":[[2146,12]]}}}],["b5139b",{"_index":7027,"t":{"1704":{"position":[[578,6]]}}}],["b55a",{"_index":4766,"t":{"1177":{"position":[[4805,4],[5093,4],[5144,4],[5671,4],[5978,4],[6316,4],[6358,4]]}}}],["b57f",{"_index":4714,"t":{"1177":{"position":[[1325,4],[1599,4],[1650,4],[1698,4],[2227,4],[2475,4],[2761,4],[2803,4],[2972,4]]}}}],["b57f8d2489be",{"_index":8158,"t":{"2250":{"position":[[1008,12]]},"2252":{"position":[[2579,12]]}}}],["b621",{"_index":8175,"t":{"2252":{"position":[[1172,4],[2652,4]]}}}],["b682eb90fb834278afb1182018dd2133",{"_index":265,"t":{"28":{"position":[[1526,32]]}}}],["b6a3834a",{"_index":11042,"t":{"3990":{"position":[[655,8]]}}}],["b744",{"_index":6926,"t":{"1698":{"position":[[738,4]]}}}],["b76a",{"_index":4251,"t":{"995":{"position":[[3006,4]]},"1886":{"position":[[3006,4]]},"2764":{"position":[[221,4]]}}}],["b77c5aeb",{"_index":7207,"t":{"1732":{"position":[[664,8],[1475,8]]},"1734":{"position":[[665,8],[1669,8]]}}}],["b7a6",{"_index":8124,"t":{"2240":{"position":[[951,4]]},"2764":{"position":[[291,4]]}}}],["b7b7",{"_index":6662,"t":{"1659":{"position":[[86,4],[220,4]]}}}],["b7e9d7b848f4",{"_index":4568,"t":{"1163":{"position":[[263,12]]}}}],["b8210b4e",{"_index":8199,"t":{"2252":{"position":[[2152,8]]}}}],["b879",{"_index":6967,"t":{"1700":{"position":[[129,4]]}}}],["b910",{"_index":11032,"t":{"3988":{"position":[[1339,4]]}}}],["b93f",{"_index":11094,"t":{"3990":{"position":[[2220,4]]}}}],["b97d38bf128b4479981c4dbe2ef70cd5",{"_index":227,"t":{"28":{"position":[[420,32]]}}}],["b98e46fc7bcf",{"_index":6968,"t":{"1700":{"position":[[134,12]]}}}],["b991",{"_index":9077,"t":{"2764":{"position":[[137,4]]}}}],["b9a8",{"_index":4142,"t":{"993":{"position":[[79,4],[177,4]]},"1884":{"position":[[79,4],[177,4]]}}}],["b9bf5ecbcb2f",{"_index":6980,"t":{"1700":{"position":[[288,12]]}}}],["b=$a$a",{"_index":6985,"t":{"1700":{"position":[[604,6]]}}}],["ba03cdcc255d",{"_index":4229,"t":{"995":{"position":[[2128,12]]},"1886":{"position":[[2128,12]]}}}],["ba1f",{"_index":4140,"t":{"993":{"position":[[69,4],[167,4]]},"1884":{"position":[[69,4],[167,4]]}}}],["ba8b",{"_index":7159,"t":{"1713":{"position":[[1997,4],[2364,4]]}}}],["back",{"_index":1037,"t":{"169":{"position":[[756,4]]},"171":{"position":[[996,4]]},"332":{"position":[[102,7]]},"530":{"position":[[1352,4]]},"699":{"position":[[31,4]]},"703":{"position":[[38,4],[117,4]]},"705":{"position":[[572,4]]},"706":{"position":[[619,6],[944,6]]},"708":{"position":[[65,4],[810,4],[982,4],[1189,4]]},"715":{"position":[[775,6]]},"732":{"position":[[1056,5]]},"739":{"position":[[548,4],[1511,6]]},"963":{"position":[[3190,4]]},"973":{"position":[[256,7],[306,4],[428,4],[615,6]]},"978":{"position":[[2357,4]]},"1383":{"position":[[865,6],[2240,4]]},"1580":{"position":[[122,4],[215,4]]},"1854":{"position":[[3190,4]]},"1864":{"position":[[256,7],[306,4],[428,4],[615,6]]},"1869":{"position":[[2357,4]]},"1923":{"position":[[122,4],[215,4]]},"2155":{"position":[[282,6]]},"2178":{"position":[[691,6]]},"2196":{"position":[[432,4]]},"2325":{"position":[[159,6]]},"2327":{"position":[[227,6],[509,6]]},"2392":{"position":[[159,6]]},"2394":{"position":[[227,6],[509,6]]},"2431":{"position":[[2606,4]]},"2489":{"position":[[936,4]]},"2584":{"position":[[174,7],[900,6]]},"2586":{"position":[[510,6]]},"2600":{"position":[[313,6]]},"2987":{"position":[[3190,4]]},"2997":{"position":[[256,7],[306,4],[428,4],[615,6]]},"3002":{"position":[[2357,4]]},"3067":{"position":[[208,4]]},"3214":{"position":[[404,4]]},"3323":{"position":[[301,4]]},"3722":{"position":[[672,4]]},"3815":{"position":[[536,4]]},"3928":{"position":[[14,7],[3125,6]]},"4098":{"position":[[84,4]]},"4107":{"position":[[1149,4]]},"4376":{"position":[[650,6],[712,6],[777,6],[853,6]]},"4385":{"position":[[342,6]]},"4397":{"position":[[122,4]]},"4401":{"position":[[231,6],[305,6],[390,6]]},"4481":{"position":[[611,4],[688,4]]},"4483":{"position":[[36,6],[202,6],[276,4]]},"4493":{"position":[[24,6]]},"4535":{"position":[[1719,4]]}}}],["backbon",{"_index":8572,"t":{"2520":{"position":[[79,8]]}}}],["backend",{"_index":2077,"t":{"323":{"position":[[826,7]]},"701":{"position":[[107,7]]},"719":{"position":[[6,7],[285,9],[391,7]]},"734":{"position":[[107,7]]},"838":{"position":[[297,9]]},"848":{"position":[[332,8],[426,8],[471,8],[554,7]]},"850":{"position":[[140,7]]},"861":{"position":[[291,8],[966,7]]},"863":{"position":[[55,7]]},"924":{"position":[[1684,8]]},"1046":{"position":[[295,7]]},"1048":{"position":[[259,7]]},"1050":{"position":[[452,7],[543,7]]},"1297":{"position":[[1500,9]]},"1385":{"position":[[1281,7]]},"1505":{"position":[[748,7]]},"1552":{"position":[[699,8],[929,8],[1159,8],[1360,8]]},"1694":{"position":[[4536,7],[4689,7]]},"1762":{"position":[[291,8],[966,7]]},"1764":{"position":[[55,7]]},"1815":{"position":[[1684,8]]},"2029":{"position":[[587,7]]},"2319":{"position":[[523,7],[624,7]]},"2329":{"position":[[786,8]]},"2337":{"position":[[413,8]]},"2339":{"position":[[1241,8]]},"2386":{"position":[[523,7],[624,7]]},"2396":{"position":[[786,8]]},"2404":{"position":[[413,8]]},"2406":{"position":[[1241,8]]},"2580":{"position":[[270,7]]},"2649":{"position":[[1417,8]]},"2661":{"position":[[131,8]]},"2740":{"position":[[998,8]]},"2867":{"position":[[4,7]]},"2948":{"position":[[1684,8]]},"3288":{"position":[[346,7]]},"3928":{"position":[[700,7]]},"3941":{"position":[[150,9],[190,7],[476,7],[1430,7],[1616,8]]},"3943":{"position":[[346,7],[534,7]]},"3947":{"position":[[623,7],[684,9],[805,7],[1345,8],[1698,7],[2224,8],[2964,8],[4318,7],[4525,7]]},"3951":{"position":[[117,7],[169,7],[278,7]]},"4005":{"position":[[203,8]]},"4007":{"position":[[169,7]]},"4028":{"position":[[311,8]]},"4030":{"position":[[73,8]]},"4060":{"position":[[41,9]]},"4077":{"position":[[967,7]]},"4081":{"position":[[120,8]]},"4096":{"position":[[618,8]]},"4104":{"position":[[754,7]]},"4111":{"position":[[215,7]]},"4113":{"position":[[855,7],[973,7]]},"4120":{"position":[[162,7],[282,7],[340,7]]},"4122":{"position":[[133,7]]},"4124":{"position":[[472,7],[1570,7],[1842,7],[2021,7],[2206,7],[2286,7]]},"4130":{"position":[[743,7]]},"4135":{"position":[[681,8]]},"4155":{"position":[[667,8]]},"4163":{"position":[[2904,8],[2984,9],[3012,8],[3309,8],[3579,8],[4038,7]]},"4167":{"position":[[148,7]]},"4204":{"position":[[498,8]]},"4230":{"position":[[3718,7]]},"4240":{"position":[[437,7]]},"4302":{"position":[[133,7],[1289,8],[1432,7],[1568,7],[1773,7],[3993,8],[4167,8],[4592,7],[4647,8],[5095,7]]},"4308":{"position":[[171,7],[527,8],[743,7],[1232,8]]},"4333":{"position":[[12,8],[144,7],[262,8],[506,7],[605,8]]},"4475":{"position":[[684,7]]},"4562":{"position":[[5059,7],[5365,8],[5500,7],[7460,7]]},"4591":{"position":[[935,7]]},"4593":{"position":[[983,8],[1441,7],[1893,7],[2902,8],[5344,8],[5424,7]]},"4853":{"position":[[405,8]]}}}],["backfil",{"_index":11836,"t":{"4738":{"position":[[318,12]]},"4742":{"position":[[74,12]]},"4744":{"position":[[642,12],[831,12]]},"4746":{"position":[[251,11]]}}}],["background",{"_index":1427,"t":{"199":{"position":[[343,11],[2868,12]]},"386":{"position":[[96,11],[398,11]]},"391":{"position":[[292,11]]},"397":{"position":[[122,11]]},"706":{"position":[[1527,10],[1894,10]]},"1655":{"position":[[82,10]]},"1692":{"position":[[258,10]]},"3294":{"position":[[425,11]]}}}],["backport",{"_index":9844,"t":{"3185":{"position":[[878,10]]},"3264":{"position":[[711,8]]},"4257":{"position":[[1929,10]]},"4533":{"position":[[454,10]]}}}],["backup",{"_index":1920,"t":{"293":{"position":[[810,6],[831,7],[907,6]]},"696":{"position":[[53,6],[148,6],[673,7],[691,6],[975,7],[1037,6],[1123,6],[1451,8],[1475,6]]},"699":{"position":[[501,6]]},"701":{"position":[[2680,6]]},"705":{"position":[[243,6],[766,6],[812,6],[1523,6],[1657,6],[1778,6]]},"706":{"position":[[24,6],[78,6],[1042,6],[1147,6],[1277,6],[1430,6],[1824,6],[2071,7]]},"708":{"position":[[32,6],[117,7],[853,6],[883,6],[904,6],[1034,6],[1211,6],[1232,6],[1292,6]]},"730":{"position":[[24,6],[141,6]]},"732":{"position":[[556,6],[1232,6]]},"734":{"position":[[185,6]]},"738":{"position":[[589,6],[710,6],[861,6],[937,6]]},"739":{"position":[[90,6],[237,6],[336,6],[583,6],[604,6],[708,6],[742,6],[1170,6],[1331,6],[1352,6],[1432,6],[1446,6],[1940,7]]},"755":{"position":[[315,6]]},"914":{"position":[[2891,10],[4233,10],[5547,10]]},"1238":{"position":[[630,7]]},"1387":{"position":[[251,7]]},"1411":{"position":[[553,7]]},"1457":{"position":[[2890,6]]},"1474":{"position":[[433,8]]},"1484":{"position":[[251,7],[726,7]]},"1555":{"position":[[30,7],[73,8],[149,6],[204,6],[321,7],[398,7],[561,8],[1006,8],[1085,6]]},"1798":{"position":[[2891,10],[4233,10],[5547,10]]},"1979":{"position":[[251,7]]},"2148":{"position":[[251,7]]},"2317":{"position":[[69,7]]},"2323":{"position":[[269,6]]},"2325":{"position":[[25,6],[105,6],[271,6],[350,6],[643,6],[971,6],[1207,6],[1237,6]]},"2327":{"position":[[389,8],[869,6],[957,6]]},"2329":{"position":[[78,6],[95,7],[264,7],[278,7],[480,6],[566,7],[608,7],[685,7],[715,6],[779,6],[820,6],[911,6]]},"2331":{"position":[[0,7],[40,6],[116,6],[157,7],[227,7],[281,6]]},"2333":{"position":[[19,7],[110,7],[222,7],[310,6],[359,7],[429,7],[483,6]]},"2335":{"position":[[19,6],[110,6],[197,6],[258,7],[300,6],[359,6]]},"2337":{"position":[[146,6],[353,6],[460,6],[548,6]]},"2339":{"position":[[113,7],[665,6],[855,6],[1181,6],[1288,6],[1376,6]]},"2343":{"position":[[244,6]]},"2345":{"position":[[78,7]]},"2347":{"position":[[623,6]]},"2349":{"position":[[18,7],[113,6],[217,6]]},"2351":{"position":[[44,7]]},"2353":{"position":[[34,7]]},"2355":{"position":[[11,6],[89,7],[130,7],[193,6],[241,7],[289,6],[321,6],[427,6],[458,6],[619,6],[695,8],[721,6],[911,6],[975,6],[1033,8],[1112,6],[1180,6],[1378,7],[1520,6],[1535,8],[1568,6],[1704,6],[1925,6],[1978,6],[2310,6],[2544,6],[2727,7],[2929,6],[2962,6],[3054,7]]},"2384":{"position":[[69,7]]},"2390":{"position":[[269,6]]},"2392":{"position":[[25,6],[105,6],[271,6],[350,6],[643,6],[971,6],[1207,6],[1237,6]]},"2394":{"position":[[389,8],[869,6],[957,6]]},"2396":{"position":[[78,6],[95,7],[264,7],[278,7],[480,6],[566,7],[608,7],[685,7],[715,6],[779,6],[820,6],[911,6]]},"2398":{"position":[[0,7],[40,6],[116,6],[157,7],[227,7],[281,6]]},"2400":{"position":[[19,7],[110,7],[222,7],[310,6],[359,7],[429,7],[483,6]]},"2402":{"position":[[19,6],[110,6],[197,6],[258,7],[300,6],[359,6]]},"2404":{"position":[[146,6],[353,6],[460,6],[548,6]]},"2406":{"position":[[113,7],[665,6],[855,6],[1181,6],[1288,6],[1376,6]]},"2410":{"position":[[244,6]]},"2412":{"position":[[78,7]]},"2414":{"position":[[623,6]]},"2416":{"position":[[18,7],[113,6],[217,6]]},"2418":{"position":[[44,7]]},"2420":{"position":[[34,7]]},"2422":{"position":[[11,6],[89,7],[130,7],[193,6],[241,7],[289,6],[321,6],[427,6],[458,6],[619,6],[695,8],[721,6],[911,6],[975,6],[1033,8],[1112,6],[1180,6],[1378,7],[1520,6],[1535,8],[1568,6],[1704,6],[1925,6],[1978,6],[2310,6],[2544,6],[2727,7],[2929,6],[2962,6],[3054,7]]},"3185":{"position":[[1019,7]]},"3352":{"position":[[1295,6],[1712,6]]},"3398":{"position":[[1497,6]]},"3928":{"position":[[1416,6]]},"4094":{"position":[[34,7]]},"4098":{"position":[[835,8]]},"4100":{"position":[[189,7]]},"4102":{"position":[[215,7],[1054,6]]},"4104":{"position":[[459,6],[971,7]]},"4107":{"position":[[1199,6],[1385,6],[1529,6],[1682,6]]},"4116":{"position":[[386,7]]},"4120":{"position":[[11,6],[267,6],[454,6]]},"4124":{"position":[[22,6],[97,6],[195,6],[307,6],[368,6],[634,8],[908,7],[1006,6],[1062,6],[1200,6],[1370,7],[1424,6],[1589,7],[1745,7],[1958,6],[1987,6],[2070,6],[2236,8],[2358,8],[2466,6]]},"4126":{"position":[[72,6],[147,6],[306,6],[347,6]]},"4128":{"position":[[27,6],[65,6]]},"4130":{"position":[[113,6],[175,6],[321,6],[365,6],[475,6],[769,8]]},"4163":{"position":[[1915,6],[3642,6]]},"4165":{"position":[[849,6],[917,6]]},"4222":{"position":[[2496,6]]},"4420":{"position":[[1278,6]]},"4475":{"position":[[315,6]]},"4483":{"position":[[333,7],[433,6],[499,7],[590,7],[663,6]]},"4493":{"position":[[97,7],[336,7],[365,6],[531,7]]},"4562":{"position":[[6275,6]]},"4773":{"position":[[484,6]]},"4826":{"position":[[1941,6]]}}}],["backup'",{"_index":8397,"t":{"2355":{"position":[[2060,8],[2655,8]]},"2422":{"position":[[2060,8],[2655,8]]}}}],["backup.keyr",{"_index":6311,"t":{"1503":{"position":[[2106,14]]},"1525":{"position":[[1805,14]]}}}],["backup.velero.io/backup",{"_index":3166,"t":{"708":{"position":[[1143,23]]},"739":{"position":[[502,23]]}}}],["backup/ceph.client.cind",{"_index":6310,"t":{"1503":{"position":[[2080,25]]},"1525":{"position":[[1779,25]]}}}],["backup/ceph.client.cinder.keyr",{"_index":6309,"t":{"1503":{"position":[[1998,33]]},"1525":{"position":[[1697,33]]}}}],["backup/manag",{"_index":7750,"t":{"2155":{"position":[[463,15],[855,15]]}}}],["backup/restor",{"_index":3222,"t":{"739":{"position":[[153,14]]}}}],["backup=tru",{"_index":3162,"t":{"708":{"position":[[335,11],[498,11],[798,11]]}}}],["backup_gigabyt",{"_index":3702,"t":{"914":{"position":[[2867,20],[4209,20],[5522,20]]},"1798":{"position":[[2867,20],[4209,20],[5522,20]]}}}],["backup_id",{"_index":8399,"t":{"2355":{"position":[[2240,11],[2259,13],[2322,10]]},"2422":{"position":[[2240,11],[2259,13],[2322,10]]}}}],["backup_name_or_id",{"_index":8394,"t":{"2355":{"position":[[736,18],[1203,18],[2985,18]]},"2422":{"position":[[736,18],[1203,18],[2985,18]]}}}],["backup_s",{"_index":8402,"t":{"2355":{"position":[[2766,12]]},"2422":{"position":[[2766,12]]}}}],["backupstorageloc",{"_index":3220,"t":{"738":{"position":[[1089,21],[1203,22]]}}}],["backward",{"_index":9822,"t":{"3170":{"position":[[244,9]]},"3402":{"position":[[126,8]]},"3651":{"position":[[99,9]]},"3688":{"position":[[99,9]]},"3775":{"position":[[99,9]]},"3894":{"position":[[1214,9]]},"3910":{"position":[[520,9]]},"4667":{"position":[[13090,9]]}}}],["bad",{"_index":1171,"t":{"173":{"position":[[2308,3]]},"181":{"position":[[1999,3]]},"940":{"position":[[1063,3]]},"1831":{"position":[[1063,3]]},"2964":{"position":[[1063,3]]},"3928":{"position":[[4349,3]]},"4257":{"position":[[1854,3]]},"4310":{"position":[[805,3]]},"4535":{"position":[[184,3],[1091,3],[1588,3]]},"4537":{"position":[[244,3]]},"4539":{"position":[[38,3]]},"4543":{"position":[[70,3]]},"4547":{"position":[[1305,3]]}}}],["badg",{"_index":1619,"t":{"222":{"position":[[51,5],[69,6]]}}}],["bafd",{"_index":10254,"t":{"3594":{"position":[[321,4]]}}}],["balanc",{"_index":3318,"t":{"828":{"position":[[293,10]]},"846":{"position":[[310,9]]},"1077":{"position":[[133,8]]},"1455":{"position":[[532,8]]},"1605":{"position":[[580,9]]},"2574":{"position":[[283,8]]},"2678":{"position":[[383,8]]},"3310":{"position":[[750,7]]},"3317":{"position":[[21,8]]},"3759":{"position":[[316,10]]},"4202":{"position":[[339,8],[361,8]]},"4226":{"position":[[536,10],[1572,10]]},"4504":{"position":[[342,7]]},"4512":{"position":[[247,7]]},"4580":{"position":[[2757,10],[3304,10]]},"4660":{"position":[[3231,10]]}}}],["balancer_memb",{"_index":3617,"t":{"908":{"position":[[395,15]]},"1792":{"position":[[395,15]]},"4667":{"position":[[13934,16]]}}}],["balancer_member':%(target.role.name)",{"_index":5712,"t":{"1324":{"position":[[6261,37]]},"4667":{"position":[[6289,38],[14086,37]]}}}],["balenaetch",{"_index":7307,"t":{"2032":{"position":[[514,12]]}}}],["ballpen",{"_index":1613,"t":{"222":{"position":[[0,8]]}}}],["banana",{"_index":1657,"t":{"233":{"position":[[83,7]]}}}],["band",{"_index":4404,"t":{"1046":{"position":[[254,4]]},"1048":{"position":[[302,4]]},"1050":{"position":[[11,4],[328,4]]}}}],["bandwidth",{"_index":3286,"t":{"812":{"position":[[452,9]]},"1118":{"position":[[147,9],[224,9],[420,9]]},"1720":{"position":[[2950,9],[3029,9]]},"2184":{"position":[[4083,9]]},"3323":{"position":[[427,9]]},"3665":{"position":[[462,9],[573,9]]},"3673":{"position":[[1060,9]]},"3702":{"position":[[534,9],[645,9]]},"3714":{"position":[[385,9],[1944,9],[1982,10],[2126,9]]},"3789":{"position":[[534,9],[645,9]]},"3807":{"position":[[714,9]]},"3932":{"position":[[177,9],[471,9]]},"4163":{"position":[[1316,9]]},"4167":{"position":[[886,10]]},"4185":{"position":[[447,9]]},"4385":{"position":[[408,10]]},"4562":{"position":[[2133,9]]}}}],["bandwidth_poll_interv",{"_index":5520,"t":{"1301":{"position":[[2678,23],[2783,23],[2850,23],[2890,23],[3007,23],[3123,23],[3152,23]]}}}],["bandwith",{"_index":4408,"t":{"1050":{"position":[[55,9]]}}}],["bar",{"_index":1568,"t":{"214":{"position":[[0,3],[126,4],[180,4]]},"255":{"position":[[296,3]]},"928":{"position":[[373,7]]},"1819":{"position":[[373,7]]},"2431":{"position":[[473,4],[550,5],[1129,4],[1396,6],[1441,5],[2460,6],[2652,6],[2682,5],[3647,4],[3916,6],[4235,4]]},"2952":{"position":[[373,7]]}}}],["bar/endpoint",{"_index":8445,"t":{"2431":{"position":[[3063,13]]}}}],["barbican",{"_index":4451,"t":{"1077":{"position":[[187,9]]},"1281":{"position":[[0,8],[21,8],[50,8]]},"1657":{"position":[[529,8]]},"2225":{"position":[[315,8]]},"2319":{"position":[[682,10],[783,8]]},"2323":{"position":[[223,8]]},"2325":{"position":[[896,9],[919,8]]},"2329":{"position":[[241,8],[316,8]]},"2341":{"position":[[31,8],[165,8],[290,8],[554,8]]},"2343":{"position":[[117,9],[208,8],[534,8],[838,8],[929,8]]},"2347":{"position":[[27,8],[70,8],[435,9]]},"2360":{"position":[[37,8]]},"2386":{"position":[[682,10],[783,8]]},"2390":{"position":[[223,8]]},"2392":{"position":[[896,9],[919,8]]},"2396":{"position":[[241,8],[316,8]]},"2408":{"position":[[31,8],[165,8],[290,8],[554,8]]},"2410":{"position":[[117,9],[208,8],[534,8],[838,8],[929,8]]},"2414":{"position":[[27,8],[70,8],[435,9]]},"2427":{"position":[[37,8]]},"3016":{"position":[[779,9]]},"4060":{"position":[[55,8],[168,8],[352,8],[389,8],[506,9],[746,8],[782,8],[945,8]]},"4062":{"position":[[122,8]]},"4068":{"position":[[340,8]]},"4070":{"position":[[0,8]]},"4073":{"position":[[473,9]]},"4075":{"position":[[138,8]]},"4077":{"position":[[122,8],[703,8]]},"4079":{"position":[[94,8],[301,8],[539,9]]},"4081":{"position":[[195,8],[603,8],[964,8],[1417,9]]},"4083":{"position":[[116,10]]},"4087":{"position":[[0,8]]},"4113":{"position":[[1038,10],[1139,8]]},"4204":{"position":[[413,8]]}}}],["barbican_api_work",{"_index":5595,"t":{"1305":{"position":[[880,20]]}}}],["barbican_public_endpoint",{"_index":5413,"t":{"1297":{"position":[[365,25]]}}}],["barbican_tag",{"_index":5329,"t":{"1292":{"position":[[341,13]]}}}],["barbican_worker_tag",{"_index":5331,"t":{"1292":{"position":[[448,20]]}}}],["barbicancli",{"_index":374,"t":{"37":{"position":[[1200,14]]}}}],["bare",{"_index":2412,"t":{"465":{"position":[[56,4]]},"1013":{"position":[[91,4]]},"1054":{"position":[[91,4]]},"1077":{"position":[[309,4]]},"1455":{"position":[[486,4]]},"1457":{"position":[[498,4]]},"1460":{"position":[[432,4],[474,4]]},"2021":{"position":[[403,4]]},"2025":{"position":[[210,4]]},"2608":{"position":[[1210,4]]},"2849":{"position":[[8,4]]},"3022":{"position":[[36,4],[70,4]]},"3044":{"position":[[249,4]]},"3064":{"position":[[11,4],[159,4]]},"3081":{"position":[[59,4]]},"3086":{"position":[[1174,4]]},"3656":{"position":[[369,4]]},"3667":{"position":[[89,4],[228,4]]},"3669":{"position":[[293,4]]},"3693":{"position":[[428,4]]},"3708":{"position":[[101,4],[240,4]]},"3710":{"position":[[306,4],[857,4]]},"3712":{"position":[[2070,4]]},"3780":{"position":[[428,4]]},"3801":{"position":[[89,4],[228,4]]},"3803":{"position":[[293,4],[844,4]]},"3805":{"position":[[1168,4]]},"3960":{"position":[[773,4]]},"4045":{"position":[[913,6]]},"4204":{"position":[[235,4],[253,4]]},"4429":{"position":[[110,4],[190,4],[370,4]]},"4442":{"position":[[86,4],[166,4],[346,4]]},"4453":{"position":[[86,4],[166,4],[346,4]]}}}],["baremet",{"_index":4433,"t":{"1067":{"position":[[44,9],[932,9],[1611,9],[1906,9],[2033,9]]},"1263":{"position":[[7,9]]},"2644":{"position":[[525,10]]},"2672":{"position":[[525,10]]},"3761":{"position":[[15,9]]}}}],["barrier",{"_index":949,"t":{"165":{"position":[[89,7]]},"177":{"position":[[1359,7]]},"212":{"position":[[154,7]]},"3971":{"position":[[1030,7]]},"4504":{"position":[[71,7]]},"4506":{"position":[[1305,7]]},"4512":{"position":[[198,7]]},"4522":{"position":[[1705,7]]}}}],["base",{"_index":559,"t":{"76":{"position":[[67,4]]},"171":{"position":[[1085,4]]},"181":{"position":[[1990,5]]},"249":{"position":[[437,5]]},"253":{"position":[[158,5]]},"255":{"position":[[63,5]]},"280":{"position":[[1429,4]]},"286":{"position":[[123,5]]},"303":{"position":[[268,5]]},"315":{"position":[[168,5]]},"337":{"position":[[522,5]]},"339":{"position":[[233,5],[619,5]]},"364":{"position":[[197,5],[1489,5],[1550,5],[1629,5]]},"368":{"position":[[341,4],[390,4],[1056,6],[1105,4],[1144,4],[2588,4],[6757,4],[6966,4]]},"376":{"position":[[180,5]]},"430":{"position":[[71,4]]},"448":{"position":[[415,4]]},"461":{"position":[[697,5]]},"496":{"position":[[164,5]]},"526":{"position":[[279,4],[476,4],[1028,4],[1225,4]]},"528":{"position":[[32,5]]},"530":{"position":[[1428,5]]},"543":{"position":[[1039,5],[2249,5]]},"557":{"position":[[6982,5]]},"604":{"position":[[483,5]]},"616":{"position":[[62,5]]},"624":{"position":[[193,5]]},"641":{"position":[[35,5]]},"657":{"position":[[368,5]]},"666":{"position":[[35,5]]},"668":{"position":[[485,5],[1244,5]]},"671":{"position":[[854,5],[921,5]]},"706":{"position":[[317,5]]},"712":{"position":[[328,5]]},"732":{"position":[[1513,5]]},"741":{"position":[[497,5]]},"776":{"position":[[44,5]]},"790":{"position":[[26,5]]},"816":{"position":[[151,5]]},"942":{"position":[[2722,5]]},"1025":{"position":[[354,5],[412,5]]},"1038":{"position":[[322,5],[364,6]]},"1061":{"position":[[116,5]]},"1096":{"position":[[31,5]]},"1185":{"position":[[866,4]]},"1252":{"position":[[1329,4]]},"1266":{"position":[[809,4]]},"1301":{"position":[[30,5]]},"1324":{"position":[[585,4]]},"1354":{"position":[[599,5]]},"1389":{"position":[[163,5]]},"1455":{"position":[[346,5],[437,5],[962,4]]},"1468":{"position":[[1148,5]]},"1501":{"position":[[39,5]]},"1503":{"position":[[1495,4]]},"1833":{"position":[[2722,5]]},"2005":{"position":[[127,4]]},"2037":{"position":[[892,5]]},"2076":{"position":[[344,5]]},"2223":{"position":[[90,5],[187,5],[304,5]]},"2285":{"position":[[489,5]]},"2287":{"position":[[165,5]]},"2299":{"position":[[489,5]]},"2301":{"position":[[165,5]]},"2339":{"position":[[633,5]]},"2349":{"position":[[232,5]]},"2355":{"position":[[228,5]]},"2380":{"position":[[855,5]]},"2382":{"position":[[106,5]]},"2406":{"position":[[633,5]]},"2416":{"position":[[232,5]]},"2422":{"position":[[228,5]]},"2478":{"position":[[266,5],[2526,5],[2580,5]]},"2480":{"position":[[0,5],[460,4],[620,5],[716,4]]},"2489":{"position":[[37,5],[232,5],[1530,5],[1590,5]]},"2508":{"position":[[91,5]]},"2518":{"position":[[209,5]]},"2520":{"position":[[397,5],[478,5]]},"2537":{"position":[[462,6]]},"2553":{"position":[[36,5]]},"2574":{"position":[[711,5]]},"2580":{"position":[[129,4]]},"2624":{"position":[[664,5]]},"2686":{"position":[[664,5]]},"2749":{"position":[[38,5]]},"2966":{"position":[[2722,5]]},"3067":{"position":[[1043,5]]},"3083":{"position":[[744,4]]},"3114":{"position":[[169,5]]},"3116":{"position":[[458,4],[577,5]]},"3119":{"position":[[1065,5]]},"3148":{"position":[[299,5]]},"3150":{"position":[[98,4]]},"3168":{"position":[[699,5]]},"3176":{"position":[[170,4]]},"3183":{"position":[[37,5]]},"3221":{"position":[[37,5]]},"3225":{"position":[[67,5]]},"3279":{"position":[[37,5]]},"3292":{"position":[[505,5],[863,5]]},"3294":{"position":[[1322,5]]},"3296":{"position":[[563,5]]},"3298":{"position":[[187,5]]},"3348":{"position":[[374,5],[790,5]]},"3352":{"position":[[405,5],[1427,4],[1604,4],[1644,5],[1773,4],[1813,5]]},"3410":{"position":[[94,5]]},"3502":{"position":[[1044,5]]},"3627":{"position":[[261,5]]},"3868":{"position":[[40,5]]},"3923":{"position":[[354,6],[567,6]]},"3930":{"position":[[200,4]]},"3968":{"position":[[176,5],[896,5],[1997,5]]},"3980":{"position":[[206,5]]},"4073":{"position":[[546,4]]},"4075":{"position":[[361,5]]},"4081":{"position":[[2221,5]]},"4098":{"position":[[436,5]]},"4109":{"position":[[928,5]]},"4113":{"position":[[176,5]]},"4124":{"position":[[165,5]]},"4133":{"position":[[357,5]]},"4135":{"position":[[202,5],[246,5],[284,5]]},"4159":{"position":[[2203,5]]},"4163":{"position":[[9,5]]},"4165":{"position":[[565,5]]},"4224":{"position":[[950,5],[1042,5]]},"4226":{"position":[[0,5],[1923,5]]},"4230":{"position":[[2135,5]]},"4249":{"position":[[194,5]]},"4302":{"position":[[1747,5],[2082,5]]},"4317":{"position":[[101,5]]},"4327":{"position":[[254,5],[701,5]]},"4340":{"position":[[857,4]]},"4351":{"position":[[594,4]]},"4355":{"position":[[475,4]]},"4416":{"position":[[129,5]]},"4420":{"position":[[810,5]]},"4431":{"position":[[966,5]]},"4435":{"position":[[85,4]]},"4479":{"position":[[2221,5]]},"4485":{"position":[[1842,5]]},"4516":{"position":[[1504,5]]},"4518":{"position":[[314,5],[500,5]]},"4520":{"position":[[82,5],[206,5],[677,5]]},"4522":{"position":[[924,5],[1758,5]]},"4527":{"position":[[101,5],[132,5]]},"4539":{"position":[[518,5],[664,5],[4880,5],[5228,5],[5276,5],[5501,5],[5578,5],[5716,5]]},"4554":{"position":[[392,5]]},"4562":{"position":[[166,5],[2064,5],[5445,5],[6562,5],[6593,5]]},"4564":{"position":[[0,5]]},"4580":{"position":[[193,5],[2643,5],[2699,5],[2879,5]]},"4587":{"position":[[111,5],[245,5],[307,5]]},"4593":{"position":[[289,5],[1419,5],[6007,5]]},"4606":{"position":[[95,5]]},"4618":{"position":[[776,5]]},"4632":{"position":[[2906,5]]},"4634":{"position":[[30,5]]},"4656":{"position":[[555,4]]},"4658":{"position":[[0,5]]},"4660":{"position":[[212,5],[1443,5]]},"4662":{"position":[[591,5],[773,5],[819,5],[1825,5],[1855,5]]},"4665":{"position":[[442,5]]},"4667":{"position":[[619,4]]},"4722":{"position":[[810,5],[942,5]]},"4728":{"position":[[44,5],[243,5],[592,5]]},"4730":{"position":[[0,4],[83,5],[127,5],[183,5]]},"4757":{"position":[[5,5],[27,5],[111,5],[133,5]]},"4763":{"position":[[5,5],[27,5],[195,5],[219,5]]},"4767":{"position":[[67,5],[254,5]]},"4797":{"position":[[145,5]]},"4826":{"position":[[4104,5]]},"4839":{"position":[[130,6],[430,5],[800,5]]},"4877":{"position":[[27,5]]}}}],["base.yml",{"_index":5210,"t":{"1257":{"position":[[1252,8]]},"2057":{"position":[[499,8],[779,8]]},"2171":{"position":[[1392,8]]}}}],["base/harbor",{"_index":3054,"t":{"692":{"position":[[663,11]]},"694":{"position":[[39,11]]},"747":{"position":[[383,11]]}}}],["base64",{"_index":2432,"t":{"473":{"position":[[988,6]]},"578":{"position":[[817,6]]},"1425":{"position":[[217,6]]},"1909":{"position":[[249,6]]},"4857":{"position":[[268,6],[460,6]]}}}],["base_",{"_index":11800,"t":{"4667":{"position":[[328,8],[12579,8],[12864,8]]}}}],["base_&st",{"_index":9260,"t":{"2906":{"position":[[505,12]]}}}],["code_block",{"_index":797,"t":{"143":{"position":[[266,13],[471,10],[512,12]]}}}],["codebas",{"_index":1077,"t":{"171":{"position":[[1031,8]]},"4226":{"position":[[3391,8]]}}}],["codeblock",{"_index":791,"t":{"143":{"position":[[42,11],[118,11]]}}}],["codecentric/keycloakx",{"_index":9880,"t":{"3230":{"position":[[147,21]]}}}],["codingchunk",{"_index":6039,"t":{"1407":{"position":[[1994,13],[2303,13]]},"1409":{"position":[[1131,13]]},"1411":{"position":[[2521,13]]}}}],["coexist",{"_index":3944,"t":{"946":{"position":[[892,11]]},"1837":{"position":[[892,11]]},"2970":{"position":[[892,11]]},"3069":{"position":[[182,7]]}}}],["coffe",{"_index":1686,"t":{"239":{"position":[[391,7]]},"243":{"position":[[293,6]]},"245":{"position":[[260,6],[300,7]]}}}],["cognit",{"_index":1787,"t":{"258":{"position":[[142,9]]}}}],["coher",{"_index":10218,"t":{"3563":{"position":[[361,9]]}}}],["cold",{"_index":10967,"t":{"3936":{"position":[[694,4]]}}}],["collabor",{"_index":179,"t":{"24":{"position":[[397,13]]},"59":{"position":[[275,15]]},"72":{"position":[[81,13]]},"187":{"position":[[94,13]]},"197":{"position":[[507,14]]},"280":{"position":[[375,13]]},"3563":{"position":[[15,13]]},"3627":{"position":[[153,13]]},"4224":{"position":[[1491,11]]},"4560":{"position":[[2137,12]]},"4839":{"position":[[338,13]]}}}],["collabora",{"_index":11875,"t":{"4835":{"position":[[291,9]]},"4839":{"position":[[665,11]]},"4849":{"position":[[1590,10]]}}}],["collaborativli",{"_index":1368,"t":{"190":{"position":[[140,15]]}}}],["collater",{"_index":11725,"t":{"4597":{"position":[[905,10]]}}}],["colleagu",{"_index":2963,"t":{"604":{"position":[[347,9]]},"4148":{"position":[[376,11]]}}}],["collect",{"_index":891,"t":{"155":{"position":[[0,11],[86,10],[473,12],[712,11],[910,12]]},"157":{"position":[[100,10]]},"167":{"position":[[374,10]]},"171":{"position":[[668,10]]},"194":{"position":[[87,11]]},"216":{"position":[[507,10]]},"228":{"position":[[22,10]]},"247":{"position":[[16,7]]},"264":{"position":[[277,9]]},"450":{"position":[[63,10]]},"541":{"position":[[1182,8]]},"928":{"position":[[302,7]]},"1140":{"position":[[55,10]]},"1443":{"position":[[1151,10]]},"1445":{"position":[[55,10]]},"1453":{"position":[[55,10]]},"1472":{"position":[[2348,10]]},"1474":{"position":[[310,12]]},"1476":{"position":[[287,12]]},"1819":{"position":[[302,7]]},"2057":{"position":[[138,10],[171,10],[205,10]]},"2071":{"position":[[1108,10],[1143,10],[1181,10],[1701,10]]},"2074":{"position":[[272,10],[329,10]]},"2110":{"position":[[381,10],[536,10],[688,10],[842,10],[1008,10],[1176,10],[1328,10],[1483,10],[1645,10],[1798,10],[1951,10],[2105,10],[2260,10],[2415,10],[2569,10],[2722,10],[2879,10],[3039,10],[3184,10],[3336,10]]},"2551":{"position":[[277,8]]},"2626":{"position":[[410,7]]},"2632":{"position":[[224,8]]},"2647":{"position":[[990,10],[1398,9]]},"2716":{"position":[[681,7]]},"2758":{"position":[[514,11]]},"2867":{"position":[[102,9]]},"2952":{"position":[[302,7]]},"3044":{"position":[[126,11]]},"3052":{"position":[[124,10]]},"3119":{"position":[[266,10]]},"3144":{"position":[[83,9]]},"3168":{"position":[[139,9]]},"3292":{"position":[[795,9]]},"3357":{"position":[[1782,10]]},"3592":{"position":[[1264,10],[1767,10],[2157,10],[2185,10],[2246,10]]},"3625":{"position":[[200,10]]},"4283":{"position":[[359,10]]},"4291":{"position":[[250,7]]},"4420":{"position":[[2008,10]]},"4562":{"position":[[6632,10]]},"4738":{"position":[[178,10]]},"4740":{"position":[[511,9]]},"4757":{"position":[[244,10]]}}}],["collectd",{"_index":6655,"t":{"1657":{"position":[[690,8]]}}}],["collections/ansible.posix.git",{"_index":920,"t":{"155":{"position":[[1019,29]]}}}],["collectiv",{"_index":1354,"t":{"187":{"position":[[801,16]]}}}],["collector",{"_index":6153,"t":{"1437":{"position":[[8,9]]},"2716":{"position":[[1127,9],[1298,9]]}}}],["collis",{"_index":11761,"t":{"4643":{"position":[[3005,11]]}}}],["coloc",{"_index":11285,"t":{"4222":{"position":[[623,10]]}}}],["colon",{"_index":10921,"t":{"3902":{"position":[[303,6]]}}}],["color",{"_index":762,"t":{"139":{"position":[[32,6]]},"199":{"position":[[480,6]]},"938":{"position":[[1508,7]]},"963":{"position":[[3684,6],[3829,6],[3955,6]]},"1829":{"position":[[1508,7]]},"1854":{"position":[[3684,6],[3829,6],[3955,6]]},"2052":{"position":[[646,6]]},"2489":{"position":[[1715,5]]},"2902":{"position":[[108,5]]},"2930":{"position":[[698,6],[743,5],[785,5],[1509,8],[1651,5],[1660,6],[1694,8],[1717,5],[1814,8],[1898,8]]},"2932":{"position":[[130,6],[159,5],[213,5]]},"2962":{"position":[[1508,7]]},"2987":{"position":[[3684,6],[3829,6],[3955,6]]}}}],["colorblind",{"_index":9319,"t":{"2930":{"position":[[1529,13],[1734,10],[1750,13],[1834,13],[1918,13]]}}}],["column",{"_index":10095,"t":{"3390":{"position":[[376,6],[502,6],[623,6]]},"3398":{"position":[[383,6],[509,6],[630,6]]},"3468":{"position":[[339,6],[465,6],[586,6]]},"3470":{"position":[[356,6],[482,6],[603,6]]},"3502":{"position":[[371,6],[497,6],[618,6]]},"4015":{"position":[[83,6]]},"4107":{"position":[[1751,7]]},"4539":{"position":[[1966,7]]},"4826":{"position":[[463,6],[589,6],[710,6]]}}}],["column'",{"_index":7959,"t":{"2196":{"position":[[2758,8]]}}}],["com1",{"_index":5506,"t":{"1301":{"position":[[1519,5]]}}}],["combin",{"_index":959,"t":{"167":{"position":[[330,8]]},"171":{"position":[[638,8]]},"179":{"position":[[953,11]]},"323":{"position":[[1349,12]]},"327":{"position":[[165,11]]},"332":{"position":[[26,8]]},"485":{"position":[[137,11]]},"645":{"position":[[196,7]]},"677":{"position":[[196,7]]},"928":{"position":[[894,8]]},"1246":{"position":[[318,8]]},"1369":{"position":[[200,12]]},"1819":{"position":[[894,8]]},"2065":{"position":[[1229,8],[1548,8],[1869,8],[2200,8],[2522,8],[2844,8],[3165,8],[3481,8]]},"2130":{"position":[[61,11]]},"2283":{"position":[[596,8]]},"2285":{"position":[[908,11],[1084,11]]},"2293":{"position":[[268,9]]},"2297":{"position":[[596,8]]},"2299":{"position":[[908,11],[1084,11]]},"2307":{"position":[[268,9]]},"2952":{"position":[[894,8]]},"3761":{"position":[[891,8]]},"3930":{"position":[[369,12]]},"4043":{"position":[[382,11]]},"4045":{"position":[[1906,11]]},"4163":{"position":[[801,11],[3120,11]]},"4257":{"position":[[3318,11]]},"4289":{"position":[[509,11]]},"4304":{"position":[[870,11],[2791,9]]},"4459":{"position":[[1647,11]]},"4479":{"position":[[413,11]]},"4487":{"position":[[20,7]]},"4535":{"position":[[496,11]]},"4537":{"position":[[537,11]]},"4541":{"position":[[1330,11]]},"4569":{"position":[[580,8]]},"4593":{"position":[[6169,8]]},"4691":{"position":[[549,11]]}}}],["come",{"_index":515,"t":{"72":{"position":[[20,4]]},"167":{"position":[[725,6]]},"173":{"position":[[1082,5]]},"181":{"position":[[2617,4]]},"199":{"position":[[2808,5]]},"218":{"position":[[338,4]]},"378":{"position":[[696,4]]},"446":{"position":[[552,4]]},"504":{"position":[[312,5]]},"543":{"position":[[1436,5]]},"611":{"position":[[260,5]]},"696":{"position":[[1562,4]]},"699":{"position":[[424,4]]},"728":{"position":[[1083,4]]},"834":{"position":[[337,5]]},"961":{"position":[[96,5]]},"1050":{"position":[[85,4]]},"1569":{"position":[[431,5]]},"1648":{"position":[[818,4]]},"1852":{"position":[[96,5]]},"1902":{"position":[[581,5]]},"2165":{"position":[[69,4]]},"2433":{"position":[[1083,5]]},"2678":{"position":[[100,5]]},"2985":{"position":[[96,5]]},"3183":{"position":[[305,5]]},"3253":{"position":[[18,4]]},"3281":{"position":[[347,4]]},"3323":{"position":[[219,5]]},"3357":{"position":[[2825,5]]},"3363":{"position":[[17,4]]},"3369":{"position":[[17,4]]},"3582":{"position":[[1568,4]]},"3629":{"position":[[44,5]]},"3693":{"position":[[647,4]]},"3742":{"position":[[29,5]]},"3780":{"position":[[647,4]]},"3831":{"position":[[396,4]]},"3923":{"position":[[700,5]]},"3971":{"position":[[806,6]]},"4079":{"position":[[246,5]]},"4109":{"position":[[2251,4]]},"4372":{"position":[[193,4]]},"4410":{"position":[[268,4]]},"4580":{"position":[[3145,5]]},"4587":{"position":[[335,4]]},"4595":{"position":[[375,4]]},"4597":{"position":[[896,5]]},"4740":{"position":[[418,4]]},"4795":{"position":[[112,4]]},"4872":{"position":[[782,5]]}}}],["comma",{"_index":4871,"t":{"1189":{"position":[[300,5]]},"1373":{"position":[[185,5]]},"3598":{"position":[[1222,6],[2137,6]]},"3604":{"position":[[482,6]]}}}],["command",{"_index":687,"t":{"107":{"position":[[128,7]]},"130":{"position":[[512,7]]},"249":{"position":[[1881,7]]},"288":{"position":[[1091,7]]},"386":{"position":[[303,8]]},"434":{"position":[[2221,8]]},"440":{"position":[[521,8]]},"489":{"position":[[350,9],[654,8]]},"491":{"position":[[373,8],[738,7]]},"493":{"position":[[533,9]]},"512":{"position":[[307,9],[1271,8]]},"566":{"position":[[50,9],[194,8]]},"628":{"position":[[9,8],[86,7]]},"653":{"position":[[206,8]]},"655":{"position":[[46,7]]},"671":{"position":[[320,8],[569,7],[606,7]]},"673":{"position":[[46,7]]},"696":{"position":[[189,9],[399,8],[568,8]]},"701":{"position":[[1995,7],[2494,7]]},"705":{"position":[[212,7]]},"706":{"position":[[212,9]]},"708":{"position":[[742,7]]},"906":{"position":[[14,7],[66,8]]},"912":{"position":[[5,7],[271,8],[1870,7],[2070,7],[3779,8],[5938,7]]},"914":{"position":[[13,7],[205,9],[235,7],[332,7],[1322,7],[1522,7]]},"916":{"position":[[113,7]]},"932":{"position":[[1815,7],[3972,8]]},"934":{"position":[[1622,7]]},"938":{"position":[[1158,7]]},"942":{"position":[[2550,7]]},"944":{"position":[[1108,8]]},"978":{"position":[[1902,7]]},"980":{"position":[[267,8]]},"1003":{"position":[[12,7],[64,8]]},"1005":{"position":[[1388,7],[1588,7],[6843,7]]},"1007":{"position":[[97,7]]},"1147":{"position":[[127,7]]},"1185":{"position":[[1994,8]]},"1191":{"position":[[987,7]]},"1261":{"position":[[9,7],[108,7]]},"1303":{"position":[[4147,10],[4611,7],[4784,10]]},"1472":{"position":[[170,8]]},"1491":{"position":[[256,7]]},"1493":{"position":[[212,7]]},"1507":{"position":[[451,8]]},"1509":{"position":[[894,8]]},"1523":{"position":[[1313,7]]},"1574":{"position":[[14,8]]},"1644":{"position":[[111,8]]},"1652":{"position":[[213,7]]},"1655":{"position":[[15,7]]},"1657":{"position":[[16,7]]},"1661":{"position":[[639,8]]},"1667":{"position":[[10,7]]},"1669":{"position":[[128,9]]},"1673":{"position":[[151,7]]},"1677":{"position":[[6,7]]},"1694":{"position":[[42,8],[279,8]]},"1696":{"position":[[333,8]]},"1711":{"position":[[1140,7]]},"1790":{"position":[[14,7],[66,8]]},"1796":{"position":[[5,7],[271,8],[1870,7],[2070,7],[3779,8],[5938,7]]},"1798":{"position":[[13,7],[205,9],[235,7],[332,7],[1322,7],[1522,7]]},"1800":{"position":[[113,7]]},"1823":{"position":[[1815,7],[3972,8]]},"1825":{"position":[[1622,7]]},"1829":{"position":[[1158,7]]},"1833":{"position":[[2550,7]]},"1835":{"position":[[1108,8]]},"1869":{"position":[[1902,7]]},"1871":{"position":[[267,8]]},"1894":{"position":[[12,7],[64,8]]},"1896":{"position":[[1388,7],[1588,7],[6843,7]]},"1898":{"position":[[97,7]]},"1906":{"position":[[105,7]]},"1917":{"position":[[14,8]]},"1977":{"position":[[213,7]]},"1986":{"position":[[134,8]]},"2005":{"position":[[570,7]]},"2041":{"position":[[257,7]]},"2045":{"position":[[26,8]]},"2102":{"position":[[5,7]]},"2150":{"position":[[162,7],[430,7]]},"2155":{"position":[[1077,7]]},"2163":{"position":[[4513,7]]},"2199":{"position":[[1127,8]]},"2244":{"position":[[80,7]]},"2285":{"position":[[1452,8]]},"2289":{"position":[[471,8],[695,8]]},"2291":{"position":[[316,7]]},"2295":{"position":[[588,7],[726,7]]},"2299":{"position":[[1452,8]]},"2303":{"position":[[471,8],[695,8]]},"2305":{"position":[[316,7]]},"2309":{"position":[[588,7],[726,7]]},"2327":{"position":[[98,8],[625,8]]},"2331":{"position":[[89,9],[255,8]]},"2333":{"position":[[457,8]]},"2341":{"position":[[376,8]]},"2349":{"position":[[347,7],[410,7]]},"2351":{"position":[[347,7]]},"2355":{"position":[[59,8],[2188,7]]},"2394":{"position":[[98,8],[625,8]]},"2398":{"position":[[89,9],[255,8]]},"2400":{"position":[[457,8]]},"2408":{"position":[[376,8]]},"2416":{"position":[[347,7],[410,7]]},"2418":{"position":[[347,7]]},"2422":{"position":[[59,8],[2188,7]]},"2445":{"position":[[174,8]]},"2451":{"position":[[617,9],[653,8]]},"2457":{"position":[[94,7]]},"2461":{"position":[[150,8],[182,8]]},"2463":{"position":[[159,8],[194,8]]},"2465":{"position":[[153,8],[186,8]]},"2482":{"position":[[288,7]]},"2626":{"position":[[453,8]]},"2647":{"position":[[2252,8]]},"2649":{"position":[[1473,8],[3563,8]]},"2674":{"position":[[481,8]]},"2692":{"position":[[532,8]]},"2695":{"position":[[110,8]]},"2703":{"position":[[809,8]]},"2712":{"position":[[749,7]]},"2723":{"position":[[398,7]]},"2725":{"position":[[359,7]]},"2734":{"position":[[39,7]]},"2740":{"position":[[1096,7]]},"2756":{"position":[[416,7],[682,7],[1013,7],[1240,7],[2375,9],[2611,9]]},"2956":{"position":[[1815,7],[3972,8]]},"2958":{"position":[[1622,7]]},"2962":{"position":[[1158,7]]},"2966":{"position":[[2550,7]]},"2968":{"position":[[1108,8]]},"3002":{"position":[[1902,7]]},"3004":{"position":[[267,8]]},"3153":{"position":[[76,7],[270,8]]},"3159":{"position":[[170,7]]},"3223":{"position":[[406,8]]},"3230":{"position":[[275,8]]},"3285":{"position":[[268,8],[392,7],[515,7]]},"3348":{"position":[[1273,7]]},"3352":{"position":[[1497,7]]},"3381":{"position":[[2699,7]]},"3384":{"position":[[1688,7]]},"3571":{"position":[[1346,7]]},"3594":{"position":[[828,7]]},"3602":{"position":[[627,7]]},"3742":{"position":[[48,7]]},"3883":{"position":[[116,7]]},"3906":{"position":[[118,7]]},"3947":{"position":[[299,9]]},"4013":{"position":[[252,9]]},"4222":{"position":[[3882,8]]},"4230":{"position":[[2789,7]]},"4304":{"position":[[2587,7]]},"4485":{"position":[[660,8],[1423,7],[2301,8]]},"4868":{"position":[[28,7]]},"4870":{"position":[[116,7],[144,8]]}}}],["commandlin",{"_index":7422,"t":{"2052":{"position":[[528,11]]}}}],["comment",{"_index":1790,"t":{"258":{"position":[[280,7]]},"364":{"position":[[946,7]]},"368":{"position":[[7359,7]]},"524":{"position":[[269,7],[395,7],[521,7],[1005,7],[1131,7],[1257,7]]},"530":{"position":[[1373,8],[1660,10],[1759,9],[2059,8],[2931,7]]},"1472":{"position":[[1154,7]]},"1996":{"position":[[252,9]]},"2199":{"position":[[875,8]]},"2618":{"position":[[1317,9]]},"2622":{"position":[[125,8]]},"4015":{"position":[[227,7]]},"4226":{"position":[[166,9]]},"4560":{"position":[[244,9]]},"4632":{"position":[[731,8],[1981,8],[2384,8],[2782,8],[2842,7]]}}}],["commerci",{"_index":8080,"t":{"2234":{"position":[[526,10]]},"3835":{"position":[[766,10]]},"4226":{"position":[[2858,10]]},"4740":{"position":[[86,12]]},"4744":{"position":[[986,10]]},"4759":{"position":[[74,12]]}}}],["commit",{"_index":698,"t":{"117":{"position":[[119,10]]},"173":{"position":[[537,10]]},"181":{"position":[[1719,9]]},"197":{"position":[[354,9]]},"201":{"position":[[332,7]]},"249":{"position":[[1773,6],[1799,6],[1938,6],[1958,6],[1981,6],[2046,7]]},"597":{"position":[[730,7]]},"604":{"position":[[498,6]]},"616":{"position":[[75,6]]},"618":{"position":[[350,6]]},"624":{"position":[[217,6]]},"634":{"position":[[92,6],[328,6]]},"653":{"position":[[553,7]]},"1179":{"position":[[973,6],[2046,6]]},"1220":{"position":[[131,9]]},"1224":{"position":[[407,6],[426,6],[480,9]]},"1246":{"position":[[1012,6]]},"1257":{"position":[[1661,6],[1843,6]]},"1259":{"position":[[933,6]]},"1491":{"position":[[133,6]]},"1561":{"position":[[1102,6]]},"1704":{"position":[[1851,10],[2530,10]]},"2067":{"position":[[24,6]]},"2163":{"position":[[3363,6]]},"2171":{"position":[[1806,6],[1992,6]]},"2211":{"position":[[2272,6]]},"2747":{"position":[[134,6],[163,6],[219,6]]},"3162":{"position":[[744,6]]},"3381":{"position":[[2589,6],[2638,6]]},"3384":{"position":[[1578,6],[1627,6]]},"3575":{"position":[[511,10],[544,7]]},"3698":{"position":[[1270,7],[1434,6]]},"3829":{"position":[[2701,11],[2760,7]]},"3971":{"position":[[34,8]]},"4562":{"position":[[3979,10]]},"4662":{"position":[[1582,6],[1606,6],[1628,6],[1651,6]]}}}],["committe",{"_index":11486,"t":{"4340":{"position":[[817,10]]},"4351":{"position":[[554,10]]},"4627":{"position":[[274,9]]},"4669":{"position":[[1221,9]]},"4671":{"position":[[20,9]]}}}],["committee'",{"_index":10511,"t":{"3685":{"position":[[166,11]]}}}],["commod",{"_index":4424,"t":{"1061":{"position":[[874,9]]}}}],["common",{"_index":498,"t":{"70":{"position":[[15,6]]},"249":{"position":[[1659,7]]},"286":{"position":[[187,6]]},"370":{"position":[[408,6]]},"489":{"position":[[50,6]]},"545":{"position":[[402,6]]},"572":{"position":[[583,6]]},"611":{"position":[[154,7]]},"618":{"position":[[101,6]]},"820":{"position":[[140,6]]},"1073":{"position":[[325,6],[349,7]]},"1236":{"position":[[546,6],[624,8],[756,8]]},"1431":{"position":[[184,6]]},"1455":{"position":[[2110,6]]},"1513":{"position":[[0,6],[349,6],[536,6],[798,6]]},"1521":{"position":[[0,6]]},"1523":{"position":[[0,6]]},"1657":{"position":[[711,6]]},"1686":{"position":[[616,9]]},"1694":{"position":[[684,6],[760,6],[1210,6],[1692,6],[2478,6],[2588,6],[2732,6],[2855,6],[2870,6],[2978,6],[3119,6],[3254,6],[3415,6],[3551,6],[3690,6],[3812,6],[3947,6],[4082,6],[4217,6],[4355,6],[4514,6],[4667,6],[4828,6],[4967,6],[5076,6],[5214,6],[5766,6],[6020,10]]},"1711":{"position":[[263,6]]},"1902":{"position":[[145,6],[183,6]]},"2057":{"position":[[149,7]]},"2071":{"position":[[1154,8]]},"2167":{"position":[[223,6],[483,6],[513,6]]},"2184":{"position":[[5525,6]]},"2211":{"position":[[801,6]]},"2317":{"position":[[24,6]]},"2384":{"position":[[24,6]]},"2512":{"position":[[748,6]]},"2535":{"position":[[347,7]]},"2549":{"position":[[548,6]]},"2682":{"position":[[706,6]]},"2714":{"position":[[546,6]]},"2758":{"position":[[20,6]]},"3375":{"position":[[606,6]]},"3592":{"position":[[2397,13]]},"3714":{"position":[[2233,6]]},"4009":{"position":[[65,6],[243,6]]},"4222":{"position":[[1382,6]]},"4294":{"position":[[424,6]]},"4535":{"position":[[3187,6]]},"4539":{"position":[[3151,6]]},"4547":{"position":[[1084,6]]},"4589":{"position":[[199,7],[620,6]]},"4676":{"position":[[54,6]]},"4691":{"position":[[33,6],[53,6],[235,6],[843,6]]}}}],["common.yml",{"_index":6780,"t":{"1694":{"position":[[1734,10],[6730,10],[7466,10]]}}}],["commonli",{"_index":1260,"t":{"181":{"position":[[90,8]]},"1429":{"position":[[80,8]]},"2293":{"position":[[344,8],[434,8]]},"2307":{"position":[[344,8],[434,8]]},"2590":{"position":[[76,8]]},"2916":{"position":[[110,8]]},"3690":{"position":[[1038,8],[1472,8]]},"3744":{"position":[[9,8]]},"3777":{"position":[[1139,8],[1573,8]]},"4593":{"position":[[24,8],[820,8],[1774,8],[3477,8]]},"4679":{"position":[[289,8]]},"4715":{"position":[[5,8]]},"4717":{"position":[[25,8]]}}}],["commun",{"_index":22,"t":{"7":{"position":[[33,9],[370,9],[479,10],[588,9]]},"19":{"position":[[73,9]]},"24":{"position":[[510,9]]},"26":{"position":[[192,9]]},"28":{"position":[[31,9],[119,9],[137,9]]},"31":{"position":[[51,9]]},"33":{"position":[[31,9]]},"68":{"position":[[173,9]]},"72":{"position":[[47,9],[114,10],[172,9],[238,9],[288,9]]},"74":{"position":[[184,9]]},"90":{"position":[[114,9]]},"99":{"position":[[47,10]]},"165":{"position":[[215,9]]},"173":{"position":[[350,9]]},"177":{"position":[[401,9]]},"179":{"position":[[376,9]]},"187":{"position":[[242,10],[932,9],[1164,9]]},"190":{"position":[[12,10],[209,9]]},"192":{"position":[[325,10],[345,9]]},"194":{"position":[[241,10],[395,9]]},"197":{"position":[[693,10],[791,9],[907,9],[1220,10],[1272,10],[1482,10]]},"199":{"position":[[292,9],[913,9],[1000,9],[1114,9],[2060,10],[2334,9],[2434,9],[2536,10],[2829,10]]},"262":{"position":[[24,9],[133,10]]},"332":{"position":[[148,9]]},"427":{"position":[[683,9]]},"541":{"position":[[650,13],[854,13]]},"588":{"position":[[1811,13],[1990,11]]},"641":{"position":[[738,10]]},"666":{"position":[[738,10]]},"804":{"position":[[42,9],[85,10]]},"834":{"position":[[24,11],[100,12]]},"844":{"position":[[264,10]]},"848":{"position":[[269,11]]},"871":{"position":[[1465,9]]},"875":{"position":[[548,10],[577,9]]},"980":{"position":[[1154,10]]},"1226":{"position":[[2018,13]]},"1346":{"position":[[107,14],[135,13]]},"1405":{"position":[[410,13],[1310,13]]},"1772":{"position":[[1465,9]]},"1776":{"position":[[548,10],[577,9]]},"1871":{"position":[[1154,10]]},"2146":{"position":[[315,13]]},"2252":{"position":[[664,11]]},"2285":{"position":[[502,13],[578,13],[617,13]]},"2295":{"position":[[912,10]]},"2299":{"position":[[502,13],[578,13],[617,13]]},"2427":{"position":[[2131,10]]},"2431":{"position":[[859,11],[2591,11]]},"2475":{"position":[[201,9]]},"2489":{"position":[[99,10],[1539,9],[1624,9]]},"2529":{"position":[[344,11],[691,13]]},"2553":{"position":[[132,9],[547,9]]},"2572":{"position":[[418,11]]},"2594":{"position":[[197,9]]},"2756":{"position":[[168,9]]},"2853":{"position":[[6,13],[145,13],[182,13]]},"2916":{"position":[[38,11]]},"3050":{"position":[[604,10]]},"3073":{"position":[[86,12]]},"3110":{"position":[[75,9]]},"3142":{"position":[[75,9]]},"3144":{"position":[[60,10],[262,9],[442,12]]},"3148":{"position":[[959,9],[1066,9]]},"3174":{"position":[[75,9]]},"3176":{"position":[[60,10],[142,9],[398,12]]},"3212":{"position":[[75,9]]},"3214":{"position":[[14,9]]},"3246":{"position":[[383,9]]},"3270":{"position":[[75,9]]},"3319":{"position":[[75,9]]},"3321":{"position":[[562,9]]},"3323":{"position":[[37,11]]},"3340":{"position":[[75,9]]},"3346":{"position":[[665,9]]},"3361":{"position":[[37,9]]},"3367":{"position":[[391,9]]},"3390":{"position":[[976,9]]},"3392":{"position":[[157,10]]},"3396":{"position":[[58,9]]},"3525":{"position":[[100,9]]},"3531":{"position":[[502,9]]},"3533":{"position":[[61,9],[273,9],[324,10],[361,9],[415,13],[478,10],[489,9],[564,9],[2035,9]]},"3535":{"position":[[56,10]]},"3563":{"position":[[144,9],[473,9]]},"3623":{"position":[[71,9],[329,10]]},"3625":{"position":[[152,11],[185,10]]},"3627":{"position":[[668,9]]},"3636":{"position":[[254,10]]},"3638":{"position":[[186,9]]},"3962":{"position":[[40,11]]},"3968":{"position":[[195,9],[909,9],[957,9],[1119,9],[1609,10],[1785,9],[2170,9],[2212,9],[2630,9],[2757,9]]},"3971":{"position":[[0,9],[159,9],[884,9],[920,9]]},"3973":{"position":[[96,10],[206,10],[585,9]]},"3975":{"position":[[58,9]]},"4081":{"position":[[1793,10]]},"4144":{"position":[[673,11]]},"4146":{"position":[[1132,9],[1827,9],[2530,9],[2728,10],[2819,9],[2923,10],[3059,9]]},"4148":{"position":[[212,9],[871,10]]},"4163":{"position":[[4451,11]]},"4206":{"position":[[179,10]]},"4215":{"position":[[248,10]]},"4220":{"position":[[1331,14],[1458,13],[1903,13],[2049,13]]},"4222":{"position":[[499,13],[586,13],[649,13],[2989,14]]},"4224":{"position":[[1393,10],[1522,9],[1975,13]]},"4226":{"position":[[1277,9]]},"4228":{"position":[[400,14],[1484,9]]},"4230":{"position":[[5275,9]]},"4236":{"position":[[328,13],[500,13]]},"4238":{"position":[[74,14],[262,13]]},"4240":{"position":[[532,13]]},"4242":{"position":[[123,13]]},"4257":{"position":[[4008,9]]},"4294":{"position":[[142,13],[315,13],[457,13]]},"4298":{"position":[[29,13],[581,13],[680,13]]},"4300":{"position":[[24,13],[775,13]]},"4302":{"position":[[46,13],[280,13],[401,13],[497,13],[624,13],[3892,13],[3945,13],[4422,13]]},"4304":{"position":[[66,13],[271,14]]},"4306":{"position":[[214,9],[666,12]]},"4308":{"position":[[29,13],[998,13]]},"4310":{"position":[[168,13],[1758,13],[2419,13]]},"4315":{"position":[[22,13],[308,9]]},"4317":{"position":[[78,13]]},"4335":{"position":[[58,13]]},"4337":{"position":[[33,13]]},"4353":{"position":[[600,12]]},"4418":{"position":[[447,9]]},"4485":{"position":[[23,13]]},"4535":{"position":[[795,14],[3645,14],[3702,14],[3788,13],[3977,13],[4081,13],[4118,15]]},"4537":{"position":[[119,13]]},"4547":{"position":[[658,13],[734,14]]},"4560":{"position":[[1235,9],[1311,14],[2161,11],[2721,9],[3941,9]]},"4562":{"position":[[1690,9],[2689,9],[4081,9],[4173,9],[4463,9]]},"4593":{"position":[[106,9],[371,9],[412,9],[3245,9],[3367,9]]},"4656":{"position":[[115,9]]},"4662":{"position":[[1885,11]]},"4681":{"position":[[226,9]]},"4826":{"position":[[332,9],[1104,9]]},"4829":{"position":[[247,11]]},"4881":{"position":[[54,9]]}}}],["community'",{"_index":10293,"t":{"3644":{"position":[[177,11]]}}}],["community.general.timezon",{"_index":4995,"t":{"1203":{"position":[[128,26]]}}}],["community.github.io/helm",{"_index":9042,"t":{"2756":{"position":[[197,24]]},"4881":{"position":[[83,24]]}}}],["community/kub",{"_index":9043,"t":{"2756":{"position":[[321,14]]},"4881":{"position":[[153,14]]}}}],["community/prometheu",{"_index":9046,"t":{"2756":{"position":[[587,20]]}}}],["compact",{"_index":8874,"t":{"2684":{"position":[[987,10],[1094,10]]},"4481":{"position":[[537,10],[1045,10],[1066,10],[1110,10]]},"4491":{"position":[[160,7],[245,10],[277,10]]}}}],["compact.concurr",{"_index":8876,"t":{"2684":{"position":[[1039,19]]}}}],["compact.concurrency=3",{"_index":8869,"t":{"2684":{"position":[[108,21]]}}}],["compaction/defragment",{"_index":11543,"t":{"4475":{"position":[[283,26]]}}}],["compactor",{"_index":8862,"t":{"2684":{"position":[[0,10],[187,10],[939,9]]},"4730":{"position":[[1097,9]]}}}],["compani",{"_index":1125,"t":{"173":{"position":[[897,9],[1008,7],[1253,7],[1498,9],[1732,9],[2150,9],[2312,9]]},"175":{"position":[[83,7]]},"181":{"position":[[1004,9],[2373,9]]},"187":{"position":[[670,10]]},"205":{"position":[[106,9]]},"778":{"position":[[156,9]]},"1466":{"position":[[1392,7]]},"3144":{"position":[[162,9]]},"3308":{"position":[[898,9]]},"3344":{"position":[[1025,10]]},"3563":{"position":[[123,9]]},"3625":{"position":[[222,10]]},"4560":{"position":[[2066,9],[2511,10],[3428,9],[3705,9],[3723,9],[3771,9],[4648,9],[4937,10]]},"4562":{"position":[[1785,9],[2968,9],[4261,9]]},"4839":{"position":[[994,10]]}}}],["company/organ",{"_index":677,"t":{"103":{"position":[[134,21]]},"3571":{"position":[[771,21]]}}}],["company_nam",{"_index":10062,"t":{"3378":{"position":[[1260,12]]}}}],["compar",{"_index":2605,"t":{"530":{"position":[[1730,8]]},"600":{"position":[[168,8]]},"818":{"position":[[331,8]]},"932":{"position":[[3900,7]]},"942":{"position":[[2428,8]]},"1823":{"position":[[3900,7]]},"1833":{"position":[[2428,8]]},"2029":{"position":[[384,8]]},"2535":{"position":[[274,9]]},"2580":{"position":[[308,10]]},"2956":{"position":[[3900,7]]},"2966":{"position":[[2428,8]]},"3014":{"position":[[222,8]]},"3677":{"position":[[924,8]]},"3714":{"position":[[1652,8]]},"3791":{"position":[[946,8]]},"4109":{"position":[[2141,8]]},"4146":{"position":[[189,11]]},"4281":{"position":[[887,8],[1233,8]]},"4313":{"position":[[1284,7]]},"4516":{"position":[[737,9],[1306,9]]},"4518":{"position":[[479,8]]},"4520":{"position":[[349,8]]},"4562":{"position":[[1572,8]]},"4593":{"position":[[3696,8],[4772,8]]},"4612":{"position":[[739,10]]}}}],["comparison",{"_index":3239,"t":{"741":{"position":[[1523,10]]},"1185":{"position":[[616,10]]},"1252":{"position":[[1128,10]]},"2234":{"position":[[758,10]]},"3047":{"position":[[432,10]]},"3671":{"position":[[694,11]]},"3712":{"position":[[1126,11]]},"3805":{"position":[[801,11]]},"3910":{"position":[[147,10]]},"4144":{"position":[[599,10]]},"4562":{"position":[[3586,10],[4543,10]]},"4656":{"position":[[355,10]]}}}],["compat",{"_index":33,"t":{"7":{"position":[[150,10]]},"177":{"position":[[730,11],[1051,12]]},"185":{"position":[[204,10]]},"197":{"position":[[286,11]]},"282":{"position":[[225,10]]},"288":{"position":[[279,13]]},"297":{"position":[[151,10]]},"309":{"position":[[114,10]]},"341":{"position":[[29,10]]},"427":{"position":[[112,10]]},"438":{"position":[[439,10]]},"440":{"position":[[92,13]]},"696":{"position":[[1423,10]]},"701":{"position":[[64,10],[187,10]]},"734":{"position":[[64,10]]},"788":{"position":[[197,10]]},"842":{"position":[[269,10]]},"1067":{"position":[[1175,13]]},"1169":{"position":[[218,8]]},"2011":{"position":[[0,13]]},"2584":{"position":[[1362,14]]},"2586":{"position":[[972,14]]},"2914":{"position":[[1258,14]]},"2920":{"position":[[236,10]]},"3159":{"position":[[123,10]]},"3168":{"position":[[269,11]]},"3170":{"position":[[254,10]]},"3259":{"position":[[143,10],[170,10],[448,10]]},"3296":{"position":[[444,13]]},"3308":{"position":[[215,10],[589,10]]},"3361":{"position":[[255,14]]},"3367":{"position":[[91,10],[271,10]]},"3373":{"position":[[91,10]]},"3381":{"position":[[924,10]]},"3384":{"position":[[1355,10]]},"3386":{"position":[[206,10],[397,10]]},"3390":{"position":[[913,10]]},"3402":{"position":[[135,13]]},"3468":{"position":[[264,10]]},"3582":{"position":[[398,10],[590,10],[1295,10],[1694,10],[1758,10]]},"3594":{"position":[[125,10],[153,10]]},"3596":{"position":[[48,11],[572,10],[739,10]]},"3651":{"position":[[109,12]]},"3688":{"position":[[109,12]]},"3727":{"position":[[88,10],[142,10]]},"3729":{"position":[[63,10],[86,10]]},"3731":{"position":[[2217,14]]},"3735":{"position":[[91,10]]},"3775":{"position":[[109,12]]},"3894":{"position":[[1224,10]]},"3910":{"position":[[530,13]]},"3913":{"position":[[362,10]]},"3916":{"position":[[426,10]]},"3923":{"position":[[305,10]]},"3968":{"position":[[1816,13]]},"4206":{"position":[[124,13],[494,13]]},"4210":{"position":[[145,10]]},"4508":{"position":[[261,14],[299,10]]},"4667":{"position":[[13100,13]]},"4730":{"position":[[807,10]]},"4826":{"position":[[1034,10]]}}}],["compen",{"_index":11335,"t":{"4226":{"position":[[857,10]]}}}],["compet",{"_index":10965,"t":{"3932":{"position":[[163,9]]}}}],["competit",{"_index":1344,"t":{"187":{"position":[[530,11]]}}}],["competitor",{"_index":1142,"t":{"173":{"position":[[1373,11]]}}}],["compil",{"_index":3330,"t":{"838":{"position":[[166,7]]},"2800":{"position":[[0,9]]},"2818":{"position":[[64,9]]},"2938":{"position":[[0,9]]}}}],["complain",{"_index":6612,"t":{"1648":{"position":[[1339,8]]}}}],["complement",{"_index":3271,"t":{"784":{"position":[[13,10]]},"2582":{"position":[[72,13]]},"3193":{"position":[[23,11]]}}}],["complet",{"_index":657,"t":{"95":{"position":[[578,8]]},"171":{"position":[[1071,8]]},"243":{"position":[[390,13]]},"286":{"position":[[728,8]]},"295":{"position":[[1273,10],[1335,11],[1413,9]]},"305":{"position":[[22,8]]},"397":{"position":[[208,10]]},"423":{"position":[[206,10]]},"491":{"position":[[144,8]]},"530":{"position":[[1118,10]]},"887":{"position":[[792,10],[811,10],[856,10],[872,10]]},"912":{"position":[[4020,8]]},"944":{"position":[[245,9],[836,9],[1197,9],[1265,9]]},"959":{"position":[[263,10]]},"971":{"position":[[176,10]]},"1167":{"position":[[86,10]]},"1226":{"position":[[2390,8]]},"1236":{"position":[[68,8]]},"1259":{"position":[[1471,8]]},"1385":{"position":[[2243,10]]},"1399":{"position":[[118,8]]},"1413":{"position":[[282,8]]},"1423":{"position":[[337,8]]},"1441":{"position":[[19,10]]},"1457":{"position":[[582,10]]},"1466":{"position":[[1252,10],[3169,11]]},"1474":{"position":[[639,10]]},"1503":{"position":[[809,10]]},"1525":{"position":[[1057,8]]},"1544":{"position":[[241,9],[468,9]]},"1603":{"position":[[311,11]]},"1659":{"position":[[597,10]]},"1694":{"position":[[351,8],[1187,9],[1660,9],[2455,9],[2565,9],[2701,9],[2824,9],[2951,9],[3092,9],[3231,9],[3388,9],[3524,9],[3663,9],[3789,9],[3924,9],[4059,9],[4194,9],[4328,9],[4471,9],[4624,9],[4785,9],[4935,9],[5053,9],[5182,9],[5821,9],[6652,9],[7265,9]]},"1796":{"position":[[4020,8]]},"1811":{"position":[[792,10],[811,10],[856,10],[872,10]]},"1835":{"position":[[245,9],[836,9],[1197,9],[1265,9]]},"1850":{"position":[[263,10]]},"1862":{"position":[[176,10]]},"2059":{"position":[[709,10]]},"2184":{"position":[[3053,10],[5474,8]]},"2186":{"position":[[19,9]]},"2211":{"position":[[865,9],[1055,8]]},"2248":{"position":[[18,10]]},"2441":{"position":[[78,9]]},"2482":{"position":[[523,8]]},"2512":{"position":[[1254,11]]},"2709":{"position":[[198,8]]},"2714":{"position":[[196,8]]},"2889":{"position":[[516,9]]},"2914":{"position":[[251,8]]},"2968":{"position":[[245,9],[836,9],[1197,9],[1265,9]]},"2983":{"position":[[263,10]]},"2995":{"position":[[176,10]]},"3016":{"position":[[827,8]]},"3073":{"position":[[167,8],[251,8],[672,8]]},"3086":{"position":[[1268,8]]},"3088":{"position":[[712,8]]},"3121":{"position":[[1211,8]]},"3148":{"position":[[265,10]]},"3225":{"position":[[560,8]]},"3244":{"position":[[121,12]]},"3276":{"position":[[763,8]]},"3294":{"position":[[76,8]]},"3352":{"position":[[221,8]]},"3355":{"position":[[553,8]]},"3549":{"position":[[819,10]]},"3665":{"position":[[911,11]]},"3702":{"position":[[1124,11]]},"3789":{"position":[[983,11]]},"3795":{"position":[[589,12]]},"3837":{"position":[[108,12]]},"3923":{"position":[[435,8]]},"3928":{"position":[[1248,8],[3050,10],[5391,8]]},"4068":{"position":[[146,8]]},"4146":{"position":[[91,12],[1002,8]]},"4159":{"position":[[351,8]]},"4240":{"position":[[515,8]]},"4376":{"position":[[38,10]]},"4433":{"position":[[933,8],[1439,8]]},"4479":{"position":[[1440,10]]},"4485":{"position":[[2372,8]]},"4535":{"position":[[1478,8]]},"4539":{"position":[[1745,8]]},"4558":{"position":[[30,8]]},"4562":{"position":[[3710,10]]},"4593":{"position":[[716,8]]},"4656":{"position":[[422,8]]},"4699":{"position":[[142,9]]},"4717":{"position":[[263,8]]},"4863":{"position":[[16,8]]}}}],["completli",{"_index":6416,"t":{"1559":{"position":[[43,10]]}}}],["complex",{"_index":1347,"t":{"187":{"position":[[572,7]]},"370":{"position":[[793,10]]},"1056":{"position":[[269,12],[2354,12]]},"1061":{"position":[[1067,11]]},"1064":{"position":[[2526,12]]},"1067":{"position":[[1976,7]]},"1464":{"position":[[747,7]]},"1484":{"position":[[682,10]]},"2258":{"position":[[112,7]]},"2485":{"position":[[42,7]]},"2525":{"position":[[367,7]]},"2690":{"position":[[359,7]]},"3052":{"position":[[257,10]]},"3384":{"position":[[438,12]]},"3525":{"position":[[360,7]]},"3561":{"position":[[37,7]]},"3563":{"position":[[233,11]]},"3567":{"position":[[15,10]]},"3575":{"position":[[317,7]]},"3947":{"position":[[3441,8]]},"4230":{"position":[[3296,10],[4253,10]]},"4236":{"position":[[301,10]]},"4238":{"position":[[385,7]]},"4306":{"position":[[33,7]]},"4313":{"position":[[1125,7]]},"4435":{"position":[[1513,10]]},"4516":{"position":[[966,12],[1136,10]]},"4518":{"position":[[341,10]]},"4520":{"position":[[300,10]]},"4522":{"position":[[988,10]]},"4525":{"position":[[595,10]]},"4654":{"position":[[48,7]]},"4728":{"position":[[940,10]]}}}],["compli",{"_index":633,"t":{"93":{"position":[[227,6]]},"145":{"position":[[238,8]]},"293":{"position":[[994,6]]},"3153":{"position":[[115,6]]},"3187":{"position":[[433,6]]},"3592":{"position":[[853,8]]},"3606":{"position":[[1656,6]]},"3913":{"position":[[285,6],[489,6]]},"4030":{"position":[[162,6]]},"4448":{"position":[[254,6]]}}}],["complianc",{"_index":212,"t":{"26":{"position":[[758,10]]},"28":{"position":[[3288,10],[3320,10]]},"31":{"position":[[191,10]]},"173":{"position":[[421,10]]},"284":{"position":[[65,10],[83,10],[350,11],[439,10],[645,10]]},"293":{"position":[[971,11]]},"297":{"position":[[60,10]]},"526":{"position":[[814,10],[1551,10]]},"530":{"position":[[859,10],[1054,10]]},"788":{"position":[[51,10]]},"1259":{"position":[[17,10]]},"2487":{"position":[[275,10]]},"2499":{"position":[[559,10]]},"2501":{"position":[[908,11],[968,10]]},"2503":{"position":[[144,10],[208,10]]},"2506":{"position":[[448,10]]},"2510":{"position":[[543,10]]},"2520":{"position":[[269,10],[562,11],[605,10]]},"2522":{"position":[[597,11]]},"2539":{"position":[[453,10]]},"2555":{"position":[[476,10]]},"2592":{"position":[[516,10]]},"3073":{"position":[[858,10]]},"3168":{"position":[[380,10],[447,11]]},"3206":{"position":[[676,10]]},"3308":{"position":[[547,10]]},"3346":{"position":[[228,10]]},"3357":{"position":[[1869,10],[1884,10]]},"3361":{"position":[[501,10]]},"3375":{"position":[[8,10],[112,10],[362,10],[549,10]]},"3378":{"position":[[145,10],[784,10]]},"3381":{"position":[[1082,10]]},"3384":{"position":[[855,10],[1513,10]]},"3414":{"position":[[412,10]]},"3584":{"position":[[334,10]]},"3602":{"position":[[397,10],[444,10]]},"3606":{"position":[[1370,10],[1426,10]]},"3615":{"position":[[39,10]]},"3627":{"position":[[637,10]]},"3683":{"position":[[364,10]]},"3704":{"position":[[1066,10]]},"3731":{"position":[[268,10]]},"3742":{"position":[[618,10]]},"3751":{"position":[[173,11]]},"3793":{"position":[[698,11],[1349,10]]},"3795":{"position":[[364,10],[574,10]]},"3866":{"position":[[328,10]]},"3888":{"position":[[331,11],[349,10],[378,10]]},"3916":{"position":[[394,10]]},"3930":{"position":[[254,10]]},"4178":{"position":[[875,11]]},"4182":{"position":[[379,10]]},"4200":{"position":[[758,11]]},"4259":{"position":[[548,10]]},"4266":{"position":[[605,10]]},"4268":{"position":[[602,10]]},"4291":{"position":[[1038,11],[1626,10]]},"4337":{"position":[[492,10]]},"4629":{"position":[[179,10]]}}}],["compliance_check",{"_index":2154,"t":{"364":{"position":[[1606,17]]},"366":{"position":[[239,18]]}}}],["compliant",{"_index":610,"t":{"84":{"position":[[693,9]]},"280":{"position":[[786,9]]},"291":{"position":[[181,9]]},"293":{"position":[[1072,9]]},"295":{"position":[[173,9]]},"351":{"position":[[11,10],[43,10]]},"790":{"position":[[63,10]]},"2376":{"position":[[375,9]]},"2429":{"position":[[125,9]]},"3103":{"position":[[595,9]]},"3121":{"position":[[549,10]]},"3136":{"position":[[595,9]]},"3281":{"position":[[121,9],[149,9]]},"3525":{"position":[[192,9]]},"3679":{"position":[[26,9]]},"3793":{"position":[[26,9]]},"3835":{"position":[[894,10]]},"3923":{"position":[[114,9],[200,9]]},"4157":{"position":[[1217,10]]},"4198":{"position":[[10,9]]},"4202":{"position":[[47,9]]},"4204":{"position":[[46,9]]},"4257":{"position":[[657,9],[2278,9],[2523,10],[2686,10],[2861,9],[4460,10]]},"4268":{"position":[[291,9],[363,9]]},"4342":{"position":[[273,9]]},"4353":{"position":[[803,9]]},"4372":{"position":[[157,9]]},"4414":{"position":[[624,9]]},"4569":{"position":[[432,9],[892,9]]},"4572":{"position":[[441,9]]},"4576":{"position":[[349,9]]},"4582":{"position":[[407,9],[573,9]]},"4589":{"position":[[440,9]]},"4593":{"position":[[3571,9]]}}}],["complic",{"_index":2660,"t":{"549":{"position":[[1012,10]]},"3296":{"position":[[647,11]]},"4236":{"position":[[435,11]]},"4244":{"position":[[550,11]]},"4246":{"position":[[539,11]]},"4518":{"position":[[467,11]]}}}],["compon",{"_index":1832,"t":{"275":{"position":[[191,11]]},"282":{"position":[[395,10]]},"334":{"position":[[4,9]]},"345":{"position":[[33,10]]},"376":{"position":[[147,9]]},"401":{"position":[[97,10],[727,10],[921,10],[1470,10]]},"403":{"position":[[545,9]]},"421":{"position":[[684,11]]},"423":{"position":[[314,10],[607,10],[1124,10]]},"425":{"position":[[208,10]]},"493":{"position":[[504,10]]},"537":{"position":[[58,10],[222,10]]},"541":{"position":[[24,10],[772,9],[1041,9]]},"543":{"position":[[244,10],[392,10],[432,10]]},"551":{"position":[[247,10],[416,9],[826,11],[1034,10],[1152,9],[2295,11],[2862,11],[3190,11],[3215,10]]},"576":{"position":[[198,11]]},"705":{"position":[[22,10]]},"738":{"position":[[22,10],[332,10]]},"836":{"position":[[117,11]]},"842":{"position":[[62,9]]},"846":{"position":[[977,11]]},"1009":{"position":[[33,10],[664,11]]},"1064":{"position":[[1043,10]]},"1113":{"position":[[166,10]]},"1257":{"position":[[613,11]]},"1331":{"position":[[97,10]]},"1433":{"position":[[396,11],[874,10],[1169,10]]},"1466":{"position":[[3029,10]]},"1468":{"position":[[315,11]]},"1513":{"position":[[213,11]]},"1523":{"position":[[153,10],[229,10]]},"1529":{"position":[[502,10]]},"2055":{"position":[[213,10],[543,10]]},"2171":{"position":[[760,11]]},"2376":{"position":[[137,9]]},"2429":{"position":[[218,9]]},"2529":{"position":[[22,11],[73,10],[171,10],[724,11]]},"2574":{"position":[[41,10]]},"2592":{"position":[[147,9]]},"2596":{"position":[[43,9]]},"2606":{"position":[[251,9]]},"2608":{"position":[[586,11]]},"2612":{"position":[[261,10]]},"2614":{"position":[[46,10],[133,10],[793,9]]},"2618":{"position":[[1464,10],[1619,10]]},"2620":{"position":[[5,9]]},"2626":{"position":[[2393,10]]},"2628":{"position":[[501,11],[978,10]]},"2638":{"position":[[5,9]]},"2644":{"position":[[376,10]]},"2651":{"position":[[446,10]]},"2655":{"position":[[662,10]]},"2661":{"position":[[466,10]]},"2663":{"position":[[120,10]]},"2672":{"position":[[376,10]]},"2680":{"position":[[64,10]]},"2712":{"position":[[263,10]]},"2778":{"position":[[129,13]]},"2812":{"position":[[14,10]]},"2814":{"position":[[168,10],[590,11],[850,9],[959,10]]},"2867":{"position":[[12,10]]},"2887":{"position":[[27,10],[194,10]]},"2889":{"position":[[6,10],[120,10]]},"2910":{"position":[[94,10],[234,13]]},"2914":{"position":[[660,12],[755,11],[866,12],[941,10]]},"2916":{"position":[[763,10]]},"2934":{"position":[[403,11]]},"2940":{"position":[[156,11],[490,10]]},"3016":{"position":[[878,10]]},"3064":{"position":[[236,11]]},"3132":{"position":[[146,11]]},"3153":{"position":[[1278,11]]},"3164":{"position":[[104,11],[291,10]]},"3172":{"position":[[122,9]]},"3202":{"position":[[104,11],[253,9]]},"3221":{"position":[[85,11]]},"3223":{"position":[[175,10],[965,9]]},"3225":{"position":[[146,11]]},"3232":{"position":[[12,9]]},"3248":{"position":[[181,10],[244,10]]},"3266":{"position":[[148,10]]},"3276":{"position":[[273,11],[694,10]]},"3279":{"position":[[85,11]]},"3296":{"position":[[461,11]]},"3298":{"position":[[269,10]]},"3321":{"position":[[106,10],[265,10],[338,9]]},"3344":{"position":[[559,11]]},"3346":{"position":[[863,10]]},"3348":{"position":[[909,10]]},"3355":{"position":[[606,10]]},"3357":{"position":[[6,9],[2845,10],[3212,10]]},"3516":{"position":[[479,11]]},"3561":{"position":[[78,10],[195,11]]},"3565":{"position":[[60,10],[75,10]]},"3569":{"position":[[704,10],[721,9],[747,9],[962,10],[1018,9]]},"3571":{"position":[[252,9],[933,10],[1142,10],[1538,10]]},"3573":{"position":[[710,10],[725,10],[1274,10]]},"4107":{"position":[[1114,10],[1306,10]]},"4109":{"position":[[2800,10]]},"4146":{"position":[[1516,10],[1610,11],[2091,11]]},"4230":{"position":[[4024,10]]},"4279":{"position":[[1137,11]]},"4300":{"position":[[507,9]]},"4302":{"position":[[433,10]]},"4333":{"position":[[117,10],[479,10]]},"4340":{"position":[[891,9]]},"4351":{"position":[[628,9]]},"4420":{"position":[[1967,10]]},"4427":{"position":[[374,10]]},"4433":{"position":[[295,11]]},"4435":{"position":[[464,11],[490,9]]},"4440":{"position":[[366,10],[552,9]]},"4444":{"position":[[614,9]]},"4451":{"position":[[366,10],[552,9]]},"4455":{"position":[[614,9]]},"4495":{"position":[[89,11]]},"4533":{"position":[[270,10],[640,9]]},"4535":{"position":[[435,11],[668,10],[1350,10],[1414,11],[1546,9],[2013,10],[2414,10],[3289,10],[3397,10],[3518,10]]},"4537":{"position":[[109,9],[377,11],[857,10]]},"4547":{"position":[[357,9],[613,10]]},"4587":{"position":[[1499,9]]},"4591":{"position":[[582,9]]},"4614":{"position":[[425,11]]},"4660":{"position":[[263,10],[655,10],[733,9],[792,9],[862,9],[935,9],[1669,10],[1936,9],[2050,9],[2436,9]]},"4662":{"position":[[249,10],[1358,10]]},"4691":{"position":[[1036,9],[1090,10]]},"4699":{"position":[[184,10]]},"4703":{"position":[[35,11],[258,11]]},"4705":{"position":[[57,10],[70,9],[154,11],[244,10],[330,9],[443,10],[549,10],[599,10]]},"4709":{"position":[[0,10],[113,10],[124,10]]},"4724":{"position":[[240,10]]},"4730":{"position":[[276,9],[414,11]]},"4797":{"position":[[297,9]]},"4801":{"position":[[102,9]]},"4826":{"position":[[85,10]]},"4833":{"position":[[35,10]]},"4839":{"position":[[323,10]]},"4847":{"position":[[13,10]]}}}],["component\",\"id\":\"3ebed33a",{"_index":9123,"t":{"2780":{"position":[[263,25]]}}}],["component'",{"_index":2676,"t":{"551":{"position":[[2656,11]]},"3571":{"position":[[1729,11]]}}}],["component(",{"_index":9283,"t":{"2914":{"position":[[823,12]]}}}],["component/compon",{"_index":10228,"t":{"3571":{"position":[[455,19]]}}}],["component=registri",{"_index":3130,"t":{"706":{"position":[[2114,18]]}}}],["components.yaml",{"_index":2445,"t":{"475":{"position":[[198,15]]},"580":{"position":[[456,15],[787,15]]}}}],["components/servic",{"_index":3199,"t":{"726":{"position":[[55,19]]}}}],["compos",{"_index":3210,"t":{"728":{"position":[[881,8]]},"1486":{"position":[[543,7]]},"1493":{"position":[[232,8]]},"1688":{"position":[[318,7],[338,7]]},"2112":{"position":[[397,8]]},"2117":{"position":[[116,7],[2179,7]]},"2155":{"position":[[579,7],[950,7]]},"3097":{"position":[[541,7],[593,7],[627,7],[674,7]]},"3130":{"position":[[659,7],[711,7],[745,7],[792,7]]},"3159":{"position":[[244,7],[321,7],[399,7],[517,8]]},"4427":{"position":[[124,8]]},"4440":{"position":[[115,8]]},"4451":{"position":[[115,8]]},"4562":{"position":[[6961,8],[7000,8],[7027,8]]},"4662":{"position":[[94,8]]}}}],["compose@manager.servic",{"_index":7745,"t":{"2155":{"position":[[227,23],[682,23]]}}}],["composit",{"_index":8643,"t":{"2580":{"position":[[48,14],[67,10]]},"2584":{"position":[[868,10],[923,13],[1151,10]]},"2586":{"position":[[478,10],[533,13],[761,10]]},"2602":{"position":[[133,11]]}}}],["comprehend",{"_index":10222,"t":{"3569":{"position":[[136,10]]},"3571":{"position":[[136,10]]}}}],["comprehens",{"_index":1860,"t":{"282":{"position":[[466,18]]},"297":{"position":[[228,14]]},"500":{"position":[[416,13]]},"530":{"position":[[723,13],[924,13]]},"533":{"position":[[20,13]]},"543":{"position":[[2373,13]]},"549":{"position":[[1551,14]]},"2489":{"position":[[1394,13]]},"2501":{"position":[[930,13]]},"2531":{"position":[[1373,13]]},"2555":{"position":[[92,13],[450,13]]},"2557":{"position":[[289,13]]},"2559":{"position":[[398,13]]},"2592":{"position":[[471,13]]},"2598":{"position":[[398,13]]},"3119":{"position":[[62,13]]},"3390":{"position":[[224,17]]},"3561":{"position":[[237,14]]},"3573":{"position":[[320,13]]},"3575":{"position":[[202,15]]},"3693":{"position":[[501,13]]},"3780":{"position":[[501,13]]},"4144":{"position":[[585,13]]},"4512":{"position":[[6,13]]}}}],["compress",{"_index":3883,"t":{"942":{"position":[[146,8]]},"951":{"position":[[701,11]]},"973":{"position":[[113,10]]},"1405":{"position":[[1072,8],[1234,12]]},"1833":{"position":[[146,8]]},"1842":{"position":[[701,11]]},"1864":{"position":[[113,10]]},"2682":{"position":[[612,8]]},"2966":{"position":[[146,8]]},"2975":{"position":[[701,11]]},"2997":{"position":[[113,10]]}}}],["compression_mod",{"_index":6067,"t":{"1409":{"position":[[730,17],[1231,17]]}}}],["compris",{"_index":3272,"t":{"794":{"position":[[15,9]]},"3071":{"position":[[60,9]]},"3148":{"position":[[88,9]]},"3180":{"position":[[118,9]]},"3561":{"position":[[56,9]]},"4516":{"position":[[1015,8]]}}}],["compromis",{"_index":4379,"t":{"1040":{"position":[[419,10]]},"2287":{"position":[[796,10]]},"2301":{"position":[[796,10]]},"2516":{"position":[[452,11]]},"2529":{"position":[[1093,12],[1265,10]]},"2531":{"position":[[341,12],[436,11]]},"2584":{"position":[[1650,10]]},"2586":{"position":[[1260,10]]},"4109":{"position":[[2621,10],[2764,10],[3566,15],[3635,10],[3976,11],[4408,10],[4502,10]]},"4133":{"position":[[1304,10],[1443,10],[1608,10],[1702,10]]},"4222":{"position":[[2353,11],[3523,12]]},"4304":{"position":[[641,10]]},"4433":{"position":[[900,11]]}}}],["comput",{"_index":1849,"t":{"280":{"position":[[854,10]]},"332":{"position":[[53,9]]},"545":{"position":[[178,8]]},"792":{"position":[[67,9]]},"814":{"position":[[55,7],[186,7]]},"816":{"position":[[49,7],[481,7],[798,7],[834,7]]},"818":{"position":[[392,7]]},"822":{"position":[[85,7]]},"824":{"position":[[2,7],[43,7],[84,7],[121,7],[335,7]]},"830":{"position":[[171,7]]},"834":{"position":[[92,7]]},"844":{"position":[[32,8],[185,7]]},"890":{"position":[[136,7]]},"906":{"position":[[558,7]]},"912":{"position":[[1125,7],[3365,7],[3415,7]]},"914":{"position":[[2464,11],[3140,7],[3771,11],[4478,7],[5112,11],[5795,7]]},"930":{"position":[[507,7]]},"978":{"position":[[403,7]]},"986":{"position":[[32,7],[55,7]]},"988":{"position":[[28,7],[51,7]]},"1003":{"position":[[112,7]]},"1005":{"position":[[388,7],[970,7],[996,7]]},"1016":{"position":[[0,7]]},"1018":{"position":[[0,7]]},"1022":{"position":[[14,7]]},"1030":{"position":[[52,7],[731,8]]},"1036":{"position":[[147,7],[230,7]]},"1038":{"position":[[245,7],[295,7]]},"1040":{"position":[[123,7]]},"1042":{"position":[[4,7]]},"1067":{"position":[[800,7]]},"1077":{"position":[[218,7]]},"1107":{"position":[[0,7]]},"1118":{"position":[[278,7],[321,7],[391,7],[449,7],[600,7],[649,7],[693,7],[714,7]]},"1201":{"position":[[637,7]]},"1226":{"position":[[3484,7],[3597,9]]},"1301":{"position":[[1506,7]]},"1363":{"position":[[44,7],[123,7]]},"1373":{"position":[[9,7],[469,7],[807,9],[963,7],[1061,9]]},"1375":{"position":[[205,7]]},"1377":{"position":[[56,7],[170,9]]},"1383":{"position":[[673,7],[2114,7]]},"1385":{"position":[[52,7],[309,7],[685,7],[797,7],[2316,7],[2425,7]]},"1455":{"position":[[77,7],[876,7],[901,7]]},"1709":{"position":[[42,7],[152,7],[194,7],[268,7],[305,7],[348,7],[407,7],[421,7],[464,7],[512,7]]},"1711":{"position":[[515,7],[691,7],[880,7],[966,7]]},"1713":{"position":[[43,7],[197,7],[288,7],[398,7],[448,7],[472,7],[648,7],[693,7],[1086,7],[1312,7],[1415,7],[2600,7],[2684,7]]},"1732":{"position":[[27,7],[103,7],[138,7],[708,7],[1038,7],[1087,7],[1122,7],[1519,7]]},"1734":{"position":[[32,7],[57,7],[104,7],[139,7],[709,7],[1038,7],[1063,7],[1108,7],[1143,7],[1713,7]]},"1743":{"position":[[338,7]]},"1748":{"position":[[136,7]]},"1790":{"position":[[558,7]]},"1796":{"position":[[1125,7],[3365,7],[3415,7]]},"1798":{"position":[[2464,11],[3140,7],[3771,11],[4478,7],[5112,11],[5795,7]]},"1821":{"position":[[507,7]]},"1869":{"position":[[403,7]]},"1877":{"position":[[32,7],[55,7]]},"1879":{"position":[[28,7],[51,7]]},"1894":{"position":[[112,7]]},"1896":{"position":[[388,7],[970,7],[996,7]]},"2252":{"position":[[2870,7]]},"2276":{"position":[[353,8],[698,7]]},"2327":{"position":[[35,7],[568,7]]},"2358":{"position":[[35,7]]},"2394":{"position":[[35,7],[568,7]]},"2425":{"position":[[35,7]]},"2576":{"position":[[199,7]]},"2954":{"position":[[507,7]]},"3002":{"position":[[403,7]]},"3103":{"position":[[275,8]]},"3136":{"position":[[275,8]]},"3255":{"position":[[105,9]]},"3285":{"position":[[326,7]]},"3367":{"position":[[466,7]]},"3406":{"position":[[286,7]]},"3569":{"position":[[401,7]]},"3673":{"position":[[452,7],[548,7],[641,7],[983,6]]},"3677":{"position":[[881,7]]},"3698":{"position":[[1587,7]]},"3714":{"position":[[315,7],[572,7],[1014,7],[1062,7],[1596,7]]},"3772":{"position":[[0,7],[191,7]]},"3791":{"position":[[903,7]]},"3807":{"position":[[73,7],[169,7],[264,7],[636,7]]},"3904":{"position":[[306,7]]},"3941":{"position":[[646,7]]},"3947":{"position":[[1211,7]]},"4096":{"position":[[342,7],[877,14]]},"4109":{"position":[[4758,8]]},"4155":{"position":[[391,7]]},"4157":{"position":[[775,8]]},"4159":{"position":[[2074,8]]},"4163":{"position":[[1576,8],[1585,7],[1634,7],[1706,7],[2152,7],[2387,7],[2549,7],[2736,7],[4397,7],[5155,7],[5230,7]]},"4165":{"position":[[209,7],[274,7],[327,7]]},"4167":{"position":[[3,7],[438,7]]},"4202":{"position":[[243,7],[256,7]]},"4217":{"position":[[167,7],[310,7]]},"4230":{"position":[[1459,7],[1545,7],[1604,7],[1825,7],[2211,7],[2374,7],[2532,7]]},"4296":{"position":[[253,7]]},"4302":{"position":[[812,7],[1174,7],[2701,7],[2950,7]]},"4304":{"position":[[43,7],[217,7],[2406,7],[2467,7],[2690,7]]},"4313":{"position":[[1468,7]]},"4327":{"position":[[39,7],[350,7],[674,7],[833,7]]},"4331":{"position":[[193,7]]},"4412":{"position":[[65,9]]},"4429":{"position":[[393,13]]},"4442":{"position":[[369,13]]},"4446":{"position":[[749,11]]},"4453":{"position":[[369,13]]},"4457":{"position":[[749,11]]},"4556":{"position":[[65,9],[98,9],[207,9]]},"4679":{"position":[[324,9]]},"4722":{"position":[[85,7]]},"4738":{"position":[[621,7]]},"4773":{"position":[[139,7]]},"4826":{"position":[[107,9]]},"4843":{"position":[[44,9]]}}}],["compute.conf",{"_index":5855,"t":{"1365":{"position":[[141,12]]},"1367":{"position":[[136,12]]},"1373":{"position":[[794,12],[1048,12]]},"1377":{"position":[[157,12]]}}}],["compute.inst",{"_index":9375,"t":{"3036":{"position":[[18,20]]}}}],["compute.instance.create.end",{"_index":9411,"t":{"3036":{"position":[[1077,27]]}}}],["compute.instance.exist",{"_index":9416,"t":{"3036":{"position":[[1305,23]]}}}],["compute.instance.upd",{"_index":9413,"t":{"3036":{"position":[[1201,23]]}}}],["compute:20.0.1.20230919",{"_index":7118,"t":{"1711":{"position":[[1740,23]]}}}],["compute:27.1.1.20230919",{"_index":7105,"t":{"1711":{"position":[[1207,23]]}}}],["compute_id",{"_index":7246,"t":{"1743":{"position":[[269,10]]}}}],["compute_zon",{"_index":4264,"t":{"1005":{"position":[[401,13],[983,12]]},"1896":{"position":[[401,13],[983,12]]}}}],["computefilter,computecapabilitiesfilter,imagepropertiesfilter,servergroupantiaffinityfilter,servergroupaffinityfilter,numatopologyfilt",{"_index":5863,"t":{"1371":{"position":[[421,136]]}}}],["con",{"_index":3746,"t":{"928":{"position":[[19,4]]},"1819":{"position":[[19,4]]},"2376":{"position":[[472,5]]},"2952":{"position":[[19,4]]},"4185":{"position":[[736,4]]},"4189":{"position":[[157,4],[539,5]]},"4279":{"position":[[861,5]]},"4281":{"position":[[1010,5]]},"4283":{"position":[[1061,5]]},"4510":{"position":[[149,4]]},"4512":{"position":[[133,5]]},"4514":{"position":[[206,5]]},"4518":{"position":[[257,5]]}}}],["conceal",{"_index":11296,"t":{"4222":{"position":[[1929,9]]}}}],["concentr",{"_index":2342,"t":{"425":{"position":[[15,11],[422,13]]},"597":{"position":[[219,11]]},"4161":{"position":[[405,11]]}}}],["concept",{"_index":569,"t":{"78":{"position":[[169,8]]},"356":{"position":[[248,8]]},"500":{"position":[[458,8],[524,8]]},"924":{"position":[[2023,8]]},"1009":{"position":[[4,7]]},"1815":{"position":[[2023,8]]},"2580":{"position":[[547,8]]},"2582":{"position":[[238,8]]},"2794":{"position":[[84,8]]},"2914":{"position":[[404,8]]},"2948":{"position":[[2023,8]]},"3121":{"position":[[106,7],[318,8]]},"3294":{"position":[[1129,10]]},"3308":{"position":[[872,7]]},"3344":{"position":[[220,8]]},"3346":{"position":[[467,7]]},"3348":{"position":[[167,8]]},"3352":{"position":[[2031,7]]},"3527":{"position":[[248,7]]},"3592":{"position":[[288,9],[1219,7],[2537,9]]},"3757":{"position":[[13,7]]},"4041":{"position":[[27,8]]},"4047":{"position":[[589,7]]},"4081":{"position":[[1514,8]]},"4094":{"position":[[125,8]]},"4146":{"position":[[1750,7]]},"4230":{"position":[[363,7],[1021,7],[1074,8]]},"4232":{"position":[[19,7]]},"4279":{"position":[[1371,8]]},"4281":{"position":[[1378,8]]},"4370":{"position":[[249,7]]},"4395":{"position":[[205,7]]},"4433":{"position":[[2127,7]]},"4446":{"position":[[624,7]]},"4457":{"position":[[624,7]]},"4479":{"position":[[2296,7]]},"4531":{"position":[[53,8]]},"4551":{"position":[[52,8]]},"4569":{"position":[[196,7]]},"4574":{"position":[[437,8],[483,9]]},"4593":{"position":[[1036,7],[1637,7],[4700,7]]}}}],["concepts/api's/autom",{"_index":9285,"t":{"2914":{"position":[[1214,25]]}}}],["conceptu",{"_index":9914,"t":{"3288":{"position":[[77,14]]},"4222":{"position":[[2555,10]]},"4606":{"position":[[424,10]]},"4643":{"position":[[691,10]]}}}],["concern",{"_index":8350,"t":{"2321":{"position":[[112,8]]},"2388":{"position":[[112,8]]},"2485":{"position":[[500,9]]},"2487":{"position":[[125,8]]},"2525":{"position":[[694,9]]},"3468":{"position":[[28,9]]},"4081":{"position":[[1882,10]]},"4098":{"position":[[395,10]]},"4220":{"position":[[60,9]]},"4222":{"position":[[925,7]]},"4236":{"position":[[60,7]]},"4257":{"position":[[5069,10]]},"4302":{"position":[[1873,10]]},"4306":{"position":[[731,10]]},"4493":{"position":[[453,8]]},"4865":{"position":[[145,10]]}}}],["concis",{"_index":1902,"t":{"293":{"position":[[34,7]]},"2709":{"position":[[128,7]]},"3571":{"position":[[1085,7]]},"4362":{"position":[[22,7]]}}}],["conclud",{"_index":11404,"t":{"4257":{"position":[[5602,9]]}}}],["conclus",{"_index":10971,"t":{"3947":{"position":[[484,11],[1040,11],[1936,11],[2556,11],[3152,11],[4119,11]]},"3984":{"position":[[1536,11]]},"4081":{"position":[[2023,10]]},"4291":{"position":[[649,10]]},"4477":{"position":[[22,10]]},"4522":{"position":[[1459,11]]},"4654":{"position":[[609,10]]}}}],["concret",{"_index":1561,"t":{"209":{"position":[[110,8]]},"786":{"position":[[30,8]]},"4228":{"position":[[1263,8]]},"4362":{"position":[[328,8]]}}}],["concurr",{"_index":3201,"t":{"726":{"position":[[121,12]]},"741":{"position":[[1013,10]]},"4504":{"position":[[910,10]]},"4506":{"position":[[1600,10],[1666,10]]},"4508":{"position":[[657,12],[721,12]]},"4512":{"position":[[500,10]]}}}],["condens",{"_index":5935,"t":{"1387":{"position":[[328,9]]},"1484":{"position":[[784,9]]},"1979":{"position":[[328,9]]},"2148":{"position":[[328,9]]}}}],["condit",{"_index":875,"t":{"153":{"position":[[28,9],[191,9]]},"192":{"position":[[90,9]]},"417":{"position":[[2106,10]]},"481":{"position":[[82,11]]},"1301":{"position":[[2412,12],[2956,12]]},"3537":{"position":[[164,10]]},"3770":{"position":[[87,9]]},"4034":{"position":[[470,10]]},"4485":{"position":[[2647,9]]},"4656":{"position":[[877,10]]}}}],["conditions@latest",{"_index":2468,"t":{"481":{"position":[[126,17]]}}}],["condorcet",{"_index":10289,"t":{"3640":{"position":[[84,9]]}}}],["conduc",{"_index":7764,"t":{"2155":{"position":[[1836,8]]}}}],["conduct",{"_index":1420,"t":{"197":{"position":[[2047,7]]},"199":{"position":[[1149,7],[3210,7],[3265,7],[3310,8]]},"293":{"position":[[935,9]]},"551":{"position":[[3243,7]]},"2489":{"position":[[150,7]]},"2567":{"position":[[1207,7]]},"3110":{"position":[[209,7]]},"3627":{"position":[[403,8]]},"3629":{"position":[[517,8]]},"4224":{"position":[[2375,9]]},"4726":{"position":[[13,9]]},"4733":{"position":[[13,9]]}}}],["conductor",{"_index":3300,"t":{"818":{"position":[[528,9],[553,9],[587,11]]},"2155":{"position":[[1783,9],[1845,9]]}}}],["conect",{"_index":8460,"t":{"2433":{"position":[[564,8]]}}}],["conf",{"_index":3638,"t":{"912":{"position":[[1565,8]]},"914":{"position":[[1017,8]]},"1005":{"position":[[1081,8],[6540,6]]},"1796":{"position":[[1565,8]]},"1798":{"position":[[1017,8]]},"1896":{"position":[[1081,8],[6540,6]]}}}],["confer",{"_index":1778,"t":{"255":{"position":[[522,10]]},"4560":{"position":[[2303,12],[3546,12]]}}}],["conferenc",{"_index":1743,"t":{"253":{"position":[[51,13]]},"4839":{"position":[[588,12]]}}}],["confid",{"_index":1340,"t":{"187":{"position":[[399,11]]},"3606":{"position":[[1532,10]]},"4148":{"position":[[361,9]]},"4763":{"position":[[131,9]]}}}],["confidenti",{"_index":9899,"t":{"3255":{"position":[[92,12]]}}}],["config",{"_index":691,"t":{"111":{"position":[[21,6]]},"368":{"position":[[3397,6]]},"520":{"position":[[352,6]]},"528":{"position":[[176,6],[360,6],[579,6],[727,6],[918,6]]},"555":{"position":[[108,6]]},"588":{"position":[[991,6]]},"622":{"position":[[213,7],[360,7]]},"659":{"position":[[625,6]]},"661":{"position":[[150,7],[301,7]]},"705":{"position":[[828,6],[946,6],[1794,6]]},"738":{"position":[[726,6]]},"892":{"position":[[306,6]]},"912":{"position":[[425,6],[444,6],[1515,6],[1540,6],[1754,6],[1886,6],[1913,6],[1942,6]]},"914":{"position":[[510,6],[529,6],[967,6],[992,6],[1206,6],[1338,6],[1365,6],[1394,6]]},"916":{"position":[[4,6],[174,6]]},"955":{"position":[[440,6]]},"963":{"position":[[486,7],[498,6],[4973,6],[5291,7]]},"973":{"position":[[465,6]]},"1005":{"position":[[418,6],[437,6],[1031,6],[1056,6],[1271,6],[1404,6],[1431,6],[1460,6],[6454,6],[6515,6],[6727,6],[6878,6]]},"1007":{"position":[[4,6],[158,6]]},"1193":{"position":[[70,6]]},"1252":{"position":[[3799,6]]},"1301":{"position":[[380,6],[2343,6],[2432,6]]},"1303":{"position":[[169,6],[257,6],[314,6],[2667,6]]},"1371":{"position":[[311,7]]},"1373":{"position":[[122,6]]},"1391":{"position":[[663,7],[1615,7]]},"1421":{"position":[[590,7],[1120,6],[1545,7],[1668,7],[1761,6]]},"1439":{"position":[[14,6],[105,6]]},"1564":{"position":[[321,6]]},"1635":{"position":[[361,6]]},"1694":{"position":[[3272,6],[3588,6],[3848,6],[3983,6],[4118,6],[4252,6],[5094,6]]},"1750":{"position":[[306,6]]},"1796":{"position":[[425,6],[444,6],[1515,6],[1540,6],[1754,6],[1886,6],[1913,6],[1942,6]]},"1798":{"position":[[510,6],[529,6],[967,6],[992,6],[1206,6],[1338,6],[1365,6],[1394,6]]},"1800":{"position":[[4,6],[174,6]]},"1846":{"position":[[440,6]]},"1854":{"position":[[486,7],[498,6],[4973,6],[5291,7]]},"1864":{"position":[[465,6]]},"1896":{"position":[[418,6],[437,6],[1031,6],[1056,6],[1271,6],[1404,6],[1431,6],[1460,6],[6454,6],[6515,6],[6727,6],[6878,6]]},"1898":{"position":[[4,6],[158,6]]},"2037":{"position":[[178,6],[340,6]]},"2123":{"position":[[970,6]]},"2128":{"position":[[4,6],[145,6]]},"2132":{"position":[[499,6],[677,6],[796,6]]},"2190":{"position":[[700,6],[823,6]]},"2248":{"position":[[381,6]]},"2368":{"position":[[221,6]]},"2602":{"position":[[323,6]]},"2612":{"position":[[21,6],[128,6]]},"2655":{"position":[[408,6],[529,6]]},"2661":{"position":[[337,6]]},"2682":{"position":[[686,6]]},"2692":{"position":[[1373,6]]},"2728":{"position":[[301,6]]},"2756":{"position":[[801,6],[829,6]]},"2855":{"position":[[74,7]]},"2859":{"position":[[25,6],[224,7]]},"2883":{"position":[[244,6]]},"2979":{"position":[[440,6]]},"2987":{"position":[[486,7],[498,6],[4973,6],[5291,7]]},"2997":{"position":[[465,6]]},"3030":{"position":[[210,6]]},"3384":{"position":[[1314,6]]},"4060":{"position":[[177,6],[361,6]]},"4348":{"position":[[223,6]]},"4662":{"position":[[698,6],[793,6],[851,6]]},"4730":{"position":[[2359,6]]}}}],["config.example.osism.yaml",{"_index":5937,"t":{"1389":{"position":[[197,25]]},"1391":{"position":[[2519,25]]}}}],["config.example.yaml",{"_index":5936,"t":{"1389":{"position":[[177,19]]},"1391":{"position":[[9,19],[264,19],[637,19],[911,19],[1583,19],[1887,19],[2911,19]]},"1981":{"position":[[91,19]]},"1996":{"position":[[59,19]]}}}],["config.json",{"_index":5582,"t":{"1303":{"position":[[3864,11],[4564,11]]},"1694":{"position":[[4377,11]]},"2928":{"position":[[44,11]]}}}],["config.tmpl.json",{"_index":9297,"t":{"2928":{"position":[[178,17]]}}}],["config.yaml",{"_index":3041,"t":{"692":{"position":[[42,11]]},"1389":{"position":[[46,12]]},"1981":{"position":[[78,12]]},"1984":{"position":[[206,12]]},"1996":{"position":[[9,11]]},"2480":{"position":[[184,11]]},"2612":{"position":[[32,11]]},"2655":{"position":[[429,11]]}}}],["config.yaml.j2",{"_index":2581,"t":{"522":{"position":[[523,14]]}}}],["config.yaml.templ",{"_index":11488,"t":{"4348":{"position":[[253,22]]}}}],["config/cspo",{"_index":2535,"t":{"510":{"position":[[79,11]]}}}],["config/openstack",{"_index":8280,"t":{"2272":{"position":[[105,19]]}}}],["config/openstack/clouds.yaml",{"_index":3760,"t":{"932":{"position":[[115,31]]},"934":{"position":[[255,31]]},"1823":{"position":[[115,31]]},"1825":{"position":[[255,31]]},"2956":{"position":[[115,31]]},"2958":{"position":[[255,31]]},"3384":{"position":[[935,29]]}}}],["config/openstack/secure.yaml",{"_index":3820,"t":{"934":{"position":[[1016,32]]},"1825":{"position":[[1016,32]]},"2958":{"position":[[1016,32]]}}}],["config/systemd/us",{"_index":3928,"t":{"942":{"position":[[3602,23],[3655,23]]},"1833":{"position":[[3602,23],[3655,23]]},"2966":{"position":[[3602,23],[3655,23]]}}}],["config=\"config",{"_index":8853,"t":{"2682":{"position":[[181,16]]}}}],["config_fil",{"_index":5588,"t":{"1303":{"position":[[4198,15],[4835,15]]}}}],["configdb",{"_index":11962,"t":{"4849":{"position":[[1500,10]]}}}],["configfil",{"_index":4347,"t":{"1005":{"position":[[6476,11]]},"1896":{"position":[[6476,11]]}}}],["configmap",{"_index":3229,"t":{"741":{"position":[[853,10]]},"2567":{"position":[[47,9],[314,9]]},"2569":{"position":[[82,10],[127,10]]},"2604":{"position":[[328,9],[501,10]]},"2624":{"position":[[650,9],[673,9],[785,10],[925,9]]},"4113":{"position":[[2117,10]]}}}],["configmap.yaml",{"_index":8613,"t":{"2565":{"position":[[67,14]]}}}],["configur",{"_index":706,"t":{"119":{"position":[[247,13]]},"151":{"position":[[414,13]]},"155":{"position":[[119,9]]},"159":{"position":[[205,13]]},"253":{"position":[[203,13]]},"258":{"position":[[166,13],[441,10]]},"293":{"position":[[385,14],[691,10]]},"319":{"position":[[405,10]]},"323":{"position":[[1228,10],[1393,9]]},"339":{"position":[[118,13],[214,14]]},"354":{"position":[[273,10]]},"358":{"position":[[159,14],[189,13]]},"360":{"position":[[145,13],[672,13],[759,13]]},"362":{"position":[[11,10]]},"364":{"position":[[71,14],[326,13],[494,15]]},"366":{"position":[[755,13]]},"368":{"position":[[5492,13]]},"376":{"position":[[313,13]]},"391":{"position":[[190,14],[223,14]]},"397":{"position":[[30,11]]},"401":{"position":[[70,13]]},"423":{"position":[[618,16]]},"430":{"position":[[125,9],[286,11]]},"446":{"position":[[226,13]]},"450":{"position":[[77,13]]},"473":{"position":[[405,9]]},"498":{"position":[[95,13]]},"504":{"position":[[148,9],[322,11]]},"514":{"position":[[1756,13],[1813,13]]},"522":{"position":[[45,13],[375,13]]},"533":{"position":[[287,11],[368,14],[424,15],[521,15]]},"539":{"position":[[57,11],[207,14],[315,13],[496,14]]},"541":{"position":[[290,10]]},"543":{"position":[[917,14],[2457,15]]},"545":{"position":[[1110,14]]},"549":{"position":[[1267,14]]},"553":{"position":[[27,13]]},"557":{"position":[[2430,13],[2478,9],[2550,9],[3273,9],[3363,9]]},"578":{"position":[[365,9]]},"586":{"position":[[0,9]]},"588":{"position":[[38,9]]},"597":{"position":[[435,13]]},"620":{"position":[[27,11]]},"622":{"position":[[11,13],[511,14],[569,13]]},"632":{"position":[[233,13]]},"641":{"position":[[385,9],[562,9]]},"655":{"position":[[94,10],[243,13]]},"657":{"position":[[81,10],[571,13]]},"659":{"position":[[70,10],[232,13]]},"661":{"position":[[4,13],[354,14],[677,14]]},"666":{"position":[[385,9],[562,9]]},"668":{"position":[[245,11],[312,14]]},"673":{"position":[[94,10],[243,13]]},"706":{"position":[[337,14],[1776,13]]},"712":{"position":[[348,14]]},"738":{"position":[[847,9]]},"741":{"position":[[1112,10],[1461,10]]},"816":{"position":[[908,9]]},"867":{"position":[[4,13],[199,14]]},"871":{"position":[[1062,13]]},"873":{"position":[[1117,13]]},"887":{"position":[[1231,10]]},"894":{"position":[[202,13]]},"910":{"position":[[567,13]]},"914":{"position":[[128,10]]},"924":{"position":[[624,13],[656,11]]},"930":{"position":[[129,9]]},"934":{"position":[[224,9],[1397,9],[2379,9]]},"936":{"position":[[135,9]]},"942":{"position":[[489,9]]},"949":{"position":[[501,10],[723,10]]},"951":{"position":[[1365,12]]},"957":{"position":[[61,13]]},"961":{"position":[[85,10],[937,9],[1182,9]]},"963":{"position":[[624,9],[1324,13],[1861,10]]},"1009":{"position":[[322,13],[385,11]]},"1056":{"position":[[809,15],[1939,10]]},"1067":{"position":[[545,13],[1480,14],[2458,14]]},"1103":{"position":[[28,14]]},"1142":{"position":[[563,13]]},"1151":{"position":[[46,9]]},"1167":{"position":[[320,13]]},"1169":{"position":[[14,13],[1185,13],[1225,13],[1369,13]]},"1175":{"position":[[82,13],[528,9],[3080,13],[3102,13],[3173,13],[3241,13],[3310,13],[3353,9],[3400,13],[3531,13],[3587,13],[3705,9],[3874,9],[4414,13],[4442,13],[4493,13]]},"1177":{"position":[[589,13],[617,9],[702,9],[983,13],[1054,9],[4192,13],[4220,9],[4305,9],[4586,13],[4657,9]]},"1179":{"position":[[32,13],[519,13],[995,13],[1030,13],[1141,13],[1177,9],[2068,13],[2103,13]]},"1183":{"position":[[45,14],[338,10],[555,13]]},"1185":{"position":[[243,13],[378,13]]},"1191":{"position":[[406,13]]},"1195":{"position":[[63,13]]},"1199":{"position":[[797,13]]},"1214":{"position":[[155,13]]},"1216":{"position":[[4,13],[96,13]]},"1218":{"position":[[29,13],[131,13],[229,13]]},"1220":{"position":[[182,13],[702,13]]},"1222":{"position":[[1473,16]]},"1224":{"position":[[16,13],[761,13]]},"1226":{"position":[[4,13],[192,13],[241,13],[337,13],[580,13],[2125,13],[2248,14],[2407,13],[2474,13],[2503,13],[3794,14],[5863,13],[6043,13]]},"1230":{"position":[[482,13],[1401,13],[1436,13]]},"1232":{"position":[[2,13],[105,13],[161,13],[211,13],[530,13]]},"1234":{"position":[[43,13],[124,13],[182,14],[240,13]]},"1236":{"position":[[36,13],[77,13],[857,13],[1285,13]]},"1238":{"position":[[52,13]]},"1244":{"position":[[87,9],[126,13],[232,13],[506,13],[938,13]]},"1246":{"position":[[396,13]]},"1248":{"position":[[1101,13],[1212,9]]},"1250":{"position":[[185,14],[218,11]]},"1252":{"position":[[292,13],[500,13],[929,13],[2580,9],[2874,10],[3551,14],[3625,14]]},"1257":{"position":[[265,13],[656,13],[1415,13],[1692,13],[1781,13]]},"1259":{"position":[[1212,13]]},"1261":{"position":[[536,13]]},"1266":{"position":[[124,13],[822,13],[1547,13],[1669,13],[1716,14],[2409,13],[2537,13]]},"1268":{"position":[[61,15]]},"1271":{"position":[[121,14]]},"1275":{"position":[[8,13],[38,13],[127,13]]},"1277":{"position":[[22,13],[47,13]]},"1279":{"position":[[34,13]]},"1281":{"position":[[30,13],[59,13]]},"1283":{"position":[[26,13],[53,13]]},"1287":{"position":[[32,13],[62,13]]},"1289":{"position":[[26,13]]},"1295":{"position":[[71,10]]},"1297":{"position":[[90,13],[1402,13],[3875,13]]},"1301":{"position":[[298,13],[938,10],[1338,13],[1446,9],[2015,13],[2185,14],[2575,9],[3217,13],[3342,13],[3520,13]]},"1303":{"position":[[59,13],[2050,13],[2707,13],[3287,13],[3912,11]]},"1305":{"position":[[72,10],[375,14]]},"1308":{"position":[[22,13]]},"1310":{"position":[[28,13],[56,13]]},"1312":{"position":[[203,13]]},"1318":{"position":[[26,13]]},"1320":{"position":[[26,13]]},"1322":{"position":[[30,13]]},"1324":{"position":[[178,13],[208,9],[354,13],[548,13]]},"1327":{"position":[[26,13],[53,13]]},"1329":{"position":[[28,13],[56,13],[165,13],[209,13],[291,13]]},"1331":{"position":[[354,13],[430,13],[489,13]]},"1333":{"position":[[32,13],[62,13]]},"1335":{"position":[[28,13],[56,13]]},"1338":{"position":[[18,13]]},"1340":{"position":[[44,13]]},"1354":{"position":[[263,10]]},"1356":{"position":[[22,13],[47,13]]},"1369":{"position":[[90,13]]},"1371":{"position":[[568,13]]},"1373":{"position":[[906,13],[1110,13]]},"1375":{"position":[[12,10],[343,13]]},"1383":{"position":[[560,10],[601,9],[1501,13],[1687,13],[2141,9]]},"1385":{"position":[[281,13],[628,13]]},"1389":{"position":[[12,13]]},"1391":{"position":[[1684,13]]},"1397":{"position":[[482,11]]},"1399":{"position":[[68,13],[230,13]]},"1407":{"position":[[243,9]]},"1409":{"position":[[61,9]]},"1413":{"position":[[113,13]]},"1421":{"position":[[1678,13]]},"1423":{"position":[[289,13]]},"1433":{"position":[[238,14],[832,13]]},"1435":{"position":[[58,9]]},"1437":{"position":[[76,13]]},"1443":{"position":[[55,14]]},"1447":{"position":[[117,9]]},"1451":{"position":[[298,10],[545,10],[907,13]]},"1455":{"position":[[929,9]]},"1457":{"position":[[2703,13],[2854,14],[2918,14],[3039,13],[4087,13]]},"1460":{"position":[[156,13],[189,13],[259,13],[302,13]]},"1464":{"position":[[418,14],[755,14],[822,9]]},"1466":{"position":[[655,9],[815,9],[1866,9]]},"1470":{"position":[[54,13]]},"1472":{"position":[[2539,13]]},"1474":{"position":[[382,14],[492,13],[574,9],[665,14],[728,13],[858,13],[928,13]]},"1478":{"position":[[13,13],[48,13],[370,9]]},"1497":{"position":[[59,13],[92,13],[162,13],[324,13]]},"1501":{"position":[[50,13],[185,13],[246,13],[278,13],[301,13],[384,13],[485,13],[820,13],[994,13],[1180,13],[1304,13]]},"1503":{"position":[[752,13],[882,13],[1651,13],[2805,13]]},"1505":{"position":[[353,9]]},"1509":{"position":[[99,13]]},"1513":{"position":[[868,9]]},"1517":{"position":[[116,13]]},"1523":{"position":[[1282,9],[1750,9]]},"1525":{"position":[[944,13],[1350,13],[2314,13]]},"1552":{"position":[[235,13],[468,13],[512,10]]},"1561":{"position":[[79,13],[1076,13],[1150,13],[1201,14]]},"1574":{"position":[[282,13]]},"1600":{"position":[[12,13],[71,13],[111,13]]},"1644":{"position":[[291,13]]},"1657":{"position":[[145,13]]},"1661":{"position":[[52,13],[123,13]]},"1665":{"position":[[115,13]]},"1711":{"position":[[835,13]]},"1713":{"position":[[7,13],[84,13],[141,13],[2552,13]]},"1752":{"position":[[202,13]]},"1768":{"position":[[4,13],[199,14]]},"1772":{"position":[[1062,13]]},"1774":{"position":[[1117,13]]},"1794":{"position":[[567,13]]},"1798":{"position":[[128,10]]},"1811":{"position":[[1231,10]]},"1815":{"position":[[624,13],[656,11]]},"1821":{"position":[[129,9]]},"1825":{"position":[[224,9],[1397,9],[2379,9]]},"1827":{"position":[[135,9]]},"1833":{"position":[[489,9]]},"1840":{"position":[[501,10],[723,10]]},"1842":{"position":[[1365,12]]},"1848":{"position":[[61,13]]},"1852":{"position":[[85,10],[937,9],[1182,9]]},"1854":{"position":[[624,9],[1324,13],[1861,10]]},"1906":{"position":[[227,13]]},"1917":{"position":[[282,13]]},"1984":{"position":[[192,10]]},"1988":{"position":[[254,15]]},"2003":{"position":[[178,13]]},"2009":{"position":[[101,9]]},"2013":{"position":[[237,13]]},"2015":{"position":[[80,9]]},"2021":{"position":[[234,13]]},"2025":{"position":[[446,14]]},"2032":{"position":[[1177,13]]},"2039":{"position":[[230,13]]},"2045":{"position":[[198,13]]},"2048":{"position":[[15,14],[1677,14],[1790,10],[1812,13],[2119,13],[2665,11],[2699,10]]},"2055":{"position":[[782,13]]},"2065":{"position":[[273,13]]},"2067":{"position":[[374,13]]},"2086":{"position":[[415,13]]},"2090":{"position":[[195,13]]},"2117":{"position":[[168,9]]},"2121":{"position":[[367,14]]},"2123":{"position":[[1686,14]]},"2128":{"position":[[53,13]]},"2132":{"position":[[169,13]]},"2163":{"position":[[3399,13],[4393,13]]},"2165":{"position":[[218,13],[425,10]]},"2171":{"position":[[344,13],[408,13],[818,13],[1555,13],[1841,13],[1930,13],[2063,13],[2121,13]]},"2184":{"position":[[401,9]]},"2190":{"position":[[561,13],[655,14],[719,13]]},"2196":{"position":[[91,10],[1040,13],[2520,13],[3325,13]]},"2199":{"position":[[774,13]]},"2207":{"position":[[497,13],[550,9],[965,9]]},"2209":{"position":[[57,13],[106,9]]},"2219":{"position":[[30,9]]},"2221":{"position":[[4,13],[87,13]]},"2240":{"position":[[1303,13]]},"2248":{"position":[[287,13]]},"2252":{"position":[[2390,10]]},"2272":{"position":[[40,13],[229,13]]},"2276":{"position":[[1674,13]]},"2287":{"position":[[143,13],[452,13],[946,14]]},"2301":{"position":[[143,13],[452,13],[946,14]]},"2321":{"position":[[293,13]]},"2368":{"position":[[86,13],[343,10]]},"2376":{"position":[[188,10],[335,13]]},"2388":{"position":[[293,13]]},"2429":{"position":[[77,9]]},"2431":{"position":[[1676,14],[4190,10]]},"2433":{"position":[[60,13],[791,10],[830,10]]},"2437":{"position":[[399,13]]},"2439":{"position":[[121,13]]},"2441":{"position":[[26,13],[159,13],[251,13]]},"2447":{"position":[[70,10]]},"2453":{"position":[[199,13]]},"2467":{"position":[[1371,13],[1429,13],[1558,13]]},"2469":{"position":[[44,13],[102,13],[231,13]]},"2473":{"position":[[101,13]]},"2475":{"position":[[108,10]]},"2478":{"position":[[39,14],[441,14],[696,14],[935,14],[1229,13],[1697,14],[2422,14],[2733,14]]},"2480":{"position":[[237,13],[320,13],[398,14],[998,14],[1204,14],[1304,14]]},"2482":{"position":[[10,13],[62,14]]},"2497":{"position":[[333,13]]},"2499":{"position":[[508,15]]},"2506":{"position":[[356,13],[410,14]]},"2508":{"position":[[463,13]]},"2510":{"position":[[317,13]]},"2512":{"position":[[441,15],[838,13],[1503,13],[1701,13],[1740,15]]},"2529":{"position":[[913,14],[984,15]]},"2531":{"position":[[1493,14]]},"2537":{"position":[[58,13],[417,15]]},"2539":{"position":[[222,15]]},"2555":{"position":[[389,14]]},"2567":{"position":[[79,14],[215,14],[352,10],[575,10],[824,15],[856,15],[1332,14],[1392,14],[1654,14],[1715,9],[1800,14]]},"2569":{"position":[[72,9]]},"2574":{"position":[[685,14]]},"2602":{"position":[[67,13],[244,13]]},"2606":{"position":[[346,10]]},"2614":{"position":[[375,14]]},"2636":{"position":[[660,11],[873,14]]},"2647":{"position":[[312,13],[791,9],[867,11],[1911,14]]},"2649":{"position":[[347,13],[2969,14]]},"2651":{"position":[[109,13]]},"2661":{"position":[[207,10],[273,13],[381,13],[443,13]]},"2663":{"position":[[27,13],[78,13]]},"2674":{"position":[[135,14]]},"2692":{"position":[[1527,9],[1606,13],[1653,10]]},"2703":{"position":[[79,9]]},"2714":{"position":[[160,10]]},"2720":{"position":[[0,13],[87,13]]},"2728":{"position":[[28,13],[155,13]]},"2743":{"position":[[77,10]]},"2756":{"position":[[1036,13]]},"2820":{"position":[[10,13]]},"2822":{"position":[[0,9]]},"2824":{"position":[[63,9]]},"2826":{"position":[[258,13],[347,13]]},"2830":{"position":[[15,9]]},"2855":{"position":[[0,9]]},"2859":{"position":[[113,9]]},"2863":{"position":[[13,13]]},"2883":{"position":[[11,14],[228,9],[409,9],[487,9],[561,13]]},"2900":{"position":[[160,9],[317,13],[335,14]]},"2906":{"position":[[17,13]]},"2928":{"position":[[18,13],[151,13],[210,14]]},"2930":{"position":[[59,13],[148,13],[1237,13]]},"2934":{"position":[[290,9],[530,13]]},"2948":{"position":[[624,13],[656,11]]},"2954":{"position":[[129,9]]},"2958":{"position":[[224,9],[1397,9],[2379,9]]},"2960":{"position":[[135,9]]},"2966":{"position":[[489,9]]},"2973":{"position":[[501,10],[723,10]]},"2975":{"position":[[1365,12]]},"2981":{"position":[[61,13]]},"2985":{"position":[[85,10],[937,9],[1182,9]]},"2987":{"position":[[624,9],[1324,13],[1861,10]]},"3022":{"position":[[1064,10]]},"3050":{"position":[[19,13]]},"3088":{"position":[[110,13]]},"3093":{"position":[[165,13]]},"3223":{"position":[[239,14],[851,12]]},"3238":{"position":[[535,9],[685,14]]},"3257":{"position":[[162,13]]},"3259":{"position":[[324,14]]},"3281":{"position":[[369,13]]},"3313":{"position":[[318,11]]},"3348":{"position":[[756,13]]},"3350":{"position":[[108,13]]},"3352":{"position":[[1330,13],[1366,13],[1745,13],[2261,10]]},"3418":{"position":[[225,14]]},"3470":{"position":[[882,13]]},"3571":{"position":[[1195,14],[1464,14],[1510,12]]},"3575":{"position":[[829,13]]},"3669":{"position":[[387,10]]},"3710":{"position":[[400,10]]},"3744":{"position":[[1217,14],[2039,14]]},"3803":{"position":[[387,10]]},"3837":{"position":[[61,10]]},"3890":{"position":[[115,13]]},"3932":{"position":[[247,10],[1016,13]]},"3941":{"position":[[1587,13]]},"3943":{"position":[[363,14],[550,14]]},"3947":{"position":[[64,10],[248,14],[2139,13],[2284,10],[2946,10],[3400,9],[3738,13],[4487,13],[4659,14]]},"3960":{"position":[[39,13],[243,11],[285,13],[525,9]]},"3962":{"position":[[82,13],[226,13],[283,13]]},"3984":{"position":[[288,10],[375,10],[509,13],[658,9],[1667,10]]},"4026":{"position":[[52,10]]},"4028":{"position":[[197,13]]},"4030":{"position":[[24,10]]},"4043":{"position":[[209,10]]},"4045":{"position":[[388,10],[569,10]]},"4053":{"position":[[25,15]]},"4060":{"position":[[920,10]]},"4077":{"position":[[516,10]]},"4113":{"position":[[2170,13]]},"4120":{"position":[[189,10],[301,10]]},"4126":{"position":[[176,10]]},"4135":{"position":[[355,13]]},"4144":{"position":[[206,9]]},"4146":{"position":[[1863,13]]},"4148":{"position":[[525,13]]},"4163":{"position":[[2994,11],[3160,13],[3290,10],[3452,11],[3483,13]]},"4167":{"position":[[297,11]]},"4178":{"position":[[321,13]]},"4180":{"position":[[250,13]]},"4182":{"position":[[337,15]]},"4224":{"position":[[2741,14]]},"4230":{"position":[[2944,14],[3157,15],[3324,13],[3595,13],[4139,13],[4819,9],[4937,13]]},"4240":{"position":[[187,13],[298,13]]},"4270":{"position":[[929,13]]},"4298":{"position":[[207,13]]},"4302":{"position":[[1816,13],[1852,13],[2844,10]]},"4304":{"position":[[786,11],[1456,14],[1787,10],[2042,10],[2096,10],[2880,14],[3025,14]]},"4306":{"position":[[16,13],[159,13],[563,13],[750,15]]},"4310":{"position":[[551,15]]},"4319":{"position":[[20,14],[144,14]]},"4323":{"position":[[60,10],[127,10],[223,14],[298,10],[459,11]]},"4325":{"position":[[237,10],[301,14],[343,10]]},"4327":{"position":[[282,10],[405,13],[535,14]]},"4331":{"position":[[257,10]]},"4372":{"position":[[91,11]]},"4479":{"position":[[1515,14]]},"4481":{"position":[[889,13]]},"4485":{"position":[[991,10],[1137,13]]},"4489":{"position":[[497,9],[779,13]]},"4525":{"position":[[246,14],[349,14]]},"4529":{"position":[[31,13],[106,13]]},"4537":{"position":[[63,14]]},"4539":{"position":[[7456,9]]},"4541":{"position":[[2097,10]]},"4543":{"position":[[963,14],[1348,10]]},"4547":{"position":[[551,11]]},"4551":{"position":[[152,9]]},"4562":{"position":[[3899,10]]},"4569":{"position":[[630,13]]},"4591":{"position":[[377,9],[896,13]]},"4593":{"position":[[1192,13],[1872,11],[2172,13],[2767,13],[3989,10],[4556,13],[4614,14],[5068,14]]},"4597":{"position":[[104,13]]},"4608":{"position":[[15,13],[605,14],[861,13]]},"4610":{"position":[[50,13]]},"4614":{"position":[[1262,10],[1372,13]]},"4618":{"position":[[161,10],[295,13]]},"4632":{"position":[[1520,10],[2184,13]]},"4643":{"position":[[3110,10]]},"4660":{"position":[[1454,13]]},"4662":{"position":[[682,13]]},"4665":{"position":[[79,13]]},"4667":{"position":[[582,13],[13146,10]]},"4669":{"position":[[53,13],[358,13],[839,13]]},"4730":{"position":[[863,10],[912,10],[952,10],[995,10],[1079,10],[1123,10],[1168,10],[1215,10],[1260,10],[1311,10],[1368,10],[1416,10]]},"4765":{"position":[[87,13]]},"4826":{"position":[[159,11],[3677,13]]},"4831":{"position":[[18,13]]},"4833":{"position":[[8,13]]},"4839":{"position":[[1658,12]]},"4845":{"position":[[162,13]]},"4847":{"position":[[132,13]]},"4849":{"position":[[150,13]]},"4861":{"position":[[511,14]]},"4877":{"position":[[376,13]]},"4883":{"position":[[92,13]]}}}],["configuration.md",{"_index":9222,"t":{"2863":{"position":[[31,17]]},"2883":{"position":[[579,17]]},"3571":{"position":[[336,16]]}}}],["configuration.yml",{"_index":4664,"t":{"1175":{"position":[[3493,18]]},"1177":{"position":[[826,18],[4429,18]]},"1179":{"position":[[1267,17]]},"1185":{"position":[[421,18]]},"1252":{"position":[[543,18],[2403,17]]},"1259":{"position":[[629,18]]},"2207":{"position":[[335,18],[1041,17],[1122,18]]},"3093":{"position":[[17,17],[141,19]]}}}],["configuration/monitoring/ceph",{"_index":7256,"t":{"1909":{"position":[[41,29]]}}}],["configuration_directori",{"_index":4637,"t":{"1173":{"position":[[490,23]]},"1443":{"position":[[496,23]]}}}],["configuration_git_vers",{"_index":5214,"t":{"1259":{"position":[[600,25]]}}}],["configuration_vers",{"_index":8049,"t":{"2219":{"position":[[245,21]]}}}],["confirm",{"_index":1622,"t":{"224":{"position":[[152,9],[257,13]]},"295":{"position":[[615,7],[953,7]]},"440":{"position":[[446,7]]},"2032":{"position":[[774,13]]},"3925":{"position":[[546,9]]}}}],["conflict",{"_index":6134,"t":{"1431":{"position":[[289,11]]},"2034":{"position":[[1077,11]]},"2725":{"position":[[197,9]]},"2743":{"position":[[106,10]]},"3101":{"position":[[51,9]]},"4257":{"position":[[3462,11]]},"4508":{"position":[[765,10]]},"4562":{"position":[[669,9]]},"4604":{"position":[[305,8]]},"4665":{"position":[[669,8]]}}}],["conform",{"_index":1833,"t":{"277":{"position":[[138,11]]},"297":{"position":[[31,11],[291,11]]},"299":{"position":[[41,11]]},"301":{"position":[[82,11],[108,11],[524,11],[589,11],[647,11],[793,11]]},"305":{"position":[[251,11],[682,11]]},"309":{"position":[[0,11],[284,11]]},"524":{"position":[[180,11],[300,11],[426,11],[552,11]]},"526":{"position":[[124,11],[155,11],[555,11],[792,11]]},"530":{"position":[[839,11]]},"2845":{"position":[[127,10]]},"3071":{"position":[[300,11]]},"3103":{"position":[[84,11]]},"3136":{"position":[[84,11],[848,11],[918,11]]},"3168":{"position":[[281,11]]},"3346":{"position":[[267,10]]},"3361":{"position":[[198,12]]},"3365":{"position":[[73,7]]},"3371":{"position":[[73,7]]},"3468":{"position":[[731,11]]},"3529":{"position":[[311,11],[376,11],[421,11]]},"3537":{"position":[[235,11],[539,10]]},"3554":{"position":[[213,11],[248,11]]},"3556":{"position":[[63,11]]},"3558":{"position":[[114,11],[286,7]]},"3592":{"position":[[616,8]]},"3704":{"position":[[107,7]]},"3740":{"position":[[46,7]]},"3879":{"position":[[169,10]]},"3883":{"position":[[379,7]]},"3938":{"position":[[193,10]]},"4055":{"position":[[4,11]]},"4089":{"position":[[0,11],[271,10]]},"4130":{"position":[[0,11]]},"4171":{"position":[[101,12]]},"4198":{"position":[[701,12]]},"4206":{"position":[[142,11]]},"4261":{"position":[[352,11]]},"4268":{"position":[[65,12]]},"4273":{"position":[[801,11]]},"4275":{"position":[[559,11]]},"4279":{"position":[[1344,11]]},"4283":{"position":[[165,11]]},"4291":{"position":[[9,11],[898,11],[1287,11],[1475,11]]},"4310":{"position":[[903,11]]},"4315":{"position":[[351,11]]},"4337":{"position":[[0,11],[176,11]]},"4348":{"position":[[4,11]]},"4407":{"position":[[151,12]]},"4499":{"position":[[0,11]]},"4549":{"position":[[0,11]]},"4651":{"position":[[0,11]]},"4775":{"position":[[86,11]]},"4824":{"position":[[0,11]]},"4826":{"position":[[2703,11]]}}}],["confront",{"_index":1410,"t":{"197":{"position":[[1513,8],[1768,8]]}}}],["confus",{"_index":2967,"t":{"611":{"position":[[710,9]]},"1252":{"position":[[2437,9]]},"3556":{"position":[[28,9]]},"3990":{"position":[[1194,7]]},"4047":{"position":[[804,7]]},"4163":{"position":[[4358,9]]},"4632":{"position":[[2656,9]]}}}],["congest",{"_index":11544,"t":{"4479":{"position":[[152,10]]}}}],["conjunct",{"_index":9251,"t":{"2889":{"position":[[338,11]]},"3712":{"position":[[472,11]]},"4308":{"position":[[199,11]]},"4327":{"position":[[850,11]]},"4608":{"position":[[738,11]]}}}],["conn",{"_index":6229,"t":{"1457":{"position":[[1540,4],[1659,4],[2290,4]]}}}],["connect",{"_index":165,"t":{"24":{"position":[[193,9]]},"253":{"position":[[257,8]]},"255":{"position":[[0,7],[504,9],[600,12],[639,12]]},"264":{"position":[[3,7]]},"291":{"position":[[145,10]]},"293":{"position":[[442,12]]},"295":{"position":[[137,10]]},"311":{"position":[[278,7],[332,10]]},"313":{"position":[[109,7]]},"315":{"position":[[102,7]]},"317":{"position":[[139,7]]},"319":{"position":[[143,7],[350,7],[1059,9]]},"325":{"position":[[48,7],[143,7]]},"366":{"position":[[65,10]]},"368":{"position":[[2357,7]]},"423":{"position":[[933,7]]},"520":{"position":[[859,7]]},"541":{"position":[[624,12],[963,12],[1087,13]]},"551":{"position":[[616,10]]},"557":{"position":[[4512,9]]},"741":{"position":[[1024,12]]},"812":{"position":[[403,9],[476,12]]},"824":{"position":[[176,8]]},"836":{"position":[[417,10]]},"848":{"position":[[220,7]]},"924":{"position":[[1529,12]]},"932":{"position":[[446,9],[473,8],[1377,7],[2605,7],[3739,7],[3820,11]]},"949":{"position":[[525,11]]},"963":{"position":[[1540,10],[1988,12]]},"976":{"position":[[130,7]]},"978":{"position":[[1163,7]]},"980":{"position":[[1007,10]]},"1030":{"position":[[241,7]]},"1034":{"position":[[88,8]]},"1046":{"position":[[52,9]]},"1048":{"position":[[48,9]]},"1107":{"position":[[188,7]]},"1195":{"position":[[156,7]]},"1301":{"position":[[3409,10]]},"1391":{"position":[[1346,12],[1552,10],[1818,7]]},"1405":{"position":[[234,12],[1420,7]]},"1457":{"position":[[3382,11],[3608,7]]},"1464":{"position":[[448,13]]},"1466":{"position":[[195,13]]},"1484":{"position":[[395,7]]},"1655":{"position":[[164,10]]},"1704":{"position":[[82,10],[1891,12],[2570,12]]},"1740":{"position":[[349,11]]},"1745":{"position":[[133,7]]},"1815":{"position":[[1529,12]]},"1823":{"position":[[446,9],[473,8],[1377,7],[2605,7],[3739,7],[3820,11]]},"1840":{"position":[[525,11]]},"1854":{"position":[[1540,10],[1988,12]]},"1867":{"position":[[130,7]]},"1869":{"position":[[1163,7]]},"1871":{"position":[[1007,10]]},"1986":{"position":[[45,7],[147,11]]},"2027":{"position":[[784,13]]},"2032":{"position":[[1070,7],[1435,11]]},"2034":{"position":[[904,7]]},"2037":{"position":[[244,7]]},"2048":{"position":[[891,10],[956,10],[1030,10],[1089,10],[1148,10],[1209,10],[1270,10],[1331,10],[2889,11]]},"2121":{"position":[[318,11]]},"2142":{"position":[[238,7],[296,10]]},"2144":{"position":[[1329,10]]},"2146":{"position":[[756,12],[817,12]]},"2152":{"position":[[43,12],[93,10],[141,10]]},"2188":{"position":[[207,7]]},"2190":{"position":[[462,7]]},"2196":{"position":[[27,7],[1797,7],[2587,8]]},"2250":{"position":[[165,7]]},"2256":{"position":[[628,10]]},"2283":{"position":[[198,8]]},"2287":{"position":[[379,12]]},"2297":{"position":[[198,8]]},"2301":{"position":[[379,12]]},"2366":{"position":[[280,7],[334,10]]},"2374":{"position":[[90,8]]},"2376":{"position":[[161,7]]},"2380":{"position":[[910,7]]},"2431":{"position":[[675,7],[1078,7],[1322,7]]},"2433":{"position":[[126,7],[189,7],[847,9]]},"2716":{"position":[[1258,10]]},"2718":{"position":[[353,9]]},"2720":{"position":[[1040,10],[1069,10]]},"2743":{"position":[[0,10]]},"2824":{"position":[[77,10]]},"2940":{"position":[[122,7]]},"2948":{"position":[[1529,12]]},"2956":{"position":[[446,9],[473,8],[1377,7],[2605,7],[3739,7],[3820,11]]},"2973":{"position":[[525,11]]},"2987":{"position":[[1540,10],[1988,12]]},"3000":{"position":[[130,7]]},"3002":{"position":[[1163,7]]},"3004":{"position":[[1007,10]]},"3047":{"position":[[364,10]]},"3086":{"position":[[1001,7],[1390,11]]},"3088":{"position":[[37,7]]},"3101":{"position":[[193,10]]},"3183":{"position":[[383,13]]},"3238":{"position":[[568,7],[814,7]]},"3255":{"position":[[51,7]]},"3288":{"position":[[331,11]]},"3313":{"position":[[146,7],[195,7]]},"3346":{"position":[[744,10]]},"3398":{"position":[[2162,11]]},"3833":{"position":[[584,7]]},"3845":{"position":[[29,8]]},"3859":{"position":[[28,8]]},"3883":{"position":[[139,7]]},"3906":{"position":[[141,7]]},"3928":{"position":[[4095,10]]},"3978":{"position":[[96,7]]},"3980":{"position":[[64,10]]},"4034":{"position":[[58,8]]},"4037":{"position":[[206,8]]},"4066":{"position":[[36,8]]},"4096":{"position":[[915,12]]},"4109":{"position":[[1028,12],[1170,12],[1348,13],[1451,12],[3674,10]]},"4130":{"position":[[398,8]]},"4133":{"position":[[457,12],[599,12],[777,13],[880,12]]},"4135":{"position":[[415,12]]},"4146":{"position":[[610,7]]},"4159":{"position":[[1385,11]]},"4161":{"position":[[650,12],[820,11]]},"4163":{"position":[[407,7],[988,10],[1155,10],[1334,9],[2298,10],[3801,10]]},"4167":{"position":[[644,10],[670,10],[688,11]]},"4178":{"position":[[472,10],[726,11]]},"4220":{"position":[[779,7]]},"4222":{"position":[[1881,12]]},"4224":{"position":[[1180,11]]},"4230":{"position":[[564,10]]},"4294":{"position":[[31,12]]},"4300":{"position":[[517,12]]},"4302":{"position":[[1953,10],[2041,12],[3095,11],[3152,11],[3241,11],[3419,10]]},"4304":{"position":[[826,11],[950,11],[2310,11]]},"4308":{"position":[[923,11],[1081,12]]},"4313":{"position":[[327,10]]},"4323":{"position":[[155,10],[324,11]]},"4325":{"position":[[262,12]]},"4327":{"position":[[19,11],[663,10]]},"4329":{"position":[[66,11]]},"4333":{"position":[[30,9],[83,11],[340,11]]},"4337":{"position":[[346,8],[449,8]]},"4359":{"position":[[65,10]]},"4365":{"position":[[33,8]]},"4390":{"position":[[46,8]]},"4407":{"position":[[78,10]]},"4506":{"position":[[699,11]]},"4508":{"position":[[645,11]]},"4572":{"position":[[106,12]]},"4580":{"position":[[1231,11]]},"4589":{"position":[[275,7]]},"4593":{"position":[[2504,9],[3602,7],[5647,9]]},"4629":{"position":[[65,8]]},"4705":{"position":[[272,12]]},"4726":{"position":[[286,12]]},"4733":{"position":[[929,12]]},"4791":{"position":[[311,10],[411,10]]},"4826":{"position":[[2646,11]]}}}],["connect/auth?client_id=secur",{"_index":8449,"t":{"2431":{"position":[[3410,31]]}}}],["connect/auth?scope=openid",{"_index":8453,"t":{"2431":{"position":[[3793,30]]}}}],["connection_uri",{"_index":11463,"t":{"4304":{"position":[[3050,15]]}}}],["consectetur",{"_index":5,"t":{"3":{"position":[[28,11]]}}}],["consecut",{"_index":10919,"t":{"3894":{"position":[[2037,11]]}}}],["consensu",{"_index":9281,"t":{"2914":{"position":[[379,9],[498,9],[529,9]]},"3531":{"position":[[158,10],[207,9]]},"4310":{"position":[[1476,9]]}}}],["consequ",{"_index":2611,"t":{"530":{"position":[[2215,13]]},"2196":{"position":[[666,10]]},"3529":{"position":[[1895,12]]},"3563":{"position":[[245,13]]},"3879":{"position":[[457,12]]},"3992":{"position":[[68,12]]},"3998":{"position":[[92,12]]},"4073":{"position":[[222,12]]},"4094":{"position":[[253,12]]},"4098":{"position":[[342,11]]},"4107":{"position":[[936,13],[1019,12],[1041,12],[1759,12]]},"4109":{"position":[[797,12],[1670,12],[2531,12],[3482,12],[3896,12],[4223,12]]},"4133":{"position":[[226,12]]},"4146":{"position":[[487,13]]},"4593":{"position":[[1576,12]]}}}],["consequat",{"_index":17,"t":{"3":{"position":[[141,10]]}}}],["consequnc",{"_index":11204,"t":{"4113":{"position":[[1438,11]]}}}],["conserv",{"_index":4055,"t":{"963":{"position":[[3262,10]]},"1571":{"position":[[487,12]]},"1854":{"position":[[3262,10]]},"1904":{"position":[[487,12]]},"2987":{"position":[[3262,10]]}}}],["consid",{"_index":1028,"t":{"169":{"position":[[460,10],[516,8],[1145,8]]},"175":{"position":[[489,8]]},"177":{"position":[[213,10],[327,10],[606,11],[762,10],[909,8]]},"181":{"position":[[787,10]]},"190":{"position":[[231,10]]},"216":{"position":[[295,9]]},"218":{"position":[[14,8]]},"220":{"position":[[207,9]]},"288":{"position":[[10,10]]},"293":{"position":[[1057,10]]},"364":{"position":[[553,10]]},"368":{"position":[[2174,10]]},"530":{"position":[[1674,8]]},"545":{"position":[[461,10]]},"732":{"position":[[1612,8]]},"844":{"position":[[282,10]]},"930":{"position":[[685,8]]},"934":{"position":[[1474,8]]},"936":{"position":[[711,8]]},"940":{"position":[[272,8]]},"963":{"position":[[3816,8]]},"969":{"position":[[57,8],[250,8]]},"973":{"position":[[43,8],[411,8]]},"1030":{"position":[[453,10]]},"1439":{"position":[[277,10]]},"1623":{"position":[[110,11]]},"1821":{"position":[[685,8]]},"1825":{"position":[[1474,8]]},"1827":{"position":[[711,8]]},"1831":{"position":[[272,8]]},"1854":{"position":[[3816,8]]},"1860":{"position":[[57,8],[250,8]]},"1864":{"position":[[43,8],[411,8]]},"1954":{"position":[[110,11]]},"2146":{"position":[[901,10]]},"2261":{"position":[[23,10]]},"2487":{"position":[[739,11]]},"2647":{"position":[[1226,8]]},"2649":{"position":[[2491,8]]},"2794":{"position":[[239,10]]},"2836":{"position":[[125,10]]},"2857":{"position":[[107,8]]},"2875":{"position":[[117,10]]},"2954":{"position":[[685,8]]},"2958":{"position":[[1474,8]]},"2960":{"position":[[711,8]]},"2964":{"position":[[272,8]]},"2987":{"position":[[3816,8]]},"2993":{"position":[[57,8],[250,8]]},"2997":{"position":[[43,8],[411,8]]},"3022":{"position":[[435,8]]},"3460":{"position":[[476,11]]},"3527":{"position":[[2335,10]]},"3529":{"position":[[650,11],[767,10],[1881,11]]},"3535":{"position":[[84,10]]},"3539":{"position":[[324,10]]},"3598":{"position":[[384,10]]},"3606":{"position":[[1064,10]]},"3608":{"position":[[189,10]]},"3681":{"position":[[1487,10]]},"3718":{"position":[[1526,10]]},"3811":{"position":[[1503,10]]},"3826":{"position":[[215,10]]},"3829":{"position":[[1535,10]]},"3835":{"position":[[551,10]]},"3928":{"position":[[4531,10]]},"3932":{"position":[[705,10]]},"3947":{"position":[[830,10],[1272,9]]},"3956":{"position":[[25,10]]},"3984":{"position":[[0,11]]},"4015":{"position":[[44,10]]},"4081":{"position":[[63,10],[423,8]]},"4107":{"position":[[2152,10]]},"4109":{"position":[[42,10],[1993,8]]},"4144":{"position":[[480,9]]},"4159":{"position":[[1341,10],[1621,10]]},"4161":{"position":[[243,9]]},"4189":{"position":[[3,8],[135,8]]},"4198":{"position":[[123,8],[558,10]]},"4204":{"position":[[144,10]]},"4220":{"position":[[1442,11]]},"4222":{"position":[[799,11],[1082,8]]},"4228":{"position":[[322,10]]},"4253":{"position":[[49,10],[203,10]]},"4257":{"position":[[45,11],[1181,11],[1394,10]]},"4268":{"position":[[280,10]]},"4291":{"position":[[925,11]]},"4302":{"position":[[3715,10],[4451,10]]},"4304":{"position":[[988,10],[1117,10]]},"4306":{"position":[[590,11]]},"4313":{"position":[[397,11],[485,10]]},"4422":{"position":[[230,10],[397,11]]},"4479":{"position":[[452,11]]},"4535":{"position":[[2090,10]]},"4545":{"position":[[56,10]]},"4560":{"position":[[552,10],[774,10],[1020,10],[1755,10],[3123,10]]},"4562":{"position":[[1742,10],[1912,10],[2718,8],[5383,9]]},"4597":{"position":[[317,10]]},"4699":{"position":[[319,10],[411,10]]},"4707":{"position":[[1171,10]]},"4744":{"position":[[314,10]]},"4795":{"position":[[74,11]]}}}],["consider",{"_index":1738,"t":{"249":{"position":[[2097,14]]},"852":{"position":[[214,12]]},"1042":{"position":[[217,14]]},"2584":{"position":[[560,13]]},"2586":{"position":[[170,13]]},"3052":{"position":[[750,14]]},"3272":{"position":[[12,12]]},"3529":{"position":[[671,14]]},"3554":{"position":[[83,15]]},"3602":{"position":[[1170,15]]},"3681":{"position":[[971,14]]},"3718":{"position":[[1010,14]]},"3811":{"position":[[1010,14]]},"3815":{"position":[[635,14]]},"4011":{"position":[[4,14]]},"4104":{"position":[[257,13]]},"4146":{"position":[[3286,13]]},"4198":{"position":[[184,13]]},"4224":{"position":[[2986,15]]},"4230":{"position":[[303,15]]},"4232":{"position":[[214,15]]},"4300":{"position":[[444,14]]},"4313":{"position":[[27,14]]},"4327":{"position":[[924,14]]},"4446":{"position":[[12,14]]},"4457":{"position":[[12,14]]},"4477":{"position":[[55,14]]},"4502":{"position":[[54,14]]},"4506":{"position":[[496,13]]},"4531":{"position":[[73,15]]},"4591":{"position":[[792,14]]},"4684":{"position":[[37,14]]}}}],["considerations.md",{"_index":1740,"t":{"249":{"position":[[2196,18]]}}}],["consist",{"_index":505,"t":{"70":{"position":[[233,10]]},"197":{"position":[[1919,8]]},"201":{"position":[[627,10]]},"249":{"position":[[1169,10]]},"297":{"position":[[213,10]]},"378":{"position":[[280,11]]},"539":{"position":[[89,13]]},"543":{"position":[[2903,10]]},"593":{"position":[[158,7]]},"611":{"position":[[90,8]]},"664":{"position":[[158,7]]},"706":{"position":[[241,8]]},"712":{"position":[[252,8]]},"812":{"position":[[24,8]]},"820":{"position":[[34,8]]},"867":{"position":[[18,8]]},"910":{"position":[[441,8]]},"1056":{"position":[[1181,10],[1351,11],[2184,10]]},"1064":{"position":[[312,10],[689,10],[1350,10],[2332,10]]},"1768":{"position":[[18,8]]},"1794":{"position":[[441,8]]},"2094":{"position":[[93,10]]},"2211":{"position":[[595,10],[1131,10]]},"2333":{"position":[[149,10],[172,11]]},"2339":{"position":[[401,10],[424,11]]},"2358":{"position":[[603,8]]},"2400":{"position":[[149,10],[172,11]]},"2406":{"position":[[401,10],[424,11]]},"2425":{"position":[[603,8]]},"2501":{"position":[[696,12]]},"2529":{"position":[[54,7]]},"2574":{"position":[[100,10],[170,10],[248,10],[1084,10],[1144,10]]},"2576":{"position":[[31,10]]},"2608":{"position":[[930,10]]},"2754":{"position":[[57,10]]},"3088":{"position":[[565,10]]},"3344":{"position":[[523,8]]},"3348":{"position":[[92,8]]},"3355":{"position":[[62,8]]},"3357":{"position":[[3191,8]]},"3361":{"position":[[549,8]]},"3386":{"position":[[39,10]]},"3390":{"position":[[198,12]]},"3414":{"position":[[459,11]]},"3418":{"position":[[454,11]]},"3527":{"position":[[701,7]]},"3563":{"position":[[388,10]]},"3575":{"position":[[433,10]]},"3625":{"position":[[61,8]]},"3837":{"position":[[125,11]]},"3928":{"position":[[4148,11]]},"4030":{"position":[[756,11]]},"4113":{"position":[[1744,10]]},"4163":{"position":[[563,7]]},"4306":{"position":[[283,10]]},"4313":{"position":[[195,8]]},"4427":{"position":[[54,8]]},"4431":{"position":[[2019,13]]},"4433":{"position":[[1266,7]]},"4440":{"position":[[54,8]]},"4451":{"position":[[54,8]]},"4481":{"position":[[19,11]]},"4547":{"position":[[2480,10]]},"4627":{"position":[[306,10]]},"4669":{"position":[[1253,10]]},"4671":{"position":[[52,10]]},"4679":{"position":[[28,8]]},"4724":{"position":[[94,10]]},"4730":{"position":[[665,7]]},"4872":{"position":[[9,8]]}}}],["consol",{"_index":3786,"t":{"932":{"position":[[2573,7],[2657,7],[3933,7]]},"938":{"position":[[619,7],[1612,7]]},"976":{"position":[[202,7]]},"978":{"position":[[524,7],[549,7]]},"1266":{"position":[[2625,7]]},"1340":{"position":[[8,7],[36,7]]},"1391":{"position":[[410,7]]},"1455":{"position":[[1530,7],[1558,7]]},"1667":{"position":[[2,7]]},"1669":{"position":[[19,7],[35,7],[96,8],[330,7]]},"1671":{"position":[[97,7],[232,7]]},"1673":{"position":[[41,7],[452,7]]},"1675":{"position":[[27,7],[251,7]]},"1823":{"position":[[2573,7],[2657,7],[3933,7]]},"1829":{"position":[[619,7],[1612,7]]},"1867":{"position":[[202,7]]},"1869":{"position":[[524,7],[549,7]]},"1996":{"position":[[168,7]]},"2032":{"position":[[1768,8]]},"2034":{"position":[[854,7],[1855,8]]},"2142":{"position":[[415,7]]},"2184":{"position":[[3660,7]]},"2256":{"position":[[23,7],[52,7],[803,7]]},"2270":{"position":[[460,7],[478,7]]},"2431":{"position":[[3286,7],[3448,9],[3997,7],[4465,8]]},"2956":{"position":[[2573,7],[2657,7],[3933,7]]},"2962":{"position":[[619,7],[1612,7]]},"3000":{"position":[[202,7]]},"3002":{"position":[[524,7],[549,7]]},"3083":{"position":[[724,7]]},"3916":{"position":[[535,7]]}}}],["console.log('insid",{"_index":808,"t":{"143":{"position":[[492,19]]}}}],["console.services.a.regiocloud.tech",{"_index":5465,"t":{"1297":{"position":[[2893,34]]}}}],["consolid",{"_index":8717,"t":{"2614":{"position":[[4,12]]},"4275":{"position":[[71,12]]},"4291":{"position":[[278,11]]},"4580":{"position":[[2340,12]]}}}],["conspicu",{"_index":11297,"t":{"4222":{"position":[[2027,11]]}}}],["const",{"_index":807,"t":{"143":{"position":[[465,5]]},"167":{"position":[[936,5],[961,5],[1086,5],[1226,5],[1262,5],[1429,5],[1503,5],[1613,5],[1713,5],[1859,5],[1988,5],[2118,5]]}}}],["constantli",{"_index":8581,"t":{"2525":{"position":[[202,10]]},"4116":{"position":[[298,10]]},"4302":{"position":[[3458,10]]}}}],["constitut",{"_index":1194,"t":{"177":{"position":[[13,11]]}}}],["constrain",{"_index":8711,"t":{"2608":{"position":[[127,11]]}}}],["constraint",{"_index":2834,"t":{"557":{"position":[[7008,12]]},"2287":{"position":[[171,12]]},"2301":{"position":[[171,12]]},"4431":{"position":[[937,10],[1036,10]]},"4433":{"position":[[2889,10]]},"4437":{"position":[[136,11]]},"4522":{"position":[[307,12]]},"4733":{"position":[[1831,11]]},"4746":{"position":[[285,13]]}}}],["constru",{"_index":10249,"t":{"3592":{"position":[[2281,9]]},"3761":{"position":[[769,9]]}}}],["construct",{"_index":1457,"t":{"199":{"position":[[1082,12],[2741,15]]},"303":{"position":[[392,11]]},"3582":{"position":[[2049,12]]},"3683":{"position":[[84,9]]},"3742":{"position":[[129,9]]},"3795":{"position":[[84,9]]},"4178":{"position":[[270,12]]}}}],["consult",{"_index":5163,"t":{"1240":{"position":[[109,7]]},"2258":{"position":[[133,11]]},"3083":{"position":[[559,7]]},"3116":{"position":[[290,7]]},"3365":{"position":[[282,7]]},"3371":{"position":[[282,7]]},"4130":{"position":[[566,7]]},"4169":{"position":[[160,9]]},"4337":{"position":[[589,7]]},"4629":{"position":[[278,7]]}}}],["consum",{"_index":1144,"t":{"173":{"position":[[1403,7]]},"175":{"position":[[95,7]]},"177":{"position":[[145,9]]},"181":{"position":[[1925,7]]},"183":{"position":[[317,9]]},"319":{"position":[[56,7]]},"854":{"position":[[213,8],[230,8],[239,8],[344,8]]},"1720":{"position":[[201,8],[432,8],[819,8],[1529,8],[2343,8]]},"2114":{"position":[[16,7]]},"2119":{"position":[[637,8]]},"2146":{"position":[[678,9]]},"2221":{"position":[[426,9]]},"2647":{"position":[[1044,10]]},"2678":{"position":[[204,7]]},"3050":{"position":[[399,10]]},"3073":{"position":[[808,9]]},"3086":{"position":[[962,7]]},"3355":{"position":[[541,7]]},"3706":{"position":[[515,9]]},"3799":{"position":[[515,9]]},"3988":{"position":[[1651,9]]},"4124":{"position":[[996,9]]},"4370":{"position":[[51,9],[350,9]]},"4395":{"position":[[8,9],[290,9]]},"4397":{"position":[[19,9]]},"4587":{"position":[[592,7]]},"4589":{"position":[[640,7]]},"4654":{"position":[[74,8],[294,9]]},"4660":{"position":[[1550,8],[1685,8]]},"4757":{"position":[[96,9],[193,9]]},"4767":{"position":[[216,9],[280,8]]},"4791":{"position":[[204,8]]},"4801":{"position":[[586,10]]}}}],["consumpt",{"_index":6211,"t":{"1455":{"position":[[1209,11],[1340,12],[1679,11]]},"3189":{"position":[[579,11]]},"3820":{"position":[[321,12],[446,12]]},"4562":{"position":[[6579,11],[6610,11]]},"4593":{"position":[[5324,11]]},"4703":{"position":[[199,12]]},"4728":{"position":[[964,11]]}}}],["contact",{"_index":132,"t":{"19":{"position":[[49,7]]},"26":{"position":[[202,7]]},"28":{"position":[[41,7]]},"31":{"position":[[61,7]]},"33":{"position":[[41,7]]},"197":{"position":[[1827,7]]},"205":{"position":[[83,7]]},"243":{"position":[[34,7]]},"253":{"position":[[352,8]]},"692":{"position":[[586,7]]},"1250":{"position":[[502,9]]},"2178":{"position":[[333,7]]},"2839":{"position":[[269,7]]},"3835":{"position":[[1821,7]]},"4109":{"position":[[4020,7]]},"4835":{"position":[[1908,7]]}}}],["contain",{"_index":158,"t":{"24":{"position":[[63,7]]},"39":{"position":[[249,12]]},"66":{"position":[[66,9]]},"80":{"position":[[9,9],[48,10]]},"84":{"position":[[98,9],[493,9]]},"93":{"position":[[16,10],[78,7],[131,10]]},"97":{"position":[[15,7]]},"99":{"position":[[15,7]]},"173":{"position":[[811,7]]},"181":{"position":[[1127,8]]},"249":{"position":[[2061,7]]},"271":{"position":[[129,10],[229,10],[570,10]]},"273":{"position":[[163,11]]},"275":{"position":[[89,7]]},"301":{"position":[[142,7]]},"315":{"position":[[11,9]]},"319":{"position":[[748,9]]},"334":{"position":[[134,9],[174,9]]},"337":{"position":[[428,9]]},"360":{"position":[[259,10]]},"364":{"position":[[954,8]]},"368":{"position":[[7668,8]]},"370":{"position":[[4,9],[97,9],[344,9]]},"372":{"position":[[63,9],[254,9]]},"374":{"position":[[4,9],[206,9],[258,10],[366,9]]},"376":{"position":[[40,9]]},"378":{"position":[[466,10],[512,9],[548,9],[580,9],[647,9]]},"380":{"position":[[81,10]]},"401":{"position":[[587,8],[684,8],[1167,8]]},"417":{"position":[[1512,9],[1560,9],[1656,10],[1694,9]]},"423":{"position":[[386,9]]},"434":{"position":[[1779,9]]},"442":{"position":[[385,9]]},"459":{"position":[[72,8]]},"463":{"position":[[1466,8]]},"487":{"position":[[175,10]]},"491":{"position":[[869,9]]},"496":{"position":[[111,9]]},"512":{"position":[[607,9]]},"514":{"position":[[176,9]]},"518":{"position":[[689,8]]},"522":{"position":[[322,7]]},"524":{"position":[[653,8],[1389,8]]},"528":{"position":[[219,8]]},"533":{"position":[[452,9]]},"541":{"position":[[492,9],[562,9]]},"543":{"position":[[226,9]]},"555":{"position":[[686,10]]},"572":{"position":[[22,8]]},"622":{"position":[[54,8]]},"655":{"position":[[456,9],[747,9]]},"659":{"position":[[294,10],[437,10],[614,10]]},"668":{"position":[[839,7]]},"673":{"position":[[456,9],[747,9]]},"696":{"position":[[79,9],[817,9]]},"701":{"position":[[389,8],[2502,8]]},"706":{"position":[[1938,9],[2019,9]]},"719":{"position":[[25,9]]},"728":{"position":[[88,9],[569,8],[848,10]]},"739":{"position":[[1637,7]]},"741":{"position":[[71,9]]},"743":{"position":[[93,9]]},"749":{"position":[[52,9]]},"753":{"position":[[103,9],[189,9]]},"755":{"position":[[72,9]]},"796":{"position":[[15,9],[61,9]]},"850":{"position":[[202,11],[330,10]]},"871":{"position":[[288,9]]},"873":{"position":[[349,9]]},"896":{"position":[[180,8]]},"942":{"position":[[653,9]]},"951":{"position":[[76,8],[509,7],[856,9],[975,9],[1083,9],[1254,8]]},"963":{"position":[[1343,8]]},"1009":{"position":[[679,8]]},"1073":{"position":[[168,10],[403,9]]},"1140":{"position":[[13,8]]},"1185":{"position":[[408,8]]},"1189":{"position":[[279,9],[357,9]]},"1222":{"position":[[160,10]]},"1224":{"position":[[692,8]]},"1248":{"position":[[1266,10]]},"1252":{"position":[[530,8]]},"1268":{"position":[[26,8]]},"1303":{"position":[[117,10],[793,9],[3352,9],[3815,10],[3848,9]]},"1352":{"position":[[19,10]]},"1391":{"position":[[1482,7],[2247,10],[3319,8]]},"1397":{"position":[[655,9]]},"1443":{"position":[[891,9]]},"1445":{"position":[[13,8]]},"1451":{"position":[[400,9],[750,8],[870,10]]},"1453":{"position":[[13,8]]},"1472":{"position":[[90,10]]},"1493":{"position":[[56,10],[317,9]]},"1513":{"position":[[229,9]]},"1523":{"position":[[132,8]]},"1542":{"position":[[19,9]]},"1673":{"position":[[56,9]]},"1694":{"position":[[2877,10]]},"1696":{"position":[[12,9]]},"1711":{"position":[[941,10],[1032,9],[1121,9]]},"1754":{"position":[[180,8]]},"1772":{"position":[[288,9]]},"1774":{"position":[[349,9]]},"1833":{"position":[[653,9]]},"1842":{"position":[[76,8],[509,7],[856,9],[975,9],[1083,9],[1254,8]]},"1854":{"position":[[1343,8]]},"2059":{"position":[[761,9],[979,9],[1491,9]]},"2065":{"position":[[448,8]]},"2071":{"position":[[24,9],[423,9],[467,9],[573,9],[876,9],[1238,9],[1415,9],[1750,10],[1839,9]]},"2074":{"position":[[95,9],[545,9],[646,9],[683,9],[777,9]]},"2076":{"position":[[23,9],[225,9],[327,9],[362,9]]},"2119":{"position":[[110,8]]},"2123":{"position":[[1114,10]]},"2142":{"position":[[355,10]]},"2150":{"position":[[75,7]]},"2163":{"position":[[3661,10]]},"2165":{"position":[[102,11],[298,10],[749,10],[809,10]]},"2178":{"position":[[902,8]]},"2196":{"position":[[1602,8],[2779,8]]},"2211":{"position":[[365,11],[2463,10]]},"2231":{"position":[[56,10]]},"2276":{"position":[[271,8]]},"2285":{"position":[[845,8],[952,7]]},"2299":{"position":[[845,8],[952,7]]},"2325":{"position":[[507,7]]},"2327":{"position":[[734,10]]},"2343":{"position":[[480,7],[815,8]]},"2349":{"position":[[307,9],[368,9]]},"2380":{"position":[[886,9]]},"2382":{"position":[[194,9]]},"2392":{"position":[[507,7]]},"2394":{"position":[[734,10]]},"2410":{"position":[[480,7],[815,8]]},"2416":{"position":[[307,9],[368,9]]},"2480":{"position":[[206,8],[884,8],[923,7]]},"2497":{"position":[[186,9]]},"2499":{"position":[[264,9]]},"2501":{"position":[[198,9],[399,9],[752,9]]},"2506":{"position":[[515,9]]},"2508":{"position":[[277,9],[524,9]]},"2512":{"position":[[142,11],[415,9]]},"2516":{"position":[[173,11]]},"2518":{"position":[[322,10]]},"2525":{"position":[[596,9]]},"2529":{"position":[[1153,11],[1173,10],[1304,11],[1325,9],[1349,9]]},"2531":{"position":[[9,9],[105,9],[200,9]]},"2535":{"position":[[17,9],[127,9]]},"2567":{"position":[[636,11],[664,11],[1010,8],[1314,8],[1636,8]]},"2578":{"position":[[695,9]]},"2600":{"position":[[52,8]]},"2602":{"position":[[89,11]]},"2604":{"position":[[10,8]]},"2606":{"position":[[10,8]]},"2608":{"position":[[608,8]]},"2614":{"position":[[352,8]]},"2640":{"position":[[91,8]]},"2647":{"position":[[146,8]]},"2649":{"position":[[409,8],[1332,8]]},"2661":{"position":[[10,8]]},"2668":{"position":[[96,8]]},"2678":{"position":[[10,8]]},"2680":{"position":[[10,8]]},"2692":{"position":[[1595,10]]},"2716":{"position":[[234,7],[274,7],[308,7],[927,9]]},"2720":{"position":[[271,10]]},"2723":{"position":[[108,9]]},"2732":{"position":[[213,9],[262,9],[315,9],[336,9],[355,9],[370,9],[435,9],[453,9],[494,9],[536,9],[556,9],[597,9],[660,9]]},"2743":{"position":[[293,9]]},"2754":{"position":[[299,11]]},"2798":{"position":[[69,9]]},"2892":{"position":[[26,8]]},"2928":{"position":[[122,8]]},"2930":{"position":[[1153,8]]},"2932":{"position":[[146,10]]},"2934":{"position":[[985,8]]},"2940":{"position":[[404,9]]},"2966":{"position":[[653,9]]},"2975":{"position":[[76,8],[509,7],[856,9],[975,9],[1083,9],[1254,8]]},"2987":{"position":[[1343,8]]},"3016":{"position":[[266,11],[868,9]]},"3024":{"position":[[34,10]]},"3044":{"position":[[348,9]]},"3067":{"position":[[4,9]]},"3099":{"position":[[18,9]]},"3119":{"position":[[696,7]]},"3153":{"position":[[492,9]]},"3166":{"position":[[86,9]]},"3168":{"position":[[313,9],[653,9]]},"3172":{"position":[[346,10]]},"3185":{"position":[[610,9]]},"3193":{"position":[[96,9]]},"3204":{"position":[[171,9]]},"3206":{"position":[[443,9]]},"3257":{"position":[[22,8]]},"3290":{"position":[[193,9]]},"3294":{"position":[[367,8],[894,7]]},"3298":{"position":[[13,9],[95,9]]},"3357":{"position":[[987,9]]},"3468":{"position":[[225,10],[974,9],[1337,9]]},"3527":{"position":[[853,7]]},"3529":{"position":[[261,10],[342,8],[1445,10]]},"3533":{"position":[[230,7],[1428,10]]},"3569":{"position":[[763,9]]},"3594":{"position":[[203,7],[965,7]]},"3598":{"position":[[1203,7],[1483,9],[1553,9]]},"3604":{"position":[[442,7]]},"3611":{"position":[[258,9]]},"3634":{"position":[[22,8]]},"3722":{"position":[[36,9]]},"3742":{"position":[[928,10]]},"3744":{"position":[[2155,8],[2777,8]]},"3757":{"position":[[217,9]]},"3763":{"position":[[807,8]]},"3820":{"position":[[121,7]]},"3826":{"position":[[55,9]]},"3829":{"position":[[2356,8],[2981,7]]},"3835":{"position":[[735,7],[1122,8],[1775,8]]},"3853":{"position":[[167,7]]},"3855":{"position":[[198,7]]},"3870":{"position":[[19,7]]},"3923":{"position":[[280,9],[343,10]]},"3925":{"position":[[774,9],[936,9]]},"3964":{"position":[[204,11]]},"4107":{"position":[[164,8]]},"4113":{"position":[[1770,11],[1789,9],[1848,8]]},"4155":{"position":[[219,7]]},"4165":{"position":[[265,8],[318,8]]},"4187":{"position":[[374,8]]},"4215":{"position":[[105,9]]},"4217":{"position":[[209,9]]},"4224":{"position":[[2011,11]]},"4230":{"position":[[988,9],[1177,9],[2822,9],[3025,10],[3274,10],[3314,9],[3970,9],[4111,9],[4850,9],[5371,10]]},"4234":{"position":[[69,9],[91,10]]},"4275":{"position":[[920,9]]},"4281":{"position":[[371,10]]},"4283":{"position":[[629,9]]},"4287":{"position":[[45,9]]},"4289":{"position":[[197,9]]},"4388":{"position":[[197,10]]},"4407":{"position":[[337,9]]},"4410":{"position":[[2,9],[82,9],[247,9]]},"4414":{"position":[[223,9],[537,9]]},"4416":{"position":[[59,9]]},"4418":{"position":[[330,9]]},"4420":{"position":[[2,9],[333,9],[980,9],[1095,9],[1455,9],[1651,9],[1829,9],[2599,9],[2724,9],[2838,9]]},"4422":{"position":[[32,9]]},"4427":{"position":[[494,10]]},"4429":{"position":[[226,9],[339,11]]},"4431":{"position":[[107,8]]},"4442":{"position":[[202,9],[315,11]]},"4444":{"position":[[555,8]]},"4453":{"position":[[202,9],[315,11]]},"4455":{"position":[[555,8]]},"4459":{"position":[[1812,10]]},"4516":{"position":[[126,11],[175,7],[306,10],[678,11]]},"4518":{"position":[[245,11],[304,9],[427,11]]},"4535":{"position":[[49,10],[1465,8]]},"4539":{"position":[[967,7],[1949,10],[2340,10],[3051,8]]},"4541":{"position":[[378,11]]},"4543":{"position":[[239,10]]},"4545":{"position":[[75,9],[181,9]]},"4554":{"position":[[2,9],[82,9],[291,9]]},"4558":{"position":[[183,9],[359,9],[424,9]]},"4560":{"position":[[392,9],[1059,8],[1390,8],[2829,8]]},"4562":{"position":[[53,9],[300,9],[904,9],[1031,9],[1165,8],[1448,9],[2032,9],[2553,9],[3523,9],[4407,9],[5107,9],[5402,9],[7499,9]]},"4564":{"position":[[57,9],[214,9]]},"4566":{"position":[[18,9]]},"4574":{"position":[[246,9],[315,9],[462,9]]},"4667":{"position":[[13570,7],[13719,7]]},"4695":{"position":[[129,7],[285,7],[354,7],[440,7],[489,8],[590,7],[641,7]]},"4707":{"position":[[11,8]]},"4826":{"position":[[2961,9],[3354,9]]},"4839":{"position":[[862,9]]}}}],["container",{"_index":2260,"t":{"374":{"position":[[165,13]]},"924":{"position":[[863,13]]},"1815":{"position":[[863,13]]},"1998":{"position":[[187,13]]},"2499":{"position":[[113,13],[294,13]]},"2506":{"position":[[563,13]]},"2510":{"position":[[473,13]]},"2948":{"position":[[863,13]]},"3569":{"position":[[325,16]]},"4146":{"position":[[1584,16],[1715,16]]},"4230":{"position":[[5296,16]]},"4502":{"position":[[289,16]]},"4516":{"position":[[593,16]]},"4522":{"position":[[544,16]]}}}],["container'",{"_index":6156,"t":{"1437":{"position":[[199,11]]}}}],["container.servic",{"_index":7151,"t":{"1713":{"position":[[515,17],[567,17],[619,17],[1476,17],[1530,17]]}}}],["container_action=restart",{"_index":6369,"t":{"1542":{"position":[[67,24]]}}}],["container_creation.featur",{"_index":9021,"t":{"2732":{"position":[[174,29]]}}}],["container_engin",{"_index":6422,"t":{"1561":{"position":[[289,17],[610,17]]}}}],["container_http_proxi",{"_index":5835,"t":{"1352":{"position":[[245,21]]}}}],["container_https_proxi",{"_index":5836,"t":{"1352":{"position":[[308,22]]}}}],["container_level_testing/featur",{"_index":8920,"t":{"2697":{"position":[[140,33]]}}}],["container_level_testing/features/container_creation_deletion.featur",{"_index":9022,"t":{"2736":{"position":[[65,68]]}}}],["container_level_testing/features/step",{"_index":9023,"t":{"2738":{"position":[[127,40]]}}}],["container_level_testing/features](https://github.com/sovereigncloudstack/sc",{"_index":8904,"t":{"2692":{"position":[[745,77]]}}}],["container_name=nova_comput",{"_index":6368,"t":{"1542":{"position":[[34,27]]}}}],["container_no_proxi",{"_index":5838,"t":{"1352":{"position":[[515,19]]}}}],["containerd",{"_index":2638,"t":{"543":{"position":[[273,11]]},"4514":{"position":[[240,10]]},"4726":{"position":[[439,10]]},"4733":{"position":[[1277,10]]}}}],["containers—identifi",{"_index":8563,"t":{"2503":{"position":[[384,22]]}}}],["contani",{"_index":2488,"t":{"487":{"position":[[401,10]]}}}],["contemporari",{"_index":10232,"t":{"3573":{"position":[[26,12]]}}}],["content",{"_index":650,"t":{"95":{"position":[[301,7],[816,8]]},"117":{"position":[[25,7]]},"139":{"position":[[123,7],[162,7],[202,7],[245,7],[287,7]]},"167":{"position":[[1019,8],[1968,7]]},"207":{"position":[[37,7],[242,7],[269,7],[306,7]]},"249":{"position":[[1624,7]]},"307":{"position":[[174,7]]},"368":{"position":[[5135,7],[6441,7],[6499,7],[7798,7]]},"514":{"position":[[646,7]]},"645":{"position":[[119,7]]},"659":{"position":[[185,7]]},"668":{"position":[[498,7]]},"677":{"position":[[119,7]]},"865":{"position":[[299,8]]},"961":{"position":[[1253,9]]},"1169":{"position":[[203,7]]},"1175":{"position":[[3647,7],[3781,7],[4257,7],[4388,8]]},"1177":{"position":[[100,7],[854,7],[3969,7],[4457,7]]},"1179":{"position":[[1230,8]]},"1218":{"position":[[12,7]]},"1220":{"position":[[52,7]]},"1224":{"position":[[465,7],[624,8]]},"1232":{"position":[[82,7]]},"1301":{"position":[[19,7],[1373,8],[1627,8],[3555,8]]},"1303":{"position":[[2690,7]]},"1383":{"position":[[1282,8]]},"1482":{"position":[[45,7]]},"1495":{"position":[[45,7]]},"1501":{"position":[[1406,7]]},"1766":{"position":[[299,8]]},"1852":{"position":[[1253,9]]},"2065":{"position":[[545,8],[645,7],[726,7]]},"2119":{"position":[[309,8]]},"2207":{"position":[[368,7]]},"2276":{"position":[[8,7],[2655,7]]},"2321":{"position":[[276,8]]},"2341":{"position":[[280,9]]},"2388":{"position":[[276,8]]},"2408":{"position":[[280,9]]},"2626":{"position":[[1128,8]]},"2762":{"position":[[71,8]]},"2766":{"position":[[73,8]]},"2772":{"position":[[69,8]]},"2778":{"position":[[69,8]]},"2784":{"position":[[71,8]]},"2790":{"position":[[71,8]]},"2908":{"position":[[84,8]]},"2910":{"position":[[174,8]]},"2985":{"position":[[1253,9]]},"3088":{"position":[[763,8]]},"3121":{"position":[[1262,8]]},"3206":{"position":[[780,7]]},"3253":{"position":[[79,7]]},"3529":{"position":[[1029,9]]},"3533":{"position":[[615,7]]},"3558":{"position":[[24,8]]},"3573":{"position":[[1223,7]]},"3575":{"position":[[444,7]]},"3731":{"position":[[1515,7]]},"3829":{"position":[[3655,7]]},"3932":{"position":[[831,8]]},"4030":{"position":[[707,7]]},"4420":{"position":[[997,7]]},"4539":{"position":[[1330,9]]},"4562":{"position":[[1263,7],[3298,7],[6125,7],[7255,7]]},"4829":{"position":[[457,7]]}}}],["context",{"_index":680,"t":{"103":{"position":[[199,7]]},"179":{"position":[[1559,7]]},"280":{"position":[[1503,7]]},"288":{"position":[[1161,7]]},"368":{"position":[[3159,7]]},"537":{"position":[[176,7]]},"545":{"position":[[7,7],[256,7],[497,8]]},"834":{"position":[[589,8]]},"1207":{"position":[[213,7]]},"1491":{"position":[[164,9]]},"2321":{"position":[[17,7]]},"2388":{"position":[[17,7]]},"2467":{"position":[[1348,7]]},"2469":{"position":[[21,7]]},"2531":{"position":[[1116,7],[1192,8]]},"2716":{"position":[[1098,7],[1241,7],[1596,7],[2046,7],[2213,7],[2294,7]]},"2728":{"position":[[241,7],[312,7]]},"2756":{"position":[[784,8],[812,8],[840,7],[886,7]]},"2873":{"position":[[241,7]]},"3367":{"position":[[346,7]]},"3378":{"position":[[1035,7]]},"3529":{"position":[[93,7],[1068,8],[1352,7]]},"3571":{"position":[[594,7],[836,7]]},"3956":{"position":[[47,7]]},"4094":{"position":[[49,7]]},"4355":{"position":[[430,8]]},"4433":{"position":[[1220,7],[1686,7]]},"4446":{"position":[[704,7]]},"4457":{"position":[[704,7]]},"4537":{"position":[[1303,7]]},"4547":{"position":[[83,8]]},"4554":{"position":[[350,7]]},"4589":{"position":[[824,7]]},"4593":{"position":[[5677,7]]},"4612":{"position":[[686,7]]},"4740":{"position":[[535,8]]}}}],["context.redir",{"_index":8988,"t":{"2716":{"position":[[1913,17]]}}}],["context.test_nam",{"_index":8986,"t":{"2716":{"position":[[1854,19]]}}}],["contextu",{"_index":955,"t":{"167":{"position":[[105,13]]}}}],["contigu",{"_index":5893,"t":{"1383":{"position":[[401,10]]}}}],["contin",{"_index":9688,"t":{"3050":{"position":[[828,11]]}}}],["conting",{"_index":1572,"t":{"214":{"position":[[239,10]]},"216":{"position":[[80,10]]}}}],["continu",{"_index":622,"t":{"90":{"position":[[54,9]]},"197":{"position":[[1364,9]]},"372":{"position":[[131,10]]},"520":{"position":[[65,10]]},"818":{"position":[[599,8]]},"928":{"position":[[288,10]]},"944":{"position":[[510,8]]},"978":{"position":[[1453,8],[1534,8],[2180,10],[2445,8]]},"1030":{"position":[[707,8]]},"1052":{"position":[[72,8]]},"1480":{"position":[[276,8]]},"1819":{"position":[[288,10]]},"1835":{"position":[[510,8]]},"1869":{"position":[[1453,8],[1534,8],[2180,10],[2445,8]]},"2485":{"position":[[510,10]]},"2489":{"position":[[194,10],[653,10],[718,10],[1017,10]]},"2501":{"position":[[480,10]]},"2503":{"position":[[166,10]]},"2510":{"position":[[290,12],[430,12]]},"2512":{"position":[[1401,10],[1842,12]]},"2520":{"position":[[146,10],[298,10],[683,10]]},"2525":{"position":[[704,10],[870,10]]},"2539":{"position":[[79,10]]},"2551":{"position":[[519,12]]},"2553":{"position":[[216,12]]},"2576":{"position":[[216,9],[316,9]]},"2592":{"position":[[562,12]]},"2655":{"position":[[88,12]]},"2952":{"position":[[288,10]]},"2968":{"position":[[510,8]]},"3002":{"position":[[1453,8],[1534,8],[2180,10],[2445,8]]},"3071":{"position":[[186,8]]},"3148":{"position":[[146,12],[396,12],[936,10]]},"3180":{"position":[[200,12]]},"3218":{"position":[[256,12]]},"3225":{"position":[[1024,11]]},"3248":{"position":[[438,10]]},"3266":{"position":[[588,10]]},"3272":{"position":[[107,8]]},"3276":{"position":[[109,9]]},"3290":{"position":[[478,12]]},"3310":{"position":[[688,8]]},"3321":{"position":[[14,12]]},"3346":{"position":[[911,10]]},"3375":{"position":[[212,10]]},"3384":{"position":[[185,10]]},"3584":{"position":[[359,10]]},"3690":{"position":[[1363,8]]},"3731":{"position":[[341,10],[684,12]]},"3777":{"position":[[1464,8]]},"3866":{"position":[[353,10]]},"4100":{"position":[[755,10]]},"4253":{"position":[[376,12]]},"4283":{"position":[[958,8]]},"4410":{"position":[[145,10]]},"4554":{"position":[[145,10]]}}}],["contract",{"_index":10875,"t":{"3835":{"position":[[2023,10]]},"4587":{"position":[[513,10]]},"4733":{"position":[[554,8]]}}}],["contractor",{"_index":9863,"t":{"3214":{"position":[[51,11],[178,11]]}}}],["contrast",{"_index":2610,"t":{"530":{"position":[[2046,9]]},"2351":{"position":[[702,9]]},"2418":{"position":[[702,9]]},"3978":{"position":[[139,8]]},"4124":{"position":[[2414,8]]},"4146":{"position":[[2042,9]]},"4744":{"position":[[791,8]]},"4767":{"position":[[229,8]]}}}],["contrib/update.pi",{"_index":3467,"t":{"887":{"position":[[7,17],[1625,17]]},"1811":{"position":[[7,17],[1625,17]]}}}],["contrib/x",{"_index":8668,"t":{"2600":{"position":[[363,9]]}}}],["contribut",{"_index":37,"t":{"7":{"position":[[200,10]]},"74":{"position":[[165,13]]},"113":{"position":[[26,10]]},"169":{"position":[[656,13],[802,10]]},"173":{"position":[[1299,13],[1417,13],[1593,11]]},"179":{"position":[[920,11],[994,11],[1712,10]]},"181":{"position":[[915,11],[1803,10]]},"183":{"position":[[116,13]]},"190":{"position":[[289,10]]},"194":{"position":[[223,10]]},"197":{"position":[[1931,13]]},"249":{"position":[[163,12],[218,12],[272,12],[421,12],[805,12],[978,12],[1027,12],[1242,13]]},"266":{"position":[[111,10],[275,10]]},"275":{"position":[[327,10]]},"280":{"position":[[1130,10]]},"345":{"position":[[255,13]]},"854":{"position":[[711,11]]},"1661":{"position":[[486,12]]},"2023":{"position":[[442,14]]},"2489":{"position":[[1212,10]]},"2751":{"position":[[0,13]]},"2865":{"position":[[0,13]]},"2936":{"position":[[192,10]]},"3014":{"position":[[210,11]]},"3050":{"position":[[472,10]]},"3110":{"position":[[14,12]]},"3142":{"position":[[14,12],[164,10]]},"3144":{"position":[[544,10]]},"3174":{"position":[[14,12],[164,10]]},"3176":{"position":[[500,10]]},"3189":{"position":[[227,11]]},"3212":{"position":[[14,12],[164,10]]},"3214":{"position":[[393,10]]},"3234":{"position":[[170,10]]},"3238":{"position":[[727,10]]},"3244":{"position":[[315,13]]},"3251":{"position":[[131,11]]},"3270":{"position":[[14,12],[164,10]]},"3276":{"position":[[628,13]]},"3298":{"position":[[482,11]]},"3313":{"position":[[427,11]]},"3319":{"position":[[14,12],[164,10]]},"3323":{"position":[[10,12],[546,14]]},"3340":{"position":[[14,12],[164,10]]},"3563":{"position":[[53,12]]},"3571":{"position":[[1633,11],[1711,10]]},"3627":{"position":[[181,10],[276,14]]},"3629":{"position":[[352,12]]},"3968":{"position":[[311,10],[2111,13],[2604,12]]},"3973":{"position":[[507,13]]},"4224":{"position":[[1535,10]]},"4310":{"position":[[1302,10]]},"4560":{"position":[[1488,12],[2280,11],[2927,12],[3523,11],[3733,12],[3794,12]]},"4562":{"position":[[4281,14]]},"4593":{"position":[[381,13],[3255,13]]},"4623":{"position":[[259,11],[494,13]]},"4632":{"position":[[505,12],[710,12]]},"4656":{"position":[[68,10],[909,12]]},"4837":{"position":[[0,13]]}}}],["contribute.md",{"_index":10227,"t":{"3571":{"position":[[361,13]]}}}],["contributor",{"_index":1238,"t":{"179":{"position":[[829,12]]},"181":{"position":[[859,11],[1359,12]]},"183":{"position":[[245,12]]},"185":{"position":[[433,11]]},"197":{"position":[[99,13],[707,12],[1975,12]]},"199":{"position":[[3281,11]]},"249":{"position":[[67,12],[1678,12]]},"251":{"position":[[103,11]]},"275":{"position":[[15,11],[67,12]]},"277":{"position":[[40,11]]},"345":{"position":[[273,11]]},"347":{"position":[[19,11]]},"3110":{"position":[[157,11],[254,12]]},"3144":{"position":[[38,12],[314,13]]},"3176":{"position":[[38,12],[106,12]]},"3346":{"position":[[641,12]]},"3627":{"position":[[50,11],[137,12]]},"3971":{"position":[[68,12]]},"4504":{"position":[[157,13]]},"4506":{"position":[[1317,13]]},"4560":{"position":[[1986,13],[3198,12],[3348,13],[3679,12],[4571,13],[5108,14]]}}}],["contributor'",{"_index":9775,"t":{"3144":{"position":[[144,13]]}}}],["control",{"_index":109,"t":{"12":{"position":[[286,7]]},"15":{"position":[[284,7]]},"173":{"position":[[1032,7]]},"255":{"position":[[288,7]]},"378":{"position":[[829,10]]},"382":{"position":[[148,8],[622,10]]},"417":{"position":[[48,11],[150,10],[347,11],[452,10],[1359,10],[1430,11],[2036,11],[2073,10]]},"423":{"position":[[366,10]]},"461":{"position":[[239,10]]},"463":{"position":[[740,10],[977,10],[1151,10]]},"475":{"position":[[424,10]]},"485":{"position":[[4,10],[160,10],[329,10]]},"487":{"position":[[329,10],[419,10]]},"489":{"position":[[1083,10]]},"493":{"position":[[37,10]]},"514":{"position":[[67,10]]},"518":{"position":[[91,7]]},"541":{"position":[[708,10],[758,7],[813,7],[985,7],[1438,12]]},"557":{"position":[[314,7],[492,7],[2021,7],[6699,7],[6880,7]]},"590":{"position":[[659,10],[1443,10]]},"692":{"position":[[100,10],[261,10],[361,10]]},"699":{"position":[[268,10],[359,10]]},"741":{"position":[[212,10],[287,11],[842,10],[913,10]]},"745":{"position":[[91,10]]},"747":{"position":[[19,10],[180,10],[280,10]]},"812":{"position":[[89,7],[164,7]]},"814":{"position":[[70,10],[97,7]]},"818":{"position":[[455,11],[627,10],[670,11],[813,7]]},"820":{"position":[[20,7],[176,7],[278,10]]},"822":{"position":[[4,7],[287,10],[394,10]]},"832":{"position":[[123,10]]},"844":{"position":[[345,10]]},"961":{"position":[[1572,10]]},"967":{"position":[[592,8]]},"1016":{"position":[[14,7]]},"1018":{"position":[[85,7]]},"1022":{"position":[[0,7]]},"1028":{"position":[[2,7],[337,7]]},"1036":{"position":[[51,7]]},"1038":{"position":[[86,7],[100,7]]},"1040":{"position":[[26,7],[159,7]]},"1042":{"position":[[329,7]]},"1056":{"position":[[793,7],[1622,12]]},"1064":{"position":[[899,7],[1764,7]]},"1067":{"position":[[2234,7]]},"1105":{"position":[[2,7],[242,7],[343,7],[471,7]]},"1169":{"position":[[2070,7],[2130,7]]},"1226":{"position":[[3332,7],[3386,12],[3474,9],[3824,7],[3878,11],[3958,8],[4164,7]]},"1259":{"position":[[205,7]]},"1263":{"position":[[247,7]]},"1387":{"position":[[155,10]]},"1433":{"position":[[341,7],[582,7],[615,7],[648,7],[715,7]]},"1462":{"position":[[59,7],[389,7]]},"1466":{"position":[[1757,10],[2610,7]]},"1472":{"position":[[2660,8],[2856,8]]},"1484":{"position":[[155,10]]},"1507":{"position":[[198,7]]},"1529":{"position":[[150,7],[183,7],[216,7],[283,7]]},"1552":{"position":[[55,7],[494,7]]},"1555":{"position":[[380,7]]},"1561":{"position":[[147,7]]},"1671":{"position":[[118,7],[240,8]]},"1679":{"position":[[625,7]]},"1694":{"position":[[6349,10]]},"1713":{"position":[[2110,10],[2153,10]]},"1745":{"position":[[200,7]]},"1852":{"position":[[1572,10]]},"1858":{"position":[[592,8]]},"1979":{"position":[[155,10]]},"2013":{"position":[[23,10]]},"2021":{"position":[[0,11],[63,11]]},"2025":{"position":[[377,10]]},"2132":{"position":[[344,7]]},"2148":{"position":[[155,10]]},"2163":{"position":[[4227,7]]},"2196":{"position":[[818,10]]},"2480":{"position":[[470,8]]},"2508":{"position":[[630,8]]},"2529":{"position":[[124,10],[505,7]]},"2531":{"position":[[1014,11]]},"2537":{"position":[[360,9]]},"2539":{"position":[[354,11]]},"2574":{"position":[[724,8]]},"2578":{"position":[[475,12]]},"2584":{"position":[[1060,10]]},"2586":{"position":[[670,10]]},"2608":{"position":[[572,7],[946,7]]},"2612":{"position":[[247,7]]},"2614":{"position":[[32,7],[119,7],[447,7],[526,7],[779,7]]},"2634":{"position":[[84,10]]},"2644":{"position":[[362,7]]},"2655":{"position":[[648,7]]},"2672":{"position":[[362,7]]},"2725":{"position":[[820,11]]},"2730":{"position":[[93,11]]},"2889":{"position":[[663,11]]},"2985":{"position":[[1572,10]]},"2991":{"position":[[592,8]]},"3083":{"position":[[484,10]]},"3101":{"position":[[238,11]]},"3134":{"position":[[114,7]]},"3153":{"position":[[1245,11],[1613,11]]},"3185":{"position":[[1027,8]]},"3230":{"position":[[57,7]]},"3266":{"position":[[388,7]]},"3296":{"position":[[964,7],[1018,7],[1175,7]]},"3315":{"position":[[153,7]]},"3352":{"position":[[1464,7]]},"3925":{"position":[[1020,7],[1108,7],[1591,7]]},"3928":{"position":[[66,7],[163,7],[274,7],[375,7],[514,7],[604,7],[1288,7]]},"3930":{"position":[[148,7]]},"3947":{"position":[[175,7]]},"3960":{"position":[[457,7]]},"3964":{"position":[[178,7],[330,7]]},"3968":{"position":[[766,7],[1495,7]]},"3980":{"position":[[219,7],[297,8]]},"3998":{"position":[[160,7]]},"4026":{"position":[[163,7]]},"4075":{"position":[[374,7]]},"4146":{"position":[[2073,7]]},"4220":{"position":[[194,8]]},"4224":{"position":[[712,7]]},"4226":{"position":[[1311,10],[1555,7],[1750,7],[3797,7]]},"4230":{"position":[[1293,10]]},"4234":{"position":[[335,10]]},"4240":{"position":[[329,7]]},"4289":{"position":[[50,7]]},"4300":{"position":[[551,7]]},"4304":{"position":[[191,7],[323,7],[358,7],[511,11],[1660,7]]},"4331":{"position":[[213,10]]},"4410":{"position":[[424,7]]},"4420":{"position":[[823,7],[855,8],[1943,7]]},"4427":{"position":[[138,7],[186,7],[350,7],[556,7]]},"4429":{"position":[[165,7]]},"4431":{"position":[[33,7],[2334,7],[2437,7]]},"4433":{"position":[[68,7],[177,7],[356,7],[563,7],[759,7],[942,7],[1244,7],[1418,7],[1872,7],[1994,7],[2175,7],[2319,7]]},"4435":{"position":[[158,7],[450,7],[674,7]]},"4440":{"position":[[129,7],[177,7],[342,7],[541,10]]},"4442":{"position":[[141,7]]},"4444":{"position":[[516,7]]},"4448":{"position":[[446,7],[617,7]]},"4451":{"position":[[129,7],[177,7],[342,7],[541,10]]},"4453":{"position":[[141,7]]},"4455":{"position":[[516,7]]},"4459":{"position":[[172,7],[343,7],[1522,11],[2101,11]]},"4464":{"position":[[22,7]]},"4479":{"position":[[872,8],[1047,7],[1075,11],[1161,11],[1396,11],[1793,8],[1807,7],[2144,7],[2232,8],[2374,7]]},"4485":{"position":[[93,10],[2132,10]]},"4489":{"position":[[529,11]]},"4497":{"position":[[5,7]]},"4527":{"position":[[114,7],[145,7]]},"4529":{"position":[[663,7]]},"4535":{"position":[[2808,7],[4274,7]]},"4537":{"position":[[903,7],[1094,7],[1205,10],[1458,7]]},"4539":{"position":[[147,7],[193,7],[1249,7],[2580,11],[5241,8],[5514,8],[6554,12],[6577,11],[6879,12],[6956,10],[6990,11],[7318,11],[7515,10]]},"4543":{"position":[[1114,11],[1224,10],[1382,7],[1426,7]]},"4547":{"position":[[861,7],[978,7],[2737,8],[3392,10],[3797,10],[3949,10]]},"4551":{"position":[[80,11]]},"4562":{"position":[[3350,9]]},"4580":{"position":[[2893,10],[3003,11],[3206,11],[3432,11],[3524,10],[3590,11]]},"4582":{"position":[[425,10],[481,11]]},"4632":{"position":[[2919,7]]},"4634":{"position":[[43,7]]},"4660":{"position":[[225,8]]},"4726":{"position":[[307,7],[412,7],[571,10]]},"4733":{"position":[[314,7],[681,7],[950,7],[1124,10],[1250,7]]},"4879":{"position":[[41,11]]}}}],["control1",{"_index":11729,"t":{"4606":{"position":[[108,8]]}}}],["controller.allowsnippetannotations=tru",{"_index":12003,"t":{"4879":{"position":[[432,39]]}}}],["controller.config.hsts=fals",{"_index":12004,"t":{"4879":{"position":[[478,28]]}}}],["controller:23.6.1.20230919",{"_index":7131,"t":{"1711":{"position":[[2281,26]]}}}],["controller_flavor",{"_index":2689,"t":{"555":{"position":[[315,17]]},"557":{"position":[[229,17]]},"588":{"position":[[1156,17]]}}}],["controller_root_disk",{"_index":2711,"t":{"557":{"position":[[434,20]]}}}],["controller_server_group_id",{"_index":2745,"t":{"557":{"position":[[1914,26]]}}}],["controllermanager.manager.source=oci",{"_index":2452,"t":{"475":{"position":[[836,36]]}}}],["controllerplugin",{"_index":2943,"t":{"590":{"position":[[1081,16]]}}}],["controller’",{"_index":2524,"t":{"496":{"position":[[33,12]]},"498":{"position":[[30,12]]}}}],["controlplan",{"_index":2698,"t":{"555":{"position":[[494,13]]},"588":{"position":[[1307,13]]},"4728":{"position":[[1598,13]]}}}],["controlplaneavailabilityzon",{"_index":2830,"t":{"557":{"position":[[6585,29],[6630,29]]}}}],["controlplaneomitavailabilityzon",{"_index":2832,"t":{"557":{"position":[[6748,32],[6794,32]]}}}],["conveni",{"_index":2911,"t":{"588":{"position":[[1579,10]]},"696":{"position":[[1663,10]]},"728":{"position":[[1184,10]]},"732":{"position":[[519,10]]},"934":{"position":[[1517,12]]},"940":{"position":[[1665,10]]},"1825":{"position":[[1517,12]]},"1831":{"position":[[1665,10]]},"2958":{"position":[[1517,12]]},"2964":{"position":[[1665,10]]},"3026":{"position":[[26,12]]},"3073":{"position":[[1036,12]]},"3294":{"position":[[690,10]]},"3820":{"position":[[68,12]]}}}],["convent",{"_index":2180,"t":{"368":{"position":[[894,10],[5331,10],[5432,10]]},"2439":{"position":[[626,11]]},"3410":{"position":[[189,12]]},"3945":{"position":[[70,11]]},"4639":{"position":[[16,10]]}}}],["converg",{"_index":3311,"t":{"824":{"position":[[307,9]]},"1020":{"position":[[6,9]]}}}],["convers",{"_index":1635,"t":{"226":{"position":[[52,14]]},"2360":{"position":[[1318,10]]},"2427":{"position":[[1318,10]]},"3761":{"position":[[1285,10]]},"4017":{"position":[[367,11]]},"4146":{"position":[[1247,11]]},"4793":{"position":[[517,10]]}}}],["conversion_format",{"_index":3367,"t":{"861":{"position":[[1179,17]]},"1762":{"position":[[1179,17]]}}}],["convert",{"_index":3364,"t":{"861":{"position":[[318,7]]},"1175":{"position":[[5088,7]]},"1385":{"position":[[2412,7]]},"1762":{"position":[[318,7]]},"2236":{"position":[[120,9],[443,9]]},"2238":{"position":[[292,9]]},"2242":{"position":[[556,9]]},"2244":{"position":[[51,9]]},"2246":{"position":[[9,7],[202,7],[324,8]]},"2248":{"position":[[97,10]]},"2274":{"position":[[101,10]]},"2343":{"position":[[1295,10]]},"2360":{"position":[[146,8],[1206,7],[1702,10]]},"2410":{"position":[[1295,10]]},"2427":{"position":[[146,8],[1206,7],[1702,10]]},"3761":{"position":[[1102,8]]}}}],["convey",{"_index":1872,"t":{"286":{"position":[[48,6]]},"530":{"position":[[1343,8]]}}}],["cooki",{"_index":6810,"t":{"1694":{"position":[[3447,6]]},"2196":{"position":[[1423,8],[1523,7]]}}}],["cookie_secur",{"_index":4036,"t":{"963":{"position":[[1092,13]]},"1854":{"position":[[1092,13]]},"2987":{"position":[[1092,13]]}}}],["cookiecutt",{"_index":5013,"t":{"1218":{"position":[[77,13],[91,12]]},"1220":{"position":[[77,12],[451,12],[932,13]]},"1222":{"position":[[133,12],[217,12]]},"1226":{"position":[[64,12],[1064,13],[2683,13]]},"1230":{"position":[[1003,12],[1169,12]]},"1305":{"position":[[330,12]]},"1501":{"position":[[109,12],[140,12]]},"1519":{"position":[[238,12]]},"2173":{"position":[[249,12]]}}}],["cool",{"_index":11232,"t":{"4159":{"position":[[1397,7]]},"4161":{"position":[[679,7],[870,7]]},"4163":{"position":[[2313,8],[3816,8]]},"4167":{"position":[[775,7]]}}}],["cooper",{"_index":1115,"t":{"173":{"position":[[525,11]]},"4420":{"position":[[2474,9]]}}}],["coordin",{"_index":519,"t":{"72":{"position":[[70,10]]},"1468":{"position":[[366,11]]},"4109":{"position":[[5091,11]]}}}],["cope",{"_index":11838,"t":{"4742":{"position":[[621,4]]}}}],["copi",{"_index":651,"t":{"95":{"position":[[312,5],[442,6],[545,4],[722,4]]},"151":{"position":[[401,4]]},"167":{"position":[[1365,4],[1958,4]]},"368":{"position":[[468,6]]},"489":{"position":[[1341,4]]},"491":{"position":[[280,4]]},"510":{"position":[[67,6]]},"514":{"position":[[427,4]]},"887":{"position":[[909,4]]},"936":{"position":[[317,4]]},"978":{"position":[[1878,4]]},"1173":{"position":[[354,4],[695,6],[730,4]]},"1248":{"position":[[1242,6]]},"1303":{"position":[[137,7],[225,7],[282,7],[2635,7],[2679,6],[3738,7],[3979,6]]},"1324":{"position":[[660,6]]},"1503":{"position":[[1581,4],[2358,4]]},"1517":{"position":[[199,4]]},"1523":{"position":[[970,4]]},"1525":{"position":[[1101,4]]},"1694":{"position":[[2987,4],[3128,4],[3560,7],[3699,7],[4364,7],[4487,4],[4507,4],[4523,7],[4640,4],[4660,4],[4676,7],[4801,4],[4821,4],[4837,7]]},"1811":{"position":[[909,4]]},"1827":{"position":[[317,4]]},"1869":{"position":[[1878,4]]},"2037":{"position":[[0,4]]},"2057":{"position":[[367,4]]},"2059":{"position":[[0,4]]},"2086":{"position":[[402,4]]},"2171":{"position":[[1092,4]]},"2207":{"position":[[433,4]]},"2242":{"position":[[197,4],[515,4]]},"2244":{"position":[[12,4],[179,7],[248,6]]},"2252":{"position":[[42,6]]},"2319":{"position":[[453,4]]},"2327":{"position":[[758,4]]},"2329":{"position":[[378,4]]},"2335":{"position":[[307,6]]},"2337":{"position":[[57,6],[360,4]]},"2339":{"position":[[1188,4]]},"2347":{"position":[[207,5]]},"2358":{"position":[[425,6],[463,5]]},"2386":{"position":[[453,4]]},"2394":{"position":[[758,4]]},"2396":{"position":[[378,4]]},"2402":{"position":[[307,6]]},"2404":{"position":[[57,6],[360,4]]},"2406":{"position":[[1188,4]]},"2414":{"position":[[207,5]]},"2425":{"position":[[425,6],[463,5]]},"2431":{"position":[[835,4],[1140,4],[1458,4],[2552,4]]},"2859":{"position":[[89,4]]},"2908":{"position":[[0,4]]},"2910":{"position":[[0,4]]},"2934":{"position":[[521,4]]},"2960":{"position":[[317,4]]},"3002":{"position":[[1878,4]]},"3381":{"position":[[2239,4]]},"3984":{"position":[[1484,7]]},"4102":{"position":[[1072,4]]},"4113":{"position":[[785,4]]},"4124":{"position":[[1033,7]]},"4281":{"position":[[416,6],[1059,4]]},"4291":{"position":[[1897,7]]},"4667":{"position":[[695,6]]},"4831":{"position":[[92,4]]},"4833":{"position":[[576,4]]}}}],["copy&past",{"_index":688,"t":{"107":{"position":[[145,10]]},"3571":{"position":[[1363,10]]}}}],["copydocscommand",{"_index":1007,"t":{"167":{"position":[[1994,15]]}}}],["copyleft",{"_index":1054,"t":{"171":{"position":[[70,8],[448,8],[1320,8]]},"173":{"position":[[2343,8]]},"177":{"position":[[742,8],[782,8],[1064,8],[1110,8],[1255,8],[1390,10],[1436,10]]},"181":{"position":[[2407,8],[2498,8],[2704,8]]},"249":{"position":[[1595,10]]}}}],["copyright",{"_index":1196,"t":{"177":{"position":[[92,9],[340,9],[516,9],[1349,9]]},"181":{"position":[[38,9],[172,9],[263,10],[339,9],[405,9],[461,9],[670,9],[731,9],[1136,9],[1372,9],[1415,10],[1482,10],[1607,9]]}}}],["cor",{"_index":8999,"t":{"2720":{"position":[[723,4],[778,4],[806,5],[874,4],[911,4]]},"2822":{"position":[[91,4]]}}}],["core",{"_index":1357,"t":{"187":{"position":[[949,4]]},"194":{"position":[[51,5]]},"197":{"position":[[483,4]]},"280":{"position":[[1234,4]]},"337":{"position":[[398,4]]},"376":{"position":[[133,4]]},"401":{"position":[[92,4],[722,4]]},"421":{"position":[[671,4]]},"423":{"position":[[301,4],[1119,4]]},"425":{"position":[[203,4]]},"537":{"position":[[244,4]]},"541":{"position":[[19,4]]},"755":{"position":[[620,4],[936,4]]},"824":{"position":[[474,4]]},"830":{"position":[[26,4]]},"842":{"position":[[57,4]]},"894":{"position":[[2282,6]]},"914":{"position":[[2476,9],[3783,9],[5124,9]]},"1040":{"position":[[448,5],[712,4]]},"1042":{"position":[[751,4]]},"1105":{"position":[[794,5],[833,5]]},"1113":{"position":[[556,5]]},"1189":{"position":[[271,5]]},"1369":{"position":[[48,5]]},"1371":{"position":[[150,5]]},"1373":{"position":[[92,5],[292,5],[674,5]]},"1375":{"position":[[33,5],[608,5],[696,4]]},"1377":{"position":[[38,5],[79,5],[263,5],[288,6],[429,6]]},"1379":{"position":[[80,6],[232,5],[397,5]]},"1381":{"position":[[133,5]]},"1383":{"position":[[235,5],[581,6],[725,5]]},"1752":{"position":[[2282,6]]},"1798":{"position":[[2476,9],[3783,9],[5124,9]]},"2027":{"position":[[139,5]]},"2376":{"position":[[123,4]]},"2618":{"position":[[940,4]]},"2692":{"position":[[1016,6]]},"2914":{"position":[[588,4],[818,4],[1209,4]]},"3223":{"position":[[273,5],[960,4]]},"3279":{"position":[[391,4]]},"3390":{"position":[[173,4]]},"3661":{"position":[[27,4],[236,4],[327,4],[982,4],[1630,4]]},"3671":{"position":[[820,4],[841,4],[863,4]]},"3675":{"position":[[42,5],[422,5]]},"3679":{"position":[[512,5]]},"3698":{"position":[[119,4],[328,4],[419,4],[1120,4],[1668,4],[2284,4]]},"3704":{"position":[[451,5]]},"3712":{"position":[[1293,4],[1352,5],[1636,5],[1737,5],[1829,4],[1850,4],[1872,4],[2111,4]]},"3720":{"position":[[42,5],[425,5]]},"3744":{"position":[[329,5],[385,5],[404,7],[437,5],[712,5],[731,6],[772,5],[1341,5],[1360,5],[1399,5],[1640,5],[1659,5],[1707,5],[2503,5],[2768,4]]},"3785":{"position":[[119,4],[328,4],[419,4],[1120,4],[1982,4]]},"3793":{"position":[[515,5]]},"3805":{"position":[[927,4],[948,4],[970,4],[1214,4]]},"3813":{"position":[[42,5],[422,5]]},"3894":{"position":[[293,4],[327,4],[432,4],[524,4],[569,4]]},"3898":{"position":[[86,4],[111,4],[137,4],[169,4],[204,4],[230,4],[255,4],[284,4],[316,4],[342,4],[371,4],[397,4],[423,4],[450,4],[477,4]]},"3900":{"position":[[89,4],[126,4],[164,4],[204,4],[242,4],[278,4],[315,4],[353,4],[395,4],[434,4],[472,4],[512,4],[551,4]]},"3902":{"position":[[370,4],[386,5]]},"3968":{"position":[[2128,4]]},"3973":{"position":[[524,4]]},"4146":{"position":[[1745,4]]},"4159":{"position":[[1409,4]]},"4161":{"position":[[663,4],[797,4]]},"4167":{"position":[[728,4]]},"4178":{"position":[[536,4]]},"4340":{"position":[[886,4]]},"4351":{"position":[[623,4]]},"4560":{"position":[[928,4],[2456,4],[5259,4],[5373,4]]},"4826":{"position":[[18,4]]}}}],["coredn",{"_index":2927,"t":{"590":{"position":[[414,7],[470,7]]}}}],["corner",{"_index":2368,"t":{"434":{"position":[[1520,6]]},"512":{"position":[[80,6],[995,6]]},"963":{"position":[[3109,8]]},"1854":{"position":[[3109,8]]},"2987":{"position":[[3109,8]]}}}],["cornerston",{"_index":1371,"t":{"190":{"position":[[255,11]]}}}],["corpor",{"_index":1291,"t":{"181":{"position":[[1965,9]]}}}],["corpu",{"_index":10196,"t":{"3533":{"position":[[3019,6]]},"3541":{"position":[[44,6]]}}}],["correct",{"_index":1113,"t":{"173":{"position":[[469,7],[665,7]]},"197":{"position":[[1680,7]]},"368":{"position":[[4026,7]]},"440":{"position":[[469,7]]},"442":{"position":[[66,7]]},"446":{"position":[[376,7]]},"487":{"position":[[143,7]]},"1173":{"position":[[369,7]]},"1244":{"position":[[691,7]]},"1297":{"position":[[1492,7]]},"1391":{"position":[[945,7]]},"1523":{"position":[[2157,7]]},"1525":{"position":[[2306,7]]},"1694":{"position":[[3296,7]]},"1718":{"position":[[119,9]]},"1906":{"position":[[219,7]]},"1988":{"position":[[28,7]]},"2130":{"position":[[49,8]]},"2199":{"position":[[843,7]]},"2231":{"position":[[1058,7]]},"2355":{"position":[[579,7]]},"2422":{"position":[[579,7]]},"2433":{"position":[[336,7]]},"2478":{"position":[[2652,7]]},"2512":{"position":[[554,7]]},"3906":{"position":[[247,8]]},"3918":{"position":[[792,7]]},"3928":{"position":[[3660,7]]},"4109":{"position":[[2859,7]]},"4178":{"position":[[313,7]]},"4180":{"position":[[242,7]]},"4535":{"position":[[3071,7]]},"4539":{"position":[[641,7]]},"4667":{"position":[[370,7]]},"4701":{"position":[[359,7]]},"4733":{"position":[[368,7]]}}}],["correctli",{"_index":2623,"t":{"541":{"position":[[95,9]]},"1067":{"position":[[1763,9]]},"1324":{"position":[[6629,9],[6890,9]]},"1552":{"position":[[523,10]]},"1986":{"position":[[197,10]]},"2037":{"position":[[973,9]]},"2353":{"position":[[904,9]]},"2420":{"position":[[904,9]]},"2567":{"position":[[328,9],[914,9]]},"2728":{"position":[[63,9]]},"2743":{"position":[[67,9]]},"2756":{"position":[[897,9]]},"3984":{"position":[[278,9],[365,9],[1678,9]]},"4068":{"position":[[47,9]]},"4120":{"position":[[200,9]]},"4226":{"position":[[3987,9]]},"4230":{"position":[[3404,9],[4188,10],[4829,9]]},"4491":{"position":[[56,9]]},"4535":{"position":[[1052,10]]},"4539":{"position":[[5064,10],[7481,10]]},"4667":{"position":[[6623,9],[6884,9]]},"4730":{"position":[[1728,9]]}}}],["correl",{"_index":9180,"t":{"2814":{"position":[[679,9]]}}}],["correspond",{"_index":2662,"t":{"549":{"position":[[1323,13]]},"967":{"position":[[806,11]]},"1028":{"position":[[105,13]]},"1171":{"position":[[647,13]]},"1236":{"position":[[326,13]]},"1383":{"position":[[1825,13]]},"1858":{"position":[[806,11]]},"2059":{"position":[[890,13],[2601,13]]},"2211":{"position":[[1933,13],[1996,13],[2098,13],[2211,13]]},"2325":{"position":[[668,13]]},"2327":{"position":[[406,13],[594,13]]},"2329":{"position":[[364,13]]},"2331":{"position":[[58,13]]},"2337":{"position":[[207,13]]},"2341":{"position":[[348,13]]},"2343":{"position":[[75,13],[267,13],[901,13]]},"2351":{"position":[[134,13]]},"2355":{"position":[[2122,13]]},"2372":{"position":[[238,13]]},"2392":{"position":[[668,13]]},"2394":{"position":[[406,13],[594,13]]},"2396":{"position":[[364,13]]},"2398":{"position":[[58,13]]},"2404":{"position":[[207,13]]},"2408":{"position":[[348,13]]},"2410":{"position":[[75,13],[267,13],[901,13]]},"2418":{"position":[[134,13]]},"2422":{"position":[[2122,13]]},"2443":{"position":[[850,13]]},"2451":{"position":[[594,13]]},"2626":{"position":[[602,13]]},"2740":{"position":[[415,13],[656,13]]},"2991":{"position":[[806,11]]},"3050":{"position":[[856,13]]},"3083":{"position":[[144,13]]},"3101":{"position":[[394,13]]},"3116":{"position":[[135,13]]},"3159":{"position":[[477,13]]},"3234":{"position":[[230,13]]},"3361":{"position":[[622,11]]},"3365":{"position":[[294,13]]},"3371":{"position":[[294,13]]},"3386":{"position":[[447,11]]},"3537":{"position":[[221,13]]},"3592":{"position":[[1293,13]]},"3596":{"position":[[91,13],[156,13]]},"3608":{"position":[[462,13],[644,13]]},"3636":{"position":[[221,13]]},"3712":{"position":[[221,13]]},"3722":{"position":[[1005,13]]},"3731":{"position":[[2160,13]]},"3744":{"position":[[689,11],[2742,11]]},"3815":{"position":[[1003,13]]},"3881":{"position":[[335,13]]},"3894":{"position":[[437,11],[822,11],[1067,13]]},"3902":{"position":[[104,13]]},"4007":{"position":[[281,13]]},"4032":{"position":[[0,13]]},"4060":{"position":[[482,13]]},"4109":{"position":[[224,13]]},"4165":{"position":[[640,13]]},"4185":{"position":[[142,13]]},"4200":{"position":[[40,13]]},"4202":{"position":[[108,13],[156,13]]},"4204":{"position":[[102,13],[191,13]]},"4291":{"position":[[2411,13]]},"4302":{"position":[[331,13]]},"4306":{"position":[[537,13]]},"4313":{"position":[[852,13]]},"4327":{"position":[[628,13],[903,13]]},"4459":{"position":[[1088,11],[1564,11]]},"4610":{"position":[[431,13],[559,13]]},"4629":{"position":[[124,13]]},"4826":{"position":[[349,13]]}}}],["correspondingnod",{"_index":4699,"t":{"1177":{"position":[[886,18],[4489,18]]}}}],["corrupt",{"_index":1309,"t":{"181":{"position":[[2664,7]]},"1578":{"position":[[238,10]]},"1921":{"position":[[238,10]]},"2242":{"position":[[116,9]]},"4483":{"position":[[353,9]]}}}],["cortex",{"_index":10379,"t":{"3671":{"position":[[318,6]]},"3712":{"position":[[630,6]]},"3805":{"position":[[409,6]]}}}],["cosign",{"_index":11669,"t":{"4562":{"position":[[3317,7],[6156,6],[6165,6]]}}}],["cosmo",{"_index":2345,"t":{"427":{"position":[[16,6]]}}}],["cost",{"_index":4368,"t":{"1030":{"position":[[667,4]]},"1061":{"position":[[784,4],[842,5]]},"1455":{"position":[[1185,4],[1316,4]]},"3047":{"position":[[313,6]]},"3835":{"position":[[85,4]]},"4385":{"position":[[453,4]]},"4446":{"position":[[381,5]]},"4457":{"position":[[381,5]]},"4504":{"position":[[621,5]]},"4506":{"position":[[1089,4],[1149,5]]},"4508":{"position":[[897,4]]},"4514":{"position":[[119,4]]},"4522":{"position":[[509,4]]},"4795":{"position":[[147,6]]}}}],["couldn't",{"_index":11533,"t":{"4448":{"position":[[245,8]]}}}],["count",{"_index":3870,"t":{"940":{"position":[[337,5]]},"1694":{"position":[[7199,5]]},"1831":{"position":[[337,5]]},"2964":{"position":[[337,5]]},"3673":{"position":[[995,5]]},"3714":{"position":[[1027,5]]},"3722":{"position":[[947,5]]},"3807":{"position":[[649,5]]},"3815":{"position":[[945,5]]},"3990":{"position":[[996,5]]},"4124":{"position":[[617,5]]},"4612":{"position":[[915,5]]}}}],["count=1",{"_index":8270,"t":{"2266":{"position":[[276,7]]}}}],["count=32",{"_index":6702,"t":{"1665":{"position":[[1060,8]]}}}],["counter",{"_index":1479,"t":{"199":{"position":[[1780,7]]},"2649":{"position":[[702,8]]},"2720":{"position":[[479,7]]},"4730":{"position":[[1707,8]]}}}],["counterpart",{"_index":8085,"t":{"2234":{"position":[[809,12]]}}}],["countri",{"_index":1230,"t":{"179":{"position":[[494,10]]}}}],["coupl",{"_index":1985,"t":{"305":{"position":[[299,7]]},"944":{"position":[[680,6]]},"1835":{"position":[[680,6]]},"2968":{"position":[[680,6]]},"3321":{"position":[[515,9]]},"3355":{"position":[[452,7]]},"4433":{"position":[[841,9]]},"4446":{"position":[[1337,7]]},"4457":{"position":[[1337,7]]}}}],["cours",{"_index":2310,"t":{"413":{"position":[[190,6]]},"618":{"position":[[215,7]]},"828":{"position":[[307,7]]},"932":{"position":[[325,6],[2698,6]]},"965":{"position":[[118,7]]},"976":{"position":[[53,6]]},"978":{"position":[[2135,7]]},"1383":{"position":[[1485,6]]},"1823":{"position":[[325,6],[2698,6]]},"1856":{"position":[[118,7]]},"1867":{"position":[[53,6]]},"1869":{"position":[[2135,7]]},"2029":{"position":[[205,6]]},"2956":{"position":[[325,6],[2698,6]]},"2989":{"position":[[118,7]]},"3000":{"position":[[53,6]]},"3002":{"position":[[2135,7]]},"3144":{"position":[[331,6]]},"3164":{"position":[[427,6]]},"3176":{"position":[[287,6]]},"3276":{"position":[[395,6]]},"3731":{"position":[[1464,6]]},"3744":{"position":[[222,6]]},"3894":{"position":[[371,6]]},"3928":{"position":[[5757,6]]},"4580":{"position":[[1415,6],[3373,6]]},"4643":{"position":[[935,8]]},"4872":{"position":[[448,6]]}}}],["cove",{"_index":10589,"t":{"3712":{"position":[[1752,5]]}}}],["coven",{"_index":1513,"t":{"199":{"position":[[3293,8]]}}}],["cover",{"_index":1253,"t":{"179":{"position":[[1342,7],[1455,7],[1574,7]]},"222":{"position":[[57,6]]},"249":{"position":[[500,7]]},"305":{"position":[[70,5]]},"438":{"position":[[542,6]]},"557":{"position":[[5069,5]]},"696":{"position":[[630,6]]},"706":{"position":[[468,5],[1098,7]]},"924":{"position":[[524,7]]},"1240":{"position":[[182,7]]},"1387":{"position":[[365,7]]},"1484":{"position":[[821,7]]},"1501":{"position":[[213,7]]},"1646":{"position":[[309,7]]},"1815":{"position":[[524,7]]},"1979":{"position":[[365,7]]},"2119":{"position":[[1218,5]]},"2123":{"position":[[1657,8]]},"2148":{"position":[[365,7]]},"2285":{"position":[[1165,5]]},"2299":{"position":[[1165,5]]},"2321":{"position":[[197,5]]},"2388":{"position":[[197,5]]},"2473":{"position":[[10,6]]},"2527":{"position":[[165,8]]},"2584":{"position":[[1094,5]]},"2586":{"position":[[704,5]]},"2608":{"position":[[1369,7]]},"2618":{"position":[[915,6]]},"2649":{"position":[[188,6]]},"2651":{"position":[[11,6]]},"2690":{"position":[[292,5]]},"2802":{"position":[[244,5],[327,5],[397,5]]},"2948":{"position":[[524,7]]},"3067":{"position":[[928,7]]},"3150":{"position":[[361,8],[814,7]]},"3157":{"position":[[157,6]]},"3246":{"position":[[368,7]]},"3248":{"position":[[606,5]]},"3290":{"position":[[124,6],[268,8]]},"3292":{"position":[[215,6]]},"3357":{"position":[[3024,7],[3275,7]]},"3502":{"position":[[30,5]]},"3549":{"position":[[1496,5]]},"3571":{"position":[[1153,8]]},"3735":{"position":[[131,5]]},"3738":{"position":[[212,5]]},"3928":{"position":[[6171,7]]},"4098":{"position":[[798,8]]},"4109":{"position":[[261,8]]},"4180":{"position":[[145,5]]},"4291":{"position":[[1109,7],[1281,5]]},"4319":{"position":[[73,7]]},"4543":{"position":[[462,5]]},"4578":{"position":[[130,7]]},"4580":{"position":[[2025,5]]},"4595":{"position":[[130,8]]},"4632":{"position":[[2205,5]]},"4728":{"position":[[1534,8]]},"4839":{"position":[[1807,7]]}}}],["coverag",{"_index":8604,"t":{"2553":{"position":[[392,9]]},"2590":{"position":[[393,9]]},"2592":{"position":[[363,9]]},"2692":{"position":[[920,9]]},"2802":{"position":[[180,8],[286,8],[310,8]]},"3044":{"position":[[67,8]]},"3064":{"position":[[105,9]]},"3114":{"position":[[124,8]]},"3168":{"position":[[903,8]]},"3259":{"position":[[227,9]]},"4109":{"position":[[825,8],[1698,8],[2559,8],[4251,8]]},"4133":{"position":[[254,8]]}}}],["coverage.out",{"_index":9169,"t":{"2802":{"position":[[220,12],[339,12],[409,12]]}}}],["coverprofil",{"_index":9168,"t":{"2802":{"position":[[207,12]]}}}],["covert",{"_index":8093,"t":{"2238":{"position":[[142,9]]},"4222":{"position":[[1241,6],[1500,6]]}}}],["cozi",{"_index":1589,"t":{"218":{"position":[[216,9]]}}}],["cp",{"_index":1008,"t":{"167":{"position":[[2012,3]]},"489":{"position":[[1374,2]]},"491":{"position":[[382,2]]},"514":{"position":[[481,2]]},"942":{"position":[[3626,2]]},"1224":{"position":[[271,2]]},"1833":{"position":[[3626,2]]},"2121":{"position":[[511,2]]},"2207":{"position":[[1009,2]]},"2883":{"position":[[257,2]]},"2966":{"position":[[3626,2]]}}}],["cpu",{"_index":2630,"t":{"541":{"position":[[1191,4]]},"824":{"position":[[470,3]]},"1040":{"position":[[377,3]]},"1105":{"position":[[760,3],[805,3]]},"1107":{"position":[[479,3],[625,3]]},"1109":{"position":[[407,3]]},"1113":{"position":[[528,3]]},"1118":{"position":[[349,3]]},"1187":{"position":[[166,3],[594,3]]},"1189":{"position":[[0,3],[263,4],[350,4],[402,4],[417,3],[508,4],[550,5],[940,4],[1049,5],[1218,5]]},"1301":{"position":[[1474,3]]},"1373":{"position":[[52,3],[209,3],[347,3]]},"1375":{"position":[[409,5],[568,3]]},"1377":{"position":[[99,3],[284,3],[309,3]]},"1379":{"position":[[76,3]]},"1455":{"position":[[579,3],[609,3],[1492,4]]},"2003":{"position":[[174,3]]},"2021":{"position":[[358,4]]},"2027":{"position":[[110,3]]},"2252":{"position":[[256,4]]},"3402":{"position":[[270,3]]},"3406":{"position":[[314,4]]},"3653":{"position":[[874,3]]},"3656":{"position":[[109,3],[134,3],[292,5],[313,3]]},"3658":{"position":[[7,3]]},"3661":{"position":[[529,4],[579,3],[865,4],[1507,3],[1611,4],[1787,3]]},"3669":{"position":[[220,3],[342,4]]},"3671":{"position":[[50,4],[212,3]]},"3677":{"position":[[162,3],[849,4]]},"3681":{"position":[[77,3]]},"3690":{"position":[[773,3]]},"3693":{"position":[[168,3],[193,3],[351,5],[372,3]]},"3695":{"position":[[7,4]]},"3698":{"position":[[634,4],[686,3],[998,4],[1616,4],[2161,3],[2265,4],[2441,3]]},"3706":{"position":[[164,3],[719,4]]},"3710":{"position":[[233,3],[355,4]]},"3712":{"position":[[73,4]]},"3718":{"position":[[77,3]]},"3747":{"position":[[193,4],[291,3]]},"3761":{"position":[[375,3],[426,5],[745,3]]},"3763":{"position":[[174,3],[878,4]]},"3772":{"position":[[23,4]]},"3777":{"position":[[874,3]]},"3780":{"position":[[168,3],[193,3],[351,5],[372,3]]},"3782":{"position":[[7,4]]},"3785":{"position":[[634,4],[686,3],[1001,4],[1379,3],[1859,3],[1963,4],[2139,3]]},"3791":{"position":[[160,3],[871,4]]},"3799":{"position":[[164,3],[719,4]]},"3803":{"position":[[220,3],[342,4]]},"3805":{"position":[[50,4],[212,3]]},"3811":{"position":[[77,3]]},"3850":{"position":[[36,3],[99,3]]},"3855":{"position":[[476,3]]},"3894":{"position":[[416,3],[458,3]]},"3902":{"position":[[42,5]]},"3904":{"position":[[274,4]]},"3928":{"position":[[2603,3]]},"4135":{"position":[[176,4]]},"4722":{"position":[[561,3]]},"4726":{"position":[[257,4]]},"4733":{"position":[[610,4],[900,4]]},"4738":{"position":[[524,3],[696,4]]}}}],["cpu_dedicated_set",{"_index":5865,"t":{"1373":{"position":[[136,17]]}}}],["cpu_dedicated_set=2",{"_index":5871,"t":{"1373":{"position":[[817,19]]}}}],["cpu_dedicated_set=4",{"_index":5874,"t":{"1373":{"position":[[1071,19]]}}}],["cpu_power_management_strategy=cpu_st",{"_index":5868,"t":{"1373":{"position":[[623,39]]}}}],["cpu_shared_set=4",{"_index":5882,"t":{"1377":{"position":[[180,16]]}}}],["cpy%sync",{"_index":4694,"t":{"1175":{"position":[[5079,8]]}}}],["craft",{"_index":1840,"t":{"280":{"position":[[439,8]]},"376":{"position":[[202,7]]},"2261":{"position":[[95,7]]},"2520":{"position":[[206,5]]},"2871":{"position":[[219,7]]},"3246":{"position":[[249,7]]},"3573":{"position":[[262,8]]},"3986":{"position":[[517,5]]},"3994":{"position":[[160,8]]}}}],["crash",{"_index":4094,"t":{"973":{"position":[[394,6]]},"1435":{"position":[[9,5],[91,5]]},"1503":{"position":[[1169,5],[1201,5]]},"1864":{"position":[[394,6]]},"2333":{"position":[[143,5]]},"2339":{"position":[[395,5]]},"2400":{"position":[[143,5]]},"2406":{"position":[[395,5]]},"2997":{"position":[[394,6]]},"3928":{"position":[[4066,6],[4418,7]]},"4479":{"position":[[632,8]]}}}],["crc",{"_index":5990,"t":{"1405":{"position":[[636,3]]}}}],["crd",{"_index":2334,"t":{"421":{"position":[[810,4],[877,4]]},"427":{"position":[[562,4]]},"456":{"position":[[22,3]]},"699":{"position":[[287,4]]},"1056":{"position":[[1611,6]]},"1407":{"position":[[212,3]]},"1409":{"position":[[30,3]]},"1411":{"position":[[212,3]]},"1443":{"position":[[239,3],[617,4],[641,3],[1067,3]]},"1525":{"position":[[929,5]]},"1527":{"position":[[117,4]]},"1962":{"position":[[108,4]]},"1966":{"position":[[108,4]]},"2539":{"position":[[555,4]]},"4562":{"position":[[7088,5]]}}}],["crd'",{"_index":8657,"t":{"2584":{"position":[[1234,5]]},"2586":{"position":[[844,5]]}}}],["cre",{"_index":2820,"t":{"557":{"position":[[6385,3]]}}}],["creat",{"_index":48,"t":{"7":{"position":[[354,7]]},"19":{"position":[[126,6]]},"24":{"position":[[270,7]]},"39":{"position":[[0,6],[59,7]]},"70":{"position":[[502,8]]},"167":{"position":[[1194,6],[1824,6]]},"169":{"position":[[856,6],[1078,6]]},"171":{"position":[[575,7],[1005,6]]},"173":{"position":[[1824,6]]},"177":{"position":[[224,8]]},"181":{"position":[[1213,6]]},"207":{"position":[[30,6],[235,6]]},"224":{"position":[[622,6]]},"237":{"position":[[0,6]]},"241":{"position":[[312,6],[482,6]]},"247":{"position":[[89,6],[127,6],[170,6],[196,6]]},"249":{"position":[[289,7],[637,7],[1448,6]]},"262":{"position":[[8,7]]},"269":{"position":[[49,7]]},"271":{"position":[[48,6],[531,6]]},"307":{"position":[[113,6]]},"329":{"position":[[57,7]]},"354":{"position":[[120,6]]},"360":{"position":[[875,6]]},"364":{"position":[[637,6],[904,8]]},"368":{"position":[[196,6],[1718,6],[3821,7],[3914,6],[7574,8]]},"378":{"position":[[71,9]]},"382":{"position":[[264,6]]},"391":{"position":[[579,6]]},"395":{"position":[[7,7]]},"397":{"position":[[262,8],[318,6]]},"417":{"position":[[116,7],[268,8],[507,8]]},"430":{"position":[[240,6]]},"432":{"position":[[59,6]]},"434":{"position":[[1527,7],[1577,6]]},"438":{"position":[[493,8]]},"440":{"position":[[0,6],[614,6]]},"446":{"position":[[91,7]]},"461":{"position":[[610,6]]},"463":{"position":[[1494,6]]},"465":{"position":[[11,6]]},"475":{"position":[[659,7],[763,6]]},"477":{"position":[[278,6]]},"489":{"position":[[102,7],[1176,7],[1240,6],[1290,7]]},"493":{"position":[[417,6],[464,7]]},"496":{"position":[[121,6]]},"498":{"position":[[156,6]]},"500":{"position":[[330,6]]},"504":{"position":[[281,6]]},"506":{"position":[[59,6]]},"512":{"position":[[87,6],[135,6],[263,7]]},"514":{"position":[[1655,6],[1676,6],[1804,8]]},"526":{"position":[[842,7],[1579,7]]},"539":{"position":[[44,8]]},"543":{"position":[[944,6]]},"557":{"position":[[538,7],[751,7],[4074,8],[4115,6],[4300,8],[4426,8],[4457,6],[4582,8],[4705,8],[5940,6],[6871,8]]},"564":{"position":[[20,6]]},"566":{"position":[[169,6]]},"568":{"position":[[95,6]]},"570":{"position":[[75,6],[128,6],[178,7]]},"572":{"position":[[214,6],[301,6],[516,6],[602,6]]},"576":{"position":[[0,6],[30,6]]},"584":{"position":[[33,6],[528,6]]},"586":{"position":[[1471,7],[1566,7]]},"588":{"position":[[3,6],[528,6],[1561,7],[1840,7]]},"593":{"position":[[433,6]]},"595":{"position":[[265,7],[538,8]]},"597":{"position":[[619,6],[681,8],[746,8]]},"624":{"position":[[169,8]]},"628":{"position":[[79,6],[99,7],[310,6],[317,7]]},"630":{"position":[[28,6]]},"641":{"position":[[19,6]]},"655":{"position":[[33,7],[213,6],[562,6]]},"664":{"position":[[433,6]]},"666":{"position":[[19,6]]},"668":{"position":[[38,7],[1218,6]]},"673":{"position":[[33,7],[213,6],[562,6]]},"686":{"position":[[145,6]]},"692":{"position":[[139,6]]},"694":{"position":[[175,6]]},"696":{"position":[[698,7]]},"699":{"position":[[228,8],[487,6]]},"701":{"position":[[209,6],[926,7],[1229,6],[1988,6],[2449,6]]},"705":{"position":[[108,6],[264,7],[1088,6],[1415,7],[1509,6]]},"708":{"position":[[890,6],[1218,6]]},"734":{"position":[[213,6]]},"738":{"position":[[944,7]]},"739":{"position":[[590,6],[727,7],[1403,6]]},"747":{"position":[[58,6]]},"751":{"position":[[145,6]]},"814":{"position":[[489,8]]},"816":{"position":[[1056,8]]},"836":{"position":[[292,6]]},"848":{"position":[[439,8],[509,8],[576,8]]},"865":{"position":[[281,7],[641,6]]},"871":{"position":[[1076,7]]},"873":{"position":[[1131,7]]},"894":{"position":[[391,6],[793,6],[962,6],[1071,6],[1266,7],[1319,7],[1373,7],[1427,7]]},"906":{"position":[[139,6],[164,6],[186,6]]},"910":{"position":[[344,6]]},"912":{"position":[[24,6],[146,7],[220,7],[342,6],[465,6],[487,6],[505,6],[2086,6],[2104,6],[2124,6],[2138,6],[2159,6],[2171,6],[2638,6],[2691,6],[2738,6],[3714,6],[3826,6],[3921,7],[4584,6],[4679,6],[5168,6]]},"914":{"position":[[4659,7],[5976,7]]},"916":{"position":[[158,6]]},"924":{"position":[[593,6],[1940,6]]},"928":{"position":[[778,7]]},"932":{"position":[[365,6],[606,6],[710,6],[747,6],[873,6],[954,6],[999,6],[1100,6],[1193,6],[1256,6],[1301,6],[1413,6],[1453,6],[1546,8],[1934,6],[2315,6],[2818,6],[3536,6]]},"934":{"position":[[1966,8],[2339,7]]},"938":{"position":[[465,8],[1537,8],[2156,7],[2380,6],[2416,6]]},"942":{"position":[[270,6],[682,7]]},"946":{"position":[[509,8],[650,7],[788,6]]},"951":{"position":[[964,6],[1093,6],[1181,7]]},"961":{"position":[[1019,6],[1061,6],[1199,6],[1476,6],[1996,6]]},"978":{"position":[[22,7]]},"980":{"position":[[606,7]]},"993":{"position":[[106,8]]},"1005":{"position":[[2947,8],[3008,8],[3943,8],[4004,8],[4939,8],[5103,8]]},"1007":{"position":[[142,6]]},"1009":{"position":[[160,7]]},"1056":{"position":[[709,9]]},"1171":{"position":[[907,7]]},"1173":{"position":[[613,7]]},"1175":{"position":[[4539,6],[4582,6],[4628,7]]},"1177":{"position":[[363,8],[1777,6],[1990,6],[3185,6],[5383,6],[5461,6]]},"1179":{"position":[[2199,6],[2240,6]]},"1183":{"position":[[533,6]]},"1185":{"position":[[530,7]]},"1191":{"position":[[946,6],[1123,6]]},"1197":{"position":[[52,7]]},"1199":{"position":[[605,7]]},"1205":{"position":[[471,7]]},"1218":{"position":[[261,7],[303,7]]},"1222":{"position":[[24,7],[83,6]]},"1224":{"position":[[521,7]]},"1226":{"position":[[47,7],[2142,8],[2218,7],[2453,8],[5838,7]]},"1232":{"position":[[146,8]]},"1236":{"position":[[311,7],[910,7]]},"1238":{"position":[[586,7],[622,7]]},"1252":{"position":[[1028,8]]},"1259":{"position":[[477,6]]},"1268":{"position":[[123,6]]},"1271":{"position":[[18,7]]},"1297":{"position":[[59,7]]},"1301":{"position":[[1265,6],[1547,6],[2467,6],[3460,6]]},"1303":{"position":[[91,7]]},"1324":{"position":[[339,7],[6579,7],[12557,7],[12693,6]]},"1375":{"position":[[59,6],[242,6]]},"1379":{"position":[[18,6]]},"1383":{"position":[[1237,6],[2335,6]]},"1385":{"position":[[650,7]]},"1421":{"position":[[300,6],[364,6],[1509,7]]},"1423":{"position":[[36,7]]},"1427":{"position":[[78,7]]},"1431":{"position":[[38,7],[123,7],[206,6],[261,8]]},"1457":{"position":[[648,6],[976,7],[1023,7]]},"1460":{"position":[[231,7]]},"1466":{"position":[[1079,7],[1126,7]]},"1472":{"position":[[21,7]]},"1497":{"position":[[134,7],[301,6]]},"1501":{"position":[[96,7]]},"1503":{"position":[[2520,7]]},"1515":{"position":[[38,6]]},"1527":{"position":[[82,8]]},"1555":{"position":[[23,6],[135,6],[183,6],[313,7],[1023,6]]},"1561":{"position":[[0,6],[238,6],[563,6]]},"1631":{"position":[[16,6]]},"1639":{"position":[[22,6],[94,6],[166,6]]},"1694":{"position":[[2741,8]]},"1711":{"position":[[1148,7]]},"1720":{"position":[[69,6],[190,6]]},"1740":{"position":[[455,6]]},"1752":{"position":[[391,6],[793,6],[962,6],[1071,6],[1266,7],[1319,7],[1373,7],[1427,7]]},"1766":{"position":[[281,7],[641,6]]},"1772":{"position":[[1076,7]]},"1774":{"position":[[1131,7]]},"1790":{"position":[[139,6],[164,6],[186,6]]},"1794":{"position":[[344,6]]},"1796":{"position":[[24,6],[146,7],[220,7],[342,6],[465,6],[487,6],[505,6],[2086,6],[2104,6],[2124,6],[2138,6],[2159,6],[2171,6],[2638,6],[2691,6],[2738,6],[3714,6],[3826,6],[3921,7],[4584,6],[4679,6],[5168,6]]},"1798":{"position":[[4659,7],[5976,7]]},"1800":{"position":[[158,6]]},"1815":{"position":[[593,6],[1940,6]]},"1819":{"position":[[778,7]]},"1823":{"position":[[365,6],[606,6],[710,6],[747,6],[873,6],[954,6],[999,6],[1100,6],[1193,6],[1256,6],[1301,6],[1413,6],[1453,6],[1546,8],[1934,6],[2315,6],[2818,6],[3536,6]]},"1825":{"position":[[1966,8],[2339,7]]},"1829":{"position":[[465,8],[1537,8],[2156,7],[2380,6],[2416,6]]},"1833":{"position":[[270,6],[682,7]]},"1837":{"position":[[509,8],[650,7],[788,6]]},"1842":{"position":[[964,6],[1093,6],[1181,7]]},"1852":{"position":[[1019,6],[1061,6],[1199,6],[1476,6],[1996,6]]},"1869":{"position":[[22,7]]},"1871":{"position":[[606,7]]},"1884":{"position":[[106,8]]},"1896":{"position":[[2947,8],[3008,8],[3943,8],[4004,8],[4939,8],[5103,8]]},"1898":{"position":[[142,6]]},"1962":{"position":[[209,6]]},"1970":{"position":[[22,6],[94,6],[166,6]]},"2005":{"position":[[615,6]]},"2029":{"position":[[275,8]]},"2032":{"position":[[536,6]]},"2034":{"position":[[226,6],[275,6],[307,6],[354,6],[383,6],[474,7],[482,6],[621,6],[687,6]]},"2048":{"position":[[2839,6],[2922,6],[3112,6]]},"2057":{"position":[[412,7]]},"2059":{"position":[[93,7],[397,8],[424,7],[1010,7],[1358,7],[1521,7],[2672,6]]},"2065":{"position":[[51,7],[336,7],[435,7]]},"2069":{"position":[[10,6]]},"2117":{"position":[[796,6],[967,6],[1147,6],[1406,6]]},"2119":{"position":[[766,7]]},"2121":{"position":[[405,8]]},"2123":{"position":[[119,6],[412,6],[1089,6]]},"2130":{"position":[[235,6]]},"2132":{"position":[[143,6],[429,6]]},"2142":{"position":[[26,8]]},"2146":{"position":[[126,7]]},"2155":{"position":[[1093,7]]},"2184":{"position":[[1979,6],[3110,6],[3179,6],[6419,6],[6479,7]]},"2199":{"position":[[582,7]]},"2207":{"position":[[1188,6]]},"2211":{"position":[[1820,6],[2076,7]]},"2221":{"position":[[61,6]]},"2227":{"position":[[162,6],[169,6]]},"2240":{"position":[[1011,8]]},"2250":{"position":[[574,6]]},"2252":{"position":[[136,6],[626,6],[2519,6]]},"2261":{"position":[[51,6]]},"2263":{"position":[[134,6],[361,6]]},"2266":{"position":[[0,6],[93,6],[160,6],[300,6],[381,6],[446,6],[580,7],[642,6]]},"2268":{"position":[[0,6],[108,6],[282,7]]},"2276":{"position":[[2037,6]]},"2281":{"position":[[101,6]]},"2283":{"position":[[428,8]]},"2285":{"position":[[30,7],[331,8],[1197,6],[1377,6]]},"2289":{"position":[[505,6],[734,6]]},"2293":{"position":[[402,6],[547,6],[588,6],[717,6],[759,6],[890,6],[933,6],[1065,6],[1107,6]]},"2295":{"position":[[435,6]]},"2297":{"position":[[428,8]]},"2299":{"position":[[30,7],[331,8],[1197,6],[1377,6]]},"2303":{"position":[[505,6],[734,6]]},"2307":{"position":[[402,6],[547,6],[588,6],[717,6],[759,6],[890,6],[933,6],[1065,6],[1107,6]]},"2309":{"position":[[435,6]]},"2317":{"position":[[46,8]]},"2325":{"position":[[412,8]]},"2327":{"position":[[91,6],[281,7],[657,6],[712,6]]},"2329":{"position":[[230,7],[469,8],[693,7],[845,7]]},"2331":{"position":[[15,7],[123,6],[204,7],[288,6]]},"2333":{"position":[[10,8],[118,7],[242,7],[317,6],[406,7],[490,6]]},"2337":{"position":[[260,6]]},"2339":{"position":[[29,6],[106,6],[234,8],[436,6],[553,6],[603,6],[697,6],[846,6],[909,6]]},"2343":{"position":[[144,7],[707,7]]},"2347":{"position":[[633,7],[802,7]]},"2349":{"position":[[142,6]]},"2351":{"position":[[73,7],[378,6]]},"2353":{"position":[[168,7],[585,6],[721,6]]},"2355":{"position":[[97,7],[208,6],[343,7],[434,6],[835,8],[931,6],[1063,8],[1677,7],[1936,7],[2595,6],[2752,6]]},"2358":{"position":[[71,7],[166,7]]},"2372":{"position":[[30,6]]},"2380":{"position":[[206,8],[674,7]]},"2384":{"position":[[46,8]]},"2392":{"position":[[412,8]]},"2394":{"position":[[91,6],[281,7],[657,6],[712,6]]},"2396":{"position":[[230,7],[469,8],[693,7],[845,7]]},"2398":{"position":[[15,7],[123,6],[204,7],[288,6]]},"2400":{"position":[[10,8],[118,7],[242,7],[317,6],[406,7],[490,6]]},"2404":{"position":[[260,6]]},"2406":{"position":[[29,6],[106,6],[234,8],[436,6],[553,6],[603,6],[697,6],[846,6],[909,6]]},"2410":{"position":[[144,7],[707,7]]},"2414":{"position":[[633,7],[802,7]]},"2416":{"position":[[142,6]]},"2418":{"position":[[73,7],[378,6]]},"2420":{"position":[[168,7],[585,6],[721,6]]},"2422":{"position":[[97,7],[208,6],[343,7],[434,6],[835,8],[931,6],[1063,8],[1677,7],[1936,7],[2595,6],[2752,6]]},"2425":{"position":[[71,7],[166,7]]},"2431":{"position":[[628,6],[1030,6],[2801,7]]},"2433":{"position":[[96,7],[421,7],[622,8],[662,7],[912,8],[1158,7]]},"2443":{"position":[[374,6]]},"2445":{"position":[[86,7],[198,6]]},"2451":{"position":[[72,8],[349,7],[364,8],[437,6]]},"2453":{"position":[[5,8],[341,6],[389,6],[684,7],[711,6]]},"2461":{"position":[[0,8],[48,6]]},"2463":{"position":[[0,8],[54,6]]},"2465":{"position":[[0,8],[50,6]]},"2478":{"position":[[1138,8]]},"2569":{"position":[[163,7]]},"2578":{"position":[[11,8],[429,8]]},"2582":{"position":[[345,8]]},"2584":{"position":[[1200,8],[1306,8]]},"2586":{"position":[[810,8],[916,8]]},"2602":{"position":[[1451,6]]},"2608":{"position":[[747,6]]},"2612":{"position":[[12,6]]},"2624":{"position":[[219,7]]},"2626":{"position":[[996,6],[1036,6]]},"2649":{"position":[[1485,6],[2515,7]]},"2655":{"position":[[391,6]]},"2661":{"position":[[511,8]]},"2678":{"position":[[603,6]]},"2684":{"position":[[338,8],[534,7]]},"2692":{"position":[[930,6],[1452,6],[1562,6]]},"2705":{"position":[[0,6]]},"2712":{"position":[[396,6],[621,6],[686,6]]},"2714":{"position":[[133,8],[1684,7]]},"2716":{"position":[[1023,6],[1074,6],[1353,7],[1409,7],[1624,7],[1698,7]]},"2718":{"position":[[286,7]]},"2725":{"position":[[237,6],[1054,6]]},"2730":{"position":[[188,6]]},"2732":{"position":[[244,8],[306,6],[408,8],[511,6]]},"2738":{"position":[[0,8]]},"2740":{"position":[[0,6],[750,6],[771,6]]},"2747":{"position":[[0,6],[507,6]]},"2754":{"position":[[259,6]]},"2802":{"position":[[171,6]]},"2814":{"position":[[806,7],[911,8]]},"2839":{"position":[[137,6]]},"2863":{"position":[[247,7]]},"2879":{"position":[[156,6]]},"2881":{"position":[[0,6]]},"2883":{"position":[[191,6],[217,6]]},"2910":{"position":[[79,8]]},"2940":{"position":[[279,7]]},"2948":{"position":[[593,6],[1940,6]]},"2952":{"position":[[778,7]]},"2956":{"position":[[365,6],[606,6],[710,6],[747,6],[873,6],[954,6],[999,6],[1100,6],[1193,6],[1256,6],[1301,6],[1413,6],[1453,6],[1546,8],[1934,6],[2315,6],[2818,6],[3536,6]]},"2958":{"position":[[1966,8],[2339,7]]},"2962":{"position":[[465,8],[1537,8],[2156,7],[2380,6],[2416,6]]},"2966":{"position":[[270,6],[682,7]]},"2970":{"position":[[509,8],[650,7],[788,6]]},"2975":{"position":[[964,6],[1093,6],[1181,7]]},"2985":{"position":[[1019,6],[1061,6],[1199,6],[1476,6],[1996,6]]},"3002":{"position":[[22,7]]},"3004":{"position":[[606,7]]},"3016":{"position":[[77,6]]},"3022":{"position":[[1205,7]]},"3032":{"position":[[90,6]]},"3052":{"position":[[87,7]]},"3064":{"position":[[147,8]]},"3067":{"position":[[308,6],[737,7]]},"3073":{"position":[[158,6],[661,8]]},"3086":{"position":[[133,8]]},"3101":{"position":[[443,8]]},"3103":{"position":[[13,7]]},"3136":{"position":[[13,7]]},"3144":{"position":[[410,7]]},"3148":{"position":[[737,7],[973,7]]},"3153":{"position":[[681,6]]},"3168":{"position":[[92,7]]},"3176":{"position":[[366,7]]},"3187":{"position":[[33,7]]},"3189":{"position":[[465,6]]},"3208":{"position":[[135,8]]},"3223":{"position":[[363,6],[499,8],[657,6]]},"3225":{"position":[[407,7],[667,7]]},"3232":{"position":[[137,7]]},"3238":{"position":[[358,6]]},"3264":{"position":[[32,8]]},"3288":{"position":[[398,6],[492,6]]},"3294":{"position":[[714,6]]},"3296":{"position":[[819,6],[1397,6]]},"3352":{"position":[[848,7],[1130,7],[2628,7],[3458,7],[3784,7]]},"3361":{"position":[[221,7]]},"3378":{"position":[[230,6],[287,6],[335,6]]},"3381":{"position":[[16,6],[2733,8]]},"3384":{"position":[[100,6],[1722,8]]},"3502":{"position":[[751,6]]},"3533":{"position":[[83,7],[2057,7]]},"3537":{"position":[[680,7]]},"3558":{"position":[[48,6]]},"3573":{"position":[[140,9],[478,6],[763,7]]},"3590":{"position":[[118,6]]},"3665":{"position":[[937,6],[1064,6],[1322,7],[1786,7],[1871,7],[1959,7]]},"3669":{"position":[[26,7]]},"3677":{"position":[[1366,7],[1461,6],[1538,6]]},"3690":{"position":[[935,8]]},"3702":{"position":[[1150,6],[1277,6],[1669,7],[2121,7]]},"3710":{"position":[[39,7]]},"3724":{"position":[[51,7]]},"3742":{"position":[[737,6],[892,8]]},"3759":{"position":[[120,8]]},"3777":{"position":[[1036,8]]},"3789":{"position":[[1009,6],[1136,6],[1528,7],[1993,7],[2078,7],[2166,7]]},"3791":{"position":[[1388,7],[1483,6],[1560,6]]},"3797":{"position":[[40,6]]},"3803":{"position":[[26,7]]},"3817":{"position":[[51,7]]},"3840":{"position":[[44,6]]},"3879":{"position":[[443,8]]},"3885":{"position":[[39,6]]},"3904":{"position":[[919,7],[1014,6],[1091,6]]},"3908":{"position":[[40,6]]},"3920":{"position":[[39,6]]},"3928":{"position":[[360,6]]},"3930":{"position":[[391,6]]},"3932":{"position":[[494,6]]},"3934":{"position":[[235,8]]},"3941":{"position":[[666,7],[677,8],[811,7],[1380,8]]},"3943":{"position":[[109,8]]},"3968":{"position":[[66,6]]},"3978":{"position":[[340,7]]},"3982":{"position":[[6,8]]},"3986":{"position":[[361,6]]},"3988":{"position":[[26,7],[95,8],[165,7]]},"3990":{"position":[[329,6]]},"3994":{"position":[[86,6],[132,7]]},"3996":{"position":[[418,8]]},"4005":{"position":[[120,7]]},"4007":{"position":[[308,7]]},"4009":{"position":[[37,6]]},"4013":{"position":[[175,8]]},"4017":{"position":[[94,7]]},"4037":{"position":[[308,7],[369,8],[439,7],[497,8]]},"4041":{"position":[[359,7],[385,7],[620,8],[686,7],[951,7]]},"4043":{"position":[[135,7],[440,7]]},"4045":{"position":[[1234,6]]},"4081":{"position":[[1637,8]]},"4116":{"position":[[379,6]]},"4118":{"position":[[222,6]]},"4124":{"position":[[157,7],[938,8],[1072,8]]},"4130":{"position":[[91,6]]},"4153":{"position":[[439,8]]},"4157":{"position":[[1196,6]]},"4163":{"position":[[342,6]]},"4165":{"position":[[954,6]]},"4200":{"position":[[231,8]]},"4224":{"position":[[23,6]]},"4226":{"position":[[443,7]]},"4228":{"position":[[456,7]]},"4230":{"position":[[336,7],[861,8],[1162,8],[1323,6],[1429,6],[3134,6],[3556,8],[3639,8],[4130,8]]},"4257":{"position":[[3195,7]]},"4275":{"position":[[346,8]]},"4277":{"position":[[34,6]]},"4279":{"position":[[481,7]]},"4289":{"position":[[0,6]]},"4291":{"position":[[1437,7]]},"4306":{"position":[[434,8]]},"4340":{"position":[[98,6]]},"4348":{"position":[[212,8]]},"4380":{"position":[[96,7]]},"4388":{"position":[[136,6]]},"4405":{"position":[[121,8]]},"4407":{"position":[[256,6]]},"4412":{"position":[[127,8]]},"4431":{"position":[[1407,6]]},"4516":{"position":[[701,6],[1185,7],[1614,6]]},"4518":{"position":[[166,6]]},"4535":{"position":[[3632,8]]},"4539":{"position":[[2474,7],[6745,7]]},"4543":{"position":[[1871,7]]},"4572":{"position":[[423,7]]},"4580":{"position":[[902,7],[1048,6],[1702,7],[3605,8]]},"4593":{"position":[[1989,6],[4067,7]]},"4595":{"position":[[199,6]]},"4610":{"position":[[144,7],[259,7],[506,8]]},"4612":{"position":[[304,6]]},"4614":{"position":[[970,7],[1316,8]]},"4639":{"position":[[0,6]]},"4643":{"position":[[255,6],[498,8],[836,8],[855,8],[956,6],[1333,8],[1359,6],[1390,6],[1431,7],[1477,8],[1504,6],[1551,6],[2024,7],[2209,7]]},"4654":{"position":[[0,8],[636,6]]},"4656":{"position":[[169,6]]},"4658":{"position":[[512,6]]},"4662":{"position":[[1330,7]]},"4667":{"position":[[6573,7]]},"4691":{"position":[[1172,8]]},"4701":{"position":[[200,8]]},"4709":{"position":[[90,7]]},"4713":{"position":[[24,6]]},"4724":{"position":[[438,6]]},"4730":{"position":[[175,7],[2164,7]]},"4736":{"position":[[262,8]]},"4738":{"position":[[243,8]]},"4744":{"position":[[1016,8]]},"4755":{"position":[[262,8]]},"4757":{"position":[[309,8]]},"4826":{"position":[[3791,6]]},"4845":{"position":[[0,6],[122,8]]},"4849":{"position":[[1544,8]]},"4851":{"position":[[0,6],[48,6]]},"4853":{"position":[[0,6]]},"4857":{"position":[[61,7]]},"4861":{"position":[[377,6]]},"4863":{"position":[[265,7]]},"4872":{"position":[[307,6],[467,6]]},"4875":{"position":[[282,6]]},"4879":{"position":[[409,6]]},"4881":{"position":[[210,6]]}}}],["create.pi",{"_index":3608,"t":{"906":{"position":[[4,9]]},"910":{"position":[[468,9]]},"912":{"position":[[192,9],[3769,9]]},"914":{"position":[[159,9]]},"916":{"position":[[39,9]]},"1790":{"position":[[4,9]]},"1794":{"position":[[468,9]]},"1796":{"position":[[192,9],[3769,9]]},"1798":{"position":[[159,9]]},"1800":{"position":[[39,9]]}}}],["create_domain",{"_index":8910,"t":{"2692":{"position":[[1244,14]]}}}],["create_machin",{"_index":8912,"t":{"2692":{"position":[[1315,15]]}}}],["create_project",{"_index":8911,"t":{"2692":{"position":[[1282,15]]}}}],["create_rook_clust",{"_index":5964,"t":{"1391":{"position":[[2967,19]]}}}],["created_at",{"_index":9439,"t":{"3036":{"position":[[2094,11],[3202,11],[4039,11],[5248,11],[10865,11],[11732,11]]}}}],["createdat",{"_index":9183,"t":{"2816":{"position":[[202,12]]}}}],["createdat\":\"2024",{"_index":9148,"t":{"2790":{"position":[[109,19]]}}}],["createimag",{"_index":8354,"t":{"2327":{"position":[[23,11],[556,11]]},"2358":{"position":[[9,11],[550,11]]},"2394":{"position":[[23,11],[556,11]]},"2425":{"position":[[9,11],[550,11]]}}}],["creation",{"_index":1174,"t":{"175":{"position":[[53,8]]},"280":{"position":[[968,9]]},"291":{"position":[[165,8]]},"295":{"position":[[157,8]]},"370":{"position":[[178,8]]},"500":{"position":[[121,8]]},"516":{"position":[[69,8]]},"530":{"position":[[807,9],[1008,9]]},"539":{"position":[[486,9]]},"545":{"position":[[1100,9]]},"701":{"position":[[1028,9]]},"890":{"position":[[41,9]]},"901":{"position":[[42,8]]},"934":{"position":[[2121,8]]},"963":{"position":[[4209,8]]},"1226":{"position":[[321,8]]},"1232":{"position":[[193,8]]},"1305":{"position":[[359,8]]},"1385":{"position":[[528,8],[564,8]]},"1460":{"position":[[288,8]]},"1472":{"position":[[3171,8]]},"1501":{"position":[[169,8],[232,8]]},"1748":{"position":[[41,9]]},"1785":{"position":[[42,8]]},"1825":{"position":[[2121,8]]},"1854":{"position":[[4209,8]]},"2023":{"position":[[265,8],[563,8]]},"2059":{"position":[[724,8]]},"2146":{"position":[[16,8],[40,8]]},"2283":{"position":[[731,9]]},"2285":{"position":[[1443,8]]},"2289":{"position":[[177,8]]},"2291":{"position":[[90,9],[152,8],[229,8]]},"2295":{"position":[[279,8],[304,9]]},"2297":{"position":[[731,9]]},"2299":{"position":[[1443,8]]},"2303":{"position":[[177,8]]},"2305":{"position":[[90,9],[152,8],[229,8]]},"2309":{"position":[[279,8],[304,9]]},"2327":{"position":[[1007,9]]},"2337":{"position":[[227,8],[323,8],[598,9]]},"2339":{"position":[[770,8],[976,8],[1426,9]]},"2353":{"position":[[64,8]]},"2394":{"position":[[1007,9]]},"2404":{"position":[[227,8],[323,8],[598,9]]},"2406":{"position":[[770,8],[976,8],[1426,9]]},"2420":{"position":[[64,8]]},"2433":{"position":[[1250,8]]},"2451":{"position":[[456,8],[608,8]]},"2461":{"position":[[141,8]]},"2463":{"position":[[150,8]]},"2465":{"position":[[144,8]]},"2553":{"position":[[292,9],[309,8]]},"2602":{"position":[[1923,8]]},"2712":{"position":[[821,8],[969,8]]},"2716":{"position":[[822,8]]},"2812":{"position":[[90,10]]},"2958":{"position":[[2121,8]]},"2987":{"position":[[4209,8]]},"3230":{"position":[[830,8]]},"3264":{"position":[[618,8]]},"3266":{"position":[[115,8]]},"3313":{"position":[[54,8]]},"3352":{"position":[[3122,8]]},"3406":{"position":[[132,8]]},"3561":{"position":[[211,8]]},"3677":{"position":[[1119,8]]},"3742":{"position":[[682,9]]},"3791":{"position":[[1142,8]]},"3904":{"position":[[671,8]]},"3941":{"position":[[105,8]]},"4041":{"position":[[1070,9]]},"4165":{"position":[[546,8]]},"4279":{"position":[[790,8]]},"4291":{"position":[[215,8],[335,8]]},"4516":{"position":[[915,8]]},"4543":{"position":[[1200,9]]},"4643":{"position":[[1284,8],[1599,8],[1862,8],[2789,8]]},"4713":{"position":[[207,9]]},"4757":{"position":[[415,9]]}}}],["creativ",{"_index":1728,"t":{"249":{"position":[[1650,8]]}}}],["creator",{"_index":3076,"t":{"701":{"position":[[1119,7]]},"4062":{"position":[[233,7],[270,10]]},"4081":{"position":[[1462,8],[2196,7],[2302,7]]},"4085":{"position":[[173,7]]}}}],["creator':%(target.role.name)",{"_index":5713,"t":{"1324":{"position":[[6302,31]]}}}],["cred",{"_index":269,"t":{"28":{"position":[[1651,4]]}}}],["credenti",{"_index":416,"t":{"39":{"position":[[16,11],[47,11]]},"309":{"position":[[178,11],[271,12]]},"323":{"position":[[44,11]]},"368":{"position":[[2342,11],[2500,12],[3473,12]]},"526":{"position":[[307,11],[1056,11]]},"528":{"position":[[117,11],[250,11]]},"557":{"position":[[3868,11]]},"584":{"position":[[51,11]]},"701":{"position":[[261,11],[561,11],[669,11],[706,11],[792,11],[968,11],[1006,11],[1047,11],[1177,11],[1217,11],[1976,11],[2211,10]]},"705":{"position":[[307,11]]},"734":{"position":[[158,11]]},"753":{"position":[[236,11]]},"894":{"position":[[437,12]]},"930":{"position":[[339,11]]},"934":{"position":[[1078,11],[2393,11]]},"963":{"position":[[5127,11]]},"1407":{"position":[[1164,11]]},"1752":{"position":[[437,12]]},"1821":{"position":[[339,11]]},"1825":{"position":[[1078,11],[2393,11]]},"1854":{"position":[[5127,11]]},"2184":{"position":[[596,11],[1654,11],[1707,11],[1891,11],[1998,11],[2253,10]]},"2196":{"position":[[366,11],[749,12]]},"2238":{"position":[[7,11],[98,11]]},"2250":{"position":[[37,12],[242,11]]},"2431":{"position":[[819,11],[3864,11]]},"2531":{"position":[[610,12]]},"2563":{"position":[[124,10]]},"2584":{"position":[[158,11]]},"2602":{"position":[[507,12]]},"2604":{"position":[[259,11]]},"2616":{"position":[[190,12]]},"2647":{"position":[[362,11],[2749,12]]},"2659":{"position":[[186,12]]},"2676":{"position":[[223,12]]},"2908":{"position":[[603,12]]},"2910":{"position":[[377,12]]},"2954":{"position":[[339,11]]},"2958":{"position":[[1078,11],[2393,11]]},"2987":{"position":[[5127,11]]},"3067":{"position":[[602,11]]},"3119":{"position":[[1223,11]]},"3378":{"position":[[252,11]]},"3381":{"position":[[1592,10],[1884,10],[2128,10]]},"3384":{"position":[[253,10]]},"3460":{"position":[[194,11]]},"4171":{"position":[[403,11]]},"4535":{"position":[[554,11],[1196,11],[1229,11]]},"4539":{"position":[[3434,11],[5104,11],[7342,11]]},"4587":{"position":[[157,11]]},"4857":{"position":[[215,11],[408,11]]},"4863":{"position":[[173,11],[470,11]]},"4885":{"position":[[95,11]]}}}],["credentials.bash",{"_index":3244,"t":{"747":{"position":[[465,16]]}}}],["crestmont",{"_index":10587,"t":{"3712":{"position":[[1642,12]]}}}],["crhc4",{"_index":2950,"t":{"590":{"position":[[1249,5]]}}}],["criteria",{"_index":11243,"t":{"4171":{"position":[[269,8]]},"4261":{"position":[[530,8]]},"4263":{"position":[[55,8]]},"4376":{"position":[[108,8],[226,8]]},"4839":{"position":[[1138,8]]}}}],["critic",{"_index":1834,"t":{"280":{"position":[[84,8]]},"286":{"position":[[306,9],[596,8]]},"288":{"position":[[97,8],[484,8],[615,8],[947,9]]},"293":{"position":[[589,8]]},"295":{"position":[[1491,8],[1534,8]]},"541":{"position":[[194,8],[1032,8]]},"543":{"position":[[2329,9]]},"551":{"position":[[348,8],[3462,8]]},"1391":{"position":[[590,9]]},"1407":{"position":[[2646,8]]},"1409":{"position":[[1503,9]]},"2065":{"position":[[2417,9],[2435,8]]},"2139":{"position":[[519,8]]},"2478":{"position":[[589,12]]},"2485":{"position":[[54,8]]},"2501":{"position":[[284,8]]},"2506":{"position":[[288,8]]},"2512":{"position":[[32,8],[73,8],[1199,8],[1315,8]]},"2516":{"position":[[102,8]]},"2520":{"position":[[887,8]]},"2525":{"position":[[309,8],[379,8]]},"2879":{"position":[[230,8]]},"3346":{"position":[[987,8]]},"3829":{"position":[[1145,8],[2278,8],[2799,8],[5128,8]]},"3925":{"position":[[611,8]]},"3928":{"position":[[2167,8]]},"4257":{"position":[[5909,8]]},"4270":{"position":[[599,8]]},"4340":{"position":[[877,8]]},"4344":{"position":[[161,8]]},"4351":{"position":[[614,8]]},"4355":{"position":[[407,8],[441,8]]},"4535":{"position":[[140,8],[1341,8],[1537,8]]},"4547":{"position":[[348,8]]},"4703":{"position":[[141,8]]}}}],["critical_bug",{"_index":10838,"t":{"3829":{"position":[[1100,12]]}}}],["crl",{"_index":10656,"t":{"3731":{"position":[[2627,6]]}}}],["cron",{"_index":3479,"t":{"887":{"position":[[1324,4]]},"914":{"position":[[246,5]]},"1157":{"position":[[29,4]]},"1513":{"position":[[502,5],[588,5]]},"1694":{"position":[[3573,4]]},"1711":{"position":[[2857,4]]},"1798":{"position":[[246,5]]},"1811":{"position":[[1324,4]]},"2167":{"position":[[189,5],[275,5]]}}}],["cronjob",{"_index":6411,"t":{"1555":{"position":[[1039,7]]},"2565":{"position":[[53,7]]},"2567":{"position":[[134,7],[255,8],[452,7],[564,7],[953,8]]},"2569":{"position":[[250,8],[270,7]]},"3384":{"position":[[515,8]]},"4113":{"position":[[2027,7]]}}}],["cronjob.yaml",{"_index":8614,"t":{"2565":{"position":[[94,12]]},"2567":{"position":[[418,13]]},"2569":{"position":[[343,12]]}}}],["cronjob/configmap.yaml",{"_index":8615,"t":{"2567":{"position":[[3,23]]},"2569":{"position":[[216,22]]}}}],["cronjob/trivi",{"_index":8616,"t":{"2567":{"position":[[404,13]]},"2569":{"position":[[329,13]]}}}],["cross",{"_index":1250,"t":{"179":{"position":[[1254,5]]},"269":{"position":[[116,5],[142,5]]},"301":{"position":[[458,5]]},"3047":{"position":[[277,5]]},"3069":{"position":[[89,5]]},"3281":{"position":[[599,5]]},"4165":{"position":[[421,5],[1062,5]]},"4167":{"position":[[464,6]]},"4310":{"position":[[530,5]]},"4376":{"position":[[327,5]]},"4849":{"position":[[1390,5]]}}}],["crossplan",{"_index":8642,"t":{"2580":{"position":[[0,10],[355,10],[559,10],[666,10]]},"2582":{"position":[[252,10]]},"2584":{"position":[[857,10],[912,10],[1016,10],[1140,10]]},"2586":{"position":[[467,10],[522,10],[626,10],[750,10]]},"2600":{"position":[[93,10],[352,10]]},"2602":{"position":[[41,10],[220,10],[542,10],[705,10]]},"3288":{"position":[[307,10]]}}}],["crowd",{"_index":4057,"t":{"963":{"position":[[3410,7]]},"1854":{"position":[[3410,7]]},"2987":{"position":[[3410,7]]},"3894":{"position":[[516,7]]},"3898":{"position":[[469,7]]},"3900":{"position":[[543,7]]},"3902":{"position":[[378,7]]}}}],["crt",{"_index":4809,"t":{"1183":{"position":[[679,3]]},"1297":{"position":[[1916,3]]}}}],["crucial",{"_index":1845,"t":{"280":{"position":[[687,7],[1536,7]]},"282":{"position":[[289,7]]},"537":{"position":[[92,7]]},"638":{"position":[[131,10]]},"2487":{"position":[[1234,7]]},"2514":{"position":[[38,7]]},"2522":{"position":[[27,7]]},"2549":{"position":[[107,7]]},"2551":{"position":[[79,7]]},"3406":{"position":[[90,7]]},"4504":{"position":[[44,7]]},"4506":{"position":[[1221,7]]},"4560":{"position":[[707,7]]},"4562":{"position":[[288,7]]},"4701":{"position":[[57,7]]}}}],["crush",{"_index":6107,"t":{"1421":{"position":[[666,5]]},"1580":{"position":[[335,5],[534,5],[615,6],[652,5],[693,6]]},"1603":{"position":[[130,5],[259,5]]},"1605":{"position":[[695,5],[731,5],[1819,5],[1841,5],[1915,5]]},"1623":{"position":[[144,5]]},"1627":{"position":[[11,5]]},"1639":{"position":[[11,5],[83,5],[155,5]]},"1641":{"position":[[151,5]]},"1923":{"position":[[335,5],[534,5],[615,6],[652,5],[693,6]]},"1954":{"position":[[144,5]]},"1958":{"position":[[11,5]]},"1970":{"position":[[11,5],[83,5],[155,5]]},"1972":{"position":[[151,5]]},"4144":{"position":[[404,5]]}}}],["crush_rul",{"_index":6589,"t":{"1641":{"position":[[31,10]]},"1972":{"position":[[31,10]]}}}],["crush_rule_nam",{"_index":6574,"t":{"1631":{"position":[[65,19]]},"1962":{"position":[[258,19]]}}}],["crushroot",{"_index":6106,"t":{"1421":{"position":[[598,10]]}}}],["crypt",{"_index":8416,"t":{"2360":{"position":[[1775,5]]},"2427":{"position":[[1775,5]]}}}],["crypto",{"_index":11342,"t":{"4226":{"position":[[1958,6],[2562,6]]},"4244":{"position":[[480,6]]},"4246":{"position":[[469,6]]}}}],["cryptograph",{"_index":8349,"t":{"2319":{"position":[[722,13]]},"2386":{"position":[[722,13]]},"3761":{"position":[[1142,17]]},"4113":{"position":[[1078,13]]},"4304":{"position":[[1128,17]]}}}],["cryptographi",{"_index":10126,"t":{"3406":{"position":[[144,13]]},"3759":{"position":[[0,12]]},"4226":{"position":[[3347,12]]}}}],["cryptokey",{"_index":11354,"t":{"4226":{"position":[[3636,9]]}}}],["cryptpad",{"_index":11878,"t":{"4835":{"position":[[390,8]]},"4839":{"position":[[677,10]]},"4849":{"position":[[1615,9]]}}}],["cryptsetup",{"_index":8410,"t":{"2360":{"position":[[1494,10],[1997,10]]},"2427":{"position":[[1494,10],[1997,10]]}}}],["cs",{"_index":2933,"t":{"590":{"position":[[531,2],[600,2],[678,2],[942,2]]}}}],["cs_channel",{"_index":2884,"t":{"586":{"position":[[958,13]]}}}],["cs_channel=st",{"_index":2876,"t":{"586":{"position":[[490,17]]}}}],["cs_class_nam",{"_index":2907,"t":{"588":{"position":[[1290,16]]}}}],["cs_class_name=openstack",{"_index":2901,"t":{"588":{"position":[[421,23]]}}}],["cs_cloudname=openstack",{"_index":2877,"t":{"586":{"position":[[573,22]]}}}],["cs_cluster_nam",{"_index":2903,"t":{"588":{"position":[[915,18],[1694,18],[1951,18]]}}}],["cs_cluster_name=c",{"_index":2895,"t":{"588":{"position":[[77,18]]}}}],["cs_external_id",{"_index":2906,"t":{"588":{"position":[[1265,17]]}}}],["cs_external_id=ebfe5546",{"_index":2900,"t":{"588":{"position":[[353,23]]}}}],["cs_k8s_patch_version=6",{"_index":2902,"t":{"588":{"position":[[505,22]]}}}],["cs_k8s_version",{"_index":2883,"t":{"586":{"position":[[929,19]]},"588":{"position":[[458,20]]}}}],["cs_k8s_version=1.29",{"_index":2874,"t":{"586":{"position":[[339,19]]}}}],["cs_name",{"_index":2882,"t":{"586":{"position":[[899,10]]},"588":{"position":[[445,12]]}}}],["cs_name=sc",{"_index":2873,"t":{"586":{"position":[[206,11]]}}}],["cs_namespac",{"_index":2867,"t":{"584":{"position":[[487,17],[508,17]]},"586":{"position":[[851,15],[1297,15]]},"588":{"position":[[945,15],[1661,15],[1918,17]]}}}],["cs_namespace=mi",{"_index":2857,"t":{"582":{"position":[[7,15]]}}}],["cs_pod_cidr",{"_index":2904,"t":{"588":{"position":[[1040,14]]}}}],["cs_pod_cidr=192.168.0.0/16",{"_index":2897,"t":{"588":{"position":[[195,26]]}}}],["cs_secretnam",{"_index":2890,"t":{"586":{"position":[[1367,16]]}}}],["cs_secretname=\"${cs_cloudnam",{"_index":2878,"t":{"586":{"position":[[603,31]]}}}],["cs_service_cidr",{"_index":2905,"t":{"588":{"position":[[1108,18]]}}}],["cs_service_cidr=10.96.0.0/12",{"_index":2899,"t":{"588":{"position":[[317,28]]}}}],["cs_version",{"_index":2888,"t":{"586":{"position":[[1138,13]]},"588":{"position":[[482,15]]}}}],["cs_version=v1",{"_index":2875,"t":{"586":{"position":[[469,13]]}}}],["csctl",{"_index":2547,"t":{"514":{"position":[[1546,6],[1582,5],[1649,5],[1836,5],[1849,5]]},"526":{"position":[[668,6],[1411,6]]},"551":{"position":[[57,5]]},"560":{"position":[[6,5],[127,5]]},"566":{"position":[[5,7],[131,5]]},"568":{"position":[[28,6]]},"597":{"position":[[29,8]]},"604":{"position":[[423,5]]},"606":{"position":[[93,5],[307,6]]},"608":{"position":[[77,5]]},"611":{"position":[[175,5]]},"614":{"position":[[42,5],[208,5]]},"616":{"position":[[24,5],[133,5]]},"618":{"position":[[30,5]]},"620":{"position":[[43,6]]},"626":{"position":[[81,5]]},"628":{"position":[[665,5],[706,5],[742,6]]},"632":{"position":[[177,5]]},"638":{"position":[[259,5]]},"643":{"position":[[4,5]]},"653":{"position":[[43,5],[509,6],[518,5],[532,5]]},"655":{"position":[[207,5],[556,5]]},"657":{"position":[[312,5],[451,5]]},"659":{"position":[[91,5],[249,5]]},"661":{"position":[[21,5]]},"668":{"position":[[29,5],[407,5],[628,5],[731,5],[1043,5]]},"671":{"position":[[12,5],[800,5],[814,7]]},"673":{"position":[[207,5],[556,5]]},"675":{"position":[[4,5]]},"3223":{"position":[[1082,5]]},"3232":{"position":[[102,5]]},"3281":{"position":[[823,5],[855,5]]}}}],["csctl.clusterstack.x",{"_index":2971,"t":{"622":{"position":[[176,20]]},"661":{"position":[[113,20],[406,20]]}}}],["csctl.yaml",{"_index":2549,"t":{"514":{"position":[[1719,10]]},"622":{"position":[[37,10]]},"659":{"position":[[216,11]]},"661":{"position":[[54,11]]}}}],["csctl_0.0.2_linux_amd64",{"_index":2986,"t":{"653":{"position":[[118,23],[833,23]]}}}],["csctl_0.0.3_linux_amd64.tar.gz",{"_index":3004,"t":{"671":{"position":[[180,30]]}}}],["csctl__linux_amd64.tar.gz",{"_index":3011,"t":{"671":{"position":[[680,36],[755,34]]}}}],["csi",{"_index":2273,"t":{"378":{"position":[[806,3]]},"401":{"position":[[993,4]]},"590":{"position":[[1077,3],[1164,3],[1234,3],[1304,3],[1374,3]]},"696":{"position":[[845,5],[1379,3]]},"699":{"position":[[150,3],[392,3]]},"705":{"position":[[1308,3]]},"1405":{"position":[[962,3]]},"3185":{"position":[[269,3]]},"4146":{"position":[[770,3]]},"4376":{"position":[[292,3]]},"4849":{"position":[[904,4],[932,4]]}}}],["csi:v0.4.2",{"_index":3103,"t":{"705":{"position":[[737,10]]}}}],["csmctl",{"_index":2489,"t":{"489":{"position":[[113,6],[1141,7],[1160,7],[1233,6]]}}}],["cso",{"_index":2442,"t":{"475":{"position":[[38,3],[68,3],[409,3],[420,3],[741,3],[748,3]]},"491":{"position":[[607,3]]},"493":{"position":[[13,3],[33,3]]},"500":{"position":[[82,5],[562,3]]},"572":{"position":[[75,5]]},"578":{"position":[[4,3],[190,3]]},"580":{"position":[[107,3],[208,3],[238,3],[296,3],[326,3]]},"3357":{"position":[[818,4]]}}}],["csp",{"_index":144,"t":{"19":{"position":[[234,3]]},"584":{"position":[[4,3],[476,3],[594,3],[640,3]]},"2431":{"position":[[20,4]]},"2435":{"position":[[131,4]]},"2439":{"position":[[423,4],[590,4],[709,4]]},"2449":{"position":[[53,3]]},"2453":{"position":[[84,3],[220,4]]},"2463":{"position":[[597,4]]},"2467":{"position":[[211,4],[383,3]]},"2497":{"position":[[78,5]]},"2501":{"position":[[257,4]]},"2506":{"position":[[10,6]]},"2522":{"position":[[56,5]]},"2602":{"position":[[339,3],[948,3]]},"2618":{"position":[[109,3],[154,3],[350,3]]},"3288":{"position":[[174,4]]},"3290":{"position":[[633,4]]},"3296":{"position":[[1247,5],[1263,3],[1289,3]]},"3835":{"position":[[1289,3]]},"3998":{"position":[[4,3]]},"4060":{"position":[[865,4]]},"4068":{"position":[[181,4]]},"4075":{"position":[[191,3]]},"4077":{"position":[[308,4]]},"4079":{"position":[[79,4],[435,4]]},"4081":{"position":[[1033,4]]},"4083":{"position":[[53,4],[286,4]]},"4089":{"position":[[393,3]]},"4096":{"position":[[266,3]]},"4100":{"position":[[104,4],[565,3]]},"4102":{"position":[[308,4]]},"4107":{"position":[[975,4],[1036,4],[1073,4],[1266,4],[1454,4],[1601,4],[1776,4],[1986,4]]},"4109":{"position":[[4002,4]]},"4118":{"position":[[13,3]]},"4124":{"position":[[1661,3],[2135,3]]},"4153":{"position":[[266,4]]},"4155":{"position":[[829,3]]},"4157":{"position":[[494,4],[1175,4]]},"4159":{"position":[[1460,4]]},"4161":{"position":[[311,5],[384,4]]},"4163":{"position":[[682,5],[4434,4]]},"4165":{"position":[[1048,4],[1086,4]]},"4178":{"position":[[146,3]]},"4182":{"position":[[175,3]]},"4187":{"position":[[503,4]]},"4189":{"position":[[245,3],[277,3],[421,4],[480,4],[638,4]]},"4191":{"position":[[40,4],[114,4]]},"4198":{"position":[[45,5]]},"4202":{"position":[[532,4]]},"4206":{"position":[[427,3]]},"4217":{"position":[[13,3],[260,3]]},"4220":{"position":[[50,4],[182,4],[491,3],[614,3]]},"4222":{"position":[[234,3],[313,3]]},"4249":{"position":[[478,4]]},"4251":{"position":[[17,3]]},"4257":{"position":[[197,4],[1195,3],[2114,4],[2249,4],[3238,4],[3612,4],[3676,4],[3906,4],[4172,4],[4557,4],[4647,4],[5040,4],[5258,4],[5761,4]]},"4259":{"position":[[293,3]]},"4261":{"position":[[404,4]]},"4266":{"position":[[156,4],[488,4]]},"4268":{"position":[[325,3],[665,3]]},"4270":{"position":[[186,4],[409,4],[745,4]]},"4296":{"position":[[38,3]]},"4298":{"position":[[534,3]]},"4300":{"position":[[244,4],[538,3]]},"4302":{"position":[[3209,3]]},"4310":{"position":[[234,4],[623,4],[725,4],[930,4],[1261,4],[2512,4]]},"4315":{"position":[[180,3],[346,4]]},"4362":{"position":[[109,3],[397,3]]},"4410":{"position":[[557,5]]},"4412":{"position":[[30,4]]},"4414":{"position":[[174,5],[199,3],[333,4]]},"4464":{"position":[[176,4]]},"4556":{"position":[[30,4]]},"4562":{"position":[[1502,4],[2150,5],[5374,3]]},"4574":{"position":[[173,3]]},"4580":{"position":[[1142,3],[1498,3],[3319,4],[3495,3]]},"4582":{"position":[[0,4],[120,4],[342,4],[493,4]]},"4587":{"position":[[50,4],[313,3]]},"4606":{"position":[[553,3],[672,3]]},"4612":{"position":[[480,3],[651,3]]},"4618":{"position":[[1063,3]]},"4632":{"position":[[1164,4],[1351,3],[1558,4],[1830,3],[1959,3]]},"4637":{"position":[[5,4]]},"4660":{"position":[[550,4],[1894,3],[2248,3],[2613,3]]},"4662":{"position":[[61,3]]},"4667":{"position":[[13366,3],[14241,3],[14658,4]]},"4669":{"position":[[627,3]]},"4724":{"position":[[540,3]]},"4726":{"position":[[65,3],[709,3],[967,3]]},"4728":{"position":[[582,4],[662,3]]},"4733":{"position":[[65,3],[1695,3],[1749,3]]},"4736":{"position":[[135,5]]},"4755":{"position":[[135,5]]},"4763":{"position":[[252,3]]}}}],["csp'",{"_index":9921,"t":{"3290":{"position":[[850,5]]},"4587":{"position":[[213,5]]},"4669":{"position":[[936,5]]}}}],["cspo",{"_index":2525,"t":{"496":{"position":[[106,4]]},"500":{"position":[[37,6],[217,4]]},"518":{"position":[[76,4]]},"572":{"position":[[128,6]]},"578":{"position":[[12,4],[198,4]]},"580":{"position":[[98,4],[524,4],[555,4],[614,4],[645,4]]},"3357":{"position":[[823,4]]}}}],["cspotempl",{"_index":2887,"t":{"586":{"position":[[1113,12],[1273,12]]}}}],["csr",{"_index":11542,"t":{"4473":{"position":[[214,3]]},"4485":{"position":[[2160,3],[2273,4],[2322,3],[2354,5],[2524,3],[2550,3],[2586,3],[2657,3]]}}}],["css",{"_index":9321,"t":{"2930":{"position":[[1690,3]]},"2932":{"position":[[188,3]]}}}],["cstate",{"_index":11790,"t":{"4662":{"position":[[26,6]]}}}],["csum=\"tru",{"_index":7009,"t":{"1702":{"position":[[386,13],[544,13]]},"1704":{"position":[[1162,13],[1288,13],[1414,13]]}}}],["csv",{"_index":11611,"t":{"4539":{"position":[[1917,3]]}}}],["ctl",{"_index":2959,"t":{"597":{"position":[[77,4]]},"4230":{"position":[[2769,3],[3112,3],[4784,3],[5360,3]]}}}],["ctl1",{"_index":5496,"t":{"1301":{"position":[[613,5],[1072,6]]}}}],["ctl2",{"_index":5497,"t":{"1301":{"position":[[619,4]]}}}],["ctl3",{"_index":5498,"t":{"1301":{"position":[[628,5]]}}}],["cto",{"_index":1084,"t":{"171":{"position":[[1182,5]]}}}],["ctr",{"_index":3791,"t":{"932":{"position":[[2870,4]]},"1823":{"position":[[2870,4]]},"2956":{"position":[[2870,4]]}}}],["ctr+=1",{"_index":3799,"t":{"932":{"position":[[3159,6]]},"1823":{"position":[[3159,6]]},"2956":{"position":[[3159,6]]}}}],["ctr=0",{"_index":3789,"t":{"932":{"position":[[2851,5]]},"1823":{"position":[[2851,5]]},"2956":{"position":[[2851,5]]}}}],["ctrl",{"_index":10078,"t":{"3381":{"position":[[1909,4],[2157,4]]}}}],["ctrl+c",{"_index":7901,"t":{"2190":{"position":[[285,6]]}}}],["ctxt.tenant_id",{"_index":9576,"t":{"3036":{"position":[[7853,14]]}}}],["ctxt.trustor_user_id",{"_index":9487,"t":{"3036":{"position":[[4646,24]]}}}],["ctxt.user_id",{"_index":9488,"t":{"3036":{"position":[[4671,15],[4866,12],[7820,12]]}}}],["cu",{"_index":10601,"t":{"3714":{"position":[[586,5]]},"3744":{"position":[[2152,2],[2211,3],[2538,3],[2571,3]]}}}],["cuda",{"_index":10666,"t":{"3744":{"position":[[324,4],[380,4],[432,4],[707,4],[767,4],[1336,4],[1394,4],[1635,4],[1702,4]]}}}],["cultiv",{"_index":522,"t":{"72":{"position":[[140,9]]}}}],["cultur",{"_index":1430,"t":{"199":{"position":[[440,8]]},"2489":{"position":[[1041,8],[1114,7]]}}}],["cumbersom",{"_index":2955,"t":{"595":{"position":[[57,10]]}}}],["cup",{"_index":1674,"t":{"237":{"position":[[328,5]]}}}],["curat",{"_index":542,"t":{"74":{"position":[[3,6]]},"264":{"position":[[251,7]]},"3130":{"position":[[904,7]]},"3361":{"position":[[67,7]]}}}],["cure",{"_index":1117,"t":{"173":{"position":[[698,4],[837,4]]},"181":{"position":[[2234,4]]}}}],["curl",{"_index":2443,"t":{"475":{"position":[[82,4]]},"580":{"position":[[340,4],[660,4]]},"686":{"position":[[255,4]]},"745":{"position":[[280,4]]},"751":{"position":[[255,4]]},"930":{"position":[[802,4]]},"955":{"position":[[97,4]]},"961":{"position":[[394,4],[399,4],[542,4]]},"1144":{"position":[[354,4]]},"1443":{"position":[[1094,4]]},"1564":{"position":[[2,4]]},"1566":{"position":[[2,4]]},"1821":{"position":[[802,4]]},"1846":{"position":[[97,4]]},"1852":{"position":[[394,4],[399,4],[542,4]]},"2626":{"position":[[1112,4],[1903,4],[2140,4],[2603,4]]},"2649":{"position":[[1615,4],[1909,4]]},"2760":{"position":[[2,4]]},"2762":{"position":[[2,4]]},"2764":{"position":[[2,4]]},"2766":{"position":[[2,4]]},"2768":{"position":[[2,4]]},"2770":{"position":[[2,4]]},"2772":{"position":[[0,4]]},"2774":{"position":[[2,4]]},"2776":{"position":[[2,4]]},"2778":{"position":[[0,4]]},"2780":{"position":[[2,4]]},"2782":{"position":[[2,4]]},"2784":{"position":[[2,4]]},"2786":{"position":[[2,4]]},"2788":{"position":[[2,4]]},"2790":{"position":[[2,4]]},"2792":{"position":[[2,4]]},"2855":{"position":[[82,4]]},"2904":{"position":[[99,5],[152,5]]},"2908":{"position":[[60,4]]},"2910":{"position":[[105,4]]},"2954":{"position":[[802,4]]},"2979":{"position":[[97,4]]},"2985":{"position":[[394,4],[399,4],[542,4]]}}}],["currect",{"_index":8322,"t":{"2281":{"position":[[137,7]]}}}],["currenc",{"_index":2080,"t":{"323":{"position":[[952,8]]}}}],["current",{"_index":125,"t":{"17":{"position":[[76,9]]},"66":{"position":[[32,9]]},"293":{"position":[[316,7]]},"297":{"position":[[335,7]]},"311":{"position":[[468,9]]},"317":{"position":[[209,9]]},"319":{"position":[[181,9],[900,9],[976,9]]},"321":{"position":[[324,9]]},"323":{"position":[[1635,9]]},"341":{"position":[[9,7]]},"366":{"position":[[130,10]]},"468":{"position":[[0,10]]},"502":{"position":[[47,7]]},"520":{"position":[[298,9]]},"530":{"position":[[406,9],[655,10],[2743,9]]},"595":{"position":[[4,7],[120,7],[238,10],[717,10]]},"661":{"position":[[369,10]]},"732":{"position":[[325,9]]},"880":{"position":[[159,7],[176,10]]},"887":{"position":[[830,7],[891,7],[2493,7],[3376,7],[4314,7],[5690,7],[6533,7],[7343,7],[8119,7]]},"944":{"position":[[218,7],[415,7],[523,7],[905,7]]},"946":{"position":[[729,9]]},"978":{"position":[[1005,7]]},"1252":{"position":[[3572,9]]},"1257":{"position":[[1629,7]]},"1259":{"position":[[723,7]]},"1324":{"position":[[15,9],[73,9]]},"1371":{"position":[[197,9]]},"1385":{"position":[[2217,9]]},"1391":{"position":[[3393,9]]},"1407":{"position":[[62,9],[137,7]]},"1423":{"position":[[197,9]]},"1439":{"position":[[32,9]]},"1441":{"position":[[135,9]]},"1451":{"position":[[92,9]]},"1457":{"position":[[3264,9]]},"1462":{"position":[[136,10]]},"1484":{"position":[[328,9]]},"1523":{"position":[[1368,9],[2169,7],[2200,7]]},"1555":{"position":[[924,9]]},"1571":{"position":[[4,7]]},"1574":{"position":[[170,7]]},"1688":{"position":[[128,9]]},"1692":{"position":[[188,9]]},"1736":{"position":[[296,7],[794,7]]},"1781":{"position":[[159,7],[176,10]]},"1811":{"position":[[830,7],[891,7],[2493,7],[3376,7],[4314,7],[5690,7],[6533,7],[7343,7],[8119,7]]},"1835":{"position":[[218,7],[415,7],[523,7],[905,7]]},"1837":{"position":[[729,9]]},"1869":{"position":[[1005,7]]},"1904":{"position":[[4,7]]},"1917":{"position":[[170,7]]},"2011":{"position":[[21,7]]},"2032":{"position":[[11,9],[255,9]]},"2055":{"position":[[0,9]]},"2102":{"position":[[49,7]]},"2130":{"position":[[185,7]]},"2139":{"position":[[289,9]]},"2163":{"position":[[4412,9]]},"2171":{"position":[[1769,7]]},"2182":{"position":[[194,7]]},"2184":{"position":[[1437,9]]},"2188":{"position":[[29,9]]},"2196":{"position":[[616,9]]},"2219":{"position":[[472,9],[537,9]]},"2225":{"position":[[27,9]]},"2272":{"position":[[87,7]]},"2370":{"position":[[0,9]]},"2372":{"position":[[343,9]]},"2380":{"position":[[9,9],[317,9],[458,9]]},"2382":{"position":[[0,9]]},"2439":{"position":[[33,9]]},"2451":{"position":[[117,9]]},"2501":{"position":[[65,7]]},"2632":{"position":[[0,10]]},"2638":{"position":[[158,9]]},"2649":{"position":[[46,9]]},"2747":{"position":[[265,7]]},"2845":{"position":[[0,9]]},"2898":{"position":[[257,9],[325,9]]},"2916":{"position":[[189,7]]},"2968":{"position":[[218,7],[415,7],[523,7],[905,7]]},"2970":{"position":[[729,9]]},"3002":{"position":[[1005,7]]},"3022":{"position":[[87,9]]},"3052":{"position":[[734,9]]},"3097":{"position":[[346,9]]},"3119":{"position":[[628,7]]},"3130":{"position":[[535,9]]},"3159":{"position":[[143,7]]},"3162":{"position":[[431,10],[517,10],[626,10]]},"3230":{"position":[[485,9]]},"3234":{"position":[[261,9]]},"3244":{"position":[[391,9]]},"3248":{"position":[[546,9]]},"3257":{"position":[[71,7]]},"3285":{"position":[[552,9]]},"3290":{"position":[[387,9]]},"3296":{"position":[[323,7]]},"3361":{"position":[[732,9]]},"3460":{"position":[[535,7]]},"3539":{"position":[[252,7]]},"3582":{"position":[[648,9]]},"3613":{"position":[[152,7]]},"3690":{"position":[[1541,9]]},"3718":{"position":[[454,10]]},"3731":{"position":[[1124,7],[1893,9]]},"3747":{"position":[[181,11]]},"3763":{"position":[[825,9],[858,7]]},"3777":{"position":[[1642,9]]},"3811":{"position":[[454,10]]},"3879":{"position":[[474,9]]},"3925":{"position":[[4,9],[968,9]]},"3930":{"position":[[697,7]]},"3945":{"position":[[244,9]]},"3947":{"position":[[216,9],[429,10]]},"4019":{"position":[[0,10]]},"4028":{"position":[[432,9]]},"4045":{"position":[[975,7]]},"4077":{"position":[[203,9]]},"4081":{"position":[[1756,9]]},"4098":{"position":[[520,10]]},"4144":{"position":[[4,7],[499,7]]},"4146":{"position":[[1341,7],[2430,9]]},"4150":{"position":[[230,9]]},"4163":{"position":[[5019,7]]},"4165":{"position":[[1076,9]]},"4185":{"position":[[252,7]]},"4226":{"position":[[953,7]]},"4230":{"position":[[3831,9],[4332,9]]},"4240":{"position":[[575,9]]},"4257":{"position":[[15,7],[1418,7]]},"4259":{"position":[[818,7]]},"4261":{"position":[[504,7]]},"4263":{"position":[[29,7]]},"4273":{"position":[[252,7]]},"4291":{"position":[[1313,9]]},"4302":{"position":[[3509,9],[5103,9]]},"4337":{"position":[[140,9]]},"4359":{"position":[[202,9]]},"4382":{"position":[[3,9]]},"4418":{"position":[[295,9]]},"4433":{"position":[[2068,9]]},"4459":{"position":[[1027,7]]},"4466":{"position":[[0,10],[224,7]]},"4483":{"position":[[606,7]]},"4535":{"position":[[1962,7]]},"4539":{"position":[[3667,7]]},"4543":{"position":[[1026,7]]},"4560":{"position":[[5074,9]]},"4562":{"position":[[1832,9],[1973,11]]},"4569":{"position":[[911,7]]},"4580":{"position":[[1975,9],[2469,9]]},"4591":{"position":[[490,9]]},"4593":{"position":[[2334,9],[5705,10],[6040,9],[6071,9]]},"4597":{"position":[[511,7],[574,9],[729,9],[801,9]]},"4643":{"position":[[2651,9]]},"4707":{"position":[[290,7]]},"4709":{"position":[[156,9],[320,10]]},"4724":{"position":[[0,10]]},"4742":{"position":[[711,9]]}}}],["custom",{"_index":500,"t":{"70":{"position":[[52,9],[362,9]]},"311":{"position":[[180,8],[373,8]]},"321":{"position":[[135,8],[218,8],[263,8],[455,8]]},"323":{"position":[[1073,8]]},"370":{"position":[[706,9],[815,10]]},"372":{"position":[[348,10]]},"382":{"position":[[179,6]]},"384":{"position":[[105,6]]},"391":{"position":[[145,6]]},"397":{"position":[[70,6]]},"403":{"position":[[216,6]]},"411":{"position":[[167,6]]},"417":{"position":[[68,6]]},"427":{"position":[[273,6],[359,6],[410,6]]},"434":{"position":[[867,6],[1884,6]]},"454":{"position":[[87,6]]},"512":{"position":[[712,6]]},"543":{"position":[[1315,14]]},"553":{"position":[[20,6]]},"638":{"position":[[4,6]]},"645":{"position":[[216,6]]},"651":{"position":[[4,6]]},"677":{"position":[[216,6]]},"683":{"position":[[4,6]]},"814":{"position":[[511,9]]},"816":{"position":[[343,11]]},"854":{"position":[[368,8]]},"887":{"position":[[920,9]]},"1042":{"position":[[309,8],[666,9]]},"1056":{"position":[[1489,14],[1583,6],[1759,6]]},"1064":{"position":[[1970,14],[2020,13]]},"1142":{"position":[[64,6]]},"1185":{"position":[[1777,6],[1803,6]]},"1248":{"position":[[60,6],[245,6],[510,6],[524,6],[903,6],[1084,6],[1226,6],[1457,6]]},"1252":{"position":[[771,6],[1475,6],[1588,6],[3414,6]]},"1314":{"position":[[308,6]]},"1316":{"position":[[39,6],[130,6],[207,6],[459,6],[609,6]]},"1385":{"position":[[599,6]]},"1421":{"position":[[609,7]]},"1443":{"position":[[155,6],[184,6],[610,6],[781,6]]},"1464":{"position":[[991,6]]},"1468":{"position":[[403,14]]},"1525":{"position":[[922,6]]},"1561":{"position":[[9,6],[1113,6]]},"1657":{"position":[[104,6]]},"1661":{"position":[[0,6],[526,6],[759,6],[1014,6]]},"1663":{"position":[[71,6],[195,6],[211,6]]},"1694":{"position":[[3826,6],[3961,6],[4096,6],[4231,6]]},"1811":{"position":[[920,9]]},"1996":{"position":[[200,9]]},"2076":{"position":[[272,14]]},"2188":{"position":[[415,6]]},"2192":{"position":[[59,9]]},"2366":{"position":[[182,8],[375,8]]},"2372":{"position":[[17,8]]},"2433":{"position":[[151,8],[240,8],[344,8],[587,8],[1116,8]]},"2506":{"position":[[132,8]]},"2539":{"position":[[560,7]]},"2549":{"position":[[464,6]]},"2551":{"position":[[348,6]]},"2553":{"position":[[276,6]]},"2555":{"position":[[352,14]]},"2559":{"position":[[588,13],[626,14]]},"2567":{"position":[[1429,9],[1519,9],[1815,9]]},"2578":{"position":[[394,8]]},"2598":{"position":[[588,13],[626,14]]},"2612":{"position":[[121,6]]},"2614":{"position":[[233,9],[292,6]]},"2624":{"position":[[698,6]]},"2649":{"position":[[1494,6]]},"2655":{"position":[[522,6]]},"2749":{"position":[[220,9]]},"2887":{"position":[[97,10]]},"3172":{"position":[[97,6]]},"3185":{"position":[[817,6]]},"3225":{"position":[[719,6],[802,6]]},"3227":{"position":[[34,6]]},"3234":{"position":[[116,9]]},"3236":{"position":[[39,10],[116,9]]},"3238":{"position":[[41,8],[391,8],[489,8],[512,8]]},"3248":{"position":[[383,8]]},"3268":{"position":[[201,6],[236,9]]},"3285":{"position":[[149,6],[218,6]]},"3288":{"position":[[367,9]]},"3290":{"position":[[544,6]]},"3313":{"position":[[294,9]]},"3352":{"position":[[524,10]]},"3367":{"position":[[411,9],[567,9],[649,9],[913,9],[978,9],[1170,9]]},"3398":{"position":[[1891,8]]},"3460":{"position":[[155,9]]},"3470":{"position":[[841,9]]},"3516":{"position":[[252,8]]},"3565":{"position":[[207,6]]},"3573":{"position":[[773,6]]},"3592":{"position":[[748,10]]},"3606":{"position":[[1320,9]]},"3653":{"position":[[134,8],[957,10]]},"3681":{"position":[[262,8],[288,9],[441,9],[1198,9]]},"3690":{"position":[[134,8],[856,10]]},"3693":{"position":[[45,9]]},"3706":{"position":[[500,9],[999,9]]},"3718":{"position":[[262,8],[288,9],[441,9],[1225,9]]},"3777":{"position":[[134,8],[957,10]]},"3780":{"position":[[45,9]]},"3799":{"position":[[500,9],[999,9]]},"3811":{"position":[[262,8],[288,9],[441,9],[1202,9]]},"3815":{"position":[[709,9]]},"3835":{"position":[[166,9],[844,8],[995,9],[1477,8],[1804,8]]},"3892":{"position":[[134,8]]},"3923":{"position":[[512,9]]},"3984":{"position":[[495,9],[808,9],[1412,9]]},"3988":{"position":[[637,6],[1641,9]]},"3994":{"position":[[346,9]]},"4041":{"position":[[229,6],[631,6],[847,6]]},"4047":{"position":[[283,6],[419,6]]},"4051":{"position":[[534,6]]},"4079":{"position":[[194,10]]},"4081":{"position":[[1535,8]]},"4100":{"position":[[579,8]]},"4107":{"position":[[1889,9]]},"4120":{"position":[[575,9]]},"4126":{"position":[[267,10]]},"4130":{"position":[[919,10]]},"4157":{"position":[[375,9],[676,9],[1035,9]]},"4159":{"position":[[1035,9]]},"4163":{"position":[[1801,9],[1853,9],[1960,9],[3622,9],[4581,9]]},"4165":{"position":[[713,9]]},"4189":{"position":[[253,9]]},"4217":{"position":[[232,8]]},"4220":{"position":[[439,10],[622,8],[727,8]]},"4222":{"position":[[26,8]]},"4226":{"position":[[286,8]]},"4230":{"position":[[4613,13]]},"4238":{"position":[[411,6]]},"4257":{"position":[[2777,9]]},"4281":{"position":[[167,10]]},"4291":{"position":[[1404,6]]},"4294":{"position":[[236,10]]},"4298":{"position":[[174,9],[736,8]]},"4300":{"position":[[639,8]]},"4302":{"position":[[3775,8]]},"4329":{"position":[[33,9]]},"4378":{"position":[[69,9]]},"4403":{"position":[[68,9]]},"4414":{"position":[[161,9]]},"4429":{"position":[[155,9]]},"4431":{"position":[[2148,9]]},"4433":{"position":[[2838,9]]},"4435":{"position":[[1354,9]]},"4442":{"position":[[131,9]]},"4453":{"position":[[131,9]]},"4525":{"position":[[148,9]]},"4539":{"position":[[6145,8],[6790,6]]},"4547":{"position":[[2290,9]]},"4562":{"position":[[4376,9],[5324,8]]},"4578":{"position":[[77,6]]},"4587":{"position":[[84,9],[287,9],[476,8],[504,8],[638,9]]},"4591":{"position":[[93,9],[387,8]]},"4593":{"position":[[2263,9],[3749,9],[3811,11],[3844,11],[4390,8],[4522,8],[4637,9],[5765,6],[6094,6],[6206,8],[6246,9]]},"4604":{"position":[[70,9],[193,8]]},"4608":{"position":[[501,9],[922,9]]},"4610":{"position":[[180,9],[457,8]]},"4632":{"position":[[1790,9],[1918,9],[2366,9]]},"4637":{"position":[[30,8]]},"4643":{"position":[[38,9],[296,8],[433,8],[607,10],[2439,8],[2473,9],[2511,9],[2539,9],[2592,8],[2738,8],[2827,9],[2876,9],[2942,9],[3134,9],[3469,8]]},"4654":{"position":[[100,10]]},"4662":{"position":[[942,8]]},"4667":{"position":[[14495,8],[14788,8]]},"4669":{"position":[[151,9],[535,9]]},"4722":{"position":[[57,9],[177,9]]},"4724":{"position":[[445,8],[573,8]]},"4726":{"position":[[779,9],[838,8]]},"4728":{"position":[[268,8],[396,8],[436,9],[723,8],[825,8],[983,8]]},"4733":{"position":[[282,9],[495,8],[545,8],[710,8],[1714,8],[1814,8]]},"4738":{"position":[[269,9]]},"4744":{"position":[[1027,6],[1057,6]]},"4746":{"position":[[319,6]]},"4757":{"position":[[335,9]]},"4759":{"position":[[313,8]]},"4791":{"position":[[446,8]]},"4793":{"position":[[109,8]]},"4826":{"position":[[2360,8],[3632,9]]},"4875":{"position":[[68,6]]}}}],["custom.crt",{"_index":4514,"t":{"1142":{"position":[[227,10]]},"1248":{"position":[[690,10]]}}}],["custom_them",{"_index":5651,"t":{"1316":{"position":[[420,12],[644,14],[739,14]]}}}],["customer/us",{"_index":11270,"t":{"4220":{"position":[[16,13]]}}}],["customera",{"_index":8461,"t":{"2433":{"position":[[609,9],[864,9]]}}}],["customis",{"_index":4574,"t":{"1167":{"position":[[396,11]]},"1314":{"position":[[151,11]]},"1433":{"position":[[456,9]]},"2071":{"position":[[2094,10]]},"2199":{"position":[[481,13],[514,13]]},"2211":{"position":[[688,9]]},"2219":{"position":[[44,9],[1089,15]]}}}],["customisation:external_api",{"_index":7969,"t":{"2199":{"position":[[652,26]]}}}],["customiz",{"_index":6169,"t":{"1441":{"position":[[30,12]]},"1443":{"position":[[105,12]]},"2482":{"position":[[541,12]]},"3573":{"position":[[369,12]]}}}],["customization.yaml.gotmpl",{"_index":11890,"t":{"4835":{"position":[[1383,25]]}}}],["customthem",{"_index":5652,"t":{"1316":{"position":[[440,11]]}}}],["cut",{"_index":2384,"t":{"440":{"position":[[155,4]]},"442":{"position":[[131,3]]},"3259":{"position":[[553,3]]},"4459":{"position":[[1934,4]]}}}],["cut'n'past",{"_index":3827,"t":{"934":{"position":[[1686,13]]},"1825":{"position":[[1686,13]]},"2958":{"position":[[1686,13]]}}}],["cutleri",{"_index":1676,"t":{"237":{"position":[[343,8]]}}}],["cutoff",{"_index":10858,"t":{"3833":{"position":[[221,6],[250,6],[344,6]]}}}],["cve",{"_index":1960,"t":{"301":{"position":[[224,3]]},"1312":{"position":[[90,4]]},"2535":{"position":[[342,4]]},"3164":{"position":[[155,3],[173,3],[263,3]]},"3202":{"position":[[164,4],[270,4]]},"3306":{"position":[[328,4],[421,4]]},"4257":{"position":[[5064,4]]},"4340":{"position":[[765,4]]},"4344":{"position":[[170,4]]},"4351":{"position":[[502,4]]},"4355":{"position":[[416,5],[450,3],[459,3],[542,3]]},"4656":{"position":[[988,4]]}}}],["cvss",{"_index":10325,"t":{"3661":{"position":[[717,4]]},"3698":{"position":[[827,4]]},"3785":{"position":[[812,4]]},"3829":{"position":[[2860,4]]},"4257":{"position":[[5918,5],[5952,5],[5983,5],[6015,5]]},"4270":{"position":[[608,5],[642,5],[673,5],[705,5]]},"4344":{"position":[[175,5]]},"4355":{"position":[[470,4],[508,4]]}}}],["cvssv3.1",{"_index":11491,"t":{"4355":{"position":[[560,10]]}}}],["cyber",{"_index":8528,"t":{"2487":{"position":[[408,5]]},"4096":{"position":[[942,5]]},"4107":{"position":[[729,5]]},"4109":{"position":[[4359,5],[4456,5],[4973,5]]},"4133":{"position":[[1564,5],[1656,5]]},"4135":{"position":[[70,5]]},"4137":{"position":[[200,5]]}}}],["cyborg_api_port",{"_index":5352,"t":{"1295":{"position":[[749,16]]}}}],["cyborg_external_fqdn",{"_index":5351,"t":{"1295":{"position":[[699,20]]}}}],["cyborg_public_endpoint",{"_index":5350,"t":{"1295":{"position":[[676,22]]}}}],["cycl",{"_index":2103,"t":{"339":{"position":[[323,5]]},"551":{"position":[[1735,7],[3428,7]]},"938":{"position":[[439,5]]},"1073":{"position":[[90,5],[362,5]]},"1468":{"position":[[343,5]]},"1829":{"position":[[439,5]]},"2520":{"position":[[309,5]]},"2962":{"position":[[439,5]]},"3121":{"position":[[179,6]]},"3148":{"position":[[622,5]]},"3164":{"position":[[37,6]]},"3202":{"position":[[37,6]]},"3246":{"position":[[26,5]]},"3266":{"position":[[753,6]]},"3272":{"position":[[97,6]]},"3279":{"position":[[304,5]]},"3306":{"position":[[26,5]]},"3321":{"position":[[46,5]]},"3761":{"position":[[108,6]]},"3791":{"position":[[1654,7]]},"3904":{"position":[[1185,7]]},"4257":{"position":[[324,5],[4598,5]]},"4340":{"position":[[307,7]]},"4351":{"position":[[733,5]]},"4353":{"position":[[80,6]]},"4506":{"position":[[1009,7],[1078,7]]}}}],["cyclondx",{"_index":8661,"t":{"2590":{"position":[[203,8]]}}}],["czvf",{"_index":7749,"t":{"2155":{"position":[[458,4]]}}}],["d",{"_index":1723,"t":{"249":{"position":[[925,3]]},"481":{"position":[[370,1],[401,4]]},"932":{"position":[[1776,1]]},"938":{"position":[[902,1]]},"942":{"position":[[2308,1],[2392,1]]},"1111":{"position":[[472,1]]},"1391":{"position":[[364,2]]},"1472":{"position":[[3318,2],[3397,1]]},"1688":{"position":[[350,1]]},"1696":{"position":[[232,1]]},"1730":{"position":[[131,1]]},"1823":{"position":[[1776,1]]},"1829":{"position":[[902,1]]},"1833":{"position":[[2308,1],[2392,1]]},"1986":{"position":[[230,1]]},"1996":{"position":[[122,2]]},"2626":{"position":[[1198,1]]},"2762":{"position":[[107,1]]},"2766":{"position":[[109,1]]},"2772":{"position":[[105,1]]},"2778":{"position":[[105,1]]},"2784":{"position":[[107,1]]},"2790":{"position":[[107,1]]},"2908":{"position":[[137,1],[170,1],[205,1],[229,1],[287,1]]},"2910":{"position":[[210,1]]},"2956":{"position":[[1776,1]]},"2962":{"position":[[902,1]]},"2966":{"position":[[2308,1],[2392,1]]},"3381":{"position":[[1914,2],[2162,2]]},"4857":{"position":[[276,1],[468,1]]}}}],["d${alia",{"_index":11762,"t":{"4643":{"position":[[3022,9]]}}}],["d000001",{"_index":11753,"t":{"4643":{"position":[[1366,7]]}}}],["d0b0add9ede0452791f71cb900e35242",{"_index":4246,"t":{"995":{"position":[[2467,32]]},"1886":{"position":[[2467,32]]}}}],["d199",{"_index":6660,"t":{"1659":{"position":[[76,4],[210,4]]}}}],["d33b0d15fd474131a335207216297a2a",{"_index":4213,"t":{"995":{"position":[[1850,32],[2907,32],[2942,32]]},"1886":{"position":[[1850,32],[2907,32],[2942,32]]}}}],["d4d0a161f9024fc8b517b0375eb97c89",{"_index":4248,"t":{"995":{"position":[[2622,32],[2657,32]]},"1886":{"position":[[2622,32],[2657,32]]}}}],["d4de2f32cdf8",{"_index":7129,"t":{"1711":{"position":[[2250,12]]}}}],["d500924",{"_index":447,"t":{"47":{"position":[[82,9]]}}}],["d5509c54b8cb",{"_index":9085,"t":{"2764":{"position":[[296,16]]}}}],["d62c13",{"_index":9326,"t":{"2930":{"position":[[1932,9]]}}}],["d63307fb",{"_index":11125,"t":{"4026":{"position":[[887,8]]},"4030":{"position":[[834,8]]}}}],["d64f0b",{"_index":6990,"t":{"1700":{"position":[[821,6]]}}}],["d64f0b9d",{"_index":6964,"t":{"1700":{"position":[[110,8]]}}}],["d743cb8c8f31",{"_index":8227,"t":{"2254":{"position":[[1392,12]]}}}],["d7ab",{"_index":11085,"t":{"3990":{"position":[[2124,4]]}}}],["d7rzz",{"_index":2951,"t":{"590":{"position":[[1319,5]]}}}],["d9",{"_index":7700,"t":{"2139":{"position":[[477,2]]}}}],["d90cdb468e88",{"_index":4240,"t":{"995":{"position":[[2346,12]]},"1886":{"position":[[2346,12]]}}}],["d912d0a5",{"_index":10251,"t":{"3594":{"position":[[302,8]]}}}],["d9dc2f33e76240219db484526e9f601d",{"_index":302,"t":{"28":{"position":[[3002,32]]}}}],["d_linux_amd64.tar.gz",{"_index":3008,"t":{"671":{"position":[[363,46]]}}}],["downloads/mi",{"_index":7623,"t":{"2121":{"position":[[514,14]]}}}],["downsampl",{"_index":8871,"t":{"2684":{"position":[[317,11],[513,11],[601,11],[1264,12]]},"2686":{"position":[[34,12],[136,12],[628,10]]}}}],["downsample.concurr",{"_index":8880,"t":{"2684":{"position":[[1206,22]]}}}],["downsample.concurrency=3",{"_index":8870,"t":{"2684":{"position":[[134,24]]}}}],["downsid",{"_index":2337,"t":{"423":{"position":[[738,9]]},"3968":{"position":[[1455,8]]},"3984":{"position":[[686,9]]},"3990":{"position":[[1067,9],[3090,9]]},"4163":{"position":[[123,8],[5314,9]]},"4257":{"position":[[1620,9]]},"4801":{"position":[[474,8]]}}}],["downstream",{"_index":1239,"t":{"179":{"position":[[875,10]]},"183":{"position":[[58,10],[306,10]]},"3073":{"position":[[797,10]]},"3298":{"position":[[525,10]]},"4266":{"position":[[178,10]]},"4560":{"position":[[4814,10]]},"4593":{"position":[[651,10]]},"4801":{"position":[[575,10]]}}}],["downtim",{"_index":2059,"t":{"319":{"position":[[920,8]]},"1064":{"position":[[1893,8]]},"1387":{"position":[[87,9]]},"1484":{"position":[[87,9],[658,9]]},"1979":{"position":[[87,9]]},"2148":{"position":[[87,9]]},"2231":{"position":[[137,8],[164,8]]},"2467":{"position":[[1672,8]]},"2469":{"position":[[345,8]]},"3928":{"position":[[389,9]]},"4222":{"position":[[1988,9]]},"4230":{"position":[[3857,8]]},"4475":{"position":[[469,9]]},"4504":{"position":[[882,8]]},"4506":{"position":[[1717,9]]},"4512":{"position":[[465,8]]},"4514":{"position":[[36,9]]}}}],["dox",{"_index":1473,"t":{"199":{"position":[[1574,11]]}}}],["dozen",{"_index":3948,"t":{"949":{"position":[[308,6]]},"1840":{"position":[[308,6]]},"2973":{"position":[[308,6]]}}}],["dpdk_tunnel_interfac",{"_index":5489,"t":{"1299":{"position":[[409,21]]}}}],["dpu",{"_index":11002,"t":{"3971":{"position":[[756,5]]}}}],["dr",{"_index":11242,"t":{"4169":{"position":[[130,2]]}}}],["draft",{"_index":2388,"t":{"440":{"position":[[623,5]]},"442":{"position":[[11,5]]},"1324":{"position":[[34,5]]},"2435":{"position":[[75,5]]},"3121":{"position":[[100,5]]},"3234":{"position":[[57,5]]},"3367":{"position":[[175,6]]},"3386":{"position":[[608,6]]},"3388":{"position":[[107,5]]},"3390":{"position":[[422,6],[707,5]]},"3394":{"position":[[371,5]]},"3396":{"position":[[182,5]]},"3398":{"position":[[429,6],[714,5]]},"3400":{"position":[[64,5]]},"3404":{"position":[[39,5]]},"3408":{"position":[[39,5]]},"3412":{"position":[[39,5]]},"3416":{"position":[[39,5]]},"3420":{"position":[[69,5]]},"3422":{"position":[[164,5]]},"3424":{"position":[[69,5]]},"3432":{"position":[[69,5]]},"3434":{"position":[[39,5]]},"3440":{"position":[[39,5]]},"3442":{"position":[[69,5]]},"3444":{"position":[[69,5]]},"3448":{"position":[[39,5]]},"3450":{"position":[[69,5]]},"3454":{"position":[[62,5]]},"3456":{"position":[[39,5]]},"3458":{"position":[[62,5]]},"3464":{"position":[[39,5]]},"3466":{"position":[[69,5]]},"3468":{"position":[[385,6],[670,5]]},"3470":{"position":[[402,6],[687,5]]},"3472":{"position":[[69,5]]},"3474":{"position":[[473,5]]},"3476":{"position":[[39,5]]},"3480":{"position":[[39,5]]},"3482":{"position":[[62,5]]},"3484":{"position":[[69,5]]},"3488":{"position":[[39,5]]},"3490":{"position":[[62,5]]},"3492":{"position":[[69,5]]},"3494":{"position":[[69,5]]},"3498":{"position":[[39,5]]},"3500":{"position":[[62,5]]},"3502":{"position":[[417,6],[702,5]]},"3504":{"position":[[69,5]]},"3506":{"position":[[69,5]]},"3508":{"position":[[69,5]]},"3510":{"position":[[69,5]]},"3512":{"position":[[69,5]]},"3514":{"position":[[69,5]]},"3516":{"position":[[553,5]]},"3527":{"position":[[1861,6]]},"3531":{"position":[[68,6],[539,5]]},"3533":{"position":[[240,5],[1337,6],[1921,5],[2951,5]]},"3549":{"position":[[279,5]]},"3558":{"position":[[210,8],[393,6]]},"3586":{"position":[[32,6]]},"3606":{"position":[[867,6]]},"3608":{"position":[[86,5]]},"3677":{"position":[[945,7]]},"3791":{"position":[[967,7]]},"4000":{"position":[[65,5]]},"4826":{"position":[[509,6],[800,5]]}}}],["draft'",{"_index":10189,"t":{"3533":{"position":[[607,7]]}}}],["dragon",{"_index":4961,"t":{"1197":{"position":[[221,6],[374,6],[527,6],[680,6]]},"1205":{"position":[[349,6],[671,6]]},"1391":{"position":[[1077,6],[1129,6],[1181,6]]},"1457":{"position":[[910,7],[966,6],[1067,6]]},"1466":{"position":[[1069,6],[1170,6]]},"1472":{"position":[[268,7],[835,6]]},"1480":{"position":[[120,6]]},"1555":{"position":[[1151,6]]},"1694":{"position":[[6696,6]]},"2032":{"position":[[1578,6]]},"2034":{"position":[[1665,6]]}}}],["dragon@ip_address_from_your_serv",{"_index":7311,"t":{"2032":{"position":[[1617,34]]},"2034":{"position":[[1704,34]]}}}],["dragon@ip_address_from_your_server:/home/dragon/wireguard",{"_index":7326,"t":{"2037":{"position":[[388,57]]}}}],["dragon@manag",{"_index":7367,"t":{"2048":{"position":[[711,17],[1480,17]]}}}],["dragon@testb",{"_index":6704,"t":{"1669":{"position":[[138,14],[282,14]]},"1675":{"position":[[135,14]]}}}],["dragon@your_manager_nod",{"_index":6285,"t":{"1472":{"position":[[3444,24]]},"1480":{"position":[[178,24]]}}}],["dragonfli",{"_index":11651,"t":{"4560":{"position":[[2609,9],[2619,9],[2803,11]]},"4562":{"position":[[96,10],[780,9],[1603,10],[1632,9],[2332,9],[2500,9],[4972,10],[5227,9],[5753,9],[6871,9],[7420,10]]},"4566":{"position":[[47,9]]}}}],["dragonfly'",{"_index":11667,"t":{"4562":{"position":[[2432,11]]}}}],["drastic",{"_index":10800,"t":{"3761":{"position":[[1305,11]]}}}],["drawback",{"_index":11568,"t":{"4502":{"position":[[444,9]]},"4562":{"position":[[3574,8]]}}}],["dri",{"_index":1660,"t":{"233":{"position":[[103,5]]},"867":{"position":[[240,3]]},"887":{"position":[[251,3]]},"908":{"position":[[225,3]]},"914":{"position":[[568,3],[1575,3],[1861,3]]},"1768":{"position":[[240,3]]},"1792":{"position":[[225,3]]},"1798":{"position":[[568,3],[1575,3],[1861,3]]},"1811":{"position":[[251,3]]},"1984":{"position":[[51,3]]},"1986":{"position":[[218,3]]},"2104":{"position":[[49,3]]}}}],["drill",{"_index":8734,"t":{"2616":{"position":[[303,5]]},"2659":{"position":[[299,5]]}}}],["drink",{"_index":1588,"t":{"218":{"position":[[209,6]]},"237":{"position":[[230,6]]},"239":{"position":[[351,7]]},"241":{"position":[[394,7]]},"243":{"position":[[251,6]]},"245":{"position":[[226,6]]}}}],["drive",{"_index":2573,"t":{"520":{"position":[[55,5]]},"1593":{"position":[[1028,5],[1052,5]]},"1936":{"position":[[1028,5],[1052,5]]},"2005":{"position":[[201,5]]},"2013":{"position":[[93,5]]},"2021":{"position":[[87,6]]},"2435":{"position":[[159,5]]},"2520":{"position":[[28,5]]},"3675":{"position":[[471,6]]},"3720":{"position":[[474,6]]},"3761":{"position":[[143,6]]},"3813":{"position":[[471,6]]},"3941":{"position":[[33,7]]},"4005":{"position":[[22,5]]},"4007":{"position":[[120,5]]},"4096":{"position":[[776,5]]}}}],["drive'",{"_index":7315,"t":{"2034":{"position":[[673,7]]}}}],["driven",{"_index":2137,"t":{"364":{"position":[[190,6],[862,6],[986,6],[1078,6],[1128,6],[1183,6],[1252,6],[1333,6],[1420,6]]},"2553":{"position":[[142,6]]},"2723":{"position":[[50,6]]},"3292":{"position":[[460,6]]},"3361":{"position":[[47,6]]}}}],["driver",{"_index":3073,"t":{"699":{"position":[[154,6],[396,7]]},"705":{"position":[[1233,7]]},"928":{"position":[[35,6],[586,6]]},"930":{"position":[[70,6],[170,6]]},"932":{"position":[[267,6],[678,6],[1907,6],[2208,6],[2595,6],[2679,7],[2792,7],[2933,6],[3317,6],[4016,6]]},"934":{"position":[[1832,6]]},"936":{"position":[[342,6]]},"946":{"position":[[61,6]]},"949":{"position":[[434,6]]},"961":{"position":[[833,7],[986,7],[1170,6]]},"965":{"position":[[4,6]]},"969":{"position":[[46,6]]},"976":{"position":[[145,6],[271,6]]},"1067":{"position":[[1021,8],[1087,8],[1141,8]]},"1285":{"position":[[140,6]]},"1405":{"position":[[726,8],[897,7],[966,6]]},"1451":{"position":[[273,6],[372,6],[474,7],[601,6]]},"1466":{"position":[[2575,7]]},"1523":{"position":[[1118,6],[1156,7]]},"1819":{"position":[[35,6],[586,6]]},"1821":{"position":[[70,6],[170,6]]},"1823":{"position":[[267,6],[678,6],[1907,6],[2208,6],[2595,6],[2679,7],[2792,7],[2933,6],[3317,6],[4016,6]]},"1825":{"position":[[1832,6]]},"1827":{"position":[[342,6]]},"1837":{"position":[[61,6]]},"1840":{"position":[[434,6]]},"1852":{"position":[[833,7],[986,7],[1170,6]]},"1856":{"position":[[4,6]]},"1860":{"position":[[46,6]]},"1867":{"position":[[145,6],[271,6]]},"2123":{"position":[[638,7],[803,7]]},"2184":{"position":[[6077,6]]},"2231":{"position":[[854,6],[892,7],[1205,6],[1243,7]]},"2952":{"position":[[35,6],[586,6]]},"2954":{"position":[[70,6],[170,6]]},"2956":{"position":[[267,6],[678,6],[1907,6],[2208,6],[2595,6],[2679,7],[2792,7],[2933,6],[3317,6],[4016,6]]},"2958":{"position":[[1832,6]]},"2960":{"position":[[342,6]]},"2970":{"position":[[61,6]]},"2973":{"position":[[434,6]]},"2985":{"position":[[833,7],[986,7],[1170,6]]},"2989":{"position":[[4,6]]},"2993":{"position":[[46,6]]},"3000":{"position":[[145,6],[271,6]]},"3554":{"position":[[266,6]]},"3960":{"position":[[319,7],[495,6]]},"4060":{"position":[[985,7]]},"4122":{"position":[[141,7]]},"4126":{"position":[[313,6]]},"4128":{"position":[[72,7]]},"4226":{"position":[[1322,6]]},"4325":{"position":[[390,7],[408,6]]},"4420":{"position":[[1270,7]]},"4562":{"position":[[5295,7]]}}}],["driver.html",{"_index":5325,"t":{"1285":{"position":[[330,11]]}}}],["driverbyte=driver_ok",{"_index":7687,"t":{"2139":{"position":[[186,20]]}}}],["drop",{"_index":814,"t":{"143":{"position":[[581,4]]},"2602":{"position":[[2127,7]]},"2900":{"position":[[225,4]]},"3130":{"position":[[234,7]]},"3298":{"position":[[558,7]]},"4351":{"position":[[292,7]]}}}],["dropdown",{"_index":4051,"t":{"963":{"position":[[2685,8]]},"1854":{"position":[[2685,8]]},"2987":{"position":[[2685,8]]}}}],["drumbeat",{"_index":1576,"t":{"216":{"position":[[358,9]]}}}],["drwxr",{"_index":6396,"t":{"1555":{"position":[[581,5],[625,5]]}}}],["dst",{"_index":3771,"t":{"932":{"position":[[1050,3],[1352,3]]},"961":{"position":[[1112,3]]},"1823":{"position":[[1050,3],[1352,3]]},"1852":{"position":[[1112,3]]},"2293":{"position":[[622,3],[793,3],[967,3]]},"2307":{"position":[[622,3],[793,3],[967,3]]},"2956":{"position":[[1050,3],[1352,3]]},"2985":{"position":[[1112,3]]}}}],["dual",{"_index":4384,"t":{"1040":{"position":[[705,4]]},"1042":{"position":[[743,4]]},"1105":{"position":[[683,4]]},"1107":{"position":[[550,4]]},"1109":{"position":[[289,4]]},"1111":{"position":[[397,4]]},"1113":{"position":[[451,4]]},"4222":{"position":[[2644,4]]}}}],["due",{"_index":1290,"t":{"181":{"position":[[1957,4]]},"255":{"position":[[89,3]]},"286":{"position":[[756,3]]},"319":{"position":[[720,3]]},"551":{"position":[[605,3],[3016,3]]},"852":{"position":[[251,3]]},"1348":{"position":[[287,3]]},"1350":{"position":[[265,3]]},"1352":{"position":[[374,3]]},"1354":{"position":[[570,3]]},"1578":{"position":[[295,3]]},"1619":{"position":[[730,3],[779,3]]},"1688":{"position":[[27,3]]},"1921":{"position":[[295,3]]},"1950":{"position":[[730,3],[779,3]]},"2165":{"position":[[205,3]]},"2214":{"position":[[106,3]]},"2240":{"position":[[1249,3]]},"2439":{"position":[[0,3]]},"3071":{"position":[[619,3]]},"3148":{"position":[[342,3]]},"3264":{"position":[[588,3]]},"3474":{"position":[[324,3]]},"3602":{"position":[[1154,3]]},"3829":{"position":[[1487,3]]},"3947":{"position":[[2117,3],[3368,3]]},"3971":{"position":[[981,3]]},"4081":{"position":[[469,3]]},"4109":{"position":[[2422,3],[5428,3]]},"4124":{"position":[[1439,3],[1614,3]]},"4133":{"position":[[75,3]]},"4220":{"position":[[351,3]]},"4251":{"position":[[296,3]]},"4294":{"position":[[97,3]]},"4302":{"position":[[3378,3],[4278,3],[4880,3]]},"4304":{"position":[[1544,4]]},"4310":{"position":[[247,3],[422,3],[935,3],[1489,3]]},"4313":{"position":[[514,3],[719,3],[1133,3]]},"4385":{"position":[[224,3]]},"4401":{"position":[[89,3]]},"4433":{"position":[[912,3],[1052,3]]},"4435":{"position":[[1467,3]]},"4444":{"position":[[88,3]]},"4446":{"position":[[279,3]]},"4455":{"position":[[88,3]]},"4457":{"position":[[279,3]]},"4471":{"position":[[138,3]]},"4479":{"position":[[145,3],[1374,3]]},"4489":{"position":[[162,3]]},"4504":{"position":[[725,3]]},"4512":{"position":[[384,3]]},"4516":{"position":[[570,3]]},"4518":{"position":[[352,3]]},"4525":{"position":[[0,3],[225,3]]},"4529":{"position":[[466,3]]},"4533":{"position":[[0,3]]},"4537":{"position":[[161,3]]},"4539":{"position":[[6120,3]]},"4541":{"position":[[825,3]]},"4545":{"position":[[303,3]]},"4547":{"position":[[330,3],[2591,3]]},"4562":{"position":[[608,3]]},"4608":{"position":[[291,3]]},"4614":{"position":[[234,3],[669,3]]},"4746":{"position":[[243,4]]}}}],["dumb",{"_index":6721,"t":{"1673":{"position":[[171,4]]},"1711":{"position":[[1231,5],[1359,5],[1484,5],[1619,5],[1764,5],[1909,5],[2046,5],[2179,5],[2308,5],[2432,5],[2573,5],[2811,5],[2919,5],[3029,5]]}}}],["dummi",{"_index":5296,"t":{"1271":{"position":[[0,5]]},"2266":{"position":[[181,5]]},"3159":{"position":[[414,5]]}}}],["dummy0",{"_index":5300,"t":{"1271":{"position":[[164,6]]},"1275":{"position":[[337,6],[463,6],[537,7]]}}}],["dummy_image_nam",{"_index":8271,"t":{"2266":{"position":[[316,19],[338,19],[361,19],[484,19]]}}}],["dummy_image_name=\"dummi",{"_index":8267,"t":{"2266":{"position":[[206,24]]}}}],["dump",{"_index":6557,"t":{"1613":{"position":[[85,4],[100,4]]},"1619":{"position":[[53,4],[288,4]]},"1627":{"position":[[22,4]]},"1944":{"position":[[85,4],[100,4]]},"1950":{"position":[[53,4],[288,4]]},"1958":{"position":[[22,4]]}}}],["duplic",{"_index":8372,"t":{"2343":{"position":[[194,10]]},"2410":{"position":[[194,10]]},"3565":{"position":[[181,12]]},"3673":{"position":[[1104,10]]},"3714":{"position":[[1299,10]]},"3807":{"position":[[758,10]]},"4427":{"position":[[405,10]]},"4435":{"position":[[440,9]]},"4440":{"position":[[397,10]]},"4446":{"position":[[550,12]]},"4451":{"position":[[397,10]]},"4457":{"position":[[550,12]]},"4691":{"position":[[161,12]]}}}],["duplicateresourc",{"_index":8962,"t":{"2712":{"position":[[1533,17]]}}}],["duplo",{"_index":1652,"t":{"233":{"position":[[50,6]]}}}],["durabl",{"_index":11499,"t":{"4376":{"position":[[1083,10]]},"4535":{"position":[[1667,10]]}}}],["durat",{"_index":6488,"t":{"1576":{"position":[[26,10]]},"1694":{"position":[[1017,8],[1831,8],[2236,8],[5982,8],[6430,8]]},"1919":{"position":[[26,10]]},"2716":{"position":[[559,8]]},"2720":{"position":[[412,8]]},"3731":{"position":[[1333,8]]},"3768":{"position":[[264,8]]}}}],["duration_avg",{"_index":6870,"t":{"1694":{"position":[[7224,12]]}}}],["duration_tot",{"_index":6869,"t":{"1694":{"position":[[7207,14]]}}}],["dure",{"_index":46,"t":{"7":{"position":[[317,6]]},"543":{"position":[[1094,6]]},"732":{"position":[[986,6]]},"738":{"position":[[1015,6]]},"903":{"position":[[46,6]]},"944":{"position":[[744,6]]},"1144":{"position":[[193,6]]},"1220":{"position":[[908,6]]},"1433":{"position":[[791,6]]},"1457":{"position":[[984,6],[1031,6]]},"1466":{"position":[[1087,6],[1134,6],[2680,6]]},"1486":{"position":[[317,6]]},"1648":{"position":[[38,6]]},"1787":{"position":[[46,6]]},"1835":{"position":[[744,6]]},"2034":{"position":[[62,6]]},"2055":{"position":[[574,6]]},"2163":{"position":[[3627,6]]},"2165":{"position":[[1023,6]]},"2184":{"position":[[2892,6]]},"2207":{"position":[[118,6]]},"2289":{"position":[[164,6]]},"2291":{"position":[[218,6]]},"2295":{"position":[[297,6]]},"2303":{"position":[[164,6]]},"2305":{"position":[[218,6]]},"2309":{"position":[[297,6]]},"2380":{"position":[[682,6]]},"2480":{"position":[[268,6],[981,6],[1187,6],[1287,6]]},"2701":{"position":[[135,6]]},"2703":{"position":[[40,6]]},"2712":{"position":[[1377,6]]},"2716":{"position":[[1632,6]]},"2968":{"position":[[744,6]]},"3022":{"position":[[257,6]]},"3121":{"position":[[165,6]]},"3246":{"position":[[0,6]]},"3266":{"position":[[729,6]]},"3272":{"position":[[71,6],[331,6]]},"3276":{"position":[[173,6]]},"3292":{"position":[[80,6],[750,6]]},"3306":{"position":[[0,6]]},"3310":{"position":[[524,6]]},"3323":{"position":[[741,6]]},"3525":{"position":[[314,6]]},"3529":{"position":[[974,6]]},"3565":{"position":[[262,6]]},"4077":{"position":[[60,6]]},"4206":{"position":[[374,6]]},"4222":{"position":[[2892,6]]},"4302":{"position":[[2715,6]]},"4431":{"position":[[1920,6],[2407,6]]},"4479":{"position":[[778,6]]},"4485":{"position":[[1211,6]]},"4506":{"position":[[1517,6]]},"4543":{"position":[[1189,6]]},"4545":{"position":[[288,6]]},"4632":{"position":[[483,6]]},"4639":{"position":[[34,6]]},"4643":{"position":[[2778,6]]},"4722":{"position":[[653,6]]},"4742":{"position":[[158,6]]}}}],["dus2",{"_index":10048,"t":{"3367":{"position":[[1101,5]]}}}],["dvr",{"_index":9774,"t":{"3140":{"position":[[28,5]]}}}],["dynam",{"_index":3312,"t":{"824":{"position":[[393,11]]},"1329":{"position":[[88,7],[113,7],[149,7],[193,7]]},"2289":{"position":[[127,11]]},"2303":{"position":[[127,11]]},"2487":{"position":[[575,7]]},"2489":{"position":[[158,7]]},"2557":{"position":[[54,7]]},"2743":{"position":[[200,7]]},"3257":{"position":[[99,7]]},"3960":{"position":[[277,7],[513,11]]},"4230":{"position":[[2098,11]]},"4302":{"position":[[3396,7]]},"4420":{"position":[[634,7]]},"4703":{"position":[[288,12]]}}}],["dysfunct",{"_index":9954,"t":{"3317":{"position":[[86,13]]}}}],["e",{"_index":1947,"t":{"295":{"position":[[1459,2],[1613,5]]},"942":{"position":[[3187,1]]},"949":{"position":[[796,2]]},"1177":{"position":[[1831,1],[2010,1]]},"1222":{"position":[[291,1],[318,1]]},"1457":{"position":[[3103,1],[3920,1]]},"1507":{"position":[[326,1]]},"1509":{"position":[[660,1]]},"1540":{"position":[[30,1],[56,1]]},"1542":{"position":[[32,1],[65,1]]},"1544":{"position":[[309,1],[331,1],[500,1]]},"1552":{"position":[[767,1],[807,1],[849,1],[997,1],[1036,1],[1078,1],[1203,1],[1243,1],[1280,1],[1404,1],[1443,1],[1480,1]]},"1555":{"position":[[269,1]]},"1557":{"position":[[232,1]]},"1600":{"position":[[211,1]]},"1605":{"position":[[1399,1],[1420,1]]},"1661":{"position":[[991,1]]},"1665":{"position":[[228,1]]},"1686":{"position":[[629,1]]},"1704":{"position":[[196,1],[308,1]]},"1709":{"position":[[235,1]]},"1740":{"position":[[89,1]]},"1833":{"position":[[3187,1]]},"1840":{"position":[[796,2]]},"2048":{"position":[[3492,1]]},"2146":{"position":[[705,1]]},"2159":{"position":[[33,1]]},"2163":{"position":[[4014,1]]},"2165":{"position":[[1962,1]]},"2171":{"position":[[464,1]]},"2207":{"position":[[1270,1]]},"2798":{"position":[[121,1],[251,1]]},"2834":{"position":[[8,1],[54,1]]},"2966":{"position":[[3187,1]]},"2973":{"position":[[796,2]]},"3644":{"position":[[132,1]]},"3712":{"position":[[1634,1]]},"3722":{"position":[[614,1],[628,1],[641,1],[725,1],[739,1],[752,1]]},"3815":{"position":[[478,1],[492,1],[505,1],[589,1],[603,1],[616,1]]},"4562":{"position":[[6046,1]]},"4660":{"position":[[1634,1]]},"4855":{"position":[[144,1]]}}}],["e.g",{"_index":145,"t":{"19":{"position":[[243,5]]},"181":{"position":[[1985,4]]},"199":{"position":[[1866,4]]},"258":{"position":[[617,4]]},"288":{"position":[[565,6],[911,6]]},"309":{"position":[[190,6],[408,6]]},"323":{"position":[[1617,4]]},"395":{"position":[[163,4]]},"397":{"position":[[492,4]]},"425":{"position":[[520,4]]},"434":{"position":[[422,4]]},"440":{"position":[[160,5]]},"463":{"position":[[80,4],[125,4],[462,4],[618,4],[673,5]]},"477":{"position":[[381,5]]},"479":{"position":[[302,4]]},"526":{"position":[[645,4],[1388,4]]},"530":{"position":[[1652,4]]},"597":{"position":[[364,4],[550,4],[672,4]]},"606":{"position":[[151,4]]},"618":{"position":[[292,5]]},"624":{"position":[[85,4]]},"632":{"position":[[303,5],[535,4]]},"641":{"position":[[138,4]]},"657":{"position":[[591,5]]},"659":{"position":[[490,4]]},"661":{"position":[[519,5]]},"666":{"position":[[138,4]]},"668":{"position":[[327,4]]},"686":{"position":[[124,4]]},"688":{"position":[[400,5]]},"696":{"position":[[1167,5],[1362,5]]},"706":{"position":[[2079,4]]},"715":{"position":[[113,5]]},"728":{"position":[[372,4]]},"732":{"position":[[158,5]]},"739":{"position":[[1655,5]]},"741":{"position":[[359,4],[1093,4]]},"751":{"position":[[124,4]]},"816":{"position":[[612,4]]},"846":{"position":[[486,4],[989,4]]},"926":{"position":[[266,5]]},"930":{"position":[[585,4]]},"938":{"position":[[293,5]]},"940":{"position":[[438,5]]},"946":{"position":[[122,4]]},"949":{"position":[[1059,4]]},"963":{"position":[[4168,4]]},"980":{"position":[[161,4]]},"1038":{"position":[[218,5]]},"1185":{"position":[[826,4]]},"1189":{"position":[[707,5]]},"1226":{"position":[[2151,4]]},"1238":{"position":[[229,4]]},"1257":{"position":[[164,4]]},"1303":{"position":[[2458,4]]},"1371":{"position":[[319,5]]},"1373":{"position":[[978,5]]},"1375":{"position":[[219,5]]},"1377":{"position":[[108,4]]},"1379":{"position":[[298,5]]},"1383":{"position":[[657,4],[1805,4],[2364,5]]},"1391":{"position":[[1289,5],[1331,6],[1698,5]]},"1443":{"position":[[727,4]]},"1466":{"position":[[540,5],[902,4]]},"1501":{"position":[[352,5]]},"1503":{"position":[[2488,5]]},"1529":{"position":[[90,4]]},"1574":{"position":[[377,4]]},"1580":{"position":[[547,5]]},"1641":{"position":[[91,4]]},"1817":{"position":[[266,5]]},"1821":{"position":[[585,4]]},"1829":{"position":[[293,5]]},"1831":{"position":[[438,5]]},"1837":{"position":[[122,4]]},"1840":{"position":[[1059,4]]},"1854":{"position":[[4168,4]]},"1871":{"position":[[161,4]]},"1917":{"position":[[377,4]]},"1923":{"position":[[547,5]]},"1972":{"position":[[91,4]]},"2055":{"position":[[597,5]]},"2057":{"position":[[102,5]]},"2059":{"position":[[2620,4]]},"2165":{"position":[[1168,5]]},"2171":{"position":[[164,4]]},"2188":{"position":[[314,5]]},"2211":{"position":[[652,5],[898,5],[997,4],[1194,4],[1475,4],[1632,4]]},"2214":{"position":[[66,5]]},"2248":{"position":[[311,5]]},"2266":{"position":[[51,5],[200,5]]},"2270":{"position":[[42,5],[429,4]]},"2327":{"position":[[54,5]]},"2360":{"position":[[1894,5]]},"2394":{"position":[[54,5]]},"2427":{"position":[[1894,5]]},"2431":{"position":[[708,4],[1116,4],[2824,5]]},"2478":{"position":[[1078,6]]},"2518":{"position":[[293,6]]},"2531":{"position":[[593,6]]},"2535":{"position":[[427,6]]},"2574":{"position":[[203,4]]},"2580":{"position":[[455,4]]},"2624":{"position":[[840,4],[989,4]]},"2626":{"position":[[1106,5],[1897,5],[2134,5],[2597,5]]},"2647":{"position":[[1269,4]]},"2649":{"position":[[2478,4]]},"2663":{"position":[[131,4]]},"2898":{"position":[[160,4]]},"2914":{"position":[[1273,4]]},"2950":{"position":[[266,5]]},"2954":{"position":[[585,4]]},"2962":{"position":[[293,5]]},"2964":{"position":[[438,5]]},"2970":{"position":[[122,4]]},"2973":{"position":[[1059,4]]},"2987":{"position":[[4168,4]]},"3004":{"position":[[161,4]]},"3052":{"position":[[665,4]]},"3088":{"position":[[742,4]]},"3121":{"position":[[1241,4]]},"3248":{"position":[[122,5]]},"3266":{"position":[[167,4]]},"3296":{"position":[[276,4]]},"3352":{"position":[[598,5]]},"3357":{"position":[[3542,4]]},"3381":{"position":[[1643,4]]},"3527":{"position":[[2059,6]]},"3558":{"position":[[461,4]]},"3584":{"position":[[322,5]]},"3594":{"position":[[61,4]]},"3663":{"position":[[134,5]]},"3673":{"position":[[1028,5]]},"3677":{"position":[[1439,4]]},"3681":{"position":[[946,4]]},"3700":{"position":[[128,5]]},"3706":{"position":[[888,4]]},"3718":{"position":[[985,4]]},"3731":{"position":[[372,6]]},"3759":{"position":[[289,5]]},"3763":{"position":[[1045,5]]},"3787":{"position":[[128,5]]},"3791":{"position":[[1461,4]]},"3799":{"position":[[888,4]]},"3807":{"position":[[682,5]]},"3811":{"position":[[985,4]]},"3824":{"position":[[63,4]]},"3829":{"position":[[395,5],[2092,4]]},"3831":{"position":[[677,4]]},"3835":{"position":[[103,5],[2045,4]]},"3866":{"position":[[316,5]]},"3904":{"position":[[992,4]]},"3925":{"position":[[624,4]]},"3928":{"position":[[920,5]]},"3930":{"position":[[386,4],[1035,5]]},"4060":{"position":[[368,4]]},"4081":{"position":[[190,4]]},"4083":{"position":[[95,5]]},"4094":{"position":[[885,4]]},"4096":{"position":[[417,5],[519,5],[647,5],[782,5]]},"4102":{"position":[[709,4]]},"4107":{"position":[[1125,5],[1317,5]]},"4109":{"position":[[2180,5],[3755,4],[4926,4],[5377,4]]},"4111":{"position":[[191,5]]},"4120":{"position":[[119,5]]},"4122":{"position":[[117,5]]},"4137":{"position":[[515,4]]},"4139":{"position":[[218,4]]},"4153":{"position":[[174,4]]},"4155":{"position":[[466,5],[568,5],[696,5]]},"4159":{"position":[[2229,4]]},"4163":{"position":[[5191,5]]},"4167":{"position":[[655,5]]},"4178":{"position":[[256,5]]},"4182":{"position":[[136,4]]},"4204":{"position":[[73,4]]},"4222":{"position":[[85,5]]},"4253":{"position":[[264,4]]},"4257":{"position":[[4184,5]]},"4287":{"position":[[99,5]]},"4302":{"position":[[955,5],[1298,5],[1715,5],[5197,5]]},"4331":{"position":[[279,5]]},"4355":{"position":[[553,6]]},"4410":{"position":[[140,4],[291,4]]},"4420":{"position":[[170,5],[904,4],[1219,4],[2398,4],[2551,5],[2884,4]]},"4431":{"position":[[1762,5]]},"4435":{"position":[[856,4]]},"4459":{"position":[[1221,4],[1899,4]]},"4493":{"position":[[131,4]]},"4529":{"position":[[227,4],[621,5]]},"4533":{"position":[[68,4]]},"4535":{"position":[[1213,4],[2024,5]]},"4539":{"position":[[3856,4]]},"4554":{"position":[[140,4]]},"4560":{"position":[[917,5],[1335,4],[2316,4],[2771,4],[3559,4]]},"4562":{"position":[[3835,4],[5067,5],[5251,4],[7468,5]]},"4580":{"position":[[1847,4]]},"4587":{"position":[[409,4],[499,4]]},"4591":{"position":[[186,4],[423,4],[684,5],[696,4]]},"4593":{"position":[[1481,6],[1617,4],[2805,5],[3005,4]]},"4595":{"position":[[63,4],[153,4]]},"4597":{"position":[[644,5],[883,4]]},"4632":{"position":[[397,4]]},"4643":{"position":[[2483,4],[3017,4]]},"4654":{"position":[[83,5]]},"4660":{"position":[[1313,5],[1868,4],[2153,4],[2727,5]]},"4707":{"position":[[1079,4]]},"4713":{"position":[[134,4]]},"4722":{"position":[[556,4]]},"4742":{"position":[[510,5],[568,5]]},"4748":{"position":[[145,5]]},"4761":{"position":[[188,5],[246,5]]},"4845":{"position":[[198,4]]},"4857":{"position":[[503,4]]},"4870":{"position":[[153,4]]},"4872":{"position":[[368,5]]},"4877":{"position":[[234,4]]}}}],["e.v",{"_index":3261,"t":{"776":{"position":[[87,4]]},"3731":{"position":[[1814,5],[1920,5]]}}}],["e02ddfc0e82a",{"_index":7999,"t":{"2207":{"position":[[645,12],[774,12],[825,12]]}}}],["e0ded111a007",{"_index":6759,"t":{"1686":{"position":[[703,12]]}}}],["e12c89f88b44",{"_index":11033,"t":{"3988":{"position":[[1344,12]]}}}],["e1be6a",{"_index":9320,"t":{"2930":{"position":[[1543,9]]}}}],["e2",{"_index":276,"t":{"28":{"position":[[1843,3],[1860,3]]},"364":{"position":[[1167,3],[1230,3],[1317,3],[1398,3]]},"524":{"position":[[90,3],[122,3],[166,3],[231,3],[286,3],[357,3],[412,3],[483,3],[538,3],[598,3],[677,3],[756,3],[787,3],[814,3],[852,3],[902,3],[961,3],[1022,3],[1087,3],[1148,3],[1213,3],[1274,3],[1328,3],[1413,3],[1498,3],[1529,3]]},"526":{"position":[[110,3],[541,3],[871,3],[1290,3]]},"528":{"position":[[49,3]]},"530":{"position":[[59,5],[599,3],[707,4],[748,5],[902,4],[949,5],[1105,3],[1329,3],[1449,3],[1497,3],[1520,3],[1545,3],[1567,3],[1620,3],[2307,3],[2397,3],[2551,4],[2591,4],[2663,3],[2692,3],[2761,3],[2799,4],[2868,4]]},"3193":{"position":[[132,3]]},"4215":{"position":[[57,5]]},"4222":{"position":[[867,5]]},"4224":{"position":[[3057,3]]},"4273":{"position":[[226,3],[421,3],[555,3]]},"4279":{"position":[[45,3],[210,3],[450,3],[540,3],[710,3],[1175,3],[1291,3],[1419,3]]},"4281":{"position":[[22,3],[135,3],[258,3],[386,3],[782,3],[930,3],[999,3],[1272,3],[1344,3],[1416,3]]},"4291":{"position":[[597,3],[628,3],[730,3],[1124,3],[1236,3],[1820,3],[1951,3]]},"4355":{"position":[[764,3]]},"4584":{"position":[[72,3]]}}}],["e2e.yaml",{"_index":2579,"t":{"522":{"position":[[473,8]]},"526":{"position":[[694,8],[1437,8]]},"530":{"position":[[185,8]]}}}],["e425",{"_index":9102,"t":{"2776":{"position":[[134,4]]}}}],["e485697f",{"_index":4305,"t":{"1005":{"position":[[3191,8],[3429,8],[3744,8],[3859,8],[6024,8]]},"1896":{"position":[[3191,8],[3429,8],[3744,8],[3859,8],[6024,8]]}}}],["e514c2c8",{"_index":11101,"t":{"3990":{"position":[[2325,8]]}}}],["e533",{"_index":8249,"t":{"2256":{"position":[[440,4]]}}}],["e58a7a8af17",{"_index":7244,"t":{"1743":{"position":[[171,12]]}}}],["e5b8",{"_index":4769,"t":{"1177":{"position":[[4852,4],[5189,4],[5240,4],[5731,4],[6096,4],[6520,4],[6562,4]]}}}],["e74",{"_index":6937,"t":{"1698":{"position":[[1117,3]]}}}],["e7622c1048ac4520a2d050ae141e826b",{"_index":248,"t":{"28":{"position":[[1165,32]]}}}],["e7c4b05c",{"_index":4250,"t":{"995":{"position":[[2997,8]]},"1886":{"position":[[2997,8]]}}}],["e828",{"_index":4289,"t":{"1005":{"position":[[2756,4]]},"1896":{"position":[[2756,4]]}}}],["e85f",{"_index":7180,"t":{"1720":{"position":[[466,4],[992,4],[1702,4],[2516,4]]}}}],["e89ac8c9f66f46b5a983b2a05d2a66ec",{"_index":307,"t":{"28":{"position":[[3162,32]]}}}],["e8d5",{"_index":8173,"t":{"2252":{"position":[[1162,4],[2642,4]]}}}],["each",{"_index":574,"t":{"78":{"position":[[295,4]]},"151":{"position":[[78,4]]},"167":{"position":[[1307,4]]},"199":{"position":[[933,4],[3076,4]]},"271":{"position":[[333,4]]},"305":{"position":[[353,5]]},"321":{"position":[[130,4]]},"323":{"position":[[1068,4]]},"368":{"position":[[816,4],[963,4],[2796,4],[3865,4]]},"384":{"position":[[31,4]]},"401":{"position":[[1025,4]]},"452":{"position":[[97,4]]},"465":{"position":[[43,4]]},"530":{"position":[[2003,4]]},"537":{"position":[[69,4],[343,4]]},"541":{"position":[[1653,4]]},"543":{"position":[[75,4]]},"549":{"position":[[47,4],[99,4],[167,4]]},"551":{"position":[[235,4],[1978,4]]},"557":{"position":[[2405,4]]},"604":{"position":[[76,4]]},"812":{"position":[[240,4]]},"818":{"position":[[168,4],[428,4]]},"834":{"position":[[41,4]]},"848":{"position":[[466,4]]},"871":{"position":[[517,4]]},"873":{"position":[[129,4]]},"896":{"position":[[86,4]]},"936":{"position":[[615,4]]},"940":{"position":[[458,4]]},"942":{"position":[[100,4]]},"1005":{"position":[[2358,4]]},"1048":{"position":[[122,4]]},"1105":{"position":[[772,4]]},"1175":{"position":[[4,4],[1559,4],[1878,4],[2641,4],[2833,4],[3423,4],[3605,4]]},"1177":{"position":[[278,4]]},"1257":{"position":[[1505,4]]},"1301":{"position":[[2548,4]]},"1303":{"position":[[3347,4]]},"1373":{"position":[[101,4]]},"1385":{"position":[[2420,4]]},"1391":{"position":[[3452,4]]},"1421":{"position":[[1271,4],[1445,4]]},"1433":{"position":[[869,4]]},"1437":{"position":[[49,4]]},"1472":{"position":[[32,4]]},"1501":{"position":[[0,4],[427,4]]},"1574":{"position":[[531,4],[720,4]]},"1605":{"position":[[505,4],[538,4]]},"1646":{"position":[[149,4],[574,4],[924,4],[1054,4],[1314,4],[1574,4],[1755,4],[1943,4]]},"1648":{"position":[[343,4],[470,4],[485,4],[695,4],[1437,4],[1592,4],[1687,4]]},"1692":{"position":[[0,4]]},"1754":{"position":[[86,4]]},"1772":{"position":[[517,4]]},"1774":{"position":[[129,4]]},"1827":{"position":[[615,4]]},"1831":{"position":[[458,4]]},"1833":{"position":[[100,4]]},"1896":{"position":[[2358,4]]},"1917":{"position":[[531,4],[720,4]]},"2037":{"position":[[371,4]]},"2065":{"position":[[4,4],[525,4]]},"2086":{"position":[[78,4]]},"2128":{"position":[[210,4]]},"2163":{"position":[[4061,4]]},"2171":{"position":[[1645,4]]},"2178":{"position":[[773,4]]},"2188":{"position":[[499,4]]},"2190":{"position":[[599,4]]},"2246":{"position":[[296,4]]},"2289":{"position":[[142,4]]},"2295":{"position":[[178,4]]},"2303":{"position":[[142,4]]},"2309":{"position":[[178,4]]},"2323":{"position":[[291,4]]},"2327":{"position":[[293,4]]},"2358":{"position":[[178,4]]},"2376":{"position":[[427,4]]},"2390":{"position":[[291,4]]},"2394":{"position":[[293,4]]},"2425":{"position":[[178,4]]},"2451":{"position":[[250,4]]},"2473":{"position":[[244,4]]},"2482":{"position":[[87,4],[660,4]]},"2489":{"position":[[1269,4],[1274,4],[1329,4]]},"2503":{"position":[[21,4]]},"2529":{"position":[[361,4]]},"2574":{"position":[[144,4]]},"2576":{"position":[[126,4]]},"2632":{"position":[[154,4]]},"2649":{"position":[[1258,4]]},"2661":{"position":[[461,4]]},"2712":{"position":[[1486,4]]},"2716":{"position":[[1316,4],[1671,4]]},"2718":{"position":[[328,6],[392,4]]},"2732":{"position":[[81,4]]},"2930":{"position":[[1176,4]]},"2960":{"position":[[615,4]]},"2964":{"position":[[458,4]]},"2966":{"position":[[100,4]]},"3185":{"position":[[656,4]]},"3238":{"position":[[386,4]]},"3276":{"position":[[715,4]]},"3290":{"position":[[258,4]]},"3361":{"position":[[611,4]]},"3375":{"position":[[630,4],[690,4]]},"3386":{"position":[[436,4],[570,4]]},"3527":{"position":[[60,4],[299,4],[443,4],[517,4],[1422,4],[1654,4]]},"3529":{"position":[[10,4],[1213,4]]},"3549":{"position":[[157,4]]},"3571":{"position":[[375,4]]},"3582":{"position":[[819,4],[1541,4],[1594,4]]},"3592":{"position":[[1015,4],[1480,4],[1496,4]]},"3594":{"position":[[0,4]]},"3598":{"position":[[657,4]]},"3600":{"position":[[410,4],[498,4]]},"3602":{"position":[[935,4]]},"3606":{"position":[[62,4]]},"3608":{"position":[[417,4]]},"3646":{"position":[[0,4]]},"3677":{"position":[[1248,4]]},"3731":{"position":[[0,4]]},"3791":{"position":[[1271,4]]},"3837":{"position":[[89,4]]},"3870":{"position":[[77,4]]},"3902":{"position":[[259,4]]},"3904":{"position":[[802,4]]},"3918":{"position":[[350,4]]},"3923":{"position":[[105,4]]},"3925":{"position":[[1128,4]]},"3973":{"position":[[448,4]]},"3984":{"position":[[1773,4]]},"3992":{"position":[[137,4]]},"4005":{"position":[[105,4]]},"4015":{"position":[[531,4]]},"4034":{"position":[[124,4],[229,4],[259,4]]},"4037":{"position":[[451,4]]},"4041":{"position":[[913,4]]},"4094":{"position":[[280,4],[371,4]]},"4100":{"position":[[138,4]]},"4102":{"position":[[943,4]]},"4104":{"position":[[181,4]]},"4107":{"position":[[51,4]]},"4109":{"position":[[91,4]]},"4130":{"position":[[229,4]]},"4144":{"position":[[613,4]]},"4146":{"position":[[843,4]]},"4157":{"position":[[963,4]]},"4159":{"position":[[98,4],[1581,4],[2141,4],[2305,4]]},"4163":{"position":[[395,4],[425,4],[5241,4]]},"4167":{"position":[[510,4]]},"4178":{"position":[[21,4],[77,4],[417,4],[490,4],[556,4]]},"4226":{"position":[[1487,4]]},"4228":{"position":[[503,4],[601,4],[840,4],[1014,4]]},"4230":{"position":[[1001,4],[1599,4],[3612,4]]},"4275":{"position":[[962,4]]},"4277":{"position":[[183,4]]},"4283":{"position":[[504,4]]},"4310":{"position":[[1753,4]]},"4337":{"position":[[461,4]]},"4359":{"position":[[155,4]]},"4446":{"position":[[792,4]]},"4448":{"position":[[655,4],[700,4],[751,4],[888,4]]},"4457":{"position":[[792,4]]},"4459":{"position":[[381,4],[638,4]]},"4535":{"position":[[2969,4]]},"4539":{"position":[[5075,4]]},"4541":{"position":[[43,4]]},"4543":{"position":[[1326,4]]},"4562":{"position":[[5319,4]]},"4593":{"position":[[4019,4]]},"4610":{"position":[[292,4]]},"4614":{"position":[[1029,4]]},"4643":{"position":[[2434,4],[2587,4]]},"4667":{"position":[[14599,4]]},"4691":{"position":[[1370,4]]},"4705":{"position":[[166,4],[325,4]]},"4728":{"position":[[263,4]]},"4730":{"position":[[580,4]]}}}],["earli",{"_index":1964,"t":{"301":{"position":[[373,5]]},"942":{"position":[[4149,5]]},"1833":{"position":[[4149,5]]},"2487":{"position":[[978,5]]},"2537":{"position":[[581,5]]},"2966":{"position":[[4149,5]]},"3533":{"position":[[574,5]]},"4109":{"position":[[4088,5]]},"4146":{"position":[[1464,5]]},"4614":{"position":[[710,6]]},"4654":{"position":[[401,5]]}}}],["earlier",{"_index":1911,"t":{"293":{"position":[[463,7]]},"305":{"position":[[135,7]]},"705":{"position":[[284,7]]},"1224":{"position":[[529,7]]},"1484":{"position":[[570,8]]},"1688":{"position":[[355,7]]},"2480":{"position":[[838,7]]},"3833":{"position":[[236,8]]},"4283":{"position":[[324,8]]},"4481":{"position":[[740,8]]},"4483":{"position":[[117,7]]},"4547":{"position":[[2927,8]]},"4665":{"position":[[472,7]]},"4667":{"position":[[222,7]]}}}],["earthquak",{"_index":11190,"t":{"4109":{"position":[[1839,10],[2059,11]]},"4133":{"position":[[1113,10]]}}}],["eas",{"_index":1151,"t":{"173":{"position":[[1874,4]]},"423":{"position":[[1080,4]]},"3101":{"position":[[347,4]]},"3223":{"position":[[802,4]]},"3724":{"position":[[312,4]]},"3817":{"position":[[312,4]]},"4142":{"position":[[315,4]]},"4146":{"position":[[48,4]]},"4224":{"position":[[2242,4],[3219,4]]},"4587":{"position":[[457,4]]},"4660":{"position":[[695,4]]}}}],["eascii",{"_index":6729,"t":{"1673":{"position":[[339,6]]}}}],["easeiest",{"_index":9016,"t":{"2725":{"position":[[933,8]]}}}],["easi",{"_index":178,"t":{"24":{"position":[[392,4]]},"86":{"position":[[47,5]]},"107":{"position":[[140,4]]},"161":{"position":[[119,4]]},"173":{"position":[[152,4]]},"305":{"position":[[230,4]]},"378":{"position":[[613,4]]},"430":{"position":[[33,5]]},"595":{"position":[[618,5]]},"912":{"position":[[158,4]]},"934":{"position":[[1678,4]]},"961":{"position":[[77,4]]},"1030":{"position":[[549,4]]},"1796":{"position":[[158,4]]},"1825":{"position":[[1678,4]]},"1852":{"position":[[77,4]]},"1988":{"position":[[213,6]]},"2800":{"position":[[47,5]]},"2839":{"position":[[226,4]]},"2896":{"position":[[94,4]]},"2958":{"position":[[1678,4]]},"2985":{"position":[[77,4]]},"3150":{"position":[[233,4]]},"3279":{"position":[[506,4]]},"3549":{"position":[[419,4]]},"3571":{"position":[[1358,4]]},"4224":{"position":[[2552,4]]},"4230":{"position":[[483,4]]},"4257":{"position":[[5358,4]]},"4281":{"position":[[1020,4]]},"4289":{"position":[[223,4]]},"4300":{"position":[[164,4]]},"4308":{"position":[[358,4]]},"4310":{"position":[[1448,4],[2454,4]]},"4506":{"position":[[68,4],[1331,4],[1389,4]]},"4508":{"position":[[828,4]]},"4537":{"position":[[233,4]]},"4539":{"position":[[4257,4]]},"4660":{"position":[[500,4],[1034,4],[1974,4],[2594,4]]},"4662":{"position":[[181,4],[313,4]]},"4667":{"position":[[12892,4]]}}}],["easier",{"_index":877,"t":{"153":{"position":[[127,6]]},"171":{"position":[[956,6]]},"301":{"position":[[434,6]]},"305":{"position":[[1329,6]]},"339":{"position":[[267,6]]},"401":{"position":[[1122,6]]},"419":{"position":[[139,6]]},"475":{"position":[[717,7]]},"489":{"position":[[592,6]]},"1056":{"position":[[762,6]]},"1238":{"position":[[11,6]]},"2023":{"position":[[710,7]]},"2088":{"position":[[120,6]]},"3050":{"position":[[392,6]]},"3073":{"position":[[786,6]]},"3086":{"position":[[380,7]]},"3150":{"position":[[645,6]]},"3187":{"position":[[388,6]]},"3310":{"position":[[247,6]]},"3527":{"position":[[509,7]]},"3679":{"position":[[761,6]]},"3704":{"position":[[1419,6]]},"3793":{"position":[[951,6]]},"3894":{"position":[[2107,6]]},"3984":{"position":[[461,6]]},"4109":{"position":[[5185,6]]},"4135":{"position":[[734,6]]},"4257":{"position":[[559,7]]},"4514":{"position":[[138,6]]},"4786":{"position":[[13,6]]}}}],["easiest",{"_index":1803,"t":{"264":{"position":[[106,7]]}}}],["easili",{"_index":2339,"t":{"423":{"position":[[1034,7]]},"425":{"position":[[793,6]]},"593":{"position":[[449,7]]},"645":{"position":[[286,7]]},"664":{"position":[[449,7]]},"677":{"position":[[286,7]]},"1061":{"position":[[432,6]]},"2108":{"position":[[148,6]]},"2119":{"position":[[225,6]]},"2274":{"position":[[91,6]]},"2287":{"position":[[1096,6]]},"2301":{"position":[[1096,6]]},"2327":{"position":[[536,6]]},"2329":{"position":[[802,6]]},"2394":{"position":[[536,6]]},"2396":{"position":[[802,6]]},"2431":{"position":[[1451,6]]},"2551":{"position":[[452,6]]},"2590":{"position":[[492,6]]},"2916":{"position":[[495,6]]},"3103":{"position":[[226,6]]},"3121":{"position":[[644,6]]},"3136":{"position":[[226,6]]},"3189":{"position":[[604,7]]},"3223":{"position":[[697,7]]},"3321":{"position":[[492,6]]},"3390":{"position":[[327,6]]},"3941":{"position":[[1057,6],[1144,7]]},"4009":{"position":[[370,6]]},"4094":{"position":[[420,6]]},"4098":{"position":[[733,6]]},"4163":{"position":[[4716,6]]},"4200":{"position":[[211,6]]},"4302":{"position":[[2281,6]]},"4304":{"position":[[634,6]]},"4308":{"position":[[253,6]]},"4504":{"position":[[174,6]]},"4593":{"position":[[2354,6],[5754,6]]},"4654":{"position":[[310,6]]},"4681":{"position":[[260,6]]},"4759":{"position":[[492,6]]}}}],["east",{"_index":9830,"t":{"3183":{"position":[[216,4]]}}}],["eavesdrop",{"_index":5989,"t":{"1405":{"position":[[315,13]]},"4222":{"position":[[1067,14],[2689,13],[2907,13]]},"4224":{"position":[[1883,15],[2050,14]]}}}],["eb7522b1",{"_index":4701,"t":{"1177":{"position":[[1154,8],[1525,8],[1731,8],[2281,8],[2524,8],[2892,8],[2998,8]]}}}],["eba5414a4f8549b28a62af199d82dab5",{"_index":313,"t":{"28":{"position":[[3352,32]]}}}],["ebc048b02ab2",{"_index":7136,"t":{"1711":{"position":[[2509,12]]}}}],["ebfe5546",{"_index":2693,"t":{"555":{"position":[[424,9]]},"557":{"position":[[69,9]]}}}],["ebgp",{"_index":9979,"t":{"3352":{"position":[[2042,5]]}}}],["ebpf",{"_index":11345,"t":{"4226":{"position":[[2158,4]]},"4244":{"position":[[113,4]]},"4246":{"position":[[102,4]]}}}],["ebpf3",{"_index":11317,"t":{"4224":{"position":[[59,5],[666,6],[679,5],[944,5]]},"4226":{"position":[[1917,5]]},"4228":{"position":[[999,5]]}}}],["ec",{"_index":6220,"t":{"1455":{"position":[[1869,3]]}}}],["ec2",{"_index":417,"t":{"39":{"position":[[43,3]]},"701":{"position":[[257,3],[665,3],[702,3],[788,3],[964,3],[1043,3],[1173,3],[1213,3],[1972,3]]},"705":{"position":[[303,3]]},"734":{"position":[[154,3]]},"830":{"position":[[195,3]]}}}],["ec2//bin/activ",{"_index":9014,"t":{"2725":{"position":[[476,31]]}}}],["environment_name>/scripts/activ",{"_index":9013,"t":{"2725":{"position":[[374,35]]}}}],["environments/.lock",{"_index":5147,"t":{"1236":{"position":[[888,18]]}}}],["environments//playbook",{"_index":6677,"t":{"1661":{"position":[[648,35]]}}}],["environments//roles//api/key",{"_index":8493,"t":{"2478":{"position":[[2154,30]]}}}],["https:///api/v2/import",{"_index":8509,"t":{"2480":{"position":[[1077,36]]}}}],["https:///engagement/.servic",{"_index":6602,"t":{"1646":{"position":[[1812,11]]},"1648":{"position":[[555,11]]}}}],["id_rsa.neutron",{"_index":9766,"t":{"3126":{"position":[[197,14]]}}}],["id_rsa.oper",{"_index":6284,"t":{"1472":{"position":[[3227,16],[3428,15]]},"1480":{"position":[[162,15]]}}}],["id_token",{"_index":9275,"t":{"2908":{"position":[[493,11]]}}}],["idc",{"_index":2813,"t":{"557":{"position":[[6013,3]]}}}],["idea",{"_index":2307,"t":{"407":{"position":[[141,4]]},"417":{"position":[[934,4]]},"427":{"position":[[629,4]]},"444":{"position":[[120,4]]},"706":{"position":[[1984,4]]},"755":{"position":[[783,4]]},"1240":{"position":[[101,4]]},"1348":{"position":[[348,4]]},"1354":{"position":[[647,4]]},"1661":{"position":[[182,4]]},"2163":{"position":[[4111,4]]},"2372":{"position":[[4,4]]},"2433":{"position":[[36,4]]},"3236":{"position":[[54,4],[300,5]]},"3238":{"position":[[143,4]]},"3279":{"position":[[396,5]]},"3288":{"position":[[4,4]]},"3323":{"position":[[485,4]]},"3625":{"position":[[265,4]]},"3996":{"position":[[152,4]]},"4224":{"position":[[131,4]]},"4230":{"position":[[691,4]]},"4414":{"position":[[450,4]]},"4433":{"position":[[2536,4]]},"4589":{"position":[[482,4]]}}}],["ideal",{"_index":2477,"t":{"485":{"position":[[131,5]]},"741":{"position":[[697,5]]},"852":{"position":[[141,5]]},"928":{"position":[[886,7]]},"934":{"position":[[2304,8]]},"1061":{"position":[[751,5]]},"1468":{"position":[[1195,6]]},"1819":{"position":[[886,7]]},"1825":{"position":[[2304,8]]},"2025":{"position":[[304,5]]},"2914":{"position":[[1444,7]]},"2952":{"position":[[886,7]]},"2958":{"position":[[2304,8]]},"3378":{"position":[[1415,8]]},"3381":{"position":[[985,8]]},"3529":{"position":[[404,7]]},"3573":{"position":[[121,5]]},"3592":{"position":[[1577,8]]},"4100":{"position":[[730,5]]},"4224":{"position":[[1834,7],[2604,7]]}}}],["idempot",{"_index":7312,"t":{"2034":{"position":[[20,10]]},"3352":{"position":[[2979,10]]}}}],["ident",{"_index":502,"t":{"70":{"position":[[150,8]]},"84":{"position":[[38,8],[252,8],[411,10],[582,10],[621,10],[703,8]]},"199":{"position":[[359,11],[603,8],[655,8],[1797,9]]},"311":{"position":[[95,10],[435,8]]},"313":{"position":[[137,8]]},"319":{"position":[[28,11],[64,10]]},"323":{"position":[[235,10]]},"822":{"position":[[26,8]]},"836":{"position":[[16,8]]},"934":{"position":[[324,8]]},"1013":{"position":[[305,8]]},"1018":{"position":[[63,8]]},"1054":{"position":[[305,8]]},"1199":{"position":[[529,8]]},"1472":{"position":[[3288,8]]},"1825":{"position":[[324,8]]},"2184":{"position":[[727,9],[1420,10],[1933,9]]},"2196":{"position":[[2342,8],[2399,8],[3147,8],[3204,8]]},"2227":{"position":[[411,8],[432,8]]},"2276":{"position":[[171,8],[377,9],[526,9],[746,8]]},"2366":{"position":[[97,10],[465,8]]},"2376":{"position":[[169,8]]},"2380":{"position":[[763,8]]},"2429":{"position":[[164,8]]},"2431":{"position":[[1007,8],[4209,8]]},"2433":{"position":[[213,8],[728,8],[770,8]]},"2437":{"position":[[97,8],[291,8]]},"2439":{"position":[[326,10]]},"2499":{"position":[[450,9]]},"2512":{"position":[[595,9]]},"2574":{"position":[[480,9]]},"2584":{"position":[[641,8],[678,8],[737,8]]},"2586":{"position":[[251,8],[288,8],[347,8]]},"2836":{"position":[[78,10]]},"2889":{"position":[[282,8]]},"2958":{"position":[[324,8]]},"3022":{"position":[[221,8]]},"3119":{"position":[[414,8],[442,10]]},"3189":{"position":[[36,8]]},"3234":{"position":[[133,8]]},"3313":{"position":[[91,8],[166,8],[701,10]]},"3460":{"position":[[69,8],[389,8],[507,11],[556,8]]},"3470":{"position":[[27,8],[222,9],[745,8]]},"3531":{"position":[[441,8]]},"3569":{"position":[[1249,8]]},"3638":{"position":[[155,8]]},"3644":{"position":[[189,8]]},"3712":{"position":[[1372,10]]},"4081":{"position":[[1569,8],[2212,8]]},"4085":{"position":[[114,8]]},"4202":{"position":[[272,8],[290,8],[825,8]]},"4222":{"position":[[3608,8]]},"4304":{"position":[[2498,8],[2676,10]]},"4313":{"position":[[997,8],[1177,10],[1444,8]]},"4327":{"position":[[649,10]]},"4412":{"position":[[85,8],[159,8]]},"4420":{"position":[[532,10],[577,10],[642,8]]},"4473":{"position":[[258,8]]},"4562":{"position":[[5805,10]]},"4587":{"position":[[615,10],[944,8],[1096,10],[1170,11],[1197,11]]},"4589":{"position":[[450,8],[566,11],[662,11]]},"4591":{"position":[[25,8]]},"4593":{"position":[[1047,9],[1163,8],[1365,8],[1932,9],[3945,8],[4134,8],[4177,8],[5271,10]]},"4604":{"position":[[212,8]]},"4606":{"position":[[372,8]]},"4616":{"position":[[46,8],[68,8]]},"4618":{"position":[[140,8],[478,8],[711,8]]},"4620":{"position":[[285,8]]},"4623":{"position":[[22,8],[524,8]]},"4632":{"position":[[2759,8]]},"4643":{"position":[[2759,8],[2805,8],[3074,8]]},"4660":{"position":[[2822,9]]},"4669":{"position":[[822,11]]},"4722":{"position":[[142,8]]},"4826":{"position":[[3532,8]]},"4839":{"position":[[381,8]]}}}],["identif",{"_index":8573,"t":{"2520":{"position":[[332,14]]},"4691":{"position":[[355,14]]}}}],["identifi",{"_index":140,"t":{"19":{"position":[[184,10]]},"26":{"position":[[148,10]]},"28":{"position":[[7,10]]},"31":{"position":[[7,10]]},"33":{"position":[[7,10]]},"199":{"position":[[1550,11]]},"303":{"position":[[607,11]]},"307":{"position":[[301,11]]},"345":{"position":[[11,8]]},"557":{"position":[[5386,10]]},"934":{"position":[[2235,8]]},"938":{"position":[[2143,8]]},"946":{"position":[[601,8]]},"1163":{"position":[[31,10],[63,10]]},"1177":{"position":[[3611,11]]},"1395":{"position":[[31,10],[63,10]]},"1825":{"position":[[2235,8]]},"1829":{"position":[[2143,8]]},"1837":{"position":[[601,8]]},"2048":{"position":[[659,8]]},"2242":{"position":[[184,8]]},"2272":{"position":[[283,11]]},"2285":{"position":[[420,8]]},"2299":{"position":[[420,8]]},"2325":{"position":[[717,10]]},"2337":{"position":[[99,10]]},"2343":{"position":[[302,11]]},"2347":{"position":[[726,11]]},"2353":{"position":[[298,10]]},"2392":{"position":[[717,10]]},"2404":{"position":[[99,10]]},"2410":{"position":[[302,11]]},"2414":{"position":[[726,11]]},"2420":{"position":[[298,10]]},"2487":{"position":[[836,8],[1113,8]]},"2489":{"position":[[831,10],[1430,8],[1459,8]]},"2497":{"position":[[289,11]]},"2499":{"position":[[53,11]]},"2508":{"position":[[413,8]]},"2514":{"position":[[200,10]]},"2520":{"position":[[811,10]]},"2531":{"position":[[1573,8]]},"2537":{"position":[[262,10]]},"2549":{"position":[[54,11]]},"2551":{"position":[[91,11],[307,8]]},"2557":{"position":[[109,11]]},"2682":{"position":[[527,8]]},"2810":{"position":[[146,10]]},"2958":{"position":[[2235,8]]},"2962":{"position":[[2143,8]]},"2970":{"position":[[601,8]]},"3073":{"position":[[732,11]]},"3238":{"position":[[280,8]]},"3474":{"position":[[171,10]]},"3533":{"position":[[1492,10]]},"3594":{"position":[[291,10]]},"3604":{"position":[[39,10]]},"3994":{"position":[[225,11]]},"4224":{"position":[[1794,10]]},"4257":{"position":[[2458,8]]},"4310":{"position":[[157,10]]},"4414":{"position":[[50,10]]},"4506":{"position":[[1471,9]]},"4533":{"position":[[171,11]]},"4537":{"position":[[257,8]]},"4539":{"position":[[5088,10]]},"4541":{"position":[[2289,11]]},"4587":{"position":[[129,11]]},"4691":{"position":[[498,11],[572,11],[587,8]]},"4695":{"position":[[221,8]]},"4703":{"position":[[11,11]]},"4707":{"position":[[68,11]]},"4713":{"position":[[107,10],[323,11]]},"4715":{"position":[[143,11],[317,10]]},"4849":{"position":[[431,11]]}}}],["identifying/authent",{"_index":11474,"t":{"4313":{"position":[[300,26]]}}}],["identitiesonly=y",{"_index":6280,"t":{"1472":{"position":[[2273,19],[3406,18]]},"1480":{"position":[[140,18]]}}}],["identity.authent",{"_index":9529,"t":{"3036":{"position":[[6011,21]]}}}],["identity.endpoint",{"_index":9514,"t":{"3036":{"position":[[5524,22]]}}}],["identity.group",{"_index":9508,"t":{"3036":{"position":[[5413,19]]}}}],["identity.o",{"_index":9510,"t":{"3036":{"position":[[5452,12]]}}}],["identity.polici",{"_index":9515,"t":{"3036":{"position":[[5547,20]]}}}],["identity.project",{"_index":9507,"t":{"3036":{"position":[[5391,21]]}}}],["identity.region",{"_index":9512,"t":{"3036":{"position":[[5481,20]]}}}],["identity.rol",{"_index":9509,"t":{"3036":{"position":[[5433,18]]}}}],["identity.role_assign",{"_index":9522,"t":{"3036":{"position":[[5789,26]]}}}],["identity.servic",{"_index":9513,"t":{"3036":{"position":[[5502,21]]}}}],["identity.us",{"_index":9506,"t":{"3036":{"position":[[5372,18]]}}}],["identity:.yml",{"_index":4639,"t":{"1175":{"position":[[41,34]]},"1179":{"position":[[49,35],[536,34],[1299,35]]}}}],["inventory/host_vars/inventory_host_name.yml",{"_index":5905,"t":{"1383":{"position":[[1558,44]]}}}],["inventory/host_vars/node01.yml",{"_index":5094,"t":{"1226":{"position":[[4198,30],[4328,30],[4479,30],[4646,30],[4933,30],[5219,30],[5357,30]]}}}],["inventory/host_vars/testb",{"_index":5930,"t":{"1385":{"position":[[1714,27],[2039,27]]}}}],["inventory_hostnam",{"_index":889,"t":{"153":{"position":[[541,18]]},"1303":{"position":[[536,18],[670,18],[2233,18]]},"2088":{"position":[[356,18]]}}}],["inventory_reconcil",{"_index":7484,"t":{"2071":{"position":[[2164,20],[2235,20]]},"2155":{"position":[[2031,20],[2119,20]]}}}],["invers",{"_index":3644,"t":{"912":{"position":[[2568,7],[2625,7],[2678,7],[2725,7],[2777,7],[2836,7],[2896,7],[2955,7],[3020,7],[3074,7]]},"914":{"position":[[1801,7],[1848,7],[1894,7],[1952,7]]},"1005":{"position":[[1793,7],[1828,7],[1862,7],[1899,7],[1936,7],[1969,7]]},"1796":{"position":[[2568,7],[2625,7],[2678,7],[2725,7],[2777,7],[2836,7],[2896,7],[2955,7],[3020,7],[3074,7]]},"1798":{"position":[[1801,7],[1848,7],[1894,7],[1952,7]]},"1896":{"position":[[1793,7],[1828,7],[1862,7],[1899,7],[1936,7],[1969,7]]}}}],["invest",{"_index":9693,"t":{"3067":{"position":[[454,9]]},"3248":{"position":[[3,8]]},"3355":{"position":[[385,8]]},"3968":{"position":[[2531,6],[2694,6]]},"3971":{"position":[[246,10],[1001,10]]},"3973":{"position":[[174,10],[716,11]]},"4291":{"position":[[2368,10]]},"4508":{"position":[[963,10]]}}}],["investig",{"_index":2912,"t":{"588":{"position":[[1608,11]]},"938":{"position":[[663,11]]},"1619":{"position":[[683,11]]},"1829":{"position":[[663,11]]},"1950":{"position":[[683,11]]},"2962":{"position":[[663,11]]},"3088":{"position":[[747,11]]},"3121":{"position":[[1246,11]]},"3964":{"position":[[408,14]]},"4185":{"position":[[710,12]]},"4230":{"position":[[88,12]]},"4291":{"position":[[608,13]]},"4520":{"position":[[112,11]]}}}],["invit",{"_index":536,"t":{"72":{"position":[[389,6]]},"224":{"position":[[670,6]]},"3629":{"position":[[140,7]]}}}],["invoic",{"_index":3867,"t":{"940":{"position":[[153,7]]},"1831":{"position":[[153,7]]},"2964":{"position":[[153,7]]},"4738":{"position":[[252,8]]},"4757":{"position":[[318,8],[451,8]]}}}],["invok",{"_index":2387,"t":{"440":{"position":[[498,8]]},"489":{"position":[[641,8]]},"4222":{"position":[[3845,6]]}}}],["involv",{"_index":1527,"t":{"205":{"position":[[116,9]]},"249":{"position":[[1228,9]]},"280":{"position":[[952,8]]},"351":{"position":[[90,8]]},"407":{"position":[[198,9]]},"595":{"position":[[655,9]]},"1244":{"position":[[812,8]]},"1346":{"position":[[815,8]]},"1369":{"position":[[112,9]]},"2325":{"position":[[1223,9]]},"2392":{"position":[[1223,9]]},"2463":{"position":[[583,9]]},"2487":{"position":[[30,8],[756,8],[1019,8]]},"2527":{"position":[[30,8]]},"3381":{"position":[[1495,9]]},"3563":{"position":[[92,11]]},"3960":{"position":[[746,8]]},"4222":{"position":[[1430,8],[1717,8],[3029,8]]},"4224":{"position":[[2654,7]]},"4228":{"position":[[961,8]]},"4230":{"position":[[1153,8],[4121,8]]},"4302":{"position":[[3614,8]]},"4304":{"position":[[119,8]]},"4306":{"position":[[45,8]]},"4331":{"position":[[155,8]]},"4333":{"position":[[234,8]]},"4604":{"position":[[259,9]]},"4724":{"position":[[283,8]]}}}],["io",{"_index":10948,"t":{"3928":{"position":[[2777,2],[2841,2],[2929,2]]},"3932":{"position":[[662,2]]}}}],["iod32",{"_index":6643,"t":{"1650":{"position":[[803,5]]},"1975":{"position":[[803,5]]}}}],["iodepth",{"_index":6641,"t":{"1650":{"position":[[605,7]]},"1975":{"position":[[605,7]]}}}],["iodepth=32",{"_index":6642,"t":{"1650":{"position":[[682,10]]},"1975":{"position":[[682,10]]}}}],["ioengine=\"libaio",{"_index":6617,"t":{"1650":{"position":[[80,17]]},"1975":{"position":[[80,17]]}}}],["ioengine=${ioengin",{"_index":6630,"t":{"1650":{"position":[[321,20],[637,20]]},"1975":{"position":[[321,20],[637,20]]}}}],["iop",{"_index":7176,"t":{"1720":{"position":[[124,4],[144,5],[1948,4],[1985,4],[2796,4],[2867,4]]},"3665":{"position":[[563,5]]},"3702":{"position":[[635,5],[797,4]]},"3789":{"position":[[635,5]]},"3894":{"position":[[701,4]]},"3925":{"position":[[1811,4]]},"3928":{"position":[[4990,4]]},"3930":{"position":[[506,4],[671,5]]},"3932":{"position":[[485,4]]},"3936":{"position":[[127,4]]},"3938":{"position":[[209,4]]},"4385":{"position":[[419,4]]}}}],["iotop",{"_index":4519,"t":{"1144":{"position":[[383,5]]}}}],["ip",{"_index":2738,"t":{"557":{"position":[[1285,3],[1356,2],[1455,2]]},"692":{"position":[[124,2],[220,2],[232,2]]},"741":{"position":[[465,2],[487,2]]},"747":{"position":[[43,2],[139,2],[151,2]]},"828":{"position":[[193,3]]},"846":{"position":[[140,2],[162,4],[178,2],[216,2]]},"924":{"position":[[1394,5]]},"932":{"position":[[3234,2],[3431,2],[3434,2],[3533,2],[3601,2],[3617,2],[3659,2],[3687,3],[3727,2]]},"934":{"position":[[2051,3]]},"938":{"position":[[1941,3]]},"940":{"position":[[753,4]]},"942":{"position":[[814,3],[855,2],[925,2]]},"978":{"position":[[905,2],[1054,2]]},"980":{"position":[[206,4]]},"1181":{"position":[[195,2]]},"1226":{"position":[[1626,2],[1766,2],[1876,2]]},"1230":{"position":[[652,2],[742,2]]},"1252":{"position":[[2602,2],[2697,2],[2829,2]]},"1391":{"position":[[1318,2],[1359,3]]},"1547":{"position":[[33,3],[46,2],[79,2]]},"1574":{"position":[[690,2]]},"1704":{"position":[[1133,3],[1259,3],[1385,3]]},"1743":{"position":[[189,2]]},"1745":{"position":[[14,2],[440,2]]},"1815":{"position":[[1394,5]]},"1823":{"position":[[3234,2],[3431,2],[3434,2],[3533,2],[3601,2],[3617,2],[3659,2],[3687,3],[3727,2]]},"1825":{"position":[[2051,3]]},"1829":{"position":[[1941,3]]},"1831":{"position":[[753,4]]},"1833":{"position":[[814,3],[855,2],[925,2]]},"1869":{"position":[[905,2],[1054,2]]},"1871":{"position":[[206,4]]},"1917":{"position":[[690,2]]},"2032":{"position":[[1676,2]]},"2034":{"position":[[873,2],[1763,2]]},"2037":{"position":[[322,2],[990,2],[1179,2]]},"2048":{"position":[[393,2],[1411,2],[1809,2],[3559,2]]},"2130":{"position":[[14,2],[146,2],[169,2]]},"2180":{"position":[[222,2]]},"2190":{"position":[[532,2]]},"2192":{"position":[[237,2]]},"2196":{"position":[[1752,2]]},"2199":{"position":[[98,2],[254,2]]},"2236":{"position":[[512,2]]},"2240":{"position":[[1501,3],[1515,2]]},"2248":{"position":[[378,2],[424,2]]},"2549":{"position":[[97,2],[434,2]]},"2614":{"position":[[466,3],[545,4]]},"2649":{"position":[[3028,3]]},"2714":{"position":[[324,2]]},"2716":{"position":[[1891,2]]},"2718":{"position":[[325,2],[707,2]]},"2849":{"position":[[38,3],[84,3]]},"2855":{"position":[[146,3],[259,3]]},"2948":{"position":[[1394,5]]},"2956":{"position":[[3234,2],[3431,2],[3434,2],[3533,2],[3601,2],[3617,2],[3659,2],[3687,3],[3727,2]]},"2958":{"position":[[2051,3]]},"2962":{"position":[[1941,3]]},"2964":{"position":[[753,4]]},"2966":{"position":[[814,3],[855,2],[925,2]]},"3002":{"position":[[905,2],[1054,2]]},"3004":{"position":[[206,4]]},"3153":{"position":[[1526,2],[1635,3]]},"3185":{"position":[[1056,2]]},"3348":{"position":[[543,3]]},"3978":{"position":[[48,2]]},"3988":{"position":[[487,2],[513,2]]},"4039":{"position":[[33,2],[128,2]]},"4051":{"position":[[384,2],[410,2]]},"4109":{"position":[[3154,2]]},"4113":{"position":[[1291,2],[1312,2]]},"4135":{"position":[[477,2]]},"4222":{"position":[[3558,2],[3631,2]]},"4226":{"position":[[3716,3]]},"4228":{"position":[[589,2],[631,2]]},"4302":{"position":[[1029,3]]},"4849":{"position":[[1243,3]]},"4872":{"position":[[427,2]]}}}],["ip=10.50.40.230",{"_index":8206,"t":{"2252":{"position":[[2731,15]]}}}],["ip>:..servic",{"_index":6599,"t":{"1646":{"position":[[1231,18]]},"1648":{"position":[[1497,18]]}}}],["mds_group_nam",{"_index":4842,"t":{"1185":{"position":[[1442,15]]}}}],["mds_placement_label",{"_index":5956,"t":{"1391":{"position":[[2598,20]]}}}],["meal",{"_index":1683,"t":{"239":{"position":[[309,5]]}}}],["mean",{"_index":1500,"t":{"199":{"position":[[3002,4]]},"288":{"position":[[321,5]]},"309":{"position":[[161,6]]},"337":{"position":[[226,5]]},"368":{"position":[[3052,5],[3172,5]]},"423":{"position":[[161,4]]},"487":{"position":[[310,5]]},"741":{"position":[[407,5],[1205,5]]},"776":{"position":[[184,5]]},"846":{"position":[[833,5]]},"938":{"position":[[1139,7]]},"973":{"position":[[212,5]]},"1040":{"position":[[76,5]]},"1437":{"position":[[128,7]]},"1484":{"position":[[521,7]]},"1571":{"position":[[280,4]]},"1603":{"position":[[453,4]]},"1617":{"position":[[98,4]]},"1635":{"position":[[144,4]]},"1829":{"position":[[1139,7]]},"1864":{"position":[[212,5]]},"1904":{"position":[[280,4]]},"1948":{"position":[[98,4]]},"1984":{"position":[[104,7]]},"2050":{"position":[[11,5]]},"2065":{"position":[[953,4],[1417,4],[1736,4],[2057,4],[2388,4],[2710,4],[3032,4],[3353,4],[3669,4]]},"2165":{"position":[[597,5]]},"2252":{"position":[[240,5]]},"2276":{"position":[[562,4]]},"2295":{"position":[[103,5]]},"2309":{"position":[[103,5]]},"2341":{"position":[[68,5]]},"2374":{"position":[[74,5]]},"2408":{"position":[[68,5]]},"2429":{"position":[[146,5]]},"2439":{"position":[[298,7]]},"2447":{"position":[[546,5]]},"2467":{"position":[[269,7],[1356,5]]},"2469":{"position":[[29,5]]},"2489":{"position":[[1721,8]]},"2602":{"position":[[2074,7]]},"2614":{"position":[[86,5]]},"2714":{"position":[[372,5]]},"2902":{"position":[[114,8]]},"2962":{"position":[[1139,7]]},"2997":{"position":[[212,5]]},"3276":{"position":[[486,5]]},"3298":{"position":[[506,5]]},"3348":{"position":[[227,5]]},"3533":{"position":[[406,5]]},"3549":{"position":[[974,5]]},"3582":{"position":[[1500,5],[2011,5]]},"3584":{"position":[[49,5]]},"3596":{"position":[[170,6]]},"3598":{"position":[[690,5]]},"3653":{"position":[[424,7]]},"3661":{"position":[[7,7]]},"3665":{"position":[[10,7]]},"3667":{"position":[[177,7]]},"3669":{"position":[[188,5]]},"3671":{"position":[[183,5],[730,7],[797,7]]},"3690":{"position":[[424,7]]},"3698":{"position":[[99,7]]},"3702":{"position":[[82,7]]},"3708":{"position":[[189,7]]},"3710":{"position":[[201,5]]},"3712":{"position":[[1162,7],[1806,7]]},"3747":{"position":[[225,7],[464,7]]},"3777":{"position":[[424,7]]},"3785":{"position":[[99,7]]},"3789":{"position":[[82,7]]},"3801":{"position":[[177,7]]},"3803":{"position":[[188,5]]},"3805":{"position":[[183,5],[837,7],[904,7]]},"3829":{"position":[[75,5],[796,7],[3603,7],[4801,5]]},"3866":{"position":[[79,5]]},"3872":{"position":[[320,7]]},"3874":{"position":[[438,7]]},"3894":{"position":[[156,5],[298,5],[645,5],[1494,5]]},"3910":{"position":[[410,5]]},"3928":{"position":[[5348,7]]},"3930":{"position":[[553,5],[607,5]]},"3982":{"position":[[270,6]]},"4007":{"position":[[77,7]]},"4037":{"position":[[262,5]]},"4075":{"position":[[5,7]]},"4096":{"position":[[1004,5]]},"4104":{"position":[[326,5]]},"4107":{"position":[[2035,4]]},"4109":{"position":[[435,7]]},"4118":{"position":[[5,7]]},"4159":{"position":[[1510,5]]},"4161":{"position":[[736,6]]},"4165":{"position":[[242,5]]},"4189":{"position":[[388,5]]},"4217":{"position":[[5,7]]},"4220":{"position":[[1484,7]]},"4224":{"position":[[1482,5]]},"4291":{"position":[[1055,5],[1892,4]]},"4296":{"position":[[5,7]]},"4300":{"position":[[114,5]]},"4302":{"position":[[3857,5]]},"4353":{"position":[[405,7]]},"4376":{"position":[[693,6]]},"4385":{"position":[[619,4]]},"4414":{"position":[[186,5]]},"4429":{"position":[[84,7]]},"4431":{"position":[[1026,5]]},"4433":{"position":[[125,6],[307,7],[1703,5],[1965,7]]},"4442":{"position":[[60,7]]},"4444":{"position":[[238,5],[630,4]]},"4448":{"position":[[909,7]]},"4453":{"position":[[60,7]]},"4455":{"position":[[238,5],[630,4]]},"4459":{"position":[[659,7]]},"4473":{"position":[[90,7]]},"4483":{"position":[[540,7]]},"4485":{"position":[[1814,5]]},"4525":{"position":[[583,4]]},"4527":{"position":[[5,7]]},"4537":{"position":[[1311,6]]},"4539":{"position":[[3423,5]]},"4562":{"position":[[5081,5]]},"4574":{"position":[[60,7]]},"4593":{"position":[[362,5]]},"4606":{"position":[[77,7]]},"4612":{"position":[[694,5]]},"4614":{"position":[[348,7],[1302,5]]},"4707":{"position":[[786,6]]}}}],["meaning",{"_index":2341,"t":{"423":{"position":[[1212,10]]},"2065":{"position":[[80,10]]},"3308":{"position":[[356,10]]},"4045":{"position":[[2107,10]]},"4691":{"position":[[132,10]]}}}],["meaningfulli",{"_index":11456,"t":{"4304":{"position":[[1826,12]]}}}],["meant",{"_index":2331,"t":{"421":{"position":[[319,5]]},"446":{"position":[[621,5]]},"584":{"position":[[24,5]]},"946":{"position":[[592,5]]},"1837":{"position":[[592,5]]},"2285":{"position":[[547,5]]},"2299":{"position":[[547,5]]},"2435":{"position":[[98,5]]},"2970":{"position":[[592,5]]},"3077":{"position":[[49,5]]},"3357":{"position":[[3236,5]]},"3549":{"position":[[883,5]]},"3582":{"position":[[1126,5]]},"3606":{"position":[[1510,5]]},"3677":{"position":[[1319,5]]},"3791":{"position":[[1341,5]]},"3904":{"position":[[872,5]]},"3928":{"position":[[5449,5]]},"3930":{"position":[[117,5]]},"3934":{"position":[[345,5]]},"4667":{"position":[[12882,5]]},"4839":{"position":[[1500,5]]}}}],["meanwhil",{"_index":1248,"t":{"179":{"position":[[1219,9]]},"848":{"position":[[302,10]]},"3119":{"position":[[200,10]]}}}],["measur",{"_index":1531,"t":{"205":{"position":[[369,8]]},"209":{"position":[[131,9]]},"924":{"position":[[1566,9]]},"1387":{"position":[[299,8]]},"1484":{"position":[[299,8],[745,8]]},"1815":{"position":[[1566,9]]},"1979":{"position":[[299,8]]},"2148":{"position":[[299,8]]},"2478":{"position":[[2010,9]]},"2531":{"position":[[991,8]]},"2559":{"position":[[185,12]]},"2598":{"position":[[185,12]]},"2699":{"position":[[108,12]]},"2948":{"position":[[1566,9]]},"3248":{"position":[[147,10]]},"3592":{"position":[[1561,10],[2116,9]]},"3661":{"position":[[477,8]]},"3698":{"position":[[582,8]]},"3731":{"position":[[2033,8]]},"3757":{"position":[[89,11],[173,7]]},"3761":{"position":[[249,9]]},"3785":{"position":[[582,8]]},"3826":{"position":[[450,8]]},"3894":{"position":[[353,8]]},"4100":{"position":[[95,8],[413,8]]},"4102":{"position":[[152,9],[231,8],[453,8],[521,8],[790,8]]},"4104":{"position":[[280,7],[374,8],[557,8]]},"4109":{"position":[[2329,8],[4653,8]]},"4133":{"position":[[2061,7]]},"4159":{"position":[[1720,11]]},"4169":{"position":[[249,8]]},"4220":{"position":[[1688,8]]},"4222":{"position":[[150,8]]},"4302":{"position":[[4268,9],[4801,8]]},"4317":{"position":[[52,8]]},"4329":{"position":[[15,7]]},"4331":{"position":[[15,7]]},"4479":{"position":[[700,7]]},"4545":{"position":[[38,12],[624,12]]}}}],["mechan",{"_index":2039,"t":{"317":{"position":[[84,10]]},"530":{"position":[[2242,9],[2420,10]]},"668":{"position":[[444,9],[683,9],[718,9]]},"701":{"position":[[681,10]]},"816":{"position":[[22,9]]},"1240":{"position":[[50,10]]},"1301":{"position":[[910,10]]},"2052":{"position":[[51,10]]},"2196":{"position":[[115,10]]},"2261":{"position":[[283,10]]},"2270":{"position":[[15,9]]},"2283":{"position":[[62,10]]},"2297":{"position":[[62,10]]},"2335":{"position":[[366,11]]},"2402":{"position":[[366,11]]},"2529":{"position":[[581,10]]},"2557":{"position":[[485,11]]},"2574":{"position":[[391,11]]},"2600":{"position":[[268,9]]},"2914":{"position":[[773,10]]},"3022":{"position":[[1304,9]]},"3384":{"position":[[274,9]]},"3584":{"position":[[35,9]]},"3665":{"position":[[1040,9]]},"3679":{"position":[[150,9]]},"3681":{"position":[[1163,9]]},"3698":{"position":[[1684,9]]},"3702":{"position":[[1253,9]]},"3718":{"position":[[1190,9]]},"3731":{"position":[[811,9]]},"3735":{"position":[[266,10]]},"3789":{"position":[[1112,9]]},"3793":{"position":[[150,9]]},"3811":{"position":[[1167,9]]},"3866":{"position":[[103,9]]},"4037":{"position":[[69,10]]},"4081":{"position":[[993,9]]},"4098":{"position":[[327,11]]},"4135":{"position":[[614,10]]},"4220":{"position":[[1263,11],[1883,11]]},"4224":{"position":[[1957,10],[2161,10],[2807,9]]},"4226":{"position":[[3618,10]]},"4273":{"position":[[352,10]]},"4294":{"position":[[442,10]]},"4298":{"position":[[350,10],[518,10],[775,10]]},"4300":{"position":[[199,10],[384,10]]},"4304":{"position":[[1074,10]]},"4310":{"position":[[511,10],[594,10],[1078,10],[1781,10],[1887,10],[2121,10]]},"4313":{"position":[[154,11]]},"4315":{"position":[[148,9]]},"4410":{"position":[[432,10]]},"4459":{"position":[[1496,10],[2075,10]]},"4485":{"position":[[1249,10]]},"4529":{"position":[[314,11],[393,10]]},"4535":{"position":[[516,11]]},"4539":{"position":[[1410,11],[3587,10]]},"4547":{"position":[[1933,11],[2212,10],[2352,11]]},"4593":{"position":[[5916,10]]},"4701":{"position":[[244,8]]},"4726":{"position":[[886,9]]}}}],["media",{"_index":1533,"t":{"207":{"position":[[24,5],[500,5],[578,5]]},"216":{"position":[[375,6]]},"224":{"position":[[430,6]]},"228":{"position":[[209,6]]},"247":{"position":[[210,5]]},"848":{"position":[[100,5],[259,5]]},"1464":{"position":[[212,5]]},"2027":{"position":[[838,5]]},"2032":{"position":[[141,5]]},"3352":{"position":[[1458,5]]},"3702":{"position":[[1519,6]]},"3789":{"position":[[1378,6]]}}}],["medium",{"_index":7690,"t":{"2139":{"position":[[276,6],[528,6]]},"3361":{"position":[[371,6]]},"3731":{"position":[[503,7]]},"3971":{"position":[[606,6]]},"4107":{"position":[[653,6]]},"4109":{"position":[[592,6],[977,6],[1098,6],[1239,6],[1306,6],[1409,6],[1501,6],[2596,6],[2720,6],[4477,6]]},"4133":{"position":[[406,6],[527,6],[668,6],[735,6],[838,6],[930,6],[988,6],[1677,6]]}}}],["meet",{"_index":47,"t":{"7":{"position":[[336,9],[647,5]]},"59":{"position":[[4,8]]},"66":{"position":[[12,8]]},"68":{"position":[[26,8],[61,4]]},"72":{"position":[[8,8]]},"76":{"position":[[44,5]]},"187":{"position":[[1201,8],[1268,8]]},"197":{"position":[[1133,9]]},"205":{"position":[[287,9]]},"207":{"position":[[465,8]]},"216":{"position":[[391,9]]},"220":{"position":[[56,4]]},"224":{"position":[[449,9]]},"237":{"position":[[83,4]]},"241":{"position":[[457,5]]},"253":{"position":[[27,4],[189,4],[404,7]]},"255":{"position":[[249,4]]},"280":{"position":[[144,4]]},"288":{"position":[[662,4]]},"699":{"position":[[597,5]]},"1056":{"position":[[1671,4]]},"1061":{"position":[[439,7]]},"1064":{"position":[[2150,4]]},"2380":{"position":[[393,4]]},"2487":{"position":[[309,4]]},"2644":{"position":[[689,4]]},"2672":{"position":[[689,4]]},"3110":{"position":[[320,4]]},"3533":{"position":[[440,8]]},"3608":{"position":[[481,8]]},"4176":{"position":[[90,4]]},"4508":{"position":[[29,4]]},"4520":{"position":[[540,4]]},"4560":{"position":[[1151,5],[2637,5],[3857,5]]},"4632":{"position":[[764,7],[2014,7],[2415,7],[2813,7]]}}}],["meetup",{"_index":1388,"t":{"194":{"position":[[528,7]]},"203":{"position":[[70,8]]}}}],["meltdown",{"_index":10323,"t":{"3661":{"position":[[609,9]]},"3698":{"position":[[716,9]]},"3785":{"position":[[716,9]]}}}],["member",{"_index":133,"t":{"19":{"position":[[83,7]]},"59":{"position":[[95,7]]},"78":{"position":[[527,6]]},"197":{"position":[[888,7],[1205,7]]},"199":{"position":[[408,7],[894,7],[2415,7],[2489,7]]},"307":{"position":[[35,7]]},"530":{"position":[[2114,7],[2287,7]]},"908":{"position":[[379,6]]},"930":{"position":[[372,6]]},"1169":{"position":[[303,8]]},"1407":{"position":[[699,6]]},"1527":{"position":[[532,6]]},"1679":{"position":[[377,6]]},"1704":{"position":[[1692,6],[2368,6]]},"1725":{"position":[[55,6],[132,6],[366,6]]},"1792":{"position":[[379,6]]},"1821":{"position":[[372,6]]},"2447":{"position":[[656,6]]},"2478":{"position":[[1437,8]]},"2489":{"position":[[1186,7]]},"2747":{"position":[[562,6]]},"2836":{"position":[[229,7]]},"2839":{"position":[[108,8]]},"2954":{"position":[[372,6]]},"3264":{"position":[[308,7],[419,7]]},"3346":{"position":[[599,7]]},"3378":{"position":[[516,6],[590,8]]},"3627":{"position":[[0,8],[92,6],[125,7],[420,7],[618,8]]},"3629":{"position":[[215,6],[261,7]]},"3638":{"position":[[22,6]]},"3644":{"position":[[40,7]]},"3648":{"position":[[125,7]]},"3724":{"position":[[188,7]]},"3817":{"position":[[188,7]]},"3928":{"position":[[1046,6]]},"3982":{"position":[[317,8]]},"4043":{"position":[[76,6]]},"4081":{"position":[[1585,7],[2227,6],[2262,6]]},"4085":{"position":[[95,6]]},"4535":{"position":[[1648,6]]},"4560":{"position":[[1403,8],[2842,8]]},"4632":{"position":[[1124,8]]},"4643":{"position":[[1210,6],[1269,6],[1406,6],[1582,6],[1708,6],[1807,6],[2080,6],[2292,6],[3247,6],[3289,7]]},"4667":{"position":[[13915,8]]}}}],["member':%(target.role.name)",{"_index":5711,"t":{"1324":{"position":[[6221,30]]},"2447":{"position":[[740,30]]},"4667":{"position":[[6249,30],[14046,30]]}}}],["member@lists.scs.commun",{"_index":1814,"t":{"266":{"position":[[429,26]]}}}],["membership",{"_index":168,"t":{"24":{"position":[[241,11]]},"323":{"position":[[124,11],[666,10],[724,11]]},"2465":{"position":[[344,11]]},"3629":{"position":[[474,11]]},"4539":{"position":[[3234,10]]}}}],["memcach",{"_index":6337,"t":{"1513":{"position":[[435,9],[1124,9],[1146,9]]},"2167":{"position":[[663,9],[693,9],[726,9]]},"2225":{"position":[[220,9]]},"3016":{"position":[[585,10]]}}}],["memcached.yaml.gotmpl",{"_index":11906,"t":{"4835":{"position":[[2388,21]]}}}],["memori",{"_index":2323,"t":{"417":{"position":[[1615,6]]},"541":{"position":[[1196,7]]},"1040":{"position":[[320,6]]},"1105":{"position":[[601,6]]},"1107":{"position":[[496,6],[641,6]]},"1109":{"position":[[423,6]]},"1113":{"position":[[369,6]]},"1118":{"position":[[380,6]]},"1187":{"position":[[148,6],[195,6]]},"1189":{"position":[[666,6]]},"1383":{"position":[[103,7],[182,6],[423,6],[745,6],[881,7],[2259,6]]},"2360":{"position":[[1750,6]]},"2427":{"position":[[1750,6]]},"2682":{"position":[[265,7]]},"3653":{"position":[[769,6]]},"3656":{"position":[[212,6]]},"3663":{"position":[[47,7],[55,6],[184,6]]},"3673":{"position":[[1074,6]]},"3679":{"position":[[940,6]]},"3690":{"position":[[668,6]]},"3693":{"position":[[271,6]]},"3700":{"position":[[41,7],[49,6],[182,6],[296,6]]},"3704":{"position":[[847,6]]},"3706":{"position":[[743,6]]},"3714":{"position":[[345,6],[395,6],[1740,6],[1866,6],[1954,6],[2142,7]]},"3777":{"position":[[769,6]]},"3780":{"position":[[271,6]]},"3787":{"position":[[41,7],[49,6],[182,6],[296,6]]},"3793":{"position":[[1130,6]]},"3799":{"position":[[743,6]]},"3807":{"position":[[728,6]]},"3928":{"position":[[913,6],[1584,7]]}}}],["memory_mb",{"_index":9388,"t":{"3036":{"position":[[388,10]]}}}],["mental",{"_index":1449,"t":{"199":{"position":[[779,6]]}}}],["mention",{"_index":1535,"t":{"207":{"position":[[100,9]]},"258":{"position":[[374,7]]},"366":{"position":[[354,9]]},"528":{"position":[[528,9]]},"671":{"position":[[957,9]]},"706":{"position":[[1445,9]]},"930":{"position":[[614,9]]},"1036":{"position":[[3,9]]},"1821":{"position":[[614,9]]},"2323":{"position":[[10,9]]},"2390":{"position":[[10,9]]},"2604":{"position":[[471,9]]},"2636":{"position":[[888,9]]},"2954":{"position":[[614,9]]},"3323":{"position":[[96,7]]},"3361":{"position":[[670,9]]},"3592":{"position":[[2363,9]]},"3602":{"position":[[723,10]]},"3673":{"position":[[1263,9]]},"3698":{"position":[[1386,9]]},"3716":{"position":[[187,9]]},"3763":{"position":[[85,9],[135,9]]},"3809":{"position":[[164,9]]},"4013":{"position":[[466,9],[546,9]]},"4206":{"position":[[49,9]]},"4279":{"position":[[415,9]]},"4281":{"position":[[508,9]]},"4283":{"position":[[314,9]]},"4298":{"position":[[3,9]]},"4315":{"position":[[12,9]]},"4327":{"position":[[974,9]]},"4420":{"position":[[2769,10]]},"4422":{"position":[[373,9]]},"4479":{"position":[[330,9]]},"4520":{"position":[[566,9]]},"4547":{"position":[[2917,9]]},"4562":{"position":[[4995,10],[7357,9],[7651,9]]},"4691":{"position":[[324,9]]}}}],["mentor",{"_index":1453,"t":{"199":{"position":[[926,6]]}}}],["menu",{"_index":5636,"t":{"1314":{"position":[[143,4]]},"2478":{"position":[[2096,4]]}}}],["merch",{"_index":1551,"t":{"207":{"position":[[623,6]]},"209":{"position":[[33,5]]},"216":{"position":[[433,6],[455,5],[477,5]]}}}],["merchandis",{"_index":1699,"t":{"245":{"position":[[87,12]]}}}],["mere",{"_index":10169,"t":{"3525":{"position":[[697,6]]},"4310":{"position":[[2353,4]]}}}],["merg",{"_index":660,"t":{"95":{"position":[[621,7]]},"201":{"position":[[182,7],[278,7],[388,7],[437,7]]},"271":{"position":[[268,5],[308,5]]},"362":{"position":[[168,5],[188,6],[523,5],[633,5]]},"522":{"position":[[182,5]]},"1259":{"position":[[713,5]]},"1301":{"position":[[2007,7],[2271,6]]},"1303":{"position":[[181,6],[2275,7],[2620,5]]},"2059":{"position":[[481,7],[2849,6]]},"2065":{"position":[[737,6]]},"2443":{"position":[[495,5]]},"2747":{"position":[[622,5]]},"3251":{"position":[[147,6]]},"3352":{"position":[[331,5]]},"3533":{"position":[[1656,5],[1855,6]]},"3549":{"position":[[267,6]]},"4089":{"position":[[188,6]]},"4169":{"position":[[136,8]]},"4171":{"position":[[560,7]]},"4173":{"position":[[77,7]]}}}],["merge_yaml",{"_index":5527,"t":{"1303":{"position":[[326,11]]}}}],["mesh",{"_index":11324,"t":{"4224":{"position":[[1033,4]]},"4228":{"position":[[1082,5]]}}}],["messag",{"_index":524,"t":{"72":{"position":[[205,7]]},"249":{"position":[[1780,9],[1806,7],[1945,8],[1988,8]]},"258":{"position":[[311,9]]},"288":{"position":[[67,8],[394,7],[446,7],[624,9],[863,8],[961,7],[997,8],[1325,7]]},"337":{"position":[[331,7]]},"434":{"position":[[1013,7],[1219,7]]},"493":{"position":[[661,7],[867,7]]},"588":{"position":[[732,7]]},"688":{"position":[[94,7]]},"818":{"position":[[206,7]]},"822":{"position":[[247,7]]},"834":{"position":[[64,7],[170,7],[238,7],[270,7],[445,7]]},"887":{"position":[[969,7]]},"894":{"position":[[842,7]]},"912":{"position":[[1389,7]]},"914":{"position":[[782,7]]},"949":{"position":[[60,8]]},"1005":{"position":[[916,7]]},"1236":{"position":[[510,7],[977,7]]},"1472":{"position":[[2104,7],[2305,7]]},"1574":{"position":[[409,8]]},"1619":{"position":[[645,7]]},"1696":{"position":[[587,7]]},"1752":{"position":[[842,7]]},"1796":{"position":[[1389,7]]},"1798":{"position":[[782,7]]},"1811":{"position":[[969,7]]},"1840":{"position":[[60,8]]},"1896":{"position":[[916,7]]},"1917":{"position":[[409,8]]},"1950":{"position":[[645,7]]},"2142":{"position":[[214,8]]},"2146":{"position":[[608,8],[688,8]]},"2431":{"position":[[4316,7]]},"2747":{"position":[[176,10]]},"2973":{"position":[[60,8]]},"3034":{"position":[[261,7],[336,7]]},"3036":{"position":[[14806,7]]},"3159":{"position":[[491,7]]},"3264":{"position":[[108,7]]},"3916":{"position":[[60,8],[569,9]]},"4222":{"position":[[3228,8]]},"4302":{"position":[[365,7],[387,7],[2062,7]]},"4325":{"position":[[33,7],[85,7],[156,9]]},"4335":{"position":[[152,9]]},"4722":{"position":[[625,8]]}}}],["messages/month",{"_index":10995,"t":{"3971":{"position":[[134,14]]}}}],["met",{"_index":10513,"t":{"3688":{"position":[[232,3]]},"3775":{"position":[[232,3]]},"4104":{"position":[[1023,4]]},"4153":{"position":[[429,4]]},"4163":{"position":[[1143,3]]},"4376":{"position":[[239,3]]},"4407":{"position":[[581,4]]}}}],["meta",{"_index":3387,"t":{"865":{"position":[[891,5]]},"869":{"position":[[116,4]]},"871":{"position":[[690,5]]},"873":{"position":[[686,5]]},"875":{"position":[[125,5],[181,4]]},"887":{"position":[[9202,5]]},"978":{"position":[[380,4]]},"1175":{"position":[[5064,5]]},"1694":{"position":[[2471,4],[5803,4]]},"1766":{"position":[[891,5]]},"1770":{"position":[[116,4]]},"1772":{"position":[[690,5]]},"1774":{"position":[[686,5]]},"1776":{"position":[[125,5],[181,4]]},"1811":{"position":[[9202,5]]},"1869":{"position":[[380,4]]},"2117":{"position":[[1639,5]]},"3002":{"position":[[380,4]]},"3592":{"position":[[1340,4]]},"4748":{"position":[[43,4]]}}}],["metadata",{"_index":2417,"t":{"465":{"position":[[179,9]]},"518":{"position":[[889,9]]},"555":{"position":[[51,9]]},"586":{"position":[[811,9],[1257,9]]},"588":{"position":[[899,9]]},"705":{"position":[[1292,9]]},"706":{"position":[[977,8]]},"717":{"position":[[25,8]]},"816":{"position":[[308,8]]},"838":{"position":[[356,8],[442,8]]},"850":{"position":[[266,8]]},"869":{"position":[[59,8],[280,8],[386,8]]},"924":{"position":[[1499,8]]},"978":{"position":[[425,9],[1324,8]]},"1409":{"position":[[578,8]]},"1598":{"position":[[11,8],[31,8]]},"1711":{"position":[[1588,8]]},"1713":{"position":[[2031,8],[2080,8]]},"1770":{"position":[[59,8],[280,8],[386,8]]},"1815":{"position":[[1499,8]]},"1869":{"position":[[425,9],[1324,8]]},"2321":{"position":[[311,8]]},"2325":{"position":[[794,8]]},"2327":{"position":[[342,9]]},"2347":{"position":[[495,8]]},"2353":{"position":[[335,8]]},"2355":{"position":[[2669,8]]},"2358":{"position":[[252,9],[615,8]]},"2360":{"position":[[616,9]]},"2388":{"position":[[311,8]]},"2392":{"position":[[794,8]]},"2394":{"position":[[342,9]]},"2414":{"position":[[495,8]]},"2420":{"position":[[335,8]]},"2422":{"position":[[2669,8]]},"2425":{"position":[[252,9],[615,8]]},"2427":{"position":[[616,9]]},"2431":{"position":[[1330,8],[1759,8]]},"2602":{"position":[[379,9],[473,9],[654,9],[1016,9],[1149,9],[1258,9],[1613,9],[1770,9]]},"2665":{"position":[[216,8]]},"2740":{"position":[[893,9]]},"2948":{"position":[[1499,8]]},"3002":{"position":[[425,9],[1324,8]]},"3071":{"position":[[154,8]]},"3086":{"position":[[850,8]]},"3103":{"position":[[689,8]]},"3136":{"position":[[689,8],[949,8]]},"3398":{"position":[[941,8]]},"3410":{"position":[[19,8],[75,8],[496,8]]},"3527":{"position":[[1686,9]]},"3533":{"position":[[1239,8],[2451,9],[2590,8]]},"3539":{"position":[[473,8]]},"3541":{"position":[[203,8]]},"3770":{"position":[[164,8]]},"3820":{"position":[[129,8]]},"3857":{"position":[[420,8]]},"3872":{"position":[[673,8]]},"3932":{"position":[[1241,8]]},"3936":{"position":[[522,8],[626,8]]},"3941":{"position":[[1165,8]]},"4459":{"position":[[761,8]]},"4464":{"position":[[378,8]]},"4580":{"position":[[1311,8]]},"4593":{"position":[[2796,8]]},"4669":{"position":[[1142,8]]},"4703":{"position":[[23,8]]},"4748":{"position":[[90,8]]},"4773":{"position":[[249,8]]},"4826":{"position":[[1335,8]]},"4853":{"position":[[116,9]]},"4877":{"position":[[431,9],[569,9],[967,9]]}}}],["metadata.clusterstack.x",{"_index":2674,"t":{"551":{"position":[[2208,23],[2775,23]]}}}],["metadata.yaml",{"_index":2376,"t":{"438":{"position":[[262,13],[387,14],[479,13]]},"489":{"position":[[905,13]]},"493":{"position":[[267,13]]},"514":{"position":[[1421,13]]},"541":{"position":[[1853,14]]},"549":{"position":[[1397,14]]},"551":{"position":[[1930,14],[2165,13],[2722,13],[3440,13]]},"616":{"position":[[255,13]]}}}],["metadata_item",{"_index":3693,"t":{"914":{"position":[[2613,17],[3926,17],[5262,17]]},"1798":{"position":[[2613,17],[3926,17],[5262,17]]}}}],["metadatadevic",{"_index":6108,"t":{"1421":{"position":[[676,15]]}}}],["metadatapool",{"_index":6036,"t":{"1407":{"position":[[1758,13]]},"1409":{"position":[[538,13]]}}}],["metadataserv",{"_index":6071,"t":{"1409":{"position":[[1348,15]]}}}],["metadef",{"_index":10507,"t":{"3681":{"position":[[1154,8]]},"3718":{"position":[[1181,8]]},"3811":{"position":[[1158,8]]}}}],["metal",{"_index":2413,"t":{"465":{"position":[[61,5]]},"1013":{"position":[[96,5]]},"1054":{"position":[[96,5]]},"1077":{"position":[[314,5]]},"1455":{"position":[[491,5]]},"1457":{"position":[[503,5]]},"1460":{"position":[[437,5],[479,5]]},"2025":{"position":[[215,5]]},"2608":{"position":[[1215,5]]},"2849":{"position":[[13,5]]},"3022":{"position":[[41,6],[75,5]]},"3044":{"position":[[254,5]]},"3064":{"position":[[16,5],[164,5]]},"3081":{"position":[[64,5]]},"3086":{"position":[[1179,5]]},"3656":{"position":[[374,5]]},"3667":{"position":[[94,5],[233,5]]},"3669":{"position":[[298,5]]},"3693":{"position":[[433,5]]},"3708":{"position":[[106,5],[245,5]]},"3710":{"position":[[311,5],[862,5]]},"3712":{"position":[[2075,6]]},"3780":{"position":[[433,5]]},"3801":{"position":[[94,5],[233,5]]},"3803":{"position":[[298,5],[849,5]]},"3805":{"position":[[1173,6]]},"3960":{"position":[[778,5]]},"4204":{"position":[[240,5],[258,5]]},"4429":{"position":[[115,5],[195,5],[375,5]]},"4442":{"position":[[91,5],[171,5],[351,5]]},"4453":{"position":[[91,5],[171,5],[351,5]]}}}],["meter",{"_index":242,"t":{"28":{"position":[[1027,8]]},"1077":{"position":[[345,8]]},"3030":{"position":[[45,8]]},"3034":{"position":[[112,7],[138,6]]},"3038":{"position":[[369,6],[450,8]]},"3040":{"position":[[34,7]]},"3189":{"position":[[829,8]]},"3206":{"position":[[567,8]]},"3357":{"position":[[1749,8],[1762,8]]},"3502":{"position":[[1014,8],[1119,8]]},"3516":{"position":[[85,8],[398,9]]},"4736":{"position":[[392,8],[530,8]]},"4738":{"position":[[168,9]]},"4740":{"position":[[226,8],[261,8],[526,8]]},"4744":{"position":[[407,8]]},"4755":{"position":[[392,8]]},"4757":{"position":[[234,9],[475,8]]},"4759":{"position":[[214,8]]},"4763":{"position":[[61,8],[298,8]]},"4797":{"position":[[118,9],[167,8],[421,8]]},"4801":{"position":[[158,8],[352,8]]},"4826":{"position":[[4070,8],[4183,8]]}}}],["meter_sink",{"_index":9679,"t":{"3040":{"position":[[57,10],[83,10]]}}}],["meter_sourc",{"_index":9678,"t":{"3040":{"position":[[21,12]]}}}],["method",{"_index":750,"t":{"132":{"position":[[45,7]]},"319":{"position":[[599,7]]},"362":{"position":[[606,8]]},"382":{"position":[[744,6]]},"473":{"position":[[132,6]]},"543":{"position":[[994,6],[1600,7],[2499,7],[2684,7]]},"551":{"position":[[1761,6]]},"1301":{"position":[[1997,6]]},"1466":{"position":[[1343,6]]},"1486":{"position":[[54,8]]},"2119":{"position":[[70,6]]},"2443":{"position":[[784,6]]},"2478":{"position":[[1952,7]]},"2551":{"position":[[367,8]]},"2649":{"position":[[78,6],[146,6],[239,8]]},"2898":{"position":[[274,7],[347,7],[482,6]]},"2904":{"position":[[174,7]]},"3036":{"position":[[13526,7]]},"3761":{"position":[[211,7]]},"3763":{"position":[[127,7]]},"4195":{"position":[[183,7]]},"4291":{"position":[[2580,7]]},"4302":{"position":[[4617,6]]},"4479":{"position":[[434,7]]},"4535":{"position":[[3445,6]]},"4539":{"position":[[769,7],[1613,8],[1667,7],[1675,7],[1850,6],[5533,6]]},"4541":{"position":[[1279,7],[1598,7],[1754,7]]},"4547":{"position":[[2067,7],[2415,8]]},"4717":{"position":[[135,6]]}}}],["methodolog",{"_index":8537,"t":{"2489":{"position":[[57,11]]},"3290":{"position":[[34,11]]}}}],["metric",{"_index":1557,"t":{"207":{"position":[[773,7],[818,8]]},"541":{"position":[[1101,7],[1167,7],[1214,7]]},"590":{"position":[[996,7]]},"1040":{"position":[[147,7]]},"1411":{"position":[[1473,7]]},"1694":{"position":[[365,7],[496,7],[582,7],[7024,7]]},"2478":{"position":[[2896,7]]},"2559":{"position":[[382,8],[471,8]]},"2598":{"position":[[382,8],[471,8]]},"2612":{"position":[[218,6]]},"2614":{"position":[[101,7]]},"2616":{"position":[[333,7]]},"2618":{"position":[[89,7],[173,7]]},"2624":{"position":[[67,6],[119,6],[428,7],[506,6],[536,6],[705,6],[833,6]]},"2626":{"position":[[70,7]]},"2647":{"position":[[11,7],[1001,7],[1199,8],[1390,7]]},"2649":{"position":[[275,7],[384,7],[440,7],[560,8],[658,7],[803,8],[833,7],[886,7],[934,7],[2582,7]]},"2655":{"position":[[619,6]]},"2659":{"position":[[329,7]]},"2674":{"position":[[99,7]]},"2678":{"position":[[217,8]]},"2699":{"position":[[142,6]]},"2701":{"position":[[108,7],[183,7]]},"2703":{"position":[[23,7],[213,7],[398,7]]},"2716":{"position":[[693,7]]},"2720":{"position":[[1094,7],[1141,7],[1172,7],[1241,7],[1259,7],[1328,7],[1346,7]]},"2867":{"position":[[72,8],[87,7]]},"2869":{"position":[[26,7],[105,9],[115,8],[133,9],[143,8],[173,8],[198,9],[208,8]]},"2871":{"position":[[26,8],[159,7],[195,7]]},"3030":{"position":[[4,7],[144,7]]},"3032":{"position":[[51,7],[157,7],[218,7]]},"3038":{"position":[[295,7]]},"3044":{"position":[[117,8]]},"3067":{"position":[[554,7]]},"3101":{"position":[[296,7]]},"3189":{"position":[[591,7]]},"3292":{"position":[[771,7]]},"3352":{"position":[[3294,7]]},"4222":{"position":[[4096,7]]},"4420":{"position":[[1492,7]]},"4562":{"position":[[381,7],[6324,8],[6354,8],[6401,8]]},"4722":{"position":[[465,8]]},"4726":{"position":[[299,7],[329,7],[369,7],[377,7],[522,8],[614,7],[691,7],[865,7]]},"4728":{"position":[[383,7],[812,7]]},"4730":{"position":[[852,7],[1384,6],[1588,7],[2475,7]]},"4733":{"position":[[942,7],[972,7],[1020,7],[1075,8],[1167,7],[1207,7],[1215,7]]},"4738":{"position":[[415,7],[465,6],[559,8],[579,7],[664,6],[720,6]]},"4742":{"position":[[399,7],[478,7],[540,7],[645,7]]},"4744":{"position":[[475,8],[510,7],[628,6]]},"4761":{"position":[[63,7],[156,7],[218,7]]}}}],["mgmt",{"_index":2580,"t":{"522":{"position":[[510,4]]},"1704":{"position":[[610,4]]}}}],["mgmt.yaml.gotmpl",{"_index":11886,"t":{"4835":{"position":[[1208,16]]}}}],["mgr",{"_index":4821,"t":{"1183":{"position":[[996,5]]},"1391":{"position":[[2696,3]]},"1433":{"position":[[183,3],[422,3]]},"1503":{"position":[[979,3],[1009,4]]},"1644":{"position":[[93,3],[208,5]]},"1646":{"position":[[1276,3],[1456,3]]},"1648":{"position":[[657,3]]},"3153":{"position":[[243,3],[367,5]]}}}],["mgr.5184",{"_index":6903,"t":{"1698":{"position":[[208,10],[865,10]]}}}],["mgr.testb",{"_index":6902,"t":{"1698":{"position":[[189,11],[846,11]]}}}],["mgr:children",{"_index":6141,"t":{"1433":{"position":[[596,13]]},"1529":{"position":[[164,13]]}}}],["mgr@.servic",{"_index":6600,"t":{"1646":{"position":[[1491,18]]}}}],["mgr_group_nam",{"_index":4843,"t":{"1185":{"position":[[1473,15]]}}}],["mgr_placement_label",{"_index":5958,"t":{"1391":{"position":[[2649,20]]}}}],["mi210",{"_index":10740,"t":{"3744":{"position":[[2240,5]]}}}],["mi250",{"_index":10746,"t":{"3744":{"position":[[2282,5]]}}}],["mi250x",{"_index":10751,"t":{"3744":{"position":[[2327,6]]}}}],["mi300x",{"_index":10756,"t":{"3744":{"position":[[2600,6]]}}}],["mi325x",{"_index":10763,"t":{"3744":{"position":[[2650,6]]}}}],["mib",{"_index":6913,"t":{"1698":{"position":[[300,3],[957,3]]},"3826":{"position":[[298,4]]}}}],["micro)servic",{"_index":3119,"t":{"706":{"position":[[262,15]]},"712":{"position":[[273,15]]}}}],["microcod",{"_index":10321,"t":{"3661":{"position":[[550,9],[647,9],[1386,10],[1548,10]]},"3698":{"position":[[657,9],[754,9],[1464,9],[2040,10],[2202,10]]},"3785":{"position":[[657,9],[739,9],[1210,9],[1738,10],[1900,10]]}}}],["microphon",{"_index":1771,"t":{"255":{"position":[[333,10]]}}}],["microsoft",{"_index":1061,"t":{"171":{"position":[[414,9]]},"3971":{"position":[[648,10]]}}}],["microvers",{"_index":8373,"t":{"2343":{"position":[[373,12]]},"2410":{"position":[[373,12]]}}}],["mid",{"_index":8424,"t":{"2382":{"position":[[301,3]]},"4257":{"position":[[5979,3]]},"4270":{"position":[[669,3]]}}}],["middl",{"_index":3128,"t":{"706":{"position":[[1856,6]]},"2529":{"position":[[859,6]]},"4045":{"position":[[1763,6]]},"4222":{"position":[[784,6],[956,6]]},"4310":{"position":[[1665,6]]}}}],["middlewar",{"_index":8831,"t":{"2665":{"position":[[98,14]]}}}],["midnight&skip=0",{"_index":7674,"t":{"2132":{"position":[[1567,16]]}}}],["mig",{"_index":10669,"t":{"3744":{"position":[[360,3],[569,6],[1213,3],[1319,3],[1615,3],[2035,3],[2489,4]]}}}],["migrat",{"_index":786,"t":{"141":{"position":[[367,9]]},"703":{"position":[[169,7]]},"728":{"position":[[68,9],[185,9],[377,9],[601,7],[663,7],[1052,10]]},"730":{"position":[[61,9]]},"732":{"position":[[5,9],[49,7],[420,7],[997,9]]},"734":{"position":[[261,10]]},"739":{"position":[[19,7]]},"755":{"position":[[646,10],[744,9],[795,9],[914,9],[954,9]]},"861":{"position":[[785,9]]},"986":{"position":[[5,7],[133,7]]},"1387":{"position":[[32,7]]},"1391":{"position":[[173,9],[887,8],[2415,11],[3171,7],[3300,10]]},"1484":{"position":[[32,7],[603,7]]},"1486":{"position":[[132,8],[324,10]]},"1709":{"position":[[5,7]]},"1713":{"position":[[160,7]]},"1762":{"position":[[785,9]]},"1877":{"position":[[5,7],[133,7]]},"1979":{"position":[[32,7]]},"1981":{"position":[[13,10],[175,9],[337,10]]},"1984":{"position":[[241,10]]},"1986":{"position":[[248,9]]},"1988":{"position":[[180,10],[276,7],[305,9]]},"1992":{"position":[[54,9],[161,10]]},"2148":{"position":[[32,7]]},"2234":{"position":[[52,9],[100,9],[325,10],[338,9],[560,9],[649,10],[707,9]]},"2236":{"position":[[278,7]]},"2252":{"position":[[2343,8]]},"3088":{"position":[[424,9]]},"3130":{"position":[[186,9]]},"3189":{"position":[[754,9]]},"3193":{"position":[[175,8]]},"3223":{"position":[[758,8],[811,9]]},"3266":{"position":[[657,9]]},"3665":{"position":[[385,10]]},"3702":{"position":[[457,10]]},"3724":{"position":[[317,10]]},"3789":{"position":[[457,10]]},"3817":{"position":[[317,10]]},"3894":{"position":[[1003,10]]},"3928":{"position":[[1327,9]]},"3932":{"position":[[737,9],[913,9],[1069,9],[1190,9]]},"3936":{"position":[[604,9],[677,9],[699,9]]},"3941":{"position":[[1126,8],[1242,9]]},"3947":{"position":[[1470,9],[2006,9]]},"3968":{"position":[[990,9]]},"4146":{"position":[[56,9],[303,7],[415,9],[516,9],[2405,10],[2452,9],[2577,9],[2672,9]]},"4148":{"position":[[580,9],[656,9]]},"4150":{"position":[[0,9]]},"4236":{"position":[[399,10]]},"4302":{"position":[[746,9],[772,9],[2727,9]]},"4304":{"position":[[5,9],[261,9],[1268,10],[1366,9],[1624,9],[1980,10],[2142,10],[2535,10],[2762,10],[2831,9]]},"4313":{"position":[[118,9],[243,9]]},"4327":{"position":[[9,9],[199,9],[265,9],[712,9]]},"4335":{"position":[[213,9]]},"4420":{"position":[[1348,9]]},"4829":{"position":[[159,9]]},"4835":{"position":[[906,10],[1011,10]]},"4839":{"position":[[735,7]]}}}],["migrate_md",{"_index":5968,"t":{"1391":{"position":[[3039,11]]}}}],["migrate_mds_pool",{"_index":5969,"t":{"1391":{"position":[[3053,17]]}}}],["migrate_mgr",{"_index":5970,"t":{"1391":{"position":[[3073,12]]}}}],["migrate_mon",{"_index":5965,"t":{"1391":{"position":[[2989,12]]}}}],["migrate_osd",{"_index":5966,"t":{"1391":{"position":[[3004,12]]}}}],["migrate_osd_pool",{"_index":5967,"t":{"1391":{"position":[[3019,17]]}}}],["migrate_rgw",{"_index":5971,"t":{"1391":{"position":[[3088,12]]}}}],["migrate_rgw_pool",{"_index":5972,"t":{"1391":{"position":[[3103,17]]}}}],["migratekit",{"_index":8083,"t":{"2234":{"position":[[660,10]]}}}],["migration_interfac",{"_index":5105,"t":{"1226":{"position":[[5085,20]]},"1299":{"position":[[195,19]]}}}],["migration_modul",{"_index":5962,"t":{"1391":{"position":[[2892,18],[2931,18],[3222,17]]}}}],["milan",{"_index":10386,"t":{"3671":{"position":[[446,7]]},"3706":{"position":[[922,5]]},"3712":{"position":[[758,7],[2086,5]]},"3799":{"position":[[922,5]]},"3805":{"position":[[537,7]]}}}],["milk",{"_index":1688,"t":{"239":{"position":[[404,5]]},"245":{"position":[[308,5]]}}}],["mimic",{"_index":11575,"t":{"4512":{"position":[[83,5]]},"4514":{"position":[[295,5]]},"4516":{"position":[[251,5],[498,5],[1854,5]]},"4520":{"position":[[804,6]]},"4522":{"position":[[736,5],[1579,6]]},"4667":{"position":[[93,6]]}}}],["mimick",{"_index":8377,"t":{"2343":{"position":[[1188,8]]},"2360":{"position":[[1337,8]]},"2410":{"position":[[1188,8]]},"2427":{"position":[[1337,8]]},"4518":{"position":[[204,9]]}}}],["min",{"_index":483,"t":{"64":{"position":[[52,5]]},"1305":{"position":[[173,3],[253,3]]},"1669":{"position":[[237,4]]},"1675":{"position":[[191,4]]},"4479":{"position":[[968,3]]},"4489":{"position":[[337,3]]}}}],["min_disk",{"_index":3384,"t":{"865":{"position":[[819,9]]},"871":{"position":[[619,9]]},"873":{"position":[[613,9]]},"875":{"position":[[222,8]]},"887":{"position":[[9131,9]]},"1766":{"position":[[819,9]]},"1772":{"position":[[619,9]]},"1774":{"position":[[613,9]]},"1776":{"position":[[222,8]]},"1811":{"position":[[9131,9]]},"3665":{"position":[[802,9],[1462,9]]},"3702":{"position":[[1015,9],[1809,9]]},"3789":{"position":[[874,9],[1668,9]]},"3826":{"position":[[267,8]]}}}],["min_ram",{"_index":3385,"t":{"865":{"position":[[831,8]]},"871":{"position":[[631,8]]},"873":{"position":[[625,8]]},"875":{"position":[[235,7]]},"887":{"position":[[9143,8]]},"1766":{"position":[[831,8]]},"1772":{"position":[[631,8]]},"1774":{"position":[[625,8]]},"1776":{"position":[[235,7]]},"1811":{"position":[[9143,8]]},"3826":{"position":[[286,7]]}}}],["min_siz",{"_index":4625,"t":{"1171":{"position":[[380,9]]},"1411":{"position":[[668,9],[975,9],[1281,9],[1588,9],[1891,9],[2211,9],[2608,9]]}}}],["min_step",{"_index":8890,"t":{"2686":{"position":[[517,9]]}}}],["mind",{"_index":3217,"t":{"738":{"position":[[127,4]]},"739":{"position":[[902,4]]},"2196":{"position":[[562,5]]},"2826":{"position":[[189,5]]},"3022":{"position":[[708,4]]},"4660":{"position":[[3539,4]]}}}],["mindset",{"_index":10997,"t":{"3971":{"position":[[273,9]]}}}],["mineri",{"_index":256,"t":{"28":{"position":[[1382,6]]}}}],["minikub",{"_index":9253,"t":{"2898":{"position":[[212,8]]}}}],["minim",{"_index":347,"t":{"37":{"position":[[512,7]]},"105":{"position":[[5,7]]},"362":{"position":[[98,7]]},"543":{"position":[[131,7]]},"887":{"position":[[6956,7],[7111,7],[7364,7],[7669,7]]},"1025":{"position":[[77,7]]},"1064":{"position":[[1883,9]]},"1103":{"position":[[229,7]]},"1466":{"position":[[2040,8]]},"1661":{"position":[[190,8]]},"1811":{"position":[[6956,7],[7111,7],[7364,7],[7669,7]]},"2820":{"position":[[2,7]]},"3088":{"position":[[143,9]]},"3571":{"position":[[1025,7]]},"3968":{"position":[[1426,7]]},"4079":{"position":[[399,8]]},"4153":{"position":[[392,7]]},"4163":{"position":[[2434,7],[3937,7]]},"4224":{"position":[[579,8],[2331,8]]},"4506":{"position":[[155,8]]},"4522":{"position":[[287,9]]},"4537":{"position":[[319,8]]},"4539":{"position":[[5003,7]]},"4543":{"position":[[845,9],[937,10]]},"4572":{"position":[[354,7]]},"4591":{"position":[[663,9]]},"4660":{"position":[[1982,8]]},"4688":{"position":[[22,7]]}}}],["minimalist",{"_index":7299,"t":{"2025":{"position":[[30,12]]}}}],["minimum",{"_index":3419,"t":{"867":{"position":[[79,7]]},"1050":{"position":[[254,7]]},"1244":{"position":[[799,8]]},"1736":{"position":[[288,7],[786,7]]},"1768":{"position":[[79,7]]},"2021":{"position":[[408,7]]},"2027":{"position":[[59,7],[178,7],[298,7]]},"2684":{"position":[[265,7],[573,7]]},"3544":{"position":[[112,7]]},"4109":{"position":[[238,7]]},"4255":{"position":[[33,7],[155,7]]},"4257":{"position":[[2977,7],[3038,7],[3370,7]]},"4435":{"position":[[632,7]]},"4539":{"position":[[6517,7]]},"4543":{"position":[[365,8]]},"4695":{"position":[[602,7]]}}}],["minimum/optim",{"_index":4729,"t":{"1177":{"position":[[3545,18]]}}}],["minio",{"_index":3468,"t":{"887":{"position":[[292,5],[314,5],[381,5],[403,5],[470,5],[488,5],[575,5],[593,5]]},"1811":{"position":[[292,5],[314,5],[381,5],[403,5],[470,5],[488,5],[575,5],[593,5]]}}}],["minio.services.osism.tech",{"_index":9849,"t":{"3197":{"position":[[82,25]]}}}],["minio.yaml.gotmpl",{"_index":11907,"t":{"4835":{"position":[[2423,17]]}}}],["minio_access_key",{"_index":3470,"t":{"887":{"position":[[341,17]]},"1811":{"position":[[341,17]]}}}],["minio_bucket",{"_index":3474,"t":{"887":{"position":[[616,13]]},"1811":{"position":[[616,13]]}}}],["minio_secret_key",{"_index":3471,"t":{"887":{"position":[[430,17]]},"1811":{"position":[[430,17]]}}}],["minio_serv",{"_index":3472,"t":{"887":{"position":[[511,13]]},"1811":{"position":[[511,13]]}}}],["ministri",{"_index":3264,"t":{"776":{"position":[[122,8]]},"3214":{"position":[[233,8]]}}}],["minor",{"_index":2264,"t":{"376":{"position":[[307,5]]},"463":{"position":[[498,5]]},"477":{"position":[[181,5],[245,5]]},"479":{"position":[[287,5],[554,5]]},"549":{"position":[[225,5],[731,5]]},"755":{"position":[[394,5]]},"2055":{"position":[[48,5],[111,5],[265,5],[312,5],[359,5]]},"2076":{"position":[[266,5]]},"3136":{"position":[[896,5]]},"3153":{"position":[[1077,5]]},"3204":{"position":[[9,5]]},"3279":{"position":[[336,5],[634,5]]},"3835":{"position":[[1228,7]]},"4109":{"position":[[2712,7],[3443,5],[4260,5],[4372,7]]},"4133":{"position":[[1401,7],[1465,5],[1577,7]]},"4222":{"position":[[1666,5]]},"4340":{"position":[[259,5],[402,5],[457,5],[564,5]]},"4344":{"position":[[20,5]]},"4351":{"position":[[131,5],[232,5],[796,5]]},"4355":{"position":[[200,5]]},"4533":{"position":[[487,5]]}}}],["minut",{"_index":2156,"t":{"364":{"position":[[1663,7]]},"434":{"position":[[2070,7]]},"481":{"position":[[303,8]]},"512":{"position":[[1108,8]]},"938":{"position":[[1398,8]]},"940":{"position":[[322,6]]},"1711":{"position":[[1256,7],[1273,7],[1384,7],[1401,7],[1509,7],[1526,7]]},"1829":{"position":[[1398,8]]},"1831":{"position":[[322,6]]},"2032":{"position":[[870,8]]},"2155":{"position":[[1205,6],[1227,6],[1338,6],[1360,6],[1450,6],[1472,6],[1612,6],[1634,6],[1736,6],[1758,6],[1863,6],[1885,6],[1984,6],[2006,6],[2148,6],[2170,6],[2273,6],[2295,6],[2408,6],[2430,6],[2544,6],[2566,6],[2671,6],[2693,6],[2806,6],[2828,6],[2940,6],[2962,6],[3073,6],[3095,6],[3188,6],[3210,6]]},"2184":{"position":[[4151,7]]},"2231":{"position":[[196,7]]},"2626":{"position":[[1301,7]]},"2647":{"position":[[1276,6]]},"2684":{"position":[[417,8]]},"2847":{"position":[[51,8]]},"2896":{"position":[[138,8]]},"2962":{"position":[[1398,8]]},"2964":{"position":[[322,6]]},"4109":{"position":[[741,8]]},"4185":{"position":[[606,9]]},"4244":{"position":[[150,7]]},"4246":{"position":[[139,7]]},"4493":{"position":[[163,7],[188,8]]}}}],["mirror",{"_index":2665,"t":{"551":{"position":[[799,6]]},"863":{"position":[[7,6],[91,6]]},"878":{"position":[[70,6]]},"880":{"position":[[124,8]]},"883":{"position":[[140,6],[182,7]]},"887":{"position":[[1257,9],[9015,6]]},"1764":{"position":[[7,6],[91,6]]},"1779":{"position":[[70,6]]},"1781":{"position":[[124,8]]},"1807":{"position":[[140,6],[182,7]]},"1811":{"position":[[1257,9],[9015,6]]},"2211":{"position":[[989,7],[1833,6],[2069,6],[2347,6]]},"2584":{"position":[[1260,8]]},"2586":{"position":[[870,8]]},"2600":{"position":[[82,6]]},"3153":{"position":[[618,8]]},"3835":{"position":[[1407,8]]},"4102":{"position":[[1024,7]]},"4667":{"position":[[12626,6]]}}}],["mirror_url",{"_index":3550,"t":{"887":{"position":[[8964,10],[9981,11]]},"1811":{"position":[[8964,10],[9981,11]]}}}],["misconfigur",{"_index":8523,"t":{"2485":{"position":[[426,18]]},"2487":{"position":[[197,18],[1300,18]]},"2499":{"position":[[325,18],[411,18]]},"2501":{"position":[[150,18],[709,13]]},"2508":{"position":[[256,17]]},"2512":{"position":[[109,18],[535,18],[566,17]]},"2516":{"position":[[140,18]]},"2529":{"position":[[0,13],[144,17]]},"2535":{"position":[[573,18]]},"2537":{"position":[[273,17]]},"2539":{"position":[[430,18]]},"3984":{"position":[[328,16],[754,16]]},"4251":{"position":[[303,18]]},"4444":{"position":[[131,18]]},"4455":{"position":[[131,18]]}}}],["mislead",{"_index":11520,"t":{"4433":{"position":[[1202,10]]}}}],["mismatch",{"_index":10777,"t":{"3747":{"position":[[114,8],[387,8]]}}}],["miss",{"_index":2112,"t":{"354":{"position":[[216,7]]},"1383":{"position":[[146,7]]},"1407":{"position":[[72,7]]},"1661":{"position":[[446,7]]},"1743":{"position":[[205,7]]},"2144":{"position":[[1403,7]]},"2184":{"position":[[3092,7]]},"2240":{"position":[[1256,7]]},"3661":{"position":[[1798,7]]},"3698":{"position":[[2452,7]]},"3722":{"position":[[1215,7]]},"3785":{"position":[[2150,7]]},"3815":{"position":[[1213,7]]},"3857":{"position":[[75,7],[128,7]]},"3883":{"position":[[219,7]]},"3906":{"position":[[256,7]]},"4148":{"position":[[314,7]]},"4533":{"position":[[113,7]]},"4560":{"position":[[684,7]]},"4736":{"position":[[23,7]]},"4755":{"position":[[23,7]]}}}],["mission",{"_index":537,"t":{"72":{"position":[[418,7]]},"169":{"position":[[36,7]]},"1073":{"position":[[129,7]]}}}],["mistak",{"_index":1382,"t":{"194":{"position":[[311,8],[359,7]]},"199":{"position":[[3174,9]]},"301":{"position":[[364,8]]},"595":{"position":[[881,9]]},"738":{"position":[[1007,7]]},"4109":{"position":[[4550,8],[4644,8]]}}}],["mistral_api_public_port",{"_index":5376,"t":{"1295":{"position":[[1591,24]]}}}],["mistral_external_fqdn",{"_index":5375,"t":{"1295":{"position":[[1540,21]]}}}],["mistral_public_endpoint",{"_index":5374,"t":{"1295":{"position":[[1516,23]]}}}],["mistrust",{"_index":11247,"t":{"4182":{"position":[[35,8]]}}}],["mit",{"_index":1157,"t":{"173":{"position":[[2041,3]]}}}],["mitig",{"_index":3227,"t":{"741":{"position":[[720,11]]},"2487":{"position":[[482,8]]},"2497":{"position":[[305,10]]},"2512":{"position":[[1574,10]]},"2531":{"position":[[1586,8]]},"2647":{"position":[[1211,8]]},"3661":{"position":[[804,11],[1413,11]]},"3698":{"position":[[896,11],[1317,11],[1706,12],[2067,11]]},"3785":{"position":[[917,11],[1239,10],[1313,11],[1765,11]]},"3928":{"position":[[1429,8]]},"4135":{"position":[[744,8]]},"4230":{"position":[[586,8],[5060,8]]},"4308":{"position":[[441,9]]},"4471":{"position":[[315,8]]},"4479":{"position":[[1187,8]]},"4481":{"position":[[488,8]]},"4525":{"position":[[402,9]]},"4529":{"position":[[338,8]]},"4722":{"position":[[1026,8]]}}}],["mitm",{"_index":11288,"t":{"4222":{"position":[[963,6]]},"4224":{"position":[[1932,4]]}}}],["mix",{"_index":5881,"t":{"1377":{"position":[[13,3]]},"1379":{"position":[[42,5]]},"1381":{"position":[[114,5]]},"3943":{"position":[[300,3]]},"3996":{"position":[[505,4]]},"4310":{"position":[[1608,3]]},"4728":{"position":[[1408,3]]}}}],["mixed_flavor_nam",{"_index":5885,"t":{"1379":{"position":[[177,18],[362,18]]}}}],["mixin",{"_index":8798,"t":{"2649":{"position":[[1185,6],[2405,6],[2445,6],[2677,5]]},"4728":{"position":[[1426,5]]},"4733":{"position":[[1470,5]]}}}],["mixin/prometheus_alerts.yml",{"_index":8801,"t":{"2649":{"position":[[1688,27]]}}}],["mixtur",{"_index":10213,"t":{"3556":{"position":[[104,7]]}}}],["mkdir",{"_index":2490,"t":{"489":{"position":[[360,5]]},"514":{"position":[[853,5]]},"701":{"position":[[2061,5]]},"942":{"position":[[3593,5]]},"963":{"position":[[139,5]]},"1222":{"position":[[116,5]]},"1443":{"position":[[931,5]]},"1650":{"position":[[119,5]]},"1833":{"position":[[3593,5]]},"1854":{"position":[[139,5]]},"1975":{"position":[[119,5]]},"2121":{"position":[[490,5]]},"2184":{"position":[[261,5]]},"2966":{"position":[[3593,5]]},"2987":{"position":[[139,5]]},"4845":{"position":[[56,5]]},"4861":{"position":[[431,5]]}}}],["mkk9fdv9wujiqtuyhaofmd+uys/hqvsf/hm9scuvfhw02gtdzkcxliwhfhjoj7rbduumk",{"_index":2218,"t":{"368":{"position":[[4704,69]]}}}],["ml",{"_index":6458,"t":{"1564":{"position":[[318,2]]}}}],["ml2",{"_index":10984,"t":{"3960":{"position":[[307,3],[483,3]]},"4215":{"position":[[339,3]]}}}],["mm",{"_index":9307,"t":{"2930":{"position":[[551,2]]},"3829":{"position":[[3004,2],[3763,2],[3817,2]]},"3833":{"position":[[45,2],[59,2]]},"3835":{"position":[[1665,2]]}}}],["mmmm",{"_index":9311,"t":{"2930":{"position":[[645,4]]}}}],["mms.github.io/trivi",{"_index":8625,"t":{"2569":{"position":[[643,19]]}}}],["mnt/test",{"_index":8147,"t":{"2248":{"position":[[639,10]]}}}],["mobil",{"_index":1765,"t":{"255":{"position":[[220,6]]}}}],["mock",{"_index":8501,"t":{"2480":{"position":[[310,4]]},"2624":{"position":[[1006,4]]},"2626":{"position":[[139,4],[551,4],[859,4],[944,4]]},"4279":{"position":[[1116,4]]},"4730":{"position":[[2024,6],[2051,4],[2264,6]]}}}],["mod_auth_mellon",{"_index":2043,"t":{"319":{"position":[[269,15]]}}}],["mod_auth_openidc",{"_index":2041,"t":{"319":{"position":[[236,17]]}}}],["mod_oauth2",{"_index":2042,"t":{"319":{"position":[[254,10]]},"3086":{"position":[[1072,10]]}}}],["mode",{"_index":857,"t":{"151":{"position":[[165,5],[563,5]]},"271":{"position":[[274,4]]},"362":{"position":[[174,5],[529,4]]},"405":{"position":[[473,4]]},"485":{"position":[[311,4]]},"514":{"position":[[38,6],[119,4],[251,4],[304,5],[693,4]]},"522":{"position":[[188,5]]},"624":{"position":[[94,4]]},"630":{"position":[[19,5]]},"632":{"position":[[11,4]]},"634":{"position":[[9,4],[295,4]]},"636":{"position":[[9,4],[39,5]]},"638":{"position":[[11,4]]},"643":{"position":[[23,5]]},"645":{"position":[[5,4]]},"647":{"position":[[5,4]]},"649":{"position":[[18,5]]},"651":{"position":[[11,4]]},"655":{"position":[[494,4],[519,4],[641,4]]},"673":{"position":[[494,4],[519,4],[641,4]]},"675":{"position":[[23,5]]},"677":{"position":[[5,4]]},"679":{"position":[[5,4]]},"681":{"position":[[18,5]]},"683":{"position":[[11,4]]},"708":{"position":[[27,4],[1337,4]]},"739":{"position":[[300,4],[888,5],[925,4],[1258,4],[1877,5],[1982,4],[2035,4]]},"1173":{"position":[[234,5]]},"1266":{"position":[[2689,4]]},"1297":{"position":[[1682,4]]},"1303":{"position":[[636,5],[3567,7]]},"1552":{"position":[[639,4]]},"1671":{"position":[[165,4]]},"1984":{"position":[[43,4],[87,4]]},"1986":{"position":[[18,4],[97,4],[232,4]]},"1988":{"position":[[153,4]]},"2048":{"position":[[1572,6]]},"2086":{"position":[[166,5],[564,5]]},"2123":{"position":[[226,5],[378,5]]},"2180":{"position":[[159,6]]},"2341":{"position":[[709,4]]},"2347":{"position":[[271,4],[394,4]]},"2408":{"position":[[709,4]]},"2414":{"position":[[271,4],[394,4]]},"2608":{"position":[[1160,4]]},"2930":{"position":[[1646,4],[1745,4]]},"3474":{"position":[[281,4]]},"4376":{"position":[[575,5]]},"4401":{"position":[[41,4]]},"4420":{"position":[[1503,4]]},"4481":{"position":[[479,5],[1056,4]]},"4491":{"position":[[256,4]]},"4508":{"position":[[582,5]]},"4539":{"position":[[4786,5],[4844,4],[5988,5],[6399,5]]},"4543":{"position":[[1390,5]]},"4562":{"position":[[1317,5],[6421,4]]}}}],["model",{"_index":1270,"t":{"181":{"position":[[680,6]]},"370":{"position":[[661,6]]},"706":{"position":[[996,7]]},"717":{"position":[[44,7]]},"1056":{"position":[[50,5]]},"1103":{"position":[[17,6]]},"1107":{"position":[[387,5]]},"1175":{"position":[[412,6]]},"1177":{"position":[[3423,6]]},"1301":{"position":[[2538,6]]},"2003":{"position":[[237,5]]},"2576":{"position":[[46,9]]},"2914":{"position":[[164,7]]},"3298":{"position":[[348,5]]},"3348":{"position":[[253,6]]},"3563":{"position":[[348,5]]},"3706":{"position":[[206,7]]},"3799":{"position":[[206,7]]},"4224":{"position":[[1655,8],[1819,9]]},"4226":{"position":[[34,8]]},"4236":{"position":[[37,9]]},"4446":{"position":[[1135,5]]},"4457":{"position":[[1135,5]]},"4525":{"position":[[534,6]]},"4572":{"position":[[32,5]]},"4589":{"position":[[128,6]]},"4593":{"position":[[4325,6]]}}}],["moder",{"_index":1749,"t":{"253":{"position":[[277,9]]},"951":{"position":[[517,10]]},"1301":{"position":[[1871,9]]},"1842":{"position":[[517,10]]},"2975":{"position":[[517,10]]}}}],["modern",{"_index":1180,"t":{"175":{"position":[[338,6]]},"280":{"position":[[841,6]]},"924":{"position":[[272,6],[1952,7]]},"1050":{"position":[[70,6]]},"1815":{"position":[[272,6],[1952,7]]},"2485":{"position":[[0,6]]},"2948":{"position":[[272,6],[1952,7]]},"3298":{"position":[[169,6]]},"4142":{"position":[[48,7]]},"4679":{"position":[[254,6]]}}}],["modif",{"_index":1057,"t":{"171":{"position":[[147,14],[343,13]]},"249":{"position":[[614,14]]},"890":{"position":[[51,13]]},"1748":{"position":[[51,13]]},"4238":{"position":[[418,13]]},"4547":{"position":[[3494,12],[3574,13]]}}}],["modifi",{"_index":932,"t":{"159":{"position":[[329,8]]},"192":{"position":[[53,8]]},"249":{"position":[[912,8]]},"530":{"position":[[141,9]]},"568":{"position":[[7,6]]},"578":{"position":[[112,6]]},"910":{"position":[[355,6]]},"912":{"position":[[35,6]]},"1244":{"position":[[492,9]]},"1301":{"position":[[3383,6]]},"1433":{"position":[[1213,9]]},"1794":{"position":[[355,6]]},"1796":{"position":[[35,6]]},"2090":{"position":[[319,8]]},"2104":{"position":[[114,9]]},"2216":{"position":[[225,6]]},"2380":{"position":[[735,6]]},"2482":{"position":[[274,9]]},"2604":{"position":[[432,6]]},"2628":{"position":[[222,6],[587,8],[700,8],[789,8],[882,8]]},"2740":{"position":[[497,9],[551,6],[645,6]]},"2743":{"position":[[173,6]]},"2749":{"position":[[152,7]]},"2810":{"position":[[186,8]]},"2934":{"position":[[342,6]]},"3381":{"position":[[218,6]]},"3533":{"position":[[2489,6]]},"3571":{"position":[[1605,6]]},"3679":{"position":[[1732,9]]},"3706":{"position":[[1942,9]]},"3799":{"position":[[1824,9]]},"3894":{"position":[[462,8],[848,9]]},"4222":{"position":[[3335,10]]},"4253":{"position":[[345,8]]},"4539":{"position":[[1276,6],[3455,8],[6753,6],[7064,6]]},"4545":{"position":[[600,8]]},"4580":{"position":[[1443,6]]},"4669":{"position":[[29,8]]},"4738":{"position":[[357,9]]},"4742":{"position":[[217,6]]}}}],["modify_at",{"_index":9641,"t":{"3036":{"position":[[12459,10],[12672,10]]}}}],["modprob",{"_index":5848,"t":{"1359":{"position":[[95,8],[120,8]]},"1361":{"position":[[97,8],[124,8]]}}}],["modul",{"_index":678,"t":{"103":{"position":[[172,6]]},"167":{"position":[[128,7]]},"169":{"position":[[563,7]]},"303":{"position":[[4,6],[63,6],[290,6],[382,6],[413,6],[564,6]]},"305":{"position":[[213,7]]},"307":{"position":[[50,6]]},"319":{"position":[[223,7],[393,7],[825,8]]},"836":{"position":[[25,6]]},"846":{"position":[[25,6],[566,6]]},"1009":{"position":[[48,7],[222,7],[293,7],[370,7]]},"1111":{"position":[[317,8]]},"1147":{"position":[[365,7],[377,6]]},"1203":{"position":[[155,7]]},"1391":{"position":[[3264,7],[3333,7],[3415,8],[3434,7],[3494,6],[3539,8]]},"1435":{"position":[[15,6]]},"1740":{"position":[[237,7]]},"1984":{"position":[[152,7],[180,8]]},"2110":{"position":[[82,6]]},"2649":{"position":[[867,7]]},"3355":{"position":[[83,8]]},"3571":{"position":[[809,6]]},"3592":{"position":[[1254,7],[1469,6],[1515,6],[2171,7],[2260,7],[2305,7],[2331,6]]},"3594":{"position":[[559,7],[589,6]]},"3598":{"position":[[133,6],[451,7],[701,6],[807,6],[976,6]]},"3600":{"position":[[64,6],[108,6],[331,6],[661,7],[1028,7]]},"3604":{"position":[[103,7]]},"3761":{"position":[[640,6]]},"3964":{"position":[[197,6]]},"3968":{"position":[[246,8],[1577,7],[1692,7],[1714,6],[1842,7]]},"3973":{"position":[[64,7]]},"4075":{"position":[[321,6]]},"4226":{"position":[[1909,7],[2309,8]]},"4234":{"position":[[146,6]]},"4275":{"position":[[281,7]]},"4539":{"position":[[707,7],[1096,7],[1151,7],[1257,8]]},"4545":{"position":[[227,6]]},"4593":{"position":[[591,6]]},"4773":{"position":[[113,7]]},"4775":{"position":[[62,7]]},"4839":{"position":[[1681,7]]}}}],["modular",{"_index":4417,"t":{"1056":{"position":[[1518,7]]},"1391":{"position":[[3136,7]]},"3355":{"position":[[290,7]]},"3621":{"position":[[106,7]]},"4728":{"position":[[1118,7]]},"4839":{"position":[[306,7]]}}}],["module_arg",{"_index":6426,"t":{"1561":{"position":[[360,12],[683,12]]}}}],["module_nam",{"_index":6424,"t":{"1561":{"position":[[338,12],[659,12]]}}}],["moment",{"_index":594,"t":{"80":{"position":[[82,7]]},"887":{"position":[[1249,7],[1292,7]]},"1191":{"position":[[785,6]]},"1236":{"position":[[701,6],[1166,6]]},"1252":{"position":[[3477,6]]},"1266":{"position":[[1609,6]]},"1515":{"position":[[87,7]]},"1659":{"position":[[183,6]]},"1811":{"position":[[1249,7],[1292,7]]},"2025":{"position":[[526,6]]},"2045":{"position":[[142,7]]},"2270":{"position":[[165,7]]},"4017":{"position":[[285,7]]},"4257":{"position":[[5791,6]]},"4270":{"position":[[296,6]]},"4464":{"position":[[159,6]]},"4541":{"position":[[676,7]]}}}],["momentj",{"_index":1795,"t":{"258":{"position":[[595,8]]}}}],["mon",{"_index":3943,"t":{"946":{"position":[[764,3]]},"961":{"position":[[1648,3]]},"1038":{"position":[[164,5]]},"1173":{"position":[[156,4]]},"1185":{"position":[[2053,3]]},"1191":{"position":[[662,3]]},"1391":{"position":[[2747,3]]},"1433":{"position":[[164,3],[431,3]]},"1503":{"position":[[932,3],[962,4]]},"1644":{"position":[[85,3],[178,5]]},"1646":{"position":[[1905,3],[2085,3]]},"1648":{"position":[[305,3]]},"1837":{"position":[[764,3]]},"1852":{"position":[[1648,3]]},"2970":{"position":[[764,3]]},"2985":{"position":[[1648,3]]},"3153":{"position":[[235,3],[337,5]]},"3230":{"position":[[877,3]]},"4733":{"position":[[1736,3]]}}}],["mon.testb",{"_index":6935,"t":{"1698":{"position":[[1086,11]]}}}],["mon.yaml",{"_index":8916,"t":{"2692":{"position":[[1443,8]]}}}],["mon:children",{"_index":6142,"t":{"1433":{"position":[[629,13]]},"1529":{"position":[[197,13]]}}}],["mon@.servic",{"_index":6604,"t":{"1646":{"position":[[2120,18]]}}}],["mon_allow_pool_delet",{"_index":6577,"t":{"1635":{"position":[[246,21]]}}}],["mon_group_nam",{"_index":4844,"t":{"1185":{"position":[[1498,15]]}}}],["mon_placement_label",{"_index":5959,"t":{"1391":{"position":[[2700,20]]}}}],["mon_warn_on_pool_no_redund",{"_index":6164,"t":{"1439":{"position":[[332,31]]}}}],["monclient",{"_index":7730,"t":{"2144":{"position":[[1267,10]]}}}],["money",{"_index":1302,"t":{"181":{"position":[[2476,6]]},"776":{"position":[[178,5]]},"3971":{"position":[[694,5]]},"4189":{"position":[[200,6]]}}}],["monitor",{"_index":118,"t":{"15":{"position":[[0,11]]},"26":{"position":[[284,10],[342,10],[630,7]]},"28":{"position":[[410,7],[784,10],[3299,7],[3331,7]]},"33":{"position":[[130,7],[184,7],[211,7],[286,7]]},"68":{"position":[[90,10]]},"76":{"position":[[33,10],[123,10],[203,10]]},"334":{"position":[[40,10],[62,7]]},"337":{"position":[[355,10]]},"356":{"position":[[411,7]]},"541":{"position":[[1469,10]]},"846":{"position":[[340,8]]},"924":{"position":[[36,7],[1045,7],[1628,7],[1808,7],[1859,10],[1992,10],[2053,10],[2125,7]]},"928":{"position":[[646,7],[812,8]]},"930":{"position":[[722,7]]},"934":{"position":[[1895,7],[2367,7]]},"938":{"position":[[26,8],[161,7],[189,7],[394,7],[799,7]]},"940":{"position":[[176,10],[848,10]]},"942":{"position":[[2270,7],[3859,10],[3928,9]]},"946":{"position":[[670,7]]},"949":{"position":[[137,11]]},"959":{"position":[[21,7]]},"967":{"position":[[137,8]]},"971":{"position":[[53,7]]},"978":{"position":[[1604,11]]},"980":{"position":[[1122,7]]},"999":{"position":[[129,7]]},"1013":{"position":[[428,10]]},"1016":{"position":[[56,10]]},"1054":{"position":[[428,10]]},"1113":{"position":[[184,10]]},"1226":{"position":[[3210,10],[3276,10],[3319,12],[3926,7]]},"1468":{"position":[[569,10]]},"1486":{"position":[[216,7]]},"1511":{"position":[[291,10]]},"1521":{"position":[[39,10]]},"1635":{"position":[[222,8]]},"1711":{"position":[[718,10],[755,10]]},"1713":{"position":[[2629,10],[2666,10]]},"1815":{"position":[[36,7],[1045,7],[1628,7],[1808,7],[1859,10],[1992,10],[2053,10],[2125,7]]},"1819":{"position":[[646,7],[812,8]]},"1821":{"position":[[722,7]]},"1825":{"position":[[1895,7],[2367,7]]},"1829":{"position":[[26,8],[161,7],[189,7],[394,7],[799,7]]},"1831":{"position":[[176,10],[848,10]]},"1833":{"position":[[2270,7],[3859,10],[3928,9]]},"1837":{"position":[[670,7]]},"1840":{"position":[[137,11]]},"1850":{"position":[[21,7]]},"1858":{"position":[[137,8]]},"1862":{"position":[[53,7]]},"1869":{"position":[[1604,11]]},"1871":{"position":[[1122,7]]},"1890":{"position":[[129,7]]},"2184":{"position":[[5050,10],[5275,10],[5338,10],[5426,10]]},"2203":{"position":[[503,10]]},"2205":{"position":[[395,10]]},"2489":{"position":[[664,11]]},"2501":{"position":[[349,11],[795,7]]},"2503":{"position":[[177,10]]},"2506":{"position":[[183,11],[262,11]]},"2510":{"position":[[400,7]]},"2512":{"position":[[906,10],[962,10]]},"2514":{"position":[[249,10]]},"2516":{"position":[[17,11]]},"2518":{"position":[[415,11],[449,7]]},"2525":{"position":[[881,10]]},"2606":{"position":[[268,10]]},"2608":{"position":[[491,7],[686,10],[1336,10]]},"2614":{"position":[[243,10],[416,7],[750,10],[953,10],[1002,10]]},"2616":{"position":[[118,10],[287,11],[401,10]]},"2618":{"position":[[42,10],[244,10],[412,10],[478,10],[624,10],[707,10],[792,10],[926,10],[1002,11],[1186,10],[1383,10],[1412,10]]},"2622":{"position":[[61,11],[166,10],[199,10]]},"2624":{"position":[[12,10],[268,11],[320,10],[452,10]]},"2626":{"position":[[16,10],[95,10],[171,10],[1240,10],[1277,11],[2329,10]]},"2630":{"position":[[91,10]]},"2636":{"position":[[169,10],[818,10],[1044,10],[1093,10]]},"2638":{"position":[[147,10]]},"2640":{"position":[[12,10],[104,10]]},"2642":{"position":[[22,10],[157,10]]},"2644":{"position":[[162,10],[268,10],[632,10],[791,10]]},"2647":{"position":[[1694,10],[1755,10],[1837,10],[1958,10],[2007,10],[2293,10],[2342,10]]},"2649":{"position":[[208,10],[2808,10],[2899,10],[3008,10],[3140,10],[3189,10],[3604,10],[3653,10]]},"2651":{"position":[[56,10],[218,10],[476,11],[623,7]]},"2655":{"position":[[13,10]]},"2657":{"position":[[140,10],[189,10]]},"2659":{"position":[[114,10],[283,11],[397,10]]},"2668":{"position":[[12,10],[109,10]]},"2670":{"position":[[22,10],[157,10]]},"2672":{"position":[[162,10],[268,10],[632,10],[791,10]]},"2674":{"position":[[59,10],[182,10],[231,10],[522,10],[571,10]]},"2678":{"position":[[58,10]]},"2680":{"position":[[204,10]]},"2688":{"position":[[26,7]]},"2690":{"position":[[15,7]]},"2692":{"position":[[35,7],[84,7],[208,7],[554,7],[1270,7]]},"2695":{"position":[[13,7]]},"2697":{"position":[[40,7],[125,7],[255,7],[328,7],[463,7]]},"2699":{"position":[[15,7]]},"2703":{"position":[[333,9],[441,8]]},"2705":{"position":[[66,7],[432,7],[451,7],[545,7],[564,7],[654,7],[673,7]]},"2712":{"position":[[143,7],[462,7],[534,7],[867,7],[1411,7]]},"2714":{"position":[[717,7],[796,7],[1189,7]]},"2725":{"position":[[82,7],[104,7]]},"2734":{"position":[[91,7]]},"2736":{"position":[[50,7]]},"2867":{"position":[[130,10]]},"2948":{"position":[[36,7],[1045,7],[1628,7],[1808,7],[1859,10],[1992,10],[2053,10],[2125,7]]},"2952":{"position":[[646,7],[812,8]]},"2954":{"position":[[722,7]]},"2958":{"position":[[1895,7],[2367,7]]},"2962":{"position":[[26,8],[161,7],[189,7],[394,7],[799,7]]},"2964":{"position":[[176,10],[848,10]]},"2966":{"position":[[2270,7],[3859,10],[3928,9]]},"2970":{"position":[[670,7]]},"2973":{"position":[[137,11]]},"2983":{"position":[[21,7]]},"2991":{"position":[[137,8]]},"2995":{"position":[[53,7]]},"3002":{"position":[[1604,11]]},"3022":{"position":[[1136,7],[1161,7]]},"3050":{"position":[[649,10],[802,10]]},"3052":{"position":[[49,7],[182,10],[452,7],[549,7]]},"3086":{"position":[[608,7],[676,7]]},"3095":{"position":[[151,10]]},"3101":{"position":[[104,7]]},"3119":{"position":[[47,7],[228,7]]},"3153":{"position":[[917,7]]},"3185":{"position":[[984,9]]},"3225":{"position":[[95,10],[158,10],[292,10],[355,10]]},"3230":{"position":[[386,8],[401,10],[456,8],[750,7]]},"3255":{"position":[[179,10]]},"3264":{"position":[[216,8],[334,8],[400,7]]},"3276":{"position":[[379,8]]},"3292":{"position":[[55,7],[194,8],[947,7],[1017,7]]},"3346":{"position":[[239,7]]},"3357":{"position":[[250,7],[1232,7],[1256,7],[1386,7],[1410,7],[1482,7],[1501,7],[1513,10],[1536,7]]},"3375":{"position":[[123,8],[560,7]]},"3378":{"position":[[194,7],[220,9],[795,7]]},"3384":{"position":[[1524,8]]},"3502":{"position":[[110,11]]},"3569":{"position":[[1126,10]]},"3938":{"position":[[309,10]]},"4146":{"position":[[874,8]]},"4222":{"position":[[1271,10],[2481,9]]},"4226":{"position":[[1062,10]]},"4228":{"position":[[879,8]]},"4230":{"position":[[1970,8]]},"4257":{"position":[[4821,9],[4935,9]]},"4362":{"position":[[473,7]]},"4420":{"position":[[1368,10]]},"4504":{"position":[[806,10]]},"4506":{"position":[[1336,10],[1394,10],[1582,10]]},"4508":{"position":[[776,10],[850,10]]},"4512":{"position":[[429,10]]},"4514":{"position":[[180,10]]},"4541":{"position":[[448,10]]},"4547":{"position":[[1609,11]]},"4562":{"position":[[1383,13],[6300,10]]},"4660":{"position":[[2168,11],[3192,10]]},"4662":{"position":[[1134,7]]},"4724":{"position":[[197,10]]},"4728":{"position":[[62,10]]},"4730":{"position":[[56,10],[1530,10],[1797,10]]},"4733":{"position":[[1675,10],[1783,10]]},"4744":{"position":[[268,10],[776,11]]},"4759":{"position":[[574,10]]},"4791":{"position":[[322,10]]}}}],["monitor.git",{"_index":8897,"t":{"2692":{"position":[[182,11]]}}}],["monitor/blob/main/dashboard/readme.md",{"_index":3966,"t":{"953":{"position":[[60,37]]},"1844":{"position":[[60,37]]},"2977":{"position":[[60,37]]}}}],["monitor/blob/main/dockerfil",{"_index":8899,"t":{"2692":{"position":[[327,29]]}}}],["monitor/blob/main/requirements.txt",{"_index":8901,"t":{"2692":{"position":[[464,35]]}}}],["monitor/boostrap.pi",{"_index":10089,"t":{"3384":{"position":[[866,20]]}}}],["monitor/bootstrap.yaml",{"_index":10073,"t":{"3381":{"position":[[1093,23]]}}}],["monitor/debian12",{"_index":10004,"t":{"3357":{"position":[[1350,16]]}}}],["monitor/tree/main/cloud_level_testing/featur",{"_index":8903,"t":{"2692":{"position":[[693,47]]}}}],["monitor/tree/main/container_level_testing/featur",{"_index":8905,"t":{"2692":{"position":[[830,51]]}}}],["monitor_address",{"_index":5110,"t":{"1226":{"position":[[5321,16]]}}}],["monitoring.localhost",{"_index":9336,"t":{"2934":{"position":[[488,20]]}}}],["monitoring.localhost:8080",{"_index":9232,"t":{"2873":{"position":[[404,26]]}}}],["monitoring.scs.community/alertmanag",{"_index":8771,"t":{"2628":{"position":[[751,37]]}}}],["monitoring.scs.community/thano",{"_index":8767,"t":{"2628":{"position":[[555,31]]}}}],["monitoring.yaml",{"_index":11858,"t":{"4833":{"position":[[337,15]]}}}],["monitoring1",{"_index":196,"t":{"26":{"position":[[307,11]]},"28":{"position":[[764,11]]}}}],["monitornig",{"_index":8953,"t":{"2712":{"position":[[77,11]]}}}],["monolith",{"_index":9282,"t":{"2914":{"position":[[628,11]]},"2916":{"position":[[627,10]]}}}],["monolyt",{"_index":8982,"t":{"2716":{"position":[[1030,9]]}}}],["monorepo",{"_index":5012,"t":{"1216":{"position":[[82,9]]}}}],["month",{"_index":4064,"t":{"963":{"position":[[4108,6]]},"1854":{"position":[[4108,6]]},"2055":{"position":[[40,7]]},"2987":{"position":[[4108,6]]},"3022":{"position":[[277,7]]},"3168":{"position":[[9,6],[938,6]]},"3253":{"position":[[48,7]]},"3292":{"position":[[96,7]]},"3604":{"position":[[171,6]]},"3661":{"position":[[493,5],[689,5],[1365,7]]},"3698":{"position":[[598,5],[799,5],[1528,5],[2019,7]]},"3731":{"position":[[1199,6],[1389,7],[1549,6]]},"3785":{"position":[[598,5],[784,5],[1280,6],[1717,7]]},"3829":{"position":[[980,5],[4870,5]]},"3894":{"position":[[385,5]]},"3971":{"position":[[61,6],[491,6],[506,6]]},"4109":{"position":[[650,6],[686,5]]},"4257":{"position":[[6005,5],[6037,6]]},"4270":{"position":[[695,5],[727,6]]},"4340":{"position":[[667,7],[688,6],[744,6]]},"4344":{"position":[[50,6]]},"4351":{"position":[[374,7],[443,6],[755,7]]},"4355":{"position":[[247,6]]},"4493":{"position":[[274,7]]},"4662":{"position":[[1592,6],[1637,6],[1660,6]]}}}],["monthli",{"_index":6158,"t":{"1437":{"position":[[412,7]]},"3731":{"position":[[544,8]]},"3829":{"position":[[926,7],[1433,8],[1613,7],[2212,8]]},"4340":{"position":[[350,8]]},"4351":{"position":[[860,8]]},"4493":{"position":[[291,7]]}}}],["months/year",{"_index":9959,"t":{"3325":{"position":[[92,12]]}}}],["more",{"_index":476,"t":{"61":{"position":[[146,4]]},"72":{"position":[[303,4]]},"171":{"position":[[1261,4]]},"183":{"position":[[205,4]]},"187":{"position":[[35,4]]},"190":{"position":[[43,4]]},"216":{"position":[[693,4]]},"218":{"position":[[326,4]]},"284":{"position":[[544,4]]},"313":{"position":[[121,4]]},"351":{"position":[[135,4]]},"364":{"position":[[1691,4]]},"368":{"position":[[1503,4]]},"370":{"position":[[570,4]]},"372":{"position":[[305,4]]},"374":{"position":[[120,4]]},"386":{"position":[[327,4]]},"391":{"position":[[571,4]]},"401":{"position":[[1503,4]]},"419":{"position":[[150,4]]},"485":{"position":[[513,4]]},"514":{"position":[[1793,4]]},"530":{"position":[[1701,4]]},"588":{"position":[[124,4],[242,4],[647,4],[793,4]]},"705":{"position":[[504,4]]},"715":{"position":[[815,4]]},"741":{"position":[[1298,4]]},"812":{"position":[[52,4]]},"816":{"position":[[510,4]]},"861":{"position":[[1076,4]]},"910":{"position":[[507,4],[562,4]]},"924":{"position":[[716,4],[772,4],[1739,4],[1947,4],[1974,4],[2184,5]]},"928":{"position":[[151,5]]},"934":{"position":[[1644,4]]},"940":{"position":[[537,4],[596,4],[1057,5]]},"944":{"position":[[687,4]]},"946":{"position":[[289,4]]},"949":{"position":[[921,4]]},"951":{"position":[[141,4]]},"963":{"position":[[5299,4]]},"978":{"position":[[336,4],[490,4]]},"980":{"position":[[753,4],[786,4]]},"993":{"position":[[126,4]]},"1036":{"position":[[301,4]]},"1056":{"position":[[2293,4]]},"1067":{"position":[[1971,4]]},"1107":{"position":[[526,4]]},"1118":{"position":[[172,4],[219,4],[344,4],[375,4],[415,4]]},"1171":{"position":[[515,4]]},"1185":{"position":[[175,4]]},"1189":{"position":[[388,4]]},"1218":{"position":[[437,4]]},"1220":{"position":[[850,4]]},"1230":{"position":[[1030,4],[1196,4]]},"1250":{"position":[[623,4]]},"1252":{"position":[[224,4]]},"1266":{"position":[[912,4]]},"1385":{"position":[[256,4],[436,4]]},"1391":{"position":[[3328,4]]},"1437":{"position":[[277,4]]},"1451":{"position":[[759,5]]},"1455":{"position":[[1090,4]]},"1464":{"position":[[520,4]]},"1544":{"position":[[101,4]]},"1555":{"position":[[54,4]]},"1648":{"position":[[119,4]]},"1700":{"position":[[562,4]]},"1709":{"position":[[118,4]]},"1713":{"position":[[364,4]]},"1718":{"position":[[19,4]]},"1762":{"position":[[1076,4]]},"1794":{"position":[[507,4],[562,4]]},"1815":{"position":[[716,4],[772,4],[1739,4],[1947,4],[1974,4],[2184,5]]},"1819":{"position":[[151,5]]},"1825":{"position":[[1644,4]]},"1831":{"position":[[537,4],[596,4],[1057,5]]},"1835":{"position":[[687,4]]},"1837":{"position":[[289,4]]},"1840":{"position":[[921,4]]},"1842":{"position":[[141,4]]},"1854":{"position":[[5299,4]]},"1869":{"position":[[336,4],[490,4]]},"1871":{"position":[[753,4],[786,4]]},"1884":{"position":[[126,4]]},"1900":{"position":[[125,4]]},"1996":{"position":[[266,4]]},"2005":{"position":[[353,4]]},"2021":{"position":[[353,4]]},"2023":{"position":[[374,4]]},"2027":{"position":[[145,4],[334,4]]},"2163":{"position":[[4127,4]]},"2175":{"position":[[643,4]]},"2184":{"position":[[4404,4]]},"2221":{"position":[[101,4]]},"2258":{"position":[[107,4]]},"2285":{"position":[[777,4],[1211,4],[1316,4]]},"2299":{"position":[[777,4],[1211,4],[1316,4]]},"2329":{"position":[[797,4]]},"2372":{"position":[[298,4]]},"2396":{"position":[[797,4]]},"2443":{"position":[[729,4]]},"2447":{"position":[[850,4]]},"2451":{"position":[[232,4]]},"2485":{"position":[[296,4]]},"2531":{"position":[[248,4],[1301,4]]},"2626":{"position":[[1436,4]]},"2649":{"position":[[2624,4]]},"2665":{"position":[[118,4],[182,4]]},"2697":{"position":[[601,4]]},"2712":{"position":[[1259,4]]},"2745":{"position":[[4,4]]},"2898":{"position":[[507,4]]},"2910":{"position":[[390,4]]},"2948":{"position":[[716,4],[772,4],[1739,4],[1947,4],[1974,4],[2184,5]]},"2952":{"position":[[151,5]]},"2958":{"position":[[1644,4]]},"2964":{"position":[[537,4],[596,4],[1057,5]]},"2968":{"position":[[687,4]]},"2970":{"position":[[289,4]]},"2973":{"position":[[921,4]]},"2975":{"position":[[141,4]]},"2987":{"position":[[5299,4]]},"3002":{"position":[[336,4],[490,4]]},"3004":{"position":[[753,4],[786,4]]},"3022":{"position":[[107,4]]},"3050":{"position":[[644,4],[773,4]]},"3055":{"position":[[152,4]]},"3083":{"position":[[607,4]]},"3088":{"position":[[181,4]]},"3091":{"position":[[220,4]]},"3116":{"position":[[345,4]]},"3121":{"position":[[639,4]]},"3124":{"position":[[106,4]]},"3148":{"position":[[914,4]]},"3153":{"position":[[1129,4],[1146,4],[1273,4]]},"3162":{"position":[[286,4]]},"3168":{"position":[[977,4]]},"3187":{"position":[[333,4]]},"3189":{"position":[[599,4]]},"3191":{"position":[[129,4]]},"3244":{"position":[[146,4]]},"3253":{"position":[[74,4],[141,4]]},"3259":{"position":[[532,4]]},"3266":{"position":[[235,4],[374,4]]},"3268":{"position":[[174,4]]},"3308":{"position":[[351,4]]},"3310":{"position":[[793,4]]},"3315":{"position":[[139,4]]},"3321":{"position":[[307,4],[418,4],[487,4]]},"3323":{"position":[[5,4]]},"3361":{"position":[[693,4],[780,4]]},"3365":{"position":[[234,4]]},"3371":{"position":[[234,4]]},"3378":{"position":[[91,4]]},"3525":{"position":[[774,4]]},"3527":{"position":[[861,4]]},"3539":{"position":[[384,4]]},"3541":{"position":[[114,4]]},"3575":{"position":[[182,4]]},"3592":{"position":[[245,4],[2567,4]]},"3661":{"position":[[380,4],[1346,4]]},"3665":{"position":[[484,4]]},"3671":{"position":[[21,4]]},"3673":{"position":[[1181,4]]},"3679":{"position":[[522,4],[678,4]]},"3681":{"position":[[172,4],[910,4]]},"3698":{"position":[[472,4],[2000,4]]},"3702":{"position":[[556,4]]},"3704":{"position":[[1308,4]]},"3706":{"position":[[271,5],[662,4],[1483,4],[1617,4]]},"3712":{"position":[[44,4],[1484,4],[1761,4]]},"3714":{"position":[[57,4],[1255,4]]},"3716":{"position":[[60,4]]},"3718":{"position":[[172,4],[949,4]]},"3724":{"position":[[291,4]]},"3731":{"position":[[3085,4]]},"3742":{"position":[[252,4]]},"3761":{"position":[[199,4]]},"3763":{"position":[[115,4]]},"3785":{"position":[[472,4],[1698,4]]},"3789":{"position":[[556,4]]},"3793":{"position":[[525,4],[840,4]]},"3799":{"position":[[271,5],[662,4],[1480,4],[1614,4]]},"3805":{"position":[[21,4]]},"3809":{"position":[[37,4]]},"3811":{"position":[[172,4],[949,4]]},"3817":{"position":[[291,4]]},"3824":{"position":[[183,4]]},"3829":{"position":[[1307,4]]},"3831":{"position":[[631,4]]},"3879":{"position":[[282,4]]},"3894":{"position":[[1515,4]]},"3923":{"position":[[626,4]]},"3928":{"position":[[2104,4]]},"3930":{"position":[[364,4],[480,4]]},"3932":{"position":[[395,4],[783,4]]},"3941":{"position":[[297,4],[1139,4],[1533,4]]},"3956":{"position":[[180,4]]},"3982":{"position":[[59,4]]},"3984":{"position":[[1594,4]]},"4021":{"position":[[40,4]]},"4045":{"position":[[812,4],[1035,4],[1441,4]]},"4047":{"position":[[336,4]]},"4053":{"position":[[98,4]]},"4079":{"position":[[430,4]]},"4102":{"position":[[907,4]]},"4107":{"position":[[1991,4]]},"4109":{"position":[[606,4],[669,4],[4705,4],[5210,4],[5510,4]]},"4113":{"position":[[1765,4]]},"4133":{"position":[[1936,4]]},"4137":{"position":[[634,4]]},"4139":{"position":[[337,4]]},"4146":{"position":[[1846,4],[1907,4],[2124,4],[2364,4]]},"4148":{"position":[[123,4]]},"4159":{"position":[[1175,4]]},"4163":{"position":[[2422,4],[3925,4]]},"4165":{"position":[[131,4]]},"4167":{"position":[[312,4]]},"4178":{"position":[[104,4]]},"4200":{"position":[[345,4]]},"4220":{"position":[[86,4],[580,4]]},"4222":{"position":[[2121,4]]},"4230":{"position":[[222,4],[4986,4],[5396,4]]},"4238":{"position":[[482,4]]},"4253":{"position":[[534,4],[543,4]]},"4257":{"position":[[2132,4],[5504,4]]},"4279":{"position":[[574,4]]},"4310":{"position":[[485,4]]},"4327":{"position":[[951,4]]},"4351":{"position":[[645,4]]},"4431":{"position":[[1910,4]]},"4433":{"position":[[1709,4],[2561,4]]},"4448":{"position":[[676,4]]},"4459":{"position":[[423,4],[1669,4]]},"4479":{"position":[[988,4],[1530,4],[2327,4]]},"4481":{"position":[[1087,4]]},"4489":{"position":[[698,4]]},"4506":{"position":[[729,4]]},"4516":{"position":[[1393,4],[1705,4],[1841,4]]},"4518":{"position":[[17,4],[275,4],[462,4]]},"4520":{"position":[[401,4]]},"4522":{"position":[[1052,4],[1126,4],[1881,4]]},"4529":{"position":[[564,4]]},"4533":{"position":[[621,4]]},"4535":{"position":[[950,4],[1745,4],[4393,4]]},"4539":{"position":[[1740,4],[3067,4],[4095,4]]},"4545":{"position":[[430,4]]},"4547":{"position":[[193,4]]},"4562":{"position":[[4232,4],[4241,4],[4784,4]]},"4569":{"position":[[741,4]]},"4574":{"position":[[451,4]]},"4593":{"position":[[5835,4]]},"4610":{"position":[[274,4]]},"4632":{"position":[[1186,4]]},"4722":{"position":[[678,4]]},"4724":{"position":[[370,4],[379,4]]},"4767":{"position":[[81,4]]},"4786":{"position":[[23,4]]},"4801":{"position":[[408,4]]},"4845":{"position":[[37,4],[142,4]]},"4849":{"position":[[176,4]]},"4861":{"position":[[490,4]]}}}],["moreov",{"_index":8520,"t":{"2485":{"position":[[122,9]]},"2525":{"position":[[447,9]]},"4148":{"position":[[164,9]]},"4222":{"position":[[3928,9]]},"4291":{"position":[[1563,9]]}}}],["mostli",{"_index":6565,"t":{"1619":{"position":[[714,6]]},"1950":{"position":[[714,6]]},"2712":{"position":[[1003,6]]},"3047":{"position":[[96,9]]},"4104":{"position":[[98,6]]},"4226":{"position":[[1793,6]]},"4353":{"position":[[438,6]]},"4431":{"position":[[2129,6]]},"4547":{"position":[[1593,6]]},"4746":{"position":[[42,6]]}}}],["motiv",{"_index":3207,"t":{"728":{"position":[[340,10]]},"3529":{"position":[[160,10],[1402,10]]},"4236":{"position":[[15,10]]},"4279":{"position":[[432,10]]},"4414":{"position":[[17,9]]},"4782":{"position":[[44,10]]},"4812":{"position":[[0,10]]}}}],["motto",{"_index":1556,"t":{"207":{"position":[[756,6]]}}}],["mount",{"_index":2540,"t":{"514":{"position":[[140,5]]},"715":{"position":[[399,6]]},"717":{"position":[[508,6]]},"719":{"position":[[224,7]]},"724":{"position":[[211,6]]},"726":{"position":[[310,7]]},"1303":{"position":[[3336,7],[3456,9]]},"1385":{"position":[[399,7],[580,5]]},"1464":{"position":[[218,6]]},"1736":{"position":[[276,6],[774,6]]},"2013":{"position":[[99,7]]},"2034":{"position":[[258,7],[581,7]]},"2155":{"position":[[374,5],[766,5]]},"2211":{"position":[[333,5]]},"2240":{"position":[[108,8],[133,7],[503,7],[571,8],[1109,6]]},"2248":{"position":[[241,8],[494,5],[533,5],[620,5],[664,5]]},"2360":{"position":[[1900,7]]},"2427":{"position":[[1900,7]]},"2624":{"position":[[642,7]]},"4113":{"position":[[2398,7]]},"4407":{"position":[[267,5]]},"4539":{"position":[[2665,7]]}}}],["mounter",{"_index":5993,"t":{"1405":{"position":[[785,9],[833,9]]}}}],["mountpoint",{"_index":6255,"t":{"1466":{"position":[[1978,11]]},"2248":{"position":[[325,11]]},"2250":{"position":[[354,12]]},"2254":{"position":[[673,12]]}}}],["mous",{"_index":4063,"t":{"963":{"position":[[4080,6]]},"1854":{"position":[[4080,6]]},"2987":{"position":[[4080,6]]}}}],["move",{"_index":1189,"t":{"175":{"position":[[772,5]]},"502":{"position":[[23,6]]},"514":{"position":[[1111,4]]},"671":{"position":[[332,4]]},"728":{"position":[[235,6]]},"802":{"position":[[46,4]]},"1175":{"position":[[5070,4]]},"1433":{"position":[[1159,4]]},"1482":{"position":[[17,6]]},"1495":{"position":[[17,6]]},"1529":{"position":[[23,4]]},"1641":{"position":[[74,4]]},"1972":{"position":[[74,4]]},"2240":{"position":[[63,5]]},"2258":{"position":[[285,4]]},"2382":{"position":[[84,5]]},"3093":{"position":[[236,5]]},"3166":{"position":[[74,4]]},"3189":{"position":[[785,6]]},"3204":{"position":[[102,4]]},"3223":{"position":[[740,5]]},"3225":{"position":[[709,5],[792,5]]},"3279":{"position":[[415,4]]},"3355":{"position":[[338,4]]},"3539":{"position":[[206,6]]},"3558":{"position":[[0,4],[315,4]]},"3722":{"position":[[104,5]]},"3910":{"position":[[366,5]]},"4064":{"position":[[189,5]]},"4224":{"position":[[1241,4]]},"4228":{"position":[[1033,6]]},"4522":{"position":[[882,6]]},"4597":{"position":[[76,4]]}}}],["movement",{"_index":8129,"t":{"2242":{"position":[[40,8]]},"2529":{"position":[[402,8]]}}}],["mozilla",{"_index":11466,"t":{"4306":{"position":[[481,7]]},"4319":{"position":[[132,7]]},"4337":{"position":[[562,7]]}}}],["mozilla'",{"_index":11467,"t":{"4306":{"position":[[602,9]]}}}],["mozillawiki",{"_index":11483,"t":{"4335":{"position":[[244,12]]}}}],["mpl",{"_index":1091,"t":{"171":{"position":[[1375,3]]}}}],["mqtt",{"_index":2158,"t":{"366":{"position":[[60,4],[146,4],[642,5]]}}}],["ms",{"_index":6213,"t":{"1455":{"position":[[1240,2]]},"1704":{"position":[[1777,2],[2055,2],[2118,2],[2456,2],[2734,2],[2797,2]]},"3925":{"position":[[1894,2]]}}}],["msg",{"_index":2245,"t":{"368":{"position":[[7839,4]]},"1457":{"position":[[3375,6],[3554,6]]},"1704":{"position":[[2047,3],[2105,3],[2726,3],[2784,3]]},"2110":{"position":[[3899,6]]},"2142":{"position":[[157,4]]}}}],["msg=\"purg",{"_index":3151,"t":{"706":{"position":[[2547,10]]}}}],["msg=\"purgeupload",{"_index":3143,"t":{"706":{"position":[[2378,17]]}}}],["msg=\"start",{"_index":3136,"t":{"706":{"position":[[2220,13]]}}}],["msgr",{"_index":5998,"t":{"1405":{"position":[[1349,4],[1507,4]]}}}],["msgr2",{"_index":5997,"t":{"1405":{"position":[[1329,6]]}}}],["mssql",{"_index":6212,"t":{"1455":{"position":[[1221,5]]}}}],["mt69p",{"_index":2939,"t":{"590":{"position":[[889,5]]}}}],["mta",{"_index":3950,"t":{"949":{"position":[[482,4]]},"1840":{"position":[[482,4]]},"2973":{"position":[[482,4]]}}}],["mtr",{"_index":4522,"t":{"1144":{"position":[[414,3]]}}}],["mtu",{"_index":2828,"t":{"557":{"position":[[6514,5]]},"1226":{"position":[[2648,4],[4909,4]]},"1271":{"position":[[175,3]]},"1275":{"position":[[503,4],[527,4]]},"1331":{"position":[[17,3],[73,3],[191,3],[288,4],[341,3]]},"2048":{"position":[[1703,3],[2019,4]]}}}],["much",{"_index":1075,"t":{"171":{"position":[[951,4]]},"370":{"position":[[758,4]]},"407":{"position":[[153,4]]},"434":{"position":[[150,4]]},"508":{"position":[[150,4]]},"600":{"position":[[158,4]]},"928":{"position":[[518,4]]},"978":{"position":[[1380,4]]},"1103":{"position":[[149,4],[321,4]]},"1107":{"position":[[491,4]]},"1118":{"position":[[516,4]]},"1363":{"position":[[70,4]]},"1819":{"position":[[518,4]]},"1869":{"position":[[1380,4]]},"2027":{"position":[[206,4]]},"2184":{"position":[[4078,4]]},"2234":{"position":[[143,4]]},"2429":{"position":[[422,4]]},"2578":{"position":[[359,4]]},"2952":{"position":[[518,4]]},"3002":{"position":[[1380,4]]},"3014":{"position":[[74,4]]},"3067":{"position":[[618,4]]},"3121":{"position":[[634,4]]},"3144":{"position":[[289,4]]},"3150":{"position":[[640,4]]},"3176":{"position":[[254,4]]},"3214":{"position":[[412,4]]},"3244":{"position":[[141,4]]},"3253":{"position":[[136,4]]},"3310":{"position":[[341,4]]},"3348":{"position":[[841,4]]},"3681":{"position":[[1361,5]]},"3718":{"position":[[1388,5]]},"3761":{"position":[[1354,4]]},"3811":{"position":[[1365,5]]},"3928":{"position":[[1620,4]]},"3947":{"position":[[1976,4],[4301,4]]},"3968":{"position":[[1911,4]]},"3971":{"position":[[1050,4]]},"3984":{"position":[[1082,4]]},"4150":{"position":[[181,4]]},"4189":{"position":[[533,5]]},"4191":{"position":[[194,5]]},"4224":{"position":[[302,4],[1249,4]]},"4226":{"position":[[3378,4]]},"4253":{"position":[[585,4]]},"4257":{"position":[[5485,4]]},"4302":{"position":[[4469,4]]},"4491":{"position":[[90,4]]},"4545":{"position":[[520,5]]},"4656":{"position":[[24,4]]},"4733":{"position":[[1325,4]]},"4746":{"position":[[187,4]]}}}],["multi",{"_index":3386,"t":{"865":{"position":[[878,6]]},"871":{"position":[[175,6],[678,6]]},"873":{"position":[[235,6],[673,6]]},"887":{"position":[[9190,6]]},"1064":{"position":[[1122,5],[1314,5]]},"1766":{"position":[[878,6]]},"1772":{"position":[[175,6],[678,6]]},"1774":{"position":[[235,6],[673,6]]},"1811":{"position":[[9190,6]]},"2580":{"position":[[584,5],[756,5]]},"2582":{"position":[[224,5],[455,5]]},"2600":{"position":[[293,5]]},"2632":{"position":[[323,5]]},"3083":{"position":[[478,5]]},"3296":{"position":[[0,5],[58,5],[350,5]]},"3665":{"position":[[1102,5]]},"3702":{"position":[[1315,5]]},"3714":{"position":[[1495,5]]},"3744":{"position":[[550,5]]},"3789":{"position":[[1174,5]]},"3925":{"position":[[798,5]]},"3928":{"position":[[503,5],[954,5],[4310,5]]},"4420":{"position":[[1081,5],[1243,5]]},"4437":{"position":[[154,5],[167,5]]},"4562":{"position":[[5268,5],[6174,5],[7380,5]]}}}],["multiattach",{"_index":10974,"t":{"3947":{"position":[[2187,12],[2501,12],[2543,12]]},"3951":{"position":[[187,11]]}}}],["multipl",{"_index":401,"t":{"37":{"position":[[1679,8]]},"401":{"position":[[175,8]]},"423":{"position":[[21,8]]},"477":{"position":[[215,8],[285,8],[334,8],[357,8]]},"496":{"position":[[379,9]]},"533":{"position":[[168,8],[336,8]]},"541":{"position":[[1406,8]]},"545":{"position":[[801,8]]},"547":{"position":[[68,8],[88,8],[130,8],[258,8]]},"549":{"position":[[127,8],[195,8],[701,8],[1676,8]]},"595":{"position":[[95,8],[637,8],[775,8]]},"604":{"position":[[3,8]]},"620":{"position":[[10,8]]},"628":{"position":[[0,8]]},"630":{"position":[[10,8]]},"643":{"position":[[14,8]]},"675":{"position":[[14,8]]},"706":{"position":[[253,8]]},"712":{"position":[[264,8]]},"814":{"position":[[46,8]]},"836":{"position":[[299,8]]},"848":{"position":[[417,8]]},"912":{"position":[[1933,8]]},"914":{"position":[[1385,8]]},"938":{"position":[[265,8]]},"946":{"position":[[12,8],[332,8]]},"978":{"position":[[1682,8]]},"1005":{"position":[[1451,8]]},"1046":{"position":[[164,8]]},"1064":{"position":[[1786,8],[2391,8]]},"1067":{"position":[[1003,8]]},"1230":{"position":[[984,8],[1150,8]]},"1421":{"position":[[1488,8]]},"1429":{"position":[[133,8]]},"1431":{"position":[[239,8]]},"1441":{"position":[[56,8]]},"1796":{"position":[[1933,8]]},"1798":{"position":[[1385,8]]},"1829":{"position":[[265,8]]},"1837":{"position":[[12,8],[332,8]]},"1869":{"position":[[1682,8]]},"1896":{"position":[[1451,8]]},"2037":{"position":[[286,8]]},"2190":{"position":[[496,8]]},"2196":{"position":[[832,8]]},"2276":{"position":[[1692,8]]},"2283":{"position":[[494,8]]},"2295":{"position":[[40,8],[314,8]]},"2297":{"position":[[494,8]]},"2309":{"position":[[40,8],[314,8]]},"2549":{"position":[[269,8]]},"2590":{"position":[[157,8]]},"2663":{"position":[[111,8]]},"2682":{"position":[[371,8]]},"2716":{"position":[[242,8],[282,8],[316,8]]},"2912":{"position":[[13,8]]},"2914":{"position":[[651,8]]},"2962":{"position":[[265,8]]},"2970":{"position":[[12,8],[332,8]]},"3002":{"position":[[1682,8]]},"3032":{"position":[[97,8]]},"3153":{"position":[[853,8]]},"3527":{"position":[[2066,8]]},"3592":{"position":[[684,8]]},"3600":{"position":[[962,8]]},"3613":{"position":[[230,8]]},"3702":{"position":[[1456,8]]},"3761":{"position":[[900,8]]},"3789":{"position":[[1315,8]]},"3872":{"position":[[264,8]]},"3874":{"position":[[382,8]]},"3894":{"position":[[1421,8],[1650,8]]},"3925":{"position":[[1007,8]]},"3947":{"position":[[1282,8],[1572,8],[2255,8],[2685,8],[4101,8]]},"3971":{"position":[[318,8]]},"4015":{"position":[[431,8]]},"4028":{"position":[[44,8]]},"4107":{"position":[[459,8]]},"4176":{"position":[[134,8],[168,8]]},"4178":{"position":[[841,8]]},"4185":{"position":[[597,8]]},"4187":{"position":[[250,8]]},"4220":{"position":[[927,8],[1550,8],[1741,8]]},"4222":{"position":[[751,8]]},"4238":{"position":[[549,8]]},"4313":{"position":[[61,8]]},"4351":{"position":[[33,8]]},"4420":{"position":[[708,8],[1131,8]]},"4427":{"position":[[365,8],[437,8]]},"4431":{"position":[[67,8],[116,8],[333,8],[2353,8]]},"4433":{"position":[[1277,8],[1737,8],[2235,8]]},"4435":{"position":[[745,8],[939,8],[993,8],[1026,8]]},"4440":{"position":[[357,8],[429,8]]},"4444":{"position":[[395,8]]},"4448":{"position":[[491,8],[814,8]]},"4451":{"position":[[357,8],[429,8]]},"4455":{"position":[[395,8]]},"4459":{"position":[[217,8],[564,8],[1274,8]]},"4464":{"position":[[61,8]]},"4479":{"position":[[243,8]]},"4483":{"position":[[212,8],[631,9]]},"4487":{"position":[[28,8]]},"4504":{"position":[[460,8]]},"4508":{"position":[[706,8]]},"4535":{"position":[[1502,8]]},"4539":{"position":[[1503,8],[6860,8]]},"4547":{"position":[[1924,8],[2343,8]]},"4560":{"position":[[2753,8]]},"4562":{"position":[[5171,8],[6694,8]]},"4589":{"position":[[8,8]]},"4593":{"position":[[1884,8],[4168,8],[5042,8]]},"4667":{"position":[[13426,8],[13781,8]]},"4691":{"position":[[1411,8]]},"4705":{"position":[[99,8],[145,8]]},"4730":{"position":[[2108,8]]}}}],["multipli",{"_index":3235,"t":{"741":{"position":[[1167,11],[1274,10]]},"906":{"position":[[526,10],[547,10],[580,10],[613,10]]},"912":{"position":[[1076,10],[1114,10],[1168,10],[1222,10],[3301,10],[3335,10],[3354,10],[3404,10],[3431,10],[3481,10],[3508,10],[3558,10],[5896,10],[5956,10],[6113,10],[6326,10]]},"1790":{"position":[[526,10],[547,10],[580,10],[613,10]]},"1796":{"position":[[1076,10],[1114,10],[1168,10],[1222,10],[3301,10],[3335,10],[3354,10],[3404,10],[3431,10],[3481,10],[3508,10],[3558,10],[5896,10],[5956,10],[6113,10],[6326,10]]}}}],["multiprocessor",{"_index":10600,"t":{"3714":{"position":[[544,15]]},"3744":{"position":[[273,14]]}}}],["multitail",{"_index":4535,"t":{"1147":{"position":[[190,9]]}}}],["mutabl",{"_index":8331,"t":{"2283":{"position":[[666,7]]},"2297":{"position":[[666,7]]}}}],["mutat",{"_index":2463,"t":{"479":{"position":[[1576,8]]},"4479":{"position":[[941,8]]},"4489":{"position":[[310,8]]},"4539":{"position":[[6701,6]]}}}],["mute",{"_index":6487,"t":{"1576":{"position":[[14,4]]},"1919":{"position":[[14,4]]}}}],["mutual",{"_index":11468,"t":{"4310":{"position":[[459,8]]}}}],["mv",{"_index":2991,"t":{"653":{"position":[[335,2]]},"671":{"position":[[443,2],[811,2]]},"703":{"position":[[586,2]]}}}],["mvp",{"_index":514,"t":{"70":{"position":[[513,4]]},"2618":{"position":[[1254,3],[1298,3]]},"2622":{"position":[[94,3]]},"4654":{"position":[[541,3]]},"4730":{"position":[[9,3],[654,3]]}}}],["mwf8uclkgrunvsylsmgupb163l89",{"_index":7962,"t":{"2196":{"position":[[3521,28]]}}}],["mx",{"_index":10357,"t":{"3665":{"position":[[1161,2]]},"3702":{"position":[[1374,2]]},"3789":{"position":[[1233,2]]}}}],["mx]n",{"_index":10308,"t":{"3658":{"position":[[118,8]]}}}],["mx]n[n/h/s/p",{"_index":10519,"t":{"3695":{"position":[[98,15]]}}}],["mx]n[n/s/l/p",{"_index":10812,"t":{"3782":{"position":[[98,15]]}}}],["mxmxchere",{"_index":251,"t":{"28":{"position":[[1216,9]]}}}],["my_cinder_featur",{"_index":8026,"t":{"2211":{"position":[[1503,17]]}}}],["my_corp_net",{"_index":8177,"t":{"2252":{"position":[[1646,12],[1947,11]]}}}],["my_feature_branch",{"_index":8023,"t":{"2211":{"position":[[1347,17]]}}}],["my_job",{"_index":2132,"t":{"362":{"position":[[264,7]]}}}],["my_job1",{"_index":2129,"t":{"362":{"position":[[217,7]]}}}],["my_job2",{"_index":2130,"t":{"362":{"position":[[227,7]]}}}],["my_network=10.50.40.230",{"_index":8215,"t":{"2254":{"position":[[426,23]]}}}],["my_other_corp_net",{"_index":8198,"t":{"2252":{"position":[[2132,17]]}}}],["my_pipeline1",{"_index":2128,"t":{"362":{"position":[[195,13]]}}}],["my_pipeline2",{"_index":2131,"t":{"362":{"position":[[242,13]]}}}],["mycirro",{"_index":3381,"t":{"865":{"position":[[750,8]]},"1766":{"position":[[750,8]]}}}],["mycloud",{"_index":408,"t":{"37":{"position":[[1821,7]]},"963":{"position":[[2494,7],[2702,7]]},"1854":{"position":[[2494,7],[2702,7]]},"2117":{"position":[[584,7]]},"2987":{"position":[[2494,7],[2702,7]]}}}],["mydomain.exampl",{"_index":2788,"t":{"557":{"position":[[4764,20]]}}}],["mydomain.xyz",{"_index":7582,"t":{"2117":{"position":[[702,13]]}}}],["myfile.pi",{"_index":7504,"t":{"2098":{"position":[[6,9]]},"2104":{"position":[[144,9]]}}}],["myfirsttestjob",{"_index":2238,"t":{"368":{"position":[[6734,14],[7031,14],[7099,14]]}}}],["myflavor",{"_index":7577,"t":{"2117":{"position":[[600,8]]}}}],["mykeypair",{"_index":7578,"t":{"2117":{"position":[[638,9]]}}}],["myprivatenet",{"_index":7579,"t":{"2117":{"position":[[657,12]]}}}],["myproject",{"_index":7580,"t":{"2117":{"position":[[679,9]]}}}],["myprovid",{"_index":2974,"t":{"622":{"position":[[289,10]]},"661":{"position":[[226,12]]}}}],["myprovider.csctl.clusterstack.x",{"_index":2975,"t":{"622":{"position":[[312,31]]}}}],["myprovider>.csctl.clusterstack.x",{"_index":3000,"t":{"661":{"position":[[251,33]]}}}],["myriad",{"_index":11587,"t":{"4525":{"position":[[236,6]]}}}],["mysecondtestjob",{"_index":2241,"t":{"368":{"position":[[6942,15],[7061,15],[7158,15]]}}}],["mysql",{"_index":7718,"t":{"2142":{"position":[[249,5]]},"2914":{"position":[[914,7]]}}}],["mysql_db",{"_index":6425,"t":{"1561":{"position":[[351,8]]},"2142":{"position":[[148,8]]}}}],["mysql_us",{"_index":6435,"t":{"1561":{"position":[[672,10]]}}}],["mysqlbackup",{"_index":6403,"t":{"1555":{"position":[[728,11],[876,11]]}}}],["mytest.conf",{"_index":4349,"t":{"1007":{"position":[[192,11]]},"1898":{"position":[[192,11]]}}}],["n",{"_index":2431,"t":{"473":{"position":[[955,1]]},"475":{"position":[[407,1],[746,1]]},"481":{"position":[[200,1],[432,1]]},"493":{"position":[[11,1]]},"518":{"position":[[74,1]]},"528":{"position":[[776,1]]},"578":{"position":[[784,1]]},"584":{"position":[[506,1]]},"588":{"position":[[1659,1],[1916,1]]},"688":{"position":[[54,1]]},"692":{"position":[[186,1]]},"708":{"position":[[270,1],[428,1],[593,1],[1098,1]]},"738":{"position":[[1145,1]]},"739":{"position":[[413,1]]},"741":{"position":[[883,1]]},"747":{"position":[[105,1]]},"938":{"position":[[905,1],[2465,2],[2626,1],[2710,1],[2725,1],[2730,1],[2771,1]]},"940":{"position":[[62,1],[445,1],[450,1]]},"942":{"position":[[978,1],[2311,1],[2316,1],[2395,1],[2400,1],[2500,1],[3222,1]]},"949":{"position":[[373,1]]},"1175":{"position":[[4940,1],[5005,1]]},"1177":{"position":[[2438,1],[2503,1],[2571,1],[5942,1],[6006,1],[6070,1],[6134,1]]},"1425":{"position":[[126,1]]},"1829":{"position":[[905,1],[2465,2],[2626,1],[2710,1],[2725,1],[2730,1],[2771,1]]},"1831":{"position":[[62,1],[445,1],[450,1]]},"1833":{"position":[[978,1],[2311,1],[2316,1],[2395,1],[2400,1],[2500,1],[3222,1]]},"1840":{"position":[[373,1]]},"1909":{"position":[[158,1]]},"2144":{"position":[[133,1]]},"2150":{"position":[[210,1]]},"2480":{"position":[[1409,1]]},"2602":{"position":[[1543,1]]},"2873":{"position":[[267,1]]},"2962":{"position":[[905,1],[2465,2],[2626,1],[2710,1],[2725,1],[2730,1],[2771,1]]},"2964":{"position":[[62,1],[445,1],[450,1]]},"2966":{"position":[[978,1],[2311,1],[2316,1],[2395,1],[2400,1],[2500,1],[3222,1]]},"2973":{"position":[[373,1]]},"3126":{"position":[[189,1]]},"3527":{"position":[[1045,1]]},"3658":{"position":[[96,1],[197,1]]},"3665":{"position":[[18,1],[331,1],[439,1],[593,1]]},"3673":{"position":[[443,1],[539,1],[680,1]]},"3677":{"position":[[789,1]]},"3695":{"position":[[131,1]]},"3702":{"position":[[90,1],[403,1],[511,1],[665,1],[1781,1]]},"3712":{"position":[[116,3]]},"3714":{"position":[[150,3],[525,1],[649,1]]},"3744":{"position":[[150,4]]},"3782":{"position":[[131,1]]},"3789":{"position":[[90,1],[403,1],[511,1],[665,1],[1640,1]]},"3791":{"position":[[811,1]]},"3807":{"position":[[64,1],[160,1],[303,1],[353,1]]},"3829":{"position":[[3470,1],[3684,1],[3695,1],[4102,1]]},"3888":{"position":[[242,2],[265,1]]},"3894":{"position":[[106,1],[605,1],[670,1],[906,4],[1175,3]]},"4853":{"position":[[564,1]]},"4855":{"position":[[159,1]]},"4857":{"position":[[177,1],[370,1]]}}}],["n/a",{"_index":8216,"t":{"2254":{"position":[[452,3]]},"4302":{"position":[[1310,4],[1465,4]]}}}],["n/s/l/p",{"_index":10309,"t":{"3658":{"position":[[127,9]]}}}],["n[u][o",{"_index":10307,"t":{"3658":{"position":[[109,8]]},"3695":{"position":[[88,7]]},"3782":{"position":[[88,7]]}}}],["n_bms_3",{"_index":10539,"t":{"3702":{"position":[[1850,7]]},"3789":{"position":[[1709,7]]}}}],["naa",{"_index":11333,"t":{"4226":{"position":[[432,7]]},"4244":{"position":[[55,6]]},"4246":{"position":[[44,6]]}}}],["naabu",{"_index":8547,"t":{"2489":{"position":[[1421,5]]},"2506":{"position":[[210,5]]},"2512":{"position":[[169,5]]},"2549":{"position":[[15,5]]}}}],["name",{"_index":190,"t":{"26":{"position":[[172,4]]},"28":{"position":[[26,4]]},"31":{"position":[[31,4]]},"33":{"position":[[26,4]]},"37":{"position":[[1493,5]]},"93":{"position":[[98,5]]},"147":{"position":[[23,6],[84,4],[122,5],[183,5]]},"151":{"position":[[221,4],[395,5]]},"153":{"position":[[216,4],[340,5]]},"155":{"position":[[113,5],[257,5],[511,5],[646,5],[789,5],[925,5],[986,5]]},"167":{"position":[[1759,4]]},"199":{"position":[[1762,5]]},"222":{"position":[[46,4],[64,4]]},"271":{"position":[[259,4]]},"301":{"position":[[204,5]]},"303":{"position":[[344,6],[362,4],[547,4]]},"307":{"position":[[251,4]]},"323":{"position":[[1500,5]]},"362":{"position":[[126,5],[364,4]]},"366":{"position":[[477,5]]},"368":{"position":[[335,5],[777,5],[833,4],[939,4],[2565,5],[2651,5],[2816,4],[3435,5],[4368,5],[4374,6],[5210,6],[5254,4],[5324,6],[5422,5],[5572,4],[5733,4],[5775,4],[6117,5],[6202,4],[6261,4],[6521,5],[6728,5],[6773,5],[6796,4],[6936,5]]},"382":{"position":[[854,6]]},"393":{"position":[[263,6],[431,4]]},"397":{"position":[[254,4]]},"434":{"position":[[935,4],[1185,4]]},"440":{"position":[[281,4]]},"463":{"position":[[58,4],[184,6],[262,4],[278,4],[580,4]]},"465":{"position":[[189,5],[250,5]]},"477":{"position":[[112,4]]},"479":{"position":[[842,4],[1245,4]]},"493":{"position":[[583,4],[833,4],[960,4]]},"510":{"position":[[292,5]]},"514":{"position":[[454,4]]},"518":{"position":[[948,5]]},"530":{"position":[[2561,6],[2601,6],[2809,6],[2878,6]]},"551":{"position":[[1924,5]]},"555":{"position":[[61,5],[309,5],[356,5],[399,5],[619,5],[775,4],[824,6],[916,5]]},"557":{"position":[[0,4],[1674,5],[1781,4],[1882,4],[4825,5],[5330,5],[5464,5],[5581,6],[5874,5],[6319,5],[6399,5]]},"584":{"position":[[163,4]]},"586":{"position":[[51,4],[91,4],[537,4],[821,5],[893,5],[1107,5],[1267,5],[1361,5]]},"588":{"position":[[909,5],[1150,5],[1197,5],[1240,5],[1458,5]]},"590":{"position":[[61,4]]},"595":{"position":[[188,8]]},"611":{"position":[[454,5]]},"622":{"position":[[416,4]]},"632":{"position":[[274,5]]},"661":{"position":[[568,4]]},"671":{"position":[[139,4]]},"688":{"position":[[64,4]]},"692":{"position":[[202,4]]},"705":{"position":[[165,5],[1302,5]]},"708":{"position":[[245,4],[403,4],[520,4],[568,4],[710,4],[770,4],[860,4],[1073,4]]},"732":{"position":[[1462,4]]},"739":{"position":[[388,4],[1371,5]]},"747":{"position":[[121,4]]},"846":{"position":[[615,4]]},"865":{"position":[[424,4],[744,5],[1648,4]]},"869":{"position":[[166,4]]},"871":{"position":[[335,4],[572,5]]},"873":{"position":[[392,4],[551,6],[568,5]]},"875":{"position":[[65,4]]},"887":{"position":[[9053,5]]},"890":{"position":[[200,6]]},"894":{"position":[[348,4],[627,4],[637,4],[737,4],[1015,6],[1120,6],[2163,4]]},"896":{"position":[[340,4],[388,6],[458,4]]},"898":{"position":[[34,5],[120,4],[166,5]]},"906":{"position":[[213,4],[380,4]]},"908":{"position":[[324,4]]},"910":{"position":[[289,4]]},"912":{"position":[[546,4],[689,4],[694,5],[798,4],[2215,4],[2238,4],[2268,4],[2520,4],[2525,4],[2761,4],[2797,4],[3643,5],[4084,4],[4176,4],[4660,4],[4767,4],[5263,4],[5370,4],[7124,4],[7207,4],[7588,5],[8175,4],[8259,4]]},"914":{"position":[[649,4],[654,5],[945,4],[1743,4],[1748,4]]},"926":{"position":[[153,5],[169,5]]},"932":{"position":[[583,5],[1738,4],[1970,4],[2923,4],[3307,4]]},"934":{"position":[[1206,5],[2035,5],[2089,5]]},"938":{"position":[[1846,4],[2121,6]]},"942":{"position":[[3964,4]]},"951":{"position":[[42,4],[876,4]]},"963":{"position":[[2064,5],[2215,4]]},"978":{"position":[[586,4],[1118,4]]},"980":{"position":[[87,5]]},"1005":{"position":[[288,4],[963,4]]},"1142":{"position":[[221,5]]},"1167":{"position":[[466,5],[507,5],[550,5],[587,5]]},"1171":{"position":[[129,5]]},"1173":{"position":[[128,5]]},"1175":{"position":[[720,5],[3467,5]]},"1181":{"position":[[155,4]]},"1185":{"position":[[283,5],[331,4],[875,4],[901,4],[1152,4]]},"1191":{"position":[[1038,4],[1101,4]]},"1201":{"position":[[907,5]]},"1203":{"position":[[334,4]]},"1205":{"position":[[155,5],[284,4],[358,5],[448,4]]},"1226":{"position":[[1182,4],[1229,4],[1306,4],[2801,4],[2848,4]]},"1230":{"position":[[617,4],[1389,4]]},"1244":{"position":[[304,5]]},"1248":{"position":[[684,5],[1192,4]]},"1252":{"position":[[332,5],[402,4],[1338,4],[1364,4]]},"1259":{"position":[[551,4]]},"1268":{"position":[[243,5]]},"1303":{"position":[[276,5]]},"1314":{"position":[[375,8],[522,8],[772,8],[919,8]]},"1316":{"position":[[269,4],[346,5],[414,5]]},"1324":{"position":[[6661,4],[6920,4],[7198,4],[12983,4]]},"1346":{"position":[[1192,6]]},"1383":{"position":[[1364,5]]},"1385":{"position":[[718,4],[755,4],[830,4],[908,4],[989,4],[1051,4]]},"1391":{"position":[[237,5],[1922,5],[2131,4],[2560,5]]},"1407":{"position":[[1120,4],[1704,5]]},"1409":{"position":[[485,5],[1207,5]]},"1411":{"position":[[547,5],[854,5],[1161,5],[1467,5],[1774,5],[2091,5],[2397,5]]},"1417":{"position":[[162,5],[187,5],[212,5]]},"1419":{"position":[[124,5],[158,5],[177,5],[196,5],[215,5],[249,5],[268,5],[287,5],[306,5],[340,5],[359,5],[378,5]]},"1421":{"position":[[344,4],[403,5],[430,5],[457,5],[1214,5],[1283,6],[1356,5],[1457,5],[1471,5],[1574,5],[1770,5]]},"1429":{"position":[[4,4],[93,4]]},"1443":{"position":[[581,5],[633,5]]},"1466":{"position":[[974,4],[1671,4]]},"1472":{"position":[[232,4]]},"1501":{"position":[[815,4],[989,4],[1175,4]]},"1557":{"position":[[165,4]]},"1561":{"position":[[111,5],[232,5],[505,5],[557,5],[832,5]]},"1580":{"position":[[558,4],[629,5],[707,5]]},"1587":{"position":[[55,5]]},"1605":{"position":[[62,4],[855,4],[1498,4],[1888,4]]},"1633":{"position":[[220,5]]},"1646":{"position":[[120,5],[614,4],[693,4],[963,5],[1073,4],[1152,4],[1333,4],[1412,4],[1593,5],[1674,5],[1962,4],[2041,4]]},"1648":{"position":[[66,6],[145,6],[1631,5]]},"1661":{"position":[[581,6],[689,4]]},"1665":{"position":[[382,5],[454,5],[611,5],[776,5],[948,5]]},"1686":{"position":[[261,4]]},"1688":{"position":[[111,5]]},"1694":{"position":[[971,4],[1674,4],[2208,4],[5759,4],[7854,4],[8913,4]]},"1696":{"position":[[503,5]]},"1700":{"position":[[147,5],[224,5],[301,5],[828,5],[875,5],[922,5]]},"1704":{"position":[[1572,5],[2248,5]]},"1711":{"position":[[1169,5]]},"1720":{"position":[[498,4],[812,4],[1522,4],[2336,4]]},"1725":{"position":[[119,5]]},"1740":{"position":[[303,5],[392,5],[449,5],[537,5]]},"1748":{"position":[[200,6]]},"1752":{"position":[[348,4],[627,4],[637,4],[737,4],[1015,6],[1120,6],[2163,4]]},"1754":{"position":[[340,4],[388,6],[458,4]]},"1756":{"position":[[34,5],[120,4],[166,5]]},"1766":{"position":[[424,4],[744,5],[1648,4]]},"1770":{"position":[[166,4]]},"1772":{"position":[[335,4],[572,5]]},"1774":{"position":[[392,4],[551,6],[568,5]]},"1776":{"position":[[65,4]]},"1790":{"position":[[213,4],[380,4]]},"1792":{"position":[[324,4]]},"1794":{"position":[[289,4]]},"1796":{"position":[[546,4],[689,4],[694,5],[798,4],[2215,4],[2238,4],[2268,4],[2520,4],[2525,4],[2761,4],[2797,4],[3643,5],[4084,4],[4176,4],[4660,4],[4767,4],[5263,4],[5370,4],[7124,4],[7207,4],[7588,5],[8175,4],[8259,4]]},"1798":{"position":[[649,4],[654,5],[945,4],[1743,4],[1748,4]]},"1811":{"position":[[9053,5]]},"1817":{"position":[[153,5],[169,5]]},"1823":{"position":[[583,5],[1738,4],[1970,4],[2923,4],[3307,4]]},"1825":{"position":[[1206,5],[2035,5],[2089,5]]},"1829":{"position":[[1846,4],[2121,6]]},"1833":{"position":[[3964,4]]},"1842":{"position":[[42,4],[876,4]]},"1854":{"position":[[2064,5],[2215,4]]},"1869":{"position":[[586,4],[1118,4]]},"1871":{"position":[[87,5]]},"1896":{"position":[[288,4],[963,4]]},"1923":{"position":[[558,4],[629,5],[707,5]]},"1930":{"position":[[55,5]]},"1964":{"position":[[220,5]]},"2037":{"position":[[887,4],[940,4],[1349,4]]},"2039":{"position":[[82,4]]},"2048":{"position":[[672,4],[2833,5],[2916,5],[3008,5],[3106,5],[3196,5],[3584,4]]},"2052":{"position":[[942,4]]},"2057":{"position":[[439,5]]},"2059":{"position":[[120,5],[508,4],[1723,5],[1863,5]]},"2065":{"position":[[106,4],[225,5]]},"2071":{"position":[[361,5]]},"2084":{"position":[[23,6],[84,4],[122,5],[183,5]]},"2086":{"position":[[222,4],[396,5]]},"2088":{"position":[[155,5]]},"2117":{"position":[[530,5],[790,5],[871,5],[961,5],[1141,5],[1400,5],[1540,5],[1697,5],[1738,5],[1821,5],[1913,5],[1994,5],[2060,5],[2099,5],[2152,5],[2245,5],[2298,5],[2372,5],[2411,5],[2450,5],[2487,5]]},"2119":{"position":[[1117,5]]},"2121":{"position":[[330,5],[471,5]]},"2123":{"position":[[35,5],[113,5],[252,5],[406,5],[481,5],[571,5],[789,5],[868,5],[884,4]]},"2126":{"position":[[20,6]]},"2146":{"position":[[662,4]]},"2155":{"position":[[1066,4]]},"2178":{"position":[[406,4],[915,4]]},"2184":{"position":[[1199,4],[1239,4],[1321,4],[1366,4],[1406,5],[1463,4],[1615,4],[1802,4],[1964,4]]},"2194":{"position":[[274,4]]},"2199":{"position":[[1048,5]]},"2207":{"position":[[1360,4]]},"2211":{"position":[[621,4],[892,5],[1157,4],[1442,4],[2163,4],[2379,5]]},"2219":{"position":[[844,4],[1105,4]]},"2240":{"position":[[1199,5]]},"2250":{"position":[[341,5],[885,4]]},"2252":{"position":[[865,4],[1789,4],[2330,4]]},"2254":{"position":[[173,4]]},"2276":{"position":[[190,5],[441,5]]},"2327":{"position":[[666,4]]},"2347":{"position":[[330,4],[882,5],[1044,4]]},"2355":{"position":[[806,4],[879,4],[2433,4],[2850,4]]},"2372":{"position":[[58,5]]},"2394":{"position":[[666,4]]},"2414":{"position":[[330,4],[882,5],[1044,4]]},"2422":{"position":[[806,4],[879,4],[2433,4],[2850,4]]},"2431":{"position":[[216,4],[482,4],[1110,5],[2764,4]]},"2439":{"position":[[223,5],[401,4],[548,5],[619,6]]},"2451":{"position":[[61,5],[146,5],[222,5]]},"2478":{"position":[[566,5]]},"2480":{"position":[[544,5],[1564,4]]},"2569":{"position":[[721,4]]},"2602":{"position":[[389,5],[402,4],[483,5],[496,4],[560,5],[573,4],[664,5],[677,4],[908,5],[1026,5],[1159,5],[1190,4],[1268,5],[1301,4],[1369,5],[1415,5],[1446,4],[1552,5],[1623,5],[1653,4],[1664,5],[1780,5],[1815,4],[1826,5]]},"2626":{"position":[[242,4],[484,4],[1200,9],[2019,4],[2490,4]]},"2655":{"position":[[472,4]]},"2703":{"position":[[467,4],[640,4]]},"2705":{"position":[[416,4],[529,4],[638,4]]},"2720":{"position":[[1364,4]]},"2732":{"position":[[325,5],[484,5],[546,5]]},"2740":{"position":[[250,4],[276,4],[903,5],[1016,5]]},"2743":{"position":[[381,5]]},"2756":{"position":[[1451,5],[1516,5],[1538,4],[2320,5],[2713,4]]},"2808":{"position":[[215,6]]},"2812":{"position":[[343,7]]},"2814":{"position":[[335,7]]},"2816":{"position":[[303,6]]},"2830":{"position":[[148,5]]},"2857":{"position":[[101,5]]},"2869":{"position":[[77,6]]},"2879":{"position":[[340,5]]},"2900":{"position":[[262,5]]},"2930":{"position":[[621,6]]},"2932":{"position":[[219,6]]},"2950":{"position":[[153,5],[169,5]]},"2956":{"position":[[583,5],[1738,4],[1970,4],[2923,4],[3307,4]]},"2958":{"position":[[1206,5],[2035,5],[2089,5]]},"2962":{"position":[[1846,4],[2121,6]]},"2966":{"position":[[3964,4]]},"2975":{"position":[[42,4],[876,4]]},"2987":{"position":[[2064,5],[2215,4]]},"3002":{"position":[[586,4],[1118,4]]},"3004":{"position":[[87,5]]},"3034":{"position":[[15,5],[46,5]]},"3036":{"position":[[3340,5],[3981,5],[4731,5],[4919,5],[7920,5],[8064,5],[8204,5],[8342,5],[8602,5],[8757,5],[8924,5],[9084,5],[9239,5],[9394,5],[10806,5],[11978,5],[13228,5]]},"3038":{"position":[[15,5],[44,5],[109,5],[124,5],[149,5]]},"3040":{"position":[[15,5],[77,5]]},"3071":{"position":[[96,6],[143,6]]},"3091":{"position":[[4,5]]},"3093":{"position":[[100,4]]},"3101":{"position":[[46,4]]},"3103":{"position":[[672,6]]},"3136":{"position":[[672,6],[880,6]]},"3206":{"position":[[137,7],[284,6]]},"3308":{"position":[[702,6],[830,6]]},"3367":{"position":[[241,4]]},"3381":{"position":[[1931,5],[1937,6],[2179,5],[2185,6]]},"3398":{"position":[[762,6]]},"3402":{"position":[[15,6],[66,6]]},"3410":{"position":[[182,6]]},"3470":{"position":[[781,6]]},"3527":{"position":[[903,4],[1238,7],[1265,4],[1735,4]]},"3533":{"position":[[854,5],[1020,7],[1037,4],[1153,4],[1186,6],[2747,4],[2778,6],[2831,6]]},"3592":{"position":[[1761,5]]},"3594":{"position":[[339,4],[356,4]]},"3596":{"position":[[521,4],[538,4]]},"3598":{"position":[[240,5],[871,5]]},"3600":{"position":[[83,4],[95,4],[122,6],[265,6]]},"3653":{"position":[[343,6],[404,5],[590,5]]},"3669":{"position":[[569,5]]},"3671":{"position":[[685,4]]},"3673":{"position":[[106,5],[373,5]]},"3679":{"position":[[619,5],[1288,6],[1452,6],[1495,6]]},"3681":{"position":[[55,6],[420,5],[1314,5]]},"3683":{"position":[[101,6],[270,4],[323,5]]},"3685":{"position":[[120,6],[340,6],[493,6]]},"3688":{"position":[[313,7]]},"3690":{"position":[[343,6],[404,5],[489,5],[1016,4],[1331,5],[1445,5]]},"3693":{"position":[[565,5],[706,5],[772,5],[840,6]]},"3695":{"position":[[332,5]]},"3704":{"position":[[68,4],[95,4],[216,5],[307,4],[493,5],[1249,5],[1501,6]]},"3706":{"position":[[341,6],[453,4],[696,5],[811,5],[1461,5],[1497,5]]},"3710":{"position":[[582,5]]},"3712":{"position":[[1117,4]]},"3718":{"position":[[55,6],[420,5],[1341,5]]},"3722":{"position":[[188,6],[362,5],[418,6],[517,5],[833,5],[1368,5],[1525,5]]},"3724":{"position":[[517,5]]},"3740":{"position":[[19,4],[63,6]]},"3742":{"position":[[105,6],[148,4],[226,6],[409,5],[582,5],[643,5]]},"3744":{"position":[[137,5],[456,4],[795,4],[1418,4],[1730,4],[2224,4],[2584,4],[2850,4]]},"3747":{"position":[[85,4],[240,4],[479,5]]},"3751":{"position":[[18,5],[153,5]]},"3761":{"position":[[187,4]]},"3775":{"position":[[313,7]]},"3777":{"position":[[343,6],[404,5],[590,5],[1117,4],[1432,5],[1546,5]]},"3780":{"position":[[565,5],[706,5],[772,5],[840,6]]},"3782":{"position":[[332,5]]},"3793":{"position":[[558,5],[781,5],[1514,6],[1714,6],[1757,6]]},"3795":{"position":[[101,6],[270,4],[323,5],[419,5],[554,5],[764,5]]},"3799":{"position":[[341,6],[453,4],[696,5],[811,5],[1458,5],[1494,5]]},"3803":{"position":[[569,5]]},"3805":{"position":[[792,4]]},"3811":{"position":[[55,6],[420,5],[1318,5]]},"3815":{"position":[[52,6],[226,5],[282,6],[381,5],[831,5],[1366,5],[1523,5]]},"3817":{"position":[[517,5]]},"3824":{"position":[[33,5],[219,5],[296,5]]},"3829":{"position":[[116,4],[197,4],[772,5],[1196,4],[3063,4],[4081,5],[4441,4],[4682,4],[4847,4]]},"3864":{"position":[[263,6]]},"3872":{"position":[[29,4],[41,4],[416,4],[431,4],[506,4],[521,4],[592,4]]},"3874":{"position":[[29,4],[41,4],[148,4],[557,4],[694,4],[799,4]]},"3876":{"position":[[10,5],[150,5],[398,5],[520,5],[651,5]]},"3879":{"position":[[231,4],[287,5]]},"3888":{"position":[[228,5],[274,6]]},"3894":{"position":[[135,4],[167,4],[183,4],[265,7],[485,6],[1161,5],[1184,4],[1299,5],[1318,6],[1398,6],[1442,5],[1619,4],[1782,4],[2071,4],[2244,6],[2280,5],[2348,7]]},"3898":{"position":[[12,4]]},"3900":{"position":[[12,4]]},"3902":{"position":[[244,5],[341,5]]},"3906":{"position":[[567,4],[686,7]]},"3910":{"position":[[59,6],[189,5]]},"3918":{"position":[[602,4],[651,4],[668,5],[762,4],[779,4]]},"3923":{"position":[[27,6]]},"3928":{"position":[[5619,6],[5744,4],[5790,7]]},"3930":{"position":[[87,6]]},"3932":{"position":[[1138,6]]},"3936":{"position":[[61,6],[212,6]]},"3945":{"position":[[63,6]]},"3947":{"position":[[631,5],[793,4],[962,4]]},"3951":{"position":[[125,4]]},"3990":{"position":[[1324,4],[1359,5]]},"4017":{"position":[[191,4],[461,5]]},"4023":{"position":[[252,4]]},"4026":{"position":[[949,4]]},"4030":{"position":[[896,4]]},"4073":{"position":[[467,5]]},"4096":{"position":[[360,4],[461,4],[566,4]]},"4102":{"position":[[515,5]]},"4124":{"position":[[2405,5]]},"4146":{"position":[[532,5]]},"4155":{"position":[[409,4],[510,4],[615,4]]},"4230":{"position":[[903,5]]},"4306":{"position":[[629,4]]},"4374":{"position":[[226,4]]},"4385":{"position":[[115,4]]},"4399":{"position":[[163,4]]},"4485":{"position":[[2617,4]]},"4535":{"position":[[3194,4]]},"4539":{"position":[[1974,5],[3166,4]]},"4541":{"position":[[1345,4]]},"4547":{"position":[[1091,4]]},"4578":{"position":[[204,5]]},"4616":{"position":[[7,5]]},"4632":{"position":[[11,6],[165,5],[2467,6],[2596,5]]},"4637":{"position":[[106,5]]},"4639":{"position":[[9,6]]},"4643":{"position":[[15,7],[27,6],[195,4],[2382,7],[2998,6]]},"4667":{"position":[[6655,4],[6914,4],[7192,4]]},"4691":{"position":[[143,6]]},"4693":{"position":[[136,5]]},"4697":{"position":[[18,5]]},"4707":{"position":[[22,5]]},"4773":{"position":[[184,6]]},"4826":{"position":[[1146,6],[3572,6]]},"4849":{"position":[[792,5],[1476,4],[1553,5]]},"4853":{"position":[[126,5],[423,5]]},"4872":{"position":[[71,5],[165,4]]},"4877":{"position":[[441,5],[579,5],[638,5],[829,5],[977,5],[1033,5],[1216,5]]}}}],["name/sc",{"_index":8700,"t":{"2602":{"position":[[2158,8]]}}}],["name/ten",{"_index":8699,"t":{"2602":{"position":[[2108,11]]}}}],["name:ten",{"_index":8690,"t":{"2602":{"position":[[1530,11]]}}}],["name=bench",{"_index":6636,"t":{"1650":{"position":[[403,10],[732,10]]},"1975":{"position":[[403,10],[732,10]]}}}],["name>.servic",{"_index":6606,"t":{"1648":{"position":[[394,13],[746,13]]}}}],["name>_dev_mod",{"_index":8029,"t":{"2211":{"position":[[1956,14]]}}}],["name>_dev_repos_pul",{"_index":8032,"t":{"2211":{"position":[[2234,20]]}}}],["name>_git_repositori",{"_index":8030,"t":{"2211":{"position":[[2019,20]]}}}],["name>_source_vers",{"_index":8031,"t":{"2211":{"position":[[2121,20]]}}}],["name_based_external_front",{"_index":5431,"t":{"1297":{"position":[[1134,25],[1656,25]]}}}],["name_of_the_test(context",{"_index":9025,"t":{"2738":{"position":[[256,26]]}}}],["name_schem",{"_index":10890,"t":{"3874":{"position":[[88,11],[603,12],[740,12],[845,12]]},"3876":{"position":[[176,12]]},"3918":{"position":[[619,11],[730,11]]}}}],["name_serv",{"_index":5068,"t":{"1222":{"position":[[1347,11]]},"1230":{"position":[[907,11]]}}}],["names.pi",{"_index":1977,"t":{"303":{"position":[[713,9]]}}}],["nameserv",{"_index":2779,"t":{"557":{"position":[[4031,11]]},"1230":{"position":[[919,11],[940,10],[1035,11]]},"1268":{"position":[[285,12],[525,12]]},"4872":{"position":[[357,10],[533,10],[586,10],[914,10],[950,10],[1025,10]]}}}],["namespac",{"_index":2360,"t":{"434":{"position":[[925,9],[1175,9]]},"465":{"position":[[208,10]]},"475":{"position":[[770,9]]},"493":{"position":[[573,9],[823,9],[950,9]]},"518":{"position":[[966,10]]},"555":{"position":[[67,10]]},"584":{"position":[[86,9],[535,9]]},"586":{"position":[[840,10],[1286,10]]},"588":{"position":[[934,10]]},"590":{"position":[[51,9]]},"705":{"position":[[117,9]]},"708":{"position":[[227,9],[385,9],[550,9],[839,9],[921,10],[1055,9],[1249,10]]},"739":{"position":[[370,9],[665,10],[779,9],[1531,9],[1610,9]]},"1191":{"position":[[1355,9]]},"1391":{"position":[[1939,10],[2140,10],[2577,10]]},"1397":{"position":[[238,9]]},"1407":{"position":[[1196,9]]},"1429":{"position":[[117,9],[181,10]]},"1431":{"position":[[15,9],[169,10],[384,9]]},"2590":{"position":[[324,11]]},"2600":{"position":[[151,10],[244,10],[434,9]]},"2602":{"position":[[369,9],[531,10],[694,10],[1172,10],[1283,10],[1428,10],[1635,10],[1797,10]]},"2668":{"position":[[183,10]]},"2720":{"position":[[1249,9],[1267,9]]},"2730":{"position":[[162,9],[195,9]]},"2863":{"position":[[257,9]]},"4220":{"position":[[1831,10]]},"4420":{"position":[[1166,11]]},"4543":{"position":[[1173,9],[1331,9]]},"4547":{"position":[[3871,9]]},"4580":{"position":[[285,10],[761,11],[800,10],[880,10],[910,9],[1087,11],[1252,10],[1397,9],[1487,10],[2246,10]]},"4849":{"position":[[543,11],[1374,10]]},"4851":{"position":[[9,9],[55,9],[70,9]]},"4853":{"position":[[513,10],[571,9]]},"4855":{"position":[[166,9]]},"4857":{"position":[[184,9],[377,9]]},"4872":{"position":[[177,9]]},"4875":{"position":[[257,9],[289,9]]},"4879":{"position":[[383,9],[416,9]]},"4881":{"position":[[187,9],[217,9]]}}}],["namev1",{"_index":10637,"t":{"3722":{"position":[[597,9]]},"3815":{"position":[[461,9]]}}}],["namev1=$(echo",{"_index":10640,"t":{"3722":{"position":[[694,13]]},"3815":{"position":[[558,13]]}}}],["namev2",{"_index":10641,"t":{"3722":{"position":[[708,9]]},"3815":{"position":[[572,9]]}}}],["namev2=$(echo",{"_index":10636,"t":{"3722":{"position":[[583,13]]},"3815":{"position":[[447,13]]}}}],["naming.md",{"_index":10181,"t":{"3527":{"position":[[1298,10]]},"3533":{"position":[[1083,10],[1133,10]]}}}],["napkin",{"_index":1677,"t":{"237":{"position":[[352,8]]}}}],["napl",{"_index":10381,"t":{"3671":{"position":[[349,8]]},"3712":{"position":[[661,8]]},"3805":{"position":[[440,8]]}}}],["nat",{"_index":9983,"t":{"3352":{"position":[[2921,3]]}}}],["nation",{"_index":1431,"t":{"199":{"position":[[449,8]]}}}],["nativ",{"_index":2532,"t":{"500":{"position":[[170,6]]},"1064":{"position":[[224,6],[465,6]]},"2584":{"position":[[1515,6]]},"2586":{"position":[[1125,6]]},"3292":{"position":[[640,6]]},"3923":{"position":[[367,6],[580,6],[652,7]]},"3986":{"position":[[53,6]]},"4023":{"position":[[181,8]]},"4146":{"position":[[2308,6]]},"4224":{"position":[[937,6]]},"4230":{"position":[[799,6]]},"4234":{"position":[[284,6]]},"4283":{"position":[[1070,8]]},"4302":{"position":[[831,6],[2137,8],[2774,6]]},"4304":{"position":[[1336,6]]},"4313":{"position":[[456,6]]},"4327":{"position":[[121,6],[219,6],[524,6]]},"4333":{"position":[[668,6]]},"4335":{"position":[[233,6]]},"4556":{"position":[[91,6],[200,6]]},"4593":{"position":[[2603,7]]},"4604":{"position":[[515,6]]},"4618":{"position":[[88,9],[679,6]]},"4623":{"position":[[99,8],[381,8]]},"4665":{"position":[[582,8],[687,6]]},"4839":{"position":[[159,6]]}}}],["natur",{"_index":8342,"t":{"2293":{"position":[[201,6]]},"2307":{"position":[[201,6]]},"3582":{"position":[[1397,10]]},"3698":{"position":[[84,7]]},"3785":{"position":[[84,7]]},"4104":{"position":[[862,7]]},"4107":{"position":[[765,7]]},"4109":{"position":[[5440,6]]},"4135":{"position":[[50,7]]},"4137":{"position":[[180,7]]},"4182":{"position":[[94,7]]},"4215":{"position":[[390,7]]},"4222":{"position":[[4201,6]]},"4226":{"position":[[2378,7]]},"4294":{"position":[[108,6]]},"4302":{"position":[[3404,6]]},"4310":{"position":[[1525,7]]},"4516":{"position":[[581,6]]},"4826":{"position":[[407,9]]}}}],["navig",{"_index":459,"t":{"59":{"position":[[118,8]]},"1491":{"position":[[0,8]]},"1493":{"position":[[0,8]]},"2478":{"position":[[456,8]]},"2626":{"position":[[1219,8]]},"2873":{"position":[[390,10]]},"3563":{"position":[[595,10]]},"3569":{"position":[[32,10]]},"3571":{"position":[[32,10]]}}}],["nb",{"_index":7017,"t":{"1704":{"position":[[68,2],[481,2],[1453,2]]}}}],["nbctl",{"_index":7026,"t":{"1704":{"position":[[525,5]]}}}],["nbd",{"_index":5992,"t":{"1405":{"position":[[711,3],[799,4],[884,3]]}}}],["nbde",{"_index":9759,"t":{"3116":{"position":[[616,6]]}}}],["nc",{"_index":4955,"t":{"1195":{"position":[[150,2]]}}}],["ncdu",{"_index":4536,"t":{"1147":{"position":[[202,4]]}}}],["near",{"_index":8423,"t":{"2382":{"position":[[177,4]]},"3346":{"position":[[188,5]]},"3390":{"position":[[586,4],[674,4]]},"3398":{"position":[[593,4],[681,4]]},"3468":{"position":[[549,4],[637,4]]},"3470":{"position":[[566,4],[654,4]]},"3502":{"position":[[581,4],[669,4]]},"4148":{"position":[[91,4]]},"4826":{"position":[[673,4],[761,4]]}}}],["nearli",{"_index":835,"t":{"145":{"position":[[7,6]]}}}],["neccesari",{"_index":8500,"t":{"2480":{"position":[[87,9]]}}}],["necess",{"_index":8358,"t":{"2327":{"position":[[838,9]]},"2337":{"position":[[429,9]]},"2339":{"position":[[1257,9]]},"2394":{"position":[[838,9]]},"2404":{"position":[[429,9]]},"2406":{"position":[[1257,9]]},"3843":{"position":[[285,10]]},"3932":{"position":[[624,9]]},"4157":{"position":[[920,9]]},"4291":{"position":[[2789,10]]},"4353":{"position":[[173,9]]},"4502":{"position":[[33,9]]},"4587":{"position":[[664,9],[1129,9]]},"4643":{"position":[[3315,9]]}}}],["necessari",{"_index":882,"t":{"153":{"position":[[314,10]]},"218":{"position":[[158,9]]},"220":{"position":[[415,10]]},"237":{"position":[[158,9]]},"239":{"position":[[177,10]]},"241":{"position":[[169,10],[472,9]]},"243":{"position":[[219,9]]},"245":{"position":[[203,10],[270,10]]},"275":{"position":[[274,9]]},"280":{"position":[[1668,9]]},"293":{"position":[[716,9]]},"368":{"position":[[1247,9]]},"391":{"position":[[334,9]]},"401":{"position":[[1237,9]]},"417":{"position":[[1171,10]]},"425":{"position":[[55,9]]},"434":{"position":[[558,10]]},"543":{"position":[[331,9],[479,9],[2437,9]]},"557":{"position":[[178,9]]},"572":{"position":[[282,9]]},"588":{"position":[[812,10]]},"597":{"position":[[417,10]]},"618":{"position":[[54,9]]},"641":{"position":[[193,9],[399,9]]},"655":{"position":[[142,9]]},"666":{"position":[[193,9],[399,9]]},"668":{"position":[[279,9],[1145,9]]},"673":{"position":[[142,9]]},"1028":{"position":[[145,9]]},"1030":{"position":[[205,9]]},"1032":{"position":[[64,9]]},"1109":{"position":[[65,9]]},"1111":{"position":[[70,9]]},"1167":{"position":[[264,9],[359,9]]},"1177":{"position":[[1788,9],[5394,9]]},"1222":{"position":[[70,9]]},"1232":{"position":[[359,9]]},"1248":{"position":[[920,9]]},"1257":{"position":[[95,10],[1017,10]]},"1292":{"position":[[16,9]]},"1387":{"position":[[282,9]]},"1455":{"position":[[1473,9]]},"1457":{"position":[[2593,9],[2742,9]]},"1466":{"position":[[3119,9]]},"1474":{"position":[[142,10]]},"1476":{"position":[[142,10]]},"1478":{"position":[[116,9],[234,9]]},"1480":{"position":[[371,10]]},"1484":{"position":[[282,9]]},"1501":{"position":[[1289,10]]},"1503":{"position":[[84,9],[1104,9],[1531,9]]},"1509":{"position":[[167,9]]},"1515":{"position":[[145,9]]},"1523":{"position":[[1093,9],[1181,10]]},"1525":{"position":[[164,9],[1229,9]]},"1593":{"position":[[993,9]]},"1619":{"position":[[848,10]]},"1688":{"position":[[441,9]]},"1936":{"position":[[993,9]]},"1950":{"position":[[848,10]]},"1979":{"position":[[282,9]]},"2029":{"position":[[233,9]]},"2037":{"position":[[98,9]]},"2055":{"position":[[758,10]]},"2059":{"position":[[215,9]]},"2074":{"position":[[136,9]]},"2076":{"position":[[291,10]]},"2148":{"position":[[282,9]]},"2155":{"position":[[16,9]]},"2167":{"position":[[24,9]]},"2171":{"position":[[95,10],[1157,10],[2362,10]]},"2184":{"position":[[1752,9],[2824,9],[3068,9],[5656,9]]},"2192":{"position":[[138,10]]},"2199":{"position":[[307,9],[740,9]]},"2231":{"position":[[829,9],[917,10],[1180,9],[1268,10]]},"2261":{"position":[[127,9]]},"2287":{"position":[[980,9]]},"2291":{"position":[[167,9]]},"2301":{"position":[[980,9]]},"2305":{"position":[[167,9]]},"2355":{"position":[[1867,9]]},"2422":{"position":[[1867,9]]},"2478":{"position":[[58,9],[528,9]]},"2512":{"position":[[313,10]]},"2531":{"position":[[269,9],[1258,10]]},"2567":{"position":[[106,9]]},"2569":{"position":[[117,9]]},"2614":{"position":[[365,9]]},"2716":{"position":[[1796,9]]},"2725":{"position":[[634,9]]},"3223":{"position":[[292,9]]},"3378":{"position":[[742,9]]},"3381":{"position":[[259,9],[806,9],[1125,9],[1427,9]]},"3525":{"position":[[234,9]]},"3529":{"position":[[240,10]]},"3537":{"position":[[627,10]]},"3539":{"position":[[335,9]]},"3571":{"position":[[894,9]]},"3575":{"position":[[253,10]]},"3853":{"position":[[77,9]]},"3984":{"position":[[1268,9]]},"4045":{"position":[[2028,9]]},"4122":{"position":[[166,10]]},"4157":{"position":[[96,9]]},"4161":{"position":[[70,9]]},"4182":{"position":[[316,9]]},"4189":{"position":[[577,9]]},"4226":{"position":[[812,10]]},"4228":{"position":[[1702,9]]},"4230":{"position":[[1334,9],[1858,9],[4014,9]]},"4240":{"position":[[204,10]]},"4268":{"position":[[808,9]]},"4289":{"position":[[386,9]]},"4291":{"position":[[2379,9]]},"4310":{"position":[[2482,9]]},"4313":{"position":[[1394,9]]},"4446":{"position":[[983,9]]},"4457":{"position":[[983,9]]},"4481":{"position":[[332,9],[808,9]]},"4489":{"position":[[762,10]]},"4504":{"position":[[278,9]]},"4516":{"position":[[327,9]]},"4522":{"position":[[1410,9]]},"4547":{"position":[[595,9]]},"4620":{"position":[[305,9]]},"4643":{"position":[[1627,9],[3428,9]]},"4765":{"position":[[8,9]]}}}],["necessarili",{"_index":1278,"t":{"181":{"position":[[1321,11]]},"2276":{"position":[[550,11]]},"3665":{"position":[[450,11]]},"3702":{"position":[[522,11]]},"3789":{"position":[[522,11]]},"3984":{"position":[[1138,11]]},"4376":{"position":[[928,11]]},"4479":{"position":[[1714,11]]},"4525":{"position":[[571,11]]},"4674":{"position":[[239,11]]}}}],["necessit",{"_index":2636,"t":{"541":{"position":[[1755,12]]},"549":{"position":[[1206,12]]},"3573":{"position":[[599,12]]},"4146":{"position":[[2110,13]]},"4506":{"position":[[328,13]]}}}],["need",{"_index":192,"t":{"26":{"position":[[222,6]]},"28":{"position":[[61,6]]},"31":{"position":[[81,6]]},"33":{"position":[[61,6]]},"47":{"position":[[24,5]]},"54":{"position":[[24,5]]},"76":{"position":[[134,5]]},"78":{"position":[[604,4]]},"84":{"position":[[123,4]]},"103":{"position":[[29,4]]},"105":{"position":[[31,4]]},"130":{"position":[[484,4],[755,4]]},"151":{"position":[[38,6],[93,5]]},"153":{"position":[[7,4],[99,7]]},"171":{"position":[[918,4],[1058,5],[1107,6]]},"173":{"position":[[1016,5]]},"177":{"position":[[38,5]]},"179":{"position":[[179,5]]},"181":{"position":[[755,4],[1058,6],[2174,6],[2199,4],[2569,4],[2901,4]]},"216":{"position":[[534,4]]},"220":{"position":[[233,4],[340,5]]},"253":{"position":[[373,4]]},"264":{"position":[[46,4]]},"271":{"position":[[168,4],[523,4]]},"273":{"position":[[48,4]]},"323":{"position":[[356,5],[1444,5]]},"351":{"position":[[32,4]]},"354":{"position":[[228,4]]},"358":{"position":[[207,4],[420,4]]},"364":{"position":[[296,4],[609,4],[684,5]]},"368":{"position":[[825,5],[972,4],[1290,4],[1424,4],[1601,4],[2336,5],[2808,5],[3343,5]]},"370":{"position":[[243,5]]},"378":{"position":[[751,6]]},"401":{"position":[[752,6]]},"407":{"position":[[30,6]]},"409":{"position":[[11,4],[74,5],[119,4]]},"411":{"position":[[124,4]]},"413":{"position":[[19,4]]},"417":{"position":[[2060,7]]},"423":{"position":[[353,5],[963,4]]},"427":{"position":[[487,6]]},"430":{"position":[[50,4],[117,4]]},"432":{"position":[[108,5]]},"438":{"position":[[345,4]]},"452":{"position":[[178,7]]},"454":{"position":[[26,6],[202,7]]},"479":{"position":[[349,4],[477,4],[1368,4]]},"487":{"position":[[109,4]]},"504":{"position":[[90,4]]},"506":{"position":[[108,5]]},"514":{"position":[[702,4],[1712,4]]},"541":{"position":[[1630,5]]},"543":{"position":[[1395,5]]},"557":{"position":[[1519,6],[4107,4]]},"588":{"position":[[119,4],[237,4]]},"602":{"position":[[343,4]]},"606":{"position":[[81,7]]},"641":{"position":[[117,5]]},"653":{"position":[[187,4]]},"661":{"position":[[69,5]]},"666":{"position":[[117,5]]},"668":{"position":[[804,6],[1188,7]]},"671":{"position":[[986,4]]},"690":{"position":[[47,5]]},"692":{"position":[[709,4]]},"705":{"position":[[1046,4]]},"708":{"position":[[128,4]]},"715":{"position":[[764,4]]},"747":{"position":[[429,4]]},"755":{"position":[[550,6]]},"790":{"position":[[40,5]]},"800":{"position":[[70,6]]},"910":{"position":[[556,5]]},"912":{"position":[[7016,4],[7510,4]]},"924":{"position":[[147,6]]},"928":{"position":[[977,6]]},"932":{"position":[[3836,4]]},"934":{"position":[[3,4],[807,4],[1147,4],[2095,4]]},"936":{"position":[[96,4],[635,4]]},"942":{"position":[[674,4],[3493,4]]},"949":{"position":[[448,5],[547,4]]},"955":{"position":[[37,4]]},"957":{"position":[[230,6]]},"959":{"position":[[4,4]]},"961":{"position":[[847,5]]},"963":{"position":[[535,5],[2105,4]]},"973":{"position":[[236,4]]},"978":{"position":[[1994,4]]},"980":{"position":[[332,4],[493,5],[665,5]]},"1042":{"position":[[630,5]]},"1050":{"position":[[41,4],[501,4]]},"1061":{"position":[[451,5]]},"1226":{"position":[[131,5]]},"1246":{"position":[[49,7]]},"1259":{"position":[[653,5],[1078,6]]},"1266":{"position":[[71,5]]},"1301":{"position":[[1538,5],[3451,5]]},"1324":{"position":[[6395,4],[6496,6],[6781,6],[7034,6]]},"1352":{"position":[[50,4]]},"1373":{"position":[[25,5]]},"1375":{"position":[[631,4]]},"1391":{"position":[[875,5],[1809,5],[2113,5],[2306,4],[2435,5],[3272,4],[3563,4]]},"1397":{"position":[[285,5]]},"1407":{"position":[[1176,5]]},"1443":{"position":[[570,4],[622,4]]},"1462":{"position":[[278,4]]},"1464":{"position":[[652,6]]},"1466":{"position":[[1210,6],[3055,4]]},"1472":{"position":[[199,4],[2791,4]]},"1484":{"position":[[465,5]]},"1497":{"position":[[512,6]]},"1503":{"position":[[2582,4]]},"1646":{"position":[[169,4]]},"1648":{"position":[[17,4]]},"1794":{"position":[[556,5]]},"1796":{"position":[[7016,4],[7510,4]]},"1815":{"position":[[147,6]]},"1819":{"position":[[977,6]]},"1823":{"position":[[3836,4]]},"1825":{"position":[[3,4],[807,4],[1147,4],[2095,4]]},"1827":{"position":[[96,4],[635,4]]},"1833":{"position":[[674,4],[3493,4]]},"1840":{"position":[[448,5],[547,4]]},"1846":{"position":[[37,4]]},"1848":{"position":[[230,6]]},"1850":{"position":[[4,4]]},"1852":{"position":[[847,5]]},"1854":{"position":[[535,5],[2105,4]]},"1864":{"position":[[236,4]]},"1869":{"position":[[1994,4]]},"1871":{"position":[[332,4],[493,5],[665,5]]},"1994":{"position":[[121,7]]},"2005":{"position":[[213,5]]},"2025":{"position":[[120,6]]},"2032":{"position":[[999,6]]},"2052":{"position":[[89,4]]},"2055":{"position":[[74,6],[811,4],[865,4]]},"2065":{"position":[[592,6],[844,5],[1287,5],[1606,5],[1927,5],[2258,5],[2580,5],[2902,5],[3223,5],[3539,5]]},"2086":{"position":[[38,6],[93,5]]},"2088":{"position":[[7,4],[92,7]]},"2119":{"position":[[6,4],[541,4],[580,5]]},"2121":{"position":[[81,4]]},"2128":{"position":[[231,5]]},"2184":{"position":[[6650,7]]},"2196":{"position":[[1615,6]]},"2240":{"position":[[167,4],[1438,5]]},"2242":{"position":[[279,4]]},"2246":{"position":[[316,4]]},"2250":{"position":[[17,4]]},"2252":{"position":[[31,4],[440,4],[611,6],[1459,4],[2418,4]]},"2256":{"position":[[706,4]]},"2258":{"position":[[64,4],[127,5]]},"2274":{"position":[[37,4]]},"2276":{"position":[[138,4],[2029,4]]},"2279":{"position":[[564,4]]},"2281":{"position":[[4,4]]},"2285":{"position":[[42,4],[482,6],[795,6],[1131,4]]},"2287":{"position":[[106,4],[217,6],[1017,7]]},"2295":{"position":[[153,4]]},"2299":{"position":[[42,4],[482,6],[795,6],[1131,4]]},"2301":{"position":[[106,4],[217,6],[1017,7]]},"2309":{"position":[[153,4]]},"2329":{"position":[[544,6]]},"2341":{"position":[[515,5]]},"2353":{"position":[[232,4]]},"2355":{"position":[[1665,5]]},"2360":{"position":[[239,5]]},"2368":{"position":[[156,5]]},"2396":{"position":[[544,6]]},"2408":{"position":[[515,5]]},"2420":{"position":[[232,4]]},"2422":{"position":[[1665,5]]},"2427":{"position":[[239,5]]},"2431":{"position":[[195,4],[3126,4]]},"2433":{"position":[[179,6],[1205,6]]},"2443":{"position":[[822,4]]},"2445":{"position":[[74,5]]},"2478":{"position":[[1209,6],[1917,5],[2198,7]]},"2482":{"position":[[209,6]]},"2487":{"position":[[726,6]]},"2508":{"position":[[365,7]]},"2525":{"position":[[191,4]]},"2553":{"position":[[365,6]]},"2567":{"position":[[1571,5]]},"2614":{"position":[[406,6]]},"2622":{"position":[[142,5]]},"2628":{"position":[[250,6],[689,4],[870,5]]},"2678":{"position":[[175,6]]},"2692":{"position":[[1620,6]]},"2712":{"position":[[739,4]]},"2714":{"position":[[650,6],[1613,4]]},"2716":{"position":[[2087,6]]},"2725":{"position":[[776,4],[839,4]]},"2730":{"position":[[28,4]]},"2749":{"position":[[200,6]]},"2822":{"position":[[104,4]]},"2826":{"position":[[4,5],[204,5]]},"2839":{"position":[[211,4]]},"2871":{"position":[[55,7]]},"2883":{"position":[[4,6]]},"2887":{"position":[[16,5],[205,4]]},"2889":{"position":[[419,5]]},"2898":{"position":[[96,7],[379,5]]},"2916":{"position":[[606,4]]},"2940":{"position":[[505,6]]},"2948":{"position":[[147,6]]},"2952":{"position":[[977,6]]},"2956":{"position":[[3836,4]]},"2958":{"position":[[3,4],[807,4],[1147,4],[2095,4]]},"2960":{"position":[[96,4],[635,4]]},"2966":{"position":[[674,4],[3493,4]]},"2973":{"position":[[448,5],[547,4]]},"2979":{"position":[[37,4]]},"2981":{"position":[[230,6]]},"2983":{"position":[[4,4]]},"2985":{"position":[[847,5]]},"2987":{"position":[[535,5],[2105,4]]},"2997":{"position":[[236,4]]},"3002":{"position":[[1994,4]]},"3004":{"position":[[332,4],[493,5],[665,5]]},"3050":{"position":[[115,4],[167,5]]},"3055":{"position":[[82,4],[122,6]]},"3071":{"position":[[283,4],[541,4]]},"3073":{"position":[[555,4]]},"3091":{"position":[[391,4]]},"3121":{"position":[[715,5]]},"3124":{"position":[[188,6]]},"3132":{"position":[[26,4]]},"3134":{"position":[[156,4]]},"3166":{"position":[[138,6]]},"3168":{"position":[[490,5]]},"3290":{"position":[[856,6]]},"3294":{"position":[[982,4]]},"3296":{"position":[[1347,6]]},"3298":{"position":[[388,6]]},"3310":{"position":[[277,4]]},"3313":{"position":[[712,4]]},"3348":{"position":[[803,5]]},"3375":{"position":[[281,4]]},"3378":{"position":[[4,4]]},"3381":{"position":[[667,4],[1672,4]]},"3384":{"position":[[665,6]]},"3460":{"position":[[146,4],[283,4]]},"3516":{"position":[[36,4],[421,4]]},"3525":{"position":[[387,5]]},"3533":{"position":[[632,4]]},"3546":{"position":[[171,4]]},"3571":{"position":[[666,4],[1046,6],[1626,6]]},"3573":{"position":[[444,6]]},"3598":{"position":[[1127,4]]},"3602":{"position":[[855,5]]},"3606":{"position":[[940,4]]},"3611":{"position":[[79,4]]},"3613":{"position":[[85,4]]},"3638":{"position":[[196,5]]},"3653":{"position":[[37,4],[522,4]]},"3665":{"position":[[540,4],[1629,4]]},"3673":{"position":[[897,4],[1229,4]]},"3681":{"position":[[209,4],[1258,4],[1354,6],[1446,4]]},"3690":{"position":[[37,4],[1410,4]]},"3698":{"position":[[41,4]]},"3702":{"position":[[612,4],[1976,4]]},"3706":{"position":[[562,4],[1293,4]]},"3714":{"position":[[928,4],[1830,5]]},"3716":{"position":[[153,4]]},"3718":{"position":[[209,4],[1285,4],[1381,6],[1473,4]]},"3722":{"position":[[987,5],[1499,4]]},"3731":{"position":[[863,4]]},"3738":{"position":[[124,6]]},"3744":{"position":[[1281,4],[2103,4]]},"3777":{"position":[[37,4],[522,4],[1511,4]]},"3785":{"position":[[41,4],[1228,6]]},"3789":{"position":[[612,4],[1835,4]]},"3799":{"position":[[562,4],[1293,4]]},"3807":{"position":[[550,4]]},"3809":{"position":[[130,4]]},"3811":{"position":[[209,4],[1262,4],[1358,6],[1450,4]]},"3815":{"position":[[985,5],[1497,4]]},"3831":{"position":[[24,5],[236,5]]},"3833":{"position":[[28,5],[262,5]]},"3835":{"position":[[1005,4]]},"3843":{"position":[[12,4]]},"3853":{"position":[[12,4]]},"3892":{"position":[[37,4],[407,4]]},"3925":{"position":[[888,6]]},"3928":{"position":[[1224,5],[4649,4],[4976,4]]},"3932":{"position":[[235,5],[864,4]]},"3938":{"position":[[35,5]]},"3947":{"position":[[551,4],[2396,5],[3314,4]]},"3949":{"position":[[173,6]]},"3951":{"position":[[77,6],[446,5]]},"3960":{"position":[[793,7]]},"3968":{"position":[[820,7],[1026,7],[1874,4]]},"3984":{"position":[[1251,6],[1461,5]]},"3986":{"position":[[464,5]]},"3994":{"position":[[281,5]]},"4028":{"position":[[383,4]]},"4045":{"position":[[1311,4],[1457,7]]},"4060":{"position":[[218,5],[870,4],[1042,6]]},"4068":{"position":[[128,4]]},"4081":{"position":[[414,5],[1242,5],[1949,7]]},"4094":{"position":[[678,6]]},"4096":{"position":[[724,6]]},"4100":{"position":[[621,4]]},"4104":{"position":[[586,6],[714,7]]},"4109":{"position":[[484,5],[557,5],[4666,6],[4877,5]]},"4144":{"position":[[518,5],[685,5]]},"4146":{"position":[[2188,5]]},"4150":{"position":[[206,7]]},"4153":{"position":[[418,4]]},"4161":{"position":[[771,5]]},"4163":{"position":[[843,4],[1132,4],[1210,5],[1433,4],[2776,4],[4443,4]]},"4165":{"position":[[35,4]]},"4171":{"position":[[337,5]]},"4178":{"position":[[990,5]]},"4182":{"position":[[204,5],[362,6]]},"4198":{"position":[[284,4]]},"4202":{"position":[[691,6]]},"4226":{"position":[[1456,4]]},"4230":{"position":[[4763,6]]},"4240":{"position":[[137,4]]},"4253":{"position":[[37,5]]},"4257":{"position":[[2478,4],[2793,4],[3818,4],[5050,4],[5232,6],[5480,4],[5638,4]]},"4275":{"position":[[682,4],[1048,4]]},"4283":{"position":[[339,4],[1113,6]]},"4294":{"position":[[338,4]]},"4302":{"position":[[1796,5],[2439,4]]},"4310":{"position":[[1727,5]]},"4313":{"position":[[1064,4],[1244,4]]},"4340":{"position":[[41,4]]},"4353":{"position":[[991,4]]},"4362":{"position":[[268,4]]},"4385":{"position":[[637,5]]},"4414":{"position":[[596,5]]},"4431":{"position":[[1481,4],[1985,4]]},"4433":{"position":[[534,4],[1771,5]]},"4446":{"position":[[472,5]]},"4457":{"position":[[472,5]]},"4477":{"position":[[70,4]]},"4479":{"position":[[1455,4]]},"4481":{"position":[[107,5],[296,5]]},"4483":{"position":[[449,5]]},"4485":{"position":[[282,4],[2076,4],[2554,5],[2596,4]]},"4489":{"position":[[416,5]]},"4502":{"position":[[363,4]]},"4504":{"position":[[224,7]]},"4518":{"position":[[363,4]]},"4522":{"position":[[46,6],[424,4],[824,4]]},"4525":{"position":[[158,5],[391,4]]},"4529":{"position":[[798,4]]},"4535":{"position":[[1561,5],[2430,4],[2634,4],[2727,4]]},"4539":{"position":[[777,5],[1159,4]]},"4572":{"position":[[43,5]]},"4587":{"position":[[767,5]]},"4589":{"position":[[800,5]]},"4591":{"position":[[60,5],[882,4]]},"4593":{"position":[[2124,4],[2216,5]]},"4595":{"position":[[93,4],[340,4]]},"4643":{"position":[[2715,6]]},"4654":{"position":[[368,4]]},"4656":{"position":[[733,7]]},"4662":{"position":[[858,6],[1121,5]]},"4667":{"position":[[6389,4],[6490,6],[6775,6],[7028,6]]},"4691":{"position":[[211,5]]},"4715":{"position":[[257,4]]},"4722":{"position":[[279,5]]},"4724":{"position":[[532,7],[691,6]]},"4726":{"position":[[37,5],[722,4]]},"4728":{"position":[[114,6],[1317,5]]},"4733":{"position":[[37,5],[603,6]]},"4742":{"position":[[93,4],[198,4]]},"4746":{"position":[[120,7]]},"4748":{"position":[[187,4]]},"4765":{"position":[[119,6]]},"4767":{"position":[[6,4],[271,4]]},"4795":{"position":[[63,4]]},"4797":{"position":[[271,4]]},"4801":{"position":[[118,5],[294,4]]},"4833":{"position":[[660,5]]},"4861":{"position":[[876,6]]},"4868":{"position":[[9,4]]},"4872":{"position":[[907,4]]},"4883":{"position":[[111,4]]}}}],["needless",{"_index":11250,"t":{"4185":{"position":[[616,8]]}}}],["needlessli",{"_index":11382,"t":{"4236":{"position":[[478,10]]}}}],["neg",{"_index":4076,"t":{"967":{"position":[[98,10]]},"1858":{"position":[[98,10]]},"2991":{"position":[[98,10]]},"3894":{"position":[[616,8]]}}}],["neglig",{"_index":1099,"t":{"173":{"position":[[212,11],[974,11]]},"4220":{"position":[[382,9]]}}}],["negoti",{"_index":1392,"t":{"197":{"position":[[472,10]]},"3731":{"position":[[3048,10]]},"4226":{"position":[[3117,12]]},"4230":{"position":[[1842,11]]}}}],["ness",{"_index":11740,"t":{"4625":{"position":[[369,4]]},"4632":{"position":[[2961,4]]},"4634":{"position":[[85,4]]}}}],["nessu",{"_index":8498,"t":{"2478":{"position":[[2383,7]]}}}],["nest",{"_index":2189,"t":{"368":{"position":[[2041,9]]},"1359":{"position":[[63,6]]},"1361":{"position":[[65,6]]},"2003":{"position":[[115,6],[148,6],[252,6]]},"2019":{"position":[[43,6]]},"2178":{"position":[[208,6]]},"2343":{"position":[[772,6]]},"2410":{"position":[[772,6]]},"3669":{"position":[[409,6],[535,8]]},"3710":{"position":[[422,6],[548,8],[758,6]]},"3803":{"position":[[409,6],[535,8],[745,6]]}}}],["nested=i",{"_index":5845,"t":{"1359":{"position":[[22,9]]},"1361":{"position":[[24,9]]}}}],["net",{"_index":4278,"t":{"1005":{"position":[[2434,3],[2835,3]]},"1007":{"position":[[251,3]]},"1525":{"position":[[2373,4]]},"1704":{"position":[[615,4]]},"1896":{"position":[[2434,3],[2835,3]]},"1898":{"position":[[251,3]]},"1906":{"position":[[286,4]]},"2252":{"position":[[2678,3]]}}}],["net.core.rmem_max",{"_index":4983,"t":{"1201":{"position":[[405,17]]}}}],["net.core.somaxconn",{"_index":4986,"t":{"1201":{"position":[[511,18]]}}}],["net.core.wmem_max",{"_index":4981,"t":{"1201":{"position":[[369,17]]}}}],["net.ipv4.tcp_fin_timeout",{"_index":4984,"t":{"1201":{"position":[[441,24]]}}}],["net.ipv4.tcp_keepalive_intvl",{"_index":4979,"t":{"1201":{"position":[[288,28]]}}}],["net.ipv4.tcp_keepalive_prob",{"_index":4980,"t":{"1201":{"position":[[328,29]]}}}],["net.ipv4.tcp_keepalive_tim",{"_index":4978,"t":{"1201":{"position":[[249,27]]}}}],["net.ipv4.tcp_max_syn_backlog",{"_index":4988,"t":{"1201":{"position":[[579,28]]}}}],["net.ipv4.tcp_syncooki",{"_index":4987,"t":{"1201":{"position":[[544,23]]}}}],["net.ipv4.tcp_tw_reus",{"_index":4985,"t":{"1201":{"position":[[478,21]]}}}],["net.netfilter.nf_conntrack_max",{"_index":4989,"t":{"1201":{"position":[[645,30]]}}}],["net003",{"_index":6235,"t":{"1457":{"position":[[3330,9],[3509,9]]}}}],["netbox",{"_index":894,"t":{"155":{"position":[[129,6]]},"1232":{"position":[[298,6]]},"1478":{"position":[[192,6],[251,6],[290,6]]},"2039":{"position":[[628,6]]},"2155":{"position":[[2464,6],[2521,7],[2529,6]]},"2192":{"position":[[490,6]]},"2194":{"position":[[1111,6]]},"2225":{"position":[[230,6]]},"3016":{"position":[[314,7]]},"3086":{"position":[[1226,6],[1412,7]]},"3348":{"position":[[483,7]]},"3357":{"position":[[92,7],[2952,7]]},"3962":{"position":[[135,6],[179,6]]}}}],["netbox.netbox",{"_index":893,"t":{"155":{"position":[[60,13],[488,13]]}}}],["netbox.netbox.netbox_manufactur",{"_index":896,"t":{"155":{"position":[[150,34]]}}}],["netbox.services.in",{"_index":7336,"t":{"2037":{"position":[[1431,18]]}}}],["netbox.testbed.osism.xyz",{"_index":7911,"t":{"2192":{"position":[[465,24]]}}}],["netbox:latest",{"_index":7773,"t":{"2155":{"position":[[2493,13]]}}}],["netbox_data_manufactur",{"_index":904,"t":{"155":{"position":[[405,25]]}}}],["netbox_sit",{"_index":909,"t":{"155":{"position":[[539,12]]}}}],["netbox_token",{"_index":898,"t":{"155":{"position":[[216,13],[234,12],[583,13],[601,12]]}}}],["netbox_url",{"_index":897,"t":{"155":{"position":[[185,11],[201,10],[552,11],[568,10]]}}}],["netcat",{"_index":3843,"t":{"938":{"position":[[66,6]]},"1829":{"position":[[66,6]]},"2962":{"position":[[66,6]]}}}],["netdata",{"_index":4361,"t":{"1013":{"position":[[500,7]]},"1054":{"position":[[500,7]]},"1226":{"position":[[4463,7],[4586,7]]},"1711":{"position":[[632,7],[671,7]]},"2039":{"position":[[689,7]]},"2194":{"position":[[1166,7]]},"2225":{"position":[[237,7]]},"3016":{"position":[[331,8]]},"3357":{"position":[[227,8],[2960,8]]}}}],["netdata_host_typ",{"_index":5096,"t":{"1226":{"position":[[4510,18],[4604,18]]}}}],["netlifi",{"_index":11799,"t":{"4662":{"position":[[1216,7],[1273,7],[1343,7],[1847,7]]}}}],["netowrk",{"_index":5298,"t":{"1271":{"position":[[91,7]]}}}],["netplan",{"_index":5244,"t":{"1266":{"position":[[49,7],[112,7],[759,7],[2602,7],[2797,7],[2841,7]]},"1268":{"position":[[4,7]]},"1271":{"position":[[113,7]]},"1275":{"position":[[427,7]]},"2048":{"position":[[2097,7]]}}}],["netplan(5",{"_index":5258,"t":{"1266":{"position":[[934,11]]}}}],["netweav",{"_index":6218,"t":{"1455":{"position":[[1767,9],[1794,9]]}}}],["network",{"_index":51,"t":{"7":{"position":[[400,8]]},"171":{"position":[[226,9]]},"175":{"position":[[388,9],[786,9]]},"177":{"position":[[274,7]]},"179":{"position":[[1199,7]]},"197":{"position":[[33,7],[1165,8]]},"305":{"position":[[798,11]]},"423":{"position":[[396,7]]},"533":{"position":[[462,7]]},"539":{"position":[[196,10]]},"541":{"position":[[502,7],[572,11],[616,7],[936,7]]},"545":{"position":[[200,7]]},"557":{"position":[[161,8],[1207,8],[1220,7],[1577,7],[4466,8],[4566,7],[6567,7]]},"794":{"position":[[56,7]]},"812":{"position":[[324,8]]},"814":{"position":[[370,7]]},"820":{"position":[[206,7]]},"822":{"position":[[125,11],[145,10],[432,7]]},"824":{"position":[[146,10],[206,8]]},"828":{"position":[[13,7],[28,7],[129,8],[164,7],[215,7]]},"834":{"position":[[145,7]]},"846":{"position":[[14,10],[53,10],[117,9],[279,8],[418,9],[555,10],[741,10]]},"906":{"position":[[244,7],[271,7],[354,7],[454,7],[499,7],[591,7]]},"912":{"position":[[573,8],[597,8],[667,7],[827,8],[853,8],[899,7],[1015,7],[1179,7],[1319,7],[2286,7],[2305,7],[2342,7],[2362,7],[2471,7],[2500,7],[2824,7],[2860,7],[2884,7],[2921,7],[2998,7],[3041,7],[3217,7],[3247,7],[3442,7],[3492,7],[3659,7],[3701,7]]},"914":{"position":[[37,8],[2694,10],[2723,10],[3066,7],[4016,10],[4047,10],[4403,7],[5346,10],[5375,10],[5720,7]]},"924":{"position":[[1333,7],[1366,9]]},"932":{"position":[[376,7],[404,7],[417,7],[519,8],[547,7],[702,7],[722,7],[788,7],[801,7],[1943,7],[1956,7],[3336,8]]},"938":{"position":[[1893,8],[2607,8],[2689,9]]},"942":{"position":[[1362,7],[1733,8],[1742,8],[2021,8],[2485,8]]},"978":{"position":[[1195,8]]},"995":{"position":[[232,7],[1515,7],[1611,7]]},"999":{"position":[[225,8]]},"1003":{"position":[[256,7],[280,7]]},"1005":{"position":[[568,7],[576,8],[588,7],[1700,7],[1708,7],[1718,7],[1744,7],[2421,7],[2822,7]]},"1007":{"position":[[236,7]]},"1013":{"position":[[152,10]]},"1016":{"position":[[73,7]]},"1018":{"position":[[42,7]]},"1022":{"position":[[42,7],[79,7]]},"1030":{"position":[[173,7],[215,7],[404,10]]},"1034":{"position":[[12,7],[137,9],[220,7]]},"1040":{"position":[[819,7]]},"1042":{"position":[[1090,7]]},"1044":{"position":[[4,7],[109,10]]},"1046":{"position":[[182,8],[259,7],[278,8],[303,7],[329,7],[393,8],[454,8]]},"1048":{"position":[[105,7],[142,7],[181,7],[222,8],[240,7],[267,7],[284,7],[307,7]]},"1050":{"position":[[16,7],[202,8],[238,9],[333,8],[378,7],[419,9],[460,8],[614,7]]},"1054":{"position":[[152,10]]},"1067":{"position":[[832,11],[1819,7],[1882,10],[1957,9],[1984,10],[2092,7]]},"1077":{"position":[[257,10]]},"1107":{"position":[[115,7],[153,7]]},"1111":{"position":[[12,7],[35,7],[121,8],[147,7]]},"1183":{"position":[[237,7]]},"1226":{"position":[[1978,7],[2240,7],[2359,7],[2399,7],[2466,7],[2495,7],[3607,7],[3641,7],[3786,7],[3809,9],[4630,7]]},"1230":{"position":[[68,7]]},"1266":{"position":[[31,7],[862,7],[950,8],[1661,7],[2401,7],[2529,7]]},"1275":{"position":[[405,7]]},"1331":{"position":[[48,7],[89,7],[127,7],[223,8],[280,7],[326,7],[380,7]]},"1346":{"position":[[255,8],[797,8],[871,8],[883,7],[993,7]]},"1348":{"position":[[370,9]]},"1354":{"position":[[286,7],[669,9]]},"1399":{"position":[[60,7],[222,7]]},"1405":{"position":[[345,8],[1616,10]]},"1455":{"position":[[1254,7],[1376,7],[1396,7],[1438,7],[1505,8]]},"1457":{"position":[[2846,7],[2910,7],[2945,7],[3031,7],[3314,8],[3493,8]]},"1466":{"position":[[187,7],[677,7],[730,7],[829,7]]},"1468":{"position":[[944,7]]},"1474":{"position":[[374,7],[484,7],[515,7],[548,7],[626,7],[657,7],[779,7],[850,7],[920,7]]},"1511":{"position":[[273,7]]},"1519":{"position":[[88,7]]},"1574":{"position":[[725,7]]},"1702":{"position":[[85,7],[112,7]]},"1707":{"position":[[9,7],[81,7]]},"1711":{"position":[[122,7],[347,7]]},"1713":{"position":[[1391,7],[1559,7],[1605,7],[2334,7],[2421,7]]},"1745":{"position":[[212,7]]},"1790":{"position":[[244,7],[271,7],[354,7],[454,7],[499,7],[591,7]]},"1796":{"position":[[573,8],[597,8],[667,7],[827,8],[853,8],[899,7],[1015,7],[1179,7],[1319,7],[2286,7],[2305,7],[2342,7],[2362,7],[2471,7],[2500,7],[2824,7],[2860,7],[2884,7],[2921,7],[2998,7],[3041,7],[3217,7],[3247,7],[3442,7],[3492,7],[3659,7],[3701,7]]},"1798":{"position":[[37,8],[2694,10],[2723,10],[3066,7],[4016,10],[4047,10],[4403,7],[5346,10],[5375,10],[5720,7]]},"1815":{"position":[[1333,7],[1366,9]]},"1823":{"position":[[376,7],[404,7],[417,7],[519,8],[547,7],[702,7],[722,7],[788,7],[801,7],[1943,7],[1956,7],[3336,8]]},"1829":{"position":[[1893,8],[2607,8],[2689,9]]},"1833":{"position":[[1362,7],[1733,8],[1742,8],[2021,8],[2485,8]]},"1869":{"position":[[1195,8]]},"1886":{"position":[[232,7],[1515,7],[1611,7]]},"1890":{"position":[[225,8]]},"1894":{"position":[[256,7],[280,7]]},"1896":{"position":[[568,7],[576,8],[588,7],[1700,7],[1708,7],[1718,7],[1744,7],[2421,7],[2822,7]]},"1898":{"position":[[236,7]]},"1917":{"position":[[725,7]]},"2027":{"position":[[661,7],[680,7],[741,7]]},"2029":{"position":[[251,9]]},"2032":{"position":[[1088,7],[1534,7]]},"2034":{"position":[[1621,7]]},"2048":{"position":[[130,7],[174,7],[625,8],[686,7],[746,7],[874,7],[939,7],[1001,7],[1022,7],[1060,7],[1081,7],[1119,7],[1140,7],[1180,7],[1201,7],[1241,7],[1262,7],[1302,7],[1323,7],[1669,7],[1762,7],[2084,7],[2216,7],[2864,7],[2947,7],[3444,7],[3522,8],[3667,8],[3789,7]]},"2117":{"position":[[648,8],[1564,8],[1577,7]]},"2146":{"position":[[462,7],[748,7],[781,7],[833,10]]},"2173":{"position":[[99,7]]},"2178":{"position":[[722,7],[934,8]]},"2180":{"position":[[278,7]]},"2184":{"position":[[5113,8],[6527,7]]},"2236":{"position":[[267,7],[515,7]]},"2240":{"position":[[1529,8]]},"2252":{"position":[[1478,7],[1669,7]]},"2254":{"position":[[189,8]]},"2256":{"position":[[724,7],[859,7]]},"2266":{"position":[[511,7],[767,7]]},"2268":{"position":[[247,7]]},"2272":{"position":[[337,7]]},"2276":{"position":[[424,10]]},"2283":{"position":[[45,7],[159,7],[215,8],[249,7]]},"2287":{"position":[[18,7]]},"2297":{"position":[[45,7],[159,7],[215,8],[249,7]]},"2301":{"position":[[18,7]]},"2321":{"position":[[237,7]]},"2388":{"position":[[237,7]]},"2499":{"position":[[384,10]]},"2529":{"position":[[265,7],[298,7]]},"2537":{"position":[[409,7]]},"2555":{"position":[[121,9],[218,7]]},"2574":{"position":[[222,10]]},"2697":{"position":[[210,9]]},"2712":{"position":[[405,7],[630,7]]},"2714":{"position":[[246,8]]},"2718":{"position":[[200,8],[380,7],[433,7],[601,7]]},"2798":{"position":[[107,7]]},"2948":{"position":[[1333,7],[1366,9]]},"2956":{"position":[[376,7],[404,7],[417,7],[519,8],[547,7],[702,7],[722,7],[788,7],[801,7],[1943,7],[1956,7],[3336,8]]},"2962":{"position":[[1893,8],[2607,8],[2689,9]]},"2966":{"position":[[1362,7],[1733,8],[1742,8],[2021,8],[2485,8]]},"3002":{"position":[[1195,8]]},"3016":{"position":[[93,10]]},"3036":{"position":[[7585,12],[7882,9]]},"3088":{"position":[[74,7]]},"3116":{"position":[[586,7]]},"3344":{"position":[[253,7]]},"3348":{"position":[[209,12],[349,7]]},"3352":{"position":[[1872,7],[2399,7],[2531,11],[2708,7],[3172,9],[3749,7]]},"3357":{"position":[[496,10],[628,7]]},"3367":{"position":[[1186,7]]},"3398":{"position":[[197,11]]},"3468":{"position":[[1409,10]]},"3569":{"position":[[451,7]]},"3656":{"position":[[305,7]]},"3665":{"position":[[20,7],[734,8]]},"3673":{"position":[[1169,11]]},"3675":{"position":[[73,7]]},"3677":{"position":[[1044,9]]},"3681":{"position":[[701,7]]},"3693":{"position":[[364,7]]},"3702":{"position":[[92,7],[947,8]]},"3704":{"position":[[554,7]]},"3716":{"position":[[48,11]]},"3718":{"position":[[740,7]]},"3720":{"position":[[73,7]]},"3780":{"position":[[364,7]]},"3789":{"position":[[92,7],[806,8]]},"3791":{"position":[[1066,9]]},"3809":{"position":[[25,11]]},"3811":{"position":[[740,7]]},"3813":{"position":[[73,7]]},"3894":{"position":[[898,7]]},"3904":{"position":[[442,7],[595,9]]},"3925":{"position":[[276,9],[411,9],[1222,7],[1259,7],[1413,9]]},"3928":{"position":[[3110,9],[5267,7],[6020,9]]},"3930":{"position":[[943,9]]},"3932":{"position":[[808,9]]},"3941":{"position":[[559,7]]},"3956":{"position":[[63,11],[240,8],[340,7],[389,7]]},"3960":{"position":[[8,7],[67,7],[140,7],[200,8],[222,7],[539,7],[729,7]]},"3962":{"position":[[218,7]]},"3964":{"position":[[140,7],[243,7]]},"3968":{"position":[[2401,7]]},"3978":{"position":[[127,8]]},"3980":{"position":[[99,8],[256,7]]},"3984":{"position":[[562,10],[1739,7]]},"3986":{"position":[[142,7],[431,7]]},"3990":{"position":[[4,7],[79,7],[316,7],[1230,7],[1432,7],[1984,7],[2105,7],[2584,7]]},"3994":{"position":[[250,7]]},"3996":{"position":[[99,7]]},"4007":{"position":[[153,7]]},"4037":{"position":[[52,7],[167,7],[223,8]]},"4039":{"position":[[65,7]]},"4041":{"position":[[190,10]]},"4043":{"position":[[771,7]]},"4096":{"position":[[443,7],[501,7],[907,7]]},"4109":{"position":[[1277,7],[1362,7],[1394,7]]},"4113":{"position":[[1367,9],[2219,7]]},"4133":{"position":[[706,7],[791,7],[823,7]]},"4135":{"position":[[347,7],[407,7]]},"4142":{"position":[[93,9]]},"4155":{"position":[[492,7],[550,7],[926,8],[943,8],[967,10]]},"4157":{"position":[[784,7]]},"4159":{"position":[[2095,7]]},"4163":{"position":[[4648,8],[4669,7],[4811,10],[4871,7],[5124,7],[5363,7],[5528,7],[6127,7]]},"4165":{"position":[[12,10]]},"4202":{"position":[[378,7],[394,10]]},"4220":{"position":[[829,7],[1062,8],[1127,9],[1185,7],[1417,7],[1617,10],[1805,10],[1823,7]]},"4222":{"position":[[578,7],[1157,7],[1345,7],[1470,7],[1610,7],[1829,7],[1980,7],[2171,7],[2265,7],[2774,7],[3011,8],[3100,8],[3246,8],[3273,7],[3600,7],[3679,7]]},"4224":{"position":[[499,7],[956,10],[1110,9],[2436,7]]},"4226":{"position":[[231,10],[306,10],[349,10],[408,10],[463,7],[602,7],[1190,10],[1361,8],[1413,8],[1972,7],[2140,10],[2335,10],[2664,7],[2777,7],[3273,7],[3506,7]]},"4228":{"position":[[530,8],[547,8],[683,7],[1603,10]]},"4230":{"position":[[1352,10],[1764,8],[2155,7],[2505,7]]},"4232":{"position":[[151,10]]},"4234":{"position":[[209,11]]},"4238":{"position":[[105,7]]},"4244":{"position":[[31,10],[353,7]]},"4246":{"position":[[20,10],[342,7]]},"4296":{"position":[[164,10]]},"4302":{"position":[[861,7],[946,8],[1007,8],[1056,7],[1099,8],[1208,7],[1273,7],[1326,7],[1416,7],[1507,7],[3025,7],[3320,7],[4400,8],[4530,7]]},"4304":{"position":[[523,7]]},"4308":{"position":[[127,8],[873,7],[1156,7],[1216,7]]},"4327":{"position":[[456,7]]},"4329":{"position":[[97,8]]},"4331":{"position":[[175,9],[205,7],[238,7]]},"4333":{"position":[[62,8],[75,7],[193,7],[418,8]]},"4459":{"position":[[1333,7]]},"4479":{"position":[[1730,7]]},"4493":{"position":[[478,7]]},"4529":{"position":[[647,7]]},"4535":{"position":[[2614,8]]},"4537":{"position":[[428,9],[604,7]]},"4539":{"position":[[406,7]]},"4541":{"position":[[984,9]]},"4545":{"position":[[153,7]]},"4547":{"position":[[1394,7]]},"4562":{"position":[[2244,7]]},"4569":{"position":[[15,7],[227,7],[541,7]]},"4572":{"position":[[21,10],[163,10],[369,10]]},"4574":{"position":[[256,7],[290,10],[347,10],[472,10],[493,7],[535,7]]},"4576":{"position":[[48,10],[97,11]]},"4580":{"position":[[30,7],[68,7],[146,7],[458,10],[537,7],[741,7],[779,7],[1063,7],[1375,7],[1462,7],[1511,7],[1718,7],[1778,10],[1941,7],[2179,7],[2257,7]]},"4582":{"position":[[20,7],[142,7],[514,10],[665,7]]},"4584":{"position":[[21,7]]},"4679":{"position":[[306,7]]},"4722":{"position":[[126,11]]},"4726":{"position":[[273,7]]},"4733":{"position":[[628,7],[916,7]]},"4742":{"position":[[173,7]]},"4775":{"position":[[220,10]]},"4826":{"position":[[3431,10]]},"4849":{"position":[[1200,11]]}}}],["network.host",{"_index":5547,"t":{"1303":{"position":[[1185,13],[3089,13]]}}}],["network.id",{"_index":4294,"t":{"1005":{"position":[[2868,10]]},"1896":{"position":[[2868,10]]}}}],["network.yml",{"_index":7402,"t":{"2048":{"position":[[2819,11]]}}}],["network/control",{"_index":11441,"t":{"4302":{"position":[[908,18],[1151,18]]}}}],["network/subnet",{"_index":2780,"t":{"557":{"position":[[4128,14]]}}}],["network=$(openstack",{"_index":3905,"t":{"942":{"position":[[1342,19]]},"1833":{"position":[[1342,19]]},"2966":{"position":[[1342,19]]}}}],["network_allow_service_restart",{"_index":5283,"t":{"1266":{"position":[[2920,29],[2999,30]]}}}],["network_availability_zon",{"_index":7859,"t":{"2178":{"position":[[1234,25]]},"2219":{"position":[[596,25]]}}}],["network_bond",{"_index":5271,"t":{"1266":{"position":[[1731,13]]}}}],["network_bonds|to_nice_yaml(indent=4)|indent(4",{"_index":5261,"t":{"1266":{"position":[[1033,46]]}}}],["network_bridg",{"_index":5274,"t":{"1266":{"position":[[1836,15]]}}}],["network_bridges|to_nice_yaml(indent=4)|indent(4",{"_index":5262,"t":{"1266":{"position":[[1095,48]]}}}],["network_dummy_interfac",{"_index":5299,"t":{"1271":{"position":[[136,25]]},"1275":{"position":[[435,25]]}}}],["network_dummy_interface_mtu",{"_index":5302,"t":{"1271":{"position":[[224,28]]}}}],["network_ethernet",{"_index":5090,"t":{"1226":{"position":[[2566,18],[4827,18]]},"1266":{"position":[[1945,17]]},"1268":{"position":[[173,18]]},"1275":{"position":[[470,18]]},"2048":{"position":[[1976,18]]}}}],["network_ethernets|to_nice_yaml(indent=4)|indent(4",{"_index":5264,"t":{"1266":{"position":[[1161,50]]}}}],["network_external_allocation_pool_end",{"_index":7084,"t":{"1707":{"position":[[211,36]]}}}],["network_external_allocation_pool_start",{"_index":7086,"t":{"1707":{"position":[[266,38]]}}}],["network_external_cidr",{"_index":7088,"t":{"1707":{"position":[[323,21]]}}}],["network_external_cloud",{"_index":7090,"t":{"1707":{"position":[[364,22]]}}}],["network_external_gateway_ip",{"_index":7091,"t":{"1707":{"position":[[393,27]]}}}],["network_external_nam",{"_index":7093,"t":{"1707":{"position":[[437,21]]}}}],["network_external_provider_network_typ",{"_index":7094,"t":{"1707":{"position":[[466,38]]}}}],["network_external_provider_physical_network",{"_index":7095,"t":{"1707":{"position":[[510,42]]}}}],["network_external_st",{"_index":7097,"t":{"1707":{"position":[[562,22]]}}}],["network_interfac",{"_index":5100,"t":{"1226":{"position":[[4964,18]]},"1275":{"position":[[925,18]]},"1299":{"position":[[30,17],[83,17],[136,17],[174,17],[255,17],[388,17]]}}}],["network_mtu",{"_index":2824,"t":{"557":{"position":[[6443,11]]}}}],["network_nam",{"_index":7408,"t":{"2048":{"position":[[3220,13]]}}}],["network_netplan_fil",{"_index":5249,"t":{"1266":{"position":[[239,20]]}}}],["network_netplan_managed_files_extra",{"_index":5254,"t":{"1266":{"position":[[607,36]]}}}],["network_netplan_path",{"_index":5248,"t":{"1266":{"position":[[214,20]]}}}],["network_netplan_permiss",{"_index":5251,"t":{"1266":{"position":[[338,27]]}}}],["network_netplan_remove_unmanaged_fil",{"_index":5253,"t":{"1266":{"position":[[472,38]]}}}],["network_render",{"_index":5260,"t":{"1266":{"position":[[1003,16],[1622,16]]}}}],["network_trait",{"_index":9575,"t":{"3036":{"position":[[7787,15],[7904,15],[8048,15],[8188,15],[8326,15],[8472,15],[8586,15],[8741,15],[8908,15],[9068,15],[9223,15],[9378,15],[9541,15]]}}}],["network_tunnel",{"_index":5275,"t":{"1266":{"position":[[2058,15]]}}}],["network_tunnels|to_nice_yaml(indent=4)|indent(4",{"_index":5266,"t":{"1266":{"position":[[1227,48]]}}}],["network_typ",{"_index":5245,"t":{"1266":{"position":[[98,13]]},"1273":{"position":[[38,12],[108,13]]},"1275":{"position":[[413,13]]}}}],["network_vers",{"_index":5259,"t":{"1266":{"position":[[971,15],[1501,15]]}}}],["network_vlan",{"_index":5276,"t":{"1266":{"position":[[2167,13]]},"1268":{"position":[[394,14]]}}}],["network_vlans|to_nice_yaml(indent=4)|indent(4",{"_index":5267,"t":{"1266":{"position":[[1289,46]]}}}],["network_vrf",{"_index":5277,"t":{"1266":{"position":[[2272,12]]}}}],["network_vrfs|to_nice_yaml(indent=4)|indent(4",{"_index":5269,"t":{"1266":{"position":[[1348,45]]}}}],["network_workload_interfac",{"_index":7396,"t":{"2048":{"position":[[2166,26],[2438,27]]}}}],["network_zon",{"_index":4265,"t":{"1005":{"position":[[601,13],[1731,12]]},"1896":{"position":[[601,13],[1731,12]]}}}],["networkcard",{"_index":8090,"t":{"2236":{"position":[[369,11]]},"2248":{"position":[[395,11]]}}}],["networkd",{"_index":5270,"t":{"1266":{"position":[[1639,8]]}}}],["networking.k8s.io/v1",{"_index":9030,"t":{"2740":{"position":[[858,20]]},"4578":{"position":[[286,20]]},"4582":{"position":[[98,21],[386,20],[552,20]]},"4853":{"position":[[77,22]]}}}],["networkmtu",{"_index":2826,"t":{"557":{"position":[[6468,10]]}}}],["networkpolici",{"_index":11686,"t":{"4569":{"position":[[395,13],[775,13]]},"4572":{"position":[[289,13]]},"4578":{"position":[[245,14]]},"4580":{"position":[[0,13],[2415,13]]},"4582":{"position":[[55,13],[583,13]]}}}],["neutral",{"_index":11256,"t":{"4189":{"position":[[319,8]]}}}],["neutron",{"_index":3302,"t":{"820":{"position":[[214,10]]},"846":{"position":[[32,7],[87,7],[349,7],[428,7],[591,10],[678,7],[969,7],[1021,7]]},"995":{"position":[[114,7],[167,7],[222,7],[278,7],[333,7],[392,7],[451,7],[513,7],[943,7],[1036,7],[1129,7],[1222,7],[1315,7],[1410,7],[1505,7],[1601,7],[1697,7],[1792,7],[1887,7],[1982,7],[2081,7],[2186,7],[2292,7],[2398,7]]},"1067":{"position":[[820,7],[1863,7]]},"1077":{"position":[[248,8]]},"1226":{"position":[[3680,8]]},"1329":{"position":[[0,7],[20,7],[48,7],[80,7],[105,7],[141,7],[185,7],[233,7],[249,7],[276,7]]},"1331":{"position":[[0,7],[232,7],[464,7]]},"1519":{"position":[[316,7]]},"1523":{"position":[[814,7],[842,7],[862,7]]},"1704":{"position":[[585,8]]},"1711":{"position":[[432,7]]},"1713":{"position":[[2068,7]]},"1886":{"position":[[114,7],[167,7],[222,7],[278,7],[333,7],[392,7],[451,7],[513,7],[943,7],[1036,7],[1129,7],[1222,7],[1315,7],[1410,7],[1505,7],[1601,7],[1697,7],[1792,7],[1887,7],[1982,7],[2081,7],[2186,7],[2292,7],[2398,7]]},"2048":{"position":[[2137,7],[2622,7]]},"2173":{"position":[[327,7]]},"2225":{"position":[[402,7]]},"2231":{"position":[[593,7],[621,7],[652,7]]},"2276":{"position":[[492,9]]},"3016":{"position":[[665,8]]},"3130":{"position":[[105,7]]},"3960":{"position":[[97,7],[311,7],[487,7]]},"3964":{"position":[[41,7]]},"3980":{"position":[[271,7],[346,7]]},"4000":{"position":[[145,7]]},"4002":{"position":[[31,7]]},"4055":{"position":[[415,7]]},"4057":{"position":[[73,7]]},"4096":{"position":[[525,7]]},"4155":{"position":[[574,7]]},"4171":{"position":[[642,7]]},"4173":{"position":[[159,7]]},"4202":{"position":[[386,7]]},"4226":{"position":[[826,7],[979,8],[1333,8]]},"4228":{"position":[[190,7]]},"4230":{"position":[[0,7],[69,7]]},"4244":{"position":[[21,7],[609,7],[649,7]]},"4246":{"position":[[10,7],[598,7],[638,7]]},"4302":{"position":[[853,7],[1048,7],[1087,7]]},"4329":{"position":[[189,7],[263,7],[309,7]]},"4331":{"position":[[34,7],[167,7],[271,7]]}}}],["neutron'",{"_index":11444,"t":{"4302":{"position":[[3006,9],[3301,9]]}}}],["neutron.services.a.regiocloud.tech",{"_index":5456,"t":{"1297":{"position":[[2381,34]]}}}],["neutron2",{"_index":11316,"t":{"4224":{"position":[[44,8],[652,8],[885,8],[1594,9]]},"4226":{"position":[[380,8]]},"4228":{"position":[[910,8],[972,8],[1435,8],[1668,8]]},"4230":{"position":[[1270,8]]},"4234":{"position":[[350,9]]},"4240":{"position":[[153,8]]}}}],["neutron_api_work",{"_index":5616,"t":{"1305":{"position":[[1330,19]]}}}],["neutron_availability_zone_hints_network",{"_index":8058,"t":{"2219":{"position":[[910,39]]}}}],["neutron_availability_zone_hints_rout",{"_index":8059,"t":{"2219":{"position":[[950,38]]}}}],["neutron_bridge_nam",{"_index":7397,"t":{"2048":{"position":[[2285,19],[2481,20]]}}}],["neutron_external_interfac",{"_index":5106,"t":{"1226":{"position":[[5108,27]]},"1299":{"position":[[53,26],[434,26]]}}}],["neutron_floatingip",{"_index":8067,"t":{"2219":{"position":[[1185,18]]}}}],["neutron_metadata_work",{"_index":5617,"t":{"1305":{"position":[[1350,24]]}}}],["neutron_ovn_metadata_ag",{"_index":7115,"t":{"1711":{"position":[[1675,26]]},"1713":{"position":[[1449,26]]}}}],["neutron_plugin_ag",{"_index":6341,"t":{"1519":{"position":[[156,20],[324,21]]},"2173":{"position":[[167,20],[335,21]]}}}],["neutron_public_endpoint",{"_index":5425,"t":{"1297":{"position":[[841,24]]}}}],["neutron_router_enable_snat",{"_index":8060,"t":{"2219":{"position":[[989,26]]}}}],["neutron_server_external_back",{"_index":5457,"t":{"1297":{"position":[[2428,28]]}}}],["neutron_ssh_key",{"_index":9765,"t":{"3126":{"position":[[48,15],[79,16]]}}}],["neutroncli",{"_index":371,"t":{"37":{"position":[[1134,13]]}}}],["never",{"_index":847,"t":{"147":{"position":[[89,5]]},"151":{"position":[[134,5]]},"159":{"position":[[323,5]]},"417":{"position":[[212,5]]},"622":{"position":[[84,5]]},"865":{"position":[[1069,5]]},"940":{"position":[[526,5],[1125,5]]},"1509":{"position":[[609,5]]},"1569":{"position":[[577,5]]},"1766":{"position":[[1069,5]]},"1831":{"position":[[526,5],[1125,5]]},"1902":{"position":[[727,5]]},"2084":{"position":[[89,5]]},"2086":{"position":[[135,5]]},"2090":{"position":[[313,5]]},"2132":{"position":[[47,5]]},"2439":{"position":[[803,5]]},"2964":{"position":[[526,5],[1125,5]]},"3829":{"position":[[1166,5],[1206,5]]},"4102":{"position":[[1187,5]]},"4104":{"position":[[1014,5]]},"4171":{"position":[[288,5]]}}}],["nevertheless",{"_index":1242,"t":{"179":{"position":[[1078,12]]},"1387":{"position":[[97,13]]},"1484":{"position":[[97,13]]},"1979":{"position":[[97,13]]},"2148":{"position":[[97,13]]},"3073":{"position":[[635,13]]},"3230":{"position":[[465,13]]},"3941":{"position":[[1561,13]]},"3947":{"position":[[2365,13],[3354,13]]},"4045":{"position":[[932,13]]},"4109":{"position":[[3350,12]]},"4163":{"position":[[3534,12]]},"4353":{"position":[[829,12]]},"4376":{"position":[[125,13]]},"4422":{"position":[[277,12]]},"4479":{"position":[[665,12]]},"4525":{"position":[[112,13]]},"4541":{"position":[[1000,12]]},"4861":{"position":[[146,13]]}}}],["new",{"_index":135,"t":{"19":{"position":[[106,3]]},"59":{"position":[[316,3]]},"78":{"position":[[218,3],[373,3]]},"199":{"position":[[95,3]]},"201":{"position":[[328,3]]},"253":{"position":[[318,3]]},"299":{"position":[[24,3]]},"301":{"position":[[496,4]]},"364":{"position":[[457,3]]},"368":{"position":[[205,3],[7563,3]]},"397":{"position":[[474,3]]},"403":{"position":[[483,3]]},"407":{"position":[[269,3],[370,3]]},"415":{"position":[[25,3]]},"438":{"position":[[504,3]]},"463":{"position":[[1033,3]]},"479":{"position":[[484,3],[854,3]]},"485":{"position":[[231,3],[488,3]]},"549":{"position":[[367,3]]},"551":{"position":[[48,3],[731,3],[1056,3],[1083,3],[1390,3]]},"557":{"position":[[4124,3]]},"602":{"position":[[350,3]]},"647":{"position":[[174,3]]},"679":{"position":[[174,3]]},"701":{"position":[[2458,3]]},"705":{"position":[[1063,3],[1444,3]]},"848":{"position":[[495,3]]},"871":{"position":[[1295,3]]},"873":{"position":[[1214,3],[1265,3]]},"887":{"position":[[4762,3],[8418,3]]},"912":{"position":[[3835,3]]},"918":{"position":[[59,3]]},"932":{"position":[[1557,3],[3855,3]]},"938":{"position":[[648,3]]},"963":{"position":[[2025,3],[2308,4]]},"1067":{"position":[[675,3]]},"1073":{"position":[[624,3]]},"1175":{"position":[[3396,3],[4384,3]]},"1179":{"position":[[480,3],[2206,3],[2323,3]]},"1191":{"position":[[55,3],[953,3],[968,3]]},"1205":{"position":[[429,3]]},"1218":{"position":[[154,3],[212,3]]},"1220":{"position":[[146,3]]},"1232":{"position":[[157,3],[207,3]]},"1238":{"position":[[572,3],[596,3]]},"1244":{"position":[[333,3]]},"1246":{"position":[[1027,3]]},"1257":{"position":[[238,3]]},"1312":{"position":[[147,3]]},"1451":{"position":[[895,3]]},"1464":{"position":[[943,3]]},"1466":{"position":[[987,3]]},"1507":{"position":[[164,3],[194,3]]},"1509":{"position":[[131,3]]},"1511":{"position":[[198,3],[575,3]]},"1569":{"position":[[466,3]]},"1571":{"position":[[116,3],[556,3]]},"1600":{"position":[[34,3],[91,3],[143,3]]},"1637":{"position":[[174,3],[693,3]]},"1641":{"position":[[147,3]]},"1675":{"position":[[70,3]]},"1772":{"position":[[1295,3]]},"1774":{"position":[[1214,3],[1265,3]]},"1796":{"position":[[3835,3]]},"1802":{"position":[[59,3]]},"1811":{"position":[[4762,3],[8418,3]]},"1823":{"position":[[1557,3],[3855,3]]},"1829":{"position":[[648,3]]},"1854":{"position":[[2025,3],[2308,4]]},"1902":{"position":[[616,3]]},"1904":{"position":[[116,3],[556,3]]},"1968":{"position":[[247,3],[766,3]]},"1972":{"position":[[147,3]]},"2034":{"position":[[696,3]]},"2055":{"position":[[460,3]]},"2057":{"position":[[435,3]]},"2059":{"position":[[116,3],[263,3],[520,3],[2079,3],[2414,3],[2705,3]]},"2065":{"position":[[238,3],[344,3],[1144,3]]},"2074":{"position":[[21,3]]},"2076":{"position":[[19,3]]},"2114":{"position":[[293,3]]},"2130":{"position":[[244,3]]},"2165":{"position":[[214,3]]},"2171":{"position":[[383,3]]},"2211":{"position":[[2498,3]]},"2240":{"position":[[1022,3],[1352,3],[1525,3]]},"2250":{"position":[[387,3]]},"2252":{"position":[[686,3]]},"2285":{"position":[[1216,3]]},"2299":{"position":[[1216,3]]},"2339":{"position":[[612,3]]},"2347":{"position":[[119,3]]},"2351":{"position":[[233,3]]},"2355":{"position":[[217,3],[443,3],[676,3],[818,3],[1074,3],[1641,3],[2604,3],[2862,3]]},"2406":{"position":[[612,3]]},"2414":{"position":[[119,3]]},"2418":{"position":[[233,3]]},"2422":{"position":[[217,3],[443,3],[676,3],[818,3],[1074,3],[1641,3],[2604,3],[2862,3]]},"2431":{"position":[[1039,3]]},"2433":{"position":[[1134,3]]},"2478":{"position":[[2217,3],[2790,3]]},"2489":{"position":[[799,3]]},"2501":{"position":[[146,3]]},"2510":{"position":[[520,3]]},"2512":{"position":[[1450,3]]},"2549":{"position":[[622,3]]},"2555":{"position":[[334,3]]},"2557":{"position":[[617,3]]},"2592":{"position":[[118,3],[317,3]]},"2682":{"position":[[536,3]]},"2716":{"position":[[2290,3]]},"2738":{"position":[[9,3],[37,3],[86,3]]},"2740":{"position":[[9,3],[33,3],[188,3],[223,3],[591,3]]},"2749":{"position":[[259,3]]},"2847":{"position":[[7,3]]},"2902":{"position":[[181,3]]},"2910":{"position":[[90,3]]},"2916":{"position":[[402,3]]},"2956":{"position":[[1557,3],[3855,3]]},"2962":{"position":[[648,3]]},"2987":{"position":[[2025,3],[2308,4]]},"3050":{"position":[[414,3]]},"3073":{"position":[[478,4]]},"3083":{"position":[[218,3]]},"3086":{"position":[[1283,3]]},"3097":{"position":[[256,3],[589,3]]},"3099":{"position":[[88,3]]},"3130":{"position":[[707,3],[1055,3]]},"3148":{"position":[[698,3]]},"3150":{"position":[[378,3],[669,3]]},"3155":{"position":[[50,3]]},"3162":{"position":[[912,3]]},"3189":{"position":[[299,3]]},"3193":{"position":[[189,3]]},"3206":{"position":[[2,3],[104,3],[217,3]]},"3218":{"position":[[318,3]]},"3230":{"position":[[397,3],[608,3]]},"3238":{"position":[[37,3]]},"3266":{"position":[[791,3]]},"3276":{"position":[[368,3]]},"3281":{"position":[[75,3]]},"3288":{"position":[[501,3]]},"3292":{"position":[[44,3],[179,3],[400,3],[432,3]]},"3294":{"position":[[450,3],[468,3]]},"3296":{"position":[[281,3]]},"3308":{"position":[[789,3]]},"3313":{"position":[[668,3]]},"3344":{"position":[[216,3]]},"3357":{"position":[[1399,5]]},"3378":{"position":[[344,3]]},"3470":{"position":[[837,3]]},"3525":{"position":[[442,3]]},"3533":{"position":[[14,3],[41,3],[2653,3],[2890,3],[2924,3]]},"3537":{"position":[[640,3],[660,3]]},"3588":{"position":[[335,3]]},"3606":{"position":[[1388,3]]},"3608":{"position":[[241,3],[335,3],[382,3]]},"3627":{"position":[[614,3]]},"3661":{"position":[[700,3]]},"3698":{"position":[[810,3]]},"3731":{"position":[[1664,3]]},"3785":{"position":[[795,3]]},"3829":{"position":[[303,3],[335,3],[2420,3],[2773,3],[4827,3]]},"3879":{"position":[[192,3],[423,3],[552,3]]},"3881":{"position":[[469,3]]},"3925":{"position":[[1538,3]]},"3930":{"position":[[4,3],[526,3],[1143,3]]},"3932":{"position":[[898,3]]},"3968":{"position":[[1242,3]]},"3971":{"position":[[435,3]]},"4047":{"position":[[83,3]]},"4062":{"position":[[82,3]]},"4081":{"position":[[211,3]]},"4130":{"position":[[187,3]]},"4142":{"position":[[173,3]]},"4165":{"position":[[963,3]]},"4178":{"position":[[821,3]]},"4226":{"position":[[3502,3]]},"4230":{"position":[[872,3],[1173,3],[3458,3],[3966,3]]},"4234":{"position":[[79,3]]},"4253":{"position":[[418,3]]},"4257":{"position":[[433,3],[510,3],[1142,3],[2570,3],[3154,3],[3292,3]]},"4268":{"position":[[29,3]]},"4270":{"position":[[19,3]]},"4289":{"position":[[265,3]]},"4342":{"position":[[245,3],[381,3]]},"4351":{"position":[[228,3]]},"4353":{"position":[[247,3],[553,3],[756,3]]},"4355":{"position":[[166,3],[602,3],[664,3]]},"4362":{"position":[[123,3],[199,3]]},"4525":{"position":[[57,3]]},"4562":{"position":[[3933,3],[3967,3]]},"4580":{"position":[[1083,3],[2085,3],[3616,3]]},"4593":{"position":[[2197,3],[2259,3],[2378,3]]},"4604":{"position":[[381,3]]},"4608":{"position":[[661,3]]},"4612":{"position":[[311,3]]},"4614":{"position":[[878,3],[954,3],[1327,3],[1388,3]]},"4632":{"position":[[641,3]]},"4637":{"position":[[26,3]]},"4643":{"position":[[292,3],[1307,3],[1441,3],[1660,3],[2734,3]]},"4654":{"position":[[645,3]]},"4656":{"position":[[178,3]]},"4660":{"position":[[1953,3]]},"4662":{"position":[[332,3]]},"4667":{"position":[[13165,3]]},"4669":{"position":[[96,3],[510,3],[750,3]]},"4701":{"position":[[184,3]]},"4713":{"position":[[31,3],[80,3],[165,3],[256,3]]},"4715":{"position":[[189,3]]},"4767":{"position":[[200,3]]},"4826":{"position":[[3628,3]]}}}],["newcom",{"_index":456,"t":{"59":{"position":[[69,9]]}}}],["newer",{"_index":3441,"t":{"871":{"position":[[1148,5]]},"963":{"position":[[2427,6]]},"1405":{"position":[[1172,6],[1545,7]]},"1637":{"position":[[738,5]]},"1772":{"position":[[1148,5]]},"1854":{"position":[[2427,6]]},"1968":{"position":[[811,5]]},"2236":{"position":[[309,5]]},"2987":{"position":[[2427,6]]},"3829":{"position":[[3708,5]]},"4268":{"position":[[557,5]]},"4353":{"position":[[197,5],[1035,5]]},"4483":{"position":[[327,5]]},"4593":{"position":[[3105,5]]}}}],["newest",{"_index":11397,"t":{"4257":{"position":[[1568,6],[1809,6],[2602,6]]},"4266":{"position":[[78,6]]},"4660":{"position":[[3022,6]]}}}],["newli",{"_index":2913,"t":{"588":{"position":[[1834,5]]},"932":{"position":[[4002,5]]},"1823":{"position":[[4002,5]]},"2119":{"position":[[760,5]]},"2624":{"position":[[213,5]]},"2859":{"position":[[4,5]]},"2956":{"position":[[4002,5]]},"3361":{"position":[[215,5]]},"3988":{"position":[[159,5]]},"4037":{"position":[[302,5]]},"4268":{"position":[[149,5]]},"4380":{"position":[[90,5]]},"4580":{"position":[[896,5]]}}}],["newlin",{"_index":7732,"t":{"2144":{"position":[[1411,7]]}}}],["newslett",{"_index":1538,"t":{"207":{"position":[[224,10],[395,10]]},"216":{"position":[[401,11]]},"224":{"position":[[437,11]]},"228":{"position":[[250,11]]}}}],["next",{"_index":1311,"t":{"181":{"position":[[2713,4]]},"258":{"position":[[682,4]]},"266":{"position":[[531,4]]},"364":{"position":[[712,4]]},"411":{"position":[[4,4]]},"421":{"position":[[284,4],[853,4]]},"504":{"position":[[142,5]]},"632":{"position":[[521,4]]},"696":{"position":[[502,4]]},"961":{"position":[[1889,4]]},"963":{"position":[[901,5]]},"1437":{"position":[[41,4]]},"1466":{"position":[[857,4]]},"1852":{"position":[[1889,4]]},"1854":{"position":[[901,5]]},"2055":{"position":[[700,4]]},"2059":{"position":[[1751,4],[1892,4],[2245,4]]},"2188":{"position":[[584,4]]},"2360":{"position":[[592,5]]},"2427":{"position":[[592,5]]},"2453":{"position":[[1033,5]]},"2647":{"position":[[1729,4]]},"2692":{"position":[[1850,4]]},"2985":{"position":[[1889,4]]},"2987":{"position":[[901,5]]},"3022":{"position":[[172,4],[823,4],[1321,4]]},"3097":{"position":[[306,4]]},"3130":{"position":[[366,4],[1105,4]]},"3168":{"position":[[933,4]]},"3187":{"position":[[141,4]]},"3234":{"position":[[332,4]]},"3248":{"position":[[575,4]]},"3251":{"position":[[207,4]]},"3266":{"position":[[740,4],[840,4]]},"3298":{"position":[[606,4]]},"3313":{"position":[[554,4],[856,4]]},"3323":{"position":[[752,4]]},"3375":{"position":[[584,4]]},"3378":{"position":[[1560,4]]},"3384":{"position":[[1567,4]]},"3533":{"position":[[1543,4]]},"3604":{"position":[[233,4]]},"3606":{"position":[[182,4]]},"3698":{"position":[[0,4]]},"3785":{"position":[[0,4]]},"3881":{"position":[[248,4]]},"4539":{"position":[[837,4]]},"4562":{"position":[[7242,4]]},"4667":{"position":[[533,4]]}}}],["nextcloud",{"_index":1192,"t":{"175":{"position":[[826,9]]},"260":{"position":[[142,9]]},"266":{"position":[[10,9],[346,9],[383,9]]},"4835":{"position":[[1115,9],[1198,9]]},"4839":{"position":[[569,12]]},"4849":{"position":[[1707,10]]}}}],["nextcloud.yaml.gotmpl",{"_index":11887,"t":{"4835":{"position":[[1238,21]]}}}],["nexu",{"_index":7913,"t":{"2192":{"position":[[597,5]]},"2194":{"position":[[1221,5]]},"3086":{"position":[[1349,6],[1405,6]]},"4560":{"position":[[5236,5],[5242,5]]}}}],["nexus.testbed.osism.xyz",{"_index":7912,"t":{"2192":{"position":[[573,23]]}}}],["nf",{"_index":8095,"t":{"2238":{"position":[[305,3]]},"2248":{"position":[[356,3]]}}}],["nfs_group_nam",{"_index":4845,"t":{"1185":{"position":[[1523,15]]}}}],["nftabl",{"_index":9984,"t":{"3352":{"position":[[2941,8]]}}}],["ng",{"_index":9341,"t":{"2934":{"position":[[897,2]]}}}],["nginx",{"_index":1904,"t":{"293":{"position":[[161,5]]},"688":{"position":[[175,5]]},"692":{"position":[[94,5],[196,5],[255,5],[355,5]]},"741":{"position":[[259,6],[281,5],[638,5],[828,5],[893,5],[907,5],[1321,5],[1385,5]]},"747":{"position":[[13,5],[115,5],[174,5],[274,5]]},"2725":{"position":[[806,5]]},"2730":{"position":[[44,5],[118,5],[154,5],[180,5]]},"2940":{"position":[[422,5]]},"3083":{"position":[[372,5]]},"3101":{"position":[[4,5]]},"3153":{"position":[[1599,5]]},"3185":{"position":[[235,5]]},"4580":{"position":[[2920,6]]},"4849":{"position":[[859,7]]},"4853":{"position":[[234,7]]},"4879":{"position":[[8,5],[311,5],[325,5],[375,5],[401,5]]}}}],["nginx.ingress.kubernetes.io/limit",{"_index":3223,"t":{"741":{"position":[[364,33],[1127,33]]}}}],["nginx/examples/auth/oauth",{"_index":8761,"t":{"2628":{"position":[[133,25]]}}}],["nginx/ingress",{"_index":9020,"t":{"2730":{"position":[[140,13]]}}}],["nic",{"_index":4462,"t":{"1105":{"position":[[693,3]]},"1107":{"position":[[560,3]]},"1109":{"position":[[299,3]]},"1111":{"position":[[419,3]]},"1113":{"position":[[461,3]]},"2240":{"position":[[1289,3]]},"2252":{"position":[[1583,3],[1602,4],[2674,3]]},"3183":{"position":[[366,3]]}}}],["nice",{"_index":1637,"t":{"226":{"position":[[256,4]]},"593":{"position":[[488,4]]},"940":{"position":[[1731,7]]},"1831":{"position":[[1731,7]]},"2964":{"position":[[1731,7]]},"3064":{"position":[[216,6]]},"3187":{"position":[[338,6]]},"3928":{"position":[[2623,10]]},"3945":{"position":[[215,4]]},"4562":{"position":[[1101,4]]},"4660":{"position":[[237,4]]}}}],["nightli",{"_index":10025,"t":{"3367":{"position":[[43,7]]},"3373":{"position":[[43,7]]},"3381":{"position":[[859,7]]},"3731":{"position":[[494,8]]}}}],["nip.io",{"_index":9217,"t":{"2857":{"position":[[122,6]]}}}],["nist",{"_index":11593,"t":{"4535":{"position":[[1257,5]]}}}],["nkgq6",{"_index":2952,"t":{"590":{"position":[[1389,5]]}}}],["nl/v/t/c[i",{"_index":10518,"t":{"3695":{"position":[[75,11]]},"3782":{"position":[[75,11]]}}}],["no",{"_index":9971,"t":{"3348":{"position":[[342,3]]}}}],["no_proxi",{"_index":5840,"t":{"1354":{"position":[[246,8],[780,9]]}}}],["noassign",{"_index":3623,"t":{"912":{"position":[[703,8],[2544,8]]},"914":{"position":[[663,8],[1777,8]]},"1796":{"position":[[703,8],[2544,8]]},"1798":{"position":[[663,8],[1777,8]]}}}],["nobackfil",{"_index":6554,"t":{"1609":{"position":[[57,10]]},"1646":{"position":[[413,10]]},"1648":{"position":[[1091,10]]},"1940":{"position":[[57,10]]}}}],["nobl",{"_index":3542,"t":{"887":{"position":[[8127,5]]},"1811":{"position":[[8127,5]]}}}],["nocleanup",{"_index":4266,"t":{"1005":{"position":[[618,10],[1779,9]]},"1896":{"position":[[618,10],[1779,9]]}}}],["nocreat",{"_index":3624,"t":{"912":{"position":[[727,8],[751,8],[771,8],[2601,8],[2658,8],[2707,8]]},"1796":{"position":[[727,8],[751,8],[771,8],[2601,8],[2658,8],[2707,8]]}}}],["node",{"_index":727,"t":{"130":{"position":[[49,4],[843,5],[1007,4]]},"368":{"position":[[528,5],[768,6],[1542,5],[7743,6]]},"384":{"position":[[4,4]]},"391":{"position":[[370,4],[390,4],[498,4]]},"397":{"position":[[142,4]]},"401":{"position":[[825,4],[1341,4],[1354,4]]},"403":{"position":[[621,4]]},"405":{"position":[[308,4],[405,4]]},"409":{"position":[[92,4]]},"413":{"position":[[65,4]]},"423":{"position":[[123,4]]},"425":{"position":[[125,4]]},"446":{"position":[[243,4]]},"448":{"position":[[203,4]]},"454":{"position":[[94,4],[114,5]]},"489":{"position":[[923,4]]},"493":{"position":[[285,4]]},"496":{"position":[[237,4]]},"500":{"position":[[253,4]]},"526":{"position":[[347,5],[1096,5]]},"533":{"position":[[363,4]]},"537":{"position":[[292,4]]},"539":{"position":[[562,4]]},"541":{"position":[[1002,5],[1227,5]]},"543":{"position":[[0,4],[80,4],[285,4],[538,4],[643,4],[815,4],[955,4],[1019,4],[1361,4],[1483,4],[1708,4],[1762,4],[1969,4],[2132,4],[2406,4],[2585,4],[2611,4],[2695,4]]},"549":{"position":[[1235,4]]},"551":{"position":[[540,4],[1250,4],[2106,4],[2463,4],[2530,4],[2694,4],[2980,4]]},"557":{"position":[[328,6],[421,6],[506,6],[719,6],[2035,5],[2161,5],[2239,6],[6894,6]]},"588":{"position":[[2069,5]]},"593":{"position":[[313,4]]},"602":{"position":[[242,4]]},"604":{"position":[[109,4],[175,4],[328,4]]},"618":{"position":[[75,4],[280,4]]},"632":{"position":[[449,4]]},"634":{"position":[[234,4]]},"641":{"position":[[443,4]]},"647":{"position":[[210,4]]},"655":{"position":[[325,4],[361,4],[426,4],[653,4],[798,4]]},"657":{"position":[[356,4]]},"659":{"position":[[567,4],[664,4]]},"664":{"position":[[313,4],[491,4]]},"666":{"position":[[443,4]]},"668":{"position":[[359,4],[900,4],[1172,4]]},"673":{"position":[[325,4],[361,4],[426,4],[653,4],[798,4]]},"679":{"position":[[210,4]]},"705":{"position":[[1763,4]]},"715":{"position":[[180,4]]},"717":{"position":[[281,4]]},"738":{"position":[[695,4]]},"814":{"position":[[63,6]]},"816":{"position":[[57,5],[489,5],[842,6]]},"818":{"position":[[400,5],[638,6],[821,6]]},"820":{"position":[[66,6],[289,5],[338,6]]},"822":{"position":[[12,4],[93,6],[298,4],[405,4]]},"832":{"position":[[134,5]]},"844":{"position":[[193,6]]},"936":{"position":[[209,4]]},"986":{"position":[[40,4],[63,4]]},"988":{"position":[[36,4],[59,4]]},"1009":{"position":[[137,5]]},"1022":{"position":[[8,5],[22,5],[36,5],[50,5],[64,5]]},"1028":{"position":[[10,4],[135,5],[251,5],[345,5],[391,5]]},"1030":{"position":[[60,5],[308,5],[515,5],[725,5]]},"1032":{"position":[[20,4]]},"1034":{"position":[[20,4]]},"1036":{"position":[[59,6],[155,5],[238,5]]},"1038":{"position":[[303,4]]},"1040":{"position":[[34,5],[131,6],[167,5]]},"1042":{"position":[[12,5],[137,6],[624,5]]},"1046":{"position":[[73,5]]},"1048":{"position":[[127,5]]},"1050":{"position":[[672,6]]},"1067":{"position":[[1621,5],[1916,6],[2043,5]]},"1105":{"position":[[10,4],[142,5],[250,5],[351,5],[479,6]]},"1107":{"position":[[8,5]]},"1109":{"position":[[20,4],[357,6]]},"1111":{"position":[[20,4],[155,6]]},"1113":{"position":[[12,5],[43,4],[62,5]]},"1118":{"position":[[72,6],[119,6],[329,5],[399,5],[457,6],[657,4],[701,4],[722,5]]},"1142":{"position":[[92,5],[352,5],[446,5]]},"1144":{"position":[[74,4]]},"1153":{"position":[[91,5]]},"1155":{"position":[[77,4]]},"1167":{"position":[[741,6]]},"1169":{"position":[[1592,5],[1717,5],[1923,5],[2078,7]]},"1175":{"position":[[22,4],[3428,4],[3462,4],[3610,5]]},"1177":{"position":[[152,5],[764,4],[792,4],[1009,4],[2080,5],[4020,5],[4367,4],[4395,4],[4612,4],[5523,5]]},"1185":{"position":[[1032,5],[1829,4],[1862,4],[1895,4]]},"1189":{"position":[[36,5],[673,5],[841,5],[852,4],[922,6],[990,5],[1030,5],[1042,4],[1165,4],[1188,4],[1211,4],[1344,4],[1367,4],[1390,4],[1406,4]]},"1191":{"position":[[86,5],[388,5],[738,5],[1010,6],[1050,4],[1138,4],[1178,4],[1233,4],[1277,4],[1402,4],[1623,4]]},"1197":{"position":[[75,4],[320,4],[344,4],[473,4],[497,4],[626,4],[650,4]]},"1199":{"position":[[58,5]]},"1201":{"position":[[106,5],[859,5]]},"1203":{"position":[[86,5]]},"1205":{"position":[[89,5]]},"1209":{"position":[[192,4]]},"1214":{"position":[[283,6]]},"1218":{"position":[[291,5]]},"1224":{"position":[[811,4]]},"1226":{"position":[[926,4],[995,4],[1080,4],[1195,4],[1241,4],[1318,4],[1647,4],[1692,5],[1784,6],[2428,5],[2699,4],[2814,4],[2860,4],[3017,5],[3102,5],[3157,5],[3247,5],[3366,5],[3576,5],[3731,6],[3858,5],[4255,4],[4569,4],[5283,4],[5421,4],[5442,5]]},"1234":{"position":[[114,5],[280,5]]},"1248":{"position":[[627,6],[1439,5]]},"1252":{"position":[[1513,4],[1633,4],[1698,5],[1846,5],[2070,4],[2107,4],[2214,4],[2247,4]]},"1259":{"position":[[695,4]]},"1263":{"position":[[255,5]]},"1266":{"position":[[2707,6],[2756,4]]},"1275":{"position":[[28,5],[92,4]]},"1301":{"position":[[1514,4]]},"1342":{"position":[[111,5],[153,5]]},"1344":{"position":[[133,4],[164,5],[188,5]]},"1354":{"position":[[310,5]]},"1363":{"position":[[52,4],[131,5]]},"1371":{"position":[[175,5]]},"1373":{"position":[[477,4],[892,4],[971,6]]},"1375":{"position":[[213,5]]},"1377":{"position":[[64,4]]},"1383":{"position":[[651,5],[681,4],[700,5],[776,4],[1125,4],[1161,4],[1743,5],[2122,5]]},"1385":{"position":[[60,4],[73,4],[317,5],[693,4],[706,4],[805,4],[843,4],[957,4],[1013,4],[1090,4],[1163,4],[1742,4],[2067,4],[2324,5],[2433,4]]},"1391":{"position":[[1040,4],[1092,4],[1144,4],[1303,4],[2619,4],[2670,4],[2721,4],[2772,4],[2823,4]]},"1397":{"position":[[167,5]]},"1417":{"position":[[177,4],[202,4],[227,4]]},"1419":{"position":[[139,4],[230,4],[321,4]]},"1421":{"position":[[53,5],[349,5],[418,4],[445,4],[472,4],[960,4],[1104,5],[1224,5],[1347,6],[1450,4],[1716,4]]},"1433":{"position":[[353,4],[723,5],[1029,5],[1193,5]]},"1447":{"position":[[88,5]]},"1455":{"position":[[85,5]]},"1457":{"position":[[43,5],[74,4],[114,4],[210,5],[363,5],[509,6],[565,6],[615,5],[1251,5],[2672,6],[2821,6],[4116,5],[4211,5]]},"1460":{"position":[[359,4],[399,4],[443,5],[485,5]]},"1462":{"position":[[87,5],[199,5],[351,5],[488,5]]},"1464":{"position":[[188,5],[623,4],[695,4]]},"1466":{"position":[[907,4],[1768,6],[2066,4],[2293,6],[2618,4],[2714,4]]},"1468":{"position":[[48,4],[63,5],[81,4],[178,4],[464,5],[633,4],[895,4],[1174,4],[1357,4]]},"1470":{"position":[[91,5],[124,4],[183,5]]},"1472":{"position":[[37,5],[163,6],[194,4],[367,5],[1565,5],[1656,5],[1701,4],[2027,5]]},"1474":{"position":[[418,4],[682,4],[959,6]]},"1476":{"position":[[390,5],[434,5]]},"1480":{"position":[[65,5],[106,4],[317,6],[333,4]]},"1484":{"position":[[541,5]]},"1486":{"position":[[166,5],[209,6]]},"1497":{"position":[[192,4],[251,5],[266,4],[359,4],[383,4],[494,4],[552,4],[591,4],[753,4],[907,5]]},"1501":{"position":[[551,5]]},"1507":{"position":[[206,4]]},"1509":{"position":[[241,5],[502,5],[559,4],[706,5]]},"1511":{"position":[[86,6],[114,5]]},"1515":{"position":[[73,6]]},"1529":{"position":[[51,5],[550,6]]},"1534":{"position":[[2,4],[135,4],[198,4]]},"1536":{"position":[[22,4],[51,4]]},"1538":{"position":[[20,4],[47,4]]},"1544":{"position":[[28,4],[121,4],[168,4],[181,4],[364,4],[396,4],[409,4],[533,4]]},"1552":{"position":[[685,4],[884,4],[915,4],[1113,4],[1145,4],[1315,4],[1346,4],[1515,4]]},"1555":{"position":[[388,5]]},"1557":{"position":[[160,4]]},"1561":{"position":[[1179,4],[1251,5]]},"1574":{"position":[[536,4]]},"1580":{"position":[[114,4]]},"1603":{"position":[[29,6],[101,4]]},"1605":{"position":[[20,4],[139,4],[248,4],[357,4],[482,4],[932,4],[1041,4],[1144,4],[1278,5],[1575,4],[1684,4],[1787,4],[1805,4],[1862,4],[1902,4],[1936,4],[2042,4]]},"1637":{"position":[[178,5]]},"1644":{"position":[[417,4]]},"1646":{"position":[[154,5],[564,5],[583,5],[707,5],[1036,5],[1059,5],[1166,5],[1296,5],[1319,5],[1426,5],[1556,5],[1579,5],[1689,4],[1925,5],[1948,5],[2055,5]]},"1648":{"position":[[325,5],[348,5],[452,5],[475,5],[507,4],[607,4],[677,5],[700,5],[1442,4],[1692,4]]},"1665":{"position":[[90,5]]},"1669":{"position":[[66,4],[153,4],[186,4],[297,4],[347,4]]},"1671":{"position":[[183,6],[198,4]]},"1673":{"position":[[74,4],[116,4],[468,4]]},"1675":{"position":[[54,4],[150,4],[267,4]]},"1679":{"position":[[190,4],[227,4],[264,4],[726,4],[763,4],[800,4]]},"1681":{"position":[[32,4],[128,4]]},"1683":{"position":[[28,4],[117,4]]},"1694":{"position":[[8079,4],[8278,4],[8377,4],[8928,4]]},"1696":{"position":[[30,4]]},"1698":{"position":[[126,4],[201,4],[399,4],[563,4],[783,4],[858,4],[1013,4],[1098,4],[1251,4],[1451,4],[2150,4]]},"1702":{"position":[[93,4]]},"1704":{"position":[[735,4],[831,4],[927,4],[1088,4],[1113,4],[1214,4],[1239,4],[1340,4],[1365,4]]},"1709":{"position":[[50,4],[160,4],[202,4],[229,4],[276,4],[397,4],[492,4]]},"1711":{"position":[[55,4],[103,4],[198,4],[273,4],[304,4],[335,4],[391,4],[415,4],[443,4],[502,5],[552,4],[620,4],[682,4],[699,4],[888,4],[974,5],[2150,4]]},"1713":{"position":[[51,4],[205,4],[296,4],[406,4],[480,4],[721,4],[1096,4],[1423,4],[1631,4],[2048,4],[2099,4],[2129,4],[2442,4],[2608,4],[2692,4]]},"1716":{"position":[[363,4],[456,4],[549,4],[639,4],[733,4],[827,4],[1090,4],[1141,4],[1243,4],[1294,4],[1396,4],[1447,4],[1832,4],[1925,4],[2018,4]]},"1728":{"position":[[69,4]]},"1730":{"position":[[85,4]]},"1732":{"position":[[91,4],[726,4],[1075,4],[1537,4]]},"1734":{"position":[[92,4],[727,4],[1096,4],[1731,4]]},"1745":{"position":[[155,5],[220,6]]},"1827":{"position":[[209,4]]},"1877":{"position":[[40,4],[63,4]]},"1879":{"position":[[36,4],[59,4]]},"1906":{"position":[[128,5]]},"1917":{"position":[[536,4]]},"1923":{"position":[[114,4]]},"1968":{"position":[[251,5]]},"2029":{"position":[[378,5],[781,5]]},"2052":{"position":[[158,4]]},"2112":{"position":[[367,4]]},"2119":{"position":[[892,6],[1041,5]]},"2132":{"position":[[352,4]]},"2139":{"position":[[959,4],[1226,5],[1557,4]]},"2142":{"position":[[106,4],[386,4],[399,4],[431,4],[447,4],[501,4]]},"2146":{"position":[[434,4]]},"2163":{"position":[[4217,5],[4235,6]]},"2167":{"position":[[138,5],[159,5]]},"2171":{"position":[[2103,5],[2177,5],[2527,4]]},"2184":{"position":[[3229,6],[3616,5],[3676,4]]},"2192":{"position":[[725,4],[758,4],[787,4],[820,4],[849,4],[882,4],[911,4],[944,4],[973,4],[1006,4],[1035,4],[1068,4],[1097,4],[1130,4],[1159,4],[1192,4],[1221,4],[1254,4],[1283,4],[1316,4]]},"2194":{"position":[[531,4],[554,4],[620,4],[643,4],[709,4],[732,4]]},"2199":{"position":[[1151,4]]},"2207":{"position":[[34,4],[319,4],[523,4],[998,4],[1025,4],[1106,4],[1218,4],[1262,4],[1437,4],[1585,4],[1694,4]]},"2211":{"position":[[2438,4]]},"2370":{"position":[[34,5]]},"2529":{"position":[[772,6]]},"2582":{"position":[[127,4]]},"2608":{"position":[[960,5],[991,4],[1249,4]]},"2614":{"position":[[461,4],[540,4],[573,5],[582,4]]},"2632":{"position":[[168,5]]},"2644":{"position":[[391,6]]},"2672":{"position":[[391,6]]},"2960":{"position":[[209,4]]},"3026":{"position":[[64,4]]},"3083":{"position":[[409,5],[495,4]]},"3086":{"position":[[23,4],[294,4],[466,5]]},"3088":{"position":[[69,4]]},"3091":{"position":[[327,5],[461,5]]},"3101":{"position":[[142,6]]},"3150":{"position":[[289,4]]},"3185":{"position":[[363,4]]},"3223":{"position":[[215,4],[1049,4],[1124,4]]},"3266":{"position":[[402,4]]},"3281":{"position":[[806,4],[903,4]]},"3285":{"position":[[15,4],[52,5],[102,5],[291,6],[334,4]]},"3315":{"position":[[167,4]]},"3348":{"position":[[964,5]]},"3352":{"position":[[548,5],[2091,4],[2119,5],[2192,5],[2553,4],[2612,4],[3031,6],[3414,5]]},"3406":{"position":[[294,5]]},"3468":{"position":[[1022,5],[1069,4]]},"3665":{"position":[[649,4]]},"3702":{"position":[[721,4]]},"3772":{"position":[[8,5],[199,5]]},"3789":{"position":[[721,4]]},"3925":{"position":[[1034,5],[1122,5]]},"3928":{"position":[[4,4],[80,5],[114,5],[158,4],[343,4],[509,4],[543,4],[599,4],[760,4],[960,4],[1110,5],[1164,5],[1302,5],[2138,5],[4316,4],[4380,4],[4426,4],[4481,6],[4598,4],[5409,4]]},"3930":{"position":[[156,5]]},"3932":{"position":[[9,5]]},"3941":{"position":[[1103,4]]},"3947":{"position":[[1236,6],[2776,4]]},"3964":{"position":[[148,6],[251,6]]},"4028":{"position":[[114,4]]},"4089":{"position":[[365,5]]},"4109":{"position":[[1260,5],[1532,5]]},"4133":{"position":[[689,5],[961,5]]},"4135":{"position":[[19,4]]},"4137":{"position":[[149,4],[226,4],[411,5],[455,5]]},"4139":{"position":[[114,5],[158,5]]},"4146":{"position":[[981,5]]},"4217":{"position":[[241,4]]},"4220":{"position":[[1478,5],[1508,4],[1941,4],[2001,4]]},"4222":{"position":[[408,6],[608,5]]},"4224":{"position":[[878,6]]},"4228":{"position":[[395,4],[478,4],[486,4],[512,5],[562,5],[606,4],[662,4],[1149,4],[1157,4],[1523,4],[1531,4]]},"4230":{"position":[[418,6],[1006,5],[1467,6],[1553,6],[1612,4],[1833,5],[2219,4],[2261,4],[2382,5],[2540,5],[2565,5],[4430,6]]},"4232":{"position":[[125,5]]},"4236":{"position":[[137,5],[252,4],[525,5]]},"4238":{"position":[[60,4]]},"4240":{"position":[[337,5]]},"4242":{"position":[[118,4]]},"4289":{"position":[[58,5]]},"4302":{"position":[[820,5],[927,5],[1182,5],[1399,5],[2709,5],[2958,5],[3623,5]]},"4304":{"position":[[225,5],[2414,5],[2475,5],[2698,6]]},"4310":{"position":[[536,4]]},"4313":{"position":[[1220,4],[1439,4],[1476,5]]},"4327":{"position":[[47,5],[358,5],[682,6],[841,5]]},"4331":{"position":[[71,5],[149,5],[224,6]]},"4333":{"position":[[243,6],[329,6],[366,5],[588,5]]},"4376":{"position":[[632,5],[754,4]]},"4385":{"position":[[320,4]]},"4401":{"position":[[197,4],[273,4]]},"4427":{"position":[[104,6],[176,5],[219,5]]},"4431":{"position":[[132,5],[268,5],[342,5],[489,4],[507,4],[621,6],[731,6],[1015,5],[1074,4],[1204,5],[1820,6],[1970,5]]},"4433":{"position":[[477,6],[500,5],[864,4],[1351,5],[1476,5],[1580,6],[2008,5],[2204,5],[2333,5],[2519,6],[2597,5],[2958,5],[3060,5],[3089,5]]},"4435":{"position":[[298,4],[533,4],[1077,5],[1198,5],[1461,5]]},"4440":{"position":[[95,6],[167,5],[210,5],[438,5],[510,5]]},"4446":{"position":[[101,5]]},"4448":{"position":[[76,5],[460,5],[769,5],[880,4],[929,5],[1007,4]]},"4451":{"position":[[95,6],[167,5],[210,5],[438,5],[510,5]]},"4457":{"position":[[101,5]]},"4459":{"position":[[76,5],[186,5],[519,5],[630,4],[679,5],[780,4],[945,5]]},"4461":{"position":[[88,4]]},"4464":{"position":[[188,5],[360,4]]},"4466":{"position":[[121,4]]},"4516":{"position":[[997,4]]},"4535":{"position":[[1809,4]]},"4537":{"position":[[917,6],[1380,6]]},"4539":{"position":[[4816,4],[4825,4],[6458,4],[7019,4],[7084,4],[7216,4]]},"4541":{"position":[[19,4],[48,5],[364,4]]},"4547":{"position":[[2445,4]]},"4726":{"position":[[399,4]]},"4728":{"position":[[1590,7]]},"4733":{"position":[[339,5],[674,6],[1028,4],[1237,4]]},"4775":{"position":[[165,4]]},"4826":{"position":[[3014,5],[3066,4]]},"4839":{"position":[[1611,4]]},"4870":{"position":[[170,6]]}}}],["node'",{"_index":6115,"t":{"1421":{"position":[[1276,6]]}}}],["node.data",{"_index":5553,"t":{"1303":{"position":[[1477,10],[3117,10]]}}}],["node.j",{"_index":724,"t":{"127":{"position":[[4,7]]},"130":{"position":[[29,7],[124,7],[898,7]]},"3573":{"position":[[948,7]]},"4420":{"position":[[2409,8]]}}}],["node.mast",{"_index":5552,"t":{"1303":{"position":[[1459,12],[2355,12],[2463,12],[2582,12],[3133,12]]}}}],["node.nam",{"_index":5544,"t":{"1303":{"position":[[1112,10],[3151,10]]}}}],["node.systems.osism.xyz",{"_index":6252,"t":{"1466":{"position":[[932,23]]}}}],["node01",{"_index":5083,"t":{"1226":{"position":[[1085,6],[1589,6],[2704,6],[3061,6],[3203,6]]},"1659":{"position":[[26,6],[460,8],[736,6]]}}}],["node_cidr",{"_index":2773,"t":{"557":{"position":[[3090,9],[4341,9],[4690,9]]}}}],["node_config_directori",{"_index":5533,"t":{"1303":{"position":[[584,21]]}}}],["node_custom_config",{"_index":5530,"t":{"1303":{"position":[[401,18],[445,18],[500,18]]}}}],["node_ips=$(kubectl",{"_index":8720,"t":{"2614":{"position":[[550,18]]}}}],["nodeaffin",{"_index":6145,"t":{"1433":{"position":[[921,13]]},"4431":{"position":[[835,12]]}}}],["nodebug",{"_index":4267,"t":{"1005":{"position":[[632,8],[1816,7]]},"1896":{"position":[[632,8],[1816,7]]}}}],["nodecidr",{"_index":2783,"t":{"557":{"position":[[4386,9],[4489,9]]}}}],["nodeep",{"_index":6491,"t":{"1578":{"position":[[38,6],[93,6]]},"1921":{"position":[[38,6],[93,6]]}}}],["nodeimag",{"_index":2527,"t":{"496":{"position":[[186,10]]},"551":{"position":[[2324,10],[2891,10]]}}}],["nodelet",{"_index":4268,"t":{"1005":{"position":[[644,9],[1849,8]]},"1896":{"position":[[644,9],[1849,8]]}}}],["nodenam",{"_index":4663,"t":{"1175":{"position":[[3473,10]]},"1179":{"position":[[491,9],[1202,11],[2262,10]]},"1600":{"position":[[162,11],[199,10]]}}}],["nodeplugin",{"_index":2947,"t":{"590":{"position":[[1168,10],[1238,10],[1308,10],[1378,10]]}}}],["nodepool",{"_index":7611,"t":{"2119":{"position":[[698,9],[729,8],[788,8],[930,8],[1006,8]]},"2123":{"position":[[1666,8]]},"2678":{"position":[[571,8]]}}}],["nodepool.pub",{"_index":7614,"t":{"2119":{"position":[[970,13]]},"2123":{"position":[[529,15]]}}}],["nodeport",{"_index":9033,"t":{"2743":{"position":[[184,8]]},"2756":{"position":[[1075,8],[1131,8]]},"4537":{"position":[[1570,8]]},"4547":{"position":[[1495,8]]}}}],["nodeports.yaml",{"_index":9056,"t":{"2756":{"position":[[2145,14]]}}}],["noderestrict",{"_index":11619,"t":{"4539":{"position":[[6974,15],[7499,15]]},"4547":{"position":[[3366,15]]}}}],["nodes/disk",{"_index":8755,"t":{"2626":{"position":[[1660,10]]}}}],["nodes_boot_from_imag",{"_index":8061,"t":{"2219":{"position":[[1016,21]]}}}],["nodes_boot_from_volum",{"_index":8062,"t":{"2219":{"position":[[1038,22]]}}}],["nodes_use_ephemeral_storag",{"_index":8063,"t":{"2219":{"position":[[1061,27]]}}}],["nodeselector",{"_index":11514,"t":{"4431":{"position":[[782,13]]}}}],["nodeselectorterm",{"_index":6147,"t":{"1433":{"position":[[983,18]]}}}],["nodeset",{"_index":2170,"t":{"368":{"position":[[541,8],[759,8],[1529,8]]},"2059":{"position":[[1826,8],[1982,8]]}}}],["nodomain",{"_index":3625,"t":{"912":{"position":[[789,8],[2752,8]]},"1796":{"position":[[789,8],[2752,8]]}}}],["nodown",{"_index":6595,"t":{"1646":{"position":[[491,6]]},"1648":{"position":[[1044,6]]}}}],["nodri",{"_index":3679,"t":{"914":{"position":[[687,5],[1834,5]]},"1798":{"position":[[687,5],[1834,5]]}}}],["nofloat",{"_index":4269,"t":{"1005":{"position":[[657,11],[1884,10]]},"1896":{"position":[[657,11],[1884,10]]}}}],["noha",{"_index":3626,"t":{"912":{"position":[[814,5],[839,5],[865,5],[2811,5],[2870,5],[2931,5]]},"1796":{"position":[[814,5],[839,5],[865,5],[2811,5],[2870,5],[2931,5]]}}}],["nomanag",{"_index":3627,"t":{"912":{"position":[[889,9],[2988,9]]},"914":{"position":[[701,8],[724,8],[1871,8],[1926,8]]},"1796":{"position":[[889,9],[2988,9]]},"1798":{"position":[[701,8],[724,8],[1871,8],[1926,8]]}}}],["nomin",{"_index":10285,"t":{"3627":{"position":[[329,8]]},"3629":{"position":[[296,8]]},"3636":{"position":[[81,9],[124,8],[146,10],[350,10]]},"3648":{"position":[[50,10]]}}}],["non",{"_index":157,"t":{"24":{"position":[[38,3]]},"175":{"position":[[727,3]]},"177":{"position":[[155,4],[1386,3]]},"197":{"position":[[468,3]]},"284":{"position":[[79,3],[435,3],[514,3]]},"288":{"position":[[546,3]]},"293":{"position":[[1068,3]]},"301":{"position":[[155,3]]},"309":{"position":[[261,3]]},"360":{"position":[[944,3]]},"572":{"position":[[531,3]]},"826":{"position":[[122,3]]},"1030":{"position":[[44,3]]},"1348":{"position":[[448,3]]},"1354":{"position":[[759,3]]},"1421":{"position":[[635,3],[710,3]]},"1455":{"position":[[549,3]]},"1457":{"position":[[3759,4]]},"2110":{"position":[[3906,4]]},"2192":{"position":[[226,3]]},"2349":{"position":[[287,3]]},"2355":{"position":[[377,3],[1604,3]]},"2416":{"position":[[287,3]]},"2422":{"position":[[377,3],[1604,3]]},"2626":{"position":[[1631,3]]},"2651":{"position":[[165,3]]},"2930":{"position":[[96,3]]},"3073":{"position":[[314,3]]},"3077":{"position":[[79,3]]},"3121":{"position":[[455,3]]},"3268":{"position":[[151,3]]},"3276":{"position":[[501,3]]},"3290":{"position":[[748,3]]},"3294":{"position":[[595,3]]},"3346":{"position":[[983,3]]},"3537":{"position":[[535,3]]},"3544":{"position":[[150,3]]},"3549":{"position":[[1203,3]]},"3598":{"position":[[1638,3],[1871,3]]},"3669":{"position":[[326,3]]},"3679":{"position":[[925,3]]},"3681":{"position":[[477,3]]},"3704":{"position":[[832,3]]},"3710":{"position":[[339,3]]},"3718":{"position":[[515,3]]},"3731":{"position":[[737,3]]},"3747":{"position":[[408,3]]},"3793":{"position":[[1115,3]]},"3803":{"position":[[326,3]]},"3811":{"position":[[515,3]]},"3824":{"position":[[264,3]]},"3829":{"position":[[3207,3]]},"3879":{"position":[[165,3]]},"3881":{"position":[[227,3]]},"3883":{"position":[[474,3]]},"3894":{"position":[[612,3]]},"3906":{"position":[[457,3]]},"4005":{"position":[[387,3]]},"4009":{"position":[[279,3]]},"4130":{"position":[[131,3]]},"4157":{"position":[[16,3]]},"4238":{"position":[[435,3]]},"4257":{"position":[[653,3]]},"4279":{"position":[[932,3]]},"4281":{"position":[[913,3]]},"4306":{"position":[[196,3]]},"4359":{"position":[[488,3]]},"4385":{"position":[[573,3]]},"4435":{"position":[[861,3]]},"4531":{"position":[[16,3]]},"4539":{"position":[[392,3]]},"4547":{"position":[[3033,3]]},"4562":{"position":[[6518,4],[6645,3],[6660,3]]},"4612":{"position":[[385,3],[657,4]]},"4643":{"position":[[1882,3]]},"4703":{"position":[[130,3]]},"4730":{"position":[[1026,3]]},"4744":{"position":[[1089,3]]}}}],["none",{"_index":2762,"t":{"557":{"position":[[2300,6],[2663,5],[3204,6],[3494,5]]},"692":{"position":[[406,6]]},"701":{"position":[[1728,4]]},"747":{"position":[[325,6]]},"865":{"position":[[1090,4],[1111,4]]},"887":{"position":[[369,5],[458,5],[9445,4]]},"894":{"position":[[2071,4],[2094,4]]},"912":{"position":[[2031,5]]},"914":{"position":[[1483,5]]},"1005":{"position":[[1549,5]]},"1324":{"position":[[12932,4]]},"1409":{"position":[[385,4],[456,4]]},"1466":{"position":[[3,4]]},"1734":{"position":[[790,4],[1792,4]]},"1752":{"position":[[2071,4],[2094,4]]},"1766":{"position":[[1090,4],[1111,4]]},"1796":{"position":[[2031,5]]},"1798":{"position":[[1483,5]]},"1811":{"position":[[369,5],[458,5],[9445,4]]},"1896":{"position":[[1549,5]]},"2240":{"position":[[426,4]]},"2254":{"position":[[1353,4],[1537,4]]},"2692":{"position":[[1331,4]]},"2914":{"position":[[1177,4]]},"3712":{"position":[[254,6]]},"3749":{"position":[[0,4]]},"3829":{"position":[[3270,5],[3611,4]]},"3833":{"position":[[672,4]]},"3847":{"position":[[0,5]]},"3861":{"position":[[0,5]]},"3988":{"position":[[887,4],[919,4],[926,4],[1011,4],[1053,4],[1139,4],[1176,4],[1183,4],[1268,4],[1315,4]]},"4026":{"position":[[806,4],[980,4]]},"4030":{"position":[[656,4],[963,4]]},"4051":{"position":[[791,4],[823,4],[830,4],[915,4],[952,4],[959,4],[1044,4],[1091,4],[1177,4],[1219,4]]},"4193":{"position":[[0,5]]},"4367":{"position":[[0,5]]},"4392":{"position":[[0,5]]},"4468":{"position":[[0,5]]},"4752":{"position":[[0,4]]},"4771":{"position":[[0,4]]},"4799":{"position":[[0,5]]},"4805":{"position":[[0,5]]}}}],["none:%(target.role.domain_id)",{"_index":5690,"t":{"1324":{"position":[[3003,32],[3963,32],[4480,32]]},"4667":{"position":[[3031,32],[3991,32],[4508,32]]}}}],["nonetheless",{"_index":11618,"t":{"4539":{"position":[[6199,12]]},"4580":{"position":[[524,12]]}}}],["nonsens",{"_index":11571,"t":{"4504":{"position":[[680,11]]}}}],["noofday",{"_index":9304,"t":{"2930":{"position":[[428,8],[1308,8]]}}}],["noop",{"_index":2184,"t":{"368":{"position":[[1355,4]]}}}],["noout",{"_index":6497,"t":{"1580":{"position":[[52,5],[171,5],[239,5],[424,5],[454,5],[476,5],[505,5],[524,5],[609,5],[642,5],[687,5]]},"1646":{"position":[[392,5]]},"1648":{"position":[[1068,5]]},"1923":{"position":[[52,5],[171,5],[239,5],[424,5],[454,5],[476,5],[505,5],[524,5],[609,5],[642,5],[687,5]]}}}],["nopasswd",{"_index":6230,"t":{"1457":{"position":[[1767,9]]}}}],["noprovid",{"_index":2305,"t":{"405":{"position":[[462,10]]},"463":{"position":[[1106,10]]},"465":{"position":[[325,11]]}}}],["noqa",{"_index":881,"t":{"153":{"position":[[306,4]]},"163":{"position":[[163,5]]},"4861":{"position":[[162,5]]}}}],["norandom",{"_index":3628,"t":{"912":{"position":[[921,9],[3061,8]]},"1796":{"position":[[921,9],[3061,8]]}}}],["norebal",{"_index":6556,"t":{"1609":{"position":[[109,11]]},"1646":{"position":[[464,11]]},"1648":{"position":[[1146,11]]},"1940":{"position":[[109,11]]}}}],["norecov",{"_index":6594,"t":{"1646":{"position":[[439,9]]},"1648":{"position":[[1119,9]]}}}],["norecoveri",{"_index":6555,"t":{"1609":{"position":[[83,10]]},"1940":{"position":[[83,10]]}}}],["nori",{"_index":7849,"t":{"2178":{"position":[[716,5]]},"3367":{"position":[[1180,5]]}}}],["noris/wavecon",{"_index":9818,"t":{"3168":{"position":[[761,13]]}}}],["norm",{"_index":10139,"t":{"3468":{"position":[[84,5]]},"3533":{"position":[[3009,9]]},"3535":{"position":[[101,9]]},"3541":{"position":[[34,9]]}}}],["normal",{"_index":2293,"t":{"397":{"position":[[689,6]]},"417":{"position":[[1190,6]]},"479":{"position":[[153,8]]},"608":{"position":[[53,6]]},"755":{"position":[[358,8]]},"859":{"position":[[154,6]]},"930":{"position":[[250,6],[358,6]]},"940":{"position":[[1318,8]]},"976":{"position":[[46,6]]},"980":{"position":[[250,6]]},"1111":{"position":[[61,8]]},"1185":{"position":[[634,6]]},"1191":{"position":[[1460,6]]},"1252":{"position":[[1146,6]]},"1257":{"position":[[1004,8]]},"1271":{"position":[[84,6]]},"1648":{"position":[[1381,6]]},"1745":{"position":[[187,8]]},"1760":{"position":[[154,6]]},"1821":{"position":[[250,6],[358,6]]},"1831":{"position":[[1318,8]]},"1867":{"position":[[46,6]]},"1871":{"position":[[250,6]]},"2065":{"position":[[3076,6]]},"2171":{"position":[[1144,8]]},"2431":{"position":[[4370,6]]},"2930":{"position":[[1639,6]]},"2954":{"position":[[250,6],[358,6]]},"2964":{"position":[[1318,8]]},"3000":{"position":[[46,6]]},"3004":{"position":[[250,6]]},"3168":{"position":[[536,7]]},"3714":{"position":[[1087,8]]},"3824":{"position":[[157,8]]},"3928":{"position":[[452,6],[1497,8],[3555,8]]},"3934":{"position":[[180,6]]},"3947":{"position":[[1659,6],[2923,6]]},"4165":{"position":[[185,8]]},"4444":{"position":[[3,6]]},"4455":{"position":[[3,6]]},"4471":{"position":[[215,6]]},"4485":{"position":[[144,9]]},"4539":{"position":[[2465,8]]},"4545":{"position":[[534,8]]},"4547":{"position":[[1145,6]]}}}],["north",{"_index":9832,"t":{"3183":{"position":[[230,5]]},"4560":{"position":[[3572,5]]}}}],["noscrub",{"_index":6490,"t":{"1578":{"position":[[15,7],[68,7]]},"1921":{"position":[[15,7],[68,7]]}}}],["noset",{"_index":6361,"t":{"1536":{"position":[[33,5]]},"1538":{"position":[[31,5]]}}}],["nosuid",{"_index":6258,"t":{"1466":{"position":[[2365,6]]}}}],["notabl",{"_index":8337,"t":{"2287":{"position":[[184,7]]},"2301":{"position":[[184,7]]},"3947":{"position":[[4651,7]]},"4226":{"position":[[1886,7]]},"4801":{"position":[[466,7]]}}}],["notari",{"_index":11679,"t":{"4562":{"position":[[7321,6]]}}}],["notat",{"_index":2964,"t":{"611":{"position":[[39,8],[132,8],[504,8],[612,8]]},"2549":{"position":[[453,10]]},"2932":{"position":[[192,9]]}}}],["note",{"_index":162,"t":{"24":{"position":[[163,4],[384,4]]},"37":{"position":[[233,7],[707,7]]},"139":{"position":[[43,5],[113,4]]},"295":{"position":[[1634,5]]},"349":{"position":[[16,5]]},"438":{"position":[[189,7]]},"440":{"position":[[252,7]]},"442":{"position":[[212,6]]},"479":{"position":[[1509,4],[1664,5]]},"489":{"position":[[988,5]]},"514":{"position":[[230,7],[677,7]]},"520":{"position":[[671,7]]},"530":{"position":[[341,7],[358,4]]},"541":{"position":[[1312,4]]},"551":{"position":[[0,5]]},"557":{"position":[[3819,4]]},"572":{"position":[[565,4]]},"588":{"position":[[106,5],[224,5]]},"688":{"position":[[364,5]]},"696":{"position":[[1218,4]]},"701":{"position":[[692,4],[2470,4]]},"705":{"position":[[185,4],[360,4]]},"706":{"position":[[0,4],[577,4]]},"715":{"position":[[701,5]]},"724":{"position":[[397,5]]},"728":{"position":[[523,4],[890,4]]},"732":{"position":[[1711,4]]},"887":{"position":[[1144,4]]},"912":{"position":[[187,4]]},"924":{"position":[[538,5]]},"930":{"position":[[743,6]]},"938":{"position":[[1211,6]]},"940":{"position":[[0,4]]},"944":{"position":[[434,4]]},"949":{"position":[[567,4],[850,5]]},"951":{"position":[[308,4]]},"963":{"position":[[3670,4]]},"971":{"position":[[103,4]]},"978":{"position":[[1664,5]]},"1157":{"position":[[141,4]]},"1159":{"position":[[136,4]]},"1177":{"position":[[379,4]]},"1226":{"position":[[4231,5],[4386,5],[4538,5],[4679,5],[5252,5],[5390,5]]},"1257":{"position":[[32,5],[123,5]]},"1301":{"position":[[1752,4]]},"1344":{"position":[[201,4]]},"1375":{"position":[[328,4]]},"1381":{"position":[[169,4]]},"1391":{"position":[[2258,4],[3424,4]]},"1466":{"position":[[2452,4]]},"1484":{"position":[[564,5]]},"1491":{"position":[[104,6]]},"1493":{"position":[[103,6],[374,4]]},"1503":{"position":[[166,5]]},"1525":{"position":[[246,5]]},"1569":{"position":[[347,4]]},"1587":{"position":[[29,4]]},"1593":{"position":[[826,4]]},"1617":{"position":[[51,4]]},"1621":{"position":[[24,4]]},"1623":{"position":[[0,4]]},"1635":{"position":[[152,4]]},"1637":{"position":[[594,4]]},"1646":{"position":[[102,5],[676,4],[1135,4],[1395,4],[1657,4],[2024,4]]},"1648":{"position":[[26,5]]},"1796":{"position":[[187,4]]},"1811":{"position":[[1144,4]]},"1815":{"position":[[538,5]]},"1821":{"position":[[743,6]]},"1829":{"position":[[1211,6]]},"1831":{"position":[[0,4]]},"1835":{"position":[[434,4]]},"1840":{"position":[[567,4],[850,5]]},"1842":{"position":[[308,4]]},"1854":{"position":[[3670,4]]},"1862":{"position":[[103,4]]},"1869":{"position":[[1664,5]]},"1902":{"position":[[497,4]]},"1912":{"position":[[60,4]]},"1914":{"position":[[65,4]]},"1930":{"position":[[29,4]]},"1936":{"position":[[826,4]]},"1948":{"position":[[51,4]]},"1952":{"position":[[24,4]]},"1954":{"position":[[0,4]]},"1968":{"position":[[0,4],[667,4]]},"1984":{"position":[[0,4]]},"1992":{"position":[[73,4]]},"2027":{"position":[[105,4]]},"2039":{"position":[[109,4]]},"2045":{"position":[[87,4]]},"2059":{"position":[[2426,5]]},"2061":{"position":[[34,6]]},"2065":{"position":[[43,4],[119,5],[348,5],[1000,4],[1038,5],[1255,5],[1574,5],[1791,5],[1895,5],[2122,5],[2226,5],[2444,5],[2548,5],[2766,5],[2870,5],[3191,5],[3403,5],[3507,5]]},"2069":{"position":[[25,5]]},"2112":{"position":[[0,4]]},"2163":{"position":[[4084,4]]},"2171":{"position":[[32,5],[123,5]]},"2178":{"position":[[411,4]]},"2180":{"position":[[114,4]]},"2184":{"position":[[3465,5]]},"2194":{"position":[[301,4]]},"2219":{"position":[[171,4]]},"2242":{"position":[[0,4]]},"2246":{"position":[[0,4]]},"2248":{"position":[[0,4]]},"2276":{"position":[[506,7]]},"2329":{"position":[[90,4],[434,4]]},"2333":{"position":[[0,4]]},"2335":{"position":[[240,4]]},"2339":{"position":[[224,4]]},"2341":{"position":[[599,4]]},"2343":{"position":[[966,4]]},"2347":{"position":[[0,4],[5,4],[348,6]]},"2349":{"position":[[185,4]]},"2351":{"position":[[263,4]]},"2355":{"position":[[302,4]]},"2360":{"position":[[1612,4]]},"2396":{"position":[[90,4],[434,4]]},"2400":{"position":[[0,4]]},"2402":{"position":[[240,4]]},"2406":{"position":[[224,4]]},"2408":{"position":[[599,4]]},"2410":{"position":[[966,4]]},"2414":{"position":[[0,4],[5,4],[348,6]]},"2416":{"position":[[185,4]]},"2418":{"position":[[263,4]]},"2422":{"position":[[302,4]]},"2427":{"position":[[1612,4]]},"2453":{"position":[[754,4]]},"2461":{"position":[[83,4]]},"2463":{"position":[[92,4],[360,4]]},"2465":{"position":[[86,4]]},"2478":{"position":[[1147,4]]},"2567":{"position":[[1503,5]]},"2608":{"position":[[858,4]]},"2614":{"position":[[429,4]]},"2618":{"position":[[229,4]]},"2626":{"position":[[1521,5]]},"2647":{"position":[[857,4],[2084,5]]},"2649":{"position":[[3395,5]]},"2674":{"position":[[313,5]]},"2682":{"position":[[273,5]]},"2684":{"position":[[159,5],[827,4]]},"2686":{"position":[[90,5]]},"2714":{"position":[[1645,4]]},"2875":{"position":[[99,5]]},"2879":{"position":[[213,6]]},"2908":{"position":[[525,5]]},"2910":{"position":[[296,5]]},"2912":{"position":[[99,4]]},"2916":{"position":[[361,4]]},"2930":{"position":[[1298,5]]},"2948":{"position":[[538,5]]},"2954":{"position":[[743,6]]},"2962":{"position":[[1211,6]]},"2964":{"position":[[0,4]]},"2968":{"position":[[434,4]]},"2973":{"position":[[567,4],[850,5]]},"2975":{"position":[[308,4]]},"2987":{"position":[[3670,4]]},"2995":{"position":[[103,4]]},"3002":{"position":[[1664,5]]},"3067":{"position":[[969,6]]},"3073":{"position":[[1005,5]]},"3083":{"position":[[597,5]]},"3091":{"position":[[210,5]]},"3105":{"position":[[142,4]]},"3116":{"position":[[335,5]]},"3121":{"position":[[237,5]]},"3124":{"position":[[96,5]]},"3132":{"position":[[261,4]]},"3138":{"position":[[142,4]]},"3150":{"position":[[837,6]]},"3153":{"position":[[578,5]]},"3157":{"position":[[79,6]]},"3195":{"position":[[79,6]]},"3200":{"position":[[77,5],[156,4]]},"3204":{"position":[[324,6]]},"3240":{"position":[[79,6]]},"3292":{"position":[[28,5]]},"3300":{"position":[[79,6]]},"3310":{"position":[[361,4],[448,4]]},"3325":{"position":[[110,4],[169,5]]},"3357":{"position":[[2812,6],[3387,4]]},"3381":{"position":[[131,4],[653,4],[2491,4]]},"3384":{"position":[[0,5]]},"3398":{"position":[[829,5],[909,5],[996,5],[1124,5],[1468,5],[1839,5],[2133,5]]},"3468":{"position":[[835,5],[935,5],[1154,5],[1463,5]]},"3470":{"position":[[958,5]]},"3525":{"position":[[210,4],[682,6]]},"3533":{"position":[[584,4],[1219,5],[1683,5]]},"3582":{"position":[[629,4]]},"3592":{"position":[[2234,4]]},"3598":{"position":[[2144,5]]},"3602":{"position":[[1054,5]]},"3606":{"position":[[1364,5],[1685,5]]},"3651":{"position":[[45,4]]},"3658":{"position":[[186,5]]},"3661":{"position":[[123,4],[519,4]]},"3665":{"position":[[142,4]]},"3673":{"position":[[0,4],[584,4],[881,6]]},"3677":{"position":[[563,4],[663,5],[918,5]]},"3679":{"position":[[967,4],[1634,4]]},"3681":{"position":[[0,4]]},"3688":{"position":[[45,4]]},"3690":{"position":[[867,4]]},"3695":{"position":[[121,4],[275,4]]},"3698":{"position":[[215,4],[624,4]]},"3702":{"position":[[214,4]]},"3704":{"position":[[874,4]]},"3706":{"position":[[540,4],[1387,4],[1569,4]]},"3712":{"position":[[1202,4]]},"3714":{"position":[[402,4],[912,6],[1345,4]]},"3718":{"position":[[0,4]]},"3761":{"position":[[714,4]]},"3763":{"position":[[616,5]]},"3775":{"position":[[45,4]]},"3777":{"position":[[968,4]]},"3782":{"position":[[121,4],[275,4]]},"3785":{"position":[[215,4],[624,4]]},"3789":{"position":[[214,4]]},"3791":{"position":[[561,4],[685,5],[940,5]]},"3793":{"position":[[1157,4]]},"3799":{"position":[[540,4],[1387,4],[1566,4]]},"3807":{"position":[[205,4],[534,6]]},"3811":{"position":[[0,4]]},"3826":{"position":[[422,5]]},"3829":{"position":[[1251,4],[3963,4],[4087,4]]},"3831":{"position":[[102,6],[277,5],[365,4]]},"3833":{"position":[[1112,4]]},"3835":{"position":[[321,4],[419,4],[1857,4]]},"3855":{"position":[[372,5]]},"3857":{"position":[[172,4]]},"3881":{"position":[[19,4]]},"3888":{"position":[[292,4]]},"3894":{"position":[[2001,4]]},"3896":{"position":[[71,4]]},"3904":{"position":[[33,4],[157,5]]},"3910":{"position":[[308,4]]},"3928":{"position":[[5798,4]]},"3947":{"position":[[4209,6]]},"4055":{"position":[[406,5]]},"4057":{"position":[[64,5]]},"4109":{"position":[[1569,4]]},"4130":{"position":[[644,4]]},"4137":{"position":[[0,4]]},"4146":{"position":[[1327,4]]},"4251":{"position":[[253,4]]},"4259":{"position":[[155,5]]},"4300":{"position":[[395,4]]},"4302":{"position":[[1620,5]]},"4304":{"position":[[746,4]]},"4365":{"position":[[171,4]]},"4435":{"position":[[1388,6]]},"4479":{"position":[[1640,5]]},"4485":{"position":[[1564,4],[2422,6]]},"4562":{"position":[[7158,6]]},"4604":{"position":[[738,5],[782,5]]},"4618":{"position":[[631,4],[851,5]]},"4620":{"position":[[154,5]]},"4623":{"position":[[218,5]]},"4643":{"position":[[514,4]]},"4667":{"position":[[12531,4],[12991,5],[14158,4]]},"4826":{"position":[[1213,5],[1298,5],[1390,5],[1528,5],[1907,5],[2303,5],[2612,5],[2812,5],[2917,5],[3151,5],[3485,5],[3753,5]]},"4841":{"position":[[7,4]]},"4849":{"position":[[676,5]]},"4855":{"position":[[176,4]]},"4872":{"position":[[798,4]]},"4879":{"position":[[181,4]]}}}],["note_email_address",{"_index":3919,"t":{"942":{"position":[[2855,18]]},"949":{"position":[[997,20]]},"1833":{"position":[[2855,18]]},"1840":{"position":[[997,20]]},"2966":{"position":[[2855,18]]},"2973":{"position":[[997,20]]}}}],["noteabl",{"_index":10973,"t":{"3947":{"position":[[2103,9],[2580,9]]}}}],["notepad",{"_index":1615,"t":{"222":{"position":[[18,8]]}}}],["noteworthi",{"_index":9725,"t":{"3088":{"position":[[215,10]]},"3121":{"position":[[867,10]]}}}],["noth",{"_index":2979,"t":{"632":{"position":[[591,7]]},"887":{"position":[[2850,7],[3849,7],[6027,7],[6866,7],[7692,7]]},"930":{"position":[[0,7]]},"938":{"position":[[1562,7]]},"1185":{"position":[[167,7]]},"1226":{"position":[[3753,7]]},"1252":{"position":[[216,7]]},"1466":{"position":[[1570,7]]},"1811":{"position":[[2850,7],[3849,7],[6027,7],[6866,7],[7692,7]]},"1821":{"position":[[0,7]]},"1829":{"position":[[1562,7]]},"2110":{"position":[[262,7]]},"2146":{"position":[[264,7]]},"2954":{"position":[[0,7]]},"2962":{"position":[[1562,7]]},"3020":{"position":[[0,7]]},"3210":{"position":[[0,7]]},"3673":{"position":[[281,7]]},"3850":{"position":[[202,7]]},"4733":{"position":[[1552,7]]}}}],["notic",{"_index":9792,"t":{"3162":{"position":[[56,7]]},"3197":{"position":[[60,8]]},"3200":{"position":[[56,8]]},"3242":{"position":[[60,8]]},"3829":{"position":[[3314,7],[3367,6],[3823,6],[3873,6]]},"3928":{"position":[[2117,6]]},"4146":{"position":[[2859,10]]},"4259":{"position":[[489,6]]},"4261":{"position":[[417,6]]},"4268":{"position":[[758,6]]},"4270":{"position":[[765,6]]},"4736":{"position":[[15,7]]},"4755":{"position":[[15,7]]}}}],["notif",{"_index":3946,"t":{"949":{"position":[[160,12],[620,13],[764,13]]},"1840":{"position":[[160,12],[620,13],[764,13]]},"2478":{"position":[[2706,13],[2755,13]]},"2604":{"position":[[81,13],[640,13]]},"2636":{"position":[[334,13]]},"2973":{"position":[[160,12],[620,13],[764,13]]},"3225":{"position":[[315,13]]},"3588":{"position":[[212,12]]},"4662":{"position":[[366,12],[1464,12]]},"4722":{"position":[[874,13]]}}}],["notifi",{"_index":873,"t":{"151":{"position":[[574,7]]},"1303":{"position":[[764,7]]},"2086":{"position":[[575,7]]},"3036":{"position":[[14780,8]]},"3038":{"position":[[192,11],[340,8]]},"3731":{"position":[[2918,8]]}}}],["notset",{"_index":5943,"t":{"1391":{"position":[[553,7]]}}}],["nov'23",{"_index":9898,"t":{"3255":{"position":[[84,7]]}}}],["nova",{"_index":2703,"t":{"555":{"position":[[614,4]]},"557":{"position":[[6621,8],[6914,4]]},"588":{"position":[[1453,4]]},"816":{"position":[[416,4],[777,4]]},"818":{"position":[[97,4],[140,4],[523,4],[548,4]]},"838":{"position":[[144,4]]},"844":{"position":[[0,4]]},"850":{"position":[[58,5]]},"932":{"position":[[2307,4]]},"995":{"position":[[62,4]]},"1003":{"position":[[125,4],[293,4]]},"1067":{"position":[[791,4]]},"1077":{"position":[[212,5]]},"1226":{"position":[[3555,4]]},"1252":{"position":[[3656,6]]},"1297":{"position":[[3870,4]]},"1301":{"position":[[961,7],[989,5],[1055,5],[1222,4],[2474,4]]},"1356":{"position":[[0,4],[17,4],[42,4]]},"1369":{"position":[[58,4]]},"1371":{"position":[[50,4],[85,4],[296,4],[629,4]]},"1373":{"position":[[4,4],[1171,4]]},"1377":{"position":[[222,4]]},"1383":{"position":[[331,4],[2151,4]]},"1385":{"position":[[93,4],[276,4],[2291,5],[2396,4],[2523,5]]},"1503":{"position":[[312,5]]},"1523":{"position":[[870,4],[895,4],[912,4]]},"1525":{"position":[[392,5]]},"1709":{"position":[[402,4],[507,4]]},"1711":{"position":[[544,4]]},"1713":{"position":[[1081,4],[1103,4]]},"1716":{"position":[[654,4],[748,4],[842,4]]},"1732":{"position":[[98,4],[703,4],[735,4],[1082,4],[1514,4],[1546,4]]},"1734":{"position":[[99,4],[704,4],[736,4],[1103,4],[1708,4],[1740,4]]},"1823":{"position":[[2307,4]]},"1886":{"position":[[62,4]]},"1894":{"position":[[125,4],[293,4]]},"2178":{"position":[[1193,6],[1227,6],[1262,6]]},"2211":{"position":[[1007,4]]},"2219":{"position":[[194,4],[622,4],[761,4]]},"2225":{"position":[[410,4]]},"2231":{"position":[[660,4],[685,4],[713,4]]},"2276":{"position":[[447,5]]},"2319":{"position":[[63,5],[142,5]]},"2323":{"position":[[156,4]]},"2353":{"position":[[1041,4]]},"2386":{"position":[[63,5],[142,5]]},"2390":{"position":[[156,4]]},"2420":{"position":[[1041,4]]},"2956":{"position":[[2307,4]]},"3016":{"position":[[643,5]]},"3164":{"position":[[302,4]]},"3890":{"position":[[72,4],[110,4]]},"3934":{"position":[[56,4]]},"3947":{"position":[[1136,4],[1581,4],[1778,4]]},"4096":{"position":[[423,4]]},"4113":{"position":[[116,5],[215,5],[328,5],[449,5]]},"4155":{"position":[[472,4]]},"4202":{"position":[[251,4]]},"4228":{"position":[[176,5]]},"4302":{"position":[[738,4],[764,4],[2745,4],[2832,4]]},"4304":{"position":[[937,4],[1317,4],[2084,4],[2512,4],[3020,4]]},"4335":{"position":[[181,4]]}}}],["nova.conf",{"_index":5481,"t":{"1297":{"position":[[3892,9]]},"1301":{"position":[[492,9],[579,9]]},"1385":{"position":[[618,9]]}}}],["nova.services.a.regiocloud.tech",{"_index":5462,"t":{"1297":{"position":[[2731,31]]}}}],["nova_api_external_back",{"_index":5463,"t":{"1297":{"position":[[2775,22]]}}}],["nova_api_public_port",{"_index":5409,"t":{"1295":{"position":[[2883,21]]}}}],["nova_api_work",{"_index":5618,"t":{"1305":{"position":[[1375,16]]}}}],["nova_backend",{"_index":5931,"t":{"1385":{"position":[[1973,13],[2189,13]]}}}],["nova_cell_conductor_work",{"_index":5622,"t":{"1305":{"position":[[1469,27]]}}}],["nova_comput",{"_index":7106,"t":{"1711":{"position":[[1291,12]]},"1713":{"position":[[606,12]]},"2144":{"position":[[76,12]]}}}],["nova_external_fqdn",{"_index":5408,"t":{"1295":{"position":[[2835,18]]}}}],["nova_instance_datadir_volum",{"_index":5929,"t":{"1385":{"position":[[1634,28],[1820,29],[1940,28],[2145,29]]}}}],["nova_instance_id",{"_index":9624,"t":{"3036":{"position":[[11642,17]]}}}],["nova_legacy_public_endpoint",{"_index":5377,"t":{"1295":{"position":[[1623,27]]}}}],["nova_libvirt",{"_index":5851,"t":{"1359":{"position":[[196,12]]},"1361":{"position":[[204,12]]},"1711":{"position":[[1419,12]]},"1713":{"position":[[554,12]]}}}],["nova_metadata_api_work",{"_index":5620,"t":{"1305":{"position":[[1420,25]]}}}],["nova_novncproxy_external_back",{"_index":5466,"t":{"1297":{"position":[[2940,29]]}}}],["nova_public_base_endpoint",{"_index":5378,"t":{"1295":{"position":[[1654,25],[1724,25],[2809,25]]},"1297":{"position":[[909,26]]}}}],["nova_public_endpoint",{"_index":5380,"t":{"1295":{"position":[[1700,20]]}}}],["nova_scheduler_work",{"_index":5621,"t":{"1305":{"position":[[1446,22]]}}}],["nova_ssh",{"_index":7111,"t":{"1711":{"position":[[1544,8]]},"1713":{"position":[[506,8]]}}}],["nova_superconductor_work",{"_index":5619,"t":{"1305":{"position":[[1392,27]]}}}],["nova_volume_id",{"_index":9637,"t":{"3036":{"position":[[12164,15]]}}}],["novacli",{"_index":372,"t":{"37":{"position":[[1157,10]]}}}],["novemb",{"_index":9801,"t":{"3164":{"position":[[119,8]]}}}],["novnc",{"_index":5482,"t":{"1297":{"position":[[3937,5]]},"2256":{"position":[[362,5]]},"3083":{"position":[[694,5]]}}}],["novncproxy_base_url",{"_index":5484,"t":{"1297":{"position":[[4002,19]]}}}],["novolum",{"_index":4270,"t":{"1005":{"position":[[672,9],[1923,8]]},"1896":{"position":[[672,9],[1923,8]]}}}],["now",{"_index":171,"t":{"24":{"position":[[291,4]]},"95":{"position":[[802,3]]},"130":{"position":[[873,3]]},"136":{"position":[[8,3]]},"199":{"position":[[2217,3]]},"273":{"position":[[222,4]]},"368":{"position":[[2250,3]]},"374":{"position":[[353,4]]},"444":{"position":[[168,3]]},"491":{"position":[[431,4]]},"493":{"position":[[358,3]]},"514":{"position":[[530,4]]},"566":{"position":[[160,3]]},"887":{"position":[[2192,3],[2376,3],[8696,3]]},"894":{"position":[[1467,3]]},"930":{"position":[[807,5]]},"938":{"position":[[246,4],[807,4]]},"942":{"position":[[2258,3]]},"961":{"position":[[794,3],[1732,3]]},"963":{"position":[[1594,3],[1754,3],[2622,3]]},"1073":{"position":[[522,3]]},"1175":{"position":[[3793,3],[5326,3]]},"1179":{"position":[[2287,3]]},"1191":{"position":[[1441,3]]},"1224":{"position":[[476,3]]},"1457":{"position":[[4221,3]]},"1480":{"position":[[250,3],[357,3]]},"1482":{"position":[[32,3]]},"1495":{"position":[[32,3]]},"1549":{"position":[[91,3]]},"1571":{"position":[[406,3]]},"1593":{"position":[[486,3],[520,3]]},"1646":{"position":[[799,3],[1222,3],[1482,3],[2111,3]]},"1648":{"position":[[375,3],[537,3],[727,3],[1221,3],[1392,4],[1488,3],[1735,3]]},"1659":{"position":[[618,3]]},"1745":{"position":[[235,3]]},"1752":{"position":[[1467,3]]},"1811":{"position":[[2192,3],[2376,3],[8696,3]]},"1821":{"position":[[807,5]]},"1829":{"position":[[246,4],[807,4]]},"1833":{"position":[[2258,3]]},"1852":{"position":[[794,3],[1732,3]]},"1854":{"position":[[1594,3],[1754,3],[2622,3]]},"1904":{"position":[[406,3]]},"1936":{"position":[[486,3],[520,3]]},"2034":{"position":[[1530,3]]},"2048":{"position":[[1620,3],[2111,3],[2630,3],[3456,3],[3540,3]]},"2059":{"position":[[2761,3]]},"2121":{"position":[[582,3]]},"2246":{"position":[[5,3]]},"2248":{"position":[[140,3]]},"2250":{"position":[[153,3]]},"2252":{"position":[[1451,3]]},"2256":{"position":[[653,3],[941,3]]},"2279":{"position":[[662,3]]},"2339":{"position":[[1207,3]]},"2360":{"position":[[1565,3],[1855,3]]},"2406":{"position":[[1207,3]]},"2427":{"position":[[1565,3],[1855,3]]},"2431":{"position":[[2304,4]]},"2584":{"position":[[304,4]]},"2600":{"position":[[6,4]]},"2602":{"position":[[1951,4]]},"2626":{"position":[[2237,4]]},"2934":{"position":[[197,3],[517,3],[773,3]]},"2954":{"position":[[807,5]]},"2962":{"position":[[246,4],[807,4]]},"2966":{"position":[[2258,3]]},"2985":{"position":[[794,3],[1732,3]]},"2987":{"position":[[1594,3],[1754,3],[2622,3]]},"3022":{"position":[[537,4]]},"3044":{"position":[[385,4]]},"3055":{"position":[[6,3]]},"3058":{"position":[[66,3]]},"3083":{"position":[[87,3]]},"3086":{"position":[[31,3],[299,3],[1068,3]]},"3088":{"position":[[3,3]]},"3091":{"position":[[420,4]]},"3093":{"position":[[56,3],[379,3]]},"3095":{"position":[[244,3]]},"3097":{"position":[[416,4]]},"3101":{"position":[[86,3],[263,3]]},"3116":{"position":[[78,3]]},"3121":{"position":[[128,4],[630,3],[781,4],[805,3],[929,3]]},"3130":{"position":[[605,4]]},"3150":{"position":[[705,3]]},"3153":{"position":[[1235,3],[1473,3],[1554,3]]},"3159":{"position":[[353,3]]},"3162":{"position":[[349,3]]},"3183":{"position":[[111,3],[301,3]]},"3185":{"position":[[375,3],[476,4],[633,3],[775,3],[860,3]]},"3189":{"position":[[408,3],[453,3],[667,3]]},"3191":{"position":[[116,3]]},"3193":{"position":[[19,3],[261,4]]},"3227":{"position":[[60,3]]},"3230":{"position":[[115,3]]},"3238":{"position":[[82,3]]},"3257":{"position":[[18,3]]},"3268":{"position":[[127,3]]},"3279":{"position":[[568,3]]},"3281":{"position":[[882,3]]},"3285":{"position":[[32,3],[82,3],[126,3],[195,3]]},"3288":{"position":[[138,3]]},"3292":{"position":[[119,3]]},"3294":{"position":[[59,3]]},"3296":{"position":[[1132,3]]},"3298":{"position":[[108,3]]},"3308":{"position":[[115,3]]},"3317":{"position":[[155,4]]},"3378":{"position":[[1509,3]]},"3390":{"position":[[543,3]]},"3398":{"position":[[550,3]]},"3468":{"position":[[506,3]]},"3470":{"position":[[523,3]]},"3502":{"position":[[538,3]]},"3592":{"position":[[258,3],[2554,3]]},"3613":{"position":[[271,4]]},"3735":{"position":[[6,4]]},"3761":{"position":[[1433,3]]},"3888":{"position":[[122,3],[209,3]]},"4045":{"position":[[266,3]]},"4144":{"position":[[70,3]]},"4826":{"position":[[630,3]]}}}],["nowaday",{"_index":11925,"t":{"4839":{"position":[[840,8]]}}}],["nowait",{"_index":4271,"t":{"1005":{"position":[[685,7],[1958,6]]},"1896":{"position":[[685,7],[1958,6]]}}}],["npm",{"_index":712,"t":{"121":{"position":[[0,3],[23,3]]},"130":{"position":[[939,4]]},"134":{"position":[[124,3]]},"136":{"position":[[65,3]]},"167":{"position":[[670,3]]},"2535":{"position":[[449,4]]},"2934":{"position":[[790,3]]},"4662":{"position":[[154,3]]}}}],["npm/github/zapi",{"_index":11794,"t":{"4662":{"position":[[134,17]]}}}],["npx",{"_index":9340,"t":{"2934":{"position":[[893,3]]}}}],["nr=1048576",{"_index":4587,"t":{"1167":{"position":[[796,10]]}}}],["ns",{"_index":2472,"t":{"481":{"position":[[367,2],[397,3],[434,3]]},"1587":{"position":[[10,2]]},"1930":{"position":[[10,2]]}}}],["nsa",{"_index":11637,"t":{"4551":{"position":[[122,3]]}}}],["nscd",{"_index":4551,"t":{"1159":{"position":[[28,4]]}}}],["nsllaalighht17",{"_index":7961,"t":{"2196":{"position":[[3506,14]]}}}],["ntp",{"_index":3306,"t":{"822":{"position":[[266,4]]},"1226":{"position":[[418,3],[5659,3]]},"1230":{"position":[[1085,3],[1106,3],[1201,3]]},"1447":{"position":[[71,3]]},"3352":{"position":[[2295,3]]}}}],["ntp_server",{"_index":5071,"t":{"1222":{"position":[[1386,10]]},"1230":{"position":[[1074,10]]}}}],["nubu",{"_index":11888,"t":{"4835":{"position":[[1264,5]]},"4839":{"position":[[455,7]]},"4857":{"position":[[209,5],[402,5]]}}}],["nubus.yaml.gotmpl",{"_index":11889,"t":{"4835":{"position":[[1343,17]]}}}],["nuclei",{"_index":8549,"t":{"2489":{"position":[[1502,6]]},"2506":{"position":[[431,6]]},"2553":{"position":[[15,6]]}}}],["null",{"_index":2166,"t":{"368":{"position":[[354,4]]},"2814":{"position":[[388,5]]}}}],["num",{"_index":3152,"t":{"706":{"position":[[2576,3],[2591,3]]},"1637":{"position":[[599,3]]},"1968":{"position":[[672,3]]}}}],["num_nod",{"_index":5538,"t":{"1303":{"position":[[931,9],[1005,10],[1054,9],[1729,9]]}}}],["num_osd",{"_index":4654,"t":{"1175":{"position":[[963,9],[1034,8],[1618,9],[1937,9],[2282,9],[2700,9],[2892,9]]},"1177":{"position":[[473,9],[1125,9]]}}}],["num_pg",{"_index":6583,"t":{"1637":{"position":[[584,9]]},"1968":{"position":[[657,9]]}}}],["numa",{"_index":4870,"t":{"1189":{"position":[[31,4],[742,4],[836,4],[917,4],[985,4]]},"1371":{"position":[[100,4],[170,4]]},"1383":{"position":[[259,4],[291,4],[646,4],[695,4],[771,4],[1120,4],[1156,4]]}}}],["numactl",{"_index":4880,"t":{"1189":{"position":[[879,8],[998,7]]}}}],["numatopologyfilt",{"_index":5860,"t":{"1371":{"position":[[8,18],[270,18]]}}}],["number",{"_index":494,"t":{"68":{"position":[[12,6]]},"163":{"position":[[223,8]]},"181":{"position":[[1571,6]]},"226":{"position":[[212,7]]},"368":{"position":[[5879,6]]},"473":{"position":[[325,6]]},"578":{"position":[[285,6]]},"741":{"position":[[1037,6]]},"818":{"position":[[382,6]]},"838":{"position":[[514,6]]},"842":{"position":[[189,6]]},"844":{"position":[[165,6]]},"938":{"position":[[2241,6],[2478,6],[2525,6]]},"961":{"position":[[1631,6]]},"963":{"position":[[3564,7],[3594,7],[3719,7],[4538,6]]},"978":{"position":[[990,6]]},"1003":{"position":[[300,6],[422,6]]},"1005":{"position":[[696,6],[703,7],[822,6],[1989,6],[1996,6],[2136,6],[2479,6]]},"1007":{"position":[[255,6]]},"1175":{"position":[[1075,6]]},"1185":{"position":[[41,6]]},"1189":{"position":[[424,8]]},"1252":{"position":[[90,6]]},"1268":{"position":[[43,6]]},"1301":{"position":[[1766,7]]},"1305":{"position":[[4,6],[605,6]]},"1373":{"position":[[309,6],[380,6]]},"1383":{"position":[[63,6],[135,6],[505,6]]},"1433":{"position":[[4,6]]},"1466":{"position":[[346,6]]},"1507":{"position":[[404,6]]},"1509":{"position":[[231,6],[847,6]]},"1523":{"position":[[143,6]]},"1637":{"position":[[205,6],[307,6],[525,6],[657,6]]},"1648":{"position":[[584,6]]},"1829":{"position":[[2241,6],[2478,6],[2525,6]]},"1852":{"position":[[1631,6]]},"1854":{"position":[[3564,7],[3594,7],[3719,7],[4538,6]]},"1869":{"position":[[990,6]]},"1894":{"position":[[300,6],[422,6]]},"1896":{"position":[[696,6],[703,7],[822,6],[1989,6],[1996,6],[2136,6],[2479,6]]},"1898":{"position":[[255,6]]},"1968":{"position":[[278,6],[380,6],[598,6],[730,6]]},"2175":{"position":[[518,6]]},"2283":{"position":[[262,7]]},"2285":{"position":[[608,8]]},"2297":{"position":[[262,7]]},"2299":{"position":[[608,8]]},"2478":{"position":[[1261,6]]},"2626":{"position":[[1645,7]]},"2684":{"position":[[1061,6],[1231,6]]},"2714":{"position":[[598,6]]},"2718":{"position":[[131,6],[744,7],[774,7]]},"2740":{"position":[[1039,7]]},"2756":{"position":[[1622,6]]},"2930":{"position":[[437,6],[478,6],[902,6],[964,6],[1125,6]]},"2962":{"position":[[2241,6],[2478,6],[2525,6]]},"2985":{"position":[[1631,6]]},"2987":{"position":[[3564,7],[3594,7],[3719,7],[4538,6]]},"3002":{"position":[[990,6]]},"3024":{"position":[[12,9],[58,6]]},"3075":{"position":[[12,9]]},"3081":{"position":[[179,6]]},"3083":{"position":[[208,6]]},"3086":{"position":[[797,6]]},"3101":{"position":[[275,6]]},"3105":{"position":[[12,9]]},"3138":{"position":[[12,9]]},"3153":{"position":[[981,6]]},"3168":{"position":[[967,6]]},"3170":{"position":[[24,6]]},"3189":{"position":[[2,6]]},"3261":{"position":[[2,6]]},"3281":{"position":[[359,6]]},"3310":{"position":[[498,6]]},"3367":{"position":[[116,7]]},"3402":{"position":[[186,6]]},"3527":{"position":[[95,7],[205,7],[352,7],[379,6],[400,6],[415,9],[743,7],[1037,7],[1167,6],[1200,6],[1410,7],[1461,6],[1585,6],[1646,7]]},"3533":{"position":[[808,6],[909,6],[1519,6],[1555,7],[1638,6],[2254,6],[2332,6]]},"3537":{"position":[[664,6]]},"3549":{"position":[[145,6],[539,7],[639,7],[1062,6]]},"3556":{"position":[[43,6]]},"3586":{"position":[[127,6]]},"3653":{"position":[[632,6]]},"3656":{"position":[[124,6],[138,6]]},"3658":{"position":[[226,7]]},"3690":{"position":[[531,6]]},"3693":{"position":[[183,6],[197,6]]},"3695":{"position":[[160,7]]},"3698":{"position":[[12,6]]},"3714":{"position":[[154,6],[1209,6],[1521,6],[1823,6]]},"3744":{"position":[[1193,7],[2015,7]]},"3761":{"position":[[569,6],[1174,7]]},"3777":{"position":[[632,6]]},"3780":{"position":[[183,6],[197,6]]},"3782":{"position":[[160,7]]},"3785":{"position":[[12,6]]},"3829":{"position":[[228,7]]},"3855":{"position":[[252,6]]},"3894":{"position":[[2049,7],[2060,6]]},"3902":{"position":[[31,7]]},"3923":{"position":[[59,6]]},"3947":{"position":[[3120,6],[3271,6]]},"3949":{"position":[[154,6]]},"3951":{"position":[[329,6]]},"4200":{"position":[[697,6]]},"4261":{"position":[[38,7]]},"4281":{"position":[[57,6]]},"4283":{"position":[[1021,6]]},"4420":{"position":[[2131,6]]},"4446":{"position":[[730,6]]},"4457":{"position":[[730,6]]},"4483":{"position":[[489,6]]},"4489":{"position":[[4,6]]},"4493":{"position":[[404,7]]},"4560":{"position":[[2446,6]]},"4580":{"position":[[1189,6],[2355,6]]},"4722":{"position":[[572,6]]},"4738":{"position":[[686,6]]},"4835":{"position":[[132,7]]},"4839":{"position":[[296,6],[702,6],[1671,6]]},"4853":{"position":[[457,7]]},"4872":{"position":[[23,6],[729,6]]}}}],["number_of_nod",{"_index":8052,"t":{"2219":{"position":[[627,15]]}}}],["number_of_volum",{"_index":8053,"t":{"2219":{"position":[[645,17]]}}}],["numer",{"_index":9716,"t":{"3086":{"position":[[59,8]]},"3204":{"position":[[0,8]]},"3279":{"position":[[310,9]]},"3355":{"position":[[74,8]]},"3357":{"position":[[2507,8],[2836,8]]},"3561":{"position":[[69,8]]},"3829":{"position":[[2367,9]]},"4416":{"position":[[10,8]]}}}],["nut",{"_index":1658,"t":{"233":{"position":[[91,4]]}}}],["nv",{"_index":5512,"t":{"1301":{"position":[[1866,2]]}}}],["nve",{"_index":11276,"t":{"4220":{"position":[[1358,4]]}}}],["nvidia",{"_index":10402,"t":{"3673":{"position":[[682,6],[724,6]]},"3675":{"position":[[366,6]]},"3714":{"position":[[527,6],[626,7],[2082,6]]},"3720":{"position":[[369,6]]},"3744":{"position":[[143,6],[412,6],[738,6],[1374,6],[1673,6],[2482,6]]},"3807":{"position":[[305,6],[330,7]]},"3813":{"position":[[366,6]]}}}],["nvm",{"_index":726,"t":{"130":{"position":[[41,3],[334,3],[365,3],[410,3],[432,4],[437,3],[551,3],[572,3],[618,3],[705,3],[849,3],[865,3]]}}}],["nvme",{"_index":4376,"t":{"1040":{"position":[[241,4],[758,4]]},"1042":{"position":[[473,4],[796,4]]},"1105":{"position":[[545,4]]},"1107":{"position":[[224,4],[281,4],[420,4]]},"1109":{"position":[[235,4]]},"1111":{"position":[[235,4]]},"1113":{"position":[[288,4]]},"1144":{"position":[[420,4]]},"1583":{"position":[[30,4]]},"1585":{"position":[[25,4]]},"1587":{"position":[[2,4]]},"1589":{"position":[[52,4]]},"1591":{"position":[[52,4],[109,4]]},"1639":{"position":[[213,4]]},"1641":{"position":[[110,4]]},"1926":{"position":[[30,4]]},"1928":{"position":[[25,4]]},"1930":{"position":[[2,4]]},"1932":{"position":[[52,4]]},"1934":{"position":[[52,4],[109,4]]},"1970":{"position":[[213,4]]},"1972":{"position":[[110,4]]},"2178":{"position":[[682,4]]},"3665":{"position":[[127,4]]},"3675":{"position":[[172,4],[466,4]]},"3702":{"position":[[199,4],[776,4]]},"3704":{"position":[[697,4]]},"3720":{"position":[[172,4],[469,4]]},"3789":{"position":[[199,4]]},"3813":{"position":[[172,4],[466,4]]},"3894":{"position":[[876,4]]},"3928":{"position":[[5104,4],[5691,4]]},"3930":{"position":[[735,5],[873,5]]}}}],["nvme01",{"_index":6118,"t":{"1421":{"position":[[1477,8]]}}}],["nvme0n1",{"_index":4660,"t":{"1175":{"position":[[1459,7],[1609,8],[1695,7],[1747,7],[1776,7],[1928,8],[2014,7],[2068,7],[2136,7],[2273,8],[2374,7],[2399,7],[2452,7],[2468,7],[2541,7],[2691,8],[2969,7],[3047,7]]}}}],["nvme1n1",{"_index":4661,"t":{"1175":{"position":[[2731,7],[2883,8],[2994,7],[3063,7]]}}}],["nwipe",{"_index":6525,"t":{"1593":{"position":[[1229,6]]},"1936":{"position":[[1229,6]]}}}],["nydu",{"_index":11676,"t":{"4562":{"position":[[6913,6]]}}}],["o",{"_index":215,"t":{"26":{"position":[[844,1]]},"28":{"position":[[310,1],[1767,1]]},"557":{"position":[[6011,1]]},"938":{"position":[[896,1]]},"942":{"position":[[946,1],[1159,1],[1234,1],[1308,1],[1383,1],[1463,1],[1537,1],[1619,1],[1911,1],[2188,1],[2302,1],[2386,1]]},"955":{"position":[[168,1]]},"961":{"position":[[487,1]]},"963":{"position":[[175,1]]},"1299":{"position":[[305,2]]},"1425":{"position":[[179,1]]},"1443":{"position":[[1100,1]]},"1472":{"position":[[2271,1],[3404,1]]},"1480":{"position":[[138,1]]},"1673":{"position":[[267,1],[382,1]]},"1704":{"position":[[193,1],[305,1]]},"1829":{"position":[[896,1]]},"1833":{"position":[[946,1],[1159,1],[1234,1],[1308,1],[1383,1],[1463,1],[1537,1],[1619,1],[1911,1],[2188,1],[2302,1],[2386,1]]},"1846":{"position":[[168,1]]},"1852":{"position":[[487,1]]},"1854":{"position":[[175,1]]},"1909":{"position":[[211,1]]},"2246":{"position":[[121,1],[222,1]]},"2614":{"position":[[626,1]]},"2800":{"position":[[63,1]]},"2962":{"position":[[896,1]]},"2966":{"position":[[946,1],[1159,1],[1234,1],[1308,1],[1383,1],[1463,1],[1537,1],[1619,1],[1911,1],[2188,1],[2302,1],[2386,1]]},"2979":{"position":[[168,1]]},"2985":{"position":[[487,1]]},"2987":{"position":[[175,1]]},"3663":{"position":[[328,1]]},"3679":{"position":[[964,2]]},"3700":{"position":[[352,1]]},"3704":{"position":[[871,2]]},"3706":{"position":[[759,1]]},"3787":{"position":[[352,1]]},"3793":{"position":[[1154,2]]},"3799":{"position":[[759,1]]},"3916":{"position":[[510,1]]},"4857":{"position":[[228,1],[421,1]]}}}],["o'clock",{"_index":2152,"t":{"364":{"position":[[1590,7]]}}}],["o=cloudsmith/caddy/st",{"_index":4084,"t":{"967":{"position":[[821,25]]},"1858":{"position":[[821,25]]},"2991":{"position":[[821,25]]}}}],["oaep",{"_index":2213,"t":{"368":{"position":[[4417,4],[5927,5],[6587,4],[6642,4],[6697,4]]},"3381":{"position":[[1980,4],[2228,4],[2400,4],[2465,4]]}}}],["oathkeep",{"_index":9203,"t":{"2832":{"position":[[42,10],[88,10]]},"2836":{"position":[[59,10]]},"2857":{"position":[[161,10]]},"2869":{"position":[[182,10]]},"2871":{"position":[[246,10]]},"2889":{"position":[[135,10],[186,10],[355,10]]}}}],["oathkeeper.localhost",{"_index":9334,"t":{"2934":{"position":[[453,20]]}}}],["oathkeeper/config.yaml",{"_index":9199,"t":{"2828":{"position":[[19,22]]}}}],["oauth",{"_index":2048,"t":{"319":{"position":[[481,5]]},"2376":{"position":[[365,5]]},"2382":{"position":[[364,5]]},"2628":{"position":[[470,5],[1026,5]]},"2636":{"position":[[443,5]]},"2839":{"position":[[55,5],[151,5]]},"2879":{"position":[[172,5]]},"2883":{"position":[[238,5]]},"3225":{"position":[[329,5]]},"3460":{"position":[[599,5]]},"4589":{"position":[[255,5]]},"4593":{"position":[[1301,5]]},"4597":{"position":[[597,5]]},"4660":{"position":[[179,7]]}}}],["oauth/oauth2",{"_index":8762,"t":{"2628":{"position":[[194,12],[436,12]]}}}],["oauth2",{"_index":4074,"t":{"963":{"position":[[5120,6],[5369,7]]},"1854":{"position":[[5120,6],[5369,7]]},"2628":{"position":[[10,6],[394,6]]},"2987":{"position":[[5120,6],[5369,7]]},"3236":{"position":[[254,6]]},"4593":{"position":[[3548,7]]},"4597":{"position":[[144,6]]}}}],["oauth2_proxy_client_id",{"_index":8764,"t":{"2628":{"position":[[292,22]]}}}],["oauth2_proxy_client_secret",{"_index":8765,"t":{"2628":{"position":[[315,26]]}}}],["oauth2_proxy_cookie_secret",{"_index":8766,"t":{"2628":{"position":[[342,26]]}}}],["obfusc",{"_index":11525,"t":{"4435":{"position":[[1291,10]]}}}],["object",{"_index":428,"t":{"39":{"position":[[266,7],[298,6]]},"45":{"position":[[118,6]]},"52":{"position":[[101,6]]},"74":{"position":[[122,9]]},"382":{"position":[[286,6],[426,7],[524,7],[932,6]]},"391":{"position":[[526,7]]},"393":{"position":[[78,7],[152,8],[178,7],[522,7]]},"395":{"position":[[56,7]]},"397":{"position":[[170,7]]},"401":{"position":[[612,7],[1080,8],[1106,6],[1191,6],[1220,7],[1287,7]]},"417":{"position":[[589,7],[765,7],[796,7],[889,7],[2140,7]]},"423":{"position":[[809,7]]},"425":{"position":[[77,7]]},"459":{"position":[[17,6]]},"461":{"position":[[17,6],[407,7],[512,7],[645,7],[688,8],[746,7]]},"463":{"position":[[1200,7],[1249,7],[1336,6],[1533,8]]},"465":{"position":[[31,7]]},"471":{"position":[[315,8]]},"477":{"position":[[17,6],[307,8]]},"479":{"position":[[501,6],[765,6],[1128,7],[1175,8],[1220,6],[1285,6]]},"487":{"position":[[541,7]]},"510":{"position":[[425,6]]},"518":{"position":[[323,9]]},"555":{"position":[[722,6],[768,6]]},"611":{"position":[[447,6]]},"696":{"position":[[1434,6]]},"701":{"position":[[43,6],[238,6],[511,6],[2583,6]]},"719":{"position":[[270,6]]},"734":{"position":[[43,6]]},"738":{"position":[[991,6]]},"822":{"position":[[336,6]]},"838":{"position":[[227,6]]},"842":{"position":[[113,6],[131,6],[256,6]]},"848":{"position":[[286,6]]},"850":{"position":[[23,6],[170,7],[248,7],[318,7]]},"852":{"position":[[11,7]]},"863":{"position":[[40,6]]},"912":{"position":[[228,8]]},"951":{"position":[[911,6]]},"973":{"position":[[140,6]]},"976":{"position":[[301,6]]},"1061":{"position":[[93,7],[964,7]]},"1077":{"position":[[77,6]]},"1391":{"position":[[197,7]]},"1619":{"position":[[34,8],[320,7],[411,7],[438,7],[795,8]]},"1764":{"position":[[40,6]]},"1796":{"position":[[228,8]]},"1842":{"position":[[911,6]]},"1864":{"position":[[140,6]]},"1867":{"position":[[301,6]]},"1950":{"position":[[34,8],[320,7],[411,7],[438,7],[795,8]]},"2146":{"position":[[65,6],[114,7]]},"2276":{"position":[[387,6]]},"2576":{"position":[[640,7]]},"2584":{"position":[[962,7],[981,7]]},"2586":{"position":[[572,7],[591,7]]},"2636":{"position":[[686,6]]},"2716":{"position":[[1113,6],[1722,6],[2302,8]]},"2804":{"position":[[80,7],[168,6],[290,6]]},"2814":{"position":[[52,6]]},"2930":{"position":[[713,6]]},"2975":{"position":[[911,6]]},"2997":{"position":[[140,6]]},"3000":{"position":[[301,6]]},"3034":{"position":[[371,7]]},"3172":{"position":[[230,7]]},"3281":{"position":[[949,6]]},"3296":{"position":[[528,8],[617,7],[838,6]]},"3346":{"position":[[14,10]]},"3357":{"position":[[392,7]]},"3584":{"position":[[103,11]]},"3866":{"position":[[137,11]]},"3870":{"position":[[68,8],[82,6]]},"3923":{"position":[[316,6]]},"3947":{"position":[[3515,7],[3529,7],[4235,7]]},"3990":{"position":[[1243,7],[1341,6],[1379,7],[1564,6],[1578,6]]},"4007":{"position":[[374,6]]},"4096":{"position":[[693,10]]},"4113":{"position":[[1694,6],[1937,7],[2135,7]]},"4135":{"position":[[373,8]]},"4144":{"position":[[703,11]]},"4146":{"position":[[945,6]]},"4202":{"position":[[423,6],[438,6]]},"4204":{"position":[[442,6],[461,6]]},"4210":{"position":[[120,6]]},"4222":{"position":[[835,9]]},"4275":{"position":[[9,9]]},"4374":{"position":[[97,6]]},"4522":{"position":[[1851,10]]},"4539":{"position":[[1044,7],[1322,7],[6771,7],[7032,7],[7092,7]]},"4547":{"position":[[3514,8]]},"4688":{"position":[[123,8]]},"4691":{"position":[[100,6],[276,6],[787,7]]},"4693":{"position":[[4,7]]},"4695":{"position":[[15,7],[114,8],[658,7]]},"4697":{"position":[[66,8]]},"4713":{"position":[[493,8]]},"4717":{"position":[[54,8],[202,6],[272,7]]},"4728":{"position":[[562,6],[905,6]]},"4742":{"position":[[516,6]]},"4761":{"position":[[194,6]]}}}],["object_id",{"_index":11041,"t":{"3990":{"position":[[643,9],[2857,9]]}}}],["object_typ",{"_index":11047,"t":{"3990":{"position":[[696,11],[2910,11]]}}}],["objectstore.http.request",{"_index":9556,"t":{"3036":{"position":[[6725,24]]}}}],["objectstore_request",{"_index":9557,"t":{"3036":{"position":[[6758,20]]}}}],["objectstores.yaml",{"_index":11859,"t":{"4833":{"position":[[353,17]]}}}],["oblect",{"_index":8983,"t":{"2716":{"position":[[1084,6]]}}}],["oblig",{"_index":1072,"t":{"171":{"position":[[820,10]]},"173":{"position":[[176,11]]},"4310":{"position":[[1632,12]]}}}],["obscur",{"_index":11315,"t":{"4222":{"position":[[4182,9]]}}}],["observ",{"_index":119,"t":{"15":{"position":[[69,13]]},"76":{"position":[[218,13]]},"171":{"position":[[1132,8]]},"197":{"position":[[1560,7],[1641,12]]},"239":{"position":[[248,8]]},"362":{"position":[[25,7],[297,7]]},"425":{"position":[[588,13]]},"980":{"position":[[861,8]]},"1513":{"position":[[170,11]]},"1564":{"position":[[243,13]]},"1871":{"position":[[861,8]]},"2602":{"position":[[1915,7]]},"2604":{"position":[[102,8],[668,8]]},"2606":{"position":[[325,8],[596,8]]},"2608":{"position":[[301,13],[330,8],[403,13],[663,8],[839,8]]},"2612":{"position":[[77,8]]},"2614":{"position":[[323,8],[1029,8]]},"2616":{"position":[[109,8]]},"2618":{"position":[[33,8],[301,13],[403,8],[615,8],[783,8]]},"2622":{"position":[[218,8]]},"2624":{"position":[[92,8],[259,8],[311,8],[443,8],[887,9]]},"2626":{"position":[[86,8],[162,8],[250,8],[363,8],[489,8],[1268,8]]},"2628":{"position":[[1046,8]]},"2630":{"position":[[82,8]]},"2632":{"position":[[83,8],[159,8],[206,8]]},"2636":{"position":[[551,8],[1120,8]]},"2638":{"position":[[194,7]]},"2644":{"position":[[231,8],[310,8],[327,8],[414,9]]},"2647":{"position":[[1124,7],[2065,8],[2398,8]]},"2649":{"position":[[1501,8],[1877,8],[2185,8],[2708,8],[2742,8],[3052,8],[3249,8],[3291,8],[3709,8],[3749,8]]},"2651":{"position":[[47,8],[209,8],[288,8],[578,8]]},"2655":{"position":[[4,8],[420,8],[477,8]]},"2659":{"position":[[105,8]]},"2665":{"position":[[138,7]]},"2672":{"position":[[231,8],[310,8],[327,8],[414,9]]},"2678":{"position":[[76,8],[824,8]]},"2680":{"position":[[275,13]]},"2745":{"position":[[39,13]]},"2754":{"position":[[37,13]]},"2756":{"position":[[2564,13]]},"3004":{"position":[[861,8]]},"3225":{"position":[[0,14],[19,13]]},"3230":{"position":[[576,8]]},"3255":{"position":[[161,13]]},"3276":{"position":[[340,13]]},"3352":{"position":[[3249,13]]},"3502":{"position":[[934,13]]},"3829":{"position":[[2046,8]]},"3925":{"position":[[1316,8]]},"4222":{"position":[[1507,11]]},"4226":{"position":[[2346,13]]},"4420":{"position":[[1379,13]]},"4587":{"position":[[258,11]]},"4593":{"position":[[944,8]]},"4722":{"position":[[355,9],[385,13]]},"4724":{"position":[[74,13],[486,13]]},"4726":{"position":[[198,13],[931,13],[990,13],[1037,13],[1073,7],[1088,8],[1195,13]]},"4728":{"position":[[19,13],[127,13],[365,8],[695,13],[1024,13],[1056,13],[1165,7],[1245,9],[1259,13],[1341,7],[1353,13]]},"4730":{"position":[[147,13],[204,13],[228,13],[345,7],[462,13],[538,8],[570,9],[700,13],[772,8],[1970,13],[2152,8],[2210,13]]},"4733":{"position":[[586,13],[743,13],[1595,13]]},"4826":{"position":[[3986,13]]}}}],["observe/tamp",{"_index":11278,"t":{"4220":{"position":[[2016,14]]}}}],["observer.yaml",{"_index":8706,"t":{"2604":{"position":[[567,13]]},"2606":{"position":[[525,14]]},"2628":{"position":[[947,13]]},"2647":{"position":[[2228,14],[2369,13]]},"2649":{"position":[[3539,14],[3680,13]]},"2657":{"position":[[216,13]]},"2674":{"position":[[457,14],[598,13]]},"2678":{"position":[[695,13]]}}}],["observer_id",{"_index":9554,"t":{"3036":{"position":[[6670,12],[7528,12],[10010,12],[14324,12]]}}}],["observer_typeuri",{"_index":9552,"t":{"3036":{"position":[[6619,17],[14365,17]]}}}],["obsolet",{"_index":10658,"t":{"3738":{"position":[[252,8]]}}}],["obtain",{"_index":2070,"t":{"323":{"position":[[56,8],[307,8]]},"2032":{"position":[[1665,6]]},"2034":{"position":[[1752,6]]},"2368":{"position":[[124,6],[273,6]]},"2431":{"position":[[2944,8]]},"3365":{"position":[[41,6]]},"3371":{"position":[[41,6]]},"3729":{"position":[[23,6]]},"4195":{"position":[[286,6]]},"4485":{"position":[[1005,6]]},"4707":{"position":[[249,6]]}}}],["obviou",{"_index":10281,"t":{"3611":{"position":[[290,8]]},"3653":{"position":[[623,8]]},"3690":{"position":[[522,8]]},"3777":{"position":[[623,8]]},"4313":{"position":[[703,7]]},"4446":{"position":[[292,7]]},"4457":{"position":[[292,7]]},"4614":{"position":[[108,7]]}}}],["obvious",{"_index":2183,"t":{"368":{"position":[[1229,9]]},"928":{"position":[[91,9]]},"963":{"position":[[3987,10]]},"973":{"position":[[345,10]]},"1819":{"position":[[91,9]]},"1854":{"position":[[3987,10]]},"1864":{"position":[[345,10]]},"2952":{"position":[[91,9]]},"2987":{"position":[[3987,10]]},"2997":{"position":[[345,10]]},"3636":{"position":[[313,10]]},"3928":{"position":[[1788,9]]},"3930":{"position":[[329,9]]},"4535":{"position":[[1369,9]]}}}],["occ2",{"_index":10066,"t":{"3381":{"position":[[115,5]]}}}],["occasion",{"_index":1774,"t":{"255":{"position":[[385,13]]},"834":{"position":[[610,13]]},"980":{"position":[[880,13]]},"1871":{"position":[[880,13]]},"3004":{"position":[[880,13]]},"3592":{"position":[[1195,12]]},"3928":{"position":[[1893,10],[2265,10]]},"4222":{"position":[[1643,12]]},"4294":{"position":[[169,12]]}}}],["occm",{"_index":9837,"t":{"3185":{"position":[[260,4]]}}}],["occur",{"_index":2161,"t":{"366":{"position":[[317,9]]},"551":{"position":[[1311,7]]},"834":{"position":[[603,6]]},"928":{"position":[[743,5]]},"940":{"position":[[1645,7]]},"1385":{"position":[[2502,5]]},"1472":{"position":[[1868,7],[1971,7]]},"1819":{"position":[[743,5]]},"1831":{"position":[[1645,7]]},"2150":{"position":[[269,5]]},"2184":{"position":[[2885,6]]},"2431":{"position":[[2193,8]]},"2716":{"position":[[1579,7]]},"2930":{"position":[[1117,7],[1379,6]]},"2952":{"position":[[743,5]]},"2964":{"position":[[1645,7]]},"3594":{"position":[[1144,5]]},"4107":{"position":[[339,5]]},"4109":{"position":[[145,9],[395,9],[452,6],[527,6],[599,6],[662,6],[727,6],[3004,5],[3707,5],[5453,9]]},"4133":{"position":[[190,6]]},"4167":{"position":[[806,5]]},"4206":{"position":[[368,5]]},"4220":{"position":[[345,5]]},"4420":{"position":[[1586,5]]}}}],["occurr",{"_index":10258,"t":{"3594":{"position":[[1299,10]]},"3602":{"position":[[940,10]]}}}],["oci",{"_index":2420,"t":{"473":{"position":[[99,3],[1006,3]]},"475":{"position":[[253,3],[565,9]]},"3281":{"position":[[468,3],[786,3]]},"4420":{"position":[[2383,3]]},"4562":{"position":[[6792,3],[6815,3]]}}}],["oci://registry.scs.community/clust",{"_index":2450,"t":{"475":{"position":[[780,36]]}}}],["oci://registry.scs.community/openstack",{"_index":8783,"t":{"2647":{"position":[[498,38]]}}}],["oci_access_token_b64",{"_index":2441,"t":{"473":{"position":[[1480,20]]}}}],["oci_password_b64",{"_index":2440,"t":{"473":{"position":[[1460,16]]}}}],["oci_registry_b64=cmvnaxn0cnkuc2nzlmnvbw11bml0eq",{"_index":2435,"t":{"473":{"position":[[1155,49]]}}}],["oci_repository_b64=cmvnaxn0cnkuc2nzlmnvbw11bml0es9rywfzl2nsdxn0zxitc3rhy2tzcg",{"_index":2437,"t":{"473":{"position":[[1237,79]]}}}],["oci_username_b64",{"_index":2439,"t":{"473":{"position":[[1439,16]]}}}],["oct",{"_index":6898,"t":{"1698":{"position":[[102,3],[375,3],[539,3],[759,3],[989,3],[1227,3]]}}}],["oct'23",{"_index":9897,"t":{"3255":{"position":[[0,7]]}}}],["octavia",{"_index":2760,"t":{"557":{"position":[[2282,8],[2307,7],[2324,7],[2711,7],[2795,7],[3186,8],[3211,7],[3228,7],[3542,7],[3626,7]]},"1077":{"position":[[119,8]]},"1335":{"position":[[0,7],[20,7],[48,7]]},"1523":{"position":[[917,7],[937,7],[975,7],[1016,7],[1036,7],[1232,7],[1355,7],[1525,8],[1550,7],[2086,8],[2246,7]]},"1702":{"position":[[152,7]]},"1704":{"position":[[707,7],[803,7],[899,7]]},"1745":{"position":[[178,8]]},"2184":{"position":[[6097,7],[6298,7]]},"2225":{"position":[[434,7]]},"2231":{"position":[[718,7],[746,7],[777,7],[968,7],[1132,7]]},"3016":{"position":[[674,8]]},"3022":{"position":[[1105,9]]},"3230":{"position":[[224,7],[303,7]]},"3264":{"position":[[21,10]]},"3285":{"position":[[384,7],[429,7]]},"3317":{"position":[[4,7],[100,7],[175,7]]},"4202":{"position":[[348,7]]},"4580":{"position":[[3190,7],[3258,7]]}}}],["octavia.amphorae.drivers.health.heartbeat_udp",{"_index":7239,"t":{"1743":{"position":[[85,45]]}}}],["octavia.services.a.regiocloud.tech",{"_index":5474,"t":{"1297":{"position":[[3414,34]]}}}],["octavia/amphora",{"_index":6342,"t":{"1523":{"position":[[1259,15]]},"2231":{"position":[[995,15]]}}}],["octavia_api_external_back",{"_index":5475,"t":{"1297":{"position":[[3461,25]]}}}],["octavia_api_work",{"_index":5623,"t":{"1305":{"position":[[1497,19]]}}}],["octavia_healthmanager_health_work",{"_index":5624,"t":{"1305":{"position":[[1517,36]]}}}],["octavia_healthmanager_stats_work",{"_index":5625,"t":{"1305":{"position":[[1554,35]]}}}],["octavia_keystone_password",{"_index":6345,"t":{"1523":{"position":[[1852,25],[2008,25]]}}}],["octavia_network_interfac",{"_index":5107,"t":{"1226":{"position":[[5138,26]]},"1299":{"position":[[276,25]]}}}],["octavia_network_typ",{"_index":5488,"t":{"1299":{"position":[[316,20]]}}}],["octavia_public_endpoint",{"_index":5428,"t":{"1297":{"position":[[976,24]]}}}],["octaviacli",{"_index":373,"t":{"37":{"position":[[1177,13]]},"934":{"position":[[166,13]]},"1825":{"position":[[166,13]]},"2958":{"position":[[166,13]]}}}],["octo",{"_index":1783,"t":{"258":{"position":[[94,4]]}}}],["octob",{"_index":9751,"t":{"3105":{"position":[[258,8]]},"3132":{"position":[[340,8]]},"3197":{"position":[[179,7]]},"3310":{"position":[[434,8]]}}}],["od",{"_index":11978,"t":{"4863":{"position":[[418,3]]}}}],["odss",{"_index":6580,"t":{"1637":{"position":[[347,4]]},"1968":{"position":[[420,4]]}}}],["of=\"$dummy_image_nam",{"_index":8268,"t":{"2266":{"position":[[247,22]]}}}],["off",{"_index":9885,"t":{"3236":{"position":[[291,4]]},"4740":{"position":[[444,5]]}}}],["offens",{"_index":1406,"t":{"197":{"position":[[1386,8]]}}}],["offer",{"_index":1330,"t":{"187":{"position":[[28,6],[708,9]]},"216":{"position":[[104,6]]},"297":{"position":[[88,8]]},"321":{"position":[[9,6]]},"370":{"position":[[59,6],[694,5]]},"374":{"position":[[390,5]]},"378":{"position":[[420,8]]},"401":{"position":[[377,5]]},"533":{"position":[[238,8],[626,8]]},"545":{"position":[[115,6],[1056,6]]},"551":{"position":[[1599,6]]},"701":{"position":[[177,6]]},"772":{"position":[[143,9]]},"774":{"position":[[123,5]]},"794":{"position":[[79,7]]},"796":{"position":[[55,5]]},"798":{"position":[[79,8]]},"824":{"position":[[295,5]]},"842":{"position":[[213,6]]},"846":{"position":[[686,6]]},"1067":{"position":[[317,8]]},"1252":{"position":[[1096,6]]},"1259":{"position":[[360,6]]},"1314":{"position":[[36,7]]},"1587":{"position":[[157,6]]},"1930":{"position":[[157,6]]},"2234":{"position":[[612,9]]},"2329":{"position":[[60,6]]},"2335":{"position":[[325,5]]},"2355":{"position":[[26,6]]},"2366":{"position":[[438,6]]},"2396":{"position":[[60,6]]},"2402":{"position":[[325,5]]},"2422":{"position":[[26,6]]},"2431":{"position":[[4041,5]]},"2437":{"position":[[128,6],[275,5]]},"2555":{"position":[[191,6]]},"2557":{"position":[[512,6]]},"2559":{"position":[[391,6]]},"2572":{"position":[[133,10],[182,10],[217,9],[252,10]]},"2574":{"position":[[1121,9]]},"2576":{"position":[[628,7]]},"2598":{"position":[[391,6]]},"2618":{"position":[[74,5]]},"2624":{"position":[[961,9]]},"2914":{"position":[[307,8]]},"2940":{"position":[[224,6]]},"3097":{"position":[[482,7]]},"3103":{"position":[[632,10]]},"3130":{"position":[[460,7]]},"3136":{"position":[[632,10]]},"3365":{"position":[[29,8]]},"3371":{"position":[[29,8]]},"3394":{"position":[[98,10]]},"3561":{"position":[[409,8]]},"3563":{"position":[[283,5]]},"3573":{"position":[[313,6]]},"3582":{"position":[[143,9],[247,5]]},"3600":{"position":[[825,6]]},"3611":{"position":[[140,6]]},"3653":{"position":[[200,5]]},"3667":{"position":[[58,5]]},"3677":{"position":[[693,7],[899,5]]},"3679":{"position":[[67,5],[581,5],[672,5],[718,5],[1243,5],[1325,5],[1392,5]]},"3681":{"position":[[237,9],[586,8],[611,8],[719,5],[815,5]]},"3685":{"position":[[21,5]]},"3690":{"position":[[200,5]]},"3704":{"position":[[17,5],[246,5],[609,5],[1211,5],[1302,5],[1376,5]]},"3706":{"position":[[52,5],[389,5],[1201,5]]},"3708":{"position":[[70,5]]},"3718":{"position":[[237,9],[625,8],[650,8],[758,5],[854,5]]},"3724":{"position":[[373,5]]},"3731":{"position":[[593,5],[984,5]]},"3772":{"position":[[33,5]]},"3777":{"position":[[200,5]]},"3791":{"position":[[715,7],[921,5]]},"3793":{"position":[[67,5],[743,5],[834,5],[908,5],[1469,5],[1561,5],[1654,5]]},"3799":{"position":[[52,5],[389,5],[1201,5]]},"3801":{"position":[[58,5]]},"3811":{"position":[[237,9],[625,8],[650,8],[758,5],[854,5]]},"3817":{"position":[[373,5]]},"3820":{"position":[[12,5]]},"3831":{"position":[[886,5]]},"3864":{"position":[[143,9]]},"3892":{"position":[[200,5]]},"3904":{"position":[[187,7],[324,5]]},"3923":{"position":[[129,9],[145,8],[225,9]]},"3928":{"position":[[5288,6],[5771,7]]},"3930":{"position":[[353,5]]},"4073":{"position":[[423,6]]},"4077":{"position":[[213,6],[267,9],[384,9]]},"4094":{"position":[[900,6]]},"4116":{"position":[[10,6]]},"4120":{"position":[[444,5]]},"4124":{"position":[[1707,6],[2150,5]]},"4126":{"position":[[256,7]]},"4146":{"position":[[1898,6],[2355,6],[2490,5],[2653,8]]},"4185":{"position":[[876,5]]},"4187":{"position":[[47,6]]},"4189":{"position":[[489,5],[677,5]]},"4202":{"position":[[514,7],[726,7]]},"4206":{"position":[[469,6]]},"4291":{"position":[[1369,6]]},"4302":{"position":[[1737,5],[2127,5],[2750,6],[3261,5],[3519,7],[4045,5]]},"4310":{"position":[[2258,5]]},"4362":{"position":[[151,8]]},"4410":{"position":[[478,5]]},"4414":{"position":[[126,8],[209,5]]},"4479":{"position":[[2318,6]]},"4508":{"position":[[441,5]]},"4522":{"position":[[342,6],[1256,8]]},"4543":{"position":[[1080,6]]},"4560":{"position":[[5278,6],[5436,7]]},"4562":{"position":[[1491,7],[1991,5],[2164,6],[5393,8]]},"4580":{"position":[[1181,5]]},"4582":{"position":[[354,5]]},"4593":{"position":[[501,6],[801,6],[1027,6],[2663,8],[3454,6],[3731,6],[4272,6],[5019,8]]},"4632":{"position":[[1684,8]]},"4665":{"position":[[388,5]]},"4722":{"position":[[24,5],[241,7],[328,10]]},"4728":{"position":[[79,6],[1475,5]]},"4733":{"position":[[231,9]]}}}],["offic",{"_index":1233,"t":{"179":{"position":[[591,7]]},"1250":{"position":[[671,7]]},"1555":{"position":[[98,7],[946,7]]},"4096":{"position":[[179,6]]},"4098":{"position":[[637,6]]},"4146":{"position":[[450,9]]},"4155":{"position":[[743,6]]},"4298":{"position":[[438,7]]}}}],["offici",{"_index":1808,"t":{"264":{"position":[[294,8]]},"362":{"position":[[811,8]]},"364":{"position":[[1717,8]]},"366":{"position":[[711,8]]},"368":{"position":[[2200,8],[6297,8]]},"393":{"position":[[565,8]]},"520":{"position":[[795,8]]},"696":{"position":[[132,8]]},"703":{"position":[[222,8]]},"705":{"position":[[519,8]]},"706":{"position":[[69,8],[1178,8],[1268,8]]},"728":{"position":[[537,8]]},"755":{"position":[[179,8],[507,8]]},"846":{"position":[[207,8]]},"936":{"position":[[79,8]]},"1056":{"position":[[381,8]]},"1161":{"position":[[4,8]]},"1393":{"position":[[4,8]]},"1569":{"position":[[4,8]]},"1827":{"position":[[79,8]]},"1902":{"position":[[4,8],[215,8]]},"2023":{"position":[[502,8],[621,8]]},"2137":{"position":[[4,8]]},"2482":{"position":[[670,8]]},"2879":{"position":[[22,8]]},"2960":{"position":[[79,8]]},"3140":{"position":[[41,10]]},"3185":{"position":[[102,10],[166,10]]},"3375":{"position":[[349,8]]},"3533":{"position":[[1896,8]]},"3679":{"position":[[1617,8]]},"3704":{"position":[[1625,8]]},"3731":{"position":[[255,8]]},"3793":{"position":[[1879,8]]},"4146":{"position":[[391,10]]},"4273":{"position":[[206,8]]},"4279":{"position":[[190,8],[812,8]]},"4313":{"position":[[530,10]]},"4327":{"position":[[147,10]]},"4346":{"position":[[69,8]]},"4351":{"position":[[249,10]]},"4353":{"position":[[497,8]]},"4355":{"position":[[888,8],[1001,8]]},"4357":{"position":[[59,8]]},"4420":{"position":[[2749,10]]},"4479":{"position":[[833,8]]},"4578":{"position":[[145,8]]},"4580":{"position":[[1999,8]]},"4604":{"position":[[534,8]]},"4623":{"position":[[296,8]]}}}],["offlin",{"_index":5869,"t":{"1373":{"position":[[666,7]]},"2242":{"position":[[84,8]]},"2248":{"position":[[186,7]]},"3731":{"position":[[1425,8]]},"4506":{"position":[[622,7]]},"4508":{"position":[[520,7],[574,7]]},"4522":{"position":[[349,7]]}}}],["oflag=direct,dsync",{"_index":6703,"t":{"1665":{"position":[[1069,19]]}}}],["oft",{"_index":5223,"t":{"1259":{"position":[[1308,3]]}}}],["og",{"_index":3778,"t":{"932":{"position":[[1509,2]]},"1823":{"position":[[1509,2]]},"2956":{"position":[[1509,2]]}}}],["ogth7hi2zywrs5tnaik/qlvsb7am+lqrp7lmlm4jmd6woyr7dishu7omd1gqem2zumgga",{"_index":2215,"t":{"368":{"position":[[4494,69]]}}}],["oh",{"_index":7558,"t":{"2110":{"position":[[3476,2]]}}}],["ohm0",{"_index":6997,"t":{"1702":{"position":[[172,5],[645,4],[660,4]]}}}],["oid",{"_index":2810,"t":{"557":{"position":[[5928,3]]}}}],["oidc",{"_index":2034,"t":{"311":{"position":[[597,5]]},"319":{"position":[[707,4]]},"321":{"position":[[25,4]]},"323":{"position":[[1213,4]]},"327":{"position":[[73,4]]},"329":{"position":[[77,4]]},"557":{"position":[[5792,5],[5798,5],[6139,4],[6240,5],[6246,5],[6374,5]]},"963":{"position":[[1535,4],[4276,4],[4627,4]]},"1854":{"position":[[1535,4],[4276,4],[4627,4]]},"2196":{"position":[[35,6],[110,4],[170,5],[195,5],[646,4],[1860,5]]},"2368":{"position":[[131,4],[209,4]]},"2372":{"position":[[144,4]]},"2376":{"position":[[38,4]]},"2380":{"position":[[290,4]]},"2431":{"position":[[229,5],[321,4],[383,4],[495,5],[514,4],[713,4],[1121,4],[2365,5],[2776,4],[2830,4],[3552,4],[3639,4],[4227,4]]},"2433":{"position":[[647,4],[1096,4]]},"2602":{"position":[[2059,4]]},"2830":{"position":[[29,4]]},"2914":{"position":[[710,4]]},"2987":{"position":[[1535,4],[4276,4],[4627,4]]},"3022":{"position":[[241,5]]},"3058":{"position":[[45,4]]},"3062":{"position":[[68,4]]},"3077":{"position":[[0,4],[35,4]]},"3189":{"position":[[60,4]]},"4562":{"position":[[5900,5]]},"4589":{"position":[[283,6],[407,5]]},"4593":{"position":[[1018,5],[3542,5],[3964,6]]},"4643":{"position":[[2572,4],[3493,4],[3528,4]]},"4660":{"position":[[187,6]]},"4662":{"position":[[661,5],[1412,4]]}}}],["oidc:engin",{"_index":2822,"t":{"557":{"position":[[6410,16]]}}}],["oidc:infra",{"_index":2823,"t":{"557":{"position":[[6431,11]]}}}],["oidc:jane.do",{"_index":2811,"t":{"557":{"position":[[5962,14]]}}}],["oidc_config",{"_index":2705,"t":{"555":{"position":[[876,12],[922,11]]}}}],["oidc_config.client_id",{"_index":2790,"t":{"557":{"position":[[4870,21]]}}}],["oidc_config.groups_claim",{"_index":2807,"t":{"557":{"position":[[5617,24]]}}}],["oidc_config.groups_prefix",{"_index":2816,"t":{"557":{"position":[[6207,25]]}}}],["oidc_config.issuer_url",{"_index":2791,"t":{"557":{"position":[[4955,22]]}}}],["oidc_config.username_claim",{"_index":2797,"t":{"557":{"position":[[5229,26]]}}}],["oidc_config.username_prefix",{"_index":2809,"t":{"557":{"position":[[5757,27]]}}}],["oif",{"_index":9742,"t":{"3103":{"position":[[158,3]]},"3136":{"position":[[158,3]]},"3144":{"position":[[508,4]]},"3176":{"position":[[464,4]]},"3214":{"position":[[356,3]]}}}],["oin",{"_index":1247,"t":{"179":{"position":[[1207,5],[1736,3]]}}}],["ok",{"_index":6665,"t":{"1659":{"position":[[456,3]]},"1694":{"position":[[7891,2],[8988,2]]},"3932":{"position":[[1082,2]]}}}],["ok=11",{"_index":6669,"t":{"1659":{"position":[[745,5]]}}}],["okay",{"_index":10979,"t":{"3949":{"position":[[199,4]]},"4257":{"position":[[5690,4]]}}}],["okd",{"_index":8813,"t":{"2655":{"position":[[180,4]]}}}],["old",{"_index":336,"t":{"37":{"position":[[297,3]]},"1238":{"position":[[645,3]]},"2130":{"position":[[142,3],[216,3]]},"2240":{"position":[[1188,3]]},"2347":{"position":[[161,3]]},"2414":{"position":[[161,3]]},"2930":{"position":[[1003,3]]},"3159":{"position":[[377,3]]},"3166":{"position":[[14,3]]},"3187":{"position":[[4,3]]},"3200":{"position":[[92,3]]},"3230":{"position":[[435,3]]},"3310":{"position":[[412,3]]},"3357":{"position":[[1245,5]]},"3533":{"position":[[2422,3]]},"3537":{"position":[[696,3]]},"3554":{"position":[[4,3]]},"3606":{"position":[[1672,3]]},"3671":{"position":[[554,3],[749,3]]},"3712":{"position":[[986,3],[1181,3]]},"3722":{"position":[[829,3],[1183,3],[1518,3]]},"3805":{"position":[[661,3],[856,3]]},"3815":{"position":[[827,3],[1181,3],[1516,3]]},"3829":{"position":[[372,3],[3977,3],[4180,3],[4945,3]]},"4062":{"position":[[44,3]]},"4701":{"position":[[213,3]]},"4715":{"position":[[164,3]]},"4742":{"position":[[783,3]]}}}],["old_instance_s",{"_index":9643,"t":{"3036":{"position":[[12609,18]]}}}],["old_stat",{"_index":9414,"t":{"3036":{"position":[[1254,10]]}}}],["old_volume_s",{"_index":9639,"t":{"3036":{"position":[[12400,16]]}}}],["older",{"_index":2381,"t":{"440":{"position":[[66,5]]},"871":{"position":[[445,5]]},"873":{"position":[[1334,5]]},"991":{"position":[[21,5],[152,5]]},"1147":{"position":[[415,5]]},"1175":{"position":[[402,5]]},"1455":{"position":[[1486,5]]},"1637":{"position":[[765,5]]},"1772":{"position":[[445,5]]},"1774":{"position":[[1334,5]]},"1882":{"position":[[21,5],[152,5]]},"1968":{"position":[[838,5]]},"2032":{"position":[[237,5]]},"3185":{"position":[[202,5]]},"3554":{"position":[[99,5]]},"3606":{"position":[[1445,5],[1483,5]]},"3744":{"position":[[205,5]]},"3829":{"position":[[4241,5]]},"4249":{"position":[[269,5]]},"4253":{"position":[[451,5],[605,5]]},"4257":{"position":[[638,5],[841,5],[929,5],[1943,5],[3543,5],[4100,5],[4401,5]]},"4268":{"position":[[346,5]]},"4362":{"position":[[253,5]]},"4533":{"position":[[40,5]]},"4604":{"position":[[671,5],[879,5]]},"4618":{"position":[[745,5]]},"4667":{"position":[[57,5]]}}}],["olderthan=2023",{"_index":3144,"t":{"706":{"position":[[2406,14]]}}}],["oldest",{"_index":11489,"t":{"4351":{"position":[[274,6]]}}}],["olso",{"_index":11732,"t":{"4614":{"position":[[1120,4]]}}}],["omap",{"_index":6560,"t":{"1619":{"position":[[29,4],[315,4],[406,4]]},"1950":{"position":[[29,4],[315,4],[406,4]]}}}],["omiss",{"_index":11261,"t":{"4198":{"position":[[671,8]]}}}],["omit",{"_index":2306,"t":{"405":{"position":[[529,8]]},"557":{"position":[[6858,7]]},"2263":{"position":[[329,7]]},"2806":{"position":[[206,7]]},"2808":{"position":[[89,4],[127,4]]},"2812":{"position":[[169,7],[222,7]]},"2814":{"position":[[114,7],[484,7]]},"2816":{"position":[[176,7]]},"3665":{"position":[[171,7]]},"3679":{"position":[[977,8]]},"3702":{"position":[[243,7]]},"3704":{"position":[[884,8]]},"3789":{"position":[[243,7]]},"3793":{"position":[[1167,8]]},"4163":{"position":[[5327,8]]},"4200":{"position":[[218,7]]},"4669":{"position":[[672,8]]}}}],["on",{"_index":609,"t":{"84":{"position":[[656,3],[679,3]]},"107":{"position":[[115,3],[160,3],[211,3]]},"167":{"position":[[348,3]]},"177":{"position":[[65,3]]},"181":{"position":[[104,4]]},"199":{"position":[[2410,4]]},"201":{"position":[[237,3]]},"207":{"position":[[212,5],[839,5]]},"245":{"position":[[515,3]]},"255":{"position":[[424,3]]},"284":{"position":[[226,4]]},"288":{"position":[[343,3],[390,3],[477,3]]},"305":{"position":[[341,3]]},"332":{"position":[[66,3]]},"360":{"position":[[126,3],[248,3],[612,3]]},"364":{"position":[[39,3],[665,3]]},"368":{"position":[[209,4],[5472,3],[5962,3]]},"370":{"position":[[415,4]]},"391":{"position":[[562,3]]},"401":{"position":[[583,3]]},"403":{"position":[[722,4]]},"417":{"position":[[64,3],[901,3],[1494,3],[1794,3],[1847,3]]},"419":{"position":[[45,3]]},"425":{"position":[[439,3]]},"461":{"position":[[366,4]]},"465":{"position":[[18,3]]},"479":{"position":[[582,3]]},"489":{"position":[[650,3]]},"491":{"position":[[105,3]]},"496":{"position":[[401,3]]},"514":{"position":[[45,3]]},"528":{"position":[[560,3]]},"557":{"position":[[1240,3],[1256,3]]},"588":{"position":[[134,3],[252,3]]},"593":{"position":[[193,3],[244,3]]},"604":{"position":[[31,3],[144,3]]},"611":{"position":[[242,3],[675,3]]},"618":{"position":[[97,3],[223,3]]},"628":{"position":[[68,3]]},"634":{"position":[[225,4]]},"645":{"position":[[27,4]]},"647":{"position":[[178,4]]},"664":{"position":[[193,3],[244,3]]},"671":{"position":[[953,3]]},"677":{"position":[[27,4]]},"679":{"position":[[178,4]]},"692":{"position":[[76,4]]},"708":{"position":[[724,3]]},"728":{"position":[[274,3],[392,3],[688,3]]},"739":{"position":[[48,3]]},"782":{"position":[[111,3]]},"798":{"position":[[100,3]]},"800":{"position":[[51,3]]},"812":{"position":[[45,3],[148,3],[188,3]]},"816":{"position":[[520,3],[552,3]]},"818":{"position":[[263,3]]},"836":{"position":[[255,3]]},"854":{"position":[[57,3]]},"873":{"position":[[170,3]]},"896":{"position":[[55,3],[71,3]]},"932":{"position":[[2275,3]]},"938":{"position":[[411,3],[761,3]]},"940":{"position":[[863,3]]},"942":{"position":[[2728,3],[2751,3]]},"944":{"position":[[143,3]]},"949":{"position":[[217,3],[931,3]]},"951":{"position":[[1316,3]]},"963":{"position":[[3012,3],[3148,3]]},"980":{"position":[[841,4]]},"1036":{"position":[[226,3]]},"1046":{"position":[[93,3],[375,3],[443,3]]},"1056":{"position":[[305,3]]},"1073":{"position":[[309,3]]},"1171":{"position":[[525,3],[558,3]]},"1189":{"position":[[398,3]]},"1230":{"position":[[936,3],[1102,3]]},"1252":{"position":[[1257,3],[2590,3]]},"1301":{"position":[[2655,3]]},"1385":{"position":[[446,3]]},"1389":{"position":[[127,3]]},"1437":{"position":[[381,3]]},"1468":{"position":[[1157,3]]},"1484":{"position":[[442,3]]},"1486":{"position":[[345,4]]},"1509":{"position":[[585,3],[732,3]]},"1637":{"position":[[780,3],[845,3]]},"1745":{"position":[[144,3]]},"1754":{"position":[[55,3],[71,3]]},"1774":{"position":[[170,3]]},"1823":{"position":[[2275,3]]},"1829":{"position":[[411,3],[761,3]]},"1831":{"position":[[863,3]]},"1833":{"position":[[2728,3],[2751,3]]},"1835":{"position":[[143,3]]},"1840":{"position":[[217,3],[931,3]]},"1842":{"position":[[1316,3]]},"1854":{"position":[[3012,3],[3148,3]]},"1871":{"position":[[841,4]]},"1968":{"position":[[853,3],[918,3]]},"2029":{"position":[[134,3]]},"2032":{"position":[[289,3]]},"2041":{"position":[[83,3]]},"2048":{"position":[[515,3]]},"2057":{"position":[[611,3],[637,3]]},"2074":{"position":[[253,3]]},"2121":{"position":[[258,3]]},"2130":{"position":[[248,4]]},"2163":{"position":[[3854,3],[4137,3]]},"2178":{"position":[[48,3]]},"2184":{"position":[[3945,3]]},"2211":{"position":[[1767,4]]},"2234":{"position":[[274,3],[601,3]]},"2236":{"position":[[286,3],[365,3]]},"2242":{"position":[[463,4]]},"2252":{"position":[[185,3],[383,4],[633,3]]},"2261":{"position":[[216,3]]},"2266":{"position":[[82,3]]},"2276":{"position":[[2646,4]]},"2285":{"position":[[1204,3],[1309,3]]},"2287":{"position":[[1025,3]]},"2299":{"position":[[1204,3],[1309,3]]},"2301":{"position":[[1025,3]]},"2327":{"position":[[747,3],[754,3]]},"2355":{"position":[[157,3]]},"2358":{"position":[[126,3]]},"2380":{"position":[[304,3]]},"2394":{"position":[[747,3],[754,3]]},"2422":{"position":[[157,3]]},"2425":{"position":[[126,3]]},"2429":{"position":[[384,3]]},"2431":{"position":[[46,3],[159,3],[3541,3]]},"2433":{"position":[[933,4]]},"2453":{"position":[[845,4]]},"2478":{"position":[[2221,4]]},"2584":{"position":[[845,3]]},"2586":{"position":[[455,3]]},"2596":{"position":[[125,3]]},"2608":{"position":[[980,3]]},"2649":{"position":[[1452,3]]},"2684":{"position":[[504,3]]},"2754":{"position":[[120,3]]},"2845":{"position":[[57,3],[76,3]]},"2914":{"position":[[260,3]]},"2930":{"position":[[1162,3]]},"2932":{"position":[[86,4]]},"2956":{"position":[[2275,3]]},"2962":{"position":[[411,3],[761,3]]},"2964":{"position":[[863,3]]},"2966":{"position":[[2728,3],[2751,3]]},"2968":{"position":[[143,3]]},"2973":{"position":[[217,3],[931,3]]},"2975":{"position":[[1316,3]]},"2987":{"position":[[3012,3],[3148,3]]},"3004":{"position":[[841,4]]},"3022":{"position":[[812,3]]},"3030":{"position":[[100,3]]},"3134":{"position":[[73,3]]},"3148":{"position":[[558,3]]},"3172":{"position":[[190,3]]},"3223":{"position":[[395,3],[415,3]]},"3266":{"position":[[384,3]]},"3276":{"position":[[795,3],[862,3],[943,3]]},"3279":{"position":[[380,3],[623,3]]},"3298":{"position":[[595,3]]},"3310":{"position":[[640,3]]},"3315":{"position":[[149,3]]},"3357":{"position":[[3286,3],[3343,3],[3699,4]]},"3378":{"position":[[55,3],[70,3],[1549,3]]},"3381":{"position":[[2323,3]]},"3386":{"position":[[666,3]]},"3523":{"position":[[0,3]]},"3527":{"position":[[435,3],[871,3],[1778,3],[1854,3],[1915,3]]},"3533":{"position":[[729,3],[1439,3],[2198,3]]},"3537":{"position":[[415,3]]},"3539":{"position":[[377,3]]},"3541":{"position":[[107,3]]},"3544":{"position":[[65,3]]},"3549":{"position":[[108,3]]},"3571":{"position":[[1333,3],[1378,3],[1429,3]]},"3582":{"position":[[1203,5],[1599,3]]},"3592":{"position":[[1465,3],[2208,3],[2327,3]]},"3598":{"position":[[1740,3],[2270,3]]},"3604":{"position":[[142,3]]},"3606":{"position":[[1464,4],[1489,3],[1714,3]]},"3613":{"position":[[47,3]]},"3629":{"position":[[309,3],[368,3]]},"3632":{"position":[[49,3]]},"3634":{"position":[[43,3]]},"3636":{"position":[[116,3]]},"3677":{"position":[[1274,3]]},"3681":{"position":[[939,3]]},"3706":{"position":[[1627,3],[1775,4]]},"3714":{"position":[[1375,3]]},"3718":{"position":[[978,3]]},"3727":{"position":[[304,3]]},"3742":{"position":[[770,3]]},"3744":{"position":[[211,3],[259,3],[364,4],[682,3],[2148,3],[2757,3]]},"3761":{"position":[[1004,3]]},"3763":{"position":[[490,4]]},"3791":{"position":[[1297,3]]},"3799":{"position":[[1624,3]]},"3811":{"position":[[978,3]]},"3843":{"position":[[190,5]]},"3853":{"position":[[184,3]]},"3870":{"position":[[93,3]]},"3872":{"position":[[708,3]]},"3874":{"position":[[525,3],[660,3],[900,3]]},"3881":{"position":[[211,3]]},"3894":{"position":[[381,3],[1525,3],[1582,3],[1597,5]]},"3902":{"position":[[285,3]]},"3904":{"position":[[828,3]]},"3918":{"position":[[98,3],[849,3]]},"3925":{"position":[[1359,3]]},"3928":{"position":[[0,3],[62,3],[105,3],[1034,3],[2717,4],[4376,3]]},"3932":{"position":[[727,4]]},"3941":{"position":[[1543,3]]},"3947":{"position":[[1365,3],[1906,3],[4034,3],[4058,3]]},"3968":{"position":[[1744,3]]},"3982":{"position":[[52,3]]},"4013":{"position":[[581,4]]},"4015":{"position":[[464,3],[558,3]]},"4021":{"position":[[33,3]]},"4030":{"position":[[0,3]]},"4034":{"position":[[273,3]]},"4041":{"position":[[488,3]]},"4047":{"position":[[462,4]]},"4081":{"position":[[648,3]]},"4094":{"position":[[546,3],[628,3]]},"4102":{"position":[[917,3]]},"4104":{"position":[[136,3]]},"4109":{"position":[[616,3],[639,3]]},"4113":{"position":[[1758,3]]},"4126":{"position":[[414,3]]},"4137":{"position":[[644,3]]},"4139":{"position":[[347,3]]},"4146":{"position":[[1499,3]]},"4153":{"position":[[317,3]]},"4159":{"position":[[563,3],[1185,3],[2258,3]]},"4161":{"position":[[569,3],[1116,3]]},"4163":{"position":[[582,3],[1074,3],[1524,3],[1702,3],[2013,3],[2335,3],[2958,3],[3049,3],[3838,3],[5600,3],[5861,3],[5921,3]]},"4165":{"position":[[141,3],[450,3]]},"4167":{"position":[[322,3],[397,3]]},"4178":{"position":[[338,3]]},"4180":{"position":[[267,3]]},"4220":{"position":[[43,3],[1499,3]]},"4230":{"position":[[2207,3]]},"4236":{"position":[[521,3]]},"4251":{"position":[[208,3]]},"4257":{"position":[[75,3],[143,3],[2534,3]]},"4277":{"position":[[171,3]]},"4302":{"position":[[2607,4],[3339,3]]},"4359":{"position":[[191,3]]},"4370":{"position":[[371,3]]},"4395":{"position":[[311,3]]},"4410":{"position":[[316,4]]},"4414":{"position":[[100,3]]},"4427":{"position":[[165,3]]},"4433":{"position":[[860,3],[1460,3],[2481,3]]},"4435":{"position":[[814,4]]},"4440":{"position":[[156,3]]},"4446":{"position":[[1050,3]]},"4448":{"position":[[613,3]]},"4451":{"position":[[156,3]]},"4457":{"position":[[1050,3]]},"4459":{"position":[[339,3],[1662,3]]},"4493":{"position":[[202,3],[229,3],[257,3],[287,3]]},"4516":{"position":[[445,3]]},"4539":{"position":[[756,3],[1138,3],[3060,3],[6386,3],[6930,3]]},"4547":{"position":[[797,3],[2095,3],[2424,3],[2476,3]]},"4560":{"position":[[460,3]]},"4562":{"position":[[2208,3],[3570,3],[4337,3]]},"4589":{"position":[[166,3]]},"4591":{"position":[[781,3],[985,3]]},"4593":{"position":[[4854,3]]},"4595":{"position":[[117,3]]},"4597":{"position":[[272,3]]},"4610":{"position":[[267,3]]},"4632":{"position":[[1179,3]]},"4656":{"position":[[499,4]]},"4691":{"position":[[217,3]]},"4701":{"position":[[188,3],[217,3]]},"4740":{"position":[[391,3]]},"4845":{"position":[[30,3],[135,3]]},"4861":{"position":[[483,3]]}}}],["on_behalf_of",{"_index":9666,"t":{"3036":{"position":[[14549,13]]}}}],["on_image_delet",{"_index":8389,"t":{"2351":{"position":[[722,18]]},"2418":{"position":[[722,18]]}}}],["onboard",{"_index":1813,"t":{"266":{"position":[[327,7],[366,10],[393,10]]},"1111":{"position":[[490,7]]},"3238":{"position":[[26,10]]},"3460":{"position":[[255,10]]},"3470":{"position":[[826,10]]},"3627":{"position":[[603,10]]},"3629":{"position":[[200,9]]},"3638":{"position":[[135,10]]},"4587":{"position":[[462,10]]},"4593":{"position":[[2249,7]]},"4643":{"position":[[234,10],[305,9]]},"4826":{"position":[[3617,10]]}}}],["onc",{"_index":658,"t":{"95":{"position":[[597,4]]},"130":{"position":[[648,4]]},"136":{"position":[[75,4]]},"239":{"position":[[73,4]]},"440":{"position":[[437,4]]},"491":{"position":[[641,4],[772,4]]},"493":{"position":[[444,4]]},"496":{"position":[[496,4]]},"498":{"position":[[390,4]]},"504":{"position":[[186,4]]},"510":{"position":[[342,4]]},"588":{"position":[[1713,4]]},"880":{"position":[[220,4]]},"912":{"position":[[215,4]]},"940":{"position":[[1691,4]]},"949":{"position":[[709,4]]},"978":{"position":[[2109,4]]},"1234":{"position":[[0,4]]},"1497":{"position":[[205,4]]},"1646":{"position":[[1841,5]]},"1781":{"position":[[220,4]]},"1796":{"position":[[215,4]]},"1831":{"position":[[1691,4]]},"1840":{"position":[[709,4]]},"1869":{"position":[[2109,4]]},"2037":{"position":[[794,4]]},"2114":{"position":[[166,4]]},"2188":{"position":[[198,4]]},"2266":{"position":[[538,4]]},"2341":{"position":[[105,4]]},"2355":{"position":[[1451,4],[2874,4],[3127,4]]},"2408":{"position":[[105,4]]},"2422":{"position":[[1451,4],[2874,4],[3127,4]]},"2431":{"position":[[1691,4]]},"2441":{"position":[[453,4]]},"2445":{"position":[[106,5]]},"2478":{"position":[[1133,4]]},"2594":{"position":[[81,4]]},"2665":{"position":[[0,4]]},"2756":{"position":[[2348,4]]},"2964":{"position":[[1691,4]]},"2973":{"position":[[709,4]]},"3002":{"position":[[2109,4]]},"3325":{"position":[[132,4]]},"3533":{"position":[[2644,4]]},"3537":{"position":[[0,4]]},"3598":{"position":[[509,4]]},"3731":{"position":[[1054,4],[2058,4]]},"3829":{"position":[[848,4],[909,4],[971,4],[1030,4],[1087,4],[4861,4]]},"3881":{"position":[[415,4]]},"3925":{"position":[[519,4]]},"3971":{"position":[[474,4]]},"4034":{"position":[[248,6]]},"4041":{"position":[[367,4]]},"4109":{"position":[[467,4],[542,4],[679,4]]},"4113":{"position":[[2014,5],[2066,5]]},"4171":{"position":[[357,5]]},"4230":{"position":[[1924,4]]},"4257":{"position":[[229,4],[402,4]]},"4275":{"position":[[355,4]]},"4313":{"position":[[633,4]]},"4420":{"position":[[2211,4]]},"4493":{"position":[[385,4]]},"4660":{"position":[[802,5]]},"4669":{"position":[[178,4]]},"4863":{"position":[[0,4]]}}}],["oneself",{"_index":10288,"t":{"3636":{"position":[[133,8]]}}}],["ones—to",{"_index":10023,"t":{"3361":{"position":[[229,7]]}}}],["ongo",{"_index":8568,"t":{"2512":{"position":[[1354,7]]},"2814":{"position":[[417,8],[626,7]]},"4240":{"position":[[488,7]]},"4270":{"position":[[129,7]]},"4291":{"position":[[957,7]]},"4580":{"position":[[2531,7]]},"4699":{"position":[[170,7]]}}}],["ongoing\",\"work",{"_index":9068,"t":{"2760":{"position":[[118,17]]}}}],["onlin",{"_index":4434,"t":{"1067":{"position":[[687,7]]},"1580":{"position":[[127,6]]},"1648":{"position":[[823,6]]},"1923":{"position":[[127,6]]},"3533":{"position":[[433,6]]},"3731":{"position":[[1318,6]]},"4839":{"position":[[650,6]]}}}],["onto",{"_index":7419,"t":{"2052":{"position":[[149,4]]},"2355":{"position":[[626,4],[1720,4],[2936,4]]},"2422":{"position":[[626,4],[1720,4],[2936,4]]},"2489":{"position":[[1324,4]]},"3638":{"position":[[146,4]]},"4047":{"position":[[37,4]]},"4150":{"position":[[39,4]]},"4222":{"position":[[3237,4]]}}}],["onward",{"_index":6317,"t":{"1507":{"position":[[29,8]]},"1509":{"position":[[29,8]]},"4479":{"position":[[1105,8]]}}}],["op",{"_index":2091,"t":{"334":{"position":[[18,3]]},"2139":{"position":[[569,2]]},"2431":{"position":[[388,3],[1126,2],[3060,2],[3557,2],[3644,2],[4232,2]]},"3052":{"position":[[439,3]]},"3357":{"position":[[205,3],[1218,3],[1375,3],[1490,3],[1606,3],[1745,3],[1861,3]]},"3527":{"position":[[1621,3],[1947,3]]},"3531":{"position":[[373,4]]},"4826":{"position":[[3775,3],[3823,3],[3889,3],[3938,3],[4042,3],[4095,3],[4160,3]]}}}],["open",{"_index":21,"t":{"7":{"position":[[28,4],[133,5],[365,4]]},"70":{"position":[[120,4]]},"72":{"position":[[153,4],[276,4]]},"78":{"position":[[407,8]]},"136":{"position":[[166,4]]},"163":{"position":[[304,4]]},"169":{"position":[[432,4]]},"171":{"position":[[1298,4]]},"173":{"position":[[338,4],[1287,4],[1662,4],[1795,4],[1928,4],[2185,4]]},"179":{"position":[[364,4],[693,4],[1184,4],[1350,4],[1463,4],[1582,4]]},"181":{"position":[[9,4],[365,4],[516,4],[2359,5]]},"183":{"position":[[25,4]]},"185":{"position":[[215,4]]},"187":{"position":[[108,4],[253,4],[1126,4]]},"190":{"position":[[33,5],[165,5]]},"192":{"position":[[0,4],[27,4],[155,4],[172,4],[212,4],[320,4]]},"194":{"position":[[16,4],[28,4],[260,4],[341,4],[389,5],[416,4],[512,4]]},"197":{"position":[[269,5],[377,6],[391,4],[502,4],[578,5],[584,4],[623,4]]},"201":{"position":[[716,4]]},"249":{"position":[[367,4],[529,4],[687,4],[1205,4],[1323,4]]},"253":{"position":[[308,7]]},"262":{"position":[[19,4]]},"266":{"position":[[183,7]]},"280":{"position":[[363,4],[1265,4]]},"282":{"position":[[383,4]]},"293":{"position":[[804,5]]},"332":{"position":[[136,4]]},"368":{"position":[[7260,5]]},"419":{"position":[[78,4]]},"514":{"position":[[535,4]]},"524":{"position":[[144,6],[880,6]]},"653":{"position":[[692,4]]},"703":{"position":[[90,4]]},"741":{"position":[[152,4]]},"776":{"position":[[57,4]]},"840":{"position":[[4,4]]},"842":{"position":[[11,4]]},"846":{"position":[[769,4]]},"938":{"position":[[643,4],[1692,4]]},"961":{"position":[[865,6]]},"969":{"position":[[213,4]]},"1061":{"position":[[11,4],[803,4]]},"1073":{"position":[[4,4]]},"1111":{"position":[[345,4]]},"1238":{"position":[[214,5]]},"1503":{"position":[[647,4]]},"1519":{"position":[[0,4],[75,4],[400,4]]},"1525":{"position":[[727,4]]},"1564":{"position":[[150,4],[226,4],[304,4],[377,4],[464,4]]},"1700":{"position":[[20,4]]},"1702":{"position":[[67,4]]},"1829":{"position":[[643,4],[1692,4]]},"1852":{"position":[[865,6]]},"1860":{"position":[[213,4]]},"2023":{"position":[[79,4]]},"2173":{"position":[[0,4],[86,4],[405,4]]},"2178":{"position":[[547,4]]},"2196":{"position":[[201,4]]},"2234":{"position":[[456,4]]},"2270":{"position":[[437,7]]},"2287":{"position":[[329,6]]},"2301":{"position":[[329,6]]},"2431":{"position":[[556,4],[806,4],[971,4],[2688,4],[3251,4]]},"2489":{"position":[[1439,4]]},"2499":{"position":[[210,4]]},"2503":{"position":[[407,4]]},"2506":{"position":[[230,4]]},"2512":{"position":[[97,4],[179,4]]},"2549":{"position":[[66,4]]},"2572":{"position":[[22,4],[473,4]]},"2574":{"position":[[29,4]]},"2590":{"position":[[26,4]]},"2712":{"position":[[1710,4]]},"2832":{"position":[[176,5]]},"2962":{"position":[[643,4],[1692,4]]},"2985":{"position":[[865,6]]},"2993":{"position":[[213,4]]},"3073":{"position":[[74,4]]},"3103":{"position":[[416,5]]},"3119":{"position":[[180,4]]},"3132":{"position":[[134,4]]},"3136":{"position":[[416,5]]},"3144":{"position":[[373,4]]},"3148":{"position":[[293,5],[335,6]]},"3176":{"position":[[329,4]]},"3202":{"position":[[145,4]]},"3214":{"position":[[320,4]]},"3323":{"position":[[354,4]]},"3346":{"position":[[717,4],[874,6]]},"3348":{"position":[[331,4],[464,4]]},"3352":{"position":[[3737,4]]},"3357":{"position":[[615,4]]},"3361":{"position":[[270,9]]},"3367":{"position":[[615,4],[950,4]]},"3381":{"position":[[2613,4]]},"3384":{"position":[[1602,4]]},"3386":{"position":[[221,4]]},"3519":{"position":[[267,8]]},"3529":{"position":[[836,4],[895,4]]},"3582":{"position":[[413,4],[1238,4]]},"3594":{"position":[[70,4],[391,4],[544,4]]},"3621":{"position":[[114,4]]},"3623":{"position":[[152,4]]},"3625":{"position":[[36,4]]},"3642":{"position":[[19,4]]},"3984":{"position":[[933,7],[1062,7]]},"4045":{"position":[[1040,4],[1433,4]]},"4146":{"position":[[3072,4],[3108,4],[3180,8]]},"4224":{"position":[[918,4]]},"4226":{"position":[[720,4],[1177,4],[2842,4],[3254,4]]},"4228":{"position":[[640,4],[1494,4]]},"4230":{"position":[[806,4],[5262,4]]},"4234":{"position":[[234,4]]},"4244":{"position":[[160,4],[340,4]]},"4246":{"position":[[149,4],[329,4]]},"4257":{"position":[[3996,4]]},"4259":{"position":[[774,4]]},"4283":{"position":[[782,4]]},"4306":{"position":[[654,4]]},"4418":{"position":[[246,4],[413,5],[434,4],[460,4],[501,5],[525,5]]},"4554":{"position":[[449,4]]},"4556":{"position":[[169,4]]},"4560":{"position":[[6,4],[923,4],[1167,6],[1189,4],[1248,5],[1439,4],[1532,4],[2653,6],[2675,4],[2734,4],[2878,4],[2971,4],[3873,6],[3895,4],[3954,4],[4017,4],[4108,4],[4224,4],[5188,5],[5254,4],[5368,4]]},"4562":{"position":[[41,4],[201,4],[257,4],[395,4],[476,4],[1019,4],[1655,4],[2595,4],[3494,4],[4068,4],[4114,4],[4564,4]]},"4593":{"position":[[94,4],[3236,4]]},"4742":{"position":[[832,4]]},"4826":{"position":[[64,4]]},"4835":{"position":[[1719,4]]},"4839":{"position":[[137,4],[788,4],[1150,9]]},"4857":{"position":[[470,4]]}}}],["open('image.key",{"_index":8407,"t":{"2360":{"position":[[1407,17]]},"2427":{"position":[[1407,17]]}}}],["openapi",{"_index":9152,"t":{"2794":{"position":[[123,8]]},"2804":{"position":[[18,7],[47,7]]},"2845":{"position":[[173,8]]},"2918":{"position":[[751,7],[779,7]]},"2934":{"position":[[157,7]]},"2940":{"position":[[104,7]]},"3153":{"position":[[762,7]]},"3294":{"position":[[1121,7]]},"3502":{"position":[[857,7]]},"4674":{"position":[[71,7]]},"4679":{"position":[[138,7]]},"4684":{"position":[[19,7]]},"4826":{"position":[[3905,7]]}}}],["opendesk",{"_index":11846,"t":{"4831":{"position":[[0,8],[100,9]]},"4835":{"position":[[1374,8],[1422,8],[1463,8]]},"4839":{"position":[[49,8],[105,8],[1241,8],[1398,8],[1616,8],[1728,8],[1841,8]]},"4841":{"position":[[57,9]]},"4843":{"position":[[10,8],[127,8]]},"4849":{"position":[[525,10]]},"4853":{"position":[[302,9]]},"4861":{"position":[[241,8],[274,8],[368,8]]},"4863":{"position":[[311,9]]},"4865":{"position":[[45,8]]},"4868":{"position":[[142,8]]},"4872":{"position":[[0,8],[124,8]]},"4877":{"position":[[4,8]]},"4885":{"position":[[17,8]]}}}],["opendesk_main.gotmpl",{"_index":11860,"t":{"4833":{"position":[[371,20]]}}}],["opendesk_master_password",{"_index":11969,"t":{"4855":{"position":[[67,39]]}}}],["opendesk_smtprelay_password",{"_index":11968,"t":{"4855":{"position":[[24,42]]}}}],["opendev",{"_index":7646,"t":{"2123":{"position":[[795,7]]},"2380":{"position":[[165,7],[566,7]]}}}],["opendevorg",{"_index":7645,"t":{"2123":{"position":[[777,11],[897,11]]}}}],["opendistro",{"_index":6462,"t":{"1564":{"position":[[382,11]]}}}],["openid",{"_index":2029,"t":{"311":{"position":[[271,6]]},"313":{"position":[[102,6]]},"317":{"position":[[132,6]]},"319":{"position":[[136,6],[343,6]]},"325":{"position":[[41,6],[136,6]]},"2196":{"position":[[20,6],[1790,6],[2385,6],[2580,6],[3190,6],[3346,6],[3359,7]]},"2366":{"position":[[273,6]]},"2374":{"position":[[83,6]]},"2376":{"position":[[154,6]]},"2380":{"position":[[903,6]]},"2431":{"position":[[668,6],[1071,6],[1315,6]]},"2906":{"position":[[10,6]]},"3086":{"position":[[994,6]]},"3238":{"position":[[560,7],[807,6]]},"3255":{"position":[[44,6]]},"3294":{"position":[[826,7]]},"3313":{"position":[[188,6]]},"4589":{"position":[[268,6]]},"4593":{"position":[[3595,6]]}}}],["openidconnect",{"_index":11614,"t":{"4539":{"position":[[3861,13]]}}}],["openinfra",{"_index":4442,"t":{"1073":{"position":[[39,9]]},"3361":{"position":[[141,9]]},"3640":{"position":[[167,9]]}}}],["openldap",{"_index":11710,"t":{"4593":{"position":[[1449,9]]}}}],["openli",{"_index":11200,"t":{"4109":{"position":[[4156,6]]}}}],["openproject",{"_index":11893,"t":{"4835":{"position":[[1507,11],[1608,11]]},"4839":{"position":[[542,13]]},"4849":{"position":[[1732,12]]}}}],["openrc",{"_index":385,"t":{"37":{"position":[[1403,6]]},"1314":{"position":[[21,6]]},"2274":{"position":[[17,6]]},"2276":{"position":[[21,6],[2614,6]]},"2279":{"position":[[584,6]]},"2281":{"position":[[42,6]]}}}],["openrc.sh",{"_index":395,"t":{"37":{"position":[[1540,9]]},"701":{"position":[[495,9]]},"2250":{"position":[[79,9]]},"2276":{"position":[[76,9],[2689,9]]},"2279":{"position":[[652,9]]},"2281":{"position":[[182,9]]}}}],["opensearch",{"_index":5224,"t":{"1261":{"position":[[27,10],[80,10],[138,10],[214,10]]},"1303":{"position":[[32,10],[77,10],[150,10],[238,10],[295,10],[519,16],[782,10],[872,10],[1978,11],[2427,10],[2648,10],[3369,10],[3445,10],[4325,13],[4691,10],[4962,13]]},"1521":{"position":[[132,10],[143,10],[191,10],[228,10],[251,10]]},"1564":{"position":[[231,11]]},"1698":{"position":[[0,10],[48,10]]},"2029":{"position":[[173,11],[494,10]]},"2039":{"position":[[745,10],[799,10]]},"2169":{"position":[[0,10],[11,10],[59,10],[96,10],[130,10]]},"2184":{"position":[[5569,10]]},"2194":{"position":[[1274,10],[1331,10]]},"2225":{"position":[[245,10]]},"3352":{"position":[[3302,10],[3423,11]]}}}],["opensearch.yml",{"_index":5531,"t":{"1303":{"position":[[420,18],[555,18],[2252,17],[2567,14]]}}}],["opensearch.yml.j2",{"_index":5537,"t":{"1303":{"position":[[825,17],[897,17],[2402,17]]}}}],["opensearch/opensearch.yml",{"_index":5532,"t":{"1303":{"position":[[464,29],[606,29]]}}}],["opensearch:opensearch",{"_index":5590,"t":{"1303":{"position":[[4418,24],[4510,24],[5055,24],[5147,24]]}}}],["opensearch_cluster_nam",{"_index":5549,"t":{"1303":{"position":[[1279,23]]}}}],["opensearch_port",{"_index":5556,"t":{"1303":{"position":[[1683,15]]}}}],["opensearch_services['opensearch'].en",{"_index":5536,"t":{"1303":{"position":[[715,41]]}}}],["openshift",{"_index":4448,"t":{"1073":{"position":[[657,10]]},"1075":{"position":[[60,9]]},"1077":{"position":[[60,9]]},"1079":{"position":[[44,9]]},"1081":{"position":[[60,9]]}}}],["openssh",{"_index":4088,"t":{"969":{"position":[[172,7]]},"1149":{"position":[[146,7]]},"1466":{"position":[[2956,7]]},"1675":{"position":[[11,7]]},"1860":{"position":[[172,7]]},"2993":{"position":[[172,7]]}}}],["openssl",{"_index":9804,"t":{"3164":{"position":[[190,7]]},"3759":{"position":[[300,7]]}}}],["openst",{"_index":7774,"t":{"2155":{"position":[[2644,8]]}}}],["openstack",{"_index":332,"t":{"37":{"position":[[164,9],[1247,9],[1499,9],[1568,9],[1616,9],[1761,9],[1800,9],[1856,9],[1866,9]]},"39":{"position":[[33,9]]},"41":{"position":[[0,9]]},"49":{"position":[[25,9]]},"56":{"position":[[26,9]]},"167":{"position":[[148,9]]},"282":{"position":[[429,10]]},"309":{"position":[[212,9]]},"313":{"position":[[54,10],[77,9],[161,10]]},"319":{"position":[[372,9]]},"323":{"position":[[894,9],[989,9],[1106,9],[1320,9],[1473,9]]},"327":{"position":[[11,9]]},"337":{"position":[[388,9]]},"343":{"position":[[296,10]]},"368":{"position":[[2439,9]]},"376":{"position":[[230,9],[362,9],[446,9]]},"378":{"position":[[326,10],[402,12]]},"498":{"position":[[79,9],[243,9],[274,9]]},"500":{"position":[[27,9],[289,10],[380,9]]},"504":{"position":[[34,9]]},"512":{"position":[[159,10],[1085,10]]},"514":{"position":[[990,9],[1287,9],[1439,9]]},"518":{"position":[[721,9],[954,11]]},"522":{"position":[[455,9]]},"524":{"position":[[170,9],[290,9],[416,9],[542,9],[906,9],[1026,9],[1152,9],[1278,9]]},"526":{"position":[[114,9],[262,9],[297,9],[404,9],[459,9],[545,9],[767,10],[875,9],[1011,9],[1046,9],[1153,9],[1208,9],[1294,9],[1510,10]]},"528":{"position":[[15,9],[95,9],[228,9],[276,9]]},"530":{"position":[[316,10],[392,9]]},"535":{"position":[[83,10]]},"545":{"position":[[437,10]]},"555":{"position":[[470,9],[575,9],[625,9]]},"557":{"position":[[151,9],[284,9],[384,9],[513,9],[726,9],[1753,11],[1765,11],[1854,11],[1866,11],[4051,9],[4403,9]]},"572":{"position":[[118,9],[352,9]]},"576":{"position":[[181,9],[337,9]]},"578":{"position":[[92,9]]},"584":{"position":[[179,10],[218,10]]},"586":{"position":[[883,9]]},"590":{"position":[[1060,9],[1147,9],[1217,9],[1287,9],[1357,9],[1427,9]]},"701":{"position":[[155,9],[339,9],[366,9],[459,9],[1203,9],[1962,9],[2567,9]]},"732":{"position":[[164,9]]},"814":{"position":[[176,9]]},"818":{"position":[[52,9],[87,9],[148,9]]},"830":{"position":[[161,9]]},"834":{"position":[[5,9],[579,9]]},"836":{"position":[[6,9],[107,9]]},"838":{"position":[[4,9],[102,9]]},"840":{"position":[[88,9]]},"846":{"position":[[4,9],[76,10],[184,9],[545,9],[858,9]]},"848":{"position":[[0,9]]},"857":{"position":[[4,9],[68,9]]},"859":{"position":[[57,9],[125,9],[200,9]]},"861":{"position":[[4,9],[500,10],[1041,9]]},"865":{"position":[[57,9],[100,9],[137,9],[192,9],[330,9],[449,9],[1585,9],[1653,9],[1690,9],[1722,9]]},"875":{"position":[[472,9]]},"883":{"position":[[4,9]]},"885":{"position":[[100,9]]},"887":{"position":[[640,9],[1429,9]]},"890":{"position":[[4,9]]},"892":{"position":[[4,9],[209,9],[371,9],[463,9]]},"894":{"position":[[76,9],[452,9],[491,9],[1043,9],[1148,9],[1492,9],[1544,9],[1585,9]]},"896":{"position":[[247,9],[431,9]]},"901":{"position":[[4,9],[54,9]]},"903":{"position":[[19,9],[233,9]]},"908":{"position":[[89,9],[343,9]]},"910":{"position":[[76,9],[403,9]]},"912":{"position":[[176,10],[261,9],[3954,9],[5737,9],[5767,9],[5996,9],[6166,9],[6501,9],[7066,10]]},"914":{"position":[[81,9],[172,9]]},"924":{"position":[[19,9],[1028,9],[1791,9],[2108,9]]},"926":{"position":[[80,9],[284,11]]},"928":{"position":[[629,9]]},"930":{"position":[[439,9],[472,9],[567,9],[705,9]]},"932":{"position":[[39,9],[589,9],[625,9],[692,9],[730,9],[821,9],[929,9],[969,9],[1070,9],[1231,9],[1271,9],[1435,9],[1917,9],[2563,9],[2647,9],[2716,9],[2740,9],[2765,9],[3514,9]]},"934":{"position":[[23,9],[706,9],[1612,9],[1717,9],[1738,9],[1761,9],[1878,9]]},"938":{"position":[[9,9],[172,9],[377,9],[782,9],[1444,9],[1794,9],[1822,9],[2102,9]]},"940":{"position":[[1438,9],[1461,9],[1498,9],[1527,9]]},"942":{"position":[[557,9],[577,9],[3909,11]]},"946":{"position":[[368,9]]},"951":{"position":[[180,9],[1073,9]]},"961":{"position":[[994,9],[1031,9],[1129,9]]},"967":{"position":[[120,9]]},"971":{"position":[[36,9]]},"978":{"position":[[112,9],[539,9]]},"980":{"position":[[257,9]]},"983":{"position":[[19,9],[112,9],[276,9]]},"999":{"position":[[4,9],[60,9]]},"1001":{"position":[[19,9],[106,9]]},"1005":{"position":[[76,9],[2230,9]]},"1013":{"position":[[40,9]]},"1028":{"position":[[39,9]]},"1036":{"position":[[94,9]]},"1046":{"position":[[143,9]]},"1054":{"position":[[40,9]]},"1056":{"position":[[1040,12]]},"1061":{"position":[[236,9]]},"1064":{"position":[[1261,10]]},"1067":{"position":[[0,9],[399,9],[712,10],[763,9],[970,9],[2125,9]]},"1073":{"position":[[110,10],[214,9],[388,10],[546,9],[574,9],[635,9]]},"1075":{"position":[[38,9]]},"1077":{"position":[[38,9]]},"1079":{"position":[[22,9]]},"1081":{"position":[[38,9]]},"1096":{"position":[[44,9]]},"1105":{"position":[[61,9]]},"1183":{"position":[[169,9]]},"1226":{"position":[[3545,9],[3670,9]]},"1230":{"position":[[1273,10]]},"1244":{"position":[[419,9],[762,9]]},"1248":{"position":[[1066,9],[1256,9]]},"1263":{"position":[[59,9],[264,10],[370,9],[577,9],[846,9]]},"1285":{"position":[[114,9]]},"1295":{"position":[[45,9]]},"1301":{"position":[[2123,9]]},"1324":{"position":[[575,9],[729,9],[7106,9],[12575,9],[12659,9],[13159,9]]},"1352":{"position":[[396,10]]},"1354":{"position":[[78,10]]},"1375":{"position":[[225,9],[761,9]]},"1379":{"position":[[125,9],[304,9]]},"1383":{"position":[[2370,9]]},"1407":{"position":[[5,9]]},"1503":{"position":[[2611,9]]},"1505":{"position":[[109,9],[307,9],[492,9],[632,9]]},"1511":{"position":[[307,9]]},"1513":{"position":[[65,9],[97,9]]},"1517":{"position":[[160,9]]},"1521":{"position":[[99,9]]},"1523":{"position":[[29,9],[70,9],[111,9],[219,9],[369,9],[480,9],[1417,9],[2208,9]]},"1525":{"position":[[1155,10],[2415,9]]},"1527":{"position":[[183,9]]},"1700":{"position":[[0,10],[58,9],[760,9]]},"1707":{"position":[[127,9]]},"1709":{"position":[[76,9],[321,9],[437,9]]},"1711":{"position":[[1080,9]]},"1713":{"position":[[231,9],[322,9],[438,9],[666,9],[1285,9],[1381,9],[1578,9],[2307,9],[2394,9]]},"1716":{"position":[[2,9],[1471,9]]},"1720":{"position":[[152,9],[639,9],[1279,9],[1349,9],[2044,9],[2163,9]]},"1725":{"position":[[69,9]]},"1728":{"position":[[0,9]]},"1730":{"position":[[14,11],[172,9]]},"1732":{"position":[[0,9],[111,9],[1011,9],[1095,9]]},"1734":{"position":[[0,9],[112,9],[1006,9],[1116,9]]},"1740":{"position":[[91,9]]},"1745":{"position":[[79,9]]},"1748":{"position":[[4,9]]},"1750":{"position":[[4,9],[209,9],[371,9],[463,9]]},"1752":{"position":[[76,9],[452,9],[491,9],[1043,9],[1148,9],[1492,9],[1544,9],[1585,9]]},"1754":{"position":[[247,9],[431,9]]},"1758":{"position":[[4,9],[68,9]]},"1760":{"position":[[57,9],[125,9],[200,9]]},"1762":{"position":[[4,9],[500,10],[1041,9]]},"1766":{"position":[[57,9],[100,9],[137,9],[192,9],[330,9],[449,9],[1585,9],[1653,9],[1690,9],[1722,9]]},"1776":{"position":[[472,9]]},"1785":{"position":[[4,9],[54,9]]},"1787":{"position":[[19,9],[233,9]]},"1792":{"position":[[89,9],[343,9]]},"1794":{"position":[[76,9],[403,9]]},"1796":{"position":[[176,10],[261,9],[3954,9],[5737,9],[5767,9],[5996,9],[6166,9],[6501,9],[7066,10]]},"1798":{"position":[[81,9],[172,9]]},"1807":{"position":[[4,9]]},"1809":{"position":[[100,9]]},"1811":{"position":[[640,9],[1429,9]]},"1815":{"position":[[19,9],[1028,9],[1791,9],[2108,9]]},"1817":{"position":[[80,9],[284,11]]},"1819":{"position":[[629,9]]},"1821":{"position":[[439,9],[472,9],[567,9],[705,9]]},"1823":{"position":[[39,9],[589,9],[625,9],[692,9],[730,9],[821,9],[929,9],[969,9],[1070,9],[1231,9],[1271,9],[1435,9],[1917,9],[2563,9],[2647,9],[2716,9],[2740,9],[2765,9],[3514,9]]},"1825":{"position":[[23,9],[706,9],[1612,9],[1717,9],[1738,9],[1761,9],[1878,9]]},"1829":{"position":[[9,9],[172,9],[377,9],[782,9],[1444,9],[1794,9],[1822,9],[2102,9]]},"1831":{"position":[[1438,9],[1461,9],[1498,9],[1527,9]]},"1833":{"position":[[557,9],[577,9],[3909,11]]},"1837":{"position":[[368,9]]},"1842":{"position":[[180,9],[1073,9]]},"1852":{"position":[[994,9],[1031,9],[1129,9]]},"1858":{"position":[[120,9]]},"1862":{"position":[[36,9]]},"1869":{"position":[[112,9],[539,9]]},"1871":{"position":[[257,9]]},"1874":{"position":[[19,9],[112,9],[276,9]]},"1890":{"position":[[4,9],[60,9]]},"1892":{"position":[[19,9],[106,9]]},"1896":{"position":[[76,9],[2230,9]]},"2034":{"position":[[1440,9]]},"2039":{"position":[[441,9],[861,9]]},"2041":{"position":[[235,9],[265,10],[276,9],[309,9],[330,9]]},"2043":{"position":[[4,9]]},"2048":{"position":[[3494,9]]},"2055":{"position":[[232,10],[603,9],[621,9]]},"2057":{"position":[[534,9],[615,9],[834,9],[869,9]]},"2117":{"position":[[415,9]]},"2155":{"position":[[2591,9],[2653,9]]},"2175":{"position":[[101,9]]},"2178":{"position":[[69,9],[154,9]]},"2184":{"position":[[151,9],[4188,9],[4984,9],[5081,9],[5483,9],[5638,9],[6087,9],[6288,9],[6364,9],[6599,9]]},"2194":{"position":[[584,9],[673,9],[762,9],[1465,9]]},"2196":{"position":[[126,9],[222,9],[512,9],[1553,9],[1636,9],[1733,9],[1760,9],[1825,9],[2017,9],[2042,9],[2059,9],[2549,9],[2822,9],[2847,9],[2864,9],[3696,9],[3738,9]]},"2199":{"position":[[30,9],[53,9],[196,9],[219,9],[606,9],[629,9],[956,9],[980,9],[1003,9]]},"2201":{"position":[[62,9],[101,9]]},"2203":{"position":[[374,9],[434,9]]},"2205":{"position":[[264,9],[325,9]]},"2211":{"position":[[45,9],[288,9],[1847,9]]},"2223":{"position":[[30,9],[174,9],[211,9],[228,9],[245,9]]},"2225":{"position":[[304,10]]},"2231":{"position":[[32,9],[204,9],[1089,9]]},"2234":{"position":[[89,10],[113,9],[590,10],[727,10],[799,9]]},"2236":{"position":[[35,9],[393,9],[485,9]]},"2238":{"position":[[88,9]]},"2240":{"position":[[1034,9]]},"2246":{"position":[[182,10]]},"2248":{"position":[[227,10]]},"2250":{"position":[[27,9],[129,9],[277,9],[449,9],[536,9],[558,9],[776,9]]},"2252":{"position":[[167,10],[332,9],[421,9],[696,9],[1659,9],[2502,9]]},"2254":{"position":[[0,9],[686,9]]},"2256":{"position":[[42,9],[818,9]]},"2261":{"position":[[238,9]]},"2263":{"position":[[118,9]]},"2266":{"position":[[284,9],[429,9],[625,9]]},"2268":{"position":[[91,9],[309,9],[341,11]]},"2270":{"position":[[48,9],[325,9],[468,9],[770,9]]},"2272":{"position":[[149,9],[306,9],[327,9]]},"2276":{"position":[[118,9],[579,9],[1356,9],[1527,9],[2145,10],[2742,10]]},"2279":{"position":[[54,12]]},"2281":{"position":[[305,10]]},"2283":{"position":[[19,9]]},"2289":{"position":[[480,9],[704,9],[902,9]]},"2291":{"position":[[337,9]]},"2293":{"position":[[522,9],[558,9],[692,9],[729,9],[865,9],[903,9],[1040,9],[1077,9]]},"2295":{"position":[[418,9],[609,9],[747,9]]},"2297":{"position":[[19,9]]},"2303":{"position":[[480,9],[704,9],[902,9]]},"2305":{"position":[[337,9]]},"2307":{"position":[[522,9],[558,9],[692,9],[729,9],[865,9],[903,9],[1040,9],[1077,9]]},"2309":{"position":[[418,9],[609,9],[747,9]]},"2325":{"position":[[1002,9],[1070,9]]},"2327":{"position":[[68,9],[608,9],[634,9]]},"2331":{"position":[[72,9],[99,9],[264,9]]},"2333":{"position":[[293,9],[466,9]]},"2337":{"position":[[244,9]]},"2339":{"position":[[527,9],[680,9],[893,9],[1084,9],[1126,9]]},"2341":{"position":[[385,9],[544,9],[643,9]]},"2343":{"position":[[392,9],[627,9],[1088,9],[1254,10]]},"2347":{"position":[[213,9],[813,9],[1020,9]]},"2349":{"position":[[126,9]]},"2351":{"position":[[362,9]]},"2353":{"position":[[350,9],[568,9],[704,9]]},"2355":{"position":[[704,9],[1163,9],[2357,9],[2735,9],[2945,9]]},"2358":{"position":[[47,10]]},"2360":{"position":[[91,9],[136,9],[318,10],[536,9],[741,9],[873,9],[1149,9]]},"2372":{"position":[[214,9],[419,9]]},"2376":{"position":[[226,9]]},"2378":{"position":[[16,9]]},"2380":{"position":[[249,9]]},"2392":{"position":[[1002,9],[1070,9]]},"2394":{"position":[[68,9],[608,9],[634,9]]},"2398":{"position":[[72,9],[99,9],[264,9]]},"2400":{"position":[[293,9],[466,9]]},"2404":{"position":[[244,9]]},"2406":{"position":[[527,9],[680,9],[893,9],[1084,9],[1126,9]]},"2408":{"position":[[385,9],[544,9],[643,9]]},"2410":{"position":[[392,9],[627,9],[1088,9],[1254,10]]},"2414":{"position":[[213,9],[813,9],[1020,9]]},"2416":{"position":[[126,9]]},"2418":{"position":[[362,9]]},"2420":{"position":[[350,9],[568,9],[704,9]]},"2422":{"position":[[704,9],[1163,9],[2357,9],[2735,9],[2945,9]]},"2425":{"position":[[47,10]]},"2427":{"position":[[91,9],[136,9],[318,10],[536,9],[741,9],[873,9],[1149,9]]},"2433":{"position":[[1052,9]]},"2437":{"position":[[78,9]]},"2439":{"position":[[55,9],[911,9]]},"2441":{"position":[[352,9]]},"2445":{"position":[[183,9]]},"2451":{"position":[[420,9]]},"2453":{"position":[[696,9],[1112,9]]},"2455":{"position":[[0,9]]},"2457":{"position":[[115,9]]},"2461":{"position":[[33,9]]},"2463":{"position":[[36,9]]},"2465":{"position":[[34,9],[382,9],[450,9]]},"2467":{"position":[[474,9],[571,9],[680,9],[792,9],[929,9],[1029,9],[1141,9],[1256,9]]},"2563":{"position":[[170,9]]},"2567":{"position":[[813,10]]},"2574":{"position":[[212,9],[268,9],[301,9],[439,9]]},"2576":{"position":[[189,9]]},"2580":{"position":[[460,9],[700,9]]},"2584":{"position":[[196,9],[334,9]]},"2600":{"position":[[104,9]]},"2602":{"position":[[197,9]]},"2638":{"position":[[225,9]]},"2647":{"position":[[35,9],[101,9],[348,9],[479,9],[557,9],[776,9],[1018,9],[1189,9],[1416,9],[1444,9],[1865,9],[2428,9],[2522,9],[2581,9],[2666,9]]},"2688":{"position":[[145,9]]},"2690":{"position":[[80,9]]},"2692":{"position":[[939,9],[1115,9],[1551,10],[1822,9]]},"2701":{"position":[[86,10]]},"2709":{"position":[[0,9],[35,9]]},"2712":{"position":[[281,9],[708,9],[1670,9]]},"2714":{"position":[[553,9]]},"2716":{"position":[[65,9],[1276,9]]},"2948":{"position":[[19,9],[1028,9],[1791,9],[2108,9]]},"2950":{"position":[[80,9],[284,11]]},"2952":{"position":[[629,9]]},"2954":{"position":[[439,9],[472,9],[567,9],[705,9]]},"2956":{"position":[[39,9],[589,9],[625,9],[692,9],[730,9],[821,9],[929,9],[969,9],[1070,9],[1231,9],[1271,9],[1435,9],[1917,9],[2563,9],[2647,9],[2716,9],[2740,9],[2765,9],[3514,9]]},"2958":{"position":[[23,9],[706,9],[1612,9],[1717,9],[1738,9],[1761,9],[1878,9]]},"2962":{"position":[[9,9],[172,9],[377,9],[782,9],[1444,9],[1794,9],[1822,9],[2102,9]]},"2964":{"position":[[1438,9],[1461,9],[1498,9],[1527,9]]},"2966":{"position":[[557,9],[577,9],[3909,11]]},"2970":{"position":[[368,9]]},"2975":{"position":[[180,9],[1073,9]]},"2985":{"position":[[994,9],[1031,9],[1129,9]]},"2991":{"position":[[120,9]]},"2995":{"position":[[36,9]]},"3002":{"position":[[112,9],[539,9]]},"3004":{"position":[[257,9]]},"3016":{"position":[[227,9],[610,10],[700,9]]},"3022":{"position":[[1075,9],[1119,9]]},"3044":{"position":[[197,10]]},"3047":{"position":[[382,9]]},"3050":{"position":[[579,9]]},"3052":{"position":[[32,9]]},"3071":{"position":[[206,9],[340,9],[366,9]]},"3073":{"position":[[439,10],[1125,9],[1140,9]]},"3083":{"position":[[179,9],[621,9]]},"3086":{"position":[[591,9]]},"3095":{"position":[[0,9]]},"3103":{"position":[[131,9],[256,10]]},"3116":{"position":[[170,9],[359,9]]},"3119":{"position":[[30,9],[211,9],[1055,9]]},"3121":{"position":[[400,10],[459,9]]},"3136":{"position":[[131,9],[256,10]]},"3148":{"position":[[837,9]]},"3150":{"position":[[0,9]]},"3153":{"position":[[4,9],[900,9]]},"3159":{"position":[[151,9],[178,9]]},"3164":{"position":[[281,9]]},"3168":{"position":[[589,9]]},"3172":{"position":[[49,9],[112,9]]},"3183":{"position":[[59,9]]},"3185":{"position":[[335,9],[793,9]]},"3189":{"position":[[102,9],[270,9],[425,9]]},"3202":{"position":[[243,9]]},"3221":{"position":[[97,9]]},"3223":{"position":[[921,9],[1031,9],[1072,9]]},"3230":{"position":[[369,9],[439,9]]},"3234":{"position":[[203,9]]},"3236":{"position":[[183,9]]},"3238":{"position":[[842,9]]},"3255":{"position":[[18,9]]},"3264":{"position":[[436,9]]},"3266":{"position":[[353,9]]},"3279":{"position":[[97,9]]},"3281":{"position":[[304,10],[840,10],[868,9]]},"3292":{"position":[[663,9]]},"3296":{"position":[[1253,9],[1279,9]]},"3313":{"position":[[408,9],[584,9]]},"3315":{"position":[[118,9]]},"3352":{"position":[[2182,9],[2792,9],[3042,9],[3134,9]]},"3357":{"position":[[660,9]]},"3367":{"position":[[1070,9]]},"3378":{"position":[[12,9],[177,9]]},"3402":{"position":[[93,9]]},"3418":{"position":[[102,9]]},"3460":{"position":[[641,9]]},"3516":{"position":[[351,9]]},"3565":{"position":[[17,9]]},"3653":{"position":[[3,9],[165,9],[268,10]]},"3677":{"position":[[1444,9]]},"3683":{"position":[[188,9],[287,11]]},"3690":{"position":[[3,9],[165,9],[268,10]]},"3724":{"position":[[146,9],[240,9]]},"3742":{"position":[[450,9],[546,11],[696,9]]},"3751":{"position":[[50,9]]},"3777":{"position":[[3,9],[165,9],[268,10]]},"3791":{"position":[[1466,9]]},"3795":{"position":[[188,9],[287,11],[451,9]]},"3797":{"position":[[4,9]]},"3817":{"position":[[146,9],[240,9]]},"3826":{"position":[[87,12],[155,9],[517,9]]},"3840":{"position":[[4,9]]},"3845":{"position":[[41,9]]},"3853":{"position":[[213,10]]},"3859":{"position":[[40,9]]},"3883":{"position":[[153,9]]},"3885":{"position":[[4,9]]},"3890":{"position":[[40,9],[62,9],[100,9]]},"3892":{"position":[[3,9],[165,9],[268,10]]},"3904":{"position":[[997,9]]},"3906":{"position":[[155,9]]},"3908":{"position":[[4,9]]},"3918":{"position":[[429,9]]},"3920":{"position":[[4,9]]},"3932":{"position":[[31,9],[119,9]]},"3934":{"position":[[17,9]]},"3941":{"position":[[11,9]]},"3943":{"position":[[568,10]]},"3945":{"position":[[161,9]]},"3947":{"position":[[473,10],[564,10],[637,9]]},"3958":{"position":[[46,9]]},"3960":{"position":[[28,10],[87,9]]},"3962":{"position":[[30,9]]},"3978":{"position":[[24,11]]},"3980":{"position":[[425,10]]},"3982":{"position":[[339,9]]},"3988":{"position":[[235,9]]},"3990":{"position":[[306,9],[1422,9],[2574,9]]},"4005":{"position":[[94,10],[416,9]]},"4007":{"position":[[92,9]]},"4013":{"position":[[242,9]]},"4017":{"position":[[52,9],[159,9]]},"4026":{"position":[[369,9]]},"4034":{"position":[[73,9]]},"4037":{"position":[[24,11]]},"4039":{"position":[[227,9]]},"4041":{"position":[[180,9],[1159,9]]},"4043":{"position":[[403,9]]},"4045":{"position":[[88,9],[1170,9],[1610,9]]},"4047":{"position":[[54,9]]},"4051":{"position":[[130,9]]},"4053":{"position":[[142,9]]},"4055":{"position":[[131,9]]},"4064":{"position":[[149,10]]},"4066":{"position":[[48,9]]},"4073":{"position":[[413,9]]},"4075":{"position":[[107,9],[181,9],[241,9]]},"4077":{"position":[[681,9]]},"4081":{"position":[[320,10],[1783,9]]},"4089":{"position":[[133,9],[438,9]]},"4091":{"position":[[20,9]]},"4094":{"position":[[890,9]]},"4096":{"position":[[316,9],[431,11],[536,11],[663,11]]},"4109":{"position":[[3160,9],[3767,9]]},"4113":{"position":[[11,10]]},"4116":{"position":[[0,9]]},"4118":{"position":[[63,9]]},"4120":{"position":[[128,10]]},"4128":{"position":[[0,9],[48,9]]},"4130":{"position":[[414,9]]},"4146":{"position":[[627,9]]},"4148":{"position":[[322,9]]},"4153":{"position":[[32,9]]},"4155":{"position":[[480,11],[585,11],[712,11],[879,9]]},"4200":{"position":[[15,9],[372,9],[627,9],[717,9]]},"4202":{"position":[[122,9],[170,9]]},"4204":{"position":[[116,9],[205,9]]},"4206":{"position":[[10,9]]},"4208":{"position":[[4,9]]},"4210":{"position":[[30,9]]},"4215":{"position":[[238,9],[329,9]]},"4220":{"position":[[1728,9]]},"4222":{"position":[[317,9],[2616,9]]},"4224":{"position":[[641,10],[826,9],[1195,9],[1301,9],[1383,9],[1512,9],[3085,9]]},"4226":{"position":[[128,9],[221,9],[320,10],[363,9]]},"4228":{"position":[[88,9],[1222,9],[1351,9],[1638,9]]},"4230":{"position":[[466,9],[876,9],[909,9],[972,9],[1119,9],[2699,9],[4039,9]]},"4232":{"position":[[171,10]]},"4234":{"position":[[199,9],[302,9]]},"4242":{"position":[[140,9]]},"4244":{"position":[[65,9],[251,9],[264,9],[700,9]]},"4246":{"position":[[54,9],[240,9],[253,9],[689,9]]},"4251":{"position":[[67,9],[234,9],[327,9],[391,10]]},"4253":{"position":[[269,9]]},"4257":{"position":[[62,9],[909,9],[987,9],[1078,9],[1170,10],[1332,9],[1816,9],[4658,9],[4801,9]]},"4259":{"position":[[77,9]]},"4261":{"position":[[475,9]]},"4263":{"position":[[0,9]]},"4270":{"position":[[80,9]]},"4294":{"position":[[483,9]]},"4296":{"position":[[88,9]]},"4298":{"position":[[58,9],[197,9],[264,9]]},"4300":{"position":[[50,9],[476,9],[690,9]]},"4302":{"position":[[114,9],[204,9],[244,9],[302,9],[423,9],[1259,9],[1833,9],[1979,9],[1999,9],[2173,10],[3545,9],[3967,9],[4934,10],[5050,9]]},"4304":{"position":[[138,10],[401,9],[727,9],[896,9],[1306,10]]},"4308":{"position":[[754,10]]},"4310":{"position":[[1128,9],[1231,9],[2292,9]]},"4313":{"position":[[580,9]]},"4317":{"position":[[187,9]]},"4321":{"position":[[30,9],[180,9],[389,9]]},"4323":{"position":[[33,9],[94,9],[196,9],[269,9],[475,9]]},"4325":{"position":[[132,9],[316,9]]},"4327":{"position":[[172,10]]},"4329":{"position":[[87,9]]},"4333":{"position":[[43,9],[107,9],[469,9]]},"4335":{"position":[[0,9],[25,9],[72,9],[126,9]]},"4337":{"position":[[362,9]]},"4580":{"position":[[1301,9],[3248,9]]},"4593":{"position":[[2308,9],[5233,9],[5898,9],[6061,9],[6116,9],[6158,10]]},"4595":{"position":[[169,9]]},"4597":{"position":[[753,9]]},"4604":{"position":[[135,9],[346,9],[543,9],[653,9],[858,9]]},"4606":{"position":[[132,9],[159,9],[203,9],[245,9],[287,9],[330,9],[534,9],[603,9],[640,9]]},"4608":{"position":[[200,9],[338,10]]},"4614":{"position":[[284,9],[415,9],[726,11],[924,9],[1034,9]]},"4616":{"position":[[189,9]]},"4618":{"position":[[4,9]]},"4620":{"position":[[4,9]]},"4623":{"position":[[111,9],[305,9],[393,9],[514,9]]},"4627":{"position":[[86,9],[254,9]]},"4629":{"position":[[81,9]]},"4632":{"position":[[222,11],[2876,9],[2988,9],[3058,9]]},"4634":{"position":[[0,9],[112,9],[182,9]]},"4637":{"position":[[120,9]]},"4639":{"position":[[93,9]]},"4643":{"position":[[160,9],[578,9],[744,9],[1342,9],[1374,9],[1486,9],[1535,9],[1672,9],[1755,9],[2009,9],[2046,9],[2194,9],[2242,9],[3349,9]]},"4665":{"position":[[33,9],[297,9],[454,9],[530,10]]},"4667":{"position":[[378,9],[410,9],[609,9],[764,9],[7100,9],[12664,9]]},"4669":{"position":[[793,9],[1100,10],[1168,10],[1201,9]]},"4671":{"position":[[0,9]]},"4724":{"position":[[230,9]]},"4730":{"position":[[404,9]]},"4736":{"position":[[64,10]]},"4744":{"position":[[78,9]]},"4755":{"position":[[64,10]]},"4773":{"position":[[121,9]]},"4793":{"position":[[313,10]]},"4797":{"position":[[37,9]]},"4801":{"position":[[170,10]]}}}],["openstack'",{"_index":2769,"t":{"557":{"position":[[2743,11],[2813,11],[3574,11],[3644,11]]},"832":{"position":[[11,11]]},"1263":{"position":[[332,11]]},"4045":{"position":[[591,11]]},"4228":{"position":[[111,11]]},"4302":{"position":[[4299,11]]},"4308":{"position":[[454,11]]}}}],["openstack.cloud.host_aggreg",{"_index":7225,"t":{"1740":{"position":[[198,30],[477,31]]}}}],["openstack.cloud.keypair",{"_index":7638,"t":{"2123":{"position":[[440,24]]}}}],["openstack.cloud.network",{"_index":7403,"t":{"2048":{"position":[[2955,24]]}}}],["openstack.cloud.security_group",{"_index":7587,"t":{"2117":{"position":[[818,31]]}}}],["openstack.cloud.security_group_rul",{"_index":7588,"t":{"2117":{"position":[[1001,36],[1181,36]]}}}],["openstack.cloud.serv",{"_index":7593,"t":{"2117":{"position":[[1425,23]]}}}],["openstack.cloud.subnet",{"_index":7407,"t":{"2048":{"position":[[3144,23]]}}}],["openstack.html",{"_index":7016,"t":{"1704":{"position":[[45,14]]}}}],["openstack.html#shorten",{"_index":6994,"t":{"1700":{"position":[[1009,25]]}}}],["openstack.img",{"_index":3449,"t":{"873":{"position":[[892,13],[995,13],[1098,13]]},"1774":{"position":[[892,13],[995,13],[1098,13]]}}}],["openstack.pi",{"_index":10778,"t":{"3751":{"position":[[24,12]]},"3795":{"position":[[425,12]]},"3883":{"position":[[18,12]]},"3906":{"position":[[19,12]]}}}],["openstack.upbound.io/v1beta1",{"_index":8674,"t":{"2602":{"position":[[423,28]]}}}],["openstack.yml",{"_index":7442,"t":{"2057":{"position":[[698,13],[852,13]]}}}],["openstack/arch",{"_index":4454,"t":{"1096":{"position":[[134,14]]}}}],["openstack/keycloak",{"_index":8658,"t":{"2584":{"position":[[1467,22],[1522,22]]},"2586":{"position":[[1077,22],[1132,22]]}}}],["openstack/kolla",{"_index":7483,"t":{"2071":{"position":[[1616,15]]}}}],["openstack/releases/latest/download/cspo",{"_index":2856,"t":{"580":{"position":[[732,39]]}}}],["openstack/sc",{"_index":3280,"t":{"812":{"position":[[3,13]]},"816":{"position":[[110,13]]},"820":{"position":[[3,14]]},"828":{"position":[[89,14]]},"830":{"position":[[34,13]]}}}],["openstack1",{"_index":11398,"t":{"4257":{"position":[[2062,11]]}}}],["openstack_benchmark_build_infra.featur",{"_index":8966,"t":{"2714":{"position":[[76,40],[732,39],[812,39],[1127,39],[1204,39],[1475,40]]},"2716":{"position":[[1527,39],[1948,39]]},"2718":{"position":[[520,40],[811,39]]}}}],["openstack_cacert",{"_index":5180,"t":{"1248":{"position":[[1353,17]]}}}],["openstack_create_network.featur",{"_index":8956,"t":{"2712":{"position":[[315,33],[477,32],[550,32],[1439,32]]}}}],["openstack_extra001_key",{"_index":4630,"t":{"1173":{"position":[[102,23],[275,22]]}}}],["openstack_extra001_pool",{"_index":4615,"t":{"1171":{"position":[[104,24],[484,23]]}}}],["openstack_extra001_pool.nam",{"_index":4633,"t":{"1173":{"position":[[201,28]]}}}],["openstack_keys_extra",{"_index":4629,"t":{"1173":{"position":[[34,20],[247,21]]}}}],["openstack_pool_default_min_s",{"_index":4626,"t":{"1171":{"position":[[394,31],[782,31]]}}}],["openstack_pool_default_pg_num",{"_index":4618,"t":{"1171":{"position":[[156,29],[203,29],[816,29]]}}}],["openstack_pool_default_s",{"_index":4624,"t":{"1171":{"position":[[348,27],[849,27]]}}}],["openstack_pools_extra",{"_index":4614,"t":{"1171":{"position":[[35,21],[455,22]]}}}],["openstack_security_group",{"_index":2742,"t":{"557":{"position":[[1614,25]]}}}],["openstack_service_rpc_work",{"_index":5593,"t":{"1305":{"position":[[181,30]]}}}],["openstack_service_work",{"_index":5591,"t":{"1305":{"position":[[105,26],[277,25],[505,25]]}}}],["openstack_testflow.featur",{"_index":8958,"t":{"2712":{"position":[[762,26],[882,26],[930,26]]}}}],["openstack_vers",{"_index":5038,"t":{"1222":{"position":[[781,17],[1424,17]]},"1228":{"position":[[274,17]]},"1230":{"position":[[1240,17]]},"1257":{"position":[[428,17]]},"2171":{"position":[[575,17]]},"2219":{"position":[[665,17]]}}}],["openstack_workload_manager_installation_dir?th",{"_index":8908,"t":{"2692":{"position":[[1143,49]]}}}],["openstack_workload_manager_installation_dir}/profiles/health",{"_index":8915,"t":{"2692":{"position":[[1380,62]]}}}],["openstackcli",{"_index":321,"t":{"37":{"position":[[4,15],[127,15],[216,16],[1040,15],[1289,16]]},"924":{"position":[[1129,15]]},"934":{"position":[[100,15]]},"1523":{"position":[[509,15]]},"1815":{"position":[[1129,15]]},"1825":{"position":[[100,15]]},"2117":{"position":[[147,15],[2214,15]]},"2231":{"position":[[233,15]]},"2238":{"position":[[222,15]]},"2272":{"position":[[0,15]]},"2445":{"position":[[138,15]]},"2948":{"position":[[1129,15]]},"2958":{"position":[[100,15]]},"3683":{"position":[[215,16]]},"3742":{"position":[[477,16]]},"3795":{"position":[[215,16]]}}}],["openstackclusterstackreleas",{"_index":2523,"t":{"496":{"position":[[4,28],[451,28]]}}}],["openstackclusterstackreleasetempl",{"_index":2886,"t":{"586":{"position":[[1070,36],[1220,36]]}}}],["openstackclusterstackreleasetemplate.infrastructure.clusterstack.x",{"_index":2893,"t":{"586":{"position":[[1479,66]]}}}],["openstacknodeimagereleas",{"_index":2526,"t":{"496":{"position":[[128,25],[292,25],[513,26]]},"498":{"position":[[4,25],[348,25]]}}}],["openstackproviderclientnotset",{"_index":2567,"t":{"518":{"position":[[594,32]]}}}],["openstack’",{"_index":4437,"t":{"1067":{"position":[[1310,11]]}}}],["opensus",{"_index":3729,"t":{"924":{"position":[[56,8],[238,8]]},"1815":{"position":[[56,8],[238,8]]},"2948":{"position":[[56,8],[238,8]]},"3824":{"position":[[68,9]]}}}],["opentelekomcloud",{"_index":7843,"t":{"2178":{"position":[[506,16]]}}}],["opentofu",{"_index":7871,"t":{"2184":{"position":[[2785,8],[3141,9]]},"2219":{"position":[[105,8]]},"2227":{"position":[[91,9],[205,9]]},"3223":{"position":[[749,8]]}}}],["opentracing.trac",{"_index":8815,"t":{"2661":{"position":[[156,18]]}}}],["openva",{"_index":8551,"t":{"2489":{"position":[[1642,9]]},"2555":{"position":[[38,8]]}}}],["openvirtualnetwork\"(ovn",{"_index":3351,"t":{"846":{"position":[[895,25]]}}}],["openvswitch",{"_index":6340,"t":{"1519":{"position":[[39,11],[63,11]]},"1711":{"position":[[376,11]]},"2048":{"position":[[2582,11]]},"2173":{"position":[[39,11],[74,11]]},"2225":{"position":[[256,11]]},"3016":{"position":[[514,12]]},"3130":{"position":[[199,11]]},"4215":{"position":[[398,11]]}}}],["openvswitch_db",{"_index":7138,"t":{"1711":{"position":[[2629,14]]}}}],["openvswitch_vswitchd",{"_index":6998,"t":{"1702":{"position":[[196,20]]},"1711":{"position":[[2488,20]]}}}],["openxchang",{"_index":11896,"t":{"4835":{"position":[[1838,11],[1885,11]]},"4849":{"position":[[1527,13],[1559,13]]}}}],["openxchange.yaml.gotmpl",{"_index":11898,"t":{"4835":{"position":[[1948,23]]}}}],["oper",{"_index":30,"t":{"7":{"position":[[115,9]]},"66":{"position":[[101,10]]},"74":{"position":[[220,9]]},"76":{"position":[[147,10]]},"86":{"position":[[87,7]]},"90":{"position":[[88,11]]},"97":{"position":[[23,11],[104,10]]},"169":{"position":[[58,9]]},"187":{"position":[[380,8],[692,7],[821,11],[1131,10]]},"194":{"position":[[33,10],[517,10]]},"197":{"position":[[132,10],[251,9],[589,11]]},"280":{"position":[[917,9]]},"293":{"position":[[255,9]]},"309":{"position":[[377,9]]},"311":{"position":[[50,9],[228,8]]},"332":{"position":[[114,8]]},"370":{"position":[[294,9],[781,11]]},"372":{"position":[[108,10]]},"374":{"position":[[137,9]]},"376":{"position":[[347,7]]},"378":{"position":[[165,11],[200,11],[268,11]]},"382":{"position":[[53,9],[128,10]]},"391":{"position":[[308,8]]},"393":{"position":[[223,8]]},"397":{"position":[[579,8]]},"403":{"position":[[18,8],[282,10],[311,8],[607,9]]},"405":{"position":[[18,8],[116,8],[168,8],[441,8]]},"407":{"position":[[326,8]]},"421":{"position":[[754,8],[844,8],[886,9]]},"427":{"position":[[313,10],[383,8],[577,9]]},"430":{"position":[[15,8]]},"434":{"position":[[0,8],[1796,8]]},"438":{"position":[[61,9],[533,8]]},"440":{"position":[[365,8]]},"446":{"position":[[407,8]]},"450":{"position":[[284,9]]},"452":{"position":[[13,8]]},"473":{"position":[[18,8],[213,8],[646,8],[1064,8],[1410,8]]},"477":{"position":[[618,8],[770,8]]},"479":{"position":[[1677,8]]},"491":{"position":[[825,8]]},"500":{"position":[[73,8]]},"504":{"position":[[44,8]]},"508":{"position":[[0,8]]},"512":{"position":[[624,8]]},"537":{"position":[[137,9]]},"541":{"position":[[210,9]]},"543":{"position":[[43,9],[139,9]]},"572":{"position":[[66,8]]},"590":{"position":[[201,8],[266,8]]},"593":{"position":[[18,8],[404,8]]},"595":{"position":[[228,9]]},"614":{"position":[[28,9]]},"641":{"position":[[94,9],[108,8],[504,8],[627,9]]},"645":{"position":[[248,8]]},"657":{"position":[[155,8],[429,8]]},"664":{"position":[[18,8],[404,8],[571,9]]},"666":{"position":[[94,9],[108,8],[504,8],[627,9]]},"668":{"position":[[129,8]]},"677":{"position":[[248,8]]},"688":{"position":[[19,10],[240,8],[305,8],[387,9]]},"728":{"position":[[114,8]]},"732":{"position":[[335,8]]},"755":{"position":[[98,8]]},"838":{"position":[[377,9]]},"854":{"position":[[24,8],[41,8],[74,8],[121,10],[157,8],[283,8],[396,9],[566,9]]},"859":{"position":[[42,8],[185,8]]},"890":{"position":[[92,8]]},"938":{"position":[[500,9]]},"946":{"position":[[934,11]]},"949":{"position":[[83,8],[582,9]]},"978":{"position":[[2078,9]]},"1009":{"position":[[401,10],[591,10]]},"1056":{"position":[[1371,11],[1766,11],[1794,11],[2014,11],[2342,11]]},"1061":{"position":[[1055,11]]},"1064":{"position":[[489,8],[674,10],[1607,11]]},"1067":{"position":[[523,9]]},"1073":{"position":[[204,9],[595,10]]},"1105":{"position":[[525,9]]},"1107":{"position":[[261,9]]},"1109":{"position":[[272,9]]},"1111":{"position":[[272,9]]},"1113":{"position":[[266,11],[326,9]]},"1179":{"position":[[2381,10]]},"1193":{"position":[[111,8]]},"1301":{"position":[[1250,8],[1428,8],[1529,8],[3196,8],[3442,8]]},"1354":{"position":[[52,8]]},"1391":{"position":[[2363,9]]},"1431":{"position":[[138,8],[349,8]]},"1433":{"position":[[1083,9]]},"1457":{"position":[[655,8],[682,8],[952,8],[1193,8],[1637,8],[2022,8],[2204,8]]},"1466":{"position":[[1055,8],[1914,9],[2687,9],[2740,9]]},"1472":{"position":[[4,8],[244,8],[745,8],[1055,8],[1082,8],[2208,8],[3187,8]]},"1484":{"position":[[502,8]]},"1486":{"position":[[398,8]]},"1497":{"position":[[780,9]]},"1525":{"position":[[1004,8],[1041,8]]},"1623":{"position":[[25,10]]},"1637":{"position":[[104,9]]},"1646":{"position":[[334,10]]},"1648":{"position":[[993,10],[1185,10]]},"1659":{"position":[[14,8],[104,10],[238,10]]},"1667":{"position":[[101,8]]},"1711":{"position":[[34,8]]},"1743":{"position":[[296,8]]},"1745":{"position":[[380,8]]},"1748":{"position":[[92,8]]},"1760":{"position":[[42,8],[185,8]]},"1829":{"position":[[500,9]]},"1837":{"position":[[934,11]]},"1840":{"position":[[83,8],[582,9]]},"1869":{"position":[[2078,9]]},"1912":{"position":[[230,9]]},"1954":{"position":[[25,10]]},"1968":{"position":[[177,9]]},"1981":{"position":[[296,11]]},"2032":{"position":[[183,9],[812,9]]},"2052":{"position":[[121,9]]},"2057":{"position":[[337,10]]},"2071":{"position":[[1327,10],[1371,10],[1504,10],[1548,10]]},"2161":{"position":[[9,11]]},"2196":{"position":[[1774,10],[1973,9],[3710,10]]},"2287":{"position":[[252,7],[272,9],[593,9]]},"2301":{"position":[[252,7],[272,9],[593,9]]},"2360":{"position":[[1652,9]]},"2366":{"position":[[52,9],[230,8]]},"2427":{"position":[[1652,9]]},"2429":{"position":[[363,9]]},"2431":{"position":[[1407,8],[2426,8],[2618,8]]},"2433":{"position":[[384,9]]},"2449":{"position":[[57,9]]},"2451":{"position":[[739,9]]},"2485":{"position":[[199,11]]},"2497":{"position":[[41,9],[550,10],[589,10]]},"2501":{"position":[[266,9]]},"2506":{"position":[[0,9]]},"2508":{"position":[[0,9]]},"2514":{"position":[[16,10]]},"2522":{"position":[[62,10]]},"2525":{"position":[[40,11],[524,11]]},"2533":{"position":[[107,8]]},"2535":{"position":[[488,9]]},"2539":{"position":[[10,8],[143,8],[388,8]]},"2565":{"position":[[117,8]]},"2567":{"position":[[1371,8],[1467,8]]},"2569":{"position":[[369,9],[408,8],[453,8],[468,9],[618,8],[675,9],[771,8]]},"2594":{"position":[[20,8],[108,9],[178,9]]},"2649":{"position":[[126,8]]},"2655":{"position":[[48,7]]},"2806":{"position":[[59,10]]},"2808":{"position":[[78,10]]},"2812":{"position":[[111,10]]},"2814":{"position":[[733,10]]},"2836":{"position":[[13,10],[420,11]]},"2887":{"position":[[83,9],[246,10]]},"2930":{"position":[[1556,14]]},"2962":{"position":[[500,9]]},"2970":{"position":[[934,11]]},"2973":{"position":[[83,8],[582,9]]},"3002":{"position":[[2078,9]]},"3016":{"position":[[297,11]]},"3044":{"position":[[97,11]]},"3047":{"position":[[553,8]]},"3050":{"position":[[254,12]]},"3086":{"position":[[518,10]]},"3134":{"position":[[142,9]]},"3148":{"position":[[210,9]]},"3153":{"position":[[946,9]]},"3155":{"position":[[54,9]]},"3162":{"position":[[608,9]]},"3187":{"position":[[125,8],[222,8]]},"3189":{"position":[[309,10],[725,9]]},"3206":{"position":[[694,10]]},"3214":{"position":[[40,10]]},"3218":{"position":[[167,8]]},"3223":{"position":[[607,8],[951,8]]},"3230":{"position":[[198,9]]},"3238":{"position":[[344,9]]},"3257":{"position":[[188,10]]},"3259":{"position":[[93,9]]},"3288":{"position":[[318,8]]},"3290":{"position":[[499,8]]},"3296":{"position":[[44,9],[157,8]]},"3302":{"position":[[85,9]]},"3308":{"position":[[330,9]]},"3310":{"position":[[262,9],[714,9],[798,11]]},"3313":{"position":[[635,10]]},"3321":{"position":[[627,9]]},"3323":{"position":[[281,9],[614,9]]},"3344":{"position":[[54,7],[971,8]]},"3346":{"position":[[199,11],[211,9],[970,9]]},"3348":{"position":[[357,9]]},"3352":{"position":[[1248,9],[1410,9],[2676,9],[3757,9]]},"3355":{"position":[[132,9],[526,9]]},"3367":{"position":[[258,8]]},"3398":{"position":[[284,10]]},"3406":{"position":[[102,10]]},"3410":{"position":[[100,9]]},"3468":{"position":[[138,9]]},"3502":{"position":[[0,11],[242,11]]},"3516":{"position":[[175,9]]},"3531":{"position":[[398,10]]},"3569":{"position":[[1034,9]]},"3582":{"position":[[697,10]]},"3627":{"position":[[783,11]]},"3653":{"position":[[120,9]]},"3690":{"position":[[120,9]]},"3693":{"position":[[24,9]]},"3727":{"position":[[260,9]]},"3729":{"position":[[3,9]]},"3731":{"position":[[229,8],[970,8],[2136,8],[2900,8]]},"3759":{"position":[[101,10],[184,10]]},"3777":{"position":[[120,9]]},"3780":{"position":[[24,9]]},"3820":{"position":[[27,9]]},"3829":{"position":[[162,9],[3954,8]]},"3833":{"position":[[557,9],[715,9],[772,9]]},"3881":{"position":[[106,8],[503,8]]},"3892":{"position":[[120,9]]},"3913":{"position":[[268,9]]},"3918":{"position":[[478,12]]},"3925":{"position":[[1685,9]]},"3928":{"position":[[1196,9]]},"3945":{"position":[[100,10]]},"3980":{"position":[[455,9]]},"3984":{"position":[[472,9]]},"4039":{"position":[[205,8]]},"4060":{"position":[[1006,9]]},"4107":{"position":[[1083,7],[1466,7]]},"4109":{"position":[[4266,9],[4313,9]]},"4124":{"position":[[1013,10]]},"4130":{"position":[[234,10],[447,10]]},"4133":{"position":[[1471,9],[1518,9]]},"4187":{"position":[[240,9]]},"4217":{"position":[[78,8]]},"4220":{"position":[[400,10]]},"4222":{"position":[[287,8],[1353,11]]},"4228":{"position":[[78,9]]},"4230":{"position":[[3395,8],[4443,8],[4644,8]]},"4240":{"position":[[33,9]]},"4302":{"position":[[4627,10]]},"4420":{"position":[[176,7],[1414,9]]},"4444":{"position":[[21,10],[59,11],[258,10]]},"4455":{"position":[[21,10],[59,11],[258,10]]},"4481":{"position":[[469,9],[701,8]]},"4493":{"position":[[602,9]]},"4508":{"position":[[323,9]]},"4516":{"position":[[190,9],[616,9],[1812,9]]},"4518":{"position":[[101,9]]},"4522":{"position":[[649,9],[1287,9]]},"4539":{"position":[[939,10],[4969,11],[5056,7],[6525,11]]},"4541":{"position":[[328,10]]},"4545":{"position":[[552,10]]},"4562":{"position":[[4399,7],[5030,8],[6982,8],[7009,8],[7431,8]]},"4576":{"position":[[211,10]]},"4580":{"position":[[1114,8],[1168,8]]},"4582":{"position":[[621,9]]},"4593":{"position":[[4495,9]]},"4595":{"position":[[313,9]]},"4654":{"position":[[89,10]]},"4660":{"position":[[1898,9],[2203,9],[2252,8],[2617,8],[3001,8]]},"4695":{"position":[[572,10]]},"4701":{"position":[[130,10]]},"4707":{"position":[[592,14],[810,11]]},"4722":{"position":[[894,10],[974,10]]},"4728":{"position":[[178,9]]},"4733":{"position":[[450,11]]},"4740":{"position":[[99,9]]},"4759":{"position":[[87,9]]},"4793":{"position":[[41,10],[381,9]]},"4883":{"position":[[30,8]]}}}],["operat",{"_index":7098,"t":{"1711":{"position":[[8,8]]}}}],["operato",{"_index":8429,"t":{"2431":{"position":[[883,7]]}}}],["operator'",{"_index":4484,"t":{"1113":{"position":[[222,10]]},"4220":{"position":[[1204,10]]}}}],["operator/.releas",{"_index":2508,"t":{"489":{"position":[[1440,17]]}}}],["operator/releases/latest/download/cso",{"_index":2444,"t":{"475":{"position":[[145,37]]},"580":{"position":[[403,37]]}}}],["operator/trivi",{"_index":8626,"t":{"2569":{"position":[[744,14]]}}}],["operator/trivy_results.json",{"_index":8619,"t":{"2567":{"position":[[971,28]]}}}],["operator/values.yaml",{"_index":8621,"t":{"2567":{"position":[[1282,21]]},"2569":{"position":[[487,20]]}}}],["operator_public_key",{"_index":6226,"t":{"1457":{"position":[[1334,19]]}}}],["operator_us",{"_index":4973,"t":{"1199":{"position":[[668,13]]}}}],["operators/develop",{"_index":9287,"t":{"2918":{"position":[[187,20]]}}}],["operators/postgr",{"_index":3033,"t":{"688":{"position":[[457,19]]}}}],["operators/redi",{"_index":3032,"t":{"688":{"position":[[423,16]]}}}],["opinion",{"_index":2100,"t":{"339":{"position":[[96,11]]},"401":{"position":[[23,11]]},"421":{"position":[[413,8],[481,11]]},"446":{"position":[[164,7]]},"1443":{"position":[[26,11]]},"2574":{"position":[[737,11]]},"2578":{"position":[[170,11],[201,8]]},"2914":{"position":[[107,8],[328,11]]},"2918":{"position":[[87,11],[326,9],[419,7],[631,11]]},"3180":{"position":[[237,11]]},"3218":{"position":[[293,11]]},"3255":{"position":[[195,11]]},"4759":{"position":[[417,11]]}}}],["opm",{"_index":3669,"t":{"912":{"position":[[7594,3],[7719,3]]},"1796":{"position":[[7594,3],[7719,3]]}}}],["opportun",{"_index":1143,"t":{"173":{"position":[[1388,11]]},"192":{"position":[[234,11]]},"2626":{"position":[[2255,11]]},"3323":{"position":[[579,11]]}}}],["oppos",{"_index":9286,"t":{"2918":{"position":[[28,7]]},"4189":{"position":[[650,7]]},"4466":{"position":[[130,7]]}}}],["opposit",{"_index":1317,"t":{"183":{"position":[[151,8]]},"4163":{"position":[[5401,9]]}}}],["opsi",{"_index":10850,"t":{"3829":{"position":[[4687,5]]}}}],["opt",{"_index":8466,"t":{"2439":{"position":[[723,3]]},"2612":{"position":[[93,3]]},"2655":{"position":[[493,3]]},"3016":{"position":[[348,4]]},"3086":{"position":[[1306,4]]},"3185":{"position":[[568,4]]},"3592":{"position":[[2316,3]]},"3611":{"position":[[87,3]]},"3695":{"position":[[54,4],[228,4]]},"3782":{"position":[[54,4],[228,4]]},"4191":{"position":[[134,3]]},"4224":{"position":[[2496,3]]},"4230":{"position":[[4354,3]]},"4448":{"position":[[347,3]]},"4667":{"position":[[14251,3]]}}}],["opt/ansible/secrets/id_rsa.oper",{"_index":4963,"t":{"1197":{"position":[[249,36],[402,36],[555,36],[708,36]]},"1199":{"position":[[488,36]]}}}],["opt/cloud",{"_index":7316,"t":{"2034":{"position":[[974,10],[1049,10],[1140,10],[1309,10],[1455,10]]}}}],["opt/configur",{"_index":5221,"t":{"1259":{"position":[[1131,18]]},"1503":{"position":[[1549,19]]},"1525":{"position":[[1247,19]]},"2201":{"position":[[6,18]]}}}],["opt/configuration/environments/manag",{"_index":7822,"t":{"2163":{"position":[[4560,39]]}}}],["opt/configuration/environments/manager/group_vars/manager.yml",{"_index":7394,"t":{"2048":{"position":[[1913,62],[2375,62]]}}}],["opt/configuration/environments/openstack/playbook",{"_index":7401,"t":{"2048":{"position":[[2750,50]]}}}],["opt/configuration/environments/rook/fil",{"_index":6178,"t":{"1443":{"position":[[937,42],[983,42]]}}}],["opt/configuration/inventory/group_vars/generic/network.yml",{"_index":7393,"t":{"2048":{"position":[[1853,59],[2315,59]]}}}],["opt/configuration/inventory/host_vars/testb",{"_index":7992,"t":{"2207":{"position":[[272,46],[1059,46]]}}}],["opt/configuration/scripts/bootstrap.sh",{"_index":7892,"t":{"2184":{"position":[[5152,40]]}}}],["opt/configuration/scripts/bootstrap/301",{"_index":7894,"t":{"2184":{"position":[[6247,40]]}}}],["opt/configuration/scripts/bootstrap/302",{"_index":7897,"t":{"2184":{"position":[[6323,40]]}}}],["opt/configuration/scripts/check.sh",{"_index":7893,"t":{"2184":{"position":[[5911,36]]}}}],["opt/configuration/scripts/deploy",{"_index":8010,"t":{"2209":{"position":[[361,33],[407,33]]}}}],["opt/configuration/scripts/deploy/000",{"_index":7978,"t":{"2203":{"position":[[19,37]]}}}],["opt/configuration/scripts/deploy/001",{"_index":7883,"t":{"2184":{"position":[[4711,37]]},"2203":{"position":[[76,37]]}}}],["opt/configuration/scripts/deploy/005",{"_index":7885,"t":{"2184":{"position":[[4768,37]]}}}],["opt/configuration/scripts/deploy/100",{"_index":7887,"t":{"2184":{"position":[[4820,37]]},"2203":{"position":[[133,37],[216,37]]}}}],["opt/configuration/scripts/deploy/200",{"_index":7888,"t":{"2184":{"position":[[4875,37]]},"2203":{"position":[[271,37]]}}}],["opt/configuration/scripts/deploy/300",{"_index":7890,"t":{"2184":{"position":[[4946,37]]},"2203":{"position":[[336,37]]}}}],["opt/configuration/scripts/deploy/310",{"_index":7980,"t":{"2203":{"position":[[396,37]]}}}],["opt/configuration/scripts/deploy/400",{"_index":7891,"t":{"2184":{"position":[[5012,37],[5300,37]]},"2203":{"position":[[465,37]]}}}],["opt/configuration/scripts/deploy/500",{"_index":7982,"t":{"2203":{"position":[[526,37]]}}}],["opt/configuration/scripts/deploy/510",{"_index":7983,"t":{"2203":{"position":[[578,37]]}}}],["opt/configuration/scripts/dis",{"_index":7877,"t":{"2184":{"position":[[4300,34]]}}}],["opt/configuration/scripts/en",{"_index":7879,"t":{"2184":{"position":[[4475,33]]}}}],["opt/configuration/scripts/pul",{"_index":7880,"t":{"2184":{"position":[[4575,31]]}}}],["opt/configuration/scripts/upgrade/100",{"_index":7985,"t":{"2205":{"position":[[19,38],[75,38]]},"2209":{"position":[[458,38]]}}}],["opt/configuration/scripts/upgrade/200",{"_index":7986,"t":{"2205":{"position":[[159,38]]}}}],["opt/configuration/scripts/upgrade/300",{"_index":7987,"t":{"2205":{"position":[[225,38]]}}}],["opt/configuration/scripts/upgrade/310",{"_index":7988,"t":{"2205":{"position":[[286,38]]}}}],["opt/configuration/scripts/upgrade/400",{"_index":7989,"t":{"2205":{"position":[[356,38]]}}}],["opt/configuration/scripts/upgrade/500",{"_index":7990,"t":{"2205":{"position":[[418,38]]}}}],["opt/configuration/scripts/upgrade/510",{"_index":7991,"t":{"2205":{"position":[[471,38]]}}}],["opt/configuration/secrets/become_password",{"_index":6231,"t":{"1457":{"position":[[1861,43],[1938,42],[2061,42],[2243,42]]}}}],["opt/configuration/secrets/conn_password",{"_index":6228,"t":{"1457":{"position":[[1482,41],[1555,40],[1674,40],[2305,40]]}}}],["opt/configuration/upgrade.sh",{"_index":7364,"t":{"2045":{"position":[[212,29]]}}}],["opt/manag",{"_index":6763,"t":{"1688":{"position":[[298,12]]},"2155":{"position":[[607,12],[978,12]]},"2199":{"position":[[1188,12]]},"2209":{"position":[[285,12]]}}}],["opt/reports/valid",{"_index":6591,"t":{"1644":{"position":[[425,23]]}}}],["opt/stack",{"_index":8012,"t":{"2211":{"position":[[313,10]]}}}],["opt/td",{"_index":6724,"t":{"1673":{"position":[[224,7],[315,7]]}}}],["optic",{"_index":7288,"t":{"2021":{"position":[[79,7],[200,7]]}}}],["optim",{"_index":547,"t":{"74":{"position":[[99,7]]},"295":{"position":[[828,7],[912,7]]},"339":{"position":[[108,9]]},"852":{"position":[[280,13]]},"1064":{"position":[[1668,10]]},"1067":{"position":[[1401,7]]},"1455":{"position":[[413,8],[477,8],[596,8],[671,8],[884,8],[997,8],[1061,8],[1139,8],[1227,8],[1270,8],[1415,8],[1514,8],[1538,8],[1578,8],[1615,8],[1656,8],[1700,8],[1741,8],[1777,8],[1821,8],[1873,9],[1945,8],[2148,8],[2205,8]]},"2376":{"position":[[211,9]]},"2608":{"position":[[43,9]]},"3189":{"position":[[380,8],[615,8]]},"3502":{"position":[[271,8]]},"4124":{"position":[[1395,9]]},"4224":{"position":[[2898,8]]},"4506":{"position":[[975,9]]},"4662":{"position":[[1299,9]]}}}],["option",{"_index":692,"t":{"111":{"position":[[28,7]]},"115":{"position":[[10,8]]},"141":{"position":[[130,6]]},"169":{"position":[[480,8]]},"203":{"position":[[109,10]]},"224":{"position":[[327,6]]},"249":{"position":[[1894,6]]},"282":{"position":[[184,9]]},"315":{"position":[[91,10]]},"366":{"position":[[769,7]]},"378":{"position":[[571,8]]},"384":{"position":[[143,7]]},"471":{"position":[[41,10]]},"477":{"position":[[499,8]]},"479":{"position":[[1393,6]]},"553":{"position":[[41,7],[107,9]]},"557":{"position":[[2654,8],[3485,8]]},"614":{"position":[[127,9]]},"659":{"position":[[588,11]]},"705":{"position":[[462,8]]},"712":{"position":[[224,8]]},"739":{"position":[[845,11]]},"741":{"position":[[317,7],[1421,6]]},"755":{"position":[[856,6]]},"816":{"position":[[540,11],[787,7]]},"822":{"position":[[271,11]]},"836":{"position":[[452,7]]},"848":{"position":[[398,6]]},"861":{"position":[[571,6]]},"863":{"position":[[115,8]]},"887":{"position":[[49,9],[62,7]]},"894":{"position":[[282,8],[516,9],[529,7]]},"896":{"position":[[329,8]]},"906":{"position":[[38,7]]},"910":{"position":[[223,8]]},"912":{"position":[[1354,8],[1668,7],[1795,7],[1842,6],[2042,6]]},"914":{"position":[[747,8],[1120,7],[1247,7],[1294,6],[1494,6]]},"916":{"position":[[126,7]]},"924":{"position":[[1591,12]]},"932":{"position":[[2518,10]]},"942":{"position":[[2936,7]]},"949":{"position":[[382,8],[788,6]]},"978":{"position":[[1570,6]]},"1003":{"position":[[36,7]]},"1005":{"position":[[221,8],[881,8],[1184,7],[1313,7],[1360,6],[1560,6],[6641,7],[6768,7],[6815,6]]},"1007":{"position":[[110,7]]},"1030":{"position":[[681,7]]},"1042":{"position":[[867,10],[970,10],[1045,10]]},"1175":{"position":[[199,8],[898,8],[999,8],[1145,8],[1243,8]]},"1183":{"position":[[798,6]]},"1232":{"position":[[305,8]]},"1252":{"position":[[756,9]]},"1257":{"position":[[984,11]]},"1259":{"position":[[371,6]]},"1297":{"position":[[1734,6],[1749,6]]},"1301":{"position":[[1093,6],[1128,6]]},"1324":{"position":[[13002,7]]},"1359":{"position":[[5,8]]},"1361":{"position":[[5,8]]},"1369":{"position":[[104,7]]},"1373":{"position":[[129,6]]},"1391":{"position":[[106,8]]},"1399":{"position":[[38,7]]},"1413":{"position":[[206,7]]},"1421":{"position":[[1071,6]]},"1425":{"position":[[345,7]]},"1437":{"position":[[90,6]]},"1457":{"position":[[2568,11],[2717,11],[2960,11],[3764,10]]},"1466":{"position":[[2271,9]]},"1478":{"position":[[98,8],[216,8]]},"1491":{"position":[[200,7],[431,7]]},"1493":{"position":[[428,7]]},"1505":{"position":[[38,9]]},"1511":{"position":[[413,9]]},"1513":{"position":[[130,9]]},"1515":{"position":[[109,9]]},"1523":{"position":[[1044,9]]},"1525":{"position":[[2328,7],[2440,10]]},"1580":{"position":[[371,6]]},"1698":{"position":[[684,9]]},"1702":{"position":[[377,8],[535,8]]},"1704":{"position":[[1153,8],[1279,8],[1405,8]]},"1711":{"position":[[168,10],[583,10],[648,10],[1071,8]]},"1752":{"position":[[282,8],[516,9],[529,7]]},"1754":{"position":[[329,8]]},"1762":{"position":[[571,6]]},"1764":{"position":[[115,8]]},"1790":{"position":[[38,7]]},"1794":{"position":[[223,8]]},"1796":{"position":[[1354,8],[1668,7],[1795,7],[1842,6],[2042,6]]},"1798":{"position":[[747,8],[1120,7],[1247,7],[1294,6],[1494,6]]},"1800":{"position":[[126,7]]},"1811":{"position":[[49,9],[62,7]]},"1815":{"position":[[1591,12]]},"1823":{"position":[[2518,10]]},"1833":{"position":[[2936,7]]},"1840":{"position":[[382,8],[788,6]]},"1869":{"position":[[1570,6]]},"1894":{"position":[[36,7]]},"1896":{"position":[[221,8],[881,8],[1184,7],[1313,7],[1360,6],[1560,6],[6641,7],[6768,7],[6815,6]]},"1898":{"position":[[110,7]]},"1906":{"position":[[241,7]]},"1923":{"position":[[371,6]]},"1981":{"position":[[64,6]]},"1990":{"position":[[43,7]]},"1996":{"position":[[227,8]]},"2013":{"position":[[184,7],[199,7]]},"2027":{"position":[[728,8]]},"2034":{"position":[[534,6]]},"2104":{"position":[[31,6]]},"2106":{"position":[[73,7]]},"2157":{"position":[[96,9]]},"2171":{"position":[[1124,11]]},"2184":{"position":[[520,12],[4535,6],[5985,9],[6563,9]]},"2234":{"position":[[696,6]]},"2246":{"position":[[93,10]]},"2248":{"position":[[29,8]]},"2252":{"position":[[1519,10]]},"2276":{"position":[[1760,8]]},"2285":{"position":[[646,10]]},"2299":{"position":[[646,10]]},"2347":{"position":[[707,8]]},"2351":{"position":[[596,9]]},"2414":{"position":[[707,8]]},"2418":{"position":[[596,9]]},"2473":{"position":[[115,7]]},"2478":{"position":[[1348,11],[2289,6]]},"2482":{"position":[[341,7]]},"2626":{"position":[[735,8],[772,8]]},"2647":{"position":[[326,8],[2120,6]]},"2649":{"position":[[3431,6]]},"2651":{"position":[[123,7],[420,8]]},"2674":{"position":[[349,6]]},"2686":{"position":[[541,7]]},"2703":{"position":[[302,8],[562,8]]},"2712":{"position":[[1307,6]]},"2725":{"position":[[728,10]]},"2849":{"position":[[42,9]]},"2914":{"position":[[214,7]]},"2948":{"position":[[1591,12]]},"2956":{"position":[[2518,10]]},"2966":{"position":[[2936,7]]},"2973":{"position":[[382,8],[788,6]]},"3002":{"position":[[1570,6]]},"3016":{"position":[[691,8]]},"3067":{"position":[[545,8]]},"3069":{"position":[[77,11]]},"3081":{"position":[[189,8]]},"3168":{"position":[[230,9]]},"3183":{"position":[[345,6]]},"3257":{"position":[[176,7]]},"3266":{"position":[[139,8]]},"3279":{"position":[[189,6]]},"3281":{"position":[[383,8]]},"3296":{"position":[[727,7]]},"3323":{"position":[[440,6]]},"3357":{"position":[[2067,9]]},"3381":{"position":[[167,8]]},"3414":{"position":[[156,8]]},"3521":{"position":[[117,10]]},"3527":{"position":[[2607,8]]},"3529":{"position":[[622,8],[1853,8]]},"3571":{"position":[[1557,8]]},"3592":{"position":[[785,6],[867,8],[2029,8]]},"3602":{"position":[[103,8],[510,8],[618,8]]},"3608":{"position":[[96,12]]},"3658":{"position":[[27,9],[46,9],[66,9]]},"3669":{"position":[[148,8]]},"3673":{"position":[[20,8],[659,9],[958,8]]},"3681":{"position":[[1327,8]]},"3695":{"position":[[30,9],[178,8]]},"3706":{"position":[[1757,9]]},"3710":{"position":[[161,8]]},"3712":{"position":[[161,7]]},"3714":{"position":[[482,9],[989,8],[1904,8]]},"3718":{"position":[[1354,8]]},"3722":{"position":[[906,6],[1064,6]]},"3742":{"position":[[813,8]]},"3763":{"position":[[371,10]]},"3768":{"position":[[114,9]]},"3782":{"position":[[30,9],[178,8]]},"3803":{"position":[[148,8]]},"3807":{"position":[[282,9],[611,8]]},"3811":{"position":[[1331,8]]},"3815":{"position":[[904,6],[1062,6]]},"3829":{"position":[[2336,8],[4617,9]]},"3833":{"position":[[734,9]]},"3835":{"position":[[575,9],[787,9],[1055,9],[1389,11],[1416,9],[1632,9],[1746,9]]},"3866":{"position":[[199,8]]},"3872":{"position":[[85,10],[96,8]]},"3874":{"position":[[210,10],[221,8]]},"3881":{"position":[[142,8]]},"3894":{"position":[[504,7],[864,7]]},"3928":{"position":[[1640,6],[4685,6],[4740,6],[6135,7]]},"3943":{"position":[[585,7]]},"3947":{"position":[[41,6],[903,6],[1261,7],[1596,6],[1681,6],[1715,8],[1919,7],[2153,7],[2384,6],[2626,7],[2982,6],[3186,6],[3254,6],[3389,7],[3619,8],[3640,8],[4192,6],[4359,6],[4501,7]]},"3949":{"position":[[28,7]]},"3951":{"position":[[156,8],[217,8],[367,9],[504,8]]},"3953":{"position":[[49,7]]},"3968":{"position":[[0,6],[1034,6],[1541,6],[1639,6],[2284,6],[2332,6]]},"3973":{"position":[[28,6]]},"3986":{"position":[[109,8]]},"3992":{"position":[[493,6],[576,7]]},"3996":{"position":[[77,7],[121,7],[513,6]]},"4023":{"position":[[80,9]]},"4026":{"position":[[29,6]]},"4060":{"position":[[421,6]]},"4081":{"position":[[495,6]]},"4124":{"position":[[237,7],[322,8],[1141,6],[2112,8]]},"4126":{"position":[[44,6]]},"4130":{"position":[[683,8]]},"4146":{"position":[[1067,6]]},"4157":{"position":[[389,6]]},"4189":{"position":[[30,8],[175,7]]},"4198":{"position":[[640,8]]},"4215":{"position":[[23,7]]},"4220":{"position":[[511,6]]},"4226":{"position":[[625,7],[1594,8]]},"4255":{"position":[[133,7]]},"4257":{"position":[[176,6],[1468,6],[4476,6]]},"4281":{"position":[[899,6],[1245,6]]},"4283":{"position":[[199,6]]},"4285":{"position":[[78,6],[166,6]]},"4291":{"position":[[1579,7],[1728,7],[1773,7],[2456,7],[2535,7]]},"4304":{"position":[[1209,7]]},"4310":{"position":[[0,6],[76,6],[809,6],[983,6],[1025,6],[1412,9],[1427,6],[1516,8],[1598,6],[1650,6],[1687,7],[2239,6]]},"4325":{"position":[[424,8]]},"4327":{"position":[[419,7]]},"4329":{"position":[[6,8]]},"4331":{"position":[[6,8]]},"4420":{"position":[[287,8]]},"4433":{"position":[[216,8]]},"4435":{"position":[[846,9]]},"4448":{"position":[[851,8]]},"4459":{"position":[[601,8]]},"4499":{"position":[[19,8]]},"4520":{"position":[[254,8]]},"4535":{"position":[[3263,6],[3860,7]]},"4539":{"position":[[2119,6],[3034,7]]},"4547":{"position":[[3092,11]]},"4562":{"position":[[4789,7]]},"4572":{"position":[[206,9],[230,8]]},"4576":{"position":[[247,8]]},"4580":{"position":[[417,9]]},"4582":{"position":[[364,6]]},"4595":{"position":[[144,8],[261,8]]},"4597":{"position":[[328,7],[475,6]]},"4614":{"position":[[116,6]]},"4620":{"position":[[269,7]]},"4641":{"position":[[0,8]]},"4643":{"position":[[3580,6],[3590,6]]},"4649":{"position":[[19,8]]},"4651":{"position":[[19,8]]},"4669":{"position":[[962,9]]},"4686":{"position":[[117,10]]},"4709":{"position":[[185,8]]},"4730":{"position":[[2310,6]]},"4744":{"position":[[1007,8]]},"4788":{"position":[[19,8]]},"4795":{"position":[[43,7]]},"4797":{"position":[[400,7],[511,6]]},"4814":{"position":[[0,8]]},"4816":{"position":[[0,6],[10,6],[31,6],[41,6]]},"4822":{"position":[[19,8]]},"4824":{"position":[[19,8]]},"4831":{"position":[[32,8]]}}}],["optmiz",{"_index":6201,"t":{"1455":{"position":[[723,7]]}}}],["oracl",{"_index":6215,"t":{"1455":{"position":[[1571,6],[1591,6]]}}}],["orchestr",{"_index":2257,"t":{"372":{"position":[[264,13]]},"376":{"position":[[50,14]]},"796":{"position":[[71,13]]},"822":{"position":[[352,13]]},"830":{"position":[[315,13]]},"854":{"position":[[296,12]]},"890":{"position":[[123,12]]},"1064":{"position":[[584,11]]},"1077":{"position":[[163,13]]},"1748":{"position":[[123,12]]},"2059":{"position":[[1843,12],[1999,12]]},"2578":{"position":[[705,13]]},"3468":{"position":[[208,13]]},"4107":{"position":[[716,12]]},"4109":{"position":[[5333,12]]},"4148":{"position":[[70,13]]},"4204":{"position":[[507,13],[526,13]]},"4429":{"position":[[236,13]]},"4442":{"position":[[212,13]]},"4453":{"position":[[212,13]]},"4839":{"position":[[872,13]]}}}],["orchestration.stack",{"_index":9485,"t":{"3036":{"position":[[4541,21]]}}}],["orchestration_crud",{"_index":9486,"t":{"3036":{"position":[[4571,19]]}}}],["order",{"_index":693,"t":{"117":{"position":[[3,5]]},"149":{"position":[[17,5]]},"167":{"position":[[459,5]]},"209":{"position":[[81,5]]},"216":{"position":[[419,5]]},"239":{"position":[[283,5]]},"241":{"position":[[150,5]]},"364":{"position":[[283,5]]},"382":{"position":[[334,5]]},"397":{"position":[[309,5]]},"401":{"position":[[1250,5]]},"403":{"position":[[75,5]]},"407":{"position":[[40,5],[86,5]]},"413":{"position":[[51,5]]},"423":{"position":[[971,5]]},"477":{"position":[[434,5]]},"489":{"position":[[1069,5]]},"510":{"position":[[132,5]]},"530":{"position":[[1252,5]]},"641":{"position":[[259,5]]},"666":{"position":[[259,5]]},"705":{"position":[[997,5]]},"732":{"position":[[1549,6]]},"912":{"position":[[1648,5]]},"914":{"position":[[1100,5]]},"949":{"position":[[394,5]]},"1005":{"position":[[1164,5],[6621,5]]},"1244":{"position":[[710,5],[866,6]]},"1486":{"position":[[568,5]]},"1511":{"position":[[251,6]]},"1513":{"position":[[143,5]]},"1635":{"position":[[160,5]]},"1646":{"position":[[3,5]]},"1648":{"position":[[155,5]]},"1652":{"position":[[317,5]]},"1796":{"position":[[1648,5]]},"1798":{"position":[[1100,5]]},"1840":{"position":[[394,5]]},"1896":{"position":[[1164,5],[6621,5]]},"1977":{"position":[[317,5]]},"2021":{"position":[[189,6]]},"2048":{"position":[[2239,5]]},"2119":{"position":[[625,5]]},"2121":{"position":[[3,5]]},"2188":{"position":[[602,5]]},"2211":{"position":[[1524,5]]},"2343":{"position":[[235,5],[1212,5]]},"2410":{"position":[[235,5],[1212,5]]},"2480":{"position":[[337,5],[1322,5]]},"2584":{"position":[[1085,5]]},"2586":{"position":[[695,5]]},"2714":{"position":[[179,5],[1638,6]]},"2790":{"position":[[326,9]]},"2814":{"position":[[454,8]]},"2816":{"position":[[88,5],[152,6],[161,8]]},"2973":{"position":[[394,5]]},"3050":{"position":[[368,5]]},"3296":{"position":[[373,5],[420,5]]},"3321":{"position":[[575,5]]},"3365":{"position":[[3,5]]},"3371":{"position":[[3,5]]},"3527":{"position":[[461,5]]},"3582":{"position":[[934,5]]},"3592":{"position":[[141,5],[2383,5]]},"3598":{"position":[[1077,5]]},"3606":{"position":[[310,6],[357,6]]},"3611":{"position":[[3,5]]},"3638":{"position":[[107,5]]},"3661":{"position":[[1827,5]]},"3663":{"position":[[442,5]]},"3669":{"position":[[809,8]]},"3673":{"position":[[1273,6]]},"3698":{"position":[[2481,5]]},"3700":{"position":[[465,5]]},"3706":{"position":[[1813,5]]},"3710":{"position":[[958,8]]},"3716":{"position":[[197,6]]},"3785":{"position":[[2179,5]]},"3787":{"position":[[465,5]]},"3803":{"position":[[945,8]]},"3809":{"position":[[174,6]]},"3829":{"position":[[5160,6]]},"3835":{"position":[[1544,5]]},"3910":{"position":[[277,5]]},"3928":{"position":[[3273,5],[3674,9]]},"4148":{"position":[[559,5]]},"4275":{"position":[[533,5]]},"4277":{"position":[[89,5],[191,5]]},"4283":{"position":[[233,5],[537,6],[675,5]]},"4302":{"position":[[2479,5]]},"4304":{"position":[[1817,5]]},"4313":{"position":[[743,5]]},"4355":{"position":[[3,5],[1207,5]]},"4420":{"position":[[216,5],[2518,5]]},"4427":{"position":[[534,5]]},"4431":{"position":[[141,5],[200,5],[690,5],[2374,5]]},"4433":{"position":[[258,5],[2449,5],[3069,5]]},"4435":{"position":[[60,5],[201,5],[1145,5],[1305,5]]},"4440":{"position":[[519,5]]},"4444":{"position":[[423,5]]},"4448":{"position":[[85,5],[1088,5]]},"4451":{"position":[[519,5]]},"4455":{"position":[[423,5]]},"4459":{"position":[[85,5]]},"4471":{"position":[[297,5]]},"4473":{"position":[[229,5]]},"4475":{"position":[[647,5]]},"4477":{"position":[[3,5]]},"4479":{"position":[[349,5],[1967,5],[2048,5]]},"4481":{"position":[[254,5]]},"4483":{"position":[[49,5],[230,5]]},"4485":{"position":[[3,5],[211,5],[2363,5]]},"4489":{"position":[[88,5],[197,5]]},"4493":{"position":[[542,5]]},"4525":{"position":[[182,5]]},"4529":{"position":[[329,5]]},"4535":{"position":[[1911,5],[3470,5],[4245,5]]},"4537":{"position":[[310,5]]},"4539":{"position":[[3,5],[797,5],[1190,5],[3732,5],[4496,5],[5830,5],[6477,5]]},"4547":{"position":[[141,5],[845,5],[1261,5],[2143,5],[2706,5],[3424,5],[3834,5]]},"4558":{"position":[[3,5]]},"4560":{"position":[[63,5]]},"4618":{"position":[[494,5]]},"4656":{"position":[[541,5]]},"4691":{"position":[[744,6],[766,5]]},"4701":{"position":[[65,6],[457,5]]},"4791":{"position":[[105,5]]},"4793":{"position":[[360,5]]},"4795":{"position":[[3,5]]}}}],["org",{"_index":167,"t":{"24":{"position":[[237,3]]},"963":{"position":[[5053,4],[5152,3]]},"1854":{"position":[[5053,4],[5152,3]]},"2121":{"position":[[529,3],[569,3],[683,3]]},"2987":{"position":[[5053,4],[5152,3]]},"3378":{"position":[[541,4]]}}}],["org/mi",{"_index":2126,"t":{"362":{"position":[[135,6]]}}}],["org/zuul_demo_config",{"_index":7650,"t":{"2123":{"position":[[992,21]]}}}],["org/zuul_demo_repo",{"_index":7651,"t":{"2123":{"position":[[1057,18]]}}}],["organ",{"_index":1389,"t":{"197":{"position":[[44,13]]},"199":{"position":[[466,13]]},"201":{"position":[[138,13]]},"216":{"position":[[219,10],[446,8]]},"220":{"position":[[352,10]]},"241":{"position":[[385,8],[446,10],[491,8]]},"311":{"position":[[189,13]]},"343":{"position":[[212,13],[400,13]]},"520":{"position":[[901,13]]},"530":{"position":[[1897,13],[2140,12],[2274,12]]},"545":{"position":[[382,12],[522,12]]},"547":{"position":[[183,9]]},"772":{"position":[[203,13]]},"963":{"position":[[4377,12]]},"1056":{"position":[[1635,13],[1845,13]]},"1064":{"position":[[2110,13]]},"1067":{"position":[[2143,13]]},"1259":{"position":[[55,13]]},"1854":{"position":[[4377,12]]},"2126":{"position":[[62,13]]},"2366":{"position":[[191,13]]},"2485":{"position":[[135,13]]},"2514":{"position":[[57,13]]},"2522":{"position":[[520,13]]},"2525":{"position":[[460,13]]},"2565":{"position":[[25,9]]},"2580":{"position":[[166,14]]},"2836":{"position":[[264,13]]},"2987":{"position":[[4377,12]]},"3392":{"position":[[186,13]]},"3519":{"position":[[200,13],[371,12]]},"3582":{"position":[[203,13]]},"3625":{"position":[[237,13],[354,13],[383,12]]},"3627":{"position":[[32,12],[111,13],[215,13],[501,13],[574,12],[830,13]]},"3629":{"position":[[31,12],[105,12],[283,12]]},"3636":{"position":[[61,12]]},"3638":{"position":[[43,12]]},"3864":{"position":[[203,13]]},"4109":{"position":[[5265,13]]},"4473":{"position":[[131,12]]},"4506":{"position":[[1162,12]]},"4508":{"position":[[998,13]]},"4539":{"position":[[3284,12],[4032,12],[4366,12],[6063,13]]},"4556":{"position":[[132,12]]},"4560":{"position":[[1274,9],[2739,9],[3959,9]]},"4562":{"position":[[3556,13]]},"4593":{"position":[[4024,12],[4298,12],[4531,13],[4858,12],[4905,14]]},"4839":{"position":[[355,14]]}}}],["organis",{"_index":648,"t":{"95":{"position":[[258,12]]},"368":{"position":[[5369,12]]},"442":{"position":[[456,13]]},"1056":{"position":[[193,13],[2125,13]]},"1064":{"position":[[2280,13]]},"1501":{"position":[[783,12],[957,12],[1131,12]]},"3047":{"position":[[210,12]]},"3390":{"position":[[806,12]]},"3523":{"position":[[36,12]]},"3527":{"position":[[130,13],[475,12]]},"3533":{"position":[[176,13],[2150,13]]},"4826":{"position":[[913,12]]}}}],["organisation'",{"_index":10208,"t":{"3549":{"position":[[1527,14]]}}}],["organisation/demo",{"_index":644,"t":{"95":{"position":[[109,17]]}}}],["organiz",{"_index":2026,"t":{"311":{"position":[[113,14]]},"2366":{"position":[[115,14]]},"3549":{"position":[[1215,14]]},"4502":{"position":[[558,14]]},"4522":{"position":[[31,14],[1638,14]]},"4539":{"position":[[6127,14]]}}}],["organization#permiss",{"_index":2609,"t":{"530":{"position":[[1974,24]]}}}],["organization'",{"_index":1409,"t":{"197":{"position":[[1428,15]]},"201":{"position":[[856,14]]},"293":{"position":[[1091,14]]},"4504":{"position":[[8,14]]}}}],["organization/compani",{"_index":676,"t":{"103":{"position":[[83,20]]},"3571":{"position":[[720,20]]}}}],["orgs/sovereigncloudstack/data.yaml",{"_index":1521,"t":{"201":{"position":[[744,35]]}}}],["orient",{"_index":1441,"t":{"199":{"position":[[635,12]]},"3088":{"position":[[197,9]]},"3350":{"position":[[37,11]]},"4722":{"position":[[693,8]]}}}],["origin",{"_index":1283,"t":{"181":{"position":[[1674,6],[1771,6]]},"185":{"position":[[419,6]]},"199":{"position":[[458,7]]},"249":{"position":[[29,6]]},"251":{"position":[[89,6]]},"440":{"position":[[260,6],[459,6],[539,6]]},"963":{"position":[[3202,9]]},"1175":{"position":[[5051,6]]},"1854":{"position":[[3202,9]]},"2329":{"position":[[203,8]]},"2347":{"position":[[554,8],[641,10]]},"2349":{"position":[[202,8],[250,11]]},"2351":{"position":[[62,10]]},"2353":{"position":[[138,8]]},"2355":{"position":[[332,10],[2003,8],[2445,8]]},"2396":{"position":[[203,8]]},"2414":{"position":[[554,8],[641,10]]},"2416":{"position":[[202,8],[250,11]]},"2418":{"position":[[62,10]]},"2420":{"position":[[138,8]]},"2422":{"position":[[332,10],[2003,8],[2445,8]]},"2453":{"position":[[673,10],[875,6]]},"2647":{"position":[[2190,8]]},"2649":{"position":[[3501,8]]},"2674":{"position":[[419,8]]},"2720":{"position":[[887,7],[916,7]]},"2747":{"position":[[356,6]]},"2822":{"position":[[22,7],[96,7]]},"2987":{"position":[[3202,9]]},"3276":{"position":[[184,8]]},"3410":{"position":[[274,7]]},"4102":{"position":[[1225,8]]},"4226":{"position":[[4016,11]]},"4230":{"position":[[2182,11]]},"4355":{"position":[[533,8]]},"4593":{"position":[[2850,10]]},"4744":{"position":[[63,7]]}}}],["origin=cloudsmith/caddy/st",{"_index":4083,"t":{"967":{"position":[[763,33]]},"1858":{"position":[[763,33]]},"2991":{"position":[[763,33]]}}}],["orphan",{"_index":3125,"t":{"706":{"position":[[1572,8]]},"2463":{"position":[[549,8]]}}}],["or—if",{"_index":10244,"t":{"3592":{"position":[[511,5]]}}}],["os",{"_index":405,"t":{"37":{"position":[[1744,2],[1812,2]]},"293":{"position":[[299,2],[539,2]]},"432":{"position":[[55,3]]},"506":{"position":[[55,3]]},"894":{"position":[[1556,2],[1597,2],[1979,2],[2016,2],[2187,2]]},"934":{"position":[[727,2]]},"942":{"position":[[3119,2],[3194,2]]},"1324":{"position":[[12671,2],[13171,2]]},"1700":{"position":[[70,2],[772,2]]},"1709":{"position":[[333,2],[449,2]]},"1713":{"position":[[678,2],[1297,2],[1590,2],[2319,2],[2406,2]]},"1716":{"position":[[14,2],[1483,2]]},"1720":{"position":[[164,2],[651,2],[1291,2],[1361,2],[2056,2],[2175,2]]},"1725":{"position":[[81,2]]},"1728":{"position":[[12,2]]},"1730":{"position":[[28,2],[184,2]]},"1732":{"position":[[12,2],[123,2],[1023,2],[1107,2]]},"1734":{"position":[[12,2],[29,2],[124,2],[1018,2],[1035,2],[1128,2]]},"1745":{"position":[[91,2]]},"1752":{"position":[[1556,2],[1597,2],[1979,2],[2016,2],[2187,2]]},"1825":{"position":[[727,2]]},"1833":{"position":[[3119,2],[3194,2]]},"2011":{"position":[[64,2],[95,2]]},"2019":{"position":[[99,4]]},"2196":{"position":[[2073,2],[2122,2],[2176,2],[2208,2],[2234,2],[2292,2],[2314,2],[2339,2],[2373,2],[2396,2],[2426,2],[2878,2],[2927,2],[2981,2],[3013,2],[3039,2],[3097,2],[3119,2],[3144,2],[3178,2],[3201,2],[3231,2],[3343,2]]},"2252":{"position":[[2867,2]]},"2272":{"position":[[267,2],[318,2]]},"2279":{"position":[[17,2]]},"2343":{"position":[[416,2]]},"2410":{"position":[[416,2]]},"2958":{"position":[[727,2]]},"2966":{"position":[[3119,2],[3194,2]]},"3230":{"position":[[867,2]]},"3357":{"position":[[1222,2]]},"3410":{"position":[[384,2]]},"3824":{"position":[[17,2]]},"3829":{"position":[[1845,2]]},"3835":{"position":[[218,2],[1531,2],[1701,2],[2054,2]]},"3928":{"position":[[4062,3]]},"3951":{"position":[[289,2]]},"3956":{"position":[[333,2]]},"3968":{"position":[[1340,2]]},"4516":{"position":[[642,3]]}}}],["os.environ[\"os_auth_url",{"_index":8310,"t":{"2279":{"position":[[93,26]]}}}],["os.environ[\"os_identity_api_vers",{"_index":8317,"t":{"2279":{"position":[[433,38]]}}}],["os.environ[\"os_password",{"_index":8315,"t":{"2279":{"position":[[334,26]]}}}],["os.environ[\"os_project_domain_nam",{"_index":8312,"t":{"2279":{"position":[[190,37]]}}}],["os.environ[\"os_project_nam",{"_index":8311,"t":{"2279":{"position":[[136,30]]}}}],["os.environ[\"os_region_nam",{"_index":8316,"t":{"2279":{"position":[[379,29]]}}}],["os.environ[\"os_user_domain_nam",{"_index":8314,"t":{"2279":{"position":[[287,34]]}}}],["os.environ[\"os_usernam",{"_index":8313,"t":{"2279":{"position":[[240,26]]}}}],["os:operatingsystem",{"_index":10864,"t":{"3833":{"position":[[1215,18]]}}}],["os_",{"_index":8321,"t":{"2279":{"position":[[608,3]]}}}],["os_application_credential_id",{"_index":9018,"t":{"2725":{"position":[[1230,29]]}}}],["os_application_credential_secret",{"_index":9019,"t":{"2725":{"position":[[1263,33]]}}}],["os_architectur",{"_index":9402,"t":{"3036":{"position":[[738,16]]}}}],["os_auth_typ",{"_index":9017,"t":{"2725":{"position":[[1133,13]]}}}],["os_auth_url",{"_index":8284,"t":{"2276":{"position":[[716,11],[2172,12]]},"2281":{"position":[[332,12]]},"2725":{"position":[[1150,12]]}}}],["os_auth_url=https://api.testbed.osism.xyz:5000/v3",{"_index":8285,"t":{"2276":{"position":[[791,49]]}}}],["os_cacert",{"_index":3927,"t":{"942":{"position":[[3505,10]]},"1833":{"position":[[3505,10]]},"2966":{"position":[[3505,10]]}}}],["os_cacert=/home/debian/ca",{"_index":3887,"t":{"942":{"position":[[396,25]]},"1833":{"position":[[396,25]]},"2966":{"position":[[396,25]]}}}],["os_cacert=/path/to/cacert.crt",{"_index":3841,"t":{"936":{"position":[[681,29]]},"1827":{"position":[[681,29]]},"2960":{"position":[[681,29]]}}}],["os_cloud",{"_index":407,"t":{"37":{"position":[[1790,9]]},"932":{"position":[[184,8]]},"934":{"position":[[771,9]]},"942":{"position":[[3442,8]]},"1823":{"position":[[184,8]]},"1825":{"position":[[771,9]]},"1833":{"position":[[3442,8]]},"2041":{"position":[[199,9]]},"2956":{"position":[[184,8]]},"2958":{"position":[[771,9]]},"2966":{"position":[[3442,8]]},"3602":{"position":[[585,9],[595,10]]},"3683":{"position":[[232,9]]},"3742":{"position":[[494,9]]},"3751":{"position":[[94,8]]},"3795":{"position":[[232,9],[495,8]]},"3916":{"position":[[309,8],[477,9]]}}}],["os_cloud=$os_cloud",{"_index":10926,"t":{"3916":{"position":[[490,18]]}}}],["os_cloud=.yml",{"_index":6678,"t":{"1661":{"position":[[701,9]]}}}],["playbook",{"_index":846,"t":{"147":{"position":[[71,10]]},"151":{"position":[[120,9]]},"157":{"position":[[192,9]]},"271":{"position":[[547,10],[589,9]]},"368":{"position":[[453,8],[1569,9],[1980,10],[2027,9],[2846,10],[7599,8],[7659,8],[7758,9]]},"522":{"position":[[307,9],[415,9]]},"526":{"position":[[586,8],[685,8],[1329,8],[1428,8]]},"826":{"position":[[29,9]]},"1175":{"position":[[3324,9]]},"1177":{"position":[[1076,9],[4679,9]]},"1385":{"position":[[606,9]]},"1472":{"position":[[2332,8],[2688,8],[2884,8]]},"1474":{"position":[[607,9]]},"1478":{"position":[[403,9]]},"1561":{"position":[[21,8]]},"1644":{"position":[[18,9],[220,9],[344,9]]},"1657":{"position":[[59,9]]},"1694":{"position":[[373,8],[432,8],[487,8],[548,8],[610,8],[978,8],[1703,8],[2215,8],[6115,8],[7015,8],[7861,8]]},"1740":{"position":[[40,9],[54,8]]},"2057":{"position":[[265,9],[289,9]]},"2071":{"position":[[965,9],[1010,9]]},"2074":{"position":[[380,8]]},"2084":{"position":[[71,10]]},"2086":{"position":[[121,9]]},"2117":{"position":[[514,9]]},"2119":{"position":[[163,8]]},"2123":{"position":[[1306,8]]},"2184":{"position":[[4242,10]]},"2207":{"position":[[572,9]]},"2216":{"position":[[23,8]]},"2433":{"position":[[87,8],[407,8]]},"2482":{"position":[[331,9]]},"3026":{"position":[[92,9]]},"3093":{"position":[[0,8],[79,8]]},"3119":{"position":[[114,9]]},"3130":{"position":[[847,8]]},"3153":{"position":[[168,9]]},"3225":{"position":[[746,8],[833,8]]},"3384":{"position":[[390,10]]}}}],["playbook.yaml",{"_index":2196,"t":{"368":{"position":[[2721,13],[3512,13]]}}}],["playbooks/base/post",{"_index":2175,"t":{"368":{"position":[[685,19]]}}}],["playbooks/base/post.yaml",{"_index":2174,"t":{"368":{"position":[[658,24]]}}}],["playbooks/base/pre.yaml",{"_index":2173,"t":{"368":{"position":[[622,23]]}}}],["playbooks/clouds.yaml.j2",{"_index":10067,"t":{"3381":{"position":[[225,25]]}}}],["playbooks/mi",{"_index":2195,"t":{"368":{"position":[[2708,12]]}}}],["playbooks/pull/215/fil",{"_index":7488,"t":{"2074":{"position":[[422,24]]}}}],["playbooks/testplaybook.yaml",{"_index":2240,"t":{"368":{"position":[[6835,29],[6901,27],[7770,27]]}}}],["playbooks/testplaybooktwo.yaml",{"_index":2242,"t":{"368":{"position":[[6976,30]]}}}],["playground",{"_index":7839,"t":{"2175":{"position":[[435,11]]}}}],["playground0",{"_index":281,"t":{"28":{"position":[[2008,11],[2029,11]]}}}],["playground1",{"_index":285,"t":{"28":{"position":[[2112,11],[2133,11]]}}}],["playground2",{"_index":287,"t":{"28":{"position":[[2216,11],[2237,11]]}}}],["playground3",{"_index":289,"t":{"28":{"position":[[2320,11],[2341,11]]}}}],["playground4",{"_index":291,"t":{"28":{"position":[[2424,11],[2445,11]]}}}],["playground5",{"_index":293,"t":{"28":{"position":[[2528,11],[2549,11]]}}}],["playground6",{"_index":295,"t":{"28":{"position":[[2632,11],[2653,11]]}}}],["playground7",{"_index":297,"t":{"28":{"position":[[2736,11],[2757,11]]}}}],["playground8",{"_index":299,"t":{"28":{"position":[[2840,11],[2861,11]]}}}],["playground9",{"_index":301,"t":{"28":{"position":[[2944,11],[2965,11]]}}}],["pleas",{"_index":131,"t":{"19":{"position":[[42,6],[119,6]]},"37":{"position":[[755,6],[1550,6]]},"66":{"position":[[112,6]]},"68":{"position":[[199,6]]},"145":{"position":[[179,6]]},"153":{"position":[[38,6],[279,6]]},"155":{"position":[[435,6],[724,6]]},"157":{"position":[[27,6]]},"161":{"position":[[0,6]]},"163":{"position":[[91,6],[169,6],[297,6]]},"199":{"position":[[14,6],[146,6]]},"201":{"position":[[709,6]]},"337":{"position":[[610,6]]},"345":{"position":[[218,6]]},"347":{"position":[[0,6]]},"434":{"position":[[317,6]]},"438":{"position":[[217,6]]},"442":{"position":[[162,6],[284,6]]},"444":{"position":[[144,6]]},"473":{"position":[[1419,6]]},"479":{"position":[[1502,6]]},"491":{"position":[[273,6]]},"508":{"position":[[317,6]]},"514":{"position":[[1142,6],[1781,6]]},"530":{"position":[[351,6]]},"588":{"position":[[148,6],[270,6]]},"930":{"position":[[551,6]]},"963":{"position":[[826,6],[1113,6],[5058,6]]},"1177":{"position":[[372,6]]},"1344":{"position":[[194,6]]},"1369":{"position":[[125,6]]},"1407":{"position":[[98,6]]},"1433":{"position":[[147,6]]},"1439":{"position":[[88,6]]},"1455":{"position":[[830,6]]},"1503":{"position":[[669,6]]},"1525":{"position":[[749,6]]},"1659":{"position":[[696,6]]},"1821":{"position":[[551,6]]},"1854":{"position":[[826,6],[1113,6],[5058,6]]},"1906":{"position":[[0,6]]},"1912":{"position":[[0,6]]},"1914":{"position":[[0,6]]},"1938":{"position":[[0,6]]},"2037":{"position":[[608,6]]},"2039":{"position":[[35,6]]},"2045":{"position":[[80,6]]},"2163":{"position":[[4077,6]]},"2178":{"position":[[326,6]]},"2184":{"position":[[1052,6]]},"2190":{"position":[[135,6]]},"2194":{"position":[[226,6]]},"2209":{"position":[[0,6]]},"2221":{"position":[[54,6]]},"2242":{"position":[[503,6]]},"2250":{"position":[[254,6]]},"2276":{"position":[[1508,7]]},"2372":{"position":[[322,6]]},"2380":{"position":[[345,6]]},"2622":{"position":[[73,6]]},"2655":{"position":[[261,6]]},"2745":{"position":[[60,6]]},"2758":{"position":[[280,6]]},"2804":{"position":[[316,6]]},"2826":{"position":[[70,6]]},"2896":{"position":[[21,6]]},"2898":{"position":[[457,6]]},"2954":{"position":[[551,6]]},"2987":{"position":[[826,6],[1113,6],[5058,6]]},"3083":{"position":[[552,6]]},"3093":{"position":[[64,6]]},"3110":{"position":[[59,6]]},"3116":{"position":[[283,6]]},"3132":{"position":[[254,6]]},"3142":{"position":[[59,6]]},"3153":{"position":[[571,6]]},"3157":{"position":[[39,6]]},"3159":{"position":[[583,6]]},"3162":{"position":[[10,6]]},"3174":{"position":[[59,6]]},"3195":{"position":[[39,6]]},"3197":{"position":[[0,6]]},"3200":{"position":[[10,6]]},"3212":{"position":[[59,6]]},"3240":{"position":[[39,6]]},"3242":{"position":[[0,6]]},"3270":{"position":[[59,6]]},"3300":{"position":[[39,6]]},"3308":{"position":[[504,7]]},"3310":{"position":[[354,6]]},"3319":{"position":[[59,6]]},"3340":{"position":[[59,6]]},"3365":{"position":[[275,6]]},"3371":{"position":[[275,6]]},"3381":{"position":[[1561,6]]},"3629":{"position":[[486,6]]},"3714":{"position":[[1338,6]]},"3920":{"position":[[131,6]]},"4130":{"position":[[559,6]]},"4337":{"position":[[582,6]]},"4604":{"position":[[690,6]]},"4629":{"position":[[271,6]]},"4643":{"position":[[507,6]]},"4833":{"position":[[46,6]]},"4839":{"position":[[1821,6]]},"4841":{"position":[[0,6]]},"4849":{"position":[[135,6]]},"4861":{"position":[[113,6]]},"4865":{"position":[[69,6]]},"4868":{"position":[[125,6]]}}}],["pledg",{"_index":1116,"t":{"173":{"position":[[613,7]]},"179":{"position":[[1701,7]]},"181":{"position":[[2144,7]]},"197":{"position":[[739,6]]}}}],["plethora",{"_index":9167,"t":{"2802":{"position":[[75,8]]}}}],["plu",{"_index":8964,"t":{"2712":{"position":[[1699,4]]},"3170":{"position":[[229,4]]},"3731":{"position":[[1373,4]]},"3923":{"position":[[296,5]]},"3947":{"position":[[4010,5]]},"4051":{"position":[[103,4]]}}}],["plug",{"_index":9933,"t":{"3298":{"position":[[250,4]]}}}],["plugin",{"_index":2272,"t":{"378":{"position":[[798,7],[810,6]]},"541":{"position":[[538,7]]},"557":{"position":[[5608,8]]},"655":{"position":[[386,6]]},"661":{"position":[[634,7]]},"668":{"position":[[676,6],[711,6]]},"673":{"position":[[386,6]]},"696":{"position":[[1383,6]]},"701":{"position":[[2424,6]]},"705":{"position":[[60,8],[668,7],[690,6],[726,6],[1595,7],[1617,6]]},"738":{"position":[[60,8],[527,7],[549,6]]},"846":{"position":[[842,8]]},"1564":{"position":[[309,8]]},"2108":{"position":[[37,7]]},"2433":{"position":[[310,6],[1242,7]]},"2557":{"position":[[530,7]]},"2932":{"position":[[122,7]]},"3097":{"position":[[601,6]]},"3130":{"position":[[719,6]]},"3159":{"position":[[332,6]]},"3227":{"position":[[96,7]]},"3238":{"position":[[131,7],[259,7]]},"3281":{"position":[[861,6]]},"4060":{"position":[[81,8],[103,6],[270,6],[496,6],[771,7],[804,6]]},"4068":{"position":[[349,7]]},"4070":{"position":[[9,7]]},"4077":{"position":[[983,6],[1034,7]]},"4079":{"position":[[291,6],[526,7]]},"4081":{"position":[[47,8],[109,7],[215,7],[612,7],[675,7],[753,7],[860,7]]},"4087":{"position":[[9,7]]},"4215":{"position":[[343,6]]},"4224":{"position":[[32,6]]},"4226":{"position":[[552,6]]},"4228":{"position":[[981,6],[1677,6]]},"4230":{"position":[[8,7],[77,6]]},"4273":{"position":[[517,7],[564,6]]},"4275":{"position":[[31,7],[591,7],[913,6]]},"4277":{"position":[[52,7],[262,6],[285,7]]},"4279":{"position":[[31,6],[1295,6]]},"4281":{"position":[[26,6]]},"4283":{"position":[[288,8]]},"4285":{"position":[[64,6]]},"4291":{"position":[[1411,7],[1555,7],[2514,6],[2763,8]]},"4569":{"position":[[296,8],[362,7],[509,6],[750,7]]},"4572":{"position":[[85,7]]},"4574":{"position":[[339,7],[358,6]]},"4576":{"position":[[164,7]]},"4578":{"position":[[57,7]]},"4580":{"position":[[344,7],[469,8],[675,7],[1805,7],[2508,7],[3131,7]]},"4582":{"position":[[28,6],[150,6],[711,7]]}}}],["plugins.security.dis",{"_index":5543,"t":{"1303":{"position":[[1078,26],[3249,26]]}}}],["plural",{"_index":11811,"t":{"4697":{"position":[[27,6]]}}}],["pluscloud",{"_index":7845,"t":{"2178":{"position":[[537,9],[577,9]]},"3103":{"position":[[406,9]]},"3136":{"position":[[406,9]]},"3367":{"position":[[605,9]]}}}],["pluscloudopen",{"_index":7846,"t":{"2178":{"position":[[563,13]]}}}],["plusserv",{"_index":78,"t":{"9":{"position":[[109,10]]},"22":{"position":[[54,10]]},"24":{"position":[[119,10],[319,10]]},"2178":{"position":[[552,10],[596,10]]},"3103":{"position":[[321,10]]},"3136":{"position":[[321,10]]},"3168":{"position":[[746,10]]},"3272":{"position":[[249,10]]},"3367":{"position":[[354,10],[659,10]]},"3378":{"position":[[1045,10]]}}}],["po",{"_index":8758,"t":{"2626":{"position":[[2443,2]]}}}],["poc",{"_index":4720,"t":{"1177":{"position":[[3173,5]]},"2584":{"position":[[280,3]]},"3236":{"position":[[366,4]]},"3288":{"position":[[98,3],[615,4]]},"3367":{"position":[[739,3],[753,3],[809,3],[833,3]]},"4230":{"position":[[1029,5],[1563,3],[4320,3]]},"4593":{"position":[[5596,3]]}}}],["pod",{"_index":2515,"t":{"491":{"position":[[834,3]]},"541":{"position":[[672,4],[1237,5],[1277,3]]},"555":{"position":[[137,5]]},"588":{"position":[[1020,5]]},"590":{"position":[[43,4]]},"708":{"position":[[152,4],[201,3],[241,3],[1069,3]]},"715":{"position":[[395,3]]},"717":{"position":[[504,3]]},"719":{"position":[[111,3]]},"724":{"position":[[207,3]]},"726":{"position":[[209,3]]},"739":{"position":[[384,3]]},"1405":{"position":[[973,3]]},"1431":{"position":[[97,5]]},"1433":{"position":[[820,4]]},"2539":{"position":[[204,5]]},"2723":{"position":[[223,5]]},"2743":{"position":[[353,3],[376,4],[405,3],[450,4]]},"2756":{"position":[[1306,3]]},"2853":{"position":[[141,3],[278,4]]},"2873":{"position":[[51,4]]},"3185":{"position":[[1040,3]]},"3268":{"position":[[116,3]]},"3296":{"position":[[1036,4]]},"4113":{"position":[[1679,3],[1966,5],[2411,4]]},"4137":{"position":[[251,3]]},"4275":{"position":[[137,4],[229,3],[1080,3]]},"4283":{"position":[[91,3]]},"4407":{"position":[[352,4]]},"4427":{"position":[[243,4]]},"4431":{"position":[[545,4],[879,3],[892,3],[908,3],[951,3],[989,4],[1064,4],[1150,3],[1471,3],[1568,3],[1980,4]]},"4433":{"position":[[202,4],[458,4],[1176,4],[1286,4],[1546,4]]},"4440":{"position":[[234,4]]},"4451":{"position":[[234,4]]},"4529":{"position":[[300,3],[679,5]]},"4539":{"position":[[2538,4],[2682,4],[4903,4],[5475,3],[7028,3]]},"4541":{"position":[[105,4]]},"4543":{"position":[[0,3],[91,4],[397,3],[959,3],[1034,3],[1091,3],[1145,3],[1196,3],[1480,3],[1547,3],[1866,4]]},"4547":{"position":[[2182,5],[3510,3],[3597,3],[3774,3]]},"4551":{"position":[[99,3]]},"4580":{"position":[[92,4],[128,4],[862,4],[2875,3]]},"4726":{"position":[[325,3]]},"4733":{"position":[[968,3]]}}}],["pod'",{"_index":11206,"t":{"4113":{"position":[[2213,5]]}}}],["pod/harbor",{"_index":3160,"t":{"708":{"position":[[286,10],[1117,10]]},"739":{"position":[[476,10]]}}}],["pod_cidr",{"_index":2896,"t":{"588":{"position":[[138,9]]}}}],["podaffin",{"_index":11516,"t":{"4431":{"position":[[1264,11]]}}}],["podantiaffin",{"_index":11517,"t":{"4431":{"position":[[1280,15]]}}}],["podman",{"_index":5030,"t":{"1222":{"position":[[269,7]]},"1493":{"position":[[86,6]]}}}],["podmonitor",{"_index":11957,"t":{"4849":{"position":[[1290,12]]}}}],["pods/statu",{"_index":9228,"t":{"2873":{"position":[[294,11]]}}}],["podspec",{"_index":11515,"t":{"4431":{"position":[[817,7],[1246,7]]}}}],["point",{"_index":59,"t":{"7":{"position":[[506,5]]},"70":{"position":[[209,5]]},"199":{"position":[[130,6]]},"262":{"position":[[160,5]]},"307":{"position":[[196,6]]},"440":{"position":[[300,8]]},"543":{"position":[[1868,8]]},"551":{"position":[[357,5],[1001,5]]},"696":{"position":[[787,5]]},"701":{"position":[[2538,6]]},"706":{"position":[[44,5]]},"712":{"position":[[138,6]]},"715":{"position":[[479,7]]},"717":{"position":[[598,7]]},"828":{"position":[[75,6]]},"834":{"position":[[424,5]]},"932":{"position":[[217,5]]},"1025":{"position":[[333,5]]},"1028":{"position":[[417,6]]},"1040":{"position":[[613,5]]},"1042":{"position":[[557,5]]},"1105":{"position":[[422,5]]},"1113":{"position":[[239,5]]},"1142":{"position":[[398,5]]},"1226":{"position":[[280,6]]},"1297":{"position":[[12,8]]},"1385":{"position":[[586,5]]},"1457":{"position":[[2991,5]]},"1466":{"position":[[759,6]]},"1823":{"position":[[217,5]]},"1902":{"position":[[125,5]]},"1988":{"position":[[201,5]]},"2057":{"position":[[725,5]]},"2175":{"position":[[690,5]]},"2186":{"position":[[37,6]]},"2234":{"position":[[413,6],[442,5]]},"2281":{"position":[[12,5]]},"2285":{"position":[[1022,5]]},"2289":{"position":[[256,6]]},"2299":{"position":[[1022,5]]},"2303":{"position":[[256,6]]},"2443":{"position":[[310,6]]},"2529":{"position":[[513,5]]},"2602":{"position":[[2176,5]]},"2616":{"position":[[8,6]]},"2626":{"position":[[890,6]]},"2644":{"position":[[299,6]]},"2647":{"position":[[2457,6]]},"2649":{"position":[[670,5],[2567,5]]},"2659":{"position":[[8,6]]},"2672":{"position":[[299,6]]},"2676":{"position":[[8,6]]},"2828":{"position":[[130,5]]},"2830":{"position":[[95,8]]},"2849":{"position":[[61,8]]},"2956":{"position":[[217,5]]},"3086":{"position":[[732,5]]},"3148":{"position":[[722,6]]},"3210":{"position":[[37,6]]},"3350":{"position":[[12,5]]},"3529":{"position":[[911,6]]},"3582":{"position":[[1090,6],[1963,7]]},"3706":{"position":[[1043,6]]},"3799":{"position":[[1043,6]]},"3829":{"position":[[2466,6]]},"3831":{"position":[[45,5],[460,5],[595,5],[843,5]]},"3947":{"position":[[3107,5]]},"3984":{"position":[[783,5]]},"4045":{"position":[[1992,5]]},"4102":{"position":[[1114,6]]},"4159":{"position":[[1649,5]]},"4161":{"position":[[919,6]]},"4163":{"position":[[832,6],[921,5]]},"4178":{"position":[[202,7]]},"4222":{"position":[[2442,7],[2841,7]]},"4230":{"position":[[4278,6]]},"4253":{"position":[[479,5]]},"4257":{"position":[[696,6]]},"4302":{"position":[[3742,5]]},"4433":{"position":[[1599,6]]},"4475":{"position":[[227,6]]},"4504":{"position":[[23,5]]},"4516":{"position":[[1161,6]]},"4560":{"position":[[692,6],[2579,5]]},"4562":{"position":[[631,6]]},"4589":{"position":[[547,5]]},"4593":{"position":[[1223,5]]},"4623":{"position":[[481,5]]},"4707":{"position":[[269,5],[338,6]]},"4715":{"position":[[231,5]]},"4797":{"position":[[354,5]]},"4849":{"position":[[57,5]]},"4872":{"position":[[393,5]]}}}],["pointer",{"_index":3170,"t":{"712":{"position":[[41,8]]}}}],["polici",{"_index":1150,"t":{"173":{"position":[[1862,8],[2197,8]]},"181":{"position":[[1975,9]]},"293":{"position":[[1115,9]]},"717":{"position":[[93,9],[117,9]]},"830":{"position":[[284,8]]},"914":{"position":[[3304,6],[3412,6],[4644,6],[4753,6],[5961,6],[6070,6]]},"967":{"position":[[874,8]]},"1324":{"position":[[5,6],[541,6]]},"1720":{"position":[[95,6],[1240,6],[2034,7]]},"1798":{"position":[[3304,6],[3412,6],[4644,6],[4753,6],[5961,6],[6070,6]]},"1858":{"position":[[874,8]]},"2287":{"position":[[563,6]]},"2301":{"position":[[563,6]]},"2441":{"position":[[152,6]]},"2443":{"position":[[36,6],[332,6],[436,6],[518,6],[643,6]]},"2447":{"position":[[128,6],[388,6],[464,6]]},"2453":{"position":[[192,6]]},"2499":{"position":[[483,9],[609,8]]},"2501":{"position":[[901,6]]},"2506":{"position":[[505,9]]},"2512":{"position":[[642,8]]},"2520":{"position":[[111,6],[212,8],[420,9]]},"2529":{"position":[[273,9],[306,9]]},"2531":{"position":[[1128,9],[1205,8]]},"2914":{"position":[[952,8]]},"2991":{"position":[[874,8]]},"3097":{"position":[[49,7]]},"3130":{"position":[[49,7]]},"3468":{"position":[[781,6]]},"3470":{"position":[[256,9]]},"3525":{"position":[[61,6]]},"3824":{"position":[[362,8],[480,6]]},"3829":{"position":[[1566,7]]},"3868":{"position":[[60,7]]},"3932":{"position":[[441,8]]},"3980":{"position":[[236,8]]},"4062":{"position":[[48,8]]},"4073":{"position":[[344,8]]},"4081":{"position":[[1091,7],[1216,6],[1269,6],[2148,8]]},"4085":{"position":[[58,8]]},"4353":{"position":[[397,7],[1106,6]]},"4420":{"position":[[2113,6]]},"4448":{"position":[[835,6]]},"4459":{"position":[[585,6]]},"4533":{"position":[[610,6]]},"4539":{"position":[[4644,8],[5285,8]]},"4543":{"position":[[441,8],[510,8],[724,7],[789,6],[867,6],[1008,7],[1514,6],[1573,6],[1712,6]]},"4545":{"position":[[161,6]]},"4547":{"position":[[239,7],[281,8],[3635,8],[3718,6],[3745,6],[3857,8]]},"4560":{"position":[[1862,6]]},"4562":{"position":[[6685,6]]},"4569":{"position":[[23,6],[235,9],[549,8],[605,6]]},"4574":{"position":[[501,6]]},"4580":{"position":[[38,8],[169,6],[545,8],[749,8],[787,8],[928,8],[1071,8],[1107,6],[1207,9],[1383,8],[1470,8],[1519,8],[1726,8],[2187,8],[2265,9]]},"4582":{"position":[[614,6],[673,6]]},"4584":{"position":[[29,8]]},"4608":{"position":[[780,6]]},"4610":{"position":[[43,6]]},"4614":{"position":[[908,6],[1086,6],[1284,6],[1365,6]]},"4618":{"position":[[407,6],[769,6],[897,8]]},"4620":{"position":[[103,9]]},"4629":{"position":[[263,7]]},"4665":{"position":[[72,6]]},"4667":{"position":[[14,6],[274,6],[575,6],[12545,6],[12645,8],[13297,6],[13489,6]]},"4669":{"position":[[46,6]]},"4775":{"position":[[132,6]]},"4826":{"position":[[2758,6]]}}}],["policy.networking.k8s.io",{"_index":11702,"t":{"4582":{"position":[[271,24]]}}}],["policy.yaml",{"_index":11156,"t":{"4062":{"position":[[211,11]]},"4614":{"position":[[1098,13]]},"4618":{"position":[[453,11]]}}}],["policy4",{"_index":11733,"t":{"4614":{"position":[[1125,8]]}}}],["policy_fil",{"_index":8471,"t":{"2443":{"position":[[212,13]]}}}],["policymak",{"_index":1851,"t":{"280":{"position":[[931,12]]}}}],["polit",{"_index":1446,"t":{"199":{"position":[[747,9]]}}}],["poll",{"_index":1810,"t":{"266":{"position":[[54,6]]},"3030":{"position":[[130,4]]},"3032":{"position":[[62,4],[191,7],[210,7]]},"4763":{"position":[[190,4],[214,4],[286,7]]},"4767":{"position":[[249,4],[338,4]]}}}],["polling.yaml",{"_index":9369,"t":{"3032":{"position":[[13,12]]}}}],["pollster",{"_index":9372,"t":{"3034":{"position":[[174,9]]}}}],["pollut",{"_index":10918,"t":{"3894":{"position":[[1708,9]]}}}],["pont",{"_index":10767,"t":{"3744":{"position":[[2716,6]]}}}],["pool",{"_index":1249,"t":{"179":{"position":[[1241,4],[1740,5]]},"938":{"position":[[1972,5]]},"1171":{"position":[[6,5],[889,5],[943,6]]},"1173":{"position":[[193,7],[649,6]]},"1175":{"position":[[5046,4]]},"1191":{"position":[[13,4],[29,7],[59,4],[972,4],[1157,4],[1242,4],[1350,4]]},"1301":{"position":[[3399,4]]},"1409":{"position":[[587,4],[891,4]]},"1411":{"position":[[6,5],[102,6],[539,5],[2083,5]]},"1503":{"position":[[1070,5],[1151,5],[1439,5],[1472,5]]},"1574":{"position":[[226,4],[262,5],[305,4]]},"1619":{"position":[[520,4]]},"1623":{"position":[[20,4],[87,6]]},"1625":{"position":[[11,4]]},"1629":{"position":[[11,4]]},"1631":{"position":[[11,4]]},"1633":{"position":[[80,4],[155,4]]},"1635":{"position":[[42,5],[86,4],[187,6]]},"1637":{"position":[[76,4],[325,4],[356,6],[557,4]]},"1641":{"position":[[11,4],[81,4]]},"1736":{"position":[[218,4],[716,4]]},"1829":{"position":[[1972,5]]},"1917":{"position":[[226,4],[262,5],[305,4]]},"1950":{"position":[[520,4]]},"1954":{"position":[[20,4],[87,6]]},"1956":{"position":[[11,4]]},"1960":{"position":[[68,4]]},"1962":{"position":[[85,5],[174,4],[204,4]]},"1964":{"position":[[80,4],[155,4]]},"1966":{"position":[[85,5],[174,4],[235,5]]},"1968":{"position":[[149,4],[398,4],[429,6],[630,4]]},"1972":{"position":[[11,4],[81,4]]},"2048":{"position":[[3570,4]]},"2962":{"position":[[1972,5]]},"3706":{"position":[[1347,4]]},"3761":{"position":[[935,5],[1049,4],[1132,4]]},"3763":{"position":[[600,5]]},"3799":{"position":[[1347,4]]},"4560":{"position":[[3190,4]]}}}],["pool=extra001",{"_index":4941,"t":{"1191":{"position":[[706,14]]}}}],["pool_nam",{"_index":6573,"t":{"1631":{"position":[[23,11]]},"1633":{"position":[[104,11]]},"1635":{"position":[[98,11],[110,11]]},"1962":{"position":[[216,11]]},"1964":{"position":[[104,11]]}}}],["poolnam",{"_index":6582,"t":{"1637":{"position":[[566,10]]},"1641":{"position":[[20,10]]},"1968":{"position":[[639,10]]},"1972":{"position":[[20,10]]}}}],["poor",{"_index":1489,"t":{"199":{"position":[[2144,4],[2162,4]]}}}],["popul",{"_index":2397,"t":{"461":{"position":[[524,9]]},"2184":{"position":[[4549,10]]}}}],["popular",{"_index":1158,"t":{"173":{"position":[[2064,7]]},"264":{"position":[[148,7]]},"834":{"position":[[216,7]]},"2094":{"position":[[11,7]]},"2574":{"position":[[21,7]]},"3744":{"position":[[172,7]]},"4738":{"position":[[106,7]]}}}],["port",{"_index":1917,"t":{"293":{"position":[[726,6],[784,5]]},"557":{"position":[[1260,4]]},"753":{"position":[[79,4],[139,4]]},"846":{"position":[[474,4]]},"914":{"position":[[2737,7],[4063,7],[5389,7]]},"932":{"position":[[1054,4],[1356,4],[3413,4],[3545,4]]},"938":{"position":[[1910,5]]},"957":{"position":[[143,4]]},"961":{"position":[[857,4],[1116,4]]},"967":{"position":[[390,5],[418,5]]},"978":{"position":[[837,4]]},"995":{"position":[[124,4],[953,4],[1046,4],[1139,4],[1232,4]]},"1040":{"position":[[804,4]]},"1042":{"position":[[1075,4]]},"1048":{"position":[[113,5]]},"1105":{"position":[[688,4]]},"1107":{"position":[[555,4]]},"1109":{"position":[[294,4]]},"1111":{"position":[[402,4]]},"1113":{"position":[[456,4]]},"1181":{"position":[[179,4]]},"1195":{"position":[[205,6]]},"1197":{"position":[[228,4],[381,4],[534,4],[687,4]]},"1199":{"position":[[455,5]]},"1230":{"position":[[420,4]]},"1261":{"position":[[237,4]]},"1297":{"position":[[1181,5]]},"1405":{"position":[[1357,4],[1460,4]]},"1407":{"position":[[2463,5]]},"1457":{"position":[[3635,4]]},"1501":{"position":[[1550,4]]},"1702":{"position":[[323,4],[437,4],[481,4],[595,4],[640,4],[693,4],[722,4]]},"1704":{"position":[[620,4],[690,4],[722,4],[786,4],[818,4],[882,4],[914,4]]},"1711":{"position":[[1163,5]]},"1798":{"position":[[2737,7],[4063,7],[5389,7]]},"1823":{"position":[[1054,4],[1356,4],[3413,4],[3545,4]]},"1829":{"position":[[1910,5]]},"1848":{"position":[[143,4]]},"1852":{"position":[[857,4],[1116,4]]},"1858":{"position":[[390,5],[418,5]]},"1869":{"position":[[837,4]]},"1886":{"position":[[124,4],[953,4],[1046,4],[1139,4],[1232,4]]},"2048":{"position":[[1540,6],[2725,4]]},"2117":{"position":[[267,5],[324,4]]},"2155":{"position":[[1108,5]]},"2180":{"position":[[300,5]]},"2283":{"position":[[180,4],[257,4],[546,4],[822,5]]},"2285":{"position":[[603,4]]},"2287":{"position":[[314,4],[764,4]]},"2291":{"position":[[81,5]]},"2293":{"position":[[462,6],[626,4],[797,4],[971,4]]},"2295":{"position":[[90,7]]},"2297":{"position":[[180,4],[257,4],[546,4],[822,5]]},"2299":{"position":[[603,4]]},"2301":{"position":[[314,4],[764,4]]},"2305":{"position":[[81,5]]},"2307":{"position":[[462,6],[626,4],[797,4],[971,4]]},"2309":{"position":[[90,7]]},"2482":{"position":[[378,5]]},"2489":{"position":[[1444,5]]},"2499":{"position":[[215,5]]},"2503":{"position":[[412,6]]},"2506":{"position":[[235,4]]},"2508":{"position":[[334,5]]},"2512":{"position":[[102,6],[184,5],[778,5]]},"2516":{"position":[[133,6]]},"2518":{"position":[[355,6]]},"2549":{"position":[[26,4],[71,5],[254,4],[471,4],[509,4],[555,6]]},"2649":{"position":[[3036,5]]},"2714":{"position":[[339,4]]},"2718":{"position":[[613,4],[739,4],[769,4]]},"2740":{"position":[[1033,5]]},"2743":{"position":[[101,4],[143,5]]},"2756":{"position":[[1221,4],[1276,5],[1287,4],[1368,4],[1414,4],[1482,5],[1604,5],[1617,4],[1700,5],[1713,4],[1879,4],[1950,4]]},"2869":{"position":[[57,6],[72,4]]},"2873":{"position":[[196,4],[281,4]]},"2885":{"position":[[123,4]]},"2956":{"position":[[1054,4],[1356,4],[3413,4],[3545,4]]},"2962":{"position":[[1910,5]]},"2981":{"position":[[143,4]]},"2985":{"position":[[857,4],[1116,4]]},"2991":{"position":[[390,5],[418,5]]},"3002":{"position":[[837,4]]},"3036":{"position":[[7610,9],[8169,6]]},"3230":{"position":[[725,5]]},"3264":{"position":[[233,5],[639,5]]},"3978":{"position":[[84,5]]},"3980":{"position":[[58,5]]},"3984":{"position":[[870,4],[1278,4]]},"3988":{"position":[[524,4]]},"4037":{"position":[[188,4]]},"4043":{"position":[[556,5]]},"4045":{"position":[[673,4],[1346,4],[1446,5],[1577,4]]},"4047":{"position":[[681,6]]},"4051":{"position":[[421,4]]},"4222":{"position":[[2335,5]]},"4226":{"position":[[1140,6]]},"4304":{"position":[[2182,4]]},"4327":{"position":[[376,4]]},"4535":{"position":[[2750,5]]},"4537":{"position":[[42,5],[84,5],[277,5],[356,5],[567,4],[817,5],[924,5],[1354,4],[1387,5]]},"4539":{"position":[[369,4]]},"4541":{"position":[[495,4],[591,4],[688,4],[816,4],[930,6],[942,4],[1038,4]]},"4547":{"position":[[1362,5],[1448,5],[1562,4],[1690,4],[2875,5],[2941,4]]},"4580":{"position":[[202,4]]},"4849":{"position":[[1017,5],[1066,5],[1109,5],[1189,5]]},"4853":{"position":[[451,5]]}}}],["port(",{"_index":3042,"t":{"692":{"position":[[235,7]]},"747":{"position":[[154,7]]},"2283":{"position":[[394,7]]},"2297":{"position":[[394,7]]}}}],["port/socket",{"_index":11482,"t":{"4327":{"position":[[771,11]]}}}],["port=5432",{"_index":9158,"t":{"2798":{"position":[[208,9]]},"2800":{"position":[[199,9]]}}}],["port>://.servic",{"_index":6598,"t":{"1646":{"position":[[808,22]]},"1648":{"position":[[1744,22]]}}}],["radosgw_address",{"_index":4610,"t":{"1169":{"position":[[1664,15],[1888,16]]},"1226":{"position":[[5340,16]]}}}],["radoslib",{"_index":6290,"t":{"1486":{"position":[[467,8]]},"1491":{"position":[[309,8]]},"1493":{"position":[[134,8],[190,8]]}}}],["radowsgw_interfac",{"_index":4609,"t":{"1169":{"position":[[1642,18],[1744,18]]}}}],["raft",{"_index":4364,"t":{"1028":{"position":[[373,4]]},"1105":{"position":[[442,4]]}}}],["raid",{"_index":3356,"t":{"852":{"position":[[185,5],[275,4]]},"1040":{"position":[[778,4]]},"1042":{"position":[[816,4]]},"1385":{"position":[[472,4]]},"1466":{"position":[[1461,4],[1512,5],[1601,6]]},"3928":{"position":[[5192,4]]}}}],["rais",{"_index":1255,"t":{"179":{"position":[[1406,5]]},"199":{"position":[[956,5]]},"295":{"position":[[1481,7]]},"305":{"position":[[622,5]]},"345":{"position":[[44,5]]},"1633":{"position":[[45,6]]},"1964":{"position":[[45,6]]},"3549":{"position":[[1257,6]]},"3973":{"position":[[662,6]]}}}],["ralli",{"_index":9354,"t":{"3016":{"position":[[454,6]]},"3086":{"position":[[658,6]]}}}],["ram",{"_index":90,"t":{"12":{"position":[[121,4]]},"15":{"position":[[119,4]]},"824":{"position":[[491,3]]},"867":{"position":[[87,3]]},"894":{"position":[[2370,3]]},"898":{"position":[[246,3]]},"914":{"position":[[2636,6],[3949,6],[5285,6]]},"1005":{"position":[[2322,4]]},"1040":{"position":[[743,3]]},"1042":{"position":[[781,3]]},"1301":{"position":[[1482,3]]},"1375":{"position":[[251,3]]},"1468":{"position":[[540,3]]},"1752":{"position":[[2370,3]]},"1756":{"position":[[246,3]]},"1768":{"position":[[87,3]]},"1798":{"position":[[2636,6],[3949,6],[5285,6]]},"1896":{"position":[[2322,4]]},"2013":{"position":[[5,3]]},"2019":{"position":[[5,3]]},"2021":{"position":[[363,3]]},"2027":{"position":[[312,3]]},"2180":{"position":[[152,3]]},"2252":{"position":[[273,4]]},"2321":{"position":[[272,3]]},"2388":{"position":[[272,3]]},"2692":{"position":[[1040,4]]},"3402":{"position":[[203,4]]},"3418":{"position":[[262,4]]},"3653":{"position":[[649,4]]},"3656":{"position":[[198,3]]},"3675":{"position":[[63,4],[156,4],[227,3],[317,4],[447,4],[504,4]]},"3677":{"position":[[877,3],[1239,4]]},"3679":{"position":[[527,3],[933,3]]},"3690":{"position":[[548,4],[1199,4]]},"3693":{"position":[[257,3]]},"3695":{"position":[[425,3]]},"3704":{"position":[[465,4],[543,4],[840,3]]},"3720":{"position":[[63,4],[156,4],[227,3],[320,4],[450,4],[507,4]]},"3747":{"position":[[198,3]]},"3777":{"position":[[649,4],[1300,4]]},"3780":{"position":[[257,3]]},"3782":{"position":[[425,3]]},"3791":{"position":[[899,3],[1262,4]]},"3793":{"position":[[530,3],[1123,3]]},"3795":{"position":[[731,4]]},"3813":{"position":[[63,4],[156,4],[227,3],[317,4],[447,4],[504,4]]},"3898":{"position":[[33,3]]},"3900":{"position":[[33,3]]},"3902":{"position":[[58,4]]},"3904":{"position":[[302,3],[793,4]]},"3928":{"position":[[846,3]]},"3930":{"position":[[843,3]]},"3941":{"position":[[1186,3]]},"4107":{"position":[[564,3]]},"4109":{"position":[[1126,3]]},"4133":{"position":[[555,3]]},"4135":{"position":[[172,3]]},"4726":{"position":[[262,4]]},"4733":{"position":[[615,4],[905,4]]},"4738":{"position":[[752,3]]}}}],["ram[gib",{"_index":10304,"t":{"3658":{"position":[[18,8]]},"3695":{"position":[[21,8]]},"3782":{"position":[[21,8]]}}}],["ran",{"_index":8931,"t":{"2703":{"position":[[536,3]]},"4481":{"position":[[723,3]]}}}],["rancher",{"_index":3445,"t":{"873":{"position":[[605,7]]},"1774":{"position":[[605,7]]},"4479":{"position":[[1584,7]]}}}],["rancher/k3s:v1.28.8",{"_index":8715,"t":{"2612":{"position":[[52,19]]}}}],["ranchero",{"_index":3444,"t":{"873":{"position":[[574,9],[1161,9],[1177,9],[1193,9],[1289,9]]},"1774":{"position":[[574,9],[1161,9],[1177,9],[1193,9],[1289,9]]}}}],["random",{"_index":3609,"t":{"906":{"position":[[331,6]]},"912":{"position":[[1300,7],[3087,6],[3620,6],[3636,6]]},"1790":{"position":[[331,6]]},"1796":{"position":[[1300,7],[3087,6],[3620,6],[3636,6]]},"2048":{"position":[[2252,7]]},"3693":{"position":[[558,6]]},"3757":{"position":[[130,10]]},"3761":{"position":[[79,10],[562,6],[1167,6]]},"3780":{"position":[[558,6]]},"4863":{"position":[[374,6]]}}}],["randread",{"_index":6622,"t":{"1650":{"position":[[174,10]]},"1975":{"position":[[174,10]]}}}],["randwrit",{"_index":6621,"t":{"1650":{"position":[[155,11]]},"1975":{"position":[[155,11]]}}}],["rang",{"_index":1497,"t":{"199":{"position":[[2859,5]]},"295":{"position":[[1161,7],[1224,5]]},"370":{"position":[[379,5]]},"533":{"position":[[208,5]]},"772":{"position":[[57,5],[194,5]]},"932":{"position":[[763,5]]},"1067":{"position":[[1053,5]]},"1189":{"position":[[341,5]]},"1230":{"position":[[51,5]]},"1373":{"position":[[222,6],[518,5],[744,5]]},"1823":{"position":[[763,5]]},"2037":{"position":[[1182,6]]},"2285":{"position":[[679,7]]},"2299":{"position":[[679,7]]},"2482":{"position":[[613,5]]},"2549":{"position":[[100,6],[437,7],[476,7],[514,6]]},"2553":{"position":[[207,5]]},"2555":{"position":[[175,5]]},"2557":{"position":[[521,5]]},"2686":{"position":[[311,5]]},"2690":{"position":[[305,5]]},"2718":{"position":[[756,5],[863,5]]},"2956":{"position":[[763,5]]},"3153":{"position":[[1529,7]]},"3185":{"position":[[1059,7]]},"3248":{"position":[[17,5]]},"3361":{"position":[[328,5]]},"3519":{"position":[[57,5],[191,5]]},"3582":{"position":[[57,5],[194,5]]},"3611":{"position":[[60,5]]},"3621":{"position":[[57,5]]},"3864":{"position":[[57,5],[194,5]]},"3925":{"position":[[1870,5]]},"3928":{"position":[[4272,5]]},"3988":{"position":[[516,5],[529,5]]},"4051":{"position":[[413,5],[426,5]]},"4410":{"position":[[491,5]]},"4543":{"position":[[472,5]]},"4562":{"position":[[32,5],[224,5]]},"4576":{"position":[[122,5]]},"4580":{"position":[[219,7]]},"4691":{"position":[[937,7],[1319,5]]},"4707":{"position":[[161,5],[510,5]]}}}],["range(4",{"_index":803,"t":{"143":{"position":[[370,9]]}}}],["range.respons",{"_index":8852,"t":{"2682":{"position":[[160,14],[665,14]]}}}],["range.split",{"_index":8847,"t":{"2682":{"position":[[37,11],[323,11]]}}}],["rank",{"_index":10294,"t":{"3646":{"position":[[32,4]]},"4257":{"position":[[5864,6]]}}}],["rapid",{"_index":2670,"t":{"551":{"position":[[1722,5],[3415,5]]},"2501":{"position":[[224,5]]},"2514":{"position":[[166,5]]},"3712":{"position":[[802,6]]},"3805":{"position":[[579,6]]}}}],["rapidli",{"_index":2672,"t":{"551":{"position":[[1800,7]]}}}],["rapids(p",{"_index":10581,"t":{"3712":{"position":[[915,9]]}}}],["rare",{"_index":1141,"t":{"173":{"position":[[1347,6]]},"1346":{"position":[[921,6]]},"1354":{"position":[[703,4]]},"3706":{"position":[[830,6]]},"3799":{"position":[[830,6]]},"4109":{"position":[[2089,4],[3883,6]]},"4742":{"position":[[561,6]]},"4761":{"position":[[239,6]]}}}],["raspbian",{"_index":3990,"t":{"961":{"position":[[271,8]]},"1852":{"position":[[271,8]]},"2985":{"position":[[271,8]]}}}],["rate",{"_index":2422,"t":{"473":{"position":[[501,4]]},"578":{"position":[[461,4]]},"741":{"position":[[28,4],[121,4],[303,4],[672,4],[1327,4],[1440,4],[1486,4],[1597,4]]},"2482":{"position":[[408,4]]},"4475":{"position":[[264,4]]},"4479":{"position":[[0,4],[723,4],[1592,4],[2271,4]]},"4489":{"position":[[716,4]]},"4497":{"position":[[13,4]]},"4726":{"position":[[603,5]]},"4733":{"position":[[1156,5]]}}}],["ratelimit",{"_index":8825,"t":{"2663":{"position":[[279,14]]},"4479":{"position":[[277,9],[375,9],[1055,9],[1196,9]]},"4489":{"position":[[509,9]]}}}],["rating/bil",{"_index":11265,"t":{"4204":{"position":[[304,14]]}}}],["ratio",{"_index":1595,"t":{"218":{"position":[[390,5]]},"226":{"position":[[103,5]]},"1301":{"position":[[1497,5]]},"3677":{"position":[[179,5]]},"3791":{"position":[[177,5]]}}}],["ration",{"_index":9153,"t":{"2794":{"position":[[171,8]]}}}],["rational",{"_index":10277,"t":{"3606":{"position":[[1229,9]]},"4632":{"position":[[202,10],[1491,10],[2301,10],[2639,10]]},"4736":{"position":[[466,9]]}}}],["raw",{"_index":769,"t":{"141":{"position":[[79,3]]},"305":{"position":[[785,3],[840,3]]},"861":{"position":[[358,4],[520,3],[1028,4],[1199,3],[1325,3]]},"1385":{"position":[[1204,3],[1337,4]]},"1762":{"position":[[358,4],[520,3],[1028,4],[1199,3],[1325,3]]},"2246":{"position":[[39,3],[137,3],[224,3]]},"2248":{"position":[[254,3],[504,3]]},"2250":{"position":[[707,3]]},"2319":{"position":[[217,3]]},"2325":{"position":[[519,3]]},"2360":{"position":[[1035,3],[1877,3]]},"2386":{"position":[[217,3]]},"2392":{"position":[[519,3]]},"2427":{"position":[[1035,3],[1877,3]]},"2684":{"position":[[242,3]]},"3206":{"position":[[776,3]]},"3594":{"position":[[436,3]]},"3596":{"position":[[623,3]]},"3833":{"position":[[1069,3]]},"4113":{"position":[[515,3]]}}}],["raw/direct",{"_index":10954,"t":{"3928":{"position":[[3480,10]]}}}],["ray",{"_index":813,"t":{"143":{"position":[[573,4]]}}}],["rb",{"_index":8408,"t":{"2360":{"position":[[1425,6]]},"2427":{"position":[[1425,6]]}}}],["rbac",{"_index":3708,"t":{"914":{"position":[[3299,4],[3407,4],[4639,4],[4748,4],[5956,4],[6065,4]]},"1798":{"position":[[3299,4],[3407,4],[4639,4],[4748,4],[5956,4],[6065,4]]},"2574":{"position":[[700,4]]},"2602":{"position":[[922,4]]},"3980":{"position":[[196,4],[264,4],[279,4]]},"3986":{"position":[[150,4]]},"3990":{"position":[[12,4],[324,4],[1238,4],[1440,4],[2592,4]]},"3996":{"position":[[107,4]]},"4000":{"position":[[153,4]]},"4002":{"position":[[39,4]]},"4062":{"position":[[93,4]]},"4075":{"position":[[351,4]]},"4081":{"position":[[2128,5]]},"4085":{"position":[[32,4]]},"4089":{"position":[[425,4]]},"4091":{"position":[[7,4]]},"4527":{"position":[[122,4]]},"4539":{"position":[[1115,4],[5490,4],[5523,4],[6103,5],[6226,4]]},"4547":{"position":[[2507,4],[2586,4]]},"4606":{"position":[[85,4],[193,4],[234,4],[277,4],[318,4],[363,4]]},"4614":{"position":[[376,4],[1050,4],[1257,4]]},"4627":{"position":[[336,4]]},"4632":{"position":[[284,4]]},"4660":{"position":[[201,4]]},"4667":{"position":[[13176,4]]},"4669":{"position":[[1283,4]]},"4671":{"position":[[82,4]]}}}],["rbac.authorization.k8s.io",{"_index":8688,"t":{"2602":{"position":[[1325,25]]}}}],["rbac.authorization.k8s.io/v1",{"_index":8680,"t":{"2602":{"position":[[969,28],[1211,28]]}}}],["rbac1",{"_index":11164,"t":{"4081":{"position":[[1837,6]]}}}],["rbac_polici",{"_index":3698,"t":{"914":{"position":[[2748,14],[4076,14],[5401,14]]},"1798":{"position":[[2748,14],[4076,14],[5401,14]]}}}],["rbacpolici",{"_index":4151,"t":{"995":{"position":[[402,10],[1992,10],[2091,10]]},"1886":{"position":[[402,10],[1992,10],[2091,10]]}}}],["rbd",{"_index":773,"t":{"141":{"position":[[149,4]]},"861":{"position":[[590,4]]},"1171":{"position":[[332,5]]},"1173":{"position":[[170,4],[189,3]]},"1191":{"position":[[101,4],[677,4],[702,3],[957,3],[1068,3],[1114,4],[1119,3],[1191,3],[1217,3],[1318,3]]},"1385":{"position":[[1394,3]]},"1405":{"position":[[795,3],[811,3]]},"1633":{"position":[[186,3],[231,4]]},"1762":{"position":[[590,4]]},"1964":{"position":[[186,3],[231,4]]}}}],["rbdmap.servic",{"_index":4948,"t":{"1191":{"position":[[1551,14]]}}}],["rbdmirror_group_nam",{"_index":4847,"t":{"1185":{"position":[[1579,21]]}}}],["rc",{"_index":393,"t":{"37":{"position":[[1509,2]]},"701":{"position":[[376,2],[469,2]]},"932":{"position":[[3180,3],[3189,3]]},"1314":{"position":[[544,2],[941,2]]},"1823":{"position":[[3180,3],[3189,3]]},"2110":{"position":[[3974,5]]},"2956":{"position":[[3180,3],[3189,3]]}}}],["rc=0",{"_index":3790,"t":{"932":{"position":[[2857,4]]},"1669":{"position":[[205,4]]},"1823":{"position":[[2857,4]]},"2956":{"position":[[2857,4]]}}}],["rc=1",{"_index":3795,"t":{"932":{"position":[[3070,5]]},"1823":{"position":[[3070,5]]},"2956":{"position":[[3070,5]]}}}],["rc=2",{"_index":3797,"t":{"932":{"position":[[3131,5]]},"1823":{"position":[[3131,5]]},"2956":{"position":[[3131,5]]}}}],["rdbm",{"_index":6216,"t":{"1455":{"position":[[1598,5]]}}}],["rdna1=1",{"_index":10412,"t":{"3673":{"position":[[823,8]]},"3714":{"position":[[783,8]]},"3807":{"position":[[471,8]]}}}],["rdna2=2",{"_index":10413,"t":{"3673":{"position":[[832,9]]},"3807":{"position":[[480,8]]}}}],["rdna3=3",{"_index":10818,"t":{"3807":{"position":[[489,8]]}}}],["rdrand",{"_index":10793,"t":{"3761":{"position":[[442,6]]},"3772":{"position":[[93,6]]}}}],["rdrand/rdse",{"_index":10877,"t":{"3850":{"position":[[45,13]]}}}],["rdseed",{"_index":10792,"t":{"3761":{"position":[[432,6]]},"3772":{"position":[[83,6]]}}}],["re",{"_index":2140,"t":{"364":{"position":[[933,2]]},"423":{"position":[[1146,2]]},"528":{"position":[[512,2]]},"653":{"position":[[667,2]]},"938":{"position":[[2811,2]]},"1175":{"position":[[4471,2]]},"1238":{"position":[[534,2]]},"1688":{"position":[[80,2]]},"1709":{"position":[[291,2]]},"1829":{"position":[[2811,2]]},"2184":{"position":[[4457,2]]},"2347":{"position":[[46,2]]},"2414":{"position":[[46,2]]},"2934":{"position":[[368,2]]},"2962":{"position":[[2811,2]]},"3352":{"position":[[890,2],[921,2]]},"3984":{"position":[[356,2]]},"4163":{"position":[[6016,2]]},"4539":{"position":[[3508,2]]},"4591":{"position":[[374,2]]},"4614":{"position":[[0,2]]},"4632":{"position":[[812,2]]},"4801":{"position":[[181,2]]}}}],["reach",{"_index":1792,"t":{"258":{"position":[[428,8]]},"275":{"position":[[346,5]]},"427":{"position":[[710,5]]},"444":{"position":[[151,5]]},"1226":{"position":[[1659,7],[4267,7]]},"1346":{"position":[[1025,7]]},"1443":{"position":[[77,5]]},"1497":{"position":[[573,5]]},"2048":{"position":[[282,5],[372,7]]},"2199":{"position":[[1030,7]]},"2339":{"position":[[816,7],[1015,7]]},"2355":{"position":[[2890,7]]},"2406":{"position":[[816,7],[1015,7]]},"2422":{"position":[[2890,7]]},"2718":{"position":[[576,7],[666,5]]},"3052":{"position":[[247,7]]},"3223":{"position":[[72,7]]},"3352":{"position":[[807,8]]},"3724":{"position":[[126,8]]},"3817":{"position":[[126,8]]},"3943":{"position":[[410,7]]},"4100":{"position":[[445,5],[483,6]]},"4163":{"position":[[4304,7]]},"4222":{"position":[[3373,7]]},"4226":{"position":[[109,7]]},"4302":{"position":[[3164,8]]},"4310":{"position":[[89,5],[973,5]]},"4539":{"position":[[315,7]]},"4614":{"position":[[356,8]]}}}],["reachabl",{"_index":3747,"t":{"928":{"position":[[125,12],[921,12],[998,12]]},"932":{"position":[[3245,9]]},"1457":{"position":[[3148,9],[3965,9]]},"1819":{"position":[[125,12],[921,12],[998,12]]},"1823":{"position":[[3245,9]]},"2117":{"position":[[1945,9]]},"2879":{"position":[[314,9]]},"2952":{"position":[[125,12],[921,12],[998,12]]},"2956":{"position":[[3245,9]]},"4654":{"position":[[231,9]]},"4662":{"position":[[1803,9]]}}}],["reaction",{"_index":11406,"t":{"4257":{"position":[[5849,8]]}}}],["reactiv",{"_index":3456,"t":{"875":{"position":[[312,13]]},"1776":{"position":[[312,13]]}}}],["read",{"_index":970,"t":{"167":{"position":[[1010,4]]},"187":{"position":[[1117,4]]},"337":{"position":[[538,4],[617,4]]},"368":{"position":[[4109,8]]},"473":{"position":[[579,5]]},"481":{"position":[[359,4]]},"514":{"position":[[1788,4]]},"520":{"position":[[786,4]]},"528":{"position":[[480,5]]},"578":{"position":[[539,5]]},"732":{"position":[[1556,4]]},"738":{"position":[[897,4]]},"739":{"position":[[121,4]]},"834":{"position":[[370,4]]},"934":{"position":[[989,4]]},"963":{"position":[[1426,4]]},"1109":{"position":[[179,4]]},"1224":{"position":[[128,4]]},"1257":{"position":[[15,4],[106,4]]},"1433":{"position":[[154,4]]},"1439":{"position":[[95,4]]},"1470":{"position":[[251,4]]},"1621":{"position":[[174,4]]},"1623":{"position":[[5,4]]},"1637":{"position":[[465,4]]},"1650":{"position":[[167,6]]},"1720":{"position":[[119,4],[1943,4]]},"1825":{"position":[[989,4]]},"1854":{"position":[[1426,4]]},"1952":{"position":[[174,4]]},"1954":{"position":[[5,4]]},"1968":{"position":[[538,4]]},"1975":{"position":[[167,6]]},"2065":{"position":[[924,4]]},"2139":{"position":[[382,4],[728,5],[801,5],[863,5],[893,5]]},"2171":{"position":[[15,4],[106,4]]},"2276":{"position":[[1599,4]]},"2649":{"position":[[992,4]]},"2804":{"position":[[220,4]]},"2918":{"position":[[497,4],[512,4],[817,4],[844,4]]},"2958":{"position":[[989,4]]},"2987":{"position":[[1426,4]]},"3236":{"position":[[270,4]]},"3768":{"position":[[193,4],[278,4]]},"3883":{"position":[[36,4]]},"3906":{"position":[[37,4]]},"4102":{"position":[[1173,4]]},"4535":{"position":[[197,4],[723,4]]},"4537":{"position":[[1127,4],[1491,4]]},"4539":{"position":[[1857,5]]},"4541":{"position":[[406,4]]},"4547":{"position":[[1540,4],[2865,4]]},"4660":{"position":[[349,4]]},"4662":{"position":[[481,4]]},"4709":{"position":[[62,4]]}}}],["read(16",{"_index":7696,"t":{"2139":{"position":[[444,8]]}}}],["read/writ",{"_index":10786,"t":{"3761":{"position":[[97,10]]}}}],["read_bytes_sec",{"_index":7198,"t":{"1720":{"position":[[2972,14]]}}}],["read_bytes_sec_max",{"_index":7201,"t":{"1720":{"position":[[3051,18]]}}}],["read_iops_sec",{"_index":7192,"t":{"1720":{"position":[[2813,13]]}}}],["read_iops_sec='1000",{"_index":7184,"t":{"1720":{"position":[[530,21],[1041,21],[1763,21]]}}}],["read_iops_sec='2000",{"_index":7190,"t":{"1720":{"position":[[2577,21]]}}}],["read_iops_sec=1000",{"_index":7177,"t":{"1720":{"position":[[228,18]]}}}],["read_iops_sec=2000",{"_index":7188,"t":{"1720":{"position":[[2099,18]]}}}],["read_iops_sec_max",{"_index":7195,"t":{"1720":{"position":[[2884,17]]}}}],["readabl",{"_index":1859,"t":{"282":{"position":[[450,11]]},"368":{"position":[[3641,8]]},"934":{"position":[[1649,8]]},"936":{"position":[[368,8]]},"1700":{"position":[[415,12],[567,9]]},"1825":{"position":[[1649,8]]},"1827":{"position":[[368,8]]},"2690":{"position":[[267,8]]},"2723":{"position":[[173,8]]},"2958":{"position":[[1649,8]]},"2960":{"position":[[368,8]]},"3168":{"position":[[192,8]]},"3394":{"position":[[237,8]]},"3414":{"position":[[357,8]]},"3584":{"position":[[281,8]]},"3590":{"position":[[23,8]]},"3611":{"position":[[147,11]]},"3681":{"position":[[489,8]]},"3718":{"position":[[527,8]]},"3811":{"position":[[527,8]]},"3831":{"position":[[299,8]]},"3866":{"position":[[275,8]]}}}],["reader",{"_index":3068,"t":{"696":{"position":[[413,7]]},"2447":{"position":[[667,6]]},"2651":{"position":[[521,6]]},"4081":{"position":[[1444,7]]},"4094":{"position":[[494,7]]},"4100":{"position":[[265,6],[355,6]]},"4102":{"position":[[402,6]]},"4111":{"position":[[108,7]]},"4200":{"position":[[578,7]]},"4277":{"position":[[236,7]]},"4667":{"position":[[13831,8]]}}}],["reader':%(target.role.name)",{"_index":8476,"t":{"2447":{"position":[[774,30]]},"4667":{"position":[[14127,30]]}}}],["readfilesync('./docs.package.json",{"_index":974,"t":{"167":{"position":[[1107,36]]}}}],["readi",{"_index":689,"t":{"109":{"position":[[20,5]]},"245":{"position":[[134,5],[194,5]]},"339":{"position":[[647,5]]},"391":{"position":[[406,6],[534,5]]},"395":{"position":[[156,6]]},"397":{"position":[[178,5]]},"401":{"position":[[383,5]]},"407":{"position":[[69,5]]},"417":{"position":[[546,6]]},"434":{"position":[[1202,5],[1398,6]]},"479":{"position":[[703,5]]},"491":{"position":[[475,6],[688,5],[790,5]]},"493":{"position":[[850,5]]},"496":{"position":[[490,5],[549,5]]},"498":{"position":[[384,5]]},"510":{"position":[[438,6],[488,6]]},"541":{"position":[[381,5]]},"590":{"position":[[66,5]]},"688":{"position":[[88,5]]},"812":{"position":[[535,6]]},"938":{"position":[[748,5]]},"1073":{"position":[[162,5]]},"1175":{"position":[[5330,5]]},"1179":{"position":[[2291,5]]},"1457":{"position":[[633,5],[4200,6]]},"1480":{"position":[[228,6]]},"1829":{"position":[[748,5]]},"2032":{"position":[[1481,5]]},"2034":{"position":[[1568,5]]},"2236":{"position":[[152,6]]},"2553":{"position":[[482,6]]},"2594":{"position":[[144,6]]},"2883":{"position":[[88,5]]},"2898":{"position":[[398,5]]},"2934":{"position":[[777,5]]},"2962":{"position":[[748,5]]},"3022":{"position":[[479,6],[794,5]]},"3052":{"position":[[95,5]]},"3064":{"position":[[270,6]]},"3067":{"position":[[254,5]]},"3086":{"position":[[909,5]]},"3223":{"position":[[675,5]]},"3537":{"position":[[28,5]]},"4539":{"position":[[3760,5]]},"4560":{"position":[[1810,5]]},"4562":{"position":[[1534,5],[3732,5],[4754,5],[6534,6]]},"4726":{"position":[[346,6]]},"4733":{"position":[[989,6]]}}}],["readili",{"_index":10808,"t":{"3763":{"position":[[915,7]]},"4466":{"position":[[36,7]]}}}],["readm",{"_index":984,"t":{"167":{"position":[[1347,6],[1700,6]]},"301":{"position":[[811,7]]},"514":{"position":[[1572,6]]},"3018":{"position":[[9,7]]},"3028":{"position":[[9,6]]},"3225":{"position":[[537,6]]},"3350":{"position":[[56,6]]},"3558":{"position":[[162,6]]},"3742":{"position":[[241,6]]}}}],["readme.md",{"_index":997,"t":{"167":{"position":[[1764,11]]},"924":{"position":[[1771,9]]},"938":{"position":[[530,9],[1200,10]]},"942":{"position":[[3425,9]]},"1815":{"position":[[1771,9]]},"1829":{"position":[[530,9],[1200,10]]},"1833":{"position":[[3425,9]]},"2948":{"position":[[1771,9]]},"2962":{"position":[[530,9],[1200,10]]},"2966":{"position":[[3425,9]]},"4130":{"position":[[589,9]]},"4281":{"position":[[1151,10]]},"4337":{"position":[[612,9]]},"4629":{"position":[[301,9]]}}}],["readonli",{"_index":3155,"t":{"708":{"position":[[18,8],[1328,8]]},"738":{"position":[[1260,10],[1293,8]]},"739":{"position":[[291,8],[879,8],[916,8],[1249,8],[1868,8],[1916,8],[1973,8],[2026,8]]}}}],["readwriteonc",{"_index":10154,"t":{"3474":{"position":[[260,13]]},"4376":{"position":[[554,13]]},"4385":{"position":[[134,13]]},"4401":{"position":[[0,13]]}}}],["real",{"_index":3236,"t":{"741":{"position":[[1345,4]]},"934":{"position":[[523,4]]},"1105":{"position":[[839,4]]},"1107":{"position":[[675,4]]},"1111":{"position":[[162,4]]},"1113":{"position":[[562,4]]},"1375":{"position":[[485,4]]},"1397":{"position":[[125,4]]},"1569":{"position":[[684,4]]},"1637":{"position":[[88,4]]},"1825":{"position":[[523,4]]},"1902":{"position":[[834,4]]},"1968":{"position":[[161,4]]},"2188":{"position":[[97,4]]},"2487":{"position":[[1165,4]]},"2501":{"position":[[37,4]]},"2512":{"position":[[983,4]]},"2714":{"position":[[54,4]]},"2877":{"position":[[153,4]]},"2958":{"position":[[523,4]]},"3014":{"position":[[193,4]]},"3067":{"position":[[755,4]]},"3230":{"position":[[588,4]]},"3302":{"position":[[102,4]]},"3323":{"position":[[209,4]]},"3348":{"position":[[832,4]]},"3381":{"position":[[62,4]]},"3763":{"position":[[485,4]]},"3928":{"position":[[3440,4]]},"4279":{"position":[[1215,4]]},"4431":{"position":[[2281,4]]},"4512":{"position":[[89,4]]},"4514":{"position":[[311,4]]},"4516":{"position":[[257,4],[504,4],[765,5],[1210,4],[1425,4],[1862,4]]},"4518":{"position":[[49,4]]},"4520":{"position":[[447,4],[811,4]]},"4522":{"position":[[742,4],[1084,4],[1586,4]]},"4662":{"position":[[846,4]]}}}],["realis",{"_index":9962,"t":{"3344":{"position":[[842,8],[877,8]]},"3352":{"position":[[2575,8]]}}}],["realist",{"_index":8754,"t":{"2626":{"position":[[1635,9]]},"3928":{"position":[[1558,9]]},"4104":{"position":[[603,9]]},"4516":{"position":[[1721,9]]},"4520":{"position":[[750,9]]},"4522":{"position":[[842,9],[1517,9]]}}}],["realiti",{"_index":8756,"t":{"2626":{"position":[[1739,8]]},"3930":{"position":[[819,7]]}}}],["realiz",{"_index":2326,"t":{"417":{"position":[[1868,7]]},"1257":{"position":[[1601,8]]},"2171":{"position":[[1741,8]]},"3323":{"position":[[337,8]]},"3352":{"position":[[2440,8]]}}}],["realli",{"_index":771,"t":{"141":{"position":[[98,6]]},"163":{"position":[[62,6]]},"861":{"position":[[539,6]]},"914":{"position":[[1590,6]]},"1354":{"position":[[696,6]]},"1571":{"position":[[391,7],[399,6]]},"1603":{"position":[[446,6]]},"1635":{"position":[[130,6],[137,6]]},"1700":{"position":[[37,6]]},"1762":{"position":[[539,6]]},"1798":{"position":[[1590,6]]},"1904":{"position":[[391,7],[399,6]]},"2130":{"position":[[42,6]]},"3022":{"position":[[633,6]]},"3820":{"position":[[94,6]]},"4539":{"position":[[2812,6],[3619,6]]}}}],["realm",{"_index":2062,"t":{"319":{"position":[[1022,5]]},"321":{"position":[[177,6],[399,5],[473,7]]},"2196":{"position":[[864,5],[882,5],[1204,5]]},"2431":{"position":[[570,5],[985,5],[1359,5],[1481,5],[2702,5],[3302,5]]},"2433":{"position":[[112,5],[160,6],[201,7],[249,6],[353,5],[472,5],[523,5],[545,5],[596,5],[639,5],[685,5],[704,6],[760,6],[815,6],[874,6],[1125,6],[1179,6]]},"2576":{"position":[[310,5]]},"3189":{"position":[[185,5]]},"3238":{"position":[[209,5],[307,5],[375,6],[467,5],[498,6]]},"4593":{"position":[[1659,9],[1792,6],[1911,5],[2014,5],[4793,7]]},"4643":{"position":[[2411,6],[2501,5],[2601,5],[2644,6],[2703,6],[2747,5],[2936,5],[2968,5],[3158,5],[3478,5],[3546,5]]}}}],["realtim",{"_index":4360,"t":{"1013":{"position":[[477,8]]},"1054":{"position":[[477,8]]},"1455":{"position":[[1691,8],[1713,8]]}}}],["ream",{"_index":9886,"t":{"3238":{"position":[[521,4]]}}}],["reanim",{"_index":10652,"t":{"3731":{"position":[[1613,10]]}}}],["reason",{"_index":1212,"t":{"177":{"position":[[895,10]]},"179":{"position":[[447,7]]},"284":{"position":[[503,6]]},"319":{"position":[[961,6]]},"434":{"position":[[1006,6],[1212,6]]},"493":{"position":[[654,6],[860,6]]},"518":{"position":[[584,9]]},"549":{"position":[[929,6]]},"816":{"position":[[636,7]]},"846":{"position":[[532,8]]},"926":{"position":[[104,10]]},"928":{"position":[[552,7]]},"938":{"position":[[1307,8]]},"942":{"position":[[3997,6]]},"963":{"position":[[3838,10]]},"1259":{"position":[[41,8]]},"1354":{"position":[[238,7]]},"1637":{"position":[[296,10]]},"1704":{"position":[[1785,7],[2464,7]]},"1709":{"position":[[387,6]]},"1732":{"position":[[437,6]]},"1734":{"position":[[438,6],[1442,6]]},"1817":{"position":[[104,10]]},"1819":{"position":[[552,7]]},"1829":{"position":[[1307,8]]},"1833":{"position":[[3997,6]]},"1854":{"position":[[3838,10]]},"1968":{"position":[[369,10]]},"2429":{"position":[[26,10]]},"2525":{"position":[[795,7]]},"2608":{"position":[[1009,6]]},"2624":{"position":[[471,7]]},"2950":{"position":[[104,10]]},"2952":{"position":[[552,7]]},"2962":{"position":[[1307,8]]},"2966":{"position":[[3997,6]]},"2987":{"position":[[3838,10]]},"3047":{"position":[[247,7],[320,7]]},"3073":{"position":[[299,6]]},"3266":{"position":[[447,7]]},"3308":{"position":[[721,10]]},"3352":{"position":[[938,10],[2329,8]]},"3529":{"position":[[1528,9]]},"3679":{"position":[[1082,6]]},"3690":{"position":[[1299,10]]},"3704":{"position":[[989,6]]},"3722":{"position":[[294,6]]},"3731":{"position":[[2547,7]]},"3777":{"position":[[1400,10]]},"3793":{"position":[[1272,6]]},"3815":{"position":[[158,6]]},"3829":{"position":[[1950,6]]},"3833":{"position":[[403,7]]},"3850":{"position":[[5,10]]},"3857":{"position":[[267,8]]},"3894":{"position":[[1385,8]]},"3910":{"position":[[544,8]]},"3928":{"position":[[2191,10],[4014,6],[4838,8]]},"4081":{"position":[[482,7]]},"4109":{"position":[[3411,7],[3940,6]]},"4182":{"position":[[21,10]]},"4189":{"position":[[99,7]]},"4257":{"position":[[3874,10],[5156,10],[6117,11]]},"4259":{"position":[[208,10],[349,10],[748,10]]},"4261":{"position":[[328,6]]},"4294":{"position":[[376,7]]},"4306":{"position":[[315,7]]},"4342":{"position":[[348,10]]},"4481":{"position":[[186,8]]},"4483":{"position":[[423,7]]},"4504":{"position":[[469,7]]},"4506":{"position":[[921,10]]},"4591":{"position":[[163,10]]},"4593":{"position":[[855,12]]},"4597":{"position":[[445,7],[556,8]]},"4625":{"position":[[264,6]]},"4763":{"position":[[120,10]]},"4784":{"position":[[76,9]]},"4797":{"position":[[551,7]]},"4801":{"position":[[77,8]]}}}],["reason_cod",{"_index":9605,"t":{"3036":{"position":[[10437,12]]}}}],["reasons17",{"_index":11348,"t":{"4226":{"position":[[2901,9]]}}}],["reassign",{"_index":7575,"t":{"2114":{"position":[[276,10]]}}}],["reattach",{"_index":3848,"t":{"938":{"position":[[605,10]]},"1829":{"position":[[605,10]]},"2962":{"position":[[605,10]]}}}],["rebal",{"_index":6536,"t":{"1603":{"position":[[298,9]]}}}],["rebalanc",{"_index":6611,"t":{"1648":{"position":[[1298,11]]},"2139":{"position":[[1409,11]]}}}],["rebas",{"_index":2380,"t":{"440":{"position":[[51,6]]}}}],["reboot",{"_index":5278,"t":{"1266":{"position":[[2576,9]]},"1383":{"position":[[1729,9]]},"1457":{"position":[[2953,6],[2976,6],[3077,6],[3274,9],[3454,8],[3752,6],[3847,6],[3894,6]]},"1474":{"position":[[687,6],[760,6],[945,6]]},"1476":{"position":[[415,6],[449,6]]},"1544":{"position":[[11,6],[36,8],[161,6],[225,6],[299,6],[389,6],[458,6],[490,6]]},"1709":{"position":[[183,6],[219,6],[284,6]]},"1736":{"position":[[481,6]]},"2034":{"position":[[820,8]]},"2165":{"position":[[1186,8]]},"2270":{"position":[[183,6],[222,7],[598,9]]}}}],["reboot_wait=tru",{"_index":6371,"t":{"1544":{"position":[[311,16]]}}}],["rebuild",{"_index":5222,"t":{"1259":{"position":[[1239,7]]},"4163":{"position":[[5733,7],[5971,7]]}}}],["rebuilt",{"_index":3425,"t":{"871":{"position":[[58,7]]},"873":{"position":[[62,8],[198,7]]},"1772":{"position":[[58,7]]},"1774":{"position":[[62,8],[198,7]]},"2155":{"position":[[3295,8]]},"3230":{"position":[[343,7]]},"3285":{"position":[[461,7]]}}}],["recal",{"_index":2243,"t":{"368":{"position":[[7439,6]]}}}],["recap",{"_index":6666,"t":{"1659":{"position":[[478,5]]}}}],["recapitul",{"_index":11380,"t":{"4232":{"position":[[185,12]]}}}],["receiv",{"_index":1060,"t":{"171":{"position":[[395,8]]},"183":{"position":[[107,8]]},"293":{"position":[[307,8]]},"489":{"position":[[155,8]]},"949":{"position":[[300,7]]},"1472":{"position":[[2076,7]]},"1840":{"position":[[300,7]]},"2341":{"position":[[110,8],[236,9]]},"2347":{"position":[[107,9]]},"2351":{"position":[[223,7]]},"2408":{"position":[[110,8],[236,9]]},"2414":{"position":[[107,9]]},"2418":{"position":[[223,7]]},"2604":{"position":[[174,8]]},"2624":{"position":[[764,9]]},"2678":{"position":[[418,8]]},"2712":{"position":[[1340,7]]},"2861":{"position":[[52,7]]},"2973":{"position":[[300,7]]},"3086":{"position":[[688,8]]},"3121":{"position":[[651,7]]},"3153":{"position":[[1052,8]]},"3170":{"position":[[56,7]]},"3191":{"position":[[120,8]]},"3644":{"position":[[124,7]]},"3712":{"position":[[1661,8]]},"3835":{"position":[[1332,7],[1553,7]]},"3990":{"position":[[970,8]]},"4226":{"position":[[3822,9]]},"4249":{"position":[[338,7]]},"4253":{"position":[[358,7],[398,7],[489,7],[645,7],[707,7]]},"4257":{"position":[[2193,9]]},"4547":{"position":[[150,7]]},"4593":{"position":[[4934,7]]},"4730":{"position":[[970,8]]},"4797":{"position":[[192,8]]}}}],["received:\\nssh",{"_index":6237,"t":{"1457":{"position":[[3592,15]]}}}],["receiver.yaml",{"_index":8705,"t":{"2604":{"position":[[314,13],[410,13]]}}}],["receiver_project",{"_index":9476,"t":{"3036":{"position":[[4261,17]]}}}],["receiver_us",{"_index":9478,"t":{"3036":{"position":[[4314,14]]}}}],["recenc",{"_index":9857,"t":{"3206":{"position":[[381,8]]},"4348":{"position":[[52,7]]},"4353":{"position":[[1098,7]]},"4365":{"position":[[155,7]]}}}],["recent",{"_index":1154,"t":{"173":{"position":[[1921,6]]},"423":{"position":[[497,6]]},"2916":{"position":[[222,6]]},"3573":{"position":[[864,6]]},"3744":{"position":[[180,6]]},"3761":{"position":[[204,6]]},"3763":{"position":[[120,6]]},"3850":{"position":[[16,6],[138,6]]},"3857":{"position":[[382,6]]},"4041":{"position":[[1152,6]]},"4257":{"position":[[489,6],[2361,6]]},"4351":{"position":[[124,6]]},"4593":{"position":[[5086,8]]},"4662":{"position":[[1669,6],[1689,6]]},"4667":{"position":[[12657,6]]},"4715":{"position":[[281,6]]}}}],["recheck",{"_index":2141,"t":{"364":{"position":[[963,7]]},"368":{"position":[[7424,7]]}}}],["rechenzentrum",{"_index":10033,"t":{"3367":{"position":[[504,13]]}}}],["recip",{"_index":11507,"t":{"4414":{"position":[[281,8]]}}}],["recipi",{"_index":1055,"t":{"171":{"position":[[94,9],[305,10]]},"179":{"position":[[886,10]]},"949":{"position":[[935,10]]},"1840":{"position":[[935,10]]},"2973":{"position":[[935,10]]}}}],["reciproc",{"_index":1052,"t":{"171":{"position":[[31,10],[523,11]]},"173":{"position":[[1095,10],[1687,10]]},"175":{"position":[[4,11]]}}}],["recit",{"_index":3365,"t":{"861":{"position":[[419,7]]},"1762":{"position":[[419,7]]}}}],["recogn",{"_index":2576,"t":{"522":{"position":[[23,10]]},"2188":{"position":[[637,10]]},"3549":{"position":[[427,9]]},"3606":{"position":[[580,11]]},"3894":{"position":[[30,11]]},"4275":{"position":[[373,11]]},"4516":{"position":[[92,9]]},"4539":{"position":[[569,10]]},"4691":{"position":[[484,10]]}}}],["recognis",{"_index":10297,"t":{"3653":{"position":[[897,13]]}}}],["recogniz",{"_index":10514,"t":{"3690":{"position":[[796,13]]},"3777":{"position":[[897,13]]}}}],["recommend",{"_index":340,"t":{"37":{"position":[[358,9],[799,9],[866,11]]},"130":{"position":[[6,11],[787,11]]},"173":{"position":[[1842,15]]},"216":{"position":[[47,15]]},"255":{"position":[[77,11]]},"282":{"position":[[119,13],[157,13]]},"284":{"position":[[278,16]]},"293":{"position":[[890,11]]},"295":{"position":[[1149,11],[1212,11]]},"368":{"position":[[378,11]]},"473":{"position":[[390,11]]},"500":{"position":[[470,9]]},"578":{"position":[[350,11]]},"692":{"position":[[470,11]]},"739":{"position":[[1208,11]]},"755":{"position":[[484,15]]},"894":{"position":[[781,11],[800,11],[1082,11],[1175,11],[1443,11]]},"896":{"position":[[135,11]]},"930":{"position":[[294,11]]},"938":{"position":[[1731,14]]},"940":{"position":[[1371,9]]},"946":{"position":[[313,11]]},"967":{"position":[[6,11],[243,11]]},"1036":{"position":[[122,11]]},"1040":{"position":[[228,12],[550,15]]},"1042":{"position":[[494,15]]},"1046":{"position":[[153,10],[222,11]]},"1048":{"position":[[4,11]]},"1050":{"position":[[287,11]]},"1052":{"position":[[23,11]]},"1103":{"position":[[441,14]]},"1107":{"position":[[329,11]]},"1109":{"position":[[202,15],[317,9]]},"1118":{"position":[[6,11]]},"1177":{"position":[[3126,11]]},"1185":{"position":[[851,11]]},"1226":{"position":[[6147,12]]},"1244":{"position":[[66,11]]},"1250":{"position":[[657,9]]},"1252":{"position":[[1314,11]]},"1259":{"position":[[1226,12]]},"1324":{"position":[[87,12]]},"1385":{"position":[[221,11],[500,11]]},"1391":{"position":[[618,12]]},"1405":{"position":[[915,11]]},"1457":{"position":[[1417,13],[1796,13],[2875,11],[3000,11]]},"1462":{"position":[[312,11]]},"1466":{"position":[[1436,11],[1469,12],[1629,12],[1652,11],[1993,12]]},"1476":{"position":[[355,12]]},"1484":{"position":[[338,11],[765,12]]},"1497":{"position":[[761,12]]},"1503":{"position":[[551,11]]},"1511":{"position":[[429,11]]},"1525":{"position":[[44,11],[631,11]]},"1549":{"position":[[44,11]]},"1593":{"position":[[1156,11]]},"1661":{"position":[[412,14]]},"1752":{"position":[[781,11],[800,11],[1082,11],[1175,11],[1443,11]]},"1754":{"position":[[135,11]]},"1821":{"position":[[294,11]]},"1829":{"position":[[1731,14]]},"1831":{"position":[[1371,9]]},"1837":{"position":[[313,11]]},"1858":{"position":[[6,11],[243,11]]},"1900":{"position":[[44,11]]},"1936":{"position":[[1156,11]]},"2023":{"position":[[658,11]]},"2034":{"position":[[1291,12]]},"2157":{"position":[[112,11]]},"2163":{"position":[[4248,11]]},"2165":{"position":[[1803,11]]},"2184":{"position":[[3972,11]]},"2196":{"position":[[1311,11]]},"2287":{"position":[[505,11]]},"2301":{"position":[[505,11]]},"2341":{"position":[[579,11]]},"2408":{"position":[[579,11]]},"2451":{"position":[[21,11]]},"2478":{"position":[[1446,11]]},"2480":{"position":[[1354,11]]},"2626":{"position":[[690,12]]},"2649":{"position":[[2253,9]]},"2655":{"position":[[330,9]]},"2661":{"position":[[354,11]]},"2680":{"position":[[19,11]]},"2682":{"position":[[777,15]]},"2684":{"position":[[1141,15],[1312,15]]},"2725":{"position":[[147,11]]},"2754":{"position":[[124,14]]},"2839":{"position":[[122,11]]},"2871":{"position":[[135,12]]},"2896":{"position":[[68,11]]},"2898":{"position":[[335,11]]},"2930":{"position":[[1330,11]]},"2954":{"position":[[294,11]]},"2962":{"position":[[1731,14]]},"2964":{"position":[[1371,9]]},"2970":{"position":[[313,11]]},"2991":{"position":[[6,11],[243,11]]},"3086":{"position":[[764,11]]},"3130":{"position":[[214,12]]},"3132":{"position":[[211,9]]},"3140":{"position":[[91,12]]},"3150":{"position":[[447,11]]},"3206":{"position":[[310,15]]},"3281":{"position":[[184,9]]},"3406":{"position":[[171,10]]},"3414":{"position":[[139,12]]},"3418":{"position":[[45,11],[179,11]]},"3521":{"position":[[91,14]]},"3527":{"position":[[2482,11]]},"3529":{"position":[[453,9],[962,11],[1565,9]]},"3598":{"position":[[1292,12],[2318,11],[2358,11]]},"3663":{"position":[[86,12]]},"3669":{"position":[[516,9],[747,12]]},"3671":{"position":[[503,11]]},"3673":{"position":[[37,11]]},"3710":{"position":[[529,9],[802,12]]},"3712":{"position":[[935,11]]},"3714":{"position":[[1096,11]]},"3731":{"position":[[578,11]]},"3742":{"position":[[865,11]]},"3768":{"position":[[6,11]]},"3770":{"position":[[6,11],[189,11]]},"3803":{"position":[[516,9],[789,12]]},"3805":{"position":[[610,11]]},"3824":{"position":[[166,9]]},"3826":{"position":[[103,9],[357,12],[409,12],[566,11]]},"3829":{"position":[[6,11],[351,11],[2177,9],[4150,9],[4344,14]]},"3831":{"position":[[330,11]]},"3833":{"position":[[140,11],[902,12],[1059,9],[1198,11]]},"3843":{"position":[[178,11]]},"3864":{"position":[[363,12]]},"3866":{"position":[[182,12]]},"3872":{"position":[[129,11],[141,13],[470,12]]},"3874":{"position":[[254,11],[266,13],[633,12]]},"3876":{"position":[[384,11],[951,12]]},"3881":{"position":[[391,11]]},"3883":{"position":[[68,11],[310,11]]},"3894":{"position":[[1553,9],[2257,11]]},"3898":{"position":[[0,11]]},"3900":{"position":[[0,11]]},"3902":{"position":[[232,11],[329,11]]},"3904":{"position":[[751,11]]},"3906":{"position":[[69,11],[351,11]]},"3910":{"position":[[217,16],[375,11],[487,9]]},"3913":{"position":[[101,12]]},"3918":{"position":[[261,11]]},"3925":{"position":[[1820,12]]},"3928":{"position":[[196,11]]},"3936":{"position":[[464,15]]},"3943":{"position":[[618,12]]},"3947":{"position":[[4635,10]]},"3951":{"position":[[60,11],[238,11]]},"3973":{"position":[[10,10]]},"3986":{"position":[[290,11]]},"3992":{"position":[[221,11],[520,9]]},"4015":{"position":[[246,11],[308,11],[664,15]]},"4021":{"position":[[14,10]]},"4028":{"position":[[481,15]]},"4030":{"position":[[124,15]]},"4034":{"position":[[322,11]]},"4079":{"position":[[504,15]]},"4081":{"position":[[0,9],[82,9],[519,14],[1122,10]]},"4124":{"position":[[5,9]]},"4161":{"position":[[147,15],[259,14],[515,15]]},"4163":{"position":[[763,15],[2208,15],[3711,15],[6105,15]]},"4171":{"position":[[589,15]]},"4173":{"position":[[106,15]]},"4185":{"position":[[824,12]]},"4189":{"position":[[82,12]]},"4191":{"position":[[244,12]]},"4298":{"position":[[394,15]]},"4300":{"position":[[350,9]]},"4302":{"position":[[3530,11]]},"4304":{"position":[[768,10]]},"4306":{"position":[[517,15]]},"4308":{"position":[[363,14],[1134,9]]},"4310":{"position":[[1003,16],[1068,9],[1216,11],[1612,15],[2166,15],[2358,15]]},"4313":{"position":[[541,11]]},"4317":{"position":[[30,9],[133,16]]},"4321":{"position":[[437,16]]},"4327":{"position":[[556,11],[738,11]]},"4355":{"position":[[577,11],[1150,11]]},"4359":{"position":[[441,11]]},"4376":{"position":[[14,15]]},"4407":{"position":[[504,11]]},"4422":{"position":[[290,9]]},"4435":{"position":[[1087,11]]},"4448":{"position":[[305,11],[584,11],[685,11],[779,11]]},"4459":{"position":[[310,11],[529,11]]},"4489":{"position":[[651,11],[903,11]]},"4493":{"position":[[51,11],[504,11]]},"4495":{"position":[[247,11]]},"4533":{"position":[[569,11]]},"4535":{"position":[[1630,10],[3455,11]]},"4539":{"position":[[98,12],[1583,10],[6264,11],[6408,12],[6432,11],[6934,11]]},"4541":{"position":[[791,9],[881,10],[1013,11]]},"4543":{"position":[[266,11]]},"4547":{"position":[[755,11],[2576,9],[3303,11],[3891,9]]},"4569":{"position":[[484,16]]},"4580":{"position":[[2494,9]]},"4593":{"position":[[5502,11]]},"4645":{"position":[[0,11]]},"4686":{"position":[[91,14]]},"4730":{"position":[[613,14]]},"4744":{"position":[[435,14]]},"4818":{"position":[[0,11]]},"4872":{"position":[[292,11],[565,11]]},"4879":{"position":[[225,11]]}}}],["reconcil",{"_index":2324,"t":{"417":{"position":[[1824,10]]},"427":{"position":[[299,10],[392,11],[590,9]]},"461":{"position":[[250,10]]},"1175":{"position":[[3195,10],[4515,10]]},"1177":{"position":[[669,10],[1957,10],[4272,10],[5428,10]]},"1179":{"position":[[1074,9],[1109,10],[2147,9],[2182,10]]},"1259":{"position":[[1364,10]]},"2048":{"position":[[2554,10]]},"2059":{"position":[[627,10]]},"2071":{"position":[[2026,10]]},"2155":{"position":[[3310,10]]},"2207":{"position":[[1151,10]]}}}],["reconciled/handl",{"_index":8639,"t":{"2578":{"position":[[269,19]]}}}],["reconciler:latest",{"_index":7766,"t":{"2155":{"position":[[2078,17]]}}}],["reconcili",{"_index":3026,"t":{"688":{"position":[[142,14],[206,14],[274,14],[339,14]]}}}],["reconfigur",{"_index":2057,"t":{"319":{"position":[[834,13]]},"1183":{"position":[[1182,11]]},"1305":{"position":[[656,11],[749,11]]},"1314":{"position":[[210,11]]},"1552":{"position":[[271,11],[299,11]]},"3352":{"position":[[2689,15]]},"4593":{"position":[[2361,12]]}}}],["reconnaiss",{"_index":8601,"t":{"2549":{"position":[[127,14]]}}}],["reconnect",{"_index":1776,"t":{"255":{"position":[[454,12]]},"938":{"position":[[318,10]]},"1829":{"position":[[318,10]]},"2962":{"position":[[318,10]]}}}],["reconsid",{"_index":12001,"t":{"4879":{"position":[[240,10]]}}}],["record",{"_index":1724,"t":{"249":{"position":[[1013,6]]},"692":{"position":[[150,6]]},"747":{"position":[[69,6]]},"924":{"position":[[1240,9]]},"940":{"position":[[1389,7]]},"1297":{"position":[[4,7],[1477,7]]},"1694":{"position":[[389,6],[446,6],[504,6]]},"1815":{"position":[[1240,9]]},"1831":{"position":[[1389,7]]},"2188":{"position":[[132,7]]},"2199":{"position":[[1097,7],[1171,7]]},"2794":{"position":[[197,7]]},"2916":{"position":[[481,7]]},"2948":{"position":[[1240,9]]},"2964":{"position":[[1389,7]]},"3294":{"position":[[192,6]]},"3352":{"position":[[3388,9]]},"3392":{"position":[[110,7]]},"3398":{"position":[[1291,6]]},"3420":{"position":[[62,6]]},"3422":{"position":[[157,6]]},"3424":{"position":[[62,6]]},"3430":{"position":[[62,6]]},"3432":{"position":[[62,6]]},"3442":{"position":[[62,6]]},"3444":{"position":[[62,6]]},"3450":{"position":[[62,6]]},"3460":{"position":[[732,6]]},"3466":{"position":[[62,6]]},"3472":{"position":[[62,6]]},"3484":{"position":[[62,6]]},"3492":{"position":[[62,6]]},"3494":{"position":[[62,6]]},"3504":{"position":[[62,6]]},"3506":{"position":[[62,6]]},"3508":{"position":[[62,6]]},"3510":{"position":[[62,6]]},"3512":{"position":[[62,6]]},"3514":{"position":[[62,6]]},"3525":{"position":[[296,7],[566,7]]},"3527":{"position":[[1816,7]]},"3529":{"position":[[1205,7],[1227,6],[1427,7]]},"3533":{"position":[[1713,6]]},"3554":{"position":[[127,7]]},"3582":{"position":[[1937,6]]},"3584":{"position":[[14,6]]},"3586":{"position":[[157,8]]},"3588":{"position":[[198,9]]},"3594":{"position":[[26,8]]},"3702":{"position":[[847,6]]},"3923":{"position":[[736,6]]},"3941":{"position":[[274,6]]},"4011":{"position":[[62,6]]},"4023":{"position":[[69,6]]},"4032":{"position":[[23,6]]},"4094":{"position":[[309,6],[732,6]]},"4098":{"position":[[150,6]]},"4102":{"position":[[52,6]]},"4107":{"position":[[14,6]]},"4111":{"position":[[60,6]]},"4142":{"position":[[14,6]]},"4144":{"position":[[113,6],[473,6]]},"4185":{"position":[[703,6]]},"4283":{"position":[[889,7]]},"4291":{"position":[[1715,6]]},"4355":{"position":[[546,6]]},"4420":{"position":[[430,6]]},"4429":{"position":[[62,6]]},"4446":{"position":[[83,6]]},"4457":{"position":[[83,6]]},"4543":{"position":[[1653,8]]},"4752":{"position":[[25,8]]},"4771":{"position":[[25,8]]},"4826":{"position":[[1715,6]]},"4872":{"position":[[327,6],[487,7]]}}}],["recov",{"_index":4093,"t":{"973":{"position":[[371,7]]},"1864":{"position":[[371,7]]},"2997":{"position":[[371,7]]},"3928":{"position":[[4438,9]]},"4102":{"position":[[826,7]]},"4104":{"position":[[1055,9]]},"4137":{"position":[[681,10]]},"4139":{"position":[[384,10]]},"4431":{"position":[[2496,7]]}}}],["recover",{"_index":1921,"t":{"293":{"position":[[955,15]]}}}],["recover_after_nod",{"_index":5539,"t":{"1303":{"position":[[983,19],[1807,19]]}}}],["recoveri",{"_index":3090,"t":{"703":{"position":[[155,9]]},"1250":{"position":[[493,8]]},"1557":{"position":[[132,8],[193,8]]},"1559":{"position":[[101,9]]},"1621":{"position":[[29,8],[124,8]]},"1952":{"position":[[29,8],[124,8]]},"3928":{"position":[[629,8],[4238,8]]},"4096":{"position":[[679,8]]},"4100":{"position":[[200,8]]},"4102":{"position":[[190,9],[781,8]]},"4420":{"position":[[1330,8]]}}}],["recreat",{"_index":8344,"t":{"2295":{"position":[[164,9]]},"2309":{"position":[[164,9]]}}}],["recur",{"_index":6286,"t":{"1474":{"position":[[276,9]]},"1476":{"position":[[253,9]]},"2501":{"position":[[595,9],[742,9]]},"2508":{"position":[[588,9]]},"2512":{"position":[[1635,9]]},"2516":{"position":[[567,9]]},"2518":{"position":[[457,9]]}}}],["recurs",{"_index":1005,"t":{"167":{"position":[[1936,10]]},"1303":{"position":[[4443,10],[4535,10],[5080,10],[5172,10]]},"1665":{"position":[[543,8]]}}}],["red",{"_index":1865,"t":{"284":{"position":[[234,4]]},"938":{"position":[[1573,3]]},"963":{"position":[[3632,3]]},"1075":{"position":[[30,3]]},"1077":{"position":[[30,3]]},"1079":{"position":[[14,3]]},"1081":{"position":[[30,3]]},"1829":{"position":[[1573,3]]},"1854":{"position":[[3632,3]]},"2902":{"position":[[148,4]]},"2962":{"position":[[1573,3]]},"2987":{"position":[[3632,3]]},"4560":{"position":[[4281,3],[4309,3]]},"4562":{"position":[[2629,3],[2788,3],[3071,3]]},"4593":{"position":[[125,3],[170,3]]}}}],["redact",{"_index":3955,"t":{"951":{"position":[[404,6]]},"1842":{"position":[[404,6]]},"2975":{"position":[[404,6]]}}}],["redcarpet",{"_index":830,"t":{"143":{"position":[[705,11]]}}}],["redcarpet.new(\"hello",{"_index":831,"t":{"143":{"position":[[728,20]]}}}],["redeploy",{"_index":9718,"t":{"3086":{"position":[[444,10]]}}}],["redfish",{"_index":4436,"t":{"1067":{"position":[[1112,8]]},"1464":{"position":[[251,7]]},"3352":{"position":[[1442,7]]}}}],["redhat",{"_index":4447,"t":{"1073":{"position":[[539,6],[628,6]]},"1312":{"position":[[232,6]]}}}],["redi",{"_index":3030,"t":{"688":{"position":[[299,5]]},"706":{"position":[[560,6],[587,5],[679,5],[769,5]]},"708":{"position":[[108,5],[146,5],[208,6],[304,5],[366,6],[467,5],[528,5],[630,5],[688,6],[1025,5],[1135,5]]},"715":{"position":[[389,5],[505,5],[515,5],[585,5],[727,5],[744,5]]},"739":{"position":[[327,5],[494,5],[834,5]]},"1513":{"position":[[409,5],[1100,5],[1118,5]]},"1688":{"position":[[386,5],[465,5]]},"2155":{"position":[[2718,5],[2792,5]]},"2167":{"position":[[602,5],[628,5],[657,5]]},"2225":{"position":[[298,5]]},"3016":{"position":[[551,6]]}}}],["redirect",{"_index":1894,"t":{"288":{"position":[[711,8]]},"578":{"position":[[181,8]]},"1183":{"position":[[98,8]]},"1698":{"position":[[488,11],[1340,11]]},"2196":{"position":[[300,10],[421,10]]},"2431":{"position":[[1149,8],[2574,8],[2915,8],[3112,8],[3664,8],[3977,10]]},"2433":{"position":[[320,8]]},"2906":{"position":[[443,8]]},"2930":{"position":[[289,10]]},"3238":{"position":[[441,8]]},"4222":{"position":[[3264,8]]}}}],["redirect_uri=http%3a%2f%2flocalhost%3a3000%2flogin",{"_index":9267,"t":{"2908":{"position":[[231,52]]}}}],["redirecturi",{"_index":9193,"t":{"2826":{"position":[[134,11]]}}}],["redirecturl",{"_index":9301,"t":{"2930":{"position":[[259,11]]},"2934":{"position":[[721,11]]}}}],["redis.type.extern",{"_index":3178,"t":{"715":{"position":[[553,20]]}}}],["redis.type.intern",{"_index":3173,"t":{"715":{"position":[[250,20]]}}}],["redis.yaml.gotmpl",{"_index":11911,"t":{"4835":{"position":[[2557,17]]}}}],["redistribut",{"_index":1224,"t":{"179":{"position":[[209,12]]},"181":{"position":[[561,12],[1089,12]]},"249":{"position":[[1155,13]]}}}],["redon",{"_index":7872,"t":{"2184":{"position":[[3046,6]]}}}],["reduc",{"_index":2266,"t":{"378":{"position":[[152,8]]},"778":{"position":[[54,7]]},"782":{"position":[[89,7]]},"949":{"position":[[346,7]]},"978":{"position":[[1951,6]]},"1056":{"position":[[1363,7],[1890,6]]},"1061":{"position":[[893,7],[1046,8]]},"1064":{"position":[[1599,7]]},"1067":{"position":[[628,8]]},"1383":{"position":[[42,7],[124,6]]},"1511":{"position":[[527,7]]},"1513":{"position":[[152,6]]},"1605":{"position":[[442,6]]},"1840":{"position":[[346,7]]},"1869":{"position":[[1951,6]]},"2157":{"position":[[211,7]]},"2221":{"position":[[396,7]]},"2501":{"position":[[309,8]]},"2508":{"position":[[644,6]]},"2512":{"position":[[1027,8]]},"2518":{"position":[[365,6]]},"2572":{"position":[[502,8]]},"2973":{"position":[[346,7]]},"3002":{"position":[[1951,6]]},"3091":{"position":[[412,7]]},"3101":{"position":[[267,7]]},"3460":{"position":[[270,8]]},"3677":{"position":[[969,7]]},"3791":{"position":[[991,7]]},"3984":{"position":[[321,6]]},"4045":{"position":[[867,8]]},"4102":{"position":[[326,6]]},"4109":{"position":[[2348,6],[4611,6],[4676,6]]},"4157":{"position":[[628,6]]},"4224":{"position":[[342,6],[1404,8]]},"4257":{"position":[[382,6]]},"4308":{"position":[[308,7]]},"4420":{"position":[[2120,6]]},"4508":{"position":[[216,8]]},"4522":{"position":[[320,7]]},"4580":{"position":[[3077,6]]},"4587":{"position":[[750,7]]},"4593":{"position":[[4740,7]]},"4691":{"position":[[154,6]]}}}],["redund",{"_index":3283,"t":{"812":{"position":[[416,9]]},"814":{"position":[[280,10]]},"850":{"position":[[88,9]]},"1061":{"position":[[525,10]]},"3352":{"position":[[1918,9]]},"3894":{"position":[[1742,9]]},"3928":{"position":[[25,9],[719,9],[5337,10]]},"4094":{"position":[[19,10],[401,11],[448,10]]},"4098":{"position":[[110,10],[406,10],[820,10]]},"4100":{"position":[[175,10]]},"4102":{"position":[[200,10],[889,10]]},"4104":{"position":[[488,10]]},"4107":{"position":[[891,10],[1281,10],[1344,9]]},"4111":{"position":[[233,11]]},"4133":{"position":[[2032,10]]},"4135":{"position":[[659,10]]},"4153":{"position":[[214,10]]},"4157":{"position":[[0,10],[141,10],[297,9]]},"4159":{"position":[[1489,9]]},"4161":{"position":[[17,10],[95,10],[189,10],[783,10]]},"4163":{"position":[[235,10],[752,10],[1720,10],[2262,10],[3765,10],[4549,10],[4615,10]]},"4167":{"position":[[548,10],[621,10],[714,10],[757,10]]},"4178":{"position":[[383,10],[449,10],[522,10],[707,9]]},"4180":{"position":[[155,10]]},"4220":{"position":[[1678,9]]},"4224":{"position":[[2762,9]]},"4238":{"position":[[361,9],[516,11]]},"4291":{"position":[[290,9]]},"4376":{"position":[[800,9],[876,9],[996,10]]},"4385":{"position":[[365,9],[562,10]]},"4401":{"position":[[328,9],[413,9]]},"4433":{"position":[[49,10],[880,10],[1608,9],[1895,9]]},"4435":{"position":[[188,9],[322,10]]},"4446":{"position":[[341,11]]},"4457":{"position":[[341,11]]}}}],["redundantli",{"_index":3316,"t":{"826":{"position":[[126,12]]},"842":{"position":[[168,11]]}}}],["redwood",{"_index":10588,"t":{"3712":{"position":[[1743,8]]}}}],["reef",{"_index":4559,"t":{"1161":{"position":[[301,4]]},"1393":{"position":[[237,4]]},"1569":{"position":[[292,4]]},"1902":{"position":[[442,4]]},"2137":{"position":[[307,4]]},"2201":{"position":[[163,4],[195,4]]},"2223":{"position":[[140,4]]},"2649":{"position":[[499,4]]},"3221":{"position":[[164,4]]},"3279":{"position":[[165,4]]}}}],["reelect",{"_index":10939,"t":{"3928":{"position":[[1993,10],[2524,10]]}}}],["ref",{"_index":5218,"t":{"1259":{"position":[[797,3]]},"1635":{"position":[[368,3]]},"2132":{"position":[[758,3],[874,3]]},"3598":{"position":[[786,3]]}}}],["refactor",{"_index":1966,"t":{"301":{"position":[[513,10]]}}}],["refer",{"_index":491,"t":{"66":{"position":[[119,5]]},"68":{"position":[[206,5]]},"74":{"position":[[250,9]]},"78":{"position":[[685,9]]},"82":{"position":[[13,9]]},"95":{"position":[[238,9]]},"199":{"position":[[1739,9]]},"282":{"position":[[555,8]]},"337":{"position":[[187,9],[494,9]]},"339":{"position":[[56,9],[429,9],[485,9]]},"368":{"position":[[2877,10],[3534,9]]},"376":{"position":[[531,5]]},"382":{"position":[[297,5],[998,6]]},"397":{"position":[[459,9]]},"411":{"position":[[109,10]]},"446":{"position":[[32,6]]},"461":{"position":[[763,9]]},"463":{"position":[[1410,10]]},"479":{"position":[[57,10]]},"520":{"position":[[544,5]]},"522":{"position":[[202,10]]},"533":{"position":[[48,9]]},"543":{"position":[[1158,9],[2104,10],[2558,10]]},"545":{"position":[[313,6]]},"696":{"position":[[264,10]]},"730":{"position":[[93,6]]},"732":{"position":[[754,5]]},"734":{"position":[[127,5]]},"736":{"position":[[53,5]]},"741":{"position":[[585,9]]},"743":{"position":[[56,9]]},"786":{"position":[[0,9]]},"788":{"position":[[14,9],[129,9]]},"796":{"position":[[5,6]]},"802":{"position":[[61,9]]},"804":{"position":[[0,5]]},"846":{"position":[[194,6]]},"1025":{"position":[[387,9]]},"1169":{"position":[[1239,10]]},"1218":{"position":[[469,5]]},"1220":{"position":[[836,9]]},"1222":{"position":[[496,10]]},"1257":{"position":[[1046,9]]},"1277":{"position":[[61,9]]},"1279":{"position":[[48,9]]},"1281":{"position":[[73,9]]},"1283":{"position":[[67,9]]},"1287":{"position":[[76,9]]},"1289":{"position":[[40,9]]},"1295":{"position":[[2400,5]]},"1308":{"position":[[36,9]]},"1310":{"position":[[70,9]]},"1318":{"position":[[40,9]]},"1320":{"position":[[40,9]]},"1322":{"position":[[44,9]]},"1327":{"position":[[67,9]]},"1329":{"position":[[70,9],[223,9]]},"1331":{"position":[[245,10]]},"1333":{"position":[[76,9]]},"1335":{"position":[[70,9]]},"1338":{"position":[[32,9]]},"1340":{"position":[[58,9]]},"1356":{"position":[[61,9]]},"1369":{"position":[[132,5]]},"1387":{"position":[[379,5]]},"1484":{"position":[[835,5]]},"1503":{"position":[[676,5]]},"1525":{"position":[[756,5]]},"1979":{"position":[[379,5]]},"1996":{"position":[[280,5]]},"2148":{"position":[[379,5]]},"2150":{"position":[[486,5]]},"2152":{"position":[[168,5]]},"2171":{"position":[[1186,9]]},"2175":{"position":[[167,9]]},"2184":{"position":[[854,9]]},"2190":{"position":[[377,10]]},"2211":{"position":[[1295,9]]},"2325":{"position":[[863,10],[906,5]]},"2343":{"position":[[574,9]]},"2353":{"position":[[926,9]]},"2358":{"position":[[665,11]]},"2360":{"position":[[640,9]]},"2366":{"position":[[413,9]]},"2376":{"position":[[264,9]]},"2392":{"position":[[863,10],[906,5]]},"2410":{"position":[[574,9]]},"2420":{"position":[[926,9]]},"2425":{"position":[[665,11]]},"2427":{"position":[[640,9]]},"2435":{"position":[[33,6]]},"2447":{"position":[[805,5]]},"2451":{"position":[[774,10]]},"2478":{"position":[[752,6]]},"2482":{"position":[[651,5]]},"2567":{"position":[[1124,9]]},"2608":{"position":[[1096,6]]},"2612":{"position":[[294,5]]},"2614":{"position":[[270,5]]},"2618":{"position":[[825,9],[987,8],[1043,5],[1284,6],[1495,9]]},"2620":{"position":[[68,9]]},"2630":{"position":[[52,9]]},"2638":{"position":[[68,9]]},"2649":{"position":[[13,9]]},"2655":{"position":[[268,5],[695,5]]},"2661":{"position":[[256,9]]},"2758":{"position":[[287,5]]},"2794":{"position":[[52,9],[260,9],[414,10]]},"2804":{"position":[[323,5]]},"2812":{"position":[[250,12]]},"2814":{"position":[[155,12]]},"2826":{"position":[[77,5]]},"2845":{"position":[[18,9]]},"2889":{"position":[[555,9]]},"2896":{"position":[[28,5]]},"2898":{"position":[[464,5]]},"2914":{"position":[[340,9],[841,9],[1132,9]]},"2918":{"position":[[343,9]]},"2920":{"position":[[43,9]]},"2924":{"position":[[43,9]]},"2936":{"position":[[51,5],[179,5]]},"3103":{"position":[[767,9]]},"3121":{"position":[[284,9],[375,9]]},"3136":{"position":[[767,9]]},"3150":{"position":[[406,9],[753,9]]},"3153":{"position":[[66,9]]},"3157":{"position":[[13,9],[46,5]]},"3159":{"position":[[557,9],[590,5]]},"3162":{"position":[[22,5]]},"3168":{"position":[[716,9]]},"3183":{"position":[[9,9]]},"3189":{"position":[[862,9]]},"3195":{"position":[[13,9],[46,5]]},"3200":{"position":[[22,5]]},"3204":{"position":[[268,5]]},"3206":{"position":[[870,9]]},"3221":{"position":[[9,9]]},"3225":{"position":[[39,9]]},"3230":{"position":[[83,9]]},"3240":{"position":[[13,9],[46,5]]},"3259":{"position":[[252,9]]},"3279":{"position":[[9,9]]},"3281":{"position":[[79,9]]},"3294":{"position":[[1193,9]]},"3300":{"position":[[13,9],[46,5]]},"3308":{"position":[[675,9]]},"3344":{"position":[[70,9]]},"3346":{"position":[[364,9],[810,9]]},"3348":{"position":[[687,9]]},"3350":{"position":[[147,10],[166,6]]},"3352":{"position":[[1085,9],[3916,9]]},"3355":{"position":[[35,10]]},"3502":{"position":[[795,9]]},"3529":{"position":[[1111,10],[1741,10]]},"3533":{"position":[[344,5],[935,6],[2409,5]]},"3537":{"position":[[350,9]]},"3549":{"position":[[800,5],[1074,9]]},"3567":{"position":[[211,11]]},"3573":{"position":[[682,9]]},"3592":{"position":[[1693,9]]},"3600":{"position":[[46,9]]},"3621":{"position":[[126,9]]},"3681":{"position":[[435,5]]},"3685":{"position":[[465,9]]},"3702":{"position":[[829,5]]},"3718":{"position":[[435,5]]},"3735":{"position":[[212,9],[345,5]]},"3811":{"position":[[435,5]]},"3829":{"position":[[728,9]]},"3833":{"position":[[999,10]]},"3923":{"position":[[395,9]]},"3925":{"position":[[320,9]]},"3928":{"position":[[2422,9],[4708,9]]},"3980":{"position":[[146,10]]},"4075":{"position":[[58,9]]},"4100":{"position":[[216,5]]},"4102":{"position":[[598,6]]},"4128":{"position":[[38,9]]},"4142":{"position":[[136,9]]},"4144":{"position":[[12,9],[531,9]]},"4146":{"position":[[1423,9],[1765,9],[2225,9]]},"4148":{"position":[[696,9],[790,9]]},"4157":{"position":[[832,9]]},"4185":{"position":[[8,9]]},"4187":{"position":[[444,9]]},"4200":{"position":[[461,9]]},"4257":{"position":[[1038,9],[1255,9],[1721,9],[6088,5]]},"4266":{"position":[[233,10]]},"4306":{"position":[[343,9]]},"4310":{"position":[[2186,5]]},"4317":{"position":[[158,9]]},"4321":{"position":[[308,5],[358,9]]},"4414":{"position":[[420,9]]},"4431":{"position":[[598,9]]},"4433":{"position":[[580,9]]},"4485":{"position":[[385,9]]},"4533":{"position":[[584,5]]},"4547":{"position":[[210,5]]},"4558":{"position":[[62,9],[388,9]]},"4560":{"position":[[109,9]]},"4564":{"position":[[245,9]]},"4591":{"position":[[535,9]]},"4597":{"position":[[47,9]]},"4604":{"position":[[367,5],[697,5]]},"4616":{"position":[[249,10]]},"4620":{"position":[[126,5]]},"4632":{"position":[[742,11],[1992,11],[2395,11],[2793,11]]},"4643":{"position":[[718,9]]},"4658":{"position":[[302,9],[444,9]]},"4667":{"position":[[13737,9]]},"4674":{"position":[[8,9],[155,9]]},"4676":{"position":[[6,9]]},"4701":{"position":[[298,10],[367,11],[382,9],[490,9]]},"4705":{"position":[[414,9],[457,6]]},"4709":{"position":[[233,9]]},"4724":{"position":[[42,9],[299,9]]},"4793":{"position":[[328,9]]},"4826":{"position":[[3839,9]]},"4839":{"position":[[1828,5]]},"4845":{"position":[[272,9]]},"4861":{"position":[[595,9]]}}}],["referenc",{"_index":2277,"t":{"382":{"position":[[443,10]]},"393":{"position":[[494,11]]},"498":{"position":[[125,10]]},"543":{"position":[[1773,10]]},"668":{"position":[[926,10]]},"2123":{"position":[[1407,11]]},"2327":{"position":[[318,10]]},"2347":{"position":[[146,11]]},"2351":{"position":[[628,10],[745,10],[800,11]]},"2358":{"position":[[216,10]]},"2394":{"position":[[318,10]]},"2414":{"position":[[146,11]]},"2418":{"position":[[628,10],[745,10],[800,11]]},"2425":{"position":[[216,10]]},"2725":{"position":[[1084,10]]},"2814":{"position":[[836,11]]},"3168":{"position":[[341,10]]},"3575":{"position":[[376,10]]},"3598":{"position":[[965,10]]},"3604":{"position":[[612,10]]},"3615":{"position":[[146,10]]},"3829":{"position":[[92,11],[754,10],[1182,10],[3563,12],[4066,11]]},"4023":{"position":[[109,10]]},"4094":{"position":[[390,10]]},"4277":{"position":[[315,10]]},"4420":{"position":[[2078,10]]},"4580":{"position":[[3652,10]]},"4667":{"position":[[12801,10]]},"4691":{"position":[[1010,10],[1136,10]]},"4705":{"position":[[533,10]]}}}],["refin",{"_index":545,"t":{"74":{"position":[[57,8]]},"78":{"position":[[149,6]]},"2025":{"position":[[337,8]]},"2512":{"position":[[1599,6]]},"3055":{"position":[[101,7]]},"4230":{"position":[[4749,10]]}}}],["reflect",{"_index":1078,"t":{"171":{"position":[[1045,8]]},"541":{"position":[[1836,9]]},"549":{"position":[[1380,9]]},"551":{"position":[[853,8],[930,10]]},"1397":{"position":[[297,9]]},"2626":{"position":[[1727,7]]},"2740":{"position":[[579,7]]},"3191":{"position":[[64,10]]},"3357":{"position":[[3865,9]]},"3563":{"position":[[546,7]]},"3669":{"position":[[108,9],[578,7]]},"3673":{"position":[[927,7]]},"3677":{"position":[[1013,8]]},"3710":{"position":[[121,9],[591,7]]},"3714":{"position":[[958,7]]},"3731":{"position":[[2657,9]]},"3791":{"position":[[1035,8]]},"3803":{"position":[[108,9],[578,7]]},"3807":{"position":[[580,7]]},"3829":{"position":[[4466,7]]},"3902":{"position":[[392,10],[507,10]]},"3904":{"position":[[564,8]]},"4435":{"position":[[1225,7]]},"4705":{"position":[[311,7]]}}}],["reformat",{"_index":6522,"t":{"1593":{"position":[[947,8]]},"1936":{"position":[[947,8]]},"2110":{"position":[[332,8],[487,8],[639,8],[793,8],[959,8],[1127,8],[1279,8],[1434,8],[1596,8],[1749,8],[1902,8],[2056,8],[2211,8],[2366,8],[2520,8],[2673,8],[2830,8],[2990,8],[3135,8],[3287,8],[3560,12]]},"2150":{"position":[[173,8]]}}}],["refrain",{"_index":8467,"t":{"2439":{"position":[[730,7]]}}}],["refresh",{"_index":6240,"t":{"1457":{"position":[[3686,7]]},"1711":{"position":[[766,7],[812,7]]},"1713":{"position":[[2447,7],[2483,7],[2529,7]]},"2171":{"position":[[2450,7]]},"2908":{"position":[[476,7]]},"4230":{"position":[[2048,9]]}}}],["refresh_token",{"_index":9274,"t":{"2908":{"position":[[452,16]]}}}],["refriger",{"_index":1697,"t":{"243":{"position":[[265,13]]}}}],["refs/heads/main",{"_index":7668,"t":{"2132":{"position":[[762,15],[878,15]]}}}],["refstack",{"_index":7462,"t":{"2059":{"position":[[1811,9]]},"2184":{"position":[[5898,8]]},"2219":{"position":[[721,8]]},"3016":{"position":[[461,8]]},"3071":{"position":[[401,10]]}}}],["refus",{"_index":1625,"t":{"224":{"position":[[337,8]]},"2142":{"position":[[307,11]]}}}],["regard",{"_index":673,"t":{"99":{"position":[[33,9]]},"117":{"position":[[44,9]]},"123":{"position":[[182,9]]},"275":{"position":[[111,9],[252,9]]},"288":{"position":[[1041,9]]},"423":{"position":[[753,7]]},"446":{"position":[[519,7]]},"706":{"position":[[408,9]]},"1433":{"position":[[367,9]]},"2451":{"position":[[189,9]]},"2574":{"position":[[1285,7]]},"2576":{"position":[[534,9]]},"2578":{"position":[[636,9]]},"2580":{"position":[[746,9]]},"2918":{"position":[[111,9],[240,9]]},"3148":{"position":[[514,7]]},"3164":{"position":[[145,9],[253,9]]},"3348":{"position":[[718,6]]},"3422":{"position":[[53,7]]},"3702":{"position":[[787,9]]},"3857":{"position":[[198,9]]},"3888":{"position":[[68,9]]},"3949":{"position":[[124,9]]},"3956":{"position":[[573,6]]},"3998":{"position":[[105,9]]},"4081":{"position":[[534,9]]},"4104":{"position":[[87,7]]},"4148":{"position":[[300,9]]},"4310":{"position":[[641,9]]},"4340":{"position":[[165,9]]},"4342":{"position":[[295,6]]},"4346":{"position":[[24,9]]},"4353":{"position":[[122,6]]},"4357":{"position":[[14,9]]},"4378":{"position":[[20,9]]},"4403":{"position":[[20,9]]},"4461":{"position":[[78,9]]},"4554":{"position":[[503,6]]},"4608":{"position":[[543,6]]},"4667":{"position":[[14163,9]]}}}],["regardless",{"_index":590,"t":{"78":{"position":[[663,10]]},"194":{"position":[[179,10]]},"199":{"position":[[1586,10]]},"543":{"position":[[2473,10]]},"963":{"position":[[5014,10]]},"1056":{"position":[[1138,10]]},"1064":{"position":[[1383,10]]},"1854":{"position":[[5014,10]]},"2071":{"position":[[2046,10]]},"2339":{"position":[[137,11]]},"2355":{"position":[[1299,10]]},"2358":{"position":[[275,10]]},"2406":{"position":[[137,11]]},"2422":{"position":[[1299,10]]},"2425":{"position":[[275,10]]},"2451":{"position":[[627,10]]},"2987":{"position":[[5014,10]]},"3872":{"position":[[545,10]]},"3874":{"position":[[753,10]]},"4189":{"position":[[263,10]]},"4308":{"position":[[556,10]]},"4525":{"position":[[500,10]]},"4625":{"position":[[160,10]]}}}],["regener",{"_index":4788,"t":{"1179":{"position":[[1126,10]]},"2188":{"position":[[527,11]]}}}],["regex",{"_index":10891,"t":{"3874":{"position":[[107,7]]}}}],["regio",{"_index":7847,"t":{"2178":{"position":[[661,5]]}}}],["regio.cloud",{"_index":3458,"t":{"878":{"position":[[99,12]]},"1779":{"position":[[99,12]]},"2175":{"position":[[141,12]]},"2178":{"position":[[614,11],[643,11],[1010,12]]},"2184":{"position":[[1149,11]]},"2199":{"position":[[397,11]]},"2219":{"position":[[141,12]]},"3367":{"position":[[884,11]]}}}],["regiocloud",{"_index":6298,"t":{"1501":{"position":[[772,10],[946,10],[1120,10]]},"2178":{"position":[[632,10]]},"2184":{"position":[[1271,10],[1478,10],[1530,11],[1576,10],[2040,11],[2061,10],[2341,11],[2427,11],[2448,10],[2696,11]]},"2219":{"position":[[234,10]]}}}],["regiocloud.conf",{"_index":7904,"t":{"2190":{"position":[[774,16]]}}}],["regiocloud/configur",{"_index":5025,"t":{"1220":{"position":[[593,24],[781,24]]}}}],["region",{"_index":3098,"t":{"705":{"position":[[374,6]]},"812":{"position":[[17,6],[304,7],[392,6],[489,7]]},"818":{"position":[[343,8]]},"820":{"position":[[164,7]]},"830":{"position":[[81,7]]},"934":{"position":[[362,6]]},"938":{"position":[[2799,7]]},"1383":{"position":[[412,7]]},"1825":{"position":[[362,6]]},"1829":{"position":[[2799,7]]},"2276":{"position":[[1701,8]]},"2958":{"position":[[362,6]]},"2962":{"position":[[2799,7]]},"3036":{"position":[[11786,7]]},"3071":{"position":[[479,8]]},"3367":{"position":[[623,8],[1054,8]]},"3381":{"position":[[398,6]]},"3384":{"position":[[1001,6]]},"3925":{"position":[[1369,7]]},"4107":{"position":[[682,8]]},"4109":{"position":[[1829,6],[1904,6],[1977,6],[2159,7]]},"4133":{"position":[[1103,6],[1178,6],[1251,6]]},"4163":{"position":[[444,7],[1539,6]]},"4167":{"position":[[828,6]]},"4222":{"position":[[2649,8]]},"4446":{"position":[[1313,8]]},"4457":{"position":[[1313,8]]},"4459":{"position":[[1695,6]]},"4466":{"position":[[145,6]]},"4877":{"position":[[762,7],[1149,7]]}}}],["region'",{"_index":3288,"t":{"814":{"position":[[88,8]]}}}],["region=regionone,enablesharedconfig=tru",{"_index":3105,"t":{"705":{"position":[[953,40]]}}}],["region=regionone,s3forcepathstyle=\"true\",s3url=https://api.gx",{"_index":3104,"t":{"705":{"position":[[835,61],[1801,61]]},"738":{"position":[[733,61]]}}}],["region_nam",{"_index":2862,"t":{"584":{"position":[[354,12]]},"934":{"position":[[348,13]]},"1825":{"position":[[348,13]]},"2276":{"position":[[2449,12],[2920,12]]},"2279":{"position":[[364,14]]},"2281":{"position":[[495,12]]},"2725":{"position":[[1396,12]]},"2958":{"position":[[348,13]]},"3381":{"position":[[385,12]]},"3384":{"position":[[988,12]]}}}],["regional",{"_index":10032,"t":{"3367":{"position":[[493,10]]}}}],["regionon",{"_index":2863,"t":{"584":{"position":[[367,11]]},"2276":{"position":[[2933,9]]}}}],["regist",{"_index":1593,"t":{"218":{"position":[[346,11]]},"224":{"position":[[226,8]]},"264":{"position":[[132,8]]},"520":{"position":[[110,10]]},"1665":{"position":[[592,9]]},"2117":{"position":[[1673,9]]},"2624":{"position":[[187,9]]},"2651":{"position":[[271,8]]},"3673":{"position":[[313,11]]},"3706":{"position":[[1429,8]]},"3722":{"position":[[1329,11]]},"3799":{"position":[[1426,8]]},"3815":{"position":[[1327,11]]},"3829":{"position":[[1754,10]]},"4302":{"position":[[536,10],[663,10],[2327,10]]},"4321":{"position":[[81,10],[231,10]]},"4541":{"position":[[57,9]]},"4730":{"position":[[2135,8]]}}}],["registr",{"_index":1542,"t":{"207":{"position":[[362,12]]},"224":{"position":[[171,13],[244,12]]},"241":{"position":[[227,14]]},"1250":{"position":[[476,12]]},"2178":{"position":[[276,12]]},"2347":{"position":[[948,12]]},"2414":{"position":[[948,12]]},"2441":{"position":[[181,12]]},"3833":{"position":[[1184,13]]}}}],["registri",{"_index":83,"t":{"12":{"position":[[65,8]]},"334":{"position":[[184,8]]},"378":{"position":[[522,8],[590,9]]},"442":{"position":[[395,9]]},"473":{"position":[[103,9],[1010,9],[1369,8]]},"475":{"position":[[257,8]]},"655":{"position":[[336,8],[372,9],[466,9],[664,8],[681,9],[757,8]]},"673":{"position":[[336,8],[372,9],[466,9],[664,8],[681,9],[757,8]]},"696":{"position":[[89,8]]},"706":{"position":[[1485,8],[1622,9],[1767,8],[1929,8],[2010,8],[2136,8]]},"715":{"position":[[57,8]]},"719":{"position":[[102,8]]},"728":{"position":[[98,9]]},"741":{"position":[[81,9]]},"743":{"position":[[103,9]]},"749":{"position":[[62,8]]},"753":{"position":[[113,8],[199,8]]},"755":{"position":[[82,9]]},"2535":{"position":[[137,8]]},"3162":{"position":[[837,8]]},"3185":{"position":[[620,8],[693,8],[740,11]]},"3206":{"position":[[453,8]]},"3281":{"position":[[472,9],[790,9]]},"3357":{"position":[[971,8],[997,8],[1067,8]]},"3468":{"position":[[984,10],[1347,8]]},"4283":{"position":[[663,8]]},"4287":{"position":[[55,9]]},"4289":{"position":[[207,8]]},"4410":{"position":[[12,8],[128,8],[257,10]]},"4414":{"position":[[146,10],[233,10],[310,8],[399,8],[547,8],[634,9]]},"4416":{"position":[[69,8],[118,10]]},"4418":{"position":[[340,8]]},"4420":{"position":[[12,8],[134,8],[343,8],[1105,8],[1465,8],[1592,8],[1676,10],[1721,10],[1839,8],[1906,8],[1991,8],[2342,8],[2734,8],[2848,8]]},"4422":{"position":[[42,8],[264,9],[420,8]]},"4554":{"position":[[12,8],[128,8],[301,13],[334,8]]},"4558":{"position":[[112,8],[193,12],[369,8],[434,9]]},"4560":{"position":[[402,13]]},"4562":{"position":[[63,8],[310,8],[914,12],[1041,8],[1323,8],[1458,8],[2563,8],[4417,10],[5412,8],[6432,8]]},"4564":{"position":[[67,13],[224,8]]},"4566":{"position":[[28,11]]},"4730":{"position":[[2417,8],[2466,8]]},"4826":{"position":[[2971,10],[3364,8]]}}}],["registry.k8s.io",{"_index":9812,"t":{"3166":{"position":[[122,15]]}}}],["registry.scs.commun",{"_index":2436,"t":{"473":{"position":[[1207,22]]},"3193":{"position":[[143,22]]}}}],["registry.scs.community/centr",{"_index":8671,"t":{"2602":{"position":[[258,30]]}}}],["registry.scs.community/kaas/clust",{"_index":2438,"t":{"473":{"position":[[1319,35]]}}}],["registry.scs.community/statu",{"_index":9162,"t":{"2798":{"position":[[275,29]]}}}],["registry.upload_purging.interv",{"_index":3127,"t":{"706":{"position":[[1699,34]]}}}],["registry/registri",{"_index":7496,"t":{"2074":{"position":[[793,19]]}}}],["regress",{"_index":1954,"t":{"301":{"position":[[57,10],[564,10]]}}}],["regul",{"_index":2021,"t":{"309":{"position":[[84,11]]},"3390":{"position":[[883,11]]},"4189":{"position":[[556,11]]},"4362":{"position":[[40,12]]},"4539":{"position":[[5543,10]]},"4614":{"position":[[1228,9]]},"4632":{"position":[[1817,10]]},"4826":{"position":[[1004,11]]}}}],["regular",{"_index":1543,"t":{"207":{"position":[[414,8]]},"266":{"position":[[291,7]]},"293":{"position":[[823,7]]},"696":{"position":[[683,7]]},"871":{"position":[[69,7]]},"978":{"position":[[1596,7]]},"1772":{"position":[[69,7]]},"1869":{"position":[[1596,7]]},"2325":{"position":[[1199,7]]},"2349":{"position":[[59,7]]},"2392":{"position":[[1199,7]]},"2416":{"position":[[59,7]]},"2531":{"position":[[815,7],[1546,7]]},"2555":{"position":[[263,7],[538,7]]},"2596":{"position":[[267,7]]},"3002":{"position":[[1596,7]]},"3176":{"position":[[162,7]]},"3365":{"position":[[147,7]]},"3371":{"position":[[147,7]]},"3573":{"position":[[888,7]]},"3874":{"position":[[115,7],[574,7],[711,7],[816,7]]},"3960":{"position":[[602,7]]},"4249":{"position":[[180,7]]},"4253":{"position":[[436,7]]},"4287":{"position":[[87,7]]},"4304":{"position":[[2166,7]]},"4525":{"position":[[11,7]]},"4535":{"position":[[1711,7]]},"4643":{"position":[[1874,7]]}}}],["regularli",{"_index":1962,"t":{"301":{"position":[[282,9]]},"423":{"position":[[673,9]]},"949":{"position":[[698,10]]},"967":{"position":[[283,9]]},"1523":{"position":[[1203,9]]},"1840":{"position":[[698,10]]},"1858":{"position":[[283,9]]},"2231":{"position":[[939,9]]},"2506":{"position":[[378,9]]},"2549":{"position":[[571,9]]},"2553":{"position":[[572,9]]},"2557":{"position":[[594,9]]},"2559":{"position":[[729,9]]},"2594":{"position":[[222,9]]},"2598":{"position":[[729,9]]},"2973":{"position":[[698,10]]},"2991":{"position":[[283,9]]},"3091":{"position":[[333,9]]},"3829":{"position":[[51,9]]},"4483":{"position":[[26,9]]},"4485":{"position":[[301,9],[1901,10]]},"4491":{"position":[[24,10]]},"4493":{"position":[[34,10]]},"4495":{"position":[[154,10],[275,9]]},"4529":{"position":[[822,9]]},"4547":{"position":[[128,9]]}}}],["regulatori",{"_index":1856,"t":{"280":{"position":[[1584,10]]},"2487":{"position":[[314,10]]},"2499":{"position":[[622,10]]},"2520":{"position":[[714,10]]}}}],["reinstal",{"_index":7310,"t":{"2032":{"position":[[1056,13]]},"2756":{"position":[[2531,9]]}}}],["reinvent",{"_index":8629,"t":{"2572":{"position":[[360,11]]}}}],["reject",{"_index":10183,"t":{"3527":{"position":[[1891,8],[2387,8],[2461,8],[2521,9]]},"3529":{"position":[[823,9]]},"3531":{"position":[[99,9]]},"3541":{"position":[[94,9]]},"3586":{"position":[[60,8]]},"3731":{"position":[[2004,6]]},"4539":{"position":[[1286,6]]},"4541":{"position":[[1246,8]]},"4543":{"position":[[1557,9]]},"4547":{"position":[[3037,8]]}}}],["rejected_at",{"_index":10186,"t":{"3527":{"position":[[2353,11]]}}}],["rekey",{"_index":9976,"t":{"3352":{"position":[[737,8]]}}}],["rel",{"_index":1097,"t":{"173":{"position":[[141,10]]},"258":{"position":[[646,8]]},"514":{"position":[[313,10]]},"1346":{"position":[[910,10]]},"2196":{"position":[[1362,10]]},"3602":{"position":[[368,9]]},"4107":{"position":[[402,10]]},"4861":{"position":[[168,9]]}}}],["relat",{"_index":860,"t":{"151":{"position":[[278,7]]},"360":{"position":[[953,7]]},"459":{"position":[[244,7]]},"496":{"position":[[505,7]]},"659":{"position":[[371,7],[540,7]]},"692":{"position":[[638,7]]},"696":{"position":[[762,7],[898,7]]},"717":{"position":[[17,7]]},"732":{"position":[[767,7]]},"738":{"position":[[228,7]]},"1603":{"position":[[176,8]]},"1665":{"position":[[633,7]]},"2086":{"position":[[279,7]]},"2439":{"position":[[371,8]]},"2478":{"position":[[917,7]]},"2480":{"position":[[251,7]]},"2487":{"position":[[954,7]]},"2527":{"position":[[210,7]]},"2561":{"position":[[122,7]]},"2604":{"position":[[541,7],[616,7]]},"2606":{"position":[[499,7],[553,7]]},"2618":{"position":[[1309,7]]},"2622":{"position":[[117,7]]},"2628":{"position":[[920,7],[1015,7]]},"2636":{"position":[[180,7],[348,7],[449,7],[650,6]]},"2649":{"position":[[894,7],[1001,7]]},"2678":{"position":[[669,7],[794,7]]},"2826":{"position":[[250,7]]},"2902":{"position":[[47,7]]},"3292":{"position":[[337,7]]},"3310":{"position":[[52,7]]},"3344":{"position":[[302,7]]},"3390":{"position":[[118,7]]},"3470":{"position":[[206,7]]},"3529":{"position":[[1079,7],[1122,7],[1709,7],[1752,7]]},"3690":{"position":[[994,7]]},"3777":{"position":[[1095,7]]},"3925":{"position":[[629,10]]},"3980":{"position":[[354,7]]},"4075":{"position":[[121,7]]},"4109":{"position":[[759,8],[2493,8]]},"4133":{"position":[[51,8]]},"4157":{"position":[[1097,8]]},"4163":{"position":[[712,8]]},"4257":{"position":[[1897,7]]},"4302":{"position":[[880,7],[3444,9]]},"4405":{"position":[[44,7]]},"4560":{"position":[[5551,7],[5660,7]]},"4608":{"position":[[147,8]]},"4649":{"position":[[0,7]]},"4699":{"position":[[262,7]]},"4705":{"position":[[22,8]]},"4759":{"position":[[322,8]]},"4788":{"position":[[0,7]]},"4822":{"position":[[0,7]]}}}],["relationship",{"_index":2664,"t":{"551":{"position":[[389,12]]},"3516":{"position":[[261,12]]},"3688":{"position":[[282,12]]},"3775":{"position":[[282,12]]},"3968":{"position":[[2021,13]]},"4539":{"position":[[6160,12]]},"4793":{"position":[[118,13]]}}}],["relax",{"_index":1569,"t":{"214":{"position":[[22,7]]},"226":{"position":[[44,7]]}}}],["relay",{"_index":12006,"t":{"4885":{"position":[[118,5]]}}}],["relay.org",{"_index":11949,"t":{"4849":{"position":[[981,10]]}}}],["releas",{"_index":742,"t":{"130":{"position":[[634,7]]},"171":{"position":[[190,7]]},"175":{"position":[[276,9],[557,9]]},"207":{"position":[[702,9]]},"293":{"position":[[643,8]]},"343":{"position":[[52,8]]},"349":{"position":[[8,7]]},"368":{"position":[[1823,7]]},"382":{"position":[[1046,7]]},"401":{"position":[[1422,8]]},"403":{"position":[[487,8]]},"417":{"position":[[1384,7]]},"438":{"position":[[28,7],[75,7],[125,7],[208,8],[419,9],[508,7]]},"440":{"position":[[72,8],[141,7],[629,7]]},"442":{"position":[[17,7],[81,8],[141,7],[204,7],[243,7],[482,8]]},"446":{"position":[[362,8]]},"450":{"position":[[173,7]]},"452":{"position":[[42,7]]},"459":{"position":[[135,8]]},"461":{"position":[[73,7],[321,7]]},"463":{"position":[[160,7],[337,7],[588,7],[1037,8]]},"473":{"position":[[51,8],[79,8],[266,9],[667,8],[1085,8]]},"475":{"position":[[42,7],[337,9]]},"479":{"position":[[1492,9],[1656,7]]},"485":{"position":[[79,8]]},"487":{"position":[[42,7],[268,7],[354,7],[443,7]]},"489":{"position":[[30,7],[77,7],[196,7],[217,8],[263,7],[306,7],[437,7],[537,7],[619,7],[674,8],[737,9],[747,9],[1120,7],[1213,8],[1364,9]]},"496":{"position":[[82,7],[223,7],[371,7]]},"514":{"position":[[931,7],[1122,8]]},"543":{"position":[[1005,9],[1449,7],[1987,8],[2491,7],[2661,7]]},"549":{"position":[[976,7]]},"578":{"position":[[75,8]]},"580":{"position":[[212,7],[300,7],[529,7],[619,7]]},"593":{"position":[[138,7],[369,8],[534,7]]},"595":{"position":[[142,7],[560,9]]},"597":{"position":[[534,7],[632,7],[699,8],[762,8]]},"600":{"position":[[25,7],[107,7]]},"606":{"position":[[277,7]]},"616":{"position":[[99,8]]},"624":{"position":[[130,7],[158,7],[178,7]]},"628":{"position":[[107,7],[325,7],[609,7],[671,7],[712,7]]},"630":{"position":[[35,7]]},"632":{"position":[[117,7],[210,7],[370,7]]},"634":{"position":[[369,8]]},"636":{"position":[[70,8]]},"641":{"position":[[660,7],[675,8]]},"647":{"position":[[30,8],[126,7]]},"649":{"position":[[39,7]]},"653":{"position":[[32,7],[813,7]]},"664":{"position":[[138,7],[369,8],[516,7]]},"666":{"position":[[660,7],[675,8]]},"671":{"position":[[660,7]]},"679":{"position":[[30,8],[126,7]]},"681":{"position":[[39,7]]},"688":{"position":[[134,7],[198,7],[266,7],[331,7]]},"703":{"position":[[415,7]]},"846":{"position":[[868,8]]},"873":{"position":[[134,7]]},"883":{"position":[[103,7]]},"887":{"position":[[1402,7],[8825,7]]},"1230":{"position":[[152,7],[874,8],[1310,7]]},"1257":{"position":[[24,7],[115,7],[207,7],[583,7],[1193,8]]},"1259":{"position":[[294,7]]},"1324":{"position":[[739,8]]},"1441":{"position":[[70,9]]},"1523":{"position":[[2218,8]]},"1571":{"position":[[17,8],[143,8],[339,8]]},"1774":{"position":[[134,7]]},"1807":{"position":[[103,7]]},"1811":{"position":[[1402,7],[8825,7]]},"1904":{"position":[[17,8],[143,8],[339,8]]},"2025":{"position":[[83,7]]},"2032":{"position":[[200,7],[243,8]]},"2055":{"position":[[24,7],[54,8],[117,8],[271,8],[451,8],[509,8],[589,7]]},"2057":{"position":[[398,7],[544,8],[588,8],[663,9],[738,8],[770,8],[990,7]]},"2059":{"position":[[35,7],[66,8],[79,7],[314,7],[351,7],[383,7],[410,7],[524,7],[904,7],[971,7],[1707,8],[2418,7],[2506,7],[2688,7],[2750,7],[2802,7]]},"2061":{"position":[[26,7]]},"2065":{"position":[[35,7],[698,8],[992,7],[1080,7],[1247,7],[1566,7],[1887,7],[2218,7],[2540,7],[2862,7],[3183,7],[3499,7]]},"2069":{"position":[[17,7]]},"2071":{"position":[[800,7]]},"2074":{"position":[[571,7]]},"2126":{"position":[[76,7]]},"2163":{"position":[[4473,7]]},"2165":{"position":[[902,8]]},"2171":{"position":[[24,7],[115,7],[231,7],[289,7],[329,7],[730,7],[1333,8]]},"2182":{"position":[[210,7]]},"2184":{"position":[[3457,7]]},"2223":{"position":[[40,8]]},"2231":{"position":[[1099,7]]},"2439":{"position":[[929,9]]},"2649":{"position":[[504,7]]},"2758":{"position":[[142,7],[223,7],[558,7]]},"2904":{"position":[[201,8]]},"2940":{"position":[[390,8]]},"3012":{"position":[[0,8]]},"3014":{"position":[[268,7]]},"3016":{"position":[[915,7]]},"3022":{"position":[[177,9],[772,7],[828,9],[1326,9]]},"3024":{"position":[[4,7]]},"3042":{"position":[[0,8]]},"3044":{"position":[[15,7]]},"3062":{"position":[[201,7]]},"3067":{"position":[[961,7]]},"3073":{"position":[[957,8],[997,7],[1158,7]]},"3075":{"position":[[4,7]]},"3079":{"position":[[0,8]]},"3081":{"position":[[15,7]]},"3083":{"position":[[47,9],[121,7],[589,7],[636,7]]},"3088":{"position":[[678,7]]},"3091":{"position":[[202,7]]},"3097":{"position":[[311,7]]},"3105":{"position":[[4,7],[160,7]]},"3112":{"position":[[0,8]]},"3114":{"position":[[15,7]]},"3116":{"position":[[38,9],[112,7],[327,7],[374,7],[420,7]]},"3121":{"position":[[229,7],[1177,7]]},"3124":{"position":[[88,7]]},"3130":{"position":[[377,8],[1110,7]]},"3132":{"position":[[55,7],[271,7]]},"3138":{"position":[[4,7],[160,7]]},"3146":{"position":[[0,8]]},"3148":{"position":[[0,7],[443,9]]},"3150":{"position":[[14,7],[60,7],[546,7],[829,7]]},"3153":{"position":[[657,8]]},"3164":{"position":[[15,7]]},"3172":{"position":[[279,8]]},"3178":{"position":[[0,8]]},"3180":{"position":[[21,8],[30,7]]},"3187":{"position":[[146,8]]},"3202":{"position":[[15,7]]},"3204":{"position":[[316,7]]},"3216":{"position":[[4,7]]},"3218":{"position":[[21,8],[30,7],[112,7]]},"3223":{"position":[[482,8],[999,8],[1060,7]]},"3234":{"position":[[341,8]]},"3246":{"position":[[200,8]]},"3251":{"position":[[216,8]]},"3261":{"position":[[94,7]]},"3266":{"position":[[517,8],[745,7],[845,7]]},"3272":{"position":[[346,7]]},"3274":{"position":[[0,7]]},"3276":{"position":[[36,8],[165,7]]},"3279":{"position":[[342,8],[370,9],[584,7],[640,8],[665,7]]},"3281":{"position":[[447,7],[553,7],[579,9],[658,8],[765,7]]},"3292":{"position":[[20,7],[139,9]]},"3294":{"position":[[104,7],[359,7]]},"3298":{"position":[[611,7]]},"3306":{"position":[[226,8]]},"3308":{"position":[[5,7]]},"3313":{"position":[[559,7],[865,9]]},"3321":{"position":[[286,8]]},"3325":{"position":[[51,7],[62,7],[80,8],[137,7],[150,8]]},"3357":{"position":[[1209,8],[2556,8]]},"3533":{"position":[[3036,8]]},"3535":{"position":[[123,8],[147,7]]},"3549":{"position":[[489,9],[522,8],[862,7]]},"3569":{"position":[[1290,8]]},"3651":{"position":[[34,7]]},"3661":{"position":[[704,8]]},"3688":{"position":[[34,7]]},"3698":{"position":[[814,8]]},"3775":{"position":[[34,7]]},"3785":{"position":[[799,8]]},"3829":{"position":[[1360,8],[4903,8]]},"3831":{"position":[[269,7]]},"3833":{"position":[[117,8]]},"3936":{"position":[[105,8]]},"3968":{"position":[[1674,9],[1860,8]]},"3971":{"position":[[370,7],[425,9],[521,9]]},"4041":{"position":[[1169,9]]},"4043":{"position":[[255,8]]},"4045":{"position":[[17,7],[212,7],[1022,7]]},"4047":{"position":[[176,9]]},"4055":{"position":[[398,7]]},"4057":{"position":[[56,7]]},"4081":{"position":[[1978,8]]},"4249":{"position":[[275,8]]},"4251":{"position":[[118,7],[179,9]]},"4253":{"position":[[406,8],[457,8],[548,8]]},"4257":{"position":[[119,8],[153,7],[367,8],[437,8],[587,8],[644,8],[788,8],[847,9],[935,8],[997,8],[1088,8],[1146,7],[1228,8],[1342,9],[1370,8],[1575,8],[1693,9],[1826,8],[1970,9],[1984,8],[2043,8],[2368,8],[2428,7],[3924,8]]},"4304":{"position":[[1295,7]]},"4340":{"position":[[265,8],[299,7],[321,7],[408,7],[463,7],[482,7],[627,7]]},"4342":{"position":[[134,9]]},"4344":{"position":[[63,7],[132,7]]},"4346":{"position":[[46,9],[128,8]]},"4351":{"position":[[42,7],[137,8],[260,9],[351,8],[725,7],[802,8],[838,8],[951,7],[970,7]]},"4353":{"position":[[72,7],[132,8],[517,9],[570,8]]},"4355":{"position":[[179,9],[260,8],[339,8],[655,8],[1129,8]]},"4357":{"position":[[36,9],[119,8]]},"4359":{"position":[[242,9]]},"4362":{"position":[[496,8]]},"4370":{"position":[[32,7]]},"4535":{"position":[[3430,9]]},"4562":{"position":[[7247,7]]},"4604":{"position":[[568,7],[663,7],[885,9]]},"4620":{"position":[[187,7]]},"4623":{"position":[[437,8]]},"4665":{"position":[[22,7],[275,8],[307,7],[464,7],[519,7]]},"4667":{"position":[[48,8],[230,8],[420,7],[774,8],[12674,9]]}}}],["release.pi",{"_index":7446,"t":{"2057":{"position":[[903,11],[950,10]]}}}],["release/dock",{"_index":2492,"t":{"489":{"position":[[369,15],[403,15]]}}}],["release/get",{"_index":7253,"t":{"1902":{"position":[[77,15]]}}}],["release/openstack",{"_index":2543,"t":{"514":{"position":[[862,18],[897,18],[1331,18],[1363,18]]}}}],["release=6.0.0b",{"_index":7447,"t":{"2057":{"position":[[915,14]]}}}],["release_tag",{"_index":2386,"t":{"440":{"position":[[185,14],[203,14],[546,14]]}}}],["release_tag=/credentials/o",{"_index":3078,"t":{"701":{"position":[[1566,60]]}}}],["scs.sovereignit.cloud:8080",{"_index":445,"t":{"45":{"position":[[169,26]]},"701":{"position":[[2635,26]]},"705":{"position":[[897,26],[1863,26]]},"738":{"position":[[795,26]]}}}],["scs.yaml",{"_index":8707,"t":{"2604":{"position":[[677,8]]},"2606":{"position":[[605,8]]},"2628":{"position":[[1055,8]]},"2636":{"position":[[560,8],[1129,8]]},"2678":{"position":[[833,8]]}}}],["scs/brand.yaml",{"_index":8779,"t":{"2636":{"position":[[105,14]]}}}],["scs/components/autom",{"_index":9922,"t":{"3290":{"position":[[940,24],[1068,24]]},"3357":{"position":[[2238,24]]}}}],["scs/components/centr",{"_index":9917,"t":{"3288":{"position":[[662,22]]}}}],["scs/guides/openstack",{"_index":10003,"t":{"3357":{"position":[[1322,20]]}}}],["scs/issuer.yaml",{"_index":8780,"t":{"2636":{"position":[[137,15]]}}}],["scs/logo.yaml",{"_index":8778,"t":{"2636":{"position":[[74,13]]}}}],["scs/zuul",{"_index":2591,"t":{"528":{"position":[[167,8],[351,8],[570,8],[718,8]]}}}],["scs:aspect1",{"_index":11117,"t":{"4013":{"position":[[422,13]]}}}],["scs:cpu",{"_index":3587,"t":{"894":{"position":[[2261,7]]},"1752":{"position":[[2261,7]]},"3418":{"position":[[328,7]]},"3894":{"position":[[273,7]]},"3902":{"position":[[347,7]]}}}],["scs:disk0",{"_index":3589,"t":{"894":{"position":[[2289,9]]},"1752":{"position":[[2289,9]]},"3902":{"position":[[418,9]]}}}],["scs:diskn",{"_index":10134,"t":{"3418":{"position":[[346,9]]},"3894":{"position":[[579,9]]}}}],["scs:encrypt",{"_index":11122,"t":{"4015":{"position":[[258,17]]},"4026":{"position":[[280,15],[829,15]]},"4030":{"position":[[679,15]]}}}],["scs:name",{"_index":3591,"t":{"894":{"position":[[2311,8],[2339,8]]},"1752":{"position":[[2311,8],[2339,8]]},"3418":{"position":[[315,8]]},"3888":{"position":[[91,8]]},"3894":{"position":[[82,8],[1125,8],[1269,8],[2201,8]]},"3902":{"position":[[213,8],[310,8]]},"3906":{"position":[[597,8]]}}}],["scs:replic",{"_index":11123,"t":{"4015":{"position":[[320,18]]},"4028":{"position":[[554,16]]}}}],["scs](https://github.com/sovereigncloudstack/docs/blob/main/community/cloud",{"_index":10054,"t":{"3378":{"position":[[884,74]]}}}],["scs_dev_project",{"_index":11756,"t":{"4643":{"position":[[1519,15],[1566,15],[1733,15],[1791,15],[1832,15],[2276,15]]}}}],["scs_release_r1",{"_index":9704,"t":{"3075":{"position":[[126,15]]}}}],["scs_release_r2",{"_index":9747,"t":{"3105":{"position":[[126,15]]}}}],["scs_release_r3",{"_index":9770,"t":{"3138":{"position":[[126,15]]}}}],["scshm",{"_index":9925,"t":{"3292":{"position":[[316,5],[404,5]]}}}],["scsi",{"_index":3390,"t":{"865":{"position":[[931,4],[979,4]]},"871":{"position":[[730,4],[757,4]]},"873":{"position":[[726,4],[753,4]]},"887":{"position":[[9242,4],[9290,4]]},"1766":{"position":[[931,4],[979,4]]},"1772":{"position":[[730,4],[757,4]]},"1774":{"position":[[726,4],[753,4]]},"1811":{"position":[[9242,4],[9290,4]]},"2013":{"position":[[18,4],[62,4]]},"2236":{"position":[[336,4]]},"2250":{"position":[[652,4]]},"3826":{"position":[[351,5]]}}}],["scss",{"_index":10136,"t":{"3422":{"position":[[0,4]]}}}],["sd",{"_index":4351,"t":{"1013":{"position":[[75,5]]},"1054":{"position":[[75,5]]},"1421":{"position":[[1805,6]]},"2139":{"position":[[127,2],[236,2],[330,2],[411,2]]},"3357":{"position":[[361,3]]}}}],["sd[b",{"_index":6093,"t":{"1417":{"position":[[129,6]]}}}],["sda",{"_index":4647,"t":{"1175":{"position":[[734,3],[1348,3],[1434,4],[1649,3],[1735,4],[1968,3],[2055,4],[2328,3],[2440,4],[2923,3],[3035,4]]},"1179":{"position":[[103,4],[631,4],[1353,4]]}}}],["sda,snapshot=external,file=/var/lib/libvirt/images/ub2022_cib_boostrap.qcow2",{"_index":7270,"t":{"2005":{"position":[[693,76]]}}}],["sda=imguuid:image:12:tru",{"_index":10488,"t":{"3677":{"position":[[1509,25]]},"3791":{"position":[[1531,25]]},"3904":{"position":[[1062,25]]}}}],["sdb",{"_index":4665,"t":{"1175":{"position":[[3757,4],[3915,4]]},"1177":{"position":[[518,4],[1209,4]]},"1179":{"position":[[159,4],[687,4],[1409,4]]},"1226":{"position":[[5546,4]]},"1421":{"position":[[1463,5]]},"2207":{"position":[[602,4]]}}}],["sdb1",{"_index":4754,"t":{"1177":{"position":[[4129,5],[4709,5]]}}}],["sdb2",{"_index":4755,"t":{"1177":{"position":[[4135,5],[4766,5]]}}}],["sdb3",{"_index":4756,"t":{"1177":{"position":[[4141,5],[4823,5]]}}}],["sdb4",{"_index":4757,"t":{"1177":{"position":[[4147,5],[4880,5]]}}}],["sdc",{"_index":4666,"t":{"1175":{"position":[[3762,4],[3971,4]]},"1177":{"position":[[534,4],[1276,4]]},"1179":{"position":[[457,3],[579,3],[743,4],[1465,4],[1878,4]]},"1226":{"position":[[5553,4]]},"2207":{"position":[[658,4]]}}}],["sdd",{"_index":4697,"t":{"1177":{"position":[[468,4],[530,3],[546,3],[1105,4],[1221,3],[1288,3]]},"1226":{"position":[[5560,4]]},"2207":{"position":[[245,3],[455,3],[714,4]]}}}],["sde",{"_index":5112,"t":{"1226":{"position":[[5567,4]]}}}],["sdf",{"_index":7680,"t":{"2139":{"position":[[17,3],[140,5],[249,5],[343,5],[424,5],[546,4],[937,3]]}}}],["sdk",{"_index":5731,"t":{"1324":{"position":[[7116,3]]},"2709":{"position":[[17,3]]},"3159":{"position":[[161,4]]},"4667":{"position":[[7110,3]]}}}],["sdn",{"_index":4354,"t":{"1013":{"position":[[163,5]]},"1054":{"position":[[163,5]]},"1711":{"position":[[474,3]]},"3255":{"position":[[247,3]]},"3357":{"position":[[482,3]]},"3956":{"position":[[85,3],[141,3]]},"3958":{"position":[[14,3]]},"3960":{"position":[[692,3]]},"3964":{"position":[[52,4]]},"3968":{"position":[[1259,4],[2847,3]]},"3975":{"position":[[9,3]]},"4155":{"position":[[905,3]]},"4163":{"position":[[5983,3]]},"4296":{"position":[[143,3]]},"4302":{"position":[[1095,3],[3414,4]]},"4331":{"position":[[42,3]]}}}],["sea",{"_index":11196,"t":{"4109":{"position":[[2311,4]]}}}],["seagate_st16000nm004j_zr604zdz0000c210pwe9",{"_index":7712,"t":{"2139":{"position":[[1068,42],[1269,42]]}}}],["seamless",{"_index":10021,"t":{"3357":{"position":[[3621,8]]},"3398":{"position":[[252,9]]},"3561":{"position":[[418,8]]},"3573":{"position":[[658,8]]}}}],["seamlessli",{"_index":2269,"t":{"378":{"position":[[377,10]]},"1061":{"position":[[193,10]]},"1067":{"position":[[741,10],[2056,10]]},"2372":{"position":[[493,11]]},"2553":{"position":[[505,10]]},"2559":{"position":[[504,10]]},"2598":{"position":[[504,10]]}}}],["search",{"_index":709,"t":{"119":{"position":[[329,6]]},"632":{"position":[[188,6]]},"1238":{"position":[[252,6]]},"1268":{"position":[[334,7],[565,7]]},"2052":{"position":[[666,6]]},"3556":{"position":[[139,9]]},"3575":{"position":[[906,6]]},"4176":{"position":[[329,6]]}}}],["seat",{"_index":10287,"t":{"3634":{"position":[[36,6],[56,5],[131,5]]}}}],["sec",{"_index":279,"t":{"28":{"position":[[1956,3]]},"3357":{"position":[[2125,3]]}}}],["secgrp",{"_index":3910,"t":{"942":{"position":[[1791,7],[1799,8],[2048,8]]},"1833":{"position":[[1791,7],[1799,8],[2048,8]]},"2966":{"position":[[1791,7],[1799,8],[2048,8]]}}}],["secgrps=$(openstack",{"_index":3908,"t":{"942":{"position":[[1571,19]]},"1833":{"position":[[1571,19]]},"2966":{"position":[[1571,19]]}}}],["second",{"_index":2060,"t":{"319":{"position":[[940,8]]},"323":{"position":[[1538,6]]},"401":{"position":[[666,6]]},"403":{"position":[[538,6]]},"417":{"position":[[1798,7],[1851,7]]},"430":{"position":[[105,7]]},"477":{"position":[[568,7]]},"604":{"position":[[242,6]]},"741":{"position":[[472,7],[1061,6],[1414,6]]},"938":{"position":[[2265,7]]},"951":{"position":[[268,7]]},"978":{"position":[[1178,6],[1628,6],[1724,6],[2260,6]]},"1003":{"position":[[228,9],[388,9]]},"1147":{"position":[[472,7]]},"1189":{"position":[[482,7],[532,6]]},"1252":{"position":[[1554,6],[1717,6],[1859,6]]},"1511":{"position":[[495,6]]},"1652":{"position":[[241,7]]},"1829":{"position":[[2265,7]]},"1842":{"position":[[268,7]]},"1869":{"position":[[1178,6],[1628,6],[1724,6],[2260,6]]},"1894":{"position":[[228,9],[388,9]]},"1977":{"position":[[241,7]]},"2071":{"position":[[372,7]]},"2157":{"position":[[179,6]]},"2431":{"position":[[152,6]]},"2649":{"position":[[816,6]]},"2962":{"position":[[2265,7]]},"2975":{"position":[[268,7]]},"3002":{"position":[[1178,6],[1628,6],[1724,6],[2260,6]]},"3172":{"position":[[310,6]]},"3527":{"position":[[1510,6]]},"3731":{"position":[[2934,6]]},"3768":{"position":[[293,8]]},"3925":{"position":[[1630,8]]},"3947":{"position":[[2082,6]]},"4102":{"position":[[986,6]]},"4126":{"position":[[37,6]]},"4163":{"position":[[1090,6]]},"4230":{"position":[[1058,6]]},"4479":{"position":[[1285,6]]},"4547":{"position":[[2190,6]]},"4660":{"position":[[1384,7]]}}}],["secondari",{"_index":7289,"t":{"2021":{"position":[[98,9]]},"3183":{"position":[[356,9]]},"3673":{"position":[[349,9]]},"4283":{"position":[[870,9]]}}}],["secondli",{"_index":8645,"t":{"2580":{"position":[[181,9]]},"2584":{"position":[[697,9]]},"2586":{"position":[[307,9]]}}}],["secret",{"_index":422,"t":{"39":{"position":[[136,6]]},"354":{"position":[[127,8]]},"368":{"position":[[2234,9],[2531,7],[2640,8],[2669,7],[2735,7],[2787,8],[2801,6],[2870,6],[2892,6],[2970,6],[3351,7],[3363,6],[3427,7],[3489,6],[3548,6],[3619,6],[3694,8],[3726,7],[3921,8],[4360,7],[5174,7],[5247,6],[5402,6],[5476,6],[5552,6],[5632,6],[5966,7],[6029,6],[6090,7],[6222,7],[6321,7],[6513,7],[6762,8],[6808,6],[6865,7],[7520,7],[7860,8],[7940,7]]},"498":{"position":[[118,6]]},"518":{"position":[[675,7],[746,6],[882,6]]},"528":{"position":[[79,6],[134,6],[324,6],[538,6],[696,7],[785,7]]},"555":{"position":[[94,7]]},"557":{"position":[[1822,6],[1901,6]]},"584":{"position":[[156,6]]},"586":{"position":[[1354,6]]},"588":{"position":[[977,7]]},"692":{"position":[[436,7]]},"701":{"position":[[1680,6],[2257,6]]},"705":{"position":[[777,6],[1668,6]]},"738":{"position":[[600,6]]},"747":{"position":[[355,7]]},"887":{"position":[[387,6],[409,6]]},"951":{"position":[[367,7]]},"963":{"position":[[1352,7]]},"1224":{"position":[[565,7],[674,7]]},"1226":{"position":[[363,7],[443,8],[542,7]]},"1238":{"position":[[177,7],[407,7]]},"1407":{"position":[[1132,6]]},"1425":{"position":[[142,6]]},"1472":{"position":[[1854,7]]},"1523":{"position":[[1764,6],[1775,6],[1930,6]]},"1561":{"position":[[1003,6],[1133,7]]},"1811":{"position":[[387,6],[409,6]]},"1842":{"position":[[367,7]]},"1854":{"position":[[1352,7]]},"1909":{"position":[[112,6],[174,6]]},"2025":{"position":[[537,7],[690,7]]},"2119":{"position":[[22,7],[249,7],[371,6]]},"2184":{"position":[[2139,6],[2264,6],[2390,6]]},"2196":{"position":[[2244,6],[3049,6]]},"2319":{"position":[[693,6]]},"2323":{"position":[[212,7]]},"2325":{"position":[[928,7]]},"2341":{"position":[[7,7],[83,6],[152,7],[299,7],[395,6],[508,6],[653,6],[697,6]]},"2343":{"position":[[281,6],[543,7],[567,6],[847,7],[1003,6]]},"2347":{"position":[[36,6],[100,6],[165,6],[223,6],[284,6],[403,6],[483,6],[563,7],[616,6],[751,6],[794,7],[977,6],[1030,6]]},"2351":{"position":[[148,6],[211,6],[296,6],[639,6],[756,6]]},"2360":{"position":[[883,6]]},"2386":{"position":[[693,6]]},"2390":{"position":[[212,7]]},"2392":{"position":[[928,7]]},"2408":{"position":[[7,7],[83,6],[152,7],[299,7],[395,6],[508,6],[653,6],[697,6]]},"2410":{"position":[[281,6],[543,7],[567,6],[847,7],[1003,6]]},"2414":{"position":[[36,6],[100,6],[165,6],[223,6],[284,6],[403,6],[483,6],[563,7],[616,6],[751,6],[794,7],[977,6],[1030,6]]},"2418":{"position":[[148,6],[211,6],[296,6],[639,6],[756,6]]},"2427":{"position":[[883,6]]},"2431":{"position":[[851,7],[2394,6]]},"2480":{"position":[[126,7],[1340,7],[1411,8]]},"2529":{"position":[[972,7]]},"2531":{"position":[[546,6],[585,7]]},"2535":{"position":[[637,8]]},"2569":{"position":[[97,8],[142,7]]},"2602":{"position":[[615,6],[647,6]]},"2636":{"position":[[16,7]]},"2826":{"position":[[39,6],[94,7]]},"2877":{"position":[[4,9],[169,8]]},"2879":{"position":[[488,7]]},"2883":{"position":[[30,8],[63,8],[297,7]]},"2900":{"position":[[194,8],[296,7]]},"2908":{"position":[[193,8],[578,6]]},"2975":{"position":[[367,7]]},"2987":{"position":[[1352,7]]},"3296":{"position":[[1354,7]]},"3352":{"position":[[590,7]]},"3381":{"position":[[1387,7],[1610,6],[1923,7],[2139,6],[2171,7]]},"3384":{"position":[[89,7],[298,8]]},"4081":{"position":[[1656,7]]},"4113":{"position":[[1049,6],[2128,6]]},"4135":{"position":[[315,6]]},"4535":{"position":[[108,8]]},"4726":{"position":[[830,7]]},"4733":{"position":[[1303,8]]},"4857":{"position":[[198,6],[391,6]]},"4877":{"position":[[424,6],[469,6],[856,6],[1243,6]]}}}],["secret'",{"_index":8368,"t":{"2341":{"position":[[271,8]]},"2408":{"position":[[271,8]]}}}],["secret.bash",{"_index":3036,"t":{"690":{"position":[[27,11]]},"692":{"position":[[751,11]]},"694":{"position":[[27,11],[85,11]]}}}],["secret_id",{"_index":8371,"t":{"2341":{"position":[[481,10],[664,11]]},"2351":{"position":[[329,10]]},"2360":{"position":[[853,12],[961,10]]},"2408":{"position":[[481,10],[664,11]]},"2418":{"position":[[329,10]]},"2427":{"position":[[853,12],[961,10]]}}}],["secret_k8s_cluster_api_provid",{"_index":2226,"t":{"368":{"position":[[5738,32]]}}}],["secret_key",{"_index":4031,"t":{"963":{"position":[[1003,10]]},"1854":{"position":[[1003,10]]},"2987":{"position":[[1003,10]]}}}],["secret_nam",{"_index":2744,"t":{"557":{"position":[[1835,11]]},"2347":{"position":[[335,12],[682,12],[1049,12]]},"2414":{"position":[[335,12],[682,12],[1049,12]]}}}],["secret_repository_nam",{"_index":2224,"t":{"368":{"position":[[5589,23],[6527,22],[6873,22]]}}}],["secret_repository_name_foobar",{"_index":2233,"t":{"368":{"position":[[6266,30]]}}}],["secretaccesskeysecretref",{"_index":11998,"t":{"4877":{"position":[[803,25],[1190,25]]}}}],["secretkey",{"_index":3246,"t":{"747":{"position":[[494,11]]}}}],["secretnam",{"_index":2239,"t":{"368":{"position":[[6779,10]]},"4853":{"position":[[290,11]]}}}],["secretname.secretvalue1",{"_index":2246,"t":{"368":{"position":[[7872,23]]}}}],["secretref",{"_index":8676,"t":{"2602":{"position":[[520,10]]}}}],["secrets.bash",{"_index":3055,"t":{"692":{"position":[[675,12]]},"694":{"position":[[51,12]]},"747":{"position":[[395,12]]}}}],["secrets.env",{"_index":9188,"t":{"2824":{"position":[[47,11],[106,11]]},"2826":{"position":[[57,12],[307,11]]}}}],["secrets.gotmpl",{"_index":11865,"t":{"4833":{"position":[[456,14]]}}}],["secrets.yaml",{"_index":8505,"t":{"2480":{"position":[[861,12]]}}}],["secrets.yml",{"_index":4831,"t":{"1185":{"position":[[455,11]]},"1252":{"position":[[577,11]]}}}],["secrets/id_rsa.configuration.pub",{"_index":5079,"t":{"1224":{"position":[[889,32]]}}}],["secrets/vaultpass",{"_index":5081,"t":{"1226":{"position":[[513,18]]},"1238":{"position":[[600,17]]},"1472":{"position":[[1398,17]]}}}],["secrets/vaultpass_backup_.. + + + + +Search the documentation + + + + + + + + + + + + + + + +

Search the documentation

+ + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000000..91a2be8d69 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1 @@ +https://docs.scs.community/blogweekly0.5https://docs.scs.community/blog/archiveweekly0.5https://docs.scs.community/blog/authorsweekly0.5https://docs.scs.community/blog/first-blog-postweekly0.5https://docs.scs.community/blog/tagsweekly0.5https://docs.scs.community/blog/tags/communityweekly0.5https://docs.scs.community/blog/tags/howtoweekly0.5https://docs.scs.community/searchweekly0.5https://docs.scs.community/community/weekly0.5https://docs.scs.community/community/category/contribute-to-docsweekly0.5https://docs.scs.community/community/category/toolsweekly0.5https://docs.scs.community/community/central-services/plusserver-gx-scsweekly0.5https://docs.scs.community/community/cloud-resources/weekly0.5https://docs.scs.community/community/cloud-resources/getting-started-openstackweekly0.5https://docs.scs.community/community/cloud-resources/plusserver-gx-scsweekly0.5https://docs.scs.community/community/cloud-resources/wavestackweekly0.5https://docs.scs.community/community/collaboration/weekly0.5https://docs.scs.community/community/collaboration/sig-central-apiweekly0.5https://docs.scs.community/community/collaboration/sig-communityweekly0.5https://docs.scs.community/community/collaboration/sig-documentationweekly0.5https://docs.scs.community/community/collaboration/sig-monitoringweekly0.5https://docs.scs.community/community/collaboration/sig-standardizationweekly0.5https://docs.scs.community/community/collaboration/team-containerweekly0.5https://docs.scs.community/community/collaboration/team-iaasweekly0.5https://docs.scs.community/community/collaboration/team-iamweekly0.5https://docs.scs.community/community/collaboration/team-opsweekly0.5https://docs.scs.community/community/contribute/adding-docs-guideweekly0.5https://docs.scs.community/community/contribute/doc-files-structure-guideweekly0.5https://docs.scs.community/community/contribute/docs-workflow-explanationweekly0.5https://docs.scs.community/community/contribute/linting-guideweekly0.5https://docs.scs.community/community/contribute/local-docusaurus-development-guideweekly0.5https://docs.scs.community/community/contribute/styleguideweekly0.5https://docs.scs.community/community/contribute/styleguides/ansible_styleguideweekly0.5https://docs.scs.community/community/hackathons/checklistweekly0.5https://docs.scs.community/community/license-considerationsweekly0.5https://docs.scs.community/community/mission-statementweekly0.5https://docs.scs.community/community/tools/github/branchprotectionweekly0.5https://docs.scs.community/community/tools/github/dco-and-licensesweekly0.5https://docs.scs.community/community/tools/github/tips-and-tricksweekly0.5https://docs.scs.community/community/tools/jitsiweekly0.5https://docs.scs.community/community/tools/mailinglistsweekly0.5https://docs.scs.community/community/tools/matrixweekly0.5https://docs.scs.community/community/tools/nextcloudweekly0.5https://docs.scs.community/community/tools/zuulweekly0.5https://docs.scs.community/contributor-docs/weekly0.5https://docs.scs.community/contributor-docs/development/weekly0.5https://docs.scs.community/contributor-docs/development/tests/rfc2119-keyword-test-guideweekly0.5https://docs.scs.community/contributor-docs/development/tests/test-implementation-guideweekly0.5https://docs.scs.community/contributor-docs/operations/iam/identity-federation-in-scsweekly0.5https://docs.scs.community/contributor-docs/operations/iam/openstack-federation-via-oidcweekly0.5https://docs.scs.community/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guideweekly0.5https://docs.scs.community/docs/weekly0.5https://docs.scs.community/docs/category/apiweekly0.5https://docs.scs.community/docs/category/automated-pentestingweekly0.5https://docs.scs.community/docs/category/central-apiweekly0.5https://docs.scs.community/docs/category/cluster-stacksweekly0.5https://docs.scs.community/docs/category/componentsweekly0.5https://docs.scs.community/docs/category/components-1weekly0.5https://docs.scs.community/docs/category/components-2weekly0.5https://docs.scs.community/docs/category/conceptsweekly0.5https://docs.scs.community/docs/category/configurationweekly0.5https://docs.scs.community/docs/category/container-registryweekly0.5https://docs.scs.community/docs/category/deploymentweekly0.5https://docs.scs.community/docs/category/deployment-examplesweekly0.5https://docs.scs.community/docs/category/guides-1weekly0.5https://docs.scs.community/docs/category/guides-2weekly0.5https://docs.scs.community/docs/category/iaas-layerweekly0.5https://docs.scs.community/docs/category/meteringweekly0.5https://docs.scs.community/docs/category/monitoringweekly0.5https://docs.scs.community/docs/category/operating-scsweekly0.5https://docs.scs.community/docs/category/pentesting-iaasweekly0.5https://docs.scs.community/docs/category/pentesting-kaasweekly0.5https://docs.scs.community/docs/category/releasesweekly0.5https://docs.scs.community/docs/category/scs-health-monitorweekly0.5https://docs.scs.community/docs/category/status-pageweekly0.5https://docs.scs.community/docs/category/turnkey-solutionweekly0.5https://docs.scs.community/docs/category/webweekly0.5https://docs.scs.community/docs/container/weekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/mgt-cluster-flowweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/node-image-flowweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/overviewweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/user-flowweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/architecture/workload-cluster-flowweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/conceptweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/weekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/provider-integrationweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/develop/releasingweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/reference/clusterstackweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/terminologyweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/managing-clusterstacksweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/quickstartweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/troubleshootweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/upgrade-flowweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-operator/topics/using-local-clusterstacksweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllersweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/developweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overviewweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstartweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshootingweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stacks/continuous-integrationweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stacks/overviewweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/configurationweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stacks/providers/openstack/quickstartweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/csctl/designweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/csctl/developing-and-testing-csctlweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/csctl/getting_startedweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/csctl/how_to_use_csctlweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/csctl/overviewweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/csctl/quickstartweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/backup_and_restoreweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/ha-deploymentweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/migrationweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/persistenceweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/quickstartweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/rate_limitweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/scs-deploymentweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/upgradeweekly0.5https://docs.scs.community/docs/container/deployment-examples/a/weekly0.5https://docs.scs.community/docs/container/deployment-examples/a/hardwareweekly0.5https://docs.scs.community/docs/container/deployment-examples/a/softwareweekly0.5https://docs.scs.community/docs/container/guides/guide1weekly0.5https://docs.scs.community/docs/container/overview/architectureweekly0.5https://docs.scs.community/docs/container/overview/knowledgeweekly0.5https://docs.scs.community/docs/faq/weekly0.5https://docs.scs.community/docs/getting-started/containerizationweekly0.5https://docs.scs.community/docs/getting-started/overviewweekly0.5https://docs.scs.community/docs/getting-started/virtualizationweekly0.5https://docs.scs.community/docs/glossaryweekly0.5https://docs.scs.community/docs/iaas/components/weekly0.5https://docs.scs.community/docs/iaas/components/flavor-managerweekly0.5https://docs.scs.community/docs/iaas/components/image-manager/weekly0.5https://docs.scs.community/docs/iaas/components/image-manager/updateweekly0.5https://docs.scs.community/docs/iaas/components/openstack-health-monitorweekly0.5https://docs.scs.community/docs/iaas/components/project-managerweekly0.5https://docs.scs.community/docs/iaas/components/resource-managerweekly0.5https://docs.scs.community/docs/iaas/components/sandbox-managerweekly0.5https://docs.scs.community/docs/iaas/components/simple-stressweekly0.5https://docs.scs.community/docs/iaas/deployment-examples/artcodix/weekly0.5https://docs.scs.community/docs/iaas/guides/weekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/weekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/cephweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/clusterapiweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/gardenerweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/ironicweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/k3sweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/keycloakweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/netdataweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/openstackweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/prometheusweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/sonicweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/teleportweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/designweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/hardware-bomweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/layersweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/nodesweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/use-casesweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/cephweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/weekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/certificatesweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/packagesweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/resolvconfweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/servicesweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/sshconfigweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/sysctlweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/timezoneweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/userweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/configuration-repositoryweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/inventoryweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/loadbalancerweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/managerweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/networkweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/weekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/aodhweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/barbicanweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/ceilometerweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/cinderweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/designateweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/glanceweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/heatweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/horizonweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/ironicweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/keystoneweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/magnumweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/manilaweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/neutronweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/novaweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/octaviaweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/placementweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/skylineweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/proxyweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/rookweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/rookifyweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/services/weekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/services/chronyweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/services/dockerweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/services/tunedweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/validations/weekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/bootstrapweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/examples/weekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/examples/cloud-in-a-boxweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/examples/testbedweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/managerweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/provisioningweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/rookifyweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/seedweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/weekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/cephweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/infrastructureweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/kubernetesweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/logging-monitoringweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/networkweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/openstackweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/rookweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/rookifyweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/cephweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/infrastructureweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/manager/weekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/manager/applyweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/manager/consoleweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/manager/getweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/manager/logweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/manager/taskweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/networkweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/weekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/cinderweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/keystoneweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/neutronweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/novaweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/octaviaweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/weekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/flavor-managerweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/image-manager/weekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/image-manager/updateweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitorweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/project-managerweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/resource-managerweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/sandbox-managerweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/simple-stressweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/rookweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/rookifyweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/weekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/cloud-in-a-box/weekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/cloud-in-a-box/running-on-a-virtual-machineweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/contributor-guideweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/developer-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/developer-guide/releasesweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/developer-guide/scriptsweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/developer-guide/style-guideweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/developer-guide/zuulweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/testbedweekly0.5https://docs.scs.community/docs/iaas/guides/troubleshooting-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/troubleshooting-guide/cephweekly0.5https://docs.scs.community/docs/iaas/guides/troubleshooting-guide/managerweekly0.5https://docs.scs.community/docs/iaas/guides/troubleshooting-guide/openstackweekly0.5https://docs.scs.community/docs/iaas/guides/troubleshooting-guide/rookifyweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/cephweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/dockerweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/infrastructureweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/logging-monitoringweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/managerweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/networkweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/openstackweekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/migration-vmware-esxiweekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/openstack/weekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/openstack/install-instance-from-isoweekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/openstack/openstackclientweekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/openstack/security-groupsweekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/openstack/user-data-backupsweekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/security-groups/weekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/user-data-backupsweekly0.5https://docs.scs.community/docs/iaas/overview/architectureweekly0.5https://docs.scs.community/docs/iaas/overview/computeweekly0.5https://docs.scs.community/docs/iaas/overview/knowledgeweekly0.5https://docs.scs.community/docs/iaas/overview/networkweekly0.5https://docs.scs.community/docs/iaas/overview/storageweekly0.5https://docs.scs.community/docs/iam/weekly0.5https://docs.scs.community/docs/iam/domain-manager-setup-and-usageweekly0.5https://docs.scs.community/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operationsweekly0.5https://docs.scs.community/docs/iam/SCS-example-setup-configuration-descriptionweekly0.5https://docs.scs.community/docs/operating-scs/audits/weekly0.5https://docs.scs.community/docs/operating-scs/components/automated-pentesting-iaas/overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/automated-pentesting-iaas/quickstartweekly0.5https://docs.scs.community/docs/operating-scs/components/automated-pentesting-iaas/reportsweekly0.5https://docs.scs.community/docs/operating-scs/components/automated-pentesting-iaas/toolsweekly0.5https://docs.scs.community/docs/operating-scs/components/automated-pentesting-kaas/overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/automated-pentesting-kaas/quickstartweekly0.5https://docs.scs.community/docs/operating-scs/components/automated-pentesting-kaas/toolsweekly0.5https://docs.scs.community/docs/operating-scs/components/central-api/overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/central-api/poc-setupweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/alertmanagerweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/iaasweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/infrastructure_servicesweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/k3sweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/kaasweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/oauthweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/quickstartweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/scs-deploymentweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/status-pageweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/tracingweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/tuningweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/zuulweekly0.5https://docs.scs.community/docs/operating-scs/components/scs-health-monitor/overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/scs-health-monitor/SetupObservabilityStackweekly0.5https://docs.scs.community/docs/operating-scs/components/scs-health-monitor/Testflowweekly0.5https://docs.scs.community/docs/operating-scs/components/scs-health-monitor/Workflowweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-api/docs/configurationweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-api/docs/contributeweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-api/docs/example-requestsweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-api/docs/overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-api/docs/quickstartweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-api/docs/requestsweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-api/docs/requirementsweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/admin-authenticationweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/configurationweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/contributeweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/faqweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/k3sweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/kindweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/monitoringweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/quickstartweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/requirementsweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/scs-publicweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-deployment/docs/usageweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-openapi/docs/component_overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-openapi/docs/componentsweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-openapi/docs/levels_of_consensusweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-openapi/docs/overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-web/docs/configurationweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-web/docs/contributeweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-web/docs/overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-web/docs/quickstartweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page-web/docs/requirementsweekly0.5https://docs.scs.community/docs/operating-scs/guides/openstack-health-monitor/Debian12-Installweekly0.5https://docs.scs.community/docs/operating-scs/incident-management/weekly0.5https://docs.scs.community/docs/operating-scs/lifecycle-management/weekly0.5https://docs.scs.community/docs/operating-scs/logging/weekly0.5https://docs.scs.community/docs/operating-scs/metering/meter_configurationweekly0.5https://docs.scs.community/docs/operating-scs/monitoring/weekly0.5https://docs.scs.community/docs/operating-scs/overviewweekly0.5https://docs.scs.community/docs/releases/Release0weekly0.5https://docs.scs.community/docs/releases/Release1weekly0.5https://docs.scs.community/docs/releases/Release2weekly0.5https://docs.scs.community/docs/releases/Release3weekly0.5https://docs.scs.community/docs/releases/Release4weekly0.5https://docs.scs.community/docs/releases/Release5weekly0.5https://docs.scs.community/docs/releases/Release6weekly0.5https://docs.scs.community/docs/releases/Release7weekly0.5https://docs.scs.community/docs/releases/ReleaseXweekly0.5https://docs.scs.community/docs/standards/weekly0.5https://docs.scs.community/docs/turnkey-solution/hardware-landscapeweekly0.5https://docs.scs.community/docs/turnkey-solution/overviewweekly0.5https://docs.scs.community/standards/weekly0.5https://docs.scs.community/standards/certification/overviewweekly0.5https://docs.scs.community/standards/certification/overview.templateweekly0.5https://docs.scs.community/standards/certification/pipelineweekly0.5https://docs.scs.community/standards/certification/scopes-versionsweekly0.5https://docs.scs.community/standards/global/weekly0.5https://docs.scs.community/standards/global/scs-0001weekly0.5https://docs.scs.community/standards/global/scs-0002weekly0.5https://docs.scs.community/standards/global/scs-0003weekly0.5https://docs.scs.community/standards/global/scs-0004weekly0.5https://docs.scs.community/standards/global/scs-0005weekly0.5https://docs.scs.community/standards/iaas/weekly0.5https://docs.scs.community/standards/iaas/scs-0100weekly0.5https://docs.scs.community/standards/iaas/scs-0101weekly0.5https://docs.scs.community/standards/iaas/scs-0102weekly0.5https://docs.scs.community/standards/iaas/scs-0103weekly0.5https://docs.scs.community/standards/iaas/scs-0104weekly0.5https://docs.scs.community/standards/iaas/scs-0110weekly0.5https://docs.scs.community/standards/iaas/scs-0111weekly0.5https://docs.scs.community/standards/iaas/scs-0112weekly0.5https://docs.scs.community/standards/iaas/scs-0113weekly0.5https://docs.scs.community/standards/iaas/scs-0114weekly0.5https://docs.scs.community/standards/iaas/scs-0115weekly0.5https://docs.scs.community/standards/iaas/scs-0116weekly0.5https://docs.scs.community/standards/iaas/scs-0117weekly0.5https://docs.scs.community/standards/iaas/scs-0118weekly0.5https://docs.scs.community/standards/iaas/scs-0119weekly0.5https://docs.scs.community/standards/iaas/scs-0120weekly0.5https://docs.scs.community/standards/iaas/scs-0121weekly0.5https://docs.scs.community/standards/iaas/scs-0122weekly0.5https://docs.scs.community/standards/iaas/scs-0123weekly0.5https://docs.scs.community/standards/iaas/scs-0124weekly0.5https://docs.scs.community/standards/iaas/scs-0125weekly0.5https://docs.scs.community/standards/iam/weekly0.5https://docs.scs.community/standards/iam/scs-0300weekly0.5https://docs.scs.community/standards/iam/scs-0301weekly0.5https://docs.scs.community/standards/iam/scs-0302weekly0.5https://docs.scs.community/standards/kaas/weekly0.5https://docs.scs.community/standards/kaas/scs-0200weekly0.5https://docs.scs.community/standards/kaas/scs-0210weekly0.5https://docs.scs.community/standards/kaas/scs-0211weekly0.5https://docs.scs.community/standards/kaas/scs-0212weekly0.5https://docs.scs.community/standards/kaas/scs-0213weekly0.5https://docs.scs.community/standards/kaas/scs-0214weekly0.5https://docs.scs.community/standards/kaas/scs-0215weekly0.5https://docs.scs.community/standards/kaas/scs-0216weekly0.5https://docs.scs.community/standards/kaas/scs-0217weekly0.5https://docs.scs.community/standards/kaas/scs-0218weekly0.5https://docs.scs.community/standards/kaas/scs-0219weekly0.5https://docs.scs.community/standards/ops/weekly0.5https://docs.scs.community/standards/ops/scs-0400weekly0.5https://docs.scs.community/standards/ops/scs-0401weekly0.5https://docs.scs.community/standards/ops/scs-0402weekly0.5https://docs.scs.community/standards/ops/scs-0403weekly0.5https://docs.scs.community/standards/ops/scs-0410weekly0.5https://docs.scs.community/standards/ops/scs-0411weekly0.5https://docs.scs.community/standards/ops/scs-0412weekly0.5https://docs.scs.community/standards/scs-0001-v1-sovereign-cloud-standardsweekly0.5https://docs.scs.community/standards/scs-0002-v1-standards-docs-orgweekly0.5https://docs.scs.community/standards/scs-0002-v2-standards-docs-orgweekly0.5https://docs.scs.community/standards/scs-0003-v1-sovereign-cloud-standards-yamlweekly0.5https://docs.scs.community/standards/scs-0004-v1-achieving-certificationweekly0.5https://docs.scs.community/standards/scs-0005-v1-project-governanceweekly0.5https://docs.scs.community/standards/scs-0100-v1-flavor-namingweekly0.5https://docs.scs.community/standards/scs-0100-v2-flavor-namingweekly0.5https://docs.scs.community/standards/scs-0100-v3-flavor-namingweekly0.5https://docs.scs.community/standards/scs-0100-w1-flavor-naming-implementation-testingweekly0.5https://docs.scs.community/standards/scs-0101-v1-entropyweekly0.5https://docs.scs.community/standards/scs-0101-w1-entropy-implementation-testingweekly0.5https://docs.scs.community/standards/scs-0102-v1-image-metadataweekly0.5https://docs.scs.community/standards/scs-0102-w1-image-metadata-implementation-testingweekly0.5https://docs.scs.community/standards/scs-0103-v1-standard-flavorsweekly0.5https://docs.scs.community/standards/scs-0104-v1-standard-imagesweekly0.5https://docs.scs.community/standards/scs-0104-w1-standard-images-implementationweekly0.5https://docs.scs.community/standards/scs-0110-v1-ssd-flavorsweekly0.5https://docs.scs.community/standards/scs-0111-v1-volume-type-decisionsweekly0.5https://docs.scs.community/standards/scs-0112-v1-sonicweekly0.5https://docs.scs.community/standards/scs-0113-v1-security-groups-decision-recordweekly0.5https://docs.scs.community/standards/scs-0114-v1-volume-type-standardweekly0.5https://docs.scs.community/standards/scs-0115-v1-default-rules-for-security-groupsweekly0.5https://docs.scs.community/standards/scs-0116-v1-key-manager-standardweekly0.5https://docs.scs.community/standards/scs-0116-w1-key-manager-implementation-testingweekly0.5https://docs.scs.community/standards/scs-0117-v1-volume-backup-serviceweekly0.5https://docs.scs.community/standards/scs-0118-v1-taxonomy-of-failsafe-levelsweekly0.5https://docs.scs.community/standards/scs-0118-w1-example-impacts-of-failure-scenariosweekly0.5https://docs.scs.community/standards/scs-0119-v1-rook-decisionweekly0.5https://docs.scs.community/standards/scs-0120-v1-capi-imagesweekly0.5https://docs.scs.community/standards/scs-0121-v1-Availability-Zones-Standardweekly0.5https://docs.scs.community/standards/scs-0121-w1-Availability-Zones-Standardweekly0.5https://docs.scs.community/standards/scs-0122-v1-node-to-node-encryptionweekly0.5https://docs.scs.community/standards/scs-0123-v1-mandatory-and-supported-IaaS-servicesweekly0.5https://docs.scs.community/standards/scs-0124-v1-security-of-iaas-service-softwareweekly0.5https://docs.scs.community/standards/scs-0124-w1-security-of-iaas-service-softwareweekly0.5https://docs.scs.community/standards/scs-0125-v1-secure-connectionsweekly0.5https://docs.scs.community/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-testsweekly0.5https://docs.scs.community/standards/scs-0210-v1-k8s-new-version-policyweekly0.5https://docs.scs.community/standards/scs-0210-v2-k8s-version-policyweekly0.5https://docs.scs.community/standards/scs-0210-w1-k8s-version-policy-implementation-testingweekly0.5https://docs.scs.community/standards/scs-0211-v1-kaas-default-storage-classweekly0.5https://docs.scs.community/standards/scs-0211-v2-kaas-default-storage-classweekly0.5https://docs.scs.community/standards/scs-0211-w1-kaas-default-storage-class-implementation-testingweekly0.5https://docs.scs.community/standards/scs-0212-v1-requirements-for-container-registriesweekly0.5https://docs.scs.community/standards/scs-0213-v1-k8s-nodes-anti-affinityweekly0.5https://docs.scs.community/standards/scs-0214-v1-k8s-node-distributionweekly0.5https://docs.scs.community/standards/scs-0214-v2-k8s-node-distributionweekly0.5https://docs.scs.community/standards/scs-0214-w1-k8s-node-distribution-implementation-testingweekly0.5https://docs.scs.community/standards/scs-0215-v1-robustness-featuresweekly0.5https://docs.scs.community/standards/scs-0216-v1-requirements-for-testing-cluster-stacksweekly0.5https://docs.scs.community/standards/scs-0217-v1-cluster-hardeningweekly0.5https://docs.scs.community/standards/scs-0218-v1-container-registry-for-scs-standard-implementationweekly0.5https://docs.scs.community/standards/scs-0219-v1-kaas-networkingweekly0.5https://docs.scs.community/standards/scs-0219-w1-kaas-networkingweekly0.5https://docs.scs.community/standards/scs-0300-v1-requirements-for-sso-identity-federationweekly0.5https://docs.scs.community/standards/scs-0301-v1-naming-conventionsweekly0.5https://docs.scs.community/standards/scs-0302-v1-domain-manager-roleweekly0.5https://docs.scs.community/standards/scs-0302-w1-domain-manager-implementation-notesweekly0.5https://docs.scs.community/standards/scs-0400-v1-status-page-create-decisionweekly0.5https://docs.scs.community/standards/scs-0401-v1-status-page-reference-implementation-decisionweekly0.5https://docs.scs.community/standards/scs-0402-v1-status-page-openapi-spec-decisionweekly0.5https://docs.scs.community/standards/scs-0403-v1-csp-kaas-observability-stackweekly0.5https://docs.scs.community/standards/scs-0410-v1-gnocchi-as-metering-databaseweekly0.5https://docs.scs.community/standards/scs-0411-v1-publishing_method_for_metering_dataweekly0.5https://docs.scs.community/standards/scs-0412-v1-metering-jsonweekly0.5https://docs.scs.community/standards/scs-compatible-iaasweekly0.5https://docs.scs.community/standards/scs-compatible-kaasweekly0.5https://docs.scs.community/standards/scs-XXXX-vN-decision-record-templateweekly0.5https://docs.scs.community/standards/scs-XXXX-vN-standard-templateweekly0.5https://docs.scs.community/standards/standards/overviewweekly0.5https://docs.scs.community/user-docs/weekly0.5https://docs.scs.community/user-docs/application-examples/opendesk-on-scs/configurationweekly0.5https://docs.scs.community/user-docs/application-examples/opendesk-on-scs/contributeweekly0.5https://docs.scs.community/user-docs/application-examples/opendesk-on-scs/getting_startedweekly0.5https://docs.scs.community/user-docs/application-examples/opendesk-on-scs/overviewweekly0.5https://docs.scs.community/user-docs/application-examples/opendesk-on-scs/quickstartweekly0.5https://docs.scs.community/user-docs/application-examples/opendesk-on-scs/requirementsweekly0.5https://docs.scs.community/user-docs/application-examples/opendesk-on-scs/user-importweekly0.5https://docs.scs.community/user-docs/category/application-examplesweekly0.5https://docs.scs.community/user-docs/category/opendesk-on-scsweekly0.5https://docs.scs.community/weekly0.5 \ No newline at end of file diff --git a/standards/certification/overview.template/index.html b/standards/certification/overview.template/index.html new file mode 100644 index 0000000000..f4b48de12c --- /dev/null +++ b/standards/certification/overview.template/index.html @@ -0,0 +1,29 @@ + + + + + +overview.template | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Certification

+

SCS certificates come with various scopes. See Scopes and Versions for details.

+

Becoming certified

+

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.

+

Compliant cloud environments

+

This is a list of clouds that we test on a nightly basis against the certificate scope SCS-compatible IaaS.

+ + \ No newline at end of file diff --git a/standards/certification/overview/index.html b/standards/certification/overview/index.html new file mode 100644 index 0000000000..c742d20dd2 --- /dev/null +++ b/standards/certification/overview/index.html @@ -0,0 +1,31 @@ + + + + + +overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Certification

+

SCS certificates come with various scopes. See Scopes and Versions for details.

+

Becoming certified

+

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.

+

Compliant cloud environments

+

This is a list of clouds that we test on a nightly basis against the certificate scope SCS-compatible IaaS.

+

Version numbers are suffixed by a symbol depending on state: * for draft, † for warn (soon to be deprecated), and †† for deprecated.

+
NameDescriptionOperatorSCS-compatible IaaSHealthMon
gx-scsDev environment provided for SCS & GAIA-X contextplusserver GmbH🟧 v3††HM
aov.cloudCommunity cloud for customersaov IT.Services GmbH🛑 –HM
CC@RRZEPrivate Compute Cloud (CC) for FAURegionales Rechenzentrum Erlangen✅ v4, v5.1(soon)
CNDSPublic cloud for customersartcodix GmbH✅ v4, v5.1HM
pluscloud open
(4 regions)
Public cloud for customersplusserver GmbHprod1: 🛑 –
prod2: 🛑 –
prod3: 🛑 –
prod4: 🛑 –
HM1
HM2
HM3
HM4
PoC KDOCloud PoC for FITKOKDO Service GmbH / OSISM GmbH🛑 –(soon)
PoC WG-Cloud OSBACloud PoC for FITKOCloud&Heat Technologies GmbH✅ v4HM
REGIO.cloudPublic cloud for customersOSISM GmbH🛑 –HM
ScaleUp Open CloudPublic cloud for customersScaleUp Technologies GmbH & Co. KG✅ v4, v5.1HM
syseleven
(2 SCS regions)
Public OpenStack CloudSysEleven GmbHdus2: 🟧 v3††
ham1: 🟧 v3††
(soon)
(soon)
WavestackPublic cloud for customersnoris network AG/Wavecon GmbH🛑 –HM
+ + \ No newline at end of file diff --git a/standards/certification/pipeline/index.html b/standards/certification/pipeline/index.html new file mode 100644 index 0000000000..0dd923b669 --- /dev/null +++ b/standards/certification/pipeline/index.html @@ -0,0 +1,145 @@ + + + + + +SCS Compliance Check Pipeline Manual | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Compliance Check Pipeline Manual

+

The SCS compliance check suite runs automated tests, generates a signed report for the run, and feeds it to +the compliance monitor. Roughly speaking, this process has to be performed daily, for instance, using a +continuous-integration "pipeline".

+

Providers of public clouds do not need to use their own pipelines; those clouds can be tested via the +official SCS compliance check pipeline.

+

Alternatively, if using this pipeline is not feasible (for instance, for private clouds) or not desired, +cloud-service providers can run the tests and feed the compliance monitor themselves.

+

The next subsection shows common requirements for each of these two cases. The two subsections after that +are each dedicated to the specific cases.

+

Common requirements for the compliance checks

+

for SCS-compatible IaaS

+

You need an OpenStack project that allows for at least one server and one router, possibly more if it's going +to be used for purposes other than compliance testing (such as the +OpenStack Health Monitor or the +SCS Health Monitor).

+
    +
  1. +

    Create an application credential. It must be possible to create resources such as servers, routers, etc.

    +
  2. +
  3. +

    Create a new branch in the standards repository:

    +
      +
    • git clone git@github.com:SovereignCloudStack/standards.git
    • +
    • cd standards
    • +
    • git checkout -b feat/add_my_cloud
    • +
    +

    CAUTION: If you are not a member of the SCS Github org, this won't work. +Ask the SCS team (or other members) to add you. Alternatively, you may fork the repository on +Github first and then clone the fork.

    +
  4. +
  5. +

    Add your subject to the results table. This is necessary so your subject shows up in the +compliance monitor web-site. Add the following lines +(substituting all-caps parts except HM):

    +
     | [gx-scs](https://github.com/SovereignCloudStack/docs/blob/main/community/cloud-resources/plusserver-gx-scs.md) | Dev environment provided for SCS & GAIA-X context | plusserver GmbH |
    {#- #} [{{ results | pick('gx-scs', iaas) | summary }}]({{ detail_url('gx-scs', iaas) }}) {# -#}
    | [HM](https://health.gx-scs.sovereignit.cloud:3000/) |
    +| [SUBJECT_NAME](YOUR_URL) | DESCRIPTION | COMPANY_NAME |
    +{#- #} [{{ results | pick('SUBJECT_NAME', iaas) | summary }}]({{ detail_url('SUBJECT_NAME', iaas) }}) {# -#}
    +| [HM](HEALTH_MONITOR_URL) |
    +

    Ideally, insert the lines at a position that keeps the part of the table below gx-scs sorted.

    +
  6. +
+

Now you can proceed with the steps from one of the next subsections, depending on whether you want to +check suite run by the SCS pipeline or not.

+

How to add a new test subject to the official pipeline

+

for SCS-compatible IaaS

+

We are going to create a pull request that is very similar to real-life example that +adds the test subject scaleup-occ2. +(However, note that this example also adds an optional GitHub workflow, which we won't do here.)

+
    +
  1. +

    Modify playbooks/clouds.yaml.j2. +This is necessary so that the tests can access your cloud. +You can use the following template (replace all-caps parts):

    +
      SUBJECT_NAME:
    region_name: REGION
    interface: "public"
    identity_api_version: 3
    auth_type: "v3applicationcredential"
    auth:
    auth_url: AUTH_URL
    application_credential_id: "{{ clouds_conf.SUBJECT_NAME_ac_id }}"
    application_credential_secret: "{{ clouds_conf.SUBJECT_NAME_a_ac_secret }}"
    +

    Note that you need to replace dashes (and other special characters) by underscores in the last two lines.

    +
  2. +
  3. +

    Add your subject to Tests/config.toml. +This is necessary so that your cloud will be included in the nightly tests. Add a line like so:

    +
     [presets.all]
    scopes = [
    "scs-compatible-iaas",
    ]
    subjects = [
    "gx-scs",
    + "SUBJECT_NAME",
    +

    Ideally, insert your subject so that the list (after gx-scs) remains sorted.

    +
  4. +
  5. +

    Add your subject to compliance-monitor/bootstrap.yaml. +This is necessary to that the reports will be accepted as genuine. Add a section like so:

    +
       - subject: artcodix
    delegates:
    - zuul_ci
    + - subject: SUBJECT_NAME
    + delegates:
    + - zuul_ci
    +

    Again, insert your subject so that the list (after gx-scs) remains sorted.

    +
  6. +
  7. +

    Finally, add secrets to .zuul.d/secure.yaml. +This is necessary so the tests can access your cloud.

    +

    This step is the most involved, and you can always have us do it for you; in that case, please send us +the application credential id and secret via an encrypted channel, e.g. Matrix.

    +

    To proceed, you need zuul-client installed:

    +
    pipx install zuul-client
    +

    Then you can execute:

    +
    $ zuul-client --zuul-url https://zuul.sovereignit.cloud/ encrypt --tenant scs --project SovereignCloudStack/standards
    <PASTE application credential id HERE>
    <HIT ctrl-d>

    ...
    - secret:
    name: <name>
    data:
    <fieldname>: !encrypted/pkcs1-oaep
    - ...

    $ zuul-client --zuul-url https://zuul.sovereignit.cloud/ encrypt --tenant scs --project SovereignCloudStack/standards
    <PASTE application credential secret HERE>
    <HIT ctrl-d>

    ...
    - secret:
    name: <name>
    data:
    <fieldname>: !encrypted/pkcs1-oaep
    - ...
    +

    Copy the parts of the respective outputs starting in the final line shown here (the one starting -). +Insert them like so:

    +
    +   SUBJECT_NAME_ac_id: !encrypted/pkcs1-oaep
    + - ENCRYPTED_ID
    + SUBJECT_NAME_ac_secret: !encrypted/pkcs1-oaep
    + - ENCRYPTED_SECRET
    +

    Note that you have to use the same keys as in Step 1 (that is, with special characters replaced).

    +
  8. +
  9. +

    Commit your changes and open a pull request:

    +
    git commit -asm "Add SUBJECT_NAME"
    git push # the output of this command will show you the URL for creating the pull request
    +
  10. +
+

How to feed the compliance monitor yourself

+

for SCS-compatible IaaS

+

Note: you may have to adapt these instructions to your infrastructure. For instance, the secrets +we create here are stored locally. If you want to include the check suite into your own +continuous-integration pipeline, you may want to use some dedicated credential store and mechanism for +injecting secrets.

+

You may want to take inspiration from our own Zuul setup by looking at +.zuul.d and +playbooks. +However, don't be overwhelmed by the complexities of Zuul; it's well possible to use other solutions, +including a cronjob.

+
    +
  1. +

    Install requirements.

    +
    virtualenv .venv
    . .venv/bin/activate
    pip install -r requirements.txt
    pip install passlib argon2_cffi # these are only needed for Step 2
    +
  2. +
  3. +

    Run our support script (substitute $SUBJECT_NAME appropriately):

    +
    Tests/add_subject.py $SUBJECT_NAME
    +

    Follow the instructions. +At the end, it will tell you to amend the file compliance-monitor/boostrap.py. Do so.

    +
  4. +
  5. +

    Make sure you have $SUBJECT_NAME in your .config/openstack/clouds.yaml like so:

    +
      SUBJECT_NAME:
    region_name: REGION
    interface: "public"
    identity_api_version: 3
    auth_type: "v3applicationcredential"
    auth:
    auth_url: AUTH_URL
    application_credential_id: "APPLICATION_CREDENTIAL_ID"
    application_credential_secret: "APPLICATION_CREDENTIAL_SECRET"
    +
  6. +
  7. +

    Perform a test run of the check suite like so:

    +
    python3 Tests/scs-test-runner.py --config Tests/config.toml run --scope scs-compatible-iaas --subject $SUBJECT_NAME
    +

    If the report can't be submitted at the very end, this is to be expected, because the keyfile is not yet +known to the compliance monitor. To change this, we proceed to the next step.

    +
  8. +
  9. +

    Commit your changes and open a pull request:

    +
    git commit -asm "Add SUBJECT_NAME"
    git push # the output of this command will show you the URL for creating the pull request
    +
  10. +
+ + \ No newline at end of file diff --git a/standards/certification/scopes-versions/index.html b/standards/certification/scopes-versions/index.html new file mode 100644 index 0000000000..2a2c49fd40 --- /dev/null +++ b/standards/certification/scopes-versions/index.html @@ -0,0 +1,44 @@ + + + + + +Scopes and versions | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Scopes and versions

+

SCS provides a certification framework consisting of six different kinds of certificates of varying scope. +These scopes can be sorted into two dimensions:

+
    +
  1. certification level, of which there are three: +
      +
    • SCS-compatible
    • +
    • SCS-open
    • +
    • SCS-sovereign
    • +
    +
  2. +
  3. cloud layer, of which there are two: +
      +
    • infastructure as a service (IaaS)
    • +
    • Kubernetes as a service (KaaS)
    • +
    +
  4. +
+

So, for instance, a certificate can have the scope SCS-compatible IaaS or SCS-sovereign KaaS.

+

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.

+

Alt text

+ + \ No newline at end of file diff --git a/standards/global/index.html b/standards/global/index.html new file mode 100644 index 0000000000..79728adc21 --- /dev/null +++ b/standards/global/index.html @@ -0,0 +1,36 @@ + + + + + +Global Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Global Standards

+

This track encompasses the foundational standards that guide the overall structure, documentation, and general topics related to the Sovereign Cloud Stack. It serves as the core framework, ensuring consistency, clarity, and comprehensibility across all aspects of the cloud stack, fostering an environment where information is easily accessible and understood.

+

*Legend to the column headings and entries:

+
    +
  • Document states: Draft, Effective, Deprecated (and no longer effective)
  • +
  • Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future
  • +
  • Entries in the effective column marked with a † will turn deprecated in the near future
  • +
+ + + +
+
StandardDescriptionDraftEffectiveDeprecated*
scs-0001Sovereign Cloud Standards-v1-
scs-0002Standards, Docs and Organisationv2v1-
scs-0003Sovereign Cloud Standards YAMLv1--
scs-0004Regulations for achieving SCS-compatible certificationv1--
scs-0005Governance of the SCS communityv1--
+ + \ No newline at end of file diff --git a/standards/global/scs-0001/index.html b/standards/global/scs-0001/index.html new file mode 100644 index 0000000000..4a6a4bbbb7 --- /dev/null +++ b/standards/global/scs-0001/index.html @@ -0,0 +1,28 @@ + + + + + +scs-0001: Sovereign Cloud Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0001: Sovereign Cloud Standards

+

SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision +records within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in +the development and maintenance of interoperable and transparent cloud infrastructure standards.

+
VersionTypeStatestabilizeddeprecated
scs-0001-v1ProceduralStable2022-11-28-
+ + \ No newline at end of file diff --git a/standards/global/scs-0002/index.html b/standards/global/scs-0002/index.html new file mode 100644 index 0000000000..0c2504341d --- /dev/null +++ b/standards/global/scs-0002/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0002: Standards, Docs and Organisation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/global/scs-0003/index.html b/standards/global/scs-0003/index.html new file mode 100644 index 0000000000..83b370f53f --- /dev/null +++ b/standards/global/scs-0003/index.html @@ -0,0 +1,28 @@ + + + + + +scs-0003: Sovereign Cloud Standards YAML | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0003: Sovereign Cloud Standards YAML

+

SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings, +categorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning +in a machine-readable YAML format for clarity, traceability, and tool integration.

+
VersionTypeStatestabilizeddeprecated
scs-0003-v1ProceduralDraft--
+ + \ No newline at end of file diff --git a/standards/global/scs-0004/index.html b/standards/global/scs-0004/index.html new file mode 100644 index 0000000000..291caa175b --- /dev/null +++ b/standards/global/scs-0004/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0004: Regulations for achieving SCS-compatible certification | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0004: Regulations for achieving SCS-compatible certification

+
VersionTypeStatestabilizeddeprecated
scs-0004-v1ProceduralDraft--
+ + \ No newline at end of file diff --git a/standards/global/scs-0005/index.html b/standards/global/scs-0005/index.html new file mode 100644 index 0000000000..8ef05df055 --- /dev/null +++ b/standards/global/scs-0005/index.html @@ -0,0 +1,26 @@ + + + + + +scs-0005: Governance of the SCS community | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0005: Governance of the SCS community

+

SCS-0005 outlines the structure and governance of the SCS community by the SCS Project Board and how this is elected.

+
VersionTypeStatestabilizeddeprecated
scs-0005-v1ProceduralDraft--
+ + \ No newline at end of file diff --git a/standards/iaas/index.html b/standards/iaas/index.html new file mode 100644 index 0000000000..c5ee0f33dc --- /dev/null +++ b/standards/iaas/index.html @@ -0,0 +1,36 @@ + + + + + +IaaS Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

IaaS Standards

+

The IaaS Layer Standards track focuses on the protocols, guidelines, and specifications that govern the infrastructure as a service layer. This encompasses standards for virtual machines, storage, networking, and other foundational resources, ensuring seamless, efficient, and secure operation, interoperability, and management of the underlying cloud infrastructure.

+

*Legend to the column headings and entries:

+
    +
  • Document states: Draft, Effective, Deprecated (and no longer effective)
  • +
  • Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future
  • +
  • Entries in the effective column marked with a † will turn deprecated in the near future
  • +
+ + + +
+
StandardDescriptionDraftEffectiveDeprecated*
scs-0100SCS Flavor Naming Standard-v3v1, v2
Supplement: Implementation and Testing Notesw1--
scs-0101SCS Entropy-v1-
Supplement: Implementation and Testing Notesw1--
scs-0102SCS Image Metadata-v1-
Supplement: Implementation and Testing Notesw1--
scs-0103SCS Standard Flavors and Properties-v1-
scs-0104SCS Standard Images-v1-
Supplement: Implementation Notesw1--
scs-0110SSD Flavors-v1-
scs-0111Decisions for the Volume Type Standardv1--
scs-0112SONiC Support in SCSv1--
scs-0113Security Groups Decision Recordv1--
scs-0114SCS Volume Types-v1-
scs-0115Default Rules for Security Groups-v1-
scs-0116SCS Key Manager Standard-v1-
Supplement: Implementation and Testing Notesw1--
scs-0117Volume Backup Functionality-v1-
scs-0118SCS Taxonomy of Failsafe Levelsv1--
Supplement: Examples of Failure Cases and their impact on IaaS and KaaS resourcesw1--
scs-0119Replacement of the deprecated ceph-ansible toolv1--
scs-0120Cluster-API imagesv1--
scs-0121SCS Availability Zones-v1-
Supplement: Implementation and Testing Notesw1--
scs-0122End-to-End Encryption between Customer Workloadsv1--
scs-0123Mandatory and Supported IaaS Services-v1-
scs-0124Standard for the security of IaaS service softwarev1--
Supplement: SCS Standard for the security of IaaS service software: Implementation and Testing Notesw1--
scs-0125Secure Connectionsv1--
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0100/index.html b/standards/iaas/scs-0100/index.html new file mode 100644 index 0000000000..ac933f559b --- /dev/null +++ b/standards/iaas/scs-0100/index.html @@ -0,0 +1,31 @@ + + + + + +scs-0100: SCS Flavor Naming Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0100: SCS Flavor Naming Standard

+

The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack +environments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM, +and Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for +usability and portability across all SCS flavors.

+
VersionTypeStatestabilizeddeprecated
scs-0100-v1StandardDeprecated2022-09-082023-10-31
scs-0100-v2StandardDeprecated2023-02-212023-11-30
scs-0100-v3StandardStable2023-06-14-
+

Supplement: Implementation and Testing Notes

+
VersionStatestabilizeddeprecated
w1Draft--
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0101/index.html b/standards/iaas/scs-0101/index.html new file mode 100644 index 0000000000..cd47697d57 --- /dev/null +++ b/standards/iaas/scs-0101/index.html @@ -0,0 +1,33 @@ + + + + + +scs-0101: SCS Entropy | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0101: SCS Entropy

+

The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations +such as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and +activating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy +accessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into +virtual instances and ensures the availability and quality of entropy in virtual environments, promoting system +security and efficiency.

+
VersionTypeStatestabilizeddeprecated
scs-0101-v1StandardStable2024-02-08-
+

Supplement: Implementation and Testing Notes

+
VersionStatestabilizeddeprecated
w1Draft--
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0102/index.html b/standards/iaas/scs-0102/index.html new file mode 100644 index 0000000000..11f5a5f4bb --- /dev/null +++ b/standards/iaas/scs-0102/index.html @@ -0,0 +1,32 @@ + + + + + +scs-0102: SCS Image Metadata | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0102: SCS Image Metadata

+

The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating +system images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements, +image handling protocols including updating and origin, and licensing/support details. These guidelines ensure +that users can understand, access, and utilize OS images effectively, with clear information on features, updates, +and licensing provided through well-defined metadata properties.

+
VersionTypeStatestabilizeddeprecated
scs-0102-v1StandardStable2022-10-31-
+

Supplement: Implementation and Testing Notes

+
VersionStatestabilizeddeprecated
w1Draft--
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0103/index.html b/standards/iaas/scs-0103/index.html new file mode 100644 index 0000000000..8bc7a1524a --- /dev/null +++ b/standards/iaas/scs-0103/index.html @@ -0,0 +1,30 @@ + + + + + +scs-0103: SCS Standard Flavors and Properties | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0103: SCS Standard Flavors and Properties

+

The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack +environments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific +configurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs:name-vN, scs:cpu-type, +and scs:diskN-type to detail the flavor's specifications. This standard facilitates guaranteed availability and +consistency of flavors, simplifying the deployment process for DevOps teams.

+
VersionTypeStatestabilizeddeprecated
scs-0103-v1StandardStable2024-02-08-
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0104/index.html b/standards/iaas/scs-0104/index.html new file mode 100644 index 0000000000..3a8a5e447d --- /dev/null +++ b/standards/iaas/scs-0104/index.html @@ -0,0 +1,32 @@ + + + + + +scs-0104: SCS Standard Images | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0104: SCS Standard Images

+

The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments, +specifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined +deployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard's +machine-readable document facilitates automated processing for compliance and integration purposes, promoting +consistency and reliability in cloud environments.

+
VersionTypeStatestabilizeddeprecated
scs-0104-v1ProceduralStable2024-02-21-
+

Supplement: Implementation Notes

+
VersionStatestabilizeddeprecated
w1Draft--
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0110/index.html b/standards/iaas/scs-0110/index.html new file mode 100644 index 0000000000..e3bf5542b3 --- /dev/null +++ b/standards/iaas/scs-0110/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0110: SSD Flavors | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0111/index.html b/standards/iaas/scs-0111/index.html new file mode 100644 index 0000000000..06b6ec594a --- /dev/null +++ b/standards/iaas/scs-0111/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0111: Decisions for the Volume Type Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0112/index.html b/standards/iaas/scs-0112/index.html new file mode 100644 index 0000000000..9bf4c8d699 --- /dev/null +++ b/standards/iaas/scs-0112/index.html @@ -0,0 +1,26 @@ + + + + + +scs-0112: SONiC Support in SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0112: SONiC Support in SCS

+

SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.

+
VersionTypeStatestabilizeddeprecated
scs-0112-v1Decision RecordDraft--
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0113/index.html b/standards/iaas/scs-0113/index.html new file mode 100644 index 0000000000..36823e8837 --- /dev/null +++ b/standards/iaas/scs-0113/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0113: Security Groups Decision Record | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0114/index.html b/standards/iaas/scs-0114/index.html new file mode 100644 index 0000000000..882b1d2ada --- /dev/null +++ b/standards/iaas/scs-0114/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0114: SCS Volume Types | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0115/index.html b/standards/iaas/scs-0115/index.html new file mode 100644 index 0000000000..aa4e8626fe --- /dev/null +++ b/standards/iaas/scs-0115/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0115: Default Rules for Security Groups | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0116/index.html b/standards/iaas/scs-0116/index.html new file mode 100644 index 0000000000..ecffc9a8f1 --- /dev/null +++ b/standards/iaas/scs-0116/index.html @@ -0,0 +1,27 @@ + + + + + +scs-0116: SCS Key Manager Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0117/index.html b/standards/iaas/scs-0117/index.html new file mode 100644 index 0000000000..afc1a34fe7 --- /dev/null +++ b/standards/iaas/scs-0117/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0117: Volume Backup Functionality | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0118/index.html b/standards/iaas/scs-0118/index.html new file mode 100644 index 0000000000..312df1ee5a --- /dev/null +++ b/standards/iaas/scs-0118/index.html @@ -0,0 +1,27 @@ + + + + + +scs-0118: SCS Taxonomy of Failsafe Levels | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0118: SCS Taxonomy of Failsafe Levels

+
VersionTypeStatestabilizeddeprecated
scs-0118-v1Decision RecordDraft--
+

Supplement: Examples of Failure Cases and their impact on IaaS and KaaS resources

+
VersionStatestabilizeddeprecated
w1Draft--
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0119/index.html b/standards/iaas/scs-0119/index.html new file mode 100644 index 0000000000..1d8f7a90f6 --- /dev/null +++ b/standards/iaas/scs-0119/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0119: Replacement of the deprecated ceph-ansible tool | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0120/index.html b/standards/iaas/scs-0120/index.html new file mode 100644 index 0000000000..5974b05c8d --- /dev/null +++ b/standards/iaas/scs-0120/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0120: Cluster-API images | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0121/index.html b/standards/iaas/scs-0121/index.html new file mode 100644 index 0000000000..d5bd8c9512 --- /dev/null +++ b/standards/iaas/scs-0121/index.html @@ -0,0 +1,27 @@ + + + + + +scs-0121: SCS Availability Zones | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0122/index.html b/standards/iaas/scs-0122/index.html new file mode 100644 index 0000000000..9193f09625 --- /dev/null +++ b/standards/iaas/scs-0122/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0122: _End-to-End Encryption between Customer Workloads_ | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0123/index.html b/standards/iaas/scs-0123/index.html new file mode 100644 index 0000000000..df4ab06e00 --- /dev/null +++ b/standards/iaas/scs-0123/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0123: Mandatory and Supported IaaS Services | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0124/index.html b/standards/iaas/scs-0124/index.html new file mode 100644 index 0000000000..0bc6f96342 --- /dev/null +++ b/standards/iaas/scs-0124/index.html @@ -0,0 +1,27 @@ + + + + + +scs-0124: Standard for the security of IaaS service software | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0124: Standard for the security of IaaS service software

+
VersionTypeStatestabilizeddeprecated
scs-0124-v1StandardDraft--
+

Supplement: SCS Standard for the security of IaaS service software: Implementation and Testing Notes

+
VersionStatestabilizeddeprecated
w1Draft--
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0125/index.html b/standards/iaas/scs-0125/index.html new file mode 100644 index 0000000000..808514ac75 --- /dev/null +++ b/standards/iaas/scs-0125/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0125: Secure Connections | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iam/index.html b/standards/iam/index.html new file mode 100644 index 0000000000..3e7d74fdec --- /dev/null +++ b/standards/iam/index.html @@ -0,0 +1,36 @@ + + + + + +IAM Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

IAM Standards

+

This track revolves around Identity and Access Management (IAM) standards, providing guidelines for ensuring secure and efficient user authentication, authorization, and administration. It addresses issues related to user identity, permissions, roles, and policies, aiming to safeguard and streamline access to cloud resources and services.

+

*Legend to the column headings and entries:

+
    +
  • Document states: Draft, Effective, Deprecated (and no longer effective)
  • +
  • Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future
  • +
  • Entries in the effective column marked with a † will turn deprecated in the near future
  • +
+ + + +
+
StandardDescriptionDraftEffectiveDeprecated*
scs-0300Requirements for SSO identity federation-v1-
scs-0301Naming for domains/groups/roles/project when onboarding new customersv1--
scs-0302Domain Manager configuration for Keystone-v1-
Supplement: Domain Manager implementation notesw1--
+ + \ No newline at end of file diff --git a/standards/iam/scs-0300/index.html b/standards/iam/scs-0300/index.html new file mode 100644 index 0000000000..24cfcdd309 --- /dev/null +++ b/standards/iam/scs-0300/index.html @@ -0,0 +1,31 @@ + + + + + +scs-0300: Requirements for SSO identity federation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0300: Requirements for SSO identity federation

+

The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign +Cloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed +externally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard +focuses on delegating authentication to external identity providers and mapping users to roles within SCS for +authorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity +Provider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible.

+
VersionTypeStatestabilizeddeprecated
scs-0300-v1Decision RecordStable2023-06-21-
+ + \ No newline at end of file diff --git a/standards/iam/scs-0301/index.html b/standards/iam/scs-0301/index.html new file mode 100644 index 0000000000..8d280a32a8 --- /dev/null +++ b/standards/iam/scs-0301/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0301: Naming for domains/groups/roles/project when onboarding new customers | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0301: Naming for domains/groups/roles/project when onboarding new customers

+
VersionTypeStatestabilizeddeprecated
scs-0301-v1Decision RecordDraft--
+ + \ No newline at end of file diff --git a/standards/iam/scs-0302/index.html b/standards/iam/scs-0302/index.html new file mode 100644 index 0000000000..5ae567f7dc --- /dev/null +++ b/standards/iam/scs-0302/index.html @@ -0,0 +1,27 @@ + + + + + +scs-0302: Domain Manager configuration for Keystone | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0302: Domain Manager configuration for Keystone

+
VersionTypeStatestabilizeddeprecated
scs-0302-v1StandardStable2024-11-13-
+

Supplement: Domain Manager implementation notes

+
VersionStatestabilizeddeprecated
w1Draft--
+ + \ No newline at end of file diff --git a/standards/index.html b/standards/index.html new file mode 100644 index 0000000000..8ea8c41b37 --- /dev/null +++ b/standards/index.html @@ -0,0 +1,28 @@ + + + + + +Introduction | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Introduction

+

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.

+

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.

+

Alt text

+

Learn more about these scopes as well as the currently certified clouds under Certification. More details on individual standards can be found under Standards.

+ + \ No newline at end of file diff --git a/standards/kaas/index.html b/standards/kaas/index.html new file mode 100644 index 0000000000..07383b98b7 --- /dev/null +++ b/standards/kaas/index.html @@ -0,0 +1,36 @@ + + + + + +KaaS Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

KaaS Standards

+

Standards in this track are concerned with Kubernetes as a Service layer, outlining norms and best practices for deploying, managing, and operating Kubernetes clusters. These standards aim to ensure that the orchestration of containers is streamlined, secure, and compatible across various cloud environments and platforms.

+

*Legend to the column headings and entries:

+
    +
  • Document states: Draft, Effective, Deprecated (and no longer effective)
  • +
  • Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future
  • +
  • Entries in the effective column marked with a † will turn deprecated in the near future
  • +
+ + + +
+
StandardDescriptionDraftEffectiveDeprecated*
scs-0200Using Sonobuoy for KaaS conformance testsv1--
scs-0210SCS K8S Version Policy-v2v1
Supplement: Implementation and Testing Notesw1--
scs-0211SCS KaaS default storage classv2v1-
Supplement: Implementation and Testing Notesw1--
scs-0212Requirements for container registriesv1--
scs-0213Kubernetes Nodes Anti Affinityv1--
scs-0214Kubernetes Node Distribution and Availability-v1, v2-
Supplement: Implementation and Testing Notesw1--
scs-0215Robustness features for Kubernetes clustersv1--
scs-0216Requirements for testing cluster-stacksv1--
scs-0217Kubernetes cluster hardeningv1--
scs-0218Container registry for SCS standard implementationv1--
scs-0219KaaS Networking Standard-v1-
Supplement: Implementation Notesw1--
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0200/index.html b/standards/kaas/scs-0200/index.html new file mode 100644 index 0000000000..4406a0c675 --- /dev/null +++ b/standards/kaas/scs-0200/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0200: Using Sonobuoy for KaaS conformance tests | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0210/index.html b/standards/kaas/scs-0210/index.html new file mode 100644 index 0000000000..1af2e1d7a4 --- /dev/null +++ b/standards/kaas/scs-0210/index.html @@ -0,0 +1,27 @@ + + + + + +scs-0210: SCS K8S Version Policy | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0210: SCS K8S Version Policy

+
VersionTypeStatestabilizeddeprecated
scs-0210-v1StandardDeprecated2023-02-072024-02-08
scs-0210-v2StandardStable2024-02-08-
+

Supplement: Implementation and Testing Notes

+
VersionStatestabilizeddeprecated
w1Draft--
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0211/index.html b/standards/kaas/scs-0211/index.html new file mode 100644 index 0000000000..70796a48c5 --- /dev/null +++ b/standards/kaas/scs-0211/index.html @@ -0,0 +1,31 @@ + + + + + +scs-0211: SCS KaaS default storage class | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0211: SCS KaaS default storage class

+

The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS). +The standard ensures that the default StorageClass, identified by the "storageclass.kubernetes.io/is-default-class" +annotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or +host hardware failures.

+
VersionTypeStatestabilizeddeprecated
scs-0211-v1StandardStable2023-02-13-
scs-0211-v2StandardDraft--
+

Supplement: Implementation and Testing Notes

+
VersionStatestabilizeddeprecated
w1Draft--
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0212/index.html b/standards/kaas/scs-0212/index.html new file mode 100644 index 0000000000..989aa2f289 --- /dev/null +++ b/standards/kaas/scs-0212/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0212: Requirements for container registries | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0213/index.html b/standards/kaas/scs-0213/index.html new file mode 100644 index 0000000000..baafc21307 --- /dev/null +++ b/standards/kaas/scs-0213/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0213: Kubernetes Nodes Anti Affinity | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0214/index.html b/standards/kaas/scs-0214/index.html new file mode 100644 index 0000000000..fec8bc3184 --- /dev/null +++ b/standards/kaas/scs-0214/index.html @@ -0,0 +1,27 @@ + + + + + +scs-0214: Kubernetes Node Distribution and Availability | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0214: Kubernetes Node Distribution and Availability

+
VersionTypeStatestabilizeddeprecated
scs-0214-v1StandardStable2024-02-08-
scs-0214-v2StandardStable2024-11-21-
+

Supplement: Implementation and Testing Notes

+
VersionStatestabilizeddeprecated
w1Draft--
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0215/index.html b/standards/kaas/scs-0215/index.html new file mode 100644 index 0000000000..55e3ca9c09 --- /dev/null +++ b/standards/kaas/scs-0215/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0215: Robustness features for Kubernetes clusters | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0216/index.html b/standards/kaas/scs-0216/index.html new file mode 100644 index 0000000000..ac6ddc3051 --- /dev/null +++ b/standards/kaas/scs-0216/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0216: Requirements for testing cluster-stacks | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0217/index.html b/standards/kaas/scs-0217/index.html new file mode 100644 index 0000000000..e993969275 --- /dev/null +++ b/standards/kaas/scs-0217/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0217: Kubernetes cluster hardening | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0218/index.html b/standards/kaas/scs-0218/index.html new file mode 100644 index 0000000000..3574ddeb46 --- /dev/null +++ b/standards/kaas/scs-0218/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0218: Container registry for SCS standard implementation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0218: Container registry for SCS standard implementation

+
VersionTypeStatestabilizeddeprecated
scs-0218-v1Decision RecordDraft--
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0219/index.html b/standards/kaas/scs-0219/index.html new file mode 100644 index 0000000000..32f9e950d2 --- /dev/null +++ b/standards/kaas/scs-0219/index.html @@ -0,0 +1,27 @@ + + + + + +scs-0219: KaaS Networking Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0219: KaaS Networking Standard

+
VersionTypeStatestabilizeddeprecated
scs-0219-v1StandardStable2024-11-21-
+

Supplement: Implementation Notes

+
VersionStatestabilizeddeprecated
w1Draft--
+ + \ No newline at end of file diff --git a/standards/ops/index.html b/standards/ops/index.html new file mode 100644 index 0000000000..8e479ebda0 --- /dev/null +++ b/standards/ops/index.html @@ -0,0 +1,36 @@ + + + + + +Ops Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Ops Standards

+

Operational Tooling Standards cover the protocols and guidelines associated with tools and utilities used for monitoring, management, and maintenance of the cloud environment. This includes standards for status pages, alerts, logs, and other operational tools, aiming to optimize the reliability, performance, and security of cloud services and resources.

+

*Legend to the column headings and entries:

+
    +
  • Document states: Draft, Effective, Deprecated (and no longer effective)
  • +
  • Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future
  • +
  • Entries in the effective column marked with a † will turn deprecated in the near future
  • +
+ + + +
+
StandardDescriptionDraftEffectiveDeprecated*
scs-0400Status Page create decisionv1--
scs-0401Status page reference implementation decisionv1--
scs-0402Status page OpenAPI decisionv1--
scs-0403Architecture for the Cloud Service provider Observability System for the KaaS Layerv1--
scs-0410Gnocchi as database for meteringv1--
scs-0411Push-based approach for providing usage datav1--
scs-0412Exposition of IaaS metering data as JSONv1--
+ + \ No newline at end of file diff --git a/standards/ops/scs-0400/index.html b/standards/ops/scs-0400/index.html new file mode 100644 index 0000000000..94aa30d5a8 --- /dev/null +++ b/standards/ops/scs-0400/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0400: Status Page create decision | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/ops/scs-0401/index.html b/standards/ops/scs-0401/index.html new file mode 100644 index 0000000000..7386f84851 --- /dev/null +++ b/standards/ops/scs-0401/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0401: Status page reference implementation decision | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0401: Status page reference implementation decision

+
VersionTypeStatestabilizeddeprecated
scs-0401-v1Decision RecordDraft--
+ + \ No newline at end of file diff --git a/standards/ops/scs-0402/index.html b/standards/ops/scs-0402/index.html new file mode 100644 index 0000000000..03af560820 --- /dev/null +++ b/standards/ops/scs-0402/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0402: Status page OpenAPI decision | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0402: Status page OpenAPI decision

+
VersionTypeStatestabilizeddeprecated
scs-0402-v1Decision RecordDraft--
+ + \ No newline at end of file diff --git a/standards/ops/scs-0403/index.html b/standards/ops/scs-0403/index.html new file mode 100644 index 0000000000..af70f7b067 --- /dev/null +++ b/standards/ops/scs-0403/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer

+
VersionTypeStatestabilizeddeprecated
scs-0403-v1Decision RecordDraft--
+ + \ No newline at end of file diff --git a/standards/ops/scs-0410/index.html b/standards/ops/scs-0410/index.html new file mode 100644 index 0000000000..6c938459d7 --- /dev/null +++ b/standards/ops/scs-0410/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0410: Gnocchi as database for metering | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0410: Gnocchi as database for metering

+
VersionTypeStatestabilizeddeprecated
scs-0410-v1Decision RecordDraft--
+ + \ No newline at end of file diff --git a/standards/ops/scs-0411/index.html b/standards/ops/scs-0411/index.html new file mode 100644 index 0000000000..6939cf37f5 --- /dev/null +++ b/standards/ops/scs-0411/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0411: Push-based approach for providing usage data | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0411: Push-based approach for providing usage data

+
VersionTypeStatestabilizeddeprecated
scs-0411-v1Decision RecordDraft--
+ + \ No newline at end of file diff --git a/standards/ops/scs-0412/index.html b/standards/ops/scs-0412/index.html new file mode 100644 index 0000000000..2a5d7fba62 --- /dev/null +++ b/standards/ops/scs-0412/index.html @@ -0,0 +1,30 @@ + + + + + +scs-0412: Exposition of IaaS metering data as JSON | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

scs-0412: Exposition of IaaS metering data as JSON

+

The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format +within the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with +their existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format +provided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation +layers and implementation components.

+
VersionTypeStatestabilizeddeprecated
scs-0412-v1StandardDraft--
+ + \ No newline at end of file diff --git a/standards/scs-0001-v1-sovereign-cloud-standards/index.html b/standards/scs-0001-v1-sovereign-cloud-standards/index.html new file mode 100644 index 0000000000..866925dbf9 --- /dev/null +++ b/standards/scs-0001-v1-sovereign-cloud-standards/index.html @@ -0,0 +1,302 @@ + + + + + +Sovereign Cloud Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Sovereign Cloud Standards

Introduction

+

The Sovereign Cloud Stack (SCS) provides standards +for a range of cloud infrastructure types. +It strives for interoperable and sovereign cloud stacks +which can be deployed and used by a wide range of organizations and individuals. +Wherever feasible, +transparency and openness both in respect to the inner workings of the platforms standardised by SCS, +as well as the SCS organization itself +are a paradigm we intend to live.

+

Requirements

+

The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

+

In addition, "FORBIDDEN" is to be interpreted equivalent to "MUST NOT".

+

Sovereign Cloud Standard documents

+

One of the main products of the SCS organisation are Sovereign Cloud Standard documents.

+

Types of documents

+

Procedural

+

A procedural SCS document describes a process, a policy or a guideline +to which the SCS community adheres.

+

Standard

+

A standard SCS document describes a technical standard for SCS compliant clouds. +Note that it may not be necessary for all clouds to implement all standards.

+

Decision Record

+

Sometimes during the development of the SCS standard, +a complex technical decision needs to be taken, +which does not directly result in a new standard.

+

The SCS document format formally integrates +the documentation of such decisions +as documents of type Decision Record.

+

Supplement

+

A supplement extends a Standard with additional information, such as implementation and testing notes, +that is merely informative, but not authoritative, and that may be subject to change more frequently +than the standard itself.

+

Document format

+

The SCS documents are provided in GitHub flavored markdown. +Each document is assigned a unique number. +To disambiguate with other organisations using similar schemes +(such as XEPs, PEPs or IETF RFCs), +the numbers are prefixed with SCS-.

+

To allow a concept to evolve while allowing breaking changes, +each SCS document is associated with a major version number. +This major version number is a positive number +and the numbering starts at one for each document.

+

In order to make organisation of the SCS documents easier, +each document also has a slugified title. +The slugified title MUST NOT be changed after the acceptance of the document into the repository, +as it is part of its canonical URL. +It MUST consist only of lower-case ASCII letters, numbers and hyphens. +It MUST NOT start with a hyphen and SHOULD start with a lower-case letter. +It SHOULD NOT contain more than one subsequent hyphen.

+

The file name of an SCS document is formed using the following pattern: +scs-XXXX-vN-T.md, where +XXXX is replaced with the zero-padded document number, +N is replaced with the major version of the document, and +T is replaced with the slugified title. +For a document with the number 190, with a major version number 2 and a slugified title flavor-naming, +the resulting file name would be scs-0190-v2-flavor-naming.md.

+

Supplements deviate from this pattern in that they employ a w instead of a v in front of the version +number, and each supplement uses the same document number as the main document it is extending.

+

The second digit in XXXX describes the track where the document belongs:

+
TrackNumber
Global0
IaaS1
KaaS2
IAM3
Ops4
+

In addition to the number, each document has the following metadata, +embedded in the markdown header.

+
Field nameRequirementDescription
typeREQUIREDone of Procedural, Standard, Decision Record, or Supplement
statusREQUIREDone of Draft, Stable, Deprecated, or Rejected
trackREQUIREDone of Global, IaaS, KaaS, IAM, Ops
supplementsREQUIRED precisely when type is Supplementlist of documents that are extended by this document (e.g., multiple major versions)
deprecated_atREQUIRED if status is DeprecatedISO formatted date indicating the date after which the deprecation is in effect
stabilized_atREQUIRED if status was ever StableISO formatted date indicating the date after which the document was considered stable
rejected_atREQUIRED if status is RejectedISO formatted date indicating the date on which the document was rejected
replaced_byRECOMMENDED if status is Deprecated or Rejected, FORBIDDEN otherwiseList of documents which replace this document.
replacesOPTIONALList of documents which this document replaces.
+

Sections

+

Standard

+

Each Standard document MUST have the following sections:

+
    +
  • An Introduction providing context on the document and linking to other relevant materials.
  • +
  • A Motivation section which details why this document or the thing it describes is necessary.
  • +
  • A section containing the actual standardization decision.
  • +
  • A Conformance Tests section that contains hints on how to validate +conformance with this spec, ideally links to conformance test cases.
  • +
+

We also RECOMMEND the following sections:

+
    +
  • A Terminology section which briefly describes terms used in the document, including possible abbreviations.
  • +
+

In addition, the following OPTIONAL sections should be considered:

+
    +
  • A Design Considerations section for Standard type documents, +which details other choices +which have been considered for the specific feature +but were ultimately rejected.
  • +
  • An Open Questions section which links to issues +detailing any open discussion points with respect to a document. +This section is RECOMMENDED during the discussion phase (pre 1.0.0) +as a "table of contents" of things to work on in that context.
  • +
  • A Related Documents section which references related Standards +or Decisions, both upstream and/or other SCS documents.
  • +
+

Decision Record

+

Each Decision Record document MUST have the following sections:

+
    +
  • An Abstract providing a brief introduction on the topic of the document.
  • +
  • A Context section describing the issue relevant for motivating this Decision Record.
  • +
  • A section containing the actual decision that is introduced. The section should also include +reasoning for this decision.
  • +
+

We also RECOMMEND the following sections:

+
    +
  • A Terminology section which shortly describes terms used in the document, including possible abbreviations.
  • +
  • A Related Documents section which references related Standards +or Decisions, both upstream and/or other SCS documents.
  • +
+

In addition, the following OPTIONAL sections should be considered:

+
    +
  • A Consequences section describing outcomes from implementing the changes described.
  • +
+

Process

+

The lifecycle of an SCS document goes through the following phases: +Draft, Stable, Deprecated, and Rejected.

+ +

All decisions for phase transitions follow loose consensus, +where the group which has to form the consensus depends on the track of the document:

+
    +
  • IaaS: The team working on infrastructure-as-a-service topics
  • +
  • KaaS: The team working on Kubernetes-as-a-service topics
  • +
  • Ops: The team working on operations topics
  • +
  • IAM: The team working on identity and access management topics
  • +
  • Global: The entire SCS community
  • +
+

Supplements may be kept in Draft state, because they are not authoritative.

+

Proposal phase

+

Proposal of a new document

+

To propose a new SCS document, +a community participant creates a pull request on GitHub +against the standards repository in the SovereignCloudStack organisation. +In the beginning, the pull request will contain a draft of an SCS document and +the community participant should present it to the SCS community. +They may refer to the SCS Community page +for an overview of applicable means of communication and online meetings +to get in touch with the SCS community. +Community participants are encouraged to present their proposal to the SCS community early on. +Note that the proposal draft's content does not need to be finished in any way at this stage.

+

The pull request for the proposal MUST add exactly one SCS document, +in the Standards folder. +In the proposal phase, +the document number MUST be replaced with xxxx in the file name, +except for a Supplement, which uses the document number of the document it refers to. +The major version MUST be 1.

+

For a document with a slugified title flavor-naming, +the file name would for instance be scs-xxxx-v1-flavor-naming.md; +for a Supplement of scs-0100-v3-flavor-naming.md, +the file name might be scs-0100-w1-flavor-naming-implementation-testing.md (note the w1!).

+

The metadata MUST indicate the intended track and type of the document, +and the status MUST be set to Draft; +for a Supplement, the supplements field MUST be set +to a list of documents (usually containing one element).

+

Upon acceptance by the group of people identified by the track, +a number is assigned +(the next unused number) +and the proposer is asked +to rename the file to replace the xxxx with that number +before the merge of the pull request.

+

Note: +Documents on the Design Record track MAY be proposed or accepted directly into Stable state, +if no further discussion is required.

+

Hereafter, +the pull request can be merged +and henceforth the document is an official SCS document in Draft state.

+

Proposal of a major update to a stable document

+

To propose major update to a Stable SCS document, +a community participant creates a pull request on GitHub +against the standards repository in the SovereignCloudStack organisation.

+

The pull request MUST add exactly one SCS document, +in the Standards folder. +The document number MUST be the same as the document it is updating, +and the major version number MUST be incremented by 1. +The slugified title MAY be changed.

+

It MUST refer to the old document in its replaces metadata. +The pull request SHOULD NOT modify the previous document; +deprecation of the previous document +as well as adding the replaced_by metadata is a separate step, +and can only be executed once the new document is Stable.

+

For a document updating a hypothetical SCS-0390-v3 document, +the file name may be scs-0390-v4-flavor-naming-this-time-its-serious.md.

+

Other than the file naming difference, +the proposal process is the same as for new documents. +In particular, the new document starts out in Draft state +and does not automatically become part of the normative corpus of an SCS release.

+

Development phase (Draft)

+

In this phase, +the document is developed inside the SCS community.

+

It should not be considered to be normative for any SCS release, +even if an SCS release happens after the acceptance of the document.

+

Experimental and exploratory implementations are encouraged, +however, implementors must be prepared for breaking changes.

+

Changes to the documents are gated through pull requests.

+

Stabilized phase (Stable)

+

Once the document is deemed ready for production use, +its status is changed to Stable.

+

If the document in question is a Standard +(and if applicable), +the following conditions MUST all be satisfied before stabilizing:

+
    +
  • the corresponding conformance tests have been implemented +according to the general guidelines,
  • +
  • they have been shown to work with the reference implementation,
  • +
  • they are documented in the standard or one of its Supplement +documents.
  • +
+

After stabilization, +changes to the document which may render existing implementations non-conformant +MUST NOT be made.

+

If a breaking change to an existing SCS document is deemed necessary, +a new document with a new number shall be created +and the old document SHOULD be deprecated.

+

Deprecation phase (Deprecated)

+

When a document is no longer deemed fit for production use, +it can be marked as deprecated.

+

Deprecations SHOULD be announced ahead of their execution by setting the +deprecated_at field to a future date and moving the status to Deprecated. +This signals current and future implementors +that the subject of the document +is not considered necessary or state of the art anymore.

+

If one or more replacement documents for the document exists, +it MUST be listed in the replaced_by metadata field.

+

Rejection

+

If a document is removed from the normative corpus of SCS standards, +its status is changed to Rejected.

+

If one or more replacement documents for the document exists, +it MUST be listed in the replaced_by metadata field.

+

Open Questions

+

Stabilization criteria

+

When should a document be stabilized? +Should we require at least one public implementation? +Should we require a minimum experimental time? +What about non-Standard track documents?

+

Breaking change criteria

+

When is a change breaking and cannot be applied to a Stable document? +What about previously undefined behaviour (uncovered edge case)? +What about ambiguous wording? +Do we need a separate "Errata" section?

+

Design Considerations

+

Versioning

+

An alternative to the proposed scheme for stabilization +is the use of SemVer-like versioning.

+

In that case, one would have an individual version number with each document, +where a major version greater than zero indicates a stable document. +The Stable state would be merged with Draft state into an Active state +and shared between the stabilized and the development phase.

+

The advantages of such an approach are:

+
    +
  • It is easy to recognize whether an SCS document has changed between two SCS +releases, just by looking at the released version number.
  • +
  • It is possible to make breaking changes after stabilization by increasing the +major version number.
  • +
+

The disadvantages of that approach are:

+
    +
  • +

    It is possible to make breaking changes after stabilization. +Potentially, a hypothetical SCS-1234 document might refer to something completely different +in a hypothetical R15 release than what it meant in R5, +if there have been sufficient, gradual breaking changes to the document.

    +

    That means that for proper linking, +it would be required to always include the major version number +when referring to an SCS document.

    +

    This implies having to keep all former versions around in a canonical, linkable form. +This induces non-trivial organizational and editorial overhead +and raises questions around which changes are acceptable to "archived" versions, +if any.

    +
  • +
  • +

    It would require a clone of the SemVer spec, +as that spec is highly specific toward software +and does not fully +(at least not in the standard-as-written) +cover specifics of a standards organisation's use-cases.

    +
  • +
+

Acknowledgements

+

This document is heavily inspired by XEP-0001, as published by the XMPP Standards Foundation.

+ + \ No newline at end of file diff --git a/standards/scs-0002-v1-standards-docs-org/index.html b/standards/scs-0002-v1-standards-docs-org/index.html new file mode 100644 index 0000000000..e4899d8053 --- /dev/null +++ b/standards/scs-0002-v1-standards-docs-org/index.html @@ -0,0 +1,52 @@ + + + + + +Standards, Docs and Organisation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Standards, Docs and Organisation

Introduction

+

The old Docs repository had a subdirectory Design-Docs/ which holds Docs on +Design Considerations, older Architecture Decision Records (ADRs) and even +Standards. It also has a Design-Docs/tools/ subdirectory with conformance +checks and our overall conformance check driver (from PR#182).

+

Motivation

+

This directory structure is confusing in a number of ways:

+
    +
  • The conformance checks are hard to find.
  • +
  • The mixture of document types requires searching at two or three places.
  • +
+

We want to improve this (while avoiding unnecessary churn).

+

Suggested cleanup (step 1)

+
    +
  • Move Design-Docs/tools/ contents to Tests/ +
      +
    • Also create subdirectories then for layers and test, while the overall +conformance check tool, certification specs and README remain in Tests/.
    • +
    +
  • +
  • Rename Design-Docs/ to Drafts/. +
      +
    • Use individual PRs to rewrite existing ADRs and Standards there to conform +to our standards and move them over to Standards/.
    • +
    +
  • +
+

Some documents with findings will remain in the Drafts directory. +We may want to categorize these and have a folder e.g. for research results.

+ + \ No newline at end of file diff --git a/standards/scs-0002-v2-standards-docs-org/index.html b/standards/scs-0002-v2-standards-docs-org/index.html new file mode 100644 index 0000000000..5b350f0451 --- /dev/null +++ b/standards/scs-0002-v2-standards-docs-org/index.html @@ -0,0 +1,104 @@ + + + + + +SCS Documentation structure | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Documentation structure

Introduction

+

The Sovereign Cloud Stack (SCS) is a complex ecosystem, comprised of numerous Components and packages designed to accommodate a wide array of use cases. Given the unique functionalities of these components, the creation of a unified and comprehensible documentation presents a significant challenge. This procedural standard aims to define the structure and maintenance process for our documentation, thereby offering seamless and efficient access to users.

+

Motivation

+

SCS promotes a collaborative environment by actively contributing to upstream projects. The involvement of individuals and companies within our community significantly enhances the SCS Bill of Materials (BOM), further amplifying its complexity. Consequently, our documentation must:

+
    +
  • Offer an overview and visual representation of the architectural model
  • +
  • Foster coherence by maintaining a consistent theme throughout the documentation
  • +
  • Facilitate a transparent and inclusive community environment
  • +
  • Describe various deployment examples and use cases
  • +
  • Reflect the SCS structure in the documentation's navigation
  • +
+

Distributed Documentation

+

In line with the OpenStack documentation approach, most SCS Components and components maintain independent documentation. To keep this documentation up-to-date and eliminate manual duplication, we utilize a custom workflow that synchronizes individual documents during the static documentation page's build process.

+

Methodology and Taxonomy

+

Addressing the complexity of SCS requires an effective documentation structure. Accordingly, we have adopted the Diataxis taxonomy, categorizing the documentation into four distinct sections: Tutorials, Guides, References, and Explanations.

+

Structure Template

+

The technical documentation and navigation should parallel the logical structure of the SCS Architecture. By doing so, users can better comprehend the information hierarchy and effectively visualize the SCS. The proposed structure is as follows:

+
├── Introduction
├── Getting Started
│ ├── Overview
│ ├── Virtualization
│ └── Containerization
├── IaaS Layer
│ ├── Overview
│ │ ├── Architecture
│ │ ├── Compute
│ │ ├── Storage
│ │ ├── Knowledge
│ │ └── Network
│ ├── Deployment Examples
│ │ ├── Example 1
│ │ │ ├── Hardware
│ │ │ └── Software
│ │ ├── ...
│ │ │ ├── Hardware
│ │ │ └── Software
│ │ └── Example x
│ │ ├── Hardware
│ │ └── Software
│ ├── Guides
│ │ ├── Guide 1
│ │ ├ ...
│ │ └── Guide x
│ └── Components
│ ├── Component 1
│ ├ ...
│ └── Component x
├── Container Layer
│ ├── Overview
│ │ ├── Architecture
│ │ └── ...
│ ├── Prerequisites
│ │ ├── Hardware
│ │ ├── Software
│ │ └── Knowledge
│ ├── Guides
│ │ ├── Guide 1
│ │ ├── ...
│ │ └── Guide x
│ └── Components
│ ├── k8s-cluster-api-provider
│ ├ ...
│ └── Component x
├── Operating SCS
│ ├── Overview
│ ├── Guides
│ │ ├── Guide 1
│ │ ├── ...
│ │ └── Guide x
│ ├── Monitoring
│ ├── Incident Management
│ ├── Audits
│ ├── Lifecycle Management: Patches/Updates & Upgrades
│ └── Logging
├── Identity and Access Management (IAM)
├── Releases
├── Standards
├── FAQ
└── Glossary
+

Single Component/Component

+

The technical documentation and navigation should parallel the logical structure of the SCS Architecture. By doing so, users can better comprehend the information hierarchy and effectively visualize the SCS. The proposed structure is as follows:

+
│        ├── Component
│ │ ├── overview.md
│ │ └── requirements.md
│ │ ├── quickstart.md
│ │ ├── configuration.md
│ │ ├── contribute.md
+

Each document serves a specific purpose:

+

Overview

+

This document introduces the Component/component by addressing the basic "Why," "How," and "What" questions, and articulating the problems it solves in the broader SCS context answering the following questions:

+
    +
  • What is it and for what do I need this? What benefits does it have for users?
  • +
  • What organization/company does this belong to? (Link to company/organization)
  • +
  • Where am I – as module – within the bigger context of SCS?
  • +
+

Requirements

+

This section enumerates the necessary prerequisites to utilize the component, including software, hardware, and any required technical knowledge. What are the minimal requirements needed for a quickstart?

+

Quickstart

+

A concise guide providing users with a quick set up of the component, covering installation instructions, basic configuration, and initial steps. Caution: it is only for testing and not for production.

+
    +
  • What is the aim of this quickstart guide?
  • +
  • Rule: one line per command for easy copy&paste and one line for description where possible
  • +
  • Rule: only one working path for installation.
  • +
+

Configuration

+

This section elaborates on the configurable aspects of the component, such as options, parameters, or settings that users can modify to suit their needs.

+

Contribute

+

This document provides instructions on how interested parties can contribute to the component's development. It includes information on issue submission, proposed changes, and participation in discussions.

+

Technical Implementation

+

SCS employs Docusaurus, a contemporary static website generator, to implement the Docs Standard. Docusaurus serves as an ideal platform for creating, managing, and deploying extensive documentation.

+

Documentation Framework

+

Docusaurus' robust toolkit assists in crafting and maintaining quality documentation. It offers comprehensive features such as Markdown support, customizable themes, and versioning, making it an excellent choice for our needs. This platform allows us to create user-friendly and visually engaging documentation.

+

Special Implementation Details

+

The unique architecture of SCS necessitates a unique approach to documentation. To ensure seamless integration of reference documentation for Components and components developed for SCS, we have created a custom workflow. This workflow automatically syncs upstream repositories, pulling the most recent documentation at regular intervals.

+

We have accomplished this by utilizing a Node.js post-install script found here.

+

This script prompts the system to pull the latest docs every eight hours and build the static page. The workflow's specifications can be viewed here.

+

The SCS documentation is built by the tooling from the docs-page repository, pulling content from docs repository as well as many other components as defined in the docs.package.json here.

+

Writing Style and Format – Style Guide

+

Formatting and Linting

+

All documentation text files must be provided as markdown files with an .md extension. This prerequisite ensures uniformity across our documents, making them more accessible and comprehensible.

+

Diagrams, Charts, and Images

+

When necessary, diagrams, charts, and images can be used to simplify complex information. They should be properly captioned and referenced in the text.

+

Linting

+

To maintain a clean and consistent content repository, we enforce linting on:

+
    +
  • All staged files before committing
  • +
  • All Pull Requests
  • +
+
Pre Commit
+

We run markdownlint against staged Git files using the Husky Git hook. This process is facilitated by lint-staged and husky.

+

The markdown files are linted according to the rules specified by markdownlint-cli2 and formatted with prettier.

+

The linting rules are specified in the configuration file .markdownlint-cli2.jsonc. Additionally, markdownlint-rule-search-replace

+
GitHub Workflows
+

There are two actions running on every Pull Request on the main branch:

+
    +
  1. link-validator.yml validates every link in the markdown files.
  2. +
  3. pr-markdownlint.yml checks all markdown files according to the rules defined within .markdownlint-cli2.jsonc.
  4. +
+

The Style Guide can be found here.

+

Open Questions

+

--

+

Reference

+

--

+ + \ No newline at end of file diff --git a/standards/scs-0003-v1-sovereign-cloud-standards-yaml/index.html b/standards/scs-0003-v1-sovereign-cloud-standards-yaml/index.html new file mode 100644 index 0000000000..30fec22392 --- /dev/null +++ b/standards/scs-0003-v1-sovereign-cloud-standards-yaml/index.html @@ -0,0 +1,240 @@ + + + + + +Sovereign Cloud Standards YAML | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Sovereign Cloud Standards YAML

Introduction

+

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.

+

SCS plans to offer six kinds of certificates with varying scope. These scopes can be sorted into two dimensions:

+
    +
  1. certification level, of which there are three: +
      +
    • SCS-compatible
    • +
    • SCS-open
    • +
    • SCS-sovereign
    • +
    +
  2. +
  3. cloud layer, of which there are two: +
      +
    • infrastructure as a service (IaaS)
    • +
    • Kubernetes as a service (KaaS)
    • +
    +
  4. +
+

So, for instance, a certificate can have the scope SCS-compatible IaaS or SCS-sovereign KaaS. +Note that we don't currently have separate certification layers for Operations and IAM. +We expect that tests for these aspects will exist, but be incorporated into the IaaS +and KaaS layers.

+

Each certificate scope amounts to a set of standards that have to be fulfilled by the cloud service in question in order for a certificate to be issued. +In addition, a certificate with a certain scope may only be issued if some other certificate is already held. +Case in point: the certification levels are meant to be seen as a progression, where the upper levels build on the lower ones, and +the certificate for "SCS-open IaaS" will only be issued if a certificate for "SCS-compatible IaaS" is already held. +We say that the latter certificate is a prerequisite of the former.

+

Naturally, as the state of the art progresses, so do our certificates. We keep track of the changes by means of versioning. +That is to say that each certificate scope can come in several versions, each one of them having its distinct timespan when it is in effect. +For instance, we might have

+
    +
  • SCS-compatible IaaS v1, effective 2021-01-01 through 2023-10-31
  • +
  • SCS-compatible IaaS v2, effective 2023-03-23 through 2023-11-30
  • +
+

and so on (but usually, we aim to keep at most two versions in effect, with an overlap of 4 to 6 weeks).

+

This decision record describes two main points:

+
    +
  1. How we denote our certificate scopes by means of a YAML file.
  2. +
  3. Our process for constructing and progressing the certificate scopes.
  4. +
+

Motivation

+

This decision record establishes a mechanism (by means of the YAML file) with the following three main objectives:

+
    +
  • to provide an overview of the mandatory standards for the different SCS certificate scopes
  • +
  • to make the lifecycle of certificate scopes traceable
  • +
  • to provide a machine-readable document for further processing (e.g. for a compliance tool suite or continuous integration).
  • +
+

Overview of mandatory SCS standards

+

Digging through a repository of draft, stable, replaced and rejected standards becomes increasingly challenging with a growing number +documents and decision records. A central document that lists all mandatory standards to acquire a certificate with a certain scope can +resolve this issue. It provides clarity for providers as well as users and helps to understand the value +proposition of SCS.

+

Lifecycle of certificate scopes

+

Standards and therefore certifications will evolve over time. To provide transparency and traceability for the lifecycle of SCS certificate +scopes, the whole history of our certifications should be recorded. Pre-notification of changes to our certificate scopes allows +users to adapt their environments or deployment automation to the new standards in advance.

+

Machine-readability for further processing

+

By providing a machine-readable document, we can generate web-friendly overviews of our certificate scopes as well as create a tool suite +that checks environments against all described standards.

+

Basic concepts

+

The introduction stated that a certificate scope amounts to a set of standards that have to be fulfilled by the cloud service in question in order for a certificate to be issued. +While instructive, this view is still a bit simplified. Let's get more precise now by defining the following concepts.

+
    +
  1. (Test) subject: +The cloud under test.
  2. +
  3. Test case (also spelled testcase in code): +A statement about the subject that can be evaluated unambiguously to be either satisfied or not. The result is either PASS or FAIL, or—if the test could not be performed—DNF (did not finish). +A test case can be as simple as "the subject conforms to standard X", but a standard can also be decomposed into multiple test cases, which can then be reported on (also to the customers) individually. +This latter option has the advantage that we can show explicitly if the subject complies with optional parts of the standard.
  4. +
  5. Check: +A script that determines and reports the results of certain test cases. The report is printed to stdout, and each test case is reported as a single line of the form testcase-id: [PASS/FAIL]. The result DNF is not reported. Lines of other forms are permissible and will be ignored. +We also occasionally extend the concept of check to manual audits.
  6. +
  7. Module: +A collection of test cases and corresponding checks, together with additional meta information such as the result lifetime, description, and a list of tags for a test case. +Ultimately, we aim to specify one module for each version of each standard: the module translates the standard into something measurable and, ideally, executable to be used for certification.
  8. +
  9. Selector (expression): +An expression used to select test cases by referring to the tags that must (or must not) be present.
  10. +
  11. Target: +A named collection of test cases specified using selector expressions. +Ultimately, the certification of a subject always depends on a designated "main" target; all its test cases must be passed for the certificate to be awarded. +Further targets can be used to report on optional aspects of the certificate, such as particularly good security and encryption measures.
  12. +
  13. (Certificate-scope) version: +A collection of modules and a collection of targets, one of them being "main". +Note that a collection of modules can again be construed as a (larger) module. We opt to use one module per standard version, as mentioned above, in order to make commonalities between certificate-scope versions explicit.
  14. +
  15. Certificate scope: +A list of certificate-scope versions.
  16. +
+

Having introduced these concepts, we can now get even more precise by defining the actual specification in YAML format.

+

SCS Certification YAML

+

Each certificate scope is recorded in a dedicated YAML file, e.g. scs-open-kaas.yaml. +For an example of such a file, see +scs-compatible-iaas.yaml or +scs-compatible-kaas.yaml.

+

The certification YAML MUST contain the following keys:

+
KeyTypeDescriptionExample
uuidStringUniversally unique identifierd912d0a5-826a-4b01-bafd-b48f65f76f43
nameStringFull name of this certificate scopeSCS-open KaaS
urlStringValid URL to the latest raw version of this documenthttps://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/scs-open-kaas.yaml
modulesArray of mapsList of module descriptors (described below)(see below)
timelineArray of mapsList of timeline entries (described below)(see below)
versionsArray of mapsList of version descriptors (described below)(see below)
+

A uuid may be generated on the command line using the tool uuidgen or using Python as follows: python3 -c "import uuid; print(uuid.uuid4())"

+

The certification YAML MAY contain the following keys:

+
KeyTypeDescription
prerequisiteMapDescriptor for the prerequisite certificate scope (see below)
variablesArray of StringLists variables that may occur in check tool descriptors
+

The main check tool will expect an assignment for these variables (which is specific to the subject under test), and every occurrence of the variable in the check tool descriptor will be substituted accordingly.

+

Prerequisite descriptor

+

A certificate within a certain level (above SCS-compatible) can only be granted if a valid corresponding certificate of the level below is presented, +where corresponding means: of the same layer. The latter certificate is said to be a prerequisite for the former.

+

We implement this logic by allowing for the designation of a certificate scope as a prerequisite; +then a certificate of that prerequisite scope has to be presented before the certificate of the scope in question can be granted.

+
KeyTypeDescriptionExample
nameStringFull name of the certificate scopeSCS-compatible IaaS
urlStringValid URL to the latest raw version of the certificate scopehttps://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/scs-compatible-iaas.yaml
+

Version descriptor

+
KeyTypeDescriptionExample
versionStringrequired: version of the particular list of standardsv3
includeArrayrequired: list of module ids or include descriptors (see below)[scs-0100-v3]
targetsMap of mapsrequired: this maps target names to selector expressions (explained below)main: mandatory
stabilized_atDateISO formatted date indicating the date after this version is considered stable.2022-11-09
+

The ids of the test cases of all the modules specified via include MUST be pairwise different.

+

Once a version descriptor has a stabilized_at field, the version is deemed stable, and the descriptor may no longer be changed.

+

Include descriptor

+

Each include may be specified by means of a module id (i.e., a string) or by an include descriptor:

+
KeyTypeDescriptionExample
refStringid of the module to be includedscs-0100-v3
parametersMapMaps parameter names to parameter valuesimage_spec: https://raw.github...s/scs-0104-v1-images.yaml
+

When the referenced module uses parameters, then these parameters must be assigned values here.

+

Selector expressions

+

In order to define what a selector expression is, we need to define tags, atoms and terms first.

+

A tag is a string that does not contain any space, comma, forward slash, or exclamation mark.

+

Examples: iaas, mandatory, recommended, encryption.

+

An atom is a string that is either (i) a tag or (ii) an exclamation mark followed by tag. +A list of tags satisfies the atom if

+
    +
  • the atom is of form (i) and the tag is contained in the list, or
  • +
  • the atom is of form (ii) and the tag is not contained in the list.
  • +
+

Examples: mandatory, !mandatory.

+

A term is a string that is a non-empty list of atoms joined by slashes. +A list of tags satisfies the term if it satisfies at least one of the atoms.

+

Examples: mandatory, mandatory/recommended, !mandatory/encryption.

+

A selector (expression) is a string that is a non-empty list of terms joined by space. +A list of tags satisfies the selector if it satisfies all the terms.

+

Examples: mandatory, iaas mandatory, iaas !mandatory/encryption.

+

In the map targets above, it is possible to specify a list of selectors that are joined by comma. +(Note that this is still a string, not a YAML list.) +A list of tags satisfies this list of selectors if it satisfies at least one of the selectors.

+

Examples: mandatory iaas, recommended kaas (NOT: [mandatory iaas, recommended kaas])

+

Module descriptor

+
KeyTypeDescriptionExample
idStringid for referring to this modulescs-0100-v3
nameStringname of this moduleFlavor naming v3
urlStringValid URL to relevant documentation (usually a standard document)https://docs.scs.community/standards/scs-0100-v3-flavor-naming
parametersListList of parameters that the checks in this module might use[image_spec]
runArrayList of all checks that should be run; each entry being a check descriptor(see below)
testcasesArrayList of all test cases; each entry being a test-case descriptor(see below)
+

The parameters specified here will be added to the variable assignment for all check tools that belong to this module, so they will be substituted in the same way. +The values to these parameters must be provided in the include descriptor as explained above.

+

Using parameters offers two advantages:

+
    +
  • they may show up in the automatically generated documentation, whereas the check tools themselves probably won't.
  • +
  • multiple versions of a standard can be represented using the same module, if everything that changes between versions can be captured by the parameters.
  • +
+

Check descriptor

+

The following fields are valid for every check descriptor:

+
KeyTypeDescriptionExample
sectionStringOptional what section to associate this check with (sections can be checked in isolation)weekly
+

Additional fields are valid depending on whether the check is automated or manual.

+

Automated check

+
KeyTypeDescriptionExample
executableStringValid local filename (relative to the path of scs-compliance-check.py) of a script that verifies compliance with the particular standardimage-md-check.py
envMapOptional key-value map of environment variables (values may use variables)OS_CLOUD: {os_cloud}
argsStringOptional command-line arguments to be passed to the check_tool (may use variables)-v -k {kubeconfig}
+

As mentioned, variables may be used within env and args; they are enclosed in single braces, like so: {var}. +If a brace is desired, it needs to be doubled: {{ will be turned into {. When the main check tool is run, +each occurrence of a variable will be substituted for according to the variable assignment for the subject under test.

+

Note: the executable could in principle also be given via a URL; however, this is not yet supported due to security considerations.

+

Manual check

+

TBD

+

Test-case descriptor

+
KeyTypeDescriptionExample
idStringIdentifier for this test case (immutable and unique within this module)image-md-check
lifetimeStringOne of: day (default), week, month, quarter; the test result is valid until the end of the next periodweek
tagsList of stringsA tag is a keyword that will be used to select this test case using a selector expression[mandatory]
descriptionStringShort description of the test case
+

A tag MUST NOT contain any of these characters: space, comma, exclamation mark, forward slash.

+

The id of a test case MUST NOT be changed. +Exceptions MAY be made if the test case is not referenced by any stable version.

+

Timeline entry

+

The timeline is a list of timeline entries as detailed below. Each timeline entry represents a time period +starting at a given date and ending immediately before the chronologically next entry, if any, otherwise the +time period extends indefinitely. The list itself SHOULD be sorted by this date in descending order, however +tooling MUST NOT depend on this order.

+
KeyTypeDescriptionExample
dateDateISO formatted date indicating the date when this period begins.2022-11-09
versionsMap of stringsMaps versions to validity codev3: effective
+

The following validity codes are recognized:

+
    +
  • effective: the version can be certified against; it MUST be stable at the start of the period.
  • +
  • warn: the version can be certified against, but a PASS MUST be accompanied by a warning that the version +is about to expire; the version MUST be stable at the start of the period.
  • +
  • draft: the version can be tested against, but not certified; the version need not be stable.
  • +
  • deprecated: the version can be tested against, but not certified.
  • +
+

Any version not listed in versions is considered deprecated.

+

If no other restriction is given, any version listed in version SHOULD be tested against. +This includes any version listed as deprecated; the rationale here is that, while the test subject +can no longer be certified against it, some customers may still work with that version.

+

Note: Compliance with a new (effective) version often implies compliance with an older (deprecated) one. +Including the older one into the test is meant to increase the confidence that this is indeed the case, or, +if it isn't, serves to provide a clear picture of how many test subjects still comply with the old version.

+

Note: We intend to keep only one version in effect, except for a grace period of 4 to 6 weeks, when two versions +are effective at the same time.

+

Process

+

The lifecycle any version of any certificate scope goes through the following phases: +Draft and (optionally) Stable. The phase transition is performed using a pull request.

+ +

The timeline is considered append-only (or rather, prepend-only). A new entry is added using +a pull request.

+

It is possible to use the same pull request to add a new version, stabilize some version, and +add a new timeline entry, if so desired.

+

Each pull request is to be voted upon in the corresponding team meeting. The vote has to be +on the pull request only, i.e., it may not affect any other pull request or issue, and it +must be announced 14 days in advance via the corresponding mailing list.

+

Design Considerations

+

File format

+

In order to have a document that can be processed by a wide range of tools, we need to opt for a simple but yet well-supported format. +YAML offers readability for humans as well as good support by many frameworks. Since YAML is heavily used in the cloud and container +domain, the choice is obvious.

+

Dependency graph for certifications

+

This standard only allows depending on exactly one certification, otherwise we would need to use a list of mappings. Since this is +in accordance to the current plan of the SIG Standardization & Certification, we can safely ignore multiple dependency of +certification for now.

+

Tooling

+

The SCS repository Docs has a tool scs-compliance-check.py in the Tests directory +which parses the SCS Certification YAML and then runs the tests referenced there, returning the results +of the tests.

+

Open Questions

+

Acknowledgements

+

This document is heavily inspired by the publiccode.yml standard, as published by the Foundation for Public Code.

+ + \ No newline at end of file diff --git a/standards/scs-0004-v1-achieving-certification/index.html b/standards/scs-0004-v1-achieving-certification/index.html new file mode 100644 index 0000000000..346d4fc5af --- /dev/null +++ b/standards/scs-0004-v1-achieving-certification/index.html @@ -0,0 +1,68 @@ + + + + + +Regulations for achieving SCS-compatible certification | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Regulations for achieving SCS-compatible certification

Introduction

+

The Sovereign Cloud Stack (SCS) issues certificates with various scopes, among them SCS-compatible IaaS (infrastructure as a service) and SCS-compatible KaaS (Kubernetes as a service).

+

This document details how a cloud service provider (henceforth also called operator) can attain such a certificate for one of their clouds.

+

Motivation

+

As operator, I want to obtain a certificate with the scope SCS-compatible IaaS or SCS-compatible KaaS.

+

Regulations

+
    +
  1. +

    Each certificate issued pertains to a given cloud, a given scope, and a given version of that scope with a fixed expiry date. The certificate is only valid for that cloud and for the time frame that ends on that expiry date.

    +
  2. +
  3. +

    The operator MUST include the official SCS compliance test suite (which does not require admin privileges) in their continuous test infrastructure (e.g., Zuul). The tests MUST be run at given intervals, depending on their resource-usage classification:

    +
      +
    • light: at least nightly,
    • +
    • medium: at least weekly,
    • +
    • heavy: at least monthly.
    • +
    +

    For public clouds, it is recommended to offer the SCS project access to the infrastructure so the test suite runs can be triggered continuously by the SCS team.

    +

    Alternatively, and for non-public clouds, the results (log files) MUST be submitted to SCS (by a mechanism of SCS' choice) at least weekly, and they need to be reproduced again on request by SCS.

    +
  4. +
  5. +

    If the desired certificate requires manual checks, then the operator MUST offer the SCS project suitable access. Manual checks MUST be repeated once every quarter.

    +
  6. +
  7. +

    Details on the standards achieved, as well as the current state and the history of all test and check results of the past 18 months will be displayed on a public webpage (henceforth, certificate status page) owned by SCS.

    +

    The page will be kept online for the duration of the certificate's validity, plus at least 3 months; afterwards, it can be taken offline, either upon request or in the course of maintenance cleanup. However, the page's content won't be deleted until 12 months after the certificate's expiration, for the page will be reanimated and reused if, within this timeframe, a new certificate is issued for the same scope and the same cloud.

    +
  8. +
  9. +

    The SCS certification assessment body (initially the SCS project in the OSB Alliance e.V., possibly further entities empowered to do so by the SCS trademark owner, currently the OSB Alliance e.V.) WILL review the certification application and either grant the certification, reject it or ask for further measures or information.

    +
  10. +
  11. +

    Once the certificate is granted by the SCS certification assessment body, the operator SHOULD use the corresponding logo and publicly state the certified "SCS compatibility" on the respective layer for the time of the validity of the certification. In case of a public cloud, this public display is even REQUIRED. In any case, the logo MUST be accompanied by a hyperlink (a QR code for printed assets) to the respective certificate status page.

    +
  12. +
  13. +

    If the certificate is to be revoked for any reason, it will be included in a publicly available Certificate Revocation List (CRL). This fact will also be reflected in the certificate status page.

    +
  14. +
  15. +

    If any of the automated tests or manual checks fail after the certificate has been issued, the certificate is not immediately revoked. Rather, the automated tests MUST pass 99.x % of the runs, and the operator SHALL be notified at the second failed attempt in a row at the latest. In case a manual check fails, it has to be repeated at a date to be negotiated with SCS. It MAY NOT fail more than two times in a row.

    +
  16. +
+

Design Considerations

+

Open Questions

+ +

As of now, this document pertains to the certificate scopes on the certification level SCS-compatible only. It will be extended to cover the remaining levels as they become relevant, either directly or by way of referring to additional documents.

+

For details on our mechanisms for developing, denoting, and versioning the certificate scopes, we refer to the document scs-0003-v1.

+ + \ No newline at end of file diff --git a/standards/scs-0005-v1-project-governance/index.html b/standards/scs-0005-v1-project-governance/index.html new file mode 100644 index 0000000000..9371cf7732 --- /dev/null +++ b/standards/scs-0005-v1-project-governance/index.html @@ -0,0 +1,95 @@ + + + + + +Governance of the SCS community | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Governance of the SCS community

Introduction

+

The Sovereign Cloud Stack (SCS) provides standards +for a range of cloud infrastructure types as well as a modular open-source +reference implementation. +The project is governed by the SCS Project Board.

+

Role of the SCS Project Board

+

The role of the SCS Project Board is the overall governance of the SCS Community and Project. +This happens together with the Forum SCS-Standards of the Open Source Business Alliance. To further +underline this alignment, the Forum SCS-Standards is part of the SCS Project Board. +The SCS Project Board itself is elected by the SCS Community.

+

Definitions

+

SCS Project

+

The SCS Project is the Open-Source project that consists of the software, documentation, documents, blog posts as well as the people ("SCS Community") working on this.

+

SCS Community

+

The collective of people, companies, and organizations promoting the idea of the SCS Project as well as the people working on the various aspects.

+

SCS GitHub Organization

+

The SCS GitHub Organization is this: https://github.com/sovereigncloudstack

+

Roles in the SCS GitHub Organization

+

Members

+

Joining the SCS GitHub Organization as a contributor results in being assigned the member role in the organization. Members are contributors or collaborators who:

+
    +
  • Actively contribute to projects within the organization.
  • +
  • Have repository-specific access based on their contributions.
  • +
  • Are eligible to vote in elections and nominate candidates for the SCS Project Board.
  • +
  • Must adhere to the Code of Conduct.
  • +
+

Owners

+

Members of the SCS Project Board are also designated as owners of the SCS GitHub organization. Owners have administrative privileges, including:

+
    +
  • Managing organization-level settings.
  • +
  • Onboarding new members.
  • +
  • Enforcing compliance with governance and community standards.
  • +
+

This alignment ensures that governance roles in the SCS Project Board directly translate into operational responsibilities within the GitHub organization.

+

Joining the SCS GitHub Organization

+

Since being part of the GitHub organization comes with a set of responsibilities, joining the SCS GitHub Organization can be done by:

+
    +
  • being invited by the SCS Project Board
  • +
  • submitting a request to be onboarded as a member to the SCS Project Board
  • +
  • have existing members of the GitHub organization nominate you
  • +
+

One of these items is sufficient.

+

Actively contributing to one or several of the projects under the governance of the SCS project board should typically result in a membership. Please be aware of our Code of Conduct.

+

Election of the SCS Project Board

+

Term

+

The SCS Project Board is elected for the term of one year. Elections are done +within the last six weeks of the calendar year.

+

Seats on the board

+

The SCS Project Board contains five seats. One of these seats is filled by +the delegate of the Forum SCS-Standards. The other four seats are voted upon.

+

Nominations

+

Every person who is part of the Sovereign Cloud Stack GitHub organization can be +nominated for the board. Likewise, one can nominate oneself. +The nomination is done by adding the person with the required data to the file corresponding to the term in the "Community-Governance" folder in the Standards repository. Obviously, the person, that is to be nominated, should be asked before being added to the file.

+

Eligible for voting

+

Every person who is a member of the GitHub organization "Sovereign Cloud Stack" is eligible for voting. In order to be able to vote an onboarding onto the Identity Management of the SCS community needs to happen.

+

Electoral management

+

The voting process is governed by the Forum SCS-Standards. +Voting is done using the Condorcet Internet Voting Service. This is the same system as is being used by the OpenInfra foundation.

+

Voting period

+

The voting will be open for a week.

+

Announcement

+

The voting will be announced on the SCS-Members Mailinglist as well as on the General & Announcements. Enlisted voters will receive e-mails to the email address used in the SCS community's Identity Management system.

+

Mechanisms

+

Each eligible voter is asked to rank the candidates according to their priorities. +The four favorite choices among all voters will be elected into the SCS Project Board.

+

Roles in the SCS Project Board

+

Among the elected Project Board a spokesperson is nominated. The spokesperson is +elected by a simple majority vote among the members of the project board. The +spokesperson is elected for the whole term.

+ + \ No newline at end of file diff --git a/standards/scs-0100-v1-flavor-naming/index.html b/standards/scs-0100-v1-flavor-naming/index.html new file mode 100644 index 0000000000..4979fd2da7 --- /dev/null +++ b/standards/scs-0100-v1-flavor-naming/index.html @@ -0,0 +1,305 @@ + + + + + +SCS Flavor Naming Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Flavor Naming Standard

Introduction

+

This is the standard v1.0 for SCS Release 0. +Note that we intend to only extend it (so it's always backwards compatible), +but try to avoid changing in incompatible ways.

+

Motivation

+

In OpenStack environments there is a need to define different flavors for instances. +The flavors are pre-defined by the operator, the customer can not change these. +OpenStack providers thus typically offer a large selection of flavors.

+

While flavors can be discovered (openstack flavor list), it is helpful for users (DevOps teams), +to have

+
    +
  • A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere.
  • +
  • Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered.
  • +
+

While not all details will be encoded in the name, the key features should be obvious: +Number of vCPUs, RAM, Root Disk. +Extra features are important as well: There will be flavors with GPU support, fast disks for databases, +memory-heavy applications, and other useful aspects of an instance.

+

It may also be important to make the CPU generation clearly recognisable, as this is always a topic in +discussions with customers.

+

Proposal

+

Type of information included

+

We believe the following characteristics are important in a flavour description:

+
TypeDescription
GenerationCPU Generation
Number of CPUNumber of vCPUs - suffixed by L,V,T,C (see below)
Amount of RAMAmount of memory available for the VM
Performance ClassAbility to label high-performance CPUs, disks, network
CPU TypeX86-intel, X86-amd, ARM, RISC-V, Generic
"bms"Bare Metal System (no virtualization/hypervisor)
+

Complete Proposal

+
PrefixCPUSuffixRAM[GiB]optional: Disk[GB]optional: Disk typeoptional: extra features
SCS-NL/V/T/C[i]:N[u][o][:[Mx]N][n/s/l/p][-hyp][-hwv]-[arch[N][h][-[G/g]X[N][:M[h]]][-ib]
+

(Note that N and M are placeholders for numbers here).

+

Proposal Details

+

[REQUIRED] CPU Suffixes

+
SuffixMeaning
Cdedicated Core
Tdedicated Thread (SMT)
VvCPU (oversubscribed)
LvCPU (heavily oversubscribed)
+

Baseline

+

Note that vCPU oversubscription for a V vCPU should be implemented such, that we +can guarantee at least 20% of a core in >99% of the time; this can be achieved by +limiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled) +or by more advanced workload management logic. Otherwise L (low performance) must be +used. The >99% is measured over a month (1% is 7.2h/month).

+

Note that CPUs must use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.). +We expect that microcode gets updated within less than a month of a new release; for CVSS scores above 8, +we expect less than a week. +The provider must enable at least all mitigations that are enabled by default in the Linux kernel. CPUs that +are susceptible to L1TF (intel x86 pre Cascade Lake) must switch off hyperthreading OR (in the future) +use core scheduling implementations that are deemed to be secure by the SCS security team, or declare themselves +as insecure with the i suffix (see below).

+

Higher oversubscription

+

Must be indicated with a L vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and +the lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month).

+

Insufficient microcode

+

Not using these mitigations must be indicated by an additional i suffix for insecure +(weak protection against CPU vulnerabilities through insufficient microcode, lack of disabled hyperthreading +on L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor).

+

Examples

+
    +
  • SCS-2C:4:10n
  • +
  • SCS-2T:4:10n
  • +
  • SCS-2V:4:10n
  • +
  • SCS-2L:4:10n
  • +
  • SCS-2Li:4:10n
  • +
  • SCS-2:**4:10n - CPU suffix missing
  • +
  • SCS-2iT:4:10n - This order is forbidden
  • +
+

[REQUIRED] Memory

+

Baseline

+

We expect cloud providers to use ECC memory. +Memory oversubscription is not recommended. +It is allowed to specify half GiBs (e.g. 3.5), though this is discouraged for larger memory sizes (>= 10GiB).

+

No ECC

+

If no ECC is used, the u suffix must indicate this.

+

Enabled Oversubscription

+

You have to expose this with the o sufffix.

+

Examples

+
    +
  • SCS-2C:4:10n
  • +
  • SCS-2C:3.5:10n
  • +
  • SCS-2C:4u:10n
  • +
  • SCS-2C:4o:10n
  • +
  • SCS-2C:4uo:10n
  • +
  • SCS-2C:4ou:10n - This order is forbidden
  • +
+

[OPTIONAL] Disk sizes and types

+
Disk typeMeaning
nNetwork shared storage (ceph/cinder)
hLocal disk (HDD: SATA/SAS class)
sLocal SSD disk
pLocal high-perf NVMe
+

Baseline

+

Note that disk type might be omitted — the user then can not take any assumptions +on what storage is provided for the root disk (that the image gets provisioned to).

+

It does make sense for n to be requested explicitly to allow for smooth live migration. +h typically provides latency advantages vs n (but not necessarily bandwidth and +also is more likely to fail), s and p are for applications that need low +latency (high IOPS) and bandwidth disk I/O. n storage is expected to survive +single-disk and single-node failure.

+

If the disk size is left out, the cloud is expected to allocate a disk (network or local) +that is large enough to fit the root file system (min_disk in image). This automatic +allocation is indicated with : without a disk size. +If the : is left out completely, the user must create a boot volume manually and +tell the instance to boot from it or use the +block_device_mapping_v2 +mechanism explicitly to create the boot volume from an image.

+

Multi-provisioned Disk

+

The disk size can be prefixed with Mx prefix, where M is an integer specifying that the disk +is provisioned M times.

+

Examples

+
    +
  • SCS-2C:4:10n
  • +
  • SCS-2C:4:10s
  • +
  • SCS-2C:4:10s-bms-z3
  • +
  • SCS-2C:4:3x10s - Cloud creates three 10GB SSDs
  • +
  • SCS-2C:4:3x10s-bms-z3
  • +
  • SCS-2C:4:10 - Cloud decides disk type
  • +
  • SCS-2C:4:10-bms-z3
  • +
  • SCS-2C:4:n - Cloud decides disk size (min_disk from image or larger)
  • +
  • SCS-2C:4:n-bms-3
  • +
  • SCS-2C:4: - Cloud decides disk type and size
  • +
  • SCS-2C:4:-bms-z3
  • +
  • SCS-2C:4:-bms-z3h-GNa:64-ib
  • +
  • SCS-2C:4:-ib
  • +
  • SCS-2C:4 - You need to specify a boot volume yourself (boot from volume, or use block_device_mapping_v2)
  • +
  • SCS-2C:4-bms-z3
  • +
  • SCS-2C:4:3x - Cloud decides disk type and size and creates three of them (FIXME: Is this useful?)
  • +
  • SCS-2C:4:3xs - Cloud decides size and creates three local SSD volumes (FIXME: useful?)
  • +
  • SCS-2C:4:3x10 - Cloud decides type and creates three 10GB volumes
  • +
  • SCS-2C:4:1.5n - You must not specify disk sizes which are not in full GiBs
  • +
+

[OPTIONAL] Hypervisor

+

The default Hypervisor is assumed to be KVM. Clouds, that offer different hypervisors +or Bare Metal Systems should indicate the Hypervisor according to the following table:

+
hypMeaning
kvmKVM
xenXen
vmwVMware
hyvHyper-V
bmsBare Metal System
+

Examples

+
    +
  • SCS-2C:4:10n
  • +
  • SCS-2C:4:10n-bms
  • +
  • SCS-2C:4:10n-bms-z3h
  • +
+

[OPTIONAL] Hardware virtualization / Nested virtualization

+

If the instances that are created with this flavor support hardware-accelerated +virtualization, this can be reflected with the -hwv flag (after the optional +Hypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel) +or svm (AMD) is available. This will be the case on Bare Metal flavors on almost +all non-ancient x86 CPUs or if your virtualization hypervisor is configured to +support nested virtualization. +Flavors without the -hwv flag may or may not support hardware virtualization (as we +recommend enabling nesting, but don't require flavor names to reflect all +capabilities. Flavors may overdeliver ...)

+

Examples

+
    +
  • SCS-2C:4:10 - may or may not support HW virtualization in VMs
  • +
  • SCS-2C:4:10-kvm-hwv
  • +
  • SCS-2C:4:10-hwv - not recommended, but allowed
  • +
  • SCS-2C:4:10-hwv-xen - illegal, wrong ordering
  • +
+

[OPTIONAL] CPU Architecture Details

+

Arch details provide more details on the specific CPU:

+
    +
  • Vendor
  • +
  • Generation
  • +
  • Frequency
  • +
+

Generation and Vendor

+

The generations are vendor specific and can be left out. +Not specifying arch means that we have a generic CPU (x86-64).

+
Generationi (Intel x86-64)z (AMD x86-64) a (AArch64)r (RISC-V)
0pre Skylakepre Zenpre Cortex A76TBD
1SkylakeZen-1 (Naples)A76/NeoN1 classTBD
2Cascade LakeZen-2 (Rome)A78/x1/NeoV1 classTBD
3Ice LakeZen-3 (Milan)A71x/NeoN2 (ARMv9)TBD
4Zen-4 (Genoa)TBD
+

It is recommended to leave out the 0 when specifying the old generation; this will +help the parser tool, which assumes 0 for an unspecified value and does leave it +out when generating the name for comparison. In other words: 0 has a meaning of +"rather old or unspecified".

+

Frequency Suffixes

+
SuffixMeaning
h>2.75GHz all-core
hh>3.25GHz all-core
hhh>3.75GHz all-core
+

Examples

+
    +
  • SCS-2C:4:10n
  • +
  • SCS-2C:4:10n-z
  • +
  • SCS-2C:4:10n-z3
  • +
  • SCS-2C:4:10n-z3h
  • +
  • SCS-2C:4:10n-z3hh
  • +
  • SCS-2C:4:10n-bms-z
  • +
  • SCS-2C:4:10n-bms-z3
  • +
  • SCS-2C:4:10n-bms-z3
  • +
  • SCS-2C:4:10n-bms-z3h
  • +
  • SCS-2C:4:10n-bms-z3hh
  • +
+

[OPTIONAL] Extra features

+

Note that these are optional — it is recommended for providers to encode this information +into the flavor name, so there is a systematic way of differentiating flavors. +Providers could leave it out however, leaving it to extra_specs to make these flavor +capabilities discoverable. Nothing prevents providers from registering the same flavor +under a secondary (or tertiary) name.

+

-GX[N][:M[h]] indicates a Pass-Through GPU from vendor X of gen N with M compute units / SMs / EUs exposed. +-gX[N][:M[h]] indicates a vGPU from vendor X of gen N with M compute units / SMs / EUs assigned.

+

Note that the vendor letter is mandatory, generation and compute units are optional.

+
GPUVendor
NnVidia
AAMD
IIntel
+

Generations could be nVidia (f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, ...), +AMD (GCN-x=0.x, RDNA1=1, RDNA2=2), intel (Gen9=0.9, Xe(12.1)=1, ...), ... +(Note: This may need further work to properly reflect what's out there.)

+

The optional h suffix to the comput unit count indicates high-performance (e.g. high freq or special +high bandwidth gfx memory such as HBM); +h can be duplicated for even higher performance.

+

-ib indicates Infiniband networking.

+

More extensions will be forthcoming.

+

Extensions need to be specified in the above-mentioned order.

+

Proposal Examples

+
ExampleDecoding
SCS-2C:4:10n2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk
SCS-8Ti:32:50p-i18 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe
SCS-1L:1u:51 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific)
SCS-16T:64:200s-GNa:64-ib16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 64 Passthrough nVidia Ampere SMs
SCS-4C:16:2x200p-a14 dedicated Arm64 cores (A78 class), 16GiB RAM, 2x200GB local NVMe drives
SCS-1V:0.51 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)
+

Standard SCS flavors

+

These are flavors expected to exist on standard SCS clouds (x86-64).

+

We expect disk sizes to be 5, 10, 20, 50, 100, 200, 500, 1000GB, 2000GB. +We expect a typical CPU

GiB
ratio of 1:4.

+
vCPU:RAM ratioMandatory Flavors
1:4SCS-1V:4, SCS-1V:4:10
2:8SCS-2V:8, SCS-2V:8:20
4:16SCS-4V:16, SCS-4V:16:50
8:32SCS-8V:32, SCS-8V:32:100
1:2SCS-1V:2, SCS-1V:2:5
2:4SCS-2V:4, SCS-2V:4:10
4:8SCS-4V:8, SCS-4V:8:20
8:16SCS-8V:16, SCS-8V:16:50
16:32SCS-16V:32, SCS-16V:32:100
1:8SCS-1V:8, SCS-1V:8:20
2:16SCS-2V:16, SCS-2V:16:50
4:32SCS-4V:32, SCS-4V:32:100
1:1SCS-1L:1, SCS-1L:1:5
+

Note that all vCPUs are oversubscribed — the smallest 1L:1 flavor allows +for heavy oversubscription (note the L), and thus can be offered very +cheaply — imagine jump hosts ... +Disks types are not specified (and expected to be n or h typically).

+

The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM +compute hosts) to offer all flavors.

+

Note: Compared to previous drafts, we have heavily reduced the variations +on disk sizes — this reflects that for the standard networked cinder +disks, you can pass blockdevice_mapping_v2 on server (VM) creation to +allocate a boot disk of any size you desire. We have scaled the few +mandatory disk sizes with the amount of RAM. For each flavor there is +also one _without a pre-attached disk — these are meant to be used +to boot from a volume (either created beforehand or allocated on-the-fly +with block_device_mapping_v2, e.g. +openstack server create --flavor SCS-1V:2 --block-device-mapping sda=IMGUUID:image:12:true +to create a bootable 12G cinder volume from image IMGUUID that gets tied to the VM +instance lifecycle.)

+

Naming policies

+

To be certified as an SCS compliant x86-64 IaaS platform, you must offer all standard SCS flavors +according to the previous section. (We may define a mechanism that allows exceptions to be +granted in a way that makes this very transparent and visible to clients.)

+

You are allowed to understate your performance; you may implement a SCS-1Vl:1:5 flavor with +a flavor that actually implements SCS-1T:1:5n (i.e. you dedicate a secured hyperthread instead +of high oversubscription) or even SCS-1D:1.5:8s (1 dedicated core, 50% more RAM and a 8GiB SSD).

+

We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V:32:100). +Larger providers that offer more details are expected to still also offer the short variants +for usability and easier portability, even beyond the mandated flavors.

+

You must be very careful to expose low vCPU guarantees (L instead ov V), insecure +hyperthreading/microcode i, non-ECC-RAM u, memory oversubscription o. Note that omitting these qualifiers is +overstating your security, reliability or performance properties and may be reason for +clients to feel betrayed or claim damages. It might, in extreme cases, also cause SCS to withdraw certification +along with public statements.

+

You may offer additional SCS- flavors, following the naming scheme outlined here.

+

You may offer additional flavors, not following above scheme.

+

You must not offer flavors with the SCS- prefix which do not follow this naming scheme. +You must not extend the SCS naming scheme with your own suffices; you are encouraged however +to suggest extensions that we can discuss and add to the official scheme.

+

Note that all letters are case-sensitive. +In case you wonder: Feature indicators are capitalized, modifiers are lower case. +(An exception is the uppercase -G for a passthrough GPU vs. lowercase -g for vGPU.)

+

Rationale

+

Note that we expect most clouds to prefer short flavor names, +not indicating CPU details or hypervisor types. See above list +of standard flavors to get a feeling.

+

However, more successful providers will often need to differentiate their +offerings in response to customer demand and allow customers to request +flavors with specific detailed properties. The goal of this proposal is to avoid +providers to invent their own names and then refer customers to extra_specs +or worse a non-machine-readable service description to find out the details.

+

So a cloud provider might well evolve from offering SCS-8T:16:50 to offering +SCS-8T:16:50n, SCS-8T:16:50n-i2 and SCS-8T:16:50n-a2 to specify that he +is using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome. +We would expect the cloud provider to still offer the generic flavor +SCS-8C:16:50 and allow the scheduler (placement service) to pick both more +specific types (or just one if e.g. capacity management considerations suggest +so). We would expect providers in such cases to ensure that the price of a requested +flavor does not depend on the scheduler decisions.

+

We are looking into the metadefs +mechanism and extra_specs +to allow customers to ask for specific flavor properties without the need to +encode all these flavor details into the flavor name, so the optional pieces +may not be needed much. However, there must be a way to request flavor +properties without encoding the need into an image — this indirection is +considered broken by the SCS team.

+

Validation

+

There is a script in flavor_name_check.py +which can be used to decode, validate and construct flavor names. +This script must stay in sync with the specification text.

+

Ensure you have your OpenStack tooling (python3-openstackclient, OS_CLOUD) setup and call +tools/flavor-name-check.py -c $(openstack flavor list -f value -c Name) to get a report +on the flavor list compliance of the cloud environment.

+

Beyond SCS: Gaia-X

+

Some providers might offer VM services ("IaaS") without trying to adhere to SCS standards, +yet still finding the flavor naming standards useful. The Gaia-X Technical Committee's +Provider Working Group (WG) would seem like a logical place for such discussions then. +If so, we could +replace the SCS- prefix with a GX- prefix and transfer the naming scheme governance from +the SCS project to the Gaia-X Provider WG (where we participate). SCS certification would +then reference the Gaia-X flavor naming standard as a requirement.

+ + \ No newline at end of file diff --git a/standards/scs-0100-v2-flavor-naming/index.html b/standards/scs-0100-v2-flavor-naming/index.html new file mode 100644 index 0000000000..c8584a9de4 --- /dev/null +++ b/standards/scs-0100-v2-flavor-naming/index.html @@ -0,0 +1,393 @@ + + + + + +SCS Flavor Naming Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Flavor Naming Standard

Introduction

+

This is the standard v2.1 for SCS Release 4. +Note that we intend to only extend it (so it's always backwards compatible), +but try to avoid changing in incompatible ways. +(See at the end for the v1 to v2 transition where we have not met that +goal, but at least managed to have a 1:1 relationship between v1 and v2 names.)

+

Motivation

+

In OpenStack environments there is a need to define different flavors for instances. +The flavors are pre-defined by the operator, the customer can not change these. +OpenStack providers thus typically offer a large selection of flavors.

+

While flavors can be discovered (openstack flavor list), it is helpful for users (DevOps teams), +to have

+
    +
  • A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere.
  • +
  • Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered.
  • +
+

While not all details will be encoded in the name, the key features should be obvious: +Number of vCPUs, RAM, Root Disk. +Extra features are important as well: There will be flavors with GPU support, fast disks for databases, +memory-heavy applications, and other useful aspects of an instance.

+

It may also be important to make the CPU generation clearly recognizable, as this is always a topic in +discussions with customers.

+

Note that not all relevant properties of flavors can be discovered; creating a specification +to address this is a separate but related effort to the name standardization. +Commonly used infrastructure-as-code tools do not provide a way to use discoverability +features to express something like "I want a flavor with 2 vCPUs, 8GiB of RAM, a local +20GB SSD disk and Infiniband support, but I don't care whether it's AMD or intel" in a +reasonable manner. Using flavor names to express this will thus continue to be useful, +and we don't expect the need for standardization of flavor names to go away until +the commonly used IaC tools work on a higher abstraction layer than they currently do.

+

Design Considerations

+

Type of information included

+

From discussions of our operators with their customers we learned that +the following characteristics are important in a flavor description:

+
TypeDescription
GenerationCPU Generation
Number of CPUNumber of vCPUs - suffixed by L,V,T,C (see below)
Amount of RAMAmount of memory available for the VM
Performance ClassAbility to label high-performance CPUs, disks, network
CPU TypeX86-intel, X86-amd, ARM, RISC-V, Generic
"bms"Bare Metal System (no virtualization/hypervisor)
+

This list is likely not comprehensive and will grow over time.

+

Rather than using random names s5a.medium and assigning a discrete set of properties +to them, we wanted to come up with a scheme that allows to systematically derive +names from properties and vice versa. The scheme allows for short names (by not +encoding all details) as well as very detailed longer names.

+

Complete Proposal for systematic flavor naming

+
PrefixCPUs & SuffixRAM[GiB]optional: Disk[GB]&typeopt: extensions
SCS-NL/V/T/C[i]-N[u][o][-[Mx]N[n/s/l/p]][_EXT]
+

Note that N and M are placeholders for numbers here. +The optional fields are denoted in brackets (and have opt: in the header). +See below for extensions.

+

Note that all letters are case-sensitive.

+

Typical flavor names look like SCS-4V-16-50 for a flavor with 4vCPUs (with limited +oversubscription), 16GiB RAM and a 50GB disk (of unspecified type).

+

Proposal Details

+

[REQUIRED] CPU Suffixes

+

Next to the number of vCPUs, these vCPUs need to be characterized ti describe their nature.

+
SuffixMeaning
Cdedicated Core
Tdedicated Thread (SMT)
VvCPU (oversubscribed)
LvCPU (heavily oversubscribed)
+

Baseline

+

Note that vCPU oversubscription for a V vCPU should be implemented such, that we +can guarantee at least 20% of a core in >99% of the time; this can be achieved by +limiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled) +or by more advanced workload management logic. Otherwise L (low performance) instead +of V must be used. The >99% is measured over a month (1% is 7.2h/month).

+

Note that CPUs should use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.). +Microcode must be updated within less than a month of a new release; for CVSS scores above 8, +providers should do it in less than a week. +The provider should enable at least all mitigations that are enabled by default in the Linux kernel and the +KVM hypervisor. CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) should switch off hyperthreading +OR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team.

+

If microcode updates needed for mitigation are lacking for longer than a month, default kernel/hypervisor +mitigations are disabled or hyperthreading is enabled despite the CPU being susceptible to L1TF, the +flavors must declare themselves insecure with the i suffix (see below).

+

Higher oversubscription

+

Must be indicated with a L vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and +the lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month).

+

Insufficient microcode

+

Not using these mitigations must be indicated by an additional i suffix for insecure +(weak protection against CPU vulnerabilities through insufficient microcode, lack of disabled hyperthreading +on L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor).

+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2T-4-10n
  • +
  • SCS-2V-4-10n
  • +
  • SCS-2L-4-10n
  • +
  • SCS-2Li-4-10n
  • +
  • SCS-2-**4-10n - CPU suffix missing
  • +
  • SCS-2iT-4-10n - This order is forbidden
  • +
+

[REQUIRED] Memory

+

Baseline

+

Cloud providers should use ECC memory. +Memory oversubscription should not be used. +It is allowed to specify half GiBs (e.g. 3.5), though this should not be done for larger memory sizes (>= 10GiB).

+

No ECC

+

If no ECC is used, the u suffix must indicate this.

+

Enabled Oversubscription

+

If memory is oversubscribed, you must expose this with the o suffix.

+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-3.5-10n
  • +
  • SCS-2C-4u-10n
  • +
  • SCS-2C-4o-10n
  • +
  • SCS-2C-4uo-10n
  • +
  • SCS-2C-4ou-10n - This order is forbidden
  • +
+

[OPTIONAL] Disk sizes and types

+

Disk sizes (in GB) should use sizes 5, 10, 20, 50, 100, 200, 500, 1000.

+
Disk typeMeaning
nNetwork shared storage (ceph/cinder)
hLocal disk (HDD: SATA/SAS class)
sLocal SSD disk
pLocal high-perf NVMe
+

Baseline

+

Note that disk type might be omitted — the user then can not take any assumptions +on what storage is provided for the root disk (that the image gets provisioned to).

+

It does make sense for n to be requested explicitly to allow for smooth live migration. +h typically provides latency advantages vs n (but not necessarily bandwidth and +also is more likely to fail), s and p are for applications that need low +latency (high IOPS) and bandwidth disk I/O. n storage is expected to survive +single-disk and single-node failure.

+

If the disk size is left out, the cloud is expected to allocate a disk (network or local) +that is large enough to fit the root file system (min_disk in image). This automatic +allocation is indicated with - without a disk size. +If the - is left out completely, the user must create a boot volume manually and +tell the instance to boot from it or use the +block_device_mapping_v2 +mechanism explicitly to create the boot volume from an image.

+

Multi-provisioned Disk

+

The disk size can be prefixed with Mx prefix, where M is an integer specifying that the disk +is provisioned M times. Multiple disks provided this way should be independent storage media, +so users can expect some level of parallelism and independence.

+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-4-10s
  • +
  • SCS-2C-4-10s_bms_z3
  • +
  • SCS-2C-4-3x10s - Cloud creates three 10GB SSDs
  • +
  • SCS-2C-4-3x10s_bms_z3
  • +
  • SCS-2C-4-10 - Cloud decides disk type
  • +
  • SCS-2C-4-10_bms_z3
  • +
  • SCS-2C-4-n - Cloud decides disk size (min_disk from image or larger)
  • +
  • SCS-2C-4-n_bms_3
  • +
  • SCS-2C-4- - Cloud decides disk type and size
  • +
  • SCS-2C-4-_bms_z3
  • +
  • SCS-2C-4-_bms_z3h_GNa-64_ib
  • +
  • SCS-2C-4-_ib
  • +
  • SCS-2C-4 - You need to specify a boot volume yourself (boot from volume, or use block_device_mapping_v2)
  • +
  • SCS-2C-4_bms_z3
  • +
  • SCS-2C-4-3x- - Cloud decides disk type and size and creates three of them (FIXME: Is this useful?)
  • +
  • SCS-2C-4-3xs - Cloud decides size and creates three local SSD volumes (FIXME: useful?)
  • +
  • SCS-2C-4-3x10 - Cloud decides type and creates three 10GB volumes
  • +
  • SCS-2C-4-1.5n - You must not specify disk sizes which are not in full GiBs
  • +
+

Standard SCS flavors

+

These are flavors that must exist on standard SCS clouds (x86-64).

+

We expect disk sizes to be 5, 10, 20, 50, 100, 200, 500, 1000GB, 2000GB. +We expect a typical CPU

GiB
ratio of 1:4.

+
vCPU:RAM ratioMandatory Flavors
1:4SCS-1V-4, SCS-1V-4-10
2:8SCS-2V-8, SCS-2V-8-20
4:16SCS-4V-16, SCS-4V-16-50
8:32SCS-8V-32, SCS-8V-32-100
1:2SCS-1V-2, SCS-1V-2-5
2:4SCS-2V-4, SCS-2V-4-10
4:8SCS-4V-8, SCS-4V-8-20
8:16SCS-8V-16, SCS-8V-16-50
16:32SCS-16V-32, SCS-16V-32-100
1:8SCS-1V-8, SCS-1V-8-20
2:16SCS-2V-16, SCS-2V-16-50
4:32SCS-4V-32, SCS-4V-32-100
1:1SCS-1L-1, SCS-1L-1-5
+

Note that all vCPUs of SCS standard flavors are oversubscribed — the smallest 1L-1 +flavor allows for heavy oversubscription (note the L), and thus can be offered very +cheaply — imagine jump hosts ... +Disks types are not specified (and expected to be n or h typically).

+

The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM +compute hosts) to offer all flavors.

+

Note: Compared to previous drafts, we have heavily reduced the variations +on disk sizes — this reflects that for the standard networked cinder +disks, you can pass block_device_mapping_v2 on server (VM) creation to +allocate a boot disk of any size you desire. We have scaled the few +mandatory disk sizes with the amount of RAM. For each flavor there is +also one without a pre-attached disk — these are meant to be used +to boot from a volume (either created beforehand or allocated on-the-fly +with block_device_mapping_v2, e.g. +openstack server create --flavor SCS-1V:2 --block-device-mapping sda=IMGUUID:image:12:true +to create a bootable 12G cinder volume from image IMGUUID that gets tied to the VM +instance life cycle.)

+

Naming policy compliance

+

To be certified as an SCS compliant x86-64 IaaS platform, you must offer all standard SCS flavors +according to the previous section. (We may define a mechanism that allows exceptions to be +granted in a way that makes this very transparent and visible to clients.)

+

You are allowed to understate your performance; you may implement a SCS-1V-1-5 flavor with +a flavor that actually implements SCS-1T-1-5n (i.e. you dedicate a dedicated hyperthread instead +of higher oversubscription) or even SCS-1D-1.5-8s (1 dedicated core, 50% more RAM and a 8GiB SSD).

+

Flavor names indicating certain capabilities must at least provide these, otherwise they +are in violation of the SCS specification and prevent SCS compliance.

+

We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V-32-100). +Larger providers that offer more details (using the extension below) are expected to still also +offer the short variants for usability and easier portability, even beyond the mandated flavors.

+

You must be very careful to expose low vCPU guarantees (L instead of V), insecure +hyperthreading/microcode i, non-ECC-RAM u, memory oversubscription o. Note that omitting these qualifiers is +overstating your security, reliability or performance properties and may be reason for +clients to feel betrayed or claim damages. This would prevent SCS compliance and certification; +in extreme cases, the SCS project might be forced to work with public statements.

+

You may offer additional SCS- flavors, following the naming scheme and rules outlined here.

+

You may offer additional flavors, not following above scheme and not starting with SCS-

+

You must not offer flavors with the SCS- prefix which do not follow this naming scheme. +You must not extend the SCS naming scheme with your own suffices; you are encouraged however +to suggest extensions that we can discuss and add to the official scheme.

+

Validation

+

There is a script in flavor_name_check.py +which can be used to decode, validate and construct flavor names. +This script must stay in sync with the specification text.

+

Ensure you have your OpenStack tooling (python3-openstackclient, OS_CLOUD) setup and call +tools/flavor-name-check.py -c $(openstack flavor list -f value -c Name) to get a report +on the flavor list compliance of the cloud environment.

+

The script flavor-names-openstack.py talks to the OpenStack API of the +cloud specified by the OS_CLOUD environment and queries properties and checks +the names for standards compliance and completeness w.r.t. the mandatory +flavor list. It goes beyond the above example in checking that the discoverable +features of flavors (vCPUs, RAM, Disk) match what the flavor names claim.

+

Operational tooling

+

The openstack-flavor-manager is able to +create all standard, mandatory SCS flavors for you.

+

Extensions

+

Extensions provide a possibility for providers that offer a very differentiated set +of flavors to indicate hypervisors, support for hardware/nested virtualization, +CPU types and generations, high-frequency models, GPU support and GPU types as +well as Infiniband support. (More extensions may be appended in the future.)

+

Using the systematic naming approach ensures that two providers that offer flavors +with the same specific features will use the same name for them, thus simplifying +life for their customers when consuming these flavors.

+

Note that there is no need to indicate all details and extra features this way. +Flavors may always perform better or have more features than indicated in a name. +Underperformance (CPU suffices L or i or memory suffices o and u) on the other +hand MUST be indicated in the name; this happens rarely in practice.

+

For smaller providers, the ability to e.g. differentiate between an AMD Milan and an intel +IceLake and exposed the slightly different feature set to customers and have slightly +different price points is often not worth the extra effort. This is because having +this extra differentiation causes fragmentation of the machines (host aggregates) +that can offer these flavors, thus resulting in a lower utilization (as the capacity +management will need to have a certain amount of headroom per machine pool to avoid +running out of capacity).

+

Note that it possible for providers to register both the generic short names and the +longer, more detailed names and allow them to use the same set of machines (host aggregates). +Note that machines (hypervisors) can be part of more than one host aggregate.

+

The extensions have the format:

+

[_hyp][_hwv][_[arch[N][h][_[G/g]X[N][-M[h]]][_ib]

+

Remember that letters are case-sensitive. +In case you wonder: Feature indicators are capitalized, modifiers are lower case. +(An exception is the uppercase -G for a pass-through GPU vs. lowercase -g for vGPU.)

+

[OPTIONAL] Hypervisor

+

The default Hypervisor is assumed to be KVM. Clouds, that offer different hypervisors +or Bare Metal Systems should indicate the Hypervisor according to the following table:

+
hypMeaning
kvmKVM
xenXen
vmwVMware
hyvHyper-V
bmsBare Metal System
+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-4-10n_bms
  • +
  • SCS-2C-4-10n_bms_z3h
  • +
+

[OPTIONAL] Hardware virtualization / Nested virtualization

+

If the instances that are created with this flavor support hardware-accelerated +virtualization, this can be reflected with the _hwv flag (after the optional +Hypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel) +or svm (AMD) is available. This will be the case on Bare Metal flavors on almost +all non-ancient x86 CPUs or if your virtualization hypervisor is configured to +support nested virtualization. +Flavors without the _hwv flag may or may not support hardware virtualization (as we +recommend enabling nesting, but don't require flavor names to reflect all +capabilities. Flavors may over-deliver ...)

+

Examples

+
    +
  • SCS-2C-4-10 - may or may not support HW virtualization in VMs
  • +
  • SCS-2C-4-10_kvm_hwv - kvm with enabled nested virtualization
  • +
  • SCS-2C-4-10_hwv - not recommended, but allowed
  • +
  • SCS-2C-4-10_bms_hwv - better: bare metal with HW virt support (VMX on intel, SVM on AMD, ...)
  • +
  • SCS-2C-4-10_hwv_xen - illegal, wrong ordering
  • +
+

[OPTIONAL] CPU Architecture Details

+

Arch details provide more details on the specific CPU:

+
    +
  • Vendor
  • +
  • Generation
  • +
  • Frequency
  • +
+

Generation and Vendor

+

The generations are vendor specific and can be left out. +Not specifying arch means that we have a generic CPU (x86-64). +The letters i, z, a and r specify the vendors Intel, +AMD (z like in Zen), ARM v8+, RISC-V.

+
Generationi (Intel x86-64)z (AMD x86-64) a (AArch64)r (RISC-V)
0pre Skylakepre Zenpre Cortex A76TBD
1SkylakeZen-1 (Naples)A76/NeoN1 classTBD
2Cascade LakeZen-2 (Rome)A78/x1/NeoV1 classTBD
3Ice LakeZen-3 (Milan)A71x/NeoN2 (ARMv9)TBD
4Sapphire RapidsZen-4 (Genoa)TBD
+

It is recommended to leave out the 0 when specifying the old generation; this will +help the parser tool, which assumes 0 for an unspecified value and does leave it +out when generating the name for comparison. In other words: 0 has a meaning of +"rather old or unspecified".

+

Frequency Suffixes

+
SuffixMeaning
h>2.75GHz all-core
hh>3.25GHz all-core
hhh>3.75GHz all-core
+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-4-10n_z
  • +
  • SCS-2C-4-10n_z3
  • +
  • SCS-2C-4-10n_z3h
  • +
  • SCS-2C-4-10n_z3hh
  • +
  • SCS-2C-4-10n_bms_z
  • +
  • SCS-2C-4-10n_bms_z3
  • +
  • SCS-2C-4-10n_bms_z3
  • +
  • SCS-2C-4-10n_bms_z3h
  • +
  • SCS-2C-4-10n_bms_z3hh - Bare Metal, Intel Ice Lake with > 3.25GHz all core freq
  • +
+

[OPTIONAL] GPU support

+

_GX[N][-M[h]] indicates a Pass-Through GPU from vendor X of gen N with M compute units / SMs / EUs exposed. +_gX[N][-M[h]] indicates a vGPU from vendor X of gen N with M compute units / SMs / EUs assigned.

+

Note that the vendor letter X is mandatory, generation and compute units are optional.

+
GPUVendor
NnVidia
AAMD
IIntel
+

For nVidia, the generation N can be f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, l=Ada Lovelace, ..., +for AMD GCN-x=0.x, RDNA1=1, RDNA2=2, RDNA3=3, for intel Gen9=0.9, Xe(12.1)=1, ... +(Note: This may need further work to properly reflect what's out there.)

+

The optional h suffix to the compute unit count indicates high-performance (e.g. high freq or special +high bandwidth gfx memory such as HBM); +h can be duplicated for even higher performance.

+

[OPTIONAL] Infiniband

+

_ib indicates Infiniband networking.

+

More extensions may be forthcoming and appended in a later revision of this spec.

+

Extensions need to be specified in the above-mentioned order.

+

Naming options advice

+

Note that we expect most clouds to prefer short flavor names, +not indicating CPU details or hypervisor types. See above list +of standard flavors to get a feeling.

+

However, more successful providers will often need to differentiate their +offerings in response to customer demand and allow customers to request +flavors with specific detailed properties. The goal of this proposal is to avoid +providers to invent their own names and then refer customers to (currently +incompletely standardized) extra_specs +or worse a non-machine-readable service descriptions to find out the details.

+

So a cloud provider might well evolve from offering SCS-8T-16-50 to offering +SCS-8T-16-50n, SCS-8T-16-50n_i2 and SCS-8T-16-50n_a2 to specify that he +is using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome. +We would expect the cloud provider to still offer the generic flavor +SCS-8T-16-50 and allow the scheduler (placement service) to pick both more +specific types (or just one if e.g. capacity management considerations suggest +so). Providers should in such cases make sure that the price does not depend +on scheduler decisions.

+

We are looking into the metadefs +mechanism and extra_specs +to allow customers to ask for specific flavor properties without the need to +encode all these flavor details into the flavor name, so the optional pieces +may not be needed much. However, there must be a way to request flavor +properties without encoding the need into an image — the indirection via +an image is considered broken by the SCS team.

+

Proposal Examples

+
ExampleDecoding
SCS-2C-4-10n2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk
SCS-8Ti-32-50p_i18 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe
SCS-1L-1u-51 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific)
SCS-16T-64-200s_GNa-64_ib16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 64 Passthrough nVidia Ampere SMs
SCS-4C-16-2x200p_a14 dedicated Arm64 cores (A76 class), 16GiB RAM, 2x200GB local NVMe drives
SCS-1V-0.51 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)
+

Previous standard versions

+

Version 1 of the standard +used a slightly different naming syntax while the logic was exactly the same. +What is a - in v2 used to be a :; _ used to be -. The reason for +the change was certain Kubernetes tools using the flavor names as labels. +Labels however are subject to stricter naming rules and in particular don't +allow for a :. See PR #190 +for a discussion.

+

Version 1 flavor names can be translated to v2 using the following transformation:

+
NAMEV2=$(echo "$NAMEV1" | sed -e 's/\-/_/g' -e 's/:/-/g' -e 's/^SCS_/SCS-/')
+

and the way back can be done with

+
NAMEV1=$(echo "$NAMEV2" | sed -e 's/\-/:/g' -e 's/_/-/g' -e 's/^SCS:/SCS-/')
+

Considerations for how providers can ensure a smooth transition for their customers +from v1 to v2 are written in a separate document.

+

For the time being, the validation tools still accept the old names with a warning +(despite the unchanged SCS- prefix) unless you pass option -2 to them. They will +however not count v1 flavors towards fulfilling the needs against the corresponding +v2 mandatory flavor list unless you pass the option -1. +In other words: An IaaS infrastructure with the 26 +v1 mandatory flavors will produce 26 warnings (for using old flavors) and 26 +errors (for missing the 26 mandatory v2 flavors) unless you pass -1 in which +case no errors and no warnings will be produced. Registering the 26 mandatory +v2 flavor names in addition will result in passing the test with only 26 +warnings — unless you specify -2. If you do and want to pass you'll need +to remove the old v1 names or rename them to no longer start with SCS-.

+

Beyond SCS

+

The Gaia-X provider working group which could have created a superseding standard +does no longer exist.

+

However, we have been reaching out to the OpenStack Public Cloud SIG and the ALASCA +members to seek further alignment.

+

Getting upstream OpenStack support for flavor aliases would provide more flexibility +and ease migrations between providers, also providers that don't offer the SCS- +flavors.

+

We also would like to see upstream extra_specs standardizing the discoverability of some +properties exposed via the SCS names and work on IaC tooling (terraform ...) +to make use of these when selecting a flavor.

+ + \ No newline at end of file diff --git a/standards/scs-0100-v3-flavor-naming/index.html b/standards/scs-0100-v3-flavor-naming/index.html new file mode 100644 index 0000000000..a18e1bba46 --- /dev/null +++ b/standards/scs-0100-v3-flavor-naming/index.html @@ -0,0 +1,416 @@ + + + + + +SCS Flavor Naming Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Flavor Naming Standard

Introduction

+

This is the standard v3.2 for SCS Release 8. +Note that we intend to only extend it (so it's always backwards compatible), +but try to avoid changing in incompatible ways. +(See at the end for the v1 to v2 transition where we have not met that +goal, but at least managed to have a 1:1 relationship between v1 and v2 names.)

+

Motivation

+

In OpenStack environments there is a need to define different flavors for instances. +The flavors are pre-defined by the operator, the customer can not change these. +OpenStack providers thus typically offer a large selection of flavors.

+

While flavors can be discovered (openstack flavor list), it is helpful for users (DevOps teams), +to have a naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere.

+

While not all details will be encoded in the name, the key features should be obvious: +Number of vCPUs, RAM, Root Disk. +Extra features are important as well: There will be flavors with GPU support, fast disks for databases, +memory-heavy applications, and other useful aspects of an instance.

+

It may also be important to make the CPU generation clearly recognizable, as this is always a topic in +discussions with customers.

+

Note that not all relevant properties of flavors can be discovered; creating a specification +to address this is a separate but related effort to the name standardization. +Commonly used infrastructure-as-code tools do not provide a way to use discoverability +features to express something like "I want a flavor with 2 vCPUs, 8GiB of RAM, a local +20GB SSD disk and Infiniband support, but I don't care whether it's AMD or intel" in a +reasonable manner. Using flavor names to express this will thus continue to be useful, +and we don't expect the need for standardization of flavor names to go away until +the commonly used IaC tools work on a higher abstraction layer than they currently do.

+

Design Considerations

+

Type of information included

+

From discussions of our operators with their customers we learned that +the following characteristics are important in a flavor description:

+
TypeDescription
GenerationCPU Generation
Number of CPUNumber of vCPUs - suffixed by L,V,T,C (see below)
Amount of RAMAmount of memory available for the VM
Performance ClassAbility to label high-performance CPUs, disks, network
CPU TypeX86-intel, X86-amd, ARM, RISC-V, Generic
"bms"Bare Metal System (no virtualization/hypervisor)
+

This list is likely not comprehensive and will grow over time.

+

Rather than using random names s5a.medium and assigning a discrete set of properties +to them, we wanted to come up with a scheme that allows to systematically derive +names from properties and vice versa. The scheme allows for short names (by not +encoding all details) as well as very detailed longer names.

+

Complete Proposal for systematic flavor naming

+
PrefixCPUs & SuffixRAM[GiB]optional: Disk[GB]&typeopt: extensions
SCS-NL/V/T/C[i]-N[u][o][-[Mx]N[n/h/s/p]][_EXT]
+

Note that N and M are placeholders for numbers here. +The optional fields are denoted in brackets (and have opt: in the header). +See below for extensions.

+

Note that all letters are case-sensitive.

+

Typical flavor names look like SCS-4V-16-50 for a flavor with 4vCPUs (with limited +oversubscription), 16GiB RAM and a 50GB disk (of unspecified type).

+

Proposal Details

+

[REQUIRED] CPU Suffixes

+

Next to the number of vCPUs, these vCPUs need to be characterized to describe their nature.

+
SuffixMeaning
Cdedicated Core
Tdedicated Thread (SMT)
VvCPU (oversubscribed)
LvCPU (heavily oversubscribed)
+

Baseline

+

Note that vCPU oversubscription for a V vCPU should be implemented such, that we +can guarantee at least 20% of a core in >99% of the time; this can be achieved by +limiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled) +or by more advanced workload management logic. Otherwise L (low performance) instead +of V must be used. The >99% is measured over a month (1% is 7.2h/month).

+

Note that CPUs should use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.). +In particular,

+
    +
  • microcode must be updated within less than a month of a new release; for CVSS scores above 8, +providers should do it in less than a week.
  • +
  • all mitigations that are enabled by default in the Linux kernel and the KVM hypervisor +should be enabled,
  • +
  • CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) should have hyperthreading +disabled OR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team.
  • +
+

That is to say, except when the suffix i is used, the provider commits itself to implementing the appropriate mitigations +if and when they become available, within the timeframes mentioned above.

+

If a provider does not want to commit to deploying available microcode fixes and upstream kernel/hypervisor updates within a month or +if the provider wants to enable hyperthreading on compute hosts despite having CPUs susceptible to L1TF there +(and no SCS-accepted core-scheduling mechanism is used for mitigation), +the flavors must be declared insecure with the i suffix (see below).

+

Higher oversubscription

+

Must be indicated with a L vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and +the lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month).

+

Insufficient microcode

+

Not using these mitigations must be indicated by an additional i suffix for insecure +(weak protection against CPU vulnerabilities through insufficient microcode, lack of disabled hyperthreading +on L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor).

+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2T-4-10n
  • +
  • SCS-2V-4-10n
  • +
  • SCS-2L-4-10n
  • +
  • SCS-2Li-4-10n
  • +
  • SCS-2-**4-10n - CPU suffix missing
  • +
  • SCS-2iT-4-10n - This order is forbidden
  • +
+

[REQUIRED] Memory

+

Baseline

+

Cloud providers should use ECC memory. +Memory oversubscription should not be used. +It is allowed to specify half GiBs (e.g. 3.5), though this should not be done for larger memory sizes (>= 10GiB).

+

No ECC

+

If no ECC is used, the u suffix must indicate this.

+

Enabled Oversubscription

+

If memory is oversubscribed, you must expose this with the o suffix.

+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-3.5-10n
  • +
  • SCS-2C-4u-10n
  • +
  • SCS-2C-4o-10n
  • +
  • SCS-2C-4uo-10n
  • +
  • SCS-2C-4ou-10n - This order is forbidden
  • +
+

[OPTIONAL] Disk sizes and types

+

Disk sizes (in GB) should use sizes 5, 10, 20, 50, 100, 200, 500, 1000.

+
Disk typeMeaning
nNetwork shared storage (ceph/cinder)
hLocal disk (HDD: SATA/SAS class)
sLocal SSD disk
pLocal high-perf NVMe
+

Baseline

+

Note that disk type might be omitted — the user then can not take any assumptions +on what storage is provided for the root disk (that the image gets provisioned to).

+

It does make sense for n to be requested explicitly to allow for smooth live migration. +h typically provides latency advantages vs n (but not necessarily bandwidth and +also is more likely to fail), s and p are for applications that need low +latency (high IOPS) and bandwidth disk I/O. n storage is expected to survive +single-disk and single-node failure.

+

For specific requirements on the SSD and NVMe disks regarding IOPS and +power-loss protection, refer to Decision Record scs-0110-ssd-flavors.

+

If the disk size is left out, the cloud is expected to allocate a disk (network or local) +that is large enough to fit the root file system (min_disk in image). This automatic +allocation is indicated with - without a disk size. +If the - is left out completely, the user must create a boot volume manually and +tell the instance to boot from it or use the +block_device_mapping_v2 +mechanism explicitly to create the boot volume from an image.

+

Multi-provisioned Disk

+

The disk size can be prefixed with Mx prefix, where M is an integer specifying that the disk +is provisioned M times. Multiple disks provided this way should be independent storage media, +so users can expect some level of parallelism and independence.

+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-4-10s
  • +
  • SCS-2C-4-10s_bms_z3
  • +
  • SCS-2C-4-3x10s - Cloud creates three 10GB SSDs
  • +
  • SCS-2C-4-3x10s_bms_z3
  • +
  • SCS-2C-4-10 - Cloud decides disk type
  • +
  • SCS-2C-4-10_bms_z3
  • +
  • SCS-2C-4-n - Cloud decides disk size (min_disk from image or larger)
  • +
  • SCS-2C-4-n_bms_3
  • +
  • SCS-2C-4- - Cloud decides disk type and size
  • +
  • SCS-2C-4-_bms_z3
  • +
  • SCS-2C-4-_bms_z3h_GNa-64_ib
  • +
  • SCS-2C-4-_ib
  • +
  • SCS-2C-4 - You need to specify a boot volume yourself (boot from volume, or use block_device_mapping_v2)
  • +
  • SCS-2C-4_bms_z3
  • +
  • SCS-2C-4-3x10 - Cloud decides type and creates three 10GB volumes
  • +
  • SCS-2C-4-1.5n - You must not specify disk sizes which are not in full GiBs
  • +
+

Naming policy compliance

+

Every flavor you offer MUST satisfy the following assertion:

+
    +
  • If its name starts with SCS-, the name has to conform to the syntax outlined above, and +the flavor must at least provide the capabilities indicated by the name.
  • +
+

That is to say:

+
    +
  • +

    You may offer flavors not following the above scheme, as long as the name does not +start with SCS-.

    +
  • +
  • +

    You are allowed to understate your performance; for instance, a flavor that satisfies +SCS-1C-1.5-8s (1 dedicated core, 1.5 GiB RAM, 8 GiB SSD) may also be named +SCS-1T-1-5n (1 dedicated hyperthread, 1 GiB RAM, 5 GiB network volume) or even +SCS-1V-1-5. Similarly, you may offer the (v3 mandatory) SCS-2V-4-20s with a SCS-2V-4-20p +implementation (using a local NVMe instead of an SSD).

    +
  • +
+

You must be very careful to expose low vCPU guarantees (L instead of V), insecure +hyperthreading/microcode i, non-ECC-RAM u, memory oversubscription o. Note that omitting these qualifiers +is overstating your security, reliability or performance properties and may be reason for +clients to feel betrayed or claim damages. This would prevent SCS compliance and certification; +in extreme cases, the SCS project might be forced to work with public statements.

+

We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V-32-100). +Larger providers that offer more details (using the extension below) are expected to still also +offer the short variants for usability and easier portability, even beyond the mandated flavors.

+

You must not extend the SCS naming scheme with your own extensions; you are encouraged however +to suggest extensions that we can discuss and add to the official scheme.

+

Extensions

+

Extensions provide a possibility for providers that offer a very differentiated set +of flavors to indicate hypervisors, support for hardware/nested virtualization, +CPU types and generations, high-frequency models, GPU support and GPU types as +well as Infiniband support. (More extensions may be appended in the future.)

+

Using the systematic naming approach ensures that two providers that offer flavors +with the same specific features will use the same name for them, thus simplifying +life for their customers when consuming these flavors.

+

Note that there is no need to indicate all details and extra features this way. +Flavors may always perform better or have more features than indicated in a name. +Underperformance (CPU suffixes L or i or memory suffixes o and u) on the other +hand MUST be indicated in the name; this happens rarely in practice.

+

For smaller providers, the ability to e.g. differentiate between an AMD Milan and an intel +IceLake and exposed the slightly different feature set to customers and have slightly +different price points is often not worth the extra effort. This is because having +this extra differentiation causes fragmentation of the machines (host aggregates) +that can offer these flavors, thus resulting in a lower utilization (as the capacity +management will need to have a certain amount of headroom per machine pool to avoid +running out of capacity).

+

Note that it is possible for providers to register both the generic short names and the +longer, more detailed names and allow them to use the same set of machines (host aggregates). +Note that machines (hypervisors) can be part of more than one host aggregate.

+

The extensions have the format:

+

[_hyp][_hwv][_arch[N][h]][_[G/g]X[N][-M][h]][_ib]

+

Extensions are individually optional, but the ones that are used must appear in the order +given in the above line.

+

Remember that letters are case-sensitive. +In case you wonder: Feature indicators are capitalized, modifiers are lower case. +(An exception is the uppercase _G for a pass-through GPU vs. lowercase _g for vGPU.)

+

[OPTIONAL] Hypervisor

+

Format: _hyp

+

The default Hypervisor is assumed to be KVM. Clouds that offer different hypervisors +or Bare Metal Systems should indicate the Hypervisor according to the following table:

+
hypMeaning
kvmKVM
xenXen
vmwVMware
hyvHyper-V
bmsBare Metal System
+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-4-10n_bms
  • +
  • SCS-2C-4-10n_bms_z3h
  • +
+

[OPTIONAL] Hardware virtualization / Nested virtualization

+

Format: _hwv

+

If the instances that are created with this flavor support hardware-accelerated +virtualization, this can be reflected with the _hwv flag (after the optional +Hypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel) +or svm (AMD) is available. This will be the case on Bare Metal flavors on almost +all non-ancient x86 CPUs or if your virtualization hypervisor is configured to +support nested virtualization. +Flavors without the _hwv flag may or may not support hardware virtualization (as we +recommend enabling nesting, but don't require flavor names to reflect all +capabilities. Flavors may over-deliver ...)

+

Examples

+
    +
  • SCS-2C-4-10 - may or may not support HW virtualization in VMs
  • +
  • SCS-2C-4-10_kvm_hwv - kvm with enabled nested virtualization
  • +
  • SCS-2C-4-10_hwv - not recommended, but allowed
  • +
  • SCS-2C-4-10_bms_hwv - better: bare metal with HW virt support (VMX on intel, SVM on AMD, ...)
  • +
  • SCS-2C-4-10_hwv_xen - illegal, wrong ordering
  • +
+

[OPTIONAL] CPU Architecture Details

+

Format: _arch[N][h]

+

This extension provides more details on the specific CPU:

+
    +
  • vendor/architecture (arch)
  • +
  • generation (N)
  • +
  • frequency (h)
  • +
+

Generation and Vendor

+

The options for arch are as follows:

+
Lettervendor/architectureCorresponding image architecture
(none)Generic x86-64x86_64
iIntel x86-64x86_64
zAMD (Zen) x86-64x86_64
aARM v8+aarch64
rRISC-V(not yet listed in Glance)
+

The generation is vendor specific and can be left out, but it can only be specified in +conjunction with a vendor. At present, these values are possible:

+
Generationi (Intel x86-64)z (AMD x86-64) a (AArch64)r (RISC-V)
0pre Skylakepre Zenpre Cortex A76TBD
1SkylakeZen-1 (Naples)A76/NeoN1 classTBD
2Cascade LakeZen-2 (Rome)A78/x1/NeoV1 classTBD
3Ice LakeZen-3 (Milan)A71x/NeoN2/V2(ARMv9)TBD
4Sapphire RapidsZen-4 (Genoa)AmpereOne (ARMv8.6)TBD
5Sierra Forest(E)Zen-5 (Turin)A72x/NeoN3/V3(Av9.2)TBD
6Granite Rapids(P)TBD
+

It is recommended to leave out the 0 when specifying the old generation; this will +help the parser tool, which assumes 0 for an unspecified value and does leave it +out when generating the name for comparison. In other words: 0 has a meaning of +"rather old or unspecified".

+
note

We don't differentiate between Zen-4 (Genoa) and Zen-4c (Bergamo); L3 cache per +Siena core is smaller on Bergamo and the frequency lower but the cores are otherwise +identical. As we already have a qualifier h that allows to specify higher frequencies +(which Genoa thus may use more and Bergamo not), we have enough distinction +capabilities. The same applies to Zen-5 (Turin) and Zen-5c (Turin Dense). +For intel with the server E-cores (Crestmont), these received their own +generation assignment, as the difference to the server P-cores (Redwood Cove) +is more significant.

+

Frequency Suffixes

+
SuffixMeaning
h>2.75GHz all-core
hh>3.25GHz all-core
hhh>3.75GHz all-core
+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-4-10n_z
  • +
  • SCS-2C-4-10n_z3
  • +
  • SCS-2C-4-10n_z3h
  • +
  • SCS-2C-4-10n_z3hh
  • +
  • SCS-2C-4-10n_bms_z
  • +
  • SCS-2C-4-10n_bms_z3
  • +
  • SCS-2C-4-10n_bms_z3
  • +
  • SCS-2C-4-10n_bms_z3h
  • +
  • SCS-2C-4-10n_bms_z3hh - Bare Metal, AMD Milan with > 3.25GHz all core freq
  • +
+

[OPTIONAL] GPU support

+

Format: _[G/g]X[N[-M[h][-V[h]]]]

+

This extension provides more details on the specific GPU:

+
    +
  • pass-through (G) vs. virtual GPU (g)
  • +
  • vendor (X)
  • +
  • generation (N)
  • +
  • number (M) of processing units that are exposed (for pass-through) or assigned; see table below for vendor-specific terminology
  • +
  • high-frequency indicator (h) for compute units
  • +
  • amount of video memory (V) in GiB
  • +
  • an indicator for high-bandwidth memory
  • +
+

Note that the vendor letter X is mandatory, generation and processing units are optional.

+
letter Xvendorprocessing units
NnVidiastreaming multiprocessors (SMs)
AAMDcompute units (CUs)
IIntelexecution units (EUs)
+

For nVidia, the generation N can be f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, l=Ada Lovelace, g=Grace Hopper, ..., +for AMD GCN-x=0.x, RDNA1=1, C/RDNA2=2, C/RDNA3=3, C/RDNA3.5=3.5, C/RDNA4=4, ... +for Intel Gen9=0.9, Xe(12.1/DG1)=1, Xe(12.2)=2, Arc(12.7/DG2)=3 ... +(Note: This may need further work to properly reflect what's out there.)

+

The optional h suffix to the compute unit count indicates high-frequency GPU compute units. +It is not normally recommended to use it except if there are several variants of cards within +a generation of GPUs and with similar number of SMs/CUs/EUs. +In case there are even more than two variants, the letter h can be duplicated for even +higher frquencies.

+

Please note that there are GPUs from one generation and vendor that have vastly different sizes +(or different fractions are being passed to an instance with multi-instance-GPUs). The number +M allows to differentiate between them and have an indicator of the compute capability and +parallelism. M can not at all be compared between different generations let alone different +vendors.

+

The amount of video memory dedicated to the instance can be indicated by V (in binary +Gigabytes). This number needs to be an integer - fractional memory sizes must be rounded +down. An optional h can be used to indicate high bandwidth memory (such as HBM2+) with +bandwidths well above 1GiB/s.

+

Example: SCS-16V-64-500s_GNa-14-6h +This flavor has a pass-through GPU nVidia Ampere with 14 SMs and 6 GiB of high-bandwidth video +memory. Looking through GPU specs you could guess it's 1/4 of an A30.

+

We have a table with common GPUs in the +implementation hints for this standard

+

[OPTIONAL] Infiniband

+

Format: _ib

+

This extension indicates Infiniband networking.

+

More extensions may be forthcoming and appended in a later revision of this spec.

+

Extensions need to be specified in the above-mentioned order.

+

Naming options advice

+

Note that we expect most clouds to prefer short flavor names, +not indicating CPU details or hypervisor types. See above list +of standard flavors to get a feeling.

+

However, more successful providers will often need to differentiate their +offerings in response to customer demand and allow customers to request +flavors with specific detailed properties. The goal of this proposal is to avoid +providers to invent their own names and then refer customers to (currently +incompletely standardized) extra_specs +or worse a non-machine-readable service descriptions to find out the details.

+

So a cloud provider might well evolve from offering SCS-8T-16-50 to offering +SCS-8T-16-50n, SCS-8T-16-50n_i2 and SCS-8T-16-50n_z2 to specify that he +is using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome. +We would expect the cloud provider to still offer the generic flavor +SCS-8T-16-50 and allow the scheduler (placement service) to pick both more +specific types (or just one if e.g. capacity management considerations suggest +so). Providers in such cases should ensure that the price of a requested +flavor does not depend on the scheduler decisions.

+

We are looking into the metadefs +mechanism and extra_specs +to allow customers to ask for specific flavor properties without the need to +encode all these flavor details into the flavor name, so the optional pieces +may not be needed much. However, there must be a way to request flavor +properties without encoding the need into an image — the indirection via +an image is considered broken by the SCS team.

+

Proposal Examples

+
ExampleDecoding
SCS-2C-4-10n2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk
SCS-8Ti-32-50p_i18 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe
SCS-1L-1u-51 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific)
SCS-16T-64-200s_GNa-72-24_ib16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 72 Passthrough nVidia Ampere SMs
SCS-4C-16-2x200p_a14 dedicated Arm64 cores (A76 class), 16GiB RAM, 2x200GB local NVMe drives
SCS-1V-0.51 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)
+

Previous standard versions

+

Previous versions up to version 3.0 contained the list of +mandatory/recommended flavors, which has been moved to +a standard of its own.

+

Version 1 of the standard +used a slightly different naming syntax while the logic was exactly the same. +What is a - in v2 used to be a :; _ used to be -. The reason for +the change was certain Kubernetes tools using the flavor names as labels. +Labels however are subject to stricter naming rules and in particular don't +allow for a :. See PR #190 +for a discussion.

+

Version 1 flavor names can be translated to v2 using the following transformation:

+
NAMEV2=$(echo "$NAMEV1" | sed -e 's/\-/_/g' -e 's/:/-/g' -e 's/^SCS_/SCS-/')
+

and the way back can be done with

+
NAMEV1=$(echo "$NAMEV2" | sed -e 's/\-/:/g' -e 's/_/-/g' -e 's/^SCS:/SCS-/')
+

For the time being, the validation tools still accept the old names with a warning +(despite the unchanged SCS- prefix) unless you pass option -2 to them. They will +however not count v1 flavors towards fulfilling the needs against the corresponding +v2 mandatory flavor list unless you pass the option -1. +In other words: An IaaS infrastructure with the 26 +v1 mandatory flavors will produce 26 warnings (for using old flavors) and 26 +errors (for missing the 26 mandatory v2 flavors) unless you pass -1 in which +case no errors and no warnings will be produced. Registering the 26 mandatory +v2 flavor names in addition will result in passing the test with only 26 +warnings — unless you specify -2. If you do and want to pass you'll need +to remove the old v1 names or rename them to no longer start with SCS-.

+

Beyond SCS

+

The Gaia-X provider working group which could have created a superseding standard +does no longer exist.

+

However, we have been reaching out to the OpenStack Public Cloud SIG and the ALASCA +members to seek further alignment.

+

Getting upstream OpenStack support for flavor aliases would provide more flexibility +and ease migrations between providers, also providers that don't offer the SCS- +flavors.

+

We also would like to see upstream extra_specs standardizing the discoverability of some +properties exposed via the SCS names and work on IaC tooling (terraform ...) +to make use of these when selecting a flavor.

+ + \ No newline at end of file diff --git a/standards/scs-0100-w1-flavor-naming-implementation-testing/index.html b/standards/scs-0100-w1-flavor-naming-implementation-testing/index.html new file mode 100644 index 0000000000..c713443a76 --- /dev/null +++ b/standards/scs-0100-w1-flavor-naming-implementation-testing/index.html @@ -0,0 +1,105 @@ + + + + + +SCS Flavor Naming Standard: Implementation and Testing Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Flavor Naming Standard: Implementation and Testing Notes

Introduction

+

The three major versions of the standard that exist so far are very similar, and deliberately so. +Therefore, the procedures needed to implement or test them are very similar as well. Yet, this document +will only cover v3, because v1 and v2 are already obsolete by the time of writing.

+

Implementation notes

+

Every flavor whose name starts with SCS- must conform with the naming scheme laid down in the standard.

+

Operational tooling

+

Syntax check

+

The test suite +comes with a handy +command-line utility +that can be used to validate flavor names, to interactively construct a flavor name +via a questionnaire, and to generate prose descriptions for given flavor names. +See the README +for more details.

+

The functionality of this script is also (partially) exposed via the web page +https://flavors.scs.community/, which can both +parse SCS flavors names as well as generate them.

+

With the OpenStack tooling (python3-openstackclient, OS_CLOUD) in place, you can call +cli.py -v parse v3 $(openstack flavor list -f value -c Name) to get a report +on the syntax compliance of the flavor names of the cloud environment.

+

Flavor creation

+

The OpenStack Flavor Manager from OSISM +will create a whole set of flavors in one go. +To that end, it provides different options: either the standard mandatory and +possibly recommended flavors can be created, or the user can set a file containing his flavors.

+

GPU table

+

The most commonly used datacenter GPUs are listed here, showing what GPUs (or partitions +of a GPU) result in what GPU part of the flavor name.

+

Nvidia (N)

+

We show the most popular recent generations here. Older one are of course possible as well.

+
Ampere (a)
+

One Streaming Multiprocessor on Ampere has 64 (A30, A100) or 128 Cuda Cores (A10, A40).

+

GPUs without MIG (one SM has 128 Cuda Cores and 4 Tensor Cores):

+
Nvidia GPUTensor CCuda CoresSMsVRAMSCS name piece
A1028892167224G GDDR6GNa-72-24
A40336107528448G GDDR6GNa-84-48
+

GPUs with Multi-Instance-GPU (MIG), where GPUs can be partitioned and the partitions handed +out as as pass-through PCIe devices to instances. One SM corresponds to 64 Cuda Cores and +4 Tensor Cores.

+
Nvidia GPUFractionTensor CCuda CoresSMsVRAMSCS GPU name
A301/122435845624G HBM2GNa-56-24
A301/211217922812G HBM2GNa-28-12
A301/456896146G HBM2GNa-14-6
A30X1/122435845624G HBM2eGNa-56h-24h
A1001/1432691210880G HBM2eGNa-108h-80h
A1001/221634565440G HBM2eGNa-54h-40h
A1001/410817282720G HBM2eGNa-27h-20h
A1001/760+960+15+10G HBM2eGNa-15h-10h+
A100X1/1432691210880G HBM2eGNa-108-80h
+

[+] The precise numbers for the 1/7 MIG configurations are not known by the author of +this document and need validation.

+
Ada Lovelave (l)
+

No MIG support, 128 Cuda Cores and 4 Tensor Cores per SM.

+
Nvidia GPUTensor CCuda CoresSMsVRAMSCS name piece
L423274245824G GDDR6GNl-58-24
L405681817614248G GDDR6GNl-142-48
L40G5681817614248G GDDR6GNl-142h-48
L40S5681817614248G GDDR6GNl-142hh-48
+
Grace Hopper (g)
+

These have MIG support and 128 Cuda Cores and 4 Tensor Cores per SM.

+
Nvidia GPUFractionTensor CCuda CoresSMsVRAMSCS GPU name
H1001/15281689613280G HBM3GNg-132-80h
H1001/226484486640G HBM3GNg-66-40h
H1001/413242243320G HBM3GNg-33-20h
H1001/772+2304+18+10G HBM3GNg-18-10h+
H2001/152816896132141G HBM3eGNg-132-141h
H2001/2264168966670G HBM3eGNg-66-70h
...
+

[+] The precise numbers for the 1/7 MIG configurations are not known by the author of +this document and need validation.

+

AMD Radeon (A)

+
CDNA 2 (2)
+

One CU contains 64 Stream Processors.

+
AMD InstinctStream ProcCUsVRAMSCS name piece
Inst MI210665610464G HBM2eGA2-104-64h
Inst MI25013312208128G HBM2eGA2-208-128h
Inst MI250X14080229128G HBM2eGA2-220-128h
+
CDNA 3 (3)
+

SRIOV partitioning is possible, resulting in pass-through for +up to 8 partitions, somewhat similar to Nvidia MIG. 4 Tensor +Cores and 64 Stream Processors per CU.

+
AMD GPUTensor CStream ProcCUsVRAMSCS name piece
Inst MI300X121619456304192G HBM3GA3-304-192h
Inst MI325X121619456304288G HBM3GA3-304-288h
+

intel Xe (I)

+
Xe-HPC (Ponte Vecchio) (3)
+

1 EU corresponds to one Tensor Core and contains 128 Shading Units.

+
intel DC GPUTensor CShading UEUsVRAMSCS name part
Max 11005671685648G HBM2eGI3-56-48h
Max 155012816384128128G HBM2eGI3-128-128h
+

Automated tests

+

Errors

+

The following items MUST be detected and reported as an error:

+
    +
  • any syntax error in a name starting with SCS-,
  • +
  • any mismatch between any immediately discoverable property of a flavor (currently, CPU, RAM and disk size) +and the meaning of its name (which is usually a lower bound), such as the CPU generation or hypervisor.
  • +
+

In addition, the following items MAY be reported as an error:

+
    +
  • any mismatch between any non-immediately discoverable property of flavor and the meaning of its name.
  • +
+

Warnings

+

None so far.

+

Implementation

+

The script flavor-names-openstack.py +talks to the OpenStack API of the cloud specified by the OS_CLOUD environment and queries properties and +checks the names for standards compliance.

+

Manual tests

+

To be determined.

+ + \ No newline at end of file diff --git a/standards/scs-0101-v1-entropy/index.html b/standards/scs-0101-v1-entropy/index.html new file mode 100644 index 0000000000..079e99a0d9 --- /dev/null +++ b/standards/scs-0101-v1-entropy/index.html @@ -0,0 +1,115 @@ + + + + + +SCS Entropy | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Entropy

Introduction

+

Entropy in information technology

+

Entropy is a concept that is widely used in the scope of information +technology. It is a measurement of the amount of disorder or randomness in +a system. Entropy is used to measure the amount of information in a +self-contained system, as well as the amount of incertitude that exists in this +system.

+

Real-world uses of entropy

+

Cryptography is a very prominent, albeit not the only application that +heavily relies on entropy for operations such as creating secure keys. +When the available entropy runs out, said operations can stall and +take an abnormally long amount of time, which in turn can lead to +malfunctions, e.g., with OpenSSL or load balancers.

+

Sources of entropy

+

In traditional baremetal systems the amount of incertitude is sourced +from the randomness of the read/write cycles of the disk heads of a disk drive, +bus timings, or keyboard timings, to name a few.

+

More recent methods of generating entropy include measuring IRQ jitter +(available in Linux since kernel 5.4 or, before that, via a daemon such as +HavegeD) as well as dedicated CPU +instructions (available in virtually all major CPUs: RDSEED or RDRAND +on x86_64 and RNDR on arm64).

+

Finally, a dedicated device can be utilized — if present — that is +called hardware random number generator or HRNG for short. For instance, +the Trusted Platform Module +includes a HRNG. On Linux systems, the HRNG appears as /dev/hwrng. +Note that, while the dedicated CPU instructions can be construed as +a HRNG, they are not treated as such by the kernel, i.e., they do not +appear as /dev/hwrng!

+

The Linux kernel combines multiple sources of entropy into a pool. To this +end, it will use all the sources discussed so far with one exception: +the HRNG must be fed into the pool (if so desired) via the daemon rngd. +The kernel converts the entropy from the pool into cryptographically +secure random numbers that appear under /dev/random and /dev/urandom.

+

With kernel 5.18, the algorithm that accomplishes +said conversion has been drastically improved (see +linux-rng-5.17-18), +so much so that running out of entropy is virtually ruled out. +These patches have now also arrived in the upstream LTS images.

+

Entropy in virtual instances

+

Virtual instances or virtual machines do not have the traditional sources +of entropy mentioned above. However, the more recent methods mentioned +above do work just fine (the CPU instructions are not privileged).

+

Alternatively, a virtualized HRNG called virtio-rng can be established +that injects entropy from the host into the instance, where this +entropy can be sourced optionally from either the host's /dev/random or +some HRNG in the host. This virtualized HRNG behaves just like a real +one, that is, it appears as /dev/hwrng, and the daemon rngd must +be used to feed it into the kernel's entropy pool.

+

On a side note, the kernel exposes available HRNGs via the special +directory /sys/devices/virtual/misc/hw_random. In particular, the +file rng_available lists available HRNGs while the file rng_current +contains the HRNG currently used.

+

In summary, with current kernels and CPUs entropy in virtual instances +is readily available to a sufficient degree. In addition, the host's +entropy sources can be injected using virtio-rng if so desired, e.g., +to enable access to a HRNG.

+

Motivation

+

As stated above, good sources of entropy are paramount for many +important applications. This standard ensures that sufficient entropy +will be available in virtual instances.

+

Entropy in SCS clouds

+

Flavors

+

It is recommended that all flavors have the following attribute:

+
hw_rng:allowed=True
+

The following attributes are optional:

+
hw_rng:rate_bytes - The allowed amount of bytes for the the guest
to read from the host's entropy per period.
hw_rng:rate_period - Sets the duration of a read period in seconds.
+

Images

+

It is recommended to use images having a kernel (patch level) version 5.18 +or up. This condition is already satisfied by every mandatory image defined +in the Image Metadata Standard.

+

It is recommended that images activate the attribute hw_rng_model: virtio.

+

The daemon rngd must be installed (usually from rng-tools +or rng-utils).

+

The user may choose to use the virtio-rng device via rngd.

+

Compute nodes

+

Compute nodes must use CPUs that offer instructions for accessing +entropy (such as RDSEED or RDRAND on x86_64 or RNDR on arm64), and +these instructions may not be filtered by the hypervisor.

+

Compute nodes may provide a HRNG via rngd.

+ + \ No newline at end of file diff --git a/standards/scs-0101-w1-entropy-implementation-testing/index.html b/standards/scs-0101-w1-entropy-implementation-testing/index.html new file mode 100644 index 0000000000..3d356f6551 --- /dev/null +++ b/standards/scs-0101-w1-entropy-implementation-testing/index.html @@ -0,0 +1,68 @@ + + + + + +SCS Entropy: Implementation and Testing Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Entropy: Implementation and Testing Notes

Implementation notes

+

With reasonably recent hardware—x86 CPU with RDRAND/RDSEED (Intel from 2012, +AMD from 2015) or ARM CPU with FEAT_RNG or FEAT_RNG_TRAP—and recent VM image—Linux +kernel 5.18 or higher—, there is (almost) nothing to be done.

+

Only the flavor and image attributes required by the standard have to be set:

+
    +
  • flavor extra_spec: hw_rng:allowed=True ,
  • +
  • image property: hw_rng_model: virtio .
  • +
+

Automated tests

+

Images sample

+

Some checks need to be performed on a live instance. For these checks, it is +necessary to choose a sample of VM images to test on.

+

For the time being, the sample MUST contain at least one public image reported +by OpenStack. This may be extended in the future.

+

Errors

+

For every image in the chosen sample, the following items MUST be detected and +reported as an error:

+
    +
  • the service rngd is not running,
  • +
  • the special file /proc/sys/kernel/random/entropy_avail does not contain +the value 256 (pinned since kernel 5.18),
  • +
  • the number of FIPS 140-2 failures exceeds 3 out of 1000 blocks +tested, as determined by cat /dev/random | rngtest -c 1000 .
  • +
+

Note: The latter two items act as surrogates for the following item, which +cannot be detected directly:

+
    +
  • CPU instructions for accessing entropy are not available to the VMs.
  • +
+

Warnings

+

The following items MUST be detected and reported as a warning:

+
    +
  • any flavor missing the attribute hw_rng:allowed=True,
  • +
  • any image missing the attribute hw_rng_model: virtio,
  • +
+

Note that the requirement regarding the kernel patch level will not be +checked, because of two reasons: (a) we already check the file entropy_avail +(see subsection on Errors), and (b) users can always choose a recent image, +as ensured by the image metadata standard.

+

Implementation

+

The script entropy-check.py +connects to OpenStack and performs the checks described in this section.

+

Manual tests

+

None.

+ + \ No newline at end of file diff --git a/standards/scs-0102-v1-image-metadata/index.html b/standards/scs-0102-v1-image-metadata/index.html new file mode 100644 index 0000000000..7b86352673 --- /dev/null +++ b/standards/scs-0102-v1-image-metadata/index.html @@ -0,0 +1,222 @@ + + + + + +SCS Image Metadata | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Image Metadata

Motivation

+

Many clouds offer standard Operating System images for their users' convenience. +To make them really useful, they should contain metadata (properties) to allow +users to understand what they can expect using these images.

+

The specification is targeting images that are managed by the service provider, +provided for public consumption. The spec or parts of it however might turn out +to be useful whenever someone manages images for somebody else's consumption.

+

Overview

+

We categorize the image properties into a few buckets

+
    +
  • Technical requirements and features
  • +
  • Image handling aspects
  • +
  • Licensing/Maintenance/Support aspects
  • +
+

Naming

+

We suggest plain OS images to be named "Distribution Version", +e.g. "openSUSE Leap 15.3" or "Ubuntu 20.04" or "CentOS 8", "Windows Server 2012R2". +We do not normally recommend to add more detailed patch levels into the name.

+

Special variants that include specific non-standard features should be named +"Distribution Version Feature1 Feature2".

+

There are several policies possible to provide updated images to include the latest +bug- and security fixes. This is outlined in update policy description below.

+

Technical requirements and features

+

This is dependent on whether we deal with VM images or container images.

+

For VM images (OpenStack), we recommend to use the properties as described +in the OpenStack Image documentation.

+

The following properties are considered mandatory:

+
    +
  • architecture, hypervisor_type
  • +
  • min_disk (in GiB), min_ram (in MiB)
  • +
  • os_version, os_distro
  • +
  • hw_rng_model, hw_disk_bus (scsi recommended, and then setting hw_scsi_model is also recommended)
  • +
+

Note: Disk sizes tend to be measured in GB = 10^9 and not GiB = 2^30 in the disk industry, but OpenStack uses GiB.

+

The following properties are recommended (if the features are supported):

+
    +
  • os_secure_boot, hw_firmware_type
  • +
  • hw_watchdog_action, hw_mem_encryption, hw_pmu, hw_video_ram, hw_vif_multiqueue_enabled
  • +
+

The trait:XXX=required property can be used to indicate that certain virtual hardware +features XXX are required.

+

Image handling

+

Image updating

+

It is recommended that provider managed images are regularly updated. +This means that users referencing an image by name will always get the latest image for the +operating system indicated by that name (which includes a version number, but not the patch +level).

+

Technically, the thus updated image is a new image and will thus carry a new UUID. +It is recommended that the old image gets renamed (e.g. build date or patch level attached) +and hidden (os_hidden=True), but remains accessible via its (unchanged) UUID for some +time.

+

The update handling by the provider is described via the properties replace_frequency, +uuid_validity, provided_until, and hotfix_hours.

+

The replace_frequency, provided_until, and hotfix_hours fields reference to the image +as referenced by its name.

+
replace_frequencymeaning
yearlythe image will get replaced at least once per year
quarterlythe image will get replaced at least once per quarter
monthlythe image will get replaced at least once per month
weeklythe image will get replaced at least once per week
dailythe image will get replaced at least once per day
critical_bugthe image will get replaced for critical issues only
neverthe image referenced by name will never change (until the date provided_until)
+

Note the at least wording: Providers can replace images more often. +The frequency is starting from the first release; so an image published on 2021-04-14 with an +update frequency of monthly, should be replaced no later than 2021-05-14. Due to weekends +etc., up to 3 days later is not considered a violation of this policy. So a valid sequence +from an image with monthly update frequency might be 2021-04-14, 2021-05-14, 2021-06-15, +2021-07-14, 2021-07-27 (hotfix), 2021-08-13 ...

+

Promises to update the registered public images typically depend on upstream image providers +(Linux distributors, OS vendors) keeping their promises to build and provide updated images. +Failures from upstream are not a reason to claim the cloud provider to be in violation of his +promises. However, if the provider observes massive upstream failures (which can e.g. cause +increased security risks), we advise the provider to inform the users.

+

We recommend updating images at least monthly.

+

The hotfix_hours field indicates how providers deal with critical security issues +that affect the images; it is an optional field that contains a numerical value, indicating +how quickly (in hours) a new image is provided after the latter of the points in time that +the issue becomes public and a tested fix is available as maintenance update from the upstream +distribution. A value of 0 indicates a best-effort approach without firm SLAs; the field not +being present indicates no commitment. A value of 48 would indicate that the provider +commits to a new image within 48hrs. A critical issue is defined as a security vulnerability +with a CVSS score of 9.0 or higher that affects software that is included in the image.

+

The provided_until field is supposed to contain a date in YYYY-MM-DD format that +indicates until when an image under this name will be provided and (according to the +replace_frequency) updated at least. (Providers are free to provide updates for +longer or leave the non-updated image visible for longer.) +If this field is set to none, no promises are made, if it is set to notice, updates +will be provided until a deprecation notice is published. (The values are the same as +for below uuid_validity, except that forever and last-N don't make any sense.)

+

The uuid_validity field indicates how long the public image will be referencable +by its UUID.

+
uuid_validitymeaning
noneUUID will only be valid as long as the content does not change
last-NThe last N images for newer replacement will remain accessible via UUID
YYYY-MM-DDUUID will be valid until at least the date YYYY-MM-DD
noticeUUID will remain valid until a deprecation notice will be published
foreverUUID will remain valid for as long as the cloud operates
+

Note that the old images must be hidden from the image catalogue or renamed (or both) +to avoid failing referencing by name. Note that last-N may be limited by the provided_until +date. We recommend providers that keep old images according to the advertized uuid_validity +to hide older images (setting the os_hidden property to True). If the outdated images must +remain visible, the recommendation is to rename the images by attaching a datestamp in the +format " YYYYMMDD" to the name where the date must reflect the build_date of the image.

+

The three properties uuid_validity, provided_until and replace_frequency are mandatory; +the field hotfix_hours is optional.

+

All dates are in UTC.

+

Example

+

Providing an image with name OPSYS MAJ.MIN with +replace_frequency=monthly, provided_until=2022-09-30, uuid_validity=2022-12-31, +hotfix_hours=0 +means that we will have a new image with this name at least once per month (starting from +the initial release) until the end of September 2022. Old images will be hidden and/or +renamed, but remain accessible via their UUID until at least the end of 2022 (in Universal Time). +The provider makes an effort to replace images upon critical security issues out of order.

+

Image Origin

+
    +
  • +

    Mandatory: image_source needs to be a URL to point to a place from which the image can be downloaded. +(Note: This may be set to the string "private" to indicate that the image can not be freely +downloaded.)

    +
  • +
  • +

    Mandatory: image_description needs to be a URL (or text) with release notes and other human-readable +data about the image.

    +
  • +
  • +

    Recommended tag: managed_by_VENDOR

    +
  • +
+

Note that for most images that come straight from an upstream source, image_description should point +to an upstream web page where these images are described. If download links are available as well +on that page, image_source can point to the same page, otherwise a more direct link to the image +should be used, e.g. directly linking the .qcow2 or .img file. +If providers have their own image building machinery or do some post-processing on top of +upstream images, they should point to the place where they document and offer these images.

+

Image build info

+
    +
  • +

    Mandatory: image_build_date needs to be YYYY-MM-DD or YYYY-MM-DD hh:mm[:ss] (time in UTC, +24hrs clock). +All publicly released and generally recommended patches before this date must be included in the +image build. If the cutoff date is earlier, this cutoff date needs to be set instead, even +if the actual build happens significantly after the cutoff date. If not all patches can be +included for a good reason, then the patchlevel field (see below) must be used to describe +the patch status.

    +
  • +
  • +

    Mandatory: image_original_user is the default login user for the operating system which can connect +to the image via the injected SSH key or provided password. (This can be set to none if no default +username exists for the operating system.)

    +
  • +
  • +

    Optional: patchlevel can be set to an operating specific patch level that describes the +patch status — typically we would expect the image_build_date to be sufficient.

    +
  • +
  • +

    Recommended: os_hash_algo and os_hash_value: The sha256 or sha512 hash +for the image file. (This references the image file in the format it is stored in, we +recommend raw over qcow2 for systems that use ceph.) Note that these values are +typically generated automatically upon image registration.

    +
  • +
  • +

    Recommended tag: os:OPERATINGSYSTEM

    +
  • +
+

Licensing / Maintenance subscription / Support

+

Some images require a license; in many cases the cloud providers include the license cost +by a per-use (e.g. hourly) fee. However, it is also possible sometimes that customers +use their own license agreements with the OS vendor with a bring-your-own-license (BYOL) +program. These properties may be attached to the image. Note that free Linux images +might not use any of these properties, except maybe maintained_until. Note that +Windows images would typically require license_included, subscription_included. +A boolean property that is not present is considered to be false.

+
    +
  • Optional: license_included (boolean) indicates whether the flavor fee +includes the licenses required to use this image. This field is mandatory for +images that contain software that requires commercial licenses.
  • +
  • Optional: license_required (boolean) indicates whether a customer must bring +its own license to be license compliant. This can not be true at the same time as the +previous setting. This field is mandatory IF customers need to bring their own +license to use the image.
  • +
  • Optional: subscription_included (boolean) indicates that the image contains already +a maintenance subscription which typically gives access to bug fixes, security +fixes and (minor) function updates. If a subscription is included, the CSP should +have prepared the image to also receive the provided maintenance updates from the +vendor (optionally via a mirror).
  • +
  • Optional: subscription_required (boolean) indicates that the customer requires +a maintenance subscription from the OS vendor in order to receive fixes +(which is often also a prerequisite to be eligible for support).
  • +
  • Optional: maintained_until: YYYY-MM-DD promises maintenance from the OS vendor +until at least this date (in UTC).
  • +
  • Optional: l1_support_contact contains a URI that provides customer support +contact for issues with this image. Note that this field must only be set if the +service provider does provide support for this image included in the image/flavor +pricing (but it might be provided by a contracted 3rd party, e.g. the OS vendor).
  • +
+

Conformance Tests

+

The script image-md-check.py retrieves the +image list from a configured cloud and checks each image for the +completeness and consistency of mandatory properties.

+ + \ No newline at end of file diff --git a/standards/scs-0102-w1-image-metadata-implementation-testing/index.html b/standards/scs-0102-w1-image-metadata-implementation-testing/index.html new file mode 100644 index 0000000000..e4cb3511b5 --- /dev/null +++ b/standards/scs-0102-w1-image-metadata-implementation-testing/index.html @@ -0,0 +1,37 @@ + + + + + +SCS Image Metadata: Implementation and Testing Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Image Metadata: Implementation and Testing Notes

Implementation notes

+

The OpenStack Image Manager from OSISM +will create a set of images from a "spec file" provided by the user, which can also set the required properties +for these images.

+

Automated tests

+

Images sample

+

Some checks need to be performed on a live instance. All publicly available images on this instance +will be checked for either only the mandatory properties or possibly also the recommended ones. +Additionally, a user can also decide to test their private images, although this isn't a necessity.

+

Implementation

+

The script image-md-check.py +connects to OpenStack and performs the checks described in this section.

+

Manual tests

+

None.

+ + \ No newline at end of file diff --git a/standards/scs-0103-v1-standard-flavors/index.html b/standards/scs-0103-v1-standard-flavors/index.html new file mode 100644 index 0000000000..34a1c6064b --- /dev/null +++ b/standards/scs-0103-v1-standard-flavors/index.html @@ -0,0 +1,151 @@ + + + + + +SCS Standard Flavors and Properties | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Standard Flavors and Properties

Introduction

+

This is v1.1 of the standard, which lifts the following restriction regarding the property scs:name-vN: +this property may now be used on any flavor, rather than standard flavors only. In addition, the "vN" is +now interpreted as "name variant N" instead of "version N of the naming standard". Note that this change +indeed preserves compliance, i.e., compliance with v1.0 implies compliance with v1.1.

+

Terminology

+

extra_specs +Additional properties on an OpenStack flavor, see +OpenStack Nova user documentation +and +OpenStack Nova configuration documentation.

+

Motivation

+

In OpenStack environments there is a need to define different flavors for instances. +The flavors are pre-defined by the operator, the customer can not change these. +OpenStack providers thus typically offer a large selection of flavors.

+

While flavors can be discovered (openstack flavor list), it is helpful for users (DevOps teams), +to have a guaranteed set of flavors available on all SCS clouds, so these need not be discovered.

+

Properties (extra_specs)

+

The following extra_specs are recognized, together with the respective semantics:

+
    +
  • scs:name-vN=NAME (where N is a positive integer, and NAME is some string) means that +NAME is a valid name for this flavor according to any major version of the SCS standard on +flavor naming.
  • +
  • scs:cpu-type=shared-core means that at least 20% of a core in >99% of the time, +measured over the course of one month (1% is 7,2 h/month). The cpu-type=shared-core +corresponds to the V cpu modifier in the flavor-naming spec, +other options are crowded-core (L), dedicated-thread (T) and dedicated-core (C).
  • +
  • scs:diskN-type=ssd (where N is a non-negative integer, usually 0) means that the +root disk N must support 1000 sequential IOPS per VM, and it must be equipped with +power-loss protection; see scs-0110-v1-ssd-flavors. +The diskN-type=ssd setting corresponds to the s disk modifier, other options +are nvme (p), hdd (h) and network (n). Only flavors without disk and +those with diskN-type=network can be expected to support live-migration.
  • +
+

Whenever ANY of these are present on ANY flavor, the corresponding semantics must be satisfied.

+

The extra_spec scs:name-vN is to be interpreted as "name variant N". This name scheme is designed to be +backwards compatible with v1.0 of this standard, where scs:name-vN is interpreted as +"name according to naming standard vN". We abandon this former interpretation for two reasons:

+
    +
  1. the naming standards admit multiple (even many) names for the same flavor, and we want to provide a means +of advertising more than one of them (said standards recommend using two: a short one and a long one),
  2. +
  3. the same flavor name may be valid according to multiple versions at the same time, which would lead to +a pollution of the extra_specs with redundant properties; for instance, the name +SCS-4V-16 is valid for both scs-0100-v2 and +scs-0100-v3, and, since it does not use any extension, it will be valid +for any future version that only changes the extensions, such as the GPU vendor and architecture.
  4. +
+

Note that it is not required to use consecutive numbers to number the name variants. +This way, it becomes easier to remove a single variant (no "closing the gap" required).

+

If extra_specs of the form scs:name-vN are used to specify SCS flavor names, it is RECOMMENDED to include +names for the latest stable major version of the standard on flavor naming.

+

Standard SCS flavors

+

Following are flavors that must exist on standard SCS clouds (x86-64). +Note that this statement does not preclude the existence of additional flavors.

+

Mandatory

+
Recommended namevCPUsvCPU typeRAM [GiB]Root disk [GB]Disk type
SCS-1V-41shared-core4
SCS-2V-82shared-core8
SCS-4V-164shared-core16
SCS-4V-16-100s4shared-core16100ssd
SCS-8V-328shared-core32
SCS-1V-21shared-core2
SCS-2V-42shared-core4
SCS-2V-4-20s2shared-core420ssd
SCS-4V-84shared-core8
SCS-8V-168shared-core16
SCS-16V-3216shared-core32
SCS-1V-81shared-core8
SCS-2V-162shared-core16
SCS-4V-324shared-core32
SCS-1L-11crowded-core1
+ +
Recommended namevCPUsvCPU typeRAM [GiB]Root disk [GB]Disk type
SCS-1V-4-101shared-core410(any)
SCS-2V-8-202shared-core820(any)
SCS-4V-16-504shared-core1650(any)
SCS-8V-32-1008shared-core32100(any)
SCS-1V-2-51shared-core25(any)
SCS-2V-4-102shared-core410(any)
SCS-4V-8-204shared-core820(any)
SCS-8V-16-508shared-core1650(any)
SCS-16V-32-10016shared-core32100(any)
SCS-1V-8-201shared-core820(any)
SCS-2V-16-502shared-core1650(any)
SCS-4V-32-1004shared-core32100(any)
SCS-1L-1-51crowded-core15(any)
+

Guarantees and properties

+

The figures given in the table (number of CPUs, amount of RAM, root disk size) must match +precisely the corresponding figures in the flavor.

+

In addition, the following properties must be set (in the extra_specs):

+
    +
  • scs:name-v1 to the recommended name, but with each dash AFTER the first one replaced by a colon,
  • +
  • scs:name-v2 to the recommended name,
  • +
  • scs:cpu-type to shared-core or crowded-core, reflecting the vCPU type,
  • +
  • scs:disk0-type not set if no disk is provided, otherwise set to ssd or some other +value, reflecting the disk type.
  • +
+

Remarks

+

We expect the most used vCPU

GiB
ratio to be 1:4.

+

Note that all vCPUs of SCS standard flavors are oversubscribed — the smallest 1L-1 +flavor allows for heavy oversubscription (note the L), and thus can be offered very +cheaply — imagine jump hosts ...

+

The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM +compute hosts) to offer all flavors.

+

Except for the two flavors with SSD root volume, disks types are not specified +(and expected to be network disks (Ceph/Cinder) or local SATA/SAS disks typically).

+

We only included a limited variation of disk sizes — this reflects that +for the standard networked cinder +disks, you can pass block_device_mapping_v2 on server (VM) creation to +allocate a boot disk of any size you desire. We have scaled the few +recommended disk sizes with the amount of RAM. For each flavor there is +also one without a pre-attached disk — these are meant to be used +to boot from a volume (either created beforehand or allocated on-the-fly +with block_device_mapping_v2, e.g. +openstack server create --flavor SCS-1V-2 --block-device-mapping sda=IMGUUID:image:12:true +to create a bootable 12G cinder volume from image IMGUUID that gets tied to the VM +instance life cycle.)

+

Conformance Tests

+

The script flavors-openstack.py +will read the lists of mandatory and recommended flavors +from a yaml file provided as command-line argument, connect to an OpenStack installation, +and check whether the flavors are present and their extra_specs are correct.

+

Missing flavors will be reported on various logging channels: error for mandatory, warning for +recommended flavors. Incorrect extra_specs will be reported as error in any case. +The return code will be non-zero if the test could not be performed or if any error was +reported.

+

The script does not check whether a name given via the extra_spec scs:name-vN is indeed valid according +to any major version of the SCS standard on flavor naming.

+

Operational tooling

+

The openstack-flavor-manager is able to +create all standard, mandatory SCS flavors for you. It takes input that can be generated by +flavor-manager-input.py.

+

Previous standard versions

+

The list of standard flavors used to be part of the flavor naming standard up until +version 3. The following changes have been made to +the list in comparison with said standard:

+
    +
  • the flavor names have been turned into recommendations, and
  • +
  • the properties have been introduced in order to help discoverability.
  • +
+

Note that the flavors with fixed size root disks have all moved to Recommended +with scs-0100-v3. +This means that they are not a certification requirement any longer, +but we still recommend implementing these for backwards compatibility reasons. +Also in that standard, two flavors with SSD+ root disks have been added, as defined in +scs-0110-v1-ssd-flavors.md

+ + \ No newline at end of file diff --git a/standards/scs-0104-v1-standard-images/index.html b/standards/scs-0104-v1-standard-images/index.html new file mode 100644 index 0000000000..08398184c0 --- /dev/null +++ b/standards/scs-0104-v1-standard-images/index.html @@ -0,0 +1,105 @@ + + + + + +SCS Standard Images | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Standard Images

Introduction

+

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.

+

To this end, SCS unifies the naming and sourcing of virtual machine images, and for certain images their presence is mandated or recommended.

+

Motivation

+

Following the example of the SCS standards YAML, +this standard establishes, by means of a YAML file, a mechanism with the following main objectives:

+
    +
  • to maintain a list of mandatory, recommended, and optional images, which also fixes the source location,
  • +
  • to provide a machine-readable document for further processing (e.g. for a compliance tool suite or continuous integration).
  • +
+

Uploading custom images

+

Image upload via Glance MUST be allowed based on a fair-use policy.

+

Standard images YAML

+

The YAML file MUST contain the key images, whose value is a list of objects. Each object has one of two forms, as described below.

+

Image specification, single image

+
KeyTypeDescriptionExample
nameStringName of the image"Debian 12"
statusString (optional)optional (default), mandatory or recommended"recommended"
sourceStringPrefix of the source URL"https://cloud.debian.org/images/cloud/bookworm/"
OR: List of stringsmultiple possible prefixes(see full example below)
+

The meaning of this specification is as follows.

+
    +
  1. If the status is mandatory, then an image with the name given via name MUST be present.
  2. +
  3. If the status is recommended, then an image with the name given via name SHOULD be present.
  4. +
  5. Regardless of the status: +if an image with the name given is present, then its image_source property +(as described in the Image Metadata standard) +MUST start with one of the prefixes given via source.
  6. +
+

Image specification, class of images

+
KeyTypeDescriptionExample
nameStringName of the class of images"ubuntu-2204-kube"
name_schemeString (regex)Regular expression for the image name"ubuntu-2204-kube-v[0-9].[0-9]+(.[0-9]+)?"
statusString (optional)optional (default), mandatory or recommended"recommended"
sourceStringPrefix of the source URL"https://swift.services.a.regiocloud.tech"
OR: List of stringsmultiple possible prefixes(see full example below)
+

The meaning of this specification is as follows:

+
    +
  1. If the status is mandatory, then at least one image MUST be present whose name +matches the regular expression given via name_scheme.
  2. +
  3. If the status is recommended, then at least one image SHOULD be present whose name +matches the regular expression given via name_scheme.
  4. +
  5. Regardless of the status: +for any image whose name matches the regular expression given via name_scheme, +its image_source property MUST start with one of the prefixes given via source.
  6. +
+

Full example

+
images:
- name: "Ubuntu 22.04"
source:
- https://cloud-images.ubuntu.com/releases/jammy/
- https://cloud-images.ubuntu.com/jammy/
status: mandatory
- name: "ubuntu-capi-image"
name_scheme: "ubuntu-capi-image v[0-9]\\.[0-9]+(\\.[0-9]+)?"
source: https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-k8s-capi-images/ubuntu-2204-kube
status: recommended
- name: "Ubuntu 20.04"
source:
- https://cloud-images.ubuntu.com/releases/focal/
- https://cloud-images.ubuntu.com/focal/
- name: "Debian 12"
source:
- https://cloud.debian.org/images/cloud/bookworm/
- https://cdimage.debian.org/cdimage/cloud/bookworm/
- name: "Debian 11"
source:
- https://cloud.debian.org/images/cloud/bullseye/
- https://cdimage.debian.org/cdimage/cloud/bullseye/
+

This example provides allowable source prefixes for two Debian versions, two Ubuntu +versions, and for any version of the Kubernetes cloud API provider. Only the latter is +recommended, while only Ubuntu 22.04 is mandatory.

+

Lifecycle considerations

+

YAML lifecycle

+

The YAML file is generally located under +https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/.

+

Any change that could render existing installations non-conformant (i.e., when new +specifications are added, when the name scheme of a specification is changed to +match more names than before, when the status of an existing specification changes to +mandatory, or when some source prefix is removed) requires a new YAML file to be created. +As a consequence, any currently valid certificates stay valid; the change can only take +effect in a new version of the certificate in question, if so desired.

+

Image lifecycle

+

It is important to note that this standard does not prohibit any images, and neither +does it preclude the operator from providing any and all optional images.

+

It is possible that a specification is mandatory in one version and non-mandatory in the +next version. This standard makes no statement as to what is supposed to happen to the +corresponding images in a live cloud environment. It is recommended to keep the +once-mandatory images in the live environment. As for new environments, it is up to the +operator whether to provide any or all of these images, as stated above.

+

Conformance Tests

+

The script images-openstack.py will read the lists of mandatory and recommended images +from a yaml file provided as command-line argument, connect to an OpenStack installation, +and check whether the images are present. Missing images will be reported on various +logging channels: error for mandatory, info for recommended images. Additionally, images +whose image_source does not conform with the specifications will be reported on the +error channel. The return code will be non-zero if the test could not be performed or +if any errors have been reported.

+

Operational tooling

+

The openstack-image-manager is able to +create all standard, mandatory SCS images for you given image definitions from a YAML file.

+ + \ No newline at end of file diff --git a/standards/scs-0104-w1-standard-images-implementation/index.html b/standards/scs-0104-w1-standard-images-implementation/index.html new file mode 100644 index 0000000000..c755d4fbfe --- /dev/null +++ b/standards/scs-0104-w1-standard-images-implementation/index.html @@ -0,0 +1,68 @@ + + + + + +SCS Standard Images: Implementation Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Standard Images: Implementation Notes

Introduction

+

The SCS standard on standard images does not in itself lay down what images are actually +required or recommended; rather it specifies the format of a YAML file that in turn serves +said purpose. The particular YAML file that an implementer (a cloud service provider or operator) +has to comply with is given in the respective version of the certificate scope "SCS-compatible IaaS" +as a parameter to the standard. This document is intended to give implementers a +step-by-step guide on how to comply with the SCS certificate scope.

+

Step-by-step walkthrough

+

Option A: pragmatic

+

Run the test script on your environment and check the error messages :)

+
    +
  1. +

    Check out the standards repository.

    +
    git clone https://github.com/SovereignCloudStack/standards.git
    cd standards
    +
  2. +
  3. +

    Install requirements:

    +
    python3 -m venv .venv && source .venv/bin/activate
    pip install -r requirements.txt
    +
  4. +
  5. +

    Make sure that your OS_CLOUD environment variable is set.

    +
  6. +
  7. +

    Run the main check script:

    +
    python3 ./Tests/scs-compliance-check.py ./Tests/scs-compatible-iaas.yaml -t standard-images-check \
    -s $OS_CLOUD -a os_cloud=$OS_CLOUD -o report.yaml -C
    +
  8. +
  9. +

    Inspect console output (stderr) for error messages.

    +
  10. +
+

Option B: principled

+
    +
  1. Find your intended version of the certificate scope in the overview table. It will most likely be one whose 'State' is 'Effective' or 'Stable'.
  2. +
  3. In (or below) the row labeled 'scs-0104: Standard images', you find a link to the YAML file that lists mandatory and recommended images, such as scs-0104-v1-images.yaml for v4 of the certificate scope.
  4. +
  5. For each entry under images, ensure the following (either manually or by using the OpenStack Image Manager described in the section "Operational Tooling"): +
      +
    • if the entry says status: mandatory, your environment MUST provide this image, i.e., an image whose name matches the name_scheme or (in absence of a name scheme) the name.
    • +
    • every actual image in your environment that matches the name_scheme or (in absence of a name scheme) the name has the correct image_source property: its value MUST start with one of the prefixes listed under source.
    • +
    +
  6. +
+

Operational Tooling

+

The openstack-image-manager is able to +create all standard, mandatory SCS images for you given image definitions from a YAML file. +Please see its documentation for details.

+ + \ No newline at end of file diff --git a/standards/scs-0110-v1-ssd-flavors/index.html b/standards/scs-0110-v1-ssd-flavors/index.html new file mode 100644 index 0000000000..7a2ff80288 --- /dev/null +++ b/standards/scs-0110-v1-ssd-flavors/index.html @@ -0,0 +1,227 @@ + + + + + +SSD Flavors | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SSD Flavors

Introduction

+

SCS defines an IaaS Flavor Naming standard that mandates a number of standard flavors +to be available in each SCS-compliant IaaS offering. While offering or exposing +IaaS is not a requirement for SCS-compliant infrastructure offerings — SCS allows +for platforms only exposing the container layer (plus S3 compatible object storage) +for wave 2 (container-based) cloud-native workloads -- +the SCS reference implementation does include a complete IaaS implementation that +many providers want to expose as they have customers desiring access at this layer +for wave 1 (VM-based) cloud-native workloads or for the virtualization of more +classical (not cloud-native) workloads. The IaaS implementation thus comes with +standards.

+

This Decision Record is about adding a few mandatory flavors on the IaaS level +that include flavors with local SSD (or better) storage.

+

Motivation

+

The currently defined standard flavors +do not include +flavors that use local storage. For certain workloads such as databases or big data +filesystems, local storage is highly desirable as replication may be handled at +the application layer, making replication/redundancy in a networked storage solution +(ceph in the SCS reference implementation) an unneeded and undesired property. +Furthermore, write access to networked and replicated storage typically incurs +a certain latency, as the writes can only be acknowledged once all the replicas +have confirmed that the data has hit stable storage. Write latency is critical +for e.g. relational database performance.

+

The main purpose for the IaaS layer in SCS is to perform as a solid foundation +to provide and manage kubernetes container clusters in a multi-tenant scenario. +As such the standards at the IaaS layer should ensure that all the needed +types of resources are available for the container clusters. This is not +currently the case: In a scenario with multiple k8s control-plane nodes set +up via kubeadm (as part of the k8s cluster-api automation), the control plane +nodes each run an etcd instance and together form an etcd cluster.

+

etcd is sensitive to scheduling, network and storage latencies. While network +latencies and scheduling latencies have not been observed to be an issue in +clusters within one cloud region, the storage latency is. With remote networked +storage as delivered from ceph, the long tail of write latency causes etcd +to often time out heartbeats, causing a new leader election with a leader +change, preventing control plane changes on k8s for a few seconds. Too many +leader changes can slow down cluster operation and even bring it to a halt.

+

The etcd requirements are well documented. +In particular, over a hundred of sequential IOPS are recommended. This +requires write latencies in the range of a single-digit ms (or better).

+

Design Considerations

+

Options considered

+

One-node etcd (backed by redundant storage)

+

If k8s uses only one control plane node, there will only be one etcd node, +avoiding timed out heartbeats. Single node control planes are typically not +recommended for production workloads though. They are limited with respect +to control plane performance, have a higher chance to fail (as a single node failure +can create cluster control-plane downtime) and can not undergo rolling upgrades.

+

Though not the normal setup with kubeadm, it is possible to use a multi-node +control plane using a single-node etcd. This shares some of the challenges of +single-node control-planes, although recovery may be faster to perform at least +in scenarios where the etcd backend storage is redundant and not affected by the +single-node outage.

+

Neither scenario fulfills typical requirements for production workloads.

+

RAM (tmpfs) etcd storage

+

etcd could keep its database in volatile memory (e.g. on a tmpfs filesystem). +For multi-node etcd clusters, this could actually be made work, as long as at +least one cluster member stays alive and proper care is taken to remove shut-down +nodes from the cluster. A loss of power affecting all nodes or a hardware +maintenance operation not tracking etcd needs would result in a complete +loss of all cluster state. The control plane nodes would require live migration +to avoid this in the maintenance case. For the power loss scenario, a frequent +backup might mitigate the cluster state loss case somewhat.

+

The etcd database is normally limited to 2GiB in size, which is something +that is realistic to keep in main memory. (Typical database sizes are +much smaller.)

+

This option requires additional care and may not be suitable for all +production scenarios, but would seem a possible fallback position for +etcd. It does obviously not address the database scenario.

+

Heartbeat slowdown

+

To avoid causing too many fail-overs by occasional high latencies, the +frequency of heartbeats can be lowered from the default 1/100ms. +The reelection timeout should change along with it (typically set to +10 beats).

+

This will cause etcd to take a bit more time to notice the loss of a node, +which is not typically critical if done within reasonable limits. +This change however does not fully address the issue — occasional write latencies +above 100ms will still cause failed heartbeats, just less often.

+

This change has been implemented in the +k8s-cluster-api-provider +reference implementation: The heartbeat has been changed from 1/100ms (10/s) +to 1/250ms (4/s) and the reelection timeout from 1s to 2.5s.

+

The etcd process also is afforded a higher CPU priority (lower niceness), +resulting in a lower scheduling latency, as high-prio processes preempt lower-prio +ones when they get woken up. The etcd process also gets its IO priority +increased to get treated preferentially in case the IO scheduler has many +outstanding requests. This has some positive effects with the CFQ IO scheduler.

+

The slower heartbeat and the priority tweaks do lower the amount of leader +changes but are insufficient to completely address the issue on the tests +performed against networked ceph-backed storage.

+

Filesystem tuning

+

Databases must ensure that certain data has hit stable storage before acknowledging +writes — this is required in order to live up to the ACID +guarantees in situations when disruptions might happen. Databases typically use +fsync() calls to ensure that write buffers are written to real persistent storage +unless they use raw/direct block devices circumventing Linux's page and buffer cache.

+

etcd normally uses a write-ahead-log (WOL) file that lives on a Linux filesystem and +uses fsync to ensure the correct write ordering. Trouble with fsync is that it +also causes unrelated data to be written out with most existing Linux filesystems, +adding to the latency.

+

It is possible to tell the Linux filesystems to not wait for all data to have hit +storage before returning from fsync() calls. This avoids the latency caused by +fsync but also subverts the very reason for using fsync: In case of a disruption +(OS crash, power outage, loss of connection to storage, ...), the state is likely +not consistent, as the kernel has lied to the application about data having been +written out. Recovery from such a scenario can range from smooth to impossible.

+

In a multi-node cluster, this may not be as bad as it sounds — if only one +node is affected by a disruption, the crashed node can be recovered by resyncing +the data from other nodes. In practice an inconsistent state would be considered +too risky, and it should be preferred to set up a fresh node to join the +existing etcd cluster. This would need to be implemented to make this option +less risky.

+

The reference implementation has an option to use these unsafe filesystem settings. +However, they are not enabled by default for good reasons.

+

Flavors with local storage

+

Flavors with local storage will have their root filesystem on a local storage +device. To fulfill the need for high IOPS that etcd and especially databases +have, the local storage device should be a solid state device — an SSD or +NVMe device. While some use cases might even be fulfilled with local +spinning disks (or raid arrays of local spinning disks).

+

Local solid state storage avoids any network overhead and offers best latency. +It however is not typically redundant, meaning that the loss of the device +or the complete hardware node will result in data loss. So it is meant to +be used with applications such as database clusters, replicating filesystems +or block devices or etcd which can handle this at the application layer.

+

The flavor naming spec in SCS allows performance to be understated — a +flavor with NVMe storage can be advertised under the SSD storage name +(and of course can be offered under both names).

+

Note that this addresses the simple case where the root disk with the +root filesystem (and possibly additional filesystems that are set up +when first booting) uses the local storage. Scenarios where additional +low-latency networked or local storage are made available via cinder +and attached for database storage are possible and viable options for +some scenarios, but not covered here.

+

Decision

+

Two new mandatory flavors: SCS-2V-4-20s and SCS-4V-16-100s are added +to the SCS flavor naming standard. The first is meant to be a good fit for +k8s control nodes with etcd while the latter is a solid base for a +small database server. Clouds claiming SCS-compliance for their IaaS +layer MUST provide these two additional flavors.

+

Obviously providers MAY offer many more combinations and e.g. create +flavors with large local SSDs.

+

The local storage advertised this way MUST support more than +1000 sequential IOPS per VM of both new mandatory types (which means a +write latency lower than 1ms — this typically means SSDs/NVMEs that +support at least several 10ks of parallel IOPS, not a challenge for +current hardware).

+

Local disks, SSDs, NVMes MUST have Power-Loss-Protection such that +data reported to be written, but in reality being stored in RAM or SLC +cache of an SSD or NVMe, is guaranteed to not be lost in case of a power +loss.

+

Like with networked storage, the provider must ensure that data +from previous users is not accessible (e.g. by securely erasing it +or by using a different encryption key) when local storage gets +allocated to a new VM.

+

Out of Scope

+

Hardware nodes (hypervisors in OpenStack language) that support flavors +with local storage (are part of an appropriate OpenStack host aggregate) +may have many VMs competing for bandwidth to the attached local storage +devices; the host needs to be configured such that it can sustain VMs +writing at full speed without causing the host to be overloaded or +to cause huge queues for these writes.

+

A more generic approach is to apply storage QoS policies to the VMs to +manage bandwidth and IOPS and create the ability to have better +performance isolation with certain guarantees. While this is desirable, +it has not been found a necessity for etcd in our tests. +Disk IO QoS is not part of this spec but may be considered in another one.

+

Live-migration with local storage is significantly more difficult than with +networked storage: The contents of the local disks also need to be replicated +over to the new host. Live-migration for these VMs may thus take significantly +longer or not be possible at all, depending on the configuration from the provider. +Not supporting live-migration is OK for flavors with local disks according +to the flavor naming spec — a capability to indicate whether +live-migration is supported will be subject to a flavor-metadata discoverability +spec that is planned for the future.

+

Implementation note

+

Local storage in OpenStack can be provided directly via nova or via the +cinder service. While the latter has the advantage of making volumes +visible and manageable via most of the normal cinder capabilities, it +has the disadvantage of creating an indirection via iSCSI. This +results in higher latency. The requirements in the above spec are +not meant to mandate or prevent the implementation via either route.

+ +

The flavors will be added as mandatory flavors to the +flavor-naming standard, +which will thus have to be released in a v3.

+

The IOPS and Power-Loss requirements from this decision should become +part of the flavor-naming standard for disk type s.

+

When we standardize storage types in the future, additional possibilities +to solve the latency requirements for databases and etcd may emerge.

+

When we standardize QoS features there, we may amend this standard with +QoS recommendations or possibly requirements.

+

A future flavor metadata discoverability standard will indicate whether +these flavors can be live-migrated. A future VM metadata standard will allow +users to request live-migration and/or cold migration or restart to be or to +not be performed.

+

Conformance Tests

+

The list of mandatory flavors that needs to be present should be added to the +SCS-Spec.MandatoryFlavors.yaml +spec as soon as this ADR becomes part of the certification requirements.

+

Checks for conforming with IOPS and purging requirements will require +test instances to be launched and might become part of a monitoring +solution.

+ + \ No newline at end of file diff --git a/standards/scs-0111-v1-volume-type-decisions/index.html b/standards/scs-0111-v1-volume-type-decisions/index.html new file mode 100644 index 0000000000..2a38400396 --- /dev/null +++ b/standards/scs-0111-v1-volume-type-decisions/index.html @@ -0,0 +1,73 @@ + + + + + +Decisions for the Volume Type Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Decisions for the Volume Type Standard

Introduction

+

Volumes in OpenStack are virtual drives. They are managed by the storage service Cinder, which abstracts creation and usage of many different storage backends. While it is possible to use a backend like lvm which can reside on the same host as the hypervisor, this decision record wants to make a more clear differentiation between volumes and the ephemeral storage of a virtual machine. For all SCS deployments we want to assume that volumes are always residing in a storage backend that is NOT on the same host as a hypervisor - in short terms: Volumes are network storage. Ephemeral storage on the other hand is the only storage residing on a compute host. It is created by creating a VM directly from an Image and is automatically lost as soon as the VM cease to exist. Volumes on the other hand have to be created from Images and only after that can be used for VMs. They are persistent and will remain in the last state a VM has written on them before they cease to exit. Being persistent and not relying on the host where the VM resides, Volumes can easily be attached to another VM in case of a node outage and VMs be migrated way more easily, because only metadata and data in RAM has to be shifted to another host, accelerating any migration or evacuation of a VM.

+

Volume Types are used to classify volumes and provide a basic decision for what kind of volume should be created. These volume types can sometimes very be backend-specific, and it might be hard for a user to choose the most suitable volume type, if there is more than one default type. Nevertheless, most of the configuration is done in the backends themselves, so volume types only work as a rough classification.

+

Motivation

+

We want to standardize a few varieties of volume types. While a user can choose simple things like size when creating a volume, Volume Types define a few broader aspects of volume. Encryption of volumes for example is solely decided by the volume type. And whether the volume will be replicated is a mix between definition in the volume type and backend specific configuration, but it's visibility can only be reached in the volume type.

+

In General: what the different volume types are capable of is highly dependent on both the used backend and the configurations of OpenStack. A few options are worth being at least recommended.

+

Design Considerations

+

We want to have a discoverable Standard. So there should be no naming conventions as per request by operators.

+

This first decision will have impacts on upstream OpenStack development, as those things, that would be nice to discover, may not be currently discoverable by users or not at all.

+

There are several aspects of volume types, which will be discussed in the following:

+

Options considered

+

Encryption

+

Encryption for volumes is an option which has to be configured within the volume type. As an admin it is possible to set encryption-provider, key size, cipher and control location. As an admin it is also currently possible to see these configurations in a volume type with list and show commands. A user should not see these parameters in detail, but a boolean value that describes whether encryption is used or not. Currently, this is not possible in upstream OpenStack.

+

Conclusion: This is a solid aspect to be standardized. But it will need work on OpenStack, to have a boolean value presented to the users.

+

Backend Name

+

OpenStack Cinder works with a lot of different backends. They all have some kind of special features, which might be attractive for a user. But showing the name of the backend to users is also considered a security risk by Cinder developers. Overall it is always an option to make users aware of special features through the name and description of a volume type and sometimes even through extra_specs.

+

Conclusion: This should not be standardized.

+

Availability Zones

+

Availability Zones are used in Nova and Cinder separately to provide an often also physical separation of compute hosts or storage nodes. This leads to two options to consider:

+
    +
  1. +

    Multiple Volume AZs: This might be used if there are different backends present in one IaaS structure. The different volume types are usually used for the different volume AZs. This makes migration between those AZs only be possible for administrators.

    +
  2. +
  3. +

    Volume Types that can be attached to multiple Nova Azs: This option can be seen in the extra specs of a volume type also by normal users. Another option is to use backend specific options, as for example with ceph that directly interacts with nova for this. In that case there will not be any visible extra specs for the users.

    +
  4. +
+

Another question is how many providers use one of these options or both.

+

Conclusion: The first part doesn't make much sense to standardize, as migration between the volume types can only be done by admins. However, the second part might be noteable, but due to the variety of configuration options very hard to standardize.

+

Multiattach

+

It is possible in a few backends to attach a volume to multiple VMs. This has to be configured in the Volume Type and this information is also accessible for users. Nevertheless, this option also needs a lot of work from users, as those types of volumes have to have a file system, that is capable of multiattach. Many providers don't provide multiattach.

+

Conclusion: It might be noteable, that this already is a discoverable option.

+

Replication

+

Replication states, whether there are multiple replicas of a volume. Thus answers the question, whether the data could survive a node outage. Again there are different ways to achieve replicated volumes. It can either be defined in the volume type and is discoverable also by normal users, or it is configured in the backend. The last option is usually used with ceph for example. This makes it hard to discover, whether a volume is replicated or not. Another point is the number of replicas, that exist.

+

Conclusion: Replication is a good option to be standardized. Whether this should be done as a boolean option or if the number of replicas is also something users need to know should still be discussed. Nevertheless, due to the different options to configure replication this will be quite complex.

+

QoS

+

Quality of Service parameters can be stated in a volume qos object. These objects can then be associated to a volume type (or directly to a volume as an admin only option). But this is optional and thus even good or very good volume QoS parameters that are acquired through hardware configuration and storage parameters, might go by unmentioned. +Furthermore, the indirection makes it harder to discover the qos for a volume type. Only admins will see the associated qos ID and will have to take a closer look at the qos after discovering the volume type. PLUS: there can only be one qos association for one volume type. But a qos can be used for multiple volumes.

+

Conclusion: The benefit of displaying qos parameters is clear, thus this option should be noted. But are volume qos objects widely used? If not, standardization process would be too much work.

+

Other Backend-specific Highlights

+

While every option above described things, that can at least be partly or for admins only visible in volume types, there are many different configuration options in hardware and backend providers can make use of. It is sadly not possible to get them into the volume type directly, but we recommend, that notable configurations are written into the description of a volume type to achieve transparency for the users.

+

Open questions

+
    +
  1. How often are the different options used by providers and users respectively? Especially important for qos and replication!
  2. +
  3. Regarding Replication: Is the number of replicas needed by users and is it okay for providers to provide this information?
  4. +
+

Decision

+
AspectStandardize?Discoverabilityother Things
encryptionRecommendedwork neededextra_spec: encrypted=True/False
Backend name---
AZs--describe as optional and backend-dependend
multiattach-yesdescribe as optional
ReplicationRecommendedlot of workeither get from backend to OS or as extra_spec defined by deployer
Number of Replicas, etc?lot of workoptional, work on it after Replication is standardized
Volume QoS?admin onlyneeds further discussion, should be at least described as optional
+ +

This is an etherpad with a further look into the Options and a few examples.

+ + \ No newline at end of file diff --git a/standards/scs-0112-v1-sonic/index.html b/standards/scs-0112-v1-sonic/index.html new file mode 100644 index 0000000000..ee69bddc18 --- /dev/null +++ b/standards/scs-0112-v1-sonic/index.html @@ -0,0 +1,94 @@ + + + + + +SONiC Support in SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SONiC Support in SCS

Introduction

+

SONiC support in SCS was considered within the context of VP04 Networking, sub-lot 1 SDN scalability. Different challenges and approaches to SDN scalability have been explored and more specifically those who require support in the underlay network. Using SONiC in the underlay can have benefits for SCS users by using a standardized OS for network devices and also having a clear path for network scalability when using SONiC. For this to work, we have to define how SONiC is used and supported architecturally in SCS. This document outlines the architectural decisions in regard to SONiC support and integration in SCS.

+

Motivation

+

In respect to SDN scalability improvements in Openstack and SCS, there are several ways SONiC can be leveraged.

+

SONiC as a network OS where dynamic network configuration in Openstack is required

+

In many network designs for Openstack, configuration of the actual network hardware by Openstack Neutron service is required. The following network designs apply:

+
    +
  • +

    VLANs. Using VLANs to segment tenant networks requires the network switch to be configured. This can be manual or dynamic configuration via the ML2 Neutron driver.

    +
  • +
  • +

    EVPN/VXLAN on the switch. In this use case, SONiC runs on leaf switches. Leafs terminate VXLAN endpoints and run BGP/EVPN for the control plane. Again, the ML2 Neutron driver is used to dynamically configure the network switch. The link between the switch and the service is regular VLAN.

    +
  • +
  • +

    VXLAN on servers and switches. This is a hybrid use case, where most of the SDN is pushed to the server, but the network is still involved where support for bare metal hosts is needed.

    +
  • +
+

Automation and tooling for SONiC

+

There is no tooling in SCS or Openstack communities to facilitate the rollout and configuration of enterprise scale SONiC deployments. Netbox and OSISM can be integrated, so that Netbox becomes the source of truth for network configuration and OSISM supports the initial rollout and configuration for the switches.

+

OVN for SONiC

+

OVN and OVS are extensively leveraged in Neutron to SDN. In large scale deployments, OVN can become a bottleneck by exhausting resources on network nodes. SONiC can host the OVN control plane as a module (container) and spare the resources in network nodes. There is however a potential other bottleneck on SONiC hardware, as OVN control plane can be resource intensive. This is a potential area for further investigation.

+

Design Considerations

+

There are different ways SONiC support can be implemented in SCS, very similar to existing approaches with Linux.

+

Options considered

+

Option 1: SCS distribution of SONiC

+

With this approach, SCS will create its own distribution of SONiC, similar to what Debian or Arch are for Linux. This distribution will be based on the SONiC community distribution, but will have SCS specific modules, which will be developed and maintained by SCS. SCS will contribute its code to dedicated SCS repositories and build its own SONiC images. The code can eventually be pushed upstream, but not as top priority. This approach will allow SCS to have a clear path for SONiC support and integration in SCS, but will also require SCS to maintain a distribution of SONiC, which is a significant effort. Upstream/downstream changes will have to be managed and maintained. However, the advantage is that SCS will have full control over the distribution and can make changes as needed. Users will have to use the SCS distribution of SONiC, which will be based on the community distribution. If users already deploy community or enterprise SONiC, a migration path to SCS SONiC will be needed.

+

Option 2: SCS will support SONiC but will not change it

+

SCS supports enterprise and community versions of SONiC but will not develop its own code for it. This will significantly limit the ability to develop new features for SDN, because all changes will be done in the tooling around SONiC and not in the OS itself. The advantages are that SCS will still improve SONiC support and will have minimal effort for this. The downside is that some features like OVN control plane for SONiC will not be possible.

+

Option 3: SCS develops SCS-specific modules as add-on for any SONiC (Community or Enterprise)

+

In option 3, SCS will change SONiC by releasing its own modules for it. Those module can be provided as add-ons and installed on top of any version, community or enterprise. While compatibility between the modules the SONiC releases will need to be maintained, there will be much broader support for SONiC and users will be able to pick and chose distributions based on their existing relationships and experience and use SCS independent of this. In cases where SCS provides contributions to core SONiC, those can be made in upstream Community repositories, so that the whole community including the propitiatory vendors can adopt them eventually.

+

Option 4: SCS does not adopt SONiC at all

+

This option entails no dedicated effort on SCS's part in supporting SONiC network equipment for its users and software stack. Users can still use SONiC from what is available by other projects or if they invest the effort themselves. This has several disadvantages:

+
    +
  • SCS is not contributing to the SONiC community
  • +
  • the value for SCS by users who already use or plan to invest in SONiC is diminished
  • +
  • users have less incentive to use community SONiC and switch to Enterprise SONiC
  • +
  • SCS will not be able to leverage SONiC for SDN scalability improvements
  • +
+

Open questions

+

State of SONiC community?

+

community version: mature or not?

+

Commits: between 40-52 per month. Contributors to master: 10-20. Mailing list: 6 lists, about 10-30 messages/month for list. Community version supports 25 hardware vendors. Requires significant time and resource investment and "Explorer's mindset".

+

enterprise version: mature or not?

+

Multiple vendor distributions. Expensive in general

+
    +
  • release schedule - how often are features and bugfixes released?
  • +
+

New tags appears on different periods, once 2 times per month, other 3 months between releases.

+
    +
  • adoption penetration - how many vendors use it? What type of vendors (big, medium and large)?
  • +
+

Good initial adoption: Microsoft, Target. Adoption requires time and money

+
    +
  • Is SONiC being overtaken by alternatives: SmartNICs and DPUs? How relevant is it still and will be in the coming years?
  • +
+

Actually not, because of different use cases.

+
    +
  • Sustainability of community SONIC for 2025+
  • +
+

The SONiC community is healthy and growing, however progress is slower due to factors like investment of resources. The barrier of entry is much higher than other similar OSS projects.

+

Decision

+

IaaS team recommends to use Option 3: SCS develops SCS-specific modules as add-on for any SONiC (Community or Enterprise). It has the best tradeoff between time and resource investment and benefits for the community. Adopting this strategy would allow SCS to be agile and quickly adopt SONiC, by providing users with clear path while allowing the freedom to choose different hardware and software vendors. SCS code can be packaged independently of each SONiC distribution and installed as add-on. Also, SCS contributions to core SONiC will be done directly upstream, so that the whole community can benefit from them.

+

Work on hardware support in SONiC should be raised in upstream and SCS shouldn't make significant investments in this area.

+ +
+ + \ No newline at end of file diff --git a/standards/scs-0113-v1-security-groups-decision-record/index.html b/standards/scs-0113-v1-security-groups-decision-record/index.html new file mode 100644 index 0000000000..5a93e935ff --- /dev/null +++ b/standards/scs-0113-v1-security-groups-decision-record/index.html @@ -0,0 +1,124 @@ + + + + + +Security Groups Decision Record | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Security Groups Decision Record

Introduction

+

Security Groups in IaaS (OpenStack) are sets of ip table rules, that are applied to ports which connect a virtual machine to a network. +In contrast to other resources like flavors or volume types that are always publicly accessible, or images that can be both public and private, security groups are always bound to the project level. +That creates some difficulties for a possible standard of Security Groups, which are discussed in this document.

+

Terminology

+

Security Group +A set of iptables rules that is applied to ports connecting a virtual machine and a network.

+

Security Group Rule (abbr. Rule) +This references a single rule within a security group.

+

RBAC +Role Based Access Control used for policies and alike.

+

network rbac / neutron rbac +These access controls will let administrators and users share neutron related resources with other projects.

+

admin +The most powerful role in OpenStack. Only given to some Operators of the Cloud Infrastructure.

+

Context

+

While creating a virtual machine and also later on, one or more security groups can be added to it. +When there is no security group specified the default security group will always be added. +Like every other security group, the default group is also project bound. +That means, it can be edited as required by project members. +By design of OpenStack and when not changed, default rules in the default security group block all incoming traffic except from the same Security Group and only allow outgoing traffic1.

+

Reasons for and against a standard for security groups

+

Considering having most likely similar security groups within different projects, it might make sense to standardize a few security groups for often used cases like ssh, http, https and maybe icmp. +What speaks for standardizing a certain set of security groups:

+
    +
  1. Having a set of correctly configured security groups could reduce misconfiguration from users
  2. +
  3. Re-using correctly configured security groups saves time for users
  4. +
  5. Auditing security groups would be way easier for operators when helping customers
  6. +
  7. The configuration for the Security Groups can be done by networking experts, which may result in a higher security level as when users without expertise configure them
  8. +
+

What are the downsides of having a set of standardized security groups:

+
    +
  1. A bug or misconfiguration is a single point of failure for ALL customers
  2. +
  3. Users might apply the wrong security group to their port or VM because they lack the domain knowledge, unknowingly opening themselves to attacks
  4. +
  5. Users will not inspect such default security groups: this may result in applying a wrong group and opening traffic too much
  6. +
  7. the central authority managing the groups does not necessarily know the use case of the user, the user/operator must know best what kind of security their workload needs. What is a necessary port for 99% of deployments might be a security disaster for my deployment
  8. +
  9. Providing default groups could have the effect of stopping customers to think about their specific security needs and instead just copying default groups and or rules
  10. +
+

This leads to a conclusion, that a set of default security groups is only more valuable than harmful for users:

+
    +
  1. when the rules in those groups are configured correctly
  2. +
  3. and when the users still have to think about their network security on their own for each VM they start
  4. +
+

Technical limitations

+

As security groups are project bound and there is no native way to them to be shared, we are left with three options:

+
    +
  1. To use another endpoint network rbac to share security groups among different projects.
  2. +
  3. To adhere to the project scope of security groups and only give documentation about recommended security groups to users.
  4. +
  5. To only add a tutorial on how to create your own security group in general, how to detect what kind of network permissions your project needs for most frequent (linux) workloads and how to craft your own security groups in a secure way.
  6. +
+

Option 0: Pre-Requirement: default rules for the (default) security group

+

For every project that is created there will also be a project-specific default security group created. +The default rules for the default groups and all other newly created groups can be looked up like this:

+
stack@devstack:~/devstack$ openstack default security group rule list
+------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+
| ID | IP Protocol | Ethertype | IP Range | Port Range | Direction | Remote Security Group | Remote Address Group | Used in default Security Group | Used in custom Security Group |
+------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+
| 47b929fd-9b39-4f22- | None | IPv6 | ::/0 | | egress | None | None | True | True |
| abc5-7d4f64d10909 | | | | | | | | | |
| 6ace51bb-5258-45ab- | None | IPv6 | ::/0 | | ingress | PARENT | None | True | False |
| 9ba9-1efbebfb086b | | | | | | | | | |
| 92a79600-5358-4fef- | None | IPv4 | 0.0.0.0/0 | | egress | None | None | True | True |
| a390-822665f46070 | | | | | | | | | |
| 997bb0c2-652e-4d1f- | None | IPv4 | 0.0.0.0/0 | | ingress | PARENT | None | True | False |
| b910-e12c89f88b44 | | | | | | | | | |
+------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+
+

Those rules can be edited, which may pose a security risk for customers consuming the default security group. +This should be addressed as a pre-requirement here.

+

Option 1: operator usage of network rbac

+

The network rbac endpoint2 manages the possibility to share and access certain network-specific resources such as security groups. +For admins, it is possible to use this endpoint to share a security group with ALL projects within the cloud including ALL projects of ALL domains:

+
stack@devstack:~/devstack$ openstack network rbac create --target-all-projects --action access_as_shared --type security_group group-for-everyone
+-------------------+--------------------------------------+
| Field | Value |
+-------------------+--------------------------------------+
| action | access_as_shared |
| id | 394d8e71-143f-4c5b-a72f-cd10af3222df |
| object_id | b6a3834a-f89c-47a9-9ed6-ca89e93701c4 |
| object_type | security_group |
| project_id | 15f2ab0eaa5b4372b759bde609e86224 |
| target_project_id | * |
+-------------------+--------------------------------------+
+

This would fulfill our goal to grant access to predefined security groups for all projects and all groups received as shared do not count into the projects quota for security groups. +But there are a few downsides to this:

+
    +
  1. This should be strictly bound to the admin: no other user should be able to share security groups so to not confuse user.
  2. +
  3. The managing of those network rbac objects can get out of hand pretty quickly, because there neither is an explicit name for such an object nor do the names of the shared objects appear:
  4. +
+
stack@devstack:~/devstack$ openstack network rbac list --long
+-----------------------------+----------------+-----------------------------+--------------------+
| ID | Object Type | Object ID | Action |
+-----------------------------+----------------+-----------------------------+--------------------+
| 97507e4c-7413-4d61-ab21- | security_group | 110b1bea-f0e0-4fb7-9fc7- | access_as_shared |
| 047fc23516dd | | cda1b6f927b0 | |
| bc22a865-46f9-4cd2-80af- | security_group | 5f22e42e-95dc-4c0a-8651- | access_as_shared |
| 3c249ba0e010 | | 57b1dfc8639f | |
| 2467806f-5428-4506-8e23- | network | 02ef8579-9917-4a01-893d- | access_as_shared |
| f4690db04e01 | | cb2f9f3d5f98 | |
| ed40996e-218d-4daa-b222- | network | 73edb86b-d7ab-4db3-82b7- | access_as_external |
| f3c603a5b8a6 | | 25fa8b012e40 | |
| 45e0a707-af82-42a6-b93f- | subnetpool | cd7addd1-05d9-48a8-bc38- | access_as_shared |
| efde18216f13 | | 4a581354983f | |
| e514c2c8-65ac-4062-8b03- | subnetpool | ad1cc1ed-3261-4df2-8c73- | access_as_shared |
| fe24f6fc4656 | | c3dd72d59061 | |
+-----------------------------+----------------+-----------------------------+--------------------+
stack@devstack:~/devstack$ openstack network rbac show bc22a865-46f9-4cd2-80af-3c249ba0e010
+-------------------+--------------------------------------+
| Field | Value |
+-------------------+--------------------------------------+
| action | access_as_shared |
| id | bc22a865-46f9-4cd2-80af-3c249ba0e010 |
| object_id | 5f22e42e-95dc-4c0a-8651-57b1dfc8639f |
| object_type | security_group |
| project_id | 15f2ab0eaa5b4372b759bde609e86224 |
| target_project_id | * |
+-------------------+--------------------------------------+
+

The biggest downside: As soon as a security group is shared, everyone from every project, can edit the rules of this group.

+

Option 2: stay project-scoped

+

Using and adhering the project scope of the security groups has the consequence, that:

+
    +
  1. either an admin has to set up security groups for each project
  2. +
  3. or the SCS project only provides a guide on how to set up and use some recommended security groups.
  4. +
+

As users are allowed to, will and should edit their security groups, there is no way to ensure, that a certain set of security groups with certain rules is always present in a project. +So packing an extra burden on admins is unreasonable. +The option to give a guide and recommend a few security groups however is a quite good option.

+

Option 3: security-focused guide

+

Instead of providing users with a set of default groups or the knowledge about how to create default groups, there could be a guide created that focuses on the crafting of a security group in a secure way. +That would include identifying what kind of network permission a single VM needs and how to proceed after gathering all requirements of the customers workload.

+

Decisions

+

The default Security Group Rules should be standardized as a pre-requirement (Option 0).

+

Using the network rbac endpoint (Option 1) would not solve the idea of having pre-defined and administrator audited Security Groups, because it is possible for any user to edit the rules of shared Security Groups. +Instead, the project-scope of the Security Groups should by focused and a guide prepared, that gives insight about creating and using Security Groups with a few examples but with a clear security focus (Mix of Option 2 and 3).

+

Consequences

+

Any CSP will have to follow the standard for the default Security Group Rules. +There are no consequences regarding Security Groups as it and users stay in full control and responsible for their own Security Groups

+ +

A PR to standardize default Security Group Rules +A PR to a first draft for a guide for security groups

+ +

Footnotes

+
    +
  1. +

    Default Security Group Rules

    +
  2. +
  3. +

    Neutron RBAC

    +
  4. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0114-v1-volume-type-standard/index.html b/standards/scs-0114-v1-volume-type-standard/index.html new file mode 100644 index 0000000000..6a4d85efc9 --- /dev/null +++ b/standards/scs-0114-v1-volume-type-standard/index.html @@ -0,0 +1,85 @@ + + + + + +SCS Volume Types | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Volume Types

Introduction

+

A volume is a virtual drive that is to be used by an instance (i.e., a virtual machine). With OpenStack, +each volume is created per a type that determines basic features of the volume as provided by the backend, +such as encryption, replication, or quality of service. As of the writing of this document, presence or absence of these +features can not be discovered with full certainty by non-privileged users via the OpenStack API.

+

Glossary

+

The following special terms are used throughout this standard document:

+
TermMeaning
volumeOpenStack resource, virtual drive which usually resides in a network storage backend
volume featureA certain feature a volume can possess
aspectPart of a volume type that will activate a corresponding feature in a created volume
AZAvailability Zone
Volume QoSQuality of Service object for Volumes
+

Motivation

+

As an SCS user, I want to be able to create volumes with certain common features, such as encryption or +replication, and to do so in a standardized manner as well as programmatically. +This standard outlines a way of formally advertising these common aspects for a volume type to +non-privileged users, so that the most suitable volume type can be discovered and selected easily — both by +the human user and by a program.

+

Design Considerations

+

All considerations can be looked up in detail in the Decision Record for the Volume Type Standard.

+

Systematic Description of Volume Types

+

To test whether a deployment has volume types with certain aspects, the discoverability of the parameters in the volume type has to be given. As for the time this standard is created, there is no way for users to discover all aspects through OpenStack commands. Therefore, the aspects, that are fulfilled within a volume type, should be stated in the beginning of the description of a volume type in the following manner:

+

[scs:aspect1, aspect2, ..., aspectN]...

+

The mentioned aspects MUST be sorted alphabetically and every aspect should only be mentioned to the maximal amount of one.

+

Standardized Aspects

+

The following table shows which aspects are considered in this standard. The third column shows how the description of the volume type has to be adjusted, if the aspect is fulfilled:

+
AspectRequirementstandardized descriptioncomment
EncryptionRecommended"[scs:encrypted]"volume is encrypted
ReplicationRecommended"[scs:replicated]"volume is replicated to avoid data loss in a case of hardware failure
+

It is possible to use multiple of those aspects within one volume type. There don't have to be different volume types for each aspect. +For instance, one volume type that uses LUKS-encryption with a ceph storage with inherent replication would fulfill all recommendations of this standard.

+

DEFAULT volume type

+

There is always a default volume type defined in an OpenStack deployment. This volume type is created in the setup of cinder and will always be present in any OpenStack deployments under the name __default__. This standard does not have any requirements about this volume type at this moment, instead deployers are free to choose what fits best in their environment. Conversely, a cloud user can not expect any specific behavior or properties from volume types named __default__.

+

REQUIRED volume types

+

Currently, this standard will not require volume types with certain specification.

+ +

This standard recommends to have one or more volume types, that feature encryption and replication.

+

OPTIONAL volume types

+

Any other aspects of volume types, that can be found in the decision record are OPTIONAL. They SHOULD NOT be referenced in the way this standard describes. Some of them already are natively discoverable by users, while others could be described in the name or description of a volume type. Users should look into the provided volume types of the Cloud Service Providers, if they want to use some of these other aspects.

+

Implementation Details

+

Encryption

+

Encryption for volumes is an option which has to be configured within the volume type. As an admin it is possible to set encryption-provider, key size, cipher and control location. Additionally to be discoverable by users, the description should start with an aspect list such as [scs:encrypted] (potentially with additional aspects). It should look like this example:

+
openstack volume type show LUKS
+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| access_project_ids | None |
| description | [scs:encrypted] This volume uses LUKS-encryption |
| id | d63307fb-167a-4aa0-9066-66595ea9fb21 |
| is_public | True |
| name | LUKS |
| qos_specs_id | None |
+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+

Replication

+

Replication states whether or not there are multiple replicas of a volume, i.e., whether the data could survive a node outage. Unfortunately, there are two ways replication can be achieved:

+
    +
  1. In the configuration of a volume type. It then is visible as extra_spec in the properties of a volume type.
  2. +
  3. Via the used backend. Ceph for example provides automatic replication, that does not need to be specified in the volume type. This is currently not visible for users.
  4. +
+

To fulfill this recommendation, the description should start with an aspect list such as [scs:replicated] (potentially with additional aspects).

+

Example

+

One volume type that is configured as an encrypted volume type in a ceph backend, with automated replication would fit both recommendations and will be enough to comply to this part of the volume type standard.

+

It should look like the following part:

+
+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| access_project_ids | None |
| description | [scs:encrypted, replicated] Content will be replicated three times to ensure consistency and availability for your data. LUKS encryption is used. |
| id | d63307fb-167a-4aa0-9066-66595ea9fb21 |
| is_public | True |
| name | hdd-three-replicas-LUKS |
| properties | |
| qos_specs_id | None |
+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ + +

Conformance Tests

+

The script /Tests/iaas/volume-types/volume-types-check.py connects to an OpenStack environment and tests +the following:

+
    +
  • for each volume type: if its description starts with [scs:....], then this prefix is a feature list +(sorted, each entry at most once), and each entry is one of the possible features described here,
  • +
  • the recommended volume types are present (otherwise, a WARNING is produced).
  • +
+

The return code is zero precisely when the test could be performed and the conditions are satisfied. +Otherwise, detailed errors and warnings are output to stderr.

+ + \ No newline at end of file diff --git a/standards/scs-0115-v1-default-rules-for-security-groups/index.html b/standards/scs-0115-v1-default-rules-for-security-groups/index.html new file mode 100644 index 0000000000..1f0bfa7fb7 --- /dev/null +++ b/standards/scs-0115-v1-default-rules-for-security-groups/index.html @@ -0,0 +1,118 @@ + + + + + +Default Rules for Security Groups | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Default Rules for Security Groups

Introduction

+

Security Groups in IaaS (OpenStack) are part of the network security mechanisms provided for the users. +They resemble sets of virtual firewall rules allowing specific network traffic at a port of a VM that connects it to a network. +They are project-bound, which means that all Security Groups that are newly created are only available to the project in which they were created. +This is also the case for the default Security Group that is created for each project as soon as the project itself is created.

+

Terminology

+

Security Group (abbr. SG) +Set of ip table rules, used for tenant network security.

+

Security Group Rule (abbr. SG Rule) +A single ip table rule, that is part of a Security Group.

+

Administrator (abbr. Admin) +Operator = User of an OpenStack cloud with the admin role.

+

Default Security Groups, Custom Security Groups and default Security Group Rules

+

To properly understand the concepts in this standard and avoid ambiguity, it is very important to distinguish between the following similar-sounding but different resources in the OpenStack Networking API:

+
    +
  1. default Security Group
  2. +
  3. custom Security Group
  4. +
  5. default Security Group Rules
  6. +
+

A default Security Group is a predefined Security Group which is automatically created once a project is created and is specific to that project. +This Security Group is called "default" and there exists only one per project. +It will automatically be assigned to VMs that have no other Security Group explicitly assigned to it, when a VM is created.

+

A custom Security Group is any additional Security Group created within a project separate from the default Security Group of the project.

+

The default Security Group Rules may target the default Security Groups or the custom Security Groups or both. +They resemble a rule template and each Security Group will be initially created with rules according to this template.

+

Although the rules of a Security Group may be adjusted freely after its creation, these default rule presets applied on initialization are predefined. +In recent OpenStack releases, both presets can be adjusted independently by administrators of the infrastructure.

+

Motivation

+

The rules of a Security Group can be edited by default by any user with the member role within a project. +But when a Security Group is created it automatically incorporates a few Security Group rules that are configured as default rules. +Since the 2023.2 release, the default set of Security Group rules can be adjusted. +This functionality is only available to administrators12. +In combination with the OpenStack behavior that when a VM is created with no Security Group specified, the default Security Group of the project is automatically applied to the ports of the VM, +a user cannot be sure which firewall rules are applied to such a VM.

+

Therefore, this standard proposes default Security Group rules that MUST be set by administrators to avoid divergence in default network security between different IaaS environments.

+

Design Considerations

+

Up to the 2023.1 release (Antelope) the default Security Group rules are defined in the OpenStack code. +We should not require changing this behavior through code changes in deployments.

+

Beginning with the 2023.2 release (Bobcat) the default Security Group rules can now be edited by administrators through an API. +All rules that should be present as default in Security Groups have to be configured by admins through this API.

+

There are two ways to approach a standard for the default rules of Security Groups.

+
    +
  1. +

    There could be a set of rules standardized that has to be configured by admins.

    +

    OpenStack's default rules for Security Groups already provide a good baseline for port security, because they allow all egress traffic and for the default Security Group only ingress traffic from the same group.

    +

    Allowing more rules would not benefit the security level, while reducing or limiting the existing rules would barely improve it. +Nevertheless, a standard could hold up the current security level against possible future release with more open default rules. +Changing the default rules will not change the rules of any existing Security Groups.

    +
  2. +
  3. +

    With the already strict OpenStack default rules users are required in most use cases to create and manage their own Security Groups.

    +

    This has the benefit that users need to explicitly think about the port security of their VMs and may be less likely to apply Security Groups which rules open up more ports than needed. +There is also a guide from the SCS project on how to set up a Security Group that also focuses on having a good port security3.

    +

    With the default OpenStack behavior of having already strict rules, which in most cases require users to manage their own Security Groups, this standard should mandate a middle way: +It should allow adjusting the default rules, but only to a stricter version.

    +
  4. +
+

Allowing all outgoing traffic in the default rules in combination with blocking all incoming traffic would be strict enough from a security point of view. +And it would make it necessary for users to check and change the rules of their Security Group to a meaningful set.

+

Further Annotations

+

This standard should only be applied onto versions of OpenStack that implement the new endpoint for the default Security Group rules, which would only include 2023.2 or higher releases.

+

It is possible to have different default Security Group rules for the default Security Group and custom Security Groups. +And it is arguable to have a more strict standard for default rules for the default Security Group than for the custom Security Groups. +Because the latter ones are not automatically applied to a VM but are always edited by the users to apply to their requirements.

+

The allowlisting concept of Security Group rules makes it hard to allow traffic with an exception to certain ports. +It would be possible to just define many rules to achieve what a blocklist would achieve. +But having many rules may confuse users, and they may not disable unnecessary default rules in their Security Groups.

+

Standard

+

The default Security Group rules for the default Security Groups SHOULD allow incoming traffic from the same Security Group. +The default Security Group rules for ALL Security Groups MUST NOT allow any other incoming traffic. Neither IPv4 nor IPv6. +This can be achieved through having ingress rules in the default Security Group rules that allow ingress traffic from the Remote Security Group "PARENT" but are only used in the default Security Group.

+

The default Security Group rules for ALL Security Groups SHOULD allow egress Traffic for both IPv4 and IPv6.

+

Example

+

In the following table, there is only ingress traffic between the same default Security Groups allowed plus all egress traffic:

+
$ openstack default security group rule list
+--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+
| ID | IP Protocol | Ethertype | IP Range | Port Range | Direction | Remote Security Group | Remote Address Group | Used in default Security Group | Used in custom Security Group |
+--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+
| 47b929fd-9b39-4f22-abc5- | None | IPv6 | ::/0 | | egress | None | None | True | True |
| 7d4f64d10909 | | | | | | | | | |
| 92a79600-5358-4fef-a390- | None | IPv4 | 0.0.0.0/0 | | egress | None | None | True | True |
| 822665f46070 | | | | | | | | | |
| 93e35d0c-2482-4ec1-9fbd- | None | IPv4 | 0.0.0.0/0 | | ingress | PARENT | None | True | False |
| fd8c9a21a04e | | | | | | | | | |
| ed5cd662-add2-4e42-b0a7- | None | IPv6 | ::/0 | | ingress | PARENT | None | True | False |
| 3b585d348820 | | | | | | | | | |
+--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+
+ +

The spec for introducing configurability for the default Security Groups Rules can be found here.

+

More about Security Groups as a resource in OpenStack can be found here.

+

Conformance Tests

+

The conformance tests should check for the absence of any ingress traffic rules except traffic from the same Security Group in the openstack default security group rule list. +As having egress rules is allowed by this standard, but not forced and can be set in various ways, the tests should check for presence of any egress rules.

+ +

Footnotes

+
    +
  1. +

    Tracking of development for editable default SG rules

    +
  2. +
  3. +

    Release Notes of Neutron 2023.2

    +
  4. +
  5. +

    Guide for Security Groups

    +
  6. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0116-v1-key-manager-standard/index.html b/standards/scs-0116-v1-key-manager-standard/index.html new file mode 100644 index 0000000000..5a6a802889 --- /dev/null +++ b/standards/scs-0116-v1-key-manager-standard/index.html @@ -0,0 +1,96 @@ + + + + + +SCS Key Manager Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Key Manager Standard

Introduction

+

To encrypt user data like volumes or in the future also Images and ephemeral storage for VMs, the key has to be present in the infrastructure. +A Key Manager service within the infrastructure can be utilized to store keys. +Consequently providing keys for every encryption or decryption is possible without including the user. +Also authorization policies can be applied on every request to the Key Manager service. +OpenStack offers a Key Manager implementation that is named Barbican, which provides these features. +This standard aims to provide a base level of security for Cloud Service Providers that integrate a Key Manager into their deployments.

+

Terminology

+
TermMeaning
APIApplication Programming Interface, often referring to the REST API interfaces provided by OpenStack and related services
BarbicanThe Key Manager implementation in OpenStack
CSPCloud Service Provider, provider managing the OpenStack infrastructure
IaaSInfrastructure-as-a-Service
HSMHardware Security Module
KEKKey Encryption Key
RBACRole Based Access Control
+

Motivation

+

User data encryption requires an encryption key to be known during encryption and decryption processes. +Key Managers like Barbican provide this functionality on the IaaS-Level. +Not every IaaS deployment currently offers user data encryption as part of their standard offering. +This standard should encourage CSPs to integrate a Key Manager and thus increase the amount of Clouds with offerings of data encryption. +It is also important to take a closer look into the Key Manager and analyze how such a service can be configured securely.

+

A Key Manager service manages keys in a secure manner, but this can be achieved differently and is not primarily in scope of this standard. +The OpenStack Key Manager Barbican stores keys encrypted with a project specific KEK in the database. +The KEKs are also stored encrypted in the same database. +The Master-KEK, used to encrypt the project specific KEKs is not stored in the database and is stored differently depending on the backend storage plugin used. +This standard also abstracts the used plugins and wants to ensure that the Master-KEK is protected, too.

+

Design Considerations

+

While discussing what this standard should aim for it was discovered that some CSPs don't use Barbican or another Key Manager at all and do not provide the feature to encrypt user data to their customers. +This should change, but the exact change comes with financial burden, when choosing a plugin in Barbican to store the Master-KEK or choosing to integrate another Key Manager service instead. +To minimize the burden and enable more CSPs to step up and provide encryption, this standard will only make recommendations about plugins from Barbican.

+

Options considered

+

Recommend or even mandate specific Key Manager plugins

+

It was considered to only recommend a certain set of plugins or backends for the Key Manager, but this may be very prone to change if e.g. Barbican adds a new plugin. +As the SCS only wants to mandate the API that can be abstracted through the Castellan library in OpenStack, integrating any other Key Manager implementation is not uncommon, so this standard needs to consider other possible Key Managers as well. +Due to these reasons this option was disregarded.

+

Recommendation regarding the handling of the Master KEK

+

Looking into the available Barbican plugins and possible attack vectors one design decision in the plugins is very important: where and how to store the Master-KEK. +Because the Plugins might use different technologies there are many locations for the Master KEK possible. +Most of the Plugins increase the security level by not storing the Master-KEK in plain text on the physical machine Barbican is running on. +This mechanism as a whole, is something that CSPs should aim to do.

+

Standardization of the Key Manager Policy

+

Because this standards recommends or even eventually mandates the presence of a Key Manager, the situation about the policy of the Key Manager needs to be discussed. +The policy of an IaaS service should use the same roles as the other IaaS services. +Unfortunately this does not apply to the Key Manager implementation Barbican. +It has the roles reader, audit and creator, which are not present in the Keystone role concept. +The roles a customer usually gets through the Identity API is member. +Leaving it this way will prevent users from creating and using secrets even when a Key Manager is integrated.

+

To unify the roles among all IaaS services, there is currently work done in the OpenStack Community. +This initiative is called secure RBAC1. +Also the SCS is discussing a standard concerning the roles2. +When this is done, there is no further work needed. +But as of the 2024.1 release, this is still under development.

+

In conclusion this standard should mandate everyone who uses a Key Manager that does not include the secure RBAC, to adjust the policies to have a mapping between the internal creator and the identity-based member role. +This will result in a member being allowed to do everything a creator can do.

+

Key Manager Standard

+

To increase security and allow user data encryption, CSPs SHOULD implement the Key Manager API (e.g. implemented by Barbican). +The Keys managed by this Key Manager MUST be stored encrypted and the Master-KEK of the Key Manager MUST be stored in another place than the Keys.

+

If possible CSPs SHOULD NOT store the Master-KEK in plain-text on the physical host the Key Manager is running on.

+

Key Manager Policies

+

If a Key Manager without secure RBAC enabled is used, the policies MUST be adjusted to let the member role of the Identity service be equivalent to the Key Manager internal creator role.

+ +

Barbican Plugins

+

Conformance Tests

+

Conformance must be tested in two steps.

+
    +
  1. The check whether a Key Manager is present can be done in a similar way as in the mandatory OpenStack service APIs standard and the test should be merged into the mandatory service test as soon as a Key Manager is required in scs-conformant infrastructures.
  2. +
  3. The check, that there is no Master-KEK present on the Key Manager Node, has to be done by the CSP themself.
  4. +
+ +

Footnotes

+
    +
  1. +

    Secure RBAC work in OpenStack

    +
  2. +
  3. +

    Issue for a role standard in SCS

    +
  4. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0116-w1-key-manager-implementation-testing/index.html b/standards/scs-0116-w1-key-manager-implementation-testing/index.html new file mode 100644 index 0000000000..e39282e6d5 --- /dev/null +++ b/standards/scs-0116-w1-key-manager-implementation-testing/index.html @@ -0,0 +1,57 @@ + + + + + +SCS Key Manager Standard: Implementation and Testing Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Key Manager Standard: Implementation and Testing Notes

Implementation

+

A Key Manager service can have different backends. +For Barbican these are called Plugins. +The standard plugin is simple_crypto, which has the Master-KEK written in the Barbican config file. +In that case the Master-KEK needs additional protection. +When the simple_crypto plugin is used, securing the Master-KEK can be achieved through protection of the Barbican config e.g. through running Barbican in an enclave.

+

Another option to secure the Master-KEK would be using an HSM with a corresponding plugin in Barbican. +In that case the Master-KEK will be stored inside the HSM and encryption and decryption of the Project-KEKs will also happen in the HSM. +There are also software HSMs available, that should be tested for their integration into the Barbican workflow.

+

Other Plugins in Barbican are the KMIP plugin and Vault1. +They are storing the keys differently and CSPs need to make sure, that the access to the keys is configured securely.

+
tip

Barbican supports deploying out-of-tree drivers what enables operators to satisfy their specific needs.

+

Policies

+

When a Key Manager is used, but it uses the old policies and does not enforce the new secure RBAC work, the roles between Barbican and the other IaaS services differ. +This can be done with a small change in the policy.yaml file. The creator has to be defined like this:

+
"creator": "role:member"
+

Automated Tests

+

The check for the presence of a Key Manager is done with a test script, that checks the presence of a Key Manager service in the catalog endpoint of Openstack. +This check can eventually be moved to the checks for the mandatory an supported service/API list, in case of a promotion of the Key Manager to the mandatory list.

+

Implementation

+

The script check-for-key-manager.py +connects to OpenStack and performs the checks described in this section.

+

Manual Tests

+

It is not possible to check a deployment for a correctly protected Master KEK automatically from the outside. +Even audits would need to check the complete host for plain-text keys. +CSPs are responsible for ensuring the protection of the Master KEK and they have to make at least their architecture for that protection auditable.

+ +

Footnotes

+
    +
  1. +

    Barbican Plugins

    +
  2. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0117-v1-volume-backup-service/index.html b/standards/scs-0117-v1-volume-backup-service/index.html new file mode 100644 index 0000000000..c895c8738c --- /dev/null +++ b/standards/scs-0117-v1-volume-backup-service/index.html @@ -0,0 +1,78 @@ + + + + + +Volume Backup Functionality | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Volume Backup Functionality

Introduction

+

OpenStack offers a variety of resources where users are able to transfer and store data in the infrastructure. +A prime example of these resources are volumes which are attached to virtual machines as virtual block storage devices. +As such they carry potentially large amounts of user data which is constantly changing at runtime. +It is important for users to have the ability to create backups of this data in a reliable and effifcient manner.

+

Terminology

+
TermMeaning
CSPCloud Service Provider, provider managing the OpenStack infrastructure
IaaSAbbreviation for Infrastructure as a Service
ImageIaaS resource representing a snapshot of a block storage disk, can be used to create Volumes
VolumeIaaS resource representing a virtual block storage device that can be attached as a disk to virtual machines
+

Motivation

+

The volume backup functionality of the Block Storage API is a feature that is not available in all clouds per default, e.g., in OpenStack. +The feature requires a backend to be prepared and configured correctly before it can be used. +In the Block Storage service, the backup storage backend is usually configured separately from the storage backend of the general volume service and may not be mandatory. +Thus, an arbitrary cloud may or may not offer the backup feature in the Block Storage API.

+

This standard aims to make this functionality the default in SCS clouds so that customers can expect the feature to be usable.

+

Design Considerations

+

The standard should make sure that the feature is available and usable but should not limit the exact implementation (e.g. choice of backend driver) any further than necessary.

+

Options considered

+

Only recommend volume backup feature, use images as alternative

+

As an alternative to the volume backup feature of the Block Storage API, images can also be created based on volumes and act as a backup under certain circumstances. +As an option, this standard could keep the actual integration of the volume backup feature optional and guide users how to use images as backup targets instead in case the feature is unavailable.

+

However, it is not guaranteed that the image backend storage is separate from the volume storage. +For instance, both could be using the same Ceph cluster. +In such case, the images would not count as genuine backups.

+

Although users are able to download images and transfer them to a different storage location, this approach might also prove unfeasible depending on the image size and the existence (or lack) of appropriate target storage on the user side.

+

Furthermore, incremental backups are not possible when creating images from volumes either. +This results in time-consuming backup operations of fully copying a volume everytime a backup is created.

+

Focus on feature availability, make feature mandatory

+

This option is pretty straightforward. +It would make the volume backup feature mandatory for SCS clouds. +This way users can expect the feature to be available and usable.

+

With this, users can leverage functionalities like incremental backups and benefit from optimized performance of the backup process due to the tight integration with the volume service.

+

However, it does not seem feasible to also mandate having a separate storage backend for volume backups at the same time due to potential infrastructure limitations at CSP-side making it hard or even impossible to offer. +As such, the actual benefit of backups in terms of reliability and security aspects would be questionable if a separate storage backend is not mandated and therefore not guaranteed.

+

This approach would focus on feature availability rather than backup reliability.

+

Focus on backup reliability, make separate backend mandatory

+

As an alternative, the volume backup feature availability could be made optional but in case a CSP chooses to offer it, the standard would mandate a separate storage backend to be used for volume backups. +This way, failures of the volume storage backend would not directly impact the availability and safety of volume backups, making them actually live up to their name.

+

In contrast to the above, this approach would focus on backup reliability rather than feature availability.

+

Standard

+

This standard decides to go with the second option and makes the volume backup feature mandatory in the following way:

+

In an SCS cloud, the volume backup functionality MUST be configured properly and its API as defined per /v3/{project_id}/backups MUST be offered to customers. +If using Cinder, a suitable backup driver MUST be set up.

+

The volume backup target storage SHOULD be a separate storage system from the one used for volumes themselves.

+ + +

Conformance Tests

+

Conformance tests include using the /v3/{project_id}/backups Block Storage API endpoint to create a volume and a backup of it as a non-admin user and subsequently restore the backup on a new volume while verifying the success of each operation. +These tests verify the mandatory part of the standard: providing the Volume Backup API.

+

There is a test suite in volume-backup-tester.py. +The test suite connects to the OpenStack API and executes basic operations using the volume backup API to verify that the functionality requested by the standard is available. +Please consult the associated README.md for detailed setup and testing instructions.

+

Note that these tests don't verify the optional part of the standard: providing a separate storage backend for Cinder volume backups. +This cannot be checked from outside of the infrastructure as it is an architectural property of the infrastructure itself and transparent to customers.

+ + \ No newline at end of file diff --git a/standards/scs-0118-v1-taxonomy-of-failsafe-levels/index.html b/standards/scs-0118-v1-taxonomy-of-failsafe-levels/index.html new file mode 100644 index 0000000000..1af9935c7b --- /dev/null +++ b/standards/scs-0118-v1-taxonomy-of-failsafe-levels/index.html @@ -0,0 +1,129 @@ + + + + + +SCS Taxonomy of Failsafe Levels | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Taxonomy of Failsafe Levels

Abstract

+

When talking about redundancy and backups in the context of cloud infrastructures, the scope under which circumstances these concepts apply to various resources is neither homogenous nor intuitive. +There does exist very detailed lists of risks and what consequences there are for each risk, but this Decision Record should give a high-level view on the topic. +So that in each standard that referenced redundancy, it can easily be seen how far this redundancy goes in that certain circumstance. +Readers of such standards should be able to know at one glance, whether the achieved failure safeness is on a basic level or a higher one and whether there would be additional actions needed to protect the data.

+

This is why this decision record aims to define different levels of failure safety. +These levels can then be used in standards to clearly set the scope that certain procedures in e.g. OpenStack offer.

+

Glossary

+
TermExplanation
Availability Zone(also: AZ) internal representation of physical grouping of service hosts, which also lead to internal grouping of resources.
BSIGerman Federal Office for Information Security (Bundesamt für Sicherheit in der Informationstechnik).
CSPCloud Service Provider, provider managing the OpenStack infrastructure.
ComputeA generic name for the IaaS service, that manages virtual machines (e.g. Nova in OpenStack).
NetworkA generic name for the IaaS service, that manages network resources (e.g. Neutron in OpenStack).
StorageA generic name for the IaaS service, that manages the storage backends and virtual devices (e.g. Cinder in OpenStack).
RTORecovery Time Objective, the acceptable time needed to restore a ressource.
DiskA physical disk drive (e.g. HDD, SSD) in the infrastructure.
HostA physical machine in the infrastructure providing computational, storage and/or network connectivity capabilities.
Cyber attack/threatAttacks on the infrastructure through the means of electronic access.
+

Context

+

Some standards provided by the SCS project will talk about or require procedures to back up resources or have redundancy for resources. +This decision record should discuss, which failure threats exist within an IaaS and KaaS deployment and will classify them into several levels according to their impact and possible handling mechanisms. +In consequence these levels should be used in standards concerning redundancy or failure safety.

+

Based on our research, no similar standardized classification scheme seems to exist currently. +Something close but also very detailed is the BSI-Standard 200-3 (german) published by the German Federal Office for Information Security. +As we want to focus on IaaS and K8s resources and also have an easily understandable structure that can be applied in standards covering replication, redundancy and backups, this document is too detailed.

+

Goal of this Decision Record

+

The SCS wants to classify levels of failure cases according to their impact and the respective measures CSPs can implement to prepare for each level. +Standards that deal with redundancy or backups or recovery SHOULD refer to the levels of this standard. +Thus every reader knows, up to which level of failsafeness the implementation of the standard works. +Reader then should be able to abstract what kind of other measures they have to apply, to reach the failsafe lavel they want to reach.

+
caution

This document will not be a replacement for a risk analysis. +Every CSP and every Customer (user of IaaS or KaaS resources) need to do a risk analysis of their own. +Also the differentiation of failure cases in classes, may not be an ideal basis for Business Continuity Planning. +It may be used to get general hints and directions though.

+

Differentiation between failsafe levels and high availability, disaster recovery, redundancy and backups

+

The levels of failsafeness defined in this decision record classify the possibilities and impacts of failure cases (such as data loss) and the possible measures. +High Availability, disaster recovery, redundancy and backups are all measures that can and should be applied to IaaS and KaaS deployments by both CSPs and Users to reduce the possibility and impact of data loss. +So with this document every reader can see to what level of failsafeness their measures protect user data.

+

To differentiate also between the named measures the following table can be used:

+
TermExplanation
High AvailabilityRefers to the availability of resources over an extended period of time unaffected by smaller hardware issues. E.g. achievable through having several instances of resources.
Disaster RecoveryMeasures taken after an incident to recover data, IaaS resource and maybe even physical resources.
RedundancyHaving more than one (or two) instances of each resource, to be able to switch to the second resource (could also be a data mirror) in case of a failure.
BackupA specific copy of user data, that presents all data points at a given time. Usually managed by users themself, read only and never stored in the same place as the original data.
+

Failsafe Levels and RTO

+

As this documents classifies failure case with very broad impacts and it is written in regards of mostly IaaS and KaaS, there cannot be one simple RTO set. +The RTOs will differ for each resource and also between IaaS and KaaS level. +It should be taken into consideration that the measure to achieve the RTOs for IaaS and KaaS means to make user data available again through measures within the infrastructure. +But this will not be effective, when there is no backup of the user data or a redundancy of it already in place. +So the different failsafe levels, measures and impacts will be needed to define realistic RTOs. +For example a storage disk that has a failure will not result in a volume gein unavailable and needing a defined RTO, when the storage backend uses internal replication and still has two replicas of the user data. +While in the worst case of a natural disaster, most likely a severe fire, the whole deployment will be lost and if there were no off-site backups done by users any defined RTO will never be met, because the data cannot be recovered anymore.

+

Decision

+

Failsafe Levels

+

This Decision Record defines four failsafe levels, each of which describe what kind of failures have to +be tolerated by a provided service.

+
caution

This table only contains examples of failure cases. +This should not be used as a replacement for a risk analysis.

+

In general, the lowest, level 1, describes isolated/local failures which can occur very frequently, whereas +the highest, level 4, describes relatively unlikely failures that impact a whole or even multiple datacenter(s):

+
LevelProbabilityImpactExamples
1Very Highsmall Hardware IssueDisk failure, RAM failure, small software bug
2HighRack-wideRack outage, power outage, small fire
3Mediumsite-wide (temporary)Regional power outage, huge fire, orchestrated cyber attack
4Lowsite destructionNatural disaster
+

For example, a provided service with failsafe level 2 tolerates a rack outage (because there is some kind of +redundancy in place.)

+

There are some general consequences, that can be addressed by CSPs and users in the following ways:

+
Levelconsequences for CSPsconsequences for Users
1. LevelCSPs MUST operate replicas for important components (e.g. replicated volume back-end, replicated database, ...).Users SHOULD backup their data themself and place it on an other host.
2. LevelCSPs MUST have redundancy for important components (e.g. HA for API services, redundant power supply, ...).Users MUST backup their data themselves and place it on an other host.
3. LevelCSPs SHOULD operate hardware in dedicated Availability Zones.Users SHOULD backup their data, in different AZs or even other deployments.
4. LevelCSPs may not be able to save user data from such catastrophes.Users MUST have a backup of their data in a different geographic location.
+
caution

The columns consequences for CSPs / Users only show examples of actions that may provide this class of failure safety for a certain resource. +Customers should always check, what they can do to protect their data and not rely solely on the CSP.

+

More specific guidance on what these levels mean on the IaaS and KaaS layers will be provided in the sections +further down. +But beforehand, we will describe the considered failure scenarios and the resources that may be affected.

+

Failure Scenarios

+

The following failure scenarios have been considered for the proposed failsafe levels. +For each failure scenario, we estimate the probability of occurence and the (worst case) damage caused by the scenario. +Furthermore, the corresponding minimum failsafe level covering that failure scenario is given. +The following table give a coarse view over the probabilities, that are used to describe the occurance of failure cases:

+
ProbabilityMeaning
Very LowOccurs at most once a decade OR needs extremly unlikely circumstances.
LowOccurs at most once a year OR needs very unlikely circumstances.
MediumOccurs more than one time a year, up to one time a month.
HighOccurs more than once a month and up to a daily basis.
Very HighOccurs within minutes.
+ +
Failure ScenarioProbabilityConsequencesFailsafe Level Coverage
Disk FailureHighPermanent data loss in this disk. Impact depends on type of lost data (data base, user data)L1
Host Failure (without disks)Medium to HighPermanent loss of functionality and connectivity of host (impact depends on type of host)L1
Host FailureMedium to HighData loss in RAM and temporary loss of functionality and connectivity of host (impact depends on type of host)L1
Rack OutageMediumOutage of all nodes in rackL2
Network router/switch outageMediumTemporary loss of service, loss of connectivity, network partitioningL2
Loss of network uplinkMediumTemporary loss of service, loss of connectivityL3
Power Outage (Data Center supply)MediumTemporary outage of all nodes in all racksL3
+

Environmental

+

Note that probability for these scenarios is dependent on the location.

+
Failure ScenarioProbabilityConsequencesFailsafe Level Coverage
FireLowpermanent Disk and Host loss in the affected zoneL3
FloodVery Lowpermanent Disk and Host loss in the affected regionL4
EarthquakeVery Lowpermanent Disk and Host loss in the affected regionL4
Storm/TornadoLowpermanent Disk and Host loss in the affected regionL4
+

As we consider mainly deployments in central Europe, the probability of earthquakes is low and in the rare case of such an event the severity is also low compared to other regions in the world (e.g. the pacific ring of fire). +The event of a flood will most likely come from overflowing rivers instead of storm floods from a sea. +There can be measures taken, to reduce the probability and severity of a flooding event in central Europe due to simply choosing a different location for a deployment.

+ +
Failure ScenarioProbabilityConsequencesFailsafe Level Coverage
Software bug (major)Low to Mediumpermanent loss or compromise of data that trigger the bug up to data on the whole deploymentL3
Software bug (minor)Medium to Hightemporary or partial loss or compromise of dataL1
+

Many software components have lots of lines of code and cannot be proven correct in their whole functionality. +They are tested instead with at best enough test cases to check every interaction. +Still bugs can and will occur in software. +Most of them are rather small issues, that might even seem like a feature to some. +An exmple for this would be: whether a floating IP in OpenStack could be assigned to a VM even if it is already bound to another VM. +Bugs like this do not affect a whole deployment, when they are triggered, but just specific data or resources. +Nevertheless those bugs can be a daily struggle. +This is the reason, the probability of such minor bugs may be pretty high, but the consequences would either be just temporary or would only result in small losses or compromisation.

+

On the other hand major bugs, which might be used to compromise data, that is not in direct connection to the triggered bug, occur only a few times a year. +This can be seen e.g. in the OpenStack Security Advisories, where there were only 3 major bugs found in 2023. +While these bugs might appear only rarely their consequences are immense. +They might be the reason for a whole deployment to be compromised or shut down. +CSPs should be in contact with people triaging and patching such bugs, to be informed early and to be able to update their deployments, before the bug is openly announced.

+

Human Interference

+
Failure ScenarioProbabilityConsequencesFailsafe Level Coverage
Minor operating errorHighTemporary outageL1
Major operating errorLowPermanent loss of dataL3
Cyber attack (minor)Very Highpermanent loss or compromise of data on affected Disk and HostL1
Cyber attack (major)Mediumpermanent loss or compromise of data on affected Disk and HostL3
+

Mistakes in maintaining a data center will always happen. +To reduce the probability of such a mistake, measures are needed to reduce human error, which is more an issue of sociology and psychology instead of computer science. +On the other side an attack on an infrastructure cannot be avoided by this. +Instead every deployment needs to be prepared for an attack all the time, e.g. through security updates. +The severity of Cyber attacks can also vary broadly: from denial-of-service attacks, which should only be a temporary issue, up until coordinated attacks to steal or destroy data, which could also affect a whole deployment. +The easier an attack is, the more frequently it will be used by various persons and organizations up to be just daily business. +Major attacks are often orchestrated and require specific knowledge e.g. of Day-0 Bugs or the attacked infrastructure. +Due to that nature their occurance is less likely, but the damage done can be far more severe.

+

Consequences

+

Using the definition of levels established in this decision record throughout all SCS standards would allow readers to understand up to which level certain procedures or aspects of resources (e.g. volume types or a backend requiring redundancy) would protect their data and/or resource availability.

+

Affected Resources

+

IaaS Layer (OpenStack Resources)

+
ResourceExplanationAffected by Level
Ephemeral VMEquals the server resource in Nova, booting from ephemeral storage.L1, L2, L3, L4
Volume-based VMEquals the server resource in Nova, booting from a volume.L2, L3, L4
Ephemeral StorageDisk storage directly supplied to a virtual machine by Nova. Different from volumes.L1, L2, L3, L4
Ironic MachineA physical host managed by Ironic or as a server resource in Nova.L1, L2, L3, L4
(Glance) ImageIaaS resource usually storing raw disk data. Managed by the Glance service.(L1), L2, L3, L4
(Cinder) VolumeIaaS resource representing block storage disk that can be attached as a virtual disk to virtual machines. Managed by the Cinder service.(L1, L2), L3, L4
(Volume) SnapshotThinly-provisioned copy-on-write snapshots of volumes. Stored in the same Cinder storage backend as volumes.(L1, L2), L3, L4
Volume TypeAttribute of volumes determining storage details of a volume such as backend location or whether the volume will be encrypted.L3, L4
(Barbican) SecretIaaS resource storing cryptographic assets such as encryption keys. Managed by the Barbican service.L3, L4
Key Encryption KeyIaaS resource, used to encrypt other keys to be able to store them encrypted in a database.L3, L4
Floating IPIaaS resource, an IP that is usually routed and accessible from external networks.L3, L4
+

KaaS Layer (Kubernetes Resources)

+

A detailed list of consequnces for certain failures can be found in the Kubernetes docs. +The following table gives an overview about certain resources on the KaaS Layer and in which failsafe classes they are affected:

+
Resource(s)ExplanationAffected by Level
PodKubernetes object that represents a workload to be executed, consisting of one or more containers.L3, L4
ContainerA lightweight and portable executable image that contains software and all of its dependencies.L3, L4
Deployment, StatefulSetKubernetes objects that manage a set of Pods.L3, L4
JobApplication workload that runs once.L3, L4
CronJobApplication workload that runs once, but repeatedly at specific intervals.L3, L4
ConfigMap, SecretObjects holding static application configuration data.L3, L4
ServiceMakes a Pod's network service accessible inside a cluster.(L2), L3, L4
IngressMakes a Service externally accessible.L2, L3, L4
PersistentVolume (PV)Persistent storage that can be bound and mounted to a pod.L1, L2, L3, L4
+

Also see Kubernetes Glossary.

+ + \ No newline at end of file diff --git a/standards/scs-0118-w1-example-impacts-of-failure-scenarios/index.html b/standards/scs-0118-w1-example-impacts-of-failure-scenarios/index.html new file mode 100644 index 0000000000..51475a4bc5 --- /dev/null +++ b/standards/scs-0118-w1-example-impacts-of-failure-scenarios/index.html @@ -0,0 +1,55 @@ + + + + + +SCS Taxonomy of Failsafe Levels: Examples of Failure Cases and their impact on IaaS and KaaS resources | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Taxonomy of Failsafe Levels: Examples of Failure Cases and their impact on IaaS and KaaS resources

Examples of the impact from certain failure scenarios on Cloud Resources

+

Failure cases in Cloud deployments can be hardware related, environmental, due to software errors or human interference. +The following table summerizes different failure scenarios, that can occur:

+
Failure ScenarioProbabilityConsequencesFailsafe Level Coverage
Disk FailureHighPermanent data loss in this disk. Impact depends on type of lost data (data base, user data)L1
Host Failure (without disks)Medium to HighPermanent loss of functionality and connectivity of host (impact depends on type of host)L1
Host FailureMedium to HighData loss in RAM and temporary loss of functionality and connectivity of host (impact depends on type of host)L1
Rack OutageMediumOutage of all nodes in rackL2
Network router/switch outageMediumTemporary loss of service, loss of connectivity, network partitioningL2
Loss of network uplinkMediumTemporary loss of service, loss of connectivityL3
Power Outage (Data Center supply)MediumTemporary outage of all nodes in all racksL3
FireMediumpermanent Disk and Host loss in the affected zoneL3
FloodLowpermanent Disk and Host loss in the affected regionL4
EarthquakeVery Lowpermanent Disk and Host loss in the affected regionL4
Storm/TornadoLowpermanent Disk and Host loss in the affected regionL4
Software bug (major)Lowpermanent loss or compromise of data that trigger the bug up to data on the whole physical machineL3
Software bug (minor)Hightemporary or partial loss or compromise of dataL1
Minor operating errorHighTemporary outageL1
Major operating errorLowPermanent loss of dataL3
Cyber attack (minor)Highpermanent loss or compromise of data on affected Disk and HostL1
Cyber attack (major)Mediumpermanent loss or compromise of data on affected Disk and HostL3
+

Those failure scenarios can result in either only temporary (T) or permanent (P) loss of IaaS / KaaS resources or data. +Additionally, there are a lot of resources in IaaS alone that are more or less affected by these failure scenarios. +The following tables shows the impact when no redundancy or failure safety measure is in place, i.e., when +not even failsafe level 1 is fulfilled.

+

Impact on IaaS Resources (IaaS Layer)

+
ResourceDisk LossNode LossRack LossPower LossNatural CatastrophyCyber ThreatSoftware Bug
ImageP1T2T/PTP (T3)T/PP
VolumeP1T2T/PTP (T3)T/PP
User Data on RAM /CPUPPPPT/PP
volume-based VMP1T2T/PTP (T3)T/PP
ephemeral-based VMP1PPTP (T3)T/PP
Ironic-based VMP4PPTP (T3)T/PP
SecretP1T2T/PTP (T3)T/PP
network configuration (DB objects)P1T2T/PTP (T3)T/PP
network connectivity (materialization)T2T/PTP (T3)T/PT
floating IPP1T2T/PTP (T3)T/PT
+

For some cases, this only results in temporary unavailability and cloud infrastructures usually have certain mechanisms in place to avoid data loss, like redundancy in storage backends and databases. +So some of these outages are easier to mitigate than others.

+

Impact on Kubernetes Resources (KaaS layer)

+
note

In case the KaaS layer runs on top of IaaS layer, the impacts described in the above table apply for the KaaS layer as well.

+
ResourceDisk LossNode LossRack LossPower LossNatural CatastrophyCyber ThreatSoftware Bug
NodePT/P
KubeletTT/P
PodTT/P
PVCPP
API ServerTT/P
+ +

Footnotes

+
    +
  1. +

    If the resource is located on that specific disk. 2 3 4 5 6 7

    +
  2. +
  3. +

    If the resource is located on that specific node. 2 3 4 5 6 7

    +
  4. +
  5. +

    In case of disks, nodes or racks are not destroyed, some data could be safed. E.g. when a fire just destroyes the power line. 2 3 4 5 6 7 8 9

    +
  6. +
  7. +

    Everything located on that specific disk. If more than one disk is used, some data could be recovered.

    +
  8. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0119-v1-rook-decision/index.html b/standards/scs-0119-v1-rook-decision/index.html new file mode 100644 index 0000000000..256fa7639d --- /dev/null +++ b/standards/scs-0119-v1-rook-decision/index.html @@ -0,0 +1,59 @@ + + + + + +Replacement of the deprecated ceph-ansible tool | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Replacement of the deprecated ceph-ansible tool

Abstract

+

This decision record evaluates the choice for a modern, future-proof deployment tool for the networked storage solution Ceph in the SCS reference implementation, OSISM. +The new deployment tool aims to enhance Kubernetes integration within SCS, potentially allowing providers to manage the Ceph cluster with greater ease and efficiency.

+

Context

+

The current reference implementation relies on ceph-ansible, which is now deprecated. As a result, this decision record evaluates two alternatives: Cephadm and Rook.

+

Both tools are designed to roll out and configure Ceph clusters, providing the capability to manage clusters throughout their lifecycle. This includes functionalities such as adding or removing OSDs, upgrading Ceph services, and managing CRUSH maps, as outlined in the Feature-Decision-Table.

+

This decision record considers both the current and future needs of the reference implementation. The decision is guided by a comprehensive comparison of each tool's capabilities and limitations as well as the SCS communities needs and futures objectives.

+

Comparison of Features

+

The tool selected in this decision MUST ensure:

+
    +
  • ease of migration
  • +
  • future-proofness
  • +
  • feature-completeness and feature-maturity
  • +
  • effective management of Ceph clusters
  • +
+

Feature Decision Table

+

A comparative analysis of Cephadm and Rook highlights the following:

+
FeatureSupported in CephadmSupported in Rook
Migrate from other setups☑ Adoption of clusters, that where built with ceph-ansible is officially supported.☐ Migration from other setups is not offically supported. See this issue. Consequently, SCS develops a migration tool, named rookify. Alternatively, Rook allows to use Ceph as an external cluster.
Connect RGW with OpenStack Keystone☑ Experimental
Deploy specific Ceph versions
Upgrade to specific Ceph versions☑ Streamlined upgrade process.☑ Rook, CSI and Ceph upgrades have to be aligned, there is a guide available for each Rook version.
Deploy Ceph Monitors
Deploy Ceph Managers
Deploy Ceph OSDs
Deploy Ceph Object Gateway (RGW)
Removal of nodes
Purging of complete cluster
+

☐ not supported (yet) +☑ supported +☑☑ better option +☒ not supported on purpose

+

Evaluation in the Light of SCS Community Plans and Preferences

+

Environment: Cephadm is better suited for traditional or standalone environments. Conversely, Rook is tailored for Kubernetes. That being said, it's important to note that the current state of resource deployment and management on Kubernetes within the IaaS reference implementation is still in its early stages. This would make Rook one of the first components to utilise Kubernetes in OSISM.

+

Deployment: Cephadm uses containerization for Ceph components, whereas Rook fully embraces the Kubernetes ecosystem for deployment and management. Although containerization is already a core concept in the reference implementation, there is a strong push from the SCS community to adopt more Kubernetes.

+

Configuration and Management: Rook offers a more straightforward experience for those already utilizing Kubernetes, leveraging Kubernetes' features for automation and scaling. In contrast, Cephadm grants finer control over Ceph components, albeit necessitating more manual intervention. In both cases, this is something that needs to be partly abstracted by the reference implementation.

+

Integration: Rook provides better integration with cloud-native tools and environments, whereas Cephadm offers a more Ceph-centric management experience.

+

Migration: Rook does not currently provide any migration support, while Cephadm does offer this capability. However, the SCS community is highly supportive of developing a migration tool (Rookify) for Rook, as this would enhance SCS's influence by offering the first migration solution specifically for Rook providers.

+

SCS Community: An important factor in our decision is the preferences and direction of the SCS community and its providers. There is a noticeable trend towards increased use of Kubernetes within the community. This indicates a preference for deployment tools that integrate well with Kubernetes environments.

+

SCS Future Goals: The SCS community is open to building tools that provide open-source, publicly available solutions beyond the scope of SCS. This openness to development efforts that address limitations of the chosen tools, such as Rook, is also a key consideration in our decision.

+

Decision

+

As OSISM will increasingly focus on a Kubernetes-centric approach for orchestration in the near future, adopting Rook is a more suitable and standardized approach. Moreover, many service providers within the SCS community (including several who deploy OSISM) already have experience with Kubernetes. Regarding the missing OpenStack Keystone integration, we are confident that colleagues, who work on this issue, will provide a solution in a timely manner. We expect that deploying Ceph with Rook will simplify deployment and configuration form the outset. +In order to allow for a migration from existing Ceph installations to Rook, we decided to develop a migration tool (called Rookify) for the reference implementation. If the development of Rookify goes beyond the targeted scope of the reference implementation the tool will add value to the Ceph as well as the Rook community.

+

Consequences

+

Migrating an existing Ceph environment onto Kubernetes, as well as bringing together existing but independent Ceph and Kubernetes environments, will become straight forward without much manual interference needed. +Landscapes that currently do not deploy a Kubernetes cluster have to adapt and provide a Kubernetes cluster in the future.

+ + \ No newline at end of file diff --git a/standards/scs-0120-v1-capi-images/index.html b/standards/scs-0120-v1-capi-images/index.html new file mode 100644 index 0000000000..f6c3f2f8de --- /dev/null +++ b/standards/scs-0120-v1-capi-images/index.html @@ -0,0 +1,68 @@ + + + + + +Cluster-API images | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Cluster-API images

Abstract

+

The SCS reference implementation for the Kubernetes-as-a-service layer is built on top of Cluster API (CAPI), and therefore it depends on the corresponding VM images, which may or may not be present on the underlying infrastructure-as-a-service layer. Current tooling will make sure to upload the required image in case it's not present or outdated. However, these ad-hoc uploads will not be shared across environments, which may lead to waste of bandwidth (for transferring the image), storage (if images are not stored in a deduplicated manner), and not least time (because the upload does take multiple minutes). Needless to say, it may also lead to excessive greenhouse-gas emissions.

+

This decision record investigates the pros and cons of making the CAPI images mandatory. Ultimately, the decision is made to keep them recommended; we stress, however, that providers who offer the images by default should advertise this fact.

+

Terminology

+
    +
  • Kubernetes as a service (KaaS): A service that offers provisioning Kubernetes clusters.
  • +
  • Cluster API (CAPI): "Cluster API is a Kubernetes sub-project focused on providing declarative APIs and tooling to simplify provisioning, upgrading, and operating multiple Kubernetes clusters." (source) This API can thus be used to implement KaaS.
  • +
  • CAPI image: Virtual machine image that contains a standardized Kubernetes setup to be used for CAPI. The SCS reference implementation for KaaS depends on these images.
  • +
  • CSP: Cloud-service provider
  • +
+

Design considerations

+

We consider the following two options:

+
    +
  1. Make CAPI image mandatory.
  2. +
  3. Keep CAPI image recommended.
  4. +
+

For reasons of symmetry, it suffices to consider the pros and cons of the first option.

+

Pros:

+
    +
  • Save time, money, physical resources and power for both CSP and customer.
  • +
  • Regardless of CSP taste, this KaaS tech is part of SCS.
  • +
+

Neutral:

+
    +
  • The CAPI image can be provided in an automated fashion that means virtually no burden to the CSP.
  • +
  • The KaaS implementation will work either way.
  • +
  • Willing CSPs may offer the image by default and advertise as much.
  • +
+

Cons:

+
    +
  • Additional regulations would be necessary to guarantee quality and timeliness of image.
  • +
  • Some CSPs may be opposed to being forced to offer a certain service, which may hurt the overall acceptance +of the SCS standardization efforts.
  • +
+

Decision

+

Ultimately, we value the freedom of the CSPs (and the acceptance of the standardization efforts) highest; +willing CSPs are welcome to opt in, i.e., to provide up-to-date images and advertise as much.

+

Therefore we decide to keep the CAPI images recommended.

+

Consequences

+

None, as the status quo is being kept.

+

Open questions

+

Some interesting potential future work does remain, however: to find a way to certify that a willing provider +does indeed provide up-to-date images. It would be possible with today's methods to certify that a CAPI +image is present (the image_spec yaml file would have to be split up to obtain a separate test case), but +we there is no way to make sure that the image is up to date.

+ + \ No newline at end of file diff --git a/standards/scs-0121-v1-Availability-Zones-Standard/index.html b/standards/scs-0121-v1-Availability-Zones-Standard/index.html new file mode 100644 index 0000000000..e9b37b97a4 --- /dev/null +++ b/standards/scs-0121-v1-Availability-Zones-Standard/index.html @@ -0,0 +1,167 @@ + + + + + +SCS Availability Zones | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Availability Zones

Introduction

+

On the IaaS level especially in OpenStack it is possible to group resources in Availability Zones. +Such Zones often are mapped to the physical layer of a deployment, such as e.g. physical separation of hardware or redundancy of power circuits or fire zones. +But how CSPs apply Availability Zones to the IaaS Layer in one deplyoment may differ widely. +Therefore this standard will address the minimal requirements that need to be met, when creating Avaiability Zones.

+

Terminology

+
TermExplanation
Availability Zone(also: AZ) internal representation of physical grouping of service hosts, which also lead to internal grouping of resources.
Fire ZoneA physical separation in a data center that will contain fire within it. Effectively stopping spreading of fire.
PDUPower Distribution Unit, used to distribute the power to all physical machines of a single server rack.
ComputeA generic name for the IaaS service, that manages virtual machines (e.g. Nova in OpenStack).
NetworkA generic name for the IaaS service, that manages network resources (e.g. Neutron in OpenStack).
StorageA generic name for the IaaS service, that manages the storage backends and virtual devices (e.g. Cinder in OpenStack).
BSIGerman Federal Office for Information Security (Bundesamt für Sicherheit in der Informationstechnik)
CSPCloud Service Provider, provider managing the OpenStack infrastructure.
SDNSoftware Defined Network, virtual networks managed by the networking service.
+

Motivation

+

Redundancy is a non-trivial but relevant issue for a cloud deployment. +First and foremost it is necessary to increase failure safety through redundancy on the physical layer. +The IaaS layer as the first abstraction layer from the hardware has an important role in this topic, too. +The grouping of redundant physical resources into Availability Zones on the IaaS level, gives customers the option to distribute their workload to different AZs which will result in a better failure safety. +While CSPs already have some similarities in their grouping of physical resources to AZs, there are also differences. +This standard aims to reduce those differences and will clarify, what customers can expect from Availability Zones in IaaS.

+

Availability Zones in IaaS can be set up for Compute, Network and Storage separately while all may be referring to the same physical separation in a deployment. +This standard elaborates the necessity of having Availability Zones for each of these classes of resources. +It will also check the requirements customers may have, when thinking about Availability Zones in relation to the taxonomy of failure safety levels 1. +The result should enable CSPs to know when to create AZs to be SCS-compliant.

+

Design Considerations

+

Availability Zones should represent parts of the same physical deployment that are independent of each other. +The maximum level of physical independence is achieved through putting physical machines into different fire zones. +In that case a failure case up to level 3 as described in the taxonomy of failure safety levels document1 will not lead to a complete outage of the deployment.

+

Having Availability Zones represent fire zones will also result in AZs being able to take workload from another AZ in a failure case of Level 3. +So that even the destruction of one Availability Zone will not automatically include the destruction of the other AZs.

+
caution

Even with fire zones being physically designed to protect parts of a data center from severe destruction in case of a fire, this will not always succeed. +Availability Zones in Clouds are most of the time within the same physical data center. +In case of a big catastrophe like a huge fire or a flood the whole data center could be destroyed. +Availability Zones will not protect customers against these failure cases of level 4 of the taxonomy of failure safety1.

+

Smaller deplyoments like edge deployments may not have more than one fire zone in a single location. +To include such deployments, it should not be required to use Availability Zones.

+

Other physical factors that should be considered are the power supplies, internet connection, cooling and core routing. +Availability Zones were also used by CSPs as a representations of redundant PDUs. +That means there are deployments, which have Availability Zones per rack as each rack has it's own PDU and this was considered to be the single point of failure an AZ should represent. +While this is also a possible measurement of independency it only provides failure safety for level 2. +Therefore this standard should be very clear about which independency an AZ should represent and it should not be allowed to have different deployments with their Availability Zones representing different levels of failure safety.

+

Additionally Availability Zones are available for Compute, Storage and Network services. +They behave differently for each of these resources and also when working across resource-based Availability Zones, e.g. attaching a volume from one AZ to a virtual machine in another AZ. +For each of these IaaS resource classes, it should be defined, under which circumstances Availability Zones should be used.

+

Scope of the Availability Zone Standard

+

When elaborating redundancy and failure safety in data centers, it is necessary to also define redundancy on the physical level. +There are already recommendations from the BSI for physical redundancy within a cloud deployment 2. +This standard considers these recommendation as a basis, that is followed by most CSPs. +So this standard will not go into details, already provided by the CSP, but will rather concentrate on the IaaS layer and only have a coarse view on the physical layer. +The first assumtion from the recommendations of the BSI is that the destruction of one fire zone will not lead to an outage of all power lines (not PDUs), internet connections, core routers or cooling systems.

+

For the setup of Availability Zone this means, that within every AZ, there needs to be redundancy in core routers, internet connection, power lines and at least two separate cooling systems. +This should avoid having single points of failure within the Availability Zones. +But all this physical infrastructure can be the same over all Availability Zones in a deployment, when it is possible to survive the destruction of one fire zone.

+

Options considered

+

Physical-based Availability Zones

+

It is possible standardize the usage of Availability Zones over all IaaS resources. +The downside from this is, that the IaaS resources behave so differently, that they have different requirements for redundancy and thus Availability Zones. +This is not the way to go. +Besides that, it is already possible to create two physically separated deployments close to each other, connect them with each other and use regions to differ between the IaaS on both deployments.

+

The question that remains is, what an Availability Zone should consist of? +Having one Availability Zone per fire zone gives the best level of failure safety, that can be achieved by CSPs. +When building up on the relation between fire zone and physical redundancy recommendations as from the BSI, this combination is a good starting point, but need to be checked for the validity for the different IaaS resources.

+

Another point is where Availability Zones can be instantiated and what the connection between AZs should look like. +To have a proper way to deal with outages of one AZ, where a second AZ can step in, a few requirements need to be met for the connection between those two AZs. +The amount data that needs to be transferred very fast in a failure case may be enormous, so there is a requirement for a high bandwidth between connected AZs. +Tho avoid additional failure cases the latency between those two Availability Zones need to be low. +With such requirements it is very clear that AZs should only reside within one (physical) region of an IaaS deployment.

+

AZs in Compute

+

Compute Hosts are physical machines on which the compute service runs. +A single virtual machine is always running on ONE compute host. +Redundancy of virtual machines is either up to the layer above IaaS or up to the customers themself. +Having Availability Zones gives customers the possibility to let another virtual machine as a backup run within another Availability Zone.

+

Customers will expect that in case of the failure of one Availability Zone all other AZs are still available. +The highest possible failure safety here is achieved, when Availability Zones for Compute are used for different fire zones.

+

When the BSI recommendations are followed, there should already be redundancy in power lines, internet connection and cooling. +An outage of one of these physical resources will not affect the compute host and its resources for more than a minimal timeframe. +But when a single PDU is used for a rack, a failure of that PDU will result in an outage of all compute hosts in this rack. +In such a case it is not relevant, whether this rack represents a whole Availability Zone or is only part of a bigger AZ. +All virtual machines on the affected compute hosts will not be available and need to be restarted on other hosts, whether of the same Availability Zone or another.

+

AZs in Storage

+

There are many different backends used for the storage service with Ceph being one of the most prominent backends. +Configuring those backends can already include to span one storage cluster over physical machines in different fire zones. +In combination with internal replication a configuration is possible, that already distributes replicas from volumes over different fire zones. +When a deployment has such a configured storage backend, it already can provide safety in case of a failure of level 3.

+

Using Availability Zones is also possible for the storage service, but configuring AZs, when having a configuration like above will not increase safety. +Nevertheless using AZs when having different backends in different fire zones will give customers a hint to backup volumes into storages of other AZs.

+

Additionally when the BSI recommendations are followed, there should already be redundancy in power lines, internet connection and cooling. +An outage of one of these physical resources will not affect the storage host and its resources for more than a minimal timeframe. +When internal replication is used, either through the IaaS or through the storage backend itself, the outage of a single PDU and such a single rack will not affect the availability of the data itself. +All these physical factors are not requiring the usage of an Availability Zone for Storage. +An increase of the level of failure safety will not be reached through AZs in these cases.

+

Still it might be confusing when having deployments with compute AZs but without storage AZs. +CSPs may need to communicate clearly up to which failure safety level their storage service can automatically have redundancy and from which level customers are responsible for the redundancy of their data.

+

AZs in Network

+

Virtualized network resources can typically be quickly and easily set up from building instructions. +Those instructions are stored in the database of the networking service.

+

If a physical machine, on which certain network resources are set up, is not available anymore, the resources can be rolled out on another physical machine, without being dependent on the current situation of the lost resources. +There might only be a loss of a few packets within the affected network resources.

+

With having Compute and Storage in a good state (e.g. through having fire zones with a compute AZ each and storage being replicated over the fire zones) there would be no downsides to omitting Availability Zones for the network service. +It might even be the opposite: Having resources running in certain Availability Zones might prevent them from being scheduled in other AZs3. +As the network resources like routers are bound to an AZ, in a failure case of one AZ all resource definitions might still be there in the database, while the implementation of those resources is gone. +Trying to rebuild them in another AZ is not possible, because the scheduler will not allow them to be implemented in another AZ, than the one thats present in their definition. +In a failure case of one AZ this might lead to a lot of manual work to rebuild the SDN from scratch instead of just re-using the definitions.

+

Because of this severe side effect, this standard will make no recommendations about Network AZs.

+

Cross-Attaching volumes from one AZ to another compute AZ

+

Without the networking AZs we only need to take a closer look into attaching volumes to virtual machines across AZs.

+

When there is more than one Storage Availability Zone, those AZs do normally align with the Compute Availability Zones. +This means that fire zone 1 contains compute AZ 1 and storage AZ 1 , fire zone 2 contains compute AZ 2 and storage AZ 2 and the same for fire zone 3. +It is possible to allow or forbid cross-attaching volumes from one storage Availability Zone to virtual machines in another AZ. +If it is not allowed, then the creation of volume-based virtual machines will fail, if there is no space left for VMs in the corresponding Availability Zone. +While this may be unfortunate, it gives customers a very clear picture of an Availability Zone. +It clarifies that having a virtual machine in another AZ also requires having a backup or replication of volumes in the other storage AZ. +Then this backup or replication can be used to create a new virtual machine in the other AZ.

+

It seems to be a good decision to not encourage CSPs to allow cross-attach. +Currently CSPs also do not seem to widely use it.

+

Standard

+

If Compute Availability Zones are used, they MUST be in different fire zones. +Availabilty Zones for Storage SHOULD be setup, if there is no storage backend used that can span over different fire zones and automatically replicate the data. +Otherwise a single Availabilty Zone for Storage SHOULD be configured.

+

If more than one Availability Zone for Storage is set up, the attaching of volumes from one Storage Availability Zone to another Compute Availability Zone (cross-attach) SHOULD NOT be possible.

+

Within each Availability Zone:

+
    +
  • there MUST be redundancy in power supply, as in line into the deployment
  • +
  • there MUST be redundancy in external connection (e.g. internet connection or WAN-connection)
  • +
  • there MUST be redundancy in core routers
  • +
  • there SHOULD be redundancy in the cooling system
  • +
+

AZs SHOULD only occur within the same region and have a low-latency interconnection with a high bandwidth.

+ +

The taxonomy of failsafe levels can be used to get an overview over the levels of failure safety in a deployment(TODO: link after DR is merged.)

+

The BSI can be consulted for further information about failure risks, risk analysis for a datacenter or measures for availability.

+

Conformance Tests

+

As this standard will not require Availability Zones to be present, we cannot automatically test the conformance. +The other parts of the standard are physical or internal and could only be tested through an audit. +Whether there are fire zones physically available is a criteria that will never change for a single deployment - this only needs to be audited once. +It might be possible to also use Gaia-X Credentials to provide such information, which then could be tested.

+ +

Footnotes

+
    +
  1. +

    Taxonomy of Failsafe Levels in SCS (TODO: change link as soon as taxonomy is merged) 2 3

    +
  2. +
  3. +

    Availability recommendations from the BSI

    +
  4. +
  5. +

    Availability Zones in Neutron for OVN

    +
  6. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0121-w1-Availability-Zones-Standard/index.html b/standards/scs-0121-w1-Availability-Zones-Standard/index.html new file mode 100644 index 0000000000..ee3e3c30af --- /dev/null +++ b/standards/scs-0121-w1-Availability-Zones-Standard/index.html @@ -0,0 +1,50 @@ + + + + + +SCS Availability Zones: Implementation and Testing Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Availability Zones: Implementation and Testing Notes

Automated Tests

+

The standard will not preclude small deployments and edge deployments, that both will not meet the requirement for being divided into multiple Availability Zones. +Thus multiple Availability Zones are not always present. +Somtimes there can just be a single Availability Zones. +Because of that, there will be no automated tests to search for AZs.

+

Required Documentation

+

The requirements for each Availability Zone are written in the Standard. +For each deployment, that uses more than a single Availability Zone, the CSP has to provide documentation to proof the following points:

+
    +
  1. The presence of fire zones MUST be documented (e.g. through construction plans of the deployment).
  2. +
  3. The correct configuration of one AZ per fire zone MUST be documented.
  4. +
  5. The redundancy in Power Supply within each AZ MUST be documented.
  6. +
  7. The redundancy in external connection within each AZ MUST be documented.
  8. +
  9. The redundancy in core routers within each AZ MUST be documented.
  10. +
+

All of these requirements will either not change at all like the fire zones or it is very unlikely for them to change like redundant internet connection. +Because of this documentation must only be provided in the following cases:

+
    +
  1. When a new deployment with multiple AZs should be tested for compliance.
  2. +
  3. When there are physical changes in a deplyoment, which already provided the documentation: the changes needs to be documented and provided as soon as possible.
  4. +
+

Alternative Documentation

+

If a deployment already did undergo certification like ISO 27001 or ISO 9001, those certificates can be provided as part of the documentation to cover the redundancy parts. +It is still required to document the existence of fire zones and the correct configuration of one AZ per fire zone.

+

Physical Audits

+

In cases where it is reasonable to mistrust the provided documentation, a physical audit by a natural person - called auditor - send by e.g. the OSBA should be performed. +The CSP of the deployment, which needs such an audit, should grant access to the auditor to the physical infrastructure and should show them all necessary IaaS-Layer configurations, that are needed to verify compliance to this standard.

+ + \ No newline at end of file diff --git a/standards/scs-0122-v1-node-to-node-encryption/index.html b/standards/scs-0122-v1-node-to-node-encryption/index.html new file mode 100644 index 0000000000..a4b4a0e76c --- /dev/null +++ b/standards/scs-0122-v1-node-to-node-encryption/index.html @@ -0,0 +1,499 @@ + + + + + +_End-to-End Encryption between Customer Workloads_ | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

_End-to-End Encryption between Customer Workloads_

Abstract

+

This document explores options for developing end-to-end (E2E) encryption for +VMs, Magnum workloads, and container layers to enhance security between user +services. It includes a detailed review of various technologies, feedback from +the OpenStack community, and the decision-making process that led to selecting +VXLANs with the OpenStack ML2 plugin and it's later abandonment in favour of +natural openvswitch-ipsec solution.

+

Terminology

+
TermMeaning
CSPCloud service provider, in this document it includes also an operator of a private cloud
VMVirtual machine, alternatively instance, is a virtualized compute resource that functions as a self-contained server for a customer
NodeMachine under CSP administration which hosts cloud services and compute instances
+

Context

+

Motivation

+

The security of customer/user workloads is one of CSPs main concerns. With +larger and more diverse cloud instances, parts of the underlying physical +infrastructure can be outside of CSPs direct control, either when +interconnecting datacenters via public internet or in the case of renting +infrastructure from third party. Many security breaches occur due to +actions of malicious or negligent inhouse operators. While some burden lies +with customers, which should secure their own workloads, CSP should have the +option to transparently protect the data pathways between instances, more so +for private clouds, where CSP and customer are the same entity or parts of the +same entity.

+

In RFC89261 it is stated:

+
+

A tenant system in a customer premises (private data center) may want to +connect to tenant systems on their tenant overlay network in a public cloud +data center, or a tenant may want to have its tenant systems located in +multiple geographically separated data centers for high availability. Geneve +data traffic between tenant systems across such separated networks should be +protected from threats when traversing public networks. Any Geneve overlay +data leaving the data center network beyond the operator's security domain +SHOULD be secured by encryption mechanisms, such as IPsec or other VPN +technologies, to protect the communications between the NVEs when they are +geographically separated over untrusted network links.

+
+

We aren't considering the communication intra node, meaning inside one host +node between different VMs potentially of multiple tenants as this is a +question of tenant isolation, not of networking security, and encryption here +would be possibly a redundant measure. Isolation of VMs is handled by OpenStack +on multiple levels - overlay tunneling protocols, routing rules on networking +level, network namespaces on kernel level and hypervisor isolation mechanisms. +All the communication here is existing inside node and any malicious agent with +high enough access to the node itself to observe/tamper with the internal +communication traffic would pressumably have access to the encryption keys +themselves, rendering the encryption ineffective.

+

Potential threats in detail

+

We are assuming that:

+
    +
  • the customer workloads are not executed within secure enclaves (e.g. Security +Guard Extensions (SGX)) and aren't using security measures like end-to-end +encryption themselves, either relying with security on the CSP or in the case +of a private cloud are run by the operator of the cloud
  • +
  • the CSP OpenStack administrators are deemed trustworthy since they possess +root access to the host nodes, with access to keys and certificates, enabling +them to bypass any form of internode communication encryption
  • +
  • a third party or an independent team manages physical network communication +between nodes within a colocation setting or the communication passes unsafe +public infrastructure in the case of a single stretched instance spanning +multiple data centers
  • +
+

Man in the Middle Attack

+

Considering the assumptions and the objective to enforce end-to-end (E2E) +encryption for user workloads, our primary security concern is averting +man-in-the-middle (MITM) attacks. These can be categorized into two distinct +forms: active and passive.

+
Passive Attacks - Eavesdropping
+

Consider the scenario where an untrusted individual, such as a third party +network administrator, with physical access to the data center engages in +'passive' covert surveillance, silently monitoring unencrypted traffic +without interfering with data integrity or network operations.

+

Wiretapping is a common technique employed in such espionage. It involves the +unauthorized attachment to network cabling, enabling the covert observation of +data transit. This activity typically goes unnoticed as it does not disrupt +the flow of network traffic, although it may occasionally introduce minor +transmission errors.

+

An alternative strategy involves deploying an interception device that +captures and retransmits data, which could potentially introduce network +latency or, if deployed disruptively, cause connectivity interruptions. Such +devices can be concealed by synchronizing their installation with network +downtime, maintenance periods, or less conspicuous times like power outages. +They could also be strategically placed in less secure, more accessible +locations, such as inter-building network links. This applies to wiretapping +as well.

+

Furthermore, the vulnerability extends to network devices, where an attacker +could exploit unsecured management ports or leverage compromised remote +management tools (like IPMI) to gain unauthorized access. Such access points, +especially those not routinely monitored like backup VPNs, present additional +security risks.

+

Below is a conceptual diagram depicting potential vulnerabilities in an +OpenStack deployment across dual regions, highlighting how these passive +eavesdropping techniques could be facilitated.

+

image

+
Active - Spoofing / Tampering
+

Active network attacks like spoofing and tampering exploit various access +points, often leveraging vulnerabilities uncovered during passive eavesdropping +phases. These attacks actively manipulate or introduce unauthorized +communications on the network.

+

Spoofing involves an attacker masquerading as another device or user within the +network. This deception can manifest in several ways:

+
    +
  • ARP Spoofing: The attacker sends forged ARP (Address Resolution Protocol) +messages onto the network. This can redirect network traffic flow to the +attacker's machine, intercepting, modifying, or blocking data before it +reaches its intended destination.
  • +
  • DNS Spoofing: By responding with falsified DNS replies, an attacker can +reroute traffic to malicious sites, further compromising or data exfiltration.
  • +
  • IP Spoofing: The attacker disguises their network identity by falsifying +IP address information in packets, tricking the network into accepting them +as legitimate traffic. This can be particularly damaging if encryption is not +enforced, enabling the attacker to interact with databases, invoke APIs, or +execute unauthorized commands while appearing as a trusted entity.
  • +
+

Moreover, when an active interception device is in place, attackers can extend +their capabilities to traffic filtering. They might selectively delete or alter +logs and metrics to erase traces of their intrusion or fabricate system +performance data, thus obscuring the true nature of their activities.

+

Preliminary considerations

+

Initially we wanted to create a plugin into Neutron2 using eBPF3 to +secure the traffic automatically between VMs. We presented the idea in a +team IaaS call4. After the initial round of feedback specific requirements +emerged.

+

Utilize existing solutions

+

Leverage existing technologies and frameworks as much as possible. This +approach aims to reduce development time and ensure the solution is built on +proven, reliable foundations. Potential technologies include:

+
    +
  • OVS5 + IPSec6: Provides an overlay network and has built-in +support for encryption using IPsec. Leveraging OVS can minimize development +time since it is already integrated with OpenStack.
  • +
  • Neutron2 with eBPF3: Using eBPF3 could provide fine-grained +control over packet filtering and encryption directly in the kernel.
  • +
  • TripleO7 (with IPsec): TripleO7 tool set for OpenStack deployment +supports IPsec tunnels between nodes.
  • +
  • Neutron2 + Cilium8: Cilium is an open source, cloud native +eBPF3-based networking solution, including transparent encryption tools.
  • +
  • Tailscale9 is a mesh VPN based on WireGuard10 that simplifies the +setup of secure, encrypted networks. This could be a potential alternative +to managing encrypted connections in OpenStack environments.
  • +
+

Upstream integration

+

Move as much of the development work upstream into existing OpenStack projects. +This will help ensure the solution is maintained by the wider OpenStack +community, reducing the risk of it becoming unmaintained or unusable in the +future. This means to collaborate with the OpenStack community to contribute +changes upstream, particularly in projects like Neutron2, OVN11, +kolla12 and ansible-kolla13.

+

Address threat modeling issues

+

"We should not encrypt something just for the sake of encryption." The solution +must address the specific security issues identified in the +threat modeling. This ideally includes +protecting against both passive (eavesdropping) and active (spoofing, +tampering) MITM attacks. Encryption mechanisms on all communication channels +between VMs, containers, hosts prevents successfull eavesdropping, +authentication and integrity checks prevent spoofing and tampering. For example +IPsec6 provides mechanisms for both encyption and integrity verification.

+

Performance impact and ease of use

+

Evaluate the performance impact of the encryption solution and ensure it is +minimal. Performance benchmarking should be conducted to assess the impact of +the encryption solution on network throughput and latency. For local trusted +scenarios opt out should be possible. The solution should also be easy to use +and manage, both for administrators and ideally fully transparent for +end-users. This may involve developing user-friendly interfaces and automated +tools for key management and configuration.

+

Avoid redundant encryption

+

If possible, develop a mechanism to detect and avoid encrypting traffic that is +already encrypted. This will help optimize performance and resource usage.

+

By focusing on these detailed requirements and considerations, we aim to +develop a robust, efficient, and sustainable E2E encryption solution for +OpenStack environments. This solution will not only enhance security for user +workloads but also ensure long-term maintainability and ease of use.

+

Exploration of technologies

+

Based on the result of the threat modeling and presentation, we explored the +following technologies and also reached out to the OpenStack mailing list for +additional comments.

+

This section provides a brief explanation of OpenStack networking and design +decisions for encryption between customer workloads.

+

Networking in OpenStack

+

The foundation of networking in OpenStack is the Neutron2 project, +providing networking as a service (NaaS). It creates and manages network +resources such as switches, routers, subnets, firewalls and load balancers, +uses plugin architecture to support different physical network implementation +options and is accessible to admin or other services through API.

+

Another integral part is the Open vSwitch (OVS)5 - a widely adopted virtual +switch implementation, which is not strictly necessary, as Neutron is quite +flexible with compenents used to implement the infrastructure, but tends to +be the agent of choice and is the current default agent for Neutron. It allows +it to respond to environment changes, supporting accounting and monitoring +protocols and maintaining OVSDB state database. It manages virtual ports, +bridges and tunnels on hosts.

+

Open Virtual Networking (OVN11) is a logical abstraction layer on top of OVS, +developed by the same community that became the default controller driver for +Neutron. It manages logical networks insulated from underlying physical/virtual +networks by encapsulation. It replaces the need for OVS agents running on each +host and supports L2 switching, distributed L3 routing, access control and load +balancing.

+

Encryption options

+
MACsec14
+

A layer 2 security protocol, defined by an IEEE standard 802.1AE. It allows to +secure an ethernet link for almost all traffic, including control protocols +like DHCP and ARP. It is mostly implemented in hardware, in routers and +switches, but software implementations exist, notably a Linux kernel module.

+
eBPF3-based encryption with Linux Kernel Crypto API
+

A network packet specific filtering technology in Linux kernel called +Berkeley Packet Filter (BPF) uses a specialized virtual machine inside +kernel to run filters on the networking stack. eBPF is an extension of this +principle to a general purpose stack which can run sandboxed programs in kernel +without changes of kernel code or loading modules. High-performance networking +observability and security is a natural use-case with projects like Cilium8 +implementing transparent in-kernel packet encryption with it. Linux kernel +itself also provides an encryption framework called +Linux Kernel Crypto API15 which such solutions use.

+
IPsec6
+

Internet Protocol security is a suite of protocols for network security on +layer 3, providing authentication and packets encryption used for example in +Virtual Private Network (VPN) setups. It is an IETF16 specification with +various open source and commercial implementations. For historical +reasons17 it defines two main transmission protocols +Authentication Header (AH) and Encapsulating Security Payload (ESP) where only +the latter provides encryption in addition to authentication and integrity. The +key negotiations use the IKE(v1/v2) protocol to establish and maintain +Security Associations (SA).

+
WireGuard10
+

Aims to be a simple and fast open source secure network tunneling solution +working on layer 3, utilizing state-of-the-art cryptography while maintaining +much simpler codebase and runtime setup as alternative solutions18. Focus +is on fast in-kernel encryption. WireGuard10 adds new network interfaces, +managable by standard tooling (ifconfig, route,...) which act as tunneling +interfaces. Main mechanism, called Cryptokey routing, are tables associating +public keys of endpoints with allowed IPs inside given tunnels. These behave as +routing tables when sending and access control lists (ACL) when receiving +packets. All packets are sent over UDP. Built-in roaming is achieved by both +server and clients being able to update the peer list by examining from where +correctly authenticated data originates.

+

Solution proposals

+

TripleO7 with IPsec6

+
+

TripleO is a project aimed at installing, upgrading and operating OpenStack +clouds using OpenStack's own cloud facilities as the foundation - building on +Nova, Ironic, Neutron and Heat to automate cloud management at datacenter +scale

+
+

This project is retired as of February 2024, but its approach was considered +for adoption.

+

Its deployment allowed for IPsec6 encryption of node communication. When +utilized, two types of tunnels were created in overcloud: node-to-node tunnels +for each two nodes on the same network, for all networks those nodes were on, +and Virtual IP tunnels. Each node hosting the Virtual IP would open a tunnel +for any node in the specific network that can properly authenticate.

+

OVN11 + IPsec6

+

There is support in the OVN11 project for IPsec6 encryption of tunnel +traffic19. A daemon running in each chassis automatically manages and +monitors IPsec6 tunnel states.

+

Neutron2 + Cilium8

+

Another potential architecture involves a Neutron2 plugin hooking an +eBPF3 proxy on each interface and moving internal traffic via an encrypted +Cilium8 mesh. Cilium uses IPsec6 or WireGuard[wg] to transparently +encrypt node-to-node traffic. There were some attempts to integrate Cilium8 +with OpenStack 20, 21, but we didn't find any concrete projects +which would leverage the transparent encryption ability of Cilium8 in +OpenStack environment. This path would pressumably require significant +development.

+

Neutron2 + Calico22

+

The Calico22 project in its community open source version provides +node-to-node encryption using WireGuard10. Despite being primarily a +Kubernetes networking project, it provides an OpenStack integration23 via +a Neutron2 plugin and deploying the necessary subset of tools like etcd, +Calico agent Felix, routing daemon BIRD and a DHCP agent.

+

Proof of concept implementations

+

Neutron Plugin

+

Initially the potential for developing a specialized Neutron plugin was +investigated and a simple skeleton implementation for testing purposes was +devised.

+

Own development was later abandoned in favor of a more sustainable solution +using existing technologies as disussed in +preliminary considerations.

+

Manual setup

+

We created a working Proof of Concept with manually setting up VXLAN tunnels +between nodes. While this solution ensures no impact on OpenStack and is easy +to set up, it has limitations, such as unencrypted data transmission if the +connection breaks. To mitigate this, we proposed using a dedicated subnet +present only in the IPsec6 tunnels.

+

We presented the idea to the kolla-ansible[^ak] project, but it was deemed out +of scope. Instead, we were directed towards a native Open vSwitch solution +supporting IPsec6. This requires creating a new OpenStack service +(working name: openstack-ipsec) and a role to manage chassis keys and run the +openstack-ipsec container on each node.

+

Proof of concept (PoC) implementation

+

In our second proof of concept, we decided to implement support for +openstack-ipsec. The initial step involved creating a new container image +within the kolla12 project specifically for this purpose.

+
Architecture
+

When Neutron2 uses OVN11 as controller it instructs it to create the +necessary virtual networking infrastructure (logical switches, routers, etc.), +particullary to create Geneve tunnels between compute nodes. These tunnels are +used to carry traffic between instances on different compute nodes.

+

In PoC setup Libreswan24 suite runs on each compute node and manages the +IPSec6 tunnels. It encrypts the traffic flowing over the Geneve tunnels, +ensuring that data is secure as it traverses the physical network. In setup +phase it establishes IPSec tunnels between compute nodes by negotiating the +necessary security parameters (encryption, authentication, etc.). Once the +tunnels are established, Libreswan24 monitors and manages them, ensuring +that the encryption keys are periodically refreshed and that the tunnels remain +up. It also dynamically adds and removes tunnels based on changes of network +topology.

+

A packet originating from a VM on one compute node and destined for a VM on +a different node is processed by OVS and encapsulated into a Geneve tunnel. +Before the Geneve-encapsulated packet leaves the compute node, it passes +through the Libreswan process, which applies IPSec encryption. The encrypted +packet traverses the physical network to the destination compute node. On the +destination node, Libreswan24 decrypts the packet, and OVN11 handles +decapsulation and forwards it to the target VM.

+
Challanges
+

Implementing the openstack-ipsec image we encountered a significant challenge: +the ovs-ctl start-ovs-ipsec command could not run inside the container because +it requires a running init.d or systemctl to start the IPsec daemon immediately +after OVS11 deploys the configuration. We attempted to use supervisor to +manage the processes within the container. However, this solution forced a +manual start of the IPsec daemon before ovs-ctl had the chance to create the +appropriate configurations.

+

Another challenge was the requirement for both the IPsec daemon and ovs-ipsec +to run within a single container. This added complexity to the container +configuration and management, making it harder to ensure both services operated +correctly and efficiently.

+
Additional infrastructure
+

New ansible role for generating chassis keys and distributing them to the +respective machines was created. This utility also handles the configuration on +each machine. Managing and creating production certificates is up to the user, +which is also true for the backend TLS certificates in kolla-ansible13. +While this management should be handled within the same process, it currently +poses a risk of downtime when certificates expire, as it requires careful +management and timely renewal of certificates.

+

The new container image was designed to include all necessary +components for openstack-ipsec. Using supervisor to manage the IPsec daemon +within the container involved creating configuration files to ensure all +services start correctly. However, integrating supervisor introduced additional +complexity and potential points of failure.

+
Possible improvements
+

PoC doesn't currently address the opt-out possibility for disabling the +encryption for some specific group of nodes, where operator deems it +detrimental because of them being virtual or where security is already handled +in some other layer of the stack. This could be implemented as a further +customization available to the operator to encrypt only some subset of Geneve +tunnels, either in blacklist or whitelist manner.

+

Further refinement is needed to ensure ovs-ctl and the IPsec daemon start and +configure correctly within the container environment. Exploring alternative +process management tools or improving the configuration of supervisor could +help achieve a more robust solution.

+

Implementing automated certificate management could mitigate the risks +associated with manual certificate renewals. Tools like Certbot or integration +with existing Public Key Infrastructure (PKI) solutions might be beneficial.

+

Engaging with the upstream Open vSwitch community to address containerization +challenges and improve support for running ovs-ctl within containers could lead +to more sustainable solution.

+

Decision

+

The final proof of concept implementation demonstrated the feasibility of +implementing transparent IPsec6 encryption between nodes in an OVN11 +logical networking setup in OpenStack. +To recapitulate our preliminary considerations:

+

Utilize existing solutions

+

Implementation in kolla-ansible13 is unintrusive, provided by a +self-contained new kolla12 container, which only adds an IPsec6 +tunneling support module to OVS5, which is already an integral part of +OpenStack networking, and a mature open source toolkit - Libreswan24. Also +OVN11 has native support in OpenStack and became the default controller for +Neutron2.

+

Address threat modeling issues

+

As disussed in motivation and threat +modelling sections our concern lies with the +potentially vulnerable physical infrastructure between nodes inside or between +data centers. In this case ensuring encryption and integrity of packets before +leaving any node addresses these threats, while avoiding the complexity of +securing the communication on the VM level, where frequent additions, deletions +and migrations could render such system complicated and error prone. We also +don't needlessly encrypt VM communication inside one node.

+

Avoid redundant encryption

+

As the encryption happens inside tunnels specific for inter-node workload +communication, isolated on own network and also inside Geneve tunnels, no cloud +service data, which could be possibly encrypted on higher-levels (TLS) is +possible here. As to the workload communication itself - detecting higher-layer +encryption in a way that would allow IPsec6 to avoid redundant encryption +is complex and would require custom modifications or non-standard solutions. +It's usually safer and more straightforward to allow the redundancy, ensuring +security at multiple layers, rather than trying to eliminate it.

+

Performance impact and ease of use

+

Setup is straightforward for the operator, there is just a flag to enable or +disable the IPsec6 encryption inside Geneve tunnels and the need to set the +Neutron2 agent to OVN11. No other configuration is necessary. The only +other administrative burden is the deployment of certificates to provided +configuration directory on the control node.

+

Certificate management for this solution can and should be handled in the same +way as for the backend service certificates which are part of the ongoing +efforts to provide complete service communication encryption in kolla-ansible. +Currently the management of these certificates is partially left on external +processes, but if a toolset or a process would be devised inside the project, +this solution would fit in.

+

Upstream integration

+

The potential for upstream adoption and long-term maintainability makes this a +promising direction for securing inter-node communication in OpenStack +environments.

+

References

+ +

Footnotes

+
    +
  1. +

    RFC8926

    +
  2. +
  3. +

    Neutron - networking as a service (NaaS) in OpenStack 2 3 4 5 6 7 8 9 10 11 12

    +
  4. +
  5. +

    eBPF 2 3 4 5 6

    +
  6. +
  7. +

    Team IaaS call minutes

    +
  8. +
  9. +

    open vSwitch 2 3

    +
  10. +
  11. +

    IPsec 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

    +
  12. +
  13. +

    TripleO - OpenStack on OpenStack 2 3

    +
  14. +
  15. +

    Cillium 2 3 4 5 6

    +
  16. +
  17. +

    Tailscale

    +
  18. +
  19. +

    WireGuard 2 3 4

    +
  20. +
  21. +

    Open Virtual Network (OVN) 2 3 4 5 6 7 8 9 10

    +
  22. +
  23. +

    kolla project 2 3

    +
  24. +
  25. +

    kolla-ansible project 2 3

    +
  26. +
  27. +

    MACsec standard

    +
  28. +
  29. +

    Linux Kernel Crypto API

    +
  30. +
  31. +

    Internet Engineering Task Force (IETF)

    +
  32. +
  33. +

    Why is IPsec so complicated

    +
  34. +
  35. +

    WireGuard white paper

    +
  36. +
  37. +

    OVN IPsec tutorial

    +
  38. +
  39. +

    Neutron + Cilium architecture example

    +
  40. +
  41. +

    Neutron + Cilium Proposal

    +
  42. +
  43. +

    Calico 2

    +
  44. +
  45. +

    Calico for OpenStack

    +
  46. +
  47. +

    Libreswan VPN software 2 3 4

    +
  48. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0123-v1-mandatory-and-supported-IaaS-services/index.html b/standards/scs-0123-v1-mandatory-and-supported-IaaS-services/index.html new file mode 100644 index 0000000000..91d2b113ae --- /dev/null +++ b/standards/scs-0123-v1-mandatory-and-supported-IaaS-services/index.html @@ -0,0 +1,64 @@ + + + + + +Mandatory and Supported IaaS Services | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Mandatory and Supported IaaS Services

Introduction

+

To be SCS-compliant a Cloud Service Provider (CSP) has to fulfill all SCS standards. +Some of those standards are broad and consider all APIs of all services on the IaaS-Layer like the consideration of a role standard. +There exist many services on that layer and for a first step they need to be limited to have a clear scope for the standards and the Cloud Service Providers following them. +For this purpose, this standard will establish lists for mandatory services whose APIs have to be present in a SCS cloud as well as supported services, which APIs are considered by some standards and may even be tested for their integration but are optional in a sense that their omission will not violate SCS conformance.

+

Motivation

+

There are many OpenStack APIs and their corresponding services that can be deployed on the IaaS level. +These services have differences in the quality of their implementation and liveness and some of them may be easily omitted when creating an IaaS deployment. +To fulfill all SCS-provided standards only a subset of these APIs are required. +Some more but not all remaining OpenStack APIs are also supported additionally by the SCS project and may be part of its reference implementation. +This results in different levels of support for specific services. +This document will give readers insight about how the SCS classifies the OpenStack APIs accordingly. +If a cloud provides all mandatory and any number of supported OpenStack APIs, it can be tested for SCS-compliance. +Any unsupported APIs will not be tested.

+

Mandatory IaaS APIs

+

The following IaaS APIs MUST be present in SCS-compliant IaaS deployments and could be implemented with the corresponding OpenStack services:

+
Mandatory APIcorresponding OpenStack Servicedescription
block-storageCinderBlock Storage service
computeNovaCompute service
identityKeystoneIdentity service
imageGlanceImage service
load-balancerOctaviaLoad-balancer service
networkNeutronNetworking service
s3S3 API object storageObject Storage service
+
caution

S3 API implementations may differ in certain offered features. +CSPs must publicly describe the endpoints of their S3 solutions and which implementations they use in their deployment. +Users should always research whether a needed feature is supported in the offered implementation.

+

The endpoints of services MUST be findable through the catalog list of the identity API1.

+

Supported IaaS APIs

+

The following IaaS APIs MAY be present in SCS-compliant IaaS deployment, e.g. implemented thorugh the corresponding OpenStack services, and are considered in the SCS standards.

+
Supported APIcorresponding OpenStack Servicedescription
bare-metalIronicBare Metal provisioning service
billingCloudKittyRating/Billing service
dnsDesignateDNS service
haMasakariInstances High Availability service
key-managerBarbicanKey Manager service
object-storeSwiftObject Store with different possible backends
orchestrationHeatOrchestration service
shared-file-systemsManilaShared File Systems service
time-series-databaseGnocchiTime Series Database service
+

Unsupported IaaS APIs

+

All other OpenStack services, whose APIs are not mentioned in the mandatory or supported lists will not be tested for their compatibility and conformance in SCS clouds by the SCS community. +Those services MAY be integrated into IaaS deployments by a Cloud Service Provider on their own responsibility but SCS will not assume they are present and potential issues that occur during deployment or usage have to be handled by the CSP on their own accord. +The SCS standard offers no guarantees for compatibility or reliability of services categorized as unsupported.

+ +

The OpenStack Services

+

Conformance Tests

+

The presence of the mandatory OpenStack APIs will be tested in this test-script +The test will further check whether the object-store endpoint is compatible to s3.

+ +

Footnotes

+
    +
  1. +

    Integrate into the service catalog of Keystone

    +
  2. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0124-v1-security-of-iaas-service-software/index.html b/standards/scs-0124-v1-security-of-iaas-service-software/index.html new file mode 100644 index 0000000000..ca29a6a4ac --- /dev/null +++ b/standards/scs-0124-v1-security-of-iaas-service-software/index.html @@ -0,0 +1,120 @@ + + + + + +Standard for the security of IaaS service software | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Standard for the security of IaaS service software

Introduction

+

Software security relies on bug patches and security updates being available for specific versions of the software. +The services, which build the IaaS Layer should be updated on a regular basis based on updates provided by their respective authors or distributors. +But older releases or versions of the software of these services may not receive updates anymore. +Unpatched versions should not be used in deployments as they are a security risk, so this standard will define how CSPs should deal with software versions and security updates.

+

Terminology

+
TermExplanation
CSPCloud Service Provider, provider managing the OpenStack infrastructure.
SLURPSkip Level Upgrade Release Process - A Process that allows upgrades between two releases, while skipping the one in between them.
OSSNOpenStack Security Note - security issues from 3rd parties or due to misconfigurations.
OSSAOpenStack Security Advisories - security issues and advices for OpenStack.
+

Motivation

+

On the IaaS Layer the software, that needs to be considered in the scope of this standard, is mainly the APIs of IaaS Services. +Also there might be shared libraries and other dependencies, that could be considered part of the IaaS Layer. +In software projects like e.g. OpenStack that provide the main services and all APIs, the software will be modified and receive bug fixes continuously and will receive releases of new versions on a regular basis. +Older releases will at some point not receive updates anymore, because maintaining more and more releases simultaneously requires too much manpower. +Thus older versions will also eventually not receive security updates anymore. +Using versions which do not receive updates anymore threatens the baseline security of deployments and should be avoided under all circumstances.

+

Design Considerations

+

It would be possible to define a minimum version of IaaS Layer software to avoid security risks. +In the following paragraphs several options of defining a minimum version or dealing with security patches otherwise are discussed.

+

Options considered

+

Only Allow the current versions of Software

+

Considering that OpenStack as one provider of IaaS Layer Software has two releases per year, with one SLURP release per year, this option would require CSPs to update their deployment once or twice a year. +Updating a whole deployment is a lot of work and requires also good life-cycle management. +Following only the SLURP releases would reduce this work to once per year.

+

While following new releases closely already provides a deployment with recent bug fixes and new features, it also makes developing standards easier. +Differences between releases will accumulate eventually and may render older releases non-compliant to the SCS standards at some point.

+

On the other hand on the IaaS Level there aren't many breaking changes introduced by releases and also most standards will also work with older releases. +Security updates and bug fixes are also provided by OpenStack for a few older releases with the state maintained according to the OpenStack releases overview1. +Additionally the SCS reference implementation is integrating OpenStack releases after half a year - so about the time when a new release is published by OpenStack. +Considering a CSP that wants to use only SLURP releases and waits for the reference implementation to adopt them, will already lag over a year (i.e. 2 OpenStack releases) behind the latest release, this cannot be considered as using the current version of IaaS Layer Software. +Thus this option can be discarded.

+

Allow only maintained versions of Software

+

While following closely to the newest releases could be advised, there are several downsides to requiring this workflow, even if it would be only for SLURP releases. +Following the SCS reference implementation for example would also lead into being a little bit behind the newest OpenStack release. +But this is not as bad as it may seem to be, because security related fixes and bug fixes are backported to older but still maintained releases. +All releases that are still maintained can be looked up at the releases page from OpenStack1.

+

Allowing maintained versions would give CSPs a little bit more time to update and test their environments, while still receiving relevant security updates and bug fixes. +Also CSPs that want to become SCS-compliant will not have to take on the burden to upgrade their deployments to very recent releases immediately, but can instead test with an existing release before an upgrade and identify where they need to put in additional work to become SCS-compliant.

+

One problem is, that there might be new features implemented in the newest versions of the software, which are desired by other SCS standards to be SCS-compliant. +In that case allowing all maintained versions would lead to a two-year timespan customers would need to wait for before such a feature becomes available in all SCS-compliant deployments. +In case of security relevant features this is not advisable.

+

Standards implicitly define the minimum versions of Software

+

Instead of requiring a defined minimum software version centrally, it could be derived from the individual standards. +Because: Whenever there is a new wanted behavior a standard should be created and a resonable timeframe given to CSPs to adopt a software version that can fulfill the new standard. +Through the combination of all standards that are in place, the minimum version for the IaaS service software is implicitly given.

+

This would avoid to have conflicting versions of software in terms of feature parity, while also allowing older software. +Using this approach requires an additional advise to CSPs to update or implement patches for security issues.

+

Advise CSPs to integrate software updates

+

As long as maintained versions of software are used, updates with security patches are available and only need to be integrated. +This can and should be done in a reasonable short timeframe.

+

But CSPs may even use releases of IaaS software, that are either not maintained anymore by an open source community or may be even closed source implementations of the mandatory IaaS APIs. +Allowing older versions or closed source software would only be acceptable, when CSPs assure (e.g. in documentation), that they themself will patch the software within their deployments. +Security bug fixes must be implemented and proof of the fix then provided. +Only under these circumstances deployments with older or alternative IaaS Layer software may be handled as compliant.

+

This option could be taken for granted, but to actually advise using it may encourage CSPs to take a closer look on their life-cycle management and security risk handling. +And CSPs using OpenStack could even be encouraged to upgrade their deployments.

+

Dependencies of the IaaS Layer Software

+

While the IaaS service software like OpenStack itself is monitored and security issues announced in OSSNs and OSSAs, these services have lots of dependecies, that are not monitored by the same entity. +When dependencies have security issues, there might be no OSSN or OSSA, so CSPs also need to watch CVEs concerning these dependencies themselves. +Those dependencies must also be updated in a reasonable timeframe, when a security issue is disclosed.

+

What timeframe is needed to fix the issue?

+

CSPs should be encouraged to fix security issues as fast as possible. +Some security issues are very easy to exploit so as soon as the vulnerability is disclosed attacks on deployments will start. +Other vulnerabilities may need much knowledge and more time to be exploited. +Also the impact of different vulnerabilities will differ.

+

So it can be concluded that some security issues need to be fixed immediately while for others it is okay to take some time. +The BSI already has some guidance2 on how fast CSPs should respond. +From the moment a vulnerability is disclosed these are the advised reaction times ranked by the severity of the vulnerability:

+
    +
  1. Critical (CVSS = 9.0 – 10.0): 3 hours
  2. +
  3. High (CVSS = 7.0 – 8.9): 3 days
  4. +
  5. Mid (CVSS = 4.0 – 6.9): 1 month
  6. +
  7. Low (CVSS = 0.1 – 3.9): 3 months
  8. +
+

This standard will follow this guidance and refer to these timeframes as "reasonable timeframes".

+

Standard for a minimum IaaS Layer Software version

+

If a deployment is affected by a security issue and a maintained1 version of OpenStack is used as implementation for IaaS Layer software, security patches noted in OSSNs and OSSAs MUST be integrated within a reasonable timeframe according to the severity of the security issue2. +Otherwise the CSP MUST implement security bug fixes themself within a reasonable timeframe, when the deplyoment is affected by a security issue according to the severity of the security issue2.

+

In both cases a notice of the update MUST be send to the OSBA, so that the compliance will not be revoked.

+

If a deployment uses a dependency of the IaaS service software which is affected by a security issue, this software also MUST be updated with security patches within a reasonable timeframe2.

+

An open SBOM list MAY be used to propagate the current version of the software and may be used as proof of updates.

+

Conformance Tests

+

In case of provided SBOMs the version numbers of the software could be checked. +But this is not a requirement, so there cannot be such a test. +Tests on the integration of security patches itself are difficult. +And even if tests for certain security issues are possible, then those might be interpreted as an attack. +This is the reason there will be no conformance test.

+

Rather the standard requires that CSPs provide notice of the fixed vulnerabilites themselves.

+ +

Footnotes

+
    +
  1. +

    OpenStack versions and their current status 2 3

    +
  2. +
  3. +

    C5 criteria catalog with timeframes for responses on page 70. 2 3 4

    +
  4. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0124-w1-security-of-iaas-service-software/index.html b/standards/scs-0124-w1-security-of-iaas-service-software/index.html new file mode 100644 index 0000000000..07a2b6d8b9 --- /dev/null +++ b/standards/scs-0124-w1-security-of-iaas-service-software/index.html @@ -0,0 +1,58 @@ + + + + + +SCS Standard for the security of IaaS service software: Implementation and Testing Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS Standard for the security of IaaS service software: Implementation and Testing Notes

Testing or Detecting security updates in software

+

It is not always possible to automatically test, whether the software has the newest security updates. +This is because software versions may differ or some CSPs might have added downstream code parts or using other software than the reference. +Also vulnerabilites and their fixes are quite different in testing, some might not be testable while others are. +Additionally testing might be perceived as an attack on the infrastructure. +So this standard will rely on the work and information CSPs must provide. +There are different cases and procedures which are addressed in the following parts, that lead to compliance for this standard.

+

Procedure to become compliant to the security of IaaS service software Standard

+

This is the procedure when a new deployment wants to achieve SCS-conformancy. +There are two states such a deployment can be in:

+
    +
  1. +

    When a deployment is newly build or installed it usually uses software which includes all the latest security and bug fixes. +Such deployments should be considered compliant to the standard.

    +
  2. +
  3. +

    When a CSP wants to make an older deployment compliant to the SCS standards and thus also to this standard, it should be checked, whether the running software is up to date and all vulnerabilites are fixed. +Any updates or upgrades to even newer versions should be done before the SCS compliance for every other standard is checked. +Afterwards the CSP may provide information about the used software in an SBOM or otherwise should provide a notice about the deployment having integrated all necessary vulnerability patches.

    +
  4. +
+

Procedure when new vulnerabilites are discovered

+

Whenever there are new vulnerabilities discovered in IaaS service software like OpenStack there is either an internal discussion ongoing or it is just a smaller issue. +In the first case CSPs should have someone following such discussions and may even help preparing and testing patches. +From the moment on the vulnerability is disclosed publicly, the risk of it being actively exploited increases greatly. +So CSPs MUST watch out for announcements like in the OSSAs and OSSNs and when they are affected, update their deployment within the following timeframes according to the severity of the issue:

+
    +
  1. Critical (CVSS = 9.0 – 10.0): 3 hours
  2. +
  3. High (CVSS = 7.0 – 8.9): 3 days
  4. +
  5. Mid (CVSS = 4.0 – 6.9): 1 month
  6. +
  7. Low (CVSS = 0.1 – 3.9): 3 months
  8. +
+

Afterwards CSPs MUST provide a notice to the OSBA, that they are not or not anymore affected by the vulnerabilty. +This can be done through either telling, what patches were integrated or showing configuration that renders the attack impossible. +It could also be provided a list of services, when the affected service is not used in that deployment.

+ + \ No newline at end of file diff --git a/standards/scs-0125-v1-secure-connections/index.html b/standards/scs-0125-v1-secure-connections/index.html new file mode 100644 index 0000000000..15c52a0606 --- /dev/null +++ b/standards/scs-0125-v1-secure-connections/index.html @@ -0,0 +1,213 @@ + + + + + +Secure Connections | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Secure Connections

Introduction

+

A lot of internal and external connectivity is established to and within a cloud infrastructure. +Due to the nature of the IaaS approach, many communication channels may occasionally or even primarily carry potentially sensitive data of customers. +To protect this data from both tampering and unintended disclosure, communication channels need to be properly secured.

+

For this reason, the SCS project standardizes the use of common protection mechanisms for communication channels in OpenStack infrastructures.

+

Terminology

+
TermMeaning
CACertificate Authority
CSPCloud Service Provider, provider managing the OpenStack infrastructure
PKIPublic Key Infrastructure
SDNSoftware-Defined Networking
SSLSecure Sockets Layer, the predecessor of TLS
TLSTransport Layer Security
Compute HostSystem within the IaaS infrastructure that runs the hypervisor services and hosts virtual machines
+

Motivation

+

As mentioned above, a lot of communication channels in an OpenStack infrastructure carry data that is potentially sensitive. +For example this includes authentication data of customers and internal OpenStack configuration data such as encryption keys among others. +OpenStack does not generically mandate or preconfigure the use of specific protection mechanisms by itself and instead only makes recommendations about best practices in its offical Security Guide.

+

To address the potential lack of implementation of such mechanisms by a CSP and to establish a reliable foundation for communication data protection in SCS clouds, the SCS project formulates this standard for securing communication channels in the infrastructure, so that a customer can rely on adequate security mechanisms being in use.

+

Design Considerations

+

There are many internal communication channels in OpenStack with different characteristics, location and eligible means of protection. +Not all channels are equally easy to secure and some protection mechanisms might put unbearable burdens on a CSP. +Hence, careful assessment is required to determine for which the SCS standard will either mandate or recommend the use of a protection mechanism.

+

Note that this standard only focuses on security considerations for securing the Openstack API as well as inter-component connections, which a CSP has full control over on an infrastructure level. +This standard will not address the security of customer-deployed instances and services on top of OpenStack or other IaaS implementations.

+

For this distinction to be made, applicable communication channels must be categorized and classified accordingly.

+

Communication Channels

+

The following overview will classify the main communication channels.

+
#ClassificationDetailsExample solution
1OpenStack database backend trafficReplication and sync between database instances of the OpenStack services' databasesSSL/TLS
2OpenStack database frontend trafficCommunication between OpenStack services and their corresponding databasesSSL/TLS
3Message queue trafficMessage queue communication between OpenStack components as provided by oslo.messagingSSL/TLS
4External API communicationHTTP traffic to services registered as external endpoints in the Keystone service catalogSSL/TLS
5Internal API communicationHTTP traffic to services registered as internal endpoints in the Keystone service catalogSSL/TLS
6Nova VM migration trafficNova VM migration data transfer traffic between compute nodesQEMU-native TLS
7External Neutron network trafficVM-related traffic between the network/controller nodes and external networks (e.g. internet) established through routed provider networks and floating IPsVPN
8Internal Neutron network trafficTraffic within Neutron SDN networks exchanged between internal systems such as network/controller and compute nodesWireGuard
9Storage network frontend trafficTraffic exchanged between OpenStack and network storage backends (e.g. Ceph)N/A*
10Storage network replication trafficTraffic exchanged between individual storage nodes within the network storage backend for replication purposesN/A*
+

* The characteristics of the storage network traffic is highly specific to the individual storage backend and no generic solution can be stated here.

+

Notes about the classification categories and implications:

+
    +
  1. Most database clustering solutions (e.g. MariaDB Galera) offer TLS-based encryption of their backend channels. This needs no additional configuration in OpenStack and is a configuration solely concerning the database cluster.
  2. +
  3. The database frontend interface is the primary connection target for the OpenStack services. OpenStack supports using TLS for database connections.
  4. +
  5. For the message queue, AMQP-based solutions such as RabbitMQ and QPid do offer TLS natively which is also supported by OpenStack. ZeroMQ does not and requires WireGuard or CIPSO instead.
  6. +
  7. External API endpoints can be protected easily by using a TLS proxy. They can then be registered with their HTTPS endpoint in the Keystone service catalog. The certificates of external APIs usually need to be signed by a well-known CA in order to be accepted by arbitrary external clients.
  8. +
  9. Internal API endpoints can be treated and secured similarly to the external ones using a TLS proxy and adequate certificates.
  10. +
  11. For protecting the data transferred between compute nodes during live-migration of VMs, Nova offers support for QEMU-native TLS. As an alternative, SSH is also a channel that Nova can be configured to use between hosts for this but requires passwordless SSH keys with root access to all other compute nodes which in turn requires further hardening.
  12. +
  13. Neutron's external network traffic leaves the IaaS infrastructure. This part is twofold: connections initiated by the VMs themselves (egress) and connections reaching VMs from the outside (ingress). The CSP cannot influence the egress connections but can offer VPNaaS for the ingress direction.
  14. +
  15. Neutron's internal network traffic is one of the hardest aspects to address. Due to the highly dynamic nature of SDN, connection endpoints and relations are constantly changing. There is no holistic approach currently offered or recommended by OpenStack itself. Encrypted tunnels could be established between all involved nodes but would require a scalable solution and reliable key management. WireGuard could be considered a good starting point for this. A per-tenant/per-customer encryption remains very hard to establish this way though.
  16. +
  17. The available means of securing frontend storage communication are dependent on the protocol used for communication between OpenStack and the storage backend. Some storage solutions and protocols might offer authentication and encryption functionality by default but that cannot be assumed to be the case for every possible backend. Furthermore, storage is highly sensitive to latency and performance impacts imposed by such measures. Due to the fact that OpenStack's volume encryption functionality encrypts block storage data before it enters the storage network, an unsecured communication channel may be considered not as much of a problem here as it is for other channels*.
  18. +
  19. Storage network replication traffic is highly specific to the storage backend solution and its method of operation. For some backends this channel might not even exists, depending on their architecture. As such, in most cases it is up to the storage solution to provide adequate measures for protection of this channel. As with the frontend storage traffic, due to the possible at-rest encryption implemented by OpenStack, only already encrypted data is transferred here for some resources*.
  20. +
+

* Encryption of data implemented by OpenStack before it is passed to the storage backend currently only applies to block data of volumes that use an encrypted volume type. Other data (e.g. of unencrypted volumes, images) is transferred to and from the storage in plaintext.

+

libvirt Hypervisor Interface on Compute Nodes

+

Live migration of virtual machines between compute hosts requires communication between the hypervisor services of the involved hosts. +In OpenStack, the libvirt virtualization API is used to control the hypervisor on compute nodes as well as to enable the live migration communication. +This libvirt interface allows direct control of the hypervisor. +Besides control of virtual machines themselves, in OpenStack this also includes attaching and detaching volumes, setting or retrieving their encryption keys and controlling network attachments. +As such, severe risks are associated with unauthorized access to this interface as it can easily compromise sensitive data of arbitrary tenants if abused.

+

This is acknowledged in the OpenStack Security Note OSSN-0007, which recommends either configuring SASL and/or TLS for libvirt connections or utilizing the UNIX socket in combination with SSH.

+

The OpenStack kolla-ansible documentation on Nova libvirt connections state:

+
+

This should not be considered as providing a secure, encrypted channel, since the username/password SASL mechanisms available for TCP are no longer considered cryptographically secure.

+
+

This leaves only TLS or UNIX socket with SSH as viable options for securing the channel.

+

TLS for libvirt and live migration

+

Since the Stein release of OpenStack, Nova supports QEMU-native TLS which protects the migration data streams using TLS. +It requires to add LIBVIRTD_ARGS="--listen" to the QEMU configuration, which will lead to TLS being active on the libvirt interface per default (due to listen_tls defaulting to being enabled). +This protects data streams for migration as well as the hypervisor control channel data flow with TLS but does not restrict access. +Client certificates must be deployed additionally and libvirt configured accordingly[^4] in order to meaningfully restrict access to the interface as advised by the OSSN-0007 document, see restricting-access in Libvirt doc.

+

Local UNIX socket and SSH live migration

+

As an alternative to the TLS setup, libvirt can be configured to use a local UNIX socket and Nova can be configured to use SSH to this socket for live migrations instead. +The regular libvirt port can then be limited to localhost (127.0.0.1) which will make it inaccessible from outside the host but still enables local connections to use it. +The challenge of this approach lies in restricting the SSH access on the compute nodes appropriately to avoid full root access across compute nodes for the SSH user identity that Nova will use for live migration. +This can be addressed by restricting the command set that is available and the paths that are accessible to these target SSH user identities on compute nodes, limiting them to the scope strictly required by the live migration.

+

A basic setup for combining the UNIX socket with SSH live migration settings is illustrated below.

+

Libvirt configuration:

+
listen_tcp = 1
listen_addr = "127.0.0.1"
unix_sock_group = "libvirt"
unix_sock_ro_perms = "0770"
unix_sock_rw_perms = "0770"
+

Nova configuration:

+
[libvirt]
connection_uri=
live_migration_uri=qemu+ssh://...
live_migration_scheme = ssh

+

TLS Configuration Recommendations

+

Server-side TLS configuration is complex and involves a lot of choices for protocol versions, cipher suites and algorithms. +Determining and maintaining secure configuration guidelines for this is non-trivial for a community project as it requires a high level security expertise and consistent evaluation. +For this reason, the standard should reference widely accepted best practices and established third party guidelines instead of creating and maintaining its own set of rules.

+

Mozilla publishes and maintains TLS recommendations and corresponding presets for configuration and testing. +Considering Mozilla's well-established name in the internet and open source communities, this could qualify as a good basis for the standard concerning the TLS configurations.

+

Storage network protection

+

As stated in the overview of communication channels, the existence and characteristics of the storage frontend and replication networks are highly specific to the storage backend solution in use. +In conjunction with the fact that storage performance is easily impacted by anything that introduces latency or reduces throughput on these channels, there is no easy recommendation on how to secure them that can be made here.

+

This is partially mitigated by OpenStack's ability to encrypt storage data before it enters the storage backend, protecting the data regardless of the storage channels characteristics. +But this only applies to block data of volumes that use an encrypted volume type and does not apply to other data put into the storage backend by OpenStack, for example images. +As such, this does not fully address unsecured storage channels.

+

However, requiring the network storage channels to be dedicated physical connections separate from the other channels like tenant VM traffic or API communication can increase both the reliability as well as security of the storage connections. +Therefore this standard should at least recommend a dedicated network infrastructure to be implemented for the storage if network storage backends are used, such as Ceph.

+

Options considered

+

Option 1: fully mandate securing all channels without differentiation

+

This option would reach the highest security standard and establish protection on all identified communication channels simultaneously. +However, this would burden CSPs greatly due to the difficulty of addressing some of the channels and properly maintaining the solution. +Also there is a risk of making this incompatible with existing infrastructures due to some of their specifics being mutually exclusive to the more intricate protection mechanisms such as cross-node WireGuard configurations. +As a third aspect, not all mechanisms might fulfill the CSPs requirements regarding performance and stability and the SCS standard cannot in good faith force CSPs to use technologies not suited to their infrastructures.

+

This seems like a bad option from many perspectives. +It also allows very little flexibility and might even make SCS conformance unappealing to CSPs due to the immense effort required to reach it.

+

Option 2: only make recommendations

+

This option would limit the SCS project to only recommend mechanisms in this standard like presented in the OpenStack Security Guide. +Although this can increase awareness about the best practices recommended by OpenStack and maybe encourage CSPs to abide by them, it would actually contribute very little to the security baseline of SCS infrastructures as a whole since everything would stay optional.

+

This option would be very easy to standardize and get consensus on due to its lightweight and optional nature. +However, the actual added value for SCS is questionable at best.

+

Option 3: mix recommendations and obligations

+

This option forms a middle ground between options 1 and 2. +For this, the standard needs to carefully assess each communication channel, mechanisms for protecting it and the effort required to do so as well as the implications. +Then, only for mechanisms that are known to be reliable, are feasible to implement and for which the benefits clearly outweigh the integration effort required, should this standard enforce their implementation in a permissive way. +For any remaining mechanisms the SCS standard should only make recommendations and refer to known best practices where applicable.

+

This option would still offer improvements over arbitrary OpenStack clouds by establishing a baseline that goes beyond mere recommendations while still taking into account that not all communication channels are equally easy to secure and allowing necessary flexibility for the CSP.

+

Open questions

+

Choosing the best protection mechanism for the libvirt hypervisor interface

+

As described in the Design Considerations section, there are multiple ways of securing the libvirt interface and live migration channels using TLS or SSH mechanisms. +Upon closer inspection, this consists of two problems to address:

+
    +
  1. encrypting migration traffic utilizing the libvirt interface itself
  2. +
  3. identifying/authenticating connecting clients and properly restricting their permission set
  4. +
+

When considering problem no. 1 in an isolated fashion, the QEMU-native TLS approach could be considered preferable simply due to it being officially recommended and documented by upstream OpenStack and tightly integrated into QEMU.

+

However, once problem no. 2 is taken into account, the choice does not seem as obvious anymore due to the fact that in order to properly authenticate clients in the TLS case, X.509 client certificate authentication along with a corresponding PKI as well as key management would be required. +Although similar aspects would be relevant for the SSH approach where SSH key and identity management as well as proper permission restriction would need to be implemented, the SSH approach could turn out less complex due to the fact that the foundation for SSH identities most likely already exists on a node-level and does not need to rely on a full PKI.

+

To properly compare both possible approaches of securing the libvirt interface, extensive testing and evaulation would be necessary along with a sophisticated key and node identity management for compute nodes which this standard alone does not provide.

+

Verifying standard conformance for internal mechanisms

+

Most of the mentioned communication channels to be secured are part of the internal IaaS infrastructure of a SCS cloud. +When an internal protection mechanism is implemented by the CSP it cannot be verified from outside of the infrastructure without administrative access to the infrastructure.

+

Thus, the SCS community is unable to fully assess a CSPs conformance to this standard without a dedicated audit of the infrastructure.

+

Standard

+

This standard will mandate or recommend appropriate measures for securing the communication channels based on existing standards and recommendations. +It will reference documents like the OpenStack Security Guide where applicable.

+

Transport Layer Security (TLS)

+ +

API Interfaces

+
    +
  • Internal API endpoints of all OpenStack services MUST use TLS. Their endpoint as registered in the Keystone service catalog MUST be an HTTPS address.
  • +
  • External API endpoints of all OpenStack services MUST use TLS. Their endpoint as registered in the Keystone service catalog MUST be an HTTPS address.
  • +
+

You MAY refer to TLS proxies and HTTP services and Secure reference architectures of the OpenStack Security Guide for best practices and recommendations.

+

Database Connections

+ +

Message Queue Connections

+ +

Hypervisor and Live Migration Connections

+
    +
  • The live migration connections between compute nodes SHOULD be secured by encryption. +
      +
    • If QEMU and libvirt are used, QEMU-native TLS is an approach officially documented by OpenStack. See Secure live migration with QEMU-native TLS. As an alternative, SSH-based live migration MAY be configured instead.
    • +
    +
  • +
  • If using libvirt as the hypervisor interface on compute nodes the libvirt port (as per its listen_addr configuration option) SHOULD NOT be exposed to the network in an unauthenticated and unprotected fashion: +
      +
    • For the QEMU-native TLS configuration, it is RECOMMENDED to enforce TLS client certificate authentication and assign corresponding client identities to connecting compute nodes.
    • +
    • For the SSH-based live migration approach, it is RECOMMENDED to limit the libvirt port/socket to the local host and establish SSH key pairs for compute nodes in conjunction with restricted SSH permissions.
    • +
    +
  • +
+

See the corresponding Design Considerations section for more details about the mentioned approaches.

+

External VM Connections

+
    +
  • As an OPTIONAL measure to assist customers in protecting external connections to their OpenStack networks and VMs, the infrastructure MAY provide VPNaaS solutions to users. +
      +
    • For example the Neutron VPNaaS service MAY be integrated into the infrastructure with the Neutron VPNaaS API extension enabled. See the Neutron VPNaaS documentation.
    • +
    +
  • +
+

Internal Neutron Connections

+
    +
  • As an OPTIONAL measure to protect Neutron SDN traffic between physical nodes within the infrastructure, encrypted tunnels MAY be established between nodes involved in Neutron networks, such as compute and network controller nodes, at the network interfaces configured in Neutron (e.g. via WireGuard or similar solutions).
  • +
+

Storage Connections

+
    +
  • For storage backends that are connected to OpenStack over the network, the network connections between the OpenStack components and the storage backend SHOULD be located on a separate physical network with dedicated interfaces at the involved nodes.
  • +
  • For storage backends that transfer replication data between individual storage nodes, the connections between those nodes SHOULD be implemented by a dedicated physical network.
  • +
  • Where applicable, storage traffic between OpenStack components and the storage backend (frontend traffic) as well as storage replication traffic between storage nodes themselves (backend traffic) MAY be encrypted using the storage protocols native security features (if any) or a generic solution such as WireGuard.
  • +
+ + +

Conformance Tests

+

Conformance tests are limited to communication channels exposed to users, such as the public API interfaces. +Internal channels and APIs are currently not part of the automated conformance tests because they are not exposed and cannot be audited without direct access to the infrastructure.

+

There is a test suite in tls-checker.py. +The test suite connects to the OpenStack API and retrieves all public API endpoints from the service catalog. +It then connects to each endpoint and verifies the compliance to the standard by checking SSL/TLS properties against the Mozilla TLS preset. +Please consult the associated README.md for detailed setup and testing instructions.

+ + \ No newline at end of file diff --git a/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests/index.html b/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests/index.html new file mode 100644 index 0000000000..1b4e8722e1 --- /dev/null +++ b/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests/index.html @@ -0,0 +1,207 @@ + + + + + +Using Sonobuoy for KaaS conformance tests | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Using Sonobuoy for KaaS conformance tests

Motivation

+

With the k8s-cluster-api-provider, the SCS provides a tool to generate +and manage k8s clusters on top of its IaaS infrastructure. As part of +the application, Sonobuoy is used as a test suite to execute the +official Kubernetes e2e tests. +We expect that current and future tests derived from SCS standards +will benefit from (or even require) the testing mechanisms that Sonobuoy provides.

+

Apart from running the Kubernetes e2e tests, Sonobuoy also allows users to write +their own tests and apply them as a self-managed plugin. +All tests not provided by the e2e test plugin could therefore +be written by the respective SCS teams responsible for the standards or tests and +then be made executable with Sonobuoy. Hence, Sonobuoy could provide both a pre-done +test suite and a framework to write additional conformance tests required for SCS.

+

Short Sonobuoy Introduction

+

The main objective of Sonobuoy plugins is to present test +results in a consolidated way. To do this, Sonobuoy integrates the test into a pod, +which is then applied to the K8s cluster under test. A Sonobuoy worker supervises +this pod and forwards all test results to the aggregator module. It does this by +waiting for a specific "Done" file to be created. Once this file is recognized, +the worker forwards the results to the aggregator, using a predefined location +for the results file within a folder, as seen in following image: +image search api

+

In order to use the existing conformance tests as a Sonobuoy plugin, a wrapper +around the individual test scripts would be required. This wrapper would need to +have the following effects:

+
    +
  • gathers all test results and provides them in the results file
  • +
  • run tests in sequence and signal the worker when it's finished by generating a "Done" file
  • +
+

Apart from providing the test results, a plugin container must also forward the +status of each test by setting a status flag in the results file. +Additionally, the tests would need to be able to run inside a pod in the K8s cluster under test.

+

Design Considerations

+

There are different approaches to create a Sonobuoy plugin, which are discussed +below in order to find a best practice for the SCS project. The documented approaches +show one example each in order to give a better representation to the reader.

+

Sonobuoy provides plugin examples in the plugins repository, +which are referenced throughout this section.

+

Option 1 Golang based approach 1: Pick a framework from the Sonobuoy plugin examples

+

The seemingly most interesting plugin is the e2e-skeleton, which uses +the kubernetes-sigs/e2e-framework. The kubernetes-sigs/e2e-framework +is a stand-alone project that is separate from the official Kubernetes e2e tests. +The framework provides proper documentation as well as helper functions that abstract +client functionalities, similar to those found in "kubernetes/kubernetes/test/e2e/framework" repository.

+

As mentioned in the motivation of the e2e-framework, +the project was created to circumvent the disadvantages of Kubernetes' own e2e-tests, +which are described in more detail in the goals.

+

PROS:

+
    +
  • arguments in favor of this framework can also be found under the goals description of the documentation
  • +
  • e2e-framework is a well-defined framework, that allows the handling of resource creation and deletion
  • +
  • official framework provided by "Kubernetes-sigs"
  • +
+

CONS:

+
    +
  • arguments not in favor of this framework can be derived from the Non-Goals description of the documentation: +
      +
    • "no responsibility for bootstrapping or the execution of the tests themselves" can be ignored, as this is partly taken over by Sonobuoy
    • +
    • "no mock or fake cluster components" can be ignored, since the e2e tests of SCS should be used to test real clusters and their functionality
    • +
    • for this test procedure, the Sonobuoy e2e plugin should be run in addition to the SCS KaaS conformance tests
    • +
    +
  • +
+
+

proof of concept: ../Tests/kaas/kaas-sonobuoy-go-example-e2e-framework/

+
+

Option 2 Golang based approach 2: Reuse the Kubernetes own e2e test infrastructure and framework

+

The existing Sonobuoy e2e plugin already provides a vast number of tests that could +be adapted or reused for the SCS project.

+

If these e2e tests are to be reused in a customized structure, a framework like ginkgo +must be used as it is used by the Kubernetes e2e test infrastructure. +This could use the implementation of the build process responsible for the Docker +image containing the e2e tests. The setup could be copied from kubernetes/test/conformance/image +and adapted to the projects requirements. The mentioned build process must use the +files of the following directories from the Kubernetes repository:

+ +

PROS:

+ +

CONS:

+
    +
  • not easy to implement, as we would have to copy part of the Kubernetes repository and track the changes from the upstream
  • +
  • according to README.md, part of it seems to be outdated and might change with a future version + +
  • +
+
+

TODO: provide proof of concept: kaas-sonobuoy-go-example-k8s-e2e

+
+

Option 3 Write Python scripts for tests

+

Sonobuoy makes it possible to write tests in Python and execute them like other +tests in a pod on the K8s cluster. It would therefore be possible to keep on writing +conformance tests in Python.

+

This option would require a wrapper in order to make the tests scripts executable +as Sonobuoy plugins. This wrapper, as mentioned earlier, would need to capture +the collection of test results as well as the generation of the "Done" file after +the test execution is finished. This could be managed by executing each test script +in a sequential order.

+

The wrapper as well as the python tests and test framework could then be stored +in a container image and uploaded to a registry in order to be usable by Sonobuoy +within the k8s-cluster-api-provider.

+

This approach also leaves the decision open as to which test framework should be +used for Python, which should be decided in a secondary Decision Record.

+
+

proof of work: ../Tests/kaas/k8s-default-storage-class

+
+

PROS:

+
    +
  • continue using the already available Python tests +
      +
    • only a small number of tests is implemented thus far
    • +
    +
  • +
+

CONS:

+
    +
  • no "native" support in Sonobuoy, a wrapper is needed
  • +
  • decision for a framework is still not done
  • +
+

Approaches to providing a Sonobuoy plugin image

+

The following section showcases both ways to provide a Sonobuoy plugin image. +Option 1 would most likely be used, if an image is published to be used by an end user. +Option 2 is the expected way for local development and testing.

+

Option 1 Public container registry

+

The image can be made available via a public container registry, which would require +a regular job (e.g. CI/CD) to build and publish the image.

+

Option 2 Local image upload

+

Create the image locally on the "clusterctl admin control node" and then upload +it manually to the Kubernetes cluster under test.

+

Both approaches are useful in different ways. While the usage of a container registry +allows easy distribution of tests and guarantees new images through the usage of a +CI/CD job, it also makes it harder to test changes quickly, since a wait time could be +necessary to let the CI/CD job run through and access the image. This can be solved +by using the "Local image upload" or a combination of both approaches.

+

Decision

+

The KaaS conformance test MUST be provided as a test suite holding the +test cases for the Kubernetes clusters to be checked. +Furthermore, the test cases themselves MUST be wrapped by a test framework to:

+
    +
  • handle the creation and deletion of resources
  • +
  • collect and present results
  • +
  • consolidate redundant code across test cases
  • +
  • support the creation of test cases through predefined structures
  • +
+

As with the k8s-cluster-api-provider the SCS provides a tooling to generate +its KaaS infrastructure. Part of the k8s-cluster-api-provider is the usage +of Sonobuoy as a test suite to execute the Kubernetes own e2e tests. +Investigating those e2e test lead to the conclusion that they are not always reusable. +The main purpose of Kubernetes own e2e tests is to test the functionality of +the Kubernetes code itself and not the resources and setup of a specific KaaS infrastructure +as it is the aim of the SCS KaaS conformance test.

+

However, considering that the SCS has an ongoing process of defining standards and +implementing test cases to check their compliance, that means in some cases future standards +might already be covered by the e2e test inside the Kubernetes repository. +Hence, before writing tests, a developer SHOULD check the Kubernetes e2e tests for +existing test cases that might cover conformance of a standard currently being worked on.

+

As described above, Sonobuoy offers the possibility to generate custom plugins +that provide self-created test cases. Therefore, future conformance tests MUST +be executable by Sonobuoy by wrapping them in a Sonobuoy plugin. +Moreover, three options for the implementation of the SCS KaaS compliance test +cases are described above so that it can be decided within this decision record which +options should be used.

+

As a first decision, "Option 2 Go Approach 2: Reuse Kubernetes' own e2e test infrastructure and framework" +is the least viable, as it would mean copying almost all the files used from +the Kubernetes e2e tests. This framework is closely linked to the development of +the Kubernetes code. Therefore, changes to its structure mainly are in line with its usage +in the Kubernetes repository itself and is most likely not relevant for other parties. +Changes in the framework cloud have a greater impact on our side as they are +predictable. The development effort gained by reusing these examples could be +outweighed by the investment necessary to adapt tests to the corresponding framework changes.

+

This leaves "Option 1 Go approach 1: Pick framework from the Sonobuoy plugin examples" +and "Option 3 Write Python scripts for tests" as methods for implementing test cases. +It is possible to use both approaches in parallel, which would enable usage of both Python +and Go code. This could possibly generate two Sonobuoy plugins, but this isn't a necessity.

+ + \ No newline at end of file diff --git a/standards/scs-0210-v1-k8s-new-version-policy/index.html b/standards/scs-0210-v1-k8s-new-version-policy/index.html new file mode 100644 index 0000000000..33dc422c20 --- /dev/null +++ b/standards/scs-0210-v1-k8s-new-version-policy/index.html @@ -0,0 +1,66 @@ + + + + + +SCS K8S Version Policy for new Kubernetes versions | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS K8S Version Policy for new Kubernetes versions

Introduction

+

Here we will describe how fast providers need to keep up with the upstream Kubernetes version.

+

To create an informed decision we summarize here the Kubernetes rules regarding versioning at the time of writing (2023-01-16):

+

Kubernetes usually provides about 3 minor releases per year (see Kubernetes Release Cycle).

+

Patch release cadence is typically monthly. However, the first patches after the first minor release usually arrive 1-2 weeks after the first minor release +(see Patch Release Cadence).

+

As stated in Kubernetes Support Period, in general the latest 3 minor versions are maintained by the Kubernetes project. +Every release will be maintained for about 14 months. +The first 12 months are the standard support period. +The remaining 2 months are only for:

+
    +
  • CVEs (under the advisement of the Security Response Committee)
  • +
  • dependency issues (including base image updates)
  • +
  • critical core component issues
  • +
+

Motivation

+

Kubernetes is a fast-paced project. +We want to achieve that providers keep up to date with upstream and do not fall behind Kubernetes releases. +This ensures that users are able to upgrade their clusters to address security issues, bug fixes and new features when using SCS compliant clusters in regard to Kubernetes. +However, providers should have reasonable time to implement the new Kubernetes versions and test them.

+

Decision

+
    +
  • Must provide latest minor version no later than 4 months after release
  • +
  • Must provide latest patch version no later than a week after release
  • +
  • Should be faster for critical CVEs (CVSS >= 8)
  • +
  • Should be tested
  • +
+ +

All important documents regarding versioning, releases, etc. for the official Kubernetes project can be found on the Kubernetes Releases page.

+

Conformance Tests

+

The conformance test is written in the 'k8s-version-recency-check.py' script. The script requires the path to a valid +kubeconfig file, which should describe the k8s cluster under test. This can either be done by creating a config from +the also provided 'config.yaml.template' or by calling the test script with its cli arguments.

+ + \ No newline at end of file diff --git a/standards/scs-0210-v2-k8s-version-policy/index.html b/standards/scs-0210-v2-k8s-version-policy/index.html new file mode 100644 index 0000000000..7b6b0b85e3 --- /dev/null +++ b/standards/scs-0210-v2-k8s-version-policy/index.html @@ -0,0 +1,92 @@ + + + + + +SCS K8S Version Policy | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS K8S Version Policy

Introduction

+

The Kubernetes project maintains multiple release versions including their patched versions. +In the project, the three most recent minor releases are actively maintained, with a fourth +version being in development. As soon as a new minor version is officially released, +the oldest version is dropped out of the support period. +Kubernetes supports its releases for around 14 months. 12 of these are the standard +support period. The remaining 2 months are the end-of-life support period for things like:

+
    +
  • CVEs (under the advisement of the Security Response Committee)
  • +
  • dependency issues (including base image updates)
  • +
  • critical core component issues
  • +
+

More information can be found under [Kubernetes Support Period].

+

The Kubernetes release cycle is set around 4 months, which +usually results in about 3 minor releases per year.

+

Patches to these releases are provided monthly, except for the first patch, +which is usually provided 1-2 weeks after the initial release (see Patch Release +Cadence).

+

Motivation

+

Kubernetes is a living, fast-paced project, which follows a pre-defined release cycle. +This enables forward planning with regard to releases and patches, but also implies a +necessity to upgrade to newer versions quickly, since these often include new features, +important security updates or especially if a previous version falls out of the support +period window.

+

We want to achieve an up-to-date policy, meaning that providers should be mostly in +sync with the upstream and don't fall behind the official Kubernetes releases. +This is achievable, since new versions are released periodical on a well communicated +schedule, enabling providers and users to set up processes around it. +Being up-to-date ensures that security issues and bugs are addressed and new features +are made available when using SCS compliant clusters.

+

It is nevertheless important to at least support all Kubernetes versions that are still +inside the support period, since users could depend on specific versions or may need +longer to upgrade their workloads to a newer version.

+

The standard therefore should provide a version recency policy as well as a support +window period.

+

Decision

+

In order to keep up-to-date with the latest Kubernetes features, bug fixes and security improvements, +the provided Kubernetes versions should be kept up-to-date with new upstream releases:

+
    +
  • The latest minor version MUST be provided no later than 4 months after release.
  • +
  • The latest patch version MUST be provided no later than 2 weeks after release.
  • +
  • This time period MUST be even shorter for patches that fix critical CVEs. +In this context, a critical CVE is a CVE with a CVSS base score >= 8 according +to the CVSS version used in the original CVE record (e.g., CVSSv3.1). +It is RECOMMENDED to provide a new patch version in a 2-day time period after their release.
  • +
  • New versions MUST be tested before being rolled out on productive infrastructure; +at least the CNCF E2E tests should be passed beforehand.
  • +
+

At the same time, providers must support Kubernetes versions at least as long as the +official sources as described in Kubernetes Support Period:

+
    +
  • Kubernetes versions MUST be supported as long as the official sources support them +according to the Kubernetes Support Period and their end-of-life +date according to the Kubernetes Releases page.
  • +
  • It is RECOMMENDED to not support versions after this period in order to not encourage +usage of out-of-date versions.
  • +
+ +

All documents regarding versioning, releases, etc. for the official Kubernetes projects can +be found on the Kubernetes Releases page.

+

Conformance Tests

+

The script k8s_version_policy.py requires a kubeconfig file with connection details for +a set of existing Kubernetes clusters that should be checked, with each of these clusters +representing one of the currently supported upstream Kubernetes releases. +It will check the encountered cluster versions according to the rules of this standard. +Rule violations will be reported on various logging channels: ERROR for mandatory rules +and INFO for recommended rules. +The script will exit with a non-zero status if a mandatory rule has been violated or if +the test could not be performed.

+ + \ No newline at end of file diff --git a/standards/scs-0210-w1-k8s-version-policy-implementation-testing/index.html b/standards/scs-0210-w1-k8s-version-policy-implementation-testing/index.html new file mode 100644 index 0000000000..d836fed4c3 --- /dev/null +++ b/standards/scs-0210-w1-k8s-version-policy-implementation-testing/index.html @@ -0,0 +1,41 @@ + + + + + +SCS K8S Version Policy: Implementation and Testing Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS K8S Version Policy: Implementation and Testing Notes

Implementation notes

+

The standard is quite concise about the regulations, +so they are not restated here. Suffice it to say that a +CSP must make new versions for their KaaS offering available in a timely fashion, so that +new versions are available in a short window of time. +Older versions need to be supported until the end of their support window.

+

Concrete implementation details can't be given here, since not every CSP does provide +their versions the same way. The best advice to give is to monitor the +Kubernetes releases page closely.

+

Automated tests

+

Implementation

+

The script k8s_version_policy.py +connects to an existing K8s cluster and checks the version against a list of versions, that +are calculated to be inside a recency window.

+

Note that this implementation is subject to change, because testing an existing cluster is not +sufficient to guarantee that all active k8s branches are supported and kept up to date.

+

Manual tests

+

None.

+ + \ No newline at end of file diff --git a/standards/scs-0211-v1-kaas-default-storage-class/index.html b/standards/scs-0211-v1-kaas-default-storage-class/index.html new file mode 100644 index 0000000000..99a45a3ad6 --- /dev/null +++ b/standards/scs-0211-v1-kaas-default-storage-class/index.html @@ -0,0 +1,70 @@ + + + + + +SCS KaaS default storage class | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS KaaS default storage class

Introduction

+

Cluster consumers can request persistent storage via PersistentVolumeClaims which is provisioned automatically by cloud-provided automation. +Storage requirements may vary across use cases, so there is the concept of StorageClasses. StorageClasses define some set of storage properties. So, consumers can choose one of these depending on the use case.

+

Kubernetes documentation

+

Motivation

+

While often times, consumers will choose a StorageClass explicitly, usually, there is also a default StorageClass to fall back on in case it is not chosen explicitly (that is, when storageClassName is not set on the PersistentVolumeClaim).

+

This document attempts to define the properties this default StorageClass should have.

+

Decision

+

The default StorageClass is made default using the storageclass.kubernetes.io/is-default-class annotation, following Kubernetes upstream. Hence, standardizing its name is not required for the intents of this standard.

+ +
    +
  • ReadWriteOnce must be a supported access mode
  • +
  • volume must be protected against data loss due to hardware failures of a single disk or host
  • +
  • volume must not be bound to the lifecycle of a Kubernetes Node
  • +
+

Hence,

+
    +
  • ...volume must not be backed by local storage on the Kubernetes Node VM itself
  • +
  • ...volume may be backed by some kind of redundant storage within an AZ, across hosts
  • +
  • ...volume may be backed by some kind of redundant storage across AZ's
  • +
+ +
    +
  • NO fixed guarantees regarding latency/bandwidth/IOPS/...
  • +
+

Generally, customers should be able to expect low-tier performance without pricing surprises.

+ +

This document does not describe performance related properties. +This will be done in another document which is yet to be created.

+

Conformance Tests

+

The script k8s-default-storage-class-check.py requires a kubeconfig file with connection +details for the Kubernetes cluster that should be checked for conformance. +It will check for a default storage class and use the associated storage provider to +try to create and mount a PersistentVolumeClaim with the aforementioned properties to +a container in a Pod. +After it is done, it cleans up the resources. +Rule violations will be reported on various logging channels: ERROR for mandatory rules +and INFO for recommended rules. +An exit code of zero indicates that the standard has been met.

+ + \ No newline at end of file diff --git a/standards/scs-0211-v2-kaas-default-storage-class/index.html b/standards/scs-0211-v2-kaas-default-storage-class/index.html new file mode 100644 index 0000000000..1a90f9c17c --- /dev/null +++ b/standards/scs-0211-v2-kaas-default-storage-class/index.html @@ -0,0 +1,68 @@ + + + + + +SCS KaaS default storage class | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS KaaS default storage class

Introduction

+

This is the standard v2 for SCS Release 7.

+

Cluster consumers can request persistent storage via PersistentVolumeClaims, which is provisioned +automatically by cloud-provided automation. +Storage requirements may vary across use cases, so there is the concept of storage classes (StorageClass). +Storage classes define some set of storage properties and consumers can choose one of these depending on the use case.

+

Motivation

+

A lot of third-party software, such as Helm charts, assume that a default storage class is configured. +Thus, for an out-of-the-box working experience, a SCS compliant Kubernetes cluster should come +preconfigured with a sensible default storage class providing persistent storage.

+

Decision

+

A freshly provisioned Kubernetes cluster MUST have a default storage class, i.e., a StorageClass +object that is annotated with storageclass.kubernetes.io/is-default-class=true as described in the +Kubernetes documentation. +The name of this storage class is not standardized.

+ +

The following recommendations are not completely tested yet and therefore do not represent hard requirement criteria so far. Nevertheless, they are important prerequisites for ensuring data storage stability. Generally, these criteria are met by choosing the right provisioner such as Cinder CSI Provisioner. And this shall be cross-checked against a list of provisioners.

+

If the persistent volumes (PV) provisioned by the provided default storage class are required to be failure-safe they MUST fulfill all +of the following properties:

+
    +
  • MUST support the ReadWriteOnce access mode.
  • +
  • MUST NOT be bound to the lifecycle of a Kubernetes node.
  • +
  • MUST NOT be backed by local or ephemeral storage.
    +This means: +
      +
    • MUST NOT be backed by local storage on the Kubernetes Node VM itself.
    • +
    • MAY be backed by some kind of redundant storage within an AZ, across hosts.
    • +
    • MAY be backed by some kind of redundant storage across AZ's.
    • +
    +
  • +
+

Volumes that are not necessarily required to be failure-safe may be local/node-bound/non-redundant. This might be the case with fast to run applications that take care of data durability and availability on application level.

+

The provisioned storage class MAY support volume expansion (allowVolumeExpansion=true).

+ +
    +
  • NO fixed guarantees regarding latency/bandwidth/IOPS/etc. +Generally, customers should be able to expect low-tier performance without pricing surprises.
  • +
+

Previous standard versions

+

Version v1 of this standard did not enforce the +existence of a default storage class in a newly created cluster.

+

Conformance Tests

+

Is currently under progress stage: pull-request.

+ + \ No newline at end of file diff --git a/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing/index.html b/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing/index.html new file mode 100644 index 0000000000..d60ef3416a --- /dev/null +++ b/standards/scs-0211-w1-kaas-default-storage-class-implementation-testing/index.html @@ -0,0 +1,44 @@ + + + + + +SCS KaaS default storage class: Implementation and Testing Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

SCS KaaS default storage class: Implementation and Testing Notes

Implementation notes

+

A StorageClass is made default by using the storageclass.kubernetes.io/is-default-class +annotation; a standardized name is not given. ReadWriteOnce must be supported by the volume, +and it must be protected against data loss due to hardware failures. +Therefore, volumes must not be bound to the lifecycle of a Kubernetes node and, at best, +be backed by some kind of redundant storage. +Guarantees for latency, bandwidth, IOPS and so on are not given.

+

The cost-intensive part of this standard would be the hardware failure protection by binding +the StorageClass to redundant, non-lifecycle bound storage, since this would mean that +storage needs to be provided in a higher capacity to achieve the same usable capacity.

+

Automated tests

+

Notes

+

The test for the SCS Kaas Default storage class +checks if a default storage class is available and if this storage class can be used +to create a PersistentVolume from a PersistentVolumeClaim for a container.

+

Implementation

+

The script k8s-default-storage-class-check.py +connects to an existing K8s cluster and checks for the availability of a default storage class. +This can also be done via Sonobuoy.

+

Manual tests

+

None.

+ + \ No newline at end of file diff --git a/standards/scs-0212-v1-requirements-for-container-registries/index.html b/standards/scs-0212-v1-requirements-for-container-registries/index.html new file mode 100644 index 0000000000..3a7a95803d --- /dev/null +++ b/standards/scs-0212-v1-requirements-for-container-registries/index.html @@ -0,0 +1,186 @@ + + + + + +Requirements for container registries | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Requirements for container registries

Introduction

+

A container registry is an infrastructure service to enable storing and accessing container +images. Images can be pushed to the registry by e.g. Continuous integration pipelines and +be pulled from by runtime environments like Kubernetes clusters.

+

Container registries come in various forms, e.g. publicly accessible ones like Docker Hub or +self-hosted and cloud-hosted services. The latter examples may apply various access control +mechanisms to restrict access. Both solutions offer a wide range of features that may or may not +attract potential users and CSPs.

+

Terminology

+

Cloud Service Provider (abbr. CSP) +Entity that provides scalable computing resources

+

Identity Provider (abbr. IdP) +System that creates, maintains, and manages identity information

+

Motivation

+

This standard is motivated by different use cases identified through the topics in the SCS project. +One use case would be the offering of private registries for customers by CSPs, which means that a CSP could +offer private container registries either as a service or as a provided "recipe" to deploy a private registry +utilizing the CSPs infrastructure. +Another use case would be the selection of a registry for the SCS reference implementation.

+

The idea and purpose of this document is to specify what requirements a specific technical container +registry implementation (i.e. software solution) needs to fulfill for an SCS-compliant registry.

+

Design considerations

+

There are numerous features that should be evaluated for a container registry solution. +It is important to assess the registries based on the requirements of the OSS health checks and +desired features defined by the SCS. The following two subsections show these requirements.

+

OSS health check

+

It is important to evaluate the health of a project before even evaluating the project for its feature set. +A project should therefore fulfill all OSS health checks be defined by the +OSS-Health document. +This document evaluates the health of the open-source projects that were selected from +the currently available solutions. The container registry software must fulfill all OSS +health checks defined below:

+
    +
  • Four Opens (code is fully open source, community is open and diverse, development process is open, design process is open)
  • +
  • Maturity
  • +
  • Security
  • +
  • Activity
  • +
  • Lock-in risk assessment
  • +
+

Required and desirable features check

+

A container registry provides a specific feature set, which can be mapped out against the requirements +described in this section. The registry should generally be robust (e.g. operate under heavy load) and +secure in order to be acceptable for the SCS standard. Therefore, a required and optional feature set +were defined, to which a container registry must abide and be evaluated against.

+

Required features

+
    +
  • Audit Logs +
      +
    • ability to record use in auditable logs so that activity can be traced to a single user
    • +
    +
  • +
  • Authentication of system identities +
      +
    • support for authenticating system identities like Kubernetes clusters
    • +
    • possibly support for dynamic identity tokens from some IdP
    • +
    +
  • +
  • Authentication of users +
      +
    • support for multiple authentication systems (IdM integration)
    • +
    • user and user account management
    • +
    +
  • +
  • Authorization +
      +
    • role-based access control to ensure strict access controls
    • +
    +
  • +
  • Automation +
      +
    • integration with CI/CD tools e.g. via webhooks
    • +
    +
  • +
  • Vulnerability scanning +
      +
    • reveal security vulnerabilities in container images
    • +
    +
  • +
  • Content Trust and Validation +
      +
    • verify image authenticity before running
    • +
    • image signing
    • +
    +
  • +
  • Multi-tenancy +
      +
    • container registry is able to serve multiple tenants (projects, teams, namespaces)
    • +
    • implementation on the storage level, see e.g. Keppel, which uses +multi-tenant-aware storage drivers
    • +
    +
  • +
  • Backup and restore +
      +
    • possible strategies for disaster recovery and data migration scenarios
    • +
    +
  • +
  • Monitoring +
      +
    • observability is a key feature for operating a service in production so the container registry should expose key metrics
    • +
    +
  • +
  • HA mode +
      +
    • enable the possibility of system uptime, even if a failure of some sort could occur
    • +
    +
  • +
  • Registry replication +
      +
    • replication allows users to replicate container images between registries of the same instances and between registries of different instances as well
    • +
    +
  • +
  • Proxy cache (pull-through cache) +
      +
    • Proxy cache enables the use of a container registry to proxy and cache images from a target public or private registry
    • +
    +
  • +
  • Quota management +
      +
    • ability to control resource use of components or the whole registry
    • +
    +
  • +
  • Garbage collection +
      +
    • removing blobs from the filesystem when they are no longer referenced by a manifest
    • +
    +
  • +
  • Retention policy +
      +
    • reduce the number of image tags, many of which might not be required after a given time or once a subsequent image tag has superseded them
    • +
    +
  • +
+

Desirable features

+
    +
  • Additionally supported artifacts +
      +
    • Additional artifacts that the registry is able to store in addition to OCI artifacts, e.g. Java, Node.js, or Python packages
    • +
    +
  • +
  • Integration possibilities +
      +
    • Ability to cooperate with another software solution in order to improve own feature set (e.g. integration of P2P solution for improving container image distribution (download speed and stability, high scalability, ...))
    • +
    +
  • +
  • Deployment capabilities +
      +
    • ways to deploy a container registry (only "official" ways are mentioned)
    • +
    +
  • +
  • Administration capabilities "as a code" +
      +
    • ability to manage container registry via "as a code" solutions, e.g. Ansible role
    • +
    +
  • +
+

Standard

+

It is very unlikely, that every Container registry can fulfill every requirement defined by this document, and probably +not all deployments require every feature listed here. The required feature set should therefore be carefully considered +by the provider of the registry. We nevertheless RECOMMEND using most of the feature set provided in this document.

+

If the features mentioned above are all considered, a possible registry solution SHOULD fulfill the majority of +the required features. But this is again dependent on the specific use case and the surrounding architecture.

+ +

OSS-Health

+ + \ No newline at end of file diff --git a/standards/scs-0213-v1-k8s-nodes-anti-affinity/index.html b/standards/scs-0213-v1-k8s-nodes-anti-affinity/index.html new file mode 100644 index 0000000000..490826dab9 --- /dev/null +++ b/standards/scs-0213-v1-k8s-nodes-anti-affinity/index.html @@ -0,0 +1,147 @@ + + + + + +Kubernetes Nodes Anti Affinity | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Kubernetes Nodes Anti Affinity

Introduction

+

A Kubernetes instance is provided as a cluster, which consists of a set of worker machines, also called nodes. +A cluster is composed of a control plane and at least one worker node. +The control plane manages the worker nodes and therefore the pods in the cluster by making +decisions about scheduling, event detection and global decisions. Inside the control plane, +multiple components exist, which can be duplicated and distributed over multiple machines +inside the cluster. Typically, no user containers are run on these machines in order to +separate the control plane from the live system.

+

Glossary

+

The following special terms are used throughout this decision record document:

+
TermMeaning
WorkerVirtual or bare-metal machine, which hosts workloads of customers
Control PlaneVirtual or bare-metal machine, which hosts the container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers.
MachineVirtual or bare-metal entity with computational capabilities
+

Motivation

+

In a productive environment, the control plane usually runs across multiple machines and +a cluster usually contains multiple worker nodes in order to provide fault-tolerance and +high availability.

+

In order to ensure availability and scaling of workloads, even if some nodes in the cluster +could fail, they should be distributed over multiple nodes on different machines. +This can be steered with the Affinity or Anti Affinity features, which are separated by +Kubernetes into two features:

+
    +
  • +

    Node Affinity

    +

    The Node Affinity feature allows to match pods according to logical matches of +key-value-pairs referring to labels of nodes. +These can be defined with different weights or preferences in order to allow fine-grained +selection of nodes. The feature works similar to the Kubernetes nodeSelector. +It is defined in the PodSpec using the nodeAffinity field in the affinity section.

    +
  • +
  • +

    Pod Affinity

    +

    Pod Affinity or Pod Anti Affinity allows the constraint of pod scheduling based on the +labels of pods already running on a node. +This means the constraint will match other pods on a node according to their labels key-value-pairs +and then either schedule the pod to the same (Affinity) or another (Anti Affinity) node. +This feature is also defined in the PodSpec using the podAffinity and podAntiAffinity +fields in the affinity section. [3]

    +
  • +
+

Both features allow the usage of "required" or "preferred" keywords, which create +"hard" or "soft" affinities. By using a hard affinity, a pod would need to be scheduled +according to the rules set. If this possibility is not given, the pod can't be scheduled. +A soft affinity would allow scheduling even if the requirements are not fulfilled, but +they would be preferred if possible.

+

These features allow efficient resource usage (e.g. by scheduling workloads to evenly +distribute across nodes) and provide fault-tolerance and therefore high availability. +But they also require more work during the setup of a service architecture, since nodes +and pods need to be labelled and described consistently.

+

In the case of SCS, affinity of the workloads themselves is not relevant, since this +feature is mostly used by the customers of the providers. +Instead, the expected standard should enable the Kubernetes cluster to handle Anti Affinity +rules with a real physical separation as well as distributing the control plane over +multiple machines in order to provide fault-tolerance during system outages. +If the control plane survives an outage, a Kubernetes cluster can recover later on.

+

Design considerations

+

SCS plans to require a Hard Anti Affinity and/or Redundancy for the control plane and +a Soft Anti Affinity for workers. This means, that Anti Affinity would be required for +the control planes and their pods and only optional (but encouraged) for workers.

+

In order to achieve the goals for these components, meaning availability and fault tolerance +for the control plane, an outage resistant cluster, and the availability +promise given with Anti Affinity for pods on the worker nodes, a separation of nodes +on the hardware level would need to be achieved.

+

For the control plane, a reference to the "Kubernetes High Availability" [1] +can be useful, since it provides two ways to set up a highly available cluster. +Both approaches are very similar. The "Stacked Control Plane" [2] requires less infrastructure, +but also runs the risk of failed coupling, where if one node fails, the redundancy could be +compromised due to the loss of a complete control plane instance. +The "External ETCD" solves this problem, but also requires double the infrastructure, due +to the externally incorporated etcd clusters.

+

This also shows, that the wording "anti affinity" as used with Kubernetes pods is probably +slightly misleading in the context of a Kubernetes control plane. It may consist of multiple +pods with individual tasks, but distributing them over different nodes through Anti Affinity +would probably still cascade the whole control plane into a complete failure, if one of +the used nodes goes down. It could be possible to replicate specific important pods and +assign them to different nodes, but at this point, a redundant setup like presented in [1] could be used. +So Anti Affinity in this context probably means more like distribution over multiple +physical machines, which needs to be planned beforehand on the machine/server level.

+

Therefore, would it be preferred for the control plane to use a redundant setup, which +is separated over different physical machines, meaning at least half of the control plane +nodes runs on a different physical machine as the rest. The currently used ClusterAPI +enables this by establishing the concept of "failure domains". These are used to control +the placement of k8s nodes and distribute them over multiple physical machines. +For example, a High Availability K8s cluster with three control plane nodes could be +distributed over three different availability zones (and therefore 3 different +physical machines) in order to survive the failure of one availability zone. [5]

+

For worker nodes, the whole idea of Anti Affinity is more of a preferable situation. +The nodes themselves should at best be distributed over different machines, but this +is not a requirement, especially since smaller providers wouldn't have the capacity to +provide enough machines for these distributed Kubernetes clusters. Since customers that +use the Affinity or Topology spread constraint [4] features would be especially interested +in the worker nodes that host their workloads, it should be ensured that a good labeling +system is provided for the nodes in order to see if two nodes are hosted on the same machine.

+

Decision

+

The future standard should define a few important things in order to provide a solid base +for the usage and advantages of workloads with Anti Affinity rules.

+

Control planes SHOULD be made redundant in order to provide fault-tolerance and security +against fatal errors on this layer, in the case of node failures. How this redundancy +is achieved SHOULD be left to the providers, but since failure must be avoided, it is +REQUIRED to at least duplicate control plane components. Half of every component SHOULD +be located on a different node on a different physical machine than the other half +of them. This should provide at least the minimum requirements for a fault-tolerant control plane. +For the standard, there is also a possibility to define multiple stages of distributed infrastructure +and only make sensible ones a requirement and the rest optional, e.g.

+
    +
  • non-distributed clusters
  • +
  • High-Availability clusters that are +
      +
    • distributed over multiple machines/availability zones
    • +
    • distributed over multiple clouds
    • +
    • distributed over multiple physical locations/datacenters
    • +
    +
  • +
+

The worker nodes are RECOMMENDED to be distributed over different machines. In order to +provide clear information to the users, the nodes should be labeled to reflect the +mapping to the underlying clusters. The labels can be obfuscated in order to not reveal +the underlying structures to customers and users. It should be noted, that it is NOT REQUIRED +to have this anti affinity for the worker nodes due to the requirements of infrastructure +and complexity associated with this.

+

Documents

+

Kubernetes High Availability Documentation 1 +Kubernetes High Availability - Stacked ETCD 2 +Affinity and Anti-Affinity 3 +Topology Spread Constraints 4 +SCS Multi AZ and Multi Cloud Environments 5

+ + \ No newline at end of file diff --git a/standards/scs-0214-v1-k8s-node-distribution/index.html b/standards/scs-0214-v1-k8s-node-distribution/index.html new file mode 100644 index 0000000000..79c3145ac6 --- /dev/null +++ b/standards/scs-0214-v1-k8s-node-distribution/index.html @@ -0,0 +1,81 @@ + + + + + +Kubernetes Node Distribution and Availability | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Kubernetes Node Distribution and Availability

Introduction

+

A Kubernetes instance is provided as a cluster, which consists of a set of machines, +so-called nodes. A cluster is composed of a control plane and at least one worker node. +The control plane manages the worker nodes and therefore the pods in the cluster by making +decisions about scheduling, event detection and rights management. Inside the control plane, +multiple components exist, which can be duplicated and distributed over multiple nodes +inside the cluster. Typically, no user workloads are run on these nodes in order to +separate the controller component from user workloads, which could pose a security risk.

+

Glossary

+

The following terms are used throughout this document:

+
TermMeaning
WorkerVirtual or bare-metal machine, which hosts workloads of customers
Control PlaneVirtual or bare-metal machine, which hosts the container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers.
MachineVirtual or bare-metal entity with computational capabilities
+

Motivation

+

In normal day-to-day operation, it is not unusual for some operational failures, either +due to wear and tear of hardware, software misconfigurations, external problems or +user errors. Whichever was the source of such an outage, it always means down-time for +operations and users and possible even data loss. +Therefore, a Kubernetes cluster in a productive environment should be distributed over +multiple "failure zones" in order to provide fault-tolerance and high availability. +This is especially important for the control plane of the cluster, since it contains the +state of the whole cluster. A failure of this component could mean an unrecoverable failure +of the whole cluster.

+

Design Considerations

+

Most design considerations of this standard follow the previously written Decision Record +Kubernetes Nodes Anti Affinity as well as the Kubernetes documents about +High Availability and Best practices for large clusters.

+

SCS wishes to prefer distributed, highly-available systems due to their obvious advantages +like fault-tolerance and data redundancy. But it also understands the costs and overhead +for the providers associated with this effort, since the infrastructure needs to have +hardware which will just be used to provide fail-over safety or duplication.

+

The document Best practices for large clusters describes the concept of a failure zone. +This term isn't defined any further, but can in this context be described as a number of +physical (computing) machines in such a vicinity to each other (either through physical +or logical interconnection in some way), that specific problems inside this zone would put +all these machines at risk of failure/shutdown. It is therefore necessary for important +data or services to not be present just on one failure zone. +How such a failure zone should be defined is dependent on the risk model of the service/data +and its owner as well as the capabilities of the provider. Zones could be set from things +like single machines or racks up to whole datacenters or even regions, which could be +coupled by things like electrical grids. They're therefore purely logical entities, which +shouldn't be defined further in this document.

+

Decision

+

This standard formulates the requirement for the distribution of Kubernetes nodes in order +to provide a fault-tolerant and available Kubernetes cluster infrastructure. +Since some providers only have small environments to work with and therefore couldn't +comply with this standard, it will be treated as a RECOMMENDED standard, where providers +can OPT OUT.

+

If the standard is used by a provider, the following decisions are binding and valid:

+
    +
  • The control plane nodes MUST be distributed over multiple physical machines. Kubernetes +provides best-practices on this topic, which are also RECOMMENDED by SCS.
  • +
  • At least one control plane instance MUST be run in each "failure zone", more are +RECOMMENDED in each "failure zone" to provide fault-tolerance for each zone.
  • +
  • Worker nodes are RECOMMENDED to be distributed over multiple zones. This policy makes +it OPTIONAL to provide a worker node in each "failure zone", meaning that worker nodes +can also be scaled vertically first before scaling horizontally.
  • +
  • Worker node distribution MUST be indicated to the user through some kind of labeling +in order to enable (anti)-affinity for workloads over "failure zones".
  • +
+ + \ No newline at end of file diff --git a/standards/scs-0214-v2-k8s-node-distribution/index.html b/standards/scs-0214-v2-k8s-node-distribution/index.html new file mode 100644 index 0000000000..baacd075f5 --- /dev/null +++ b/standards/scs-0214-v2-k8s-node-distribution/index.html @@ -0,0 +1,101 @@ + + + + + +Kubernetes Node Distribution and Availability | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Kubernetes Node Distribution and Availability

Introduction

+

A Kubernetes instance is provided as a cluster, which consists of a set of machines, +so-called nodes. A cluster is composed of a control plane and at least one worker node. +The control plane manages the worker nodes and therefore the pods in the cluster by making +decisions about scheduling, event detection and rights management. Inside the control plane, +multiple components exist, which can be duplicated and distributed over multiple nodes +inside the cluster. Typically, no user workloads are run on these nodes in order to +separate the controller component from user workloads, which could pose a security risk.

+

Glossary

+

The following terms are used throughout this document:

+
TermMeaning
WorkerVirtual or bare-metal machine, which hosts workloads of customers
Control PlaneVirtual or bare-metal machine, which hosts the container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers.
MachineVirtual or bare-metal entity with computational capabilities
+

Motivation

+

In normal day-to-day operation, it is not unusual for some operational failures, either +due to wear and tear of hardware, software misconfigurations, external problems or +user errors. Whichever was the source of such an outage, it always means down-time for +operations and users and possible even data loss. +Therefore, a Kubernetes cluster in a productive environment should be distributed over +multiple "failure zones" in order to provide fault-tolerance and high availability. +This is especially important for the control plane of the cluster, since it contains the +state of the whole cluster. A failure of this component could mean an unrecoverable failure +of the whole cluster.

+

Design Considerations

+

Most design considerations of this standard follow the previously written Decision Record +Kubernetes Nodes Anti Affinity as well as the Kubernetes documents about +High Availability and Best practices for large clusters.

+

SCS wishes to prefer distributed, highly-available systems due to their obvious advantages +like fault-tolerance and data redundancy. But it also understands the costs and overhead +for the providers associated with this effort, since the infrastructure needs to have +hardware which will just be used to provide fail-over safety or duplication.

+

The document Best practices for large clusters describes the concept of a failure zone. +This term isn't defined any further, but can in this context be described as a number of +physical (computing) machines in such a vicinity to each other (either through physical +or logical interconnection in some way), that specific problems inside this zone would put +all these machines at risk of failure/shutdown. It is therefore necessary for important +data or services to not be present just on one failure zone. +How such a failure zone should be defined is dependent on the risk model of the service/data +and its owner as well as the capabilities of the provider. Zones could be set from things +like single machines or racks up to whole datacenters or even regions, which could be +coupled by things like electrical grids. They're therefore purely logical entities, which +shouldn't be defined further in this document.

+

Decision

+

This standard formulates the requirement for the distribution of Kubernetes nodes in order +to provide a fault-tolerant and available Kubernetes cluster infrastructure.

+

The control plane nodes MUST be distributed over multiple physical machines. +Kubernetes provides best-practices on this topic, which are also RECOMMENDED by SCS.

+

At least one control plane instance MUST be run in each "failure zone" used for the cluster, +more instances per "failure zone" are possible to provide fault-tolerance inside a zone.

+

Worker nodes are RECOMMENDED to be distributed over multiple zones. This policy makes +it OPTIONAL to provide a worker node in each "failure zone", meaning that worker nodes +can also be scaled vertically first before scaling horizontally.

+

To provide metadata about the node distribution and possibly provide the ability +to schedule workloads efficiently, which also enables testing of this standard, +providers MUST annotate their K8s nodes with the labels listed below. +These labels MUST be kept up to date with the current state of the deployment.

+
    +
  • +

    topology.kubernetes.io/zone

    +

    Corresponds with the label described in K8s labels documentation. +It provides a logical zone of failure on the side of the provider, e.g. a server rack +in the same electrical circuit or multiple machines bound to the internet through a +singular network structure. How this is defined exactly is up to the plans of the provider. +The field gets autopopulated most of the time by either the kubelet or external mechanisms +like the cloud controller.

    +
  • +
  • +

    topology.kubernetes.io/region

    +

    Corresponds with the label described in K8s labels documentation. +It describes the combination of one or more failure zones into a region or domain, therefore +showing a larger entity of logical failure zone. An example for this could be a building +containing racks that are put into such a zone, since they're all prone to failure, if e.g. +the power for the building is cut. How this is defined exactly is also up to the provider. +The field gets autopopulated most of the time by either the kubelet or external mechanisms +like the cloud controller.

    +
  • +
+

Previous standard versions

+

This is version 2 of the standard; it extends version 1 with the +requirements regarding node labeling.

+ + \ No newline at end of file diff --git a/standards/scs-0214-w1-k8s-node-distribution-implementation-testing/index.html b/standards/scs-0214-w1-k8s-node-distribution-implementation-testing/index.html new file mode 100644 index 0000000000..3b430770c9 --- /dev/null +++ b/standards/scs-0214-w1-k8s-node-distribution-implementation-testing/index.html @@ -0,0 +1,37 @@ + + + + + +Kubernetes Node Distribution and Availability: Implementation and Testing Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Kubernetes Node Distribution and Availability: Implementation and Testing Notes

Implementation notes

+

A Kubernetes clusters control plane must be distributed over multiple physical machines, as well +as different "failure zones". How these are defined is at the moment up to the CSP. +Worker nodes can also be distributed over "failure zones", but this isn't a requirement. +Distribution must be shown through labelling, so that users can access these information.

+

Node distribution metadata is provided through the usage of the labels +topology.kubernetes.io/region and topology.kubernetes.io/zone.

+

Automated tests

+

Currently, automated testing is not readily possible because we cannot access information about +the underlying host of a node (as opposed to its region and zone). Therefore, the test will only output +a tentative result.

+

The current implementation can be found in the script k8s_node_distribution_check.py.

+

Manual tests

+

None.

+ + \ No newline at end of file diff --git a/standards/scs-0215-v1-robustness-features/index.html b/standards/scs-0215-v1-robustness-features/index.html new file mode 100644 index 0000000000..cf4a1422b9 --- /dev/null +++ b/standards/scs-0215-v1-robustness-features/index.html @@ -0,0 +1,208 @@ + + + + + +Robustness features for Kubernetes clusters | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Robustness features for Kubernetes clusters

Introduction

+

Kubernetes clusters in a productive environment are under the assumption to always perform perfectly without any major +interruptions. But due to external or unforeseen influences, clusters can be disrupted in their normal workflow, which +could lead to slow responsiveness or even malfunctions. +In order to possibly mitigate some problems for the Kubernetes clusters, robustness features should be introduced into +the SCS standards. These would harden the cluster infrastructure against several problems, making failures less likely.

+

Glossary

+

The following special terms are used throughout this standard document:

+
TermAbbreviationMeaning
Certificate AuthorityCATrusted organization that issues digital certificates entities
Certificate Signing RequestCSRRequest in order to apply for a digital identity certificate
+

Motivation

+

A typical productive Kubernetes cluster could be hardened in many different ways, whereas probably many of these actions +would overlap and target similar weaknesses of a cluster. +For this version of the standard, the following points should be addressed:

+
    +
  • Kube-API rate limiting
  • +
  • etcd compaction/defragmentation
  • +
  • etcd backup
  • +
  • Certificate Authority (CA) expiration avoidance
  • +
+

These robustness features should mainly increase the up-time of the Kubernetes cluster by avoiding downtimes either +because of internal problems or external threads like "Denial of Service" attacks. +Additionally, the etcd database should be strengthened with these features in order to provide a secure and robust +backend for the Kubernetes cluster.

+

Design Considerations

+

In order to provide a conclusive standard, some design considerations need to be set beforehand:

+

Kube-API rate limiting

+

Rate limiting is the practice of preventing too many requests to the same server in some time frame. This can help prevent +service interruptions due to congestion and therefore slow responsiveness or even service shutdown. +Kubernetes suggests multiple ways to integrate such a Ratelimit for its API server, a few of which will be mentioned here. +In order to provide a useful Ratelimit for the Kubernetes cluster, combination of these methods should be considered.

+

API server flags

+

The Kubernetes API server has some flags available to limit the amount of incoming requests that will be accepted by +the server, which should prevent crashing of the API server. This nevertheless shouldn't be the only measure to +introduce a rate limit, since important requests could get blocked during high traffic periods (at least according to +the official documentation). +The following controls are available to tune the server:

+
    +
  • max-requests-inflight
  • +
  • max-mutating-requests-inflight
  • +
  • min-request-timeout
  • +
+

More details can be found in the following documents: +Flow Control

+

Ratelimit Admission Controller

+

From version 1.13 onwards, Kubernetes includes a EventRateLimit Admission Controller, which aims to mitigate Ratelimit +problems associated with the API server by providing limits for requests every second either to specific resources or +even the whole API server. If requests are denied due to this Admission Controller, they're either cached or denied +completely and need to be retried; this also depends on the EventRateLimit configuration. +More details can be found in the following documents: +Rancher rate limiting +EventRateLimit +It is important to note, that this only helps the API server against event overloads and not necessarily the network +in front of it, which could still be overwhelmed.

+

Flow control

+

Flow control for the Kubernetes API server can be provided by the API priority and fairness feature, which classifies +and isolates requests in a fine-grained way in order to prevent an overload of the API server. +The package introduces queues in order to not deny requests and dequeue them through Fair Queueing techniques. +Overall, the Flow control package introduces many different features like request queues, rule-based flow control, +different priority levels and rate limit maximums. +The concept documentation offers a more in-depth explanation of the feature: +Flow Control

+

etcd maintenance

+

etcd is a strongly consistent, distributed key-value store that provides a reliable way to store data that needs to be +accessed by a distributed system or cluster of machines. For these reasons, etcd was chosen as the default database +for Kubernetes. +In order to remain reliable, an etcd cluster needs periodic maintenance. This is necessary to maintain the etcd keyspace; +failure to do so could lead to a cluster-wide alarm, which would put the cluster into a limited-operation mode. +To mitigate this scenario, the etcd keyspace can be compacted. Additionally, an etcd cluster can be defragmented, which +gives back disk space to the underlying file system and can help bring the cluster back into an operable state, if it +ran out of space earlier.

+

etcd keyspace maintenance can be achieved by providing the necessary flags/parameters to etcd, either via the KubeadmControlPlane or in the +configuration file of the etcd cluster, if it is managed independent of the Kubernetes cluster. +Possible flags, that can be set for this feature, are:

+
    +
  • auto-compaction-mode
  • +
  • auto-compaction-retention
  • +
+

More information about compaction can be found in the respective etcd documentation +etcd maintenance

+

etcd backup

+

An etcd cluster should be regularly backed up in order to be able to restore the cluster to a known good state at an +earlier space in time if a failure or incorrect state happens. +The cluster should be backed up multiple times in order to have different possible states to go back to. This is especially +useful, if data in the newer backups was already corrupted in some way or important data was deleted in them. +For this reason, a backup strategy needs to be developed with a decreasing number of backups in an increasing period of time, +meaning that the previous year should only have 1 backup, but the current week should have multiple. +Information about the backup process can be found in the etcd documentation: +Upgrade etcd

+

Certificate rotation

+

In order to secure the communication of a Kubernetes cluster, (TLS) certificates signed by a controlled +Certificate Authority (CA) can be used. +Normally, these certificates expire after a set period of time. In order to avoid expiration and failure of a cluster, +these certificates need to be rotated regularly and at best automatically. +Certificates can either be rotated manually (a reference for manually working with certificates can be found +here) +or automatically, which requires other things to care about in a deployment.

+

Some tools or clusters provide possibilities to rotate certificates manually. +For example, kubeadm and k3s provides the following commands

+
# kubeadm
kubeadm certs renew all

# k3s
k3s certificate rotate
+

A CA might also expire. Unfortunately, not all Kubernetes tools have functionality to renew these certificates. +Instead, documentation is provided to manually rotating a CA ([Manual rotation of ca certificate]).

+

Automatic certificate rotation

+

kubelet can be configured to obtain properly signed certificates from the certificates.k8s.io API of Kubernetes. +To do this, set serverTLSBootstrap: true in the configuration file of kubelet, which enables both the certificate request +during bootstrapping and the rotation mechanism. Setting rotateCertificates: true only enables the certificate rotation [Kubeadm certs]. +--rotate-certificates or --rotate-server-certificates shouldn't be used as command line arguments to set these flags, +since both parameters are deprecated according to [Certificate rotation].

+

It is also important to note that some Kubernetes clusters or admin tools provide additional ways to rotate certificates. +For example, kubeadm automatically rotates certificates, if the cluster is updated with the tool (see [Automatic Certificate renewal]). +This would also mean, that at least kubeadm-based clusters can be assumed to rotate their certificates regularly, +since they would probably be updated within the time period described in the +standard SCS-0210-v2.

+

If an automatic certificate rotation happens, these certificates need to be approved either manually or by a third party +controller like the kubelet csr approver, which can be deployed on +a Kubernetes cluster to automate this process.

+

A manual approval of these CSRs could be done with the commands

+
kubectl get csr
kubectl certificate approve <CSR>
+

in order to complete a certificate rotation. +But it should be noted, that this is also most likely dependent on the Kubernetes cluster solution in use.

+

kubectl get csr allows to check, if a CSR needs to be approved; a Pending CSR would need to be approved.

+
NAME        AGE     SIGNERNAME                        REQUESTOR                      CONDITION
csr-9wvgt 112s kubernetes.io/kubelet-serving system:node:worker-1 Pending
+

Further information and examples can be found in the Kubernetes documentation: +Kubeadm certs +Kubelet TLS bootstrapping

+

Decision

+

Robustness features combine multiple aspects of increasing the security, hardness and +longevity of a Kubernetes cluster. The decisions will be separated into their respective +areas.

+

Kube-API rate limiting

+

The number of requests send to the kube-api or Kubernetes API server MUST be limited +in order to protect the server against outages, deceleration or malfunctions due to an +overload of requests. +In order to do so, at least the following parameters MUST be set on a Kubernetes cluster:

+
    +
  • max-requests-inflight
  • +
  • max-mutating-requests-inflight
  • +
  • min-request-timeout
  • +
+

Values for these flags/parameters SHOULD be adapted to the needs of the environment and +the expected load.

+

A cluster MUST also activate and configure a Ratelimit admission controller. +This requires an EventRateLimit resource to be deployed on the Kubernetes cluster. +The following settings are RECOMMENDED for a cluster-wide deployment, but more +fine-grained rate limiting can also be applied, if this is necessary.

+
kind: Configuration
apiVersion: eventratelimit.admission.k8s.io/v1alpha1
limits:
- burst: 20000
qps: 5000
type: Server
+

It is also RECOMMENDED to activate the Kubernetes API priority and fairness feature, +which also uses the aforementioned cluster parameters to better queue, schedule and +prioritize incoming requests.

+

etcd compaction

+

etcd MUST be cleaned up regularly, so that it functions correctly and doesn't take +up too much space, which happens because of its increase of the keyspace.

+

To compact the etcd keyspace, the following flags/parameters MUST be set for etcd:

+
    +
  • auto-compaction-mode = periodic
  • +
  • auto-compaction-retention = 8h
  • +
+

etcd backup

+

An etcd cluster MUST be backed up regularly. It is RECOMMENDED to adapt +a strategy of decreasing backups over longer time periods, e.g. keeping snapshots every +10 minutes for the last 120 minutes, then one hourly for 1 day, then one daily for 2 weeks, +then one weekly for 3 months, then one monthly for 2 years, and after that a yearly backup. +At the very least, a backup MUST be done once a week. +These numbers can be adapted to the security setup and concerns like storage or network +usage. It is also RECOMMENDED to encrypt the backups in order to secure them further. +How this is done is up to the operator.

+

Certificate rotation

+

It should be avoided, that certificates expire either on the whole cluster or for single components. +To avoid this scenario, certificates MUST be rotated regularly; in the +case of SCS, we REQUIRE at least a yearly certificate rotation.

+

It is also RECOMMENDED to renew the CA regularly to avoid an expiration of the CA. +This standard doesn't set an exact timeline for a renewal, since it is dependent on lifetime and +therefore expiration date of the CA in question.

+ +

Flow Control +Rate limiting +EventRateLimit +etcd maintenance +Upgrade etcd +Kubeadm certs +Kubelet TLS bootstrapping +Certificate rotation +Manual rotation of ca certificate +Automatic Certificate renewal

+

Conformance Tests

+

Conformance Tests, OPTIONAL

+ + \ No newline at end of file diff --git a/standards/scs-0216-v1-requirements-for-testing-cluster-stacks/index.html b/standards/scs-0216-v1-requirements-for-testing-cluster-stacks/index.html new file mode 100644 index 0000000000..330f7df921 --- /dev/null +++ b/standards/scs-0216-v1-requirements-for-testing-cluster-stacks/index.html @@ -0,0 +1,130 @@ + + + + + +Requirements for testing cluster-stacks | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Requirements for testing cluster-stacks

Introduction

+

In this proposal, we discuss the necessity and design considerations of a lightweight solution for testing cluster-stacks. The purpose is to address the challenges associated with testing on an Infrastructure as a Service (IaaS) provider and the limitations of using Docker as the primary containerization tool for testing. This proposal will elaborate on why we need to test in a local environment, specifically a laptop, and the benefits and drawbacks associated with it. We aim to make an informed decision for testing cluster stacks to cater to both the organizational and technical perspectives of our stakeholders.

+

Motivation

+

From an organization's point of view, it is crucial to lower the entry barrier for testing. This action will make it possible for anyone, including external contributors, to easily participate in the testing process without needing an account with the IaaS provider. It is also necessary to overcome the hurdles associated with maintaining a balance in the provider account and managing sponsorships to fund the testing.

+

From a technical standpoint, there are multiple reasons to favor a local environment for testing. Among them is the ability to test without internet, finish tests in a shorter timeframe, and incur no cost. The provider independence of Cluster Stacks makes it nonsensical to test with a specific provider due to the varied behaviors of different providers. There are also challenges in monitoring and debugging tests run on IaaS providers and dealing with their downtime and limitations on concurrent testing.

+

Design Considerations

+
    +
  1. +

    Lightweight Solution +The testing solution should be lightweight and easy to use in a local environment, such as a laptop. This lightweight solution should minimize dependencies and resource usage while maximizing speed and efficiency of the tests. It should be capable of handling the cluster-stack testing requirements without necessitating a bulky or resource-intensive setup.

    +
  2. +
  3. +

    Independence from Specific Providers +The solution should be generalized and not bound to any specific provider. This consideration ensures that the solution can be applied to any provider, guaranteeing its versatility and broad applicability.

    +
  4. +
  5. +

    Offline Testing +The testing solution should support testing without internet connection, which will enable more robust and flexible testing scenarios. It should be possible to run the tests even in cases of limited or disrupted internet access.

    +
  6. +
  7. +

    Fast Execution Time +The tests should execute within a reasonably short amount of time. The solution must be optimized to ensure quick testing cycles, which can help increase productivity and shorten development cycles.

    +
  8. +
  9. +

    No-Cost Solution +The solution should not impose any additional costs on the organization or individual testers. This characteristic is crucial to enable widespread adoption of the testing process and to lower the entry barrier for contributors.

    +
  10. +
  11. +

    Easy Monitoring and Debugging +The solution should provide easy monitoring and debugging capabilities. It should allow developers to quickly identify, diagnose, and fix issues that arise during testing, without requiring access to any external logs or monitoring tools.

    +
  12. +
  13. +

    Concurrent Testing +The solution should support the ability to run concurrent tests without causing any disruption or downtime. This ability can improve the efficiency and speed of the testing process.

    +
  14. +
+

Required Features

+

The proposed solution should meet the following feature requirements:

+
    +
  1. Local Environment: The solution should support a local testing environment that allows developers to test cluster stacks on their local machines, reducing dependencies on external providers.
  2. +
  3. Compatibility: The solution should be compatible with various operating systems and platforms, ensuring its usability across diverse environments.
  4. +
  5. Performance: The solution should offer high-performance testing capabilities, allowing fast execution of tests.
  6. +
  7. Offline Support: The solution should allow testing in offline mode, ensuring tests can be performed even without an internet connection.
  8. +
  9. Concurrency: The solution should support running multiple tests concurrently without causing disruptions or conflicts.
  10. +
  11. Monitoring & Debugging: The solution should provide easy-to-use tools for monitoring test progress and debugging issues.
  12. +
  13. Cost-effectiveness: The solution should not require any financial investment from the testers or the organization, promoting broad accessibility and usage.
  14. +
+

Pros and Cons of Different Approaches

+

Two potential approaches for testing cluster stacks are the use of an IaaS provider and the use of a local environment. Here we discuss the pros and cons of these two approaches.

+

IaaS Provider (OpenStack, Hetzner, AWS)

+

Pros

+
    +
  • Comprehensive testing environment with advanced capabilities.
  • +
  • Possibility to mimic real-world production environments closely.
  • +
+

Cons

+
    +
  • Requires signing up and account management, which can be a barrier for some testers.
  • +
  • Requires maintaining a balance in the provider account, which can pose financial burdens.
  • +
  • Internet dependency for testing.
  • +
  • Potential for prolonged testing time due to various dependencies.
  • +
  • Challenges with monitoring and debugging.
  • +
  • Potential downtime and difficulty in running concurrent tests.
  • +
+

Local Environment (Docker, KubeVirt)

+

Pros

+
    +
  • Faster test execution with no downtime.
  • +
  • Ability to test without internet.
  • +
  • Independent of any provider knowledge.
  • +
  • Cost-free testing.
  • +
  • Easier integration into CI/CD.
  • +
  • Simplified monitoring and debugging.
  • +
+

Cons

+
    +
  • Limited systemd support and containerd support for kubeadm in Docker.
  • +
  • Inability to mimic the exact real-world production environments.
  • +
+

Beyond Docker: Virtual Machine based Approach

+

While Docker provides significant benefits for local environment testing, it's important to recognize its limitations. Docker containers, by design, are lightweight and don't contain a full operating system which can lead to challenges when trying to mimic real-world production environments. Also, Docker containers lack some necessary features like systemd which is used in many production environments for initializing and managing services.

+

One major aspect that Docker lacks is the ability to mimic real-world production environments effectively. This is primarily due to its nature as a containerization tool, operating within the host OS, and sharing resources among its containers. This might create disparities in behavior when comparing to deployments on real, isolated systems, which could be problematic in some scenarios.

+

Furthermore, Docker utilizes a Union File System for its images, leading to the creation of layers. This approach can lead to some complexities when dealing with node-images which comprise a significant chunk of our layers. Handling such situations might require workarounds that could add additional complexity and potential points of failure. This creates a blind spot, as real providers won't require these workarounds, which might lead to disparities in results when comparing testing in local and actual production environments.

+

Therefore, to achieve a more accurate representation of real-world environments, we propose a solution that utilizes a virtual machine based approach for local testing. This approach could leverage tools like KubeVirt, Vagrant, or VirtualBox to create and manage virtual machines on the local environment. This strategy would provide a more robust and realistic environment for testing, as it can better emulate the behavior of a full-fledged operating system and thereby more closely mimic a real-world production environment.

+

Virtual Machine Based Approach

+

Pros

+
    +
  • Provides a more accurate representation of real-world production environments.
  • +
  • Allows for full operating system emulation, including features like systemd.
  • +
  • Can create isolated environments, thereby mimicking actual deployments better than containers.
  • +
+

Cons

+
    +
  • Potentially more resource-intensive than container-based solutions.
  • +
  • Increased complexity due to the need for managing full virtual machines rather than lightweight containers.
  • +
  • Initial setup might be more complicated compared to a Docker-based solution.
  • +
+

Proposed Path Forward

+

Given the limitations of Docker and the potential advantages of a virtual machine based approach, we propose to investigate further into this strategy. The exact tool or set of tools used can be determined based on a thorough evaluation of the available options.

+

Although there might be some initial complexity and potentially higher resource usage compared to Docker, we believe that the benefits of more accurate testing and better emulation of real-world environments outweigh these potential disadvantages.

+

The proposed solution should meet all the requirements mentioned in the previous sections of the proposal, in addition to providing the benefits of a virtual machine based approach. By doing so, we aim to establish a robust, reliable, and realistic testing environment for cluster stacks that mimics real-world production environments as closely as possible.

+

Conclusion

+

After thoroughly examining the organizational needs, technical requirements, and potential testing approaches, it is evident that testing cluster stacks in a local environment provides significant advantages over using an Infrastructure as a Service (IaaS) provider. A local environment minimizes financial constraints, reduces testing time, offers offline capabilities, and enables greater tester participation without the need for specialized IaaS knowledge.

+

While Docker stands out for its broad adoption, cost-effectiveness, and impressive containerization benefits, it also presents some limitations that cannot be overlooked. The lack of full operating system emulation and certain system features like systemd pose challenges to mimic real-world production environments accurately.

+

Given Docker's limitations and the need to reproduce realistic testing scenarios, we propose moving beyond Docker to a virtual machine-based approach. Even though this approach may introduce initial complexity and potentially higher resource usage, it promises a more accurate representation of real-world environments, thereby ensuring more reliable and robust test results.

+

Tools such as KubeVirt, Vagrant, or VirtualBox could potentially fulfill our requirements, offering benefits such as full operating system emulation and isolated environments. However, an in-depth evaluation of these and possibly other tools is necessary to determine the best path forward.

+

In conclusion, our goal is to design a robust, reliable, and realistic testing environment for cluster stacks that closely mimics real-world production environments, aligns with our organizational and technical perspectives, and ensures a low entry barrier for all testers. Embracing a virtual machine-based approach for local environment testing represents a promising strategy to achieve this objective, paving the way for more efficient and reliable cluster stack testing.

+ + \ No newline at end of file diff --git a/standards/scs-0217-v1-cluster-hardening/index.html b/standards/scs-0217-v1-cluster-hardening/index.html new file mode 100644 index 0000000000..4a295ae671 --- /dev/null +++ b/standards/scs-0217-v1-cluster-hardening/index.html @@ -0,0 +1,396 @@ + + + + + +Kubernetes cluster hardening | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Kubernetes cluster hardening

Introduction

+

Due to the regular changes and updates, there are always new security features to deploy and use in Kubernetes. +Nevertheless, a provider (or even a customer) needs to take action in order to achieve a +baseline-secure cluster due to the myriad of configurations possible. This is especially +the case since Kubernetes ships with insecure features and configurations out of the box, +which will need to be mitigated by an administrator with the proper knowledge. +Secure Kubernetes clusters are desirable regardless of the possible threat model, +since higher security doesn't necessarily mean higher complexity in this case.

+

Terminology

+
TermMeaning
TLSTransport Layer Security
CACertificate Authority
JWTJSON Web Token
ABACAttribute-based access control
RBACRole-based access control
+

Motivation

+

Kubernetes clusters are highly configurable, which also gives rise to different security +problems, if the configuration isn't done properly. +These security risks can potentially be exposed in many different parts of a cluster, e.g. +different APIs, authorization and authentication procedures or even Pod privilege mechanisms. +In order to mitigate these problems, different steps and hardening mechanisms could be used +to increase the security of a Kubernetes setup. +Due to the focus of the SCS KaaS standards on the providers, best practices for security +that are more focused on user environments aren't described here, e.g., the possibility for +network traffic control between pods. This could theoretically be set up by a provider, +but isn't very practical for the user, since he would probably need to request changes +regularly in this case.

+

Hardening Kubernetes

+

This section is non-authoritative and only describes concepts and design considerations.

+

Regular updates

+

Due to the risk associated with running older versions of software, e.g. known security vulnerabilities, +bugs or missing features as well as the difficulty of tracking or identifying attack vectors, +it is advised to first and foremost keep the version of the Kubernetes components up-to-date. +It should be especially important to keep on track with the patch-level versions of Kubernetes, +since they include bugfixes and security patches, which are also backported to the previous +three minor-level versions, depending on their severity and the feasibility. It is also recommended +to refer to the version skew policy for more details about component versions.

+

Securing etcd

+

The etcd database is the storage for Kubernetes, containing information about cluster workloads, states and secrets. +Gaining access to this critical infrastructure part would enable a bad actor to read the aforementioned information; +write access would be equivalent to administrative access on the Kubernetes cluster and information could be manipulated +while ignoring any restrictions or validations put in place by other Kubernetes components.

+

Securing etcd can be done through different or a combination of +many mechanisms, including strong security credentials for the etcd server, the isolation of the etcd servers behind a firewall, separate etcd +instances for components beside the API-server, ACL restrictions for read-write-access to subsets of the keyspace and +a separate CA for etcd communication, which limits the trusted partners of the etcd database to clients with a certificate from this CA. +These strategies will be explained a bit more in-depth in the following subsections.

+

Strong authentication

+

If an etcd instance wasn't secured correctly, it could be possible that a bad actor would try to authenticate against +the database. +It is therefore advised to use strong security credentials (see e.g. the strong credentials requirements by NIST) for +all user accounts on the etcd server as well as the machines running this critical component. +This is obviously a fact for all possibly accessible components, but especially true for etcd, since it contains +the complete cluster state.

+

Multiple etcd instances

+

etcd is a critical component that needs to be protected from +bad actors as well as outages. Kubernetes recommends a five-member cluster for durability and high-availability as well as regular back-ups of the data. +For more information on high-availability, look into the Kubernetes Node Distribution and Availability Standard. +It would also be possible to use these etcd instances in order to select specific instances +that aren't the current etcd leader for interaction with different components (e.g. Calico), since access to the primary etcd instance could be considered dangerous, because the full keyspace could be viewed without further restrictions (see here or here). +This approach should still be paired with etcd ACL to better restrict access.

+

etcd isolation

+

The etcd database should at best be isolated from the rest of a Kubernetes cluster. +Access should only be granted to components that need it, which is in most cases mainly (or only) +the API server. Best practice would be to host etcd on machines separate from the Kubernetes cluster +and block access from machines or networks that don't need access with specific firewall rules. +In most cases, only the API server machines should need access to etcd on ports 2379-2380.

+

ACL restrictions

+

etcd implements access control lists (ACL) and authentication since version 2.1 1. +etcd provides users and roles; users gain permissions through roles. When authentication is enabled, +each request to etcd requires authentication and the transaction is only allowed, if the user has the correct access rights. +etcd can also be launched with --client-cert-auth=true, which enables authentication via +the Common Name (CN) field of a client TLS certificate without a password. +This option enables Kubernetes components to authenticate as a user without providing a password, +which is neither possible for Kubernetes components nor planned in future releases. +This method is recommended in order to implement ACL for different Kubernetes components and +not give the Kubernetes API full root access to the etcd instance; instead, a separate user can be created.

+

TLS communication

+

etcd should use TLS for peer- and cluster-communication, so that traffic between different peered etcd instances as well +as the communication with the Kubernetes cluster can be secured. +etcd provides options for all these scenarios, including --peer-key-file=peer.key and --peer-cert-file=peer.cert +for securing peer communication and the flags --key-file=k8sclient.key and --cert-file=k8sclient.cert for securing +client communication (and therefore cluster communication). +Additionally, HTTPS should be used as the URL schema. +It is also possible to use a separate CA for the etcd in order to separate and better control access through client +certificates, since etcd by default trusts all the certificates issued by the root CA 2. +More information about authentication via TLS is provided in the chapter ACL restrictions.

+

Securing endpoints

+

Kubernetes provides a well-defined set of ports in its default configuration. These ports are +used for inter-component communication as well as external access. Due to the distribution of information +about Kubernetes clusters, it is easy for a bad actor to identify a clusters +ports and try to attack them. In order to minimize the attack vector, internal ports (and therefore components) +should not be accessible from external networks, except if there are requirements to enable this behavior.

+

A good way to restrict access would be a combination of firewalls with port +blocking and the integration of network separation. +How this is done is highly dependent on the specific setup of the provider. +An additional document could be provided in the future to give basic +guidelines for this task.

+

A list of the default ports used in Kubernetes as well as the components accessing them can be found below:

+

Control plane nodes

+
PortsProtocolPurposeUsed byAccess type
6443TCPAPI serverAllExternal, internal
2379-2380TCPetcd serverkube-apiserver, etcdInternal
10250TCPKubelet APISelf, Control planeInternal
10255TCPRead-only Kubelet APIExternal applicationsExternal, Internal
10257TCPkube-controller-managerSelfInternal
10259TCPkube-schedulerSelfInternal
+

Hint: Self in the Used by context means, that a resource will access its own port for requests.

+

Worker nodes

+
PortsProtocolPurposeUsed byAccess type
10250TCPKubelet APISelf, Control planeInternal
10255TCPRead-only Kubelet APIExternal applicationsExternal, internal
30000-32767TCPNodePort ServicesExternal
+

API security, authentication and authorization

+

In order to secure Kubernetes against bad actors, limiting and securing access to API requests +is recommended, since requests to those are able to control the entire Kubernetes cluster. +Access control is applied to both human users and Kubernetes service accounts, which goes through +several stages after a request reaches the API.

+
    +
  1. The Kubernetes API server listens on port 6443 on the first non-localhost network interface by default, +protected by TLS 3. The TLS certificate can either be signed with a private CA or based on a public key +infrastructure with a widely recognized CA behind it.
  2. +
  3. The authentication step checks the request for correct authentication based on different possible +authentication modules like password, plain tokens or JWT. Only one of these methods needs to succeed +in order to allow a request to pass to the next stage.
  4. +
  5. The authorization step authorizes a request, if a user is allowed to carry out a specific operation. +The request must contain the username of the requester, the requested action and the affected object. +Kubernetes supports different authorization modules like ABAC, RBAC or Webhooks. Only one of these +modules need to approve the request in order for it to be authorized.
  6. +
  7. The last step are Admission control modules, which can modify or reject requests after accessing +the objects contents.
  8. +
+

Authentication

+

Kubernetes provides different internal authentication mechanisms, that can be used depending +on the requirements of the cluster provider and user. Multiple authentication systems can +be enabled and the Kubernetes documentation recommends at least using two methods, +including Service Account Tokens and another method. Methods directly provided by Kubernetes include +the following (a more complete or up-to-date list may be found in the Kubernetes authentication docs):

+
    +
  • +

    Static Token Files

    +

    This method reads bearer tokens from requests and checks them against a CSV file provided to Kubernetes containing +three columns named token, username and uid. These tokens last indefinitely and the list can't be changed +without a restart of the API server. This makes this option unsuitable for production clusters.

    +
  • +
  • +

    Service Account Tokens

    +

    A service account is an authenticator that uses signed bearer tokens for request verification. +Service accounts can be given to the API server with a file containing PEM-encoded X509 RSA or +ECDSA private or public keys that verify the Service Account Tokens. +Service Accounts are normally created automatically by the API server and associated with the +pods through the ServiceAccount admission controller. Tokens are signed JSON Web Tokens, +that can be used as a Bearer Token or mounted into the pods for API server access. +Since Service Account Tokens are mainly used to allow workloads accessing the API server, +they're not really intended to authenticate users in production clusters.

    +
  • +
  • +

    X509 client certificates

    +

    Client certificate authentication can be enabled by providing a Certificate Authority +file to the API server via the --client-ca-file= option. The file contains one +or more CAs that a presented client certificate is validated against. +In this case the common subject name is used as the username for the request; +additionally, a group membership can be indicated with the certificates organization field. +These certificates are unsuitable for production use, because Kubernetes does not +support certificate revocation. This means user credentials can't be modified or +revoked without rotating the root CA and re-issuing all cluster certificates.

    +
  • +
+

As outlined, most internal authentication mechanisms of Kubernetes aren't really +usable in productive environments at the current time. Instead, external authentication +should be used in order to provide production-ready workflows. +The Kubernetes documentation lists a few examples for external authenticators, e.g.

+ +

All of these examples are useful to set up for an organization or can be used with +an already in-place solution. More information can be found in their respective +part of the Kubernetes documentation. +Most of these are good solutions for productive setups, since they enable easy +user management, access revocation and things like short-lived access tokens. +What will be used by your organization depends on the present setup and the use case.

+

Authorization

+

Authorization is done after the authentication step in order to check the rights +of a user within the system. Kubernetes authorizes API requests with the API server, +which evaluates requests against all policies in place and then allows or denies these requests. +By default, a request would be denied.

+

Kubernetes provides several authentication modes to authorize a request:

+
    +
  • +

    Node

    +

    The Node authorization mode grants permission to a Kubelet +based on the scheduled pods running on them. It allows a Kubelet to perform specific +API operations. The goal is to have a minimal set of permissions to ensure +the Kubelet can operate correctly. +Each Kubelet identifies with credentials belonging to the system:nodes group and +a username system:nodes:<node> against this authorizer.

    +
  • +
  • +

    ABAC (Attribute-based access control)

    +

    ABAC grants access rights based on policies dependent on attributes like +user attributes, resource attributes or environment attributes. +An example would be the resource attribute, which could limit access for a user +to only Pod resources.

    +
  • +
  • +

    RBAC (Role-based access control)

    +

    RBAC is a method of regulating access to the resources based on the roles of +individual users. A user therefore must have the ability to perform a specific set +of tasks with a set of resources based on his role. +Kubernetes implements Roles to accomplish this and binds these with Role Bindings +to a user in order to specify his permission set.

    +
  • +
  • +

    Webhook

    +

    Webhook authorization uses an HTTP callback to check the authorization of a user +against a URL provided for this mode. This externalises the authorization part +outside of Kubernetes.

    +
  • +
+

Most organizations and deployments work with RBAC, most often due to organizational or +customer-owner-relationship-like structures in place. +Nonetheless, neither ABAC, RBAC nor Webhook authorization can be recommended over the +other, since this all depends on the use case and required structure of a deployment. +Using at least one of these modes is recommended.

+

It is also recommended to enable the Node authorizer in order to limit Kubelet +permissions to a minimum operational state.

+

Admission Controllers

+

Admission controllers intercept requests to the Kubernetes API after the +authentication and authorization step, which validate and/or mutate the request. +This step is limited to create, modify and delete objects as well as custom +verbs, but other requests are not blocked. +Kubernetes provides multiple admission controllers, some of which are enabled by default.

+

One recommended admission controller is the NodeRestriction controller, +which limits the Node and Pod objects a Kubelet is allowed to modify to their own Node or +objects that are bound to them. It also disallows updating or removing taints and prevents changing +or adding labels with a node-restriction.kubernetes.io/ prefix. +Be aware that Kubelets will only be limited by this admission controller, if the user credentials +in the system:nodes group begin with a system:node:<nodeName> username. Administrators must therefore +configure their Kubelets correctly, if the NodeRestriction controller should be fully functional.

+

Kubelet access control

+

The Kubelet is the node agent that runs on each node. It registers with the API +server and ensures, that pods handed over to it are running and healthy according +to the specification provided to it. The HTTPS endpoint of a Kubelet exposes APIs +with varying access to sensitive data and also enables various levels +of performant operations enabling manipulation of node data and containers. +There is also a read-only HTTP endpoint that was used for monitoring a Kubelet and +its information. This port was also used by applications like kubeadm to check +the health status of the Kubelet. +This port is still available, but it is planned to be removed +in a future version. At the moment, the port is disabled by default since Kubernetes 1.10 +and shortly later also in kubeadm. +Different sources recommend disabling this port 4 5 due to possible +security risks, but since this standard recommends restricting accessibility of internal ports, +this port wouldn't be accessible from external networks. +It is nevertheless recommended to keep this port disabled, since Kubernetes also acknowledged +its risks and plans to remove it.

+

By default, the API server does not verify the Kubelets serving certificate and +requests to the HTTPS endpoint that are not rejected by other authentication +methods are treated as anonymous requests with the combination of name system:anonymous +and group system:unauthenticated. +This can be disabled by starting the Kubelet with the flag --anonymous-auth=false, +which return 401 Unauthorized for unauthenticated requests. +It is also possible to enable internal authentication methods for the Kubelet. +Possibilities include X509 client certificates as well as API bearer tokens to +authenticate against the Kubelet; details for these methods can be found in the Kubernetes docs.

+

After a request is authenticated, the authorization for it is checked, with the default +being AlwaysAllow. Requests should at best be authorized depending on their source, +so differentiation of access makes sense for the Kubelet; not all users should have +the same access rights. How access can be configured and delegated to the Kubernetes +API server can be found in the Kubernetes docs. The process works like the API request +authorization approach with verbs and resources being used as identifiers in roles and role bindings.

+

Pod security policies

+

Pod security plays a big part in securing a Kubernetes cluster, since bad actors could use pods to gain +privileged access to the systems underneath. The security risk here is mainly influenced by the capabilities +and privileges given to a container. It is therefore recommended to apply the principal of "least privilege", +which should limit the security risk to a minimum.

+

Kubernetes defines the Pod security standards +in the form of three policies that try to cover the range of the security spectrum. +These policies can be found in the following list and define a list of restricted fields that can only be +changed to a set of allowed values. An up-to-date list of these values can be found here.

+
    +
  • +

    Privileged

    +

    Unrestricted policy, providing the widest possible level of permissions. +This policy allows for known privilege escalations.

    +
  • +
  • +

    Baseline

    +

    Minimally restrictive policy which prevents known privilege escalations. +Allows the default (minimally specified) Pod configuration.

    +
  • +
  • +

    Restricted

    +

    Heavily restricted policy, following current Pod hardening best practices.

    +
  • +
+

Kubernetes also offers the Pod security admission controller, which enforces +the Pod security standards on a namespace level during pod creation. +The admission controller defines the standard to be used with the three levels +privileged, baseline and restricted. Each namespace can be configured to enforce +a different control mode, which defines what action the control plane takes +after a violation of the selected Pod security is detected.

+
    +
  • +

    enforce

    +

    Policy violations will cause the pod to be rejected.

    +
  • +
  • +

    audit

    +

    Policy violations will trigger the addition of an audit annotation to the event +recorded in the audit log, but are otherwise allowed.

    +
  • +
  • +

    warn

    +

    Policy violations will trigger a user-facing warning, but are otherwise allowed.

    +
  • +
+

Be aware, that enforce is not applied to workload resources, only to the pods created from their template.

+

Further measurements

+

While researching this topic, further measurements were considered such as container image verification, +distroless images, usage of ImagePolicyWebhook, network policy enforcement, +container sandboxing and prevention of kernel module loading. +Most of these were taken out of the document during writing due to either being the responsibility +of the clusters' user (and therefore not possible to implement for the provider), being more relevant +for high security clusters or changing the expected cluster environment too much, so that normally +expected operations could potentially not work in such a modified cluster. +These measurements will possibly be introduced in a future document about higher security clusters.

+

Standard

+

This standard provides the baseline security requirements for a cluster in the SCS context.

+

Kubernetes clusters MUST be updated regularly in order to receive bugfixes and security patches. +For more information refer to the SCS K8s Version Policy, +which outlines the version update policies of the SCS.

+

Hardening etcd is important due to it being a critical component inside a Kubernetes cluster. +etcd SHOULD be isolated from the Kubernetes cluster by being hosted on separate (virtual) machines. +If this is the case, access to these instances MUST be configured, so that only the API server and +necessary cluster components requiring access can access etcd. +Communication with etcd MUST be secured with TLS for both peer- and cluster-communication. +It is RECOMMENDED to use a CA separate from the one used for the Kubernetes cluster for etcd in +order to better control and issue certificates for clients allowed to access etcd. +ACL MUST be enabled for etcd, which allows better control of the access rights to specific key sets +for specific users. Authentication MUST be done via the Common Name (CN) field of the TLS client +certificates (since normal username-password-authentication isn't implemented for Kubernetes).

+

Kubernetes' endpoints MUST be secured in order to provide a small attack surface for bad actors. +It MUST NOT be possible to access Kubernetes ports from outside the internal network hosting the +Kubernetes cluster except for the ports of the API server (default 6443) and the NodePort Services +(default 30000-32767). The read-only Kubelet API port (default 10255), which is mostly used for monitoring, +SHOULD be disabled altogether if it isn't in use, mainly because the port is HTTP-only +and can deliver sensitive information to the outside. +Endpoints MUST be secured via HTTPS.

+

Securing Kubernetes via authentication and authorization is another important topic here. +Authentication is possible through multiple mechanisms, including Kubernetes-provided systems as well as external +authentication processes. +A cluster MUST implement at least two methods for authentication. One of these MUST be Service Account Tokens, in order +to provide full functionality to Pods. A second authentication mechanisms can be chosen depending on the requirements +of the provider and/or customer.

+

Authorization also can be provided through multiple mechanisms. +A cluster MUST activate at least two authorization methods, one of which MUST be Node authorization and another one +consisting of either ABAC, RBAC or Webhook authorization depending on the required use case. +We RECOMMEND RBAC due to it fitting most use cases and being very well documented, but your setup might require another solution.

+

In order to harden Kubelet access control, a Kubelet SHOULD only be accessible internally via HTTPS. This is already the +case for the Kubelet API, except for the read-only port, which is only available as HTTP. As mentioned earlier, this port +should be disabled. +Kubelets MUST disable anonymous request authentication to disallow non-rejected requests to go through as anonymous requests. +OPTIONALLY, X509 client certificate authentication or API bearer token authentication can be enabled. +Request authorization for the Kubelet MUST be delegated to the API server via Webhook authorization as it is recommended +by the Kubernetes documentation. +Additionally, the NodeRestriction admission controller MUST be activated in order to limit interactions between +different Kubelets by disallowing modification of Pod objects, if they're not bound to the Kubelet requesting the modification.

+

At last, Pod security standards in the form of policies MUST be activated for the cluster. The SCS REQUIRES at least +the Baseline policy with the Restricted policy CAN also be used. +The Pod security admission controller MUST also be activated in order to enforce these policies on a namespace level. +We RECOMMEND the enforce level to be used for this admission controller setup.

+

Conformance Tests

+

Conformance Tests will be written within another issue.

+ +
+ + \ No newline at end of file diff --git a/standards/scs-0218-v1-container-registry-for-scs-standard-implementation/index.html b/standards/scs-0218-v1-container-registry-for-scs-standard-implementation/index.html new file mode 100644 index 0000000000..d092a9d257 --- /dev/null +++ b/standards/scs-0218-v1-container-registry-for-scs-standard-implementation/index.html @@ -0,0 +1,336 @@ + + + + + +Container registry for SCS standard implementation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Container registry for SCS standard implementation

Introduction

+

A container registry is an infrastructure service to enable storing and accessing container +images. Images can be pushed to the registry by e.g. Continuous integration pipelines and +be pulled from by runtime environments like Kubernetes clusters.

+

In the standard document ["Requirements for container registries"], requirements for a +registry in the context of SCS were introduced. These are based on the principals, that +a usable project should be open source, active and feature-rich, especially with regard +to security.

+

Terminology

+

Cloud Service Provider (abbr. CSP) +Entity that provides scalable computing resources

+

Cloud Native Computing Foundation (abbr. CNCF) +Organization that hosts and develops open source projects for cloud native computing

+

Motivation

+

In order to provide a usable, complete experience for the SCS reference implementation, it must be decided +on a registry in accordance with requirements set by the ["Requirements for container registries"] standard +as well as other dependencies set by the SCS project, including the OSS requirements.

+

This document should finally lead to a decision about the container registry used as a reference implementation of the SCS container registry.

+

Evaluated projects

+

A few open source projects were evaluated for this document in order to find suitable candidates +for the SCS reference implementation. These projects can be found in the following list of +evaluated projects with their classified categories and comments. An initial assessment was +done with the checks for OSS healthiness +and a general overview of the features described in ["Requirements for container registries"], which enables +classifying the projects into one of three categories as follows:

+
    +
  • +

    ✔️ The project passed all OSS health checks and will be considered +further as a valid candidate.

    +
  • +
  • +

    The project passed almost all OSS health checks. +There is place for improvement, but the missing points are not crucial from the OSS +health check perspective. The project will be considered further as a valid candidate.

    +
  • +
  • +

    The project does not pass the OSS health checks. Some OSS health check +showstoppers have been found (e.g. open core software, not actively maintained). +The project is filtered at this stage and won't be considered further.

    +
  • +
+

The following list contains these projects with a small assessment listed below them:

+
    +
  • +

    ✔️ Harbor

    +
      +
    • Harbor project meets all "four opens" +
        +
      • Source code is open and available under the Apache 2 license
      • +
      • Community is open, structured and +well organized via workgroups and +various communications channels e.g. Slack, mailing lists, etc. +(#harbor Slack channel contains 3k+ members)
      • +
      • The development process is open via GitHub issues and well described in the +contributing +document
      • +
      • The design process is open via GitHub issues. Proposals are public. +The decision process is well described as well. The project's roadmap is +available in the roadmap document
      • +
      +
    • +
    • Maturity is on the CNCF graduation level. +CNCF graduated projects are considered to be stable, widely adopted and production-ready
    • +
    • Security +
        +
      • The security disclosure and response policy is well described in the project's +security document
      • +
      • The code is reviewed within a standard PR process
      • +
      +
    • +
    • Activity +
        +
      • 250+ contributors, 4k+ forks, 13k+ GitHub stars
      • +
      • The project has been adopted +by many companies that run Harbor in their production environments
      • +
      • The project collaborates with other communities and projects +(see Partners of Harbor section of the +project's website)
      • +
      • The project is visible and actively contributes to various conferences, e.g. +FOSDEM 22, +KubeCon Europe, etc.
      • +
      +
    • +
    • Lock-in risk assessment +
        +
      • The project's maintainers +document shows that there are a sufficient number of core +maintainers/contributors that differ over various companies, we therefore deem +the lock-in risk arising from a single point of failure to be low
      • +
      +
    • +
    +
  • +
  • +

    ✔️ Dragonfly

    +
      +
    • Dragonfly project meets all "four opens" +
        +
      • Source code is open and available under the Apache 2 license
      • +
      • Community is open +organized via multiple channels e.g. Slack, mailing lists, etc. +(#dragonfly Slack channel contains ~50 members)
      • +
      • The development process is open via GitHub issues and well described in the +contributing document
      • +
      • The design process is open via GitHub issues. The project's roadmap is available in +the project's webpage
      • +
      +
    • +
    • Maturity is on the CNCF incubating level +CNCF incubating project is considered stable and used in production by users with +the healthy pool of contributors
    • +
    • Security +
        +
      • The security disclosure is handled via a dedicated email address
      • +
      • The code is reviewed within a standard PR process
      • +
      +
    • +
    • Activity +
        +
      • 30+ contributors, 100+ forks, 1k+ GitHub stars
      • +
      • The project has been adopted +by many companies that run Harbor in their production environments
      • +
      • The project is visible and actively contributes to various conferences, +e.g. KubeCon North America, +KubeCon Europe, etc.
      • +
      +
    • +
    • Lock-in risk assessment + +
    • +
    +
  • +
  • +

    Project Quay

    +
      +
    • Project Quay meets all "four opens" +
        +
      • Source code is open and available under the Apache 2 license
      • +
      • Community is open organized via mailing +list and IRC
      • +
      • Development process is open via JBoss JIRA +issues and well described in the governance document
      • +
      • Design process is open via JBoss JIRA +issues. The project's roadmap is available on the project's webpage
      • +
      +
    • +
    • Maturity +
        +
      • Project Quay is an open-source project that started ~9 years ago. +It powers Red Hat enterprise products Red Hat Quay and Quay.io, which are used in +a productive way by many. Therefore, the project's maturity is at the good level
      • +
      +
    • +
    • Security +
        +
      • The security disclosure is handled via a dedicated email address
      • +
      • The code is reviewed within a standard PR process
      • +
      +
    • +
    • Activity +
        +
      • 50+ contributors, 200+ forks, 2k+ GitHub stars
      • +
      • The project has been used by many companies that +run Quay in their production environments
      • +
      +
    • +
    • Lock-in risk assessment +
        +
      • The project's owners/maintainers list is not publicly available and is stored in +the downstream repository. +Therefore, it is hard to distinguish the risk of project failure caused by low +diversity across the companies. This should be improved.
      • +
      +
    • +
    +
  • +
  • +

    Keppel

    +
      +
    • The project seems to be not widely used in a productive way and also the activity +around is currently not on a good level (5+ contributors). The development +process as well as the design process seem to be open, but neither of them are +documented yet.
    • +
    +
  • +
  • +

    Nexus

    +
      +
    • Nexus is an open core software that offers paid pro version with advanced features
    • +
    +
  • +
  • +

    JFrog

    +
      +
    • JFrog Artifactory is shipped as an open core software +with limited features. The software is primarily offered as a paid pro version
    • +
    +
  • +
  • +

    Kraken

    +
      +
    • It seems that the project is not actively maintained as is discussed in the related +project's issue
    • +
    +
  • +
  • +

    Portus

    +
      +
    • It seems that the project is not actively maintained as is discussed in the related +project's issue
    • +
    +
  • +
+

Deeper look into selected projects

+

In the previous section, a wide range of open-source container registry projects (Quay, Harbor, Dragonfly, +Keppel, Portus, Kraken, etc.) has been carefully evaluated based on the two main +factors: the open-source health and range of supported features.

+

The open-source software health is crucial and container registry implementation should +pass it. It evaluates several important metrics of an open source software like whether the code/community/development/design +is fully open or whether the project's maturity, security, and activity are on the desired +level. This check also evaluates the lock-in risk due to possible single points of +failure or internal project conflicts and several other aspects. +Overall, three projects passed the OSS health checks:

+ +

The above projects were then evaluated from the "supported features" perspective. +The document ["Requirements for container registries"] provides a "Required and desirable features check", which +provides desired feature sets for open-source container registry implementations according to +SCS requirements (and nice-to-haves). The list of required features is quite long and contains +features that are primarily focused on security (authentication, vulnerability scanning, content trust, and validation, etc.), +scalability (HA mode, registry replication, p2p integration, etc.) and visibility (monitoring). +These requirements should ensure that the selected container registry implementation +could be offered by CSPs as a secure and enterprise-ready solution.

+

The following section compares the selected projects Dragonfly, Quay, and Harbor.

+

Dragonfly is a healthy open-source project with a growing community +and CNCF incubating maturity level. It is considered stable, and widely used by many +companies in their production environments. We currently see that it is not as +feature-rich as Harbor or Quay, hence it is not considered the best choice here. +It seems, that its main aim (currently) is to offer (an efficient, stable, and secure) +container distribution solution based on p2p technology. This improves download +efficiency and saves bandwidth across CSPs. It also offers integration possibilities +that allow one to use it as a p2p distribution network via a "preheat" API. This +integration was implemented in the Harbor project via Dragonfly "preheat" adapter, and +both parties may benefit from the integration. Harbor profits from Dragonfly's p2p +distribution capabilities and on the other hand the Dragonfly project profits from +Harbor's feature-rich container registry "frontend".

+

Quay is an open-source project maintained by Red Hat. Its OSS health is +on a good level, the surrounding community is growing, and we consider it to be quite +mature as it powers enterprise solutions like Red Hat Quay and Quay.io. +Besides this, there is still a place for OSS health improvement. It is hard to +distinguish the risk of project failure caused by low diversity across the companies +because the project's owners/maintainers list is not publicly available and is stored in +the Red Hat private repository. +Its feature set is impressive and this project fulfills all must-haves defined in +this document. Quay gives you security over your repositories with image +vulnerability scanning (Clair integration), content validation (Cosign integration), +and access controls. Harbor stands out here as it allows users to use also project Trivy +for vulnerability scanning. Project Quay also provides a scalable open-source +platform to host container images across any size organization. One drawback in +comparison to Harbor is that the proxy cache feature is still marked as a +Technology Preview, +hence this feature may not be completely production-ready yet. On the other hand, +the project Quay supports building Dockerfiles +using a set of workers on e.g. Kubernetes. Build triggers, such as GitHub webhooks +can be configured to automatically build new versions of repositories when new code is +committed. This feature is not supported by the Harbor project.

+

Harbor is an outstanding open-source, community-led project with fully open and +well-documented processes. Its large and thriving community powers the fast-growing +feature set and attracts more and more developers and companies to active contributions. +Harbor's CNCF graduation in 2020 made it one of the best choices for enterprise +customers that want to operate container registries securely and in a large scale. +Its community size, landscape, and CNCF graduation make a significant difference in +comparison to Quay's open-source health capabilities. +The list of supported features is also impressive. This project fulfills all must-haves +defined in this document and overcome project Quay with a production-ready proxy cache +feature and more options that the user may use in case of image vulnerability scanning. +In addition, Harbor profits from p2p distribution capabilities via integration of p2p +solutions like Kraken and Dragonfly. It is worth mentioning that Harbor, by design, +operates on a single storage backend (e.g. S3). It means that the storage of container +images is shared even when the Harbor instance serves multiple tenants. The same +approach is used in Quay and Dragonfly projects, but e.g. Keppel uses multi-tenant-aware +storage drivers instead so that each customer gets their own separate storage backend. +CSP that considers offering container registry "as a service" solution based on Harbor +should be aware of this shared storage backend architecture.

+

In the following table, the feature sets of the evaluated projects that passed the OSS health state +are listed and matched against. This enables a better understanding of the decision-making for this document.

+
FeaturesHarborQuayDragonfly
Audit Logs
Authentication of system identities✓ Robot Accounts✓ Robot Accounts
Authentication of users✓ Local database, LDAP, OIDC, UAA✓ Local database, LDAP, Keystone, JWT✓ Local database
Authorization
Automation✓ Webhooks (HTTP, Slack)✓ Webhooks (HTTP, Slack, E-mail ...), building images
Vulnerability scanning✓ Trivy, Clair✓ Clair
Content Trust and Validation✓ Cosign✓ Cosign
Multi-tenancy✓ (not on the storage level)✓ (not on the storage level)✓ (not on the storage level)
Backup and restore
Monitoring✓ Prometheus metrics, Tracing✓ Prometheus metrics, Tracing (only for Clair)✓ Prometheus metrics, Tracing
HA mode
Registry replication
Proxy cache✓ Feature is in the technology preview stage (non production ready)
Quota management✓ Based on storage consumption✓ Based on storage consumption
Garbage collection✓ Non-blocking✓ Non-blocking
Retention policy✓ Multiple tag retention rules✓ Only tag expiration rules
Additional supported artifacts✗ (only OCI artifacts)✗ (only OCI artifacts)✓ Maven, YUM
Integration possibilities✓ Dragonfly (P2P), Kraken (P2P)✓ Harbor, Nydus, eStargz
Deployment capabilities✓ Docker-compose, Helm chart, Operator✓ Docker-compose, Operator✓ Docker-compose, Helm chart
Administration capabilities✓ Terraform, CRDs, Client libraries✓ Ansible, Client libraries✓ Client libraries
+

Notes:

+
    +
  • Automation: Harbor should support webhooks following CloudEvents spec in the next release
  • +
  • Content Trust and Validation: Harbor announced the deprecation of Notary +integration, hence it is not mentioned in the table
  • +
  • Multi-tenancy: Harbor, Quay, as well as Dragonfly, operates on a single storage +backend (e.g. S3), i.e. the storage of container images is shared between tenants
  • +
  • Additional supported artifacts: Harbor announced the deprecation of Chartmuseum +integration, hence it is not mentioned in the table
  • +
+

Decision

+

Based on the requirements laid out in ["Requirements for container registries"], the OSS health check +and the possible software solutions presented in this document, it was decided to use the Harbor project +as the container registry for the SCS reference implementation.

+ +

"Requirements for container registries" +harbor +dragonfly +projectquay

+ + \ No newline at end of file diff --git a/standards/scs-0219-v1-kaas-networking/index.html b/standards/scs-0219-v1-kaas-networking/index.html new file mode 100644 index 0000000000..88fb375161 --- /dev/null +++ b/standards/scs-0219-v1-kaas-networking/index.html @@ -0,0 +1,77 @@ + + + + + +KaaS Networking Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

KaaS Networking Standard

Introduction

+

Kubernetes defines a networking model that needs to be implemented by a separate CNI plugin. +Beyond basic connectivity within the cluster, however, there are many networking features that are specified but optional. +Some of these optional features provide vital functionality, such as the NetworkPolicy API and the Ingress API.

+

This standard specifies a minimal set of networking features that users can expect in clusters created by an SCS-compliant KaaS provider.

+

Terminology

+

The following terms are used throughout this document:

+
TermMeaning
KaaS, managed KubernetesKubernetes as a Service, automated on-demand deployment of Kubernetes clusters.
CSPCloud Service Provider, the provider of the KaaS infrastructure.
CNIContainer Network Interface, a standardized networking interface for container runtimes.
CNI plugin, networking pluginKubernetes bindings for a CNI implementation, translates Kubernetes API concepts into more basic container networking concepts.
network policyA set of rules to restrict network traffic in a Kubernetes cluster.
+

Motivation

+

KaaS providers will typically support aditional networking functionality beyond basic Kubernetes networking. +The specific range of features depends on the used CNI plugin, but may also be extended by additional operators. +Users may expect certain optional functionality, so we should define a baseline feature set that has to be available in an SCS-compliant KaaS cluster.

+

Design Considerations

+

The Kubernetes API can be extended arbitrarily. +Many CNI plugins will define custom resources to enable functionality that is not covered in the official API specification. +Sometimes they will even reuse names from different API groups, such as NetworkPolicy, which exists in the basic networking.k8s.io/v1 API, but also in projectcalico.org/v3.

+

To avoid any ambiguity, we should therefore be explicit about the API groups and versions of resources. +We should also avoid mandating third-party API extensions, to avoid dependencies on specific third-party software and keep the standard as generic as possible.

+

Options considered

+

NetworkPolicy API

+

Kubernetes network policies are used to restrict network traffic between pods in a cluster, but also between pods and external network resources. +The policy rules can filter based on port and address ranges, but also on Kubernetes-specific target attributes such as namespaces and labels. +They must be implemented by the CNI plugin, and though they are widely supported, they are still technically optional, and there are some lightweight networking plugins, such as Flannel, that are not enforcing them.

+

Nonetheless, network policies are widely used and most users will expect them in a managed Kubernetes cluster. +The wide, but varying support among CNI plugins makes them a good target for SCS standardization.

+

Default Network Policies in Namespaces

+

Basic network policies are namespaced resources, and can only filter traffic to and from pods in their own namespace. +In a newly created namespace without policies the default behavior will apply, which is to not restrict traffic at all.

+

It can be desirable to automatically create default network policies in new namespaces, using a policy operator such as Kyverno. +A CSP could provide such an operator and offer a number of default policies, like blocking connections to other namespaces by default, or blocking access to the OpenStack metadata service.

+

Any user with permissions to manage their own network policies in a namespace will of course be able to remove or modify any default network policies in that namespace. +CSP-provided network policies should thus only be viewed as a safety default, and should only be deployed if they are actually beneficial to users.

+

AdminNetworkPolicy API

+

An alternative to automatically created default network policies are API extensions that allow cluster-wide networking rules. +Some CNI plugins have implemented such extensions, e.g. Calico's GlobalNetworkPolicy and Cilium's CiliumClusterwideNetworkPolicy.

+

The Kubernetes Network Special Interest Group is currently working on an official API extension to cover this functionality. +This API extension introduces the new AdminNetworkPolicy and BaselineAdminNetworkPolicy resources, which represent cluster-wide network policies with respectively higher or lower precedence than namespaced network policies.

+

This API is also a good candidate for standardization because it consolidates a number of vendor-specific workarounds to limitations of the NetworkPolicy API. +It has not been stabilized yet, so currently we can at most recommend CNI plugins where there is ongoing work to support these features.

+

Ingress API

+

The Ingress API allows the external exposure of HTTP/HTTPS-based services running in the cluster. +Unlike the L3/L4-based LoadBalancer Service type, Ingress provides L7 load balancing, HTTP routing, and TLS termination for services. +This functionality can be provided within the cluster by a pod-based ingress controller such as ingress-nginx, that exposes Ingress resources as Services.

+

However, there are also Ingress controllers that integrate with underlying infrastructure and may help to reduce overhead. +Examples for this are the Cilium CNI plugin, which comes with built-in Ingress support, and the Octavia Ingress controller, which may be a good choice if OpenStack Octavia is already used to provide L3/L4 load balancing.

+

The CSPs that manage the underlying infrastructure can of course make the best choice for such an integrated Ingress controller, so they should be encouraged to do so. +Even with a CSP-provided default Ingress controller present, users will be able to use alternative Ingress controllers by creating a new IngressClass, which can then be referenced in Ingress resources.

+

Decision

+

CSPs MUST provide a network plugin that fully supports NetworkPolicy resources in the API version networking.k8s.io/v1. +CSPs SHOULD provide a network plugin that supports or is working on support for the AdminNetworkPolicy and BaselineAdminNetworkPolicy resources of the policy.networking.k8s.io API group, in their latest version, up to v1.

+

CSPs SHOULD offer the option for a managed, networking.k8s.io/v1-compliant Ingress controller and a default IngressClass resource for this controller.

+

CSPs MAY add default networking restrictions, using either networking.k8s.io/v1-compliant NetworkPolicy resources with a policy operator, or alternatively any cluster-wide network policy extensions provided by the CNI plugin.

+

Conformance Tests

+

Required support for network policies will be tested using the upstream e2e tests via Sonobuoy.

+ + \ No newline at end of file diff --git a/standards/scs-0219-w1-kaas-networking/index.html b/standards/scs-0219-w1-kaas-networking/index.html new file mode 100644 index 0000000000..80ea9db630 --- /dev/null +++ b/standards/scs-0219-w1-kaas-networking/index.html @@ -0,0 +1,39 @@ + + + + + +KaaS Networking Standard: Implementation Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

KaaS Networking Standard: Implementation Notes

List of compliant CNI Plugins

+

The Kubernetes Network Policy API working group maintains a list of work-in-progress implementations of the AdminNetworkPolicy and BaselineAdminNetworkPolicy resources. +Besides their own proof-of-concept implementation of kube-network-policies, at the time of writing they list the following CNI plugins:

+ +

All of these plugins also implement the basic NetworkPolicy API, and are therefore compliant both with the standard's requirements and recommendations.

+

The CNI plugin Flannel does not support network policies by itself, but can be combined with Calico for policy enforcement. +This configuration is known as Canal and will likely profit from Calico's support for AdminNetworkPolicy.

+

There are more CNI plugins that support the NetworkPolicy API, but are not known to work on support of the AdminNetworkPolicy extensions. +As such they are still compliant with the current version of the Standard. +However, these seem to be either vendor-specific, like the Azure CNI, or unmaintained, like Weave.

+ + \ No newline at end of file diff --git a/standards/scs-0300-v1-requirements-for-sso-identity-federation/index.html b/standards/scs-0300-v1-requirements-for-sso-identity-federation/index.html new file mode 100644 index 0000000000..c6f126fc22 --- /dev/null +++ b/standards/scs-0300-v1-requirements-for-sso-identity-federation/index.html @@ -0,0 +1,232 @@ + + + + + +Requirements for SSO identity federation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Requirements for SSO identity federation

Introduction

+

Our assumption is that there are use cases, where CSPs would like to be able to +let customers access their SCS based services by identifying themselves with +credentials that are stored and managed external to the CSP's SCS installation.

+

This is based on the observation that prospective customers of an SCS based CSP +sometimes already come equipped with an IAM solution of their choice, either on +premises or e.g. as an external 3rd party cloud service. To ease onboarding of +customer employees (or e.g. customer contracted 3rd party admin staff) as SCS +users, it would be good to be able to consume these external identities in SCS.

+

For customers this avoids the necessity to explicitly maintain an additional +dedicated account in SCS and this also reduces what SCS needs to do with +respect to taking care of persisting user account information.

+

To put it in other words, in SCS we would like to be able to delegate +authentication to external identity providers and map those users to roles in +SCS that can be used for authorization decisions when users access SCS services.

+

In addition to user identities there we also see the necessity to support the +use of "machine identities" (aka "workload identities" or "service accounts"). +These will probably be SCS-local accounts and have for example the purpose +to grant CaaS workload access to storage resources served by the infrastructure +layer. Exact architectural details for this are still in active discussion, +but it is anticipated that the IdP component should be very useful in +facilitating the integration.

+

Motivation for this document

+

SCS has multiple service layers, like IaaS and CaaS, both of which running their +own technological stack with specific internal models of accounts and +authorization.

+

One thing these services have in common, is that they are able +to use SSO protocols like OAuth 2.0 or OpenID Connect (OIDC) on top of it to +delegate authentication. They are service providers (SAML terminology) and can +be relying on parties (OIDC terminology) of a protocol compliant identity provider +(IdP).

+

So the idea is, to run an SSO IdP as part of SCS to provide a dedicated point +of entry for identities, which the SCS service layers can use as a common +interface to consume external user identities.

+

The purpose of this document is to specify what requirements a specific +technical IdP implementation (i.e. software solution) needs to fulfill +in the context of SCS.

+

Design Considerations

+

As a central service for identity handling, the IdP +service needs to be robust and reliable.

+

Customers shall be able to access self-service, so that +they can make reasonable adjustments e.g. to role mapping. +At the time of writing this document it's still undecided +if SCS has the requirement of a dedicated "self-service" service +that serves as a frontend to provision and re-configure +customer specific data, abstracting e.g. from IdP specific +user interface particularities.

+

Keycloak is currently being deployed as part of the IaaS reference implementation. +Technically this IdP component shall be shifted from the management +plane to be run on the basis of a "minimal" Kubernetes (e.g. K3S), +e.g. to make use of the "self-healing" and scaling features achievable +with that.

+

So one of the considerations is if the solution will work well on a +K8S environment. The instances will need to share configuration +(probably via the shared backend database) as well as session state. +Maybe one is better prepared for horizontal scaling than the other.

+

Options considered

+

Keycloak

+

Keycloak is a commonly used IdP solution implemented in Java. +It is developed as an open source community project. +Red Hat uses it as upstream source for their Red Hat SSO product +and is also listed as sponsor of the project. +Starting with version 17 the default distribution is based on +Quarkus instead of WildFly/JBoss.

+

The project maintains several means of community contributions +as listed on the community section +of the project website. It uses GitHub issues +to track development.

+

It offers a REST API for administration and there's a separately maintained +3rd party python module as well as ansible support for it. Both of these are +downstream of Keycloak itself and may thus not always be feature complete and +suffer latency with respect to getting adjusted to upstream changes.

+

It offers support for commonly used SSO protocols and is "reasonably" fast +in adopting to protocol standard changes and extensions. This has been +observed in the case of logout support (backend and frontend variants) in OIDC.

+

It offers a concept of "Identity Brokering", where Keycloak is not just IdP +but also "client" to other IdPs. This allows daisy-chaining of identity +federation. In this configuration it can work as a point of protocol +transition between different supported SSO protocols (SAML, OAuth 2.0, etc.).

+

Beyond this capability of using other IdPs as identity sources, it also supports +using classic LDAP based IAM services as backend (OpenLDAP and Active Directory, +e.g.).

+

Keycloak's implementation makes some design decisions, that are specific +to it and have consequences for clients of the service. E.g. Keycloak +has a concept of management "Realms", which have their own specific +set of HTTP API entrypoints, both for administration and for IdP +requests.

+

Commonly Keycloak realms can be used to map them 1:1 to user domains, +but since Keycloak supports configuring multiple backend IdPs in a +realm to be used for "Identity Brokering", there is always the +possibility to create a kind of "proxy" realm to provide a single +standard set of HTTP API endpoints for SSO clients (service providers) +to avoid the need to frequently extend/reduce client service configuration +whenever a new IdP federation needs to be added to Keycloak to onboard +a new customer. This is relevant for services like OpenStack Keystone, +which currently cannot be easily reconfigured for new SSO endpoints +without restarting the service, making the service unavailable for +a short span of time and increasing risk connected with service restarts.

+

Since version 17, Keycloak claims that it's capability for +"cloud native" deployments on Kubernetes has improved.

+

Keycloak is offering a documented REST API +for all aspects of its administration interface.

+

For storage of Keycloak configuration and local user metadata +(e.g. from which external IdP a user account originally came from) +Keycloak supports several SQL backends through JDBC. Thus, +it can be hooked up to a Postgres Database or to a +MariaDB/Galera cluster e.g.

+

As of April 11, 2023, Keycloak joined the CNCF as an incubating project.

+

Zitadel

+

Zitadel is a newer implementation of an SSO IdP. +It is implemented in Go and under active development and maintained by ZITADEL.

+

The project is open for community contributions +to all parts of the ecosystem. +Feature requests and bugs being tracked on GitHub for development. +Community questions can be asked in the public chat or via GitHub Discussions. +ZITADEL offers support for the commonly used authentication and authorization protocols such as OIDC, OAuth2, SAML2. +It is a compliant and certified OpenID Connect provider with support for various Grant Types for both human users and machine users. +Compared to Keycloak SPIs, ZITADEL offers Actions to customize and integrate (eg, calling external APIs, Webhooks, customizing pre-built workflows, customizing tokens) +Actions are executed at runtime and can be maintained independently of platform. +Identity brokering (OIDC, SAML, JWT) can be configured system-wide or for each organization with templates. +Users will be created just in time for audit purposes and linked to the external identity provider. +Users can have multiple identity providers linked to their profile.

+

It came to attention of the SCS project because it offers a +fresh take of an organization focussed data model, which has +the potential to simplify IdP federation to SCS customer domains +in the following areas:

+
    +
  • For client services (single set of HTTP API endpoints).
  • +
  • For SCS operators for provisioning customer organizations +and robust configuration by using templated client, role and mapping +configuration.
  • +
  • For SCS customers for a robust user experience for self servicing.
  • +
+

The concept for Delegated Access Management +reduces the management overhead compared to isolated realms. +Projects (Applications + Roles) can be maintained by one organization and delegated to be used by other Organizations. +Managers that receive granted Projects can assign users permissions to use the project.

+

Zitadel is offering REST APIs +for multiple areas of use and configuration.

+

It recently also added support for the Device Authorization Grant, +which, at time of writing, is a feature that is relevant +for SCS to be able to use OpenStack CLI and APIs with federated +identities (Device Authorization Grant).

+

Support for consumption of LDAP backends is available since Zitadel v2.23.0 +(see this guide).

+

ZITADEL supported backend databases are CockroachDB and PostgreSQL.

+

For production setups it is recommended +to use Kubernetes (or similar like Knative) and CockroachDB.

+

At time of writing a PoC "spike" is done to assess and verify the hopes +connected with Zitadel in the context of the SCS testbed.

+

Currently, Zitadel is lacking the possibility to easily add custom claims. +It supports urn:zitadel:iam:user:metadata, but that is more suitable +towards Kubernetes and cannot be parsed with the OpenStack mapping mechanism. +There is work going on which +may be suitable to resolve this issue. +An approach based on Zitadel actions is also currently evaluated. +OpenStack currently makes use of custom claims to pass openstack-default-project +from the IdP to OpenStack. Combined with federation to external customer managed IdPs +this should allow customers to manage settings like these in their own IAM.

+

Open questions

+
    +
  • How would we implement testbed deployment support for Zitadel? +
      +
    • e.g. wsgi-keystone.conf would need to look different. One template covering both options?
    • +
    • e.g. steps like openstack federation protocol create would probably be different.
    • +
    +
  • +
  • Should we support both as options? +
      +
    • What's the benefit?
    • +
    • How would we allow SCS operators to choose?
    • +
    +
  • +
  • Do we need some kind of SWOT analysis to come to a decision?
  • +
+

Decision

+

SCS wants to make use of an IdP as part of the reference implementation. +To move forward with topics of configuration and mapping of roles in a +OAuth2 federation scenario as well as questions of token lifecycles etc. across +the federation stack it makes sense to focus on one IdP implementation at a +given time. Both considered options seem to be potentially viable, but ultimately, +a decision should be made, even if there are no strict/strong reasons for +dismissing either option in particular.

+

The project's current choice is Keycloak for the following reasons: +Keycloak currently supports the OAuth 2.0 grants that SCS wants to make +use of (e.g. Device Authorization Grant). It is the implementation for +which integration is currently documented in OpenStack and implemented +in kolla-ansible. SCS currently deploys Keycloak and the IAM team has +most hands-on experience with it, e.g. when it comes to collateral questions +like how to make TLS and signing certificates available to the IdP that shall +be used in federation to external domains.

+ + +

Conformance Tests

+

Conformance Tests, OPTIONAL

+ + \ No newline at end of file diff --git a/standards/scs-0301-v1-naming-conventions/index.html b/standards/scs-0301-v1-naming-conventions/index.html new file mode 100644 index 0000000000..b501765850 --- /dev/null +++ b/standards/scs-0301-v1-naming-conventions/index.html @@ -0,0 +1,89 @@ + + + + + +Naming for domains/groups/roles/project when onboarding new customers | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Naming for domains/groups/roles/project when onboarding new customers

Introduction

+

When CSPs try to enroll a new customer they encounter themselves in +a situation where they have to choose names for the openstack domain, +project and user.

+

Motivation

+

Create a naming convention to use during the provisioning of the users and +groups through an openstack domain.

+

Design Considerations

+

OPTIONAL

+

Options considered

+

PS approach to naming

+

For naming the customers the suggestion from PS is the following:

+

A prefix will be used to differentiate domain, project and user in +the openstack environment. The project name is also added as a suffix.

+

So the onboarding tool will create the following structure for a new +customer onboarded in the system.

+
domain: d<customer_id>
project: p<customer_id>-<project_name>
user: u<customer_id>-<user_name>
+

For the customer also a domain admin group and a project admin group are +created. Please note that, at the time of writing, PCO is not making any +use of OpenStack domains to isolate customers. So, for the scope of this +document, the term "domain admin" is used in a conceptual way rather than +referring to the specific OpenStack implementation. For the scope of this +document "domain admins" can do things like creating projects, creating +users and granting users access to some projects (within the domain of +course). "Users" can create and view resources within the projects that +they have been granted access to by the "domain admin". +These groups use the prefix "gd" for domain group and "gp" for group project +and are build like the following:

+
domain admin group: gd<customer_id>-member
project admin group: gp<customer_id>-<project_name>-member
+

For the creation of a domain a new domain admin group is created.

+
openstack domain create d000001
openstack group create gd000001-member
+

When a project is created a new admin group for that project is created.

+
openstack project create p000001-scs_dev_project
openstack group create p000001-scs_dev_project-member
+

After the creation of a project it is necessary to assign roles to the +new groups.

+
openstack role add --group gd000001-member --project p000001-scs_dev_project $role
openstack role add --group gp000001-scs_dev_project-member --project p000001-scs_dev_project $role
+

For the creation of regular non admin users, the accounts will be added +to the "domain admin" group to give them access to all projects within +the domain.

+
openstack user created u000001-user1
openstack group add user gd000001-member u000001-user1
+

In the case of machine accounts, they are only added to the specific +"project admin" groups.

+
openstack user created u000001-svc_user_project
openstack group add user gp000001-scs_dev_project-member u000001-svc_user_project
+

In case of using federation, there are suggestions to the namings within Keycloak.

+

The realms in Keycloak for each customer would be the same as the customer. e.g. The Keycloak realm for "Customer A" +will be called "Customer A".

+

There should be an OIDC client in each customer realm to allow the federation to the Proxy realm. Currently called OSISM +on the testbed.

+

On the proxy realm, it's needed to add this new customer realm as an identity provider. During the creation of the identity +provider for "Customer A", the field "Alias" should be set to <customer-id>. This will make that the users federated from +realm "Customer A" to the proxy realm to be prefixed to avoid naming collisions, e.g. d${ALIAS}-${CLAIM.preferred_username}.

+

Also, on the identity federation there should be configured to store the <customer-id> from that realm into the users. So it +can be sent to Keystone mapping to use it as gd<customer-id>-member and gp<customer-id>-<project_name>-member. There is +also the necessity of a mapper to send the openstack-default-project.

+

Add the additional mappings for roles and groups as necessary to get the attributes from the customer realm into the OIDC +userinfo that is put into the OIDC to the proxy realm and from there to Keystone.

+

Option 2

+

Option 2 description

+

Open questions

+

RECOMMENDED

+

Decision

+

Decision

+ +

Related Documents, OPTIONAL

+

Conformance Tests

+

Conformance Tests, OPTIONAL

+ + \ No newline at end of file diff --git a/standards/scs-0302-v1-domain-manager-role/index.html b/standards/scs-0302-v1-domain-manager-role/index.html new file mode 100644 index 0000000000..367e5ecd69 --- /dev/null +++ b/standards/scs-0302-v1-domain-manager-role/index.html @@ -0,0 +1,195 @@ + + + + + +Domain Manager configuration for Keystone | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Domain Manager configuration for Keystone

Introduction

+

SCS Clouds should provide a way to grant Domain Manager rights to SCS Customers which provides IAM self-service capabilities within an OpenStack domain. +Such capabilities should enable the SCS customer to manage identity resources within their domain without involving the provider of the cloud. +To avoid conflict with the unscoped admin role in OpenStack we want to refer to this new persona as "Domain Manager", introducing the manager role in the API for domains.

+
info

The Domain Manager functionality will be a native part of the official OpenStack beginning with release 2024.2 ("Dalmatian").

To implement the Domain Manager in SCS clouds using an OpenStack release older than 2024.2, please refer to the supplemental implementation notes for this standard. +The implementation notes document describes an alternative implementation that can be used for OpenStack 2024.1 and older releases.

+

Terminology

+

The following special terms are used throughout this standard document:

+
TermMeaning
RBACRole-Based Access Control1 established by OpenStack Keystone
projectOpenStack project as per Keystone RBAC
userOpenStack user as per Keystone RBAC
groupOpenStack group as per Keystone RBAC
roleOpenStack role as per Keystone RBAC
domainOpenStack domain as per Keystone RBAC
IAMidentity and access management
personaAbstract and conceptual role of a user in terms of IAM
IAM resourcesprojects, users, groups, roles, domains as managed by OpenStack Keystone
CSPCloud Service Provider, provider managing the OpenStack infrastructure
cloud adminOpenStack user belonging to the CSP that possesses the admin role
+

Motivation

+

In the default configuration of Keystone, only users with the admin role may manage the IAM resources such as projects, groups and users and their relation through role assignments. +The admin role in OpenStack Keystone is not properly scoped when assigned within a domain or project only as due to hard-coded architectural limitations in OpenStack, a user with the admin role may escalate their privileges outside their assigned project or domain boundaries. +Thus, it is not possible to properly give customers a self-service functionality in regard to project, group and user management with the default configuration.

+

To address this, this standard defines a new Domain Manager persona implemented using a domain-scoped manager role in conjunction with appropriate Keystone API policy adjustments to establish a standardized extension to the default Keystone configuration allowing for IAM self-service capabilities for customers within domains.

+

Desired Workflow

+
    +
  1. The cloud admin deploys the Domain Manager policy configuration for Keystone as per this standard if it is not already applied.
  2. +
  3. The cloud admin creates the desired domains for the customers for which IAM self-service capabilities are desired.
  4. +
  5. The cloud admin creates one or more users within each of the applicable domains and assigns the manager role for a certain domain to them. These users represent the Domain Managers of the corresponding domain.
  6. +
  7. The customer uses the Domain Manager users to manage (create, update, delete) users, projects, groups and corresponding role assignments within their domain.
  8. +
+

Design Considerations

+
    +
  • the Domain Manager persona MUST support managing projects, groups and users within a specific domain
  • +
  • the Domain Manager persona MUST be properly scoped to a domain, it MUST NOT gain access to resources outside its owning domain
  • +
  • the Domain Manager persona MUST NOT be able to manipulate existing roles or create new roles
  • +
  • the Domain Manager persona MUST only be able to assign specific non-administrative* roles to their managed users where the applicable roles are defined by the CSP
  • +
  • Domain Managers MUST NOT be able to abuse the role assignment functionalities to escalate their own privileges or those of other users beyond the roles defined by the CSP
  • +
+

* "non-administrative" in this context means this excludes the role "admin" and any comparable role that grants permissions beyond domain and tenant scope. +Since the "manager" role as defined in this standard is domain-scoped for a Domain Manager, it does not count as administrative.

+

Options considered

+

Re-using the existing admin role

+

As role assignments can be scoped to project, groups and domains the most obvious option would be to assign the existing admin role to users representing Domain Managers in a scoped fashion.

+

However, due to architectural limitations2 of the existing OpenStack implementation of roles, the admin role has a special meaning reaching beyond the RBAC checks done by Keystone and other OpenStack components. +This results in special permissions being granted to users possessing the role which ignore the project or domain scope of the role assignment. +This poses severe security risks as the proper scoping of the admin role is impossible. +Due to this, this approach was discarded early.

+

Upstream (OpenStack) is in the process of addressing this across the services, but it has not been fully implemented yet, especially for domains3.

+

Introducing a new persona and role with API policy changes

+

OpenStack Keystone allows for new roles to be created via its API by administrative users. +Additionally, each OpenStack API's RBAC can be adjusted through an API policy file (policy.yaml) through olso-policy4, Keystone included. +The possibility of managing users, projects, role assignments and so on is regulated through Keystone's RBAC configured by its API policy file.

+

This means that by creating a new role and extending Keystone's API policy configuration a new Domain Manager persona can be established that is limited to a specific subset of the Keystone API to be used to manage users, projects and role assignments within a domain.

+

Decision

+

A role named "manager" MUST be present in the identity service.

+

The identity service MUST implement the Domain Manager functionality for this role. +The implementation details depend on the OpenStack Keystone version used. +See the sections below for reference.

+

For OpenStack Keystone 2024.2 or later

+

For OpenStack Keystone 2024.2 or later the Domain Manager persona is already integrated natively. +To guarantee proper scope protection, the Identity API MUST be configured with "enforce_scope" and "enforce_new_defaults" enabled for the oslo.policy library.

+

Example entries for the keystone.conf configuration file:

+
[oslo_policy]
enforce_new_defaults = True
enforce_scope = True
+

The "is_domain_managed_role" policy rule MAY be adjusted using a dedicated policy.yaml file for the Identity API in order to adjust the set of roles a Domain Manager is able to assign/revoke. +When doing so, the admin role MUST NOT be added to this set.

+

Note about upgrading from SCS Domain Manager to native integration

+

In case the Identity API was upgraded from an older version where the policy-based Domain Manager implementation of SCS described in the implementation notes for this standard was still in use, the policies described there MUST be removed. +The only exception to this is the "is_domain_managed_role" rule in case any adjustments have been made to that rule and the CSP wants to preserve them.

+

For OpenStack Keystone 2024.1 or below

+

For OpenStack Keystone 2024.1 or below, the Domain Manager functionality MUST be implemented using API policies. +For details, refer to the implementation notes for this standard.

+

For the release 2024.1 and below, changing the "enforce_scope" and "enforce_new_defaults" options for the Identity API is not necessary for the Domain Manager implementation.

+ +

Upstream contribution spec for the Domain Manager functionality

+

Description: Upstream Identity service specification to introduce the Domain Manager functionality natively in OpenStack Keystone. +After implementing the Domain Manager functionality as described in the implementation notes for this standard, the SCS project contributed the functionality to the official OpenStack project. +This eventually resulted in the feature being integrated natively in OpenStack Keystone starting with the 2024.2 release. +The specification was the starting point of the contribution.

+

Link: OpenStack Identity Specs: Domain Manager Persona for domain-scoped self-service administration

+

"admin"-ness not properly scoped

+

Description: Upstream bug report about the underlying architectural issue of the admin role not being properly scoped and giving system-level admin permissions regardless of whether the admin role assignment was scoped to project or domain level. +This is the main reason for the admin role being inappropriate to implement Domain Managers.

+

Link: Launchpad bug: "admin"-ness not properly scoped

+

Consistent and Secure Default RBAC

+

Description: Upstream rework of the default role definitions and hierarchy across all OpenStack services. +Aims to introduce support for a scoped manager role by 2024 but only focuses on project-level scoping for this role so far, not domain-level.

+

Link: OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC

+

Conformance Tests

+

There is a test suite in domain-manager-check.py. +The test suite connects to the OpenStack API using two sample domains and corresponding Domain Manager accounts. +It verifies the compliance to the standard and the proper domain-scoping as defined by the Keystone policy. +Please consult the associated README.md for detailed setup and testing instructions.

+

Appendix

+

Decision Record

+

Change the naming of the Domain Manager role to align with upstream

+

Decision Date: 2024-03-13

+

Decision Maker: Team IaaS

+

Decision:

+
    +
  • the Domain Manager role should be named "manager" not "domain-manager"
  • +
+

Rationale:

+
    +
  • upstream (OpenStack) will introduce a "manager" role with the upcoming RBAC rework
  • +
  • the "manager" role is intended to grant managing capabilities bound to the scope it is assigned for, e.g. projects; it would make sense to also integrate the Domain Manager approach here
  • +
  • during the process of contributing the Domain Manager functionality upstream we were asked to use the already defined "manager" role instead of introducing a new role; so the rename would then also be in line with the upstream contribution
  • +
+

Links / Comments / References:

+ +

Allow flexibility for the roles a Domain Manager can assign/revoke within domain

+

Decision Date: 2023-09-27

+

Decision Maker: Team IaaS, Team IAM

+

Decision:

+
    +
  • the standard should not strictly limit the roles a Domain Manager can assign/revoke to/from other users within a domain to the "member" role
  • +
  • the standard should allow CSPs to define one or more roles for Domain Managers to manage
  • +
  • whether or not this includes the Domain Manager role itself is not to be predefined by the standard and should be up to the CSP to decide instead
  • +
  • the standard should only strictly prohibit adding the "admin" role to the list of roles manageable by Domain Managers
  • +
+

Rationale:

+
    +
  • the available and configured roles might differ between CSPs and infrastructures
  • +
  • the Domain Manager standard should be flexible enough to adapt to different environments while still offering the intended functionality
  • +
  • there might be a tradeoff between self-service flexibility desired by customers and the security regulation a CSP wants to impose, thus allowing or prohibiting the designation of Domain Managers by customers themselves should be up to the CSP to decide
  • +
+

Links / Comments / References:

+ +

Extend domain management functionality to Keystone groups

+

Decision Date: 2023-08-04

+

Decision Maker: SIG IAM

+

Decision:

+
    +
  • the Domain Manager Standard configuration should cover the groups functionality of Keystone, allowing domain manager to manage groups in domains
  • +
+

Rationale:

+
    +
  • the groups functionality is a desired IAM feature for customers
  • +
+

Links / Comments / References:

+ +

Change the naming of the Domain Manager role

+

Decision Date: 2023-08-04

+

Decision Maker: SIG IAM

+

Decision:

+
    +
  • the Domain Manager role should be named "domain-manager" not "domain-admin".
  • +
+

Rationale:

+ +

Links / Comments / References:

+ + +

Footnotes

+
    +
  1. +

    OpenStack Documentation: Role-Based Access Control Overview

    +
  2. +
  3. +

    Launchpad bug: "admin"-ness not properly scoped

    +
  4. +
  5. +

    OpenStack Documentation: Keystone for Other Services - Domain Scope

    +
  6. +
  7. +

    OpenStack Documentation: Administering Applications that use oslo.policy

    +
  8. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0302-w1-domain-manager-implementation-notes/index.html b/standards/scs-0302-w1-domain-manager-implementation-notes/index.html new file mode 100644 index 0000000000..582484add7 --- /dev/null +++ b/standards/scs-0302-w1-domain-manager-implementation-notes/index.html @@ -0,0 +1,74 @@ + + + + + +Domain Manager implementation notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Domain Manager implementation notes

Implementation notes

+
caution

If a Keystone release of OpenStack 2024.2 or later is used, the policy configuration described in this document MUST be removed again in case it was applied in the past prior to the upgrade.

+
info

The implementation described in this document only applies to Keystone releases prior to the OpenStack release 2024.2 ("Dalmatian"). +This document describes a transitional solution to offer the Domain Manager functionality for SCS clouds based on an OpenStack release earlier than 2024.2.

Beginning with the 2024.2 release of OpenStack, the Domain Manager persona is integrated natively into Keystone and the implementation described below is unnecessary and might conflict with the native implementation.

+

Policy adjustments

+

The following policy can be applied to Keystone releases older than 2024.2 ("Dalmatian"). +It mimics the Domain Manager persona implemented by Keystone starting with version 2024.2 and makes the functionality available for earlier releases of Keystone.

+

The only parts of the policy definitions below that may be changed are:

+
    +
  1. The "base_*" definitions to align them to the correct OpenStack defaults matching the OpenStack release of the environment in case those differ from this template.
  2. +
  3. The "is_domain_managed_role" definition (see next section below).
  4. +
+
# SCS Domain Manager policy configuration

# Section A: OpenStack base definitions
# The entries beginning with "base_<rule>" should be exact copies of the
# default "identity:<rule>" definitions for the target OpenStack release.
# They will be extended upon for the manager role below this section.
"base_get_domain": "(role:reader and system_scope:all) or token.domain.id:%(target.domain.id)s or token.project.domain.id:%(target.domain.id)s"
"base_list_domains": "(role:reader and system_scope:all)"
"base_list_roles": "(role:reader and system_scope:all)"
"base_get_role": "(role:reader and system_scope:all)"
"base_list_users": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
"base_get_user": "(role:reader and system_scope:all) or (role:reader and token.domain.id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"
"base_create_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"
"base_update_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"
"base_delete_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"
"base_list_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
"base_get_project": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.project.domain_id)s) or project_id:%(target.project.id)s"
"base_create_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"
"base_update_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"
"base_delete_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"
"base_list_user_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"
"base_check_grant": "(role:reader and system_scope:all) or ((role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"
"base_list_grants": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)"
"base_create_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"
"base_revoke_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"
"base_list_role_assignments": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
"base_list_groups": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"
"base_get_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"
"base_create_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"
"base_update_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"
"base_delete_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"
"base_list_groups_for_user": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(user_id)s"
"base_list_users_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"
"base_remove_user_from_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"
"base_check_user_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"
"base_add_user_to_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"

# Section B: Domain Manager Extensions

# classify domain managers with a special role
"is_domain_manager": "role:manager"

# specify a rule that whitelists roles which domain admins are permitted
# to assign and revoke within their domain
"is_domain_managed_role": "'member':%(target.role.name)s or 'load-balancer_member':%(target.role.name)s"

# allow domain admins to retrieve their own domain (does not need changes)
"identity:get_domain": "rule:base_get_domain or rule:admin_required"

# list_domains is needed for GET /v3/domains?name=... requests
# this is mandatory for things like
# `create user --domain $DOMAIN_NAME $USER_NAME` to correctly discover
# domains by name
"identity:list_domains": "rule:is_domain_manager or rule:base_list_domains or rule:admin_required"

# list_roles is needed for GET /v3/roles?name=... requests
# this is mandatory for things like `role add ... $ROLE_NAME`` to correctly
# discover roles by name
"identity:list_roles": "rule:is_domain_manager or rule:base_list_roles or rule:admin_required"

# get_role is needed for GET /v3/roles/{role_id} requests
# this is mandatory for the OpenStack SDK to properly process role assignments
# which are issued by role id instead of name
"identity:get_role": "(rule:is_domain_manager and rule:is_domain_managed_role) or rule:base_get_role or rule:admin_required"

# allow domain admins to manage users within their domain
"identity:list_users": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_users or rule:admin_required"
"identity:get_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_get_user or rule:admin_required"
"identity:create_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_create_user or rule:admin_required"
"identity:update_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_update_user or rule:admin_required"
"identity:delete_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_delete_user or rule:admin_required"

# allow domain admins to manage projects within their domain
"identity:list_projects": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_projects or rule:admin_required"
"identity:get_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_get_project or rule:admin_required"
"identity:create_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_create_project or rule:admin_required"
"identity:update_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_update_project or rule:admin_required"
"identity:delete_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_delete_project or rule:admin_required"
"identity:list_user_projects": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_user_projects or rule:admin_required"

# allow domain managers to manage role assignments within their domain
# (restricted to specific roles by the 'is_domain_managed_role' rule)
#
# project-level role assignment to user within domain
"is_domain_user_project_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s"
# project-level role assignment to group within domain
"is_domain_group_project_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.project.domain_id)s"
# domain-level role assignment to group
"is_domain_level_group_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.domain.id)s"
# domain-level role assignment to user
"is_domain_level_user_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.domain.id)s"
"domain_manager_grant": "rule:is_domain_manager and (rule:is_domain_user_project_grant or rule:is_domain_group_project_grant or rule:is_domain_level_group_grant or rule:is_domain_level_user_grant)"
"identity:check_grant": "rule:domain_manager_grant or rule:base_check_grant or rule:admin_required"
"identity:list_grants": "rule:domain_manager_grant or rule:base_list_grants or rule:admin_required"
"identity:create_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_create_grant or rule:admin_required"
"identity:revoke_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_revoke_grant or rule:admin_required"
"identity:list_role_assignments": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_role_assignments or rule:admin_required"

# allow domain managers to manage groups within their domain
"identity:list_groups": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_list_groups or rule:admin_required"
"identity:get_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_get_group or rule:admin_required"
"identity:create_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_create_group or rule:admin_required"
"identity:update_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_update_group or rule:admin_required"
"identity:delete_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_delete_group or rule:admin_required"
"identity:list_groups_for_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_groups_for_user or rule:admin_required"
"identity:list_users_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_list_users_in_group or rule:admin_required"
"identity:remove_user_from_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_remove_user_from_group or rule:admin_required"
"identity:check_user_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_check_user_in_group or rule:admin_required"
"identity:add_user_to_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_add_user_to_group or rule:admin_required"
+

Note that the policy file begins with a list of "base_*" rule definitions ("Section A"). +These mirror the default policies of recent OpenStack releases. +They are used as a basis for the domain-manager-specific changes which are implemented in "Section B" where they are referenced to via "or rule:base_*" accordingly. +The section of "base_*" rules is meant for easy maintenance/update of default rules while keeping the domain-manager-specific rules separate.

+
+

Note: +The "or rule:admin_required" appendix to the rule definitions in "Section B" is included for backwards compatibility with environments not yet fully configured for the new secure RBAC standard1.

+
+

Specifying manageable roles via "is_domain_managed_role"

+

The "is_domain_managed_role" rule of the above policy template may be adjusted according to the requirements of the CSP and infrastructure architecture to specify different or multiple roles as manageable by Domain Managers as long as the policy rule adheres to the following:

+
    +
  • the "is_domain_managed_role" rule MUST NOT contain the "admin" role, neither directly nor transitively
  • +
  • the "is_domain_managed_role" rule MUST define all applicable roles directly, it MUST NOT contain a "rule:" reference within itself
  • +
+
Example: permitting multiple roles
+

The following example permits the "reader" role to be assigned/revoked by a Domain Manager in addition to the default "member" and "load-balancer_member" roles. +Further roles can be appended using the logical or directive.

+
"is_domain_managed_role": "'member':%(target.role.name)s or 'load-balancer_member':%(target.role.name)s or 'reader':%(target.role.name)s"
+

Note regarding the manager role

+

When adjusting the "is_domain_managed_role" rule a CSP might opt to also include the "manager" role itself in the manageable roles, resulting in Domain Managers being able to propagate the Domain Manager capabilities to other users within their domain. +This increases the self-service capabilities of the customer but introduces risks of Domain Managers also being able to revoke this role from themselves or each other (within their domain) in an unintended fashion.

+

CSPs have to carefully evaluate whether Domain Manager designation authority should reside solely on their side or be part of the customer self-service scope and decide about adding "'manager':%(target.role.name)s" to the rule accordingly.

+

Impact

+

Applying this implementation modifies the API policy configuration of Keystone and introduces a new persona to Keystone to enable IAM self-service for customers within a domain. +Once assigned, this persona allows special Domain Manager users within a domain to manage users, project, groups and role assignments as part of the IAM self-service.

+

However, the configuration change introduced by this implementation does not automatically assign the Domain Manager persona to any users per default. +Assigning the new persona and granting customers the resulting self-service capabilities is a deliberate action to be taken by the CSP on a per-tenant (i.e. per domain) basis.

+

Omitting the provisioning of any Domain Manager users (i.e. not assigning the new persona to any user) will result in an OpenStack cloud that behaves identically to a configuration without the implementation applied, making the actual usage of the functionality a CSP's choice and entirely optional.

+

Security implications

+

As a result of the "identity:list_roles" rule (see above), Domain Managers are able to see all roles via "openstack role list" and can inspect the metadata of any role with "openstack role show"

+ +

Footnotes

+
    +
  1. +

    OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC

    +
  2. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0400-v1-status-page-create-decision/index.html b/standards/scs-0400-v1-status-page-create-decision/index.html new file mode 100644 index 0000000000..7ea6579267 --- /dev/null +++ b/standards/scs-0400-v1-status-page-create-decision/index.html @@ -0,0 +1,163 @@ + + + + + +Status Page create decision | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Status Page create decision

Introduction

+

Creating and maintaining IT infrastructure is a complex task. +Any kind of consumer (e.g. operators, customers) can +be supported by presenting the status of all possible parts of the +serving infrastructure. Whether a service is not reachable or +the used hardware is having an outage we want the consumers to be easily informed +by using a "Status Page" application. The need for a "Status Page" +came up early in the SCS project and the requirements a "Status Page" application +has to fulfill were defined and written down on 2022-06-02 as the +MVP-0 epic. +The upcoming research on existing solutions came to the conclusion that we want to +create a new "Status Page" application.

+

Existing Applications

+

Since we want to use as much as possible from existing projects and contribute to +upstream projects to support the community with our efforts, it was a hard +decision to create a new "Status Page" application.

+

Before the decision was made some existing and known applications were tested +and analyzed if they would fit to our use case. An overview of this +comparison can be found below in this document +While this is not a complete list of all existing applications it did +capture the most promising ones from the awesome-status-page list +in order to have base to decide upon.

+

Work on an existing project only makes sense if the project is healthy OR can be +brought into a healthy state. If upstream does not accept patches a fork is needed. +The fork however only makes sense if the underlying technology is worth to be maintained. +The possible candidates did not fulfill these conditions - in the cases where +contribution seemed possible the candidates looked abandoned and long existing CVEs weren't +worked on.

+

Decision

+

Based on the results the decision was made, that the effort is likely to be the same if +we pick up an existing project and try to get it in shape for our use case. It was not +100% clear if this would even be possible or if we still would have to maintain our +own additional patches.

+

So there will be a reference implementation that will match the requirements we have. +In addition, there will be an architecture design documentation. So if the reference +implementation may not fit to you, it will be possible to create your own application.

+

Status Page Requirements

+
    +
  • +

    The status page application should be simplistic in software design and should not depend on a large +variety of services

    +
      +
    • simplistic, yet existing user management for write access (oauth? OIDC?) +
        +
      • Simple RBAC (role based access control) is nice to have
      • +
      +
    • +
    • support that components are only visible to a subset of users +
        +
      • implies that there is a role that is read-only
      • +
      • On-Prem use case might be handled by having an authenticating reverse proxy in front
      • +
      +
    • +
    +
  • +
  • +

    The status page application should allow for simple and easy theming

    +
      +
    • Page = (Possibly simple) Web-UI
    • +
    +
  • +
  • +

    As a CSP, I want to have a status page that allows to

    +
      +
    • define locations and similar grouping (AZs, ...)
    • +
    • define components globally or per location +_to ease maintenance I want to define per component where it belongs so that I only have +to define a component once, but have it visible in several locations +_ status per component should be allowed to be toggleable per location or overall * a component should allow for several statuses, that are defined by me
    • +
    +
  • +
  • +

    Status, Status Items should be easy to extract

    +
      +
    • REST(less)-API to interact with +_API should be versioned +_ this allows for embedding status information in other applications, such as cloud +dashboards +_this also allows for submitting items from other tooling +_ incoming webhooks (https POST) should be supported (e.g. for air-gapped setups) – +i.e. submitting a health beacon every x seconds +_web-UI wanted for posting updates as well +_ Token based Auth
    • +
    +
  • +
  • +

    Configuration should be manageable with YAML files (imho this annoys me using Uptime Kuma)

    +
  • +
  • +

    As a consumer of the status page, I'd like to subscribe to events on the status page via e-mail

    +
      +
    • for everything
    • +
    • for specific components
    • +
    +
  • +
  • +

    As a consumer of the status page, I'd like to subscribe to an RSS or atom feed

    +
  • +
  • +

    Allow for the ability to trigger webhooks upon certain events (to submit info to other systems via +webhooks, e.g. chat/messenger)

    +
  • +
  • +

    As a CSP Operator, I want to be able to flag a component with a new status quick and easy

    +
      +
    • to minimize the probability of making errors, updating the status of a component should not be +hard brainwork
    • +
    • updates can be both machine generated status changes (triggered e.g. by health monitoring) +and updates from human operators
    • +
    • updating a status should allow the CSP Operator to do that in a fashion that either pushes +infos to the subscribers or just updates the status on the status page
    • +
    • updating the status can either be toggling the status of the component or can be +accompanied by additional textual information.
    • +
    • When updating a status with textual information the status page application should make it +easy for me as the CSP Operator to do in a way, that if different people submit infos over time, +they are presented in a similar way (e.g. the status page application should guide so that the +resulting infos are presented in an identical way). Example: when updating infos of an incident +over time the timeline should automatically be sorted by the status page application so that it +does not depend on the Operator whether the newest info is on top or at the bottom. This is +typical thing that varies if several people update items
    • +
    +
  • +
  • +

    Allow for templates for certain types of incidents

    +
  • +
  • +

    User-specific monitoring (how are MY instances, load-balancers, ... doing?) is OUT OF SCOPE for +the status page.

    +
      +
    • But having it would be useful and if we have something like this, link it from the status page +(and a link to horizon might be the default)
    • +
    +
  • +
  • +

    Sidenote: External hosting is desired to avoid status page going down with infra

    +
  • +
+

With those requirements in mind the projects that initially were found, were evaluated.

+

Comparison matrix

+
CachetHQClearStatusciaocStateGatusIssue Statusstatusfy
CSP VIEW
small dependency tree❌ Composer❌ ruby gems⁇ helm chart❌ npm/github/zapier❌ npm dependencies very huge
easy themable
grouping (by location...)
components definition ...
... local or global
... easy flagging with new status
... push notification on update
... updates with additional information
API Support ...❌ read only✅ GitHub API
... versioned
... web ui for posting updates
... token based auth✅ Auth managed by git provider❌ only basic auth❌ BUT OIDC!
manageable configuration❌ config depends on web server and initial install relies on env variables❌ based on hugo CMS❌ config by env variables❌ based on hugo CMS❌ no real config needed
templating support✅ twig❌ Hugo itself uses GO template libraries
CUSTOMER VIEW
subscription support ...❌ only by git provider
... send by eMail
watchdog for status page support
trigger webhook support❌ needs cachet-monitor
additional infos-basically a theme for hugo cms, depends on netlify cms-basically a theme for hugo cms, depends on netlify cms-It's highly optimized for github pagesSPA created with netlify
hidden components
user management✅ by OIDC⁇ through github?
different output format on notification
external hosting❌ looks like you are limited to github
project healthy❌ last commit 17 months❌ last commit 3 years❌ last commit 5 months✅ last commit 2 months✅ recent activities✅ recent activities❌ archived and abandoned by the owner
documentation✅ API ❌ User Documentation⁇u❌ not reachable anymore
git based⁇ a netlify based installation is able to communicate with github
project pageproject pageproject pageproject pageproject pageproject pageproject pageproject page
+ + \ No newline at end of file diff --git a/standards/scs-0401-v1-status-page-reference-implementation-decision/index.html b/standards/scs-0401-v1-status-page-reference-implementation-decision/index.html new file mode 100644 index 0000000000..fe64c8e40f --- /dev/null +++ b/standards/scs-0401-v1-status-page-reference-implementation-decision/index.html @@ -0,0 +1,34 @@ + + + + + +Status page reference implementation decision | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Status page reference implementation decision

Introduction

+

For the reference implementation of the status page API defined by the OpenAPI spec some decision should be made to which technology to be used and why.

+

A reference implementation should be of use to most of the intended group, but is not necessarily applicable for every use case.

+

Motivation

+

For a reference implementation to be of any use, some common and widely used technologies should be used, so it's useful to most of the intended user group.

+

Decision

+

Programming Language

+

The status page application consists of an api server as well as a frontend. For implementing the api server, which is generated from the OpenAPI spec, Go was chosen, because of maturity and widespread usage as industry standard. Go, in particular, is a modern programming language and is commonly used in network and cloud computing environments.

+

Database

+

As database, PostgreSQL was chosen, since it is a mature, well-known database. PostgreSQL can be run in various environments from small setups to scaled setups. +Furthermore, PostgreSQL is a very healthy project with an active community and a solid license. It easily passed the SCS OSS health check.

+ + \ No newline at end of file diff --git a/standards/scs-0402-v1-status-page-openapi-spec-decision/index.html b/standards/scs-0402-v1-status-page-openapi-spec-decision/index.html new file mode 100644 index 0000000000..064cbdce17 --- /dev/null +++ b/standards/scs-0402-v1-status-page-openapi-spec-decision/index.html @@ -0,0 +1,108 @@ + + + + + +Status page OpenAPI decision | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Status page OpenAPI decision

Introduction

+

While defining the OpenAPI spec some considerations and decisions are made and should be documented.

+

Requirements

+

The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

+

In addition, "FORBIDDEN" is to be interpreted equivalent to "MUST NOT".

+

Motivation

+

The spec should be as minimal as possible, while being as understandable as possible, so some choices to the design of API objects, requests and responses are made.

+

Decision

+

Common definitions

+

Some defined schemas are used as common types. These common definitions help to simplify the actual object definitions by providing meaningful names, and reduce duplication. A change of ID type for example only needs one change in the common definition, and not in any of the object definitions which include an ID.

+

Special mentions:

+

Id

+

IDs are used for identification of resources, which can be retrieved by the API.

+

UUIDs are used, to ensure uniqueness. Also, they can be visually recognized as identifier.

+

Incremental

+

An Incremental is used in combination with other identifiers to identify a sub resource of any kind. Incrementals themselves are not globally unique, but unique for every sub resource of a unique resource.

+

Generation and order

+

Generation and Order are predefined objects which include a Incremental typed field for the common usages of the Incremental value.

+

SeverityValue

+

A SeverityValue is an unsigned integer ranging from 0 to 100 inclusively. It MUST be utilized by an Impact when referenced by a requested Component to gauge the severity of the impact on that component. It MUST be added to an Impact when referenced by an Incident, when its created. While being described as an unsigned integer, implementing this value MAY not require it to be an uint data type in any form, because its range even fits in a signed int8 (byte) data type. Each severity value SHOULD be unique, as multiple severities with the same value will be ambiguous.

+

API objects

+

All objects which are used as payload, either as request or response, are defined by schemas. This centralizes the maintenance of field names and types, for both requests and responses.

+

API object fields

+

Most fields of objects are not required. This allows usage as request and response payloads.

+

Responses of payload objects, which contain an ID or an Incremental typed field, MUST fill the ID or Incremental field to fully identify the (sub) resource.

+

Requests on a single resource MUST contain the ID in the path parameters. Request on sub resources MUST contain the ID and Incremental typed value as path parameters. The payload SHOULD NOT contain the ID or Incremental typed field. +If it contains these fields as payload, they SHALL NOT change them.

+

Requests to updating operations SHOULD contain the minimum of the changed fields, but MAY contain the full object. ID and Incremental typed fields MUST follow the same rules as stated above.

+

Endpoint naming

+

The endpoints are named in plural form, even when handling single objects, to keep uniform paths.

+

Incidents

+

Incidents are the main information bearer at the status page. They hold most of the data that describes an incident:

+
    +
  • when it happened
  • +
  • when it completed or if it is still ongoing
  • +
  • which components it affected
  • +
  • the stages the incident progressed through
  • +
  • all updates related to the resolution of the incident
  • +
+

An incident is considered active while no end time has been set. Incidents whose end time has been set are considered to be inactive or resolved.

+

Phase list

+

The list of phases that an incident can go through has a crucial order. So it MUST be handled as the given list.

+

Delete or update operations are FORBIDDEN.

+

To "change" a phase list, a new one must be created. The old one must be kept. For this mechanic the lists are structured in generations. All references to phases MUST include their generation to ensure correct references.

+

To reference a single phase a PhaseReference MUST include a generation and an order field. This MAY be used to reference a single generation too.

+

Labels

+

Labels are identifying metadata to components. They do not represent a resource or sub resource of any kind. They are designed as non system critical pieces of information, mainly intended for human consumption.

+

Labels are simple key/value pairs attached to components, categorizing them dynamically.

+

Impact

+

An impact defines the relation between an incident and a component. A component can be affected by multiple incidents and an incident can affect multiple components. Each of these impacts can have a different type depending on the incident and component, like for example connectivity or performance issues.

+

To reflect this, each component and incident can have a list of impacts, stating the type of impact and a reference to the incident or component, it refers to.

+

Furthermore, a SeverityValue MUST be supplied to the Impact when referenced by a Component, to gauge the impact's severity on that component.

+

Severity

+

A severity contains a name, that MUST be unique and will be used as identifier. The SeverityValue marks the upper boundary of the severity.

+

The severity's value range is calculated by taking the previous severity's (SeverityA) value and adding 1 to obtain the starting point and taking the current severity's (SeverityB) value as the end point. These limits are inclusive.

+
0, ... , SeverityA.value, SeverityA.value, + 1, ... , SeverityB.value - 1, SeverityB.value, SeverityB.value + 1, ... , 100
|<------------range of severity values for SeverityB------------->|
+

Example:

+
[
{
"displayName": "operational",
"value": 33
},
{
"displayName": "limited",
"value": 66
},
{
"displayName": "broken",
"value": 100
}
]
+

A special severity of type "maintenance" is given the exact value of 0.

+

This means:

+
    +
  • maintenance at 0
  • +
  • operational from 1 to 33
  • +
  • limited from 34 to 66
  • +
  • broken from 67 to 100.
  • +
+

A value of 100 is the maximum of the severity value.

+

A severity with the value of 100 MUST always be supplied. This is the highest severity for the system. If no severity with a value of 100 exists, e.g. the highest severity value is set at 90, an Impact with a higher SeverityValue WILL be considered to be an unknown severity.

+

Component impacts

+

Components list their impacts, which they are affected by, as read only. Only an incident creates an impact on a component. Components MUST only list their currently active impacts.

+

An optional at parameter can be supplied, to set a reference time to show all incidents, active at that time, even when they are inactive currently.

+

Maintenance

+

Any impact that has the reserved SeverityValue of 0 is a maintenance time slot. As such it MUST include a start and end time. However, both are allowed to be set in the future.

+

Return of POST requests

+

Generally POST requests create new resources. These endpoints do not return the new resource, but a unique identifier to the resource e.g. a UUID.

+

In most cases the new resource won't be used directly after creation. Most often list calls are used. If the new resource is used directly, it can be retrieved by the returned identifier.

+

Payloads to POST requests SHALL NOT include ID or Incremental typed fields, it lies in the responsibility of the API server to assign IDs and Incrementals to objects.

+

Return of PATCH requests

+

Most commonly PATCH requests are used to partially or fully change a resource. These requests do not respond with the changed resource, nor an identifier.

+

Both the old state as well as the new state are known on the client at that point in time and if they need to load the actual recent version from the server, the identifier is already known.

+

PATCH vs PUT for updating resources

+

The PUT requests is most commonly used to update full objects, whereas PATCH is used for partial updates.

+

PATCH is used as the default method for updating resources because it does not require the full object for an update, but does not discourage the use of the complete object.

+

Authentication and authorization

+

The API spec does not include either authentication (AuthN) nor authorization (AuthZ) of any kind. The API server MUST be secured by a reverse/auth proxy.

+ + \ No newline at end of file diff --git a/standards/scs-0403-v1-csp-kaas-observability-stack/index.html b/standards/scs-0403-v1-csp-kaas-observability-stack/index.html new file mode 100644 index 0000000000..6dae94eecf --- /dev/null +++ b/standards/scs-0403-v1-csp-kaas-observability-stack/index.html @@ -0,0 +1,211 @@ + + + + + +Architecture for the Cloud Service provider Observability System for the KaaS Layer | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Architecture for the Cloud Service provider Observability System for the KaaS Layer

Introduction

+

Cloud Service Providers offer a variety of products to a customer. Those can include compute resources like virtual machines, networking, and identity and access management. As customers of those services build their applications upon those offered services the service provider needs to ensure a certain quality level of their offerings. This is done by observing the infrastructure. Observability systems leverage different types of telemetry data which include:

+
    +
  1. Metrics: Usually time series data about different parameters of a system which can include e.g. CPU usage, number of active requests, health status, etc.
  2. +
  3. Logs: Messages of software events during runtime
  4. +
  5. Traces: A more developer-oriented form of logging to provide insights into an application or to analyze request flows in distributed systems.
  6. +
+

Based on those data, an alerting system can be used to send out notifications to an Operations Team if a system behaves abnormally. Based on the telemetry data the Operations Team can find the issue, work on it, and mitigate future incidents.

+

Motivation

+

Currently, only the IaaS Layer of the SCS Reference Implementation has an Observability Stack consisting of tools like Prometheus, Grafana, and Alertmanager as well as several Exporters to extract monitoring data from the several OpenStack components and additional software that is involved in the Reference Implementation. As the Kubernetes as a Service Layer becomes more and more important and the work on the Cluster API approach to create customer clusters progresses further, an observability solution for this layer is also needed. CSP should be able to watch over customer clusters and intervene if a cluster gets in a malfunctioning state. For this, a toolset and architecture are needed which is proposed in this ADR.

+

Requirements

+

A survey was conducted to gather the needs and requirements of a CSP when providing Kubernetes as a Service. The feedback of the survey led to the following requirement on a Kubernetes as a Service Observability System:

+
    +
  • Telemetry Data that MUST be fetched: +
      +
    • CPU, RAM, Disk, Network
    • +
    • HTTP Connectivity Metrics
    • +
    • Control Plane and Pod metrics (States, Ready, etc.)
    • +
    • K8s certs metrics
    • +
    • Metrics of underlying node
    • +
    • Logs of control plane, kubelet and containerd
    • +
    +
  • +
  • Telemetry Data that MAY be fetched: +
      +
    • K8s resources (exporters, kubestate metrics, cadvisor, parts of the kubelet)
    • +
    • Ingress controller exporter (http error rate, cert metrics like expiration date)
    • +
    +
  • +
  • Telemetry Data that SHOULD NOT BE fetched: +
      +
    • Any metrics or logs a CSP does not need to provide support with respect to their SLA with a Customer.
    • +
    +
  • +
  • Telemetry Data that MUST NOT be fetched: +
      +
    • Secrets
    • +
    • Customer Specific Workload Metrics
    • +
    +
  • +
  • The Alerting Mechanism MUST include a default ruleset
  • +
  • The Observability Stack MUST run on the CSP Infrastructure
  • +
  • The Observability Stack MUST be High Available
  • +
  • The Observability Stack MUST be able to observe itself
  • +
  • Observed Clusters SHOULD have a low resource impact on the used software to provide telemetry data for the Observability Stack
  • +
+

Options considered

+

Use of the dNation Observability Stack as a base

+

The dNation monitoring stack offers a lot of basic capabilities needed on an observability stack for Kubernetes like Prometheus Operator, Grafana, Alertmanager, Loki, Promtail and Thanos.

+

Pull-based Architecture

+

Each customer cluster has Thanos and Prometheus installed in addition to Thanos and Prometheus on the Observer Cluster. Metrics of a customer cluster are pulled from Thanos (Customer Cluster) for short term queries, as for long term queries the data of all Thanos instances is stored in an external Object Store of the CSP.

+

Push-based Archtitecture

+

Here, Thanos and Prometheus are only used on the CSP side to store and manage all observability data. For the customer clusters only the Prometheus Agent will be used. Prometheus Agent will push all metrics of a Customer Cluster to the central Thanos instance and is preserved in an external Object Store. This introduces less complexity and resource consumption on the customer workload clusters.

+

Scope of the Observability Architecture

+

The Observability Cluster and Architecture SHOULD be defined in a modular way so that it can be used to not only observe the Kubernetes Layer of an SCS Stack, but every aspect of an SCS Stack.

+

Observing the Observability Infrastructure

+

For usage in production, it needs to be possible to observe the Observability Cluster itself.

+

Alerting Rulesets

+

Use a mix of kubernetes-mixin alerts and dNation Alerts Ruleset, as they offer an extensive and well reviewed set of default Alerts covering the important Parts of a Kubernetes Deployment (Nodes, Controlplane, K8s Resources, etc.)

+

Decisions

+
    +
  1. Base the MVP-0 Implementation on the dNation Kubernetes Monitoring Stack.
  2. +
  3. The Push-based Architecture was chosen over the Pull-based Approach.
  4. +
  5. The Observability Stack will be created based on the dNation observability stack
  6. +
  7. The Observability Stack can be used as a standalone component to use with the Kubernetes Layer. It should be possible to observe other parts of an SCS Stack like the status of the OpenStack components, but this will not be mandatory.
  8. +
  9. The Observability Stack should be designed that it is possible to provision two observer clusters side by side, observing each other. To do this is only a recommendation for production usage.
  10. +
  11. The MVP-0 will consist of the following features: +
      +
    • Observability data from KaaS Clusters is scraped +
        +
      • K8s cluster that hosts observer deployment is deployed
      • +
      • S3 compatible bucket as a storage for long term metrics is configured
      • +
      • thanos query-frontend is deployed and configured
      • +
      • thanos query is deployed and configured
      • +
      • thanos receiver is deployed and configured (simple deployment, non HA, without router)
      • +
      • thanos ruler is deployed and configured
      • +
      • thanos compactor is deployed and configured
      • +
      • thanos bucket-web is deployed and configured
      • +
      • thanos storegateway is deployed and configured
      • +
      • prometheus server is deployed and configured
      • +
      • prometheus alertmanager is deployed and configured
      • +
      • prometheus black-box exporter is deployed and configured
      • +
      • kaas-metric-importer is deployed and configured (service aims to differentiate between intentional deletion of KaaS instances and failures in the KaaS monitoring agent)
      • +
      +
    • +
    • Alerts are defined on the KaaS Clusters metrics +
        +
      • all prometheus alerts are working as expected
      • +
      +
    • +
    • There exist Dashboards for KaaS Cluster Health +
        +
      • KaaS L0 dashboard counters are working correctly
      • +
      • Dedicated L0 dashboards are deployed for KaaS and for IaaS monitoring layers
      • +
      +
    • +
    • There exist Dashboards for SCS services endpoints health (BlackBox exporter)
    • +
    • There exist Dashboards for IaaS layer health
    • +
    • Automatic Setup of Exporters for Observability of managed K8s clusters +
        +
      • KaaS service is mocked
      • +
      • VM that will host a mock of KaaS service is deployed
      • +
      • a script that deploys a multiple KinD clusters and register them in observer is created
      • +
      +
    • +
    • Automatic Setup of Thanos sidecar for Observability of IaaS layer (testbed) +
        +
      • IaaS service is mocked
      • +
      • OSISM testbed is deployed
      • +
      • implement an option to deploy thanos sidecar with some simple config in OSISM testbed
      • +
      +
    • +
    • There exist Dashboards for Harbor Registry Health
    • +
    • Alerts are defined on the Harbor Registry metrics
    • +
    +
  12. +
+

Reference

+

Outcome of the CSP Survey about Requirements for KaaS Observability

+

A survey was conducted to gather the needs and requirements of a CSP when providing Kubernetes as a Service. The results of the Survey (Questions with answers) were the following:

+
    +
  1. +

    What is your understanding of a managed Kubernetes Offering:

    +
      +
    • Hassle-Free Installation and Maintenance (customer viewpoint); Providing control plane and worker nodes and responsibility for correct function but agnostic to workload
    • +
    • Day0, 1 and 2 (~planning, provisioning, operations) full lifecycle management or let customer manages some parts of that, depending on customer contract
    • +
    +
  2. +
  3. +

    What Type and Depth of observability is needed

    +
      +
    • CPU, RAM, HDD and Network usage, Health and Function of Cluster Nodes, control plane and if desired Customer Workload
    • +
    +
  4. +
  5. +

    Do you have an observability infrastructure, if yes, how it is built

    + +
  6. +
  7. +

    Data Must haves

    +
      +
    • CPU, RAM, Disk, Network
    • +
    • HTTP Connectivity Metrics
    • +
    • Control Plane and Pod metrics (States, Ready, etc.)
    • +
    • Workload specific metrics
    • +
    • Node Stats
    • +
    • K8s resources (exporters, kubestate metrics, cadvisor, parts of the kubelet)
    • +
    • Ingress controller exporter (http error rate, cert metrics like expiration date)
    • +
    • K8s certs metrics
    • +
    • Metrics of underlying node
    • +
    • Logs of control plane, kubelet and containerd
    • +
    +
  8. +
  9. +

    Must Not haves

    +
      +
    • Secrets, otherwise as much as possible for anomaly detection over long time data
    • +
    +
  10. +
  11. +

    Must have Alerts

    + +
  12. +
  13. +

    Must NOT Alert on

    +
      +
    • Should not wake people, nothing that does not lead to Action items
    • +
    +
  14. +
  15. +

    Observability from Within Or Outside KaaS. How does the architecture look like?

    +
      +
    • Monitoring Infra on CSP Side
    • +
    • Data from Customer Clusters and Mon Infra on CSP and KaaS, get both data. KaaS Monitoring can also be used by customer
    • +
    +
  16. +
  17. +

    Special Constraints

    +
      +
    • HA Setup in different Clusters on Different Sites
    • +
    +
  18. +
+ + \ No newline at end of file diff --git a/standards/scs-0410-v1-gnocchi-as-metering-database/index.html b/standards/scs-0410-v1-gnocchi-as-metering-database/index.html new file mode 100644 index 0000000000..a25c0cac27 --- /dev/null +++ b/standards/scs-0410-v1-gnocchi-as-metering-database/index.html @@ -0,0 +1,172 @@ + + + + + +Gnocchi as database for metering | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Gnocchi as database for metering

Introduction

+

In the past we noticed missing events in the telemetry stack of OpenStack. +This results in situations where the Cloud Service Provider (CSP) +may think that a resource is still in use while the owner shut it down, +or may not be aware of a resource which has been created.

+

Such inaccurate data is a problem, +when it is supposed to be used for billing purposes.

+

This document discusses how such metering data should be stored +within the SCS. +In particular, +it provides rationale for the choice of Gnocchi +as time-series database for metering data +within SCS.

+

Definitions

+
    +
  • +

    TSDB, time-series database: +Database which is specialised for storing data which is keyed by a timestamp. +Popular examples are InfluxDB, Graphite, rrd, and Prometheus.

    +
  • +
  • +

    Metering: +Collection of usage data of a cloud, +for the specific purpose of creating invoices +to bill customers for the resources they have allocated.

    +
  • +
  • +

    backfilling: +The process of adding and modifying data in the past +within a time-series database.

    +
  • +
  • +

    Metric: +A single time-series vector. +Typically, a metric represents a single property of a resource, +such as CPU usage of an instance.

    +
  • +
  • +

    Resource metrics: +A group of metrics belonging to a single resource. +A compute instance, for instance, +may have a metric indicating the number of CPUs allocated, +another metric indicating the amount of RAM allocated, +etc.

    +
  • +
+

Motivation

+

Being able to hold users accountable +for the resources they use +is a prerequisite for commercially operating a cloud. +The SCS project wants to deliver a cloud stack +which can be used for that purpose, +hence providing reliable metering data is a requirement.

+

As metering data is inherently keyed by time, +a time-series database is required. +The choice of time-series database is an important one +as different databases come with different trade-offs. +Not all databases are suitable for the kind of data +which is collected in a metering context.

+

Design Considerations

+

The following requirements for a time-series database exist:

+
    +
  • +

    MUST support backfilling: +As we need to catch up on changes to resources +which may have happened during a brief network interruption, +we need to be able to modify data after it has been written to the TSDB.

    +
  • +
  • +

    MUST be able to handle lots of resources: +As billing should happen with a resource-level granularity, +we expect a lot of different metrics inside the TSDB.

    +
  • +
  • +

    MUST scale to different timescales: +We expect to have metrics which change frequently (e.g. object store usage) +and metrics which change rarely (e.g. cinder volume sizes). +The TSDB must be able to cope with both types of metrics efficiently.

    +
  • +
  • +

    SHOULD provide an efficient way to query all currently alive resources.

    +
  • +
  • +

    SHOULD allow truncation of storage to remove old data.

    +
  • +
  • +

    MUST be available under an appropriate Open Source license, +even for productive use cases.

    +
  • +
+

Options

+

Using Gnocchi

+

Gnocchi is a time-series database +which has its origins in the OpenStack ecosystem.

+

It supports all requirements except truncation, +which might have to be implemented.

+

Using Prometheus

+

Prometheus is a widely used time-series database +with its focus on monitoring and incident response. +While it is considered efficient for this use-case, +it has shortcomings which make it unsuitable for the metering use case:

+
    +
  • +

    Explicit recommendation against high-cardinality metrics: +As we would have to label metrics by resource IDs and project IDs, +we have to expect a very high cardinality, +also with a significant amount of metric churn.

    +
  • +
  • +

    Backfilling, albeit possible, is not well-supported.

    +
  • +
+

Using InfluxDB

+

InfluxDB is a widely used time-series database +with its focus on monitoring.

+

In contrast to Prometheus, it does support backfilling. +However, like Prometheus, +it seems to run into scalability issues in high-cardinality scenarios.

+

In addition, +clustering is only available in commercial licensing options.

+

Creating a custom TSDB implementation

+

A custom TSDB implementation +is a non-trivial project to pursue.

+

Decision

+

We use Gnocchi. +According to research, +it mostly fulfills the requirements. +While some small development efforts may be needed, +to make it fully usable, +the amount of work is anticipated much less +than making Prometheus or Influx fit the bill +(due to backfilling / cardinality scaling constraints), +let alone rolling a custom implementation.

+

Open questions

+
    +
  • +

    What will be the granularity of the events meta information?

    +

    If we decide to use resource metadata +as a place to store slow-changing information +(e.g. instance flavors, volume sizes), +we need to know what the granularity of that is.

    +
  • +
+ +
    +
  • SCS-0411-v1
  • +
+

Conformance Tests

+

None (this is a decision record).

+ + \ No newline at end of file diff --git a/standards/scs-0411-v1-publishing_method_for_metering_data/index.html b/standards/scs-0411-v1-publishing_method_for_metering_data/index.html new file mode 100644 index 0000000000..6bcd1d44e4 --- /dev/null +++ b/standards/scs-0411-v1-publishing_method_for_metering_data/index.html @@ -0,0 +1,108 @@ + + + + + +Push-based approach for providing usage data | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Push-based approach for providing usage data

Introduction

+

In the past we noticed missing events in the telemetry stack of OpenStack. +This results in situations where the Cloud Service Provider (CSP) +may think that a resource is still in use while the owner shut it down, +or may not be aware of a resource which has been created.

+

Such inaccurate data is a problem, +when it is supposed to be used for billing purposes.

+

This document discusses how such metering data should be made available +to the cloud service provider +for forwarding into their own billing solution.

+

Definitions

+
    +
  • +

    Push-based flow: +In a push-based flow, +the system generating data actively sends that data to a consumer.

    +
  • +
  • +

    Pull-based flow: +In a pull-based flow, +the system generating data waits for the system consuming the data +to ask for that data.

    +
  • +
  • +

    Metering: +Collection of usage data of a cloud, +for the specific purpose of creating invoices +to bill customers for the resources they have allocated.

    +
  • +
  • +

    Billing: +The entire process of creation, management and sending of invoices +generated from metering data.

    +
  • +
+

Motivation

+

Being able to bill users +for the resources they use +is a prerequisite for commercially operating a cloud. +The SCS project wants to deliver a cloud stack +which can be used for that purpose, +hence providing reliable metering data is a requirement.

+

We generally expect that cloud providers already have +some kind of customer-relation management or billing system in place. +Hence, it is important that the SCS is not too opinionated +on this implementation detail, +but provides a system which can easily interface with other systems.

+

This is similar to how the SCS specified the monitoring stack.

+

Design Considerations

+

The following requirements exist for the process for providing metrics to the cloud service provider:

+
    +
  • MUST scale to different timescales: +We expect to have metrics which change frequently (e.g. object store usage) +and metrics which change rarely (e.g. cinder volume sizes).
  • +
+

Options

+

Push-based flow

+

In a push-based flow, +the to-be-implemented metering system pushes events to the sink +as soon as it is reasonably confident +that the event can be used for billing purposes.

+

Poll-based flow

+

In the poll-based flow, +whichever system the CSP runs would be responsible for polling the metering API +in a frequency sufficient to capture all data with sufficient granularity.

+

Open questions

+
    +
  • What is necessary to extend the availability of sending to various sinks?
  • +
  • How does the configuration look like that is needed to push to a sink from the same type that will be already implemented?
  • +
+

Decision

+

As we need to support very different time scales of data, +the push-based flow is more suitable: +it allows the producer of the data, +which knows about the interval in which it changes, +when to provide new data to the consumer. +In contrast to that, +a poll-based flow would need the consumer to know about change intervals, +or alternatively poll in the highest change frequency ever expected.

+ +
    +
  • SCS-0410-v1
  • +
+

Conformance Tests

+

None (this is a decision record).

+ + \ No newline at end of file diff --git a/standards/scs-0412-v1-metering-json/index.html b/standards/scs-0412-v1-metering-json/index.html new file mode 100644 index 0000000000..a58fb7903b --- /dev/null +++ b/standards/scs-0412-v1-metering-json/index.html @@ -0,0 +1,89 @@ + + + + + +Exposition of IaaS metering data as JSON | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Exposition of IaaS metering data as JSON

Introduction

+

The Sovereign Cloud Stack project intends to standardise an infrastructure-as-a-service (IaaS) layer. +In order to economically sustainably run a cloud, +it is generally useful to know which user or tenant consumes which amount of resources in which time frame.

+

Similarly to how the SCS provides an interface for connecting monitoring services to detect outages, +this standard aims for providing an interface for connecting systems which aggregate customer resource usage.

+

Motivation

+

In general, +users of the SCS (i.e. cloud operators) may already have different systems in place +for tracking customer relationships +as well as billing.

+

Those systems are unlikely to have a uniform interface across all possible implementations. +Likewise, those systems are unlikely to have a way to interface with OpenStack, +the reference IaaS layer in SCS.

+

In order to provide SCS operators with a way to integrate the SCS IaaS layer with their billing, +this document shall provide a standard format, +upon which shim conversion layers (to whichever billing system is in place) +can be built.

+

Design Considerations

+

In order to define a standard, +the various options for formats need to be considered. +However, all formats also come with different implementation costs.

+

These aspects are weighed in this section.

+

Options considered

+

Use Ceilometer HTTP hook format

+

The OpenStack Ceilometer project, +which serves as a hub for all things telemetry and metering, +provides an HTTP-based hook to extract metering data. +This hook receives JSON-formatted data.

+

Using this data has the advantage +that we do not need to implement another component to translate the format +which may in turn be a point of failure.

+

Use another format

+

In this option, +a format for metering data is researched and reused, or defined and specified by the SCS project.

+

This option was not explored deeply, for the reasons explained in the decision.

+

Open questions

+

None.

+

Decision

+

We chose the Ceilometer HTTP hook format, described below, for the following reasons:

+
    +
  • +

    Ceilometer is a component which needs to be there anyway for successful metering of OpenStack. Re-using the format makes sense.

    +
  • +
  • +

    Using any other format requires a translation layer. However, users will likely need their own translation layer anyway, to integrate the metering with their own infrastructure. Hence, it makes more sense to expose the data from Ceilometer directly.

    +

    A notable downside of this approach is that a change in Ceilometers format will inevitably cause issues in all downstream consumers.

    +
  • +
+ +
    +
  • SCS-0410-v1
  • +
  • SCS-0411-v1
  • +
+

Conformance Tests

+

None.

+ + \ No newline at end of file diff --git a/standards/scs-XXXX-vN-decision-record-template/index.html b/standards/scs-XXXX-vN-decision-record-template/index.html new file mode 100644 index 0000000000..060ab33a8e --- /dev/null +++ b/standards/scs-XXXX-vN-decision-record-template/index.html @@ -0,0 +1,37 @@ + + + + + +_Descriptive title_ | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

_Descriptive title_

Abstract

+

Very short introduction about the topic of this document.

+

Terminology

+

Example (abbr. Ex) +This is the description for an example terminology.

+

Context

+

What is the issue that we're seeing that is motivating this decision or change?

+

Decision

+

What is the decision that we're proposing and/or doing? +Should also include reasoning for this decision

+

Consequences

+

What becomes easier or more difficult to do because of this change?

+ +

Related Documents, OPTIONAL

+ + \ No newline at end of file diff --git a/standards/scs-XXXX-vN-standard-template/index.html b/standards/scs-XXXX-vN-standard-template/index.html new file mode 100644 index 0000000000..588666246f --- /dev/null +++ b/standards/scs-XXXX-vN-standard-template/index.html @@ -0,0 +1,45 @@ + + + + + +_Descriptive title_ | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

_Descriptive title_

Introduction

+

Introduction

+

Terminology

+

Example (abbr. Ex) +This is the description for an example terminology.

+

Motivation

+

Motivation

+

Design Considerations

+

OPTIONAL

+

Options considered

+

Option 1

+

Option 1 description

+

Option 2

+

Option 2 description

+

Open questions

+

RECOMMENDED

+

Standard

+

What is the essence of this standard? Adjust heading accordingly.

+ +

Related Documents, OPTIONAL

+

Conformance Tests

+

Conformance Tests, OPTIONAL

+ + \ No newline at end of file diff --git a/standards/scs-compatible-iaas/index.html b/standards/scs-compatible-iaas/index.html new file mode 100644 index 0000000000..515107394f --- /dev/null +++ b/standards/scs-compatible-iaas/index.html @@ -0,0 +1,25 @@ + + + + + +SCS-compatible IaaS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/standards/scs-compatible-kaas/index.html b/standards/scs-compatible-kaas/index.html new file mode 100644 index 0000000000..0edfdd427c --- /dev/null +++ b/standards/scs-compatible-kaas/index.html @@ -0,0 +1,25 @@ + + + + + +SCS-compatible KaaS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/standards/standards/overview/index.html b/standards/standards/overview/index.html new file mode 100644 index 0000000000..d1a894ce49 --- /dev/null +++ b/standards/standards/overview/index.html @@ -0,0 +1,37 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

Standards are the core deliverable of SCS. By standardizing the open source software components of a cloud computing stack, their versions, how they are to be configured, deployed and utilized, SCS guarantees the reproducibility of a certain behavior of this technology.

+

SCS standards are discussed, developed and maintained in the community by the corresponding teams (see Track in the table below), which naturally include existing users of SCS.

+

*Legend to the column headings and entries:

+
    +
  • Document states: Draft, Effective, Deprecated (and no longer effective)
  • +
  • Entries in the effective column marked with an * are stable right now but turn to effective documents in the near future
  • +
  • Entries in the effective column marked with a † will turn deprecated in the near future
  • +
+ + + +
+
StandardTrackDescriptionDraftEffectiveDeprecated*
scs-0001GlobalSovereign Cloud Standards-v1-
scs-0002GlobalStandards, Docs and Organisationv2v1-
scs-0003GlobalSovereign Cloud Standards YAMLv1--
scs-0004GlobalRegulations for achieving SCS-compatible certificationv1--
scs-0005GlobalGovernance of the SCS communityv1--
scs-0100IaaSSCS Flavor Naming Standard-v3v1, v2
Supplement: Implementation and Testing Notesw1--
scs-0101IaaSSCS Entropy-v1-
Supplement: Implementation and Testing Notesw1--
scs-0102IaaSSCS Image Metadata-v1-
Supplement: Implementation and Testing Notesw1--
scs-0103IaaSSCS Standard Flavors and Properties-v1-
scs-0104IaaSSCS Standard Images-v1-
Supplement: Implementation Notesw1--
scs-0110IaaSSSD Flavors-v1-
scs-0111IaaSDecisions for the Volume Type Standardv1--
scs-0112IaaSSONiC Support in SCSv1--
scs-0113IaaSSecurity Groups Decision Recordv1--
scs-0114IaaSSCS Volume Types-v1-
scs-0115IaaSDefault Rules for Security Groups-v1-
scs-0116IaaSSCS Key Manager Standard-v1-
Supplement: Implementation and Testing Notesw1--
scs-0117IaaSVolume Backup Functionality-v1-
scs-0118IaaSSCS Taxonomy of Failsafe Levelsv1--
Supplement: Examples of Failure Cases and their impact on IaaS and KaaS resourcesw1--
scs-0119IaaSReplacement of the deprecated ceph-ansible toolv1--
scs-0120IaaSCluster-API imagesv1--
scs-0121IaaSSCS Availability Zones-v1-
Supplement: Implementation and Testing Notesw1--
scs-0122IaaSEnd-to-End Encryption between Customer Workloadsv1--
scs-0123IaaSMandatory and Supported IaaS Services-v1-
scs-0124IaaSStandard for the security of IaaS service softwarev1--
Supplement: SCS Standard for the security of IaaS service software: Implementation and Testing Notesw1--
scs-0125IaaSSecure Connectionsv1--
scs-0200KaaSUsing Sonobuoy for KaaS conformance testsv1--
scs-0210KaaSSCS K8S Version Policy-v2v1
Supplement: Implementation and Testing Notesw1--
scs-0211KaaSSCS KaaS default storage classv2v1-
Supplement: Implementation and Testing Notesw1--
scs-0212KaaSRequirements for container registriesv1--
scs-0213KaaSKubernetes Nodes Anti Affinityv1--
scs-0214KaaSKubernetes Node Distribution and Availability-v1, v2-
Supplement: Implementation and Testing Notesw1--
scs-0215KaaSRobustness features for Kubernetes clustersv1--
scs-0216KaaSRequirements for testing cluster-stacksv1--
scs-0217KaaSKubernetes cluster hardeningv1--
scs-0218KaaSContainer registry for SCS standard implementationv1--
scs-0219KaaSKaaS Networking Standard-v1-
Supplement: Implementation Notesw1--
scs-0300IAMRequirements for SSO identity federation-v1-
scs-0301IAMNaming for domains/groups/roles/project when onboarding new customersv1--
scs-0302IAMDomain Manager configuration for Keystone-v1-
Supplement: Domain Manager implementation notesw1--
scs-0400OpsStatus Page create decisionv1--
scs-0401OpsStatus page reference implementation decisionv1--
scs-0402OpsStatus page OpenAPI decisionv1--
scs-0403OpsArchitecture for the Cloud Service provider Observability System for the KaaS Layerv1--
scs-0410OpsGnocchi as database for meteringv1--
scs-0411OpsPush-based approach for providing usage datav1--
scs-0412OpsExposition of IaaS metering data as JSONv1--
+ + \ No newline at end of file diff --git a/user-docs/application-examples/opendesk-on-scs/configuration/index.html b/user-docs/application-examples/opendesk-on-scs/configuration/index.html new file mode 100644 index 0000000000..bed20643be --- /dev/null +++ b/user-docs/application-examples/opendesk-on-scs/configuration/index.html @@ -0,0 +1,32 @@ + + + + + +Configuration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Configuration

+

openDesk has many configuration options. You can view them and their default values in your copy of openDesk:

+

Basic components

+

For the configuration of the basic components please have a look at the .yaml files in helmfile/environments/default.

+
$ ls helmfile/environments/default
cache.yaml
certificate.yaml
charts.yaml
cluster.yaml
database.yaml
debug.yaml
enterprise.yaml
functional.yaml
global.generated.yaml
global.gotmpl
_helper.yaml
images.yaml
ingress.yaml
monitoring.yaml
objectstores.yaml
opendesk_main.gotmpl
persistence.yaml
replicas.yaml
repositories.yaml
resources.yaml
secrets.gotmpl
security.yaml
selinux.yaml
smtp.gotmpl
theme.gotmpl
turn.gotmpl
+

To overwrite a specific default setting, copy the snippet into you own values.yaml.gotmpl file and change the values to your need.

+

Apps

+

The settings of the apps reside underneath helmfile/apps (just like their helmfiles). As you see, the different apps have different numbers of values files. Review them carefully and edit your own values.yaml.gotmpl to overwrite any default setting.

+
$ tree helmfile/apps/
helmfile/apps/
├── collabora
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   └── values.yaml.gotmpl
├── cryptpad
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   └── values.yaml.gotmpl
├── element
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   ├── values-element.yaml.gotmpl
│   ├── values-synapse-web.yaml.gotmpl
│   ├── values-synapse.yaml.gotmpl
│   └── values-well-known.yaml.gotmpl
├── intercom-service
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   └── values.yaml.gotmpl
├── jitsi
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   └── values-jitsi.yaml.gotmpl
├── migrations-post
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   └── values.yaml.gotmpl
├── migrations-pre
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   └── values.yaml.gotmpl
├── nextcloud
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   ├── values-nextcloud-mgmt.yaml.gotmpl
│   └── values-nextcloud.yaml.gotmpl
├── nubus
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   ├── values-nubus.yaml.gotmpl
│   ├── values-opendesk-customization.yaml.gotmpl
│   ├── values-opendesk-images.yaml.gotmpl
│   └── values-opendesk-keycloak-bootstrap.yaml.gotmpl
├── openproject
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   └── values.yaml.gotmpl
├── openproject-bootstrap
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   └── values.yaml.gotmpl
├── open-xchange
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   ├── values-dovecot.yaml.gotmpl
│   ├── values-openxchange-bootstrap.yaml.gotmpl
│   ├── values-openxchange-enterprise-contact-picker.yaml.gotmpl
│   └── values-openxchange.yaml.gotmpl
├── provisioning
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   └── values-oxconnector.yaml.gotmpl
├── services
│   ├── helmfile-child.yaml.gotmpl
│   ├── helmfile.yaml.gotmpl
│   ├── values-certificates.yaml.gotmpl
│   ├── values-clamav-distributed.yaml.gotmpl
│   ├── values-clamav-simple.yaml.gotmpl
│   ├── values-dkimpy.yaml.gotmpl
│   ├── values-home.yaml.gotmpl
│   ├── values-mariadb.yaml.gotmpl
│   ├── values-memcached.yaml.gotmpl
│   ├── values-minio.yaml.gotmpl
│   ├── values-otterize.yaml.gotmpl
│   ├── values-postfix.yaml.gotmpl
│   ├── values-postgresql.yaml.gotmpl
│   └── values-redis.yaml.gotmpl
└── xwiki
├── helmfile-child.yaml.gotmpl
├── helmfile.yaml.gotmpl
└── values.yaml.gotmpl


+ + \ No newline at end of file diff --git a/user-docs/application-examples/opendesk-on-scs/contribute/index.html b/user-docs/application-examples/opendesk-on-scs/contribute/index.html new file mode 100644 index 0000000000..e10eb17ff8 --- /dev/null +++ b/user-docs/application-examples/opendesk-on-scs/contribute/index.html @@ -0,0 +1,25 @@ + + + + + +Contribute | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/user-docs/application-examples/opendesk-on-scs/getting_started/index.html b/user-docs/application-examples/opendesk-on-scs/getting_started/index.html new file mode 100644 index 0000000000..12ea1eb680 --- /dev/null +++ b/user-docs/application-examples/opendesk-on-scs/getting_started/index.html @@ -0,0 +1,61 @@ + + + + + +Getting started: Deployment from a local machine | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Getting started: Deployment from a local machine

+

Please note the general Getting Started documentation by openDesk.

+

Clone the openDesk repository

+

Clone the openDesk repository to your local computer:

+
git clone https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk
cd opendesk
+

Add settings for your environment

+

Create your own directory for one or more environments:

+
mkdir -p helmfile/environments/example-env/dev/
+

In the folder you created, add one or more files with the configuration for your environment, e.g. values.yaml.gotmpl (see the Getting Started chapter for an example).

+

Reference the environment you want to deploy in helmfile.yaml:

+
cat helmfile.yaml  <<__EOF__
example-env:
values:
- "helmfile/environments/example-env/dev/*.yaml.gotmpl"
__EOF__
+

Choose your components

+

Decide which components you want to deploy. If you start with some apps only, you can enable the rest of them later. +In the example configuration below all apps are enabled for the initial rollout.

+

Basic configuration

+

You can use the following example settings as a starting point for your helmfile/environments/example-env/dev/values.yaml.gotmpl file. Please see the configuration chapter for more details.

+
{{/*
SPDX-FileCopyrightText: 2024 Zentrum für Digitale Souveränität der Öffentlichen Verwaltung (ZenDiS) GmbH
SPDX-FileCopyrightText: 2023 Bundesministerium des Innern und für Heimat, PG ZenDiS "Projektgruppe für Aufbau ZenDiS"
SPDX-License-Identifier: Apache-2.0
*/}}

---
grafana:
dashboards:
annotations:
"grafana-dashboard-folder": "openDesk: {{ env "NAMESPACE" | default "Main" }}"
enabled: true

functional:
authentication:
twoFactor:
# Define a list of groups to enable 2FA for.
# Note: Removing a group from the list will not disable 2FA for the removed group.
groups: []

certificate:
issuerRef:
name: "letsencrypt-prod"
wildcard: true

ingress:
ingressClassName: "nginx"

persistence:
storageClassNames:
RWX: "csi-cinder-sc-delete"
RWO: "csi-cinder-sc-delete"

smtp:
host: "host.example-relay.org"
username: "some-account"
port: 587

turn:
server:
host: "turn.example.org"
port: "3478"
tls:
host: "turn.example.org"
port: "5349"

cluster:
service:
type: "ClusterIP"
api:
domain: "api.example.org"
port: 6443
networking:
ingressGatewayIP: "YOUR-PUBLIC-IP"

prometheus:
serviceMonitors:
enabled: true
podMonitors:
enabled: true
prometheusRules:
enabled: true

security:
clusterPostfix:
namespace: "swp-cross-instance-mail"

debug:
enabled: true

databases:
oxAppsuite:
host: "mariadb"
# DB name has to set or else "configdb" will used while "openxchange" is created.
name: "openxchange"
username: "root"

collabora:
enabled: true

cryptpad:
enabled: true

element:
enabled: true

intercom:
enabled: true

jitsi:
enabled: true

nextcloud:
enabled: true

openproject:
enabled: true

oxAppsuite:
enabled: true

oxConnector:
enabled: true

xwiki:
enabled: true

...

+

Namespace

+

Create a namespace in your SCS cluster:

+
kubectl create namespace your-namespace
+

Deploy an ingress resource inside the namespace

+

Create an ingress resource:

+
cat >ingress-resource.yaml <<EOF
---
apiVersion: "networking.k8s.io/v1"
kind: "Ingress"
metadata:
name: "example.org"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: "nginx"
tls:
- hosts:
- "example.org"
- "*.example.org"
secretName: "opendesk-certificates-tls"
rules:
- host: "*.example.org"
http:
paths:
- pathType: "Prefix"
path: "/"
backend:
service:
name: "ums-portal-frontend"
port:
number: 443
EOF
+

Deploy the ingress resource inside your namespace:

+
kubectl apply -f ingress-resource.yaml -n your-namespace
+

Deployment

+

Trigger the deployment:

+
OPENDESK_SMTPRELAY_PASSWORD="************" OPENDESK_MASTER_PASSWORD="************" DOMAIN="example.org" helmfile apply -e example-env -n your-namespace

+

Note that the wrapper script supports you in running some of the above tasks.

+

First login

+

Two accounts, an admin and a user account, are automatically created for you.

+

The default admin user is called default.admin, you can retrieve its password by running:

+
kubectl -n your-namespace get secret ums-nubus-credentials -o json | jq -r '.data.admin_password' | base64 -d
+

The default user is called default.user, you can retrieve its password by running:

+
kubectl -n your-namespace get secret ums-nubus-credentials -o json | jq -r '.data.user_password' | base64 -d
+

Open the portal in your browser, e.g. https://portal.example.org and log in.

+

Deploy the desired apps

+

To add an app later you don't have to run helmfile in the top-level directory. You can cd into the app's directory underneath helmfile/apps an execute helmfile in there. The advantage is that this is faster.

+ + \ No newline at end of file diff --git a/user-docs/application-examples/opendesk-on-scs/overview/index.html b/user-docs/application-examples/opendesk-on-scs/overview/index.html new file mode 100644 index 0000000000..0816c37362 --- /dev/null +++ b/user-docs/application-examples/opendesk-on-scs/overview/index.html @@ -0,0 +1,30 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Overview

+

This guide takes you through the steps to deploy openDesk on a Sovereign Cloud Stack Kubernetes cluster. +openDesk is a Kubernetes based, open-source and cloud-native digital workplace suite provided by the Zentrum für Digitale Souveränität der Öffentlichen Verwaltung (ZenDiS) GmbH.

+

It bundles a number of modular software components for collaboration in organizations, such as an identity and access management system with a web based portal (Univention Nubus), a groupware (OX App Suite), tools for knowledge and project management (XWiki, OpenProject), file sharing (Nextcloud), video conferencing (Jitsi), chat (Element), and weboffice tools for online editing (Collabora, Cryptpad).

+

An increasing number of public administrations migrate their work environments to free/libre and/or open source-based solutions. These environments are nowadays built on the container orchestration software Kubernetes. Public administrations strive to be as independent as possible from a few large global companies. Therefore, it is important for them to also have a choice of implementations of the underlying stack for their deployments. The same criteria of openness, standardization and interoperability that apply to the actual tools delivered by openDesk can be applied to the underlying cluster infastructure when running on a Sovereign Cloud Stack cluster.

+

This howto describes the steps to deploy an openDesk environment from a local machine to a Kubernetes cluster in the simplest possible way. It is meant to support Kubernetes beginners in getting started with a deployment in SCS. The goal is to get a single node openDesk installation with a portal and a configurable number of modules that are accessible via a web browser. openDesk also provides information about deployment via Gitlab CI which is not covered here.

+

Please refer to the openDesk documentation for further details.

+ + \ No newline at end of file diff --git a/user-docs/application-examples/opendesk-on-scs/quickstart/index.html b/user-docs/application-examples/opendesk-on-scs/quickstart/index.html new file mode 100644 index 0000000000..76dccec22b --- /dev/null +++ b/user-docs/application-examples/opendesk-on-scs/quickstart/index.html @@ -0,0 +1,42 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Quickstart

+

To get started quickly, you can use the wrapper script that does parts of the work described in Getting started. Please see that page for details nevertheless. # noqa: [relative-link-path]

+ +
git clone https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk
cd opendesk
+
    +
  • Create a folder for the settings of your environment: mkdir -p helmfile/environments/example-env/dev/
  • +
  • Add one or more files with your configuration, for example values.yaml.gotmpl (see Getting Started for an example).
  • +
  • Reference the environment you want to deploy in helmfile.yaml:
  • +
+
cat helmfile.yaml  <<__EOF__
example-env:
values:
- "helmfile/environments/example-env/dev/*.yaml.gotmpl"
__EOF__
+
    +
  • Download the wrapper script. Make it executable.
  • +
  • Edit the variables at the top of the script to fit your needs.
  • +
  • Run it.
  • +
+ + \ No newline at end of file diff --git a/user-docs/application-examples/opendesk-on-scs/requirements/index.html b/user-docs/application-examples/opendesk-on-scs/requirements/index.html new file mode 100644 index 0000000000..1645050a48 --- /dev/null +++ b/user-docs/application-examples/opendesk-on-scs/requirements/index.html @@ -0,0 +1,61 @@ + + + + + +Requirements | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Requirements

+

You can find the general requirements in the openDesk documentation. Please study them before beginning. This howto only touches on requirements concerning the rollout on an SCS cluster.

+

Preparation of your local environment

+

Command line tools

+

You will need the following command line tools on your machine:

+ +

If you run into any problems, please check the openDesk requirements for the required software versions of these tools.

+

KUBECONFIG

+

Store the cluster access information for your SCS cluster in ~/.kube/config. Test the access to the cluster on your command line with a kubectl command, e.g. kubectl get nodes.

+

Preparation of the nameserver

+

openDesk consists of a number of resources with different virtual host names and subdomains. The proposed procedure deploys openDesk on a subdomain that matches the name of the namespace you choose. You will thus get URLs like portal.dev.example.org or wiki.prod.example.org.

+

Therefore it is recommended to create a wildcard A record for the domain in your nameserver (e.g. *.example.org) and point it to your cluster's public IP address.

+

It is of course possible to create individual A records for all resources.

+

The choice of your nameserver has an impact: It is recommended to use a nameserver that gives you API access: In this howto, TLS certificates are fetched from the certification authority Letsencrypt. Because of the number of different services, a wildcard certificate comes in handy. Note that you can only request wildcard certificates from Letsencrypt via the dns-01 challenge. To do so you need a nameserver with API access. If your nameserver does not support this, you can delegate the zone to a different nameserver and fetch an API access token from there.

+

Preparation of the Kubernetes cluster

+

Install cert-manager

+

Install cert-manager in your cluster. It is required to include the custom resource definitions (--set installCRDs=true).

+
helm repo add jetstack https://charts.jetstack.io --force-update
helm repo update
helm upgrade -i cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set installCRDs=true
+

Deploy a certificate issuer

+

The openDesk helmfiles are based on the assumption that you - as the cluster admin - take care of a certificate issuer that can just be used then. For Letsencrypt's ACME dns-01 challenge add a cluster issuer by defining it in a file, e.g. clusterIssuer.yaml and applying it to the cluster. Check the documentation for your respective DNS provider to put together the relevant configuration details.

+
---
apiVersion: v1
kind: Secret
metadata:
name: my-dns-provider
data:
secret-access-key: my-generated-access-token
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
privateKeySecretRef:
name: example-account-key
server: https://acme-staging-v02.api.letsencrypt.org/directory
solvers:
- dns01:
my-dns-provider:
region: eu-west-1
accessKeyID: my-key-id
secretAccessKeySecretRef:
name: my-dns-provider
key: secret-access-key
selector:
dnsNames:
- '*.example.org'
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
privateKeySecretRef:
name: example-account-key
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- dns01:
my-dns-provider:
region: eu-west-1
accessKeyID: my-key-id
secretAccessKeySecretRef:
name: my-dns-provider
key: secret-access-key
selector:
dnsNames:
- '*.example.org'
+

Ingress Controller

+

Ingress-nginx is the only tested ingress controller. The installation must support snippet annotations (allowSnippetAnnotations=true). You can install and update it as shown below. Note that for production environments it is recommended to reconsider the HSTS setting given here.

+
helm upgrade --install ingress-nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginx  --namespace ingress-nginx --create-namespace --set controller.allowSnippetAnnotations=true --set controller.config.hsts=false
+

Prometheus

+

Prometheus is a requirement:

+
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm upgrade -i prometheus prometheus-community/kube-prometheus-stack --namespace prometheus --create-namespace
+

Storage

+

Clarify with your SCS cluster operator what kind of storage your K8s cluster provides. Your configuration will need the according information. You can query the available storage classes like so:

+
kubectl get storageclasses.storage.k8s.io
+

You can hand over the storage class in your values.yaml.gotmpl (see Getting Started).

+

Optional: Credentials for a mail relay

+

If you want your openDesk deployment to be able to send outgoing emails, have the hostname and credentials of an SMTP relay at hand.

+ + \ No newline at end of file diff --git a/user-docs/application-examples/opendesk-on-scs/user-import/index.html b/user-docs/application-examples/opendesk-on-scs/user-import/index.html new file mode 100644 index 0000000000..fe5babb493 --- /dev/null +++ b/user-docs/application-examples/opendesk-on-scs/user-import/index.html @@ -0,0 +1,29 @@ + + + + + +User import | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

User import

+

Once you have a complete deployment, you can add additional accounts via the administration interface. +For this, you can use the administrative account default.admin, whose credentials are provided after the deployment (see First login.

+

Alternatively, users can be created automatically from a source file. +The [openDesk User Importer](openDesk User Importer) supports both random test users and predefined users from ods files. +To keep it simple you could also use the credentials from default.admin.

+ + \ No newline at end of file diff --git a/user-docs/category/application-examples/index.html b/user-docs/category/application-examples/index.html new file mode 100644 index 0000000000..c57114e695 --- /dev/null +++ b/user-docs/category/application-examples/index.html @@ -0,0 +1,24 @@ + + + + + +Application Examples | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/user-docs/category/opendesk-on-scs/index.html b/user-docs/category/opendesk-on-scs/index.html new file mode 100644 index 0000000000..448987f227 --- /dev/null +++ b/user-docs/category/opendesk-on-scs/index.html @@ -0,0 +1,24 @@ + + + + + +OpenDesk on SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/user-docs/index.html b/user-docs/index.html new file mode 100644 index 0000000000..db8055bde6 --- /dev/null +++ b/user-docs/index.html @@ -0,0 +1,27 @@ + + + + + +Introduction | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + +

Introduction

+

Welcome to the User Documentation of the Sovereign Cloud Stack (SCS)

+

In this section, users will find helpful information and practical guides for working with SCS clouds. We provide insights into various application use cases, migration tutorials between different SCS cloud service providers, and showcase ways to communicate remotely with your cloud without a user interface.

+

Discover best practices to make the most of your cloud, from introductions to specific applications to advanced use cases. Stay tuned for upcoming content designed to simplify your cloud experience.

+ + \ No newline at end of file